aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.ru>2022-02-10 16:44:39 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:39 +0300
commite9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (patch)
tree64175d5cadab313b3e7039ebaa06c5bc3295e274 /contrib/libs
parent2598ef1d0aee359b4b6d5fdd1758916d5907d04f (diff)
downloadydb-e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0.tar.gz
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs')
-rw-r--r--contrib/libs/antlr3_cpp_runtime/ya.make4
-rw-r--r--contrib/libs/apache/arrow/cpp/src/arrow/array/README.md40
-rw-r--r--contrib/libs/apache/arrow/cpp/src/arrow/compute/README.md116
-rw-r--r--contrib/libs/apache/arrow/cpp/src/arrow/io/api.h48
-rw-r--r--contrib/libs/apache/arrow/cpp/src/arrow/ipc/api.h50
-rw-r--r--contrib/libs/apache/arrow/cpp/src/arrow/vendored/datetime/README.md42
-rw-r--r--contrib/libs/apache/arrow/cpp/src/arrow/vendored/musl/README.md50
-rw-r--r--contrib/libs/apache/arrow/cpp/src/arrow/vendored/portable-snippets/README.md20
-rw-r--r--contrib/libs/apache/arrow/cpp/src/arrow/vendored/utfcpp/README.md56
-rw-r--r--contrib/libs/apache/arrow/ya.make4
-rw-r--r--contrib/libs/apache/orc/.yandex_meta/devtools.copyrights.report102
-rw-r--r--contrib/libs/apache/orc/.yandex_meta/devtools.licenses.report146
-rw-r--r--contrib/libs/apache/orc/.yandex_meta/licenses.list.txt40
-rw-r--r--contrib/libs/apache/orc/LICENSE312
-rw-r--r--contrib/libs/apache/orc/NOTICE2
-rw-r--r--contrib/libs/apache/orc/README.md8
-rw-r--r--contrib/libs/apache/orc/c++/include/orc/Common.hh14
-rw-r--r--contrib/libs/apache/orc/c++/include/orc/Reader.hh12
-rw-r--r--contrib/libs/apache/orc/c++/include/orc/Statistics.hh4
-rw-r--r--contrib/libs/apache/orc/c++/include/orc/orc-config.hh2
-rw-r--r--contrib/libs/apache/orc/c++/src/Adaptor.hh76
-rw-r--r--contrib/libs/apache/orc/c++/src/BloomFilter.cc24
-rw-r--r--contrib/libs/apache/orc/c++/src/BloomFilter.hh32
-rw-r--r--contrib/libs/apache/orc/c++/src/ColumnReader.cc2
-rw-r--r--contrib/libs/apache/orc/c++/src/ColumnWriter.cc2
-rw-r--r--contrib/libs/apache/orc/c++/src/Common.cc52
-rw-r--r--contrib/libs/apache/orc/c++/src/Compression.cc154
-rw-r--r--contrib/libs/apache/orc/c++/src/OrcFile.cc4
-rw-r--r--contrib/libs/apache/orc/c++/src/Reader.cc20
-rw-r--r--contrib/libs/apache/orc/c++/src/Reader.hh20
-rw-r--r--contrib/libs/apache/orc/c++/src/RleEncoderV2.cc4
-rw-r--r--contrib/libs/apache/orc/c++/src/Statistics.hh52
-rw-r--r--contrib/libs/apache/orc/c++/src/Writer.cc2
-rw-r--r--contrib/libs/apache/orc/proto/orc_proto.proto40
-rw-r--r--contrib/libs/apache/orc/ya.make8
-rw-r--r--contrib/libs/base64/ya.make4
-rw-r--r--contrib/libs/brotli/ya.make4
-rw-r--r--contrib/libs/c-ares/CHANGES1108
-rw-r--r--contrib/libs/c-ares/README.md4
-rw-r--r--contrib/libs/c-ares/RELEASE-NOTES44
-rw-r--r--contrib/libs/c-ares/acountry.c14
-rw-r--r--contrib/libs/c-ares/adig.c4
-rw-r--r--contrib/libs/c-ares/ahost.c2
-rw-r--r--contrib/libs/c-ares/ares.h118
-rw-r--r--contrib/libs/c-ares/ares__close_sockets.c4
-rw-r--r--contrib/libs/c-ares/ares__get_hostent.c2
-rw-r--r--contrib/libs/c-ares/ares__parse_into_addrinfo.c532
-rw-r--r--contrib/libs/c-ares/ares__readaddrinfo.c520
-rw-r--r--contrib/libs/c-ares/ares__sortaddrinfo.c990
-rw-r--r--contrib/libs/c-ares/ares_freeaddrinfo.c114
-rw-r--r--contrib/libs/c-ares/ares_getaddrinfo.c1530
-rw-r--r--contrib/libs/c-ares/ares_gethostbyname.c28
-rw-r--r--contrib/libs/c-ares/ares_getnameinfo.c4
-rw-r--r--contrib/libs/c-ares/ares_init.c20
-rw-r--r--contrib/libs/c-ares/ares_ipv6.h14
-rw-r--r--contrib/libs/c-ares/ares_parse_a_reply.c262
-rw-r--r--contrib/libs/c-ares/ares_parse_aaaa_reply.c262
-rw-r--r--contrib/libs/c-ares/ares_parse_soa_reply.c200
-rw-r--r--contrib/libs/c-ares/ares_parse_txt_reply.c2
-rw-r--r--contrib/libs/c-ares/ares_private.h92
-rw-r--r--contrib/libs/c-ares/ares_process.c84
-rw-r--r--contrib/libs/c-ares/ares_search.c10
-rw-r--r--contrib/libs/c-ares/ares_version.h8
-rw-r--r--contrib/libs/c-ares/test/ares-test-ai.h114
-rw-r--r--contrib/libs/c-ares/test/ares-test-init.cc36
-rw-r--r--contrib/libs/c-ares/test/ares-test-internal.cc210
-rw-r--r--contrib/libs/c-ares/test/ares-test-live.cc242
-rw-r--r--contrib/libs/c-ares/test/ares-test-misc.cc18
-rw-r--r--contrib/libs/c-ares/test/ares-test-mock-ai.cc1446
-rw-r--r--contrib/libs/c-ares/test/ares-test-mock.cc32
-rw-r--r--contrib/libs/c-ares/test/ares-test-parse-a.cc42
-rw-r--r--contrib/libs/c-ares/test/ares-test-parse-aaaa.cc4
-rw-r--r--contrib/libs/c-ares/test/ares-test-parse-soa-any.cc222
-rw-r--r--contrib/libs/c-ares/test/ares-test-parse-soa.cc2
-rw-r--r--contrib/libs/c-ares/test/ares-test.cc148
-rw-r--r--contrib/libs/c-ares/test/ares-test.h120
-rw-r--r--contrib/libs/c-ares/test/ya.make4
-rw-r--r--contrib/libs/c-ares/ya.make12
-rw-r--r--contrib/libs/crcutil/ya.make4
-rw-r--r--contrib/libs/cxxsupp/builtins/ya.make8
-rw-r--r--contrib/libs/cxxsupp/libcxx/ya.make4
-rw-r--r--contrib/libs/cxxsupp/libcxxabi-parts/ya.make2
-rw-r--r--contrib/libs/cxxsupp/libcxxrt/ya.make2
-rw-r--r--contrib/libs/cxxsupp/openmp/ya.make4
-rw-r--r--contrib/libs/double-conversion/ya.make4
-rw-r--r--contrib/libs/expat/.yandex_meta/devtools.copyrights.report142
-rw-r--r--contrib/libs/expat/.yandex_meta/devtools.licenses.report14
-rw-r--r--contrib/libs/expat/.yandex_meta/licenses.list.txt6
-rw-r--r--contrib/libs/expat/README.md164
-rw-r--r--contrib/libs/expat/expat.h62
-rw-r--r--contrib/libs/expat/expat_config.h18
-rw-r--r--contrib/libs/expat/expat_external.h16
-rw-r--r--contrib/libs/expat/lib/ascii.h10
-rw-r--r--contrib/libs/expat/lib/asciitab.h6
-rw-r--r--contrib/libs/expat/lib/iasciitab.h6
-rw-r--r--contrib/libs/expat/lib/internal.h98
-rw-r--r--contrib/libs/expat/lib/latin1tab.h6
-rw-r--r--contrib/libs/expat/lib/nametab.h4
-rw-r--r--contrib/libs/expat/lib/siphash.h8
-rw-r--r--contrib/libs/expat/lib/utf8tab.h6
-rw-r--r--contrib/libs/expat/lib/winconfig.h8
-rw-r--r--contrib/libs/expat/lib/xmlparse.c2338
-rw-r--r--contrib/libs/expat/lib/xmlrole.c24
-rw-r--r--contrib/libs/expat/lib/xmlrole.h8
-rw-r--r--contrib/libs/expat/lib/xmltok.c52
-rw-r--r--contrib/libs/expat/lib/xmltok.h10
-rw-r--r--contrib/libs/expat/lib/xmltok_impl.c22
-rw-r--r--contrib/libs/expat/lib/xmltok_impl.h4
-rw-r--r--contrib/libs/expat/lib/xmltok_ns.c8
-rw-r--r--contrib/libs/expat/ya.make4
-rw-r--r--contrib/libs/farmhash/ya.make4
-rw-r--r--contrib/libs/fastlz/ya.make4
-rw-r--r--contrib/libs/grpc/src/proto/grpc/reflection/v1alpha/ya.make4
-rw-r--r--contrib/libs/grpc/src/python/grpcio_reflection/grpc_reflection/v1alpha/reflection.py4
-rw-r--r--contrib/libs/grpc/src/python/grpcio_reflection/ya.make2
-rw-r--r--contrib/libs/grpc/ya.make4
-rw-r--r--contrib/libs/hdr_histogram/ya.make4
-rw-r--r--contrib/libs/highwayhash/ya.make4
-rw-r--r--contrib/libs/libaio/ya.make4
-rw-r--r--contrib/libs/libunwind/include/__libunwind_config.h44
-rw-r--r--contrib/libs/libunwind/include/libunwind.h304
-rw-r--r--contrib/libs/libunwind/src/DwarfInstructions.hpp2
-rw-r--r--contrib/libs/libunwind/src/Registers.hpp1044
-rw-r--r--contrib/libs/libunwind/src/Unwind-sjlj.c24
-rw-r--r--contrib/libs/libunwind/src/UnwindCursor.hpp208
-rw-r--r--contrib/libs/libunwind/src/UnwindRegistersRestore.S384
-rw-r--r--contrib/libs/libunwind/src/UnwindRegistersSave.S420
-rw-r--r--contrib/libs/libunwind/src/assembly.h98
-rw-r--r--contrib/libs/libunwind/src/config.h12
-rw-r--r--contrib/libs/libunwind/src/libunwind.cpp6
-rw-r--r--contrib/libs/linuxvdso/ya.make8
-rw-r--r--contrib/libs/llvm12/CODE_OWNERS.TXT36
-rw-r--r--contrib/libs/llvm12/CREDITS.TXT32
-rw-r--r--contrib/libs/llvm12/include/llvm-c/Core.h108
-rw-r--r--contrib/libs/llvm12/include/llvm-c/DebugInfo.h6
-rw-r--r--contrib/libs/llvm12/include/llvm-c/Error.h10
-rw-r--r--contrib/libs/llvm12/include/llvm-c/LLJIT.h448
-rw-r--r--contrib/libs/llvm12/include/llvm-c/Orc.h680
-rw-r--r--contrib/libs/llvm12/include/llvm-c/OrcEE.h132
-rw-r--r--contrib/libs/llvm12/include/llvm-c/Transforms/Scalar.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/APFixedPoint.h496
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/APFloat.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/APInt.h52
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/APSInt.h20
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/Any.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/BitVector.h22
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/DenseMap.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/DenseMapInfo.h90
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/DenseSet.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/DepthFirstIterator.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/DirectedGraph.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/FloatingPointMode.h36
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/FunctionExtras.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/Hashing.h50
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/IntervalMap.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/IntrusiveRefCntPtr.h88
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/Optional.h214
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/STLExtras.h126
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/Sequence.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/SetVector.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/SmallSet.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/SmallString.h54
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/SmallVector.h840
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/SparseSet.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/Statistic.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/StringExtras.h192
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/StringMap.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/StringSet.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/Triple.h130
-rw-r--r--contrib/libs/llvm12/include/llvm/ADT/simple_ilist.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/AliasAnalysis.h96
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/AliasSetTracker.h42
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/AssumptionCache.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/BasicAliasAnalysis.h94
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/BlockFrequencyInfoImpl.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/BranchProbabilityInfo.h490
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/CFGPrinter.h32
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/CGSCCPassManager.h110
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/CaptureTracking.h16
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/CodeMetrics.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/ConstantFolding.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/ConstraintSystem.h198
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/DDG.h54
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/DDGPrinter.h204
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/Delinearization.h88
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/DemandedBits.h28
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/DivergenceAnalysis.h62
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/EHPersonalities.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/FunctionPropertiesAnalysis.h194
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/IRSimilarityIdentifier.h1600
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/IVDescriptors.h160
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/InlineAdvisor.h130
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/InlineSizeEstimatorAnalysis.h22
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/InstCount.h78
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/InstructionSimplify.h56
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/IntervalIterator.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/IteratedDominanceFrontier.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/LazyBranchProbabilityInfo.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/LazyCallGraph.h56
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/LazyValueInfo.h18
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/Lint.h28
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/Loads.h18
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/LoopAccessAnalysis.h26
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/LoopAnalysisManager.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/LoopCacheAnalysis.h30
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/LoopInfo.h38
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/LoopInfoImpl.h30
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/LoopNestAnalysis.h30
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/MLInlineAdvisor.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/MemDerefPrinter.h70
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/MemoryDependenceAnalysis.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/MemoryLocation.h104
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/MemorySSA.h82
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/MemorySSAUpdater.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/ModuleDebugInfoPrinter.h80
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/MustExecute.h38
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/ObjCARCAnalysisUtils.h18
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/OptimizationRemarkEmitter.h16
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/PhiValues.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/ProfileSummaryInfo.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/RegionInfoImpl.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/ReplayInlineAdvisor.h104
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/ScalarEvolution.h418
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/ScalarEvolutionDivision.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/ScalarEvolutionExpressions.h192
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/SparsePropagation.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/StackLifetime.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/StackSafetyAnalysis.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/SyncDependenceAnalysis.h56
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/TargetLibraryInfo.def42
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/TargetLibraryInfo.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/TargetTransformInfo.h488
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/TargetTransformInfoImpl.h412
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h246
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/Utils/Local.h78
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/Utils/TFUtils.h356
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/ValueLattice.h22
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/ValueTracking.h150
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/VecFuncs.def292
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/VectorUtils.h60
-rw-r--r--contrib/libs/llvm12/include/llvm/BinaryFormat/COFF.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/BinaryFormat/Dwarf.def36
-rw-r--r--contrib/libs/llvm12/include/llvm/BinaryFormat/Dwarf.h172
-rw-r--r--contrib/libs/llvm12/include/llvm/BinaryFormat/DynamicTags.def2
-rw-r--r--contrib/libs/llvm12/include/llvm/BinaryFormat/ELF.h110
-rw-r--r--contrib/libs/llvm12/include/llvm/BinaryFormat/ELFRelocs/CSKY.def148
-rw-r--r--contrib/libs/llvm12/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def24
-rw-r--r--contrib/libs/llvm12/include/llvm/BinaryFormat/MachO.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/BinaryFormat/Wasm.h70
-rw-r--r--contrib/libs/llvm12/include/llvm/BinaryFormat/WasmRelocs.def10
-rw-r--r--contrib/libs/llvm12/include/llvm/BinaryFormat/WasmTraits.h158
-rw-r--r--contrib/libs/llvm12/include/llvm/BinaryFormat/XCOFF.h224
-rw-r--r--contrib/libs/llvm12/include/llvm/Bitcode/BitcodeCommon.h82
-rw-r--r--contrib/libs/llvm12/include/llvm/Bitcode/BitcodeConvenience.h994
-rw-r--r--contrib/libs/llvm12/include/llvm/Bitcode/BitcodeWriter.h24
-rw-r--r--contrib/libs/llvm12/include/llvm/Bitcode/LLVMBitCodes.h38
-rw-r--r--contrib/libs/llvm12/include/llvm/Bitstream/BitCodes.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/Bitstream/BitstreamWriter.h186
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/AsmPrinter.h206
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/AsmPrinterHandler.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/BasicBlockSectionUtils.h82
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/BasicTTIImpl.h704
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/CalcSpillWeights.h68
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/CallingConvLower.h20
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/CodeGenPassBuilder.h2310
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/CommandFlags.h56
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/DIE.h18
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/DbgEntityHistoryCalculator.h48
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/DebugHandlerBase.h22
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/DwarfStringPoolEntry.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/FastISel.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/FunctionLoweringInfo.h56
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/CSEInfo.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/CallLowering.h260
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/CombinerHelper.h526
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/GISelKnownBits.h16
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/IRTranslator.h160
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/InstructionSelector.h68
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h132
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h210
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h136
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h140
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/Localizer.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h202
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h320
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h24
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/Utils.h208
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/ISDOpcodes.h202
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/LiveInterval.h30
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/LiveIntervalUnion.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/LiveIntervals.h24
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/LiveRangeEdit.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/LiveRegMatrix.h20
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/LiveRegUnits.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/LiveVariables.h54
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/LowLevelType.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MBFIWrapper.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MIRFormatter.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MIRYamlMapping.h100
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachineBasicBlock.h58
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachineBlockFrequencyInfo.h40
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachineCombinerPattern.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachineConstantPool.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachineFrameInfo.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachineFunction.h106
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachineInstr.h74
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachineInstrBuilder.h54
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachineJumpTableInfo.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachineLoopInfo.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachineModuleInfo.h46
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachineOperand.h18
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachineOutliner.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachinePassManager.h534
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachinePassRegistry.def394
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachinePipeliner.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachineRegisterInfo.h48
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachineSSAUpdater.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachineStableHash.h82
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MachineTraceMetrics.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/MultiHazardRecognizer.h116
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/NonRelocatableStringpool.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/Passes.h40
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/RDFLiveness.h64
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/RDFRegisters.h82
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/ReachingDefAnalysis.h54
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/RegAllocPBQP.h30
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/Register.h40
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/RegisterPressure.h34
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/RegisterScavenging.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/RuntimeLibcalls.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/ScheduleDAGInstrs.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/ScheduleHazardRecognizer.h18
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/SelectionDAG.h206
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/SelectionDAGNodes.h288
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/SelectionDAGTargetInfo.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/SlotIndexes.h34
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/StableHashing.h246
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/StackMaps.h102
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/SwitchLoweringUtils.h16
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/TargetCallingConv.h96
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/TargetFrameLowering.h20
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/TargetInstrInfo.h220
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/TargetLowering.h190
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h38
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/TargetPassConfig.h30
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/TargetRegisterInfo.h152
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/TargetSubtargetInfo.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/TileShapeInfo.h216
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/ValueTypes.h134
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/ValueTypes.td222
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/VirtRegMap.h58
-rw-r--r--contrib/libs/llvm12/include/llvm/CodeGen/WasmEHFuncInfo.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/Config/abi-breaking.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Config/abi-breaking.h.cmake2
-rw-r--r--contrib/libs/llvm12/include/llvm/Config/config-linux.h26
-rw-r--r--contrib/libs/llvm12/include/llvm/Config/config-osx.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/Config/config-win.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/Config/config.h.cmake22
-rw-r--r--contrib/libs/llvm12/include/llvm/Config/llvm-config-linux.h26
-rw-r--r--contrib/libs/llvm12/include/llvm/Config/llvm-config-osx.h38
-rw-r--r--contrib/libs/llvm12/include/llvm/Config/llvm-config-win.h38
-rw-r--r--contrib/libs/llvm12/include/llvm/Config/llvm-config.h.cmake18
-rw-r--r--contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinker.h112
-rw-r--r--contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinkerDeclContext.h44
-rw-r--r--contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFStreamer.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/CVRecord.h20
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def70
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/SymbolDumper.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/SymbolRecordHelpers.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeCollection.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeHashing.h22
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeIndex.h20
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeRecord.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeRecordHelpers.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/DIContext.h24
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h20
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFContext.h24
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h36
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h18
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h16
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDie.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFExpression.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFFormValue.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFListTable.h68
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFUnit.h26
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFVerifier.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/PDB/DIA/DIASession.h208
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h120
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h104
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeInlineSiteSymbol.h114
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeSession.h22
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/SymbolCache.h48
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/TpiStream.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/PDB/PDBExtras.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/PDB/PDBSymbol.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/DebugInfo/Symbolize/Symbolize.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Demangle/ItaniumDemangle.h334
-rw-r--r--contrib/libs/llvm12/include/llvm/Demangle/Utility.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/ELF.h22
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h26
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/JITLink.h156
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/JITLinkDylib.h70
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h30
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/MachO.h20
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/MachO_arm64.h20
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h22
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/JITSymbol.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Core.h902
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h54
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/LLJIT.h56
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Layer.h48
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/LazyReexports.h16
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/MachOPlatform.h32
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h72
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRPCTargetProcessControl.h852
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h486
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h294
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h36
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h40
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h180
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/OrcError.h170
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/RPCUtils.h3336
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h388
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/Serialization.h1560
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h352
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Speculation.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h154
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TPCEHFrameRegistrar.h130
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h466
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h1262
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h104
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h98
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h458
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/ExecutionEngine/RuntimeDyld.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/FileCheck/FileCheck.h454
-rw-r--r--contrib/libs/llvm12/include/llvm/Frontend/Directive/DirectiveBase.td90
-rw-r--r--contrib/libs/llvm12/include/llvm/Frontend/OpenACC/ACC.td158
-rw-r--r--contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMP.inc7014
-rw-r--r--contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMP.td392
-rw-r--r--contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPConstants.h62
-rw-r--r--contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPContext.h72
-rw-r--r--contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPGridValues.h22
-rw-r--r--contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPIRBuilder.h762
-rw-r--r--contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPKinds.def1034
-rw-r--r--contrib/libs/llvm12/include/llvm/FuzzMutate/IRMutator.h22
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Argument.h48
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Assumptions.h122
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Attributes.h142
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Attributes.td60
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/BasicBlock.h118
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/CallingConv.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Constant.h50
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/ConstantRange.h48
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Constants.h188
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/DIBuilder.h76
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/DataLayout.h70
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/DebugInfoMetadata.h422
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/DebugLoc.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/DerivedTypes.h72
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/DiagnosticInfo.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Dominators.h46
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/FixedMetadataKinds.def6
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/FixedPointBuilder.h952
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Function.h92
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/GetElementPtrTypeIterator.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/GlobalObject.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/GlobalVariable.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/IRBuilder.h290
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/IRPrintingPasses.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/InstrTypes.h246
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Instruction.h88
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Instructions.h144
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/IntrinsicInst.h158
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Intrinsics.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Intrinsics.td818
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/IntrinsicsAArch64.td506
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/IntrinsicsAMDGPU.td184
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/IntrinsicsARM.td26
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/IntrinsicsBPF.td18
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/IntrinsicsNVVM.td106
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/IntrinsicsPowerPC.td732
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/IntrinsicsRISCV.td2048
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/IntrinsicsVE.td70
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/IntrinsicsVEVL.gen.td2426
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/IntrinsicsWebAssembly.td338
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/IntrinsicsX86.td252
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/LLVMContext.h26
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/LLVMRemarkStreamer.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/LegacyPassManagers.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/MDBuilder.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/MatrixBuilder.h54
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Metadata.def4
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Metadata.h92
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Module.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/ModuleSummaryIndex.h20
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Operator.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/OptBisect.h28
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/PassInstrumentation.h196
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/PassManager.h126
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/PassManagerInternal.h44
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/PassTimingInfo.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/PatternMatch.h522
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/PredIteratorCache.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/PrintPasses.h110
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/PseudoProbe.h196
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/ReplaceConstant.h78
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/RuntimeLibcalls.def62
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Statepoint.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/StructuralHash.h90
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/SymbolTableListTraits.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Type.h58
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/User.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/VPIntrinsics.def216
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Value.def36
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Value.h184
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/ValueHandle.h28
-rw-r--r--contrib/libs/llvm12/include/llvm/IR/Verifier.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/InitializePasses.h72
-rw-r--r--contrib/libs/llvm12/include/llvm/InterfaceStub/ELFObjHandler.h116
-rw-r--r--contrib/libs/llvm12/include/llvm/InterfaceStub/ELFStub.h154
-rw-r--r--contrib/libs/llvm12/include/llvm/InterfaceStub/TBEHandler.h108
-rw-r--r--contrib/libs/llvm12/include/llvm/LTO/Config.h48
-rw-r--r--contrib/libs/llvm12/include/llvm/LTO/LTO.h16
-rw-r--r--contrib/libs/llvm12/include/llvm/LTO/LTOBackend.h48
-rw-r--r--contrib/libs/llvm12/include/llvm/LTO/legacy/LTOCodeGenerator.h16
-rw-r--r--contrib/libs/llvm12/include/llvm/LinkAllPasses.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCAsmBackend.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCAsmInfo.h92
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCAsmMacro.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCAssembler.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCContext.h46
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCDwarf.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCExpr.h28
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCFragment.h104
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCInst.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCInstPrinter.h24
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCInstrDesc.h40
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCMachObjectWriter.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCObjectFileInfo.h26
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCObjectStreamer.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCParser/AsmLexer.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCParser/MCAsmLexer.h40
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCParser/MCAsmParser.h50
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCParser/MCTargetAsmParser.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCPseudoProbe.h378
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCRegister.h24
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCRegisterInfo.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCSchedule.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCSectionXCOFF.h22
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCStreamer.h56
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCSubtargetInfo.h28
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCSymbol.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCSymbolWasm.h36
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCTargetOptions.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCWasmObjectWriter.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCWin64EH.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCWinCOFFStreamer.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/MCWinEH.h44
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/StringTableBuilder.h22
-rw-r--r--contrib/libs/llvm12/include/llvm/MC/SubtargetFeature.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/MCA/HardwareUnits/Scheduler.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/ArchiveWriter.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/Binary.h18
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/COFF.h44
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/ELF.h1168
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/ELFObjectFile.h352
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/ELFTypes.h56
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/MachO.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/MachOUniversal.h16
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/MachOUniversalWriter.h226
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/ObjectFile.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/RelocationResolver.h16
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/StackMapParser.h36
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/SymbolicFile.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/Wasm.h32
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/XCOFFObjectFile.h202
-rw-r--r--contrib/libs/llvm12/include/llvm/ObjectYAML/ArchiveYAML.h176
-rw-r--r--contrib/libs/llvm12/include/llvm/ObjectYAML/DWARFEmitter.h24
-rw-r--r--contrib/libs/llvm12/include/llvm/ObjectYAML/DWARFYAML.h310
-rw-r--r--contrib/libs/llvm12/include/llvm/ObjectYAML/ELFYAML.h518
-rw-r--r--contrib/libs/llvm12/include/llvm/ObjectYAML/MachOYAML.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/ObjectYAML/MinidumpYAML.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/ObjectYAML/ObjectYAML.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/ObjectYAML/WasmYAML.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/ObjectYAML/yaml2obj.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/Option/ArgList.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/Option/OptParser.td146
-rw-r--r--contrib/libs/llvm12/include/llvm/Option/OptTable.h52
-rw-r--r--contrib/libs/llvm12/include/llvm/Option/Option.h16
-rw-r--r--contrib/libs/llvm12/include/llvm/Pass.h40
-rw-r--r--contrib/libs/llvm12/include/llvm/PassAnalysisSupport.h30
-rw-r--r--contrib/libs/llvm12/include/llvm/Passes/PassBuilder.h198
-rw-r--r--contrib/libs/llvm12/include/llvm/Passes/StandardInstrumentations.h458
-rw-r--r--contrib/libs/llvm12/include/llvm/ProfileData/Coverage/CoverageMapping.h126
-rw-r--r--contrib/libs/llvm12/include/llvm/ProfileData/GCOV.h82
-rw-r--r--contrib/libs/llvm12/include/llvm/ProfileData/InstrProf.h42
-rw-r--r--contrib/libs/llvm12/include/llvm/ProfileData/InstrProfData.inc248
-rw-r--r--contrib/libs/llvm12/include/llvm/ProfileData/InstrProfReader.h36
-rw-r--r--contrib/libs/llvm12/include/llvm/ProfileData/InstrProfWriter.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/ProfileData/ProfileCommon.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/ProfileData/SampleProf.h560
-rw-r--r--contrib/libs/llvm12/include/llvm/ProfileData/SampleProfReader.h228
-rw-r--r--contrib/libs/llvm12/include/llvm/ProfileData/SampleProfWriter.h284
-rw-r--r--contrib/libs/llvm12/include/llvm/Remarks/BitstreamRemarkParser.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/Remarks/HotnessThresholdParser.h148
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/AArch64TargetParser.def70
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/AArch64TargetParser.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/AMDGPUMetadata.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/AMDHSAKernelDescriptor.h82
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/ARMTargetParser.def28
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/ARMTargetParser.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/ARMWinEH.h170
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/AlignOf.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/Allocator.h24
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/AtomicOrdering.h30
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/BinaryItemStream.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/CFGDiff.h158
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/CheckedArithmetic.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/CommandLine.h46
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/Compiler.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/CrashRecoveryContext.h16
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/DOTGraphTraits.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/Error.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/ErrorHandling.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/ErrorOr.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/ExitCodes.h88
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/FileCollector.h112
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/FileSystem.h134
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/FileSystem/UniqueID.h126
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/FormatVariadic.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/GenericDomTree.h96
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/GenericDomTreeConstruction.h260
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/GlobPattern.h20
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/GraphWriter.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/Host.h28
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/InitLLVM.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/InstructionCost.h498
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/JSON.h352
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/KnownBits.h286
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/LineIterator.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/MachineValueType.h440
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/MathExtras.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/MemoryBuffer.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/MemoryBufferRef.h134
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/Parallel.h196
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/Path.h76
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/PluginLoader.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/Process.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/Program.h20
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/RISCVTargetParser.def28
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/Signals.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/Signposts.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/SourceMgr.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/SwapByteOrder.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/SymbolRemappingReader.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/TargetOpcodes.def152
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/TargetParser.h42
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/TargetRegistry.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/TaskQueue.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/Threading.h22
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/ToolOutputFile.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/TrigramIndex.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/TypeSize.h876
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/VirtualFileSystem.h42
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/Win64EH.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/X86TargetParser.def18
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/X86TargetParser.h30
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/YAMLParser.h18
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/YAMLTraits.h130
-rw-r--r--contrib/libs/llvm12/include/llvm/Support/raw_ostream.h212
-rw-r--r--contrib/libs/llvm12/include/llvm/TableGen/DirectiveEmitter.h444
-rw-r--r--contrib/libs/llvm12/include/llvm/TableGen/Error.h34
-rw-r--r--contrib/libs/llvm12/include/llvm/TableGen/Record.h428
-rw-r--r--contrib/libs/llvm12/include/llvm/TableGen/SearchableTable.td30
-rw-r--r--contrib/libs/llvm12/include/llvm/Target/CGPassBuilderOption.h152
-rw-r--r--contrib/libs/llvm12/include/llvm/Target/GenericOpcodes.td788
-rw-r--r--contrib/libs/llvm12/include/llvm/Target/GlobalISel/Combine.td678
-rw-r--r--contrib/libs/llvm12/include/llvm/Target/GlobalISel/SelectionDAGCompat.td54
-rw-r--r--contrib/libs/llvm12/include/llvm/Target/Target.td422
-rw-r--r--contrib/libs/llvm12/include/llvm/Target/TargetCallingConv.td6
-rw-r--r--contrib/libs/llvm12/include/llvm/Target/TargetInstrPredicate.td46
-rw-r--r--contrib/libs/llvm12/include/llvm/Target/TargetItinerary.td2
-rw-r--r--contrib/libs/llvm12/include/llvm/Target/TargetLoweringObjectFile.h54
-rw-r--r--contrib/libs/llvm12/include/llvm/Target/TargetMachine.h138
-rw-r--r--contrib/libs/llvm12/include/llvm/Target/TargetOptions.h110
-rw-r--r--contrib/libs/llvm12/include/llvm/Target/TargetPfmCounters.td4
-rw-r--r--contrib/libs/llvm12/include/llvm/Target/TargetSchedule.td28
-rw-r--r--contrib/libs/llvm12/include/llvm/Target/TargetSelectionDAG.td302
-rw-r--r--contrib/libs/llvm12/include/llvm/Testing/Support/SupportHelpers.h276
-rw-r--r--contrib/libs/llvm12/include/llvm/TextAPI/MachO/Platform.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Coroutines.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroCleanup.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroEarly.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroElide.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroSplit.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/HelloNew/HelloWorld.h68
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/IPO.h24
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/IPO/AlwaysInliner.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/IPO/Annotation2Metadata.h82
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/IPO/Attributor.h1200
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/IPO/BlockExtractor.h72
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/IPO/IROutliner.h738
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/IPO/Inliner.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/IPO/LoopExtractor.h86
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/IPO/LowerTypeTests.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/IPO/OpenMPOpt.h20
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/IPO/SampleContextTracker.h326
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/IPO/SampleProfile.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/IPO/SampleProfileProbe.h316
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/IPO/StripSymbols.h116
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/IPO/WholeProgramDevirt.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/InstCombine/InstCombiner.h1078
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Instrumentation.h10
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/AddressSanitizer.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/BoundsChecking.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/DataFlowSanitizer.h86
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/GCOVProfiler.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/HWAddressSanitizer.h38
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/MemProfiler.h124
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/MemorySanitizer.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/SanitizerCoverage.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/ObjCARC.h36
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar.h98
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/AnnotationRemarks.h74
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/ConstraintElimination.h70
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/DCE.h12
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/GVN.h24
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/IndVarSimplify.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/InferAddressSpaces.h76
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/JumpThreading.h74
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopFlatten.h86
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopIdiomRecognize.h26
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopInterchange.h70
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopPassManager.h522
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopReroll.h76
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopRotation.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopUnrollPass.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopVersioningLICM.h72
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/LowerAtomic.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/LowerExpectIntrinsic.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/LowerMatrixIntrinsics.h14
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/MemCpyOptimizer.h36
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/NaryReassociate.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/Reg2Mem.h76
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/SROA.h6
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h80
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h76
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/SimplifyCFG.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/StraightLineStrengthReduce.h70
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Scalar/StructurizeCFG.h62
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/BasicBlockUtils.h236
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/BuildLibCalls.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/CallGraphUpdater.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/Cloning.h86
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/Debugify.h124
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/FixIrreducible.h62
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/InstructionNamer.h62
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/Local.h48
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopPeel.h102
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopRotationUtils.h4
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopUtils.h144
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopVersioning.h26
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/LowerSwitch.h74
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/MatrixUtils.h210
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/MetaRenamer.h74
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/PredicateInfo.h38
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h940
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/SimplifyCFGOptions.h176
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/SimplifyIndVar.h46
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/SimplifyLibCalls.h2
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/StripGCRelocates.h72
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/StripNonLineTableDebugInfo.h74
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h20
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Utils/UnifyLoopExits.h66
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h114
-rw-r--r--contrib/libs/llvm12/include/llvm/Transforms/Vectorize/SLPVectorizer.h8
-rw-r--r--contrib/libs/llvm12/include/llvm/module.modulemap30
-rw-r--r--contrib/libs/llvm12/include/ya.make282
-rw-r--r--contrib/libs/llvm12/lib/Analysis/AliasAnalysis.cpp162
-rw-r--r--contrib/libs/llvm12/lib/Analysis/AliasAnalysisEvaluator.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Analysis/AliasSetTracker.cpp48
-rw-r--r--contrib/libs/llvm12/lib/Analysis/Analysis.cpp8
-rw-r--r--contrib/libs/llvm12/lib/Analysis/AssumeBundleQueries.cpp28
-rw-r--r--contrib/libs/llvm12/lib/Analysis/AssumptionCache.cpp24
-rw-r--r--contrib/libs/llvm12/lib/Analysis/BasicAliasAnalysis.cpp652
-rw-r--r--contrib/libs/llvm12/lib/Analysis/BranchProbabilityInfo.cpp1118
-rw-r--r--contrib/libs/llvm12/lib/Analysis/CFG.cpp22
-rw-r--r--contrib/libs/llvm12/lib/Analysis/CFGPrinter.cpp14
-rw-r--r--contrib/libs/llvm12/lib/Analysis/CFLAndersAliasAnalysis.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Analysis/CGSCCPassManager.cpp1024
-rw-r--r--contrib/libs/llvm12/lib/Analysis/CallGraph.cpp58
-rw-r--r--contrib/libs/llvm12/lib/Analysis/CallGraphSCCPass.cpp50
-rw-r--r--contrib/libs/llvm12/lib/Analysis/CallPrinter.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Analysis/CaptureTracking.cpp162
-rw-r--r--contrib/libs/llvm12/lib/Analysis/CodeMetrics.cpp20
-rw-r--r--contrib/libs/llvm12/lib/Analysis/ConstantFolding.cpp532
-rw-r--r--contrib/libs/llvm12/lib/Analysis/ConstraintSystem.cpp316
-rw-r--r--contrib/libs/llvm12/lib/Analysis/CostModel.cpp16
-rw-r--r--contrib/libs/llvm12/lib/Analysis/DDG.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Analysis/DDGPrinter.cpp300
-rw-r--r--contrib/libs/llvm12/lib/Analysis/Delinearization.cpp64
-rw-r--r--contrib/libs/llvm12/lib/Analysis/DemandedBits.cpp210
-rw-r--r--contrib/libs/llvm12/lib/Analysis/DependenceAnalysis.cpp68
-rw-r--r--contrib/libs/llvm12/lib/Analysis/DependenceGraphBuilder.cpp134
-rw-r--r--contrib/libs/llvm12/lib/Analysis/DevelopmentModeInlineAdvisor.cpp1062
-rw-r--r--contrib/libs/llvm12/lib/Analysis/DivergenceAnalysis.cpp260
-rw-r--r--contrib/libs/llvm12/lib/Analysis/DomTreeUpdater.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Analysis/EHPersonalities.cpp42
-rw-r--r--contrib/libs/llvm12/lib/Analysis/FunctionPropertiesAnalysis.cpp176
-rw-r--r--contrib/libs/llvm12/lib/Analysis/GlobalsModRef.cpp42
-rw-r--r--contrib/libs/llvm12/lib/Analysis/IRSimilarityIdentifier.cpp1874
-rw-r--r--contrib/libs/llvm12/lib/Analysis/IVDescriptors.cpp448
-rw-r--r--contrib/libs/llvm12/lib/Analysis/ImportedFunctionsInliningStatistics.cpp424
-rw-r--r--contrib/libs/llvm12/lib/Analysis/IndirectCallPromotionAnalysis.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Analysis/InlineAdvisor.cpp298
-rw-r--r--contrib/libs/llvm12/lib/Analysis/InlineCost.cpp464
-rw-r--r--contrib/libs/llvm12/lib/Analysis/InlineSizeEstimatorAnalysis.cpp126
-rw-r--r--contrib/libs/llvm12/lib/Analysis/InstCount.cpp108
-rw-r--r--contrib/libs/llvm12/lib/Analysis/InstructionSimplify.cpp1526
-rw-r--r--contrib/libs/llvm12/lib/Analysis/LazyCallGraph.cpp506
-rw-r--r--contrib/libs/llvm12/lib/Analysis/LazyValueInfo.cpp364
-rw-r--r--contrib/libs/llvm12/lib/Analysis/LegacyDivergenceAnalysis.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Analysis/Lint.cpp430
-rw-r--r--contrib/libs/llvm12/lib/Analysis/Loads.cpp128
-rw-r--r--contrib/libs/llvm12/lib/Analysis/LoopAccessAnalysis.cpp76
-rw-r--r--contrib/libs/llvm12/lib/Analysis/LoopAnalysisManager.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Analysis/LoopCacheAnalysis.cpp20
-rw-r--r--contrib/libs/llvm12/lib/Analysis/LoopInfo.cpp52
-rw-r--r--contrib/libs/llvm12/lib/Analysis/LoopNestAnalysis.cpp220
-rw-r--r--contrib/libs/llvm12/lib/Analysis/LoopPass.cpp36
-rw-r--r--contrib/libs/llvm12/lib/Analysis/MLInlineAdvisor.cpp78
-rw-r--r--contrib/libs/llvm12/lib/Analysis/MemDepPrinter.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Analysis/MemDerefPrinter.cpp68
-rw-r--r--contrib/libs/llvm12/lib/Analysis/MemoryBuiltins.cpp38
-rw-r--r--contrib/libs/llvm12/lib/Analysis/MemoryDependenceAnalysis.cpp86
-rw-r--r--contrib/libs/llvm12/lib/Analysis/MemoryLocation.cpp132
-rw-r--r--contrib/libs/llvm12/lib/Analysis/MemorySSA.cpp350
-rw-r--r--contrib/libs/llvm12/lib/Analysis/MemorySSAUpdater.cpp130
-rw-r--r--contrib/libs/llvm12/lib/Analysis/ModuleDebugInfoPrinter.cpp80
-rw-r--r--contrib/libs/llvm12/lib/Analysis/ModuleSummaryAnalysis.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Analysis/MustExecute.cpp144
-rw-r--r--contrib/libs/llvm12/lib/Analysis/ObjCARCAliasAnalysis.cpp18
-rw-r--r--contrib/libs/llvm12/lib/Analysis/ObjCARCAnalysisUtils.cpp40
-rw-r--r--contrib/libs/llvm12/lib/Analysis/OptimizationRemarkEmitter.cpp50
-rw-r--r--contrib/libs/llvm12/lib/Analysis/RegionPass.cpp66
-rw-r--r--contrib/libs/llvm12/lib/Analysis/ReleaseModeModelRunner.cpp180
-rw-r--r--contrib/libs/llvm12/lib/Analysis/ReplayInlineAdvisor.cpp164
-rw-r--r--contrib/libs/llvm12/lib/Analysis/ScalarEvolution.cpp2890
-rw-r--r--contrib/libs/llvm12/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp8
-rw-r--r--contrib/libs/llvm12/lib/Analysis/ScalarEvolutionDivision.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Analysis/ScopedNoAliasAA.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Analysis/StackLifetime.cpp114
-rw-r--r--contrib/libs/llvm12/lib/Analysis/StackSafetyAnalysis.cpp360
-rw-r--r--contrib/libs/llvm12/lib/Analysis/SyncDependenceAnalysis.cpp568
-rw-r--r--contrib/libs/llvm12/lib/Analysis/TFUtils.cpp572
-rw-r--r--contrib/libs/llvm12/lib/Analysis/TargetLibraryInfo.cpp70
-rw-r--r--contrib/libs/llvm12/lib/Analysis/TargetTransformInfo.cpp304
-rw-r--r--contrib/libs/llvm12/lib/Analysis/TypeBasedAliasAnalysis.cpp164
-rw-r--r--contrib/libs/llvm12/lib/Analysis/VFABIDemangling.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Analysis/ValueTracking.cpp1744
-rw-r--r--contrib/libs/llvm12/lib/Analysis/VectorUtils.cpp106
-rw-r--r--contrib/libs/llvm12/lib/Analysis/ya.make34
-rw-r--r--contrib/libs/llvm12/lib/AsmParser/LLLexer.cpp16
-rw-r--r--contrib/libs/llvm12/lib/AsmParser/LLParser.cpp4012
-rw-r--r--contrib/libs/llvm12/lib/AsmParser/LLParser.h440
-rw-r--r--contrib/libs/llvm12/lib/AsmParser/LLToken.h14
-rw-r--r--contrib/libs/llvm12/lib/AsmParser/ya.make10
-rw-r--r--contrib/libs/llvm12/lib/BinaryFormat/Dwarf.cpp50
-rw-r--r--contrib/libs/llvm12/lib/BinaryFormat/MachO.cpp6
-rw-r--r--contrib/libs/llvm12/lib/BinaryFormat/MsgPackDocument.cpp4
-rw-r--r--contrib/libs/llvm12/lib/BinaryFormat/Wasm.cpp8
-rw-r--r--contrib/libs/llvm12/lib/BinaryFormat/XCOFF.cpp156
-rw-r--r--contrib/libs/llvm12/lib/BinaryFormat/ya.make4
-rw-r--r--contrib/libs/llvm12/lib/Bitcode/Reader/BitcodeAnalyzer.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Bitcode/Reader/BitcodeReader.cpp406
-rw-r--r--contrib/libs/llvm12/lib/Bitcode/Reader/MetadataLoader.cpp318
-rw-r--r--contrib/libs/llvm12/lib/Bitcode/Reader/ya.make10
-rw-r--r--contrib/libs/llvm12/lib/Bitcode/Writer/BitcodeWriter.cpp314
-rw-r--r--contrib/libs/llvm12/lib/Bitcode/Writer/ValueEnumerator.cpp62
-rw-r--r--contrib/libs/llvm12/lib/Bitcode/Writer/ya.make14
-rw-r--r--contrib/libs/llvm12/lib/Bitstream/Reader/BitstreamReader.cpp12
-rw-r--r--contrib/libs/llvm12/lib/Bitstream/Reader/ya.make4
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AllocationOrder.cpp16
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AllocationOrder.h158
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/Analysis.cpp54
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AIXException.cpp158
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AccelTable.cpp16
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AddressPool.cpp2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AddressPool.h2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AsmPrinter.cpp732
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp84
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp48
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/ByteStreamer.h8
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp256
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/CodeViewDebug.h14
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DIE.cpp118
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DIEHash.cpp20
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DIEHash.h6
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp368
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp144
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp8
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp110
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h14
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfDebug.cpp522
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfDebug.h112
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfException.h28
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfExpression.cpp80
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfExpression.h18
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfFile.cpp14
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfFile.h4
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp8
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfStringPool.h2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfUnit.cpp292
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfUnit.h26
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/EHStreamer.cpp598
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/EHStreamer.h68
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp8
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp168
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/PseudoProbePrinter.h106
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WasmException.cpp12
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WasmException.h2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WinCFGuard.cpp82
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WinCFGuard.h2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WinException.cpp64
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AsmPrinter/ya.make34
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/AtomicExpandPass.cpp22
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/BasicBlockSections.cpp968
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/BranchFolding.cpp12
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/BranchFolding.h2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/BranchRelaxation.cpp48
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/BreakFalseDeps.cpp38
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/CalcSpillWeights.cpp296
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/CallingConvLower.cpp32
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/CodeGen.cpp6
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/CodeGenPassBuilder.cpp50
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/CodeGenPrepare.cpp494
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/CommandFlags.cpp184
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/DeadMachineInstructionElim.cpp32
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/DetectDeadLanes.cpp2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/DwarfEHPrepare.cpp290
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/EarlyIfConversion.cpp196
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/ExpandReductions.cpp140
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/FixupStatepointCallerSaved.cpp668
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GCRootLowering.cpp8
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/CSEInfo.cpp36
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/CSEMIRBuilder.cpp64
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/CallLowering.cpp886
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/Combiner.cpp6
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/CombinerHelper.cpp3832
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/GISelChangeObserver.cpp2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/GISelKnownBits.cpp356
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/IRTranslator.cpp1642
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp12
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/InstructionSelect.cpp2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/InstructionSelector.cpp2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalityPredicates.cpp34
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalizeMutations.cpp20
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/Legalizer.cpp2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalizerHelper.cpp2534
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalizerInfo.cpp8
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/Localizer.cpp46
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp216
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/Utils.cpp656
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalISel/ya.make20
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/GlobalMerge.cpp6
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/HardwareLoops.cpp58
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/IfConversion.cpp6
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/ImplicitNullChecks.cpp356
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/InlineSpiller.cpp166
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/InterferenceCache.cpp6
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/InterferenceCache.h16
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/InterleavedAccessPass.cpp194
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/InterleavedLoadCombinePass.cpp18
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/IntrinsicLowering.cpp2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/LLVMTargetMachine.cpp78
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/LexicalScopes.cpp2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp6726
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp194
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/LiveDebugValues.h64
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp3988
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/LiveDebugVariables.cpp120
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/LiveInterval.cpp24
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/LiveIntervalCalc.cpp6
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/LiveIntervalUnion.cpp26
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/LiveIntervals.cpp88
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/LiveRangeEdit.cpp28
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/LiveRangeShrink.cpp4
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/LiveRegMatrix.cpp62
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/LiveVariables.cpp60
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/LocalStackSlotAllocation.cpp12
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/LowLevelType.cpp32
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/LowerEmuTLS.cpp4
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MBFIWrapper.cpp24
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MIRCanonicalizerPass.cpp12
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MIRParser/MILexer.cpp14
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MIRParser/MILexer.h4
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MIRParser/MIParser.cpp50
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MIRParser/MIRParser.cpp68
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MIRParser/ya.make18
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MIRPrinter.cpp118
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MIRVRegNamerUtils.cpp28
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineBasicBlock.cpp338
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineBlockFrequencyInfo.cpp20
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineBlockPlacement.cpp118
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineCSE.cpp46
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineCheckDebugify.cpp252
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineCombiner.cpp132
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineCopyPropagation.cpp146
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineDebugify.cpp62
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineFunction.cpp152
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineFunctionPrinterPass.cpp4
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineFunctionSplitter.cpp310
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineInstr.cpp238
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineLICM.cpp164
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineLoopInfo.cpp112
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineModuleInfo.cpp44
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineOperand.cpp42
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineOutliner.cpp18
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachinePassManager.cpp242
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachinePipeliner.cpp60
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineRegisterInfo.cpp10
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineSSAUpdater.cpp14
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineScheduler.cpp360
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineSink.cpp512
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineStableHash.cpp388
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineTraceMetrics.cpp28
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineVerifier.cpp542
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MultiHazardRecognizer.cpp184
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/PHIElimination.cpp110
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/PHIEliminationUtils.cpp2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/ParallelCG.cpp4
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/PeepholeOptimizer.cpp158
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/PostRAHazardRecognizer.cpp6
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/PreISelIntrinsicLowering.cpp2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/PrologEpilogInserter.cpp62
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/PseudoProbeInserter.cpp190
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/RDFLiveness.cpp210
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/RDFRegisters.cpp36
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/ReachingDefAnalysis.cpp220
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/RegAllocBase.cpp36
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/RegAllocBase.h4
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/RegAllocBasic.cpp58
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/RegAllocFast.cpp1698
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/RegAllocGreedy.cpp550
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/RegAllocPBQP.cpp124
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/RegisterClassInfo.cpp20
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/RegisterCoalescer.cpp348
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/RegisterCoalescer.h16
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/RegisterPressure.cpp82
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/RegisterScavenging.cpp24
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/RenameIndependentSubregs.cpp10
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SafeStack.cpp36
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SafeStackLayout.cpp8
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/ScheduleDAGInstrs.cpp18
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/ScheduleDAGPrinter.cpp2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/DAGCombiner.cpp3020
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/FastISel.cpp142
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp8
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/InstrEmitter.cpp202
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/InstrEmitter.h22
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp882
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp432
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp680
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp20
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeTypes.h84
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp12
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp46
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp1334
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp20
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp52
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAG.cpp1186
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp42
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp932
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h16
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp100
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp212
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/StatepointLowering.cpp492
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/TargetLowering.cpp1614
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ya.make18
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/ShrinkWrap.cpp8
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SjLjEHPrepare.cpp2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SplitKit.cpp80
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SplitKit.h20
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/StackColoring.cpp102
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/StackMaps.cpp340
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/StackProtector.cpp66
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/StackSlotColoring.cpp18
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SwiftErrorValueTracking.cpp4
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/SwitchLoweringUtils.cpp6
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/TailDuplicator.cpp2
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/TargetFrameLoweringImpl.cpp12
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/TargetInstrInfo.cpp74
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/TargetLoweringBase.cpp394
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/TargetLoweringObjectFileImpl.cpp628
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/TargetOptionsImpl.cpp12
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/TargetPassConfig.cpp468
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/TargetRegisterInfo.cpp104
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/TargetSubtargetInfo.cpp10
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/TwoAddressInstructionPass.cpp276
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/TypePromotion.cpp12
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/ValueTypes.cpp66
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/VirtRegMap.cpp18
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/WasmEHPrepare.cpp32
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/WinEHPrepare.cpp4
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/XRayInstrumentation.cpp14
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/ya.make46
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp6
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/EnumTables.cpp22
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp10
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordName.cpp10
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordSerialization.cpp2
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp4
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeRecordMapping.cpp2
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeStreamMerger.cpp2
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/ya.make6
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAddressRange.cpp6
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp8
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFContext.cpp122
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp16
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp20
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp4
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp72
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp4
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLine.cpp92
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp14
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp20
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp14
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp148
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDie.cpp94
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFExpression.cpp34
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFFormValue.cpp24
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp4
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFListTable.cpp10
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp8
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFUnit.cpp148
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFVerifier.cpp84
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/ya.make10
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/MSF/MSFBuilder.cpp4
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/MSF/ya.make4
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp116
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp18
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp2
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp2
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumSymbols.cpp82
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp184
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeInlineSiteSymbol.cpp354
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp8
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp2
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSession.cpp156
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp2
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp2
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolCache.cpp156
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp92
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDB.cpp2
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBContext.cpp74
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBExtras.cpp30
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp4
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbol.cpp34
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/UDTLayout.cpp8
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/ya.make16
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/Symbolize/DIPrinter.cpp8
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h6
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/Symbolize/Symbolize.cpp16
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/Symbolize/ya.make12
-rw-r--r--contrib/libs/llvm12/lib/Demangle/Demangle.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Demangle/ya.make2
-rw-r--r--contrib/libs/llvm12/lib/ExecutionEngine/ExecutionEngine.cpp4
-rw-r--r--contrib/libs/llvm12/lib/ExecutionEngine/MCJIT/MCJIT.h10
-rw-r--r--contrib/libs/llvm12/lib/ExecutionEngine/MCJIT/ya.make16
-rw-r--r--contrib/libs/llvm12/lib/ExecutionEngine/PerfJITEvents/ya.make16
-rw-r--r--contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp4
-rw-r--r--contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp40
-rw-r--r--contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp4
-rw-r--r--contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp22
-rw-r--r--contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h10
-rw-r--r--contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h8
-rw-r--r--contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/ya.make12
-rw-r--r--contrib/libs/llvm12/lib/ExecutionEngine/SectionMemoryManager.cpp26
-rw-r--r--contrib/libs/llvm12/lib/ExecutionEngine/ya.make16
-rw-r--r--contrib/libs/llvm12/lib/Frontend/OpenMP/OMPContext.cpp60
-rw-r--r--contrib/libs/llvm12/lib/Frontend/OpenMP/OMPIRBuilder.cpp1602
-rw-r--r--contrib/libs/llvm12/lib/Frontend/OpenMP/ya.make10
-rw-r--r--contrib/libs/llvm12/lib/IR/AsmWriter.cpp262
-rw-r--r--contrib/libs/llvm12/lib/IR/Assumptions.cpp72
-rw-r--r--contrib/libs/llvm12/lib/IR/AttributeImpl.h12
-rw-r--r--contrib/libs/llvm12/lib/IR/Attributes.cpp352
-rw-r--r--contrib/libs/llvm12/lib/IR/AutoUpgrade.cpp652
-rw-r--r--contrib/libs/llvm12/lib/IR/BasicBlock.cpp162
-rw-r--r--contrib/libs/llvm12/lib/IR/ConstantFold.cpp226
-rw-r--r--contrib/libs/llvm12/lib/IR/ConstantRange.cpp188
-rw-r--r--contrib/libs/llvm12/lib/IR/Constants.cpp618
-rw-r--r--contrib/libs/llvm12/lib/IR/Core.cpp102
-rw-r--r--contrib/libs/llvm12/lib/IR/DIBuilder.cpp78
-rw-r--r--contrib/libs/llvm12/lib/IR/DataLayout.cpp476
-rw-r--r--contrib/libs/llvm12/lib/IR/DebugInfo.cpp68
-rw-r--r--contrib/libs/llvm12/lib/IR/DebugInfoMetadata.cpp252
-rw-r--r--contrib/libs/llvm12/lib/IR/DebugLoc.cpp4
-rw-r--r--contrib/libs/llvm12/lib/IR/DiagnosticInfo.cpp30
-rw-r--r--contrib/libs/llvm12/lib/IR/Dominators.cpp40
-rw-r--r--contrib/libs/llvm12/lib/IR/Function.cpp224
-rw-r--r--contrib/libs/llvm12/lib/IR/Globals.cpp12
-rw-r--r--contrib/libs/llvm12/lib/IR/IRBuilder.cpp190
-rw-r--r--contrib/libs/llvm12/lib/IR/IRPrintingPasses.cpp6
-rw-r--r--contrib/libs/llvm12/lib/IR/Instruction.cpp56
-rw-r--r--contrib/libs/llvm12/lib/IR/Instructions.cpp404
-rw-r--r--contrib/libs/llvm12/lib/IR/IntrinsicInst.cpp38
-rw-r--r--contrib/libs/llvm12/lib/IR/LLVMContext.cpp14
-rw-r--r--contrib/libs/llvm12/lib/IR/LLVMContextImpl.cpp36
-rw-r--r--contrib/libs/llvm12/lib/IR/LLVMContextImpl.h284
-rw-r--r--contrib/libs/llvm12/lib/IR/LLVMRemarkStreamer.cpp14
-rw-r--r--contrib/libs/llvm12/lib/IR/LegacyPassManager.cpp96
-rw-r--r--contrib/libs/llvm12/lib/IR/MDBuilder.cpp26
-rw-r--r--contrib/libs/llvm12/lib/IR/Mangler.cpp62
-rw-r--r--contrib/libs/llvm12/lib/IR/Metadata.cpp418
-rw-r--r--contrib/libs/llvm12/lib/IR/Module.cpp2
-rw-r--r--contrib/libs/llvm12/lib/IR/ModuleSummaryIndex.cpp48
-rw-r--r--contrib/libs/llvm12/lib/IR/Operator.cpp28
-rw-r--r--contrib/libs/llvm12/lib/IR/OptBisect.cpp4
-rw-r--r--contrib/libs/llvm12/lib/IR/Pass.cpp14
-rw-r--r--contrib/libs/llvm12/lib/IR/PassInstrumentation.cpp38
-rw-r--r--contrib/libs/llvm12/lib/IR/PassManager.cpp96
-rw-r--r--contrib/libs/llvm12/lib/IR/PassRegistry.cpp4
-rw-r--r--contrib/libs/llvm12/lib/IR/PassTimingInfo.cpp68
-rw-r--r--contrib/libs/llvm12/lib/IR/PrintPasses.cpp176
-rw-r--r--contrib/libs/llvm12/lib/IR/ProfileSummary.cpp2
-rw-r--r--contrib/libs/llvm12/lib/IR/PseudoProbe.cpp198
-rw-r--r--contrib/libs/llvm12/lib/IR/ReplaceConstant.cpp140
-rw-r--r--contrib/libs/llvm12/lib/IR/SafepointIRVerifier.cpp2
-rw-r--r--contrib/libs/llvm12/lib/IR/StructuralHash.cpp168
-rw-r--r--contrib/libs/llvm12/lib/IR/Type.cpp90
-rw-r--r--contrib/libs/llvm12/lib/IR/Use.cpp18
-rw-r--r--contrib/libs/llvm12/lib/IR/User.cpp2
-rw-r--r--contrib/libs/llvm12/lib/IR/Value.cpp128
-rw-r--r--contrib/libs/llvm12/lib/IR/Verifier.cpp602
-rw-r--r--contrib/libs/llvm12/lib/IR/ya.make20
-rw-r--r--contrib/libs/llvm12/lib/IRReader/IRReader.cpp8
-rw-r--r--contrib/libs/llvm12/lib/IRReader/ya.make12
-rw-r--r--contrib/libs/llvm12/lib/Linker/IRMover.cpp170
-rw-r--r--contrib/libs/llvm12/lib/Linker/LinkModules.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Linker/ya.make12
-rw-r--r--contrib/libs/llvm12/lib/MC/ELFObjectWriter.cpp60
-rw-r--r--contrib/libs/llvm12/lib/MC/MCAsmBackend.cpp22
-rw-r--r--contrib/libs/llvm12/lib/MC/MCAsmInfo.cpp18
-rw-r--r--contrib/libs/llvm12/lib/MC/MCAsmInfoXCOFF.cpp18
-rw-r--r--contrib/libs/llvm12/lib/MC/MCAsmMacro.cpp10
-rw-r--r--contrib/libs/llvm12/lib/MC/MCAsmStreamer.cpp236
-rw-r--r--contrib/libs/llvm12/lib/MC/MCAssembler.cpp174
-rw-r--r--contrib/libs/llvm12/lib/MC/MCCodeView.cpp2
-rw-r--r--contrib/libs/llvm12/lib/MC/MCContext.cpp78
-rw-r--r--contrib/libs/llvm12/lib/MC/MCDisassembler/ya.make6
-rw-r--r--contrib/libs/llvm12/lib/MC/MCDwarf.cpp26
-rw-r--r--contrib/libs/llvm12/lib/MC/MCELFStreamer.cpp46
-rw-r--r--contrib/libs/llvm12/lib/MC/MCExpr.cpp196
-rw-r--r--contrib/libs/llvm12/lib/MC/MCFragment.cpp48
-rw-r--r--contrib/libs/llvm12/lib/MC/MCObjectFileInfo.cpp248
-rw-r--r--contrib/libs/llvm12/lib/MC/MCObjectStreamer.cpp172
-rw-r--r--contrib/libs/llvm12/lib/MC/MCParser/AsmLexer.cpp302
-rw-r--r--contrib/libs/llvm12/lib/MC/MCParser/AsmParser.cpp228
-rw-r--r--contrib/libs/llvm12/lib/MC/MCParser/COFFAsmParser.cpp18
-rw-r--r--contrib/libs/llvm12/lib/MC/MCParser/COFFMasmParser.cpp148
-rw-r--r--contrib/libs/llvm12/lib/MC/MCParser/DarwinAsmParser.cpp2
-rw-r--r--contrib/libs/llvm12/lib/MC/MCParser/ELFAsmParser.cpp24
-rw-r--r--contrib/libs/llvm12/lib/MC/MCParser/MasmParser.cpp2332
-rw-r--r--contrib/libs/llvm12/lib/MC/MCParser/WasmAsmParser.cpp120
-rw-r--r--contrib/libs/llvm12/lib/MC/MCParser/ya.make6
-rw-r--r--contrib/libs/llvm12/lib/MC/MCPseudoProbe.cpp426
-rw-r--r--contrib/libs/llvm12/lib/MC/MCSchedule.cpp4
-rw-r--r--contrib/libs/llvm12/lib/MC/MCSection.cpp4
-rw-r--r--contrib/libs/llvm12/lib/MC/MCSectionELF.cpp12
-rw-r--r--contrib/libs/llvm12/lib/MC/MCSectionMachO.cpp20
-rw-r--r--contrib/libs/llvm12/lib/MC/MCSectionWasm.cpp18
-rw-r--r--contrib/libs/llvm12/lib/MC/MCSectionXCOFF.cpp2
-rw-r--r--contrib/libs/llvm12/lib/MC/MCStreamer.cpp114
-rw-r--r--contrib/libs/llvm12/lib/MC/MCSubtargetInfo.cpp58
-rw-r--r--contrib/libs/llvm12/lib/MC/MCSymbolXCOFF.cpp8
-rw-r--r--contrib/libs/llvm12/lib/MC/MCWin64EH.cpp938
-rw-r--r--contrib/libs/llvm12/lib/MC/MCWinCOFFStreamer.cpp22
-rw-r--r--contrib/libs/llvm12/lib/MC/StringTableBuilder.cpp30
-rw-r--r--contrib/libs/llvm12/lib/MC/WasmObjectWriter.cpp1106
-rw-r--r--contrib/libs/llvm12/lib/MC/WinCOFFObjectWriter.cpp6
-rw-r--r--contrib/libs/llvm12/lib/MC/XCOFFObjectWriter.cpp40
-rw-r--r--contrib/libs/llvm12/lib/MC/ya.make10
-rw-r--r--contrib/libs/llvm12/lib/Object/Archive.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Object/ArchiveWriter.cpp222
-rw-r--r--contrib/libs/llvm12/lib/Object/Binary.cpp12
-rw-r--r--contrib/libs/llvm12/lib/Object/COFFObjectFile.cpp114
-rw-r--r--contrib/libs/llvm12/lib/Object/ELF.cpp80
-rw-r--r--contrib/libs/llvm12/lib/Object/ELFObjectFile.cpp284
-rw-r--r--contrib/libs/llvm12/lib/Object/MachOObjectFile.cpp66
-rw-r--r--contrib/libs/llvm12/lib/Object/MachOUniversal.cpp58
-rw-r--r--contrib/libs/llvm12/lib/Object/MachOUniversalWriter.cpp674
-rw-r--r--contrib/libs/llvm12/lib/Object/ObjectFile.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Object/RelocationResolver.cpp366
-rw-r--r--contrib/libs/llvm12/lib/Object/SymbolSize.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Object/SymbolicFile.cpp86
-rw-r--r--contrib/libs/llvm12/lib/Object/WasmObjectFile.cpp476
-rw-r--r--contrib/libs/llvm12/lib/Object/XCOFFObjectFile.cpp600
-rw-r--r--contrib/libs/llvm12/lib/Object/ya.make20
-rw-r--r--contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMapping.cpp60
-rw-r--r--contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMappingReader.cpp94
-rw-r--r--contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMappingWriter.cpp28
-rw-r--r--contrib/libs/llvm12/lib/ProfileData/Coverage/ya.make10
-rw-r--r--contrib/libs/llvm12/lib/ProfileData/GCOV.cpp1006
-rw-r--r--contrib/libs/llvm12/lib/ProfileData/InstrProf.cpp24
-rw-r--r--contrib/libs/llvm12/lib/ProfileData/InstrProfReader.cpp42
-rw-r--r--contrib/libs/llvm12/lib/ProfileData/InstrProfWriter.cpp18
-rw-r--r--contrib/libs/llvm12/lib/ProfileData/ProfileSummaryBuilder.cpp88
-rw-r--r--contrib/libs/llvm12/lib/ProfileData/SampleProf.cpp152
-rw-r--r--contrib/libs/llvm12/lib/ProfileData/SampleProfReader.cpp508
-rw-r--r--contrib/libs/llvm12/lib/ProfileData/SampleProfWriter.cpp404
-rw-r--r--contrib/libs/llvm12/lib/ProfileData/ya.make10
-rw-r--r--contrib/libs/llvm12/lib/Remarks/BitstreamRemarkParser.h6
-rw-r--r--contrib/libs/llvm12/lib/Remarks/ya.make6
-rw-r--r--contrib/libs/llvm12/lib/Support/AArch64TargetParser.cpp26
-rw-r--r--contrib/libs/llvm12/lib/Support/AMDGPUMetadata.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Support/APFixedPoint.cpp1148
-rw-r--r--contrib/libs/llvm12/lib/Support/APFloat.cpp98
-rw-r--r--contrib/libs/llvm12/lib/Support/APInt.cpp18
-rw-r--r--contrib/libs/llvm12/lib/Support/ARMAttributeParser.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Support/ARMTargetParser.cpp40
-rw-r--r--contrib/libs/llvm12/lib/Support/CRC.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Support/CachePruning.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Support/CommandLine.cpp90
-rw-r--r--contrib/libs/llvm12/lib/Support/Compression.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Support/ConvertUTFWrapper.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Support/CrashRecoveryContext.cpp66
-rw-r--r--contrib/libs/llvm12/lib/Support/DebugCounter.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Support/DynamicLibrary.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Support/ELFAttributeParser.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Support/Error.cpp8
-rw-r--r--contrib/libs/llvm12/lib/Support/ErrorHandling.cpp14
-rw-r--r--contrib/libs/llvm12/lib/Support/FileCollector.cpp158
-rw-r--r--contrib/libs/llvm12/lib/Support/FormatVariadic.cpp22
-rw-r--r--contrib/libs/llvm12/lib/Support/Host.cpp388
-rw-r--r--contrib/libs/llvm12/lib/Support/InitLLVM.cpp18
-rw-r--r--contrib/libs/llvm12/lib/Support/InstructionCost.cpp48
-rw-r--r--contrib/libs/llvm12/lib/Support/JSON.cpp412
-rw-r--r--contrib/libs/llvm12/lib/Support/KnownBits.cpp794
-rw-r--r--contrib/libs/llvm12/lib/Support/LineIterator.cpp12
-rw-r--r--contrib/libs/llvm12/lib/Support/LowLevelType.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Support/MemoryBufferRef.cpp38
-rw-r--r--contrib/libs/llvm12/lib/Support/Path.cpp64
-rw-r--r--contrib/libs/llvm12/lib/Support/PrettyStackTrace.cpp22
-rw-r--r--contrib/libs/llvm12/lib/Support/Process.cpp28
-rw-r--r--contrib/libs/llvm12/lib/Support/Program.cpp18
-rw-r--r--contrib/libs/llvm12/lib/Support/SHA1.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Support/Signals.cpp14
-rw-r--r--contrib/libs/llvm12/lib/Support/Signposts.cpp42
-rw-r--r--contrib/libs/llvm12/lib/Support/SmallVector.cpp118
-rw-r--r--contrib/libs/llvm12/lib/Support/SourceMgr.cpp76
-rw-r--r--contrib/libs/llvm12/lib/Support/TargetParser.cpp166
-rw-r--r--contrib/libs/llvm12/lib/Support/Timer.cpp20
-rw-r--r--contrib/libs/llvm12/lib/Support/TrigramIndex.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Support/Triple.cpp132
-rw-r--r--contrib/libs/llvm12/lib/Support/Unicode.cpp22
-rw-r--r--contrib/libs/llvm12/lib/Support/Unix/Path.inc142
-rw-r--r--contrib/libs/llvm12/lib/Support/Unix/Process.inc6
-rw-r--r--contrib/libs/llvm12/lib/Support/Unix/Program.inc10
-rw-r--r--contrib/libs/llvm12/lib/Support/Unix/Signals.inc36
-rw-r--r--contrib/libs/llvm12/lib/Support/Unix/Threading.inc16
-rw-r--r--contrib/libs/llvm12/lib/Support/VirtualFileSystem.cpp254
-rw-r--r--contrib/libs/llvm12/lib/Support/Windows/Path.inc112
-rw-r--r--contrib/libs/llvm12/lib/Support/Windows/Process.inc4
-rw-r--r--contrib/libs/llvm12/lib/Support/Windows/Program.inc78
-rw-r--r--contrib/libs/llvm12/lib/Support/Windows/Signals.inc8
-rw-r--r--contrib/libs/llvm12/lib/Support/Windows/Threading.inc38
-rw-r--r--contrib/libs/llvm12/lib/Support/X86TargetParser.cpp416
-rw-r--r--contrib/libs/llvm12/lib/Support/YAMLParser.cpp232
-rw-r--r--contrib/libs/llvm12/lib/Support/YAMLTraits.cpp108
-rw-r--r--contrib/libs/llvm12/lib/Support/raw_ostream.cpp112
-rw-r--r--contrib/libs/llvm12/lib/Support/ya.make10
-rw-r--r--contrib/libs/llvm12/lib/TableGen/DetailedRecordsBackend.cpp406
-rw-r--r--contrib/libs/llvm12/lib/TableGen/Error.cpp162
-rw-r--r--contrib/libs/llvm12/lib/TableGen/JSONBackend.cpp2
-rw-r--r--contrib/libs/llvm12/lib/TableGen/Main.cpp62
-rw-r--r--contrib/libs/llvm12/lib/TableGen/Record.cpp792
-rw-r--r--contrib/libs/llvm12/lib/TableGen/TGLexer.cpp80
-rw-r--r--contrib/libs/llvm12/lib/TableGen/TGLexer.h40
-rw-r--r--contrib/libs/llvm12/lib/TableGen/TGParser.cpp1028
-rw-r--r--contrib/libs/llvm12/lib/TableGen/TGParser.h10
-rw-r--r--contrib/libs/llvm12/lib/TableGen/TableGenBackendSkeleton.cpp128
-rw-r--r--contrib/libs/llvm12/lib/TableGen/ya.make8
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64.h12
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64.td352
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64AdvSIMDScalarPass.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64AsmPrinter.cpp510
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64BranchTargets.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.cpp100
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td122
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64CompressJumpTables.cpp62
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp88
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64FalkorHWPFFix.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64FastISel.cpp12
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64FrameLowering.cpp790
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64FrameLowering.h40
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp126
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64ISelLowering.cpp5278
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64ISelLowering.h216
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrFormats.td202
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrGISel.td120
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrInfo.cpp784
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrInfo.h96
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrInfo.td544
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp66
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64MCInstLower.cpp12
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp164
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64MachineFunctionInfo.h108
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64MacroFusion.cpp26
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64RegisterInfo.cpp166
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64RegisterInfo.h30
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64RegisterInfo.td52
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64SIMDInstrOpt.cpp12
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64SVEInstrInfo.td842
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA55.td678
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA57.td82
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA57WriteRes.td38
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA64FX.td7780
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedTSV110.td1490
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp8
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64StackTagging.cpp26
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64StackTaggingPreRA.cpp332
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64Subtarget.cpp36
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64Subtarget.h84
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64SystemOperands.td330
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetMachine.cpp70
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetMachine.h12
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetTransformInfo.cpp356
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetTransformInfo.h66
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp1118
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/AsmParser/ya.make22
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp86
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/Disassembler/ya.make22
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64CallLowering.cpp64
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64CallLowering.h6
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.h58
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp2062
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp454
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h4
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp374
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp1408
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PostSelectOptimize.cpp374
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp20
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp150
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.h18
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h8
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp110
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp62
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h14
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h4
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp12
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp112
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h36
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp72
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/ya.make20
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/SVEInstrFormats.td726
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/SVEIntrinsicOpts.cpp86
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/TargetInfo/ya.make8
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp16
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/Utils/AArch64BaseInfo.h36
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/Utils/ya.make12
-rw-r--r--contrib/libs/llvm12/lib/Target/AArch64/ya.make42
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/A15SDOptimizer.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARM.h10
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARM.td180
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMAsmPrinter.cpp92
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMBaseInstrInfo.cpp1210
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMBaseInstrInfo.h300
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMBaseRegisterInfo.cpp30
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMBaseRegisterInfo.h12
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMBlockPlacement.cpp456
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMCallLowering.cpp64
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMCallLowering.h8
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMConstantIslandPass.cpp132
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMExpandPseudoInsts.cpp164
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMFastISel.cpp24
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMFeatures.h2
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMFrameLowering.cpp12
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMFrameLowering.h6
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMHazardRecognizer.cpp358
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMHazardRecognizer.h68
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMISelLowering.cpp1156
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMISelLowering.h54
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td6
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMInstrInfo.td148
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMInstrMVE.td970
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMInstrNEON.td144
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMInstrThumb.td22
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMInstrThumb2.td92
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMInstrVFP.td46
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMLegalizerInfo.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMLoadStoreOptimizer.cpp728
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMLowOverheadLoops.cpp1660
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMParallelDSP.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMPredicates.td10
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMRegisterBankInfo.cpp14
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMRegisterInfo.td34
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMSLSHardening.cpp832
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMSchedule.td108
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMScheduleA57.td142
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMScheduleA57WriteRes.td14
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMScheduleA9.td4
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMScheduleM7.td976
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMScheduleR52.td4
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMScheduleSwift.td4
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMSubtarget.cpp18
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMSubtarget.h36
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMTargetMachine.cpp34
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMTargetMachine.h12
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMTargetTransformInfo.cpp1352
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ARMTargetTransformInfo.h64
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/AsmParser/ARMAsmParser.cpp36
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/AsmParser/ya.make22
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/Disassembler/ARMDisassembler.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/Disassembler/ya.make20
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h52
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h2
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h2
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp262
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h32
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ya.make22
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/MVEGatherScatterLowering.cpp428
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/MVETailPredUtils.h314
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/MVETailPredication.cpp322
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/MVEVPTBlockPass.cpp54
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/MVEVPTOptimisationsPass.cpp888
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/TargetInfo/ya.make8
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/Thumb2InstrInfo.cpp94
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/Thumb2InstrInfo.h16
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/Thumb2SizeReduction.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/Utils/ya.make12
-rw-r--r--contrib/libs/llvm12/lib/Target/ARM/ya.make42
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/AsmParser/ya.make20
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/BPF.h66
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/BPFAbstractMemberAccess.cpp510
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/BPFAdjustOpt.cpp646
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/BPFCORE.h60
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/BPFCheckAndAdjustIR.cpp260
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/BPFInstrFormats.td22
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/BPFInstrInfo.td366
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/BPFMIChecking.cpp140
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/BPFMIPeephole.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/BPFPreserveDIType.cpp148
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/BPFSubtarget.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/BPFSubtarget.h2
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/BPFTargetMachine.cpp116
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/BPFTargetMachine.h12
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/BPFTargetTransformInfo.h122
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/BTF.def2
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/BTFDebug.cpp174
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/BTFDebug.h34
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/Disassembler/BPFDisassembler.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/Disassembler/ya.make16
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.h2
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp18
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/ya.make16
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/TargetInfo/ya.make8
-rw-r--r--contrib/libs/llvm12/lib/Target/BPF/ya.make38
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/NVPTXInstPrinter.h2
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/NVPTXMCAsmInfo.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/ya.make16
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTX.h38
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTXAsmPrinter.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTXFrameLowering.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTXFrameLowering.h6
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp8
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTXISelLowering.cpp36
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTXISelLowering.h4
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrFormats.td32
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrInfo.td36
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTXIntrinsics.td66
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTXLowerArgs.cpp12
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTXRegisterInfo.td4
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTXSubtarget.cpp8
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTXSubtarget.h2
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetMachine.cpp58
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetMachine.h4
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetTransformInfo.cpp514
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetTransformInfo.h6
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVVMIntrRange.cpp56
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/NVVMReflect.cpp28
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo/ya.make8
-rw-r--r--contrib/libs/llvm12/lib/Target/NVPTX/ya.make36
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp164
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/AsmParser/ya.make20
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp50
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/Disassembler/ya.make16
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCCallLowering.cpp106
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCCallLowering.h80
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp184
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp40
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCLegalizerInfo.h56
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp54
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h78
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBanks.td30
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp8
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp48
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp236
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.h14
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h6
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp216
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h114
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp100
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h22
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp38
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h16
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp16
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/ya.make18
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/P9InstrResources.td2
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPC.h98
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPC.td74
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCAsmPrinter.cpp1226
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCBoolRetToInt.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCCCState.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCCTRLoops.cpp60
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCCallingConv.td14
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCEarlyReturn.cpp32
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCFastISel.cpp32
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCFrameLowering.cpp528
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCISelDAGToDAG.cpp974
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCISelLowering.cpp3042
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCISelLowering.h154
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCInstr64Bit.td128
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrAltivec.td198
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrFormats.td4
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrHTM.td4
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrInfo.cpp1822
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrInfo.h160
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrInfo.td520
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrPrefix.td3378
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrVSX.td442
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp60
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCLowerMASSVEntries.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCMCInstLower.cpp26
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCMIPeephole.cpp284
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp68
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCMachineFunctionInfo.h62
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCMachineScheduler.cpp272
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCMacroFusion.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCPreEmitPeephole.cpp476
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCReduceCRLogicals.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCRegisterInfo.cpp262
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCRegisterInfo.h36
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCRegisterInfo.td180
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCScheduleP9.td10
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCSubtarget.cpp84
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCSubtarget.h52
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCTLSDynamicCall.cpp78
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetMachine.cpp132
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetMachine.h10
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetTransformInfo.cpp682
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetTransformInfo.h24
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCVSXFMAMutate.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp54
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.cpp16
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.h2
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo/ya.make8
-rw-r--r--contrib/libs/llvm12/lib/Target/PowerPC/ya.make44
-rw-r--r--contrib/libs/llvm12/lib/Target/README.txt8
-rw-r--r--contrib/libs/llvm12/lib/Target/TargetLoweringObjectFile.cpp118
-rw-r--r--contrib/libs/llvm12/lib/Target/TargetMachine.cpp46
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/AsmParser/X86AsmParser.cpp1938
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/AsmParser/ya.make20
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/Disassembler/X86Disassembler.cpp8
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/Disassembler/ya.make16
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp22
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.h2
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp46
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86BaseInfo.h34
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp18
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp38
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp20
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.h2
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp240
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp14
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h6
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ShuffleDecode.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86WinCOFFStreamer.cpp14
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/ya.make20
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/TargetInfo/ya.make8
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86.h14
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86.td988
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86AsmPrinter.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86AsmPrinter.h6
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86AvoidStoreForwardingBlocks.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86CallFrameOptimization.cpp22
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86CallLowering.cpp68
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86CallLowering.h8
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86CallingConv.cpp20
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td20
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86CmovConversion.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86DomainReassignment.cpp44
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86EvexToVex.cpp52
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86ExpandPseudo.cpp132
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86FastISel.cpp134
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86FixupBWInsts.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86FixupLEAs.cpp24
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86FixupSetCC.cpp22
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86FlagsCopyLowering.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86FrameLowering.cpp140
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86FrameLowering.h20
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86ISelDAGToDAG.cpp1026
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86ISelLowering.cpp6494
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86ISelLowering.h70
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86IndirectBranchTracking.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InsertPrefetch.cpp8
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InsertWait.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstCombineIntrinsic.cpp4034
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td84
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td304
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrArithmetic.td18
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrCompiler.td236
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrFMA.td22
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrFPStack.td8
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrFoldTables.cpp28
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrFormats.td12
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrFragmentsSIMD.td44
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrInfo.cpp374
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrInfo.h40
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrInfo.td232
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrKL.td172
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrMMX.td4
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrSNP.td94
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrSSE.td248
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrSVM.td38
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrSystem.td26
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstrTDX.td78
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InstructionSelector.cpp52
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86InterleavedAccess.cpp18
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86IntrinsicsInfo.h40
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86LegalizerInfo.cpp30
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp176
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86LoadValueInjectionRetHardening.cpp58
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86LowerAMXType.cpp702
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86MCInstLower.cpp82
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86PartialReduction.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86PreTileConfig.cpp530
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86RegisterInfo.cpp260
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86RegisterInfo.h22
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86RegisterInfo.td20
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86SelectionDAGInfo.cpp16
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86SpeculativeExecutionSideEffectSuppression.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86SpeculativeLoadHardening.cpp16
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86Subtarget.cpp64
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86Subtarget.h82
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86TargetMachine.cpp144
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86TargetMachine.h4
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86TargetObjectFile.h2
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86TargetTransformInfo.cpp604
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86TargetTransformInfo.h44
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86TileConfig.cpp496
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/X86WinEHState.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Target/X86/ya.make42
-rw-r--r--contrib/libs/llvm12/lib/Target/ya.make12
-rw-r--r--contrib/libs/llvm12/lib/TextAPI/MachO/Platform.cpp6
-rw-r--r--contrib/libs/llvm12/lib/TextAPI/MachO/Target.cpp2
-rw-r--r--contrib/libs/llvm12/lib/TextAPI/MachO/TextStub.cpp28
-rw-r--r--contrib/libs/llvm12/lib/TextAPI/MachO/TextStubCommon.cpp6
-rw-r--r--contrib/libs/llvm12/lib/TextAPI/MachO/ya.make60
-rw-r--r--contrib/libs/llvm12/lib/ToolDrivers/llvm-dlltool/ya.make14
-rw-r--r--contrib/libs/llvm12/lib/ToolDrivers/llvm-lib/LibDriver.cpp44
-rw-r--r--contrib/libs/llvm12/lib/ToolDrivers/llvm-lib/ya.make18
-rw-r--r--contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp182
-rw-r--r--contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine/ya.make12
-rw-r--r--contrib/libs/llvm12/lib/Transforms/CFGuard/ya.make8
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/AlwaysInliner.cpp96
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/Annotation2Metadata.cpp212
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/ArgumentPromotion.cpp48
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/Attributor.cpp880
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/AttributorAttributes.cpp2272
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/BlockExtractor.cpp104
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/ConstantMerge.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/DeadArgumentElimination.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/ForceFunctionAttrs.cpp72
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/FunctionAttrs.cpp364
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/FunctionImport.cpp52
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/GlobalOpt.cpp28
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/HotColdSplitting.cpp150
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/IPO.cpp8
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/IROutliner.cpp3528
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/Inliner.cpp64
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/LoopExtractor.cpp204
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/LowerTypeTests.cpp52
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/MergeFunctions.cpp8
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/OpenMPOpt.cpp2320
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/PartialInlining.cpp344
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/PassManagerBuilder.cpp224
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/PruneEH.cpp66
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/SampleContextTracker.cpp1170
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/SampleProfile.cpp1670
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/SampleProfileProbe.cpp868
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/StripSymbols.cpp90
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/WholeProgramDevirt.cpp28
-rw-r--r--contrib/libs/llvm12/lib/Transforms/IPO/ya.make44
-rw-r--r--contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineAddSub.cpp372
-rw-r--r--contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp880
-rw-r--r--contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp20
-rw-r--r--contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCalls.cpp774
-rw-r--r--contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCasts.cpp432
-rw-r--r--contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCompares.cpp524
-rw-r--r--contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineInternal.h106
-rw-r--r--contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp254
-rw-r--r--contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp222
-rw-r--r--contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineNegator.cpp206
-rw-r--r--contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombinePHI.cpp438
-rw-r--r--contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineSelect.cpp476
-rw-r--r--contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineShifts.cpp276
-rw-r--r--contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp264
-rw-r--r--contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineVectorOps.cpp730
-rw-r--r--contrib/libs/llvm12/lib/Transforms/InstCombine/InstructionCombining.cpp664
-rw-r--r--contrib/libs/llvm12/lib/Transforms/InstCombine/ya.make12
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/AddressSanitizer.cpp160
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/CFGMST.h18
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/CGProfile.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/ControlHeightReduction.cpp34
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp1272
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/GCOVProfiling.cpp788
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp348
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp16
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/InstrProfiling.cpp108
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/Instrumentation.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/MemProfiler.cpp1276
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/MemorySanitizer.cpp620
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/PGOInstrumentation.cpp566
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/PGOMemOPSizeOpt.cpp18
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/PoisonChecking.cpp12
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/SanitizerCoverage.cpp104
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/ThreadSanitizer.cpp250
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/ValueProfileCollector.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/ValueProfileCollector.h12
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Instrumentation/ya.make18
-rw-r--r--contrib/libs/llvm12/lib/Transforms/ObjCARC/DependencyAnalysis.cpp72
-rw-r--r--contrib/libs/llvm12/lib/Transforms/ObjCARC/DependencyAnalysis.h12
-rw-r--r--contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARC.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCAPElim.cpp84
-rw-r--r--contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCContract.cpp246
-rw-r--r--contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCExpand.cpp76
-rw-r--r--contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCOpts.cpp330
-rw-r--r--contrib/libs/llvm12/lib/Transforms/ObjCARC/ProvenanceAnalysis.cpp20
-rw-r--r--contrib/libs/llvm12/lib/Transforms/ObjCARC/ProvenanceAnalysis.h12
-rw-r--r--contrib/libs/llvm12/lib/Transforms/ObjCARC/ProvenanceAnalysisEvaluator.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Transforms/ObjCARC/PtrState.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Transforms/ObjCARC/ya.make12
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/ADCE.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp60
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/AnnotationRemarks.cpp180
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/CallSiteSplitting.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/ConstantHoisting.cpp16
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/ConstraintElimination.cpp814
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp448
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/DCE.cpp32
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/DeadStoreElimination.cpp1434
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/DivRemPairs.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/EarlyCSE.cpp658
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/FlattenCFGPass.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/GVN.cpp604
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/GVNHoist.cpp1484
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/GVNSink.cpp8
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/GuardWidening.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/IndVarSimplify.cpp394
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp150
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/InferAddressSpaces.cpp228
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/InstSimplifyPass.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/JumpThreading.cpp434
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LICM.cpp452
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopDataPrefetch.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopDeletion.cpp178
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopDistribute.cpp16
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopFlatten.cpp1456
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopFuse.cpp546
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopIdiomRecognize.cpp916
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopInterchange.cpp206
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopLoadElimination.cpp82
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopPassManager.cpp548
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopPredication.cpp16
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopRerollPass.cpp102
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopRotation.cpp70
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopSimplifyCFG.cpp34
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopSink.cpp242
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopStrengthReduce.cpp216
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopUnrollAndJamPass.cpp16
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopUnrollPass.cpp62
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopUnswitch.cpp564
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LoopVersioningLICM.cpp158
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp454
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/MemCpyOptimizer.cpp1194
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/MergeICmps.cpp24
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/NaryReassociate.cpp84
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/NewGVN.cpp58
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/PlaceSafepoints.cpp8
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/Reassociate.cpp220
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/Reg2Mem.cpp134
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp258
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/SCCP.cpp524
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/SROA.cpp404
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/Scalar.cpp44
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/ScalarizeMaskedMemIntrin.cpp1896
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/Scalarizer.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp126
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp118
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/SimplifyCFGPass.cpp256
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/Sink.cpp60
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/SpeculateAroundPHIs.cpp8
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/SpeculativeExecution.cpp16
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp138
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/StructurizeCFG.cpp224
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/TailRecursionElimination.cpp124
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/WarnMissedTransforms.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Scalar/ya.make24
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/AssumeBundleBuilder.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/BasicBlockUtils.cpp526
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/BreakCriticalEdges.cpp42
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/BuildLibCalls.cpp826
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/CallGraphUpdater.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/CallPromotionUtils.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/CloneFunction.cpp270
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/CloneModule.cpp16
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/CodeExtractor.cpp104
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/CodeMoverUtils.cpp42
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/Debugify.cpp166
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/EntryExitInstrumenter.cpp8
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/EscapeEnumerator.cpp8
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/Evaluator.cpp14
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/FixIrreducible.cpp46
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/FunctionComparator.cpp32
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/GlobalStatus.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/GuardUtils.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/InjectTLIMappings.cpp6
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/InlineFunction.cpp310
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/InstructionNamer.cpp74
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/LCSSA.cpp100
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/Local.cpp950
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/LoopPeel.cpp1724
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/LoopRotationUtils.cpp188
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/LoopSimplify.cpp20
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/LoopUnroll.cpp148
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/LoopUnrollAndJam.cpp26
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/LoopUnrollRuntime.cpp64
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/LoopUtils.cpp500
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/LoopVersioning.cpp190
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/LowerInvoke.cpp2
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/LowerSwitch.cpp390
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/MatrixUtils.cpp208
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/MetaRenamer.cpp264
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/PredicateInfo.cpp252
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/PromoteMemoryToRegister.cpp140
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/SSAUpdater.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/ScalarEvolutionExpander.cpp912
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/SimplifyCFG.cpp2284
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/SimplifyIndVar.cpp2250
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/SimplifyLibCalls.cpp188
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/StripGCRelocates.cpp58
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/StripNonLineTableDebugInfo.cpp32
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp120
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/UnifyLoopExits.cpp78
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp44
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/Utils.cpp10
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/VNCoercion.cpp40
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/ValueMapper.cpp28
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Utils/ya.make14
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp22
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp120
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Vectorize/LoopVectorizationPlanner.h82
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Vectorize/LoopVectorize.cpp5242
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Vectorize/SLPVectorizer.cpp2408
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Vectorize/VPRecipeBuilder.h12
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Vectorize/VPlan.cpp468
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Vectorize/VPlan.h784
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanPredicator.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanSLP.cpp28
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanTransforms.cpp18
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanValue.h374
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanVerifier.cpp4
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Vectorize/VectorCombine.cpp360
-rw-r--r--contrib/libs/llvm12/lib/Transforms/Vectorize/ya.make12
-rw-r--r--contrib/libs/llvm12/provides.pbtxt350
-rw-r--r--contrib/libs/llvm12/tools/dsymutil/BinaryHolder.cpp44
-rw-r--r--contrib/libs/llvm12/tools/dsymutil/BinaryHolder.h2
-rw-r--r--contrib/libs/llvm12/tools/dsymutil/DebugMap.cpp2
-rw-r--r--contrib/libs/llvm12/tools/dsymutil/DwarfLinkerForBinary.cpp256
-rw-r--r--contrib/libs/llvm12/tools/dsymutil/DwarfLinkerForBinary.h74
-rw-r--r--contrib/libs/llvm12/tools/dsymutil/MachODebugMapParser.cpp2
-rw-r--r--contrib/libs/llvm12/tools/dsymutil/MachOUtils.cpp126
-rw-r--r--contrib/libs/llvm12/tools/dsymutil/SymbolMap.cpp2
-rw-r--r--contrib/libs/llvm12/tools/dsymutil/dsymutil.cpp4
-rw-r--r--contrib/libs/llvm12/tools/dsymutil/ya.make124
-rw-r--r--contrib/libs/llvm12/tools/llvm-cvtres/llvm-cvtres.cpp4
-rw-r--r--contrib/libs/llvm12/tools/llvm-cvtres/ya.make32
-rw-r--r--contrib/libs/llvm12/tools/llvm-lipo/llvm-lipo.cpp260
-rw-r--r--contrib/libs/llvm12/tools/llvm-lipo/ya.make92
-rw-r--r--contrib/libs/llvm12/tools/llvm-ml/Opts.td220
-rw-r--r--contrib/libs/llvm12/tools/llvm-ml/llvm-ml.cpp400
-rw-r--r--contrib/libs/llvm12/tools/llvm-ml/ya.make70
-rw-r--r--contrib/libs/llvm12/tools/llvm-mt/llvm-mt.cpp4
-rw-r--r--contrib/libs/llvm12/tools/llvm-mt/ya.make16
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/BitcodeStripOpts.td48
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/COFF/COFFObjcopy.cpp46
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.cpp64
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.h4
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/CopyConfig.cpp238
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/CopyConfig.h18
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/ELF/ELFObjcopy.cpp184
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/ELF/Object.cpp1192
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/ELF/Object.h276
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/InstallNameToolOpts.td20
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp24
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOLayoutBuilder.h12
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOObjcopy.cpp242
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOObjcopy.h8
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOReader.cpp60
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOReader.h6
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOWriter.cpp26
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/MachO/Object.cpp94
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/MachO/Object.h24
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/llvm-objcopy.cpp102
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/llvm-objcopy.h26
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/wasm/Object.cpp2
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/ya.make32
-rw-r--r--contrib/libs/llvm12/tools/llvm-rc/Opts.td50
-rw-r--r--contrib/libs/llvm12/tools/llvm-rc/ResourceFileWriter.cpp24
-rw-r--r--contrib/libs/llvm12/tools/llvm-rc/ResourceScriptParser.cpp6
-rw-r--r--contrib/libs/llvm12/tools/llvm-rc/ResourceScriptStmt.h6
-rw-r--r--contrib/libs/llvm12/tools/llvm-rc/llvm-rc.cpp26
-rw-r--r--contrib/libs/llvm12/tools/llvm-rc/ya.make14
-rw-r--r--contrib/libs/llvm12/tools/llvm-symbolizer/Opts.td142
-rw-r--r--contrib/libs/llvm12/tools/llvm-symbolizer/llvm-symbolizer.cpp368
-rw-r--r--contrib/libs/llvm12/tools/llvm-symbolizer/ya.make42
-rwxr-xr-xcontrib/libs/llvm12/utils/DSAclean.py2
-rwxr-xr-xcontrib/libs/llvm12/utils/DSAextract.py2
-rw-r--r--contrib/libs/llvm12/utils/TableGen/AsmMatcherEmitter.cpp208
-rw-r--r--contrib/libs/llvm12/utils/TableGen/AsmWriterEmitter.cpp142
-rw-r--r--contrib/libs/llvm12/utils/TableGen/AsmWriterInst.cpp2
-rw-r--r--contrib/libs/llvm12/utils/TableGen/CallingConvEmitter.cpp20
-rw-r--r--contrib/libs/llvm12/utils/TableGen/CodeEmitterGen.cpp8
-rw-r--r--contrib/libs/llvm12/utils/TableGen/CodeGenDAGPatterns.cpp40
-rw-r--r--contrib/libs/llvm12/utils/TableGen/CodeGenDAGPatterns.h4
-rw-r--r--contrib/libs/llvm12/utils/TableGen/CodeGenInstruction.cpp2
-rw-r--r--contrib/libs/llvm12/utils/TableGen/CodeGenIntrinsics.h18
-rw-r--r--contrib/libs/llvm12/utils/TableGen/CodeGenMapTable.cpp16
-rw-r--r--contrib/libs/llvm12/utils/TableGen/CodeGenRegisters.cpp20
-rw-r--r--contrib/libs/llvm12/utils/TableGen/CodeGenRegisters.h4
-rw-r--r--contrib/libs/llvm12/utils/TableGen/CodeGenSchedule.cpp414
-rw-r--r--contrib/libs/llvm12/utils/TableGen/CodeGenSchedule.h18
-rw-r--r--contrib/libs/llvm12/utils/TableGen/CodeGenTarget.cpp306
-rw-r--r--contrib/libs/llvm12/utils/TableGen/CodeGenTarget.h14
-rw-r--r--contrib/libs/llvm12/utils/TableGen/DAGISelEmitter.cpp20
-rw-r--r--contrib/libs/llvm12/utils/TableGen/DAGISelMatcher.h26
-rw-r--r--contrib/libs/llvm12/utils/TableGen/DAGISelMatcherEmitter.cpp256
-rw-r--r--contrib/libs/llvm12/utils/TableGen/DAGISelMatcherGen.cpp14
-rw-r--r--contrib/libs/llvm12/utils/TableGen/DFAEmitter.cpp2
-rw-r--r--contrib/libs/llvm12/utils/TableGen/DFAPacketizerEmitter.cpp2
-rw-r--r--contrib/libs/llvm12/utils/TableGen/DirectiveEmitter.cpp1034
-rw-r--r--contrib/libs/llvm12/utils/TableGen/ExegesisEmitter.cpp2
-rw-r--r--contrib/libs/llvm12/utils/TableGen/FixedLenDecoderEmitter.cpp44
-rw-r--r--contrib/libs/llvm12/utils/TableGen/GICombinerEmitter.cpp46
-rw-r--r--contrib/libs/llvm12/utils/TableGen/GlobalISel/CodeExpander.cpp14
-rw-r--r--contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchDag.cpp2
-rw-r--r--contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchDagInstr.cpp2
-rw-r--r--contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchTree.cpp12
-rw-r--r--contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchTree.h2
-rw-r--r--contrib/libs/llvm12/utils/TableGen/GlobalISel/ya.make2
-rw-r--r--contrib/libs/llvm12/utils/TableGen/GlobalISelEmitter.cpp1124
-rw-r--r--contrib/libs/llvm12/utils/TableGen/InstrInfoEmitter.cpp58
-rw-r--r--contrib/libs/llvm12/utils/TableGen/IntrinsicEmitter.cpp32
-rw-r--r--contrib/libs/llvm12/utils/TableGen/OptParserEmitter.cpp300
-rw-r--r--contrib/libs/llvm12/utils/TableGen/PredicateExpander.cpp44
-rw-r--r--contrib/libs/llvm12/utils/TableGen/PredicateExpander.h6
-rw-r--r--contrib/libs/llvm12/utils/TableGen/PseudoLoweringEmitter.cpp132
-rw-r--r--contrib/libs/llvm12/utils/TableGen/RISCVCompressInstEmitter.cpp212
-rw-r--r--contrib/libs/llvm12/utils/TableGen/RegisterBankEmitter.cpp22
-rw-r--r--contrib/libs/llvm12/utils/TableGen/RegisterInfoEmitter.cpp52
-rw-r--r--contrib/libs/llvm12/utils/TableGen/SearchableTableEmitter.cpp266
-rw-r--r--contrib/libs/llvm12/utils/TableGen/SubtargetEmitter.cpp136
-rw-r--r--contrib/libs/llvm12/utils/TableGen/SubtargetFeatureInfo.cpp4
-rw-r--r--contrib/libs/llvm12/utils/TableGen/TableGen.cpp28
-rw-r--r--contrib/libs/llvm12/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp20
-rw-r--r--contrib/libs/llvm12/utils/TableGen/X86DisassemblerTables.cpp2
-rw-r--r--contrib/libs/llvm12/utils/TableGen/X86FoldTablesEmitter.cpp36
-rw-r--r--contrib/libs/llvm12/utils/TableGen/X86RecognizableInstr.cpp2
-rw-r--r--contrib/libs/llvm12/utils/TableGen/ya.make10
-rw-r--r--contrib/libs/llvm12/ya.make26
-rw-r--r--contrib/libs/lzmasdk/7zVersion.h54
-rw-r--r--contrib/libs/lzmasdk/Aes.c612
-rw-r--r--contrib/libs/lzmasdk/Aes.h76
-rw-r--r--contrib/libs/lzmasdk/AesOpt.c356
-rw-r--r--contrib/libs/lzmasdk/Bra.c460
-rw-r--r--contrib/libs/lzmasdk/Bra.h128
-rw-r--r--contrib/libs/lzmasdk/Bra86.c164
-rw-r--r--contrib/libs/lzmasdk/BraIA64.c106
-rw-r--r--contrib/libs/lzmasdk/CpuArch.c436
-rw-r--r--contrib/libs/lzmasdk/CpuArch.h672
-rw-r--r--contrib/libs/lzmasdk/Lzma2Dec.c976
-rw-r--r--contrib/libs/lzmasdk/Lzma2Dec.h240
-rw-r--r--contrib/libs/lzmasdk/Lzma2Enc.c1606
-rw-r--r--contrib/libs/lzmasdk/Lzma2Enc.h110
-rw-r--r--contrib/libs/lzmasdk/LzmaEnc.c20
-rw-r--r--contrib/libs/lzmasdk/LzmaEnc.h14
-rw-r--r--contrib/libs/lzmasdk/MtCoder.h282
-rw-r--r--contrib/libs/lzmasdk/MtDec.h402
-rw-r--r--contrib/libs/lzmasdk/RotateDefs.h60
-rw-r--r--contrib/libs/lzmasdk/Sha256.c496
-rw-r--r--contrib/libs/lzmasdk/Sha256.h52
-rw-r--r--contrib/libs/lzmasdk/Threads.h136
-rw-r--r--contrib/libs/lzmasdk/ya.make20
-rw-r--r--contrib/libs/nayuki_md5/ya.make8
-rw-r--r--contrib/libs/protobuf/ya.make2
-rw-r--r--contrib/libs/python/Include/bytes_methods.h2
-rw-r--r--contrib/libs/python/Include/context.h14
-rw-r--r--contrib/libs/python/Include/cpython/abstract.h14
-rw-r--r--contrib/libs/python/Include/cpython/bytearrayobject.h14
-rw-r--r--contrib/libs/python/Include/cpython/bytesobject.h14
-rw-r--r--contrib/libs/python/Include/cpython/ceval.h14
-rw-r--r--contrib/libs/python/Include/cpython/code.h14
-rw-r--r--contrib/libs/python/Include/cpython/dictobject.h14
-rw-r--r--contrib/libs/python/Include/cpython/fileobject.h14
-rw-r--r--contrib/libs/python/Include/cpython/fileutils.h14
-rw-r--r--contrib/libs/python/Include/cpython/frameobject.h14
-rw-r--r--contrib/libs/python/Include/cpython/import.h14
-rw-r--r--contrib/libs/python/Include/cpython/initconfig.h14
-rw-r--r--contrib/libs/python/Include/cpython/interpreteridobject.h14
-rw-r--r--contrib/libs/python/Include/cpython/listobject.h14
-rw-r--r--contrib/libs/python/Include/cpython/methodobject.h14
-rw-r--r--contrib/libs/python/Include/cpython/object.h14
-rw-r--r--contrib/libs/python/Include/cpython/objimpl.h14
-rw-r--r--contrib/libs/python/Include/cpython/pyerrors.h14
-rw-r--r--contrib/libs/python/Include/cpython/pylifecycle.h14
-rw-r--r--contrib/libs/python/Include/cpython/pymem.h14
-rw-r--r--contrib/libs/python/Include/cpython/pystate.h14
-rw-r--r--contrib/libs/python/Include/cpython/sysmodule.h14
-rw-r--r--contrib/libs/python/Include/cpython/traceback.h14
-rw-r--r--contrib/libs/python/Include/cpython/tupleobject.h14
-rw-r--r--contrib/libs/python/Include/cpython/unicodeobject.h14
-rw-r--r--contrib/libs/python/Include/dtoa.h2
-rw-r--r--contrib/libs/python/Include/exports.h14
-rw-r--r--contrib/libs/python/Include/genericaliasobject.h14
-rw-r--r--contrib/libs/python/Include/interpreteridobject.h14
-rw-r--r--contrib/libs/python/Include/metagrammar.h2
-rw-r--r--contrib/libs/python/Include/pgen.h2
-rw-r--r--contrib/libs/python/Include/pgenheaders.h2
-rw-r--r--contrib/libs/python/Include/picklebufobject.h14
-rw-r--r--contrib/libs/python/Include/pyframe.h14
-rw-r--r--contrib/libs/python/Include/pygetopt.h2
-rw-r--r--contrib/libs/python/Include/tracemalloc.h14
-rw-r--r--contrib/libs/rapidjson/ya.make4
-rw-r--r--contrib/libs/sparsehash/ya.make2
-rw-r--r--contrib/libs/sqlite3/config.h4
-rw-r--r--contrib/libs/sqlite3/sqlite3.h6
-rw-r--r--contrib/libs/tbb/ya.make22
-rw-r--r--contrib/libs/xz/ya.make4
-rw-r--r--contrib/libs/ya.make8
-rw-r--r--contrib/libs/yaml-cpp/ya.make4
-rw-r--r--contrib/libs/yaml/License4
-rw-r--r--contrib/libs/yaml/include/yaml.h88
-rw-r--r--contrib/libs/yaml/src/api.c88
-rw-r--r--contrib/libs/yaml/src/config.h162
-rw-r--r--contrib/libs/yaml/src/dumper.c6
-rw-r--r--contrib/libs/yaml/src/emitter.c126
-rw-r--r--contrib/libs/yaml/src/loader.c418
-rw-r--r--contrib/libs/yaml/src/parser.c32
-rw-r--r--contrib/libs/yaml/src/reader.c12
-rw-r--r--contrib/libs/yaml/src/scanner.c158
-rw-r--r--contrib/libs/yaml/src/writer.c2
-rw-r--r--contrib/libs/yaml/src/yaml_private.h102
-rw-r--r--contrib/libs/yaml/ya.make28
-rw-r--r--contrib/libs/zstd/programs/zstd/ya.make32
-rw-r--r--contrib/libs/zstd/ya.make14
-rw-r--r--contrib/libs/zstd06/ya.make4
2210 files changed, 199166 insertions, 199166 deletions
diff --git a/contrib/libs/antlr3_cpp_runtime/ya.make b/contrib/libs/antlr3_cpp_runtime/ya.make
index 5ed46d6ea0..5c019aa396 100644
--- a/contrib/libs/antlr3_cpp_runtime/ya.make
+++ b/contrib/libs/antlr3_cpp_runtime/ya.make
@@ -5,8 +5,8 @@ LIBRARY()
# directory: runtime/Cpp
# revision: a4d1928e03b2b3f74579e54a6211cd1d695001b9
-VERSION(2016-03-31-a4d1928e03b2b3f74579e54a6211cd1d695001b9)
-
+VERSION(2016-03-31-a4d1928e03b2b3f74579e54a6211cd1d695001b9)
+
LICENSE(
BSD-3-Clause AND
Unicode-Mappings
diff --git a/contrib/libs/apache/arrow/cpp/src/arrow/array/README.md b/contrib/libs/apache/arrow/cpp/src/arrow/array/README.md
index fd450d47d9..01ffa104eb 100644
--- a/contrib/libs/apache/arrow/cpp/src/arrow/array/README.md
+++ b/contrib/libs/apache/arrow/cpp/src/arrow/array/README.md
@@ -1,20 +1,20 @@
-<!---
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-
-## Implementation details related to columnar (array) data structures
+<!---
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+## Implementation details related to columnar (array) data structures
diff --git a/contrib/libs/apache/arrow/cpp/src/arrow/compute/README.md b/contrib/libs/apache/arrow/cpp/src/arrow/compute/README.md
index 269780351e..80d8918e3d 100644
--- a/contrib/libs/apache/arrow/cpp/src/arrow/compute/README.md
+++ b/contrib/libs/apache/arrow/cpp/src/arrow/compute/README.md
@@ -1,58 +1,58 @@
-<!---
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-
-## Apache Arrow C++ Compute Functions
-
-This submodule contains analytical functions that process primarily Arrow
-columnar data; some functions can process scalar or Arrow-based array
-inputs. These are intended for use inside query engines, data frame libraries,
-etc.
-
-Many functions have SQL-like semantics in that they perform elementwise or
-scalar operations on whole arrays at a time. Other functions are not SQL-like
-and compute results that may be a different length or whose results depend on
-the order of the values.
-
-Some basic terminology:
-
-* We use the term "function" to refer to particular general operation that may
- have many different implementations corresponding to different combinations
- of types or function behavior options.
-* We call a specific implementation of a function a "kernel". When executing a
- function on inputs, we must first select a suitable kernel (kernel selection
- is called "dispatching") corresponding to the value types of the inputs
-* Functions along with their kernel implementations are collected in a
- "function registry". Given a function name and argument types, we can look up
- that function and dispatch to a compatible kernel.
-
-Types of functions
-
-* Scalar functions: elementwise functions that perform scalar operations in a
- vectorized manner. These functions are generally valid for SQL-like
- context. These are called "scalar" in that the functions executed consider
- each value in an array independently, and the output array or arrays have the
- same length as the input arrays. The result for each array cell is generally
- independent of its position in the array.
-* Vector functions, which produce a result whose output is generally dependent
- on the entire contents of the input arrays. These functions **are generally
- not valid** for SQL-like processing because the output size may be different
- than the input size, and the result may change based on the order of the
- values in the array. This includes things like array subselection, sorting,
- hashing, and more.
-* Scalar aggregate functions of which can be used in a SQL-like context \ No newline at end of file
+<!---
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+## Apache Arrow C++ Compute Functions
+
+This submodule contains analytical functions that process primarily Arrow
+columnar data; some functions can process scalar or Arrow-based array
+inputs. These are intended for use inside query engines, data frame libraries,
+etc.
+
+Many functions have SQL-like semantics in that they perform elementwise or
+scalar operations on whole arrays at a time. Other functions are not SQL-like
+and compute results that may be a different length or whose results depend on
+the order of the values.
+
+Some basic terminology:
+
+* We use the term "function" to refer to particular general operation that may
+ have many different implementations corresponding to different combinations
+ of types or function behavior options.
+* We call a specific implementation of a function a "kernel". When executing a
+ function on inputs, we must first select a suitable kernel (kernel selection
+ is called "dispatching") corresponding to the value types of the inputs
+* Functions along with their kernel implementations are collected in a
+ "function registry". Given a function name and argument types, we can look up
+ that function and dispatch to a compatible kernel.
+
+Types of functions
+
+* Scalar functions: elementwise functions that perform scalar operations in a
+ vectorized manner. These functions are generally valid for SQL-like
+ context. These are called "scalar" in that the functions executed consider
+ each value in an array independently, and the output array or arrays have the
+ same length as the input arrays. The result for each array cell is generally
+ independent of its position in the array.
+* Vector functions, which produce a result whose output is generally dependent
+ on the entire contents of the input arrays. These functions **are generally
+ not valid** for SQL-like processing because the output size may be different
+ than the input size, and the result may change based on the order of the
+ values in the array. This includes things like array subselection, sorting,
+ hashing, and more.
+* Scalar aggregate functions of which can be used in a SQL-like context \ No newline at end of file
diff --git a/contrib/libs/apache/arrow/cpp/src/arrow/io/api.h b/contrib/libs/apache/arrow/cpp/src/arrow/io/api.h
index 5d6269a05a..3bfde6de45 100644
--- a/contrib/libs/apache/arrow/cpp/src/arrow/io/api.h
+++ b/contrib/libs/apache/arrow/cpp/src/arrow/io/api.h
@@ -1,24 +1,24 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-#pragma once
-
-#include "arrow/io/buffered.h"
-#include "arrow/io/compressed.h"
-#include "arrow/io/file.h"
-#include "arrow/io/interfaces.h"
-#include "arrow/io/memory.h"
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#pragma once
+
+#include "arrow/io/buffered.h"
+#include "arrow/io/compressed.h"
+#include "arrow/io/file.h"
+#include "arrow/io/interfaces.h"
+#include "arrow/io/memory.h"
diff --git a/contrib/libs/apache/arrow/cpp/src/arrow/ipc/api.h b/contrib/libs/apache/arrow/cpp/src/arrow/ipc/api.h
index 339a25a0d6..b5690aed8d 100644
--- a/contrib/libs/apache/arrow/cpp/src/arrow/ipc/api.h
+++ b/contrib/libs/apache/arrow/cpp/src/arrow/ipc/api.h
@@ -1,25 +1,25 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-#pragma once
-
-#include "arrow/ipc/dictionary.h"
-#include "arrow/ipc/feather.h"
-#include "arrow/ipc/json_simple.h"
-#include "arrow/ipc/message.h"
-#include "arrow/ipc/reader.h"
-#include "arrow/ipc/writer.h"
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#pragma once
+
+#include "arrow/ipc/dictionary.h"
+#include "arrow/ipc/feather.h"
+#include "arrow/ipc/json_simple.h"
+#include "arrow/ipc/message.h"
+#include "arrow/ipc/reader.h"
+#include "arrow/ipc/writer.h"
diff --git a/contrib/libs/apache/arrow/cpp/src/arrow/vendored/datetime/README.md b/contrib/libs/apache/arrow/cpp/src/arrow/vendored/datetime/README.md
index 308fb54aaf..811b6935ff 100644
--- a/contrib/libs/apache/arrow/cpp/src/arrow/vendored/datetime/README.md
+++ b/contrib/libs/apache/arrow/cpp/src/arrow/vendored/datetime/README.md
@@ -1,21 +1,21 @@
-<!--
-The MIT License (MIT)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
--->
-
-# Utilities for supporting date time functions
-
-Sources for datetime are adapted from Howard Hinnant's date library
-(https://github.com/HowardHinnant/date).
-
-Sources are taken from v3.0.0 release of the above project.
-
+<!--
+The MIT License (MIT)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+-->
+
+# Utilities for supporting date time functions
+
+Sources for datetime are adapted from Howard Hinnant's date library
+(https://github.com/HowardHinnant/date).
+
+Sources are taken from v3.0.0 release of the above project.
+
diff --git a/contrib/libs/apache/arrow/cpp/src/arrow/vendored/musl/README.md b/contrib/libs/apache/arrow/cpp/src/arrow/vendored/musl/README.md
index 88eb310978..40962a14ca 100644
--- a/contrib/libs/apache/arrow/cpp/src/arrow/vendored/musl/README.md
+++ b/contrib/libs/apache/arrow/cpp/src/arrow/vendored/musl/README.md
@@ -1,25 +1,25 @@
-<!--
-Copyright © 2005-2020 Rich Felker, et al.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--->
-
-Assorted utility functions are adapted from the musl libc project
-(https://musl.libc.org/).
+<!--
+Copyright © 2005-2020 Rich Felker, et al.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+-->
+
+Assorted utility functions are adapted from the musl libc project
+(https://musl.libc.org/).
diff --git a/contrib/libs/apache/arrow/cpp/src/arrow/vendored/portable-snippets/README.md b/contrib/libs/apache/arrow/cpp/src/arrow/vendored/portable-snippets/README.md
index 93bbdc1b35..9c67b7baa1 100644
--- a/contrib/libs/apache/arrow/cpp/src/arrow/vendored/portable-snippets/README.md
+++ b/contrib/libs/apache/arrow/cpp/src/arrow/vendored/portable-snippets/README.md
@@ -1,10 +1,10 @@
-<!---
-Each source file contains a preamble explaining the license situation
-for that file, which takes priority over this file. With the
-exception of some code pulled in from other repositories (such as
-µnit, an MIT-licensed project which is used for testing), the code is
-public domain, released using the CC0 1.0 Universal dedication.
--->
-
-The files in this directory are vendored from portable-snippets
-git changeset f596f8b0a4b8a6ea1166c2361a5cb7e6f802c5ea.
+<!---
+Each source file contains a preamble explaining the license situation
+for that file, which takes priority over this file. With the
+exception of some code pulled in from other repositories (such as
+µnit, an MIT-licensed project which is used for testing), the code is
+public domain, released using the CC0 1.0 Universal dedication.
+-->
+
+The files in this directory are vendored from portable-snippets
+git changeset f596f8b0a4b8a6ea1166c2361a5cb7e6f802c5ea.
diff --git a/contrib/libs/apache/arrow/cpp/src/arrow/vendored/utfcpp/README.md b/contrib/libs/apache/arrow/cpp/src/arrow/vendored/utfcpp/README.md
index bdb2db7d8d..c0abfd7d11 100644
--- a/contrib/libs/apache/arrow/cpp/src/arrow/vendored/utfcpp/README.md
+++ b/contrib/libs/apache/arrow/cpp/src/arrow/vendored/utfcpp/README.md
@@ -1,28 +1,28 @@
-<!---
- Boost Software License - Version 1.0 - August 17th, 2003
-
- Permission is hereby granted, free of charge, to any person or organization
- obtaining a copy of the software and accompanying documentation covered by
- this license (the "Software") to use, reproduce, display, distribute,
- execute, and transmit the Software, and to prepare derivative works of the
- Software, and to permit third-parties to whom the Software is furnished to
- do so, all subject to the following:
-
- The copyright notices in the Software and this entire statement, including
- the above license grant, this restriction and the following disclaimer,
- must be included in all copies of the Software, in whole or in part, and
- all derivative works of the Software, unless such copies or derivative
- works are solely in the form of machine-executable object code generated by
- a source language processor.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
- SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
- FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
--->
-
-The files in this directory are vendored from utfcpp git tag v3.1.1
-(https://github.com/nemtrif/utfcpp).
+<!---
+ Boost Software License - Version 1.0 - August 17th, 2003
+
+ Permission is hereby granted, free of charge, to any person or organization
+ obtaining a copy of the software and accompanying documentation covered by
+ this license (the "Software") to use, reproduce, display, distribute,
+ execute, and transmit the Software, and to prepare derivative works of the
+ Software, and to permit third-parties to whom the Software is furnished to
+ do so, all subject to the following:
+
+ The copyright notices in the Software and this entire statement, including
+ the above license grant, this restriction and the following disclaimer,
+ must be included in all copies of the Software, in whole or in part, and
+ all derivative works of the Software, unless such copies or derivative
+ works are solely in the form of machine-executable object code generated by
+ a source language processor.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+-->
+
+The files in this directory are vendored from utfcpp git tag v3.1.1
+(https://github.com/nemtrif/utfcpp).
diff --git a/contrib/libs/apache/arrow/ya.make b/contrib/libs/apache/arrow/ya.make
index 8ceac746b8..27b9235d9e 100644
--- a/contrib/libs/apache/arrow/ya.make
+++ b/contrib/libs/apache/arrow/ya.make
@@ -10,7 +10,7 @@ OWNER(
VERSION(5.0.0)
ORIGINAL_SOURCE(https://github.com/apache/arrow/archive/apache-arrow-5.0.0.tar.gz)
-
+
LICENSE(
Apache-2.0 AND
BSD-2-Clause AND
@@ -24,7 +24,7 @@ LICENSE(
ZPL-2.1 AND
Zlib
)
-
+
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
diff --git a/contrib/libs/apache/orc/.yandex_meta/devtools.copyrights.report b/contrib/libs/apache/orc/.yandex_meta/devtools.copyrights.report
index b418699575..093facd788 100644
--- a/contrib/libs/apache/orc/.yandex_meta/devtools.copyrights.report
+++ b/contrib/libs/apache/orc/.yandex_meta/devtools.copyrights.report
@@ -29,62 +29,62 @@
# FILE_INCLUDE - include all file data into licenses text file
# =======================
-KEEP COPYRIGHT_SERVICE_LABEL 44bf37d4806e634327301adb6333234f
+KEEP COPYRIGHT_SERVICE_LABEL 44bf37d4806e634327301adb6333234f
BELONGS ya.make
License text:
- * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
+ * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
Scancode info:
Original SPDX id: COPYRIGHT_SERVICE_LABEL
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- LICENSE [338:338]
+ LICENSE [338:338]
-KEEP COPYRIGHT_SERVICE_LABEL 522505e5894778a882702849ee07b13a
+KEEP COPYRIGHT_SERVICE_LABEL 522505e5894778a882702849ee07b13a
BELONGS ya.make
License text:
- Copyright 2011, Google Inc.
- All rights reserved.
+ Copyright 2011, Google Inc.
+ All rights reserved.
Scancode info:
Original SPDX id: COPYRIGHT_SERVICE_LABEL
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- LICENSE [274:275]
+ LICENSE [274:275]
+
+KEEP COPYRIGHT_SERVICE_LABEL 7993ed112cd32a97cc601b58343dfe3b
+BELONGS ya.make
+ License text:
+ (C) 1995-2017 Jean-loup Gailly and Mark Adler
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ LICENSE [305:305]
+
+KEEP COPYRIGHT_SERVICE_LABEL 7ddb2995f48012001146c0eb94d23367
+BELONGS ya.make
+ License text:
+ Copyright 2008 Google Inc. All rights reserved.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ LICENSE [214:214]
+
+KEEP COPYRIGHT_SERVICE_LABEL b5f926d3cac689f08ee106a28ae32f34
+BELONGS ya.make
+ License text:
+ (c) Copyright [2008-2015] Tom Preston-Werner
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ LICENSE [252:252]
-KEEP COPYRIGHT_SERVICE_LABEL 7993ed112cd32a97cc601b58343dfe3b
-BELONGS ya.make
- License text:
- (C) 1995-2017 Jean-loup Gailly and Mark Adler
- Scancode info:
- Original SPDX id: COPYRIGHT_SERVICE_LABEL
- Score : 100.00
- Match type : COPYRIGHT
- Files with this license:
- LICENSE [305:305]
-
-KEEP COPYRIGHT_SERVICE_LABEL 7ddb2995f48012001146c0eb94d23367
-BELONGS ya.make
- License text:
- Copyright 2008 Google Inc. All rights reserved.
- Scancode info:
- Original SPDX id: COPYRIGHT_SERVICE_LABEL
- Score : 100.00
- Match type : COPYRIGHT
- Files with this license:
- LICENSE [214:214]
-
-KEEP COPYRIGHT_SERVICE_LABEL b5f926d3cac689f08ee106a28ae32f34
-BELONGS ya.make
- License text:
- (c) Copyright [2008-2015] Tom Preston-Werner
- Scancode info:
- Original SPDX id: COPYRIGHT_SERVICE_LABEL
- Score : 100.00
- Match type : COPYRIGHT
- Files with this license:
- LICENSE [252:252]
-
KEEP COPYRIGHT_SERVICE_LABEL d73f33a516f5e4a9b5ce47f967383cfb
BELONGS ya.make
License text:
@@ -96,14 +96,14 @@ BELONGS ya.make
Match type : COPYRIGHT
Files with this license:
NOTICE [7:8]
-
-KEEP COPYRIGHT_SERVICE_LABEL db14b49950a466d8c06ad0d9e2101bcf
-BELONGS ya.make
- License text:
- Copyright 2013 and onwards The Apache Software Foundation.
- Scancode info:
- Original SPDX id: COPYRIGHT_SERVICE_LABEL
- Score : 100.00
- Match type : COPYRIGHT
- Files with this license:
- NOTICE [2:2]
+
+KEEP COPYRIGHT_SERVICE_LABEL db14b49950a466d8c06ad0d9e2101bcf
+BELONGS ya.make
+ License text:
+ Copyright 2013 and onwards The Apache Software Foundation.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ NOTICE [2:2]
diff --git a/contrib/libs/apache/orc/.yandex_meta/devtools.licenses.report b/contrib/libs/apache/orc/.yandex_meta/devtools.licenses.report
index c26234e647..f9ce15cbd1 100644
--- a/contrib/libs/apache/orc/.yandex_meta/devtools.licenses.report
+++ b/contrib/libs/apache/orc/.yandex_meta/devtools.licenses.report
@@ -122,18 +122,18 @@ BELONGS ya.make
Files with this license:
NOTICE [4:5]
-SKIP BSD-3-Clause 65f1885a6e62550129cec1b1c92228b7
-BELONGS ya.make
-# for snappy
- Note: matched license text is too long. Read it in the source files.
- Scancode info:
- Original SPDX id: BSD-3-Clause
- Score : 100.00
- Match type : TEXT
- Links : http://www.opensource.org/licenses/BSD-3-Clause, https://spdx.org/licenses/BSD-3-Clause
- Files with this license:
- LICENSE [277:301]
-
+SKIP BSD-3-Clause 65f1885a6e62550129cec1b1c92228b7
+BELONGS ya.make
+# for snappy
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: BSD-3-Clause
+ Score : 100.00
+ Match type : TEXT
+ Links : http://www.opensource.org/licenses/BSD-3-Clause, https://spdx.org/licenses/BSD-3-Clause
+ Files with this license:
+ LICENSE [277:301]
+
SKIP LicenseRef-scancode-unknown-license-reference 82b9c91a8f717463c6871d82aa2b1ff8
BELONGS ya.make
# notice about sub-components that have other licenses
@@ -162,30 +162,30 @@ FILE_INCLUDE NOTICE found in files: c++/src/RLEV2Util.cc at line 3, c++/src/RleE
c++/src/RLEV2Util.cc [2:16]
c++/src/RleEncoderV2.cc [2:16]
-SKIP MIT 8e611cb87fefb343bbd1b4b132671868
-BELONGS ya.make
-# for the site
- Note: matched license text is too long. Read it in the source files.
- Scancode info:
- Original SPDX id: MIT
- Score : 100.00
- Match type : TEXT
- Links : http://opensource.org/licenses/mit-license.php, https://spdx.org/licenses/MIT
- Files with this license:
- LICENSE [254:270]
-
-SKIP Zlib aa58f308323ed48be51ebc4b5d89fdbf
-BELONGS ya.make
-# for zlib
- Note: matched license text is too long. Read it in the source files.
- Scancode info:
- Original SPDX id: Zlib
- Score : 100.00
- Match type : TEXT
- Links : http://www.gzip.org/zlib/zlib_license.html, http://www.zlib.net/, https://spdx.org/licenses/Zlib
- Files with this license:
- LICENSE [307:324]
-
+SKIP MIT 8e611cb87fefb343bbd1b4b132671868
+BELONGS ya.make
+# for the site
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: MIT
+ Score : 100.00
+ Match type : TEXT
+ Links : http://opensource.org/licenses/mit-license.php, https://spdx.org/licenses/MIT
+ Files with this license:
+ LICENSE [254:270]
+
+SKIP Zlib aa58f308323ed48be51ebc4b5d89fdbf
+BELONGS ya.make
+# for zlib
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: Zlib
+ Score : 100.00
+ Match type : TEXT
+ Links : http://www.gzip.org/zlib/zlib_license.html, http://www.zlib.net/, https://spdx.org/licenses/Zlib
+ Files with this license:
+ LICENSE [307:324]
+
KEEP Apache-2.0 be1ae92e2816e00bcf72d9b9a768ac9d
BELONGS ya.make
FILE_INCLUDE NOTICE found in files: LICENSE at line 107, LICENSE at line 110, LICENSE at line 112, LICENSE at line 117, LICENSE at line 120, LICENSE at line 142
@@ -198,18 +198,18 @@ FILE_INCLUDE NOTICE found in files: LICENSE at line 107, LICENSE at line 110, LI
Files with this license:
LICENSE [2:202]
-SKIP Protobuf-License c6508a22f2888f82ca0962122f6bf026
-BELONGS ya.make
-# for protobuf
- Note: matched license text is too long. Read it in the source files.
- Scancode info:
- Original SPDX id: LicenseRef-scancode-protobuf
- Score : 100.00
- Match type : TEXT
- Links : http://protobuf.googlecode.com/svn/trunk/COPYING.txt, https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/protobuf.LICENSE
- Files with this license:
- LICENSE [216:245]
-
+SKIP Protobuf-License c6508a22f2888f82ca0962122f6bf026
+BELONGS ya.make
+# for protobuf
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: LicenseRef-scancode-protobuf
+ Score : 100.00
+ Match type : TEXT
+ Links : http://protobuf.googlecode.com/svn/trunk/COPYING.txt, https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/protobuf.LICENSE
+ Files with this license:
+ LICENSE [216:245]
+
KEEP Apache-2.0 cf6155521a56fa3ce6c29b457f7a2535
BELONGS ya.make
FILE_INCLUDE NOTICE found in files: c++/src/Adaptor.cc at line 3, c++/src/RLE.cc at line 3, c++/src/RLEV2Util.hh at line 3, c++/src/RLEv1.hh at line 3, c++/src/RLEv2.hh at line 3
@@ -225,28 +225,28 @@ FILE_INCLUDE NOTICE found in files: c++/src/Adaptor.cc at line 3, c++/src/RLE.cc
c++/src/RLEV2Util.hh [2:16]
c++/src/RLEv1.hh [2:16]
c++/src/RLEv2.hh [2:16]
-
-SKIP LicenseRef-scancode-bsd-3-clause-devine d62bead38797bd9e07e7e2167662d6b2
-BELONGS ya.make
-# for orc.threeten
- Note: matched license text is too long. Read it in the source files.
- Scancode info:
- Original SPDX id: LicenseRef-scancode-bsd-3-clause-devine
- Score : 27.57
- Match type : TEXT
- Links : https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/bsd-3-clause-devine.LICENSE
- Files with this license:
- LICENSE [361:366]
-
-SKIP MIT ef6e2d996c0ee4ccd03144f93e445032
-BELONGS ya.make
-# for the site
- License text:
- that are licensed under the MIT License (MIT):
- Scancode info:
- Original SPDX id: MIT
- Score : 100.00
- Match type : NOTICE
- Links : http://opensource.org/licenses/mit-license.php, https://spdx.org/licenses/MIT
- Files with this license:
- LICENSE [250:250]
+
+SKIP LicenseRef-scancode-bsd-3-clause-devine d62bead38797bd9e07e7e2167662d6b2
+BELONGS ya.make
+# for orc.threeten
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: LicenseRef-scancode-bsd-3-clause-devine
+ Score : 27.57
+ Match type : TEXT
+ Links : https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/bsd-3-clause-devine.LICENSE
+ Files with this license:
+ LICENSE [361:366]
+
+SKIP MIT ef6e2d996c0ee4ccd03144f93e445032
+BELONGS ya.make
+# for the site
+ License text:
+ that are licensed under the MIT License (MIT):
+ Scancode info:
+ Original SPDX id: MIT
+ Score : 100.00
+ Match type : NOTICE
+ Links : http://opensource.org/licenses/mit-license.php, https://spdx.org/licenses/MIT
+ Files with this license:
+ LICENSE [250:250]
diff --git a/contrib/libs/apache/orc/.yandex_meta/licenses.list.txt b/contrib/libs/apache/orc/.yandex_meta/licenses.list.txt
index b3bc283bf9..839a5ab922 100644
--- a/contrib/libs/apache/orc/.yandex_meta/licenses.list.txt
+++ b/contrib/libs/apache/orc/.yandex_meta/licenses.list.txt
@@ -276,38 +276,38 @@ Foundation (http://www.apache.org/).
====================COPYRIGHT====================
- * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
+ * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
====================COPYRIGHT====================
- (C) 1995-2017 Jean-loup Gailly and Mark Adler
+ (C) 1995-2017 Jean-loup Gailly and Mark Adler
+
+
+====================COPYRIGHT====================
+ (c) Copyright [2008-2015] Tom Preston-Werner
+
+
+====================COPYRIGHT====================
+ Copyright 2008 Google Inc. All rights reserved.
+
+
+====================COPYRIGHT====================
+ Copyright 2011, Google Inc.
+ All rights reserved.
+
+
+====================COPYRIGHT====================
+Copyright 2013 and onwards The Apache Software Foundation.
====================COPYRIGHT====================
- (c) Copyright [2008-2015] Tom Preston-Werner
-
-
-====================COPYRIGHT====================
- Copyright 2008 Google Inc. All rights reserved.
-
-
-====================COPYRIGHT====================
- Copyright 2011, Google Inc.
- All rights reserved.
-
-
-====================COPYRIGHT====================
-Copyright 2013 and onwards The Apache Software Foundation.
-
-
-====================COPYRIGHT====================
This product includes software developed by Hewlett-Packard:
(c) Copyright [2014-2015] Hewlett-Packard Development Company, L.P
====================File: NOTICE====================
Apache ORC
-Copyright 2013 and onwards The Apache Software Foundation.
+Copyright 2013 and onwards The Apache Software Foundation.
This product includes software developed by The Apache Software
Foundation (http://www.apache.org/).
diff --git a/contrib/libs/apache/orc/LICENSE b/contrib/libs/apache/orc/LICENSE
index c3faac768d..70507878ee 100644
--- a/contrib/libs/apache/orc/LICENSE
+++ b/contrib/libs/apache/orc/LICENSE
@@ -209,159 +209,159 @@ notices and license terms. Your use of the source code for the these
subcomponents is subject to the terms and conditions of the following
licenses.
-For protobuf:
-
- Copyright 2008 Google Inc. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
- * Neither the name of Google Inc. nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Code generated by the Protocol Buffer compiler is owned by the owner
- of the input file used when generating it. This code is not
- standalone and requires a support library to be linked with it. This
- support library is itself covered by the above license.
-
-For the site:
-
- Parts of the site formatting includes software developed by Tom Preston-Werner
- that are licensed under the MIT License (MIT):
-
- (c) Copyright [2008-2015] Tom Preston-Werner
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
-
-For snappy:
-
- Copyright 2011, Google Inc.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
- * Neither the name of Google Inc. nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-For zlib:
-
- (C) 1995-2017 Jean-loup Gailly and Mark Adler
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jean-loup Gailly Mark Adler
- jloup@gzip.org madler@alumni.caltech.edu
-
- If you use the zlib library in a product, we would appreciate *not* receiving
- lengthy legal documents to sign. The sources are provided for free but without
- warranty of any kind. The library has been entirely written by Jean-loup
- Gailly and Mark Adler; it does not include third-party code.
-
- If you redistribute modified sources, we would appreciate that you include in
- the file ChangeLog history information documenting your changes. Please read
- the FAQ for more information on the distribution of modified source versions.
-
-For orc.threeten:
-
- /*
- * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of JSR-310 nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */ \ No newline at end of file
+For protobuf:
+
+ Copyright 2008 Google Inc. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Google Inc. nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Code generated by the Protocol Buffer compiler is owned by the owner
+ of the input file used when generating it. This code is not
+ standalone and requires a support library to be linked with it. This
+ support library is itself covered by the above license.
+
+For the site:
+
+ Parts of the site formatting includes software developed by Tom Preston-Werner
+ that are licensed under the MIT License (MIT):
+
+ (c) Copyright [2008-2015] Tom Preston-Werner
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+For snappy:
+
+ Copyright 2011, Google Inc.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Google Inc. nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+For zlib:
+
+ (C) 1995-2017 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+ If you use the zlib library in a product, we would appreciate *not* receiving
+ lengthy legal documents to sign. The sources are provided for free but without
+ warranty of any kind. The library has been entirely written by Jean-loup
+ Gailly and Mark Adler; it does not include third-party code.
+
+ If you redistribute modified sources, we would appreciate that you include in
+ the file ChangeLog history information documenting your changes. Please read
+ the FAQ for more information on the distribution of modified source versions.
+
+For orc.threeten:
+
+ /*
+ * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * * Neither the name of JSR-310 nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */ \ No newline at end of file
diff --git a/contrib/libs/apache/orc/NOTICE b/contrib/libs/apache/orc/NOTICE
index 07c64d5dcb..4c79570fac 100644
--- a/contrib/libs/apache/orc/NOTICE
+++ b/contrib/libs/apache/orc/NOTICE
@@ -1,5 +1,5 @@
Apache ORC
-Copyright 2013 and onwards The Apache Software Foundation.
+Copyright 2013 and onwards The Apache Software Foundation.
This product includes software developed by The Apache Software
Foundation (http://www.apache.org/).
diff --git a/contrib/libs/apache/orc/README.md b/contrib/libs/apache/orc/README.md
index 863fb036f1..0668ee07a5 100644
--- a/contrib/libs/apache/orc/README.md
+++ b/contrib/libs/apache/orc/README.md
@@ -33,18 +33,18 @@ Bug tracking: <a href="http://orc.apache.org/bugs">Apache Jira</a>
The subdirectories are:
* c++ - the c++ reader and writer
-* cmake_modules - the cmake modules
+* cmake_modules - the cmake modules
* docker - docker scripts to build and test on various linuxes
* examples - various ORC example files that are used to test compatibility
* java - the java reader and writer
* proto - the protocol buffer definition for the ORC metadata
* site - the website and documentation
-* snap - the script to build [snaps](https://snapcraft.io/) of the ORC tools
+* snap - the script to build [snaps](https://snapcraft.io/) of the ORC tools
* tools - the c++ tools for reading and inspecting ORC files
### Building
-* Install java 1.8 or higher
+* Install java 1.8 or higher
* Install maven 3 or higher
* Install cmake
@@ -81,7 +81,7 @@ To build a release version without debug information:
To build only the Java library:
```shell
% cd java
-% ./mvnw package
+% ./mvnw package
```
diff --git a/contrib/libs/apache/orc/c++/include/orc/Common.hh b/contrib/libs/apache/orc/c++/include/orc/Common.hh
index 41bb76b80a..4aa4a85118 100644
--- a/contrib/libs/apache/orc/c++/include/orc/Common.hh
+++ b/contrib/libs/apache/orc/c++/include/orc/Common.hh
@@ -69,13 +69,13 @@ namespace orc {
ORC_JAVA_WRITER = 0,
ORC_CPP_WRITER = 1,
PRESTO_WRITER = 2,
- SCRITCHLEY_GO = 3,
- TRINO_WRITER = 4,
+ SCRITCHLEY_GO = 3,
+ TRINO_WRITER = 4,
UNKNOWN_WRITER = INT32_MAX
};
- std::string writerIdToString(uint32_t id);
-
+ std::string writerIdToString(uint32_t id);
+
enum CompressionKind {
CompressionKind_NONE = 0,
CompressionKind_ZLIB = 1,
@@ -99,9 +99,9 @@ namespace orc {
WriterVersion_HIVE_13083 = 4,
WriterVersion_ORC_101 = 5,
WriterVersion_ORC_135 = 6,
- WriterVersion_ORC_517 = 7,
- WriterVersion_ORC_203 = 8,
- WriterVersion_ORC_14 = 9,
+ WriterVersion_ORC_517 = 7,
+ WriterVersion_ORC_203 = 8,
+ WriterVersion_ORC_14 = 9,
WriterVersion_MAX = INT32_MAX
};
diff --git a/contrib/libs/apache/orc/c++/include/orc/Reader.hh b/contrib/libs/apache/orc/c++/include/orc/Reader.hh
index 8984939a50..5d9a532c11 100644
--- a/contrib/libs/apache/orc/c++/include/orc/Reader.hh
+++ b/contrib/libs/apache/orc/c++/include/orc/Reader.hh
@@ -272,12 +272,12 @@ namespace orc {
virtual uint64_t getNumberOfRows() const = 0;
/**
- * Get the software instance and version that wrote this file.
- * @return a user-facing string that specifies the software version
- */
- virtual std::string getSoftwareVersion() const = 0;
-
- /**
+ * Get the software instance and version that wrote this file.
+ * @return a user-facing string that specifies the software version
+ */
+ virtual std::string getSoftwareVersion() const = 0;
+
+ /**
* Get the user metadata keys.
* @return the set of user metadata keys
*/
diff --git a/contrib/libs/apache/orc/c++/include/orc/Statistics.hh b/contrib/libs/apache/orc/c++/include/orc/Statistics.hh
index a77f7ca898..1d4b0b6558 100644
--- a/contrib/libs/apache/orc/c++/include/orc/Statistics.hh
+++ b/contrib/libs/apache/orc/c++/include/orc/Statistics.hh
@@ -282,13 +282,13 @@ namespace orc {
* Get the minimum value for the column.
* @return minimum value
*/
- virtual const std::string & getMinimum() const = 0;
+ virtual const std::string & getMinimum() const = 0;
/**
* Get the maximum value for the column.
* @return maximum value
*/
- virtual const std::string & getMaximum() const = 0;
+ virtual const std::string & getMaximum() const = 0;
/**
* Get the total length of all values.
diff --git a/contrib/libs/apache/orc/c++/include/orc/orc-config.hh b/contrib/libs/apache/orc/c++/include/orc/orc-config.hh
index f2e526f8b2..18bbbd78e1 100644
--- a/contrib/libs/apache/orc/c++/include/orc/orc-config.hh
+++ b/contrib/libs/apache/orc/c++/include/orc/orc-config.hh
@@ -15,7 +15,7 @@
#ifndef ORC_CONFIG_HH
#define ORC_CONFIG_HH
-#define ORC_VERSION "1.6.12"
+#define ORC_VERSION "1.6.12"
#define ORC_CXX_HAS_CSTDINT
#define ORC_CXX_HAS_INITIALIZER_LIST
diff --git a/contrib/libs/apache/orc/c++/src/Adaptor.hh b/contrib/libs/apache/orc/c++/src/Adaptor.hh
index 9a8138796b..a91b9c894d 100644
--- a/contrib/libs/apache/orc/c++/src/Adaptor.hh
+++ b/contrib/libs/apache/orc/c++/src/Adaptor.hh
@@ -30,12 +30,12 @@
#define HAS_DOUBLE_TO_STRING
#define HAS_INT64_TO_STRING
#define HAS_PRE_1970
-#define HAS_POST_2038
+#define HAS_POST_2038
#define HAS_STD_ISNAN
#define HAS_STD_MUTEX
-#ifndef _MSC_VER
-#define HAS_BUILTIN_OVERFLOW_CHECK
-#endif
+#ifndef _MSC_VER
+#define HAS_BUILTIN_OVERFLOW_CHECK
+#endif
/* #undef NEEDS_REDUNDANT_MOVE */
/* #undef NEEDS_Z_PREFIX */
@@ -170,40 +170,40 @@ namespace orc {
std::string to_string(int64_t val);
}
-#ifdef HAS_BUILTIN_OVERFLOW_CHECK
- #define multiplyExact !__builtin_mul_overflow
- #define addExact !__builtin_add_overflow
-#else
-namespace orc {
- /**
- * Compute value * repetitions, return false if overflow, return true otherwise
- * and save the result at the address pointed to by result
- * imitates the jdk Math.multiplyExact implementation
- * but this method makes the assumption that repetitions > 1
- */
- static bool multiplyExact(int64_t value, int64_t repetitions, int64_t* result) {
- int64_t r = value * repetitions;
- if (((value < 0 ? -value : value) | repetitions) >> 31 != 0 && r / repetitions != value) {
- return false;
- }
- *result = r;
- return true;
- }
-
- /**
- * imitates the jdk Math.addExact implementation
- */
- static bool addExact(int64_t sum, int64_t increment, int64_t* result) {
- int64_t r = sum + increment;
- if (((sum ^ r) & (increment ^ r)) < 0) {
- return false;
- }
- *result = r;
- return true;
- }
-}
-#endif
-
+#ifdef HAS_BUILTIN_OVERFLOW_CHECK
+ #define multiplyExact !__builtin_mul_overflow
+ #define addExact !__builtin_add_overflow
+#else
+namespace orc {
+ /**
+ * Compute value * repetitions, return false if overflow, return true otherwise
+ * and save the result at the address pointed to by result
+ * imitates the jdk Math.multiplyExact implementation
+ * but this method makes the assumption that repetitions > 1
+ */
+ static bool multiplyExact(int64_t value, int64_t repetitions, int64_t* result) {
+ int64_t r = value * repetitions;
+ if (((value < 0 ? -value : value) | repetitions) >> 31 != 0 && r / repetitions != value) {
+ return false;
+ }
+ *result = r;
+ return true;
+ }
+
+ /**
+ * imitates the jdk Math.addExact implementation
+ */
+ static bool addExact(int64_t sum, int64_t increment, int64_t* result) {
+ int64_t r = sum + increment;
+ if (((sum ^ r) & (increment ^ r)) < 0) {
+ return false;
+ }
+ *result = r;
+ return true;
+ }
+}
+#endif
+
#ifndef HAS_CONSTEXPR
#define constexpr const
#endif
diff --git a/contrib/libs/apache/orc/c++/src/BloomFilter.cc b/contrib/libs/apache/orc/c++/src/BloomFilter.cc
index 42eded0065..8a1f1880e7 100644
--- a/contrib/libs/apache/orc/c++/src/BloomFilter.cc
+++ b/contrib/libs/apache/orc/c++/src/BloomFilter.cc
@@ -135,20 +135,20 @@ namespace orc {
void BloomFilterImpl::addBytes(const char * data, int64_t length) {
uint64_t hash64 = getBytesHash(data, length);
- addHash(static_cast<int64_t>(hash64));
+ addHash(static_cast<int64_t>(hash64));
}
void BloomFilterImpl::addLong(int64_t data) {
- addHash(getLongHash(data));
+ addHash(getLongHash(data));
}
bool BloomFilterImpl::testBytes(const char * data, int64_t length) const {
uint64_t hash64 = getBytesHash(data, length);
- return testHash(static_cast<int64_t>(hash64));
+ return testHash(static_cast<int64_t>(hash64));
}
bool BloomFilterImpl::testLong(int64_t data) const {
- return testHash(getLongHash(data));
+ return testHash(getLongHash(data));
}
uint64_t BloomFilterImpl::sizeInBytes() const {
@@ -210,11 +210,11 @@ namespace orc {
DIAGNOSTIC_POP
- void BloomFilterImpl::addHash(int64_t hash64) {
+ void BloomFilterImpl::addHash(int64_t hash64) {
int32_t hash1 = static_cast<int32_t>(hash64 & 0xffffffff);
- // In Java codes, we use "hash64 >>> 32" which is an unsigned shift op.
- // So we cast hash64 to uint64_t here for an unsigned right shift.
- int32_t hash2 = static_cast<int32_t>(static_cast<uint64_t>(hash64) >> 32);
+ // In Java codes, we use "hash64 >>> 32" which is an unsigned shift op.
+ // So we cast hash64 to uint64_t here for an unsigned right shift.
+ int32_t hash2 = static_cast<int32_t>(static_cast<uint64_t>(hash64) >> 32);
for (int32_t i = 1; i <= mNumHashFunctions; ++i) {
int32_t combinedHash = hash1 + i * hash2;
@@ -227,11 +227,11 @@ namespace orc {
}
}
- bool BloomFilterImpl::testHash(int64_t hash64) const{
+ bool BloomFilterImpl::testHash(int64_t hash64) const{
int32_t hash1 = static_cast<int32_t>(hash64 & 0xffffffff);
- // In Java codes, we use "hash64 >>> 32" which is an unsigned shift op.
- // So we cast hash64 to uint64_t here for an unsigned right shift.
- int32_t hash2 = static_cast<int32_t>(static_cast<uint64_t>(hash64) >> 32);
+ // In Java codes, we use "hash64 >>> 32" which is an unsigned shift op.
+ // So we cast hash64 to uint64_t here for an unsigned right shift.
+ int32_t hash2 = static_cast<int32_t>(static_cast<uint64_t>(hash64) >> 32);
for (int32_t i = 1; i <= mNumHashFunctions; ++i) {
int32_t combinedHash = hash1 + i * hash2;
diff --git a/contrib/libs/apache/orc/c++/src/BloomFilter.hh b/contrib/libs/apache/orc/c++/src/BloomFilter.hh
index e98fbd75cf..cf18a46fd9 100644
--- a/contrib/libs/apache/orc/c++/src/BloomFilter.hh
+++ b/contrib/libs/apache/orc/c++/src/BloomFilter.hh
@@ -162,13 +162,13 @@ namespace orc {
private:
friend struct BloomFilterUTF8Utils;
- friend class TestBloomFilter_testBloomFilterBasicOperations_Test;
+ friend class TestBloomFilter_testBloomFilterBasicOperations_Test;
// compute k hash values from hash64 and set bits
- void addHash(int64_t hash64);
+ void addHash(int64_t hash64);
// compute k hash values from hash64 and check bits
- bool testHash(int64_t hash64) const;
+ bool testHash(int64_t hash64) const;
void serialize(proto::BloomFilter& bloomFilter) const;
@@ -192,19 +192,19 @@ namespace orc {
const proto::BloomFilter& bloomFilter);
};
- // Thomas Wang's integer hash function
- // http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm
- // Put this in header file so tests can use it as well.
- inline int64_t getLongHash(int64_t key) {
- key = (~key) + (key << 21); // key = (key << 21) - key - 1;
- key = key ^ (key >> 24);
- key = (key + (key << 3)) + (key << 8); // key * 265
- key = key ^ (key >> 14);
- key = (key + (key << 2)) + (key << 4); // key * 21
- key = key ^ (key >> 28);
- key = key + (key << 31);
- return key;
- }
+ // Thomas Wang's integer hash function
+ // http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm
+ // Put this in header file so tests can use it as well.
+ inline int64_t getLongHash(int64_t key) {
+ key = (~key) + (key << 21); // key = (key << 21) - key - 1;
+ key = key ^ (key >> 24);
+ key = (key + (key << 3)) + (key << 8); // key * 265
+ key = key ^ (key >> 14);
+ key = (key + (key << 2)) + (key << 4); // key * 21
+ key = key ^ (key >> 28);
+ key = key + (key << 31);
+ return key;
+ }
}
#endif //ORC_BLOOMFILTER_IMPL_HH
diff --git a/contrib/libs/apache/orc/c++/src/ColumnReader.cc b/contrib/libs/apache/orc/c++/src/ColumnReader.cc
index 113484fafd..8cf660be11 100644
--- a/contrib/libs/apache/orc/c++/src/ColumnReader.cc
+++ b/contrib/libs/apache/orc/c++/src/ColumnReader.cc
@@ -374,7 +374,7 @@ namespace orc {
}
int64_t writerTime = secsBuffer[i] + epochOffset;
secsBuffer[i] = writerTimezone.convertToUTC(writerTime);
- if (secsBuffer[i] < 0 && nanoBuffer[i] > 999999) {
+ if (secsBuffer[i] < 0 && nanoBuffer[i] > 999999) {
secsBuffer[i] -= 1;
}
}
diff --git a/contrib/libs/apache/orc/c++/src/ColumnWriter.cc b/contrib/libs/apache/orc/c++/src/ColumnWriter.cc
index 958e07c23c..1408a15457 100644
--- a/contrib/libs/apache/orc/c++/src/ColumnWriter.cc
+++ b/contrib/libs/apache/orc/c++/src/ColumnWriter.cc
@@ -1811,7 +1811,7 @@ namespace orc {
}
tsStats->update(millsUTC);
- if (secs[i] < 0 && nanos[i] > 999999) {
+ if (secs[i] < 0 && nanos[i] > 999999) {
secs[i] += 1;
}
diff --git a/contrib/libs/apache/orc/c++/src/Common.cc b/contrib/libs/apache/orc/c++/src/Common.cc
index bda3ab1f14..dbf073797e 100644
--- a/contrib/libs/apache/orc/c++/src/Common.cc
+++ b/contrib/libs/apache/orc/c++/src/Common.cc
@@ -58,38 +58,38 @@ namespace orc {
return "ORC-101";
case WriterVersion_ORC_135:
return "ORC-135";
- case WriterVersion_ORC_517:
- return "ORC-517";
- case WriterVersion_ORC_203:
- return "ORC-203";
- case WriterVersion_ORC_14:
- return "ORC-14";
+ case WriterVersion_ORC_517:
+ return "ORC-517";
+ case WriterVersion_ORC_203:
+ return "ORC-203";
+ case WriterVersion_ORC_14:
+ return "ORC-14";
}
std::stringstream buffer;
buffer << "future - " << version;
return buffer.str();
}
- std::string writerIdToString(uint32_t id) {
- switch (id) {
- case ORC_JAVA_WRITER:
- return "ORC Java";
- case ORC_CPP_WRITER:
- return "ORC C++";
- case PRESTO_WRITER:
- return "Presto";
- case SCRITCHLEY_GO:
- return "Scritchley Go";
- case TRINO_WRITER:
- return "Trino";
- default: {
- std::ostringstream buffer;
- buffer << "Unknown(" << id << ")";
- return buffer.str();
- }
- }
- }
-
+ std::string writerIdToString(uint32_t id) {
+ switch (id) {
+ case ORC_JAVA_WRITER:
+ return "ORC Java";
+ case ORC_CPP_WRITER:
+ return "ORC C++";
+ case PRESTO_WRITER:
+ return "Presto";
+ case SCRITCHLEY_GO:
+ return "Scritchley Go";
+ case TRINO_WRITER:
+ return "Trino";
+ default: {
+ std::ostringstream buffer;
+ buffer << "Unknown(" << id << ")";
+ return buffer.str();
+ }
+ }
+ }
+
std::string streamKindToString(StreamKind kind) {
switch (static_cast<int>(kind)) {
case StreamKind_PRESENT:
diff --git a/contrib/libs/apache/orc/c++/src/Compression.cc b/contrib/libs/apache/orc/c++/src/Compression.cc
index 6d96970a5a..4278ed7aae 100644
--- a/contrib/libs/apache/orc/c++/src/Compression.cc
+++ b/contrib/libs/apache/orc/c++/src/Compression.cc
@@ -292,7 +292,7 @@ DIAGNOSTIC_PUSH
strm.zalloc = nullptr;
strm.zfree = nullptr;
strm.opaque = nullptr;
- strm.next_in = nullptr;
+ strm.next_in = nullptr;
if (deflateInit2(&strm, level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY)
!= Z_OK) {
@@ -1031,16 +1031,16 @@ DIAGNOSTIC_POP
capacity,
blockSize,
pool) {
- this->init();
+ this->init();
}
virtual std::string getName() const override {
return "ZstdCompressionStream";
}
-
- virtual ~ZSTDCompressionStream() override {
- this->end();
- }
+
+ virtual ~ZSTDCompressionStream() override {
+ this->end();
+ }
protected:
virtual uint64_t doBlockCompression() override;
@@ -1048,44 +1048,44 @@ DIAGNOSTIC_POP
virtual uint64_t estimateMaxCompressionSize() override {
return ZSTD_compressBound(static_cast<size_t>(bufferSize));
}
-
- private:
- void init();
- void end();
- ZSTD_CCtx *cctx;
+
+ private:
+ void init();
+ void end();
+ ZSTD_CCtx *cctx;
};
uint64_t ZSTDCompressionStream::doBlockCompression() {
- return ZSTD_compressCCtx(cctx,
- compressorBuffer.data(),
- compressorBuffer.size(),
- rawInputBuffer.data(),
- static_cast<size_t>(bufferSize),
- level);
+ return ZSTD_compressCCtx(cctx,
+ compressorBuffer.data(),
+ compressorBuffer.size(),
+ rawInputBuffer.data(),
+ static_cast<size_t>(bufferSize),
+ level);
+ }
+
+DIAGNOSTIC_PUSH
+
+#if defined(__GNUC__) || defined(__clang__)
+ DIAGNOSTIC_IGNORE("-Wold-style-cast")
+#endif
+
+ void ZSTDCompressionStream::init() {
+
+ cctx = ZSTD_createCCtx();
+ if (!cctx) {
+ throw std::runtime_error("Error while calling ZSTD_createCCtx() for zstd.");
+ }
+ }
+
+
+ void ZSTDCompressionStream::end() {
+ (void)ZSTD_freeCCtx(cctx);
+ cctx = nullptr;
}
-
-DIAGNOSTIC_PUSH
-
-#if defined(__GNUC__) || defined(__clang__)
- DIAGNOSTIC_IGNORE("-Wold-style-cast")
-#endif
-
- void ZSTDCompressionStream::init() {
-
- cctx = ZSTD_createCCtx();
- if (!cctx) {
- throw std::runtime_error("Error while calling ZSTD_createCCtx() for zstd.");
- }
- }
-
-
- void ZSTDCompressionStream::end() {
- (void)ZSTD_freeCCtx(cctx);
- cctx = nullptr;
- }
-
-DIAGNOSTIC_PUSH
-
+
+DIAGNOSTIC_PUSH
+
/**
* ZSTD block decompression
*/
@@ -1097,13 +1097,13 @@ DIAGNOSTIC_PUSH
: BlockDecompressionStream(std::move(inStream),
blockSize,
pool) {
- this->init();
+ this->init();
+ }
+
+ virtual ~ZSTDDecompressionStream() override {
+ this->end();
}
- virtual ~ZSTDDecompressionStream() override {
- this->end();
- }
-
std::string getName() const override {
std::ostringstream result;
result << "zstd(" << getStreamName() << ")";
@@ -1115,46 +1115,46 @@ DIAGNOSTIC_PUSH
uint64_t length,
char *output,
size_t maxOutputLength) override;
-
- private:
- void init();
- void end();
- ZSTD_DCtx *dctx;
+
+ private:
+ void init();
+ void end();
+ ZSTD_DCtx *dctx;
};
uint64_t ZSTDDecompressionStream::decompress(const char *input,
uint64_t length,
char *output,
size_t maxOutputLength) {
- return static_cast<uint64_t>(ZSTD_decompressDCtx(dctx,
- output,
- maxOutputLength,
- input,
- length));
+ return static_cast<uint64_t>(ZSTD_decompressDCtx(dctx,
+ output,
+ maxOutputLength,
+ input,
+ length));
+ }
+
+DIAGNOSTIC_PUSH
+
+#if defined(__GNUC__) || defined(__clang__)
+ DIAGNOSTIC_IGNORE("-Wold-style-cast")
+#endif
+
+ void ZSTDDecompressionStream::init() {
+
+ dctx = ZSTD_createDCtx();
+ if (!dctx) {
+ throw std::runtime_error("Error while calling ZSTD_createDCtx() for zstd.");
+ }
}
-DIAGNOSTIC_PUSH
-
-#if defined(__GNUC__) || defined(__clang__)
- DIAGNOSTIC_IGNORE("-Wold-style-cast")
-#endif
-
- void ZSTDDecompressionStream::init() {
-
- dctx = ZSTD_createDCtx();
- if (!dctx) {
- throw std::runtime_error("Error while calling ZSTD_createDCtx() for zstd.");
- }
- }
-
-
- void ZSTDDecompressionStream::end() {
- (void)ZSTD_freeDCtx(dctx);
- dctx = nullptr;
- }
-
-DIAGNOSTIC_PUSH
-
+
+ void ZSTDDecompressionStream::end() {
+ (void)ZSTD_freeDCtx(dctx);
+ dctx = nullptr;
+ }
+
+DIAGNOSTIC_PUSH
+
std::unique_ptr<BufferedOutputStream>
createCompressor(
CompressionKind kind,
diff --git a/contrib/libs/apache/orc/c++/src/OrcFile.cc b/contrib/libs/apache/orc/c++/src/OrcFile.cc
index 1ec2c06036..a0158bbadf 100644
--- a/contrib/libs/apache/orc/c++/src/OrcFile.cc
+++ b/contrib/libs/apache/orc/c++/src/OrcFile.cc
@@ -30,8 +30,8 @@
#include <io.h>
#define S_IRUSR _S_IREAD
#define S_IWUSR _S_IWRITE
-#define stat _stat64
-#define fstat _fstat64
+#define stat _stat64
+#define fstat _fstat64
#else
#include <unistd.h>
#define O_BINARY 0
diff --git a/contrib/libs/apache/orc/c++/src/Reader.cc b/contrib/libs/apache/orc/c++/src/Reader.cc
index fc559a6cc3..f35106ee44 100644
--- a/contrib/libs/apache/orc/c++/src/Reader.cc
+++ b/contrib/libs/apache/orc/c++/src/Reader.cc
@@ -491,7 +491,7 @@ namespace orc {
WriterId ReaderImpl::getWriterId() const {
if (footer->has_writer()) {
uint32_t id = footer->writer();
- if (id > WriterId::TRINO_WRITER) {
+ if (id > WriterId::TRINO_WRITER) {
return WriterId::UNKNOWN_WRITER;
} else {
return static_cast<WriterId>(id);
@@ -508,15 +508,15 @@ namespace orc {
}
}
- std::string ReaderImpl::getSoftwareVersion() const {
- std::ostringstream buffer;
- buffer << writerIdToString(getWriterIdValue());
- if (footer->has_softwareversion()) {
- buffer << " " << footer->softwareversion();
- }
- return buffer.str();
- }
-
+ std::string ReaderImpl::getSoftwareVersion() const {
+ std::ostringstream buffer;
+ buffer << writerIdToString(getWriterIdValue());
+ if (footer->has_softwareversion()) {
+ buffer << " " << footer->softwareversion();
+ }
+ return buffer.str();
+ }
+
WriterVersion ReaderImpl::getWriterVersion() const {
if (!contents->postscript->has_writerversion()) {
return WriterVersion_ORIGINAL;
diff --git a/contrib/libs/apache/orc/c++/src/Reader.hh b/contrib/libs/apache/orc/c++/src/Reader.hh
index 29a1e7d9c7..49e9d033d9 100644
--- a/contrib/libs/apache/orc/c++/src/Reader.hh
+++ b/contrib/libs/apache/orc/c++/src/Reader.hh
@@ -124,7 +124,7 @@ namespace orc {
proto::Footer* footer;
DataBuffer<uint64_t> firstRowOfStripe;
mutable std::unique_ptr<Type> selectedSchema;
- bool skipBloomFilters;
+ bool skipBloomFilters;
// reading state
uint64_t previousRow;
@@ -150,13 +150,13 @@ namespace orc {
*/
void seekToRowGroup(uint32_t rowGroupEntryId);
- /**
- * Check if the file has bad bloom filters. We will skip using them in the
- * following reads.
- * @return true if it has.
- */
- bool hasBadBloomFilters();
-
+ /**
+ * Check if the file has bad bloom filters. We will skip using them in the
+ * following reads.
+ * @return true if it has.
+ */
+ bool hasBadBloomFilters();
+
public:
/**
* Constructor that lets the user specify additional options.
@@ -238,8 +238,8 @@ namespace orc {
uint32_t getWriterIdValue() const override;
- std::string getSoftwareVersion() const override;
-
+ std::string getSoftwareVersion() const override;
+
WriterVersion getWriterVersion() const override;
uint64_t getNumberOfRows() const override;
diff --git a/contrib/libs/apache/orc/c++/src/RleEncoderV2.cc b/contrib/libs/apache/orc/c++/src/RleEncoderV2.cc
index 63c2753427..44e2761b74 100644
--- a/contrib/libs/apache/orc/c++/src/RleEncoderV2.cc
+++ b/contrib/libs/apache/orc/c++/src/RleEncoderV2.cc
@@ -123,7 +123,7 @@ void RleEncoderV2::write(int64_t val) {
numLiterals = MIN_REPEAT;
}
- if (fixedRunLength == MAX_LITERAL_SIZE) {
+ if (fixedRunLength == MAX_LITERAL_SIZE) {
determineEncoding(option);
writeValues(option);
}
@@ -696,7 +696,7 @@ void RleEncoderV2::writeInts(int64_t* input, uint32_t offset, size_t len, uint32
if (getClosestAlignedFixedBits(bitSize) == bitSize) {
uint32_t numBytes;
uint32_t endOffSet = static_cast<uint32_t>(offset + len);
- if (bitSize < 8 ) {
+ if (bitSize < 8 ) {
char bitMask = static_cast<char>((1 << bitSize) - 1);
uint32_t numHops = 8 / bitSize;
uint32_t remainder = static_cast<uint32_t>(len % numHops);
diff --git a/contrib/libs/apache/orc/c++/src/Statistics.hh b/contrib/libs/apache/orc/c++/src/Statistics.hh
index 7e1d92d502..ee9db23f86 100644
--- a/contrib/libs/apache/orc/c++/src/Statistics.hh
+++ b/contrib/libs/apache/orc/c++/src/Statistics.hh
@@ -94,7 +94,7 @@ namespace orc {
// GET / SET _maximum
bool hasMaximum() const { return _hasMaximum; }
- const T & getMaximum() const { return _maximum; }
+ const T & getMaximum() const { return _maximum; }
void setHasMaximum(bool hasMax) { _hasMaximum = hasMax; }
@@ -105,7 +105,7 @@ namespace orc {
void setHasMinimum(bool hasMin) { _hasMinimum = hasMin; }
- const T & getMinimum() const { return _minimum; }
+ const T & getMinimum() const { return _minimum; }
void setMinimum(T min) { _minimum = min; }
@@ -963,24 +963,24 @@ namespace orc {
_stats.setSum(sum);
}
- void update(int64_t value, int repetitions) {
- _stats.updateMinMax(value);
-
- if (_stats.hasSum()) {
- if (repetitions > 1) {
- _stats.setHasSum(multiplyExact(value, repetitions, &value));
- }
-
- if (_stats.hasSum()) {
- _stats.setHasSum(addExact(_stats.getSum(), value, &value));
-
- if (_stats.hasSum()) {
- _stats.setSum(value);
- }
- }
- }
- }
-
+ void update(int64_t value, int repetitions) {
+ _stats.updateMinMax(value);
+
+ if (_stats.hasSum()) {
+ if (repetitions > 1) {
+ _stats.setHasSum(multiplyExact(value, repetitions, &value));
+ }
+
+ if (_stats.hasSum()) {
+ _stats.setHasSum(addExact(_stats.getSum(), value, &value));
+
+ if (_stats.hasSum()) {
+ _stats.setSum(value);
+ }
+ }
+ }
+ }
+
void merge(const MutableColumnStatistics& other) override {
const IntegerColumnStatisticsImpl& intStats =
dynamic_cast<const IntegerColumnStatisticsImpl&>(other);
@@ -990,10 +990,10 @@ namespace orc {
// update sum and check overflow
_stats.setHasSum(_stats.hasSum() && intStats.hasSum());
if (_stats.hasSum()) {
- int64_t value;
- _stats.setHasSum(addExact(_stats.getSum(), intStats.getSum(), &value));
- if (_stats.hasSum()) {
- _stats.setSum(value);
+ int64_t value;
+ _stats.setHasSum(addExact(_stats.getSum(), intStats.getSum(), &value));
+ if (_stats.hasSum()) {
+ _stats.setSum(value);
}
}
}
@@ -1093,7 +1093,7 @@ namespace orc {
_stats.setHasNull(hasNull);
}
- const std::string & getMinimum() const override {
+ const std::string & getMinimum() const override {
if(hasMinimum()){
return _stats.getMinimum();
}else{
@@ -1101,7 +1101,7 @@ namespace orc {
}
}
- const std::string & getMaximum() const override {
+ const std::string & getMaximum() const override {
if(hasMaximum()){
return _stats.getMaximum();
}else{
diff --git a/contrib/libs/apache/orc/c++/src/Writer.cc b/contrib/libs/apache/orc/c++/src/Writer.cc
index 688c09cf30..b5bd19b304 100644
--- a/contrib/libs/apache/orc/c++/src/Writer.cc
+++ b/contrib/libs/apache/orc/c++/src/Writer.cc
@@ -379,7 +379,7 @@ namespace orc {
fileFooter.set_rowindexstride(
static_cast<uint32_t>(options.getRowIndexStride()));
fileFooter.set_writer(writerId);
- fileFooter.set_softwareversion(ORC_VERSION);
+ fileFooter.set_softwareversion(ORC_VERSION);
uint32_t index = 0;
buildFooterType(type, fileFooter, index);
diff --git a/contrib/libs/apache/orc/proto/orc_proto.proto b/contrib/libs/apache/orc/proto/orc_proto.proto
index 4faff52f85..e8b84dbecd 100644
--- a/contrib/libs/apache/orc/proto/orc_proto.proto
+++ b/contrib/libs/apache/orc/proto/orc_proto.proto
@@ -67,9 +67,9 @@ message TimestampStatistics {
optional sint64 maximum = 2;
optional sint64 minimumUtc = 3;
optional sint64 maximumUtc = 4;
- // store the lower 6 TS digits for min/max to achieve nanosecond precision
- optional int32 minimumNanos = 5;
- optional int32 maximumNanos = 6;
+ // store the lower 6 TS digits for min/max to achieve nanosecond precision
+ optional int32 minimumNanos = 5;
+ optional int32 maximumNanos = 6;
}
message BinaryStatistics {
@@ -343,14 +343,14 @@ message Encryption {
optional KeyProviderKind keyProvider = 4;
}
-enum CalendarKind {
- UNKNOWN_CALENDAR = 0;
- // A hybrid Julian/Gregorian calendar with a cutover point in October 1582.
- JULIAN_GREGORIAN = 1;
- // A calendar that extends the Gregorian calendar back forever.
- PROLEPTIC_GREGORIAN = 2;
-}
-
+enum CalendarKind {
+ UNKNOWN_CALENDAR = 0;
+ // A hybrid Julian/Gregorian calendar with a cutover point in October 1582.
+ JULIAN_GREGORIAN = 1;
+ // A calendar that extends the Gregorian calendar back forever.
+ PROLEPTIC_GREGORIAN = 2;
+}
+
message Footer {
optional uint64 headerLength = 1;
optional uint64 contentLength = 2;
@@ -370,12 +370,12 @@ message Footer {
// information about the encryption in this file
optional Encryption encryption = 10;
- optional CalendarKind calendar = 11;
-
- // informative description about the version of the software that wrote
- // the file. It is assumed to be within a given writer, so for example
- // ORC 1.7.2 = "1.7.2". It may include suffixes, such as "-SNAPSHOT".
- optional string softwareVersion = 12;
+ optional CalendarKind calendar = 11;
+
+ // informative description about the version of the software that wrote
+ // the file. It is assumed to be within a given writer, so for example
+ // ORC 1.7.2 = "1.7.2". It may include suffixes, such as "-SNAPSHOT".
+ optional string softwareVersion = 12;
}
enum CompressionKind {
@@ -428,9 +428,9 @@ message PostScript {
// Version of the Scritchley Go writer:
// 6 = original
//
- // Version of the Trino writer:
- // 6 = original
- //
+ // Version of the Trino writer:
+ // 6 = original
+ //
optional uint32 writerVersion = 6;
// the number of bytes in the encrypted stripe statistics
diff --git a/contrib/libs/apache/orc/ya.make b/contrib/libs/apache/orc/ya.make
index 7c79b8b3d7..5672ba95db 100644
--- a/contrib/libs/apache/orc/ya.make
+++ b/contrib/libs/apache/orc/ya.make
@@ -7,11 +7,11 @@ OWNER(
g:cpp-contrib
)
-VERSION(1.6.12)
+VERSION(1.6.12)
-ORIGINAL_SOURCE(https://github.com/apache/orc/archive/rel/release-1.6.12.tar.gz)
-
-LICENSE(Apache-2.0)
+ORIGINAL_SOURCE(https://github.com/apache/orc/archive/rel/release-1.6.12.tar.gz)
+
+LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
diff --git a/contrib/libs/base64/ya.make b/contrib/libs/base64/ya.make
index 2497947b1b..659983fe66 100644
--- a/contrib/libs/base64/ya.make
+++ b/contrib/libs/base64/ya.make
@@ -4,8 +4,8 @@ OWNER(
g:cpp-contrib
)
-VERSION(0.3.0)
-
+VERSION(0.3.0)
+
RECURSE(
avx2
ssse3
diff --git a/contrib/libs/brotli/ya.make b/contrib/libs/brotli/ya.make
index 468a9b04ae..f0941aa638 100644
--- a/contrib/libs/brotli/ya.make
+++ b/contrib/libs/brotli/ya.make
@@ -1,5 +1,5 @@
-VERSION(1.0.1)
-
+VERSION(1.0.1)
+
RECURSE(
common
dec
diff --git a/contrib/libs/c-ares/CHANGES b/contrib/libs/c-ares/CHANGES
index 8b910b7737..f6652caaa0 100644
--- a/contrib/libs/c-ares/CHANGES
+++ b/contrib/libs/c-ares/CHANGES
@@ -1,559 +1,559 @@
Changelog for the c-ares project. Generated with git2changes.pl
-Version 1.16.1 (11 May 2020)
-
-Brad House (11 May 2020)
-- c-ares 1.16.1 release prep
-
-- update travis to use xcode11.4
-
-- Prevent possible double-free in ares_getaddrinfo() if ares_destroy() is called
-
- In the event that ares_destroy() is called prior to ares_getaddrinfo() completing,
- it would result in an invalid read and double-free due to calling end_hquery() twice.
-
- Reported By: Jann Horn @ Google Project Zero
-
-GitHub (30 Apr 2020)
-- [shelley vohr brought this change]
-
- fix: windows UNICODE incompatibilities with ares_getaddrinfo (#328)
-
- Fixes the following compatibility issues:
- * Use RegQueryValueExA instead of RegQueryValueEx
- * Use ExpandEnvironmentStringsA instead of ExpandEnvironmentStrings
- * Use RegOpenKeyExA instead of RegOpenKeyExA
- * Use GetWindowsDirectoryA instead of GetWindowsDirectoryA
-
- Fix By: Shelley Vohr (@codebytere)
- Closes: #327
-
-Brad House (13 Apr 2020)
-- travis: CloudFlare does not allow T_ANY requests, so live tests that use it fail. Disable.
-
-- travis: bump macos image to the latest
-
-- cast-align warnings are false for struct sockaddr, silence
-
- Create a macro to silence false cast-align warnings when casting
- struct sockaddr * to struct sockaddr_in * and struct sockaddr_in6 *.
-
- Fix By: Brad House (@bradh352)
-
-- MacOS: Enable libresolv support for retrieving DNS servers like iOS does.
-
-GitHub (10 Apr 2020)
-- [Dmitry Igrishin brought this change]
-
- CMake: Populate the INCLUDE_DIRECTORIES property of installed targets (#323)
-
- Populate the INCLUDE_DIRECTORIES property of installed targets
-
- Fix By: Dmitry Igrishin (@dmitigr)
-
-Brad House (10 Apr 2020)
-- travis: make valgrind use cmake for tests
-
-- dont try to use libtool to run valgrind
-
-- valgrind requires libtool installed to wrap tests
-
-- scan build 7
-
-- fix travis live test
-
-- add debug for travis
-
-- try without sudo
-
-- attempt to modernize travis build environment
-
-GitHub (6 Apr 2020)
-- [Teemu R brought this change]
-
- Allow TXT records on CHAOS qclass (#321)
-
- Some DNS servers intentionally "misuse" the obsoleted CHAOS (CH) qclass to provide things like `version.bind`, `version.server`, `authors.bind`, `hostname.bind` and `id.server`.
-
- C-ares was not allowing such use cases.
-
- Fix By: Teemu R. (@rytilahti)
-
-Brad House (5 Apr 2020)
-- Remove warnings from ares_getaddrinfo.3 man page
-
- As reported in #319, non-standard macros of .IN were used.
- Replace with .RS/.RE.
-
- Fixes: #319
- Fix By: Brad House (@bradh352)
-
-- ares_getaddrinfo man page render better for man2html
-
-- update man pages to render better for man2html
-
-Version 1.16.0 (12 Mar 2020)
-
-Brad House (12 Mar 2020)
-- 1.16.0 release notes draft
-
-- attempt to fix double-free introduced in e0517f9
-
-GitHub (12 Mar 2020)
-- [David Drysdale brought this change]
-
- test: fuzzer input triggering double free (#315)
-
- OSS-Fuzz has reported a double-free with the fuzzer input file
- included here; run with:
- ./test/aresfuzz test/fuzzinput/clusterfuzz-5637790584012800
-
- Bisecting the failure points to commit e0517f97d988 ("Parse SOA records
- from ns_t_any response (#103)")
-
-- [Brad House brought this change]
-
- CMake: Install Manpages (#314)
-
- CMake wasn't installing manpages.
-
- Fixes #297
- Fix By: Brad House (@bradh352)
-
-- [Brad House brought this change]
-
- Enable cmake tests for AppVeyor (#313)
-
- Tests require linking against the static library on Windows otherwise the symbols are not exported for internals being tested.
-
- Fix By: Brad House (@bradh352)
-
-Brad House (11 Mar 2020)
-- Add AppVeyor badge
-
-- bump c-ares version to 1.16.0. test AppVeyor integration.
-
-GitHub (11 Mar 2020)
-- [Brad House brought this change]
-
- replace all usages of inet_addr() with ares_inet_pton() which is more proper (#312)
-
- Replace usage of inet_addr() with ares_inet_pton() which is more appropriate and fixes issues with legitimate addresses like 255.255.255.0. IPv6 already used this.
-
- Fixes #309
- Fix By: Brad House (@bradh352)
-
-- [Brad House brought this change]
-
- CMake: Generate WinPDB files during build (#311)
-
- Build and Install PDB (Windows Debug Symbol) files if supported by underlying system.
-
- Also update AppVeyor to test cmake builds.
-
- Fixes #245
- Fix By: Piotr Pietraszkiewicz (@ppietrasa) and Brad House (@bradh352)
-
-- [Brad House brought this change]
-
- CMake: Rework library function checking (#310)
-
- CHECK_LIBRARY_EXISTS(), while it takes a function name, does not actually verify the function exists in the library being evaluated. Instead, if the function is found in any dependent library, and the referenced library also exists, it returns true. This is not desirable.
-
- Wrap with a Macro to change the behavior.
-
- Fixes: #307
- Fix By: Brad House (@bradh352)
-
-- [Dron Rathore brought this change]
-
- Parse SOA records from ns_t_any response (#103)
-
- Added the capability of parsing SOA record from a response buffer of ns_t_any type query, this implementation doesn't interfere with existing T_SOA query's response as that too is treated as a list of records. The function returns ARES_EBADRESP if no SOA record is found(as per RFC).
-
- The basic idea of sticking to RFC that a ns_t_any too should return an SOA record is something open for discussion but I have kept the functionality intact as it was previously i.e the function returns ARES_EBADRESP if it doesn't find a SOA record regardless of which response it is parsing i.e. T_SOA or T_ANY.
-
- Note that asking for T_ANY is generally a bad idea:
- - https://blog.cloudflare.com/what-happened-next-the-deprecation-of-any/
- - https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any
-
- Bug: #102
- Fix By: Dron Rathore (@DronRathore)
-
-- [Stephen Bryant brought this change]
-
- Added CPack functionality for generating RPM or DEB packages (#283)
-
- Added CPack functionality for generating RPM or DEB packages
-
- ie: run `cpack -G RPM` (or "DEB") after building with CMake.
-
- The current configuration creates 3 separate packages for the shared library,
- the development files and the tools.
-
- Fix By: Stephen Bryant (@bf-bryants)
-
-- [tjwalton brought this change]
-
- ares_gethostbyname: Return ENODATA if no valid A or AAAA record found (#304)
-
- ares_gethostbyname() was returning ESUCCESS when no A or AAAA record was found but a CNAME pointing nowhere was present. ENODATA should be returned instead, however the hosts pointer will still be present to provide the alias list.
-
- * Return ENODATA if no valid A or AAAA record found
- * Fix and update test ParseAReplyNoData.
- * Add test for new ENODATA behaviour in ares_gethostbyname.
-
- Fixes Bug #303
- Fix By: @tjwalton
-
-- [Michal Rostecki brought this change]
-
- test: Separate live tests from SetServers* tests (#299)
-
- Before this change, SetServers, SetServersPorts and SetServersCSV
- contained test cases trying to make DNS queries with the google.com
- hostname, which requires Internet connectivity. Tests with that
- requirement should be defined in the ares-test-live.cc file and contain
- "Live" prefix to filter them out with `--gtest_filter=-*.Live*` on
- machines without Internet connectivity.
-
- Fix By: Michal Rostecki (@mrostecki)
-
-- [Adam Majer brought this change]
-
- Only count valid addresses when response parsing (#302)
-
- When ares_parse_a_reply or ares_parse_aaaa_reply is called in case
- where another AAAA and A responses exist, the resulting ares_addrttl
- count is invalid and the structure points to gibberish.
-
- This is a regression since 1.15.
-
- Issue: https://github.com/c-ares/c-ares/issues/300
- Fix By: Adam Majer (@AdamMajer)
-
-Brad House (24 Dec 2019)
-- [Kyle Edwards brought this change]
-
- CMake: Provide c-ares version in package export file (#296)
-
- The CMake package export file should provide version information.
-
- Fix By: Kyle Edwards (@KyleFromKitware)
-
-- [Ben Noordhuis brought this change]
-
- Accept invalid /etc/resolv.conf lookup values, ability to build container tests (#274)
-
- * Add CARES_BUILD_CONTAINER_TESTS CMake option to add ability to build the Linux-only containerized tests.
- * Accept invalid /etc/resolv.conf lookup values
-
- Before this commit invalid `lookup` values resulted in c-ares not using
- any lookups without any clear indication why. After this commit it uses
- the default "fb".
-
- Fix By: Ben Noordhuis (@bnoordhuis)
-
-- [Christian Ammer brought this change]
-
- Parallel A and AAAA lookups in `ares_getaddrinfo` (#290)
-
- A and AAAA lookups for ares_getaddrinfo() are now performed in parallel.
-
- For this change `ares_search` was removed from `ares_getaddrinfo`.
- Instead `ares_query` in combination with `next_dns_lookup` are
- doing the suffix search.
-
- Adding support for `.onion` addresses which are tested by
- `TEST_F(DefaultChannelTest, GetAddrinfoOnionDomain)`
-
- Fix By: Christian Ammer (@ChristianAmmer)
-
-- [Vy Nguyen brought this change]
-
- Move variables into the block where it is used to avoid unused-vars (#281)
-
- Warning uncovered with [-Werror, -Wunused-variables]
-
- Fix By: Vy Nguyen (@oontvoo)
-
-- [Vy Nguyen brought this change]
-
- Rename local macros to avoid conflicting with system ones and remove unsed variables. (Otherwise code will break once compiled with [-Werror,-Wmacro-redefined,-Wunused-variable] ) (#280)
-
- Fix new getaddrinfo code to not redefine macros on some systems.
-
- Fix By: Vy Nguyen (@oontvoo)
-
-- [Egor Pugin brought this change]
-
- [ares_getenv] Return NULL in all cases. (#279)
-
- if ares_getenv is defined, it must return a value on all platforms.
-
- Fix By: Egor Pugin (@egorpugin)
-
-- [Abhishek Arya brought this change]
-
- Add OSS-Fuzz fuzzing badge (#278)
-
- Adds based on instructions at
- https://google.github.io/oss-fuzz/getting-started/new-project-guide/#status-badge
-
- Patch By: Abhishek Arya (@inferno-chromium)
-
-- [Peter Eisentraut brought this change]
-
- ares_init_options.3: Fix layout (#275)
-
- 7e6af8e inserted the documentation of resolvconf_path in the middle of
- the item for ednspsz, leading to broken layout. Fix that.
-
- Fix By: Peter Eisentraut (@petere)
-
-- [Gregor Jasny brought this change]
-
- manpages: Fix typos detected by lintian (#269)
-
-
- Fix By: Gregor Jasny (@gjasny)
-
-- [lifenjoiner brought this change]
-
- keep command line usage up to date (#256)
-
- adig and ahost built-in help did not match args taken.
-
- Fix-By: @lifenjoiner
-
-- [Dan Noé brought this change]
-
- ares-test.cc: Handle nullptr in AddrInfo ostream. (#268)
-
- The const AddrInfo& argument to operator<< overload for AddrInfo can be
- a nullptr unique_ptr. Handle this explicitly by printing {nullptr} if
- the rest of the function cannot be safely executed.
-
- Fix-by: Dan Noé <dpn@google.com>
-
-- [Dan Noé brought this change]
-
- Add missing limits.h include from ares_getaddrinfo.c (#267)
-
- This files references INT_MAX, but does not include limits.h. This can
- cause a build failure on some platforms. Include limits.h if we have it.
-
- Fix-by: Dan Noé <dpn@google.com>
-
-- [Andrew Selivanov brought this change]
-
- fix fuzzer docs and add missing getaddrinfo docs (#265)
-
- There is a fix for a bit outdated clang fuzzer docs and ares_getaddrinfo docs.
-
- Fix By: Andrew Selivanov (@ki11roy)
-
-- [Andrew Selivanov brought this change]
-
- Fix leak and crash in ares_parse_a/aaaa_reply (#264)
-
- * fix leak if naddress of particular type found
- * fix segfault when wanted ttls count lesser than count of result records
- * add fuzzer input files that trigger problems (from #263)
-
- Reported-By: David Drysdale (@daviddrysdale)
- Fix-By: Andrew Selivanov (@ki11roy)
-
-- [Andrew Selivanov brought this change]
-
- fix segfault when parsing wrong type of record (#262)
-
- Fixes segfault when trying to ares_parse_aaaa with AF_INET and vise versa.
-
- Fix By: Andrew Selivanov (@ki11roy)
-
-- work around mingw compile failure
-
-- c++ requires explicit casts
-
-- support EnvValue on Windows by implementing setenv/unsetenv
-
-- [Andrew Selivanov brought this change]
-
- getaddrinfo enhancements (#257)
-
- * Service support has been added to getaddrinfo.
- * ares_parse_a/aaaa_record now share code with the addrinfo parser.
- * Private ares_addrinfo structure with useful extensions such as ttls (including cname ttls),
- as well as the ability to list multiple cnames in chain of lookups
-
- Work By: Andrew Selivanov @ki11roy
-
-- [Andrew Selivanov brought this change]
-
- fix ares__sortaddrinfo, use wrappers for sock_funcs (#258)
-
- Some socket functions weren't exposed for use by other areas of the library. Expose
- those and make use of them in ares__sortaddrinfo().
-
- Fix By: Andrew Selivanov (@ki11roy)
-
-- Fix c89 compilation support broken by .onion rejection changes
-
- Move .onion check lower after all variables have been declared.
-
- Bug: #246
-
-- [kedixa brought this change]
-
- getaddrinfo: callback must be called on bad domain (#249)
-
- Due to an order of incrementing the remaining queries and calling ares_query, on a bad domain
- the registered callback wouldn't be called.
-
- Bug: #248
- Fixed-By: @kedixa
-
-- [Darrin W. Cullop brought this change]
-
- Windows ARM/ARM64 requires AdvApi32 (#252)
-
- Fix link issues caused by missing library that appears to only be required on ARM (though
- docs don't list this restriction). Doesn't hurt to require it everywhere.
-
- Bug: #251
- Fixed-By: Darrin Cullop (@dwcullop)
-
-- [kedixa brought this change]
-
- getaddrinfo: avoid infinite loop in case of NXDOMAIN(#240) (#242)
-
- There are two possible causes for infinite loops fo NXDOMAIN, based on how many dots are in the domain name (one for < ARES_OPT_NDOTS and one for >= ARES_OPT_NDOTS), where it will repeat the same query over and over as the hquery->next_domain doesn't increment.
-
- Fix By: @kedixa
-
-- Portability fix for ares__sortaddrinfo()
-
- replace uint32_t with unsigned int and socklen_t with ares_socklen_t
-
- By: Brad House
-
-- [Khaidi Chu brought this change]
-
- fix: init bufp before reject .onion to make it can be free correctly (#241)
-
- When querying a .onion domain, it returns directly without setting bufp to NULL. A subsequent free() that occurs can cause a segmentation fault.
-
- Fix By: Khaidi Chu (@XadillaX)
-
-- [Andrew Selivanov brought this change]
-
- Add ares__sortaddrinfo() to support getaddrinfo() sorted results (#239)
-
- This is a port of RFC 6724 compliant sorting function from Android Bionic project:
- https://android.googlesource.com/platform/bionic/+/e919b116d35aa7deb24ddece69c491e24c3b0d6f/libc/netbsd/net/getaddrinfo.c
-
- The latest version is essentially the same, except two additional parameters to test connection with (mark/uid):
- https://android.googlesource.com/platform/bionic/+/master/libc/dns/net/getaddrinfo.c
-
- Please note that even that version has some restrictions. It doesn't support some rules from RFC 6724:
-
- Rule 3 (Avoid deprecated addresses)
- Rule 4 (Prefer home addresses)
- Rule 7 (Prefer native transport)
-
- Submitted By: Andrew Selivanov (@ki11roy)
-
-- [Christian Ammer brought this change]
-
- Increase portability of `ares-test-mock-ai.cc` (#235)
-
- * using portable ares_inet_pton and updated includes in ares-test-mock-ai
- * forgot to remove deleted ares-test-ai.cc in Makefile.inc
-
- Fix By: Christian Ammer (@ChristianAmmer)
-
-- [Fabrice Fontaine brought this change]
-
- m4/xc-cc-check.m4: use XC_CHECK_BUILD_FLAGS (#236)
-
- Use XC_CHECK_BUILD_FLAGS instead of XC_CHECK_USER_FLAGS.
- Otherwise it complains of CPPFLAGS in CFLAGS.
- [Retrieved from:
- https://git.buildroot.net/buildroot/tree/package/c-ares/0001-use_check_build_instead_of_check_user.patch]
-
- Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
- Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
- Submitted by: Fabrice Fontaine
-
-- [Christian Ammer brought this change]
-
- Bugfix for `ares_getaddrinfo` and additional unit tests (#234)
-
- This PullRequest fixes a bug in the function add_to_addrinfo which task is to add new addrinfo items to the ai_next linked list. Also additional unit tests for testing ares_getaddrinfo will be added:
-
- Additional mock server test classes (ares-test-mock-ai.cc):
- MockTCPChannelTestAI
- MockExtraOptsTestAI
- MockNoCheckRespChannelTestAI
- MockEDNSChannelTestAI
- RotateMultiMockTestAI
- NoRotateMultiMockTestAI
-
- Additional live tests (ares-test-live-ai.cc):
- LiveGetHostByNameV4
- LiveGetHostByNameV6
- LiveGetHostByNameV4AndV6
-
- Fix By: Christian Ammer (@ChristianAmmer)
-
-- [Christian Ammer brought this change]
-
- Remaining queries counter fix, additional unit tests for `ares_getaddrinfo` (#233)
-
- Remaining queries counter fix, added tests (ParallelLookups,
- SearchDomains, SearchDomainsServFailOnAAAA). Removed unnecessary
- if and commented code in test.
-
- Fix By: Christian Ammer (@ChristianAmmer)
-
-- [Christian Ammer brought this change]
-
- Add initial implementation for ares_getaddrinfo (#112)
-
- Initial implementation for ares_getaddrinfo(). It is NOT compliant with RFC6724, though
- it is expected to come closer to conformance prior to the next release.
-
- Features not supported include sorted addresses and honoring of service and hints
- parameters.
-
- Implementation by: Christian Ammer (@ChristianAmmer)
-
-- [Ben Noordhuis brought this change]
-
- test: fix bad expectation in ipv6 localhost test (#227)
-
- The LiveGetLocalhostByAddrV6 test expected to see "localhost" in the
- result when doing an address-to-name lookup for ::1 but on my system
- that resolves to "ip6-loopback" because of this stanza in /etc/hosts:
-
- $ grep ^::1 /etc/hosts
- ::1 ip6-localhost ip6-loopback
-
- Fix By: Ben Noordhuis (@bnoordhuis)
- Bug: #85
-
-- [Ben Noordhuis brought this change]
-
- ares_version.h: bump version (#230)
-
- Version change not committed from maketgz.sh
-
- Bug: #229
-
-Daniel Stenberg (24 Oct 2018)
-- ares_library_init_android.3: minor syntax edits, fixed AVAILABILITY
-
+Version 1.16.1 (11 May 2020)
+
+Brad House (11 May 2020)
+- c-ares 1.16.1 release prep
+
+- update travis to use xcode11.4
+
+- Prevent possible double-free in ares_getaddrinfo() if ares_destroy() is called
+
+ In the event that ares_destroy() is called prior to ares_getaddrinfo() completing,
+ it would result in an invalid read and double-free due to calling end_hquery() twice.
+
+ Reported By: Jann Horn @ Google Project Zero
+
+GitHub (30 Apr 2020)
+- [shelley vohr brought this change]
+
+ fix: windows UNICODE incompatibilities with ares_getaddrinfo (#328)
+
+ Fixes the following compatibility issues:
+ * Use RegQueryValueExA instead of RegQueryValueEx
+ * Use ExpandEnvironmentStringsA instead of ExpandEnvironmentStrings
+ * Use RegOpenKeyExA instead of RegOpenKeyExA
+ * Use GetWindowsDirectoryA instead of GetWindowsDirectoryA
+
+ Fix By: Shelley Vohr (@codebytere)
+ Closes: #327
+
+Brad House (13 Apr 2020)
+- travis: CloudFlare does not allow T_ANY requests, so live tests that use it fail. Disable.
+
+- travis: bump macos image to the latest
+
+- cast-align warnings are false for struct sockaddr, silence
+
+ Create a macro to silence false cast-align warnings when casting
+ struct sockaddr * to struct sockaddr_in * and struct sockaddr_in6 *.
+
+ Fix By: Brad House (@bradh352)
+
+- MacOS: Enable libresolv support for retrieving DNS servers like iOS does.
+
+GitHub (10 Apr 2020)
+- [Dmitry Igrishin brought this change]
+
+ CMake: Populate the INCLUDE_DIRECTORIES property of installed targets (#323)
+
+ Populate the INCLUDE_DIRECTORIES property of installed targets
+
+ Fix By: Dmitry Igrishin (@dmitigr)
+
+Brad House (10 Apr 2020)
+- travis: make valgrind use cmake for tests
+
+- dont try to use libtool to run valgrind
+
+- valgrind requires libtool installed to wrap tests
+
+- scan build 7
+
+- fix travis live test
+
+- add debug for travis
+
+- try without sudo
+
+- attempt to modernize travis build environment
+
+GitHub (6 Apr 2020)
+- [Teemu R brought this change]
+
+ Allow TXT records on CHAOS qclass (#321)
+
+ Some DNS servers intentionally "misuse" the obsoleted CHAOS (CH) qclass to provide things like `version.bind`, `version.server`, `authors.bind`, `hostname.bind` and `id.server`.
+
+ C-ares was not allowing such use cases.
+
+ Fix By: Teemu R. (@rytilahti)
+
+Brad House (5 Apr 2020)
+- Remove warnings from ares_getaddrinfo.3 man page
+
+ As reported in #319, non-standard macros of .IN were used.
+ Replace with .RS/.RE.
+
+ Fixes: #319
+ Fix By: Brad House (@bradh352)
+
+- ares_getaddrinfo man page render better for man2html
+
+- update man pages to render better for man2html
+
+Version 1.16.0 (12 Mar 2020)
+
+Brad House (12 Mar 2020)
+- 1.16.0 release notes draft
+
+- attempt to fix double-free introduced in e0517f9
+
+GitHub (12 Mar 2020)
+- [David Drysdale brought this change]
+
+ test: fuzzer input triggering double free (#315)
+
+ OSS-Fuzz has reported a double-free with the fuzzer input file
+ included here; run with:
+ ./test/aresfuzz test/fuzzinput/clusterfuzz-5637790584012800
+
+ Bisecting the failure points to commit e0517f97d988 ("Parse SOA records
+ from ns_t_any response (#103)")
+
+- [Brad House brought this change]
+
+ CMake: Install Manpages (#314)
+
+ CMake wasn't installing manpages.
+
+ Fixes #297
+ Fix By: Brad House (@bradh352)
+
+- [Brad House brought this change]
+
+ Enable cmake tests for AppVeyor (#313)
+
+ Tests require linking against the static library on Windows otherwise the symbols are not exported for internals being tested.
+
+ Fix By: Brad House (@bradh352)
+
+Brad House (11 Mar 2020)
+- Add AppVeyor badge
+
+- bump c-ares version to 1.16.0. test AppVeyor integration.
+
+GitHub (11 Mar 2020)
+- [Brad House brought this change]
+
+ replace all usages of inet_addr() with ares_inet_pton() which is more proper (#312)
+
+ Replace usage of inet_addr() with ares_inet_pton() which is more appropriate and fixes issues with legitimate addresses like 255.255.255.0. IPv6 already used this.
+
+ Fixes #309
+ Fix By: Brad House (@bradh352)
+
+- [Brad House brought this change]
+
+ CMake: Generate WinPDB files during build (#311)
+
+ Build and Install PDB (Windows Debug Symbol) files if supported by underlying system.
+
+ Also update AppVeyor to test cmake builds.
+
+ Fixes #245
+ Fix By: Piotr Pietraszkiewicz (@ppietrasa) and Brad House (@bradh352)
+
+- [Brad House brought this change]
+
+ CMake: Rework library function checking (#310)
+
+ CHECK_LIBRARY_EXISTS(), while it takes a function name, does not actually verify the function exists in the library being evaluated. Instead, if the function is found in any dependent library, and the referenced library also exists, it returns true. This is not desirable.
+
+ Wrap with a Macro to change the behavior.
+
+ Fixes: #307
+ Fix By: Brad House (@bradh352)
+
+- [Dron Rathore brought this change]
+
+ Parse SOA records from ns_t_any response (#103)
+
+ Added the capability of parsing SOA record from a response buffer of ns_t_any type query, this implementation doesn't interfere with existing T_SOA query's response as that too is treated as a list of records. The function returns ARES_EBADRESP if no SOA record is found(as per RFC).
+
+ The basic idea of sticking to RFC that a ns_t_any too should return an SOA record is something open for discussion but I have kept the functionality intact as it was previously i.e the function returns ARES_EBADRESP if it doesn't find a SOA record regardless of which response it is parsing i.e. T_SOA or T_ANY.
+
+ Note that asking for T_ANY is generally a bad idea:
+ - https://blog.cloudflare.com/what-happened-next-the-deprecation-of-any/
+ - https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any
+
+ Bug: #102
+ Fix By: Dron Rathore (@DronRathore)
+
+- [Stephen Bryant brought this change]
+
+ Added CPack functionality for generating RPM or DEB packages (#283)
+
+ Added CPack functionality for generating RPM or DEB packages
+
+ ie: run `cpack -G RPM` (or "DEB") after building with CMake.
+
+ The current configuration creates 3 separate packages for the shared library,
+ the development files and the tools.
+
+ Fix By: Stephen Bryant (@bf-bryants)
+
+- [tjwalton brought this change]
+
+ ares_gethostbyname: Return ENODATA if no valid A or AAAA record found (#304)
+
+ ares_gethostbyname() was returning ESUCCESS when no A or AAAA record was found but a CNAME pointing nowhere was present. ENODATA should be returned instead, however the hosts pointer will still be present to provide the alias list.
+
+ * Return ENODATA if no valid A or AAAA record found
+ * Fix and update test ParseAReplyNoData.
+ * Add test for new ENODATA behaviour in ares_gethostbyname.
+
+ Fixes Bug #303
+ Fix By: @tjwalton
+
+- [Michal Rostecki brought this change]
+
+ test: Separate live tests from SetServers* tests (#299)
+
+ Before this change, SetServers, SetServersPorts and SetServersCSV
+ contained test cases trying to make DNS queries with the google.com
+ hostname, which requires Internet connectivity. Tests with that
+ requirement should be defined in the ares-test-live.cc file and contain
+ "Live" prefix to filter them out with `--gtest_filter=-*.Live*` on
+ machines without Internet connectivity.
+
+ Fix By: Michal Rostecki (@mrostecki)
+
+- [Adam Majer brought this change]
+
+ Only count valid addresses when response parsing (#302)
+
+ When ares_parse_a_reply or ares_parse_aaaa_reply is called in case
+ where another AAAA and A responses exist, the resulting ares_addrttl
+ count is invalid and the structure points to gibberish.
+
+ This is a regression since 1.15.
+
+ Issue: https://github.com/c-ares/c-ares/issues/300
+ Fix By: Adam Majer (@AdamMajer)
+
+Brad House (24 Dec 2019)
+- [Kyle Edwards brought this change]
+
+ CMake: Provide c-ares version in package export file (#296)
+
+ The CMake package export file should provide version information.
+
+ Fix By: Kyle Edwards (@KyleFromKitware)
+
+- [Ben Noordhuis brought this change]
+
+ Accept invalid /etc/resolv.conf lookup values, ability to build container tests (#274)
+
+ * Add CARES_BUILD_CONTAINER_TESTS CMake option to add ability to build the Linux-only containerized tests.
+ * Accept invalid /etc/resolv.conf lookup values
+
+ Before this commit invalid `lookup` values resulted in c-ares not using
+ any lookups without any clear indication why. After this commit it uses
+ the default "fb".
+
+ Fix By: Ben Noordhuis (@bnoordhuis)
+
+- [Christian Ammer brought this change]
+
+ Parallel A and AAAA lookups in `ares_getaddrinfo` (#290)
+
+ A and AAAA lookups for ares_getaddrinfo() are now performed in parallel.
+
+ For this change `ares_search` was removed from `ares_getaddrinfo`.
+ Instead `ares_query` in combination with `next_dns_lookup` are
+ doing the suffix search.
+
+ Adding support for `.onion` addresses which are tested by
+ `TEST_F(DefaultChannelTest, GetAddrinfoOnionDomain)`
+
+ Fix By: Christian Ammer (@ChristianAmmer)
+
+- [Vy Nguyen brought this change]
+
+ Move variables into the block where it is used to avoid unused-vars (#281)
+
+ Warning uncovered with [-Werror, -Wunused-variables]
+
+ Fix By: Vy Nguyen (@oontvoo)
+
+- [Vy Nguyen brought this change]
+
+ Rename local macros to avoid conflicting with system ones and remove unsed variables. (Otherwise code will break once compiled with [-Werror,-Wmacro-redefined,-Wunused-variable] ) (#280)
+
+ Fix new getaddrinfo code to not redefine macros on some systems.
+
+ Fix By: Vy Nguyen (@oontvoo)
+
+- [Egor Pugin brought this change]
+
+ [ares_getenv] Return NULL in all cases. (#279)
+
+ if ares_getenv is defined, it must return a value on all platforms.
+
+ Fix By: Egor Pugin (@egorpugin)
+
+- [Abhishek Arya brought this change]
+
+ Add OSS-Fuzz fuzzing badge (#278)
+
+ Adds based on instructions at
+ https://google.github.io/oss-fuzz/getting-started/new-project-guide/#status-badge
+
+ Patch By: Abhishek Arya (@inferno-chromium)
+
+- [Peter Eisentraut brought this change]
+
+ ares_init_options.3: Fix layout (#275)
+
+ 7e6af8e inserted the documentation of resolvconf_path in the middle of
+ the item for ednspsz, leading to broken layout. Fix that.
+
+ Fix By: Peter Eisentraut (@petere)
+
+- [Gregor Jasny brought this change]
+
+ manpages: Fix typos detected by lintian (#269)
+
+
+ Fix By: Gregor Jasny (@gjasny)
+
+- [lifenjoiner brought this change]
+
+ keep command line usage up to date (#256)
+
+ adig and ahost built-in help did not match args taken.
+
+ Fix-By: @lifenjoiner
+
+- [Dan Noé brought this change]
+
+ ares-test.cc: Handle nullptr in AddrInfo ostream. (#268)
+
+ The const AddrInfo& argument to operator<< overload for AddrInfo can be
+ a nullptr unique_ptr. Handle this explicitly by printing {nullptr} if
+ the rest of the function cannot be safely executed.
+
+ Fix-by: Dan Noé <dpn@google.com>
+
+- [Dan Noé brought this change]
+
+ Add missing limits.h include from ares_getaddrinfo.c (#267)
+
+ This files references INT_MAX, but does not include limits.h. This can
+ cause a build failure on some platforms. Include limits.h if we have it.
+
+ Fix-by: Dan Noé <dpn@google.com>
+
+- [Andrew Selivanov brought this change]
+
+ fix fuzzer docs and add missing getaddrinfo docs (#265)
+
+ There is a fix for a bit outdated clang fuzzer docs and ares_getaddrinfo docs.
+
+ Fix By: Andrew Selivanov (@ki11roy)
+
+- [Andrew Selivanov brought this change]
+
+ Fix leak and crash in ares_parse_a/aaaa_reply (#264)
+
+ * fix leak if naddress of particular type found
+ * fix segfault when wanted ttls count lesser than count of result records
+ * add fuzzer input files that trigger problems (from #263)
+
+ Reported-By: David Drysdale (@daviddrysdale)
+ Fix-By: Andrew Selivanov (@ki11roy)
+
+- [Andrew Selivanov brought this change]
+
+ fix segfault when parsing wrong type of record (#262)
+
+ Fixes segfault when trying to ares_parse_aaaa with AF_INET and vise versa.
+
+ Fix By: Andrew Selivanov (@ki11roy)
+
+- work around mingw compile failure
+
+- c++ requires explicit casts
+
+- support EnvValue on Windows by implementing setenv/unsetenv
+
+- [Andrew Selivanov brought this change]
+
+ getaddrinfo enhancements (#257)
+
+ * Service support has been added to getaddrinfo.
+ * ares_parse_a/aaaa_record now share code with the addrinfo parser.
+ * Private ares_addrinfo structure with useful extensions such as ttls (including cname ttls),
+ as well as the ability to list multiple cnames in chain of lookups
+
+ Work By: Andrew Selivanov @ki11roy
+
+- [Andrew Selivanov brought this change]
+
+ fix ares__sortaddrinfo, use wrappers for sock_funcs (#258)
+
+ Some socket functions weren't exposed for use by other areas of the library. Expose
+ those and make use of them in ares__sortaddrinfo().
+
+ Fix By: Andrew Selivanov (@ki11roy)
+
+- Fix c89 compilation support broken by .onion rejection changes
+
+ Move .onion check lower after all variables have been declared.
+
+ Bug: #246
+
+- [kedixa brought this change]
+
+ getaddrinfo: callback must be called on bad domain (#249)
+
+ Due to an order of incrementing the remaining queries and calling ares_query, on a bad domain
+ the registered callback wouldn't be called.
+
+ Bug: #248
+ Fixed-By: @kedixa
+
+- [Darrin W. Cullop brought this change]
+
+ Windows ARM/ARM64 requires AdvApi32 (#252)
+
+ Fix link issues caused by missing library that appears to only be required on ARM (though
+ docs don't list this restriction). Doesn't hurt to require it everywhere.
+
+ Bug: #251
+ Fixed-By: Darrin Cullop (@dwcullop)
+
+- [kedixa brought this change]
+
+ getaddrinfo: avoid infinite loop in case of NXDOMAIN(#240) (#242)
+
+ There are two possible causes for infinite loops fo NXDOMAIN, based on how many dots are in the domain name (one for < ARES_OPT_NDOTS and one for >= ARES_OPT_NDOTS), where it will repeat the same query over and over as the hquery->next_domain doesn't increment.
+
+ Fix By: @kedixa
+
+- Portability fix for ares__sortaddrinfo()
+
+ replace uint32_t with unsigned int and socklen_t with ares_socklen_t
+
+ By: Brad House
+
+- [Khaidi Chu brought this change]
+
+ fix: init bufp before reject .onion to make it can be free correctly (#241)
+
+ When querying a .onion domain, it returns directly without setting bufp to NULL. A subsequent free() that occurs can cause a segmentation fault.
+
+ Fix By: Khaidi Chu (@XadillaX)
+
+- [Andrew Selivanov brought this change]
+
+ Add ares__sortaddrinfo() to support getaddrinfo() sorted results (#239)
+
+ This is a port of RFC 6724 compliant sorting function from Android Bionic project:
+ https://android.googlesource.com/platform/bionic/+/e919b116d35aa7deb24ddece69c491e24c3b0d6f/libc/netbsd/net/getaddrinfo.c
+
+ The latest version is essentially the same, except two additional parameters to test connection with (mark/uid):
+ https://android.googlesource.com/platform/bionic/+/master/libc/dns/net/getaddrinfo.c
+
+ Please note that even that version has some restrictions. It doesn't support some rules from RFC 6724:
+
+ Rule 3 (Avoid deprecated addresses)
+ Rule 4 (Prefer home addresses)
+ Rule 7 (Prefer native transport)
+
+ Submitted By: Andrew Selivanov (@ki11roy)
+
+- [Christian Ammer brought this change]
+
+ Increase portability of `ares-test-mock-ai.cc` (#235)
+
+ * using portable ares_inet_pton and updated includes in ares-test-mock-ai
+ * forgot to remove deleted ares-test-ai.cc in Makefile.inc
+
+ Fix By: Christian Ammer (@ChristianAmmer)
+
+- [Fabrice Fontaine brought this change]
+
+ m4/xc-cc-check.m4: use XC_CHECK_BUILD_FLAGS (#236)
+
+ Use XC_CHECK_BUILD_FLAGS instead of XC_CHECK_USER_FLAGS.
+ Otherwise it complains of CPPFLAGS in CFLAGS.
+ [Retrieved from:
+ https://git.buildroot.net/buildroot/tree/package/c-ares/0001-use_check_build_instead_of_check_user.patch]
+
+ Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
+ Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
+ Submitted by: Fabrice Fontaine
+
+- [Christian Ammer brought this change]
+
+ Bugfix for `ares_getaddrinfo` and additional unit tests (#234)
+
+ This PullRequest fixes a bug in the function add_to_addrinfo which task is to add new addrinfo items to the ai_next linked list. Also additional unit tests for testing ares_getaddrinfo will be added:
+
+ Additional mock server test classes (ares-test-mock-ai.cc):
+ MockTCPChannelTestAI
+ MockExtraOptsTestAI
+ MockNoCheckRespChannelTestAI
+ MockEDNSChannelTestAI
+ RotateMultiMockTestAI
+ NoRotateMultiMockTestAI
+
+ Additional live tests (ares-test-live-ai.cc):
+ LiveGetHostByNameV4
+ LiveGetHostByNameV6
+ LiveGetHostByNameV4AndV6
+
+ Fix By: Christian Ammer (@ChristianAmmer)
+
+- [Christian Ammer brought this change]
+
+ Remaining queries counter fix, additional unit tests for `ares_getaddrinfo` (#233)
+
+ Remaining queries counter fix, added tests (ParallelLookups,
+ SearchDomains, SearchDomainsServFailOnAAAA). Removed unnecessary
+ if and commented code in test.
+
+ Fix By: Christian Ammer (@ChristianAmmer)
+
+- [Christian Ammer brought this change]
+
+ Add initial implementation for ares_getaddrinfo (#112)
+
+ Initial implementation for ares_getaddrinfo(). It is NOT compliant with RFC6724, though
+ it is expected to come closer to conformance prior to the next release.
+
+ Features not supported include sorted addresses and honoring of service and hints
+ parameters.
+
+ Implementation by: Christian Ammer (@ChristianAmmer)
+
+- [Ben Noordhuis brought this change]
+
+ test: fix bad expectation in ipv6 localhost test (#227)
+
+ The LiveGetLocalhostByAddrV6 test expected to see "localhost" in the
+ result when doing an address-to-name lookup for ::1 but on my system
+ that resolves to "ip6-loopback" because of this stanza in /etc/hosts:
+
+ $ grep ^::1 /etc/hosts
+ ::1 ip6-localhost ip6-loopback
+
+ Fix By: Ben Noordhuis (@bnoordhuis)
+ Bug: #85
+
+- [Ben Noordhuis brought this change]
+
+ ares_version.h: bump version (#230)
+
+ Version change not committed from maketgz.sh
+
+ Bug: #229
+
+Daniel Stenberg (24 Oct 2018)
+- ares_library_init_android.3: minor syntax edits, fixed AVAILABILITY
+
Version 1.15.0 (23 Oct 2018)
Brad House (23 Oct 2018)
diff --git a/contrib/libs/c-ares/README.md b/contrib/libs/c-ares/README.md
index ef78c8e65b..148338f9e1 100644
--- a/contrib/libs/c-ares/README.md
+++ b/contrib/libs/c-ares/README.md
@@ -2,10 +2,10 @@ c-ares
======
[![Build Status](https://travis-ci.org/c-ares/c-ares.svg?branch=master)](https://travis-ci.org/c-ares/c-ares)
-[![Windows Build Status](https://ci.appveyor.com/api/projects/status/aevgc5914tm72pvs/branch/master?svg=true)](https://ci.appveyor.com/project/c-ares/c-ares/branch/master)
+[![Windows Build Status](https://ci.appveyor.com/api/projects/status/aevgc5914tm72pvs/branch/master?svg=true)](https://ci.appveyor.com/project/c-ares/c-ares/branch/master)
[![Coverage Status](https://coveralls.io/repos/c-ares/c-ares/badge.svg?branch=master&service=github)](https://coveralls.io/github/c-ares/c-ares?branch=master)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/291/badge)](https://bestpractices.coreinfrastructure.org/projects/291)
-[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/c-ares.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:c-ares)
+[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/c-ares.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:c-ares)
[![Releases](https://coderelease.io/badge/c-ares/c-ares)](https://coderelease.io/github/repository/c-ares/c-ares)
This is c-ares, an asynchronous resolver library. It is intended for
diff --git a/contrib/libs/c-ares/RELEASE-NOTES b/contrib/libs/c-ares/RELEASE-NOTES
index 5caf0bb7ef..7a9d75fe78 100644
--- a/contrib/libs/c-ares/RELEASE-NOTES
+++ b/contrib/libs/c-ares/RELEASE-NOTES
@@ -1,30 +1,30 @@
-c-ares version 1.16.1
+c-ares version 1.16.1
+
+Security:
+ o Prevent possible use-after-free and double-free in ares_getaddrinfo() if
+ ares_destroy() is called prior to ares_getaddrinfo() completing. Reported
+ by Jann Horn at Google Project Zero.
-Security:
- o Prevent possible use-after-free and double-free in ares_getaddrinfo() if
- ares_destroy() is called prior to ares_getaddrinfo() completing. Reported
- by Jann Horn at Google Project Zero.
-
Changes:
- o Allow TXT records on CHAOS qclass. Used for retriving things like
- version.bind, version.server, authoris.bind, hostname.bind, and id.server.
- [3]
+ o Allow TXT records on CHAOS qclass. Used for retriving things like
+ version.bind, version.server, authoris.bind, hostname.bind, and id.server.
+ [3]
Bug fixes:
- o Fix Windows Unicode incompatibilities with ares_getaddrinfo() [1]
- o Silence false cast-align compiler warnings due to valid casts of
- struct sockaddr to struct sockaddr_in and struct sockaddr_in6.
- o MacOS should use libresolv for retrieving DNS servers, like iOS
- o CMake build system should populate the INCLUDE_DIRECTORIES property of
- installed targets [2]
- o Correct macros in use for the ares_getaddrinfo.3 man page
+ o Fix Windows Unicode incompatibilities with ares_getaddrinfo() [1]
+ o Silence false cast-align compiler warnings due to valid casts of
+ struct sockaddr to struct sockaddr_in and struct sockaddr_in6.
+ o MacOS should use libresolv for retrieving DNS servers, like iOS
+ o CMake build system should populate the INCLUDE_DIRECTORIES property of
+ installed targets [2]
+ o Correct macros in use for the ares_getaddrinfo.3 man page
Thanks go to these friendly people for their efforts and contributions:
- Brad House (@bradh352), Daniel Stenberg (@bagder), Dmitry Igrishin (@dmitigr),
- Jann Horn, Shelly Vohr, Teemu R (@rytilahti)
- (6 contributors)
+ Brad House (@bradh352), Daniel Stenberg (@bagder), Dmitry Igrishin (@dmitigr),
+ Jann Horn, Shelly Vohr, Teemu R (@rytilahti)
+ (6 contributors)
References to bug reports and discussions on issues:
- [1] = https://github.com/c-ares/c-ares/pull/328
- [2] = https://github.com/c-ares/c-ares/pull/323
- [3] = https://github.com/c-ares/c-ares/pull/321
+ [1] = https://github.com/c-ares/c-ares/pull/328
+ [2] = https://github.com/c-ares/c-ares/pull/323
+ [3] = https://github.com/c-ares/c-ares/pull/321
diff --git a/contrib/libs/c-ares/acountry.c b/contrib/libs/c-ares/acountry.c
index 68f66fa16d..c486824434 100644
--- a/contrib/libs/c-ares/acountry.c
+++ b/contrib/libs/c-ares/acountry.c
@@ -69,12 +69,12 @@
#define INADDR_NONE 0xffffffff
#endif
-/* By using a double cast, we can get rid of the bogus warning of
- * warning: cast from 'const struct sockaddr *' to 'const struct sockaddr_in6 *' increases required alignment from 1 to 4 [-Wcast-align]
- */
-#define CARES_INADDR_CAST(type, var) ((type)((void *)var))
-
-static const char *usage = "acountry [-?hdv] {host|addr} ...\n";
+/* By using a double cast, we can get rid of the bogus warning of
+ * warning: cast from 'const struct sockaddr *' to 'const struct sockaddr_in6 *' increases required alignment from 1 to 4 [-Wcast-align]
+ */
+#define CARES_INADDR_CAST(type, var) ((type)((void *)var))
+
+static const char *usage = "acountry [-?hdv] {host|addr} ...\n";
static const char nerd_fmt[] = "%u.%u.%u.%u.zz.countries.nerd.dk";
static const char *nerd_ver1 = nerd_fmt + 14; /* .countries.nerd.dk */
static const char *nerd_ver2 = nerd_fmt + 11; /* .zz.countries.nerd.dk */
@@ -238,7 +238,7 @@ static void callback(void *arg, int status, int timeouts, struct hostent *host)
if (!cname)
printf("Failed to get CNAME for %s\n", name);
else
- find_country_from_cname(cname, *(CARES_INADDR_CAST(struct in_addr *, host->h_addr)));
+ find_country_from_cname(cname, *(CARES_INADDR_CAST(struct in_addr *, host->h_addr)));
}
/*
diff --git a/contrib/libs/c-ares/adig.c b/contrib/libs/c-ares/adig.c
index 2e97c0db3f..2d5cb8c876 100644
--- a/contrib/libs/c-ares/adig.c
+++ b/contrib/libs/c-ares/adig.c
@@ -795,8 +795,8 @@ static const char *class_name(int dnsclass)
static void usage(void)
{
- fprintf(stderr, "usage: adig [-h] [-d] [-f flag] [-s server] [-c class] "
- "[-t type] [-T|U port] name ...\n");
+ fprintf(stderr, "usage: adig [-h] [-d] [-f flag] [-s server] [-c class] "
+ "[-t type] [-T|U port] name ...\n");
exit(1);
}
diff --git a/contrib/libs/c-ares/ahost.c b/contrib/libs/c-ares/ahost.c
index 5748de9ae3..89a7c14fcb 100644
--- a/contrib/libs/c-ares/ahost.c
+++ b/contrib/libs/c-ares/ahost.c
@@ -201,6 +201,6 @@ static void callback(void *arg, int status, int timeouts, struct hostent *host)
static void usage(void)
{
- fprintf(stderr, "usage: ahost [-h] [-d] [-s {domain}] [-t {a|aaaa|u}] {host|addr} ...\n");
+ fprintf(stderr, "usage: ahost [-h] [-d] [-s {domain}] [-t {a|aaaa|u}] {host|addr} ...\n");
exit(1);
}
diff --git a/contrib/libs/c-ares/ares.h b/contrib/libs/c-ares/ares.h
index 05abaa8fc2..3f8a6954d0 100644
--- a/contrib/libs/c-ares/ares.h
+++ b/contrib/libs/c-ares/ares.h
@@ -135,9 +135,9 @@ extern "C" {
/* More error codes */
#define ARES_ECANCELLED 24 /* introduced in 1.7.0 */
-/* More ares_getaddrinfo error codes */
-#define ARES_ESERVICE 25 /* introduced in 1.?.0 */
-
+/* More ares_getaddrinfo error codes */
+#define ARES_ESERVICE 25 /* introduced in 1.?.0 */
+
/* Flag values */
#define ARES_FLAG_USEVC (1 << 0)
#define ARES_FLAG_PRIMARY (1 << 1)
@@ -197,8 +197,8 @@ extern "C" {
#define ARES_AI_V4MAPPED (1 << 4)
#define ARES_AI_ALL (1 << 5)
#define ARES_AI_ADDRCONFIG (1 << 6)
-#define ARES_AI_NOSORT (1 << 7)
-#define ARES_AI_ENVHOSTS (1 << 8)
+#define ARES_AI_NOSORT (1 << 7)
+#define ARES_AI_ENVHOSTS (1 << 8)
/* Reserved for future use */
#define ARES_AI_IDN (1 << 10)
#define ARES_AI_IDN_ALLOW_UNASSIGNED (1 << 11)
@@ -288,8 +288,8 @@ struct hostent;
struct timeval;
struct sockaddr;
struct ares_channeldata;
-struct ares_addrinfo;
-struct ares_addrinfo_hints;
+struct ares_addrinfo;
+struct ares_addrinfo_hints;
typedef struct ares_channeldata *ares_channel;
@@ -318,11 +318,11 @@ typedef int (*ares_sock_config_callback)(ares_socket_t socket_fd,
int type,
void *data);
-typedef void (*ares_addrinfo_callback)(void *arg,
- int status,
- int timeouts,
- struct ares_addrinfo *res);
-
+typedef void (*ares_addrinfo_callback)(void *arg,
+ int status,
+ int timeouts,
+ struct ares_addrinfo *res);
+
CARES_EXTERN int ares_library_init(int flags);
CARES_EXTERN int ares_library_init_mem(int flags,
@@ -386,15 +386,15 @@ CARES_EXTERN void ares_set_socket_configure_callback(ares_channel channel,
CARES_EXTERN int ares_set_sortlist(ares_channel channel,
const char *sortstr);
-CARES_EXTERN void ares_getaddrinfo(ares_channel channel,
- const char* node,
- const char* service,
- const struct ares_addrinfo_hints* hints,
- ares_addrinfo_callback callback,
- void* arg);
-
-CARES_EXTERN void ares_freeaddrinfo(struct ares_addrinfo* ai);
-
+CARES_EXTERN void ares_getaddrinfo(ares_channel channel,
+ const char* node,
+ const char* service,
+ const struct ares_addrinfo_hints* hints,
+ ares_addrinfo_callback callback,
+ void* arg);
+
+CARES_EXTERN void ares_freeaddrinfo(struct ares_addrinfo* ai);
+
/*
* Virtual function set to have user-managed socket IO.
* Note that all functions need to be defined, and when
@@ -591,44 +591,44 @@ struct ares_soa_reply {
};
/*
- * Similar to addrinfo, but with extra ttl and missing canonname.
- */
-struct ares_addrinfo_node {
- int ai_ttl;
- int ai_flags;
- int ai_family;
- int ai_socktype;
- int ai_protocol;
- ares_socklen_t ai_addrlen;
- struct sockaddr *ai_addr;
- struct ares_addrinfo_node *ai_next;
-};
-
-/*
- * alias - label of the resource record.
- * name - value (canonical name) of the resource record.
- * See RFC2181 10.1.1. CNAME terminology.
- */
-struct ares_addrinfo_cname {
- int ttl;
- char *alias;
- char *name;
- struct ares_addrinfo_cname *next;
-};
-
-struct ares_addrinfo {
- struct ares_addrinfo_cname *cnames;
- struct ares_addrinfo_node *nodes;
-};
-
-struct ares_addrinfo_hints {
- int ai_flags;
- int ai_family;
- int ai_socktype;
- int ai_protocol;
-};
-
-/*
+ * Similar to addrinfo, but with extra ttl and missing canonname.
+ */
+struct ares_addrinfo_node {
+ int ai_ttl;
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ ares_socklen_t ai_addrlen;
+ struct sockaddr *ai_addr;
+ struct ares_addrinfo_node *ai_next;
+};
+
+/*
+ * alias - label of the resource record.
+ * name - value (canonical name) of the resource record.
+ * See RFC2181 10.1.1. CNAME terminology.
+ */
+struct ares_addrinfo_cname {
+ int ttl;
+ char *alias;
+ char *name;
+ struct ares_addrinfo_cname *next;
+};
+
+struct ares_addrinfo {
+ struct ares_addrinfo_cname *cnames;
+ struct ares_addrinfo_node *nodes;
+};
+
+struct ares_addrinfo_hints {
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+};
+
+/*
** Parse the buffer, starting at *abuf and of length alen bytes, previously
** obtained from an ares_search call. Put the results in *host, if nonnull.
** Also, if addrttls is nonnull, put up to *naddrttls IPv4 addresses along with
diff --git a/contrib/libs/c-ares/ares__close_sockets.c b/contrib/libs/c-ares/ares__close_sockets.c
index b06668d2b7..0477174e3e 100644
--- a/contrib/libs/c-ares/ares__close_sockets.c
+++ b/contrib/libs/c-ares/ares__close_sockets.c
@@ -48,14 +48,14 @@ void ares__close_sockets(ares_channel channel, struct server_state *server)
if (server->tcp_socket != ARES_SOCKET_BAD)
{
SOCK_STATE_CALLBACK(channel, server->tcp_socket, 0, 0);
- ares__close_socket(channel, server->tcp_socket);
+ ares__close_socket(channel, server->tcp_socket);
server->tcp_socket = ARES_SOCKET_BAD;
server->tcp_connection_generation = ++channel->tcp_connection_generation;
}
if (server->udp_socket != ARES_SOCKET_BAD)
{
SOCK_STATE_CALLBACK(channel, server->udp_socket, 0, 0);
- ares__close_socket(channel, server->udp_socket);
+ ares__close_socket(channel, server->udp_socket);
server->udp_socket = ARES_SOCKET_BAD;
}
}
diff --git a/contrib/libs/c-ares/ares__get_hostent.c b/contrib/libs/c-ares/ares__get_hostent.c
index 67203e5a25..367f39037b 100644
--- a/contrib/libs/c-ares/ares__get_hostent.c
+++ b/contrib/libs/c-ares/ares__get_hostent.c
@@ -138,7 +138,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
addr.addrV4.s_addr = INADDR_NONE;
if ((family == AF_INET) || (family == AF_UNSPEC))
{
- if (ares_inet_pton(AF_INET, txtaddr, &addr.addrV4) > 0)
+ if (ares_inet_pton(AF_INET, txtaddr, &addr.addrV4) > 0)
{
/* Actual network address family and length. */
addr.family = AF_INET;
diff --git a/contrib/libs/c-ares/ares__parse_into_addrinfo.c b/contrib/libs/c-ares/ares__parse_into_addrinfo.c
index 51e88d0134..b0801632b4 100644
--- a/contrib/libs/c-ares/ares__parse_into_addrinfo.c
+++ b/contrib/libs/c-ares/ares__parse_into_addrinfo.c
@@ -1,266 +1,266 @@
-/* Copyright (C) 2019 by Andrew Selivanov
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting
- * documentation, and that the name of M.I.T. not be used in
- * advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- */
-
-#include "ares_setup.h"
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-# include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-# include <arpa/inet.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
-
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-
-#ifdef HAVE_LIMITS_H
-# include <limits.h>
-#endif
-
-#include "ares.h"
-#include "ares_dns.h"
-#include "ares_private.h"
-
-int ares__parse_into_addrinfo2(const unsigned char *abuf,
- int alen,
- char **question_hostname,
- struct ares_addrinfo *ai)
-{
- unsigned int qdcount, ancount;
- int status, i, rr_type, rr_class, rr_len, rr_ttl;
- int got_a = 0, got_aaaa = 0, got_cname = 0;
- long len;
- const unsigned char *aptr;
- char *hostname, *rr_name = NULL, *rr_data;
- struct ares_addrinfo_cname *cname, *cnames = NULL;
- struct ares_addrinfo_node *node, *nodes = NULL;
- struct sockaddr_in *sin;
- struct sockaddr_in6 *sin6;
-
- *question_hostname = NULL;
-
- /* Give up if abuf doesn't have room for a header. */
- if (alen < HFIXEDSZ)
- return ARES_EBADRESP;
-
- /* Fetch the question and answer count from the header. */
- qdcount = DNS_HEADER_QDCOUNT(abuf);
- ancount = DNS_HEADER_ANCOUNT(abuf);
- if (qdcount != 1)
- return ARES_EBADRESP;
-
-
- /* Expand the name from the question, and skip past the question. */
- aptr = abuf + HFIXEDSZ;
- status = ares__expand_name_for_response(aptr, abuf, alen, question_hostname, &len);
- if (status != ARES_SUCCESS)
- return status;
- if (aptr + len + QFIXEDSZ > abuf + alen)
- {
- return ARES_EBADRESP;
- }
-
- hostname = *question_hostname;
-
- aptr += len + QFIXEDSZ;
-
- /* Examine each answer resource record (RR) in turn. */
- for (i = 0; i < (int)ancount; i++)
- {
- /* Decode the RR up to the data field. */
- status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
- if (status != ARES_SUCCESS)
- {
- rr_name = NULL;
- goto failed_stat;
- }
-
- aptr += len;
- if (aptr + RRFIXEDSZ > abuf + alen)
- {
- status = ARES_EBADRESP;
- goto failed_stat;
- }
- rr_type = DNS_RR_TYPE(aptr);
- rr_class = DNS_RR_CLASS(aptr);
- rr_len = DNS_RR_LEN(aptr);
- rr_ttl = DNS_RR_TTL(aptr);
- aptr += RRFIXEDSZ;
- if (aptr + rr_len > abuf + alen)
- {
- status = ARES_EBADRESP;
- goto failed_stat;
- }
-
- if (rr_class == C_IN && rr_type == T_A
- && rr_len == sizeof(struct in_addr)
- && strcasecmp(rr_name, hostname) == 0)
- {
- got_a = 1;
- if (aptr + sizeof(struct in_addr) > abuf + alen)
- { /* LCOV_EXCL_START: already checked above */
- status = ARES_EBADRESP;
- goto failed_stat;
- } /* LCOV_EXCL_STOP */
-
- node = ares__append_addrinfo_node(&nodes);
- if (!node)
- {
- status = ARES_ENOMEM;
- goto failed_stat;
- }
-
- sin = ares_malloc(sizeof(struct sockaddr_in));
- if (!sin)
- {
- status = ARES_ENOMEM;
- goto failed_stat;
- }
- memset(sin, 0, sizeof(struct sockaddr_in));
- memcpy(&sin->sin_addr.s_addr, aptr, sizeof(struct in_addr));
- sin->sin_family = AF_INET;
-
- node->ai_addr = (struct sockaddr *)sin;
- node->ai_family = AF_INET;
- node->ai_addrlen = sizeof(struct sockaddr_in);
-
- node->ai_ttl = rr_ttl;
-
- status = ARES_SUCCESS;
- }
- else if (rr_class == C_IN && rr_type == T_AAAA
- && rr_len == sizeof(struct ares_in6_addr)
- && strcasecmp(rr_name, hostname) == 0)
- {
- got_aaaa = 1;
- if (aptr + sizeof(struct ares_in6_addr) > abuf + alen)
- { /* LCOV_EXCL_START: already checked above */
- status = ARES_EBADRESP;
- goto failed_stat;
- } /* LCOV_EXCL_STOP */
-
- node = ares__append_addrinfo_node(&nodes);
- if (!node)
- {
- status = ARES_ENOMEM;
- goto failed_stat;
- }
-
- sin6 = ares_malloc(sizeof(struct sockaddr_in6));
- if (!sin6)
- {
- status = ARES_ENOMEM;
- goto failed_stat;
- }
-
- memset(sin6, 0, sizeof(struct sockaddr_in6));
- memcpy(&sin6->sin6_addr.s6_addr, aptr, sizeof(struct ares_in6_addr));
- sin6->sin6_family = AF_INET6;
-
- node->ai_addr = (struct sockaddr *)sin6;
- node->ai_family = AF_INET6;
- node->ai_addrlen = sizeof(struct sockaddr_in6);
-
- node->ai_ttl = rr_ttl;
-
- status = ARES_SUCCESS;
- }
-
- if (rr_class == C_IN && rr_type == T_CNAME)
- {
- got_cname = 1;
- status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
- &len);
- if (status != ARES_SUCCESS)
- {
- goto failed_stat;
- }
-
- /* Decode the RR data and replace the hostname with it. */
- /* SA: Seems wrong as it introduses order dependency. */
- hostname = rr_data;
-
- cname = ares__append_addrinfo_cname(&cnames);
- if (!cname)
- {
- status = ARES_ENOMEM;
- ares_free(rr_data);
- goto failed_stat;
- }
- cname->ttl = rr_ttl;
- cname->alias = rr_name;
- cname->name = rr_data;
- }
- else
- {
- ares_free(rr_name);
- }
-
-
- aptr += rr_len;
- if (aptr > abuf + alen)
- { /* LCOV_EXCL_START: already checked above */
- status = ARES_EBADRESP;
- goto failed_stat;
- } /* LCOV_EXCL_STOP */
- }
-
- if (status == ARES_SUCCESS)
- {
- ares__addrinfo_cat_nodes(&ai->nodes, nodes);
- if (got_cname)
- {
- ares__addrinfo_cat_cnames(&ai->cnames, cnames);
- return status;
- }
- else if (got_a == 0 && got_aaaa == 0)
- {
- /* the check for naliases to be zero is to make sure CNAME responses
- don't get caught here */
- status = ARES_ENODATA;
- }
- }
-
- return status;
-
-failed_stat:
- ares_free(rr_name);
- ares__freeaddrinfo_cnames(cnames);
- ares__freeaddrinfo_nodes(nodes);
- return status;
-}
-
-int ares__parse_into_addrinfo(const unsigned char *abuf,
- int alen,
- struct ares_addrinfo *ai)
-{
- int status;
- char *question_hostname;
- status = ares__parse_into_addrinfo2(abuf, alen, &question_hostname, ai);
- ares_free(question_hostname);
- return status;
-}
+/* Copyright (C) 2019 by Andrew Selivanov
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+#else
+# include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+# include <arpa/nameser_compat.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_private.h"
+
+int ares__parse_into_addrinfo2(const unsigned char *abuf,
+ int alen,
+ char **question_hostname,
+ struct ares_addrinfo *ai)
+{
+ unsigned int qdcount, ancount;
+ int status, i, rr_type, rr_class, rr_len, rr_ttl;
+ int got_a = 0, got_aaaa = 0, got_cname = 0;
+ long len;
+ const unsigned char *aptr;
+ char *hostname, *rr_name = NULL, *rr_data;
+ struct ares_addrinfo_cname *cname, *cnames = NULL;
+ struct ares_addrinfo_node *node, *nodes = NULL;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+
+ *question_hostname = NULL;
+
+ /* Give up if abuf doesn't have room for a header. */
+ if (alen < HFIXEDSZ)
+ return ARES_EBADRESP;
+
+ /* Fetch the question and answer count from the header. */
+ qdcount = DNS_HEADER_QDCOUNT(abuf);
+ ancount = DNS_HEADER_ANCOUNT(abuf);
+ if (qdcount != 1)
+ return ARES_EBADRESP;
+
+
+ /* Expand the name from the question, and skip past the question. */
+ aptr = abuf + HFIXEDSZ;
+ status = ares__expand_name_for_response(aptr, abuf, alen, question_hostname, &len);
+ if (status != ARES_SUCCESS)
+ return status;
+ if (aptr + len + QFIXEDSZ > abuf + alen)
+ {
+ return ARES_EBADRESP;
+ }
+
+ hostname = *question_hostname;
+
+ aptr += len + QFIXEDSZ;
+
+ /* Examine each answer resource record (RR) in turn. */
+ for (i = 0; i < (int)ancount; i++)
+ {
+ /* Decode the RR up to the data field. */
+ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
+ if (status != ARES_SUCCESS)
+ {
+ rr_name = NULL;
+ goto failed_stat;
+ }
+
+ aptr += len;
+ if (aptr + RRFIXEDSZ > abuf + alen)
+ {
+ status = ARES_EBADRESP;
+ goto failed_stat;
+ }
+ rr_type = DNS_RR_TYPE(aptr);
+ rr_class = DNS_RR_CLASS(aptr);
+ rr_len = DNS_RR_LEN(aptr);
+ rr_ttl = DNS_RR_TTL(aptr);
+ aptr += RRFIXEDSZ;
+ if (aptr + rr_len > abuf + alen)
+ {
+ status = ARES_EBADRESP;
+ goto failed_stat;
+ }
+
+ if (rr_class == C_IN && rr_type == T_A
+ && rr_len == sizeof(struct in_addr)
+ && strcasecmp(rr_name, hostname) == 0)
+ {
+ got_a = 1;
+ if (aptr + sizeof(struct in_addr) > abuf + alen)
+ { /* LCOV_EXCL_START: already checked above */
+ status = ARES_EBADRESP;
+ goto failed_stat;
+ } /* LCOV_EXCL_STOP */
+
+ node = ares__append_addrinfo_node(&nodes);
+ if (!node)
+ {
+ status = ARES_ENOMEM;
+ goto failed_stat;
+ }
+
+ sin = ares_malloc(sizeof(struct sockaddr_in));
+ if (!sin)
+ {
+ status = ARES_ENOMEM;
+ goto failed_stat;
+ }
+ memset(sin, 0, sizeof(struct sockaddr_in));
+ memcpy(&sin->sin_addr.s_addr, aptr, sizeof(struct in_addr));
+ sin->sin_family = AF_INET;
+
+ node->ai_addr = (struct sockaddr *)sin;
+ node->ai_family = AF_INET;
+ node->ai_addrlen = sizeof(struct sockaddr_in);
+
+ node->ai_ttl = rr_ttl;
+
+ status = ARES_SUCCESS;
+ }
+ else if (rr_class == C_IN && rr_type == T_AAAA
+ && rr_len == sizeof(struct ares_in6_addr)
+ && strcasecmp(rr_name, hostname) == 0)
+ {
+ got_aaaa = 1;
+ if (aptr + sizeof(struct ares_in6_addr) > abuf + alen)
+ { /* LCOV_EXCL_START: already checked above */
+ status = ARES_EBADRESP;
+ goto failed_stat;
+ } /* LCOV_EXCL_STOP */
+
+ node = ares__append_addrinfo_node(&nodes);
+ if (!node)
+ {
+ status = ARES_ENOMEM;
+ goto failed_stat;
+ }
+
+ sin6 = ares_malloc(sizeof(struct sockaddr_in6));
+ if (!sin6)
+ {
+ status = ARES_ENOMEM;
+ goto failed_stat;
+ }
+
+ memset(sin6, 0, sizeof(struct sockaddr_in6));
+ memcpy(&sin6->sin6_addr.s6_addr, aptr, sizeof(struct ares_in6_addr));
+ sin6->sin6_family = AF_INET6;
+
+ node->ai_addr = (struct sockaddr *)sin6;
+ node->ai_family = AF_INET6;
+ node->ai_addrlen = sizeof(struct sockaddr_in6);
+
+ node->ai_ttl = rr_ttl;
+
+ status = ARES_SUCCESS;
+ }
+
+ if (rr_class == C_IN && rr_type == T_CNAME)
+ {
+ got_cname = 1;
+ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
+ &len);
+ if (status != ARES_SUCCESS)
+ {
+ goto failed_stat;
+ }
+
+ /* Decode the RR data and replace the hostname with it. */
+ /* SA: Seems wrong as it introduses order dependency. */
+ hostname = rr_data;
+
+ cname = ares__append_addrinfo_cname(&cnames);
+ if (!cname)
+ {
+ status = ARES_ENOMEM;
+ ares_free(rr_data);
+ goto failed_stat;
+ }
+ cname->ttl = rr_ttl;
+ cname->alias = rr_name;
+ cname->name = rr_data;
+ }
+ else
+ {
+ ares_free(rr_name);
+ }
+
+
+ aptr += rr_len;
+ if (aptr > abuf + alen)
+ { /* LCOV_EXCL_START: already checked above */
+ status = ARES_EBADRESP;
+ goto failed_stat;
+ } /* LCOV_EXCL_STOP */
+ }
+
+ if (status == ARES_SUCCESS)
+ {
+ ares__addrinfo_cat_nodes(&ai->nodes, nodes);
+ if (got_cname)
+ {
+ ares__addrinfo_cat_cnames(&ai->cnames, cnames);
+ return status;
+ }
+ else if (got_a == 0 && got_aaaa == 0)
+ {
+ /* the check for naliases to be zero is to make sure CNAME responses
+ don't get caught here */
+ status = ARES_ENODATA;
+ }
+ }
+
+ return status;
+
+failed_stat:
+ ares_free(rr_name);
+ ares__freeaddrinfo_cnames(cnames);
+ ares__freeaddrinfo_nodes(nodes);
+ return status;
+}
+
+int ares__parse_into_addrinfo(const unsigned char *abuf,
+ int alen,
+ struct ares_addrinfo *ai)
+{
+ int status;
+ char *question_hostname;
+ status = ares__parse_into_addrinfo2(abuf, alen, &question_hostname, ai);
+ ares_free(question_hostname);
+ return status;
+}
diff --git a/contrib/libs/c-ares/ares__readaddrinfo.c b/contrib/libs/c-ares/ares__readaddrinfo.c
index 9ee8d7f0c4..dd3abe2e9f 100644
--- a/contrib/libs/c-ares/ares__readaddrinfo.c
+++ b/contrib/libs/c-ares/ares__readaddrinfo.c
@@ -1,260 +1,260 @@
-/* Copyright (C) 2019 by Andrew Selivanov
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting
- * documentation, and that the name of M.I.T. not be used in
- * advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- */
-
-#include "ares_setup.h"
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-# include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-# include <arpa/inet.h>
-#endif
-
-#include "ares.h"
-#include "ares_inet_net_pton.h"
-#include "ares_nowarn.h"
-#include "ares_private.h"
-
-#define MAX_ALIASES 40
-
-int ares__readaddrinfo(FILE *fp,
- const char *name,
- unsigned short port,
- const struct ares_addrinfo_hints *hints,
- struct ares_addrinfo *ai)
-{
- char *line = NULL, *p, *q;
- char *txtaddr, *txthost, *txtalias;
- char *aliases[MAX_ALIASES];
- unsigned int i, alias_count;
- int status;
- size_t linesize;
- ares_sockaddr addr;
- struct ares_addrinfo_cname *cname = NULL, *cnames = NULL;
- struct ares_addrinfo_node *node = NULL, *nodes = NULL;
- int match_with_alias, match_with_canonical;
- int want_cname = hints->ai_flags & ARES_AI_CANONNAME;
-
- /* Validate family */
- switch (hints->ai_family) {
- case AF_INET:
- case AF_INET6:
- case AF_UNSPEC:
- break;
- default:
- return ARES_EBADFAMILY;
- }
-
-
- while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
- {
- match_with_alias = 0;
- match_with_canonical = 0;
- alias_count = 0;
- /* Trim line comment. */
- p = line;
- while (*p && (*p != '#'))
- p++;
- *p = '\0';
-
- /* Trim trailing whitespace. */
- q = p - 1;
- while ((q >= line) && ISSPACE(*q))
- q--;
- *++q = '\0';
-
- /* Skip leading whitespace. */
- p = line;
- while (*p && ISSPACE(*p))
- p++;
- if (!*p)
- /* Ignore line if empty. */
- continue;
-
- /* Pointer to start of IPv4 or IPv6 address part. */
- txtaddr = p;
-
- /* Advance past address part. */
- while (*p && !ISSPACE(*p))
- p++;
- if (!*p)
- /* Ignore line if reached end of line. */
- continue;
-
- /* Null terminate address part. */
- *p = '\0';
-
- /* Advance to host name */
- p++;
- while (*p && ISSPACE(*p))
- p++;
- if (!*p)
- /* Ignore line if reached end of line. */
- continue; /* LCOV_EXCL_LINE: trailing whitespace already stripped */
-
- /* Pointer to start of host name. */
- txthost = p;
-
- /* Advance past host name. */
- while (*p && !ISSPACE(*p))
- p++;
-
- /* Pointer to start of first alias. */
- txtalias = NULL;
- if (*p)
- {
- q = p + 1;
- while (*q && ISSPACE(*q))
- q++;
- if (*q)
- txtalias = q;
- }
-
- /* Null terminate host name. */
- *p = '\0';
-
- /* Find out if host name matches with canonical host name. */
- if (strcasecmp(txthost, name) == 0)
- {
- match_with_canonical = 1;
- }
-
- /* Find out if host name matches with one of the aliases. */
- while (txtalias)
- {
- p = txtalias;
- while (*p && !ISSPACE(*p))
- p++;
- q = p;
- while (*q && ISSPACE(*q))
- q++;
- *p = '\0';
- if (strcasecmp(txtalias, name) == 0)
- {
- match_with_alias = 1;
- if (!want_cname)
- break;
- }
- if (alias_count < MAX_ALIASES)
- {
- aliases[alias_count++] = txtalias;
- }
- txtalias = *q ? q : NULL;
- }
-
- /* Try next line if host does not match. */
- if (!match_with_alias && !match_with_canonical)
- {
- continue;
- }
-
- /*
- * Convert address string to network address for the requested families.
- * Actual address family possible values are AF_INET and AF_INET6 only.
- */
- if ((hints->ai_family == AF_INET) || (hints->ai_family == AF_UNSPEC))
- {
- addr.sa4.sin_port = htons(port);
- if (ares_inet_pton(AF_INET, txtaddr, &addr.sa4.sin_addr) > 0)
- {
- node = ares__append_addrinfo_node(&nodes);
- if(!node)
- {
- goto enomem;
- }
-
- node->ai_family = addr.sa.sa_family = AF_INET;
- node->ai_addrlen = sizeof(sizeof(addr.sa4));
- node->ai_addr = ares_malloc(sizeof(addr.sa4));
- if (!node->ai_addr)
- {
- goto enomem;
- }
- memcpy(node->ai_addr, &addr.sa4, sizeof(addr.sa4));
- }
- }
- if ((hints->ai_family == AF_INET6) || (hints->ai_family == AF_UNSPEC))
- {
- addr.sa6.sin6_port = htons(port);
- if (ares_inet_pton(AF_INET6, txtaddr, &addr.sa6.sin6_addr) > 0)
- {
- node = ares__append_addrinfo_node(&nodes);
- if (!node)
- {
- goto enomem;
- }
-
- node->ai_family = addr.sa.sa_family = AF_INET6;
- node->ai_addrlen = sizeof(sizeof(addr.sa6));
- node->ai_addr = ares_malloc(sizeof(addr.sa6));
- if (!node->ai_addr)
- {
- goto enomem;
- }
- memcpy(node->ai_addr, &addr.sa6, sizeof(addr.sa6));
- }
- }
- if (!node)
- /* Ignore line if invalid address string for the requested family. */
- continue;
-
- if (want_cname)
- {
- for (i = 0; i < alias_count; ++i)
- {
- cname = ares__append_addrinfo_cname(&cnames);
- if (!cname)
- {
- goto enomem;
- }
- cname->alias = ares_strdup(aliases[i]);
- cname->name = ares_strdup(txthost);
- }
- /* No aliases, cname only. */
- if(!alias_count)
- {
- cname = ares__append_addrinfo_cname(&cnames);
- if (!cname)
- {
- goto enomem;
- }
- cname->name = ares_strdup(txthost);
- }
- }
- }
-
- /* Last read failed. */
- if (status == ARES_ENOMEM)
- {
- goto enomem;
- }
-
- /* Free line buffer. */
- ares_free(line);
-
- ares__addrinfo_cat_cnames(&ai->cnames, cnames);
- ares__addrinfo_cat_nodes(&ai->nodes, nodes);
-
- return node ? ARES_SUCCESS : ARES_ENOTFOUND;
-
-enomem:
- ares_free(line);
- ares__freeaddrinfo_cnames(cnames);
- ares__freeaddrinfo_nodes(nodes);
- return ARES_ENOMEM;
-}
+/* Copyright (C) 2019 by Andrew Selivanov
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#include "ares.h"
+#include "ares_inet_net_pton.h"
+#include "ares_nowarn.h"
+#include "ares_private.h"
+
+#define MAX_ALIASES 40
+
+int ares__readaddrinfo(FILE *fp,
+ const char *name,
+ unsigned short port,
+ const struct ares_addrinfo_hints *hints,
+ struct ares_addrinfo *ai)
+{
+ char *line = NULL, *p, *q;
+ char *txtaddr, *txthost, *txtalias;
+ char *aliases[MAX_ALIASES];
+ unsigned int i, alias_count;
+ int status;
+ size_t linesize;
+ ares_sockaddr addr;
+ struct ares_addrinfo_cname *cname = NULL, *cnames = NULL;
+ struct ares_addrinfo_node *node = NULL, *nodes = NULL;
+ int match_with_alias, match_with_canonical;
+ int want_cname = hints->ai_flags & ARES_AI_CANONNAME;
+
+ /* Validate family */
+ switch (hints->ai_family) {
+ case AF_INET:
+ case AF_INET6:
+ case AF_UNSPEC:
+ break;
+ default:
+ return ARES_EBADFAMILY;
+ }
+
+
+ while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
+ {
+ match_with_alias = 0;
+ match_with_canonical = 0;
+ alias_count = 0;
+ /* Trim line comment. */
+ p = line;
+ while (*p && (*p != '#'))
+ p++;
+ *p = '\0';
+
+ /* Trim trailing whitespace. */
+ q = p - 1;
+ while ((q >= line) && ISSPACE(*q))
+ q--;
+ *++q = '\0';
+
+ /* Skip leading whitespace. */
+ p = line;
+ while (*p && ISSPACE(*p))
+ p++;
+ if (!*p)
+ /* Ignore line if empty. */
+ continue;
+
+ /* Pointer to start of IPv4 or IPv6 address part. */
+ txtaddr = p;
+
+ /* Advance past address part. */
+ while (*p && !ISSPACE(*p))
+ p++;
+ if (!*p)
+ /* Ignore line if reached end of line. */
+ continue;
+
+ /* Null terminate address part. */
+ *p = '\0';
+
+ /* Advance to host name */
+ p++;
+ while (*p && ISSPACE(*p))
+ p++;
+ if (!*p)
+ /* Ignore line if reached end of line. */
+ continue; /* LCOV_EXCL_LINE: trailing whitespace already stripped */
+
+ /* Pointer to start of host name. */
+ txthost = p;
+
+ /* Advance past host name. */
+ while (*p && !ISSPACE(*p))
+ p++;
+
+ /* Pointer to start of first alias. */
+ txtalias = NULL;
+ if (*p)
+ {
+ q = p + 1;
+ while (*q && ISSPACE(*q))
+ q++;
+ if (*q)
+ txtalias = q;
+ }
+
+ /* Null terminate host name. */
+ *p = '\0';
+
+ /* Find out if host name matches with canonical host name. */
+ if (strcasecmp(txthost, name) == 0)
+ {
+ match_with_canonical = 1;
+ }
+
+ /* Find out if host name matches with one of the aliases. */
+ while (txtalias)
+ {
+ p = txtalias;
+ while (*p && !ISSPACE(*p))
+ p++;
+ q = p;
+ while (*q && ISSPACE(*q))
+ q++;
+ *p = '\0';
+ if (strcasecmp(txtalias, name) == 0)
+ {
+ match_with_alias = 1;
+ if (!want_cname)
+ break;
+ }
+ if (alias_count < MAX_ALIASES)
+ {
+ aliases[alias_count++] = txtalias;
+ }
+ txtalias = *q ? q : NULL;
+ }
+
+ /* Try next line if host does not match. */
+ if (!match_with_alias && !match_with_canonical)
+ {
+ continue;
+ }
+
+ /*
+ * Convert address string to network address for the requested families.
+ * Actual address family possible values are AF_INET and AF_INET6 only.
+ */
+ if ((hints->ai_family == AF_INET) || (hints->ai_family == AF_UNSPEC))
+ {
+ addr.sa4.sin_port = htons(port);
+ if (ares_inet_pton(AF_INET, txtaddr, &addr.sa4.sin_addr) > 0)
+ {
+ node = ares__append_addrinfo_node(&nodes);
+ if(!node)
+ {
+ goto enomem;
+ }
+
+ node->ai_family = addr.sa.sa_family = AF_INET;
+ node->ai_addrlen = sizeof(sizeof(addr.sa4));
+ node->ai_addr = ares_malloc(sizeof(addr.sa4));
+ if (!node->ai_addr)
+ {
+ goto enomem;
+ }
+ memcpy(node->ai_addr, &addr.sa4, sizeof(addr.sa4));
+ }
+ }
+ if ((hints->ai_family == AF_INET6) || (hints->ai_family == AF_UNSPEC))
+ {
+ addr.sa6.sin6_port = htons(port);
+ if (ares_inet_pton(AF_INET6, txtaddr, &addr.sa6.sin6_addr) > 0)
+ {
+ node = ares__append_addrinfo_node(&nodes);
+ if (!node)
+ {
+ goto enomem;
+ }
+
+ node->ai_family = addr.sa.sa_family = AF_INET6;
+ node->ai_addrlen = sizeof(sizeof(addr.sa6));
+ node->ai_addr = ares_malloc(sizeof(addr.sa6));
+ if (!node->ai_addr)
+ {
+ goto enomem;
+ }
+ memcpy(node->ai_addr, &addr.sa6, sizeof(addr.sa6));
+ }
+ }
+ if (!node)
+ /* Ignore line if invalid address string for the requested family. */
+ continue;
+
+ if (want_cname)
+ {
+ for (i = 0; i < alias_count; ++i)
+ {
+ cname = ares__append_addrinfo_cname(&cnames);
+ if (!cname)
+ {
+ goto enomem;
+ }
+ cname->alias = ares_strdup(aliases[i]);
+ cname->name = ares_strdup(txthost);
+ }
+ /* No aliases, cname only. */
+ if(!alias_count)
+ {
+ cname = ares__append_addrinfo_cname(&cnames);
+ if (!cname)
+ {
+ goto enomem;
+ }
+ cname->name = ares_strdup(txthost);
+ }
+ }
+ }
+
+ /* Last read failed. */
+ if (status == ARES_ENOMEM)
+ {
+ goto enomem;
+ }
+
+ /* Free line buffer. */
+ ares_free(line);
+
+ ares__addrinfo_cat_cnames(&ai->cnames, cnames);
+ ares__addrinfo_cat_nodes(&ai->nodes, nodes);
+
+ return node ? ARES_SUCCESS : ARES_ENOTFOUND;
+
+enomem:
+ ares_free(line);
+ ares__freeaddrinfo_cnames(cnames);
+ ares__freeaddrinfo_nodes(nodes);
+ return ARES_ENOMEM;
+}
diff --git a/contrib/libs/c-ares/ares__sortaddrinfo.c b/contrib/libs/c-ares/ares__sortaddrinfo.c
index b740860a6a..c0e2ea1528 100644
--- a/contrib/libs/c-ares/ares__sortaddrinfo.c
+++ b/contrib/libs/c-ares/ares__sortaddrinfo.c
@@ -1,495 +1,495 @@
-/*
- * Original file name getaddrinfo.c
- * Lifted from the 'Android Bionic' project with the BSD license.
- */
-
-/*
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * Copyright (C) 2018 The Android Open Source Project
- * Copyright (C) 2019 by Andrew Selivanov
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "ares_setup.h"
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-# include <netdb.h>
-#endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-
-#include <assert.h>
-#include <limits.h>
-
-#include "ares.h"
-#include "ares_private.h"
-
-struct addrinfo_sort_elem
-{
- struct ares_addrinfo_node *ai;
- int has_src_addr;
- ares_sockaddr src_addr;
- int original_order;
-};
-
-#define ARES_IPV6_ADDR_MC_SCOPE(a) ((a)->s6_addr[1] & 0x0f)
-
-#define ARES_IPV6_ADDR_SCOPE_NODELOCAL 0x01
-#define ARES_IPV6_ADDR_SCOPE_INTFACELOCAL 0x01
-#define ARES_IPV6_ADDR_SCOPE_LINKLOCAL 0x02
-#define ARES_IPV6_ADDR_SCOPE_SITELOCAL 0x05
-#define ARES_IPV6_ADDR_SCOPE_ORGLOCAL 0x08
-#define ARES_IPV6_ADDR_SCOPE_GLOBAL 0x0e
-
-#define ARES_IN_LOOPBACK(a) ((((long int)(a)) & 0xff000000) == 0x7f000000)
-
-/* RFC 4193. */
-#define ARES_IN6_IS_ADDR_ULA(a) (((a)->s6_addr[0] & 0xfe) == 0xfc)
-
-/* These macros are modelled after the ones in <netinet/in6.h>. */
-/* RFC 4380, section 2.6 */
-#define ARES_IN6_IS_ADDR_TEREDO(a) \
- ((*(const unsigned int *)(const void *)(&(a)->s6_addr[0]) == ntohl(0x20010000)))
-/* RFC 3056, section 2. */
-#define ARES_IN6_IS_ADDR_6TO4(a) \
- (((a)->s6_addr[0] == 0x20) && ((a)->s6_addr[1] == 0x02))
-/* 6bone testing address area (3ffe::/16), deprecated in RFC 3701. */
-#define ARES_IN6_IS_ADDR_6BONE(a) \
- (((a)->s6_addr[0] == 0x3f) && ((a)->s6_addr[1] == 0xfe))
-
-
-static int get_scope(const struct sockaddr *addr)
-{
- if (addr->sa_family == AF_INET6)
- {
- const struct sockaddr_in6 *addr6 = CARES_INADDR_CAST(const struct sockaddr_in6 *, addr);
- if (IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr))
- {
- return ARES_IPV6_ADDR_MC_SCOPE(&addr6->sin6_addr);
- }
- else if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr) ||
- IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr))
- {
- /*
- * RFC 4291 section 2.5.3 says loopback is to be treated as having
- * link-local scope.
- */
- return ARES_IPV6_ADDR_SCOPE_LINKLOCAL;
- }
- else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr))
- {
- return ARES_IPV6_ADDR_SCOPE_SITELOCAL;
- }
- else
- {
- return ARES_IPV6_ADDR_SCOPE_GLOBAL;
- }
- }
- else if (addr->sa_family == AF_INET)
- {
- const struct sockaddr_in *addr4 = CARES_INADDR_CAST(const struct sockaddr_in *, addr);
- unsigned long int na = ntohl(addr4->sin_addr.s_addr);
- if (ARES_IN_LOOPBACK(na) || /* 127.0.0.0/8 */
- (na & 0xffff0000) == 0xa9fe0000) /* 169.254.0.0/16 */
- {
- return ARES_IPV6_ADDR_SCOPE_LINKLOCAL;
- }
- else
- {
- /*
- * RFC 6724 section 3.2. Other IPv4 addresses, including private
- * addresses and shared addresses (100.64.0.0/10), are assigned global
- * scope.
- */
- return ARES_IPV6_ADDR_SCOPE_GLOBAL;
- }
- }
- else
- {
- /*
- * This should never happen.
- * Return a scope with low priority as a last resort.
- */
- return ARES_IPV6_ADDR_SCOPE_NODELOCAL;
- }
-}
-
-static int get_label(const struct sockaddr *addr)
-{
- if (addr->sa_family == AF_INET)
- {
- return 4;
- }
- else if (addr->sa_family == AF_INET6)
- {
- const struct sockaddr_in6 *addr6 = CARES_INADDR_CAST(const struct sockaddr_in6 *, addr);
- if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr))
- {
- return 0;
- }
- else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr))
- {
- return 4;
- }
- else if (ARES_IN6_IS_ADDR_6TO4(&addr6->sin6_addr))
- {
- return 2;
- }
- else if (ARES_IN6_IS_ADDR_TEREDO(&addr6->sin6_addr))
- {
- return 5;
- }
- else if (ARES_IN6_IS_ADDR_ULA(&addr6->sin6_addr))
- {
- return 13;
- }
- else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr))
- {
- return 3;
- }
- else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr))
- {
- return 11;
- }
- else if (ARES_IN6_IS_ADDR_6BONE(&addr6->sin6_addr))
- {
- return 12;
- }
- else
- {
- /* All other IPv6 addresses, including global unicast addresses. */
- return 1;
- }
- }
- else
- {
- /*
- * This should never happen.
- * Return a semi-random label as a last resort.
- */
- return 1;
- }
-}
-
-/*
- * Get the precedence for a given IPv4/IPv6 address.
- * RFC 6724, section 2.1.
- */
-static int get_precedence(const struct sockaddr *addr)
-{
- if (addr->sa_family == AF_INET)
- {
- return 35;
- }
- else if (addr->sa_family == AF_INET6)
- {
- const struct sockaddr_in6 *addr6 = CARES_INADDR_CAST(const struct sockaddr_in6 *, addr);
- if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr))
- {
- return 50;
- }
- else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr))
- {
- return 35;
- }
- else if (ARES_IN6_IS_ADDR_6TO4(&addr6->sin6_addr))
- {
- return 30;
- }
- else if (ARES_IN6_IS_ADDR_TEREDO(&addr6->sin6_addr))
- {
- return 5;
- }
- else if (ARES_IN6_IS_ADDR_ULA(&addr6->sin6_addr))
- {
- return 3;
- }
- else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr) ||
- IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr) ||
- ARES_IN6_IS_ADDR_6BONE(&addr6->sin6_addr))
- {
- return 1;
- }
- else
- {
- /* All other IPv6 addresses, including global unicast addresses. */
- return 40;
- }
- }
- else
- {
- return 1;
- }
-}
-
-/*
- * Find number of matching initial bits between the two addresses a1 and a2.
- */
-static int common_prefix_len(const struct in6_addr *a1,
- const struct in6_addr *a2)
-{
- const char *p1 = (const char *)a1;
- const char *p2 = (const char *)a2;
- unsigned i;
- for (i = 0; i < sizeof(*a1); ++i)
- {
- int x, j;
- if (p1[i] == p2[i])
- {
- continue;
- }
- x = p1[i] ^ p2[i];
- for (j = 0; j < CHAR_BIT; ++j)
- {
- if (x & (1 << (CHAR_BIT - 1)))
- {
- return i * CHAR_BIT + j;
- }
- x <<= 1;
- }
- }
- return sizeof(*a1) * CHAR_BIT;
-}
-
-/*
- * Compare two source/destination address pairs.
- * RFC 6724, section 6.
- */
-static int rfc6724_compare(const void *ptr1, const void *ptr2)
-{
- const struct addrinfo_sort_elem *a1 = (const struct addrinfo_sort_elem *)ptr1;
- const struct addrinfo_sort_elem *a2 = (const struct addrinfo_sort_elem *)ptr2;
- int scope_src1, scope_dst1, scope_match1;
- int scope_src2, scope_dst2, scope_match2;
- int label_src1, label_dst1, label_match1;
- int label_src2, label_dst2, label_match2;
- int precedence1, precedence2;
- int prefixlen1, prefixlen2;
-
- /* Rule 1: Avoid unusable destinations. */
- if (a1->has_src_addr != a2->has_src_addr)
- {
- return a2->has_src_addr - a1->has_src_addr;
- }
-
- /* Rule 2: Prefer matching scope. */
- scope_src1 = get_scope(&a1->src_addr.sa);
- scope_dst1 = get_scope(a1->ai->ai_addr);
- scope_match1 = (scope_src1 == scope_dst1);
-
- scope_src2 = get_scope(&a2->src_addr.sa);
- scope_dst2 = get_scope(a2->ai->ai_addr);
- scope_match2 = (scope_src2 == scope_dst2);
-
- if (scope_match1 != scope_match2)
- {
- return scope_match2 - scope_match1;
- }
-
- /* Rule 3: Avoid deprecated addresses. */
-
- /* Rule 4: Prefer home addresses. */
-
- /* Rule 5: Prefer matching label. */
- label_src1 = get_label(&a1->src_addr.sa);
- label_dst1 = get_label(a1->ai->ai_addr);
- label_match1 = (label_src1 == label_dst1);
-
- label_src2 = get_label(&a2->src_addr.sa);
- label_dst2 = get_label(a2->ai->ai_addr);
- label_match2 = (label_src2 == label_dst2);
-
- if (label_match1 != label_match2)
- {
- return label_match2 - label_match1;
- }
-
- /* Rule 6: Prefer higher precedence. */
- precedence1 = get_precedence(a1->ai->ai_addr);
- precedence2 = get_precedence(a2->ai->ai_addr);
- if (precedence1 != precedence2)
- {
- return precedence2 - precedence1;
- }
-
- /* Rule 7: Prefer native transport. */
-
- /* Rule 8: Prefer smaller scope. */
- if (scope_dst1 != scope_dst2)
- {
- return scope_dst1 - scope_dst2;
- }
-
- /* Rule 9: Use longest matching prefix. */
- if (a1->has_src_addr && a1->ai->ai_addr->sa_family == AF_INET6 &&
- a2->has_src_addr && a2->ai->ai_addr->sa_family == AF_INET6)
- {
- const struct sockaddr_in6 *a1_src = &a1->src_addr.sa6;
- const struct sockaddr_in6 *a1_dst =
- CARES_INADDR_CAST(const struct sockaddr_in6 *, a1->ai->ai_addr);
- const struct sockaddr_in6 *a2_src = &a2->src_addr.sa6;
- const struct sockaddr_in6 *a2_dst =
- CARES_INADDR_CAST(const struct sockaddr_in6 *, a2->ai->ai_addr);
- prefixlen1 = common_prefix_len(&a1_src->sin6_addr, &a1_dst->sin6_addr);
- prefixlen2 = common_prefix_len(&a2_src->sin6_addr, &a2_dst->sin6_addr);
- if (prefixlen1 != prefixlen2)
- {
- return prefixlen2 - prefixlen1;
- }
- }
-
- /*
- * Rule 10: Leave the order unchanged.
- * We need this since qsort() is not necessarily stable.
- */
- return a1->original_order - a2->original_order;
-}
-
-/*
- * Find the source address that will be used if trying to connect to the given
- * address.
- *
- * Returns 1 if a source address was found, 0 if the address is unreachable,
- * and -1 if a fatal error occurred. If 0 or 1, the contents of src_addr are
- * undefined.
- */
-static int find_src_addr(ares_channel channel,
- const struct sockaddr *addr,
- struct sockaddr *src_addr)
-{
- int sock;
- int ret;
- ares_socklen_t len;
-
- switch (addr->sa_family)
- {
- case AF_INET:
- len = sizeof(struct sockaddr_in);
- break;
- case AF_INET6:
- len = sizeof(struct sockaddr_in6);
- break;
- default:
- /* No known usable source address for non-INET families. */
- return 0;
- }
-
- sock = ares__open_socket(channel, addr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
- if (sock == -1)
- {
- if (errno == EAFNOSUPPORT)
- {
- return 0;
- }
- else
- {
- return -1;
- }
- }
-
- do
- {
- ret = ares__connect_socket(channel, sock, addr, len);
- }
- while (ret == -1 && errno == EINTR);
-
- if (ret == -1)
- {
- ares__close_socket(channel, sock);
- return 0;
- }
-
- if (getsockname(sock, src_addr, &len) == -1)
- {
- ares__close_socket(channel, sock);
- return -1;
- }
- ares__close_socket(channel, sock);
- return 1;
-}
-
-/*
- * Sort the linked list starting at sentinel->ai_next in RFC6724 order.
- * Will leave the list unchanged if an error occurs.
- */
-int ares__sortaddrinfo(ares_channel channel, struct ares_addrinfo_node *list_sentinel)
-{
- struct ares_addrinfo_node *cur;
- int nelem = 0, i;
- int has_src_addr;
- struct addrinfo_sort_elem *elems;
-
- cur = list_sentinel->ai_next;
- while (cur)
- {
- ++nelem;
- cur = cur->ai_next;
- }
- elems = (struct addrinfo_sort_elem *)ares_malloc(
- nelem * sizeof(struct addrinfo_sort_elem));
- if (!elems)
- {
- return ARES_ENOMEM;
- }
-
- /*
- * Convert the linked list to an array that also contains the candidate
- * source address for each destination address.
- */
- for (i = 0, cur = list_sentinel->ai_next; i < nelem; ++i, cur = cur->ai_next)
- {
- assert(cur != NULL);
- elems[i].ai = cur;
- elems[i].original_order = i;
- has_src_addr = find_src_addr(channel, cur->ai_addr, &elems[i].src_addr.sa);
- if (has_src_addr == -1)
- {
- ares_free(elems);
- return ARES_ENOTFOUND;
- }
- elems[i].has_src_addr = has_src_addr;
- }
-
- /* Sort the addresses, and rearrange the linked list so it matches the sorted
- * order. */
- qsort((void *)elems, nelem, sizeof(struct addrinfo_sort_elem),
- rfc6724_compare);
-
- list_sentinel->ai_next = elems[0].ai;
- for (i = 0; i < nelem - 1; ++i)
- {
- elems[i].ai->ai_next = elems[i + 1].ai;
- }
- elems[nelem - 1].ai->ai_next = NULL;
-
- ares_free(elems);
- return ARES_SUCCESS;
-}
+/*
+ * Original file name getaddrinfo.c
+ * Lifted from the 'Android Bionic' project with the BSD license.
+ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2019 by Andrew Selivanov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <assert.h>
+#include <limits.h>
+
+#include "ares.h"
+#include "ares_private.h"
+
+struct addrinfo_sort_elem
+{
+ struct ares_addrinfo_node *ai;
+ int has_src_addr;
+ ares_sockaddr src_addr;
+ int original_order;
+};
+
+#define ARES_IPV6_ADDR_MC_SCOPE(a) ((a)->s6_addr[1] & 0x0f)
+
+#define ARES_IPV6_ADDR_SCOPE_NODELOCAL 0x01
+#define ARES_IPV6_ADDR_SCOPE_INTFACELOCAL 0x01
+#define ARES_IPV6_ADDR_SCOPE_LINKLOCAL 0x02
+#define ARES_IPV6_ADDR_SCOPE_SITELOCAL 0x05
+#define ARES_IPV6_ADDR_SCOPE_ORGLOCAL 0x08
+#define ARES_IPV6_ADDR_SCOPE_GLOBAL 0x0e
+
+#define ARES_IN_LOOPBACK(a) ((((long int)(a)) & 0xff000000) == 0x7f000000)
+
+/* RFC 4193. */
+#define ARES_IN6_IS_ADDR_ULA(a) (((a)->s6_addr[0] & 0xfe) == 0xfc)
+
+/* These macros are modelled after the ones in <netinet/in6.h>. */
+/* RFC 4380, section 2.6 */
+#define ARES_IN6_IS_ADDR_TEREDO(a) \
+ ((*(const unsigned int *)(const void *)(&(a)->s6_addr[0]) == ntohl(0x20010000)))
+/* RFC 3056, section 2. */
+#define ARES_IN6_IS_ADDR_6TO4(a) \
+ (((a)->s6_addr[0] == 0x20) && ((a)->s6_addr[1] == 0x02))
+/* 6bone testing address area (3ffe::/16), deprecated in RFC 3701. */
+#define ARES_IN6_IS_ADDR_6BONE(a) \
+ (((a)->s6_addr[0] == 0x3f) && ((a)->s6_addr[1] == 0xfe))
+
+
+static int get_scope(const struct sockaddr *addr)
+{
+ if (addr->sa_family == AF_INET6)
+ {
+ const struct sockaddr_in6 *addr6 = CARES_INADDR_CAST(const struct sockaddr_in6 *, addr);
+ if (IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr))
+ {
+ return ARES_IPV6_ADDR_MC_SCOPE(&addr6->sin6_addr);
+ }
+ else if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr) ||
+ IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr))
+ {
+ /*
+ * RFC 4291 section 2.5.3 says loopback is to be treated as having
+ * link-local scope.
+ */
+ return ARES_IPV6_ADDR_SCOPE_LINKLOCAL;
+ }
+ else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr))
+ {
+ return ARES_IPV6_ADDR_SCOPE_SITELOCAL;
+ }
+ else
+ {
+ return ARES_IPV6_ADDR_SCOPE_GLOBAL;
+ }
+ }
+ else if (addr->sa_family == AF_INET)
+ {
+ const struct sockaddr_in *addr4 = CARES_INADDR_CAST(const struct sockaddr_in *, addr);
+ unsigned long int na = ntohl(addr4->sin_addr.s_addr);
+ if (ARES_IN_LOOPBACK(na) || /* 127.0.0.0/8 */
+ (na & 0xffff0000) == 0xa9fe0000) /* 169.254.0.0/16 */
+ {
+ return ARES_IPV6_ADDR_SCOPE_LINKLOCAL;
+ }
+ else
+ {
+ /*
+ * RFC 6724 section 3.2. Other IPv4 addresses, including private
+ * addresses and shared addresses (100.64.0.0/10), are assigned global
+ * scope.
+ */
+ return ARES_IPV6_ADDR_SCOPE_GLOBAL;
+ }
+ }
+ else
+ {
+ /*
+ * This should never happen.
+ * Return a scope with low priority as a last resort.
+ */
+ return ARES_IPV6_ADDR_SCOPE_NODELOCAL;
+ }
+}
+
+static int get_label(const struct sockaddr *addr)
+{
+ if (addr->sa_family == AF_INET)
+ {
+ return 4;
+ }
+ else if (addr->sa_family == AF_INET6)
+ {
+ const struct sockaddr_in6 *addr6 = CARES_INADDR_CAST(const struct sockaddr_in6 *, addr);
+ if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr))
+ {
+ return 0;
+ }
+ else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr))
+ {
+ return 4;
+ }
+ else if (ARES_IN6_IS_ADDR_6TO4(&addr6->sin6_addr))
+ {
+ return 2;
+ }
+ else if (ARES_IN6_IS_ADDR_TEREDO(&addr6->sin6_addr))
+ {
+ return 5;
+ }
+ else if (ARES_IN6_IS_ADDR_ULA(&addr6->sin6_addr))
+ {
+ return 13;
+ }
+ else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr))
+ {
+ return 3;
+ }
+ else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr))
+ {
+ return 11;
+ }
+ else if (ARES_IN6_IS_ADDR_6BONE(&addr6->sin6_addr))
+ {
+ return 12;
+ }
+ else
+ {
+ /* All other IPv6 addresses, including global unicast addresses. */
+ return 1;
+ }
+ }
+ else
+ {
+ /*
+ * This should never happen.
+ * Return a semi-random label as a last resort.
+ */
+ return 1;
+ }
+}
+
+/*
+ * Get the precedence for a given IPv4/IPv6 address.
+ * RFC 6724, section 2.1.
+ */
+static int get_precedence(const struct sockaddr *addr)
+{
+ if (addr->sa_family == AF_INET)
+ {
+ return 35;
+ }
+ else if (addr->sa_family == AF_INET6)
+ {
+ const struct sockaddr_in6 *addr6 = CARES_INADDR_CAST(const struct sockaddr_in6 *, addr);
+ if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr))
+ {
+ return 50;
+ }
+ else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr))
+ {
+ return 35;
+ }
+ else if (ARES_IN6_IS_ADDR_6TO4(&addr6->sin6_addr))
+ {
+ return 30;
+ }
+ else if (ARES_IN6_IS_ADDR_TEREDO(&addr6->sin6_addr))
+ {
+ return 5;
+ }
+ else if (ARES_IN6_IS_ADDR_ULA(&addr6->sin6_addr))
+ {
+ return 3;
+ }
+ else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr) ||
+ IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr) ||
+ ARES_IN6_IS_ADDR_6BONE(&addr6->sin6_addr))
+ {
+ return 1;
+ }
+ else
+ {
+ /* All other IPv6 addresses, including global unicast addresses. */
+ return 40;
+ }
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+/*
+ * Find number of matching initial bits between the two addresses a1 and a2.
+ */
+static int common_prefix_len(const struct in6_addr *a1,
+ const struct in6_addr *a2)
+{
+ const char *p1 = (const char *)a1;
+ const char *p2 = (const char *)a2;
+ unsigned i;
+ for (i = 0; i < sizeof(*a1); ++i)
+ {
+ int x, j;
+ if (p1[i] == p2[i])
+ {
+ continue;
+ }
+ x = p1[i] ^ p2[i];
+ for (j = 0; j < CHAR_BIT; ++j)
+ {
+ if (x & (1 << (CHAR_BIT - 1)))
+ {
+ return i * CHAR_BIT + j;
+ }
+ x <<= 1;
+ }
+ }
+ return sizeof(*a1) * CHAR_BIT;
+}
+
+/*
+ * Compare two source/destination address pairs.
+ * RFC 6724, section 6.
+ */
+static int rfc6724_compare(const void *ptr1, const void *ptr2)
+{
+ const struct addrinfo_sort_elem *a1 = (const struct addrinfo_sort_elem *)ptr1;
+ const struct addrinfo_sort_elem *a2 = (const struct addrinfo_sort_elem *)ptr2;
+ int scope_src1, scope_dst1, scope_match1;
+ int scope_src2, scope_dst2, scope_match2;
+ int label_src1, label_dst1, label_match1;
+ int label_src2, label_dst2, label_match2;
+ int precedence1, precedence2;
+ int prefixlen1, prefixlen2;
+
+ /* Rule 1: Avoid unusable destinations. */
+ if (a1->has_src_addr != a2->has_src_addr)
+ {
+ return a2->has_src_addr - a1->has_src_addr;
+ }
+
+ /* Rule 2: Prefer matching scope. */
+ scope_src1 = get_scope(&a1->src_addr.sa);
+ scope_dst1 = get_scope(a1->ai->ai_addr);
+ scope_match1 = (scope_src1 == scope_dst1);
+
+ scope_src2 = get_scope(&a2->src_addr.sa);
+ scope_dst2 = get_scope(a2->ai->ai_addr);
+ scope_match2 = (scope_src2 == scope_dst2);
+
+ if (scope_match1 != scope_match2)
+ {
+ return scope_match2 - scope_match1;
+ }
+
+ /* Rule 3: Avoid deprecated addresses. */
+
+ /* Rule 4: Prefer home addresses. */
+
+ /* Rule 5: Prefer matching label. */
+ label_src1 = get_label(&a1->src_addr.sa);
+ label_dst1 = get_label(a1->ai->ai_addr);
+ label_match1 = (label_src1 == label_dst1);
+
+ label_src2 = get_label(&a2->src_addr.sa);
+ label_dst2 = get_label(a2->ai->ai_addr);
+ label_match2 = (label_src2 == label_dst2);
+
+ if (label_match1 != label_match2)
+ {
+ return label_match2 - label_match1;
+ }
+
+ /* Rule 6: Prefer higher precedence. */
+ precedence1 = get_precedence(a1->ai->ai_addr);
+ precedence2 = get_precedence(a2->ai->ai_addr);
+ if (precedence1 != precedence2)
+ {
+ return precedence2 - precedence1;
+ }
+
+ /* Rule 7: Prefer native transport. */
+
+ /* Rule 8: Prefer smaller scope. */
+ if (scope_dst1 != scope_dst2)
+ {
+ return scope_dst1 - scope_dst2;
+ }
+
+ /* Rule 9: Use longest matching prefix. */
+ if (a1->has_src_addr && a1->ai->ai_addr->sa_family == AF_INET6 &&
+ a2->has_src_addr && a2->ai->ai_addr->sa_family == AF_INET6)
+ {
+ const struct sockaddr_in6 *a1_src = &a1->src_addr.sa6;
+ const struct sockaddr_in6 *a1_dst =
+ CARES_INADDR_CAST(const struct sockaddr_in6 *, a1->ai->ai_addr);
+ const struct sockaddr_in6 *a2_src = &a2->src_addr.sa6;
+ const struct sockaddr_in6 *a2_dst =
+ CARES_INADDR_CAST(const struct sockaddr_in6 *, a2->ai->ai_addr);
+ prefixlen1 = common_prefix_len(&a1_src->sin6_addr, &a1_dst->sin6_addr);
+ prefixlen2 = common_prefix_len(&a2_src->sin6_addr, &a2_dst->sin6_addr);
+ if (prefixlen1 != prefixlen2)
+ {
+ return prefixlen2 - prefixlen1;
+ }
+ }
+
+ /*
+ * Rule 10: Leave the order unchanged.
+ * We need this since qsort() is not necessarily stable.
+ */
+ return a1->original_order - a2->original_order;
+}
+
+/*
+ * Find the source address that will be used if trying to connect to the given
+ * address.
+ *
+ * Returns 1 if a source address was found, 0 if the address is unreachable,
+ * and -1 if a fatal error occurred. If 0 or 1, the contents of src_addr are
+ * undefined.
+ */
+static int find_src_addr(ares_channel channel,
+ const struct sockaddr *addr,
+ struct sockaddr *src_addr)
+{
+ int sock;
+ int ret;
+ ares_socklen_t len;
+
+ switch (addr->sa_family)
+ {
+ case AF_INET:
+ len = sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ len = sizeof(struct sockaddr_in6);
+ break;
+ default:
+ /* No known usable source address for non-INET families. */
+ return 0;
+ }
+
+ sock = ares__open_socket(channel, addr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
+ if (sock == -1)
+ {
+ if (errno == EAFNOSUPPORT)
+ {
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ do
+ {
+ ret = ares__connect_socket(channel, sock, addr, len);
+ }
+ while (ret == -1 && errno == EINTR);
+
+ if (ret == -1)
+ {
+ ares__close_socket(channel, sock);
+ return 0;
+ }
+
+ if (getsockname(sock, src_addr, &len) == -1)
+ {
+ ares__close_socket(channel, sock);
+ return -1;
+ }
+ ares__close_socket(channel, sock);
+ return 1;
+}
+
+/*
+ * Sort the linked list starting at sentinel->ai_next in RFC6724 order.
+ * Will leave the list unchanged if an error occurs.
+ */
+int ares__sortaddrinfo(ares_channel channel, struct ares_addrinfo_node *list_sentinel)
+{
+ struct ares_addrinfo_node *cur;
+ int nelem = 0, i;
+ int has_src_addr;
+ struct addrinfo_sort_elem *elems;
+
+ cur = list_sentinel->ai_next;
+ while (cur)
+ {
+ ++nelem;
+ cur = cur->ai_next;
+ }
+ elems = (struct addrinfo_sort_elem *)ares_malloc(
+ nelem * sizeof(struct addrinfo_sort_elem));
+ if (!elems)
+ {
+ return ARES_ENOMEM;
+ }
+
+ /*
+ * Convert the linked list to an array that also contains the candidate
+ * source address for each destination address.
+ */
+ for (i = 0, cur = list_sentinel->ai_next; i < nelem; ++i, cur = cur->ai_next)
+ {
+ assert(cur != NULL);
+ elems[i].ai = cur;
+ elems[i].original_order = i;
+ has_src_addr = find_src_addr(channel, cur->ai_addr, &elems[i].src_addr.sa);
+ if (has_src_addr == -1)
+ {
+ ares_free(elems);
+ return ARES_ENOTFOUND;
+ }
+ elems[i].has_src_addr = has_src_addr;
+ }
+
+ /* Sort the addresses, and rearrange the linked list so it matches the sorted
+ * order. */
+ qsort((void *)elems, nelem, sizeof(struct addrinfo_sort_elem),
+ rfc6724_compare);
+
+ list_sentinel->ai_next = elems[0].ai;
+ for (i = 0; i < nelem - 1; ++i)
+ {
+ elems[i].ai->ai_next = elems[i + 1].ai;
+ }
+ elems[nelem - 1].ai->ai_next = NULL;
+
+ ares_free(elems);
+ return ARES_SUCCESS;
+}
diff --git a/contrib/libs/c-ares/ares_freeaddrinfo.c b/contrib/libs/c-ares/ares_freeaddrinfo.c
index bcbbc66d94..128f5daec4 100644
--- a/contrib/libs/c-ares/ares_freeaddrinfo.c
+++ b/contrib/libs/c-ares/ares_freeaddrinfo.c
@@ -1,57 +1,57 @@
-
-/* Copyright 1998 by the Massachusetts Institute of Technology.
- * Copyright (C) 2019 by Andrew Selivanov
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting
- * documentation, and that the name of M.I.T. not be used in
- * advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- */
-
-#include "ares_setup.h"
-
-#ifdef HAVE_NETDB_H
-# include <netdb.h>
-#endif
-
-#include "ares.h"
-#include "ares_private.h"
-
-void ares__freeaddrinfo_cnames(struct ares_addrinfo_cname *head)
-{
- struct ares_addrinfo_cname *current;
- while (head)
- {
- current = head;
- head = head->next;
- ares_free(current->alias);
- ares_free(current->name);
- ares_free(current);
- }
-}
-
-void ares__freeaddrinfo_nodes(struct ares_addrinfo_node *head)
-{
- struct ares_addrinfo_node *current;
- while (head)
- {
- current = head;
- head = head->ai_next;
- ares_free(current->ai_addr);
- ares_free(current);
- }
-}
-
-void ares_freeaddrinfo(struct ares_addrinfo *ai)
-{
- ares__freeaddrinfo_cnames(ai->cnames);
- ares__freeaddrinfo_nodes(ai->nodes);
- ares_free(ai);
-}
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2019 by Andrew Selivanov
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+
+#include "ares.h"
+#include "ares_private.h"
+
+void ares__freeaddrinfo_cnames(struct ares_addrinfo_cname *head)
+{
+ struct ares_addrinfo_cname *current;
+ while (head)
+ {
+ current = head;
+ head = head->next;
+ ares_free(current->alias);
+ ares_free(current->name);
+ ares_free(current);
+ }
+}
+
+void ares__freeaddrinfo_nodes(struct ares_addrinfo_node *head)
+{
+ struct ares_addrinfo_node *current;
+ while (head)
+ {
+ current = head;
+ head = head->ai_next;
+ ares_free(current->ai_addr);
+ ares_free(current);
+ }
+}
+
+void ares_freeaddrinfo(struct ares_addrinfo *ai)
+{
+ ares__freeaddrinfo_cnames(ai->cnames);
+ ares__freeaddrinfo_nodes(ai->nodes);
+ ares_free(ai);
+}
diff --git a/contrib/libs/c-ares/ares_getaddrinfo.c b/contrib/libs/c-ares/ares_getaddrinfo.c
index d257e75673..be168068b1 100644
--- a/contrib/libs/c-ares/ares_getaddrinfo.c
+++ b/contrib/libs/c-ares/ares_getaddrinfo.c
@@ -1,765 +1,765 @@
-
-/* Copyright 1998, 2011, 2013 by the Massachusetts Institute of Technology.
- * Copyright (C) 2017 - 2018 by Christian Ammer
- * Copyright (C) 2019 by Andrew Selivanov
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting
- * documentation, and that the name of M.I.T. not be used in
- * advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- */
-
-#include "ares_setup.h"
-
-#ifdef HAVE_GETSERVBYNAME_R
-# if !defined(GETSERVBYNAME_R_ARGS) || \
- (GETSERVBYNAME_R_ARGS < 4) || (GETSERVBYNAME_R_ARGS > 6)
-# error "you MUST specifiy a valid number of arguments for getservbyname_r"
-# endif
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-# include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-# include <arpa/inet.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
-
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#include <assert.h>
-
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-
-#include "ares.h"
-#include "bitncmp.h"
-#include "ares_private.h"
-
-#ifdef WATT32
-#undef WIN32
-#endif
-#ifdef WIN32
-# include "ares_platform.h"
-#endif
-
-struct host_query
-{
- ares_channel channel;
- char *name;
- unsigned short port; /* in host order */
- ares_addrinfo_callback callback;
- void *arg;
- struct ares_addrinfo_hints hints;
- int sent_family; /* this family is what was is being used */
- int timeouts; /* number of timeouts we saw for this request */
- const char *remaining_lookups; /* types of lookup we need to perform ("fb" by
- default, file and dns respectively) */
- struct ares_addrinfo *ai; /* store results between lookups */
- int remaining; /* number of DNS answers waiting for */
- int next_domain; /* next search domain to try */
-};
-
-static const struct ares_addrinfo_hints default_hints = {
- 0, /* ai_flags */
- AF_UNSPEC, /* ai_family */
- 0, /* ai_socktype */
- 0, /* ai_protocol */
-};
-
-static const struct ares_addrinfo_cname empty_addrinfo_cname = {
- INT_MAX, /* ttl */
- NULL, /* alias */
- NULL, /* name */
- NULL, /* next */
-};
-
-static const struct ares_addrinfo_node empty_addrinfo_node = {
- 0, /* ai_ttl */
- 0, /* ai_flags */
- 0, /* ai_family */
- 0, /* ai_socktype */
- 0, /* ai_protocol */
- 0, /* ai_addrlen */
- NULL, /* ai_addr */
- NULL /* ai_next */
-};
-
-static const struct ares_addrinfo empty_addrinfo = {
- NULL, /* cnames */
- NULL /* nodes */
-};
-
-/* forward declarations */
-static void host_callback(void *arg, int status, int timeouts,
- unsigned char *abuf, int alen);
-static int as_is_first(const struct host_query *hquery);
-static int next_dns_lookup(struct host_query *hquery);
-
-struct ares_addrinfo_cname *ares__malloc_addrinfo_cname()
-{
- struct ares_addrinfo_cname *cname = ares_malloc(sizeof(struct ares_addrinfo_cname));
- if (!cname)
- return NULL;
-
- *cname = empty_addrinfo_cname;
- return cname;
-}
-
-struct ares_addrinfo_cname *ares__append_addrinfo_cname(struct ares_addrinfo_cname **head)
-{
- struct ares_addrinfo_cname *tail = ares__malloc_addrinfo_cname();
- struct ares_addrinfo_cname *last = *head;
- if (!last)
- {
- *head = tail;
- return tail;
- }
-
- while (last->next)
- {
- last = last->next;
- }
-
- last->next = tail;
- return tail;
-}
-
-void ares__addrinfo_cat_cnames(struct ares_addrinfo_cname **head,
- struct ares_addrinfo_cname *tail)
-{
- struct ares_addrinfo_cname *last = *head;
- if (!last)
- {
- *head = tail;
- return;
- }
-
- while (last->next)
- {
- last = last->next;
- }
-
- last->next = tail;
-}
-
-struct ares_addrinfo *ares__malloc_addrinfo()
-{
- struct ares_addrinfo *ai = ares_malloc(sizeof(struct ares_addrinfo));
- if (!ai)
- return NULL;
-
- *ai = empty_addrinfo;
- return ai;
-}
-
-struct ares_addrinfo_node *ares__malloc_addrinfo_node()
-{
- struct ares_addrinfo_node *node =
- ares_malloc(sizeof(struct ares_addrinfo_node));
- if (!node)
- return NULL;
-
- *node = empty_addrinfo_node;
- return node;
-}
-
-/* Allocate new addrinfo and append to the tail. */
-struct ares_addrinfo_node *ares__append_addrinfo_node(struct ares_addrinfo_node **head)
-{
- struct ares_addrinfo_node *tail = ares__malloc_addrinfo_node();
- struct ares_addrinfo_node *last = *head;
- if (!last)
- {
- *head = tail;
- return tail;
- }
-
- while (last->ai_next)
- {
- last = last->ai_next;
- }
-
- last->ai_next = tail;
- return tail;
-}
-
-void ares__addrinfo_cat_nodes(struct ares_addrinfo_node **head,
- struct ares_addrinfo_node *tail)
-{
- struct ares_addrinfo_node *last = *head;
- if (!last)
- {
- *head = tail;
- return;
- }
-
- while (last->ai_next)
- {
- last = last->ai_next;
- }
-
- last->ai_next = tail;
-}
-
-/* Resolve service name into port number given in host byte order.
- * If not resolved, return 0.
- */
-static unsigned short lookup_service(const char *service, int flags)
-{
- const char *proto;
- struct servent *sep;
-#ifdef HAVE_GETSERVBYNAME_R
- struct servent se;
- char tmpbuf[4096];
-#endif
-
- if (service)
- {
- if (flags & ARES_NI_UDP)
- proto = "udp";
- else if (flags & ARES_NI_SCTP)
- proto = "sctp";
- else if (flags & ARES_NI_DCCP)
- proto = "dccp";
- else
- proto = "tcp";
-#ifdef HAVE_GETSERVBYNAME_R
- memset(&se, 0, sizeof(se));
- sep = &se;
- memset(tmpbuf, 0, sizeof(tmpbuf));
-#if GETSERVBYNAME_R_ARGS == 6
- if (getservbyname_r(service, proto, &se, (void *)tmpbuf, sizeof(tmpbuf),
- &sep) != 0)
- sep = NULL; /* LCOV_EXCL_LINE: buffer large so this never fails */
-#elif GETSERVBYNAME_R_ARGS == 5
- sep =
- getservbyname_r(service, proto, &se, (void *)tmpbuf, sizeof(tmpbuf));
-#elif GETSERVBYNAME_R_ARGS == 4
- if (getservbyname_r(service, proto, &se, (void *)tmpbuf) != 0)
- sep = NULL;
-#else
- /* Lets just hope the OS uses TLS! */
- sep = getservbyname(service, proto);
-#endif
-#else
- /* Lets just hope the OS uses TLS! */
-#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
- sep = getservbyname(service, (char *)proto);
-#else
- sep = getservbyname(service, proto);
-#endif
-#endif
- return (sep ? ntohs((unsigned short)sep->s_port) : 0);
- }
- return 0;
-}
-
-/* If the name looks like an IP address or an error occured,
- * fake up a host entry, end the query immediately, and return true.
- * Otherwise return false.
- */
-static int fake_addrinfo(const char *name,
- unsigned short port,
- const struct ares_addrinfo_hints *hints,
- struct ares_addrinfo *ai,
- ares_addrinfo_callback callback,
- void *arg)
-{
- struct ares_addrinfo_cname *cname;
- struct ares_addrinfo_node *node;
- ares_sockaddr addr;
- size_t addrlen;
- int result = 0;
- int family = hints->ai_family;
- if (family == AF_INET || family == AF_INET6 || family == AF_UNSPEC)
- {
- /* It only looks like an IP address if it's all numbers and dots. */
- int numdots = 0, valid = 1;
- const char *p;
- for (p = name; *p; p++)
- {
- if (!ISDIGIT(*p) && *p != '.')
- {
- valid = 0;
- break;
- }
- else if (*p == '.')
- {
- numdots++;
- }
- }
-
- memset(&addr, 0, sizeof(addr));
-
- /* if we don't have 3 dots, it is illegal
- * (although inet_pton doesn't think so).
- */
- if (numdots != 3 || !valid)
- result = 0;
- else
- result =
- (ares_inet_pton(AF_INET, name, &addr.sa4.sin_addr) < 1 ? 0 : 1);
-
- if (result)
- {
- family = addr.sa.sa_family = AF_INET;
- addr.sa4.sin_port = htons(port);
- addrlen = sizeof(addr.sa4);
- }
- }
-
- if (family == AF_INET6 || family == AF_UNSPEC)
- {
- result =
- (ares_inet_pton(AF_INET6, name, &addr.sa6.sin6_addr) < 1 ? 0 : 1);
- addr.sa6.sin6_family = AF_INET6;
- addr.sa6.sin6_port = htons(port);
- addrlen = sizeof(addr.sa6);
- }
-
- if (!result)
- return 0;
-
- node = ares__malloc_addrinfo_node();
- if (!node)
- {
- ares_freeaddrinfo(ai);
- callback(arg, ARES_ENOMEM, 0, NULL);
- return 1;
- }
-
- ai->nodes = node;
-
- node->ai_addr = ares_malloc(addrlen);
- if (!node->ai_addr)
- {
- ares_freeaddrinfo(ai);
- callback(arg, ARES_ENOMEM, 0, NULL);
- return 1;
- }
-
- node->ai_addrlen = (unsigned int)addrlen;
- node->ai_family = addr.sa.sa_family;
- if (addr.sa.sa_family == AF_INET)
- memcpy(node->ai_addr, &addr.sa4, sizeof(addr.sa4));
- else
- memcpy(node->ai_addr, &addr.sa6, sizeof(addr.sa6));
-
- if (hints->ai_flags & ARES_AI_CANONNAME)
- {
- cname = ares__append_addrinfo_cname(&ai->cnames);
- if (!cname)
- {
- ares_freeaddrinfo(ai);
- callback(arg, ARES_ENOMEM, 0, NULL);
- return 1;
- }
-
- /* Duplicate the name, to avoid a constness violation. */
- cname->name = ares_strdup(name);
- if (!cname->name)
- {
- ares_freeaddrinfo(ai);
- callback(arg, ARES_ENOMEM, 0, NULL);
- return 1;
- }
- }
-
- callback(arg, ARES_SUCCESS, 0, ai);
- return 1;
-}
-
-static void end_hquery(struct host_query *hquery, int status)
-{
- struct ares_addrinfo_node sentinel;
- struct ares_addrinfo_node *next;
- if (status == ARES_SUCCESS)
- {
- if (!(hquery->hints.ai_flags & ARES_AI_NOSORT))
- {
- sentinel.ai_next = hquery->ai->nodes;
- ares__sortaddrinfo(hquery->channel, &sentinel);
- hquery->ai->nodes = sentinel.ai_next;
- }
- next = hquery->ai->nodes;
- /* Set port into each address (resolved separately). */
- while (next)
- {
- if (next->ai_family == AF_INET)
- {
- (CARES_INADDR_CAST(struct sockaddr_in *, next->ai_addr))->sin_port = htons(hquery->port);
- }
- else
- {
- (CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr))->sin6_port = htons(hquery->port);
- }
- next = next->ai_next;
- }
- }
- else
- {
- /* Clean up what we have collected by so far. */
- ares_freeaddrinfo(hquery->ai);
- hquery->ai = NULL;
- }
-
- hquery->callback(hquery->arg, status, hquery->timeouts, hquery->ai);
- ares_free(hquery->name);
- ares_free(hquery);
-}
-
-static int file_lookup(struct host_query *hquery)
-{
- FILE *fp;
- int error;
- int status;
- const char *path_hosts = NULL;
-
- if (hquery->hints.ai_flags & ARES_AI_ENVHOSTS)
- {
- path_hosts = getenv("CARES_HOSTS");
- }
-
- if (!path_hosts)
- {
-#ifdef WIN32
- char PATH_HOSTS[MAX_PATH];
- win_platform platform;
-
- PATH_HOSTS[0] = '\0';
-
- platform = ares__getplatform();
-
- if (platform == WIN_NT)
- {
- char tmp[MAX_PATH];
- HKEY hkeyHosts;
-
- if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ,
- &hkeyHosts) == ERROR_SUCCESS)
- {
- DWORD dwLength = MAX_PATH;
- RegQueryValueExA(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp,
- &dwLength);
- ExpandEnvironmentStringsA(tmp, PATH_HOSTS, MAX_PATH);
- RegCloseKey(hkeyHosts);
- }
- }
- else if (platform == WIN_9X)
- GetWindowsDirectoryA(PATH_HOSTS, MAX_PATH);
- else
- return ARES_ENOTFOUND;
-
- strcat(PATH_HOSTS, WIN_PATH_HOSTS);
- path_hosts = PATH_HOSTS;
-
-#elif defined(WATT32)
- const char *PATH_HOSTS = _w32_GetHostsFile();
-
- if (!PATH_HOSTS)
- return ARES_ENOTFOUND;
-#endif
- path_hosts = PATH_HOSTS;
- }
-
- fp = fopen(path_hosts, "r");
- if (!fp)
- {
- error = ERRNO;
- switch (error)
- {
- case ENOENT:
- case ESRCH:
- return ARES_ENOTFOUND;
- default:
- DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", error,
- strerror(error)));
- DEBUGF(fprintf(stderr, "Error opening file: %s\n", path_hosts));
- return ARES_EFILE;
- }
- }
- status = ares__readaddrinfo(fp, hquery->name, hquery->port, &hquery->hints, hquery->ai);
- fclose(fp);
- return status;
-}
-
-static void next_lookup(struct host_query *hquery, int status)
-{
- switch (*hquery->remaining_lookups)
- {
- case 'b':
- /* DNS lookup */
- if (next_dns_lookup(hquery))
- break;
- hquery->remaining_lookups++;
- next_lookup(hquery, status);
- break;
-
- case 'f':
- /* Host file lookup */
- if (file_lookup(hquery) == ARES_SUCCESS)
- {
- end_hquery(hquery, ARES_SUCCESS);
- break;
- }
- hquery->remaining_lookups++;
- next_lookup(hquery, status);
- break;
- default:
- /* No lookup left */
- end_hquery(hquery, status);
- break;
- }
-}
-
-static void host_callback(void *arg, int status, int timeouts,
- unsigned char *abuf, int alen)
-{
- struct host_query *hquery = (struct host_query*)arg;
- int addinfostatus = ARES_SUCCESS;
- hquery->timeouts += timeouts;
- hquery->remaining--;
-
- if (status == ARES_SUCCESS)
- {
- addinfostatus = ares__parse_into_addrinfo(abuf, alen, hquery->ai);
- }
- else if (status == ARES_EDESTRUCTION)
- {
- end_hquery(hquery, status);
- return;
- }
-
- if (!hquery->remaining)
- {
- if (addinfostatus != ARES_SUCCESS)
- {
- /* error in parsing result e.g. no memory */
- end_hquery(hquery, addinfostatus);
- }
- else if (hquery->ai->nodes)
- {
- /* at least one query ended with ARES_SUCCESS */
- end_hquery(hquery, ARES_SUCCESS);
- }
- else if (status == ARES_ENOTFOUND)
- {
- next_lookup(hquery, status);
- }
- else
- {
- end_hquery(hquery, status);
- }
- }
-
- /* at this point we keep on waiting for the next query to finish */
-}
-
-void ares_getaddrinfo(ares_channel channel,
- const char* name, const char* service,
- const struct ares_addrinfo_hints* hints,
- ares_addrinfo_callback callback, void* arg)
-{
- struct host_query *hquery;
- unsigned short port = 0;
- int family;
- struct ares_addrinfo *ai;
-
- if (!hints)
- {
- hints = &default_hints;
- }
-
- family = hints->ai_family;
-
- /* Right now we only know how to look up Internet addresses
- and unspec means try both basically. */
- if (family != AF_INET &&
- family != AF_INET6 &&
- family != AF_UNSPEC)
- {
- callback(arg, ARES_ENOTIMP, 0, NULL);
- return;
- }
-
- if (ares__is_onion_domain(name))
- {
- callback(arg, ARES_ENOTFOUND, 0, NULL);
- return;
- }
-
- if (service)
- {
- if (hints->ai_flags & ARES_AI_NUMERICSERV)
- {
- port = (unsigned short)strtoul(service, NULL, 0);
- if (!port)
- {
- callback(arg, ARES_ESERVICE, 0, NULL);
- return;
- }
- }
- else
- {
- port = lookup_service(service, 0);
- if (!port)
- {
- port = (unsigned short)strtoul(service, NULL, 0);
- if (!port)
- {
- callback(arg, ARES_ESERVICE, 0, NULL);
- return;
- }
- }
- }
- }
-
- ai = ares__malloc_addrinfo();
- if (!ai)
- {
- callback(arg, ARES_ENOMEM, 0, NULL);
- return;
- }
-
- if (fake_addrinfo(name, port, hints, ai, callback, arg))
- {
- return;
- }
-
- /* Allocate and fill in the host query structure. */
- hquery = ares_malloc(sizeof(struct host_query));
- if (!hquery)
- {
- ares_freeaddrinfo(ai);
- callback(arg, ARES_ENOMEM, 0, NULL);
- return;
- }
-
- hquery->name = ares_strdup(name);
- if (!hquery->name)
- {
- ares_free(hquery);
- ares_freeaddrinfo(ai);
- callback(arg, ARES_ENOMEM, 0, NULL);
- return;
- }
-
- hquery->port = port;
- hquery->channel = channel;
- hquery->hints = *hints;
- hquery->sent_family = -1; /* nothing is sent yet */
- hquery->callback = callback;
- hquery->arg = arg;
- hquery->remaining_lookups = channel->lookups;
- hquery->timeouts = 0;
- hquery->ai = ai;
- hquery->next_domain = -1;
- hquery->remaining = 0;
-
- /* Start performing lookups according to channel->lookups. */
- next_lookup(hquery, ARES_ECONNREFUSED /* initial error code */);
-}
-
-static int next_dns_lookup(struct host_query *hquery)
-{
- char *s = NULL;
- int is_s_allocated = 0;
- int status;
-
- /* if next_domain == -1 and as_is_first is true, try hquery->name */
- if (hquery->next_domain == -1)
- {
- if (as_is_first(hquery))
- {
- s = hquery->name;
- }
- hquery->next_domain = 0;
- }
-
- /* if as_is_first is false, try hquery->name at last */
- if (!s && hquery->next_domain == hquery->channel->ndomains) {
- if (!as_is_first(hquery))
- {
- s = hquery->name;
- }
- hquery->next_domain++;
- }
-
- if (!s && hquery->next_domain < hquery->channel->ndomains)
- {
- status = ares__cat_domain(
- hquery->name,
- hquery->channel->domains[hquery->next_domain++],
- &s);
- if (status == ARES_SUCCESS)
- {
- is_s_allocated = 1;
- }
- }
-
- if (s)
- {
- switch (hquery->hints.ai_family)
- {
- case AF_INET:
- hquery->remaining += 1;
- ares_query(hquery->channel, s, C_IN, T_A, host_callback, hquery);
- break;
- case AF_INET6:
- hquery->remaining += 1;
- ares_query(hquery->channel, s, C_IN, T_AAAA, host_callback, hquery);
- break;
- case AF_UNSPEC:
- hquery->remaining += 2;
- ares_query(hquery->channel, s, C_IN, T_A, host_callback, hquery);
- ares_query(hquery->channel, s, C_IN, T_AAAA, host_callback, hquery);
- break;
- default: break;
- }
- if (is_s_allocated)
- {
- ares_free(s);
- }
- return 1;
- }
- else
- {
- assert(!hquery->ai->nodes);
- return 0;
- }
-}
-
-static int as_is_first(const struct host_query* hquery)
-{
- char* p;
- int ndots = 0;
- for (p = hquery->name; *p; p++)
- {
- if (*p == '.')
- {
- ndots++;
- }
- }
- return ndots >= hquery->channel->ndots;
-}
+
+/* Copyright 1998, 2011, 2013 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2017 - 2018 by Christian Ammer
+ * Copyright (C) 2019 by Andrew Selivanov
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_GETSERVBYNAME_R
+# if !defined(GETSERVBYNAME_R_ARGS) || \
+ (GETSERVBYNAME_R_ARGS < 4) || (GETSERVBYNAME_R_ARGS > 6)
+# error "you MUST specifiy a valid number of arguments for getservbyname_r"
+# endif
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+#else
+# include "nameser.h"
+#endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+# include <arpa/nameser_compat.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#include <assert.h>
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include "ares.h"
+#include "bitncmp.h"
+#include "ares_private.h"
+
+#ifdef WATT32
+#undef WIN32
+#endif
+#ifdef WIN32
+# include "ares_platform.h"
+#endif
+
+struct host_query
+{
+ ares_channel channel;
+ char *name;
+ unsigned short port; /* in host order */
+ ares_addrinfo_callback callback;
+ void *arg;
+ struct ares_addrinfo_hints hints;
+ int sent_family; /* this family is what was is being used */
+ int timeouts; /* number of timeouts we saw for this request */
+ const char *remaining_lookups; /* types of lookup we need to perform ("fb" by
+ default, file and dns respectively) */
+ struct ares_addrinfo *ai; /* store results between lookups */
+ int remaining; /* number of DNS answers waiting for */
+ int next_domain; /* next search domain to try */
+};
+
+static const struct ares_addrinfo_hints default_hints = {
+ 0, /* ai_flags */
+ AF_UNSPEC, /* ai_family */
+ 0, /* ai_socktype */
+ 0, /* ai_protocol */
+};
+
+static const struct ares_addrinfo_cname empty_addrinfo_cname = {
+ INT_MAX, /* ttl */
+ NULL, /* alias */
+ NULL, /* name */
+ NULL, /* next */
+};
+
+static const struct ares_addrinfo_node empty_addrinfo_node = {
+ 0, /* ai_ttl */
+ 0, /* ai_flags */
+ 0, /* ai_family */
+ 0, /* ai_socktype */
+ 0, /* ai_protocol */
+ 0, /* ai_addrlen */
+ NULL, /* ai_addr */
+ NULL /* ai_next */
+};
+
+static const struct ares_addrinfo empty_addrinfo = {
+ NULL, /* cnames */
+ NULL /* nodes */
+};
+
+/* forward declarations */
+static void host_callback(void *arg, int status, int timeouts,
+ unsigned char *abuf, int alen);
+static int as_is_first(const struct host_query *hquery);
+static int next_dns_lookup(struct host_query *hquery);
+
+struct ares_addrinfo_cname *ares__malloc_addrinfo_cname()
+{
+ struct ares_addrinfo_cname *cname = ares_malloc(sizeof(struct ares_addrinfo_cname));
+ if (!cname)
+ return NULL;
+
+ *cname = empty_addrinfo_cname;
+ return cname;
+}
+
+struct ares_addrinfo_cname *ares__append_addrinfo_cname(struct ares_addrinfo_cname **head)
+{
+ struct ares_addrinfo_cname *tail = ares__malloc_addrinfo_cname();
+ struct ares_addrinfo_cname *last = *head;
+ if (!last)
+ {
+ *head = tail;
+ return tail;
+ }
+
+ while (last->next)
+ {
+ last = last->next;
+ }
+
+ last->next = tail;
+ return tail;
+}
+
+void ares__addrinfo_cat_cnames(struct ares_addrinfo_cname **head,
+ struct ares_addrinfo_cname *tail)
+{
+ struct ares_addrinfo_cname *last = *head;
+ if (!last)
+ {
+ *head = tail;
+ return;
+ }
+
+ while (last->next)
+ {
+ last = last->next;
+ }
+
+ last->next = tail;
+}
+
+struct ares_addrinfo *ares__malloc_addrinfo()
+{
+ struct ares_addrinfo *ai = ares_malloc(sizeof(struct ares_addrinfo));
+ if (!ai)
+ return NULL;
+
+ *ai = empty_addrinfo;
+ return ai;
+}
+
+struct ares_addrinfo_node *ares__malloc_addrinfo_node()
+{
+ struct ares_addrinfo_node *node =
+ ares_malloc(sizeof(struct ares_addrinfo_node));
+ if (!node)
+ return NULL;
+
+ *node = empty_addrinfo_node;
+ return node;
+}
+
+/* Allocate new addrinfo and append to the tail. */
+struct ares_addrinfo_node *ares__append_addrinfo_node(struct ares_addrinfo_node **head)
+{
+ struct ares_addrinfo_node *tail = ares__malloc_addrinfo_node();
+ struct ares_addrinfo_node *last = *head;
+ if (!last)
+ {
+ *head = tail;
+ return tail;
+ }
+
+ while (last->ai_next)
+ {
+ last = last->ai_next;
+ }
+
+ last->ai_next = tail;
+ return tail;
+}
+
+void ares__addrinfo_cat_nodes(struct ares_addrinfo_node **head,
+ struct ares_addrinfo_node *tail)
+{
+ struct ares_addrinfo_node *last = *head;
+ if (!last)
+ {
+ *head = tail;
+ return;
+ }
+
+ while (last->ai_next)
+ {
+ last = last->ai_next;
+ }
+
+ last->ai_next = tail;
+}
+
+/* Resolve service name into port number given in host byte order.
+ * If not resolved, return 0.
+ */
+static unsigned short lookup_service(const char *service, int flags)
+{
+ const char *proto;
+ struct servent *sep;
+#ifdef HAVE_GETSERVBYNAME_R
+ struct servent se;
+ char tmpbuf[4096];
+#endif
+
+ if (service)
+ {
+ if (flags & ARES_NI_UDP)
+ proto = "udp";
+ else if (flags & ARES_NI_SCTP)
+ proto = "sctp";
+ else if (flags & ARES_NI_DCCP)
+ proto = "dccp";
+ else
+ proto = "tcp";
+#ifdef HAVE_GETSERVBYNAME_R
+ memset(&se, 0, sizeof(se));
+ sep = &se;
+ memset(tmpbuf, 0, sizeof(tmpbuf));
+#if GETSERVBYNAME_R_ARGS == 6
+ if (getservbyname_r(service, proto, &se, (void *)tmpbuf, sizeof(tmpbuf),
+ &sep) != 0)
+ sep = NULL; /* LCOV_EXCL_LINE: buffer large so this never fails */
+#elif GETSERVBYNAME_R_ARGS == 5
+ sep =
+ getservbyname_r(service, proto, &se, (void *)tmpbuf, sizeof(tmpbuf));
+#elif GETSERVBYNAME_R_ARGS == 4
+ if (getservbyname_r(service, proto, &se, (void *)tmpbuf) != 0)
+ sep = NULL;
+#else
+ /* Lets just hope the OS uses TLS! */
+ sep = getservbyname(service, proto);
+#endif
+#else
+ /* Lets just hope the OS uses TLS! */
+#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
+ sep = getservbyname(service, (char *)proto);
+#else
+ sep = getservbyname(service, proto);
+#endif
+#endif
+ return (sep ? ntohs((unsigned short)sep->s_port) : 0);
+ }
+ return 0;
+}
+
+/* If the name looks like an IP address or an error occured,
+ * fake up a host entry, end the query immediately, and return true.
+ * Otherwise return false.
+ */
+static int fake_addrinfo(const char *name,
+ unsigned short port,
+ const struct ares_addrinfo_hints *hints,
+ struct ares_addrinfo *ai,
+ ares_addrinfo_callback callback,
+ void *arg)
+{
+ struct ares_addrinfo_cname *cname;
+ struct ares_addrinfo_node *node;
+ ares_sockaddr addr;
+ size_t addrlen;
+ int result = 0;
+ int family = hints->ai_family;
+ if (family == AF_INET || family == AF_INET6 || family == AF_UNSPEC)
+ {
+ /* It only looks like an IP address if it's all numbers and dots. */
+ int numdots = 0, valid = 1;
+ const char *p;
+ for (p = name; *p; p++)
+ {
+ if (!ISDIGIT(*p) && *p != '.')
+ {
+ valid = 0;
+ break;
+ }
+ else if (*p == '.')
+ {
+ numdots++;
+ }
+ }
+
+ memset(&addr, 0, sizeof(addr));
+
+ /* if we don't have 3 dots, it is illegal
+ * (although inet_pton doesn't think so).
+ */
+ if (numdots != 3 || !valid)
+ result = 0;
+ else
+ result =
+ (ares_inet_pton(AF_INET, name, &addr.sa4.sin_addr) < 1 ? 0 : 1);
+
+ if (result)
+ {
+ family = addr.sa.sa_family = AF_INET;
+ addr.sa4.sin_port = htons(port);
+ addrlen = sizeof(addr.sa4);
+ }
+ }
+
+ if (family == AF_INET6 || family == AF_UNSPEC)
+ {
+ result =
+ (ares_inet_pton(AF_INET6, name, &addr.sa6.sin6_addr) < 1 ? 0 : 1);
+ addr.sa6.sin6_family = AF_INET6;
+ addr.sa6.sin6_port = htons(port);
+ addrlen = sizeof(addr.sa6);
+ }
+
+ if (!result)
+ return 0;
+
+ node = ares__malloc_addrinfo_node();
+ if (!node)
+ {
+ ares_freeaddrinfo(ai);
+ callback(arg, ARES_ENOMEM, 0, NULL);
+ return 1;
+ }
+
+ ai->nodes = node;
+
+ node->ai_addr = ares_malloc(addrlen);
+ if (!node->ai_addr)
+ {
+ ares_freeaddrinfo(ai);
+ callback(arg, ARES_ENOMEM, 0, NULL);
+ return 1;
+ }
+
+ node->ai_addrlen = (unsigned int)addrlen;
+ node->ai_family = addr.sa.sa_family;
+ if (addr.sa.sa_family == AF_INET)
+ memcpy(node->ai_addr, &addr.sa4, sizeof(addr.sa4));
+ else
+ memcpy(node->ai_addr, &addr.sa6, sizeof(addr.sa6));
+
+ if (hints->ai_flags & ARES_AI_CANONNAME)
+ {
+ cname = ares__append_addrinfo_cname(&ai->cnames);
+ if (!cname)
+ {
+ ares_freeaddrinfo(ai);
+ callback(arg, ARES_ENOMEM, 0, NULL);
+ return 1;
+ }
+
+ /* Duplicate the name, to avoid a constness violation. */
+ cname->name = ares_strdup(name);
+ if (!cname->name)
+ {
+ ares_freeaddrinfo(ai);
+ callback(arg, ARES_ENOMEM, 0, NULL);
+ return 1;
+ }
+ }
+
+ callback(arg, ARES_SUCCESS, 0, ai);
+ return 1;
+}
+
+static void end_hquery(struct host_query *hquery, int status)
+{
+ struct ares_addrinfo_node sentinel;
+ struct ares_addrinfo_node *next;
+ if (status == ARES_SUCCESS)
+ {
+ if (!(hquery->hints.ai_flags & ARES_AI_NOSORT))
+ {
+ sentinel.ai_next = hquery->ai->nodes;
+ ares__sortaddrinfo(hquery->channel, &sentinel);
+ hquery->ai->nodes = sentinel.ai_next;
+ }
+ next = hquery->ai->nodes;
+ /* Set port into each address (resolved separately). */
+ while (next)
+ {
+ if (next->ai_family == AF_INET)
+ {
+ (CARES_INADDR_CAST(struct sockaddr_in *, next->ai_addr))->sin_port = htons(hquery->port);
+ }
+ else
+ {
+ (CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr))->sin6_port = htons(hquery->port);
+ }
+ next = next->ai_next;
+ }
+ }
+ else
+ {
+ /* Clean up what we have collected by so far. */
+ ares_freeaddrinfo(hquery->ai);
+ hquery->ai = NULL;
+ }
+
+ hquery->callback(hquery->arg, status, hquery->timeouts, hquery->ai);
+ ares_free(hquery->name);
+ ares_free(hquery);
+}
+
+static int file_lookup(struct host_query *hquery)
+{
+ FILE *fp;
+ int error;
+ int status;
+ const char *path_hosts = NULL;
+
+ if (hquery->hints.ai_flags & ARES_AI_ENVHOSTS)
+ {
+ path_hosts = getenv("CARES_HOSTS");
+ }
+
+ if (!path_hosts)
+ {
+#ifdef WIN32
+ char PATH_HOSTS[MAX_PATH];
+ win_platform platform;
+
+ PATH_HOSTS[0] = '\0';
+
+ platform = ares__getplatform();
+
+ if (platform == WIN_NT)
+ {
+ char tmp[MAX_PATH];
+ HKEY hkeyHosts;
+
+ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ,
+ &hkeyHosts) == ERROR_SUCCESS)
+ {
+ DWORD dwLength = MAX_PATH;
+ RegQueryValueExA(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp,
+ &dwLength);
+ ExpandEnvironmentStringsA(tmp, PATH_HOSTS, MAX_PATH);
+ RegCloseKey(hkeyHosts);
+ }
+ }
+ else if (platform == WIN_9X)
+ GetWindowsDirectoryA(PATH_HOSTS, MAX_PATH);
+ else
+ return ARES_ENOTFOUND;
+
+ strcat(PATH_HOSTS, WIN_PATH_HOSTS);
+ path_hosts = PATH_HOSTS;
+
+#elif defined(WATT32)
+ const char *PATH_HOSTS = _w32_GetHostsFile();
+
+ if (!PATH_HOSTS)
+ return ARES_ENOTFOUND;
+#endif
+ path_hosts = PATH_HOSTS;
+ }
+
+ fp = fopen(path_hosts, "r");
+ if (!fp)
+ {
+ error = ERRNO;
+ switch (error)
+ {
+ case ENOENT:
+ case ESRCH:
+ return ARES_ENOTFOUND;
+ default:
+ DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", error,
+ strerror(error)));
+ DEBUGF(fprintf(stderr, "Error opening file: %s\n", path_hosts));
+ return ARES_EFILE;
+ }
+ }
+ status = ares__readaddrinfo(fp, hquery->name, hquery->port, &hquery->hints, hquery->ai);
+ fclose(fp);
+ return status;
+}
+
+static void next_lookup(struct host_query *hquery, int status)
+{
+ switch (*hquery->remaining_lookups)
+ {
+ case 'b':
+ /* DNS lookup */
+ if (next_dns_lookup(hquery))
+ break;
+ hquery->remaining_lookups++;
+ next_lookup(hquery, status);
+ break;
+
+ case 'f':
+ /* Host file lookup */
+ if (file_lookup(hquery) == ARES_SUCCESS)
+ {
+ end_hquery(hquery, ARES_SUCCESS);
+ break;
+ }
+ hquery->remaining_lookups++;
+ next_lookup(hquery, status);
+ break;
+ default:
+ /* No lookup left */
+ end_hquery(hquery, status);
+ break;
+ }
+}
+
+static void host_callback(void *arg, int status, int timeouts,
+ unsigned char *abuf, int alen)
+{
+ struct host_query *hquery = (struct host_query*)arg;
+ int addinfostatus = ARES_SUCCESS;
+ hquery->timeouts += timeouts;
+ hquery->remaining--;
+
+ if (status == ARES_SUCCESS)
+ {
+ addinfostatus = ares__parse_into_addrinfo(abuf, alen, hquery->ai);
+ }
+ else if (status == ARES_EDESTRUCTION)
+ {
+ end_hquery(hquery, status);
+ return;
+ }
+
+ if (!hquery->remaining)
+ {
+ if (addinfostatus != ARES_SUCCESS)
+ {
+ /* error in parsing result e.g. no memory */
+ end_hquery(hquery, addinfostatus);
+ }
+ else if (hquery->ai->nodes)
+ {
+ /* at least one query ended with ARES_SUCCESS */
+ end_hquery(hquery, ARES_SUCCESS);
+ }
+ else if (status == ARES_ENOTFOUND)
+ {
+ next_lookup(hquery, status);
+ }
+ else
+ {
+ end_hquery(hquery, status);
+ }
+ }
+
+ /* at this point we keep on waiting for the next query to finish */
+}
+
+void ares_getaddrinfo(ares_channel channel,
+ const char* name, const char* service,
+ const struct ares_addrinfo_hints* hints,
+ ares_addrinfo_callback callback, void* arg)
+{
+ struct host_query *hquery;
+ unsigned short port = 0;
+ int family;
+ struct ares_addrinfo *ai;
+
+ if (!hints)
+ {
+ hints = &default_hints;
+ }
+
+ family = hints->ai_family;
+
+ /* Right now we only know how to look up Internet addresses
+ and unspec means try both basically. */
+ if (family != AF_INET &&
+ family != AF_INET6 &&
+ family != AF_UNSPEC)
+ {
+ callback(arg, ARES_ENOTIMP, 0, NULL);
+ return;
+ }
+
+ if (ares__is_onion_domain(name))
+ {
+ callback(arg, ARES_ENOTFOUND, 0, NULL);
+ return;
+ }
+
+ if (service)
+ {
+ if (hints->ai_flags & ARES_AI_NUMERICSERV)
+ {
+ port = (unsigned short)strtoul(service, NULL, 0);
+ if (!port)
+ {
+ callback(arg, ARES_ESERVICE, 0, NULL);
+ return;
+ }
+ }
+ else
+ {
+ port = lookup_service(service, 0);
+ if (!port)
+ {
+ port = (unsigned short)strtoul(service, NULL, 0);
+ if (!port)
+ {
+ callback(arg, ARES_ESERVICE, 0, NULL);
+ return;
+ }
+ }
+ }
+ }
+
+ ai = ares__malloc_addrinfo();
+ if (!ai)
+ {
+ callback(arg, ARES_ENOMEM, 0, NULL);
+ return;
+ }
+
+ if (fake_addrinfo(name, port, hints, ai, callback, arg))
+ {
+ return;
+ }
+
+ /* Allocate and fill in the host query structure. */
+ hquery = ares_malloc(sizeof(struct host_query));
+ if (!hquery)
+ {
+ ares_freeaddrinfo(ai);
+ callback(arg, ARES_ENOMEM, 0, NULL);
+ return;
+ }
+
+ hquery->name = ares_strdup(name);
+ if (!hquery->name)
+ {
+ ares_free(hquery);
+ ares_freeaddrinfo(ai);
+ callback(arg, ARES_ENOMEM, 0, NULL);
+ return;
+ }
+
+ hquery->port = port;
+ hquery->channel = channel;
+ hquery->hints = *hints;
+ hquery->sent_family = -1; /* nothing is sent yet */
+ hquery->callback = callback;
+ hquery->arg = arg;
+ hquery->remaining_lookups = channel->lookups;
+ hquery->timeouts = 0;
+ hquery->ai = ai;
+ hquery->next_domain = -1;
+ hquery->remaining = 0;
+
+ /* Start performing lookups according to channel->lookups. */
+ next_lookup(hquery, ARES_ECONNREFUSED /* initial error code */);
+}
+
+static int next_dns_lookup(struct host_query *hquery)
+{
+ char *s = NULL;
+ int is_s_allocated = 0;
+ int status;
+
+ /* if next_domain == -1 and as_is_first is true, try hquery->name */
+ if (hquery->next_domain == -1)
+ {
+ if (as_is_first(hquery))
+ {
+ s = hquery->name;
+ }
+ hquery->next_domain = 0;
+ }
+
+ /* if as_is_first is false, try hquery->name at last */
+ if (!s && hquery->next_domain == hquery->channel->ndomains) {
+ if (!as_is_first(hquery))
+ {
+ s = hquery->name;
+ }
+ hquery->next_domain++;
+ }
+
+ if (!s && hquery->next_domain < hquery->channel->ndomains)
+ {
+ status = ares__cat_domain(
+ hquery->name,
+ hquery->channel->domains[hquery->next_domain++],
+ &s);
+ if (status == ARES_SUCCESS)
+ {
+ is_s_allocated = 1;
+ }
+ }
+
+ if (s)
+ {
+ switch (hquery->hints.ai_family)
+ {
+ case AF_INET:
+ hquery->remaining += 1;
+ ares_query(hquery->channel, s, C_IN, T_A, host_callback, hquery);
+ break;
+ case AF_INET6:
+ hquery->remaining += 1;
+ ares_query(hquery->channel, s, C_IN, T_AAAA, host_callback, hquery);
+ break;
+ case AF_UNSPEC:
+ hquery->remaining += 2;
+ ares_query(hquery->channel, s, C_IN, T_A, host_callback, hquery);
+ ares_query(hquery->channel, s, C_IN, T_AAAA, host_callback, hquery);
+ break;
+ default: break;
+ }
+ if (is_s_allocated)
+ {
+ ares_free(s);
+ }
+ return 1;
+ }
+ else
+ {
+ assert(!hquery->ai->nodes);
+ return 0;
+ }
+}
+
+static int as_is_first(const struct host_query* hquery)
+{
+ char* p;
+ int ndots = 0;
+ for (p = hquery->name; *p; p++)
+ {
+ if (*p == '.')
+ {
+ ndots++;
+ }
+ }
+ return ndots >= hquery->channel->ndots;
+}
diff --git a/contrib/libs/c-ares/ares_gethostbyname.c b/contrib/libs/c-ares/ares_gethostbyname.c
index 527b0b60e8..ecd03e7931 100644
--- a/contrib/libs/c-ares/ares_gethostbyname.c
+++ b/contrib/libs/c-ares/ares_gethostbyname.c
@@ -211,13 +211,13 @@ static void host_callback(void *arg, int status, int timeouts,
if (host && channel->nsort)
sort6_addresses(host, channel->sortlist, channel->nsort);
}
- if (status == ARES_SUCCESS && host && host->h_addr_list[0] == NULL)
- {
- /* The query returned something but had no A/AAAA record
- (even after potentially retrying AAAA with A)
- so we should treat this as an error */
- status = ARES_ENODATA;
- }
+ if (status == ARES_SUCCESS && host && host->h_addr_list[0] == NULL)
+ {
+ /* The query returned something but had no A/AAAA record
+ (even after potentially retrying AAAA with A)
+ so we should treat this as an error */
+ status = ARES_ENODATA;
+ }
end_hquery(hquery, status, host);
}
else if ((status == ARES_ENODATA || status == ARES_EBADRESP ||
@@ -274,12 +274,12 @@ static int fake_hostent(const char *name, int family,
}
/* if we don't have 3 dots, it is illegal
- * (although inet_pton doesn't think so).
+ * (although inet_pton doesn't think so).
*/
if (numdots != 3 || !valid)
result = 0;
else
- result = (ares_inet_pton(AF_INET, name, &in) < 1 ? 0 : 1);
+ result = (ares_inet_pton(AF_INET, name, &in) < 1 ? 0 : 1);
if (result)
family = AF_INET;
@@ -390,11 +390,11 @@ static int file_lookup(const char *name, int family, struct hostent **host)
return ARES_ENOTFOUND;
#endif
- /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */
- if (ares__is_onion_domain(name))
- return ARES_ENOTFOUND;
-
-
+ /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */
+ if (ares__is_onion_domain(name))
+ return ARES_ENOTFOUND;
+
+
fp = fopen(PATH_HOSTS, "r");
if (!fp)
{
diff --git a/contrib/libs/c-ares/ares_getnameinfo.c b/contrib/libs/c-ares/ares_getnameinfo.c
index ca90788a70..53f91ca845 100644
--- a/contrib/libs/c-ares/ares_getnameinfo.c
+++ b/contrib/libs/c-ares/ares_getnameinfo.c
@@ -92,13 +92,13 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,
if ((sa->sa_family == AF_INET) &&
(salen == sizeof(struct sockaddr_in)))
{
- addr = CARES_INADDR_CAST(struct sockaddr_in *, sa);
+ addr = CARES_INADDR_CAST(struct sockaddr_in *, sa);
port = addr->sin_port;
}
else if ((sa->sa_family == AF_INET6) &&
(salen == sizeof(struct sockaddr_in6)))
{
- addr6 = CARES_INADDR_CAST(struct sockaddr_in6 *, sa);
+ addr6 = CARES_INADDR_CAST(struct sockaddr_in6 *, sa);
port = addr6->sin6_port;
}
else
diff --git a/contrib/libs/c-ares/ares_init.c b/contrib/libs/c-ares/ares_init.c
index efa6a4470d..e06265c6a2 100644
--- a/contrib/libs/c-ares/ares_init.c
+++ b/contrib/libs/c-ares/ares_init.c
@@ -1599,8 +1599,8 @@ static int init_by_resolv_conf(ares_channel channel)
* We'll only run this if we don't have any dns servers
* because this will get the same ones (if it works). */
if (status != ARES_EOF) {
- char propname[PROP_NAME_MAX];
- char propvalue[PROP_VALUE_MAX]="";
+ char propname[PROP_NAME_MAX];
+ char propvalue[PROP_VALUE_MAX]="";
for (i = 1; i <= MAX_DNS_PROPERTIES; i++) {
snprintf(propname, sizeof(propname), "%s%u", DNS_PROP_NAME_PREFIX, i);
if (__system_property_get(propname, propvalue) < 1) {
@@ -2038,7 +2038,7 @@ static int config_lookup(ares_channel channel, const char *str,
{
char lookups[3], *l;
const char *vqualifier p;
- int found;
+ int found;
if (altbindch == NULL)
altbindch = bindch;
@@ -2049,21 +2049,21 @@ static int config_lookup(ares_channel channel, const char *str,
*/
l = lookups;
p = str;
- found = 0;
+ found = 0;
while (*p)
{
if ((*p == *bindch || *p == *altbindch || *p == *filech) && l < lookups + 2) {
if (*p == *bindch || *p == *altbindch) *l++ = 'b';
else *l++ = 'f';
- found = 1;
+ found = 1;
}
while (*p && !ISSPACE(*p) && (*p != ','))
p++;
while (*p && (ISSPACE(*p) || (*p == ',')))
p++;
}
- if (!found)
- return ARES_ENOTINITIALIZED;
+ if (!found)
+ return ARES_ENOTINITIALIZED;
*l = '\0';
channel->lookups = ares_strdup(lookups);
return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
@@ -2311,7 +2311,7 @@ static int set_search(ares_channel channel, const char *str)
channel->ndomains = -1;
} /* LCOV_EXCL_STOP */
- channel->domains = ares_strsplit(str, ", ", 1, &cnt);
+ channel->domains = ares_strsplit(str, ", ", 1, &cnt);
channel->ndomains = (int)cnt;
if (channel->domains == NULL || channel->ndomains == 0) {
channel->domains = NULL;
@@ -2449,9 +2449,9 @@ static int ip_addr(const char *ipbuf, ares_ssize_t len, struct in_addr *addr)
if (len > 15)
return -1;
- if (ares_inet_pton(AF_INET, ipbuf, addr) < 1)
+ if (ares_inet_pton(AF_INET, ipbuf, addr) < 1)
return -1;
-
+
return 0;
}
diff --git a/contrib/libs/c-ares/ares_ipv6.h b/contrib/libs/c-ares/ares_ipv6.h
index 84622e2052..fdbc21fe8f 100644
--- a/contrib/libs/c-ares/ares_ipv6.h
+++ b/contrib/libs/c-ares/ares_ipv6.h
@@ -32,13 +32,13 @@ struct sockaddr_in6
};
#endif
-typedef union
-{
- struct sockaddr sa;
- struct sockaddr_in sa4;
- struct sockaddr_in6 sa6;
-} ares_sockaddr;
-
+typedef union
+{
+ struct sockaddr sa;
+ struct sockaddr_in sa4;
+ struct sockaddr_in6 sa6;
+} ares_sockaddr;
+
#ifndef HAVE_STRUCT_ADDRINFO
struct addrinfo
{
diff --git a/contrib/libs/c-ares/ares_parse_a_reply.c b/contrib/libs/c-ares/ares_parse_a_reply.c
index 0ede897bf0..d8a9e9b578 100644
--- a/contrib/libs/c-ares/ares_parse_a_reply.c
+++ b/contrib/libs/c-ares/ares_parse_a_reply.c
@@ -1,6 +1,6 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
- * Copyright (C) 2019 by Andrew Selivanov
+ * Copyright (C) 2019 by Andrew Selivanov
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
@@ -51,164 +51,164 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
struct hostent **host,
struct ares_addrttl *addrttls, int *naddrttls)
{
- struct ares_addrinfo ai;
- struct ares_addrinfo_node *next;
- struct ares_addrinfo_cname *next_cname;
- char **aliases = NULL;
- char *question_hostname = NULL;
- struct hostent *hostent = NULL;
- struct in_addr *addrs = NULL;
- int naliases = 0, naddrs = 0, alias = 0, i;
- int cname_ttl = INT_MAX;
- int status;
-
- memset(&ai, 0, sizeof(ai));
-
- status = ares__parse_into_addrinfo2(abuf, alen, &question_hostname, &ai);
- if (status != ARES_SUCCESS)
- {
- ares_free(question_hostname);
-
- if (naddrttls)
- {
- *naddrttls = 0;
- }
-
- return status;
- }
-
- hostent = ares_malloc(sizeof(struct hostent));
- if (!hostent)
+ struct ares_addrinfo ai;
+ struct ares_addrinfo_node *next;
+ struct ares_addrinfo_cname *next_cname;
+ char **aliases = NULL;
+ char *question_hostname = NULL;
+ struct hostent *hostent = NULL;
+ struct in_addr *addrs = NULL;
+ int naliases = 0, naddrs = 0, alias = 0, i;
+ int cname_ttl = INT_MAX;
+ int status;
+
+ memset(&ai, 0, sizeof(ai));
+
+ status = ares__parse_into_addrinfo2(abuf, alen, &question_hostname, &ai);
+ if (status != ARES_SUCCESS)
{
- goto enomem;
+ ares_free(question_hostname);
+
+ if (naddrttls)
+ {
+ *naddrttls = 0;
+ }
+
+ return status;
}
- next = ai.nodes;
- while (next)
+ hostent = ares_malloc(sizeof(struct hostent));
+ if (!hostent)
{
- if (next->ai_family == AF_INET)
+ goto enomem;
+ }
+
+ next = ai.nodes;
+ while (next)
+ {
+ if (next->ai_family == AF_INET)
{
- ++naddrs;
+ ++naddrs;
}
- next = next->ai_next;
+ next = next->ai_next;
}
-
- next_cname = ai.cnames;
- while (next_cname)
+
+ next_cname = ai.cnames;
+ while (next_cname)
{
- if(next_cname->alias)
- ++naliases;
- next_cname = next_cname->next;
+ if(next_cname->alias)
+ ++naliases;
+ next_cname = next_cname->next;
}
- aliases = ares_malloc((naliases + 1) * sizeof(char *));
- if (!aliases)
- {
- goto enomem;
- }
+ aliases = ares_malloc((naliases + 1) * sizeof(char *));
+ if (!aliases)
+ {
+ goto enomem;
+ }
- if (naliases)
+ if (naliases)
{
- next_cname = ai.cnames;
- while (next_cname)
+ next_cname = ai.cnames;
+ while (next_cname)
{
- if(next_cname->alias)
- aliases[alias++] = strdup(next_cname->alias);
- if(next_cname->ttl < cname_ttl)
- cname_ttl = next_cname->ttl;
- next_cname = next_cname->next;
+ if(next_cname->alias)
+ aliases[alias++] = strdup(next_cname->alias);
+ if(next_cname->ttl < cname_ttl)
+ cname_ttl = next_cname->ttl;
+ next_cname = next_cname->next;
}
- }
+ }
- aliases[alias] = NULL;
+ aliases[alias] = NULL;
- hostent->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *));
- if (!hostent->h_addr_list)
- {
- goto enomem;
- }
+ hostent->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *));
+ if (!hostent->h_addr_list)
+ {
+ goto enomem;
+ }
- for (i = 0; i < naddrs + 1; ++i)
- {
- hostent->h_addr_list[i] = NULL;
- }
+ for (i = 0; i < naddrs + 1; ++i)
+ {
+ hostent->h_addr_list[i] = NULL;
+ }
- if (ai.cnames)
- {
- hostent->h_name = strdup(ai.cnames->name);
- ares_free(question_hostname);
+ if (ai.cnames)
+ {
+ hostent->h_name = strdup(ai.cnames->name);
+ ares_free(question_hostname);
}
- else
- {
- hostent->h_name = question_hostname;
- }
-
- hostent->h_aliases = aliases;
- hostent->h_addrtype = AF_INET;
- hostent->h_length = sizeof(struct in_addr);
-
- if (naddrs)
+ else
{
- addrs = ares_malloc(naddrs * sizeof(struct in_addr));
- if (!addrs)
+ hostent->h_name = question_hostname;
+ }
+
+ hostent->h_aliases = aliases;
+ hostent->h_addrtype = AF_INET;
+ hostent->h_length = sizeof(struct in_addr);
+
+ if (naddrs)
+ {
+ addrs = ares_malloc(naddrs * sizeof(struct in_addr));
+ if (!addrs)
{
- goto enomem;
+ goto enomem;
}
-
- i = 0;
- next = ai.nodes;
- while (next)
+
+ i = 0;
+ next = ai.nodes;
+ while (next)
{
- if (next->ai_family == AF_INET)
+ if (next->ai_family == AF_INET)
{
- hostent->h_addr_list[i] = (char *)&addrs[i];
- memcpy(hostent->h_addr_list[i],
- &(CARES_INADDR_CAST(struct sockaddr_in *, next->ai_addr)->sin_addr),
- sizeof(struct in_addr));
- if (naddrttls && i < *naddrttls)
+ hostent->h_addr_list[i] = (char *)&addrs[i];
+ memcpy(hostent->h_addr_list[i],
+ &(CARES_INADDR_CAST(struct sockaddr_in *, next->ai_addr)->sin_addr),
+ sizeof(struct in_addr));
+ if (naddrttls && i < *naddrttls)
{
- if (next->ai_ttl > cname_ttl)
- addrttls[i].ttl = cname_ttl;
- else
- addrttls[i].ttl = next->ai_ttl;
-
- memcpy(&addrttls[i].ipaddr,
- &(CARES_INADDR_CAST(struct sockaddr_in *, next->ai_addr)->sin_addr),
- sizeof(struct in_addr));
+ if (next->ai_ttl > cname_ttl)
+ addrttls[i].ttl = cname_ttl;
+ else
+ addrttls[i].ttl = next->ai_ttl;
+
+ memcpy(&addrttls[i].ipaddr,
+ &(CARES_INADDR_CAST(struct sockaddr_in *, next->ai_addr)->sin_addr),
+ sizeof(struct in_addr));
}
- ++i;
+ ++i;
}
- next = next->ai_next;
+ next = next->ai_next;
+ }
+ if (i == 0)
+ {
+ ares_free(addrs);
}
- if (i == 0)
- {
- ares_free(addrs);
- }
- }
-
- if (host)
+ }
+
+ if (host)
+ {
+ *host = hostent;
+ }
+ else
{
- *host = hostent;
+ ares_free_hostent(hostent);
}
- else
- {
- ares_free_hostent(hostent);
- }
-
- if (naddrttls)
- {
- *naddrttls = naddrs;
- }
-
- ares__freeaddrinfo_cnames(ai.cnames);
- ares__freeaddrinfo_nodes(ai.nodes);
- return ARES_SUCCESS;
-
-enomem:
- ares_free(aliases);
- ares_free(hostent);
- ares__freeaddrinfo_cnames(ai.cnames);
- ares__freeaddrinfo_nodes(ai.nodes);
- ares_free(question_hostname);
- return ARES_ENOMEM;
+
+ if (naddrttls)
+ {
+ *naddrttls = naddrs;
+ }
+
+ ares__freeaddrinfo_cnames(ai.cnames);
+ ares__freeaddrinfo_nodes(ai.nodes);
+ return ARES_SUCCESS;
+
+enomem:
+ ares_free(aliases);
+ ares_free(hostent);
+ ares__freeaddrinfo_cnames(ai.cnames);
+ ares__freeaddrinfo_nodes(ai.nodes);
+ ares_free(question_hostname);
+ return ARES_ENOMEM;
}
diff --git a/contrib/libs/c-ares/ares_parse_aaaa_reply.c b/contrib/libs/c-ares/ares_parse_aaaa_reply.c
index 7d30f57372..0d39bfa826 100644
--- a/contrib/libs/c-ares/ares_parse_aaaa_reply.c
+++ b/contrib/libs/c-ares/ares_parse_aaaa_reply.c
@@ -1,7 +1,7 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
* Copyright 2005 Dominick Meglio
- * Copyright (C) 2019 by Andrew Selivanov
+ * Copyright (C) 2019 by Andrew Selivanov
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
@@ -53,165 +53,165 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
struct hostent **host, struct ares_addr6ttl *addrttls,
int *naddrttls)
{
- struct ares_addrinfo ai;
- struct ares_addrinfo_node *next;
- struct ares_addrinfo_cname *next_cname;
- char **aliases = NULL;
- char *question_hostname = NULL;
- struct hostent *hostent = NULL;
- struct ares_in6_addr *addrs = NULL;
- int naliases = 0, naddrs = 0, alias = 0, i;
- int cname_ttl = INT_MAX;
- int status;
-
- memset(&ai, 0, sizeof(ai));
-
- status = ares__parse_into_addrinfo2(abuf, alen, &question_hostname, &ai);
- if (status != ARES_SUCCESS)
- {
- ares_free(question_hostname);
-
- if (naddrttls)
- {
- *naddrttls = 0;
- }
-
- return status;
- }
-
- hostent = ares_malloc(sizeof(struct hostent));
- if (!hostent)
+ struct ares_addrinfo ai;
+ struct ares_addrinfo_node *next;
+ struct ares_addrinfo_cname *next_cname;
+ char **aliases = NULL;
+ char *question_hostname = NULL;
+ struct hostent *hostent = NULL;
+ struct ares_in6_addr *addrs = NULL;
+ int naliases = 0, naddrs = 0, alias = 0, i;
+ int cname_ttl = INT_MAX;
+ int status;
+
+ memset(&ai, 0, sizeof(ai));
+
+ status = ares__parse_into_addrinfo2(abuf, alen, &question_hostname, &ai);
+ if (status != ARES_SUCCESS)
{
- goto enomem;
+ ares_free(question_hostname);
+
+ if (naddrttls)
+ {
+ *naddrttls = 0;
+ }
+
+ return status;
}
- next = ai.nodes;
- while (next)
+ hostent = ares_malloc(sizeof(struct hostent));
+ if (!hostent)
{
- if(next->ai_family == AF_INET6)
+ goto enomem;
+ }
+
+ next = ai.nodes;
+ while (next)
+ {
+ if(next->ai_family == AF_INET6)
{
- ++naddrs;
+ ++naddrs;
}
- next = next->ai_next;
+ next = next->ai_next;
}
-
- next_cname = ai.cnames;
- while (next_cname)
+
+ next_cname = ai.cnames;
+ while (next_cname)
{
- if(next_cname->alias)
- ++naliases;
- next_cname = next_cname->next;
+ if(next_cname->alias)
+ ++naliases;
+ next_cname = next_cname->next;
}
- aliases = ares_malloc((naliases + 1) * sizeof(char *));
- if (!aliases)
+ aliases = ares_malloc((naliases + 1) * sizeof(char *));
+ if (!aliases)
{
- goto enomem;
- }
+ goto enomem;
+ }
- if (naliases)
- {
- next_cname = ai.cnames;
- while (next_cname)
+ if (naliases)
+ {
+ next_cname = ai.cnames;
+ while (next_cname)
{
- if(next_cname->alias)
- aliases[alias++] = strdup(next_cname->alias);
- if(next_cname->ttl < cname_ttl)
- cname_ttl = next_cname->ttl;
- next_cname = next_cname->next;
+ if(next_cname->alias)
+ aliases[alias++] = strdup(next_cname->alias);
+ if(next_cname->ttl < cname_ttl)
+ cname_ttl = next_cname->ttl;
+ next_cname = next_cname->next;
}
- }
+ }
- aliases[alias] = NULL;
+ aliases[alias] = NULL;
- hostent->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *));
- if (!hostent->h_addr_list)
- {
- goto enomem;
- }
+ hostent->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *));
+ if (!hostent->h_addr_list)
+ {
+ goto enomem;
+ }
- for (i = 0; i < naddrs + 1; ++i)
- {
- hostent->h_addr_list[i] = NULL;
- }
+ for (i = 0; i < naddrs + 1; ++i)
+ {
+ hostent->h_addr_list[i] = NULL;
+ }
- if (ai.cnames)
- {
- hostent->h_name = strdup(ai.cnames->name);
- ares_free(question_hostname);
+ if (ai.cnames)
+ {
+ hostent->h_name = strdup(ai.cnames->name);
+ ares_free(question_hostname);
}
- else
- {
- hostent->h_name = question_hostname;
- }
-
- hostent->h_aliases = aliases;
- hostent->h_addrtype = AF_INET6;
- hostent->h_length = sizeof(struct ares_in6_addr);
-
- if (naddrs)
+ else
{
- addrs = ares_malloc(naddrs * sizeof(struct ares_in6_addr));
- if (!addrs)
+ hostent->h_name = question_hostname;
+ }
+
+ hostent->h_aliases = aliases;
+ hostent->h_addrtype = AF_INET6;
+ hostent->h_length = sizeof(struct ares_in6_addr);
+
+ if (naddrs)
+ {
+ addrs = ares_malloc(naddrs * sizeof(struct ares_in6_addr));
+ if (!addrs)
{
- goto enomem;
+ goto enomem;
}
-
- i = 0;
- next = ai.nodes;
- while (next)
+
+ i = 0;
+ next = ai.nodes;
+ while (next)
{
- if(next->ai_family == AF_INET6)
+ if(next->ai_family == AF_INET6)
{
- hostent->h_addr_list[i] = (char*)&addrs[i];
- memcpy(hostent->h_addr_list[i],
- &(CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr)->sin6_addr),
- sizeof(struct ares_in6_addr));
- if (naddrttls && i < *naddrttls)
+ hostent->h_addr_list[i] = (char*)&addrs[i];
+ memcpy(hostent->h_addr_list[i],
+ &(CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr)->sin6_addr),
+ sizeof(struct ares_in6_addr));
+ if (naddrttls && i < *naddrttls)
{
- if(next->ai_ttl > cname_ttl)
- addrttls[i].ttl = cname_ttl;
- else
- addrttls[i].ttl = next->ai_ttl;
-
- memcpy(&addrttls[i].ip6addr,
- &(CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr)->sin6_addr),
- sizeof(struct ares_in6_addr));
+ if(next->ai_ttl > cname_ttl)
+ addrttls[i].ttl = cname_ttl;
+ else
+ addrttls[i].ttl = next->ai_ttl;
+
+ memcpy(&addrttls[i].ip6addr,
+ &(CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr)->sin6_addr),
+ sizeof(struct ares_in6_addr));
}
- ++i;
+ ++i;
}
- next = next->ai_next;
+ next = next->ai_next;
+ }
+
+ if (i == 0)
+ {
+ ares_free(addrs);
}
-
- if (i == 0)
- {
- ares_free(addrs);
- }
}
-
- if (host)
+
+ if (host)
+ {
+ *host = hostent;
+ }
+ else
{
- *host = hostent;
+ ares_free_hostent(hostent);
}
- else
- {
- ares_free_hostent(hostent);
- }
-
- if (naddrttls)
- {
- *naddrttls = naddrs;
- }
-
- ares__freeaddrinfo_cnames(ai.cnames);
- ares__freeaddrinfo_nodes(ai.nodes);
- return ARES_SUCCESS;
-
-enomem:
- ares_free(aliases);
- ares_free(hostent);
- ares__freeaddrinfo_cnames(ai.cnames);
- ares__freeaddrinfo_nodes(ai.nodes);
- ares_free(question_hostname);
- return ARES_ENOMEM;
+
+ if (naddrttls)
+ {
+ *naddrttls = naddrs;
+ }
+
+ ares__freeaddrinfo_cnames(ai.cnames);
+ ares__freeaddrinfo_nodes(ai.nodes);
+ return ARES_SUCCESS;
+
+enomem:
+ ares_free(aliases);
+ ares_free(hostent);
+ ares__freeaddrinfo_cnames(ai.cnames);
+ ares__freeaddrinfo_nodes(ai.nodes);
+ ares_free(question_hostname);
+ return ARES_ENOMEM;
}
diff --git a/contrib/libs/c-ares/ares_parse_soa_reply.c b/contrib/libs/c-ares/ares_parse_soa_reply.c
index 473b3542a8..8b84a368db 100644
--- a/contrib/libs/c-ares/ares_parse_soa_reply.c
+++ b/contrib/libs/c-ares/ares_parse_soa_reply.c
@@ -48,8 +48,8 @@ ares_parse_soa_reply(const unsigned char *abuf, int alen,
long len;
char *qname = NULL, *rr_name = NULL;
struct ares_soa_reply *soa = NULL;
- int qdcount, ancount, qclass;
- int status, i, rr_type, rr_class, rr_len;
+ int qdcount, ancount, qclass;
+ int status, i, rr_type, rr_class, rr_len;
int ttl;
if (alen < HFIXEDSZ)
@@ -58,12 +58,12 @@ ares_parse_soa_reply(const unsigned char *abuf, int alen,
/* parse message header */
qdcount = DNS_HEADER_QDCOUNT(abuf);
ancount = DNS_HEADER_ANCOUNT(abuf);
-
- if (qdcount != 1)
+
+ if (qdcount != 1)
+ return ARES_EBADRESP;
+ if (ancount == 0)
return ARES_EBADRESP;
- if (ancount == 0)
- return ARES_EBADRESP;
-
+
aptr = abuf + HFIXEDSZ;
/* query name */
@@ -72,113 +72,113 @@ ares_parse_soa_reply(const unsigned char *abuf, int alen,
goto failed_stat;
aptr += len;
- qclass = DNS_QUESTION_TYPE(aptr);
-
+ qclass = DNS_QUESTION_TYPE(aptr);
+
/* skip qtype & qclass */
if (aptr + QFIXEDSZ > abuf + alen)
goto failed;
aptr += QFIXEDSZ;
- /* qclass of SOA with multiple answers */
- if (qclass == T_SOA && ancount > 1)
+ /* qclass of SOA with multiple answers */
+ if (qclass == T_SOA && ancount > 1)
goto failed;
- /* examine all the records, break and return if found soa */
- for (i = 0; i < ancount; i++)
- {
- rr_name = NULL;
- status = ares__expand_name_for_response (aptr, abuf, alen, &rr_name, &len);
- if (status != ARES_SUCCESS)
- {
- ares_free(rr_name);
- goto failed_stat;
- }
-
- aptr += len;
- if ( aptr + RRFIXEDSZ > abuf + alen )
+ /* examine all the records, break and return if found soa */
+ for (i = 0; i < ancount; i++)
+ {
+ rr_name = NULL;
+ status = ares__expand_name_for_response (aptr, abuf, alen, &rr_name, &len);
+ if (status != ARES_SUCCESS)
+ {
+ ares_free(rr_name);
+ goto failed_stat;
+ }
+
+ aptr += len;
+ if ( aptr + RRFIXEDSZ > abuf + alen )
{
- ares_free(rr_name);
- status = ARES_EBADRESP;
+ ares_free(rr_name);
+ status = ARES_EBADRESP;
goto failed_stat;
}
- rr_type = DNS_RR_TYPE( aptr );
- rr_class = DNS_RR_CLASS( aptr );
- rr_len = DNS_RR_LEN( aptr );
- ttl = DNS_RR_TTL(aptr);
- aptr += RRFIXEDSZ;
- if (aptr + rr_len > abuf + alen)
- {
- ares_free(rr_name);
- status = ARES_EBADRESP;
- goto failed_stat;
- }
- if ( rr_class == C_IN && rr_type == T_SOA )
- {
- /* allocate result struct */
- soa = ares_malloc_data(ARES_DATATYPE_SOA_REPLY);
- if (!soa)
- {
- ares_free(rr_name);
- status = ARES_ENOMEM;
- goto failed_stat;
- }
-
- /* nsname */
- status = ares__expand_name_for_response(aptr, abuf, alen, &soa->nsname,
- &len);
- if (status != ARES_SUCCESS)
- {
- ares_free(rr_name);
- goto failed_stat;
- }
- aptr += len;
-
- /* hostmaster */
- status = ares__expand_name_for_response(aptr, abuf, alen,
- &soa->hostmaster, &len);
- if (status != ARES_SUCCESS)
- {
- ares_free(rr_name);
- goto failed_stat;
- }
- aptr += len;
-
- /* integer fields */
- if (aptr + 5 * 4 > abuf + alen)
- {
- ares_free(rr_name);
- goto failed;
- }
- soa->serial = DNS__32BIT(aptr + 0 * 4);
- soa->refresh = DNS__32BIT(aptr + 1 * 4);
- soa->retry = DNS__32BIT(aptr + 2 * 4);
- soa->expire = DNS__32BIT(aptr + 3 * 4);
- soa->minttl = DNS__32BIT(aptr + 4 * 4);
- soa->ttl = ttl;
-
- ares_free(qname);
- ares_free(rr_name);
-
- *soa_out = soa;
-
- return ARES_SUCCESS;
- }
- aptr += rr_len;
-
- ares_free(rr_name);
-
- if (aptr > abuf + alen)
- goto failed_stat;
- }
- /* no SOA record found */
- status = ARES_EBADRESP;
- goto failed_stat;
+ rr_type = DNS_RR_TYPE( aptr );
+ rr_class = DNS_RR_CLASS( aptr );
+ rr_len = DNS_RR_LEN( aptr );
+ ttl = DNS_RR_TTL(aptr);
+ aptr += RRFIXEDSZ;
+ if (aptr + rr_len > abuf + alen)
+ {
+ ares_free(rr_name);
+ status = ARES_EBADRESP;
+ goto failed_stat;
+ }
+ if ( rr_class == C_IN && rr_type == T_SOA )
+ {
+ /* allocate result struct */
+ soa = ares_malloc_data(ARES_DATATYPE_SOA_REPLY);
+ if (!soa)
+ {
+ ares_free(rr_name);
+ status = ARES_ENOMEM;
+ goto failed_stat;
+ }
+
+ /* nsname */
+ status = ares__expand_name_for_response(aptr, abuf, alen, &soa->nsname,
+ &len);
+ if (status != ARES_SUCCESS)
+ {
+ ares_free(rr_name);
+ goto failed_stat;
+ }
+ aptr += len;
+
+ /* hostmaster */
+ status = ares__expand_name_for_response(aptr, abuf, alen,
+ &soa->hostmaster, &len);
+ if (status != ARES_SUCCESS)
+ {
+ ares_free(rr_name);
+ goto failed_stat;
+ }
+ aptr += len;
+
+ /* integer fields */
+ if (aptr + 5 * 4 > abuf + alen)
+ {
+ ares_free(rr_name);
+ goto failed;
+ }
+ soa->serial = DNS__32BIT(aptr + 0 * 4);
+ soa->refresh = DNS__32BIT(aptr + 1 * 4);
+ soa->retry = DNS__32BIT(aptr + 2 * 4);
+ soa->expire = DNS__32BIT(aptr + 3 * 4);
+ soa->minttl = DNS__32BIT(aptr + 4 * 4);
+ soa->ttl = ttl;
+
+ ares_free(qname);
+ ares_free(rr_name);
+
+ *soa_out = soa;
+
+ return ARES_SUCCESS;
+ }
+ aptr += rr_len;
+
+ ares_free(rr_name);
+
+ if (aptr > abuf + alen)
+ goto failed_stat;
+ }
+ /* no SOA record found */
+ status = ARES_EBADRESP;
+ goto failed_stat;
failed:
status = ARES_EBADRESP;
failed_stat:
- if (soa)
- ares_free_data(soa);
+ if (soa)
+ ares_free_data(soa);
if (qname)
ares_free(qname);
return status;
diff --git a/contrib/libs/c-ares/ares_parse_txt_reply.c b/contrib/libs/c-ares/ares_parse_txt_reply.c
index ef7a1da7fe..c685dfd052 100644
--- a/contrib/libs/c-ares/ares_parse_txt_reply.c
+++ b/contrib/libs/c-ares/ares_parse_txt_reply.c
@@ -114,7 +114,7 @@ ares__parse_txt_reply (const unsigned char *abuf, int alen,
}
/* Check if we are really looking at a TXT record */
- if ((rr_class == C_IN || rr_class == C_CHAOS) && rr_type == T_TXT)
+ if ((rr_class == C_IN || rr_class == C_CHAOS) && rr_type == T_TXT)
{
/*
* There may be multiple substrings in a single TXT record. Each
diff --git a/contrib/libs/c-ares/ares_private.h b/contrib/libs/c-ares/ares_private.h
index e34c1d5ce9..3312ed1932 100644
--- a/contrib/libs/c-ares/ares_private.h
+++ b/contrib/libs/c-ares/ares_private.h
@@ -50,11 +50,11 @@
#define STATIC_TESTABLE static
#endif
-/* By using a double cast, we can get rid of the bogus warning of
- * warning: cast from 'const struct sockaddr *' to 'const struct sockaddr_in6 *' increases required alignment from 1 to 4 [-Wcast-align]
- */
-#define CARES_INADDR_CAST(type, var) ((type)((void *)var))
-
+/* By using a double cast, we can get rid of the bogus warning of
+ * warning: cast from 'const struct sockaddr *' to 'const struct sockaddr_in6 *' increases required alignment from 1 to 4 [-Wcast-align]
+ */
+#define CARES_INADDR_CAST(type, var) ((type)((void *)var))
+
#if defined(WIN32) && !defined(WATT32)
#define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP"
@@ -363,51 +363,51 @@ int ares__expand_name_for_response(const unsigned char *encoded,
char **s, long *enclen);
void ares__init_servers_state(ares_channel channel);
void ares__destroy_servers_state(ares_channel channel);
-int ares__parse_qtype_reply(const unsigned char* abuf, int alen, int* qtype);
-int ares__single_domain(ares_channel channel, const char *name, char **s);
-int ares__cat_domain(const char *name, const char *domain, char **s);
-int ares__sortaddrinfo(ares_channel channel, struct ares_addrinfo_node *ai_node);
-int ares__readaddrinfo(FILE *fp, const char *name, unsigned short port,
- const struct ares_addrinfo_hints *hints,
- struct ares_addrinfo *ai);
-
-struct ares_addrinfo *ares__malloc_addrinfo(void);
-
-struct ares_addrinfo_node *ares__malloc_addrinfo_node(void);
-void ares__freeaddrinfo_nodes(struct ares_addrinfo_node *ai_node);
-
-struct ares_addrinfo_node *ares__append_addrinfo_node(struct ares_addrinfo_node **ai_node);
-void ares__addrinfo_cat_nodes(struct ares_addrinfo_node **head,
- struct ares_addrinfo_node *tail);
-
-struct ares_addrinfo_cname *ares__malloc_addrinfo_cname(void);
-void ares__freeaddrinfo_cnames(struct ares_addrinfo_cname *ai_cname);
-
-struct ares_addrinfo_cname *ares__append_addrinfo_cname(struct ares_addrinfo_cname **ai_cname);
-
-void ares__addrinfo_cat_cnames(struct ares_addrinfo_cname **head,
- struct ares_addrinfo_cname *tail);
-
-int ares__parse_into_addrinfo(const unsigned char *abuf,
- int alen,
- struct ares_addrinfo *ai);
-
-int ares__parse_into_addrinfo2(const unsigned char *abuf,
- int alen,
- char **question_hostname,
- struct ares_addrinfo *ai);
-
+int ares__parse_qtype_reply(const unsigned char* abuf, int alen, int* qtype);
+int ares__single_domain(ares_channel channel, const char *name, char **s);
+int ares__cat_domain(const char *name, const char *domain, char **s);
+int ares__sortaddrinfo(ares_channel channel, struct ares_addrinfo_node *ai_node);
+int ares__readaddrinfo(FILE *fp, const char *name, unsigned short port,
+ const struct ares_addrinfo_hints *hints,
+ struct ares_addrinfo *ai);
+
+struct ares_addrinfo *ares__malloc_addrinfo(void);
+
+struct ares_addrinfo_node *ares__malloc_addrinfo_node(void);
+void ares__freeaddrinfo_nodes(struct ares_addrinfo_node *ai_node);
+
+struct ares_addrinfo_node *ares__append_addrinfo_node(struct ares_addrinfo_node **ai_node);
+void ares__addrinfo_cat_nodes(struct ares_addrinfo_node **head,
+ struct ares_addrinfo_node *tail);
+
+struct ares_addrinfo_cname *ares__malloc_addrinfo_cname(void);
+void ares__freeaddrinfo_cnames(struct ares_addrinfo_cname *ai_cname);
+
+struct ares_addrinfo_cname *ares__append_addrinfo_cname(struct ares_addrinfo_cname **ai_cname);
+
+void ares__addrinfo_cat_cnames(struct ares_addrinfo_cname **head,
+ struct ares_addrinfo_cname *tail);
+
+int ares__parse_into_addrinfo(const unsigned char *abuf,
+ int alen,
+ struct ares_addrinfo *ai);
+
+int ares__parse_into_addrinfo2(const unsigned char *abuf,
+ int alen,
+ char **question_hostname,
+ struct ares_addrinfo *ai);
+
#if 0 /* Not used */
long ares__tvdiff(struct timeval t1, struct timeval t2);
#endif
-ares_socket_t ares__open_socket(ares_channel channel,
- int af, int type, int protocol);
-void ares__close_socket(ares_channel, ares_socket_t);
-int ares__connect_socket(ares_channel channel,
- ares_socket_t sockfd,
- const struct sockaddr *addr,
- ares_socklen_t addrlen);
+ares_socket_t ares__open_socket(ares_channel channel,
+ int af, int type, int protocol);
+void ares__close_socket(ares_channel, ares_socket_t);
+int ares__connect_socket(ares_channel channel,
+ ares_socket_t sockfd,
+ const struct sockaddr *addr,
+ ares_socklen_t addrlen);
#define ARES_SWAP_BYTE(a,b) \
{ unsigned char swapByte = *(a); *(a) = *(b); *(b) = swapByte; }
diff --git a/contrib/libs/c-ares/ares_process.c b/contrib/libs/c-ares/ares_process.c
index 0795f5b4c4..25095d0f05 100644
--- a/contrib/libs/c-ares/ares_process.c
+++ b/contrib/libs/c-ares/ares_process.c
@@ -1104,14 +1104,14 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
}
/* Acquire a socket. */
- s = ares__open_socket(channel, server->addr.family, SOCK_STREAM, 0);
+ s = ares__open_socket(channel, server->addr.family, SOCK_STREAM, 0);
if (s == ARES_SOCKET_BAD)
return -1;
/* Configure it. */
if (configure_socket(s, server->addr.family, channel) < 0)
{
- ares__close_socket(channel, s);
+ ares__close_socket(channel, s);
return -1;
}
@@ -1128,7 +1128,7 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
(void *)&opt, sizeof(opt)) == -1)
{
- ares__close_socket(channel, s);
+ ares__close_socket(channel, s);
return -1;
}
#endif
@@ -1139,19 +1139,19 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
channel->sock_config_cb_data);
if (err < 0)
{
- ares__close_socket(channel, s);
+ ares__close_socket(channel, s);
return err;
}
}
/* Connect to the server. */
- if (ares__connect_socket(channel, s, sa, salen) == -1)
+ if (ares__connect_socket(channel, s, sa, salen) == -1)
{
int err = SOCKERRNO;
if (err != EINPROGRESS && err != EWOULDBLOCK)
{
- ares__close_socket(channel, s);
+ ares__close_socket(channel, s);
return -1;
}
}
@@ -1162,7 +1162,7 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
channel->sock_create_cb_data);
if (err < 0)
{
- ares__close_socket(channel, s);
+ ares__close_socket(channel, s);
return err;
}
}
@@ -1217,14 +1217,14 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
}
/* Acquire a socket. */
- s = ares__open_socket(channel, server->addr.family, SOCK_DGRAM, 0);
+ s = ares__open_socket(channel, server->addr.family, SOCK_DGRAM, 0);
if (s == ARES_SOCKET_BAD)
return -1;
/* Set the socket non-blocking. */
if (configure_socket(s, server->addr.family, channel) < 0)
{
- ares__close_socket(channel, s);
+ ares__close_socket(channel, s);
return -1;
}
@@ -1234,19 +1234,19 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
channel->sock_config_cb_data);
if (err < 0)
{
- ares__close_socket(channel, s);
+ ares__close_socket(channel, s);
return err;
}
}
/* Connect to the server. */
- if (ares__connect_socket(channel, s, sa, salen) == -1)
+ if (ares__connect_socket(channel, s, sa, salen) == -1)
{
int err = SOCKERRNO;
if (err != EINPROGRESS && err != EWOULDBLOCK)
{
- ares__close_socket(channel, s);
+ ares__close_socket(channel, s);
return -1;
}
}
@@ -1257,7 +1257,7 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
channel->sock_create_cb_data);
if (err < 0)
{
- ares__close_socket(channel, s);
+ ares__close_socket(channel, s);
return err;
}
}
@@ -1358,13 +1358,13 @@ static int same_address(struct sockaddr *sa, struct ares_addr *aa)
{
case AF_INET:
addr1 = &aa->addrV4;
- addr2 = &(CARES_INADDR_CAST(struct sockaddr_in *, sa))->sin_addr;
+ addr2 = &(CARES_INADDR_CAST(struct sockaddr_in *, sa))->sin_addr;
if (memcmp(addr1, addr2, sizeof(aa->addrV4)) == 0)
return 1; /* match */
break;
case AF_INET6:
addr1 = &aa->addrV6;
- addr2 = &(CARES_INADDR_CAST(struct sockaddr_in6 *, sa))->sin6_addr;
+ addr2 = &(CARES_INADDR_CAST(struct sockaddr_in6 *, sa))->sin6_addr;
if (memcmp(addr1, addr2, sizeof(aa->addrV6)) == 0)
return 1; /* match */
break;
@@ -1461,35 +1461,35 @@ void ares__free_query(struct query *query)
ares_free(query);
}
-ares_socket_t ares__open_socket(ares_channel channel,
- int af, int type, int protocol)
+ares_socket_t ares__open_socket(ares_channel channel,
+ int af, int type, int protocol)
+{
+ if (channel->sock_funcs)
+ return channel->sock_funcs->asocket(af,
+ type,
+ protocol,
+ channel->sock_func_cb_data);
+ else
+ return socket(af, type, protocol);
+}
+
+int ares__connect_socket(ares_channel channel,
+ ares_socket_t sockfd,
+ const struct sockaddr *addr,
+ ares_socklen_t addrlen)
+{
+ if (channel->sock_funcs)
+ return channel->sock_funcs->aconnect(sockfd,
+ addr,
+ addrlen,
+ channel->sock_func_cb_data);
+ else
+ return connect(sockfd, addr, addrlen);
+}
+
+void ares__close_socket(ares_channel channel, ares_socket_t s)
{
if (channel->sock_funcs)
- return channel->sock_funcs->asocket(af,
- type,
- protocol,
- channel->sock_func_cb_data);
- else
- return socket(af, type, protocol);
-}
-
-int ares__connect_socket(ares_channel channel,
- ares_socket_t sockfd,
- const struct sockaddr *addr,
- ares_socklen_t addrlen)
-{
- if (channel->sock_funcs)
- return channel->sock_funcs->aconnect(sockfd,
- addr,
- addrlen,
- channel->sock_func_cb_data);
- else
- return connect(sockfd, addr, addrlen);
-}
-
-void ares__close_socket(ares_channel channel, ares_socket_t s)
-{
- if (channel->sock_funcs)
channel->sock_funcs->aclose(s, channel->sock_func_cb_data);
else
sclose(s);
diff --git a/contrib/libs/c-ares/ares_search.c b/contrib/libs/c-ares/ares_search.c
index f33e77f92b..c4b0424f5b 100644
--- a/contrib/libs/c-ares/ares_search.c
+++ b/contrib/libs/c-ares/ares_search.c
@@ -62,7 +62,7 @@ void ares_search(ares_channel channel, const char *name, int dnsclass,
/* If name only yields one domain to search, then we don't have
* to keep extra state, so just do an ares_query().
*/
- status = ares__single_domain(channel, name, &s);
+ status = ares__single_domain(channel, name, &s);
if (status != ARES_SUCCESS)
{
callback(arg, status, 0, NULL, 0);
@@ -124,7 +124,7 @@ void ares_search(ares_channel channel, const char *name, int dnsclass,
/* Try the name as-is last; start with the first search domain. */
squery->next_domain = 1;
squery->trying_as_is = 0;
- status = ares__cat_domain(name, channel->domains[0], &s);
+ status = ares__cat_domain(name, channel->domains[0], &s);
if (status == ARES_SUCCESS)
{
ares_query(channel, s, dnsclass, type, search_callback, squery);
@@ -172,7 +172,7 @@ static void search_callback(void *arg, int status, int timeouts,
if (squery->next_domain < channel->ndomains)
{
/* Try the next domain. */
- status = ares__cat_domain(squery->name,
+ status = ares__cat_domain(squery->name,
channel->domains[squery->next_domain], &s);
if (status != ARES_SUCCESS)
end_squery(squery, status, NULL, 0);
@@ -211,7 +211,7 @@ static void end_squery(struct search_query *squery, int status,
}
/* Concatenate two domains. */
-int ares__cat_domain(const char *name, const char *domain, char **s)
+int ares__cat_domain(const char *name, const char *domain, char **s)
{
size_t nlen = strlen(name);
size_t dlen = strlen(domain);
@@ -230,7 +230,7 @@ int ares__cat_domain(const char *name, const char *domain, char **s)
* the string we should query, in an allocated buffer. If not, set *s
* to NULL.
*/
-int ares__single_domain(ares_channel channel, const char *name, char **s)
+int ares__single_domain(ares_channel channel, const char *name, char **s)
{
size_t len = strlen(name);
const char *hostaliases;
diff --git a/contrib/libs/c-ares/ares_version.h b/contrib/libs/c-ares/ares_version.h
index 1a3871c12b..c041d574de 100644
--- a/contrib/libs/c-ares/ares_version.h
+++ b/contrib/libs/c-ares/ares_version.h
@@ -3,15 +3,15 @@
#define ARES__VERSION_H
/* This is the global package copyright */
-#define ARES_COPYRIGHT "2004 - 2020 Daniel Stenberg, <daniel@haxx.se>."
+#define ARES_COPYRIGHT "2004 - 2020 Daniel Stenberg, <daniel@haxx.se>."
#define ARES_VERSION_MAJOR 1
-#define ARES_VERSION_MINOR 16
-#define ARES_VERSION_PATCH 1
+#define ARES_VERSION_MINOR 16
+#define ARES_VERSION_PATCH 1
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
(ARES_VERSION_MINOR<<8)|\
(ARES_VERSION_PATCH))
-#define ARES_VERSION_STR "1.16.1"
+#define ARES_VERSION_STR "1.16.1"
#if (ARES_VERSION >= 0x010700)
# define CARES_HAVE_ARES_LIBRARY_INIT 1
diff --git a/contrib/libs/c-ares/test/ares-test-ai.h b/contrib/libs/c-ares/test/ares-test-ai.h
index 22555d4e8c..7cf27e3306 100644
--- a/contrib/libs/c-ares/test/ares-test-ai.h
+++ b/contrib/libs/c-ares/test/ares-test-ai.h
@@ -1,57 +1,57 @@
-#ifndef ARES_TEST_AI_H
-#define ARES_TEST_AI_H
-
-#include <utility>
-#include "gtest/gtest.h"
-#include "gmock/gmock.h"
-#include "ares-test.h"
-
-namespace ares {
-namespace test {
-
-class MockChannelTestAI
- : public MockChannelOptsTest,
- public ::testing::WithParamInterface< std::pair<int, bool> > {
- public:
- MockChannelTestAI() : MockChannelOptsTest(1, GetParam().first, GetParam().second, nullptr, 0) {}
-};
-
-class MockUDPChannelTestAI
- : public MockChannelOptsTest,
- public ::testing::WithParamInterface<int> {
- public:
- MockUDPChannelTestAI() : MockChannelOptsTest(1, GetParam(), false, nullptr, 0) {}
-};
-
-class MockTCPChannelTestAI
- : public MockChannelOptsTest,
- public ::testing::WithParamInterface<int> {
- public:
- MockTCPChannelTestAI() : MockChannelOptsTest(1, GetParam(), true, nullptr, 0) {}
-};
-
-
-// Test fixture that uses a default channel.
-class DefaultChannelTestAI : public LibraryTest {
- public:
- DefaultChannelTestAI() : channel_(nullptr) {
- EXPECT_EQ(ARES_SUCCESS, ares_init(&channel_));
- EXPECT_NE(nullptr, channel_);
- }
-
- ~DefaultChannelTestAI() {
- ares_destroy(channel_);
- channel_ = nullptr;
- }
-
- // Process all pending work on ares-owned file descriptors.
- void Process();
-
- protected:
- ares_channel channel_;
-};
-
-}
-}
-
-#endif
+#ifndef ARES_TEST_AI_H
+#define ARES_TEST_AI_H
+
+#include <utility>
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include "ares-test.h"
+
+namespace ares {
+namespace test {
+
+class MockChannelTestAI
+ : public MockChannelOptsTest,
+ public ::testing::WithParamInterface< std::pair<int, bool> > {
+ public:
+ MockChannelTestAI() : MockChannelOptsTest(1, GetParam().first, GetParam().second, nullptr, 0) {}
+};
+
+class MockUDPChannelTestAI
+ : public MockChannelOptsTest,
+ public ::testing::WithParamInterface<int> {
+ public:
+ MockUDPChannelTestAI() : MockChannelOptsTest(1, GetParam(), false, nullptr, 0) {}
+};
+
+class MockTCPChannelTestAI
+ : public MockChannelOptsTest,
+ public ::testing::WithParamInterface<int> {
+ public:
+ MockTCPChannelTestAI() : MockChannelOptsTest(1, GetParam(), true, nullptr, 0) {}
+};
+
+
+// Test fixture that uses a default channel.
+class DefaultChannelTestAI : public LibraryTest {
+ public:
+ DefaultChannelTestAI() : channel_(nullptr) {
+ EXPECT_EQ(ARES_SUCCESS, ares_init(&channel_));
+ EXPECT_NE(nullptr, channel_);
+ }
+
+ ~DefaultChannelTestAI() {
+ ares_destroy(channel_);
+ channel_ = nullptr;
+ }
+
+ // Process all pending work on ares-owned file descriptors.
+ void Process();
+
+ protected:
+ ares_channel channel_;
+};
+
+}
+}
+
+#endif
diff --git a/contrib/libs/c-ares/test/ares-test-init.cc b/contrib/libs/c-ares/test/ares-test-init.cc
index 58fa02d48c..842b0e15ac 100644
--- a/contrib/libs/c-ares/test/ares-test-init.cc
+++ b/contrib/libs/c-ares/test/ares-test-init.cc
@@ -495,24 +495,24 @@ CONTAINED_TEST_F(LibraryTest, ContainerSvcConfInit,
return HasFailure();
}
-NameContentList malformedresolvconflookup = {
- {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
- "lookup garbage\n"}}; // malformed line
-CONTAINED_TEST_F(LibraryTest, ContainerMalformedResolvConfLookup,
- "myhostname", "mydomainname.org", malformedresolvconflookup) {
- ares_channel channel = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
-
- struct ares_options opts;
- int optmask = 0;
- ares_save_options(channel, &opts, &optmask);
- EXPECT_EQ(std::string("fb"), std::string(opts.lookups));
- ares_destroy_options(&opts);
-
- ares_destroy(channel);
- return HasFailure();
-}
-
+NameContentList malformedresolvconflookup = {
+ {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
+ "lookup garbage\n"}}; // malformed line
+CONTAINED_TEST_F(LibraryTest, ContainerMalformedResolvConfLookup,
+ "myhostname", "mydomainname.org", malformedresolvconflookup) {
+ ares_channel channel = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
+
+ struct ares_options opts;
+ int optmask = 0;
+ ares_save_options(channel, &opts, &optmask);
+ EXPECT_EQ(std::string("fb"), std::string(opts.lookups));
+ ares_destroy_options(&opts);
+
+ ares_destroy(channel);
+ return HasFailure();
+}
+
// Failures when expected config filenames are inaccessible.
class MakeUnreadable {
public:
diff --git a/contrib/libs/c-ares/test/ares-test-internal.cc b/contrib/libs/c-ares/test/ares-test-internal.cc
index cda8d96356..96d4edece5 100644
--- a/contrib/libs/c-ares/test/ares-test-internal.cc
+++ b/contrib/libs/c-ares/test/ares-test-internal.cc
@@ -356,107 +356,107 @@ TEST_F(LibraryTest, GetHostentAllocFail) {
fclose(fp);
}
-TEST_F(DefaultChannelTest, GetAddrInfoHostsPositive) {
- TempFile hostsfile("1.2.3.4 example.com \n"
- " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n"
- "#comment\n"
- "4.5.6.7\n"
- "1.3.5.7 \n"
- "::1 ipv6.com");
- EnvValue with_env("CARES_HOSTS", hostsfile.filename());
- struct ares_addrinfo_hints hints = {};
- AddrInfoResult result = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "example.com", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.ai_;
- EXPECT_EQ("{example.com addr=[1.2.3.4]}", ss.str());
-}
-
-TEST_F(DefaultChannelTest, GetAddrInfoHostsSpaces) {
- TempFile hostsfile("1.2.3.4 example.com \n"
- " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n"
- "#comment\n"
- "4.5.6.7\n"
- "1.3.5.7 \n"
- "::1 ipv6.com");
- EnvValue with_env("CARES_HOSTS", hostsfile.filename());
- struct ares_addrinfo_hints hints = {};
- AddrInfoResult result = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "google.com", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.ai_;
- EXPECT_EQ("{www.google.com->google.com, www2.google.com->google.com addr=[2.3.4.5]}", ss.str());
-}
-
-TEST_F(DefaultChannelTest, GetAddrInfoHostsByALias) {
- TempFile hostsfile("1.2.3.4 example.com \n"
- " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n"
- "#comment\n"
- "4.5.6.7\n"
- "1.3.5.7 \n"
- "::1 ipv6.com");
- EnvValue with_env("CARES_HOSTS", hostsfile.filename());
- struct ares_addrinfo_hints hints = {};
- AddrInfoResult result = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "www2.google.com", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.ai_;
- EXPECT_EQ("{www.google.com->google.com, www2.google.com->google.com addr=[2.3.4.5]}", ss.str());
-}
-
-TEST_F(DefaultChannelTest, GetAddrInfoHostsIPV6) {
- TempFile hostsfile("1.2.3.4 example.com \n"
- " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n"
- "#comment\n"
- "4.5.6.7\n"
- "1.3.5.7 \n"
- "::1 ipv6.com");
- EnvValue with_env("CARES_HOSTS", hostsfile.filename());
- struct ares_addrinfo_hints hints = {};
- AddrInfoResult result = {};
- hints.ai_family = AF_INET6;
- hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "ipv6.com", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.ai_;
- EXPECT_EQ("{ipv6.com addr=[[0000:0000:0000:0000:0000:0000:0000:0001]]}", ss.str());
-}
-
-TEST_F(LibraryTest, GetAddrInfoAllocFail) {
- TempFile hostsfile("1.2.3.4 example.com alias1 alias2\n");
- struct ares_addrinfo_hints hints;
- unsigned short port = 80;
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_INET;
-
- FILE *fp = fopen(hostsfile.filename(), "r");
- ASSERT_NE(nullptr, fp);
-
- for (int ii = 1; ii <= 3; ii++) {
- rewind(fp);
- ClearFails();
- SetAllocFail(ii);
- struct ares_addrinfo ai;
- EXPECT_EQ(ARES_ENOMEM, ares__readaddrinfo(fp, "example.com", port, &hints, &ai)) << ii;
- }
- fclose(fp);
-}
-
+TEST_F(DefaultChannelTest, GetAddrInfoHostsPositive) {
+ TempFile hostsfile("1.2.3.4 example.com \n"
+ " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n"
+ "#comment\n"
+ "4.5.6.7\n"
+ "1.3.5.7 \n"
+ "::1 ipv6.com");
+ EnvValue with_env("CARES_HOSTS", hostsfile.filename());
+ struct ares_addrinfo_hints hints = {};
+ AddrInfoResult result = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "example.com", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.ai_;
+ EXPECT_EQ("{example.com addr=[1.2.3.4]}", ss.str());
+}
+
+TEST_F(DefaultChannelTest, GetAddrInfoHostsSpaces) {
+ TempFile hostsfile("1.2.3.4 example.com \n"
+ " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n"
+ "#comment\n"
+ "4.5.6.7\n"
+ "1.3.5.7 \n"
+ "::1 ipv6.com");
+ EnvValue with_env("CARES_HOSTS", hostsfile.filename());
+ struct ares_addrinfo_hints hints = {};
+ AddrInfoResult result = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "google.com", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.ai_;
+ EXPECT_EQ("{www.google.com->google.com, www2.google.com->google.com addr=[2.3.4.5]}", ss.str());
+}
+
+TEST_F(DefaultChannelTest, GetAddrInfoHostsByALias) {
+ TempFile hostsfile("1.2.3.4 example.com \n"
+ " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n"
+ "#comment\n"
+ "4.5.6.7\n"
+ "1.3.5.7 \n"
+ "::1 ipv6.com");
+ EnvValue with_env("CARES_HOSTS", hostsfile.filename());
+ struct ares_addrinfo_hints hints = {};
+ AddrInfoResult result = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "www2.google.com", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.ai_;
+ EXPECT_EQ("{www.google.com->google.com, www2.google.com->google.com addr=[2.3.4.5]}", ss.str());
+}
+
+TEST_F(DefaultChannelTest, GetAddrInfoHostsIPV6) {
+ TempFile hostsfile("1.2.3.4 example.com \n"
+ " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n"
+ "#comment\n"
+ "4.5.6.7\n"
+ "1.3.5.7 \n"
+ "::1 ipv6.com");
+ EnvValue with_env("CARES_HOSTS", hostsfile.filename());
+ struct ares_addrinfo_hints hints = {};
+ AddrInfoResult result = {};
+ hints.ai_family = AF_INET6;
+ hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "ipv6.com", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.ai_;
+ EXPECT_EQ("{ipv6.com addr=[[0000:0000:0000:0000:0000:0000:0000:0001]]}", ss.str());
+}
+
+TEST_F(LibraryTest, GetAddrInfoAllocFail) {
+ TempFile hostsfile("1.2.3.4 example.com alias1 alias2\n");
+ struct ares_addrinfo_hints hints;
+ unsigned short port = 80;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+
+ FILE *fp = fopen(hostsfile.filename(), "r");
+ ASSERT_NE(nullptr, fp);
+
+ for (int ii = 1; ii <= 3; ii++) {
+ rewind(fp);
+ ClearFails();
+ SetAllocFail(ii);
+ struct ares_addrinfo ai;
+ EXPECT_EQ(ARES_ENOMEM, ares__readaddrinfo(fp, "example.com", port, &hints, &ai)) << ii;
+ }
+ fclose(fp);
+}
+
TEST(Misc, OnionDomain) {
EXPECT_EQ(0, ares__is_onion_domain("onion.no"));
EXPECT_EQ(0, ares__is_onion_domain(".onion.no"));
@@ -484,23 +484,23 @@ TEST_F(LibraryTest, Striendstr) {
const char *str = "plugh";
EXPECT_NE(nullptr, ares_striendstr(str, str));
}
-extern "C" int ares__single_domain(ares_channel, const char*, char**);
+extern "C" int ares__single_domain(ares_channel, const char*, char**);
TEST_F(DefaultChannelTest, SingleDomain) {
TempFile aliases("www www.google.com\n");
EnvValue with_env("HOSTALIASES", aliases.filename());
SetAllocSizeFail(128);
char *ptr = nullptr;
- EXPECT_EQ(ARES_ENOMEM, ares__single_domain(channel_, "www", &ptr));
+ EXPECT_EQ(ARES_ENOMEM, ares__single_domain(channel_, "www", &ptr));
channel_->flags |= ARES_FLAG_NOSEARCH|ARES_FLAG_NOALIASES;
- EXPECT_EQ(ARES_SUCCESS, ares__single_domain(channel_, "www", &ptr));
+ EXPECT_EQ(ARES_SUCCESS, ares__single_domain(channel_, "www", &ptr));
EXPECT_EQ("www", std::string(ptr));
ares_free(ptr);
ptr = nullptr;
SetAllocFail(1);
- EXPECT_EQ(ARES_ENOMEM, ares__single_domain(channel_, "www", &ptr));
+ EXPECT_EQ(ARES_ENOMEM, ares__single_domain(channel_, "www", &ptr));
EXPECT_EQ(nullptr, ptr);
}
#endif
diff --git a/contrib/libs/c-ares/test/ares-test-live.cc b/contrib/libs/c-ares/test/ares-test-live.cc
index 7d27cbc9d4..5510163e95 100644
--- a/contrib/libs/c-ares/test/ares-test-live.cc
+++ b/contrib/libs/c-ares/test/ares-test-live.cc
@@ -18,70 +18,70 @@ unsigned char gdns_addr4[4] = {0x08, 0x08, 0x08, 0x08};
unsigned char gdns_addr6[16] = {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88};
-MATCHER_P(IncludesAtLeastNumAddresses, n, "") {
- if(!arg)
- return false;
- int cnt = 0;
- for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next)
- cnt++;
- return cnt >= n;
-}
-
-MATCHER_P(OnlyIncludesAddrType, addrtype, "") {
- if(!arg)
- return false;
- for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next)
- if (ai->ai_family != addrtype)
- return false;
- return true;
-}
-
-MATCHER_P(IncludesAddrType, addrtype, "") {
- if(!arg)
- return false;
- for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next)
- if (ai->ai_family == addrtype)
- return true;
- return false;
-}
-
-//VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetAddrInfoV4) {
- //struct ares_addrinfo_hints hints = {};
- //hints.ai_family = AF_INET;
- //AddrInfoResult result;
- //ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
- //Process();
- //EXPECT_TRUE(result.done_);
- //EXPECT_EQ(ARES_SUCCESS, result.status_);
- //EXPECT_THAT(result.ai_, IncludesAtLeastNumAddresses(1));
- //EXPECT_THAT(result.ai_, OnlyIncludesAddrType(AF_INET));
-//}
-
-//VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetAddrInfoV6) {
- //struct ares_addrinfo_hints hints = {};
- //hints.ai_family = AF_INET6;
- //AddrInfoResult result;
- //ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
- //Process();
- //EXPECT_TRUE(result.done_);
- //EXPECT_EQ(ARES_SUCCESS, result.status_);
- //EXPECT_THAT(result.ai_, IncludesAtLeastNumAddresses(1));
- //EXPECT_THAT(result.ai_, OnlyIncludesAddrType(AF_INET6));
-//}
-
-//VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetAddrInfoUnspec) {
- //struct ares_addrinfo_hints hints = {};
- //hints.ai_family = AF_UNSPEC;
- //AddrInfoResult result;
- //ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
- //Process();
- //EXPECT_TRUE(result.done_);
- //EXPECT_EQ(ARES_SUCCESS, result.status_);
- //EXPECT_THAT(result.ai_, IncludesAtLeastNumAddresses(2));
- //EXPECT_THAT(result.ai_, IncludesAddrType(AF_INET6));
- //EXPECT_THAT(result.ai_, IncludesAddrType(AF_INET));
-//}
-
+MATCHER_P(IncludesAtLeastNumAddresses, n, "") {
+ if(!arg)
+ return false;
+ int cnt = 0;
+ for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next)
+ cnt++;
+ return cnt >= n;
+}
+
+MATCHER_P(OnlyIncludesAddrType, addrtype, "") {
+ if(!arg)
+ return false;
+ for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next)
+ if (ai->ai_family != addrtype)
+ return false;
+ return true;
+}
+
+MATCHER_P(IncludesAddrType, addrtype, "") {
+ if(!arg)
+ return false;
+ for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next)
+ if (ai->ai_family == addrtype)
+ return true;
+ return false;
+}
+
+//VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetAddrInfoV4) {
+ //struct ares_addrinfo_hints hints = {};
+ //hints.ai_family = AF_INET;
+ //AddrInfoResult result;
+ //ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
+ //Process();
+ //EXPECT_TRUE(result.done_);
+ //EXPECT_EQ(ARES_SUCCESS, result.status_);
+ //EXPECT_THAT(result.ai_, IncludesAtLeastNumAddresses(1));
+ //EXPECT_THAT(result.ai_, OnlyIncludesAddrType(AF_INET));
+//}
+
+//VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetAddrInfoV6) {
+ //struct ares_addrinfo_hints hints = {};
+ //hints.ai_family = AF_INET6;
+ //AddrInfoResult result;
+ //ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
+ //Process();
+ //EXPECT_TRUE(result.done_);
+ //EXPECT_EQ(ARES_SUCCESS, result.status_);
+ //EXPECT_THAT(result.ai_, IncludesAtLeastNumAddresses(1));
+ //EXPECT_THAT(result.ai_, OnlyIncludesAddrType(AF_INET6));
+//}
+
+//VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetAddrInfoUnspec) {
+ //struct ares_addrinfo_hints hints = {};
+ //hints.ai_family = AF_UNSPEC;
+ //AddrInfoResult result;
+ //ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
+ //Process();
+ //EXPECT_TRUE(result.done_);
+ //EXPECT_EQ(ARES_SUCCESS, result.status_);
+ //EXPECT_THAT(result.ai_, IncludesAtLeastNumAddresses(2));
+ //EXPECT_THAT(result.ai_, IncludesAddrType(AF_INET6));
+ //EXPECT_THAT(result.ai_, IncludesAddrType(AF_INET));
+//}
+
VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveGetHostByNameV4) {
HostResult result;
ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
@@ -214,11 +214,11 @@ TEST_P(DefaultChannelModeTest, LiveGetLocalhostByAddrV4) {
EXPECT_EQ(ARES_SUCCESS, result.status_);
EXPECT_LT(0, (int)result.host_.addrs_.size());
EXPECT_EQ(AF_INET, result.host_.addrtype_);
- // oddly, travis does not resolve to localhost, but a random hostname starting with travis-job
- if (result.host_.name_.find("travis-job") == std::string::npos) {
- EXPECT_NE(std::string::npos,
- result.host_.name_.find("localhost"));
- }
+ // oddly, travis does not resolve to localhost, but a random hostname starting with travis-job
+ if (result.host_.name_.find("travis-job") == std::string::npos) {
+ EXPECT_NE(std::string::npos,
+ result.host_.name_.find("localhost"));
+ }
}
}
@@ -234,9 +234,9 @@ TEST_P(DefaultChannelModeTest, LiveGetLocalhostByAddrV6) {
EXPECT_EQ(ARES_SUCCESS, result.status_);
EXPECT_LT(0, (int)result.host_.addrs_.size());
EXPECT_EQ(AF_INET6, result.host_.addrtype_);
- const std::string& name = result.host_.name_;
- EXPECT_TRUE(std::string::npos != name.find("localhost") ||
- std::string::npos != name.find("ip6-loopback"));
+ const std::string& name = result.host_.name_;
+ EXPECT_TRUE(std::string::npos != name.find("localhost") ||
+ std::string::npos != name.find("ip6-loopback"));
}
}
@@ -696,54 +696,54 @@ TEST_F(DefaultChannelTest, VerifySocketFunctionCallback) {
}
-TEST_F(DefaultChannelTest, LiveSetServers) {
- struct ares_addr_node server1;
- struct ares_addr_node server2;
- server1.next = &server2;
- server1.family = AF_INET;
- server1.addr.addr4.s_addr = htonl(0x01020304);
- server2.next = nullptr;
- server2.family = AF_INET;
- server2.addr.addr4.s_addr = htonl(0x02030405);
-
- // Change not allowed while request is pending
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- EXPECT_EQ(ARES_ENOTIMP, ares_set_servers(channel_, &server1));
- ares_cancel(channel_);
-}
-
-TEST_F(DefaultChannelTest, LiveSetServersPorts) {
- struct ares_addr_port_node server1;
- struct ares_addr_port_node server2;
- server1.next = &server2;
- server1.family = AF_INET;
- server1.addr.addr4.s_addr = htonl(0x01020304);
- server1.udp_port = 111;
- server1.tcp_port = 111;
- server2.next = nullptr;
- server2.family = AF_INET;
- server2.addr.addr4.s_addr = htonl(0x02030405);
- server2.udp_port = 0;
- server2.tcp_port = 0;;
- EXPECT_EQ(ARES_ENODATA, ares_set_servers_ports(nullptr, &server1));
-
- // Change not allowed while request is pending
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- EXPECT_EQ(ARES_ENOTIMP, ares_set_servers_ports(channel_, &server1));
- ares_cancel(channel_);
-}
-
-TEST_F(DefaultChannelTest, LiveSetServersCSV) {
- // Change not allowed while request is pending
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- EXPECT_EQ(ARES_ENOTIMP, ares_set_servers_csv(channel_, "1.2.3.4,2.3.4.5"));
- EXPECT_EQ(ARES_ENOTIMP, ares_set_servers_ports_csv(channel_, "1.2.3.4:56,2.3.4.5:67"));
- ares_cancel(channel_);
-}
-
-
+TEST_F(DefaultChannelTest, LiveSetServers) {
+ struct ares_addr_node server1;
+ struct ares_addr_node server2;
+ server1.next = &server2;
+ server1.family = AF_INET;
+ server1.addr.addr4.s_addr = htonl(0x01020304);
+ server2.next = nullptr;
+ server2.family = AF_INET;
+ server2.addr.addr4.s_addr = htonl(0x02030405);
+
+ // Change not allowed while request is pending
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ EXPECT_EQ(ARES_ENOTIMP, ares_set_servers(channel_, &server1));
+ ares_cancel(channel_);
+}
+
+TEST_F(DefaultChannelTest, LiveSetServersPorts) {
+ struct ares_addr_port_node server1;
+ struct ares_addr_port_node server2;
+ server1.next = &server2;
+ server1.family = AF_INET;
+ server1.addr.addr4.s_addr = htonl(0x01020304);
+ server1.udp_port = 111;
+ server1.tcp_port = 111;
+ server2.next = nullptr;
+ server2.family = AF_INET;
+ server2.addr.addr4.s_addr = htonl(0x02030405);
+ server2.udp_port = 0;
+ server2.tcp_port = 0;;
+ EXPECT_EQ(ARES_ENODATA, ares_set_servers_ports(nullptr, &server1));
+
+ // Change not allowed while request is pending
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ EXPECT_EQ(ARES_ENOTIMP, ares_set_servers_ports(channel_, &server1));
+ ares_cancel(channel_);
+}
+
+TEST_F(DefaultChannelTest, LiveSetServersCSV) {
+ // Change not allowed while request is pending
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ EXPECT_EQ(ARES_ENOTIMP, ares_set_servers_csv(channel_, "1.2.3.4,2.3.4.5"));
+ EXPECT_EQ(ARES_ENOTIMP, ares_set_servers_ports_csv(channel_, "1.2.3.4:56,2.3.4.5:67"));
+ ares_cancel(channel_);
+}
+
+
} // namespace test
} // namespace ares
diff --git a/contrib/libs/c-ares/test/ares-test-misc.cc b/contrib/libs/c-ares/test/ares-test-misc.cc
index c79f67ba1f..6fc28a8f97 100644
--- a/contrib/libs/c-ares/test/ares-test-misc.cc
+++ b/contrib/libs/c-ares/test/ares-test-misc.cc
@@ -277,15 +277,15 @@ TEST_F(DefaultChannelTest, HostByNameFileOnionDomain) {
ares_gethostbyname_file(channel_, "dontleak.onion", AF_INET, &h));
}
-TEST_F(DefaultChannelTest, GetAddrinfoOnionDomain) {
- AddrInfoResult result;
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_UNSPEC;
- ares_getaddrinfo(channel_, "dontleak.onion", NULL, &hints, AddrInfoCallback, &result);
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENOTFOUND, result.status_);
-}
-
+TEST_F(DefaultChannelTest, GetAddrinfoOnionDomain) {
+ AddrInfoResult result;
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_UNSPEC;
+ ares_getaddrinfo(channel_, "dontleak.onion", NULL, &hints, AddrInfoCallback, &result);
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ENOTFOUND, result.status_);
+}
+
// Interesting question: should tacking on a search domain let the query
// through? It seems safer to reject it because "supersecret.onion.search"
// still leaks information about the query to malicious resolvers.
diff --git a/contrib/libs/c-ares/test/ares-test-mock-ai.cc b/contrib/libs/c-ares/test/ares-test-mock-ai.cc
index 700333b826..d0df867fef 100644
--- a/contrib/libs/c-ares/test/ares-test-mock-ai.cc
+++ b/contrib/libs/c-ares/test/ares-test-mock-ai.cc
@@ -1,723 +1,723 @@
-#include "ares-test-ai.h"
-#include "dns-proto.h"
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
-#include <sstream>
-#include <vector>
-
-using testing::InvokeWithoutArgs;
-using testing::DoAll;
-
-namespace ares {
-namespace test {
-
-MATCHER_P(IncludesNumAddresses, n, "") {
- if(!arg)
- return false;
- int cnt = 0;
- for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next)
- cnt++;
- return n == cnt;
-}
-
-MATCHER_P(IncludesV4Address, address, "") {
- if(!arg)
- return false;
- in_addr addressnum = {};
- if (!ares_inet_pton(AF_INET, address, &addressnum))
- return false; // wrong number format?
- for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) {
- if (ai->ai_family != AF_INET)
- continue;
- if (reinterpret_cast<sockaddr_in*>(ai->ai_addr)->sin_addr.s_addr ==
- addressnum.s_addr)
- return true; // found
- }
- return false;
-}
-
-MATCHER_P(IncludesV6Address, address, "") {
- if(!arg)
- return false;
- in6_addr addressnum = {};
- if (!ares_inet_pton(AF_INET6, address, &addressnum)) {
- return false; // wrong number format?
- }
- for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) {
- if (ai->ai_family != AF_INET6)
- continue;
- if (!memcmp(
- reinterpret_cast<sockaddr_in6*>(ai->ai_addr)->sin6_addr.s6_addr,
- addressnum.s6_addr, sizeof(addressnum.s6_addr)))
- return true; // found
- }
- return false;
-}
-
-// UDP only so mock server doesn't get confused by concatenated requests
-TEST_P(MockUDPChannelTestAI, GetAddrInfoParallelLookups) {
- DNSPacket rsp1;
- rsp1.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", ns_t_a))
- .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &rsp1));
- DNSPacket rsp2;
- rsp2.set_response().set_aa()
- .add_question(new DNSQuestion("www.example.com", ns_t_a))
- .add_answer(new DNSARR("www.example.com", 100, {1, 2, 3, 4}));
- ON_CALL(server_, OnRequest("www.example.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &rsp2));
-
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_NOSORT;
- AddrInfoResult result1;
- ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result1);
- AddrInfoResult result2;
- ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result2);
- AddrInfoResult result3;
- ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result3);
- Process();
-
- EXPECT_TRUE(result1.done_);
- EXPECT_EQ(result1.status_, ARES_SUCCESS);
- EXPECT_THAT(result1.ai_, IncludesNumAddresses(1));
- EXPECT_THAT(result1.ai_, IncludesV4Address("2.3.4.5"));
-
- EXPECT_TRUE(result2.done_);
- EXPECT_EQ(result2.status_, ARES_SUCCESS);
- EXPECT_THAT(result2.ai_, IncludesNumAddresses(1));
- EXPECT_THAT(result2.ai_, IncludesV4Address("1.2.3.4"));
-
- EXPECT_TRUE(result3.done_);
- EXPECT_EQ(result3.status_, ARES_SUCCESS);
- EXPECT_THAT(result3.ai_, IncludesNumAddresses(1));
- EXPECT_THAT(result3.ai_, IncludesV4Address("2.3.4.5"));
-}
-
-// UDP to TCP specific test
-TEST_P(MockUDPChannelTestAI, TruncationRetry) {
- DNSPacket rsptruncated;
- rsptruncated.set_response().set_aa().set_tc()
- .add_question(new DNSQuestion("www.google.com", ns_t_a));
- DNSPacket rspok;
- rspok.set_response()
- .add_question(new DNSQuestion("www.google.com", ns_t_a))
- .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
- EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillOnce(SetReply(&server_, &rsptruncated))
- .WillOnce(SetReply(&server_, &rspok));
-
- AddrInfoResult result;
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(result.status_, ARES_SUCCESS);
- EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
- EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4"));
-}
-
-// TCP only to prevent retries
-TEST_P(MockTCPChannelTestAI, MalformedResponse) {
- std::vector<byte> one = {0x01};
- EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillOnce(SetReplyData(&server_, one));
-
- AddrInfoResult result;
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ETIMEOUT, result.status_);
-}
-
-TEST_P(MockTCPChannelTestAI, FormErrResponse) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", ns_t_a));
- rsp.set_rcode(ns_r_formerr);
- EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillOnce(SetReply(&server_, &rsp));
-
- AddrInfoResult result;
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_EFORMERR, result.status_);
-}
-
-TEST_P(MockTCPChannelTestAI, ServFailResponse) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", ns_t_a));
- rsp.set_rcode(ns_r_servfail);
- EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillOnce(SetReply(&server_, &rsp));
-
- AddrInfoResult result;
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- // ARES_FLAG_NOCHECKRESP not set, so SERVFAIL consumed
- EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
-}
-
-TEST_P(MockTCPChannelTestAI, NotImplResponse) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", ns_t_a));
- rsp.set_rcode(ns_r_notimpl);
- EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillOnce(SetReply(&server_, &rsp));
-
- AddrInfoResult result;
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- // ARES_FLAG_NOCHECKRESP not set, so NOTIMPL consumed
- EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
-}
-
-TEST_P(MockTCPChannelTestAI, RefusedResponse) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", ns_t_a));
- rsp.set_rcode(ns_r_refused);
- EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillOnce(SetReply(&server_, &rsp));
-
- AddrInfoResult result;
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- // ARES_FLAG_NOCHECKRESP not set, so REFUSED consumed
- EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
-}
-
-TEST_P(MockTCPChannelTestAI, YXDomainResponse) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", ns_t_a));
- rsp.set_rcode(ns_r_yxdomain);
- EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillOnce(SetReply(&server_, &rsp));
-
- AddrInfoResult result;
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENODATA, result.status_);
-}
-
-class MockExtraOptsTestAI
- : public MockChannelOptsTest,
- public ::testing::WithParamInterface< std::pair<int, bool> > {
- public:
- MockExtraOptsTestAI()
- : MockChannelOptsTest(1, GetParam().first, GetParam().second,
- FillOptions(&opts_),
- ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF) {}
- static struct ares_options* FillOptions(struct ares_options * opts) {
- memset(opts, 0, sizeof(struct ares_options));
- // Set a few options that affect socket communications
- opts->socket_send_buffer_size = 514;
- opts->socket_receive_buffer_size = 514;
- return opts;
- }
- private:
- struct ares_options opts_;
-};
-
-TEST_P(MockExtraOptsTestAI, SimpleQuery) {
- ares_set_local_ip4(channel_, 0x7F000001);
- byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
- ares_set_local_ip6(channel_, addr6);
- ares_set_local_dev(channel_, "dummy");
-
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", ns_t_a))
- .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &rsp));
-
- AddrInfoResult result;
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
- EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
-}
-
-class MockFlagsChannelOptsTestAI
- : public MockChannelOptsTest,
- public ::testing::WithParamInterface< std::pair<int, bool> > {
- public:
- MockFlagsChannelOptsTestAI(int flags)
- : MockChannelOptsTest(1, GetParam().first, GetParam().second,
- FillOptions(&opts_, flags), ARES_OPT_FLAGS) {}
- static struct ares_options* FillOptions(struct ares_options * opts, int flags) {
- memset(opts, 0, sizeof(struct ares_options));
- opts->flags = flags;
- return opts;
- }
- private:
- struct ares_options opts_;
-};
-
-class MockNoCheckRespChannelTestAI : public MockFlagsChannelOptsTestAI {
- public:
- MockNoCheckRespChannelTestAI() : MockFlagsChannelOptsTestAI(ARES_FLAG_NOCHECKRESP) {}
-};
-
-TEST_P(MockNoCheckRespChannelTestAI, ServFailResponse) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", ns_t_a));
- rsp.set_rcode(ns_r_servfail);
- ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &rsp));
-
- AddrInfoResult result;
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ESERVFAIL, result.status_);
-}
-
-TEST_P(MockNoCheckRespChannelTestAI, NotImplResponse) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", ns_t_a));
- rsp.set_rcode(ns_r_notimpl);
- ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &rsp));
-
- AddrInfoResult result;
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENOTIMP, result.status_);
-}
-
-TEST_P(MockNoCheckRespChannelTestAI, RefusedResponse) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", ns_t_a));
- rsp.set_rcode(ns_r_refused);
- ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &rsp));
-
- AddrInfoResult result;
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_EREFUSED, result.status_);
-}
-
-TEST_P(MockChannelTestAI, FamilyV6) {
- DNSPacket rsp6;
- rsp6.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_aaaa))
- .add_answer(new DNSAaaaRR("example.com", 100,
- {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
- ON_CALL(server_, OnRequest("example.com", ns_t_aaaa))
- .WillByDefault(SetReply(&server_, &rsp6));
- AddrInfoResult result;
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET6;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
- AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
- EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303"));
-}
-
-TEST_P(MockChannelTestAI, FamilyV4) {
- DNSPacket rsp4;
- rsp4.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_a))
- .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("example.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &rsp4));
- AddrInfoResult result = {};
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
- AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
- EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
-}
-
-TEST_P(MockChannelTestAI, FamilyV4_MultipleAddresses) {
- DNSPacket rsp4;
- rsp4.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_a))
- .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}))
- .add_answer(new DNSARR("example.com", 100, {7, 8, 9, 0}));
- ON_CALL(server_, OnRequest("example.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &rsp4));
- AddrInfoResult result = {};
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
- AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.ai_;
- EXPECT_EQ("{addr=[2.3.4.5], addr=[7.8.9.0]}", ss.str());
-}
-
-TEST_P(MockChannelTestAI, FamilyUnspecified) {
- DNSPacket rsp6;
- rsp6.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_aaaa))
- .add_answer(new DNSAaaaRR("example.com", 100,
- {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
- ON_CALL(server_, OnRequest("example.com", ns_t_aaaa))
- .WillByDefault(SetReply(&server_, &rsp6));
- DNSPacket rsp4;
- rsp4.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_a))
- .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("example.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &rsp4));
- AddrInfoResult result;
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_UNSPEC;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
- AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_THAT(result.ai_, IncludesNumAddresses(2));
- EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
- EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303"));
-}
-
-class MockEDNSChannelTestAI : public MockFlagsChannelOptsTestAI {
- public:
- MockEDNSChannelTestAI() : MockFlagsChannelOptsTestAI(ARES_FLAG_EDNS) {}
-};
-
-TEST_P(MockEDNSChannelTestAI, RetryWithoutEDNS) {
- DNSPacket rspfail;
- rspfail.set_response().set_aa().set_rcode(ns_r_servfail)
- .add_question(new DNSQuestion("www.google.com", ns_t_a));
- DNSPacket rspok;
- rspok.set_response()
- .add_question(new DNSQuestion("www.google.com", ns_t_a))
- .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
- EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillOnce(SetReply(&server_, &rspfail))
- .WillOnce(SetReply(&server_, &rspok));
-
- AddrInfoResult result;
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
- EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4"));
-}
-
-TEST_P(MockChannelTestAI, SearchDomains) {
- DNSPacket nofirst;
- nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain)
- .add_question(new DNSQuestion("www.first.com", ns_t_a));
- ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &nofirst));
- DNSPacket nosecond;
- nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain)
- .add_question(new DNSQuestion("www.second.org", ns_t_a));
- ON_CALL(server_, OnRequest("www.second.org", ns_t_a))
- .WillByDefault(SetReply(&server_, &nosecond));
- DNSPacket yesthird;
- yesthird.set_response().set_aa()
- .add_question(new DNSQuestion("www.third.gov", ns_t_a))
- .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
- .WillByDefault(SetReply(&server_, &yesthird));
-
- AddrInfoResult result;
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "www", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
- EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
-}
-
-TEST_P(MockChannelTestAI, SearchDomainsServFailOnAAAA) {
- DNSPacket nofirst;
- nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain)
- .add_question(new DNSQuestion("www.first.com", ns_t_aaaa));
- ON_CALL(server_, OnRequest("www.first.com", ns_t_aaaa))
- .WillByDefault(SetReply(&server_, &nofirst));
- DNSPacket nofirst4;
- nofirst4.set_response().set_aa().set_rcode(ns_r_nxdomain)
- .add_question(new DNSQuestion("www.first.com", ns_t_a));
- ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &nofirst4));
-
- DNSPacket nosecond;
- nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain)
- .add_question(new DNSQuestion("www.second.org", ns_t_aaaa));
- ON_CALL(server_, OnRequest("www.second.org", ns_t_aaaa))
- .WillByDefault(SetReply(&server_, &nosecond));
- DNSPacket yessecond4;
- yessecond4.set_response().set_aa()
- .add_question(new DNSQuestion("www.second.org", ns_t_a))
- .add_answer(new DNSARR("www.second.org", 0x0200, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("www.second.org", ns_t_a))
- .WillByDefault(SetReply(&server_, &yessecond4));
-
- DNSPacket failthird;
- failthird.set_response().set_aa().set_rcode(ns_r_servfail)
- .add_question(new DNSQuestion("www.third.gov", ns_t_aaaa));
- ON_CALL(server_, OnRequest("www.third.gov", ns_t_aaaa))
- .WillByDefault(SetReply(&server_, &failthird));
- DNSPacket failthird4;
- failthird4.set_response().set_aa().set_rcode(ns_r_servfail)
- .add_question(new DNSQuestion("www.third.gov", ns_t_a));
- ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
- .WillByDefault(SetReply(&server_, &failthird4));
-
- AddrInfoResult result;
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_UNSPEC;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "www", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
- EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
-}
-
-class MockMultiServerChannelTestAI
- : public MockChannelOptsTest,
- public ::testing::WithParamInterface< std::pair<int, bool> > {
- public:
- MockMultiServerChannelTestAI(bool rotate)
- : MockChannelOptsTest(3, GetParam().first, GetParam().second, nullptr, rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE) {}
- void CheckExample() {
- AddrInfoResult result;
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(result.status_, ARES_SUCCESS);
- EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
- EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
- }
-};
-
-class RotateMultiMockTestAI : public MockMultiServerChannelTestAI {
- public:
- RotateMultiMockTestAI() : MockMultiServerChannelTestAI(true) {}
-};
-
-class NoRotateMultiMockTestAI : public MockMultiServerChannelTestAI {
- public:
- NoRotateMultiMockTestAI() : MockMultiServerChannelTestAI(false) {}
-};
-
-
-TEST_P(RotateMultiMockTestAI, ThirdServer) {
- struct ares_options opts = {0};
- int optmask = 0;
- EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
- EXPECT_EQ(0, (optmask & ARES_OPT_NOROTATE));
- ares_destroy_options(&opts);
-
- DNSPacket servfailrsp;
- servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail)
- .add_question(new DNSQuestion("www.example.com", ns_t_a));
- DNSPacket notimplrsp;
- notimplrsp.set_response().set_aa().set_rcode(ns_r_notimpl)
- .add_question(new DNSQuestion("www.example.com", ns_t_a));
- DNSPacket okrsp;
- okrsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.example.com", ns_t_a))
- .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
-
- EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
- EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
- EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[2].get(), &okrsp));
- CheckExample();
-
- // Second time around, starts from server [1].
- EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[1].get(), &servfailrsp));
- EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[2].get(), &notimplrsp));
- EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[0].get(), &okrsp));
- CheckExample();
-
- // Third time around, starts from server [2].
- EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[2].get(), &servfailrsp));
- EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[0].get(), &notimplrsp));
- EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[1].get(), &okrsp));
- CheckExample();
-}
-
-TEST_P(NoRotateMultiMockTestAI, ThirdServer) {
- struct ares_options opts = {0};
- int optmask = 0;
- EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
- EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE));
- ares_destroy_options(&opts);
-
- DNSPacket servfailrsp;
- servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail)
- .add_question(new DNSQuestion("www.example.com", ns_t_a));
- DNSPacket notimplrsp;
- notimplrsp.set_response().set_aa().set_rcode(ns_r_notimpl)
- .add_question(new DNSQuestion("www.example.com", ns_t_a));
- DNSPacket okrsp;
- okrsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.example.com", ns_t_a))
- .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
-
- EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
- EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
- EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[2].get(), &okrsp));
- CheckExample();
-
- // Second time around, still starts from server [0].
- EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
- EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
- EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[2].get(), &okrsp));
- CheckExample();
-
- // Third time around, still starts from server [0].
- EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
- EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
- EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[2].get(), &okrsp));
- CheckExample();
-}
-
-TEST_P(MockChannelTestAI, FamilyV4ServiceName) {
- DNSPacket rsp4;
- rsp4.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_a))
- .add_answer(new DNSARR("example.com", 100, {1, 1, 1, 1}))
- .add_answer(new DNSARR("example.com", 100, {2, 2, 2, 2}));
- ON_CALL(server_, OnRequest("example.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &rsp4));
- AddrInfoResult result = {};
- struct ares_addrinfo_hints hints = {};
- hints.ai_family = AF_INET;
- hints.ai_flags = ARES_AI_NOSORT;
- ares_getaddrinfo(channel_, "example.com", "http", &hints, AddrInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.ai_;
- EXPECT_EQ("{addr=[1.1.1.1:80], addr=[2.2.2.2:80]}", ss.str());
-}
-
-// force-tcp does currently not work, possibly test DNS server swallows
-// bytes from second query
-//INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockChannelTestAI,
-// ::testing::ValuesIn(ares::test::families_modes));
-//const std::vector<std::pair<int, bool>> both_families_udponly = {
-// std::make_pair<int, bool>(AF_INET, false),
-// std::make_pair<int, bool>(AF_INET6, false)
-//};
-INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockChannelTestAI,
- ::testing::Values(std::make_pair<int, bool>(AF_INET, false)));
-
-INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockUDPChannelTestAI,
- ::testing::ValuesIn(ares::test::families));
-
-INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockTCPChannelTestAI,
- ::testing::ValuesIn(ares::test::families));
-
-INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockExtraOptsTestAI,
- ::testing::ValuesIn(ares::test::families_modes));
-
-INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockNoCheckRespChannelTestAI,
- ::testing::ValuesIn(ares::test::families_modes));
-
-INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockEDNSChannelTestAI,
- ::testing::ValuesIn(ares::test::families_modes));
-
-INSTANTIATE_TEST_CASE_P(TransportModesAI, RotateMultiMockTestAI,
- ::testing::ValuesIn(ares::test::families_modes));
-
-INSTANTIATE_TEST_CASE_P(TransportModesAI, NoRotateMultiMockTestAI,
- ::testing::ValuesIn(ares::test::families_modes));
-
-
-} // namespace test
-} // namespace ares
+#include "ares-test-ai.h"
+#include "dns-proto.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include <sstream>
+#include <vector>
+
+using testing::InvokeWithoutArgs;
+using testing::DoAll;
+
+namespace ares {
+namespace test {
+
+MATCHER_P(IncludesNumAddresses, n, "") {
+ if(!arg)
+ return false;
+ int cnt = 0;
+ for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next)
+ cnt++;
+ return n == cnt;
+}
+
+MATCHER_P(IncludesV4Address, address, "") {
+ if(!arg)
+ return false;
+ in_addr addressnum = {};
+ if (!ares_inet_pton(AF_INET, address, &addressnum))
+ return false; // wrong number format?
+ for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) {
+ if (ai->ai_family != AF_INET)
+ continue;
+ if (reinterpret_cast<sockaddr_in*>(ai->ai_addr)->sin_addr.s_addr ==
+ addressnum.s_addr)
+ return true; // found
+ }
+ return false;
+}
+
+MATCHER_P(IncludesV6Address, address, "") {
+ if(!arg)
+ return false;
+ in6_addr addressnum = {};
+ if (!ares_inet_pton(AF_INET6, address, &addressnum)) {
+ return false; // wrong number format?
+ }
+ for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) {
+ if (ai->ai_family != AF_INET6)
+ continue;
+ if (!memcmp(
+ reinterpret_cast<sockaddr_in6*>(ai->ai_addr)->sin6_addr.s6_addr,
+ addressnum.s6_addr, sizeof(addressnum.s6_addr)))
+ return true; // found
+ }
+ return false;
+}
+
+// UDP only so mock server doesn't get confused by concatenated requests
+TEST_P(MockUDPChannelTestAI, GetAddrInfoParallelLookups) {
+ DNSPacket rsp1;
+ rsp1.set_response().set_aa()
+ .add_question(new DNSQuestion("www.google.com", ns_t_a))
+ .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
+ ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &rsp1));
+ DNSPacket rsp2;
+ rsp2.set_response().set_aa()
+ .add_question(new DNSQuestion("www.example.com", ns_t_a))
+ .add_answer(new DNSARR("www.example.com", 100, {1, 2, 3, 4}));
+ ON_CALL(server_, OnRequest("www.example.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &rsp2));
+
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_NOSORT;
+ AddrInfoResult result1;
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result1);
+ AddrInfoResult result2;
+ ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result2);
+ AddrInfoResult result3;
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result3);
+ Process();
+
+ EXPECT_TRUE(result1.done_);
+ EXPECT_EQ(result1.status_, ARES_SUCCESS);
+ EXPECT_THAT(result1.ai_, IncludesNumAddresses(1));
+ EXPECT_THAT(result1.ai_, IncludesV4Address("2.3.4.5"));
+
+ EXPECT_TRUE(result2.done_);
+ EXPECT_EQ(result2.status_, ARES_SUCCESS);
+ EXPECT_THAT(result2.ai_, IncludesNumAddresses(1));
+ EXPECT_THAT(result2.ai_, IncludesV4Address("1.2.3.4"));
+
+ EXPECT_TRUE(result3.done_);
+ EXPECT_EQ(result3.status_, ARES_SUCCESS);
+ EXPECT_THAT(result3.ai_, IncludesNumAddresses(1));
+ EXPECT_THAT(result3.ai_, IncludesV4Address("2.3.4.5"));
+}
+
+// UDP to TCP specific test
+TEST_P(MockUDPChannelTestAI, TruncationRetry) {
+ DNSPacket rsptruncated;
+ rsptruncated.set_response().set_aa().set_tc()
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
+ DNSPacket rspok;
+ rspok.set_response()
+ .add_question(new DNSQuestion("www.google.com", ns_t_a))
+ .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillOnce(SetReply(&server_, &rsptruncated))
+ .WillOnce(SetReply(&server_, &rspok));
+
+ AddrInfoResult result;
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(result.status_, ARES_SUCCESS);
+ EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
+ EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4"));
+}
+
+// TCP only to prevent retries
+TEST_P(MockTCPChannelTestAI, MalformedResponse) {
+ std::vector<byte> one = {0x01};
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillOnce(SetReplyData(&server_, one));
+
+ AddrInfoResult result;
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ETIMEOUT, result.status_);
+}
+
+TEST_P(MockTCPChannelTestAI, FormErrResponse) {
+ DNSPacket rsp;
+ rsp.set_response().set_aa()
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
+ rsp.set_rcode(ns_r_formerr);
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillOnce(SetReply(&server_, &rsp));
+
+ AddrInfoResult result;
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_EFORMERR, result.status_);
+}
+
+TEST_P(MockTCPChannelTestAI, ServFailResponse) {
+ DNSPacket rsp;
+ rsp.set_response().set_aa()
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
+ rsp.set_rcode(ns_r_servfail);
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillOnce(SetReply(&server_, &rsp));
+
+ AddrInfoResult result;
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ // ARES_FLAG_NOCHECKRESP not set, so SERVFAIL consumed
+ EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
+}
+
+TEST_P(MockTCPChannelTestAI, NotImplResponse) {
+ DNSPacket rsp;
+ rsp.set_response().set_aa()
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
+ rsp.set_rcode(ns_r_notimpl);
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillOnce(SetReply(&server_, &rsp));
+
+ AddrInfoResult result;
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ // ARES_FLAG_NOCHECKRESP not set, so NOTIMPL consumed
+ EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
+}
+
+TEST_P(MockTCPChannelTestAI, RefusedResponse) {
+ DNSPacket rsp;
+ rsp.set_response().set_aa()
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
+ rsp.set_rcode(ns_r_refused);
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillOnce(SetReply(&server_, &rsp));
+
+ AddrInfoResult result;
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ // ARES_FLAG_NOCHECKRESP not set, so REFUSED consumed
+ EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
+}
+
+TEST_P(MockTCPChannelTestAI, YXDomainResponse) {
+ DNSPacket rsp;
+ rsp.set_response().set_aa()
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
+ rsp.set_rcode(ns_r_yxdomain);
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillOnce(SetReply(&server_, &rsp));
+
+ AddrInfoResult result;
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ENODATA, result.status_);
+}
+
+class MockExtraOptsTestAI
+ : public MockChannelOptsTest,
+ public ::testing::WithParamInterface< std::pair<int, bool> > {
+ public:
+ MockExtraOptsTestAI()
+ : MockChannelOptsTest(1, GetParam().first, GetParam().second,
+ FillOptions(&opts_),
+ ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF) {}
+ static struct ares_options* FillOptions(struct ares_options * opts) {
+ memset(opts, 0, sizeof(struct ares_options));
+ // Set a few options that affect socket communications
+ opts->socket_send_buffer_size = 514;
+ opts->socket_receive_buffer_size = 514;
+ return opts;
+ }
+ private:
+ struct ares_options opts_;
+};
+
+TEST_P(MockExtraOptsTestAI, SimpleQuery) {
+ ares_set_local_ip4(channel_, 0x7F000001);
+ byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
+ ares_set_local_ip6(channel_, addr6);
+ ares_set_local_dev(channel_, "dummy");
+
+ DNSPacket rsp;
+ rsp.set_response().set_aa()
+ .add_question(new DNSQuestion("www.google.com", ns_t_a))
+ .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
+ ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &rsp));
+
+ AddrInfoResult result;
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
+ EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
+}
+
+class MockFlagsChannelOptsTestAI
+ : public MockChannelOptsTest,
+ public ::testing::WithParamInterface< std::pair<int, bool> > {
+ public:
+ MockFlagsChannelOptsTestAI(int flags)
+ : MockChannelOptsTest(1, GetParam().first, GetParam().second,
+ FillOptions(&opts_, flags), ARES_OPT_FLAGS) {}
+ static struct ares_options* FillOptions(struct ares_options * opts, int flags) {
+ memset(opts, 0, sizeof(struct ares_options));
+ opts->flags = flags;
+ return opts;
+ }
+ private:
+ struct ares_options opts_;
+};
+
+class MockNoCheckRespChannelTestAI : public MockFlagsChannelOptsTestAI {
+ public:
+ MockNoCheckRespChannelTestAI() : MockFlagsChannelOptsTestAI(ARES_FLAG_NOCHECKRESP) {}
+};
+
+TEST_P(MockNoCheckRespChannelTestAI, ServFailResponse) {
+ DNSPacket rsp;
+ rsp.set_response().set_aa()
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
+ rsp.set_rcode(ns_r_servfail);
+ ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &rsp));
+
+ AddrInfoResult result;
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ESERVFAIL, result.status_);
+}
+
+TEST_P(MockNoCheckRespChannelTestAI, NotImplResponse) {
+ DNSPacket rsp;
+ rsp.set_response().set_aa()
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
+ rsp.set_rcode(ns_r_notimpl);
+ ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &rsp));
+
+ AddrInfoResult result;
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ENOTIMP, result.status_);
+}
+
+TEST_P(MockNoCheckRespChannelTestAI, RefusedResponse) {
+ DNSPacket rsp;
+ rsp.set_response().set_aa()
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
+ rsp.set_rcode(ns_r_refused);
+ ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &rsp));
+
+ AddrInfoResult result;
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_EREFUSED, result.status_);
+}
+
+TEST_P(MockChannelTestAI, FamilyV6) {
+ DNSPacket rsp6;
+ rsp6.set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_aaaa))
+ .add_answer(new DNSAaaaRR("example.com", 100,
+ {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
+ ON_CALL(server_, OnRequest("example.com", ns_t_aaaa))
+ .WillByDefault(SetReply(&server_, &rsp6));
+ AddrInfoResult result;
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET6;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
+ AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
+ EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303"));
+}
+
+TEST_P(MockChannelTestAI, FamilyV4) {
+ DNSPacket rsp4;
+ rsp4.set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_a))
+ .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
+ ON_CALL(server_, OnRequest("example.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &rsp4));
+ AddrInfoResult result = {};
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
+ AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
+ EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
+}
+
+TEST_P(MockChannelTestAI, FamilyV4_MultipleAddresses) {
+ DNSPacket rsp4;
+ rsp4.set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_a))
+ .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}))
+ .add_answer(new DNSARR("example.com", 100, {7, 8, 9, 0}));
+ ON_CALL(server_, OnRequest("example.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &rsp4));
+ AddrInfoResult result = {};
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
+ AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.ai_;
+ EXPECT_EQ("{addr=[2.3.4.5], addr=[7.8.9.0]}", ss.str());
+}
+
+TEST_P(MockChannelTestAI, FamilyUnspecified) {
+ DNSPacket rsp6;
+ rsp6.set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_aaaa))
+ .add_answer(new DNSAaaaRR("example.com", 100,
+ {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
+ ON_CALL(server_, OnRequest("example.com", ns_t_aaaa))
+ .WillByDefault(SetReply(&server_, &rsp6));
+ DNSPacket rsp4;
+ rsp4.set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_a))
+ .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
+ ON_CALL(server_, OnRequest("example.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &rsp4));
+ AddrInfoResult result;
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
+ AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_THAT(result.ai_, IncludesNumAddresses(2));
+ EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
+ EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303"));
+}
+
+class MockEDNSChannelTestAI : public MockFlagsChannelOptsTestAI {
+ public:
+ MockEDNSChannelTestAI() : MockFlagsChannelOptsTestAI(ARES_FLAG_EDNS) {}
+};
+
+TEST_P(MockEDNSChannelTestAI, RetryWithoutEDNS) {
+ DNSPacket rspfail;
+ rspfail.set_response().set_aa().set_rcode(ns_r_servfail)
+ .add_question(new DNSQuestion("www.google.com", ns_t_a));
+ DNSPacket rspok;
+ rspok.set_response()
+ .add_question(new DNSQuestion("www.google.com", ns_t_a))
+ .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillOnce(SetReply(&server_, &rspfail))
+ .WillOnce(SetReply(&server_, &rspok));
+
+ AddrInfoResult result;
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
+ EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4"));
+}
+
+TEST_P(MockChannelTestAI, SearchDomains) {
+ DNSPacket nofirst;
+ nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain)
+ .add_question(new DNSQuestion("www.first.com", ns_t_a));
+ ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &nofirst));
+ DNSPacket nosecond;
+ nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain)
+ .add_question(new DNSQuestion("www.second.org", ns_t_a));
+ ON_CALL(server_, OnRequest("www.second.org", ns_t_a))
+ .WillByDefault(SetReply(&server_, &nosecond));
+ DNSPacket yesthird;
+ yesthird.set_response().set_aa()
+ .add_question(new DNSQuestion("www.third.gov", ns_t_a))
+ .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
+ ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
+ .WillByDefault(SetReply(&server_, &yesthird));
+
+ AddrInfoResult result;
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "www", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
+ EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
+}
+
+TEST_P(MockChannelTestAI, SearchDomainsServFailOnAAAA) {
+ DNSPacket nofirst;
+ nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain)
+ .add_question(new DNSQuestion("www.first.com", ns_t_aaaa));
+ ON_CALL(server_, OnRequest("www.first.com", ns_t_aaaa))
+ .WillByDefault(SetReply(&server_, &nofirst));
+ DNSPacket nofirst4;
+ nofirst4.set_response().set_aa().set_rcode(ns_r_nxdomain)
+ .add_question(new DNSQuestion("www.first.com", ns_t_a));
+ ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &nofirst4));
+
+ DNSPacket nosecond;
+ nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain)
+ .add_question(new DNSQuestion("www.second.org", ns_t_aaaa));
+ ON_CALL(server_, OnRequest("www.second.org", ns_t_aaaa))
+ .WillByDefault(SetReply(&server_, &nosecond));
+ DNSPacket yessecond4;
+ yessecond4.set_response().set_aa()
+ .add_question(new DNSQuestion("www.second.org", ns_t_a))
+ .add_answer(new DNSARR("www.second.org", 0x0200, {2, 3, 4, 5}));
+ ON_CALL(server_, OnRequest("www.second.org", ns_t_a))
+ .WillByDefault(SetReply(&server_, &yessecond4));
+
+ DNSPacket failthird;
+ failthird.set_response().set_aa().set_rcode(ns_r_servfail)
+ .add_question(new DNSQuestion("www.third.gov", ns_t_aaaa));
+ ON_CALL(server_, OnRequest("www.third.gov", ns_t_aaaa))
+ .WillByDefault(SetReply(&server_, &failthird));
+ DNSPacket failthird4;
+ failthird4.set_response().set_aa().set_rcode(ns_r_servfail)
+ .add_question(new DNSQuestion("www.third.gov", ns_t_a));
+ ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
+ .WillByDefault(SetReply(&server_, &failthird4));
+
+ AddrInfoResult result;
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "www", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
+ EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
+}
+
+class MockMultiServerChannelTestAI
+ : public MockChannelOptsTest,
+ public ::testing::WithParamInterface< std::pair<int, bool> > {
+ public:
+ MockMultiServerChannelTestAI(bool rotate)
+ : MockChannelOptsTest(3, GetParam().first, GetParam().second, nullptr, rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE) {}
+ void CheckExample() {
+ AddrInfoResult result;
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(result.status_, ARES_SUCCESS);
+ EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
+ EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
+ }
+};
+
+class RotateMultiMockTestAI : public MockMultiServerChannelTestAI {
+ public:
+ RotateMultiMockTestAI() : MockMultiServerChannelTestAI(true) {}
+};
+
+class NoRotateMultiMockTestAI : public MockMultiServerChannelTestAI {
+ public:
+ NoRotateMultiMockTestAI() : MockMultiServerChannelTestAI(false) {}
+};
+
+
+TEST_P(RotateMultiMockTestAI, ThirdServer) {
+ struct ares_options opts = {0};
+ int optmask = 0;
+ EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
+ EXPECT_EQ(0, (optmask & ARES_OPT_NOROTATE));
+ ares_destroy_options(&opts);
+
+ DNSPacket servfailrsp;
+ servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail)
+ .add_question(new DNSQuestion("www.example.com", ns_t_a));
+ DNSPacket notimplrsp;
+ notimplrsp.set_response().set_aa().set_rcode(ns_r_notimpl)
+ .add_question(new DNSQuestion("www.example.com", ns_t_a));
+ DNSPacket okrsp;
+ okrsp.set_response().set_aa()
+ .add_question(new DNSQuestion("www.example.com", ns_t_a))
+ .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
+
+ EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
+ EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
+ EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[2].get(), &okrsp));
+ CheckExample();
+
+ // Second time around, starts from server [1].
+ EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[1].get(), &servfailrsp));
+ EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[2].get(), &notimplrsp));
+ EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[0].get(), &okrsp));
+ CheckExample();
+
+ // Third time around, starts from server [2].
+ EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[2].get(), &servfailrsp));
+ EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[0].get(), &notimplrsp));
+ EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[1].get(), &okrsp));
+ CheckExample();
+}
+
+TEST_P(NoRotateMultiMockTestAI, ThirdServer) {
+ struct ares_options opts = {0};
+ int optmask = 0;
+ EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
+ EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE));
+ ares_destroy_options(&opts);
+
+ DNSPacket servfailrsp;
+ servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail)
+ .add_question(new DNSQuestion("www.example.com", ns_t_a));
+ DNSPacket notimplrsp;
+ notimplrsp.set_response().set_aa().set_rcode(ns_r_notimpl)
+ .add_question(new DNSQuestion("www.example.com", ns_t_a));
+ DNSPacket okrsp;
+ okrsp.set_response().set_aa()
+ .add_question(new DNSQuestion("www.example.com", ns_t_a))
+ .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
+
+ EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
+ EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
+ EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[2].get(), &okrsp));
+ CheckExample();
+
+ // Second time around, still starts from server [0].
+ EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
+ EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
+ EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[2].get(), &okrsp));
+ CheckExample();
+
+ // Third time around, still starts from server [0].
+ EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
+ EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
+ EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[2].get(), &okrsp));
+ CheckExample();
+}
+
+TEST_P(MockChannelTestAI, FamilyV4ServiceName) {
+ DNSPacket rsp4;
+ rsp4.set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_a))
+ .add_answer(new DNSARR("example.com", 100, {1, 1, 1, 1}))
+ .add_answer(new DNSARR("example.com", 100, {2, 2, 2, 2}));
+ ON_CALL(server_, OnRequest("example.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &rsp4));
+ AddrInfoResult result = {};
+ struct ares_addrinfo_hints hints = {};
+ hints.ai_family = AF_INET;
+ hints.ai_flags = ARES_AI_NOSORT;
+ ares_getaddrinfo(channel_, "example.com", "http", &hints, AddrInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.ai_;
+ EXPECT_EQ("{addr=[1.1.1.1:80], addr=[2.2.2.2:80]}", ss.str());
+}
+
+// force-tcp does currently not work, possibly test DNS server swallows
+// bytes from second query
+//INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockChannelTestAI,
+// ::testing::ValuesIn(ares::test::families_modes));
+//const std::vector<std::pair<int, bool>> both_families_udponly = {
+// std::make_pair<int, bool>(AF_INET, false),
+// std::make_pair<int, bool>(AF_INET6, false)
+//};
+INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockChannelTestAI,
+ ::testing::Values(std::make_pair<int, bool>(AF_INET, false)));
+
+INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockUDPChannelTestAI,
+ ::testing::ValuesIn(ares::test::families));
+
+INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockTCPChannelTestAI,
+ ::testing::ValuesIn(ares::test::families));
+
+INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockExtraOptsTestAI,
+ ::testing::ValuesIn(ares::test::families_modes));
+
+INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockNoCheckRespChannelTestAI,
+ ::testing::ValuesIn(ares::test::families_modes));
+
+INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockEDNSChannelTestAI,
+ ::testing::ValuesIn(ares::test::families_modes));
+
+INSTANTIATE_TEST_CASE_P(TransportModesAI, RotateMultiMockTestAI,
+ ::testing::ValuesIn(ares::test::families_modes));
+
+INSTANTIATE_TEST_CASE_P(TransportModesAI, NoRotateMultiMockTestAI,
+ ::testing::ValuesIn(ares::test::families_modes));
+
+
+} // namespace test
+} // namespace ares
diff --git a/contrib/libs/c-ares/test/ares-test-mock.cc b/contrib/libs/c-ares/test/ares-test-mock.cc
index 99a3c6a2bf..80e9fc02b0 100644
--- a/contrib/libs/c-ares/test/ares-test-mock.cc
+++ b/contrib/libs/c-ares/test/ares-test-mock.cc
@@ -51,7 +51,7 @@ TEST_P(MockChannelTest, Basic) {
}
// UDP only so mock server doesn't get confused by concatenated requests
-TEST_P(MockUDPChannelTest, GetHostByNameParallelLookups) {
+TEST_P(MockUDPChannelTest, GetHostByNameParallelLookups) {
DNSPacket rsp1;
rsp1.set_response().set_aa()
.add_question(new DNSQuestion("www.google.com", ns_t_a))
@@ -936,21 +936,21 @@ TEST_P(MockChannelTest, GetHostByNameDestroyRelative) {
EXPECT_EQ(0, result.timeouts_);
}
-TEST_P(MockChannelTest, GetHostByNameCNAMENoData) {
- DNSPacket response;
- response.set_response().set_aa()
- .add_question(new DNSQuestion("cname.first.com", ns_t_a))
- .add_answer(new DNSCnameRR("cname.first.com", 100, "a.first.com"));
- ON_CALL(server_, OnRequest("cname.first.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &response));
-
- HostResult result;
- ares_gethostbyname(channel_, "cname.first.com", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENODATA, result.status_);
-}
-
+TEST_P(MockChannelTest, GetHostByNameCNAMENoData) {
+ DNSPacket response;
+ response.set_response().set_aa()
+ .add_question(new DNSQuestion("cname.first.com", ns_t_a))
+ .add_answer(new DNSCnameRR("cname.first.com", 100, "a.first.com"));
+ ON_CALL(server_, OnRequest("cname.first.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &response));
+
+ HostResult result;
+ ares_gethostbyname(channel_, "cname.first.com", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ENODATA, result.status_);
+}
+
TEST_P(MockChannelTest, GetHostByAddrDestroy) {
unsigned char gdns_addr4[4] = {0x08, 0x08, 0x08, 0x08};
HostResult result;
diff --git a/contrib/libs/c-ares/test/ares-test-parse-a.cc b/contrib/libs/c-ares/test/ares-test-parse-a.cc
index 6cdaba58ac..7f6a987c13 100644
--- a/contrib/libs/c-ares/test/ares-test-parse-a.cc
+++ b/contrib/libs/c-ares/test/ares-test-parse-a.cc
@@ -11,14 +11,14 @@ TEST_F(LibraryTest, ParseAReplyOK) {
DNSPacket pkt;
pkt.set_qid(0x1234).set_response().set_aa()
.add_question(new DNSQuestion("example.com", ns_t_a))
- .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5}))
- .add_answer(new DNSAaaaRR("example.com", 0x01020304, {0,0,0,0,0,0,0,0,0,0,0,0,2,3,4,5}));
+ .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5}))
+ .add_answer(new DNSAaaaRR("example.com", 0x01020304, {0,0,0,0,0,0,0,0,0,0,0,0,2,3,4,5}));
std::vector<byte> data = {
0x12, 0x34, // qid
0x84, // response + query + AA + not-TC + not-RD
0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
0x00, 0x01, // num questions
- 0x00, 0x02, // num answer RRs
+ 0x00, 0x02, // num answer RRs
0x00, 0x00, // num authority RRs
0x00, 0x00, // num additional RRs
// Question
@@ -36,15 +36,15 @@ TEST_F(LibraryTest, ParseAReplyOK) {
0x01, 0x02, 0x03, 0x04, // TTL
0x00, 0x04, // rdata length
0x02, 0x03, 0x04, 0x05,
- // Answer 2
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x1c, // RR type
- 0x00, 0x01, // class IN
- 0x01, 0x02, 0x03, 0x04, // TTL
- 0x00, 0x10, // rdata length
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x04, 0x05,
+ // Answer 2
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x1c, // RR type
+ 0x00, 0x01, // class IN
+ 0x01, 0x02, 0x03, 0x04, // TTL
+ 0x00, 0x10, // rdata length
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x04, 0x05,
};
EXPECT_EQ(data, pkt.data());
struct hostent *host = nullptr;
@@ -78,7 +78,7 @@ TEST_F(LibraryTest, ParseMalformedAReply) {
0x84, // [2] response + query + AA + not-TC + not-RD
0x00, // [3] not-RA + not-Z + not-AD + not-CD + rc=NoError
0x00, 0x01, // [4:6) num questions
- 0x00, 0x02, // [6:8) num answer RRs
+ 0x00, 0x02, // [6:8) num answer RRs
0x00, 0x00, // [8:10) num authority RRs
0x00, 0x00, // [10:12) num additional RRs
// Question
@@ -131,16 +131,16 @@ TEST_F(LibraryTest, ParseAReplyNoData) {
// Again but with a CNAME.
pkt.add_answer(new DNSCnameRR("example.com", 200, "c.example.com"));
- data = pkt.data();
- // Expect success as per https://github.com/c-ares/c-ares/commit/2c63440127feed70ccefb148b8f938a2df6c15f8
- EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
+ data = pkt.data();
+ // Expect success as per https://github.com/c-ares/c-ares/commit/2c63440127feed70ccefb148b8f938a2df6c15f8
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
&host, info, &count));
EXPECT_EQ(0, count);
- EXPECT_NE(nullptr, host);
- std::stringstream ss;
- ss << HostEnt(host);
- EXPECT_EQ("{'c.example.com' aliases=[example.com] addrs=[]}", ss.str());
- ares_free_hostent(host);
+ EXPECT_NE(nullptr, host);
+ std::stringstream ss;
+ ss << HostEnt(host);
+ EXPECT_EQ("{'c.example.com' aliases=[example.com] addrs=[]}", ss.str());
+ ares_free_hostent(host);
}
TEST_F(LibraryTest, ParseAReplyVariantA) {
diff --git a/contrib/libs/c-ares/test/ares-test-parse-aaaa.cc b/contrib/libs/c-ares/test/ares-test-parse-aaaa.cc
index 371438fca3..1314c837a6 100644
--- a/contrib/libs/c-ares/test/ares-test-parse-aaaa.cc
+++ b/contrib/libs/c-ares/test/ares-test-parse-aaaa.cc
@@ -13,8 +13,8 @@ TEST_F(LibraryTest, ParseAaaaReplyOK) {
.add_question(new DNSQuestion("example.com", ns_t_aaaa))
.add_answer(new DNSAaaaRR("example.com", 100,
{0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
- 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04}))
- .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5}));
+ 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04}))
+ .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5}));
std::vector<byte> data = pkt.data();
struct hostent *host = nullptr;
struct ares_addr6ttl info[5];
diff --git a/contrib/libs/c-ares/test/ares-test-parse-soa-any.cc b/contrib/libs/c-ares/test/ares-test-parse-soa-any.cc
index 2e2c3f9db4..804c6a0060 100644
--- a/contrib/libs/c-ares/test/ares-test-parse-soa-any.cc
+++ b/contrib/libs/c-ares/test/ares-test-parse-soa-any.cc
@@ -1,111 +1,111 @@
-#include "ares-test.h"
-#include "dns-proto.h"
-
-#include <sstream>
-#include <vector>
-
-namespace ares {
-namespace test {
-
-TEST_F(LibraryTest, ParseSoaAnyReplyOK) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_any))\
- .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5}))
- .add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"))
- .add_answer(new DNSMxRR("example.com", 100, 200, "mx2.example.com"))
- .add_answer(new DNSSoaRR("example.com", 100,
- "soa1.example.com", "fred.example.com",
- 1, 2, 3, 4, 5));
- std::vector<byte> data = pkt.data();
-
- struct ares_soa_reply* soa = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_soa_reply(data.data(), data.size(), &soa));
- ASSERT_NE(nullptr, soa);
- EXPECT_EQ("soa1.example.com", std::string(soa->nsname));
- EXPECT_EQ("fred.example.com", std::string(soa->hostmaster));
- EXPECT_EQ(1, soa->serial);
- EXPECT_EQ(2, soa->refresh);
- EXPECT_EQ(3, soa->retry);
- EXPECT_EQ(4, soa->expire);
- EXPECT_EQ(5, soa->minttl);
- ares_free_data(soa);
-}
-
-TEST_F(LibraryTest, ParseSoaAnyReplyErrors) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_any))
- .add_answer(new DNSSoaRR("example.com", 100,
- "soa1.example.com", "fred.example.com",
- 1, 2, 3, 4, 5));
- std::vector<byte> data;
- struct ares_soa_reply* soa = nullptr;
-
- // No question.
- pkt.questions_.clear();
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa));
- pkt.add_question(new DNSQuestion("example.com", ns_t_any));
-
-#ifdef DISABLED
- // Question != answer
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("Axample.com", ns_t_any));
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa));
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("example.com", ns_t_any));
-#endif
-
- // Two questions
- pkt.add_question(new DNSQuestion("example.com", ns_t_any));
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa));
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("example.com", ns_t_any));
-
- // Wrong sort of answer.
- pkt.answers_.clear();
- pkt.add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"));
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa));
- pkt.answers_.clear();
- pkt.add_answer(new DNSSoaRR("example.com", 100,
- "soa1.example.com", "fred.example.com",
- 1, 2, 3, 4, 5));
-
- // No answer.
- pkt.answers_.clear();
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa));
- pkt.add_answer(new DNSSoaRR("example.com", 100,
- "soa1.example.com", "fred.example.com",
- 1, 2, 3, 4, 5));
-
- // Truncated packets.
- data = pkt.data();
- for (size_t len = 1; len < data.size(); len++) {
- EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), len, &soa));
- }
-}
-
-TEST_F(LibraryTest, ParseSoaAnyReplyAllocFail) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_any))
- .add_answer(new DNSSoaRR("example.com", 100,
- "soa1.example.com", "fred.example.com",
- 1, 2, 3, 4, 5));
- std::vector<byte> data = pkt.data();
- struct ares_soa_reply* soa = nullptr;
-
- for (int ii = 1; ii <= 5; ii++) {
- ClearFails();
- SetAllocFail(ii);
- EXPECT_EQ(ARES_ENOMEM, ares_parse_soa_reply(data.data(), data.size(), &soa)) << ii;
- }
-}
-
-} // namespace test
-} // namespace ares
+#include "ares-test.h"
+#include "dns-proto.h"
+
+#include <sstream>
+#include <vector>
+
+namespace ares {
+namespace test {
+
+TEST_F(LibraryTest, ParseSoaAnyReplyOK) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_any))\
+ .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5}))
+ .add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"))
+ .add_answer(new DNSMxRR("example.com", 100, 200, "mx2.example.com"))
+ .add_answer(new DNSSoaRR("example.com", 100,
+ "soa1.example.com", "fred.example.com",
+ 1, 2, 3, 4, 5));
+ std::vector<byte> data = pkt.data();
+
+ struct ares_soa_reply* soa = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_soa_reply(data.data(), data.size(), &soa));
+ ASSERT_NE(nullptr, soa);
+ EXPECT_EQ("soa1.example.com", std::string(soa->nsname));
+ EXPECT_EQ("fred.example.com", std::string(soa->hostmaster));
+ EXPECT_EQ(1, soa->serial);
+ EXPECT_EQ(2, soa->refresh);
+ EXPECT_EQ(3, soa->retry);
+ EXPECT_EQ(4, soa->expire);
+ EXPECT_EQ(5, soa->minttl);
+ ares_free_data(soa);
+}
+
+TEST_F(LibraryTest, ParseSoaAnyReplyErrors) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_any))
+ .add_answer(new DNSSoaRR("example.com", 100,
+ "soa1.example.com", "fred.example.com",
+ 1, 2, 3, 4, 5));
+ std::vector<byte> data;
+ struct ares_soa_reply* soa = nullptr;
+
+ // No question.
+ pkt.questions_.clear();
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa));
+ pkt.add_question(new DNSQuestion("example.com", ns_t_any));
+
+#ifdef DISABLED
+ // Question != answer
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("Axample.com", ns_t_any));
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa));
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("example.com", ns_t_any));
+#endif
+
+ // Two questions
+ pkt.add_question(new DNSQuestion("example.com", ns_t_any));
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa));
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("example.com", ns_t_any));
+
+ // Wrong sort of answer.
+ pkt.answers_.clear();
+ pkt.add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"));
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa));
+ pkt.answers_.clear();
+ pkt.add_answer(new DNSSoaRR("example.com", 100,
+ "soa1.example.com", "fred.example.com",
+ 1, 2, 3, 4, 5));
+
+ // No answer.
+ pkt.answers_.clear();
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa));
+ pkt.add_answer(new DNSSoaRR("example.com", 100,
+ "soa1.example.com", "fred.example.com",
+ 1, 2, 3, 4, 5));
+
+ // Truncated packets.
+ data = pkt.data();
+ for (size_t len = 1; len < data.size(); len++) {
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), len, &soa));
+ }
+}
+
+TEST_F(LibraryTest, ParseSoaAnyReplyAllocFail) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_any))
+ .add_answer(new DNSSoaRR("example.com", 100,
+ "soa1.example.com", "fred.example.com",
+ 1, 2, 3, 4, 5));
+ std::vector<byte> data = pkt.data();
+ struct ares_soa_reply* soa = nullptr;
+
+ for (int ii = 1; ii <= 5; ii++) {
+ ClearFails();
+ SetAllocFail(ii);
+ EXPECT_EQ(ARES_ENOMEM, ares_parse_soa_reply(data.data(), data.size(), &soa)) << ii;
+ }
+}
+
+} // namespace test
+} // namespace ares
diff --git a/contrib/libs/c-ares/test/ares-test-parse-soa.cc b/contrib/libs/c-ares/test/ares-test-parse-soa.cc
index 3ef95ec7f1..c0ffaaed50 100644
--- a/contrib/libs/c-ares/test/ares-test-parse-soa.cc
+++ b/contrib/libs/c-ares/test/ares-test-parse-soa.cc
@@ -50,7 +50,7 @@ TEST_F(LibraryTest, ParseSoaReplyErrors) {
pkt.questions_.clear();
pkt.add_question(new DNSQuestion("Axample.com", ns_t_soa));
data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa));
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa));
pkt.questions_.clear();
pkt.add_question(new DNSQuestion("example.com", ns_t_soa));
#endif
diff --git a/contrib/libs/c-ares/test/ares-test.cc b/contrib/libs/c-ares/test/ares-test.cc
index 8c85b4ef93..ec4b460549 100644
--- a/contrib/libs/c-ares/test/ares-test.cc
+++ b/contrib/libs/c-ares/test/ares-test.cc
@@ -1,5 +1,5 @@
#include "ares-test.h"
-#include "ares-test-ai.h"
+#include "ares-test-ai.h"
#include "dns-proto.h"
// Include ares internal files for DNS protocol details
@@ -565,79 +565,79 @@ void HostCallback(void *data, int status, int timeouts,
if (verbose) std::cerr << "HostCallback(" << *result << ")" << std::endl;
}
-std::ostream& operator<<(std::ostream& os, const AddrInfoResult& result) {
- os << '{';
- if (result.done_ && result.ai_) {
- os << StatusToString(result.status_) << " " << result.ai_;
- } else {
- os << "(incomplete)";
- }
- os << '}';
- return os;
-}
-
-std::ostream& operator<<(std::ostream& os, const AddrInfo& ai) {
- os << '{';
- if (ai == nullptr) {
- os << "nullptr}";
- return os;
- }
-
- struct ares_addrinfo_cname *next_cname = ai->cnames;
- while(next_cname) {
- if(next_cname->alias) {
- os << next_cname->alias << "->";
- }
- if(next_cname->name) {
- os << next_cname->name;
- }
- if((next_cname = next_cname->next))
- os << ", ";
- else
- os << " ";
- }
-
- struct ares_addrinfo_node *next = ai->nodes;
- while(next) {
- //if(next->ai_canonname) {
- //os << "'" << next->ai_canonname << "' ";
- //}
- unsigned short port = 0;
- os << "addr=[";
- if(next->ai_family == AF_INET) {
- sockaddr_in* sin = (sockaddr_in*)next->ai_addr;
- port = ntohs(sin->sin_port);
- os << AddressToString(&sin->sin_addr, 4);
- }
- else if (next->ai_family == AF_INET6) {
- sockaddr_in6* sin = (sockaddr_in6*)next->ai_addr;
- port = ntohs(sin->sin6_port);
- os << "[" << AddressToString(&sin->sin6_addr, 16) << "]";
- }
- else
- os << "unknown family";
- if(port) {
- os << ":" << port;
- }
- os << "]";
- if((next = next->ai_next))
- os << ", ";
- }
- os << '}';
- return os;
-}
-
-void AddrInfoCallback(void *data, int status, int timeouts,
- struct ares_addrinfo *ai) {
- EXPECT_NE(nullptr, data);
- AddrInfoResult* result = reinterpret_cast<AddrInfoResult*>(data);
- result->done_ = true;
- result->status_ = status;
- result->timeouts_= timeouts;
- result->ai_ = AddrInfo(ai);
- if (verbose) std::cerr << "AddrInfoCallback(" << *result << ")" << std::endl;
-}
-
+std::ostream& operator<<(std::ostream& os, const AddrInfoResult& result) {
+ os << '{';
+ if (result.done_ && result.ai_) {
+ os << StatusToString(result.status_) << " " << result.ai_;
+ } else {
+ os << "(incomplete)";
+ }
+ os << '}';
+ return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const AddrInfo& ai) {
+ os << '{';
+ if (ai == nullptr) {
+ os << "nullptr}";
+ return os;
+ }
+
+ struct ares_addrinfo_cname *next_cname = ai->cnames;
+ while(next_cname) {
+ if(next_cname->alias) {
+ os << next_cname->alias << "->";
+ }
+ if(next_cname->name) {
+ os << next_cname->name;
+ }
+ if((next_cname = next_cname->next))
+ os << ", ";
+ else
+ os << " ";
+ }
+
+ struct ares_addrinfo_node *next = ai->nodes;
+ while(next) {
+ //if(next->ai_canonname) {
+ //os << "'" << next->ai_canonname << "' ";
+ //}
+ unsigned short port = 0;
+ os << "addr=[";
+ if(next->ai_family == AF_INET) {
+ sockaddr_in* sin = (sockaddr_in*)next->ai_addr;
+ port = ntohs(sin->sin_port);
+ os << AddressToString(&sin->sin_addr, 4);
+ }
+ else if (next->ai_family == AF_INET6) {
+ sockaddr_in6* sin = (sockaddr_in6*)next->ai_addr;
+ port = ntohs(sin->sin6_port);
+ os << "[" << AddressToString(&sin->sin6_addr, 16) << "]";
+ }
+ else
+ os << "unknown family";
+ if(port) {
+ os << ":" << port;
+ }
+ os << "]";
+ if((next = next->ai_next))
+ os << ", ";
+ }
+ os << '}';
+ return os;
+}
+
+void AddrInfoCallback(void *data, int status, int timeouts,
+ struct ares_addrinfo *ai) {
+ EXPECT_NE(nullptr, data);
+ AddrInfoResult* result = reinterpret_cast<AddrInfoResult*>(data);
+ result->done_ = true;
+ result->status_ = status;
+ result->timeouts_= timeouts;
+ result->ai_ = AddrInfo(ai);
+ if (verbose) std::cerr << "AddrInfoCallback(" << *result << ")" << std::endl;
+}
+
std::ostream& operator<<(std::ostream& os, const SearchResult& result) {
os << '{';
if (result.done_) {
diff --git a/contrib/libs/c-ares/test/ares-test.h b/contrib/libs/c-ares/test/ares-test.h
index 541e29a87d..fd3bc31c27 100644
--- a/contrib/libs/c-ares/test/ares-test.h
+++ b/contrib/libs/c-ares/test/ares-test.h
@@ -276,30 +276,30 @@ struct NameInfoResult {
};
std::ostream& operator<<(std::ostream& os, const NameInfoResult& result);
-struct AddrInfoDeleter {
- void operator() (ares_addrinfo *ptr) {
- if (ptr) ares_freeaddrinfo(ptr);
- }
-};
-
-// C++ wrapper for struct ares_addrinfo.
-using AddrInfo = std::unique_ptr<ares_addrinfo, AddrInfoDeleter>;
-
-std::ostream& operator<<(std::ostream& os, const AddrInfo& result);
-
-// Structure that describes the result of an ares_addrinfo_callback invocation.
-struct AddrInfoResult {
- AddrInfoResult() : done_(false), status_(-1), timeouts_(0) {}
- // Whether the callback has been invoked.
- bool done_;
- // Explicitly provided result information.
- int status_;
- int timeouts_;
- // Contents of the ares_addrinfo structure, if provided.
- AddrInfo ai_;
-};
-std::ostream& operator<<(std::ostream& os, const AddrInfoResult& result);
-
+struct AddrInfoDeleter {
+ void operator() (ares_addrinfo *ptr) {
+ if (ptr) ares_freeaddrinfo(ptr);
+ }
+};
+
+// C++ wrapper for struct ares_addrinfo.
+using AddrInfo = std::unique_ptr<ares_addrinfo, AddrInfoDeleter>;
+
+std::ostream& operator<<(std::ostream& os, const AddrInfo& result);
+
+// Structure that describes the result of an ares_addrinfo_callback invocation.
+struct AddrInfoResult {
+ AddrInfoResult() : done_(false), status_(-1), timeouts_(0) {}
+ // Whether the callback has been invoked.
+ bool done_;
+ // Explicitly provided result information.
+ int status_;
+ int timeouts_;
+ // Contents of the ares_addrinfo structure, if provided.
+ AddrInfo ai_;
+};
+std::ostream& operator<<(std::ostream& os, const AddrInfoResult& result);
+
// Standard implementation of ares callbacks that fill out the corresponding
// structures.
void HostCallback(void *data, int status, int timeouts,
@@ -308,8 +308,8 @@ void SearchCallback(void *data, int status, int timeouts,
unsigned char *abuf, int alen);
void NameInfoCallback(void *data, int status, int timeouts,
char *node, char *service);
-void AddrInfoCallback(void *data, int status, int timeouts,
- struct ares_addrinfo *res);
+void AddrInfoCallback(void *data, int status, int timeouts,
+ struct ares_addrinfo *res);
// Retrieve the name servers used by a channel.
std::vector<std::string> GetNameServers(ares_channel channel);
@@ -345,40 +345,40 @@ class TempFile : public TransientFile {
const char* filename() const { return filename_.c_str(); }
};
-#ifdef _WIN32
-extern "C" {
-
-static int setenv(const char *name, const char *value, int overwrite)
-{
- char *buffer;
- size_t buf_size;
-
- if (name == NULL)
- return -1;
-
- if (value == NULL)
- value = ""; /* For unset */
-
- if (!overwrite && getenv(name) != NULL) {
- return -1;
- }
-
- buf_size = strlen(name) + strlen(value) + 1 /* = */ + 1 /* NULL */;
- buffer = (char *)malloc(buf_size);
- _snprintf(buffer, buf_size, "%s=%s", name, value);
- _putenv(buffer);
- free(buffer);
- return 0;
-}
-
-static int unsetenv(const char *name)
-{
- return setenv(name, NULL, 1);
-}
-
-} /* extern "C" */
-#endif
-
+#ifdef _WIN32
+extern "C" {
+
+static int setenv(const char *name, const char *value, int overwrite)
+{
+ char *buffer;
+ size_t buf_size;
+
+ if (name == NULL)
+ return -1;
+
+ if (value == NULL)
+ value = ""; /* For unset */
+
+ if (!overwrite && getenv(name) != NULL) {
+ return -1;
+ }
+
+ buf_size = strlen(name) + strlen(value) + 1 /* = */ + 1 /* NULL */;
+ buffer = (char *)malloc(buf_size);
+ _snprintf(buffer, buf_size, "%s=%s", name, value);
+ _putenv(buffer);
+ free(buffer);
+ return 0;
+}
+
+static int unsetenv(const char *name)
+{
+ return setenv(name, NULL, 1);
+}
+
+} /* extern "C" */
+#endif
+
// RAII class for a temporary environment variable value.
class EnvValue {
public:
diff --git a/contrib/libs/c-ares/test/ya.make b/contrib/libs/c-ares/test/ya.make
index 5eb7f6c6bf..ef42eab230 100644
--- a/contrib/libs/c-ares/test/ya.make
+++ b/contrib/libs/c-ares/test/ya.make
@@ -38,7 +38,7 @@ SRCS(
ares-test-internal.cc
ares-test-live.cc
ares-test-misc.cc
- ares-test-mock-ai.cc
+ ares-test-mock-ai.cc
ares-test-mock.cc
ares-test-ns.cc
ares-test-parse-a.cc
@@ -47,7 +47,7 @@ SRCS(
ares-test-parse-naptr.cc
ares-test-parse-ns.cc
ares-test-parse-ptr.cc
- ares-test-parse-soa-any.cc
+ ares-test-parse-soa-any.cc
ares-test-parse-soa.cc
ares-test-parse-srv.cc
ares-test-parse-txt.cc
diff --git a/contrib/libs/c-ares/ya.make b/contrib/libs/c-ares/ya.make
index 7c1a7d13e8..bd35762e44 100644
--- a/contrib/libs/c-ares/ya.make
+++ b/contrib/libs/c-ares/ya.make
@@ -7,7 +7,7 @@ OWNER(
g:cpp-contrib
)
-VERSION(1.16.1)
+VERSION(1.16.1)
ORIGINAL_SOURCE(https://c-ares.haxx.se/download/c-ares-1.16.1.tar.gz)
@@ -51,10 +51,10 @@ ENDIF()
SRCS(
ares__close_sockets.c
ares__get_hostent.c
- ares__parse_into_addrinfo.c
+ ares__parse_into_addrinfo.c
ares__read_line.c
- ares__readaddrinfo.c
- ares__sortaddrinfo.c
+ ares__readaddrinfo.c
+ ares__sortaddrinfo.c
ares__timeval.c
ares_android.c
ares_cancel.c
@@ -66,8 +66,8 @@ SRCS(
ares_fds.c
ares_free_hostent.c
ares_free_string.c
- ares_freeaddrinfo.c
- ares_getaddrinfo.c
+ ares_freeaddrinfo.c
+ ares_getaddrinfo.c
ares_getenv.c
ares_gethostbyaddr.c
ares_gethostbyname.c
diff --git a/contrib/libs/crcutil/ya.make b/contrib/libs/crcutil/ya.make
index 63c51cbe69..2da8ef940f 100644
--- a/contrib/libs/crcutil/ya.make
+++ b/contrib/libs/crcutil/ya.make
@@ -2,8 +2,8 @@ LIBRARY()
LICENSE(Apache-2.0)
-VERSION(1.0)
-
+VERSION(1.0)
+
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
OWNER(
diff --git a/contrib/libs/cxxsupp/builtins/ya.make b/contrib/libs/cxxsupp/builtins/ya.make
index 4df3d704dd..d2c319c927 100644
--- a/contrib/libs/cxxsupp/builtins/ya.make
+++ b/contrib/libs/cxxsupp/builtins/ya.make
@@ -18,10 +18,10 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(2016-03-03-08f0372c351a57b01afee6c64066961203da28c5)
-
-ORIGINAL_SOURCE(https://github.com/llvm/llvm-project)
-
+VERSION(2016-03-03-08f0372c351a57b01afee6c64066961203da28c5)
+
+ORIGINAL_SOURCE(https://github.com/llvm/llvm-project)
+
OWNER(
pg
somov
diff --git a/contrib/libs/cxxsupp/libcxx/ya.make b/contrib/libs/cxxsupp/libcxx/ya.make
index 3df3c2c2da..15403fe6d5 100644
--- a/contrib/libs/cxxsupp/libcxx/ya.make
+++ b/contrib/libs/cxxsupp/libcxx/ya.make
@@ -10,8 +10,8 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(2021-04-02-7959d59028dd126416cdf10dbbd22162922e1336)
-
+VERSION(2021-04-02-7959d59028dd126416cdf10dbbd22162922e1336)
+
OWNER(
halyavin
somov
diff --git a/contrib/libs/cxxsupp/libcxxabi-parts/ya.make b/contrib/libs/cxxsupp/libcxxabi-parts/ya.make
index 87e3d8e4a9..9965f3bcf0 100644
--- a/contrib/libs/cxxsupp/libcxxabi-parts/ya.make
+++ b/contrib/libs/cxxsupp/libcxxabi-parts/ya.make
@@ -15,7 +15,7 @@ LICENSE(
)
VERSION(2021-08-17)
-
+
ORIGINAL_SOURCE(https://github.com/llvm/llvm-project/archive/f0fcd42495432670664a661e75e7cae7e904dd3e.tar.gz)
ADDINCL(
diff --git a/contrib/libs/cxxsupp/libcxxrt/ya.make b/contrib/libs/cxxsupp/libcxxrt/ya.make
index c699a041d2..12dccbd505 100644
--- a/contrib/libs/cxxsupp/libcxxrt/ya.make
+++ b/contrib/libs/cxxsupp/libcxxrt/ya.make
@@ -20,7 +20,7 @@ OWNER(
)
VERSION(2021-09-08-14bf5d5526056ae1cc16f03b7b8e96108a1e38d0)
-
+
ORIGINAL_SOURCE(https://github.com/libcxxrt/libcxxrt/archive/14bf5d5526056ae1cc16f03b7b8e96108a1e38d0.tar.gz)
ADDINCL(
diff --git a/contrib/libs/cxxsupp/openmp/ya.make b/contrib/libs/cxxsupp/openmp/ya.make
index 2351300f45..2c64468375 100644
--- a/contrib/libs/cxxsupp/openmp/ya.make
+++ b/contrib/libs/cxxsupp/openmp/ya.make
@@ -7,8 +7,8 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(5.0)
-
+VERSION(5.0)
+
OWNER(
pg
g:contrib
diff --git a/contrib/libs/double-conversion/ya.make b/contrib/libs/double-conversion/ya.make
index a45c96f9d6..52e59b0989 100644
--- a/contrib/libs/double-conversion/ya.make
+++ b/contrib/libs/double-conversion/ya.make
@@ -1,7 +1,7 @@
LIBRARY()
-VERSION(3.1.0)
-
+VERSION(3.1.0)
+
LICENSE(BSD-3-Clause)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
diff --git a/contrib/libs/expat/.yandex_meta/devtools.copyrights.report b/contrib/libs/expat/.yandex_meta/devtools.copyrights.report
index ebeb069f1a..fe869ba35c 100644
--- a/contrib/libs/expat/.yandex_meta/devtools.copyrights.report
+++ b/contrib/libs/expat/.yandex_meta/devtools.copyrights.report
@@ -38,7 +38,7 @@ BELONGS ya.make
Match type : COPYRIGHT
Files with this license:
lib/internal.h [28:34]
- lib/xmlrole.c [9:19]
+ lib/xmlrole.c [9:19]
KEEP COPYRIGHT_SERVICE_LABEL 0adb14e8c9e1c6efd33764459efe0fd7
BELONGS ya.make
@@ -59,8 +59,8 @@ BELONGS ya.make
Match type : COPYRIGHT
Files with this license:
lib/internal.h [28:34]
- lib/xmlrole.c [9:19]
- lib/xmltok.c [9:24]
+ lib/xmlrole.c [9:19]
+ lib/xmltok.c [9:24]
lib/xmltok_impl.c [9:19]
KEEP COPYRIGHT_SERVICE_LABEL 12db9abedf3e0b98a87d6f4ec1377a19
@@ -73,8 +73,8 @@ BELONGS ya.make
Files with this license:
expat.h [9:18]
expat_external.h [9:18]
- lib/xmlrole.c [9:19]
- lib/xmltok.c [9:24]
+ lib/xmlrole.c [9:19]
+ lib/xmltok.c [9:24]
lib/xmltok.h [9:15]
lib/xmltok_impl.c [9:19]
@@ -86,7 +86,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
lib/xmltok_impl.c [9:19]
KEEP COPYRIGHT_SERVICE_LABEL 1916cbefc2e0a780a3d503ba26f3780a
@@ -99,7 +99,7 @@ BELONGS ya.make
Files with this license:
expat_external.h [9:18]
lib/internal.h [28:34]
- lib/xmlrole.c [9:19]
+ lib/xmlrole.c [9:19]
lib/xmltok_ns.c [9:15]
KEEP COPYRIGHT_SERVICE_LABEL 20cd458d8adbbc3a265dc6b0fb1f06ba
@@ -110,7 +110,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmltok.c [9:24]
+ lib/xmltok.c [9:24]
KEEP COPYRIGHT_SERVICE_LABEL 2309e9d42c2779decb776323d1f5dabd
BELONGS ya.make
@@ -120,8 +120,8 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
- lib/xmltok.c [9:24]
+ lib/xmlparse.c [9:37]
+ lib/xmltok.c [9:24]
KEEP COPYRIGHT_SERVICE_LABEL 262c58e3a627f5cee77a882379e1364f
BELONGS ya.make
@@ -142,7 +142,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
KEEP COPYRIGHT_SERVICE_LABEL 338b8ad8ee9b8449a90a88a0559aefd9
BELONGS ya.make
@@ -152,7 +152,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
KEEP COPYRIGHT_SERVICE_LABEL 387a03e23bfe968e0bc1919b0ef65164
BELONGS ya.make
@@ -172,7 +172,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
KEEP COPYRIGHT_SERVICE_LABEL 52b42ccd5b2debda3846c7aad55185e7
BELONGS ya.make
@@ -182,7 +182,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmltok.c [9:24]
+ lib/xmltok.c [9:24]
KEEP COPYRIGHT_SERVICE_LABEL 581b53ae6f0fb8a0cc30c73b46bc3441
BELONGS ya.make
@@ -226,7 +226,7 @@ BELONGS ya.make
Match type : COPYRIGHT
Files with this license:
expat.h [9:18]
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
KEEP COPYRIGHT_SERVICE_LABEL 6451d5e490271b354ad3b567c7a03423
BELONGS ya.make
@@ -236,7 +236,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
KEEP COPYRIGHT_SERVICE_LABEL 660431f3ef648d1a8e72ca1d307af738
BELONGS ya.make
@@ -246,7 +246,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
KEEP COPYRIGHT_SERVICE_LABEL 671a3fd18ec8f4a472b12e1ee2d0c616
BELONGS ya.make
@@ -276,7 +276,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
KEEP COPYRIGHT_SERVICE_LABEL 7c09099ef5f35bf3be4611e6cbb14510
BELONGS ya.make
@@ -286,7 +286,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmltok.c [9:24]
+ lib/xmltok.c [9:24]
KEEP COPYRIGHT_SERVICE_LABEL 8cba36e37749b7d96d8bc8a7b47d0f6f
BELONGS ya.make
@@ -305,10 +305,10 @@ BELONGS ya.make
lib/nametab.h [9:11]
lib/utf8tab.h [9:13]
lib/winconfig.h [9:13]
- lib/xmlparse.c [9:37]
- lib/xmlrole.c [9:19]
+ lib/xmlparse.c [9:37]
+ lib/xmlrole.c [9:19]
lib/xmlrole.h [9:14]
- lib/xmltok.c [9:24]
+ lib/xmltok.c [9:24]
lib/xmltok.h [9:15]
lib/xmltok_impl.c [9:19]
lib/xmltok_impl.h [9:12]
@@ -323,8 +323,8 @@ BELONGS ya.make
Match type : COPYRIGHT
Files with this license:
lib/winconfig.h [9:13]
- lib/xmlrole.c [9:19]
- lib/xmltok.c [9:24]
+ lib/xmlrole.c [9:19]
+ lib/xmltok.c [9:24]
lib/xmltok_ns.c [9:15]
KEEP COPYRIGHT_SERVICE_LABEL 962bda2bd5ce73f8fa7de2620a3507f9
@@ -346,9 +346,9 @@ BELONGS ya.make
Match type : COPYRIGHT
Files with this license:
lib/internal.h [28:34]
- lib/xmlparse.c [9:37]
- lib/xmlrole.c [9:19]
- lib/xmltok.c [9:24]
+ lib/xmlparse.c [9:37]
+ lib/xmlrole.c [9:19]
+ lib/xmltok.c [9:24]
lib/xmltok_impl.c [9:19]
KEEP COPYRIGHT_SERVICE_LABEL 9b3bf60db417b96ccbf65e39aa3d4e63
@@ -359,9 +359,9 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
- lib/xmlrole.c [9:19]
- lib/xmltok.c [9:24]
+ lib/xmlparse.c [9:37]
+ lib/xmlrole.c [9:19]
+ lib/xmltok.c [9:24]
KEEP COPYRIGHT_SERVICE_LABEL 9fdb85dcaaf74d518b27233b48fffa52
BELONGS ya.make
@@ -373,7 +373,7 @@ BELONGS ya.make
Files with this license:
expat.h [9:18]
expat_external.h [9:18]
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
KEEP COPYRIGHT_SERVICE_LABEL a0fdd1392c0b9b2558b9ccfe44592143
BELONGS ya.make
@@ -393,7 +393,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmltok.c [9:24]
+ lib/xmltok.c [9:24]
KEEP COPYRIGHT_SERVICE_LABEL a6a07a1f1768704011ca547d57a193f2
BELONGS ya.make
@@ -403,7 +403,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmltok.c [9:24]
+ lib/xmltok.c [9:24]
KEEP COPYRIGHT_SERVICE_LABEL aab48b38c5f57f26ac27ffebe6ef5ad0
BELONGS ya.make
@@ -413,7 +413,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
KEEP COPYRIGHT_SERVICE_LABEL aafe06df8255f48781ac9d4e96e1ea4e
BELONGS ya.make
@@ -424,8 +424,8 @@ BELONGS ya.make
Match type : COPYRIGHT
Files with this license:
expat.h [9:18]
- lib/xmlparse.c [9:37]
- lib/xmltok.c [9:24]
+ lib/xmlparse.c [9:37]
+ lib/xmltok.c [9:24]
lib/xmltok_impl.c [9:19]
KEEP COPYRIGHT_SERVICE_LABEL abbaf6167a20f6ba0eee322937821c15
@@ -436,7 +436,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
KEEP COPYRIGHT_SERVICE_LABEL ac721fcd634b3e5674a847f5ed2f1c8e
BELONGS ya.make
@@ -447,7 +447,7 @@ BELONGS ya.make
Match type : COPYRIGHT
Files with this license:
expat.h [9:18]
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
KEEP COPYRIGHT_SERVICE_LABEL acbc3573ff7fdf431f94f6aea99de1e0
BELONGS ya.make
@@ -457,7 +457,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
KEEP COPYRIGHT_SERVICE_LABEL b646d644160a51f7f42f9fd9f89d8b3f
BELONGS ya.make
@@ -469,18 +469,18 @@ BELONGS ya.make
Files with this license:
expat_external.h [9:18]
-KEEP COPYRIGHT_SERVICE_LABEL b739d8961ed6fe10ebf48d7f5f06c50c
-BELONGS ya.make
- Note: matched license text is too long. Read it in the source files.
- Scancode info:
- Original SPDX id: COPYRIGHT_SERVICE_LABEL
- Score : 100.00
- Match type : COPYRIGHT
- Files with this license:
- lib/xmlparse.c [9:37]
- lib/xmlrole.c [9:19]
- lib/xmltok.c [9:24]
-
+KEEP COPYRIGHT_SERVICE_LABEL b739d8961ed6fe10ebf48d7f5f06c50c
+BELONGS ya.make
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ lib/xmlparse.c [9:37]
+ lib/xmlrole.c [9:19]
+ lib/xmltok.c [9:24]
+
KEEP COPYRIGHT_SERVICE_LABEL b927d5afef47e3ae01d339429012d6a7
BELONGS ya.make
Note: matched license text is too long. Read it in the source files.
@@ -531,10 +531,10 @@ BELONGS ya.make
lib/iasciitab.h [9:13]
lib/latin1tab.h [9:13]
lib/utf8tab.h [9:13]
- lib/xmlparse.c [9:37]
- lib/xmlrole.c [9:19]
+ lib/xmlparse.c [9:37]
+ lib/xmlrole.c [9:19]
lib/xmlrole.h [9:14]
- lib/xmltok.c [9:24]
+ lib/xmltok.c [9:24]
lib/xmltok.h [9:15]
lib/xmltok_impl.c [9:19]
lib/xmltok_impl.h [9:12]
@@ -548,7 +548,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
KEEP COPYRIGHT_SERVICE_LABEL d548c6beaeae204247905b60d5feff91
BELONGS ya.make
@@ -558,7 +558,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
lib/xmltok_impl.c [9:19]
KEEP COPYRIGHT_SERVICE_LABEL dd3c5623e58aa85a367a6638299f50f3
@@ -569,7 +569,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
KEEP COPYRIGHT_SERVICE_LABEL dfa8addb3a892dd8d176def4d3f0d567
BELONGS ya.make
@@ -581,16 +581,16 @@ BELONGS ya.make
Files with this license:
lib/ascii.h [9:14]
-KEEP COPYRIGHT_SERVICE_LABEL e2f8f506923a26765706e1ad8cc8edc6
-BELONGS ya.make
- Note: matched license text is too long. Read it in the source files.
- Scancode info:
- Original SPDX id: COPYRIGHT_SERVICE_LABEL
- Score : 100.00
- Match type : COPYRIGHT
- Files with this license:
- lib/xmlparse.c [9:37]
-
+KEEP COPYRIGHT_SERVICE_LABEL e2f8f506923a26765706e1ad8cc8edc6
+BELONGS ya.make
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ lib/xmlparse.c [9:37]
+
KEEP COPYRIGHT_SERVICE_LABEL e3d6c1b6030b59aad9996cc0a9efeda5
BELONGS ya.make
Note: matched license text is too long. Read it in the source files.
@@ -599,7 +599,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
KEEP COPYRIGHT_SERVICE_LABEL e8d75752f30998b89994f01f786353a2
BELONGS ya.make
@@ -621,7 +621,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
KEEP COPYRIGHT_SERVICE_LABEL ef0dda0153a00710149f327147a79b7f
BELONGS ya.make
@@ -652,7 +652,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
KEEP COPYRIGHT_SERVICE_LABEL fea018c6e4e19bc6bd4ac263c015567a
BELONGS ya.make
@@ -680,4 +680,4 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- lib/xmlparse.c [9:37]
+ lib/xmlparse.c [9:37]
diff --git a/contrib/libs/expat/.yandex_meta/devtools.licenses.report b/contrib/libs/expat/.yandex_meta/devtools.licenses.report
index 9992a2f2ec..0c5ff0a949 100644
--- a/contrib/libs/expat/.yandex_meta/devtools.licenses.report
+++ b/contrib/libs/expat/.yandex_meta/devtools.licenses.report
@@ -42,7 +42,7 @@ BELONGS ya.make
KEEP MIT 6bb6514a1d779748b76a73215a89ae66
BELONGS ya.make
-FILE_INCLUDE AUTHORS found in files: expat.h at line 34, expat_external.h at line 34, lib/ascii.h at line 30, lib/asciitab.h at line 29, lib/iasciitab.h at line 29, lib/internal.h at line 50, lib/latin1tab.h at line 29, lib/utf8tab.h at line 29, lib/winconfig.h at line 29, lib/xmlparse.c at line 53, lib/xmlrole.c at line 35, lib/xmlrole.h at line 30, lib/xmltok.c at line 40, lib/xmltok.h at line 31, lib/xmltok_impl.c at line 35, lib/xmltok_impl.h at line 28, lib/xmltok_ns.c at line 31
+FILE_INCLUDE AUTHORS found in files: expat.h at line 34, expat_external.h at line 34, lib/ascii.h at line 30, lib/asciitab.h at line 29, lib/iasciitab.h at line 29, lib/internal.h at line 50, lib/latin1tab.h at line 29, lib/utf8tab.h at line 29, lib/winconfig.h at line 29, lib/xmlparse.c at line 53, lib/xmlrole.c at line 35, lib/xmlrole.h at line 30, lib/xmltok.c at line 40, lib/xmltok.h at line 31, lib/xmltok_impl.c at line 35, lib/xmltok_impl.h at line 28, lib/xmltok_ns.c at line 31
Note: matched license text is too long. Read it in the source files.
Scancode info:
Original SPDX id: MIT
@@ -59,10 +59,10 @@ FILE_INCLUDE AUTHORS found in files: expat.h at line 34, expat_external.h at lin
lib/latin1tab.h [15:32]
lib/utf8tab.h [15:32]
lib/winconfig.h [15:32]
- lib/xmlparse.c [39:56]
- lib/xmlrole.c [21:38]
+ lib/xmlparse.c [39:56]
+ lib/xmlrole.c [21:38]
lib/xmlrole.h [16:33]
- lib/xmltok.c [26:43]
+ lib/xmltok.c [26:43]
lib/xmltok.h [17:34]
lib/xmltok_impl.c [21:38]
lib/xmltok_impl.h [14:31]
@@ -100,10 +100,10 @@ BELONGS ya.make
lib/nametab.h [11:11]
lib/utf8tab.h [13:13]
lib/winconfig.h [13:13]
- lib/xmlparse.c [37:37]
- lib/xmlrole.c [19:19]
+ lib/xmlparse.c [37:37]
+ lib/xmlrole.c [19:19]
lib/xmlrole.h [14:14]
- lib/xmltok.c [24:24]
+ lib/xmltok.c [24:24]
lib/xmltok.h [15:15]
lib/xmltok_impl.c [19:19]
lib/xmltok_impl.h [12:12]
diff --git a/contrib/libs/expat/.yandex_meta/licenses.list.txt b/contrib/libs/expat/.yandex_meta/licenses.list.txt
index ed639d7902..9bb32b586e 100644
--- a/contrib/libs/expat/.yandex_meta/licenses.list.txt
+++ b/contrib/libs/expat/.yandex_meta/licenses.list.txt
@@ -55,8 +55,8 @@
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2019-2020 Ben Wagner <bungeman@chromium.org>
Copyright (c) 2019 Vadim Zeitlin <vadim@zeitlins.org>
- Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
- Copyright (c) 2022 Samanta Navarro <ferivoz@riseup.net>
+ Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
+ Copyright (c) 2022 Samanta Navarro <ferivoz@riseup.net>
Licensed under the MIT license:
@@ -75,7 +75,7 @@
Copyright (c) 2017 Benbuck Nason <bnason@netflix.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
- Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
+ Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
Licensed under the MIT license:
diff --git a/contrib/libs/expat/README.md b/contrib/libs/expat/README.md
index 9c9e9e62f3..00e6cca22d 100644
--- a/contrib/libs/expat/README.md
+++ b/contrib/libs/expat/README.md
@@ -1,14 +1,14 @@
-[![Run Linux Travis CI tasks](https://github.com/libexpat/libexpat/actions/workflows/linux.yml/badge.svg)](https://github.com/libexpat/libexpat/actions/workflows/linux.yml)
+[![Run Linux Travis CI tasks](https://github.com/libexpat/libexpat/actions/workflows/linux.yml/badge.svg)](https://github.com/libexpat/libexpat/actions/workflows/linux.yml)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/libexpat/libexpat?svg=true)](https://ci.appveyor.com/project/libexpat/libexpat)
[![Packaging status](https://repology.org/badge/tiny-repos/expat.svg)](https://repology.org/metapackage/expat/versions)
-[![Downloads SourceForge](https://img.shields.io/sourceforge/dt/expat?label=Downloads%20SourceForge)](https://sourceforge.net/projects/expat/files/)
-[![Downloads GitHub](https://img.shields.io/github/downloads/libexpat/libexpat/total?label=Downloads%20GitHub)](https://github.com/libexpat/libexpat/releases)
+[![Downloads SourceForge](https://img.shields.io/sourceforge/dt/expat?label=Downloads%20SourceForge)](https://sourceforge.net/projects/expat/files/)
+[![Downloads GitHub](https://img.shields.io/github/downloads/libexpat/libexpat/total?label=Downloads%20GitHub)](https://github.com/libexpat/libexpat/releases)
-# Expat, Release 2.4.4
+# Expat, Release 2.4.4
This is Expat, a C library for parsing XML, started by
-[James Clark](https://en.wikipedia.org/wiki/James_Clark_%28programmer%29) in 1997.
+[James Clark](https://en.wikipedia.org/wiki/James_Clark_%28programmer%29) in 1997.
Expat is a stream-oriented XML parser. This means that you register
handlers with the parser before starting the parse. These handlers
are called when the parser discovers the associated structures in the
@@ -16,14 +16,14 @@ document being parsed. A start tag is an example of the kind of
structures for which you may register handlers.
Expat supports the following compilers:
-
+
- GNU GCC >=4.5
- LLVM Clang >=3.5
-- Microsoft Visual Studio >=15.0/2017 (rolling `${today} minus 5 years`)
+- Microsoft Visual Studio >=15.0/2017 (rolling `${today} minus 5 years`)
Windows users can use the
-[`expat-win32bin-*.*.*.{exe,zip}` download](https://github.com/libexpat/libexpat/releases),
-which includes both pre-compiled libraries and executables, and source code for
+[`expat-win32bin-*.*.*.{exe,zip}` download](https://github.com/libexpat/libexpat/releases),
+which includes both pre-compiled libraries and executables, and source code for
developers.
Expat is [free software](https://www.gnu.org/philosophy/free-sw.en.html).
@@ -33,67 +33,67 @@ contained in the file
distributed with this package.
This license is the same as the MIT/X Consortium license.
-
-## Using libexpat in your CMake-Based Project
-
-There are two ways of using libexpat with CMake:
-
-### a) Module Mode
-
-This approach leverages CMake's own [module `FindEXPAT`](https://cmake.org/cmake/help/latest/module/FindEXPAT.html).
-
-Notice the *uppercase* `EXPAT` in the following example:
-
-```cmake
-cmake_minimum_required(VERSION 3.0) # or 3.10, see below
-
-project(hello VERSION 1.0.0)
-
-find_package(EXPAT 2.2.8 MODULE REQUIRED)
-
-add_executable(hello
- hello.c
-)
-
-# a) for CMake >=3.10 (see CMake's FindEXPAT docs)
-target_link_libraries(hello PUBLIC EXPAT::EXPAT)
-
-# b) for CMake >=3.0
-target_include_directories(hello PRIVATE ${EXPAT_INCLUDE_DIRS})
-target_link_libraries(hello PUBLIC ${EXPAT_LIBRARIES})
-```
-
-### b) Config Mode
-
-This approach requires files from…
-
-- libexpat >=2.2.8 where packaging uses the CMake build system
-or
-- libexpat >=2.3.0 where packaging uses the GNU Autotools build system
- on Linux
-or
-- libexpat >=2.4.0 where packaging uses the GNU Autotools build system
- on macOS or MinGW.
-
-Notice the *lowercase* `expat` in the following example:
-
-```cmake
-cmake_minimum_required(VERSION 3.0)
-
-project(hello VERSION 1.0.0)
-
-find_package(expat 2.2.8 CONFIG REQUIRED char dtd ns)
-
-add_executable(hello
- hello.c
-)
-
-target_link_libraries(hello PUBLIC expat::expat)
-```
-
-
-## Building from a Git Clone
-
+
+## Using libexpat in your CMake-Based Project
+
+There are two ways of using libexpat with CMake:
+
+### a) Module Mode
+
+This approach leverages CMake's own [module `FindEXPAT`](https://cmake.org/cmake/help/latest/module/FindEXPAT.html).
+
+Notice the *uppercase* `EXPAT` in the following example:
+
+```cmake
+cmake_minimum_required(VERSION 3.0) # or 3.10, see below
+
+project(hello VERSION 1.0.0)
+
+find_package(EXPAT 2.2.8 MODULE REQUIRED)
+
+add_executable(hello
+ hello.c
+)
+
+# a) for CMake >=3.10 (see CMake's FindEXPAT docs)
+target_link_libraries(hello PUBLIC EXPAT::EXPAT)
+
+# b) for CMake >=3.0
+target_include_directories(hello PRIVATE ${EXPAT_INCLUDE_DIRS})
+target_link_libraries(hello PUBLIC ${EXPAT_LIBRARIES})
+```
+
+### b) Config Mode
+
+This approach requires files from…
+
+- libexpat >=2.2.8 where packaging uses the CMake build system
+or
+- libexpat >=2.3.0 where packaging uses the GNU Autotools build system
+ on Linux
+or
+- libexpat >=2.4.0 where packaging uses the GNU Autotools build system
+ on macOS or MinGW.
+
+Notice the *lowercase* `expat` in the following example:
+
+```cmake
+cmake_minimum_required(VERSION 3.0)
+
+project(hello VERSION 1.0.0)
+
+find_package(expat 2.2.8 CONFIG REQUIRED char dtd ns)
+
+add_executable(hello
+ hello.c
+)
+
+target_link_libraries(hello PUBLIC expat::expat)
+```
+
+
+## Building from a Git Clone
+
If you are building Expat from a check-out from the
[Git repository](https://github.com/libexpat/libexpat/),
you need to run a script that generates the configure script using the
@@ -107,11 +107,11 @@ autoconf 2.58 or newer. Run the script like this:
Once this has been done, follow the same instructions as for building
from a source distribution.
-
-## Building from a Source Distribution
-
-### a) Building with the configure script (i.e. GNU Autotools)
-
+
+## Building from a Source Distribution
+
+### a) Building with the configure script (i.e. GNU Autotools)
+
To build Expat from a source distribution, you first run the
configuration shell script in the top level distribution directory:
@@ -201,14 +201,14 @@ A reference manual is available in the file `doc/reference.html` in this
distribution.
-### b) Building with CMake
-
-The CMake build system is still *experimental* and may replace the primary
+### b) Building with CMake
+
+The CMake build system is still *experimental* and may replace the primary
build system based on GNU Autotools at some point when it is ready.
-
-
-#### Available Options
-
+
+
+#### Available Options
+
For an idea of the available (non-advanced) options for building with CMake:
```console
diff --git a/contrib/libs/expat/expat.h b/contrib/libs/expat/expat.h
index 9b662f7e13..4c5704fd93 100644
--- a/contrib/libs/expat/expat.h
+++ b/contrib/libs/expat/expat.h
@@ -7,14 +7,14 @@
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
- Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
- Copyright (c) 2000-2005 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
- Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net>
- Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net>
+ Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
+ Copyright (c) 2000-2005 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
+ Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net>
+ Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
- Copyright (c) 2016 Cristian Rodríguez <crrodriguez@opensuse.org>
- Copyright (c) 2016 Thomas Beutlich <tc@tbeu.de>
- Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
+ Copyright (c) 2016 Cristian Rodríguez <crrodriguez@opensuse.org>
+ Copyright (c) 2016 Thomas Beutlich <tc@tbeu.de>
+ Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -122,11 +122,11 @@ enum XML_Error {
XML_ERROR_RESERVED_PREFIX_XMLNS,
XML_ERROR_RESERVED_NAMESPACE_URI,
/* Added in 2.2.1. */
- XML_ERROR_INVALID_ARGUMENT,
- /* Added in 2.3.0. */
- XML_ERROR_NO_BUFFER,
- /* Added in 2.4.0. */
- XML_ERROR_AMPLIFICATION_LIMIT_BREACH
+ XML_ERROR_INVALID_ARGUMENT,
+ /* Added in 2.3.0. */
+ XML_ERROR_NO_BUFFER,
+ /* Added in 2.4.0. */
+ XML_ERROR_AMPLIFICATION_LIMIT_BREACH
};
enum XML_Content_Type {
@@ -524,7 +524,7 @@ typedef struct {
Otherwise it must return XML_STATUS_ERROR.
If info does not describe a suitable encoding, then the parser will
- return an XML_ERROR_UNKNOWN_ENCODING error.
+ return an XML_ERROR_UNKNOWN_ENCODING error.
*/
typedef int(XMLCALL *XML_UnknownEncodingHandler)(void *encodingHandlerData,
const XML_Char *name,
@@ -1008,10 +1008,10 @@ enum XML_FeatureEnum {
XML_FEATURE_SIZEOF_XML_LCHAR,
XML_FEATURE_NS,
XML_FEATURE_LARGE_SIZE,
- XML_FEATURE_ATTR_INFO,
- /* Added in Expat 2.4.0. */
- XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
- XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT
+ XML_FEATURE_ATTR_INFO,
+ /* Added in Expat 2.4.0. */
+ XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
+ XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT
/* Additional features must be added to the end of this enum. */
};
@@ -1024,24 +1024,24 @@ typedef struct {
XMLPARSEAPI(const XML_Feature *)
XML_GetFeatureList(void);
-#ifdef XML_DTD
-/* Added in Expat 2.4.0. */
-XMLPARSEAPI(XML_Bool)
-XML_SetBillionLaughsAttackProtectionMaximumAmplification(
- XML_Parser parser, float maximumAmplificationFactor);
-
-/* Added in Expat 2.4.0. */
-XMLPARSEAPI(XML_Bool)
-XML_SetBillionLaughsAttackProtectionActivationThreshold(
- XML_Parser parser, unsigned long long activationThresholdBytes);
-#endif
-
+#ifdef XML_DTD
+/* Added in Expat 2.4.0. */
+XMLPARSEAPI(XML_Bool)
+XML_SetBillionLaughsAttackProtectionMaximumAmplification(
+ XML_Parser parser, float maximumAmplificationFactor);
+
+/* Added in Expat 2.4.0. */
+XMLPARSEAPI(XML_Bool)
+XML_SetBillionLaughsAttackProtectionActivationThreshold(
+ XML_Parser parser, unsigned long long activationThresholdBytes);
+#endif
+
/* Expat follows the semantic versioning convention.
See http://semver.org.
*/
#define XML_MAJOR_VERSION 2
-#define XML_MINOR_VERSION 4
-#define XML_MICRO_VERSION 4
+#define XML_MINOR_VERSION 4
+#define XML_MICRO_VERSION 4
#ifdef __cplusplus
}
diff --git a/contrib/libs/expat/expat_config.h b/contrib/libs/expat/expat_config.h
index 6aef1e6f25..8f890fed02 100644
--- a/contrib/libs/expat/expat_config.h
+++ b/contrib/libs/expat/expat_config.h
@@ -37,9 +37,9 @@
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
-/* Define to 1 if you have the <stdio.h> header file. */
-#define HAVE_STDIO_H 1
-
+/* Define to 1 if you have the <stdio.h> header file. */
+#define HAVE_STDIO_H 1
+
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
@@ -77,7 +77,7 @@
#define PACKAGE_NAME "expat"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "expat 2.4.4"
+#define PACKAGE_STRING "expat 2.4.4"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "expat"
@@ -86,15 +86,15 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "2.4.4"
+#define PACKAGE_VERSION "2.4.4"
-/* Define to 1 if all of the C90 standard headers exist (not just the ones
- required in a freestanding environment). This macro is provided for
- backward compatibility; new code need not use it. */
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+ required in a freestanding environment). This macro is provided for
+ backward compatibility; new code need not use it. */
#define STDC_HEADERS 1
/* Version number of package */
-#define VERSION "2.4.4"
+#define VERSION "2.4.4"
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
diff --git a/contrib/libs/expat/expat_external.h b/contrib/libs/expat/expat_external.h
index 0125d676ea..8829f77091 100644
--- a/contrib/libs/expat/expat_external.h
+++ b/contrib/libs/expat/expat_external.h
@@ -7,14 +7,14 @@
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
- Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
- Copyright (c) 2000-2004 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
- Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net>
- Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
- Copyright (c) 2016 Cristian Rodríguez <crrodriguez@opensuse.org>
- Copyright (c) 2016-2019 Sebastian Pipping <sebastian@pipping.org>
- Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
- Copyright (c) 2018 Yury Gribov <tetra2005@gmail.com>
+ Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
+ Copyright (c) 2000-2004 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
+ Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net>
+ Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
+ Copyright (c) 2016 Cristian Rodríguez <crrodriguez@opensuse.org>
+ Copyright (c) 2016-2019 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
+ Copyright (c) 2018 Yury Gribov <tetra2005@gmail.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/contrib/libs/expat/lib/ascii.h b/contrib/libs/expat/lib/ascii.h
index f8701de0d9..1f594d2e54 100644
--- a/contrib/libs/expat/lib/ascii.h
+++ b/contrib/libs/expat/lib/ascii.h
@@ -6,11 +6,11 @@
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
- Copyright (c) 1999-2000 Thai Open Source Software Center Ltd
- Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
- Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
- Copyright (c) 2007 Karl Waclawek <karl@waclawek.net>
- Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 1999-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
+ Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
+ Copyright (c) 2007 Karl Waclawek <karl@waclawek.net>
+ Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/contrib/libs/expat/lib/asciitab.h b/contrib/libs/expat/lib/asciitab.h
index f78b1af276..af766fb247 100644
--- a/contrib/libs/expat/lib/asciitab.h
+++ b/contrib/libs/expat/lib/asciitab.h
@@ -7,9 +7,9 @@
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
- Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
- Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
- Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
+ Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
+ Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/contrib/libs/expat/lib/iasciitab.h b/contrib/libs/expat/lib/iasciitab.h
index e28c46b40c..5d8646f2a3 100644
--- a/contrib/libs/expat/lib/iasciitab.h
+++ b/contrib/libs/expat/lib/iasciitab.h
@@ -7,9 +7,9 @@
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
- Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
- Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
- Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
+ Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
+ Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/contrib/libs/expat/lib/internal.h b/contrib/libs/expat/lib/internal.h
index 4f4e01d468..444eba0fb0 100644
--- a/contrib/libs/expat/lib/internal.h
+++ b/contrib/libs/expat/lib/internal.h
@@ -25,12 +25,12 @@
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
- Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
- Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
- Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
- Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org>
- Copyright (c) 2018 Yury Gribov <tetra2005@gmail.com>
- Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
+ Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
+ Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
+ Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
+ Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 2018 Yury Gribov <tetra2005@gmail.com>
+ Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -105,57 +105,57 @@
# endif
#endif
-#include <limits.h> // ULONG_MAX
-
-#if defined(_WIN32) && ! defined(__USE_MINGW_ANSI_STDIO)
-# define EXPAT_FMT_ULL(midpart) "%" midpart "I64u"
-# if defined(_WIN64) // Note: modifiers "td" and "zu" do not work for MinGW
-# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "I64d"
-# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "I64u"
-# else
-# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "d"
-# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u"
-# endif
-#else
-# define EXPAT_FMT_ULL(midpart) "%" midpart "llu"
-# if ! defined(ULONG_MAX)
-# error Compiler did not define ULONG_MAX for us
-# elif ULONG_MAX == 18446744073709551615u // 2^64-1
-# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "ld"
-# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "lu"
-# else
-# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "d"
-# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u"
-# endif
-#endif
-
+#include <limits.h> // ULONG_MAX
+
+#if defined(_WIN32) && ! defined(__USE_MINGW_ANSI_STDIO)
+# define EXPAT_FMT_ULL(midpart) "%" midpart "I64u"
+# if defined(_WIN64) // Note: modifiers "td" and "zu" do not work for MinGW
+# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "I64d"
+# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "I64u"
+# else
+# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "d"
+# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u"
+# endif
+#else
+# define EXPAT_FMT_ULL(midpart) "%" midpart "llu"
+# if ! defined(ULONG_MAX)
+# error Compiler did not define ULONG_MAX for us
+# elif ULONG_MAX == 18446744073709551615u // 2^64-1
+# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "ld"
+# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "lu"
+# else
+# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "d"
+# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u"
+# endif
+#endif
+
#ifndef UNUSED_P
# define UNUSED_P(p) (void)p
#endif
-/* NOTE BEGIN If you ever patch these defaults to greater values
- for non-attack XML payload in your environment,
- please file a bug report with libexpat. Thank you!
-*/
-#define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT \
- 100.0f
-#define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT \
- 8388608 // 8 MiB, 2^23
-/* NOTE END */
-
-#include "expat.h" // so we can use type XML_Parser below
-
+/* NOTE BEGIN If you ever patch these defaults to greater values
+ for non-attack XML payload in your environment,
+ please file a bug report with libexpat. Thank you!
+*/
+#define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT \
+ 100.0f
+#define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT \
+ 8388608 // 8 MiB, 2^23
+/* NOTE END */
+
+#include "expat.h" // so we can use type XML_Parser below
+
#ifdef __cplusplus
extern "C" {
#endif
-void _INTERNAL_trim_to_complete_utf8_characters(const char *from,
- const char **fromLimRef);
-
-#if defined(XML_DTD)
-unsigned long long testingAccountingGetCountBytesDirect(XML_Parser parser);
-unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser);
-const char *unsignedCharToPrintable(unsigned char c);
+void _INTERNAL_trim_to_complete_utf8_characters(const char *from,
+ const char **fromLimRef);
+
+#if defined(XML_DTD)
+unsigned long long testingAccountingGetCountBytesDirect(XML_Parser parser);
+unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser);
+const char *unsignedCharToPrintable(unsigned char c);
#endif
#ifdef __cplusplus
diff --git a/contrib/libs/expat/lib/latin1tab.h b/contrib/libs/expat/lib/latin1tab.h
index 9d279575eb..b681d278af 100644
--- a/contrib/libs/expat/lib/latin1tab.h
+++ b/contrib/libs/expat/lib/latin1tab.h
@@ -7,9 +7,9 @@
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
- Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
- Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
- Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
+ Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
+ Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/contrib/libs/expat/lib/nametab.h b/contrib/libs/expat/lib/nametab.h
index cdfe788b3c..63485446b9 100644
--- a/contrib/libs/expat/lib/nametab.h
+++ b/contrib/libs/expat/lib/nametab.h
@@ -6,8 +6,8 @@
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
- Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
- Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
+ Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/contrib/libs/expat/lib/siphash.h b/contrib/libs/expat/lib/siphash.h
index 16a86644a1..e5406d7ee9 100644
--- a/contrib/libs/expat/lib/siphash.h
+++ b/contrib/libs/expat/lib/siphash.h
@@ -11,9 +11,9 @@
* --------------------------------------------------------------------------
* HISTORY:
*
- * 2020-10-03 (Sebastian Pipping)
- * - Drop support for Visual Studio 9.0/2008 and earlier
- *
+ * 2020-10-03 (Sebastian Pipping)
+ * - Drop support for Visual Studio 9.0/2008 and earlier
+ *
* 2019-08-03 (Sebastian Pipping)
* - Mark part of sip24_valid as to be excluded from clang-format
* - Re-format code using clang-format 9
@@ -99,7 +99,7 @@
#define SIPHASH_H
#include <stddef.h> /* size_t */
-#include <stdint.h> /* uint64_t uint32_t uint8_t */
+#include <stdint.h> /* uint64_t uint32_t uint8_t */
/*
* Workaround to not require a C++11 compiler for using ULL suffix
diff --git a/contrib/libs/expat/lib/utf8tab.h b/contrib/libs/expat/lib/utf8tab.h
index 9bae0c8103..88efcf91cc 100644
--- a/contrib/libs/expat/lib/utf8tab.h
+++ b/contrib/libs/expat/lib/utf8tab.h
@@ -7,9 +7,9 @@
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
- Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
- Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
- Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
+ Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
+ Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/contrib/libs/expat/lib/winconfig.h b/contrib/libs/expat/lib/winconfig.h
index e867bd6659..2ecd61b5b9 100644
--- a/contrib/libs/expat/lib/winconfig.h
+++ b/contrib/libs/expat/lib/winconfig.h
@@ -6,10 +6,10 @@
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
- Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
- Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net>
- Copyright (c) 2005 Karl Waclawek <karl@waclawek.net>
- Copyright (c) 2017-2021 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
+ Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net>
+ Copyright (c) 2005 Karl Waclawek <karl@waclawek.net>
+ Copyright (c) 2017-2021 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/contrib/libs/expat/lib/xmlparse.c b/contrib/libs/expat/lib/xmlparse.c
index 9a52226cf9..db0efbab0f 100644
--- a/contrib/libs/expat/lib/xmlparse.c
+++ b/contrib/libs/expat/lib/xmlparse.c
@@ -1,4 +1,4 @@
-/* 2e2c8ce5f11a473d65ec313ab20ceee6afefb355f5405afc06e7204e2e41c8c0 (2.4.4+)
+/* 2e2c8ce5f11a473d65ec313ab20ceee6afefb355f5405afc06e7204e2e41c8c0 (2.4.4+)
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
@@ -7,33 +7,33 @@
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
- Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
- Copyright (c) 2000-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
- Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net>
- Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net>
- Copyright (c) 2005-2009 Steven Solie <ssolie@users.sourceforge.net>
- Copyright (c) 2016 Eric Rahm <erahm@mozilla.com>
+ Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
+ Copyright (c) 2000-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
+ Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net>
+ Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net>
+ Copyright (c) 2005-2009 Steven Solie <ssolie@users.sourceforge.net>
+ Copyright (c) 2016 Eric Rahm <erahm@mozilla.com>
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
- Copyright (c) 2016 Gaurav <g.gupta@samsung.com>
- Copyright (c) 2016 Thomas Beutlich <tc@tbeu.de>
- Copyright (c) 2016 Gustavo Grieco <gustavo.grieco@imag.fr>
- Copyright (c) 2016 Pascal Cuoq <cuoq@trust-in-soft.com>
- Copyright (c) 2016 Ed Schouten <ed@nuxi.nl>
- Copyright (c) 2017-2018 Rhodri James <rhodri@wildebeest.org.uk>
- Copyright (c) 2017 Václav Slavík <vaclav@slavik.io>
- Copyright (c) 2017 Viktor Szakats <commit@vsz.me>
- Copyright (c) 2017 Chanho Park <chanho61.park@samsung.com>
- Copyright (c) 2017 Rolf Eike Beer <eike@sf-mail.de>
- Copyright (c) 2017 Hans Wennborg <hans@chromium.org>
- Copyright (c) 2018 Anton Maklakov <antmak.pub@gmail.com>
- Copyright (c) 2018 Benjamin Peterson <benjamin@python.org>
- Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
- Copyright (c) 2018 Mariusz Zaborski <oshogbo@vexillium.org>
- Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
- Copyright (c) 2019-2020 Ben Wagner <bungeman@chromium.org>
- Copyright (c) 2019 Vadim Zeitlin <vadim@zeitlins.org>
- Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
- Copyright (c) 2022 Samanta Navarro <ferivoz@riseup.net>
+ Copyright (c) 2016 Gaurav <g.gupta@samsung.com>
+ Copyright (c) 2016 Thomas Beutlich <tc@tbeu.de>
+ Copyright (c) 2016 Gustavo Grieco <gustavo.grieco@imag.fr>
+ Copyright (c) 2016 Pascal Cuoq <cuoq@trust-in-soft.com>
+ Copyright (c) 2016 Ed Schouten <ed@nuxi.nl>
+ Copyright (c) 2017-2018 Rhodri James <rhodri@wildebeest.org.uk>
+ Copyright (c) 2017 Václav Slavík <vaclav@slavik.io>
+ Copyright (c) 2017 Viktor Szakats <commit@vsz.me>
+ Copyright (c) 2017 Chanho Park <chanho61.park@samsung.com>
+ Copyright (c) 2017 Rolf Eike Beer <eike@sf-mail.de>
+ Copyright (c) 2017 Hans Wennborg <hans@chromium.org>
+ Copyright (c) 2018 Anton Maklakov <antmak.pub@gmail.com>
+ Copyright (c) 2018 Benjamin Peterson <benjamin@python.org>
+ Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
+ Copyright (c) 2018 Mariusz Zaborski <oshogbo@vexillium.org>
+ Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
+ Copyright (c) 2019-2020 Ben Wagner <bungeman@chromium.org>
+ Copyright (c) 2019 Vadim Zeitlin <vadim@zeitlins.org>
+ Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
+ Copyright (c) 2022 Samanta Navarro <ferivoz@riseup.net>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -56,10 +56,10 @@
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#define XML_BUILDING_EXPAT 1
-
-#include <expat_config.h>
-
+#define XML_BUILDING_EXPAT 1
+
+#include <expat_config.h>
+
#if ! defined(_GNU_SOURCE)
# define _GNU_SOURCE 1 /* syscall prototype */
#endif
@@ -77,8 +77,8 @@
#include <limits.h> /* UINT_MAX */
#include <stdio.h> /* fprintf */
#include <stdlib.h> /* getenv, rand_s */
-#include <stdint.h> /* uintptr_t */
-#include <math.h> /* isnan */
+#include <stdint.h> /* uintptr_t */
+#include <math.h> /* isnan */
#ifdef _WIN32
# define getpid GetCurrentProcessId
@@ -92,7 +92,7 @@
#ifdef _WIN32
# include "winconfig.h"
-#endif
+#endif
#include "ascii.h"
#include "expat.h"
@@ -399,31 +399,31 @@ typedef struct open_internal_entity {
XML_Bool betweenDecl; /* WFC: PE Between Declarations */
} OPEN_INTERNAL_ENTITY;
-enum XML_Account {
- XML_ACCOUNT_DIRECT, /* bytes directly passed to the Expat parser */
- XML_ACCOUNT_ENTITY_EXPANSION, /* intermediate bytes produced during entity
- expansion */
- XML_ACCOUNT_NONE /* i.e. do not account, was accounted already */
-};
-
-#ifdef XML_DTD
-typedef unsigned long long XmlBigCount;
-typedef struct accounting {
- XmlBigCount countBytesDirect;
- XmlBigCount countBytesIndirect;
- int debugLevel;
- float maximumAmplificationFactor; // >=1.0
- unsigned long long activationThresholdBytes;
-} ACCOUNTING;
-
-typedef struct entity_stats {
- unsigned int countEverOpened;
- unsigned int currentDepth;
- unsigned int maximumDepthSeen;
- int debugLevel;
-} ENTITY_STATS;
-#endif /* XML_DTD */
-
+enum XML_Account {
+ XML_ACCOUNT_DIRECT, /* bytes directly passed to the Expat parser */
+ XML_ACCOUNT_ENTITY_EXPANSION, /* intermediate bytes produced during entity
+ expansion */
+ XML_ACCOUNT_NONE /* i.e. do not account, was accounted already */
+};
+
+#ifdef XML_DTD
+typedef unsigned long long XmlBigCount;
+typedef struct accounting {
+ XmlBigCount countBytesDirect;
+ XmlBigCount countBytesIndirect;
+ int debugLevel;
+ float maximumAmplificationFactor; // >=1.0
+ unsigned long long activationThresholdBytes;
+} ACCOUNTING;
+
+typedef struct entity_stats {
+ unsigned int countEverOpened;
+ unsigned int currentDepth;
+ unsigned int maximumDepthSeen;
+ int debugLevel;
+} ENTITY_STATS;
+#endif /* XML_DTD */
+
typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start,
const char *end, const char **endPtr);
@@ -454,18 +454,18 @@ static enum XML_Error initializeEncoding(XML_Parser parser);
static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc,
const char *s, const char *end, int tok,
const char *next, const char **nextPtr,
- XML_Bool haveMore, XML_Bool allowClosingDoctype,
- enum XML_Account account);
+ XML_Bool haveMore, XML_Bool allowClosingDoctype,
+ enum XML_Account account);
static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity,
XML_Bool betweenDecl);
static enum XML_Error doContent(XML_Parser parser, int startTagLevel,
const ENCODING *enc, const char *start,
const char *end, const char **endPtr,
- XML_Bool haveMore, enum XML_Account account);
+ XML_Bool haveMore, enum XML_Account account);
static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *,
const char **startPtr, const char *end,
- const char **nextPtr, XML_Bool haveMore,
- enum XML_Account account);
+ const char **nextPtr, XML_Bool haveMore,
+ enum XML_Account account);
#ifdef XML_DTD
static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *,
const char **startPtr, const char *end,
@@ -475,8 +475,8 @@ static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *,
static void freeBindings(XML_Parser parser, BINDING *bindings);
static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *,
const char *s, TAG_NAME *tagNamePtr,
- BINDING **bindingsPtr,
- enum XML_Account account);
+ BINDING **bindingsPtr,
+ enum XML_Account account);
static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix,
const ATTRIBUTE_ID *attId, const XML_Char *uri,
BINDING **bindingsPtr);
@@ -485,18 +485,18 @@ static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
XML_Parser parser);
static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *,
XML_Bool isCdata, const char *,
- const char *, STRING_POOL *,
- enum XML_Account account);
+ const char *, STRING_POOL *,
+ enum XML_Account account);
static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *,
XML_Bool isCdata, const char *,
- const char *, STRING_POOL *,
- enum XML_Account account);
+ const char *, STRING_POOL *,
+ enum XML_Account account);
static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc,
const char *start, const char *end);
static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc,
- const char *start, const char *end,
- enum XML_Account account);
+ const char *start, const char *end,
+ enum XML_Account account);
static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
const char *start, const char *end);
static int reportComment(XML_Parser parser, const ENCODING *enc,
@@ -560,34 +560,34 @@ static XML_Parser parserCreate(const XML_Char *encodingName,
static void parserInit(XML_Parser parser, const XML_Char *encodingName);
-#ifdef XML_DTD
-static float accountingGetCurrentAmplification(XML_Parser rootParser);
-static void accountingReportStats(XML_Parser originParser, const char *epilog);
-static void accountingOnAbort(XML_Parser originParser);
-static void accountingReportDiff(XML_Parser rootParser,
- unsigned int levelsAwayFromRootParser,
- const char *before, const char *after,
- ptrdiff_t bytesMore, int source_line,
- enum XML_Account account);
-static XML_Bool accountingDiffTolerated(XML_Parser originParser, int tok,
- const char *before, const char *after,
- int source_line,
- enum XML_Account account);
-
-static void entityTrackingReportStats(XML_Parser parser, ENTITY *entity,
- const char *action, int sourceLine);
-static void entityTrackingOnOpen(XML_Parser parser, ENTITY *entity,
- int sourceLine);
-static void entityTrackingOnClose(XML_Parser parser, ENTITY *entity,
- int sourceLine);
-
-static XML_Parser getRootParserOf(XML_Parser parser,
- unsigned int *outLevelDiff);
-#endif /* XML_DTD */
-
-static unsigned long getDebugLevel(const char *variableName,
- unsigned long defaultDebugLevel);
-
+#ifdef XML_DTD
+static float accountingGetCurrentAmplification(XML_Parser rootParser);
+static void accountingReportStats(XML_Parser originParser, const char *epilog);
+static void accountingOnAbort(XML_Parser originParser);
+static void accountingReportDiff(XML_Parser rootParser,
+ unsigned int levelsAwayFromRootParser,
+ const char *before, const char *after,
+ ptrdiff_t bytesMore, int source_line,
+ enum XML_Account account);
+static XML_Bool accountingDiffTolerated(XML_Parser originParser, int tok,
+ const char *before, const char *after,
+ int source_line,
+ enum XML_Account account);
+
+static void entityTrackingReportStats(XML_Parser parser, ENTITY *entity,
+ const char *action, int sourceLine);
+static void entityTrackingOnOpen(XML_Parser parser, ENTITY *entity,
+ int sourceLine);
+static void entityTrackingOnClose(XML_Parser parser, ENTITY *entity,
+ int sourceLine);
+
+static XML_Parser getRootParserOf(XML_Parser parser,
+ unsigned int *outLevelDiff);
+#endif /* XML_DTD */
+
+static unsigned long getDebugLevel(const char *variableName,
+ unsigned long defaultDebugLevel);
+
#define poolStart(pool) ((pool)->start)
#define poolEnd(pool) ((pool)->ptr)
#define poolLength(pool) ((pool)->ptr - (pool)->start)
@@ -701,10 +701,10 @@ struct XML_ParserStruct {
enum XML_ParamEntityParsing m_paramEntityParsing;
#endif
unsigned long m_hash_secret_salt;
-#ifdef XML_DTD
- ACCOUNTING m_accounting;
- ENTITY_STATS m_entity_stats;
-#endif
+#ifdef XML_DTD
+ ACCOUNTING m_accounting;
+ ENTITY_STATS m_entity_stats;
+#endif
};
#define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s)))
@@ -889,8 +889,8 @@ gather_time_entropy(void) {
static unsigned long
ENTROPY_DEBUG(const char *label, unsigned long entropy) {
- if (getDebugLevel("EXPAT_ENTROPY_DEBUG", 0) >= 1u) {
- fprintf(stderr, "expat: Entropy: %s --> 0x%0*lx (%lu bytes)\n", label,
+ if (getDebugLevel("EXPAT_ENTROPY_DEBUG", 0) >= 1u) {
+ fprintf(stderr, "expat: Entropy: %s --> 0x%0*lx (%lu bytes)\n", label,
(int)sizeof(entropy) * 2, entropy, (unsigned long)sizeof(entropy));
}
return entropy;
@@ -975,7 +975,7 @@ parserCreate(const XML_Char *encodingName,
if (memsuite) {
XML_Memory_Handling_Suite *mtemp;
- parser = memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
+ parser = memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
if (parser != NULL) {
mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
mtemp->malloc_fcn = memsuite->malloc_fcn;
@@ -1152,18 +1152,18 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) {
parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
#endif
parser->m_hash_secret_salt = 0;
-
-#ifdef XML_DTD
- memset(&parser->m_accounting, 0, sizeof(ACCOUNTING));
- parser->m_accounting.debugLevel = getDebugLevel("EXPAT_ACCOUNTING_DEBUG", 0u);
- parser->m_accounting.maximumAmplificationFactor
- = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT;
- parser->m_accounting.activationThresholdBytes
- = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT;
-
- memset(&parser->m_entity_stats, 0, sizeof(ENTITY_STATS));
- parser->m_entity_stats.debugLevel = getDebugLevel("EXPAT_ENTITY_DEBUG", 0u);
-#endif
+
+#ifdef XML_DTD
+ memset(&parser->m_accounting, 0, sizeof(ACCOUNTING));
+ parser->m_accounting.debugLevel = getDebugLevel("EXPAT_ACCOUNTING_DEBUG", 0u);
+ parser->m_accounting.maximumAmplificationFactor
+ = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT;
+ parser->m_accounting.activationThresholdBytes
+ = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT;
+
+ memset(&parser->m_entity_stats, 0, sizeof(ENTITY_STATS));
+ parser->m_entity_stats.debugLevel = getDebugLevel("EXPAT_ENTITY_DEBUG", 0u);
+#endif
}
/* moves list of bindings to m_freeBindingList */
@@ -1984,12 +1984,12 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal) {
parser->m_errorCode = XML_ERROR_FINISHED;
return XML_STATUS_ERROR;
case XML_INITIALIZED:
- /* Has someone called XML_GetBuffer successfully before? */
- if (! parser->m_bufferPtr) {
- parser->m_errorCode = XML_ERROR_NO_BUFFER;
- return XML_STATUS_ERROR;
- }
-
+ /* Has someone called XML_GetBuffer successfully before? */
+ if (! parser->m_bufferPtr) {
+ parser->m_errorCode = XML_ERROR_NO_BUFFER;
+ return XML_STATUS_ERROR;
+ }
+
if (parser->m_parentParser == NULL && ! startParsing(parser)) {
parser->m_errorCode = XML_ERROR_NO_MEMORY;
return XML_STATUS_ERROR;
@@ -2068,11 +2068,11 @@ XML_GetBuffer(XML_Parser parser, int len) {
keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer);
if (keep > XML_CONTEXT_BYTES)
keep = XML_CONTEXT_BYTES;
- /* Detect and prevent integer overflow */
- if (keep > INT_MAX - neededSize) {
- parser->m_errorCode = XML_ERROR_NO_MEMORY;
- return NULL;
- }
+ /* Detect and prevent integer overflow */
+ if (keep > INT_MAX - neededSize) {
+ parser->m_errorCode = XML_ERROR_NO_MEMORY;
+ return NULL;
+ }
neededSize += keep;
#endif /* defined XML_CONTEXT_BYTES */
if (neededSize
@@ -2439,14 +2439,14 @@ XML_ErrorString(enum XML_Error code) {
/* Added in 2.2.5. */
case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */
return XML_L("invalid argument");
- /* Added in 2.3.0. */
- case XML_ERROR_NO_BUFFER:
- return XML_L(
- "a successful prior call to function XML_GetBuffer is required");
- /* Added in 2.4.0. */
- case XML_ERROR_AMPLIFICATION_LIMIT_BREACH:
- return XML_L(
- "limit on input amplification factor (from DTD and entities) breached");
+ /* Added in 2.3.0. */
+ case XML_ERROR_NO_BUFFER:
+ return XML_L(
+ "a successful prior call to function XML_GetBuffer is required");
+ /* Added in 2.4.0. */
+ case XML_ERROR_AMPLIFICATION_LIMIT_BREACH:
+ return XML_L(
+ "limit on input amplification factor (from DTD and entities) breached");
}
return NULL;
}
@@ -2483,75 +2483,75 @@ XML_ExpatVersionInfo(void) {
const XML_Feature *XMLCALL
XML_GetFeatureList(void) {
- static const XML_Feature features[] = {
- {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
- sizeof(XML_Char)},
- {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
- sizeof(XML_LChar)},
+ static const XML_Feature features[] = {
+ {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
+ sizeof(XML_Char)},
+ {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
+ sizeof(XML_LChar)},
#ifdef XML_UNICODE
- {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
+ {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
#endif
#ifdef XML_UNICODE_WCHAR_T
- {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
+ {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
#endif
#ifdef XML_DTD
- {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
+ {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
#endif
#ifdef XML_CONTEXT_BYTES
- {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
- XML_CONTEXT_BYTES},
+ {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
+ XML_CONTEXT_BYTES},
#endif
#ifdef XML_MIN_SIZE
- {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
+ {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
#endif
#ifdef XML_NS
- {XML_FEATURE_NS, XML_L("XML_NS"), 0},
+ {XML_FEATURE_NS, XML_L("XML_NS"), 0},
#endif
#ifdef XML_LARGE_SIZE
- {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
+ {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
#endif
#ifdef XML_ATTR_INFO
- {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
+ {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
+#endif
+#ifdef XML_DTD
+ /* Added in Expat 2.4.0. */
+ {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
+ XML_L("XML_BLAP_MAX_AMP"),
+ (long int)
+ EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT},
+ {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT,
+ XML_L("XML_BLAP_ACT_THRES"),
+ EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT},
#endif
-#ifdef XML_DTD
- /* Added in Expat 2.4.0. */
- {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
- XML_L("XML_BLAP_MAX_AMP"),
- (long int)
- EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT},
- {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT,
- XML_L("XML_BLAP_ACT_THRES"),
- EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT},
-#endif
- {XML_FEATURE_END, NULL, 0}};
+ {XML_FEATURE_END, NULL, 0}};
return features;
}
-#ifdef XML_DTD
-XML_Bool XMLCALL
-XML_SetBillionLaughsAttackProtectionMaximumAmplification(
- XML_Parser parser, float maximumAmplificationFactor) {
- if ((parser == NULL) || (parser->m_parentParser != NULL)
- || isnan(maximumAmplificationFactor)
- || (maximumAmplificationFactor < 1.0f)) {
- return XML_FALSE;
- }
- parser->m_accounting.maximumAmplificationFactor = maximumAmplificationFactor;
- return XML_TRUE;
-}
-
-XML_Bool XMLCALL
-XML_SetBillionLaughsAttackProtectionActivationThreshold(
- XML_Parser parser, unsigned long long activationThresholdBytes) {
- if ((parser == NULL) || (parser->m_parentParser != NULL)) {
- return XML_FALSE;
- }
- parser->m_accounting.activationThresholdBytes = activationThresholdBytes;
- return XML_TRUE;
-}
-#endif /* XML_DTD */
-
+#ifdef XML_DTD
+XML_Bool XMLCALL
+XML_SetBillionLaughsAttackProtectionMaximumAmplification(
+ XML_Parser parser, float maximumAmplificationFactor) {
+ if ((parser == NULL) || (parser->m_parentParser != NULL)
+ || isnan(maximumAmplificationFactor)
+ || (maximumAmplificationFactor < 1.0f)) {
+ return XML_FALSE;
+ }
+ parser->m_accounting.maximumAmplificationFactor = maximumAmplificationFactor;
+ return XML_TRUE;
+}
+
+XML_Bool XMLCALL
+XML_SetBillionLaughsAttackProtectionActivationThreshold(
+ XML_Parser parser, unsigned long long activationThresholdBytes) {
+ if ((parser == NULL) || (parser->m_parentParser != NULL)) {
+ return XML_FALSE;
+ }
+ parser->m_accounting.activationThresholdBytes = activationThresholdBytes;
+ return XML_TRUE;
+}
+#endif /* XML_DTD */
+
/* Initially tag->rawName always points into the parse buffer;
for those TAG instances opened while the current parse buffer was
processed, and not yet closed, we need to store tag->rawName in a more
@@ -2604,9 +2604,9 @@ storeRawNames(XML_Parser parser) {
static enum XML_Error PTRCALL
contentProcessor(XML_Parser parser, const char *start, const char *end,
const char **endPtr) {
- enum XML_Error result = doContent(
- parser, 0, parser->m_encoding, start, end, endPtr,
- (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT);
+ enum XML_Error result = doContent(
+ parser, 0, parser->m_encoding, start, end, endPtr,
+ (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT);
if (result == XML_ERROR_NONE) {
if (! storeRawNames(parser))
return XML_ERROR_NO_MEMORY;
@@ -2631,14 +2631,14 @@ externalEntityInitProcessor2(XML_Parser parser, const char *start,
int tok = XmlContentTok(parser->m_encoding, start, end, &next);
switch (tok) {
case XML_TOK_BOM:
-#ifdef XML_DTD
- if (! accountingDiffTolerated(parser, tok, start, next, __LINE__,
- XML_ACCOUNT_DIRECT)) {
- accountingOnAbort(parser);
- return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
- }
-#endif /* XML_DTD */
-
+#ifdef XML_DTD
+ if (! accountingDiffTolerated(parser, tok, start, next, __LINE__,
+ XML_ACCOUNT_DIRECT)) {
+ accountingOnAbort(parser);
+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
+ }
+#endif /* XML_DTD */
+
/* If we are at the end of the buffer, this would cause the next stage,
i.e. externalEntityInitProcessor3, to pass control directly to
doContent (by detecting XML_TOK_NONE) without processing any xml text
@@ -2676,10 +2676,10 @@ externalEntityInitProcessor3(XML_Parser parser, const char *start,
const char *next = start; /* XmlContentTok doesn't always set the last arg */
parser->m_eventPtr = start;
tok = XmlContentTok(parser->m_encoding, start, end, &next);
- /* Note: These bytes are accounted later in:
- - processXmlDecl
- - externalEntityContentProcessor
- */
+ /* Note: These bytes are accounted later in:
+ - processXmlDecl
+ - externalEntityContentProcessor
+ */
parser->m_eventEndPtr = next;
switch (tok) {
@@ -2721,8 +2721,8 @@ externalEntityContentProcessor(XML_Parser parser, const char *start,
const char *end, const char **endPtr) {
enum XML_Error result
= doContent(parser, 1, parser->m_encoding, start, end, endPtr,
- (XML_Bool)! parser->m_parsingStatus.finalBuffer,
- XML_ACCOUNT_ENTITY_EXPANSION);
+ (XML_Bool)! parser->m_parsingStatus.finalBuffer,
+ XML_ACCOUNT_ENTITY_EXPANSION);
if (result == XML_ERROR_NONE) {
if (! storeRawNames(parser))
return XML_ERROR_NO_MEMORY;
@@ -2733,7 +2733,7 @@ externalEntityContentProcessor(XML_Parser parser, const char *start,
static enum XML_Error
doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
const char *s, const char *end, const char **nextPtr,
- XML_Bool haveMore, enum XML_Account account) {
+ XML_Bool haveMore, enum XML_Account account) {
/* save one level of indirection */
DTD *const dtd = parser->m_dtd;
@@ -2751,17 +2751,17 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
for (;;) {
const char *next = s; /* XmlContentTok doesn't always set the last arg */
int tok = XmlContentTok(enc, s, end, &next);
-#ifdef XML_DTD
- const char *accountAfter
- = ((tok == XML_TOK_TRAILING_RSQB) || (tok == XML_TOK_TRAILING_CR))
- ? (haveMore ? s /* i.e. 0 bytes */ : end)
- : next;
- if (! accountingDiffTolerated(parser, tok, s, accountAfter, __LINE__,
- account)) {
- accountingOnAbort(parser);
- return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
- }
-#endif
+#ifdef XML_DTD
+ const char *accountAfter
+ = ((tok == XML_TOK_TRAILING_RSQB) || (tok == XML_TOK_TRAILING_CR))
+ ? (haveMore ? s /* i.e. 0 bytes */ : end)
+ : next;
+ if (! accountingDiffTolerated(parser, tok, s, accountAfter, __LINE__,
+ account)) {
+ accountingOnAbort(parser);
+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
+ }
+#endif
*eventEndPP = next;
switch (tok) {
case XML_TOK_TRAILING_CR:
@@ -2817,14 +2817,14 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
XML_Char ch = (XML_Char)XmlPredefinedEntityName(
enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
if (ch) {
-#ifdef XML_DTD
- /* NOTE: We are replacing 4-6 characters original input for 1 character
- * so there is no amplification and hence recording without
- * protection. */
- accountingDiffTolerated(parser, tok, (char *)&ch,
- ((char *)&ch) + sizeof(XML_Char), __LINE__,
- XML_ACCOUNT_ENTITY_EXPANSION);
-#endif /* XML_DTD */
+#ifdef XML_DTD
+ /* NOTE: We are replacing 4-6 characters original input for 1 character
+ * so there is no amplification and hence recording without
+ * protection. */
+ accountingDiffTolerated(parser, tok, (char *)&ch,
+ ((char *)&ch) + sizeof(XML_Char), __LINE__,
+ XML_ACCOUNT_ENTITY_EXPANSION);
+#endif /* XML_DTD */
if (parser->m_characterDataHandler)
parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1);
else if (parser->m_defaultHandler)
@@ -2943,8 +2943,8 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
}
tag->name.str = (XML_Char *)tag->buf;
*toPtr = XML_T('\0');
- result
- = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings), account);
+ result
+ = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings), account);
if (result)
return result;
if (parser->m_startElementHandler)
@@ -2968,8 +2968,8 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
if (! name.str)
return XML_ERROR_NO_MEMORY;
poolFinish(&parser->m_tempPool);
- result = storeAtts(parser, enc, s, &name, &bindings,
- XML_ACCOUNT_NONE /* token spans whole start tag */);
+ result = storeAtts(parser, enc, s, &name, &bindings,
+ XML_ACCOUNT_NONE /* token spans whole start tag */);
if (result != XML_ERROR_NONE) {
freeBindings(parser, bindings);
return result;
@@ -3104,8 +3104,8 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
/* END disabled code */
else if (parser->m_defaultHandler)
reportDefault(parser, enc, s, next);
- result
- = doCdataSection(parser, enc, &next, end, nextPtr, haveMore, account);
+ result
+ = doCdataSection(parser, enc, &next, end, nextPtr, haveMore, account);
if (result != XML_ERROR_NONE)
return result;
else if (! next) {
@@ -3234,8 +3234,8 @@ freeBindings(XML_Parser parser, BINDING *bindings) {
*/
static enum XML_Error
storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
- TAG_NAME *tagNamePtr, BINDING **bindingsPtr,
- enum XML_Account account) {
+ TAG_NAME *tagNamePtr, BINDING **bindingsPtr,
+ enum XML_Account account) {
DTD *const dtd = parser->m_dtd; /* save one level of indirection */
ELEMENT_TYPE *elementType;
int nDefaultAtts;
@@ -3381,7 +3381,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
/* normalize the attribute value */
result = storeAttributeValue(
parser, enc, isCdata, parser->m_atts[i].valuePtr,
- parser->m_atts[i].valueEnd, &parser->m_tempPool, account);
+ parser->m_atts[i].valueEnd, &parser->m_tempPool, account);
if (result)
return result;
appAtts[attIndex] = poolStart(&parser->m_tempPool);
@@ -3849,9 +3849,9 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
static enum XML_Error PTRCALL
cdataSectionProcessor(XML_Parser parser, const char *start, const char *end,
const char **endPtr) {
- enum XML_Error result = doCdataSection(
- parser, parser->m_encoding, &start, end, endPtr,
- (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT);
+ enum XML_Error result = doCdataSection(
+ parser, parser->m_encoding, &start, end, endPtr,
+ (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT);
if (result != XML_ERROR_NONE)
return result;
if (start) {
@@ -3871,8 +3871,8 @@ cdataSectionProcessor(XML_Parser parser, const char *start, const char *end,
*/
static enum XML_Error
doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
- const char *end, const char **nextPtr, XML_Bool haveMore,
- enum XML_Account account) {
+ const char *end, const char **nextPtr, XML_Bool haveMore,
+ enum XML_Account account) {
const char *s = *startPtr;
const char **eventPP;
const char **eventEndPP;
@@ -3890,14 +3890,14 @@ doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
for (;;) {
const char *next = s; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */
int tok = XmlCdataSectionTok(enc, s, end, &next);
-#ifdef XML_DTD
- if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) {
- accountingOnAbort(parser);
- return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
- }
-#else
- UNUSED_P(account);
-#endif
+#ifdef XML_DTD
+ if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) {
+ accountingOnAbort(parser);
+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
+ }
+#else
+ UNUSED_P(account);
+#endif
*eventEndPP = next;
switch (tok) {
case XML_TOK_CDATA_SECT_CLOSE:
@@ -4042,13 +4042,13 @@ doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
*eventPP = s;
*startPtr = NULL;
tok = XmlIgnoreSectionTok(enc, s, end, &next);
-# ifdef XML_DTD
- if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
- XML_ACCOUNT_DIRECT)) {
- accountingOnAbort(parser);
- return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
- }
-# endif
+# ifdef XML_DTD
+ if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
+ XML_ACCOUNT_DIRECT)) {
+ accountingOnAbort(parser);
+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
+ }
+# endif
*eventEndPP = next;
switch (tok) {
case XML_TOK_IGNORE_SECT:
@@ -4098,7 +4098,7 @@ initializeEncoding(XML_Parser parser) {
const char *s;
#ifdef XML_UNICODE
char encodingBuf[128];
- /* See comments about `protocolEncodingName` in parserInit() */
+ /* See comments about `protocolEncodingName` in parserInit() */
if (! parser->m_protocolEncodingName)
s = NULL;
else {
@@ -4133,15 +4133,15 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s,
const char *versionend;
const XML_Char *storedversion = NULL;
int standalone = -1;
-
-#ifdef XML_DTD
- if (! accountingDiffTolerated(parser, XML_TOK_XML_DECL, s, next, __LINE__,
- XML_ACCOUNT_DIRECT)) {
- accountingOnAbort(parser);
- return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
- }
-#endif
-
+
+#ifdef XML_DTD
+ if (! accountingDiffTolerated(parser, XML_TOK_XML_DECL, s, next, __LINE__,
+ XML_ACCOUNT_DIRECT)) {
+ accountingOnAbort(parser);
+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
+ }
+#endif
+
if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)(
isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr,
&version, &versionend, &encodingName, &newEncoding, &standalone)) {
@@ -4291,10 +4291,10 @@ entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
for (;;) {
tok = XmlPrologTok(parser->m_encoding, start, end, &next);
- /* Note: Except for XML_TOK_BOM below, these bytes are accounted later in:
- - storeEntityValue
- - processXmlDecl
- */
+ /* Note: Except for XML_TOK_BOM below, these bytes are accounted later in:
+ - storeEntityValue
+ - processXmlDecl
+ */
parser->m_eventEndPtr = next;
if (tok <= 0) {
if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
@@ -4313,8 +4313,8 @@ entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
break;
}
/* found end of entity value - can store it now */
- return storeEntityValue(parser, parser->m_encoding, s, end,
- XML_ACCOUNT_DIRECT);
+ return storeEntityValue(parser, parser->m_encoding, s, end,
+ XML_ACCOUNT_DIRECT);
} else if (tok == XML_TOK_XML_DECL) {
enum XML_Error result;
result = processXmlDecl(parser, 0, start, next);
@@ -4341,14 +4341,14 @@ entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
*/
else if (tok == XML_TOK_BOM && next == end
&& ! parser->m_parsingStatus.finalBuffer) {
-# ifdef XML_DTD
- if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
- XML_ACCOUNT_DIRECT)) {
- accountingOnAbort(parser);
- return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
- }
-# endif
-
+# ifdef XML_DTD
+ if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
+ XML_ACCOUNT_DIRECT)) {
+ accountingOnAbort(parser);
+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
+ }
+# endif
+
*nextPtr = next;
return XML_ERROR_NONE;
}
@@ -4391,24 +4391,24 @@ externalParEntProcessor(XML_Parser parser, const char *s, const char *end,
}
/* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
However, when parsing an external subset, doProlog will not accept a BOM
- as valid, and report a syntax error, so we have to skip the BOM, and
- account for the BOM bytes.
+ as valid, and report a syntax error, so we have to skip the BOM, and
+ account for the BOM bytes.
*/
else if (tok == XML_TOK_BOM) {
- if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
- XML_ACCOUNT_DIRECT)) {
- accountingOnAbort(parser);
- return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
- }
-
+ if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
+ XML_ACCOUNT_DIRECT)) {
+ accountingOnAbort(parser);
+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
+ }
+
s = next;
tok = XmlPrologTok(parser->m_encoding, s, end, &next);
}
parser->m_processor = prologProcessor;
return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
- (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
- XML_ACCOUNT_DIRECT);
+ (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
+ XML_ACCOUNT_DIRECT);
}
static enum XML_Error PTRCALL
@@ -4421,9 +4421,9 @@ entityValueProcessor(XML_Parser parser, const char *s, const char *end,
for (;;) {
tok = XmlPrologTok(enc, start, end, &next);
- /* Note: These bytes are accounted later in:
- - storeEntityValue
- */
+ /* Note: These bytes are accounted later in:
+ - storeEntityValue
+ */
if (tok <= 0) {
if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
*nextPtr = s;
@@ -4441,7 +4441,7 @@ entityValueProcessor(XML_Parser parser, const char *s, const char *end,
break;
}
/* found end of entity value - can store it now */
- return storeEntityValue(parser, enc, s, end, XML_ACCOUNT_DIRECT);
+ return storeEntityValue(parser, enc, s, end, XML_ACCOUNT_DIRECT);
}
start = next;
}
@@ -4455,14 +4455,14 @@ prologProcessor(XML_Parser parser, const char *s, const char *end,
const char *next = s;
int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
- (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
- XML_ACCOUNT_DIRECT);
+ (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
+ XML_ACCOUNT_DIRECT);
}
static enum XML_Error
doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
int tok, const char *next, const char **nextPtr, XML_Bool haveMore,
- XML_Bool allowClosingDoctype, enum XML_Account account) {
+ XML_Bool allowClosingDoctype, enum XML_Account account) {
#ifdef XML_DTD
static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'};
#endif /* XML_DTD */
@@ -4489,10 +4489,10 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'};
static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'};
-#ifndef XML_DTD
- UNUSED_P(account);
-#endif
-
+#ifndef XML_DTD
+ UNUSED_P(account);
+#endif
+
/* save one level of indirection */
DTD *const dtd = parser->m_dtd;
@@ -4557,20 +4557,20 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
}
}
role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc);
-#ifdef XML_DTD
+#ifdef XML_DTD
+ switch (role) {
+ case XML_ROLE_INSTANCE_START: // bytes accounted in contentProcessor
+ case XML_ROLE_XML_DECL: // bytes accounted in processXmlDecl
+ case XML_ROLE_TEXT_DECL: // bytes accounted in processXmlDecl
+ break;
+ default:
+ if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) {
+ accountingOnAbort(parser);
+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
+ }
+ }
+#endif
switch (role) {
- case XML_ROLE_INSTANCE_START: // bytes accounted in contentProcessor
- case XML_ROLE_XML_DECL: // bytes accounted in processXmlDecl
- case XML_ROLE_TEXT_DECL: // bytes accounted in processXmlDecl
- break;
- default:
- if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) {
- accountingOnAbort(parser);
- return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
- }
- }
-#endif
- switch (role) {
case XML_ROLE_XML_DECL: {
enum XML_Error result = processXmlDecl(parser, 0, s, next);
if (result != XML_ERROR_NONE)
@@ -4845,8 +4845,8 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
const XML_Char *attVal;
enum XML_Error result = storeAttributeValue(
parser, enc, parser->m_declAttributeIsCdata,
- s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool,
- XML_ACCOUNT_NONE);
+ s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool,
+ XML_ACCOUNT_NONE);
if (result)
return result;
attVal = poolStart(&dtd->pool);
@@ -4879,9 +4879,9 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
break;
case XML_ROLE_ENTITY_VALUE:
if (dtd->keepProcessing) {
- enum XML_Error result
- = storeEntityValue(parser, enc, s + enc->minBytesPerChar,
- next - enc->minBytesPerChar, XML_ACCOUNT_NONE);
+ enum XML_Error result
+ = storeEntityValue(parser, enc, s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar, XML_ACCOUNT_NONE);
if (parser->m_declEntity) {
parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool);
parser->m_declEntity->textLen
@@ -5286,15 +5286,15 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
if (parser->m_externalEntityRefHandler) {
dtd->paramEntityRead = XML_FALSE;
entity->open = XML_TRUE;
- entityTrackingOnOpen(parser, entity, __LINE__);
+ entityTrackingOnOpen(parser, entity, __LINE__);
if (! parser->m_externalEntityRefHandler(
parser->m_externalEntityRefHandlerArg, 0, entity->base,
entity->systemId, entity->publicId)) {
- entityTrackingOnClose(parser, entity, __LINE__);
+ entityTrackingOnClose(parser, entity, __LINE__);
entity->open = XML_FALSE;
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
}
- entityTrackingOnClose(parser, entity, __LINE__);
+ entityTrackingOnClose(parser, entity, __LINE__);
entity->open = XML_FALSE;
handleDefault = XML_FALSE;
if (! dtd->paramEntityRead) {
@@ -5373,7 +5373,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
if (dtd->in_eldecl) {
ELEMENT_TYPE *el;
const XML_Char *name;
- size_t nameLen;
+ size_t nameLen;
const char *nxt
= (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar);
int myindex = nextScaffoldPart(parser);
@@ -5389,13 +5389,13 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
nameLen = 0;
for (; name[nameLen++];)
;
-
- /* Detect and prevent integer overflow */
- if (nameLen > UINT_MAX - dtd->contentStringLen) {
- return XML_ERROR_NO_MEMORY;
- }
-
- dtd->contentStringLen += (unsigned)nameLen;
+
+ /* Detect and prevent integer overflow */
+ if (nameLen > UINT_MAX - dtd->contentStringLen) {
+ return XML_ERROR_NO_MEMORY;
+ }
+
+ dtd->contentStringLen += (unsigned)nameLen;
if (parser->m_elementDeclHandler)
handleDefault = XML_FALSE;
}
@@ -5498,13 +5498,13 @@ epilogProcessor(XML_Parser parser, const char *s, const char *end,
for (;;) {
const char *next = NULL;
int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
-#ifdef XML_DTD
- if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
- XML_ACCOUNT_DIRECT)) {
- accountingOnAbort(parser);
- return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
- }
-#endif
+#ifdef XML_DTD
+ if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
+ XML_ACCOUNT_DIRECT)) {
+ accountingOnAbort(parser);
+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
+ }
+#endif
parser->m_eventEndPtr = next;
switch (tok) {
/* report partial linebreak - it might be the last token */
@@ -5578,9 +5578,9 @@ processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
return XML_ERROR_NO_MEMORY;
}
entity->open = XML_TRUE;
-#ifdef XML_DTD
- entityTrackingOnOpen(parser, entity, __LINE__);
-#endif
+#ifdef XML_DTD
+ entityTrackingOnOpen(parser, entity, __LINE__);
+#endif
entity->processed = 0;
openEntity->next = parser->m_openInternalEntities;
parser->m_openInternalEntities = openEntity;
@@ -5599,22 +5599,22 @@ processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
int tok
= XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
- tok, next, &next, XML_FALSE, XML_FALSE,
- XML_ACCOUNT_ENTITY_EXPANSION);
+ tok, next, &next, XML_FALSE, XML_FALSE,
+ XML_ACCOUNT_ENTITY_EXPANSION);
} else
#endif /* XML_DTD */
result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding,
- textStart, textEnd, &next, XML_FALSE,
- XML_ACCOUNT_ENTITY_EXPANSION);
+ textStart, textEnd, &next, XML_FALSE,
+ XML_ACCOUNT_ENTITY_EXPANSION);
if (result == XML_ERROR_NONE) {
if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
entity->processed = (int)(next - textStart);
parser->m_processor = internalEntityProcessor;
} else {
-#ifdef XML_DTD
- entityTrackingOnClose(parser, entity, __LINE__);
-#endif /* XML_DTD */
+#ifdef XML_DTD
+ entityTrackingOnClose(parser, entity, __LINE__);
+#endif /* XML_DTD */
entity->open = XML_FALSE;
parser->m_openInternalEntities = openEntity->next;
/* put openEntity back in list of free instances */
@@ -5647,13 +5647,13 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
int tok
= XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
- tok, next, &next, XML_FALSE, XML_TRUE,
- XML_ACCOUNT_ENTITY_EXPANSION);
+ tok, next, &next, XML_FALSE, XML_TRUE,
+ XML_ACCOUNT_ENTITY_EXPANSION);
} else
#endif /* XML_DTD */
result = doContent(parser, openEntity->startTagLevel,
parser->m_internalEncoding, textStart, textEnd, &next,
- XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION);
+ XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION);
if (result != XML_ERROR_NONE)
return result;
@@ -5662,9 +5662,9 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
entity->processed = (int)(next - (const char *)entity->textPtr);
return result;
} else {
-#ifdef XML_DTD
- entityTrackingOnClose(parser, entity, __LINE__);
-#endif
+#ifdef XML_DTD
+ entityTrackingOnClose(parser, entity, __LINE__);
+#endif
entity->open = XML_FALSE;
parser->m_openInternalEntities = openEntity->next;
/* put openEntity back in list of free instances */
@@ -5678,8 +5678,8 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
parser->m_processor = prologProcessor;
tok = XmlPrologTok(parser->m_encoding, s, end, &next);
return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
- (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
- XML_ACCOUNT_DIRECT);
+ (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
+ XML_ACCOUNT_DIRECT);
} else
#endif /* XML_DTD */
{
@@ -5687,8 +5687,8 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
/* see externalEntityContentProcessor vs contentProcessor */
return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding,
s, end, nextPtr,
- (XML_Bool)! parser->m_parsingStatus.finalBuffer,
- XML_ACCOUNT_DIRECT);
+ (XML_Bool)! parser->m_parsingStatus.finalBuffer,
+ XML_ACCOUNT_DIRECT);
}
}
@@ -5703,10 +5703,10 @@ errorProcessor(XML_Parser parser, const char *s, const char *end,
static enum XML_Error
storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
- const char *ptr, const char *end, STRING_POOL *pool,
- enum XML_Account account) {
+ const char *ptr, const char *end, STRING_POOL *pool,
+ enum XML_Account account) {
enum XML_Error result
- = appendAttributeValue(parser, enc, isCdata, ptr, end, pool, account);
+ = appendAttributeValue(parser, enc, isCdata, ptr, end, pool, account);
if (result)
return result;
if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
@@ -5718,23 +5718,23 @@ storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
static enum XML_Error
appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
- const char *ptr, const char *end, STRING_POOL *pool,
- enum XML_Account account) {
+ const char *ptr, const char *end, STRING_POOL *pool,
+ enum XML_Account account) {
DTD *const dtd = parser->m_dtd; /* save one level of indirection */
-#ifndef XML_DTD
- UNUSED_P(account);
-#endif
-
+#ifndef XML_DTD
+ UNUSED_P(account);
+#endif
+
for (;;) {
- const char *next
- = ptr; /* XmlAttributeValueTok doesn't always set the last arg */
+ const char *next
+ = ptr; /* XmlAttributeValueTok doesn't always set the last arg */
int tok = XmlAttributeValueTok(enc, ptr, end, &next);
-#ifdef XML_DTD
- if (! accountingDiffTolerated(parser, tok, ptr, next, __LINE__, account)) {
- accountingOnAbort(parser);
- return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
- }
-#endif
+#ifdef XML_DTD
+ if (! accountingDiffTolerated(parser, tok, ptr, next, __LINE__, account)) {
+ accountingOnAbort(parser);
+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
+ }
+#endif
switch (tok) {
case XML_TOK_NONE:
return XML_ERROR_NONE;
@@ -5794,14 +5794,14 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
XML_Char ch = (XML_Char)XmlPredefinedEntityName(
enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar);
if (ch) {
-#ifdef XML_DTD
- /* NOTE: We are replacing 4-6 characters original input for 1 character
- * so there is no amplification and hence recording without
- * protection. */
- accountingDiffTolerated(parser, tok, (char *)&ch,
- ((char *)&ch) + sizeof(XML_Char), __LINE__,
- XML_ACCOUNT_ENTITY_EXPANSION);
-#endif /* XML_DTD */
+#ifdef XML_DTD
+ /* NOTE: We are replacing 4-6 characters original input for 1 character
+ * so there is no amplification and hence recording without
+ * protection. */
+ accountingDiffTolerated(parser, tok, (char *)&ch,
+ ((char *)&ch) + sizeof(XML_Char), __LINE__,
+ XML_ACCOUNT_ENTITY_EXPANSION);
+#endif /* XML_DTD */
if (! poolAppendChar(pool, ch))
return XML_ERROR_NO_MEMORY;
break;
@@ -5879,16 +5879,16 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
enum XML_Error result;
const XML_Char *textEnd = entity->textPtr + entity->textLen;
entity->open = XML_TRUE;
-#ifdef XML_DTD
- entityTrackingOnOpen(parser, entity, __LINE__);
-#endif
+#ifdef XML_DTD
+ entityTrackingOnOpen(parser, entity, __LINE__);
+#endif
result = appendAttributeValue(parser, parser->m_internalEncoding,
isCdata, (const char *)entity->textPtr,
- (const char *)textEnd, pool,
- XML_ACCOUNT_ENTITY_EXPANSION);
-#ifdef XML_DTD
- entityTrackingOnClose(parser, entity, __LINE__);
-#endif
+ (const char *)textEnd, pool,
+ XML_ACCOUNT_ENTITY_EXPANSION);
+#ifdef XML_DTD
+ entityTrackingOnClose(parser, entity, __LINE__);
+#endif
entity->open = XML_FALSE;
if (result)
return result;
@@ -5918,16 +5918,16 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
static enum XML_Error
storeEntityValue(XML_Parser parser, const ENCODING *enc,
- const char *entityTextPtr, const char *entityTextEnd,
- enum XML_Account account) {
+ const char *entityTextPtr, const char *entityTextEnd,
+ enum XML_Account account) {
DTD *const dtd = parser->m_dtd; /* save one level of indirection */
STRING_POOL *pool = &(dtd->entityValuePool);
enum XML_Error result = XML_ERROR_NONE;
#ifdef XML_DTD
int oldInEntityValue = parser->m_prologState.inEntityValue;
parser->m_prologState.inEntityValue = 1;
-#else
- UNUSED_P(account);
+#else
+ UNUSED_P(account);
#endif /* XML_DTD */
/* never return Null for the value argument in EntityDeclHandler,
since this would indicate an external entity; therefore we
@@ -5938,19 +5938,19 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
}
for (;;) {
- const char *next
- = entityTextPtr; /* XmlEntityValueTok doesn't always set the last arg */
+ const char *next
+ = entityTextPtr; /* XmlEntityValueTok doesn't always set the last arg */
int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
-
-#ifdef XML_DTD
- if (! accountingDiffTolerated(parser, tok, entityTextPtr, next, __LINE__,
- account)) {
- accountingOnAbort(parser);
- result = XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
- goto endEntityValue;
- }
-#endif
-
+
+#ifdef XML_DTD
+ if (! accountingDiffTolerated(parser, tok, entityTextPtr, next, __LINE__,
+ account)) {
+ accountingOnAbort(parser);
+ result = XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
+ goto endEntityValue;
+ }
+#endif
+
switch (tok) {
case XML_TOK_PARAM_ENTITY_REF:
#ifdef XML_DTD
@@ -5986,16 +5986,16 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
if (parser->m_externalEntityRefHandler) {
dtd->paramEntityRead = XML_FALSE;
entity->open = XML_TRUE;
- entityTrackingOnOpen(parser, entity, __LINE__);
+ entityTrackingOnOpen(parser, entity, __LINE__);
if (! parser->m_externalEntityRefHandler(
parser->m_externalEntityRefHandlerArg, 0, entity->base,
entity->systemId, entity->publicId)) {
- entityTrackingOnClose(parser, entity, __LINE__);
+ entityTrackingOnClose(parser, entity, __LINE__);
entity->open = XML_FALSE;
result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
goto endEntityValue;
}
- entityTrackingOnClose(parser, entity, __LINE__);
+ entityTrackingOnClose(parser, entity, __LINE__);
entity->open = XML_FALSE;
if (! dtd->paramEntityRead)
dtd->keepProcessing = dtd->standalone;
@@ -6003,12 +6003,12 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
dtd->keepProcessing = dtd->standalone;
} else {
entity->open = XML_TRUE;
- entityTrackingOnOpen(parser, entity, __LINE__);
+ entityTrackingOnOpen(parser, entity, __LINE__);
result = storeEntityValue(
parser, parser->m_internalEncoding, (const char *)entity->textPtr,
- (const char *)(entity->textPtr + entity->textLen),
- XML_ACCOUNT_ENTITY_EXPANSION);
- entityTrackingOnClose(parser, entity, __LINE__);
+ (const char *)(entity->textPtr + entity->textLen),
+ XML_ACCOUNT_ENTITY_EXPANSION);
+ entityTrackingOnClose(parser, entity, __LINE__);
entity->open = XML_FALSE;
if (result)
goto endEntityValue;
@@ -6548,7 +6548,7 @@ normalizePublicId(XML_Char *publicId) {
static DTD *
dtdCreate(const XML_Memory_Handling_Suite *ms) {
- DTD *p = ms->malloc_fcn(sizeof(DTD));
+ DTD *p = ms->malloc_fcn(sizeof(DTD));
if (p == NULL)
return p;
poolInit(&(p->pool), ms);
@@ -6721,8 +6721,8 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
if (! newE)
return 0;
if (oldE->nDefaultAtts) {
- newE->defaultAtts
- = ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
+ newE->defaultAtts
+ = ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
if (! newE->defaultAtts) {
return 0;
}
@@ -6884,7 +6884,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
/* table->size is a power of 2 */
table->size = (size_t)1 << INIT_POWER;
tsize = table->size * sizeof(NAMED *);
- table->v = table->mem->malloc_fcn(tsize);
+ table->v = table->mem->malloc_fcn(tsize);
if (! table->v) {
table->size = 0;
return NULL;
@@ -6924,7 +6924,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
}
size_t tsize = newSize * sizeof(NAMED *);
- NAMED **newV = table->mem->malloc_fcn(tsize);
+ NAMED **newV = table->mem->malloc_fcn(tsize);
if (! newV)
return NULL;
memset(newV, 0, tsize);
@@ -6953,7 +6953,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
}
}
}
- table->v[i] = table->mem->malloc_fcn(createSize);
+ table->v[i] = table->mem->malloc_fcn(createSize);
if (! table->v[i])
return NULL;
memset(table->v[i], 0, createSize);
@@ -7241,7 +7241,7 @@ poolGrow(STRING_POOL *pool) {
if (bytesToAllocate == 0)
return XML_FALSE;
- tem = pool->mem->malloc_fcn(bytesToAllocate);
+ tem = pool->mem->malloc_fcn(bytesToAllocate);
if (! tem)
return XML_FALSE;
tem->size = blockSize;
@@ -7430,755 +7430,755 @@ copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
memcpy(result, s, charsRequired * sizeof(XML_Char));
return result;
}
-
-#ifdef XML_DTD
-
-static float
-accountingGetCurrentAmplification(XML_Parser rootParser) {
- const XmlBigCount countBytesOutput
- = rootParser->m_accounting.countBytesDirect
- + rootParser->m_accounting.countBytesIndirect;
- const float amplificationFactor
- = rootParser->m_accounting.countBytesDirect
- ? (countBytesOutput
- / (float)(rootParser->m_accounting.countBytesDirect))
- : 1.0f;
- assert(! rootParser->m_parentParser);
- return amplificationFactor;
-}
-
-static void
-accountingReportStats(XML_Parser originParser, const char *epilog) {
- const XML_Parser rootParser = getRootParserOf(originParser, NULL);
- assert(! rootParser->m_parentParser);
-
- if (rootParser->m_accounting.debugLevel < 1) {
- return;
- }
-
- const float amplificationFactor
- = accountingGetCurrentAmplification(rootParser);
- fprintf(stderr,
- "expat: Accounting(%p): Direct " EXPAT_FMT_ULL(
- "10") ", indirect " EXPAT_FMT_ULL("10") ", amplification %8.2f%s",
- (void *)rootParser, rootParser->m_accounting.countBytesDirect,
- rootParser->m_accounting.countBytesIndirect,
- (double)amplificationFactor, epilog);
-}
-
-static void
-accountingOnAbort(XML_Parser originParser) {
- accountingReportStats(originParser, " ABORTING\n");
-}
-
-static void
-accountingReportDiff(XML_Parser rootParser,
- unsigned int levelsAwayFromRootParser, const char *before,
- const char *after, ptrdiff_t bytesMore, int source_line,
- enum XML_Account account) {
- assert(! rootParser->m_parentParser);
-
- fprintf(stderr,
- " (+" EXPAT_FMT_PTRDIFF_T("6") " bytes %s|%d, xmlparse.c:%d) %*s\"",
- bytesMore, (account == XML_ACCOUNT_DIRECT) ? "DIR" : "EXP",
- levelsAwayFromRootParser, source_line, 10, "");
-
- const char ellipis[] = "[..]";
- const size_t ellipsisLength = sizeof(ellipis) /* because compile-time */ - 1;
- const unsigned int contextLength = 10;
-
- /* Note: Performance is of no concern here */
- const char *walker = before;
- if ((rootParser->m_accounting.debugLevel >= 3)
- || (after - before)
- <= (ptrdiff_t)(contextLength + ellipsisLength + contextLength)) {
- for (; walker < after; walker++) {
- fprintf(stderr, "%s", unsignedCharToPrintable(walker[0]));
- }
- } else {
- for (; walker < before + contextLength; walker++) {
- fprintf(stderr, "%s", unsignedCharToPrintable(walker[0]));
- }
- fprintf(stderr, ellipis);
- walker = after - contextLength;
- for (; walker < after; walker++) {
- fprintf(stderr, "%s", unsignedCharToPrintable(walker[0]));
- }
- }
- fprintf(stderr, "\"\n");
-}
-
-static XML_Bool
-accountingDiffTolerated(XML_Parser originParser, int tok, const char *before,
- const char *after, int source_line,
- enum XML_Account account) {
- /* Note: We need to check the token type *first* to be sure that
- * we can even access variable <after>, safely.
- * E.g. for XML_TOK_NONE <after> may hold an invalid pointer. */
- switch (tok) {
- case XML_TOK_INVALID:
- case XML_TOK_PARTIAL:
- case XML_TOK_PARTIAL_CHAR:
- case XML_TOK_NONE:
- return XML_TRUE;
- }
-
- if (account == XML_ACCOUNT_NONE)
- return XML_TRUE; /* because these bytes have been accounted for, already */
-
- unsigned int levelsAwayFromRootParser;
- const XML_Parser rootParser
- = getRootParserOf(originParser, &levelsAwayFromRootParser);
- assert(! rootParser->m_parentParser);
-
- const int isDirect
- = (account == XML_ACCOUNT_DIRECT) && (originParser == rootParser);
- const ptrdiff_t bytesMore = after - before;
-
- XmlBigCount *const additionTarget
- = isDirect ? &rootParser->m_accounting.countBytesDirect
- : &rootParser->m_accounting.countBytesIndirect;
-
- /* Detect and avoid integer overflow */
- if (*additionTarget > (XmlBigCount)(-1) - (XmlBigCount)bytesMore)
- return XML_FALSE;
- *additionTarget += bytesMore;
-
- const XmlBigCount countBytesOutput
- = rootParser->m_accounting.countBytesDirect
- + rootParser->m_accounting.countBytesIndirect;
- const float amplificationFactor
- = accountingGetCurrentAmplification(rootParser);
- const XML_Bool tolerated
- = (countBytesOutput < rootParser->m_accounting.activationThresholdBytes)
- || (amplificationFactor
- <= rootParser->m_accounting.maximumAmplificationFactor);
-
- if (rootParser->m_accounting.debugLevel >= 2) {
- accountingReportStats(rootParser, "");
- accountingReportDiff(rootParser, levelsAwayFromRootParser, before, after,
- bytesMore, source_line, account);
- }
-
- return tolerated;
-}
-
-unsigned long long
-testingAccountingGetCountBytesDirect(XML_Parser parser) {
- if (! parser)
- return 0;
- return parser->m_accounting.countBytesDirect;
-}
-
-unsigned long long
-testingAccountingGetCountBytesIndirect(XML_Parser parser) {
- if (! parser)
- return 0;
- return parser->m_accounting.countBytesIndirect;
-}
-
-static void
-entityTrackingReportStats(XML_Parser rootParser, ENTITY *entity,
- const char *action, int sourceLine) {
- assert(! rootParser->m_parentParser);
- if (rootParser->m_entity_stats.debugLevel < 1)
- return;
-
-# if defined(XML_UNICODE)
- const char *const entityName = "[..]";
-# else
- const char *const entityName = entity->name;
-# endif
-
- fprintf(
- stderr,
- "expat: Entities(%p): Count %9d, depth %2d/%2d %*s%s%s; %s length %d (xmlparse.c:%d)\n",
- (void *)rootParser, rootParser->m_entity_stats.countEverOpened,
- rootParser->m_entity_stats.currentDepth,
- rootParser->m_entity_stats.maximumDepthSeen,
- (rootParser->m_entity_stats.currentDepth - 1) * 2, "",
- entity->is_param ? "%" : "&", entityName, action, entity->textLen,
- sourceLine);
-}
-
-static void
-entityTrackingOnOpen(XML_Parser originParser, ENTITY *entity, int sourceLine) {
- const XML_Parser rootParser = getRootParserOf(originParser, NULL);
- assert(! rootParser->m_parentParser);
-
- rootParser->m_entity_stats.countEverOpened++;
- rootParser->m_entity_stats.currentDepth++;
- if (rootParser->m_entity_stats.currentDepth
- > rootParser->m_entity_stats.maximumDepthSeen) {
- rootParser->m_entity_stats.maximumDepthSeen++;
- }
-
- entityTrackingReportStats(rootParser, entity, "OPEN ", sourceLine);
-}
-
-static void
-entityTrackingOnClose(XML_Parser originParser, ENTITY *entity, int sourceLine) {
- const XML_Parser rootParser = getRootParserOf(originParser, NULL);
- assert(! rootParser->m_parentParser);
-
- entityTrackingReportStats(rootParser, entity, "CLOSE", sourceLine);
- rootParser->m_entity_stats.currentDepth--;
-}
-
-static XML_Parser
-getRootParserOf(XML_Parser parser, unsigned int *outLevelDiff) {
- XML_Parser rootParser = parser;
- unsigned int stepsTakenUpwards = 0;
- while (rootParser->m_parentParser) {
- rootParser = rootParser->m_parentParser;
- stepsTakenUpwards++;
- }
- assert(! rootParser->m_parentParser);
- if (outLevelDiff != NULL) {
- *outLevelDiff = stepsTakenUpwards;
- }
- return rootParser;
-}
-
-const char *
-unsignedCharToPrintable(unsigned char c) {
- switch (c) {
- case 0:
- return "\\0";
- case 1:
- return "\\x1";
- case 2:
- return "\\x2";
- case 3:
- return "\\x3";
- case 4:
- return "\\x4";
- case 5:
- return "\\x5";
- case 6:
- return "\\x6";
- case 7:
- return "\\x7";
- case 8:
- return "\\x8";
- case 9:
- return "\\t";
- case 10:
- return "\\n";
- case 11:
- return "\\xB";
- case 12:
- return "\\xC";
- case 13:
- return "\\r";
- case 14:
- return "\\xE";
- case 15:
- return "\\xF";
- case 16:
- return "\\x10";
- case 17:
- return "\\x11";
- case 18:
- return "\\x12";
- case 19:
- return "\\x13";
- case 20:
- return "\\x14";
- case 21:
- return "\\x15";
- case 22:
- return "\\x16";
- case 23:
- return "\\x17";
- case 24:
- return "\\x18";
- case 25:
- return "\\x19";
- case 26:
- return "\\x1A";
- case 27:
- return "\\x1B";
- case 28:
- return "\\x1C";
- case 29:
- return "\\x1D";
- case 30:
- return "\\x1E";
- case 31:
- return "\\x1F";
- case 32:
- return " ";
- case 33:
- return "!";
- case 34:
- return "\\\"";
- case 35:
- return "#";
- case 36:
- return "$";
- case 37:
- return "%";
- case 38:
- return "&";
- case 39:
- return "'";
- case 40:
- return "(";
- case 41:
- return ")";
- case 42:
- return "*";
- case 43:
- return "+";
- case 44:
- return ",";
- case 45:
- return "-";
- case 46:
- return ".";
- case 47:
- return "/";
- case 48:
- return "0";
- case 49:
- return "1";
- case 50:
- return "2";
- case 51:
- return "3";
- case 52:
- return "4";
- case 53:
- return "5";
- case 54:
- return "6";
- case 55:
- return "7";
- case 56:
- return "8";
- case 57:
- return "9";
- case 58:
- return ":";
- case 59:
- return ";";
- case 60:
- return "<";
- case 61:
- return "=";
- case 62:
- return ">";
- case 63:
- return "?";
- case 64:
- return "@";
- case 65:
- return "A";
- case 66:
- return "B";
- case 67:
- return "C";
- case 68:
- return "D";
- case 69:
- return "E";
- case 70:
- return "F";
- case 71:
- return "G";
- case 72:
- return "H";
- case 73:
- return "I";
- case 74:
- return "J";
- case 75:
- return "K";
- case 76:
- return "L";
- case 77:
- return "M";
- case 78:
- return "N";
- case 79:
- return "O";
- case 80:
- return "P";
- case 81:
- return "Q";
- case 82:
- return "R";
- case 83:
- return "S";
- case 84:
- return "T";
- case 85:
- return "U";
- case 86:
- return "V";
- case 87:
- return "W";
- case 88:
- return "X";
- case 89:
- return "Y";
- case 90:
- return "Z";
- case 91:
- return "[";
- case 92:
- return "\\\\";
- case 93:
- return "]";
- case 94:
- return "^";
- case 95:
- return "_";
- case 96:
- return "`";
- case 97:
- return "a";
- case 98:
- return "b";
- case 99:
- return "c";
- case 100:
- return "d";
- case 101:
- return "e";
- case 102:
- return "f";
- case 103:
- return "g";
- case 104:
- return "h";
- case 105:
- return "i";
- case 106:
- return "j";
- case 107:
- return "k";
- case 108:
- return "l";
- case 109:
- return "m";
- case 110:
- return "n";
- case 111:
- return "o";
- case 112:
- return "p";
- case 113:
- return "q";
- case 114:
- return "r";
- case 115:
- return "s";
- case 116:
- return "t";
- case 117:
- return "u";
- case 118:
- return "v";
- case 119:
- return "w";
- case 120:
- return "x";
- case 121:
- return "y";
- case 122:
- return "z";
- case 123:
- return "{";
- case 124:
- return "|";
- case 125:
- return "}";
- case 126:
- return "~";
- case 127:
- return "\\x7F";
- case 128:
- return "\\x80";
- case 129:
- return "\\x81";
- case 130:
- return "\\x82";
- case 131:
- return "\\x83";
- case 132:
- return "\\x84";
- case 133:
- return "\\x85";
- case 134:
- return "\\x86";
- case 135:
- return "\\x87";
- case 136:
- return "\\x88";
- case 137:
- return "\\x89";
- case 138:
- return "\\x8A";
- case 139:
- return "\\x8B";
- case 140:
- return "\\x8C";
- case 141:
- return "\\x8D";
- case 142:
- return "\\x8E";
- case 143:
- return "\\x8F";
- case 144:
- return "\\x90";
- case 145:
- return "\\x91";
- case 146:
- return "\\x92";
- case 147:
- return "\\x93";
- case 148:
- return "\\x94";
- case 149:
- return "\\x95";
- case 150:
- return "\\x96";
- case 151:
- return "\\x97";
- case 152:
- return "\\x98";
- case 153:
- return "\\x99";
- case 154:
- return "\\x9A";
- case 155:
- return "\\x9B";
- case 156:
- return "\\x9C";
- case 157:
- return "\\x9D";
- case 158:
- return "\\x9E";
- case 159:
- return "\\x9F";
- case 160:
- return "\\xA0";
- case 161:
- return "\\xA1";
- case 162:
- return "\\xA2";
- case 163:
- return "\\xA3";
- case 164:
- return "\\xA4";
- case 165:
- return "\\xA5";
- case 166:
- return "\\xA6";
- case 167:
- return "\\xA7";
- case 168:
- return "\\xA8";
- case 169:
- return "\\xA9";
- case 170:
- return "\\xAA";
- case 171:
- return "\\xAB";
- case 172:
- return "\\xAC";
- case 173:
- return "\\xAD";
- case 174:
- return "\\xAE";
- case 175:
- return "\\xAF";
- case 176:
- return "\\xB0";
- case 177:
- return "\\xB1";
- case 178:
- return "\\xB2";
- case 179:
- return "\\xB3";
- case 180:
- return "\\xB4";
- case 181:
- return "\\xB5";
- case 182:
- return "\\xB6";
- case 183:
- return "\\xB7";
- case 184:
- return "\\xB8";
- case 185:
- return "\\xB9";
- case 186:
- return "\\xBA";
- case 187:
- return "\\xBB";
- case 188:
- return "\\xBC";
- case 189:
- return "\\xBD";
- case 190:
- return "\\xBE";
- case 191:
- return "\\xBF";
- case 192:
- return "\\xC0";
- case 193:
- return "\\xC1";
- case 194:
- return "\\xC2";
- case 195:
- return "\\xC3";
- case 196:
- return "\\xC4";
- case 197:
- return "\\xC5";
- case 198:
- return "\\xC6";
- case 199:
- return "\\xC7";
- case 200:
- return "\\xC8";
- case 201:
- return "\\xC9";
- case 202:
- return "\\xCA";
- case 203:
- return "\\xCB";
- case 204:
- return "\\xCC";
- case 205:
- return "\\xCD";
- case 206:
- return "\\xCE";
- case 207:
- return "\\xCF";
- case 208:
- return "\\xD0";
- case 209:
- return "\\xD1";
- case 210:
- return "\\xD2";
- case 211:
- return "\\xD3";
- case 212:
- return "\\xD4";
- case 213:
- return "\\xD5";
- case 214:
- return "\\xD6";
- case 215:
- return "\\xD7";
- case 216:
- return "\\xD8";
- case 217:
- return "\\xD9";
- case 218:
- return "\\xDA";
- case 219:
- return "\\xDB";
- case 220:
- return "\\xDC";
- case 221:
- return "\\xDD";
- case 222:
- return "\\xDE";
- case 223:
- return "\\xDF";
- case 224:
- return "\\xE0";
- case 225:
- return "\\xE1";
- case 226:
- return "\\xE2";
- case 227:
- return "\\xE3";
- case 228:
- return "\\xE4";
- case 229:
- return "\\xE5";
- case 230:
- return "\\xE6";
- case 231:
- return "\\xE7";
- case 232:
- return "\\xE8";
- case 233:
- return "\\xE9";
- case 234:
- return "\\xEA";
- case 235:
- return "\\xEB";
- case 236:
- return "\\xEC";
- case 237:
- return "\\xED";
- case 238:
- return "\\xEE";
- case 239:
- return "\\xEF";
- case 240:
- return "\\xF0";
- case 241:
- return "\\xF1";
- case 242:
- return "\\xF2";
- case 243:
- return "\\xF3";
- case 244:
- return "\\xF4";
- case 245:
- return "\\xF5";
- case 246:
- return "\\xF6";
- case 247:
- return "\\xF7";
- case 248:
- return "\\xF8";
- case 249:
- return "\\xF9";
- case 250:
- return "\\xFA";
- case 251:
- return "\\xFB";
- case 252:
- return "\\xFC";
- case 253:
- return "\\xFD";
- case 254:
- return "\\xFE";
- case 255:
- return "\\xFF";
- default:
- assert(0); /* never gets here */
- return "dead code";
- }
- assert(0); /* never gets here */
-}
-
-#endif /* XML_DTD */
-
-static unsigned long
-getDebugLevel(const char *variableName, unsigned long defaultDebugLevel) {
- const char *const valueOrNull = getenv(variableName);
- if (valueOrNull == NULL) {
- return defaultDebugLevel;
- }
- const char *const value = valueOrNull;
-
- errno = 0;
- char *afterValue = (char *)value;
- unsigned long debugLevel = strtoul(value, &afterValue, 10);
- if ((errno != 0) || (afterValue[0] != '\0')) {
- errno = 0;
- return defaultDebugLevel;
- }
-
- return debugLevel;
-}
+
+#ifdef XML_DTD
+
+static float
+accountingGetCurrentAmplification(XML_Parser rootParser) {
+ const XmlBigCount countBytesOutput
+ = rootParser->m_accounting.countBytesDirect
+ + rootParser->m_accounting.countBytesIndirect;
+ const float amplificationFactor
+ = rootParser->m_accounting.countBytesDirect
+ ? (countBytesOutput
+ / (float)(rootParser->m_accounting.countBytesDirect))
+ : 1.0f;
+ assert(! rootParser->m_parentParser);
+ return amplificationFactor;
+}
+
+static void
+accountingReportStats(XML_Parser originParser, const char *epilog) {
+ const XML_Parser rootParser = getRootParserOf(originParser, NULL);
+ assert(! rootParser->m_parentParser);
+
+ if (rootParser->m_accounting.debugLevel < 1) {
+ return;
+ }
+
+ const float amplificationFactor
+ = accountingGetCurrentAmplification(rootParser);
+ fprintf(stderr,
+ "expat: Accounting(%p): Direct " EXPAT_FMT_ULL(
+ "10") ", indirect " EXPAT_FMT_ULL("10") ", amplification %8.2f%s",
+ (void *)rootParser, rootParser->m_accounting.countBytesDirect,
+ rootParser->m_accounting.countBytesIndirect,
+ (double)amplificationFactor, epilog);
+}
+
+static void
+accountingOnAbort(XML_Parser originParser) {
+ accountingReportStats(originParser, " ABORTING\n");
+}
+
+static void
+accountingReportDiff(XML_Parser rootParser,
+ unsigned int levelsAwayFromRootParser, const char *before,
+ const char *after, ptrdiff_t bytesMore, int source_line,
+ enum XML_Account account) {
+ assert(! rootParser->m_parentParser);
+
+ fprintf(stderr,
+ " (+" EXPAT_FMT_PTRDIFF_T("6") " bytes %s|%d, xmlparse.c:%d) %*s\"",
+ bytesMore, (account == XML_ACCOUNT_DIRECT) ? "DIR" : "EXP",
+ levelsAwayFromRootParser, source_line, 10, "");
+
+ const char ellipis[] = "[..]";
+ const size_t ellipsisLength = sizeof(ellipis) /* because compile-time */ - 1;
+ const unsigned int contextLength = 10;
+
+ /* Note: Performance is of no concern here */
+ const char *walker = before;
+ if ((rootParser->m_accounting.debugLevel >= 3)
+ || (after - before)
+ <= (ptrdiff_t)(contextLength + ellipsisLength + contextLength)) {
+ for (; walker < after; walker++) {
+ fprintf(stderr, "%s", unsignedCharToPrintable(walker[0]));
+ }
+ } else {
+ for (; walker < before + contextLength; walker++) {
+ fprintf(stderr, "%s", unsignedCharToPrintable(walker[0]));
+ }
+ fprintf(stderr, ellipis);
+ walker = after - contextLength;
+ for (; walker < after; walker++) {
+ fprintf(stderr, "%s", unsignedCharToPrintable(walker[0]));
+ }
+ }
+ fprintf(stderr, "\"\n");
+}
+
+static XML_Bool
+accountingDiffTolerated(XML_Parser originParser, int tok, const char *before,
+ const char *after, int source_line,
+ enum XML_Account account) {
+ /* Note: We need to check the token type *first* to be sure that
+ * we can even access variable <after>, safely.
+ * E.g. for XML_TOK_NONE <after> may hold an invalid pointer. */
+ switch (tok) {
+ case XML_TOK_INVALID:
+ case XML_TOK_PARTIAL:
+ case XML_TOK_PARTIAL_CHAR:
+ case XML_TOK_NONE:
+ return XML_TRUE;
+ }
+
+ if (account == XML_ACCOUNT_NONE)
+ return XML_TRUE; /* because these bytes have been accounted for, already */
+
+ unsigned int levelsAwayFromRootParser;
+ const XML_Parser rootParser
+ = getRootParserOf(originParser, &levelsAwayFromRootParser);
+ assert(! rootParser->m_parentParser);
+
+ const int isDirect
+ = (account == XML_ACCOUNT_DIRECT) && (originParser == rootParser);
+ const ptrdiff_t bytesMore = after - before;
+
+ XmlBigCount *const additionTarget
+ = isDirect ? &rootParser->m_accounting.countBytesDirect
+ : &rootParser->m_accounting.countBytesIndirect;
+
+ /* Detect and avoid integer overflow */
+ if (*additionTarget > (XmlBigCount)(-1) - (XmlBigCount)bytesMore)
+ return XML_FALSE;
+ *additionTarget += bytesMore;
+
+ const XmlBigCount countBytesOutput
+ = rootParser->m_accounting.countBytesDirect
+ + rootParser->m_accounting.countBytesIndirect;
+ const float amplificationFactor
+ = accountingGetCurrentAmplification(rootParser);
+ const XML_Bool tolerated
+ = (countBytesOutput < rootParser->m_accounting.activationThresholdBytes)
+ || (amplificationFactor
+ <= rootParser->m_accounting.maximumAmplificationFactor);
+
+ if (rootParser->m_accounting.debugLevel >= 2) {
+ accountingReportStats(rootParser, "");
+ accountingReportDiff(rootParser, levelsAwayFromRootParser, before, after,
+ bytesMore, source_line, account);
+ }
+
+ return tolerated;
+}
+
+unsigned long long
+testingAccountingGetCountBytesDirect(XML_Parser parser) {
+ if (! parser)
+ return 0;
+ return parser->m_accounting.countBytesDirect;
+}
+
+unsigned long long
+testingAccountingGetCountBytesIndirect(XML_Parser parser) {
+ if (! parser)
+ return 0;
+ return parser->m_accounting.countBytesIndirect;
+}
+
+static void
+entityTrackingReportStats(XML_Parser rootParser, ENTITY *entity,
+ const char *action, int sourceLine) {
+ assert(! rootParser->m_parentParser);
+ if (rootParser->m_entity_stats.debugLevel < 1)
+ return;
+
+# if defined(XML_UNICODE)
+ const char *const entityName = "[..]";
+# else
+ const char *const entityName = entity->name;
+# endif
+
+ fprintf(
+ stderr,
+ "expat: Entities(%p): Count %9d, depth %2d/%2d %*s%s%s; %s length %d (xmlparse.c:%d)\n",
+ (void *)rootParser, rootParser->m_entity_stats.countEverOpened,
+ rootParser->m_entity_stats.currentDepth,
+ rootParser->m_entity_stats.maximumDepthSeen,
+ (rootParser->m_entity_stats.currentDepth - 1) * 2, "",
+ entity->is_param ? "%" : "&", entityName, action, entity->textLen,
+ sourceLine);
+}
+
+static void
+entityTrackingOnOpen(XML_Parser originParser, ENTITY *entity, int sourceLine) {
+ const XML_Parser rootParser = getRootParserOf(originParser, NULL);
+ assert(! rootParser->m_parentParser);
+
+ rootParser->m_entity_stats.countEverOpened++;
+ rootParser->m_entity_stats.currentDepth++;
+ if (rootParser->m_entity_stats.currentDepth
+ > rootParser->m_entity_stats.maximumDepthSeen) {
+ rootParser->m_entity_stats.maximumDepthSeen++;
+ }
+
+ entityTrackingReportStats(rootParser, entity, "OPEN ", sourceLine);
+}
+
+static void
+entityTrackingOnClose(XML_Parser originParser, ENTITY *entity, int sourceLine) {
+ const XML_Parser rootParser = getRootParserOf(originParser, NULL);
+ assert(! rootParser->m_parentParser);
+
+ entityTrackingReportStats(rootParser, entity, "CLOSE", sourceLine);
+ rootParser->m_entity_stats.currentDepth--;
+}
+
+static XML_Parser
+getRootParserOf(XML_Parser parser, unsigned int *outLevelDiff) {
+ XML_Parser rootParser = parser;
+ unsigned int stepsTakenUpwards = 0;
+ while (rootParser->m_parentParser) {
+ rootParser = rootParser->m_parentParser;
+ stepsTakenUpwards++;
+ }
+ assert(! rootParser->m_parentParser);
+ if (outLevelDiff != NULL) {
+ *outLevelDiff = stepsTakenUpwards;
+ }
+ return rootParser;
+}
+
+const char *
+unsignedCharToPrintable(unsigned char c) {
+ switch (c) {
+ case 0:
+ return "\\0";
+ case 1:
+ return "\\x1";
+ case 2:
+ return "\\x2";
+ case 3:
+ return "\\x3";
+ case 4:
+ return "\\x4";
+ case 5:
+ return "\\x5";
+ case 6:
+ return "\\x6";
+ case 7:
+ return "\\x7";
+ case 8:
+ return "\\x8";
+ case 9:
+ return "\\t";
+ case 10:
+ return "\\n";
+ case 11:
+ return "\\xB";
+ case 12:
+ return "\\xC";
+ case 13:
+ return "\\r";
+ case 14:
+ return "\\xE";
+ case 15:
+ return "\\xF";
+ case 16:
+ return "\\x10";
+ case 17:
+ return "\\x11";
+ case 18:
+ return "\\x12";
+ case 19:
+ return "\\x13";
+ case 20:
+ return "\\x14";
+ case 21:
+ return "\\x15";
+ case 22:
+ return "\\x16";
+ case 23:
+ return "\\x17";
+ case 24:
+ return "\\x18";
+ case 25:
+ return "\\x19";
+ case 26:
+ return "\\x1A";
+ case 27:
+ return "\\x1B";
+ case 28:
+ return "\\x1C";
+ case 29:
+ return "\\x1D";
+ case 30:
+ return "\\x1E";
+ case 31:
+ return "\\x1F";
+ case 32:
+ return " ";
+ case 33:
+ return "!";
+ case 34:
+ return "\\\"";
+ case 35:
+ return "#";
+ case 36:
+ return "$";
+ case 37:
+ return "%";
+ case 38:
+ return "&";
+ case 39:
+ return "'";
+ case 40:
+ return "(";
+ case 41:
+ return ")";
+ case 42:
+ return "*";
+ case 43:
+ return "+";
+ case 44:
+ return ",";
+ case 45:
+ return "-";
+ case 46:
+ return ".";
+ case 47:
+ return "/";
+ case 48:
+ return "0";
+ case 49:
+ return "1";
+ case 50:
+ return "2";
+ case 51:
+ return "3";
+ case 52:
+ return "4";
+ case 53:
+ return "5";
+ case 54:
+ return "6";
+ case 55:
+ return "7";
+ case 56:
+ return "8";
+ case 57:
+ return "9";
+ case 58:
+ return ":";
+ case 59:
+ return ";";
+ case 60:
+ return "<";
+ case 61:
+ return "=";
+ case 62:
+ return ">";
+ case 63:
+ return "?";
+ case 64:
+ return "@";
+ case 65:
+ return "A";
+ case 66:
+ return "B";
+ case 67:
+ return "C";
+ case 68:
+ return "D";
+ case 69:
+ return "E";
+ case 70:
+ return "F";
+ case 71:
+ return "G";
+ case 72:
+ return "H";
+ case 73:
+ return "I";
+ case 74:
+ return "J";
+ case 75:
+ return "K";
+ case 76:
+ return "L";
+ case 77:
+ return "M";
+ case 78:
+ return "N";
+ case 79:
+ return "O";
+ case 80:
+ return "P";
+ case 81:
+ return "Q";
+ case 82:
+ return "R";
+ case 83:
+ return "S";
+ case 84:
+ return "T";
+ case 85:
+ return "U";
+ case 86:
+ return "V";
+ case 87:
+ return "W";
+ case 88:
+ return "X";
+ case 89:
+ return "Y";
+ case 90:
+ return "Z";
+ case 91:
+ return "[";
+ case 92:
+ return "\\\\";
+ case 93:
+ return "]";
+ case 94:
+ return "^";
+ case 95:
+ return "_";
+ case 96:
+ return "`";
+ case 97:
+ return "a";
+ case 98:
+ return "b";
+ case 99:
+ return "c";
+ case 100:
+ return "d";
+ case 101:
+ return "e";
+ case 102:
+ return "f";
+ case 103:
+ return "g";
+ case 104:
+ return "h";
+ case 105:
+ return "i";
+ case 106:
+ return "j";
+ case 107:
+ return "k";
+ case 108:
+ return "l";
+ case 109:
+ return "m";
+ case 110:
+ return "n";
+ case 111:
+ return "o";
+ case 112:
+ return "p";
+ case 113:
+ return "q";
+ case 114:
+ return "r";
+ case 115:
+ return "s";
+ case 116:
+ return "t";
+ case 117:
+ return "u";
+ case 118:
+ return "v";
+ case 119:
+ return "w";
+ case 120:
+ return "x";
+ case 121:
+ return "y";
+ case 122:
+ return "z";
+ case 123:
+ return "{";
+ case 124:
+ return "|";
+ case 125:
+ return "}";
+ case 126:
+ return "~";
+ case 127:
+ return "\\x7F";
+ case 128:
+ return "\\x80";
+ case 129:
+ return "\\x81";
+ case 130:
+ return "\\x82";
+ case 131:
+ return "\\x83";
+ case 132:
+ return "\\x84";
+ case 133:
+ return "\\x85";
+ case 134:
+ return "\\x86";
+ case 135:
+ return "\\x87";
+ case 136:
+ return "\\x88";
+ case 137:
+ return "\\x89";
+ case 138:
+ return "\\x8A";
+ case 139:
+ return "\\x8B";
+ case 140:
+ return "\\x8C";
+ case 141:
+ return "\\x8D";
+ case 142:
+ return "\\x8E";
+ case 143:
+ return "\\x8F";
+ case 144:
+ return "\\x90";
+ case 145:
+ return "\\x91";
+ case 146:
+ return "\\x92";
+ case 147:
+ return "\\x93";
+ case 148:
+ return "\\x94";
+ case 149:
+ return "\\x95";
+ case 150:
+ return "\\x96";
+ case 151:
+ return "\\x97";
+ case 152:
+ return "\\x98";
+ case 153:
+ return "\\x99";
+ case 154:
+ return "\\x9A";
+ case 155:
+ return "\\x9B";
+ case 156:
+ return "\\x9C";
+ case 157:
+ return "\\x9D";
+ case 158:
+ return "\\x9E";
+ case 159:
+ return "\\x9F";
+ case 160:
+ return "\\xA0";
+ case 161:
+ return "\\xA1";
+ case 162:
+ return "\\xA2";
+ case 163:
+ return "\\xA3";
+ case 164:
+ return "\\xA4";
+ case 165:
+ return "\\xA5";
+ case 166:
+ return "\\xA6";
+ case 167:
+ return "\\xA7";
+ case 168:
+ return "\\xA8";
+ case 169:
+ return "\\xA9";
+ case 170:
+ return "\\xAA";
+ case 171:
+ return "\\xAB";
+ case 172:
+ return "\\xAC";
+ case 173:
+ return "\\xAD";
+ case 174:
+ return "\\xAE";
+ case 175:
+ return "\\xAF";
+ case 176:
+ return "\\xB0";
+ case 177:
+ return "\\xB1";
+ case 178:
+ return "\\xB2";
+ case 179:
+ return "\\xB3";
+ case 180:
+ return "\\xB4";
+ case 181:
+ return "\\xB5";
+ case 182:
+ return "\\xB6";
+ case 183:
+ return "\\xB7";
+ case 184:
+ return "\\xB8";
+ case 185:
+ return "\\xB9";
+ case 186:
+ return "\\xBA";
+ case 187:
+ return "\\xBB";
+ case 188:
+ return "\\xBC";
+ case 189:
+ return "\\xBD";
+ case 190:
+ return "\\xBE";
+ case 191:
+ return "\\xBF";
+ case 192:
+ return "\\xC0";
+ case 193:
+ return "\\xC1";
+ case 194:
+ return "\\xC2";
+ case 195:
+ return "\\xC3";
+ case 196:
+ return "\\xC4";
+ case 197:
+ return "\\xC5";
+ case 198:
+ return "\\xC6";
+ case 199:
+ return "\\xC7";
+ case 200:
+ return "\\xC8";
+ case 201:
+ return "\\xC9";
+ case 202:
+ return "\\xCA";
+ case 203:
+ return "\\xCB";
+ case 204:
+ return "\\xCC";
+ case 205:
+ return "\\xCD";
+ case 206:
+ return "\\xCE";
+ case 207:
+ return "\\xCF";
+ case 208:
+ return "\\xD0";
+ case 209:
+ return "\\xD1";
+ case 210:
+ return "\\xD2";
+ case 211:
+ return "\\xD3";
+ case 212:
+ return "\\xD4";
+ case 213:
+ return "\\xD5";
+ case 214:
+ return "\\xD6";
+ case 215:
+ return "\\xD7";
+ case 216:
+ return "\\xD8";
+ case 217:
+ return "\\xD9";
+ case 218:
+ return "\\xDA";
+ case 219:
+ return "\\xDB";
+ case 220:
+ return "\\xDC";
+ case 221:
+ return "\\xDD";
+ case 222:
+ return "\\xDE";
+ case 223:
+ return "\\xDF";
+ case 224:
+ return "\\xE0";
+ case 225:
+ return "\\xE1";
+ case 226:
+ return "\\xE2";
+ case 227:
+ return "\\xE3";
+ case 228:
+ return "\\xE4";
+ case 229:
+ return "\\xE5";
+ case 230:
+ return "\\xE6";
+ case 231:
+ return "\\xE7";
+ case 232:
+ return "\\xE8";
+ case 233:
+ return "\\xE9";
+ case 234:
+ return "\\xEA";
+ case 235:
+ return "\\xEB";
+ case 236:
+ return "\\xEC";
+ case 237:
+ return "\\xED";
+ case 238:
+ return "\\xEE";
+ case 239:
+ return "\\xEF";
+ case 240:
+ return "\\xF0";
+ case 241:
+ return "\\xF1";
+ case 242:
+ return "\\xF2";
+ case 243:
+ return "\\xF3";
+ case 244:
+ return "\\xF4";
+ case 245:
+ return "\\xF5";
+ case 246:
+ return "\\xF6";
+ case 247:
+ return "\\xF7";
+ case 248:
+ return "\\xF8";
+ case 249:
+ return "\\xF9";
+ case 250:
+ return "\\xFA";
+ case 251:
+ return "\\xFB";
+ case 252:
+ return "\\xFC";
+ case 253:
+ return "\\xFD";
+ case 254:
+ return "\\xFE";
+ case 255:
+ return "\\xFF";
+ default:
+ assert(0); /* never gets here */
+ return "dead code";
+ }
+ assert(0); /* never gets here */
+}
+
+#endif /* XML_DTD */
+
+static unsigned long
+getDebugLevel(const char *variableName, unsigned long defaultDebugLevel) {
+ const char *const valueOrNull = getenv(variableName);
+ if (valueOrNull == NULL) {
+ return defaultDebugLevel;
+ }
+ const char *const value = valueOrNull;
+
+ errno = 0;
+ char *afterValue = (char *)value;
+ unsigned long debugLevel = strtoul(value, &afterValue, 10);
+ if ((errno != 0) || (afterValue[0] != '\0')) {
+ errno = 0;
+ return defaultDebugLevel;
+ }
+
+ return debugLevel;
+}
diff --git a/contrib/libs/expat/lib/xmlrole.c b/contrib/libs/expat/lib/xmlrole.c
index 3acb9c1568..77746ee42d 100644
--- a/contrib/libs/expat/lib/xmlrole.c
+++ b/contrib/libs/expat/lib/xmlrole.c
@@ -7,15 +7,15 @@
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
- Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
- Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net>
- Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
- Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
- Copyright (c) 2005-2009 Steven Solie <ssolie@users.sourceforge.net>
- Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org>
- Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
- Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
- Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
+ Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
+ Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net>
+ Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
+ Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
+ Copyright (c) 2005-2009 Steven Solie <ssolie@users.sourceforge.net>
+ Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
+ Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
+ Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -38,13 +38,13 @@
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#include <expat_config.h>
-
+#include <expat_config.h>
+
#include <stddef.h>
#ifdef _WIN32
# include "winconfig.h"
-#endif
+#endif
#include "expat_external.h"
#include "internal.h"
diff --git a/contrib/libs/expat/lib/xmlrole.h b/contrib/libs/expat/lib/xmlrole.h
index 5ff7fbe8a4..d6e1fa150a 100644
--- a/contrib/libs/expat/lib/xmlrole.h
+++ b/contrib/libs/expat/lib/xmlrole.h
@@ -7,10 +7,10 @@
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
- Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
- Copyright (c) 2002 Karl Waclawek <karl@waclawek.net>
- Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
- Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
+ Copyright (c) 2002 Karl Waclawek <karl@waclawek.net>
+ Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
+ Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/contrib/libs/expat/lib/xmltok.c b/contrib/libs/expat/lib/xmltok.c
index bd570e79a6..502ca1adc3 100644
--- a/contrib/libs/expat/lib/xmltok.c
+++ b/contrib/libs/expat/lib/xmltok.c
@@ -7,20 +7,20 @@
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
- Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
- Copyright (c) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
- Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net>
- Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net>
- Copyright (c) 2005-2009 Steven Solie <ssolie@users.sourceforge.net>
- Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org>
- Copyright (c) 2016 Pascal Cuoq <cuoq@trust-in-soft.com>
- Copyright (c) 2016 Don Lewis <truckman@apache.org>
- Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
- Copyright (c) 2017 Alexander Bluhm <alexander.bluhm@gmx.net>
- Copyright (c) 2017 Benbuck Nason <bnason@netflix.com>
- Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
- Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
- Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
+ Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
+ Copyright (c) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
+ Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net>
+ Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net>
+ Copyright (c) 2005-2009 Steven Solie <ssolie@users.sourceforge.net>
+ Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 2016 Pascal Cuoq <cuoq@trust-in-soft.com>
+ Copyright (c) 2016 Don Lewis <truckman@apache.org>
+ Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
+ Copyright (c) 2017 Alexander Bluhm <alexander.bluhm@gmx.net>
+ Copyright (c) 2017 Benbuck Nason <bnason@netflix.com>
+ Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
+ Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
+ Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -43,15 +43,15 @@
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#include <expat_config.h>
-
+#include <expat_config.h>
+
#include <stddef.h>
#include <string.h> /* memcpy */
-#include <stdbool.h>
+#include <stdbool.h>
#ifdef _WIN32
# include "winconfig.h"
-#endif
+#endif
#include "expat_external.h"
#include "internal.h"
@@ -272,14 +272,14 @@ sb_byteToAscii(const ENCODING *enc, const char *p) {
#define IS_NAME_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isName##n(enc, p))
#define IS_NMSTRT_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isNmstrt##n(enc, p))
-#ifdef XML_MIN_SIZE
-# define IS_INVALID_CHAR(enc, p, n) \
- (AS_NORMAL_ENCODING(enc)->isInvalid##n \
- && AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p))
-#else
-# define IS_INVALID_CHAR(enc, p, n) \
- (AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p))
-#endif
+#ifdef XML_MIN_SIZE
+# define IS_INVALID_CHAR(enc, p, n) \
+ (AS_NORMAL_ENCODING(enc)->isInvalid##n \
+ && AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p))
+#else
+# define IS_INVALID_CHAR(enc, p, n) \
+ (AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p))
+#endif
#ifdef XML_MIN_SIZE
# define IS_NAME_CHAR_MINBPC(enc, p) \
diff --git a/contrib/libs/expat/lib/xmltok.h b/contrib/libs/expat/lib/xmltok.h
index da84bfd9c2..6f630c2f9b 100644
--- a/contrib/libs/expat/lib/xmltok.h
+++ b/contrib/libs/expat/lib/xmltok.h
@@ -7,11 +7,11 @@
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
- Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
- Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
- Copyright (c) 2002-2005 Karl Waclawek <karl@waclawek.net>
- Copyright (c) 2016-2017 Sebastian Pipping <sebastian@pipping.org>
- Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
+ Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
+ Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
+ Copyright (c) 2002-2005 Karl Waclawek <karl@waclawek.net>
+ Copyright (c) 2016-2017 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/contrib/libs/expat/lib/xmltok_impl.c b/contrib/libs/expat/lib/xmltok_impl.c
index 2ff647d246..0430591b42 100644
--- a/contrib/libs/expat/lib/xmltok_impl.c
+++ b/contrib/libs/expat/lib/xmltok_impl.c
@@ -1,4 +1,4 @@
-/* This file is included (from xmltok.c, 1-3 times depending on XML_MIN_SIZE)!
+/* This file is included (from xmltok.c, 1-3 times depending on XML_MIN_SIZE)!
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
@@ -7,15 +7,15 @@
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
- Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
- Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
- Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net>
- Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org>
- Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
- Copyright (c) 2018 Benjamin Peterson <benjamin@python.org>
- Copyright (c) 2018 Anton Maklakov <antmak.pub@gmail.com>
- Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
- Copyright (c) 2020 Boris Kolpackov <boris@codesynthesis.com>
+ Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
+ Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
+ Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net>
+ Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
+ Copyright (c) 2018 Benjamin Peterson <benjamin@python.org>
+ Copyright (c) 2018 Anton Maklakov <antmak.pub@gmail.com>
+ Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
+ Copyright (c) 2020 Boris Kolpackov <boris@codesynthesis.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -40,7 +40,7 @@
#ifdef XML_TOK_IMPL_C
-# ifndef IS_INVALID_CHAR // i.e. for UTF-16 and XML_MIN_SIZE not defined
+# ifndef IS_INVALID_CHAR // i.e. for UTF-16 and XML_MIN_SIZE not defined
# define IS_INVALID_CHAR(enc, ptr, n) (0)
# endif
diff --git a/contrib/libs/expat/lib/xmltok_impl.h b/contrib/libs/expat/lib/xmltok_impl.h
index c7e97022f5..c518aada01 100644
--- a/contrib/libs/expat/lib/xmltok_impl.h
+++ b/contrib/libs/expat/lib/xmltok_impl.h
@@ -7,8 +7,8 @@
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
- Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
- Copyright (c) 2017-2019 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
+ Copyright (c) 2017-2019 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/contrib/libs/expat/lib/xmltok_ns.c b/contrib/libs/expat/lib/xmltok_ns.c
index d0619391f1..fbdd3e3c7b 100644
--- a/contrib/libs/expat/lib/xmltok_ns.c
+++ b/contrib/libs/expat/lib/xmltok_ns.c
@@ -7,10 +7,10 @@
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
- Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
- Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net>
- Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
- Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
+ Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
+ Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net>
+ Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
+ Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2017-2021 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
diff --git a/contrib/libs/expat/ya.make b/contrib/libs/expat/ya.make
index 3b6c6a7a10..8128621e60 100644
--- a/contrib/libs/expat/ya.make
+++ b/contrib/libs/expat/ya.make
@@ -7,9 +7,9 @@ OWNER(
g:cpp-contrib
)
-VERSION(2.4.4)
+VERSION(2.4.4)
-ORIGINAL_SOURCE(https://github.com/libexpat/libexpat/releases/download/R_2_4_4/expat-2.4.4.tar.xz)
+ORIGINAL_SOURCE(https://github.com/libexpat/libexpat/releases/download/R_2_4_4/expat-2.4.4.tar.xz)
LICENSE(
CC0-1.0 AND
diff --git a/contrib/libs/farmhash/ya.make b/contrib/libs/farmhash/ya.make
index a890e89ce1..5e1a631819 100644
--- a/contrib/libs/farmhash/ya.make
+++ b/contrib/libs/farmhash/ya.make
@@ -4,8 +4,8 @@ LICENSE(MIT)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(2017-06-26-23eecfbe7e84ebf2e229bd02248f431c36e12f1a)
-
+VERSION(2017-06-26-23eecfbe7e84ebf2e229bd02248f431c36e12f1a)
+
OWNER(somov)
ADDINCL(GLOBAL contrib/libs/farmhash/include)
diff --git a/contrib/libs/fastlz/ya.make b/contrib/libs/fastlz/ya.make
index 4bed8d10f9..7f31ac0bec 100644
--- a/contrib/libs/fastlz/ya.make
+++ b/contrib/libs/fastlz/ya.make
@@ -4,8 +4,8 @@ LICENSE(MIT)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(0.1.0)
-
+VERSION(0.1.0)
+
OWNER(
g:contrib
g:cpp-contrib
diff --git a/contrib/libs/grpc/src/proto/grpc/reflection/v1alpha/ya.make b/contrib/libs/grpc/src/proto/grpc/reflection/v1alpha/ya.make
index 9b3340ec94..f8e301c937 100644
--- a/contrib/libs/grpc/src/proto/grpc/reflection/v1alpha/ya.make
+++ b/contrib/libs/grpc/src/proto/grpc/reflection/v1alpha/ya.make
@@ -15,8 +15,8 @@ PROTO_NAMESPACE(
contrib/libs/grpc
)
-PY_NAMESPACE(src.proto.grpc.reflection.v1alpha)
-
+PY_NAMESPACE(src.proto.grpc.reflection.v1alpha)
+
GRPC()
SRCS(
diff --git a/contrib/libs/grpc/src/python/grpcio_reflection/grpc_reflection/v1alpha/reflection.py b/contrib/libs/grpc/src/python/grpcio_reflection/grpc_reflection/v1alpha/reflection.py
index e68c14162e..b302cea241 100644
--- a/contrib/libs/grpc/src/python/grpcio_reflection/grpc_reflection/v1alpha/reflection.py
+++ b/contrib/libs/grpc/src/python/grpcio_reflection/grpc_reflection/v1alpha/reflection.py
@@ -16,8 +16,8 @@
import sys
import grpc
-from src.proto.grpc.reflection.v1alpha import reflection_pb2 as _reflection_pb2
-from src.proto.grpc.reflection.v1alpha import reflection_pb2_grpc as _reflection_pb2_grpc
+from src.proto.grpc.reflection.v1alpha import reflection_pb2 as _reflection_pb2
+from src.proto.grpc.reflection.v1alpha import reflection_pb2_grpc as _reflection_pb2_grpc
from grpc_reflection.v1alpha._base import BaseReflectionServicer
diff --git a/contrib/libs/grpc/src/python/grpcio_reflection/ya.make b/contrib/libs/grpc/src/python/grpcio_reflection/ya.make
index ab45c17dd4..c0f7d61dcc 100644
--- a/contrib/libs/grpc/src/python/grpcio_reflection/ya.make
+++ b/contrib/libs/grpc/src/python/grpcio_reflection/ya.make
@@ -14,7 +14,7 @@ OWNER(
PEERDIR(
contrib/libs/grpc/grpc
contrib/python/six
- contrib/libs/grpc/src/proto/grpc/reflection/v1alpha
+ contrib/libs/grpc/src/proto/grpc/reflection/v1alpha
)
IF (PYTHON2)
diff --git a/contrib/libs/grpc/ya.make b/contrib/libs/grpc/ya.make
index 16ea547e00..29848d23ea 100644
--- a/contrib/libs/grpc/ya.make
+++ b/contrib/libs/grpc/ya.make
@@ -5,8 +5,8 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(1.33.2)
-
+VERSION(1.33.2)
+
ORIGINAL_SOURCE(https://github.com/grpc/grpc)
OWNER(
diff --git a/contrib/libs/hdr_histogram/ya.make b/contrib/libs/hdr_histogram/ya.make
index ffd8e27f13..b20d977b57 100644
--- a/contrib/libs/hdr_histogram/ya.make
+++ b/contrib/libs/hdr_histogram/ya.make
@@ -7,8 +7,8 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(0.9.5)
-
+VERSION(0.9.5)
+
OWNER(
jamel
g:contrib
diff --git a/contrib/libs/highwayhash/ya.make b/contrib/libs/highwayhash/ya.make
index 6f99adf7f6..4f6dad6193 100644
--- a/contrib/libs/highwayhash/ya.make
+++ b/contrib/libs/highwayhash/ya.make
@@ -4,8 +4,8 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(2017-05-08-2b666ae078292b01024453d01480f3b362a2a012)
-
+VERSION(2017-05-08-2b666ae078292b01024453d01480f3b362a2a012)
+
OWNER(somov)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/libaio/ya.make b/contrib/libs/libaio/ya.make
index dbab3827e6..3eb09b549b 100644
--- a/contrib/libs/libaio/ya.make
+++ b/contrib/libs/libaio/ya.make
@@ -7,8 +7,8 @@ LICENSE(Service-Dll-Harness)
WITHOUT_LICENSE_TEXTS()
-VERSION(2015-07-01-5a546a834c36070648158d19dd564762d59f8eb8)
-
+VERSION(2015-07-01-5a546a834c36070648158d19dd564762d59f8eb8)
+
OWNER(
g:contrib
g:cpp-contrib
diff --git a/contrib/libs/libunwind/include/__libunwind_config.h b/contrib/libs/libunwind/include/__libunwind_config.h
index d907fdf0e9..e87bcf4003 100644
--- a/contrib/libs/libunwind/include/__libunwind_config.h
+++ b/contrib/libs/libunwind/include/__libunwind_config.h
@@ -26,12 +26,12 @@
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC64 31
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON 34
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV 64
-#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE 143
+#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE 143
#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
-# if defined(__linux__)
-# define _LIBUNWIND_TARGET_LINUX 1
-# endif
+# if defined(__linux__)
+# define _LIBUNWIND_TARGET_LINUX 1
+# endif
# if defined(__i386__)
# define _LIBUNWIND_TARGET_I386
# define _LIBUNWIND_CONTEXT_SIZE 8
@@ -138,26 +138,26 @@
#define _LIBUNWIND_CONTEXT_SIZE 16
#define _LIBUNWIND_CURSOR_SIZE 23
# elif defined(__riscv)
-# define _LIBUNWIND_TARGET_RISCV 1
-# if defined(__riscv_flen)
-# define RISCV_FLEN __riscv_flen
+# define _LIBUNWIND_TARGET_RISCV 1
+# if defined(__riscv_flen)
+# define RISCV_FLEN __riscv_flen
+# else
+# define RISCV_FLEN 0
+# endif
+# define _LIBUNWIND_CONTEXT_SIZE (32 * (__riscv_xlen + RISCV_FLEN) / 64)
+# if __riscv_xlen == 32
+# define _LIBUNWIND_CURSOR_SIZE (_LIBUNWIND_CONTEXT_SIZE + 7)
+# elif __riscv_xlen == 64
+# define _LIBUNWIND_CURSOR_SIZE (_LIBUNWIND_CONTEXT_SIZE + 12)
# else
-# define RISCV_FLEN 0
+# error "Unsupported RISC-V ABI"
# endif
-# define _LIBUNWIND_CONTEXT_SIZE (32 * (__riscv_xlen + RISCV_FLEN) / 64)
-# if __riscv_xlen == 32
-# define _LIBUNWIND_CURSOR_SIZE (_LIBUNWIND_CONTEXT_SIZE + 7)
-# elif __riscv_xlen == 64
-# define _LIBUNWIND_CURSOR_SIZE (_LIBUNWIND_CONTEXT_SIZE + 12)
-# else
-# error "Unsupported RISC-V ABI"
-# endif
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV
-# elif defined(__ve__)
-# define _LIBUNWIND_TARGET_VE 1
-# define _LIBUNWIND_CONTEXT_SIZE 67
-# define _LIBUNWIND_CURSOR_SIZE 79
-# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE
+# elif defined(__ve__)
+# define _LIBUNWIND_TARGET_VE 1
+# define _LIBUNWIND_CONTEXT_SIZE 67
+# define _LIBUNWIND_CURSOR_SIZE 79
+# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE
# else
# error "Unsupported architecture."
# endif
@@ -175,7 +175,7 @@
# define _LIBUNWIND_TARGET_SPARC64 1
# define _LIBUNWIND_TARGET_HEXAGON 1
# define _LIBUNWIND_TARGET_RISCV 1
-# define _LIBUNWIND_TARGET_VE 1
+# define _LIBUNWIND_TARGET_VE 1
# define _LIBUNWIND_CONTEXT_SIZE 167
# define _LIBUNWIND_CURSOR_SIZE 179
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287
diff --git a/contrib/libs/libunwind/include/libunwind.h b/contrib/libs/libunwind/include/libunwind.h
index 1166e0ffbb..8303c1a04c 100644
--- a/contrib/libs/libunwind/include/libunwind.h
+++ b/contrib/libs/libunwind/include/libunwind.h
@@ -1022,156 +1022,156 @@ enum {
UNW_RISCV_F31 = 63,
};
-// VE register numbers
-enum {
- UNW_VE_S0 = 0,
- UNW_VE_S1 = 1,
- UNW_VE_S2 = 2,
- UNW_VE_S3 = 3,
- UNW_VE_S4 = 4,
- UNW_VE_S5 = 5,
- UNW_VE_S6 = 6,
- UNW_VE_S7 = 7,
- UNW_VE_S8 = 8,
- UNW_VE_S9 = 9,
- UNW_VE_S10 = 10,
- UNW_VE_S11 = 11,
- UNW_VE_S12 = 12,
- UNW_VE_S13 = 13,
- UNW_VE_S14 = 14,
- UNW_VE_S15 = 15,
- UNW_VE_S16 = 16,
- UNW_VE_S17 = 17,
- UNW_VE_S18 = 18,
- UNW_VE_S19 = 19,
- UNW_VE_S20 = 20,
- UNW_VE_S21 = 21,
- UNW_VE_S22 = 22,
- UNW_VE_S23 = 23,
- UNW_VE_S24 = 24,
- UNW_VE_S25 = 25,
- UNW_VE_S26 = 26,
- UNW_VE_S27 = 27,
- UNW_VE_S28 = 28,
- UNW_VE_S29 = 29,
- UNW_VE_S30 = 30,
- UNW_VE_S31 = 31,
- UNW_VE_S32 = 32,
- UNW_VE_S33 = 33,
- UNW_VE_S34 = 34,
- UNW_VE_S35 = 35,
- UNW_VE_S36 = 36,
- UNW_VE_S37 = 37,
- UNW_VE_S38 = 38,
- UNW_VE_S39 = 39,
- UNW_VE_S40 = 40,
- UNW_VE_S41 = 41,
- UNW_VE_S42 = 42,
- UNW_VE_S43 = 43,
- UNW_VE_S44 = 44,
- UNW_VE_S45 = 45,
- UNW_VE_S46 = 46,
- UNW_VE_S47 = 47,
- UNW_VE_S48 = 48,
- UNW_VE_S49 = 49,
- UNW_VE_S50 = 50,
- UNW_VE_S51 = 51,
- UNW_VE_S52 = 52,
- UNW_VE_S53 = 53,
- UNW_VE_S54 = 54,
- UNW_VE_S55 = 55,
- UNW_VE_S56 = 56,
- UNW_VE_S57 = 57,
- UNW_VE_S58 = 58,
- UNW_VE_S59 = 59,
- UNW_VE_S60 = 60,
- UNW_VE_S61 = 61,
- UNW_VE_S62 = 62,
- UNW_VE_S63 = 63,
- UNW_VE_V0 = 64 + 0,
- UNW_VE_V1 = 64 + 1,
- UNW_VE_V2 = 64 + 2,
- UNW_VE_V3 = 64 + 3,
- UNW_VE_V4 = 64 + 4,
- UNW_VE_V5 = 64 + 5,
- UNW_VE_V6 = 64 + 6,
- UNW_VE_V7 = 64 + 7,
- UNW_VE_V8 = 64 + 8,
- UNW_VE_V9 = 64 + 9,
- UNW_VE_V10 = 64 + 10,
- UNW_VE_V11 = 64 + 11,
- UNW_VE_V12 = 64 + 12,
- UNW_VE_V13 = 64 + 13,
- UNW_VE_V14 = 64 + 14,
- UNW_VE_V15 = 64 + 15,
- UNW_VE_V16 = 64 + 16,
- UNW_VE_V17 = 64 + 17,
- UNW_VE_V18 = 64 + 18,
- UNW_VE_V19 = 64 + 19,
- UNW_VE_V20 = 64 + 20,
- UNW_VE_V21 = 64 + 21,
- UNW_VE_V22 = 64 + 22,
- UNW_VE_V23 = 64 + 23,
- UNW_VE_V24 = 64 + 24,
- UNW_VE_V25 = 64 + 25,
- UNW_VE_V26 = 64 + 26,
- UNW_VE_V27 = 64 + 27,
- UNW_VE_V28 = 64 + 28,
- UNW_VE_V29 = 64 + 29,
- UNW_VE_V30 = 64 + 30,
- UNW_VE_V31 = 64 + 31,
- UNW_VE_V32 = 64 + 32,
- UNW_VE_V33 = 64 + 33,
- UNW_VE_V34 = 64 + 34,
- UNW_VE_V35 = 64 + 35,
- UNW_VE_V36 = 64 + 36,
- UNW_VE_V37 = 64 + 37,
- UNW_VE_V38 = 64 + 38,
- UNW_VE_V39 = 64 + 39,
- UNW_VE_V40 = 64 + 40,
- UNW_VE_V41 = 64 + 41,
- UNW_VE_V42 = 64 + 42,
- UNW_VE_V43 = 64 + 43,
- UNW_VE_V44 = 64 + 44,
- UNW_VE_V45 = 64 + 45,
- UNW_VE_V46 = 64 + 46,
- UNW_VE_V47 = 64 + 47,
- UNW_VE_V48 = 64 + 48,
- UNW_VE_V49 = 64 + 49,
- UNW_VE_V50 = 64 + 50,
- UNW_VE_V51 = 64 + 51,
- UNW_VE_V52 = 64 + 52,
- UNW_VE_V53 = 64 + 53,
- UNW_VE_V54 = 64 + 54,
- UNW_VE_V55 = 64 + 55,
- UNW_VE_V56 = 64 + 56,
- UNW_VE_V57 = 64 + 57,
- UNW_VE_V58 = 64 + 58,
- UNW_VE_V59 = 64 + 59,
- UNW_VE_V60 = 64 + 60,
- UNW_VE_V61 = 64 + 61,
- UNW_VE_V62 = 64 + 62,
- UNW_VE_V63 = 64 + 63,
- UNW_VE_VM0 = 128 + 0,
- UNW_VE_VM1 = 128 + 1,
- UNW_VE_VM2 = 128 + 2,
- UNW_VE_VM3 = 128 + 3,
- UNW_VE_VM4 = 128 + 4,
- UNW_VE_VM5 = 128 + 5,
- UNW_VE_VM6 = 128 + 6,
- UNW_VE_VM7 = 128 + 7,
- UNW_VE_VM8 = 128 + 8,
- UNW_VE_VM9 = 128 + 9,
- UNW_VE_VM10 = 128 + 10,
- UNW_VE_VM11 = 128 + 11,
- UNW_VE_VM12 = 128 + 12,
- UNW_VE_VM13 = 128 + 13,
- UNW_VE_VM14 = 128 + 14,
- UNW_VE_VM15 = 128 + 15, // = 143
-
- // Following registers don't have DWARF register numbers.
- UNW_VE_VIXR = 144,
- UNW_VE_VL = 145,
-};
-
+// VE register numbers
+enum {
+ UNW_VE_S0 = 0,
+ UNW_VE_S1 = 1,
+ UNW_VE_S2 = 2,
+ UNW_VE_S3 = 3,
+ UNW_VE_S4 = 4,
+ UNW_VE_S5 = 5,
+ UNW_VE_S6 = 6,
+ UNW_VE_S7 = 7,
+ UNW_VE_S8 = 8,
+ UNW_VE_S9 = 9,
+ UNW_VE_S10 = 10,
+ UNW_VE_S11 = 11,
+ UNW_VE_S12 = 12,
+ UNW_VE_S13 = 13,
+ UNW_VE_S14 = 14,
+ UNW_VE_S15 = 15,
+ UNW_VE_S16 = 16,
+ UNW_VE_S17 = 17,
+ UNW_VE_S18 = 18,
+ UNW_VE_S19 = 19,
+ UNW_VE_S20 = 20,
+ UNW_VE_S21 = 21,
+ UNW_VE_S22 = 22,
+ UNW_VE_S23 = 23,
+ UNW_VE_S24 = 24,
+ UNW_VE_S25 = 25,
+ UNW_VE_S26 = 26,
+ UNW_VE_S27 = 27,
+ UNW_VE_S28 = 28,
+ UNW_VE_S29 = 29,
+ UNW_VE_S30 = 30,
+ UNW_VE_S31 = 31,
+ UNW_VE_S32 = 32,
+ UNW_VE_S33 = 33,
+ UNW_VE_S34 = 34,
+ UNW_VE_S35 = 35,
+ UNW_VE_S36 = 36,
+ UNW_VE_S37 = 37,
+ UNW_VE_S38 = 38,
+ UNW_VE_S39 = 39,
+ UNW_VE_S40 = 40,
+ UNW_VE_S41 = 41,
+ UNW_VE_S42 = 42,
+ UNW_VE_S43 = 43,
+ UNW_VE_S44 = 44,
+ UNW_VE_S45 = 45,
+ UNW_VE_S46 = 46,
+ UNW_VE_S47 = 47,
+ UNW_VE_S48 = 48,
+ UNW_VE_S49 = 49,
+ UNW_VE_S50 = 50,
+ UNW_VE_S51 = 51,
+ UNW_VE_S52 = 52,
+ UNW_VE_S53 = 53,
+ UNW_VE_S54 = 54,
+ UNW_VE_S55 = 55,
+ UNW_VE_S56 = 56,
+ UNW_VE_S57 = 57,
+ UNW_VE_S58 = 58,
+ UNW_VE_S59 = 59,
+ UNW_VE_S60 = 60,
+ UNW_VE_S61 = 61,
+ UNW_VE_S62 = 62,
+ UNW_VE_S63 = 63,
+ UNW_VE_V0 = 64 + 0,
+ UNW_VE_V1 = 64 + 1,
+ UNW_VE_V2 = 64 + 2,
+ UNW_VE_V3 = 64 + 3,
+ UNW_VE_V4 = 64 + 4,
+ UNW_VE_V5 = 64 + 5,
+ UNW_VE_V6 = 64 + 6,
+ UNW_VE_V7 = 64 + 7,
+ UNW_VE_V8 = 64 + 8,
+ UNW_VE_V9 = 64 + 9,
+ UNW_VE_V10 = 64 + 10,
+ UNW_VE_V11 = 64 + 11,
+ UNW_VE_V12 = 64 + 12,
+ UNW_VE_V13 = 64 + 13,
+ UNW_VE_V14 = 64 + 14,
+ UNW_VE_V15 = 64 + 15,
+ UNW_VE_V16 = 64 + 16,
+ UNW_VE_V17 = 64 + 17,
+ UNW_VE_V18 = 64 + 18,
+ UNW_VE_V19 = 64 + 19,
+ UNW_VE_V20 = 64 + 20,
+ UNW_VE_V21 = 64 + 21,
+ UNW_VE_V22 = 64 + 22,
+ UNW_VE_V23 = 64 + 23,
+ UNW_VE_V24 = 64 + 24,
+ UNW_VE_V25 = 64 + 25,
+ UNW_VE_V26 = 64 + 26,
+ UNW_VE_V27 = 64 + 27,
+ UNW_VE_V28 = 64 + 28,
+ UNW_VE_V29 = 64 + 29,
+ UNW_VE_V30 = 64 + 30,
+ UNW_VE_V31 = 64 + 31,
+ UNW_VE_V32 = 64 + 32,
+ UNW_VE_V33 = 64 + 33,
+ UNW_VE_V34 = 64 + 34,
+ UNW_VE_V35 = 64 + 35,
+ UNW_VE_V36 = 64 + 36,
+ UNW_VE_V37 = 64 + 37,
+ UNW_VE_V38 = 64 + 38,
+ UNW_VE_V39 = 64 + 39,
+ UNW_VE_V40 = 64 + 40,
+ UNW_VE_V41 = 64 + 41,
+ UNW_VE_V42 = 64 + 42,
+ UNW_VE_V43 = 64 + 43,
+ UNW_VE_V44 = 64 + 44,
+ UNW_VE_V45 = 64 + 45,
+ UNW_VE_V46 = 64 + 46,
+ UNW_VE_V47 = 64 + 47,
+ UNW_VE_V48 = 64 + 48,
+ UNW_VE_V49 = 64 + 49,
+ UNW_VE_V50 = 64 + 50,
+ UNW_VE_V51 = 64 + 51,
+ UNW_VE_V52 = 64 + 52,
+ UNW_VE_V53 = 64 + 53,
+ UNW_VE_V54 = 64 + 54,
+ UNW_VE_V55 = 64 + 55,
+ UNW_VE_V56 = 64 + 56,
+ UNW_VE_V57 = 64 + 57,
+ UNW_VE_V58 = 64 + 58,
+ UNW_VE_V59 = 64 + 59,
+ UNW_VE_V60 = 64 + 60,
+ UNW_VE_V61 = 64 + 61,
+ UNW_VE_V62 = 64 + 62,
+ UNW_VE_V63 = 64 + 63,
+ UNW_VE_VM0 = 128 + 0,
+ UNW_VE_VM1 = 128 + 1,
+ UNW_VE_VM2 = 128 + 2,
+ UNW_VE_VM3 = 128 + 3,
+ UNW_VE_VM4 = 128 + 4,
+ UNW_VE_VM5 = 128 + 5,
+ UNW_VE_VM6 = 128 + 6,
+ UNW_VE_VM7 = 128 + 7,
+ UNW_VE_VM8 = 128 + 8,
+ UNW_VE_VM9 = 128 + 9,
+ UNW_VE_VM10 = 128 + 10,
+ UNW_VE_VM11 = 128 + 11,
+ UNW_VE_VM12 = 128 + 12,
+ UNW_VE_VM13 = 128 + 13,
+ UNW_VE_VM14 = 128 + 14,
+ UNW_VE_VM15 = 128 + 15, // = 143
+
+ // Following registers don't have DWARF register numbers.
+ UNW_VE_VIXR = 144,
+ UNW_VE_VL = 145,
+};
+
#endif
diff --git a/contrib/libs/libunwind/src/DwarfInstructions.hpp b/contrib/libs/libunwind/src/DwarfInstructions.hpp
index 98c8fb2b40..c1a241c55c 100644
--- a/contrib/libs/libunwind/src/DwarfInstructions.hpp
+++ b/contrib/libs/libunwind/src/DwarfInstructions.hpp
@@ -236,7 +236,7 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
// to a NOP on pre-v8.3a architectures.
if ((R::getArch() == REGISTERS_ARM64) &&
prolog.savedRegisters[UNW_AARCH64_RA_SIGN_STATE].value &&
- returnAddress != 0) {
+ returnAddress != 0) {
#if !defined(_LIBUNWIND_IS_NATIVE_ONLY)
return UNW_ECROSSRASIGNING;
#else
diff --git a/contrib/libs/libunwind/src/Registers.hpp b/contrib/libs/libunwind/src/Registers.hpp
index 7ab71ded44..cbc3876d67 100644
--- a/contrib/libs/libunwind/src/Registers.hpp
+++ b/contrib/libs/libunwind/src/Registers.hpp
@@ -38,7 +38,7 @@ enum {
REGISTERS_SPARC64,
REGISTERS_HEXAGON,
REGISTERS_RISCV,
- REGISTERS_VE,
+ REGISTERS_VE,
};
#if defined(_LIBUNWIND_TARGET_I386)
@@ -1868,7 +1868,7 @@ inline bool Registers_arm64::validRegister(int regNum) const {
return false;
if (regNum == UNW_AARCH64_RA_SIGN_STATE)
return true;
- if ((regNum > 32) && (regNum < 64))
+ if ((regNum > 32) && (regNum < 64))
return false;
return true;
}
@@ -1881,10 +1881,10 @@ inline uint64_t Registers_arm64::getRegister(int regNum) const {
if (regNum == UNW_AARCH64_RA_SIGN_STATE)
return _registers.__ra_sign_state;
if (regNum == UNW_AARCH64_FP)
- return _registers.__fp;
+ return _registers.__fp;
if (regNum == UNW_AARCH64_LR)
- return _registers.__lr;
- if ((regNum >= 0) && (regNum < 29))
+ return _registers.__lr;
+ if ((regNum >= 0) && (regNum < 29))
return _registers.__x[regNum];
_LIBUNWIND_ABORT("unsupported arm64 register");
}
@@ -1897,10 +1897,10 @@ inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
else if (regNum == UNW_AARCH64_RA_SIGN_STATE)
_registers.__ra_sign_state = value;
else if (regNum == UNW_AARCH64_FP)
- _registers.__fp = value;
+ _registers.__fp = value;
else if (regNum == UNW_AARCH64_LR)
- _registers.__lr = value;
- else if ((regNum >= 0) && (regNum < 29))
+ _registers.__lr = value;
+ else if ((regNum >= 0) && (regNum < 29))
_registers.__x[regNum] = value;
else
_LIBUNWIND_ABORT("unsupported arm64 register");
@@ -1977,7 +1977,7 @@ inline const char *Registers_arm64::getRegisterName(int regNum) {
case UNW_AARCH64_SP:
return "sp";
case UNW_AARCH64_PC:
- return "pc";
+ return "pc";
case UNW_AARCH64_V0:
return "d0";
case UNW_AARCH64_V1:
@@ -3954,51 +3954,51 @@ inline const char *Registers_hexagon::getRegisterName(int regNum) {
#if defined(_LIBUNWIND_TARGET_RISCV)
-/// Registers_riscv holds the register state of a thread in a RISC-V
+/// Registers_riscv holds the register state of a thread in a RISC-V
/// process.
-
-// This check makes it safe when LIBUNWIND_ENABLE_CROSS_UNWINDING enabled.
-# ifdef __riscv
-# if __riscv_xlen == 32
-typedef uint32_t reg_t;
-# elif __riscv_xlen == 64
-typedef uint64_t reg_t;
-# else
-# error "Unsupported __riscv_xlen"
-# endif
-
-# if defined(__riscv_flen)
-# if __riscv_flen == 64
-typedef double fp_t;
-# elif __riscv_flen == 32
-typedef float fp_t;
-# else
-# error "Unsupported __riscv_flen"
-# endif
-# else
-// This is just for supressing undeclared error of fp_t.
-typedef double fp_t;
-# endif
-# else
-// Use Max possible width when cross unwinding
-typedef uint64_t reg_t;
-typedef double fp_t;
-# define __riscv_xlen 64
-# define __riscv_flen 64
-#endif
-
-/// Registers_riscv holds the register state of a thread.
+
+// This check makes it safe when LIBUNWIND_ENABLE_CROSS_UNWINDING enabled.
+# ifdef __riscv
+# if __riscv_xlen == 32
+typedef uint32_t reg_t;
+# elif __riscv_xlen == 64
+typedef uint64_t reg_t;
+# else
+# error "Unsupported __riscv_xlen"
+# endif
+
+# if defined(__riscv_flen)
+# if __riscv_flen == 64
+typedef double fp_t;
+# elif __riscv_flen == 32
+typedef float fp_t;
+# else
+# error "Unsupported __riscv_flen"
+# endif
+# else
+// This is just for supressing undeclared error of fp_t.
+typedef double fp_t;
+# endif
+# else
+// Use Max possible width when cross unwinding
+typedef uint64_t reg_t;
+typedef double fp_t;
+# define __riscv_xlen 64
+# define __riscv_flen 64
+#endif
+
+/// Registers_riscv holds the register state of a thread.
class _LIBUNWIND_HIDDEN Registers_riscv {
public:
Registers_riscv();
Registers_riscv(const void *registers);
bool validRegister(int num) const;
- reg_t getRegister(int num) const;
- void setRegister(int num, reg_t value);
+ reg_t getRegister(int num) const;
+ void setRegister(int num, reg_t value);
bool validFloatRegister(int num) const;
- fp_t getFloatRegister(int num) const;
- void setFloatRegister(int num, fp_t value);
+ fp_t getFloatRegister(int num) const;
+ void setFloatRegister(int num, fp_t value);
bool validVectorRegister(int num) const;
v128 getVectorRegister(int num) const;
void setVectorRegister(int num, v128 value);
@@ -4007,45 +4007,45 @@ public:
static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; }
static int getArch() { return REGISTERS_RISCV; }
- reg_t getSP() const { return _registers[2]; }
- void setSP(reg_t value) { _registers[2] = value; }
- reg_t getIP() const { return _registers[0]; }
- void setIP(reg_t value) { _registers[0] = value; }
+ reg_t getSP() const { return _registers[2]; }
+ void setSP(reg_t value) { _registers[2] = value; }
+ reg_t getIP() const { return _registers[0]; }
+ void setIP(reg_t value) { _registers[0] = value; }
private:
// _registers[0] holds the pc
- reg_t _registers[32];
-# if defined(__riscv_flen)
- fp_t _floats[32];
-# endif
+ reg_t _registers[32];
+# if defined(__riscv_flen)
+ fp_t _floats[32];
+# endif
};
inline Registers_riscv::Registers_riscv(const void *registers) {
static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),
"riscv registers do not fit into unw_context_t");
memcpy(&_registers, registers, sizeof(_registers));
-# if __riscv_xlen == 32
- static_assert(sizeof(_registers) == 0x80,
- "expected float registers to be at offset 128");
-# elif __riscv_xlen == 64
+# if __riscv_xlen == 32
+ static_assert(sizeof(_registers) == 0x80,
+ "expected float registers to be at offset 128");
+# elif __riscv_xlen == 64
static_assert(sizeof(_registers) == 0x100,
"expected float registers to be at offset 256");
-# else
-# error "Unexpected float registers."
-# endif
-
-# if defined(__riscv_flen)
+# else
+# error "Unexpected float registers."
+# endif
+
+# if defined(__riscv_flen)
memcpy(_floats,
static_cast<const uint8_t *>(registers) + sizeof(_registers),
sizeof(_floats));
-# endif
+# endif
}
inline Registers_riscv::Registers_riscv() {
memset(&_registers, 0, sizeof(_registers));
-# if defined(__riscv_flen)
+# if defined(__riscv_flen)
memset(&_floats, 0, sizeof(_floats));
-# endif
+# endif
}
inline bool Registers_riscv::validRegister(int regNum) const {
@@ -4060,7 +4060,7 @@ inline bool Registers_riscv::validRegister(int regNum) const {
return true;
}
-inline reg_t Registers_riscv::getRegister(int regNum) const {
+inline reg_t Registers_riscv::getRegister(int regNum) const {
if (regNum == UNW_REG_IP)
return _registers[0];
if (regNum == UNW_REG_SP)
@@ -4072,7 +4072,7 @@ inline reg_t Registers_riscv::getRegister(int regNum) const {
_LIBUNWIND_ABORT("unsupported riscv register");
}
-inline void Registers_riscv::setRegister(int regNum, reg_t value) {
+inline void Registers_riscv::setRegister(int regNum, reg_t value) {
if (regNum == UNW_REG_IP)
_registers[0] = value;
else if (regNum == UNW_REG_SP)
@@ -4226,37 +4226,37 @@ inline const char *Registers_riscv::getRegisterName(int regNum) {
}
inline bool Registers_riscv::validFloatRegister(int regNum) const {
-# if defined(__riscv_flen)
+# if defined(__riscv_flen)
if (regNum < UNW_RISCV_F0)
return false;
if (regNum > UNW_RISCV_F31)
return false;
return true;
-# else
- (void)regNum;
- return false;
-# endif
+# else
+ (void)regNum;
+ return false;
+# endif
}
-inline fp_t Registers_riscv::getFloatRegister(int regNum) const {
-# if defined(__riscv_flen)
+inline fp_t Registers_riscv::getFloatRegister(int regNum) const {
+# if defined(__riscv_flen)
assert(validFloatRegister(regNum));
return _floats[regNum - UNW_RISCV_F0];
-# else
+# else
(void)regNum;
_LIBUNWIND_ABORT("libunwind not built with float support");
-# endif
+# endif
}
-inline void Registers_riscv::setFloatRegister(int regNum, fp_t value) {
-# if defined(__riscv_flen)
+inline void Registers_riscv::setFloatRegister(int regNum, fp_t value) {
+# if defined(__riscv_flen)
assert(validFloatRegister(regNum));
_floats[regNum - UNW_RISCV_F0] = value;
-# else
+# else
(void)regNum;
(void)value;
_LIBUNWIND_ABORT("libunwind not built with float support");
-# endif
+# endif
}
inline bool Registers_riscv::validVectorRegister(int) const {
@@ -4271,447 +4271,447 @@ inline void Registers_riscv::setVectorRegister(int, v128) {
_LIBUNWIND_ABORT("no riscv vector register support yet");
}
#endif // _LIBUNWIND_TARGET_RISCV
-
-#if defined(_LIBUNWIND_TARGET_VE)
-/// Registers_ve holds the register state of a thread in a VE process.
-class _LIBUNWIND_HIDDEN Registers_ve {
-public:
- Registers_ve();
- Registers_ve(const void *registers);
-
- bool validRegister(int num) const;
- uint64_t getRegister(int num) const;
- void setRegister(int num, uint64_t value);
- bool validFloatRegister(int num) const;
- double getFloatRegister(int num) const;
- void setFloatRegister(int num, double value);
- bool validVectorRegister(int num) const;
- v128 getVectorRegister(int num) const;
- void setVectorRegister(int num, v128 value);
- static const char *getRegisterName(int num);
- void jumpto();
- static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE; }
- static int getArch() { return REGISTERS_VE; }
-
- uint64_t getSP() const { return _registers.__s[11]; }
- void setSP(uint64_t value) { _registers.__s[11] = value; }
- uint64_t getIP() const { return _registers.__ic; }
- void setIP(uint64_t value) { _registers.__ic = value; }
-
-private:
- // FIXME: Need to store not only scalar registers but also vector and vector
- // mask registers. VEOS uses mcontext_t defined in ucontext.h. It takes
- // 524288 bytes (65536*8 bytes), though. Currently, we use libunwind for
- // SjLj exception support only, so Registers_ve is not implemented completely.
- struct ve_thread_state_t {
- uint64_t __s[64]; // s0-s64
- uint64_t __ic; // Instruction counter (IC)
- uint64_t __vixr; // Vector Index Register
- uint64_t __vl; // Vector Length Register
- };
-
- ve_thread_state_t _registers; // total 67 registers
-
- // Currently no vector register is preserved.
-};
-
-inline Registers_ve::Registers_ve(const void *registers) {
- static_assert((check_fit<Registers_ve, unw_context_t>::does_fit),
- "ve registers do not fit into unw_context_t");
- memcpy(&_registers, static_cast<const uint8_t *>(registers),
- sizeof(_registers));
- static_assert(sizeof(_registers) == 536,
- "expected vector register offset to be 536");
-}
-
-inline Registers_ve::Registers_ve() {
- memset(&_registers, 0, sizeof(_registers));
-}
-
-inline bool Registers_ve::validRegister(int regNum) const {
- if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63)
- return true;
-
- switch (regNum) {
- case UNW_REG_IP:
- case UNW_REG_SP:
- case UNW_VE_VIXR:
- case UNW_VE_VL:
- return true;
- default:
- return false;
- }
-}
-
-inline uint64_t Registers_ve::getRegister(int regNum) const {
- if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63)
- return _registers.__s[regNum - UNW_VE_S0];
-
- switch (regNum) {
- case UNW_REG_IP:
- return _registers.__ic;
- case UNW_REG_SP:
- return _registers.__s[11];
- case UNW_VE_VIXR:
- return _registers.__vixr;
- case UNW_VE_VL:
- return _registers.__vl;
- }
- _LIBUNWIND_ABORT("unsupported ve register");
-}
-
-inline void Registers_ve::setRegister(int regNum, uint64_t value) {
- if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63) {
- _registers.__s[regNum - UNW_VE_S0] = value;
- return;
- }
-
- switch (regNum) {
- case UNW_REG_IP:
- _registers.__ic = value;
- return;
- case UNW_REG_SP:
- _registers.__s[11] = value;
- return;
- case UNW_VE_VIXR:
- _registers.__vixr = value;
- return;
- case UNW_VE_VL:
- _registers.__vl = value;
- return;
- }
- _LIBUNWIND_ABORT("unsupported ve register");
-}
-
-inline bool Registers_ve::validFloatRegister(int /* regNum */) const {
- return false;
-}
-
-inline double Registers_ve::getFloatRegister(int /* regNum */) const {
- _LIBUNWIND_ABORT("VE doesn't have float registers");
-}
-
-inline void Registers_ve::setFloatRegister(int /* regNum */,
- double /* value */) {
- _LIBUNWIND_ABORT("VE doesn't have float registers");
-}
-
-inline bool Registers_ve::validVectorRegister(int /* regNum */) const {
- return false;
-}
-
-inline v128 Registers_ve::getVectorRegister(int /* regNum */) const {
- _LIBUNWIND_ABORT("VE vector support not implemented");
-}
-
-inline void Registers_ve::setVectorRegister(int /* regNum */,
- v128 /* value */) {
- _LIBUNWIND_ABORT("VE vector support not implemented");
-}
-
-inline const char *Registers_ve::getRegisterName(int regNum) {
- switch (regNum) {
- case UNW_REG_IP:
- return "ip";
- case UNW_REG_SP:
- return "sp";
- case UNW_VE_VIXR:
- return "vixr";
- case UNW_VE_VL:
- return "vl";
- case UNW_VE_S0:
- return "s0";
- case UNW_VE_S1:
- return "s1";
- case UNW_VE_S2:
- return "s2";
- case UNW_VE_S3:
- return "s3";
- case UNW_VE_S4:
- return "s4";
- case UNW_VE_S5:
- return "s5";
- case UNW_VE_S6:
- return "s6";
- case UNW_VE_S7:
- return "s7";
- case UNW_VE_S8:
- return "s8";
- case UNW_VE_S9:
- return "s9";
- case UNW_VE_S10:
- return "s10";
- case UNW_VE_S11:
- return "s11";
- case UNW_VE_S12:
- return "s12";
- case UNW_VE_S13:
- return "s13";
- case UNW_VE_S14:
- return "s14";
- case UNW_VE_S15:
- return "s15";
- case UNW_VE_S16:
- return "s16";
- case UNW_VE_S17:
- return "s17";
- case UNW_VE_S18:
- return "s18";
- case UNW_VE_S19:
- return "s19";
- case UNW_VE_S20:
- return "s20";
- case UNW_VE_S21:
- return "s21";
- case UNW_VE_S22:
- return "s22";
- case UNW_VE_S23:
- return "s23";
- case UNW_VE_S24:
- return "s24";
- case UNW_VE_S25:
- return "s25";
- case UNW_VE_S26:
- return "s26";
- case UNW_VE_S27:
- return "s27";
- case UNW_VE_S28:
- return "s28";
- case UNW_VE_S29:
- return "s29";
- case UNW_VE_S30:
- return "s30";
- case UNW_VE_S31:
- return "s31";
- case UNW_VE_S32:
- return "s32";
- case UNW_VE_S33:
- return "s33";
- case UNW_VE_S34:
- return "s34";
- case UNW_VE_S35:
- return "s35";
- case UNW_VE_S36:
- return "s36";
- case UNW_VE_S37:
- return "s37";
- case UNW_VE_S38:
- return "s38";
- case UNW_VE_S39:
- return "s39";
- case UNW_VE_S40:
- return "s40";
- case UNW_VE_S41:
- return "s41";
- case UNW_VE_S42:
- return "s42";
- case UNW_VE_S43:
- return "s43";
- case UNW_VE_S44:
- return "s44";
- case UNW_VE_S45:
- return "s45";
- case UNW_VE_S46:
- return "s46";
- case UNW_VE_S47:
- return "s47";
- case UNW_VE_S48:
- return "s48";
- case UNW_VE_S49:
- return "s49";
- case UNW_VE_S50:
- return "s50";
- case UNW_VE_S51:
- return "s51";
- case UNW_VE_S52:
- return "s52";
- case UNW_VE_S53:
- return "s53";
- case UNW_VE_S54:
- return "s54";
- case UNW_VE_S55:
- return "s55";
- case UNW_VE_S56:
- return "s56";
- case UNW_VE_S57:
- return "s57";
- case UNW_VE_S58:
- return "s58";
- case UNW_VE_S59:
- return "s59";
- case UNW_VE_S60:
- return "s60";
- case UNW_VE_S61:
- return "s61";
- case UNW_VE_S62:
- return "s62";
- case UNW_VE_S63:
- return "s63";
- case UNW_VE_V0:
- return "v0";
- case UNW_VE_V1:
- return "v1";
- case UNW_VE_V2:
- return "v2";
- case UNW_VE_V3:
- return "v3";
- case UNW_VE_V4:
- return "v4";
- case UNW_VE_V5:
- return "v5";
- case UNW_VE_V6:
- return "v6";
- case UNW_VE_V7:
- return "v7";
- case UNW_VE_V8:
- return "v8";
- case UNW_VE_V9:
- return "v9";
- case UNW_VE_V10:
- return "v10";
- case UNW_VE_V11:
- return "v11";
- case UNW_VE_V12:
- return "v12";
- case UNW_VE_V13:
- return "v13";
- case UNW_VE_V14:
- return "v14";
- case UNW_VE_V15:
- return "v15";
- case UNW_VE_V16:
- return "v16";
- case UNW_VE_V17:
- return "v17";
- case UNW_VE_V18:
- return "v18";
- case UNW_VE_V19:
- return "v19";
- case UNW_VE_V20:
- return "v20";
- case UNW_VE_V21:
- return "v21";
- case UNW_VE_V22:
- return "v22";
- case UNW_VE_V23:
- return "v23";
- case UNW_VE_V24:
- return "v24";
- case UNW_VE_V25:
- return "v25";
- case UNW_VE_V26:
- return "v26";
- case UNW_VE_V27:
- return "v27";
- case UNW_VE_V28:
- return "v28";
- case UNW_VE_V29:
- return "v29";
- case UNW_VE_V30:
- return "v30";
- case UNW_VE_V31:
- return "v31";
- case UNW_VE_V32:
- return "v32";
- case UNW_VE_V33:
- return "v33";
- case UNW_VE_V34:
- return "v34";
- case UNW_VE_V35:
- return "v35";
- case UNW_VE_V36:
- return "v36";
- case UNW_VE_V37:
- return "v37";
- case UNW_VE_V38:
- return "v38";
- case UNW_VE_V39:
- return "v39";
- case UNW_VE_V40:
- return "v40";
- case UNW_VE_V41:
- return "v41";
- case UNW_VE_V42:
- return "v42";
- case UNW_VE_V43:
- return "v43";
- case UNW_VE_V44:
- return "v44";
- case UNW_VE_V45:
- return "v45";
- case UNW_VE_V46:
- return "v46";
- case UNW_VE_V47:
- return "v47";
- case UNW_VE_V48:
- return "v48";
- case UNW_VE_V49:
- return "v49";
- case UNW_VE_V50:
- return "v50";
- case UNW_VE_V51:
- return "v51";
- case UNW_VE_V52:
- return "v52";
- case UNW_VE_V53:
- return "v53";
- case UNW_VE_V54:
- return "v54";
- case UNW_VE_V55:
- return "v55";
- case UNW_VE_V56:
- return "v56";
- case UNW_VE_V57:
- return "v57";
- case UNW_VE_V58:
- return "v58";
- case UNW_VE_V59:
- return "v59";
- case UNW_VE_V60:
- return "v60";
- case UNW_VE_V61:
- return "v61";
- case UNW_VE_V62:
- return "v62";
- case UNW_VE_V63:
- return "v63";
- case UNW_VE_VM0:
- return "vm0";
- case UNW_VE_VM1:
- return "vm1";
- case UNW_VE_VM2:
- return "vm2";
- case UNW_VE_VM3:
- return "vm3";
- case UNW_VE_VM4:
- return "vm4";
- case UNW_VE_VM5:
- return "vm5";
- case UNW_VE_VM6:
- return "vm6";
- case UNW_VE_VM7:
- return "vm7";
- case UNW_VE_VM8:
- return "vm8";
- case UNW_VE_VM9:
- return "vm9";
- case UNW_VE_VM10:
- return "vm10";
- case UNW_VE_VM11:
- return "vm11";
- case UNW_VE_VM12:
- return "vm12";
- case UNW_VE_VM13:
- return "vm13";
- case UNW_VE_VM14:
- return "vm14";
- case UNW_VE_VM15:
- return "vm15";
- }
- return "unknown register";
-}
-#endif // _LIBUNWIND_TARGET_VE
-
+
+#if defined(_LIBUNWIND_TARGET_VE)
+/// Registers_ve holds the register state of a thread in a VE process.
+class _LIBUNWIND_HIDDEN Registers_ve {
+public:
+ Registers_ve();
+ Registers_ve(const void *registers);
+
+ bool validRegister(int num) const;
+ uint64_t getRegister(int num) const;
+ void setRegister(int num, uint64_t value);
+ bool validFloatRegister(int num) const;
+ double getFloatRegister(int num) const;
+ void setFloatRegister(int num, double value);
+ bool validVectorRegister(int num) const;
+ v128 getVectorRegister(int num) const;
+ void setVectorRegister(int num, v128 value);
+ static const char *getRegisterName(int num);
+ void jumpto();
+ static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE; }
+ static int getArch() { return REGISTERS_VE; }
+
+ uint64_t getSP() const { return _registers.__s[11]; }
+ void setSP(uint64_t value) { _registers.__s[11] = value; }
+ uint64_t getIP() const { return _registers.__ic; }
+ void setIP(uint64_t value) { _registers.__ic = value; }
+
+private:
+ // FIXME: Need to store not only scalar registers but also vector and vector
+ // mask registers. VEOS uses mcontext_t defined in ucontext.h. It takes
+ // 524288 bytes (65536*8 bytes), though. Currently, we use libunwind for
+ // SjLj exception support only, so Registers_ve is not implemented completely.
+ struct ve_thread_state_t {
+ uint64_t __s[64]; // s0-s64
+ uint64_t __ic; // Instruction counter (IC)
+ uint64_t __vixr; // Vector Index Register
+ uint64_t __vl; // Vector Length Register
+ };
+
+ ve_thread_state_t _registers; // total 67 registers
+
+ // Currently no vector register is preserved.
+};
+
+inline Registers_ve::Registers_ve(const void *registers) {
+ static_assert((check_fit<Registers_ve, unw_context_t>::does_fit),
+ "ve registers do not fit into unw_context_t");
+ memcpy(&_registers, static_cast<const uint8_t *>(registers),
+ sizeof(_registers));
+ static_assert(sizeof(_registers) == 536,
+ "expected vector register offset to be 536");
+}
+
+inline Registers_ve::Registers_ve() {
+ memset(&_registers, 0, sizeof(_registers));
+}
+
+inline bool Registers_ve::validRegister(int regNum) const {
+ if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63)
+ return true;
+
+ switch (regNum) {
+ case UNW_REG_IP:
+ case UNW_REG_SP:
+ case UNW_VE_VIXR:
+ case UNW_VE_VL:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline uint64_t Registers_ve::getRegister(int regNum) const {
+ if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63)
+ return _registers.__s[regNum - UNW_VE_S0];
+
+ switch (regNum) {
+ case UNW_REG_IP:
+ return _registers.__ic;
+ case UNW_REG_SP:
+ return _registers.__s[11];
+ case UNW_VE_VIXR:
+ return _registers.__vixr;
+ case UNW_VE_VL:
+ return _registers.__vl;
+ }
+ _LIBUNWIND_ABORT("unsupported ve register");
+}
+
+inline void Registers_ve::setRegister(int regNum, uint64_t value) {
+ if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63) {
+ _registers.__s[regNum - UNW_VE_S0] = value;
+ return;
+ }
+
+ switch (regNum) {
+ case UNW_REG_IP:
+ _registers.__ic = value;
+ return;
+ case UNW_REG_SP:
+ _registers.__s[11] = value;
+ return;
+ case UNW_VE_VIXR:
+ _registers.__vixr = value;
+ return;
+ case UNW_VE_VL:
+ _registers.__vl = value;
+ return;
+ }
+ _LIBUNWIND_ABORT("unsupported ve register");
+}
+
+inline bool Registers_ve::validFloatRegister(int /* regNum */) const {
+ return false;
+}
+
+inline double Registers_ve::getFloatRegister(int /* regNum */) const {
+ _LIBUNWIND_ABORT("VE doesn't have float registers");
+}
+
+inline void Registers_ve::setFloatRegister(int /* regNum */,
+ double /* value */) {
+ _LIBUNWIND_ABORT("VE doesn't have float registers");
+}
+
+inline bool Registers_ve::validVectorRegister(int /* regNum */) const {
+ return false;
+}
+
+inline v128 Registers_ve::getVectorRegister(int /* regNum */) const {
+ _LIBUNWIND_ABORT("VE vector support not implemented");
+}
+
+inline void Registers_ve::setVectorRegister(int /* regNum */,
+ v128 /* value */) {
+ _LIBUNWIND_ABORT("VE vector support not implemented");
+}
+
+inline const char *Registers_ve::getRegisterName(int regNum) {
+ switch (regNum) {
+ case UNW_REG_IP:
+ return "ip";
+ case UNW_REG_SP:
+ return "sp";
+ case UNW_VE_VIXR:
+ return "vixr";
+ case UNW_VE_VL:
+ return "vl";
+ case UNW_VE_S0:
+ return "s0";
+ case UNW_VE_S1:
+ return "s1";
+ case UNW_VE_S2:
+ return "s2";
+ case UNW_VE_S3:
+ return "s3";
+ case UNW_VE_S4:
+ return "s4";
+ case UNW_VE_S5:
+ return "s5";
+ case UNW_VE_S6:
+ return "s6";
+ case UNW_VE_S7:
+ return "s7";
+ case UNW_VE_S8:
+ return "s8";
+ case UNW_VE_S9:
+ return "s9";
+ case UNW_VE_S10:
+ return "s10";
+ case UNW_VE_S11:
+ return "s11";
+ case UNW_VE_S12:
+ return "s12";
+ case UNW_VE_S13:
+ return "s13";
+ case UNW_VE_S14:
+ return "s14";
+ case UNW_VE_S15:
+ return "s15";
+ case UNW_VE_S16:
+ return "s16";
+ case UNW_VE_S17:
+ return "s17";
+ case UNW_VE_S18:
+ return "s18";
+ case UNW_VE_S19:
+ return "s19";
+ case UNW_VE_S20:
+ return "s20";
+ case UNW_VE_S21:
+ return "s21";
+ case UNW_VE_S22:
+ return "s22";
+ case UNW_VE_S23:
+ return "s23";
+ case UNW_VE_S24:
+ return "s24";
+ case UNW_VE_S25:
+ return "s25";
+ case UNW_VE_S26:
+ return "s26";
+ case UNW_VE_S27:
+ return "s27";
+ case UNW_VE_S28:
+ return "s28";
+ case UNW_VE_S29:
+ return "s29";
+ case UNW_VE_S30:
+ return "s30";
+ case UNW_VE_S31:
+ return "s31";
+ case UNW_VE_S32:
+ return "s32";
+ case UNW_VE_S33:
+ return "s33";
+ case UNW_VE_S34:
+ return "s34";
+ case UNW_VE_S35:
+ return "s35";
+ case UNW_VE_S36:
+ return "s36";
+ case UNW_VE_S37:
+ return "s37";
+ case UNW_VE_S38:
+ return "s38";
+ case UNW_VE_S39:
+ return "s39";
+ case UNW_VE_S40:
+ return "s40";
+ case UNW_VE_S41:
+ return "s41";
+ case UNW_VE_S42:
+ return "s42";
+ case UNW_VE_S43:
+ return "s43";
+ case UNW_VE_S44:
+ return "s44";
+ case UNW_VE_S45:
+ return "s45";
+ case UNW_VE_S46:
+ return "s46";
+ case UNW_VE_S47:
+ return "s47";
+ case UNW_VE_S48:
+ return "s48";
+ case UNW_VE_S49:
+ return "s49";
+ case UNW_VE_S50:
+ return "s50";
+ case UNW_VE_S51:
+ return "s51";
+ case UNW_VE_S52:
+ return "s52";
+ case UNW_VE_S53:
+ return "s53";
+ case UNW_VE_S54:
+ return "s54";
+ case UNW_VE_S55:
+ return "s55";
+ case UNW_VE_S56:
+ return "s56";
+ case UNW_VE_S57:
+ return "s57";
+ case UNW_VE_S58:
+ return "s58";
+ case UNW_VE_S59:
+ return "s59";
+ case UNW_VE_S60:
+ return "s60";
+ case UNW_VE_S61:
+ return "s61";
+ case UNW_VE_S62:
+ return "s62";
+ case UNW_VE_S63:
+ return "s63";
+ case UNW_VE_V0:
+ return "v0";
+ case UNW_VE_V1:
+ return "v1";
+ case UNW_VE_V2:
+ return "v2";
+ case UNW_VE_V3:
+ return "v3";
+ case UNW_VE_V4:
+ return "v4";
+ case UNW_VE_V5:
+ return "v5";
+ case UNW_VE_V6:
+ return "v6";
+ case UNW_VE_V7:
+ return "v7";
+ case UNW_VE_V8:
+ return "v8";
+ case UNW_VE_V9:
+ return "v9";
+ case UNW_VE_V10:
+ return "v10";
+ case UNW_VE_V11:
+ return "v11";
+ case UNW_VE_V12:
+ return "v12";
+ case UNW_VE_V13:
+ return "v13";
+ case UNW_VE_V14:
+ return "v14";
+ case UNW_VE_V15:
+ return "v15";
+ case UNW_VE_V16:
+ return "v16";
+ case UNW_VE_V17:
+ return "v17";
+ case UNW_VE_V18:
+ return "v18";
+ case UNW_VE_V19:
+ return "v19";
+ case UNW_VE_V20:
+ return "v20";
+ case UNW_VE_V21:
+ return "v21";
+ case UNW_VE_V22:
+ return "v22";
+ case UNW_VE_V23:
+ return "v23";
+ case UNW_VE_V24:
+ return "v24";
+ case UNW_VE_V25:
+ return "v25";
+ case UNW_VE_V26:
+ return "v26";
+ case UNW_VE_V27:
+ return "v27";
+ case UNW_VE_V28:
+ return "v28";
+ case UNW_VE_V29:
+ return "v29";
+ case UNW_VE_V30:
+ return "v30";
+ case UNW_VE_V31:
+ return "v31";
+ case UNW_VE_V32:
+ return "v32";
+ case UNW_VE_V33:
+ return "v33";
+ case UNW_VE_V34:
+ return "v34";
+ case UNW_VE_V35:
+ return "v35";
+ case UNW_VE_V36:
+ return "v36";
+ case UNW_VE_V37:
+ return "v37";
+ case UNW_VE_V38:
+ return "v38";
+ case UNW_VE_V39:
+ return "v39";
+ case UNW_VE_V40:
+ return "v40";
+ case UNW_VE_V41:
+ return "v41";
+ case UNW_VE_V42:
+ return "v42";
+ case UNW_VE_V43:
+ return "v43";
+ case UNW_VE_V44:
+ return "v44";
+ case UNW_VE_V45:
+ return "v45";
+ case UNW_VE_V46:
+ return "v46";
+ case UNW_VE_V47:
+ return "v47";
+ case UNW_VE_V48:
+ return "v48";
+ case UNW_VE_V49:
+ return "v49";
+ case UNW_VE_V50:
+ return "v50";
+ case UNW_VE_V51:
+ return "v51";
+ case UNW_VE_V52:
+ return "v52";
+ case UNW_VE_V53:
+ return "v53";
+ case UNW_VE_V54:
+ return "v54";
+ case UNW_VE_V55:
+ return "v55";
+ case UNW_VE_V56:
+ return "v56";
+ case UNW_VE_V57:
+ return "v57";
+ case UNW_VE_V58:
+ return "v58";
+ case UNW_VE_V59:
+ return "v59";
+ case UNW_VE_V60:
+ return "v60";
+ case UNW_VE_V61:
+ return "v61";
+ case UNW_VE_V62:
+ return "v62";
+ case UNW_VE_V63:
+ return "v63";
+ case UNW_VE_VM0:
+ return "vm0";
+ case UNW_VE_VM1:
+ return "vm1";
+ case UNW_VE_VM2:
+ return "vm2";
+ case UNW_VE_VM3:
+ return "vm3";
+ case UNW_VE_VM4:
+ return "vm4";
+ case UNW_VE_VM5:
+ return "vm5";
+ case UNW_VE_VM6:
+ return "vm6";
+ case UNW_VE_VM7:
+ return "vm7";
+ case UNW_VE_VM8:
+ return "vm8";
+ case UNW_VE_VM9:
+ return "vm9";
+ case UNW_VE_VM10:
+ return "vm10";
+ case UNW_VE_VM11:
+ return "vm11";
+ case UNW_VE_VM12:
+ return "vm12";
+ case UNW_VE_VM13:
+ return "vm13";
+ case UNW_VE_VM14:
+ return "vm14";
+ case UNW_VE_VM15:
+ return "vm15";
+ }
+ return "unknown register";
+}
+#endif // _LIBUNWIND_TARGET_VE
+
} // namespace libunwind
#endif // __REGISTERS_HPP__
diff --git a/contrib/libs/libunwind/src/Unwind-sjlj.c b/contrib/libs/libunwind/src/Unwind-sjlj.c
index 539f570568..d487995bb7 100644
--- a/contrib/libs/libunwind/src/Unwind-sjlj.c
+++ b/contrib/libs/libunwind/src/Unwind-sjlj.c
@@ -32,23 +32,23 @@ struct _Unwind_FunctionContext {
// next function in stack of handlers
struct _Unwind_FunctionContext *prev;
-#if defined(__ve__)
- // VE requires to store 64 bit pointers in the buffer for SjLj execption.
- // We expand the size of values defined here. This size must be matched
- // to the size returned by TargetMachine::getSjLjDataSize().
-
+#if defined(__ve__)
+ // VE requires to store 64 bit pointers in the buffer for SjLj execption.
+ // We expand the size of values defined here. This size must be matched
+ // to the size returned by TargetMachine::getSjLjDataSize().
+
+ // set by calling function before registering to be the landing pad
+ uint64_t resumeLocation;
+
+ // set by personality handler to be parameters passed to landing pad function
+ uint64_t resumeParameters[4];
+#else
// set by calling function before registering to be the landing pad
- uint64_t resumeLocation;
-
- // set by personality handler to be parameters passed to landing pad function
- uint64_t resumeParameters[4];
-#else
- // set by calling function before registering to be the landing pad
uint32_t resumeLocation;
// set by personality handler to be parameters passed to landing pad function
uint32_t resumeParameters[4];
-#endif
+#endif
// set by calling function before registering
_Unwind_Personality_Fn personality; // arm offset=24
diff --git a/contrib/libs/libunwind/src/UnwindCursor.hpp b/contrib/libs/libunwind/src/UnwindCursor.hpp
index 4043552099..1ca842f33a 100644
--- a/contrib/libs/libunwind/src/UnwindCursor.hpp
+++ b/contrib/libs/libunwind/src/UnwindCursor.hpp
@@ -937,25 +937,25 @@ private:
}
#endif
-#if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
- bool setInfoForSigReturn() {
- R dummy;
- return setInfoForSigReturn(dummy);
- }
- int stepThroughSigReturn() {
- R dummy;
- return stepThroughSigReturn(dummy);
- }
- bool setInfoForSigReturn(Registers_arm64 &);
- int stepThroughSigReturn(Registers_arm64 &);
- template <typename Registers> bool setInfoForSigReturn(Registers &) {
- return false;
- }
- template <typename Registers> int stepThroughSigReturn(Registers &) {
- return UNW_STEP_END;
- }
-#endif
-
+#if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
+ bool setInfoForSigReturn() {
+ R dummy;
+ return setInfoForSigReturn(dummy);
+ }
+ int stepThroughSigReturn() {
+ R dummy;
+ return stepThroughSigReturn(dummy);
+ }
+ bool setInfoForSigReturn(Registers_arm64 &);
+ int stepThroughSigReturn(Registers_arm64 &);
+ template <typename Registers> bool setInfoForSigReturn(Registers &) {
+ return false;
+ }
+ template <typename Registers> int stepThroughSigReturn(Registers &) {
+ return UNW_STEP_END;
+ }
+#endif
+
#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
bool getInfoFromFdeCie(const typename CFI_Parser<A>::FDE_Info &fdeInfo,
const typename CFI_Parser<A>::CIE_Info &cieInfo,
@@ -1226,9 +1226,9 @@ private:
unw_proc_info_t _info;
bool _unwindInfoMissing;
bool _isSignalFrame;
-#if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
- bool _isSigReturn = false;
-#endif
+#if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
+ bool _isSigReturn = false;
+#endif
};
@@ -1925,11 +1925,11 @@ bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) {
template <typename A, typename R>
void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
-#if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
- _isSigReturn = false;
-#endif
-
- pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
+#if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
+ _isSigReturn = false;
+#endif
+
+ pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
#if defined(_LIBUNWIND_ARM_EHABI)
// Remove the thumb bit so the IP represents the actual instruction address.
// This matches the behaviour of _Unwind_GetIP on arm.
@@ -2027,78 +2027,78 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
}
#endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
-#if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
- if (setInfoForSigReturn())
- return;
-#endif
-
+#if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
+ if (setInfoForSigReturn())
+ return;
+#endif
+
// no unwind info, flag that we can't reliably unwind
_unwindInfoMissing = true;
}
-#if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
+#if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
+template <typename A, typename R>
+bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_arm64 &) {
+ // Look for the sigreturn trampoline. The trampoline's body is two
+ // specific instructions (see below). Typically the trampoline comes from the
+ // vDSO[1] (i.e. the __kernel_rt_sigreturn function). A libc might provide its
+ // own restorer function, though, or user-mode QEMU might write a trampoline
+ // onto the stack.
+ //
+ // This special code path is a fallback that is only used if the trampoline
+ // lacks proper (e.g. DWARF) unwind info. On AArch64, a new DWARF register
+ // constant for the PC needs to be defined before DWARF can handle a signal
+ // trampoline. This code may segfault if the target PC is unreadable, e.g.:
+ // - The PC points at a function compiled without unwind info, and which is
+ // part of an execute-only mapping (e.g. using -Wl,--execute-only).
+ // - The PC is invalid and happens to point to unreadable or unmapped memory.
+ //
+ // [1] https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/vdso/sigreturn.S
+ const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
+ // Look for instructions: mov x8, #0x8b; svc #0x0
+ if (_addressSpace.get32(pc) == 0xd2801168 &&
+ _addressSpace.get32(pc + 4) == 0xd4000001) {
+ _info = {};
+ _isSigReturn = true;
+ return true;
+ }
+ return false;
+}
+
template <typename A, typename R>
-bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_arm64 &) {
- // Look for the sigreturn trampoline. The trampoline's body is two
- // specific instructions (see below). Typically the trampoline comes from the
- // vDSO[1] (i.e. the __kernel_rt_sigreturn function). A libc might provide its
- // own restorer function, though, or user-mode QEMU might write a trampoline
- // onto the stack.
- //
- // This special code path is a fallback that is only used if the trampoline
- // lacks proper (e.g. DWARF) unwind info. On AArch64, a new DWARF register
- // constant for the PC needs to be defined before DWARF can handle a signal
- // trampoline. This code may segfault if the target PC is unreadable, e.g.:
- // - The PC points at a function compiled without unwind info, and which is
- // part of an execute-only mapping (e.g. using -Wl,--execute-only).
- // - The PC is invalid and happens to point to unreadable or unmapped memory.
- //
- // [1] https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/vdso/sigreturn.S
- const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
- // Look for instructions: mov x8, #0x8b; svc #0x0
- if (_addressSpace.get32(pc) == 0xd2801168 &&
- _addressSpace.get32(pc + 4) == 0xd4000001) {
- _info = {};
- _isSigReturn = true;
- return true;
- }
- return false;
-}
-
-template <typename A, typename R>
-int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) {
- // In the signal trampoline frame, sp points to an rt_sigframe[1], which is:
- // - 128-byte siginfo struct
- // - ucontext struct:
- // - 8-byte long (uc_flags)
- // - 8-byte pointer (uc_link)
- // - 24-byte stack_t
- // - 128-byte signal set
- // - 8 bytes of padding because sigcontext has 16-byte alignment
- // - sigcontext/mcontext_t
- // [1] https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/signal.c
- const pint_t kOffsetSpToSigcontext = (128 + 8 + 8 + 24 + 128 + 8); // 304
-
- // Offsets from sigcontext to each register.
- const pint_t kOffsetGprs = 8; // offset to "__u64 regs[31]" field
- const pint_t kOffsetSp = 256; // offset to "__u64 sp" field
- const pint_t kOffsetPc = 264; // offset to "__u64 pc" field
-
- pint_t sigctx = _registers.getSP() + kOffsetSpToSigcontext;
-
- for (int i = 0; i <= 30; ++i) {
- uint64_t value = _addressSpace.get64(sigctx + kOffsetGprs +
- static_cast<pint_t>(i * 8));
+int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) {
+ // In the signal trampoline frame, sp points to an rt_sigframe[1], which is:
+ // - 128-byte siginfo struct
+ // - ucontext struct:
+ // - 8-byte long (uc_flags)
+ // - 8-byte pointer (uc_link)
+ // - 24-byte stack_t
+ // - 128-byte signal set
+ // - 8 bytes of padding because sigcontext has 16-byte alignment
+ // - sigcontext/mcontext_t
+ // [1] https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/signal.c
+ const pint_t kOffsetSpToSigcontext = (128 + 8 + 8 + 24 + 128 + 8); // 304
+
+ // Offsets from sigcontext to each register.
+ const pint_t kOffsetGprs = 8; // offset to "__u64 regs[31]" field
+ const pint_t kOffsetSp = 256; // offset to "__u64 sp" field
+ const pint_t kOffsetPc = 264; // offset to "__u64 pc" field
+
+ pint_t sigctx = _registers.getSP() + kOffsetSpToSigcontext;
+
+ for (int i = 0; i <= 30; ++i) {
+ uint64_t value = _addressSpace.get64(sigctx + kOffsetGprs +
+ static_cast<pint_t>(i * 8));
_registers.setRegister(UNW_AARCH64_X0 + i, value);
- }
- _registers.setSP(_addressSpace.get64(sigctx + kOffsetSp));
- _registers.setIP(_addressSpace.get64(sigctx + kOffsetPc));
- _isSignalFrame = true;
- return UNW_STEP_SUCCESS;
-}
-#endif // defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
-
-template <typename A, typename R>
+ }
+ _registers.setSP(_addressSpace.get64(sigctx + kOffsetSp));
+ _registers.setIP(_addressSpace.get64(sigctx + kOffsetPc));
+ _isSignalFrame = true;
+ return UNW_STEP_SUCCESS;
+}
+#endif // defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
+
+template <typename A, typename R>
int UnwindCursor<A, R>::step() {
// Bottom of stack is defined is when unwind info cannot be found.
if (_unwindInfoMissing)
@@ -2106,27 +2106,27 @@ int UnwindCursor<A, R>::step() {
// Use unwinding info to modify register set as if function returned.
int result;
-#if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
- if (_isSigReturn) {
- result = this->stepThroughSigReturn();
- } else
-#endif
- {
+#if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
+ if (_isSigReturn) {
+ result = this->stepThroughSigReturn();
+ } else
+#endif
+ {
#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
- result = this->stepWithCompactEncoding();
+ result = this->stepWithCompactEncoding();
#elif defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
- result = this->stepWithSEHData();
+ result = this->stepWithSEHData();
#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
- result = this->stepWithDwarfFDE();
+ result = this->stepWithDwarfFDE();
#elif defined(_LIBUNWIND_ARM_EHABI)
- result = this->stepWithEHABI();
+ result = this->stepWithEHABI();
#else
#error Need _LIBUNWIND_SUPPORT_COMPACT_UNWIND or \
_LIBUNWIND_SUPPORT_SEH_UNWIND or \
_LIBUNWIND_SUPPORT_DWARF_UNWIND or \
_LIBUNWIND_ARM_EHABI
#endif
- }
+ }
// update info based on new PC
if (result == UNW_STEP_SUCCESS) {
diff --git a/contrib/libs/libunwind/src/UnwindRegistersRestore.S b/contrib/libs/libunwind/src/UnwindRegistersRestore.S
index 4824be8ed9..1df97f5fc4 100644
--- a/contrib/libs/libunwind/src/UnwindRegistersRestore.S
+++ b/contrib/libs/libunwind/src/UnwindRegistersRestore.S
@@ -139,7 +139,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv)
// load register (GPR)
#define PPC64_LR(n) \
- ld n, (8 * (n + 2))(3)
+ ld n, (8 * (n + 2))(3)
// restore integral registers
// skip r0 for now
@@ -181,12 +181,12 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv)
// (note that this also restores floating point registers and V registers,
// because part of VS is mapped to these registers)
- addi 4, 3, PPC64_OFFS_FP
+ addi 4, 3, PPC64_OFFS_FP
// load VS register
#define PPC64_LVS(n) \
- lxvd2x n, 0, 4 ;\
- addi 4, 4, 16
+ lxvd2x n, 0, 4 ;\
+ addi 4, 4, 16
// restore the first 32 VS regs (and also all floating point regs)
PPC64_LVS(0)
@@ -225,23 +225,23 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv)
// use VRSAVE to conditionally restore the remaining VS regs,
// that are where the V regs are mapped
- ld 5, PPC64_OFFS_VRSAVE(3) // test VRsave
- cmpwi 5, 0
+ ld 5, PPC64_OFFS_VRSAVE(3) // test VRsave
+ cmpwi 5, 0
beq Lnovec
// conditionally load VS
#define PPC64_CLVS_BOTTOM(n) \
beq Ldone##n ;\
- addi 4, 3, PPC64_OFFS_FP + n * 16 ;\
- lxvd2x n, 0, 4 ;\
+ addi 4, 3, PPC64_OFFS_FP + n * 16 ;\
+ lxvd2x n, 0, 4 ;\
Ldone##n:
-#define PPC64_CLVSl(n) \
- andis. 0, 5, (1 PPC_LEFT_SHIFT(47-n)) ;\
+#define PPC64_CLVSl(n) \
+ andis. 0, 5, (1 PPC_LEFT_SHIFT(47-n)) ;\
PPC64_CLVS_BOTTOM(n)
-#define PPC64_CLVSh(n) \
- andi. 0, 5, (1 PPC_LEFT_SHIFT(63-n)) ;\
+#define PPC64_CLVSh(n) \
+ andi. 0, 5, (1 PPC_LEFT_SHIFT(63-n)) ;\
PPC64_CLVS_BOTTOM(n)
PPC64_CLVSl(32)
@@ -281,7 +281,7 @@ PPC64_CLVS_BOTTOM(n)
// load FP register
#define PPC64_LF(n) \
- lfd n, (PPC64_OFFS_FP + n * 16)(3)
+ lfd n, (PPC64_OFFS_FP + n * 16)(3)
// restore float registers
PPC64_LF(0)
@@ -319,30 +319,30 @@ PPC64_CLVS_BOTTOM(n)
#if defined(__ALTIVEC__)
// restore vector registers if any are in use
- ld 5, PPC64_OFFS_VRSAVE(3) // test VRsave
- cmpwi 5, 0
+ ld 5, PPC64_OFFS_VRSAVE(3) // test VRsave
+ cmpwi 5, 0
beq Lnovec
- subi 4, 1, 16
+ subi 4, 1, 16
// r4 is now a 16-byte aligned pointer into the red zone
// the _vectorScalarRegisters may not be 16-byte aligned
// so copy via red zone temp buffer
#define PPC64_CLV_UNALIGNED_BOTTOM(n) \
beq Ldone##n ;\
- ld 0, (PPC64_OFFS_V + n * 16)(3) ;\
- std 0, 0(4) ;\
- ld 0, (PPC64_OFFS_V + n * 16 + 8)(3) ;\
- std 0, 8(4) ;\
- lvx n, 0, 4 ;\
+ ld 0, (PPC64_OFFS_V + n * 16)(3) ;\
+ std 0, 0(4) ;\
+ ld 0, (PPC64_OFFS_V + n * 16 + 8)(3) ;\
+ std 0, 8(4) ;\
+ lvx n, 0, 4 ;\
Ldone ## n:
-#define PPC64_CLV_UNALIGNEDl(n) \
- andis. 0, 5, (1 PPC_LEFT_SHIFT(15-n)) ;\
+#define PPC64_CLV_UNALIGNEDl(n) \
+ andis. 0, 5, (1 PPC_LEFT_SHIFT(15-n)) ;\
PPC64_CLV_UNALIGNED_BOTTOM(n)
-#define PPC64_CLV_UNALIGNEDh(n) \
- andi. 0, 5, (1 PPC_LEFT_SHIFT(31-n)) ;\
+#define PPC64_CLV_UNALIGNEDh(n) \
+ andi. 0, 5, (1 PPC_LEFT_SHIFT(31-n)) ;\
PPC64_CLV_UNALIGNED_BOTTOM(n)
PPC64_CLV_UNALIGNEDl(0)
@@ -382,10 +382,10 @@ PPC64_CLV_UNALIGNED_BOTTOM(n)
#endif
Lnovec:
- ld 0, PPC64_OFFS_CR(3)
- mtcr 0
- ld 0, PPC64_OFFS_SRR0(3)
- mtctr 0
+ ld 0, PPC64_OFFS_CR(3)
+ mtcr 0
+ ld 0, PPC64_OFFS_SRR0(3)
+ mtctr 0
PPC64_LR(0)
PPC64_LR(5)
@@ -407,111 +407,111 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)
// restore integral registerrs
// skip r0 for now
// skip r1 for now
- lwz 2, 16(3)
+ lwz 2, 16(3)
// skip r3 for now
// skip r4 for now
// skip r5 for now
- lwz 6, 32(3)
- lwz 7, 36(3)
- lwz 8, 40(3)
- lwz 9, 44(3)
- lwz 10, 48(3)
- lwz 11, 52(3)
- lwz 12, 56(3)
- lwz 13, 60(3)
- lwz 14, 64(3)
- lwz 15, 68(3)
- lwz 16, 72(3)
- lwz 17, 76(3)
- lwz 18, 80(3)
- lwz 19, 84(3)
- lwz 20, 88(3)
- lwz 21, 92(3)
- lwz 22, 96(3)
- lwz 23,100(3)
- lwz 24,104(3)
- lwz 25,108(3)
- lwz 26,112(3)
- lwz 27,116(3)
- lwz 28,120(3)
- lwz 29,124(3)
- lwz 30,128(3)
- lwz 31,132(3)
+ lwz 6, 32(3)
+ lwz 7, 36(3)
+ lwz 8, 40(3)
+ lwz 9, 44(3)
+ lwz 10, 48(3)
+ lwz 11, 52(3)
+ lwz 12, 56(3)
+ lwz 13, 60(3)
+ lwz 14, 64(3)
+ lwz 15, 68(3)
+ lwz 16, 72(3)
+ lwz 17, 76(3)
+ lwz 18, 80(3)
+ lwz 19, 84(3)
+ lwz 20, 88(3)
+ lwz 21, 92(3)
+ lwz 22, 96(3)
+ lwz 23,100(3)
+ lwz 24,104(3)
+ lwz 25,108(3)
+ lwz 26,112(3)
+ lwz 27,116(3)
+ lwz 28,120(3)
+ lwz 29,124(3)
+ lwz 30,128(3)
+ lwz 31,132(3)
#ifndef __NO_FPRS__
// restore float registers
- lfd 0, 160(3)
- lfd 1, 168(3)
- lfd 2, 176(3)
- lfd 3, 184(3)
- lfd 4, 192(3)
- lfd 5, 200(3)
- lfd 6, 208(3)
- lfd 7, 216(3)
- lfd 8, 224(3)
- lfd 9, 232(3)
- lfd 10,240(3)
- lfd 11,248(3)
- lfd 12,256(3)
- lfd 13,264(3)
- lfd 14,272(3)
- lfd 15,280(3)
- lfd 16,288(3)
- lfd 17,296(3)
- lfd 18,304(3)
- lfd 19,312(3)
- lfd 20,320(3)
- lfd 21,328(3)
- lfd 22,336(3)
- lfd 23,344(3)
- lfd 24,352(3)
- lfd 25,360(3)
- lfd 26,368(3)
- lfd 27,376(3)
- lfd 28,384(3)
- lfd 29,392(3)
- lfd 30,400(3)
- lfd 31,408(3)
+ lfd 0, 160(3)
+ lfd 1, 168(3)
+ lfd 2, 176(3)
+ lfd 3, 184(3)
+ lfd 4, 192(3)
+ lfd 5, 200(3)
+ lfd 6, 208(3)
+ lfd 7, 216(3)
+ lfd 8, 224(3)
+ lfd 9, 232(3)
+ lfd 10,240(3)
+ lfd 11,248(3)
+ lfd 12,256(3)
+ lfd 13,264(3)
+ lfd 14,272(3)
+ lfd 15,280(3)
+ lfd 16,288(3)
+ lfd 17,296(3)
+ lfd 18,304(3)
+ lfd 19,312(3)
+ lfd 20,320(3)
+ lfd 21,328(3)
+ lfd 22,336(3)
+ lfd 23,344(3)
+ lfd 24,352(3)
+ lfd 25,360(3)
+ lfd 26,368(3)
+ lfd 27,376(3)
+ lfd 28,384(3)
+ lfd 29,392(3)
+ lfd 30,400(3)
+ lfd 31,408(3)
#endif
#if defined(__ALTIVEC__)
// restore vector registers if any are in use
- lwz 5, 156(3) // test VRsave
- cmpwi 5, 0
+ lwz 5, 156(3) // test VRsave
+ cmpwi 5, 0
beq Lnovec
- subi 4, 1, 16
- rlwinm 4, 4, 0, 0, 27 // mask low 4-bits
+ subi 4, 1, 16
+ rlwinm 4, 4, 0, 0, 27 // mask low 4-bits
// r4 is now a 16-byte aligned pointer into the red zone
// the _vectorRegisters may not be 16-byte aligned so copy via red zone temp buffer
-
-#define LOAD_VECTOR_UNALIGNEDl(_index) \
- andis. 0, 5, (1 PPC_LEFT_SHIFT(15-_index)) SEPARATOR \
+
+#define LOAD_VECTOR_UNALIGNEDl(_index) \
+ andis. 0, 5, (1 PPC_LEFT_SHIFT(15-_index)) SEPARATOR \
beq Ldone ## _index SEPARATOR \
- lwz 0, 424+_index*16(3) SEPARATOR \
- stw 0, 0(%r4) SEPARATOR \
- lwz 0, 424+_index*16+4(%r3) SEPARATOR \
- stw 0, 4(%r4) SEPARATOR \
- lwz 0, 424+_index*16+8(%r3) SEPARATOR \
- stw 0, 8(%r4) SEPARATOR \
- lwz 0, 424+_index*16+12(%r3) SEPARATOR \
- stw 0, 12(%r4) SEPARATOR \
- lvx _index, 0, 4 SEPARATOR \
+ lwz 0, 424+_index*16(3) SEPARATOR \
+ stw 0, 0(%r4) SEPARATOR \
+ lwz 0, 424+_index*16+4(%r3) SEPARATOR \
+ stw 0, 4(%r4) SEPARATOR \
+ lwz 0, 424+_index*16+8(%r3) SEPARATOR \
+ stw 0, 8(%r4) SEPARATOR \
+ lwz 0, 424+_index*16+12(%r3) SEPARATOR \
+ stw 0, 12(%r4) SEPARATOR \
+ lvx _index, 0, 4 SEPARATOR \
Ldone ## _index:
-#define LOAD_VECTOR_UNALIGNEDh(_index) \
- andi. 0, 5, (1 PPC_LEFT_SHIFT(31-_index)) SEPARATOR \
+#define LOAD_VECTOR_UNALIGNEDh(_index) \
+ andi. 0, 5, (1 PPC_LEFT_SHIFT(31-_index)) SEPARATOR \
beq Ldone ## _index SEPARATOR \
- lwz 0, 424+_index*16(3) SEPARATOR \
- stw 0, 0(4) SEPARATOR \
- lwz 0, 424+_index*16+4(3) SEPARATOR \
- stw 0, 4(4) SEPARATOR \
- lwz 0, 424+_index*16+8(3) SEPARATOR \
- stw 0, 8(%r4) SEPARATOR \
- lwz 0, 424+_index*16+12(3) SEPARATOR \
- stw 0, 12(4) SEPARATOR \
- lvx _index, 0, 4 SEPARATOR \
+ lwz 0, 424+_index*16(3) SEPARATOR \
+ stw 0, 0(4) SEPARATOR \
+ lwz 0, 424+_index*16+4(3) SEPARATOR \
+ stw 0, 4(4) SEPARATOR \
+ lwz 0, 424+_index*16+8(3) SEPARATOR \
+ stw 0, 8(%r4) SEPARATOR \
+ lwz 0, 424+_index*16+12(3) SEPARATOR \
+ stw 0, 12(4) SEPARATOR \
+ lvx _index, 0, 4 SEPARATOR \
Ldone ## _index:
@@ -550,17 +550,17 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)
#endif
Lnovec:
- lwz 0, 136(3) // __cr
- mtcr 0
- lwz 0, 148(3) // __ctr
- mtctr 0
- lwz 0, 0(3) // __ssr0
- mtctr 0
- lwz 0, 8(3) // do r0 now
- lwz 5, 28(3) // do r5 now
- lwz 4, 24(3) // do r4 now
- lwz 1, 12(3) // do sp now
- lwz 3, 20(3) // do r3 last
+ lwz 0, 136(3) // __cr
+ mtcr 0
+ lwz 0, 148(3) // __ctr
+ mtctr 0
+ lwz 0, 0(3) // __ssr0
+ mtctr 0
+ lwz 0, 8(3) // do r0 now
+ lwz 5, 28(3) // do r5 now
+ lwz 4, 24(3) // do r4 now
+ lwz 1, 12(3) // do sp now
+ lwz 3, 20(3) // do r3 last
bctr
#elif defined(__aarch64__)
@@ -1131,7 +1131,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_sparc6jumptoEv)
jmp %o7
nop
-#elif defined(__riscv)
+#elif defined(__riscv)
//
// void libunwind::Registers_riscv::jumpto()
@@ -1141,74 +1141,74 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_sparc6jumptoEv)
//
.p2align 2
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv)
-# if defined(__riscv_flen)
- FLOAD f0, (RISCV_FOFFSET + RISCV_FSIZE * 0)(a0)
- FLOAD f1, (RISCV_FOFFSET + RISCV_FSIZE * 1)(a0)
- FLOAD f2, (RISCV_FOFFSET + RISCV_FSIZE * 2)(a0)
- FLOAD f3, (RISCV_FOFFSET + RISCV_FSIZE * 3)(a0)
- FLOAD f4, (RISCV_FOFFSET + RISCV_FSIZE * 4)(a0)
- FLOAD f5, (RISCV_FOFFSET + RISCV_FSIZE * 5)(a0)
- FLOAD f6, (RISCV_FOFFSET + RISCV_FSIZE * 6)(a0)
- FLOAD f7, (RISCV_FOFFSET + RISCV_FSIZE * 7)(a0)
- FLOAD f8, (RISCV_FOFFSET + RISCV_FSIZE * 8)(a0)
- FLOAD f9, (RISCV_FOFFSET + RISCV_FSIZE * 9)(a0)
- FLOAD f10, (RISCV_FOFFSET + RISCV_FSIZE * 10)(a0)
- FLOAD f11, (RISCV_FOFFSET + RISCV_FSIZE * 11)(a0)
- FLOAD f12, (RISCV_FOFFSET + RISCV_FSIZE * 12)(a0)
- FLOAD f13, (RISCV_FOFFSET + RISCV_FSIZE * 13)(a0)
- FLOAD f14, (RISCV_FOFFSET + RISCV_FSIZE * 14)(a0)
- FLOAD f15, (RISCV_FOFFSET + RISCV_FSIZE * 15)(a0)
- FLOAD f16, (RISCV_FOFFSET + RISCV_FSIZE * 16)(a0)
- FLOAD f17, (RISCV_FOFFSET + RISCV_FSIZE * 17)(a0)
- FLOAD f18, (RISCV_FOFFSET + RISCV_FSIZE * 18)(a0)
- FLOAD f19, (RISCV_FOFFSET + RISCV_FSIZE * 19)(a0)
- FLOAD f20, (RISCV_FOFFSET + RISCV_FSIZE * 20)(a0)
- FLOAD f21, (RISCV_FOFFSET + RISCV_FSIZE * 21)(a0)
- FLOAD f22, (RISCV_FOFFSET + RISCV_FSIZE * 22)(a0)
- FLOAD f23, (RISCV_FOFFSET + RISCV_FSIZE * 23)(a0)
- FLOAD f24, (RISCV_FOFFSET + RISCV_FSIZE * 24)(a0)
- FLOAD f25, (RISCV_FOFFSET + RISCV_FSIZE * 25)(a0)
- FLOAD f26, (RISCV_FOFFSET + RISCV_FSIZE * 26)(a0)
- FLOAD f27, (RISCV_FOFFSET + RISCV_FSIZE * 27)(a0)
- FLOAD f28, (RISCV_FOFFSET + RISCV_FSIZE * 28)(a0)
- FLOAD f29, (RISCV_FOFFSET + RISCV_FSIZE * 29)(a0)
- FLOAD f30, (RISCV_FOFFSET + RISCV_FSIZE * 30)(a0)
- FLOAD f31, (RISCV_FOFFSET + RISCV_FSIZE * 31)(a0)
-# endif
+# if defined(__riscv_flen)
+ FLOAD f0, (RISCV_FOFFSET + RISCV_FSIZE * 0)(a0)
+ FLOAD f1, (RISCV_FOFFSET + RISCV_FSIZE * 1)(a0)
+ FLOAD f2, (RISCV_FOFFSET + RISCV_FSIZE * 2)(a0)
+ FLOAD f3, (RISCV_FOFFSET + RISCV_FSIZE * 3)(a0)
+ FLOAD f4, (RISCV_FOFFSET + RISCV_FSIZE * 4)(a0)
+ FLOAD f5, (RISCV_FOFFSET + RISCV_FSIZE * 5)(a0)
+ FLOAD f6, (RISCV_FOFFSET + RISCV_FSIZE * 6)(a0)
+ FLOAD f7, (RISCV_FOFFSET + RISCV_FSIZE * 7)(a0)
+ FLOAD f8, (RISCV_FOFFSET + RISCV_FSIZE * 8)(a0)
+ FLOAD f9, (RISCV_FOFFSET + RISCV_FSIZE * 9)(a0)
+ FLOAD f10, (RISCV_FOFFSET + RISCV_FSIZE * 10)(a0)
+ FLOAD f11, (RISCV_FOFFSET + RISCV_FSIZE * 11)(a0)
+ FLOAD f12, (RISCV_FOFFSET + RISCV_FSIZE * 12)(a0)
+ FLOAD f13, (RISCV_FOFFSET + RISCV_FSIZE * 13)(a0)
+ FLOAD f14, (RISCV_FOFFSET + RISCV_FSIZE * 14)(a0)
+ FLOAD f15, (RISCV_FOFFSET + RISCV_FSIZE * 15)(a0)
+ FLOAD f16, (RISCV_FOFFSET + RISCV_FSIZE * 16)(a0)
+ FLOAD f17, (RISCV_FOFFSET + RISCV_FSIZE * 17)(a0)
+ FLOAD f18, (RISCV_FOFFSET + RISCV_FSIZE * 18)(a0)
+ FLOAD f19, (RISCV_FOFFSET + RISCV_FSIZE * 19)(a0)
+ FLOAD f20, (RISCV_FOFFSET + RISCV_FSIZE * 20)(a0)
+ FLOAD f21, (RISCV_FOFFSET + RISCV_FSIZE * 21)(a0)
+ FLOAD f22, (RISCV_FOFFSET + RISCV_FSIZE * 22)(a0)
+ FLOAD f23, (RISCV_FOFFSET + RISCV_FSIZE * 23)(a0)
+ FLOAD f24, (RISCV_FOFFSET + RISCV_FSIZE * 24)(a0)
+ FLOAD f25, (RISCV_FOFFSET + RISCV_FSIZE * 25)(a0)
+ FLOAD f26, (RISCV_FOFFSET + RISCV_FSIZE * 26)(a0)
+ FLOAD f27, (RISCV_FOFFSET + RISCV_FSIZE * 27)(a0)
+ FLOAD f28, (RISCV_FOFFSET + RISCV_FSIZE * 28)(a0)
+ FLOAD f29, (RISCV_FOFFSET + RISCV_FSIZE * 29)(a0)
+ FLOAD f30, (RISCV_FOFFSET + RISCV_FSIZE * 30)(a0)
+ FLOAD f31, (RISCV_FOFFSET + RISCV_FSIZE * 31)(a0)
+# endif
// x0 is zero
- ILOAD x1, (RISCV_ISIZE * 0)(a0) // restore pc into ra
- ILOAD x2, (RISCV_ISIZE * 2)(a0)
- ILOAD x3, (RISCV_ISIZE * 3)(a0)
- ILOAD x4, (RISCV_ISIZE * 4)(a0)
- ILOAD x5, (RISCV_ISIZE * 5)(a0)
- ILOAD x6, (RISCV_ISIZE * 6)(a0)
- ILOAD x7, (RISCV_ISIZE * 7)(a0)
- ILOAD x8, (RISCV_ISIZE * 8)(a0)
- ILOAD x9, (RISCV_ISIZE * 9)(a0)
+ ILOAD x1, (RISCV_ISIZE * 0)(a0) // restore pc into ra
+ ILOAD x2, (RISCV_ISIZE * 2)(a0)
+ ILOAD x3, (RISCV_ISIZE * 3)(a0)
+ ILOAD x4, (RISCV_ISIZE * 4)(a0)
+ ILOAD x5, (RISCV_ISIZE * 5)(a0)
+ ILOAD x6, (RISCV_ISIZE * 6)(a0)
+ ILOAD x7, (RISCV_ISIZE * 7)(a0)
+ ILOAD x8, (RISCV_ISIZE * 8)(a0)
+ ILOAD x9, (RISCV_ISIZE * 9)(a0)
// skip a0 for now
- ILOAD x11, (RISCV_ISIZE * 11)(a0)
- ILOAD x12, (RISCV_ISIZE * 12)(a0)
- ILOAD x13, (RISCV_ISIZE * 13)(a0)
- ILOAD x14, (RISCV_ISIZE * 14)(a0)
- ILOAD x15, (RISCV_ISIZE * 15)(a0)
- ILOAD x16, (RISCV_ISIZE * 16)(a0)
- ILOAD x17, (RISCV_ISIZE * 17)(a0)
- ILOAD x18, (RISCV_ISIZE * 18)(a0)
- ILOAD x19, (RISCV_ISIZE * 19)(a0)
- ILOAD x20, (RISCV_ISIZE * 20)(a0)
- ILOAD x21, (RISCV_ISIZE * 21)(a0)
- ILOAD x22, (RISCV_ISIZE * 22)(a0)
- ILOAD x23, (RISCV_ISIZE * 23)(a0)
- ILOAD x24, (RISCV_ISIZE * 24)(a0)
- ILOAD x25, (RISCV_ISIZE * 25)(a0)
- ILOAD x26, (RISCV_ISIZE * 26)(a0)
- ILOAD x27, (RISCV_ISIZE * 27)(a0)
- ILOAD x28, (RISCV_ISIZE * 28)(a0)
- ILOAD x29, (RISCV_ISIZE * 29)(a0)
- ILOAD x30, (RISCV_ISIZE * 30)(a0)
- ILOAD x31, (RISCV_ISIZE * 31)(a0)
- ILOAD x10, (RISCV_ISIZE * 10)(a0) // restore a0
+ ILOAD x11, (RISCV_ISIZE * 11)(a0)
+ ILOAD x12, (RISCV_ISIZE * 12)(a0)
+ ILOAD x13, (RISCV_ISIZE * 13)(a0)
+ ILOAD x14, (RISCV_ISIZE * 14)(a0)
+ ILOAD x15, (RISCV_ISIZE * 15)(a0)
+ ILOAD x16, (RISCV_ISIZE * 16)(a0)
+ ILOAD x17, (RISCV_ISIZE * 17)(a0)
+ ILOAD x18, (RISCV_ISIZE * 18)(a0)
+ ILOAD x19, (RISCV_ISIZE * 19)(a0)
+ ILOAD x20, (RISCV_ISIZE * 20)(a0)
+ ILOAD x21, (RISCV_ISIZE * 21)(a0)
+ ILOAD x22, (RISCV_ISIZE * 22)(a0)
+ ILOAD x23, (RISCV_ISIZE * 23)(a0)
+ ILOAD x24, (RISCV_ISIZE * 24)(a0)
+ ILOAD x25, (RISCV_ISIZE * 25)(a0)
+ ILOAD x26, (RISCV_ISIZE * 26)(a0)
+ ILOAD x27, (RISCV_ISIZE * 27)(a0)
+ ILOAD x28, (RISCV_ISIZE * 28)(a0)
+ ILOAD x29, (RISCV_ISIZE * 29)(a0)
+ ILOAD x30, (RISCV_ISIZE * 30)(a0)
+ ILOAD x31, (RISCV_ISIZE * 31)(a0)
+ ILOAD x10, (RISCV_ISIZE * 10)(a0) // restore a0
ret // jump to ra
diff --git a/contrib/libs/libunwind/src/UnwindRegistersSave.S b/contrib/libs/libunwind/src/UnwindRegistersSave.S
index ce118914b0..9566bb0335 100644
--- a/contrib/libs/libunwind/src/UnwindRegistersSave.S
+++ b/contrib/libs/libunwind/src/UnwindRegistersSave.S
@@ -338,12 +338,12 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
// store register (GPR)
#define PPC64_STR(n) \
- std n, (8 * (n + 2))(3)
+ std n, (8 * (n + 2))(3)
// save GPRs
PPC64_STR(0)
- mflr 0
- std 0, PPC64_OFFS_SRR0(3) // store lr as ssr0
+ mflr 0
+ std 0, PPC64_OFFS_SRR0(3) // store lr as ssr0
PPC64_STR(1)
PPC64_STR(2)
PPC64_STR(3)
@@ -376,28 +376,28 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
PPC64_STR(30)
PPC64_STR(31)
- mfcr 0
- std 0, PPC64_OFFS_CR(3)
- mfxer 0
- std 0, PPC64_OFFS_XER(3)
- mflr 0
- std 0, PPC64_OFFS_LR(3)
- mfctr 0
- std 0, PPC64_OFFS_CTR(3)
- mfvrsave 0
- std 0, PPC64_OFFS_VRSAVE(3)
+ mfcr 0
+ std 0, PPC64_OFFS_CR(3)
+ mfxer 0
+ std 0, PPC64_OFFS_XER(3)
+ mflr 0
+ std 0, PPC64_OFFS_LR(3)
+ mfctr 0
+ std 0, PPC64_OFFS_CTR(3)
+ mfvrsave 0
+ std 0, PPC64_OFFS_VRSAVE(3)
#if defined(__VSX__)
// save VS registers
// (note that this also saves floating point registers and V registers,
// because part of VS is mapped to these registers)
- addi 4, 3, PPC64_OFFS_FP
+ addi 4, 3, PPC64_OFFS_FP
// store VS register
#define PPC64_STVS(n) \
- stxvd2x n, 0, 4 ;\
- addi 4, 4, 16
+ stxvd2x n, 0, 4 ;\
+ addi 4, 4, 16
PPC64_STVS(0)
PPC64_STVS(1)
@@ -468,7 +468,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
// store FP register
#define PPC64_STF(n) \
- stfd n, (PPC64_OFFS_FP + n * 16)(3)
+ stfd n, (PPC64_OFFS_FP + n * 16)(3)
// save float registers
PPC64_STF(0)
@@ -510,14 +510,14 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
// Use 16-bytes below the stack pointer as an
// aligned buffer to save each vector register.
// Note that the stack pointer is always 16-byte aligned.
- subi 4, 1, 16
+ subi 4, 1, 16
-#define PPC64_STV_UNALIGNED(n) \
- stvx n, 0, 4 ;\
- ld 5, 0(4) ;\
- std 5, (PPC64_OFFS_V + n * 16)(3) ;\
- ld 5, 8(4) ;\
- std 5, (PPC64_OFFS_V + n * 16 + 8)(3)
+#define PPC64_STV_UNALIGNED(n) \
+ stvx n, 0, 4 ;\
+ ld 5, 0(4) ;\
+ std 5, (PPC64_OFFS_V + n * 16)(3) ;\
+ ld 5, 8(4) ;\
+ std 5, (PPC64_OFFS_V + n * 16 + 8)(3)
PPC64_STV_UNALIGNED(0)
PPC64_STV_UNALIGNED(1)
@@ -555,7 +555,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
#endif
#endif
- li 3, 0 // return UNW_ESUCCESS
+ li 3, 0 // return UNW_ESUCCESS
blr
@@ -568,140 +568,140 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
// thread_state pointer is in r3
//
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
- stw 0, 8(3)
- mflr 0
- stw 0, 0(3) // store lr as ssr0
- stw 1, 12(3)
- stw 2, 16(3)
- stw 3, 20(3)
- stw 4, 24(3)
- stw 5, 28(3)
- stw 6, 32(3)
- stw 7, 36(3)
- stw 8, 40(3)
- stw 9, 44(3)
- stw 10, 48(3)
- stw 11, 52(3)
- stw 12, 56(3)
- stw 13, 60(3)
- stw 14, 64(3)
- stw 15, 68(3)
- stw 16, 72(3)
- stw 17, 76(3)
- stw 18, 80(3)
- stw 19, 84(3)
- stw 20, 88(3)
- stw 21, 92(3)
- stw 22, 96(3)
- stw 23,100(3)
- stw 24,104(3)
- stw 25,108(3)
- stw 26,112(3)
- stw 27,116(3)
- stw 28,120(3)
- stw 29,124(3)
- stw 30,128(3)
- stw 31,132(3)
+ stw 0, 8(3)
+ mflr 0
+ stw 0, 0(3) // store lr as ssr0
+ stw 1, 12(3)
+ stw 2, 16(3)
+ stw 3, 20(3)
+ stw 4, 24(3)
+ stw 5, 28(3)
+ stw 6, 32(3)
+ stw 7, 36(3)
+ stw 8, 40(3)
+ stw 9, 44(3)
+ stw 10, 48(3)
+ stw 11, 52(3)
+ stw 12, 56(3)
+ stw 13, 60(3)
+ stw 14, 64(3)
+ stw 15, 68(3)
+ stw 16, 72(3)
+ stw 17, 76(3)
+ stw 18, 80(3)
+ stw 19, 84(3)
+ stw 20, 88(3)
+ stw 21, 92(3)
+ stw 22, 96(3)
+ stw 23,100(3)
+ stw 24,104(3)
+ stw 25,108(3)
+ stw 26,112(3)
+ stw 27,116(3)
+ stw 28,120(3)
+ stw 29,124(3)
+ stw 30,128(3)
+ stw 31,132(3)
// save VRSave register
- mfspr 0, 256
- stw 0, 156(3)
+ mfspr 0, 256
+ stw 0, 156(3)
// save CR registers
- mfcr 0
- stw 0, 136(3)
+ mfcr 0
+ stw 0, 136(3)
// save CTR register
- mfctr 0
- stw 0, 148(3)
+ mfctr 0
+ stw 0, 148(3)
#if !defined(__NO_FPRS__)
// save float registers
- stfd 0, 160(3)
- stfd 1, 168(3)
- stfd 2, 176(3)
- stfd 3, 184(3)
- stfd 4, 192(3)
- stfd 5, 200(3)
- stfd 6, 208(3)
- stfd 7, 216(3)
- stfd 8, 224(3)
- stfd 9, 232(3)
- stfd 10,240(3)
- stfd 11,248(3)
- stfd 12,256(3)
- stfd 13,264(3)
- stfd 14,272(3)
- stfd 15,280(3)
- stfd 16,288(3)
- stfd 17,296(3)
- stfd 18,304(3)
- stfd 19,312(3)
- stfd 20,320(3)
- stfd 21,328(3)
- stfd 22,336(3)
- stfd 23,344(3)
- stfd 24,352(3)
- stfd 25,360(3)
- stfd 26,368(3)
- stfd 27,376(3)
- stfd 28,384(3)
- stfd 29,392(3)
- stfd 30,400(3)
- stfd 31,408(3)
+ stfd 0, 160(3)
+ stfd 1, 168(3)
+ stfd 2, 176(3)
+ stfd 3, 184(3)
+ stfd 4, 192(3)
+ stfd 5, 200(3)
+ stfd 6, 208(3)
+ stfd 7, 216(3)
+ stfd 8, 224(3)
+ stfd 9, 232(3)
+ stfd 10,240(3)
+ stfd 11,248(3)
+ stfd 12,256(3)
+ stfd 13,264(3)
+ stfd 14,272(3)
+ stfd 15,280(3)
+ stfd 16,288(3)
+ stfd 17,296(3)
+ stfd 18,304(3)
+ stfd 19,312(3)
+ stfd 20,320(3)
+ stfd 21,328(3)
+ stfd 22,336(3)
+ stfd 23,344(3)
+ stfd 24,352(3)
+ stfd 25,360(3)
+ stfd 26,368(3)
+ stfd 27,376(3)
+ stfd 28,384(3)
+ stfd 29,392(3)
+ stfd 30,400(3)
+ stfd 31,408(3)
#endif
#if defined(__ALTIVEC__)
// save vector registers
- subi 4, 1, 16
- rlwinm 4, 4, 0, 0, 27 // mask low 4-bits
+ subi 4, 1, 16
+ rlwinm 4, 4, 0, 0, 27 // mask low 4-bits
// r4 is now a 16-byte aligned pointer into the red zone
#define SAVE_VECTOR_UNALIGNED(_vec, _offset) \
- stvx _vec, 0, 4 SEPARATOR \
- lwz 5, 0(4) SEPARATOR \
- stw 5, _offset(3) SEPARATOR \
- lwz 5, 4(4) SEPARATOR \
- stw 5, _offset+4(3) SEPARATOR \
- lwz 5, 8(4) SEPARATOR \
- stw 5, _offset+8(3) SEPARATOR \
- lwz 5, 12(4) SEPARATOR \
- stw 5, _offset+12(3)
-
- SAVE_VECTOR_UNALIGNED( 0, 424+0x000)
- SAVE_VECTOR_UNALIGNED( 1, 424+0x010)
- SAVE_VECTOR_UNALIGNED( 2, 424+0x020)
- SAVE_VECTOR_UNALIGNED( 3, 424+0x030)
- SAVE_VECTOR_UNALIGNED( 4, 424+0x040)
- SAVE_VECTOR_UNALIGNED( 5, 424+0x050)
- SAVE_VECTOR_UNALIGNED( 6, 424+0x060)
- SAVE_VECTOR_UNALIGNED( 7, 424+0x070)
- SAVE_VECTOR_UNALIGNED( 8, 424+0x080)
- SAVE_VECTOR_UNALIGNED( 9, 424+0x090)
- SAVE_VECTOR_UNALIGNED(10, 424+0x0A0)
- SAVE_VECTOR_UNALIGNED(11, 424+0x0B0)
- SAVE_VECTOR_UNALIGNED(12, 424+0x0C0)
- SAVE_VECTOR_UNALIGNED(13, 424+0x0D0)
- SAVE_VECTOR_UNALIGNED(14, 424+0x0E0)
- SAVE_VECTOR_UNALIGNED(15, 424+0x0F0)
- SAVE_VECTOR_UNALIGNED(16, 424+0x100)
- SAVE_VECTOR_UNALIGNED(17, 424+0x110)
- SAVE_VECTOR_UNALIGNED(18, 424+0x120)
- SAVE_VECTOR_UNALIGNED(19, 424+0x130)
- SAVE_VECTOR_UNALIGNED(20, 424+0x140)
- SAVE_VECTOR_UNALIGNED(21, 424+0x150)
- SAVE_VECTOR_UNALIGNED(22, 424+0x160)
- SAVE_VECTOR_UNALIGNED(23, 424+0x170)
- SAVE_VECTOR_UNALIGNED(24, 424+0x180)
- SAVE_VECTOR_UNALIGNED(25, 424+0x190)
- SAVE_VECTOR_UNALIGNED(26, 424+0x1A0)
- SAVE_VECTOR_UNALIGNED(27, 424+0x1B0)
- SAVE_VECTOR_UNALIGNED(28, 424+0x1C0)
- SAVE_VECTOR_UNALIGNED(29, 424+0x1D0)
- SAVE_VECTOR_UNALIGNED(30, 424+0x1E0)
- SAVE_VECTOR_UNALIGNED(31, 424+0x1F0)
+ stvx _vec, 0, 4 SEPARATOR \
+ lwz 5, 0(4) SEPARATOR \
+ stw 5, _offset(3) SEPARATOR \
+ lwz 5, 4(4) SEPARATOR \
+ stw 5, _offset+4(3) SEPARATOR \
+ lwz 5, 8(4) SEPARATOR \
+ stw 5, _offset+8(3) SEPARATOR \
+ lwz 5, 12(4) SEPARATOR \
+ stw 5, _offset+12(3)
+
+ SAVE_VECTOR_UNALIGNED( 0, 424+0x000)
+ SAVE_VECTOR_UNALIGNED( 1, 424+0x010)
+ SAVE_VECTOR_UNALIGNED( 2, 424+0x020)
+ SAVE_VECTOR_UNALIGNED( 3, 424+0x030)
+ SAVE_VECTOR_UNALIGNED( 4, 424+0x040)
+ SAVE_VECTOR_UNALIGNED( 5, 424+0x050)
+ SAVE_VECTOR_UNALIGNED( 6, 424+0x060)
+ SAVE_VECTOR_UNALIGNED( 7, 424+0x070)
+ SAVE_VECTOR_UNALIGNED( 8, 424+0x080)
+ SAVE_VECTOR_UNALIGNED( 9, 424+0x090)
+ SAVE_VECTOR_UNALIGNED(10, 424+0x0A0)
+ SAVE_VECTOR_UNALIGNED(11, 424+0x0B0)
+ SAVE_VECTOR_UNALIGNED(12, 424+0x0C0)
+ SAVE_VECTOR_UNALIGNED(13, 424+0x0D0)
+ SAVE_VECTOR_UNALIGNED(14, 424+0x0E0)
+ SAVE_VECTOR_UNALIGNED(15, 424+0x0F0)
+ SAVE_VECTOR_UNALIGNED(16, 424+0x100)
+ SAVE_VECTOR_UNALIGNED(17, 424+0x110)
+ SAVE_VECTOR_UNALIGNED(18, 424+0x120)
+ SAVE_VECTOR_UNALIGNED(19, 424+0x130)
+ SAVE_VECTOR_UNALIGNED(20, 424+0x140)
+ SAVE_VECTOR_UNALIGNED(21, 424+0x150)
+ SAVE_VECTOR_UNALIGNED(22, 424+0x160)
+ SAVE_VECTOR_UNALIGNED(23, 424+0x170)
+ SAVE_VECTOR_UNALIGNED(24, 424+0x180)
+ SAVE_VECTOR_UNALIGNED(25, 424+0x190)
+ SAVE_VECTOR_UNALIGNED(26, 424+0x1A0)
+ SAVE_VECTOR_UNALIGNED(27, 424+0x1B0)
+ SAVE_VECTOR_UNALIGNED(28, 424+0x1C0)
+ SAVE_VECTOR_UNALIGNED(29, 424+0x1D0)
+ SAVE_VECTOR_UNALIGNED(30, 424+0x1E0)
+ SAVE_VECTOR_UNALIGNED(31, 424+0x1F0)
#endif
- li 3, 0 // return UNW_ESUCCESS
+ li 3, 0 // return UNW_ESUCCESS
blr
@@ -1087,7 +1087,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
jmp %o7
clr %o0 // return UNW_ESUCCESS
-#elif defined(__riscv)
+#elif defined(__riscv)
#
# extern int __unw_getcontext(unw_context_t* thread_state)
@@ -1096,73 +1096,73 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
# thread_state pointer is in a0
#
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
- ISTORE x1, (RISCV_ISIZE * 0)(a0) // store ra as pc
- ISTORE x1, (RISCV_ISIZE * 1)(a0)
- ISTORE x2, (RISCV_ISIZE * 2)(a0)
- ISTORE x3, (RISCV_ISIZE * 3)(a0)
- ISTORE x4, (RISCV_ISIZE * 4)(a0)
- ISTORE x5, (RISCV_ISIZE * 5)(a0)
- ISTORE x6, (RISCV_ISIZE * 6)(a0)
- ISTORE x7, (RISCV_ISIZE * 7)(a0)
- ISTORE x8, (RISCV_ISIZE * 8)(a0)
- ISTORE x9, (RISCV_ISIZE * 9)(a0)
- ISTORE x10, (RISCV_ISIZE * 10)(a0)
- ISTORE x11, (RISCV_ISIZE * 11)(a0)
- ISTORE x12, (RISCV_ISIZE * 12)(a0)
- ISTORE x13, (RISCV_ISIZE * 13)(a0)
- ISTORE x14, (RISCV_ISIZE * 14)(a0)
- ISTORE x15, (RISCV_ISIZE * 15)(a0)
- ISTORE x16, (RISCV_ISIZE * 16)(a0)
- ISTORE x17, (RISCV_ISIZE * 17)(a0)
- ISTORE x18, (RISCV_ISIZE * 18)(a0)
- ISTORE x19, (RISCV_ISIZE * 19)(a0)
- ISTORE x20, (RISCV_ISIZE * 20)(a0)
- ISTORE x21, (RISCV_ISIZE * 21)(a0)
- ISTORE x22, (RISCV_ISIZE * 22)(a0)
- ISTORE x23, (RISCV_ISIZE * 23)(a0)
- ISTORE x24, (RISCV_ISIZE * 24)(a0)
- ISTORE x25, (RISCV_ISIZE * 25)(a0)
- ISTORE x26, (RISCV_ISIZE * 26)(a0)
- ISTORE x27, (RISCV_ISIZE * 27)(a0)
- ISTORE x28, (RISCV_ISIZE * 28)(a0)
- ISTORE x29, (RISCV_ISIZE * 29)(a0)
- ISTORE x30, (RISCV_ISIZE * 30)(a0)
- ISTORE x31, (RISCV_ISIZE * 31)(a0)
-
-# if defined(__riscv_flen)
- FSTORE f0, (RISCV_FOFFSET + RISCV_FSIZE * 0)(a0)
- FSTORE f1, (RISCV_FOFFSET + RISCV_FSIZE * 1)(a0)
- FSTORE f2, (RISCV_FOFFSET + RISCV_FSIZE * 2)(a0)
- FSTORE f3, (RISCV_FOFFSET + RISCV_FSIZE * 3)(a0)
- FSTORE f4, (RISCV_FOFFSET + RISCV_FSIZE * 4)(a0)
- FSTORE f5, (RISCV_FOFFSET + RISCV_FSIZE * 5)(a0)
- FSTORE f6, (RISCV_FOFFSET + RISCV_FSIZE * 6)(a0)
- FSTORE f7, (RISCV_FOFFSET + RISCV_FSIZE * 7)(a0)
- FSTORE f8, (RISCV_FOFFSET + RISCV_FSIZE * 8)(a0)
- FSTORE f9, (RISCV_FOFFSET + RISCV_FSIZE * 9)(a0)
- FSTORE f10, (RISCV_FOFFSET + RISCV_FSIZE * 10)(a0)
- FSTORE f11, (RISCV_FOFFSET + RISCV_FSIZE * 11)(a0)
- FSTORE f12, (RISCV_FOFFSET + RISCV_FSIZE * 12)(a0)
- FSTORE f13, (RISCV_FOFFSET + RISCV_FSIZE * 13)(a0)
- FSTORE f14, (RISCV_FOFFSET + RISCV_FSIZE * 14)(a0)
- FSTORE f15, (RISCV_FOFFSET + RISCV_FSIZE * 15)(a0)
- FSTORE f16, (RISCV_FOFFSET + RISCV_FSIZE * 16)(a0)
- FSTORE f17, (RISCV_FOFFSET + RISCV_FSIZE * 17)(a0)
- FSTORE f18, (RISCV_FOFFSET + RISCV_FSIZE * 18)(a0)
- FSTORE f19, (RISCV_FOFFSET + RISCV_FSIZE * 19)(a0)
- FSTORE f20, (RISCV_FOFFSET + RISCV_FSIZE * 20)(a0)
- FSTORE f21, (RISCV_FOFFSET + RISCV_FSIZE * 21)(a0)
- FSTORE f22, (RISCV_FOFFSET + RISCV_FSIZE * 22)(a0)
- FSTORE f23, (RISCV_FOFFSET + RISCV_FSIZE * 23)(a0)
- FSTORE f24, (RISCV_FOFFSET + RISCV_FSIZE * 24)(a0)
- FSTORE f25, (RISCV_FOFFSET + RISCV_FSIZE * 25)(a0)
- FSTORE f26, (RISCV_FOFFSET + RISCV_FSIZE * 26)(a0)
- FSTORE f27, (RISCV_FOFFSET + RISCV_FSIZE * 27)(a0)
- FSTORE f28, (RISCV_FOFFSET + RISCV_FSIZE * 28)(a0)
- FSTORE f29, (RISCV_FOFFSET + RISCV_FSIZE * 29)(a0)
- FSTORE f30, (RISCV_FOFFSET + RISCV_FSIZE * 30)(a0)
- FSTORE f31, (RISCV_FOFFSET + RISCV_FSIZE * 31)(a0)
-# endif
+ ISTORE x1, (RISCV_ISIZE * 0)(a0) // store ra as pc
+ ISTORE x1, (RISCV_ISIZE * 1)(a0)
+ ISTORE x2, (RISCV_ISIZE * 2)(a0)
+ ISTORE x3, (RISCV_ISIZE * 3)(a0)
+ ISTORE x4, (RISCV_ISIZE * 4)(a0)
+ ISTORE x5, (RISCV_ISIZE * 5)(a0)
+ ISTORE x6, (RISCV_ISIZE * 6)(a0)
+ ISTORE x7, (RISCV_ISIZE * 7)(a0)
+ ISTORE x8, (RISCV_ISIZE * 8)(a0)
+ ISTORE x9, (RISCV_ISIZE * 9)(a0)
+ ISTORE x10, (RISCV_ISIZE * 10)(a0)
+ ISTORE x11, (RISCV_ISIZE * 11)(a0)
+ ISTORE x12, (RISCV_ISIZE * 12)(a0)
+ ISTORE x13, (RISCV_ISIZE * 13)(a0)
+ ISTORE x14, (RISCV_ISIZE * 14)(a0)
+ ISTORE x15, (RISCV_ISIZE * 15)(a0)
+ ISTORE x16, (RISCV_ISIZE * 16)(a0)
+ ISTORE x17, (RISCV_ISIZE * 17)(a0)
+ ISTORE x18, (RISCV_ISIZE * 18)(a0)
+ ISTORE x19, (RISCV_ISIZE * 19)(a0)
+ ISTORE x20, (RISCV_ISIZE * 20)(a0)
+ ISTORE x21, (RISCV_ISIZE * 21)(a0)
+ ISTORE x22, (RISCV_ISIZE * 22)(a0)
+ ISTORE x23, (RISCV_ISIZE * 23)(a0)
+ ISTORE x24, (RISCV_ISIZE * 24)(a0)
+ ISTORE x25, (RISCV_ISIZE * 25)(a0)
+ ISTORE x26, (RISCV_ISIZE * 26)(a0)
+ ISTORE x27, (RISCV_ISIZE * 27)(a0)
+ ISTORE x28, (RISCV_ISIZE * 28)(a0)
+ ISTORE x29, (RISCV_ISIZE * 29)(a0)
+ ISTORE x30, (RISCV_ISIZE * 30)(a0)
+ ISTORE x31, (RISCV_ISIZE * 31)(a0)
+
+# if defined(__riscv_flen)
+ FSTORE f0, (RISCV_FOFFSET + RISCV_FSIZE * 0)(a0)
+ FSTORE f1, (RISCV_FOFFSET + RISCV_FSIZE * 1)(a0)
+ FSTORE f2, (RISCV_FOFFSET + RISCV_FSIZE * 2)(a0)
+ FSTORE f3, (RISCV_FOFFSET + RISCV_FSIZE * 3)(a0)
+ FSTORE f4, (RISCV_FOFFSET + RISCV_FSIZE * 4)(a0)
+ FSTORE f5, (RISCV_FOFFSET + RISCV_FSIZE * 5)(a0)
+ FSTORE f6, (RISCV_FOFFSET + RISCV_FSIZE * 6)(a0)
+ FSTORE f7, (RISCV_FOFFSET + RISCV_FSIZE * 7)(a0)
+ FSTORE f8, (RISCV_FOFFSET + RISCV_FSIZE * 8)(a0)
+ FSTORE f9, (RISCV_FOFFSET + RISCV_FSIZE * 9)(a0)
+ FSTORE f10, (RISCV_FOFFSET + RISCV_FSIZE * 10)(a0)
+ FSTORE f11, (RISCV_FOFFSET + RISCV_FSIZE * 11)(a0)
+ FSTORE f12, (RISCV_FOFFSET + RISCV_FSIZE * 12)(a0)
+ FSTORE f13, (RISCV_FOFFSET + RISCV_FSIZE * 13)(a0)
+ FSTORE f14, (RISCV_FOFFSET + RISCV_FSIZE * 14)(a0)
+ FSTORE f15, (RISCV_FOFFSET + RISCV_FSIZE * 15)(a0)
+ FSTORE f16, (RISCV_FOFFSET + RISCV_FSIZE * 16)(a0)
+ FSTORE f17, (RISCV_FOFFSET + RISCV_FSIZE * 17)(a0)
+ FSTORE f18, (RISCV_FOFFSET + RISCV_FSIZE * 18)(a0)
+ FSTORE f19, (RISCV_FOFFSET + RISCV_FSIZE * 19)(a0)
+ FSTORE f20, (RISCV_FOFFSET + RISCV_FSIZE * 20)(a0)
+ FSTORE f21, (RISCV_FOFFSET + RISCV_FSIZE * 21)(a0)
+ FSTORE f22, (RISCV_FOFFSET + RISCV_FSIZE * 22)(a0)
+ FSTORE f23, (RISCV_FOFFSET + RISCV_FSIZE * 23)(a0)
+ FSTORE f24, (RISCV_FOFFSET + RISCV_FSIZE * 24)(a0)
+ FSTORE f25, (RISCV_FOFFSET + RISCV_FSIZE * 25)(a0)
+ FSTORE f26, (RISCV_FOFFSET + RISCV_FSIZE * 26)(a0)
+ FSTORE f27, (RISCV_FOFFSET + RISCV_FSIZE * 27)(a0)
+ FSTORE f28, (RISCV_FOFFSET + RISCV_FSIZE * 28)(a0)
+ FSTORE f29, (RISCV_FOFFSET + RISCV_FSIZE * 29)(a0)
+ FSTORE f30, (RISCV_FOFFSET + RISCV_FSIZE * 30)(a0)
+ FSTORE f31, (RISCV_FOFFSET + RISCV_FSIZE * 31)(a0)
+# endif
li a0, 0 // return UNW_ESUCCESS
ret // jump to ra
diff --git a/contrib/libs/libunwind/src/assembly.h b/contrib/libs/libunwind/src/assembly.h
index 29c990a5c1..978f6bd619 100644
--- a/contrib/libs/libunwind/src/assembly.h
+++ b/contrib/libs/libunwind/src/assembly.h
@@ -34,35 +34,35 @@
#define PPC64_OFFS_V 824
#elif defined(__APPLE__) && defined(__aarch64__)
#define SEPARATOR %%
-#elif defined(__riscv)
-# define RISCV_ISIZE (__riscv_xlen / 8)
-# define RISCV_FOFFSET (RISCV_ISIZE * 32)
-# if defined(__riscv_flen)
-# define RISCV_FSIZE (__riscv_flen / 8)
-# endif
-
-# if __riscv_xlen == 64
-# define ILOAD ld
-# define ISTORE sd
-# elif __riscv_xlen == 32
-# define ILOAD lw
-# define ISTORE sw
-# else
-# error "Unsupported __riscv_xlen"
-# endif
-
-# if defined(__riscv_flen)
-# if __riscv_flen == 64
-# define FLOAD fld
-# define FSTORE fsd
-# elif __riscv_flen == 32
-# define FLOAD flw
-# define FSTORE fsw
-# else
-# error "Unsupported __riscv_flen"
-# endif
-# endif
-# define SEPARATOR ;
+#elif defined(__riscv)
+# define RISCV_ISIZE (__riscv_xlen / 8)
+# define RISCV_FOFFSET (RISCV_ISIZE * 32)
+# if defined(__riscv_flen)
+# define RISCV_FSIZE (__riscv_flen / 8)
+# endif
+
+# if __riscv_xlen == 64
+# define ILOAD ld
+# define ISTORE sd
+# elif __riscv_xlen == 32
+# define ILOAD lw
+# define ISTORE sw
+# else
+# error "Unsupported __riscv_xlen"
+# endif
+
+# if defined(__riscv_flen)
+# if __riscv_flen == 64
+# define FLOAD fld
+# define FSTORE fsd
+# elif __riscv_flen == 32
+# define FLOAD flw
+# define FSTORE fsw
+# else
+# error "Unsupported __riscv_flen"
+# endif
+# endif
+# define SEPARATOR ;
#else
#define SEPARATOR ;
#endif
@@ -117,15 +117,15 @@
#if defined(__APPLE__)
#define SYMBOL_IS_FUNC(name)
-#define HIDDEN_SYMBOL(name) .private_extern name
-#if defined(_LIBUNWIND_HIDE_SYMBOLS)
-#define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name)
-#else
+#define HIDDEN_SYMBOL(name) .private_extern name
+#if defined(_LIBUNWIND_HIDE_SYMBOLS)
+#define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name)
+#else
#define EXPORT_SYMBOL(name)
-#endif
+#endif
#define WEAK_ALIAS(name, aliasname) \
.globl SYMBOL_NAME(aliasname) SEPARATOR \
- EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
+ EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
#define NO_EXEC_STACK_DIRECTIVE
@@ -137,23 +137,23 @@
#else
#define SYMBOL_IS_FUNC(name) .type name,@function
#endif
-#define HIDDEN_SYMBOL(name) .hidden name
-#if defined(_LIBUNWIND_HIDE_SYMBOLS)
-#define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name)
-#else
+#define HIDDEN_SYMBOL(name) .hidden name
+#if defined(_LIBUNWIND_HIDE_SYMBOLS)
+#define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name)
+#else
#define EXPORT_SYMBOL(name)
-#endif
+#endif
#define WEAK_SYMBOL(name) .weak name
#if defined(__hexagon__)
-#define WEAK_ALIAS(name, aliasname) \
- EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
- WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
+#define WEAK_ALIAS(name, aliasname) \
+ EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
+ WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
.equiv SYMBOL_NAME(aliasname), SYMBOL_NAME(name)
#else
#define WEAK_ALIAS(name, aliasname) \
- EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
- WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
+ EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
+ WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
#endif
@@ -175,7 +175,7 @@
.section .drectve,"yn" SEPARATOR \
.ascii "-export:", #name, "\0" SEPARATOR \
.text
-#if defined(_LIBUNWIND_HIDE_SYMBOLS)
+#if defined(_LIBUNWIND_HIDE_SYMBOLS)
#define EXPORT_SYMBOL(name)
#else
#define EXPORT_SYMBOL(name) EXPORT_SYMBOL2(name)
@@ -235,7 +235,7 @@
#endif /* __arm__ */
#if defined(__powerpc__)
-#define PPC_LEFT_SHIFT(index) << (index)
-#endif
-
+#define PPC_LEFT_SHIFT(index) << (index)
+#endif
+
#endif /* UNWIND_ASSEMBLY_H */
diff --git a/contrib/libs/libunwind/src/config.h b/contrib/libs/libunwind/src/config.h
index fa898049d9..560edda04e 100644
--- a/contrib/libs/libunwind/src/config.h
+++ b/contrib/libs/libunwind/src/config.h
@@ -52,8 +52,8 @@
#endif
#endif
-#if defined(_LIBUNWIND_HIDE_SYMBOLS)
- // The CMake file passes -fvisibility=hidden to control ELF/Mach-O visibility.
+#if defined(_LIBUNWIND_HIDE_SYMBOLS)
+ // The CMake file passes -fvisibility=hidden to control ELF/Mach-O visibility.
#define _LIBUNWIND_EXPORT
#define _LIBUNWIND_HIDDEN
#else
@@ -71,11 +71,11 @@
#define SYMBOL_NAME(name) XSTR(__USER_LABEL_PREFIX__) #name
#if defined(__APPLE__)
-#if defined(_LIBUNWIND_HIDE_SYMBOLS)
+#if defined(_LIBUNWIND_HIDE_SYMBOLS)
#define _LIBUNWIND_ALIAS_VISIBILITY(name) __asm__(".private_extern " name);
-#else
-#define _LIBUNWIND_ALIAS_VISIBILITY(name)
-#endif
+#else
+#define _LIBUNWIND_ALIAS_VISIBILITY(name)
+#endif
#define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \
__asm__(".globl " SYMBOL_NAME(aliasname)); \
__asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name)); \
diff --git a/contrib/libs/libunwind/src/libunwind.cpp b/contrib/libs/libunwind/src/libunwind.cpp
index cef4f4b385..03f8b75b5b 100644
--- a/contrib/libs/libunwind/src/libunwind.cpp
+++ b/contrib/libs/libunwind/src/libunwind.cpp
@@ -71,10 +71,10 @@ _LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor,
#define REGISTER_KIND Registers_sparc64
#elif defined(__sparc__)
# define REGISTER_KIND Registers_sparc
-#elif defined(__riscv)
+#elif defined(__riscv)
# define REGISTER_KIND Registers_riscv
-#elif defined(__ve__)
-# define REGISTER_KIND Registers_ve
+#elif defined(__ve__)
+# define REGISTER_KIND Registers_ve
#else
# error Architecture not supported
#endif
diff --git a/contrib/libs/linuxvdso/ya.make b/contrib/libs/linuxvdso/ya.make
index c242143e6a..4da8d3d076 100644
--- a/contrib/libs/linuxvdso/ya.make
+++ b/contrib/libs/linuxvdso/ya.make
@@ -4,10 +4,10 @@ WITHOUT_LICENSE_TEXTS()
LICENSE(BSD-3-Clause)
-VERSION(2.0)
-
-ORIGINAL_SOURCE(https://github.com/gperftools/gperftools)
-
+VERSION(2.0)
+
+ORIGINAL_SOURCE(https://github.com/gperftools/gperftools)
+
OWNER(
g:contrib
g:cpp-contrib
diff --git a/contrib/libs/llvm12/CODE_OWNERS.TXT b/contrib/libs/llvm12/CODE_OWNERS.TXT
index 166d0286d1..6fc7cf1cd3 100644
--- a/contrib/libs/llvm12/CODE_OWNERS.TXT
+++ b/contrib/libs/llvm12/CODE_OWNERS.TXT
@@ -9,10 +9,10 @@ beautification by scripts. The fields are: name (N), email (E), web-address
(S) and (I) IRC handle. Each entry should contain at least the (N), (E) and
(D) fields.
-N: Paul C. Anagnostopoulos
-E: paul@windfall.com
-D: TableGen
-
+N: Paul C. Anagnostopoulos
+E: paul@windfall.com
+D: TableGen
+
N: Matt Arsenault
E: Matthew.Arsenault@amd.com
E: arsenm2@gmail.com
@@ -89,14 +89,14 @@ D: Branch weights and BlockFrequencyInfo
N: Hal Finkel
E: hfinkel@anl.gov
-D: The loop reroller and alias analysis
+D: The loop reroller and alias analysis
+
+N: Nemanja Ivanovic
+E: nemanja.i.ibm@gmail.com
+D: PowerPC Backend
-N: Nemanja Ivanovic
-E: nemanja.i.ibm@gmail.com
-D: PowerPC Backend
-
N: Dan Gohman
-E: llvm@sunfishcode.online
+E: llvm@sunfishcode.online
D: WebAssembly Backend (lib/Target/WebAssembly/*)
N: Renato Golin
@@ -176,10 +176,10 @@ N: Krzysztof Parzyszek
E: kparzysz@quicinc.com
D: Hexagon Backend
-N: Nigel Perks
-E: nigelp@xmos.com
-D: XCore Backend
-
+N: Nigel Perks
+E: nigelp@xmos.com
+D: XCore Backend
+
N: Jacques Pienaar
E: jpienaar@google.com
D: Lanai Backend
@@ -235,7 +235,7 @@ D: llvm-objcopy (tools/llvm-objcopy)
N: Martin Storsjö
E: martin@martin.st
D: MinGW
-
-N: Zi Xuan Wu (Zeson)
-E: zixuan.wu@linux.alibaba.com
-D: C-SKY backend (lib/Target/CSKY/*)
+
+N: Zi Xuan Wu (Zeson)
+E: zixuan.wu@linux.alibaba.com
+D: C-SKY backend (lib/Target/CSKY/*)
diff --git a/contrib/libs/llvm12/CREDITS.TXT b/contrib/libs/llvm12/CREDITS.TXT
index 33f06c3936..662f4bd6db 100644
--- a/contrib/libs/llvm12/CREDITS.TXT
+++ b/contrib/libs/llvm12/CREDITS.TXT
@@ -163,7 +163,7 @@ E: foldr@codedgers.com
D: Author of llvmc2
N: Dan Gohman
-E: llvm@sunfishcode.online
+E: llvm@sunfishcode.online
D: Miscellaneous bug fixes
D: WebAssembly Backend
@@ -337,10 +337,10 @@ N: Michael McCracken
E: michael.mccracken@gmail.com
D: Line number support for llvmgcc
-N: Fanbo Meng
-E: fanbo.meng@ibm.com
-D: z/OS support
-
+N: Fanbo Meng
+E: fanbo.meng@ibm.com
+D: z/OS support
+
N: Vladimir Merzliakov
E: wanderer@rsu.ru
D: Test suite fixes for FreeBSD
@@ -482,10 +482,10 @@ E: rspencer@reidspencer.com
W: http://reidspencer.com/
D: Lots of stuff, see: http://wiki.llvm.org/index.php/User:Reid
-N: Abhina Sreeskantharajan
-E: Abhina.Sreeskantharajan@ibm.com
-D: z/OS support
-
+N: Abhina Sreeskantharajan
+E: Abhina.Sreeskantharajan@ibm.com
+D: z/OS support
+
N: Alp Toker
E: alp@nuanti.com
W: http://atoker.com/
@@ -530,9 +530,9 @@ N: Li Jia He
E: hljhehlj@cn.ibm.com
D: PowerPC Backend Developer
-N: Zi Xuan Wu
-N: Zeson
-E: zixuan.wu@linux.alibaba.com
+N: Zi Xuan Wu
+N: Zeson
+E: zixuan.wu@linux.alibaba.com
N: Kang Zhang
E: shkzhang@cn.ibm.com
@@ -545,7 +545,7 @@ D: PowerPC Backend Developer
N: Djordje Todorovic
E: djordje.todorovic@rt-rk.com
D: Debug Information
-
-N: Biplob Mishra
-E: biplmish@in.ibm.com
-D: PowerPC Analysis
+
+N: Biplob Mishra
+E: biplmish@in.ibm.com
+D: PowerPC Analysis
diff --git a/contrib/libs/llvm12/include/llvm-c/Core.h b/contrib/libs/llvm12/include/llvm-c/Core.h
index cc24024524..788bc9997b 100644
--- a/contrib/libs/llvm12/include/llvm-c/Core.h
+++ b/contrib/libs/llvm12/include/llvm-c/Core.h
@@ -169,8 +169,8 @@ typedef enum {
LLVMX86_MMXTypeKind, /**< X86 MMX */
LLVMTokenTypeKind, /**< Tokens */
LLVMScalableVectorTypeKind, /**< Scalable SIMD vector type */
- LLVMBFloatTypeKind, /**< 16 bit brain floating point type */
- LLVMX86_AMXTypeKind /**< X86 AMX */
+ LLVMBFloatTypeKind, /**< 16 bit brain floating point type */
+ LLVMX86_AMXTypeKind /**< X86 AMX */
} LLVMTypeKind;
typedef enum {
@@ -289,7 +289,7 @@ typedef enum {
LLVMInlineAsmValueKind,
LLVMInstructionValueKind,
- LLVMPoisonValueValueKind
+ LLVMPoisonValueValueKind
} LLVMValueKind;
typedef enum {
@@ -612,17 +612,17 @@ unsigned LLVMGetEnumAttributeKind(LLVMAttributeRef A);
uint64_t LLVMGetEnumAttributeValue(LLVMAttributeRef A);
/**
- * Create a type attribute
- */
-LLVMAttributeRef LLVMCreateTypeAttribute(LLVMContextRef C, unsigned KindID,
- LLVMTypeRef type_ref);
-
-/**
- * Get the type attribute's value.
- */
-LLVMTypeRef LLVMGetTypeAttributeValue(LLVMAttributeRef A);
-
-/**
+ * Create a type attribute
+ */
+LLVMAttributeRef LLVMCreateTypeAttribute(LLVMContextRef C, unsigned KindID,
+ LLVMTypeRef type_ref);
+
+/**
+ * Get the type attribute's value.
+ */
+LLVMTypeRef LLVMGetTypeAttributeValue(LLVMAttributeRef A);
+
+/**
* Create a string attribute.
*/
LLVMAttributeRef LLVMCreateStringAttribute(LLVMContextRef C,
@@ -644,14 +644,14 @@ const char *LLVMGetStringAttributeValue(LLVMAttributeRef A, unsigned *Length);
*/
LLVMBool LLVMIsEnumAttribute(LLVMAttributeRef A);
LLVMBool LLVMIsStringAttribute(LLVMAttributeRef A);
-LLVMBool LLVMIsTypeAttribute(LLVMAttributeRef A);
+LLVMBool LLVMIsTypeAttribute(LLVMAttributeRef A);
+
+/**
+ * Obtain a Type from a context by its registered name.
+ */
+LLVMTypeRef LLVMGetTypeByName2(LLVMContextRef C, const char *Name);
/**
- * Obtain a Type from a context by its registered name.
- */
-LLVMTypeRef LLVMGetTypeByName2(LLVMContextRef C, const char *Name);
-
-/**
* @}
*/
@@ -892,7 +892,7 @@ LLVMValueRef LLVMGetInlineAsm(LLVMTypeRef Ty,
*/
LLVMContextRef LLVMGetModuleContext(LLVMModuleRef M);
-/** Deprecated: Use LLVMGetTypeByName2 instead. */
+/** Deprecated: Use LLVMGetTypeByName2 instead. */
LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name);
/**
@@ -1468,22 +1468,22 @@ unsigned LLVMGetPointerAddressSpace(LLVMTypeRef PointerTy);
LLVMTypeRef LLVMVectorType(LLVMTypeRef ElementType, unsigned ElementCount);
/**
- * Create a vector type that contains a defined type and has a scalable
- * number of elements.
+ * Create a vector type that contains a defined type and has a scalable
+ * number of elements.
*
- * The created type will exist in the context thats its element type
- * exists in.
+ * The created type will exist in the context thats its element type
+ * exists in.
+ *
+ * @see llvm::ScalableVectorType::get()
+ */
+LLVMTypeRef LLVMScalableVectorType(LLVMTypeRef ElementType,
+ unsigned ElementCount);
+
+/**
+ * Obtain the (possibly scalable) number of elements in a vector type.
+ *
+ * This only works on types that represent vectors (fixed or scalable).
*
- * @see llvm::ScalableVectorType::get()
- */
-LLVMTypeRef LLVMScalableVectorType(LLVMTypeRef ElementType,
- unsigned ElementCount);
-
-/**
- * Obtain the (possibly scalable) number of elements in a vector type.
- *
- * This only works on types that represent vectors (fixed or scalable).
- *
* @see llvm::VectorType::getNumElements()
*/
unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy);
@@ -1514,11 +1514,11 @@ LLVMTypeRef LLVMLabelTypeInContext(LLVMContextRef C);
LLVMTypeRef LLVMX86MMXTypeInContext(LLVMContextRef C);
/**
- * Create a X86 AMX type in a context.
- */
-LLVMTypeRef LLVMX86AMXTypeInContext(LLVMContextRef C);
-
-/**
+ * Create a X86 AMX type in a context.
+ */
+LLVMTypeRef LLVMX86AMXTypeInContext(LLVMContextRef C);
+
+/**
* Create a token type in a context.
*/
LLVMTypeRef LLVMTokenTypeInContext(LLVMContextRef C);
@@ -1535,7 +1535,7 @@ LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C);
LLVMTypeRef LLVMVoidType(void);
LLVMTypeRef LLVMLabelType(void);
LLVMTypeRef LLVMX86MMXType(void);
-LLVMTypeRef LLVMX86AMXType(void);
+LLVMTypeRef LLVMX86AMXType(void);
/**
* @}
@@ -1592,7 +1592,7 @@ LLVMTypeRef LLVMX86AMXType(void);
macro(Function) \
macro(GlobalVariable) \
macro(UndefValue) \
- macro(PoisonValue) \
+ macro(PoisonValue) \
macro(Instruction) \
macro(UnaryOperator) \
macro(BinaryOperator) \
@@ -1727,11 +1727,11 @@ LLVMBool LLVMIsConstant(LLVMValueRef Val);
LLVMBool LLVMIsUndef(LLVMValueRef Val);
/**
- * Determine whether a value instance is poisonous.
- */
-LLVMBool LLVMIsPoison(LLVMValueRef Val);
-
-/**
+ * Determine whether a value instance is poisonous.
+ */
+LLVMBool LLVMIsPoison(LLVMValueRef Val);
+
+/**
* Convert value instances between types.
*
* Internally, an LLVMValueRef is "pinned" to a specific type. This
@@ -1890,13 +1890,13 @@ LLVMValueRef LLVMConstAllOnes(LLVMTypeRef Ty);
LLVMValueRef LLVMGetUndef(LLVMTypeRef Ty);
/**
- * Obtain a constant value referring to a poison value of a type.
- *
- * @see llvm::PoisonValue::get()
- */
-LLVMValueRef LLVMGetPoison(LLVMTypeRef Ty);
-
-/**
+ * Obtain a constant value referring to a poison value of a type.
+ *
+ * @see llvm::PoisonValue::get()
+ */
+LLVMValueRef LLVMGetPoison(LLVMTypeRef Ty);
+
+/**
* Determine whether a value instance is null.
*
* @see llvm::Constant::isNullValue()
diff --git a/contrib/libs/llvm12/include/llvm-c/DebugInfo.h b/contrib/libs/llvm12/include/llvm-c/DebugInfo.h
index 5ae7ea139e..d4382ec4fb 100644
--- a/contrib/libs/llvm12/include/llvm-c/DebugInfo.h
+++ b/contrib/libs/llvm12/include/llvm-c/DebugInfo.h
@@ -166,9 +166,9 @@ enum {
LLVMDIImportedEntityMetadataKind,
LLVMDIMacroMetadataKind,
LLVMDIMacroFileMetadataKind,
- LLVMDICommonBlockMetadataKind,
- LLVMDIStringTypeMetadataKind,
- LLVMDIGenericSubrangeMetadataKind
+ LLVMDICommonBlockMetadataKind,
+ LLVMDIStringTypeMetadataKind,
+ LLVMDIGenericSubrangeMetadataKind
};
typedef unsigned LLVMMetadataKind;
diff --git a/contrib/libs/llvm12/include/llvm-c/Error.h b/contrib/libs/llvm12/include/llvm-c/Error.h
index b56951cfea..5e33613bd8 100644
--- a/contrib/libs/llvm12/include/llvm-c/Error.h
+++ b/contrib/libs/llvm12/include/llvm-c/Error.h
@@ -69,11 +69,11 @@ void LLVMDisposeErrorMessage(char *ErrMsg);
*/
LLVMErrorTypeId LLVMGetStringErrorTypeId(void);
-/**
- * Create a StringError.
- */
-LLVMErrorRef LLVMCreateStringError(const char *ErrMsg);
-
+/**
+ * Create a StringError.
+ */
+LLVMErrorRef LLVMCreateStringError(const char *ErrMsg);
+
LLVM_C_EXTERN_C_END
#endif
diff --git a/contrib/libs/llvm12/include/llvm-c/LLJIT.h b/contrib/libs/llvm12/include/llvm-c/LLJIT.h
index 2e0094fa5a..e92c772dd0 100644
--- a/contrib/libs/llvm12/include/llvm-c/LLJIT.h
+++ b/contrib/libs/llvm12/include/llvm-c/LLJIT.h
@@ -1,224 +1,224 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-/*===----------- llvm-c/LLJIT.h - OrcV2 LLJIT C bindings --------*- C++ -*-===*\
-|* *|
-|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
-|* Exceptions. *|
-|* See https://llvm.org/LICENSE.txt for license information. *|
-|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
-|* *|
-|*===----------------------------------------------------------------------===*|
-|* *|
-|* This header declares the C interface to the LLJIT class in *|
-|* libLLVMOrcJIT.a, which provides a simple MCJIT-like ORC JIT. *|
-|* *|
-|* Many exotic languages can interoperate with C code but have a harder time *|
-|* with C++ due to name mangling. So in addition to C, this interface enables *|
-|* tools written in such languages. *|
-|* *|
-|* Note: This interface is experimental. It is *NOT* stable, and may be *|
-|* changed without warning. Only C API usage documentation is *|
-|* provided. See the C++ documentation for all higher level ORC API *|
-|* details. *|
-|* *|
-\*===----------------------------------------------------------------------===*/
-
-#ifndef LLVM_C_LLJIT_H
-#define LLVM_C_LLJIT_H
-
-#include "llvm-c/Error.h"
-#include "llvm-c/Orc.h"
-#include "llvm-c/TargetMachine.h"
-#include "llvm-c/Types.h"
-
-LLVM_C_EXTERN_C_BEGIN
-
-/**
- * A function for constructing an ObjectLinkingLayer instance to be used
- * by an LLJIT instance.
- *
- * Clients can call LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator to
- * set the creator function to use when constructing an LLJIT instance.
- * This can be used to override the default linking layer implementation
- * that would otherwise be chosen by LLJITBuilder.
- *
- * Object linking layers returned by this function will become owned by the
- * LLJIT instance. The client is not responsible for managing their lifetimes
- * after the function returns.
- */
-typedef LLVMOrcObjectLayerRef (
- *LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction)(
- void *Ctx, LLVMOrcExecutionSessionRef ES, const char *Triple);
-
-/**
- * A reference to an orc::LLJITBuilder instance.
- */
-typedef struct LLVMOrcOpaqueLLJITBuilder *LLVMOrcLLJITBuilderRef;
-
-/**
- * A reference to an orc::LLJIT instance.
- */
-typedef struct LLVMOrcOpaqueLLJIT *LLVMOrcLLJITRef;
-
-/**
- * Create an LLVMOrcLLJITBuilder.
- *
- * The client owns the resulting LLJITBuilder and should dispose of it using
- * LLVMOrcDisposeLLJITBuilder once they are done with it.
- */
-LLVMOrcLLJITBuilderRef LLVMOrcCreateLLJITBuilder(void);
-
-/**
- * Dispose of an LLVMOrcLLJITBuilderRef. This should only be called if ownership
- * has not been passed to LLVMOrcCreateLLJIT (e.g. because some error prevented
- * that function from being called).
- */
-void LLVMOrcDisposeLLJITBuilder(LLVMOrcLLJITBuilderRef Builder);
-
-/**
- * Set the JITTargetMachineBuilder to be used when constructing the LLJIT
- * instance. Calling this function is optional: if it is not called then the
- * LLJITBuilder will use JITTargeTMachineBuilder::detectHost to construct a
- * JITTargetMachineBuilder.
- */
-void LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(
- LLVMOrcLLJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMB);
-
-/**
- * Set an ObjectLinkingLayer creator function for this LLJIT instance.
- */
-void LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator(
- LLVMOrcLLJITBuilderRef Builder,
- LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction F, void *Ctx);
-
-/**
- * Create an LLJIT instance from an LLJITBuilder.
- *
- * This operation takes ownership of the Builder argument: clients should not
- * dispose of the builder after calling this function (even if the function
- * returns an error). If a null Builder argument is provided then a
- * default-constructed LLJITBuilder will be used.
- *
- * On success the resulting LLJIT instance is uniquely owned by the client and
- * automatically manages the memory of all JIT'd code and all modules that are
- * transferred to it (e.g. via LLVMOrcLLJITAddLLVMIRModule). Disposing of the
- * LLJIT instance will free all memory managed by the JIT, including JIT'd code
- * and not-yet compiled modules.
- */
-LLVMErrorRef LLVMOrcCreateLLJIT(LLVMOrcLLJITRef *Result,
- LLVMOrcLLJITBuilderRef Builder);
-
-/**
- * Dispose of an LLJIT instance.
- */
-LLVMErrorRef LLVMOrcDisposeLLJIT(LLVMOrcLLJITRef J);
-
-/**
- * Get a reference to the ExecutionSession for this LLJIT instance.
- *
- * The ExecutionSession is owned by the LLJIT instance. The client is not
- * responsible for managing its memory.
- */
-LLVMOrcExecutionSessionRef LLVMOrcLLJITGetExecutionSession(LLVMOrcLLJITRef J);
-
-/**
- * Return a reference to the Main JITDylib.
- *
- * The JITDylib is owned by the LLJIT instance. The client is not responsible
- * for managing its memory.
- */
-LLVMOrcJITDylibRef LLVMOrcLLJITGetMainJITDylib(LLVMOrcLLJITRef J);
-
-/**
- * Return the target triple for this LLJIT instance. This string is owned by
- * the LLJIT instance and should not be freed by the client.
- */
-const char *LLVMOrcLLJITGetTripleString(LLVMOrcLLJITRef J);
-
-/**
- * Returns the global prefix character according to the LLJIT's DataLayout.
- */
-char LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J);
-
-/**
- * Mangles the given string according to the LLJIT instance's DataLayout, then
- * interns the result in the SymbolStringPool and returns a reference to the
- * pool entry. Clients should call LLVMOrcReleaseSymbolStringPoolEntry to
- * decrement the ref-count on the pool entry once they are finished with this
- * value.
- */
-LLVMOrcSymbolStringPoolEntryRef
-LLVMOrcLLJITMangleAndIntern(LLVMOrcLLJITRef J, const char *UnmangledName);
-
-/**
- * Add a buffer representing an object file to the given JITDylib in the given
- * LLJIT instance. This operation transfers ownership of the buffer to the
- * LLJIT instance. The buffer should not be disposed of or referenced once this
- * function returns.
- *
- * Resources associated with the given object will be tracked by the given
- * JITDylib's default resource tracker.
- */
-LLVMErrorRef LLVMOrcLLJITAddObjectFile(LLVMOrcLLJITRef J, LLVMOrcJITDylibRef JD,
- LLVMMemoryBufferRef ObjBuffer);
-
-/**
- * Add a buffer representing an object file to the given ResourceTracker's
- * JITDylib in the given LLJIT instance. This operation transfers ownership of
- * the buffer to the LLJIT instance. The buffer should not be disposed of or
- * referenced once this function returns.
- *
- * Resources associated with the given object will be tracked by ResourceTracker
- * RT.
- */
-LLVMErrorRef LLVMOrcLLJITAddObjectFileWithRT(LLVMOrcLLJITRef J,
- LLVMOrcResourceTrackerRef RT,
- LLVMMemoryBufferRef ObjBuffer);
-
-/**
- * Add an IR module to the given JITDylib in the given LLJIT instance. This
- * operation transfers ownership of the TSM argument to the LLJIT instance.
- * The TSM argument should not be disposed of or referenced once this
- * function returns.
- *
- * Resources associated with the given Module will be tracked by the given
- * JITDylib's default resource tracker.
- */
-LLVMErrorRef LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J,
- LLVMOrcJITDylibRef JD,
- LLVMOrcThreadSafeModuleRef TSM);
-
-/**
- * Add an IR module to the given ResourceTracker's JITDylib in the given LLJIT
- * instance. This operation transfers ownership of the TSM argument to the LLJIT
- * instance. The TSM argument should not be disposed of or referenced once this
- * function returns.
- *
- * Resources associated with the given Module will be tracked by ResourceTracker
- * RT.
- */
-LLVMErrorRef LLVMOrcLLJITAddLLVMIRModuleWithRT(LLVMOrcLLJITRef J,
- LLVMOrcResourceTrackerRef JD,
- LLVMOrcThreadSafeModuleRef TSM);
-
-/**
- * Look up the given symbol in the main JITDylib of the given LLJIT instance.
- *
- * This operation does not take ownership of the Name argument.
- */
-LLVMErrorRef LLVMOrcLLJITLookup(LLVMOrcLLJITRef J,
- LLVMOrcJITTargetAddress *Result,
- const char *Name);
-
-LLVM_C_EXTERN_C_END
-
-#endif /* LLVM_C_LLJIT_H */
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+/*===----------- llvm-c/LLJIT.h - OrcV2 LLJIT C bindings --------*- C++ -*-===*\
+|* *|
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
+|* Exceptions. *|
+|* See https://llvm.org/LICENSE.txt for license information. *|
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This header declares the C interface to the LLJIT class in *|
+|* libLLVMOrcJIT.a, which provides a simple MCJIT-like ORC JIT. *|
+|* *|
+|* Many exotic languages can interoperate with C code but have a harder time *|
+|* with C++ due to name mangling. So in addition to C, this interface enables *|
+|* tools written in such languages. *|
+|* *|
+|* Note: This interface is experimental. It is *NOT* stable, and may be *|
+|* changed without warning. Only C API usage documentation is *|
+|* provided. See the C++ documentation for all higher level ORC API *|
+|* details. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_LLJIT_H
+#define LLVM_C_LLJIT_H
+
+#include "llvm-c/Error.h"
+#include "llvm-c/Orc.h"
+#include "llvm-c/TargetMachine.h"
+#include "llvm-c/Types.h"
+
+LLVM_C_EXTERN_C_BEGIN
+
+/**
+ * A function for constructing an ObjectLinkingLayer instance to be used
+ * by an LLJIT instance.
+ *
+ * Clients can call LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator to
+ * set the creator function to use when constructing an LLJIT instance.
+ * This can be used to override the default linking layer implementation
+ * that would otherwise be chosen by LLJITBuilder.
+ *
+ * Object linking layers returned by this function will become owned by the
+ * LLJIT instance. The client is not responsible for managing their lifetimes
+ * after the function returns.
+ */
+typedef LLVMOrcObjectLayerRef (
+ *LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction)(
+ void *Ctx, LLVMOrcExecutionSessionRef ES, const char *Triple);
+
+/**
+ * A reference to an orc::LLJITBuilder instance.
+ */
+typedef struct LLVMOrcOpaqueLLJITBuilder *LLVMOrcLLJITBuilderRef;
+
+/**
+ * A reference to an orc::LLJIT instance.
+ */
+typedef struct LLVMOrcOpaqueLLJIT *LLVMOrcLLJITRef;
+
+/**
+ * Create an LLVMOrcLLJITBuilder.
+ *
+ * The client owns the resulting LLJITBuilder and should dispose of it using
+ * LLVMOrcDisposeLLJITBuilder once they are done with it.
+ */
+LLVMOrcLLJITBuilderRef LLVMOrcCreateLLJITBuilder(void);
+
+/**
+ * Dispose of an LLVMOrcLLJITBuilderRef. This should only be called if ownership
+ * has not been passed to LLVMOrcCreateLLJIT (e.g. because some error prevented
+ * that function from being called).
+ */
+void LLVMOrcDisposeLLJITBuilder(LLVMOrcLLJITBuilderRef Builder);
+
+/**
+ * Set the JITTargetMachineBuilder to be used when constructing the LLJIT
+ * instance. Calling this function is optional: if it is not called then the
+ * LLJITBuilder will use JITTargeTMachineBuilder::detectHost to construct a
+ * JITTargetMachineBuilder.
+ */
+void LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(
+ LLVMOrcLLJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMB);
+
+/**
+ * Set an ObjectLinkingLayer creator function for this LLJIT instance.
+ */
+void LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator(
+ LLVMOrcLLJITBuilderRef Builder,
+ LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction F, void *Ctx);
+
+/**
+ * Create an LLJIT instance from an LLJITBuilder.
+ *
+ * This operation takes ownership of the Builder argument: clients should not
+ * dispose of the builder after calling this function (even if the function
+ * returns an error). If a null Builder argument is provided then a
+ * default-constructed LLJITBuilder will be used.
+ *
+ * On success the resulting LLJIT instance is uniquely owned by the client and
+ * automatically manages the memory of all JIT'd code and all modules that are
+ * transferred to it (e.g. via LLVMOrcLLJITAddLLVMIRModule). Disposing of the
+ * LLJIT instance will free all memory managed by the JIT, including JIT'd code
+ * and not-yet compiled modules.
+ */
+LLVMErrorRef LLVMOrcCreateLLJIT(LLVMOrcLLJITRef *Result,
+ LLVMOrcLLJITBuilderRef Builder);
+
+/**
+ * Dispose of an LLJIT instance.
+ */
+LLVMErrorRef LLVMOrcDisposeLLJIT(LLVMOrcLLJITRef J);
+
+/**
+ * Get a reference to the ExecutionSession for this LLJIT instance.
+ *
+ * The ExecutionSession is owned by the LLJIT instance. The client is not
+ * responsible for managing its memory.
+ */
+LLVMOrcExecutionSessionRef LLVMOrcLLJITGetExecutionSession(LLVMOrcLLJITRef J);
+
+/**
+ * Return a reference to the Main JITDylib.
+ *
+ * The JITDylib is owned by the LLJIT instance. The client is not responsible
+ * for managing its memory.
+ */
+LLVMOrcJITDylibRef LLVMOrcLLJITGetMainJITDylib(LLVMOrcLLJITRef J);
+
+/**
+ * Return the target triple for this LLJIT instance. This string is owned by
+ * the LLJIT instance and should not be freed by the client.
+ */
+const char *LLVMOrcLLJITGetTripleString(LLVMOrcLLJITRef J);
+
+/**
+ * Returns the global prefix character according to the LLJIT's DataLayout.
+ */
+char LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J);
+
+/**
+ * Mangles the given string according to the LLJIT instance's DataLayout, then
+ * interns the result in the SymbolStringPool and returns a reference to the
+ * pool entry. Clients should call LLVMOrcReleaseSymbolStringPoolEntry to
+ * decrement the ref-count on the pool entry once they are finished with this
+ * value.
+ */
+LLVMOrcSymbolStringPoolEntryRef
+LLVMOrcLLJITMangleAndIntern(LLVMOrcLLJITRef J, const char *UnmangledName);
+
+/**
+ * Add a buffer representing an object file to the given JITDylib in the given
+ * LLJIT instance. This operation transfers ownership of the buffer to the
+ * LLJIT instance. The buffer should not be disposed of or referenced once this
+ * function returns.
+ *
+ * Resources associated with the given object will be tracked by the given
+ * JITDylib's default resource tracker.
+ */
+LLVMErrorRef LLVMOrcLLJITAddObjectFile(LLVMOrcLLJITRef J, LLVMOrcJITDylibRef JD,
+ LLVMMemoryBufferRef ObjBuffer);
+
+/**
+ * Add a buffer representing an object file to the given ResourceTracker's
+ * JITDylib in the given LLJIT instance. This operation transfers ownership of
+ * the buffer to the LLJIT instance. The buffer should not be disposed of or
+ * referenced once this function returns.
+ *
+ * Resources associated with the given object will be tracked by ResourceTracker
+ * RT.
+ */
+LLVMErrorRef LLVMOrcLLJITAddObjectFileWithRT(LLVMOrcLLJITRef J,
+ LLVMOrcResourceTrackerRef RT,
+ LLVMMemoryBufferRef ObjBuffer);
+
+/**
+ * Add an IR module to the given JITDylib in the given LLJIT instance. This
+ * operation transfers ownership of the TSM argument to the LLJIT instance.
+ * The TSM argument should not be disposed of or referenced once this
+ * function returns.
+ *
+ * Resources associated with the given Module will be tracked by the given
+ * JITDylib's default resource tracker.
+ */
+LLVMErrorRef LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J,
+ LLVMOrcJITDylibRef JD,
+ LLVMOrcThreadSafeModuleRef TSM);
+
+/**
+ * Add an IR module to the given ResourceTracker's JITDylib in the given LLJIT
+ * instance. This operation transfers ownership of the TSM argument to the LLJIT
+ * instance. The TSM argument should not be disposed of or referenced once this
+ * function returns.
+ *
+ * Resources associated with the given Module will be tracked by ResourceTracker
+ * RT.
+ */
+LLVMErrorRef LLVMOrcLLJITAddLLVMIRModuleWithRT(LLVMOrcLLJITRef J,
+ LLVMOrcResourceTrackerRef JD,
+ LLVMOrcThreadSafeModuleRef TSM);
+
+/**
+ * Look up the given symbol in the main JITDylib of the given LLJIT instance.
+ *
+ * This operation does not take ownership of the Name argument.
+ */
+LLVMErrorRef LLVMOrcLLJITLookup(LLVMOrcLLJITRef J,
+ LLVMOrcJITTargetAddress *Result,
+ const char *Name);
+
+LLVM_C_EXTERN_C_END
+
+#endif /* LLVM_C_LLJIT_H */
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm-c/Orc.h b/contrib/libs/llvm12/include/llvm-c/Orc.h
index 0a0d4d18c7..b05fde6838 100644
--- a/contrib/libs/llvm12/include/llvm-c/Orc.h
+++ b/contrib/libs/llvm12/include/llvm-c/Orc.h
@@ -46,200 +46,200 @@ LLVM_C_EXTERN_C_BEGIN
typedef uint64_t LLVMOrcJITTargetAddress;
/**
- * Represents generic linkage flags for a symbol definition.
- */
-typedef enum {
- LLVMJITSymbolGenericFlagsExported = 1U << 0,
- LLVMJITSymbolGenericFlagsWeak = 1U << 1
-} LLVMJITSymbolGenericFlags;
-
-/**
- * Represents target specific flags for a symbol definition.
- */
-typedef uint8_t LLVMJITTargetSymbolFlags;
-
-/**
- * Represents the linkage flags for a symbol definition.
- */
-typedef struct {
- uint8_t GenericFlags;
- uint8_t TargetFlags;
-} LLVMJITSymbolFlags;
-
-/**
- * Represents an evaluated symbol address and flags.
- */
-typedef struct {
- LLVMOrcJITTargetAddress Address;
- LLVMJITSymbolFlags Flags;
-} LLVMJITEvaluatedSymbol;
-
-/**
+ * Represents generic linkage flags for a symbol definition.
+ */
+typedef enum {
+ LLVMJITSymbolGenericFlagsExported = 1U << 0,
+ LLVMJITSymbolGenericFlagsWeak = 1U << 1
+} LLVMJITSymbolGenericFlags;
+
+/**
+ * Represents target specific flags for a symbol definition.
+ */
+typedef uint8_t LLVMJITTargetSymbolFlags;
+
+/**
+ * Represents the linkage flags for a symbol definition.
+ */
+typedef struct {
+ uint8_t GenericFlags;
+ uint8_t TargetFlags;
+} LLVMJITSymbolFlags;
+
+/**
+ * Represents an evaluated symbol address and flags.
+ */
+typedef struct {
+ LLVMOrcJITTargetAddress Address;
+ LLVMJITSymbolFlags Flags;
+} LLVMJITEvaluatedSymbol;
+
+/**
* A reference to an orc::ExecutionSession instance.
*/
typedef struct LLVMOrcOpaqueExecutionSession *LLVMOrcExecutionSessionRef;
/**
- * Error reporter function.
- */
-typedef void (*LLVMOrcErrorReporterFunction)(void *Ctx, LLVMErrorRef Err);
-
-/**
- * A reference to an orc::SymbolStringPool.
- */
-typedef struct LLVMOrcOpaqueSymbolStringPool *LLVMOrcSymbolStringPoolRef;
-
-/**
+ * Error reporter function.
+ */
+typedef void (*LLVMOrcErrorReporterFunction)(void *Ctx, LLVMErrorRef Err);
+
+/**
+ * A reference to an orc::SymbolStringPool.
+ */
+typedef struct LLVMOrcOpaqueSymbolStringPool *LLVMOrcSymbolStringPoolRef;
+
+/**
* A reference to an orc::SymbolStringPool table entry.
*/
-typedef struct LLVMOrcOpaqueSymbolStringPoolEntry
+typedef struct LLVMOrcOpaqueSymbolStringPoolEntry
*LLVMOrcSymbolStringPoolEntryRef;
/**
- * Represents a pair of a symbol name and an evaluated symbol.
- */
-typedef struct {
- LLVMOrcSymbolStringPoolEntryRef Name;
- LLVMJITEvaluatedSymbol Sym;
-} LLVMJITCSymbolMapPair;
-
-/**
- * Represents a list of (SymbolStringPtr, JITEvaluatedSymbol) pairs that can be
- * used to construct a SymbolMap.
- */
-typedef LLVMJITCSymbolMapPair *LLVMOrcCSymbolMapPairs;
-
-/**
- * Lookup kind. This can be used by definition generators when deciding whether
- * to produce a definition for a requested symbol.
- *
- * This enum should be kept in sync with llvm::orc::LookupKind.
- */
-typedef enum {
- LLVMOrcLookupKindStatic,
- LLVMOrcLookupKindDLSym
-} LLVMOrcLookupKind;
-
-/**
- * JITDylib lookup flags. This can be used by definition generators when
- * deciding whether to produce a definition for a requested symbol.
- *
- * This enum should be kept in sync with llvm::orc::JITDylibLookupFlags.
- */
-typedef enum {
- LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly,
- LLVMOrcJITDylibLookupFlagsMatchAllSymbols
-} LLVMOrcJITDylibLookupFlags;
-
-/**
- * Symbol lookup flags for lookup sets. This should be kept in sync with
- * llvm::orc::SymbolLookupFlags.
- */
-typedef enum {
- LLVMOrcSymbolLookupFlagsRequiredSymbol,
- LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol
-} LLVMOrcSymbolLookupFlags;
-
-/**
- * An element type for a symbol lookup set.
- */
-typedef struct {
- LLVMOrcSymbolStringPoolEntryRef Name;
- LLVMOrcSymbolLookupFlags LookupFlags;
-} LLVMOrcCLookupSetElement;
-
-/**
- * A set of symbols to look up / generate.
- *
- * The list is terminated with an element containing a null pointer for the
- * Name field.
- *
- * If a client creates an instance of this type then they are responsible for
- * freeing it, and for ensuring that all strings have been retained over the
- * course of its life. Clients receiving a copy from a callback are not
- * responsible for managing lifetime or retain counts.
- */
-typedef LLVMOrcCLookupSetElement *LLVMOrcCLookupSet;
-
-/**
- * A reference to an orc::MaterializationUnit.
- */
-typedef struct LLVMOrcOpaqueMaterializationUnit *LLVMOrcMaterializationUnitRef;
-
-/**
+ * Represents a pair of a symbol name and an evaluated symbol.
+ */
+typedef struct {
+ LLVMOrcSymbolStringPoolEntryRef Name;
+ LLVMJITEvaluatedSymbol Sym;
+} LLVMJITCSymbolMapPair;
+
+/**
+ * Represents a list of (SymbolStringPtr, JITEvaluatedSymbol) pairs that can be
+ * used to construct a SymbolMap.
+ */
+typedef LLVMJITCSymbolMapPair *LLVMOrcCSymbolMapPairs;
+
+/**
+ * Lookup kind. This can be used by definition generators when deciding whether
+ * to produce a definition for a requested symbol.
+ *
+ * This enum should be kept in sync with llvm::orc::LookupKind.
+ */
+typedef enum {
+ LLVMOrcLookupKindStatic,
+ LLVMOrcLookupKindDLSym
+} LLVMOrcLookupKind;
+
+/**
+ * JITDylib lookup flags. This can be used by definition generators when
+ * deciding whether to produce a definition for a requested symbol.
+ *
+ * This enum should be kept in sync with llvm::orc::JITDylibLookupFlags.
+ */
+typedef enum {
+ LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly,
+ LLVMOrcJITDylibLookupFlagsMatchAllSymbols
+} LLVMOrcJITDylibLookupFlags;
+
+/**
+ * Symbol lookup flags for lookup sets. This should be kept in sync with
+ * llvm::orc::SymbolLookupFlags.
+ */
+typedef enum {
+ LLVMOrcSymbolLookupFlagsRequiredSymbol,
+ LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol
+} LLVMOrcSymbolLookupFlags;
+
+/**
+ * An element type for a symbol lookup set.
+ */
+typedef struct {
+ LLVMOrcSymbolStringPoolEntryRef Name;
+ LLVMOrcSymbolLookupFlags LookupFlags;
+} LLVMOrcCLookupSetElement;
+
+/**
+ * A set of symbols to look up / generate.
+ *
+ * The list is terminated with an element containing a null pointer for the
+ * Name field.
+ *
+ * If a client creates an instance of this type then they are responsible for
+ * freeing it, and for ensuring that all strings have been retained over the
+ * course of its life. Clients receiving a copy from a callback are not
+ * responsible for managing lifetime or retain counts.
+ */
+typedef LLVMOrcCLookupSetElement *LLVMOrcCLookupSet;
+
+/**
+ * A reference to an orc::MaterializationUnit.
+ */
+typedef struct LLVMOrcOpaqueMaterializationUnit *LLVMOrcMaterializationUnitRef;
+
+/**
* A reference to an orc::JITDylib instance.
*/
typedef struct LLVMOrcOpaqueJITDylib *LLVMOrcJITDylibRef;
/**
- * A reference to an orc::ResourceTracker instance.
- */
-typedef struct LLVMOrcOpaqueResourceTracker *LLVMOrcResourceTrackerRef;
-
-/**
- * A reference to an orc::DefinitionGenerator.
- */
-typedef struct LLVMOrcOpaqueDefinitionGenerator
- *LLVMOrcDefinitionGeneratorRef;
-
-/**
- * An opaque lookup state object. Instances of this type can be captured to
- * suspend a lookup while a custom generator function attempts to produce a
- * definition.
- *
- * If a client captures a lookup state object then they must eventually call
- * LLVMOrcLookupStateContinueLookup to restart the lookup. This is required
- * in order to release memory allocated for the lookup state, even if errors
- * have occurred while the lookup was suspended (if these errors have made the
- * lookup impossible to complete then it will issue its own error before
- * destruction).
- */
-typedef struct LLVMOrcOpaqueLookupState *LLVMOrcLookupStateRef;
-
-/**
- * A custom generator function. This can be used to create a custom generator
- * object using LLVMOrcCreateCustomCAPIDefinitionGenerator. The resulting
- * object can be attached to a JITDylib, via LLVMOrcJITDylibAddGenerator, to
- * receive callbacks when lookups fail to match existing definitions.
- *
- * GeneratorObj will contain the address of the custom generator object.
- *
- * Ctx will contain the context object passed to
- * LLVMOrcCreateCustomCAPIDefinitionGenerator.
- *
- * LookupState will contain a pointer to an LLVMOrcLookupStateRef object. This
- * can optionally be modified to make the definition generation process
- * asynchronous: If the LookupStateRef value is copied, and the original
- * LLVMOrcLookupStateRef set to null, the lookup will be suspended. Once the
- * asynchronous definition process has been completed clients must call
- * LLVMOrcLookupStateContinueLookup to continue the lookup (this should be
- * done unconditionally, even if errors have occurred in the mean time, to
- * free the lookup state memory and notify the query object of the failures. If
- * LookupState is captured this function must return LLVMErrorSuccess.
- *
- * The Kind argument can be inspected to determine the lookup kind (e.g.
- * as-if-during-static-link, or as-if-during-dlsym).
- *
- * The JD argument specifies which JITDylib the definitions should be generated
- * into.
- *
- * The JDLookupFlags argument can be inspected to determine whether the original
- * lookup included non-exported symobls.
- *
- * Finally, the LookupSet argument contains the set of symbols that could not
- * be found in JD already (the set of generation candidates).
- */
-typedef LLVMErrorRef (*LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction)(
- LLVMOrcDefinitionGeneratorRef GeneratorObj, void *Ctx,
- LLVMOrcLookupStateRef *LookupState, LLVMOrcLookupKind Kind,
- LLVMOrcJITDylibRef JD, LLVMOrcJITDylibLookupFlags JDLookupFlags,
- LLVMOrcCLookupSet LookupSet, size_t LookupSetSize);
-
-/**
+ * A reference to an orc::ResourceTracker instance.
+ */
+typedef struct LLVMOrcOpaqueResourceTracker *LLVMOrcResourceTrackerRef;
+
+/**
+ * A reference to an orc::DefinitionGenerator.
+ */
+typedef struct LLVMOrcOpaqueDefinitionGenerator
+ *LLVMOrcDefinitionGeneratorRef;
+
+/**
+ * An opaque lookup state object. Instances of this type can be captured to
+ * suspend a lookup while a custom generator function attempts to produce a
+ * definition.
+ *
+ * If a client captures a lookup state object then they must eventually call
+ * LLVMOrcLookupStateContinueLookup to restart the lookup. This is required
+ * in order to release memory allocated for the lookup state, even if errors
+ * have occurred while the lookup was suspended (if these errors have made the
+ * lookup impossible to complete then it will issue its own error before
+ * destruction).
+ */
+typedef struct LLVMOrcOpaqueLookupState *LLVMOrcLookupStateRef;
+
+/**
+ * A custom generator function. This can be used to create a custom generator
+ * object using LLVMOrcCreateCustomCAPIDefinitionGenerator. The resulting
+ * object can be attached to a JITDylib, via LLVMOrcJITDylibAddGenerator, to
+ * receive callbacks when lookups fail to match existing definitions.
+ *
+ * GeneratorObj will contain the address of the custom generator object.
+ *
+ * Ctx will contain the context object passed to
+ * LLVMOrcCreateCustomCAPIDefinitionGenerator.
+ *
+ * LookupState will contain a pointer to an LLVMOrcLookupStateRef object. This
+ * can optionally be modified to make the definition generation process
+ * asynchronous: If the LookupStateRef value is copied, and the original
+ * LLVMOrcLookupStateRef set to null, the lookup will be suspended. Once the
+ * asynchronous definition process has been completed clients must call
+ * LLVMOrcLookupStateContinueLookup to continue the lookup (this should be
+ * done unconditionally, even if errors have occurred in the mean time, to
+ * free the lookup state memory and notify the query object of the failures. If
+ * LookupState is captured this function must return LLVMErrorSuccess.
+ *
+ * The Kind argument can be inspected to determine the lookup kind (e.g.
+ * as-if-during-static-link, or as-if-during-dlsym).
+ *
+ * The JD argument specifies which JITDylib the definitions should be generated
+ * into.
+ *
+ * The JDLookupFlags argument can be inspected to determine whether the original
+ * lookup included non-exported symobls.
+ *
+ * Finally, the LookupSet argument contains the set of symbols that could not
+ * be found in JD already (the set of generation candidates).
+ */
+typedef LLVMErrorRef (*LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction)(
+ LLVMOrcDefinitionGeneratorRef GeneratorObj, void *Ctx,
+ LLVMOrcLookupStateRef *LookupState, LLVMOrcLookupKind Kind,
+ LLVMOrcJITDylibRef JD, LLVMOrcJITDylibLookupFlags JDLookupFlags,
+ LLVMOrcCLookupSet LookupSet, size_t LookupSetSize);
+
+/**
* Predicate function for SymbolStringPoolEntries.
*/
-typedef int (*LLVMOrcSymbolPredicate)(void *Ctx,
- LLVMOrcSymbolStringPoolEntryRef Sym);
+typedef int (*LLVMOrcSymbolPredicate)(void *Ctx,
+ LLVMOrcSymbolStringPoolEntryRef Sym);
/**
* A reference to an orc::ThreadSafeContext instance.
@@ -258,45 +258,45 @@ typedef struct LLVMOrcOpaqueJITTargetMachineBuilder
*LLVMOrcJITTargetMachineBuilderRef;
/**
- * A reference to an orc::ObjectLayer instance.
- */
-typedef struct LLVMOrcOpaqueObjectLayer *LLVMOrcObjectLayerRef;
-
-/**
- * Attach a custom error reporter function to the ExecutionSession.
- *
- * The error reporter will be called to deliver failure notices that can not be
- * directly reported to a caller. For example, failure to resolve symbols in
- * the JIT linker is typically reported via the error reporter (callers
- * requesting definitions from the JIT will typically be delivered a
- * FailureToMaterialize error instead).
- */
-void LLVMOrcExecutionSessionSetErrorReporter(
- LLVMOrcExecutionSessionRef ES, LLVMOrcErrorReporterFunction ReportError,
- void *Ctx);
-
-/**
- * Return a reference to the SymbolStringPool for an ExecutionSession.
- *
- * Ownership of the pool remains with the ExecutionSession: The caller is
- * not required to free the pool.
- */
-LLVMOrcSymbolStringPoolRef
-LLVMOrcExecutionSessionGetSymbolStringPool(LLVMOrcExecutionSessionRef ES);
-
-/**
- * Clear all unreferenced symbol string pool entries.
- *
- * This can be called at any time to release unused entries in the
- * ExecutionSession's string pool. Since it locks the pool (preventing
- * interning of any new strings) it is recommended that it only be called
- * infrequently, ideally when the caller has reason to believe that some
- * entries will have become unreferenced, e.g. after removing a module or
- * closing a JITDylib.
- */
-void LLVMOrcSymbolStringPoolClearDeadEntries(LLVMOrcSymbolStringPoolRef SSP);
-
-/**
+ * A reference to an orc::ObjectLayer instance.
+ */
+typedef struct LLVMOrcOpaqueObjectLayer *LLVMOrcObjectLayerRef;
+
+/**
+ * Attach a custom error reporter function to the ExecutionSession.
+ *
+ * The error reporter will be called to deliver failure notices that can not be
+ * directly reported to a caller. For example, failure to resolve symbols in
+ * the JIT linker is typically reported via the error reporter (callers
+ * requesting definitions from the JIT will typically be delivered a
+ * FailureToMaterialize error instead).
+ */
+void LLVMOrcExecutionSessionSetErrorReporter(
+ LLVMOrcExecutionSessionRef ES, LLVMOrcErrorReporterFunction ReportError,
+ void *Ctx);
+
+/**
+ * Return a reference to the SymbolStringPool for an ExecutionSession.
+ *
+ * Ownership of the pool remains with the ExecutionSession: The caller is
+ * not required to free the pool.
+ */
+LLVMOrcSymbolStringPoolRef
+LLVMOrcExecutionSessionGetSymbolStringPool(LLVMOrcExecutionSessionRef ES);
+
+/**
+ * Clear all unreferenced symbol string pool entries.
+ *
+ * This can be called at any time to release unused entries in the
+ * ExecutionSession's string pool. Since it locks the pool (preventing
+ * interning of any new strings) it is recommended that it only be called
+ * infrequently, ideally when the caller has reason to believe that some
+ * entries will have become unreferenced, e.g. after removing a module or
+ * closing a JITDylib.
+ */
+void LLVMOrcSymbolStringPoolClearDeadEntries(LLVMOrcSymbolStringPoolRef SSP);
+
+/**
* Intern a string in the ExecutionSession's SymbolStringPool and return a
* reference to it. This increments the ref-count of the pool entry, and the
* returned value should be released once the client is done with it by
@@ -312,140 +312,140 @@ LLVMOrcSymbolStringPoolEntryRef
LLVMOrcExecutionSessionIntern(LLVMOrcExecutionSessionRef ES, const char *Name);
/**
- * Increments the ref-count for a SymbolStringPool entry.
- */
-void LLVMOrcRetainSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S);
-
-/**
+ * Increments the ref-count for a SymbolStringPool entry.
+ */
+void LLVMOrcRetainSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S);
+
+/**
* Reduces the ref-count for of a SymbolStringPool entry.
*/
void LLVMOrcReleaseSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S);
-const char *LLVMOrcSymbolStringPoolEntryStr(LLVMOrcSymbolStringPoolEntryRef S);
-
-/**
- * Reduces the ref-count of a ResourceTracker.
- */
-void LLVMOrcReleaseResourceTracker(LLVMOrcResourceTrackerRef RT);
-
-/**
- * Transfers tracking of all resources associated with resource tracker SrcRT
- * to resource tracker DstRT.
- */
-void LLVMOrcResourceTrackerTransferTo(LLVMOrcResourceTrackerRef SrcRT,
- LLVMOrcResourceTrackerRef DstRT);
-
-/**
- * Remove all resources associated with the given tracker. See
- * ResourceTracker::remove().
- */
-LLVMErrorRef LLVMOrcResourceTrackerRemove(LLVMOrcResourceTrackerRef RT);
-
-/**
+const char *LLVMOrcSymbolStringPoolEntryStr(LLVMOrcSymbolStringPoolEntryRef S);
+
+/**
+ * Reduces the ref-count of a ResourceTracker.
+ */
+void LLVMOrcReleaseResourceTracker(LLVMOrcResourceTrackerRef RT);
+
+/**
+ * Transfers tracking of all resources associated with resource tracker SrcRT
+ * to resource tracker DstRT.
+ */
+void LLVMOrcResourceTrackerTransferTo(LLVMOrcResourceTrackerRef SrcRT,
+ LLVMOrcResourceTrackerRef DstRT);
+
+/**
+ * Remove all resources associated with the given tracker. See
+ * ResourceTracker::remove().
+ */
+LLVMErrorRef LLVMOrcResourceTrackerRemove(LLVMOrcResourceTrackerRef RT);
+
+/**
* Dispose of a JITDylib::DefinitionGenerator. This should only be called if
* ownership has not been passed to a JITDylib (e.g. because some error
* prevented the client from calling LLVMOrcJITDylibAddGenerator).
*/
-void LLVMOrcDisposeDefinitionGenerator(LLVMOrcDefinitionGeneratorRef DG);
-
-/**
- * Dispose of a MaterializationUnit.
- */
-void LLVMOrcDisposeMaterializationUnit(LLVMOrcMaterializationUnitRef MU);
-
-/**
- * Create a MaterializationUnit to define the given symbols as pointing to
- * the corresponding raw addresses.
- */
-LLVMOrcMaterializationUnitRef
-LLVMOrcAbsoluteSymbols(LLVMOrcCSymbolMapPairs Syms, size_t NumPairs);
-
-/**
- * Create a "bare" JITDylib.
+void LLVMOrcDisposeDefinitionGenerator(LLVMOrcDefinitionGeneratorRef DG);
+
+/**
+ * Dispose of a MaterializationUnit.
+ */
+void LLVMOrcDisposeMaterializationUnit(LLVMOrcMaterializationUnitRef MU);
+
+/**
+ * Create a MaterializationUnit to define the given symbols as pointing to
+ * the corresponding raw addresses.
+ */
+LLVMOrcMaterializationUnitRef
+LLVMOrcAbsoluteSymbols(LLVMOrcCSymbolMapPairs Syms, size_t NumPairs);
+
+/**
+ * Create a "bare" JITDylib.
+ *
+ * The client is responsible for ensuring that the JITDylib's name is unique,
+ * e.g. by calling LLVMOrcExecutionSessionGetJTIDylibByName first.
+ *
+ * This call does not install any library code or symbols into the newly
+ * created JITDylib. The client is responsible for all configuration.
+ */
+LLVMOrcJITDylibRef
+LLVMOrcExecutionSessionCreateBareJITDylib(LLVMOrcExecutionSessionRef ES,
+ const char *Name);
+
+/**
+ * Create a JITDylib.
+ *
+ * The client is responsible for ensuring that the JITDylib's name is unique,
+ * e.g. by calling LLVMOrcExecutionSessionGetJTIDylibByName first.
+ *
+ * If a Platform is attached to the ExecutionSession then
+ * Platform::setupJITDylib will be called to install standard platform symbols
+ * (e.g. standard library interposes). If no Platform is installed then this
+ * call is equivalent to LLVMExecutionSessionRefCreateBareJITDylib and will
+ * always return success.
+ */
+LLVMErrorRef
+LLVMOrcExecutionSessionCreateJITDylib(LLVMOrcExecutionSessionRef ES,
+ LLVMOrcJITDylibRef *Result,
+ const char *Name);
+
+/**
+ * Returns the JITDylib with the given name, or NULL if no such JITDylib
+ * exists.
+ */
+LLVMOrcJITDylibRef
+LLVMOrcExecutionSessionGetJITDylibByName(LLVMOrcExecutionSessionRef ES,
+ const char *Name);
+
+/**
+ * Return a reference to a newly created resource tracker associated with JD.
+ * The tracker is returned with an initial ref-count of 1, and must be released
+ * with LLVMOrcReleaseResourceTracker when no longer needed.
+ */
+LLVMOrcResourceTrackerRef
+LLVMOrcJITDylibCreateResourceTracker(LLVMOrcJITDylibRef JD);
+
+/**
+ * Return a reference to the default resource tracker for the given JITDylib.
+ * This operation will increase the retain count of the tracker: Clients should
+ * call LLVMOrcReleaseResourceTracker when the result is no longer needed.
+ */
+LLVMOrcResourceTrackerRef
+LLVMOrcJITDylibGetDefaultResourceTracker(LLVMOrcJITDylibRef JD);
+
+/**
+ * Add the given MaterializationUnit to the given JITDylib.
+ *
+ * If this operation succeeds then JITDylib JD will take ownership of MU.
+ * If the operation fails then ownership remains with the caller who should
+ * call LLVMOrcDisposeMaterializationUnit to destroy it.
+ */
+LLVMErrorRef LLVMOrcJITDylibDefine(LLVMOrcJITDylibRef JD,
+ LLVMOrcMaterializationUnitRef MU);
+
+/**
+ * Calls remove on all trackers associated with this JITDylib, see
+ * JITDylib::clear().
+ */
+LLVMErrorRef LLVMOrcJITDylibClear(LLVMOrcJITDylibRef JD);
+
+/**
+ * Add a DefinitionGenerator to the given JITDylib.
*
- * The client is responsible for ensuring that the JITDylib's name is unique,
- * e.g. by calling LLVMOrcExecutionSessionGetJTIDylibByName first.
- *
- * This call does not install any library code or symbols into the newly
- * created JITDylib. The client is responsible for all configuration.
- */
-LLVMOrcJITDylibRef
-LLVMOrcExecutionSessionCreateBareJITDylib(LLVMOrcExecutionSessionRef ES,
- const char *Name);
-
-/**
- * Create a JITDylib.
- *
- * The client is responsible for ensuring that the JITDylib's name is unique,
- * e.g. by calling LLVMOrcExecutionSessionGetJTIDylibByName first.
- *
- * If a Platform is attached to the ExecutionSession then
- * Platform::setupJITDylib will be called to install standard platform symbols
- * (e.g. standard library interposes). If no Platform is installed then this
- * call is equivalent to LLVMExecutionSessionRefCreateBareJITDylib and will
- * always return success.
- */
-LLVMErrorRef
-LLVMOrcExecutionSessionCreateJITDylib(LLVMOrcExecutionSessionRef ES,
- LLVMOrcJITDylibRef *Result,
- const char *Name);
-
-/**
- * Returns the JITDylib with the given name, or NULL if no such JITDylib
- * exists.
- */
-LLVMOrcJITDylibRef
-LLVMOrcExecutionSessionGetJITDylibByName(LLVMOrcExecutionSessionRef ES,
- const char *Name);
-
-/**
- * Return a reference to a newly created resource tracker associated with JD.
- * The tracker is returned with an initial ref-count of 1, and must be released
- * with LLVMOrcReleaseResourceTracker when no longer needed.
- */
-LLVMOrcResourceTrackerRef
-LLVMOrcJITDylibCreateResourceTracker(LLVMOrcJITDylibRef JD);
-
-/**
- * Return a reference to the default resource tracker for the given JITDylib.
- * This operation will increase the retain count of the tracker: Clients should
- * call LLVMOrcReleaseResourceTracker when the result is no longer needed.
- */
-LLVMOrcResourceTrackerRef
-LLVMOrcJITDylibGetDefaultResourceTracker(LLVMOrcJITDylibRef JD);
-
-/**
- * Add the given MaterializationUnit to the given JITDylib.
- *
- * If this operation succeeds then JITDylib JD will take ownership of MU.
- * If the operation fails then ownership remains with the caller who should
- * call LLVMOrcDisposeMaterializationUnit to destroy it.
- */
-LLVMErrorRef LLVMOrcJITDylibDefine(LLVMOrcJITDylibRef JD,
- LLVMOrcMaterializationUnitRef MU);
-
-/**
- * Calls remove on all trackers associated with this JITDylib, see
- * JITDylib::clear().
- */
-LLVMErrorRef LLVMOrcJITDylibClear(LLVMOrcJITDylibRef JD);
-
-/**
- * Add a DefinitionGenerator to the given JITDylib.
- *
* The JITDylib will take ownership of the given generator: The client is no
* longer responsible for managing its memory.
*/
void LLVMOrcJITDylibAddGenerator(LLVMOrcJITDylibRef JD,
- LLVMOrcDefinitionGeneratorRef DG);
+ LLVMOrcDefinitionGeneratorRef DG);
+
+/**
+ * Create a custom generator.
+ */
+LLVMOrcDefinitionGeneratorRef LLVMOrcCreateCustomCAPIDefinitionGenerator(
+ LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction F, void *Ctx);
/**
- * Create a custom generator.
- */
-LLVMOrcDefinitionGeneratorRef LLVMOrcCreateCustomCAPIDefinitionGenerator(
- LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction F, void *Ctx);
-
-/**
* Get a DynamicLibrarySearchGenerator that will reflect process symbols into
* the JITDylib. On success the resulting generator is owned by the client.
* Ownership is typically transferred by adding the instance to a JITDylib
@@ -464,7 +464,7 @@ LLVMOrcDefinitionGeneratorRef LLVMOrcCreateCustomCAPIDefinitionGenerator(
* the global prefix if present.
*/
LLVMErrorRef LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(
- LLVMOrcDefinitionGeneratorRef *Result, char GlobalPrefx,
+ LLVMOrcDefinitionGeneratorRef *Result, char GlobalPrefx,
LLVMOrcSymbolPredicate Filter, void *FilterCtx);
/**
@@ -472,7 +472,7 @@ LLVMErrorRef LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(
*
* Ownership of the underlying ThreadSafeContext data is shared: Clients
* can and should dispose of their ThreadSafeContext as soon as they no longer
- * need to refer to it directly. Other references (e.g. from ThreadSafeModules)
+ * need to refer to it directly. Other references (e.g. from ThreadSafeModules)
* will keep the data alive as long as it is needed.
*/
LLVMOrcThreadSafeContextRef LLVMOrcCreateNewThreadSafeContext(void);
@@ -494,7 +494,7 @@ void LLVMOrcDisposeThreadSafeContext(LLVMOrcThreadSafeContextRef TSCtx);
* after this function returns.
*
* Ownership of the ThreadSafeModule is unique: If it is transferred to the JIT
- * (e.g. by LLVMOrcLLJITAddLLVMIRModule) then the client is no longer
+ * (e.g. by LLVMOrcLLJITAddLLVMIRModule) then the client is no longer
* responsible for it. If it is not transferred to the JIT then the client
* should call LLVMOrcDisposeThreadSafeModule to dispose of it.
*/
@@ -537,9 +537,9 @@ void LLVMOrcDisposeJITTargetMachineBuilder(
LLVMOrcJITTargetMachineBuilderRef JTMB);
/**
- * Dispose of an ObjectLayer.
+ * Dispose of an ObjectLayer.
*/
-void LLVMOrcDisposeObjectLayer(LLVMOrcObjectLayerRef ObjLayer);
+void LLVMOrcDisposeObjectLayer(LLVMOrcObjectLayerRef ObjLayer);
LLVM_C_EXTERN_C_END
diff --git a/contrib/libs/llvm12/include/llvm-c/OrcEE.h b/contrib/libs/llvm12/include/llvm-c/OrcEE.h
index b85197025d..a79007914e 100644
--- a/contrib/libs/llvm12/include/llvm-c/OrcEE.h
+++ b/contrib/libs/llvm12/include/llvm-c/OrcEE.h
@@ -1,66 +1,66 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-/*===-- llvm-c/OrcEE.h - OrcV2 C bindings ExecutionEngine utils -*- C++ -*-===*\
-|* *|
-|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
-|* Exceptions. *|
-|* See https://llvm.org/LICENSE.txt for license information. *|
-|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
-|* *|
-|*===----------------------------------------------------------------------===*|
-|* *|
-|* This header declares the C interface to ExecutionEngine based utils, e.g. *|
-|* RTDyldObjectLinkingLayer (based on RuntimeDyld) in Orc. *|
-|* *|
-|* Many exotic languages can interoperate with C code but have a harder time *|
-|* with C++ due to name mangling. So in addition to C, this interface enables *|
-|* tools written in such languages. *|
-|* *|
-|* Note: This interface is experimental. It is *NOT* stable, and may be *|
-|* changed without warning. Only C API usage documentation is *|
-|* provided. See the C++ documentation for all higher level ORC API *|
-|* details. *|
-|* *|
-\*===----------------------------------------------------------------------===*/
-
-#ifndef LLVM_C_ORCEE_H
-#define LLVM_C_ORCEE_H
-
-#include "llvm-c/Error.h"
-#include "llvm-c/ExecutionEngine.h"
-#include "llvm-c/Orc.h"
-#include "llvm-c/TargetMachine.h"
-#include "llvm-c/Types.h"
-
-LLVM_C_EXTERN_C_BEGIN
-
-/**
- * Create a RTDyldObjectLinkingLayer instance using the standard
- * SectionMemoryManager for memory management.
- */
-LLVMOrcObjectLayerRef
-LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager(
- LLVMOrcExecutionSessionRef ES);
-
-/**
- * Add the given listener to the given RTDyldObjectLinkingLayer.
- *
- * Note: Layer must be an RTDyldObjectLinkingLayer instance or
- * behavior is undefined.
- */
-void LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(
- LLVMOrcObjectLayerRef RTDyldObjLinkingLayer,
- LLVMJITEventListenerRef Listener);
-
-LLVM_C_EXTERN_C_END
-
-#endif /* LLVM_C_ORCEE_H */
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+/*===-- llvm-c/OrcEE.h - OrcV2 C bindings ExecutionEngine utils -*- C++ -*-===*\
+|* *|
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
+|* Exceptions. *|
+|* See https://llvm.org/LICENSE.txt for license information. *|
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This header declares the C interface to ExecutionEngine based utils, e.g. *|
+|* RTDyldObjectLinkingLayer (based on RuntimeDyld) in Orc. *|
+|* *|
+|* Many exotic languages can interoperate with C code but have a harder time *|
+|* with C++ due to name mangling. So in addition to C, this interface enables *|
+|* tools written in such languages. *|
+|* *|
+|* Note: This interface is experimental. It is *NOT* stable, and may be *|
+|* changed without warning. Only C API usage documentation is *|
+|* provided. See the C++ documentation for all higher level ORC API *|
+|* details. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_ORCEE_H
+#define LLVM_C_ORCEE_H
+
+#include "llvm-c/Error.h"
+#include "llvm-c/ExecutionEngine.h"
+#include "llvm-c/Orc.h"
+#include "llvm-c/TargetMachine.h"
+#include "llvm-c/Types.h"
+
+LLVM_C_EXTERN_C_BEGIN
+
+/**
+ * Create a RTDyldObjectLinkingLayer instance using the standard
+ * SectionMemoryManager for memory management.
+ */
+LLVMOrcObjectLayerRef
+LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager(
+ LLVMOrcExecutionSessionRef ES);
+
+/**
+ * Add the given listener to the given RTDyldObjectLinkingLayer.
+ *
+ * Note: Layer must be an RTDyldObjectLinkingLayer instance or
+ * behavior is undefined.
+ */
+void LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(
+ LLVMOrcObjectLayerRef RTDyldObjLinkingLayer,
+ LLVMJITEventListenerRef Listener);
+
+LLVM_C_EXTERN_C_END
+
+#endif /* LLVM_C_ORCEE_H */
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm-c/Transforms/Scalar.h b/contrib/libs/llvm12/include/llvm-c/Transforms/Scalar.h
index 1948959a0b..15a0885c2f 100644
--- a/contrib/libs/llvm12/include/llvm-c/Transforms/Scalar.h
+++ b/contrib/libs/llvm12/include/llvm-c/Transforms/Scalar.h
@@ -74,9 +74,9 @@ void LLVMAddIndVarSimplifyPass(LLVMPassManagerRef PM);
/** See llvm::createInstructionCombiningPass function. */
void LLVMAddInstructionCombiningPass(LLVMPassManagerRef PM);
-/** See llvm::createInstSimplifyLegacyPass function. */
-void LLVMAddInstructionSimplifyPass(LLVMPassManagerRef PM);
-
+/** See llvm::createInstSimplifyLegacyPass function. */
+void LLVMAddInstructionSimplifyPass(LLVMPassManagerRef PM);
+
/** See llvm::createJumpThreadingPass function. */
void LLVMAddJumpThreadingPass(LLVMPassManagerRef PM);
diff --git a/contrib/libs/llvm12/include/llvm/ADT/APFixedPoint.h b/contrib/libs/llvm12/include/llvm/ADT/APFixedPoint.h
index ae31489b2a..baa8b34993 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/APFixedPoint.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/APFixedPoint.h
@@ -1,248 +1,248 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- APFixedPoint.h - Fixed point constant handling -----------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file
-/// Defines the fixed point number interface.
-/// This is a class for abstracting various operations performed on fixed point
-/// types.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ADT_APFIXEDPOINT_H
-#define LLVM_ADT_APFIXEDPOINT_H
-
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace llvm {
-
-class APFloat;
-struct fltSemantics;
-
-/// The fixed point semantics work similarly to fltSemantics. The width
-/// specifies the whole bit width of the underlying scaled integer (with padding
-/// if any). The scale represents the number of fractional bits in this type.
-/// When HasUnsignedPadding is true and this type is unsigned, the first bit
-/// in the value this represents is treated as padding.
-class FixedPointSemantics {
-public:
- FixedPointSemantics(unsigned Width, unsigned Scale, bool IsSigned,
- bool IsSaturated, bool HasUnsignedPadding)
- : Width(Width), Scale(Scale), IsSigned(IsSigned),
- IsSaturated(IsSaturated), HasUnsignedPadding(HasUnsignedPadding) {
- assert(Width >= Scale && "Not enough room for the scale");
- assert(!(IsSigned && HasUnsignedPadding) &&
- "Cannot have unsigned padding on a signed type.");
- }
-
- unsigned getWidth() const { return Width; }
- unsigned getScale() const { return Scale; }
- bool isSigned() const { return IsSigned; }
- bool isSaturated() const { return IsSaturated; }
- bool hasUnsignedPadding() const { return HasUnsignedPadding; }
-
- void setSaturated(bool Saturated) { IsSaturated = Saturated; }
-
- /// Return the number of integral bits represented by these semantics. These
- /// are separate from the fractional bits and do not include the sign or
- /// padding bit.
- unsigned getIntegralBits() const {
- if (IsSigned || (!IsSigned && HasUnsignedPadding))
- return Width - Scale - 1;
- else
- return Width - Scale;
- }
-
- /// Return the FixedPointSemantics that allows for calculating the full
- /// precision semantic that can precisely represent the precision and ranges
- /// of both input values. This does not compute the resulting semantics for a
- /// given binary operation.
- FixedPointSemantics
- getCommonSemantics(const FixedPointSemantics &Other) const;
-
- /// Returns true if this fixed-point semantic with its value bits interpreted
- /// as an integer can fit in the given floating point semantic without
- /// overflowing to infinity.
- /// For example, a signed 8-bit fixed-point semantic has a maximum and
- /// minimum integer representation of 127 and -128, respectively. If both of
- /// these values can be represented (possibly inexactly) in the floating
- /// point semantic without overflowing, this returns true.
- bool fitsInFloatSemantics(const fltSemantics &FloatSema) const;
-
- /// Return the FixedPointSemantics for an integer type.
- static FixedPointSemantics GetIntegerSemantics(unsigned Width,
- bool IsSigned) {
- return FixedPointSemantics(Width, /*Scale=*/0, IsSigned,
- /*IsSaturated=*/false,
- /*HasUnsignedPadding=*/false);
- }
-
-private:
- unsigned Width : 16;
- unsigned Scale : 13;
- unsigned IsSigned : 1;
- unsigned IsSaturated : 1;
- unsigned HasUnsignedPadding : 1;
-};
-
-/// The APFixedPoint class works similarly to APInt/APSInt in that it is a
-/// functional replacement for a scaled integer. It is meant to replicate the
-/// fixed point types proposed in ISO/IEC JTC1 SC22 WG14 N1169. The class carries
-/// info about the fixed point type's width, sign, scale, and saturation, and
-/// provides different operations that would normally be performed on fixed point
-/// types.
-class APFixedPoint {
-public:
- APFixedPoint(const APInt &Val, const FixedPointSemantics &Sema)
- : Val(Val, !Sema.isSigned()), Sema(Sema) {
- assert(Val.getBitWidth() == Sema.getWidth() &&
- "The value should have a bit width that matches the Sema width");
- }
-
- APFixedPoint(uint64_t Val, const FixedPointSemantics &Sema)
- : APFixedPoint(APInt(Sema.getWidth(), Val, Sema.isSigned()), Sema) {}
-
- // Zero initialization.
- APFixedPoint(const FixedPointSemantics &Sema) : APFixedPoint(0, Sema) {}
-
- APSInt getValue() const { return APSInt(Val, !Sema.isSigned()); }
- inline unsigned getWidth() const { return Sema.getWidth(); }
- inline unsigned getScale() const { return Sema.getScale(); }
- inline bool isSaturated() const { return Sema.isSaturated(); }
- inline bool isSigned() const { return Sema.isSigned(); }
- inline bool hasPadding() const { return Sema.hasUnsignedPadding(); }
- FixedPointSemantics getSemantics() const { return Sema; }
-
- bool getBoolValue() const { return Val.getBoolValue(); }
-
- // Convert this number to match the semantics provided. If the overflow
- // parameter is provided, set this value to true or false to indicate if this
- // operation results in an overflow.
- APFixedPoint convert(const FixedPointSemantics &DstSema,
- bool *Overflow = nullptr) const;
-
- // Perform binary operations on a fixed point type. The resulting fixed point
- // value will be in the common, full precision semantics that can represent
- // the precision and ranges of both input values. See convert() for an
- // explanation of the Overflow parameter.
- APFixedPoint add(const APFixedPoint &Other, bool *Overflow = nullptr) const;
- APFixedPoint sub(const APFixedPoint &Other, bool *Overflow = nullptr) const;
- APFixedPoint mul(const APFixedPoint &Other, bool *Overflow = nullptr) const;
- APFixedPoint div(const APFixedPoint &Other, bool *Overflow = nullptr) const;
-
- // Perform shift operations on a fixed point type. Unlike the other binary
- // operations, the resulting fixed point value will be in the original
- // semantic.
- APFixedPoint shl(unsigned Amt, bool *Overflow = nullptr) const;
- APFixedPoint shr(unsigned Amt, bool *Overflow = nullptr) const {
- // Right shift cannot overflow.
- if (Overflow)
- *Overflow = false;
- return APFixedPoint(Val >> Amt, Sema);
- }
-
- /// Perform a unary negation (-X) on this fixed point type, taking into
- /// account saturation if applicable.
- APFixedPoint negate(bool *Overflow = nullptr) const;
-
- /// Return the integral part of this fixed point number, rounded towards
- /// zero. (-2.5k -> -2)
- APSInt getIntPart() const {
- if (Val < 0 && Val != -Val) // Cover the case when we have the min val
- return -(-Val >> getScale());
- else
- return Val >> getScale();
- }
-
- /// Return the integral part of this fixed point number, rounded towards
- /// zero. The value is stored into an APSInt with the provided width and sign.
- /// If the overflow parameter is provided, and the integral value is not able
- /// to be fully stored in the provided width and sign, the overflow parameter
- /// is set to true.
- APSInt convertToInt(unsigned DstWidth, bool DstSign,
- bool *Overflow = nullptr) const;
-
- /// Convert this fixed point number to a floating point value with the
- /// provided semantics.
- APFloat convertToFloat(const fltSemantics &FloatSema) const;
-
- void toString(SmallVectorImpl<char> &Str) const;
- std::string toString() const {
- SmallString<40> S;
- toString(S);
- return std::string(S.str());
- }
-
- // If LHS > RHS, return 1. If LHS == RHS, return 0. If LHS < RHS, return -1.
- int compare(const APFixedPoint &Other) const;
- bool operator==(const APFixedPoint &Other) const {
- return compare(Other) == 0;
- }
- bool operator!=(const APFixedPoint &Other) const {
- return compare(Other) != 0;
- }
- bool operator>(const APFixedPoint &Other) const { return compare(Other) > 0; }
- bool operator<(const APFixedPoint &Other) const { return compare(Other) < 0; }
- bool operator>=(const APFixedPoint &Other) const {
- return compare(Other) >= 0;
- }
- bool operator<=(const APFixedPoint &Other) const {
- return compare(Other) <= 0;
- }
-
- static APFixedPoint getMax(const FixedPointSemantics &Sema);
- static APFixedPoint getMin(const FixedPointSemantics &Sema);
-
- /// Given a floating point semantic, return the next floating point semantic
- /// with a larger exponent and larger or equal mantissa.
- static const fltSemantics *promoteFloatSemantics(const fltSemantics *S);
-
- /// Create an APFixedPoint with a value equal to that of the provided integer,
- /// and in the same semantics as the provided target semantics. If the value
- /// is not able to fit in the specified fixed point semantics, and the
- /// overflow parameter is provided, it is set to true.
- static APFixedPoint getFromIntValue(const APSInt &Value,
- const FixedPointSemantics &DstFXSema,
- bool *Overflow = nullptr);
-
- /// Create an APFixedPoint with a value equal to that of the provided
- /// floating point value, in the provided target semantics. If the value is
- /// not able to fit in the specified fixed point semantics and the overflow
- /// parameter is specified, it is set to true.
- /// For NaN, the Overflow flag is always set. For +inf and -inf, if the
- /// semantic is saturating, the value saturates. Otherwise, the Overflow flag
- /// is set.
- static APFixedPoint getFromFloatValue(const APFloat &Value,
- const FixedPointSemantics &DstFXSema,
- bool *Overflow = nullptr);
-
-private:
- APSInt Val;
- FixedPointSemantics Sema;
-};
-
-inline raw_ostream &operator<<(raw_ostream &OS, const APFixedPoint &FX) {
- OS << FX.toString();
- return OS;
-}
-
-} // namespace llvm
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- APFixedPoint.h - Fixed point constant handling -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// Defines the fixed point number interface.
+/// This is a class for abstracting various operations performed on fixed point
+/// types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_APFIXEDPOINT_H
+#define LLVM_ADT_APFIXEDPOINT_H
+
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+class APFloat;
+struct fltSemantics;
+
+/// The fixed point semantics work similarly to fltSemantics. The width
+/// specifies the whole bit width of the underlying scaled integer (with padding
+/// if any). The scale represents the number of fractional bits in this type.
+/// When HasUnsignedPadding is true and this type is unsigned, the first bit
+/// in the value this represents is treated as padding.
+class FixedPointSemantics {
+public:
+ FixedPointSemantics(unsigned Width, unsigned Scale, bool IsSigned,
+ bool IsSaturated, bool HasUnsignedPadding)
+ : Width(Width), Scale(Scale), IsSigned(IsSigned),
+ IsSaturated(IsSaturated), HasUnsignedPadding(HasUnsignedPadding) {
+ assert(Width >= Scale && "Not enough room for the scale");
+ assert(!(IsSigned && HasUnsignedPadding) &&
+ "Cannot have unsigned padding on a signed type.");
+ }
+
+ unsigned getWidth() const { return Width; }
+ unsigned getScale() const { return Scale; }
+ bool isSigned() const { return IsSigned; }
+ bool isSaturated() const { return IsSaturated; }
+ bool hasUnsignedPadding() const { return HasUnsignedPadding; }
+
+ void setSaturated(bool Saturated) { IsSaturated = Saturated; }
+
+ /// Return the number of integral bits represented by these semantics. These
+ /// are separate from the fractional bits and do not include the sign or
+ /// padding bit.
+ unsigned getIntegralBits() const {
+ if (IsSigned || (!IsSigned && HasUnsignedPadding))
+ return Width - Scale - 1;
+ else
+ return Width - Scale;
+ }
+
+ /// Return the FixedPointSemantics that allows for calculating the full
+ /// precision semantic that can precisely represent the precision and ranges
+ /// of both input values. This does not compute the resulting semantics for a
+ /// given binary operation.
+ FixedPointSemantics
+ getCommonSemantics(const FixedPointSemantics &Other) const;
+
+ /// Returns true if this fixed-point semantic with its value bits interpreted
+ /// as an integer can fit in the given floating point semantic without
+ /// overflowing to infinity.
+ /// For example, a signed 8-bit fixed-point semantic has a maximum and
+ /// minimum integer representation of 127 and -128, respectively. If both of
+ /// these values can be represented (possibly inexactly) in the floating
+ /// point semantic without overflowing, this returns true.
+ bool fitsInFloatSemantics(const fltSemantics &FloatSema) const;
+
+ /// Return the FixedPointSemantics for an integer type.
+ static FixedPointSemantics GetIntegerSemantics(unsigned Width,
+ bool IsSigned) {
+ return FixedPointSemantics(Width, /*Scale=*/0, IsSigned,
+ /*IsSaturated=*/false,
+ /*HasUnsignedPadding=*/false);
+ }
+
+private:
+ unsigned Width : 16;
+ unsigned Scale : 13;
+ unsigned IsSigned : 1;
+ unsigned IsSaturated : 1;
+ unsigned HasUnsignedPadding : 1;
+};
+
+/// The APFixedPoint class works similarly to APInt/APSInt in that it is a
+/// functional replacement for a scaled integer. It is meant to replicate the
+/// fixed point types proposed in ISO/IEC JTC1 SC22 WG14 N1169. The class carries
+/// info about the fixed point type's width, sign, scale, and saturation, and
+/// provides different operations that would normally be performed on fixed point
+/// types.
+class APFixedPoint {
+public:
+ APFixedPoint(const APInt &Val, const FixedPointSemantics &Sema)
+ : Val(Val, !Sema.isSigned()), Sema(Sema) {
+ assert(Val.getBitWidth() == Sema.getWidth() &&
+ "The value should have a bit width that matches the Sema width");
+ }
+
+ APFixedPoint(uint64_t Val, const FixedPointSemantics &Sema)
+ : APFixedPoint(APInt(Sema.getWidth(), Val, Sema.isSigned()), Sema) {}
+
+ // Zero initialization.
+ APFixedPoint(const FixedPointSemantics &Sema) : APFixedPoint(0, Sema) {}
+
+ APSInt getValue() const { return APSInt(Val, !Sema.isSigned()); }
+ inline unsigned getWidth() const { return Sema.getWidth(); }
+ inline unsigned getScale() const { return Sema.getScale(); }
+ inline bool isSaturated() const { return Sema.isSaturated(); }
+ inline bool isSigned() const { return Sema.isSigned(); }
+ inline bool hasPadding() const { return Sema.hasUnsignedPadding(); }
+ FixedPointSemantics getSemantics() const { return Sema; }
+
+ bool getBoolValue() const { return Val.getBoolValue(); }
+
+ // Convert this number to match the semantics provided. If the overflow
+ // parameter is provided, set this value to true or false to indicate if this
+ // operation results in an overflow.
+ APFixedPoint convert(const FixedPointSemantics &DstSema,
+ bool *Overflow = nullptr) const;
+
+ // Perform binary operations on a fixed point type. The resulting fixed point
+ // value will be in the common, full precision semantics that can represent
+ // the precision and ranges of both input values. See convert() for an
+ // explanation of the Overflow parameter.
+ APFixedPoint add(const APFixedPoint &Other, bool *Overflow = nullptr) const;
+ APFixedPoint sub(const APFixedPoint &Other, bool *Overflow = nullptr) const;
+ APFixedPoint mul(const APFixedPoint &Other, bool *Overflow = nullptr) const;
+ APFixedPoint div(const APFixedPoint &Other, bool *Overflow = nullptr) const;
+
+ // Perform shift operations on a fixed point type. Unlike the other binary
+ // operations, the resulting fixed point value will be in the original
+ // semantic.
+ APFixedPoint shl(unsigned Amt, bool *Overflow = nullptr) const;
+ APFixedPoint shr(unsigned Amt, bool *Overflow = nullptr) const {
+ // Right shift cannot overflow.
+ if (Overflow)
+ *Overflow = false;
+ return APFixedPoint(Val >> Amt, Sema);
+ }
+
+ /// Perform a unary negation (-X) on this fixed point type, taking into
+ /// account saturation if applicable.
+ APFixedPoint negate(bool *Overflow = nullptr) const;
+
+ /// Return the integral part of this fixed point number, rounded towards
+ /// zero. (-2.5k -> -2)
+ APSInt getIntPart() const {
+ if (Val < 0 && Val != -Val) // Cover the case when we have the min val
+ return -(-Val >> getScale());
+ else
+ return Val >> getScale();
+ }
+
+ /// Return the integral part of this fixed point number, rounded towards
+ /// zero. The value is stored into an APSInt with the provided width and sign.
+ /// If the overflow parameter is provided, and the integral value is not able
+ /// to be fully stored in the provided width and sign, the overflow parameter
+ /// is set to true.
+ APSInt convertToInt(unsigned DstWidth, bool DstSign,
+ bool *Overflow = nullptr) const;
+
+ /// Convert this fixed point number to a floating point value with the
+ /// provided semantics.
+ APFloat convertToFloat(const fltSemantics &FloatSema) const;
+
+ void toString(SmallVectorImpl<char> &Str) const;
+ std::string toString() const {
+ SmallString<40> S;
+ toString(S);
+ return std::string(S.str());
+ }
+
+ // If LHS > RHS, return 1. If LHS == RHS, return 0. If LHS < RHS, return -1.
+ int compare(const APFixedPoint &Other) const;
+ bool operator==(const APFixedPoint &Other) const {
+ return compare(Other) == 0;
+ }
+ bool operator!=(const APFixedPoint &Other) const {
+ return compare(Other) != 0;
+ }
+ bool operator>(const APFixedPoint &Other) const { return compare(Other) > 0; }
+ bool operator<(const APFixedPoint &Other) const { return compare(Other) < 0; }
+ bool operator>=(const APFixedPoint &Other) const {
+ return compare(Other) >= 0;
+ }
+ bool operator<=(const APFixedPoint &Other) const {
+ return compare(Other) <= 0;
+ }
+
+ static APFixedPoint getMax(const FixedPointSemantics &Sema);
+ static APFixedPoint getMin(const FixedPointSemantics &Sema);
+
+ /// Given a floating point semantic, return the next floating point semantic
+ /// with a larger exponent and larger or equal mantissa.
+ static const fltSemantics *promoteFloatSemantics(const fltSemantics *S);
+
+ /// Create an APFixedPoint with a value equal to that of the provided integer,
+ /// and in the same semantics as the provided target semantics. If the value
+ /// is not able to fit in the specified fixed point semantics, and the
+ /// overflow parameter is provided, it is set to true.
+ static APFixedPoint getFromIntValue(const APSInt &Value,
+ const FixedPointSemantics &DstFXSema,
+ bool *Overflow = nullptr);
+
+ /// Create an APFixedPoint with a value equal to that of the provided
+ /// floating point value, in the provided target semantics. If the value is
+ /// not able to fit in the specified fixed point semantics and the overflow
+ /// parameter is specified, it is set to true.
+ /// For NaN, the Overflow flag is always set. For +inf and -inf, if the
+ /// semantic is saturating, the value saturates. Otherwise, the Overflow flag
+ /// is set.
+ static APFixedPoint getFromFloatValue(const APFloat &Value,
+ const FixedPointSemantics &DstFXSema,
+ bool *Overflow = nullptr);
+
+private:
+ APSInt Val;
+ FixedPointSemantics Sema;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const APFixedPoint &FX) {
+ OS << FX.toString();
+ return OS;
+}
+
+} // namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/ADT/APFloat.h b/contrib/libs/llvm12/include/llvm/ADT/APFloat.h
index 2afb3070c3..14f63fb8a1 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/APFloat.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/APFloat.h
@@ -256,7 +256,7 @@ public:
/// \name Constructors
/// @{
- IEEEFloat(const fltSemantics &); // Default construct to +0.0
+ IEEEFloat(const fltSemantics &); // Default construct to +0.0
IEEEFloat(const fltSemantics &, integerPart);
IEEEFloat(const fltSemantics &, uninitializedTag);
IEEEFloat(const fltSemantics &, const APInt &);
@@ -546,9 +546,9 @@ private:
roundingMode) const;
opStatus roundSignificandWithExponent(const integerPart *, unsigned int, int,
roundingMode);
- ExponentType exponentNaN() const;
- ExponentType exponentInf() const;
- ExponentType exponentZero() const;
+ ExponentType exponentNaN() const;
+ ExponentType exponentInf() const;
+ ExponentType exponentZero() const;
/// @}
diff --git a/contrib/libs/llvm12/include/llvm/ADT/APInt.h b/contrib/libs/llvm12/include/llvm/ADT/APInt.h
index 2d8ff21c6e..8d378a25d1 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/APInt.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/APInt.h
@@ -38,7 +38,7 @@ class raw_ostream;
template <typename T> class SmallVectorImpl;
template <typename T> class ArrayRef;
template <typename T> class Optional;
-template <typename T> struct DenseMapInfo;
+template <typename T> struct DenseMapInfo;
class APInt;
@@ -104,7 +104,7 @@ private:
unsigned BitWidth; ///< The number of bits in this APInt.
- friend struct DenseMapInfo<APInt>;
+ friend struct DenseMapInfo<APInt>;
friend class APSInt;
@@ -772,8 +772,8 @@ public:
/// Move assignment operator.
APInt &operator=(APInt &&that) {
-#ifdef EXPENSIVE_CHECKS
- // Some std::shuffle implementations still do self-assignment.
+#ifdef EXPENSIVE_CHECKS
+ // Some std::shuffle implementations still do self-assignment.
if (this == &that)
return *this;
#endif
@@ -801,10 +801,10 @@ public:
APInt &operator=(uint64_t RHS) {
if (isSingleWord()) {
U.VAL = RHS;
- return clearUnusedBits();
+ return clearUnusedBits();
}
- U.pVal[0] = RHS;
- memset(U.pVal + 1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
+ U.pVal[0] = RHS;
+ memset(U.pVal + 1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
return *this;
}
@@ -861,9 +861,9 @@ public:
APInt &operator|=(uint64_t RHS) {
if (isSingleWord()) {
U.VAL |= RHS;
- return clearUnusedBits();
+ return clearUnusedBits();
}
- U.pVal[0] |= RHS;
+ U.pVal[0] |= RHS;
return *this;
}
@@ -890,9 +890,9 @@ public:
APInt &operator^=(uint64_t RHS) {
if (isSingleWord()) {
U.VAL ^= RHS;
- return clearUnusedBits();
+ return clearUnusedBits();
}
- U.pVal[0] ^= RHS;
+ U.pVal[0] ^= RHS;
return *this;
}
@@ -1410,12 +1410,12 @@ public:
/// extended, truncated, or left alone to make it that width.
APInt zextOrTrunc(unsigned width) const;
- /// Truncate to width
- ///
- /// Make this APInt have the bit width given by \p width. The value is
- /// truncated or left alone to make it that width.
- APInt truncOrSelf(unsigned width) const;
-
+ /// Truncate to width
+ ///
+ /// Make this APInt have the bit width given by \p width. The value is
+ /// truncated or left alone to make it that width.
+ APInt truncOrSelf(unsigned width) const;
+
/// Sign extend or truncate to width
///
/// Make this APInt have the bit width given by \p width. The value is sign
@@ -1460,14 +1460,14 @@ public:
setBit(BitWidth - 1);
}
- /// Set a given bit to a given value.
- void setBitVal(unsigned BitPosition, bool BitValue) {
- if (BitValue)
- setBit(BitPosition);
- else
- clearBit(BitPosition);
- }
-
+ /// Set a given bit to a given value.
+ void setBitVal(unsigned BitPosition, bool BitValue) {
+ if (BitValue)
+ setBit(BitPosition);
+ else
+ clearBit(BitPosition);
+ }
+
/// Set the bits from loBit (inclusive) to hiBit (exclusive) to 1.
/// This function handles "wrap" case when \p loBit >= \p hiBit, and calls
/// setBits when \p loBit < \p hiBit.
@@ -1628,7 +1628,7 @@ public:
/// returns the smallest bit width that will retain the negative value. For
/// example, -1 can be written as 0b1 or 0xFFFFFFFFFF. 0b1 is shorter and so
/// for -1, this function will always return 1.
- unsigned getMinSignedBits() const { return BitWidth - getNumSignBits() + 1; }
+ unsigned getMinSignedBits() const { return BitWidth - getNumSignBits() + 1; }
/// Get zero extended value
///
diff --git a/contrib/libs/llvm12/include/llvm/ADT/APSInt.h b/contrib/libs/llvm12/include/llvm/ADT/APSInt.h
index e2f9ccf863..0a07d2ec0c 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/APSInt.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/APSInt.h
@@ -25,7 +25,7 @@
namespace llvm {
-/// An arbitrary precision integer that knows its signedness.
+/// An arbitrary precision integer that knows its signedness.
class LLVM_NODISCARD APSInt : public APInt {
bool IsUnsigned;
@@ -33,7 +33,7 @@ public:
/// Default constructor that creates an uninitialized APInt.
explicit APSInt() : IsUnsigned(false) {}
- /// Create an APSInt with the specified width, default to unsigned.
+ /// Create an APSInt with the specified width, default to unsigned.
explicit APSInt(uint32_t BitWidth, bool isUnsigned = true)
: APInt(BitWidth, 0), IsUnsigned(isUnsigned) {}
@@ -85,11 +85,11 @@ public:
void setIsUnsigned(bool Val) { IsUnsigned = Val; }
void setIsSigned(bool Val) { IsUnsigned = !Val; }
- /// Append this APSInt to the specified SmallString.
+ /// Append this APSInt to the specified SmallString.
void toString(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
APInt::toString(Str, Radix, isSigned());
}
- /// Converts an APInt to a std::string. This is an inefficient
+ /// Converts an APInt to a std::string. This is an inefficient
/// method; you should prefer passing in a SmallString instead.
std::string toString(unsigned Radix) const {
return APInt::toString(Radix, isSigned());
@@ -289,15 +289,15 @@ public:
return APSInt(~static_cast<const APInt&>(*this), IsUnsigned);
}
- /// Return the APSInt representing the maximum integer value with the given
- /// bit width and signedness.
+ /// Return the APSInt representing the maximum integer value with the given
+ /// bit width and signedness.
static APSInt getMaxValue(uint32_t numBits, bool Unsigned) {
return APSInt(Unsigned ? APInt::getMaxValue(numBits)
: APInt::getSignedMaxValue(numBits), Unsigned);
}
- /// Return the APSInt representing the minimum integer value with the given
- /// bit width and signedness.
+ /// Return the APSInt representing the minimum integer value with the given
+ /// bit width and signedness.
static APSInt getMinValue(uint32_t numBits, bool Unsigned) {
return APSInt(Unsigned ? APInt::getMinValue(numBits)
: APInt::getSignedMinValue(numBits), Unsigned);
@@ -338,8 +338,8 @@ public:
static APSInt get(int64_t X) { return APSInt(APInt(64, X), false); }
static APSInt getUnsigned(uint64_t X) { return APSInt(APInt(64, X), true); }
- /// Used to insert APSInt objects, or objects that contain APSInt objects,
- /// into FoldingSets.
+ /// Used to insert APSInt objects, or objects that contain APSInt objects,
+ /// into FoldingSets.
void Profile(FoldingSetNodeID& ID) const;
};
diff --git a/contrib/libs/llvm12/include/llvm/ADT/Any.h b/contrib/libs/llvm12/include/llvm/ADT/Any.h
index 66c6f25981..adb8f22b95 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/Any.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/Any.h
@@ -30,12 +30,12 @@
namespace llvm {
-class LLVM_EXTERNAL_VISIBILITY Any {
-
- // The `Typeid<T>::Id` static data member below is a globally unique
- // identifier for the type `T`. It is explicitly marked with default
- // visibility so that when `-fvisibility=hidden` is used, the loader still
- // merges duplicate definitions across DSO boundaries.
+class LLVM_EXTERNAL_VISIBILITY Any {
+
+ // The `Typeid<T>::Id` static data member below is a globally unique
+ // identifier for the type `T`. It is explicitly marked with default
+ // visibility so that when `-fvisibility=hidden` is used, the loader still
+ // merges duplicate definitions across DSO boundaries.
template <typename T> struct TypeId { static const char Id; };
struct StorageBase {
diff --git a/contrib/libs/llvm12/include/llvm/ADT/BitVector.h b/contrib/libs/llvm12/include/llvm/ADT/BitVector.h
index 69a00a99b6..c1806c6d23 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/BitVector.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/BitVector.h
@@ -210,10 +210,10 @@ public:
return !any();
}
- /// find_first_in - Returns the index of the first set / unset bit,
- /// depending on \p Set, in the range [Begin, End).
- /// Returns -1 if all bits in the range are unset / set.
- int find_first_in(unsigned Begin, unsigned End, bool Set = true) const {
+ /// find_first_in - Returns the index of the first set / unset bit,
+ /// depending on \p Set, in the range [Begin, End).
+ /// Returns -1 if all bits in the range are unset / set.
+ int find_first_in(unsigned Begin, unsigned End, bool Set = true) const {
assert(Begin <= End && End <= Size);
if (Begin == End)
return -1;
@@ -222,14 +222,14 @@ public:
unsigned LastWord = (End - 1) / BITWORD_SIZE;
// Check subsequent words.
- // The code below is based on search for the first _set_ bit. If
- // we're searching for the first _unset_, we just take the
- // complement of each word before we use it and apply
- // the same method.
+ // The code below is based on search for the first _set_ bit. If
+ // we're searching for the first _unset_, we just take the
+ // complement of each word before we use it and apply
+ // the same method.
for (unsigned i = FirstWord; i <= LastWord; ++i) {
BitWord Copy = Bits[i];
- if (!Set)
- Copy = ~Copy;
+ if (!Set)
+ Copy = ~Copy;
if (i == FirstWord) {
unsigned FirstBit = Begin % BITWORD_SIZE;
@@ -280,7 +280,7 @@ public:
/// find_first_unset_in - Returns the index of the first unset bit in the
/// range [Begin, End). Returns -1 if all bits in the range are set.
int find_first_unset_in(unsigned Begin, unsigned End) const {
- return find_first_in(Begin, End, /* Set = */ false);
+ return find_first_in(Begin, End, /* Set = */ false);
}
/// find_last_unset_in - Returns the index of the last unset bit in the
diff --git a/contrib/libs/llvm12/include/llvm/ADT/DenseMap.h b/contrib/libs/llvm12/include/llvm/ADT/DenseMap.h
index 96839b7288..bcc503ee21 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/DenseMap.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/DenseMap.h
@@ -433,8 +433,8 @@ protected:
setNumEntries(other.getNumEntries());
setNumTombstones(other.getNumTombstones());
- if (std::is_trivially_copyable<KeyT>::value &&
- std::is_trivially_copyable<ValueT>::value)
+ if (std::is_trivially_copyable<KeyT>::value &&
+ std::is_trivially_copyable<ValueT>::value)
memcpy(reinterpret_cast<void *>(getBuckets()), other.getBuckets(),
getNumBuckets() * sizeof(BucketT));
else
@@ -961,7 +961,7 @@ public:
std::swap(*LHSB, *RHSB);
continue;
}
- // Swap separately and handle any asymmetry.
+ // Swap separately and handle any asymmetry.
std::swap(LHSB->getFirst(), RHSB->getFirst());
if (hasLHSValue) {
::new (&RHSB->getSecond()) ValueT(std::move(LHSB->getSecond()));
@@ -1049,7 +1049,7 @@ public:
if (Small) {
// First move the inline buckets into a temporary storage.
AlignedCharArrayUnion<BucketT[InlineBuckets]> TmpStorage;
- BucketT *TmpBegin = reinterpret_cast<BucketT *>(&TmpStorage);
+ BucketT *TmpBegin = reinterpret_cast<BucketT *>(&TmpStorage);
BucketT *TmpEnd = TmpBegin;
// Loop over the buckets, moving non-empty, non-tombstones into the
@@ -1139,8 +1139,8 @@ private:
assert(Small);
// Note that this cast does not violate aliasing rules as we assert that
// the memory's dynamic type is the small, inline bucket buffer, and the
- // 'storage' is a POD containing a char buffer.
- return reinterpret_cast<const BucketT *>(&storage);
+ // 'storage' is a POD containing a char buffer.
+ return reinterpret_cast<const BucketT *>(&storage);
}
BucketT *getInlineBuckets() {
@@ -1151,7 +1151,7 @@ private:
const LargeRep *getLargeRep() const {
assert(!Small);
// Note, same rule about aliasing as with getInlineBuckets.
- return reinterpret_cast<const LargeRep *>(&storage);
+ return reinterpret_cast<const LargeRep *>(&storage);
}
LargeRep *getLargeRep() {
diff --git a/contrib/libs/llvm12/include/llvm/ADT/DenseMapInfo.h b/contrib/libs/llvm12/include/llvm/ADT/DenseMapInfo.h
index 98af8ca088..03ef6ea0b0 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/DenseMapInfo.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/DenseMapInfo.h
@@ -20,8 +20,8 @@
#ifndef LLVM_ADT_DENSEMAPINFO_H
#define LLVM_ADT_DENSEMAPINFO_H
-#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringRef.h"
@@ -356,49 +356,49 @@ template <> struct DenseMapInfo<hash_code> {
static bool isEqual(hash_code LHS, hash_code RHS) { return LHS == RHS; }
};
-/// Provide DenseMapInfo for APInt.
-template <> struct DenseMapInfo<APInt> {
- static inline APInt getEmptyKey() {
- APInt V(nullptr, 0);
- V.U.VAL = 0;
- return V;
- }
-
- static inline APInt getTombstoneKey() {
- APInt V(nullptr, 0);
- V.U.VAL = 1;
- return V;
- }
-
- static unsigned getHashValue(const APInt &Key) {
- return static_cast<unsigned>(hash_value(Key));
- }
-
- static bool isEqual(const APInt &LHS, const APInt &RHS) {
- return LHS.getBitWidth() == RHS.getBitWidth() && LHS == RHS;
- }
-};
-
-/// Provide DenseMapInfo for APSInt, using the DenseMapInfo for APInt.
-template <> struct DenseMapInfo<APSInt> {
- static inline APSInt getEmptyKey() {
- return APSInt(DenseMapInfo<APInt>::getEmptyKey());
- }
-
- static inline APSInt getTombstoneKey() {
- return APSInt(DenseMapInfo<APInt>::getTombstoneKey());
- }
-
- static unsigned getHashValue(const APSInt &Key) {
- return static_cast<unsigned>(hash_value(Key));
- }
-
- static bool isEqual(const APSInt &LHS, const APSInt &RHS) {
- return LHS.getBitWidth() == RHS.getBitWidth() &&
- LHS.isUnsigned() == RHS.isUnsigned() && LHS == RHS;
- }
-};
-
+/// Provide DenseMapInfo for APInt.
+template <> struct DenseMapInfo<APInt> {
+ static inline APInt getEmptyKey() {
+ APInt V(nullptr, 0);
+ V.U.VAL = 0;
+ return V;
+ }
+
+ static inline APInt getTombstoneKey() {
+ APInt V(nullptr, 0);
+ V.U.VAL = 1;
+ return V;
+ }
+
+ static unsigned getHashValue(const APInt &Key) {
+ return static_cast<unsigned>(hash_value(Key));
+ }
+
+ static bool isEqual(const APInt &LHS, const APInt &RHS) {
+ return LHS.getBitWidth() == RHS.getBitWidth() && LHS == RHS;
+ }
+};
+
+/// Provide DenseMapInfo for APSInt, using the DenseMapInfo for APInt.
+template <> struct DenseMapInfo<APSInt> {
+ static inline APSInt getEmptyKey() {
+ return APSInt(DenseMapInfo<APInt>::getEmptyKey());
+ }
+
+ static inline APSInt getTombstoneKey() {
+ return APSInt(DenseMapInfo<APInt>::getTombstoneKey());
+ }
+
+ static unsigned getHashValue(const APSInt &Key) {
+ return static_cast<unsigned>(hash_value(Key));
+ }
+
+ static bool isEqual(const APSInt &LHS, const APSInt &RHS) {
+ return LHS.getBitWidth() == RHS.getBitWidth() &&
+ LHS.isUnsigned() == RHS.isUnsigned() && LHS == RHS;
+ }
+};
+
} // end namespace llvm
#endif // LLVM_ADT_DENSEMAPINFO_H
diff --git a/contrib/libs/llvm12/include/llvm/ADT/DenseSet.h b/contrib/libs/llvm12/include/llvm/ADT/DenseSet.h
index d6fac1f323..a0a79f6fdc 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/DenseSet.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/DenseSet.h
@@ -188,11 +188,11 @@ public:
return ConstIterator(TheMap.find(V));
}
- /// Check if the set contains the given element.
- bool contains(const_arg_type_t<ValueT> V) const {
- return TheMap.find(V) != TheMap.end();
- }
-
+ /// Check if the set contains the given element.
+ bool contains(const_arg_type_t<ValueT> V) const {
+ return TheMap.find(V) != TheMap.end();
+ }
+
/// Alternative version of find() which allows a different, and possibly less
/// expensive, key type.
/// The DenseMapInfo is responsible for supplying methods
diff --git a/contrib/libs/llvm12/include/llvm/ADT/DepthFirstIterator.h b/contrib/libs/llvm12/include/llvm/ADT/DepthFirstIterator.h
index fce66034e3..71b6e6d158 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/DepthFirstIterator.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/DepthFirstIterator.h
@@ -205,7 +205,7 @@ public:
// nodes that a depth first iteration did not find: ie unreachable nodes.
//
bool nodeVisited(NodeRef Node) const {
- return this->Visited.contains(Node);
+ return this->Visited.contains(Node);
}
/// getPathLength - Return the length of the path from the entry node to the
diff --git a/contrib/libs/llvm12/include/llvm/ADT/DirectedGraph.h b/contrib/libs/llvm12/include/llvm/ADT/DirectedGraph.h
index acc4460c74..49c6a73148 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/DirectedGraph.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/DirectedGraph.h
@@ -236,7 +236,7 @@ public:
if (*Node == N)
continue;
Node->findEdgesTo(N, TempList);
- llvm::append_range(EL, TempList);
+ llvm::append_range(EL, TempList);
TempList.clear();
}
return !EL.empty();
diff --git a/contrib/libs/llvm12/include/llvm/ADT/FloatingPointMode.h b/contrib/libs/llvm12/include/llvm/ADT/FloatingPointMode.h
index b1ef7f1ba5..dc71c475da 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/FloatingPointMode.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/FloatingPointMode.h
@@ -51,24 +51,24 @@ enum class RoundingMode : int8_t {
Invalid = -1 ///< Denotes invalid value.
};
-/// Returns text representation of the given rounding mode.
-inline StringRef spell(RoundingMode RM) {
- switch (RM) {
- case RoundingMode::TowardZero: return "towardzero";
- case RoundingMode::NearestTiesToEven: return "tonearest";
- case RoundingMode::TowardPositive: return "upward";
- case RoundingMode::TowardNegative: return "downward";
- case RoundingMode::NearestTiesToAway: return "tonearestaway";
- case RoundingMode::Dynamic: return "dynamic";
- default: return "invalid";
- }
-}
-
-inline raw_ostream &operator << (raw_ostream &OS, RoundingMode RM) {
- OS << spell(RM);
- return OS;
-}
-
+/// Returns text representation of the given rounding mode.
+inline StringRef spell(RoundingMode RM) {
+ switch (RM) {
+ case RoundingMode::TowardZero: return "towardzero";
+ case RoundingMode::NearestTiesToEven: return "tonearest";
+ case RoundingMode::TowardPositive: return "upward";
+ case RoundingMode::TowardNegative: return "downward";
+ case RoundingMode::NearestTiesToAway: return "tonearestaway";
+ case RoundingMode::Dynamic: return "dynamic";
+ default: return "invalid";
+ }
+}
+
+inline raw_ostream &operator << (raw_ostream &OS, RoundingMode RM) {
+ OS << spell(RM);
+ return OS;
+}
+
/// Represent subnormal handling kind for floating point instruction inputs and
/// outputs.
struct DenormalMode {
diff --git a/contrib/libs/llvm12/include/llvm/ADT/FunctionExtras.h b/contrib/libs/llvm12/include/llvm/ADT/FunctionExtras.h
index aed288cf0a..8eae5fb1cc 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/FunctionExtras.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/FunctionExtras.h
@@ -71,13 +71,13 @@ template <typename ReturnT, typename... ParamTs> class UniqueFunctionBase {
protected:
static constexpr size_t InlineStorageSize = sizeof(void *) * 3;
- template <typename T, class = void>
- struct IsSizeLessThanThresholdT : std::false_type {};
+ template <typename T, class = void>
+ struct IsSizeLessThanThresholdT : std::false_type {};
+
+ template <typename T>
+ struct IsSizeLessThanThresholdT<
+ T, std::enable_if_t<sizeof(T) <= 2 * sizeof(void *)>> : std::true_type {};
- template <typename T>
- struct IsSizeLessThanThresholdT<
- T, std::enable_if_t<sizeof(T) <= 2 * sizeof(void *)>> : std::true_type {};
-
// Provide a type function to map parameters that won't observe extra copies
// or moves and which are small enough to likely pass in register to values
// and all other types to l-value reference types. We use this to compute the
diff --git a/contrib/libs/llvm12/include/llvm/ADT/Hashing.h b/contrib/libs/llvm12/include/llvm/ADT/Hashing.h
index da16cbb67a..d6d956afaf 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/Hashing.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/Hashing.h
@@ -59,7 +59,7 @@
#include <cassert>
#include <cstring>
#include <string>
-#include <tuple>
+#include <tuple>
#include <utility>
namespace llvm {
@@ -120,10 +120,10 @@ template <typename T> hash_code hash_value(const T *ptr);
template <typename T, typename U>
hash_code hash_value(const std::pair<T, U> &arg);
-/// Compute a hash_code for a tuple.
-template <typename... Ts>
-hash_code hash_value(const std::tuple<Ts...> &arg);
-
+/// Compute a hash_code for a tuple.
+template <typename... Ts>
+hash_code hash_value(const std::tuple<Ts...> &arg);
+
/// Compute a hash_code for a standard string.
template <typename T>
hash_code hash_value(const std::basic_string<T> &arg);
@@ -657,26 +657,26 @@ hash_code hash_value(const std::pair<T, U> &arg) {
return hash_combine(arg.first, arg.second);
}
-// Implementation details for the hash_value overload for std::tuple<...>(...).
-namespace hashing {
-namespace detail {
-
-template <typename... Ts, std::size_t... Indices>
-hash_code hash_value_tuple_helper(const std::tuple<Ts...> &arg,
- std::index_sequence<Indices...> indices) {
- return hash_combine(std::get<Indices>(arg)...);
-}
-
-} // namespace detail
-} // namespace hashing
-
-template <typename... Ts>
-hash_code hash_value(const std::tuple<Ts...> &arg) {
- // TODO: Use std::apply when LLVM starts using C++17.
- return ::llvm::hashing::detail::hash_value_tuple_helper(
- arg, typename std::index_sequence_for<Ts...>());
-}
-
+// Implementation details for the hash_value overload for std::tuple<...>(...).
+namespace hashing {
+namespace detail {
+
+template <typename... Ts, std::size_t... Indices>
+hash_code hash_value_tuple_helper(const std::tuple<Ts...> &arg,
+ std::index_sequence<Indices...> indices) {
+ return hash_combine(std::get<Indices>(arg)...);
+}
+
+} // namespace detail
+} // namespace hashing
+
+template <typename... Ts>
+hash_code hash_value(const std::tuple<Ts...> &arg) {
+ // TODO: Use std::apply when LLVM starts using C++17.
+ return ::llvm::hashing::detail::hash_value_tuple_helper(
+ arg, typename std::index_sequence_for<Ts...>());
+}
+
// Declared and documented above, but defined here so that any of the hashing
// infrastructure is available.
template <typename T>
diff --git a/contrib/libs/llvm12/include/llvm/ADT/IntervalMap.h b/contrib/libs/llvm12/include/llvm/ADT/IntervalMap.h
index d2dd871692..efe8149cc2 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/IntervalMap.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/IntervalMap.h
@@ -970,7 +970,7 @@ public:
private:
// The root data is either a RootLeaf or a RootBranchData instance.
- AlignedCharArrayUnion<RootLeaf, RootBranchData> data;
+ AlignedCharArrayUnion<RootLeaf, RootBranchData> data;
// Tree height.
// 0: Leaves in root.
@@ -985,7 +985,7 @@ private:
Allocator &allocator;
/// Represent data as a node type without breaking aliasing rules.
- template <typename T> T &dataAs() const { return *bit_cast<T *>(&data); }
+ template <typename T> T &dataAs() const { return *bit_cast<T *>(&data); }
const RootLeaf &rootLeaf() const {
assert(!branched() && "Cannot acces leaf data in branched root");
@@ -1043,7 +1043,7 @@ private:
public:
explicit IntervalMap(Allocator &a) : height(0), rootSize(0), allocator(a) {
- assert((uintptr_t(&data) & (alignof(RootLeaf) - 1)) == 0 &&
+ assert((uintptr_t(&data) & (alignof(RootLeaf) - 1)) == 0 &&
"Insufficient alignment");
new(&rootLeaf()) RootLeaf();
}
diff --git a/contrib/libs/llvm12/include/llvm/ADT/IntrusiveRefCntPtr.h b/contrib/libs/llvm12/include/llvm/ADT/IntrusiveRefCntPtr.h
index 4f44fc927a..28bfb913ca 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/IntrusiveRefCntPtr.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/IntrusiveRefCntPtr.h
@@ -65,7 +65,7 @@
#include <atomic>
#include <cassert>
#include <cstddef>
-#include <memory>
+#include <memory>
namespace llvm {
@@ -78,23 +78,23 @@ namespace llvm {
template <class Derived> class RefCountedBase {
mutable unsigned RefCount = 0;
-protected:
+protected:
RefCountedBase() = default;
RefCountedBase(const RefCountedBase &) {}
- RefCountedBase &operator=(const RefCountedBase &) = delete;
-
-#ifndef NDEBUG
- ~RefCountedBase() {
- assert(RefCount == 0 &&
- "Destruction occured when there are still references to this.");
- }
-#else
- // Default the destructor in release builds, A trivial destructor may enable
- // better codegen.
- ~RefCountedBase() = default;
-#endif
-
-public:
+ RefCountedBase &operator=(const RefCountedBase &) = delete;
+
+#ifndef NDEBUG
+ ~RefCountedBase() {
+ assert(RefCount == 0 &&
+ "Destruction occured when there are still references to this.");
+ }
+#else
+ // Default the destructor in release builds, A trivial destructor may enable
+ // better codegen.
+ ~RefCountedBase() = default;
+#endif
+
+public:
void Retain() const { ++RefCount; }
void Release() const {
@@ -106,25 +106,25 @@ public:
/// A thread-safe version of \c RefCountedBase.
template <class Derived> class ThreadSafeRefCountedBase {
- mutable std::atomic<int> RefCount{0};
+ mutable std::atomic<int> RefCount{0};
protected:
- ThreadSafeRefCountedBase() = default;
- ThreadSafeRefCountedBase(const ThreadSafeRefCountedBase &) {}
- ThreadSafeRefCountedBase &
- operator=(const ThreadSafeRefCountedBase &) = delete;
-
-#ifndef NDEBUG
- ~ThreadSafeRefCountedBase() {
- assert(RefCount == 0 &&
- "Destruction occured when there are still references to this.");
- }
-#else
- // Default the destructor in release builds, A trivial destructor may enable
- // better codegen.
- ~ThreadSafeRefCountedBase() = default;
-#endif
-
+ ThreadSafeRefCountedBase() = default;
+ ThreadSafeRefCountedBase(const ThreadSafeRefCountedBase &) {}
+ ThreadSafeRefCountedBase &
+ operator=(const ThreadSafeRefCountedBase &) = delete;
+
+#ifndef NDEBUG
+ ~ThreadSafeRefCountedBase() {
+ assert(RefCount == 0 &&
+ "Destruction occured when there are still references to this.");
+ }
+#else
+ // Default the destructor in release builds, A trivial destructor may enable
+ // better codegen.
+ ~ThreadSafeRefCountedBase() = default;
+#endif
+
public:
void Retain() const { RefCount.fetch_add(1, std::memory_order_relaxed); }
@@ -184,11 +184,11 @@ public:
}
template <class X>
- IntrusiveRefCntPtr(std::unique_ptr<X> S) : Obj(S.release()) {
- retain();
- }
-
- template <class X>
+ IntrusiveRefCntPtr(std::unique_ptr<X> S) : Obj(S.release()) {
+ retain();
+ }
+
+ template <class X>
IntrusiveRefCntPtr(const IntrusiveRefCntPtr<X> &S) : Obj(S.get()) {
retain();
}
@@ -304,12 +304,12 @@ template <class T> struct simplify_type<const IntrusiveRefCntPtr<T>> {
}
};
-/// Factory function for creating intrusive ref counted pointers.
-template <typename T, typename... Args>
-IntrusiveRefCntPtr<T> makeIntrusiveRefCnt(Args &&...A) {
- return IntrusiveRefCntPtr<T>(new T(std::forward<Args>(A)...));
-}
-
+/// Factory function for creating intrusive ref counted pointers.
+template <typename T, typename... Args>
+IntrusiveRefCntPtr<T> makeIntrusiveRefCnt(Args &&...A) {
+ return IntrusiveRefCntPtr<T>(new T(std::forward<Args>(A)...));
+}
+
} // end namespace llvm
#endif // LLVM_ADT_INTRUSIVEREFCNTPTR_H
diff --git a/contrib/libs/llvm12/include/llvm/ADT/Optional.h b/contrib/libs/llvm12/include/llvm/ADT/Optional.h
index e3d9ea6eef..0f0725c73e 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/Optional.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/Optional.h
@@ -22,7 +22,7 @@
#ifndef LLVM_ADT_OPTIONAL_H
#define LLVM_ADT_OPTIONAL_H
-#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/None.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/type_traits.h"
@@ -40,30 +40,30 @@ namespace optional_detail {
struct in_place_t {};
/// Storage for any type.
-//
-// The specialization condition intentionally uses
-// llvm::is_trivially_copy_constructible instead of
-// std::is_trivially_copy_constructible. GCC versions prior to 7.4 may
-// instantiate the copy constructor of `T` when
-// std::is_trivially_copy_constructible is instantiated. This causes
-// compilation to fail if we query the trivially copy constructible property of
-// a class which is not copy constructible.
-//
-// The current implementation of OptionalStorage insists that in order to use
-// the trivial specialization, the value_type must be trivially copy
-// constructible and trivially copy assignable due to =default implementations
-// of the copy/move constructor/assignment. It does not follow that this is
-// necessarily the case std::is_trivially_copyable is true (hence the expanded
-// specialization condition).
-//
-// The move constructible / assignable conditions emulate the remaining behavior
-// of std::is_trivially_copyable.
-template <typename T, bool = (llvm::is_trivially_copy_constructible<T>::value &&
- std::is_trivially_copy_assignable<T>::value &&
- (std::is_trivially_move_constructible<T>::value ||
- !std::is_move_constructible<T>::value) &&
- (std::is_trivially_move_assignable<T>::value ||
- !std::is_move_assignable<T>::value))>
+//
+// The specialization condition intentionally uses
+// llvm::is_trivially_copy_constructible instead of
+// std::is_trivially_copy_constructible. GCC versions prior to 7.4 may
+// instantiate the copy constructor of `T` when
+// std::is_trivially_copy_constructible is instantiated. This causes
+// compilation to fail if we query the trivially copy constructible property of
+// a class which is not copy constructible.
+//
+// The current implementation of OptionalStorage insists that in order to use
+// the trivial specialization, the value_type must be trivially copy
+// constructible and trivially copy assignable due to =default implementations
+// of the copy/move constructor/assignment. It does not follow that this is
+// necessarily the case std::is_trivially_copyable is true (hence the expanded
+// specialization condition).
+//
+// The move constructible / assignable conditions emulate the remaining behavior
+// of std::is_trivially_copyable.
+template <typename T, bool = (llvm::is_trivially_copy_constructible<T>::value &&
+ std::is_trivially_copy_assignable<T>::value &&
+ (std::is_trivially_move_constructible<T>::value ||
+ !std::is_move_constructible<T>::value) &&
+ (std::is_trivially_move_assignable<T>::value ||
+ !std::is_move_assignable<T>::value))>
class OptionalStorage {
union {
char empty;
@@ -74,21 +74,21 @@ class OptionalStorage {
public:
~OptionalStorage() { reset(); }
- constexpr OptionalStorage() noexcept : empty(), hasVal(false) {}
+ constexpr OptionalStorage() noexcept : empty(), hasVal(false) {}
- constexpr OptionalStorage(OptionalStorage const &other) : OptionalStorage() {
+ constexpr OptionalStorage(OptionalStorage const &other) : OptionalStorage() {
if (other.hasValue()) {
emplace(other.value);
}
}
- constexpr OptionalStorage(OptionalStorage &&other) : OptionalStorage() {
+ constexpr OptionalStorage(OptionalStorage &&other) : OptionalStorage() {
if (other.hasValue()) {
emplace(std::move(other.value));
}
}
template <class... Args>
- constexpr explicit OptionalStorage(in_place_t, Args &&... args)
+ constexpr explicit OptionalStorage(in_place_t, Args &&... args)
: value(std::forward<Args>(args)...), hasVal(true) {}
void reset() noexcept {
@@ -98,13 +98,13 @@ public:
}
}
- constexpr bool hasValue() const noexcept { return hasVal; }
+ constexpr bool hasValue() const noexcept { return hasVal; }
T &getValue() LLVM_LVALUE_FUNCTION noexcept {
assert(hasVal);
return value;
}
- constexpr T const &getValue() const LLVM_LVALUE_FUNCTION noexcept {
+ constexpr T const &getValue() const LLVM_LVALUE_FUNCTION noexcept {
assert(hasVal);
return value;
}
@@ -179,16 +179,16 @@ template <typename T> class OptionalStorage<T, true> {
public:
~OptionalStorage() = default;
- constexpr OptionalStorage() noexcept : empty{} {}
+ constexpr OptionalStorage() noexcept : empty{} {}
- constexpr OptionalStorage(OptionalStorage const &other) = default;
- constexpr OptionalStorage(OptionalStorage &&other) = default;
+ constexpr OptionalStorage(OptionalStorage const &other) = default;
+ constexpr OptionalStorage(OptionalStorage &&other) = default;
OptionalStorage &operator=(OptionalStorage const &other) = default;
OptionalStorage &operator=(OptionalStorage &&other) = default;
template <class... Args>
- constexpr explicit OptionalStorage(in_place_t, Args &&... args)
+ constexpr explicit OptionalStorage(in_place_t, Args &&... args)
: value(std::forward<Args>(args)...), hasVal(true) {}
void reset() noexcept {
@@ -198,13 +198,13 @@ public:
}
}
- constexpr bool hasValue() const noexcept { return hasVal; }
+ constexpr bool hasValue() const noexcept { return hasVal; }
T &getValue() LLVM_LVALUE_FUNCTION noexcept {
assert(hasVal);
return value;
}
- constexpr T const &getValue() const LLVM_LVALUE_FUNCTION noexcept {
+ constexpr T const &getValue() const LLVM_LVALUE_FUNCTION noexcept {
assert(hasVal);
return value;
}
@@ -252,12 +252,12 @@ public:
constexpr Optional() {}
constexpr Optional(NoneType) {}
- constexpr Optional(const T &y) : Storage(optional_detail::in_place_t{}, y) {}
- constexpr Optional(const Optional &O) = default;
+ constexpr Optional(const T &y) : Storage(optional_detail::in_place_t{}, y) {}
+ constexpr Optional(const Optional &O) = default;
- constexpr Optional(T &&y)
- : Storage(optional_detail::in_place_t{}, std::move(y)) {}
- constexpr Optional(Optional &&O) = default;
+ constexpr Optional(T &&y)
+ : Storage(optional_detail::in_place_t{}, std::move(y)) {}
+ constexpr Optional(Optional &&O) = default;
Optional &operator=(T &&y) {
Storage = std::move(y);
@@ -270,7 +270,7 @@ public:
Storage.emplace(std::forward<ArgTypes>(Args)...);
}
- static constexpr Optional create(const T *y) {
+ static constexpr Optional create(const T *y) {
return y ? Optional(*y) : Optional();
}
@@ -282,20 +282,20 @@ public:
void reset() { Storage.reset(); }
- constexpr const T *getPointer() const { return &Storage.getValue(); }
+ constexpr const T *getPointer() const { return &Storage.getValue(); }
T *getPointer() { return &Storage.getValue(); }
- constexpr const T &getValue() const LLVM_LVALUE_FUNCTION {
- return Storage.getValue();
- }
+ constexpr const T &getValue() const LLVM_LVALUE_FUNCTION {
+ return Storage.getValue();
+ }
T &getValue() LLVM_LVALUE_FUNCTION { return Storage.getValue(); }
- constexpr explicit operator bool() const { return hasValue(); }
- constexpr bool hasValue() const { return Storage.hasValue(); }
- constexpr const T *operator->() const { return getPointer(); }
+ constexpr explicit operator bool() const { return hasValue(); }
+ constexpr bool hasValue() const { return Storage.hasValue(); }
+ constexpr const T *operator->() const { return getPointer(); }
T *operator->() { return getPointer(); }
- constexpr const T &operator*() const LLVM_LVALUE_FUNCTION {
- return getValue();
- }
+ constexpr const T &operator*() const LLVM_LVALUE_FUNCTION {
+ return getValue();
+ }
T &operator*() LLVM_LVALUE_FUNCTION { return getValue(); }
template <typename U>
@@ -330,157 +330,157 @@ public:
#endif
};
-template <class T> llvm::hash_code hash_value(const Optional<T> &O) {
- return O ? hash_combine(true, *O) : hash_value(false);
-}
-
+template <class T> llvm::hash_code hash_value(const Optional<T> &O) {
+ return O ? hash_combine(true, *O) : hash_value(false);
+}
+
template <typename T, typename U>
-constexpr bool operator==(const Optional<T> &X, const Optional<U> &Y) {
+constexpr bool operator==(const Optional<T> &X, const Optional<U> &Y) {
if (X && Y)
return *X == *Y;
return X.hasValue() == Y.hasValue();
}
template <typename T, typename U>
-constexpr bool operator!=(const Optional<T> &X, const Optional<U> &Y) {
+constexpr bool operator!=(const Optional<T> &X, const Optional<U> &Y) {
return !(X == Y);
}
template <typename T, typename U>
-constexpr bool operator<(const Optional<T> &X, const Optional<U> &Y) {
+constexpr bool operator<(const Optional<T> &X, const Optional<U> &Y) {
if (X && Y)
return *X < *Y;
return X.hasValue() < Y.hasValue();
}
template <typename T, typename U>
-constexpr bool operator<=(const Optional<T> &X, const Optional<U> &Y) {
+constexpr bool operator<=(const Optional<T> &X, const Optional<U> &Y) {
return !(Y < X);
}
template <typename T, typename U>
-constexpr bool operator>(const Optional<T> &X, const Optional<U> &Y) {
+constexpr bool operator>(const Optional<T> &X, const Optional<U> &Y) {
return Y < X;
}
template <typename T, typename U>
-constexpr bool operator>=(const Optional<T> &X, const Optional<U> &Y) {
+constexpr bool operator>=(const Optional<T> &X, const Optional<U> &Y) {
return !(X < Y);
}
-template <typename T>
-constexpr bool operator==(const Optional<T> &X, NoneType) {
+template <typename T>
+constexpr bool operator==(const Optional<T> &X, NoneType) {
return !X;
}
-template <typename T>
-constexpr bool operator==(NoneType, const Optional<T> &X) {
+template <typename T>
+constexpr bool operator==(NoneType, const Optional<T> &X) {
return X == None;
}
-template <typename T>
-constexpr bool operator!=(const Optional<T> &X, NoneType) {
+template <typename T>
+constexpr bool operator!=(const Optional<T> &X, NoneType) {
return !(X == None);
}
-template <typename T>
-constexpr bool operator!=(NoneType, const Optional<T> &X) {
+template <typename T>
+constexpr bool operator!=(NoneType, const Optional<T> &X) {
return X != None;
}
-template <typename T> constexpr bool operator<(const Optional<T> &X, NoneType) {
+template <typename T> constexpr bool operator<(const Optional<T> &X, NoneType) {
return false;
}
-template <typename T> constexpr bool operator<(NoneType, const Optional<T> &X) {
+template <typename T> constexpr bool operator<(NoneType, const Optional<T> &X) {
return X.hasValue();
}
-template <typename T>
-constexpr bool operator<=(const Optional<T> &X, NoneType) {
+template <typename T>
+constexpr bool operator<=(const Optional<T> &X, NoneType) {
return !(None < X);
}
-template <typename T>
-constexpr bool operator<=(NoneType, const Optional<T> &X) {
+template <typename T>
+constexpr bool operator<=(NoneType, const Optional<T> &X) {
return !(X < None);
}
-template <typename T> constexpr bool operator>(const Optional<T> &X, NoneType) {
+template <typename T> constexpr bool operator>(const Optional<T> &X, NoneType) {
return None < X;
}
-template <typename T> constexpr bool operator>(NoneType, const Optional<T> &X) {
+template <typename T> constexpr bool operator>(NoneType, const Optional<T> &X) {
return X < None;
}
-template <typename T>
-constexpr bool operator>=(const Optional<T> &X, NoneType) {
+template <typename T>
+constexpr bool operator>=(const Optional<T> &X, NoneType) {
return None <= X;
}
-template <typename T>
-constexpr bool operator>=(NoneType, const Optional<T> &X) {
+template <typename T>
+constexpr bool operator>=(NoneType, const Optional<T> &X) {
return X <= None;
}
-template <typename T>
-constexpr bool operator==(const Optional<T> &X, const T &Y) {
+template <typename T>
+constexpr bool operator==(const Optional<T> &X, const T &Y) {
return X && *X == Y;
}
-template <typename T>
-constexpr bool operator==(const T &X, const Optional<T> &Y) {
+template <typename T>
+constexpr bool operator==(const T &X, const Optional<T> &Y) {
return Y && X == *Y;
}
-template <typename T>
-constexpr bool operator!=(const Optional<T> &X, const T &Y) {
+template <typename T>
+constexpr bool operator!=(const Optional<T> &X, const T &Y) {
return !(X == Y);
}
-template <typename T>
-constexpr bool operator!=(const T &X, const Optional<T> &Y) {
+template <typename T>
+constexpr bool operator!=(const T &X, const Optional<T> &Y) {
return !(X == Y);
}
-template <typename T>
-constexpr bool operator<(const Optional<T> &X, const T &Y) {
+template <typename T>
+constexpr bool operator<(const Optional<T> &X, const T &Y) {
return !X || *X < Y;
}
-template <typename T>
-constexpr bool operator<(const T &X, const Optional<T> &Y) {
+template <typename T>
+constexpr bool operator<(const T &X, const Optional<T> &Y) {
return Y && X < *Y;
}
-template <typename T>
-constexpr bool operator<=(const Optional<T> &X, const T &Y) {
+template <typename T>
+constexpr bool operator<=(const Optional<T> &X, const T &Y) {
return !(Y < X);
}
-template <typename T>
-constexpr bool operator<=(const T &X, const Optional<T> &Y) {
+template <typename T>
+constexpr bool operator<=(const T &X, const Optional<T> &Y) {
return !(Y < X);
}
-template <typename T>
-constexpr bool operator>(const Optional<T> &X, const T &Y) {
+template <typename T>
+constexpr bool operator>(const Optional<T> &X, const T &Y) {
return Y < X;
}
-template <typename T>
-constexpr bool operator>(const T &X, const Optional<T> &Y) {
+template <typename T>
+constexpr bool operator>(const T &X, const Optional<T> &Y) {
return Y < X;
}
-template <typename T>
-constexpr bool operator>=(const Optional<T> &X, const T &Y) {
+template <typename T>
+constexpr bool operator>=(const Optional<T> &X, const T &Y) {
return !(X < Y);
}
-template <typename T>
-constexpr bool operator>=(const T &X, const Optional<T> &Y) {
+template <typename T>
+constexpr bool operator>=(const T &X, const Optional<T> &Y) {
return !(X < Y);
}
diff --git a/contrib/libs/llvm12/include/llvm/ADT/STLExtras.h b/contrib/libs/llvm12/include/llvm/ADT/STLExtras.h
index a6fa02e0f6..ba115875ce 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/STLExtras.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/STLExtras.h
@@ -200,15 +200,15 @@ public:
template <typename Callable>
function_ref(
Callable &&callable,
- // This is not the copy-constructor.
+ // This is not the copy-constructor.
std::enable_if_t<
!std::is_same<std::remove_cv_t<std::remove_reference_t<Callable>>,
- function_ref>::value> * = nullptr,
- // Functor must be callable and return a suitable type.
- std::enable_if_t<std::is_void<Ret>::value ||
- std::is_convertible<decltype(std::declval<Callable>()(
- std::declval<Params>()...)),
- Ret>::value> * = nullptr)
+ function_ref>::value> * = nullptr,
+ // Functor must be callable and return a suitable type.
+ std::enable_if_t<std::is_void<Ret>::value ||
+ std::is_convertible<decltype(std::declval<Callable>()(
+ std::declval<Params>()...)),
+ Ret>::value> * = nullptr)
: callback(callback_fn<typename std::remove_reference<Callable>::type>),
callable(reinterpret_cast<intptr_t>(&callable)) {}
@@ -279,7 +279,7 @@ template <typename ContainerTy> bool hasSingleElement(ContainerTy &&C) {
/// Return a range covering \p RangeOrContainer with the first N elements
/// excluded.
-template <typename T> auto drop_begin(T &&RangeOrContainer, size_t N = 1) {
+template <typename T> auto drop_begin(T &&RangeOrContainer, size_t N = 1) {
return make_range(std::next(adl_begin(RangeOrContainer), N),
adl_end(RangeOrContainer));
}
@@ -545,7 +545,7 @@ public:
early_inc_iterator_impl(WrappedIteratorT I) : BaseT(I) {}
using BaseT::operator*;
- decltype(*std::declval<WrappedIteratorT>()) operator*() {
+ decltype(*std::declval<WrappedIteratorT>()) operator*() {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
assert(!IsEarlyIncremented && "Cannot dereference twice!");
IsEarlyIncremented = true;
@@ -1250,15 +1250,15 @@ public:
}
};
-/// Given a container of pairs, return a range over the first elements.
-template <typename ContainerTy> auto make_first_range(ContainerTy &&c) {
- return llvm::map_range(
- std::forward<ContainerTy>(c),
- [](decltype((*std::begin(c))) elt) -> decltype((elt.first)) {
- return elt.first;
- });
-}
-
+/// Given a container of pairs, return a range over the first elements.
+template <typename ContainerTy> auto make_first_range(ContainerTy &&c) {
+ return llvm::map_range(
+ std::forward<ContainerTy>(c),
+ [](decltype((*std::begin(c))) elt) -> decltype((elt.first)) {
+ return elt.first;
+ });
+}
+
/// Given a container of pairs, return a range over the second elements.
template <typename ContainerTy> auto make_second_range(ContainerTy &&c) {
return llvm::map_range(
@@ -1435,7 +1435,7 @@ template <typename T>
// is trivially copyable.
using sort_trivially_copyable = conjunction<
std::is_pointer<T>,
- std::is_trivially_copyable<typename std::iterator_traits<T>::value_type>>;
+ std::is_trivially_copyable<typename std::iterator_traits<T>::value_type>>;
} // namespace detail
// Provide wrappers to std::sort which shuffle the elements before sorting
@@ -1484,19 +1484,19 @@ inline void sort(Container &&C, Compare Comp) {
/// which is only enabled when the operation is O(1).
template <typename R>
auto size(R &&Range,
- std::enable_if_t<
- std::is_base_of<std::random_access_iterator_tag,
- typename std::iterator_traits<decltype(
- Range.begin())>::iterator_category>::value,
- void> * = nullptr) {
+ std::enable_if_t<
+ std::is_base_of<std::random_access_iterator_tag,
+ typename std::iterator_traits<decltype(
+ Range.begin())>::iterator_category>::value,
+ void> * = nullptr) {
return std::distance(Range.begin(), Range.end());
}
/// Provide wrappers to std::for_each which take ranges instead of having to
/// pass begin/end explicitly.
-template <typename R, typename UnaryFunction>
-UnaryFunction for_each(R &&Range, UnaryFunction F) {
- return std::for_each(adl_begin(Range), adl_end(Range), F);
+template <typename R, typename UnaryFunction>
+UnaryFunction for_each(R &&Range, UnaryFunction F) {
+ return std::for_each(adl_begin(Range), adl_end(Range), F);
}
/// Provide wrappers to std::all_of which take ranges instead of having to pass
@@ -1557,13 +1557,13 @@ OutputIt copy(R &&Range, OutputIt Out) {
return std::copy(adl_begin(Range), adl_end(Range), Out);
}
-/// Provide wrappers to std::move which take ranges instead of having to
-/// pass begin/end explicitly.
-template <typename R, typename OutputIt>
-OutputIt move(R &&Range, OutputIt Out) {
- return std::move(adl_begin(Range), adl_end(Range), Out);
-}
-
+/// Provide wrappers to std::move which take ranges instead of having to
+/// pass begin/end explicitly.
+template <typename R, typename OutputIt>
+OutputIt move(R &&Range, OutputIt Out) {
+ return std::move(adl_begin(Range), adl_end(Range), Out);
+}
+
/// Wrapper function around std::find to detect if an element exists
/// in a container.
template <typename R, typename E>
@@ -1598,9 +1598,9 @@ auto count_if(R &&Range, UnaryPredicate P) {
/// Wrapper function around std::transform to apply a function to a range and
/// store the result elsewhere.
-template <typename R, typename OutputIt, typename UnaryFunction>
-OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F) {
- return std::transform(adl_begin(Range), adl_end(Range), d_first, F);
+template <typename R, typename OutputIt, typename UnaryFunction>
+OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F) {
+ return std::transform(adl_begin(Range), adl_end(Range), d_first, F);
}
/// Provide wrappers to std::partition which take ranges instead of having to
@@ -1675,22 +1675,22 @@ void erase_if(Container &C, UnaryPredicate P) {
C.erase(remove_if(C, P), C.end());
}
-/// Wrapper function to remove a value from a container:
-///
-/// C.erase(remove(C.begin(), C.end(), V), C.end());
-template <typename Container, typename ValueType>
-void erase_value(Container &C, ValueType V) {
- C.erase(std::remove(C.begin(), C.end(), V), C.end());
-}
-
-/// Wrapper function to append a range to a container.
-///
-/// C.insert(C.end(), R.begin(), R.end());
-template <typename Container, typename Range>
-inline void append_range(Container &C, Range &&R) {
- C.insert(C.end(), R.begin(), R.end());
-}
-
+/// Wrapper function to remove a value from a container:
+///
+/// C.erase(remove(C.begin(), C.end(), V), C.end());
+template <typename Container, typename ValueType>
+void erase_value(Container &C, ValueType V) {
+ C.erase(std::remove(C.begin(), C.end(), V), C.end());
+}
+
+/// Wrapper function to append a range to a container.
+///
+/// C.insert(C.end(), R.begin(), R.end());
+template <typename Container, typename Range>
+inline void append_range(Container &C, Range &&R) {
+ C.insert(C.end(), R.begin(), R.end());
+}
+
/// Given a sequence container Cont, replace the range [ContIt, ContEnd) with
/// the range [ValIt, ValEnd) (which is not from the same container).
template<typename Container, typename RandomAccessIterator>
@@ -1948,16 +1948,16 @@ decltype(auto) apply_tuple(F &&f, Tuple &&t) {
/// Return true if the sequence [Begin, End) has exactly N items. Runs in O(N)
/// time. Not meant for use with random-access iterators.
/// Can optionally take a predicate to filter lazily some items.
-template <typename IterTy,
- typename Pred = bool (*)(const decltype(*std::declval<IterTy>()) &)>
+template <typename IterTy,
+ typename Pred = bool (*)(const decltype(*std::declval<IterTy>()) &)>
bool hasNItems(
IterTy &&Begin, IterTy &&End, unsigned N,
Pred &&ShouldBeCounted =
[](const decltype(*std::declval<IterTy>()) &) { return true; },
std::enable_if_t<
- !std::is_base_of<std::random_access_iterator_tag,
- typename std::iterator_traits<std::remove_reference_t<
- decltype(Begin)>>::iterator_category>::value,
+ !std::is_base_of<std::random_access_iterator_tag,
+ typename std::iterator_traits<std::remove_reference_t<
+ decltype(Begin)>>::iterator_category>::value,
void> * = nullptr) {
for (; N; ++Begin) {
if (Begin == End)
@@ -1973,16 +1973,16 @@ bool hasNItems(
/// Return true if the sequence [Begin, End) has N or more items. Runs in O(N)
/// time. Not meant for use with random-access iterators.
/// Can optionally take a predicate to lazily filter some items.
-template <typename IterTy,
- typename Pred = bool (*)(const decltype(*std::declval<IterTy>()) &)>
+template <typename IterTy,
+ typename Pred = bool (*)(const decltype(*std::declval<IterTy>()) &)>
bool hasNItemsOrMore(
IterTy &&Begin, IterTy &&End, unsigned N,
Pred &&ShouldBeCounted =
[](const decltype(*std::declval<IterTy>()) &) { return true; },
std::enable_if_t<
- !std::is_base_of<std::random_access_iterator_tag,
- typename std::iterator_traits<std::remove_reference_t<
- decltype(Begin)>>::iterator_category>::value,
+ !std::is_base_of<std::random_access_iterator_tag,
+ typename std::iterator_traits<std::remove_reference_t<
+ decltype(Begin)>>::iterator_category>::value,
void> * = nullptr) {
for (; N; ++Begin) {
if (Begin == End)
diff --git a/contrib/libs/llvm12/include/llvm/ADT/Sequence.h b/contrib/libs/llvm12/include/llvm/ADT/Sequence.h
index 93f7a10888..ec540fb18d 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/Sequence.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/Sequence.h
@@ -49,10 +49,10 @@ public:
value_sequence_iterator(const value_sequence_iterator &) = default;
value_sequence_iterator(value_sequence_iterator &&Arg)
: Value(std::move(Arg.Value)) {}
- value_sequence_iterator &operator=(const value_sequence_iterator &Arg) {
- Value = Arg.Value;
- return *this;
- }
+ value_sequence_iterator &operator=(const value_sequence_iterator &Arg) {
+ Value = Arg.Value;
+ return *this;
+ }
template <typename U, typename Enabler = decltype(ValueT(std::declval<U>()))>
value_sequence_iterator(U &&Value) : Value(std::forward<U>(Value)) {}
diff --git a/contrib/libs/llvm12/include/llvm/ADT/SetVector.h b/contrib/libs/llvm12/include/llvm/ADT/SetVector.h
index 77210aaf7b..5dc64ecb31 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/SetVector.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/SetVector.h
@@ -212,11 +212,11 @@ public:
return true;
}
- /// Check if the SetVector contains the given key.
- bool contains(const key_type &key) const {
- return set_.find(key) != set_.end();
- }
-
+ /// Check if the SetVector contains the given key.
+ bool contains(const key_type &key) const {
+ return set_.find(key) != set_.end();
+ }
+
/// 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 {
diff --git a/contrib/libs/llvm12/include/llvm/ADT/SmallSet.h b/contrib/libs/llvm12/include/llvm/ADT/SmallSet.h
index 1601146115..6b0f3efb09 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/SmallSet.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/SmallSet.h
@@ -239,13 +239,13 @@ public:
return {Set.end()};
}
- /// Check if the SmallSet contains the given element.
- bool contains(const T &V) const {
- if (isSmall())
- return vfind(V) != Vector.end();
- return Set.find(V) != Set.end();
- }
-
+ /// Check if the SmallSet contains the given element.
+ bool contains(const T &V) const {
+ if (isSmall())
+ return vfind(V) != Vector.end();
+ return Set.find(V) != Set.end();
+ }
+
private:
bool isSmall() const { return Set.empty(); }
diff --git a/contrib/libs/llvm12/include/llvm/ADT/SmallString.h b/contrib/libs/llvm12/include/llvm/ADT/SmallString.h
index 0a4b60df10..889e6c8f78 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/SmallString.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/SmallString.h
@@ -37,12 +37,12 @@ public:
/// Initialize from a StringRef.
SmallString(StringRef S) : SmallVector<char, InternalLen>(S.begin(), S.end()) {}
- /// Initialize by concatenating a list of StringRefs.
- SmallString(std::initializer_list<StringRef> Refs)
- : SmallVector<char, InternalLen>() {
- this->append(Refs);
- }
-
+ /// Initialize by concatenating a list of StringRefs.
+ SmallString(std::initializer_list<StringRef> Refs)
+ : SmallVector<char, InternalLen>() {
+ this->append(Refs);
+ }
+
/// Initialize with a range.
template<typename ItTy>
SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {}
@@ -51,42 +51,42 @@ public:
/// @name String Assignment
/// @{
- using SmallVector<char, InternalLen>::assign;
+ using SmallVector<char, InternalLen>::assign;
/// Assign from a StringRef.
void assign(StringRef RHS) {
- SmallVectorImpl<char>::assign(RHS.begin(), RHS.end());
+ SmallVectorImpl<char>::assign(RHS.begin(), RHS.end());
}
- /// Assign from a list of StringRefs.
- void assign(std::initializer_list<StringRef> Refs) {
+ /// Assign from a list of StringRefs.
+ void assign(std::initializer_list<StringRef> Refs) {
this->clear();
- append(Refs);
+ append(Refs);
}
/// @}
/// @name String Concatenation
/// @{
- using SmallVector<char, InternalLen>::append;
+ using SmallVector<char, InternalLen>::append;
/// Append from a StringRef.
void append(StringRef RHS) {
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
- /// Append from a list of StringRefs.
- void append(std::initializer_list<StringRef> Refs) {
- size_t SizeNeeded = this->size();
- for (const StringRef &Ref : Refs)
- SizeNeeded += Ref.size();
- this->reserve(SizeNeeded);
- auto CurEnd = this->end();
- for (const StringRef &Ref : Refs) {
- this->uninitialized_copy(Ref.begin(), Ref.end(), CurEnd);
- CurEnd += Ref.size();
- }
- this->set_size(SizeNeeded);
+ /// Append from a list of StringRefs.
+ void append(std::initializer_list<StringRef> Refs) {
+ size_t SizeNeeded = this->size();
+ for (const StringRef &Ref : Refs)
+ SizeNeeded += Ref.size();
+ this->reserve(SizeNeeded);
+ auto CurEnd = this->end();
+ for (const StringRef &Ref : Refs) {
+ this->uninitialized_copy(Ref.begin(), Ref.end(), CurEnd);
+ CurEnd += Ref.size();
+ }
+ this->set_size(SizeNeeded);
}
/// @}
@@ -280,9 +280,9 @@ public:
}
// Extra operators.
- SmallString &operator=(StringRef RHS) {
- this->assign(RHS);
- return *this;
+ SmallString &operator=(StringRef RHS) {
+ this->assign(RHS);
+ return *this;
}
SmallString &operator+=(StringRef RHS) {
diff --git a/contrib/libs/llvm12/include/llvm/ADT/SmallVector.h b/contrib/libs/llvm12/include/llvm/ADT/SmallVector.h
index 636a3f872b..1794e51433 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/SmallVector.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/SmallVector.h
@@ -63,15 +63,15 @@ protected:
SmallVectorBase(void *FirstEl, size_t TotalCapacity)
: BeginX(FirstEl), Capacity(TotalCapacity) {}
- /// This is a helper for \a grow() that's out of line to reduce code
- /// duplication. This function will report a fatal error if it can't grow at
- /// least to \p MinSize.
- void *mallocForGrow(size_t MinSize, size_t TSize, size_t &NewCapacity);
-
+ /// This is a helper for \a grow() that's out of line to reduce code
+ /// duplication. This function will report a fatal error if it can't grow at
+ /// least to \p MinSize.
+ void *mallocForGrow(size_t MinSize, size_t TSize, size_t &NewCapacity);
+
/// This is an implementation of the grow() method which only works
/// on POD-like data types and is out of line to reduce code duplication.
/// This function will report a fatal error if it cannot increase capacity.
- void grow_pod(void *FirstEl, size_t MinSize, size_t TSize);
+ void grow_pod(void *FirstEl, size_t MinSize, size_t TSize);
public:
size_t size() const { return Size; }
@@ -101,9 +101,9 @@ using SmallVectorSizeType =
/// Figure out the offset of the first element.
template <class T, typename = void> struct SmallVectorAlignmentAndSize {
- alignas(SmallVectorBase<SmallVectorSizeType<T>>) char Base[sizeof(
- SmallVectorBase<SmallVectorSizeType<T>>)];
- alignas(T) char FirstEl[sizeof(T)];
+ alignas(SmallVectorBase<SmallVectorSizeType<T>>) char Base[sizeof(
+ SmallVectorBase<SmallVectorSizeType<T>>)];
+ alignas(T) char FirstEl[sizeof(T)];
};
/// This is the part of SmallVectorTemplateBase which does not depend on whether
@@ -127,8 +127,8 @@ class SmallVectorTemplateCommon
protected:
SmallVectorTemplateCommon(size_t Size) : Base(getFirstEl(), Size) {}
- void grow_pod(size_t MinSize, size_t TSize) {
- Base::grow_pod(getFirstEl(), MinSize, TSize);
+ void grow_pod(size_t MinSize, size_t TSize) {
+ Base::grow_pod(getFirstEl(), MinSize, TSize);
}
/// Return true if this is a smallvector which has not had dynamic
@@ -141,102 +141,102 @@ protected:
this->Size = this->Capacity = 0; // FIXME: Setting Capacity to 0 is suspect.
}
- /// Return true if V is an internal reference to the given range.
- bool isReferenceToRange(const void *V, const void *First, const void *Last) const {
- // Use std::less to avoid UB.
- std::less<> LessThan;
- return !LessThan(V, First) && LessThan(V, Last);
- }
-
- /// Return true if V is an internal reference to this vector.
- bool isReferenceToStorage(const void *V) const {
- return isReferenceToRange(V, this->begin(), this->end());
- }
-
- /// Return true if First and Last form a valid (possibly empty) range in this
- /// vector's storage.
- bool isRangeInStorage(const void *First, const void *Last) const {
- // Use std::less to avoid UB.
- std::less<> LessThan;
- return !LessThan(First, this->begin()) && !LessThan(Last, First) &&
- !LessThan(this->end(), Last);
- }
-
- /// Return true unless Elt will be invalidated by resizing the vector to
- /// NewSize.
- bool isSafeToReferenceAfterResize(const void *Elt, size_t NewSize) {
- // Past the end.
- if (LLVM_LIKELY(!isReferenceToStorage(Elt)))
- return true;
-
- // Return false if Elt will be destroyed by shrinking.
- if (NewSize <= this->size())
- return Elt < this->begin() + NewSize;
-
- // Return false if we need to grow.
- return NewSize <= this->capacity();
- }
-
- /// Check whether Elt will be invalidated by resizing the vector to NewSize.
- void assertSafeToReferenceAfterResize(const void *Elt, size_t NewSize) {
- assert(isSafeToReferenceAfterResize(Elt, NewSize) &&
- "Attempting to reference an element of the vector in an operation "
- "that invalidates it");
- }
-
- /// Check whether Elt will be invalidated by increasing the size of the
- /// vector by N.
- void assertSafeToAdd(const void *Elt, size_t N = 1) {
- this->assertSafeToReferenceAfterResize(Elt, this->size() + N);
- }
-
- /// Check whether any part of the range will be invalidated by clearing.
- void assertSafeToReferenceAfterClear(const T *From, const T *To) {
- if (From == To)
- return;
- this->assertSafeToReferenceAfterResize(From, 0);
- this->assertSafeToReferenceAfterResize(To - 1, 0);
- }
- template <
- class ItTy,
- std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>, T *>::value,
- bool> = false>
- void assertSafeToReferenceAfterClear(ItTy, ItTy) {}
-
- /// Check whether any part of the range will be invalidated by growing.
- void assertSafeToAddRange(const T *From, const T *To) {
- if (From == To)
- return;
- this->assertSafeToAdd(From, To - From);
- this->assertSafeToAdd(To - 1, To - From);
- }
- template <
- class ItTy,
- std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>, T *>::value,
- bool> = false>
- void assertSafeToAddRange(ItTy, ItTy) {}
-
- /// Reserve enough space to add one element, and return the updated element
- /// pointer in case it was a reference to the storage.
- template <class U>
- static const T *reserveForParamAndGetAddressImpl(U *This, const T &Elt,
- size_t N) {
- size_t NewSize = This->size() + N;
- if (LLVM_LIKELY(NewSize <= This->capacity()))
- return &Elt;
-
- bool ReferencesStorage = false;
- int64_t Index = -1;
- if (!U::TakesParamByValue) {
- if (LLVM_UNLIKELY(This->isReferenceToStorage(&Elt))) {
- ReferencesStorage = true;
- Index = &Elt - This->begin();
- }
- }
- This->grow(NewSize);
- return ReferencesStorage ? This->begin() + Index : &Elt;
- }
-
+ /// Return true if V is an internal reference to the given range.
+ bool isReferenceToRange(const void *V, const void *First, const void *Last) const {
+ // Use std::less to avoid UB.
+ std::less<> LessThan;
+ return !LessThan(V, First) && LessThan(V, Last);
+ }
+
+ /// Return true if V is an internal reference to this vector.
+ bool isReferenceToStorage(const void *V) const {
+ return isReferenceToRange(V, this->begin(), this->end());
+ }
+
+ /// Return true if First and Last form a valid (possibly empty) range in this
+ /// vector's storage.
+ bool isRangeInStorage(const void *First, const void *Last) const {
+ // Use std::less to avoid UB.
+ std::less<> LessThan;
+ return !LessThan(First, this->begin()) && !LessThan(Last, First) &&
+ !LessThan(this->end(), Last);
+ }
+
+ /// Return true unless Elt will be invalidated by resizing the vector to
+ /// NewSize.
+ bool isSafeToReferenceAfterResize(const void *Elt, size_t NewSize) {
+ // Past the end.
+ if (LLVM_LIKELY(!isReferenceToStorage(Elt)))
+ return true;
+
+ // Return false if Elt will be destroyed by shrinking.
+ if (NewSize <= this->size())
+ return Elt < this->begin() + NewSize;
+
+ // Return false if we need to grow.
+ return NewSize <= this->capacity();
+ }
+
+ /// Check whether Elt will be invalidated by resizing the vector to NewSize.
+ void assertSafeToReferenceAfterResize(const void *Elt, size_t NewSize) {
+ assert(isSafeToReferenceAfterResize(Elt, NewSize) &&
+ "Attempting to reference an element of the vector in an operation "
+ "that invalidates it");
+ }
+
+ /// Check whether Elt will be invalidated by increasing the size of the
+ /// vector by N.
+ void assertSafeToAdd(const void *Elt, size_t N = 1) {
+ this->assertSafeToReferenceAfterResize(Elt, this->size() + N);
+ }
+
+ /// Check whether any part of the range will be invalidated by clearing.
+ void assertSafeToReferenceAfterClear(const T *From, const T *To) {
+ if (From == To)
+ return;
+ this->assertSafeToReferenceAfterResize(From, 0);
+ this->assertSafeToReferenceAfterResize(To - 1, 0);
+ }
+ template <
+ class ItTy,
+ std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>, T *>::value,
+ bool> = false>
+ void assertSafeToReferenceAfterClear(ItTy, ItTy) {}
+
+ /// Check whether any part of the range will be invalidated by growing.
+ void assertSafeToAddRange(const T *From, const T *To) {
+ if (From == To)
+ return;
+ this->assertSafeToAdd(From, To - From);
+ this->assertSafeToAdd(To - 1, To - From);
+ }
+ template <
+ class ItTy,
+ std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>, T *>::value,
+ bool> = false>
+ void assertSafeToAddRange(ItTy, ItTy) {}
+
+ /// Reserve enough space to add one element, and return the updated element
+ /// pointer in case it was a reference to the storage.
+ template <class U>
+ static const T *reserveForParamAndGetAddressImpl(U *This, const T &Elt,
+ size_t N) {
+ size_t NewSize = This->size() + N;
+ if (LLVM_LIKELY(NewSize <= This->capacity()))
+ return &Elt;
+
+ bool ReferencesStorage = false;
+ int64_t Index = -1;
+ if (!U::TakesParamByValue) {
+ if (LLVM_UNLIKELY(This->isReferenceToStorage(&Elt))) {
+ ReferencesStorage = true;
+ Index = &Elt - This->begin();
+ }
+ }
+ This->grow(NewSize);
+ return ReferencesStorage ? This->begin() + Index : &Elt;
+ }
+
public:
using size_type = size_t;
using difference_type = ptrdiff_t;
@@ -320,12 +320,12 @@ template <typename T, bool = (is_trivially_copy_constructible<T>::value) &&
(is_trivially_move_constructible<T>::value) &&
std::is_trivially_destructible<T>::value>
class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
- friend class SmallVectorTemplateCommon<T>;
-
+ friend class SmallVectorTemplateCommon<T>;
+
protected:
- static constexpr bool TakesParamByValue = false;
- using ValueParamT = const T &;
-
+ static constexpr bool TakesParamByValue = false;
+ using ValueParamT = const T &;
+
SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
static void destroy_range(T *S, T *E) {
@@ -355,68 +355,68 @@ protected:
/// element, or MinSize more elements if specified.
void grow(size_t MinSize = 0);
- /// Create a new allocation big enough for \p MinSize and pass back its size
- /// in \p NewCapacity. This is the first section of \a grow().
- T *mallocForGrow(size_t MinSize, size_t &NewCapacity) {
- return static_cast<T *>(
- SmallVectorBase<SmallVectorSizeType<T>>::mallocForGrow(
- MinSize, sizeof(T), NewCapacity));
- }
-
- /// Move existing elements over to the new allocation \p NewElts, the middle
- /// section of \a grow().
- void moveElementsForGrow(T *NewElts);
-
- /// Transfer ownership of the allocation, finishing up \a grow().
- void takeAllocationForGrow(T *NewElts, size_t NewCapacity);
-
- /// Reserve enough space to add one element, and return the updated element
- /// pointer in case it was a reference to the storage.
- const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) {
- return this->reserveForParamAndGetAddressImpl(this, Elt, N);
- }
-
- /// Reserve enough space to add one element, and return the updated element
- /// pointer in case it was a reference to the storage.
- T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) {
- return const_cast<T *>(
- this->reserveForParamAndGetAddressImpl(this, Elt, N));
- }
-
- static T &&forward_value_param(T &&V) { return std::move(V); }
- static const T &forward_value_param(const T &V) { return V; }
-
- void growAndAssign(size_t NumElts, const T &Elt) {
- // Grow manually in case Elt is an internal reference.
- size_t NewCapacity;
- T *NewElts = mallocForGrow(NumElts, NewCapacity);
- std::uninitialized_fill_n(NewElts, NumElts, Elt);
- this->destroy_range(this->begin(), this->end());
- takeAllocationForGrow(NewElts, NewCapacity);
- this->set_size(NumElts);
- }
-
- template <typename... ArgTypes> T &growAndEmplaceBack(ArgTypes &&... Args) {
- // Grow manually in case one of Args is an internal reference.
- size_t NewCapacity;
- T *NewElts = mallocForGrow(0, NewCapacity);
- ::new ((void *)(NewElts + this->size())) T(std::forward<ArgTypes>(Args)...);
- moveElementsForGrow(NewElts);
- takeAllocationForGrow(NewElts, NewCapacity);
- this->set_size(this->size() + 1);
- return this->back();
- }
-
+ /// Create a new allocation big enough for \p MinSize and pass back its size
+ /// in \p NewCapacity. This is the first section of \a grow().
+ T *mallocForGrow(size_t MinSize, size_t &NewCapacity) {
+ return static_cast<T *>(
+ SmallVectorBase<SmallVectorSizeType<T>>::mallocForGrow(
+ MinSize, sizeof(T), NewCapacity));
+ }
+
+ /// Move existing elements over to the new allocation \p NewElts, the middle
+ /// section of \a grow().
+ void moveElementsForGrow(T *NewElts);
+
+ /// Transfer ownership of the allocation, finishing up \a grow().
+ void takeAllocationForGrow(T *NewElts, size_t NewCapacity);
+
+ /// Reserve enough space to add one element, and return the updated element
+ /// pointer in case it was a reference to the storage.
+ const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) {
+ return this->reserveForParamAndGetAddressImpl(this, Elt, N);
+ }
+
+ /// Reserve enough space to add one element, and return the updated element
+ /// pointer in case it was a reference to the storage.
+ T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) {
+ return const_cast<T *>(
+ this->reserveForParamAndGetAddressImpl(this, Elt, N));
+ }
+
+ static T &&forward_value_param(T &&V) { return std::move(V); }
+ static const T &forward_value_param(const T &V) { return V; }
+
+ void growAndAssign(size_t NumElts, const T &Elt) {
+ // Grow manually in case Elt is an internal reference.
+ size_t NewCapacity;
+ T *NewElts = mallocForGrow(NumElts, NewCapacity);
+ std::uninitialized_fill_n(NewElts, NumElts, Elt);
+ this->destroy_range(this->begin(), this->end());
+ takeAllocationForGrow(NewElts, NewCapacity);
+ this->set_size(NumElts);
+ }
+
+ template <typename... ArgTypes> T &growAndEmplaceBack(ArgTypes &&... Args) {
+ // Grow manually in case one of Args is an internal reference.
+ size_t NewCapacity;
+ T *NewElts = mallocForGrow(0, NewCapacity);
+ ::new ((void *)(NewElts + this->size())) T(std::forward<ArgTypes>(Args)...);
+ moveElementsForGrow(NewElts);
+ takeAllocationForGrow(NewElts, NewCapacity);
+ this->set_size(this->size() + 1);
+ return this->back();
+ }
+
public:
void push_back(const T &Elt) {
- const T *EltPtr = reserveForParamAndGetAddress(Elt);
- ::new ((void *)this->end()) T(*EltPtr);
+ const T *EltPtr = reserveForParamAndGetAddress(Elt);
+ ::new ((void *)this->end()) T(*EltPtr);
this->set_size(this->size() + 1);
}
void push_back(T &&Elt) {
- T *EltPtr = reserveForParamAndGetAddress(Elt);
- ::new ((void *)this->end()) T(::std::move(*EltPtr));
+ T *EltPtr = reserveForParamAndGetAddress(Elt);
+ ::new ((void *)this->end()) T(::std::move(*EltPtr));
this->set_size(this->size() + 1);
}
@@ -429,27 +429,27 @@ public:
// Define this out-of-line to dissuade the C++ compiler from inlining it.
template <typename T, bool TriviallyCopyable>
void SmallVectorTemplateBase<T, TriviallyCopyable>::grow(size_t MinSize) {
- size_t NewCapacity;
- T *NewElts = mallocForGrow(MinSize, NewCapacity);
- moveElementsForGrow(NewElts);
- takeAllocationForGrow(NewElts, NewCapacity);
-}
-
-// Define this out-of-line to dissuade the C++ compiler from inlining it.
-template <typename T, bool TriviallyCopyable>
-void SmallVectorTemplateBase<T, TriviallyCopyable>::moveElementsForGrow(
- T *NewElts) {
+ size_t NewCapacity;
+ T *NewElts = mallocForGrow(MinSize, NewCapacity);
+ moveElementsForGrow(NewElts);
+ takeAllocationForGrow(NewElts, NewCapacity);
+}
+
+// Define this out-of-line to dissuade the C++ compiler from inlining it.
+template <typename T, bool TriviallyCopyable>
+void SmallVectorTemplateBase<T, TriviallyCopyable>::moveElementsForGrow(
+ T *NewElts) {
// Move the elements over.
this->uninitialized_move(this->begin(), this->end(), NewElts);
// Destroy the original elements.
destroy_range(this->begin(), this->end());
-}
+}
-// Define this out-of-line to dissuade the C++ compiler from inlining it.
-template <typename T, bool TriviallyCopyable>
-void SmallVectorTemplateBase<T, TriviallyCopyable>::takeAllocationForGrow(
- T *NewElts, size_t NewCapacity) {
+// Define this out-of-line to dissuade the C++ compiler from inlining it.
+template <typename T, bool TriviallyCopyable>
+void SmallVectorTemplateBase<T, TriviallyCopyable>::takeAllocationForGrow(
+ T *NewElts, size_t NewCapacity) {
// If this wasn't grown from the inline copy, deallocate the old space.
if (!this->isSmall())
free(this->begin());
@@ -464,18 +464,18 @@ void SmallVectorTemplateBase<T, TriviallyCopyable>::takeAllocationForGrow(
/// skipping destruction.
template <typename T>
class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> {
- friend class SmallVectorTemplateCommon<T>;
-
+ friend class SmallVectorTemplateCommon<T>;
+
protected:
- /// True if it's cheap enough to take parameters by value. Doing so avoids
- /// overhead related to mitigations for reference invalidation.
- static constexpr bool TakesParamByValue = sizeof(T) <= 2 * sizeof(void *);
-
- /// Either const T& or T, depending on whether it's cheap enough to take
- /// parameters by value.
- using ValueParamT =
- typename std::conditional<TakesParamByValue, T, const T &>::type;
-
+ /// True if it's cheap enough to take parameters by value. Doing so avoids
+ /// overhead related to mitigations for reference invalidation.
+ static constexpr bool TakesParamByValue = sizeof(T) <= 2 * sizeof(void *);
+
+ /// Either const T& or T, depending on whether it's cheap enough to take
+ /// parameters by value.
+ using ValueParamT =
+ typename std::conditional<TakesParamByValue, T, const T &>::type;
+
SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
// No need to do a destroy loop for POD's.
@@ -516,43 +516,43 @@ protected:
/// least one more element or MinSize if specified.
void grow(size_t MinSize = 0) { this->grow_pod(MinSize, sizeof(T)); }
- /// Reserve enough space to add one element, and return the updated element
- /// pointer in case it was a reference to the storage.
- const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) {
- return this->reserveForParamAndGetAddressImpl(this, Elt, N);
- }
-
- /// Reserve enough space to add one element, and return the updated element
- /// pointer in case it was a reference to the storage.
- T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) {
- return const_cast<T *>(
- this->reserveForParamAndGetAddressImpl(this, Elt, N));
- }
-
- /// Copy \p V or return a reference, depending on \a ValueParamT.
- static ValueParamT forward_value_param(ValueParamT V) { return V; }
-
- void growAndAssign(size_t NumElts, T Elt) {
- // Elt has been copied in case it's an internal reference, side-stepping
- // reference invalidation problems without losing the realloc optimization.
- this->set_size(0);
- this->grow(NumElts);
- std::uninitialized_fill_n(this->begin(), NumElts, Elt);
- this->set_size(NumElts);
- }
-
- template <typename... ArgTypes> T &growAndEmplaceBack(ArgTypes &&... Args) {
- // Use push_back with a copy in case Args has an internal reference,
- // side-stepping reference invalidation problems without losing the realloc
- // optimization.
- push_back(T(std::forward<ArgTypes>(Args)...));
- return this->back();
- }
-
+ /// Reserve enough space to add one element, and return the updated element
+ /// pointer in case it was a reference to the storage.
+ const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) {
+ return this->reserveForParamAndGetAddressImpl(this, Elt, N);
+ }
+
+ /// Reserve enough space to add one element, and return the updated element
+ /// pointer in case it was a reference to the storage.
+ T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) {
+ return const_cast<T *>(
+ this->reserveForParamAndGetAddressImpl(this, Elt, N));
+ }
+
+ /// Copy \p V or return a reference, depending on \a ValueParamT.
+ static ValueParamT forward_value_param(ValueParamT V) { return V; }
+
+ void growAndAssign(size_t NumElts, T Elt) {
+ // Elt has been copied in case it's an internal reference, side-stepping
+ // reference invalidation problems without losing the realloc optimization.
+ this->set_size(0);
+ this->grow(NumElts);
+ std::uninitialized_fill_n(this->begin(), NumElts, Elt);
+ this->set_size(NumElts);
+ }
+
+ template <typename... ArgTypes> T &growAndEmplaceBack(ArgTypes &&... Args) {
+ // Use push_back with a copy in case Args has an internal reference,
+ // side-stepping reference invalidation problems without losing the realloc
+ // optimization.
+ push_back(T(std::forward<ArgTypes>(Args)...));
+ return this->back();
+ }
+
public:
- void push_back(ValueParamT Elt) {
- const T *EltPtr = reserveForParamAndGetAddress(Elt);
- memcpy(reinterpret_cast<void *>(this->end()), EltPtr, sizeof(T));
+ void push_back(ValueParamT Elt) {
+ const T *EltPtr = reserveForParamAndGetAddress(Elt);
+ memcpy(reinterpret_cast<void *>(this->end()), EltPtr, sizeof(T));
this->set_size(this->size() + 1);
}
@@ -572,9 +572,9 @@ public:
using size_type = typename SuperClass::size_type;
protected:
- using SmallVectorTemplateBase<T>::TakesParamByValue;
- using ValueParamT = typename SuperClass::ValueParamT;
-
+ using SmallVectorTemplateBase<T>::TakesParamByValue;
+ using ValueParamT = typename SuperClass::ValueParamT;
+
// Default ctor - Initialize to empty.
explicit SmallVectorImpl(unsigned N)
: SmallVectorTemplateBase<T>(N) {}
@@ -594,38 +594,38 @@ public:
this->Size = 0;
}
-private:
- template <bool ForOverwrite> void resizeImpl(size_type N) {
+private:
+ template <bool ForOverwrite> void resizeImpl(size_type N) {
if (N < this->size()) {
- this->pop_back_n(this->size() - N);
+ this->pop_back_n(this->size() - N);
} else if (N > this->size()) {
- this->reserve(N);
+ this->reserve(N);
for (auto I = this->end(), E = this->begin() + N; I != E; ++I)
- if (ForOverwrite)
- new (&*I) T;
- else
- new (&*I) T();
+ if (ForOverwrite)
+ new (&*I) T;
+ else
+ new (&*I) T();
this->set_size(N);
}
}
-public:
- void resize(size_type N) { resizeImpl<false>(N); }
-
- /// Like resize, but \ref T is POD, the new values won't be initialized.
- void resize_for_overwrite(size_type N) { resizeImpl<true>(N); }
-
- void resize(size_type N, ValueParamT NV) {
- if (N == this->size())
- return;
-
+public:
+ void resize(size_type N) { resizeImpl<false>(N); }
+
+ /// Like resize, but \ref T is POD, the new values won't be initialized.
+ void resize_for_overwrite(size_type N) { resizeImpl<true>(N); }
+
+ void resize(size_type N, ValueParamT NV) {
+ if (N == this->size())
+ return;
+
if (N < this->size()) {
- this->pop_back_n(this->size() - N);
- return;
+ this->pop_back_n(this->size() - N);
+ return;
}
-
- // N > this->size(). Defer to append.
- this->append(N - this->size(), NV);
+
+ // N > this->size(). Defer to append.
+ this->append(N - this->size(), NV);
}
void reserve(size_type N) {
@@ -633,12 +633,12 @@ public:
this->grow(N);
}
- void pop_back_n(size_type NumItems) {
- assert(this->size() >= NumItems);
- this->destroy_range(this->end() - NumItems, this->end());
- this->set_size(this->size() - NumItems);
- }
-
+ void pop_back_n(size_type NumItems) {
+ assert(this->size() >= NumItems);
+ this->destroy_range(this->end() - NumItems, this->end());
+ this->set_size(this->size() - NumItems);
+ }
+
LLVM_NODISCARD T pop_back_val() {
T Result = ::std::move(this->back());
this->pop_back();
@@ -653,17 +653,17 @@ public:
typename std::iterator_traits<in_iter>::iterator_category,
std::input_iterator_tag>::value>>
void append(in_iter in_start, in_iter in_end) {
- this->assertSafeToAddRange(in_start, in_end);
+ this->assertSafeToAddRange(in_start, in_end);
size_type NumInputs = std::distance(in_start, in_end);
- this->reserve(this->size() + NumInputs);
+ this->reserve(this->size() + NumInputs);
this->uninitialized_copy(in_start, in_end, this->end());
this->set_size(this->size() + NumInputs);
}
/// Append \p NumInputs copies of \p Elt to the end.
- void append(size_type NumInputs, ValueParamT Elt) {
- const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumInputs);
- std::uninitialized_fill_n(this->end(), NumInputs, *EltPtr);
+ void append(size_type NumInputs, ValueParamT Elt) {
+ const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumInputs);
+ std::uninitialized_fill_n(this->end(), NumInputs, *EltPtr);
this->set_size(this->size() + NumInputs);
}
@@ -671,33 +671,33 @@ public:
append(IL.begin(), IL.end());
}
- void append(const SmallVectorImpl &RHS) { append(RHS.begin(), RHS.end()); }
-
- void assign(size_type NumElts, ValueParamT Elt) {
- // Note that Elt could be an internal reference.
- if (NumElts > this->capacity()) {
- this->growAndAssign(NumElts, Elt);
- return;
- }
-
- // Assign over existing elements.
- std::fill_n(this->begin(), std::min(NumElts, this->size()), Elt);
- if (NumElts > this->size())
- std::uninitialized_fill_n(this->end(), NumElts - this->size(), Elt);
- else if (NumElts < this->size())
- this->destroy_range(this->begin() + NumElts, this->end());
+ void append(const SmallVectorImpl &RHS) { append(RHS.begin(), RHS.end()); }
+
+ void assign(size_type NumElts, ValueParamT Elt) {
+ // Note that Elt could be an internal reference.
+ if (NumElts > this->capacity()) {
+ this->growAndAssign(NumElts, Elt);
+ return;
+ }
+
+ // Assign over existing elements.
+ std::fill_n(this->begin(), std::min(NumElts, this->size()), Elt);
+ if (NumElts > this->size())
+ std::uninitialized_fill_n(this->end(), NumElts - this->size(), Elt);
+ else if (NumElts < this->size())
+ this->destroy_range(this->begin() + NumElts, this->end());
this->set_size(NumElts);
}
- // FIXME: Consider assigning over existing elements, rather than clearing &
- // re-initializing them - for all assign(...) variants.
-
+ // FIXME: Consider assigning over existing elements, rather than clearing &
+ // re-initializing them - for all assign(...) variants.
+
template <typename in_iter,
typename = std::enable_if_t<std::is_convertible<
typename std::iterator_traits<in_iter>::iterator_category,
std::input_iterator_tag>::value>>
void assign(in_iter in_start, in_iter in_end) {
- this->assertSafeToReferenceAfterClear(in_start, in_end);
+ this->assertSafeToReferenceAfterClear(in_start, in_end);
clear();
append(in_start, in_end);
}
@@ -707,13 +707,13 @@ public:
append(IL);
}
- void assign(const SmallVectorImpl &RHS) { assign(RHS.begin(), RHS.end()); }
-
+ void assign(const SmallVectorImpl &RHS) { assign(RHS.begin(), RHS.end()); }
+
iterator erase(const_iterator CI) {
// Just cast away constness because this is a non-const member function.
iterator I = const_cast<iterator>(CI);
- assert(this->isReferenceToStorage(CI) && "Iterator to erase is out of bounds.");
+ assert(this->isReferenceToStorage(CI) && "Iterator to erase is out of bounds.");
iterator N = I;
// Shift all elts down one.
@@ -728,7 +728,7 @@ public:
iterator S = const_cast<iterator>(CS);
iterator E = const_cast<iterator>(CE);
- assert(this->isRangeInStorage(S, E) && "Range to erase is out of bounds.");
+ assert(this->isRangeInStorage(S, E) && "Range to erase is out of bounds.");
iterator N = S;
// Shift all elts down.
@@ -739,26 +739,26 @@ public:
return(N);
}
-private:
- template <class ArgType> iterator insert_one_impl(iterator I, ArgType &&Elt) {
- // Callers ensure that ArgType is derived from T.
- static_assert(
- std::is_same<std::remove_const_t<std::remove_reference_t<ArgType>>,
- T>::value,
- "ArgType must be derived from T!");
-
+private:
+ template <class ArgType> iterator insert_one_impl(iterator I, ArgType &&Elt) {
+ // Callers ensure that ArgType is derived from T.
+ static_assert(
+ std::is_same<std::remove_const_t<std::remove_reference_t<ArgType>>,
+ T>::value,
+ "ArgType must be derived from T!");
+
if (I == this->end()) { // Important special case for empty vector.
- this->push_back(::std::forward<ArgType>(Elt));
+ this->push_back(::std::forward<ArgType>(Elt));
return this->end()-1;
}
- assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
+ assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
- // Grow if necessary.
- size_t Index = I - this->begin();
- std::remove_reference_t<ArgType> *EltPtr =
- this->reserveForParamAndGetAddress(Elt);
- I = this->begin() + Index;
+ // Grow if necessary.
+ size_t Index = I - this->begin();
+ std::remove_reference_t<ArgType> *EltPtr =
+ this->reserveForParamAndGetAddress(Elt);
+ I = this->begin() + Index;
::new ((void*) this->end()) T(::std::move(this->back()));
// Push everything else over.
@@ -766,26 +766,26 @@ private:
this->set_size(this->size() + 1);
// If we just moved the element we're inserting, be sure to update
- // the reference (never happens if TakesParamByValue).
- static_assert(!TakesParamByValue || std::is_same<ArgType, T>::value,
- "ArgType must be 'T' when taking by value!");
- if (!TakesParamByValue && this->isReferenceToRange(EltPtr, I, this->end()))
+ // the reference (never happens if TakesParamByValue).
+ static_assert(!TakesParamByValue || std::is_same<ArgType, T>::value,
+ "ArgType must be 'T' when taking by value!");
+ if (!TakesParamByValue && this->isReferenceToRange(EltPtr, I, this->end()))
++EltPtr;
- *I = ::std::forward<ArgType>(*EltPtr);
+ *I = ::std::forward<ArgType>(*EltPtr);
return I;
}
-public:
- iterator insert(iterator I, T &&Elt) {
- return insert_one_impl(I, this->forward_value_param(std::move(Elt)));
- }
-
+public:
+ iterator insert(iterator I, T &&Elt) {
+ return insert_one_impl(I, this->forward_value_param(std::move(Elt)));
+ }
+
iterator insert(iterator I, const T &Elt) {
- return insert_one_impl(I, this->forward_value_param(Elt));
+ return insert_one_impl(I, this->forward_value_param(Elt));
}
- iterator insert(iterator I, size_type NumToInsert, ValueParamT Elt) {
+ iterator insert(iterator I, size_type NumToInsert, ValueParamT Elt) {
// Convert iterator to elt# to avoid invalidating iterator when we reserve()
size_t InsertElt = I - this->begin();
@@ -794,11 +794,11 @@ public:
return this->begin()+InsertElt;
}
- assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
+ assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
- // Ensure there is enough space, and get the (maybe updated) address of
- // Elt.
- const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumToInsert);
+ // Ensure there is enough space, and get the (maybe updated) address of
+ // Elt.
+ const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumToInsert);
// Uninvalidate the iterator.
I = this->begin()+InsertElt;
@@ -815,12 +815,12 @@ public:
// Copy the existing elements that get replaced.
std::move_backward(I, OldEnd-NumToInsert, OldEnd);
- // If we just moved the element we're inserting, be sure to update
- // the reference (never happens if TakesParamByValue).
- if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end())
- EltPtr += NumToInsert;
-
- std::fill_n(I, NumToInsert, *EltPtr);
+ // If we just moved the element we're inserting, be sure to update
+ // the reference (never happens if TakesParamByValue).
+ if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end())
+ EltPtr += NumToInsert;
+
+ std::fill_n(I, NumToInsert, *EltPtr);
return I;
}
@@ -833,16 +833,16 @@ public:
size_t NumOverwritten = OldEnd-I;
this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
- // If we just moved the element we're inserting, be sure to update
- // the reference (never happens if TakesParamByValue).
- if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end())
- EltPtr += NumToInsert;
-
+ // If we just moved the element we're inserting, be sure to update
+ // the reference (never happens if TakesParamByValue).
+ if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end())
+ EltPtr += NumToInsert;
+
// Replace the overwritten part.
- std::fill_n(I, NumOverwritten, *EltPtr);
+ std::fill_n(I, NumOverwritten, *EltPtr);
// Insert the non-overwritten middle part.
- std::uninitialized_fill_n(OldEnd, NumToInsert - NumOverwritten, *EltPtr);
+ std::uninitialized_fill_n(OldEnd, NumToInsert - NumOverwritten, *EltPtr);
return I;
}
@@ -859,11 +859,11 @@ public:
return this->begin()+InsertElt;
}
- assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
+ assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
+
+ // Check that the reserve that follows doesn't invalidate the iterators.
+ this->assertSafeToAddRange(From, To);
- // Check that the reserve that follows doesn't invalidate the iterators.
- this->assertSafeToAddRange(From, To);
-
size_t NumToInsert = std::distance(From, To);
// Ensure there is enough space.
@@ -914,8 +914,8 @@ public:
template <typename... ArgTypes> reference emplace_back(ArgTypes &&... Args) {
if (LLVM_UNLIKELY(this->size() >= this->capacity()))
- return this->growAndEmplaceBack(std::forward<ArgTypes>(Args)...);
-
+ return this->growAndEmplaceBack(std::forward<ArgTypes>(Args)...);
+
::new ((void *)this->end()) T(std::forward<ArgTypes>(Args)...);
this->set_size(this->size() + 1);
return this->back();
@@ -950,8 +950,8 @@ void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
std::swap(this->Capacity, RHS.Capacity);
return;
}
- this->reserve(RHS.size());
- RHS.reserve(this->size());
+ this->reserve(RHS.size());
+ RHS.reserve(this->size());
// Swap the shared elements.
size_t NumShared = this->size();
@@ -1006,7 +1006,7 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::
// FIXME: don't do this if they're efficiently moveable.
if (this->capacity() < RHSSize) {
// Destroy current elements.
- this->clear();
+ this->clear();
CurSize = 0;
this->grow(RHSSize);
} else if (CurSize) {
@@ -1065,7 +1065,7 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
// elements.
if (this->capacity() < RHSSize) {
// Destroy current elements.
- this->clear();
+ this->clear();
CurSize = 0;
this->grow(RHSSize);
} else if (CurSize) {
@@ -1088,90 +1088,90 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
/// to avoid allocating unnecessary storage.
template <typename T, unsigned N>
struct SmallVectorStorage {
- alignas(T) char InlineElts[N * sizeof(T)];
+ alignas(T) char InlineElts[N * sizeof(T)];
};
/// We need the storage to be properly aligned even for small-size of 0 so that
/// the pointer math in \a SmallVectorTemplateCommon::getFirstEl() is
/// well-defined.
-template <typename T> struct alignas(T) SmallVectorStorage<T, 0> {};
-
-/// Forward declaration of SmallVector so that
-/// calculateSmallVectorDefaultInlinedElements can reference
-/// `sizeof(SmallVector<T, 0>)`.
-template <typename T, unsigned N> class LLVM_GSL_OWNER SmallVector;
-
-/// Helper class for calculating the default number of inline elements for
-/// `SmallVector<T>`.
-///
-/// This should be migrated to a constexpr function when our minimum
-/// compiler support is enough for multi-statement constexpr functions.
-template <typename T> struct CalculateSmallVectorDefaultInlinedElements {
- // Parameter controlling the default number of inlined elements
- // for `SmallVector<T>`.
- //
- // The default number of inlined elements ensures that
- // 1. There is at least one inlined element.
- // 2. `sizeof(SmallVector<T>) <= kPreferredSmallVectorSizeof` unless
- // it contradicts 1.
- static constexpr size_t kPreferredSmallVectorSizeof = 64;
-
- // static_assert that sizeof(T) is not "too big".
- //
- // Because our policy guarantees at least one inlined element, it is possible
- // for an arbitrarily large inlined element to allocate an arbitrarily large
- // amount of inline storage. We generally consider it an antipattern for a
- // SmallVector to allocate an excessive amount of inline storage, so we want
- // to call attention to these cases and make sure that users are making an
- // intentional decision if they request a lot of inline storage.
- //
- // We want this assertion to trigger in pathological cases, but otherwise
- // not be too easy to hit. To accomplish that, the cutoff is actually somewhat
- // larger than kPreferredSmallVectorSizeof (otherwise,
- // `SmallVector<SmallVector<T>>` would be one easy way to trip it, and that
- // pattern seems useful in practice).
- //
- // One wrinkle is that this assertion is in theory non-portable, since
- // sizeof(T) is in general platform-dependent. However, we don't expect this
- // to be much of an issue, because most LLVM development happens on 64-bit
- // hosts, and therefore sizeof(T) is expected to *decrease* when compiled for
- // 32-bit hosts, dodging the issue. The reverse situation, where development
- // happens on a 32-bit host and then fails due to sizeof(T) *increasing* on a
- // 64-bit host, is expected to be very rare.
- static_assert(
- sizeof(T) <= 256,
- "You are trying to use a default number of inlined elements for "
- "`SmallVector<T>` but `sizeof(T)` is really big! Please use an "
- "explicit number of inlined elements with `SmallVector<T, N>` to make "
- "sure you really want that much inline storage.");
-
- // Discount the size of the header itself when calculating the maximum inline
- // bytes.
- static constexpr size_t PreferredInlineBytes =
- kPreferredSmallVectorSizeof - sizeof(SmallVector<T, 0>);
- static constexpr size_t NumElementsThatFit = PreferredInlineBytes / sizeof(T);
- static constexpr size_t value =
- NumElementsThatFit == 0 ? 1 : NumElementsThatFit;
-};
-
+template <typename T> struct alignas(T) SmallVectorStorage<T, 0> {};
+
+/// Forward declaration of SmallVector so that
+/// calculateSmallVectorDefaultInlinedElements can reference
+/// `sizeof(SmallVector<T, 0>)`.
+template <typename T, unsigned N> class LLVM_GSL_OWNER SmallVector;
+
+/// Helper class for calculating the default number of inline elements for
+/// `SmallVector<T>`.
+///
+/// This should be migrated to a constexpr function when our minimum
+/// compiler support is enough for multi-statement constexpr functions.
+template <typename T> struct CalculateSmallVectorDefaultInlinedElements {
+ // Parameter controlling the default number of inlined elements
+ // for `SmallVector<T>`.
+ //
+ // The default number of inlined elements ensures that
+ // 1. There is at least one inlined element.
+ // 2. `sizeof(SmallVector<T>) <= kPreferredSmallVectorSizeof` unless
+ // it contradicts 1.
+ static constexpr size_t kPreferredSmallVectorSizeof = 64;
+
+ // static_assert that sizeof(T) is not "too big".
+ //
+ // Because our policy guarantees at least one inlined element, it is possible
+ // for an arbitrarily large inlined element to allocate an arbitrarily large
+ // amount of inline storage. We generally consider it an antipattern for a
+ // SmallVector to allocate an excessive amount of inline storage, so we want
+ // to call attention to these cases and make sure that users are making an
+ // intentional decision if they request a lot of inline storage.
+ //
+ // We want this assertion to trigger in pathological cases, but otherwise
+ // not be too easy to hit. To accomplish that, the cutoff is actually somewhat
+ // larger than kPreferredSmallVectorSizeof (otherwise,
+ // `SmallVector<SmallVector<T>>` would be one easy way to trip it, and that
+ // pattern seems useful in practice).
+ //
+ // One wrinkle is that this assertion is in theory non-portable, since
+ // sizeof(T) is in general platform-dependent. However, we don't expect this
+ // to be much of an issue, because most LLVM development happens on 64-bit
+ // hosts, and therefore sizeof(T) is expected to *decrease* when compiled for
+ // 32-bit hosts, dodging the issue. The reverse situation, where development
+ // happens on a 32-bit host and then fails due to sizeof(T) *increasing* on a
+ // 64-bit host, is expected to be very rare.
+ static_assert(
+ sizeof(T) <= 256,
+ "You are trying to use a default number of inlined elements for "
+ "`SmallVector<T>` but `sizeof(T)` is really big! Please use an "
+ "explicit number of inlined elements with `SmallVector<T, N>` to make "
+ "sure you really want that much inline storage.");
+
+ // Discount the size of the header itself when calculating the maximum inline
+ // bytes.
+ static constexpr size_t PreferredInlineBytes =
+ kPreferredSmallVectorSizeof - sizeof(SmallVector<T, 0>);
+ static constexpr size_t NumElementsThatFit = PreferredInlineBytes / sizeof(T);
+ static constexpr size_t value =
+ NumElementsThatFit == 0 ? 1 : NumElementsThatFit;
+};
+
/// This is a 'vector' (really, a variable-sized array), optimized
/// for the case when the array is small. It contains some number of elements
/// in-place, which allows it to avoid heap allocation when the actual number of
/// elements is below that threshold. This allows normal "small" cases to be
/// fast without losing generality for large inputs.
///
-/// \note
-/// In the absence of a well-motivated choice for the number of inlined
-/// elements \p N, it is recommended to use \c SmallVector<T> (that is,
-/// omitting the \p N). This will choose a default number of inlined elements
-/// reasonable for allocation on the stack (for example, trying to keep \c
-/// sizeof(SmallVector<T>) around 64 bytes).
+/// \note
+/// In the absence of a well-motivated choice for the number of inlined
+/// elements \p N, it is recommended to use \c SmallVector<T> (that is,
+/// omitting the \p N). This will choose a default number of inlined elements
+/// reasonable for allocation on the stack (for example, trying to keep \c
+/// sizeof(SmallVector<T>) around 64 bytes).
+///
+/// \warning This does not attempt to be exception safe.
///
-/// \warning This does not attempt to be exception safe.
-///
-/// \see https://llvm.org/docs/ProgrammersManual.html#llvm-adt-smallvector-h
-template <typename T,
- unsigned N = CalculateSmallVectorDefaultInlinedElements<T>::value>
+/// \see https://llvm.org/docs/ProgrammersManual.html#llvm-adt-smallvector-h
+template <typename T,
+ unsigned N = CalculateSmallVectorDefaultInlinedElements<T>::value>
class LLVM_GSL_OWNER SmallVector : public SmallVectorImpl<T>,
SmallVectorStorage<T, N> {
public:
@@ -1210,7 +1210,7 @@ public:
SmallVectorImpl<T>::operator=(RHS);
}
- SmallVector &operator=(const SmallVector &RHS) {
+ SmallVector &operator=(const SmallVector &RHS) {
SmallVectorImpl<T>::operator=(RHS);
return *this;
}
@@ -1225,17 +1225,17 @@ public:
SmallVectorImpl<T>::operator=(::std::move(RHS));
}
- SmallVector &operator=(SmallVector &&RHS) {
+ SmallVector &operator=(SmallVector &&RHS) {
SmallVectorImpl<T>::operator=(::std::move(RHS));
return *this;
}
- SmallVector &operator=(SmallVectorImpl<T> &&RHS) {
+ SmallVector &operator=(SmallVectorImpl<T> &&RHS) {
SmallVectorImpl<T>::operator=(::std::move(RHS));
return *this;
}
- SmallVector &operator=(std::initializer_list<T> IL) {
+ SmallVector &operator=(std::initializer_list<T> IL) {
this->assign(IL);
return *this;
}
diff --git a/contrib/libs/llvm12/include/llvm/ADT/SparseSet.h b/contrib/libs/llvm12/include/llvm/ADT/SparseSet.h
index c4f9a19ef7..f1cec90a3c 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/SparseSet.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/SparseSet.h
@@ -236,15 +236,15 @@ public:
return const_cast<SparseSet*>(this)->findIndex(KeyIndexOf(Key));
}
- /// Check if the set contains the given \c Key.
- ///
- /// @param Key A valid key to find.
- bool contains(const KeyT &Key) const { return find(Key) == end() ? 0 : 1; }
-
+ /// Check if the set contains the given \c Key.
+ ///
+ /// @param Key A valid key to find.
+ bool contains(const KeyT &Key) const { return find(Key) == end() ? 0 : 1; }
+
/// count - Returns 1 if this set contains an element identified by Key,
/// 0 otherwise.
///
- size_type count(const KeyT &Key) const { return contains(Key) ? 1 : 0; }
+ size_type count(const KeyT &Key) const { return contains(Key) ? 1 : 0; }
/// insert - Attempts to insert a new element.
///
diff --git a/contrib/libs/llvm12/include/llvm/ADT/Statistic.h b/contrib/libs/llvm12/include/llvm/ADT/Statistic.h
index b8625958c8..ad584c447e 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/Statistic.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/Statistic.h
@@ -43,8 +43,8 @@
// configure time.
#if !defined(NDEBUG) || LLVM_FORCE_ENABLE_STATS
#define LLVM_ENABLE_STATS 1
-#else
-#define LLVM_ENABLE_STATS 0
+#else
+#define LLVM_ENABLE_STATS 0
#endif
namespace llvm {
diff --git a/contrib/libs/llvm12/include/llvm/ADT/StringExtras.h b/contrib/libs/llvm12/include/llvm/ADT/StringExtras.h
index d7332d08a6..1ddaf13978 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/StringExtras.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/StringExtras.h
@@ -73,29 +73,29 @@ inline ArrayRef<uint8_t> arrayRefFromStringRef(StringRef Input) {
///
/// If \p C is not a valid hex digit, -1U is returned.
inline unsigned hexDigitValue(char C) {
- struct HexTable {
- unsigned LUT[255] = {};
- constexpr HexTable() {
- // Default initialize everything to invalid.
- for (int i = 0; i < 255; ++i)
- LUT[i] = ~0U;
- // Initialize `0`-`9`.
- for (int i = 0; i < 10; ++i)
- LUT['0' + i] = i;
- // Initialize `A`-`F` and `a`-`f`.
- for (int i = 0; i < 6; ++i)
- LUT['A' + i] = LUT['a' + i] = 10 + i;
- }
- };
- constexpr HexTable Table;
- return Table.LUT[static_cast<unsigned char>(C)];
+ struct HexTable {
+ unsigned LUT[255] = {};
+ constexpr HexTable() {
+ // Default initialize everything to invalid.
+ for (int i = 0; i < 255; ++i)
+ LUT[i] = ~0U;
+ // Initialize `0`-`9`.
+ for (int i = 0; i < 10; ++i)
+ LUT['0' + i] = i;
+ // Initialize `A`-`F` and `a`-`f`.
+ for (int i = 0; i < 6; ++i)
+ LUT['A' + i] = LUT['a' + i] = 10 + i;
+ }
+ };
+ constexpr HexTable Table;
+ return Table.LUT[static_cast<unsigned char>(C)];
}
/// Checks if character \p C is one of the 10 decimal digits.
inline bool isDigit(char C) { return C >= '0' && C <= '9'; }
/// Checks if character \p C is a hexadecimal numeric character.
-inline bool isHexDigit(char C) { return hexDigitValue(C) != ~0U; }
+inline bool isHexDigit(char C) { return hexDigitValue(C) != ~0U; }
/// Checks if character \p C is a valid letter as classified by "C" locale.
inline bool isAlpha(char C) {
@@ -184,70 +184,70 @@ inline std::string toHex(ArrayRef<uint8_t> Input, bool LowerCase = false) {
return toHex(toStringRef(Input), LowerCase);
}
-/// Store the binary representation of the two provided values, \p MSB and
-/// \p LSB, that make up the nibbles of a hexadecimal digit. If \p MSB or \p LSB
-/// do not correspond to proper nibbles of a hexadecimal digit, this method
-/// returns false. Otherwise, returns true.
-inline bool tryGetHexFromNibbles(char MSB, char LSB, uint8_t &Hex) {
+/// Store the binary representation of the two provided values, \p MSB and
+/// \p LSB, that make up the nibbles of a hexadecimal digit. If \p MSB or \p LSB
+/// do not correspond to proper nibbles of a hexadecimal digit, this method
+/// returns false. Otherwise, returns true.
+inline bool tryGetHexFromNibbles(char MSB, char LSB, uint8_t &Hex) {
unsigned U1 = hexDigitValue(MSB);
unsigned U2 = hexDigitValue(LSB);
- if (U1 == ~0U || U2 == ~0U)
- return false;
-
- Hex = static_cast<uint8_t>((U1 << 4) | U2);
- return true;
-}
-
-/// Return the binary representation of the two provided values, \p MSB and
-/// \p LSB, that make up the nibbles of a hexadecimal digit.
-inline uint8_t hexFromNibbles(char MSB, char LSB) {
- uint8_t Hex = 0;
- bool GotHex = tryGetHexFromNibbles(MSB, LSB, Hex);
- (void)GotHex;
- assert(GotHex && "MSB and/or LSB do not correspond to hex digits");
- return Hex;
-}
-
-/// Convert hexadecimal string \p Input to its binary representation and store
-/// the result in \p Output. Returns true if the binary representation could be
-/// converted from the hexadecimal string. Returns false if \p Input contains
-/// non-hexadecimal digits. The output string is half the size of \p Input.
-inline bool tryGetFromHex(StringRef Input, std::string &Output) {
+ if (U1 == ~0U || U2 == ~0U)
+ return false;
+
+ Hex = static_cast<uint8_t>((U1 << 4) | U2);
+ return true;
+}
+
+/// Return the binary representation of the two provided values, \p MSB and
+/// \p LSB, that make up the nibbles of a hexadecimal digit.
+inline uint8_t hexFromNibbles(char MSB, char LSB) {
+ uint8_t Hex = 0;
+ bool GotHex = tryGetHexFromNibbles(MSB, LSB, Hex);
+ (void)GotHex;
+ assert(GotHex && "MSB and/or LSB do not correspond to hex digits");
+ return Hex;
+}
+
+/// Convert hexadecimal string \p Input to its binary representation and store
+/// the result in \p Output. Returns true if the binary representation could be
+/// converted from the hexadecimal string. Returns false if \p Input contains
+/// non-hexadecimal digits. The output string is half the size of \p Input.
+inline bool tryGetFromHex(StringRef Input, std::string &Output) {
if (Input.empty())
- return true;
+ return true;
Output.reserve((Input.size() + 1) / 2);
if (Input.size() % 2 == 1) {
- uint8_t Hex = 0;
- if (!tryGetHexFromNibbles('0', Input.front(), Hex))
- return false;
-
- Output.push_back(Hex);
+ uint8_t Hex = 0;
+ if (!tryGetHexFromNibbles('0', Input.front(), Hex))
+ return false;
+
+ Output.push_back(Hex);
Input = Input.drop_front();
}
assert(Input.size() % 2 == 0);
while (!Input.empty()) {
- uint8_t Hex = 0;
- if (!tryGetHexFromNibbles(Input[0], Input[1], Hex))
- return false;
-
+ uint8_t Hex = 0;
+ if (!tryGetHexFromNibbles(Input[0], Input[1], Hex))
+ return false;
+
Output.push_back(Hex);
Input = Input.drop_front(2);
}
- return true;
-}
-
-/// Convert hexadecimal string \p Input to its binary representation.
-/// The return string is half the size of \p Input.
-inline std::string fromHex(StringRef Input) {
- std::string Hex;
- bool GotHex = tryGetFromHex(Input, Hex);
- (void)GotHex;
- assert(GotHex && "Input contains non hex digits");
- return Hex;
-}
-
+ return true;
+}
+
+/// Convert hexadecimal string \p Input to its binary representation.
+/// The return string is half the size of \p Input.
+inline std::string fromHex(StringRef Input) {
+ std::string Hex;
+ bool GotHex = tryGetFromHex(Input, Hex);
+ (void)GotHex;
+ assert(GotHex && "Input contains non hex digits");
+ return Hex;
+}
+
/// 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.
@@ -298,7 +298,7 @@ inline std::string utostr(uint64_t X, bool isNeg = false) {
inline std::string itostr(int64_t X) {
if (X < 0)
- return utostr(static_cast<uint64_t>(1) + ~static_cast<uint64_t>(X), true);
+ return utostr(static_cast<uint64_t>(1) + ~static_cast<uint64_t>(X), true);
else
return utostr(static_cast<uint64_t>(X));
}
@@ -391,16 +391,16 @@ inline std::string join_impl(IteratorT Begin, IteratorT End,
size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
for (IteratorT I = Begin; I != End; ++I)
- Len += (*I).size();
+ Len += (*I).size();
S.reserve(Len);
- size_t PrevCapacity = S.capacity();
- (void)PrevCapacity;
+ size_t PrevCapacity = S.capacity();
+ (void)PrevCapacity;
S += (*Begin);
while (++Begin != End) {
S += Separator;
S += (*Begin);
}
- assert(PrevCapacity == S.capacity() && "String grew during building");
+ assert(PrevCapacity == S.capacity() && "String grew during building");
return S;
}
@@ -472,30 +472,30 @@ inline std::string join_items(Sep Separator, Args &&... Items) {
return Result;
}
-/// A helper class to return the specified delimiter string after the first
-/// invocation of operator StringRef(). Used to generate a comma-separated
-/// list from a loop like so:
-///
-/// \code
-/// ListSeparator LS;
-/// for (auto &I : C)
-/// OS << LS << I.getName();
-/// \end
-class ListSeparator {
- bool First = true;
- StringRef Separator;
-
-public:
- ListSeparator(StringRef Separator = ", ") : Separator(Separator) {}
- operator StringRef() {
- if (First) {
- First = false;
- return {};
- }
- return Separator;
- }
-};
-
+/// A helper class to return the specified delimiter string after the first
+/// invocation of operator StringRef(). Used to generate a comma-separated
+/// list from a loop like so:
+///
+/// \code
+/// ListSeparator LS;
+/// for (auto &I : C)
+/// OS << LS << I.getName();
+/// \end
+class ListSeparator {
+ bool First = true;
+ StringRef Separator;
+
+public:
+ ListSeparator(StringRef Separator = ", ") : Separator(Separator) {}
+ operator StringRef() {
+ if (First) {
+ First = false;
+ return {};
+ }
+ return Separator;
+ }
+};
+
} // end namespace llvm
#endif // LLVM_ADT_STRINGEXTRAS_H
diff --git a/contrib/libs/llvm12/include/llvm/ADT/StringMap.h b/contrib/libs/llvm12/include/llvm/ADT/StringMap.h
index 7e45f1b079..155a60fd2c 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/StringMap.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/StringMap.h
@@ -85,12 +85,12 @@ protected:
void init(unsigned Size);
public:
- static constexpr uintptr_t TombstoneIntVal =
- static_cast<uintptr_t>(-1)
- << PointerLikeTypeTraits<StringMapEntryBase *>::NumLowBitsAvailable;
-
+ static constexpr uintptr_t TombstoneIntVal =
+ static_cast<uintptr_t>(-1)
+ << PointerLikeTypeTraits<StringMapEntryBase *>::NumLowBitsAvailable;
+
static StringMapEntryBase *getTombstoneVal() {
- return reinterpret_cast<StringMapEntryBase *>(TombstoneIntVal);
+ return reinterpret_cast<StringMapEntryBase *>(TombstoneIntVal);
}
unsigned getNumBuckets() const { return NumBuckets; }
diff --git a/contrib/libs/llvm12/include/llvm/ADT/StringSet.h b/contrib/libs/llvm12/include/llvm/ADT/StringSet.h
index c61360c61b..8e957f7bc7 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/StringSet.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/StringSet.h
@@ -52,9 +52,9 @@ public:
insert(const StringMapEntry<ValueTy> &mapEntry) {
return insert(mapEntry.getKey());
}
-
- /// Check if the set contains the given \c key.
- bool contains(StringRef key) const { return Base::FindKey(key) != -1; }
+
+ /// Check if the set contains the given \c key.
+ bool contains(StringRef key) const { return Base::FindKey(key) != -1; }
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/ADT/Triple.h b/contrib/libs/llvm12/include/llvm/ADT/Triple.h
index ebfabb9374..32587a9fc5 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/Triple.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/Triple.h
@@ -63,7 +63,7 @@ public:
avr, // AVR: Atmel AVR microcontroller
bpfel, // eBPF or extended BPF or 64-bit BPF (little endian)
bpfeb, // eBPF or extended BPF or 64-bit BPF (big endian)
- csky, // CSKY: csky
+ csky, // CSKY: csky
hexagon, // Hexagon: hexagon
mips, // MIPS: mips, mipsallegrex, mipsr6
mipsel, // MIPSEL: mipsel, mipsallegrexe, mipsr6el
@@ -71,7 +71,7 @@ public:
mips64el, // MIPS64EL: mips64el, mips64r6el, mipsn32el, mipsn32r6el
msp430, // MSP430: msp430
ppc, // PPC: powerpc
- ppcle, // PPCLE: powerpc (little endian)
+ ppcle, // PPCLE: powerpc (little endian)
ppc64, // PPC64: powerpc64, ppu
ppc64le, // PPC64LE: powerpc64le
r600, // R600: AMD GPUs HD2XXX - HD6XXX
@@ -112,7 +112,7 @@ public:
enum SubArchType {
NoSubArch,
- ARMSubArch_v8_7a,
+ ARMSubArch_v8_7a,
ARMSubArch_v8_6a,
ARMSubArch_v8_5a,
ARMSubArch_v8_4a,
@@ -138,8 +138,8 @@ public:
ARMSubArch_v5te,
ARMSubArch_v4t,
- AArch64SubArch_arm64e,
-
+ AArch64SubArch_arm64e,
+
KalimbaSubArch_v3,
KalimbaSubArch_v4,
KalimbaSubArch_v5,
@@ -185,7 +185,7 @@ public:
OpenBSD,
Solaris,
Win32,
- ZOS,
+ ZOS,
Haiku,
Minix,
RTEMS,
@@ -216,7 +216,7 @@ public:
GNUEABI,
GNUEABIHF,
GNUX32,
- GNUILP32,
+ GNUILP32,
CODE16,
EABI,
EABIHF,
@@ -238,7 +238,7 @@ public:
COFF,
ELF,
- GOFF,
+ GOFF,
MachO,
Wasm,
XCOFF,
@@ -483,8 +483,8 @@ public:
return getSubArch() == Triple::ARMSubArch_v7k;
}
- bool isOSzOS() const { return getOS() == Triple::ZOS; }
-
+ bool isOSzOS() const { return getOS() == Triple::ZOS; }
+
/// isOSDarwin - Is this a "Darwin" OS (macOS, iOS, tvOS or watchOS).
bool isOSDarwin() const {
return isMacOSX() || isiOS() || isWatchOS();
@@ -498,12 +498,12 @@ public:
return getEnvironment() == Triple::MacABI;
}
- /// Returns true for targets that run on a macOS machine.
- bool isTargetMachineMac() const {
- return isMacOSX() || (isOSDarwin() && (isSimulatorEnvironment() ||
- isMacCatalystEnvironment()));
- }
-
+ /// Returns true for targets that run on a macOS machine.
+ bool isTargetMachineMac() const {
+ return isMacOSX() || (isOSDarwin() && (isSimulatorEnvironment() ||
+ isMacCatalystEnvironment()));
+ }
+
bool isOSNetBSD() const {
return getOS() == Triple::NetBSD;
}
@@ -643,9 +643,9 @@ public:
return getObjectFormat() == Triple::COFF;
}
- /// Tests whether the OS uses the GOFF binary format.
- bool isOSBinFormatGOFF() const { return getObjectFormat() == Triple::GOFF; }
-
+ /// Tests whether the OS uses the GOFF binary format.
+ bool isOSBinFormatGOFF() const { return getObjectFormat() == Triple::GOFF; }
+
/// Tests whether the environment is MachO.
bool isOSBinFormatMachO() const {
return getObjectFormat() == Triple::MachO;
@@ -726,22 +726,22 @@ public:
/// Tests whether the target is AArch64 (little and big endian).
bool isAArch64() const {
- return getArch() == Triple::aarch64 || getArch() == Triple::aarch64_be ||
- getArch() == Triple::aarch64_32;
- }
-
- /// Tests whether the target is AArch64 and pointers are the size specified by
- /// \p PointerWidth.
- bool isAArch64(int PointerWidth) const {
- assert(PointerWidth == 64 || PointerWidth == 32);
- if (!isAArch64())
- return false;
- return getArch() == Triple::aarch64_32 ||
- getEnvironment() == Triple::GNUILP32
- ? PointerWidth == 32
- : PointerWidth == 64;
- }
-
+ return getArch() == Triple::aarch64 || getArch() == Triple::aarch64_be ||
+ getArch() == Triple::aarch64_32;
+ }
+
+ /// Tests whether the target is AArch64 and pointers are the size specified by
+ /// \p PointerWidth.
+ bool isAArch64(int PointerWidth) const {
+ assert(PointerWidth == 64 || PointerWidth == 32);
+ if (!isAArch64())
+ return false;
+ return getArch() == Triple::aarch64_32 ||
+ getEnvironment() == Triple::GNUILP32
+ ? PointerWidth == 32
+ : PointerWidth == 64;
+ }
+
/// Tests whether the target is MIPS 32-bit (little and big endian).
bool isMIPS32() const {
return getArch() == Triple::mips || getArch() == Triple::mipsel;
@@ -757,17 +757,17 @@ public:
return isMIPS32() || isMIPS64();
}
- /// Tests whether the target is PowerPC (32- or 64-bit LE or BE).
- bool isPPC() const {
- return getArch() == Triple::ppc || getArch() == Triple::ppc64 ||
- getArch() == Triple::ppcle || getArch() == Triple::ppc64le;
- }
-
- /// Tests whether the target is 32-bit PowerPC (little and big endian).
- bool isPPC32() const {
- return getArch() == Triple::ppc || getArch() == Triple::ppcle;
- }
-
+ /// Tests whether the target is PowerPC (32- or 64-bit LE or BE).
+ bool isPPC() const {
+ return getArch() == Triple::ppc || getArch() == Triple::ppc64 ||
+ getArch() == Triple::ppcle || getArch() == Triple::ppc64le;
+ }
+
+ /// Tests whether the target is 32-bit PowerPC (little and big endian).
+ bool isPPC32() const {
+ return getArch() == Triple::ppc || getArch() == Triple::ppcle;
+ }
+
/// Tests whether the target is 64-bit PowerPC (little and big endian).
bool isPPC64() const {
return getArch() == Triple::ppc64 || getArch() == Triple::ppc64le;
@@ -798,17 +798,17 @@ public:
return getArch() == Triple::wasm32 || getArch() == Triple::wasm64;
}
- // Tests whether the target is CSKY
- bool isCSKY() const {
- return getArch() == Triple::csky;
- }
-
- /// Tests whether the target is the Apple "arm64e" AArch64 subarch.
- bool isArm64e() const {
- return getArch() == Triple::aarch64 &&
- getSubArch() == Triple::AArch64SubArch_arm64e;
- }
-
+ // Tests whether the target is CSKY
+ bool isCSKY() const {
+ return getArch() == Triple::csky;
+ }
+
+ /// Tests whether the target is the Apple "arm64e" AArch64 subarch.
+ bool isArm64e() const {
+ return getArch() == Triple::aarch64 &&
+ getSubArch() == Triple::AArch64SubArch_arm64e;
+ }
+
/// Tests whether the target supports comdat
bool supportsCOMDAT() const {
return !(isOSBinFormatMachO() || isOSBinFormatXCOFF());
@@ -819,14 +819,14 @@ public:
return isAndroid() || isOSOpenBSD() || isWindowsCygwinEnvironment();
}
- /// Tests whether the target uses -data-sections as default.
- bool hasDefaultDataSections() const {
- return isOSBinFormatXCOFF() || isWasm();
- }
-
- /// Tests if the environment supports dllimport/export annotations.
- bool hasDLLImportExport() const { return isOSWindows() || isPS4CPU(); }
-
+ /// Tests whether the target uses -data-sections as default.
+ bool hasDefaultDataSections() const {
+ return isOSBinFormatXCOFF() || isWasm();
+ }
+
+ /// Tests if the environment supports dllimport/export annotations.
+ bool hasDLLImportExport() const { return isOSWindows() || isPS4CPU(); }
+
/// @}
/// @name Mutators
/// @{
diff --git a/contrib/libs/llvm12/include/llvm/ADT/simple_ilist.h b/contrib/libs/llvm12/include/llvm/ADT/simple_ilist.h
index 8d06d0c899..619f3f466b 100644
--- a/contrib/libs/llvm12/include/llvm/ADT/simple_ilist.h
+++ b/contrib/libs/llvm12/include/llvm/ADT/simple_ilist.h
@@ -35,8 +35,8 @@ namespace llvm {
/// This is a simple intrusive list for a \c T that inherits from \c
/// ilist_node<T>. The list never takes ownership of anything inserted in it.
///
-/// Unlike \a iplist<T> and \a ilist<T>, \a simple_ilist<T> never deletes
-/// values, and has no callback traits.
+/// Unlike \a iplist<T> and \a ilist<T>, \a simple_ilist<T> never deletes
+/// values, and has no callback traits.
///
/// The API for adding nodes include \a push_front(), \a push_back(), and \a
/// insert(). These all take values by reference (not by pointer), except for
@@ -59,7 +59,7 @@ namespace llvm {
/// to calling \a std::for_each() on the range to be discarded.
///
/// The currently available \p Options customize the nodes in the list. The
-/// same options must be specified in the \a ilist_node instantiation for
+/// same options must be specified in the \a ilist_node instantiation for
/// compatibility (although the order is irrelevant).
/// \li Use \a ilist_tag to designate which ilist_node for a given \p T this
/// list should use. This is useful if a type \p T is part of multiple,
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/AliasAnalysis.h b/contrib/libs/llvm12/include/llvm/Analysis/AliasAnalysis.h
index bfd269831d..adf34c62d7 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/AliasAnalysis.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/AliasAnalysis.h
@@ -59,17 +59,17 @@
namespace llvm {
class AnalysisUsage;
-class AtomicCmpXchgInst;
+class AtomicCmpXchgInst;
class BasicAAResult;
class BasicBlock;
-class CatchPadInst;
-class CatchReturnInst;
+class CatchPadInst;
+class CatchReturnInst;
class DominatorTree;
-class FenceInst;
-class Function;
-class InvokeInst;
-class PreservedAnalyses;
-class TargetLibraryInfo;
+class FenceInst;
+class Function;
+class InvokeInst;
+class PreservedAnalyses;
+class TargetLibraryInfo;
class Value;
/// The possible results of an alias query.
@@ -353,28 +353,28 @@ createModRefInfo(const FunctionModRefBehavior FMRB) {
class AAQueryInfo {
public:
using LocPair = std::pair<MemoryLocation, MemoryLocation>;
- struct CacheEntry {
- AliasResult Result;
- /// Number of times a NoAlias assumption has been used.
- /// 0 for assumptions that have not been used, -1 for definitive results.
- int NumAssumptionUses;
- /// Whether this is a definitive (non-assumption) result.
- bool isDefinitive() const { return NumAssumptionUses < 0; }
- };
- using AliasCacheT = SmallDenseMap<LocPair, CacheEntry, 8>;
+ struct CacheEntry {
+ AliasResult Result;
+ /// Number of times a NoAlias assumption has been used.
+ /// 0 for assumptions that have not been used, -1 for definitive results.
+ int NumAssumptionUses;
+ /// Whether this is a definitive (non-assumption) result.
+ bool isDefinitive() const { return NumAssumptionUses < 0; }
+ };
+ using AliasCacheT = SmallDenseMap<LocPair, CacheEntry, 8>;
AliasCacheT AliasCache;
using IsCapturedCacheT = SmallDenseMap<const Value *, bool, 8>;
IsCapturedCacheT IsCapturedCache;
- /// How many active NoAlias assumption uses there are.
- int NumAssumptionUses = 0;
-
- /// Location pairs for which an assumption based result is currently stored.
- /// Used to remove all potentially incorrect results from the cache if an
- /// assumption is disproven.
- SmallVector<AAQueryInfo::LocPair, 4> AssumptionBasedResults;
-
+ /// How many active NoAlias assumption uses there are.
+ int NumAssumptionUses = 0;
+
+ /// Location pairs for which an assumption based result is currently stored.
+ /// Used to remove all potentially incorrect results from the cache if an
+ /// assumption is disproven.
+ SmallVector<AAQueryInfo::LocPair, 4> AssumptionBasedResults;
+
AAQueryInfo() : AliasCache(), IsCapturedCache() {}
};
@@ -428,8 +428,8 @@ public:
/// A convenience wrapper around the primary \c alias interface.
AliasResult alias(const Value *V1, const Value *V2) {
- return alias(MemoryLocation::getBeforeOrAfter(V1),
- MemoryLocation::getBeforeOrAfter(V2));
+ return alias(MemoryLocation::getBeforeOrAfter(V1),
+ MemoryLocation::getBeforeOrAfter(V2));
}
/// A trivial helper function to check to see if the specified pointers are
@@ -446,8 +446,8 @@ public:
/// A convenience wrapper around the \c isNoAlias helper interface.
bool isNoAlias(const Value *V1, const Value *V2) {
- return isNoAlias(MemoryLocation::getBeforeOrAfter(V1),
- MemoryLocation::getBeforeOrAfter(V2));
+ return isNoAlias(MemoryLocation::getBeforeOrAfter(V1),
+ MemoryLocation::getBeforeOrAfter(V2));
}
/// A trivial helper function to check to see if the specified pointers are
@@ -469,7 +469,7 @@ public:
/// A convenience wrapper around the primary \c pointsToConstantMemory
/// interface.
bool pointsToConstantMemory(const Value *P, bool OrLocal = false) {
- return pointsToConstantMemory(MemoryLocation::getBeforeOrAfter(P), OrLocal);
+ return pointsToConstantMemory(MemoryLocation::getBeforeOrAfter(P), OrLocal);
}
/// @}
@@ -562,7 +562,7 @@ public:
/// write at most from objects pointed to by their pointer-typed arguments
/// (with arbitrary offsets).
static bool onlyAccessesArgPointees(FunctionModRefBehavior MRB) {
- return !((unsigned)MRB & FMRL_Anywhere & ~FMRL_ArgumentPointees);
+ return !((unsigned)MRB & FMRL_Anywhere & ~FMRL_ArgumentPointees);
}
/// Checks if functions with the specified behavior are known to potentially
@@ -570,27 +570,27 @@ public:
/// (with arbitrary offsets).
static bool doesAccessArgPointees(FunctionModRefBehavior MRB) {
return isModOrRefSet(createModRefInfo(MRB)) &&
- ((unsigned)MRB & FMRL_ArgumentPointees);
+ ((unsigned)MRB & FMRL_ArgumentPointees);
}
/// Checks if functions with the specified behavior are known to read and
/// write at most from memory that is inaccessible from LLVM IR.
static bool onlyAccessesInaccessibleMem(FunctionModRefBehavior MRB) {
- return !((unsigned)MRB & FMRL_Anywhere & ~FMRL_InaccessibleMem);
+ return !((unsigned)MRB & FMRL_Anywhere & ~FMRL_InaccessibleMem);
}
/// Checks if functions with the specified behavior are known to potentially
/// read or write from memory that is inaccessible from LLVM IR.
static bool doesAccessInaccessibleMem(FunctionModRefBehavior MRB) {
- return isModOrRefSet(createModRefInfo(MRB)) &&
- ((unsigned)MRB & FMRL_InaccessibleMem);
+ return isModOrRefSet(createModRefInfo(MRB)) &&
+ ((unsigned)MRB & FMRL_InaccessibleMem);
}
/// Checks if functions with the specified behavior are known to read and
/// write at most from memory that is inaccessible from LLVM IR or objects
/// pointed to by their pointer-typed arguments (with arbitrary offsets).
static bool onlyAccessesInaccessibleOrArgMem(FunctionModRefBehavior MRB) {
- return !((unsigned)MRB & FMRL_Anywhere &
+ return !((unsigned)MRB & FMRL_Anywhere &
~(FMRL_InaccessibleMem | FMRL_ArgumentPointees));
}
@@ -790,7 +790,7 @@ private:
AAQueryInfo &AAQI);
ModRefInfo getModRefInfo(const Instruction *I,
const Optional<MemoryLocation> &OptLoc,
- AAQueryInfo &AAQIP);
+ AAQueryInfo &AAQIP);
class Concept;
@@ -804,9 +804,9 @@ private:
std::vector<AnalysisKey *> AADeps;
- /// Query depth used to distinguish recursive queries.
- unsigned Depth = 0;
-
+ /// Query depth used to distinguish recursive queries.
+ unsigned Depth = 0;
+
friend class BatchAAResults;
};
@@ -847,13 +847,13 @@ public:
FunctionModRefBehavior getModRefBehavior(const CallBase *Call) {
return AA.getModRefBehavior(Call);
}
- bool isMustAlias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
- return alias(LocA, LocB) == MustAlias;
- }
- bool isMustAlias(const Value *V1, const Value *V2) {
- return alias(MemoryLocation(V1, LocationSize::precise(1)),
- MemoryLocation(V2, LocationSize::precise(1))) == MustAlias;
- }
+ bool isMustAlias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
+ return alias(LocA, LocB) == MustAlias;
+ }
+ bool isMustAlias(const Value *V1, const Value *V2) {
+ return alias(MemoryLocation(V1, LocationSize::precise(1)),
+ MemoryLocation(V2, LocationSize::precise(1))) == MustAlias;
+ }
};
/// Temporary typedef for legacy code that uses a generic \c AliasAnalysis
@@ -1161,7 +1161,7 @@ public:
ResultGetters.push_back(&getModuleAAResultImpl<AnalysisT>);
}
- Result run(Function &F, FunctionAnalysisManager &AM);
+ Result run(Function &F, FunctionAnalysisManager &AM);
private:
friend AnalysisInfoMixin<AAManager>;
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/AliasSetTracker.h b/contrib/libs/llvm12/include/llvm/Analysis/AliasSetTracker.h
index fbd2e49f90..cdb54d310d 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/AliasSetTracker.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/AliasSetTracker.h
@@ -27,10 +27,10 @@
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
-#include "llvm/Analysis/MemoryLocation.h"
+#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Metadata.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Casting.h"
#include <cassert>
@@ -41,7 +41,7 @@
namespace llvm {
-class AAResults;
+class AAResults;
class AliasSetTracker;
class BasicBlock;
class LoadInst;
@@ -54,8 +54,8 @@ class StoreInst;
class VAArgInst;
class Value;
-enum AliasResult : uint8_t;
-
+enum AliasResult : uint8_t;
+
class AliasSet : public ilist_node<AliasSet> {
friend class AliasSetTracker;
@@ -304,7 +304,7 @@ private:
void addPointer(AliasSetTracker &AST, PointerRec &Entry, LocationSize Size,
const AAMDNodes &AAInfo, bool KnownMustAlias = false,
bool SkipSizeUpdate = false);
- void addUnknownInst(Instruction *I, AAResults &AA);
+ void addUnknownInst(Instruction *I, AAResults &AA);
void removeUnknownInst(AliasSetTracker &AST, Instruction *I) {
bool WasEmpty = UnknownInsts.empty();
@@ -322,8 +322,8 @@ public:
/// If the specified pointer "may" (or must) alias one of the members in the
/// set return the appropriate AliasResult. Otherwise return NoAlias.
AliasResult aliasesPointer(const Value *Ptr, LocationSize Size,
- const AAMDNodes &AAInfo, AAResults &AA) const;
- bool aliasesUnknownInst(const Instruction *Inst, AAResults &AA) const;
+ const AAMDNodes &AAInfo, AAResults &AA) const;
+ bool aliasesUnknownInst(const Instruction *Inst, AAResults &AA) const;
};
inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) {
@@ -349,7 +349,7 @@ class AliasSetTracker {
/// handle.
struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> {};
- AAResults &AA;
+ AAResults &AA;
MemorySSA *MSSA = nullptr;
Loop *L = nullptr;
ilist<AliasSet> AliasSets;
@@ -363,9 +363,9 @@ class AliasSetTracker {
public:
/// Create an empty collection of AliasSets, and use the specified alias
/// analysis object to disambiguate load and store addresses.
- explicit AliasSetTracker(AAResults &AA) : AA(AA) {}
- explicit AliasSetTracker(AAResults &AA, MemorySSA *MSSA, Loop *L)
- : AA(AA), MSSA(MSSA), L(L) {}
+ explicit AliasSetTracker(AAResults &AA) : AA(AA) {}
+ explicit AliasSetTracker(AAResults &AA, MemorySSA *MSSA, Loop *L)
+ : AA(AA), MSSA(MSSA), L(L) {}
~AliasSetTracker() { clear(); }
/// These methods are used to add different types of instructions to the alias
@@ -404,7 +404,7 @@ public:
AliasSet &getAliasSetFor(const MemoryLocation &MemLoc);
/// Return the underlying alias analysis object used by this tracker.
- AAResults &getAliasAnalysis() const { return AA; }
+ AAResults &getAliasAnalysis() const { return AA; }
/// This method is used to remove a pointer value from the AliasSetTracker
/// entirely. It should be used when an instruction is deleted from the
@@ -468,14 +468,14 @@ inline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker &AST) {
return OS;
}
-class AliasSetsPrinterPass : public PassInfoMixin<AliasSetsPrinterPass> {
- raw_ostream &OS;
-
-public:
- explicit AliasSetsPrinterPass(raw_ostream &OS);
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-
+class AliasSetsPrinterPass : public PassInfoMixin<AliasSetsPrinterPass> {
+ raw_ostream &OS;
+
+public:
+ explicit AliasSetsPrinterPass(raw_ostream &OS);
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
} // end namespace llvm
#endif // LLVM_ANALYSIS_ALIASSETTRACKER_H
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/AssumptionCache.h b/contrib/libs/llvm12/include/llvm/Analysis/AssumptionCache.h
index 906b4613a6..86dced7f30 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/AssumptionCache.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/AssumptionCache.h
@@ -52,7 +52,7 @@ public:
enum : unsigned { ExprResultIdx = std::numeric_limits<unsigned>::max() };
struct ResultElem {
- WeakVH Assume;
+ WeakVH Assume;
/// contains either ExprResultIdx or the index of the operand bundle
/// containing the knowledge.
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/BasicAliasAnalysis.h b/contrib/libs/llvm12/include/llvm/Analysis/BasicAliasAnalysis.h
index 206cc1f395..7557bd687b 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/BasicAliasAnalysis.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/BasicAliasAnalysis.h
@@ -124,9 +124,9 @@ private:
APInt Scale;
- // Context instruction to use when querying information about this index.
- const Instruction *CxtI;
-
+ // Context instruction to use when querying information about this index.
+ const Instruction *CxtI;
+
bool operator==(const VariableGEPIndex &Other) const {
return V == Other.V && ZExtBits == Other.ZExtBits &&
SExtBits == Other.SExtBits && Scale == Other.Scale;
@@ -135,17 +135,17 @@ private:
bool operator!=(const VariableGEPIndex &Other) const {
return !operator==(Other);
}
-
- void dump() const {
- print(dbgs());
- dbgs() << "\n";
- }
- void print(raw_ostream &OS) const {
- OS << "(V=" << V->getName()
- << ", zextbits=" << ZExtBits
- << ", sextbits=" << SExtBits
- << ", scale=" << Scale << ")";
- }
+
+ void dump() const {
+ print(dbgs());
+ dbgs() << "\n";
+ }
+ void print(raw_ostream &OS) const {
+ OS << "(V=" << V->getName()
+ << ", zextbits=" << ZExtBits
+ << ", sextbits=" << SExtBits
+ << ", scale=" << Scale << ")";
+ }
};
// Represents the internal structure of a GEP, decomposed into a base pointer,
@@ -153,29 +153,29 @@ private:
struct DecomposedGEP {
// Base pointer of the GEP
const Value *Base;
- // Total constant offset from base.
- APInt Offset;
+ // Total constant offset from base.
+ APInt Offset;
// Scaled variable (non-constant) indices.
SmallVector<VariableGEPIndex, 4> VarIndices;
// Is GEP index scale compile-time constant.
bool HasCompileTimeConstantScale;
-
- void dump() const {
- print(dbgs());
- dbgs() << "\n";
- }
- void print(raw_ostream &OS) const {
- OS << "(DecomposedGEP Base=" << Base->getName()
- << ", Offset=" << Offset
- << ", VarIndices=[";
- for (size_t i = 0; i < VarIndices.size(); i++) {
- if (i != 0)
- OS << ", ";
- VarIndices[i].print(OS);
- }
- OS << "], HasCompileTimeConstantScale=" << HasCompileTimeConstantScale
- << ")";
- }
+
+ void dump() const {
+ print(dbgs());
+ dbgs() << "\n";
+ }
+ void print(raw_ostream &OS) const {
+ OS << "(DecomposedGEP Base=" << Base->getName()
+ << ", Offset=" << Offset
+ << ", VarIndices=[";
+ for (size_t i = 0; i < VarIndices.size(); i++) {
+ if (i != 0)
+ OS << ", ";
+ VarIndices[i].print(OS);
+ }
+ OS << "], HasCompileTimeConstantScale=" << HasCompileTimeConstantScale
+ << ")";
+ }
};
/// Tracks phi nodes we have visited.
@@ -203,9 +203,9 @@ private:
const DataLayout &DL, unsigned Depth, AssumptionCache *AC,
DominatorTree *DT, bool &NSW, bool &NUW);
- static DecomposedGEP
- DecomposeGEPExpression(const Value *V, const DataLayout &DL,
- AssumptionCache *AC, DominatorTree *DT);
+ static DecomposedGEP
+ DecomposeGEPExpression(const Value *V, const DataLayout &DL,
+ AssumptionCache *AC, DominatorTree *DT);
static bool isGEPBaseAtNegativeOffset(const GEPOperator *GEPOp,
const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompObject,
@@ -239,23 +239,23 @@ private:
AliasResult aliasPHI(const PHINode *PN, LocationSize PNSize,
const AAMDNodes &PNAAInfo, const Value *V2,
LocationSize V2Size, const AAMDNodes &V2AAInfo,
- AAQueryInfo &AAQI);
+ AAQueryInfo &AAQI);
AliasResult aliasSelect(const SelectInst *SI, LocationSize SISize,
const AAMDNodes &SIAAInfo, const Value *V2,
LocationSize V2Size, const AAMDNodes &V2AAInfo,
- AAQueryInfo &AAQI);
+ AAQueryInfo &AAQI);
AliasResult aliasCheck(const Value *V1, LocationSize V1Size,
- const AAMDNodes &V1AATag, const Value *V2,
- LocationSize V2Size, const AAMDNodes &V2AATag,
- AAQueryInfo &AAQI);
-
- AliasResult aliasCheckRecursive(const Value *V1, LocationSize V1Size,
- const AAMDNodes &V1AATag, const Value *V2,
- LocationSize V2Size, const AAMDNodes &V2AATag,
- AAQueryInfo &AAQI, const Value *O1,
- const Value *O2);
+ const AAMDNodes &V1AATag, const Value *V2,
+ LocationSize V2Size, const AAMDNodes &V2AATag,
+ AAQueryInfo &AAQI);
+
+ AliasResult aliasCheckRecursive(const Value *V1, LocationSize V1Size,
+ const AAMDNodes &V1AATag, const Value *V2,
+ LocationSize V2Size, const AAMDNodes &V2AATag,
+ AAQueryInfo &AAQI, const Value *O1,
+ const Value *O2);
};
/// Analysis pass providing a never-invalidated alias analysis result.
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/contrib/libs/llvm12/include/llvm/Analysis/BlockFrequencyInfoImpl.h
index daf4db72b8..f5c9294263 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/BlockFrequencyInfoImpl.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/BlockFrequencyInfoImpl.h
@@ -176,7 +176,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, BlockMass X) {
/// algorithms for BlockFrequencyInfoImplBase. Only algorithms that depend on
/// the block type (or that call such algorithms) are skipped here.
///
-/// Nevertheless, the majority of the overall algorithm documentation lives with
+/// Nevertheless, the majority of the overall algorithm documentation lives with
/// BlockFrequencyInfoImpl. See there for details.
class BlockFrequencyInfoImplBase {
public:
@@ -465,7 +465,7 @@ public:
/// Analyze irreducible SCCs.
///
- /// Separate irreducible SCCs from \c G, which is an explicit graph of \c
+ /// Separate irreducible SCCs from \c G, which is an explicit graph of \c
/// OuterLoop (or the top-level function, if \c OuterLoop is \c nullptr).
/// Insert them into \a Loops before \c Insert.
///
@@ -713,7 +713,7 @@ void IrreducibleGraph::addEdges(const BlockNode &Node,
///
/// In addition to loops, this algorithm has limited support for irreducible
/// SCCs, which are SCCs with multiple entry blocks. Irreducible SCCs are
-/// discovered on the fly, and modelled as loops with multiple headers.
+/// discovered on the fly, and modelled as loops with multiple headers.
///
/// The headers of irreducible sub-SCCs consist of its entry blocks and all
/// nodes that are targets of a backedge within it (excluding backedges within
@@ -1253,7 +1253,7 @@ bool BlockFrequencyInfoImpl<BT>::computeMassInLoop(LoopData &Loop) {
}
}
// As a heuristic, if some headers don't have a weight, give them the
- // minimum weight seen (not to disrupt the existing trends too much by
+ // minimum weight seen (not to disrupt the existing trends too much by
// using a weight that's in the general range of the other headers' weights,
// and the minimum seems to perform better than the average.)
// FIXME: better update in the passes that drop the header weight.
@@ -1456,8 +1456,8 @@ void BlockFrequencyInfoImpl<BT>::verifyMatch(
BlockNode Node = Entry.second;
if (OtherValidNodes.count(BB)) {
BlockNode OtherNode = OtherValidNodes[BB];
- const auto &Freq = Freqs[Node.Index];
- const auto &OtherFreq = Other.Freqs[OtherNode.Index];
+ const auto &Freq = Freqs[Node.Index];
+ const auto &OtherFreq = Other.Freqs[OtherNode.Index];
if (Freq.Integer != OtherFreq.Integer) {
Match = false;
dbgs() << "Freq mismatch: " << bfi_detail::getBlockName(BB) << " "
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/BranchProbabilityInfo.h b/contrib/libs/llvm12/include/llvm/Analysis/BranchProbabilityInfo.h
index e4a8f76b59..beabd622a9 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/BranchProbabilityInfo.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/BranchProbabilityInfo.h
@@ -34,16 +34,16 @@
#include <algorithm>
#include <cassert>
#include <cstdint>
-#include <memory>
+#include <memory>
#include <utility>
namespace llvm {
class Function;
-class Loop;
+class Loop;
class LoopInfo;
class raw_ostream;
-class DominatorTree;
+class DominatorTree;
class PostDominatorTree;
class TargetLibraryInfo;
class Value;
@@ -60,79 +60,79 @@ class Value;
/// identify an edge, since we can have multiple edges from Src to Dst.
/// As an example, we can have a switch which jumps to Dst with value 0 and
/// value 10.
-///
-/// Process of computing branch probabilities can be logically viewed as three
-/// step process:
-///
-/// First, if there is a profile information associated with the branch then
-/// it is trivially translated to branch probabilities. There is one exception
-/// from this rule though. Probabilities for edges leading to "unreachable"
-/// blocks (blocks with the estimated weight not greater than
-/// UNREACHABLE_WEIGHT) are evaluated according to static estimation and
-/// override profile information. If no branch probabilities were calculated
-/// on this step then take the next one.
-///
-/// Second, estimate absolute execution weights for each block based on
-/// statically known information. Roots of such information are "cold",
-/// "unreachable", "noreturn" and "unwind" blocks. Those blocks get their
-/// weights set to BlockExecWeight::COLD, BlockExecWeight::UNREACHABLE,
-/// BlockExecWeight::NORETURN and BlockExecWeight::UNWIND respectively. Then the
-/// weights are propagated to the other blocks up the domination line. In
-/// addition, if all successors have estimated weights set then maximum of these
-/// weights assigned to the block itself (while this is not ideal heuristic in
-/// theory it's simple and works reasonably well in most cases) and the process
-/// repeats. Once the process of weights propagation converges branch
-/// probabilities are set for all such branches that have at least one successor
-/// with the weight set. Default execution weight (BlockExecWeight::DEFAULT) is
-/// used for any successors which doesn't have its weight set. For loop back
-/// branches we use their weights scaled by loop trip count equal to
-/// 'LBH_TAKEN_WEIGHT/LBH_NOTTAKEN_WEIGHT'.
-///
-/// Here is a simple example demonstrating how the described algorithm works.
-///
-/// BB1
-/// / \
-/// v v
-/// BB2 BB3
-/// / \
-/// v v
-/// ColdBB UnreachBB
-///
-/// Initially, ColdBB is associated with COLD_WEIGHT and UnreachBB with
-/// UNREACHABLE_WEIGHT. COLD_WEIGHT is set to BB2 as maximum between its
-/// successors. BB1 and BB3 has no explicit estimated weights and assumed to
-/// have DEFAULT_WEIGHT. Based on assigned weights branches will have the
-/// following probabilities:
-/// P(BB1->BB2) = COLD_WEIGHT/(COLD_WEIGHT + DEFAULT_WEIGHT) =
-/// 0xffff / (0xffff + 0xfffff) = 0.0588(5.9%)
-/// P(BB1->BB3) = DEFAULT_WEIGHT_WEIGHT/(COLD_WEIGHT + DEFAULT_WEIGHT) =
-/// 0xfffff / (0xffff + 0xfffff) = 0.941(94.1%)
-/// P(BB2->ColdBB) = COLD_WEIGHT/(COLD_WEIGHT + UNREACHABLE_WEIGHT) = 1(100%)
-/// P(BB2->UnreachBB) =
-/// UNREACHABLE_WEIGHT/(COLD_WEIGHT+UNREACHABLE_WEIGHT) = 0(0%)
-///
-/// If no branch probabilities were calculated on this step then take the next
-/// one.
-///
-/// Third, apply different kinds of local heuristics for each individual
-/// branch until first match. For example probability of a pointer to be null is
-/// estimated as PH_TAKEN_WEIGHT/(PH_TAKEN_WEIGHT + PH_NONTAKEN_WEIGHT). If
-/// no local heuristic has been matched then branch is left with no explicit
-/// probability set and assumed to have default probability.
+///
+/// Process of computing branch probabilities can be logically viewed as three
+/// step process:
+///
+/// First, if there is a profile information associated with the branch then
+/// it is trivially translated to branch probabilities. There is one exception
+/// from this rule though. Probabilities for edges leading to "unreachable"
+/// blocks (blocks with the estimated weight not greater than
+/// UNREACHABLE_WEIGHT) are evaluated according to static estimation and
+/// override profile information. If no branch probabilities were calculated
+/// on this step then take the next one.
+///
+/// Second, estimate absolute execution weights for each block based on
+/// statically known information. Roots of such information are "cold",
+/// "unreachable", "noreturn" and "unwind" blocks. Those blocks get their
+/// weights set to BlockExecWeight::COLD, BlockExecWeight::UNREACHABLE,
+/// BlockExecWeight::NORETURN and BlockExecWeight::UNWIND respectively. Then the
+/// weights are propagated to the other blocks up the domination line. In
+/// addition, if all successors have estimated weights set then maximum of these
+/// weights assigned to the block itself (while this is not ideal heuristic in
+/// theory it's simple and works reasonably well in most cases) and the process
+/// repeats. Once the process of weights propagation converges branch
+/// probabilities are set for all such branches that have at least one successor
+/// with the weight set. Default execution weight (BlockExecWeight::DEFAULT) is
+/// used for any successors which doesn't have its weight set. For loop back
+/// branches we use their weights scaled by loop trip count equal to
+/// 'LBH_TAKEN_WEIGHT/LBH_NOTTAKEN_WEIGHT'.
+///
+/// Here is a simple example demonstrating how the described algorithm works.
+///
+/// BB1
+/// / \
+/// v v
+/// BB2 BB3
+/// / \
+/// v v
+/// ColdBB UnreachBB
+///
+/// Initially, ColdBB is associated with COLD_WEIGHT and UnreachBB with
+/// UNREACHABLE_WEIGHT. COLD_WEIGHT is set to BB2 as maximum between its
+/// successors. BB1 and BB3 has no explicit estimated weights and assumed to
+/// have DEFAULT_WEIGHT. Based on assigned weights branches will have the
+/// following probabilities:
+/// P(BB1->BB2) = COLD_WEIGHT/(COLD_WEIGHT + DEFAULT_WEIGHT) =
+/// 0xffff / (0xffff + 0xfffff) = 0.0588(5.9%)
+/// P(BB1->BB3) = DEFAULT_WEIGHT_WEIGHT/(COLD_WEIGHT + DEFAULT_WEIGHT) =
+/// 0xfffff / (0xffff + 0xfffff) = 0.941(94.1%)
+/// P(BB2->ColdBB) = COLD_WEIGHT/(COLD_WEIGHT + UNREACHABLE_WEIGHT) = 1(100%)
+/// P(BB2->UnreachBB) =
+/// UNREACHABLE_WEIGHT/(COLD_WEIGHT+UNREACHABLE_WEIGHT) = 0(0%)
+///
+/// If no branch probabilities were calculated on this step then take the next
+/// one.
+///
+/// Third, apply different kinds of local heuristics for each individual
+/// branch until first match. For example probability of a pointer to be null is
+/// estimated as PH_TAKEN_WEIGHT/(PH_TAKEN_WEIGHT + PH_NONTAKEN_WEIGHT). If
+/// no local heuristic has been matched then branch is left with no explicit
+/// probability set and assumed to have default probability.
class BranchProbabilityInfo {
public:
BranchProbabilityInfo() = default;
BranchProbabilityInfo(const Function &F, const LoopInfo &LI,
const TargetLibraryInfo *TLI = nullptr,
- DominatorTree *DT = nullptr,
+ DominatorTree *DT = nullptr,
PostDominatorTree *PDT = nullptr) {
- calculate(F, LI, TLI, DT, PDT);
+ calculate(F, LI, TLI, DT, PDT);
}
BranchProbabilityInfo(BranchProbabilityInfo &&Arg)
: Probs(std::move(Arg.Probs)), LastF(Arg.LastF),
- EstimatedBlockWeight(std::move(Arg.EstimatedBlockWeight)) {}
+ EstimatedBlockWeight(std::move(Arg.EstimatedBlockWeight)) {}
BranchProbabilityInfo(const BranchProbabilityInfo &) = delete;
BranchProbabilityInfo &operator=(const BranchProbabilityInfo &) = delete;
@@ -140,7 +140,7 @@ public:
BranchProbabilityInfo &operator=(BranchProbabilityInfo &&RHS) {
releaseMemory();
Probs = std::move(RHS.Probs);
- EstimatedBlockWeight = std::move(RHS.EstimatedBlockWeight);
+ EstimatedBlockWeight = std::move(RHS.EstimatedBlockWeight);
return *this;
}
@@ -198,85 +198,85 @@ public:
void setEdgeProbability(const BasicBlock *Src,
const SmallVectorImpl<BranchProbability> &Probs);
- /// Copy outgoing edge probabilities from \p Src to \p Dst.
- ///
- /// This allows to keep probabilities unset for the destination if they were
- /// unset for source.
- void copyEdgeProbabilities(BasicBlock *Src, BasicBlock *Dst);
-
+ /// Copy outgoing edge probabilities from \p Src to \p Dst.
+ ///
+ /// This allows to keep probabilities unset for the destination if they were
+ /// unset for source.
+ void copyEdgeProbabilities(BasicBlock *Src, BasicBlock *Dst);
+
static BranchProbability getBranchProbStackProtector(bool IsLikely) {
static const BranchProbability LikelyProb((1u << 20) - 1, 1u << 20);
return IsLikely ? LikelyProb : LikelyProb.getCompl();
}
void calculate(const Function &F, const LoopInfo &LI,
- const TargetLibraryInfo *TLI, DominatorTree *DT,
- PostDominatorTree *PDT);
+ const TargetLibraryInfo *TLI, DominatorTree *DT,
+ PostDominatorTree *PDT);
/// Forget analysis results for the given basic block.
void eraseBlock(const BasicBlock *BB);
- // Data structure to track SCCs for handling irreducible loops.
- class SccInfo {
- // Enum of types to classify basic blocks in SCC. Basic block belonging to
- // SCC is 'Inner' until it is either 'Header' or 'Exiting'. Note that a
- // basic block can be 'Header' and 'Exiting' at the same time.
- enum SccBlockType {
- Inner = 0x0,
- Header = 0x1,
- Exiting = 0x2,
- };
- // Map of basic blocks to SCC IDs they belong to. If basic block doesn't
- // belong to any SCC it is not in the map.
- using SccMap = DenseMap<const BasicBlock *, int>;
- // Each basic block in SCC is attributed with one or several types from
- // SccBlockType. Map value has uint32_t type (instead of SccBlockType)
- // since basic block may be for example "Header" and "Exiting" at the same
- // time and we need to be able to keep more than one value from
- // SccBlockType.
- using SccBlockTypeMap = DenseMap<const BasicBlock *, uint32_t>;
- // Vector containing classification of basic blocks for all SCCs where i'th
- // vector element corresponds to SCC with ID equal to i.
- using SccBlockTypeMaps = std::vector<SccBlockTypeMap>;
-
+ // Data structure to track SCCs for handling irreducible loops.
+ class SccInfo {
+ // Enum of types to classify basic blocks in SCC. Basic block belonging to
+ // SCC is 'Inner' until it is either 'Header' or 'Exiting'. Note that a
+ // basic block can be 'Header' and 'Exiting' at the same time.
+ enum SccBlockType {
+ Inner = 0x0,
+ Header = 0x1,
+ Exiting = 0x2,
+ };
+ // Map of basic blocks to SCC IDs they belong to. If basic block doesn't
+ // belong to any SCC it is not in the map.
+ using SccMap = DenseMap<const BasicBlock *, int>;
+ // Each basic block in SCC is attributed with one or several types from
+ // SccBlockType. Map value has uint32_t type (instead of SccBlockType)
+ // since basic block may be for example "Header" and "Exiting" at the same
+ // time and we need to be able to keep more than one value from
+ // SccBlockType.
+ using SccBlockTypeMap = DenseMap<const BasicBlock *, uint32_t>;
+ // Vector containing classification of basic blocks for all SCCs where i'th
+ // vector element corresponds to SCC with ID equal to i.
+ using SccBlockTypeMaps = std::vector<SccBlockTypeMap>;
+
SccMap SccNums;
- SccBlockTypeMaps SccBlocks;
-
- public:
- explicit SccInfo(const Function &F);
-
- /// If \p BB belongs to some SCC then ID of that SCC is returned, otherwise
- /// -1 is returned. If \p BB belongs to more than one SCC at the same time
- /// result is undefined.
- int getSCCNum(const BasicBlock *BB) const;
- /// Returns true if \p BB is a 'header' block in SCC with \p SccNum ID,
- /// false otherwise.
- bool isSCCHeader(const BasicBlock *BB, int SccNum) const {
- return getSccBlockType(BB, SccNum) & Header;
- }
- /// Returns true if \p BB is an 'exiting' block in SCC with \p SccNum ID,
- /// false otherwise.
- bool isSCCExitingBlock(const BasicBlock *BB, int SccNum) const {
- return getSccBlockType(BB, SccNum) & Exiting;
- }
- /// Fills in \p Enters vector with all such blocks that don't belong to
- /// SCC with \p SccNum ID but there is an edge to a block belonging to the
- /// SCC.
- void getSccEnterBlocks(int SccNum,
- SmallVectorImpl<BasicBlock *> &Enters) const;
- /// Fills in \p Exits vector with all such blocks that don't belong to
- /// SCC with \p SccNum ID but there is an edge from a block belonging to the
- /// SCC.
- void getSccExitBlocks(int SccNum,
- SmallVectorImpl<BasicBlock *> &Exits) const;
-
- private:
- /// Returns \p BB's type according to classification given by SccBlockType
- /// enum. Please note that \p BB must belong to SSC with \p SccNum ID.
- uint32_t getSccBlockType(const BasicBlock *BB, int SccNum) const;
- /// Calculates \p BB's type and stores it in internal data structures for
- /// future use. Please note that \p BB must belong to SSC with \p SccNum ID.
- void calculateSccBlockType(const BasicBlock *BB, int SccNum);
+ SccBlockTypeMaps SccBlocks;
+
+ public:
+ explicit SccInfo(const Function &F);
+
+ /// If \p BB belongs to some SCC then ID of that SCC is returned, otherwise
+ /// -1 is returned. If \p BB belongs to more than one SCC at the same time
+ /// result is undefined.
+ int getSCCNum(const BasicBlock *BB) const;
+ /// Returns true if \p BB is a 'header' block in SCC with \p SccNum ID,
+ /// false otherwise.
+ bool isSCCHeader(const BasicBlock *BB, int SccNum) const {
+ return getSccBlockType(BB, SccNum) & Header;
+ }
+ /// Returns true if \p BB is an 'exiting' block in SCC with \p SccNum ID,
+ /// false otherwise.
+ bool isSCCExitingBlock(const BasicBlock *BB, int SccNum) const {
+ return getSccBlockType(BB, SccNum) & Exiting;
+ }
+ /// Fills in \p Enters vector with all such blocks that don't belong to
+ /// SCC with \p SccNum ID but there is an edge to a block belonging to the
+ /// SCC.
+ void getSccEnterBlocks(int SccNum,
+ SmallVectorImpl<BasicBlock *> &Enters) const;
+ /// Fills in \p Exits vector with all such blocks that don't belong to
+ /// SCC with \p SccNum ID but there is an edge from a block belonging to the
+ /// SCC.
+ void getSccExitBlocks(int SccNum,
+ SmallVectorImpl<BasicBlock *> &Exits) const;
+
+ private:
+ /// Returns \p BB's type according to classification given by SccBlockType
+ /// enum. Please note that \p BB must belong to SSC with \p SccNum ID.
+ uint32_t getSccBlockType(const BasicBlock *BB, int SccNum) const;
+ /// Calculates \p BB's type and stores it in internal data structures for
+ /// future use. Please note that \p BB must belong to SSC with \p SccNum ID.
+ void calculateSccBlockType(const BasicBlock *BB, int SccNum);
};
private:
@@ -295,35 +295,35 @@ private:
: CallbackVH(const_cast<Value *>(V)), BPI(BPI) {}
};
- /// Pair of Loop and SCC ID number. Used to unify handling of normal and
- /// SCC based loop representations.
- using LoopData = std::pair<Loop *, int>;
- /// Helper class to keep basic block along with its loop data information.
- class LoopBlock {
- public:
- explicit LoopBlock(const BasicBlock *BB, const LoopInfo &LI,
- const SccInfo &SccI);
-
- const BasicBlock *getBlock() const { return BB; }
- BasicBlock *getBlock() { return const_cast<BasicBlock *>(BB); }
- LoopData getLoopData() const { return LD; }
- Loop *getLoop() const { return LD.first; }
- int getSccNum() const { return LD.second; }
-
- bool belongsToLoop() const { return getLoop() || getSccNum() != -1; }
- bool belongsToSameLoop(const LoopBlock &LB) const {
- return (LB.getLoop() && getLoop() == LB.getLoop()) ||
- (LB.getSccNum() != -1 && getSccNum() == LB.getSccNum());
- }
-
- private:
- const BasicBlock *const BB = nullptr;
- LoopData LD = {nullptr, -1};
- };
-
- // Pair of LoopBlocks representing an edge from first to second block.
- using LoopEdge = std::pair<const LoopBlock &, const LoopBlock &>;
-
+ /// Pair of Loop and SCC ID number. Used to unify handling of normal and
+ /// SCC based loop representations.
+ using LoopData = std::pair<Loop *, int>;
+ /// Helper class to keep basic block along with its loop data information.
+ class LoopBlock {
+ public:
+ explicit LoopBlock(const BasicBlock *BB, const LoopInfo &LI,
+ const SccInfo &SccI);
+
+ const BasicBlock *getBlock() const { return BB; }
+ BasicBlock *getBlock() { return const_cast<BasicBlock *>(BB); }
+ LoopData getLoopData() const { return LD; }
+ Loop *getLoop() const { return LD.first; }
+ int getSccNum() const { return LD.second; }
+
+ bool belongsToLoop() const { return getLoop() || getSccNum() != -1; }
+ bool belongsToSameLoop(const LoopBlock &LB) const {
+ return (LB.getLoop() && getLoop() == LB.getLoop()) ||
+ (LB.getSccNum() != -1 && getSccNum() == LB.getSccNum());
+ }
+
+ private:
+ const BasicBlock *const BB = nullptr;
+ LoopData LD = {nullptr, -1};
+ };
+
+ // Pair of LoopBlocks representing an edge from first to second block.
+ using LoopEdge = std::pair<const LoopBlock &, const LoopBlock &>;
+
DenseSet<BasicBlockCallbackVH, DenseMapInfo<Value*>> Handles;
// Since we allow duplicate edges from one basic block to another, we use
@@ -335,88 +335,88 @@ private:
/// Track the last function we run over for printing.
const Function *LastF = nullptr;
- const LoopInfo *LI = nullptr;
-
- /// Keeps information about all SCCs in a function.
- std::unique_ptr<const SccInfo> SccI;
-
- /// Keeps mapping of a basic block to its estimated weight.
- SmallDenseMap<const BasicBlock *, uint32_t> EstimatedBlockWeight;
-
- /// Keeps mapping of a loop to estimated weight to enter the loop.
- SmallDenseMap<LoopData, uint32_t> EstimatedLoopWeight;
-
- /// Helper to construct LoopBlock for \p BB.
- LoopBlock getLoopBlock(const BasicBlock *BB) const {
- return LoopBlock(BB, *LI, *SccI.get());
- }
-
- /// Returns true if destination block belongs to some loop and source block is
- /// either doesn't belong to any loop or belongs to a loop which is not inner
- /// relative to the destination block.
- bool isLoopEnteringEdge(const LoopEdge &Edge) const;
- /// Returns true if source block belongs to some loop and destination block is
- /// either doesn't belong to any loop or belongs to a loop which is not inner
- /// relative to the source block.
- bool isLoopExitingEdge(const LoopEdge &Edge) const;
- /// Returns true if \p Edge is either enters to or exits from some loop, false
- /// in all other cases.
- bool isLoopEnteringExitingEdge(const LoopEdge &Edge) const;
- /// Returns true if source and destination blocks belongs to the same loop and
- /// destination block is loop header.
- bool isLoopBackEdge(const LoopEdge &Edge) const;
- // Fills in \p Enters vector with all "enter" blocks to a loop \LB belongs to.
- void getLoopEnterBlocks(const LoopBlock &LB,
- SmallVectorImpl<BasicBlock *> &Enters) const;
- // Fills in \p Exits vector with all "exit" blocks from a loop \LB belongs to.
- void getLoopExitBlocks(const LoopBlock &LB,
- SmallVectorImpl<BasicBlock *> &Exits) const;
-
- /// Returns estimated weight for \p BB. None if \p BB has no estimated weight.
- Optional<uint32_t> getEstimatedBlockWeight(const BasicBlock *BB) const;
-
- /// Returns estimated weight to enter \p L. In other words it is weight of
- /// loop's header block not scaled by trip count. Returns None if \p L has no
- /// no estimated weight.
- Optional<uint32_t> getEstimatedLoopWeight(const LoopData &L) const;
-
- /// Return estimated weight for \p Edge. Returns None if estimated weight is
- /// unknown.
- Optional<uint32_t> getEstimatedEdgeWeight(const LoopEdge &Edge) const;
-
- /// Iterates over all edges leading from \p SrcBB to \p Successors and
- /// returns maximum of all estimated weights. If at least one edge has unknown
- /// estimated weight None is returned.
- template <class IterT>
- Optional<uint32_t>
- getMaxEstimatedEdgeWeight(const LoopBlock &SrcBB,
- iterator_range<IterT> Successors) const;
-
- /// If \p LoopBB has no estimated weight then set it to \p BBWeight and
- /// return true. Otherwise \p BB's weight remains unchanged and false is
- /// returned. In addition all blocks/loops that might need their weight to be
- /// re-estimated are put into BlockWorkList/LoopWorkList.
- bool updateEstimatedBlockWeight(LoopBlock &LoopBB, uint32_t BBWeight,
- SmallVectorImpl<BasicBlock *> &BlockWorkList,
- SmallVectorImpl<LoopBlock> &LoopWorkList);
-
- /// Starting from \p LoopBB (including \p LoopBB itself) propagate \p BBWeight
- /// up the domination tree.
- void propagateEstimatedBlockWeight(const LoopBlock &LoopBB, DominatorTree *DT,
- PostDominatorTree *PDT, uint32_t BBWeight,
- SmallVectorImpl<BasicBlock *> &WorkList,
- SmallVectorImpl<LoopBlock> &LoopWorkList);
-
- /// Returns block's weight encoded in the IR.
- Optional<uint32_t> getInitialEstimatedBlockWeight(const BasicBlock *BB);
-
- // Computes estimated weights for all blocks in \p F.
- void computeEestimateBlockWeight(const Function &F, DominatorTree *DT,
- PostDominatorTree *PDT);
-
- /// Based on computed weights by \p computeEstimatedBlockWeight set
- /// probabilities on branches.
- bool calcEstimatedHeuristics(const BasicBlock *BB);
+ const LoopInfo *LI = nullptr;
+
+ /// Keeps information about all SCCs in a function.
+ std::unique_ptr<const SccInfo> SccI;
+
+ /// Keeps mapping of a basic block to its estimated weight.
+ SmallDenseMap<const BasicBlock *, uint32_t> EstimatedBlockWeight;
+
+ /// Keeps mapping of a loop to estimated weight to enter the loop.
+ SmallDenseMap<LoopData, uint32_t> EstimatedLoopWeight;
+
+ /// Helper to construct LoopBlock for \p BB.
+ LoopBlock getLoopBlock(const BasicBlock *BB) const {
+ return LoopBlock(BB, *LI, *SccI.get());
+ }
+
+ /// Returns true if destination block belongs to some loop and source block is
+ /// either doesn't belong to any loop or belongs to a loop which is not inner
+ /// relative to the destination block.
+ bool isLoopEnteringEdge(const LoopEdge &Edge) const;
+ /// Returns true if source block belongs to some loop and destination block is
+ /// either doesn't belong to any loop or belongs to a loop which is not inner
+ /// relative to the source block.
+ bool isLoopExitingEdge(const LoopEdge &Edge) const;
+ /// Returns true if \p Edge is either enters to or exits from some loop, false
+ /// in all other cases.
+ bool isLoopEnteringExitingEdge(const LoopEdge &Edge) const;
+ /// Returns true if source and destination blocks belongs to the same loop and
+ /// destination block is loop header.
+ bool isLoopBackEdge(const LoopEdge &Edge) const;
+ // Fills in \p Enters vector with all "enter" blocks to a loop \LB belongs to.
+ void getLoopEnterBlocks(const LoopBlock &LB,
+ SmallVectorImpl<BasicBlock *> &Enters) const;
+ // Fills in \p Exits vector with all "exit" blocks from a loop \LB belongs to.
+ void getLoopExitBlocks(const LoopBlock &LB,
+ SmallVectorImpl<BasicBlock *> &Exits) const;
+
+ /// Returns estimated weight for \p BB. None if \p BB has no estimated weight.
+ Optional<uint32_t> getEstimatedBlockWeight(const BasicBlock *BB) const;
+
+ /// Returns estimated weight to enter \p L. In other words it is weight of
+ /// loop's header block not scaled by trip count. Returns None if \p L has no
+ /// no estimated weight.
+ Optional<uint32_t> getEstimatedLoopWeight(const LoopData &L) const;
+
+ /// Return estimated weight for \p Edge. Returns None if estimated weight is
+ /// unknown.
+ Optional<uint32_t> getEstimatedEdgeWeight(const LoopEdge &Edge) const;
+
+ /// Iterates over all edges leading from \p SrcBB to \p Successors and
+ /// returns maximum of all estimated weights. If at least one edge has unknown
+ /// estimated weight None is returned.
+ template <class IterT>
+ Optional<uint32_t>
+ getMaxEstimatedEdgeWeight(const LoopBlock &SrcBB,
+ iterator_range<IterT> Successors) const;
+
+ /// If \p LoopBB has no estimated weight then set it to \p BBWeight and
+ /// return true. Otherwise \p BB's weight remains unchanged and false is
+ /// returned. In addition all blocks/loops that might need their weight to be
+ /// re-estimated are put into BlockWorkList/LoopWorkList.
+ bool updateEstimatedBlockWeight(LoopBlock &LoopBB, uint32_t BBWeight,
+ SmallVectorImpl<BasicBlock *> &BlockWorkList,
+ SmallVectorImpl<LoopBlock> &LoopWorkList);
+
+ /// Starting from \p LoopBB (including \p LoopBB itself) propagate \p BBWeight
+ /// up the domination tree.
+ void propagateEstimatedBlockWeight(const LoopBlock &LoopBB, DominatorTree *DT,
+ PostDominatorTree *PDT, uint32_t BBWeight,
+ SmallVectorImpl<BasicBlock *> &WorkList,
+ SmallVectorImpl<LoopBlock> &LoopWorkList);
+
+ /// Returns block's weight encoded in the IR.
+ Optional<uint32_t> getInitialEstimatedBlockWeight(const BasicBlock *BB);
+
+ // Computes estimated weights for all blocks in \p F.
+ void computeEestimateBlockWeight(const Function &F, DominatorTree *DT,
+ PostDominatorTree *PDT);
+
+ /// Based on computed weights by \p computeEstimatedBlockWeight set
+ /// probabilities on branches.
+ bool calcEstimatedHeuristics(const BasicBlock *BB);
bool calcMetadataWeights(const BasicBlock *BB);
bool calcPointerHeuristics(const BasicBlock *BB);
bool calcZeroHeuristics(const BasicBlock *BB, const TargetLibraryInfo *TLI);
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/CFGPrinter.h b/contrib/libs/llvm12/include/llvm/Analysis/CFGPrinter.h
index a790adc529..6547ac800d 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/CFGPrinter.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/CFGPrinter.h
@@ -25,7 +25,7 @@
#ifndef LLVM_ANALYSIS_CFGPRINTER_H
#define LLVM_ANALYSIS_CFGPRINTER_H
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/HeatUtils.h"
@@ -149,18 +149,18 @@ struct DOTGraphTraits<DOTFuncInfo *> : public DefaultDOTGraphTraits {
return OS.str();
}
- static void eraseComment(std::string &OutStr, unsigned &I, unsigned Idx) {
- OutStr.erase(OutStr.begin() + I, OutStr.begin() + Idx);
- --I;
- }
-
- static std::string getCompleteNodeLabel(
- const BasicBlock *Node, DOTFuncInfo *,
- llvm::function_ref<void(raw_string_ostream &, const BasicBlock &)>
- HandleBasicBlock = [](raw_string_ostream &OS,
- const BasicBlock &Node) -> void { OS << Node; },
- llvm::function_ref<void(std::string &, unsigned &, unsigned)>
- HandleComment = eraseComment) {
+ static void eraseComment(std::string &OutStr, unsigned &I, unsigned Idx) {
+ OutStr.erase(OutStr.begin() + I, OutStr.begin() + Idx);
+ --I;
+ }
+
+ static std::string getCompleteNodeLabel(
+ const BasicBlock *Node, DOTFuncInfo *,
+ llvm::function_ref<void(raw_string_ostream &, const BasicBlock &)>
+ HandleBasicBlock = [](raw_string_ostream &OS,
+ const BasicBlock &Node) -> void { OS << Node; },
+ llvm::function_ref<void(std::string &, unsigned &, unsigned)>
+ HandleComment = eraseComment) {
enum { MaxColumns = 80 };
std::string Str;
raw_string_ostream OS(Str);
@@ -170,7 +170,7 @@ struct DOTGraphTraits<DOTFuncInfo *> : public DefaultDOTGraphTraits {
OS << ":";
}
- HandleBasicBlock(OS, *Node);
+ HandleBasicBlock(OS, *Node);
std::string OutStr = OS.str();
if (OutStr[0] == '\n')
OutStr.erase(OutStr.begin());
@@ -186,7 +186,7 @@ struct DOTGraphTraits<DOTFuncInfo *> : public DefaultDOTGraphTraits {
LastSpace = 0;
} else if (OutStr[i] == ';') { // Delete comments!
unsigned Idx = OutStr.find('\n', i + 1); // Find end of line
- HandleComment(OutStr, i, Idx);
+ HandleComment(OutStr, i, Idx);
} else if (ColNum == MaxColumns) { // Wrap lines.
// Wrap very long names even though we can't find a space.
if (!LastSpace)
@@ -302,7 +302,7 @@ struct DOTGraphTraits<DOTFuncInfo *> : public DefaultDOTGraphTraits {
" fillcolor=\"" + Color + "70\"";
return Attrs;
}
- bool isNodeHidden(const BasicBlock *Node, const DOTFuncInfo *CFGInfo);
+ bool isNodeHidden(const BasicBlock *Node, const DOTFuncInfo *CFGInfo);
void computeHiddenNodes(const Function *F);
};
} // End llvm namespace
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/CGSCCPassManager.h b/contrib/libs/llvm12/include/llvm/Analysis/CGSCCPassManager.h
index b5154cae9b..5ef05f350a 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/CGSCCPassManager.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/CGSCCPassManager.h
@@ -97,7 +97,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/PriorityWorklist.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -322,16 +322,16 @@ struct CGSCCUpdateResult {
/// for a better technique.
SmallDenseSet<std::pair<LazyCallGraph::Node *, LazyCallGraph::SCC *>, 4>
&InlinedInternalEdges;
-
- /// Weak VHs to keep track of indirect calls for the purposes of detecting
- /// devirtualization.
- ///
- /// This is a map to avoid having duplicate entries. If a Value is
- /// deallocated, its corresponding WeakTrackingVH will be nulled out. When
- /// checking if a Value is in the map or not, also check if the corresponding
- /// WeakTrackingVH is null to avoid issues with a new Value sharing the same
- /// address as a deallocated one.
- SmallMapVector<Value *, WeakTrackingVH, 16> IndirectVHs;
+
+ /// Weak VHs to keep track of indirect calls for the purposes of detecting
+ /// devirtualization.
+ ///
+ /// This is a map to avoid having duplicate entries. If a Value is
+ /// deallocated, its corresponding WeakTrackingVH will be nulled out. When
+ /// checking if a Value is in the map or not, also check if the corresponding
+ /// WeakTrackingVH is null to avoid issues with a new Value sharing the same
+ /// address as a deallocated one.
+ SmallMapVector<Value *, WeakTrackingVH, 16> IndirectVHs;
};
/// The core module pass which does a post-order walk of the SCCs and
@@ -344,13 +344,13 @@ struct CGSCCUpdateResult {
/// pass over the module to enable a \c FunctionAnalysisManager to be used
/// within this run safely.
class ModuleToPostOrderCGSCCPassAdaptor
- : public PassInfoMixin<ModuleToPostOrderCGSCCPassAdaptor> {
+ : public PassInfoMixin<ModuleToPostOrderCGSCCPassAdaptor> {
public:
- using PassConceptT =
- detail::PassConcept<LazyCallGraph::SCC, CGSCCAnalysisManager,
- LazyCallGraph &, CGSCCUpdateResult &>;
-
- explicit ModuleToPostOrderCGSCCPassAdaptor(std::unique_ptr<PassConceptT> Pass)
+ using PassConceptT =
+ detail::PassConcept<LazyCallGraph::SCC, CGSCCAnalysisManager,
+ LazyCallGraph &, CGSCCUpdateResult &>;
+
+ explicit ModuleToPostOrderCGSCCPassAdaptor(std::unique_ptr<PassConceptT> Pass)
: Pass(std::move(Pass)) {}
ModuleToPostOrderCGSCCPassAdaptor(ModuleToPostOrderCGSCCPassAdaptor &&Arg)
@@ -370,22 +370,22 @@ public:
/// Runs the CGSCC pass across every SCC in the module.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
- static bool isRequired() { return true; }
-
+ static bool isRequired() { return true; }
+
private:
- std::unique_ptr<PassConceptT> Pass;
+ std::unique_ptr<PassConceptT> Pass;
};
/// A function to deduce a function pass type and wrap it in the
/// templated adaptor.
template <typename CGSCCPassT>
-ModuleToPostOrderCGSCCPassAdaptor
+ModuleToPostOrderCGSCCPassAdaptor
createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass) {
- using PassModelT = detail::PassModel<LazyCallGraph::SCC, CGSCCPassT,
- PreservedAnalyses, CGSCCAnalysisManager,
- LazyCallGraph &, CGSCCUpdateResult &>;
- return ModuleToPostOrderCGSCCPassAdaptor(
- std::make_unique<PassModelT>(std::move(Pass)));
+ using PassModelT = detail::PassModel<LazyCallGraph::SCC, CGSCCPassT,
+ PreservedAnalyses, CGSCCAnalysisManager,
+ LazyCallGraph &, CGSCCUpdateResult &>;
+ return ModuleToPostOrderCGSCCPassAdaptor(
+ std::make_unique<PassModelT>(std::move(Pass)));
}
/// A proxy from a \c FunctionAnalysisManager to an \c SCC.
@@ -464,11 +464,11 @@ LazyCallGraph::SCC &updateCGAndAnalysisManagerForCGSCCPass(
/// pass over the SCC to enable a \c FunctionAnalysisManager to be used
/// within this run safely.
class CGSCCToFunctionPassAdaptor
- : public PassInfoMixin<CGSCCToFunctionPassAdaptor> {
+ : public PassInfoMixin<CGSCCToFunctionPassAdaptor> {
public:
- using PassConceptT = detail::PassConcept<Function, FunctionAnalysisManager>;
-
- explicit CGSCCToFunctionPassAdaptor(std::unique_ptr<PassConceptT> Pass)
+ using PassConceptT = detail::PassConcept<Function, FunctionAnalysisManager>;
+
+ explicit CGSCCToFunctionPassAdaptor(std::unique_ptr<PassConceptT> Pass)
: Pass(std::move(Pass)) {}
CGSCCToFunctionPassAdaptor(CGSCCToFunctionPassAdaptor &&Arg)
@@ -486,24 +486,24 @@ public:
/// Runs the function pass across every function in the module.
PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
- LazyCallGraph &CG, CGSCCUpdateResult &UR);
+ LazyCallGraph &CG, CGSCCUpdateResult &UR);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
private:
- std::unique_ptr<PassConceptT> Pass;
+ std::unique_ptr<PassConceptT> Pass;
};
/// A function to deduce a function pass type and wrap it in the
/// templated adaptor.
template <typename FunctionPassT>
-CGSCCToFunctionPassAdaptor
+CGSCCToFunctionPassAdaptor
createCGSCCToFunctionPassAdaptor(FunctionPassT Pass) {
- using PassModelT =
- detail::PassModel<Function, FunctionPassT, PreservedAnalyses,
- FunctionAnalysisManager>;
- return CGSCCToFunctionPassAdaptor(
- std::make_unique<PassModelT>(std::move(Pass)));
+ using PassModelT =
+ detail::PassModel<Function, FunctionPassT, PreservedAnalyses,
+ FunctionAnalysisManager>;
+ return CGSCCToFunctionPassAdaptor(
+ std::make_unique<PassModelT>(std::move(Pass)));
}
/// A helper that repeats an SCC pass each time an indirect call is refined to
@@ -520,36 +520,36 @@ createCGSCCToFunctionPassAdaptor(FunctionPassT Pass) {
/// This repetition has the potential to be very large however, as each one
/// might refine a single call site. As a consequence, in practice we use an
/// upper bound on the number of repetitions to limit things.
-class DevirtSCCRepeatedPass : public PassInfoMixin<DevirtSCCRepeatedPass> {
+class DevirtSCCRepeatedPass : public PassInfoMixin<DevirtSCCRepeatedPass> {
public:
- using PassConceptT =
- detail::PassConcept<LazyCallGraph::SCC, CGSCCAnalysisManager,
- LazyCallGraph &, CGSCCUpdateResult &>;
-
- explicit DevirtSCCRepeatedPass(std::unique_ptr<PassConceptT> Pass,
- int MaxIterations)
+ using PassConceptT =
+ detail::PassConcept<LazyCallGraph::SCC, CGSCCAnalysisManager,
+ LazyCallGraph &, CGSCCUpdateResult &>;
+
+ explicit DevirtSCCRepeatedPass(std::unique_ptr<PassConceptT> Pass,
+ int MaxIterations)
: Pass(std::move(Pass)), MaxIterations(MaxIterations) {}
/// Runs the wrapped pass up to \c MaxIterations on the SCC, iterating
/// whenever an indirect call is refined.
PreservedAnalyses run(LazyCallGraph::SCC &InitialC, CGSCCAnalysisManager &AM,
- LazyCallGraph &CG, CGSCCUpdateResult &UR);
+ LazyCallGraph &CG, CGSCCUpdateResult &UR);
private:
- std::unique_ptr<PassConceptT> Pass;
+ std::unique_ptr<PassConceptT> Pass;
int MaxIterations;
};
/// A function to deduce a function pass type and wrap it in the
/// templated adaptor.
template <typename CGSCCPassT>
-DevirtSCCRepeatedPass createDevirtSCCRepeatedPass(CGSCCPassT Pass,
- int MaxIterations) {
- using PassModelT = detail::PassModel<LazyCallGraph::SCC, CGSCCPassT,
- PreservedAnalyses, CGSCCAnalysisManager,
- LazyCallGraph &, CGSCCUpdateResult &>;
- return DevirtSCCRepeatedPass(std::make_unique<PassModelT>(std::move(Pass)),
- MaxIterations);
+DevirtSCCRepeatedPass createDevirtSCCRepeatedPass(CGSCCPassT Pass,
+ int MaxIterations) {
+ using PassModelT = detail::PassModel<LazyCallGraph::SCC, CGSCCPassT,
+ PreservedAnalyses, CGSCCAnalysisManager,
+ LazyCallGraph &, CGSCCUpdateResult &>;
+ return DevirtSCCRepeatedPass(std::make_unique<PassModelT>(std::move(Pass)),
+ MaxIterations);
}
// Clear out the debug logging macro.
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/CaptureTracking.h b/contrib/libs/llvm12/include/llvm/Analysis/CaptureTracking.h
index 3fa0c98703..ed752e0e53 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/CaptureTracking.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/CaptureTracking.h
@@ -20,8 +20,8 @@
#ifndef LLVM_ANALYSIS_CAPTURETRACKING_H
#define LLVM_ANALYSIS_CAPTURETRACKING_H
-#include "llvm/ADT/DenseMap.h"
-
+#include "llvm/ADT/DenseMap.h"
+
namespace llvm {
class Value;
@@ -103,12 +103,12 @@ namespace llvm {
/// is zero, a default value is assumed.
void PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker,
unsigned MaxUsesToExplore = 0);
-
- /// Returns true if the pointer is to a function-local object that never
- /// escapes from the function.
- bool isNonEscapingLocalObject(
- const Value *V,
- SmallDenseMap<const Value *, bool, 8> *IsCapturedCache = nullptr);
+
+ /// Returns true if the pointer is to a function-local object that never
+ /// escapes from the function.
+ bool isNonEscapingLocalObject(
+ const Value *V,
+ SmallDenseMap<const Value *, bool, 8> *IsCapturedCache = nullptr);
} // end namespace llvm
#endif
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/CodeMetrics.h b/contrib/libs/llvm12/include/llvm/Analysis/CodeMetrics.h
index 3e39bad84e..c50218dc8b 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/CodeMetrics.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/CodeMetrics.h
@@ -82,8 +82,8 @@ struct CodeMetrics {
/// Add information about a block to the current state.
void analyzeBasicBlock(const BasicBlock *BB, const TargetTransformInfo &TTI,
- const SmallPtrSetImpl<const Value *> &EphValues,
- bool PrepareForLTO = false);
+ const SmallPtrSetImpl<const Value *> &EphValues,
+ bool PrepareForLTO = false);
/// Collect a loop's ephemeral values (those used only by an assume
/// or similar intrinsics in the loop).
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/ConstantFolding.h b/contrib/libs/llvm12/include/llvm/Analysis/ConstantFolding.h
index d2e598ab9a..aecf333a1d 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/ConstantFolding.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/ConstantFolding.h
@@ -32,7 +32,7 @@ template <typename T> class ArrayRef;
class CallBase;
class Constant;
class ConstantExpr;
-class DSOLocalEquivalent;
+class DSOLocalEquivalent;
class DataLayout;
class Function;
class GlobalValue;
@@ -42,11 +42,11 @@ class Type;
/// If this constant is a constant offset from a global, return the global and
/// the constant. Because of constantexprs, this function is recursive.
-/// If the global is part of a dso_local_equivalent constant, return it through
-/// `Equiv` if it is provided.
+/// If the global is part of a dso_local_equivalent constant, return it through
+/// `Equiv` if it is provided.
bool IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV, APInt &Offset,
- const DataLayout &DL,
- DSOLocalEquivalent **DSOEquiv = nullptr);
+ const DataLayout &DL,
+ DSOLocalEquivalent **DSOEquiv = nullptr);
/// ConstantFoldInstruction - Try to constant fold the specified instruction.
/// If successful, the constant result is returned, if not, null is returned.
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/ConstraintSystem.h b/contrib/libs/llvm12/include/llvm/Analysis/ConstraintSystem.h
index a2cd1b256d..11d353bb59 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/ConstraintSystem.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/ConstraintSystem.h
@@ -1,99 +1,99 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- ConstraintSystem.h - A system of linear constraints. --------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_CONSTRAINTSYSTEM_H
-#define LLVM_ANALYSIS_CONSTRAINTSYSTEM_H
-
-#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallVector.h"
-
-#include <string>
-
-namespace llvm {
-
-class ConstraintSystem {
- /// Current linear constraints in the system.
- /// An entry of the form c0, c1, ... cn represents the following constraint:
- /// c0 >= v0 * c1 + .... + v{n-1} * cn
- SmallVector<SmallVector<int64_t, 8>, 4> Constraints;
-
- /// Current greatest common divisor for all coefficients in the system.
- uint32_t GCD = 1;
-
- // Eliminate constraints from the system using Fourier–Motzkin elimination.
- bool eliminateUsingFM();
-
- /// Print the constraints in the system, using \p Names as variable names.
- void dump(ArrayRef<std::string> Names) const;
-
- /// Print the constraints in the system, using x0...xn as variable names.
- void dump() const;
-
- /// Returns true if there may be a solution for the constraints in the system.
- bool mayHaveSolutionImpl();
-
-public:
- bool addVariableRow(const SmallVector<int64_t, 8> &R) {
- assert(Constraints.empty() || R.size() == Constraints.back().size());
- // If all variable coefficients are 0, the constraint does not provide any
- // usable information.
- if (all_of(makeArrayRef(R).drop_front(1), [](int64_t C) { return C == 0; }))
- return false;
-
- for (const auto &C : R) {
- auto A = std::abs(C);
- GCD = APIntOps::GreatestCommonDivisor({32, (uint32_t)A}, {32, GCD})
- .getZExtValue();
- }
- Constraints.push_back(R);
- return true;
- }
-
- bool addVariableRowFill(const SmallVector<int64_t, 8> &R) {
- for (auto &CR : Constraints) {
- while (CR.size() != R.size())
- CR.push_back(0);
- }
- return addVariableRow(R);
- }
-
- /// Returns true if there may be a solution for the constraints in the system.
- bool mayHaveSolution();
-
- static SmallVector<int64_t, 8> negate(SmallVector<int64_t, 8> R) {
- // The negated constraint R is obtained by multiplying by -1 and adding 1 to
- // the constant.
- R[0] += 1;
- for (auto &C : R)
- C *= -1;
- return R;
- }
-
- bool isConditionImplied(SmallVector<int64_t, 8> R);
-
- void popLastConstraint() { Constraints.pop_back(); }
-
- /// Returns the number of rows in the constraint system.
- unsigned size() const { return Constraints.size(); }
-};
-} // namespace llvm
-
-#endif // LLVM_ANALYSIS_CONSTRAINTSYSTEM_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- ConstraintSystem.h - A system of linear constraints. --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CONSTRAINTSYSTEM_H
+#define LLVM_ANALYSIS_CONSTRAINTSYSTEM_H
+
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+
+#include <string>
+
+namespace llvm {
+
+class ConstraintSystem {
+ /// Current linear constraints in the system.
+ /// An entry of the form c0, c1, ... cn represents the following constraint:
+ /// c0 >= v0 * c1 + .... + v{n-1} * cn
+ SmallVector<SmallVector<int64_t, 8>, 4> Constraints;
+
+ /// Current greatest common divisor for all coefficients in the system.
+ uint32_t GCD = 1;
+
+ // Eliminate constraints from the system using Fourier–Motzkin elimination.
+ bool eliminateUsingFM();
+
+ /// Print the constraints in the system, using \p Names as variable names.
+ void dump(ArrayRef<std::string> Names) const;
+
+ /// Print the constraints in the system, using x0...xn as variable names.
+ void dump() const;
+
+ /// Returns true if there may be a solution for the constraints in the system.
+ bool mayHaveSolutionImpl();
+
+public:
+ bool addVariableRow(const SmallVector<int64_t, 8> &R) {
+ assert(Constraints.empty() || R.size() == Constraints.back().size());
+ // If all variable coefficients are 0, the constraint does not provide any
+ // usable information.
+ if (all_of(makeArrayRef(R).drop_front(1), [](int64_t C) { return C == 0; }))
+ return false;
+
+ for (const auto &C : R) {
+ auto A = std::abs(C);
+ GCD = APIntOps::GreatestCommonDivisor({32, (uint32_t)A}, {32, GCD})
+ .getZExtValue();
+ }
+ Constraints.push_back(R);
+ return true;
+ }
+
+ bool addVariableRowFill(const SmallVector<int64_t, 8> &R) {
+ for (auto &CR : Constraints) {
+ while (CR.size() != R.size())
+ CR.push_back(0);
+ }
+ return addVariableRow(R);
+ }
+
+ /// Returns true if there may be a solution for the constraints in the system.
+ bool mayHaveSolution();
+
+ static SmallVector<int64_t, 8> negate(SmallVector<int64_t, 8> R) {
+ // The negated constraint R is obtained by multiplying by -1 and adding 1 to
+ // the constant.
+ R[0] += 1;
+ for (auto &C : R)
+ C *= -1;
+ return R;
+ }
+
+ bool isConditionImplied(SmallVector<int64_t, 8> R);
+
+ void popLastConstraint() { Constraints.pop_back(); }
+
+ /// Returns the number of rows in the constraint system.
+ unsigned size() const { return Constraints.size(); }
+};
+} // namespace llvm
+
+#endif // LLVM_ANALYSIS_CONSTRAINTSYSTEM_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/DDG.h b/contrib/libs/llvm12/include/llvm/Analysis/DDG.h
index 280a2d10a6..7629ceee4a 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/DDG.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/DDG.h
@@ -159,7 +159,7 @@ private:
setKind((InstList.size() == 0 && Input.size() == 1)
? NodeKind::SingleInstruction
: NodeKind::MultiInstruction);
- llvm::append_range(InstList, Input);
+ llvm::append_range(InstList, Input);
}
void appendInstructions(const SimpleDDGNode &Input) {
appendInstructions(Input.getInstructions());
@@ -297,12 +297,12 @@ public:
bool getDependencies(const NodeType &Src, const NodeType &Dst,
DependenceList &Deps) const;
- /// Return a string representing the type of dependence that the dependence
- /// analysis identified between the two given nodes. This function assumes
- /// that there is a memory dependence between the given two nodes.
- const std::string getDependenceString(const NodeType &Src,
- const NodeType &Dst) const;
-
+ /// Return a string representing the type of dependence that the dependence
+ /// analysis identified between the two given nodes. This function assumes
+ /// that there is a memory dependence between the given two nodes.
+ const std::string getDependenceString(const NodeType &Src,
+ const NodeType &Dst) const;
+
protected:
// Name of the graph.
std::string Name;
@@ -476,26 +476,26 @@ bool DependenceGraphInfo<NodeType>::getDependencies(
return !Deps.empty();
}
-template <typename NodeType>
-const std::string
-DependenceGraphInfo<NodeType>::getDependenceString(const NodeType &Src,
- const NodeType &Dst) const {
- std::string Str;
- raw_string_ostream OS(Str);
- DependenceList Deps;
- if (!getDependencies(Src, Dst, Deps))
- return OS.str();
- interleaveComma(Deps, OS, [&](const std::unique_ptr<Dependence> &D) {
- D->dump(OS);
- // Remove the extra new-line character printed by the dump
- // method
- if (OS.str().back() == '\n')
- OS.str().pop_back();
- });
-
- return OS.str();
-}
-
+template <typename NodeType>
+const std::string
+DependenceGraphInfo<NodeType>::getDependenceString(const NodeType &Src,
+ const NodeType &Dst) const {
+ std::string Str;
+ raw_string_ostream OS(Str);
+ DependenceList Deps;
+ if (!getDependencies(Src, Dst, Deps))
+ return OS.str();
+ interleaveComma(Deps, OS, [&](const std::unique_ptr<Dependence> &D) {
+ D->dump(OS);
+ // Remove the extra new-line character printed by the dump
+ // method
+ if (OS.str().back() == '\n')
+ OS.str().pop_back();
+ });
+
+ return OS.str();
+}
+
//===--------------------------------------------------------------------===//
// GraphTraits specializations for the DDG
//===--------------------------------------------------------------------===//
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/DDGPrinter.h b/contrib/libs/llvm12/include/llvm/Analysis/DDGPrinter.h
index bffbefdab0..bb40d82d46 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/DDGPrinter.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/DDGPrinter.h
@@ -1,102 +1,102 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- llvm/Analysis/DDGPrinter.h -------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//
-// This file defines the DOT printer for the Data-Dependence Graph (DDG).
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_DDGPRINTER_H
-#define LLVM_ANALYSIS_DDGPRINTER_H
-
-#include "llvm/Analysis/DDG.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/DOTGraphTraits.h"
-
-namespace llvm {
-
-//===--------------------------------------------------------------------===//
-// Implementation of DDG DOT Printer for a loop.
-//===--------------------------------------------------------------------===//
-class DDGDotPrinterPass : public PassInfoMixin<DDGDotPrinterPass> {
-public:
- PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
- LoopStandardAnalysisResults &AR, LPMUpdater &U);
-};
-
-//===--------------------------------------------------------------------===//
-// Specialization of DOTGraphTraits.
-//===--------------------------------------------------------------------===//
-template <>
-struct DOTGraphTraits<const DataDependenceGraph *>
- : public DefaultDOTGraphTraits {
-
- DOTGraphTraits(bool IsSimple = false) : DefaultDOTGraphTraits(IsSimple) {}
-
- /// Generate a title for the graph in DOT format
- std::string getGraphName(const DataDependenceGraph *G) {
- assert(G && "expected a valid pointer to the graph.");
- return "DDG for '" + std::string(G->getName()) + "'";
- }
-
- /// Print a DDG node either in concise form (-ddg-dot-only) or
- /// verbose mode (-ddg-dot).
- std::string getNodeLabel(const DDGNode *Node,
- const DataDependenceGraph *Graph);
-
- /// Print attributes of an edge in the DDG graph. If the edge
- /// is a MemoryDependence edge, then detailed dependence info
- /// available from DependenceAnalysis is displayed.
- std::string
- getEdgeAttributes(const DDGNode *Node,
- GraphTraits<const DDGNode *>::ChildIteratorType I,
- const DataDependenceGraph *G);
-
- /// Do not print nodes that are part of a pi-block separately. They
- /// will be printed when their containing pi-block is being printed.
- bool isNodeHidden(const DDGNode *Node, const DataDependenceGraph *G);
-
-private:
- /// Print a DDG node in concise form.
- static std::string getSimpleNodeLabel(const DDGNode *Node,
- const DataDependenceGraph *G);
-
- /// Print a DDG node with more information including containing instructions
- /// and detailed information about the dependence edges.
- static std::string getVerboseNodeLabel(const DDGNode *Node,
- const DataDependenceGraph *G);
-
- /// Print a DDG edge in concise form.
- static std::string getSimpleEdgeAttributes(const DDGNode *Src,
- const DDGEdge *Edge,
- const DataDependenceGraph *G);
-
- /// Print a DDG edge with more information including detailed information
- /// about the dependence edges.
- static std::string getVerboseEdgeAttributes(const DDGNode *Src,
- const DDGEdge *Edge,
- const DataDependenceGraph *G);
-};
-
-using DDGDotGraphTraits = DOTGraphTraits<const DataDependenceGraph *>;
-
-} // namespace llvm
-
-#endif // LLVM_ANALYSIS_DDGPRINTER_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- llvm/Analysis/DDGPrinter.h -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//
+// This file defines the DOT printer for the Data-Dependence Graph (DDG).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DDGPRINTER_H
+#define LLVM_ANALYSIS_DDGPRINTER_H
+
+#include "llvm/Analysis/DDG.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/DOTGraphTraits.h"
+
+namespace llvm {
+
+//===--------------------------------------------------------------------===//
+// Implementation of DDG DOT Printer for a loop.
+//===--------------------------------------------------------------------===//
+class DDGDotPrinterPass : public PassInfoMixin<DDGDotPrinterPass> {
+public:
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
+};
+
+//===--------------------------------------------------------------------===//
+// Specialization of DOTGraphTraits.
+//===--------------------------------------------------------------------===//
+template <>
+struct DOTGraphTraits<const DataDependenceGraph *>
+ : public DefaultDOTGraphTraits {
+
+ DOTGraphTraits(bool IsSimple = false) : DefaultDOTGraphTraits(IsSimple) {}
+
+ /// Generate a title for the graph in DOT format
+ std::string getGraphName(const DataDependenceGraph *G) {
+ assert(G && "expected a valid pointer to the graph.");
+ return "DDG for '" + std::string(G->getName()) + "'";
+ }
+
+ /// Print a DDG node either in concise form (-ddg-dot-only) or
+ /// verbose mode (-ddg-dot).
+ std::string getNodeLabel(const DDGNode *Node,
+ const DataDependenceGraph *Graph);
+
+ /// Print attributes of an edge in the DDG graph. If the edge
+ /// is a MemoryDependence edge, then detailed dependence info
+ /// available from DependenceAnalysis is displayed.
+ std::string
+ getEdgeAttributes(const DDGNode *Node,
+ GraphTraits<const DDGNode *>::ChildIteratorType I,
+ const DataDependenceGraph *G);
+
+ /// Do not print nodes that are part of a pi-block separately. They
+ /// will be printed when their containing pi-block is being printed.
+ bool isNodeHidden(const DDGNode *Node, const DataDependenceGraph *G);
+
+private:
+ /// Print a DDG node in concise form.
+ static std::string getSimpleNodeLabel(const DDGNode *Node,
+ const DataDependenceGraph *G);
+
+ /// Print a DDG node with more information including containing instructions
+ /// and detailed information about the dependence edges.
+ static std::string getVerboseNodeLabel(const DDGNode *Node,
+ const DataDependenceGraph *G);
+
+ /// Print a DDG edge in concise form.
+ static std::string getSimpleEdgeAttributes(const DDGNode *Src,
+ const DDGEdge *Edge,
+ const DataDependenceGraph *G);
+
+ /// Print a DDG edge with more information including detailed information
+ /// about the dependence edges.
+ static std::string getVerboseEdgeAttributes(const DDGNode *Src,
+ const DDGEdge *Edge,
+ const DataDependenceGraph *G);
+};
+
+using DDGDotGraphTraits = DOTGraphTraits<const DataDependenceGraph *>;
+
+} // namespace llvm
+
+#endif // LLVM_ANALYSIS_DDGPRINTER_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/Delinearization.h b/contrib/libs/llvm12/include/llvm/Analysis/Delinearization.h
index 6fb0cb48c0..229eed3074 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/Delinearization.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/Delinearization.h
@@ -1,44 +1,44 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===---- Delinearization.h - MultiDimensional Index Delinearization ------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This implements an analysis pass that tries to delinearize all GEP
-// instructions in all loops using the SCEV analysis functionality. This pass is
-// only used for testing purposes: if your pass needs delinearization, please
-// use the on-demand SCEVAddRecExpr::delinearize() function.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_DELINEARIZATION_H
-#define LLVM_ANALYSIS_DELINEARIZATION_H
-
-#include "llvm/IR/PassManager.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace llvm {
-struct DelinearizationPrinterPass
- : public PassInfoMixin<DelinearizationPrinterPass> {
- explicit DelinearizationPrinterPass(raw_ostream &OS);
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-
-private:
- raw_ostream &OS;
-};
-} // namespace llvm
-
-#endif // LLVM_ANALYSIS_DELINEARIZATION_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===---- Delinearization.h - MultiDimensional Index Delinearization ------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This implements an analysis pass that tries to delinearize all GEP
+// instructions in all loops using the SCEV analysis functionality. This pass is
+// only used for testing purposes: if your pass needs delinearization, please
+// use the on-demand SCEVAddRecExpr::delinearize() function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DELINEARIZATION_H
+#define LLVM_ANALYSIS_DELINEARIZATION_H
+
+#include "llvm/IR/PassManager.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+struct DelinearizationPrinterPass
+ : public PassInfoMixin<DelinearizationPrinterPass> {
+ explicit DelinearizationPrinterPass(raw_ostream &OS);
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+
+private:
+ raw_ostream &OS;
+};
+} // namespace llvm
+
+#endif // LLVM_ANALYSIS_DELINEARIZATION_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/DemandedBits.h b/contrib/libs/llvm12/include/llvm/Analysis/DemandedBits.h
index 11046b7557..eb3cd20a42 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/DemandedBits.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/DemandedBits.h
@@ -68,20 +68,20 @@ public:
void print(raw_ostream &OS);
- /// Compute alive bits of one addition operand from alive output and known
- /// operand bits
- static APInt determineLiveOperandBitsAdd(unsigned OperandNo,
- const APInt &AOut,
- const KnownBits &LHS,
- const KnownBits &RHS);
-
- /// Compute alive bits of one subtraction operand from alive output and known
- /// operand bits
- static APInt determineLiveOperandBitsSub(unsigned OperandNo,
- const APInt &AOut,
- const KnownBits &LHS,
- const KnownBits &RHS);
-
+ /// Compute alive bits of one addition operand from alive output and known
+ /// operand bits
+ static APInt determineLiveOperandBitsAdd(unsigned OperandNo,
+ const APInt &AOut,
+ const KnownBits &LHS,
+ const KnownBits &RHS);
+
+ /// Compute alive bits of one subtraction operand from alive output and known
+ /// operand bits
+ static APInt determineLiveOperandBitsSub(unsigned OperandNo,
+ const APInt &AOut,
+ const KnownBits &LHS,
+ const KnownBits &RHS);
+
private:
void performAnalysis();
void determineLiveOperandBits(const Instruction *UserI,
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/DivergenceAnalysis.h b/contrib/libs/llvm12/include/llvm/Analysis/DivergenceAnalysis.h
index 6c84f9034b..b92ae823de 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/DivergenceAnalysis.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/DivergenceAnalysis.h
@@ -66,10 +66,10 @@ public:
/// \brief Mark \p UniVal as a value that is always uniform.
void addUniformOverride(const Value &UniVal);
- /// \brief Mark \p DivVal as a value that is always divergent. Will not do so
- /// if `isAlwaysUniform(DivVal)`.
- /// \returns Whether the tracked divergence state of \p DivVal changed.
- bool markDivergent(const Value &DivVal);
+ /// \brief Mark \p DivVal as a value that is always divergent. Will not do so
+ /// if `isAlwaysUniform(DivVal)`.
+ /// \returns Whether the tracked divergence state of \p DivVal changed.
+ bool markDivergent(const Value &DivVal);
/// \brief Propagate divergence to all instructions in the region.
/// Divergence is seeded by calls to \p markDivergent.
@@ -85,36 +85,36 @@ public:
/// \brief Whether \p Val is divergent at its definition.
bool isDivergent(const Value &Val) const;
- /// \brief Whether \p U is divergent. Uses of a uniform value can be
- /// divergent.
+ /// \brief Whether \p U is divergent. Uses of a uniform value can be
+ /// divergent.
bool isDivergentUse(const Use &U) const;
void print(raw_ostream &OS, const Module *) const;
private:
- /// \brief Mark \p Term as divergent and push all Instructions that become
- /// divergent as a result on the worklist.
- void analyzeControlDivergence(const Instruction &Term);
- /// \brief Mark all phi nodes in \p JoinBlock as divergent and push them on
- /// the worklist.
- void taintAndPushPhiNodes(const BasicBlock &JoinBlock);
-
- /// \brief Identify all Instructions that become divergent because \p DivExit
- /// is a divergent loop exit of \p DivLoop. Mark those instructions as
- /// divergent and push them on the worklist.
- void propagateLoopExitDivergence(const BasicBlock &DivExit,
- const Loop &DivLoop);
-
- /// \brief Internal implementation function for propagateLoopExitDivergence.
- void analyzeLoopExitDivergence(const BasicBlock &DivExit,
- const Loop &OuterDivLoop);
-
- /// \brief Mark all instruction as divergent that use a value defined in \p
- /// OuterDivLoop. Push their users on the worklist.
- void analyzeTemporalDivergence(const Instruction &I,
- const Loop &OuterDivLoop);
-
- /// \brief Push all users of \p Val (in the region) to the worklist.
+ /// \brief Mark \p Term as divergent and push all Instructions that become
+ /// divergent as a result on the worklist.
+ void analyzeControlDivergence(const Instruction &Term);
+ /// \brief Mark all phi nodes in \p JoinBlock as divergent and push them on
+ /// the worklist.
+ void taintAndPushPhiNodes(const BasicBlock &JoinBlock);
+
+ /// \brief Identify all Instructions that become divergent because \p DivExit
+ /// is a divergent loop exit of \p DivLoop. Mark those instructions as
+ /// divergent and push them on the worklist.
+ void propagateLoopExitDivergence(const BasicBlock &DivExit,
+ const Loop &DivLoop);
+
+ /// \brief Internal implementation function for propagateLoopExitDivergence.
+ void analyzeLoopExitDivergence(const BasicBlock &DivExit,
+ const Loop &OuterDivLoop);
+
+ /// \brief Mark all instruction as divergent that use a value defined in \p
+ /// OuterDivLoop. Push their users on the worklist.
+ void analyzeTemporalDivergence(const Instruction &I,
+ const Loop &OuterDivLoop);
+
+ /// \brief Push all users of \p Val (in the region) to the worklist.
void pushUsers(const Value &I);
/// \brief Whether \p Val is divergent when read in \p ObservingBlock.
@@ -125,7 +125,7 @@ private:
///
/// (see markBlockJoinDivergent).
bool isJoinDivergent(const BasicBlock &Block) const {
- return DivergentJoinBlocks.contains(&Block);
+ return DivergentJoinBlocks.contains(&Block);
}
private:
@@ -150,7 +150,7 @@ private:
DenseSet<const Value *> UniformOverrides;
// Blocks with joining divergent control from different predecessors.
- DenseSet<const BasicBlock *> DivergentJoinBlocks; // FIXME Deprecated
+ DenseSet<const BasicBlock *> DivergentJoinBlocks; // FIXME Deprecated
// Detected/marked divergent values.
DenseSet<const Value *> DivergentValues;
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/EHPersonalities.h b/contrib/libs/llvm12/include/llvm/Analysis/EHPersonalities.h
index b294409778..2961af091e 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/EHPersonalities.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/EHPersonalities.h
@@ -35,12 +35,12 @@ enum class EHPersonality {
GNU_CXX_SjLj,
GNU_ObjC,
MSVC_X86SEH,
- MSVC_TableSEH,
+ MSVC_TableSEH,
MSVC_CXX,
CoreCLR,
Rust,
- Wasm_CXX,
- XL_CXX
+ Wasm_CXX,
+ XL_CXX
};
/// See if the given exception handling personality function is one
@@ -59,7 +59,7 @@ inline bool isAsynchronousEHPersonality(EHPersonality Pers) {
// unknown personalities don't catch asynch exceptions.
switch (Pers) {
case EHPersonality::MSVC_X86SEH:
- case EHPersonality::MSVC_TableSEH:
+ case EHPersonality::MSVC_TableSEH:
return true;
default:
return false;
@@ -73,7 +73,7 @@ inline bool isFuncletEHPersonality(EHPersonality Pers) {
switch (Pers) {
case EHPersonality::MSVC_CXX:
case EHPersonality::MSVC_X86SEH:
- case EHPersonality::MSVC_TableSEH:
+ case EHPersonality::MSVC_TableSEH:
case EHPersonality::CoreCLR:
return true;
default:
@@ -88,7 +88,7 @@ inline bool isScopedEHPersonality(EHPersonality Pers) {
switch (Pers) {
case EHPersonality::MSVC_CXX:
case EHPersonality::MSVC_X86SEH:
- case EHPersonality::MSVC_TableSEH:
+ case EHPersonality::MSVC_TableSEH:
case EHPersonality::CoreCLR:
case EHPersonality::Wasm_CXX:
return true;
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/FunctionPropertiesAnalysis.h b/contrib/libs/llvm12/include/llvm/Analysis/FunctionPropertiesAnalysis.h
index 81bdf6fa7b..56a25af596 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/FunctionPropertiesAnalysis.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/FunctionPropertiesAnalysis.h
@@ -1,97 +1,97 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//=- FunctionPropertiesAnalysis.h - Function Properties Analysis --*- C++ -*-=//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the FunctionPropertiesInfo and FunctionPropertiesAnalysis
-// classes used to extract function properties.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FUNCTIONPROPERTIESANALYSIS_H_
-#define LLVM_FUNCTIONPROPERTIESANALYSIS_H_
-
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-class Function;
-
-class FunctionPropertiesInfo {
-public:
- static FunctionPropertiesInfo getFunctionPropertiesInfo(const Function &F,
- const LoopInfo &LI);
-
- void print(raw_ostream &OS) const;
-
- /// Number of basic blocks
- int64_t BasicBlockCount = 0;
-
- /// Number of blocks reached from a conditional instruction, or that are
- /// 'cases' of a SwitchInstr.
- // FIXME: We may want to replace this with a more meaningful metric, like
- // number of conditionally executed blocks:
- // 'if (a) s();' would be counted here as 2 blocks, just like
- // 'if (a) s(); else s2(); s3();' would.
- int64_t BlocksReachedFromConditionalInstruction = 0;
-
- /// Number of uses of this function, plus 1 if the function is callable
- /// outside the module.
- int64_t Uses = 0;
-
- /// Number of direct calls made from this function to other functions
- /// defined in this module.
- int64_t DirectCallsToDefinedFunctions = 0;
-
- // Load Instruction Count
- int64_t LoadInstCount = 0;
-
- // Store Instruction Count
- int64_t StoreInstCount = 0;
-
- // Maximum Loop Depth in the Function
- int64_t MaxLoopDepth = 0;
-
- // Number of Top Level Loops in the Function
- int64_t TopLevelLoopCount = 0;
-};
-
-// Analysis pass
-class FunctionPropertiesAnalysis
- : public AnalysisInfoMixin<FunctionPropertiesAnalysis> {
-
-public:
- static AnalysisKey Key;
-
- using Result = FunctionPropertiesInfo;
-
- Result run(Function &F, FunctionAnalysisManager &FAM);
-};
-
-/// Printer pass for the FunctionPropertiesAnalysis results.
-class FunctionPropertiesPrinterPass
- : public PassInfoMixin<FunctionPropertiesPrinterPass> {
- raw_ostream &OS;
-
-public:
- explicit FunctionPropertiesPrinterPass(raw_ostream &OS) : OS(OS) {}
-
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-
-} // namespace llvm
-#endif // LLVM_FUNCTIONPROPERTIESANALYSIS_H_
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//=- FunctionPropertiesAnalysis.h - Function Properties Analysis --*- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the FunctionPropertiesInfo and FunctionPropertiesAnalysis
+// classes used to extract function properties.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FUNCTIONPROPERTIESANALYSIS_H_
+#define LLVM_FUNCTIONPROPERTIESANALYSIS_H_
+
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+class Function;
+
+class FunctionPropertiesInfo {
+public:
+ static FunctionPropertiesInfo getFunctionPropertiesInfo(const Function &F,
+ const LoopInfo &LI);
+
+ void print(raw_ostream &OS) const;
+
+ /// Number of basic blocks
+ int64_t BasicBlockCount = 0;
+
+ /// Number of blocks reached from a conditional instruction, or that are
+ /// 'cases' of a SwitchInstr.
+ // FIXME: We may want to replace this with a more meaningful metric, like
+ // number of conditionally executed blocks:
+ // 'if (a) s();' would be counted here as 2 blocks, just like
+ // 'if (a) s(); else s2(); s3();' would.
+ int64_t BlocksReachedFromConditionalInstruction = 0;
+
+ /// Number of uses of this function, plus 1 if the function is callable
+ /// outside the module.
+ int64_t Uses = 0;
+
+ /// Number of direct calls made from this function to other functions
+ /// defined in this module.
+ int64_t DirectCallsToDefinedFunctions = 0;
+
+ // Load Instruction Count
+ int64_t LoadInstCount = 0;
+
+ // Store Instruction Count
+ int64_t StoreInstCount = 0;
+
+ // Maximum Loop Depth in the Function
+ int64_t MaxLoopDepth = 0;
+
+ // Number of Top Level Loops in the Function
+ int64_t TopLevelLoopCount = 0;
+};
+
+// Analysis pass
+class FunctionPropertiesAnalysis
+ : public AnalysisInfoMixin<FunctionPropertiesAnalysis> {
+
+public:
+ static AnalysisKey Key;
+
+ using Result = FunctionPropertiesInfo;
+
+ Result run(Function &F, FunctionAnalysisManager &FAM);
+};
+
+/// Printer pass for the FunctionPropertiesAnalysis results.
+class FunctionPropertiesPrinterPass
+ : public PassInfoMixin<FunctionPropertiesPrinterPass> {
+ raw_ostream &OS;
+
+public:
+ explicit FunctionPropertiesPrinterPass(raw_ostream &OS) : OS(OS) {}
+
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+} // namespace llvm
+#endif // LLVM_FUNCTIONPROPERTIESANALYSIS_H_
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/IRSimilarityIdentifier.h b/contrib/libs/llvm12/include/llvm/Analysis/IRSimilarityIdentifier.h
index 4544bfc8b9..6c765c5c00 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/IRSimilarityIdentifier.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/IRSimilarityIdentifier.h
@@ -1,800 +1,800 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- IRSimilarityIdentifier.h - Find similarity in a module --------------==//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// \file
-// Interface file for the IRSimilarityIdentifier for identifying similarities in
-// IR including the IRInstructionMapper, which maps an Instruction to unsigned
-// integers.
-//
-// Two sequences of instructions are called "similar" if they perform the same
-// series of operations for all inputs.
-//
-// \code
-// %1 = add i32 %a, 10
-// %2 = add i32 %a, %1
-// %3 = icmp slt icmp %1, %2
-// \endcode
-//
-// and
-//
-// \code
-// %1 = add i32 11, %a
-// %2 = sub i32 %a, %1
-// %3 = icmp sgt icmp %2, %1
-// \endcode
-//
-// ultimately have the same result, even if the inputs, and structure are
-// slightly different.
-//
-// For instructions, we do not worry about operands that do not have fixed
-// semantic meaning to the program. We consider the opcode that the instruction
-// has, the types, parameters, and extra information such as the function name,
-// or comparison predicate. These are used to create a hash to map instructions
-// to integers to be used in similarity matching in sequences of instructions
-//
-// Terminology:
-// An IRSimilarityCandidate is a region of IRInstructionData (wrapped
-// Instructions), usually used to denote a region of similarity has been found.
-//
-// A SimilarityGroup is a set of IRSimilarityCandidates that are structurally
-// similar to one another.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_IRSIMILARITYIDENTIFIER_H
-#define LLVM_ANALYSIS_IRSIMILARITYIDENTIFIER_H
-
-#include "llvm/IR/InstVisitor.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/PassManager.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/Allocator.h"
-
-namespace llvm {
-namespace IRSimilarity {
-
-struct IRInstructionDataList;
-
-/// This represents what is and is not supported when finding similarity in
-/// Instructions.
-///
-/// Legal Instructions are considered when looking at similarity between
-/// Instructions.
-///
-/// Illegal Instructions cannot be considered when looking for similarity
-/// between Instructions. They act as boundaries between similarity regions.
-///
-/// Invisible Instructions are skipped over during analysis.
-// TODO: Shared with MachineOutliner
-enum InstrType { Legal, Illegal, Invisible };
-
-/// This provides the utilities for hashing an Instruction to an unsigned
-/// integer. Two IRInstructionDatas produce the same hash value when their
-/// underlying Instructions perform the same operation (even if they don't have
-/// the same input operands.)
-/// As a more concrete example, consider the following:
-///
-/// \code
-/// %add1 = add i32 %a, %b
-/// %add2 = add i32 %c, %d
-/// %add3 = add i64 %e, %f
-/// \endcode
-///
-// Then the IRInstructionData wrappers for these Instructions may be hashed like
-/// so:
-///
-/// \code
-/// ; These two adds have the same types and operand types, so they hash to the
-/// ; same number.
-/// %add1 = add i32 %a, %b ; Hash: 1
-/// %add2 = add i32 %c, %d ; Hash: 1
-/// ; This add produces an i64. This differentiates it from %add1 and %add2. So,
-/// ; it hashes to a different number.
-/// %add3 = add i64 %e, %f; Hash: 2
-/// \endcode
-///
-///
-/// This hashing scheme will be used to represent the program as a very long
-/// string. This string can then be placed in a data structure which can be used
-/// for similarity queries.
-///
-/// TODO: Handle types of Instructions which can be equal even with different
-/// operands. (E.g. comparisons with swapped predicates.)
-/// TODO: Handle CallInsts, which are only checked for function type
-/// by \ref isSameOperationAs.
-/// TODO: Handle GetElementPtrInsts, as some of the operands have to be the
-/// exact same, and some do not.
-struct IRInstructionData : ilist_node<IRInstructionData> {
-
- /// The source Instruction that is being wrapped.
- Instruction *Inst = nullptr;
- /// The values of the operands in the Instruction.
- SmallVector<Value *, 4> OperVals;
- /// The legality of the wrapped instruction. This is informed by InstrType,
- /// and is used when checking when two instructions are considered similar.
- /// If either instruction is not legal, the instructions are automatically not
- /// considered similar.
- bool Legal;
-
- /// This is only relevant if we are wrapping a CmpInst where we needed to
- /// change the predicate of a compare instruction from a greater than form
- /// to a less than form. It is None otherwise.
- Optional<CmpInst::Predicate> RevisedPredicate;
-
- /// Gather the information that is difficult to gather for an Instruction, or
- /// is changed. i.e. the operands of an Instruction and the Types of those
- /// operands. This extra information allows for similarity matching to make
- /// assertions that allow for more flexibility when checking for whether an
- /// Instruction performs the same operation.
- IRInstructionData(Instruction &I, bool Legality, IRInstructionDataList &IDL);
-
- /// Get the predicate that the compare instruction is using for hashing the
- /// instruction. the IRInstructionData must be wrapping a CmpInst.
- CmpInst::Predicate getPredicate() const;
-
- /// A function that swaps the predicates to their less than form if they are
- /// in a greater than form. Otherwise, the predicate is unchanged.
- ///
- /// \param CI - The comparison operation to find a consistent preidcate for.
- /// \return the consistent comparison predicate.
- static CmpInst::Predicate predicateForConsistency(CmpInst *CI);
-
- /// Hashes \p Value based on its opcode, types, and operand types.
- /// Two IRInstructionData instances produce the same hash when they perform
- /// the same operation.
- ///
- /// As a simple example, consider the following instructions.
- ///
- /// \code
- /// %add1 = add i32 %x1, %y1
- /// %add2 = add i32 %x2, %y2
- ///
- /// %sub = sub i32 %x1, %y1
- ///
- /// %add_i64 = add i64 %x2, %y2
- /// \endcode
- ///
- /// Because the first two adds operate the same types, and are performing the
- /// same action, they will be hashed to the same value.
- ///
- /// However, the subtraction instruction is not the same as an addition, and
- /// will be hashed to a different value.
- ///
- /// Finally, the last add has a different type compared to the first two add
- /// instructions, so it will also be hashed to a different value that any of
- /// the previous instructions.
- ///
- /// \param [in] ID - The IRInstructionData instance to be hashed.
- /// \returns A hash_value of the IRInstructionData.
- friend hash_code hash_value(const IRInstructionData &ID) {
- SmallVector<Type *, 4> OperTypes;
- for (Value *V : ID.OperVals)
- OperTypes.push_back(V->getType());
-
- if (isa<CmpInst>(ID.Inst))
- return llvm::hash_combine(
- llvm::hash_value(ID.Inst->getOpcode()),
- llvm::hash_value(ID.Inst->getType()),
- llvm::hash_value(ID.getPredicate()),
- llvm::hash_combine_range(OperTypes.begin(), OperTypes.end()));
- else if (CallInst *CI = dyn_cast<CallInst>(ID.Inst))
- return llvm::hash_combine(
- llvm::hash_value(ID.Inst->getOpcode()),
- llvm::hash_value(ID.Inst->getType()),
- llvm::hash_value(CI->getCalledFunction()->getName().str()),
- llvm::hash_combine_range(OperTypes.begin(), OperTypes.end()));
- return llvm::hash_combine(
- llvm::hash_value(ID.Inst->getOpcode()),
- llvm::hash_value(ID.Inst->getType()),
- llvm::hash_combine_range(OperTypes.begin(), OperTypes.end()));
- }
-
- IRInstructionDataList *IDL = nullptr;
-};
-
-struct IRInstructionDataList : simple_ilist<IRInstructionData> {};
-
-/// Compare one IRInstructionData class to another IRInstructionData class for
-/// whether they are performing a the same operation, and can mapped to the
-/// same value. For regular instructions if the hash value is the same, then
-/// they will also be close.
-///
-/// \param A - The first IRInstructionData class to compare
-/// \param B - The second IRInstructionData class to compare
-/// \returns true if \p A and \p B are similar enough to be mapped to the same
-/// value.
-bool isClose(const IRInstructionData &A, const IRInstructionData &B);
-
-struct IRInstructionDataTraits : DenseMapInfo<IRInstructionData *> {
- static inline IRInstructionData *getEmptyKey() { return nullptr; }
- static inline IRInstructionData *getTombstoneKey() {
- return reinterpret_cast<IRInstructionData *>(-1);
- }
-
- static unsigned getHashValue(const IRInstructionData *E) {
- using llvm::hash_value;
- assert(E && "IRInstructionData is a nullptr?");
- return hash_value(*E);
- }
-
- static bool isEqual(const IRInstructionData *LHS,
- const IRInstructionData *RHS) {
- if (RHS == getEmptyKey() || RHS == getTombstoneKey() ||
- LHS == getEmptyKey() || LHS == getTombstoneKey())
- return LHS == RHS;
-
- assert(LHS && RHS && "nullptr should have been caught by getEmptyKey?");
- return isClose(*LHS, *RHS);
- }
-};
-
-/// Helper struct for converting the Instructions in a Module into a vector of
-/// unsigned integers. This vector of unsigned integers can be thought of as a
-/// "numeric string". This numeric string can then be queried by, for example,
-/// data structures that find repeated substrings.
-///
-/// This hashing is done per BasicBlock in the module. To hash Instructions
-/// based off of their operations, each Instruction is wrapped in an
-/// IRInstructionData struct. The unsigned integer for an IRInstructionData
-/// depends on:
-/// - The hash provided by the IRInstructionData.
-/// - Which member of InstrType the IRInstructionData is classified as.
-// See InstrType for more details on the possible classifications, and how they
-// manifest in the numeric string.
-///
-/// The numeric string for an individual BasicBlock is terminated by an unique
-/// unsigned integer. This prevents data structures which rely on repetition
-/// from matching across BasicBlocks. (For example, the SuffixTree.)
-/// As a concrete example, if we have the following two BasicBlocks:
-/// \code
-/// bb0:
-/// %add1 = add i32 %a, %b
-/// %add2 = add i32 %c, %d
-/// %add3 = add i64 %e, %f
-/// bb1:
-/// %sub = sub i32 %c, %d
-/// \endcode
-/// We may hash the Instructions like this (via IRInstructionData):
-/// \code
-/// bb0:
-/// %add1 = add i32 %a, %b ; Hash: 1
-/// %add2 = add i32 %c, %d; Hash: 1
-/// %add3 = add i64 %e, %f; Hash: 2
-/// bb1:
-/// %sub = sub i32 %c, %d; Hash: 3
-/// %add4 = add i32 %c, %d ; Hash: 1
-/// \endcode
-/// And produce a "numeric string representation" like so:
-/// 1, 1, 2, unique_integer_1, 3, 1, unique_integer_2
-///
-/// TODO: This is very similar to the MachineOutliner, and should be
-/// consolidated into the same interface.
-struct IRInstructionMapper {
- /// The starting illegal instruction number to map to.
- ///
- /// Set to -3 for compatibility with DenseMapInfo<unsigned>.
- unsigned IllegalInstrNumber = static_cast<unsigned>(-3);
-
- /// The next available integer to assign to a legal Instruction to.
- unsigned LegalInstrNumber = 0;
-
- /// Correspondence from IRInstructionData to unsigned integers.
- DenseMap<IRInstructionData *, unsigned, IRInstructionDataTraits>
- InstructionIntegerMap;
-
- /// Set if we added an illegal number in the previous step.
- /// Since each illegal number is unique, we only need one of them between
- /// each range of legal numbers. This lets us make sure we don't add more
- /// than one illegal number per range.
- bool AddedIllegalLastTime = false;
-
- /// Marks whether we found a illegal instruction in the previous step.
- bool CanCombineWithPrevInstr = false;
-
- /// Marks whether we have found a set of instructions that is long enough
- /// to be considered for similarity.
- bool HaveLegalRange = false;
-
- /// This allocator pointer is in charge of holding on to the IRInstructionData
- /// so it is not deallocated until whatever external tool is using it is done
- /// with the information.
- SpecificBumpPtrAllocator<IRInstructionData> *InstDataAllocator = nullptr;
-
- /// This allocator pointer is in charge of creating the IRInstructionDataList
- /// so it is not deallocated until whatever external tool is using it is done
- /// with the information.
- SpecificBumpPtrAllocator<IRInstructionDataList> *IDLAllocator = nullptr;
-
- /// Get an allocated IRInstructionData struct using the InstDataAllocator.
- ///
- /// \param I - The Instruction to wrap with IRInstructionData.
- /// \param Legality - A boolean value that is true if the instruction is to
- /// be considered for similarity, and false if not.
- /// \param IDL - The InstructionDataList that the IRInstructionData is
- /// inserted into.
- /// \returns An allocated IRInstructionData struct.
- IRInstructionData *allocateIRInstructionData(Instruction &I, bool Legality,
- IRInstructionDataList &IDL);
-
- /// Get an allocated IRInstructionDataList object using the IDLAllocator.
- ///
- /// \returns An allocated IRInstructionDataList object.
- IRInstructionDataList *allocateIRInstructionDataList();
-
- IRInstructionDataList *IDL = nullptr;
-
- /// Maps the Instructions in a BasicBlock \p BB to legal or illegal integers
- /// determined by \p InstrType. Two Instructions are mapped to the same value
- /// if they are close as defined by the InstructionData class above.
- ///
- /// \param [in] BB - The BasicBlock to be mapped to integers.
- /// \param [in,out] InstrList - Vector of IRInstructionData to append to.
- /// \param [in,out] IntegerMapping - Vector of unsigned integers to append to.
- void convertToUnsignedVec(BasicBlock &BB,
- std::vector<IRInstructionData *> &InstrList,
- std::vector<unsigned> &IntegerMapping);
-
- /// Maps an Instruction to a legal integer.
- ///
- /// \param [in] It - The Instruction to be mapped to an integer.
- /// \param [in,out] IntegerMappingForBB - Vector of unsigned integers to
- /// append to.
- /// \param [in,out] InstrListForBB - Vector of InstructionData to append to.
- /// \returns The integer \p It was mapped to.
- unsigned mapToLegalUnsigned(BasicBlock::iterator &It,
- std::vector<unsigned> &IntegerMappingForBB,
- std::vector<IRInstructionData *> &InstrListForBB);
-
- /// Maps an Instruction to an illegal integer.
- ///
- /// \param [in] It - The \p Instruction to be mapped to an integer.
- /// \param [in,out] IntegerMappingForBB - Vector of unsigned integers to
- /// append to.
- /// \param [in,out] InstrListForBB - Vector of IRInstructionData to append to.
- /// \param End - true if creating a dummy IRInstructionData at the end of a
- /// basic block.
- /// \returns The integer \p It was mapped to.
- unsigned mapToIllegalUnsigned(
- BasicBlock::iterator &It, std::vector<unsigned> &IntegerMappingForBB,
- std::vector<IRInstructionData *> &InstrListForBB, bool End = false);
-
- IRInstructionMapper(SpecificBumpPtrAllocator<IRInstructionData> *IDA,
- SpecificBumpPtrAllocator<IRInstructionDataList> *IDLA)
- : InstDataAllocator(IDA), IDLAllocator(IDLA) {
- // Make sure that the implementation of DenseMapInfo<unsigned> hasn't
- // changed.
- assert(DenseMapInfo<unsigned>::getEmptyKey() == static_cast<unsigned>(-1) &&
- "DenseMapInfo<unsigned>'s empty key isn't -1!");
- assert(DenseMapInfo<unsigned>::getTombstoneKey() ==
- static_cast<unsigned>(-2) &&
- "DenseMapInfo<unsigned>'s tombstone key isn't -2!");
-
- IDL = new (IDLAllocator->Allocate())
- IRInstructionDataList();
- }
-
- /// Custom InstVisitor to classify different instructions for whether it can
- /// be analyzed for similarity.
- struct InstructionClassification
- : public InstVisitor<InstructionClassification, InstrType> {
- InstructionClassification() {}
-
- // TODO: Determine a scheme to resolve when the label is similar enough.
- InstrType visitBranchInst(BranchInst &BI) { return Illegal; }
- // TODO: Determine a scheme to resolve when the labels are similar enough.
- InstrType visitPHINode(PHINode &PN) { return Illegal; }
- // TODO: Handle allocas.
- InstrType visitAllocaInst(AllocaInst &AI) { return Illegal; }
- // We exclude variable argument instructions since variable arguments
- // requires extra checking of the argument list.
- InstrType visitVAArgInst(VAArgInst &VI) { return Illegal; }
- // We exclude all exception handling cases since they are so context
- // dependent.
- InstrType visitLandingPadInst(LandingPadInst &LPI) { return Illegal; }
- InstrType visitFuncletPadInst(FuncletPadInst &FPI) { return Illegal; }
- // DebugInfo should be included in the regions, but should not be
- // analyzed for similarity as it has no bearing on the outcome of the
- // program.
- InstrType visitDbgInfoIntrinsic(DbgInfoIntrinsic &DII) { return Invisible; }
- // TODO: Handle specific intrinsics.
- InstrType visitIntrinsicInst(IntrinsicInst &II) { return Illegal; }
- // We only allow call instructions where the function has a name and
- // is not an indirect call.
- InstrType visitCallInst(CallInst &CI) {
- Function *F = CI.getCalledFunction();
- if (!F || CI.isIndirectCall() || !F->hasName())
- return Illegal;
- return Legal;
- }
- // TODO: We do not current handle similarity that changes the control flow.
- InstrType visitInvokeInst(InvokeInst &II) { return Illegal; }
- // TODO: We do not current handle similarity that changes the control flow.
- InstrType visitCallBrInst(CallBrInst &CBI) { return Illegal; }
- // TODO: Handle interblock similarity.
- InstrType visitTerminator(Instruction &I) { return Illegal; }
- InstrType visitInstruction(Instruction &I) { return Legal; }
- };
-
- /// Maps an Instruction to a member of InstrType.
- InstructionClassification InstClassifier;
-};
-
-/// This is a class that wraps a range of IRInstructionData from one point to
-/// another in the vector of IRInstructionData, which is a region of the
-/// program. It is also responsible for defining the structure within this
-/// region of instructions.
-///
-/// The structure of a region is defined through a value numbering system
-/// assigned to each unique value in a region at the creation of the
-/// IRSimilarityCandidate.
-///
-/// For example, for each Instruction we add a mapping for each new
-/// value seen in that Instruction.
-/// IR: Mapping Added:
-/// %add1 = add i32 %a, c1 %add1 -> 3, %a -> 1, c1 -> 2
-/// %add2 = add i32 %a, %1 %add2 -> 4
-/// %add3 = add i32 c2, c1 %add3 -> 6, c2 -> 5
-///
-/// We can compare IRSimilarityCandidates against one another.
-/// The \ref isSimilar function compares each IRInstructionData against one
-/// another and if we have the same sequences of IRInstructionData that would
-/// create the same hash, we have similar IRSimilarityCandidates.
-///
-/// We can also compare the structure of IRSimilarityCandidates. If we can
-/// create a mapping of registers in the region contained by one
-/// IRSimilarityCandidate to the region contained by different
-/// IRSimilarityCandidate, they can be considered structurally similar.
-///
-/// IRSimilarityCandidate1: IRSimilarityCandidate2:
-/// %add1 = add i32 %a, %b %add1 = add i32 %d, %e
-/// %add2 = add i32 %a, %c %add2 = add i32 %d, %f
-/// %add3 = add i32 c1, c2 %add3 = add i32 c3, c4
-///
-/// Can have the following mapping from candidate to candidate of:
-/// %a -> %d, %b -> %e, %c -> %f, c1 -> c3, c2 -> c4
-/// and can be considered similar.
-///
-/// IRSimilarityCandidate1: IRSimilarityCandidate2:
-/// %add1 = add i32 %a, %b %add1 = add i32 %d, c4
-/// %add2 = add i32 %a, %c %add2 = add i32 %d, %f
-/// %add3 = add i32 c1, c2 %add3 = add i32 c3, c4
-///
-/// We cannot create the same mapping since the use of c4 is not used in the
-/// same way as %b or c2.
-class IRSimilarityCandidate {
-private:
- /// The start index of this IRSimilarityCandidate in the instruction list.
- unsigned StartIdx = 0;
-
- /// The number of instructions in this IRSimilarityCandidate.
- unsigned Len = 0;
-
- /// The first instruction in this IRSimilarityCandidate.
- IRInstructionData *FirstInst = nullptr;
-
- /// The last instruction in this IRSimilarityCandidate.
- IRInstructionData *LastInst = nullptr;
-
- /// Global Value Numbering structures
- /// @{
- /// Stores the mapping of the value to the number assigned to it in the
- /// IRSimilarityCandidate.
- DenseMap<Value *, unsigned> ValueToNumber;
- /// Stores the mapping of the number to the value assigned this number.
- DenseMap<unsigned, Value *> NumberToValue;
- /// @}
-
-public:
- /// \param StartIdx - The starting location of the region.
- /// \param Len - The length of the region.
- /// \param FirstInstIt - The starting IRInstructionData of the region.
- /// \param LastInstIt - The ending IRInstructionData of the region.
- IRSimilarityCandidate(unsigned StartIdx, unsigned Len,
- IRInstructionData *FirstInstIt,
- IRInstructionData *LastInstIt);
-
- /// \param A - The first IRInstructionCandidate to compare.
- /// \param B - The second IRInstructionCandidate to compare.
- /// \returns True when every IRInstructionData in \p A is similar to every
- /// IRInstructionData in \p B.
- static bool isSimilar(const IRSimilarityCandidate &A,
- const IRSimilarityCandidate &B);
-
- /// \param A - The first IRInstructionCandidate to compare.
- /// \param B - The second IRInstructionCandidate to compare.
- /// \returns True when every IRInstructionData in \p A is structurally similar
- /// to \p B.
- static bool compareStructure(const IRSimilarityCandidate &A,
- const IRSimilarityCandidate &B);
-
- struct OperandMapping {
- /// The IRSimilarityCandidate that holds the instruction the OperVals were
- /// pulled from.
- const IRSimilarityCandidate &IRSC;
-
- /// The operand values to be analyzed.
- ArrayRef<Value *> &OperVals;
-
- /// The current mapping of global value numbers from one IRSimilarityCandidate
- /// to another IRSimilarityCandidate.
- DenseMap<unsigned, DenseSet<unsigned>> &ValueNumberMapping;
- };
-
- /// Compare the operands in \p A and \p B and check that the current mapping
- /// of global value numbers from \p A to \p B and \p B to \A is consistent.
- ///
- /// \param A - The first IRInstructionCandidate, operand values, and current
- /// operand mappings to compare.
- /// \param B - The second IRInstructionCandidate, operand values, and current
- /// operand mappings to compare.
- /// \returns true if the IRSimilarityCandidates operands are compatible.
- static bool compareNonCommutativeOperandMapping(OperandMapping A,
- OperandMapping B);
-
- /// Compare the operands in \p A and \p B and check that the current mapping
- /// of global value numbers from \p A to \p B and \p B to \A is consistent
- /// given that the operands are commutative.
- ///
- /// \param A - The first IRInstructionCandidate, operand values, and current
- /// operand mappings to compare.
- /// \param B - The second IRInstructionCandidate, operand values, and current
- /// operand mappings to compare.
- /// \returns true if the IRSimilarityCandidates operands are compatible.
- static bool compareCommutativeOperandMapping(OperandMapping A,
- OperandMapping B);
-
- /// Compare the start and end indices of the two IRSimilarityCandidates for
- /// whether they overlap. If the start instruction of one
- /// IRSimilarityCandidate is less than the end instruction of the other, and
- /// the start instruction of one is greater than the start instruction of the
- /// other, they overlap.
- ///
- /// \returns true if the IRSimilarityCandidates do not have overlapping
- /// instructions.
- static bool overlap(const IRSimilarityCandidate &A,
- const IRSimilarityCandidate &B);
-
- /// \returns the number of instructions in this Candidate.
- unsigned getLength() const { return Len; }
-
- /// \returns the start index of this IRSimilarityCandidate.
- unsigned getStartIdx() const { return StartIdx; }
-
- /// \returns the end index of this IRSimilarityCandidate.
- unsigned getEndIdx() const { return StartIdx + Len - 1; }
-
- /// \returns The first IRInstructionData.
- IRInstructionData *front() const { return FirstInst; }
- /// \returns The last IRInstructionData.
- IRInstructionData *back() const { return LastInst; }
-
- /// \returns The first Instruction.
- Instruction *frontInstruction() { return FirstInst->Inst; }
- /// \returns The last Instruction
- Instruction *backInstruction() { return LastInst->Inst; }
-
- /// \returns The BasicBlock the IRSimilarityCandidate starts in.
- BasicBlock *getStartBB() { return FirstInst->Inst->getParent(); }
- /// \returns The BasicBlock the IRSimilarityCandidate ends in.
- BasicBlock *getEndBB() { return LastInst->Inst->getParent(); }
-
- /// \returns The Function that the IRSimilarityCandidate is located in.
- Function *getFunction() { return getStartBB()->getParent(); }
-
- /// Finds the positive number associated with \p V if it has been mapped.
- /// \param [in] V - the Value to find.
- /// \returns The positive number corresponding to the value.
- /// \returns None if not present.
- Optional<unsigned> getGVN(Value *V) {
- assert(V != nullptr && "Value is a nullptr?");
- DenseMap<Value *, unsigned>::iterator VNIt = ValueToNumber.find(V);
- if (VNIt == ValueToNumber.end())
- return None;
- return VNIt->second;
- }
-
- /// Finds the Value associate with \p Num if it exists.
- /// \param [in] Num - the number to find.
- /// \returns The Value associated with the number.
- /// \returns None if not present.
- Optional<Value *> fromGVN(unsigned Num) {
- DenseMap<unsigned, Value *>::iterator VNIt = NumberToValue.find(Num);
- if (VNIt == NumberToValue.end())
- return None;
- assert(VNIt->second != nullptr && "Found value is a nullptr!");
- return VNIt->second;
- }
-
- /// \param RHS -The IRSimilarityCandidate to compare against
- /// \returns true if the IRSimilarityCandidate is occurs after the
- /// IRSimilarityCandidate in the program.
- bool operator<(const IRSimilarityCandidate &RHS) const {
- return getStartIdx() > RHS.getStartIdx();
- }
-
- using iterator = IRInstructionDataList::iterator;
- iterator begin() const { return iterator(front()); }
- iterator end() const { return std::next(iterator(back())); }
-};
-
-typedef std::vector<IRSimilarityCandidate> SimilarityGroup;
-typedef std::vector<SimilarityGroup> SimilarityGroupList;
-
-/// This class puts all the pieces of the IRInstructionData,
-/// IRInstructionMapper, IRSimilarityCandidate together.
-///
-/// It first feeds the Module or vector of Modules into the IRInstructionMapper,
-/// and puts all the mapped instructions into a single long list of
-/// IRInstructionData.
-///
-/// The list of unsigned integers is given to the Suffix Tree or similar data
-/// structure to find repeated subsequences. We construct an
-/// IRSimilarityCandidate for each instance of the subsequence. We compare them
-/// against one another since These repeated subsequences can have different
-/// structure. For each different kind of structure found, we create a
-/// similarity group.
-///
-/// If we had four IRSimilarityCandidates A, B, C, and D where A, B and D are
-/// structurally similar to one another, while C is different we would have two
-/// SimilarityGroups:
-///
-/// SimilarityGroup 1: SimilarityGroup 2
-/// A, B, D C
-///
-/// A list of the different similarity groups is then returned after
-/// analyzing the module.
-class IRSimilarityIdentifier {
-public:
- IRSimilarityIdentifier()
- : Mapper(&InstDataAllocator, &InstDataListAllocator) {}
-
- /// \param M the module to find similarity in.
- explicit IRSimilarityIdentifier(Module &M)
- : Mapper(&InstDataAllocator, &InstDataListAllocator) {
- findSimilarity(M);
- }
-
-private:
- /// Map the instructions in the module to unsigned integers, using mapping
- /// already present in the Mapper if possible.
- ///
- /// \param [in] M Module - To map to integers.
- /// \param [in,out] InstrList - The vector to append IRInstructionData to.
- /// \param [in,out] IntegerMapping - The vector to append integers to.
- void populateMapper(Module &M, std::vector<IRInstructionData *> &InstrList,
- std::vector<unsigned> &IntegerMapping);
-
- /// Map the instructions in the modules vector to unsigned integers, using
- /// mapping already present in the mapper if possible.
- ///
- /// \param [in] Modules - The list of modules to use to populate the mapper
- /// \param [in,out] InstrList - The vector to append IRInstructionData to.
- /// \param [in,out] IntegerMapping - The vector to append integers to.
- void populateMapper(ArrayRef<std::unique_ptr<Module>> &Modules,
- std::vector<IRInstructionData *> &InstrList,
- std::vector<unsigned> &IntegerMapping);
-
- /// Find the similarity candidates in \p InstrList and corresponding
- /// \p UnsignedVec
- ///
- /// \param [in,out] InstrList - The vector to append IRInstructionData to.
- /// \param [in,out] IntegerMapping - The vector to append integers to.
- /// candidates found in the program.
- void findCandidates(std::vector<IRInstructionData *> &InstrList,
- std::vector<unsigned> &IntegerMapping);
-
-public:
- // Find the IRSimilarityCandidates in the \p Modules and group by structural
- // similarity in a SimilarityGroup, each group is returned in a
- // SimilarityGroupList.
- //
- // \param [in] Modules - the modules to analyze.
- // \returns The groups of similarity ranges found in the modules.
- SimilarityGroupList &
- findSimilarity(ArrayRef<std::unique_ptr<Module>> Modules);
-
- // Find the IRSimilarityCandidates in the given Module grouped by structural
- // similarity in a SimilarityGroup, contained inside a SimilarityGroupList.
- //
- // \param [in] M - the module to analyze.
- // \returns The groups of similarity ranges found in the module.
- SimilarityGroupList &findSimilarity(Module &M);
-
- // Clears \ref SimilarityCandidates if it is already filled by a previous run.
- void resetSimilarityCandidates() {
- // If we've already analyzed a Module or set of Modules, so we must clear
- // the SimilarityCandidates to make sure we do not have only old values
- // hanging around.
- if (SimilarityCandidates.hasValue())
- SimilarityCandidates->clear();
- else
- SimilarityCandidates = SimilarityGroupList();
- }
-
- // \returns The groups of similarity ranges found in the most recently passed
- // set of modules.
- Optional<SimilarityGroupList> &getSimilarity() {
- return SimilarityCandidates;
- }
-
-private:
- /// The allocator for IRInstructionData.
- SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-
- /// The allocator for IRInstructionDataLists.
- SpecificBumpPtrAllocator<IRInstructionDataList> InstDataListAllocator;
-
- /// Map Instructions to unsigned integers and wraps the Instruction in an
- /// instance of IRInstructionData.
- IRInstructionMapper Mapper;
-
- /// The SimilarityGroups found with the most recent run of \ref
- /// findSimilarity. None if there is no recent run.
- Optional<SimilarityGroupList> SimilarityCandidates;
-};
-
-} // end namespace IRSimilarity
-
-/// An analysis pass based on legacy pass manager that runs and returns
-/// IRSimilarityIdentifier run on the Module.
-class IRSimilarityIdentifierWrapperPass : public ModulePass {
- std::unique_ptr<IRSimilarity::IRSimilarityIdentifier> IRSI;
-
-public:
- static char ID;
- IRSimilarityIdentifierWrapperPass();
-
- IRSimilarity::IRSimilarityIdentifier &getIRSI() { return *IRSI; }
- const IRSimilarity::IRSimilarityIdentifier &getIRSI() const { return *IRSI; }
-
- bool doInitialization(Module &M) override;
- bool doFinalization(Module &M) override;
- bool runOnModule(Module &M) override;
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- }
-};
-
-/// An analysis pass that runs and returns the IRSimilarityIdentifier run on the
-/// Module.
-class IRSimilarityAnalysis : public AnalysisInfoMixin<IRSimilarityAnalysis> {
-public:
- typedef IRSimilarity::IRSimilarityIdentifier Result;
-
- Result run(Module &M, ModuleAnalysisManager &);
-
-private:
- friend AnalysisInfoMixin<IRSimilarityAnalysis>;
- static AnalysisKey Key;
-};
-
-/// Printer pass that uses \c IRSimilarityAnalysis.
-class IRSimilarityAnalysisPrinterPass
- : public PassInfoMixin<IRSimilarityAnalysisPrinterPass> {
- raw_ostream &OS;
-
-public:
- explicit IRSimilarityAnalysisPrinterPass(raw_ostream &OS) : OS(OS) {}
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-};
-
-} // end namespace llvm
-
-#endif // LLVM_ANALYSIS_IRSIMILARITYIDENTIFIER_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- IRSimilarityIdentifier.h - Find similarity in a module --------------==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// \file
+// Interface file for the IRSimilarityIdentifier for identifying similarities in
+// IR including the IRInstructionMapper, which maps an Instruction to unsigned
+// integers.
+//
+// Two sequences of instructions are called "similar" if they perform the same
+// series of operations for all inputs.
+//
+// \code
+// %1 = add i32 %a, 10
+// %2 = add i32 %a, %1
+// %3 = icmp slt icmp %1, %2
+// \endcode
+//
+// and
+//
+// \code
+// %1 = add i32 11, %a
+// %2 = sub i32 %a, %1
+// %3 = icmp sgt icmp %2, %1
+// \endcode
+//
+// ultimately have the same result, even if the inputs, and structure are
+// slightly different.
+//
+// For instructions, we do not worry about operands that do not have fixed
+// semantic meaning to the program. We consider the opcode that the instruction
+// has, the types, parameters, and extra information such as the function name,
+// or comparison predicate. These are used to create a hash to map instructions
+// to integers to be used in similarity matching in sequences of instructions
+//
+// Terminology:
+// An IRSimilarityCandidate is a region of IRInstructionData (wrapped
+// Instructions), usually used to denote a region of similarity has been found.
+//
+// A SimilarityGroup is a set of IRSimilarityCandidates that are structurally
+// similar to one another.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_IRSIMILARITYIDENTIFIER_H
+#define LLVM_ANALYSIS_IRSIMILARITYIDENTIFIER_H
+
+#include "llvm/IR/InstVisitor.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Allocator.h"
+
+namespace llvm {
+namespace IRSimilarity {
+
+struct IRInstructionDataList;
+
+/// This represents what is and is not supported when finding similarity in
+/// Instructions.
+///
+/// Legal Instructions are considered when looking at similarity between
+/// Instructions.
+///
+/// Illegal Instructions cannot be considered when looking for similarity
+/// between Instructions. They act as boundaries between similarity regions.
+///
+/// Invisible Instructions are skipped over during analysis.
+// TODO: Shared with MachineOutliner
+enum InstrType { Legal, Illegal, Invisible };
+
+/// This provides the utilities for hashing an Instruction to an unsigned
+/// integer. Two IRInstructionDatas produce the same hash value when their
+/// underlying Instructions perform the same operation (even if they don't have
+/// the same input operands.)
+/// As a more concrete example, consider the following:
+///
+/// \code
+/// %add1 = add i32 %a, %b
+/// %add2 = add i32 %c, %d
+/// %add3 = add i64 %e, %f
+/// \endcode
+///
+// Then the IRInstructionData wrappers for these Instructions may be hashed like
+/// so:
+///
+/// \code
+/// ; These two adds have the same types and operand types, so they hash to the
+/// ; same number.
+/// %add1 = add i32 %a, %b ; Hash: 1
+/// %add2 = add i32 %c, %d ; Hash: 1
+/// ; This add produces an i64. This differentiates it from %add1 and %add2. So,
+/// ; it hashes to a different number.
+/// %add3 = add i64 %e, %f; Hash: 2
+/// \endcode
+///
+///
+/// This hashing scheme will be used to represent the program as a very long
+/// string. This string can then be placed in a data structure which can be used
+/// for similarity queries.
+///
+/// TODO: Handle types of Instructions which can be equal even with different
+/// operands. (E.g. comparisons with swapped predicates.)
+/// TODO: Handle CallInsts, which are only checked for function type
+/// by \ref isSameOperationAs.
+/// TODO: Handle GetElementPtrInsts, as some of the operands have to be the
+/// exact same, and some do not.
+struct IRInstructionData : ilist_node<IRInstructionData> {
+
+ /// The source Instruction that is being wrapped.
+ Instruction *Inst = nullptr;
+ /// The values of the operands in the Instruction.
+ SmallVector<Value *, 4> OperVals;
+ /// The legality of the wrapped instruction. This is informed by InstrType,
+ /// and is used when checking when two instructions are considered similar.
+ /// If either instruction is not legal, the instructions are automatically not
+ /// considered similar.
+ bool Legal;
+
+ /// This is only relevant if we are wrapping a CmpInst where we needed to
+ /// change the predicate of a compare instruction from a greater than form
+ /// to a less than form. It is None otherwise.
+ Optional<CmpInst::Predicate> RevisedPredicate;
+
+ /// Gather the information that is difficult to gather for an Instruction, or
+ /// is changed. i.e. the operands of an Instruction and the Types of those
+ /// operands. This extra information allows for similarity matching to make
+ /// assertions that allow for more flexibility when checking for whether an
+ /// Instruction performs the same operation.
+ IRInstructionData(Instruction &I, bool Legality, IRInstructionDataList &IDL);
+
+ /// Get the predicate that the compare instruction is using for hashing the
+ /// instruction. the IRInstructionData must be wrapping a CmpInst.
+ CmpInst::Predicate getPredicate() const;
+
+ /// A function that swaps the predicates to their less than form if they are
+ /// in a greater than form. Otherwise, the predicate is unchanged.
+ ///
+ /// \param CI - The comparison operation to find a consistent preidcate for.
+ /// \return the consistent comparison predicate.
+ static CmpInst::Predicate predicateForConsistency(CmpInst *CI);
+
+ /// Hashes \p Value based on its opcode, types, and operand types.
+ /// Two IRInstructionData instances produce the same hash when they perform
+ /// the same operation.
+ ///
+ /// As a simple example, consider the following instructions.
+ ///
+ /// \code
+ /// %add1 = add i32 %x1, %y1
+ /// %add2 = add i32 %x2, %y2
+ ///
+ /// %sub = sub i32 %x1, %y1
+ ///
+ /// %add_i64 = add i64 %x2, %y2
+ /// \endcode
+ ///
+ /// Because the first two adds operate the same types, and are performing the
+ /// same action, they will be hashed to the same value.
+ ///
+ /// However, the subtraction instruction is not the same as an addition, and
+ /// will be hashed to a different value.
+ ///
+ /// Finally, the last add has a different type compared to the first two add
+ /// instructions, so it will also be hashed to a different value that any of
+ /// the previous instructions.
+ ///
+ /// \param [in] ID - The IRInstructionData instance to be hashed.
+ /// \returns A hash_value of the IRInstructionData.
+ friend hash_code hash_value(const IRInstructionData &ID) {
+ SmallVector<Type *, 4> OperTypes;
+ for (Value *V : ID.OperVals)
+ OperTypes.push_back(V->getType());
+
+ if (isa<CmpInst>(ID.Inst))
+ return llvm::hash_combine(
+ llvm::hash_value(ID.Inst->getOpcode()),
+ llvm::hash_value(ID.Inst->getType()),
+ llvm::hash_value(ID.getPredicate()),
+ llvm::hash_combine_range(OperTypes.begin(), OperTypes.end()));
+ else if (CallInst *CI = dyn_cast<CallInst>(ID.Inst))
+ return llvm::hash_combine(
+ llvm::hash_value(ID.Inst->getOpcode()),
+ llvm::hash_value(ID.Inst->getType()),
+ llvm::hash_value(CI->getCalledFunction()->getName().str()),
+ llvm::hash_combine_range(OperTypes.begin(), OperTypes.end()));
+ return llvm::hash_combine(
+ llvm::hash_value(ID.Inst->getOpcode()),
+ llvm::hash_value(ID.Inst->getType()),
+ llvm::hash_combine_range(OperTypes.begin(), OperTypes.end()));
+ }
+
+ IRInstructionDataList *IDL = nullptr;
+};
+
+struct IRInstructionDataList : simple_ilist<IRInstructionData> {};
+
+/// Compare one IRInstructionData class to another IRInstructionData class for
+/// whether they are performing a the same operation, and can mapped to the
+/// same value. For regular instructions if the hash value is the same, then
+/// they will also be close.
+///
+/// \param A - The first IRInstructionData class to compare
+/// \param B - The second IRInstructionData class to compare
+/// \returns true if \p A and \p B are similar enough to be mapped to the same
+/// value.
+bool isClose(const IRInstructionData &A, const IRInstructionData &B);
+
+struct IRInstructionDataTraits : DenseMapInfo<IRInstructionData *> {
+ static inline IRInstructionData *getEmptyKey() { return nullptr; }
+ static inline IRInstructionData *getTombstoneKey() {
+ return reinterpret_cast<IRInstructionData *>(-1);
+ }
+
+ static unsigned getHashValue(const IRInstructionData *E) {
+ using llvm::hash_value;
+ assert(E && "IRInstructionData is a nullptr?");
+ return hash_value(*E);
+ }
+
+ static bool isEqual(const IRInstructionData *LHS,
+ const IRInstructionData *RHS) {
+ if (RHS == getEmptyKey() || RHS == getTombstoneKey() ||
+ LHS == getEmptyKey() || LHS == getTombstoneKey())
+ return LHS == RHS;
+
+ assert(LHS && RHS && "nullptr should have been caught by getEmptyKey?");
+ return isClose(*LHS, *RHS);
+ }
+};
+
+/// Helper struct for converting the Instructions in a Module into a vector of
+/// unsigned integers. This vector of unsigned integers can be thought of as a
+/// "numeric string". This numeric string can then be queried by, for example,
+/// data structures that find repeated substrings.
+///
+/// This hashing is done per BasicBlock in the module. To hash Instructions
+/// based off of their operations, each Instruction is wrapped in an
+/// IRInstructionData struct. The unsigned integer for an IRInstructionData
+/// depends on:
+/// - The hash provided by the IRInstructionData.
+/// - Which member of InstrType the IRInstructionData is classified as.
+// See InstrType for more details on the possible classifications, and how they
+// manifest in the numeric string.
+///
+/// The numeric string for an individual BasicBlock is terminated by an unique
+/// unsigned integer. This prevents data structures which rely on repetition
+/// from matching across BasicBlocks. (For example, the SuffixTree.)
+/// As a concrete example, if we have the following two BasicBlocks:
+/// \code
+/// bb0:
+/// %add1 = add i32 %a, %b
+/// %add2 = add i32 %c, %d
+/// %add3 = add i64 %e, %f
+/// bb1:
+/// %sub = sub i32 %c, %d
+/// \endcode
+/// We may hash the Instructions like this (via IRInstructionData):
+/// \code
+/// bb0:
+/// %add1 = add i32 %a, %b ; Hash: 1
+/// %add2 = add i32 %c, %d; Hash: 1
+/// %add3 = add i64 %e, %f; Hash: 2
+/// bb1:
+/// %sub = sub i32 %c, %d; Hash: 3
+/// %add4 = add i32 %c, %d ; Hash: 1
+/// \endcode
+/// And produce a "numeric string representation" like so:
+/// 1, 1, 2, unique_integer_1, 3, 1, unique_integer_2
+///
+/// TODO: This is very similar to the MachineOutliner, and should be
+/// consolidated into the same interface.
+struct IRInstructionMapper {
+ /// The starting illegal instruction number to map to.
+ ///
+ /// Set to -3 for compatibility with DenseMapInfo<unsigned>.
+ unsigned IllegalInstrNumber = static_cast<unsigned>(-3);
+
+ /// The next available integer to assign to a legal Instruction to.
+ unsigned LegalInstrNumber = 0;
+
+ /// Correspondence from IRInstructionData to unsigned integers.
+ DenseMap<IRInstructionData *, unsigned, IRInstructionDataTraits>
+ InstructionIntegerMap;
+
+ /// Set if we added an illegal number in the previous step.
+ /// Since each illegal number is unique, we only need one of them between
+ /// each range of legal numbers. This lets us make sure we don't add more
+ /// than one illegal number per range.
+ bool AddedIllegalLastTime = false;
+
+ /// Marks whether we found a illegal instruction in the previous step.
+ bool CanCombineWithPrevInstr = false;
+
+ /// Marks whether we have found a set of instructions that is long enough
+ /// to be considered for similarity.
+ bool HaveLegalRange = false;
+
+ /// This allocator pointer is in charge of holding on to the IRInstructionData
+ /// so it is not deallocated until whatever external tool is using it is done
+ /// with the information.
+ SpecificBumpPtrAllocator<IRInstructionData> *InstDataAllocator = nullptr;
+
+ /// This allocator pointer is in charge of creating the IRInstructionDataList
+ /// so it is not deallocated until whatever external tool is using it is done
+ /// with the information.
+ SpecificBumpPtrAllocator<IRInstructionDataList> *IDLAllocator = nullptr;
+
+ /// Get an allocated IRInstructionData struct using the InstDataAllocator.
+ ///
+ /// \param I - The Instruction to wrap with IRInstructionData.
+ /// \param Legality - A boolean value that is true if the instruction is to
+ /// be considered for similarity, and false if not.
+ /// \param IDL - The InstructionDataList that the IRInstructionData is
+ /// inserted into.
+ /// \returns An allocated IRInstructionData struct.
+ IRInstructionData *allocateIRInstructionData(Instruction &I, bool Legality,
+ IRInstructionDataList &IDL);
+
+ /// Get an allocated IRInstructionDataList object using the IDLAllocator.
+ ///
+ /// \returns An allocated IRInstructionDataList object.
+ IRInstructionDataList *allocateIRInstructionDataList();
+
+ IRInstructionDataList *IDL = nullptr;
+
+ /// Maps the Instructions in a BasicBlock \p BB to legal or illegal integers
+ /// determined by \p InstrType. Two Instructions are mapped to the same value
+ /// if they are close as defined by the InstructionData class above.
+ ///
+ /// \param [in] BB - The BasicBlock to be mapped to integers.
+ /// \param [in,out] InstrList - Vector of IRInstructionData to append to.
+ /// \param [in,out] IntegerMapping - Vector of unsigned integers to append to.
+ void convertToUnsignedVec(BasicBlock &BB,
+ std::vector<IRInstructionData *> &InstrList,
+ std::vector<unsigned> &IntegerMapping);
+
+ /// Maps an Instruction to a legal integer.
+ ///
+ /// \param [in] It - The Instruction to be mapped to an integer.
+ /// \param [in,out] IntegerMappingForBB - Vector of unsigned integers to
+ /// append to.
+ /// \param [in,out] InstrListForBB - Vector of InstructionData to append to.
+ /// \returns The integer \p It was mapped to.
+ unsigned mapToLegalUnsigned(BasicBlock::iterator &It,
+ std::vector<unsigned> &IntegerMappingForBB,
+ std::vector<IRInstructionData *> &InstrListForBB);
+
+ /// Maps an Instruction to an illegal integer.
+ ///
+ /// \param [in] It - The \p Instruction to be mapped to an integer.
+ /// \param [in,out] IntegerMappingForBB - Vector of unsigned integers to
+ /// append to.
+ /// \param [in,out] InstrListForBB - Vector of IRInstructionData to append to.
+ /// \param End - true if creating a dummy IRInstructionData at the end of a
+ /// basic block.
+ /// \returns The integer \p It was mapped to.
+ unsigned mapToIllegalUnsigned(
+ BasicBlock::iterator &It, std::vector<unsigned> &IntegerMappingForBB,
+ std::vector<IRInstructionData *> &InstrListForBB, bool End = false);
+
+ IRInstructionMapper(SpecificBumpPtrAllocator<IRInstructionData> *IDA,
+ SpecificBumpPtrAllocator<IRInstructionDataList> *IDLA)
+ : InstDataAllocator(IDA), IDLAllocator(IDLA) {
+ // Make sure that the implementation of DenseMapInfo<unsigned> hasn't
+ // changed.
+ assert(DenseMapInfo<unsigned>::getEmptyKey() == static_cast<unsigned>(-1) &&
+ "DenseMapInfo<unsigned>'s empty key isn't -1!");
+ assert(DenseMapInfo<unsigned>::getTombstoneKey() ==
+ static_cast<unsigned>(-2) &&
+ "DenseMapInfo<unsigned>'s tombstone key isn't -2!");
+
+ IDL = new (IDLAllocator->Allocate())
+ IRInstructionDataList();
+ }
+
+ /// Custom InstVisitor to classify different instructions for whether it can
+ /// be analyzed for similarity.
+ struct InstructionClassification
+ : public InstVisitor<InstructionClassification, InstrType> {
+ InstructionClassification() {}
+
+ // TODO: Determine a scheme to resolve when the label is similar enough.
+ InstrType visitBranchInst(BranchInst &BI) { return Illegal; }
+ // TODO: Determine a scheme to resolve when the labels are similar enough.
+ InstrType visitPHINode(PHINode &PN) { return Illegal; }
+ // TODO: Handle allocas.
+ InstrType visitAllocaInst(AllocaInst &AI) { return Illegal; }
+ // We exclude variable argument instructions since variable arguments
+ // requires extra checking of the argument list.
+ InstrType visitVAArgInst(VAArgInst &VI) { return Illegal; }
+ // We exclude all exception handling cases since they are so context
+ // dependent.
+ InstrType visitLandingPadInst(LandingPadInst &LPI) { return Illegal; }
+ InstrType visitFuncletPadInst(FuncletPadInst &FPI) { return Illegal; }
+ // DebugInfo should be included in the regions, but should not be
+ // analyzed for similarity as it has no bearing on the outcome of the
+ // program.
+ InstrType visitDbgInfoIntrinsic(DbgInfoIntrinsic &DII) { return Invisible; }
+ // TODO: Handle specific intrinsics.
+ InstrType visitIntrinsicInst(IntrinsicInst &II) { return Illegal; }
+ // We only allow call instructions where the function has a name and
+ // is not an indirect call.
+ InstrType visitCallInst(CallInst &CI) {
+ Function *F = CI.getCalledFunction();
+ if (!F || CI.isIndirectCall() || !F->hasName())
+ return Illegal;
+ return Legal;
+ }
+ // TODO: We do not current handle similarity that changes the control flow.
+ InstrType visitInvokeInst(InvokeInst &II) { return Illegal; }
+ // TODO: We do not current handle similarity that changes the control flow.
+ InstrType visitCallBrInst(CallBrInst &CBI) { return Illegal; }
+ // TODO: Handle interblock similarity.
+ InstrType visitTerminator(Instruction &I) { return Illegal; }
+ InstrType visitInstruction(Instruction &I) { return Legal; }
+ };
+
+ /// Maps an Instruction to a member of InstrType.
+ InstructionClassification InstClassifier;
+};
+
+/// This is a class that wraps a range of IRInstructionData from one point to
+/// another in the vector of IRInstructionData, which is a region of the
+/// program. It is also responsible for defining the structure within this
+/// region of instructions.
+///
+/// The structure of a region is defined through a value numbering system
+/// assigned to each unique value in a region at the creation of the
+/// IRSimilarityCandidate.
+///
+/// For example, for each Instruction we add a mapping for each new
+/// value seen in that Instruction.
+/// IR: Mapping Added:
+/// %add1 = add i32 %a, c1 %add1 -> 3, %a -> 1, c1 -> 2
+/// %add2 = add i32 %a, %1 %add2 -> 4
+/// %add3 = add i32 c2, c1 %add3 -> 6, c2 -> 5
+///
+/// We can compare IRSimilarityCandidates against one another.
+/// The \ref isSimilar function compares each IRInstructionData against one
+/// another and if we have the same sequences of IRInstructionData that would
+/// create the same hash, we have similar IRSimilarityCandidates.
+///
+/// We can also compare the structure of IRSimilarityCandidates. If we can
+/// create a mapping of registers in the region contained by one
+/// IRSimilarityCandidate to the region contained by different
+/// IRSimilarityCandidate, they can be considered structurally similar.
+///
+/// IRSimilarityCandidate1: IRSimilarityCandidate2:
+/// %add1 = add i32 %a, %b %add1 = add i32 %d, %e
+/// %add2 = add i32 %a, %c %add2 = add i32 %d, %f
+/// %add3 = add i32 c1, c2 %add3 = add i32 c3, c4
+///
+/// Can have the following mapping from candidate to candidate of:
+/// %a -> %d, %b -> %e, %c -> %f, c1 -> c3, c2 -> c4
+/// and can be considered similar.
+///
+/// IRSimilarityCandidate1: IRSimilarityCandidate2:
+/// %add1 = add i32 %a, %b %add1 = add i32 %d, c4
+/// %add2 = add i32 %a, %c %add2 = add i32 %d, %f
+/// %add3 = add i32 c1, c2 %add3 = add i32 c3, c4
+///
+/// We cannot create the same mapping since the use of c4 is not used in the
+/// same way as %b or c2.
+class IRSimilarityCandidate {
+private:
+ /// The start index of this IRSimilarityCandidate in the instruction list.
+ unsigned StartIdx = 0;
+
+ /// The number of instructions in this IRSimilarityCandidate.
+ unsigned Len = 0;
+
+ /// The first instruction in this IRSimilarityCandidate.
+ IRInstructionData *FirstInst = nullptr;
+
+ /// The last instruction in this IRSimilarityCandidate.
+ IRInstructionData *LastInst = nullptr;
+
+ /// Global Value Numbering structures
+ /// @{
+ /// Stores the mapping of the value to the number assigned to it in the
+ /// IRSimilarityCandidate.
+ DenseMap<Value *, unsigned> ValueToNumber;
+ /// Stores the mapping of the number to the value assigned this number.
+ DenseMap<unsigned, Value *> NumberToValue;
+ /// @}
+
+public:
+ /// \param StartIdx - The starting location of the region.
+ /// \param Len - The length of the region.
+ /// \param FirstInstIt - The starting IRInstructionData of the region.
+ /// \param LastInstIt - The ending IRInstructionData of the region.
+ IRSimilarityCandidate(unsigned StartIdx, unsigned Len,
+ IRInstructionData *FirstInstIt,
+ IRInstructionData *LastInstIt);
+
+ /// \param A - The first IRInstructionCandidate to compare.
+ /// \param B - The second IRInstructionCandidate to compare.
+ /// \returns True when every IRInstructionData in \p A is similar to every
+ /// IRInstructionData in \p B.
+ static bool isSimilar(const IRSimilarityCandidate &A,
+ const IRSimilarityCandidate &B);
+
+ /// \param A - The first IRInstructionCandidate to compare.
+ /// \param B - The second IRInstructionCandidate to compare.
+ /// \returns True when every IRInstructionData in \p A is structurally similar
+ /// to \p B.
+ static bool compareStructure(const IRSimilarityCandidate &A,
+ const IRSimilarityCandidate &B);
+
+ struct OperandMapping {
+ /// The IRSimilarityCandidate that holds the instruction the OperVals were
+ /// pulled from.
+ const IRSimilarityCandidate &IRSC;
+
+ /// The operand values to be analyzed.
+ ArrayRef<Value *> &OperVals;
+
+ /// The current mapping of global value numbers from one IRSimilarityCandidate
+ /// to another IRSimilarityCandidate.
+ DenseMap<unsigned, DenseSet<unsigned>> &ValueNumberMapping;
+ };
+
+ /// Compare the operands in \p A and \p B and check that the current mapping
+ /// of global value numbers from \p A to \p B and \p B to \A is consistent.
+ ///
+ /// \param A - The first IRInstructionCandidate, operand values, and current
+ /// operand mappings to compare.
+ /// \param B - The second IRInstructionCandidate, operand values, and current
+ /// operand mappings to compare.
+ /// \returns true if the IRSimilarityCandidates operands are compatible.
+ static bool compareNonCommutativeOperandMapping(OperandMapping A,
+ OperandMapping B);
+
+ /// Compare the operands in \p A and \p B and check that the current mapping
+ /// of global value numbers from \p A to \p B and \p B to \A is consistent
+ /// given that the operands are commutative.
+ ///
+ /// \param A - The first IRInstructionCandidate, operand values, and current
+ /// operand mappings to compare.
+ /// \param B - The second IRInstructionCandidate, operand values, and current
+ /// operand mappings to compare.
+ /// \returns true if the IRSimilarityCandidates operands are compatible.
+ static bool compareCommutativeOperandMapping(OperandMapping A,
+ OperandMapping B);
+
+ /// Compare the start and end indices of the two IRSimilarityCandidates for
+ /// whether they overlap. If the start instruction of one
+ /// IRSimilarityCandidate is less than the end instruction of the other, and
+ /// the start instruction of one is greater than the start instruction of the
+ /// other, they overlap.
+ ///
+ /// \returns true if the IRSimilarityCandidates do not have overlapping
+ /// instructions.
+ static bool overlap(const IRSimilarityCandidate &A,
+ const IRSimilarityCandidate &B);
+
+ /// \returns the number of instructions in this Candidate.
+ unsigned getLength() const { return Len; }
+
+ /// \returns the start index of this IRSimilarityCandidate.
+ unsigned getStartIdx() const { return StartIdx; }
+
+ /// \returns the end index of this IRSimilarityCandidate.
+ unsigned getEndIdx() const { return StartIdx + Len - 1; }
+
+ /// \returns The first IRInstructionData.
+ IRInstructionData *front() const { return FirstInst; }
+ /// \returns The last IRInstructionData.
+ IRInstructionData *back() const { return LastInst; }
+
+ /// \returns The first Instruction.
+ Instruction *frontInstruction() { return FirstInst->Inst; }
+ /// \returns The last Instruction
+ Instruction *backInstruction() { return LastInst->Inst; }
+
+ /// \returns The BasicBlock the IRSimilarityCandidate starts in.
+ BasicBlock *getStartBB() { return FirstInst->Inst->getParent(); }
+ /// \returns The BasicBlock the IRSimilarityCandidate ends in.
+ BasicBlock *getEndBB() { return LastInst->Inst->getParent(); }
+
+ /// \returns The Function that the IRSimilarityCandidate is located in.
+ Function *getFunction() { return getStartBB()->getParent(); }
+
+ /// Finds the positive number associated with \p V if it has been mapped.
+ /// \param [in] V - the Value to find.
+ /// \returns The positive number corresponding to the value.
+ /// \returns None if not present.
+ Optional<unsigned> getGVN(Value *V) {
+ assert(V != nullptr && "Value is a nullptr?");
+ DenseMap<Value *, unsigned>::iterator VNIt = ValueToNumber.find(V);
+ if (VNIt == ValueToNumber.end())
+ return None;
+ return VNIt->second;
+ }
+
+ /// Finds the Value associate with \p Num if it exists.
+ /// \param [in] Num - the number to find.
+ /// \returns The Value associated with the number.
+ /// \returns None if not present.
+ Optional<Value *> fromGVN(unsigned Num) {
+ DenseMap<unsigned, Value *>::iterator VNIt = NumberToValue.find(Num);
+ if (VNIt == NumberToValue.end())
+ return None;
+ assert(VNIt->second != nullptr && "Found value is a nullptr!");
+ return VNIt->second;
+ }
+
+ /// \param RHS -The IRSimilarityCandidate to compare against
+ /// \returns true if the IRSimilarityCandidate is occurs after the
+ /// IRSimilarityCandidate in the program.
+ bool operator<(const IRSimilarityCandidate &RHS) const {
+ return getStartIdx() > RHS.getStartIdx();
+ }
+
+ using iterator = IRInstructionDataList::iterator;
+ iterator begin() const { return iterator(front()); }
+ iterator end() const { return std::next(iterator(back())); }
+};
+
+typedef std::vector<IRSimilarityCandidate> SimilarityGroup;
+typedef std::vector<SimilarityGroup> SimilarityGroupList;
+
+/// This class puts all the pieces of the IRInstructionData,
+/// IRInstructionMapper, IRSimilarityCandidate together.
+///
+/// It first feeds the Module or vector of Modules into the IRInstructionMapper,
+/// and puts all the mapped instructions into a single long list of
+/// IRInstructionData.
+///
+/// The list of unsigned integers is given to the Suffix Tree or similar data
+/// structure to find repeated subsequences. We construct an
+/// IRSimilarityCandidate for each instance of the subsequence. We compare them
+/// against one another since These repeated subsequences can have different
+/// structure. For each different kind of structure found, we create a
+/// similarity group.
+///
+/// If we had four IRSimilarityCandidates A, B, C, and D where A, B and D are
+/// structurally similar to one another, while C is different we would have two
+/// SimilarityGroups:
+///
+/// SimilarityGroup 1: SimilarityGroup 2
+/// A, B, D C
+///
+/// A list of the different similarity groups is then returned after
+/// analyzing the module.
+class IRSimilarityIdentifier {
+public:
+ IRSimilarityIdentifier()
+ : Mapper(&InstDataAllocator, &InstDataListAllocator) {}
+
+ /// \param M the module to find similarity in.
+ explicit IRSimilarityIdentifier(Module &M)
+ : Mapper(&InstDataAllocator, &InstDataListAllocator) {
+ findSimilarity(M);
+ }
+
+private:
+ /// Map the instructions in the module to unsigned integers, using mapping
+ /// already present in the Mapper if possible.
+ ///
+ /// \param [in] M Module - To map to integers.
+ /// \param [in,out] InstrList - The vector to append IRInstructionData to.
+ /// \param [in,out] IntegerMapping - The vector to append integers to.
+ void populateMapper(Module &M, std::vector<IRInstructionData *> &InstrList,
+ std::vector<unsigned> &IntegerMapping);
+
+ /// Map the instructions in the modules vector to unsigned integers, using
+ /// mapping already present in the mapper if possible.
+ ///
+ /// \param [in] Modules - The list of modules to use to populate the mapper
+ /// \param [in,out] InstrList - The vector to append IRInstructionData to.
+ /// \param [in,out] IntegerMapping - The vector to append integers to.
+ void populateMapper(ArrayRef<std::unique_ptr<Module>> &Modules,
+ std::vector<IRInstructionData *> &InstrList,
+ std::vector<unsigned> &IntegerMapping);
+
+ /// Find the similarity candidates in \p InstrList and corresponding
+ /// \p UnsignedVec
+ ///
+ /// \param [in,out] InstrList - The vector to append IRInstructionData to.
+ /// \param [in,out] IntegerMapping - The vector to append integers to.
+ /// candidates found in the program.
+ void findCandidates(std::vector<IRInstructionData *> &InstrList,
+ std::vector<unsigned> &IntegerMapping);
+
+public:
+ // Find the IRSimilarityCandidates in the \p Modules and group by structural
+ // similarity in a SimilarityGroup, each group is returned in a
+ // SimilarityGroupList.
+ //
+ // \param [in] Modules - the modules to analyze.
+ // \returns The groups of similarity ranges found in the modules.
+ SimilarityGroupList &
+ findSimilarity(ArrayRef<std::unique_ptr<Module>> Modules);
+
+ // Find the IRSimilarityCandidates in the given Module grouped by structural
+ // similarity in a SimilarityGroup, contained inside a SimilarityGroupList.
+ //
+ // \param [in] M - the module to analyze.
+ // \returns The groups of similarity ranges found in the module.
+ SimilarityGroupList &findSimilarity(Module &M);
+
+ // Clears \ref SimilarityCandidates if it is already filled by a previous run.
+ void resetSimilarityCandidates() {
+ // If we've already analyzed a Module or set of Modules, so we must clear
+ // the SimilarityCandidates to make sure we do not have only old values
+ // hanging around.
+ if (SimilarityCandidates.hasValue())
+ SimilarityCandidates->clear();
+ else
+ SimilarityCandidates = SimilarityGroupList();
+ }
+
+ // \returns The groups of similarity ranges found in the most recently passed
+ // set of modules.
+ Optional<SimilarityGroupList> &getSimilarity() {
+ return SimilarityCandidates;
+ }
+
+private:
+ /// The allocator for IRInstructionData.
+ SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
+
+ /// The allocator for IRInstructionDataLists.
+ SpecificBumpPtrAllocator<IRInstructionDataList> InstDataListAllocator;
+
+ /// Map Instructions to unsigned integers and wraps the Instruction in an
+ /// instance of IRInstructionData.
+ IRInstructionMapper Mapper;
+
+ /// The SimilarityGroups found with the most recent run of \ref
+ /// findSimilarity. None if there is no recent run.
+ Optional<SimilarityGroupList> SimilarityCandidates;
+};
+
+} // end namespace IRSimilarity
+
+/// An analysis pass based on legacy pass manager that runs and returns
+/// IRSimilarityIdentifier run on the Module.
+class IRSimilarityIdentifierWrapperPass : public ModulePass {
+ std::unique_ptr<IRSimilarity::IRSimilarityIdentifier> IRSI;
+
+public:
+ static char ID;
+ IRSimilarityIdentifierWrapperPass();
+
+ IRSimilarity::IRSimilarityIdentifier &getIRSI() { return *IRSI; }
+ const IRSimilarity::IRSimilarityIdentifier &getIRSI() const { return *IRSI; }
+
+ bool doInitialization(Module &M) override;
+ bool doFinalization(Module &M) override;
+ bool runOnModule(Module &M) override;
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ }
+};
+
+/// An analysis pass that runs and returns the IRSimilarityIdentifier run on the
+/// Module.
+class IRSimilarityAnalysis : public AnalysisInfoMixin<IRSimilarityAnalysis> {
+public:
+ typedef IRSimilarity::IRSimilarityIdentifier Result;
+
+ Result run(Module &M, ModuleAnalysisManager &);
+
+private:
+ friend AnalysisInfoMixin<IRSimilarityAnalysis>;
+ static AnalysisKey Key;
+};
+
+/// Printer pass that uses \c IRSimilarityAnalysis.
+class IRSimilarityAnalysisPrinterPass
+ : public PassInfoMixin<IRSimilarityAnalysisPrinterPass> {
+ raw_ostream &OS;
+
+public:
+ explicit IRSimilarityAnalysisPrinterPass(raw_ostream &OS) : OS(OS) {}
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_ANALYSIS_IRSIMILARITYIDENTIFIER_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/IVDescriptors.h b/contrib/libs/llvm12/include/llvm/Analysis/IVDescriptors.h
index 3077c10848..524b215744 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/IVDescriptors.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/IVDescriptors.h
@@ -40,24 +40,24 @@ class ScalarEvolution;
class SCEV;
class DominatorTree;
-/// These are the kinds of recurrences that we support.
-enum class RecurKind {
- None, ///< Not a recurrence.
- Add, ///< Sum of integers.
- Mul, ///< Product of integers.
- Or, ///< Bitwise or logical OR of integers.
- And, ///< Bitwise or logical AND of integers.
- Xor, ///< Bitwise or logical XOR of integers.
- SMin, ///< Signed integer min implemented in terms of select(cmp()).
- SMax, ///< Signed integer max implemented in terms of select(cmp()).
- UMin, ///< Unisgned integer min implemented in terms of select(cmp()).
- UMax, ///< Unsigned integer max implemented in terms of select(cmp()).
- FAdd, ///< Sum of floats.
- FMul, ///< Product of floats.
- FMin, ///< FP min implemented in terms of select(cmp()).
- FMax ///< FP max implemented in terms of select(cmp()).
-};
-
+/// These are the kinds of recurrences that we support.
+enum class RecurKind {
+ None, ///< Not a recurrence.
+ Add, ///< Sum of integers.
+ Mul, ///< Product of integers.
+ Or, ///< Bitwise or logical OR of integers.
+ And, ///< Bitwise or logical AND of integers.
+ Xor, ///< Bitwise or logical XOR of integers.
+ SMin, ///< Signed integer min implemented in terms of select(cmp()).
+ SMax, ///< Signed integer max implemented in terms of select(cmp()).
+ UMin, ///< Unisgned integer min implemented in terms of select(cmp()).
+ UMax, ///< Unsigned integer max implemented in terms of select(cmp()).
+ FAdd, ///< Sum of floats.
+ FMul, ///< Product of floats.
+ FMin, ///< FP min implemented in terms of select(cmp()).
+ FMax ///< FP max implemented in terms of select(cmp()).
+};
+
/// The RecurrenceDescriptor is used to identify recurrences variables in a
/// loop. Reduction is a special case of recurrence that has uses of the
/// recurrence variable outside the loop. The method isReductionPHI identifies
@@ -74,11 +74,11 @@ class RecurrenceDescriptor {
public:
RecurrenceDescriptor() = default;
- RecurrenceDescriptor(Value *Start, Instruction *Exit, RecurKind K,
- FastMathFlags FMF, Instruction *UAI, Type *RT,
- bool Signed, SmallPtrSetImpl<Instruction *> &CI)
+ RecurrenceDescriptor(Value *Start, Instruction *Exit, RecurKind K,
+ FastMathFlags FMF, Instruction *UAI, Type *RT,
+ bool Signed, SmallPtrSetImpl<Instruction *> &CI)
: StartValue(Start), LoopExitInstr(Exit), Kind(K), FMF(FMF),
- UnsafeAlgebraInst(UAI), RecurrenceType(RT), IsSigned(Signed) {
+ UnsafeAlgebraInst(UAI), RecurrenceType(RT), IsSigned(Signed) {
CastInsts.insert(CI.begin(), CI.end());
}
@@ -86,22 +86,22 @@ public:
class InstDesc {
public:
InstDesc(bool IsRecur, Instruction *I, Instruction *UAI = nullptr)
- : IsRecurrence(IsRecur), PatternLastInst(I),
- RecKind(RecurKind::None), UnsafeAlgebraInst(UAI) {}
+ : IsRecurrence(IsRecur), PatternLastInst(I),
+ RecKind(RecurKind::None), UnsafeAlgebraInst(UAI) {}
- InstDesc(Instruction *I, RecurKind K, Instruction *UAI = nullptr)
- : IsRecurrence(true), PatternLastInst(I), RecKind(K),
+ InstDesc(Instruction *I, RecurKind K, Instruction *UAI = nullptr)
+ : IsRecurrence(true), PatternLastInst(I), RecKind(K),
UnsafeAlgebraInst(UAI) {}
- bool isRecurrence() const { return IsRecurrence; }
+ bool isRecurrence() const { return IsRecurrence; }
- bool hasUnsafeAlgebra() const { return UnsafeAlgebraInst != nullptr; }
+ bool hasUnsafeAlgebra() const { return UnsafeAlgebraInst != nullptr; }
- Instruction *getUnsafeAlgebraInst() const { return UnsafeAlgebraInst; }
+ Instruction *getUnsafeAlgebraInst() const { return UnsafeAlgebraInst; }
- RecurKind getRecKind() const { return RecKind; }
+ RecurKind getRecKind() const { return RecKind; }
- Instruction *getPatternInst() const { return PatternLastInst; }
+ Instruction *getPatternInst() const { return PatternLastInst; }
private:
// Is this instruction a recurrence candidate.
@@ -109,8 +109,8 @@ public:
// The last instruction in a min/max pattern (select of the select(icmp())
// pattern), or the current recurrence instruction otherwise.
Instruction *PatternLastInst;
- // If this is a min/max pattern.
- RecurKind RecKind;
+ // If this is a min/max pattern.
+ RecurKind RecKind;
// Recurrence has unsafe algebra.
Instruction *UnsafeAlgebraInst;
};
@@ -120,7 +120,7 @@ public:
/// select(icmp()) this function advances the instruction pointer 'I' from the
/// compare instruction to the select instruction and stores this pointer in
/// 'PatternLastInst' member of the returned struct.
- static InstDesc isRecurrenceInstr(Instruction *I, RecurKind Kind,
+ static InstDesc isRecurrenceInstr(Instruction *I, RecurKind Kind,
InstDesc &Prev, bool HasFunNoNaNAttr);
/// Returns true if instruction I has multiple uses in Insts
@@ -131,28 +131,28 @@ public:
/// Returns true if all uses of the instruction I is within the Set.
static bool areAllUsesIn(Instruction *I, SmallPtrSetImpl<Instruction *> &Set);
- /// Returns a struct describing if the instruction is a
+ /// Returns a struct describing if the instruction is a
/// Select(ICmp(X, Y), X, Y) instruction pattern corresponding to a min(X, Y)
- /// or max(X, Y). \p Prev specifies the description of an already processed
- /// select instruction, so its corresponding cmp can be matched to it.
- static InstDesc isMinMaxSelectCmpPattern(Instruction *I,
- const InstDesc &Prev);
+ /// or max(X, Y). \p Prev specifies the description of an already processed
+ /// select instruction, so its corresponding cmp can be matched to it.
+ static InstDesc isMinMaxSelectCmpPattern(Instruction *I,
+ const InstDesc &Prev);
/// Returns a struct describing if the instruction is a
/// Select(FCmp(X, Y), (Z = X op PHINode), PHINode) instruction pattern.
- static InstDesc isConditionalRdxPattern(RecurKind Kind, Instruction *I);
+ static InstDesc isConditionalRdxPattern(RecurKind Kind, Instruction *I);
/// Returns identity corresponding to the RecurrenceKind.
- static Constant *getRecurrenceIdentity(RecurKind K, Type *Tp);
+ static Constant *getRecurrenceIdentity(RecurKind K, Type *Tp);
- /// Returns the opcode corresponding to the RecurrenceKind.
- static unsigned getOpcode(RecurKind Kind);
+ /// Returns the opcode corresponding to the RecurrenceKind.
+ static unsigned getOpcode(RecurKind Kind);
/// Returns true if Phi is a reduction of type Kind and adds it to the
/// RecurrenceDescriptor. If either \p DB is non-null or \p AC and \p DT are
/// non-null, the minimal bit width needed to compute the reduction will be
/// computed.
- static bool AddReductionVar(PHINode *Phi, RecurKind Kind, Loop *TheLoop,
+ static bool AddReductionVar(PHINode *Phi, RecurKind Kind, Loop *TheLoop,
bool HasFunNoNaNAttr,
RecurrenceDescriptor &RedDes,
DemandedBits *DB = nullptr,
@@ -181,64 +181,64 @@ public:
DenseMap<Instruction *, Instruction *> &SinkAfter,
DominatorTree *DT);
- RecurKind getRecurrenceKind() const { return Kind; }
+ RecurKind getRecurrenceKind() const { return Kind; }
- unsigned getOpcode() const { return getOpcode(getRecurrenceKind()); }
+ unsigned getOpcode() const { return getOpcode(getRecurrenceKind()); }
- FastMathFlags getFastMathFlags() const { return FMF; }
+ FastMathFlags getFastMathFlags() const { return FMF; }
- TrackingVH<Value> getRecurrenceStartValue() const { return StartValue; }
+ TrackingVH<Value> getRecurrenceStartValue() const { return StartValue; }
- Instruction *getLoopExitInstr() const { return LoopExitInstr; }
+ Instruction *getLoopExitInstr() const { return LoopExitInstr; }
/// Returns true if the recurrence has unsafe algebra which requires a relaxed
/// floating-point model.
- bool hasUnsafeAlgebra() const { return UnsafeAlgebraInst != nullptr; }
+ bool hasUnsafeAlgebra() const { return UnsafeAlgebraInst != nullptr; }
/// Returns first unsafe algebra instruction in the PHI node's use-chain.
- Instruction *getUnsafeAlgebraInst() const { return UnsafeAlgebraInst; }
+ Instruction *getUnsafeAlgebraInst() const { return UnsafeAlgebraInst; }
/// Returns true if the recurrence kind is an integer kind.
- static bool isIntegerRecurrenceKind(RecurKind Kind);
+ static bool isIntegerRecurrenceKind(RecurKind Kind);
/// Returns true if the recurrence kind is a floating point kind.
- static bool isFloatingPointRecurrenceKind(RecurKind Kind);
+ static bool isFloatingPointRecurrenceKind(RecurKind Kind);
/// Returns true if the recurrence kind is an arithmetic kind.
- static bool isArithmeticRecurrenceKind(RecurKind Kind);
-
- /// Returns true if the recurrence kind is an integer min/max kind.
- static bool isIntMinMaxRecurrenceKind(RecurKind Kind) {
- return Kind == RecurKind::UMin || Kind == RecurKind::UMax ||
- Kind == RecurKind::SMin || Kind == RecurKind::SMax;
- }
-
- /// Returns true if the recurrence kind is a floating-point min/max kind.
- static bool isFPMinMaxRecurrenceKind(RecurKind Kind) {
- return Kind == RecurKind::FMin || Kind == RecurKind::FMax;
- }
-
- /// Returns true if the recurrence kind is any min/max kind.
- static bool isMinMaxRecurrenceKind(RecurKind Kind) {
- return isIntMinMaxRecurrenceKind(Kind) || isFPMinMaxRecurrenceKind(Kind);
- }
-
+ static bool isArithmeticRecurrenceKind(RecurKind Kind);
+
+ /// Returns true if the recurrence kind is an integer min/max kind.
+ static bool isIntMinMaxRecurrenceKind(RecurKind Kind) {
+ return Kind == RecurKind::UMin || Kind == RecurKind::UMax ||
+ Kind == RecurKind::SMin || Kind == RecurKind::SMax;
+ }
+
+ /// Returns true if the recurrence kind is a floating-point min/max kind.
+ static bool isFPMinMaxRecurrenceKind(RecurKind Kind) {
+ return Kind == RecurKind::FMin || Kind == RecurKind::FMax;
+ }
+
+ /// Returns true if the recurrence kind is any min/max kind.
+ static bool isMinMaxRecurrenceKind(RecurKind Kind) {
+ return isIntMinMaxRecurrenceKind(Kind) || isFPMinMaxRecurrenceKind(Kind);
+ }
+
/// Returns the type of the recurrence. This type can be narrower than the
/// actual type of the Phi if the recurrence has been type-promoted.
- Type *getRecurrenceType() const { return RecurrenceType; }
+ Type *getRecurrenceType() const { return RecurrenceType; }
/// Returns a reference to the instructions used for type-promoting the
/// recurrence.
- const SmallPtrSet<Instruction *, 8> &getCastInsts() const { return CastInsts; }
+ const SmallPtrSet<Instruction *, 8> &getCastInsts() const { return CastInsts; }
/// Returns true if all source operands of the recurrence are SExtInsts.
- bool isSigned() const { return IsSigned; }
+ bool isSigned() const { return IsSigned; }
+
+ /// Attempts to find a chain of operations from Phi to LoopExitInst that can
+ /// be treated as a set of reductions instructions for in-loop reductions.
+ SmallVector<Instruction *, 4> getReductionOpChain(PHINode *Phi,
+ Loop *L) const;
- /// Attempts to find a chain of operations from Phi to LoopExitInst that can
- /// be treated as a set of reductions instructions for in-loop reductions.
- SmallVector<Instruction *, 4> getReductionOpChain(PHINode *Phi,
- Loop *L) const;
-
private:
// The starting value of the recurrence.
// It does not have to be zero!
@@ -246,7 +246,7 @@ private:
// The instruction who's value is used outside the loop.
Instruction *LoopExitInstr = nullptr;
// The kind of the recurrence.
- RecurKind Kind = RecurKind::None;
+ RecurKind Kind = RecurKind::None;
// The fast-math flags on the recurrent instructions. We propagate these
// fast-math flags into the vectorized FP instructions we generate.
FastMathFlags FMF;
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/InlineAdvisor.h b/contrib/libs/llvm12/include/llvm/Analysis/InlineAdvisor.h
index 37f8cc3442..e4ed1f1a81 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/InlineAdvisor.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/InlineAdvisor.h
@@ -16,10 +16,10 @@
#ifndef LLVM_INLINEADVISOR_H_
#define LLVM_INLINEADVISOR_H_
-#include "llvm/Analysis/InlineCost.h"
-#include "llvm/Config/llvm-config.h"
-#include "llvm/IR/PassManager.h"
-#include "llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h"
+#include "llvm/Analysis/InlineCost.h"
+#include "llvm/Config/llvm-config.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h"
#include <memory>
#include <unordered_set>
@@ -43,11 +43,11 @@ class OptimizationRemarkEmitter;
/// requires the full C Tensorflow API library, and evaluates models
/// dynamically. This mode also permits generating training logs, for offline
/// training.
-enum class InliningAdvisorMode : int {
- Default,
- Release,
- Development
-};
+enum class InliningAdvisorMode : int {
+ Default,
+ Release,
+ Development
+};
class InlineAdvisor;
/// Capture state between an inlining decision having had been made, and
@@ -73,7 +73,7 @@ public:
/// behavior by implementing the corresponding record*Impl.
///
/// Call after inlining succeeded, and did not result in deleting the callee.
- void recordInlining();
+ void recordInlining();
/// Call after inlining succeeded, and resulted in deleting the callee.
void recordInliningWithCalleeDeleted();
@@ -119,44 +119,44 @@ private:
assert(!Recorded && "Recording should happen exactly once");
Recorded = true;
}
- void recordInlineStatsIfNeeded();
+ void recordInlineStatsIfNeeded();
bool Recorded = false;
};
-class DefaultInlineAdvice : public InlineAdvice {
-public:
- DefaultInlineAdvice(InlineAdvisor *Advisor, CallBase &CB,
- Optional<InlineCost> OIC, OptimizationRemarkEmitter &ORE,
- bool EmitRemarks = true)
- : InlineAdvice(Advisor, CB, ORE, OIC.hasValue()), OriginalCB(&CB),
- OIC(OIC), EmitRemarks(EmitRemarks) {}
-
-private:
- void recordUnsuccessfulInliningImpl(const InlineResult &Result) override;
- void recordInliningWithCalleeDeletedImpl() override;
- void recordInliningImpl() override;
-
-private:
- CallBase *const OriginalCB;
- Optional<InlineCost> OIC;
- bool EmitRemarks;
-};
-
+class DefaultInlineAdvice : public InlineAdvice {
+public:
+ DefaultInlineAdvice(InlineAdvisor *Advisor, CallBase &CB,
+ Optional<InlineCost> OIC, OptimizationRemarkEmitter &ORE,
+ bool EmitRemarks = true)
+ : InlineAdvice(Advisor, CB, ORE, OIC.hasValue()), OriginalCB(&CB),
+ OIC(OIC), EmitRemarks(EmitRemarks) {}
+
+private:
+ void recordUnsuccessfulInliningImpl(const InlineResult &Result) override;
+ void recordInliningWithCalleeDeletedImpl() override;
+ void recordInliningImpl() override;
+
+private:
+ CallBase *const OriginalCB;
+ Optional<InlineCost> OIC;
+ bool EmitRemarks;
+};
+
/// Interface for deciding whether to inline a call site or not.
class InlineAdvisor {
public:
InlineAdvisor(InlineAdvisor &&) = delete;
- virtual ~InlineAdvisor();
+ virtual ~InlineAdvisor();
/// Get an InlineAdvice containing a recommendation on whether to
/// inline or not. \p CB is assumed to be a direct call. \p FAM is assumed to
- /// be up-to-date wrt previous inlining decisions. \p MandatoryOnly indicates
- /// only mandatory (always-inline) call sites should be recommended - this
- /// allows the InlineAdvisor track such inlininings.
+ /// be up-to-date wrt previous inlining decisions. \p MandatoryOnly indicates
+ /// only mandatory (always-inline) call sites should be recommended - this
+ /// allows the InlineAdvisor track such inlininings.
/// Returns an InlineAdvice with the inlining recommendation.
- std::unique_ptr<InlineAdvice> getAdvice(CallBase &CB,
- bool MandatoryOnly = false);
+ std::unique_ptr<InlineAdvice> getAdvice(CallBase &CB,
+ bool MandatoryOnly = false);
/// This must be called when the Inliner pass is entered, to allow the
/// InlineAdvisor update internal state, as result of function passes run
@@ -169,14 +169,14 @@ public:
virtual void onPassExit() {}
protected:
- InlineAdvisor(Module &M, FunctionAnalysisManager &FAM);
- virtual std::unique_ptr<InlineAdvice> getAdviceImpl(CallBase &CB) = 0;
- virtual std::unique_ptr<InlineAdvice> getMandatoryAdvice(CallBase &CB,
- bool Advice);
+ InlineAdvisor(Module &M, FunctionAnalysisManager &FAM);
+ virtual std::unique_ptr<InlineAdvice> getAdviceImpl(CallBase &CB) = 0;
+ virtual std::unique_ptr<InlineAdvice> getMandatoryAdvice(CallBase &CB,
+ bool Advice);
- Module &M;
+ Module &M;
FunctionAnalysisManager &FAM;
- std::unique_ptr<ImportedFunctionsInliningStatistics> ImportedFunctionsStats;
+ std::unique_ptr<ImportedFunctionsInliningStatistics> ImportedFunctionsStats;
/// We may want to defer deleting functions to after the inlining for a whole
/// module has finished. This allows us to reliably use function pointers as
@@ -191,14 +191,14 @@ protected:
return DeletedFunctions.count(F);
}
- enum class MandatoryInliningKind { NotMandatory, Always, Never };
-
- static MandatoryInliningKind getMandatoryKind(CallBase &CB,
- FunctionAnalysisManager &FAM,
- OptimizationRemarkEmitter &ORE);
-
- OptimizationRemarkEmitter &getCallerORE(CallBase &CB);
-
+ enum class MandatoryInliningKind { NotMandatory, Always, Never };
+
+ static MandatoryInliningKind getMandatoryKind(CallBase &CB,
+ FunctionAnalysisManager &FAM,
+ OptimizationRemarkEmitter &ORE);
+
+ OptimizationRemarkEmitter &getCallerORE(CallBase &CB);
+
private:
friend class InlineAdvice;
void markFunctionAsDeleted(Function *F);
@@ -210,12 +210,12 @@ private:
/// reusable as-is for inliner pass test scenarios, as well as for regular use.
class DefaultInlineAdvisor : public InlineAdvisor {
public:
- DefaultInlineAdvisor(Module &M, FunctionAnalysisManager &FAM,
- InlineParams Params)
- : InlineAdvisor(M, FAM), Params(Params) {}
+ DefaultInlineAdvisor(Module &M, FunctionAnalysisManager &FAM,
+ InlineParams Params)
+ : InlineAdvisor(M, FAM), Params(Params) {}
private:
- std::unique_ptr<InlineAdvice> getAdviceImpl(CallBase &CB) override;
+ std::unique_ptr<InlineAdvice> getAdviceImpl(CallBase &CB) override;
void onPassExit() override { freeDeletedFunctions(); }
@@ -235,8 +235,8 @@ public:
// InlineAdvisor must be preserved across analysis invalidations.
return false;
}
- bool tryCreate(InlineParams Params, InliningAdvisorMode Mode,
- StringRef ReplayFile);
+ bool tryCreate(InlineParams Params, InliningAdvisorMode Mode,
+ StringRef ReplayFile);
InlineAdvisor *getAdvisor() const { return Advisor.get(); }
void clear() { Advisor.reset(); }
@@ -254,12 +254,12 @@ std::unique_ptr<InlineAdvisor>
getReleaseModeAdvisor(Module &M, ModuleAnalysisManager &MAM);
#endif
-#ifdef LLVM_HAVE_TF_API
-std::unique_ptr<InlineAdvisor>
-getDevelopmentModeAdvisor(Module &M, ModuleAnalysisManager &MAM,
- std::function<bool(CallBase &)> GetDefaultAdvice);
-#endif
-
+#ifdef LLVM_HAVE_TF_API
+std::unique_ptr<InlineAdvisor>
+getDevelopmentModeAdvisor(Module &M, ModuleAnalysisManager &MAM,
+ std::function<bool(CallBase &)> GetDefaultAdvice);
+#endif
+
// Default (manual policy) decision making helper APIs. Shared with the legacy
// pass manager inliner.
@@ -278,9 +278,9 @@ void emitInlinedInto(OptimizationRemarkEmitter &ORE, DebugLoc DLoc,
bool ForProfileContext = false,
const char *PassName = nullptr);
-/// get call site location as string
-std::string getCallSiteLocation(DebugLoc DLoc);
-
+/// get call site location as string
+std::string getCallSiteLocation(DebugLoc DLoc);
+
/// Add location info to ORE message.
void addLocationToRemarks(OptimizationRemark &Remark, DebugLoc DLoc);
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/InlineSizeEstimatorAnalysis.h b/contrib/libs/llvm12/include/llvm/Analysis/InlineSizeEstimatorAnalysis.h
index 8537820b23..f1536aa2c4 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/InlineSizeEstimatorAnalysis.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/InlineSizeEstimatorAnalysis.h
@@ -38,19 +38,19 @@ public:
private:
std::unique_ptr<TFModelEvaluator> Evaluator;
};
-
-class InlineSizeEstimatorAnalysisPrinterPass
- : public PassInfoMixin<InlineSizeEstimatorAnalysisPrinterPass> {
- raw_ostream &OS;
-
-public:
- explicit InlineSizeEstimatorAnalysisPrinterPass(raw_ostream &OS) : OS(OS) {}
-
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
+
+class InlineSizeEstimatorAnalysisPrinterPass
+ : public PassInfoMixin<InlineSizeEstimatorAnalysisPrinterPass> {
+ raw_ostream &OS;
+
+public:
+ explicit InlineSizeEstimatorAnalysisPrinterPass(raw_ostream &OS) : OS(OS) {}
+
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
} // namespace llvm
#endif // LLVM_ANALYSIS_INLINESIZEESTIMATORANALYSIS_H
-
+
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/InstCount.h b/contrib/libs/llvm12/include/llvm/Analysis/InstCount.h
index ad65952c6f..ef18c1e5a1 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/InstCount.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/InstCount.h
@@ -1,39 +1,39 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- InstCount.h - Collects the count of all instructions -----*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass collects the count of all instructions and reports them
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_INSTCOUNT_H
-#define LLVM_ANALYSIS_INSTCOUNT_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-
-class Function;
-
-struct InstCountPass : PassInfoMixin<InstCountPass> {
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &);
-};
-
-} // end namespace llvm
-
-#endif // LLVM_ANALYSIS_INSTCOUNT_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- InstCount.h - Collects the count of all instructions -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass collects the count of all instructions and reports them
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_INSTCOUNT_H
+#define LLVM_ANALYSIS_INSTCOUNT_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Function;
+
+struct InstCountPass : PassInfoMixin<InstCountPass> {
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_ANALYSIS_INSTCOUNT_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/InstructionSimplify.h b/contrib/libs/llvm12/include/llvm/Analysis/InstructionSimplify.h
index cbff6d3736..4add1631ba 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/InstructionSimplify.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/InstructionSimplify.h
@@ -33,10 +33,10 @@
// same call context of that function (and not split between caller and callee
// contexts of a directly recursive call, for example).
//
-// Additionally, these routines can't simplify to the instructions that are not
-// def-reachable, meaning we can't just scan the basic block for instructions
-// to simplify to.
-//
+// Additionally, these routines can't simplify to the instructions that are not
+// def-reachable, meaning we can't just scan the basic block for instructions
+// to simplify to.
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
@@ -109,39 +109,39 @@ struct SimplifyQuery {
// be safely used.
const InstrInfoQuery IIQ;
- /// Controls whether simplifications are allowed to constrain the range of
- /// possible values for uses of undef. If it is false, simplifications are not
- /// allowed to assume a particular value for a use of undef for example.
- bool CanUseUndef = true;
-
+ /// Controls whether simplifications are allowed to constrain the range of
+ /// possible values for uses of undef. If it is false, simplifications are not
+ /// allowed to assume a particular value for a use of undef for example.
+ bool CanUseUndef = true;
+
SimplifyQuery(const DataLayout &DL, const Instruction *CXTI = nullptr)
: DL(DL), CxtI(CXTI) {}
SimplifyQuery(const DataLayout &DL, const TargetLibraryInfo *TLI,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
- const Instruction *CXTI = nullptr, bool UseInstrInfo = true,
- bool CanUseUndef = true)
- : DL(DL), TLI(TLI), DT(DT), AC(AC), CxtI(CXTI), IIQ(UseInstrInfo),
- CanUseUndef(CanUseUndef) {}
+ const Instruction *CXTI = nullptr, bool UseInstrInfo = true,
+ bool CanUseUndef = true)
+ : DL(DL), TLI(TLI), DT(DT), AC(AC), CxtI(CXTI), IIQ(UseInstrInfo),
+ CanUseUndef(CanUseUndef) {}
SimplifyQuery getWithInstruction(Instruction *I) const {
SimplifyQuery Copy(*this);
Copy.CxtI = I;
return Copy;
}
- SimplifyQuery getWithoutUndef() const {
- SimplifyQuery Copy(*this);
- Copy.CanUseUndef = false;
- return Copy;
- }
-
- /// If CanUseUndef is true, returns whether \p V is undef.
- /// Otherwise always return false.
- bool isUndefValue(Value *V) const {
- if (!CanUseUndef)
- return false;
- return isa<UndefValue>(V);
- }
+ SimplifyQuery getWithoutUndef() const {
+ SimplifyQuery Copy(*this);
+ Copy.CanUseUndef = false;
+ return Copy;
+ }
+
+ /// If CanUseUndef is true, returns whether \p V is undef.
+ /// Otherwise always return false.
+ bool isUndefValue(Value *V) const {
+ if (!CanUseUndef)
+ return false;
+ return isa<UndefValue>(V);
+ }
};
// NOTE: the explicit multiple argument versions of these functions are
@@ -299,8 +299,8 @@ Value *SimplifyFreezeInst(Value *Op, const SimplifyQuery &Q);
Value *SimplifyInstruction(Instruction *I, const SimplifyQuery &Q,
OptimizationRemarkEmitter *ORE = nullptr);
-/// See if V simplifies when its operand Op is replaced with RepOp. If not,
-/// return null.
+/// See if V simplifies when its operand Op is replaced with RepOp. If not,
+/// return null.
/// AllowRefinement specifies whether the simplification can be a refinement,
/// or whether it needs to be strictly identical.
Value *SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/IntervalIterator.h b/contrib/libs/llvm12/include/llvm/Analysis/IntervalIterator.h
index 9476a63df6..105fcf3430 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/IntervalIterator.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/IntervalIterator.h
@@ -88,7 +88,7 @@ inline void addNodeToInterval(Interval *Int, BasicBlock *BB) {
// BasicBlocks are added to the interval.
inline void addNodeToInterval(Interval *Int, Interval *I) {
// Add all of the nodes in I as new nodes in Int.
- llvm::append_range(Int->Nodes, I->Nodes);
+ llvm::append_range(Int->Nodes, I->Nodes);
}
template<class NodeTy, class OrigContainer_t, class GT = GraphTraits<NodeTy *>,
@@ -234,7 +234,7 @@ private:
if (Int->isSuccessor(NodeHeader)) {
// If we were in the successor list from before... remove from succ list
- llvm::erase_value(Int->Successors, NodeHeader);
+ llvm::erase_value(Int->Successors, NodeHeader);
}
// Now that we have discovered that Node is in the interval, perhaps some
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/IteratedDominanceFrontier.h b/contrib/libs/llvm12/include/llvm/Analysis/IteratedDominanceFrontier.h
index 6036777c70..d3d6488d74 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/IteratedDominanceFrontier.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/IteratedDominanceFrontier.h
@@ -80,7 +80,7 @@ ChildrenGetterTy<BasicBlock, IsPostDom>::get(const NodeRef &N) {
return {Children.begin(), Children.end()};
}
- return GD->template getChildren<IsPostDom>(N);
+ return GD->template getChildren<IsPostDom>(N);
}
} // end of namespace IDFCalculatorDetail
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/LazyBranchProbabilityInfo.h b/contrib/libs/llvm12/include/llvm/Analysis/LazyBranchProbabilityInfo.h
index f0dfb97b52..fd7252c103 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/LazyBranchProbabilityInfo.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/LazyBranchProbabilityInfo.h
@@ -70,7 +70,7 @@ class LazyBranchProbabilityInfoPass : public FunctionPass {
BranchProbabilityInfo &getCalculated() {
if (!Calculated) {
assert(F && LI && "call setAnalysis");
- BPI.calculate(*F, *LI, TLI, nullptr, nullptr);
+ BPI.calculate(*F, *LI, TLI, nullptr, nullptr);
Calculated = true;
}
return BPI;
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/LazyCallGraph.h b/contrib/libs/llvm12/include/llvm/Analysis/LazyCallGraph.h
index a67d8079cd..2b0fa56f9d 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/LazyCallGraph.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/LazyCallGraph.h
@@ -1053,29 +1053,29 @@ public:
/// fully visited by the DFS prior to calling this routine.
void removeDeadFunction(Function &F);
- /// Add a new function split/outlined from an existing function.
- ///
- /// The new function may only reference other functions that the original
- /// function did.
- ///
- /// The original function must reference (either directly or indirectly) the
- /// new function.
- ///
- /// The new function may also reference the original function.
- /// It may end up in a parent SCC in the case that the original function's
- /// edge to the new function is a ref edge, and the edge back is a call edge.
- void addSplitFunction(Function &OriginalFunction, Function &NewFunction);
-
- /// Add new ref-recursive functions split/outlined from an existing function.
- ///
- /// The new functions may only reference other functions that the original
- /// function did. The new functions may reference (not call) the original
- /// function.
- ///
- /// The original function must reference (not call) all new functions.
- /// All new functions must reference (not call) each other.
- void addSplitRefRecursiveFunctions(Function &OriginalFunction,
- ArrayRef<Function *> NewFunctions);
+ /// Add a new function split/outlined from an existing function.
+ ///
+ /// The new function may only reference other functions that the original
+ /// function did.
+ ///
+ /// The original function must reference (either directly or indirectly) the
+ /// new function.
+ ///
+ /// The new function may also reference the original function.
+ /// It may end up in a parent SCC in the case that the original function's
+ /// edge to the new function is a ref edge, and the edge back is a call edge.
+ void addSplitFunction(Function &OriginalFunction, Function &NewFunction);
+
+ /// Add new ref-recursive functions split/outlined from an existing function.
+ ///
+ /// The new functions may only reference other functions that the original
+ /// function did. The new functions may reference (not call) the original
+ /// function.
+ ///
+ /// The original function must reference (not call) all new functions.
+ /// All new functions must reference (not call) each other.
+ void addSplitRefRecursiveFunctions(Function &OriginalFunction,
+ ArrayRef<Function *> NewFunctions);
///@}
@@ -1180,11 +1180,11 @@ private:
/// the NodeMap.
Node &insertInto(Function &F, Node *&MappedN);
- /// Helper to initialize a new node created outside of creating SCCs and add
- /// it to the NodeMap if necessary. For example, useful when a function is
- /// split.
- Node &initNode(Function &F);
-
+ /// Helper to initialize a new node created outside of creating SCCs and add
+ /// it to the NodeMap if necessary. For example, useful when a function is
+ /// split.
+ Node &initNode(Function &F);
+
/// Helper to update pointers back to the graph object during moves.
void updateGraphPtrs();
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/LazyValueInfo.h b/contrib/libs/llvm12/include/llvm/Analysis/LazyValueInfo.h
index ade4e43345..e729bfb6ae 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/LazyValueInfo.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/LazyValueInfo.h
@@ -78,20 +78,20 @@ public:
Instruction *CxtI = nullptr);
/// Determine whether the specified value comparison with a constant is known
- /// to be true or false at the specified instruction.
- /// \p Pred is a CmpInst predicate. If \p UseBlockValue is true, the block
- /// value is also taken into account.
+ /// to be true or false at the specified instruction.
+ /// \p Pred is a CmpInst predicate. If \p UseBlockValue is true, the block
+ /// value is also taken into account.
Tristate getPredicateAt(unsigned Pred, Value *V, Constant *C,
- Instruction *CxtI, bool UseBlockValue = false);
+ Instruction *CxtI, bool UseBlockValue = false);
- /// Determine whether the specified value is known to be a constant at the
- /// specified instruction. Return null if not.
- Constant *getConstant(Value *V, Instruction *CxtI);
+ /// Determine whether the specified value is known to be a constant at the
+ /// specified instruction. Return null if not.
+ Constant *getConstant(Value *V, Instruction *CxtI);
/// Return the ConstantRange constraint that is known to hold for the
- /// specified value at the specified instruction. This may only be called
+ /// specified value at the specified instruction. This may only be called
/// on integer-typed Values.
- ConstantRange getConstantRange(Value *V, Instruction *CxtI,
+ ConstantRange getConstantRange(Value *V, Instruction *CxtI,
bool UndefAllowed = true);
/// Determine whether the specified value is known to be a
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/Lint.h b/contrib/libs/llvm12/include/llvm/Analysis/Lint.h
index 76e5c760e1..69edc46162 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/Lint.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/Lint.h
@@ -26,34 +26,34 @@
#ifndef LLVM_ANALYSIS_LINT_H
#define LLVM_ANALYSIS_LINT_H
-#include "llvm/IR/PassManager.h"
-
+#include "llvm/IR/PassManager.h"
+
namespace llvm {
class FunctionPass;
class Module;
class Function;
-FunctionPass *createLintLegacyPassPass();
+FunctionPass *createLintLegacyPassPass();
-/// Lint a module.
+/// Lint a module.
///
/// This should only be used for debugging, because it plays games with
/// PassManagers and stuff.
-void lintModule(const Module &M);
+void lintModule(const Module &M);
+
+// Lint a function.
+void lintFunction(const Function &F);
-// Lint a function.
-void lintFunction(const Function &F);
+class LintPass : public PassInfoMixin<LintPass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
-class LintPass : public PassInfoMixin<LintPass> {
-public:
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
+} // namespace llvm
-} // namespace llvm
+#endif // LLVM_ANALYSIS_LINT_H
-#endif // LLVM_ANALYSIS_LINT_H
-
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/Loads.h b/contrib/libs/llvm12/include/llvm/Analysis/Loads.h
index 686b6cddc9..e9ee328a15 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/Loads.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/Loads.h
@@ -162,15 +162,15 @@ Value *FindAvailablePtrLoadStore(Value *Ptr, Type *AccessTy, bool AtLeastAtomic,
BasicBlock::iterator &ScanFrom,
unsigned MaxInstsToScan, AAResults *AA,
bool *IsLoadCSE, unsigned *NumScanedInst);
-
-/// Returns true if a pointer value \p A can be replace with another pointer
-/// value \B if they are deemed equal through some means (e.g. information from
-/// conditions).
-/// NOTE: the current implementations is incomplete and unsound. It does not
-/// reject all invalid cases yet, but will be made stricter in the future. In
-/// particular this means returning true means unknown if replacement is safe.
-bool canReplacePointersIfEqual(Value *A, Value *B, const DataLayout &DL,
- Instruction *CtxI);
+
+/// Returns true if a pointer value \p A can be replace with another pointer
+/// value \B if they are deemed equal through some means (e.g. information from
+/// conditions).
+/// NOTE: the current implementations is incomplete and unsound. It does not
+/// reject all invalid cases yet, but will be made stricter in the future. In
+/// particular this means returning true means unknown if replacement is safe.
+bool canReplacePointersIfEqual(Value *A, Value *B, const DataLayout &DL,
+ Instruction *CtxI);
}
#endif
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/LoopAccessAnalysis.h b/contrib/libs/llvm12/include/llvm/Analysis/LoopAccessAnalysis.h
index 2dca69742a..e1460d75cf 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/LoopAccessAnalysis.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/LoopAccessAnalysis.h
@@ -178,8 +178,8 @@ public:
MemoryDepChecker(PredicatedScalarEvolution &PSE, const Loop *L)
: PSE(PSE), InnermostLoop(L), AccessIdx(0), MaxSafeDepDistBytes(0),
- MaxSafeVectorWidthInBits(-1U),
- FoundNonConstantDistanceDependence(false),
+ MaxSafeVectorWidthInBits(-1U),
+ FoundNonConstantDistanceDependence(false),
Status(VectorizationSafetyStatus::Safe), RecordDependences(true) {}
/// Register the location (instructions are given increasing numbers)
@@ -212,21 +212,21 @@ public:
return Status == VectorizationSafetyStatus::Safe;
}
- /// Return true if the number of elements that are safe to operate on
- /// simultaneously is not bounded.
- bool isSafeForAnyVectorWidth() const {
- return MaxSafeVectorWidthInBits == UINT_MAX;
- }
-
+ /// Return true if the number of elements that are safe to operate on
+ /// simultaneously is not bounded.
+ bool isSafeForAnyVectorWidth() const {
+ return MaxSafeVectorWidthInBits == UINT_MAX;
+ }
+
/// The maximum number of bytes of a vector register we can vectorize
/// the accesses safely with.
uint64_t getMaxSafeDepDistBytes() { return MaxSafeDepDistBytes; }
/// Return the number of elements that are safe to operate on
/// simultaneously, multiplied by the size of the element in bits.
- uint64_t getMaxSafeVectorWidthInBits() const {
- return MaxSafeVectorWidthInBits;
- }
+ uint64_t getMaxSafeVectorWidthInBits() const {
+ return MaxSafeVectorWidthInBits;
+ }
/// In same cases when the dependency check fails we can still
/// vectorize the loop with a dynamic array access check.
@@ -291,7 +291,7 @@ private:
/// 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 MaxSafeVectorWidthInBits;
+ uint64_t MaxSafeVectorWidthInBits;
/// If we see a non-constant dependence distance we can still try to
/// vectorize this loop with runtime checks.
@@ -434,7 +434,7 @@ public:
bool UseDependencies);
/// Returns the checks that generateChecks created.
- const SmallVectorImpl<RuntimePointerCheck> &getChecks() const {
+ const SmallVectorImpl<RuntimePointerCheck> &getChecks() const {
return Checks;
}
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/LoopAnalysisManager.h b/contrib/libs/llvm12/include/llvm/Analysis/LoopAnalysisManager.h
index b341eba1f9..3b1043055d 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/LoopAnalysisManager.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/LoopAnalysisManager.h
@@ -64,7 +64,7 @@ struct LoopStandardAnalysisResults {
ScalarEvolution &SE;
TargetLibraryInfo &TLI;
TargetTransformInfo &TTI;
- BlockFrequencyInfo *BFI;
+ BlockFrequencyInfo *BFI;
MemorySSA *MSSA;
};
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/LoopCacheAnalysis.h b/contrib/libs/llvm12/include/llvm/Analysis/LoopCacheAnalysis.h
index db618c6151..7b61a992aa 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/LoopCacheAnalysis.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/LoopCacheAnalysis.h
@@ -23,18 +23,18 @@
#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/IR/Instructions.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
-class AAResults;
-class DependenceInfo;
+class AAResults;
+class DependenceInfo;
class LPMUpdater;
-class ScalarEvolution;
-class SCEV;
-class TargetTransformInfo;
-
+class ScalarEvolution;
+class SCEV;
+class TargetTransformInfo;
+
using CacheCostTy = int64_t;
using LoopVectorTy = SmallVector<Loop *, 8>;
@@ -78,7 +78,7 @@ public:
/// the same chace line iff the distance between them in the innermost
/// dimension is less than the cache line size. Return None if unsure.
Optional<bool> hasSpacialReuse(const IndexedReference &Other, unsigned CLS,
- AAResults &AA) const;
+ AAResults &AA) const;
/// Return true if the current object and the indexed reference \p Other
/// have distance smaller than \p MaxDistance in the dimension associated with
@@ -86,7 +86,7 @@ public:
/// MaxDistance and None if unsure.
Optional<bool> hasTemporalReuse(const IndexedReference &Other,
unsigned MaxDistance, const Loop &L,
- DependenceInfo &DI, AAResults &AA) const;
+ DependenceInfo &DI, AAResults &AA) const;
/// Compute the cost of the reference w.r.t. the given loop \p L when it is
/// considered in the innermost position in the loop nest.
@@ -126,7 +126,7 @@ private:
/// Return true if the given reference \p Other is definetely aliased with
/// the indexed reference represented by this class.
- bool isAliased(const IndexedReference &Other, AAResults &AA) const;
+ bool isAliased(const IndexedReference &Other, AAResults &AA) const;
private:
/// True if the reference can be delinearized, false otherwise.
@@ -191,7 +191,7 @@ public:
/// between array elements accessed in a loop so that the elements are
/// classified to have temporal reuse.
CacheCost(const LoopVectorTy &Loops, const LoopInfo &LI, ScalarEvolution &SE,
- TargetTransformInfo &TTI, AAResults &AA, DependenceInfo &DI,
+ TargetTransformInfo &TTI, AAResults &AA, DependenceInfo &DI,
Optional<unsigned> TRT = None);
/// Create a CacheCost for the loop nest rooted by \p Root.
@@ -205,9 +205,9 @@ public:
/// Return the estimated cost of loop \p L if the given loop is part of the
/// loop nest associated with this object. Return -1 otherwise.
CacheCostTy getLoopCost(const Loop &L) const {
- auto IT = llvm::find_if(LoopCosts, [&L](const LoopCacheCostTy &LCC) {
- return LCC.first == &L;
- });
+ auto IT = llvm::find_if(LoopCosts, [&L](const LoopCacheCostTy &LCC) {
+ return LCC.first == &L;
+ });
return (IT != LoopCosts.end()) ? (*IT).second : -1;
}
@@ -266,7 +266,7 @@ private:
const LoopInfo &LI;
ScalarEvolution &SE;
TargetTransformInfo &TTI;
- AAResults &AA;
+ AAResults &AA;
DependenceInfo &DI;
};
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/LoopInfo.h b/contrib/libs/llvm12/include/llvm/Analysis/LoopInfo.h
index 52ee839a13..0674e1d61f 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/LoopInfo.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/LoopInfo.h
@@ -163,17 +163,17 @@ public:
reverse_iterator rbegin() const { return getSubLoops().rbegin(); }
reverse_iterator rend() const { return getSubLoops().rend(); }
- // LoopInfo does not detect irreducible control flow, just natural
- // loops. That is, it is possible that there is cyclic control
- // flow within the "innermost loop" or around the "outermost
- // loop".
-
- /// Return true if the loop does not contain any (natural) loops.
- bool isInnermost() const { return getSubLoops().empty(); }
- /// Return true if the loop does not have a parent (natural) loop
- // (i.e. it is outermost, which is the same as top-level).
- bool isOutermost() const { return getParentLoop() == nullptr; }
-
+ // LoopInfo does not detect irreducible control flow, just natural
+ // loops. That is, it is possible that there is cyclic control
+ // flow within the "innermost loop" or around the "outermost
+ // loop".
+
+ /// Return true if the loop does not contain any (natural) loops.
+ bool isInnermost() const { return getSubLoops().empty(); }
+ /// Return true if the loop does not have a parent (natural) loop
+ // (i.e. it is outermost, which is the same as top-level).
+ bool isOutermost() const { return getParentLoop() == nullptr; }
+
/// Get a list of the basic blocks which make up this loop.
ArrayRef<BlockT *> getBlocks() const {
assert(!isInvalid() && "Loop not in a valid state!");
@@ -309,9 +309,9 @@ public:
/// Otherwise return null.
BlockT *getUniqueExitBlock() const;
- /// Return true if this loop does not have any exit blocks.
- bool hasNoExitBlocks() const;
-
+ /// Return true if this loop does not have any exit blocks.
+ bool hasNoExitBlocks() const;
+
/// Edge type.
typedef std::pair<BlockT *, BlockT *> Edge;
@@ -850,9 +850,9 @@ public:
/// unrolling pass is run more than once (which it generally is).
void setLoopAlreadyUnrolled();
- /// Add llvm.loop.mustprogress to this loop's loop id metadata.
- void setLoopMustProgress();
-
+ /// Add llvm.loop.mustprogress to this loop's loop id metadata.
+ void setLoopMustProgress();
+
void dump() const;
void dumpVerbose() const;
@@ -997,7 +997,7 @@ public:
LoopT *removeLoop(iterator I) {
assert(I != end() && "Cannot remove end iterator!");
LoopT *L = *I;
- assert(L->isOutermost() && "Not a top-level loop!");
+ assert(L->isOutermost() && "Not a top-level loop!");
TopLevelLoops.erase(TopLevelLoops.begin() + (I - begin()));
return L;
}
@@ -1025,7 +1025,7 @@ public:
/// This adds the specified loop to the collection of top-level loops.
void addTopLevelLoop(LoopT *New) {
- assert(New->isOutermost() && "Loop already in subloop!");
+ assert(New->isOutermost() && "Loop already in subloop!");
TopLevelLoops.push_back(New);
}
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/LoopInfoImpl.h b/contrib/libs/llvm12/include/llvm/Analysis/LoopInfoImpl.h
index 72b1f3d0d5..6032e9babb 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/LoopInfoImpl.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/LoopInfoImpl.h
@@ -75,13 +75,13 @@ void LoopBase<BlockT, LoopT>::getExitBlocks(
ExitBlocks.push_back(Succ);
}
-template <class BlockT, class LoopT>
-bool LoopBase<BlockT, LoopT>::hasNoExitBlocks() const {
- SmallVector<BlockT *, 8> ExitBlocks;
- getExitBlocks(ExitBlocks);
- return ExitBlocks.empty();
-}
-
+template <class BlockT, class LoopT>
+bool LoopBase<BlockT, LoopT>::hasNoExitBlocks() const {
+ SmallVector<BlockT *, 8> ExitBlocks;
+ getExitBlocks(ExitBlocks);
+ return ExitBlocks.empty();
+}
+
/// getExitBlock - If getExitBlocks would return exactly one block,
/// return that block. Otherwise return null.
template <class BlockT, class LoopT>
@@ -516,7 +516,7 @@ void PopulateLoopsDFS<BlockT, LoopT>::insertIntoLoop(BlockT *Block) {
if (Subloop && Block == Subloop->getHeader()) {
// We reach this point once per subloop after processing all the blocks in
// the subloop.
- if (!Subloop->isOutermost())
+ if (!Subloop->isOutermost())
Subloop->getParentLoop()->getSubLoopsVector().push_back(Subloop);
else
LI->addTopLevelLoop(Subloop);
@@ -680,13 +680,13 @@ static void compareLoops(const LoopT *L, const LoopT *OtherL,
"Mismatched basic blocks in the loops!");
const SmallPtrSetImpl<const BlockT *> &BlocksSet = L->getBlocksSet();
- const SmallPtrSetImpl<const BlockT *> &OtherBlocksSet =
- OtherL->getBlocksSet();
+ const SmallPtrSetImpl<const BlockT *> &OtherBlocksSet =
+ OtherL->getBlocksSet();
assert(BlocksSet.size() == OtherBlocksSet.size() &&
- llvm::all_of(BlocksSet,
- [&OtherBlocksSet](const BlockT *BB) {
- return OtherBlocksSet.count(BB);
- }) &&
+ llvm::all_of(BlocksSet,
+ [&OtherBlocksSet](const BlockT *BB) {
+ return OtherBlocksSet.count(BB);
+ }) &&
"Mismatched basic blocks in BlocksSets!");
}
#endif
@@ -696,7 +696,7 @@ void LoopInfoBase<BlockT, LoopT>::verify(
const DomTreeBase<BlockT> &DomTree) const {
DenseSet<const LoopT *> Loops;
for (iterator I = begin(), E = end(); I != E; ++I) {
- assert((*I)->isOutermost() && "Top-level loop has a parent!");
+ assert((*I)->isOutermost() && "Top-level loop has a parent!");
(*I)->verifyLoopNest(&Loops);
}
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/LoopNestAnalysis.h b/contrib/libs/llvm12/include/llvm/Analysis/LoopNestAnalysis.h
index 4c6de08553..2c7c3a21e3 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/LoopNestAnalysis.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/LoopNestAnalysis.h
@@ -21,7 +21,7 @@
#ifndef LLVM_ANALYSIS_LOOPNESTANALYSIS_H
#define LLVM_ANALYSIS_LOOPNESTANALYSIS_H
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/Analysis/LoopInfo.h"
@@ -67,12 +67,12 @@ public:
/// getMaxPerfectDepth(Loop_i) would return 2.
static unsigned getMaxPerfectDepth(const Loop &Root, ScalarEvolution &SE);
- /// Recursivelly traverse all empty 'single successor' basic blocks of \p From
- /// (if there are any). Return the last basic block found or \p End if it was
- /// reached during the search.
- static const BasicBlock &skipEmptyBlockUntil(const BasicBlock *From,
- const BasicBlock *End);
-
+ /// Recursivelly traverse all empty 'single successor' basic blocks of \p From
+ /// (if there are any). Return the last basic block found or \p End if it was
+ /// reached during the search.
+ static const BasicBlock &skipEmptyBlockUntil(const BasicBlock *From,
+ const BasicBlock *End);
+
/// Return the outermost loop in the loop nest.
Loop &getOutermostLoop() const { return *Loops.front(); }
@@ -138,16 +138,16 @@ public:
/// Return true if all loops in the loop nest are in simplify form.
bool areAllLoopsSimplifyForm() const {
- return all_of(Loops, [](const Loop *L) { return L->isLoopSimplifyForm(); });
+ return all_of(Loops, [](const Loop *L) { return L->isLoopSimplifyForm(); });
+ }
+
+ /// Return true if all loops in the loop nest are in rotated form.
+ bool areAllLoopsRotatedForm() const {
+ return all_of(Loops, [](const Loop *L) { return L->isRotatedForm(); });
}
- /// Return true if all loops in the loop nest are in rotated form.
- bool areAllLoopsRotatedForm() const {
- return all_of(Loops, [](const Loop *L) { return L->isRotatedForm(); });
- }
-
- StringRef getName() const { return Loops.front()->getName(); }
-
+ StringRef getName() const { return Loops.front()->getName(); }
+
protected:
const unsigned MaxPerfectDepth; // maximum perfect nesting depth level.
LoopVectorTy Loops; // the loops in the nest (in breadth first order).
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/MLInlineAdvisor.h b/contrib/libs/llvm12/include/llvm/Analysis/MLInlineAdvisor.h
index 6f4a551bb6..da34d4fe96 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/MLInlineAdvisor.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/MLInlineAdvisor.h
@@ -47,13 +47,13 @@ public:
const MLModelRunner &getModelRunner() const { return *ModelRunner.get(); }
protected:
- std::unique_ptr<InlineAdvice> getAdviceImpl(CallBase &CB) override;
+ std::unique_ptr<InlineAdvice> getAdviceImpl(CallBase &CB) override;
+
+ std::unique_ptr<InlineAdvice> getMandatoryAdvice(CallBase &CB,
+ bool Advice) override;
+
+ virtual std::unique_ptr<MLInlineAdvice> getMandatoryAdviceImpl(CallBase &CB);
- std::unique_ptr<InlineAdvice> getMandatoryAdvice(CallBase &CB,
- bool Advice) override;
-
- virtual std::unique_ptr<MLInlineAdvice> getMandatoryAdviceImpl(CallBase &CB);
-
virtual std::unique_ptr<MLInlineAdvice>
getAdviceFromModel(CallBase &CB, OptimizationRemarkEmitter &ORE);
@@ -113,7 +113,7 @@ private:
} // namespace llvm
#endif // LLVM_ANALYSIS_MLINLINEADVISOR_H
-
+
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/MemDerefPrinter.h b/contrib/libs/llvm12/include/llvm/Analysis/MemDerefPrinter.h
index 22d163f8d1..c327d44935 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/MemDerefPrinter.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/MemDerefPrinter.h
@@ -1,35 +1,35 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- MemDerefPrinter.h - Printer for isDereferenceablePointer -----------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_MEMDEREFPRINTER_H
-#define LLVM_ANALYSIS_MEMDEREFPRINTER_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-class MemDerefPrinterPass : public PassInfoMixin<MemDerefPrinterPass> {
- raw_ostream &OS;
-
-public:
- MemDerefPrinterPass(raw_ostream &OS) : OS(OS) {}
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-} // namespace llvm
-
-#endif // LLVM_ANALYSIS_MEMDEREFPRINTER_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- MemDerefPrinter.h - Printer for isDereferenceablePointer -----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_MEMDEREFPRINTER_H
+#define LLVM_ANALYSIS_MEMDEREFPRINTER_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+class MemDerefPrinterPass : public PassInfoMixin<MemDerefPrinterPass> {
+ raw_ostream &OS;
+
+public:
+ MemDerefPrinterPass(raw_ostream &OS) : OS(OS) {}
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+} // namespace llvm
+
+#endif // LLVM_ANALYSIS_MEMDEREFPRINTER_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/MemoryDependenceAnalysis.h b/contrib/libs/llvm12/include/llvm/Analysis/MemoryDependenceAnalysis.h
index 137c7e59d0..84ec93a5cf 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/MemoryDependenceAnalysis.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/MemoryDependenceAnalysis.h
@@ -309,7 +309,7 @@ private:
/// The maximum size of the dereferences of the pointer.
///
/// May be UnknownSize if the sizes are unknown.
- LocationSize Size = LocationSize::afterPointer();
+ LocationSize Size = LocationSize::afterPointer();
/// The AA tags associated with dereferences of the pointer.
///
/// The members may be null if there are no tags or conflicting tags.
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/MemoryLocation.h b/contrib/libs/llvm12/include/llvm/Analysis/MemoryLocation.h
index b4cc30b572..331bbb7515 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/MemoryLocation.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/MemoryLocation.h
@@ -71,10 +71,10 @@ class VAArgInst;
// None.
class LocationSize {
enum : uint64_t {
- BeforeOrAfterPointer = ~uint64_t(0),
- AfterPointer = BeforeOrAfterPointer - 1,
- MapEmpty = BeforeOrAfterPointer - 2,
- MapTombstone = BeforeOrAfterPointer - 3,
+ BeforeOrAfterPointer = ~uint64_t(0),
+ AfterPointer = BeforeOrAfterPointer - 1,
+ MapEmpty = BeforeOrAfterPointer - 2,
+ MapTombstone = BeforeOrAfterPointer - 3,
ImpreciseBit = uint64_t(1) << 63,
// The maximum value we can represent without falling back to 'unknown'.
@@ -89,11 +89,11 @@ class LocationSize {
constexpr LocationSize(uint64_t Raw, DirectConstruction): Value(Raw) {}
- static_assert(AfterPointer & ImpreciseBit,
- "AfterPointer is imprecise by definition.");
- static_assert(BeforeOrAfterPointer & ImpreciseBit,
- "BeforeOrAfterPointer is imprecise by definition.");
-
+ static_assert(AfterPointer & ImpreciseBit,
+ "AfterPointer is imprecise by definition.");
+ static_assert(BeforeOrAfterPointer & ImpreciseBit,
+ "BeforeOrAfterPointer is imprecise by definition.");
+
public:
// FIXME: Migrate all users to construct via either `precise` or `upperBound`,
// to make it more obvious at the callsite the kind of size that they're
@@ -102,12 +102,12 @@ public:
// Since the overwhelming majority of users of this provide precise values,
// this assumes the provided value is precise.
constexpr LocationSize(uint64_t Raw)
- : Value(Raw > MaxValue ? AfterPointer : Raw) {}
+ : Value(Raw > MaxValue ? AfterPointer : Raw) {}
static LocationSize precise(uint64_t Value) { return LocationSize(Value); }
static LocationSize precise(TypeSize Value) {
if (Value.isScalable())
- return afterPointer();
+ return afterPointer();
return precise(Value.getFixedSize());
}
@@ -116,27 +116,27 @@ public:
if (LLVM_UNLIKELY(Value == 0))
return precise(0);
if (LLVM_UNLIKELY(Value > MaxValue))
- return afterPointer();
+ return afterPointer();
return LocationSize(Value | ImpreciseBit, Direct);
}
static LocationSize upperBound(TypeSize Value) {
if (Value.isScalable())
- return afterPointer();
+ return afterPointer();
return upperBound(Value.getFixedSize());
}
- /// Any location after the base pointer (but still within the underlying
- /// object).
- constexpr static LocationSize afterPointer() {
- return LocationSize(AfterPointer, Direct);
+ /// Any location after the base pointer (but still within the underlying
+ /// object).
+ constexpr static LocationSize afterPointer() {
+ return LocationSize(AfterPointer, Direct);
+ }
+
+ /// Any location before or after the base pointer (but still within the
+ /// underlying object).
+ constexpr static LocationSize beforeOrAfterPointer() {
+ return LocationSize(BeforeOrAfterPointer, Direct);
}
- /// Any location before or after the base pointer (but still within the
- /// underlying object).
- constexpr static LocationSize beforeOrAfterPointer() {
- return LocationSize(BeforeOrAfterPointer, Direct);
- }
-
// Sentinel values, generally used for maps.
constexpr static LocationSize mapTombstone() {
return LocationSize(MapTombstone, Direct);
@@ -151,24 +151,24 @@ public:
if (Other == *this)
return *this;
- if (Value == BeforeOrAfterPointer || Other.Value == BeforeOrAfterPointer)
- return beforeOrAfterPointer();
- if (Value == AfterPointer || Other.Value == AfterPointer)
- return afterPointer();
+ if (Value == BeforeOrAfterPointer || Other.Value == BeforeOrAfterPointer)
+ return beforeOrAfterPointer();
+ if (Value == AfterPointer || Other.Value == AfterPointer)
+ return afterPointer();
return upperBound(std::max(getValue(), Other.getValue()));
}
- bool hasValue() const {
- return Value != AfterPointer && Value != BeforeOrAfterPointer;
- }
+ bool hasValue() const {
+ return Value != AfterPointer && Value != BeforeOrAfterPointer;
+ }
uint64_t getValue() const {
assert(hasValue() && "Getting value from an unknown LocationSize!");
return Value & ~ImpreciseBit;
}
// Returns whether or not this value is precise. Note that if a value is
- // precise, it's guaranteed to not be unknown.
+ // precise, it's guaranteed to not be unknown.
bool isPrecise() const {
return (Value & ImpreciseBit) == 0;
}
@@ -176,9 +176,9 @@ public:
// Convenience method to check if this LocationSize's value is 0.
bool isZero() const { return hasValue() && getValue() == 0; }
- /// Whether accesses before the base pointer are possible.
- bool mayBeBeforePointer() const { return Value == BeforeOrAfterPointer; }
-
+ /// Whether accesses before the base pointer are possible.
+ bool mayBeBeforePointer() const { return Value == BeforeOrAfterPointer; }
+
bool operator==(const LocationSize &Other) const {
return Value == Other.Value;
}
@@ -269,30 +269,30 @@ public:
return getForArgument(Call, ArgIdx, &TLI);
}
- /// Return a location that may access any location after Ptr, while remaining
- /// within the underlying object.
- static MemoryLocation getAfter(const Value *Ptr,
- const AAMDNodes &AATags = AAMDNodes()) {
- return MemoryLocation(Ptr, LocationSize::afterPointer(), AATags);
- }
-
- /// Return a location that may access any location before or after Ptr, while
- /// remaining within the underlying object.
- static MemoryLocation
- getBeforeOrAfter(const Value *Ptr, const AAMDNodes &AATags = AAMDNodes()) {
- return MemoryLocation(Ptr, LocationSize::beforeOrAfterPointer(), AATags);
- }
-
+ /// Return a location that may access any location after Ptr, while remaining
+ /// within the underlying object.
+ static MemoryLocation getAfter(const Value *Ptr,
+ const AAMDNodes &AATags = AAMDNodes()) {
+ return MemoryLocation(Ptr, LocationSize::afterPointer(), AATags);
+ }
+
+ /// Return a location that may access any location before or after Ptr, while
+ /// remaining within the underlying object.
+ static MemoryLocation
+ getBeforeOrAfter(const Value *Ptr, const AAMDNodes &AATags = AAMDNodes()) {
+ return MemoryLocation(Ptr, LocationSize::beforeOrAfterPointer(), AATags);
+ }
+
// Return the exact size if the exact size is known at compiletime,
// otherwise return MemoryLocation::UnknownSize.
static uint64_t getSizeOrUnknown(const TypeSize &T) {
return T.isScalable() ? UnknownSize : T.getFixedSize();
}
- MemoryLocation()
- : Ptr(nullptr), Size(LocationSize::beforeOrAfterPointer()), AATags() {}
-
- explicit MemoryLocation(const Value *Ptr, LocationSize Size,
+ MemoryLocation()
+ : Ptr(nullptr), Size(LocationSize::beforeOrAfterPointer()), AATags() {}
+
+ explicit MemoryLocation(const Value *Ptr, LocationSize Size,
const AAMDNodes &AATags = AAMDNodes())
: Ptr(Ptr), Size(Size), AATags(AATags) {}
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/MemorySSA.h b/contrib/libs/llvm12/include/llvm/Analysis/MemorySSA.h
index 906e09dcc9..a8b23dccd2 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/MemorySSA.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/MemorySSA.h
@@ -95,7 +95,7 @@
#include "llvm/IR/DerivedUser.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/Operator.h"
+#include "llvm/IR/Operator.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
@@ -116,7 +116,7 @@ namespace llvm {
/// Enables memory ssa as a dependency for loop passes.
extern cl::opt<bool> EnableMSSALoopDependency;
-class AllocaInst;
+class AllocaInst;
class Function;
class Instruction;
class MemoryAccess;
@@ -279,7 +279,7 @@ public:
// Retrieve AliasResult type of the optimized access. Ideally this would be
// returned by the caching walker and may go away in the future.
Optional<AliasResult> getOptimizedAccessType() const {
- return isOptimized() ? OptimizedAccessAlias : None;
+ return isOptimized() ? OptimizedAccessAlias : None;
}
/// Reset the ID of what this MemoryUse was optimized to, causing it to
@@ -1185,11 +1185,11 @@ class upward_defs_iterator
using BaseT = upward_defs_iterator::iterator_facade_base;
public:
- upward_defs_iterator(const MemoryAccessPair &Info, DominatorTree *DT,
- bool *PerformedPhiTranslation = nullptr)
+ upward_defs_iterator(const MemoryAccessPair &Info, DominatorTree *DT,
+ bool *PerformedPhiTranslation = nullptr)
: DefIterator(Info.first), Location(Info.second),
- OriginalAccess(Info.first), DT(DT),
- PerformedPhiTranslation(PerformedPhiTranslation) {
+ OriginalAccess(Info.first), DT(DT),
+ PerformedPhiTranslation(PerformedPhiTranslation) {
CurrentPair.first = nullptr;
WalkingPhi = Info.first && isa<MemoryPhi>(Info.first);
@@ -1221,42 +1221,42 @@ public:
BasicBlock *getPhiArgBlock() const { return DefIterator.getPhiArgBlock(); }
private:
- /// Returns true if \p Ptr is guaranteed to be loop invariant for any possible
- /// loop. In particular, this guarantees that it only references a single
- /// MemoryLocation during execution of the containing function.
- bool IsGuaranteedLoopInvariant(Value *Ptr) const;
-
+ /// Returns true if \p Ptr is guaranteed to be loop invariant for any possible
+ /// loop. In particular, this guarantees that it only references a single
+ /// MemoryLocation during execution of the containing function.
+ bool IsGuaranteedLoopInvariant(Value *Ptr) const;
+
void fillInCurrentPair() {
CurrentPair.first = *DefIterator;
- CurrentPair.second = Location;
+ CurrentPair.second = Location;
if (WalkingPhi && Location.Ptr) {
- // Mark size as unknown, if the location is not guaranteed to be
- // loop-invariant for any possible loop in the function. Setting the size
- // to unknown guarantees that any memory accesses that access locations
- // after the pointer are considered as clobbers, which is important to
- // catch loop carried dependences.
- if (Location.Ptr &&
- !IsGuaranteedLoopInvariant(const_cast<Value *>(Location.Ptr)))
- CurrentPair.second =
- Location.getWithNewSize(LocationSize::beforeOrAfterPointer());
+ // Mark size as unknown, if the location is not guaranteed to be
+ // loop-invariant for any possible loop in the function. Setting the size
+ // to unknown guarantees that any memory accesses that access locations
+ // after the pointer are considered as clobbers, which is important to
+ // catch loop carried dependences.
+ if (Location.Ptr &&
+ !IsGuaranteedLoopInvariant(const_cast<Value *>(Location.Ptr)))
+ CurrentPair.second =
+ Location.getWithNewSize(LocationSize::beforeOrAfterPointer());
PHITransAddr Translator(
const_cast<Value *>(Location.Ptr),
OriginalAccess->getBlock()->getModule()->getDataLayout(), nullptr);
-
+
if (!Translator.PHITranslateValue(OriginalAccess->getBlock(),
DefIterator.getPhiArgBlock(), DT,
- true)) {
- Value *TransAddr = Translator.getAddr();
- if (TransAddr != Location.Ptr) {
- CurrentPair.second = CurrentPair.second.getWithNewPtr(TransAddr);
-
- if (TransAddr &&
- !IsGuaranteedLoopInvariant(const_cast<Value *>(TransAddr)))
- CurrentPair.second = CurrentPair.second.getWithNewSize(
- LocationSize::beforeOrAfterPointer());
-
- if (PerformedPhiTranslation)
- *PerformedPhiTranslation = true;
+ true)) {
+ Value *TransAddr = Translator.getAddr();
+ if (TransAddr != Location.Ptr) {
+ CurrentPair.second = CurrentPair.second.getWithNewPtr(TransAddr);
+
+ if (TransAddr &&
+ !IsGuaranteedLoopInvariant(const_cast<Value *>(TransAddr)))
+ CurrentPair.second = CurrentPair.second.getWithNewSize(
+ LocationSize::beforeOrAfterPointer());
+
+ if (PerformedPhiTranslation)
+ *PerformedPhiTranslation = true;
}
}
}
@@ -1266,15 +1266,15 @@ private:
memoryaccess_def_iterator DefIterator;
MemoryLocation Location;
MemoryAccess *OriginalAccess = nullptr;
- DominatorTree *DT = nullptr;
+ DominatorTree *DT = nullptr;
bool WalkingPhi = false;
- bool *PerformedPhiTranslation = nullptr;
+ bool *PerformedPhiTranslation = nullptr;
};
-inline upward_defs_iterator
-upward_defs_begin(const MemoryAccessPair &Pair, DominatorTree &DT,
- bool *PerformedPhiTranslation = nullptr) {
- return upward_defs_iterator(Pair, &DT, PerformedPhiTranslation);
+inline upward_defs_iterator
+upward_defs_begin(const MemoryAccessPair &Pair, DominatorTree &DT,
+ bool *PerformedPhiTranslation = nullptr) {
+ return upward_defs_iterator(Pair, &DT, PerformedPhiTranslation);
}
inline upward_defs_iterator upward_defs_end() { return upward_defs_iterator(); }
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/MemorySSAUpdater.h b/contrib/libs/llvm12/include/llvm/Analysis/MemorySSAUpdater.h
index f469eaa962..2f1cfde006 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/MemorySSAUpdater.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/MemorySSAUpdater.h
@@ -126,11 +126,11 @@ public:
ArrayRef<BasicBlock *> ExitBlocks,
ArrayRef<std::unique_ptr<ValueToValueMapTy>> VMaps, DominatorTree &DT);
- /// Apply CFG updates, analogous with the DT edge updates. By default, the
- /// DT is assumed to be already up to date. If UpdateDTFirst is true, first
- /// update the DT with the same updates.
- void applyUpdates(ArrayRef<CFGUpdate> Updates, DominatorTree &DT,
- bool UpdateDTFirst = false);
+ /// Apply CFG updates, analogous with the DT edge updates. By default, the
+ /// DT is assumed to be already up to date. If UpdateDTFirst is true, first
+ /// update the DT with the same updates.
+ void applyUpdates(ArrayRef<CFGUpdate> Updates, DominatorTree &DT,
+ bool UpdateDTFirst = false);
/// Apply CFG insert updates, analogous with the DT edge updates.
void applyInsertUpdates(ArrayRef<CFGUpdate> Updates, DominatorTree &DT);
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/ModuleDebugInfoPrinter.h b/contrib/libs/llvm12/include/llvm/Analysis/ModuleDebugInfoPrinter.h
index 838aa9d908..7472cc410a 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/ModuleDebugInfoPrinter.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/ModuleDebugInfoPrinter.h
@@ -1,40 +1,40 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- ModuleDebugInfoPrinter.h - -----------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_MODULEDEBUGINFOPRINTER_H
-#define LLVM_ANALYSIS_MODULEDEBUGINFOPRINTER_H
-
-#include "llvm/IR/DebugInfo.h"
-#include "llvm/IR/PassManager.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace llvm {
-
-class ModuleDebugInfoPrinterPass
- : public PassInfoMixin<ModuleDebugInfoPrinterPass> {
- DebugInfoFinder Finder;
- raw_ostream &OS;
-
-public:
- explicit ModuleDebugInfoPrinterPass(raw_ostream &OS);
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-};
-} // end namespace llvm
-
-#endif // LLVM_ANALYSIS_MODULEDEBUGINFOPRINTER_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- ModuleDebugInfoPrinter.h - -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_MODULEDEBUGINFOPRINTER_H
+#define LLVM_ANALYSIS_MODULEDEBUGINFOPRINTER_H
+
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+class ModuleDebugInfoPrinterPass
+ : public PassInfoMixin<ModuleDebugInfoPrinterPass> {
+ DebugInfoFinder Finder;
+ raw_ostream &OS;
+
+public:
+ explicit ModuleDebugInfoPrinterPass(raw_ostream &OS);
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+} // end namespace llvm
+
+#endif // LLVM_ANALYSIS_MODULEDEBUGINFOPRINTER_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/MustExecute.h b/contrib/libs/llvm12/include/llvm/Analysis/MustExecute.h
index 4f21c153cc..d6998f6de4 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/MustExecute.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/MustExecute.h
@@ -34,8 +34,8 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/InstructionPrecedenceTracking.h"
-#include "llvm/IR/PassManager.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Support/raw_ostream.h"
namespace llvm {
@@ -550,23 +550,23 @@ private:
MustBeExecutedIterator EndIterator;
};
-class MustExecutePrinterPass : public PassInfoMixin<MustExecutePrinterPass> {
- raw_ostream &OS;
-
-public:
- MustExecutePrinterPass(raw_ostream &OS) : OS(OS) {}
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-
-class MustBeExecutedContextPrinterPass
- : public PassInfoMixin<MustBeExecutedContextPrinterPass> {
- raw_ostream &OS;
-
-public:
- MustBeExecutedContextPrinterPass(raw_ostream &OS) : OS(OS) {}
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-};
-
+class MustExecutePrinterPass : public PassInfoMixin<MustExecutePrinterPass> {
+ raw_ostream &OS;
+
+public:
+ MustExecutePrinterPass(raw_ostream &OS) : OS(OS) {}
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+class MustBeExecutedContextPrinterPass
+ : public PassInfoMixin<MustBeExecutedContextPrinterPass> {
+ raw_ostream &OS;
+
+public:
+ MustBeExecutedContextPrinterPass(raw_ostream &OS) : OS(OS) {}
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
} // namespace llvm
#endif
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/ObjCARCAnalysisUtils.h b/contrib/libs/llvm12/include/llvm/Analysis/ObjCARCAnalysisUtils.h
index f0814f34db..7c9b1ff296 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/ObjCARCAnalysisUtils.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/ObjCARCAnalysisUtils.h
@@ -37,9 +37,9 @@
#include "llvm/IR/ValueHandle.h"
namespace llvm {
-
-class AAResults;
-
+
+class AAResults;
+
namespace objcarc {
/// A handy option to enable/disable all ARC Optimizations.
@@ -73,9 +73,9 @@ inline bool ModuleHasARC(const Module &M) {
/// 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) {
+inline const Value *GetUnderlyingObjCPtr(const Value *V) {
for (;;) {
- V = getUnderlyingObject(V);
+ V = getUnderlyingObject(V);
if (!IsForwarding(GetBasicARCInstKind(V)))
break;
V = cast<CallInst>(V)->getArgOperand(0);
@@ -86,12 +86,12 @@ inline const Value *GetUnderlyingObjCPtr(const Value *V) {
/// A wrapper for GetUnderlyingObjCPtr used for results memoization.
inline const Value *
-GetUnderlyingObjCPtrCached(const Value *V,
+GetUnderlyingObjCPtrCached(const Value *V,
DenseMap<const Value *, WeakTrackingVH> &Cache) {
if (auto InCache = Cache.lookup(V))
return InCache;
- const Value *Computed = GetUnderlyingObjCPtr(V);
+ const Value *Computed = GetUnderlyingObjCPtr(V);
Cache[V] = const_cast<Value *>(Computed);
return Computed;
}
@@ -154,7 +154,7 @@ inline bool IsPotentialRetainableObjPtr(const Value *Op) {
return false;
// Special arguments can not be a valid retainable object pointer.
if (const Argument *Arg = dyn_cast<Argument>(Op))
- if (Arg->hasPassPointeeByValueCopyAttr() || Arg->hasNestAttr() ||
+ if (Arg->hasPassPointeeByValueCopyAttr() || Arg->hasNestAttr() ||
Arg->hasStructRetAttr())
return false;
// Only consider values with pointer types.
@@ -170,7 +170,7 @@ inline bool IsPotentialRetainableObjPtr(const Value *Op) {
return true;
}
-bool IsPotentialRetainableObjPtr(const Value *Op, AAResults &AA);
+bool IsPotentialRetainableObjPtr(const Value *Op, AAResults &AA);
/// Helper for GetARCInstKind. Determines what kind of construct CS
/// is.
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/OptimizationRemarkEmitter.h b/contrib/libs/llvm12/include/llvm/Analysis/OptimizationRemarkEmitter.h
index 4301fd4818..3bbbe85e8a 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/OptimizationRemarkEmitter.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/OptimizationRemarkEmitter.h
@@ -95,15 +95,15 @@ public:
/// provide more context so that non-trivial false positives can be quickly
/// detected by the user.
bool allowExtraAnalysis(StringRef PassName) const {
- return OptimizationRemarkEmitter::allowExtraAnalysis(*F, PassName);
+ return OptimizationRemarkEmitter::allowExtraAnalysis(*F, PassName);
+ }
+ static bool allowExtraAnalysis(const Function &F, StringRef PassName) {
+ return allowExtraAnalysis(F.getContext(), PassName);
+ }
+ static bool allowExtraAnalysis(LLVMContext &Ctx, StringRef PassName) {
+ return Ctx.getLLVMRemarkStreamer() ||
+ Ctx.getDiagHandlerPtr()->isAnyRemarkEnabled(PassName);
}
- static bool allowExtraAnalysis(const Function &F, StringRef PassName) {
- return allowExtraAnalysis(F.getContext(), PassName);
- }
- static bool allowExtraAnalysis(LLVMContext &Ctx, StringRef PassName) {
- return Ctx.getLLVMRemarkStreamer() ||
- Ctx.getDiagHandlerPtr()->isAnyRemarkEnabled(PassName);
- }
private:
const Function *F;
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/PhiValues.h b/contrib/libs/llvm12/include/llvm/Analysis/PhiValues.h
index c01f89dab5..15a722d067 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/PhiValues.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/PhiValues.h
@@ -28,7 +28,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/ValueHandle.h"
@@ -47,7 +47,7 @@ class Function;
/// it is queried.
class PhiValues {
public:
- using ValueSet = SmallSetVector<Value *, 4>;
+ using ValueSet = SmallSetVector<Value *, 4>;
/// Construct an empty PhiValues.
PhiValues(const Function &F) : F(F) {}
@@ -77,7 +77,7 @@ public:
FunctionAnalysisManager::Invalidator &);
private:
- using ConstValueSet = SmallSetVector<const Value *, 4>;
+ using ConstValueSet = SmallSetVector<const Value *, 4>;
/// The next depth number to be used by processPhi.
unsigned int NextDepthNumber = 1;
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/ProfileSummaryInfo.h b/contrib/libs/llvm12/include/llvm/Analysis/ProfileSummaryInfo.h
index 9f31d7041a..c862044992 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/ProfileSummaryInfo.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/ProfileSummaryInfo.h
@@ -45,7 +45,7 @@ class Function;
// units. This would require making this depend on BFI.
class ProfileSummaryInfo {
private:
- const Module &M;
+ const Module &M;
std::unique_ptr<ProfileSummary> Summary;
void computeThresholds();
// Count thresholds to answer isHotCount and isColdCount queries.
@@ -65,8 +65,8 @@ private:
mutable DenseMap<int, uint64_t> ThresholdCache;
public:
- ProfileSummaryInfo(const Module &M) : M(M) { refresh(); }
-
+ ProfileSummaryInfo(const Module &M) : M(M) { refresh(); }
+
ProfileSummaryInfo(ProfileSummaryInfo &&Arg) = default;
/// If no summary is present, attempt to refresh.
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/RegionInfoImpl.h b/contrib/libs/llvm12/include/llvm/Analysis/RegionInfoImpl.h
index e1a50f12d7..11c12808ff 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/RegionInfoImpl.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/RegionInfoImpl.h
@@ -592,8 +592,8 @@ bool RegionInfoBase<Tr>::isRegion(BlockT *entry, BlockT *exit) const {
// Exit is the header of a loop that contains the entry. In this case,
// the dominance frontier must only contain the exit.
if (!DT->dominates(entry, exit)) {
- for (BlockT *successor : *entrySuccs) {
- if (successor != exit && successor != entry)
+ for (BlockT *successor : *entrySuccs) {
+ if (successor != exit && successor != entry)
return false;
}
@@ -822,7 +822,7 @@ void RegionInfoBase<Tr>::verifyAnalysis() const {
// Region pass manager support.
template <class Tr>
typename Tr::RegionT *RegionInfoBase<Tr>::getRegionFor(BlockT *BB) const {
- return BBtoRegion.lookup(BB);
+ return BBtoRegion.lookup(BB);
}
template <class Tr>
@@ -897,7 +897,7 @@ typename Tr::RegionT *RegionInfoBase<Tr>::getCommonRegion(RegionT *A,
template <class Tr>
typename Tr::RegionT *
RegionInfoBase<Tr>::getCommonRegion(SmallVectorImpl<RegionT *> &Regions) const {
- RegionT *ret = Regions.pop_back_val();
+ RegionT *ret = Regions.pop_back_val();
for (RegionT *R : Regions)
ret = getCommonRegion(ret, R);
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/ReplayInlineAdvisor.h b/contrib/libs/llvm12/include/llvm/Analysis/ReplayInlineAdvisor.h
index 40d6ff8d78..d2e2d7d785 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/ReplayInlineAdvisor.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/ReplayInlineAdvisor.h
@@ -1,52 +1,52 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- ReplayInlineAdvisor.h - Replay Inline Advisor interface -*- C++ --*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-#ifndef LLVM_ANALYSIS_REPLAYINLINEADVISOR_H
-#define LLVM_ANALYSIS_REPLAYINLINEADVISOR_H
-
-#include "llvm/ADT/StringSet.h"
-#include "llvm/Analysis/InlineAdvisor.h"
-#include "llvm/IR/LLVMContext.h"
-
-namespace llvm {
-class BasicBlock;
-class CallBase;
-class Function;
-class Module;
-class OptimizationRemarkEmitter;
-
-/// Replay inline advisor that uses optimization remarks from inlining of
-/// previous build to guide current inlining. This is useful for inliner tuning.
-class ReplayInlineAdvisor : public InlineAdvisor {
-public:
- ReplayInlineAdvisor(Module &M, FunctionAnalysisManager &FAM,
- LLVMContext &Context,
- std::unique_ptr<InlineAdvisor> OriginalAdvisor,
- StringRef RemarksFile, bool EmitRemarks);
- std::unique_ptr<InlineAdvice> getAdviceImpl(CallBase &CB) override;
- bool areReplayRemarksLoaded() const { return HasReplayRemarks; }
-
-private:
- StringSet<> InlineSitesFromRemarks;
- std::unique_ptr<InlineAdvisor> OriginalAdvisor;
- bool HasReplayRemarks = false;
- bool EmitRemarks = false;
-};
-} // namespace llvm
-#endif // LLVM_ANALYSIS_REPLAYINLINEADVISOR_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- ReplayInlineAdvisor.h - Replay Inline Advisor interface -*- C++ --*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+#ifndef LLVM_ANALYSIS_REPLAYINLINEADVISOR_H
+#define LLVM_ANALYSIS_REPLAYINLINEADVISOR_H
+
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Analysis/InlineAdvisor.h"
+#include "llvm/IR/LLVMContext.h"
+
+namespace llvm {
+class BasicBlock;
+class CallBase;
+class Function;
+class Module;
+class OptimizationRemarkEmitter;
+
+/// Replay inline advisor that uses optimization remarks from inlining of
+/// previous build to guide current inlining. This is useful for inliner tuning.
+class ReplayInlineAdvisor : public InlineAdvisor {
+public:
+ ReplayInlineAdvisor(Module &M, FunctionAnalysisManager &FAM,
+ LLVMContext &Context,
+ std::unique_ptr<InlineAdvisor> OriginalAdvisor,
+ StringRef RemarksFile, bool EmitRemarks);
+ std::unique_ptr<InlineAdvice> getAdviceImpl(CallBase &CB) override;
+ bool areReplayRemarksLoaded() const { return HasReplayRemarks; }
+
+private:
+ StringSet<> InlineSitesFromRemarks;
+ std::unique_ptr<InlineAdvisor> OriginalAdvisor;
+ bool HasReplayRemarks = false;
+ bool EmitRemarks = false;
+};
+} // namespace llvm
+#endif // LLVM_ANALYSIS_REPLAYINLINEADVISOR_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/ScalarEvolution.h b/contrib/libs/llvm12/include/llvm/Analysis/ScalarEvolution.h
index 9788c9a473..12110dd0c6 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/ScalarEvolution.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/ScalarEvolution.h
@@ -77,7 +77,7 @@ class StructType;
class TargetLibraryInfo;
class Type;
class Value;
-enum SCEVTypes : unsigned short;
+enum SCEVTypes : unsigned short;
/// This class represents an analyzed expression in the program. These are
/// opaque objects that the client is not allowed to do much with directly.
@@ -90,7 +90,7 @@ class SCEV : public FoldingSetNode {
FoldingSetNodeIDRef FastID;
// The SCEV baseclass this node corresponds to
- const SCEVTypes SCEVType;
+ const SCEVTypes SCEVType;
protected:
// Estimated complexity of this node's expression tree size.
@@ -127,13 +127,13 @@ public:
NoWrapMask = (1 << 3) - 1
};
- explicit SCEV(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy,
+ explicit SCEV(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy,
unsigned short ExpressionSize)
: FastID(ID), SCEVType(SCEVTy), ExpressionSize(ExpressionSize) {}
SCEV(const SCEV &) = delete;
SCEV &operator=(const SCEV &) = delete;
- SCEVTypes getSCEVType() const { return SCEVType; }
+ SCEVTypes getSCEVType() const { return SCEVType; }
/// Return the LLVM type of this SCEV expression.
Type *getType() const;
@@ -519,7 +519,7 @@ public:
const SCEV *getConstant(ConstantInt *V);
const SCEV *getConstant(const APInt &Val);
const SCEV *getConstant(Type *Ty, uint64_t V, bool isSigned = false);
- const SCEV *getPtrToIntExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0);
+ const SCEV *getPtrToIntExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0);
const SCEV *getTruncateExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0);
const SCEV *getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0);
const SCEV *getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0);
@@ -581,9 +581,9 @@ public:
/// \p IndexExprs The expressions for the indices.
const SCEV *getGEPExpr(GEPOperator *GEP,
const SmallVectorImpl<const SCEV *> &IndexExprs);
- const SCEV *getAbsExpr(const SCEV *Op, bool IsNSW);
- const SCEV *getSignumExpr(const SCEV *Op);
- const SCEV *getMinMaxExpr(SCEVTypes Kind,
+ const SCEV *getAbsExpr(const SCEV *Op, bool IsNSW);
+ const SCEV *getSignumExpr(const SCEV *Op);
+ const SCEV *getMinMaxExpr(SCEVTypes Kind,
SmallVectorImpl<const SCEV *> &Operands);
const SCEV *getSMaxExpr(const SCEV *LHS, const SCEV *RHS);
const SCEV *getSMaxExpr(SmallVectorImpl<const SCEV *> &Operands);
@@ -602,22 +602,22 @@ public:
/// Return a SCEV for the constant 1 of a specific type.
const SCEV *getOne(Type *Ty) { return getConstant(Ty, 1); }
- /// Return a SCEV for the constant -1 of a specific type.
- const SCEV *getMinusOne(Type *Ty) {
- return getConstant(Ty, -1, /*isSigned=*/true);
- }
-
- /// Return an expression for sizeof ScalableTy that is type IntTy, where
- /// ScalableTy is a scalable vector type.
- const SCEV *getSizeOfScalableVectorExpr(Type *IntTy,
- ScalableVectorType *ScalableTy);
-
- /// Return an expression for the alloc size of AllocTy that is type IntTy
+ /// Return a SCEV for the constant -1 of a specific type.
+ const SCEV *getMinusOne(Type *Ty) {
+ return getConstant(Ty, -1, /*isSigned=*/true);
+ }
+
+ /// Return an expression for sizeof ScalableTy that is type IntTy, where
+ /// ScalableTy is a scalable vector type.
+ const SCEV *getSizeOfScalableVectorExpr(Type *IntTy,
+ ScalableVectorType *ScalableTy);
+
+ /// Return an expression for the alloc size of AllocTy that is type IntTy
const SCEV *getSizeOfExpr(Type *IntTy, Type *AllocTy);
- /// Return an expression for the store size of StoreTy that is type IntTy
- const SCEV *getStoreSizeOfExpr(Type *IntTy, Type *StoreTy);
-
+ /// Return an expression for the store size of StoreTy that is type IntTy
+ const SCEV *getStoreSizeOfExpr(Type *IntTy, Type *StoreTy);
+
/// Return an expression for offsetof on the given field with type IntTy
const SCEV *getOffsetOfExpr(Type *IntTy, StructType *STy, unsigned FieldNo);
@@ -701,12 +701,12 @@ public:
bool isLoopEntryGuardedByCond(const Loop *L, ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS);
- /// Test whether entry to the basic block is protected by a conditional
- /// between LHS and RHS.
- bool isBasicBlockEntryGuardedByCond(const BasicBlock *BB,
- ICmpInst::Predicate Pred, const SCEV *LHS,
- const SCEV *RHS);
-
+ /// Test whether entry to the basic block is protected by a conditional
+ /// between LHS and RHS.
+ bool isBasicBlockEntryGuardedByCond(const BasicBlock *BB,
+ ICmpInst::Predicate Pred, const SCEV *LHS,
+ const SCEV *RHS);
+
/// Test whether the backedge of the loop is protected by a conditional
/// between LHS and RHS. This is used to eliminate casts.
bool isLoopBackedgeGuardedByCond(const Loop *L, ICmpInst::Predicate Pred,
@@ -726,8 +726,8 @@ public:
/// before taking the branch. For loops with multiple exits, it may not be
/// the number times that the loop header executes if the loop exits
/// prematurely via another branch.
- unsigned getSmallConstantTripCount(const Loop *L,
- const BasicBlock *ExitingBlock);
+ unsigned getSmallConstantTripCount(const Loop *L,
+ const BasicBlock *ExitingBlock);
/// Returns the upper bound of the loop trip count as a normal unsigned
/// value.
@@ -749,7 +749,7 @@ public:
/// for getSmallConstantTripCount, this assumes that control exits the loop
/// via ExitingBlock.
unsigned getSmallConstantTripMultiple(const Loop *L,
- const BasicBlock *ExitingBlock);
+ const BasicBlock *ExitingBlock);
/// The terms "backedge taken count" and "exit count" are used
/// interchangeably to refer to the number of times the backedge of a loop
@@ -760,8 +760,8 @@ public:
Exact,
/// A constant which provides an upper bound on the exact trip count.
ConstantMaximum,
- /// An expression which provides an upper bound on the exact trip count.
- SymbolicMaximum,
+ /// An expression which provides an upper bound on the exact trip count.
+ SymbolicMaximum,
};
/// Return the number of times the backedge executes before the given exit
@@ -769,8 +769,8 @@ public:
/// For a single exit loop, this value is equivelent to the result of
/// getBackedgeTakenCount. The loop is guaranteed to exit (via *some* exit)
/// before the backedge is executed (ExitCount + 1) times. Note that there
- /// is no guarantee about *which* exit is taken on the exiting iteration.
- const SCEV *getExitCount(const Loop *L, const BasicBlock *ExitingBlock,
+ /// is no guarantee about *which* exit is taken on the exiting iteration.
+ const SCEV *getExitCount(const Loop *L, const BasicBlock *ExitingBlock,
ExitCountKind Kind = Exact);
/// If the specified loop has a predictable backedge-taken count, return it,
@@ -798,16 +798,16 @@ public:
/// SCEVCouldNotCompute object.
const SCEV *getConstantMaxBackedgeTakenCount(const Loop *L) {
return getBackedgeTakenCount(L, ConstantMaximum);
- }
-
- /// When successful, this returns a SCEV that is greater than or equal
- /// to (i.e. a "conservative over-approximation") of the value returend by
- /// getBackedgeTakenCount. If such a value cannot be computed, it returns the
- /// SCEVCouldNotCompute object.
- const SCEV *getSymbolicMaxBackedgeTakenCount(const Loop *L) {
- return getBackedgeTakenCount(L, SymbolicMaximum);
- }
-
+ }
+
+ /// When successful, this returns a SCEV that is greater than or equal
+ /// to (i.e. a "conservative over-approximation") of the value returend by
+ /// getBackedgeTakenCount. If such a value cannot be computed, it returns the
+ /// SCEVCouldNotCompute object.
+ const SCEV *getSymbolicMaxBackedgeTakenCount(const Loop *L) {
+ return getBackedgeTakenCount(L, SymbolicMaximum);
+ }
+
/// Return true if the backedge taken count is either the value returned by
/// getConstantMaxBackedgeTakenCount or zero.
bool isBackedgeTakenCountMaxOrZero(const Loop *L);
@@ -945,11 +945,11 @@ public:
bool isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *LHS,
const SCEV *RHS);
- /// Test if the given expression is known to satisfy the condition described
- /// by Pred, LHS, and RHS in the given Context.
- bool isKnownPredicateAt(ICmpInst::Predicate Pred, const SCEV *LHS,
- const SCEV *RHS, const Instruction *Context);
-
+ /// Test if the given expression is known to satisfy the condition described
+ /// by Pred, LHS, and RHS in the given Context.
+ bool isKnownPredicateAt(ICmpInst::Predicate Pred, const SCEV *LHS,
+ const SCEV *RHS, const Instruction *Context);
+
/// Test if the condition described by Pred, LHS, RHS is known to be true on
/// every iteration of the loop of the recurrency LHS.
bool isKnownOnEveryIteration(ICmpInst::Predicate Pred,
@@ -960,47 +960,47 @@ public:
/// around. A predicate is said to be monotonically decreasing if may go
/// from being true to being false as the loop iterates, but never the other
/// way around.
- enum MonotonicPredicateType {
- MonotonicallyIncreasing,
- MonotonicallyDecreasing
- };
-
- /// If, for all loop invariant X, the predicate "LHS `Pred` X" is
- /// monotonically increasing or decreasing, returns
- /// Some(MonotonicallyIncreasing) and Some(MonotonicallyDecreasing)
- /// respectively. If we could not prove either of these facts, returns None.
- Optional<MonotonicPredicateType>
- getMonotonicPredicateType(const SCEVAddRecExpr *LHS,
- ICmpInst::Predicate Pred);
-
- struct LoopInvariantPredicate {
- ICmpInst::Predicate Pred;
- const SCEV *LHS;
- const SCEV *RHS;
-
- LoopInvariantPredicate(ICmpInst::Predicate Pred, const SCEV *LHS,
- const SCEV *RHS)
- : Pred(Pred), LHS(LHS), RHS(RHS) {}
- };
- /// If the result of the predicate LHS `Pred` RHS is loop invariant with
- /// respect to L, return a LoopInvariantPredicate with LHS and RHS being
- /// invariants, available at L's entry. Otherwise, return None.
- Optional<LoopInvariantPredicate>
- getLoopInvariantPredicate(ICmpInst::Predicate Pred, const SCEV *LHS,
- const SCEV *RHS, const Loop *L);
-
- /// If the result of the predicate LHS `Pred` RHS is loop invariant with
- /// respect to L at given Context during at least first MaxIter iterations,
- /// return a LoopInvariantPredicate with LHS and RHS being invariants,
- /// available at L's entry. Otherwise, return None. The predicate should be
- /// the loop's exit condition.
- Optional<LoopInvariantPredicate>
- getLoopInvariantExitCondDuringFirstIterations(ICmpInst::Predicate Pred,
- const SCEV *LHS,
- const SCEV *RHS, const Loop *L,
- const Instruction *Context,
- const SCEV *MaxIter);
-
+ enum MonotonicPredicateType {
+ MonotonicallyIncreasing,
+ MonotonicallyDecreasing
+ };
+
+ /// If, for all loop invariant X, the predicate "LHS `Pred` X" is
+ /// monotonically increasing or decreasing, returns
+ /// Some(MonotonicallyIncreasing) and Some(MonotonicallyDecreasing)
+ /// respectively. If we could not prove either of these facts, returns None.
+ Optional<MonotonicPredicateType>
+ getMonotonicPredicateType(const SCEVAddRecExpr *LHS,
+ ICmpInst::Predicate Pred);
+
+ struct LoopInvariantPredicate {
+ ICmpInst::Predicate Pred;
+ const SCEV *LHS;
+ const SCEV *RHS;
+
+ LoopInvariantPredicate(ICmpInst::Predicate Pred, const SCEV *LHS,
+ const SCEV *RHS)
+ : Pred(Pred), LHS(LHS), RHS(RHS) {}
+ };
+ /// If the result of the predicate LHS `Pred` RHS is loop invariant with
+ /// respect to L, return a LoopInvariantPredicate with LHS and RHS being
+ /// invariants, available at L's entry. Otherwise, return None.
+ Optional<LoopInvariantPredicate>
+ getLoopInvariantPredicate(ICmpInst::Predicate Pred, const SCEV *LHS,
+ const SCEV *RHS, const Loop *L);
+
+ /// If the result of the predicate LHS `Pred` RHS is loop invariant with
+ /// respect to L at given Context during at least first MaxIter iterations,
+ /// return a LoopInvariantPredicate with LHS and RHS being invariants,
+ /// available at L's entry. Otherwise, return None. The predicate should be
+ /// the loop's exit condition.
+ Optional<LoopInvariantPredicate>
+ getLoopInvariantExitCondDuringFirstIterations(ICmpInst::Predicate Pred,
+ const SCEV *LHS,
+ const SCEV *RHS, const Loop *L,
+ const Instruction *Context,
+ const SCEV *MaxIter);
+
/// Simplify LHS and RHS in a comparison with predicate Pred. Return true
/// iff any changes were made. If the operands are provably equal or
/// unequal, LHS and RHS are set to the same value and Pred is set to either
@@ -1170,20 +1170,20 @@ public:
const SCEV *S, const Loop *L,
SmallPtrSetImpl<const SCEVPredicate *> &Preds);
- /// Compute \p LHS - \p RHS and returns the result as an APInt if it is a
- /// constant, and None if it isn't.
- ///
- /// This is intended to be a cheaper version of getMinusSCEV. We can be
- /// frugal here since we just bail out of actually constructing and
- /// canonicalizing an expression in the cases where the result isn't going
- /// to be a constant.
- Optional<APInt> computeConstantDifference(const SCEV *LHS, const SCEV *RHS);
-
- /// Update no-wrap flags of an AddRec. This may drop the cached info about
- /// this AddRec (such as range info) in case if new flags may potentially
- /// sharpen it.
- void setNoWrapFlags(SCEVAddRecExpr *AddRec, SCEV::NoWrapFlags Flags);
-
+ /// Compute \p LHS - \p RHS and returns the result as an APInt if it is a
+ /// constant, and None if it isn't.
+ ///
+ /// This is intended to be a cheaper version of getMinusSCEV. We can be
+ /// frugal here since we just bail out of actually constructing and
+ /// canonicalizing an expression in the cases where the result isn't going
+ /// to be a constant.
+ Optional<APInt> computeConstantDifference(const SCEV *LHS, const SCEV *RHS);
+
+ /// Update no-wrap flags of an AddRec. This may drop the cached info about
+ /// this AddRec (such as range info) in case if new flags may potentially
+ /// sharpen it.
+ void setNoWrapFlags(SCEVAddRecExpr *AddRec, SCEV::NoWrapFlags Flags);
+
private:
/// A CallbackVH to arrange for ScalarEvolution to be notified whenever a
/// Value is deleted.
@@ -1264,7 +1264,7 @@ private:
ValueExprMapType ValueExprMap;
/// Mark predicate values currently being processed by isImpliedCond.
- SmallPtrSet<const Value *, 6> PendingLoopPredicates;
+ SmallPtrSet<const Value *, 6> PendingLoopPredicates;
/// Mark SCEVUnknown Phis currently being processed by getRangeRef.
SmallPtrSet<const PHINode *, 6> PendingPhiRanges;
@@ -1367,41 +1367,41 @@ private:
/// never have more than one computable exit.
SmallVector<ExitNotTakenInfo, 1> ExitNotTaken;
- /// Expression indicating the least constant maximum backedge-taken count of
- /// the loop that is known, or a SCEVCouldNotCompute. This expression is
- /// only valid if the redicates associated with all loop exits are true.
- const SCEV *ConstantMax;
-
- /// Indicating if \c ExitNotTaken has an element for every exiting block in
- /// the loop.
- bool IsComplete;
-
- /// Expression indicating the least maximum backedge-taken count of the loop
- /// that is known, or a SCEVCouldNotCompute. Lazily computed on first query.
- const SCEV *SymbolicMax = nullptr;
-
+ /// Expression indicating the least constant maximum backedge-taken count of
+ /// the loop that is known, or a SCEVCouldNotCompute. This expression is
+ /// only valid if the redicates associated with all loop exits are true.
+ const SCEV *ConstantMax;
+
+ /// Indicating if \c ExitNotTaken has an element for every exiting block in
+ /// the loop.
+ bool IsComplete;
+
+ /// Expression indicating the least maximum backedge-taken count of the loop
+ /// that is known, or a SCEVCouldNotCompute. Lazily computed on first query.
+ const SCEV *SymbolicMax = nullptr;
+
/// True iff the backedge is taken either exactly Max or zero times.
bool MaxOrZero = false;
- bool isComplete() const { return IsComplete; }
- const SCEV *getConstantMax() const { return ConstantMax; }
+ bool isComplete() const { return IsComplete; }
+ const SCEV *getConstantMax() const { return ConstantMax; }
public:
- BackedgeTakenInfo() : ConstantMax(nullptr), IsComplete(false) {}
+ BackedgeTakenInfo() : ConstantMax(nullptr), IsComplete(false) {}
BackedgeTakenInfo(BackedgeTakenInfo &&) = default;
BackedgeTakenInfo &operator=(BackedgeTakenInfo &&) = default;
using EdgeExitInfo = std::pair<BasicBlock *, ExitLimit>;
/// Initialize BackedgeTakenInfo from a list of exact exit counts.
- BackedgeTakenInfo(ArrayRef<EdgeExitInfo> ExitCounts, bool IsComplete,
- const SCEV *ConstantMax, bool MaxOrZero);
+ BackedgeTakenInfo(ArrayRef<EdgeExitInfo> ExitCounts, bool IsComplete,
+ const SCEV *ConstantMax, bool MaxOrZero);
/// Test whether this BackedgeTakenInfo contains any computed information,
/// or whether it's all SCEVCouldNotCompute values.
bool hasAnyInfo() const {
- return !ExitNotTaken.empty() ||
- !isa<SCEVCouldNotCompute>(getConstantMax());
+ return !ExitNotTaken.empty() ||
+ !isa<SCEVCouldNotCompute>(getConstantMax());
}
/// Test whether this BackedgeTakenInfo contains complete information.
@@ -1432,22 +1432,22 @@ private:
/// edge, or SCEVCouldNotCompute. The loop is guaranteed not to exit via
/// this block before this number of iterations, but may exit via another
/// block.
- const SCEV *getExact(const BasicBlock *ExitingBlock,
- ScalarEvolution *SE) const;
+ const SCEV *getExact(const BasicBlock *ExitingBlock,
+ ScalarEvolution *SE) const;
- /// Get the constant max backedge taken count for the loop.
- const SCEV *getConstantMax(ScalarEvolution *SE) const;
+ /// Get the constant max backedge taken count for the loop.
+ const SCEV *getConstantMax(ScalarEvolution *SE) const;
- /// Get the constant max backedge taken count for the particular loop exit.
- const SCEV *getConstantMax(const BasicBlock *ExitingBlock,
- ScalarEvolution *SE) const;
+ /// Get the constant max backedge taken count for the particular loop exit.
+ const SCEV *getConstantMax(const BasicBlock *ExitingBlock,
+ ScalarEvolution *SE) const;
+
+ /// Get the symbolic max backedge taken count for the loop.
+ const SCEV *getSymbolicMax(const Loop *L, ScalarEvolution *SE);
- /// Get the symbolic max backedge taken count for the loop.
- const SCEV *getSymbolicMax(const Loop *L, ScalarEvolution *SE);
-
/// Return true if the number of times this backedge is taken is either the
- /// value returned by getConstantMax or zero.
- bool isConstantMaxOrZero(ScalarEvolution *SE) const;
+ /// value returned by getConstantMax or zero.
+ bool isConstantMaxOrZero(ScalarEvolution *SE) const;
/// Return true if any backedge taken count expressions refer to the given
/// subexpression.
@@ -1552,13 +1552,13 @@ private:
ConstantRange getRangeForAffineAR(const SCEV *Start, const SCEV *Stop,
const SCEV *MaxBECount, unsigned BitWidth);
- /// Determines the range for the affine non-self-wrapping SCEVAddRecExpr {\p
- /// Start,+,\p Stop}<nw>.
- ConstantRange getRangeForAffineNoSelfWrappingAR(const SCEVAddRecExpr *AddRec,
- const SCEV *MaxBECount,
- unsigned BitWidth,
- RangeSignHint SignHint);
-
+ /// Determines the range for the affine non-self-wrapping SCEVAddRecExpr {\p
+ /// Start,+,\p Stop}<nw>.
+ ConstantRange getRangeForAffineNoSelfWrappingAR(const SCEVAddRecExpr *AddRec,
+ const SCEV *MaxBECount,
+ unsigned BitWidth,
+ RangeSignHint SignHint);
+
/// Try to compute a range for the affine SCEVAddRecExpr {\p Start,+,\p
/// Stop} by "factoring out" a ternary expression from the add recurrence.
/// Helper called by \c getRange.
@@ -1604,7 +1604,7 @@ private:
/// Return the BackedgeTakenInfo for the given loop, lazily computing new
/// values if the loop hasn't been analyzed yet. The returned result is
/// guaranteed not to be predicated.
- BackedgeTakenInfo &getBackedgeTakenInfo(const Loop *L);
+ BackedgeTakenInfo &getBackedgeTakenInfo(const Loop *L);
/// Similar to getBackedgeTakenInfo, but will add predicates as required
/// with the purpose of returning complete information.
@@ -1637,11 +1637,11 @@ private:
bool ExitIfTrue, bool ControlsExit,
bool AllowPredicates = false);
- /// Return a symbolic upper bound for the backedge taken count of the loop.
- /// This is more general than getConstantMaxBackedgeTakenCount as it returns
- /// an arbitrary expression as opposed to only constants.
- const SCEV *computeSymbolicMaxBackedgeTakenCount(const Loop *L);
-
+ /// Return a symbolic upper bound for the backedge taken count of the loop.
+ /// This is more general than getConstantMaxBackedgeTakenCount as it returns
+ /// an arbitrary expression as opposed to only constants.
+ const SCEV *computeSymbolicMaxBackedgeTakenCount(const Loop *L);
+
// Helper functions for computeExitLimitFromCond to avoid exponential time
// complexity.
@@ -1679,10 +1679,10 @@ private:
Value *ExitCond, bool ExitIfTrue,
bool ControlsExit,
bool AllowPredicates);
- Optional<ScalarEvolution::ExitLimit>
- computeExitLimitFromCondFromBinOp(ExitLimitCacheTy &Cache, const Loop *L,
- Value *ExitCond, bool ExitIfTrue,
- bool ControlsExit, bool AllowPredicates);
+ Optional<ScalarEvolution::ExitLimit>
+ computeExitLimitFromCondFromBinOp(ExitLimitCacheTy &Cache, const Loop *L,
+ Value *ExitCond, bool ExitIfTrue,
+ bool ControlsExit, bool AllowPredicates);
/// Compute the number of times the backedge of the specified loop will
/// execute if its exit condition were a conditional branch of the ICmpInst
@@ -1761,44 +1761,44 @@ private:
/// Return a predecessor of BB (which may not be an immediate predecessor)
/// which has exactly one successor from which BB is reachable, or null if
/// no such block is found.
- std::pair<const BasicBlock *, const BasicBlock *>
- getPredecessorWithUniqueSuccessorForBB(const BasicBlock *BB) const;
+ std::pair<const BasicBlock *, const BasicBlock *>
+ getPredecessorWithUniqueSuccessorForBB(const BasicBlock *BB) const;
/// Test whether the condition described by Pred, LHS, and RHS is true
- /// whenever the given FoundCondValue value evaluates to true in given
- /// Context. If Context is nullptr, then the found predicate is true
- /// everywhere. LHS and FoundLHS may have different type width.
+ /// whenever the given FoundCondValue value evaluates to true in given
+ /// Context. If Context is nullptr, then the found predicate is true
+ /// everywhere. LHS and FoundLHS may have different type width.
bool isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS,
- const Value *FoundCondValue, bool Inverse,
- const Instruction *Context = nullptr);
+ const Value *FoundCondValue, bool Inverse,
+ const Instruction *Context = nullptr);
+
+ /// Test whether the condition described by Pred, LHS, and RHS is true
+ /// whenever the given FoundCondValue value evaluates to true in given
+ /// Context. If Context is nullptr, then the found predicate is true
+ /// everywhere. LHS and FoundLHS must have same type width.
+ bool isImpliedCondBalancedTypes(ICmpInst::Predicate Pred, const SCEV *LHS,
+ const SCEV *RHS,
+ ICmpInst::Predicate FoundPred,
+ const SCEV *FoundLHS, const SCEV *FoundRHS,
+ const Instruction *Context);
/// Test whether the condition described by Pred, LHS, and RHS is true
- /// whenever the given FoundCondValue value evaluates to true in given
- /// Context. If Context is nullptr, then the found predicate is true
- /// everywhere. LHS and FoundLHS must have same type width.
- bool isImpliedCondBalancedTypes(ICmpInst::Predicate Pred, const SCEV *LHS,
- const SCEV *RHS,
- ICmpInst::Predicate FoundPred,
- const SCEV *FoundLHS, const SCEV *FoundRHS,
- const Instruction *Context);
-
- /// Test whether the condition described by Pred, LHS, and RHS is true
/// whenever the condition described by FoundPred, FoundLHS, FoundRHS is
- /// true in given Context. If Context is nullptr, then the found predicate is
- /// true everywhere.
+ /// true in given Context. If Context is nullptr, then the found predicate is
+ /// true everywhere.
bool isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS,
ICmpInst::Predicate FoundPred, const SCEV *FoundLHS,
- const SCEV *FoundRHS,
- const Instruction *Context = nullptr);
+ const SCEV *FoundRHS,
+ const Instruction *Context = nullptr);
/// Test whether the condition described by Pred, LHS, and RHS is true
/// whenever the condition described by Pred, FoundLHS, and FoundRHS is
- /// true in given Context. If Context is nullptr, then the found predicate is
- /// true everywhere.
+ /// true in given Context. If Context is nullptr, then the found predicate is
+ /// true everywhere.
bool isImpliedCondOperands(ICmpInst::Predicate Pred, const SCEV *LHS,
const SCEV *RHS, const SCEV *FoundLHS,
- const SCEV *FoundRHS,
- const Instruction *Context = nullptr);
+ const SCEV *FoundRHS,
+ const Instruction *Context = nullptr);
/// Test whether the condition described by Pred, LHS, and RHS is true
/// whenever the condition described by Pred, FoundLHS, and FoundRHS is
@@ -1831,7 +1831,7 @@ private:
/// Return true if the condition denoted by \p LHS \p Pred \p RHS is implied
/// by a call to @llvm.experimental.guard in \p BB.
- bool isImpliedViaGuard(const BasicBlock *BB, ICmpInst::Predicate Pred,
+ bool isImpliedViaGuard(const BasicBlock *BB, ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS);
/// Test whether the condition described by Pred, LHS, and RHS is true
@@ -1849,18 +1849,18 @@ private:
/// whenever the condition described by Pred, FoundLHS, and FoundRHS is
/// true.
///
- /// This routine tries to weaken the known condition basing on fact that
- /// FoundLHS is an AddRec.
- bool isImpliedCondOperandsViaAddRecStart(ICmpInst::Predicate Pred,
- const SCEV *LHS, const SCEV *RHS,
- const SCEV *FoundLHS,
- const SCEV *FoundRHS,
- const Instruction *Context);
-
- /// 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 weaken the known condition basing on fact that
+ /// FoundLHS is an AddRec.
+ bool isImpliedCondOperandsViaAddRecStart(ICmpInst::Predicate Pred,
+ const SCEV *LHS, const SCEV *RHS,
+ const SCEV *FoundLHS,
+ const SCEV *FoundRHS,
+ const Instruction *Context);
+
+ /// 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.
@@ -1919,18 +1919,18 @@ private:
/// Try to prove NSW or NUW on \p AR relying on ConstantRange manipulation.
SCEV::NoWrapFlags proveNoWrapViaConstantRanges(const SCEVAddRecExpr *AR);
- /// Try to prove NSW on \p AR by proving facts about conditions known on
- /// entry and backedge.
- SCEV::NoWrapFlags proveNoSignedWrapViaInduction(const SCEVAddRecExpr *AR);
-
- /// Try to prove NUW on \p AR by proving facts about conditions known on
- /// entry and backedge.
- SCEV::NoWrapFlags proveNoUnsignedWrapViaInduction(const SCEVAddRecExpr *AR);
-
- Optional<MonotonicPredicateType>
- getMonotonicPredicateTypeImpl(const SCEVAddRecExpr *LHS,
- ICmpInst::Predicate Pred);
-
+ /// Try to prove NSW on \p AR by proving facts about conditions known on
+ /// entry and backedge.
+ SCEV::NoWrapFlags proveNoSignedWrapViaInduction(const SCEVAddRecExpr *AR);
+
+ /// Try to prove NUW on \p AR by proving facts about conditions known on
+ /// entry and backedge.
+ SCEV::NoWrapFlags proveNoUnsignedWrapViaInduction(const SCEVAddRecExpr *AR);
+
+ Optional<MonotonicPredicateType>
+ getMonotonicPredicateTypeImpl(const SCEVAddRecExpr *LHS,
+ ICmpInst::Predicate Pred);
+
/// Return SCEV no-wrap flags that can be proven based on reasoning about
/// how poison produced from no-wrap flags on this value (e.g. a nuw add)
/// would trigger undefined behavior on overflow.
@@ -2028,9 +2028,9 @@ private:
/// Assign A and B to LHS and RHS, respectively.
bool matchURem(const SCEV *Expr, const SCEV *&LHS, const SCEV *&RHS);
- /// Try to apply information from loop guards for \p L to \p Expr.
- const SCEV *applyLoopGuards(const SCEV *Expr, const Loop *L);
-
+ /// Try to apply information from loop guards for \p L to \p Expr.
+ const SCEV *applyLoopGuards(const SCEV *Expr, const Loop *L);
+
/// Look for a SCEV expression with type `SCEVType` and operands `Ops` in
/// `UniqueSCEVs`.
///
@@ -2039,7 +2039,7 @@ private:
/// constructed to look up the SCEV and the third component is the insertion
/// point.
std::tuple<SCEV *, FoldingSetNodeID, void *>
- findExistingSCEVInCache(SCEVTypes SCEVType, ArrayRef<const SCEV *> Ops);
+ findExistingSCEVInCache(SCEVTypes SCEVType, ArrayRef<const SCEV *> Ops);
FoldingSet<SCEV> UniqueSCEVs;
FoldingSet<SCEVPredicate> UniquePreds;
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/ScalarEvolutionDivision.h b/contrib/libs/llvm12/include/llvm/Analysis/ScalarEvolutionDivision.h
index 370172fd74..ddcd264525 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/ScalarEvolutionDivision.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/ScalarEvolutionDivision.h
@@ -40,7 +40,7 @@ public:
// Except in the trivial case described above, we do not know how to divide
// Expr by Denominator for the following functions with empty implementation.
- void visitPtrToIntExpr(const SCEVPtrToIntExpr *Numerator) {}
+ void visitPtrToIntExpr(const SCEVPtrToIntExpr *Numerator) {}
void visitTruncateExpr(const SCEVTruncateExpr *Numerator) {}
void visitZeroExtendExpr(const SCEVZeroExtendExpr *Numerator) {}
void visitSignExtendExpr(const SCEVSignExtendExpr *Numerator) {}
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/ScalarEvolutionExpressions.h b/contrib/libs/llvm12/include/llvm/Analysis/ScalarEvolutionExpressions.h
index d0d9f176df..1841c92d43 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/ScalarEvolutionExpressions.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -42,12 +42,12 @@ class ConstantRange;
class Loop;
class Type;
- enum SCEVTypes : unsigned short {
+ enum SCEVTypes : unsigned short {
// These should be ordered in terms of increasing complexity to make the
// folders simpler.
scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr,
scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr, scUMinExpr, scSMinExpr,
- scPtrToInt, scUnknown, scCouldNotCompute
+ scPtrToInt, scUnknown, scCouldNotCompute
};
/// This class represents a constant integer value.
@@ -81,58 +81,58 @@ class Type;
/// This is the base class for unary cast operator classes.
class SCEVCastExpr : public SCEV {
protected:
- std::array<const SCEV *, 1> Operands;
+ std::array<const SCEV *, 1> Operands;
Type *Ty;
- SCEVCastExpr(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy, const SCEV *op,
- Type *ty);
+ SCEVCastExpr(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy, const SCEV *op,
+ Type *ty);
public:
- const SCEV *getOperand() const { return Operands[0]; }
- const SCEV *getOperand(unsigned i) const {
- assert(i == 0 && "Operand index out of range!");
- return Operands[0];
- }
- using op_iterator = std::array<const SCEV *, 1>::const_iterator;
- using op_range = iterator_range<op_iterator>;
-
- op_range operands() const {
- return make_range(Operands.begin(), Operands.end());
- }
- size_t getNumOperands() const { return 1; }
+ const SCEV *getOperand() const { return Operands[0]; }
+ const SCEV *getOperand(unsigned i) const {
+ assert(i == 0 && "Operand index out of range!");
+ return Operands[0];
+ }
+ using op_iterator = std::array<const SCEV *, 1>::const_iterator;
+ using op_range = iterator_range<op_iterator>;
+
+ op_range operands() const {
+ return make_range(Operands.begin(), Operands.end());
+ }
+ size_t getNumOperands() const { return 1; }
Type *getType() const { return Ty; }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const SCEV *S) {
- return S->getSCEVType() == scPtrToInt || S->getSCEVType() == scTruncate ||
- S->getSCEVType() == scZeroExtend ||
- S->getSCEVType() == scSignExtend;
- }
- };
-
- /// This class represents a cast from a pointer to a pointer-sized integer
- /// value.
- class SCEVPtrToIntExpr : public SCEVCastExpr {
- friend class ScalarEvolution;
-
- SCEVPtrToIntExpr(const FoldingSetNodeIDRef ID, const SCEV *Op, Type *ITy);
-
- public:
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const SCEV *S) {
- return S->getSCEVType() == scPtrToInt;
- }
- };
-
- /// This is the base class for unary integral cast operator classes.
- class SCEVIntegralCastExpr : public SCEVCastExpr {
- protected:
- SCEVIntegralCastExpr(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy,
- const SCEV *op, Type *ty);
-
- public:
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const SCEV *S) {
+ return S->getSCEVType() == scPtrToInt || S->getSCEVType() == scTruncate ||
+ S->getSCEVType() == scZeroExtend ||
+ S->getSCEVType() == scSignExtend;
+ }
+ };
+
+ /// This class represents a cast from a pointer to a pointer-sized integer
+ /// value.
+ class SCEVPtrToIntExpr : public SCEVCastExpr {
+ friend class ScalarEvolution;
+
+ SCEVPtrToIntExpr(const FoldingSetNodeIDRef ID, const SCEV *Op, Type *ITy);
+
+ public:
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const SCEV *S) {
+ return S->getSCEVType() == scPtrToInt;
+ }
+ };
+
+ /// This is the base class for unary integral cast operator classes.
+ class SCEVIntegralCastExpr : public SCEVCastExpr {
+ protected:
+ SCEVIntegralCastExpr(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy,
+ const SCEV *op, Type *ty);
+
+ public:
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const SCEV *S) {
return S->getSCEVType() == scTruncate ||
S->getSCEVType() == scZeroExtend ||
S->getSCEVType() == scSignExtend;
@@ -141,7 +141,7 @@ class Type;
/// This class represents a truncation of an integer value to a
/// smaller integer value.
- class SCEVTruncateExpr : public SCEVIntegralCastExpr {
+ class SCEVTruncateExpr : public SCEVIntegralCastExpr {
friend class ScalarEvolution;
SCEVTruncateExpr(const FoldingSetNodeIDRef ID,
@@ -156,7 +156,7 @@ class Type;
/// This class represents a zero extension of a small integer value
/// to a larger integer value.
- class SCEVZeroExtendExpr : public SCEVIntegralCastExpr {
+ class SCEVZeroExtendExpr : public SCEVIntegralCastExpr {
friend class ScalarEvolution;
SCEVZeroExtendExpr(const FoldingSetNodeIDRef ID,
@@ -171,7 +171,7 @@ class Type;
/// This class represents a sign extension of a small integer value
/// to a larger integer value.
- class SCEVSignExtendExpr : public SCEVIntegralCastExpr {
+ class SCEVSignExtendExpr : public SCEVIntegralCastExpr {
friend class ScalarEvolution;
SCEVSignExtendExpr(const FoldingSetNodeIDRef ID,
@@ -310,29 +310,29 @@ class Type;
class SCEVUDivExpr : public SCEV {
friend class ScalarEvolution;
- std::array<const SCEV *, 2> Operands;
+ std::array<const SCEV *, 2> Operands;
SCEVUDivExpr(const FoldingSetNodeIDRef ID, const SCEV *lhs, const SCEV *rhs)
- : SCEV(ID, scUDivExpr, computeExpressionSize({lhs, rhs})) {
- Operands[0] = lhs;
- Operands[1] = rhs;
- }
+ : SCEV(ID, scUDivExpr, computeExpressionSize({lhs, rhs})) {
+ Operands[0] = lhs;
+ Operands[1] = rhs;
+ }
public:
- const SCEV *getLHS() const { return Operands[0]; }
- const SCEV *getRHS() const { return Operands[1]; }
- size_t getNumOperands() const { return 2; }
- const SCEV *getOperand(unsigned i) const {
- assert((i == 0 || i == 1) && "Operand index out of range!");
- return i == 0 ? getLHS() : getRHS();
- }
-
- using op_iterator = std::array<const SCEV *, 2>::const_iterator;
- using op_range = iterator_range<op_iterator>;
- op_range operands() const {
- return make_range(Operands.begin(), Operands.end());
- }
-
+ const SCEV *getLHS() const { return Operands[0]; }
+ const SCEV *getRHS() const { return Operands[1]; }
+ size_t getNumOperands() const { return 2; }
+ const SCEV *getOperand(unsigned i) const {
+ assert((i == 0 || i == 1) && "Operand index out of range!");
+ return i == 0 ? getLHS() : getRHS();
+ }
+
+ using op_iterator = std::array<const SCEV *, 2>::const_iterator;
+ using op_range = iterator_range<op_iterator>;
+ op_range operands() const {
+ return make_range(Operands.begin(), Operands.end());
+ }
+
Type *getType() const {
// In most cases the types of LHS and RHS will be the same, but in some
// crazy cases one or the other may be a pointer. ScalarEvolution doesn't
@@ -448,7 +448,7 @@ class Type;
public:
static bool classof(const SCEV *S) {
- return isMinMaxType(S->getSCEVType());
+ return isMinMaxType(S->getSCEVType());
}
static enum SCEVTypes negate(enum SCEVTypes T) {
@@ -577,8 +577,8 @@ class Type;
switch (S->getSCEVType()) {
case scConstant:
return ((SC*)this)->visitConstant((const SCEVConstant*)S);
- case scPtrToInt:
- return ((SC *)this)->visitPtrToIntExpr((const SCEVPtrToIntExpr *)S);
+ case scPtrToInt:
+ return ((SC *)this)->visitPtrToIntExpr((const SCEVPtrToIntExpr *)S);
case scTruncate:
return ((SC*)this)->visitTruncateExpr((const SCEVTruncateExpr*)S);
case scZeroExtend:
@@ -606,7 +606,7 @@ class Type;
case scCouldNotCompute:
return ((SC*)this)->visitCouldNotCompute((const SCEVCouldNotCompute*)S);
}
- llvm_unreachable("Unknown SCEV kind!");
+ llvm_unreachable("Unknown SCEV kind!");
}
RetVal visitCouldNotCompute(const SCEVCouldNotCompute *S) {
@@ -643,13 +643,13 @@ class Type;
switch (S->getSCEVType()) {
case scConstant:
case scUnknown:
- continue;
- case scPtrToInt:
+ continue;
+ case scPtrToInt:
case scTruncate:
case scZeroExtend:
case scSignExtend:
push(cast<SCEVCastExpr>(S)->getOperand());
- continue;
+ continue;
case scAddExpr:
case scMulExpr:
case scSMaxExpr:
@@ -659,17 +659,17 @@ class Type;
case scAddRecExpr:
for (const auto *Op : cast<SCEVNAryExpr>(S)->operands())
push(Op);
- continue;
+ continue;
case scUDivExpr: {
const SCEVUDivExpr *UDiv = cast<SCEVUDivExpr>(S);
push(UDiv->getLHS());
push(UDiv->getRHS());
- continue;
+ continue;
}
case scCouldNotCompute:
llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
}
- llvm_unreachable("Unknown SCEV kind!");
+ llvm_unreachable("Unknown SCEV kind!");
}
}
};
@@ -737,13 +737,13 @@ class Type;
return Constant;
}
- const SCEV *visitPtrToIntExpr(const SCEVPtrToIntExpr *Expr) {
- const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand());
- return Operand == Expr->getOperand()
- ? Expr
- : SE.getPtrToIntExpr(Operand, Expr->getType());
- }
-
+ const SCEV *visitPtrToIntExpr(const SCEVPtrToIntExpr *Expr) {
+ const SCEV *Operand = ((SC *)this)->visit(Expr->getOperand());
+ return Operand == Expr->getOperand()
+ ? Expr
+ : SE.getPtrToIntExpr(Operand, Expr->getType());
+ }
+
const SCEV *visitTruncateExpr(const SCEVTruncateExpr *Expr) {
const SCEV *Operand = ((SC*)this)->visit(Expr->getOperand());
return Operand == Expr->getOperand()
@@ -854,30 +854,30 @@ class Type;
};
using ValueToValueMap = DenseMap<const Value *, Value *>;
- using ValueToSCEVMapTy = DenseMap<const Value *, const SCEV *>;
+ using ValueToSCEVMapTy = DenseMap<const Value *, const SCEV *>;
/// The SCEVParameterRewriter takes a scalar evolution expression and updates
- /// the SCEVUnknown components following the Map (Value -> SCEV).
+ /// the SCEVUnknown components following the Map (Value -> SCEV).
class SCEVParameterRewriter : public SCEVRewriteVisitor<SCEVParameterRewriter> {
public:
static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE,
- ValueToSCEVMapTy &Map) {
- SCEVParameterRewriter Rewriter(SE, Map);
+ ValueToSCEVMapTy &Map) {
+ SCEVParameterRewriter Rewriter(SE, Map);
return Rewriter.visit(Scev);
}
- SCEVParameterRewriter(ScalarEvolution &SE, ValueToSCEVMapTy &M)
- : SCEVRewriteVisitor(SE), Map(M) {}
+ SCEVParameterRewriter(ScalarEvolution &SE, ValueToSCEVMapTy &M)
+ : SCEVRewriteVisitor(SE), Map(M) {}
const SCEV *visitUnknown(const SCEVUnknown *Expr) {
- auto I = Map.find(Expr->getValue());
- if (I == Map.end())
- return Expr;
- return I->second;
+ auto I = Map.find(Expr->getValue());
+ if (I == Map.end())
+ return Expr;
+ return I->second;
}
private:
- ValueToSCEVMapTy &Map;
+ ValueToSCEVMapTy &Map;
};
using LoopToScevMapT = DenseMap<const Loop *, const SCEV *>;
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/SparsePropagation.h b/contrib/libs/llvm12/include/llvm/Analysis/SparsePropagation.h
index 5996920354..6f35675503 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/SparsePropagation.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/SparsePropagation.h
@@ -492,7 +492,7 @@ void SparseSolver<LatticeKey, LatticeVal, KeyInfo>::Solve() {
// Process the basic block work list.
while (!BBWorkList.empty()) {
- BasicBlock *BB = BBWorkList.pop_back_val();
+ BasicBlock *BB = BBWorkList.pop_back_val();
LLVM_DEBUG(dbgs() << "\nPopped off BBWL: " << *BB);
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/StackLifetime.h b/contrib/libs/llvm12/include/llvm/Analysis/StackLifetime.h
index 4257507b9c..c17d154b19 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/StackLifetime.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/StackLifetime.h
@@ -20,7 +20,7 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/raw_ostream.h"
@@ -129,8 +129,8 @@ private:
DenseMap<const BasicBlock *, SmallVector<std::pair<unsigned, Marker>, 4>>
BBMarkers;
- bool HasUnknownLifetimeStartOrEnd = false;
-
+ bool HasUnknownLifetimeStartOrEnd = false;
+
void dumpAllocas() const;
void dumpBlockLiveness() const;
void dumpLiveRanges() const;
@@ -176,9 +176,9 @@ public:
static inline raw_ostream &operator<<(raw_ostream &OS, const BitVector &V) {
OS << "{";
- ListSeparator LS;
- for (int Idx = V.find_first(); Idx >= 0; Idx = V.find_next(Idx))
- OS << LS << Idx;
+ ListSeparator LS;
+ for (int Idx = V.find_first(); Idx >= 0; Idx = V.find_next(Idx))
+ OS << LS << Idx;
OS << "}";
return OS;
}
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/StackSafetyAnalysis.h b/contrib/libs/llvm12/include/llvm/Analysis/StackSafetyAnalysis.h
index a4121213eb..783af1e5e3 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/StackSafetyAnalysis.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/StackSafetyAnalysis.h
@@ -58,8 +58,8 @@ public:
/// StackSafety assumes that missing parameter information means possibility
/// of access to the parameter with any offset, so we can correctly link
/// code without StackSafety information, e.g. non-ThinLTO.
- std::vector<FunctionSummary::ParamAccess>
- getParamAccesses(ModuleSummaryIndex &Index) const;
+ std::vector<FunctionSummary::ParamAccess>
+ getParamAccesses(ModuleSummaryIndex &Index) const;
};
class StackSafetyGlobalInfo {
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/SyncDependenceAnalysis.h b/contrib/libs/llvm12/include/llvm/Analysis/SyncDependenceAnalysis.h
index ea0db64a28..f31348e744 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/SyncDependenceAnalysis.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/SyncDependenceAnalysis.h
@@ -28,7 +28,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/LoopInfo.h"
#include <memory>
-#include <unordered_map>
+#include <unordered_map>
namespace llvm {
@@ -38,27 +38,27 @@ class Loop;
class PostDominatorTree;
using ConstBlockSet = SmallPtrSet<const BasicBlock *, 4>;
-struct ControlDivergenceDesc {
- // Join points of divergent disjoint paths.
- ConstBlockSet JoinDivBlocks;
- // Divergent loop exits
- ConstBlockSet LoopDivBlocks;
-};
-
-struct ModifiedPO {
- std::vector<const BasicBlock *> LoopPO;
- std::unordered_map<const BasicBlock *, unsigned> POIndex;
- void appendBlock(const BasicBlock &BB) {
- POIndex[&BB] = LoopPO.size();
- LoopPO.push_back(&BB);
- }
- unsigned getIndexOf(const BasicBlock &BB) const {
- return POIndex.find(&BB)->second;
- }
- unsigned size() const { return LoopPO.size(); }
- const BasicBlock *getBlockAt(unsigned Idx) const { return LoopPO[Idx]; }
-};
-
+struct ControlDivergenceDesc {
+ // Join points of divergent disjoint paths.
+ ConstBlockSet JoinDivBlocks;
+ // Divergent loop exits
+ ConstBlockSet LoopDivBlocks;
+};
+
+struct ModifiedPO {
+ std::vector<const BasicBlock *> LoopPO;
+ std::unordered_map<const BasicBlock *, unsigned> POIndex;
+ void appendBlock(const BasicBlock &BB) {
+ POIndex[&BB] = LoopPO.size();
+ LoopPO.push_back(&BB);
+ }
+ unsigned getIndexOf(const BasicBlock &BB) const {
+ return POIndex.find(&BB)->second;
+ }
+ unsigned size() const { return LoopPO.size(); }
+ const BasicBlock *getBlockAt(unsigned Idx) const { return LoopPO[Idx]; }
+};
+
/// \brief Relates points of divergent control to join points in
/// reducible CFGs.
///
@@ -79,19 +79,19 @@ public:
/// header. Those exit blocks are added to the returned set.
/// If L is the parent loop of \p Term and an exit of L is in the returned
/// set then L is a divergent loop.
- const ControlDivergenceDesc &getJoinBlocks(const Instruction &Term);
+ const ControlDivergenceDesc &getJoinBlocks(const Instruction &Term);
private:
- static ControlDivergenceDesc EmptyDivergenceDesc;
+ static ControlDivergenceDesc EmptyDivergenceDesc;
+
+ ModifiedPO LoopPO;
- ModifiedPO LoopPO;
-
const DominatorTree &DT;
const PostDominatorTree &PDT;
const LoopInfo &LI;
- std::map<const Instruction *, std::unique_ptr<ControlDivergenceDesc>>
- CachedControlDivDescs;
+ std::map<const Instruction *, std::unique_ptr<ControlDivergenceDesc>>
+ CachedControlDivDescs;
};
} // namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/TargetLibraryInfo.def b/contrib/libs/llvm12/include/llvm/Analysis/TargetLibraryInfo.def
index 3b8edfe4cc..defc95d006 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/TargetLibraryInfo.def
+++ b/contrib/libs/llvm12/include/llvm/Analysis/TargetLibraryInfo.def
@@ -262,12 +262,12 @@ TLI_DEFINE_STRING_INTERNAL("__atanhf_finite")
/// long double __atanhl_finite(long double x);
TLI_DEFINE_ENUM_INTERNAL(atanhl_finite)
TLI_DEFINE_STRING_INTERNAL("__atanhl_finite")
-/// void __atomic_load(size_t size, void *mptr, void *vptr, int smodel);
-TLI_DEFINE_ENUM_INTERNAL(atomic_load)
-TLI_DEFINE_STRING_INTERNAL("__atomic_load")
-/// void __atomic_store(size_t size, void *mptr, void *vptr, int smodel);
-TLI_DEFINE_ENUM_INTERNAL(atomic_store)
-TLI_DEFINE_STRING_INTERNAL("__atomic_store")
+/// void __atomic_load(size_t size, void *mptr, void *vptr, int smodel);
+TLI_DEFINE_ENUM_INTERNAL(atomic_load)
+TLI_DEFINE_STRING_INTERNAL("__atomic_load")
+/// void __atomic_store(size_t size, void *mptr, void *vptr, int smodel);
+TLI_DEFINE_ENUM_INTERNAL(atomic_store)
+TLI_DEFINE_STRING_INTERNAL("__atomic_store")
/// double __cosh_finite(double x);
TLI_DEFINE_ENUM_INTERNAL(cosh_finite)
TLI_DEFINE_STRING_INTERNAL("__cosh_finite")
@@ -366,9 +366,9 @@ TLI_DEFINE_STRING_INTERNAL("__memcpy_chk")
/// void *__memmove_chk(void *s1, const void *s2, size_t n, size_t s1size);
TLI_DEFINE_ENUM_INTERNAL(memmove_chk)
TLI_DEFINE_STRING_INTERNAL("__memmove_chk")
-/// void *__mempcpy_chk(void *s1, const void *s2, size_t n, size_t s1size);
-TLI_DEFINE_ENUM_INTERNAL(mempcpy_chk)
-TLI_DEFINE_STRING_INTERNAL("__mempcpy_chk")
+/// void *__mempcpy_chk(void *s1, const void *s2, size_t n, size_t s1size);
+TLI_DEFINE_ENUM_INTERNAL(mempcpy_chk)
+TLI_DEFINE_STRING_INTERNAL("__mempcpy_chk")
/// void *__memset_chk(void *s, char v, size_t n, size_t s1size);
TLI_DEFINE_ENUM_INTERNAL(memset_chk)
TLI_DEFINE_STRING_INTERNAL("__memset_chk")
@@ -1420,18 +1420,18 @@ TLI_DEFINE_STRING_INTERNAL("utimes")
/// void *valloc(size_t size);
TLI_DEFINE_ENUM_INTERNAL(valloc)
TLI_DEFINE_STRING_INTERNAL("valloc")
-/// void *vec_calloc(size_t count, size_t size);
-TLI_DEFINE_ENUM_INTERNAL(vec_calloc)
-TLI_DEFINE_STRING_INTERNAL("vec_calloc")
-/// void vec_free(void *ptr);
-TLI_DEFINE_ENUM_INTERNAL(vec_free)
-TLI_DEFINE_STRING_INTERNAL("vec_free")
-/// void *vec_malloc(size_t size);
-TLI_DEFINE_ENUM_INTERNAL(vec_malloc)
-TLI_DEFINE_STRING_INTERNAL("vec_malloc")
-/// void *vec_realloc(void *ptr, size_t size);
-TLI_DEFINE_ENUM_INTERNAL(vec_realloc)
-TLI_DEFINE_STRING_INTERNAL("vec_realloc")
+/// void *vec_calloc(size_t count, size_t size);
+TLI_DEFINE_ENUM_INTERNAL(vec_calloc)
+TLI_DEFINE_STRING_INTERNAL("vec_calloc")
+/// void vec_free(void *ptr);
+TLI_DEFINE_ENUM_INTERNAL(vec_free)
+TLI_DEFINE_STRING_INTERNAL("vec_free")
+/// void *vec_malloc(size_t size);
+TLI_DEFINE_ENUM_INTERNAL(vec_malloc)
+TLI_DEFINE_STRING_INTERNAL("vec_malloc")
+/// void *vec_realloc(void *ptr, size_t size);
+TLI_DEFINE_ENUM_INTERNAL(vec_realloc)
+TLI_DEFINE_STRING_INTERNAL("vec_realloc")
/// int vfprintf(FILE *stream, const char *format, va_list ap);
TLI_DEFINE_ENUM_INTERNAL(vfprintf)
TLI_DEFINE_STRING_INTERNAL("vfprintf")
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/TargetLibraryInfo.h b/contrib/libs/llvm12/include/llvm/Analysis/TargetLibraryInfo.h
index eb758dc4e8..c313c1b850 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/TargetLibraryInfo.h
@@ -95,7 +95,7 @@ public:
enum VectorLibrary {
NoLibrary, // Don't use any vector library.
Accelerate, // Use Accelerate framework.
- LIBMVEC_X86,// GLIBC Vector Math library.
+ LIBMVEC_X86,// GLIBC Vector Math library.
MASSV, // IBM MASS vector library.
SVML // Intel short vector math library.
};
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/TargetTransformInfo.h b/contrib/libs/llvm12/include/llvm/Analysis/TargetTransformInfo.h
index 29ccd951e1..c4317b08d6 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/TargetTransformInfo.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/TargetTransformInfo.h
@@ -28,13 +28,13 @@
#ifndef LLVM_ANALYSIS_TARGETTRANSFORMINFO_H
#define LLVM_ANALYSIS_TARGETTRANSFORMINFO_H
-#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/InstructionCost.h"
+#include "llvm/Support/InstructionCost.h"
#include <functional>
namespace llvm {
@@ -51,7 +51,7 @@ class CallBase;
class ExtractElementInst;
class Function;
class GlobalValue;
-class InstCombiner;
+class InstCombiner;
class IntrinsicInst;
class LoadInst;
class LoopAccessInfo;
@@ -66,7 +66,7 @@ class TargetLibraryInfo;
class Type;
class User;
class Value;
-struct KnownBits;
+struct KnownBits;
template <typename T> class Optional;
/// Information about a load/store intrinsic defined by the target.
@@ -101,7 +101,7 @@ struct HardwareLoopInfo {
Loop *L = nullptr;
BasicBlock *ExitBlock = nullptr;
BranchInst *ExitBranch = nullptr;
- const SCEV *TripCount = nullptr;
+ const SCEV *TripCount = nullptr;
IntegerType *CountType = nullptr;
Value *LoopDecrement = nullptr; // Decrement the loop counter by this
// value in every iteration.
@@ -125,7 +125,7 @@ class IntrinsicCostAttributes {
SmallVector<Type *, 4> ParamTys;
SmallVector<const Value *, 4> Arguments;
FastMathFlags FMF;
- ElementCount VF = ElementCount::getFixed(1);
+ ElementCount VF = ElementCount::getFixed(1);
// If ScalarizationCost is UINT_MAX, the cost of scalarizing the
// arguments and the return value will be computed based on types.
unsigned ScalarizationCost = std::numeric_limits<unsigned>::max();
@@ -136,10 +136,10 @@ public:
IntrinsicCostAttributes(Intrinsic::ID Id, const CallBase &CI);
IntrinsicCostAttributes(Intrinsic::ID Id, const CallBase &CI,
- ElementCount Factor);
+ ElementCount Factor);
IntrinsicCostAttributes(Intrinsic::ID Id, const CallBase &CI,
- ElementCount Factor, unsigned ScalarCost);
+ ElementCount Factor, unsigned ScalarCost);
IntrinsicCostAttributes(Intrinsic::ID Id, Type *RTy,
ArrayRef<Type *> Tys, FastMathFlags Flags);
@@ -162,7 +162,7 @@ public:
Intrinsic::ID getID() const { return IID; }
const IntrinsicInst *getInst() const { return II; }
Type *getReturnType() const { return RetTy; }
- ElementCount getVectorFactor() const { return VF; }
+ ElementCount getVectorFactor() const { return VF; }
FastMathFlags getFlags() const { return FMF; }
unsigned getScalarizationCost() const { return ScalarizationCost; }
const SmallVectorImpl<const Value *> &getArgs() const { return Arguments; }
@@ -239,24 +239,24 @@ public:
///
/// Note, this method does not cache the cost calculation and it
/// can be expensive in some cases.
- InstructionCost getInstructionCost(const Instruction *I,
- enum TargetCostKind kind) const {
- InstructionCost Cost;
+ InstructionCost getInstructionCost(const Instruction *I,
+ enum TargetCostKind kind) const {
+ InstructionCost Cost;
switch (kind) {
case TCK_RecipThroughput:
- Cost = getInstructionThroughput(I);
- break;
+ Cost = getInstructionThroughput(I);
+ break;
case TCK_Latency:
- Cost = getInstructionLatency(I);
- break;
+ Cost = getInstructionLatency(I);
+ break;
case TCK_CodeSize:
case TCK_SizeAndLatency:
- Cost = getUserCost(I, kind);
- break;
+ Cost = getUserCost(I, kind);
+ break;
}
- if (Cost == -1)
- Cost.setInvalid();
- return Cost;
+ if (Cost == -1)
+ Cost.setInvalid();
+ return Cost;
}
/// Underlying constants for 'cost' values in this interface.
@@ -296,9 +296,9 @@ public:
/// individual classes of instructions would be better.
unsigned getInliningThresholdMultiplier() const;
- /// \returns A value to be added to the inlining threshold.
- unsigned adjustInliningThreshold(const CallBase *CB) const;
-
+ /// \returns A value to be added to the inlining threshold.
+ unsigned adjustInliningThreshold(const CallBase *CB) const;
+
/// \returns Vector bonus in percent.
///
/// Vector bonuses: We want to more aggressively inline vector-dense kernels
@@ -342,7 +342,7 @@ public:
/// 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, TargetCostKind CostKind) const {
- SmallVector<const Value *, 4> Operands(U->operand_values());
+ SmallVector<const Value *, 4> Operands(U->operand_values());
return getUserCost(U, Operands, CostKind);
}
@@ -397,8 +397,8 @@ public:
bool isNoopAddrSpaceCast(unsigned FromAS, unsigned ToAS) const;
- unsigned getAssumedAddrSpace(const Value *V) const;
-
+ unsigned getAssumedAddrSpace(const Value *V) const;
+
/// Rewrite intrinsic call \p II such that \p OldV will be replaced with \p
/// NewV, which has a different address space. This should happen for every
/// operand index that collectFlatAddressOperands returned for the intrinsic.
@@ -562,29 +562,29 @@ public:
/// target-independent defaults with information from \p L and \p SE.
void getPeelingPreferences(Loop *L, ScalarEvolution &SE,
PeelingPreferences &PP) const;
-
- /// Targets can implement their own combinations for target-specific
- /// intrinsics. This function will be called from the InstCombine pass every
- /// time a target-specific intrinsic is encountered.
- ///
- /// \returns None to not do anything target specific or a value that will be
- /// returned from the InstCombiner. It is possible to return null and stop
- /// further processing of the intrinsic by returning nullptr.
- Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
- IntrinsicInst &II) const;
- /// Can be used to implement target-specific instruction combining.
- /// \see instCombineIntrinsic
- Optional<Value *>
- simplifyDemandedUseBitsIntrinsic(InstCombiner &IC, IntrinsicInst &II,
- APInt DemandedMask, KnownBits &Known,
- bool &KnownBitsComputed) const;
- /// Can be used to implement target-specific instruction combining.
- /// \see instCombineIntrinsic
- Optional<Value *> simplifyDemandedVectorEltsIntrinsic(
- InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
- APInt &UndefElts2, APInt &UndefElts3,
- std::function<void(Instruction *, unsigned, APInt, APInt &)>
- SimplifyAndSetOp) const;
+
+ /// Targets can implement their own combinations for target-specific
+ /// intrinsics. This function will be called from the InstCombine pass every
+ /// time a target-specific intrinsic is encountered.
+ ///
+ /// \returns None to not do anything target specific or a value that will be
+ /// returned from the InstCombiner. It is possible to return null and stop
+ /// further processing of the intrinsic by returning nullptr.
+ Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
+ IntrinsicInst &II) const;
+ /// Can be used to implement target-specific instruction combining.
+ /// \see instCombineIntrinsic
+ Optional<Value *>
+ simplifyDemandedUseBitsIntrinsic(InstCombiner &IC, IntrinsicInst &II,
+ APInt DemandedMask, KnownBits &Known,
+ bool &KnownBitsComputed) const;
+ /// Can be used to implement target-specific instruction combining.
+ /// \see instCombineIntrinsic
+ Optional<Value *> simplifyDemandedVectorEltsIntrinsic(
+ InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
+ APInt &UndefElts2, APInt &UndefElts3,
+ std::function<void(Instruction *, unsigned, APInt, APInt &)>
+ SimplifyAndSetOp) const;
/// @}
/// \name Scalar Target Information
@@ -626,11 +626,11 @@ public:
bool isLSRCostLess(TargetTransformInfo::LSRCost &C1,
TargetTransformInfo::LSRCost &C2) const;
- /// Return true if LSR major cost is number of registers. Targets which
- /// implement their own isLSRCostLess and unset number of registers as major
- /// cost should return false, otherwise return true.
- bool isNumRegsMajorCostOfLSR() const;
-
+ /// Return true if LSR major cost is number of registers. Targets which
+ /// implement their own isLSRCostLess and unset number of registers as major
+ /// cost should return false, otherwise return true.
+ bool isNumRegsMajorCostOfLSR() const;
+
/// \returns true if LSR should not optimize a chain that includes \p I.
bool isProfitableLSRChainElement(Instruction *I) const;
@@ -720,9 +720,9 @@ public:
/// Return true if this type is legal.
bool isTypeLegal(Type *Ty) const;
- /// Returns the estimated number of registers required to represent \p Ty.
- unsigned getRegUsageForType(Type *Ty) const;
-
+ /// Returns the estimated number of registers required to represent \p Ty.
+ unsigned getRegUsageForType(Type *Ty) const;
+
/// Return true if switches should be turned into lookup tables for the
/// target.
bool shouldBuildLookupTables() const;
@@ -831,9 +831,9 @@ public:
/// 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 getIntImmCostInst(unsigned Opc, unsigned Idx, const APInt &Imm, Type *Ty,
- TargetCostKind CostKind,
- Instruction *Inst = nullptr) const;
+ int getIntImmCostInst(unsigned Opc, unsigned Idx, const APInt &Imm, Type *Ty,
+ TargetCostKind CostKind,
+ Instruction *Inst = nullptr) const;
int getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
Type *Ty, TargetCostKind CostKind) const;
@@ -897,10 +897,10 @@ public:
static ReductionKind matchVectorSplittingReduction(
const ExtractElementInst *ReduxRoot, unsigned &Opcode, VectorType *&Ty);
- static ReductionKind matchVectorReduction(const ExtractElementInst *ReduxRoot,
- unsigned &Opcode, VectorType *&Ty,
- bool &IsPairwise);
-
+ static ReductionKind matchVectorReduction(const ExtractElementInst *ReduxRoot,
+ unsigned &Opcode, VectorType *&Ty,
+ bool &IsPairwise);
+
/// Additional information about an operand's possible values.
enum OperandValueKind {
OK_AnyValue, // Operand can have any value.
@@ -937,10 +937,10 @@ public:
/// \return The width of the smallest vector register type.
unsigned getMinVectorRegisterBitWidth() const;
- /// \return The maximum value of vscale if the target specifies an
- /// architectural maximum vector length, and None otherwise.
- Optional<unsigned> getMaxVScale() const;
-
+ /// \return The maximum value of vscale if the target specifies an
+ /// architectural maximum vector length, and None otherwise.
+ Optional<unsigned> getMaxVScale() const;
+
/// \return True if the vectorization factor should be chosen to
/// make the vector of the smallest element type match the size of a
/// vector register. For wider element types, this could result in
@@ -954,11 +954,11 @@ public:
/// applies when shouldMaximizeVectorBandwidth returns true.
unsigned getMinimumVF(unsigned ElemWidth) const;
- /// \return The maximum vectorization factor for types of given element
- /// bit width and opcode, or 0 if there is no maximum VF.
- /// Currently only used by the SLP vectorizer.
- unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) const;
-
+ /// \return The maximum vectorization factor for types of given element
+ /// bit width and opcode, or 0 if there is no maximum VF.
+ /// Currently only used by the SLP vectorizer.
+ unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) 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.
@@ -1061,47 +1061,47 @@ public:
int getShuffleCost(ShuffleKind Kind, VectorType *Tp, int Index = 0,
VectorType *SubTp = nullptr) const;
- /// Represents a hint about the context in which a cast is used.
- ///
- /// For zext/sext, the context of the cast is the operand, which must be a
- /// load of some kind. For trunc, the context is of the cast is the single
- /// user of the instruction, which must be a store of some kind.
- ///
- /// This enum allows the vectorizer to give getCastInstrCost an idea of the
- /// type of cast it's dealing with, as not every cast is equal. For instance,
- /// the zext of a load may be free, but the zext of an interleaving load can
- //// be (very) expensive!
- ///
- /// See \c getCastContextHint to compute a CastContextHint from a cast
- /// Instruction*. Callers can use it if they don't need to override the
- /// context and just want it to be calculated from the instruction.
- ///
- /// FIXME: This handles the types of load/store that the vectorizer can
- /// produce, which are the cases where the context instruction is most
- /// likely to be incorrect. There are other situations where that can happen
- /// too, which might be handled here but in the long run a more general
- /// solution of costing multiple instructions at the same times may be better.
- enum class CastContextHint : uint8_t {
- None, ///< The cast is not used with a load/store of any kind.
- Normal, ///< The cast is used with a normal load/store.
- Masked, ///< The cast is used with a masked load/store.
- GatherScatter, ///< The cast is used with a gather/scatter.
- Interleave, ///< The cast is used with an interleaved load/store.
- Reversed, ///< The cast is used with a reversed load/store.
- };
-
- /// Calculates a CastContextHint from \p I.
- /// This should be used by callers of getCastInstrCost if they wish to
- /// determine the context from some instruction.
- /// \returns the CastContextHint for ZExt/SExt/Trunc, None if \p I is nullptr,
- /// or if it's another type of cast.
- static CastContextHint getCastContextHint(const Instruction *I);
-
+ /// Represents a hint about the context in which a cast is used.
+ ///
+ /// For zext/sext, the context of the cast is the operand, which must be a
+ /// load of some kind. For trunc, the context is of the cast is the single
+ /// user of the instruction, which must be a store of some kind.
+ ///
+ /// This enum allows the vectorizer to give getCastInstrCost an idea of the
+ /// type of cast it's dealing with, as not every cast is equal. For instance,
+ /// the zext of a load may be free, but the zext of an interleaving load can
+ //// be (very) expensive!
+ ///
+ /// See \c getCastContextHint to compute a CastContextHint from a cast
+ /// Instruction*. Callers can use it if they don't need to override the
+ /// context and just want it to be calculated from the instruction.
+ ///
+ /// FIXME: This handles the types of load/store that the vectorizer can
+ /// produce, which are the cases where the context instruction is most
+ /// likely to be incorrect. There are other situations where that can happen
+ /// too, which might be handled here but in the long run a more general
+ /// solution of costing multiple instructions at the same times may be better.
+ enum class CastContextHint : uint8_t {
+ None, ///< The cast is not used with a load/store of any kind.
+ Normal, ///< The cast is used with a normal load/store.
+ Masked, ///< The cast is used with a masked load/store.
+ GatherScatter, ///< The cast is used with a gather/scatter.
+ Interleave, ///< The cast is used with an interleaved load/store.
+ Reversed, ///< The cast is used with a reversed load/store.
+ };
+
+ /// Calculates a CastContextHint from \p I.
+ /// This should be used by callers of getCastInstrCost if they wish to
+ /// determine the context from some instruction.
+ /// \returns the CastContextHint for ZExt/SExt/Trunc, None if \p I is nullptr,
+ /// or if it's another type of cast.
+ static CastContextHint getCastContextHint(const Instruction *I);
+
/// \return The expected cost of cast instructions, such as bitcast, trunc,
/// zext, etc. If there is an existing instruction that holds Opcode, it
/// may be passed in the 'I' parameter.
int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
- TTI::CastContextHint CCH,
+ TTI::CastContextHint CCH,
TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency,
const Instruction *I = nullptr) const;
@@ -1117,14 +1117,14 @@ public:
/// \returns The expected cost of compare and select instructions. If there
/// is an existing instruction that holds Opcode, it may be passed in the
- /// 'I' parameter. The \p VecPred parameter can be used to indicate the select
- /// is using a compare with the specified predicate as condition. When vector
- /// types are passed, \p VecPred must be used for all lanes.
- int getCmpSelInstrCost(
- unsigned Opcode, Type *ValTy, Type *CondTy = nullptr,
- CmpInst::Predicate VecPred = CmpInst::BAD_ICMP_PREDICATE,
- TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput,
- const Instruction *I = nullptr) const;
+ /// 'I' parameter. The \p VecPred parameter can be used to indicate the select
+ /// is using a compare with the specified predicate as condition. When vector
+ /// types are passed, \p VecPred must be used for all lanes.
+ int getCmpSelInstrCost(
+ unsigned Opcode, Type *ValTy, Type *CondTy = nullptr,
+ CmpInst::Predicate VecPred = CmpInst::BAD_ICMP_PREDICATE,
+ TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput,
+ const Instruction *I = nullptr) const;
/// \return The expected cost of vector Insert and Extract.
/// Use -1 to indicate that there is no information on the index value.
@@ -1192,16 +1192,16 @@ public:
VectorType *Ty, VectorType *CondTy, bool IsPairwiseForm, bool IsUnsigned,
TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput) const;
- /// Calculate the cost of an extended reduction pattern, similar to
- /// getArithmeticReductionCost of an Add reduction with an extension and
- /// optional multiply. This is the cost of as:
- /// ResTy vecreduce.add(ext(Ty A)), or if IsMLA flag is set then:
- /// ResTy vecreduce.add(mul(ext(Ty A), ext(Ty B)). The reduction happens
- /// on a VectorType with ResTy elements and Ty lanes.
- InstructionCost getExtendedAddReductionCost(
- bool IsMLA, bool IsUnsigned, Type *ResTy, VectorType *Ty,
- TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput) const;
-
+ /// Calculate the cost of an extended reduction pattern, similar to
+ /// getArithmeticReductionCost of an Add reduction with an extension and
+ /// optional multiply. This is the cost of as:
+ /// ResTy vecreduce.add(ext(Ty A)), or if IsMLA flag is set then:
+ /// ResTy vecreduce.add(mul(ext(Ty A), ext(Ty B)). The reduction happens
+ /// on a VectorType with ResTy elements and Ty lanes.
+ InstructionCost getExtendedAddReductionCost(
+ bool IsMLA, bool IsUnsigned, Type *ResTy, VectorType *Ty,
+ TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput) const;
+
/// \returns The cost of Intrinsic instructions. Analyses the real arguments.
/// Three cases are handled: 1. scalar instruction 2. vector instruction
/// 3. scalar instruction which is to be vectorized.
@@ -1337,24 +1337,24 @@ public:
bool useReductionIntrinsic(unsigned Opcode, Type *Ty,
ReductionFlags Flags) const;
- /// \returns True if the target prefers reductions in loop.
- bool preferInLoopReduction(unsigned Opcode, Type *Ty,
- ReductionFlags Flags) const;
-
- /// \returns True if the target prefers reductions select kept in the loop
- /// when tail folding. i.e.
- /// loop:
- /// p = phi (0, s)
- /// a = add (p, x)
- /// s = select (mask, a, p)
- /// vecreduce.add(s)
- ///
- /// As opposed to the normal scheme of p = phi (0, a) which allows the select
- /// to be pulled out of the loop. If the select(.., add, ..) can be predicated
- /// by the target, this can lead to cleaner code generation.
- bool preferPredicatedReductionSelect(unsigned Opcode, Type *Ty,
- ReductionFlags Flags) const;
-
+ /// \returns True if the target prefers reductions in loop.
+ bool preferInLoopReduction(unsigned Opcode, Type *Ty,
+ ReductionFlags Flags) const;
+
+ /// \returns True if the target prefers reductions select kept in the loop
+ /// when tail folding. i.e.
+ /// loop:
+ /// p = phi (0, s)
+ /// a = add (p, x)
+ /// s = select (mask, a, p)
+ /// vecreduce.add(s)
+ ///
+ /// As opposed to the normal scheme of p = phi (0, a) which allows the select
+ /// to be pulled out of the loop. If the select(.., add, ..) can be predicated
+ /// by the target, this can lead to cleaner code generation.
+ bool preferPredicatedReductionSelect(unsigned Opcode, Type *Ty,
+ ReductionFlags Flags) const;
+
/// \returns True if the target wants to expand the given reduction intrinsic
/// into a shuffle sequence.
bool shouldExpandReduction(const IntrinsicInst *II) const;
@@ -1363,9 +1363,9 @@ public:
/// to a stack reload.
unsigned getGISelRematGlobalCost() const;
- /// \returns True if the target supports scalable vectors.
- bool supportsScalableVectors() const;
-
+ /// \returns True if the target supports scalable vectors.
+ bool supportsScalableVectors() const;
+
/// \name Vector Predication Information
/// @{
/// Whether the target supports the %evl parameter of VP intrinsic efficiently
@@ -1405,7 +1405,7 @@ public:
ArrayRef<const Value *> Operands,
TTI::TargetCostKind CostKind) = 0;
virtual unsigned getInliningThresholdMultiplier() = 0;
- virtual unsigned adjustInliningThreshold(const CallBase *CB) = 0;
+ virtual unsigned adjustInliningThreshold(const CallBase *CB) = 0;
virtual int getInlinerVectorBonusPercent() = 0;
virtual int getMemcpyCost(const Instruction *I) = 0;
virtual unsigned
@@ -1422,7 +1422,7 @@ public:
virtual bool collectFlatAddressOperands(SmallVectorImpl<int> &OpIndexes,
Intrinsic::ID IID) const = 0;
virtual bool isNoopAddrSpaceCast(unsigned FromAS, unsigned ToAS) const = 0;
- virtual unsigned getAssumedAddrSpace(const Value *V) const = 0;
+ virtual unsigned getAssumedAddrSpace(const Value *V) const = 0;
virtual Value *rewriteIntrinsicWithAddressSpace(IntrinsicInst *II,
Value *OldV,
Value *NewV) const = 0;
@@ -1440,17 +1440,17 @@ public:
AssumptionCache &AC, TargetLibraryInfo *TLI,
DominatorTree *DT, const LoopAccessInfo *LAI) = 0;
virtual bool emitGetActiveLaneMask() = 0;
- virtual Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
- IntrinsicInst &II) = 0;
- virtual Optional<Value *>
- simplifyDemandedUseBitsIntrinsic(InstCombiner &IC, IntrinsicInst &II,
- APInt DemandedMask, KnownBits &Known,
- bool &KnownBitsComputed) = 0;
- virtual Optional<Value *> simplifyDemandedVectorEltsIntrinsic(
- InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
- APInt &UndefElts2, APInt &UndefElts3,
- std::function<void(Instruction *, unsigned, APInt, APInt &)>
- SimplifyAndSetOp) = 0;
+ virtual Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
+ IntrinsicInst &II) = 0;
+ virtual Optional<Value *>
+ simplifyDemandedUseBitsIntrinsic(InstCombiner &IC, IntrinsicInst &II,
+ APInt DemandedMask, KnownBits &Known,
+ bool &KnownBitsComputed) = 0;
+ virtual Optional<Value *> simplifyDemandedVectorEltsIntrinsic(
+ InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
+ APInt &UndefElts2, APInt &UndefElts3,
+ std::function<void(Instruction *, unsigned, APInt, APInt &)>
+ SimplifyAndSetOp) = 0;
virtual bool isLegalAddImmediate(int64_t Imm) = 0;
virtual bool isLegalICmpImmediate(int64_t Imm) = 0;
virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
@@ -1459,7 +1459,7 @@ public:
Instruction *I) = 0;
virtual bool isLSRCostLess(TargetTransformInfo::LSRCost &C1,
TargetTransformInfo::LSRCost &C2) = 0;
- virtual bool isNumRegsMajorCostOfLSR() = 0;
+ virtual bool isNumRegsMajorCostOfLSR() = 0;
virtual bool isProfitableLSRChainElement(Instruction *I) = 0;
virtual bool canMacroFuseCmp() = 0;
virtual bool canSaveCmp(Loop *L, BranchInst **BI, ScalarEvolution *SE,
@@ -1486,7 +1486,7 @@ public:
virtual bool isProfitableToHoist(Instruction *I) = 0;
virtual bool useAA() = 0;
virtual bool isTypeLegal(Type *Ty) = 0;
- virtual unsigned getRegUsageForType(Type *Ty) = 0;
+ virtual unsigned getRegUsageForType(Type *Ty) = 0;
virtual bool shouldBuildLookupTables() = 0;
virtual bool shouldBuildLookupTablesForConstant(Constant *C) = 0;
virtual bool useColdCCForColdCall(Function &F) = 0;
@@ -1517,8 +1517,8 @@ public:
virtual int getIntImmCost(const APInt &Imm, Type *Ty,
TargetCostKind CostKind) = 0;
virtual int getIntImmCostInst(unsigned Opc, unsigned Idx, const APInt &Imm,
- Type *Ty, TargetCostKind CostKind,
- Instruction *Inst = nullptr) = 0;
+ Type *Ty, TargetCostKind CostKind,
+ Instruction *Inst = nullptr) = 0;
virtual int getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
const APInt &Imm, Type *Ty,
TargetCostKind CostKind) = 0;
@@ -1528,10 +1528,10 @@ public:
virtual const char *getRegisterClassName(unsigned ClassID) const = 0;
virtual unsigned getRegisterBitWidth(bool Vector) const = 0;
virtual unsigned getMinVectorRegisterBitWidth() = 0;
- virtual Optional<unsigned> getMaxVScale() const = 0;
+ virtual Optional<unsigned> getMaxVScale() const = 0;
virtual bool shouldMaximizeVectorBandwidth(bool OptSize) const = 0;
virtual unsigned getMinimumVF(unsigned ElemWidth) const = 0;
- virtual unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) const = 0;
+ virtual unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) const = 0;
virtual bool shouldConsiderAddressTypePromotion(
const Instruction &I, bool &AllowPromotionWithoutCommonHeader) = 0;
virtual unsigned getCacheLineSize() const = 0;
@@ -1573,7 +1573,7 @@ public:
virtual int getShuffleCost(ShuffleKind Kind, VectorType *Tp, int Index,
VectorType *SubTp) = 0;
virtual int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
- CastContextHint CCH,
+ CastContextHint CCH,
TTI::TargetCostKind CostKind,
const Instruction *I) = 0;
virtual int getExtractWithExtendCost(unsigned Opcode, Type *Dst,
@@ -1581,7 +1581,7 @@ public:
virtual int getCFInstrCost(unsigned Opcode,
TTI::TargetCostKind CostKind) = 0;
virtual int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
- CmpInst::Predicate VecPred,
+ CmpInst::Predicate VecPred,
TTI::TargetCostKind CostKind,
const Instruction *I) = 0;
virtual int getVectorInstrCost(unsigned Opcode, Type *Val,
@@ -1609,9 +1609,9 @@ public:
virtual int getMinMaxReductionCost(VectorType *Ty, VectorType *CondTy,
bool IsPairwiseForm, bool IsUnsigned,
TTI::TargetCostKind CostKind) = 0;
- virtual InstructionCost getExtendedAddReductionCost(
- bool IsMLA, bool IsUnsigned, Type *ResTy, VectorType *Ty,
- TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput) = 0;
+ virtual InstructionCost getExtendedAddReductionCost(
+ bool IsMLA, bool IsUnsigned, Type *ResTy, VectorType *Ty,
+ TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput) = 0;
virtual int getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
TTI::TargetCostKind CostKind) = 0;
virtual int getCallInstrCost(Function *F, Type *RetTy,
@@ -1659,13 +1659,13 @@ public:
VectorType *VecTy) const = 0;
virtual bool useReductionIntrinsic(unsigned Opcode, Type *Ty,
ReductionFlags) const = 0;
- virtual bool preferInLoopReduction(unsigned Opcode, Type *Ty,
- ReductionFlags) const = 0;
- virtual bool preferPredicatedReductionSelect(unsigned Opcode, Type *Ty,
- ReductionFlags) const = 0;
+ virtual bool preferInLoopReduction(unsigned Opcode, Type *Ty,
+ ReductionFlags) const = 0;
+ virtual bool preferPredicatedReductionSelect(unsigned Opcode, Type *Ty,
+ ReductionFlags) const = 0;
virtual bool shouldExpandReduction(const IntrinsicInst *II) const = 0;
virtual unsigned getGISelRematGlobalCost() const = 0;
- virtual bool supportsScalableVectors() const = 0;
+ virtual bool supportsScalableVectors() const = 0;
virtual bool hasActiveVectorLength() const = 0;
virtual int getInstructionLatency(const Instruction *I) = 0;
};
@@ -1690,9 +1690,9 @@ public:
unsigned getInliningThresholdMultiplier() override {
return Impl.getInliningThresholdMultiplier();
}
- unsigned adjustInliningThreshold(const CallBase *CB) override {
- return Impl.adjustInliningThreshold(CB);
- }
+ unsigned adjustInliningThreshold(const CallBase *CB) override {
+ return Impl.adjustInliningThreshold(CB);
+ }
int getInlinerVectorBonusPercent() override {
return Impl.getInlinerVectorBonusPercent();
}
@@ -1726,10 +1726,10 @@ public:
return Impl.isNoopAddrSpaceCast(FromAS, ToAS);
}
- unsigned getAssumedAddrSpace(const Value *V) const override {
- return Impl.getAssumedAddrSpace(V);
- }
-
+ unsigned getAssumedAddrSpace(const Value *V) const override {
+ return Impl.getAssumedAddrSpace(V);
+ }
+
Value *rewriteIntrinsicWithAddressSpace(IntrinsicInst *II, Value *OldV,
Value *NewV) const override {
return Impl.rewriteIntrinsicWithAddressSpace(II, OldV, NewV);
@@ -1760,26 +1760,26 @@ public:
bool emitGetActiveLaneMask() override {
return Impl.emitGetActiveLaneMask();
}
- Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
- IntrinsicInst &II) override {
- return Impl.instCombineIntrinsic(IC, II);
- }
- Optional<Value *>
- simplifyDemandedUseBitsIntrinsic(InstCombiner &IC, IntrinsicInst &II,
- APInt DemandedMask, KnownBits &Known,
- bool &KnownBitsComputed) override {
- return Impl.simplifyDemandedUseBitsIntrinsic(IC, II, DemandedMask, Known,
- KnownBitsComputed);
- }
- Optional<Value *> simplifyDemandedVectorEltsIntrinsic(
- InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
- APInt &UndefElts2, APInt &UndefElts3,
- std::function<void(Instruction *, unsigned, APInt, APInt &)>
- SimplifyAndSetOp) override {
- return Impl.simplifyDemandedVectorEltsIntrinsic(
- IC, II, DemandedElts, UndefElts, UndefElts2, UndefElts3,
- SimplifyAndSetOp);
- }
+ Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
+ IntrinsicInst &II) override {
+ return Impl.instCombineIntrinsic(IC, II);
+ }
+ Optional<Value *>
+ simplifyDemandedUseBitsIntrinsic(InstCombiner &IC, IntrinsicInst &II,
+ APInt DemandedMask, KnownBits &Known,
+ bool &KnownBitsComputed) override {
+ return Impl.simplifyDemandedUseBitsIntrinsic(IC, II, DemandedMask, Known,
+ KnownBitsComputed);
+ }
+ Optional<Value *> simplifyDemandedVectorEltsIntrinsic(
+ InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
+ APInt &UndefElts2, APInt &UndefElts3,
+ std::function<void(Instruction *, unsigned, APInt, APInt &)>
+ SimplifyAndSetOp) override {
+ return Impl.simplifyDemandedVectorEltsIntrinsic(
+ IC, II, DemandedElts, UndefElts, UndefElts2, UndefElts3,
+ SimplifyAndSetOp);
+ }
bool isLegalAddImmediate(int64_t Imm) override {
return Impl.isLegalAddImmediate(Imm);
}
@@ -1796,9 +1796,9 @@ public:
TargetTransformInfo::LSRCost &C2) override {
return Impl.isLSRCostLess(C1, C2);
}
- bool isNumRegsMajorCostOfLSR() override {
- return Impl.isNumRegsMajorCostOfLSR();
- }
+ bool isNumRegsMajorCostOfLSR() override {
+ return Impl.isNumRegsMajorCostOfLSR();
+ }
bool isProfitableLSRChainElement(Instruction *I) override {
return Impl.isProfitableLSRChainElement(I);
}
@@ -1860,9 +1860,9 @@ public:
}
bool useAA() override { return Impl.useAA(); }
bool isTypeLegal(Type *Ty) override { return Impl.isTypeLegal(Ty); }
- unsigned getRegUsageForType(Type *Ty) override {
- return Impl.getRegUsageForType(Ty);
- }
+ unsigned getRegUsageForType(Type *Ty) override {
+ return Impl.getRegUsageForType(Ty);
+ }
bool shouldBuildLookupTables() override {
return Impl.shouldBuildLookupTables();
}
@@ -1927,10 +1927,10 @@ public:
TargetCostKind CostKind) override {
return Impl.getIntImmCost(Imm, Ty, CostKind);
}
- int getIntImmCostInst(unsigned Opc, unsigned Idx, const APInt &Imm, Type *Ty,
- TargetCostKind CostKind,
- Instruction *Inst = nullptr) override {
- return Impl.getIntImmCostInst(Opc, Idx, Imm, Ty, CostKind, Inst);
+ int getIntImmCostInst(unsigned Opc, unsigned Idx, const APInt &Imm, Type *Ty,
+ TargetCostKind CostKind,
+ Instruction *Inst = nullptr) override {
+ return Impl.getIntImmCostInst(Opc, Idx, Imm, Ty, CostKind, Inst);
}
int getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
Type *Ty, TargetCostKind CostKind) override {
@@ -1952,18 +1952,18 @@ public:
unsigned getMinVectorRegisterBitWidth() override {
return Impl.getMinVectorRegisterBitWidth();
}
- Optional<unsigned> getMaxVScale() const override {
- return Impl.getMaxVScale();
- }
+ Optional<unsigned> getMaxVScale() const override {
+ return Impl.getMaxVScale();
+ }
bool shouldMaximizeVectorBandwidth(bool OptSize) const override {
return Impl.shouldMaximizeVectorBandwidth(OptSize);
}
unsigned getMinimumVF(unsigned ElemWidth) const override {
return Impl.getMinimumVF(ElemWidth);
}
- unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) const override {
- return Impl.getMaximumVF(ElemWidth, Opcode);
- }
+ unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) const override {
+ return Impl.getMaximumVF(ElemWidth, Opcode);
+ }
bool shouldConsiderAddressTypePromotion(
const Instruction &I, bool &AllowPromotionWithoutCommonHeader) override {
return Impl.shouldConsiderAddressTypePromotion(
@@ -2031,9 +2031,9 @@ public:
return Impl.getShuffleCost(Kind, Tp, Index, SubTp);
}
int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
- CastContextHint CCH, TTI::TargetCostKind CostKind,
+ CastContextHint CCH, TTI::TargetCostKind CostKind,
const Instruction *I) override {
- return Impl.getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
+ return Impl.getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
}
int getExtractWithExtendCost(unsigned Opcode, Type *Dst, VectorType *VecTy,
unsigned Index) override {
@@ -2043,10 +2043,10 @@ public:
return Impl.getCFInstrCost(Opcode, CostKind);
}
int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
- CmpInst::Predicate VecPred,
+ CmpInst::Predicate VecPred,
TTI::TargetCostKind CostKind,
const Instruction *I) override {
- return Impl.getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind, I);
+ return Impl.getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind, I);
}
int getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index) override {
return Impl.getVectorInstrCost(Opcode, Val, Index);
@@ -2092,12 +2092,12 @@ public:
return Impl.getMinMaxReductionCost(Ty, CondTy, IsPairwiseForm, IsUnsigned,
CostKind);
}
- InstructionCost getExtendedAddReductionCost(
- bool IsMLA, bool IsUnsigned, Type *ResTy, VectorType *Ty,
- TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput) override {
- return Impl.getExtendedAddReductionCost(IsMLA, IsUnsigned, ResTy, Ty,
- CostKind);
- }
+ InstructionCost getExtendedAddReductionCost(
+ bool IsMLA, bool IsUnsigned, Type *ResTy, VectorType *Ty,
+ TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput) override {
+ return Impl.getExtendedAddReductionCost(IsMLA, IsUnsigned, ResTy, Ty,
+ CostKind);
+ }
int getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
TTI::TargetCostKind CostKind) override {
return Impl.getIntrinsicInstrCost(ICA, CostKind);
@@ -2191,14 +2191,14 @@ public:
ReductionFlags Flags) const override {
return Impl.useReductionIntrinsic(Opcode, Ty, Flags);
}
- bool preferInLoopReduction(unsigned Opcode, Type *Ty,
- ReductionFlags Flags) const override {
- return Impl.preferInLoopReduction(Opcode, Ty, Flags);
- }
- bool preferPredicatedReductionSelect(unsigned Opcode, Type *Ty,
- ReductionFlags Flags) const override {
- return Impl.preferPredicatedReductionSelect(Opcode, Ty, Flags);
- }
+ bool preferInLoopReduction(unsigned Opcode, Type *Ty,
+ ReductionFlags Flags) const override {
+ return Impl.preferInLoopReduction(Opcode, Ty, Flags);
+ }
+ bool preferPredicatedReductionSelect(unsigned Opcode, Type *Ty,
+ ReductionFlags Flags) const override {
+ return Impl.preferPredicatedReductionSelect(Opcode, Ty, Flags);
+ }
bool shouldExpandReduction(const IntrinsicInst *II) const override {
return Impl.shouldExpandReduction(II);
}
@@ -2207,10 +2207,10 @@ public:
return Impl.getGISelRematGlobalCost();
}
- bool supportsScalableVectors() const override {
- return Impl.supportsScalableVectors();
- }
-
+ bool supportsScalableVectors() const override {
+ return Impl.supportsScalableVectors();
+ }
+
bool hasActiveVectorLength() const override {
return Impl.hasActiveVectorLength();
}
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/TargetTransformInfoImpl.h b/contrib/libs/llvm12/include/llvm/Analysis/TargetTransformInfoImpl.h
index 30212e7c4d..0627f8b1be 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -27,7 +27,7 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
-#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Type.h"
@@ -53,7 +53,7 @@ public:
int getGEPCost(Type *PointeeType, const Value *Ptr,
ArrayRef<const Value *> Operands,
- TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency) const {
+ TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency) const {
// In the basic model, we just assume that all-constant GEPs will be folded
// into their uses via addressing modes.
for (unsigned Idx = 0, Size = Operands.size(); Idx != Size; ++Idx)
@@ -66,31 +66,31 @@ public:
unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI,
unsigned &JTSize,
ProfileSummaryInfo *PSI,
- BlockFrequencyInfo *BFI) const {
+ BlockFrequencyInfo *BFI) const {
(void)PSI;
(void)BFI;
JTSize = 0;
return SI.getNumCases();
}
- unsigned getInliningThresholdMultiplier() const { return 1; }
- unsigned adjustInliningThreshold(const CallBase *CB) const { return 0; }
+ unsigned getInliningThresholdMultiplier() const { return 1; }
+ unsigned adjustInliningThreshold(const CallBase *CB) const { return 0; }
- int getInlinerVectorBonusPercent() const { return 150; }
+ int getInlinerVectorBonusPercent() const { return 150; }
- unsigned getMemcpyCost(const Instruction *I) const {
- return TTI::TCC_Expensive;
- }
+ unsigned getMemcpyCost(const Instruction *I) const {
+ return TTI::TCC_Expensive;
+ }
- bool hasBranchDivergence() const { return false; }
+ bool hasBranchDivergence() const { return false; }
- bool useGPUDivergenceAnalysis() const { return false; }
+ bool useGPUDivergenceAnalysis() const { return false; }
- bool isSourceOfDivergence(const Value *V) const { return false; }
+ bool isSourceOfDivergence(const Value *V) const { return false; }
- bool isAlwaysUniform(const Value *V) const { return false; }
+ bool isAlwaysUniform(const Value *V) const { return false; }
- unsigned getFlatAddressSpace() const { return -1; }
+ unsigned getFlatAddressSpace() const { return -1; }
bool collectFlatAddressOperands(SmallVectorImpl<int> &OpIndexes,
Intrinsic::ID IID) const {
@@ -99,14 +99,14 @@ public:
bool isNoopAddrSpaceCast(unsigned, unsigned) const { return false; }
- unsigned getAssumedAddrSpace(const Value *V) const { return -1; }
-
+ unsigned getAssumedAddrSpace(const Value *V) const { return -1; }
+
Value *rewriteIntrinsicWithAddressSpace(IntrinsicInst *II, Value *OldV,
Value *NewV) const {
return nullptr;
}
- bool isLoweredToCall(const Function *F) const {
+ bool isLoweredToCall(const Function *F) const {
assert(F && "A concrete function must be provided to this routine.");
// FIXME: These should almost certainly not be handled here, and instead
@@ -144,7 +144,7 @@ public:
bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
AssumptionCache &AC, TargetLibraryInfo *LibInfo,
- HardwareLoopInfo &HWLoopInfo) const {
+ HardwareLoopInfo &HWLoopInfo) const {
return false;
}
@@ -159,60 +159,60 @@ public:
return false;
}
- Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
- IntrinsicInst &II) const {
- return None;
- }
-
- Optional<Value *>
- simplifyDemandedUseBitsIntrinsic(InstCombiner &IC, IntrinsicInst &II,
- APInt DemandedMask, KnownBits &Known,
- bool &KnownBitsComputed) const {
- return None;
- }
-
- Optional<Value *> simplifyDemandedVectorEltsIntrinsic(
- InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
- APInt &UndefElts2, APInt &UndefElts3,
- std::function<void(Instruction *, unsigned, APInt, APInt &)>
- SimplifyAndSetOp) const {
- return None;
- }
-
+ Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
+ IntrinsicInst &II) const {
+ return None;
+ }
+
+ Optional<Value *>
+ simplifyDemandedUseBitsIntrinsic(InstCombiner &IC, IntrinsicInst &II,
+ APInt DemandedMask, KnownBits &Known,
+ bool &KnownBitsComputed) const {
+ return None;
+ }
+
+ Optional<Value *> simplifyDemandedVectorEltsIntrinsic(
+ InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
+ APInt &UndefElts2, APInt &UndefElts3,
+ std::function<void(Instruction *, unsigned, APInt, APInt &)>
+ SimplifyAndSetOp) const {
+ return None;
+ }
+
void getUnrollingPreferences(Loop *, ScalarEvolution &,
- TTI::UnrollingPreferences &) const {}
+ TTI::UnrollingPreferences &) const {}
void getPeelingPreferences(Loop *, ScalarEvolution &,
- TTI::PeelingPreferences &) const {}
+ TTI::PeelingPreferences &) const {}
- bool isLegalAddImmediate(int64_t Imm) const { return false; }
+ bool isLegalAddImmediate(int64_t Imm) const { return false; }
- bool isLegalICmpImmediate(int64_t Imm) const { return false; }
+ bool isLegalICmpImmediate(int64_t Imm) const { return false; }
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
bool HasBaseReg, int64_t Scale, unsigned AddrSpace,
- Instruction *I = nullptr) const {
+ Instruction *I = nullptr) const {
// Guess that only reg and reg+reg addressing is allowed. This heuristic is
// taken from the implementation of LSR.
return !BaseGV && BaseOffset == 0 && (Scale == 0 || Scale == 1);
}
- bool isLSRCostLess(TTI::LSRCost &C1, TTI::LSRCost &C2) const {
+ bool isLSRCostLess(TTI::LSRCost &C1, TTI::LSRCost &C2) const {
return std::tie(C1.NumRegs, C1.AddRecCost, C1.NumIVMuls, C1.NumBaseAdds,
C1.ScaleCost, C1.ImmCost, C1.SetupCost) <
std::tie(C2.NumRegs, C2.AddRecCost, C2.NumIVMuls, C2.NumBaseAdds,
C2.ScaleCost, C2.ImmCost, C2.SetupCost);
}
- bool isNumRegsMajorCostOfLSR() const { return true; }
+ bool isNumRegsMajorCostOfLSR() const { return true; }
+
+ bool isProfitableLSRChainElement(Instruction *I) const { return false; }
- bool isProfitableLSRChainElement(Instruction *I) const { return false; }
+ bool canMacroFuseCmp() const { return false; }
- bool canMacroFuseCmp() const { return false; }
-
bool canSaveCmp(Loop *L, BranchInst **BI, ScalarEvolution *SE, LoopInfo *LI,
DominatorTree *DT, AssumptionCache *AC,
- TargetLibraryInfo *LibInfo) const {
+ TargetLibraryInfo *LibInfo) const {
return false;
}
@@ -220,51 +220,51 @@ public:
bool shouldFavorBackedgeIndex(const Loop *L) const { return false; }
- bool isLegalMaskedStore(Type *DataType, Align Alignment) const {
- return false;
- }
+ bool isLegalMaskedStore(Type *DataType, Align Alignment) const {
+ return false;
+ }
- bool isLegalMaskedLoad(Type *DataType, Align Alignment) const {
- return false;
- }
+ bool isLegalMaskedLoad(Type *DataType, Align Alignment) const {
+ return false;
+ }
- bool isLegalNTStore(Type *DataType, Align Alignment) const {
+ bool isLegalNTStore(Type *DataType, Align Alignment) const {
// By default, assume nontemporal memory stores are available for stores
// that are aligned and have a size that is a power of 2.
unsigned DataSize = DL.getTypeStoreSize(DataType);
return Alignment >= DataSize && isPowerOf2_32(DataSize);
}
- bool isLegalNTLoad(Type *DataType, Align Alignment) const {
+ bool isLegalNTLoad(Type *DataType, Align Alignment) const {
// By default, assume nontemporal memory loads are available for loads that
// are aligned and have a size that is a power of 2.
unsigned DataSize = DL.getTypeStoreSize(DataType);
return Alignment >= DataSize && isPowerOf2_32(DataSize);
}
- bool isLegalMaskedScatter(Type *DataType, Align Alignment) const {
- return false;
- }
+ bool isLegalMaskedScatter(Type *DataType, Align Alignment) const {
+ return false;
+ }
- bool isLegalMaskedGather(Type *DataType, Align Alignment) const {
- return false;
- }
+ bool isLegalMaskedGather(Type *DataType, Align Alignment) const {
+ return false;
+ }
- bool isLegalMaskedCompressStore(Type *DataType) const { return false; }
+ bool isLegalMaskedCompressStore(Type *DataType) const { return false; }
- bool isLegalMaskedExpandLoad(Type *DataType) const { return false; }
+ bool isLegalMaskedExpandLoad(Type *DataType) const { return false; }
- bool hasDivRemOp(Type *DataType, bool IsSigned) const { return false; }
+ bool hasDivRemOp(Type *DataType, bool IsSigned) const { return false; }
- bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const {
- return false;
- }
+ bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const {
+ return false;
+ }
- bool prefersVectorizedAddressing() const { return true; }
+ bool prefersVectorizedAddressing() const { return true; }
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
- bool HasBaseReg, int64_t Scale,
- unsigned AddrSpace) const {
+ bool HasBaseReg, int64_t Scale,
+ unsigned AddrSpace) const {
// Guess that all legal addressing mode are free.
if (isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, Scale,
AddrSpace))
@@ -272,87 +272,87 @@ public:
return -1;
}
- bool LSRWithInstrQueries() const { return false; }
+ bool LSRWithInstrQueries() const { return false; }
+
+ bool isTruncateFree(Type *Ty1, Type *Ty2) const { return false; }
- bool isTruncateFree(Type *Ty1, Type *Ty2) const { return false; }
+ bool isProfitableToHoist(Instruction *I) const { return true; }
- bool isProfitableToHoist(Instruction *I) const { return true; }
+ bool useAA() const { return false; }
- bool useAA() const { return false; }
+ bool isTypeLegal(Type *Ty) const { return false; }
- bool isTypeLegal(Type *Ty) const { return false; }
+ unsigned getRegUsageForType(Type *Ty) const { return 1; }
- unsigned getRegUsageForType(Type *Ty) const { return 1; }
+ bool shouldBuildLookupTables() const { return true; }
+ bool shouldBuildLookupTablesForConstant(Constant *C) const { return true; }
- bool shouldBuildLookupTables() const { return true; }
- bool shouldBuildLookupTablesForConstant(Constant *C) const { return true; }
+ bool useColdCCForColdCall(Function &F) const { return false; }
- bool useColdCCForColdCall(Function &F) const { return false; }
-
unsigned getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts,
- bool Insert, bool Extract) const {
+ bool Insert, bool Extract) const {
return 0;
}
unsigned getOperandsScalarizationOverhead(ArrayRef<const Value *> Args,
- unsigned VF) const {
+ unsigned VF) const {
return 0;
}
- bool supportsEfficientVectorElementLoadStore() const { return false; }
+ bool supportsEfficientVectorElementLoadStore() const { return false; }
- bool enableAggressiveInterleaving(bool LoopHasReductions) const {
- return false;
- }
+ bool enableAggressiveInterleaving(bool LoopHasReductions) const {
+ return false;
+ }
TTI::MemCmpExpansionOptions enableMemCmpExpansion(bool OptSize,
bool IsZeroCmp) const {
return {};
}
- bool enableInterleavedAccessVectorization() const { return false; }
+ bool enableInterleavedAccessVectorization() const { return false; }
- bool enableMaskedInterleavedAccessVectorization() const { return false; }
+ bool enableMaskedInterleavedAccessVectorization() const { return false; }
- bool isFPVectorizationPotentiallyUnsafe() const { return false; }
+ bool isFPVectorizationPotentiallyUnsafe() const { return false; }
bool allowsMisalignedMemoryAccesses(LLVMContext &Context, unsigned BitWidth,
unsigned AddressSpace, unsigned Alignment,
- bool *Fast) const {
+ bool *Fast) const {
return false;
}
- TTI::PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const {
+ TTI::PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const {
return TTI::PSK_Software;
}
- bool haveFastSqrt(Type *Ty) const { return false; }
+ bool haveFastSqrt(Type *Ty) const { return false; }
- bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const { return true; }
+ bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const { return true; }
- unsigned getFPOpCost(Type *Ty) const {
- return TargetTransformInfo::TCC_Basic;
- }
+ unsigned getFPOpCost(Type *Ty) const {
+ return TargetTransformInfo::TCC_Basic;
+ }
int getIntImmCodeSizeCost(unsigned Opcode, unsigned Idx, const APInt &Imm,
- Type *Ty) const {
+ Type *Ty) const {
return 0;
}
unsigned getIntImmCost(const APInt &Imm, Type *Ty,
- TTI::TargetCostKind CostKind) const {
+ TTI::TargetCostKind CostKind) const {
return TTI::TCC_Basic;
}
unsigned getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm,
- Type *Ty, TTI::TargetCostKind CostKind,
- Instruction *Inst = nullptr) const {
+ Type *Ty, TTI::TargetCostKind CostKind,
+ Instruction *Inst = nullptr) const {
return TTI::TCC_Free;
}
unsigned getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
const APInt &Imm, Type *Ty,
- TTI::TargetCostKind CostKind) const {
+ TTI::TargetCostKind CostKind) const {
return TTI::TCC_Free;
}
@@ -375,18 +375,18 @@ public:
unsigned getRegisterBitWidth(bool Vector) const { return 32; }
- unsigned getMinVectorRegisterBitWidth() const { return 128; }
+ unsigned getMinVectorRegisterBitWidth() const { return 128; }
+
+ Optional<unsigned> getMaxVScale() const { return None; }
- Optional<unsigned> getMaxVScale() const { return None; }
-
bool shouldMaximizeVectorBandwidth(bool OptSize) const { return false; }
unsigned getMinimumVF(unsigned ElemWidth) const { return 0; }
- unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) const { return 0; }
-
- bool shouldConsiderAddressTypePromotion(
- const Instruction &I, bool &AllowPromotionWithoutCommonHeader) const {
+ unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) const { return 0; }
+
+ bool shouldConsiderAddressTypePromotion(
+ const Instruction &I, bool &AllowPromotionWithoutCommonHeader) const {
AllowPromotionWithoutCommonHeader = false;
return false;
}
@@ -425,7 +425,7 @@ public:
unsigned getMaxPrefetchIterationsAhead() const { return UINT_MAX; }
bool enableWritePrefetching() const { return false; }
- unsigned getMaxInterleaveFactor(unsigned VF) const { return 1; }
+ unsigned getMaxInterleaveFactor(unsigned VF) const { return 1; }
unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty,
TTI::TargetCostKind CostKind,
@@ -434,7 +434,7 @@ public:
TTI::OperandValueProperties Opd1PropInfo,
TTI::OperandValueProperties Opd2PropInfo,
ArrayRef<const Value *> Args,
- const Instruction *CxtI = nullptr) const {
+ const Instruction *CxtI = nullptr) const {
// FIXME: A number of transformation tests seem to require these values
// which seems a little odd for how arbitary there are.
switch (Opcode) {
@@ -453,14 +453,14 @@ public:
}
unsigned getShuffleCost(TTI::ShuffleKind Kind, VectorType *Ty, int Index,
- VectorType *SubTp) const {
+ VectorType *SubTp) const {
return 1;
}
unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
- TTI::CastContextHint CCH,
+ TTI::CastContextHint CCH,
TTI::TargetCostKind CostKind,
- const Instruction *I) const {
+ const Instruction *I) const {
switch (Opcode) {
default:
break;
@@ -483,24 +483,24 @@ public:
// Identity and pointer-to-pointer casts are free.
return 0;
break;
- case Instruction::Trunc: {
+ case Instruction::Trunc: {
// trunc to a native type is free (assuming the target has compare and
// shift-right of the same width).
- TypeSize DstSize = DL.getTypeSizeInBits(Dst);
- if (!DstSize.isScalable() && DL.isLegalInteger(DstSize.getFixedSize()))
+ TypeSize DstSize = DL.getTypeSizeInBits(Dst);
+ if (!DstSize.isScalable() && DL.isLegalInteger(DstSize.getFixedSize()))
return 0;
break;
}
- }
+ }
return 1;
}
unsigned getExtractWithExtendCost(unsigned Opcode, Type *Dst,
- VectorType *VecTy, unsigned Index) const {
+ VectorType *VecTy, unsigned Index) const {
return 1;
}
- unsigned getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind) const {
+ unsigned getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind) const {
// A phi would be free, unless we're costing the throughput because it
// will require a register.
if (Opcode == Instruction::PHI && CostKind != TTI::TCK_RecipThroughput)
@@ -509,14 +509,14 @@ public:
}
unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
- CmpInst::Predicate VecPred,
+ CmpInst::Predicate VecPred,
TTI::TargetCostKind CostKind,
const Instruction *I) const {
return 1;
}
- unsigned getVectorInstrCost(unsigned Opcode, Type *Val,
- unsigned Index) const {
+ unsigned getVectorInstrCost(unsigned Opcode, Type *Val,
+ unsigned Index) const {
return 1;
}
@@ -528,33 +528,33 @@ public:
unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment,
unsigned AddressSpace,
- TTI::TargetCostKind CostKind) const {
+ TTI::TargetCostKind CostKind) const {
return 1;
}
unsigned getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
const Value *Ptr, bool VariableMask,
Align Alignment, TTI::TargetCostKind CostKind,
- const Instruction *I = nullptr) const {
+ const Instruction *I = nullptr) const {
return 1;
}
unsigned getInterleavedMemoryOpCost(
unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
- bool UseMaskForCond, bool UseMaskForGaps) const {
+ bool UseMaskForCond, bool UseMaskForGaps) const {
return 1;
}
unsigned getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
- TTI::TargetCostKind CostKind) const {
+ TTI::TargetCostKind CostKind) const {
switch (ICA.getID()) {
default:
break;
case Intrinsic::annotation:
case Intrinsic::assume:
case Intrinsic::sideeffect:
- case Intrinsic::pseudoprobe:
+ case Intrinsic::pseudoprobe:
case Intrinsic::dbg_declare:
case Intrinsic::dbg_value:
case Intrinsic::dbg_label:
@@ -565,7 +565,7 @@ public:
case Intrinsic::is_constant:
case Intrinsic::lifetime_start:
case Intrinsic::lifetime_end:
- case Intrinsic::experimental_noalias_scope_decl:
+ case Intrinsic::experimental_noalias_scope_decl:
case Intrinsic::objectsize:
case Intrinsic::ptr_annotation:
case Intrinsic::var_annotation:
@@ -587,38 +587,38 @@ public:
}
unsigned getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type *> Tys,
- TTI::TargetCostKind CostKind) const {
+ TTI::TargetCostKind CostKind) const {
return 1;
}
- unsigned getNumberOfParts(Type *Tp) const { return 0; }
+ unsigned getNumberOfParts(Type *Tp) const { return 0; }
unsigned getAddressComputationCost(Type *Tp, ScalarEvolution *,
- const SCEV *) const {
+ const SCEV *) const {
return 0;
}
unsigned getArithmeticReductionCost(unsigned, VectorType *, bool,
- TTI::TargetCostKind) const {
- return 1;
- }
+ TTI::TargetCostKind) const {
+ return 1;
+ }
unsigned getMinMaxReductionCost(VectorType *, VectorType *, bool, bool,
- TTI::TargetCostKind) const {
- return 1;
- }
-
- InstructionCost getExtendedAddReductionCost(
- bool IsMLA, bool IsUnsigned, Type *ResTy, VectorType *Ty,
- TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput) const {
- return 1;
- }
-
- unsigned getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) const {
- return 0;
- }
-
- bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info) const {
+ TTI::TargetCostKind) const {
+ return 1;
+ }
+
+ InstructionCost getExtendedAddReductionCost(
+ bool IsMLA, bool IsUnsigned, Type *ResTy, VectorType *Ty,
+ TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput) const {
+ return 1;
+ }
+
+ unsigned getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) const {
+ return 0;
+ }
+
+ bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info) const {
return false;
}
@@ -632,7 +632,7 @@ public:
}
Value *getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst,
- Type *ExpectedType) const {
+ Type *ExpectedType) const {
return nullptr;
}
@@ -710,34 +710,34 @@ public:
return false;
}
- bool preferInLoopReduction(unsigned Opcode, Type *Ty,
- TTI::ReductionFlags Flags) const {
- return false;
- }
-
- bool preferPredicatedReductionSelect(unsigned Opcode, Type *Ty,
- TTI::ReductionFlags Flags) const {
- return false;
- }
-
+ bool preferInLoopReduction(unsigned Opcode, Type *Ty,
+ TTI::ReductionFlags Flags) const {
+ return false;
+ }
+
+ bool preferPredicatedReductionSelect(unsigned Opcode, Type *Ty,
+ TTI::ReductionFlags Flags) const {
+ return false;
+ }
+
bool shouldExpandReduction(const IntrinsicInst *II) const { return true; }
unsigned getGISelRematGlobalCost() const { return 1; }
- bool supportsScalableVectors() const { return false; }
-
+ bool supportsScalableVectors() const { return false; }
+
bool hasActiveVectorLength() const { return false; }
protected:
// Obtain the minimum required size to hold the value (without the sign)
// In case of a vector it returns the min required size for one element.
- unsigned minRequiredElementSize(const Value *Val, bool &isSigned) const {
+ unsigned minRequiredElementSize(const Value *Val, bool &isSigned) const {
if (isa<ConstantDataVector>(Val) || isa<ConstantVector>(Val)) {
const auto *VectorValue = cast<Constant>(Val);
// In case of a vector need to pick the max between the min
// required size for each element
- auto *VT = cast<FixedVectorType>(Val->getType());
+ auto *VT = cast<FixedVectorType>(Val->getType());
// Assume unsigned elements
isSigned = false;
@@ -785,12 +785,12 @@ protected:
return Val->getType()->getScalarSizeInBits();
}
- bool isStridedAccess(const SCEV *Ptr) const {
+ bool isStridedAccess(const SCEV *Ptr) const {
return Ptr && isa<SCEVAddRecExpr>(Ptr);
}
const SCEVConstant *getConstantStrideStep(ScalarEvolution *SE,
- const SCEV *Ptr) const {
+ const SCEV *Ptr) const {
if (!isStridedAccess(Ptr))
return nullptr;
const SCEVAddRecExpr *AddRec = cast<SCEVAddRecExpr>(Ptr);
@@ -798,7 +798,7 @@ protected:
}
bool isConstantStridedAccessLessThan(ScalarEvolution *SE, const SCEV *Ptr,
- int64_t MergeDistance) const {
+ int64_t MergeDistance) const {
const SCEVConstant *Step = getConstantStrideStep(SE, Ptr);
if (!Step)
return false;
@@ -860,12 +860,12 @@ public:
uint64_t Field = ConstIdx->getZExtValue();
BaseOffset += DL.getStructLayout(STy)->getElementOffset(Field);
} else {
- // If this operand is a scalable type, bail out early.
- // TODO: handle scalable vectors
- if (isa<ScalableVectorType>(TargetType))
- return TTI::TCC_Basic;
- int64_t ElementSize =
- DL.getTypeAllocSize(GTI.getIndexedType()).getFixedSize();
+ // If this operand is a scalable type, bail out early.
+ // TODO: handle scalable vectors
+ if (isa<ScalableVectorType>(TargetType))
+ return TTI::TCC_Basic;
+ int64_t ElementSize =
+ DL.getTypeAllocSize(GTI.getIndexedType()).getFixedSize();
if (ConstIdx) {
BaseOffset +=
ConstIdx->getValue().sextOrTrunc(PtrSizeBits) * ElementSize;
@@ -890,17 +890,17 @@ public:
int getUserCost(const User *U, ArrayRef<const Value *> Operands,
TTI::TargetCostKind CostKind) {
auto *TargetTTI = static_cast<T *>(this);
- // Handle non-intrinsic calls, invokes, and callbr.
+ // Handle non-intrinsic calls, invokes, and callbr.
// FIXME: Unlikely to be true for anything but CodeSize.
- auto *CB = dyn_cast<CallBase>(U);
- if (CB && !isa<IntrinsicInst>(U)) {
- if (const Function *F = CB->getCalledFunction()) {
+ auto *CB = dyn_cast<CallBase>(U);
+ if (CB && !isa<IntrinsicInst>(U)) {
+ if (const Function *F = CB->getCalledFunction()) {
if (!TargetTTI->isLoweredToCall(F))
return TTI::TCC_Basic; // Give a basic cost if it will be lowered
- return TTI::TCC_Basic * (F->getFunctionType()->getNumParams() + 1);
+ return TTI::TCC_Basic * (F->getFunctionType()->getNumParams() + 1);
}
- // For indirect or other calls, scale cost by number of arguments.
+ // For indirect or other calls, scale cost by number of arguments.
return TTI::TCC_Basic * (CB->arg_size() + 1);
}
@@ -912,12 +912,12 @@ public:
switch (Opcode) {
default:
break;
- case Instruction::Call: {
- assert(isa<IntrinsicInst>(U) && "Unexpected non-intrinsic call");
- auto *Intrinsic = cast<IntrinsicInst>(U);
- IntrinsicCostAttributes CostAttrs(Intrinsic->getIntrinsicID(), *CB);
- return TargetTTI->getIntrinsicInstrCost(CostAttrs, CostKind);
- }
+ case Instruction::Call: {
+ assert(isa<IntrinsicInst>(U) && "Unexpected non-intrinsic call");
+ auto *Intrinsic = cast<IntrinsicInst>(U);
+ IntrinsicCostAttributes CostAttrs(Intrinsic->getIntrinsicID(), *CB);
+ return TargetTTI->getIntrinsicInstrCost(CostAttrs, CostKind);
+ }
case Instruction::Br:
case Instruction::Ret:
case Instruction::PHI:
@@ -978,8 +978,8 @@ public:
case Instruction::SExt:
case Instruction::ZExt:
case Instruction::AddrSpaceCast:
- return TargetTTI->getCastInstrCost(
- Opcode, Ty, OpTy, TTI::getCastContextHint(I), CostKind, I);
+ return TargetTTI->getCastInstrCost(
+ Opcode, Ty, OpTy, TTI::getCastContextHint(I), CostKind, I);
case Instruction::Store: {
auto *SI = cast<StoreInst>(U);
Type *ValTy = U->getOperand(0)->getType();
@@ -996,16 +996,16 @@ public:
case Instruction::Select: {
Type *CondTy = U->getOperand(0)->getType();
return TargetTTI->getCmpSelInstrCost(Opcode, U->getType(), CondTy,
- CmpInst::BAD_ICMP_PREDICATE,
+ CmpInst::BAD_ICMP_PREDICATE,
CostKind, I);
}
case Instruction::ICmp:
case Instruction::FCmp: {
Type *ValTy = U->getOperand(0)->getType();
- // TODO: Also handle ICmp/FCmp constant expressions.
+ // TODO: Also handle ICmp/FCmp constant expressions.
return TargetTTI->getCmpSelInstrCost(Opcode, ValTy, U->getType(),
- I ? cast<CmpInst>(I)->getPredicate()
- : CmpInst::BAD_ICMP_PREDICATE,
+ I ? cast<CmpInst>(I)->getPredicate()
+ : CmpInst::BAD_ICMP_PREDICATE,
CostKind, I);
}
case Instruction::InsertElement: {
@@ -1057,23 +1057,23 @@ public:
if (CI)
Idx = CI->getZExtValue();
- // Try to match a reduction (a series of shufflevector and vector ops
- // followed by an extractelement).
- unsigned RdxOpcode;
- VectorType *RdxType;
- bool IsPairwise;
- switch (TTI::matchVectorReduction(EEI, RdxOpcode, RdxType, IsPairwise)) {
+ // Try to match a reduction (a series of shufflevector and vector ops
+ // followed by an extractelement).
+ unsigned RdxOpcode;
+ VectorType *RdxType;
+ bool IsPairwise;
+ switch (TTI::matchVectorReduction(EEI, RdxOpcode, RdxType, IsPairwise)) {
case TTI::RK_Arithmetic:
- return TargetTTI->getArithmeticReductionCost(RdxOpcode, RdxType,
- IsPairwise, CostKind);
+ return TargetTTI->getArithmeticReductionCost(RdxOpcode, RdxType,
+ IsPairwise, CostKind);
case TTI::RK_MinMax:
return TargetTTI->getMinMaxReductionCost(
- RdxType, cast<VectorType>(CmpInst::makeCmpResultType(RdxType)),
- IsPairwise, /*IsUnsigned=*/false, CostKind);
+ RdxType, cast<VectorType>(CmpInst::makeCmpResultType(RdxType)),
+ IsPairwise, /*IsUnsigned=*/false, CostKind);
case TTI::RK_UnsignedMinMax:
return TargetTTI->getMinMaxReductionCost(
- RdxType, cast<VectorType>(CmpInst::makeCmpResultType(RdxType)),
- IsPairwise, /*IsUnsigned=*/true, CostKind);
+ RdxType, cast<VectorType>(CmpInst::makeCmpResultType(RdxType)),
+ IsPairwise, /*IsUnsigned=*/true, CostKind);
case TTI::RK_None:
break;
}
@@ -1086,7 +1086,7 @@ public:
}
int getInstructionLatency(const Instruction *I) {
- SmallVector<const Value *, 4> Operands(I->operand_values());
+ SmallVector<const Value *, 4> Operands(I->operand_values());
if (getUserCost(I, Operands, TTI::TCK_Latency) == TTI::TCC_Free)
return 0;
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h b/contrib/libs/llvm12/include/llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h
index bf20189de3..3fc8df0c75 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h
@@ -1,123 +1,123 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===-- ImportedFunctionsInliningStatistics.h -------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-// Generating inliner statistics for imported functions, mostly useful for
-// ThinLTO.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_IMPORTEDFUNCTIONSINLININGSTATISTICS_H
-#define LLVM_TRANSFORMS_UTILS_IMPORTEDFUNCTIONSINLININGSTATISTICS_H
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include <string>
-#include <vector>
-
-namespace llvm {
-class Module;
-class Function;
-/// Calculate and dump ThinLTO specific inliner stats.
-/// The main statistics are:
-/// (1) Number of inlined imported functions,
-/// (2) Number of imported functions inlined into importing module (indirect),
-/// (3) Number of non imported functions inlined into importing module
-/// (indirect).
-/// The difference between first and the second is that first stat counts
-/// all performed inlines on imported functions, but the second one only the
-/// functions that have been eventually inlined to a function in the importing
-/// module (by a chain of inlines). Because llvm uses bottom-up inliner, it is
-/// possible to e.g. import function `A`, `B` and then inline `B` to `A`,
-/// and after this `A` might be too big to be inlined into some other function
-/// that calls it. It calculates this statistic by building graph, where
-/// the nodes are functions, and edges are performed inlines and then by marking
-/// the edges starting from not imported function.
-///
-/// If `Verbose` is set to true, then it also dumps statistics
-/// per each inlined function, sorted by the greatest inlines count like
-/// - number of performed inlines
-/// - number of performed inlines to importing module
-class ImportedFunctionsInliningStatistics {
-private:
- /// InlineGraphNode represents node in graph of inlined functions.
- struct InlineGraphNode {
- // Default-constructible and movable.
- InlineGraphNode() = default;
- InlineGraphNode(InlineGraphNode &&) = default;
- InlineGraphNode &operator=(InlineGraphNode &&) = default;
-
- llvm::SmallVector<InlineGraphNode *, 8> InlinedCallees;
- /// Incremented every direct inline.
- int32_t NumberOfInlines = 0;
- /// Number of inlines into non imported function (possibly indirect via
- /// intermediate inlines). Computed based on graph search.
- int32_t NumberOfRealInlines = 0;
- bool Imported = false;
- bool Visited = false;
- };
-
-public:
- ImportedFunctionsInliningStatistics() = default;
- ImportedFunctionsInliningStatistics(
- const ImportedFunctionsInliningStatistics &) = delete;
-
- /// Set information like AllFunctions, ImportedFunctions, ModuleName.
- void setModuleInfo(const Module &M);
- /// Record inline of @param Callee to @param Caller for statistis.
- void recordInline(const Function &Caller, const Function &Callee);
- /// Dump stats computed with InlinerStatistics class.
- /// If @param Verbose is true then separate statistics for every inlined
- /// function will be printed.
- void dump(bool Verbose);
-
-private:
- /// Creates new Node in NodeMap and sets attributes, or returns existed one.
- InlineGraphNode &createInlineGraphNode(const Function &);
- void calculateRealInlines();
- void dfs(InlineGraphNode &GraphNode);
-
- using NodesMapTy =
- llvm::StringMap<std::unique_ptr<InlineGraphNode>>;
- using SortedNodesTy =
- std::vector<const NodesMapTy::MapEntryTy*>;
- /// Returns vector of elements sorted by
- /// (-NumberOfInlines, -NumberOfRealInlines, FunctionName).
- SortedNodesTy getSortedNodes();
-
-private:
- /// This map manage life of all InlineGraphNodes. Unique pointer to
- /// InlineGraphNode used since the node pointers are also saved in the
- /// InlinedCallees vector. If it would store InlineGraphNode instead then the
- /// address of the node would not be invariant.
- NodesMapTy NodesMap;
- /// Non external functions that have some other function inlined inside.
- std::vector<StringRef> NonImportedCallers;
- int AllFunctions = 0;
- int ImportedFunctions = 0;
- StringRef ModuleName;
-};
-
-enum class InlinerFunctionImportStatsOpts {
- No = 0,
- Basic = 1,
- Verbose = 2,
-};
-
-} // llvm
-
-#endif // LLVM_TRANSFORMS_UTILS_IMPORTEDFUNCTIONSINLININGSTATISTICS_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===-- ImportedFunctionsInliningStatistics.h -------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// Generating inliner statistics for imported functions, mostly useful for
+// ThinLTO.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_IMPORTEDFUNCTIONSINLININGSTATISTICS_H
+#define LLVM_TRANSFORMS_UTILS_IMPORTEDFUNCTIONSINLININGSTATISTICS_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <vector>
+
+namespace llvm {
+class Module;
+class Function;
+/// Calculate and dump ThinLTO specific inliner stats.
+/// The main statistics are:
+/// (1) Number of inlined imported functions,
+/// (2) Number of imported functions inlined into importing module (indirect),
+/// (3) Number of non imported functions inlined into importing module
+/// (indirect).
+/// The difference between first and the second is that first stat counts
+/// all performed inlines on imported functions, but the second one only the
+/// functions that have been eventually inlined to a function in the importing
+/// module (by a chain of inlines). Because llvm uses bottom-up inliner, it is
+/// possible to e.g. import function `A`, `B` and then inline `B` to `A`,
+/// and after this `A` might be too big to be inlined into some other function
+/// that calls it. It calculates this statistic by building graph, where
+/// the nodes are functions, and edges are performed inlines and then by marking
+/// the edges starting from not imported function.
+///
+/// If `Verbose` is set to true, then it also dumps statistics
+/// per each inlined function, sorted by the greatest inlines count like
+/// - number of performed inlines
+/// - number of performed inlines to importing module
+class ImportedFunctionsInliningStatistics {
+private:
+ /// InlineGraphNode represents node in graph of inlined functions.
+ struct InlineGraphNode {
+ // Default-constructible and movable.
+ InlineGraphNode() = default;
+ InlineGraphNode(InlineGraphNode &&) = default;
+ InlineGraphNode &operator=(InlineGraphNode &&) = default;
+
+ llvm::SmallVector<InlineGraphNode *, 8> InlinedCallees;
+ /// Incremented every direct inline.
+ int32_t NumberOfInlines = 0;
+ /// Number of inlines into non imported function (possibly indirect via
+ /// intermediate inlines). Computed based on graph search.
+ int32_t NumberOfRealInlines = 0;
+ bool Imported = false;
+ bool Visited = false;
+ };
+
+public:
+ ImportedFunctionsInliningStatistics() = default;
+ ImportedFunctionsInliningStatistics(
+ const ImportedFunctionsInliningStatistics &) = delete;
+
+ /// Set information like AllFunctions, ImportedFunctions, ModuleName.
+ void setModuleInfo(const Module &M);
+ /// Record inline of @param Callee to @param Caller for statistis.
+ void recordInline(const Function &Caller, const Function &Callee);
+ /// Dump stats computed with InlinerStatistics class.
+ /// If @param Verbose is true then separate statistics for every inlined
+ /// function will be printed.
+ void dump(bool Verbose);
+
+private:
+ /// Creates new Node in NodeMap and sets attributes, or returns existed one.
+ InlineGraphNode &createInlineGraphNode(const Function &);
+ void calculateRealInlines();
+ void dfs(InlineGraphNode &GraphNode);
+
+ using NodesMapTy =
+ llvm::StringMap<std::unique_ptr<InlineGraphNode>>;
+ using SortedNodesTy =
+ std::vector<const NodesMapTy::MapEntryTy*>;
+ /// Returns vector of elements sorted by
+ /// (-NumberOfInlines, -NumberOfRealInlines, FunctionName).
+ SortedNodesTy getSortedNodes();
+
+private:
+ /// This map manage life of all InlineGraphNodes. Unique pointer to
+ /// InlineGraphNode used since the node pointers are also saved in the
+ /// InlinedCallees vector. If it would store InlineGraphNode instead then the
+ /// address of the node would not be invariant.
+ NodesMapTy NodesMap;
+ /// Non external functions that have some other function inlined inside.
+ std::vector<StringRef> NonImportedCallers;
+ int AllFunctions = 0;
+ int ImportedFunctions = 0;
+ StringRef ModuleName;
+};
+
+enum class InlinerFunctionImportStatsOpts {
+ No = 0,
+ Basic = 1,
+ Verbose = 2,
+};
+
+} // llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_IMPORTEDFUNCTIONSINLININGSTATISTICS_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/Utils/Local.h b/contrib/libs/llvm12/include/llvm/Analysis/Utils/Local.h
index 32801f7c14..f6b4cf83b2 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/Utils/Local.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/Utils/Local.h
@@ -37,7 +37,7 @@ Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP,
bool NoAssumptions = false) {
GEPOperator *GEPOp = cast<GEPOperator>(GEP);
Type *IntIdxTy = DL.getIndexType(GEP->getType());
- Value *Result = nullptr;
+ Value *Result = nullptr;
// If the GEP is inbounds, we know that none of the addressing operations will
// overflow in a signed sense.
@@ -53,7 +53,7 @@ Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP,
++i, ++GTI) {
Value *Op = *i;
uint64_t Size = DL.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask;
- Value *Offset;
+ Value *Offset;
if (Constant *OpC = dyn_cast<Constant>(Op)) {
if (OpC->isZeroValue())
continue;
@@ -62,47 +62,47 @@ Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP,
if (StructType *STy = GTI.getStructTypeOrNull()) {
uint64_t OpValue = OpC->getUniqueInteger().getZExtValue();
Size = DL.getStructLayout(STy)->getElementOffset(OpValue);
- if (!Size)
- continue;
-
- Offset = ConstantInt::get(IntIdxTy, Size);
- } else {
- // Splat the constant if needed.
- if (IntIdxTy->isVectorTy() && !OpC->getType()->isVectorTy())
- OpC = ConstantVector::getSplat(
- cast<VectorType>(IntIdxTy)->getElementCount(), OpC);
-
- Constant *Scale = ConstantInt::get(IntIdxTy, Size);
- Constant *OC =
- ConstantExpr::getIntegerCast(OpC, IntIdxTy, true /*SExt*/);
- Offset =
- ConstantExpr::getMul(OC, Scale, false /*NUW*/, isInBounds /*NSW*/);
+ if (!Size)
+ continue;
+
+ Offset = ConstantInt::get(IntIdxTy, Size);
+ } else {
+ // Splat the constant if needed.
+ if (IntIdxTy->isVectorTy() && !OpC->getType()->isVectorTy())
+ OpC = ConstantVector::getSplat(
+ cast<VectorType>(IntIdxTy)->getElementCount(), OpC);
+
+ Constant *Scale = ConstantInt::get(IntIdxTy, Size);
+ Constant *OC =
+ ConstantExpr::getIntegerCast(OpC, IntIdxTy, true /*SExt*/);
+ Offset =
+ ConstantExpr::getMul(OC, Scale, false /*NUW*/, isInBounds /*NSW*/);
}
- } else {
- // Splat the index if needed.
- if (IntIdxTy->isVectorTy() && !Op->getType()->isVectorTy())
- Op = Builder->CreateVectorSplat(
- cast<FixedVectorType>(IntIdxTy)->getNumElements(), Op);
-
- // Convert to correct type.
- if (Op->getType() != IntIdxTy)
- Op = Builder->CreateIntCast(Op, IntIdxTy, true, Op->getName().str()+".c");
- if (Size != 1) {
- // We'll let instcombine(mul) convert this to a shl if possible.
- Op = Builder->CreateMul(Op, ConstantInt::get(IntIdxTy, Size),
- GEP->getName().str() + ".idx", false /*NUW*/,
- isInBounds /*NSW*/);
- }
- Offset = Op;
+ } else {
+ // Splat the index if needed.
+ if (IntIdxTy->isVectorTy() && !Op->getType()->isVectorTy())
+ Op = Builder->CreateVectorSplat(
+ cast<FixedVectorType>(IntIdxTy)->getNumElements(), Op);
+
+ // Convert to correct type.
+ if (Op->getType() != IntIdxTy)
+ Op = Builder->CreateIntCast(Op, IntIdxTy, true, Op->getName().str()+".c");
+ if (Size != 1) {
+ // We'll let instcombine(mul) convert this to a shl if possible.
+ Op = Builder->CreateMul(Op, ConstantInt::get(IntIdxTy, Size),
+ GEP->getName().str() + ".idx", false /*NUW*/,
+ isInBounds /*NSW*/);
+ }
+ Offset = Op;
}
- if (Result)
- Result = Builder->CreateAdd(Result, Offset, GEP->getName().str()+".offs",
- false /*NUW*/, isInBounds /*NSW*/);
- else
- Result = Offset;
+ if (Result)
+ Result = Builder->CreateAdd(Result, Offset, GEP->getName().str()+".offs",
+ false /*NUW*/, isInBounds /*NSW*/);
+ else
+ Result = Offset;
}
- return Result ? Result : Constant::getNullValue(IntIdxTy);
+ return Result ? Result : Constant::getNullValue(IntIdxTy);
}
}
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/Utils/TFUtils.h b/contrib/libs/llvm12/include/llvm/Analysis/Utils/TFUtils.h
index ce5f3088d7..2248ebf6da 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/Utils/TFUtils.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/Utils/TFUtils.h
@@ -16,11 +16,11 @@
#ifndef LLVM_ANALYSIS_UTILS_TFUTILS_H
#define LLVM_ANALYSIS_UTILS_TFUTILS_H
-#include "llvm/Config/llvm-config.h"
+#include "llvm/Config/llvm-config.h"
#ifdef LLVM_HAVE_TF_API
#include "llvm/IR/LLVMContext.h"
-#include "llvm/Support/JSON.h"
+#include "llvm/Support/JSON.h"
#include <memory>
#include <vector>
@@ -44,141 +44,141 @@ namespace llvm {
class TFModelEvaluatorImpl;
class EvaluationResultImpl;
-/// TensorSpec encapsulates the specification of a tensor: its dimensions, or
-/// "shape" (row-major), its type (see TensorSpec::getDataType specializations
-/// for supported types), its name and port (see "TensorFlow: Large-Scale
-/// Machine Learning on Heterogeneous Distributed Systems", section 4.2, para 2:
-/// https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/45166.pdf)
-///
-/// TensorSpec is used to set up a TFModelEvaluator by describing the expected
-/// inputs and outputs.
-class TensorSpec final {
-public:
- template <typename T>
- static TensorSpec createSpec(const std::string &Name,
- const std::vector<int64_t> &Shape,
- int Port = 0) {
- return TensorSpec(Name, Port, getDataType<T>(), Shape);
- }
-
- const std::string &name() const { return Name; }
- int port() const { return Port; }
- int typeIndex() const { return TypeIndex; }
- const std::vector<int64_t> &shape() const { return Shape; }
-
- bool operator==(const TensorSpec &Other) const {
- return Name == Other.Name && Port == Other.Port &&
- TypeIndex == Other.TypeIndex && Shape == Other.Shape;
- }
-
- bool operator!=(const TensorSpec &Other) const { return !(*this == Other); }
-
- /// Get the number of elements in a tensor with this shape.
- size_t getElementCount() const { return ElementCount; }
- /// Get the size, in bytes, of one element.
- size_t getElementByteSize() const;
-
- template <typename T> bool isElementType() const {
- return getDataType<T>() == TypeIndex;
- }
-
-private:
- TensorSpec(const std::string &Name, int Port, int TypeIndex,
- const std::vector<int64_t> &Shape);
-
- template <typename T> static int getDataType() {
- llvm_unreachable("Undefined tensor type");
- }
-
- std::string Name;
- int Port = 0;
- int TypeIndex = 0;
- std::vector<int64_t> Shape;
- size_t ElementCount = 0;
-};
-
-/// Construct a TensorSpec from a JSON dictionary of the form:
-/// { "name": <string>,
-/// "port": <int>,
-/// "type": <string. Use LLVM's types, e.g. float, double, int64_t>,
-/// "shape": <array of ints> }
-/// For the "type" field, see the C++ primitive types used in
-/// TFUTILS_SUPPORTED_TYPES.
-Optional<TensorSpec> getTensorSpecFromJSON(LLVMContext &Ctx,
- const json::Value &Value);
-
-struct LoggedFeatureSpec {
- TensorSpec Spec;
- Optional<std::string> LoggingName;
-};
-
-/// Load the output specs. If SpecFileOverride is not empty, that path is used.
-/// Otherwise, the file is assumed to be called 'output_spec.json' and be found
-/// under ModelPath (the model directory).
-/// The first output tensor name must match ExpectedDecisionName.
-/// In case of error, the return is None and the error is logged.
-Optional<std::vector<LoggedFeatureSpec>>
-loadOutputSpecs(LLVMContext &Ctx, StringRef ExpectedDecisionName,
- StringRef ModelPath, StringRef SpecFileOverride = StringRef());
-
-/// Logging utility - given an ordered specification of features, and assuming
-/// a scalar reward, allow logging feature values and rewards, and then print
-/// as tf.train.SequenceExample text protobuf.
-/// The assumption is that, for an event to be logged (i.e. a set of feature
-/// values and a reward), the user calls the log* API for each feature exactly
-/// once, providing the index matching the position in the feature spec list
-/// provided at construction:
-/// event 0:
-/// logTensorValue(0, ...)
-/// logTensorValue(1, ...)
-/// ...
-/// logReward(...)
-/// event 1:
-/// logTensorValue(0, ...)
-/// logTensorValue(1, ...)
-/// ...
-/// logReward(...)
-///
-/// At the end, call print to generate the protobuf.
-class Logger final {
-public:
- /// Construct a Logger. If IncludeReward is false, then logReward shouldn't
- /// be called, and the reward feature won't be printed out.
- Logger(const std::vector<LoggedFeatureSpec> &FeatureSpecs,
- const TensorSpec &RewardSpec, bool IncludeReward)
- : FeatureSpecs(FeatureSpecs), RewardSpec(RewardSpec),
- RawLogData(FeatureSpecs.size() + IncludeReward),
- IncludeReward(IncludeReward) {}
-
- template <typename T> void logReward(T Value) {
- assert(IncludeReward);
- logTensorValue(RawLogData.size() - 1, &Value);
- }
-
- template <typename T> void logFinalReward(T Value) {
- assert(RawLogData.back().empty());
- logReward(Value);
- }
-
- template <typename T>
- void logTensorValue(size_t FeatureID, const T *Value, size_t Size = 1) {
- const char *Start = reinterpret_cast<const char *>(Value);
- const char *End = Start + sizeof(T) * Size;
- RawLogData[FeatureID].insert(RawLogData[FeatureID].end(), Start, End);
- }
-
- void print(raw_ostream &OS);
-
-private:
- std::vector<LoggedFeatureSpec> FeatureSpecs;
- TensorSpec RewardSpec;
- /// RawData has one entry per feature, plus one more for the reward.
- /// Each feature's values are then stored in a vector, in succession.
- /// This means the ith event is stored at [*][i]
- std::vector<std::vector<char>> RawLogData;
- const bool IncludeReward;
-};
-
+/// TensorSpec encapsulates the specification of a tensor: its dimensions, or
+/// "shape" (row-major), its type (see TensorSpec::getDataType specializations
+/// for supported types), its name and port (see "TensorFlow: Large-Scale
+/// Machine Learning on Heterogeneous Distributed Systems", section 4.2, para 2:
+/// https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/45166.pdf)
+///
+/// TensorSpec is used to set up a TFModelEvaluator by describing the expected
+/// inputs and outputs.
+class TensorSpec final {
+public:
+ template <typename T>
+ static TensorSpec createSpec(const std::string &Name,
+ const std::vector<int64_t> &Shape,
+ int Port = 0) {
+ return TensorSpec(Name, Port, getDataType<T>(), Shape);
+ }
+
+ const std::string &name() const { return Name; }
+ int port() const { return Port; }
+ int typeIndex() const { return TypeIndex; }
+ const std::vector<int64_t> &shape() const { return Shape; }
+
+ bool operator==(const TensorSpec &Other) const {
+ return Name == Other.Name && Port == Other.Port &&
+ TypeIndex == Other.TypeIndex && Shape == Other.Shape;
+ }
+
+ bool operator!=(const TensorSpec &Other) const { return !(*this == Other); }
+
+ /// Get the number of elements in a tensor with this shape.
+ size_t getElementCount() const { return ElementCount; }
+ /// Get the size, in bytes, of one element.
+ size_t getElementByteSize() const;
+
+ template <typename T> bool isElementType() const {
+ return getDataType<T>() == TypeIndex;
+ }
+
+private:
+ TensorSpec(const std::string &Name, int Port, int TypeIndex,
+ const std::vector<int64_t> &Shape);
+
+ template <typename T> static int getDataType() {
+ llvm_unreachable("Undefined tensor type");
+ }
+
+ std::string Name;
+ int Port = 0;
+ int TypeIndex = 0;
+ std::vector<int64_t> Shape;
+ size_t ElementCount = 0;
+};
+
+/// Construct a TensorSpec from a JSON dictionary of the form:
+/// { "name": <string>,
+/// "port": <int>,
+/// "type": <string. Use LLVM's types, e.g. float, double, int64_t>,
+/// "shape": <array of ints> }
+/// For the "type" field, see the C++ primitive types used in
+/// TFUTILS_SUPPORTED_TYPES.
+Optional<TensorSpec> getTensorSpecFromJSON(LLVMContext &Ctx,
+ const json::Value &Value);
+
+struct LoggedFeatureSpec {
+ TensorSpec Spec;
+ Optional<std::string> LoggingName;
+};
+
+/// Load the output specs. If SpecFileOverride is not empty, that path is used.
+/// Otherwise, the file is assumed to be called 'output_spec.json' and be found
+/// under ModelPath (the model directory).
+/// The first output tensor name must match ExpectedDecisionName.
+/// In case of error, the return is None and the error is logged.
+Optional<std::vector<LoggedFeatureSpec>>
+loadOutputSpecs(LLVMContext &Ctx, StringRef ExpectedDecisionName,
+ StringRef ModelPath, StringRef SpecFileOverride = StringRef());
+
+/// Logging utility - given an ordered specification of features, and assuming
+/// a scalar reward, allow logging feature values and rewards, and then print
+/// as tf.train.SequenceExample text protobuf.
+/// The assumption is that, for an event to be logged (i.e. a set of feature
+/// values and a reward), the user calls the log* API for each feature exactly
+/// once, providing the index matching the position in the feature spec list
+/// provided at construction:
+/// event 0:
+/// logTensorValue(0, ...)
+/// logTensorValue(1, ...)
+/// ...
+/// logReward(...)
+/// event 1:
+/// logTensorValue(0, ...)
+/// logTensorValue(1, ...)
+/// ...
+/// logReward(...)
+///
+/// At the end, call print to generate the protobuf.
+class Logger final {
+public:
+ /// Construct a Logger. If IncludeReward is false, then logReward shouldn't
+ /// be called, and the reward feature won't be printed out.
+ Logger(const std::vector<LoggedFeatureSpec> &FeatureSpecs,
+ const TensorSpec &RewardSpec, bool IncludeReward)
+ : FeatureSpecs(FeatureSpecs), RewardSpec(RewardSpec),
+ RawLogData(FeatureSpecs.size() + IncludeReward),
+ IncludeReward(IncludeReward) {}
+
+ template <typename T> void logReward(T Value) {
+ assert(IncludeReward);
+ logTensorValue(RawLogData.size() - 1, &Value);
+ }
+
+ template <typename T> void logFinalReward(T Value) {
+ assert(RawLogData.back().empty());
+ logReward(Value);
+ }
+
+ template <typename T>
+ void logTensorValue(size_t FeatureID, const T *Value, size_t Size = 1) {
+ const char *Start = reinterpret_cast<const char *>(Value);
+ const char *End = Start + sizeof(T) * Size;
+ RawLogData[FeatureID].insert(RawLogData[FeatureID].end(), Start, End);
+ }
+
+ void print(raw_ostream &OS);
+
+private:
+ std::vector<LoggedFeatureSpec> FeatureSpecs;
+ TensorSpec RewardSpec;
+ /// RawData has one entry per feature, plus one more for the reward.
+ /// Each feature's values are then stored in a vector, in succession.
+ /// This means the ith event is stored at [*][i]
+ std::vector<std::vector<char>> RawLogData;
+ const bool IncludeReward;
+};
+
class TFModelEvaluator final {
public:
/// The result of a model evaluation. Handles the lifetime of the output
@@ -187,26 +187,26 @@ public:
class EvaluationResult {
public:
EvaluationResult(const EvaluationResult &) = delete;
- EvaluationResult &operator=(const EvaluationResult &Other) = delete;
-
+ EvaluationResult &operator=(const EvaluationResult &Other) = delete;
+
EvaluationResult(EvaluationResult &&Other);
- EvaluationResult &operator=(EvaluationResult &&Other);
-
+ EvaluationResult &operator=(EvaluationResult &&Other);
+
~EvaluationResult();
- /// Get a (const) pointer to the first element of the tensor at Index.
+ /// Get a (const) pointer to the first element of the tensor at Index.
template <typename T> T *getTensorValue(size_t Index) {
return static_cast<T *>(getUntypedTensorValue(Index));
}
- template <typename T> const T *getTensorValue(size_t Index) const {
- return static_cast<T *>(getUntypedTensorValue(Index));
- }
-
- /// Get a (const) pointer to the untyped data of the tensor.
- void *getUntypedTensorValue(size_t Index);
- const void *getUntypedTensorValue(size_t Index) const;
-
+ template <typename T> const T *getTensorValue(size_t Index) const {
+ return static_cast<T *>(getUntypedTensorValue(Index));
+ }
+
+ /// Get a (const) pointer to the untyped data of the tensor.
+ void *getUntypedTensorValue(size_t Index);
+ const void *getUntypedTensorValue(size_t Index) const;
+
private:
friend class TFModelEvaluator;
EvaluationResult(std::unique_ptr<EvaluationResultImpl> Impl);
@@ -214,14 +214,14 @@ public:
};
TFModelEvaluator(StringRef SavedModelPath,
- const std::vector<TensorSpec> &InputSpecs,
- const std::vector<TensorSpec> &OutputSpecs,
+ const std::vector<TensorSpec> &InputSpecs,
+ const std::vector<TensorSpec> &OutputSpecs,
const char *Tags = "serve");
- TFModelEvaluator(StringRef SavedModelPath,
- const std::vector<TensorSpec> &InputSpecs,
- function_ref<TensorSpec(size_t)> GetOutputSpecs,
- size_t OutputSpecsSize, const char *Tags = "serve");
-
+ TFModelEvaluator(StringRef SavedModelPath,
+ const std::vector<TensorSpec> &InputSpecs,
+ function_ref<TensorSpec(size_t)> GetOutputSpecs,
+ size_t OutputSpecsSize, const char *Tags = "serve");
+
~TFModelEvaluator();
TFModelEvaluator(const TFModelEvaluator &) = delete;
TFModelEvaluator(TFModelEvaluator &&) = delete;
@@ -246,27 +246,27 @@ private:
std::unique_ptr<TFModelEvaluatorImpl> Impl;
};
-/// List of supported types, as a pair:
-/// - C++ type
-/// - enum name (implementation-specific)
-#define TFUTILS_SUPPORTED_TYPES(M) \
- M(float, TF_FLOAT) \
- M(double, TF_DOUBLE) \
- M(int8_t, TF_INT8) \
- M(uint8_t, TF_UINT8) \
- M(int16_t, TF_INT16) \
- M(uint16_t, TF_UINT16) \
- M(int32_t, TF_INT32) \
- M(uint32_t, TF_UINT32) \
- M(int64_t, TF_INT64) \
- M(uint64_t, TF_UINT64)
-
-#define TFUTILS_GETDATATYPE_DEF(T, E) \
- template <> int TensorSpec::getDataType<T>();
-
-TFUTILS_SUPPORTED_TYPES(TFUTILS_GETDATATYPE_DEF)
-
-#undef TFUTILS_GETDATATYPE_DEF
+/// List of supported types, as a pair:
+/// - C++ type
+/// - enum name (implementation-specific)
+#define TFUTILS_SUPPORTED_TYPES(M) \
+ M(float, TF_FLOAT) \
+ M(double, TF_DOUBLE) \
+ M(int8_t, TF_INT8) \
+ M(uint8_t, TF_UINT8) \
+ M(int16_t, TF_INT16) \
+ M(uint16_t, TF_UINT16) \
+ M(int32_t, TF_INT32) \
+ M(uint32_t, TF_UINT32) \
+ M(int64_t, TF_INT64) \
+ M(uint64_t, TF_UINT64)
+
+#define TFUTILS_GETDATATYPE_DEF(T, E) \
+ template <> int TensorSpec::getDataType<T>();
+
+TFUTILS_SUPPORTED_TYPES(TFUTILS_GETDATATYPE_DEF)
+
+#undef TFUTILS_GETDATATYPE_DEF
} // namespace llvm
#endif // LLVM_HAVE_TF_API
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/ValueLattice.h b/contrib/libs/llvm12/include/llvm/Analysis/ValueLattice.h
index fdb1edde7f..6b9e7e3650 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/ValueLattice.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/ValueLattice.h
@@ -18,7 +18,7 @@
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
-#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Instructions.h"
//
//===----------------------------------------------------------------------===//
// ValueLatticeElement
@@ -464,16 +464,16 @@ public:
if (isConstant() && Other.isConstant())
return ConstantExpr::getCompare(Pred, getConstant(), Other.getConstant());
- if (ICmpInst::isEquality(Pred)) {
- // not(C) != C => true, not(C) == C => false.
- if ((isNotConstant() && Other.isConstant() &&
- getNotConstant() == Other.getConstant()) ||
- (isConstant() && Other.isNotConstant() &&
- getConstant() == Other.getNotConstant()))
- return Pred == ICmpInst::ICMP_NE
- ? ConstantInt::getTrue(Ty) : ConstantInt::getFalse(Ty);
- }
-
+ if (ICmpInst::isEquality(Pred)) {
+ // not(C) != C => true, not(C) == C => false.
+ if ((isNotConstant() && Other.isConstant() &&
+ getNotConstant() == Other.getConstant()) ||
+ (isConstant() && Other.isNotConstant() &&
+ getConstant() == Other.getNotConstant()))
+ return Pred == ICmpInst::ICMP_NE
+ ? ConstantInt::getTrue(Ty) : ConstantInt::getFalse(Ty);
+ }
+
// Integer constants are represented as ConstantRanges with single
// elements.
if (!isConstantRange() || !Other.isConstantRange())
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/ValueTracking.h b/contrib/libs/llvm12/include/llvm/Analysis/ValueTracking.h
index 65c4f66864..ccc0b62f08 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/ValueTracking.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/ValueTracking.h
@@ -28,14 +28,14 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Intrinsics.h"
-#include "llvm/IR/Operator.h"
+#include "llvm/IR/Operator.h"
#include <cassert>
#include <cstdint>
namespace llvm {
class AddOperator;
-class AllocaInst;
+class AllocaInst;
class APInt;
class AssumptionCache;
class DominatorTree;
@@ -52,8 +52,8 @@ class StringRef;
class TargetLibraryInfo;
class Value;
-constexpr unsigned MaxAnalysisRecursionDepth = 6;
-
+constexpr unsigned MaxAnalysisRecursionDepth = 6;
+
/// Determine which bits of V are known to be either zero or one and return
/// them in the KnownZero/KnownOne bit sets.
///
@@ -377,13 +377,13 @@ constexpr unsigned MaxAnalysisRecursionDepth = 6;
/// that the returned value has pointer type if the specified value does. If
/// the MaxLookup value is non-zero, it limits the number of instructions to
/// be stripped off.
- Value *getUnderlyingObject(Value *V, unsigned MaxLookup = 6);
- inline const Value *getUnderlyingObject(const Value *V,
+ Value *getUnderlyingObject(Value *V, unsigned MaxLookup = 6);
+ inline const Value *getUnderlyingObject(const Value *V,
unsigned MaxLookup = 6) {
- return getUnderlyingObject(const_cast<Value *>(V), MaxLookup);
+ return getUnderlyingObject(const_cast<Value *>(V), MaxLookup);
}
- /// 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
@@ -411,30 +411,30 @@ constexpr unsigned MaxAnalysisRecursionDepth = 6;
/// Since A[i] and A[i-1] are independent pointers, getUnderlyingObjects
/// should not assume that Curr and Prev share the same underlying object thus
/// it shouldn't look through the phi above.
- void getUnderlyingObjects(const Value *V,
+ void getUnderlyingObjects(const Value *V,
SmallVectorImpl<const Value *> &Objects,
- LoopInfo *LI = nullptr, unsigned MaxLookup = 6);
+ LoopInfo *LI = nullptr, unsigned MaxLookup = 6);
- /// This is a wrapper around getUnderlyingObjects and adds support for basic
+ /// This is a wrapper around getUnderlyingObjects and adds support for basic
/// ptrtoint+arithmetic+inttoptr sequences.
bool getUnderlyingObjectsForCodeGen(const Value *V,
- SmallVectorImpl<Value *> &Objects);
-
- /// Returns unique alloca where the value comes from, or nullptr.
- /// If OffsetZero is true check that V points to the begining of the alloca.
- AllocaInst *findAllocaForValue(Value *V, bool OffsetZero = false);
- inline const AllocaInst *findAllocaForValue(const Value *V,
- bool OffsetZero = false) {
- return findAllocaForValue(const_cast<Value *>(V), OffsetZero);
- }
-
+ SmallVectorImpl<Value *> &Objects);
+
+ /// Returns unique alloca where the value comes from, or nullptr.
+ /// If OffsetZero is true check that V points to the begining of the alloca.
+ AllocaInst *findAllocaForValue(Value *V, bool OffsetZero = false);
+ inline const AllocaInst *findAllocaForValue(const Value *V,
+ bool OffsetZero = false) {
+ return findAllocaForValue(const_cast<Value *>(V), OffsetZero);
+ }
+
/// Return true if the only users of this pointer are lifetime markers.
bool onlyUsedByLifetimeMarkers(const Value *V);
- /// Return true if the only users of this pointer are lifetime markers or
- /// droppable instructions.
- bool onlyUsedByLifetimeMarkersOrDroppableInsts(const Value *V);
-
+ /// Return true if the only users of this pointer are lifetime markers or
+ /// droppable instructions.
+ bool onlyUsedByLifetimeMarkersOrDroppableInsts(const Value *V);
+
/// Return true if speculation of the given load must be suppressed to avoid
/// ordering or interfering with an active sanitizer. If not suppressed,
/// dereferenceability and alignment must be proven separately. Note: This
@@ -591,65 +591,65 @@ constexpr unsigned MaxAnalysisRecursionDepth = 6;
/// if, for all i, r is evaluated to poison or op raises UB if vi = poison.
/// To filter out operands that raise UB on poison, you can use
/// getGuaranteedNonPoisonOp.
- bool propagatesPoison(const Operator *I);
+ bool propagatesPoison(const Operator *I);
- /// Insert operands of I into Ops such that I will trigger undefined behavior
- /// if I is executed and that operand has a poison value.
- void getGuaranteedNonPoisonOps(const Instruction *I,
- SmallPtrSetImpl<const Value *> &Ops);
+ /// Insert operands of I into Ops such that I will trigger undefined behavior
+ /// if I is executed and that operand has a poison value.
+ void getGuaranteedNonPoisonOps(const Instruction *I,
+ SmallPtrSetImpl<const Value *> &Ops);
- /// Return true if the given instruction must trigger undefined behavior
+ /// Return true if the given instruction must trigger undefined behavior
/// when I is executed with any operands which appear in KnownPoison holding
/// a poison value at the point of execution.
bool mustTriggerUB(const Instruction *I,
const SmallSet<const Value *, 16>& KnownPoison);
- /// Return true if this function can prove that if Inst is executed
- /// and yields a poison value or undef bits, then that will trigger
- /// undefined behavior.
+ /// Return true if this function can prove that if Inst is executed
+ /// and yields a poison value or undef bits, then that will trigger
+ /// undefined behavior.
///
/// Note that this currently only considers the basic block that is
- /// the parent of Inst.
- bool programUndefinedIfUndefOrPoison(const Instruction *Inst);
- bool programUndefinedIfPoison(const Instruction *Inst);
-
- /// canCreateUndefOrPoison returns true if Op can create undef or poison from
- /// non-undef & non-poison operands.
- /// For vectors, canCreateUndefOrPoison returns true if there is potential
- /// poison or undef in any element of the result when vectors without
- /// undef/poison poison are given as operands.
- /// For example, given `Op = shl <2 x i32> %x, <0, 32>`, this function returns
- /// true. If Op raises immediate UB but never creates poison or undef
- /// (e.g. sdiv I, 0), canCreatePoison returns false.
- ///
- /// canCreatePoison returns true if Op can create poison from non-poison
+ /// the parent of Inst.
+ bool programUndefinedIfUndefOrPoison(const Instruction *Inst);
+ bool programUndefinedIfPoison(const Instruction *Inst);
+
+ /// canCreateUndefOrPoison returns true if Op can create undef or poison from
+ /// non-undef & non-poison operands.
+ /// For vectors, canCreateUndefOrPoison returns true if there is potential
+ /// poison or undef in any element of the result when vectors without
+ /// undef/poison poison are given as operands.
+ /// For example, given `Op = shl <2 x i32> %x, <0, 32>`, this function returns
+ /// true. If Op raises immediate UB but never creates poison or undef
+ /// (e.g. sdiv I, 0), canCreatePoison returns false.
+ ///
+ /// canCreatePoison returns true if Op can create poison from non-poison
/// operands.
- bool canCreateUndefOrPoison(const Operator *Op);
- bool canCreatePoison(const Operator *Op);
-
- /// Return true if V is poison given that ValAssumedPoison is already poison.
- /// For example, if ValAssumedPoison is `icmp X, 10` and V is `icmp X, 5`,
- /// impliesPoison returns true.
- bool impliesPoison(const Value *ValAssumedPoison, const Value *V);
-
- /// Return true if this function can prove that V does not have undef bits
- /// and is never poison. If V is an aggregate value or vector, check whether
- /// all elements (except padding) are not undef or poison.
- /// Note that this is different from canCreateUndefOrPoison because the
- /// function assumes Op's operands are not poison/undef.
- ///
+ bool canCreateUndefOrPoison(const Operator *Op);
+ bool canCreatePoison(const Operator *Op);
+
+ /// Return true if V is poison given that ValAssumedPoison is already poison.
+ /// For example, if ValAssumedPoison is `icmp X, 10` and V is `icmp X, 5`,
+ /// impliesPoison returns true.
+ bool impliesPoison(const Value *ValAssumedPoison, const Value *V);
+
+ /// Return true if this function can prove that V does not have undef bits
+ /// and is never poison. If V is an aggregate value or vector, check whether
+ /// all elements (except padding) are not undef or poison.
+ /// Note that this is different from canCreateUndefOrPoison because the
+ /// function assumes Op's operands are not poison/undef.
+ ///
/// If CtxI and DT are specified this method performs flow-sensitive analysis
/// and returns true if it is guaranteed to be never undef or poison
/// immediately before the CtxI.
bool isGuaranteedNotToBeUndefOrPoison(const Value *V,
- AssumptionCache *AC = nullptr,
+ AssumptionCache *AC = nullptr,
const Instruction *CtxI = nullptr,
const DominatorTree *DT = nullptr,
unsigned Depth = 0);
- bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC = nullptr,
- const Instruction *CtxI = nullptr,
- const DominatorTree *DT = nullptr,
- unsigned Depth = 0);
+ bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC = nullptr,
+ const Instruction *CtxI = nullptr,
+ const DominatorTree *DT = nullptr,
+ unsigned Depth = 0);
/// Specific patterns of select instructions we can match.
enum SelectPatternFlavor {
@@ -740,14 +740,14 @@ constexpr unsigned MaxAnalysisRecursionDepth = 6;
/// minimum/maximum flavor.
CmpInst::Predicate getInverseMinMaxPred(SelectPatternFlavor SPF);
- /// Check if the values in \p VL are select instructions that can be converted
- /// to a min or max (vector) intrinsic. Returns the intrinsic ID, if such a
- /// conversion is possible, together with a bool indicating whether all select
- /// conditions are only used by the selects. Otherwise return
- /// Intrinsic::not_intrinsic.
- std::pair<Intrinsic::ID, bool>
- canConvertToMinOrMaxIntrinsic(ArrayRef<Value *> VL);
-
+ /// Check if the values in \p VL are select instructions that can be converted
+ /// to a min or max (vector) intrinsic. Returns the intrinsic ID, if such a
+ /// conversion is possible, together with a bool indicating whether all select
+ /// conditions are only used by the selects. Otherwise return
+ /// Intrinsic::not_intrinsic.
+ std::pair<Intrinsic::ID, bool>
+ canConvertToMinOrMaxIntrinsic(ArrayRef<Value *> VL);
+
/// Return true if RHS is known to be implied true by LHS. Return false if
/// RHS is known to be implied false by LHS. Otherwise, return None if no
/// implication can be made.
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/VecFuncs.def b/contrib/libs/llvm12/include/llvm/Analysis/VecFuncs.def
index 01dc54f3a0..cfc3d61158 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/VecFuncs.def
+++ b/contrib/libs/llvm12/include/llvm/Analysis/VecFuncs.def
@@ -62,87 +62,87 @@ TLI_DEFINE_VECFUNC("acoshf", "vacoshf", 4)
TLI_DEFINE_VECFUNC("atanhf", "vatanhf", 4)
-#elif defined(TLI_DEFINE_LIBMVEC_X86_VECFUNCS)
-// GLIBC Vector math Functions
-
-TLI_DEFINE_VECFUNC("sin", "_ZGVbN2v_sin", 2)
-TLI_DEFINE_VECFUNC("sin", "_ZGVdN4v_sin", 4)
-
-TLI_DEFINE_VECFUNC("sinf", "_ZGVbN4v_sinf", 4)
-TLI_DEFINE_VECFUNC("sinf", "_ZGVdN8v_sinf", 8)
-
-TLI_DEFINE_VECFUNC("llvm.sin.f64", "_ZGVbN2v_sin", 2)
-TLI_DEFINE_VECFUNC("llvm.sin.f64", "_ZGVdN4v_sin", 4)
-
-TLI_DEFINE_VECFUNC("llvm.sin.f32", "_ZGVbN4v_sinf", 4)
-TLI_DEFINE_VECFUNC("llvm.sin.f32", "_ZGVdN8v_sinf", 8)
-
-TLI_DEFINE_VECFUNC("cos", "_ZGVbN2v_cos", 2)
-TLI_DEFINE_VECFUNC("cos", "_ZGVdN4v_cos", 4)
-
-TLI_DEFINE_VECFUNC("cosf", "_ZGVbN4v_cosf", 4)
-TLI_DEFINE_VECFUNC("cosf", "_ZGVdN8v_cosf", 8)
-
-TLI_DEFINE_VECFUNC("llvm.cos.f64", "_ZGVbN2v_cos", 2)
-TLI_DEFINE_VECFUNC("llvm.cos.f64", "_ZGVdN4v_cos", 4)
-
-TLI_DEFINE_VECFUNC("llvm.cos.f32", "_ZGVbN4v_cosf", 4)
-TLI_DEFINE_VECFUNC("llvm.cos.f32", "_ZGVdN8v_cosf", 8)
-
-TLI_DEFINE_VECFUNC("pow", "_ZGVbN2vv_pow", 2)
-TLI_DEFINE_VECFUNC("pow", "_ZGVdN4vv_pow", 4)
-
-TLI_DEFINE_VECFUNC("powf", "_ZGVbN4vv_powf", 4)
-TLI_DEFINE_VECFUNC("powf", "_ZGVdN8vv_powf", 8)
-
-TLI_DEFINE_VECFUNC("__pow_finite", "_ZGVbN2vv___pow_finite", 2)
-TLI_DEFINE_VECFUNC("__pow_finite", "_ZGVdN4vv___pow_finite", 4)
-
-TLI_DEFINE_VECFUNC("__powf_finite", "_ZGVbN4vv___powf_finite", 4)
-TLI_DEFINE_VECFUNC("__powf_finite", "_ZGVdN8vv___powf_finite", 8)
-
-TLI_DEFINE_VECFUNC("llvm.pow.f64", "_ZGVbN2vv_pow", 2)
-TLI_DEFINE_VECFUNC("llvm.pow.f64", "_ZGVdN4vv_pow", 4)
-
-TLI_DEFINE_VECFUNC("llvm.pow.f32", "_ZGVbN4vv_powf", 4)
-TLI_DEFINE_VECFUNC("llvm.pow.f32", "_ZGVdN8vv_powf", 8)
-
-TLI_DEFINE_VECFUNC("exp", "_ZGVbN2v_exp", 2)
-TLI_DEFINE_VECFUNC("exp", "_ZGVdN4v_exp", 4)
-
-TLI_DEFINE_VECFUNC("expf", "_ZGVbN4v_expf", 4)
-TLI_DEFINE_VECFUNC("expf", "_ZGVdN8v_expf", 8)
-
-TLI_DEFINE_VECFUNC("__exp_finite", "_ZGVbN2v___exp_finite", 2)
-TLI_DEFINE_VECFUNC("__exp_finite", "_ZGVdN4v___exp_finite", 4)
-
-TLI_DEFINE_VECFUNC("__expf_finite", "_ZGVbN4v___expf_finite", 4)
-TLI_DEFINE_VECFUNC("__expf_finite", "_ZGVdN8v___expf_finite", 8)
-
-TLI_DEFINE_VECFUNC("llvm.exp.f64", "_ZGVbN2v_exp", 2)
-TLI_DEFINE_VECFUNC("llvm.exp.f64", "_ZGVdN4v_exp", 4)
-
-TLI_DEFINE_VECFUNC("llvm.exp.f32", "_ZGVbN4v_expf", 4)
-TLI_DEFINE_VECFUNC("llvm.exp.f32", "_ZGVdN8v_expf", 8)
-
-TLI_DEFINE_VECFUNC("log", "_ZGVbN2v_log", 2)
-TLI_DEFINE_VECFUNC("log", "_ZGVdN4v_log", 4)
-
-TLI_DEFINE_VECFUNC("logf", "_ZGVbN4v_logf", 4)
-TLI_DEFINE_VECFUNC("logf", "_ZGVdN8v_logf", 8)
-
-TLI_DEFINE_VECFUNC("__log_finite", "_ZGVbN2v___log_finite", 2)
-TLI_DEFINE_VECFUNC("__log_finite", "_ZGVdN4v___log_finite", 4)
-
-TLI_DEFINE_VECFUNC("__logf_finite", "_ZGVbN4v___logf_finite", 4)
-TLI_DEFINE_VECFUNC("__logf_finite", "_ZGVdN8v___logf_finite", 8)
-
-TLI_DEFINE_VECFUNC("llvm.log.f64", "_ZGVbN2v_log", 2)
-TLI_DEFINE_VECFUNC("llvm.log.f64", "_ZGVdN4v_log", 4)
-
-TLI_DEFINE_VECFUNC("llvm.log.f32", "_ZGVbN4v_logf", 4)
-TLI_DEFINE_VECFUNC("llvm.log.f32", "_ZGVdN8v_logf", 8)
-
+#elif defined(TLI_DEFINE_LIBMVEC_X86_VECFUNCS)
+// GLIBC Vector math Functions
+
+TLI_DEFINE_VECFUNC("sin", "_ZGVbN2v_sin", 2)
+TLI_DEFINE_VECFUNC("sin", "_ZGVdN4v_sin", 4)
+
+TLI_DEFINE_VECFUNC("sinf", "_ZGVbN4v_sinf", 4)
+TLI_DEFINE_VECFUNC("sinf", "_ZGVdN8v_sinf", 8)
+
+TLI_DEFINE_VECFUNC("llvm.sin.f64", "_ZGVbN2v_sin", 2)
+TLI_DEFINE_VECFUNC("llvm.sin.f64", "_ZGVdN4v_sin", 4)
+
+TLI_DEFINE_VECFUNC("llvm.sin.f32", "_ZGVbN4v_sinf", 4)
+TLI_DEFINE_VECFUNC("llvm.sin.f32", "_ZGVdN8v_sinf", 8)
+
+TLI_DEFINE_VECFUNC("cos", "_ZGVbN2v_cos", 2)
+TLI_DEFINE_VECFUNC("cos", "_ZGVdN4v_cos", 4)
+
+TLI_DEFINE_VECFUNC("cosf", "_ZGVbN4v_cosf", 4)
+TLI_DEFINE_VECFUNC("cosf", "_ZGVdN8v_cosf", 8)
+
+TLI_DEFINE_VECFUNC("llvm.cos.f64", "_ZGVbN2v_cos", 2)
+TLI_DEFINE_VECFUNC("llvm.cos.f64", "_ZGVdN4v_cos", 4)
+
+TLI_DEFINE_VECFUNC("llvm.cos.f32", "_ZGVbN4v_cosf", 4)
+TLI_DEFINE_VECFUNC("llvm.cos.f32", "_ZGVdN8v_cosf", 8)
+
+TLI_DEFINE_VECFUNC("pow", "_ZGVbN2vv_pow", 2)
+TLI_DEFINE_VECFUNC("pow", "_ZGVdN4vv_pow", 4)
+
+TLI_DEFINE_VECFUNC("powf", "_ZGVbN4vv_powf", 4)
+TLI_DEFINE_VECFUNC("powf", "_ZGVdN8vv_powf", 8)
+
+TLI_DEFINE_VECFUNC("__pow_finite", "_ZGVbN2vv___pow_finite", 2)
+TLI_DEFINE_VECFUNC("__pow_finite", "_ZGVdN4vv___pow_finite", 4)
+
+TLI_DEFINE_VECFUNC("__powf_finite", "_ZGVbN4vv___powf_finite", 4)
+TLI_DEFINE_VECFUNC("__powf_finite", "_ZGVdN8vv___powf_finite", 8)
+
+TLI_DEFINE_VECFUNC("llvm.pow.f64", "_ZGVbN2vv_pow", 2)
+TLI_DEFINE_VECFUNC("llvm.pow.f64", "_ZGVdN4vv_pow", 4)
+
+TLI_DEFINE_VECFUNC("llvm.pow.f32", "_ZGVbN4vv_powf", 4)
+TLI_DEFINE_VECFUNC("llvm.pow.f32", "_ZGVdN8vv_powf", 8)
+
+TLI_DEFINE_VECFUNC("exp", "_ZGVbN2v_exp", 2)
+TLI_DEFINE_VECFUNC("exp", "_ZGVdN4v_exp", 4)
+
+TLI_DEFINE_VECFUNC("expf", "_ZGVbN4v_expf", 4)
+TLI_DEFINE_VECFUNC("expf", "_ZGVdN8v_expf", 8)
+
+TLI_DEFINE_VECFUNC("__exp_finite", "_ZGVbN2v___exp_finite", 2)
+TLI_DEFINE_VECFUNC("__exp_finite", "_ZGVdN4v___exp_finite", 4)
+
+TLI_DEFINE_VECFUNC("__expf_finite", "_ZGVbN4v___expf_finite", 4)
+TLI_DEFINE_VECFUNC("__expf_finite", "_ZGVdN8v___expf_finite", 8)
+
+TLI_DEFINE_VECFUNC("llvm.exp.f64", "_ZGVbN2v_exp", 2)
+TLI_DEFINE_VECFUNC("llvm.exp.f64", "_ZGVdN4v_exp", 4)
+
+TLI_DEFINE_VECFUNC("llvm.exp.f32", "_ZGVbN4v_expf", 4)
+TLI_DEFINE_VECFUNC("llvm.exp.f32", "_ZGVdN8v_expf", 8)
+
+TLI_DEFINE_VECFUNC("log", "_ZGVbN2v_log", 2)
+TLI_DEFINE_VECFUNC("log", "_ZGVdN4v_log", 4)
+
+TLI_DEFINE_VECFUNC("logf", "_ZGVbN4v_logf", 4)
+TLI_DEFINE_VECFUNC("logf", "_ZGVdN8v_logf", 8)
+
+TLI_DEFINE_VECFUNC("__log_finite", "_ZGVbN2v___log_finite", 2)
+TLI_DEFINE_VECFUNC("__log_finite", "_ZGVdN4v___log_finite", 4)
+
+TLI_DEFINE_VECFUNC("__logf_finite", "_ZGVbN4v___logf_finite", 4)
+TLI_DEFINE_VECFUNC("__logf_finite", "_ZGVdN8v___logf_finite", 8)
+
+TLI_DEFINE_VECFUNC("llvm.log.f64", "_ZGVbN2v_log", 2)
+TLI_DEFINE_VECFUNC("llvm.log.f64", "_ZGVdN4v_log", 4)
+
+TLI_DEFINE_VECFUNC("llvm.log.f32", "_ZGVbN4v_logf", 4)
+TLI_DEFINE_VECFUNC("llvm.log.f32", "_ZGVdN8v_logf", 8)
+
#elif defined(TLI_DEFINE_MASSV_VECFUNCS)
// IBM MASS library's vector Functions
@@ -326,70 +326,70 @@ TLI_DEFINE_VECFUNC("llvm.log.f32", "__svml_logf4", 4)
TLI_DEFINE_VECFUNC("llvm.log.f32", "__svml_logf8", 8)
TLI_DEFINE_VECFUNC("llvm.log.f32", "__svml_logf16", 16)
-TLI_DEFINE_VECFUNC("log2", "__svml_log22", 2)
-TLI_DEFINE_VECFUNC("log2", "__svml_log24", 4)
-TLI_DEFINE_VECFUNC("log2", "__svml_log28", 8)
-
-TLI_DEFINE_VECFUNC("log2f", "__svml_log2f4", 4)
-TLI_DEFINE_VECFUNC("log2f", "__svml_log2f8", 8)
-TLI_DEFINE_VECFUNC("log2f", "__svml_log2f16", 16)
-
-TLI_DEFINE_VECFUNC("__log2_finite", "__svml_log22", 2)
-TLI_DEFINE_VECFUNC("__log2_finite", "__svml_log24", 4)
-TLI_DEFINE_VECFUNC("__log2_finite", "__svml_log28", 8)
-
-TLI_DEFINE_VECFUNC("__log2f_finite", "__svml_log2f4", 4)
-TLI_DEFINE_VECFUNC("__log2f_finite", "__svml_log2f8", 8)
-TLI_DEFINE_VECFUNC("__log2f_finite", "__svml_log2f16", 16)
-
-TLI_DEFINE_VECFUNC("llvm.log2.f64", "__svml_log22", 2)
-TLI_DEFINE_VECFUNC("llvm.log2.f64", "__svml_log24", 4)
-TLI_DEFINE_VECFUNC("llvm.log2.f64", "__svml_log28", 8)
-
-TLI_DEFINE_VECFUNC("llvm.log2.f32", "__svml_log2f4", 4)
-TLI_DEFINE_VECFUNC("llvm.log2.f32", "__svml_log2f8", 8)
-TLI_DEFINE_VECFUNC("llvm.log2.f32", "__svml_log2f16", 16)
-
-TLI_DEFINE_VECFUNC("log10", "__svml_log102", 2)
-TLI_DEFINE_VECFUNC("log10", "__svml_log104", 4)
-TLI_DEFINE_VECFUNC("log10", "__svml_log108", 8)
-
-TLI_DEFINE_VECFUNC("log10f", "__svml_log10f4", 4)
-TLI_DEFINE_VECFUNC("log10f", "__svml_log10f8", 8)
-TLI_DEFINE_VECFUNC("log10f", "__svml_log10f16", 16)
-
-TLI_DEFINE_VECFUNC("__log10_finite", "__svml_log102", 2)
-TLI_DEFINE_VECFUNC("__log10_finite", "__svml_log104", 4)
-TLI_DEFINE_VECFUNC("__log10_finite", "__svml_log108", 8)
-
-TLI_DEFINE_VECFUNC("__log10f_finite", "__svml_log10f4", 4)
-TLI_DEFINE_VECFUNC("__log10f_finite", "__svml_log10f8", 8)
-TLI_DEFINE_VECFUNC("__log10f_finite", "__svml_log10f16", 16)
-
-TLI_DEFINE_VECFUNC("llvm.log10.f64", "__svml_log102", 2)
-TLI_DEFINE_VECFUNC("llvm.log10.f64", "__svml_log104", 4)
-TLI_DEFINE_VECFUNC("llvm.log10.f64", "__svml_log108", 8)
-
-TLI_DEFINE_VECFUNC("llvm.log10.f32", "__svml_log10f4", 4)
-TLI_DEFINE_VECFUNC("llvm.log10.f32", "__svml_log10f8", 8)
-TLI_DEFINE_VECFUNC("llvm.log10.f32", "__svml_log10f16", 16)
-
-TLI_DEFINE_VECFUNC("sqrt", "__svml_sqrt2", 2)
-TLI_DEFINE_VECFUNC("sqrt", "__svml_sqrt4", 4)
-TLI_DEFINE_VECFUNC("sqrt", "__svml_sqrt8", 8)
-
-TLI_DEFINE_VECFUNC("sqrtf", "__svml_sqrtf4", 4)
-TLI_DEFINE_VECFUNC("sqrtf", "__svml_sqrtf8", 8)
-TLI_DEFINE_VECFUNC("sqrtf", "__svml_sqrtf16", 16)
-
-TLI_DEFINE_VECFUNC("__sqrt_finite", "__svml_sqrt2", 2)
-TLI_DEFINE_VECFUNC("__sqrt_finite", "__svml_sqrt4", 4)
-TLI_DEFINE_VECFUNC("__sqrt_finite", "__svml_sqrt8", 8)
-
-TLI_DEFINE_VECFUNC("__sqrtf_finite", "__svml_sqrtf4", 4)
-TLI_DEFINE_VECFUNC("__sqrtf_finite", "__svml_sqrtf8", 8)
-TLI_DEFINE_VECFUNC("__sqrtf_finite", "__svml_sqrtf16", 16)
-
+TLI_DEFINE_VECFUNC("log2", "__svml_log22", 2)
+TLI_DEFINE_VECFUNC("log2", "__svml_log24", 4)
+TLI_DEFINE_VECFUNC("log2", "__svml_log28", 8)
+
+TLI_DEFINE_VECFUNC("log2f", "__svml_log2f4", 4)
+TLI_DEFINE_VECFUNC("log2f", "__svml_log2f8", 8)
+TLI_DEFINE_VECFUNC("log2f", "__svml_log2f16", 16)
+
+TLI_DEFINE_VECFUNC("__log2_finite", "__svml_log22", 2)
+TLI_DEFINE_VECFUNC("__log2_finite", "__svml_log24", 4)
+TLI_DEFINE_VECFUNC("__log2_finite", "__svml_log28", 8)
+
+TLI_DEFINE_VECFUNC("__log2f_finite", "__svml_log2f4", 4)
+TLI_DEFINE_VECFUNC("__log2f_finite", "__svml_log2f8", 8)
+TLI_DEFINE_VECFUNC("__log2f_finite", "__svml_log2f16", 16)
+
+TLI_DEFINE_VECFUNC("llvm.log2.f64", "__svml_log22", 2)
+TLI_DEFINE_VECFUNC("llvm.log2.f64", "__svml_log24", 4)
+TLI_DEFINE_VECFUNC("llvm.log2.f64", "__svml_log28", 8)
+
+TLI_DEFINE_VECFUNC("llvm.log2.f32", "__svml_log2f4", 4)
+TLI_DEFINE_VECFUNC("llvm.log2.f32", "__svml_log2f8", 8)
+TLI_DEFINE_VECFUNC("llvm.log2.f32", "__svml_log2f16", 16)
+
+TLI_DEFINE_VECFUNC("log10", "__svml_log102", 2)
+TLI_DEFINE_VECFUNC("log10", "__svml_log104", 4)
+TLI_DEFINE_VECFUNC("log10", "__svml_log108", 8)
+
+TLI_DEFINE_VECFUNC("log10f", "__svml_log10f4", 4)
+TLI_DEFINE_VECFUNC("log10f", "__svml_log10f8", 8)
+TLI_DEFINE_VECFUNC("log10f", "__svml_log10f16", 16)
+
+TLI_DEFINE_VECFUNC("__log10_finite", "__svml_log102", 2)
+TLI_DEFINE_VECFUNC("__log10_finite", "__svml_log104", 4)
+TLI_DEFINE_VECFUNC("__log10_finite", "__svml_log108", 8)
+
+TLI_DEFINE_VECFUNC("__log10f_finite", "__svml_log10f4", 4)
+TLI_DEFINE_VECFUNC("__log10f_finite", "__svml_log10f8", 8)
+TLI_DEFINE_VECFUNC("__log10f_finite", "__svml_log10f16", 16)
+
+TLI_DEFINE_VECFUNC("llvm.log10.f64", "__svml_log102", 2)
+TLI_DEFINE_VECFUNC("llvm.log10.f64", "__svml_log104", 4)
+TLI_DEFINE_VECFUNC("llvm.log10.f64", "__svml_log108", 8)
+
+TLI_DEFINE_VECFUNC("llvm.log10.f32", "__svml_log10f4", 4)
+TLI_DEFINE_VECFUNC("llvm.log10.f32", "__svml_log10f8", 8)
+TLI_DEFINE_VECFUNC("llvm.log10.f32", "__svml_log10f16", 16)
+
+TLI_DEFINE_VECFUNC("sqrt", "__svml_sqrt2", 2)
+TLI_DEFINE_VECFUNC("sqrt", "__svml_sqrt4", 4)
+TLI_DEFINE_VECFUNC("sqrt", "__svml_sqrt8", 8)
+
+TLI_DEFINE_VECFUNC("sqrtf", "__svml_sqrtf4", 4)
+TLI_DEFINE_VECFUNC("sqrtf", "__svml_sqrtf8", 8)
+TLI_DEFINE_VECFUNC("sqrtf", "__svml_sqrtf16", 16)
+
+TLI_DEFINE_VECFUNC("__sqrt_finite", "__svml_sqrt2", 2)
+TLI_DEFINE_VECFUNC("__sqrt_finite", "__svml_sqrt4", 4)
+TLI_DEFINE_VECFUNC("__sqrt_finite", "__svml_sqrt8", 8)
+
+TLI_DEFINE_VECFUNC("__sqrtf_finite", "__svml_sqrtf4", 4)
+TLI_DEFINE_VECFUNC("__sqrtf_finite", "__svml_sqrtf8", 8)
+TLI_DEFINE_VECFUNC("__sqrtf_finite", "__svml_sqrtf16", 16)
+
TLI_DEFINE_VECFUNC("exp2", "__svml_exp22", 2)
TLI_DEFINE_VECFUNC("exp2", "__svml_exp24", 4)
TLI_DEFINE_VECFUNC("exp2", "__svml_exp28", 8)
@@ -420,7 +420,7 @@ TLI_DEFINE_VECFUNC("__exp2f_finite", "__svml_exp2f16", 16)
#undef TLI_DEFINE_VECFUNC
#undef TLI_DEFINE_ACCELERATE_VECFUNCS
-#undef TLI_DEFINE_LIBMVEC_X86_VECFUNCS
+#undef TLI_DEFINE_LIBMVEC_X86_VECFUNCS
#undef TLI_DEFINE_MASSV_VECFUNCS
#undef TLI_DEFINE_SVML_VECFUNCS
#undef TLI_DEFINE_MASSV_VECFUNCS_NAMES
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/VectorUtils.h b/contrib/libs/llvm12/include/llvm/Analysis/VectorUtils.h
index 82047c3aec..dc23c9c9ee 100644
--- a/contrib/libs/llvm12/include/llvm/Analysis/VectorUtils.h
+++ b/contrib/libs/llvm12/include/llvm/Analysis/VectorUtils.h
@@ -21,12 +21,12 @@
#define LLVM_ANALYSIS_VECTORUTILS_H
#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/LoopAccessAnalysis.h"
#include "llvm/Support/CheckedArithmetic.h"
namespace llvm {
-class TargetLibraryInfo;
+class TargetLibraryInfo;
/// Describes the type of Parameters
enum class VFParamKind {
@@ -106,8 +106,8 @@ struct VFShape {
// Retrieve the VFShape that can be used to map a (scalar) function to itself,
// with VF = 1.
static VFShape getScalarShape(const CallInst &CI) {
- return VFShape::get(CI, ElementCount::getFixed(1),
- /*HasGlobalPredicate*/ false);
+ return VFShape::get(CI, ElementCount::getFixed(1),
+ /*HasGlobalPredicate*/ false);
}
// Retrieve the basic vectorization shape of the function, where all
@@ -122,7 +122,7 @@ struct VFShape {
Parameters.push_back(
VFParameter({CI.arg_size(), VFParamKind::GlobalPredicate}));
- return {EC.getKnownMinValue(), EC.isScalable(), Parameters};
+ return {EC.getKnownMinValue(), EC.isScalable(), Parameters};
}
/// Sanity check on the Parameters in the VFShape.
bool hasValidParameterList() const;
@@ -307,19 +307,19 @@ namespace Intrinsic {
typedef unsigned ID;
}
-/// A helper function for converting Scalar types to vector types. If
-/// the incoming type is void, we return void. If the EC represents a
-/// scalar, we return the scalar type.
-inline Type *ToVectorTy(Type *Scalar, ElementCount EC) {
- if (Scalar->isVoidTy() || Scalar->isMetadataTy() || EC.isScalar())
+/// A helper function for converting Scalar types to vector types. If
+/// the incoming type is void, we return void. If the EC represents a
+/// scalar, we return the scalar type.
+inline Type *ToVectorTy(Type *Scalar, ElementCount EC) {
+ if (Scalar->isVoidTy() || Scalar->isMetadataTy() || EC.isScalar())
return Scalar;
- return VectorType::get(Scalar, EC);
+ return VectorType::get(Scalar, EC);
+}
+
+inline Type *ToVectorTy(Type *Scalar, unsigned VF) {
+ return ToVectorTy(Scalar, ElementCount::getFixed(VF));
}
-inline Type *ToVectorTy(Type *Scalar, unsigned VF) {
- return ToVectorTy(Scalar, ElementCount::getFixed(VF));
-}
-
/// 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 (or scalars handled by
@@ -365,7 +365,7 @@ int getSplatIndex(ArrayRef<int> Mask);
/// 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.
-Value *getSplatValue(const Value *V);
+Value *getSplatValue(const Value *V);
/// Return true if each element of the vector value \p V is poisoned or equal to
/// every other non-poisoned element. If an index element is specified, either
@@ -551,20 +551,20 @@ createSequentialMask(unsigned Start, unsigned NumInts, unsigned NumUndefs);
/// elements, it will be padded with undefs.
Value *concatenateVectors(IRBuilderBase &Builder, ArrayRef<Value *> Vecs);
-/// Given a mask vector of i1, Return true if all of the elements of this
-/// predicate mask are known to be false or undef. That is, return true if all
-/// lanes can be assumed inactive.
+/// Given a mask vector of i1, Return true if all of the elements of this
+/// predicate mask are known to be false or undef. That is, return true if all
+/// lanes can be assumed inactive.
bool maskIsAllZeroOrUndef(Value *Mask);
-/// Given a mask vector of i1, Return true if all of the elements of this
-/// predicate mask are known to be true or undef. That is, return true if all
-/// lanes can be assumed active.
+/// Given a mask vector of i1, Return true if all of the elements of this
+/// predicate mask are known to be true or undef. That is, return true if all
+/// lanes can be assumed active.
bool maskIsAllOneOrUndef(Value *Mask);
/// Given a mask vector of the form <Y x i1>, return an APInt (of bitwidth Y)
/// for each lane which may be active.
APInt possiblyDemandedEltsInMask(Value *Mask);
-
+
/// The group of interleaved loads/stores sharing the same stride and
/// close to each other.
///
@@ -627,11 +627,11 @@ public:
return false;
int32_t Key = *MaybeKey;
- // Skip if the key is used for either the tombstone or empty special values.
- if (DenseMapInfo<int32_t>::getTombstoneKey() == Key ||
- DenseMapInfo<int32_t>::getEmptyKey() == Key)
- return false;
-
+ // Skip if the key is used for either the tombstone or empty special values.
+ if (DenseMapInfo<int32_t>::getTombstoneKey() == Key ||
+ DenseMapInfo<int32_t>::getEmptyKey() == Key)
+ return false;
+
// Skip if there is already a member with the same index.
if (Members.find(Key) != Members.end())
return false;
@@ -667,7 +667,7 @@ public:
/// \returns nullptr if contains no such member.
InstTy *getMember(uint32_t Index) const {
int32_t Key = SmallestKey + Index;
- return Members.lookup(Key);
+ return Members.lookup(Key);
}
/// Get the index for the given member. Unlike the key in the member
@@ -785,7 +785,7 @@ public:
/// \returns nullptr if doesn't have such group.
InterleaveGroup<Instruction> *
getInterleaveGroup(const Instruction *Instr) const {
- return InterleaveGroupMap.lookup(Instr);
+ return InterleaveGroupMap.lookup(Instr);
}
iterator_range<SmallPtrSetIterator<llvm::InterleaveGroup<Instruction> *>>
diff --git a/contrib/libs/llvm12/include/llvm/BinaryFormat/COFF.h b/contrib/libs/llvm12/include/llvm/BinaryFormat/COFF.h
index 09e45e1455..4734d29e2c 100644
--- a/contrib/libs/llvm12/include/llvm/BinaryFormat/COFF.h
+++ b/contrib/libs/llvm12/include/llvm/BinaryFormat/COFF.h
@@ -318,7 +318,7 @@ enum SectionCharacteristics : uint32_t {
IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000,
IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000,
IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000,
- IMAGE_SCN_ALIGN_MASK = 0x00F00000,
+ IMAGE_SCN_ALIGN_MASK = 0x00F00000,
IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000,
IMAGE_SCN_MEM_DISCARDABLE = 0x02000000,
IMAGE_SCN_MEM_NOT_CACHED = 0x04000000,
diff --git a/contrib/libs/llvm12/include/llvm/BinaryFormat/Dwarf.def b/contrib/libs/llvm12/include/llvm/BinaryFormat/Dwarf.def
index d2a504afac..f69877bb50 100644
--- a/contrib/libs/llvm12/include/llvm/BinaryFormat/Dwarf.def
+++ b/contrib/libs/llvm12/include/llvm/BinaryFormat/Dwarf.def
@@ -17,7 +17,7 @@
defined HANDLE_DW_VIRTUALITY || defined HANDLE_DW_DEFAULTED || \
defined HANDLE_DW_CC || defined HANDLE_DW_LNS || defined HANDLE_DW_LNE || \
defined HANDLE_DW_LNCT || defined HANDLE_DW_MACRO || \
- defined HANDLE_DW_MACRO_GNU || defined HANDLE_MACRO_FLAG || \
+ defined HANDLE_DW_MACRO_GNU || defined HANDLE_MACRO_FLAG || \
defined HANDLE_DW_RLE || defined HANDLE_DW_LLE || \
(defined HANDLE_DW_CFA && defined HANDLE_DW_CFA_PRED) || \
defined HANDLE_DW_APPLE_PROPERTY || defined HANDLE_DW_UT || \
@@ -88,10 +88,10 @@
#define HANDLE_DW_MACRO(ID, NAME)
#endif
-#ifndef HANDLE_DW_MACRO_GNU
-#define HANDLE_DW_MACRO_GNU(ID, NAME)
-#endif
-
+#ifndef HANDLE_DW_MACRO_GNU
+#define HANDLE_DW_MACRO_GNU(ID, NAME)
+#endif
+
#ifndef HANDLE_MACRO_FLAG
#define HANDLE_MACRO_FLAG(ID, NAME)
#endif
@@ -841,18 +841,18 @@ HANDLE_DW_MACRO(0x0a, import_sup)
HANDLE_DW_MACRO(0x0b, define_strx)
HANDLE_DW_MACRO(0x0c, undef_strx)
-// GNU .debug_macro extension.
-HANDLE_DW_MACRO_GNU(0x01, define)
-HANDLE_DW_MACRO_GNU(0x02, undef)
-HANDLE_DW_MACRO_GNU(0x03, start_file)
-HANDLE_DW_MACRO_GNU(0x04, end_file)
-HANDLE_DW_MACRO_GNU(0x05, define_indirect)
-HANDLE_DW_MACRO_GNU(0x06, undef_indirect)
-HANDLE_DW_MACRO_GNU(0x07, transparent_include)
-HANDLE_DW_MACRO_GNU(0x08, define_indirect_alt)
-HANDLE_DW_MACRO_GNU(0x09, undef_indirect_alt)
-HANDLE_DW_MACRO_GNU(0x0a, transparent_include_alt)
-
+// GNU .debug_macro extension.
+HANDLE_DW_MACRO_GNU(0x01, define)
+HANDLE_DW_MACRO_GNU(0x02, undef)
+HANDLE_DW_MACRO_GNU(0x03, start_file)
+HANDLE_DW_MACRO_GNU(0x04, end_file)
+HANDLE_DW_MACRO_GNU(0x05, define_indirect)
+HANDLE_DW_MACRO_GNU(0x06, undef_indirect)
+HANDLE_DW_MACRO_GNU(0x07, transparent_include)
+HANDLE_DW_MACRO_GNU(0x08, define_indirect_alt)
+HANDLE_DW_MACRO_GNU(0x09, undef_indirect_alt)
+HANDLE_DW_MACRO_GNU(0x0a, transparent_include_alt)
+
// DWARF v5 Macro header flags.
HANDLE_MACRO_FLAG(0x01, OFFSET_SIZE)
HANDLE_MACRO_FLAG(0x02, DEBUG_LINE_OFFSET)
@@ -1002,7 +1002,7 @@ HANDLE_DW_SECT(8, RNGLISTS)
#undef HANDLE_DW_LNE
#undef HANDLE_DW_LNCT
#undef HANDLE_DW_MACRO
-#undef HANDLE_DW_MACRO_GNU
+#undef HANDLE_DW_MACRO_GNU
#undef HANDLE_MACRO_FLAG
#undef HANDLE_DW_RLE
#undef HANDLE_DW_LLE
diff --git a/contrib/libs/llvm12/include/llvm/BinaryFormat/Dwarf.h b/contrib/libs/llvm12/include/llvm/BinaryFormat/Dwarf.h
index aaaf43bfe5..59f43234d2 100644
--- a/contrib/libs/llvm12/include/llvm/BinaryFormat/Dwarf.h
+++ b/contrib/libs/llvm12/include/llvm/BinaryFormat/Dwarf.h
@@ -34,8 +34,8 @@
#include "llvm/Support/FormatVariadicDetails.h"
#include "llvm/ADT/Triple.h"
-#include <limits>
-
+#include <limits>
+
namespace llvm {
class StringRef;
@@ -127,11 +127,11 @@ enum LocationAtom {
#include "llvm/BinaryFormat/Dwarf.def"
DW_OP_lo_user = 0xe0,
DW_OP_hi_user = 0xff,
- DW_OP_LLVM_fragment = 0x1000, ///< Only used in LLVM metadata.
- DW_OP_LLVM_convert = 0x1001, ///< Only used in LLVM metadata.
- DW_OP_LLVM_tag_offset = 0x1002, ///< Only used in LLVM metadata.
- DW_OP_LLVM_entry_value = 0x1003, ///< Only used in LLVM metadata.
- DW_OP_LLVM_implicit_pointer = 0x1004, ///< Only used in LLVM metadata.
+ DW_OP_LLVM_fragment = 0x1000, ///< Only used in LLVM metadata.
+ DW_OP_LLVM_convert = 0x1001, ///< Only used in LLVM metadata.
+ DW_OP_LLVM_tag_offset = 0x1002, ///< Only used in LLVM metadata.
+ DW_OP_LLVM_entry_value = 0x1003, ///< Only used in LLVM metadata.
+ DW_OP_LLVM_implicit_pointer = 0x1004, ///< Only used in LLVM metadata.
};
enum TypeKind : uint8_t {
@@ -193,7 +193,7 @@ enum SourceLanguage {
};
inline bool isCPlusPlus(SourceLanguage S) {
- bool result = false;
+ bool result = false;
// Deliberately enumerate all the language options so we get a warning when
// new language options are added (-Wswitch) that'll hopefully help keep this
// switch up-to-date when new C++ versions are added.
@@ -202,8 +202,8 @@ inline bool isCPlusPlus(SourceLanguage S) {
case DW_LANG_C_plus_plus_03:
case DW_LANG_C_plus_plus_11:
case DW_LANG_C_plus_plus_14:
- result = true;
- break;
+ result = true;
+ break;
case DW_LANG_C89:
case DW_LANG_C:
case DW_LANG_Ada83:
@@ -242,70 +242,70 @@ inline bool isCPlusPlus(SourceLanguage S) {
case DW_LANG_BORLAND_Delphi:
case DW_LANG_lo_user:
case DW_LANG_hi_user:
- result = false;
- break;
+ result = false;
+ break;
}
-
- return result;
+
+ return result;
+}
+
+inline bool isFortran(SourceLanguage S) {
+ bool result = false;
+ // Deliberately enumerate all the language options so we get a warning when
+ // new language options are added (-Wswitch) that'll hopefully help keep this
+ // switch up-to-date when new Fortran versions are added.
+ switch (S) {
+ case DW_LANG_Fortran77:
+ case DW_LANG_Fortran90:
+ case DW_LANG_Fortran95:
+ case DW_LANG_Fortran03:
+ case DW_LANG_Fortran08:
+ result = true;
+ break;
+ case DW_LANG_C89:
+ case DW_LANG_C:
+ case DW_LANG_Ada83:
+ case DW_LANG_C_plus_plus:
+ case DW_LANG_Cobol74:
+ case DW_LANG_Cobol85:
+ case DW_LANG_Pascal83:
+ case DW_LANG_Modula2:
+ case DW_LANG_Java:
+ case DW_LANG_C99:
+ case DW_LANG_Ada95:
+ case DW_LANG_PLI:
+ case DW_LANG_ObjC:
+ case DW_LANG_ObjC_plus_plus:
+ case DW_LANG_UPC:
+ case DW_LANG_D:
+ case DW_LANG_Python:
+ case DW_LANG_OpenCL:
+ case DW_LANG_Go:
+ case DW_LANG_Modula3:
+ case DW_LANG_Haskell:
+ case DW_LANG_C_plus_plus_03:
+ case DW_LANG_C_plus_plus_11:
+ case DW_LANG_OCaml:
+ case DW_LANG_Rust:
+ case DW_LANG_C11:
+ case DW_LANG_Swift:
+ case DW_LANG_Julia:
+ case DW_LANG_Dylan:
+ case DW_LANG_C_plus_plus_14:
+ case DW_LANG_RenderScript:
+ case DW_LANG_BLISS:
+ case DW_LANG_Mips_Assembler:
+ case DW_LANG_GOOGLE_RenderScript:
+ case DW_LANG_BORLAND_Delphi:
+ case DW_LANG_lo_user:
+ case DW_LANG_hi_user:
+ result = false;
+ break;
+ }
+
+ return result;
}
-inline bool isFortran(SourceLanguage S) {
- bool result = false;
- // Deliberately enumerate all the language options so we get a warning when
- // new language options are added (-Wswitch) that'll hopefully help keep this
- // switch up-to-date when new Fortran versions are added.
- switch (S) {
- case DW_LANG_Fortran77:
- case DW_LANG_Fortran90:
- case DW_LANG_Fortran95:
- case DW_LANG_Fortran03:
- case DW_LANG_Fortran08:
- result = true;
- break;
- case DW_LANG_C89:
- case DW_LANG_C:
- case DW_LANG_Ada83:
- case DW_LANG_C_plus_plus:
- case DW_LANG_Cobol74:
- case DW_LANG_Cobol85:
- case DW_LANG_Pascal83:
- case DW_LANG_Modula2:
- case DW_LANG_Java:
- case DW_LANG_C99:
- case DW_LANG_Ada95:
- case DW_LANG_PLI:
- case DW_LANG_ObjC:
- case DW_LANG_ObjC_plus_plus:
- case DW_LANG_UPC:
- case DW_LANG_D:
- case DW_LANG_Python:
- case DW_LANG_OpenCL:
- case DW_LANG_Go:
- case DW_LANG_Modula3:
- case DW_LANG_Haskell:
- case DW_LANG_C_plus_plus_03:
- case DW_LANG_C_plus_plus_11:
- case DW_LANG_OCaml:
- case DW_LANG_Rust:
- case DW_LANG_C11:
- case DW_LANG_Swift:
- case DW_LANG_Julia:
- case DW_LANG_Dylan:
- case DW_LANG_C_plus_plus_14:
- case DW_LANG_RenderScript:
- case DW_LANG_BLISS:
- case DW_LANG_Mips_Assembler:
- case DW_LANG_GOOGLE_RenderScript:
- case DW_LANG_BORLAND_Delphi:
- case DW_LANG_lo_user:
- case DW_LANG_hi_user:
- result = false;
- break;
- }
-
- return result;
-}
-
enum CaseSensitivity {
// Identifier case codes
DW_ID_case_sensitive = 0x00,
@@ -380,14 +380,14 @@ enum MacroEntryType {
DW_MACRO_hi_user = 0xff
};
-/// GNU .debug_macro macro information entry type encodings.
-enum GnuMacroEntryType {
-#define HANDLE_DW_MACRO_GNU(ID, NAME) DW_MACRO_GNU_##NAME = ID,
-#include "llvm/BinaryFormat/Dwarf.def"
- DW_MACRO_GNU_lo_user = 0xe0,
- DW_MACRO_GNU_hi_user = 0xff
-};
-
+/// GNU .debug_macro macro information entry type encodings.
+enum GnuMacroEntryType {
+#define HANDLE_DW_MACRO_GNU(ID, NAME) DW_MACRO_GNU_##NAME = ID,
+#include "llvm/BinaryFormat/Dwarf.def"
+ DW_MACRO_GNU_lo_user = 0xe0,
+ DW_MACRO_GNU_hi_user = 0xff
+};
+
/// DWARF v5 range list entry encoding values.
enum RnglistEntries {
#define HANDLE_DW_RLE(ID, NAME) DW_RLE_##NAME = ID,
@@ -551,7 +551,7 @@ StringRef LNStandardString(unsigned Standard);
StringRef LNExtendedString(unsigned Encoding);
StringRef MacinfoString(unsigned Encoding);
StringRef MacroString(unsigned Encoding);
-StringRef GnuMacroString(unsigned Encoding);
+StringRef GnuMacroString(unsigned Encoding);
StringRef RangeListEncodingString(unsigned Encoding);
StringRef LocListEncodingString(unsigned Encoding);
StringRef CallFrameString(unsigned Encoding, Triple::ArchType Arch);
@@ -563,7 +563,7 @@ StringRef GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage);
StringRef IndexString(unsigned Idx);
StringRef FormatString(DwarfFormat Format);
StringRef FormatString(bool IsDWARF64);
-StringRef RLEString(unsigned RLE);
+StringRef RLEString(unsigned RLE);
/// @}
/// \defgroup DwarfConstantsParsing Dwarf constants parsing functions
@@ -755,11 +755,11 @@ template <> struct EnumTraits<LocationAtom> : public std::true_type {
static constexpr char Type[3] = "OP";
static constexpr StringRef (*StringFn)(unsigned) = &OperationEncodingString;
};
-
-inline uint64_t computeTombstoneAddress(uint8_t AddressByteSize) {
- return std::numeric_limits<uint64_t>::max() >> (8 - AddressByteSize) * 8;
-}
-
+
+inline uint64_t computeTombstoneAddress(uint8_t AddressByteSize) {
+ return std::numeric_limits<uint64_t>::max() >> (8 - AddressByteSize) * 8;
+}
+
} // End of namespace dwarf
/// Dwarf constants format_provider
diff --git a/contrib/libs/llvm12/include/llvm/BinaryFormat/DynamicTags.def b/contrib/libs/llvm12/include/llvm/BinaryFormat/DynamicTags.def
index 51629818a4..c08f8a53bd 100644
--- a/contrib/libs/llvm12/include/llvm/BinaryFormat/DynamicTags.def
+++ b/contrib/libs/llvm12/include/llvm/BinaryFormat/DynamicTags.def
@@ -120,7 +120,7 @@ DYNAMIC_TAG(VERNEEDNUM, 0X6FFFFFFF) // The number of entries in DT_VERNEED.
// AArch64 specific dynamic table entries
AARCH64_DYNAMIC_TAG(AARCH64_BTI_PLT, 0x70000001)
AARCH64_DYNAMIC_TAG(AARCH64_PAC_PLT, 0x70000003)
-AARCH64_DYNAMIC_TAG(AARCH64_VARIANT_PCS, 0x70000005)
+AARCH64_DYNAMIC_TAG(AARCH64_VARIANT_PCS, 0x70000005)
// Hexagon specific dynamic table entries
HEXAGON_DYNAMIC_TAG(HEXAGON_SYMSZ, 0x70000000)
diff --git a/contrib/libs/llvm12/include/llvm/BinaryFormat/ELF.h b/contrib/libs/llvm12/include/llvm/BinaryFormat/ELF.h
index c2313871b2..7a00c6fba3 100644
--- a/contrib/libs/llvm12/include/llvm/BinaryFormat/ELF.h
+++ b/contrib/libs/llvm12/include/llvm/BinaryFormat/ELF.h
@@ -114,17 +114,17 @@ struct Elf64_Ehdr {
unsigned char getDataEncoding() const { return e_ident[EI_DATA]; }
};
-// File types.
-// See current registered ELF types at:
-// http://www.sco.com/developers/gabi/latest/ch4.eheader.html
+// File types.
+// See current registered ELF types at:
+// http://www.sco.com/developers/gabi/latest/ch4.eheader.html
enum {
ET_NONE = 0, // No file type
ET_REL = 1, // Relocatable file
ET_EXEC = 2, // Executable file
ET_DYN = 3, // Shared object file
ET_CORE = 4, // Core file
- ET_LOOS = 0xfe00, // Beginning of operating system-specific codes
- ET_HIOS = 0xfeff, // Operating system-specific
+ ET_LOOS = 0xfe00, // Beginning of operating system-specific codes
+ ET_HIOS = 0xfeff, // Operating system-specific
ET_LOPROC = 0xff00, // Beginning of processor-specific codes
ET_HIPROC = 0xffff // Processor-specific
};
@@ -323,7 +323,7 @@ enum {
EM_LANAI = 244, // Lanai 32-bit processor
EM_BPF = 247, // Linux kernel bpf virtual machine
EM_VE = 251, // NEC SX-Aurora VE
- EM_CSKY = 252, // C-SKY 32-bit processor
+ EM_CSKY = 252, // C-SKY 32-bit processor
};
// Object file classes.
@@ -371,14 +371,14 @@ enum {
ELFOSABI_LAST_ARCH = 255 // Last Architecture-specific OS ABI
};
-// AMDGPU OS ABI Version identification.
-enum {
- // ELFABIVERSION_AMDGPU_HSA_V1 does not exist because OS ABI identification
- // was never defined for V1.
- ELFABIVERSION_AMDGPU_HSA_V2 = 0,
- ELFABIVERSION_AMDGPU_HSA_V3 = 1,
-};
-
+// AMDGPU OS ABI Version identification.
+enum {
+ // ELFABIVERSION_AMDGPU_HSA_V1 does not exist because OS ABI identification
+ // was never defined for V1.
+ ELFABIVERSION_AMDGPU_HSA_V2 = 0,
+ ELFABIVERSION_AMDGPU_HSA_V3 = 1,
+};
+
#define ELF_RELOC(name, value) name = value,
// X86_64 relocations.
@@ -706,39 +706,39 @@ enum : unsigned {
EF_AMDGPU_MACH_R600_LAST = EF_AMDGPU_MACH_R600_TURKS,
// AMDGCN-based processors.
- EF_AMDGPU_MACH_AMDGCN_GFX600 = 0x020,
- EF_AMDGPU_MACH_AMDGCN_GFX601 = 0x021,
- EF_AMDGPU_MACH_AMDGCN_GFX700 = 0x022,
- EF_AMDGPU_MACH_AMDGCN_GFX701 = 0x023,
- EF_AMDGPU_MACH_AMDGCN_GFX702 = 0x024,
- EF_AMDGPU_MACH_AMDGCN_GFX703 = 0x025,
- EF_AMDGPU_MACH_AMDGCN_GFX704 = 0x026,
- EF_AMDGPU_MACH_AMDGCN_RESERVED_0X27 = 0x027,
- EF_AMDGPU_MACH_AMDGCN_GFX801 = 0x028,
- EF_AMDGPU_MACH_AMDGCN_GFX802 = 0x029,
- EF_AMDGPU_MACH_AMDGCN_GFX803 = 0x02a,
- EF_AMDGPU_MACH_AMDGCN_GFX810 = 0x02b,
- EF_AMDGPU_MACH_AMDGCN_GFX900 = 0x02c,
- EF_AMDGPU_MACH_AMDGCN_GFX902 = 0x02d,
- EF_AMDGPU_MACH_AMDGCN_GFX904 = 0x02e,
- EF_AMDGPU_MACH_AMDGCN_GFX906 = 0x02f,
- EF_AMDGPU_MACH_AMDGCN_GFX908 = 0x030,
- EF_AMDGPU_MACH_AMDGCN_GFX909 = 0x031,
- EF_AMDGPU_MACH_AMDGCN_GFX90C = 0x032,
- EF_AMDGPU_MACH_AMDGCN_GFX1010 = 0x033,
- EF_AMDGPU_MACH_AMDGCN_GFX1011 = 0x034,
- EF_AMDGPU_MACH_AMDGCN_GFX1012 = 0x035,
- EF_AMDGPU_MACH_AMDGCN_GFX1030 = 0x036,
- EF_AMDGPU_MACH_AMDGCN_GFX1031 = 0x037,
- EF_AMDGPU_MACH_AMDGCN_GFX1032 = 0x038,
- EF_AMDGPU_MACH_AMDGCN_GFX1033 = 0x039,
- EF_AMDGPU_MACH_AMDGCN_GFX602 = 0x03a,
- EF_AMDGPU_MACH_AMDGCN_GFX705 = 0x03b,
- EF_AMDGPU_MACH_AMDGCN_GFX805 = 0x03c,
+ EF_AMDGPU_MACH_AMDGCN_GFX600 = 0x020,
+ EF_AMDGPU_MACH_AMDGCN_GFX601 = 0x021,
+ EF_AMDGPU_MACH_AMDGCN_GFX700 = 0x022,
+ EF_AMDGPU_MACH_AMDGCN_GFX701 = 0x023,
+ EF_AMDGPU_MACH_AMDGCN_GFX702 = 0x024,
+ EF_AMDGPU_MACH_AMDGCN_GFX703 = 0x025,
+ EF_AMDGPU_MACH_AMDGCN_GFX704 = 0x026,
+ EF_AMDGPU_MACH_AMDGCN_RESERVED_0X27 = 0x027,
+ EF_AMDGPU_MACH_AMDGCN_GFX801 = 0x028,
+ EF_AMDGPU_MACH_AMDGCN_GFX802 = 0x029,
+ EF_AMDGPU_MACH_AMDGCN_GFX803 = 0x02a,
+ EF_AMDGPU_MACH_AMDGCN_GFX810 = 0x02b,
+ EF_AMDGPU_MACH_AMDGCN_GFX900 = 0x02c,
+ EF_AMDGPU_MACH_AMDGCN_GFX902 = 0x02d,
+ EF_AMDGPU_MACH_AMDGCN_GFX904 = 0x02e,
+ EF_AMDGPU_MACH_AMDGCN_GFX906 = 0x02f,
+ EF_AMDGPU_MACH_AMDGCN_GFX908 = 0x030,
+ EF_AMDGPU_MACH_AMDGCN_GFX909 = 0x031,
+ EF_AMDGPU_MACH_AMDGCN_GFX90C = 0x032,
+ EF_AMDGPU_MACH_AMDGCN_GFX1010 = 0x033,
+ EF_AMDGPU_MACH_AMDGCN_GFX1011 = 0x034,
+ EF_AMDGPU_MACH_AMDGCN_GFX1012 = 0x035,
+ EF_AMDGPU_MACH_AMDGCN_GFX1030 = 0x036,
+ EF_AMDGPU_MACH_AMDGCN_GFX1031 = 0x037,
+ EF_AMDGPU_MACH_AMDGCN_GFX1032 = 0x038,
+ EF_AMDGPU_MACH_AMDGCN_GFX1033 = 0x039,
+ EF_AMDGPU_MACH_AMDGCN_GFX602 = 0x03a,
+ EF_AMDGPU_MACH_AMDGCN_GFX705 = 0x03b,
+ EF_AMDGPU_MACH_AMDGCN_GFX805 = 0x03c,
// First/last AMDGCN-based processors.
EF_AMDGPU_MACH_AMDGCN_FIRST = EF_AMDGPU_MACH_AMDGCN_GFX600,
- EF_AMDGPU_MACH_AMDGCN_LAST = EF_AMDGPU_MACH_AMDGCN_GFX805,
+ EF_AMDGPU_MACH_AMDGCN_LAST = EF_AMDGPU_MACH_AMDGCN_GFX805,
// Indicates if the "xnack" target feature is enabled for all code contained
// in the object.
@@ -795,12 +795,12 @@ enum {
#include "ELFRelocs/VE.def"
};
-
-// ELF Relocation types for CSKY
-enum {
-#include "ELFRelocs/CSKY.def"
-};
-
+
+// ELF Relocation types for CSKY
+enum {
+#include "ELFRelocs/CSKY.def"
+};
+
#undef ELF_RELOC
// Section header.
@@ -878,11 +878,11 @@ enum : unsigned {
SHT_LLVM_ADDRSIG = 0x6fff4c03, // List of address-significant symbols
// for safe ICF.
SHT_LLVM_DEPENDENT_LIBRARIES =
- 0x6fff4c04, // LLVM Dependent Library Specifiers.
- SHT_LLVM_SYMPART = 0x6fff4c05, // Symbol partition specification.
- SHT_LLVM_PART_EHDR = 0x6fff4c06, // ELF header for loadable partition.
- SHT_LLVM_PART_PHDR = 0x6fff4c07, // Phdrs for loadable partition.
- SHT_LLVM_BB_ADDR_MAP = 0x6fff4c08, // LLVM Basic Block Address Map.
+ 0x6fff4c04, // LLVM Dependent Library Specifiers.
+ SHT_LLVM_SYMPART = 0x6fff4c05, // Symbol partition specification.
+ SHT_LLVM_PART_EHDR = 0x6fff4c06, // ELF header for loadable partition.
+ SHT_LLVM_PART_PHDR = 0x6fff4c07, // Phdrs for loadable partition.
+ SHT_LLVM_BB_ADDR_MAP = 0x6fff4c08, // LLVM Basic Block Address Map.
// Android's experimental support for SHT_RELR sections.
// https://android.googlesource.com/platform/bionic/+/b7feec74547f84559a1467aca02708ff61346d2a/libc/include/elf.h#512
SHT_ANDROID_RELR = 0x6fffff00, // Relocation entries; only offsets.
diff --git a/contrib/libs/llvm12/include/llvm/BinaryFormat/ELFRelocs/CSKY.def b/contrib/libs/llvm12/include/llvm/BinaryFormat/ELFRelocs/CSKY.def
index f6d583f453..c5f2dbae80 100644
--- a/contrib/libs/llvm12/include/llvm/BinaryFormat/ELFRelocs/CSKY.def
+++ b/contrib/libs/llvm12/include/llvm/BinaryFormat/ELFRelocs/CSKY.def
@@ -1,74 +1,74 @@
-
-#ifndef ELF_RELOC
-#error "ELF_RELOC must be defined"
-#endif
-
-ELF_RELOC(R_CKCORE_NONE, 0)
-ELF_RELOC(R_CKCORE_ADDR32, 1)
-ELF_RELOC(R_CKCORE_PCREL_IMM8_4, 2)
-ELF_RELOC(R_CKCORE_PCREL_IMM11_2, 3)
-ELF_RELOC(R_CKCORE_PCREL_IMM4_2, 4)
-ELF_RELOC(R_CKCORE_PCREL32, 5)
-ELF_RELOC(R_CKCORE_PCREL_JSR_IMM11_2, 6)
-ELF_RELOC(R_CKCORE_GNU_VTINHERIT, 7)
-ELF_RELOC(R_CKCORE_GNU_VTENTRY, 8)
-ELF_RELOC(R_CKCORE_RELATIVE, 9)
-ELF_RELOC(R_CKCORE_COPY, 10)
-ELF_RELOC(R_CKCORE_GLOB_DAT, 11)
-ELF_RELOC(R_CKCORE_JUMP_SLOT, 12)
-ELF_RELOC(R_CKCORE_GOTOFF, 13)
-ELF_RELOC(R_CKCORE_GOTPC, 14)
-ELF_RELOC(R_CKCORE_GOT32, 15)
-ELF_RELOC(R_CKCORE_PLT32, 16)
-ELF_RELOC(R_CKCORE_ADDRGOT, 17)
-ELF_RELOC(R_CKCORE_ADDRPLT, 18)
-ELF_RELOC(R_CKCORE_PCREL_IMM26_2, 19)
-ELF_RELOC(R_CKCORE_PCREL_IMM16_2, 20)
-ELF_RELOC(R_CKCORE_PCREL_IMM16_4, 21)
-ELF_RELOC(R_CKCORE_PCREL_IMM10_2, 22)
-ELF_RELOC(R_CKCORE_PCREL_IMM10_4, 23)
-ELF_RELOC(R_CKCORE_ADDR_HI16, 24)
-ELF_RELOC(R_CKCORE_ADDR_LO16, 25)
-ELF_RELOC(R_CKCORE_GOTPC_HI16, 26)
-ELF_RELOC(R_CKCORE_GOTPC_LO16, 27)
-ELF_RELOC(R_CKCORE_GOTOFF_HI16, 28)
-ELF_RELOC(R_CKCORE_GOTOFF_LO16, 29)
-ELF_RELOC(R_CKCORE_GOT12, 30)
-ELF_RELOC(R_CKCORE_GOT_HI16, 31)
-ELF_RELOC(R_CKCORE_GOT_LO16, 32)
-ELF_RELOC(R_CKCORE_PLT12, 33)
-ELF_RELOC(R_CKCORE_PLT_HI16, 34)
-ELF_RELOC(R_CKCORE_PLT_LO16, 35)
-ELF_RELOC(R_CKCORE_ADDRGOT_HI16, 36)
-ELF_RELOC(R_CKCORE_ADDRGOT_LO16, 37)
-ELF_RELOC(R_CKCORE_ADDRPLT_HI16, 38)
-ELF_RELOC(R_CKCORE_ADDRPLT_LO16, 39)
-ELF_RELOC(R_CKCORE_PCREL_JSR_IMM26_2, 40)
-ELF_RELOC(R_CKCORE_TOFFSET_LO16, 41)
-ELF_RELOC(R_CKCORE_DOFFSET_LO16, 42)
-ELF_RELOC(R_CKCORE_PCREL_IMM18_2, 43)
-ELF_RELOC(R_CKCORE_DOFFSET_IMM18, 44)
-ELF_RELOC(R_CKCORE_DOFFSET_IMM18_2, 45)
-ELF_RELOC(R_CKCORE_DOFFSET_IMM18_4, 46)
-ELF_RELOC(R_CKCORE_GOTOFF_IMM18, 47)
-ELF_RELOC(R_CKCORE_GOT_IMM18_4, 48)
-ELF_RELOC(R_CKCORE_PLT_IMM18_4, 49)
-ELF_RELOC(R_CKCORE_PCREL_IMM7_4, 50)
-ELF_RELOC(R_CKCORE_TLS_LE32, 51)
-ELF_RELOC(R_CKCORE_TLS_IE32, 52)
-ELF_RELOC(R_CKCORE_TLS_GD32, 53)
-ELF_RELOC(R_CKCORE_TLS_LDM32, 54)
-ELF_RELOC(R_CKCORE_TLS_LDO32, 55)
-ELF_RELOC(R_CKCORE_TLS_DTPMOD32, 56)
-ELF_RELOC(R_CKCORE_TLS_DTPOFF32, 57)
-ELF_RELOC(R_CKCORE_TLS_TPOFF32, 58)
-ELF_RELOC(R_CKCORE_PCREL_FLRW_IMM8_4, 59)
-ELF_RELOC(R_CKCORE_NOJSRI, 60)
-ELF_RELOC(R_CKCORE_CALLGRAPH, 61)
-ELF_RELOC(R_CKCORE_IRELATIVE, 62)
-ELF_RELOC(R_CKCORE_PCREL_BLOOP_IMM4_4, 63)
-ELF_RELOC(R_CKCORE_PCREL_BLOOP_IMM12_4, 64)
-ELF_RELOC(R_CKCORE_PCREL_VLRW_IMM12_1, 65)
-ELF_RELOC(R_CKCORE_PCREL_VLRW_IMM12_2, 66)
-ELF_RELOC(R_CKCORE_PCREL_VLRW_IMM12_4, 67)
-ELF_RELOC(R_CKCORE_PCREL_VLRW_IMM12_8, 68)
+
+#ifndef ELF_RELOC
+#error "ELF_RELOC must be defined"
+#endif
+
+ELF_RELOC(R_CKCORE_NONE, 0)
+ELF_RELOC(R_CKCORE_ADDR32, 1)
+ELF_RELOC(R_CKCORE_PCREL_IMM8_4, 2)
+ELF_RELOC(R_CKCORE_PCREL_IMM11_2, 3)
+ELF_RELOC(R_CKCORE_PCREL_IMM4_2, 4)
+ELF_RELOC(R_CKCORE_PCREL32, 5)
+ELF_RELOC(R_CKCORE_PCREL_JSR_IMM11_2, 6)
+ELF_RELOC(R_CKCORE_GNU_VTINHERIT, 7)
+ELF_RELOC(R_CKCORE_GNU_VTENTRY, 8)
+ELF_RELOC(R_CKCORE_RELATIVE, 9)
+ELF_RELOC(R_CKCORE_COPY, 10)
+ELF_RELOC(R_CKCORE_GLOB_DAT, 11)
+ELF_RELOC(R_CKCORE_JUMP_SLOT, 12)
+ELF_RELOC(R_CKCORE_GOTOFF, 13)
+ELF_RELOC(R_CKCORE_GOTPC, 14)
+ELF_RELOC(R_CKCORE_GOT32, 15)
+ELF_RELOC(R_CKCORE_PLT32, 16)
+ELF_RELOC(R_CKCORE_ADDRGOT, 17)
+ELF_RELOC(R_CKCORE_ADDRPLT, 18)
+ELF_RELOC(R_CKCORE_PCREL_IMM26_2, 19)
+ELF_RELOC(R_CKCORE_PCREL_IMM16_2, 20)
+ELF_RELOC(R_CKCORE_PCREL_IMM16_4, 21)
+ELF_RELOC(R_CKCORE_PCREL_IMM10_2, 22)
+ELF_RELOC(R_CKCORE_PCREL_IMM10_4, 23)
+ELF_RELOC(R_CKCORE_ADDR_HI16, 24)
+ELF_RELOC(R_CKCORE_ADDR_LO16, 25)
+ELF_RELOC(R_CKCORE_GOTPC_HI16, 26)
+ELF_RELOC(R_CKCORE_GOTPC_LO16, 27)
+ELF_RELOC(R_CKCORE_GOTOFF_HI16, 28)
+ELF_RELOC(R_CKCORE_GOTOFF_LO16, 29)
+ELF_RELOC(R_CKCORE_GOT12, 30)
+ELF_RELOC(R_CKCORE_GOT_HI16, 31)
+ELF_RELOC(R_CKCORE_GOT_LO16, 32)
+ELF_RELOC(R_CKCORE_PLT12, 33)
+ELF_RELOC(R_CKCORE_PLT_HI16, 34)
+ELF_RELOC(R_CKCORE_PLT_LO16, 35)
+ELF_RELOC(R_CKCORE_ADDRGOT_HI16, 36)
+ELF_RELOC(R_CKCORE_ADDRGOT_LO16, 37)
+ELF_RELOC(R_CKCORE_ADDRPLT_HI16, 38)
+ELF_RELOC(R_CKCORE_ADDRPLT_LO16, 39)
+ELF_RELOC(R_CKCORE_PCREL_JSR_IMM26_2, 40)
+ELF_RELOC(R_CKCORE_TOFFSET_LO16, 41)
+ELF_RELOC(R_CKCORE_DOFFSET_LO16, 42)
+ELF_RELOC(R_CKCORE_PCREL_IMM18_2, 43)
+ELF_RELOC(R_CKCORE_DOFFSET_IMM18, 44)
+ELF_RELOC(R_CKCORE_DOFFSET_IMM18_2, 45)
+ELF_RELOC(R_CKCORE_DOFFSET_IMM18_4, 46)
+ELF_RELOC(R_CKCORE_GOTOFF_IMM18, 47)
+ELF_RELOC(R_CKCORE_GOT_IMM18_4, 48)
+ELF_RELOC(R_CKCORE_PLT_IMM18_4, 49)
+ELF_RELOC(R_CKCORE_PCREL_IMM7_4, 50)
+ELF_RELOC(R_CKCORE_TLS_LE32, 51)
+ELF_RELOC(R_CKCORE_TLS_IE32, 52)
+ELF_RELOC(R_CKCORE_TLS_GD32, 53)
+ELF_RELOC(R_CKCORE_TLS_LDM32, 54)
+ELF_RELOC(R_CKCORE_TLS_LDO32, 55)
+ELF_RELOC(R_CKCORE_TLS_DTPMOD32, 56)
+ELF_RELOC(R_CKCORE_TLS_DTPOFF32, 57)
+ELF_RELOC(R_CKCORE_TLS_TPOFF32, 58)
+ELF_RELOC(R_CKCORE_PCREL_FLRW_IMM8_4, 59)
+ELF_RELOC(R_CKCORE_NOJSRI, 60)
+ELF_RELOC(R_CKCORE_CALLGRAPH, 61)
+ELF_RELOC(R_CKCORE_IRELATIVE, 62)
+ELF_RELOC(R_CKCORE_PCREL_BLOOP_IMM4_4, 63)
+ELF_RELOC(R_CKCORE_PCREL_BLOOP_IMM12_4, 64)
+ELF_RELOC(R_CKCORE_PCREL_VLRW_IMM12_1, 65)
+ELF_RELOC(R_CKCORE_PCREL_VLRW_IMM12_2, 66)
+ELF_RELOC(R_CKCORE_PCREL_VLRW_IMM12_4, 67)
+ELF_RELOC(R_CKCORE_PCREL_VLRW_IMM12_8, 68)
diff --git a/contrib/libs/llvm12/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def b/contrib/libs/llvm12/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def
index ab04332310..0422aa0606 100644
--- a/contrib/libs/llvm12/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def
+++ b/contrib/libs/llvm12/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def
@@ -97,14 +97,14 @@
#undef R_PPC64_DTPREL16_HIGH
#undef R_PPC64_DTPREL16_HIGHA
#undef R_PPC64_REL24_NOTOC
-#undef R_PPC64_PCREL_OPT
+#undef R_PPC64_PCREL_OPT
#undef R_PPC64_PCREL34
#undef R_PPC64_GOT_PCREL34
-#undef R_PPC64_TPREL34
-#undef R_PPC64_DTPREL34
-#undef R_PPC64_GOT_TLSGD_PCREL34
-#undef R_PPC64_GOT_TLSLD_PCREL34
-#undef R_PPC64_GOT_TPREL_PCREL34
+#undef R_PPC64_TPREL34
+#undef R_PPC64_DTPREL34
+#undef R_PPC64_GOT_TLSGD_PCREL34
+#undef R_PPC64_GOT_TLSLD_PCREL34
+#undef R_PPC64_GOT_TPREL_PCREL34
#undef R_PPC64_IRELATIVE
#undef R_PPC64_REL16
#undef R_PPC64_REL16_LO
@@ -200,14 +200,14 @@ ELF_RELOC(R_PPC64_TPREL16_HIGHA, 113)
ELF_RELOC(R_PPC64_DTPREL16_HIGH, 114)
ELF_RELOC(R_PPC64_DTPREL16_HIGHA, 115)
ELF_RELOC(R_PPC64_REL24_NOTOC, 116)
-ELF_RELOC(R_PPC64_PCREL_OPT, 123)
+ELF_RELOC(R_PPC64_PCREL_OPT, 123)
ELF_RELOC(R_PPC64_PCREL34, 132)
ELF_RELOC(R_PPC64_GOT_PCREL34, 133)
-ELF_RELOC(R_PPC64_TPREL34, 146)
-ELF_RELOC(R_PPC64_DTPREL34, 147)
-ELF_RELOC(R_PPC64_GOT_TLSGD_PCREL34, 148)
-ELF_RELOC(R_PPC64_GOT_TLSLD_PCREL34, 149)
-ELF_RELOC(R_PPC64_GOT_TPREL_PCREL34, 150)
+ELF_RELOC(R_PPC64_TPREL34, 146)
+ELF_RELOC(R_PPC64_DTPREL34, 147)
+ELF_RELOC(R_PPC64_GOT_TLSGD_PCREL34, 148)
+ELF_RELOC(R_PPC64_GOT_TLSLD_PCREL34, 149)
+ELF_RELOC(R_PPC64_GOT_TPREL_PCREL34, 150)
ELF_RELOC(R_PPC64_IRELATIVE, 248)
ELF_RELOC(R_PPC64_REL16, 249)
ELF_RELOC(R_PPC64_REL16_LO, 250)
diff --git a/contrib/libs/llvm12/include/llvm/BinaryFormat/MachO.h b/contrib/libs/llvm12/include/llvm/BinaryFormat/MachO.h
index fdce485a9d..d087c87917 100644
--- a/contrib/libs/llvm12/include/llvm/BinaryFormat/MachO.h
+++ b/contrib/libs/llvm12/include/llvm/BinaryFormat/MachO.h
@@ -90,7 +90,7 @@ enum {
MH_NO_HEAP_EXECUTION = 0x01000000u,
MH_APP_EXTENSION_SAFE = 0x02000000u,
MH_NLIST_OUTOFSYNC_WITH_DYLDINFO = 0x04000000u,
- MH_SIM_SUPPORT = 0x08000000u,
+ MH_SIM_SUPPORT = 0x08000000u,
MH_DYLIB_IN_CACHE = 0x80000000u,
};
@@ -503,8 +503,8 @@ enum PlatformType {
PLATFORM_MACCATALYST = 6,
PLATFORM_IOSSIMULATOR = 7,
PLATFORM_TVOSSIMULATOR = 8,
- PLATFORM_WATCHOSSIMULATOR = 9,
- PLATFORM_DRIVERKIT = 10,
+ PLATFORM_WATCHOSSIMULATOR = 9,
+ PLATFORM_DRIVERKIT = 10,
};
// Values for tools enum in build_tool_version.
@@ -1501,7 +1501,7 @@ enum CPUSubTypeARM {
enum CPUSubTypeARM64 {
CPU_SUBTYPE_ARM64_ALL = 0,
- CPU_SUBTYPE_ARM64_V8 = 1,
+ CPU_SUBTYPE_ARM64_V8 = 1,
CPU_SUBTYPE_ARM64E = 2,
};
diff --git a/contrib/libs/llvm12/include/llvm/BinaryFormat/Wasm.h b/contrib/libs/llvm12/include/llvm/BinaryFormat/Wasm.h
index 02fe8b71ff..5b8be4f7e6 100644
--- a/contrib/libs/llvm12/include/llvm/BinaryFormat/Wasm.h
+++ b/contrib/libs/llvm12/include/llvm/BinaryFormat/Wasm.h
@@ -48,7 +48,7 @@ struct WasmDylinkInfo {
uint32_t MemoryAlignment; // P2 alignment of memory
uint32_t TableSize; // Table size in elements
uint32_t TableAlignment; // P2 alignment of table
- std::vector<StringRef> Needed; // Shared library dependencies
+ std::vector<StringRef> Needed; // Shared library dependencies
};
struct WasmProducerInfo {
@@ -74,17 +74,17 @@ struct WasmLimits {
uint64_t Maximum;
};
-struct WasmTableType {
+struct WasmTableType {
uint8_t ElemType;
WasmLimits Limits;
};
-struct WasmTable {
- uint32_t Index;
- WasmTableType Type;
- StringRef SymbolName; // from the "linking" section
-};
-
+struct WasmTable {
+ uint32_t Index;
+ WasmTableType Type;
+ StringRef SymbolName; // from the "linking" section
+};
+
struct WasmInitExpr {
uint8_t Opcode;
union {
@@ -127,7 +127,7 @@ struct WasmImport {
union {
uint32_t SigIndex;
WasmGlobalType Global;
- WasmTableType Table;
+ WasmTableType Table;
WasmLimits Memory;
WasmEventType Event;
};
@@ -153,11 +153,11 @@ struct WasmFunction {
struct WasmDataSegment {
uint32_t InitFlags;
- // Present if InitFlags & WASM_DATA_SEGMENT_HAS_MEMINDEX.
- uint32_t MemoryIndex;
- // Present if InitFlags & WASM_DATA_SEGMENT_IS_PASSIVE == 0.
- WasmInitExpr Offset;
-
+ // Present if InitFlags & WASM_DATA_SEGMENT_HAS_MEMINDEX.
+ uint32_t MemoryIndex;
+ // Present if InitFlags & WASM_DATA_SEGMENT_IS_PASSIVE == 0.
+ WasmInitExpr Offset;
+
ArrayRef<uint8_t> Content;
StringRef Name; // from the "segment info" section
uint32_t Alignment;
@@ -202,22 +202,22 @@ struct WasmSymbolInfo {
// For symbols to be exported from the final module
Optional<StringRef> ExportName;
union {
- // For function, table, or global symbols, the index in function, table, or
- // global index space.
+ // For function, table, or global symbols, the index in function, table, or
+ // global index space.
uint32_t ElementIndex;
// For a data symbols, the address of the data relative to segment.
WasmDataReference DataRef;
};
};
-enum class NameType {
- FUNCTION,
- GLOBAL,
- DATA_SEGMENT,
-};
-
-struct WasmDebugName {
- NameType Type;
+enum class NameType {
+ FUNCTION,
+ GLOBAL,
+ DATA_SEGMENT,
+};
+
+struct WasmDebugName {
+ NameType Type;
uint32_t Index;
StringRef Name;
};
@@ -273,7 +273,7 @@ enum : unsigned {
WASM_OPCODE_END = 0x0b,
WASM_OPCODE_CALL = 0x10,
WASM_OPCODE_LOCAL_GET = 0x20,
- WASM_OPCODE_LOCAL_SET = 0x21,
+ WASM_OPCODE_LOCAL_SET = 0x21,
WASM_OPCODE_GLOBAL_GET = 0x23,
WASM_OPCODE_GLOBAL_SET = 0x24,
WASM_OPCODE_I32_STORE = 0x36,
@@ -310,8 +310,8 @@ enum : unsigned {
};
enum : unsigned {
- WASM_DATA_SEGMENT_IS_PASSIVE = 0x01,
- WASM_DATA_SEGMENT_HAS_MEMINDEX = 0x02,
+ WASM_DATA_SEGMENT_IS_PASSIVE = 0x01,
+ WASM_DATA_SEGMENT_HAS_MEMINDEX = 0x02,
};
// Feature policy prefixes used in the custom "target_features" section
@@ -323,10 +323,10 @@ enum : uint8_t {
// Kind codes used in the custom "name" section
enum : unsigned {
- WASM_NAMES_FUNCTION = 1,
- WASM_NAMES_LOCAL = 2,
- WASM_NAMES_GLOBAL = 7,
- WASM_NAMES_DATA_SEGMENT = 9,
+ WASM_NAMES_FUNCTION = 1,
+ WASM_NAMES_LOCAL = 2,
+ WASM_NAMES_GLOBAL = 7,
+ WASM_NAMES_DATA_SEGMENT = 9,
};
// Kind codes used in the custom "linking" section
@@ -341,8 +341,8 @@ enum : unsigned {
enum : unsigned {
WASM_COMDAT_DATA = 0x0,
WASM_COMDAT_FUNCTION = 0x1,
- // GLOBAL, EVENT, and TABLE are in here but LLVM doesn't use them yet.
- WASM_COMDAT_SECTION = 0x5,
+ // GLOBAL, EVENT, and TABLE are in here but LLVM doesn't use them yet.
+ WASM_COMDAT_SECTION = 0x5,
};
// Kind codes used in the custom "linking" section in the WASM_SYMBOL_TABLE
@@ -352,7 +352,7 @@ enum WasmSymbolType : unsigned {
WASM_SYMBOL_TYPE_GLOBAL = 0x2,
WASM_SYMBOL_TYPE_SECTION = 0x3,
WASM_SYMBOL_TYPE_EVENT = 0x4,
- WASM_SYMBOL_TYPE_TABLE = 0x5,
+ WASM_SYMBOL_TYPE_TABLE = 0x5,
};
// Kinds of event attributes.
@@ -388,7 +388,7 @@ enum class ValType {
F32 = WASM_TYPE_F32,
F64 = WASM_TYPE_F64,
V128 = WASM_TYPE_V128,
- FUNCREF = WASM_TYPE_FUNCREF,
+ FUNCREF = WASM_TYPE_FUNCREF,
EXTERNREF = WASM_TYPE_EXTERNREF,
};
diff --git a/contrib/libs/llvm12/include/llvm/BinaryFormat/WasmRelocs.def b/contrib/libs/llvm12/include/llvm/BinaryFormat/WasmRelocs.def
index 0a417482aa..dca63eca94 100644
--- a/contrib/libs/llvm12/include/llvm/BinaryFormat/WasmRelocs.def
+++ b/contrib/libs/llvm12/include/llvm/BinaryFormat/WasmRelocs.def
@@ -20,8 +20,8 @@ WASM_RELOC(R_WASM_MEMORY_ADDR_LEB64, 14)
WASM_RELOC(R_WASM_MEMORY_ADDR_SLEB64, 15)
WASM_RELOC(R_WASM_MEMORY_ADDR_I64, 16)
WASM_RELOC(R_WASM_MEMORY_ADDR_REL_SLEB64, 17)
-WASM_RELOC(R_WASM_TABLE_INDEX_SLEB64, 18)
-WASM_RELOC(R_WASM_TABLE_INDEX_I64, 19)
-WASM_RELOC(R_WASM_TABLE_NUMBER_LEB, 20)
-WASM_RELOC(R_WASM_MEMORY_ADDR_TLS_SLEB, 21)
-WASM_RELOC(R_WASM_FUNCTION_OFFSET_I64, 22)
+WASM_RELOC(R_WASM_TABLE_INDEX_SLEB64, 18)
+WASM_RELOC(R_WASM_TABLE_INDEX_I64, 19)
+WASM_RELOC(R_WASM_TABLE_NUMBER_LEB, 20)
+WASM_RELOC(R_WASM_MEMORY_ADDR_TLS_SLEB, 21)
+WASM_RELOC(R_WASM_FUNCTION_OFFSET_I64, 22)
diff --git a/contrib/libs/llvm12/include/llvm/BinaryFormat/WasmTraits.h b/contrib/libs/llvm12/include/llvm/BinaryFormat/WasmTraits.h
index c64bbb0738..9a99113934 100644
--- a/contrib/libs/llvm12/include/llvm/BinaryFormat/WasmTraits.h
+++ b/contrib/libs/llvm12/include/llvm/BinaryFormat/WasmTraits.h
@@ -1,79 +1,79 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- WasmTraits.h - DenseMap traits for the Wasm structures ---*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides llvm::DenseMapInfo traits for the Wasm structures.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_BINARYFORMAT_WASMTRAITS_H
-#define LLVM_BINARYFORMAT_WASMTRAITS_H
-
-#include "llvm/ADT/Hashing.h"
-#include "llvm/BinaryFormat/Wasm.h"
-
-namespace llvm {
-
-template <typename T> struct DenseMapInfo;
-
-// Traits for using WasmSignature in a DenseMap.
-template <> struct DenseMapInfo<wasm::WasmSignature> {
- static wasm::WasmSignature getEmptyKey() {
- wasm::WasmSignature Sig;
- Sig.State = wasm::WasmSignature::Empty;
- return Sig;
- }
- static wasm::WasmSignature getTombstoneKey() {
- wasm::WasmSignature Sig;
- Sig.State = wasm::WasmSignature::Tombstone;
- return Sig;
- }
- static unsigned getHashValue(const wasm::WasmSignature &Sig) {
- uintptr_t H = hash_value(Sig.State);
- for (auto Ret : Sig.Returns)
- H = hash_combine(H, Ret);
- for (auto Param : Sig.Params)
- H = hash_combine(H, Param);
- return H;
- }
- static bool isEqual(const wasm::WasmSignature &LHS,
- const wasm::WasmSignature &RHS) {
- return LHS == RHS;
- }
-};
-
-// Traits for using WasmGlobalType in a DenseMap
-template <> struct DenseMapInfo<wasm::WasmGlobalType> {
- static wasm::WasmGlobalType getEmptyKey() {
- return wasm::WasmGlobalType{1, true};
- }
- static wasm::WasmGlobalType getTombstoneKey() {
- return wasm::WasmGlobalType{2, true};
- }
- static unsigned getHashValue(const wasm::WasmGlobalType &GlobalType) {
- return hash_combine(GlobalType.Type, GlobalType.Mutable);
- }
- static bool isEqual(const wasm::WasmGlobalType &LHS,
- const wasm::WasmGlobalType &RHS) {
- return LHS == RHS;
- }
-};
-
-} // end namespace llvm
-
-#endif // LLVM_BINARYFORMAT_WASMTRAITS_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- WasmTraits.h - DenseMap traits for the Wasm structures ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides llvm::DenseMapInfo traits for the Wasm structures.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BINARYFORMAT_WASMTRAITS_H
+#define LLVM_BINARYFORMAT_WASMTRAITS_H
+
+#include "llvm/ADT/Hashing.h"
+#include "llvm/BinaryFormat/Wasm.h"
+
+namespace llvm {
+
+template <typename T> struct DenseMapInfo;
+
+// Traits for using WasmSignature in a DenseMap.
+template <> struct DenseMapInfo<wasm::WasmSignature> {
+ static wasm::WasmSignature getEmptyKey() {
+ wasm::WasmSignature Sig;
+ Sig.State = wasm::WasmSignature::Empty;
+ return Sig;
+ }
+ static wasm::WasmSignature getTombstoneKey() {
+ wasm::WasmSignature Sig;
+ Sig.State = wasm::WasmSignature::Tombstone;
+ return Sig;
+ }
+ static unsigned getHashValue(const wasm::WasmSignature &Sig) {
+ uintptr_t H = hash_value(Sig.State);
+ for (auto Ret : Sig.Returns)
+ H = hash_combine(H, Ret);
+ for (auto Param : Sig.Params)
+ H = hash_combine(H, Param);
+ return H;
+ }
+ static bool isEqual(const wasm::WasmSignature &LHS,
+ const wasm::WasmSignature &RHS) {
+ return LHS == RHS;
+ }
+};
+
+// Traits for using WasmGlobalType in a DenseMap
+template <> struct DenseMapInfo<wasm::WasmGlobalType> {
+ static wasm::WasmGlobalType getEmptyKey() {
+ return wasm::WasmGlobalType{1, true};
+ }
+ static wasm::WasmGlobalType getTombstoneKey() {
+ return wasm::WasmGlobalType{2, true};
+ }
+ static unsigned getHashValue(const wasm::WasmGlobalType &GlobalType) {
+ return hash_combine(GlobalType.Type, GlobalType.Mutable);
+ }
+ static bool isEqual(const wasm::WasmGlobalType &LHS,
+ const wasm::WasmGlobalType &RHS) {
+ return LHS == RHS;
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_BINARYFORMAT_WASMTRAITS_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/BinaryFormat/XCOFF.h b/contrib/libs/llvm12/include/llvm/BinaryFormat/XCOFF.h
index c1d709bb71..b98e838c8a 100644
--- a/contrib/libs/llvm12/include/llvm/BinaryFormat/XCOFF.h
+++ b/contrib/libs/llvm12/include/llvm/BinaryFormat/XCOFF.h
@@ -25,7 +25,7 @@
namespace llvm {
class StringRef;
-template <unsigned> class SmallString;
+template <unsigned> class SmallString;
namespace XCOFF {
@@ -36,7 +36,7 @@ constexpr size_t NameSize = 8;
constexpr size_t SymbolTableEntrySize = 18;
constexpr size_t RelocationSerializationSize32 = 10;
constexpr uint16_t RelocOverflow = 65535;
-constexpr uint8_t AllocRegNo = 31;
+constexpr uint8_t AllocRegNo = 31;
enum ReservedSectionNum : int16_t { N_DEBUG = -2, N_ABS = -1, N_UNDEF = 0 };
@@ -303,116 +303,116 @@ enum CFileCpuId : uint8_t {
StringRef getMappingClassString(XCOFF::StorageMappingClass SMC);
StringRef getRelocationTypeString(XCOFF::RelocationType Type);
-SmallString<32> parseParmsType(uint32_t Value, unsigned ParmsNum);
-
-struct TracebackTable {
- enum LanguageID : uint8_t {
- C,
- Fortran,
- Pascal,
- Ada,
- PL1,
- Basic,
- Lisp,
- Cobol,
- Modula2,
- CPlusPlus,
- Rpg,
- PL8,
- PLIX = PL8,
- Assembly,
- Java,
- ObjectiveC
- };
- // Byte 1
- static constexpr uint32_t VersionMask = 0xFF00'0000;
- static constexpr uint8_t VersionShift = 24;
-
- // Byte 2
- static constexpr uint32_t LanguageIdMask = 0x00FF'0000;
- static constexpr uint8_t LanguageIdShift = 16;
-
- // Byte 3
- static constexpr uint32_t IsGlobaLinkageMask = 0x0000'8000;
- static constexpr uint32_t IsOutOfLineEpilogOrPrologueMask = 0x0000'4000;
- static constexpr uint32_t HasTraceBackTableOffsetMask = 0x0000'2000;
- static constexpr uint32_t IsInternalProcedureMask = 0x0000'1000;
- static constexpr uint32_t HasControlledStorageMask = 0x0000'0800;
- static constexpr uint32_t IsTOClessMask = 0x0000'0400;
- static constexpr uint32_t IsFloatingPointPresentMask = 0x0000'0200;
- static constexpr uint32_t IsFloatingPointOperationLogOrAbortEnabledMask =
- 0x0000'0100;
-
- // Byte 4
- static constexpr uint32_t IsInterruptHandlerMask = 0x0000'0080;
- static constexpr uint32_t IsFunctionNamePresentMask = 0x0000'0040;
- static constexpr uint32_t IsAllocaUsedMask = 0x0000'0020;
- static constexpr uint32_t OnConditionDirectiveMask = 0x0000'001C;
- static constexpr uint32_t IsCRSavedMask = 0x0000'0002;
- static constexpr uint32_t IsLRSavedMask = 0x0000'0001;
- static constexpr uint8_t OnConditionDirectiveShift = 2;
-
- // Byte 5
- static constexpr uint32_t IsBackChainStoredMask = 0x8000'0000;
- static constexpr uint32_t IsFixupMask = 0x4000'0000;
- static constexpr uint32_t FPRSavedMask = 0x3F00'0000;
- static constexpr uint32_t FPRSavedShift = 24;
-
- // Byte 6
- static constexpr uint32_t HasVectorInfoMask = 0x0080'0000;
- static constexpr uint32_t HasExtensionTableMask = 0x0040'0000;
- static constexpr uint32_t GPRSavedMask = 0x003F'0000;
- static constexpr uint32_t GPRSavedShift = 16;
-
- // Byte 7
- static constexpr uint32_t NumberOfFixedParmsMask = 0x0000'FF00;
- static constexpr uint8_t NumberOfFixedParmsShift = 8;
-
- // Byte 8
- static constexpr uint32_t NumberOfFloatingPointParmsMask = 0x0000'00FE;
- static constexpr uint32_t HasParmsOnStackMask = 0x0000'0001;
- static constexpr uint8_t NumberOfFloatingPointParmsShift = 1;
-
- // Masks to select leftmost bits for decoding parameter type information.
- // Bit to use when vector info is not presented.
- static constexpr uint32_t ParmTypeIsFloatingBit = 0x8000'0000;
- static constexpr uint32_t ParmTypeFloatingIsDoubleBit = 0x4000'0000;
- // Bits to use when vector info is presented.
- static constexpr uint32_t ParmTypeIsFixedBits = 0x0000'0000;
- static constexpr uint32_t ParmTypeIsVectorBits = 0x4000'0000;
- static constexpr uint32_t ParmTypeIsFloatingBits = 0x8000'0000;
- static constexpr uint32_t ParmTypeIsDoubleBits = 0xC000'0000;
- static constexpr uint32_t ParmTypeMask = 0xC000'0000;
-
- // Vector extension
- static constexpr uint16_t NumberOfVRSavedMask = 0xFC00;
- static constexpr uint16_t IsVRSavedOnStackMask = 0x0200;
- static constexpr uint16_t HasVarArgsMask = 0x0100;
- static constexpr uint8_t NumberOfVRSavedShift = 10;
-
- static constexpr uint16_t NumberOfVectorParmsMask = 0x00FE;
- static constexpr uint16_t HasVMXInstructionMask = 0x0001;
- static constexpr uint8_t NumberOfVectorParmsShift = 1;
-
- static constexpr uint32_t ParmTypeIsVectorCharBit = 0x0000'0000;
- static constexpr uint32_t ParmTypeIsVectorShortBit = 0x4000'0000;
- static constexpr uint32_t ParmTypeIsVectorIntBit = 0x8000'0000;
- static constexpr uint32_t ParmTypeIsVectorFloatBit = 0xC000'0000;
-};
-
-// Extended Traceback table flags.
-enum ExtendedTBTableFlag : uint8_t {
- TB_OS1 = 0x80, ///< Reserved for OS use.
- TB_RESERVED = 0x40, ///< Reserved for compiler.
- TB_SSP_CANARY = 0x20, ///< stack smasher canary present on stack.
- TB_OS2 = 0x10, ///< Reserved for OS use.
- TB_EH_INFO = 0x08, ///< Exception handling info present.
- TB_LONGTBTABLE2 = 0x01 ///< Additional tbtable extension exists.
-};
-
-StringRef getNameForTracebackTableLanguageId(TracebackTable::LanguageID LangId);
-SmallString<32> getExtendedTBTableFlagString(uint8_t Flag);
-
+SmallString<32> parseParmsType(uint32_t Value, unsigned ParmsNum);
+
+struct TracebackTable {
+ enum LanguageID : uint8_t {
+ C,
+ Fortran,
+ Pascal,
+ Ada,
+ PL1,
+ Basic,
+ Lisp,
+ Cobol,
+ Modula2,
+ CPlusPlus,
+ Rpg,
+ PL8,
+ PLIX = PL8,
+ Assembly,
+ Java,
+ ObjectiveC
+ };
+ // Byte 1
+ static constexpr uint32_t VersionMask = 0xFF00'0000;
+ static constexpr uint8_t VersionShift = 24;
+
+ // Byte 2
+ static constexpr uint32_t LanguageIdMask = 0x00FF'0000;
+ static constexpr uint8_t LanguageIdShift = 16;
+
+ // Byte 3
+ static constexpr uint32_t IsGlobaLinkageMask = 0x0000'8000;
+ static constexpr uint32_t IsOutOfLineEpilogOrPrologueMask = 0x0000'4000;
+ static constexpr uint32_t HasTraceBackTableOffsetMask = 0x0000'2000;
+ static constexpr uint32_t IsInternalProcedureMask = 0x0000'1000;
+ static constexpr uint32_t HasControlledStorageMask = 0x0000'0800;
+ static constexpr uint32_t IsTOClessMask = 0x0000'0400;
+ static constexpr uint32_t IsFloatingPointPresentMask = 0x0000'0200;
+ static constexpr uint32_t IsFloatingPointOperationLogOrAbortEnabledMask =
+ 0x0000'0100;
+
+ // Byte 4
+ static constexpr uint32_t IsInterruptHandlerMask = 0x0000'0080;
+ static constexpr uint32_t IsFunctionNamePresentMask = 0x0000'0040;
+ static constexpr uint32_t IsAllocaUsedMask = 0x0000'0020;
+ static constexpr uint32_t OnConditionDirectiveMask = 0x0000'001C;
+ static constexpr uint32_t IsCRSavedMask = 0x0000'0002;
+ static constexpr uint32_t IsLRSavedMask = 0x0000'0001;
+ static constexpr uint8_t OnConditionDirectiveShift = 2;
+
+ // Byte 5
+ static constexpr uint32_t IsBackChainStoredMask = 0x8000'0000;
+ static constexpr uint32_t IsFixupMask = 0x4000'0000;
+ static constexpr uint32_t FPRSavedMask = 0x3F00'0000;
+ static constexpr uint32_t FPRSavedShift = 24;
+
+ // Byte 6
+ static constexpr uint32_t HasVectorInfoMask = 0x0080'0000;
+ static constexpr uint32_t HasExtensionTableMask = 0x0040'0000;
+ static constexpr uint32_t GPRSavedMask = 0x003F'0000;
+ static constexpr uint32_t GPRSavedShift = 16;
+
+ // Byte 7
+ static constexpr uint32_t NumberOfFixedParmsMask = 0x0000'FF00;
+ static constexpr uint8_t NumberOfFixedParmsShift = 8;
+
+ // Byte 8
+ static constexpr uint32_t NumberOfFloatingPointParmsMask = 0x0000'00FE;
+ static constexpr uint32_t HasParmsOnStackMask = 0x0000'0001;
+ static constexpr uint8_t NumberOfFloatingPointParmsShift = 1;
+
+ // Masks to select leftmost bits for decoding parameter type information.
+ // Bit to use when vector info is not presented.
+ static constexpr uint32_t ParmTypeIsFloatingBit = 0x8000'0000;
+ static constexpr uint32_t ParmTypeFloatingIsDoubleBit = 0x4000'0000;
+ // Bits to use when vector info is presented.
+ static constexpr uint32_t ParmTypeIsFixedBits = 0x0000'0000;
+ static constexpr uint32_t ParmTypeIsVectorBits = 0x4000'0000;
+ static constexpr uint32_t ParmTypeIsFloatingBits = 0x8000'0000;
+ static constexpr uint32_t ParmTypeIsDoubleBits = 0xC000'0000;
+ static constexpr uint32_t ParmTypeMask = 0xC000'0000;
+
+ // Vector extension
+ static constexpr uint16_t NumberOfVRSavedMask = 0xFC00;
+ static constexpr uint16_t IsVRSavedOnStackMask = 0x0200;
+ static constexpr uint16_t HasVarArgsMask = 0x0100;
+ static constexpr uint8_t NumberOfVRSavedShift = 10;
+
+ static constexpr uint16_t NumberOfVectorParmsMask = 0x00FE;
+ static constexpr uint16_t HasVMXInstructionMask = 0x0001;
+ static constexpr uint8_t NumberOfVectorParmsShift = 1;
+
+ static constexpr uint32_t ParmTypeIsVectorCharBit = 0x0000'0000;
+ static constexpr uint32_t ParmTypeIsVectorShortBit = 0x4000'0000;
+ static constexpr uint32_t ParmTypeIsVectorIntBit = 0x8000'0000;
+ static constexpr uint32_t ParmTypeIsVectorFloatBit = 0xC000'0000;
+};
+
+// Extended Traceback table flags.
+enum ExtendedTBTableFlag : uint8_t {
+ TB_OS1 = 0x80, ///< Reserved for OS use.
+ TB_RESERVED = 0x40, ///< Reserved for compiler.
+ TB_SSP_CANARY = 0x20, ///< stack smasher canary present on stack.
+ TB_OS2 = 0x10, ///< Reserved for OS use.
+ TB_EH_INFO = 0x08, ///< Exception handling info present.
+ TB_LONGTBTABLE2 = 0x01 ///< Additional tbtable extension exists.
+};
+
+StringRef getNameForTracebackTableLanguageId(TracebackTable::LanguageID LangId);
+SmallString<32> getExtendedTBTableFlagString(uint8_t Flag);
+
} // end namespace XCOFF
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Bitcode/BitcodeCommon.h b/contrib/libs/llvm12/include/llvm/Bitcode/BitcodeCommon.h
index 30372eeef1..07fd251bfb 100644
--- a/contrib/libs/llvm12/include/llvm/Bitcode/BitcodeCommon.h
+++ b/contrib/libs/llvm12/include/llvm/Bitcode/BitcodeCommon.h
@@ -1,41 +1,41 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- BitcodeCommon.h - Common code for encode/decode --------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This header defines common code to be used by BitcodeWriter and
-// BitcodeReader.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_BITCODE_BITCODECOMMON_H
-#define LLVM_BITCODE_BITCODECOMMON_H
-
-#include "llvm/ADT/Bitfields.h"
-
-namespace llvm {
-
-struct AllocaPackedValues {
- using Align = Bitfield::Element<unsigned, 0, 5>;
- using UsedWithInAlloca = Bitfield::Element<bool, Align::NextBit, 1>;
- using ExplicitType = Bitfield::Element<bool, UsedWithInAlloca::NextBit, 1>;
- using SwiftError = Bitfield::Element<bool, ExplicitType::NextBit, 1>;
-};
-
-} // namespace llvm
-
-#endif // LLVM_BITCODE_BITCODECOMMON_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- BitcodeCommon.h - Common code for encode/decode --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines common code to be used by BitcodeWriter and
+// BitcodeReader.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_BITCODECOMMON_H
+#define LLVM_BITCODE_BITCODECOMMON_H
+
+#include "llvm/ADT/Bitfields.h"
+
+namespace llvm {
+
+struct AllocaPackedValues {
+ using Align = Bitfield::Element<unsigned, 0, 5>;
+ using UsedWithInAlloca = Bitfield::Element<bool, Align::NextBit, 1>;
+ using ExplicitType = Bitfield::Element<bool, UsedWithInAlloca::NextBit, 1>;
+ using SwiftError = Bitfield::Element<bool, ExplicitType::NextBit, 1>;
+};
+
+} // namespace llvm
+
+#endif // LLVM_BITCODE_BITCODECOMMON_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Bitcode/BitcodeConvenience.h b/contrib/libs/llvm12/include/llvm/Bitcode/BitcodeConvenience.h
index 31a2545fa4..a0b837d3ff 100644
--- a/contrib/libs/llvm12/include/llvm/Bitcode/BitcodeConvenience.h
+++ b/contrib/libs/llvm12/include/llvm/Bitcode/BitcodeConvenience.h
@@ -1,497 +1,497 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- llvm/Bitcode/BitcodeConvenience.h - Convenience Wrappers -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file Convenience wrappers for the LLVM bitcode format and bitstream APIs.
-///
-/// This allows you to use a sort of DSL to declare and use bitcode
-/// abbreviations and records. Example:
-///
-/// \code
-/// using Metadata = BCRecordLayout<
-/// METADATA_ID, // ID
-/// BCFixed<16>, // Module format major version
-/// BCFixed<16>, // Module format minor version
-/// BCBlob // misc. version information
-/// >;
-/// Metadata metadata(Out);
-/// metadata.emit(ScratchRecord, VERSION_MAJOR, VERSION_MINOR, Data);
-/// \endcode
-///
-/// For details on the bitcode format, see
-/// http://llvm.org/docs/BitCodeFormat.html
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_BITCODE_BITCODECONVENIENCE_H
-#define LLVM_BITCODE_BITCODECONVENIENCE_H
-
-#include "llvm/Bitstream/BitCodes.h"
-#include "llvm/Bitstream/BitstreamWriter.h"
-#include <cstdint>
-
-namespace llvm {
-namespace detail {
-/// Convenience base for all kinds of bitcode abbreviation fields.
-///
-/// This just defines common properties queried by the metaprogramming.
-template <bool Compound = false> class BCField {
-public:
- static const bool IsCompound = Compound;
-
- /// Asserts that the given data is a valid value for this field.
- template <typename T> static void assertValid(const T &data) {}
-
- /// Converts a raw numeric representation of this value to its preferred
- /// type.
- template <typename T> static T convert(T rawValue) { return rawValue; }
-};
-} // namespace detail
-
-/// Represents a literal operand in a bitcode record.
-///
-/// The value of a literal operand is the same for all instances of the record,
-/// so it is only emitted in the abbreviation definition.
-///
-/// Note that because this uses a compile-time template, you cannot have a
-/// literal operand that is fixed at run-time without dropping down to the
-/// raw LLVM APIs.
-template <uint64_t Value> class BCLiteral : public detail::BCField<> {
-public:
- static void emitOp(llvm::BitCodeAbbrev &abbrev) {
- abbrev.Add(llvm::BitCodeAbbrevOp(Value));
- }
-
- template <typename T> static void assertValid(const T &data) {
- assert(data == Value && "data value does not match declared literal value");
- }
-};
-
-/// Represents a fixed-width value in a bitcode record.
-///
-/// Note that the LLVM bitcode format only supports unsigned values.
-template <unsigned Width> class BCFixed : public detail::BCField<> {
-public:
- static_assert(Width <= 64, "fixed-width field is too large");
-
- static void emitOp(llvm::BitCodeAbbrev &abbrev) {
- abbrev.Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, Width));
- }
-
- static void assertValid(const bool &data) {
- assert(llvm::isUInt<Width>(data) &&
- "data value does not fit in the given bit width");
- }
-
- template <typename T> static void assertValid(const T &data) {
- assert(data >= 0 && "cannot encode signed integers");
- assert(llvm::isUInt<Width>(data) &&
- "data value does not fit in the given bit width");
- }
-};
-
-/// Represents a variable-width value in a bitcode record.
-///
-/// The \p Width parameter should include the continuation bit.
-///
-/// Note that the LLVM bitcode format only supports unsigned values.
-template <unsigned Width> class BCVBR : public detail::BCField<> {
- static_assert(Width >= 2, "width does not have room for continuation bit");
-
-public:
- static void emitOp(llvm::BitCodeAbbrev &abbrev) {
- abbrev.Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, Width));
- }
-
- template <typename T> static void assertValid(const T &data) {
- assert(data >= 0 && "cannot encode signed integers");
- }
-};
-
-/// Represents a character encoded in LLVM's Char6 encoding.
-///
-/// This format is suitable for encoding decimal numbers (without signs or
-/// exponents) and C identifiers (without dollar signs), but not much else.
-///
-/// \sa http://llvm.org/docs/BitCodeFormat.html#char6-encoded-value
-class BCChar6 : public detail::BCField<> {
-public:
- static void emitOp(llvm::BitCodeAbbrev &abbrev) {
- abbrev.Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Char6));
- }
-
- template <typename T> static void assertValid(const T &data) {
- assert(llvm::BitCodeAbbrevOp::isChar6(data) && "invalid Char6 data");
- }
-
- template <typename T> char convert(T rawValue) {
- return static_cast<char>(rawValue);
- }
-};
-
-/// Represents an untyped blob of bytes.
-///
-/// If present, this must be the last field in a record.
-class BCBlob : public detail::BCField<true> {
-public:
- static void emitOp(llvm::BitCodeAbbrev &abbrev) {
- abbrev.Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
- }
-};
-
-/// Represents an array of some other type.
-///
-/// If present, this must be the last field in a record.
-template <typename ElementTy> class BCArray : public detail::BCField<true> {
- static_assert(!ElementTy::IsCompound, "arrays can only contain scalar types");
-
-public:
- static void emitOp(llvm::BitCodeAbbrev &abbrev) {
- abbrev.Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Array));
- ElementTy::emitOp(abbrev);
- }
-};
-
-namespace detail {
-/// Attaches the last field to an abbreviation.
-///
-/// This is the base case for \c emitOps.
-///
-/// \sa BCRecordLayout::emitAbbrev
-template <typename FieldTy> static void emitOps(llvm::BitCodeAbbrev &abbrev) {
- FieldTy::emitOp(abbrev);
-}
-
-/// Attaches fields to an abbreviation.
-///
-/// This is the recursive case for \c emitOps.
-///
-/// \sa BCRecordLayout::emitAbbrev
-template <typename FieldTy, typename Next, typename... Rest>
-static void emitOps(llvm::BitCodeAbbrev &abbrev) {
- static_assert(!FieldTy::IsCompound,
- "arrays and blobs may not appear in the middle of a record");
- FieldTy::emitOp(abbrev);
- emitOps<Next, Rest...>(abbrev);
-}
-
-/// Helper class for dealing with a scalar element in the middle of a record.
-///
-/// \sa BCRecordLayout
-template <typename ElementTy, typename... Fields> class BCRecordCoding {
-public:
- template <typename BufferTy, typename ElementDataTy, typename... DataTy>
- static void emit(llvm::BitstreamWriter &Stream, BufferTy &buffer,
- unsigned code, ElementDataTy element, DataTy &&...data) {
- static_assert(!ElementTy::IsCompound,
- "arrays and blobs may not appear in the middle of a record");
- ElementTy::assertValid(element);
- buffer.push_back(element);
- BCRecordCoding<Fields...>::emit(Stream, buffer, code,
- std::forward<DataTy>(data)...);
- }
-
- template <typename T, typename ElementDataTy, typename... DataTy>
- static void read(ArrayRef<T> buffer, ElementDataTy &element,
- DataTy &&...data) {
- assert(!buffer.empty() && "too few elements in buffer");
- element = ElementTy::convert(buffer.front());
- BCRecordCoding<Fields...>::read(buffer.slice(1),
- std::forward<DataTy>(data)...);
- }
-
- template <typename T, typename... DataTy>
- static void read(ArrayRef<T> buffer, NoneType, DataTy &&...data) {
- assert(!buffer.empty() && "too few elements in buffer");
- BCRecordCoding<Fields...>::read(buffer.slice(1),
- std::forward<DataTy>(data)...);
- }
-};
-
-/// Helper class for dealing with a scalar element at the end of a record.
-///
-/// This has a separate implementation because up until now we've only been
-/// \em building the record (into a data buffer), and now we need to hand it
-/// off to the BitstreamWriter to be emitted.
-///
-/// \sa BCRecordLayout
-template <typename ElementTy> class BCRecordCoding<ElementTy> {
-public:
- template <typename BufferTy, typename DataTy>
- static void emit(llvm::BitstreamWriter &Stream, BufferTy &buffer,
- unsigned code, const DataTy &data) {
- static_assert(!ElementTy::IsCompound,
- "arrays and blobs need special handling");
- ElementTy::assertValid(data);
- buffer.push_back(data);
- Stream.EmitRecordWithAbbrev(code, buffer);
- }
-
- template <typename T, typename DataTy>
- static void read(ArrayRef<T> buffer, DataTy &data) {
- assert(buffer.size() == 1 && "record data does not match layout");
- data = ElementTy::convert(buffer.front());
- }
-
- template <typename T> static void read(ArrayRef<T> buffer, NoneType) {
- assert(buffer.size() == 1 && "record data does not match layout");
- (void)buffer;
- }
-
- template <typename T> static void read(ArrayRef<T> buffer) = delete;
-};
-
-/// Helper class for dealing with an array at the end of a record.
-///
-/// \sa BCRecordLayout::emitRecord
-template <typename ElementTy> class BCRecordCoding<BCArray<ElementTy>> {
-public:
- template <typename BufferTy>
- static void emit(llvm::BitstreamWriter &Stream, BufferTy &buffer,
- unsigned code, StringRef data) {
- // TODO: validate array data.
- Stream.EmitRecordWithArray(code, buffer, data);
- }
-
- template <typename BufferTy, typename ArrayTy>
- static void emit(llvm::BitstreamWriter &Stream, BufferTy &buffer,
- unsigned code, const ArrayTy &array) {
-#ifndef NDEBUG
- for (auto &element : array)
- ElementTy::assertValid(element);
-#endif
- buffer.reserve(buffer.size() + std::distance(array.begin(), array.end()));
- std::copy(array.begin(), array.end(), std::back_inserter(buffer));
- Stream.EmitRecordWithAbbrev(code, buffer);
- }
-
- template <typename BufferTy, typename ElementDataTy, typename... DataTy>
- static void emit(llvm::BitstreamWriter &Stream, BufferTy &buffer,
- unsigned code, ElementDataTy element, DataTy... data) {
- std::array<ElementDataTy, 1 + sizeof...(data)> array{{element, data...}};
- emit(Stream, buffer, code, array);
- }
-
- template <typename BufferTy>
- static void emit(llvm::BitstreamWriter &Stream, BufferTy &Buffer,
- unsigned code, NoneType) {
- Stream.EmitRecordWithAbbrev(code, Buffer);
- }
-
- template <typename T>
- static void read(ArrayRef<T> Buffer, ArrayRef<T> &rawData) {
- rawData = Buffer;
- }
-
- template <typename T, typename ArrayTy>
- static void read(ArrayRef<T> buffer, ArrayTy &array) {
- array.append(llvm::map_iterator(buffer.begin(), T::convert),
- llvm::map_iterator(buffer.end(), T::convert));
- }
-
- template <typename T> static void read(ArrayRef<T> buffer, NoneType) {
- (void)buffer;
- }
-
- template <typename T> static void read(ArrayRef<T> buffer) = delete;
-};
-
-/// Helper class for dealing with a blob at the end of a record.
-///
-/// \sa BCRecordLayout
-template <> class BCRecordCoding<BCBlob> {
-public:
- template <typename BufferTy>
- static void emit(llvm::BitstreamWriter &Stream, BufferTy &buffer,
- unsigned code, StringRef data) {
- Stream.EmitRecordWithBlob(code, buffer, data);
- }
-
- template <typename T> static void read(ArrayRef<T> buffer) { (void)buffer; }
-
- /// Blob data is not stored in the buffer if you are using the correct
- /// accessor; this method should not be used.
- template <typename T, typename DataTy>
- static void read(ArrayRef<T> buffer, DataTy &data) = delete;
-};
-
-/// A type trait whose \c type field is the last of its template parameters.
-template <typename Head, typename... Tail> struct last_type {
- using type = typename last_type<Tail...>::type;
-};
-
-template <typename Head> struct last_type<Head> { using type = Head; };
-
-/// A type trait whose \c value field is \c true if the last type is BCBlob.
-template <typename... Types>
-using has_blob = std::is_same<BCBlob, typename last_type<int, Types...>::type>;
-
-/// A type trait whose \c value field is \c true if the given type is a
-/// BCArray (of any element kind).
-template <typename T> struct is_array {
-private:
- template <typename E> static bool check(BCArray<E> *);
- static int check(...);
-
-public:
- typedef bool value_type;
- static constexpr bool value = !std::is_same<decltype(check((T *)nullptr)),
- decltype(check(false))>::value;
-};
-
-/// A type trait whose \c value field is \c true if the last type is a
-/// BCArray (of any element kind).
-template <typename... Types>
-using has_array = is_array<typename last_type<int, Types...>::type>;
-} // namespace detail
-
-/// Represents a single bitcode record type.
-///
-/// This class template is meant to be instantiated and then given a name,
-/// so that from then on that name can be used.
-template <typename IDField, typename... Fields> class BCGenericRecordLayout {
- llvm::BitstreamWriter &Stream;
-
-public:
- /// The abbreviation code used for this record in the current block.
- ///
- /// Note that this is not the same as the semantic record code, which is the
- /// first field of the record.
- const unsigned AbbrevCode;
-
- /// Create a layout and register it with the given bitstream writer.
- explicit BCGenericRecordLayout(llvm::BitstreamWriter &Stream)
- : Stream(Stream), AbbrevCode(emitAbbrev(Stream)) {}
-
- /// Emit a record to the bitstream writer, using the given buffer for scratch
- /// space.
- ///
- /// Note that even fixed arguments must be specified here.
- template <typename BufferTy, typename... Data>
- void emit(BufferTy &buffer, unsigned id, Data &&...data) const {
- emitRecord(Stream, buffer, AbbrevCode, id, std::forward<Data>(data)...);
- }
-
- /// Registers this record's layout with the bitstream reader.
- ///
- /// eturns The abbreviation code for the newly-registered record type.
- static unsigned emitAbbrev(llvm::BitstreamWriter &Stream) {
- auto Abbrev = std::make_shared<llvm::BitCodeAbbrev>();
- detail::emitOps<IDField, Fields...>(*Abbrev);
- return Stream.EmitAbbrev(std::move(Abbrev));
- }
-
- /// Emit a record identified by \p abbrCode to bitstream reader \p Stream,
- /// using \p buffer for scratch space.
- ///
- /// Note that even fixed arguments must be specified here. Blobs are passed
- /// as StringRefs, while arrays can be passed inline, as aggregates, or as
- /// pre-encoded StringRef data. Skipped values and empty arrays should use
- /// the special Nothing value.
- template <typename BufferTy, typename... Data>
- static void emitRecord(llvm::BitstreamWriter &Stream, BufferTy &buffer,
- unsigned abbrCode, unsigned recordID, Data &&...data) {
- static_assert(sizeof...(data) <= sizeof...(Fields) ||
- detail::has_array<Fields...>::value,
- "Too many record elements");
- static_assert(sizeof...(data) >= sizeof...(Fields),
- "Too few record elements");
- buffer.clear();
- detail::BCRecordCoding<IDField, Fields...>::emit(
- Stream, buffer, abbrCode, recordID, std::forward<Data>(data)...);
- }
-
- /// Extract record data from \p buffer into the given data fields.
- ///
- /// Note that even fixed arguments must be specified here. Pass \c Nothing
- /// if you don't care about a particular parameter. Blob data is not included
- /// in the buffer and should be handled separately by the caller.
- template <typename ElementTy, typename... Data>
- static void readRecord(ArrayRef<ElementTy> buffer, Data &&...data) {
- static_assert(sizeof...(data) <= sizeof...(Fields),
- "Too many record elements");
- static_assert(sizeof...(Fields) <=
- sizeof...(data) + detail::has_blob<Fields...>::value,
- "Too few record elements");
- return detail::BCRecordCoding<Fields...>::read(buffer,
- std::forward<Data>(data)...);
- }
-
- /// Extract record data from \p buffer into the given data fields.
- ///
- /// Note that even fixed arguments must be specified here. Pass \c Nothing
- /// if you don't care about a particular parameter. Blob data is not included
- /// in the buffer and should be handled separately by the caller.
- template <typename BufferTy, typename... Data>
- static void readRecord(BufferTy &buffer, Data &&...data) {
- return readRecord(llvm::makeArrayRef(buffer), std::forward<Data>(data)...);
- }
-};
-
-/// A record with a fixed record code.
-template <unsigned RecordCode, typename... Fields>
-class BCRecordLayout
- : public BCGenericRecordLayout<BCLiteral<RecordCode>, Fields...> {
- using Base = BCGenericRecordLayout<BCLiteral<RecordCode>, Fields...>;
-
-public:
- enum : unsigned {
- /// The record code associated with this layout.
- Code = RecordCode
- };
-
- /// Create a layout and register it with the given bitstream writer.
- explicit BCRecordLayout(llvm::BitstreamWriter &Stream) : Base(Stream) {}
-
- /// Emit a record to the bitstream writer, using the given buffer for scratch
- /// space.
- ///
- /// Note that even fixed arguments must be specified here.
- template <typename BufferTy, typename... Data>
- void emit(BufferTy &buffer, Data &&...data) const {
- Base::emit(buffer, RecordCode, std::forward<Data>(data)...);
- }
-
- /// Emit a record identified by \p abbrCode to bitstream reader \p Stream,
- /// using \p buffer for scratch space.
- ///
- /// Note that even fixed arguments must be specified here. Currently, arrays
- /// and blobs can only be passed as StringRefs.
- template <typename BufferTy, typename... Data>
- static void emitRecord(llvm::BitstreamWriter &Stream, BufferTy &buffer,
- unsigned abbrCode, Data &&...data) {
- Base::emitRecord(Stream, buffer, abbrCode, RecordCode,
- std::forward<Data>(data)...);
- }
-};
-
-/// RAII object to pair entering and exiting a sub-block.
-class BCBlockRAII {
- llvm::BitstreamWriter &Stream;
-
-public:
- BCBlockRAII(llvm::BitstreamWriter &Stream, unsigned block, unsigned abbrev)
- : Stream(Stream) {
- Stream.EnterSubblock(block, abbrev);
- }
-
- ~BCBlockRAII() { Stream.ExitBlock(); }
-};
-} // namespace llvm
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- llvm/Bitcode/BitcodeConvenience.h - Convenience Wrappers -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file Convenience wrappers for the LLVM bitcode format and bitstream APIs.
+///
+/// This allows you to use a sort of DSL to declare and use bitcode
+/// abbreviations and records. Example:
+///
+/// \code
+/// using Metadata = BCRecordLayout<
+/// METADATA_ID, // ID
+/// BCFixed<16>, // Module format major version
+/// BCFixed<16>, // Module format minor version
+/// BCBlob // misc. version information
+/// >;
+/// Metadata metadata(Out);
+/// metadata.emit(ScratchRecord, VERSION_MAJOR, VERSION_MINOR, Data);
+/// \endcode
+///
+/// For details on the bitcode format, see
+/// http://llvm.org/docs/BitCodeFormat.html
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_BITCODECONVENIENCE_H
+#define LLVM_BITCODE_BITCODECONVENIENCE_H
+
+#include "llvm/Bitstream/BitCodes.h"
+#include "llvm/Bitstream/BitstreamWriter.h"
+#include <cstdint>
+
+namespace llvm {
+namespace detail {
+/// Convenience base for all kinds of bitcode abbreviation fields.
+///
+/// This just defines common properties queried by the metaprogramming.
+template <bool Compound = false> class BCField {
+public:
+ static const bool IsCompound = Compound;
+
+ /// Asserts that the given data is a valid value for this field.
+ template <typename T> static void assertValid(const T &data) {}
+
+ /// Converts a raw numeric representation of this value to its preferred
+ /// type.
+ template <typename T> static T convert(T rawValue) { return rawValue; }
+};
+} // namespace detail
+
+/// Represents a literal operand in a bitcode record.
+///
+/// The value of a literal operand is the same for all instances of the record,
+/// so it is only emitted in the abbreviation definition.
+///
+/// Note that because this uses a compile-time template, you cannot have a
+/// literal operand that is fixed at run-time without dropping down to the
+/// raw LLVM APIs.
+template <uint64_t Value> class BCLiteral : public detail::BCField<> {
+public:
+ static void emitOp(llvm::BitCodeAbbrev &abbrev) {
+ abbrev.Add(llvm::BitCodeAbbrevOp(Value));
+ }
+
+ template <typename T> static void assertValid(const T &data) {
+ assert(data == Value && "data value does not match declared literal value");
+ }
+};
+
+/// Represents a fixed-width value in a bitcode record.
+///
+/// Note that the LLVM bitcode format only supports unsigned values.
+template <unsigned Width> class BCFixed : public detail::BCField<> {
+public:
+ static_assert(Width <= 64, "fixed-width field is too large");
+
+ static void emitOp(llvm::BitCodeAbbrev &abbrev) {
+ abbrev.Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, Width));
+ }
+
+ static void assertValid(const bool &data) {
+ assert(llvm::isUInt<Width>(data) &&
+ "data value does not fit in the given bit width");
+ }
+
+ template <typename T> static void assertValid(const T &data) {
+ assert(data >= 0 && "cannot encode signed integers");
+ assert(llvm::isUInt<Width>(data) &&
+ "data value does not fit in the given bit width");
+ }
+};
+
+/// Represents a variable-width value in a bitcode record.
+///
+/// The \p Width parameter should include the continuation bit.
+///
+/// Note that the LLVM bitcode format only supports unsigned values.
+template <unsigned Width> class BCVBR : public detail::BCField<> {
+ static_assert(Width >= 2, "width does not have room for continuation bit");
+
+public:
+ static void emitOp(llvm::BitCodeAbbrev &abbrev) {
+ abbrev.Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, Width));
+ }
+
+ template <typename T> static void assertValid(const T &data) {
+ assert(data >= 0 && "cannot encode signed integers");
+ }
+};
+
+/// Represents a character encoded in LLVM's Char6 encoding.
+///
+/// This format is suitable for encoding decimal numbers (without signs or
+/// exponents) and C identifiers (without dollar signs), but not much else.
+///
+/// \sa http://llvm.org/docs/BitCodeFormat.html#char6-encoded-value
+class BCChar6 : public detail::BCField<> {
+public:
+ static void emitOp(llvm::BitCodeAbbrev &abbrev) {
+ abbrev.Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Char6));
+ }
+
+ template <typename T> static void assertValid(const T &data) {
+ assert(llvm::BitCodeAbbrevOp::isChar6(data) && "invalid Char6 data");
+ }
+
+ template <typename T> char convert(T rawValue) {
+ return static_cast<char>(rawValue);
+ }
+};
+
+/// Represents an untyped blob of bytes.
+///
+/// If present, this must be the last field in a record.
+class BCBlob : public detail::BCField<true> {
+public:
+ static void emitOp(llvm::BitCodeAbbrev &abbrev) {
+ abbrev.Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
+ }
+};
+
+/// Represents an array of some other type.
+///
+/// If present, this must be the last field in a record.
+template <typename ElementTy> class BCArray : public detail::BCField<true> {
+ static_assert(!ElementTy::IsCompound, "arrays can only contain scalar types");
+
+public:
+ static void emitOp(llvm::BitCodeAbbrev &abbrev) {
+ abbrev.Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Array));
+ ElementTy::emitOp(abbrev);
+ }
+};
+
+namespace detail {
+/// Attaches the last field to an abbreviation.
+///
+/// This is the base case for \c emitOps.
+///
+/// \sa BCRecordLayout::emitAbbrev
+template <typename FieldTy> static void emitOps(llvm::BitCodeAbbrev &abbrev) {
+ FieldTy::emitOp(abbrev);
+}
+
+/// Attaches fields to an abbreviation.
+///
+/// This is the recursive case for \c emitOps.
+///
+/// \sa BCRecordLayout::emitAbbrev
+template <typename FieldTy, typename Next, typename... Rest>
+static void emitOps(llvm::BitCodeAbbrev &abbrev) {
+ static_assert(!FieldTy::IsCompound,
+ "arrays and blobs may not appear in the middle of a record");
+ FieldTy::emitOp(abbrev);
+ emitOps<Next, Rest...>(abbrev);
+}
+
+/// Helper class for dealing with a scalar element in the middle of a record.
+///
+/// \sa BCRecordLayout
+template <typename ElementTy, typename... Fields> class BCRecordCoding {
+public:
+ template <typename BufferTy, typename ElementDataTy, typename... DataTy>
+ static void emit(llvm::BitstreamWriter &Stream, BufferTy &buffer,
+ unsigned code, ElementDataTy element, DataTy &&...data) {
+ static_assert(!ElementTy::IsCompound,
+ "arrays and blobs may not appear in the middle of a record");
+ ElementTy::assertValid(element);
+ buffer.push_back(element);
+ BCRecordCoding<Fields...>::emit(Stream, buffer, code,
+ std::forward<DataTy>(data)...);
+ }
+
+ template <typename T, typename ElementDataTy, typename... DataTy>
+ static void read(ArrayRef<T> buffer, ElementDataTy &element,
+ DataTy &&...data) {
+ assert(!buffer.empty() && "too few elements in buffer");
+ element = ElementTy::convert(buffer.front());
+ BCRecordCoding<Fields...>::read(buffer.slice(1),
+ std::forward<DataTy>(data)...);
+ }
+
+ template <typename T, typename... DataTy>
+ static void read(ArrayRef<T> buffer, NoneType, DataTy &&...data) {
+ assert(!buffer.empty() && "too few elements in buffer");
+ BCRecordCoding<Fields...>::read(buffer.slice(1),
+ std::forward<DataTy>(data)...);
+ }
+};
+
+/// Helper class for dealing with a scalar element at the end of a record.
+///
+/// This has a separate implementation because up until now we've only been
+/// \em building the record (into a data buffer), and now we need to hand it
+/// off to the BitstreamWriter to be emitted.
+///
+/// \sa BCRecordLayout
+template <typename ElementTy> class BCRecordCoding<ElementTy> {
+public:
+ template <typename BufferTy, typename DataTy>
+ static void emit(llvm::BitstreamWriter &Stream, BufferTy &buffer,
+ unsigned code, const DataTy &data) {
+ static_assert(!ElementTy::IsCompound,
+ "arrays and blobs need special handling");
+ ElementTy::assertValid(data);
+ buffer.push_back(data);
+ Stream.EmitRecordWithAbbrev(code, buffer);
+ }
+
+ template <typename T, typename DataTy>
+ static void read(ArrayRef<T> buffer, DataTy &data) {
+ assert(buffer.size() == 1 && "record data does not match layout");
+ data = ElementTy::convert(buffer.front());
+ }
+
+ template <typename T> static void read(ArrayRef<T> buffer, NoneType) {
+ assert(buffer.size() == 1 && "record data does not match layout");
+ (void)buffer;
+ }
+
+ template <typename T> static void read(ArrayRef<T> buffer) = delete;
+};
+
+/// Helper class for dealing with an array at the end of a record.
+///
+/// \sa BCRecordLayout::emitRecord
+template <typename ElementTy> class BCRecordCoding<BCArray<ElementTy>> {
+public:
+ template <typename BufferTy>
+ static void emit(llvm::BitstreamWriter &Stream, BufferTy &buffer,
+ unsigned code, StringRef data) {
+ // TODO: validate array data.
+ Stream.EmitRecordWithArray(code, buffer, data);
+ }
+
+ template <typename BufferTy, typename ArrayTy>
+ static void emit(llvm::BitstreamWriter &Stream, BufferTy &buffer,
+ unsigned code, const ArrayTy &array) {
+#ifndef NDEBUG
+ for (auto &element : array)
+ ElementTy::assertValid(element);
+#endif
+ buffer.reserve(buffer.size() + std::distance(array.begin(), array.end()));
+ std::copy(array.begin(), array.end(), std::back_inserter(buffer));
+ Stream.EmitRecordWithAbbrev(code, buffer);
+ }
+
+ template <typename BufferTy, typename ElementDataTy, typename... DataTy>
+ static void emit(llvm::BitstreamWriter &Stream, BufferTy &buffer,
+ unsigned code, ElementDataTy element, DataTy... data) {
+ std::array<ElementDataTy, 1 + sizeof...(data)> array{{element, data...}};
+ emit(Stream, buffer, code, array);
+ }
+
+ template <typename BufferTy>
+ static void emit(llvm::BitstreamWriter &Stream, BufferTy &Buffer,
+ unsigned code, NoneType) {
+ Stream.EmitRecordWithAbbrev(code, Buffer);
+ }
+
+ template <typename T>
+ static void read(ArrayRef<T> Buffer, ArrayRef<T> &rawData) {
+ rawData = Buffer;
+ }
+
+ template <typename T, typename ArrayTy>
+ static void read(ArrayRef<T> buffer, ArrayTy &array) {
+ array.append(llvm::map_iterator(buffer.begin(), T::convert),
+ llvm::map_iterator(buffer.end(), T::convert));
+ }
+
+ template <typename T> static void read(ArrayRef<T> buffer, NoneType) {
+ (void)buffer;
+ }
+
+ template <typename T> static void read(ArrayRef<T> buffer) = delete;
+};
+
+/// Helper class for dealing with a blob at the end of a record.
+///
+/// \sa BCRecordLayout
+template <> class BCRecordCoding<BCBlob> {
+public:
+ template <typename BufferTy>
+ static void emit(llvm::BitstreamWriter &Stream, BufferTy &buffer,
+ unsigned code, StringRef data) {
+ Stream.EmitRecordWithBlob(code, buffer, data);
+ }
+
+ template <typename T> static void read(ArrayRef<T> buffer) { (void)buffer; }
+
+ /// Blob data is not stored in the buffer if you are using the correct
+ /// accessor; this method should not be used.
+ template <typename T, typename DataTy>
+ static void read(ArrayRef<T> buffer, DataTy &data) = delete;
+};
+
+/// A type trait whose \c type field is the last of its template parameters.
+template <typename Head, typename... Tail> struct last_type {
+ using type = typename last_type<Tail...>::type;
+};
+
+template <typename Head> struct last_type<Head> { using type = Head; };
+
+/// A type trait whose \c value field is \c true if the last type is BCBlob.
+template <typename... Types>
+using has_blob = std::is_same<BCBlob, typename last_type<int, Types...>::type>;
+
+/// A type trait whose \c value field is \c true if the given type is a
+/// BCArray (of any element kind).
+template <typename T> struct is_array {
+private:
+ template <typename E> static bool check(BCArray<E> *);
+ static int check(...);
+
+public:
+ typedef bool value_type;
+ static constexpr bool value = !std::is_same<decltype(check((T *)nullptr)),
+ decltype(check(false))>::value;
+};
+
+/// A type trait whose \c value field is \c true if the last type is a
+/// BCArray (of any element kind).
+template <typename... Types>
+using has_array = is_array<typename last_type<int, Types...>::type>;
+} // namespace detail
+
+/// Represents a single bitcode record type.
+///
+/// This class template is meant to be instantiated and then given a name,
+/// so that from then on that name can be used.
+template <typename IDField, typename... Fields> class BCGenericRecordLayout {
+ llvm::BitstreamWriter &Stream;
+
+public:
+ /// The abbreviation code used for this record in the current block.
+ ///
+ /// Note that this is not the same as the semantic record code, which is the
+ /// first field of the record.
+ const unsigned AbbrevCode;
+
+ /// Create a layout and register it with the given bitstream writer.
+ explicit BCGenericRecordLayout(llvm::BitstreamWriter &Stream)
+ : Stream(Stream), AbbrevCode(emitAbbrev(Stream)) {}
+
+ /// Emit a record to the bitstream writer, using the given buffer for scratch
+ /// space.
+ ///
+ /// Note that even fixed arguments must be specified here.
+ template <typename BufferTy, typename... Data>
+ void emit(BufferTy &buffer, unsigned id, Data &&...data) const {
+ emitRecord(Stream, buffer, AbbrevCode, id, std::forward<Data>(data)...);
+ }
+
+ /// Registers this record's layout with the bitstream reader.
+ ///
+ /// eturns The abbreviation code for the newly-registered record type.
+ static unsigned emitAbbrev(llvm::BitstreamWriter &Stream) {
+ auto Abbrev = std::make_shared<llvm::BitCodeAbbrev>();
+ detail::emitOps<IDField, Fields...>(*Abbrev);
+ return Stream.EmitAbbrev(std::move(Abbrev));
+ }
+
+ /// Emit a record identified by \p abbrCode to bitstream reader \p Stream,
+ /// using \p buffer for scratch space.
+ ///
+ /// Note that even fixed arguments must be specified here. Blobs are passed
+ /// as StringRefs, while arrays can be passed inline, as aggregates, or as
+ /// pre-encoded StringRef data. Skipped values and empty arrays should use
+ /// the special Nothing value.
+ template <typename BufferTy, typename... Data>
+ static void emitRecord(llvm::BitstreamWriter &Stream, BufferTy &buffer,
+ unsigned abbrCode, unsigned recordID, Data &&...data) {
+ static_assert(sizeof...(data) <= sizeof...(Fields) ||
+ detail::has_array<Fields...>::value,
+ "Too many record elements");
+ static_assert(sizeof...(data) >= sizeof...(Fields),
+ "Too few record elements");
+ buffer.clear();
+ detail::BCRecordCoding<IDField, Fields...>::emit(
+ Stream, buffer, abbrCode, recordID, std::forward<Data>(data)...);
+ }
+
+ /// Extract record data from \p buffer into the given data fields.
+ ///
+ /// Note that even fixed arguments must be specified here. Pass \c Nothing
+ /// if you don't care about a particular parameter. Blob data is not included
+ /// in the buffer and should be handled separately by the caller.
+ template <typename ElementTy, typename... Data>
+ static void readRecord(ArrayRef<ElementTy> buffer, Data &&...data) {
+ static_assert(sizeof...(data) <= sizeof...(Fields),
+ "Too many record elements");
+ static_assert(sizeof...(Fields) <=
+ sizeof...(data) + detail::has_blob<Fields...>::value,
+ "Too few record elements");
+ return detail::BCRecordCoding<Fields...>::read(buffer,
+ std::forward<Data>(data)...);
+ }
+
+ /// Extract record data from \p buffer into the given data fields.
+ ///
+ /// Note that even fixed arguments must be specified here. Pass \c Nothing
+ /// if you don't care about a particular parameter. Blob data is not included
+ /// in the buffer and should be handled separately by the caller.
+ template <typename BufferTy, typename... Data>
+ static void readRecord(BufferTy &buffer, Data &&...data) {
+ return readRecord(llvm::makeArrayRef(buffer), std::forward<Data>(data)...);
+ }
+};
+
+/// A record with a fixed record code.
+template <unsigned RecordCode, typename... Fields>
+class BCRecordLayout
+ : public BCGenericRecordLayout<BCLiteral<RecordCode>, Fields...> {
+ using Base = BCGenericRecordLayout<BCLiteral<RecordCode>, Fields...>;
+
+public:
+ enum : unsigned {
+ /// The record code associated with this layout.
+ Code = RecordCode
+ };
+
+ /// Create a layout and register it with the given bitstream writer.
+ explicit BCRecordLayout(llvm::BitstreamWriter &Stream) : Base(Stream) {}
+
+ /// Emit a record to the bitstream writer, using the given buffer for scratch
+ /// space.
+ ///
+ /// Note that even fixed arguments must be specified here.
+ template <typename BufferTy, typename... Data>
+ void emit(BufferTy &buffer, Data &&...data) const {
+ Base::emit(buffer, RecordCode, std::forward<Data>(data)...);
+ }
+
+ /// Emit a record identified by \p abbrCode to bitstream reader \p Stream,
+ /// using \p buffer for scratch space.
+ ///
+ /// Note that even fixed arguments must be specified here. Currently, arrays
+ /// and blobs can only be passed as StringRefs.
+ template <typename BufferTy, typename... Data>
+ static void emitRecord(llvm::BitstreamWriter &Stream, BufferTy &buffer,
+ unsigned abbrCode, Data &&...data) {
+ Base::emitRecord(Stream, buffer, abbrCode, RecordCode,
+ std::forward<Data>(data)...);
+ }
+};
+
+/// RAII object to pair entering and exiting a sub-block.
+class BCBlockRAII {
+ llvm::BitstreamWriter &Stream;
+
+public:
+ BCBlockRAII(llvm::BitstreamWriter &Stream, unsigned block, unsigned abbrev)
+ : Stream(Stream) {
+ Stream.EnterSubblock(block, abbrev);
+ }
+
+ ~BCBlockRAII() { Stream.ExitBlock(); }
+};
+} // namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Bitcode/BitcodeWriter.h b/contrib/libs/llvm12/include/llvm/Bitcode/BitcodeWriter.h
index 0a1df1b70b..ad9e44a8d7 100644
--- a/contrib/libs/llvm12/include/llvm/Bitcode/BitcodeWriter.h
+++ b/contrib/libs/llvm12/include/llvm/Bitcode/BitcodeWriter.h
@@ -54,7 +54,7 @@ class raw_ostream;
public:
/// Create a BitcodeWriter that writes to Buffer.
- BitcodeWriter(SmallVectorImpl<char> &Buffer, raw_fd_stream *FS = nullptr);
+ BitcodeWriter(SmallVectorImpl<char> &Buffer, raw_fd_stream *FS = nullptr);
~BitcodeWriter();
@@ -159,18 +159,18 @@ class raw_ostream;
const std::map<std::string, GVSummaryMapTy>
*ModuleToSummariesForIndex = nullptr);
- /// If EmbedBitcode is set, save a copy of the llvm IR as data in the
- /// __LLVM,__bitcode section (.llvmbc on non-MacOS).
- /// If available, pass the serialized module via the Buf parameter. If not,
- /// pass an empty (default-initialized) MemoryBufferRef, and the serialization
- /// will be handled by this API. The same behavior happens if the provided Buf
- /// is not bitcode (i.e. if it's invalid data or even textual LLVM assembly).
- /// If EmbedCmdline is set, the command line is also exported in
- /// the corresponding section (__LLVM,_cmdline / .llvmcmd) - even if CmdArgs
- /// were empty.
+ /// If EmbedBitcode is set, save a copy of the llvm IR as data in the
+ /// __LLVM,__bitcode section (.llvmbc on non-MacOS).
+ /// If available, pass the serialized module via the Buf parameter. If not,
+ /// pass an empty (default-initialized) MemoryBufferRef, and the serialization
+ /// will be handled by this API. The same behavior happens if the provided Buf
+ /// is not bitcode (i.e. if it's invalid data or even textual LLVM assembly).
+ /// If EmbedCmdline is set, the command line is also exported in
+ /// the corresponding section (__LLVM,_cmdline / .llvmcmd) - even if CmdArgs
+ /// were empty.
void EmbedBitcodeInModule(Module &M, MemoryBufferRef Buf, bool EmbedBitcode,
- bool EmbedCmdline,
- const std::vector<uint8_t> &CmdArgs);
+ bool EmbedCmdline,
+ const std::vector<uint8_t> &CmdArgs);
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Bitcode/LLVMBitCodes.h b/contrib/libs/llvm12/include/llvm/Bitcode/LLVMBitCodes.h
index a770e11fe6..c7566c85e3 100644
--- a/contrib/libs/llvm12/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/contrib/libs/llvm12/include/llvm/Bitcode/LLVMBitCodes.h
@@ -175,8 +175,8 @@ enum TypeCodes {
TYPE_CODE_TOKEN = 22, // TOKEN
- TYPE_CODE_BFLOAT = 23, // BRAIN FLOATING POINT
- TYPE_CODE_X86_AMX = 24 // X86 AMX
+ TYPE_CODE_BFLOAT = 23, // BRAIN FLOATING POINT
+ TYPE_CODE_X86_AMX = 24 // X86 AMX
};
enum OperandBundleTagCode {
@@ -346,11 +346,11 @@ enum MetadataCodes {
METADATA_INDEX_OFFSET = 38, // [offset]
METADATA_INDEX = 39, // [bitpos]
METADATA_LABEL = 40, // [distinct, scope, name, file, line]
- METADATA_STRING_TYPE = 41, // [distinct, name, size, align,...]
- // Codes 42 and 43 are reserved for support for Fortran array specific debug
- // info.
- METADATA_COMMON_BLOCK = 44, // [distinct, scope, name, variable,...]
- METADATA_GENERIC_SUBRANGE = 45 // [distinct, count, lo, up, stride]
+ METADATA_STRING_TYPE = 41, // [distinct, name, size, align,...]
+ // Codes 42 and 43 are reserved for support for Fortran array specific debug
+ // info.
+ METADATA_COMMON_BLOCK = 44, // [distinct, scope, name, variable,...]
+ METADATA_GENERIC_SUBRANGE = 45 // [distinct, count, lo, up, stride]
};
// The constants block (CONSTANTS_BLOCK_ID) describes emission for each
@@ -383,7 +383,7 @@ enum ConstantsCodes {
// asmdialect,asmstr,conststr]
CST_CODE_CE_GEP_WITH_INRANGE_INDEX = 24, // [opty, flags, n x operands]
CST_CODE_CE_UNOP = 25, // CE_UNOP: [opcode, opval]
- CST_CODE_POISON = 26, // POISON
+ CST_CODE_POISON = 26, // POISON
};
/// CastOpcodes - These are values used in the bitcode files to encode which
@@ -549,9 +549,9 @@ enum FunctionCodes {
FUNC_CODE_DEBUG_LOC = 35, // DEBUG_LOC: [Line,Col,ScopeVal, IAVal]
FUNC_CODE_INST_FENCE = 36, // FENCE: [ordering, synchscope]
- FUNC_CODE_INST_CMPXCHG_OLD = 37, // CMPXCHG: [ptrty, ptr, cmp, val, vol,
- // ordering, synchscope,
- // failure_ordering?, weak?]
+ FUNC_CODE_INST_CMPXCHG_OLD = 37, // CMPXCHG: [ptrty, ptr, cmp, val, vol,
+ // ordering, synchscope,
+ // failure_ordering?, weak?]
FUNC_CODE_INST_ATOMICRMW = 38, // ATOMICRMW: [ptrty,ptr,val, operation,
// align, vol,
// ordering, synchscope]
@@ -565,9 +565,9 @@ enum FunctionCodes {
FUNC_CODE_INST_GEP = 43, // GEP: [inbounds, n x operands]
FUNC_CODE_INST_STORE = 44, // STORE: [ptrty,ptr,valty,val, align, vol]
FUNC_CODE_INST_STOREATOMIC = 45, // STORE: [ptrty,ptr,val, align, vol
- FUNC_CODE_INST_CMPXCHG = 46, // CMPXCHG: [ptrty, ptr, cmp, val, vol,
- // success_ordering, synchscope,
- // failure_ordering, weak]
+ FUNC_CODE_INST_CMPXCHG = 46, // CMPXCHG: [ptrty, ptr, cmp, val, vol,
+ // success_ordering, synchscope,
+ // failure_ordering, weak]
FUNC_CODE_INST_LANDINGPAD = 47, // LANDINGPAD: [ty,val,num,id0,val0...]
FUNC_CODE_INST_CLEANUPRET = 48, // CLEANUPRET: [val] or [val,bb#]
FUNC_CODE_INST_CATCHRET = 49, // CATCHRET: [val,bb#]
@@ -659,11 +659,11 @@ enum AttributeKindCodes {
ATTR_KIND_NO_MERGE = 66,
ATTR_KIND_NULL_POINTER_IS_VALID = 67,
ATTR_KIND_NOUNDEF = 68,
- ATTR_KIND_BYREF = 69,
- ATTR_KIND_MUSTPROGRESS = 70,
- ATTR_KIND_NO_CALLBACK = 71,
- ATTR_KIND_HOT = 72,
- ATTR_KIND_NO_PROFILE = 73,
+ ATTR_KIND_BYREF = 69,
+ ATTR_KIND_MUSTPROGRESS = 70,
+ ATTR_KIND_NO_CALLBACK = 71,
+ ATTR_KIND_HOT = 72,
+ ATTR_KIND_NO_PROFILE = 73,
};
enum ComdatSelectionKindCodes {
diff --git a/contrib/libs/llvm12/include/llvm/Bitstream/BitCodes.h b/contrib/libs/llvm12/include/llvm/Bitstream/BitCodes.h
index ba33d3760d..5132bc5df0 100644
--- a/contrib/libs/llvm12/include/llvm/Bitstream/BitCodes.h
+++ b/contrib/libs/llvm12/include/llvm/Bitstream/BitCodes.h
@@ -25,7 +25,7 @@
#define LLVM_BITSTREAM_BITCODES_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
@@ -145,7 +145,7 @@ public:
}
/// isChar6 - Return true if this character is legal in the Char6 encoding.
- static bool isChar6(char C) { return isAlnum(C) || C == '.' || C == '_'; }
+ static bool isChar6(char C) { return isAlnum(C) || C == '.' || C == '_'; }
static unsigned EncodeChar6(char C) {
if (C >= 'a' && C <= 'z') return C-'a';
if (C >= 'A' && C <= 'Z') return C-'A'+26;
diff --git a/contrib/libs/llvm12/include/llvm/Bitstream/BitstreamWriter.h b/contrib/libs/llvm12/include/llvm/Bitstream/BitstreamWriter.h
index 1a8d1c22d3..dc4c1ff1ef 100644
--- a/contrib/libs/llvm12/include/llvm/Bitstream/BitstreamWriter.h
+++ b/contrib/libs/llvm12/include/llvm/Bitstream/BitstreamWriter.h
@@ -27,28 +27,28 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Bitstream/BitCodes.h"
#include "llvm/Support/Endian.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
#include <vector>
namespace llvm {
class BitstreamWriter {
- /// Out - The buffer that keeps unflushed bytes.
+ /// Out - The buffer that keeps unflushed bytes.
SmallVectorImpl<char> &Out;
- /// FS - The file stream that Out flushes to. If FS is nullptr, it does not
- /// support read or seek, Out cannot be flushed until all data are written.
- raw_fd_stream *FS;
-
- /// FlushThreshold - If FS is valid, this is the threshold (unit B) to flush
- /// FS.
- const uint64_t FlushThreshold;
-
+ /// FS - The file stream that Out flushes to. If FS is nullptr, it does not
+ /// support read or seek, Out cannot be flushed until all data are written.
+ raw_fd_stream *FS;
+
+ /// FlushThreshold - If FS is valid, this is the threshold (unit B) to flush
+ /// FS.
+ const uint64_t FlushThreshold;
+
/// CurBit - Always between 0 and 31 inclusive, specifies the next bit to use.
unsigned CurBit;
- /// CurValue - The current value. Only bits < CurBit are valid.
+ /// CurValue - The current value. Only bits < CurBit are valid.
uint32_t CurValue;
/// CurCodeSize - This is the declared size of code values used for the
@@ -82,49 +82,49 @@ class BitstreamWriter {
void WriteByte(unsigned char Value) {
Out.push_back(Value);
- FlushToFile();
+ FlushToFile();
}
void WriteWord(unsigned Value) {
Value = support::endian::byte_swap<uint32_t, support::little>(Value);
Out.append(reinterpret_cast<const char *>(&Value),
reinterpret_cast<const char *>(&Value + 1));
- FlushToFile();
+ FlushToFile();
}
- uint64_t GetNumOfFlushedBytes() const { return FS ? FS->tell() : 0; }
+ uint64_t GetNumOfFlushedBytes() const { return FS ? FS->tell() : 0; }
+
+ size_t GetBufferOffset() const { return Out.size() + GetNumOfFlushedBytes(); }
- size_t GetBufferOffset() const { return Out.size() + GetNumOfFlushedBytes(); }
-
size_t GetWordIndex() const {
size_t Offset = GetBufferOffset();
assert((Offset & 3) == 0 && "Not 32-bit aligned");
return Offset / 4;
}
- /// If the related file stream supports reading, seeking and writing, flush
- /// the buffer if its size is above a threshold.
- void FlushToFile() {
- if (!FS)
- return;
- if (Out.size() < FlushThreshold)
- return;
- FS->write((char *)&Out.front(), Out.size());
- Out.clear();
- }
-
+ /// If the related file stream supports reading, seeking and writing, flush
+ /// the buffer if its size is above a threshold.
+ void FlushToFile() {
+ if (!FS)
+ return;
+ if (Out.size() < FlushThreshold)
+ return;
+ FS->write((char *)&Out.front(), Out.size());
+ Out.clear();
+ }
+
public:
- /// Create a BitstreamWriter that writes to Buffer \p O.
- ///
- /// \p FS is the file stream that \p O flushes to incrementally. If \p FS is
- /// null, \p O does not flush incrementially, but writes to disk at the end.
- ///
- /// \p FlushThreshold is the threshold (unit M) to flush \p O if \p FS is
- /// valid.
- BitstreamWriter(SmallVectorImpl<char> &O, raw_fd_stream *FS = nullptr,
- uint32_t FlushThreshold = 512)
- : Out(O), FS(FS), FlushThreshold(FlushThreshold << 20), CurBit(0),
- CurValue(0), CurCodeSize(2) {}
+ /// Create a BitstreamWriter that writes to Buffer \p O.
+ ///
+ /// \p FS is the file stream that \p O flushes to incrementally. If \p FS is
+ /// null, \p O does not flush incrementially, but writes to disk at the end.
+ ///
+ /// \p FlushThreshold is the threshold (unit M) to flush \p O if \p FS is
+ /// valid.
+ BitstreamWriter(SmallVectorImpl<char> &O, raw_fd_stream *FS = nullptr,
+ uint32_t FlushThreshold = 512)
+ : Out(O), FS(FS), FlushThreshold(FlushThreshold << 20), CurBit(0),
+ CurValue(0), CurCodeSize(2) {}
~BitstreamWriter() {
assert(CurBit == 0 && "Unflushed data remaining");
@@ -145,60 +145,60 @@ public:
/// with the specified value.
void BackpatchWord(uint64_t BitNo, unsigned NewWord) {
using namespace llvm::support;
- uint64_t ByteNo = BitNo / 8;
- uint64_t StartBit = BitNo & 7;
- uint64_t NumOfFlushedBytes = GetNumOfFlushedBytes();
-
- if (ByteNo >= NumOfFlushedBytes) {
- assert((!endian::readAtBitAlignment<uint32_t, little, unaligned>(
- &Out[ByteNo - NumOfFlushedBytes], StartBit)) &&
- "Expected to be patching over 0-value placeholders");
- endian::writeAtBitAlignment<uint32_t, little, unaligned>(
- &Out[ByteNo - NumOfFlushedBytes], NewWord, StartBit);
- return;
- }
-
- // If the byte offset to backpatch is flushed, use seek to backfill data.
- // First, save the file position to restore later.
- uint64_t CurPos = FS->tell();
-
- // Copy data to update into Bytes from the file FS and the buffer Out.
- char Bytes[9]; // Use one more byte to silence a warning from Visual C++.
- size_t BytesNum = StartBit ? 8 : 4;
- size_t BytesFromDisk = std::min(static_cast<uint64_t>(BytesNum), NumOfFlushedBytes - ByteNo);
- size_t BytesFromBuffer = BytesNum - BytesFromDisk;
-
- // When unaligned, copy existing data into Bytes from the file FS and the
- // buffer Out so that it can be updated before writing. For debug builds
- // read bytes unconditionally in order to check that the existing value is 0
- // as expected.
-#ifdef NDEBUG
- if (StartBit)
-#endif
- {
- FS->seek(ByteNo);
- ssize_t BytesRead = FS->read(Bytes, BytesFromDisk);
- (void)BytesRead; // silence warning
- assert(BytesRead >= 0 && static_cast<size_t>(BytesRead) == BytesFromDisk);
- for (size_t i = 0; i < BytesFromBuffer; ++i)
- Bytes[BytesFromDisk + i] = Out[i];
- assert((!endian::readAtBitAlignment<uint32_t, little, unaligned>(
- Bytes, StartBit)) &&
- "Expected to be patching over 0-value placeholders");
- }
-
- // Update Bytes in terms of bit offset and value.
- endian::writeAtBitAlignment<uint32_t, little, unaligned>(Bytes, NewWord,
- StartBit);
-
- // Copy updated data back to the file FS and the buffer Out.
- FS->seek(ByteNo);
- FS->write(Bytes, BytesFromDisk);
- for (size_t i = 0; i < BytesFromBuffer; ++i)
- Out[i] = Bytes[BytesFromDisk + i];
-
- // Restore the file position.
- FS->seek(CurPos);
+ uint64_t ByteNo = BitNo / 8;
+ uint64_t StartBit = BitNo & 7;
+ uint64_t NumOfFlushedBytes = GetNumOfFlushedBytes();
+
+ if (ByteNo >= NumOfFlushedBytes) {
+ assert((!endian::readAtBitAlignment<uint32_t, little, unaligned>(
+ &Out[ByteNo - NumOfFlushedBytes], StartBit)) &&
+ "Expected to be patching over 0-value placeholders");
+ endian::writeAtBitAlignment<uint32_t, little, unaligned>(
+ &Out[ByteNo - NumOfFlushedBytes], NewWord, StartBit);
+ return;
+ }
+
+ // If the byte offset to backpatch is flushed, use seek to backfill data.
+ // First, save the file position to restore later.
+ uint64_t CurPos = FS->tell();
+
+ // Copy data to update into Bytes from the file FS and the buffer Out.
+ char Bytes[9]; // Use one more byte to silence a warning from Visual C++.
+ size_t BytesNum = StartBit ? 8 : 4;
+ size_t BytesFromDisk = std::min(static_cast<uint64_t>(BytesNum), NumOfFlushedBytes - ByteNo);
+ size_t BytesFromBuffer = BytesNum - BytesFromDisk;
+
+ // When unaligned, copy existing data into Bytes from the file FS and the
+ // buffer Out so that it can be updated before writing. For debug builds
+ // read bytes unconditionally in order to check that the existing value is 0
+ // as expected.
+#ifdef NDEBUG
+ if (StartBit)
+#endif
+ {
+ FS->seek(ByteNo);
+ ssize_t BytesRead = FS->read(Bytes, BytesFromDisk);
+ (void)BytesRead; // silence warning
+ assert(BytesRead >= 0 && static_cast<size_t>(BytesRead) == BytesFromDisk);
+ for (size_t i = 0; i < BytesFromBuffer; ++i)
+ Bytes[BytesFromDisk + i] = Out[i];
+ assert((!endian::readAtBitAlignment<uint32_t, little, unaligned>(
+ Bytes, StartBit)) &&
+ "Expected to be patching over 0-value placeholders");
+ }
+
+ // Update Bytes in terms of bit offset and value.
+ endian::writeAtBitAlignment<uint32_t, little, unaligned>(Bytes, NewWord,
+ StartBit);
+
+ // Copy updated data back to the file FS and the buffer Out.
+ FS->seek(ByteNo);
+ FS->write(Bytes, BytesFromDisk);
+ for (size_t i = 0; i < BytesFromBuffer; ++i)
+ Out[i] = Bytes[BytesFromDisk + i];
+
+ // Restore the file position.
+ FS->seek(CurPos);
}
void BackpatchWord64(uint64_t BitNo, uint64_t Val) {
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/AsmPrinter.h b/contrib/libs/llvm12/include/llvm/CodeGen/AsmPrinter.h
index 8686c464fc..f95cbeb0e5 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/AsmPrinter.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/AsmPrinter.h
@@ -73,7 +73,7 @@ class MCSymbol;
class MCTargetOptions;
class MDNode;
class Module;
-class PseudoProbeHandler;
+class PseudoProbeHandler;
class raw_ostream;
class StackMaps;
class StringRef;
@@ -147,31 +147,31 @@ public:
using GOTEquivUsePair = std::pair<const GlobalVariable *, unsigned>;
MapVector<const MCSymbol *, GOTEquivUsePair> GlobalGOTEquivs;
- /// struct HandlerInfo and Handlers permit users or target extended
- /// AsmPrinter to add their own handlers.
- struct HandlerInfo {
- std::unique_ptr<AsmPrinterHandler> Handler;
- const char *TimerName;
- const char *TimerDescription;
- const char *TimerGroupName;
- const char *TimerGroupDescription;
-
- HandlerInfo(std::unique_ptr<AsmPrinterHandler> Handler,
- const char *TimerName, const char *TimerDescription,
- const char *TimerGroupName, const char *TimerGroupDescription)
- : Handler(std::move(Handler)), TimerName(TimerName),
- TimerDescription(TimerDescription), TimerGroupName(TimerGroupName),
- TimerGroupDescription(TimerGroupDescription) {}
- };
-
+ /// struct HandlerInfo and Handlers permit users or target extended
+ /// AsmPrinter to add their own handlers.
+ struct HandlerInfo {
+ std::unique_ptr<AsmPrinterHandler> Handler;
+ const char *TimerName;
+ const char *TimerDescription;
+ const char *TimerGroupName;
+ const char *TimerGroupDescription;
+
+ HandlerInfo(std::unique_ptr<AsmPrinterHandler> Handler,
+ const char *TimerName, const char *TimerDescription,
+ const char *TimerGroupName, const char *TimerGroupDescription)
+ : Handler(std::move(Handler)), TimerName(TimerName),
+ TimerDescription(TimerDescription), TimerGroupName(TimerGroupName),
+ TimerGroupDescription(TimerGroupDescription) {}
+ };
+
private:
MCSymbol *CurrentFnEnd = nullptr;
- /// Map a basic block section ID to the exception symbol associated with that
- /// section. Map entries are assigned and looked up via
- /// AsmPrinter::getMBBExceptionSym.
- DenseMap<unsigned, MCSymbol *> MBBSectionExceptionSyms;
-
+ /// Map a basic block section ID to the exception symbol associated with that
+ /// section. Map entries are assigned and looked up via
+ /// AsmPrinter::getMBBExceptionSym.
+ DenseMap<unsigned, MCSymbol *> MBBSectionExceptionSyms;
+
// The symbol used to represent the start of the current BB section of the
// function. This is used to calculate the size of the BB section.
MCSymbol *CurrentSectionBeginSym = nullptr;
@@ -189,8 +189,8 @@ protected:
/// A vector of all debug/EH info emitters we should use. This vector
/// maintains ownership of the emitters.
- std::vector<HandlerInfo> Handlers;
- size_t NumUserHandlers = 0;
+ std::vector<HandlerInfo> Handlers;
+ size_t NumUserHandlers = 0;
public:
struct SrcMgrDiagInfo {
@@ -214,10 +214,10 @@ private:
/// If the target supports dwarf debug info, this pointer is non-null.
DwarfDebug *DD = nullptr;
- /// A handler that supports pseudo probe emission with embedded inline
- /// context.
- PseudoProbeHandler *PP = nullptr;
-
+ /// A handler that supports pseudo probe emission with embedded inline
+ /// context.
+ PseudoProbeHandler *PP = nullptr;
+
/// If the current module uses dwarf CFI annotations strictly for debugging.
bool isCFIMoveForDebugging = false;
@@ -233,14 +233,14 @@ public:
uint16_t getDwarfVersion() const;
void setDwarfVersion(uint16_t Version);
- bool isDwarf64() const;
-
- /// Returns 4 for DWARF32 and 8 for DWARF64.
- unsigned int getDwarfOffsetByteSize() const;
-
- /// Returns 4 for DWARF32 and 12 for DWARF64.
- unsigned int getUnitLengthFieldByteSize() const;
-
+ bool isDwarf64() const;
+
+ /// Returns 4 for DWARF32 and 8 for DWARF64.
+ unsigned int getDwarfOffsetByteSize() const;
+
+ /// Returns 4 for DWARF32 and 12 for DWARF64.
+ unsigned int getUnitLengthFieldByteSize() const;
+
bool isPositionIndependent() const;
/// Return true if assembly output should contain comments.
@@ -256,10 +256,10 @@ public:
MCSymbol *getFunctionBegin() const { return CurrentFnBegin; }
MCSymbol *getFunctionEnd() const { return CurrentFnEnd; }
- // Return the exception symbol associated with the MBB section containing a
- // given basic block.
- MCSymbol *getMBBExceptionSym(const MachineBasicBlock &MBB);
-
+ // Return the exception symbol associated with the MBB section containing a
+ // given basic block.
+ MCSymbol *getMBBExceptionSym(const MachineBasicBlock &MBB);
+
/// Return information about object file lowering.
const TargetLoweringObjectFile &getObjFileLowering() const;
@@ -370,10 +370,10 @@ public:
void emitStackSizeSection(const MachineFunction &MF);
- void emitBBAddrMapSection(const MachineFunction &MF);
-
- void emitPseudoProbe(const MachineInstr &MI);
-
+ void emitBBAddrMapSection(const MachineFunction &MF);
+
+ void emitPseudoProbe(const MachineInstr &MI);
+
void emitRemarksSection(remarks::RemarkStreamer &RS);
enum CFIMoveType { CFI_M_None, CFI_M_EH, CFI_M_Debug };
@@ -401,32 +401,32 @@ public:
/// so, emit it and return true, otherwise do nothing and return false.
bool emitSpecialLLVMGlobal(const GlobalVariable *GV);
- /// `llvm.global_ctors` and `llvm.global_dtors` are arrays of Structor
- /// structs.
- ///
- /// Priority - init priority
- /// Func - global initialization or global clean-up function
- /// ComdatKey - associated data
- struct Structor {
- int Priority = 0;
- Constant *Func = nullptr;
- GlobalValue *ComdatKey = nullptr;
-
- Structor() = default;
- };
-
- /// This method gathers an array of Structors and then sorts them out by
- /// Priority.
- /// @param List The initializer of `llvm.global_ctors` or `llvm.global_dtors`
- /// array.
- /// @param[out] Structors Sorted Structor structs by Priority.
- void preprocessXXStructorList(const DataLayout &DL, const Constant *List,
- SmallVector<Structor, 8> &Structors);
-
- /// This method emits `llvm.global_ctors` or `llvm.global_dtors` list.
- virtual void emitXXStructorList(const DataLayout &DL, const Constant *List,
- bool IsCtor);
-
+ /// `llvm.global_ctors` and `llvm.global_dtors` are arrays of Structor
+ /// structs.
+ ///
+ /// Priority - init priority
+ /// Func - global initialization or global clean-up function
+ /// ComdatKey - associated data
+ struct Structor {
+ int Priority = 0;
+ Constant *Func = nullptr;
+ GlobalValue *ComdatKey = nullptr;
+
+ Structor() = default;
+ };
+
+ /// This method gathers an array of Structors and then sorts them out by
+ /// Priority.
+ /// @param List The initializer of `llvm.global_ctors` or `llvm.global_dtors`
+ /// array.
+ /// @param[out] Structors Sorted Structor structs by Priority.
+ void preprocessXXStructorList(const DataLayout &DL, const Constant *List,
+ SmallVector<Structor, 8> &Structors);
+
+ /// This method emits `llvm.global_ctors` or `llvm.global_dtors` list.
+ virtual void emitXXStructorList(const DataLayout &DL, const Constant *List,
+ bool IsCtor);
+
/// Emit an alignment directive to the specified power of two boundary. If a
/// global value is specified, and if that global has an explicit alignment
/// requested, it will override the alignment request if required for
@@ -461,11 +461,11 @@ public:
// Overridable Hooks
//===------------------------------------------------------------------===//
- void addAsmPrinterHandler(HandlerInfo Handler) {
- Handlers.insert(Handlers.begin(), std::move(Handler));
- NumUserHandlers++;
- }
-
+ void addAsmPrinterHandler(HandlerInfo Handler) {
+ Handlers.insert(Handlers.begin(), std::move(Handler));
+ NumUserHandlers++;
+ }
+
// Targets can, or in the case of EmitInstruction, must implement these to
// customize output.
@@ -617,7 +617,7 @@ public:
unsigned GetSizeOfEncodedValue(unsigned Encoding) const;
/// Emit reference to a ttype global with a specified encoding.
- virtual void emitTTypeReference(const GlobalValue *GV, unsigned Encoding);
+ virtual void emitTTypeReference(const GlobalValue *GV, unsigned Encoding);
/// Emit a reference to a symbol for use in dwarf. Different object formats
/// represent this in different ways. Some use a relocation others encode
@@ -625,39 +625,39 @@ public:
void emitDwarfSymbolReference(const MCSymbol *Label,
bool ForceOffset = false) const;
- /// Emit the 4- or 8-byte offset of a string from the start of its section.
+ /// Emit the 4- or 8-byte offset of a string from the start of its section.
///
/// When possible, emit a DwarfStringPool section offset without any
/// relocations, and without using the symbol. Otherwise, defers to \a
/// emitDwarfSymbolReference().
- ///
- /// The length of the emitted value depends on the DWARF format.
+ ///
+ /// The length of the emitted value depends on the DWARF format.
void emitDwarfStringOffset(DwarfStringPoolEntry S) const;
- /// Emit the 4-or 8-byte offset of a string from the start of its section.
+ /// Emit the 4-or 8-byte offset of a string from the start of its section.
void emitDwarfStringOffset(DwarfStringPoolEntryRef S) const {
emitDwarfStringOffset(S.getEntry());
}
- /// Emit something like ".long Label + Offset" or ".quad Label + Offset"
- /// depending on the DWARF format.
- void emitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const;
-
- /// Emit 32- or 64-bit value depending on the DWARF format.
- void emitDwarfLengthOrOffset(uint64_t Value) const;
-
- /// Emit a special value of 0xffffffff if producing 64-bit debugging info.
- void maybeEmitDwarf64Mark() const;
-
- /// Emit a unit length field. The actual format, DWARF32 or DWARF64, is chosen
- /// according to the settings.
- void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) const;
-
- /// Emit a unit length field. The actual format, DWARF32 or DWARF64, is chosen
- /// according to the settings.
- void emitDwarfUnitLength(const MCSymbol *Hi, const MCSymbol *Lo,
- const Twine &Comment) const;
-
+ /// Emit something like ".long Label + Offset" or ".quad Label + Offset"
+ /// depending on the DWARF format.
+ void emitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const;
+
+ /// Emit 32- or 64-bit value depending on the DWARF format.
+ void emitDwarfLengthOrOffset(uint64_t Value) const;
+
+ /// Emit a special value of 0xffffffff if producing 64-bit debugging info.
+ void maybeEmitDwarf64Mark() const;
+
+ /// Emit a unit length field. The actual format, DWARF32 or DWARF64, is chosen
+ /// according to the settings.
+ void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) const;
+
+ /// Emit a unit length field. The actual format, DWARF32 or DWARF64, is chosen
+ /// according to the settings.
+ void emitDwarfUnitLength(const MCSymbol *Hi, const MCSymbol *Lo,
+ const Twine &Comment) const;
+
/// Emit reference to a call site with a specified encoding
void emitCallSiteOffset(const MCSymbol *Hi, const MCSymbol *Lo,
unsigned Encoding) const;
@@ -798,9 +798,9 @@ private:
GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy &S);
/// Emit GlobalAlias or GlobalIFunc.
void emitGlobalIndirectSymbol(Module &M, const GlobalIndirectSymbol &GIS);
-
- /// This method decides whether the specified basic block requires a label.
- bool shouldEmitLabelForBasicBlock(const MachineBasicBlock &MBB) const;
+
+ /// This method decides whether the specified basic block requires a label.
+ bool shouldEmitLabelForBasicBlock(const MachineBasicBlock &MBB) const;
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/AsmPrinterHandler.h b/contrib/libs/llvm12/include/llvm/CodeGen/AsmPrinterHandler.h
index 8346f98dd9..6b5bda2d8d 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/AsmPrinterHandler.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/AsmPrinterHandler.h
@@ -30,10 +30,10 @@ class MachineBasicBlock;
class MachineFunction;
class MachineInstr;
class MCSymbol;
-class Module;
+class Module;
-typedef MCSymbol *ExceptionSymbolProvider(AsmPrinter *Asm,
- const MachineBasicBlock *MBB);
+typedef MCSymbol *ExceptionSymbolProvider(AsmPrinter *Asm,
+ const MachineBasicBlock *MBB);
/// Collects and handles AsmPrinter objects required to build debug
/// or EH information.
@@ -45,8 +45,8 @@ public:
/// this tracks that size.
virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) = 0;
- virtual void beginModule(Module *M) {}
-
+ virtual void beginModule(Module *M) {}
+
/// Emit all sections that should come after the content.
virtual void endModule() = 0;
@@ -85,7 +85,7 @@ public:
/// Process end of a basic block during basic block sections.
virtual void endBasicBlock(const MachineBasicBlock &MBB) {}
};
-
+
} // End of namespace llvm
#endif
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/BasicBlockSectionUtils.h b/contrib/libs/llvm12/include/llvm/CodeGen/BasicBlockSectionUtils.h
index b9783cbc79..8018d0ff62 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/BasicBlockSectionUtils.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/BasicBlockSectionUtils.h
@@ -1,41 +1,41 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- BasicBlockSectionUtils.h - Utilities for basic block sections --===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_BASICBLOCKSECTIONUTILS_H
-#define LLVM_CODEGEN_BASICBLOCKSECTIONUTILS_H
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/CommandLine.h"
-
-namespace llvm {
-
-extern cl::opt<std::string> BBSectionsColdTextPrefix;
-
-class MachineFunction;
-class MachineBasicBlock;
-
-using MachineBasicBlockComparator =
- function_ref<bool(const MachineBasicBlock &, const MachineBasicBlock &)>;
-
-void sortBasicBlocksAndUpdateBranches(MachineFunction &MF,
- MachineBasicBlockComparator MBBCmp);
-
-} // end namespace llvm
-
-#endif // LLVM_CODEGEN_BASICBLOCKSECTIONUTILS_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- BasicBlockSectionUtils.h - Utilities for basic block sections --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_BASICBLOCKSECTIONUTILS_H
+#define LLVM_CODEGEN_BASICBLOCKSECTIONUTILS_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/CommandLine.h"
+
+namespace llvm {
+
+extern cl::opt<std::string> BBSectionsColdTextPrefix;
+
+class MachineFunction;
+class MachineBasicBlock;
+
+using MachineBasicBlockComparator =
+ function_ref<bool(const MachineBasicBlock &, const MachineBasicBlock &)>;
+
+void sortBasicBlocksAndUpdateBranches(MachineFunction &MF,
+ MachineBasicBlockComparator MBBCmp);
+
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_BASICBLOCKSECTIONUTILS_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/BasicTTIImpl.h b/contrib/libs/llvm12/include/llvm/CodeGen/BasicTTIImpl.h
index 9d2c9571a5..85ca4b303c 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/BasicTTIImpl.h
@@ -121,14 +121,14 @@ private:
/// Estimate a cost of subvector extraction as a sequence of extract and
/// insert operations.
- unsigned getExtractSubvectorOverhead(VectorType *VTy, int Index,
+ unsigned getExtractSubvectorOverhead(VectorType *VTy, int Index,
FixedVectorType *SubVTy) {
assert(VTy && SubVTy &&
"Can only extract subvectors from vectors");
int NumSubElts = SubVTy->getNumElements();
- assert((!isa<FixedVectorType>(VTy) ||
- (Index + NumSubElts) <=
- (int)cast<FixedVectorType>(VTy)->getNumElements()) &&
+ assert((!isa<FixedVectorType>(VTy) ||
+ (Index + NumSubElts) <=
+ (int)cast<FixedVectorType>(VTy)->getNumElements()) &&
"SK_ExtractSubvector index out of range");
unsigned Cost = 0;
@@ -146,14 +146,14 @@ private:
/// Estimate a cost of subvector insertion as a sequence of extract and
/// insert operations.
- unsigned getInsertSubvectorOverhead(VectorType *VTy, int Index,
+ unsigned getInsertSubvectorOverhead(VectorType *VTy, int Index,
FixedVectorType *SubVTy) {
assert(VTy && SubVTy &&
"Can only insert subvectors into vectors");
int NumSubElts = SubVTy->getNumElements();
- assert((!isa<FixedVectorType>(VTy) ||
- (Index + NumSubElts) <=
- (int)cast<FixedVectorType>(VTy)->getNumElements()) &&
+ assert((!isa<FixedVectorType>(VTy) ||
+ (Index + NumSubElts) <=
+ (int)cast<FixedVectorType>(VTy)->getNumElements()) &&
"SK_InsertSubvector index out of range");
unsigned Cost = 0;
@@ -232,13 +232,13 @@ public:
}
bool isNoopAddrSpaceCast(unsigned FromAS, unsigned ToAS) const {
- return getTLI()->getTargetMachine().isNoopAddrSpaceCast(FromAS, ToAS);
+ return getTLI()->getTargetMachine().isNoopAddrSpaceCast(FromAS, ToAS);
+ }
+
+ unsigned getAssumedAddrSpace(const Value *V) const {
+ return getTLI()->getTargetMachine().getAssumedAddrSpace(V);
}
- unsigned getAssumedAddrSpace(const Value *V) const {
- return getTLI()->getTargetMachine().getAssumedAddrSpace(V);
- }
-
Value *rewriteIntrinsicWithAddressSpace(IntrinsicInst *II, Value *OldV,
Value *NewV) const {
return nullptr;
@@ -279,10 +279,10 @@ public:
return TargetTransformInfoImplBase::isLSRCostLess(C1, C2);
}
- bool isNumRegsMajorCostOfLSR() {
- return TargetTransformInfoImplBase::isNumRegsMajorCostOfLSR();
- }
-
+ bool isNumRegsMajorCostOfLSR() {
+ return TargetTransformInfoImplBase::isNumRegsMajorCostOfLSR();
+ }
+
bool isProfitableLSRChainElement(Instruction *I) {
return TargetTransformInfoImplBase::isProfitableLSRChainElement(I);
}
@@ -312,10 +312,10 @@ public:
return getTLI()->isTypeLegal(VT);
}
- unsigned getRegUsageForType(Type *Ty) {
- return getTLI()->getTypeLegalizationCost(DL, Ty).first;
- }
-
+ unsigned getRegUsageForType(Type *Ty) {
+ return getTLI()->getTypeLegalizationCost(DL, Ty).first;
+ }
+
int getGEPCost(Type *PointeeType, const Value *Ptr,
ArrayRef<const Value *> Operands) {
return BaseT::getGEPCost(PointeeType, Ptr, Operands);
@@ -408,7 +408,7 @@ public:
}
unsigned getInliningThresholdMultiplier() { return 1; }
- unsigned adjustInliningThreshold(const CallBase *CB) { return 0; }
+ unsigned adjustInliningThreshold(const CallBase *CB) { return 0; }
int getInlinerVectorBonusPercent() { return 150; }
@@ -500,30 +500,30 @@ public:
return BaseT::emitGetActiveLaneMask();
}
- Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
- IntrinsicInst &II) {
- return BaseT::instCombineIntrinsic(IC, II);
- }
-
- Optional<Value *> simplifyDemandedUseBitsIntrinsic(InstCombiner &IC,
- IntrinsicInst &II,
- APInt DemandedMask,
- KnownBits &Known,
- bool &KnownBitsComputed) {
- return BaseT::simplifyDemandedUseBitsIntrinsic(IC, II, DemandedMask, Known,
- KnownBitsComputed);
- }
-
- Optional<Value *> simplifyDemandedVectorEltsIntrinsic(
- InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
- APInt &UndefElts2, APInt &UndefElts3,
- std::function<void(Instruction *, unsigned, APInt, APInt &)>
- SimplifyAndSetOp) {
- return BaseT::simplifyDemandedVectorEltsIntrinsic(
- IC, II, DemandedElts, UndefElts, UndefElts2, UndefElts3,
- SimplifyAndSetOp);
- }
-
+ Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
+ IntrinsicInst &II) {
+ return BaseT::instCombineIntrinsic(IC, II);
+ }
+
+ Optional<Value *> simplifyDemandedUseBitsIntrinsic(InstCombiner &IC,
+ IntrinsicInst &II,
+ APInt DemandedMask,
+ KnownBits &Known,
+ bool &KnownBitsComputed) {
+ return BaseT::simplifyDemandedUseBitsIntrinsic(IC, II, DemandedMask, Known,
+ KnownBitsComputed);
+ }
+
+ Optional<Value *> simplifyDemandedVectorEltsIntrinsic(
+ InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
+ APInt &UndefElts2, APInt &UndefElts3,
+ std::function<void(Instruction *, unsigned, APInt, APInt &)>
+ SimplifyAndSetOp) {
+ return BaseT::simplifyDemandedVectorEltsIntrinsic(
+ IC, II, DemandedElts, UndefElts, UndefElts2, UndefElts3,
+ SimplifyAndSetOp);
+ }
+
int getInstructionLatency(const Instruction *I) {
if (isa<LoadInst>(I))
return getST()->getSchedModel().DefaultLoadLatency;
@@ -579,8 +579,8 @@ public:
unsigned getRegisterBitWidth(bool Vector) const { return 32; }
- Optional<unsigned> getMaxVScale() const { return None; }
-
+ Optional<unsigned> getMaxVScale() const { return None; }
+
/// Estimate the overhead of scalarizing an instruction. Insert and Extract
/// are set if the demanded result elements need to be inserted and/or
/// extracted from vectors.
@@ -616,7 +616,7 @@ public:
return thisT()->getScalarizationOverhead(Ty, DemandedElts, Insert, Extract);
}
- /// Estimate the overhead of scalarizing an instruction's unique
+ /// Estimate the overhead of scalarizing an instruction's unique
/// non-constant operands. The types of the arguments are ordinarily
/// scalar, in which case the costs are multiplied with VF.
unsigned getOperandsScalarizationOverhead(ArrayRef<const Value *> Args,
@@ -624,14 +624,14 @@ public:
unsigned Cost = 0;
SmallPtrSet<const Value*, 4> UniqueOperands;
for (const Value *A : Args) {
- // Disregard things like metadata arguments.
- Type *Ty = A->getType();
- if (!Ty->isIntOrIntVectorTy() && !Ty->isFPOrFPVectorTy() &&
- !Ty->isPtrOrPtrVectorTy())
- continue;
-
+ // Disregard things like metadata arguments.
+ Type *Ty = A->getType();
+ if (!Ty->isIntOrIntVectorTy() && !Ty->isFPOrFPVectorTy() &&
+ !Ty->isPtrOrPtrVectorTy())
+ continue;
+
if (!isa<Constant>(A) && UniqueOperands.insert(A).second) {
- auto *VecTy = dyn_cast<VectorType>(Ty);
+ auto *VecTy = dyn_cast<VectorType>(Ty);
if (VecTy) {
// If A is a vector operand, VF should be 1 or correspond to A.
assert((VF == 1 ||
@@ -639,7 +639,7 @@ public:
"Vector argument does not match VF");
}
else
- VecTy = FixedVectorType::get(Ty, VF);
+ VecTy = FixedVectorType::get(Ty, VF);
Cost += getScalarizationOverhead(VecTy, false, true);
}
@@ -713,8 +713,8 @@ public:
if (auto *VTy = dyn_cast<VectorType>(Ty)) {
unsigned Num = cast<FixedVectorType>(VTy)->getNumElements();
unsigned Cost = thisT()->getArithmeticInstrCost(
- Opcode, VTy->getScalarType(), CostKind, Opd1Info, Opd2Info,
- Opd1PropInfo, Opd2PropInfo, Args, CxtI);
+ Opcode, VTy->getScalarType(), CostKind, Opd1Info, Opd2Info,
+ Opd1PropInfo, Opd2PropInfo, Args, CxtI);
// Return the cost of multiple scalar invocation plus the cost of
// inserting and extracting the values.
return getScalarizationOverhead(VTy, Args) + Num * Cost;
@@ -737,20 +737,20 @@ public:
case TTI::SK_PermuteTwoSrc:
return getPermuteShuffleOverhead(cast<FixedVectorType>(Tp));
case TTI::SK_ExtractSubvector:
- return getExtractSubvectorOverhead(Tp, Index,
+ return getExtractSubvectorOverhead(Tp, Index,
cast<FixedVectorType>(SubTp));
case TTI::SK_InsertSubvector:
- return getInsertSubvectorOverhead(Tp, Index,
+ return getInsertSubvectorOverhead(Tp, Index,
cast<FixedVectorType>(SubTp));
}
llvm_unreachable("Unknown TTI::ShuffleKind");
}
unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
- TTI::CastContextHint CCH,
+ TTI::CastContextHint CCH,
TTI::TargetCostKind CostKind,
const Instruction *I = nullptr) {
- if (BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I) == 0)
+ if (BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I) == 0)
return 0;
const TargetLoweringBase *TLI = getTLI();
@@ -788,12 +788,12 @@ public:
return 0;
LLVM_FALLTHROUGH;
case Instruction::SExt:
- if (I && getTLI()->isExtFree(I))
+ if (I && getTLI()->isExtFree(I))
return 0;
// If this is a zext/sext of a load, return 0 if the corresponding
// extending load exists on target.
- if (CCH == TTI::CastContextHint::Normal) {
+ if (CCH == TTI::CastContextHint::Normal) {
EVT ExtVT = EVT::getEVT(Dst);
EVT LoadVT = EVT::getEVT(Src);
unsigned LType =
@@ -868,7 +868,7 @@ public:
unsigned SplitCost =
(!SplitSrc || !SplitDst) ? TTI->getVectorSplitCost() : 0;
return SplitCost +
- (2 * TTI->getCastInstrCost(Opcode, SplitDstTy, SplitSrcTy, CCH,
+ (2 * TTI->getCastInstrCost(Opcode, SplitDstTy, SplitSrcTy, CCH,
CostKind, I));
}
@@ -876,7 +876,7 @@ public:
// the operation will get scalarized.
unsigned Num = cast<FixedVectorType>(DstVTy)->getNumElements();
unsigned Cost = thisT()->getCastInstrCost(
- Opcode, Dst->getScalarType(), Src->getScalarType(), CCH, CostKind, I);
+ Opcode, Dst->getScalarType(), Src->getScalarType(), CCH, CostKind, I);
// Return the cost of multiple scalar invocation plus the cost of
// inserting and extracting the values.
@@ -901,7 +901,7 @@ public:
return thisT()->getVectorInstrCost(Instruction::ExtractElement, VecTy,
Index) +
thisT()->getCastInstrCost(Opcode, Dst, VecTy->getElementType(),
- TTI::CastContextHint::None, TTI::TCK_RecipThroughput);
+ TTI::CastContextHint::None, TTI::TCK_RecipThroughput);
}
unsigned getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind) {
@@ -909,7 +909,7 @@ public:
}
unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
- CmpInst::Predicate VecPred,
+ CmpInst::Predicate VecPred,
TTI::TargetCostKind CostKind,
const Instruction *I = nullptr) {
const TargetLoweringBase *TLI = getTLI();
@@ -918,8 +918,8 @@ public:
// TODO: Handle other cost kinds.
if (CostKind != TTI::TCK_RecipThroughput)
- return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
- I);
+ return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
+ I);
// Selects on vectors are actually vector selects.
if (ISD == ISD::SELECT) {
@@ -944,7 +944,7 @@ public:
if (CondTy)
CondTy = CondTy->getScalarType();
unsigned Cost = thisT()->getCmpSelInstrCost(
- Opcode, ValVTy->getScalarType(), CondTy, VecPred, CostKind, I);
+ Opcode, ValVTy->getScalarType(), CondTy, VecPred, CostKind, I);
// Return the cost of multiple scalar invocation plus the cost of
// inserting and extracting the values.
@@ -978,11 +978,11 @@ public:
return Cost;
if (Src->isVectorTy() &&
- // In practice it's not currently possible to have a change in lane
- // length for extending loads or truncating stores so both types should
- // have the same scalable property.
- TypeSize::isKnownLT(Src->getPrimitiveSizeInBits(),
- LT.second.getSizeInBits())) {
+ // In practice it's not currently possible to have a change in lane
+ // length for extending loads or truncating stores so both types should
+ // have the same scalable property.
+ TypeSize::isKnownLT(Src->getPrimitiveSizeInBits(),
+ LT.second.getSizeInBits())) {
// This is a vector load that legalizes to a larger type than the vector
// itself. Unless the corresponding extending load or truncating store is
// legal, then this will scalarize.
@@ -1005,51 +1005,51 @@ public:
return Cost;
}
- unsigned getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
- const Value *Ptr, bool VariableMask,
- Align Alignment, TTI::TargetCostKind CostKind,
- const Instruction *I = nullptr) {
- auto *VT = cast<FixedVectorType>(DataTy);
- // Assume the target does not have support for gather/scatter operations
- // and provide a rough estimate.
- //
- // First, compute the cost of extracting the individual addresses and the
- // individual memory operations.
- int LoadCost =
- VT->getNumElements() *
- (getVectorInstrCost(
- Instruction::ExtractElement,
- FixedVectorType::get(PointerType::get(VT->getElementType(), 0),
- VT->getNumElements()),
- -1) +
- getMemoryOpCost(Opcode, VT->getElementType(), Alignment, 0, CostKind));
-
- // Next, compute the cost of packing the result in a vector.
- int PackingCost = getScalarizationOverhead(VT, Opcode != Instruction::Store,
- Opcode == Instruction::Store);
-
- int ConditionalCost = 0;
- if (VariableMask) {
- // Compute the cost of conditionally executing the memory operations with
- // variable masks. This includes extracting the individual conditions, a
- // branches and PHIs to combine the results.
- // NOTE: Estimating the cost of conditionally executing the memory
- // operations accurately is quite difficult and the current solution
- // provides a very rough estimate only.
- ConditionalCost =
- VT->getNumElements() *
- (getVectorInstrCost(
- Instruction::ExtractElement,
- FixedVectorType::get(Type::getInt1Ty(DataTy->getContext()),
- VT->getNumElements()),
- -1) +
- getCFInstrCost(Instruction::Br, CostKind) +
- getCFInstrCost(Instruction::PHI, CostKind));
- }
-
- return LoadCost + PackingCost + ConditionalCost;
- }
-
+ unsigned getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
+ const Value *Ptr, bool VariableMask,
+ Align Alignment, TTI::TargetCostKind CostKind,
+ const Instruction *I = nullptr) {
+ auto *VT = cast<FixedVectorType>(DataTy);
+ // Assume the target does not have support for gather/scatter operations
+ // and provide a rough estimate.
+ //
+ // First, compute the cost of extracting the individual addresses and the
+ // individual memory operations.
+ int LoadCost =
+ VT->getNumElements() *
+ (getVectorInstrCost(
+ Instruction::ExtractElement,
+ FixedVectorType::get(PointerType::get(VT->getElementType(), 0),
+ VT->getNumElements()),
+ -1) +
+ getMemoryOpCost(Opcode, VT->getElementType(), Alignment, 0, CostKind));
+
+ // Next, compute the cost of packing the result in a vector.
+ int PackingCost = getScalarizationOverhead(VT, Opcode != Instruction::Store,
+ Opcode == Instruction::Store);
+
+ int ConditionalCost = 0;
+ if (VariableMask) {
+ // Compute the cost of conditionally executing the memory operations with
+ // variable masks. This includes extracting the individual conditions, a
+ // branches and PHIs to combine the results.
+ // NOTE: Estimating the cost of conditionally executing the memory
+ // operations accurately is quite difficult and the current solution
+ // provides a very rough estimate only.
+ ConditionalCost =
+ VT->getNumElements() *
+ (getVectorInstrCost(
+ Instruction::ExtractElement,
+ FixedVectorType::get(Type::getInt1Ty(DataTy->getContext()),
+ VT->getNumElements()),
+ -1) +
+ getCFInstrCost(Instruction::Br, CostKind) +
+ getCFInstrCost(Instruction::PHI, CostKind));
+ }
+
+ return LoadCost + PackingCost + ConditionalCost;
+ }
+
unsigned getInterleavedMemoryOpCost(
unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
@@ -1204,52 +1204,52 @@ public:
/// Get intrinsic cost based on arguments.
unsigned getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
TTI::TargetCostKind CostKind) {
- // Check for generically free intrinsics.
+ // Check for generically free intrinsics.
if (BaseT::getIntrinsicInstrCost(ICA, CostKind) == 0)
return 0;
- // Assume that target intrinsics are cheap.
- Intrinsic::ID IID = ICA.getID();
- if (Function::isTargetIntrinsic(IID))
- return TargetTransformInfo::TCC_Basic;
-
+ // Assume that target intrinsics are cheap.
+ Intrinsic::ID IID = ICA.getID();
+ if (Function::isTargetIntrinsic(IID))
+ return TargetTransformInfo::TCC_Basic;
+
if (ICA.isTypeBasedOnly())
return getTypeBasedIntrinsicInstrCost(ICA, CostKind);
Type *RetTy = ICA.getReturnType();
-
- ElementCount VF = ICA.getVectorFactor();
- ElementCount RetVF =
- (RetTy->isVectorTy() ? cast<VectorType>(RetTy)->getElementCount()
- : ElementCount::getFixed(1));
- assert((RetVF.isScalar() || VF.isScalar()) &&
- "VF > 1 and RetVF is a vector type");
+
+ ElementCount VF = ICA.getVectorFactor();
+ ElementCount RetVF =
+ (RetTy->isVectorTy() ? cast<VectorType>(RetTy)->getElementCount()
+ : ElementCount::getFixed(1));
+ assert((RetVF.isScalar() || VF.isScalar()) &&
+ "VF > 1 and RetVF is a vector type");
const IntrinsicInst *I = ICA.getInst();
const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
FastMathFlags FMF = ICA.getFlags();
switch (IID) {
- default:
- break;
-
- case Intrinsic::cttz:
- // FIXME: If necessary, this should go in target-specific overrides.
- if (VF.isScalar() && RetVF.isScalar() &&
- getTLI()->isCheapToSpeculateCttz())
- return TargetTransformInfo::TCC_Basic;
- break;
-
- case Intrinsic::ctlz:
- // FIXME: If necessary, this should go in target-specific overrides.
- if (VF.isScalar() && RetVF.isScalar() &&
- getTLI()->isCheapToSpeculateCtlz())
- return TargetTransformInfo::TCC_Basic;
- break;
-
- case Intrinsic::memcpy:
- return thisT()->getMemcpyCost(ICA.getInst());
-
+ default:
+ break;
+
+ case Intrinsic::cttz:
+ // FIXME: If necessary, this should go in target-specific overrides.
+ if (VF.isScalar() && RetVF.isScalar() &&
+ getTLI()->isCheapToSpeculateCttz())
+ return TargetTransformInfo::TCC_Basic;
+ break;
+
+ case Intrinsic::ctlz:
+ // FIXME: If necessary, this should go in target-specific overrides.
+ if (VF.isScalar() && RetVF.isScalar() &&
+ getTLI()->isCheapToSpeculateCtlz())
+ return TargetTransformInfo::TCC_Basic;
+ break;
+
+ case Intrinsic::memcpy:
+ return thisT()->getMemcpyCost(ICA.getInst());
+
case Intrinsic::masked_scatter: {
- assert(VF.isScalar() && "Can't vectorize types here.");
+ assert(VF.isScalar() && "Can't vectorize types here.");
const Value *Mask = Args[3];
bool VarMask = !isa<Constant>(Mask);
Align Alignment = cast<ConstantInt>(Args[2])->getAlignValue();
@@ -1258,57 +1258,57 @@ public:
VarMask, Alignment, CostKind, I);
}
case Intrinsic::masked_gather: {
- assert(VF.isScalar() && "Can't vectorize types here.");
+ assert(VF.isScalar() && "Can't vectorize types here.");
const Value *Mask = Args[2];
bool VarMask = !isa<Constant>(Mask);
Align Alignment = cast<ConstantInt>(Args[1])->getAlignValue();
return thisT()->getGatherScatterOpCost(Instruction::Load, RetTy, Args[0],
VarMask, Alignment, CostKind, I);
}
- case Intrinsic::experimental_vector_extract: {
- // FIXME: Handle case where a scalable vector is extracted from a scalable
- // vector
- if (isa<ScalableVectorType>(RetTy))
- return BaseT::getIntrinsicInstrCost(ICA, CostKind);
- unsigned Index = cast<ConstantInt>(Args[1])->getZExtValue();
- return thisT()->getShuffleCost(TTI::SK_ExtractSubvector,
- cast<VectorType>(Args[0]->getType()),
- Index, cast<VectorType>(RetTy));
- }
- case Intrinsic::experimental_vector_insert: {
- // FIXME: Handle case where a scalable vector is inserted into a scalable
- // vector
- if (isa<ScalableVectorType>(Args[1]->getType()))
- return BaseT::getIntrinsicInstrCost(ICA, CostKind);
- unsigned Index = cast<ConstantInt>(Args[2])->getZExtValue();
- return thisT()->getShuffleCost(
- TTI::SK_InsertSubvector, cast<VectorType>(Args[0]->getType()), Index,
- cast<VectorType>(Args[1]->getType()));
- }
- case Intrinsic::vector_reduce_add:
- case Intrinsic::vector_reduce_mul:
- case Intrinsic::vector_reduce_and:
- case Intrinsic::vector_reduce_or:
- case Intrinsic::vector_reduce_xor:
- case Intrinsic::vector_reduce_smax:
- case Intrinsic::vector_reduce_smin:
- case Intrinsic::vector_reduce_fmax:
- case Intrinsic::vector_reduce_fmin:
- case Intrinsic::vector_reduce_umax:
- case Intrinsic::vector_reduce_umin: {
+ case Intrinsic::experimental_vector_extract: {
+ // FIXME: Handle case where a scalable vector is extracted from a scalable
+ // vector
+ if (isa<ScalableVectorType>(RetTy))
+ return BaseT::getIntrinsicInstrCost(ICA, CostKind);
+ unsigned Index = cast<ConstantInt>(Args[1])->getZExtValue();
+ return thisT()->getShuffleCost(TTI::SK_ExtractSubvector,
+ cast<VectorType>(Args[0]->getType()),
+ Index, cast<VectorType>(RetTy));
+ }
+ case Intrinsic::experimental_vector_insert: {
+ // FIXME: Handle case where a scalable vector is inserted into a scalable
+ // vector
+ if (isa<ScalableVectorType>(Args[1]->getType()))
+ return BaseT::getIntrinsicInstrCost(ICA, CostKind);
+ unsigned Index = cast<ConstantInt>(Args[2])->getZExtValue();
+ return thisT()->getShuffleCost(
+ TTI::SK_InsertSubvector, cast<VectorType>(Args[0]->getType()), Index,
+ cast<VectorType>(Args[1]->getType()));
+ }
+ case Intrinsic::vector_reduce_add:
+ case Intrinsic::vector_reduce_mul:
+ case Intrinsic::vector_reduce_and:
+ case Intrinsic::vector_reduce_or:
+ case Intrinsic::vector_reduce_xor:
+ case Intrinsic::vector_reduce_smax:
+ case Intrinsic::vector_reduce_smin:
+ case Intrinsic::vector_reduce_fmax:
+ case Intrinsic::vector_reduce_fmin:
+ case Intrinsic::vector_reduce_umax:
+ case Intrinsic::vector_reduce_umin: {
IntrinsicCostAttributes Attrs(IID, RetTy, Args[0]->getType(), FMF, 1, I);
- return getTypeBasedIntrinsicInstrCost(Attrs, CostKind);
+ return getTypeBasedIntrinsicInstrCost(Attrs, CostKind);
+ }
+ case Intrinsic::vector_reduce_fadd:
+ case Intrinsic::vector_reduce_fmul: {
+ IntrinsicCostAttributes Attrs(
+ IID, RetTy, {Args[0]->getType(), Args[1]->getType()}, FMF, 1, I);
+ return getTypeBasedIntrinsicInstrCost(Attrs, CostKind);
}
- case Intrinsic::vector_reduce_fadd:
- case Intrinsic::vector_reduce_fmul: {
- IntrinsicCostAttributes Attrs(
- IID, RetTy, {Args[0]->getType(), Args[1]->getType()}, FMF, 1, I);
- return getTypeBasedIntrinsicInstrCost(Attrs, CostKind);
- }
case Intrinsic::fshl:
case Intrinsic::fshr: {
- if (isa<ScalableVectorType>(RetTy))
- return BaseT::getIntrinsicInstrCost(ICA, CostKind);
+ if (isa<ScalableVectorType>(RetTy))
+ return BaseT::getIntrinsicInstrCost(ICA, CostKind);
const Value *X = Args[0];
const Value *Y = Args[1];
const Value *Z = Args[2];
@@ -1339,48 +1339,48 @@ public:
// For non-rotates (X != Y) we must add shift-by-zero handling costs.
if (X != Y) {
Type *CondTy = RetTy->getWithNewBitWidth(1);
- Cost +=
- thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
- Cost +=
- thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ Cost +=
+ thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ Cost +=
+ thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
}
return Cost;
}
}
- // TODO: Handle the remaining intrinsic with scalable vector type
- if (isa<ScalableVectorType>(RetTy))
- return BaseT::getIntrinsicInstrCost(ICA, CostKind);
-
- // Assume that we need to scalarize this intrinsic.
- SmallVector<Type *, 4> Types;
- for (const Value *Op : Args) {
- Type *OpTy = Op->getType();
- assert(VF.isScalar() || !OpTy->isVectorTy());
- Types.push_back(VF.isScalar()
- ? OpTy
- : FixedVectorType::get(OpTy, VF.getKnownMinValue()));
- }
-
- if (VF.isVector() && !RetTy->isVoidTy())
- RetTy = FixedVectorType::get(RetTy, VF.getKnownMinValue());
-
- // Compute the scalarization overhead based on Args for a vector
- // intrinsic. A vectorizer will pass a scalar RetTy and VF > 1, while
- // CostModel will pass a vector RetTy and VF is 1.
- unsigned ScalarizationCost = std::numeric_limits<unsigned>::max();
- if (RetVF.isVector() || VF.isVector()) {
- ScalarizationCost = 0;
- if (!RetTy->isVoidTy())
- ScalarizationCost +=
- getScalarizationOverhead(cast<VectorType>(RetTy), true, false);
- ScalarizationCost +=
- getOperandsScalarizationOverhead(Args, VF.getKnownMinValue());
- }
-
- IntrinsicCostAttributes Attrs(IID, RetTy, Types, FMF, ScalarizationCost, I);
- return thisT()->getTypeBasedIntrinsicInstrCost(Attrs, CostKind);
+ // TODO: Handle the remaining intrinsic with scalable vector type
+ if (isa<ScalableVectorType>(RetTy))
+ return BaseT::getIntrinsicInstrCost(ICA, CostKind);
+
+ // Assume that we need to scalarize this intrinsic.
+ SmallVector<Type *, 4> Types;
+ for (const Value *Op : Args) {
+ Type *OpTy = Op->getType();
+ assert(VF.isScalar() || !OpTy->isVectorTy());
+ Types.push_back(VF.isScalar()
+ ? OpTy
+ : FixedVectorType::get(OpTy, VF.getKnownMinValue()));
+ }
+
+ if (VF.isVector() && !RetTy->isVoidTy())
+ RetTy = FixedVectorType::get(RetTy, VF.getKnownMinValue());
+
+ // Compute the scalarization overhead based on Args for a vector
+ // intrinsic. A vectorizer will pass a scalar RetTy and VF > 1, while
+ // CostModel will pass a vector RetTy and VF is 1.
+ unsigned ScalarizationCost = std::numeric_limits<unsigned>::max();
+ if (RetVF.isVector() || VF.isVector()) {
+ ScalarizationCost = 0;
+ if (!RetTy->isVoidTy())
+ ScalarizationCost +=
+ getScalarizationOverhead(cast<VectorType>(RetTy), true, false);
+ ScalarizationCost +=
+ getOperandsScalarizationOverhead(Args, VF.getKnownMinValue());
+ }
+
+ IntrinsicCostAttributes Attrs(IID, RetTy, Types, FMF, ScalarizationCost, I);
+ return thisT()->getTypeBasedIntrinsicInstrCost(Attrs, CostKind);
}
/// Get intrinsic cost based on argument types.
@@ -1396,20 +1396,20 @@ public:
unsigned ScalarizationCostPassed = ICA.getScalarizationCost();
bool SkipScalarizationCost = ICA.skipScalarizationCost();
- VectorType *VecOpTy = nullptr;
- if (!Tys.empty()) {
- // The vector reduction operand is operand 0 except for fadd/fmul.
- // Their operand 0 is a scalar start value, so the vector op is operand 1.
- unsigned VecTyIndex = 0;
- if (IID == Intrinsic::vector_reduce_fadd ||
- IID == Intrinsic::vector_reduce_fmul)
- VecTyIndex = 1;
- assert(Tys.size() > VecTyIndex && "Unexpected IntrinsicCostAttributes");
- VecOpTy = dyn_cast<VectorType>(Tys[VecTyIndex]);
- }
-
- // Library call cost - other than size, make it expensive.
- unsigned SingleCallCost = CostKind == TTI::TCK_CodeSize ? 1 : 10;
+ VectorType *VecOpTy = nullptr;
+ if (!Tys.empty()) {
+ // The vector reduction operand is operand 0 except for fadd/fmul.
+ // Their operand 0 is a scalar start value, so the vector op is operand 1.
+ unsigned VecTyIndex = 0;
+ if (IID == Intrinsic::vector_reduce_fadd ||
+ IID == Intrinsic::vector_reduce_fmul)
+ VecTyIndex = 1;
+ assert(Tys.size() > VecTyIndex && "Unexpected IntrinsicCostAttributes");
+ VecOpTy = dyn_cast<VectorType>(Tys[VecTyIndex]);
+ }
+
+ // Library call cost - other than size, make it expensive.
+ unsigned SingleCallCost = CostKind == TTI::TCK_CodeSize ? 1 : 10;
SmallVector<unsigned, 2> ISDs;
switch (IID) {
default: {
@@ -1483,12 +1483,12 @@ public:
case Intrinsic::maxnum:
ISDs.push_back(ISD::FMAXNUM);
break;
- case Intrinsic::minimum:
- ISDs.push_back(ISD::FMINIMUM);
- break;
- case Intrinsic::maximum:
- ISDs.push_back(ISD::FMAXIMUM);
- break;
+ case Intrinsic::minimum:
+ ISDs.push_back(ISD::FMINIMUM);
+ break;
+ case Intrinsic::maximum:
+ ISDs.push_back(ISD::FMAXIMUM);
+ break;
case Intrinsic::copysign:
ISDs.push_back(ISD::FCOPYSIGN);
break;
@@ -1529,7 +1529,7 @@ public:
case Intrinsic::lifetime_start:
case Intrinsic::lifetime_end:
case Intrinsic::sideeffect:
- case Intrinsic::pseudoprobe:
+ case Intrinsic::pseudoprobe:
return 0;
case Intrinsic::masked_store: {
Type *Ty = Tys[0];
@@ -1543,72 +1543,72 @@ public:
return thisT()->getMaskedMemoryOpCost(Instruction::Load, Ty, TyAlign, 0,
CostKind);
}
- case Intrinsic::vector_reduce_add:
+ case Intrinsic::vector_reduce_add:
return thisT()->getArithmeticReductionCost(Instruction::Add, VecOpTy,
/*IsPairwiseForm=*/false,
CostKind);
- case Intrinsic::vector_reduce_mul:
+ case Intrinsic::vector_reduce_mul:
return thisT()->getArithmeticReductionCost(Instruction::Mul, VecOpTy,
/*IsPairwiseForm=*/false,
CostKind);
- case Intrinsic::vector_reduce_and:
+ case Intrinsic::vector_reduce_and:
return thisT()->getArithmeticReductionCost(Instruction::And, VecOpTy,
/*IsPairwiseForm=*/false,
CostKind);
- case Intrinsic::vector_reduce_or:
+ case Intrinsic::vector_reduce_or:
return thisT()->getArithmeticReductionCost(Instruction::Or, VecOpTy,
/*IsPairwiseForm=*/false,
CostKind);
- case Intrinsic::vector_reduce_xor:
+ case Intrinsic::vector_reduce_xor:
return thisT()->getArithmeticReductionCost(Instruction::Xor, VecOpTy,
/*IsPairwiseForm=*/false,
CostKind);
- case Intrinsic::vector_reduce_fadd:
+ case Intrinsic::vector_reduce_fadd:
// FIXME: Add new flag for cost of strict reductions.
return thisT()->getArithmeticReductionCost(Instruction::FAdd, VecOpTy,
/*IsPairwiseForm=*/false,
CostKind);
- case Intrinsic::vector_reduce_fmul:
+ case Intrinsic::vector_reduce_fmul:
// FIXME: Add new flag for cost of strict reductions.
return thisT()->getArithmeticReductionCost(Instruction::FMul, VecOpTy,
/*IsPairwiseForm=*/false,
CostKind);
- case Intrinsic::vector_reduce_smax:
- case Intrinsic::vector_reduce_smin:
- case Intrinsic::vector_reduce_fmax:
- case Intrinsic::vector_reduce_fmin:
+ case Intrinsic::vector_reduce_smax:
+ case Intrinsic::vector_reduce_smin:
+ case Intrinsic::vector_reduce_fmax:
+ case Intrinsic::vector_reduce_fmin:
return thisT()->getMinMaxReductionCost(
VecOpTy, cast<VectorType>(CmpInst::makeCmpResultType(VecOpTy)),
/*IsPairwiseForm=*/false,
/*IsUnsigned=*/false, CostKind);
- case Intrinsic::vector_reduce_umax:
- case Intrinsic::vector_reduce_umin:
+ case Intrinsic::vector_reduce_umax:
+ case Intrinsic::vector_reduce_umin:
return thisT()->getMinMaxReductionCost(
VecOpTy, cast<VectorType>(CmpInst::makeCmpResultType(VecOpTy)),
/*IsPairwiseForm=*/false,
/*IsUnsigned=*/true, CostKind);
- case Intrinsic::abs:
- case Intrinsic::smax:
- case Intrinsic::smin:
- case Intrinsic::umax:
- case Intrinsic::umin: {
- // abs(X) = select(icmp(X,0),X,sub(0,X))
- // minmax(X,Y) = select(icmp(X,Y),X,Y)
- Type *CondTy = RetTy->getWithNewBitWidth(1);
- unsigned Cost = 0;
- // TODO: Ideally getCmpSelInstrCost would accept an icmp condition code.
- Cost +=
- thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
- Cost +=
- thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
- // TODO: Should we add an OperandValueProperties::OP_Zero property?
- if (IID == Intrinsic::abs)
- Cost += thisT()->getArithmeticInstrCost(
- BinaryOperator::Sub, RetTy, CostKind, TTI::OK_UniformConstantValue);
- return Cost;
- }
+ case Intrinsic::abs:
+ case Intrinsic::smax:
+ case Intrinsic::smin:
+ case Intrinsic::umax:
+ case Intrinsic::umin: {
+ // abs(X) = select(icmp(X,0),X,sub(0,X))
+ // minmax(X,Y) = select(icmp(X,Y),X,Y)
+ Type *CondTy = RetTy->getWithNewBitWidth(1);
+ unsigned Cost = 0;
+ // TODO: Ideally getCmpSelInstrCost would accept an icmp condition code.
+ Cost +=
+ thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ Cost +=
+ thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ // TODO: Should we add an OperandValueProperties::OP_Zero property?
+ if (IID == Intrinsic::abs)
+ Cost += thisT()->getArithmeticInstrCost(
+ BinaryOperator::Sub, RetTy, CostKind, TTI::OK_UniformConstantValue);
+ return Cost;
+ }
case Intrinsic::sadd_sat:
case Intrinsic::ssub_sat: {
Type *CondTy = RetTy->getWithNewBitWidth(1);
@@ -1624,12 +1624,12 @@ public:
IntrinsicCostAttributes Attrs(OverflowOp, OpTy, {RetTy, RetTy}, FMF,
ScalarizationCostPassed);
Cost += thisT()->getIntrinsicInstrCost(Attrs, CostKind);
- Cost +=
- thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
- Cost += 2 * thisT()->getCmpSelInstrCost(
- BinaryOperator::Select, RetTy, CondTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ Cost +=
+ thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ Cost += 2 * thisT()->getCmpSelInstrCost(
+ BinaryOperator::Select, RetTy, CondTy,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
return Cost;
}
case Intrinsic::uadd_sat:
@@ -1645,9 +1645,9 @@ public:
IntrinsicCostAttributes Attrs(OverflowOp, OpTy, {RetTy, RetTy}, FMF,
ScalarizationCostPassed);
Cost += thisT()->getIntrinsicInstrCost(Attrs, CostKind);
- Cost +=
- thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ Cost +=
+ thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
return Cost;
}
case Intrinsic::smul_fix:
@@ -1657,14 +1657,14 @@ public:
unsigned ExtOp =
IID == Intrinsic::smul_fix ? Instruction::SExt : Instruction::ZExt;
- TTI::CastContextHint CCH = TTI::CastContextHint::None;
+ TTI::CastContextHint CCH = TTI::CastContextHint::None;
unsigned Cost = 0;
- Cost += 2 * thisT()->getCastInstrCost(ExtOp, ExtTy, RetTy, CCH, CostKind);
+ Cost += 2 * thisT()->getCastInstrCost(ExtOp, ExtTy, RetTy, CCH, CostKind);
Cost +=
thisT()->getArithmeticInstrCost(Instruction::Mul, ExtTy, CostKind);
Cost += 2 * thisT()->getCastInstrCost(Instruction::Trunc, RetTy, ExtTy,
- CCH, CostKind);
+ CCH, CostKind);
Cost += thisT()->getArithmeticInstrCost(Instruction::LShr, RetTy,
CostKind, TTI::OK_AnyValue,
TTI::OK_UniformConstantValue);
@@ -1692,12 +1692,12 @@ public:
// Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign)
unsigned Cost = 0;
Cost += thisT()->getArithmeticInstrCost(Opcode, SumTy, CostKind);
- Cost += 3 * thisT()->getCmpSelInstrCost(
- Instruction::ICmp, SumTy, OverflowTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
- Cost += 2 * thisT()->getCmpSelInstrCost(
- Instruction::Select, OverflowTy, OverflowTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ Cost += 3 * thisT()->getCmpSelInstrCost(
+ Instruction::ICmp, SumTy, OverflowTy,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ Cost += 2 * thisT()->getCmpSelInstrCost(
+ Instruction::Select, OverflowTy, OverflowTy,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
Cost += thisT()->getArithmeticInstrCost(BinaryOperator::And, OverflowTy,
CostKind);
return Cost;
@@ -1712,9 +1712,9 @@ public:
unsigned Cost = 0;
Cost += thisT()->getArithmeticInstrCost(Opcode, SumTy, CostKind);
- Cost +=
- thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, SumTy, OverflowTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ Cost +=
+ thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, SumTy, OverflowTy,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
return Cost;
}
case Intrinsic::smul_with_overflow:
@@ -1726,14 +1726,14 @@ public:
unsigned ExtOp =
IID == Intrinsic::smul_fix ? Instruction::SExt : Instruction::ZExt;
- TTI::CastContextHint CCH = TTI::CastContextHint::None;
+ TTI::CastContextHint CCH = TTI::CastContextHint::None;
unsigned Cost = 0;
- Cost += 2 * thisT()->getCastInstrCost(ExtOp, ExtTy, MulTy, CCH, CostKind);
+ Cost += 2 * thisT()->getCastInstrCost(ExtOp, ExtTy, MulTy, CCH, CostKind);
Cost +=
thisT()->getArithmeticInstrCost(Instruction::Mul, ExtTy, CostKind);
Cost += 2 * thisT()->getCastInstrCost(Instruction::Trunc, MulTy, ExtTy,
- CCH, CostKind);
+ CCH, CostKind);
Cost += thisT()->getArithmeticInstrCost(Instruction::LShr, MulTy,
CostKind, TTI::OK_AnyValue,
TTI::OK_UniformConstantValue);
@@ -1743,9 +1743,9 @@ public:
CostKind, TTI::OK_AnyValue,
TTI::OK_UniformConstantValue);
- Cost +=
- thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, MulTy, OverflowTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ Cost +=
+ thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, MulTy, OverflowTy,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
return Cost;
}
case Intrinsic::ctpop:
@@ -1754,12 +1754,12 @@ public:
// library call but still not a cheap instruction.
SingleCallCost = TargetTransformInfo::TCC_Expensive;
break;
- case Intrinsic::ctlz:
- ISDs.push_back(ISD::CTLZ);
- break;
- case Intrinsic::cttz:
- ISDs.push_back(ISD::CTTZ);
- break;
+ case Intrinsic::ctlz:
+ ISDs.push_back(ISD::CTLZ);
+ break;
+ case Intrinsic::cttz:
+ ISDs.push_back(ISD::CTTZ);
+ break;
case Intrinsic::bswap:
ISDs.push_back(ISD::BSWAP);
break;
@@ -1795,7 +1795,7 @@ public:
}
}
- auto *MinLegalCostI = std::min_element(LegalCost.begin(), LegalCost.end());
+ auto *MinLegalCostI = std::min_element(LegalCost.begin(), LegalCost.end());
if (MinLegalCostI != LegalCost.end())
return *MinLegalCostI;
@@ -1992,10 +1992,10 @@ public:
(IsPairwise + 1) * thisT()->getShuffleCost(TTI::SK_ExtractSubvector,
Ty, NumVecElts, SubTy);
MinMaxCost +=
- thisT()->getCmpSelInstrCost(CmpOpcode, SubTy, CondTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind) +
+ thisT()->getCmpSelInstrCost(CmpOpcode, SubTy, CondTy,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind) +
thisT()->getCmpSelInstrCost(Instruction::Select, SubTy, CondTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
Ty = SubTy;
++LongVectorCount;
}
@@ -2017,37 +2017,37 @@ public:
thisT()->getShuffleCost(TTI::SK_PermuteSingleSrc, Ty, 0, Ty);
MinMaxCost +=
NumReduxLevels *
- (thisT()->getCmpSelInstrCost(CmpOpcode, Ty, CondTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind) +
+ (thisT()->getCmpSelInstrCost(CmpOpcode, Ty, CondTy,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind) +
thisT()->getCmpSelInstrCost(Instruction::Select, Ty, CondTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind));
+ CmpInst::BAD_ICMP_PREDICATE, CostKind));
// The last min/max should be in vector registers and we counted it above.
// So just need a single extractelement.
return ShuffleCost + MinMaxCost +
thisT()->getVectorInstrCost(Instruction::ExtractElement, Ty, 0);
}
- InstructionCost getExtendedAddReductionCost(bool IsMLA, bool IsUnsigned,
- Type *ResTy, VectorType *Ty,
- TTI::TargetCostKind CostKind) {
- // Without any native support, this is equivalent to the cost of
- // vecreduce.add(ext) or if IsMLA vecreduce.add(mul(ext, ext))
- VectorType *ExtTy = VectorType::get(ResTy, Ty);
- unsigned RedCost = thisT()->getArithmeticReductionCost(
- Instruction::Add, ExtTy, false, CostKind);
- unsigned MulCost = 0;
- unsigned ExtCost = thisT()->getCastInstrCost(
- IsUnsigned ? Instruction::ZExt : Instruction::SExt, ExtTy, Ty,
- TTI::CastContextHint::None, CostKind);
- if (IsMLA) {
- MulCost =
- thisT()->getArithmeticInstrCost(Instruction::Mul, ExtTy, CostKind);
- ExtCost *= 2;
- }
-
- return RedCost + MulCost + ExtCost;
- }
-
+ InstructionCost getExtendedAddReductionCost(bool IsMLA, bool IsUnsigned,
+ Type *ResTy, VectorType *Ty,
+ TTI::TargetCostKind CostKind) {
+ // Without any native support, this is equivalent to the cost of
+ // vecreduce.add(ext) or if IsMLA vecreduce.add(mul(ext, ext))
+ VectorType *ExtTy = VectorType::get(ResTy, Ty);
+ unsigned RedCost = thisT()->getArithmeticReductionCost(
+ Instruction::Add, ExtTy, false, CostKind);
+ unsigned MulCost = 0;
+ unsigned ExtCost = thisT()->getCastInstrCost(
+ IsUnsigned ? Instruction::ZExt : Instruction::SExt, ExtTy, Ty,
+ TTI::CastContextHint::None, CostKind);
+ if (IsMLA) {
+ MulCost =
+ thisT()->getArithmeticInstrCost(Instruction::Mul, ExtTy, CostKind);
+ ExtCost *= 2;
+ }
+
+ return RedCost + MulCost + ExtCost;
+ }
+
unsigned getVectorSplitCost() { return 1; }
/// @}
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/CalcSpillWeights.h b/contrib/libs/llvm12/include/llvm/CodeGen/CalcSpillWeights.h
index 8b7fe2f307..defa1590c1 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/CalcSpillWeights.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/CalcSpillWeights.h
@@ -53,57 +53,57 @@ class VirtRegMap;
class VirtRegAuxInfo {
MachineFunction &MF;
LiveIntervals &LIS;
- const VirtRegMap &VRM;
+ const VirtRegMap &VRM;
const MachineLoopInfo &Loops;
const MachineBlockFrequencyInfo &MBFI;
public:
- VirtRegAuxInfo(MachineFunction &MF, LiveIntervals &LIS,
- const VirtRegMap &VRM, const MachineLoopInfo &Loops,
- const MachineBlockFrequencyInfo &MBFI)
- : MF(MF), LIS(LIS), VRM(VRM), Loops(Loops), MBFI(MBFI) {}
+ VirtRegAuxInfo(MachineFunction &MF, LiveIntervals &LIS,
+ const VirtRegMap &VRM, const MachineLoopInfo &Loops,
+ const MachineBlockFrequencyInfo &MBFI)
+ : MF(MF), LIS(LIS), VRM(VRM), Loops(Loops), MBFI(MBFI) {}
+
+ virtual ~VirtRegAuxInfo() = default;
- virtual ~VirtRegAuxInfo() = default;
-
/// (re)compute li's spill weight and allocation hint.
- void calculateSpillWeightAndHint(LiveInterval &LI);
+ void calculateSpillWeightAndHint(LiveInterval &LI);
- /// 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 beginning of the split artifact. Instructions
+ /// \param LI The live interval to be split.
+ /// \param Start The expected beginning of the split artifact. Instructions
/// before start will not affect the weight.
- /// \param End The expected end of the split artifact. Instructions
+ /// \param End The expected end of the split artifact. Instructions
/// after end will not affect the weight.
/// \return The expected spill weight of the split artifact. Returns
- /// negative weight for unspillable LI.
- float futureWeight(LiveInterval &LI, SlotIndex Start, SlotIndex End);
-
- /// Compute spill weights and allocation hints for all virtual register
- /// live intervals.
- void calculateSpillWeightsAndHints();
-
- protected:
+ /// negative weight for unspillable LI.
+ float futureWeight(LiveInterval &LI, SlotIndex Start, SlotIndex End);
+
+ /// Compute spill weights and allocation hints for all virtual register
+ /// live intervals.
+ void calculateSpillWeightsAndHints();
+
+ protected:
/// Helper function for weight calculations.
- /// (Re)compute LI's spill weight and allocation hint, or, for non null
+ /// (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.
- /// \param LI The live interval for which to compute the weight.
- /// \param Start The expected beginning of the split artifact. Instructions
+ /// artifact of LI that will span between start and end slot indexes.
+ /// \param LI The live interval for which to compute the weight.
+ /// \param Start The expected beginning of the split artifact. Instructions
/// before start will not affect the weight. Relevant for
/// weight calculation of future split artifact.
- /// \param End The expected end of the split artifact. Instructions
+ /// \param End The expected end of the split artifact. Instructions
/// after end will not affect the weight. Relevant for
/// weight calculation of future split artifact.
- /// \return The spill weight. Returns negative weight for unspillable LI.
- float weightCalcHelper(LiveInterval &LI, SlotIndex *Start = nullptr,
- SlotIndex *End = nullptr);
-
- /// Weight normalization function.
- virtual float normalize(float UseDefFreq, unsigned Size,
- unsigned NumInstr) {
- return normalizeSpillWeight(UseDefFreq, Size, NumInstr);
- }
+ /// \return The spill weight. Returns negative weight for unspillable LI.
+ float weightCalcHelper(LiveInterval &LI, SlotIndex *Start = nullptr,
+ SlotIndex *End = nullptr);
+
+ /// Weight normalization function.
+ virtual float normalize(float UseDefFreq, unsigned Size,
+ unsigned NumInstr) {
+ return normalizeSpillWeight(UseDefFreq, Size, NumInstr);
+ }
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/CallingConvLower.h b/contrib/libs/llvm12/include/llvm/CodeGen/CallingConvLower.h
index 85263986db..8383d11725 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/CallingConvLower.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/CallingConvLower.h
@@ -23,7 +23,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/Register.h"
+#include "llvm/CodeGen/Register.h"
#include "llvm/CodeGen/TargetCallingConv.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/MC/MCRegisterInfo.h"
@@ -32,7 +32,7 @@
namespace llvm {
class CCState;
-class MachineFunction;
+class MachineFunction;
class MVT;
class TargetRegisterInfo;
@@ -347,11 +347,11 @@ public:
return Regs.size();
}
- void DeallocateReg(MCPhysReg Reg) {
- assert(isAllocated(Reg) && "Trying to deallocate an unallocated register");
- MarkUnallocated(Reg);
- }
-
+ void DeallocateReg(MCPhysReg Reg) {
+ assert(isAllocated(Reg) && "Trying to deallocate an unallocated register");
+ MarkUnallocated(Reg);
+ }
+
/// AllocateReg - Attempt to allocate one register. If it is not available,
/// return zero. Otherwise, return the register, marking it and any aliases
/// as allocated.
@@ -445,7 +445,7 @@ public:
return AllocateStack(Size, Align(Alignment));
}
- void ensureMaxAlignment(Align Alignment);
+ void ensureMaxAlignment(Align Alignment);
/// Version of AllocateStack with extra register to be shadowed.
LLVM_ATTRIBUTE_DEPRECATED(unsigned AllocateStack(unsigned Size,
@@ -582,8 +582,8 @@ public:
private:
/// MarkAllocated - Mark a register and all of its aliases as allocated.
void MarkAllocated(MCPhysReg Reg);
-
- void MarkUnallocated(MCPhysReg Reg);
+
+ void MarkUnallocated(MCPhysReg Reg);
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/CodeGenPassBuilder.h b/contrib/libs/llvm12/include/llvm/CodeGen/CodeGenPassBuilder.h
index e23ff00b9f..cf1633258f 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/CodeGenPassBuilder.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/CodeGenPassBuilder.h
@@ -1,1155 +1,1155 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- Construction of codegen pass pipelines ------------------*- C++ -*--===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-/// \file
-///
-/// Interfaces for registering analysis passes, producing common pass manager
-/// configurations, and parsing of pass pipelines.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_CODEGENPASSBUILDER_H
-#define LLVM_CODEGEN_CODEGENPASSBUILDER_H
-
-#include "llvm/ADT/FunctionExtras.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/BasicAliasAnalysis.h"
-#include "llvm/Analysis/CFLAndersAliasAnalysis.h"
-#include "llvm/Analysis/CFLSteensAliasAnalysis.h"
-#include "llvm/Analysis/ScopedNoAliasAA.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
-#include "llvm/CodeGen/ExpandReductions.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/MachinePassManager.h"
-#include "llvm/CodeGen/PreISelIntrinsicLowering.h"
-#include "llvm/CodeGen/UnreachableBlockElim.h"
-#include "llvm/IR/IRPrintingPasses.h"
-#include "llvm/IR/PassManager.h"
-#include "llvm/IR/Verifier.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCTargetOptions.h"
-#include "llvm/Support/CodeGen.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Target/CGPassBuilderOption.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/Transforms/Scalar/ConstantHoisting.h"
-#include "llvm/Transforms/Scalar/LoopPassManager.h"
-#include "llvm/Transforms/Scalar/LoopStrengthReduce.h"
-#include "llvm/Transforms/Scalar/LowerConstantIntrinsics.h"
-#include "llvm/Transforms/Scalar/MergeICmps.h"
-#include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h"
-#include "llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h"
-#include "llvm/Transforms/Utils.h"
-#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
-#include "llvm/Transforms/Utils/LowerInvoke.h"
-#include <cassert>
-#include <string>
-#include <type_traits>
-#include <utility>
-
-namespace llvm {
-
-// FIXME: Dummy target independent passes definitions that have not yet been
-// ported to new pass manager. Once they do, remove these.
-#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
- struct PASS_NAME : public PassInfoMixin<PASS_NAME> { \
- template <typename... Ts> PASS_NAME(Ts &&...) {} \
- PreservedAnalyses run(Function &, FunctionAnalysisManager &) { \
- return PreservedAnalyses::all(); \
- } \
- };
-#define DUMMY_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
- struct PASS_NAME : public PassInfoMixin<PASS_NAME> { \
- template <typename... Ts> PASS_NAME(Ts &&...) {} \
- PreservedAnalyses run(Module &, ModuleAnalysisManager &) { \
- return PreservedAnalyses::all(); \
- } \
- };
-#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
- struct PASS_NAME : public PassInfoMixin<PASS_NAME> { \
- template <typename... Ts> PASS_NAME(Ts &&...) {} \
- Error run(Module &, MachineFunctionAnalysisManager &) { \
- return Error::success(); \
- } \
- PreservedAnalyses run(MachineFunction &, \
- MachineFunctionAnalysisManager &) { \
- llvm_unreachable("this api is to make new PM api happy"); \
- } \
- static AnalysisKey Key; \
- };
-#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
- struct PASS_NAME : public PassInfoMixin<PASS_NAME> { \
- template <typename... Ts> PASS_NAME(Ts &&...) {} \
- PreservedAnalyses run(MachineFunction &, \
- MachineFunctionAnalysisManager &) { \
- return PreservedAnalyses::all(); \
- } \
- static AnalysisKey Key; \
- };
-#include "MachinePassRegistry.def"
-
-/// This class provides access to building LLVM's passes.
-///
-/// Its members provide the baseline state available to passes during their
-/// construction. The \c MachinePassRegistry.def file specifies how to construct
-/// all of the built-in passes, and those may reference these members during
-/// construction.
-template <typename DerivedT> class CodeGenPassBuilder {
-public:
- explicit CodeGenPassBuilder(LLVMTargetMachine &TM, CGPassBuilderOption Opts,
- PassInstrumentationCallbacks *PIC)
- : TM(TM), Opt(Opts), PIC(PIC) {
- // Target could set CGPassBuilderOption::MISchedPostRA to true to achieve
- // substitutePass(&PostRASchedulerID, &PostMachineSchedulerID)
-
- // Target should override TM.Options.EnableIPRA in their target-specific
- // LLVMTM ctor. See TargetMachine::setGlobalISel for example.
- if (Opt.EnableIPRA)
- TM.Options.EnableIPRA = *Opt.EnableIPRA;
-
- if (Opt.EnableGlobalISelAbort)
- TM.Options.GlobalISelAbort = *Opt.EnableGlobalISelAbort;
-
- if (!Opt.OptimizeRegAlloc)
- Opt.OptimizeRegAlloc = getOptLevel() != CodeGenOpt::None;
- }
-
- Error buildPipeline(ModulePassManager &MPM, MachineFunctionPassManager &MFPM,
- raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
- CodeGenFileType FileType) const;
-
- void registerModuleAnalyses(ModuleAnalysisManager &) const;
- void registerFunctionAnalyses(FunctionAnalysisManager &) const;
- void registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &) const;
- std::pair<StringRef, bool> getPassNameFromLegacyName(StringRef) const;
-
- void registerAnalyses(MachineFunctionAnalysisManager &MFAM) const {
- registerModuleAnalyses(*MFAM.MAM);
- registerFunctionAnalyses(*MFAM.FAM);
- registerMachineFunctionAnalyses(MFAM);
- }
-
- PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const {
- return PIC;
- }
-
-protected:
- template <typename PassT> using has_key_t = decltype(PassT::Key);
-
- template <typename PassT>
- using is_module_pass_t = decltype(std::declval<PassT &>().run(
- std::declval<Module &>(), std::declval<ModuleAnalysisManager &>()));
-
- template <typename PassT>
- using is_function_pass_t = decltype(std::declval<PassT &>().run(
- std::declval<Function &>(), std::declval<FunctionAnalysisManager &>()));
-
- // Function object to maintain state while adding codegen IR passes.
- class AddIRPass {
- public:
- AddIRPass(ModulePassManager &MPM, bool DebugPM, bool Check = true)
- : MPM(MPM), FPM(DebugPM) {
- if (Check)
- AddingFunctionPasses = false;
- }
- ~AddIRPass() {
- MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
- }
-
- // Add Function Pass
- template <typename PassT>
- std::enable_if_t<is_detected<is_function_pass_t, PassT>::value>
- operator()(PassT &&Pass) {
- if (AddingFunctionPasses && !*AddingFunctionPasses)
- AddingFunctionPasses = true;
- FPM.addPass(std::forward<PassT>(Pass));
- }
-
- // Add Module Pass
- template <typename PassT>
- std::enable_if_t<is_detected<is_module_pass_t, PassT>::value &&
- !is_detected<is_function_pass_t, PassT>::value>
- operator()(PassT &&Pass) {
- assert((!AddingFunctionPasses || !*AddingFunctionPasses) &&
- "could not add module pass after adding function pass");
- MPM.addPass(std::forward<PassT>(Pass));
- }
-
- private:
- ModulePassManager &MPM;
- FunctionPassManager FPM;
- // The codegen IR pipeline are mostly function passes with the exceptions of
- // a few loop and module passes. `AddingFunctionPasses` make sures that
- // we could only add module passes at the beginning of the pipeline. Once
- // we begin adding function passes, we could no longer add module passes.
- // This special-casing introduces less adaptor passes. If we have the need
- // of adding module passes after function passes, we could change the
- // implementation to accommodate that.
- Optional<bool> AddingFunctionPasses;
- };
-
- // Function object to maintain state while adding codegen machine passes.
- class AddMachinePass {
- public:
- AddMachinePass(MachineFunctionPassManager &PM) : PM(PM) {}
-
- template <typename PassT> void operator()(PassT &&Pass) {
- static_assert(
- is_detected<has_key_t, PassT>::value,
- "Machine function pass must define a static member variable `Key`.");
- for (auto &C : BeforeCallbacks)
- if (!C(&PassT::Key))
- return;
- PM.addPass(std::forward<PassT>(Pass));
- for (auto &C : AfterCallbacks)
- C(&PassT::Key);
- }
-
- template <typename PassT> void insertPass(AnalysisKey *ID, PassT Pass) {
- AfterCallbacks.emplace_back(
- [this, ID, Pass = std::move(Pass)](AnalysisKey *PassID) {
- if (PassID == ID)
- this->PM.addPass(std::move(Pass));
- });
- }
-
- void disablePass(AnalysisKey *ID) {
- BeforeCallbacks.emplace_back(
- [ID](AnalysisKey *PassID) { return PassID != ID; });
- }
-
- MachineFunctionPassManager releasePM() { return std::move(PM); }
-
- private:
- MachineFunctionPassManager &PM;
- SmallVector<llvm::unique_function<bool(AnalysisKey *)>, 4> BeforeCallbacks;
- SmallVector<llvm::unique_function<void(AnalysisKey *)>, 4> AfterCallbacks;
- };
-
- LLVMTargetMachine &TM;
- CGPassBuilderOption Opt;
- PassInstrumentationCallbacks *PIC;
-
- /// Target override these hooks to parse target-specific analyses.
- void registerTargetAnalysis(ModuleAnalysisManager &) const {}
- void registerTargetAnalysis(FunctionAnalysisManager &) const {}
- void registerTargetAnalysis(MachineFunctionAnalysisManager &) const {}
- std::pair<StringRef, bool> getTargetPassNameFromLegacyName(StringRef) const {
- return {"", false};
- }
-
- template <typename TMC> TMC &getTM() const { return static_cast<TMC &>(TM); }
- CodeGenOpt::Level getOptLevel() const { return TM.getOptLevel(); }
-
- /// Check whether or not GlobalISel should abort on error.
- /// When this is disabled, GlobalISel will fall back on SDISel instead of
- /// erroring out.
- bool isGlobalISelAbortEnabled() const {
- return TM.Options.GlobalISelAbort == GlobalISelAbortMode::Enable;
- }
-
- /// Check whether or not a diagnostic should be emitted when GlobalISel
- /// uses the fallback path. In other words, it will emit a diagnostic
- /// when GlobalISel failed and isGlobalISelAbortEnabled is false.
- bool reportDiagnosticWhenGlobalISelFallback() const {
- return TM.Options.GlobalISelAbort == GlobalISelAbortMode::DisableWithDiag;
- }
-
- /// addInstSelector - This method should install an instruction selector pass,
- /// which converts from LLVM code to machine instructions.
- Error addInstSelector(AddMachinePass &) const {
- return make_error<StringError>("addInstSelector is not overridden",
- inconvertibleErrorCode());
- }
-
- /// Add passes that optimize instruction level parallelism for out-of-order
- /// targets. These passes are run while the machine code is still in SSA
- /// form, so they can use MachineTraceMetrics to control their heuristics.
- ///
- /// All passes added here should preserve the MachineDominatorTree,
- /// MachineLoopInfo, and MachineTraceMetrics analyses.
- void addILPOpts(AddMachinePass &) const {}
-
- /// This method may be implemented by targets that want to run passes
- /// immediately before register allocation.
- void addPreRegAlloc(AddMachinePass &) const {}
-
- /// addPreRewrite - Add passes to the optimized register allocation pipeline
- /// after register allocation is complete, but before virtual registers are
- /// rewritten to physical registers.
- ///
- /// These passes must preserve VirtRegMap and LiveIntervals, and when running
- /// after RABasic or RAGreedy, they should take advantage of LiveRegMatrix.
- /// When these passes run, VirtRegMap contains legal physreg assignments for
- /// all virtual registers.
- ///
- /// Note if the target overloads addRegAssignAndRewriteOptimized, this may not
- /// be honored. This is also not generally used for the the fast variant,
- /// where the allocation and rewriting are done in one pass.
- void addPreRewrite(AddMachinePass &) const {}
-
- /// Add passes to be run immediately after virtual registers are rewritten
- /// to physical registers.
- void addPostRewrite(AddMachinePass &) const {}
-
- /// This method may be implemented by targets that want to run passes after
- /// register allocation pass pipeline but before prolog-epilog insertion.
- void addPostRegAlloc(AddMachinePass &) const {}
-
- /// This method may be implemented by targets that want to run passes after
- /// prolog-epilog insertion and before the second instruction scheduling pass.
- void addPreSched2(AddMachinePass &) const {}
-
- /// This pass may be implemented by targets that want to run passes
- /// immediately before machine code is emitted.
- void addPreEmitPass(AddMachinePass &) const {}
-
- /// Targets may add passes immediately before machine code is emitted in this
- /// callback. This is called even later than `addPreEmitPass`.
- // FIXME: Rename `addPreEmitPass` to something more sensible given its actual
- // position and remove the `2` suffix here as this callback is what
- // `addPreEmitPass` *should* be but in reality isn't.
- void addPreEmitPass2(AddMachinePass &) const {}
-
- /// {{@ For GlobalISel
- ///
-
- /// addPreISel - This method should add any "last minute" LLVM->LLVM
- /// passes (which are run just before instruction selector).
- void addPreISel(AddIRPass &) const {
- llvm_unreachable("addPreISel is not overridden");
- }
-
- /// This method should install an IR translator pass, which converts from
- /// LLVM code to machine instructions with possibly generic opcodes.
- Error addIRTranslator(AddMachinePass &) const {
- return make_error<StringError>("addIRTranslator is not overridden",
- inconvertibleErrorCode());
- }
-
- /// This method may be implemented by targets that want to run passes
- /// immediately before legalization.
- void addPreLegalizeMachineIR(AddMachinePass &) const {}
-
- /// This method should install a legalize pass, which converts the instruction
- /// sequence into one that can be selected by the target.
- Error addLegalizeMachineIR(AddMachinePass &) const {
- return make_error<StringError>("addLegalizeMachineIR is not overridden",
- inconvertibleErrorCode());
- }
-
- /// This method may be implemented by targets that want to run passes
- /// immediately before the register bank selection.
- void addPreRegBankSelect(AddMachinePass &) const {}
-
- /// This method should install a register bank selector pass, which
- /// assigns register banks to virtual registers without a register
- /// class or register banks.
- Error addRegBankSelect(AddMachinePass &) const {
- return make_error<StringError>("addRegBankSelect is not overridden",
- inconvertibleErrorCode());
- }
-
- /// This method may be implemented by targets that want to run passes
- /// immediately before the (global) instruction selection.
- void addPreGlobalInstructionSelect(AddMachinePass &) const {}
-
- /// This method should install a (global) instruction selector pass, which
- /// converts possibly generic instructions to fully target-specific
- /// instructions, thereby constraining all generic virtual registers to
- /// register classes.
- Error addGlobalInstructionSelect(AddMachinePass &) const {
- return make_error<StringError>(
- "addGlobalInstructionSelect is not overridden",
- inconvertibleErrorCode());
- }
- /// @}}
-
- /// High level function that adds all passes necessary to go from llvm IR
- /// representation to the MI representation.
- /// Adds IR based lowering and target specific optimization passes and finally
- /// the core instruction selection passes.
- /// \returns true if an error occurred, false otherwise.
- void addISelPasses(AddIRPass &) const;
-
- /// Add the actual instruction selection passes. This does not include
- /// preparation passes on IR.
- Error addCoreISelPasses(AddMachinePass &) const;
-
- /// Add the complete, standard set of LLVM CodeGen passes.
- /// Fully developed targets will not generally override this.
- Error addMachinePasses(AddMachinePass &) const;
-
- /// Add passes to lower exception handling for the code generator.
- void addPassesToHandleExceptions(AddIRPass &) const;
-
- /// Add common target configurable passes that perform LLVM IR to IR
- /// transforms following machine independent optimization.
- void addIRPasses(AddIRPass &) const;
-
- /// Add pass to prepare the LLVM IR for code generation. This should be done
- /// before exception handling preparation passes.
- void addCodeGenPrepare(AddIRPass &) const;
-
- /// Add common passes that perform LLVM IR to IR transforms in preparation for
- /// instruction selection.
- void addISelPrepare(AddIRPass &) const;
-
- /// Methods with trivial inline returns are convenient points in the common
- /// codegen pass pipeline where targets may insert passes. Methods with
- /// out-of-line standard implementations are major CodeGen stages called by
- /// addMachinePasses. Some targets may override major stages when inserting
- /// passes is insufficient, but maintaining overriden stages is more work.
- ///
-
- /// addMachineSSAOptimization - Add standard passes that optimize machine
- /// instructions in SSA form.
- void addMachineSSAOptimization(AddMachinePass &) const;
-
- /// addFastRegAlloc - Add the minimum set of target-independent passes that
- /// are required for fast register allocation.
- Error addFastRegAlloc(AddMachinePass &) const;
-
- /// addOptimizedRegAlloc - Add passes related to register allocation.
- /// LLVMTargetMachine provides standard regalloc passes for most targets.
- void addOptimizedRegAlloc(AddMachinePass &) const;
-
- /// Add passes that optimize machine instructions after register allocation.
- void addMachineLateOptimization(AddMachinePass &) const;
-
- /// addGCPasses - Add late codegen passes that analyze code for garbage
- /// collection. This should return true if GC info should be printed after
- /// these passes.
- void addGCPasses(AddMachinePass &) const {}
-
- /// Add standard basic block placement passes.
- void addBlockPlacement(AddMachinePass &) const;
-
- using CreateMCStreamer =
- std::function<Expected<std::unique_ptr<MCStreamer>>(MCContext &)>;
- void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const {
- llvm_unreachable("addAsmPrinter is not overridden");
- }
-
- /// Utilities for targets to add passes to the pass manager.
- ///
-
- /// createTargetRegisterAllocator - Create the register allocator pass for
- /// this target at the current optimization level.
- void addTargetRegisterAllocator(AddMachinePass &, bool Optimized) const;
-
- /// addMachinePasses helper to create the target-selected or overriden
- /// regalloc pass.
- void addRegAllocPass(AddMachinePass &, bool Optimized) const;
-
- /// Add core register alloator passes which do the actual register assignment
- /// and rewriting. \returns true if any passes were added.
- Error addRegAssignmentFast(AddMachinePass &) const;
- Error addRegAssignmentOptimized(AddMachinePass &) const;
-
-private:
- DerivedT &derived() { return static_cast<DerivedT &>(*this); }
- const DerivedT &derived() const {
- return static_cast<const DerivedT &>(*this);
- }
-};
-
-template <typename Derived>
-Error CodeGenPassBuilder<Derived>::buildPipeline(
- ModulePassManager &MPM, MachineFunctionPassManager &MFPM,
- raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
- CodeGenFileType FileType) const {
- AddIRPass addIRPass(MPM, Opt.DebugPM);
- addISelPasses(addIRPass);
-
- AddMachinePass addPass(MFPM);
- if (auto Err = addCoreISelPasses(addPass))
- return std::move(Err);
-
- if (auto Err = derived().addMachinePasses(addPass))
- return std::move(Err);
-
- derived().addAsmPrinter(
- addPass, [this, &Out, DwoOut, FileType](MCContext &Ctx) {
- return this->TM.createMCStreamer(Out, DwoOut, FileType, Ctx);
- });
-
- addPass(FreeMachineFunctionPass());
- return Error::success();
-}
-
-static inline AAManager registerAAAnalyses(CFLAAType UseCFLAA) {
- AAManager AA;
-
- // The order in which these are registered determines their priority when
- // being queried.
-
- switch (UseCFLAA) {
- case CFLAAType::Steensgaard:
- AA.registerFunctionAnalysis<CFLSteensAA>();
- break;
- case CFLAAType::Andersen:
- AA.registerFunctionAnalysis<CFLAndersAA>();
- break;
- case CFLAAType::Both:
- AA.registerFunctionAnalysis<CFLAndersAA>();
- AA.registerFunctionAnalysis<CFLSteensAA>();
- break;
- default:
- break;
- }
-
- // Basic AliasAnalysis support.
- // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that
- // BasicAliasAnalysis wins if they disagree. This is intended to help
- // support "obvious" type-punning idioms.
- AA.registerFunctionAnalysis<TypeBasedAA>();
- AA.registerFunctionAnalysis<ScopedNoAliasAA>();
- AA.registerFunctionAnalysis<BasicAA>();
-
- return AA;
-}
-
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::registerModuleAnalyses(
- ModuleAnalysisManager &MAM) const {
-#define MODULE_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR) \
- MAM.registerPass([&] { return PASS_NAME CONSTRUCTOR; });
-#include "MachinePassRegistry.def"
- derived().registerTargetAnalysis(MAM);
-}
-
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::registerFunctionAnalyses(
- FunctionAnalysisManager &FAM) const {
- FAM.registerPass([this] { return registerAAAnalyses(this->Opt.UseCFLAA); });
-
-#define FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR) \
- FAM.registerPass([&] { return PASS_NAME CONSTRUCTOR; });
-#include "MachinePassRegistry.def"
- derived().registerTargetAnalysis(FAM);
-}
-
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::registerMachineFunctionAnalyses(
- MachineFunctionAnalysisManager &MFAM) const {
-#define MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR) \
- MFAM.registerPass([&] { return PASS_NAME CONSTRUCTOR; });
-#include "MachinePassRegistry.def"
- derived().registerTargetAnalysis(MFAM);
-}
-
-// FIXME: For new PM, use pass name directly in commandline seems good.
-// Translate stringfied pass name to its old commandline name. Returns the
-// matching legacy name and a boolean value indicating if the pass is a machine
-// pass.
-template <typename Derived>
-std::pair<StringRef, bool>
-CodeGenPassBuilder<Derived>::getPassNameFromLegacyName(StringRef Name) const {
- std::pair<StringRef, bool> Ret;
- if (Name.empty())
- return Ret;
-
-#define FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
- if (Name == NAME) \
- Ret = {#PASS_NAME, false};
-#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
- if (Name == NAME) \
- Ret = {#PASS_NAME, false};
-#define MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
- if (Name == NAME) \
- Ret = {#PASS_NAME, false};
-#define DUMMY_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
- if (Name == NAME) \
- Ret = {#PASS_NAME, false};
-#define MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
- if (Name == NAME) \
- Ret = {#PASS_NAME, true};
-#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
- if (Name == NAME) \
- Ret = {#PASS_NAME, true};
-#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
- if (Name == NAME) \
- Ret = {#PASS_NAME, true};
-#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
- if (Name == NAME) \
- Ret = {#PASS_NAME, true};
-#include "llvm/CodeGen/MachinePassRegistry.def"
-
- if (Ret.first.empty())
- Ret = derived().getTargetPassNameFromLegacyName(Name);
-
- if (Ret.first.empty())
- report_fatal_error(Twine('\"') + Twine(Name) +
- Twine("\" pass could not be found."));
-
- return Ret;
-}
-
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addISelPasses(AddIRPass &addPass) const {
- if (TM.useEmulatedTLS())
- addPass(LowerEmuTLSPass());
-
- addPass(PreISelIntrinsicLoweringPass());
-
- derived().addIRPasses(addPass);
- derived().addCodeGenPrepare(addPass);
- addPassesToHandleExceptions(addPass);
- derived().addISelPrepare(addPass);
-}
-
-/// Add common target configurable passes that perform LLVM IR to IR transforms
-/// following machine independent optimization.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addIRPasses(AddIRPass &addPass) const {
- // Before running any passes, run the verifier to determine if the input
- // coming from the front-end and/or optimizer is valid.
- if (!Opt.DisableVerify)
- addPass(VerifierPass());
-
- // Run loop strength reduction before anything else.
- if (getOptLevel() != CodeGenOpt::None && !Opt.DisableLSR) {
- addPass(createFunctionToLoopPassAdaptor(
- LoopStrengthReducePass(), /*UseMemorySSA*/ true, Opt.DebugPM));
- // FIXME: use -stop-after so we could remove PrintLSR
- if (Opt.PrintLSR)
- addPass(PrintFunctionPass(dbgs(), "\n\n*** Code after LSR ***\n"));
- }
-
- if (getOptLevel() != CodeGenOpt::None) {
- // The MergeICmpsPass tries to create memcmp calls by grouping sequences of
- // loads and compares. ExpandMemCmpPass then tries to expand those calls
- // into optimally-sized loads and compares. The transforms are enabled by a
- // target lowering hook.
- if (!Opt.DisableMergeICmps)
- addPass(MergeICmpsPass());
- addPass(ExpandMemCmpPass());
- }
-
- // Run GC lowering passes for builtin collectors
- // TODO: add a pass insertion point here
- addPass(GCLoweringPass());
- addPass(ShadowStackGCLoweringPass());
- addPass(LowerConstantIntrinsicsPass());
-
- // Make sure that no unreachable blocks are instruction selected.
- addPass(UnreachableBlockElimPass());
-
- // Prepare expensive constants for SelectionDAG.
- if (getOptLevel() != CodeGenOpt::None && !Opt.DisableConstantHoisting)
- addPass(ConstantHoistingPass());
-
- if (getOptLevel() != CodeGenOpt::None && !Opt.DisablePartialLibcallInlining)
- addPass(PartiallyInlineLibCallsPass());
-
- // Instrument function entry and exit, e.g. with calls to mcount().
- addPass(EntryExitInstrumenterPass(/*PostInlining=*/true));
-
- // Add scalarization of target's unsupported masked memory intrinsics pass.
- // the unsupported intrinsic will be replaced with a chain of basic blocks,
- // that stores/loads element one-by-one if the appropriate mask bit is set.
- addPass(ScalarizeMaskedMemIntrinPass());
-
- // Expand reduction intrinsics into shuffle sequences if the target wants to.
- addPass(ExpandReductionsPass());
-}
-
-/// Turn exception handling constructs into something the code generators can
-/// handle.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addPassesToHandleExceptions(
- AddIRPass &addPass) const {
- const MCAsmInfo *MCAI = TM.getMCAsmInfo();
- assert(MCAI && "No MCAsmInfo");
- switch (MCAI->getExceptionHandlingType()) {
- case ExceptionHandling::SjLj:
- // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both
- // Dwarf EH prepare needs to be run after SjLj prepare. Otherwise,
- // catch info can get misplaced when a selector ends up more than one block
- // removed from the parent invoke(s). This could happen when a landing
- // pad is shared by multiple invokes and is also a target of a normal
- // edge from elsewhere.
- addPass(SjLjEHPreparePass());
- LLVM_FALLTHROUGH;
- case ExceptionHandling::DwarfCFI:
- case ExceptionHandling::ARM:
- case ExceptionHandling::AIX:
- addPass(DwarfEHPass(getOptLevel()));
- break;
- case ExceptionHandling::WinEH:
- // We support using both GCC-style and MSVC-style exceptions on Windows, so
- // add both preparation passes. Each pass will only actually run if it
- // recognizes the personality function.
- addPass(WinEHPass());
- addPass(DwarfEHPass(getOptLevel()));
- break;
- case ExceptionHandling::Wasm:
- // Wasm EH uses Windows EH instructions, but it does not need to demote PHIs
- // on catchpads and cleanuppads because it does not outline them into
- // funclets. Catchswitch blocks are not lowered in SelectionDAG, so we
- // should remove PHIs there.
- addPass(WinEHPass(/*DemoteCatchSwitchPHIOnly=*/false));
- addPass(WasmEHPass());
- break;
- case ExceptionHandling::None:
- addPass(LowerInvokePass());
-
- // The lower invoke pass may create unreachable code. Remove it.
- addPass(UnreachableBlockElimPass());
- break;
- }
-}
-
-/// Add pass to prepare the LLVM IR for code generation. This should be done
-/// before exception handling preparation passes.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addCodeGenPrepare(AddIRPass &addPass) const {
- if (getOptLevel() != CodeGenOpt::None && !Opt.DisableCGP)
- addPass(CodeGenPreparePass());
- // TODO: Default ctor'd RewriteSymbolPass is no-op.
- // addPass(RewriteSymbolPass());
-}
-
-/// Add common passes that perform LLVM IR to IR transforms in preparation for
-/// instruction selection.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addISelPrepare(AddIRPass &addPass) const {
- derived().addPreISel(addPass);
-
- // Add both the safe stack and the stack protection passes: each of them will
- // only protect functions that have corresponding attributes.
- addPass(SafeStackPass());
- addPass(StackProtectorPass());
-
- if (Opt.PrintISelInput)
- addPass(PrintFunctionPass(dbgs(),
- "\n\n*** Final LLVM Code input to ISel ***\n"));
-
- // All passes which modify the LLVM IR are now complete; run the verifier
- // to ensure that the IR is valid.
- if (!Opt.DisableVerify)
- addPass(VerifierPass());
-}
-
-template <typename Derived>
-Error CodeGenPassBuilder<Derived>::addCoreISelPasses(
- AddMachinePass &addPass) const {
- // Enable FastISel with -fast-isel, but allow that to be overridden.
- TM.setO0WantsFastISel(Opt.EnableFastISelOption.getValueOr(true));
-
- // Determine an instruction selector.
- enum class SelectorType { SelectionDAG, FastISel, GlobalISel };
- SelectorType Selector;
-
- if (Opt.EnableFastISelOption && *Opt.EnableFastISelOption == true)
- Selector = SelectorType::FastISel;
- else if ((Opt.EnableGlobalISelOption &&
- *Opt.EnableGlobalISelOption == true) ||
- (TM.Options.EnableGlobalISel &&
- (!Opt.EnableGlobalISelOption ||
- *Opt.EnableGlobalISelOption == false)))
- Selector = SelectorType::GlobalISel;
- else if (TM.getOptLevel() == CodeGenOpt::None && TM.getO0WantsFastISel())
- Selector = SelectorType::FastISel;
- else
- Selector = SelectorType::SelectionDAG;
-
- // Set consistently TM.Options.EnableFastISel and EnableGlobalISel.
- if (Selector == SelectorType::FastISel) {
- TM.setFastISel(true);
- TM.setGlobalISel(false);
- } else if (Selector == SelectorType::GlobalISel) {
- TM.setFastISel(false);
- TM.setGlobalISel(true);
- }
-
- // Add instruction selector passes.
- if (Selector == SelectorType::GlobalISel) {
- if (auto Err = derived().addIRTranslator(addPass))
- return std::move(Err);
-
- derived().addPreLegalizeMachineIR(addPass);
-
- if (auto Err = derived().addLegalizeMachineIR(addPass))
- return std::move(Err);
-
- // Before running the register bank selector, ask the target if it
- // wants to run some passes.
- derived().addPreRegBankSelect(addPass);
-
- if (auto Err = derived().addRegBankSelect(addPass))
- return std::move(Err);
-
- derived().addPreGlobalInstructionSelect(addPass);
-
- if (auto Err = derived().addGlobalInstructionSelect(addPass))
- return std::move(Err);
-
- // Pass to reset the MachineFunction if the ISel failed.
- addPass(ResetMachineFunctionPass(reportDiagnosticWhenGlobalISelFallback(),
- isGlobalISelAbortEnabled()));
-
- // Provide a fallback path when we do not want to abort on
- // not-yet-supported input.
- if (!isGlobalISelAbortEnabled())
- if (auto Err = derived().addInstSelector(addPass))
- return std::move(Err);
-
- } else if (auto Err = derived().addInstSelector(addPass))
- return std::move(Err);
-
- // Expand pseudo-instructions emitted by ISel. Don't run the verifier before
- // FinalizeISel.
- addPass(FinalizeISelPass());
-
- // // Print the instruction selected machine code...
- // printAndVerify("After Instruction Selection");
-
- return Error::success();
-}
-
-/// Add the complete set of target-independent postISel code generator passes.
-///
-/// This can be read as the standard order of major LLVM CodeGen stages. Stages
-/// with nontrivial configuration or multiple passes are broken out below in
-/// add%Stage routines.
-///
-/// Any CodeGenPassBuilder<Derived>::addXX routine may be overriden by the
-/// Target. The addPre/Post methods with empty header implementations allow
-/// injecting target-specific fixups just before or after major stages.
-/// Additionally, targets have the flexibility to change pass order within a
-/// stage by overriding default implementation of add%Stage routines below. Each
-/// technique has maintainability tradeoffs because alternate pass orders are
-/// not well supported. addPre/Post works better if the target pass is easily
-/// tied to a common pass. But if it has subtle dependencies on multiple passes,
-/// the target should override the stage instead.
-template <typename Derived>
-Error CodeGenPassBuilder<Derived>::addMachinePasses(
- AddMachinePass &addPass) const {
- // Add passes that optimize machine instructions in SSA form.
- if (getOptLevel() != CodeGenOpt::None) {
- derived().addMachineSSAOptimization(addPass);
- } else {
- // If the target requests it, assign local variables to stack slots relative
- // to one another and simplify frame index references where possible.
- addPass(LocalStackSlotPass());
- }
-
- if (TM.Options.EnableIPRA)
- addPass(RegUsageInfoPropagationPass());
-
- // Run pre-ra passes.
- derived().addPreRegAlloc(addPass);
-
- // Run register allocation and passes that are tightly coupled with it,
- // including phi elimination and scheduling.
- if (*Opt.OptimizeRegAlloc) {
- derived().addOptimizedRegAlloc(addPass);
- } else {
- if (auto Err = derived().addFastRegAlloc(addPass))
- return Err;
- }
-
- // Run post-ra passes.
- derived().addPostRegAlloc(addPass);
-
- // Insert prolog/epilog code. Eliminate abstract frame index references...
- if (getOptLevel() != CodeGenOpt::None) {
- addPass(PostRAMachineSinkingPass());
- addPass(ShrinkWrapPass());
- }
-
- addPass(PrologEpilogInserterPass());
-
- /// Add passes that optimize machine instructions after register allocation.
- if (getOptLevel() != CodeGenOpt::None)
- derived().addMachineLateOptimization(addPass);
-
- // Expand pseudo instructions before second scheduling pass.
- addPass(ExpandPostRAPseudosPass());
-
- // Run pre-sched2 passes.
- derived().addPreSched2(addPass);
-
- if (Opt.EnableImplicitNullChecks)
- addPass(ImplicitNullChecksPass());
-
- // Second pass scheduler.
- // Let Target optionally insert this pass by itself at some other
- // point.
- if (getOptLevel() != CodeGenOpt::None &&
- !TM.targetSchedulesPostRAScheduling()) {
- if (Opt.MISchedPostRA)
- addPass(PostMachineSchedulerPass());
- else
- addPass(PostRASchedulerPass());
- }
-
- // GC
- derived().addGCPasses(addPass);
-
- // Basic block placement.
- if (getOptLevel() != CodeGenOpt::None)
- derived().addBlockPlacement(addPass);
-
- // Insert before XRay Instrumentation.
- addPass(FEntryInserterPass());
-
- addPass(XRayInstrumentationPass());
- addPass(PatchableFunctionPass());
-
- derived().addPreEmitPass(addPass);
-
- if (TM.Options.EnableIPRA)
- // Collect register usage information and produce a register mask of
- // clobbered registers, to be used to optimize call sites.
- addPass(RegUsageInfoCollectorPass());
-
- addPass(FuncletLayoutPass());
-
- addPass(StackMapLivenessPass());
- addPass(LiveDebugValuesPass());
-
- if (TM.Options.EnableMachineOutliner && getOptLevel() != CodeGenOpt::None &&
- Opt.EnableMachineOutliner != RunOutliner::NeverOutline) {
- bool RunOnAllFunctions =
- (Opt.EnableMachineOutliner == RunOutliner::AlwaysOutline);
- bool AddOutliner = RunOnAllFunctions || TM.Options.SupportsDefaultOutlining;
- if (AddOutliner)
- addPass(MachineOutlinerPass(RunOnAllFunctions));
- }
-
- // Add passes that directly emit MI after all other MI passes.
- derived().addPreEmitPass2(addPass);
-
- return Error::success();
-}
-
-/// Add passes that optimize machine instructions in SSA form.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addMachineSSAOptimization(
- AddMachinePass &addPass) const {
- // Pre-ra tail duplication.
- addPass(EarlyTailDuplicatePass());
-
- // Optimize PHIs before DCE: removing dead PHI cycles may make more
- // instructions dead.
- addPass(OptimizePHIsPass());
-
- // This pass merges large allocas. StackSlotColoring is a different pass
- // which merges spill slots.
- addPass(StackColoringPass());
-
- // If the target requests it, assign local variables to stack slots relative
- // to one another and simplify frame index references where possible.
- addPass(LocalStackSlotPass());
-
- // With optimization, dead code should already be eliminated. However
- // there is one known exception: lowered code for arguments that are only
- // used by tail calls, where the tail calls reuse the incoming stack
- // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll).
- addPass(DeadMachineInstructionElimPass());
-
- // Allow targets to insert passes that improve instruction level parallelism,
- // like if-conversion. Such passes will typically need dominator trees and
- // loop info, just like LICM and CSE below.
- derived().addILPOpts(addPass);
-
- addPass(EarlyMachineLICMPass());
- addPass(MachineCSEPass());
-
- addPass(MachineSinkingPass());
-
- addPass(PeepholeOptimizerPass());
- // Clean-up the dead code that may have been generated by peephole
- // rewriting.
- addPass(DeadMachineInstructionElimPass());
-}
-
-//===---------------------------------------------------------------------===//
-/// Register Allocation Pass Configuration
-//===---------------------------------------------------------------------===//
-
-/// Instantiate the default register allocator pass for this target for either
-/// the optimized or unoptimized allocation path. This will be added to the pass
-/// manager by addFastRegAlloc in the unoptimized case or addOptimizedRegAlloc
-/// in the optimized case.
-///
-/// A target that uses the standard regalloc pass order for fast or optimized
-/// allocation may still override this for per-target regalloc
-/// selection. But -regalloc=... always takes precedence.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addTargetRegisterAllocator(
- AddMachinePass &addPass, bool Optimized) const {
- if (Optimized)
- addPass(RAGreedyPass());
- else
- addPass(RAFastPass());
-}
-
-/// Find and instantiate the register allocation pass requested by this target
-/// at the current optimization level. Different register allocators are
-/// defined as separate passes because they may require different analysis.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addRegAllocPass(AddMachinePass &addPass,
- bool Optimized) const {
- if (Opt.RegAlloc == RegAllocType::Default)
- // With no -regalloc= override, ask the target for a regalloc pass.
- derived().addTargetRegisterAllocator(addPass, Optimized);
- else if (Opt.RegAlloc == RegAllocType::Basic)
- addPass(RABasicPass());
- else if (Opt.RegAlloc == RegAllocType::Fast)
- addPass(RAFastPass());
- else if (Opt.RegAlloc == RegAllocType::Greedy)
- addPass(RAGreedyPass());
- else if (Opt.RegAlloc == RegAllocType::PBQP)
- addPass(RAPBQPPass());
- else
- llvm_unreachable("unknonwn register allocator type");
-}
-
-template <typename Derived>
-Error CodeGenPassBuilder<Derived>::addRegAssignmentFast(
- AddMachinePass &addPass) const {
- if (Opt.RegAlloc != RegAllocType::Default &&
- Opt.RegAlloc != RegAllocType::Fast)
- return make_error<StringError>(
- "Must use fast (default) register allocator for unoptimized regalloc.",
- inconvertibleErrorCode());
-
- addRegAllocPass(addPass, false);
- return Error::success();
-}
-
-template <typename Derived>
-Error CodeGenPassBuilder<Derived>::addRegAssignmentOptimized(
- AddMachinePass &addPass) const {
- // Add the selected register allocation pass.
- addRegAllocPass(addPass, true);
-
- // Allow targets to change the register assignments before rewriting.
- derived().addPreRewrite(addPass);
-
- // Finally rewrite virtual registers.
- addPass(VirtRegRewriterPass());
- // Perform stack slot coloring and post-ra machine LICM.
- //
- // FIXME: Re-enable coloring with register when it's capable of adding
- // kill markers.
- addPass(StackSlotColoringPass());
-
- return Error::success();
-}
-
-/// Add the minimum set of target-independent passes that are required for
-/// register allocation. No coalescing or scheduling.
-template <typename Derived>
-Error CodeGenPassBuilder<Derived>::addFastRegAlloc(
- AddMachinePass &addPass) const {
- addPass(PHIEliminationPass());
- addPass(TwoAddressInstructionPass());
- return derived().addRegAssignmentFast(addPass);
-}
-
-/// Add standard target-independent passes that are tightly coupled with
-/// optimized register allocation, including coalescing, machine instruction
-/// scheduling, and register allocation itself.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addOptimizedRegAlloc(
- AddMachinePass &addPass) const {
- addPass(DetectDeadLanesPass());
-
- addPass(ProcessImplicitDefsPass());
-
- // Edge splitting is smarter with machine loop info.
- addPass(PHIEliminationPass());
-
- // Eventually, we want to run LiveIntervals before PHI elimination.
- if (Opt.EarlyLiveIntervals)
- addPass(LiveIntervalsPass());
-
- addPass(TwoAddressInstructionPass());
- addPass(RegisterCoalescerPass());
-
- // The machine scheduler may accidentally create disconnected components
- // when moving subregister definitions around, avoid this by splitting them to
- // separate vregs before. Splitting can also improve reg. allocation quality.
- addPass(RenameIndependentSubregsPass());
-
- // PreRA instruction scheduling.
- addPass(MachineSchedulerPass());
-
- if (derived().addRegAssignmentOptimized(addPass)) {
- // Allow targets to expand pseudo instructions depending on the choice of
- // registers before MachineCopyPropagation.
- derived().addPostRewrite(addPass);
-
- // Copy propagate to forward register uses and try to eliminate COPYs that
- // were not coalesced.
- addPass(MachineCopyPropagationPass());
-
- // Run post-ra machine LICM to hoist reloads / remats.
- //
- // FIXME: can this move into MachineLateOptimization?
- addPass(MachineLICMPass());
- }
-}
-
-//===---------------------------------------------------------------------===//
-/// Post RegAlloc Pass Configuration
-//===---------------------------------------------------------------------===//
-
-/// Add passes that optimize machine instructions after register allocation.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addMachineLateOptimization(
- AddMachinePass &addPass) const {
- // Branch folding must be run after regalloc and prolog/epilog insertion.
- addPass(BranchFolderPass());
-
- // Tail duplication.
- // Note that duplicating tail just increases code size and degrades
- // performance for targets that require Structured Control Flow.
- // In addition it can also make CFG irreducible. Thus we disable it.
- if (!TM.requiresStructuredCFG())
- addPass(TailDuplicatePass());
-
- // Copy propagation.
- addPass(MachineCopyPropagationPass());
-}
-
-/// Add standard basic block placement passes.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addBlockPlacement(
- AddMachinePass &addPass) const {
- addPass(MachineBlockPlacementPass());
- // Run a separate pass to collect block placement statistics.
- if (Opt.EnableBlockPlacementStats)
- addPass(MachineBlockPlacementStatsPass());
-}
-
-} // namespace llvm
-
-#endif // LLVM_CODEGEN_CODEGENPASSBUILDER_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- Construction of codegen pass pipelines ------------------*- C++ -*--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// Interfaces for registering analysis passes, producing common pass manager
+/// configurations, and parsing of pass pipelines.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_CODEGENPASSBUILDER_H
+#define LLVM_CODEGEN_CODEGENPASSBUILDER_H
+
+#include "llvm/ADT/FunctionExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/BasicAliasAnalysis.h"
+#include "llvm/Analysis/CFLAndersAliasAnalysis.h"
+#include "llvm/Analysis/CFLSteensAliasAnalysis.h"
+#include "llvm/Analysis/ScopedNoAliasAA.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
+#include "llvm/CodeGen/ExpandReductions.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachinePassManager.h"
+#include "llvm/CodeGen/PreISelIntrinsicLowering.h"
+#include "llvm/CodeGen/UnreachableBlockElim.h"
+#include "llvm/IR/IRPrintingPasses.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Target/CGPassBuilderOption.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Scalar/ConstantHoisting.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
+#include "llvm/Transforms/Scalar/LoopStrengthReduce.h"
+#include "llvm/Transforms/Scalar/LowerConstantIntrinsics.h"
+#include "llvm/Transforms/Scalar/MergeICmps.h"
+#include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h"
+#include "llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h"
+#include "llvm/Transforms/Utils.h"
+#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
+#include "llvm/Transforms/Utils/LowerInvoke.h"
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <utility>
+
+namespace llvm {
+
+// FIXME: Dummy target independent passes definitions that have not yet been
+// ported to new pass manager. Once they do, remove these.
+#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
+ struct PASS_NAME : public PassInfoMixin<PASS_NAME> { \
+ template <typename... Ts> PASS_NAME(Ts &&...) {} \
+ PreservedAnalyses run(Function &, FunctionAnalysisManager &) { \
+ return PreservedAnalyses::all(); \
+ } \
+ };
+#define DUMMY_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
+ struct PASS_NAME : public PassInfoMixin<PASS_NAME> { \
+ template <typename... Ts> PASS_NAME(Ts &&...) {} \
+ PreservedAnalyses run(Module &, ModuleAnalysisManager &) { \
+ return PreservedAnalyses::all(); \
+ } \
+ };
+#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
+ struct PASS_NAME : public PassInfoMixin<PASS_NAME> { \
+ template <typename... Ts> PASS_NAME(Ts &&...) {} \
+ Error run(Module &, MachineFunctionAnalysisManager &) { \
+ return Error::success(); \
+ } \
+ PreservedAnalyses run(MachineFunction &, \
+ MachineFunctionAnalysisManager &) { \
+ llvm_unreachable("this api is to make new PM api happy"); \
+ } \
+ static AnalysisKey Key; \
+ };
+#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
+ struct PASS_NAME : public PassInfoMixin<PASS_NAME> { \
+ template <typename... Ts> PASS_NAME(Ts &&...) {} \
+ PreservedAnalyses run(MachineFunction &, \
+ MachineFunctionAnalysisManager &) { \
+ return PreservedAnalyses::all(); \
+ } \
+ static AnalysisKey Key; \
+ };
+#include "MachinePassRegistry.def"
+
+/// This class provides access to building LLVM's passes.
+///
+/// Its members provide the baseline state available to passes during their
+/// construction. The \c MachinePassRegistry.def file specifies how to construct
+/// all of the built-in passes, and those may reference these members during
+/// construction.
+template <typename DerivedT> class CodeGenPassBuilder {
+public:
+ explicit CodeGenPassBuilder(LLVMTargetMachine &TM, CGPassBuilderOption Opts,
+ PassInstrumentationCallbacks *PIC)
+ : TM(TM), Opt(Opts), PIC(PIC) {
+ // Target could set CGPassBuilderOption::MISchedPostRA to true to achieve
+ // substitutePass(&PostRASchedulerID, &PostMachineSchedulerID)
+
+ // Target should override TM.Options.EnableIPRA in their target-specific
+ // LLVMTM ctor. See TargetMachine::setGlobalISel for example.
+ if (Opt.EnableIPRA)
+ TM.Options.EnableIPRA = *Opt.EnableIPRA;
+
+ if (Opt.EnableGlobalISelAbort)
+ TM.Options.GlobalISelAbort = *Opt.EnableGlobalISelAbort;
+
+ if (!Opt.OptimizeRegAlloc)
+ Opt.OptimizeRegAlloc = getOptLevel() != CodeGenOpt::None;
+ }
+
+ Error buildPipeline(ModulePassManager &MPM, MachineFunctionPassManager &MFPM,
+ raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
+ CodeGenFileType FileType) const;
+
+ void registerModuleAnalyses(ModuleAnalysisManager &) const;
+ void registerFunctionAnalyses(FunctionAnalysisManager &) const;
+ void registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &) const;
+ std::pair<StringRef, bool> getPassNameFromLegacyName(StringRef) const;
+
+ void registerAnalyses(MachineFunctionAnalysisManager &MFAM) const {
+ registerModuleAnalyses(*MFAM.MAM);
+ registerFunctionAnalyses(*MFAM.FAM);
+ registerMachineFunctionAnalyses(MFAM);
+ }
+
+ PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const {
+ return PIC;
+ }
+
+protected:
+ template <typename PassT> using has_key_t = decltype(PassT::Key);
+
+ template <typename PassT>
+ using is_module_pass_t = decltype(std::declval<PassT &>().run(
+ std::declval<Module &>(), std::declval<ModuleAnalysisManager &>()));
+
+ template <typename PassT>
+ using is_function_pass_t = decltype(std::declval<PassT &>().run(
+ std::declval<Function &>(), std::declval<FunctionAnalysisManager &>()));
+
+ // Function object to maintain state while adding codegen IR passes.
+ class AddIRPass {
+ public:
+ AddIRPass(ModulePassManager &MPM, bool DebugPM, bool Check = true)
+ : MPM(MPM), FPM(DebugPM) {
+ if (Check)
+ AddingFunctionPasses = false;
+ }
+ ~AddIRPass() {
+ MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+ }
+
+ // Add Function Pass
+ template <typename PassT>
+ std::enable_if_t<is_detected<is_function_pass_t, PassT>::value>
+ operator()(PassT &&Pass) {
+ if (AddingFunctionPasses && !*AddingFunctionPasses)
+ AddingFunctionPasses = true;
+ FPM.addPass(std::forward<PassT>(Pass));
+ }
+
+ // Add Module Pass
+ template <typename PassT>
+ std::enable_if_t<is_detected<is_module_pass_t, PassT>::value &&
+ !is_detected<is_function_pass_t, PassT>::value>
+ operator()(PassT &&Pass) {
+ assert((!AddingFunctionPasses || !*AddingFunctionPasses) &&
+ "could not add module pass after adding function pass");
+ MPM.addPass(std::forward<PassT>(Pass));
+ }
+
+ private:
+ ModulePassManager &MPM;
+ FunctionPassManager FPM;
+ // The codegen IR pipeline are mostly function passes with the exceptions of
+ // a few loop and module passes. `AddingFunctionPasses` make sures that
+ // we could only add module passes at the beginning of the pipeline. Once
+ // we begin adding function passes, we could no longer add module passes.
+ // This special-casing introduces less adaptor passes. If we have the need
+ // of adding module passes after function passes, we could change the
+ // implementation to accommodate that.
+ Optional<bool> AddingFunctionPasses;
+ };
+
+ // Function object to maintain state while adding codegen machine passes.
+ class AddMachinePass {
+ public:
+ AddMachinePass(MachineFunctionPassManager &PM) : PM(PM) {}
+
+ template <typename PassT> void operator()(PassT &&Pass) {
+ static_assert(
+ is_detected<has_key_t, PassT>::value,
+ "Machine function pass must define a static member variable `Key`.");
+ for (auto &C : BeforeCallbacks)
+ if (!C(&PassT::Key))
+ return;
+ PM.addPass(std::forward<PassT>(Pass));
+ for (auto &C : AfterCallbacks)
+ C(&PassT::Key);
+ }
+
+ template <typename PassT> void insertPass(AnalysisKey *ID, PassT Pass) {
+ AfterCallbacks.emplace_back(
+ [this, ID, Pass = std::move(Pass)](AnalysisKey *PassID) {
+ if (PassID == ID)
+ this->PM.addPass(std::move(Pass));
+ });
+ }
+
+ void disablePass(AnalysisKey *ID) {
+ BeforeCallbacks.emplace_back(
+ [ID](AnalysisKey *PassID) { return PassID != ID; });
+ }
+
+ MachineFunctionPassManager releasePM() { return std::move(PM); }
+
+ private:
+ MachineFunctionPassManager &PM;
+ SmallVector<llvm::unique_function<bool(AnalysisKey *)>, 4> BeforeCallbacks;
+ SmallVector<llvm::unique_function<void(AnalysisKey *)>, 4> AfterCallbacks;
+ };
+
+ LLVMTargetMachine &TM;
+ CGPassBuilderOption Opt;
+ PassInstrumentationCallbacks *PIC;
+
+ /// Target override these hooks to parse target-specific analyses.
+ void registerTargetAnalysis(ModuleAnalysisManager &) const {}
+ void registerTargetAnalysis(FunctionAnalysisManager &) const {}
+ void registerTargetAnalysis(MachineFunctionAnalysisManager &) const {}
+ std::pair<StringRef, bool> getTargetPassNameFromLegacyName(StringRef) const {
+ return {"", false};
+ }
+
+ template <typename TMC> TMC &getTM() const { return static_cast<TMC &>(TM); }
+ CodeGenOpt::Level getOptLevel() const { return TM.getOptLevel(); }
+
+ /// Check whether or not GlobalISel should abort on error.
+ /// When this is disabled, GlobalISel will fall back on SDISel instead of
+ /// erroring out.
+ bool isGlobalISelAbortEnabled() const {
+ return TM.Options.GlobalISelAbort == GlobalISelAbortMode::Enable;
+ }
+
+ /// Check whether or not a diagnostic should be emitted when GlobalISel
+ /// uses the fallback path. In other words, it will emit a diagnostic
+ /// when GlobalISel failed and isGlobalISelAbortEnabled is false.
+ bool reportDiagnosticWhenGlobalISelFallback() const {
+ return TM.Options.GlobalISelAbort == GlobalISelAbortMode::DisableWithDiag;
+ }
+
+ /// addInstSelector - This method should install an instruction selector pass,
+ /// which converts from LLVM code to machine instructions.
+ Error addInstSelector(AddMachinePass &) const {
+ return make_error<StringError>("addInstSelector is not overridden",
+ inconvertibleErrorCode());
+ }
+
+ /// Add passes that optimize instruction level parallelism for out-of-order
+ /// targets. These passes are run while the machine code is still in SSA
+ /// form, so they can use MachineTraceMetrics to control their heuristics.
+ ///
+ /// All passes added here should preserve the MachineDominatorTree,
+ /// MachineLoopInfo, and MachineTraceMetrics analyses.
+ void addILPOpts(AddMachinePass &) const {}
+
+ /// This method may be implemented by targets that want to run passes
+ /// immediately before register allocation.
+ void addPreRegAlloc(AddMachinePass &) const {}
+
+ /// addPreRewrite - Add passes to the optimized register allocation pipeline
+ /// after register allocation is complete, but before virtual registers are
+ /// rewritten to physical registers.
+ ///
+ /// These passes must preserve VirtRegMap and LiveIntervals, and when running
+ /// after RABasic or RAGreedy, they should take advantage of LiveRegMatrix.
+ /// When these passes run, VirtRegMap contains legal physreg assignments for
+ /// all virtual registers.
+ ///
+ /// Note if the target overloads addRegAssignAndRewriteOptimized, this may not
+ /// be honored. This is also not generally used for the the fast variant,
+ /// where the allocation and rewriting are done in one pass.
+ void addPreRewrite(AddMachinePass &) const {}
+
+ /// Add passes to be run immediately after virtual registers are rewritten
+ /// to physical registers.
+ void addPostRewrite(AddMachinePass &) const {}
+
+ /// This method may be implemented by targets that want to run passes after
+ /// register allocation pass pipeline but before prolog-epilog insertion.
+ void addPostRegAlloc(AddMachinePass &) const {}
+
+ /// This method may be implemented by targets that want to run passes after
+ /// prolog-epilog insertion and before the second instruction scheduling pass.
+ void addPreSched2(AddMachinePass &) const {}
+
+ /// This pass may be implemented by targets that want to run passes
+ /// immediately before machine code is emitted.
+ void addPreEmitPass(AddMachinePass &) const {}
+
+ /// Targets may add passes immediately before machine code is emitted in this
+ /// callback. This is called even later than `addPreEmitPass`.
+ // FIXME: Rename `addPreEmitPass` to something more sensible given its actual
+ // position and remove the `2` suffix here as this callback is what
+ // `addPreEmitPass` *should* be but in reality isn't.
+ void addPreEmitPass2(AddMachinePass &) const {}
+
+ /// {{@ For GlobalISel
+ ///
+
+ /// addPreISel - This method should add any "last minute" LLVM->LLVM
+ /// passes (which are run just before instruction selector).
+ void addPreISel(AddIRPass &) const {
+ llvm_unreachable("addPreISel is not overridden");
+ }
+
+ /// This method should install an IR translator pass, which converts from
+ /// LLVM code to machine instructions with possibly generic opcodes.
+ Error addIRTranslator(AddMachinePass &) const {
+ return make_error<StringError>("addIRTranslator is not overridden",
+ inconvertibleErrorCode());
+ }
+
+ /// This method may be implemented by targets that want to run passes
+ /// immediately before legalization.
+ void addPreLegalizeMachineIR(AddMachinePass &) const {}
+
+ /// This method should install a legalize pass, which converts the instruction
+ /// sequence into one that can be selected by the target.
+ Error addLegalizeMachineIR(AddMachinePass &) const {
+ return make_error<StringError>("addLegalizeMachineIR is not overridden",
+ inconvertibleErrorCode());
+ }
+
+ /// This method may be implemented by targets that want to run passes
+ /// immediately before the register bank selection.
+ void addPreRegBankSelect(AddMachinePass &) const {}
+
+ /// This method should install a register bank selector pass, which
+ /// assigns register banks to virtual registers without a register
+ /// class or register banks.
+ Error addRegBankSelect(AddMachinePass &) const {
+ return make_error<StringError>("addRegBankSelect is not overridden",
+ inconvertibleErrorCode());
+ }
+
+ /// This method may be implemented by targets that want to run passes
+ /// immediately before the (global) instruction selection.
+ void addPreGlobalInstructionSelect(AddMachinePass &) const {}
+
+ /// This method should install a (global) instruction selector pass, which
+ /// converts possibly generic instructions to fully target-specific
+ /// instructions, thereby constraining all generic virtual registers to
+ /// register classes.
+ Error addGlobalInstructionSelect(AddMachinePass &) const {
+ return make_error<StringError>(
+ "addGlobalInstructionSelect is not overridden",
+ inconvertibleErrorCode());
+ }
+ /// @}}
+
+ /// High level function that adds all passes necessary to go from llvm IR
+ /// representation to the MI representation.
+ /// Adds IR based lowering and target specific optimization passes and finally
+ /// the core instruction selection passes.
+ /// \returns true if an error occurred, false otherwise.
+ void addISelPasses(AddIRPass &) const;
+
+ /// Add the actual instruction selection passes. This does not include
+ /// preparation passes on IR.
+ Error addCoreISelPasses(AddMachinePass &) const;
+
+ /// Add the complete, standard set of LLVM CodeGen passes.
+ /// Fully developed targets will not generally override this.
+ Error addMachinePasses(AddMachinePass &) const;
+
+ /// Add passes to lower exception handling for the code generator.
+ void addPassesToHandleExceptions(AddIRPass &) const;
+
+ /// Add common target configurable passes that perform LLVM IR to IR
+ /// transforms following machine independent optimization.
+ void addIRPasses(AddIRPass &) const;
+
+ /// Add pass to prepare the LLVM IR for code generation. This should be done
+ /// before exception handling preparation passes.
+ void addCodeGenPrepare(AddIRPass &) const;
+
+ /// Add common passes that perform LLVM IR to IR transforms in preparation for
+ /// instruction selection.
+ void addISelPrepare(AddIRPass &) const;
+
+ /// Methods with trivial inline returns are convenient points in the common
+ /// codegen pass pipeline where targets may insert passes. Methods with
+ /// out-of-line standard implementations are major CodeGen stages called by
+ /// addMachinePasses. Some targets may override major stages when inserting
+ /// passes is insufficient, but maintaining overriden stages is more work.
+ ///
+
+ /// addMachineSSAOptimization - Add standard passes that optimize machine
+ /// instructions in SSA form.
+ void addMachineSSAOptimization(AddMachinePass &) const;
+
+ /// addFastRegAlloc - Add the minimum set of target-independent passes that
+ /// are required for fast register allocation.
+ Error addFastRegAlloc(AddMachinePass &) const;
+
+ /// addOptimizedRegAlloc - Add passes related to register allocation.
+ /// LLVMTargetMachine provides standard regalloc passes for most targets.
+ void addOptimizedRegAlloc(AddMachinePass &) const;
+
+ /// Add passes that optimize machine instructions after register allocation.
+ void addMachineLateOptimization(AddMachinePass &) const;
+
+ /// addGCPasses - Add late codegen passes that analyze code for garbage
+ /// collection. This should return true if GC info should be printed after
+ /// these passes.
+ void addGCPasses(AddMachinePass &) const {}
+
+ /// Add standard basic block placement passes.
+ void addBlockPlacement(AddMachinePass &) const;
+
+ using CreateMCStreamer =
+ std::function<Expected<std::unique_ptr<MCStreamer>>(MCContext &)>;
+ void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const {
+ llvm_unreachable("addAsmPrinter is not overridden");
+ }
+
+ /// Utilities for targets to add passes to the pass manager.
+ ///
+
+ /// createTargetRegisterAllocator - Create the register allocator pass for
+ /// this target at the current optimization level.
+ void addTargetRegisterAllocator(AddMachinePass &, bool Optimized) const;
+
+ /// addMachinePasses helper to create the target-selected or overriden
+ /// regalloc pass.
+ void addRegAllocPass(AddMachinePass &, bool Optimized) const;
+
+ /// Add core register alloator passes which do the actual register assignment
+ /// and rewriting. \returns true if any passes were added.
+ Error addRegAssignmentFast(AddMachinePass &) const;
+ Error addRegAssignmentOptimized(AddMachinePass &) const;
+
+private:
+ DerivedT &derived() { return static_cast<DerivedT &>(*this); }
+ const DerivedT &derived() const {
+ return static_cast<const DerivedT &>(*this);
+ }
+};
+
+template <typename Derived>
+Error CodeGenPassBuilder<Derived>::buildPipeline(
+ ModulePassManager &MPM, MachineFunctionPassManager &MFPM,
+ raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
+ CodeGenFileType FileType) const {
+ AddIRPass addIRPass(MPM, Opt.DebugPM);
+ addISelPasses(addIRPass);
+
+ AddMachinePass addPass(MFPM);
+ if (auto Err = addCoreISelPasses(addPass))
+ return std::move(Err);
+
+ if (auto Err = derived().addMachinePasses(addPass))
+ return std::move(Err);
+
+ derived().addAsmPrinter(
+ addPass, [this, &Out, DwoOut, FileType](MCContext &Ctx) {
+ return this->TM.createMCStreamer(Out, DwoOut, FileType, Ctx);
+ });
+
+ addPass(FreeMachineFunctionPass());
+ return Error::success();
+}
+
+static inline AAManager registerAAAnalyses(CFLAAType UseCFLAA) {
+ AAManager AA;
+
+ // The order in which these are registered determines their priority when
+ // being queried.
+
+ switch (UseCFLAA) {
+ case CFLAAType::Steensgaard:
+ AA.registerFunctionAnalysis<CFLSteensAA>();
+ break;
+ case CFLAAType::Andersen:
+ AA.registerFunctionAnalysis<CFLAndersAA>();
+ break;
+ case CFLAAType::Both:
+ AA.registerFunctionAnalysis<CFLAndersAA>();
+ AA.registerFunctionAnalysis<CFLSteensAA>();
+ break;
+ default:
+ break;
+ }
+
+ // Basic AliasAnalysis support.
+ // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that
+ // BasicAliasAnalysis wins if they disagree. This is intended to help
+ // support "obvious" type-punning idioms.
+ AA.registerFunctionAnalysis<TypeBasedAA>();
+ AA.registerFunctionAnalysis<ScopedNoAliasAA>();
+ AA.registerFunctionAnalysis<BasicAA>();
+
+ return AA;
+}
+
+template <typename Derived>
+void CodeGenPassBuilder<Derived>::registerModuleAnalyses(
+ ModuleAnalysisManager &MAM) const {
+#define MODULE_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR) \
+ MAM.registerPass([&] { return PASS_NAME CONSTRUCTOR; });
+#include "MachinePassRegistry.def"
+ derived().registerTargetAnalysis(MAM);
+}
+
+template <typename Derived>
+void CodeGenPassBuilder<Derived>::registerFunctionAnalyses(
+ FunctionAnalysisManager &FAM) const {
+ FAM.registerPass([this] { return registerAAAnalyses(this->Opt.UseCFLAA); });
+
+#define FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR) \
+ FAM.registerPass([&] { return PASS_NAME CONSTRUCTOR; });
+#include "MachinePassRegistry.def"
+ derived().registerTargetAnalysis(FAM);
+}
+
+template <typename Derived>
+void CodeGenPassBuilder<Derived>::registerMachineFunctionAnalyses(
+ MachineFunctionAnalysisManager &MFAM) const {
+#define MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR) \
+ MFAM.registerPass([&] { return PASS_NAME CONSTRUCTOR; });
+#include "MachinePassRegistry.def"
+ derived().registerTargetAnalysis(MFAM);
+}
+
+// FIXME: For new PM, use pass name directly in commandline seems good.
+// Translate stringfied pass name to its old commandline name. Returns the
+// matching legacy name and a boolean value indicating if the pass is a machine
+// pass.
+template <typename Derived>
+std::pair<StringRef, bool>
+CodeGenPassBuilder<Derived>::getPassNameFromLegacyName(StringRef Name) const {
+ std::pair<StringRef, bool> Ret;
+ if (Name.empty())
+ return Ret;
+
+#define FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
+ if (Name == NAME) \
+ Ret = {#PASS_NAME, false};
+#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
+ if (Name == NAME) \
+ Ret = {#PASS_NAME, false};
+#define MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
+ if (Name == NAME) \
+ Ret = {#PASS_NAME, false};
+#define DUMMY_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
+ if (Name == NAME) \
+ Ret = {#PASS_NAME, false};
+#define MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
+ if (Name == NAME) \
+ Ret = {#PASS_NAME, true};
+#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
+ if (Name == NAME) \
+ Ret = {#PASS_NAME, true};
+#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
+ if (Name == NAME) \
+ Ret = {#PASS_NAME, true};
+#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
+ if (Name == NAME) \
+ Ret = {#PASS_NAME, true};
+#include "llvm/CodeGen/MachinePassRegistry.def"
+
+ if (Ret.first.empty())
+ Ret = derived().getTargetPassNameFromLegacyName(Name);
+
+ if (Ret.first.empty())
+ report_fatal_error(Twine('\"') + Twine(Name) +
+ Twine("\" pass could not be found."));
+
+ return Ret;
+}
+
+template <typename Derived>
+void CodeGenPassBuilder<Derived>::addISelPasses(AddIRPass &addPass) const {
+ if (TM.useEmulatedTLS())
+ addPass(LowerEmuTLSPass());
+
+ addPass(PreISelIntrinsicLoweringPass());
+
+ derived().addIRPasses(addPass);
+ derived().addCodeGenPrepare(addPass);
+ addPassesToHandleExceptions(addPass);
+ derived().addISelPrepare(addPass);
+}
+
+/// Add common target configurable passes that perform LLVM IR to IR transforms
+/// following machine independent optimization.
+template <typename Derived>
+void CodeGenPassBuilder<Derived>::addIRPasses(AddIRPass &addPass) const {
+ // Before running any passes, run the verifier to determine if the input
+ // coming from the front-end and/or optimizer is valid.
+ if (!Opt.DisableVerify)
+ addPass(VerifierPass());
+
+ // Run loop strength reduction before anything else.
+ if (getOptLevel() != CodeGenOpt::None && !Opt.DisableLSR) {
+ addPass(createFunctionToLoopPassAdaptor(
+ LoopStrengthReducePass(), /*UseMemorySSA*/ true, Opt.DebugPM));
+ // FIXME: use -stop-after so we could remove PrintLSR
+ if (Opt.PrintLSR)
+ addPass(PrintFunctionPass(dbgs(), "\n\n*** Code after LSR ***\n"));
+ }
+
+ if (getOptLevel() != CodeGenOpt::None) {
+ // The MergeICmpsPass tries to create memcmp calls by grouping sequences of
+ // loads and compares. ExpandMemCmpPass then tries to expand those calls
+ // into optimally-sized loads and compares. The transforms are enabled by a
+ // target lowering hook.
+ if (!Opt.DisableMergeICmps)
+ addPass(MergeICmpsPass());
+ addPass(ExpandMemCmpPass());
+ }
+
+ // Run GC lowering passes for builtin collectors
+ // TODO: add a pass insertion point here
+ addPass(GCLoweringPass());
+ addPass(ShadowStackGCLoweringPass());
+ addPass(LowerConstantIntrinsicsPass());
+
+ // Make sure that no unreachable blocks are instruction selected.
+ addPass(UnreachableBlockElimPass());
+
+ // Prepare expensive constants for SelectionDAG.
+ if (getOptLevel() != CodeGenOpt::None && !Opt.DisableConstantHoisting)
+ addPass(ConstantHoistingPass());
+
+ if (getOptLevel() != CodeGenOpt::None && !Opt.DisablePartialLibcallInlining)
+ addPass(PartiallyInlineLibCallsPass());
+
+ // Instrument function entry and exit, e.g. with calls to mcount().
+ addPass(EntryExitInstrumenterPass(/*PostInlining=*/true));
+
+ // Add scalarization of target's unsupported masked memory intrinsics pass.
+ // the unsupported intrinsic will be replaced with a chain of basic blocks,
+ // that stores/loads element one-by-one if the appropriate mask bit is set.
+ addPass(ScalarizeMaskedMemIntrinPass());
+
+ // Expand reduction intrinsics into shuffle sequences if the target wants to.
+ addPass(ExpandReductionsPass());
+}
+
+/// Turn exception handling constructs into something the code generators can
+/// handle.
+template <typename Derived>
+void CodeGenPassBuilder<Derived>::addPassesToHandleExceptions(
+ AddIRPass &addPass) const {
+ const MCAsmInfo *MCAI = TM.getMCAsmInfo();
+ assert(MCAI && "No MCAsmInfo");
+ switch (MCAI->getExceptionHandlingType()) {
+ case ExceptionHandling::SjLj:
+ // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both
+ // Dwarf EH prepare needs to be run after SjLj prepare. Otherwise,
+ // catch info can get misplaced when a selector ends up more than one block
+ // removed from the parent invoke(s). This could happen when a landing
+ // pad is shared by multiple invokes and is also a target of a normal
+ // edge from elsewhere.
+ addPass(SjLjEHPreparePass());
+ LLVM_FALLTHROUGH;
+ case ExceptionHandling::DwarfCFI:
+ case ExceptionHandling::ARM:
+ case ExceptionHandling::AIX:
+ addPass(DwarfEHPass(getOptLevel()));
+ break;
+ case ExceptionHandling::WinEH:
+ // We support using both GCC-style and MSVC-style exceptions on Windows, so
+ // add both preparation passes. Each pass will only actually run if it
+ // recognizes the personality function.
+ addPass(WinEHPass());
+ addPass(DwarfEHPass(getOptLevel()));
+ break;
+ case ExceptionHandling::Wasm:
+ // Wasm EH uses Windows EH instructions, but it does not need to demote PHIs
+ // on catchpads and cleanuppads because it does not outline them into
+ // funclets. Catchswitch blocks are not lowered in SelectionDAG, so we
+ // should remove PHIs there.
+ addPass(WinEHPass(/*DemoteCatchSwitchPHIOnly=*/false));
+ addPass(WasmEHPass());
+ break;
+ case ExceptionHandling::None:
+ addPass(LowerInvokePass());
+
+ // The lower invoke pass may create unreachable code. Remove it.
+ addPass(UnreachableBlockElimPass());
+ break;
+ }
+}
+
+/// Add pass to prepare the LLVM IR for code generation. This should be done
+/// before exception handling preparation passes.
+template <typename Derived>
+void CodeGenPassBuilder<Derived>::addCodeGenPrepare(AddIRPass &addPass) const {
+ if (getOptLevel() != CodeGenOpt::None && !Opt.DisableCGP)
+ addPass(CodeGenPreparePass());
+ // TODO: Default ctor'd RewriteSymbolPass is no-op.
+ // addPass(RewriteSymbolPass());
+}
+
+/// Add common passes that perform LLVM IR to IR transforms in preparation for
+/// instruction selection.
+template <typename Derived>
+void CodeGenPassBuilder<Derived>::addISelPrepare(AddIRPass &addPass) const {
+ derived().addPreISel(addPass);
+
+ // Add both the safe stack and the stack protection passes: each of them will
+ // only protect functions that have corresponding attributes.
+ addPass(SafeStackPass());
+ addPass(StackProtectorPass());
+
+ if (Opt.PrintISelInput)
+ addPass(PrintFunctionPass(dbgs(),
+ "\n\n*** Final LLVM Code input to ISel ***\n"));
+
+ // All passes which modify the LLVM IR are now complete; run the verifier
+ // to ensure that the IR is valid.
+ if (!Opt.DisableVerify)
+ addPass(VerifierPass());
+}
+
+template <typename Derived>
+Error CodeGenPassBuilder<Derived>::addCoreISelPasses(
+ AddMachinePass &addPass) const {
+ // Enable FastISel with -fast-isel, but allow that to be overridden.
+ TM.setO0WantsFastISel(Opt.EnableFastISelOption.getValueOr(true));
+
+ // Determine an instruction selector.
+ enum class SelectorType { SelectionDAG, FastISel, GlobalISel };
+ SelectorType Selector;
+
+ if (Opt.EnableFastISelOption && *Opt.EnableFastISelOption == true)
+ Selector = SelectorType::FastISel;
+ else if ((Opt.EnableGlobalISelOption &&
+ *Opt.EnableGlobalISelOption == true) ||
+ (TM.Options.EnableGlobalISel &&
+ (!Opt.EnableGlobalISelOption ||
+ *Opt.EnableGlobalISelOption == false)))
+ Selector = SelectorType::GlobalISel;
+ else if (TM.getOptLevel() == CodeGenOpt::None && TM.getO0WantsFastISel())
+ Selector = SelectorType::FastISel;
+ else
+ Selector = SelectorType::SelectionDAG;
+
+ // Set consistently TM.Options.EnableFastISel and EnableGlobalISel.
+ if (Selector == SelectorType::FastISel) {
+ TM.setFastISel(true);
+ TM.setGlobalISel(false);
+ } else if (Selector == SelectorType::GlobalISel) {
+ TM.setFastISel(false);
+ TM.setGlobalISel(true);
+ }
+
+ // Add instruction selector passes.
+ if (Selector == SelectorType::GlobalISel) {
+ if (auto Err = derived().addIRTranslator(addPass))
+ return std::move(Err);
+
+ derived().addPreLegalizeMachineIR(addPass);
+
+ if (auto Err = derived().addLegalizeMachineIR(addPass))
+ return std::move(Err);
+
+ // Before running the register bank selector, ask the target if it
+ // wants to run some passes.
+ derived().addPreRegBankSelect(addPass);
+
+ if (auto Err = derived().addRegBankSelect(addPass))
+ return std::move(Err);
+
+ derived().addPreGlobalInstructionSelect(addPass);
+
+ if (auto Err = derived().addGlobalInstructionSelect(addPass))
+ return std::move(Err);
+
+ // Pass to reset the MachineFunction if the ISel failed.
+ addPass(ResetMachineFunctionPass(reportDiagnosticWhenGlobalISelFallback(),
+ isGlobalISelAbortEnabled()));
+
+ // Provide a fallback path when we do not want to abort on
+ // not-yet-supported input.
+ if (!isGlobalISelAbortEnabled())
+ if (auto Err = derived().addInstSelector(addPass))
+ return std::move(Err);
+
+ } else if (auto Err = derived().addInstSelector(addPass))
+ return std::move(Err);
+
+ // Expand pseudo-instructions emitted by ISel. Don't run the verifier before
+ // FinalizeISel.
+ addPass(FinalizeISelPass());
+
+ // // Print the instruction selected machine code...
+ // printAndVerify("After Instruction Selection");
+
+ return Error::success();
+}
+
+/// Add the complete set of target-independent postISel code generator passes.
+///
+/// This can be read as the standard order of major LLVM CodeGen stages. Stages
+/// with nontrivial configuration or multiple passes are broken out below in
+/// add%Stage routines.
+///
+/// Any CodeGenPassBuilder<Derived>::addXX routine may be overriden by the
+/// Target. The addPre/Post methods with empty header implementations allow
+/// injecting target-specific fixups just before or after major stages.
+/// Additionally, targets have the flexibility to change pass order within a
+/// stage by overriding default implementation of add%Stage routines below. Each
+/// technique has maintainability tradeoffs because alternate pass orders are
+/// not well supported. addPre/Post works better if the target pass is easily
+/// tied to a common pass. But if it has subtle dependencies on multiple passes,
+/// the target should override the stage instead.
+template <typename Derived>
+Error CodeGenPassBuilder<Derived>::addMachinePasses(
+ AddMachinePass &addPass) const {
+ // Add passes that optimize machine instructions in SSA form.
+ if (getOptLevel() != CodeGenOpt::None) {
+ derived().addMachineSSAOptimization(addPass);
+ } else {
+ // If the target requests it, assign local variables to stack slots relative
+ // to one another and simplify frame index references where possible.
+ addPass(LocalStackSlotPass());
+ }
+
+ if (TM.Options.EnableIPRA)
+ addPass(RegUsageInfoPropagationPass());
+
+ // Run pre-ra passes.
+ derived().addPreRegAlloc(addPass);
+
+ // Run register allocation and passes that are tightly coupled with it,
+ // including phi elimination and scheduling.
+ if (*Opt.OptimizeRegAlloc) {
+ derived().addOptimizedRegAlloc(addPass);
+ } else {
+ if (auto Err = derived().addFastRegAlloc(addPass))
+ return Err;
+ }
+
+ // Run post-ra passes.
+ derived().addPostRegAlloc(addPass);
+
+ // Insert prolog/epilog code. Eliminate abstract frame index references...
+ if (getOptLevel() != CodeGenOpt::None) {
+ addPass(PostRAMachineSinkingPass());
+ addPass(ShrinkWrapPass());
+ }
+
+ addPass(PrologEpilogInserterPass());
+
+ /// Add passes that optimize machine instructions after register allocation.
+ if (getOptLevel() != CodeGenOpt::None)
+ derived().addMachineLateOptimization(addPass);
+
+ // Expand pseudo instructions before second scheduling pass.
+ addPass(ExpandPostRAPseudosPass());
+
+ // Run pre-sched2 passes.
+ derived().addPreSched2(addPass);
+
+ if (Opt.EnableImplicitNullChecks)
+ addPass(ImplicitNullChecksPass());
+
+ // Second pass scheduler.
+ // Let Target optionally insert this pass by itself at some other
+ // point.
+ if (getOptLevel() != CodeGenOpt::None &&
+ !TM.targetSchedulesPostRAScheduling()) {
+ if (Opt.MISchedPostRA)
+ addPass(PostMachineSchedulerPass());
+ else
+ addPass(PostRASchedulerPass());
+ }
+
+ // GC
+ derived().addGCPasses(addPass);
+
+ // Basic block placement.
+ if (getOptLevel() != CodeGenOpt::None)
+ derived().addBlockPlacement(addPass);
+
+ // Insert before XRay Instrumentation.
+ addPass(FEntryInserterPass());
+
+ addPass(XRayInstrumentationPass());
+ addPass(PatchableFunctionPass());
+
+ derived().addPreEmitPass(addPass);
+
+ if (TM.Options.EnableIPRA)
+ // Collect register usage information and produce a register mask of
+ // clobbered registers, to be used to optimize call sites.
+ addPass(RegUsageInfoCollectorPass());
+
+ addPass(FuncletLayoutPass());
+
+ addPass(StackMapLivenessPass());
+ addPass(LiveDebugValuesPass());
+
+ if (TM.Options.EnableMachineOutliner && getOptLevel() != CodeGenOpt::None &&
+ Opt.EnableMachineOutliner != RunOutliner::NeverOutline) {
+ bool RunOnAllFunctions =
+ (Opt.EnableMachineOutliner == RunOutliner::AlwaysOutline);
+ bool AddOutliner = RunOnAllFunctions || TM.Options.SupportsDefaultOutlining;
+ if (AddOutliner)
+ addPass(MachineOutlinerPass(RunOnAllFunctions));
+ }
+
+ // Add passes that directly emit MI after all other MI passes.
+ derived().addPreEmitPass2(addPass);
+
+ return Error::success();
+}
+
+/// Add passes that optimize machine instructions in SSA form.
+template <typename Derived>
+void CodeGenPassBuilder<Derived>::addMachineSSAOptimization(
+ AddMachinePass &addPass) const {
+ // Pre-ra tail duplication.
+ addPass(EarlyTailDuplicatePass());
+
+ // Optimize PHIs before DCE: removing dead PHI cycles may make more
+ // instructions dead.
+ addPass(OptimizePHIsPass());
+
+ // This pass merges large allocas. StackSlotColoring is a different pass
+ // which merges spill slots.
+ addPass(StackColoringPass());
+
+ // If the target requests it, assign local variables to stack slots relative
+ // to one another and simplify frame index references where possible.
+ addPass(LocalStackSlotPass());
+
+ // With optimization, dead code should already be eliminated. However
+ // there is one known exception: lowered code for arguments that are only
+ // used by tail calls, where the tail calls reuse the incoming stack
+ // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll).
+ addPass(DeadMachineInstructionElimPass());
+
+ // Allow targets to insert passes that improve instruction level parallelism,
+ // like if-conversion. Such passes will typically need dominator trees and
+ // loop info, just like LICM and CSE below.
+ derived().addILPOpts(addPass);
+
+ addPass(EarlyMachineLICMPass());
+ addPass(MachineCSEPass());
+
+ addPass(MachineSinkingPass());
+
+ addPass(PeepholeOptimizerPass());
+ // Clean-up the dead code that may have been generated by peephole
+ // rewriting.
+ addPass(DeadMachineInstructionElimPass());
+}
+
+//===---------------------------------------------------------------------===//
+/// Register Allocation Pass Configuration
+//===---------------------------------------------------------------------===//
+
+/// Instantiate the default register allocator pass for this target for either
+/// the optimized or unoptimized allocation path. This will be added to the pass
+/// manager by addFastRegAlloc in the unoptimized case or addOptimizedRegAlloc
+/// in the optimized case.
+///
+/// A target that uses the standard regalloc pass order for fast or optimized
+/// allocation may still override this for per-target regalloc
+/// selection. But -regalloc=... always takes precedence.
+template <typename Derived>
+void CodeGenPassBuilder<Derived>::addTargetRegisterAllocator(
+ AddMachinePass &addPass, bool Optimized) const {
+ if (Optimized)
+ addPass(RAGreedyPass());
+ else
+ addPass(RAFastPass());
+}
+
+/// Find and instantiate the register allocation pass requested by this target
+/// at the current optimization level. Different register allocators are
+/// defined as separate passes because they may require different analysis.
+template <typename Derived>
+void CodeGenPassBuilder<Derived>::addRegAllocPass(AddMachinePass &addPass,
+ bool Optimized) const {
+ if (Opt.RegAlloc == RegAllocType::Default)
+ // With no -regalloc= override, ask the target for a regalloc pass.
+ derived().addTargetRegisterAllocator(addPass, Optimized);
+ else if (Opt.RegAlloc == RegAllocType::Basic)
+ addPass(RABasicPass());
+ else if (Opt.RegAlloc == RegAllocType::Fast)
+ addPass(RAFastPass());
+ else if (Opt.RegAlloc == RegAllocType::Greedy)
+ addPass(RAGreedyPass());
+ else if (Opt.RegAlloc == RegAllocType::PBQP)
+ addPass(RAPBQPPass());
+ else
+ llvm_unreachable("unknonwn register allocator type");
+}
+
+template <typename Derived>
+Error CodeGenPassBuilder<Derived>::addRegAssignmentFast(
+ AddMachinePass &addPass) const {
+ if (Opt.RegAlloc != RegAllocType::Default &&
+ Opt.RegAlloc != RegAllocType::Fast)
+ return make_error<StringError>(
+ "Must use fast (default) register allocator for unoptimized regalloc.",
+ inconvertibleErrorCode());
+
+ addRegAllocPass(addPass, false);
+ return Error::success();
+}
+
+template <typename Derived>
+Error CodeGenPassBuilder<Derived>::addRegAssignmentOptimized(
+ AddMachinePass &addPass) const {
+ // Add the selected register allocation pass.
+ addRegAllocPass(addPass, true);
+
+ // Allow targets to change the register assignments before rewriting.
+ derived().addPreRewrite(addPass);
+
+ // Finally rewrite virtual registers.
+ addPass(VirtRegRewriterPass());
+ // Perform stack slot coloring and post-ra machine LICM.
+ //
+ // FIXME: Re-enable coloring with register when it's capable of adding
+ // kill markers.
+ addPass(StackSlotColoringPass());
+
+ return Error::success();
+}
+
+/// Add the minimum set of target-independent passes that are required for
+/// register allocation. No coalescing or scheduling.
+template <typename Derived>
+Error CodeGenPassBuilder<Derived>::addFastRegAlloc(
+ AddMachinePass &addPass) const {
+ addPass(PHIEliminationPass());
+ addPass(TwoAddressInstructionPass());
+ return derived().addRegAssignmentFast(addPass);
+}
+
+/// Add standard target-independent passes that are tightly coupled with
+/// optimized register allocation, including coalescing, machine instruction
+/// scheduling, and register allocation itself.
+template <typename Derived>
+void CodeGenPassBuilder<Derived>::addOptimizedRegAlloc(
+ AddMachinePass &addPass) const {
+ addPass(DetectDeadLanesPass());
+
+ addPass(ProcessImplicitDefsPass());
+
+ // Edge splitting is smarter with machine loop info.
+ addPass(PHIEliminationPass());
+
+ // Eventually, we want to run LiveIntervals before PHI elimination.
+ if (Opt.EarlyLiveIntervals)
+ addPass(LiveIntervalsPass());
+
+ addPass(TwoAddressInstructionPass());
+ addPass(RegisterCoalescerPass());
+
+ // The machine scheduler may accidentally create disconnected components
+ // when moving subregister definitions around, avoid this by splitting them to
+ // separate vregs before. Splitting can also improve reg. allocation quality.
+ addPass(RenameIndependentSubregsPass());
+
+ // PreRA instruction scheduling.
+ addPass(MachineSchedulerPass());
+
+ if (derived().addRegAssignmentOptimized(addPass)) {
+ // Allow targets to expand pseudo instructions depending on the choice of
+ // registers before MachineCopyPropagation.
+ derived().addPostRewrite(addPass);
+
+ // Copy propagate to forward register uses and try to eliminate COPYs that
+ // were not coalesced.
+ addPass(MachineCopyPropagationPass());
+
+ // Run post-ra machine LICM to hoist reloads / remats.
+ //
+ // FIXME: can this move into MachineLateOptimization?
+ addPass(MachineLICMPass());
+ }
+}
+
+//===---------------------------------------------------------------------===//
+/// Post RegAlloc Pass Configuration
+//===---------------------------------------------------------------------===//
+
+/// Add passes that optimize machine instructions after register allocation.
+template <typename Derived>
+void CodeGenPassBuilder<Derived>::addMachineLateOptimization(
+ AddMachinePass &addPass) const {
+ // Branch folding must be run after regalloc and prolog/epilog insertion.
+ addPass(BranchFolderPass());
+
+ // Tail duplication.
+ // Note that duplicating tail just increases code size and degrades
+ // performance for targets that require Structured Control Flow.
+ // In addition it can also make CFG irreducible. Thus we disable it.
+ if (!TM.requiresStructuredCFG())
+ addPass(TailDuplicatePass());
+
+ // Copy propagation.
+ addPass(MachineCopyPropagationPass());
+}
+
+/// Add standard basic block placement passes.
+template <typename Derived>
+void CodeGenPassBuilder<Derived>::addBlockPlacement(
+ AddMachinePass &addPass) const {
+ addPass(MachineBlockPlacementPass());
+ // Run a separate pass to collect block placement statistics.
+ if (Opt.EnableBlockPlacementStats)
+ addPass(MachineBlockPlacementStatsPass());
+}
+
+} // namespace llvm
+
+#endif // LLVM_CODEGEN_CODEGENPASSBUILDER_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/CommandFlags.h b/contrib/libs/llvm12/include/llvm/CodeGen/CommandFlags.h
index 761d8f14cb..8e7b01c552 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/CommandFlags.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/CommandFlags.h
@@ -21,7 +21,7 @@
#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/MC/MCTargetOptionsCommandFlags.h"
@@ -82,8 +82,8 @@ bool getDontPlaceZerosInBSS();
bool getEnableGuaranteedTailCallOpt();
-bool getEnableAIXExtendedAltivecABI();
-
+bool getEnableAIXExtendedAltivecABI();
+
bool getDisableTailCalls();
bool getStackSymbolOrdering();
@@ -104,16 +104,16 @@ Optional<bool> getExplicitDataSections();
bool getFunctionSections();
Optional<bool> getExplicitFunctionSections();
-bool getIgnoreXCOFFVisibility();
-
-bool getXCOFFTracebackTable();
-
+bool getIgnoreXCOFFVisibility();
+
+bool getXCOFFTracebackTable();
+
std::string getBBSections();
-std::string getStackProtectorGuard();
-unsigned getStackProtectorGuardOffset();
-std::string getStackProtectorGuardReg();
-
+std::string getStackProtectorGuard();
+unsigned getStackProtectorGuardOffset();
+std::string getStackProtectorGuardReg();
+
unsigned getTLSSize();
bool getEmulatedTLS();
@@ -132,14 +132,14 @@ bool getEnableAddrsig();
bool getEmitCallSiteInfo();
-bool getEnableMachineFunctionSplitter();
-
+bool getEnableMachineFunctionSplitter();
+
bool getEnableDebugEntryValues();
-bool getPseudoProbeForProfiling();
-
-bool getValueTrackingVariableLocations();
-
+bool getPseudoProbeForProfiling();
+
+bool getValueTrackingVariableLocations();
+
bool getForceDwarfFrameSection();
bool getXRayOmitFunctionIndex();
@@ -152,17 +152,17 @@ struct RegisterCodeGenFlags {
llvm::BasicBlockSection getBBSectionsMode(llvm::TargetOptions &Options);
-llvm::StackProtectorGuards
-getStackProtectorGuardMode(llvm::TargetOptions &Options);
-
-/// Common utility function tightly tied to the options listed here. Initializes
-/// a TargetOptions object with CodeGen flags and returns it.
-/// \p TheTriple is used to determine the default value for options if
-/// options are not explicitly specified. If those triple dependant options
-/// value do not have effect for your component, a default Triple() could be
-/// passed in.
-TargetOptions InitTargetOptionsFromCodeGenFlags(const llvm::Triple &TheTriple);
-
+llvm::StackProtectorGuards
+getStackProtectorGuardMode(llvm::TargetOptions &Options);
+
+/// Common utility function tightly tied to the options listed here. Initializes
+/// a TargetOptions object with CodeGen flags and returns it.
+/// \p TheTriple is used to determine the default value for options if
+/// options are not explicitly specified. If those triple dependant options
+/// value do not have effect for your component, a default Triple() could be
+/// passed in.
+TargetOptions InitTargetOptionsFromCodeGenFlags(const llvm::Triple &TheTriple);
+
std::string getCPUStr();
std::string getFeaturesStr();
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/DIE.h b/contrib/libs/llvm12/include/llvm/CodeGen/DIE.h
index 8e2c9a52eb..dda38928e5 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/DIE.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/DIE.h
@@ -254,7 +254,7 @@ public:
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
void print(raw_ostream &O) const;
- uint64_t getIndex() const { return Index; }
+ uint64_t getIndex() const { return Index; }
};
//===--------------------------------------------------------------------===//
@@ -390,12 +390,12 @@ private:
static_assert(std::is_standard_layout<T>::value ||
std::is_pointer<T>::value,
"Expected standard layout or pointer");
- new (reinterpret_cast<void *>(&Val)) T(V);
+ new (reinterpret_cast<void *>(&Val)) T(V);
}
- template <class T> T *get() { return reinterpret_cast<T *>(&Val); }
+ template <class T> T *get() { return reinterpret_cast<T *>(&Val); }
template <class T> const T *get() const {
- return reinterpret_cast<const T *>(&Val);
+ return reinterpret_cast<const T *>(&Val);
}
template <class T> void destruct() { get<T>()->~T(); }
@@ -794,7 +794,7 @@ public:
/// Get the absolute offset within the .debug_info or .debug_types section
/// for this DIE.
- uint64_t getDebugSectionOffset() const;
+ uint64_t getDebugSectionOffset() const;
/// Compute the offset of this DIE and all its children.
///
@@ -874,7 +874,7 @@ protected:
virtual ~DIEUnit() = default;
public:
- explicit DIEUnit(dwarf::Tag UnitTag);
+ explicit DIEUnit(dwarf::Tag UnitTag);
DIEUnit(const DIEUnit &RHS) = delete;
DIEUnit(DIEUnit &&RHS) = delete;
void operator=(const DIEUnit &RHS) = delete;
@@ -896,14 +896,14 @@ public:
///
/// \returns Section pointer which can be NULL.
MCSection *getSection() const { return Section; }
- void setDebugSectionOffset(uint64_t O) { Offset = O; }
- uint64_t getDebugSectionOffset() const { return Offset; }
+ void setDebugSectionOffset(uint64_t O) { Offset = O; }
+ uint64_t getDebugSectionOffset() const { return Offset; }
DIE &getUnitDie() { return Die; }
const DIE &getUnitDie() const { return Die; }
};
struct BasicDIEUnit final : DIEUnit {
- explicit BasicDIEUnit(dwarf::Tag UnitTag) : DIEUnit(UnitTag) {}
+ explicit BasicDIEUnit(dwarf::Tag UnitTag) : DIEUnit(UnitTag) {}
};
//===--------------------------------------------------------------------===//
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/DbgEntityHistoryCalculator.h b/contrib/libs/llvm12/include/llvm/CodeGen/DbgEntityHistoryCalculator.h
index 7b6dd22d4c..2062bdea72 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/DbgEntityHistoryCalculator.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/DbgEntityHistoryCalculator.h
@@ -19,7 +19,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/LexicalScopes.h"
+#include "llvm/CodeGen/LexicalScopes.h"
#include <utility>
namespace llvm {
@@ -31,24 +31,24 @@ class MachineFunction;
class MachineInstr;
class TargetRegisterInfo;
-/// Record instruction ordering so we can query their relative positions within
-/// a function. Meta instructions are given the same ordinal as the preceding
-/// non-meta instruction. Class state is invalid if MF is modified after
-/// calling initialize.
-class InstructionOrdering {
-public:
- void initialize(const MachineFunction &MF);
- void clear() { InstNumberMap.clear(); }
-
- /// Check if instruction \p A comes before \p B, where \p A and \p B both
- /// belong to the MachineFunction passed to initialize().
- bool isBefore(const MachineInstr *A, const MachineInstr *B) const;
-
-private:
- /// Each instruction is assigned an order number.
- DenseMap<const MachineInstr *, unsigned> InstNumberMap;
-};
-
+/// Record instruction ordering so we can query their relative positions within
+/// a function. Meta instructions are given the same ordinal as the preceding
+/// non-meta instruction. Class state is invalid if MF is modified after
+/// calling initialize.
+class InstructionOrdering {
+public:
+ void initialize(const MachineFunction &MF);
+ void clear() { InstNumberMap.clear(); }
+
+ /// Check if instruction \p A comes before \p B, where \p A and \p B both
+ /// belong to the MachineFunction passed to initialize().
+ bool isBefore(const MachineInstr *A, const MachineInstr *B) const;
+
+private:
+ /// Each instruction is assigned an order number.
+ DenseMap<const MachineInstr *, unsigned> InstNumberMap;
+};
+
/// For each user variable, keep a list of instruction ranges where this
/// variable is accessible. The variables are listed in order of appearance.
class DbgValueHistoryMap {
@@ -78,8 +78,8 @@ public:
/// register-described debug values that have their end index
/// set to this entry's position in the entry vector.
class Entry {
- friend DbgValueHistoryMap;
-
+ friend DbgValueHistoryMap;
+
public:
enum EntryKind { DbgValue, Clobber };
@@ -117,9 +117,9 @@ public:
return Entries[Index];
}
- /// Drop location ranges which exist entirely outside each variable's scope.
- void trimLocationRanges(const MachineFunction &MF, LexicalScopes &LScopes,
- const InstructionOrdering &Ordering);
+ /// Drop location ranges which exist entirely outside each variable's scope.
+ void trimLocationRanges(const MachineFunction &MF, LexicalScopes &LScopes,
+ const InstructionOrdering &Ordering);
bool empty() const { return VarEntries.empty(); }
void clear() { VarEntries.clear(); }
EntriesMap::const_iterator begin() const { return VarEntries.begin(); }
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/DebugHandlerBase.h b/contrib/libs/llvm12/include/llvm/CodeGen/DebugHandlerBase.h
index 8f8d2ed909..c61873c8ea 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/DebugHandlerBase.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/DebugHandlerBase.h
@@ -117,13 +117,13 @@ protected:
virtual void endFunctionImpl(const MachineFunction *MF) = 0;
virtual void skippedNonDebugFunction() {}
-private:
- InstructionOrdering InstOrdering;
-
+private:
+ InstructionOrdering InstOrdering;
+
// AsmPrinterHandler overrides.
public:
- void beginModule(Module *M) override;
-
+ void beginModule(Module *M) override;
+
void beginInstruction(const MachineInstr *MI) override;
void endInstruction() override;
@@ -141,14 +141,14 @@ public:
/// If this type is derived from a base type then return base type size.
static uint64_t getBaseTypeSize(const DIType *Ty);
-
- /// Return true if type encoding is unsigned.
- static bool isUnsignedDIType(const DIType *Ty);
-
- const InstructionOrdering &getInstOrdering() const { return InstOrdering; }
+
+ /// Return true if type encoding is unsigned.
+ static bool isUnsignedDIType(const DIType *Ty);
+
+ const InstructionOrdering &getInstOrdering() const { return InstOrdering; }
};
-} // namespace llvm
+} // namespace llvm
#endif
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/DwarfStringPoolEntry.h b/contrib/libs/llvm12/include/llvm/CodeGen/DwarfStringPoolEntry.h
index 131fadea32..abdf6f026f 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/DwarfStringPoolEntry.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/DwarfStringPoolEntry.h
@@ -28,7 +28,7 @@ struct DwarfStringPoolEntry {
static constexpr unsigned NotIndexed = -1;
MCSymbol *Symbol;
- uint64_t Offset;
+ uint64_t Offset;
unsigned Index;
bool isIndexed() const { return Index != NotIndexed; }
@@ -54,7 +54,7 @@ public:
assert(getMapEntry()->second.Symbol && "No symbol available!");
return getMapEntry()->second.Symbol;
}
- uint64_t getOffset() const { return getMapEntry()->second.Offset; }
+ uint64_t getOffset() const { return getMapEntry()->second.Offset; }
bool isIndexed() const { return MapEntryAndIndexed.getInt(); }
unsigned getIndex() const {
assert(isIndexed());
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/FastISel.h b/contrib/libs/llvm12/include/llvm/CodeGen/FastISel.h
index 30885f0ad8..d879fb1388 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/FastISel.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/FastISel.h
@@ -249,7 +249,7 @@ public:
/// be appended.
void startNewBlock();
- /// Flush the local value map.
+ /// Flush the local value map.
void finishBasicBlock();
/// Return current debug location information.
@@ -316,7 +316,7 @@ public:
void removeDeadCode(MachineBasicBlock::iterator I,
MachineBasicBlock::iterator E);
- using SavePoint = MachineBasicBlock::iterator;
+ using SavePoint = MachineBasicBlock::iterator;
/// Prepare InsertPt to begin inserting instructions into the local
/// value area and return the old insert position.
@@ -497,10 +497,10 @@ protected:
/// - \c Add has a constant operand.
bool canFoldAddIntoGEP(const User *GEP, const Value *Add);
- /// Test whether the register associated with this value has exactly one use,
- /// in which case that single use is killing. Note that multiple IR values
- /// may map onto the same register, in which case this is not the same as
- /// checking that an IR value has one use.
+ /// Test whether the register associated with this value has exactly one use,
+ /// in which case that single use is killing. Note that multiple IR values
+ /// may map onto the same register, in which case this is not the same as
+ /// checking that an IR value has one use.
bool hasTrivialKill(const Value *V);
/// Create a machine mem operand from the given instruction.
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/FunctionLoweringInfo.h b/contrib/libs/llvm12/include/llvm/CodeGen/FunctionLoweringInfo.h
index 665c243054..9fe48ef5ff 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/FunctionLoweringInfo.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/FunctionLoweringInfo.h
@@ -98,34 +98,34 @@ public:
/// Track virtual registers created for exception pointers.
DenseMap<const Value *, Register> CatchPadExceptionPointers;
- /// Helper object to track which of three possible relocation mechanisms are
- /// used for a particular value being relocated over a statepoint.
- struct StatepointRelocationRecord {
- enum RelocType {
- // Value did not need to be relocated and can be used directly.
- NoRelocate,
- // Value was spilled to stack and needs filled at the gc.relocate.
- Spill,
- // Value was lowered to tied def and gc.relocate should be replaced with
- // copy from vreg.
- VReg,
- } type = NoRelocate;
- // Payload contains either frame index of the stack slot in which the value
- // was spilled, or virtual register which contains the re-definition.
- union payload_t {
- payload_t() : FI(-1) {}
- int FI;
- Register Reg;
- } payload;
- };
-
- /// Keep track of each value which was relocated and the strategy used to
- /// relocate that value. This information is required when visiting
- /// gc.relocates which may appear in following blocks.
- using StatepointSpillMapTy =
- DenseMap<const Value *, StatepointRelocationRecord>;
- DenseMap<const Instruction *, StatepointSpillMapTy> StatepointRelocationMaps;
-
+ /// Helper object to track which of three possible relocation mechanisms are
+ /// used for a particular value being relocated over a statepoint.
+ struct StatepointRelocationRecord {
+ enum RelocType {
+ // Value did not need to be relocated and can be used directly.
+ NoRelocate,
+ // Value was spilled to stack and needs filled at the gc.relocate.
+ Spill,
+ // Value was lowered to tied def and gc.relocate should be replaced with
+ // copy from vreg.
+ VReg,
+ } type = NoRelocate;
+ // Payload contains either frame index of the stack slot in which the value
+ // was spilled, or virtual register which contains the re-definition.
+ union payload_t {
+ payload_t() : FI(-1) {}
+ int FI;
+ Register Reg;
+ } payload;
+ };
+
+ /// Keep track of each value which was relocated and the strategy used to
+ /// relocate that value. This information is required when visiting
+ /// gc.relocates which may appear in following blocks.
+ using StatepointSpillMapTy =
+ DenseMap<const Value *, StatepointRelocationRecord>;
+ DenseMap<const Instruction *, StatepointSpillMapTy> StatepointRelocationMaps;
+
/// StaticAllocaMap - Keep track of frame indices for fixed sized allocas in
/// the entry block. This allows the allocas to be efficiently referenced
/// anywhere in the function.
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/CSEInfo.h b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/CSEInfo.h
index 92da54451d..83db4418b3 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/CSEInfo.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/CSEInfo.h
@@ -25,10 +25,10 @@
#include "llvm/CodeGen/GlobalISel/GISelWorkList.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/CodeGen.h"
namespace llvm {
-class MachineBasicBlock;
+class MachineBasicBlock;
/// A class that wraps MachineInstrs and derives from FoldingSetNode in order to
/// be uniqued in a CSEMap. The tradeoff here is extra memory allocations for
@@ -189,8 +189,8 @@ public:
const GISelInstProfileBuilder &addNodeIDRegNum(Register Reg) const;
- const GISelInstProfileBuilder &addNodeIDReg(Register Reg) const;
-
+ const GISelInstProfileBuilder &addNodeIDReg(Register Reg) const;
+
const GISelInstProfileBuilder &addNodeIDImmediate(int64_t Imm) const;
const GISelInstProfileBuilder &
addNodeIDMBB(const MachineBasicBlock *MBB) const;
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/CallLowering.h b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/CallLowering.h
index 842d7cf08b..549f200269 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/CallLowering.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/CallLowering.h
@@ -24,11 +24,11 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/CallingConvLower.h"
-#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/TargetCallingConv.h"
-#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Attributes.h"
#include "llvm/IR/CallingConv.h"
-#include "llvm/IR/Type.h"
+#include "llvm/IR/Type.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MachineValueType.h"
#include <cstdint>
@@ -39,7 +39,7 @@ namespace llvm {
class CallBase;
class DataLayout;
class Function;
-class FunctionLoweringInfo;
+class FunctionLoweringInfo;
class MachineIRBuilder;
struct MachinePointerInfo;
class MachineRegisterInfo;
@@ -51,20 +51,20 @@ class CallLowering {
virtual void anchor();
public:
- struct BaseArgInfo {
- Type *Ty;
- SmallVector<ISD::ArgFlagsTy, 4> Flags;
- bool IsFixed;
-
- BaseArgInfo(Type *Ty,
- ArrayRef<ISD::ArgFlagsTy> Flags = ArrayRef<ISD::ArgFlagsTy>(),
- bool IsFixed = true)
- : Ty(Ty), Flags(Flags.begin(), Flags.end()), IsFixed(IsFixed) {}
-
- BaseArgInfo() : Ty(nullptr), IsFixed(false) {}
- };
-
- struct ArgInfo : public BaseArgInfo {
+ struct BaseArgInfo {
+ Type *Ty;
+ SmallVector<ISD::ArgFlagsTy, 4> Flags;
+ bool IsFixed;
+
+ BaseArgInfo(Type *Ty,
+ ArrayRef<ISD::ArgFlagsTy> Flags = ArrayRef<ISD::ArgFlagsTy>(),
+ bool IsFixed = true)
+ : Ty(Ty), Flags(Flags.begin(), Flags.end()), IsFixed(IsFixed) {}
+
+ BaseArgInfo() : Ty(nullptr), IsFixed(false) {}
+ };
+
+ struct ArgInfo : public BaseArgInfo {
SmallVector<Register, 4> Regs;
// If the argument had to be split into multiple parts according to the
// target calling convention, then this contains the original vregs
@@ -74,7 +74,7 @@ public:
ArgInfo(ArrayRef<Register> Regs, Type *Ty,
ArrayRef<ISD::ArgFlagsTy> Flags = ArrayRef<ISD::ArgFlagsTy>(),
bool IsFixed = true)
- : BaseArgInfo(Ty, Flags, IsFixed), Regs(Regs.begin(), Regs.end()) {
+ : BaseArgInfo(Ty, Flags, IsFixed), Regs(Regs.begin(), Regs.end()) {
if (!Regs.empty() && Flags.empty())
this->Flags.push_back(ISD::ArgFlagsTy());
// FIXME: We should have just one way of saying "no register".
@@ -83,7 +83,7 @@ public:
"only void types should have no register");
}
- ArgInfo() : BaseArgInfo() {}
+ ArgInfo() : BaseArgInfo() {}
};
struct CallLoweringInfo {
@@ -119,15 +119,15 @@ public:
/// True if the call is to a vararg function.
bool IsVarArg = false;
-
- /// True if the function's return value can be lowered to registers.
- bool CanLowerReturn = true;
-
- /// VReg to hold the hidden sret parameter.
- Register DemoteRegister;
-
- /// The stack index for sret demotion.
- int DemoteStackIndex;
+
+ /// True if the function's return value can be lowered to registers.
+ bool CanLowerReturn = true;
+
+ /// VReg to hold the hidden sret parameter.
+ Register DemoteRegister;
+
+ /// The stack index for sret demotion.
+ int DemoteStackIndex;
};
/// Argument handling is mostly uniform between the four places that
@@ -137,18 +137,18 @@ public:
/// argument should go, exactly what happens can vary slightly. This
/// class abstracts the differences.
struct ValueHandler {
- ValueHandler(bool IsIncoming, MachineIRBuilder &MIRBuilder,
- MachineRegisterInfo &MRI, CCAssignFn *AssignFn)
- : MIRBuilder(MIRBuilder), MRI(MRI), AssignFn(AssignFn),
- IsIncomingArgumentHandler(IsIncoming) {}
+ ValueHandler(bool IsIncoming, MachineIRBuilder &MIRBuilder,
+ MachineRegisterInfo &MRI, CCAssignFn *AssignFn)
+ : MIRBuilder(MIRBuilder), MRI(MRI), AssignFn(AssignFn),
+ IsIncomingArgumentHandler(IsIncoming) {}
virtual ~ValueHandler() = default;
/// Returns true if the handler is dealing with incoming arguments,
/// i.e. those that move values from some physical location to vregs.
- bool isIncomingArgumentHandler() const {
- return IsIncomingArgumentHandler;
- }
+ bool isIncomingArgumentHandler() const {
+ return IsIncomingArgumentHandler;
+ }
/// Materialize a VReg containing the address of the specified
/// stack-based object. This is either based on a FrameIndex or
@@ -176,7 +176,7 @@ public:
virtual void assignValueToAddress(const ArgInfo &Arg, Register Addr,
uint64_t Size, MachinePointerInfo &MPO,
CCValAssign &VA) {
- assert(Arg.Regs.size() == 1);
+ assert(Arg.Regs.size() == 1);
assignValueToAddress(Arg.Regs[0], Addr, Size, MPO, VA);
}
@@ -207,22 +207,22 @@ public:
CCAssignFn *AssignFn;
private:
- bool IsIncomingArgumentHandler;
+ bool IsIncomingArgumentHandler;
virtual void anchor();
};
- struct IncomingValueHandler : public ValueHandler {
- IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
- CCAssignFn *AssignFn)
- : ValueHandler(true, MIRBuilder, MRI, AssignFn) {}
- };
-
- struct OutgoingValueHandler : public ValueHandler {
- OutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
- CCAssignFn *AssignFn)
- : ValueHandler(false, MIRBuilder, MRI, AssignFn) {}
- };
-
+ struct IncomingValueHandler : public ValueHandler {
+ IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
+ CCAssignFn *AssignFn)
+ : ValueHandler(true, MIRBuilder, MRI, AssignFn) {}
+ };
+
+ struct OutgoingValueHandler : public ValueHandler {
+ OutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
+ CCAssignFn *AssignFn)
+ : ValueHandler(false, MIRBuilder, MRI, AssignFn) {}
+ };
+
protected:
/// Getter for generic TargetLowering class.
const TargetLowering *getTLI() const {
@@ -235,17 +235,17 @@ protected:
return static_cast<const XXXTargetLowering *>(TLI);
}
- /// \returns Flags corresponding to the attributes on the \p ArgIdx-th
- /// parameter of \p Call.
- ISD::ArgFlagsTy getAttributesForArgIdx(const CallBase &Call,
- unsigned ArgIdx) const;
-
- /// Adds flags to \p Flags based off of the attributes in \p Attrs.
- /// \p OpIdx is the index in \p Attrs to add flags from.
- void addArgFlagsFromAttributes(ISD::ArgFlagsTy &Flags,
- const AttributeList &Attrs,
- unsigned OpIdx) const;
-
+ /// \returns Flags corresponding to the attributes on the \p ArgIdx-th
+ /// parameter of \p Call.
+ ISD::ArgFlagsTy getAttributesForArgIdx(const CallBase &Call,
+ unsigned ArgIdx) const;
+
+ /// Adds flags to \p Flags based off of the attributes in \p Attrs.
+ /// \p OpIdx is the index in \p Attrs to add flags from.
+ void addArgFlagsFromAttributes(ISD::ArgFlagsTy &Flags,
+ const AttributeList &Attrs,
+ unsigned OpIdx) const;
+
template <typename FuncInfoTy>
void setArgFlags(ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL,
const FuncInfoTy &FuncInfo) const;
@@ -269,7 +269,7 @@ protected:
MachineIRBuilder &MIRBuilder) const;
/// Invoke Handler::assignArg on each of the given \p Args and then use
- /// \p Handler to move them to the assigned locations.
+ /// \p Handler to move them to the assigned locations.
///
/// \return True if everything has succeeded, false otherwise.
bool handleAssignments(MachineIRBuilder &MIRBuilder,
@@ -289,14 +289,14 @@ protected:
CCAssignFn &AssignFnFixed,
CCAssignFn &AssignFnVarArg) const;
- /// Check whether parameters to a call that are passed in callee saved
- /// registers are the same as from the calling function. This needs to be
- /// checked for tail call eligibility.
- bool parametersInCSRMatch(const MachineRegisterInfo &MRI,
- const uint32_t *CallerPreservedMask,
- const SmallVectorImpl<CCValAssign> &ArgLocs,
- const SmallVectorImpl<ArgInfo> &OutVals) const;
-
+ /// Check whether parameters to a call that are passed in callee saved
+ /// registers are the same as from the calling function. This needs to be
+ /// checked for tail call eligibility.
+ bool parametersInCSRMatch(const MachineRegisterInfo &MRI,
+ const uint32_t *CallerPreservedMask,
+ const SmallVectorImpl<CCValAssign> &ArgLocs,
+ const SmallVectorImpl<ArgInfo> &OutVals) const;
+
/// \returns True if the calling convention for a callee and its caller pass
/// results in the same way. Typically used for tail call eligibility checks.
///
@@ -327,73 +327,73 @@ public:
return false;
}
- /// Load the returned value from the stack into virtual registers in \p VRegs.
- /// It uses the frame index \p FI and the start offset from \p DemoteReg.
- /// The loaded data size will be determined from \p RetTy.
- void insertSRetLoads(MachineIRBuilder &MIRBuilder, Type *RetTy,
- ArrayRef<Register> VRegs, Register DemoteReg,
- int FI) const;
-
- /// Store the return value given by \p VRegs into stack starting at the offset
- /// specified in \p DemoteReg.
- void insertSRetStores(MachineIRBuilder &MIRBuilder, Type *RetTy,
- ArrayRef<Register> VRegs, Register DemoteReg) const;
-
- /// Insert the hidden sret ArgInfo to the beginning of \p SplitArgs.
- /// This function should be called from the target specific
- /// lowerFormalArguments when \p F requires the sret demotion.
- void insertSRetIncomingArgument(const Function &F,
- SmallVectorImpl<ArgInfo> &SplitArgs,
- Register &DemoteReg, MachineRegisterInfo &MRI,
- const DataLayout &DL) const;
-
- /// For the call-base described by \p CB, insert the hidden sret ArgInfo to
- /// the OrigArgs field of \p Info.
- void insertSRetOutgoingArgument(MachineIRBuilder &MIRBuilder,
- const CallBase &CB,
- CallLoweringInfo &Info) const;
-
- /// \return True if the return type described by \p Outs can be returned
- /// without performing sret demotion.
- bool checkReturn(CCState &CCInfo, SmallVectorImpl<BaseArgInfo> &Outs,
- CCAssignFn *Fn) const;
-
- /// Get the type and the ArgFlags for the split components of \p RetTy as
- /// returned by \c ComputeValueVTs.
- void getReturnInfo(CallingConv::ID CallConv, Type *RetTy, AttributeList Attrs,
- SmallVectorImpl<BaseArgInfo> &Outs,
- const DataLayout &DL) const;
-
- /// Toplevel function to check the return type based on the target calling
- /// convention. \return True if the return value of \p MF can be returned
- /// without performing sret demotion.
- bool checkReturnTypeForCallConv(MachineFunction &MF) const;
-
- /// This hook must be implemented to check whether the return values
- /// described by \p Outs can fit into the return registers. If false
- /// is returned, an sret-demotion is performed.
- virtual bool canLowerReturn(MachineFunction &MF, CallingConv::ID CallConv,
- SmallVectorImpl<BaseArgInfo> &Outs,
- bool IsVarArg) const {
- return true;
- }
-
+ /// Load the returned value from the stack into virtual registers in \p VRegs.
+ /// It uses the frame index \p FI and the start offset from \p DemoteReg.
+ /// The loaded data size will be determined from \p RetTy.
+ void insertSRetLoads(MachineIRBuilder &MIRBuilder, Type *RetTy,
+ ArrayRef<Register> VRegs, Register DemoteReg,
+ int FI) const;
+
+ /// Store the return value given by \p VRegs into stack starting at the offset
+ /// specified in \p DemoteReg.
+ void insertSRetStores(MachineIRBuilder &MIRBuilder, Type *RetTy,
+ ArrayRef<Register> VRegs, Register DemoteReg) const;
+
+ /// Insert the hidden sret ArgInfo to the beginning of \p SplitArgs.
+ /// This function should be called from the target specific
+ /// lowerFormalArguments when \p F requires the sret demotion.
+ void insertSRetIncomingArgument(const Function &F,
+ SmallVectorImpl<ArgInfo> &SplitArgs,
+ Register &DemoteReg, MachineRegisterInfo &MRI,
+ const DataLayout &DL) const;
+
+ /// For the call-base described by \p CB, insert the hidden sret ArgInfo to
+ /// the OrigArgs field of \p Info.
+ void insertSRetOutgoingArgument(MachineIRBuilder &MIRBuilder,
+ const CallBase &CB,
+ CallLoweringInfo &Info) const;
+
+ /// \return True if the return type described by \p Outs can be returned
+ /// without performing sret demotion.
+ bool checkReturn(CCState &CCInfo, SmallVectorImpl<BaseArgInfo> &Outs,
+ CCAssignFn *Fn) const;
+
+ /// Get the type and the ArgFlags for the split components of \p RetTy as
+ /// returned by \c ComputeValueVTs.
+ void getReturnInfo(CallingConv::ID CallConv, Type *RetTy, AttributeList Attrs,
+ SmallVectorImpl<BaseArgInfo> &Outs,
+ const DataLayout &DL) const;
+
+ /// Toplevel function to check the return type based on the target calling
+ /// convention. \return True if the return value of \p MF can be returned
+ /// without performing sret demotion.
+ bool checkReturnTypeForCallConv(MachineFunction &MF) const;
+
+ /// This hook must be implemented to check whether the return values
+ /// described by \p Outs can fit into the return registers. If false
+ /// is returned, an sret-demotion is performed.
+ virtual bool canLowerReturn(MachineFunction &MF, CallingConv::ID CallConv,
+ SmallVectorImpl<BaseArgInfo> &Outs,
+ bool IsVarArg) const {
+ return true;
+ }
+
/// This hook must be implemented to lower outgoing return values, described
/// by \p Val, into the specified virtual registers \p VRegs.
/// This hook is used by GlobalISel.
///
- /// \p FLI is required for sret demotion.
- ///
+ /// \p FLI is required for sret demotion.
+ ///
/// \p SwiftErrorVReg is non-zero if the function has a swifterror parameter
/// that needs to be implicitly returned.
///
/// \return True if the lowering succeeds, false otherwise.
virtual bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
- ArrayRef<Register> VRegs, FunctionLoweringInfo &FLI,
+ ArrayRef<Register> VRegs, FunctionLoweringInfo &FLI,
Register SwiftErrorVReg) const {
if (!supportSwiftError()) {
assert(SwiftErrorVReg == 0 && "attempt to use unsupported swifterror");
- return lowerReturn(MIRBuilder, Val, VRegs, FLI);
+ return lowerReturn(MIRBuilder, Val, VRegs, FLI);
}
return false;
}
@@ -401,8 +401,8 @@ public:
/// This hook behaves as the extended lowerReturn function, but for targets
/// that do not support swifterror value promotion.
virtual bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
- ArrayRef<Register> VRegs,
- FunctionLoweringInfo &FLI) const {
+ ArrayRef<Register> VRegs,
+ FunctionLoweringInfo &FLI) const {
return false;
}
@@ -415,13 +415,13 @@ public:
/// the second in \c VRegs[1], and so on. For each argument, there will be one
/// register for each non-aggregate type, as returned by \c computeValueLLTs.
/// \p MIRBuilder is set to the proper insertion for the argument
- /// lowering. \p FLI is required for sret demotion.
+ /// lowering. \p FLI is required for sret demotion.
///
/// \return True if the lowering succeeded, false otherwise.
virtual bool lowerFormalArguments(MachineIRBuilder &MIRBuilder,
const Function &F,
- ArrayRef<ArrayRef<Register>> VRegs,
- FunctionLoweringInfo &FLI) const {
+ ArrayRef<ArrayRef<Register>> VRegs,
+ FunctionLoweringInfo &FLI) const {
return false;
}
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index 7e482d9b7d..1d29a2ddc8 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -24,8 +24,8 @@
#ifndef LLVM_CODEGEN_GLOBALISEL_COMBINER_HELPER_H
#define LLVM_CODEGEN_GLOBALISEL_COMBINER_HELPER_H
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/CodeGen/LowLevelType.h"
#include "llvm/CodeGen/Register.h"
#include "llvm/Support/Alignment.h"
@@ -34,15 +34,15 @@ namespace llvm {
class GISelChangeObserver;
class MachineIRBuilder;
-class MachineInstrBuilder;
+class MachineInstrBuilder;
class MachineRegisterInfo;
class MachineInstr;
class MachineOperand;
class GISelKnownBits;
class MachineDominatorTree;
class LegalizerInfo;
-struct LegalityQuery;
-class TargetLowering;
+struct LegalityQuery;
+class TargetLowering;
struct PreferredTuple {
LLT Ty; // The result type of the extend.
@@ -62,37 +62,37 @@ struct PtrAddChain {
Register Base;
};
-struct RegisterImmPair {
- Register Reg;
- int64_t Imm;
-};
-
-struct ShiftOfShiftedLogic {
- MachineInstr *Logic;
- MachineInstr *Shift2;
- Register LogicNonShiftReg;
- uint64_t ValSum;
-};
-
-using OperandBuildSteps =
- SmallVector<std::function<void(MachineInstrBuilder &)>, 4>;
-struct InstructionBuildSteps {
- unsigned Opcode = 0; /// The opcode for the produced instruction.
- OperandBuildSteps OperandFns; /// Operands to be added to the instruction.
- InstructionBuildSteps() = default;
- InstructionBuildSteps(unsigned Opcode, const OperandBuildSteps &OperandFns)
- : Opcode(Opcode), OperandFns(OperandFns) {}
-};
-
-struct InstructionStepsMatchInfo {
- /// Describes instructions to be built during a combine.
- SmallVector<InstructionBuildSteps, 2> InstrsToBuild;
- InstructionStepsMatchInfo() = default;
- InstructionStepsMatchInfo(
- std::initializer_list<InstructionBuildSteps> InstrsToBuild)
- : InstrsToBuild(InstrsToBuild) {}
-};
-
+struct RegisterImmPair {
+ Register Reg;
+ int64_t Imm;
+};
+
+struct ShiftOfShiftedLogic {
+ MachineInstr *Logic;
+ MachineInstr *Shift2;
+ Register LogicNonShiftReg;
+ uint64_t ValSum;
+};
+
+using OperandBuildSteps =
+ SmallVector<std::function<void(MachineInstrBuilder &)>, 4>;
+struct InstructionBuildSteps {
+ unsigned Opcode = 0; /// The opcode for the produced instruction.
+ OperandBuildSteps OperandFns; /// Operands to be added to the instruction.
+ InstructionBuildSteps() = default;
+ InstructionBuildSteps(unsigned Opcode, const OperandBuildSteps &OperandFns)
+ : Opcode(Opcode), OperandFns(OperandFns) {}
+};
+
+struct InstructionStepsMatchInfo {
+ /// Describes instructions to be built during a combine.
+ SmallVector<InstructionBuildSteps, 2> InstrsToBuild;
+ InstructionStepsMatchInfo() = default;
+ InstructionStepsMatchInfo(
+ std::initializer_list<InstructionBuildSteps> InstrsToBuild)
+ : InstrsToBuild(InstrsToBuild) {}
+};
+
class CombinerHelper {
protected:
MachineIRBuilder &Builder;
@@ -112,12 +112,12 @@ public:
return KB;
}
- const TargetLowering &getTargetLowering() const;
-
- /// \return true if the combine is running prior to legalization, or if \p
- /// Query is legal on the target.
- bool isLegalOrBeforeLegalizer(const LegalityQuery &Query) const;
-
+ const TargetLowering &getTargetLowering() const;
+
+ /// \return true if the combine is running prior to legalization, or if \p
+ /// Query is legal on the target.
+ bool isLegalOrBeforeLegalizer(const LegalityQuery &Query) const;
+
/// MachineRegisterInfo::replaceRegWith() and inform the observer of the changes
void replaceRegWith(MachineRegisterInfo &MRI, Register FromReg, Register ToReg) const;
@@ -156,18 +156,18 @@ public:
bool matchCombineIndexedLoadStore(MachineInstr &MI, IndexedLoadStoreMatchInfo &MatchInfo);
void applyCombineIndexedLoadStore(MachineInstr &MI, IndexedLoadStoreMatchInfo &MatchInfo);
- bool matchSextTruncSextLoad(MachineInstr &MI);
- bool applySextTruncSextLoad(MachineInstr &MI);
+ bool matchSextTruncSextLoad(MachineInstr &MI);
+ bool applySextTruncSextLoad(MachineInstr &MI);
- /// Match sext_inreg(load p), imm -> sextload p
- bool matchSextInRegOfLoad(MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo);
- bool applySextInRegOfLoad(MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo);
+ /// Match sext_inreg(load p), imm -> sextload p
+ bool matchSextInRegOfLoad(MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo);
+ bool applySextInRegOfLoad(MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo);
+
+ /// If a brcond's true block is not the fallthrough, make it so by inverting
+ /// the condition and swapping operands.
+ bool matchOptBrCondByInvertingCond(MachineInstr &MI);
+ void applyOptBrCondByInvertingCond(MachineInstr &MI);
- /// If a brcond's true block is not the fallthrough, make it so by inverting
- /// the condition and swapping operands.
- bool matchOptBrCondByInvertingCond(MachineInstr &MI);
- void applyOptBrCondByInvertingCond(MachineInstr &MI);
-
/// If \p MI is G_CONCAT_VECTORS, try to combine it.
/// Returns true if MI changed.
/// Right now, we support:
@@ -243,28 +243,28 @@ public:
bool matchPtrAddImmedChain(MachineInstr &MI, PtrAddChain &MatchInfo);
bool applyPtrAddImmedChain(MachineInstr &MI, PtrAddChain &MatchInfo);
- /// Fold (shift (shift base, x), y) -> (shift base (x+y))
- bool matchShiftImmedChain(MachineInstr &MI, RegisterImmPair &MatchInfo);
- bool applyShiftImmedChain(MachineInstr &MI, RegisterImmPair &MatchInfo);
-
- /// If we have a shift-by-constant of a bitwise logic op that itself has a
- /// shift-by-constant operand with identical opcode, we may be able to convert
- /// that into 2 independent shifts followed by the logic op.
- bool matchShiftOfShiftedLogic(MachineInstr &MI,
- ShiftOfShiftedLogic &MatchInfo);
- bool applyShiftOfShiftedLogic(MachineInstr &MI,
- ShiftOfShiftedLogic &MatchInfo);
-
+ /// Fold (shift (shift base, x), y) -> (shift base (x+y))
+ bool matchShiftImmedChain(MachineInstr &MI, RegisterImmPair &MatchInfo);
+ bool applyShiftImmedChain(MachineInstr &MI, RegisterImmPair &MatchInfo);
+
+ /// If we have a shift-by-constant of a bitwise logic op that itself has a
+ /// shift-by-constant operand with identical opcode, we may be able to convert
+ /// that into 2 independent shifts followed by the logic op.
+ bool matchShiftOfShiftedLogic(MachineInstr &MI,
+ ShiftOfShiftedLogic &MatchInfo);
+ bool applyShiftOfShiftedLogic(MachineInstr &MI,
+ ShiftOfShiftedLogic &MatchInfo);
+
/// Transform a multiply by a power-of-2 value to a left shift.
bool matchCombineMulToShl(MachineInstr &MI, unsigned &ShiftVal);
bool applyCombineMulToShl(MachineInstr &MI, unsigned &ShiftVal);
- // Transform a G_SHL with an extended source into a narrower shift if
- // possible.
- bool matchCombineShlOfExtend(MachineInstr &MI, RegisterImmPair &MatchData);
- bool applyCombineShlOfExtend(MachineInstr &MI,
- const RegisterImmPair &MatchData);
-
+ // Transform a G_SHL with an extended source into a narrower shift if
+ // possible.
+ bool matchCombineShlOfExtend(MachineInstr &MI, RegisterImmPair &MatchData);
+ bool applyCombineShlOfExtend(MachineInstr &MI,
+ const RegisterImmPair &MatchData);
+
/// Reduce a shift by a constant to an unmerge and a shift on a half sized
/// type. This will not produce a shift smaller than \p TargetShiftSize.
bool matchCombineShiftToUnmerge(MachineInstr &MI, unsigned TargetShiftSize,
@@ -272,86 +272,86 @@ public:
bool applyCombineShiftToUnmerge(MachineInstr &MI, const unsigned &ShiftVal);
bool tryCombineShiftToUnmerge(MachineInstr &MI, unsigned TargetShiftAmount);
- /// Transform <ty,...> G_UNMERGE(G_MERGE ty X, Y, Z) -> ty X, Y, Z.
- bool
- matchCombineUnmergeMergeToPlainValues(MachineInstr &MI,
- SmallVectorImpl<Register> &Operands);
- bool
- applyCombineUnmergeMergeToPlainValues(MachineInstr &MI,
- SmallVectorImpl<Register> &Operands);
-
- /// Transform G_UNMERGE Constant -> Constant1, Constant2, ...
- bool matchCombineUnmergeConstant(MachineInstr &MI,
- SmallVectorImpl<APInt> &Csts);
- bool applyCombineUnmergeConstant(MachineInstr &MI,
- SmallVectorImpl<APInt> &Csts);
-
- /// Transform X, Y<dead> = G_UNMERGE Z -> X = G_TRUNC Z.
- bool matchCombineUnmergeWithDeadLanesToTrunc(MachineInstr &MI);
- bool applyCombineUnmergeWithDeadLanesToTrunc(MachineInstr &MI);
-
- /// Transform X, Y = G_UNMERGE(G_ZEXT(Z)) -> X = G_ZEXT(Z); Y = G_CONSTANT 0
- bool matchCombineUnmergeZExtToZExt(MachineInstr &MI);
- bool applyCombineUnmergeZExtToZExt(MachineInstr &MI);
-
- /// Transform fp_instr(cst) to constant result of the fp operation.
- bool matchCombineConstantFoldFpUnary(MachineInstr &MI,
- Optional<APFloat> &Cst);
- bool applyCombineConstantFoldFpUnary(MachineInstr &MI,
- Optional<APFloat> &Cst);
-
- /// Transform IntToPtr(PtrToInt(x)) to x if cast is in the same address space.
- bool matchCombineI2PToP2I(MachineInstr &MI, Register &Reg);
- bool applyCombineI2PToP2I(MachineInstr &MI, Register &Reg);
-
- /// Transform PtrToInt(IntToPtr(x)) to x.
- bool matchCombineP2IToI2P(MachineInstr &MI, Register &Reg);
- bool applyCombineP2IToI2P(MachineInstr &MI, Register &Reg);
-
- /// Transform G_ADD (G_PTRTOINT x), y -> G_PTRTOINT (G_PTR_ADD x, y)
- /// Transform G_ADD y, (G_PTRTOINT x) -> G_PTRTOINT (G_PTR_ADD x, y)
- bool matchCombineAddP2IToPtrAdd(MachineInstr &MI,
- std::pair<Register, bool> &PtrRegAndCommute);
- bool applyCombineAddP2IToPtrAdd(MachineInstr &MI,
- std::pair<Register, bool> &PtrRegAndCommute);
-
- // Transform G_PTR_ADD (G_PTRTOINT C1), C2 -> C1 + C2
- bool matchCombineConstPtrAddToI2P(MachineInstr &MI, int64_t &NewCst);
- bool applyCombineConstPtrAddToI2P(MachineInstr &MI, int64_t &NewCst);
-
- /// Transform anyext(trunc(x)) to x.
- bool matchCombineAnyExtTrunc(MachineInstr &MI, Register &Reg);
- bool applyCombineAnyExtTrunc(MachineInstr &MI, Register &Reg);
-
- /// Transform [asz]ext([asz]ext(x)) to [asz]ext x.
- bool matchCombineExtOfExt(MachineInstr &MI,
- std::tuple<Register, unsigned> &MatchInfo);
- bool applyCombineExtOfExt(MachineInstr &MI,
- std::tuple<Register, unsigned> &MatchInfo);
-
- /// Transform fneg(fneg(x)) to x.
- bool matchCombineFNegOfFNeg(MachineInstr &MI, Register &Reg);
-
- /// Match fabs(fabs(x)) to fabs(x).
- bool matchCombineFAbsOfFAbs(MachineInstr &MI, Register &Src);
- bool applyCombineFAbsOfFAbs(MachineInstr &MI, Register &Src);
-
- /// Transform trunc ([asz]ext x) to x or ([asz]ext x) or (trunc x).
- bool matchCombineTruncOfExt(MachineInstr &MI,
- std::pair<Register, unsigned> &MatchInfo);
- bool applyCombineTruncOfExt(MachineInstr &MI,
- std::pair<Register, unsigned> &MatchInfo);
-
- /// Transform trunc (shl x, K) to shl (trunc x),
- /// K => K < VT.getScalarSizeInBits().
- bool matchCombineTruncOfShl(MachineInstr &MI,
- std::pair<Register, Register> &MatchInfo);
- bool applyCombineTruncOfShl(MachineInstr &MI,
- std::pair<Register, Register> &MatchInfo);
-
- /// Transform G_MUL(x, -1) to G_SUB(0, x)
- bool applyCombineMulByNegativeOne(MachineInstr &MI);
-
+ /// Transform <ty,...> G_UNMERGE(G_MERGE ty X, Y, Z) -> ty X, Y, Z.
+ bool
+ matchCombineUnmergeMergeToPlainValues(MachineInstr &MI,
+ SmallVectorImpl<Register> &Operands);
+ bool
+ applyCombineUnmergeMergeToPlainValues(MachineInstr &MI,
+ SmallVectorImpl<Register> &Operands);
+
+ /// Transform G_UNMERGE Constant -> Constant1, Constant2, ...
+ bool matchCombineUnmergeConstant(MachineInstr &MI,
+ SmallVectorImpl<APInt> &Csts);
+ bool applyCombineUnmergeConstant(MachineInstr &MI,
+ SmallVectorImpl<APInt> &Csts);
+
+ /// Transform X, Y<dead> = G_UNMERGE Z -> X = G_TRUNC Z.
+ bool matchCombineUnmergeWithDeadLanesToTrunc(MachineInstr &MI);
+ bool applyCombineUnmergeWithDeadLanesToTrunc(MachineInstr &MI);
+
+ /// Transform X, Y = G_UNMERGE(G_ZEXT(Z)) -> X = G_ZEXT(Z); Y = G_CONSTANT 0
+ bool matchCombineUnmergeZExtToZExt(MachineInstr &MI);
+ bool applyCombineUnmergeZExtToZExt(MachineInstr &MI);
+
+ /// Transform fp_instr(cst) to constant result of the fp operation.
+ bool matchCombineConstantFoldFpUnary(MachineInstr &MI,
+ Optional<APFloat> &Cst);
+ bool applyCombineConstantFoldFpUnary(MachineInstr &MI,
+ Optional<APFloat> &Cst);
+
+ /// Transform IntToPtr(PtrToInt(x)) to x if cast is in the same address space.
+ bool matchCombineI2PToP2I(MachineInstr &MI, Register &Reg);
+ bool applyCombineI2PToP2I(MachineInstr &MI, Register &Reg);
+
+ /// Transform PtrToInt(IntToPtr(x)) to x.
+ bool matchCombineP2IToI2P(MachineInstr &MI, Register &Reg);
+ bool applyCombineP2IToI2P(MachineInstr &MI, Register &Reg);
+
+ /// Transform G_ADD (G_PTRTOINT x), y -> G_PTRTOINT (G_PTR_ADD x, y)
+ /// Transform G_ADD y, (G_PTRTOINT x) -> G_PTRTOINT (G_PTR_ADD x, y)
+ bool matchCombineAddP2IToPtrAdd(MachineInstr &MI,
+ std::pair<Register, bool> &PtrRegAndCommute);
+ bool applyCombineAddP2IToPtrAdd(MachineInstr &MI,
+ std::pair<Register, bool> &PtrRegAndCommute);
+
+ // Transform G_PTR_ADD (G_PTRTOINT C1), C2 -> C1 + C2
+ bool matchCombineConstPtrAddToI2P(MachineInstr &MI, int64_t &NewCst);
+ bool applyCombineConstPtrAddToI2P(MachineInstr &MI, int64_t &NewCst);
+
+ /// Transform anyext(trunc(x)) to x.
+ bool matchCombineAnyExtTrunc(MachineInstr &MI, Register &Reg);
+ bool applyCombineAnyExtTrunc(MachineInstr &MI, Register &Reg);
+
+ /// Transform [asz]ext([asz]ext(x)) to [asz]ext x.
+ bool matchCombineExtOfExt(MachineInstr &MI,
+ std::tuple<Register, unsigned> &MatchInfo);
+ bool applyCombineExtOfExt(MachineInstr &MI,
+ std::tuple<Register, unsigned> &MatchInfo);
+
+ /// Transform fneg(fneg(x)) to x.
+ bool matchCombineFNegOfFNeg(MachineInstr &MI, Register &Reg);
+
+ /// Match fabs(fabs(x)) to fabs(x).
+ bool matchCombineFAbsOfFAbs(MachineInstr &MI, Register &Src);
+ bool applyCombineFAbsOfFAbs(MachineInstr &MI, Register &Src);
+
+ /// Transform trunc ([asz]ext x) to x or ([asz]ext x) or (trunc x).
+ bool matchCombineTruncOfExt(MachineInstr &MI,
+ std::pair<Register, unsigned> &MatchInfo);
+ bool applyCombineTruncOfExt(MachineInstr &MI,
+ std::pair<Register, unsigned> &MatchInfo);
+
+ /// Transform trunc (shl x, K) to shl (trunc x),
+ /// K => K < VT.getScalarSizeInBits().
+ bool matchCombineTruncOfShl(MachineInstr &MI,
+ std::pair<Register, Register> &MatchInfo);
+ bool applyCombineTruncOfShl(MachineInstr &MI,
+ std::pair<Register, Register> &MatchInfo);
+
+ /// Transform G_MUL(x, -1) to G_SUB(0, x)
+ bool applyCombineMulByNegativeOne(MachineInstr &MI);
+
/// Return true if any explicit use operand on \p MI is defined by a
/// G_IMPLICIT_DEF.
bool matchAnyExplicitUseIsUndef(MachineInstr &MI);
@@ -366,13 +366,13 @@ public:
/// Return true if a G_STORE instruction \p MI is storing an undef value.
bool matchUndefStore(MachineInstr &MI);
- /// Return true if a G_SELECT instruction \p MI has an undef comparison.
- bool matchUndefSelectCmp(MachineInstr &MI);
-
- /// Return true if a G_SELECT instruction \p MI has a constant comparison. If
- /// true, \p OpIdx will store the operand index of the known selected value.
- bool matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx);
-
+ /// Return true if a G_SELECT instruction \p MI has an undef comparison.
+ bool matchUndefSelectCmp(MachineInstr &MI);
+
+ /// Return true if a G_SELECT instruction \p MI has a constant comparison. If
+ /// true, \p OpIdx will store the operand index of the known selected value.
+ bool matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx);
+
/// Replace an instruction with a G_FCONSTANT with value \p C.
bool replaceInstWithFConstant(MachineInstr &MI, double C);
@@ -385,9 +385,9 @@ public:
/// Delete \p MI and replace all of its uses with its \p OpIdx-th operand.
bool replaceSingleDefInstWithOperand(MachineInstr &MI, unsigned OpIdx);
- /// Delete \p MI and replace all of its uses with \p Replacement.
- bool replaceSingleDefInstWithReg(MachineInstr &MI, Register Replacement);
-
+ /// Delete \p MI and replace all of its uses with \p Replacement.
+ bool replaceSingleDefInstWithReg(MachineInstr &MI, Register Replacement);
+
/// Return true if \p MOP1 and \p MOP2 are register operands are defined by
/// equivalent instructions.
bool matchEqualDefs(const MachineOperand &MOP1, const MachineOperand &MOP2);
@@ -405,12 +405,12 @@ public:
/// Check if operand \p OpIdx is zero.
bool matchOperandIsZero(MachineInstr &MI, unsigned OpIdx);
- /// Check if operand \p OpIdx is undef.
- bool matchOperandIsUndef(MachineInstr &MI, unsigned OpIdx);
-
- /// Check if operand \p OpIdx is known to be a power of 2.
- bool matchOperandIsKnownToBeAPowerOfTwo(MachineInstr &MI, unsigned OpIdx);
-
+ /// Check if operand \p OpIdx is undef.
+ bool matchOperandIsUndef(MachineInstr &MI, unsigned OpIdx);
+
+ /// Check if operand \p OpIdx is known to be a power of 2.
+ bool matchOperandIsKnownToBeAPowerOfTwo(MachineInstr &MI, unsigned OpIdx);
+
/// Erase \p MI
bool eraseInst(MachineInstr &MI);
@@ -420,79 +420,79 @@ public:
bool applySimplifyAddToSub(MachineInstr &MI,
std::tuple<Register, Register> &MatchInfo);
- /// Match (logic_op (op x...), (op y...)) -> (op (logic_op x, y))
- bool
- matchHoistLogicOpWithSameOpcodeHands(MachineInstr &MI,
- InstructionStepsMatchInfo &MatchInfo);
-
- /// Replace \p MI with a series of instructions described in \p MatchInfo.
- bool applyBuildInstructionSteps(MachineInstr &MI,
- InstructionStepsMatchInfo &MatchInfo);
-
- /// Match ashr (shl x, C), C -> sext_inreg (C)
- bool matchAshrShlToSextInreg(MachineInstr &MI,
- std::tuple<Register, int64_t> &MatchInfo);
- bool applyAshShlToSextInreg(MachineInstr &MI,
- std::tuple<Register, int64_t> &MatchInfo);
- /// \return true if \p MI is a G_AND instruction whose operands are x and y
- /// where x & y == x or x & y == y. (E.g., one of operands is all-ones value.)
- ///
- /// \param [in] MI - The G_AND instruction.
- /// \param [out] Replacement - A register the G_AND should be replaced with on
- /// success.
- bool matchRedundantAnd(MachineInstr &MI, Register &Replacement);
-
- /// \return true if \p MI is a G_OR instruction whose operands are x and y
- /// where x | y == x or x | y == y. (E.g., one of operands is all-zeros
- /// value.)
- ///
- /// \param [in] MI - The G_OR instruction.
- /// \param [out] Replacement - A register the G_OR should be replaced with on
- /// success.
- bool matchRedundantOr(MachineInstr &MI, Register &Replacement);
-
- /// \return true if \p MI is a G_SEXT_INREG that can be erased.
- bool matchRedundantSExtInReg(MachineInstr &MI);
-
- /// Combine inverting a result of a compare into the opposite cond code.
- bool matchNotCmp(MachineInstr &MI, SmallVectorImpl<Register> &RegsToNegate);
- bool applyNotCmp(MachineInstr &MI, SmallVectorImpl<Register> &RegsToNegate);
-
- /// Fold (xor (and x, y), y) -> (and (not x), y)
- ///{
- bool matchXorOfAndWithSameReg(MachineInstr &MI,
- std::pair<Register, Register> &MatchInfo);
- bool applyXorOfAndWithSameReg(MachineInstr &MI,
- std::pair<Register, Register> &MatchInfo);
- ///}
-
- /// Combine G_PTR_ADD with nullptr to G_INTTOPTR
- bool matchPtrAddZero(MachineInstr &MI);
- bool applyPtrAddZero(MachineInstr &MI);
-
- /// Combine G_UREM x, (known power of 2) to an add and bitmasking.
- bool applySimplifyURemByPow2(MachineInstr &MI);
-
- bool matchCombineInsertVecElts(MachineInstr &MI,
- SmallVectorImpl<Register> &MatchInfo);
-
- bool applyCombineInsertVecElts(MachineInstr &MI,
- SmallVectorImpl<Register> &MatchInfo);
-
- /// Match expression trees of the form
- ///
- /// \code
- /// sN *a = ...
- /// sM val = a[0] | (a[1] << N) | (a[2] << 2N) | (a[3] << 3N) ...
- /// \endcode
- ///
- /// And check if the tree can be replaced with a M-bit load + possibly a
- /// bswap.
- bool matchLoadOrCombine(MachineInstr &MI,
- std::function<void(MachineIRBuilder &)> &MatchInfo);
- bool applyLoadOrCombine(MachineInstr &MI,
- std::function<void(MachineIRBuilder &)> &MatchInfo);
-
+ /// Match (logic_op (op x...), (op y...)) -> (op (logic_op x, y))
+ bool
+ matchHoistLogicOpWithSameOpcodeHands(MachineInstr &MI,
+ InstructionStepsMatchInfo &MatchInfo);
+
+ /// Replace \p MI with a series of instructions described in \p MatchInfo.
+ bool applyBuildInstructionSteps(MachineInstr &MI,
+ InstructionStepsMatchInfo &MatchInfo);
+
+ /// Match ashr (shl x, C), C -> sext_inreg (C)
+ bool matchAshrShlToSextInreg(MachineInstr &MI,
+ std::tuple<Register, int64_t> &MatchInfo);
+ bool applyAshShlToSextInreg(MachineInstr &MI,
+ std::tuple<Register, int64_t> &MatchInfo);
+ /// \return true if \p MI is a G_AND instruction whose operands are x and y
+ /// where x & y == x or x & y == y. (E.g., one of operands is all-ones value.)
+ ///
+ /// \param [in] MI - The G_AND instruction.
+ /// \param [out] Replacement - A register the G_AND should be replaced with on
+ /// success.
+ bool matchRedundantAnd(MachineInstr &MI, Register &Replacement);
+
+ /// \return true if \p MI is a G_OR instruction whose operands are x and y
+ /// where x | y == x or x | y == y. (E.g., one of operands is all-zeros
+ /// value.)
+ ///
+ /// \param [in] MI - The G_OR instruction.
+ /// \param [out] Replacement - A register the G_OR should be replaced with on
+ /// success.
+ bool matchRedundantOr(MachineInstr &MI, Register &Replacement);
+
+ /// \return true if \p MI is a G_SEXT_INREG that can be erased.
+ bool matchRedundantSExtInReg(MachineInstr &MI);
+
+ /// Combine inverting a result of a compare into the opposite cond code.
+ bool matchNotCmp(MachineInstr &MI, SmallVectorImpl<Register> &RegsToNegate);
+ bool applyNotCmp(MachineInstr &MI, SmallVectorImpl<Register> &RegsToNegate);
+
+ /// Fold (xor (and x, y), y) -> (and (not x), y)
+ ///{
+ bool matchXorOfAndWithSameReg(MachineInstr &MI,
+ std::pair<Register, Register> &MatchInfo);
+ bool applyXorOfAndWithSameReg(MachineInstr &MI,
+ std::pair<Register, Register> &MatchInfo);
+ ///}
+
+ /// Combine G_PTR_ADD with nullptr to G_INTTOPTR
+ bool matchPtrAddZero(MachineInstr &MI);
+ bool applyPtrAddZero(MachineInstr &MI);
+
+ /// Combine G_UREM x, (known power of 2) to an add and bitmasking.
+ bool applySimplifyURemByPow2(MachineInstr &MI);
+
+ bool matchCombineInsertVecElts(MachineInstr &MI,
+ SmallVectorImpl<Register> &MatchInfo);
+
+ bool applyCombineInsertVecElts(MachineInstr &MI,
+ SmallVectorImpl<Register> &MatchInfo);
+
+ /// Match expression trees of the form
+ ///
+ /// \code
+ /// sN *a = ...
+ /// sM val = a[0] | (a[1] << N) | (a[2] << 2N) | (a[3] << 3N) ...
+ /// \endcode
+ ///
+ /// And check if the tree can be replaced with a M-bit load + possibly a
+ /// bswap.
+ bool matchLoadOrCombine(MachineInstr &MI,
+ std::function<void(MachineIRBuilder &)> &MatchInfo);
+ bool applyLoadOrCombine(MachineInstr &MI,
+ std::function<void(MachineIRBuilder &)> &MatchInfo);
+
/// Try to transform \p MI by using all of the above
/// combine functions. Returns true if changed.
bool tryCombine(MachineInstr &MI);
@@ -521,30 +521,30 @@ private:
/// \returns true if a candidate is found.
bool findPreIndexCandidate(MachineInstr &MI, Register &Addr, Register &Base,
Register &Offset);
-
- /// Helper function for matchLoadOrCombine. Searches for Registers
- /// which may have been produced by a load instruction + some arithmetic.
- ///
- /// \param [in] Root - The search root.
- ///
- /// \returns The Registers found during the search.
- Optional<SmallVector<Register, 8>>
- findCandidatesForLoadOrCombine(const MachineInstr *Root) const;
-
- /// Helper function for matchLoadOrCombine.
- ///
- /// Checks if every register in \p RegsToVisit is defined by a load
- /// instruction + some arithmetic.
- ///
- /// \param [out] MemOffset2Idx - Maps the byte positions each load ends up
- /// at to the index of the load.
- /// \param [in] MemSizeInBits - The number of bits each load should produce.
- ///
- /// \returns The lowest-index load found and the lowest index on success.
- Optional<std::pair<MachineInstr *, int64_t>> findLoadOffsetsForLoadOrCombine(
- SmallDenseMap<int64_t, int64_t, 8> &MemOffset2Idx,
- const SmallVector<Register, 8> &RegsToVisit,
- const unsigned MemSizeInBits);
+
+ /// Helper function for matchLoadOrCombine. Searches for Registers
+ /// which may have been produced by a load instruction + some arithmetic.
+ ///
+ /// \param [in] Root - The search root.
+ ///
+ /// \returns The Registers found during the search.
+ Optional<SmallVector<Register, 8>>
+ findCandidatesForLoadOrCombine(const MachineInstr *Root) const;
+
+ /// Helper function for matchLoadOrCombine.
+ ///
+ /// Checks if every register in \p RegsToVisit is defined by a load
+ /// instruction + some arithmetic.
+ ///
+ /// \param [out] MemOffset2Idx - Maps the byte positions each load ends up
+ /// at to the index of the load.
+ /// \param [in] MemSizeInBits - The number of bits each load should produce.
+ ///
+ /// \returns The lowest-index load found and the lowest index on success.
+ Optional<std::pair<MachineInstr *, int64_t>> findLoadOffsetsForLoadOrCombine(
+ SmallDenseMap<int64_t, int64_t, 8> &MemOffset2Idx,
+ const SmallVector<Register, 8> &RegsToVisit,
+ const unsigned MemSizeInBits);
};
} // namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h
index 3f2f27e157..0833e960fe 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h
@@ -58,7 +58,7 @@ public:
/// For convenience, finishedChangingAllUsesOfReg() will report the completion
/// of the changes. The use list may change between this call and
/// finishedChangingAllUsesOfReg().
- void changingAllUsesOfReg(const MachineRegisterInfo &MRI, Register Reg);
+ void changingAllUsesOfReg(const MachineRegisterInfo &MRI, Register Reg);
/// All instructions reported as changing by changingAllUsesOfReg() have
/// finished being changed.
void finishedChangingAllUsesOfReg();
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/GISelKnownBits.h b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/GISelKnownBits.h
index 87b74ea403..452ddd17c0 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/GISelKnownBits.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/GISelKnownBits.h
@@ -20,7 +20,7 @@
#ifndef LLVM_CODEGEN_GLOBALISEL_KNOWNBITSINFO_H
#define LLVM_CODEGEN_GLOBALISEL_KNOWNBITSINFO_H
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/Register.h"
@@ -41,13 +41,13 @@ class GISelKnownBits : public GISelChangeObserver {
/// Cache maintained during a computeKnownBits request.
SmallDenseMap<Register, KnownBits, 16> ComputeKnownBitsCache;
- void computeKnownBitsMin(Register Src0, Register Src1, KnownBits &Known,
- const APInt &DemandedElts,
- unsigned Depth = 0);
-
- unsigned computeNumSignBitsMin(Register Src0, Register Src1,
- const APInt &DemandedElts, unsigned Depth = 0);
-
+ void computeKnownBitsMin(Register Src0, Register Src1, KnownBits &Known,
+ const APInt &DemandedElts,
+ unsigned Depth = 0);
+
+ unsigned computeNumSignBitsMin(Register Src0, Register Src1,
+ const APInt &DemandedElts, unsigned Depth = 0);
+
public:
GISelKnownBits(MachineFunction &MF, unsigned MaxDepth = 6);
virtual ~GISelKnownBits() = default;
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/IRTranslator.h
index ec913aa7b9..6c1ac8e115 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/IRTranslator.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/IRTranslator.h
@@ -27,14 +27,14 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/FunctionLoweringInfo.h"
+#include "llvm/CodeGen/FunctionLoweringInfo.h"
#include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/SwiftErrorValueTracking.h"
#include "llvm/CodeGen/SwitchLoweringUtils.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/CodeGen.h"
#include <memory>
#include <utility>
@@ -45,7 +45,7 @@ class BasicBlock;
class CallInst;
class CallLowering;
class Constant;
-class ConstrainedFPIntrinsic;
+class ConstrainedFPIntrinsic;
class DataLayout;
class Instruction;
class MachineBasicBlock;
@@ -226,14 +226,14 @@ private:
/// Translate an LLVM string intrinsic (memcpy, memset, ...).
bool translateMemFunc(const CallInst &CI, MachineIRBuilder &MIRBuilder,
- unsigned Opcode);
+ unsigned Opcode);
void getStackGuard(Register DstReg, MachineIRBuilder &MIRBuilder);
bool translateOverflowIntrinsic(const CallInst &CI, unsigned Op,
MachineIRBuilder &MIRBuilder);
- bool translateFixedPointIntrinsic(unsigned Op, const CallInst &CI,
- MachineIRBuilder &MIRBuilder);
+ bool translateFixedPointIntrinsic(unsigned Op, const CallInst &CI,
+ MachineIRBuilder &MIRBuilder);
/// Helper function for translateSimpleIntrinsic.
/// \return The generic opcode for \p IntrinsicID if \p IntrinsicID is a
@@ -267,19 +267,19 @@ private:
/// \pre \p U is a call instruction.
bool translateCall(const User &U, MachineIRBuilder &MIRBuilder);
- /// When an invoke or a cleanupret unwinds to the next EH pad, there are
- /// many places it could ultimately go. In the IR, we have a single unwind
- /// destination, but in the machine CFG, we enumerate all the possible blocks.
- /// This function skips over imaginary basic blocks that hold catchswitch
- /// instructions, and finds all the "real" machine
- /// basic block destinations. As those destinations may not be successors of
- /// EHPadBB, here we also calculate the edge probability to those
- /// destinations. The passed-in Prob is the edge probability to EHPadBB.
- bool findUnwindDestinations(
- const BasicBlock *EHPadBB, BranchProbability Prob,
- SmallVectorImpl<std::pair<MachineBasicBlock *, BranchProbability>>
- &UnwindDests);
-
+ /// When an invoke or a cleanupret unwinds to the next EH pad, there are
+ /// many places it could ultimately go. In the IR, we have a single unwind
+ /// destination, but in the machine CFG, we enumerate all the possible blocks.
+ /// This function skips over imaginary basic blocks that hold catchswitch
+ /// instructions, and finds all the "real" machine
+ /// basic block destinations. As those destinations may not be successors of
+ /// EHPadBB, here we also calculate the edge probability to those
+ /// destinations. The passed-in Prob is the edge probability to EHPadBB.
+ bool findUnwindDestinations(
+ const BasicBlock *EHPadBB, BranchProbability Prob,
+ SmallVectorImpl<std::pair<MachineBasicBlock *, BranchProbability>>
+ &UnwindDests);
+
bool translateInvoke(const User &U, MachineIRBuilder &MIRBuilder);
bool translateCallBr(const User &U, MachineIRBuilder &MIRBuilder);
@@ -311,37 +311,37 @@ private:
/// MachineBasicBlocks for the function have been created.
void finishPendingPhis();
- /// Translate \p Inst into a unary operation \p Opcode.
- /// \pre \p U is a unary operation.
- bool translateUnaryOp(unsigned Opcode, const User &U,
- MachineIRBuilder &MIRBuilder);
-
+ /// Translate \p Inst into a unary operation \p Opcode.
+ /// \pre \p U is a unary operation.
+ bool translateUnaryOp(unsigned Opcode, const User &U,
+ MachineIRBuilder &MIRBuilder);
+
/// Translate \p Inst into a binary operation \p Opcode.
/// \pre \p U is a binary operation.
bool translateBinaryOp(unsigned Opcode, const User &U,
MachineIRBuilder &MIRBuilder);
- /// If the set of cases should be emitted as a series of branches, return
- /// true. If we should emit this as a bunch of and/or'd together conditions,
- /// return false.
- bool shouldEmitAsBranches(const std::vector<SwitchCG::CaseBlock> &Cases);
- /// Helper method for findMergedConditions.
- /// This function emits a branch and is used at the leaves of an OR or an
- /// AND operator tree.
- void emitBranchForMergedCondition(const Value *Cond, MachineBasicBlock *TBB,
- MachineBasicBlock *FBB,
- MachineBasicBlock *CurBB,
- MachineBasicBlock *SwitchBB,
- BranchProbability TProb,
- BranchProbability FProb, bool InvertCond);
- /// Used during condbr translation to find trees of conditions that can be
- /// optimized.
- void findMergedConditions(const Value *Cond, MachineBasicBlock *TBB,
- MachineBasicBlock *FBB, MachineBasicBlock *CurBB,
- MachineBasicBlock *SwitchBB,
- Instruction::BinaryOps Opc, BranchProbability TProb,
- BranchProbability FProb, bool InvertCond);
-
+ /// If the set of cases should be emitted as a series of branches, return
+ /// true. If we should emit this as a bunch of and/or'd together conditions,
+ /// return false.
+ bool shouldEmitAsBranches(const std::vector<SwitchCG::CaseBlock> &Cases);
+ /// Helper method for findMergedConditions.
+ /// This function emits a branch and is used at the leaves of an OR or an
+ /// AND operator tree.
+ void emitBranchForMergedCondition(const Value *Cond, MachineBasicBlock *TBB,
+ MachineBasicBlock *FBB,
+ MachineBasicBlock *CurBB,
+ MachineBasicBlock *SwitchBB,
+ BranchProbability TProb,
+ BranchProbability FProb, bool InvertCond);
+ /// Used during condbr translation to find trees of conditions that can be
+ /// optimized.
+ void findMergedConditions(const Value *Cond, MachineBasicBlock *TBB,
+ MachineBasicBlock *FBB, MachineBasicBlock *CurBB,
+ MachineBasicBlock *SwitchBB,
+ Instruction::BinaryOps Opc, BranchProbability TProb,
+ BranchProbability FProb, bool InvertCond);
+
/// Translate branch (br) instruction.
/// \pre \p U is a branch instruction.
bool translateBr(const User &U, MachineIRBuilder &MIRBuilder);
@@ -355,23 +355,23 @@ private:
void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB,
MachineIRBuilder &MIB);
- /// Generate for for the BitTest header block, which precedes each sequence of
- /// BitTestCases.
- void emitBitTestHeader(SwitchCG::BitTestBlock &BTB,
- MachineBasicBlock *SwitchMBB);
- /// Generate code to produces one "bit test" for a given BitTestCase \p B.
- void emitBitTestCase(SwitchCG::BitTestBlock &BB, MachineBasicBlock *NextMBB,
- BranchProbability BranchProbToNext, Register Reg,
- SwitchCG::BitTestCase &B, MachineBasicBlock *SwitchBB);
-
- bool lowerJumpTableWorkItem(
- SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
- MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
- MachineIRBuilder &MIB, MachineFunction::iterator BBI,
- BranchProbability UnhandledProbs, SwitchCG::CaseClusterIt I,
- MachineBasicBlock *Fallthrough, bool FallthroughUnreachable);
-
- bool lowerSwitchRangeWorkItem(SwitchCG::CaseClusterIt I, Value *Cond,
+ /// Generate for for the BitTest header block, which precedes each sequence of
+ /// BitTestCases.
+ void emitBitTestHeader(SwitchCG::BitTestBlock &BTB,
+ MachineBasicBlock *SwitchMBB);
+ /// Generate code to produces one "bit test" for a given BitTestCase \p B.
+ void emitBitTestCase(SwitchCG::BitTestBlock &BB, MachineBasicBlock *NextMBB,
+ BranchProbability BranchProbToNext, Register Reg,
+ SwitchCG::BitTestCase &B, MachineBasicBlock *SwitchBB);
+
+ bool lowerJumpTableWorkItem(
+ SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
+ MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
+ MachineIRBuilder &MIB, MachineFunction::iterator BBI,
+ BranchProbability UnhandledProbs, SwitchCG::CaseClusterIt I,
+ MachineBasicBlock *Fallthrough, bool FallthroughUnreachable);
+
+ bool lowerSwitchRangeWorkItem(SwitchCG::CaseClusterIt I, Value *Cond,
MachineBasicBlock *Fallthrough,
bool FallthroughUnreachable,
BranchProbability UnhandledProbs,
@@ -379,14 +379,14 @@ private:
MachineIRBuilder &MIB,
MachineBasicBlock *SwitchMBB);
- bool lowerBitTestWorkItem(
- SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
- MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
- MachineIRBuilder &MIB, MachineFunction::iterator BBI,
- BranchProbability DefaultProb, BranchProbability UnhandledProbs,
- SwitchCG::CaseClusterIt I, MachineBasicBlock *Fallthrough,
- bool FallthroughUnreachable);
-
+ bool lowerBitTestWorkItem(
+ SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
+ MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
+ MachineIRBuilder &MIB, MachineFunction::iterator BBI,
+ BranchProbability DefaultProb, BranchProbability UnhandledProbs,
+ SwitchCG::CaseClusterIt I, MachineBasicBlock *Fallthrough,
+ bool FallthroughUnreachable);
+
bool lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W, Value *Cond,
MachineBasicBlock *SwitchMBB,
MachineBasicBlock *DefaultMBB,
@@ -497,9 +497,9 @@ private:
bool translateFAdd(const User &U, MachineIRBuilder &MIRBuilder) {
return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
}
- bool translateFSub(const User &U, MachineIRBuilder &MIRBuilder) {
- return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
- }
+ bool translateFSub(const User &U, MachineIRBuilder &MIRBuilder) {
+ return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
+ }
bool translateFMul(const User &U, MachineIRBuilder &MIRBuilder) {
return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
}
@@ -578,8 +578,8 @@ private:
/// Current target configuration. Controls how the pass handles errors.
const TargetPassConfig *TPC;
- CodeGenOpt::Level OptLevel;
-
+ CodeGenOpt::Level OptLevel;
+
/// Current optimization remark emitter. Used to report failures.
std::unique_ptr<OptimizationRemarkEmitter> ORE;
@@ -679,12 +679,12 @@ private:
BranchProbability getEdgeProbability(const MachineBasicBlock *Src,
const MachineBasicBlock *Dst) const;
- void addSuccessorWithProb(
- MachineBasicBlock *Src, MachineBasicBlock *Dst,
- BranchProbability Prob = BranchProbability::getUnknown());
+ void addSuccessorWithProb(
+ MachineBasicBlock *Src, MachineBasicBlock *Dst,
+ BranchProbability Prob = BranchProbability::getUnknown());
public:
- IRTranslator(CodeGenOpt::Level OptLevel = CodeGenOpt::None);
+ IRTranslator(CodeGenOpt::Level OptLevel = CodeGenOpt::None);
StringRef getPassName() const override { return "IRTranslator"; }
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
index d61e273ce1..61123ff85f 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
@@ -119,14 +119,14 @@ enum {
/// - InsnID - Instruction ID
/// - Expected opcode
GIM_CheckOpcode,
-
- /// Check the opcode on the specified instruction, checking 2 acceptable
- /// alternatives.
- /// - InsnID - Instruction ID
- /// - Expected opcode
- /// - Alternative expected opcode
- GIM_CheckOpcodeIsEither,
-
+
+ /// Check the opcode on the specified instruction, checking 2 acceptable
+ /// alternatives.
+ /// - InsnID - Instruction ID
+ /// - Expected opcode
+ /// - Alternative expected opcode
+ GIM_CheckOpcodeIsEither,
+
/// Check the instruction has the right number of operands
/// - InsnID - Instruction ID
/// - Expected number of operands
@@ -179,15 +179,15 @@ enum {
GIM_CheckMemorySizeEqualToLLT,
GIM_CheckMemorySizeLessThanLLT,
GIM_CheckMemorySizeGreaterThanLLT,
-
- /// Check if this is a vector that can be treated as a vector splat
- /// constant. This is valid for both G_BUILD_VECTOR as well as
- /// G_BUILD_VECTOR_TRUNC. For AllOnes refers to individual bits, so a -1
- /// element.
- /// - InsnID - Instruction ID
- GIM_CheckIsBuildVectorAllOnes,
- GIM_CheckIsBuildVectorAllZeros,
-
+
+ /// Check if this is a vector that can be treated as a vector splat
+ /// constant. This is valid for both G_BUILD_VECTOR as well as
+ /// G_BUILD_VECTOR_TRUNC. For AllOnes refers to individual bits, so a -1
+ /// element.
+ /// - InsnID - Instruction ID
+ GIM_CheckIsBuildVectorAllOnes,
+ GIM_CheckIsBuildVectorAllZeros,
+
/// Check a generic C++ instruction predicate
/// - InsnID - Instruction ID
/// - PredicateID - The ID of the predicate function to call
@@ -261,15 +261,15 @@ enum {
/// - OtherOpIdx - Other operand index
GIM_CheckIsSameOperand,
- /// Predicates with 'let PredicateCodeUsesOperands = 1' need to examine some
- /// named operands that will be recorded in RecordedOperands. Names of these
- /// operands are referenced in predicate argument list. Emitter determines
- /// StoreIdx(corresponds to the order in which names appear in argument list).
- /// - InsnID - Instruction ID
- /// - OpIdx - Operand index
- /// - StoreIdx - Store location in RecordedOperands.
- GIM_RecordNamedOperand,
-
+ /// Predicates with 'let PredicateCodeUsesOperands = 1' need to examine some
+ /// named operands that will be recorded in RecordedOperands. Names of these
+ /// operands are referenced in predicate argument list. Emitter determines
+ /// StoreIdx(corresponds to the order in which names appear in argument list).
+ /// - InsnID - Instruction ID
+ /// - OpIdx - Operand index
+ /// - StoreIdx - Store location in RecordedOperands.
+ GIM_RecordNamedOperand,
+
/// Fail the current try-block, or completely fail to match if there is no
/// current try-block.
GIM_Reject,
@@ -462,11 +462,11 @@ protected:
std::vector<ComplexRendererFns::value_type> Renderers;
RecordedMIVector MIs;
DenseMap<unsigned, unsigned> TempRegisters;
- /// Named operands that predicate with 'let PredicateCodeUsesOperands = 1'
- /// referenced in its argument list. Operands are inserted at index set by
- /// emitter, it corresponds to the order in which names appear in argument
- /// list. Currently such predicates don't have more then 3 arguments.
- std::array<const MachineOperand *, 3> RecordedOperands;
+ /// Named operands that predicate with 'let PredicateCodeUsesOperands = 1'
+ /// referenced in its argument list. Operands are inserted at index set by
+ /// emitter, it corresponds to the order in which names appear in argument
+ /// list. Currently such predicates don't have more then 3 arguments.
+ std::array<const MachineOperand *, 3> RecordedOperands;
MatcherState(unsigned MaxRenderers);
};
@@ -527,9 +527,9 @@ protected:
llvm_unreachable(
"Subclasses must override this with a tablegen-erated function");
}
- virtual bool testMIPredicate_MI(
- unsigned, const MachineInstr &,
- const std::array<const MachineOperand *, 3> &Operands) const {
+ virtual bool testMIPredicate_MI(
+ unsigned, const MachineInstr &,
+ const std::array<const MachineOperand *, 3> &Operands) const {
llvm_unreachable(
"Subclasses must override this with a tablegen-erated function");
}
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
index b5885ff663..e3202fc976 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
@@ -161,26 +161,26 @@ bool InstructionSelector::executeMatchTable(
break;
}
- case GIM_CheckOpcode:
- case GIM_CheckOpcodeIsEither: {
+ case GIM_CheckOpcode:
+ case GIM_CheckOpcodeIsEither: {
int64_t InsnID = MatchTable[CurrentIdx++];
- int64_t Expected0 = MatchTable[CurrentIdx++];
- int64_t Expected1 = -1;
- if (MatcherOpcode == GIM_CheckOpcodeIsEither)
- Expected1 = MatchTable[CurrentIdx++];
+ int64_t Expected0 = MatchTable[CurrentIdx++];
+ int64_t Expected1 = -1;
+ if (MatcherOpcode == GIM_CheckOpcodeIsEither)
+ Expected1 = 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=" << Expected0;
- if (MatcherOpcode == GIM_CheckOpcodeIsEither)
- dbgs() << " || " << Expected1;
- dbgs() << ") // Got=" << Opcode << "\n";
- );
-
- if (Opcode != Expected0 && Opcode != Expected1) {
+ dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID
+ << "], ExpectedOpcode=" << Expected0;
+ if (MatcherOpcode == GIM_CheckOpcodeIsEither)
+ dbgs() << " || " << Expected1;
+ dbgs() << ") // Got=" << Opcode << "\n";
+ );
+
+ if (Opcode != Expected0 && Opcode != Expected1) {
if (handleReject() == RejectAndGiveUp)
return false;
}
@@ -207,7 +207,7 @@ bool InstructionSelector::executeMatchTable(
CurrentIdx = MatchTable[CurrentIdx + (Opcode - LowerBound)];
if (!CurrentIdx) {
CurrentIdx = Default;
- break;
+ break;
}
OnFailResumeAt.push_back(Default);
break;
@@ -335,35 +335,35 @@ bool InstructionSelector::executeMatchTable(
return false;
break;
}
- case GIM_CheckIsBuildVectorAllOnes:
- case GIM_CheckIsBuildVectorAllZeros: {
- int64_t InsnID = MatchTable[CurrentIdx++];
-
- DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
- dbgs() << CurrentIdx
- << ": GIM_CheckBuildVectorAll{Zeros|Ones}(MIs["
- << InsnID << "])\n");
- assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
-
- const MachineInstr *MI = State.MIs[InsnID];
- assert((MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR ||
- MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC) &&
- "Expected G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC");
-
- if (MatcherOpcode == GIM_CheckIsBuildVectorAllOnes) {
- if (!isBuildVectorAllOnes(*MI, MRI)) {
- if (handleReject() == RejectAndGiveUp)
- return false;
- }
- } else {
- if (!isBuildVectorAllZeros(*MI, MRI)) {
- if (handleReject() == RejectAndGiveUp)
- return false;
- }
- }
-
- break;
- }
+ case GIM_CheckIsBuildVectorAllOnes:
+ case GIM_CheckIsBuildVectorAllZeros: {
+ int64_t InsnID = MatchTable[CurrentIdx++];
+
+ DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
+ dbgs() << CurrentIdx
+ << ": GIM_CheckBuildVectorAll{Zeros|Ones}(MIs["
+ << InsnID << "])\n");
+ assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+
+ const MachineInstr *MI = State.MIs[InsnID];
+ assert((MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR ||
+ MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC) &&
+ "Expected G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC");
+
+ if (MatcherOpcode == GIM_CheckIsBuildVectorAllOnes) {
+ if (!isBuildVectorAllOnes(*MI, MRI)) {
+ if (handleReject() == RejectAndGiveUp)
+ return false;
+ }
+ } else {
+ if (!isBuildVectorAllZeros(*MI, MRI)) {
+ if (handleReject() == RejectAndGiveUp)
+ return false;
+ }
+ }
+
+ break;
+ }
case GIM_CheckCxxInsnPredicate: {
int64_t InsnID = MatchTable[CurrentIdx++];
int64_t Predicate = MatchTable[CurrentIdx++];
@@ -374,8 +374,8 @@ bool InstructionSelector::executeMatchTable(
assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
assert(Predicate > GIPFP_MI_Invalid && "Expected a valid predicate");
- if (!testMIPredicate_MI(Predicate, *State.MIs[InsnID],
- State.RecordedOperands))
+ if (!testMIPredicate_MI(Predicate, *State.MIs[InsnID],
+ State.RecordedOperands))
if (handleReject() == RejectAndGiveUp)
return false;
break;
@@ -625,20 +625,20 @@ bool InstructionSelector::executeMatchTable(
break;
}
- case GIM_RecordNamedOperand: {
- int64_t InsnID = MatchTable[CurrentIdx++];
- int64_t OpIdx = MatchTable[CurrentIdx++];
- uint64_t StoreIdx = MatchTable[CurrentIdx++];
-
- DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
- dbgs() << CurrentIdx << ": GIM_RecordNamedOperand(MIs["
- << InsnID << "]->getOperand(" << OpIdx
- << "), StoreIdx=" << StoreIdx << ")\n");
- assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
- assert(StoreIdx < State.RecordedOperands.size() && "Index out of range");
- State.RecordedOperands[StoreIdx] = &State.MIs[InsnID]->getOperand(OpIdx);
- break;
- }
+ case GIM_RecordNamedOperand: {
+ int64_t InsnID = MatchTable[CurrentIdx++];
+ int64_t OpIdx = MatchTable[CurrentIdx++];
+ uint64_t StoreIdx = MatchTable[CurrentIdx++];
+
+ DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
+ dbgs() << CurrentIdx << ": GIM_RecordNamedOperand(MIs["
+ << InsnID << "]->getOperand(" << OpIdx
+ << "), StoreIdx=" << StoreIdx << ")\n");
+ assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+ assert(StoreIdx < State.RecordedOperands.size() && "Index out of range");
+ State.RecordedOperands[StoreIdx] = &State.MIs[InsnID]->getOperand(OpIdx);
+ break;
+ }
case GIM_CheckRegBankForClass: {
int64_t InsnID = MatchTable[CurrentIdx++];
int64_t OpIdx = MatchTable[CurrentIdx++];
@@ -1065,12 +1065,12 @@ bool InstructionSelector::executeMatchTable(
int64_t OpIdx = MatchTable[CurrentIdx++];
int64_t RCEnum = MatchTable[CurrentIdx++];
assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
- MachineInstr &I = *OutMIs[InsnID].getInstr();
- MachineFunction &MF = *I.getParent()->getParent();
- MachineRegisterInfo &MRI = MF.getRegInfo();
- const TargetRegisterClass &RC = *TRI.getRegClass(RCEnum);
- MachineOperand &MO = I.getOperand(OpIdx);
- constrainOperandRegClass(MF, TRI, MRI, TII, RBI, I, RC, MO);
+ MachineInstr &I = *OutMIs[InsnID].getInstr();
+ MachineFunction &MF = *I.getParent()->getParent();
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ const TargetRegisterClass &RC = *TRI.getRegClass(RCEnum);
+ MachineOperand &MO = I.getOperand(OpIdx);
+ constrainOperandRegClass(MF, TRI, MRI, TII, RBI, I, RC, MO);
DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
dbgs() << CurrentIdx << ": GIR_ConstrainOperandRC(OutMIs["
<< InsnID << "], " << OpIdx << ", " << RCEnum
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
index 0d476efb2c..9bed6d039e 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
@@ -112,23 +112,23 @@ public:
Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
// zext(trunc x) - > and (aext/copy/trunc x), mask
- // zext(sext x) -> and (sext x), mask
+ // zext(sext x) -> and (sext x), mask
Register TruncSrc;
- Register SextSrc;
- if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc))) ||
- mi_match(SrcReg, MRI, m_GSExt(m_Reg(SextSrc)))) {
+ Register SextSrc;
+ if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc))) ||
+ mi_match(SrcReg, MRI, m_GSExt(m_Reg(SextSrc)))) {
LLT DstTy = MRI.getType(DstReg);
if (isInstUnsupported({TargetOpcode::G_AND, {DstTy}}) ||
isConstantUnsupported(DstTy))
return false;
LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;);
LLT SrcTy = MRI.getType(SrcReg);
- APInt MaskVal = APInt::getAllOnesValue(SrcTy.getScalarSizeInBits());
- auto Mask = Builder.buildConstant(
- DstTy, MaskVal.zext(DstTy.getScalarSizeInBits()));
- auto Extended = SextSrc ? Builder.buildSExtOrTrunc(DstTy, SextSrc) :
- Builder.buildAnyExtOrTrunc(DstTy, TruncSrc);
- Builder.buildAnd(DstReg, Extended, Mask);
+ APInt MaskVal = APInt::getAllOnesValue(SrcTy.getScalarSizeInBits());
+ auto Mask = Builder.buildConstant(
+ DstTy, MaskVal.zext(DstTy.getScalarSizeInBits()));
+ auto Extended = SextSrc ? Builder.buildSExtOrTrunc(DstTy, SextSrc) :
+ Builder.buildAnyExtOrTrunc(DstTy, TruncSrc);
+ Builder.buildAnd(DstReg, Extended, Mask);
markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts);
return true;
}
@@ -493,7 +493,7 @@ public:
MachineRegisterInfo &MRI,
MachineIRBuilder &Builder,
SmallVectorImpl<Register> &UpdatedDefs,
- GISelChangeObserver &Observer) {
+ GISelChangeObserver &Observer) {
if (!llvm::canReplaceReg(DstReg, SrcReg, MRI)) {
Builder.buildCopy(DstReg, SrcReg);
UpdatedDefs.push_back(DstReg);
@@ -513,78 +513,78 @@ public:
Observer.changedInstr(*UseMI);
}
- /// Return the operand index in \p MI that defines \p Def
- static unsigned getDefIndex(const MachineInstr &MI, Register SearchDef) {
- unsigned DefIdx = 0;
- for (const MachineOperand &Def : MI.defs()) {
- if (Def.getReg() == SearchDef)
- break;
- ++DefIdx;
- }
-
- return DefIdx;
- }
-
- bool tryCombineUnmergeValues(MachineInstr &MI,
- SmallVectorImpl<MachineInstr *> &DeadInsts,
- SmallVectorImpl<Register> &UpdatedDefs,
- GISelChangeObserver &Observer) {
+ /// Return the operand index in \p MI that defines \p Def
+ static unsigned getDefIndex(const MachineInstr &MI, Register SearchDef) {
+ unsigned DefIdx = 0;
+ for (const MachineOperand &Def : MI.defs()) {
+ if (Def.getReg() == SearchDef)
+ break;
+ ++DefIdx;
+ }
+
+ return DefIdx;
+ }
+
+ bool tryCombineUnmergeValues(MachineInstr &MI,
+ SmallVectorImpl<MachineInstr *> &DeadInsts,
+ SmallVectorImpl<Register> &UpdatedDefs,
+ GISelChangeObserver &Observer) {
assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
unsigned NumDefs = MI.getNumOperands() - 1;
- Register SrcReg = MI.getOperand(NumDefs).getReg();
- MachineInstr *SrcDef = getDefIgnoringCopies(SrcReg, MRI);
+ Register SrcReg = MI.getOperand(NumDefs).getReg();
+ MachineInstr *SrcDef = getDefIgnoringCopies(SrcReg, MRI);
if (!SrcDef)
return false;
LLT OpTy = MRI.getType(MI.getOperand(NumDefs).getReg());
LLT DestTy = MRI.getType(MI.getOperand(0).getReg());
-
- if (SrcDef->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) {
- // %0:_(<4 x s16>) = G_FOO
- // %1:_(<2 x s16>), %2:_(<2 x s16>) = G_UNMERGE_VALUES %0
- // %3:_(s16), %4:_(s16) = G_UNMERGE_VALUES %1
- //
- // %3:_(s16), %4:_(s16), %5:_(s16), %6:_(s16) = G_UNMERGE_VALUES %0
- const unsigned NumSrcOps = SrcDef->getNumOperands();
- Register SrcUnmergeSrc = SrcDef->getOperand(NumSrcOps - 1).getReg();
- LLT SrcUnmergeSrcTy = MRI.getType(SrcUnmergeSrc);
-
- // If we need to decrease the number of vector elements in the result type
- // of an unmerge, this would involve the creation of an equivalent unmerge
- // to copy back to the original result registers.
- LegalizeActionStep ActionStep = LI.getAction(
- {TargetOpcode::G_UNMERGE_VALUES, {OpTy, SrcUnmergeSrcTy}});
- switch (ActionStep.Action) {
- case LegalizeActions::Lower:
- case LegalizeActions::Unsupported:
- break;
- case LegalizeActions::FewerElements:
- case LegalizeActions::NarrowScalar:
- if (ActionStep.TypeIdx == 1)
- return false;
- break;
- default:
- return false;
- }
-
- Builder.setInstrAndDebugLoc(MI);
- auto NewUnmerge = Builder.buildUnmerge(DestTy, SrcUnmergeSrc);
-
- // TODO: Should we try to process out the other defs now? If the other
- // defs of the source unmerge are also unmerged, we end up with a separate
- // unmerge for each one.
- unsigned SrcDefIdx = getDefIndex(*SrcDef, SrcReg);
- for (unsigned I = 0; I != NumDefs; ++I) {
- Register Def = MI.getOperand(I).getReg();
- replaceRegOrBuildCopy(Def, NewUnmerge.getReg(SrcDefIdx * NumDefs + I),
- MRI, Builder, UpdatedDefs, Observer);
- }
-
- markInstAndDefDead(MI, *SrcDef, DeadInsts, SrcDefIdx);
- return true;
- }
-
+
+ if (SrcDef->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) {
+ // %0:_(<4 x s16>) = G_FOO
+ // %1:_(<2 x s16>), %2:_(<2 x s16>) = G_UNMERGE_VALUES %0
+ // %3:_(s16), %4:_(s16) = G_UNMERGE_VALUES %1
+ //
+ // %3:_(s16), %4:_(s16), %5:_(s16), %6:_(s16) = G_UNMERGE_VALUES %0
+ const unsigned NumSrcOps = SrcDef->getNumOperands();
+ Register SrcUnmergeSrc = SrcDef->getOperand(NumSrcOps - 1).getReg();
+ LLT SrcUnmergeSrcTy = MRI.getType(SrcUnmergeSrc);
+
+ // If we need to decrease the number of vector elements in the result type
+ // of an unmerge, this would involve the creation of an equivalent unmerge
+ // to copy back to the original result registers.
+ LegalizeActionStep ActionStep = LI.getAction(
+ {TargetOpcode::G_UNMERGE_VALUES, {OpTy, SrcUnmergeSrcTy}});
+ switch (ActionStep.Action) {
+ case LegalizeActions::Lower:
+ case LegalizeActions::Unsupported:
+ break;
+ case LegalizeActions::FewerElements:
+ case LegalizeActions::NarrowScalar:
+ if (ActionStep.TypeIdx == 1)
+ return false;
+ break;
+ default:
+ return false;
+ }
+
+ Builder.setInstrAndDebugLoc(MI);
+ auto NewUnmerge = Builder.buildUnmerge(DestTy, SrcUnmergeSrc);
+
+ // TODO: Should we try to process out the other defs now? If the other
+ // defs of the source unmerge are also unmerged, we end up with a separate
+ // unmerge for each one.
+ unsigned SrcDefIdx = getDefIndex(*SrcDef, SrcReg);
+ for (unsigned I = 0; I != NumDefs; ++I) {
+ Register Def = MI.getOperand(I).getReg();
+ replaceRegOrBuildCopy(Def, NewUnmerge.getReg(SrcDefIdx * NumDefs + I),
+ MRI, Builder, UpdatedDefs, Observer);
+ }
+
+ markInstAndDefDead(MI, *SrcDef, DeadInsts, SrcDefIdx);
+ return true;
+ }
+
MachineInstr *MergeI = SrcDef;
unsigned ConvertOp = 0;
@@ -812,12 +812,12 @@ public:
Changed = tryCombineSExt(MI, DeadInsts, UpdatedDefs);
break;
case TargetOpcode::G_UNMERGE_VALUES:
- Changed =
- tryCombineUnmergeValues(MI, DeadInsts, UpdatedDefs, WrapperObserver);
+ Changed =
+ tryCombineUnmergeValues(MI, DeadInsts, UpdatedDefs, WrapperObserver);
break;
case TargetOpcode::G_MERGE_VALUES:
- case TargetOpcode::G_BUILD_VECTOR:
- case TargetOpcode::G_CONCAT_VECTORS:
+ case TargetOpcode::G_BUILD_VECTOR:
+ case TargetOpcode::G_CONCAT_VECTORS:
// If any of the users of this merge are an unmerge, then add them to the
// artifact worklist in case there's folding that can be done looking up.
for (MachineInstr &U : MRI.use_instructions(MI.getOperand(0).getReg())) {
@@ -901,8 +901,8 @@ private:
/// dead.
/// MI is not marked dead.
void markDefDead(MachineInstr &MI, MachineInstr &DefMI,
- SmallVectorImpl<MachineInstr *> &DeadInsts,
- unsigned DefIdx = 0) {
+ SmallVectorImpl<MachineInstr *> &DeadInsts,
+ unsigned DefIdx = 0) {
// Collect all the copy instructions that are made dead, due to deleting
// this instruction. Collect all of them until the Trunc(DefMI).
// Eg,
@@ -929,27 +929,27 @@ private:
break;
PrevMI = TmpDef;
}
-
- if (PrevMI == &DefMI) {
- unsigned I = 0;
- bool IsDead = true;
- for (MachineOperand &Def : DefMI.defs()) {
- if (I != DefIdx) {
- if (!MRI.use_empty(Def.getReg())) {
- IsDead = false;
- break;
- }
- } else {
- if (!MRI.hasOneUse(DefMI.getOperand(DefIdx).getReg()))
- break;
- }
-
- ++I;
- }
-
- if (IsDead)
- DeadInsts.push_back(&DefMI);
- }
+
+ if (PrevMI == &DefMI) {
+ unsigned I = 0;
+ bool IsDead = true;
+ for (MachineOperand &Def : DefMI.defs()) {
+ if (I != DefIdx) {
+ if (!MRI.use_empty(Def.getReg())) {
+ IsDead = false;
+ break;
+ }
+ } else {
+ if (!MRI.hasOneUse(DefMI.getOperand(DefIdx).getReg()))
+ break;
+ }
+
+ ++I;
+ }
+
+ if (IsDead)
+ DeadInsts.push_back(&DefMI);
+ }
}
/// Mark MI as dead. If a def of one of MI's operands, DefMI, would also be
@@ -958,10 +958,10 @@ private:
/// copies in between the extends and the truncs, and this attempts to collect
/// the in between copies if they're dead.
void markInstAndDefDead(MachineInstr &MI, MachineInstr &DefMI,
- SmallVectorImpl<MachineInstr *> &DeadInsts,
- unsigned DefIdx = 0) {
+ SmallVectorImpl<MachineInstr *> &DeadInsts,
+ unsigned DefIdx = 0) {
DeadInsts.push_back(&MI);
- markDefDead(MI, DefMI, DeadInsts, DefIdx);
+ markDefDead(MI, DefMI, DeadInsts, DefIdx);
}
/// Erase the dead instructions in the list and call the observer hooks.
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index 050df84035..bf45c5e673 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -39,7 +39,7 @@ class LegalizerInfo;
class Legalizer;
class MachineRegisterInfo;
class GISelChangeObserver;
-class TargetLowering;
+class TargetLowering;
class LegalizerHelper {
public:
@@ -53,7 +53,7 @@ public:
private:
MachineRegisterInfo &MRI;
const LegalizerInfo &LI;
- const TargetLowering &TLI;
+ const TargetLowering &TLI;
public:
enum LegalizeResult {
@@ -71,7 +71,7 @@ public:
/// Expose LegalizerInfo so the clients can re-use.
const LegalizerInfo &getLegalizerInfo() const { return LI; }
- const TargetLowering &getTargetLowering() const { return TLI; }
+ const TargetLowering &getTargetLowering() const { return TLI; }
LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer,
MachineIRBuilder &B);
@@ -164,10 +164,10 @@ public:
/// def by inserting a G_BITCAST from \p CastTy
void bitcastDst(MachineInstr &MI, LLT CastTy, unsigned OpIdx);
- /// Widen \p OrigReg to \p WideTy by merging to a wider type, padding with
- /// G_IMPLICIT_DEF, and producing dead results.
- Register widenWithUnmerge(LLT WideTy, Register OrigReg);
-
+ /// Widen \p OrigReg to \p WideTy by merging to a wider type, padding with
+ /// G_IMPLICIT_DEF, and producing dead results.
+ Register widenWithUnmerge(LLT WideTy, Register OrigReg);
+
private:
LegalizeResult
widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
@@ -177,10 +177,10 @@ private:
widenScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
LegalizeResult
widenScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
- LegalizeResult widenScalarAddoSubo(MachineInstr &MI, unsigned TypeIdx,
- LLT WideTy);
- LegalizeResult widenScalarAddSubShlSat(MachineInstr &MI, unsigned TypeIdx,
- LLT WideTy);
+ LegalizeResult widenScalarAddoSubo(MachineInstr &MI, unsigned TypeIdx,
+ LLT WideTy);
+ LegalizeResult widenScalarAddSubShlSat(MachineInstr &MI, unsigned TypeIdx,
+ LLT WideTy);
/// Helper function to split a wide generic register into bitwise blocks with
/// the given Type (which implies the number of blocks needed). The generic
@@ -207,19 +207,19 @@ private:
LLT PartTy, ArrayRef<Register> PartRegs,
LLT LeftoverTy = LLT(), ArrayRef<Register> LeftoverRegs = {});
- /// Unmerge \p SrcReg into smaller sized values, and append them to \p
- /// Parts. The elements of \p Parts will be the greatest common divisor type
- /// of \p DstTy, \p NarrowTy and the type of \p SrcReg. This will compute and
- /// return the GCD type.
+ /// Unmerge \p SrcReg into smaller sized values, and append them to \p
+ /// Parts. The elements of \p Parts will be the greatest common divisor type
+ /// of \p DstTy, \p NarrowTy and the type of \p SrcReg. This will compute and
+ /// return the GCD type.
LLT extractGCDType(SmallVectorImpl<Register> &Parts, LLT DstTy,
LLT NarrowTy, Register SrcReg);
- /// Unmerge \p SrcReg into \p GCDTy typed registers. This will append all of
- /// the unpacked registers to \p Parts. This version is if the common unmerge
- /// type is already known.
- void extractGCDType(SmallVectorImpl<Register> &Parts, LLT GCDTy,
- Register SrcReg);
-
+ /// Unmerge \p SrcReg into \p GCDTy typed registers. This will append all of
+ /// the unpacked registers to \p Parts. This version is if the common unmerge
+ /// type is already known.
+ void extractGCDType(SmallVectorImpl<Register> &Parts, LLT GCDTy,
+ Register SrcReg);
+
/// Produce a merge of values in \p VRegs to define \p DstReg. Perform a merge
/// from the least common multiple type, and convert as appropriate to \p
/// DstReg.
@@ -252,23 +252,23 @@ private:
ArrayRef<Register> Src1Regs,
ArrayRef<Register> Src2Regs, LLT NarrowTy);
- void changeOpcode(MachineInstr &MI, unsigned NewOpcode);
-
+ void changeOpcode(MachineInstr &MI, unsigned NewOpcode);
+
public:
- /// Return the alignment to use for a stack temporary object with the given
- /// type.
- Align getStackTemporaryAlignment(LLT Type, Align MinAlign = Align()) const;
-
- /// Create a stack temporary based on the size in bytes and the alignment
- MachineInstrBuilder createStackTemporary(TypeSize Bytes, Align Alignment,
- MachinePointerInfo &PtrInfo);
-
- /// Get a pointer to vector element \p Index located in memory for a vector of
- /// type \p VecTy starting at a base address of \p VecPtr. If \p Index is out
- /// of bounds the returned pointer is unspecified, but will be within the
- /// vector bounds.
- Register getVectorElementPointer(Register VecPtr, LLT VecTy, Register Index);
-
+ /// Return the alignment to use for a stack temporary object with the given
+ /// type.
+ Align getStackTemporaryAlignment(LLT Type, Align MinAlign = Align()) const;
+
+ /// Create a stack temporary based on the size in bytes and the alignment
+ MachineInstrBuilder createStackTemporary(TypeSize Bytes, Align Alignment,
+ MachinePointerInfo &PtrInfo);
+
+ /// Get a pointer to vector element \p Index located in memory for a vector of
+ /// type \p VecTy starting at a base address of \p VecPtr. If \p Index is out
+ /// of bounds the returned pointer is unspecified, but will be within the
+ /// vector bounds.
+ Register getVectorElementPointer(Register VecPtr, LLT VecTy, Register Index);
+
LegalizeResult fewerElementsVectorImplicitDef(MachineInstr &MI,
unsigned TypeIdx, LLT NarrowTy);
@@ -296,11 +296,11 @@ public:
LegalizeResult fewerElementsVectorUnmergeValues(MachineInstr &MI,
unsigned TypeIdx,
LLT NarrowTy);
- LegalizeResult fewerElementsVectorMerge(MachineInstr &MI, unsigned TypeIdx,
- LLT NarrowTy);
- LegalizeResult fewerElementsVectorExtractInsertVectorElt(MachineInstr &MI,
- unsigned TypeIdx,
- LLT NarrowTy);
+ LegalizeResult fewerElementsVectorMerge(MachineInstr &MI, unsigned TypeIdx,
+ LLT NarrowTy);
+ LegalizeResult fewerElementsVectorExtractInsertVectorElt(MachineInstr &MI,
+ unsigned TypeIdx,
+ LLT NarrowTy);
LegalizeResult
reduceLoadStoreWidth(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
@@ -323,7 +323,7 @@ public:
LegalizeResult narrowScalarShift(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
LegalizeResult narrowScalarMul(MachineInstr &MI, LLT Ty);
- LegalizeResult narrowScalarFPTOI(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+ LegalizeResult narrowScalarFPTOI(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
LegalizeResult narrowScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
LegalizeResult narrowScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
@@ -334,52 +334,52 @@ public:
LegalizeResult narrowScalarCTTZ(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
LegalizeResult narrowScalarCTPOP(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
- /// Perform Bitcast legalize action on G_EXTRACT_VECTOR_ELT.
- LegalizeResult bitcastExtractVectorElt(MachineInstr &MI, unsigned TypeIdx,
- LLT CastTy);
-
- /// Perform Bitcast legalize action on G_INSERT_VECTOR_ELT.
- LegalizeResult bitcastInsertVectorElt(MachineInstr &MI, unsigned TypeIdx,
- LLT CastTy);
-
+ /// Perform Bitcast legalize action on G_EXTRACT_VECTOR_ELT.
+ LegalizeResult bitcastExtractVectorElt(MachineInstr &MI, unsigned TypeIdx,
+ LLT CastTy);
+
+ /// Perform Bitcast legalize action on G_INSERT_VECTOR_ELT.
+ LegalizeResult bitcastInsertVectorElt(MachineInstr &MI, unsigned TypeIdx,
+ LLT CastTy);
+
LegalizeResult lowerBitcast(MachineInstr &MI);
- LegalizeResult lowerLoad(MachineInstr &MI);
- LegalizeResult lowerStore(MachineInstr &MI);
- LegalizeResult lowerBitCount(MachineInstr &MI);
+ LegalizeResult lowerLoad(MachineInstr &MI);
+ LegalizeResult lowerStore(MachineInstr &MI);
+ LegalizeResult lowerBitCount(MachineInstr &MI);
LegalizeResult lowerU64ToF32BitOps(MachineInstr &MI);
- LegalizeResult lowerUITOFP(MachineInstr &MI);
- LegalizeResult lowerSITOFP(MachineInstr &MI);
- LegalizeResult lowerFPTOUI(MachineInstr &MI);
+ LegalizeResult lowerUITOFP(MachineInstr &MI);
+ LegalizeResult lowerSITOFP(MachineInstr &MI);
+ LegalizeResult lowerFPTOUI(MachineInstr &MI);
LegalizeResult lowerFPTOSI(MachineInstr &MI);
LegalizeResult lowerFPTRUNC_F64_TO_F16(MachineInstr &MI);
- LegalizeResult lowerFPTRUNC(MachineInstr &MI);
- LegalizeResult lowerFPOWI(MachineInstr &MI);
+ LegalizeResult lowerFPTRUNC(MachineInstr &MI);
+ LegalizeResult lowerFPOWI(MachineInstr &MI);
- LegalizeResult lowerMinMax(MachineInstr &MI);
- LegalizeResult lowerFCopySign(MachineInstr &MI);
+ LegalizeResult lowerMinMax(MachineInstr &MI);
+ LegalizeResult lowerFCopySign(MachineInstr &MI);
LegalizeResult lowerFMinNumMaxNum(MachineInstr &MI);
LegalizeResult lowerFMad(MachineInstr &MI);
LegalizeResult lowerIntrinsicRound(MachineInstr &MI);
LegalizeResult lowerFFloor(MachineInstr &MI);
LegalizeResult lowerMergeValues(MachineInstr &MI);
LegalizeResult lowerUnmergeValues(MachineInstr &MI);
- LegalizeResult lowerExtractInsertVectorElt(MachineInstr &MI);
+ LegalizeResult lowerExtractInsertVectorElt(MachineInstr &MI);
LegalizeResult lowerShuffleVector(MachineInstr &MI);
LegalizeResult lowerDynStackAlloc(MachineInstr &MI);
LegalizeResult lowerExtract(MachineInstr &MI);
LegalizeResult lowerInsert(MachineInstr &MI);
LegalizeResult lowerSADDO_SSUBO(MachineInstr &MI);
- LegalizeResult lowerAddSubSatToMinMax(MachineInstr &MI);
- LegalizeResult lowerAddSubSatToAddoSubo(MachineInstr &MI);
- LegalizeResult lowerShlSat(MachineInstr &MI);
+ LegalizeResult lowerAddSubSatToMinMax(MachineInstr &MI);
+ LegalizeResult lowerAddSubSatToAddoSubo(MachineInstr &MI);
+ LegalizeResult lowerShlSat(MachineInstr &MI);
LegalizeResult lowerBswap(MachineInstr &MI);
LegalizeResult lowerBitreverse(MachineInstr &MI);
LegalizeResult lowerReadWriteRegister(MachineInstr &MI);
- LegalizeResult lowerSMULH_UMULH(MachineInstr &MI);
- LegalizeResult lowerSelect(MachineInstr &MI);
-
+ LegalizeResult lowerSMULH_UMULH(MachineInstr &MI);
+ LegalizeResult lowerSelect(MachineInstr &MI);
+
};
/// Helper function that creates a libcall to the given \p Name using the given
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
index ff313f43c0..0ae41c1a8d 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
@@ -189,7 +189,7 @@ struct TypePairAndMemDesc {
MemSize == Other.MemSize;
}
- /// \returns true if this memory access is legal with for the access described
+ /// \returns true if this memory access is legal with for the access described
/// by \p Other (The alignment is sufficient for the size and result type).
bool isCompatible(const TypePairAndMemDesc &Other) const {
return Type0 == Other.Type0 && Type1 == Other.Type1 &&
@@ -224,19 +224,19 @@ Predicate any(Predicate P0, Predicate P1, Args... args) {
return any(any(P0, P1), args...);
}
-/// True iff the given type index is the specified type.
+/// True iff the given type index is the specified type.
LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit);
/// True iff the given type index is one of the specified types.
LegalityPredicate typeInSet(unsigned TypeIdx,
std::initializer_list<LLT> TypesInit);
-
-/// True iff the given type index is not the specified type.
-inline LegalityPredicate typeIsNot(unsigned TypeIdx, LLT Type) {
- return [=](const LegalityQuery &Query) {
- return Query.Types[TypeIdx] != Type;
- };
-}
-
+
+/// True iff the given type index is not the specified type.
+inline LegalityPredicate typeIsNot(unsigned TypeIdx, LLT Type) {
+ return [=](const LegalityQuery &Query) {
+ return Query.Types[TypeIdx] != Type;
+ };
+}
+
/// True iff the given types for the given pair of type indexes is one of the
/// specified type pairs.
LegalityPredicate
@@ -322,11 +322,11 @@ LegalizeMutation changeElementTo(unsigned TypeIdx, unsigned FromTypeIdx);
/// Keep the same scalar or element type as the given type.
LegalizeMutation changeElementTo(unsigned TypeIdx, LLT Ty);
-/// Change the scalar size or element size to have the same scalar size as type
-/// index \p FromIndex. Unlike changeElementTo, this discards pointer types and
-/// only changes the size.
-LegalizeMutation changeElementSizeTo(unsigned TypeIdx, unsigned FromTypeIdx);
-
+/// Change the scalar size or element size to have the same scalar size as type
+/// index \p FromIndex. Unlike changeElementTo, this discards pointer types and
+/// only changes the size.
+LegalizeMutation changeElementSizeTo(unsigned TypeIdx, unsigned FromTypeIdx);
+
/// Widen the scalar type or vector element type for the given type index to the
/// next power of 2.
LegalizeMutation widenScalarOrEltToNextPow2(unsigned TypeIdx, unsigned Min = 0);
@@ -635,7 +635,7 @@ public:
/// 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<LLT> Types) {
- return actionFor(LegalizeAction::Lower, Types);
+ return actionFor(LegalizeAction::Lower, Types);
}
/// The instruction is lowered when type index 0 is any type in the given
/// list.
@@ -646,7 +646,7 @@ public:
/// 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<std::pair<LLT, LLT>> Types) {
- return actionFor(LegalizeAction::Lower, Types);
+ return actionFor(LegalizeAction::Lower, Types);
}
/// The instruction is lowered when type indexes 0 and 1 is any type pair in
/// the given list.
@@ -671,15 +671,15 @@ public:
Types2);
}
- /// The instruction is emitted as a library call.
- LegalizeRuleSet &libcall() {
- using namespace LegalizeMutations;
- // We have no choice but conservatively assume that predicate-less lowering
- // properly handles all type indices by design:
- markAllIdxsAsCovered();
- return actionIf(LegalizeAction::Libcall, always);
- }
-
+ /// The instruction is emitted as a library call.
+ LegalizeRuleSet &libcall() {
+ using namespace LegalizeMutations;
+ // We have no choice but conservatively assume that predicate-less lowering
+ // properly handles all type indices by design:
+ markAllIdxsAsCovered();
+ return actionIf(LegalizeAction::Libcall, always);
+ }
+
/// Like legalIf, but for the Libcall action.
LegalizeRuleSet &libcallIf(LegalityPredicate Predicate) {
// We have no choice but conservatively assume that a libcall with a
@@ -722,13 +722,13 @@ public:
markAllIdxsAsCovered();
return actionIf(LegalizeAction::NarrowScalar, Predicate, Mutation);
}
- /// Narrow the scalar, specified in mutation, when type indexes 0 and 1 is any
- /// type pair in the given list.
- LegalizeRuleSet &
- narrowScalarFor(std::initializer_list<std::pair<LLT, LLT>> Types,
- LegalizeMutation Mutation) {
- return actionFor(LegalizeAction::NarrowScalar, Types, Mutation);
- }
+ /// Narrow the scalar, specified in mutation, when type indexes 0 and 1 is any
+ /// type pair in the given list.
+ LegalizeRuleSet &
+ narrowScalarFor(std::initializer_list<std::pair<LLT, LLT>> Types,
+ LegalizeMutation Mutation) {
+ return actionFor(LegalizeAction::NarrowScalar, Types, Mutation);
+ }
/// Add more elements to reach the type selected by the mutation if the
/// predicate is true.
@@ -833,13 +833,13 @@ public:
LegalizeMutations::scalarize(TypeIdx));
}
- LegalizeRuleSet &scalarizeIf(LegalityPredicate Predicate, unsigned TypeIdx) {
- using namespace LegalityPredicates;
- return actionIf(LegalizeAction::FewerElements,
- all(Predicate, isVector(typeIdx(TypeIdx))),
- LegalizeMutations::scalarize(TypeIdx));
- }
-
+ LegalizeRuleSet &scalarizeIf(LegalityPredicate Predicate, unsigned TypeIdx) {
+ using namespace LegalityPredicates;
+ return actionIf(LegalizeAction::FewerElements,
+ all(Predicate, isVector(typeIdx(TypeIdx))),
+ LegalizeMutations::scalarize(TypeIdx));
+ }
+
/// Ensure the scalar or element is at least as wide as Ty.
LegalizeRuleSet &minScalarOrElt(unsigned TypeIdx, const LLT Ty) {
using namespace LegalityPredicates;
@@ -897,10 +897,10 @@ public:
return actionIf(
LegalizeAction::NarrowScalar,
[=](const LegalityQuery &Query) {
- const LLT QueryTy = Query.Types[TypeIdx];
- return QueryTy.isScalar() &&
- QueryTy.getSizeInBits() > Ty.getSizeInBits() &&
- Predicate(Query);
+ const LLT QueryTy = Query.Types[TypeIdx];
+ return QueryTy.isScalar() &&
+ QueryTy.getSizeInBits() > Ty.getSizeInBits() &&
+ Predicate(Query);
},
changeElementTo(typeIdx(TypeIdx), Ty));
}
@@ -926,27 +926,27 @@ public:
return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
Query.Types[TypeIdx].getSizeInBits();
},
- LegalizeMutations::changeElementSizeTo(TypeIdx, LargeTypeIdx));
- }
-
- /// Narrow the scalar to match the size of another.
- LegalizeRuleSet &maxScalarSameAs(unsigned TypeIdx, unsigned NarrowTypeIdx) {
- typeIdx(TypeIdx);
- return narrowScalarIf(
+ LegalizeMutations::changeElementSizeTo(TypeIdx, LargeTypeIdx));
+ }
+
+ /// Narrow the scalar to match the size of another.
+ LegalizeRuleSet &maxScalarSameAs(unsigned TypeIdx, unsigned NarrowTypeIdx) {
+ typeIdx(TypeIdx);
+ return narrowScalarIf(
[=](const LegalityQuery &Query) {
- return Query.Types[NarrowTypeIdx].getScalarSizeInBits() <
- Query.Types[TypeIdx].getSizeInBits();
- },
- LegalizeMutations::changeElementSizeTo(TypeIdx, NarrowTypeIdx));
- }
-
- /// Change the type \p TypeIdx to have the same scalar size as type \p
- /// SameSizeIdx.
- LegalizeRuleSet &scalarSameSizeAs(unsigned TypeIdx, unsigned SameSizeIdx) {
- return minScalarSameAs(TypeIdx, SameSizeIdx)
- .maxScalarSameAs(TypeIdx, SameSizeIdx);
- }
-
+ return Query.Types[NarrowTypeIdx].getScalarSizeInBits() <
+ Query.Types[TypeIdx].getSizeInBits();
+ },
+ LegalizeMutations::changeElementSizeTo(TypeIdx, NarrowTypeIdx));
+ }
+
+ /// Change the type \p TypeIdx to have the same scalar size as type \p
+ /// SameSizeIdx.
+ LegalizeRuleSet &scalarSameSizeAs(unsigned TypeIdx, unsigned SameSizeIdx) {
+ return minScalarSameAs(TypeIdx, SameSizeIdx)
+ .maxScalarSameAs(TypeIdx, SameSizeIdx);
+ }
+
/// Conditionally widen the scalar or elt to match the size of another.
LegalizeRuleSet &minScalarEltSameAsIf(LegalityPredicate Predicate,
unsigned TypeIdx, unsigned LargeTypeIdx) {
@@ -1264,12 +1264,12 @@ public:
bool isLegal(const LegalityQuery &Query) const {
return getAction(Query).Action == LegalizeAction::Legal;
}
-
- bool isLegalOrCustom(const LegalityQuery &Query) const {
- auto Action = getAction(Query).Action;
- return Action == LegalizeAction::Legal || Action == LegalizeAction::Custom;
- }
-
+
+ bool isLegalOrCustom(const LegalityQuery &Query) const {
+ auto Action = getAction(Query).Action;
+ return Action == LegalizeAction::Legal || Action == LegalizeAction::Custom;
+ }
+
bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;
bool isLegalOrCustom(const MachineInstr &MI,
const MachineRegisterInfo &MRI) const;
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/Localizer.h b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/Localizer.h
index 65f63dc8bc..d1716931e6 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/Localizer.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/Localizer.h
@@ -71,11 +71,11 @@ private:
typedef SmallSetVector<MachineInstr *, 32> LocalizedSetVecT;
- /// If \p Op is a phi operand and not unique in that phi, that is,
- /// there are other operands in the phi with the same register,
- /// return true.
- bool isNonUniquePhiValue(MachineOperand &Op) const;
-
+ /// If \p Op is a phi operand and not unique in that phi, that is,
+ /// there are other operands in the phi with the same register,
+ /// return true.
+ bool isNonUniquePhiValue(MachineOperand &Op) const;
+
/// Do inter-block localization from the entry block.
bool localizeInterBlock(MachineFunction &MF,
LocalizedSetVecT &LocalizedInstrs);
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
index 13085d3d44..223f61ccc5 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
@@ -46,25 +46,25 @@ inline OneUse_match<SubPat> m_OneUse(const SubPat &SP) {
return SP;
}
-template <typename SubPatternT> struct OneNonDBGUse_match {
- SubPatternT SubPat;
- OneNonDBGUse_match(const SubPatternT &SP) : SubPat(SP) {}
-
- bool match(const MachineRegisterInfo &MRI, Register Reg) {
- return MRI.hasOneNonDBGUse(Reg) && SubPat.match(MRI, Reg);
- }
-};
-
-template <typename SubPat>
-inline OneNonDBGUse_match<SubPat> m_OneNonDBGUse(const SubPat &SP) {
- return SP;
-}
-
+template <typename SubPatternT> struct OneNonDBGUse_match {
+ SubPatternT SubPat;
+ OneNonDBGUse_match(const SubPatternT &SP) : SubPat(SP) {}
+
+ bool match(const MachineRegisterInfo &MRI, Register Reg) {
+ return MRI.hasOneNonDBGUse(Reg) && SubPat.match(MRI, Reg);
+ }
+};
+
+template <typename SubPat>
+inline OneNonDBGUse_match<SubPat> m_OneNonDBGUse(const SubPat &SP) {
+ return SP;
+}
+
struct ConstantMatch {
int64_t &CR;
ConstantMatch(int64_t &C) : CR(C) {}
bool match(const MachineRegisterInfo &MRI, Register Reg) {
- if (auto MaybeCst = getConstantVRegSExtVal(Reg, MRI)) {
+ if (auto MaybeCst = getConstantVRegSExtVal(Reg, MRI)) {
CR = *MaybeCst;
return true;
}
@@ -74,29 +74,29 @@ struct ConstantMatch {
inline ConstantMatch m_ICst(int64_t &Cst) { return ConstantMatch(Cst); }
-/// Matcher for a specific constant value.
-struct SpecificConstantMatch {
- int64_t RequestedVal;
- SpecificConstantMatch(int64_t RequestedVal) : RequestedVal(RequestedVal) {}
- bool match(const MachineRegisterInfo &MRI, Register Reg) {
- int64_t MatchedVal;
- return mi_match(Reg, MRI, m_ICst(MatchedVal)) && MatchedVal == RequestedVal;
- }
-};
-
-/// Matches a constant equal to \p RequestedValue.
-inline SpecificConstantMatch m_SpecificICst(int64_t RequestedValue) {
- return SpecificConstantMatch(RequestedValue);
-}
-
-///{
-/// Convenience matchers for specific integer values.
-inline SpecificConstantMatch m_ZeroInt() { return SpecificConstantMatch(0); }
-inline SpecificConstantMatch m_AllOnesInt() {
- return SpecificConstantMatch(-1);
-}
-///}
-
+/// Matcher for a specific constant value.
+struct SpecificConstantMatch {
+ int64_t RequestedVal;
+ SpecificConstantMatch(int64_t RequestedVal) : RequestedVal(RequestedVal) {}
+ bool match(const MachineRegisterInfo &MRI, Register Reg) {
+ int64_t MatchedVal;
+ return mi_match(Reg, MRI, m_ICst(MatchedVal)) && MatchedVal == RequestedVal;
+ }
+};
+
+/// Matches a constant equal to \p RequestedValue.
+inline SpecificConstantMatch m_SpecificICst(int64_t RequestedValue) {
+ return SpecificConstantMatch(RequestedValue);
+}
+
+///{
+/// Convenience matchers for specific integer values.
+inline SpecificConstantMatch m_ZeroInt() { return SpecificConstantMatch(0); }
+inline SpecificConstantMatch m_AllOnesInt() {
+ return SpecificConstantMatch(-1);
+}
+///}
+
// TODO: Rework this for different kinds of MachineOperand.
// Currently assumes the Src for a match is a register.
// We might want to support taking in some MachineOperands and call getReg on
@@ -242,12 +242,12 @@ m_GAdd(const LHS &L, const RHS &R) {
}
template <typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, TargetOpcode::G_PTR_ADD, true>
-m_GPtrAdd(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, TargetOpcode::G_PTR_ADD, true>(L, R);
-}
-
-template <typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, TargetOpcode::G_PTR_ADD, true>
+m_GPtrAdd(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, TargetOpcode::G_PTR_ADD, true>(L, R);
+}
+
+template <typename LHS, typename RHS>
inline BinaryOp_match<LHS, RHS, TargetOpcode::G_SUB> m_GSub(const LHS &L,
const RHS &R) {
return BinaryOp_match<LHS, RHS, TargetOpcode::G_SUB>(L, R);
@@ -284,12 +284,12 @@ m_GAnd(const LHS &L, const RHS &R) {
}
template <typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, TargetOpcode::G_XOR, true>
-m_GXor(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, TargetOpcode::G_XOR, true>(L, R);
-}
-
-template <typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, TargetOpcode::G_XOR, true>
+m_GXor(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, TargetOpcode::G_XOR, true>(L, R);
+}
+
+template <typename LHS, typename RHS>
inline BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true> m_GOr(const LHS &L,
const RHS &R) {
return BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true>(L, R);
@@ -307,12 +307,12 @@ m_GLShr(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, TargetOpcode::G_LSHR, false>(L, R);
}
-template <typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, TargetOpcode::G_ASHR, false>
-m_GAShr(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, TargetOpcode::G_ASHR, false>(L, R);
-}
-
+template <typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, TargetOpcode::G_ASHR, false>
+m_GAShr(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, TargetOpcode::G_ASHR, false>(L, R);
+}
+
// Helper for unary instructions (G_[ZSA]EXT/G_TRUNC) etc
template <typename SrcTy, unsigned Opcode> struct UnaryOp_match {
SrcTy L;
@@ -446,51 +446,51 @@ struct CheckType {
inline CheckType m_SpecificType(LLT Ty) { return Ty; }
-template <typename Src0Ty, typename Src1Ty, typename Src2Ty, unsigned Opcode>
-struct TernaryOp_match {
- Src0Ty Src0;
- Src1Ty Src1;
- Src2Ty Src2;
-
- TernaryOp_match(const Src0Ty &Src0, const Src1Ty &Src1, const Src2Ty &Src2)
- : Src0(Src0), Src1(Src1), Src2(Src2) {}
- template <typename OpTy>
- bool match(const MachineRegisterInfo &MRI, OpTy &&Op) {
- MachineInstr *TmpMI;
- if (mi_match(Op, MRI, m_MInstr(TmpMI))) {
- if (TmpMI->getOpcode() == Opcode && TmpMI->getNumOperands() == 4) {
- return (Src0.match(MRI, TmpMI->getOperand(1).getReg()) &&
- Src1.match(MRI, TmpMI->getOperand(2).getReg()) &&
- Src2.match(MRI, TmpMI->getOperand(3).getReg()));
- }
- }
- return false;
- }
-};
-template <typename Src0Ty, typename Src1Ty, typename Src2Ty>
-inline TernaryOp_match<Src0Ty, Src1Ty, Src2Ty,
- TargetOpcode::G_INSERT_VECTOR_ELT>
-m_GInsertVecElt(const Src0Ty &Src0, const Src1Ty &Src1, const Src2Ty &Src2) {
- return TernaryOp_match<Src0Ty, Src1Ty, Src2Ty,
- TargetOpcode::G_INSERT_VECTOR_ELT>(Src0, Src1, Src2);
-}
-
-/// Matches a register negated by a G_SUB.
-/// G_SUB 0, %negated_reg
-template <typename SrcTy>
-inline BinaryOp_match<SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB>
-m_Neg(const SrcTy &&Src) {
- return m_GSub(m_ZeroInt(), Src);
-}
-
-/// Matches a register not-ed by a G_XOR.
-/// G_XOR %not_reg, -1
-template <typename SrcTy>
-inline BinaryOp_match<SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true>
-m_Not(const SrcTy &&Src) {
- return m_GXor(Src, m_AllOnesInt());
-}
-
+template <typename Src0Ty, typename Src1Ty, typename Src2Ty, unsigned Opcode>
+struct TernaryOp_match {
+ Src0Ty Src0;
+ Src1Ty Src1;
+ Src2Ty Src2;
+
+ TernaryOp_match(const Src0Ty &Src0, const Src1Ty &Src1, const Src2Ty &Src2)
+ : Src0(Src0), Src1(Src1), Src2(Src2) {}
+ template <typename OpTy>
+ bool match(const MachineRegisterInfo &MRI, OpTy &&Op) {
+ MachineInstr *TmpMI;
+ if (mi_match(Op, MRI, m_MInstr(TmpMI))) {
+ if (TmpMI->getOpcode() == Opcode && TmpMI->getNumOperands() == 4) {
+ return (Src0.match(MRI, TmpMI->getOperand(1).getReg()) &&
+ Src1.match(MRI, TmpMI->getOperand(2).getReg()) &&
+ Src2.match(MRI, TmpMI->getOperand(3).getReg()));
+ }
+ }
+ return false;
+ }
+};
+template <typename Src0Ty, typename Src1Ty, typename Src2Ty>
+inline TernaryOp_match<Src0Ty, Src1Ty, Src2Ty,
+ TargetOpcode::G_INSERT_VECTOR_ELT>
+m_GInsertVecElt(const Src0Ty &Src0, const Src1Ty &Src1, const Src2Ty &Src2) {
+ return TernaryOp_match<Src0Ty, Src1Ty, Src2Ty,
+ TargetOpcode::G_INSERT_VECTOR_ELT>(Src0, Src1, Src2);
+}
+
+/// Matches a register negated by a G_SUB.
+/// G_SUB 0, %negated_reg
+template <typename SrcTy>
+inline BinaryOp_match<SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB>
+m_Neg(const SrcTy &&Src) {
+ return m_GSub(m_ZeroInt(), Src);
+}
+
+/// Matches a register not-ed by a G_XOR.
+/// G_XOR %not_reg, -1
+template <typename SrcTy>
+inline BinaryOp_match<SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true>
+m_Not(const SrcTy &&Src) {
+ return m_GXor(Src, m_AllOnesInt());
+}
+
} // namespace GMIPatternMatch
} // namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index 324d80e16c..6e3f7cdc26 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -25,10 +25,10 @@
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/TargetOpcodes.h"
+#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugLoc.h"
-#include "llvm/IR/Module.h"
+#include "llvm/IR/Module.h"
namespace llvm {
@@ -231,7 +231,7 @@ class MachineIRBuilder {
protected:
void validateTruncExt(const LLT Dst, const LLT Src, bool IsExtend);
- void validateUnaryOp(const LLT Res, const LLT Op0);
+ void validateUnaryOp(const LLT Res, const LLT Op0);
void validateBinaryOp(const LLT Res, const LLT Op0, const LLT Op1);
void validateShiftOp(const LLT Res, const LLT Op0, const LLT Op1);
@@ -259,11 +259,11 @@ public:
setDebugLoc(MI.getDebugLoc());
}
- MachineIRBuilder(MachineInstr &MI, GISelChangeObserver &Observer) :
- MachineIRBuilder(MI) {
- setChangeObserver(Observer);
- }
-
+ MachineIRBuilder(MachineInstr &MI, GISelChangeObserver &Observer) :
+ MachineIRBuilder(MI) {
+ setChangeObserver(Observer);
+ }
+
virtual ~MachineIRBuilder() = default;
MachineIRBuilder(const MachineIRBuilderState &BState) : State(BState) {}
@@ -743,7 +743,7 @@ public:
/// depend on bit 0 (for now).
///
/// \return The newly created instruction.
- MachineInstrBuilder buildBrCond(const SrcOp &Tst, MachineBasicBlock &Dest);
+ MachineInstrBuilder buildBrCond(const SrcOp &Tst, MachineBasicBlock &Dest);
/// Build and insert G_BRINDIRECT \p Tgt
///
@@ -827,18 +827,18 @@ public:
///
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildLoad(const DstOp &Res, const SrcOp &Addr,
- MachineMemOperand &MMO) {
- return buildLoadInstr(TargetOpcode::G_LOAD, Res, Addr, MMO);
- }
-
- /// Build and insert a G_LOAD instruction, while constructing the
- /// MachineMemOperand.
- MachineInstrBuilder
- buildLoad(const DstOp &Res, const SrcOp &Addr, MachinePointerInfo PtrInfo,
- Align Alignment,
- MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
- const AAMDNodes &AAInfo = AAMDNodes());
-
+ MachineMemOperand &MMO) {
+ return buildLoadInstr(TargetOpcode::G_LOAD, Res, Addr, MMO);
+ }
+
+ /// Build and insert a G_LOAD instruction, while constructing the
+ /// MachineMemOperand.
+ MachineInstrBuilder
+ buildLoad(const DstOp &Res, const SrcOp &Addr, MachinePointerInfo PtrInfo,
+ Align Alignment,
+ MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
+ const AAMDNodes &AAInfo = AAMDNodes());
+
/// Build and insert `Res = <opcode> Addr, MMO`.
///
/// Loads the value stored at \p Addr. Puts the result in \p Res.
@@ -871,14 +871,14 @@ public:
MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr,
MachineMemOperand &MMO);
- /// Build and insert a G_STORE instruction, while constructing the
- /// MachineMemOperand.
- MachineInstrBuilder
- buildStore(const SrcOp &Val, const SrcOp &Addr, MachinePointerInfo PtrInfo,
- Align Alignment,
- MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
- const AAMDNodes &AAInfo = AAMDNodes());
-
+ /// Build and insert a G_STORE instruction, while constructing the
+ /// MachineMemOperand.
+ MachineInstrBuilder
+ buildStore(const SrcOp &Val, const SrcOp &Addr, MachinePointerInfo PtrInfo,
+ Align Alignment,
+ MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
+ const AAMDNodes &AAInfo = AAMDNodes());
+
/// Build and insert `Res0, ... = G_EXTRACT Src, Idx0`.
///
/// \pre setBasicBlock or setMI must have been called.
@@ -970,23 +970,23 @@ public:
MachineInstrBuilder buildBuildVectorTrunc(const DstOp &Res,
ArrayRef<Register> Ops);
- /// Build and insert a vector splat of a scalar \p Src using a
- /// G_INSERT_VECTOR_ELT and G_SHUFFLE_VECTOR idiom.
- ///
- /// \pre setBasicBlock or setMI must have been called.
- /// \pre \p Src must have the same type as the element type of \p Dst
- ///
- /// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildShuffleSplat(const DstOp &Res, const SrcOp &Src);
-
- /// Build and insert \p Res = G_SHUFFLE_VECTOR \p Src1, \p Src2, \p Mask
- ///
- /// \pre setBasicBlock or setMI must have been called.
- ///
- /// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildShuffleVector(const DstOp &Res, const SrcOp &Src1,
- const SrcOp &Src2, ArrayRef<int> Mask);
-
+ /// Build and insert a vector splat of a scalar \p Src using a
+ /// G_INSERT_VECTOR_ELT and G_SHUFFLE_VECTOR idiom.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ /// \pre \p Src must have the same type as the element type of \p Dst
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildShuffleSplat(const DstOp &Res, const SrcOp &Src);
+
+ /// Build and insert \p Res = G_SHUFFLE_VECTOR \p Src1, \p Src2, \p Mask
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildShuffleVector(const DstOp &Res, const SrcOp &Src1,
+ const SrcOp &Src2, ArrayRef<int> Mask);
+
/// Build and insert \p Res = G_CONCAT_VECTORS \p Op0, ...
///
/// G_CONCAT_VECTORS creates a vector from the concatenation of 2 or more
@@ -1570,13 +1570,13 @@ public:
return buildInstr(TargetOpcode::G_FSUB, {Dst}, {Src0, Src1}, Flags);
}
- /// Build and insert \p Res = G_FDIV \p Op0, \p Op1
- MachineInstrBuilder buildFDiv(const DstOp &Dst, const SrcOp &Src0,
- const SrcOp &Src1,
- Optional<unsigned> Flags = None) {
- return buildInstr(TargetOpcode::G_FDIV, {Dst}, {Src0, Src1}, Flags);
- }
-
+ /// Build and insert \p Res = G_FDIV \p Op0, \p Op1
+ MachineInstrBuilder buildFDiv(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_FDIV, {Dst}, {Src0, Src1}, Flags);
+ }
+
/// Build and insert \p Res = G_FMA \p Op0, \p Op1, \p Op2
MachineInstrBuilder buildFMA(const DstOp &Dst, const SrcOp &Src0,
const SrcOp &Src1, const SrcOp &Src2,
@@ -1639,13 +1639,13 @@ public:
return buildInstr(TargetOpcode::G_FEXP2, {Dst}, {Src}, Flags);
}
- /// Build and insert \p Dst = G_FPOW \p Src0, \p Src1
- MachineInstrBuilder buildFPow(const DstOp &Dst, const SrcOp &Src0,
- const SrcOp &Src1,
- Optional<unsigned> Flags = None) {
- return buildInstr(TargetOpcode::G_FPOW, {Dst}, {Src0, Src1}, Flags);
- }
-
+ /// Build and insert \p Dst = G_FPOW \p Src0, \p Src1
+ MachineInstrBuilder buildFPow(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_FPOW, {Dst}, {Src0, Src1}, Flags);
+ }
+
/// Build and insert \p Res = G_FCOPYSIGN \p Op0, \p Op1
MachineInstrBuilder buildFCopysign(const DstOp &Dst, const SrcOp &Src0,
const SrcOp &Src1) {
@@ -1696,11 +1696,11 @@ public:
return buildInstr(TargetOpcode::G_UMAX, {Dst}, {Src0, Src1});
}
- /// Build and insert \p Dst = G_ABS \p Src
- MachineInstrBuilder buildAbs(const DstOp &Dst, const SrcOp &Src) {
- return buildInstr(TargetOpcode::G_ABS, {Dst}, {Src});
- }
-
+ /// Build and insert \p Dst = G_ABS \p Src
+ MachineInstrBuilder buildAbs(const DstOp &Dst, const SrcOp &Src) {
+ return buildInstr(TargetOpcode::G_ABS, {Dst}, {Src});
+ }
+
/// Build and insert \p Res = G_JUMP_TABLE \p JTI
///
/// G_JUMP_TABLE sets \p Res to the address of the jump table specified by
@@ -1709,101 +1709,101 @@ public:
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildJumpTable(const LLT PtrTy, unsigned JTI);
- /// Build and insert \p Res = G_VECREDUCE_SEQ_FADD \p ScalarIn, \p VecIn
- ///
- /// \p ScalarIn is the scalar accumulator input to start the sequential
- /// reduction operation of \p VecIn.
- MachineInstrBuilder buildVecReduceSeqFAdd(const DstOp &Dst,
- const SrcOp &ScalarIn,
- const SrcOp &VecIn) {
- return buildInstr(TargetOpcode::G_VECREDUCE_SEQ_FADD, {Dst},
- {ScalarIn, {VecIn}});
- }
-
- /// Build and insert \p Res = G_VECREDUCE_SEQ_FMUL \p ScalarIn, \p VecIn
- ///
- /// \p ScalarIn is the scalar accumulator input to start the sequential
- /// reduction operation of \p VecIn.
- MachineInstrBuilder buildVecReduceSeqFMul(const DstOp &Dst,
- const SrcOp &ScalarIn,
- const SrcOp &VecIn) {
- return buildInstr(TargetOpcode::G_VECREDUCE_SEQ_FMUL, {Dst},
- {ScalarIn, {VecIn}});
- }
-
- /// Build and insert \p Res = G_VECREDUCE_FADD \p Src
- ///
- /// \p ScalarIn is the scalar accumulator input to the reduction operation of
- /// \p VecIn.
- MachineInstrBuilder buildVecReduceFAdd(const DstOp &Dst,
- const SrcOp &ScalarIn,
- const SrcOp &VecIn) {
- return buildInstr(TargetOpcode::G_VECREDUCE_FADD, {Dst}, {ScalarIn, VecIn});
- }
-
- /// Build and insert \p Res = G_VECREDUCE_FMUL \p Src
- ///
- /// \p ScalarIn is the scalar accumulator input to the reduction operation of
- /// \p VecIn.
- MachineInstrBuilder buildVecReduceFMul(const DstOp &Dst,
- const SrcOp &ScalarIn,
- const SrcOp &VecIn) {
- return buildInstr(TargetOpcode::G_VECREDUCE_FMUL, {Dst}, {ScalarIn, VecIn});
- }
-
- /// Build and insert \p Res = G_VECREDUCE_FMAX \p Src
- MachineInstrBuilder buildVecReduceFMax(const DstOp &Dst, const SrcOp &Src) {
- return buildInstr(TargetOpcode::G_VECREDUCE_FMAX, {Dst}, {Src});
- }
-
- /// Build and insert \p Res = G_VECREDUCE_FMIN \p Src
- MachineInstrBuilder buildVecReduceFMin(const DstOp &Dst, const SrcOp &Src) {
- return buildInstr(TargetOpcode::G_VECREDUCE_FMIN, {Dst}, {Src});
- }
- /// Build and insert \p Res = G_VECREDUCE_ADD \p Src
- MachineInstrBuilder buildVecReduceAdd(const DstOp &Dst, const SrcOp &Src) {
- return buildInstr(TargetOpcode::G_VECREDUCE_ADD, {Dst}, {Src});
- }
-
- /// Build and insert \p Res = G_VECREDUCE_MUL \p Src
- MachineInstrBuilder buildVecReduceMul(const DstOp &Dst, const SrcOp &Src) {
- return buildInstr(TargetOpcode::G_VECREDUCE_MUL, {Dst}, {Src});
- }
-
- /// Build and insert \p Res = G_VECREDUCE_AND \p Src
- MachineInstrBuilder buildVecReduceAnd(const DstOp &Dst, const SrcOp &Src) {
- return buildInstr(TargetOpcode::G_VECREDUCE_AND, {Dst}, {Src});
- }
-
- /// Build and insert \p Res = G_VECREDUCE_OR \p Src
- MachineInstrBuilder buildVecReduceOr(const DstOp &Dst, const SrcOp &Src) {
- return buildInstr(TargetOpcode::G_VECREDUCE_OR, {Dst}, {Src});
- }
-
- /// Build and insert \p Res = G_VECREDUCE_XOR \p Src
- MachineInstrBuilder buildVecReduceXor(const DstOp &Dst, const SrcOp &Src) {
- return buildInstr(TargetOpcode::G_VECREDUCE_XOR, {Dst}, {Src});
- }
-
- /// Build and insert \p Res = G_VECREDUCE_SMAX \p Src
- MachineInstrBuilder buildVecReduceSMax(const DstOp &Dst, const SrcOp &Src) {
- return buildInstr(TargetOpcode::G_VECREDUCE_SMAX, {Dst}, {Src});
- }
-
- /// Build and insert \p Res = G_VECREDUCE_SMIN \p Src
- MachineInstrBuilder buildVecReduceSMin(const DstOp &Dst, const SrcOp &Src) {
- return buildInstr(TargetOpcode::G_VECREDUCE_SMIN, {Dst}, {Src});
- }
-
- /// Build and insert \p Res = G_VECREDUCE_UMAX \p Src
- MachineInstrBuilder buildVecReduceUMax(const DstOp &Dst, const SrcOp &Src) {
- return buildInstr(TargetOpcode::G_VECREDUCE_UMAX, {Dst}, {Src});
- }
-
- /// Build and insert \p Res = G_VECREDUCE_UMIN \p Src
- MachineInstrBuilder buildVecReduceUMin(const DstOp &Dst, const SrcOp &Src) {
- return buildInstr(TargetOpcode::G_VECREDUCE_UMIN, {Dst}, {Src});
- }
+ /// Build and insert \p Res = G_VECREDUCE_SEQ_FADD \p ScalarIn, \p VecIn
+ ///
+ /// \p ScalarIn is the scalar accumulator input to start the sequential
+ /// reduction operation of \p VecIn.
+ MachineInstrBuilder buildVecReduceSeqFAdd(const DstOp &Dst,
+ const SrcOp &ScalarIn,
+ const SrcOp &VecIn) {
+ return buildInstr(TargetOpcode::G_VECREDUCE_SEQ_FADD, {Dst},
+ {ScalarIn, {VecIn}});
+ }
+
+ /// Build and insert \p Res = G_VECREDUCE_SEQ_FMUL \p ScalarIn, \p VecIn
+ ///
+ /// \p ScalarIn is the scalar accumulator input to start the sequential
+ /// reduction operation of \p VecIn.
+ MachineInstrBuilder buildVecReduceSeqFMul(const DstOp &Dst,
+ const SrcOp &ScalarIn,
+ const SrcOp &VecIn) {
+ return buildInstr(TargetOpcode::G_VECREDUCE_SEQ_FMUL, {Dst},
+ {ScalarIn, {VecIn}});
+ }
+
+ /// Build and insert \p Res = G_VECREDUCE_FADD \p Src
+ ///
+ /// \p ScalarIn is the scalar accumulator input to the reduction operation of
+ /// \p VecIn.
+ MachineInstrBuilder buildVecReduceFAdd(const DstOp &Dst,
+ const SrcOp &ScalarIn,
+ const SrcOp &VecIn) {
+ return buildInstr(TargetOpcode::G_VECREDUCE_FADD, {Dst}, {ScalarIn, VecIn});
+ }
+
+ /// Build and insert \p Res = G_VECREDUCE_FMUL \p Src
+ ///
+ /// \p ScalarIn is the scalar accumulator input to the reduction operation of
+ /// \p VecIn.
+ MachineInstrBuilder buildVecReduceFMul(const DstOp &Dst,
+ const SrcOp &ScalarIn,
+ const SrcOp &VecIn) {
+ return buildInstr(TargetOpcode::G_VECREDUCE_FMUL, {Dst}, {ScalarIn, VecIn});
+ }
+
+ /// Build and insert \p Res = G_VECREDUCE_FMAX \p Src
+ MachineInstrBuilder buildVecReduceFMax(const DstOp &Dst, const SrcOp &Src) {
+ return buildInstr(TargetOpcode::G_VECREDUCE_FMAX, {Dst}, {Src});
+ }
+
+ /// Build and insert \p Res = G_VECREDUCE_FMIN \p Src
+ MachineInstrBuilder buildVecReduceFMin(const DstOp &Dst, const SrcOp &Src) {
+ return buildInstr(TargetOpcode::G_VECREDUCE_FMIN, {Dst}, {Src});
+ }
+ /// Build and insert \p Res = G_VECREDUCE_ADD \p Src
+ MachineInstrBuilder buildVecReduceAdd(const DstOp &Dst, const SrcOp &Src) {
+ return buildInstr(TargetOpcode::G_VECREDUCE_ADD, {Dst}, {Src});
+ }
+
+ /// Build and insert \p Res = G_VECREDUCE_MUL \p Src
+ MachineInstrBuilder buildVecReduceMul(const DstOp &Dst, const SrcOp &Src) {
+ return buildInstr(TargetOpcode::G_VECREDUCE_MUL, {Dst}, {Src});
+ }
+
+ /// Build and insert \p Res = G_VECREDUCE_AND \p Src
+ MachineInstrBuilder buildVecReduceAnd(const DstOp &Dst, const SrcOp &Src) {
+ return buildInstr(TargetOpcode::G_VECREDUCE_AND, {Dst}, {Src});
+ }
+
+ /// Build and insert \p Res = G_VECREDUCE_OR \p Src
+ MachineInstrBuilder buildVecReduceOr(const DstOp &Dst, const SrcOp &Src) {
+ return buildInstr(TargetOpcode::G_VECREDUCE_OR, {Dst}, {Src});
+ }
+
+ /// Build and insert \p Res = G_VECREDUCE_XOR \p Src
+ MachineInstrBuilder buildVecReduceXor(const DstOp &Dst, const SrcOp &Src) {
+ return buildInstr(TargetOpcode::G_VECREDUCE_XOR, {Dst}, {Src});
+ }
+
+ /// Build and insert \p Res = G_VECREDUCE_SMAX \p Src
+ MachineInstrBuilder buildVecReduceSMax(const DstOp &Dst, const SrcOp &Src) {
+ return buildInstr(TargetOpcode::G_VECREDUCE_SMAX, {Dst}, {Src});
+ }
+
+ /// Build and insert \p Res = G_VECREDUCE_SMIN \p Src
+ MachineInstrBuilder buildVecReduceSMin(const DstOp &Dst, const SrcOp &Src) {
+ return buildInstr(TargetOpcode::G_VECREDUCE_SMIN, {Dst}, {Src});
+ }
+
+ /// Build and insert \p Res = G_VECREDUCE_UMAX \p Src
+ MachineInstrBuilder buildVecReduceUMax(const DstOp &Dst, const SrcOp &Src) {
+ return buildInstr(TargetOpcode::G_VECREDUCE_UMAX, {Dst}, {Src});
+ }
+
+ /// Build and insert \p Res = G_VECREDUCE_UMIN \p Src
+ MachineInstrBuilder buildVecReduceUMin(const DstOp &Dst, const SrcOp &Src) {
+ return buildInstr(TargetOpcode::G_VECREDUCE_UMIN, {Dst}, {Src});
+ }
virtual MachineInstrBuilder buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
ArrayRef<SrcOp> SrcOps,
Optional<unsigned> Flags = None);
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
index baff41e3c3..0dbd1ecffe 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
@@ -111,37 +111,37 @@ public:
/// Currently the TableGen-like file would look like:
/// \code
/// PartialMapping[] = {
- /// /*32-bit add*/ {0, 32, GPR}, // Scalar entry repeated for first
- /// // vec elt.
- /// /*2x32-bit add*/ {0, 32, GPR}, {32, 32, GPR},
- /// /*<2x32-bit> vadd*/ {0, 64, VPR}
+ /// /*32-bit add*/ {0, 32, GPR}, // Scalar entry repeated for first
+ /// // vec elt.
+ /// /*2x32-bit add*/ {0, 32, GPR}, {32, 32, GPR},
+ /// /*<2x32-bit> vadd*/ {0, 64, VPR}
/// }; // PartialMapping duplicated.
///
/// ValueMapping[] {
- /// /*plain 32-bit add*/ {&PartialMapping[0], 1},
+ /// /*plain 32-bit add*/ {&PartialMapping[0], 1},
/// /*expanded vadd on 2xadd*/ {&PartialMapping[1], 2},
- /// /*plain <2x32-bit> vadd*/ {&PartialMapping[3], 1}
+ /// /*plain <2x32-bit> vadd*/ {&PartialMapping[3], 1}
/// };
/// \endcode
///
/// With the array of pointer, we would have:
/// \code
/// PartialMapping[] = {
- /// /*32-bit add lower */ { 0, 32, GPR},
+ /// /*32-bit add lower */ { 0, 32, GPR},
/// /*32-bit add upper */ {32, 32, GPR},
- /// /*<2x32-bit> vadd */ { 0, 64, VPR}
+ /// /*<2x32-bit> vadd */ { 0, 64, VPR}
/// }; // No more duplication.
///
/// BreakDowns[] = {
- /// /*AddBreakDown*/ &PartialMapping[0],
+ /// /*AddBreakDown*/ &PartialMapping[0],
/// /*2xAddBreakDown*/ &PartialMapping[0], &PartialMapping[1],
- /// /*VAddBreakDown*/ &PartialMapping[2]
+ /// /*VAddBreakDown*/ &PartialMapping[2]
/// }; // Addresses of PartialMapping duplicated (smaller).
///
/// ValueMapping[] {
- /// /*plain 32-bit add*/ {&BreakDowns[0], 1},
+ /// /*plain 32-bit add*/ {&BreakDowns[0], 1},
/// /*expanded vadd on 2xadd*/ {&BreakDowns[1], 2},
- /// /*plain <2x32-bit> vadd*/ {&BreakDowns[3], 1}
+ /// /*plain <2x32-bit> vadd*/ {&BreakDowns[3], 1}
/// };
/// \endcode
///
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/Utils.h b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/Utils.h
index 6059e13234..d07bcae8e7 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/Utils.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/GlobalISel/Utils.h
@@ -25,12 +25,12 @@
#include "llvm/CodeGen/Register.h"
#include "llvm/Support/Alignment.h"
#include "llvm/Support/LowLevelTypeImpl.h"
-#include <cstdint>
+#include <cstdint>
namespace llvm {
class AnalysisUsage;
-class GISelKnownBits;
+class GISelKnownBits;
class MachineFunction;
class MachineInstr;
class MachineOperand;
@@ -41,7 +41,7 @@ class MachineRegisterInfo;
class MCInstrDesc;
class RegisterBankInfo;
class TargetInstrInfo;
-class TargetLowering;
+class TargetLowering;
class TargetPassConfig;
class TargetRegisterInfo;
class TargetRegisterClass;
@@ -59,10 +59,10 @@ Register constrainRegToClass(MachineRegisterInfo &MRI,
/// Constrain the Register operand OpIdx, so that it is now constrained to the
/// TargetRegisterClass passed as an argument (RegClass).
-/// If this fails, create a new virtual register in the correct class and insert
-/// a COPY before \p InsertPt if it is a use or after if it is a definition.
-/// In both cases, the function also updates the register of RegMo. The debug
-/// location of \p InsertPt is used for the new copy.
+/// If this fails, create a new virtual register in the correct class and insert
+/// a COPY before \p InsertPt if it is a use or after if it is a definition.
+/// In both cases, the function also updates the register of RegMo. The debug
+/// location of \p InsertPt is used for the new copy.
///
/// \return The virtual register constrained to the right register class.
Register constrainOperandRegClass(const MachineFunction &MF,
@@ -72,13 +72,13 @@ Register constrainOperandRegClass(const MachineFunction &MF,
const RegisterBankInfo &RBI,
MachineInstr &InsertPt,
const TargetRegisterClass &RegClass,
- MachineOperand &RegMO);
+ MachineOperand &RegMO);
-/// Try to constrain Reg so that it is usable by argument OpIdx of the provided
-/// MCInstrDesc \p II. If this fails, create a new virtual register in the
-/// correct class and insert a COPY before \p InsertPt if it is a use or after
-/// if it is a definition. In both cases, the function also updates the register
-/// of RegMo.
+/// Try to constrain Reg so that it is usable by argument OpIdx of the provided
+/// MCInstrDesc \p II. If this fails, create a new virtual register in the
+/// correct class and insert a COPY before \p InsertPt if it is a use or after
+/// if it is a definition. In both cases, the function also updates the register
+/// of RegMo.
/// This is equivalent to constrainOperandRegClass(..., RegClass, ...)
/// with RegClass obtained from the MCInstrDesc. The debug location of \p
/// InsertPt is used for the new copy.
@@ -90,7 +90,7 @@ Register constrainOperandRegClass(const MachineFunction &MF,
const TargetInstrInfo &TII,
const RegisterBankInfo &RBI,
MachineInstr &InsertPt, const MCInstrDesc &II,
- MachineOperand &RegMO, unsigned OpIdx);
+ MachineOperand &RegMO, unsigned OpIdx);
/// Mutate the newly-selected instruction \p I to constrain its (possibly
/// generic) virtual register operands to the instruction's register class.
@@ -131,19 +131,19 @@ void reportGISelWarning(MachineFunction &MF, const TargetPassConfig &TPC,
MachineOptimizationRemarkEmitter &MORE,
MachineOptimizationRemarkMissed &R);
-/// If \p VReg is defined by a G_CONSTANT, return the corresponding value.
-Optional<APInt> getConstantVRegVal(Register VReg,
- const MachineRegisterInfo &MRI);
-
+/// If \p VReg is defined by a G_CONSTANT, return the corresponding value.
+Optional<APInt> getConstantVRegVal(Register VReg,
+ const MachineRegisterInfo &MRI);
+
/// If \p VReg is defined by a G_CONSTANT fits in int64_t
/// returns it.
-Optional<int64_t> getConstantVRegSExtVal(Register VReg,
- const MachineRegisterInfo &MRI);
-
+Optional<int64_t> getConstantVRegSExtVal(Register VReg,
+ const MachineRegisterInfo &MRI);
+
/// Simple struct used to hold a constant integer value and a virtual
/// register.
struct ValueAndVReg {
- APInt Value;
+ APInt Value;
Register VReg;
};
/// If \p VReg is defined by a statically evaluable chain of
@@ -153,13 +153,13 @@ struct ValueAndVReg {
/// When \p LookThroughInstrs == false this function behaves like
/// getConstantVRegVal.
/// When \p HandleFConstants == false the function bails on G_FCONSTANTs.
-/// When \p LookThroughAnyExt == true the function treats G_ANYEXT same as
-/// G_SEXT.
+/// When \p LookThroughAnyExt == true the function treats G_ANYEXT same as
+/// G_SEXT.
Optional<ValueAndVReg>
getConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI,
bool LookThroughInstrs = true,
- bool HandleFConstants = true,
- bool LookThroughAnyExt = false);
+ bool HandleFConstants = true,
+ bool LookThroughAnyExt = false);
const ConstantFP* getConstantFPVRegVal(Register VReg,
const MachineRegisterInfo &MRI);
@@ -169,20 +169,20 @@ const ConstantFP* getConstantFPVRegVal(Register VReg,
MachineInstr *getOpcodeDef(unsigned Opcode, Register Reg,
const MachineRegisterInfo &MRI);
-/// Simple struct used to hold a Register value and the instruction which
-/// defines it.
-struct DefinitionAndSourceRegister {
- MachineInstr *MI;
- Register Reg;
-};
-
-/// Find the def instruction for \p Reg, and underlying value Register folding
-/// away any copies.
-Optional<DefinitionAndSourceRegister>
-getDefSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI);
-
-/// Find the def instruction for \p Reg, folding away any trivial copies. May
-/// return nullptr if \p Reg is not a generic virtual register.
+/// Simple struct used to hold a Register value and the instruction which
+/// defines it.
+struct DefinitionAndSourceRegister {
+ MachineInstr *MI;
+ Register Reg;
+};
+
+/// Find the def instruction for \p Reg, and underlying value Register folding
+/// away any copies.
+Optional<DefinitionAndSourceRegister>
+getDefSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI);
+
+/// Find the def instruction for \p Reg, folding away any trivial copies. May
+/// return nullptr if \p Reg is not a generic virtual register.
MachineInstr *getDefIgnoringCopies(Register Reg,
const MachineRegisterInfo &MRI);
@@ -207,12 +207,12 @@ Optional<APInt> ConstantFoldBinOp(unsigned Opcode, const Register Op1,
Optional<APInt> ConstantFoldExtOp(unsigned Opcode, const Register Op1,
uint64_t Imm, const MachineRegisterInfo &MRI);
-/// Test if the given value is known to have exactly one bit set. This differs
-/// from computeKnownBits in that it doesn't necessarily determine which bit is
-/// set.
-bool isKnownToBeAPowerOfTwo(Register Val, const MachineRegisterInfo &MRI,
- GISelKnownBits *KnownBits = nullptr);
-
+/// Test if the given value is known to have exactly one bit set. This differs
+/// from computeKnownBits in that it doesn't necessarily determine which bit is
+/// set.
+bool isKnownToBeAPowerOfTwo(Register Val, const MachineRegisterInfo &MRI,
+ GISelKnownBits *KnownBits = nullptr);
+
/// Returns true if \p Val can be assumed to never be a NaN. If \p SNaN is true,
/// this returns if \p Val can be assumed to never be a signaling NaN.
bool isKnownNeverNaN(Register Val, const MachineRegisterInfo &MRI,
@@ -225,66 +225,66 @@ inline bool isKnownNeverSNaN(Register Val, const MachineRegisterInfo &MRI) {
Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO);
-/// Return a virtual register corresponding to the incoming argument register \p
-/// PhysReg. This register is expected to have class \p RC, and optional type \p
-/// RegTy. This assumes all references to the register will use the same type.
-///
-/// If there is an existing live-in argument register, it will be returned.
-/// This will also ensure there is a valid copy
-Register getFunctionLiveInPhysReg(MachineFunction &MF, const TargetInstrInfo &TII,
- MCRegister PhysReg,
- const TargetRegisterClass &RC,
- LLT RegTy = LLT());
-
-/// Return the least common multiple type of \p OrigTy and \p TargetTy, by changing the
-/// number of vector elements or scalar bitwidth. The intent is a
-/// G_MERGE_VALUES, G_BUILD_VECTOR, or G_CONCAT_VECTORS can be constructed from
-/// \p OrigTy elements, and unmerged into \p TargetTy
-LLVM_READNONE
-LLT getLCMType(LLT OrigTy, LLT TargetTy);
-
-/// Return a type where the total size is the greatest common divisor of \p
-/// OrigTy and \p TargetTy. This will try to either change the number of vector
-/// elements, or bitwidth of scalars. The intent is the result type can be used
-/// as the result of a G_UNMERGE_VALUES from \p OrigTy, and then some
-/// combination of G_MERGE_VALUES, G_BUILD_VECTOR and G_CONCAT_VECTORS (possibly
-/// with intermediate casts) can re-form \p TargetTy.
-///
-/// If these are vectors with different element types, this will try to produce
-/// a vector with a compatible total size, but the element type of \p OrigTy. If
-/// this can't be satisfied, this will produce a scalar smaller than the
-/// original vector elements.
-///
-/// In the worst case, this returns LLT::scalar(1)
-LLVM_READNONE
+/// Return a virtual register corresponding to the incoming argument register \p
+/// PhysReg. This register is expected to have class \p RC, and optional type \p
+/// RegTy. This assumes all references to the register will use the same type.
+///
+/// If there is an existing live-in argument register, it will be returned.
+/// This will also ensure there is a valid copy
+Register getFunctionLiveInPhysReg(MachineFunction &MF, const TargetInstrInfo &TII,
+ MCRegister PhysReg,
+ const TargetRegisterClass &RC,
+ LLT RegTy = LLT());
+
+/// Return the least common multiple type of \p OrigTy and \p TargetTy, by changing the
+/// number of vector elements or scalar bitwidth. The intent is a
+/// G_MERGE_VALUES, G_BUILD_VECTOR, or G_CONCAT_VECTORS can be constructed from
+/// \p OrigTy elements, and unmerged into \p TargetTy
+LLVM_READNONE
+LLT getLCMType(LLT OrigTy, LLT TargetTy);
+
+/// Return a type where the total size is the greatest common divisor of \p
+/// OrigTy and \p TargetTy. This will try to either change the number of vector
+/// elements, or bitwidth of scalars. The intent is the result type can be used
+/// as the result of a G_UNMERGE_VALUES from \p OrigTy, and then some
+/// combination of G_MERGE_VALUES, G_BUILD_VECTOR and G_CONCAT_VECTORS (possibly
+/// with intermediate casts) can re-form \p TargetTy.
+///
+/// If these are vectors with different element types, this will try to produce
+/// a vector with a compatible total size, but the element type of \p OrigTy. If
+/// this can't be satisfied, this will produce a scalar smaller than the
+/// original vector elements.
+///
+/// In the worst case, this returns LLT::scalar(1)
+LLVM_READNONE
LLT getGCDType(LLT OrigTy, LLT TargetTy);
-/// \returns The splat index of a G_SHUFFLE_VECTOR \p MI when \p MI is a splat.
-/// If \p MI is not a splat, returns None.
-Optional<int> getSplatIndex(MachineInstr &MI);
-
-/// Returns a scalar constant of a G_BUILD_VECTOR splat if it exists.
-Optional<int64_t> getBuildVectorConstantSplat(const MachineInstr &MI,
- const MachineRegisterInfo &MRI);
-
-/// Return true if the specified instruction is a G_BUILD_VECTOR or
-/// G_BUILD_VECTOR_TRUNC where all of the elements are 0 or undef.
-bool isBuildVectorAllZeros(const MachineInstr &MI,
- const MachineRegisterInfo &MRI);
-
-/// Return true if the specified instruction is a G_BUILD_VECTOR or
-/// G_BUILD_VECTOR_TRUNC where all of the elements are ~0 or undef.
-bool isBuildVectorAllOnes(const MachineInstr &MI,
- const MachineRegisterInfo &MRI);
-
-/// Returns true if given the TargetLowering's boolean contents information,
-/// the value \p Val contains a true value.
-bool isConstTrueVal(const TargetLowering &TLI, int64_t Val, bool IsVector,
- bool IsFP);
-
-/// Returns an integer representing true, as defined by the
-/// TargetBooleanContents.
-int64_t getICmpTrueVal(const TargetLowering &TLI, bool IsVector, bool IsFP);
+/// \returns The splat index of a G_SHUFFLE_VECTOR \p MI when \p MI is a splat.
+/// If \p MI is not a splat, returns None.
+Optional<int> getSplatIndex(MachineInstr &MI);
+
+/// Returns a scalar constant of a G_BUILD_VECTOR splat if it exists.
+Optional<int64_t> getBuildVectorConstantSplat(const MachineInstr &MI,
+ const MachineRegisterInfo &MRI);
+
+/// Return true if the specified instruction is a G_BUILD_VECTOR or
+/// G_BUILD_VECTOR_TRUNC where all of the elements are 0 or undef.
+bool isBuildVectorAllZeros(const MachineInstr &MI,
+ const MachineRegisterInfo &MRI);
+
+/// Return true if the specified instruction is a G_BUILD_VECTOR or
+/// G_BUILD_VECTOR_TRUNC where all of the elements are ~0 or undef.
+bool isBuildVectorAllOnes(const MachineInstr &MI,
+ const MachineRegisterInfo &MRI);
+
+/// Returns true if given the TargetLowering's boolean contents information,
+/// the value \p Val contains a true value.
+bool isConstTrueVal(const TargetLowering &TLI, int64_t Val, bool IsVector,
+ bool IsFP);
+
+/// Returns an integer representing true, as defined by the
+/// TargetBooleanContents.
+int64_t getICmpTrueVal(const TargetLowering &TLI, bool IsVector, bool IsFP);
} // End namespace llvm.
#endif
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/ISDOpcodes.h b/contrib/libs/llvm12/include/llvm/CodeGen/ISDOpcodes.h
index d944d3b4df..8dae18f3e2 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/ISDOpcodes.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/ISDOpcodes.h
@@ -93,16 +93,16 @@ enum NodeType {
/// the parent's frame or return address, and so on.
FRAMEADDR,
RETURNADDR,
-
- /// ADDROFRETURNADDR - Represents the llvm.addressofreturnaddress intrinsic.
- /// This node takes no operand, returns a target-specific pointer to the
- /// place in the stack frame where the return address of the current
- /// function is stored.
+
+ /// ADDROFRETURNADDR - Represents the llvm.addressofreturnaddress intrinsic.
+ /// This node takes no operand, returns a target-specific pointer to the
+ /// place in the stack frame where the return address of the current
+ /// function is stored.
ADDROFRETURNADDR,
-
- /// SPONENTRY - Represents the llvm.sponentry intrinsic. Takes no argument
- /// and returns the stack pointer value at the entry of the current
- /// function calling this intrinsic.
+
+ /// SPONENTRY - Represents the llvm.sponentry intrinsic. Takes no argument
+ /// and returns the stack pointer value at the entry of the current
+ /// function calling this intrinsic.
SPONENTRY,
/// LOCAL_RECOVER - Represents the llvm.localrecover intrinsic.
@@ -290,16 +290,16 @@ enum NodeType {
ADDCARRY,
SUBCARRY,
- /// Carry-using overflow-aware nodes for multiple precision addition and
- /// subtraction. These nodes take three operands: The first two are normal lhs
- /// and rhs to the add or sub, and the third is a boolean indicating if there
- /// is an incoming carry. They produce two results: the normal result of the
- /// add or sub, and a boolean that indicates if an overflow occured (*not*
- /// flag, because it may be a store to memory, etc.). If the type of the
- /// boolean is not i1 then the high bits conform to getBooleanContents.
- SADDO_CARRY,
- SSUBO_CARRY,
-
+ /// Carry-using overflow-aware nodes for multiple precision addition and
+ /// subtraction. These nodes take three operands: The first two are normal lhs
+ /// and rhs to the add or sub, and the third is a boolean indicating if there
+ /// is an incoming carry. They produce two results: the normal result of the
+ /// add or sub, and a boolean that indicates if an overflow occured (*not*
+ /// flag, because it may be a store to memory, etc.). If the type of the
+ /// boolean is not i1 then the high bits conform to getBooleanContents.
+ SADDO_CARRY,
+ SSUBO_CARRY,
+
/// RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
/// These nodes take two operands: the normal LHS and RHS to the add. They
/// produce two results: the normal result of the add, and a boolean that
@@ -336,16 +336,16 @@ enum NodeType {
SSUBSAT,
USUBSAT,
- /// RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift. The first
- /// operand is the value to be shifted, and the second argument is the amount
- /// to shift by. Both must be integers of the same bit width (W). If the true
- /// value of LHS << RHS exceeds the largest value that can be represented by
- /// W bits, the resulting value is this maximum value, Otherwise, if this
- /// value is less than the smallest value that can be represented by W bits,
- /// the resulting value is this minimum value.
- SSHLSAT,
- USHLSAT,
-
+ /// RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift. The first
+ /// operand is the value to be shifted, and the second argument is the amount
+ /// to shift by. Both must be integers of the same bit width (W). If the true
+ /// value of LHS << RHS exceeds the largest value that can be represented by
+ /// W bits, the resulting value is this maximum value, Otherwise, if this
+ /// value is less than the smallest value that can be represented by W bits,
+ /// the resulting value is this minimum value.
+ SSHLSAT,
+ USHLSAT,
+
/// RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication
/// on
/// 2 integers with the same width and scale. SCALE represents the scale of
@@ -540,8 +540,8 @@ enum NodeType {
/// IDX is first scaled by the runtime scaling factor of T. Elements IDX
/// through (IDX + num_elements(T) - 1) must be valid VECTOR indices. If this
/// condition cannot be determined statically but is false at runtime, then
- /// the result vector is undefined. The IDX parameter must be a vector index
- /// constant type, which for most targets will be an integer pointer type.
+ /// the result vector is undefined. The IDX parameter must be a vector index
+ /// constant type, which for most targets will be an integer pointer type.
///
/// This operation supports extracting a fixed-width vector from a scalable
/// vector, but not the other way around.
@@ -624,7 +624,7 @@ enum NodeType {
CTLZ,
CTPOP,
BITREVERSE,
- PARITY,
+ PARITY,
/// Bit counting operators with an undefined result for zero inputs.
CTTZ_ZERO_UNDEF,
@@ -741,21 +741,21 @@ enum NodeType {
FP_TO_SINT,
FP_TO_UINT,
- /// FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a
- /// signed or unsigned integer type with the bit width given in operand 1 with
- /// the following semantics:
- ///
- /// * If the value is NaN, zero is returned.
- /// * If the value is larger/smaller than the largest/smallest integer,
- /// the largest/smallest integer is returned (saturation).
- /// * Otherwise the result of rounding the value towards zero is returned.
- ///
- /// The width given in operand 1 must be equal to, or smaller than, the scalar
- /// result type width. It may end up being smaller than the result witdh as a
- /// result of integer type legalization.
- FP_TO_SINT_SAT,
- FP_TO_UINT_SAT,
-
+ /// FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a
+ /// signed or unsigned integer type with the bit width given in operand 1 with
+ /// the following semantics:
+ ///
+ /// * If the value is NaN, zero is returned.
+ /// * If the value is larger/smaller than the largest/smallest integer,
+ /// the largest/smallest integer is returned (saturation).
+ /// * Otherwise the result of rounding the value towards zero is returned.
+ ///
+ /// The width given in operand 1 must be equal to, or smaller than, the scalar
+ /// result type width. It may end up being smaller than the result witdh as a
+ /// result of integer type legalization.
+ FP_TO_SINT_SAT,
+ FP_TO_UINT_SAT,
+
/// X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type
/// down to the precision of the destination VT. TRUNC is a flag, which is
/// always an integer that is zero or one. If TRUNC is 0, this is a
@@ -897,18 +897,18 @@ enum NodeType {
/// BRCOND - Conditional branch. The first operand is the chain, the
/// second is the condition, the third is the block to branch to if the
/// condition is true. If the type of the condition is not i1, then the
- /// high bits must conform to getBooleanContents. If the condition is undef,
- /// it nondeterministically jumps to the block.
- /// TODO: Its semantics w.r.t undef requires further discussion; we need to
- /// make it sure that it is consistent with optimizations in MIR & the
- /// meaning of IMPLICIT_DEF. See https://reviews.llvm.org/D92015
+ /// high bits must conform to getBooleanContents. If the condition is undef,
+ /// it nondeterministically jumps to the block.
+ /// TODO: Its semantics w.r.t undef requires further discussion; we need to
+ /// make it sure that it is consistent with optimizations in MIR & the
+ /// meaning of IMPLICIT_DEF. See https://reviews.llvm.org/D92015
BRCOND,
/// BR_CC - Conditional branch. The behavior is like that of SELECT_CC, in
/// that the condition is represented as condition code, and two nodes to
/// compare, rather than as a combined SetCC node. The operands in order
- /// are chain, cc, lhs, rhs, block to branch to if condition is true. If
- /// condition is undef, it nondeterministically jumps to the block.
+ /// are chain, cc, lhs, rhs, block to branch to if condition is true. If
+ /// condition is undef, it nondeterministically jumps to the block.
BR_CC,
/// INLINEASM - Represents an inline asm block. This node always has two
@@ -1039,9 +1039,9 @@ enum NodeType {
/// DEBUGTRAP - Trap intended to get the attention of a debugger.
DEBUGTRAP,
- /// UBSANTRAP - Trap with an immediate describing the kind of sanitizer failure.
- UBSANTRAP,
-
+ /// UBSANTRAP - Trap with an immediate describing the kind of sanitizer failure.
+ UBSANTRAP,
+
/// PREFETCH - This corresponds to a prefetch intrinsic. The first operand
/// is the chain. The other operands are the address to prefetch,
/// read / write specifier, locality specifier and instruction / data cache
@@ -1136,10 +1136,10 @@ enum NodeType {
/// known nonzero constant. The only operand here is the chain.
GET_DYNAMIC_AREA_OFFSET,
- /// Pseudo probe for AutoFDO, as a place holder in a basic block to improve
- /// the sample counts quality.
- PSEUDO_PROBE,
-
+ /// Pseudo probe for AutoFDO, as a place holder in a basic block to improve
+ /// the sample counts quality.
+ PSEUDO_PROBE,
+
/// VSCALE(IMM) - Returns the runtime scaling factor used to calculate the
/// number of elements within a scalable vector. IMM is a constant integer
/// multiplier that is applied to the runtime value.
@@ -1147,25 +1147,25 @@ enum NodeType {
/// Generic reduction nodes. These nodes represent horizontal vector
/// reduction operations, producing a scalar result.
- /// The SEQ variants perform reductions in sequential order. The first
+ /// The SEQ variants perform reductions in sequential order. The first
/// operand is an initial scalar accumulator value, and the second operand
/// is the vector to reduce.
- /// E.g. RES = VECREDUCE_SEQ_FADD f32 ACC, <4 x f32> SRC_VEC
- /// ... is equivalent to
- /// RES = (((ACC + SRC_VEC[0]) + SRC_VEC[1]) + SRC_VEC[2]) + SRC_VEC[3]
- VECREDUCE_SEQ_FADD,
- VECREDUCE_SEQ_FMUL,
-
- /// These reductions have relaxed evaluation order semantics, and have a
- /// single vector operand. The order of evaluation is unspecified. For
- /// pow-of-2 vectors, one valid legalizer expansion is to use a tree
- /// reduction, i.e.:
- /// For RES = VECREDUCE_FADD <8 x f16> SRC_VEC
- /// PART_RDX = FADD SRC_VEC[0:3], SRC_VEC[4:7]
- /// PART_RDX2 = FADD PART_RDX[0:1], PART_RDX[2:3]
- /// RES = FADD PART_RDX2[0], PART_RDX2[1]
- /// For non-pow-2 vectors, this can be computed by extracting each element
- /// and performing the operation as if it were scalarized.
+ /// E.g. RES = VECREDUCE_SEQ_FADD f32 ACC, <4 x f32> SRC_VEC
+ /// ... is equivalent to
+ /// RES = (((ACC + SRC_VEC[0]) + SRC_VEC[1]) + SRC_VEC[2]) + SRC_VEC[3]
+ VECREDUCE_SEQ_FADD,
+ VECREDUCE_SEQ_FMUL,
+
+ /// These reductions have relaxed evaluation order semantics, and have a
+ /// single vector operand. The order of evaluation is unspecified. For
+ /// pow-of-2 vectors, one valid legalizer expansion is to use a tree
+ /// reduction, i.e.:
+ /// For RES = VECREDUCE_FADD <8 x f16> SRC_VEC
+ /// PART_RDX = FADD SRC_VEC[0:3], SRC_VEC[4:7]
+ /// PART_RDX2 = FADD PART_RDX[0:1], PART_RDX[2:3]
+ /// RES = FADD PART_RDX2[0], PART_RDX2[1]
+ /// For non-pow-2 vectors, this can be computed by extracting each element
+ /// and performing the operation as if it were scalarized.
VECREDUCE_FADD,
VECREDUCE_FMUL,
/// FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@@ -1184,10 +1184,10 @@ enum NodeType {
VECREDUCE_UMAX,
VECREDUCE_UMIN,
-// Vector Predication
-#define BEGIN_REGISTER_VP_SDNODE(VPSDID, ...) VPSDID,
-#include "llvm/IR/VPIntrinsics.def"
-
+// Vector Predication
+#define BEGIN_REGISTER_VP_SDNODE(VPSDID, ...) VPSDID,
+#include "llvm/IR/VPIntrinsics.def"
+
/// BUILTIN_OP_END - This must be the last enum value in this list.
/// The target-specific pre-isel opcode values start here.
BUILTIN_OP_END
@@ -1204,19 +1204,19 @@ static const int FIRST_TARGET_STRICTFP_OPCODE = BUILTIN_OP_END + 400;
/// be used with SelectionDAG::getMemIntrinsicNode.
static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END + 500;
-/// Get underlying scalar opcode for VECREDUCE opcode.
-/// For example ISD::AND for ISD::VECREDUCE_AND.
-NodeType getVecReduceBaseOpcode(unsigned VecReduceOpcode);
-
-/// Whether this is a vector-predicated Opcode.
-bool isVPOpcode(unsigned Opcode);
-
-/// The operand position of the vector mask.
-Optional<unsigned> getVPMaskIdx(unsigned Opcode);
-
-/// The operand position of the explicit vector length parameter.
-Optional<unsigned> getVPExplicitVectorLengthIdx(unsigned Opcode);
-
+/// Get underlying scalar opcode for VECREDUCE opcode.
+/// For example ISD::AND for ISD::VECREDUCE_AND.
+NodeType getVecReduceBaseOpcode(unsigned VecReduceOpcode);
+
+/// Whether this is a vector-predicated Opcode.
+bool isVPOpcode(unsigned Opcode);
+
+/// The operand position of the vector mask.
+Optional<unsigned> getVPMaskIdx(unsigned Opcode);
+
+/// The operand position of the explicit vector length parameter.
+Optional<unsigned> getVPExplicitVectorLengthIdx(unsigned Opcode);
+
//===--------------------------------------------------------------------===//
/// MemIndexedMode enum - This enum defines the load / store indexed
/// addressing modes.
@@ -1339,12 +1339,12 @@ inline bool isUnsignedIntSetCC(CondCode Code) {
return Code == SETUGT || Code == SETUGE || Code == SETULT || Code == SETULE;
}
-/// Return true if this is a setcc instruction that performs an equality
-/// comparison when used with integer operands.
-inline bool isIntEqualitySetCC(CondCode Code) {
- return Code == SETEQ || Code == SETNE;
-}
-
+/// Return true if this is a setcc instruction that performs an equality
+/// comparison when used with integer operands.
+inline bool isIntEqualitySetCC(CondCode Code) {
+ return Code == SETEQ || Code == SETNE;
+}
+
/// Return true if the specified condition returns true if the two operands to
/// the condition are equal. Note that if one of the two operands is a NaN,
/// this value is meaningless.
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/LiveInterval.h b/contrib/libs/llvm12/include/llvm/CodeGen/LiveInterval.h
index e4a03e9598..0ee69222af 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/LiveInterval.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/LiveInterval.h
@@ -32,7 +32,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
-#include "llvm/CodeGen/Register.h"
+#include "llvm/CodeGen/Register.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/MC/LaneBitmask.h"
#include "llvm/Support/Allocator.h"
@@ -605,9 +605,9 @@ namespace llvm {
/// @p End.
bool isUndefIn(ArrayRef<SlotIndex> Undefs, SlotIndex Begin,
SlotIndex End) const {
- return llvm::any_of(Undefs, [Begin, End](SlotIndex Idx) -> bool {
- return Begin <= Idx && Idx < End;
- });
+ return llvm::any_of(Undefs, [Begin, End](SlotIndex Idx) -> bool {
+ return Begin <= Idx && Idx < End;
+ });
}
/// Flush segment set into the regular segment vector.
@@ -711,16 +711,16 @@ namespace llvm {
private:
SubRange *SubRanges = nullptr; ///< Single linked list of subregister live
/// ranges.
- const Register Reg; // the register or stack slot of this interval.
- float Weight = 0.0; // weight of this interval
+ const Register Reg; // the register or stack slot of this interval.
+ float Weight = 0.0; // weight of this interval
public:
- Register reg() const { return Reg; }
- float weight() const { return Weight; }
- void incrementWeight(float Inc) { Weight += Inc; }
- void setWeight(float Value) { Weight = Value; }
+ Register reg() const { return Reg; }
+ float weight() const { return Weight; }
+ void incrementWeight(float Inc) { Weight += Inc; }
+ void setWeight(float Value) { Weight = Value; }
- LiveInterval(unsigned Reg, float Weight) : Reg(Reg), Weight(Weight) {}
+ LiveInterval(unsigned Reg, float Weight) : Reg(Reg), Weight(Weight) {}
~LiveInterval() {
clearSubRanges();
@@ -817,10 +817,10 @@ namespace llvm {
unsigned getSize() const;
/// isSpillable - Can this interval be spilled?
- bool isSpillable() const { return Weight != huge_valf; }
+ bool isSpillable() const { return Weight != huge_valf; }
/// markNotSpillable - Mark interval as not spillable
- void markNotSpillable() { Weight = huge_valf; }
+ void markNotSpillable() { Weight = huge_valf; }
/// For a given lane mask @p LaneMask, compute indexes at which the
/// lane is marked undefined by subregister <def,read-undef> definitions.
@@ -841,7 +841,7 @@ namespace llvm {
/// function will be applied to the L0010 and L0008 subranges.
///
/// \p Indexes and \p TRI are required to clean up the VNIs that
- /// don't define the related lane masks after they get shrunk. E.g.,
+ /// don't define the related lane masks after they get shrunk. E.g.,
/// when L000F gets split into L0007 and L0008 maybe only a subset
/// of the VNIs that defined L000F defines L0007.
///
@@ -877,7 +877,7 @@ namespace llvm {
bool operator<(const LiveInterval& other) const {
const SlotIndex &thisIndex = beginIndex();
const SlotIndex &otherIndex = other.beginIndex();
- return std::tie(thisIndex, Reg) < std::tie(otherIndex, other.Reg);
+ return std::tie(thisIndex, Reg) < std::tie(otherIndex, other.Reg);
}
void print(raw_ostream &OS) const;
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/LiveIntervalUnion.h b/contrib/libs/llvm12/include/llvm/CodeGen/LiveIntervalUnion.h
index d05ab9c533..6ac8cebb14 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/LiveIntervalUnion.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/LiveIntervalUnion.h
@@ -111,9 +111,9 @@ public:
void verify(LiveVirtRegBitSet& VisitedVRegs);
#endif
- // Get any virtual register that is assign to this physical unit
- LiveInterval *getOneVReg() const;
-
+ // Get any virtual register that is assign to this physical unit
+ LiveInterval *getOneVReg() const;
+
/// Query interferences between a single live virtual register and a live
/// interval union.
class Query {
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/LiveIntervals.h b/contrib/libs/llvm12/include/llvm/CodeGen/LiveIntervals.h
index bf630ba784..c4abe43a75 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/LiveIntervals.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/LiveIntervals.h
@@ -121,8 +121,8 @@ class VirtRegMap;
LiveInterval &getInterval(Register Reg) {
if (hasInterval(Reg))
return *VirtRegIntervals[Reg.id()];
-
- return createAndComputeVirtRegInterval(Reg);
+
+ return createAndComputeVirtRegInterval(Reg);
}
const LiveInterval &getInterval(Register Reg) const {
@@ -149,14 +149,14 @@ class VirtRegMap;
}
/// Interval removal.
- void removeInterval(Register Reg) {
+ void removeInterval(Register Reg) {
delete VirtRegIntervals[Reg];
VirtRegIntervals[Reg] = nullptr;
}
/// Given a register and an instruction, adds a live segment from that
/// instruction to the end of its MBB.
- LiveInterval::Segment addSegmentToEndOfBlock(Register Reg,
+ LiveInterval::Segment addSegmentToEndOfBlock(Register Reg,
MachineInstr &startInst);
/// After removing some uses of a register, shrink its live range to just
@@ -174,7 +174,7 @@ class VirtRegMap;
/// the lane mask of the subregister range.
/// This may leave the subrange empty which needs to be cleaned up with
/// LiveInterval::removeEmptySubranges() afterwards.
- void shrinkToUses(LiveInterval::SubRange &SR, Register Reg);
+ void shrinkToUses(LiveInterval::SubRange &SR, Register Reg);
/// Extend the live range \p LR to reach all points in \p Indices. The
/// points in the \p Indices array must be jointly dominated by the union
@@ -263,8 +263,8 @@ class VirtRegMap;
return Indexes->getMBBFromIndex(index);
}
- void insertMBBInMaps(MachineBasicBlock *MBB) {
- Indexes->insertMBBInMaps(MBB);
+ void insertMBBInMaps(MachineBasicBlock *MBB) {
+ Indexes->insertMBBInMaps(MBB);
assert(unsigned(MBB->getNumber()) == RegMaskBlocks.size() &&
"Blocks must be added in order.");
RegMaskBlocks.push_back(std::make_pair(RegMaskSlots.size(), 0));
@@ -429,7 +429,7 @@ class VirtRegMap;
/// Reg. Subsequent uses should rely on on-demand recomputation. \note This
/// method can result in inconsistent liveness tracking if multiple phyical
/// registers share a regunit, and should be used cautiously.
- void removeAllRegUnitsForPhysReg(MCRegister Reg) {
+ void removeAllRegUnitsForPhysReg(MCRegister Reg) {
for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
removeRegUnit(*Units);
}
@@ -437,7 +437,7 @@ class VirtRegMap;
/// Remove value numbers and related live segments starting at position
/// \p Pos that are part of any liverange of physical register \p Reg or one
/// of its subregisters.
- void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos);
+ void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos);
/// Remove value number and related live segments of \p LI and its subranges
/// that start at position \p Pos.
@@ -469,7 +469,7 @@ class VirtRegMap;
bool computeDeadValues(LiveInterval &LI,
SmallVectorImpl<MachineInstr*> *dead);
- static LiveInterval *createInterval(Register Reg);
+ static LiveInterval *createInterval(Register Reg);
void printInstrs(raw_ostream &O) const;
void dumpInstrs() const;
@@ -480,7 +480,7 @@ class VirtRegMap;
using ShrinkToUsesWorkList = SmallVector<std::pair<SlotIndex, VNInfo*>, 16>;
void extendSegmentsToUses(LiveRange &Segments,
- ShrinkToUsesWorkList &WorkList, Register Reg,
+ ShrinkToUsesWorkList &WorkList, Register Reg,
LaneBitmask LaneMask);
/// Helper function for repairIntervalsInRange(), walks backwards and
@@ -490,7 +490,7 @@ class VirtRegMap;
void repairOldRegInRange(MachineBasicBlock::iterator Begin,
MachineBasicBlock::iterator End,
const SlotIndex endIdx, LiveRange &LR,
- Register Reg,
+ Register Reg,
LaneBitmask LaneMask = LaneBitmask::getAll());
class HMEditor;
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/LiveRangeEdit.h b/contrib/libs/llvm12/include/llvm/CodeGen/LiveRangeEdit.h
index f16f8dea4a..cf6b28aebe 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/LiveRangeEdit.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/LiveRangeEdit.h
@@ -63,14 +63,14 @@ public:
/// Called when a virtual register is no longer used. Return false to defer
/// its deletion from LiveIntervals.
- virtual bool LRE_CanEraseVirtReg(Register) { return true; }
+ virtual bool LRE_CanEraseVirtReg(Register) { return true; }
/// Called before shrinking the live range of a virtual register.
- virtual void LRE_WillShrinkVirtReg(Register) {}
+ virtual void LRE_WillShrinkVirtReg(Register) {}
/// Called after cloning a virtual register.
/// This is used for new registers representing connected components of Old.
- virtual void LRE_DidCloneVirtReg(Register New, Register Old) {}
+ virtual void LRE_DidCloneVirtReg(Register New, Register Old) {}
};
private:
@@ -159,7 +159,7 @@ public:
return *Parent;
}
- Register getReg() const { return getParent().reg(); }
+ Register getReg() const { return getParent().reg(); }
/// Iterator for accessing the new registers added by this edit.
using iterator = SmallVectorImpl<Register>::const_iterator;
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/LiveRegMatrix.h b/contrib/libs/llvm12/include/llvm/CodeGen/LiveRegMatrix.h
index 4bea80c868..4d6d31e2b6 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/LiveRegMatrix.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/LiveRegMatrix.h
@@ -111,19 +111,19 @@ public:
/// If this function returns IK_Free, it is legal to assign(VirtReg, PhysReg).
/// When there is more than one kind of interference, the InterferenceKind
/// with the highest enum value is returned.
- InterferenceKind checkInterference(LiveInterval &VirtReg, MCRegister PhysReg);
+ InterferenceKind checkInterference(LiveInterval &VirtReg, MCRegister PhysReg);
/// Check for interference in the segment [Start, End) that may prevent
/// assignment to PhysReg. If this function returns true, there is
/// interference in the segment [Start, End) of some other interval already
/// assigned to PhysReg. If this function returns false, PhysReg is free at
/// the segment [Start, End).
- bool checkInterference(SlotIndex Start, SlotIndex End, MCRegister PhysReg);
+ bool checkInterference(SlotIndex Start, SlotIndex End, MCRegister PhysReg);
/// Assign VirtReg to PhysReg.
/// This will mark VirtReg's live range as occupied in the LiveRegMatrix and
/// update VirtRegMap. The live range is expected to be available in PhysReg.
- void assign(LiveInterval &VirtReg, MCRegister PhysReg);
+ void assign(LiveInterval &VirtReg, MCRegister PhysReg);
/// Unassign VirtReg from its PhysReg.
/// Assuming that VirtReg was previously assigned to a PhysReg, this undoes
@@ -131,7 +131,7 @@ public:
void unassign(LiveInterval &VirtReg);
/// Returns true if the given \p PhysReg has any live intervals assigned.
- bool isPhysRegUsed(MCRegister PhysReg) const;
+ bool isPhysRegUsed(MCRegister PhysReg) const;
//===--------------------------------------------------------------------===//
// Low-level interface.
@@ -143,25 +143,25 @@ public:
/// Check for regmask interference only.
/// Return true if VirtReg crosses a regmask operand that clobbers PhysReg.
/// If PhysReg is null, check if VirtReg crosses any regmask operands.
- bool checkRegMaskInterference(LiveInterval &VirtReg,
- MCRegister PhysReg = MCRegister::NoRegister);
+ bool checkRegMaskInterference(LiveInterval &VirtReg,
+ MCRegister PhysReg = MCRegister::NoRegister);
/// Check for regunit interference only.
/// Return true if VirtReg overlaps a fixed assignment of one of PhysRegs's
/// register units.
- bool checkRegUnitInterference(LiveInterval &VirtReg, MCRegister PhysReg);
+ bool checkRegUnitInterference(LiveInterval &VirtReg, MCRegister PhysReg);
/// Query a line of the assigned virtual register matrix directly.
/// Use MCRegUnitIterator to enumerate all regunits in the desired PhysReg.
/// This returns a reference to an internal Query data structure that is only
/// valid until the next query() call.
- LiveIntervalUnion::Query &query(const LiveRange &LR, MCRegister RegUnit);
+ LiveIntervalUnion::Query &query(const LiveRange &LR, MCRegister RegUnit);
/// Directly access the live interval unions per regunit.
/// This returns an array indexed by the regunit number.
LiveIntervalUnion *getLiveUnions() { return &Matrix[0]; }
-
- Register getOneVReg(unsigned PhysReg) const;
+
+ Register getOneVReg(unsigned PhysReg) const;
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/LiveRegUnits.h b/contrib/libs/llvm12/include/llvm/CodeGen/LiveRegUnits.h
index e4fd7ebe92..7382263262 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/LiveRegUnits.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/LiveRegUnits.h
@@ -22,7 +22,7 @@
#define LLVM_CODEGEN_LIVEREGUNITS_H
#include "llvm/ADT/BitVector.h"
-#include "llvm/CodeGen/MachineInstrBundle.h"
+#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/MC/LaneBitmask.h"
#include "llvm/MC/MCRegisterInfo.h"
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/LiveVariables.h b/contrib/libs/llvm12/include/llvm/CodeGen/LiveVariables.h
index 3924e2f5a4..8ab04c8214 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/LiveVariables.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/LiveVariables.h
@@ -112,7 +112,7 @@ public:
/// isLiveIn - Is Reg live in to MBB? This means that Reg is live through
/// MBB, or it is killed in MBB. If Reg is only used by PHI instructions in
/// MBB, it is not considered live in.
- bool isLiveIn(const MachineBasicBlock &MBB, Register Reg,
+ bool isLiveIn(const MachineBasicBlock &MBB, Register Reg,
MachineRegisterInfo &MRI);
void dump() const;
@@ -155,25 +155,25 @@ private: // Intermediate data structures
/// HandlePhysRegKill - Add kills of Reg and its sub-registers to the
/// uses. Pay special attention to the sub-register uses which may come below
/// the last use of the whole register.
- bool HandlePhysRegKill(Register Reg, MachineInstr *MI);
+ bool HandlePhysRegKill(Register Reg, MachineInstr *MI);
/// HandleRegMask - Call HandlePhysRegKill for all registers clobbered by Mask.
void HandleRegMask(const MachineOperand&);
- void HandlePhysRegUse(Register Reg, MachineInstr &MI);
- void HandlePhysRegDef(Register Reg, MachineInstr *MI,
+ void HandlePhysRegUse(Register Reg, MachineInstr &MI);
+ void HandlePhysRegDef(Register Reg, MachineInstr *MI,
SmallVectorImpl<unsigned> &Defs);
void UpdatePhysRegDefs(MachineInstr &MI, SmallVectorImpl<unsigned> &Defs);
/// FindLastRefOrPartRef - Return the last reference or partial reference of
/// the specified register.
- MachineInstr *FindLastRefOrPartRef(Register Reg);
+ MachineInstr *FindLastRefOrPartRef(Register Reg);
/// FindLastPartialDef - Return the last partial def of the specified
/// register. Also returns the sub-registers that're defined by the
/// instruction.
- MachineInstr *FindLastPartialDef(Register Reg,
- SmallSet<unsigned, 4> &PartDefRegs);
+ MachineInstr *FindLastPartialDef(Register Reg,
+ SmallSet<unsigned, 4> &PartDefRegs);
/// analyzePHINodes - Gather information about the PHI nodes in here. In
/// particular, we want to map the variable information of a virtual
@@ -190,21 +190,21 @@ public:
/// RegisterDefIsDead - Return true if the specified instruction defines the
/// specified register, but that definition is dead.
- bool RegisterDefIsDead(MachineInstr &MI, Register Reg) const;
+ bool RegisterDefIsDead(MachineInstr &MI, Register Reg) const;
//===--------------------------------------------------------------------===//
// API to update live variable information
/// replaceKillInstruction - Update register kill info by replacing a kill
/// instruction with a new one.
- void replaceKillInstruction(Register Reg, MachineInstr &OldMI,
+ void replaceKillInstruction(Register Reg, MachineInstr &OldMI,
MachineInstr &NewMI);
/// addVirtualRegisterKilled - Add information about the fact that the
/// specified register is killed after being used by the specified
/// instruction. If AddIfNotFound is true, add a implicit operand if it's
/// not found.
- void addVirtualRegisterKilled(Register IncomingReg, MachineInstr &MI,
+ void addVirtualRegisterKilled(Register IncomingReg, MachineInstr &MI,
bool AddIfNotFound = false) {
if (MI.addRegisterKilled(IncomingReg, TRI, AddIfNotFound))
getVarInfo(IncomingReg).Kills.push_back(&MI);
@@ -214,14 +214,14 @@ public:
/// register from the live variable information. Returns true if the
/// variable was marked as killed by the specified instruction,
/// false otherwise.
- bool removeVirtualRegisterKilled(Register Reg, MachineInstr &MI) {
- if (!getVarInfo(Reg).removeKill(MI))
+ bool removeVirtualRegisterKilled(Register Reg, MachineInstr &MI) {
+ if (!getVarInfo(Reg).removeKill(MI))
return false;
bool Removed = false;
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI.getOperand(i);
- if (MO.isReg() && MO.isKill() && MO.getReg() == Reg) {
+ if (MO.isReg() && MO.isKill() && MO.getReg() == Reg) {
MO.setIsKill(false);
Removed = true;
break;
@@ -240,7 +240,7 @@ public:
/// addVirtualRegisterDead - Add information about the fact that the specified
/// register is dead after being used by the specified instruction. If
/// AddIfNotFound is true, add a implicit operand if it's not found.
- void addVirtualRegisterDead(Register IncomingReg, MachineInstr &MI,
+ void addVirtualRegisterDead(Register IncomingReg, MachineInstr &MI,
bool AddIfNotFound = false) {
if (MI.addRegisterDead(IncomingReg, TRI, AddIfNotFound))
getVarInfo(IncomingReg).Kills.push_back(&MI);
@@ -250,14 +250,14 @@ public:
/// register from the live variable information. Returns true if the
/// variable was marked dead at the specified instruction, false
/// otherwise.
- bool removeVirtualRegisterDead(Register Reg, MachineInstr &MI) {
- if (!getVarInfo(Reg).removeKill(MI))
+ bool removeVirtualRegisterDead(Register Reg, MachineInstr &MI) {
+ if (!getVarInfo(Reg).removeKill(MI))
return false;
bool Removed = false;
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI.getOperand(i);
- if (MO.isReg() && MO.isDef() && MO.getReg() == Reg) {
+ if (MO.isReg() && MO.isDef() && MO.getReg() == Reg) {
MO.setIsDead(false);
Removed = true;
break;
@@ -276,25 +276,25 @@ public:
/// getVarInfo - Return the VarInfo structure for the specified VIRTUAL
/// register.
- VarInfo &getVarInfo(Register Reg);
+ VarInfo &getVarInfo(Register Reg);
void MarkVirtRegAliveInBlock(VarInfo& VRInfo, MachineBasicBlock* DefBlock,
MachineBasicBlock *BB);
- void MarkVirtRegAliveInBlock(VarInfo &VRInfo, MachineBasicBlock *DefBlock,
+ void MarkVirtRegAliveInBlock(VarInfo &VRInfo, MachineBasicBlock *DefBlock,
MachineBasicBlock *BB,
- SmallVectorImpl<MachineBasicBlock *> &WorkList);
+ SmallVectorImpl<MachineBasicBlock *> &WorkList);
- void HandleVirtRegDef(Register reg, MachineInstr &MI);
- void HandleVirtRegUse(Register reg, MachineBasicBlock *MBB, MachineInstr &MI);
-
- bool isLiveIn(Register Reg, const MachineBasicBlock &MBB) {
+ void HandleVirtRegDef(Register reg, MachineInstr &MI);
+ void HandleVirtRegUse(Register reg, MachineBasicBlock *MBB, MachineInstr &MI);
+
+ bool isLiveIn(Register Reg, const MachineBasicBlock &MBB) {
return getVarInfo(Reg).isLiveIn(MBB, Reg, *MRI);
}
/// isLiveOut - Determine if Reg is live out from MBB, when not considering
/// PHI nodes. This means that Reg is either killed by a successor block or
/// passed through one.
- bool isLiveOut(Register Reg, const MachineBasicBlock &MBB);
+ bool isLiveOut(Register Reg, const MachineBasicBlock &MBB);
/// addNewBlock - Add a new basic block BB between DomBB and SuccBB. All
/// variables that are live out of DomBB and live into SuccBB will be marked
@@ -310,10 +310,10 @@ public:
std::vector<SparseBitVector<>> &LiveInSets);
/// isPHIJoin - Return true if Reg is a phi join register.
- bool isPHIJoin(Register Reg) { return PHIJoins.test(Reg.id()); }
+ bool isPHIJoin(Register Reg) { return PHIJoins.test(Reg.id()); }
/// setPHIJoin - Mark Reg as a phi join register.
- void setPHIJoin(Register Reg) { PHIJoins.set(Reg.id()); }
+ void setPHIJoin(Register Reg) { PHIJoins.set(Reg.id()); }
};
} // End llvm namespace
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/LowLevelType.h b/contrib/libs/llvm12/include/llvm/CodeGen/LowLevelType.h
index d6a9cde70d..4c0fa175cc 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/LowLevelType.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/LowLevelType.h
@@ -30,7 +30,7 @@ namespace llvm {
class DataLayout;
class Type;
-struct fltSemantics;
+struct fltSemantics;
/// Construct a low-level type based on an LLVM type.
LLT getLLTForType(Type &Ty, const DataLayout &DL);
@@ -43,9 +43,9 @@ MVT getMVTForLLT(LLT Ty);
/// scalarable vector types, and will assert if used.
LLT getLLTForMVT(MVT Ty);
-/// Get the appropriate floating point arithmetic semantic based on the bit size
-/// of the given scalar LLT.
-const llvm::fltSemantics &getFltSemanticForLLT(LLT Ty);
+/// Get the appropriate floating point arithmetic semantic based on the bit size
+/// of the given scalar LLT.
+const llvm::fltSemantics &getFltSemanticForLLT(LLT Ty);
}
#endif // LLVM_CODEGEN_LOWLEVELTYPE_H
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MBFIWrapper.h b/contrib/libs/llvm12/include/llvm/CodeGen/MBFIWrapper.h
index 5024dd83cd..aff14a6a8b 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MBFIWrapper.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MBFIWrapper.h
@@ -35,8 +35,8 @@ class MBFIWrapper {
BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const;
void setBlockFreq(const MachineBasicBlock *MBB, BlockFrequency F);
- Optional<uint64_t> getBlockProfileCount(const MachineBasicBlock *MBB) const;
-
+ Optional<uint64_t> getBlockProfileCount(const MachineBasicBlock *MBB) const;
+
raw_ostream &printBlockFreq(raw_ostream &OS,
const MachineBasicBlock *MBB) const;
raw_ostream &printBlockFreq(raw_ostream &OS,
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MIRFormatter.h b/contrib/libs/llvm12/include/llvm/CodeGen/MIRFormatter.h
index 0a8329c9a9..b6d11b3ffa 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MIRFormatter.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MIRFormatter.h
@@ -21,15 +21,15 @@
#ifndef LLVM_CODEGEN_MIRFORMATTER_H
#define LLVM_CODEGEN_MIRFORMATTER_H
-#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstdint>
+#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
namespace llvm {
-class MachineFunction;
-class MachineInstr;
+class MachineFunction;
+class MachineInstr;
struct PerFunctionMIParsingState;
struct SlotMapping;
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MIRYamlMapping.h b/contrib/libs/llvm12/include/llvm/CodeGen/MIRYamlMapping.h
index d774dec719..3cfd2837d6 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MIRYamlMapping.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MIRYamlMapping.h
@@ -166,22 +166,22 @@ template <> struct ScalarTraits<MaybeAlign> {
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
-template <> struct ScalarTraits<Align> {
- static void output(const Align &Alignment, void *, llvm::raw_ostream &OS) {
- OS << Alignment.value();
- }
- static StringRef input(StringRef Scalar, void *, Align &Alignment) {
- unsigned long long N;
- if (getAsUnsignedInteger(Scalar, 10, N))
- return "invalid number";
- if (!isPowerOf2_64(N))
- return "must be a power of two";
- Alignment = Align(N);
- return StringRef();
- }
- static QuotingType mustQuote(StringRef) { return QuotingType::None; }
-};
-
+template <> struct ScalarTraits<Align> {
+ static void output(const Align &Alignment, void *, llvm::raw_ostream &OS) {
+ OS << Alignment.value();
+ }
+ static StringRef input(StringRef Scalar, void *, Align &Alignment) {
+ unsigned long long N;
+ if (getAsUnsignedInteger(Scalar, 10, N))
+ return "invalid number";
+ if (!isPowerOf2_64(N))
+ return "must be a power of two";
+ Alignment = Align(N);
+ return StringRef();
+ }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
+};
+
} // end namespace yaml
} // end namespace llvm
@@ -354,7 +354,7 @@ struct ScalarEnumerationTraits<TargetStackID::Value> {
static void enumeration(yaml::IO &IO, TargetStackID::Value &ID) {
IO.enumCase(ID, "default", TargetStackID::Default);
IO.enumCase(ID, "sgpr-spill", TargetStackID::SGPRSpill);
- IO.enumCase(ID, "scalable-vector", TargetStackID::ScalableVector);
+ IO.enumCase(ID, "scalable-vector", TargetStackID::ScalableVector);
IO.enumCase(ID, "noalloc", TargetStackID::NoAlloc);
}
};
@@ -448,36 +448,36 @@ template <> struct MappingTraits<CallSiteInfo> {
static const bool flow = true;
};
-/// Serializable representation of debug value substitutions.
-struct DebugValueSubstitution {
- unsigned SrcInst;
- unsigned SrcOp;
- unsigned DstInst;
- unsigned DstOp;
-
- bool operator==(const DebugValueSubstitution &Other) const {
- return std::tie(SrcInst, SrcOp, DstInst, DstOp) ==
- std::tie(Other.SrcInst, Other.SrcOp, Other.DstInst, Other.DstOp);
- }
-};
-
-template <> struct MappingTraits<DebugValueSubstitution> {
- static void mapping(IO &YamlIO, DebugValueSubstitution &Sub) {
- YamlIO.mapRequired("srcinst", Sub.SrcInst);
- YamlIO.mapRequired("srcop", Sub.SrcOp);
- YamlIO.mapRequired("dstinst", Sub.DstInst);
- YamlIO.mapRequired("dstop", Sub.DstOp);
- }
-
- static const bool flow = true;
-};
-} // namespace yaml
-} // namespace llvm
-
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::DebugValueSubstitution)
-
-namespace llvm {
-namespace yaml {
+/// Serializable representation of debug value substitutions.
+struct DebugValueSubstitution {
+ unsigned SrcInst;
+ unsigned SrcOp;
+ unsigned DstInst;
+ unsigned DstOp;
+
+ bool operator==(const DebugValueSubstitution &Other) const {
+ return std::tie(SrcInst, SrcOp, DstInst, DstOp) ==
+ std::tie(Other.SrcInst, Other.SrcOp, Other.DstInst, Other.DstOp);
+ }
+};
+
+template <> struct MappingTraits<DebugValueSubstitution> {
+ static void mapping(IO &YamlIO, DebugValueSubstitution &Sub) {
+ YamlIO.mapRequired("srcinst", Sub.SrcInst);
+ YamlIO.mapRequired("srcop", Sub.SrcOp);
+ YamlIO.mapRequired("dstinst", Sub.DstInst);
+ YamlIO.mapRequired("dstop", Sub.DstOp);
+ }
+
+ static const bool flow = true;
+};
+} // namespace yaml
+} // namespace llvm
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::DebugValueSubstitution)
+
+namespace llvm {
+namespace yaml {
struct MachineConstantPoolValue {
UnsignedValue ID;
StringValue Value;
@@ -662,7 +662,7 @@ struct MachineFunction {
std::vector<MachineConstantPoolValue> Constants; /// Constant pool.
std::unique_ptr<MachineFunctionInfo> MachineFuncInfo;
std::vector<CallSiteInfo> CallSitesInfo;
- std::vector<DebugValueSubstitution> DebugValueSubstitutions;
+ std::vector<DebugValueSubstitution> DebugValueSubstitutions;
MachineJumpTable JumpTableInfo;
BlockStringValue Body;
};
@@ -691,8 +691,8 @@ template <> struct MappingTraits<MachineFunction> {
std::vector<MachineStackObject>());
YamlIO.mapOptional("callSites", MF.CallSitesInfo,
std::vector<CallSiteInfo>());
- YamlIO.mapOptional("debugValueSubstitutions", MF.DebugValueSubstitutions,
- std::vector<DebugValueSubstitution>());
+ YamlIO.mapOptional("debugValueSubstitutions", MF.DebugValueSubstitutions,
+ std::vector<DebugValueSubstitution>());
YamlIO.mapOptional("constants", MF.Constants,
std::vector<MachineConstantPoolValue>());
YamlIO.mapOptional("machineFunctionInfo", MF.MachineFuncInfo);
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineBasicBlock.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineBasicBlock.h
index c67ba05321..fb36c30de8 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineBasicBlock.h
@@ -47,7 +47,7 @@ class Printable;
class SlotIndexes;
class StringRef;
class raw_ostream;
-class LiveIntervals;
+class LiveIntervals;
class TargetRegisterClass;
class TargetRegisterInfo;
@@ -182,9 +182,9 @@ private:
/// is only computed once and is cached.
mutable MCSymbol *CachedMCSymbol = nullptr;
- /// Marks the end of the basic block. Used during basic block sections to
- /// calculate the size of the basic block, or the BB section ending with it.
- mutable MCSymbol *CachedEndMCSymbol = nullptr;
+ /// Marks the end of the basic block. Used during basic block sections to
+ /// calculate the size of the basic block, or the BB section ending with it.
+ mutable MCSymbol *CachedEndMCSymbol = nullptr;
// Intrusive list support
MachineBasicBlock() = default;
@@ -441,9 +441,9 @@ public:
bool hasEHPadSuccessor() const;
- /// Returns true if this is the entry block of the function.
- bool isEntryBlock() const;
-
+ /// Returns true if this is the entry block of the function.
+ bool isEntryBlock() 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; }
@@ -486,9 +486,9 @@ public:
/// Sets the section ID for this basic block.
void setSectionID(MBBSectionID V) { SectionID = V; }
- /// Returns the MCSymbol marking the end of this basic block.
- MCSymbol *getEndSymbol() const;
-
+ /// Returns the MCSymbol marking the end of this basic block.
+ MCSymbol *getEndSymbol() const;
+
/// Returns true if this block may have an INLINEASM_BR (overestimate, by
/// checking if any of the successors are indirect targets of any inlineasm_br
/// in the function).
@@ -686,17 +686,17 @@ public:
return !empty() && back().isEHScopeReturn();
}
- /// Split a basic block into 2 pieces at \p SplitPoint. A new block will be
- /// inserted after this block, and all instructions after \p SplitInst moved
- /// to it (\p SplitInst will be in the original block). If \p LIS is provided,
- /// LiveIntervals will be appropriately updated. \return the newly inserted
- /// block.
- ///
- /// If \p UpdateLiveIns is true, this will ensure the live ins list is
- /// accurate, including for physreg uses/defs in the original block.
- MachineBasicBlock *splitAt(MachineInstr &SplitInst, bool UpdateLiveIns = true,
- LiveIntervals *LIS = nullptr);
-
+ /// Split a basic block into 2 pieces at \p SplitPoint. A new block will be
+ /// inserted after this block, and all instructions after \p SplitInst moved
+ /// to it (\p SplitInst will be in the original block). If \p LIS is provided,
+ /// LiveIntervals will be appropriately updated. \return the newly inserted
+ /// block.
+ ///
+ /// If \p UpdateLiveIns is true, this will ensure the live ins list is
+ /// accurate, including for physreg uses/defs in the original block.
+ MachineBasicBlock *splitAt(MachineInstr &SplitInst, bool UpdateLiveIns = true,
+ LiveIntervals *LIS = nullptr);
+
/// Split the critical edge from this block to the given successor block, and
/// return the newly created block, or null if splitting is not possible.
///
@@ -898,14 +898,14 @@ public:
void print(raw_ostream &OS, ModuleSlotTracker &MST,
const SlotIndexes * = nullptr, bool IsStandalone = true) const;
- enum PrintNameFlag {
- PrintNameIr = (1 << 0), ///< Add IR name where available
- PrintNameAttributes = (1 << 1), ///< Print attributes
- };
-
- void printName(raw_ostream &os, unsigned printNameFlags = PrintNameIr,
- ModuleSlotTracker *moduleSlotTracker = nullptr) const;
-
+ enum PrintNameFlag {
+ PrintNameIr = (1 << 0), ///< Add IR name where available
+ PrintNameAttributes = (1 << 1), ///< Print attributes
+ };
+
+ void printName(raw_ostream &os, unsigned printNameFlags = PrintNameIr,
+ ModuleSlotTracker *moduleSlotTracker = nullptr) const;
+
// Printing method used by LoopInfo.
void printAsOperand(raw_ostream &OS, bool PrintType = true) const;
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineBlockFrequencyInfo.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
index 251f53ae45..d6a36181f6 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
@@ -65,33 +65,33 @@ public:
/// information. Please note that initial frequency is equal to 1024. It means
/// that we should not rely on the value itself, but only on the comparison to
/// the other block frequencies. We do this to avoid using of floating points.
- /// For example, to get the frequency of a block relative to the entry block,
- /// divide the integral value returned by this function (the
- /// BlockFrequency::getFrequency() value) by getEntryFreq().
+ /// For example, to get the frequency of a block relative to the entry block,
+ /// divide the integral value returned by this function (the
+ /// BlockFrequency::getFrequency() value) by getEntryFreq().
BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const;
- /// Compute the frequency of the block, relative to the entry block.
- /// This API assumes getEntryFreq() is non-zero.
- float getBlockFreqRelativeToEntryBlock(const MachineBasicBlock *MBB) const {
- return getBlockFreq(MBB).getFrequency() * (1.0f / getEntryFreq());
- }
-
+ /// Compute the frequency of the block, relative to the entry block.
+ /// This API assumes getEntryFreq() is non-zero.
+ float getBlockFreqRelativeToEntryBlock(const MachineBasicBlock *MBB) const {
+ return getBlockFreq(MBB).getFrequency() * (1.0f / getEntryFreq());
+ }
+
Optional<uint64_t> getBlockProfileCount(const MachineBasicBlock *MBB) const;
Optional<uint64_t> getProfileCountFromFreq(uint64_t Freq) const;
- bool isIrrLoopHeader(const MachineBasicBlock *MBB) const;
+ bool isIrrLoopHeader(const MachineBasicBlock *MBB) const;
- /// incrementally calculate block frequencies when we split edges, to avoid
- /// full CFG traversal.
- void onEdgeSplit(const MachineBasicBlock &NewPredecessor,
- const MachineBasicBlock &NewSuccessor,
- const MachineBranchProbabilityInfo &MBPI);
+ /// incrementally calculate block frequencies when we split edges, to avoid
+ /// full CFG traversal.
+ void onEdgeSplit(const MachineBasicBlock &NewPredecessor,
+ const MachineBasicBlock &NewSuccessor,
+ const MachineBranchProbabilityInfo &MBPI);
const MachineFunction *getFunction() const;
const MachineBranchProbabilityInfo *getMBPI() const;
-
- /// Pop up a ghostview window with the current block frequency propagation
- /// rendered using dot.
+
+ /// Pop up a ghostview window with the current block frequency propagation
+ /// rendered using dot.
void view(const Twine &Name, bool isSimple = true) const;
// Print the block frequency Freq to OS using the current functions entry
@@ -103,8 +103,8 @@ public:
raw_ostream &printBlockFreq(raw_ostream &OS,
const MachineBasicBlock *MBB) const;
- /// Divide a block's BlockFrequency::getFrequency() value by this value to
- /// obtain the entry block - relative frequency of said block.
+ /// Divide a block's BlockFrequency::getFrequency() value by this value to
+ /// obtain the entry block - relative frequency of said block.
uint64_t getEntryFreq() const;
};
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineCombinerPattern.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineCombinerPattern.h
index 7557deeb15..add0aaad21 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineCombinerPattern.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineCombinerPattern.h
@@ -36,11 +36,11 @@ enum class MachineCombinerPattern {
REASSOC_XY_AMM_BMM,
REASSOC_XMM_AMM_BMM,
- // These are patterns matched by the PowerPC to reassociate FMA and FSUB to
- // reduce register pressure.
- REASSOC_XY_BCA,
- REASSOC_XY_BAC,
-
+ // These are patterns matched by the PowerPC to reassociate FMA and FSUB to
+ // reduce register pressure.
+ REASSOC_XY_BCA,
+ REASSOC_XY_BAC,
+
// These are multiply-add patterns matched by the AArch64 machine combiner.
MULADDW_OP1,
MULADDW_OP2,
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineConstantPool.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineConstantPool.h
index fe4cb90b6b..6cd70f8609 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineConstantPool.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineConstantPool.h
@@ -50,8 +50,8 @@ public:
Type *getType() const { return Ty; }
- virtual unsigned getSizeInBytes(const DataLayout &DL) const;
-
+ virtual unsigned getSizeInBytes(const DataLayout &DL) const;
+
virtual int getExistingMachineCPValue(MachineConstantPool *CP,
Align Alignment) = 0;
@@ -101,7 +101,7 @@ public:
Align getAlign() const { return Alignment; }
- unsigned getSizeInBytes(const DataLayout &DL) const;
+ unsigned getSizeInBytes(const DataLayout &DL) const;
/// This method classifies the entry according to whether or not it may
/// generate a relocation entry. This must be conservative, so if it might
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineFrameInfo.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineFrameInfo.h
index c31e8ccfd2..6a9f911f96 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineFrameInfo.h
@@ -21,7 +21,7 @@
#define LLVM_CODEGEN_MACHINEFRAMEINFO_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/Register.h"
+#include "llvm/CodeGen/Register.h"
#include "llvm/Support/Alignment.h"
#include "llvm/Support/DataTypes.h"
#include <cassert>
@@ -39,7 +39,7 @@ class AllocaInst;
/// Callee saved reg can also be saved to a different register rather than
/// on the stack by setting DstReg instead of FrameIdx.
class CalleeSavedInfo {
- Register Reg;
+ Register Reg;
union {
int FrameIdx;
unsigned DstReg;
@@ -66,14 +66,14 @@ public:
: Reg(R), FrameIdx(FI), Restored(true), SpilledToReg(false) {}
// Accessors.
- Register getReg() const { return Reg; }
+ Register getReg() const { return Reg; }
int getFrameIdx() const { return FrameIdx; }
unsigned getDstReg() const { return DstReg; }
void setFrameIdx(int FI) {
FrameIdx = FI;
SpilledToReg = false;
}
- void setDstReg(Register SpillReg) {
+ void setDstReg(Register SpillReg) {
DstReg = SpillReg;
SpilledToReg = true;
}
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineFunction.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineFunction.h
index ff1e7dc302..8b89caedf6 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineFunction.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineFunction.h
@@ -438,39 +438,39 @@ public:
using VariableDbgInfoMapTy = SmallVector<VariableDbgInfo, 4>;
VariableDbgInfoMapTy VariableDbgInfos;
- /// A count of how many instructions in the function have had numbers
- /// assigned to them. Used for debug value tracking, to determine the
- /// next instruction number.
- unsigned DebugInstrNumberingCount = 0;
-
- /// Set value of DebugInstrNumberingCount field. Avoid using this unless
- /// you're deserializing this data.
- void setDebugInstrNumberingCount(unsigned Num);
-
- /// Pair of instruction number and operand number.
- using DebugInstrOperandPair = std::pair<unsigned, unsigned>;
-
- /// Substitution map: from one <inst,operand> pair to another. Used to
- /// record changes in where a value is defined, so that debug variable
- /// locations can find it later.
- std::map<DebugInstrOperandPair, DebugInstrOperandPair>
- DebugValueSubstitutions;
-
- /// Create a substitution between one <instr,operand> value to a different,
- /// new value.
- void makeDebugValueSubstitution(DebugInstrOperandPair, DebugInstrOperandPair);
-
- /// Create substitutions for any tracked values in \p Old, to point at
- /// \p New. Needed when we re-create an instruction during optimization,
- /// which has the same signature (i.e., def operands in the same place) but
- /// a modified instruction type, flags, or otherwise. An example: X86 moves
- /// are sometimes transformed into equivalent LEAs.
- /// If the two instructions are not the same opcode, limit which operands to
- /// examine for substitutions to the first N operands by setting
- /// \p MaxOperand.
- void substituteDebugValuesForInst(const MachineInstr &Old, MachineInstr &New,
- unsigned MaxOperand = UINT_MAX);
-
+ /// A count of how many instructions in the function have had numbers
+ /// assigned to them. Used for debug value tracking, to determine the
+ /// next instruction number.
+ unsigned DebugInstrNumberingCount = 0;
+
+ /// Set value of DebugInstrNumberingCount field. Avoid using this unless
+ /// you're deserializing this data.
+ void setDebugInstrNumberingCount(unsigned Num);
+
+ /// Pair of instruction number and operand number.
+ using DebugInstrOperandPair = std::pair<unsigned, unsigned>;
+
+ /// Substitution map: from one <inst,operand> pair to another. Used to
+ /// record changes in where a value is defined, so that debug variable
+ /// locations can find it later.
+ std::map<DebugInstrOperandPair, DebugInstrOperandPair>
+ DebugValueSubstitutions;
+
+ /// Create a substitution between one <instr,operand> value to a different,
+ /// new value.
+ void makeDebugValueSubstitution(DebugInstrOperandPair, DebugInstrOperandPair);
+
+ /// Create substitutions for any tracked values in \p Old, to point at
+ /// \p New. Needed when we re-create an instruction during optimization,
+ /// which has the same signature (i.e., def operands in the same place) but
+ /// a modified instruction type, flags, or otherwise. An example: X86 moves
+ /// are sometimes transformed into equivalent LEAs.
+ /// If the two instructions are not the same opcode, limit which operands to
+ /// examine for substitutions to the first N operands by setting
+ /// \p MaxOperand.
+ void substituteDebugValuesForInst(const MachineInstr &Old, MachineInstr &New,
+ unsigned MaxOperand = UINT_MAX);
+
MachineFunction(Function &F, const LLVMTargetMachine &Target,
const TargetSubtargetInfo &STI, unsigned FunctionNum,
MachineModuleInfo &MMI);
@@ -534,8 +534,8 @@ public:
/// Returns true if this function has basic block sections enabled.
bool hasBBSections() const {
return (BBSectionsType == BasicBlockSection::All ||
- BBSectionsType == BasicBlockSection::List ||
- BBSectionsType == BasicBlockSection::Preset);
+ BBSectionsType == BasicBlockSection::List ||
+ BBSectionsType == BasicBlockSection::Preset);
}
/// Returns true if basic block labels are to be generated for this function.
@@ -807,7 +807,7 @@ public:
/// CreateMachineInstr - Allocate a new MachineInstr. Use this instead
/// of `new MachineInstr'.
MachineInstr *CreateMachineInstr(const MCInstrDesc &MCID, const DebugLoc &DL,
- bool NoImplicit = false);
+ bool NoImplicit = false);
/// Create a new MachineInstr which is a copy of \p Orig, identical in all
/// ways except the instruction has no parent, prev, or next. Bundling flags
@@ -853,14 +853,14 @@ public:
MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
int64_t Offset, uint64_t Size);
- /// getMachineMemOperand - Allocate a new MachineMemOperand by copying
- /// an existing one, replacing only the MachinePointerInfo and size.
- /// MachineMemOperands are owned by the MachineFunction and need not be
- /// explicitly deallocated.
- MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
- MachinePointerInfo &PtrInfo,
- uint64_t Size);
-
+ /// getMachineMemOperand - Allocate a new MachineMemOperand by copying
+ /// an existing one, replacing only the MachinePointerInfo and size.
+ /// MachineMemOperands are owned by the MachineFunction and need not be
+ /// explicitly deallocated.
+ MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
+ MachinePointerInfo &PtrInfo,
+ uint64_t Size);
+
/// Allocate a new MachineMemOperand by copying an existing one,
/// replacing only AliasAnalysis information. MachineMemOperands are owned
/// by the MachineFunction and need not be explicitly deallocated.
@@ -1113,10 +1113,10 @@ public:
/// the same callee.
void moveCallSiteInfo(const MachineInstr *Old,
const MachineInstr *New);
-
- unsigned getNewDebugInstrNum() {
- return ++DebugInstrNumberingCount;
- }
+
+ unsigned getNewDebugInstrNum() {
+ return ++DebugInstrNumberingCount;
+ }
};
//===--------------------------------------------------------------------===//
@@ -1183,11 +1183,11 @@ template <> struct GraphTraits<Inverse<const MachineFunction*>> :
}
};
-class MachineFunctionAnalysisManager;
-void verifyMachineFunction(MachineFunctionAnalysisManager *,
- const std::string &Banner,
- const MachineFunction &MF);
-
+class MachineFunctionAnalysisManager;
+void verifyMachineFunction(MachineFunctionAnalysisManager *,
+ const std::string &Banner,
+ const MachineFunction &MF);
+
} // end namespace llvm
#endif // LLVM_CODEGEN_MACHINEFUNCTION_H
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineInstr.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineInstr.h
index 7dbbda8971..f0f53003c4 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineInstr.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineInstr.h
@@ -256,10 +256,10 @@ private:
DebugLoc debugLoc; // Source line information.
- /// Unique instruction number. Used by DBG_INSTR_REFs to refer to the values
- /// defined by this instruction.
- unsigned DebugInstrNum;
-
+ /// Unique instruction number. Used by DBG_INSTR_REFs to refer to the values
+ /// defined by this instruction.
+ unsigned DebugInstrNum;
+
// Intrusive list support
friend struct ilist_traits<MachineInstr>;
friend struct ilist_callback_traits<MachineBasicBlock>;
@@ -291,9 +291,9 @@ public:
const MachineBasicBlock* getParent() const { return Parent; }
MachineBasicBlock* getParent() { return Parent; }
- /// Move the instruction before \p MovePos.
- void moveBefore(MachineInstr *MovePos);
-
+ /// Move the instruction before \p MovePos.
+ void moveBefore(MachineInstr *MovePos);
+
/// Return the function that contains the basic block that this instruction
/// belongs to.
///
@@ -455,18 +455,18 @@ public:
/// this DBG_LABEL instruction.
const DILabel *getDebugLabel() const;
- /// Fetch the instruction number of this MachineInstr. If it does not have
- /// one already, a new and unique number will be assigned.
- unsigned getDebugInstrNum();
-
- /// Examine the instruction number of this MachineInstr. May be zero if
- /// it hasn't been assigned a number yet.
- unsigned peekDebugInstrNum() const { return DebugInstrNum; }
-
- /// Set instruction number of this MachineInstr. Avoid using unless you're
- /// deserializing this information.
- void setDebugInstrNum(unsigned Num) { DebugInstrNum = Num; }
-
+ /// Fetch the instruction number of this MachineInstr. If it does not have
+ /// one already, a new and unique number will be assigned.
+ unsigned getDebugInstrNum();
+
+ /// Examine the instruction number of this MachineInstr. May be zero if
+ /// it hasn't been assigned a number yet.
+ unsigned peekDebugInstrNum() const { return DebugInstrNum; }
+
+ /// Set instruction number of this MachineInstr. Avoid using unless you're
+ /// deserializing this information.
+ void setDebugInstrNum(unsigned Num) { DebugInstrNum = Num; }
+
/// 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
@@ -1163,22 +1163,22 @@ public:
return getOpcode() == TargetOpcode::CFI_INSTRUCTION;
}
- bool isPseudoProbe() const {
- return getOpcode() == TargetOpcode::PSEUDO_PROBE;
- }
-
+ bool isPseudoProbe() const {
+ return getOpcode() == TargetOpcode::PSEUDO_PROBE;
+ }
+
// True if the instruction represents a position in the function.
bool isPosition() const { return isLabel() || isCFIInstruction(); }
bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; }
bool isDebugLabel() const { return getOpcode() == TargetOpcode::DBG_LABEL; }
- bool isDebugRef() const { return getOpcode() == TargetOpcode::DBG_INSTR_REF; }
- bool isDebugInstr() const {
- return isDebugValue() || isDebugLabel() || isDebugRef();
- }
- bool isDebugOrPseudoInstr() const {
- return isDebugInstr() || isPseudoProbe();
- }
+ bool isDebugRef() const { return getOpcode() == TargetOpcode::DBG_INSTR_REF; }
+ bool isDebugInstr() const {
+ return isDebugValue() || isDebugLabel() || isDebugRef();
+ }
+ bool isDebugOrPseudoInstr() const {
+ return isDebugInstr() || isPseudoProbe();
+ }
bool isDebugOffsetImm() const { return getDebugOffset().isImm(); }
@@ -1271,11 +1271,11 @@ public:
case TargetOpcode::EH_LABEL:
case TargetOpcode::GC_LABEL:
case TargetOpcode::DBG_VALUE:
- case TargetOpcode::DBG_INSTR_REF:
+ case TargetOpcode::DBG_INSTR_REF:
case TargetOpcode::DBG_LABEL:
case TargetOpcode::LIFETIME_START:
case TargetOpcode::LIFETIME_END:
- case TargetOpcode::PSEUDO_PROBE:
+ case TargetOpcode::PSEUDO_PROBE:
return true;
}
}
@@ -1348,8 +1348,8 @@ public:
/// Return true if the MachineInstr modifies (fully define or partially
/// define) the specified register.
/// NOTE: It's ignoring subreg indices on virtual registers.
- bool modifiesRegister(Register Reg,
- const TargetRegisterInfo *TRI = nullptr) const {
+ bool modifiesRegister(Register Reg,
+ const TargetRegisterInfo *TRI = nullptr) const {
return findRegisterDefOperandIdx(Reg, false, true, TRI) != -1;
}
@@ -1800,10 +1800,10 @@ public:
void setDebugValueUndef() {
assert(isDebugValue() && "Must be a debug value instruction.");
for (MachineOperand &MO : debug_operands()) {
- if (MO.isReg()) {
+ if (MO.isReg()) {
MO.setReg(0);
- MO.setSubReg(0);
- }
+ MO.setSubReg(0);
+ }
}
}
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineInstrBuilder.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineInstrBuilder.h
index 0635b48655..61c44f8a01 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineInstrBuilder.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -47,30 +47,30 @@ class MDNode;
namespace RegState {
-enum {
- /// Register definition.
- Define = 0x2,
- /// Not emitted register (e.g. carry, or temporary result).
- Implicit = 0x4,
- /// The last use of a register.
- Kill = 0x8,
- /// Unused definition.
- Dead = 0x10,
- /// Value of the register doesn't matter.
- Undef = 0x20,
- /// Register definition happens before uses.
- EarlyClobber = 0x40,
- /// Register 'use' is for debugging purpose.
- Debug = 0x80,
- /// Register reads a value that is defined inside the same instruction or
- /// bundle.
- InternalRead = 0x100,
- /// Register that may be renamed.
- Renamable = 0x200,
- DefineNoRead = Define | Undef,
- ImplicitDefine = Implicit | Define,
- ImplicitKill = Implicit | Kill
-};
+enum {
+ /// Register definition.
+ Define = 0x2,
+ /// Not emitted register (e.g. carry, or temporary result).
+ Implicit = 0x4,
+ /// The last use of a register.
+ Kill = 0x8,
+ /// Unused definition.
+ Dead = 0x10,
+ /// Value of the register doesn't matter.
+ Undef = 0x20,
+ /// Register definition happens before uses.
+ EarlyClobber = 0x40,
+ /// Register 'use' is for debugging purpose.
+ Debug = 0x80,
+ /// Register reads a value that is defined inside the same instruction or
+ /// bundle.
+ InternalRead = 0x100,
+ /// Register that may be renamed.
+ Renamable = 0x200,
+ DefineNoRead = Define | Undef,
+ ImplicitDefine = Implicit | Define,
+ ImplicitKill = Implicit | Kill
+};
} // end namespace RegState
@@ -312,9 +312,9 @@ public:
case MachineOperand::MO_BlockAddress:
return addBlockAddress(Disp.getBlockAddress(), Disp.getOffset() + off,
TargetFlags);
- case MachineOperand::MO_JumpTableIndex:
- assert(off == 0 && "cannot create offset into jump tables");
- return addJumpTableIndex(Disp.getIndex(), TargetFlags);
+ case MachineOperand::MO_JumpTableIndex:
+ assert(off == 0 && "cannot create offset into jump tables");
+ return addJumpTableIndex(Disp.getIndex(), TargetFlags);
}
}
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineJumpTableInfo.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineJumpTableInfo.h
index 3aa5f2c3c3..0b13ed4891 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineJumpTableInfo.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineJumpTableInfo.h
@@ -113,9 +113,9 @@ public:
JumpTables[Idx].MBBs.clear();
}
- /// RemoveMBBFromJumpTables - If MBB is present in any jump tables, remove it.
- bool RemoveMBBFromJumpTables(MachineBasicBlock *MBB);
-
+ /// RemoveMBBFromJumpTables - If MBB is present in any jump tables, remove it.
+ bool RemoveMBBFromJumpTables(MachineBasicBlock *MBB);
+
/// ReplaceMBBInJumpTables - If Old is the target of any jump tables, update
/// the jump tables to branch to New instead.
bool ReplaceMBBInJumpTables(MachineBasicBlock *Old, MachineBasicBlock *New);
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineLoopInfo.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineLoopInfo.h
index 5d5b3ec63c..fbd203328c 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineLoopInfo.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineLoopInfo.h
@@ -74,12 +74,12 @@ public:
/// it returns an unknown location.
DebugLoc getStartLoc() const;
- /// Returns true if the instruction is loop invariant.
- /// I.e., all virtual register operands are defined outside of the loop,
- /// physical registers aren't accessed explicitly, and there are no side
- /// effects that aren't captured by the operands or other flags.
- bool isLoopInvariant(MachineInstr &I) const;
-
+ /// Returns true if the instruction is loop invariant.
+ /// I.e., all virtual register operands are defined outside of the loop,
+ /// physical registers aren't accessed explicitly, and there are no side
+ /// effects that aren't captured by the operands or other flags.
+ bool isLoopInvariant(MachineInstr &I) const;
+
void dump() const;
private:
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineModuleInfo.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineModuleInfo.h
index 585d9adfbc..b791e255b7 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineModuleInfo.h
@@ -61,8 +61,8 @@ class Module;
//===----------------------------------------------------------------------===//
/// This class can be derived from and used by targets to hold private
/// target-specific information for each Module. Objects of type are
-/// accessed/created with MachineModuleInfo::getObjFileInfo and destroyed when
-/// the MachineModuleInfo is destroyed.
+/// accessed/created with MachineModuleInfo::getObjFileInfo and destroyed when
+/// the MachineModuleInfo is destroyed.
///
class MachineModuleInfoImpl {
public:
@@ -90,9 +90,9 @@ class MachineModuleInfo {
/// This is the MCContext used for the entire code generator.
MCContext Context;
- // This is an external context, that if assigned, will be used instead of the
- // internal context.
- MCContext *ExternalContext = nullptr;
+ // This is an external context, that if assigned, will be used instead of the
+ // internal context.
+ MCContext *ExternalContext = nullptr;
/// This is the LLVM Module being worked on.
const Module *TheModule;
@@ -159,9 +159,9 @@ class MachineModuleInfo {
public:
explicit MachineModuleInfo(const LLVMTargetMachine *TM = nullptr);
- explicit MachineModuleInfo(const LLVMTargetMachine *TM,
- MCContext *ExtContext);
-
+ explicit MachineModuleInfo(const LLVMTargetMachine *TM,
+ MCContext *ExtContext);
+
MachineModuleInfo(MachineModuleInfo &&MMII);
~MachineModuleInfo();
@@ -171,12 +171,12 @@ public:
const LLVMTargetMachine &getTarget() const { return TM; }
- const MCContext &getContext() const {
- return ExternalContext ? *ExternalContext : Context;
- }
- MCContext &getContext() {
- return ExternalContext ? *ExternalContext : Context;
- }
+ const MCContext &getContext() const {
+ return ExternalContext ? *ExternalContext : Context;
+ }
+ MCContext &getContext() {
+ return ExternalContext ? *ExternalContext : Context;
+ }
const Module *getModule() const { return TheModule; }
@@ -268,12 +268,12 @@ public:
return Personalities;
}
/// \}
-
- // MMI owes MCContext. It should never be invalidated.
- bool invalidate(Module &, const PreservedAnalyses &,
- ModuleAnalysisManager::Invalidator &) {
- return false;
- }
+
+ // MMI owes MCContext. It should never be invalidated.
+ bool invalidate(Module &, const PreservedAnalyses &,
+ ModuleAnalysisManager::Invalidator &) {
+ return false;
+ }
}; // End class MachineModuleInfo
class MachineModuleInfoWrapperPass : public ImmutablePass {
@@ -283,9 +283,9 @@ public:
static char ID; // Pass identification, replacement for typeid
explicit MachineModuleInfoWrapperPass(const LLVMTargetMachine *TM = nullptr);
- explicit MachineModuleInfoWrapperPass(const LLVMTargetMachine *TM,
- MCContext *ExtContext);
-
+ explicit MachineModuleInfoWrapperPass(const LLVMTargetMachine *TM,
+ MCContext *ExtContext);
+
// Initialization and Finalization
bool doInitialization(Module &) override;
bool doFinalization(Module &) override;
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineOperand.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineOperand.h
index ad3c11b1f1..d5ea31a6cd 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineOperand.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineOperand.h
@@ -734,12 +734,12 @@ public:
/// ChangeToImmediate - Replace this operand with a new immediate operand of
/// the specified value. If an operand is known to be an immediate already,
/// the setImm method should be used.
- void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags = 0);
+ void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags = 0);
/// ChangeToFPImmediate - Replace this operand with a new FP immediate operand
/// of the specified value. If an operand is known to be an FP immediate
/// already, the setFPImm method should be used.
- void ChangeToFPImmediate(const ConstantFP *FPImm, unsigned TargetFlags = 0);
+ void ChangeToFPImmediate(const ConstantFP *FPImm, unsigned TargetFlags = 0);
/// ChangeToES - Replace this operand with a new external symbol operand.
void ChangeToES(const char *SymName, unsigned TargetFlags = 0);
@@ -749,10 +749,10 @@ public:
unsigned TargetFlags = 0);
/// ChangeToMCSymbol - Replace this operand with a new MC symbol operand.
- void ChangeToMCSymbol(MCSymbol *Sym, unsigned TargetFlags = 0);
+ void ChangeToMCSymbol(MCSymbol *Sym, unsigned TargetFlags = 0);
/// Replace this operand with a frame index.
- void ChangeToFrameIndex(int Idx, unsigned TargetFlags = 0);
+ void ChangeToFrameIndex(int Idx, unsigned TargetFlags = 0);
/// Replace this operand with a target index.
void ChangeToTargetIndex(unsigned Idx, int64_t Offset,
@@ -765,11 +765,11 @@ public:
bool isKill = false, bool isDead = false,
bool isUndef = false, bool isDebug = false);
- /// getTargetIndexName - If this MachineOperand is a TargetIndex that has a
- /// name, attempt to get the name. Returns nullptr if the TargetIndex does not
- /// have a name. Asserts if MO is not a TargetIndex.
- const char *getTargetIndexName() const;
-
+ /// getTargetIndexName - If this MachineOperand is a TargetIndex that has a
+ /// name, attempt to get the name. Returns nullptr if the TargetIndex does not
+ /// have a name. Asserts if MO is not a TargetIndex.
+ const char *getTargetIndexName() const;
+
//===--------------------------------------------------------------------===//
// Construction methods.
//===--------------------------------------------------------------------===//
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineOutliner.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineOutliner.h
index e39090728f..ebe91415af 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineOutliner.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineOutliner.h
@@ -22,10 +22,10 @@
#ifndef LLVM_MACHINEOUTLINER_H
#define LLVM_MACHINEOUTLINER_H
-#include "llvm/CodeGen/LivePhysRegs.h"
+#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/LiveRegUnits.h"
#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
namespace llvm {
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachinePassManager.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachinePassManager.h
index efb51b1d77..d9cb20d0de 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachinePassManager.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachinePassManager.h
@@ -1,267 +1,267 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- PassManager.h --- Pass management for CodeGen ------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This header defines the pass manager interface for codegen. The codegen
-// pipeline consists of only machine function passes. There is no container
-// relationship between IR module/function and machine function in terms of pass
-// manager organization. So there is no need for adaptor classes (for example
-// ModuleToMachineFunctionAdaptor). Since invalidation could only happen among
-// machine function passes, there is no proxy classes to handle cross-IR-unit
-// invalidation. IR analysis results are provided for machine function passes by
-// their respective analysis managers such as ModuleAnalysisManager and
-// FunctionAnalysisManager.
-//
-// TODO: Add MachineFunctionProperties support.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_MACHINEPASSMANAGER_H
-#define LLVM_CODEGEN_MACHINEPASSMANAGER_H
-
-#include "llvm/ADT/FunctionExtras.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/IR/PassManager.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/type_traits.h"
-
-namespace llvm {
-class Module;
-
-extern template class AnalysisManager<MachineFunction>;
-
-/// An AnalysisManager<MachineFunction> that also exposes IR analysis results.
-class MachineFunctionAnalysisManager : public AnalysisManager<MachineFunction> {
-public:
- using Base = AnalysisManager<MachineFunction>;
-
- MachineFunctionAnalysisManager() : Base(false), FAM(nullptr), MAM(nullptr) {}
- MachineFunctionAnalysisManager(FunctionAnalysisManager &FAM,
- ModuleAnalysisManager &MAM,
- bool DebugLogging = false)
- : Base(DebugLogging), FAM(&FAM), MAM(&MAM) {}
- MachineFunctionAnalysisManager(MachineFunctionAnalysisManager &&) = default;
- MachineFunctionAnalysisManager &
- operator=(MachineFunctionAnalysisManager &&) = default;
-
- /// Get the result of an analysis pass for a Function.
- ///
- /// Runs the analysis if a cached result is not available.
- template <typename PassT> typename PassT::Result &getResult(Function &F) {
- return FAM->getResult<PassT>(F);
- }
-
- /// Get the cached result of an analysis pass for a Function.
- ///
- /// This method never runs the analysis.
- ///
- /// \returns null if there is no cached result.
- template <typename PassT>
- typename PassT::Result *getCachedResult(Function &F) {
- return FAM->getCachedResult<PassT>(F);
- }
-
- /// Get the result of an analysis pass for a Module.
- ///
- /// Runs the analysis if a cached result is not available.
- template <typename PassT> typename PassT::Result &getResult(Module &M) {
- return MAM->getResult<PassT>(M);
- }
-
- /// Get the cached result of an analysis pass for a Module.
- ///
- /// This method never runs the analysis.
- ///
- /// \returns null if there is no cached result.
- template <typename PassT> typename PassT::Result *getCachedResult(Module &M) {
- return MAM->getCachedResult<PassT>(M);
- }
-
- /// Get the result of an analysis pass for a MachineFunction.
- ///
- /// Runs the analysis if a cached result is not available.
- using Base::getResult;
-
- /// Get the cached result of an analysis pass for a MachineFunction.
- ///
- /// This method never runs the analysis.
- ///
- /// returns null if there is no cached result.
- using Base::getCachedResult;
-
- // FIXME: Add LoopAnalysisManager or CGSCCAnalysisManager if needed.
- FunctionAnalysisManager *FAM;
- ModuleAnalysisManager *MAM;
-};
-
-extern template class PassManager<MachineFunction>;
-
-/// MachineFunctionPassManager adds/removes below features to/from the base
-/// PassManager template instantiation.
-///
-/// - Support passes that implement doInitialization/doFinalization. This is for
-/// machine function passes to work on module level constructs. One such pass
-/// is AsmPrinter.
-///
-/// - Support machine module pass which runs over the module (for example,
-/// MachineOutliner). A machine module pass needs to define the method:
-///
-/// ```Error run(Module &, MachineFunctionAnalysisManager &)```
-///
-/// FIXME: machine module passes still need to define the usual machine
-/// function pass interface, namely,
-/// `PreservedAnalyses run(MachineFunction &,
-/// MachineFunctionAnalysisManager &)`
-/// But this interface wouldn't be executed. It is just a placeholder
-/// to satisfy the pass manager type-erased inteface. This
-/// special-casing of machine module pass is due to its limited use
-/// cases and the unnecessary complexity it may bring to the machine
-/// pass manager.
-///
-/// - The base class `run` method is replaced by an alternative `run` method.
-/// See details below.
-///
-/// - Support codegening in the SCC order. Users include interprocedural
-/// register allocation (IPRA).
-class MachineFunctionPassManager
- : public PassManager<MachineFunction, MachineFunctionAnalysisManager> {
- using Base = PassManager<MachineFunction, MachineFunctionAnalysisManager>;
-
-public:
- MachineFunctionPassManager(bool DebugLogging = false,
- bool RequireCodeGenSCCOrder = false,
- bool VerifyMachineFunction = false)
- : Base(DebugLogging), RequireCodeGenSCCOrder(RequireCodeGenSCCOrder),
- VerifyMachineFunction(VerifyMachineFunction) {}
- MachineFunctionPassManager(MachineFunctionPassManager &&) = default;
- MachineFunctionPassManager &
- operator=(MachineFunctionPassManager &&) = default;
-
- /// Run machine passes for a Module.
- ///
- /// The intended use is to start the codegen pipeline for a Module. The base
- /// class's `run` method is deliberately hidden by this due to the observation
- /// that we don't yet have the use cases of compositing two instances of
- /// machine pass managers, or compositing machine pass managers with other
- /// types of pass managers.
- Error run(Module &M, MachineFunctionAnalysisManager &MFAM);
-
- template <typename PassT> void addPass(PassT &&Pass) {
- Base::addPass(std::forward<PassT>(Pass));
- PassConceptT *P = Passes.back().get();
- addDoInitialization<PassT>(P);
- addDoFinalization<PassT>(P);
-
- // Add machine module pass.
- addRunOnModule<PassT>(P);
- }
-
-private:
- template <typename PassT>
- using has_init_t = decltype(std::declval<PassT &>().doInitialization(
- std::declval<Module &>(),
- std::declval<MachineFunctionAnalysisManager &>()));
-
- template <typename PassT>
- std::enable_if_t<!is_detected<has_init_t, PassT>::value>
- addDoInitialization(PassConceptT *Pass) {}
-
- template <typename PassT>
- std::enable_if_t<is_detected<has_init_t, PassT>::value>
- addDoInitialization(PassConceptT *Pass) {
- using PassModelT =
- detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
- MachineFunctionAnalysisManager>;
- auto *P = static_cast<PassModelT *>(Pass);
- InitializationFuncs.emplace_back(
- [=](Module &M, MachineFunctionAnalysisManager &MFAM) {
- return P->Pass.doInitialization(M, MFAM);
- });
- }
-
- template <typename PassT>
- using has_fini_t = decltype(std::declval<PassT &>().doFinalization(
- std::declval<Module &>(),
- std::declval<MachineFunctionAnalysisManager &>()));
-
- template <typename PassT>
- std::enable_if_t<!is_detected<has_fini_t, PassT>::value>
- addDoFinalization(PassConceptT *Pass) {}
-
- template <typename PassT>
- std::enable_if_t<is_detected<has_fini_t, PassT>::value>
- addDoFinalization(PassConceptT *Pass) {
- using PassModelT =
- detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
- MachineFunctionAnalysisManager>;
- auto *P = static_cast<PassModelT *>(Pass);
- FinalizationFuncs.emplace_back(
- [=](Module &M, MachineFunctionAnalysisManager &MFAM) {
- return P->Pass.doFinalization(M, MFAM);
- });
- }
-
- template <typename PassT>
- using is_machine_module_pass_t = decltype(std::declval<PassT &>().run(
- std::declval<Module &>(),
- std::declval<MachineFunctionAnalysisManager &>()));
-
- template <typename PassT>
- using is_machine_function_pass_t = decltype(std::declval<PassT &>().run(
- std::declval<MachineFunction &>(),
- std::declval<MachineFunctionAnalysisManager &>()));
-
- template <typename PassT>
- std::enable_if_t<!is_detected<is_machine_module_pass_t, PassT>::value>
- addRunOnModule(PassConceptT *Pass) {}
-
- template <typename PassT>
- std::enable_if_t<is_detected<is_machine_module_pass_t, PassT>::value>
- addRunOnModule(PassConceptT *Pass) {
- static_assert(is_detected<is_machine_function_pass_t, PassT>::value,
- "machine module pass needs to define machine function pass "
- "api. sorry.");
-
- using PassModelT =
- detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
- MachineFunctionAnalysisManager>;
- auto *P = static_cast<PassModelT *>(Pass);
- MachineModulePasses.emplace(
- Passes.size() - 1,
- [=](Module &M, MachineFunctionAnalysisManager &MFAM) {
- return P->Pass.run(M, MFAM);
- });
- }
-
- using FuncTy = Error(Module &, MachineFunctionAnalysisManager &);
- SmallVector<llvm::unique_function<FuncTy>, 4> InitializationFuncs;
- SmallVector<llvm::unique_function<FuncTy>, 4> FinalizationFuncs;
-
- using PassIndex = decltype(Passes)::size_type;
- std::map<PassIndex, llvm::unique_function<FuncTy>> MachineModulePasses;
-
- // Run codegen in the SCC order.
- bool RequireCodeGenSCCOrder;
-
- bool VerifyMachineFunction;
-};
-
-} // end namespace llvm
-
-#endif // LLVM_CODEGEN_MACHINEPASSMANAGER_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- PassManager.h --- Pass management for CodeGen ------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines the pass manager interface for codegen. The codegen
+// pipeline consists of only machine function passes. There is no container
+// relationship between IR module/function and machine function in terms of pass
+// manager organization. So there is no need for adaptor classes (for example
+// ModuleToMachineFunctionAdaptor). Since invalidation could only happen among
+// machine function passes, there is no proxy classes to handle cross-IR-unit
+// invalidation. IR analysis results are provided for machine function passes by
+// their respective analysis managers such as ModuleAnalysisManager and
+// FunctionAnalysisManager.
+//
+// TODO: Add MachineFunctionProperties support.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEPASSMANAGER_H
+#define LLVM_CODEGEN_MACHINEPASSMANAGER_H
+
+#include "llvm/ADT/FunctionExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/type_traits.h"
+
+namespace llvm {
+class Module;
+
+extern template class AnalysisManager<MachineFunction>;
+
+/// An AnalysisManager<MachineFunction> that also exposes IR analysis results.
+class MachineFunctionAnalysisManager : public AnalysisManager<MachineFunction> {
+public:
+ using Base = AnalysisManager<MachineFunction>;
+
+ MachineFunctionAnalysisManager() : Base(false), FAM(nullptr), MAM(nullptr) {}
+ MachineFunctionAnalysisManager(FunctionAnalysisManager &FAM,
+ ModuleAnalysisManager &MAM,
+ bool DebugLogging = false)
+ : Base(DebugLogging), FAM(&FAM), MAM(&MAM) {}
+ MachineFunctionAnalysisManager(MachineFunctionAnalysisManager &&) = default;
+ MachineFunctionAnalysisManager &
+ operator=(MachineFunctionAnalysisManager &&) = default;
+
+ /// Get the result of an analysis pass for a Function.
+ ///
+ /// Runs the analysis if a cached result is not available.
+ template <typename PassT> typename PassT::Result &getResult(Function &F) {
+ return FAM->getResult<PassT>(F);
+ }
+
+ /// Get the cached result of an analysis pass for a Function.
+ ///
+ /// This method never runs the analysis.
+ ///
+ /// \returns null if there is no cached result.
+ template <typename PassT>
+ typename PassT::Result *getCachedResult(Function &F) {
+ return FAM->getCachedResult<PassT>(F);
+ }
+
+ /// Get the result of an analysis pass for a Module.
+ ///
+ /// Runs the analysis if a cached result is not available.
+ template <typename PassT> typename PassT::Result &getResult(Module &M) {
+ return MAM->getResult<PassT>(M);
+ }
+
+ /// Get the cached result of an analysis pass for a Module.
+ ///
+ /// This method never runs the analysis.
+ ///
+ /// \returns null if there is no cached result.
+ template <typename PassT> typename PassT::Result *getCachedResult(Module &M) {
+ return MAM->getCachedResult<PassT>(M);
+ }
+
+ /// Get the result of an analysis pass for a MachineFunction.
+ ///
+ /// Runs the analysis if a cached result is not available.
+ using Base::getResult;
+
+ /// Get the cached result of an analysis pass for a MachineFunction.
+ ///
+ /// This method never runs the analysis.
+ ///
+ /// returns null if there is no cached result.
+ using Base::getCachedResult;
+
+ // FIXME: Add LoopAnalysisManager or CGSCCAnalysisManager if needed.
+ FunctionAnalysisManager *FAM;
+ ModuleAnalysisManager *MAM;
+};
+
+extern template class PassManager<MachineFunction>;
+
+/// MachineFunctionPassManager adds/removes below features to/from the base
+/// PassManager template instantiation.
+///
+/// - Support passes that implement doInitialization/doFinalization. This is for
+/// machine function passes to work on module level constructs. One such pass
+/// is AsmPrinter.
+///
+/// - Support machine module pass which runs over the module (for example,
+/// MachineOutliner). A machine module pass needs to define the method:
+///
+/// ```Error run(Module &, MachineFunctionAnalysisManager &)```
+///
+/// FIXME: machine module passes still need to define the usual machine
+/// function pass interface, namely,
+/// `PreservedAnalyses run(MachineFunction &,
+/// MachineFunctionAnalysisManager &)`
+/// But this interface wouldn't be executed. It is just a placeholder
+/// to satisfy the pass manager type-erased inteface. This
+/// special-casing of machine module pass is due to its limited use
+/// cases and the unnecessary complexity it may bring to the machine
+/// pass manager.
+///
+/// - The base class `run` method is replaced by an alternative `run` method.
+/// See details below.
+///
+/// - Support codegening in the SCC order. Users include interprocedural
+/// register allocation (IPRA).
+class MachineFunctionPassManager
+ : public PassManager<MachineFunction, MachineFunctionAnalysisManager> {
+ using Base = PassManager<MachineFunction, MachineFunctionAnalysisManager>;
+
+public:
+ MachineFunctionPassManager(bool DebugLogging = false,
+ bool RequireCodeGenSCCOrder = false,
+ bool VerifyMachineFunction = false)
+ : Base(DebugLogging), RequireCodeGenSCCOrder(RequireCodeGenSCCOrder),
+ VerifyMachineFunction(VerifyMachineFunction) {}
+ MachineFunctionPassManager(MachineFunctionPassManager &&) = default;
+ MachineFunctionPassManager &
+ operator=(MachineFunctionPassManager &&) = default;
+
+ /// Run machine passes for a Module.
+ ///
+ /// The intended use is to start the codegen pipeline for a Module. The base
+ /// class's `run` method is deliberately hidden by this due to the observation
+ /// that we don't yet have the use cases of compositing two instances of
+ /// machine pass managers, or compositing machine pass managers with other
+ /// types of pass managers.
+ Error run(Module &M, MachineFunctionAnalysisManager &MFAM);
+
+ template <typename PassT> void addPass(PassT &&Pass) {
+ Base::addPass(std::forward<PassT>(Pass));
+ PassConceptT *P = Passes.back().get();
+ addDoInitialization<PassT>(P);
+ addDoFinalization<PassT>(P);
+
+ // Add machine module pass.
+ addRunOnModule<PassT>(P);
+ }
+
+private:
+ template <typename PassT>
+ using has_init_t = decltype(std::declval<PassT &>().doInitialization(
+ std::declval<Module &>(),
+ std::declval<MachineFunctionAnalysisManager &>()));
+
+ template <typename PassT>
+ std::enable_if_t<!is_detected<has_init_t, PassT>::value>
+ addDoInitialization(PassConceptT *Pass) {}
+
+ template <typename PassT>
+ std::enable_if_t<is_detected<has_init_t, PassT>::value>
+ addDoInitialization(PassConceptT *Pass) {
+ using PassModelT =
+ detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
+ MachineFunctionAnalysisManager>;
+ auto *P = static_cast<PassModelT *>(Pass);
+ InitializationFuncs.emplace_back(
+ [=](Module &M, MachineFunctionAnalysisManager &MFAM) {
+ return P->Pass.doInitialization(M, MFAM);
+ });
+ }
+
+ template <typename PassT>
+ using has_fini_t = decltype(std::declval<PassT &>().doFinalization(
+ std::declval<Module &>(),
+ std::declval<MachineFunctionAnalysisManager &>()));
+
+ template <typename PassT>
+ std::enable_if_t<!is_detected<has_fini_t, PassT>::value>
+ addDoFinalization(PassConceptT *Pass) {}
+
+ template <typename PassT>
+ std::enable_if_t<is_detected<has_fini_t, PassT>::value>
+ addDoFinalization(PassConceptT *Pass) {
+ using PassModelT =
+ detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
+ MachineFunctionAnalysisManager>;
+ auto *P = static_cast<PassModelT *>(Pass);
+ FinalizationFuncs.emplace_back(
+ [=](Module &M, MachineFunctionAnalysisManager &MFAM) {
+ return P->Pass.doFinalization(M, MFAM);
+ });
+ }
+
+ template <typename PassT>
+ using is_machine_module_pass_t = decltype(std::declval<PassT &>().run(
+ std::declval<Module &>(),
+ std::declval<MachineFunctionAnalysisManager &>()));
+
+ template <typename PassT>
+ using is_machine_function_pass_t = decltype(std::declval<PassT &>().run(
+ std::declval<MachineFunction &>(),
+ std::declval<MachineFunctionAnalysisManager &>()));
+
+ template <typename PassT>
+ std::enable_if_t<!is_detected<is_machine_module_pass_t, PassT>::value>
+ addRunOnModule(PassConceptT *Pass) {}
+
+ template <typename PassT>
+ std::enable_if_t<is_detected<is_machine_module_pass_t, PassT>::value>
+ addRunOnModule(PassConceptT *Pass) {
+ static_assert(is_detected<is_machine_function_pass_t, PassT>::value,
+ "machine module pass needs to define machine function pass "
+ "api. sorry.");
+
+ using PassModelT =
+ detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
+ MachineFunctionAnalysisManager>;
+ auto *P = static_cast<PassModelT *>(Pass);
+ MachineModulePasses.emplace(
+ Passes.size() - 1,
+ [=](Module &M, MachineFunctionAnalysisManager &MFAM) {
+ return P->Pass.run(M, MFAM);
+ });
+ }
+
+ using FuncTy = Error(Module &, MachineFunctionAnalysisManager &);
+ SmallVector<llvm::unique_function<FuncTy>, 4> InitializationFuncs;
+ SmallVector<llvm::unique_function<FuncTy>, 4> FinalizationFuncs;
+
+ using PassIndex = decltype(Passes)::size_type;
+ std::map<PassIndex, llvm::unique_function<FuncTy>> MachineModulePasses;
+
+ // Run codegen in the SCC order.
+ bool RequireCodeGenSCCOrder;
+
+ bool VerifyMachineFunction;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_MACHINEPASSMANAGER_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachinePassRegistry.def b/contrib/libs/llvm12/include/llvm/CodeGen/MachinePassRegistry.def
index da969ba6be..e9eaa5f770 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachinePassRegistry.def
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachinePassRegistry.def
@@ -1,197 +1,197 @@
-//===- MachinePassRegistry.def - Registry of passes -------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is used as the registry of passes that are for target-independent
-// code generator.
-//
-//===----------------------------------------------------------------------===//
-
-// NOTE: NO INCLUDE GUARD DESIRED!
-
-#ifndef MODULE_ANALYSIS
-#define MODULE_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)
-#endif
-MODULE_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis, (PIC))
-#undef MODULE_ANALYSIS
-
-#ifndef MODULE_PASS
-#define MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)
-#endif
-MODULE_PASS("pre-isel-intrinsic-lowering", PreISelIntrinsicLoweringPass, ())
-#undef MODULE_PASS
-
-#ifndef FUNCTION_ANALYSIS
-#define FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)
-#endif
-FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis, (PIC))
-FUNCTION_ANALYSIS("targetir", TargetIRAnalysis, (std::move(TM.getTargetIRAnalysis())))
-#undef FUNCTION_ANALYSIS
-
-#ifndef FUNCTION_PASS
-#define FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
-#endif
-FUNCTION_PASS("mergeicmps", MergeICmpsPass, ())
-FUNCTION_PASS("lower-constant-intrinsics", LowerConstantIntrinsicsPass, ())
-FUNCTION_PASS("unreachableblockelim", UnreachableBlockElimPass, ())
-FUNCTION_PASS("consthoist", ConstantHoistingPass, ())
-FUNCTION_PASS("partially-inline-libcalls", PartiallyInlineLibCallsPass, ())
-FUNCTION_PASS("ee-instrument", EntryExitInstrumenterPass, (false))
-FUNCTION_PASS("post-inline-ee-instrument", EntryExitInstrumenterPass, (true))
-FUNCTION_PASS("expand-reductions", ExpandReductionsPass, ())
-FUNCTION_PASS("lowerinvoke", LowerInvokePass, ())
-FUNCTION_PASS("scalarize-masked-mem-intrin", ScalarizeMaskedMemIntrinPass, ())
-FUNCTION_PASS("verify", VerifierPass, ())
-#undef FUNCTION_PASS
-
-#ifndef LOOP_PASS
-#define LOOP_PASS(NAME, PASS_NAME, CONSTRUCTOR)
-#endif
-LOOP_PASS("loop-reduce", LoopStrengthReducePass, ())
-#undef LOOP_PASS
-
-#ifndef MACHINE_MODULE_PASS
-#define MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)
-#endif
-#undef MACHINE_MODULE_PASS
-
-#ifndef MACHINE_FUNCTION_ANALYSIS
-#define MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)
-#endif
-MACHINE_FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis, (PIC))
-// LiveVariables currently requires pure SSA form.
-// FIXME: Once TwoAddressInstruction pass no longer uses kill flags,
-// LiveVariables can be removed completely, and LiveIntervals can be directly
-// computed. (We still either need to regenerate kill flags after regalloc, or
-// preferably fix the scavenger to not depend on them).
-// MACHINE_FUNCTION_ANALYSIS("live-vars", LiveVariablesAnalysis())
-
-// MACHINE_FUNCTION_ANALYSIS("live-stacks", LiveStacksPass())
-// MACHINE_FUNCTION_ANALYSIS("slot-indexes", SlotIndexesAnalysis())
-// MACHINE_FUNCTION_ANALYSIS("edge-bundles", EdgeBundlesAnalysis())
-// MACHINE_FUNCTION_ANALYSIS("lazy-machine-bfi", LazyMachineBlockFrequencyInfoAnalysis())
-// MACHINE_FUNCTION_ANALYSIS("machine-bfi", MachineBlockFrequencyInfoAnalysis())
-// MACHINE_FUNCTION_ANALYSIS("machine-loops", MachineLoopInfoAnalysis())
-// MACHINE_FUNCTION_ANALYSIS("machine-dom-frontier", MachineDominanceFrontierAnalysis())
-// MACHINE_FUNCTION_ANALYSIS("machine-dom-tree", MachineDominatorTreeAnalysis())
-// MACHINE_FUNCTION_ANALYSIS("machine-ore", MachineOptimizationRemarkEmitterPassAnalysis())
-// MACHINE_FUNCTION_ANALYSIS("machine-post-dom-tree", MachinePostDominatorTreeAnalysis())
-// MACHINE_FUNCTION_ANALYSIS("machine-region-info", MachineRegionInfoPassAnalysis())
-// MACHINE_FUNCTION_ANALYSIS("machine-trace-metrics", MachineTraceMetricsAnalysis())
-// MACHINE_FUNCTION_ANALYSIS("reaching-def", ReachingDefAnalysisAnalysis())
-// MACHINE_FUNCTION_ANALYSIS("live-reg-matrix", LiveRegMatrixAnalysis())
-// MACHINE_FUNCTION_ANALYSIS("gc-analysis", GCMachineCodeAnalysisPass())
-#undef MACHINE_FUNCTION_ANALYSIS
-
-#ifndef MACHINE_FUNCTION_PASS
-#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
-#endif
-// MACHINE_FUNCTION_PASS("mir-printer", PrintMIRPass, ())
-// MACHINE_FUNCTION_PASS("free-machine-function", FreeMachineFunctionPass, ())
-#undef MACHINE_FUNCTION_PASS
-
-// After a pass is converted to new pass manager, its entry should be moved from
-// dummy table to the normal one. For example, for a machine function pass,
-// DUMMY_MACHINE_FUNCTION_PASS to MACHINE_FUNCTION_PASS.
-
-#ifndef DUMMY_FUNCTION_PASS
-#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
-#endif
-DUMMY_FUNCTION_PASS("expandmemcmp", ExpandMemCmpPass, ())
-DUMMY_FUNCTION_PASS("gc-lowering", GCLoweringPass, ())
-DUMMY_FUNCTION_PASS("shadow-stack-gc-lowering", ShadowStackGCLoweringPass, ())
-DUMMY_FUNCTION_PASS("sjljehprepare", SjLjEHPreparePass, ())
-DUMMY_FUNCTION_PASS("dwarfehprepare", DwarfEHPass, ())
-DUMMY_FUNCTION_PASS("winehprepare", WinEHPass, ())
-DUMMY_FUNCTION_PASS("wasmehprepare", WasmEHPass, ())
-DUMMY_FUNCTION_PASS("codegenprepare", CodeGenPreparePass, ())
-DUMMY_FUNCTION_PASS("safe-stack", SafeStackPass, ())
-DUMMY_FUNCTION_PASS("stack-protector", StackProtectorPass, ())
-DUMMY_FUNCTION_PASS("atomic-expand", AtomicExpandPass, ())
-DUMMY_FUNCTION_PASS("interleaved-access", InterleavedAccessPass, ())
-DUMMY_FUNCTION_PASS("indirectbr-expand", IndirectBrExpandPass, ())
-DUMMY_FUNCTION_PASS("cfguard-dispatch", CFGuardDispatchPass, ())
-DUMMY_FUNCTION_PASS("cfguard-check", CFGuardCheckPass, ())
-DUMMY_FUNCTION_PASS("gc-info-printer", GCInfoPrinterPass, ())
-#undef DUMMY_FUNCTION_PASS
-
-#ifndef DUMMY_MODULE_PASS
-#define DUMMY_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)
-#endif
-DUMMY_MODULE_PASS("lower-emutls", LowerEmuTLSPass, ())
-#undef DUMMY_MODULE_PASS
-
-#ifndef DUMMY_MACHINE_MODULE_PASS
-#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)
-#endif
-DUMMY_MACHINE_MODULE_PASS("machine-outliner", MachineOutlinerPass, ())
-#undef DUMMY_MACHINE_MODULE_PASS
-
-#ifndef DUMMY_MACHINE_FUNCTION_PASS
-#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
-#endif
-DUMMY_MACHINE_FUNCTION_PASS("mir-printer", PrintMIRPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("free-machine-function", FreeMachineFunctionPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("finalize-isel", FinalizeISelPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("localstackalloc", LocalStackSlotPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("shrink-wrap", ShrinkWrapPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("prologepilog", PrologEpilogInserterPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("postrapseudos", ExpandPostRAPseudosPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("implicit-null-checks", ImplicitNullChecksPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("postmisched", PostMachineSchedulerPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("machine-scheduler", MachineSchedulerPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("machine-cp", MachineCopyPropagationPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("post-RA-sched", PostRASchedulerPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("fentry-insert", FEntryInserterPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("xray-instrumentation", XRayInstrumentationPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("patchable-function", PatchableFunctionPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("reg-usage-propagation", RegUsageInfoPropagationPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("reg-usage-collector", RegUsageInfoCollectorPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("funclet-layout", FuncletLayoutPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("stackmap-liveness", StackMapLivenessPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("livedebugvalues", LiveDebugValuesPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("early-tailduplication", EarlyTailDuplicatePass, ())
-DUMMY_MACHINE_FUNCTION_PASS("opt-phis", OptimizePHIsPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("stack-coloring", StackColoringPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("dead-mi-elimination", DeadMachineInstructionElimPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("early-machinelicm", EarlyMachineLICMPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("machinelicm", MachineLICMPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("machine-cse", MachineCSEPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("machine-sink", MachineSinkingPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("postra-machine-sink", PostRAMachineSinkingPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("peephole-opt", PeepholeOptimizerPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("regalloc", RegAllocPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("virtregrewriter", VirtRegRewriterPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("stack-slot-coloring", StackSlotColoringPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("phi-node-elimination", PHIEliminationPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("twoaddressinstruction", TwoAddressInstructionPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("detect-dead-lanes", DetectDeadLanesPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("processimpdefs", ProcessImplicitDefsPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("liveintervals", LiveIntervalsPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("simple-register-coalescing", RegisterCoalescerPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("rename-independent-subregs", RenameIndependentSubregsPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("branch-folder", BranchFolderPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("tailduplication", TailDuplicatePass, ())
-DUMMY_MACHINE_FUNCTION_PASS("block-placement", MachineBlockPlacementPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("block-placement-stats", MachineBlockPlacementStatsPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("early-ifcvt", EarlyIfConverterPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("machine-combiner", MachineCombinerPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("lrshrink", LiveRangeShrinkPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("break-false-deps", BreakFalseDepsPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("cfi-instr-inserter", CFIInstrInserterPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("cfguard-longjmp", CFGuardLongjmpPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("ra-basic", RABasicPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("ra-fast", RAFastPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("ra-greedy", RAGreedyPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("ra-pbqp", RAPBQPPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("legalizer", LegalizerPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("irtranslator", IRTranslatorPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("regbankselect", RegBankSelectPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("instruction-select", InstructionSelectPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("reset-machine-function", ResetMachineFunctionPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("machineverifier", MachineVerifierPass, ())
-#undef DUMMY_MACHINE_FUNCTION_PASS
+//===- MachinePassRegistry.def - Registry of passes -------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is used as the registry of passes that are for target-independent
+// code generator.
+//
+//===----------------------------------------------------------------------===//
+
+// NOTE: NO INCLUDE GUARD DESIRED!
+
+#ifndef MODULE_ANALYSIS
+#define MODULE_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)
+#endif
+MODULE_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis, (PIC))
+#undef MODULE_ANALYSIS
+
+#ifndef MODULE_PASS
+#define MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#endif
+MODULE_PASS("pre-isel-intrinsic-lowering", PreISelIntrinsicLoweringPass, ())
+#undef MODULE_PASS
+
+#ifndef FUNCTION_ANALYSIS
+#define FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)
+#endif
+FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis, (PIC))
+FUNCTION_ANALYSIS("targetir", TargetIRAnalysis, (std::move(TM.getTargetIRAnalysis())))
+#undef FUNCTION_ANALYSIS
+
+#ifndef FUNCTION_PASS
+#define FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#endif
+FUNCTION_PASS("mergeicmps", MergeICmpsPass, ())
+FUNCTION_PASS("lower-constant-intrinsics", LowerConstantIntrinsicsPass, ())
+FUNCTION_PASS("unreachableblockelim", UnreachableBlockElimPass, ())
+FUNCTION_PASS("consthoist", ConstantHoistingPass, ())
+FUNCTION_PASS("partially-inline-libcalls", PartiallyInlineLibCallsPass, ())
+FUNCTION_PASS("ee-instrument", EntryExitInstrumenterPass, (false))
+FUNCTION_PASS("post-inline-ee-instrument", EntryExitInstrumenterPass, (true))
+FUNCTION_PASS("expand-reductions", ExpandReductionsPass, ())
+FUNCTION_PASS("lowerinvoke", LowerInvokePass, ())
+FUNCTION_PASS("scalarize-masked-mem-intrin", ScalarizeMaskedMemIntrinPass, ())
+FUNCTION_PASS("verify", VerifierPass, ())
+#undef FUNCTION_PASS
+
+#ifndef LOOP_PASS
+#define LOOP_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#endif
+LOOP_PASS("loop-reduce", LoopStrengthReducePass, ())
+#undef LOOP_PASS
+
+#ifndef MACHINE_MODULE_PASS
+#define MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#endif
+#undef MACHINE_MODULE_PASS
+
+#ifndef MACHINE_FUNCTION_ANALYSIS
+#define MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)
+#endif
+MACHINE_FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis, (PIC))
+// LiveVariables currently requires pure SSA form.
+// FIXME: Once TwoAddressInstruction pass no longer uses kill flags,
+// LiveVariables can be removed completely, and LiveIntervals can be directly
+// computed. (We still either need to regenerate kill flags after regalloc, or
+// preferably fix the scavenger to not depend on them).
+// MACHINE_FUNCTION_ANALYSIS("live-vars", LiveVariablesAnalysis())
+
+// MACHINE_FUNCTION_ANALYSIS("live-stacks", LiveStacksPass())
+// MACHINE_FUNCTION_ANALYSIS("slot-indexes", SlotIndexesAnalysis())
+// MACHINE_FUNCTION_ANALYSIS("edge-bundles", EdgeBundlesAnalysis())
+// MACHINE_FUNCTION_ANALYSIS("lazy-machine-bfi", LazyMachineBlockFrequencyInfoAnalysis())
+// MACHINE_FUNCTION_ANALYSIS("machine-bfi", MachineBlockFrequencyInfoAnalysis())
+// MACHINE_FUNCTION_ANALYSIS("machine-loops", MachineLoopInfoAnalysis())
+// MACHINE_FUNCTION_ANALYSIS("machine-dom-frontier", MachineDominanceFrontierAnalysis())
+// MACHINE_FUNCTION_ANALYSIS("machine-dom-tree", MachineDominatorTreeAnalysis())
+// MACHINE_FUNCTION_ANALYSIS("machine-ore", MachineOptimizationRemarkEmitterPassAnalysis())
+// MACHINE_FUNCTION_ANALYSIS("machine-post-dom-tree", MachinePostDominatorTreeAnalysis())
+// MACHINE_FUNCTION_ANALYSIS("machine-region-info", MachineRegionInfoPassAnalysis())
+// MACHINE_FUNCTION_ANALYSIS("machine-trace-metrics", MachineTraceMetricsAnalysis())
+// MACHINE_FUNCTION_ANALYSIS("reaching-def", ReachingDefAnalysisAnalysis())
+// MACHINE_FUNCTION_ANALYSIS("live-reg-matrix", LiveRegMatrixAnalysis())
+// MACHINE_FUNCTION_ANALYSIS("gc-analysis", GCMachineCodeAnalysisPass())
+#undef MACHINE_FUNCTION_ANALYSIS
+
+#ifndef MACHINE_FUNCTION_PASS
+#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#endif
+// MACHINE_FUNCTION_PASS("mir-printer", PrintMIRPass, ())
+// MACHINE_FUNCTION_PASS("free-machine-function", FreeMachineFunctionPass, ())
+#undef MACHINE_FUNCTION_PASS
+
+// After a pass is converted to new pass manager, its entry should be moved from
+// dummy table to the normal one. For example, for a machine function pass,
+// DUMMY_MACHINE_FUNCTION_PASS to MACHINE_FUNCTION_PASS.
+
+#ifndef DUMMY_FUNCTION_PASS
+#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#endif
+DUMMY_FUNCTION_PASS("expandmemcmp", ExpandMemCmpPass, ())
+DUMMY_FUNCTION_PASS("gc-lowering", GCLoweringPass, ())
+DUMMY_FUNCTION_PASS("shadow-stack-gc-lowering", ShadowStackGCLoweringPass, ())
+DUMMY_FUNCTION_PASS("sjljehprepare", SjLjEHPreparePass, ())
+DUMMY_FUNCTION_PASS("dwarfehprepare", DwarfEHPass, ())
+DUMMY_FUNCTION_PASS("winehprepare", WinEHPass, ())
+DUMMY_FUNCTION_PASS("wasmehprepare", WasmEHPass, ())
+DUMMY_FUNCTION_PASS("codegenprepare", CodeGenPreparePass, ())
+DUMMY_FUNCTION_PASS("safe-stack", SafeStackPass, ())
+DUMMY_FUNCTION_PASS("stack-protector", StackProtectorPass, ())
+DUMMY_FUNCTION_PASS("atomic-expand", AtomicExpandPass, ())
+DUMMY_FUNCTION_PASS("interleaved-access", InterleavedAccessPass, ())
+DUMMY_FUNCTION_PASS("indirectbr-expand", IndirectBrExpandPass, ())
+DUMMY_FUNCTION_PASS("cfguard-dispatch", CFGuardDispatchPass, ())
+DUMMY_FUNCTION_PASS("cfguard-check", CFGuardCheckPass, ())
+DUMMY_FUNCTION_PASS("gc-info-printer", GCInfoPrinterPass, ())
+#undef DUMMY_FUNCTION_PASS
+
+#ifndef DUMMY_MODULE_PASS
+#define DUMMY_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#endif
+DUMMY_MODULE_PASS("lower-emutls", LowerEmuTLSPass, ())
+#undef DUMMY_MODULE_PASS
+
+#ifndef DUMMY_MACHINE_MODULE_PASS
+#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#endif
+DUMMY_MACHINE_MODULE_PASS("machine-outliner", MachineOutlinerPass, ())
+#undef DUMMY_MACHINE_MODULE_PASS
+
+#ifndef DUMMY_MACHINE_FUNCTION_PASS
+#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#endif
+DUMMY_MACHINE_FUNCTION_PASS("mir-printer", PrintMIRPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("free-machine-function", FreeMachineFunctionPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("finalize-isel", FinalizeISelPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("localstackalloc", LocalStackSlotPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("shrink-wrap", ShrinkWrapPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("prologepilog", PrologEpilogInserterPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("postrapseudos", ExpandPostRAPseudosPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("implicit-null-checks", ImplicitNullChecksPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("postmisched", PostMachineSchedulerPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("machine-scheduler", MachineSchedulerPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("machine-cp", MachineCopyPropagationPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("post-RA-sched", PostRASchedulerPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("fentry-insert", FEntryInserterPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("xray-instrumentation", XRayInstrumentationPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("patchable-function", PatchableFunctionPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("reg-usage-propagation", RegUsageInfoPropagationPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("reg-usage-collector", RegUsageInfoCollectorPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("funclet-layout", FuncletLayoutPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("stackmap-liveness", StackMapLivenessPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("livedebugvalues", LiveDebugValuesPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("early-tailduplication", EarlyTailDuplicatePass, ())
+DUMMY_MACHINE_FUNCTION_PASS("opt-phis", OptimizePHIsPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("stack-coloring", StackColoringPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("dead-mi-elimination", DeadMachineInstructionElimPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("early-machinelicm", EarlyMachineLICMPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("machinelicm", MachineLICMPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("machine-cse", MachineCSEPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("machine-sink", MachineSinkingPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("postra-machine-sink", PostRAMachineSinkingPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("peephole-opt", PeepholeOptimizerPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("regalloc", RegAllocPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("virtregrewriter", VirtRegRewriterPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("stack-slot-coloring", StackSlotColoringPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("phi-node-elimination", PHIEliminationPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("twoaddressinstruction", TwoAddressInstructionPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("detect-dead-lanes", DetectDeadLanesPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("processimpdefs", ProcessImplicitDefsPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("liveintervals", LiveIntervalsPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("simple-register-coalescing", RegisterCoalescerPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("rename-independent-subregs", RenameIndependentSubregsPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("branch-folder", BranchFolderPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("tailduplication", TailDuplicatePass, ())
+DUMMY_MACHINE_FUNCTION_PASS("block-placement", MachineBlockPlacementPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("block-placement-stats", MachineBlockPlacementStatsPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("early-ifcvt", EarlyIfConverterPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("machine-combiner", MachineCombinerPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("lrshrink", LiveRangeShrinkPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("break-false-deps", BreakFalseDepsPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("cfi-instr-inserter", CFIInstrInserterPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("cfguard-longjmp", CFGuardLongjmpPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("ra-basic", RABasicPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("ra-fast", RAFastPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("ra-greedy", RAGreedyPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("ra-pbqp", RAPBQPPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("legalizer", LegalizerPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("irtranslator", IRTranslatorPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("regbankselect", RegBankSelectPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("instruction-select", InstructionSelectPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("reset-machine-function", ResetMachineFunctionPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("machineverifier", MachineVerifierPass, ())
+#undef DUMMY_MACHINE_FUNCTION_PASS
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachinePipeliner.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachinePipeliner.h
index 29650f0f9c..64ffaea914 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachinePipeliner.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachinePipeliner.h
@@ -56,7 +56,7 @@
namespace llvm {
-class AAResults;
+class AAResults;
class NodeSet;
class SMSchedule;
@@ -98,7 +98,7 @@ public:
bool runOnMachineFunction(MachineFunction &MF) override;
- void getAnalysisUsage(AnalysisUsage &AU) const override;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
private:
void preprocessPhiNodes(MachineBasicBlock &B);
@@ -283,7 +283,7 @@ public:
static bool classof(const ScheduleDAGInstrs *DAG) { return true; }
private:
- void addLoopCarriedDependences(AAResults *AA);
+ void addLoopCarriedDependences(AAResults *AA);
void updatePhiDependences();
void changeDependences();
unsigned calculateResMII();
@@ -302,7 +302,7 @@ private:
void checkValidNodeOrder(const NodeSetType &Circuits) const;
bool schedulePipeline(SMSchedule &Schedule);
bool computeDelta(MachineInstr &MI, unsigned &Delta);
- MachineInstr *findDefInLoop(Register Reg);
+ MachineInstr *findDefInLoop(Register Reg);
bool canUseLastOffsetValue(MachineInstr *MI, unsigned &BasePos,
unsigned &OffsetPos, unsigned &NewBase,
int64_t &NewOffset);
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineRegisterInfo.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineRegisterInfo.h
index c7fbcacc69..c758dd5a47 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -449,22 +449,22 @@ public:
/// Return true if there is exactly one operand defining the specified
/// register.
bool hasOneDef(Register RegNo) const {
- return hasSingleElement(def_operands(RegNo));
- }
-
- /// Returns the defining operand if there is exactly one operand defining the
- /// specified register, otherwise nullptr.
- MachineOperand *getOneDef(Register Reg) const {
- def_iterator DI = def_begin(Reg);
- if (DI == def_end()) // No defs.
- return nullptr;
-
- def_iterator OneDef = DI;
- if (++DI == def_end())
- return &*OneDef;
- return nullptr; // Multiple defs.
- }
-
+ return hasSingleElement(def_operands(RegNo));
+ }
+
+ /// Returns the defining operand if there is exactly one operand defining the
+ /// specified register, otherwise nullptr.
+ MachineOperand *getOneDef(Register Reg) const {
+ def_iterator DI = def_begin(Reg);
+ if (DI == def_end()) // No defs.
+ return nullptr;
+
+ def_iterator OneDef = DI;
+ if (++DI == def_end())
+ return &*OneDef;
+ return nullptr; // Multiple defs.
+ }
+
/// use_iterator/use_begin/use_end - Walk all uses of the specified register.
using use_iterator =
defusechain_iterator<true, false, false, true, false, false>;
@@ -515,7 +515,7 @@ public:
/// hasOneUse - Return true if there is exactly one instruction using the
/// specified register.
bool hasOneUse(Register RegNo) const {
- return hasSingleElement(use_operands(RegNo));
+ return hasSingleElement(use_operands(RegNo));
}
/// use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the
@@ -629,7 +629,7 @@ public:
/// Get an iterator over the pressure sets affected by the given physical or
/// virtual register. If RegUnit is physical, it must be a register unit (from
/// MCRegUnitIterator).
- PSetIterator getPressureSets(Register RegUnit) const;
+ PSetIterator getPressureSets(Register RegUnit) const;
//===--------------------------------------------------------------------===//
// Virtual Register Info
@@ -904,7 +904,7 @@ public:
///
/// Reserved registers may belong to an allocatable register class, but the
/// target has explicitly requested that they are not used.
- bool isReserved(MCRegister PhysReg) const {
+ bool isReserved(MCRegister PhysReg) const {
return getReservedRegs().test(PhysReg.id());
}
@@ -1184,13 +1184,13 @@ class PSetIterator {
public:
PSetIterator() = default;
- PSetIterator(Register RegUnit, const MachineRegisterInfo *MRI) {
+ PSetIterator(Register RegUnit, const MachineRegisterInfo *MRI) {
const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo();
- if (RegUnit.isVirtual()) {
+ if (RegUnit.isVirtual()) {
const TargetRegisterClass *RC = MRI->getRegClass(RegUnit);
PSet = TRI->getRegClassPressureSets(RC);
Weight = TRI->getRegClassWeight(RC).RegWeight;
- } else {
+ } else {
PSet = TRI->getRegUnitPressureSets(RegUnit);
Weight = TRI->getRegUnitWeight(RegUnit);
}
@@ -1212,8 +1212,8 @@ public:
}
};
-inline PSetIterator
-MachineRegisterInfo::getPressureSets(Register RegUnit) const {
+inline PSetIterator
+MachineRegisterInfo::getPressureSets(Register RegUnit) const {
return PSetIterator(RegUnit, this);
}
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineSSAUpdater.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineSSAUpdater.h
index fd502f3f3e..9f7949c79b 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineSSAUpdater.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineSSAUpdater.h
@@ -69,7 +69,7 @@ public:
/// Initialize - Reset this object to get ready for a new set of SSA
/// updates.
void Initialize(Register V);
- void Initialize(const TargetRegisterClass *RC);
+ void Initialize(const TargetRegisterClass *RC);
/// AddAvailableValue - Indicate that a rewritten value is available at the
/// end of the specified block with the specified value.
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineStableHash.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineStableHash.h
index 450d075ef6..d1409e35d0 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineStableHash.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineStableHash.h
@@ -1,41 +1,41 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===------------ MachineStableHash.h - MIR Stable Hashing Utilities ------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Stable hashing for MachineInstr and MachineOperand. Useful or getting a
-// hash across runs, modules, etc.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_MACHINESTABLEHASH_H
-#define LLVM_CODEGEN_MACHINESTABLEHASH_H
-
-#include "llvm/CodeGen/StableHashing.h"
-
-namespace llvm {
-class MachineInstr;
-class MachineOperand;
-
-stable_hash stableHashValue(const MachineOperand &MO);
-stable_hash stableHashValue(const MachineInstr &MI, bool HashVRegs = false,
- bool HashConstantPoolIndices = false,
- bool HashMemOperands = false);
-
-} // namespace llvm
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===------------ MachineStableHash.h - MIR Stable Hashing Utilities ------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Stable hashing for MachineInstr and MachineOperand. Useful or getting a
+// hash across runs, modules, etc.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINESTABLEHASH_H
+#define LLVM_CODEGEN_MACHINESTABLEHASH_H
+
+#include "llvm/CodeGen/StableHashing.h"
+
+namespace llvm {
+class MachineInstr;
+class MachineOperand;
+
+stable_hash stableHashValue(const MachineOperand &MO);
+stable_hash stableHashValue(const MachineInstr &MI, bool HashVRegs = false,
+ bool HashConstantPoolIndices = false,
+ bool HashMemOperands = false);
+
+} // namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineTraceMetrics.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineTraceMetrics.h
index 0c7c3da18d..2d9da27f75 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineTraceMetrics.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineTraceMetrics.h
@@ -147,13 +147,13 @@ public:
/// successors.
struct LiveInReg {
/// The virtual register required, or a register unit.
- Register Reg;
+ Register Reg;
/// For virtual registers: Minimum height of the defining instruction.
/// For regunits: Height of the highest user in the trace.
unsigned Height;
- LiveInReg(Register Reg, unsigned Height = 0) : Reg(Reg), Height(Height) {}
+ LiveInReg(Register Reg, unsigned Height = 0) : Reg(Reg), Height(Height) {}
};
/// Per-basic block information that relates to a specific trace through the
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MultiHazardRecognizer.h b/contrib/libs/llvm12/include/llvm/CodeGen/MultiHazardRecognizer.h
index b4c417e9fc..6542ceb52d 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/MultiHazardRecognizer.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/MultiHazardRecognizer.h
@@ -1,58 +1,58 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//=- llvm/CodeGen/MultiHazardRecognizer.h - Scheduling Support ----*- C++ -*-=//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the MultiHazardRecognizer class, which is a wrapper
-// for a set of ScheduleHazardRecognizer instances
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_MULTIHAZARDRECOGNIZER_H
-#define LLVM_CODEGEN_MULTIHAZARDRECOGNIZER_H
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
-
-namespace llvm {
-
-class MachineInstr;
-class SUnit;
-
-class MultiHazardRecognizer : public ScheduleHazardRecognizer {
- SmallVector<std::unique_ptr<ScheduleHazardRecognizer>, 4> Recognizers;
-
-public:
- MultiHazardRecognizer() = default;
- void AddHazardRecognizer(std::unique_ptr<ScheduleHazardRecognizer> &&);
-
- bool atIssueLimit() const override;
- HazardType getHazardType(SUnit *, int Stalls = 0) override;
- void Reset() override;
- void EmitInstruction(SUnit *) override;
- void EmitInstruction(MachineInstr *) override;
- unsigned PreEmitNoops(SUnit *) override;
- unsigned PreEmitNoops(MachineInstr *) override;
- bool ShouldPreferAnother(SUnit *) override;
- void AdvanceCycle() override;
- void RecedeCycle() override;
- void EmitNoop() override;
-};
-
-} // end namespace llvm
-
-#endif // LLVM_CODEGEN_MULTIHAZARDRECOGNIZER_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//=- llvm/CodeGen/MultiHazardRecognizer.h - Scheduling Support ----*- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the MultiHazardRecognizer class, which is a wrapper
+// for a set of ScheduleHazardRecognizer instances
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MULTIHAZARDRECOGNIZER_H
+#define LLVM_CODEGEN_MULTIHAZARDRECOGNIZER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
+
+namespace llvm {
+
+class MachineInstr;
+class SUnit;
+
+class MultiHazardRecognizer : public ScheduleHazardRecognizer {
+ SmallVector<std::unique_ptr<ScheduleHazardRecognizer>, 4> Recognizers;
+
+public:
+ MultiHazardRecognizer() = default;
+ void AddHazardRecognizer(std::unique_ptr<ScheduleHazardRecognizer> &&);
+
+ bool atIssueLimit() const override;
+ HazardType getHazardType(SUnit *, int Stalls = 0) override;
+ void Reset() override;
+ void EmitInstruction(SUnit *) override;
+ void EmitInstruction(MachineInstr *) override;
+ unsigned PreEmitNoops(SUnit *) override;
+ unsigned PreEmitNoops(MachineInstr *) override;
+ bool ShouldPreferAnother(SUnit *) override;
+ void AdvanceCycle() override;
+ void RecedeCycle() override;
+ void EmitNoop() override;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_MULTIHAZARDRECOGNIZER_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/NonRelocatableStringpool.h b/contrib/libs/llvm12/include/llvm/CodeGen/NonRelocatableStringpool.h
index 20805de987..e88472a231 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/NonRelocatableStringpool.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/NonRelocatableStringpool.h
@@ -46,7 +46,7 @@ public:
/// Get the offset of string \p S in the string table. This can insert a new
/// element or return the offset of a pre-existing one.
- uint64_t getStringOffset(StringRef S) { return getEntry(S).getOffset(); }
+ uint64_t getStringOffset(StringRef S) { return getEntry(S).getOffset(); }
/// Get permanent storage for \p S (but do not necessarily emit \p S in the
/// output section). A latter call to getStringOffset() with the same string
@@ -64,7 +64,7 @@ public:
private:
MapTy Strings;
- uint64_t CurrentEndOffset = 0;
+ uint64_t CurrentEndOffset = 0;
unsigned NumEntries = 0;
DwarfStringPoolEntryRef EmptyString;
std::function<StringRef(StringRef Input)> Translator;
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/Passes.h b/contrib/libs/llvm12/include/llvm/CodeGen/Passes.h
index d67b9b9aa0..06c68498b9 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/Passes.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/Passes.h
@@ -51,16 +51,16 @@ namespace llvm {
/// the entry block.
FunctionPass *createUnreachableBlockEliminationPass();
- /// createBasicBlockSections Pass - This pass assigns sections to machine
- /// basic blocks and is enabled with -fbasic-block-sections. Buf is a memory
- /// buffer that contains the list of functions and basic block ids to
- /// selectively enable basic block sections.
- MachineFunctionPass *createBasicBlockSectionsPass(const MemoryBuffer *Buf);
-
- /// createMachineFunctionSplitterPass - This pass splits machine functions
- /// using profile information.
- MachineFunctionPass *createMachineFunctionSplitterPass();
-
+ /// createBasicBlockSections Pass - This pass assigns sections to machine
+ /// basic blocks and is enabled with -fbasic-block-sections. Buf is a memory
+ /// buffer that contains the list of functions and basic block ids to
+ /// selectively enable basic block sections.
+ MachineFunctionPass *createBasicBlockSectionsPass(const MemoryBuffer *Buf);
+
+ /// createMachineFunctionSplitterPass - This pass splits machine functions
+ /// using profile information.
+ MachineFunctionPass *createMachineFunctionSplitterPass();
+
/// MachineFunctionPrinter pass - This pass prints out the machine function to
/// the given stream as a debugging tool.
MachineFunctionPass *
@@ -474,9 +474,9 @@ namespace llvm {
/// Create Hardware Loop pass. \see HardwareLoops.cpp
FunctionPass *createHardwareLoopsPass();
- /// This pass inserts pseudo probe annotation for callsite profiling.
- FunctionPass *createPseudoProbeInserter();
-
+ /// This pass inserts pseudo probe annotation for callsite profiling.
+ FunctionPass *createPseudoProbeInserter();
+
/// Create IR Type Promotion pass. \see TypePromotion.cpp
FunctionPass *createTypePromotionPass();
@@ -489,16 +489,16 @@ namespace llvm {
/// info was generated by another source such as clang.
ModulePass *createStripDebugMachineModulePass(bool OnlyDebugified);
- /// Creates MIR Check Debug pass. \see MachineCheckDebugify.cpp
- ModulePass *createCheckDebugMachineModulePass();
-
+ /// Creates MIR Check Debug pass. \see MachineCheckDebugify.cpp
+ ModulePass *createCheckDebugMachineModulePass();
+
/// The pass fixups statepoint machine instruction to replace usage of
/// caller saved registers with stack slots.
extern char &FixupStatepointCallerSavedID;
-
- /// The pass transform load/store <256 x i32> to AMX load/store intrinsics
- /// or split the data to two <128 x i32>.
- FunctionPass *createX86LowerAMXTypePass();
+
+ /// The pass transform load/store <256 x i32> to AMX load/store intrinsics
+ /// or split the data to two <128 x i32>.
+ FunctionPass *createX86LowerAMXTypePass();
} // End llvm namespace
#endif
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/RDFLiveness.h b/contrib/libs/llvm12/include/llvm/CodeGen/RDFLiveness.h
index 7a0320d7bd..cf0c14f6b4 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/RDFLiveness.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/RDFLiveness.h
@@ -25,8 +25,8 @@
#include "llvm/MC/LaneBitmask.h"
#include <map>
#include <set>
-#include <unordered_map>
-#include <unordered_set>
+#include <unordered_map>
+#include <unordered_set>
#include <utility>
namespace llvm {
@@ -37,32 +37,32 @@ class MachineDominatorTree;
class MachineRegisterInfo;
class TargetRegisterInfo;
-} // namespace llvm
-
-namespace llvm {
+} // namespace llvm
+
+namespace llvm {
namespace rdf {
-namespace detail {
-
-using NodeRef = std::pair<NodeId, LaneBitmask>;
-
-} // namespace detail
-} // namespace rdf
-} // namespace llvm
-
-namespace std {
-
-template <> struct hash<llvm::rdf::detail::NodeRef> {
- std::size_t operator()(llvm::rdf::detail::NodeRef R) const {
- return std::hash<llvm::rdf::NodeId>{}(R.first) ^
- std::hash<llvm::LaneBitmask::Type>{}(R.second.getAsInteger());
- }
-};
-
-} // namespace std
-
-namespace llvm {
-namespace rdf {
-
+namespace detail {
+
+using NodeRef = std::pair<NodeId, LaneBitmask>;
+
+} // namespace detail
+} // namespace rdf
+} // namespace llvm
+
+namespace std {
+
+template <> struct hash<llvm::rdf::detail::NodeRef> {
+ std::size_t operator()(llvm::rdf::detail::NodeRef R) const {
+ return std::hash<llvm::rdf::NodeId>{}(R.first) ^
+ std::hash<llvm::LaneBitmask::Type>{}(R.second.getAsInteger());
+ }
+};
+
+} // namespace std
+
+namespace llvm {
+namespace rdf {
+
struct Liveness {
public:
// This is really a std::map, except that it provides a non-trivial
@@ -79,9 +79,9 @@ namespace rdf {
std::map<MachineBasicBlock*,RegisterAggr> Map;
};
- using NodeRef = detail::NodeRef;
- using NodeRefSet = std::unordered_set<NodeRef>;
- using RefMap = std::unordered_map<RegisterId, NodeRefSet>;
+ using NodeRef = detail::NodeRef;
+ using NodeRefSet = std::unordered_set<NodeRef>;
+ using RefMap = std::unordered_map<RegisterId, NodeRefSet>;
Liveness(MachineRegisterInfo &mri, const DataFlowGraph &g)
: DFG(g), TRI(g.getTRI()), PRI(g.getPRI()), MDT(g.getDT()),
@@ -142,14 +142,14 @@ namespace rdf {
// Cache of mapping from node ids (for RefNodes) to the containing
// basic blocks. Not computing it each time for each node reduces
// the liveness calculation time by a large fraction.
- DenseMap<NodeId, MachineBasicBlock *> NBMap;
+ DenseMap<NodeId, MachineBasicBlock *> NBMap;
// Phi information:
//
// RealUseMap
// map: NodeId -> (map: RegisterId -> NodeRefSet)
// phi id -> (map: register -> set of reached non-phi uses)
- DenseMap<NodeId, RefMap> RealUseMap;
+ DenseMap<NodeId, RefMap> RealUseMap;
// Inverse iterated dominance frontier.
std::map<MachineBasicBlock*,std::set<MachineBasicBlock*>> IIDF;
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/RDFRegisters.h b/contrib/libs/llvm12/include/llvm/CodeGen/RDFRegisters.h
index 7d77206395..58a5f7e6a0 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/RDFRegisters.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/RDFRegisters.h
@@ -98,11 +98,11 @@ namespace rdf {
bool operator< (const RegisterRef &RR) const {
return Reg < RR.Reg || (Reg == RR.Reg && Mask < RR.Mask);
}
-
- size_t hash() const {
- return std::hash<RegisterId>{}(Reg) ^
- std::hash<LaneBitmask::Type>{}(Mask.getAsInteger());
- }
+
+ size_t hash() const {
+ return std::hash<RegisterId>{}(Reg) ^
+ std::hash<LaneBitmask::Type>{}(Mask.getAsInteger());
+ }
};
@@ -138,10 +138,10 @@ namespace rdf {
return MaskInfos[Register::stackSlot2Index(MaskId)].Units;
}
- const BitVector &getUnitAliases(uint32_t U) const {
- return AliasInfos[U].Regs;
- }
-
+ const BitVector &getUnitAliases(uint32_t U) const {
+ return AliasInfos[U].Regs;
+ }
+
RegisterRef mapTo(RegisterRef RR, unsigned R) const;
const TargetRegisterInfo &getTRI() const { return TRI; }
@@ -156,16 +156,16 @@ namespace rdf {
struct MaskInfo {
BitVector Units;
};
- struct AliasInfo {
- BitVector Regs;
- };
+ struct AliasInfo {
+ BitVector Regs;
+ };
const TargetRegisterInfo &TRI;
IndexedSet<const uint32_t*> RegMasks;
std::vector<RegInfo> RegInfos;
std::vector<UnitInfo> UnitInfos;
std::vector<MaskInfo> MaskInfos;
- std::vector<AliasInfo> AliasInfos;
+ std::vector<AliasInfo> AliasInfos;
bool aliasRR(RegisterRef RA, RegisterRef RB) const;
bool aliasRM(RegisterRef RR, RegisterRef RM) const;
@@ -177,15 +177,15 @@ namespace rdf {
: Units(pri.getTRI().getNumRegUnits()), PRI(pri) {}
RegisterAggr(const RegisterAggr &RG) = default;
- unsigned count() const { return Units.count(); }
+ unsigned count() const { return Units.count(); }
bool empty() const { return Units.none(); }
bool hasAliasOf(RegisterRef RR) const;
bool hasCoverOf(RegisterRef RR) const;
- bool operator==(const RegisterAggr &A) const {
- return DenseMapInfo<BitVector>::isEqual(Units, A.Units);
- }
-
+ bool operator==(const RegisterAggr &A) const {
+ return DenseMapInfo<BitVector>::isEqual(Units, A.Units);
+ }
+
static bool isCoverOf(RegisterRef RA, RegisterRef RB,
const PhysicalRegisterInfo &PRI) {
return RegisterAggr(PRI).insert(RA).hasCoverOf(RB);
@@ -202,10 +202,10 @@ namespace rdf {
RegisterRef clearIn(RegisterRef RR) const;
RegisterRef makeRegRef() const;
- size_t hash() const {
- return DenseMapInfo<BitVector>::getHashValue(Units);
- }
-
+ size_t hash() const {
+ return DenseMapInfo<BitVector>::getHashValue(Units);
+ }
+
void print(raw_ostream &OS) const;
struct rr_iterator {
@@ -260,29 +260,29 @@ namespace rdf {
};
raw_ostream &operator<< (raw_ostream &OS, const PrintLaneMaskOpt &P);
- raw_ostream &operator<< (raw_ostream &OS, const RegisterAggr &A);
+ raw_ostream &operator<< (raw_ostream &OS, const RegisterAggr &A);
} // end namespace rdf
} // end namespace llvm
-namespace std {
- template <> struct hash<llvm::rdf::RegisterRef> {
- size_t operator()(llvm::rdf::RegisterRef A) const {
- return A.hash();
- }
- };
- template <> struct hash<llvm::rdf::RegisterAggr> {
- size_t operator()(const llvm::rdf::RegisterAggr &A) const {
- return A.hash();
- }
- };
- template <> struct equal_to<llvm::rdf::RegisterAggr> {
- bool operator()(const llvm::rdf::RegisterAggr &A,
- const llvm::rdf::RegisterAggr &B) const {
- return A == B;
- }
- };
-}
+namespace std {
+ template <> struct hash<llvm::rdf::RegisterRef> {
+ size_t operator()(llvm::rdf::RegisterRef A) const {
+ return A.hash();
+ }
+ };
+ template <> struct hash<llvm::rdf::RegisterAggr> {
+ size_t operator()(const llvm::rdf::RegisterAggr &A) const {
+ return A.hash();
+ }
+ };
+ template <> struct equal_to<llvm::rdf::RegisterAggr> {
+ bool operator()(const llvm::rdf::RegisterAggr &A,
+ const llvm::rdf::RegisterAggr &B) const {
+ return A == B;
+ }
+ };
+}
#endif // LLVM_LIB_TARGET_HEXAGON_RDFREGISTERS_H
#ifdef __GNUC__
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/ReachingDefAnalysis.h b/contrib/libs/llvm12/include/llvm/CodeGen/ReachingDefAnalysis.h
index bb078a64bf..f95f8df814 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/ReachingDefAnalysis.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/ReachingDefAnalysis.h
@@ -146,25 +146,25 @@ public:
/// Provides the instruction id of the closest reaching def instruction of
/// PhysReg that reaches MI, relative to the begining of MI's basic block.
- int getReachingDef(MachineInstr *MI, MCRegister PhysReg) const;
+ int getReachingDef(MachineInstr *MI, MCRegister PhysReg) const;
/// Return whether A and B use the same def of PhysReg.
- bool hasSameReachingDef(MachineInstr *A, MachineInstr *B,
- MCRegister PhysReg) const;
+ bool hasSameReachingDef(MachineInstr *A, MachineInstr *B,
+ MCRegister PhysReg) const;
/// Return whether the reaching def for MI also is live out of its parent
/// block.
- bool isReachingDefLiveOut(MachineInstr *MI, MCRegister PhysReg) const;
+ bool isReachingDefLiveOut(MachineInstr *MI, MCRegister PhysReg) const;
/// Return the local MI that produces the live out value for PhysReg, or
/// nullptr for a non-live out or non-local def.
MachineInstr *getLocalLiveOutMIDef(MachineBasicBlock *MBB,
- MCRegister PhysReg) const;
+ MCRegister PhysReg) const;
/// If a single MachineInstr creates the reaching definition, then return it.
/// Otherwise return null.
- MachineInstr *getUniqueReachingMIDef(MachineInstr *MI,
- MCRegister PhysReg) const;
+ MachineInstr *getUniqueReachingMIDef(MachineInstr *MI,
+ MCRegister PhysReg) const;
/// If a single MachineInstr creates the reaching definition, for MIs operand
/// at Idx, then return it. Otherwise return null.
@@ -176,46 +176,46 @@ public:
/// Provide whether the register has been defined in the same basic block as,
/// and before, MI.
- bool hasLocalDefBefore(MachineInstr *MI, MCRegister PhysReg) const;
+ bool hasLocalDefBefore(MachineInstr *MI, MCRegister PhysReg) const;
/// Return whether the given register is used after MI, whether it's a local
/// use or a live out.
- bool isRegUsedAfter(MachineInstr *MI, MCRegister PhysReg) const;
+ bool isRegUsedAfter(MachineInstr *MI, MCRegister PhysReg) const;
/// Return whether the given register is defined after MI.
- bool isRegDefinedAfter(MachineInstr *MI, MCRegister PhysReg) const;
+ bool isRegDefinedAfter(MachineInstr *MI, MCRegister PhysReg) const;
/// Provides the clearance - the number of instructions since the closest
/// reaching def instuction of PhysReg that reaches MI.
- int getClearance(MachineInstr *MI, MCRegister PhysReg) const;
+ int getClearance(MachineInstr *MI, MCRegister PhysReg) const;
/// Provides the uses, in the same block as MI, of register that MI defines.
/// This does not consider live-outs.
- void getReachingLocalUses(MachineInstr *MI, MCRegister PhysReg,
+ void getReachingLocalUses(MachineInstr *MI, MCRegister PhysReg,
InstSet &Uses) const;
/// Search MBB for a definition of PhysReg and insert it into Defs. If no
/// definition is found, recursively search the predecessor blocks for them.
- void getLiveOuts(MachineBasicBlock *MBB, MCRegister PhysReg, InstSet &Defs,
+ void getLiveOuts(MachineBasicBlock *MBB, MCRegister PhysReg, InstSet &Defs,
BlockSet &VisitedBBs) const;
- void getLiveOuts(MachineBasicBlock *MBB, MCRegister PhysReg,
- InstSet &Defs) const;
+ void getLiveOuts(MachineBasicBlock *MBB, MCRegister PhysReg,
+ InstSet &Defs) const;
/// For the given block, collect the instructions that use the live-in
/// value of the provided register. Return whether the value is still
/// live on exit.
- bool getLiveInUses(MachineBasicBlock *MBB, MCRegister PhysReg,
+ bool getLiveInUses(MachineBasicBlock *MBB, MCRegister PhysReg,
InstSet &Uses) const;
/// Collect the users of the value stored in PhysReg, which is defined
/// by MI.
- void getGlobalUses(MachineInstr *MI, MCRegister PhysReg, InstSet &Uses) const;
+ void getGlobalUses(MachineInstr *MI, MCRegister PhysReg, InstSet &Uses) const;
+
+ /// Collect all possible definitions of the value stored in PhysReg, which is
+ /// used by MI.
+ void getGlobalReachingDefs(MachineInstr *MI, MCRegister PhysReg,
+ InstSet &Defs) const;
- /// Collect all possible definitions of the value stored in PhysReg, which is
- /// used by MI.
- void getGlobalReachingDefs(MachineInstr *MI, MCRegister PhysReg,
- InstSet &Defs) const;
-
/// Return whether From can be moved forwards to just before To.
bool isSafeToMoveForwards(MachineInstr *From, MachineInstr *To) const;
@@ -238,13 +238,13 @@ public:
/// Return whether a MachineInstr could be inserted at MI and safely define
/// the given register without affecting the program.
- bool isSafeToDefRegAt(MachineInstr *MI, MCRegister PhysReg) const;
+ bool isSafeToDefRegAt(MachineInstr *MI, MCRegister PhysReg) const;
/// Return whether a MachineInstr could be inserted at MI and safely define
/// the given register without affecting the program, ignoring any effects
/// on the provided instructions.
- bool isSafeToDefRegAt(MachineInstr *MI, MCRegister PhysReg,
- InstSet &Ignore) const;
+ bool isSafeToDefRegAt(MachineInstr *MI, MCRegister PhysReg,
+ InstSet &Ignore) const;
private:
/// Set up LiveRegs by merging predecessor live-out values.
@@ -279,8 +279,8 @@ private:
/// Provides the instruction of the closest reaching def instruction of
/// PhysReg that reaches MI, relative to the begining of MI's basic block.
- MachineInstr *getReachingLocalMIDef(MachineInstr *MI,
- MCRegister PhysReg) const;
+ MachineInstr *getReachingLocalMIDef(MachineInstr *MI,
+ MCRegister PhysReg) const;
};
} // namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/RegAllocPBQP.h b/contrib/libs/llvm12/include/llvm/CodeGen/RegAllocPBQP.h
index 47dcc0f554..bbf491aa5b 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/RegAllocPBQP.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/RegAllocPBQP.h
@@ -29,8 +29,8 @@
#include "llvm/CodeGen/PBQP/Math.h"
#include "llvm/CodeGen/PBQP/ReductionRules.h"
#include "llvm/CodeGen/PBQP/Solution.h"
-#include "llvm/CodeGen/Register.h"
-#include "llvm/MC/MCRegister.h"
+#include "llvm/CodeGen/Register.h"
+#include "llvm/MC/MCRegister.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
#include <cassert>
@@ -105,13 +105,13 @@ public:
AllowedRegVector() = default;
AllowedRegVector(AllowedRegVector &&) = default;
- AllowedRegVector(const std::vector<MCRegister> &OptVec)
- : NumOpts(OptVec.size()), Opts(new MCRegister[NumOpts]) {
+ AllowedRegVector(const std::vector<MCRegister> &OptVec)
+ : NumOpts(OptVec.size()), Opts(new MCRegister[NumOpts]) {
std::copy(OptVec.begin(), OptVec.end(), Opts.get());
}
unsigned size() const { return NumOpts; }
- MCRegister operator[](size_t I) const { return Opts[I]; }
+ MCRegister operator[](size_t I) const { return Opts[I]; }
bool operator==(const AllowedRegVector &Other) const {
if (NumOpts != Other.NumOpts)
@@ -125,12 +125,12 @@ public:
private:
unsigned NumOpts = 0;
- std::unique_ptr<MCRegister[]> Opts;
+ std::unique_ptr<MCRegister[]> Opts;
};
inline hash_code hash_value(const AllowedRegVector &OptRegs) {
- MCRegister *OStart = OptRegs.Opts.get();
- MCRegister *OEnd = OptRegs.Opts.get() + OptRegs.NumOpts;
+ MCRegister *OStart = OptRegs.Opts.get();
+ MCRegister *OEnd = OptRegs.Opts.get() + OptRegs.NumOpts;
return hash_combine(OptRegs.NumOpts,
hash_combine_range(OStart, OEnd));
}
@@ -152,11 +152,11 @@ public:
LiveIntervals &LIS;
MachineBlockFrequencyInfo &MBFI;
- void setNodeIdForVReg(Register VReg, GraphBase::NodeId NId) {
- VRegToNodeId[VReg.id()] = NId;
+ void setNodeIdForVReg(Register VReg, GraphBase::NodeId NId) {
+ VRegToNodeId[VReg.id()] = NId;
}
- GraphBase::NodeId getNodeIdForVReg(Register VReg) const {
+ GraphBase::NodeId getNodeIdForVReg(Register VReg) const {
auto VRegItr = VRegToNodeId.find(VReg);
if (VRegItr == VRegToNodeId.end())
return GraphBase::invalidNodeId();
@@ -168,7 +168,7 @@ public:
}
private:
- DenseMap<Register, GraphBase::NodeId> VRegToNodeId;
+ DenseMap<Register, GraphBase::NodeId> VRegToNodeId;
AllowedRegVecPool AllowedRegVecs;
};
@@ -206,8 +206,8 @@ public:
NodeMetadata(NodeMetadata &&) = default;
NodeMetadata& operator=(NodeMetadata &&) = default;
- void setVReg(Register VReg) { this->VReg = VReg; }
- Register getVReg() const { return VReg; }
+ void setVReg(Register VReg) { this->VReg = VReg; }
+ Register getVReg() const { return VReg; }
void setAllowedRegs(GraphMetadata::AllowedRegVecRef AllowedRegs) {
this->AllowedRegs = std::move(AllowedRegs);
@@ -265,7 +265,7 @@ private:
unsigned NumOpts = 0;
unsigned DeniedOpts = 0;
std::unique_ptr<unsigned[]> OptUnsafeEdges;
- Register VReg;
+ Register VReg;
GraphMetadata::AllowedRegVecRef AllowedRegs;
#ifndef NDEBUG
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/Register.h b/contrib/libs/llvm12/include/llvm/CodeGen/Register.h
index 1741bcd649..c76978991a 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/Register.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/Register.h
@@ -47,24 +47,24 @@ public:
/// frame index in a variable that normally holds a register. isStackSlot()
/// returns true if Reg is in the range used for stack slots.
///
- /// FIXME: remove in favor of member.
+ /// FIXME: remove in favor of member.
static bool isStackSlot(unsigned Reg) {
return MCRegister::isStackSlot(Reg);
}
- /// Return true if this is a stack slot.
- bool isStack() const { return MCRegister::isStackSlot(Reg); }
-
+ /// Return true if this is a stack slot.
+ bool isStack() const { return MCRegister::isStackSlot(Reg); }
+
/// Compute the frame index from a register value representing a stack slot.
- static int stackSlot2Index(Register Reg) {
- assert(Reg.isStack() && "Not a stack slot");
+ static int stackSlot2Index(Register Reg) {
+ assert(Reg.isStack() && "Not a stack slot");
return int(Reg - MCRegister::FirstStackSlot);
}
/// Convert a non-negative frame index to a stack slot register value.
- static Register index2StackSlot(int FI) {
+ static Register index2StackSlot(int FI) {
assert(FI >= 0 && "Cannot hold a negative frame index.");
- return Register(FI + MCRegister::FirstStackSlot);
+ return Register(FI + MCRegister::FirstStackSlot);
}
/// Return true if the specified register number is in
@@ -76,19 +76,19 @@ public:
/// Return true if the specified register number is in
/// the virtual register namespace.
static bool isVirtualRegister(unsigned Reg) {
- return Reg & MCRegister::VirtualRegFlag && !isStackSlot(Reg);
+ return Reg & MCRegister::VirtualRegFlag && !isStackSlot(Reg);
}
/// Convert a virtual register number to a 0-based index.
/// The first virtual register in a function will get the index 0.
- static unsigned virtReg2Index(Register Reg) {
+ static unsigned virtReg2Index(Register Reg) {
assert(isVirtualRegister(Reg) && "Not a virtual register");
return Reg & ~MCRegister::VirtualRegFlag;
}
/// Convert a 0-based index to a virtual register number.
/// This is the inverse operation of VirtReg2IndexFunctor below.
- static Register index2VirtReg(unsigned Index) {
+ static Register index2VirtReg(unsigned Index) {
assert(Index < (1u << 31) && "Index too large for virtual register range.");
return Index | MCRegister::VirtualRegFlag;
}
@@ -121,15 +121,15 @@ public:
return MCRegister(Reg);
}
- /// Utility to check-convert this value to a MCRegister. The caller is
- /// expected to have already validated that this Register is, indeed,
- /// physical.
- MCRegister asMCReg() const {
- assert(Reg == MCRegister::NoRegister ||
- MCRegister::isPhysicalRegister(Reg));
- return MCRegister(Reg);
- }
-
+ /// Utility to check-convert this value to a MCRegister. The caller is
+ /// expected to have already validated that this Register is, indeed,
+ /// physical.
+ MCRegister asMCReg() const {
+ assert(Reg == MCRegister::NoRegister ||
+ MCRegister::isPhysicalRegister(Reg));
+ return MCRegister(Reg);
+ }
+
bool isValid() const { return Reg != MCRegister::NoRegister; }
/// Comparisons between register objects
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/RegisterPressure.h b/contrib/libs/llvm12/include/llvm/CodeGen/RegisterPressure.h
index b8c675889d..11702d47e2 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/RegisterPressure.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/RegisterPressure.h
@@ -44,10 +44,10 @@ class MachineRegisterInfo;
class RegisterClassInfo;
struct RegisterMaskPair {
- Register RegUnit; ///< Virtual register or register unit.
+ Register RegUnit; ///< Virtual register or register unit.
LaneBitmask LaneMask;
- RegisterMaskPair(Register RegUnit, LaneBitmask LaneMask)
+ RegisterMaskPair(Register RegUnit, LaneBitmask LaneMask)
: RegUnit(RegUnit), LaneMask(LaneMask) {}
};
@@ -164,7 +164,7 @@ public:
const_iterator begin() const { return &PressureChanges[0]; }
const_iterator end() const { return &PressureChanges[MaxPSets]; }
- void addPressureChange(Register RegUnit, bool IsDec,
+ void addPressureChange(Register RegUnit, bool IsDec,
const MachineRegisterInfo *MRI);
void dump(const TargetRegisterInfo &TRI) const;
@@ -282,24 +282,24 @@ private:
RegSet Regs;
unsigned NumRegUnits;
- unsigned getSparseIndexFromReg(Register Reg) const {
- if (Reg.isVirtual())
+ unsigned getSparseIndexFromReg(Register Reg) const {
+ if (Reg.isVirtual())
return Register::virtReg2Index(Reg) + NumRegUnits;
assert(Reg < NumRegUnits);
return Reg;
}
- Register getRegFromSparseIndex(unsigned SparseIndex) const {
+ Register getRegFromSparseIndex(unsigned SparseIndex) const {
if (SparseIndex >= NumRegUnits)
- return Register::index2VirtReg(SparseIndex - NumRegUnits);
- return Register(SparseIndex);
+ return Register::index2VirtReg(SparseIndex - NumRegUnits);
+ return Register(SparseIndex);
}
public:
void clear();
void init(const MachineRegisterInfo &MRI);
- LaneBitmask contains(Register Reg) const {
+ LaneBitmask contains(Register Reg) const {
unsigned SparseIndex = getSparseIndexFromReg(Reg);
RegSet::const_iterator I = Regs.find(SparseIndex);
if (I == Regs.end())
@@ -339,7 +339,7 @@ public:
template<typename ContainerT>
void appendTo(ContainerT &To) const {
for (const IndexMaskPair &P : Regs) {
- Register Reg = getRegFromSparseIndex(P.Index);
+ Register Reg = getRegFromSparseIndex(P.Index);
if (P.LaneMask.any())
To.push_back(RegisterMaskPair(Reg, P.LaneMask));
}
@@ -397,7 +397,7 @@ class RegPressureTracker {
LiveRegSet LiveRegs;
/// Set of vreg defs that start a live range.
- SparseSet<Register, VirtReg2IndexFunctor> UntiedDefs;
+ SparseSet<Register, VirtReg2IndexFunctor> UntiedDefs;
/// Live-through pressure.
std::vector<unsigned> LiveThruPressure;
@@ -539,7 +539,7 @@ public:
return getDownwardPressure(MI, PressureResult, MaxPressureResult);
}
- bool hasUntiedDef(Register VirtReg) const {
+ bool hasUntiedDef(Register VirtReg) const {
return UntiedDefs.count(VirtReg);
}
@@ -555,9 +555,9 @@ protected:
/// after the current position.
SlotIndex getCurrSlot() const;
- void increaseRegPressure(Register RegUnit, LaneBitmask PreviousMask,
+ void increaseRegPressure(Register RegUnit, LaneBitmask PreviousMask,
LaneBitmask NewMask);
- void decreaseRegPressure(Register RegUnit, LaneBitmask PreviousMask,
+ void decreaseRegPressure(Register RegUnit, LaneBitmask PreviousMask,
LaneBitmask NewMask);
void bumpDeadDefs(ArrayRef<RegisterMaskPair> DeadDefs);
@@ -568,9 +568,9 @@ protected:
void discoverLiveInOrOut(RegisterMaskPair Pair,
SmallVectorImpl<RegisterMaskPair> &LiveInOrOut);
- LaneBitmask getLastUsedLanes(Register RegUnit, SlotIndex Pos) const;
- LaneBitmask getLiveLanesAt(Register RegUnit, SlotIndex Pos) const;
- LaneBitmask getLiveThroughAt(Register RegUnit, SlotIndex Pos) const;
+ LaneBitmask getLastUsedLanes(Register RegUnit, SlotIndex Pos) const;
+ LaneBitmask getLiveLanesAt(Register RegUnit, SlotIndex Pos) const;
+ LaneBitmask getLiveThroughAt(Register RegUnit, SlotIndex Pos) const;
};
void dumpRegSetPressure(ArrayRef<unsigned> SetPressure,
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/RegisterScavenging.h b/contrib/libs/llvm12/include/llvm/CodeGen/RegisterScavenging.h
index 54104dcf36..51712f3270 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/RegisterScavenging.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/RegisterScavenging.h
@@ -201,10 +201,10 @@ private:
void determineKillsAndDefs();
/// Add all Reg Units that Reg contains to BV.
- void addRegUnits(BitVector &BV, MCRegister Reg);
+ void addRegUnits(BitVector &BV, MCRegister Reg);
/// Remove all Reg Units that \p Reg contains from \p BV.
- void removeRegUnits(BitVector &BV, MCRegister Reg);
+ void removeRegUnits(BitVector &BV, MCRegister Reg);
/// Return the candidate register that is unused for the longest after
/// StartMI. UseMI is set to the instruction where the search stopped.
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/RuntimeLibcalls.h b/contrib/libs/llvm12/include/llvm/CodeGen/RuntimeLibcalls.h
index 9307012e8b..3aed932f92 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/RuntimeLibcalls.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/RuntimeLibcalls.h
@@ -22,7 +22,7 @@
#define LLVM_CODEGEN_RUNTIMELIBCALLS_H
#include "llvm/CodeGen/ValueTypes.h"
-#include "llvm/Support/AtomicOrdering.h"
+#include "llvm/Support/AtomicOrdering.h"
namespace llvm {
namespace RTLIB {
@@ -68,10 +68,10 @@ namespace RTLIB {
/// UNKNOWN_LIBCALL if there is none.
Libcall getSYNC(unsigned Opc, MVT VT);
- /// Return the outline atomics value for the given opcode, atomic ordering
- /// and type, or UNKNOWN_LIBCALL if there is none.
- Libcall getOUTLINE_ATOMIC(unsigned Opc, AtomicOrdering Order, MVT VT);
-
+ /// Return the outline atomics value for the given opcode, atomic ordering
+ /// and type, or UNKNOWN_LIBCALL if there is none.
+ Libcall getOUTLINE_ATOMIC(unsigned Opc, AtomicOrdering Order, MVT VT);
+
/// getMEMCPY_ELEMENT_UNORDERED_ATOMIC - Return
/// MEMCPY_ELEMENT_UNORDERED_ATOMIC_* value for the given element size or
/// UNKNOW_LIBCALL if there is none.
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/ScheduleDAGInstrs.h b/contrib/libs/llvm12/include/llvm/CodeGen/ScheduleDAGInstrs.h
index 01e55707ec..0ac94e6038 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/ScheduleDAGInstrs.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/ScheduleDAGInstrs.h
@@ -275,11 +275,11 @@ namespace llvm {
return SU->SchedClass;
}
- /// IsReachable - Checks if SU is reachable from TargetSU.
- bool IsReachable(SUnit *SU, SUnit *TargetSU) {
- return Topo.IsReachable(SU, TargetSU);
- }
-
+ /// IsReachable - Checks if SU is reachable from TargetSU.
+ bool IsReachable(SUnit *SU, SUnit *TargetSU) {
+ return Topo.IsReachable(SU, TargetSU);
+ }
+
/// Returns an iterator to the top of the current scheduling region.
MachineBasicBlock::iterator begin() const { return RegionBegin; }
@@ -395,7 +395,7 @@ namespace llvm {
/// Returns an existing SUnit for this MI, or nullptr.
inline SUnit *ScheduleDAGInstrs::getSUnit(MachineInstr *MI) const {
- return MISUnitMap.lookup(MI);
+ return MISUnitMap.lookup(MI);
}
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/ScheduleHazardRecognizer.h b/contrib/libs/llvm12/include/llvm/CodeGen/ScheduleHazardRecognizer.h
index baf035211c..8a3d25f4a9 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/ScheduleHazardRecognizer.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/ScheduleHazardRecognizer.h
@@ -64,7 +64,7 @@ public:
/// other instruction is available, issue it first.
/// * NoopHazard: issuing this instruction would break the program. If
/// some other instruction can be issued, do so, otherwise issue a noop.
- virtual HazardType getHazardType(SUnit *, int Stalls = 0) {
+ virtual HazardType getHazardType(SUnit *, int Stalls = 0) {
return NoHazard;
}
@@ -121,14 +121,14 @@ public:
// Default implementation: count it as a cycle.
AdvanceCycle();
}
-
- /// EmitNoops - This callback is invoked when noops were added to the
- /// instruction stream.
- virtual void EmitNoops(unsigned Quantity) {
- // Default implementation: count it as a cycle.
- for (unsigned i = 0; i < Quantity; ++i)
- EmitNoop();
- }
+
+ /// EmitNoops - This callback is invoked when noops were added to the
+ /// instruction stream.
+ virtual void EmitNoops(unsigned Quantity) {
+ // Default implementation: count it as a cycle.
+ for (unsigned i = 0; i < Quantity; ++i)
+ EmitNoop();
+ }
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/SelectionDAG.h b/contrib/libs/llvm12/include/llvm/CodeGen/SelectionDAG.h
index 1e031095f6..6dd6fcb303 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/SelectionDAG.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/SelectionDAG.h
@@ -70,7 +70,7 @@ class ConstantFP;
class ConstantInt;
class DataLayout;
struct fltSemantics;
-class FunctionLoweringInfo;
+class FunctionLoweringInfo;
class GlobalValue;
struct KnownBits;
class LegacyDivergenceAnalysis;
@@ -338,29 +338,29 @@ public:
virtual void anchor();
};
- /// Help to insert SDNodeFlags automatically in transforming. Use
- /// RAII to save and resume flags in current scope.
- class FlagInserter {
- SelectionDAG &DAG;
- SDNodeFlags Flags;
- FlagInserter *LastInserter;
-
- public:
- FlagInserter(SelectionDAG &SDAG, SDNodeFlags Flags)
- : DAG(SDAG), Flags(Flags),
- LastInserter(SDAG.getFlagInserter()) {
- SDAG.setFlagInserter(this);
- }
- FlagInserter(SelectionDAG &SDAG, SDNode *N)
- : FlagInserter(SDAG, N->getFlags()) {}
-
- FlagInserter(const FlagInserter &) = delete;
- FlagInserter &operator=(const FlagInserter &) = delete;
- ~FlagInserter() { DAG.setFlagInserter(LastInserter); }
-
- const SDNodeFlags getFlags() const { return Flags; }
- };
-
+ /// Help to insert SDNodeFlags automatically in transforming. Use
+ /// RAII to save and resume flags in current scope.
+ class FlagInserter {
+ SelectionDAG &DAG;
+ SDNodeFlags Flags;
+ FlagInserter *LastInserter;
+
+ public:
+ FlagInserter(SelectionDAG &SDAG, SDNodeFlags Flags)
+ : DAG(SDAG), Flags(Flags),
+ LastInserter(SDAG.getFlagInserter()) {
+ SDAG.setFlagInserter(this);
+ }
+ FlagInserter(SelectionDAG &SDAG, SDNode *N)
+ : FlagInserter(SDAG, N->getFlags()) {}
+
+ FlagInserter(const FlagInserter &) = delete;
+ FlagInserter &operator=(const FlagInserter &) = delete;
+ ~FlagInserter() { DAG.setFlagInserter(LastInserter); }
+
+ const SDNodeFlags getFlags() const { return Flags; }
+ };
+
/// When true, additional steps are taken to
/// ensure that getConstant() and similar functions return DAG nodes that
/// have legal types. This is important after type legalization since
@@ -463,9 +463,9 @@ public:
ProfileSummaryInfo *getPSI() const { return PSI; }
BlockFrequencyInfo *getBFI() const { return BFI; }
- FlagInserter *getFlagInserter() { return Inserter; }
- void setFlagInserter(FlagInserter *FI) { Inserter = FI; }
-
+ FlagInserter *getFlagInserter() { return Inserter; }
+ void setFlagInserter(FlagInserter *FI) { Inserter = FI; }
+
/// Just dump dot graph to a user-provided path and title.
/// This doesn't open the dot viewer program and
/// helps visualization when outside debugging session.
@@ -901,7 +901,7 @@ public:
/// Returns sum of the base pointer and offset.
/// Unlike getObjectPtrOffset this does not set NoUnsignedWrap by default.
- SDValue getMemBasePlusOffset(SDValue Base, TypeSize Offset, const SDLoc &DL,
+ SDValue getMemBasePlusOffset(SDValue Base, TypeSize Offset, const SDLoc &DL,
const SDNodeFlags Flags = SDNodeFlags());
SDValue getMemBasePlusOffset(SDValue Base, SDValue Offset, const SDLoc &DL,
const SDNodeFlags Flags = SDNodeFlags());
@@ -909,7 +909,7 @@ public:
/// 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 Ptr, TypeSize Offset) {
+ SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset) {
SDNodeFlags Flags;
Flags.setNoUnsignedWrap(true);
return getMemBasePlusOffset(Ptr, Offset, SL, Flags);
@@ -976,31 +976,31 @@ public:
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
ArrayRef<SDUse> Ops);
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
- ArrayRef<SDValue> Ops, const SDNodeFlags Flags);
+ ArrayRef<SDValue> Ops, const SDNodeFlags Flags);
SDValue getNode(unsigned Opcode, const SDLoc &DL, ArrayRef<EVT> ResultTys,
ArrayRef<SDValue> Ops);
SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
- ArrayRef<SDValue> Ops, const SDNodeFlags Flags);
-
- // Use flags from current flag inserter.
- SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
- ArrayRef<SDValue> Ops);
- SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
- ArrayRef<SDValue> Ops);
- SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue Operand);
- SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
- SDValue N2);
- SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
- SDValue N2, SDValue N3);
-
+ ArrayRef<SDValue> Ops, const SDNodeFlags Flags);
+
+ // Use flags from current flag inserter.
+ SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
+ ArrayRef<SDValue> Ops);
+ SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
+ ArrayRef<SDValue> Ops);
+ SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue Operand);
+ SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
+ SDValue N2);
+ SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
+ SDValue N2, SDValue N3);
+
// Specialize based on number of operands.
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT);
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue Operand,
- const SDNodeFlags Flags);
+ const SDNodeFlags Flags);
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
- SDValue N2, const SDNodeFlags Flags);
+ SDValue N2, const SDNodeFlags Flags);
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
- SDValue N2, SDValue N3, const SDNodeFlags Flags);
+ SDValue N2, SDValue N3, const SDNodeFlags Flags);
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
SDValue N2, SDValue N3, SDValue N4);
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
@@ -1210,12 +1210,12 @@ public:
SDValue getLifetimeNode(bool IsStart, const SDLoc &dl, SDValue Chain,
int FrameIndex, int64_t Size, int64_t Offset = -1);
- /// Creates a PseudoProbeSDNode with function GUID `Guid` and
- /// the index of the block `Index` it is probing, as well as the attributes
- /// `attr` of the probe.
- SDValue getPseudoProbeNode(const SDLoc &Dl, SDValue Chain, uint64_t Guid,
- uint64_t Index, uint32_t Attr);
-
+ /// Creates a PseudoProbeSDNode with function GUID `Guid` and
+ /// the index of the block `Index` it is probing, as well as the attributes
+ /// `attr` of the probe.
+ SDValue getPseudoProbeNode(const SDLoc &Dl, SDValue Chain, uint64_t Guid,
+ uint64_t Index, uint32_t Attr);
+
/// Create a MERGE_VALUES node from the given operands.
SDValue getMergeValues(ArrayRef<SDValue> Ops, const SDLoc &dl);
@@ -1225,15 +1225,15 @@ public:
/// This function will set the MOLoad flag on MMOFlags, but you can set it if
/// you want. The MOStore flag must not be set.
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr,
- MachinePointerInfo PtrInfo,
- MaybeAlign Alignment = MaybeAlign(),
+ MachinePointerInfo PtrInfo,
+ MaybeAlign Alignment = MaybeAlign(),
MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
const AAMDNodes &AAInfo = AAMDNodes(),
const MDNode *Ranges = nullptr);
/// FIXME: Remove once transition to Align is over.
inline SDValue
getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr,
- MachinePointerInfo PtrInfo, unsigned Alignment,
+ MachinePointerInfo PtrInfo, unsigned Alignment,
MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
const AAMDNodes &AAInfo = AAMDNodes(),
const MDNode *Ranges = nullptr) {
@@ -1245,14 +1245,14 @@ public:
SDValue
getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain,
SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT,
- MaybeAlign Alignment = MaybeAlign(),
+ MaybeAlign Alignment = MaybeAlign(),
MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
const AAMDNodes &AAInfo = AAMDNodes());
/// FIXME: Remove once transition to Align is over.
inline SDValue
getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain,
SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT,
- unsigned Alignment,
+ unsigned Alignment,
MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
const AAMDNodes &AAInfo = AAMDNodes()) {
return getExtLoad(ExtType, dl, VT, Chain, Ptr, PtrInfo, MemVT,
@@ -1269,12 +1269,12 @@ public:
MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
const AAMDNodes &AAInfo = AAMDNodes(),
const MDNode *Ranges = nullptr);
- inline SDValue getLoad(
- ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, EVT VT, const SDLoc &dl,
- SDValue Chain, SDValue Ptr, SDValue Offset, MachinePointerInfo PtrInfo,
- EVT MemVT, MaybeAlign Alignment = MaybeAlign(),
- MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
- const AAMDNodes &AAInfo = AAMDNodes(), const MDNode *Ranges = nullptr) {
+ inline SDValue getLoad(
+ ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, EVT VT, const SDLoc &dl,
+ SDValue Chain, SDValue Ptr, SDValue Offset, MachinePointerInfo PtrInfo,
+ EVT MemVT, MaybeAlign Alignment = MaybeAlign(),
+ MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
+ const AAMDNodes &AAInfo = AAMDNodes(), const MDNode *Ranges = nullptr) {
// Ensures that codegen never sees a None Alignment.
return getLoad(AM, ExtType, VT, dl, Chain, Ptr, Offset, PtrInfo, MemVT,
Alignment.getValueOr(getEVTAlign(MemVT)), MMOFlags, AAInfo,
@@ -1284,7 +1284,7 @@ public:
inline SDValue
getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, EVT VT,
const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue Offset,
- MachinePointerInfo PtrInfo, EVT MemVT, unsigned Alignment,
+ MachinePointerInfo PtrInfo, EVT MemVT, unsigned Alignment,
MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
const AAMDNodes &AAInfo = AAMDNodes(),
const MDNode *Ranges = nullptr) {
@@ -1307,7 +1307,7 @@ public:
const AAMDNodes &AAInfo = AAMDNodes());
inline SDValue
getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr,
- MachinePointerInfo PtrInfo, MaybeAlign Alignment = MaybeAlign(),
+ MachinePointerInfo PtrInfo, MaybeAlign Alignment = MaybeAlign(),
MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
const AAMDNodes &AAInfo = AAMDNodes()) {
return getStore(Chain, dl, Val, Ptr, PtrInfo,
@@ -1317,7 +1317,7 @@ public:
/// FIXME: Remove once transition to Align is over.
inline SDValue
getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr,
- MachinePointerInfo PtrInfo, unsigned Alignment,
+ MachinePointerInfo PtrInfo, unsigned Alignment,
MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
const AAMDNodes &AAInfo = AAMDNodes()) {
return getStore(Chain, dl, Val, Ptr, PtrInfo, MaybeAlign(Alignment),
@@ -1332,8 +1332,8 @@ public:
const AAMDNodes &AAInfo = AAMDNodes());
inline SDValue
getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr,
- MachinePointerInfo PtrInfo, EVT SVT,
- MaybeAlign Alignment = MaybeAlign(),
+ MachinePointerInfo PtrInfo, EVT SVT,
+ MaybeAlign Alignment = MaybeAlign(),
MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
const AAMDNodes &AAInfo = AAMDNodes()) {
return getTruncStore(Chain, dl, Val, Ptr, PtrInfo, SVT,
@@ -1343,7 +1343,7 @@ public:
/// FIXME: Remove once transition to Align is over.
inline SDValue
getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr,
- MachinePointerInfo PtrInfo, EVT SVT, unsigned Alignment,
+ MachinePointerInfo PtrInfo, EVT SVT, unsigned Alignment,
MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
const AAMDNodes &AAInfo = AAMDNodes()) {
return getTruncStore(Chain, dl, Val, Ptr, PtrInfo, SVT,
@@ -1369,11 +1369,11 @@ public:
ISD::MemIndexedMode AM);
SDValue getMaskedGather(SDVTList VTs, EVT VT, const SDLoc &dl,
ArrayRef<SDValue> Ops, MachineMemOperand *MMO,
- ISD::MemIndexType IndexType, ISD::LoadExtType ExtTy);
+ ISD::MemIndexType IndexType, ISD::LoadExtType ExtTy);
SDValue getMaskedScatter(SDVTList VTs, EVT VT, const SDLoc &dl,
ArrayRef<SDValue> Ops, MachineMemOperand *MMO,
- ISD::MemIndexType IndexType,
- bool IsTruncating = false);
+ ISD::MemIndexType IndexType,
+ bool IsTruncating = false);
/// Construct a node to track a Value* through the backend.
SDValue getSrcValue(const Value *v);
@@ -1438,9 +1438,9 @@ public:
void setNodeMemRefs(MachineSDNode *N,
ArrayRef<MachineMemOperand *> NewMemRefs);
- // Calculate divergence of node \p N based on its operands.
- bool calculateDivergence(SDNode *N);
-
+ // Calculate divergence of node \p N based on its operands.
+ bool calculateDivergence(SDNode *N);
+
// Propagates the change in divergence to users
void updateDivergence(SDNode * N);
@@ -1518,14 +1518,14 @@ public:
SDValue Operand, SDValue Subreg);
/// Get the specified node if it's already available, or else return NULL.
- SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTList,
- ArrayRef<SDValue> Ops, const SDNodeFlags Flags);
- SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTList,
- ArrayRef<SDValue> Ops);
-
- /// Check if a node exists without modifying its flags.
- bool doesNodeExist(unsigned Opcode, SDVTList VTList, ArrayRef<SDValue> Ops);
-
+ SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTList,
+ ArrayRef<SDValue> Ops, const SDNodeFlags Flags);
+ SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTList,
+ ArrayRef<SDValue> Ops);
+
+ /// Check if a node exists without modifying its flags.
+ bool doesNodeExist(unsigned Opcode, SDVTList VTList, ArrayRef<SDValue> Ops);
+
/// Creates a SDDbgValue node.
SDDbgValue *getDbgValue(DIVariable *Var, DIExpression *Expr, SDNode *N,
unsigned R, bool IsIndirect, const DebugLoc &DL,
@@ -1598,15 +1598,15 @@ public:
/// chain to the token factor. This ensures that the new memory node will have
/// the same relative memory dependency position as the old load. Returns the
/// new merged load chain.
- SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain);
-
- /// If an existing load has uses of its chain, create a token factor node with
- /// that chain and the new memory node's chain and update users of the old
- /// chain to the token factor. This ensures that the new memory node will have
- /// the same relative memory dependency position as the old load. Returns the
- /// new merged load chain.
- SDValue makeEquivalentMemoryOrdering(LoadSDNode *OldLoad, SDValue NewMemOp);
-
+ SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain);
+
+ /// If an existing load has uses of its chain, create a token factor node with
+ /// that chain and the new memory node's chain and update users of the old
+ /// chain to the token factor. This ensures that the new memory node will have
+ /// the same relative memory dependency position as the old load. Returns the
+ /// new merged load chain.
+ SDValue makeEquivalentMemoryOrdering(LoadSDNode *OldLoad, SDValue NewMemOp);
+
/// Topological-sort the AllNodes list and a
/// assign a unique node id for each node in the DAG based on their
/// topological order. Returns the number of nodes.
@@ -1843,8 +1843,8 @@ public:
/// for \p DemandedElts.
///
/// NOTE: The function will return true for a demanded splat of UNDEF values.
- bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts,
- unsigned Depth = 0);
+ bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts,
+ unsigned Depth = 0);
/// Test whether \p V has a splatted value.
bool isSplatValue(SDValue V, bool AllowUndefs = false);
@@ -1966,14 +1966,14 @@ public:
}
/// Test whether the given value is a constant int or similar node.
- SDNode *isConstantIntBuildVectorOrConstantInt(SDValue N) const;
+ SDNode *isConstantIntBuildVectorOrConstantInt(SDValue N) const;
/// Test whether the given value is a constant FP or similar node.
- SDNode *isConstantFPBuildVectorOrConstantFP(SDValue N) const ;
+ SDNode *isConstantFPBuildVectorOrConstantFP(SDValue N) const ;
/// \returns true if \p N is any kind of constant or build_vector of
/// constants, int or float. If a vector, it may not necessarily be a splat.
- inline bool isConstantValueOfAnyType(SDValue N) const {
+ inline bool isConstantValueOfAnyType(SDValue N) const {
return isConstantIntBuildVectorOrConstantInt(N) ||
isConstantFPBuildVectorOrConstantFP(N);
}
@@ -2021,10 +2021,10 @@ public:
bool shouldOptForSize() const;
- /// Get the (commutative) neutral element for the given opcode, if it exists.
- SDValue getNeutralElement(unsigned Opcode, const SDLoc &DL, EVT VT,
- SDNodeFlags Flags);
-
+ /// Get the (commutative) neutral element for the given opcode, if it exists.
+ SDValue getNeutralElement(unsigned Opcode, const SDLoc &DL, EVT VT,
+ SDNodeFlags Flags);
+
private:
void InsertNode(SDNode *N);
bool RemoveNodeFromCSEMaps(SDNode *N);
@@ -2065,8 +2065,8 @@ private:
std::map<std::pair<std::string, unsigned>, SDNode *> TargetExternalSymbols;
DenseMap<MCSymbol *, SDNode *> MCSymbols;
-
- FlagInserter *Inserter = nullptr;
+
+ FlagInserter *Inserter = nullptr;
};
template <> struct GraphTraits<SelectionDAG*> : public GraphTraits<SDNode*> {
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/SelectionDAGNodes.h b/contrib/libs/llvm12/include/llvm/CodeGen/SelectionDAGNodes.h
index e82bdb429f..67be071a77 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -92,43 +92,43 @@ namespace ISD {
/// Node predicates
-/// If N is a BUILD_VECTOR or SPLAT_VECTOR node whose elements are all the
-/// same constant or undefined, return true and return the constant value in
-/// \p SplatValue.
-bool isConstantSplatVector(const SDNode *N, APInt &SplatValue);
-
-/// Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where
-/// all of the elements are ~0 or undef. If \p BuildVectorOnly is set to
-/// true, it only checks BUILD_VECTOR.
-bool isConstantSplatVectorAllOnes(const SDNode *N,
- bool BuildVectorOnly = false);
-
-/// Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where
-/// all of the elements are 0 or undef. If \p BuildVectorOnly is set to true, it
-/// only checks BUILD_VECTOR.
-bool isConstantSplatVectorAllZeros(const SDNode *N,
- bool BuildVectorOnly = false);
-
-/// Return true if the specified node is a BUILD_VECTOR where all of the
-/// elements are ~0 or undef.
-bool isBuildVectorAllOnes(const SDNode *N);
-
-/// Return true if the specified node is a BUILD_VECTOR where all of the
-/// elements are 0 or undef.
-bool isBuildVectorAllZeros(const SDNode *N);
-
-/// Return true if the specified node is a BUILD_VECTOR node of all
-/// ConstantSDNode or undef.
-bool isBuildVectorOfConstantSDNodes(const SDNode *N);
-
-/// Return true if the specified node is a BUILD_VECTOR node of all
-/// ConstantFPSDNode or undef.
-bool isBuildVectorOfConstantFPSDNodes(const SDNode *N);
-
-/// Return true if the node has at least one operand and all operands of the
-/// specified node are ISD::UNDEF.
-bool allOperandsUndef(const SDNode *N);
-
+/// If N is a BUILD_VECTOR or SPLAT_VECTOR node whose elements are all the
+/// same constant or undefined, return true and return the constant value in
+/// \p SplatValue.
+bool isConstantSplatVector(const SDNode *N, APInt &SplatValue);
+
+/// Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where
+/// all of the elements are ~0 or undef. If \p BuildVectorOnly is set to
+/// true, it only checks BUILD_VECTOR.
+bool isConstantSplatVectorAllOnes(const SDNode *N,
+ bool BuildVectorOnly = false);
+
+/// Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where
+/// all of the elements are 0 or undef. If \p BuildVectorOnly is set to true, it
+/// only checks BUILD_VECTOR.
+bool isConstantSplatVectorAllZeros(const SDNode *N,
+ bool BuildVectorOnly = false);
+
+/// Return true if the specified node is a BUILD_VECTOR where all of the
+/// elements are ~0 or undef.
+bool isBuildVectorAllOnes(const SDNode *N);
+
+/// Return true if the specified node is a BUILD_VECTOR where all of the
+/// elements are 0 or undef.
+bool isBuildVectorAllZeros(const SDNode *N);
+
+/// Return true if the specified node is a BUILD_VECTOR node of all
+/// ConstantSDNode or undef.
+bool isBuildVectorOfConstantSDNodes(const SDNode *N);
+
+/// Return true if the specified node is a BUILD_VECTOR node of all
+/// ConstantFPSDNode or undef.
+bool isBuildVectorOfConstantFPSDNodes(const SDNode *N);
+
+/// Return true if the node has at least one operand and all operands of the
+/// specified node are ISD::UNDEF.
+bool allOperandsUndef(const SDNode *N);
+
} // end namespace ISD
//===----------------------------------------------------------------------===//
@@ -200,8 +200,8 @@ public:
return getValueType().getSizeInBits();
}
- uint64_t getScalarValueSizeInBits() const {
- return getValueType().getScalarType().getFixedSizeInBits();
+ uint64_t getScalarValueSizeInBits() const {
+ return getValueType().getScalarType().getFixedSizeInBits();
}
// Forwarding methods - These forward to the corresponding methods in SDNode.
@@ -398,8 +398,8 @@ private:
public:
/// Default constructor turns off all optimization flags.
SDNodeFlags()
- : NoUnsignedWrap(false), NoSignedWrap(false), Exact(false), NoNaNs(false),
- NoInfs(false), NoSignedZeros(false), AllowReciprocal(false),
+ : NoUnsignedWrap(false), NoSignedWrap(false), Exact(false), NoNaNs(false),
+ NoInfs(false), NoSignedZeros(false), AllowReciprocal(false),
AllowContract(false), ApproximateFuncs(false),
AllowReassociation(false), NoFPExcept(false) {}
@@ -415,17 +415,17 @@ public:
}
// These are mutators for each flag.
- void setNoUnsignedWrap(bool b) { NoUnsignedWrap = b; }
- void setNoSignedWrap(bool b) { NoSignedWrap = b; }
- void setExact(bool b) { Exact = b; }
- void setNoNaNs(bool b) { NoNaNs = b; }
- void setNoInfs(bool b) { NoInfs = b; }
- void setNoSignedZeros(bool b) { NoSignedZeros = b; }
- void setAllowReciprocal(bool b) { AllowReciprocal = b; }
- void setAllowContract(bool b) { AllowContract = b; }
- void setApproximateFuncs(bool b) { ApproximateFuncs = b; }
- void setAllowReassociation(bool b) { AllowReassociation = b; }
- void setNoFPExcept(bool b) { NoFPExcept = b; }
+ void setNoUnsignedWrap(bool b) { NoUnsignedWrap = b; }
+ void setNoSignedWrap(bool b) { NoSignedWrap = b; }
+ void setExact(bool b) { Exact = b; }
+ void setNoNaNs(bool b) { NoNaNs = b; }
+ void setNoInfs(bool b) { NoInfs = b; }
+ void setNoSignedZeros(bool b) { NoSignedZeros = b; }
+ void setAllowReciprocal(bool b) { AllowReciprocal = b; }
+ void setAllowContract(bool b) { AllowContract = b; }
+ void setApproximateFuncs(bool b) { ApproximateFuncs = b; }
+ void setAllowReassociation(bool b) { AllowReassociation = b; }
+ void setNoFPExcept(bool b) { NoFPExcept = b; }
// These are accessors for each flag.
bool hasNoUnsignedWrap() const { return NoUnsignedWrap; }
@@ -440,8 +440,8 @@ public:
bool hasAllowReassociation() const { return AllowReassociation; }
bool hasNoFPExcept() const { return NoFPExcept; }
- /// Clear any flags in this flag set that aren't also set in Flags. All
- /// flags will be cleared if Flags are undefined.
+ /// Clear any flags in this flag set that aren't also set in Flags. All
+ /// flags will be cleared if Flags are undefined.
void intersectWith(const SDNodeFlags Flags) {
NoUnsignedWrap &= Flags.NoUnsignedWrap;
NoSignedWrap &= Flags.NoSignedWrap;
@@ -533,7 +533,7 @@ BEGIN_TWO_BYTE_PACK()
class LoadSDNodeBitfields {
friend class LoadSDNode;
friend class MaskedLoadSDNode;
- friend class MaskedGatherSDNode;
+ friend class MaskedGatherSDNode;
uint16_t : NumLSBaseSDNodeBits;
@@ -544,7 +544,7 @@ BEGIN_TWO_BYTE_PACK()
class StoreSDNodeBitfields {
friend class StoreSDNode;
friend class MaskedStoreSDNode;
- friend class MaskedScatterSDNode;
+ friend class MaskedScatterSDNode;
uint16_t : NumLSBaseSDNodeBits;
@@ -696,7 +696,7 @@ public:
bool use_empty() const { return UseList == nullptr; }
/// Return true if there is exactly one use of this node.
- bool hasOneUse() const { return hasSingleElement(uses()); }
+ bool hasOneUse() const { return hasSingleElement(uses()); }
/// Return the number of uses of this node. This method takes
/// time proportional to the number of uses.
@@ -1353,18 +1353,18 @@ public:
}
const SDValue &getChain() const { return getOperand(0); }
-
+
const SDValue &getBasePtr() const {
- switch (getOpcode()) {
- case ISD::STORE:
- case ISD::MSTORE:
- return getOperand(2);
- case ISD::MGATHER:
- case ISD::MSCATTER:
- return getOperand(3);
- default:
- return getOperand(1);
- }
+ switch (getOpcode()) {
+ case ISD::STORE:
+ case ISD::MSTORE:
+ return getOperand(2);
+ case ISD::MGATHER:
+ case ISD::MSCATTER:
+ return getOperand(3);
+ default:
+ return getOperand(1);
+ }
}
// Methods to support isa and dyn_cast
@@ -1768,32 +1768,32 @@ public:
}
};
-/// This SDNode is used for PSEUDO_PROBE values, which are the function guid and
-/// the index of the basic block being probed. A pseudo probe serves as a place
-/// holder and will be removed at the end of compilation. It does not have any
-/// operand because we do not want the instruction selection to deal with any.
-class PseudoProbeSDNode : public SDNode {
- friend class SelectionDAG;
- uint64_t Guid;
- uint64_t Index;
- uint32_t Attributes;
-
- PseudoProbeSDNode(unsigned Opcode, unsigned Order, const DebugLoc &Dl,
- SDVTList VTs, uint64_t Guid, uint64_t Index, uint32_t Attr)
- : SDNode(Opcode, Order, Dl, VTs), Guid(Guid), Index(Index),
- Attributes(Attr) {}
-
-public:
- uint64_t getGuid() const { return Guid; }
- uint64_t getIndex() const { return Index; }
- uint32_t getAttributes() const { return Attributes; }
-
- // Methods to support isa and dyn_cast
- static bool classof(const SDNode *N) {
- return N->getOpcode() == ISD::PSEUDO_PROBE;
- }
-};
-
+/// This SDNode is used for PSEUDO_PROBE values, which are the function guid and
+/// the index of the basic block being probed. A pseudo probe serves as a place
+/// holder and will be removed at the end of compilation. It does not have any
+/// operand because we do not want the instruction selection to deal with any.
+class PseudoProbeSDNode : public SDNode {
+ friend class SelectionDAG;
+ uint64_t Guid;
+ uint64_t Index;
+ uint32_t Attributes;
+
+ PseudoProbeSDNode(unsigned Opcode, unsigned Order, const DebugLoc &Dl,
+ SDVTList VTs, uint64_t Guid, uint64_t Index, uint32_t Attr)
+ : SDNode(Opcode, Order, Dl, VTs), Guid(Guid), Index(Index),
+ Attributes(Attr) {}
+
+public:
+ uint64_t getGuid() const { return Guid; }
+ uint64_t getIndex() const { return Index; }
+ uint32_t getAttributes() const { return Attributes; }
+
+ // Methods to support isa and dyn_cast
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::PSEUDO_PROBE;
+ }
+};
+
class JumpTableSDNode : public SDNode {
friend class SelectionDAG;
@@ -1954,33 +1954,33 @@ public:
/// the vector width and set the bits where elements are undef.
SDValue getSplatValue(BitVector *UndefElements = nullptr) const;
- /// Find the shortest repeating sequence of values in the build vector.
- ///
- /// e.g. { u, X, u, X, u, u, X, u } -> { X }
- /// { X, Y, u, Y, u, u, X, u } -> { X, Y }
- ///
- /// Currently this must be a power-of-2 build vector.
- /// The DemandedElts mask indicates the elements that must be present,
- /// undemanded elements in Sequence may be null (SDValue()). If passed a
- /// non-null UndefElements bitvector, it will resize it to match the original
- /// vector width and set the bits where elements are undef. If result is
- /// false, Sequence will be empty.
- bool getRepeatedSequence(const APInt &DemandedElts,
- SmallVectorImpl<SDValue> &Sequence,
- BitVector *UndefElements = nullptr) const;
-
- /// Find the shortest repeating sequence of values in the build vector.
- ///
- /// e.g. { u, X, u, X, u, u, X, u } -> { X }
- /// { X, Y, u, Y, u, u, X, u } -> { X, Y }
- ///
- /// Currently this must be a power-of-2 build vector.
- /// If passed a non-null UndefElements bitvector, it will resize it to match
- /// the original vector width and set the bits where elements are undef.
- /// If result is false, Sequence will be empty.
- bool getRepeatedSequence(SmallVectorImpl<SDValue> &Sequence,
- BitVector *UndefElements = nullptr) const;
-
+ /// Find the shortest repeating sequence of values in the build vector.
+ ///
+ /// e.g. { u, X, u, X, u, u, X, u } -> { X }
+ /// { X, Y, u, Y, u, u, X, u } -> { X, Y }
+ ///
+ /// Currently this must be a power-of-2 build vector.
+ /// The DemandedElts mask indicates the elements that must be present,
+ /// undemanded elements in Sequence may be null (SDValue()). If passed a
+ /// non-null UndefElements bitvector, it will resize it to match the original
+ /// vector width and set the bits where elements are undef. If result is
+ /// false, Sequence will be empty.
+ bool getRepeatedSequence(const APInt &DemandedElts,
+ SmallVectorImpl<SDValue> &Sequence,
+ BitVector *UndefElements = nullptr) const;
+
+ /// Find the shortest repeating sequence of values in the build vector.
+ ///
+ /// e.g. { u, X, u, X, u, u, X, u } -> { X }
+ /// { X, Y, u, Y, u, u, X, u } -> { X, Y }
+ ///
+ /// Currently this must be a power-of-2 build vector.
+ /// If passed a non-null UndefElements bitvector, it will resize it to match
+ /// the original vector width and set the bits where elements are undef.
+ /// If result is false, Sequence will be empty.
+ bool getRepeatedSequence(SmallVectorImpl<SDValue> &Sequence,
+ BitVector *UndefElements = nullptr) const;
+
/// Returns the demanded splatted constant or null if this is not a constant
/// splat.
///
@@ -2436,9 +2436,9 @@ public:
ISD::MemIndexType getIndexType() const {
return static_cast<ISD::MemIndexType>(LSBaseSDNodeBits.AddressingMode);
}
- void setIndexType(ISD::MemIndexType IndexType) {
- LSBaseSDNodeBits.AddressingMode = IndexType;
- }
+ void setIndexType(ISD::MemIndexType IndexType) {
+ LSBaseSDNodeBits.AddressingMode = IndexType;
+ }
bool isIndexScaled() const {
return (getIndexType() == ISD::SIGNED_SCALED) ||
(getIndexType() == ISD::UNSIGNED_SCALED);
@@ -2471,18 +2471,18 @@ public:
MaskedGatherSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
EVT MemVT, MachineMemOperand *MMO,
- ISD::MemIndexType IndexType, ISD::LoadExtType ETy)
+ ISD::MemIndexType IndexType, ISD::LoadExtType ETy)
: MaskedGatherScatterSDNode(ISD::MGATHER, Order, dl, VTs, MemVT, MMO,
- IndexType) {
- LoadSDNodeBits.ExtTy = ETy;
- }
+ IndexType) {
+ LoadSDNodeBits.ExtTy = ETy;
+ }
const SDValue &getPassThru() const { return getOperand(1); }
- ISD::LoadExtType getExtensionType() const {
- return ISD::LoadExtType(LoadSDNodeBits.ExtTy);
- }
-
+ ISD::LoadExtType getExtensionType() const {
+ return ISD::LoadExtType(LoadSDNodeBits.ExtTy);
+ }
+
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::MGATHER;
}
@@ -2496,17 +2496,17 @@ public:
MaskedScatterSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
EVT MemVT, MachineMemOperand *MMO,
- ISD::MemIndexType IndexType, bool IsTrunc)
+ ISD::MemIndexType IndexType, bool IsTrunc)
: MaskedGatherScatterSDNode(ISD::MSCATTER, Order, dl, VTs, MemVT, MMO,
- IndexType) {
- StoreSDNodeBits.IsTruncating = IsTrunc;
- }
-
- /// Return true if the op does a truncation before store.
- /// For integers this is the same as doing a TRUNCATE and storing the result.
- /// For floats, it is the same as doing an FP_ROUND and storing the result.
- bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
-
+ IndexType) {
+ StoreSDNodeBits.IsTruncating = IsTrunc;
+ }
+
+ /// Return true if the op does a truncation before store.
+ /// For integers this is the same as doing a TRUNCATE and storing the result.
+ /// For floats, it is the same as doing an FP_ROUND and storing the result.
+ bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
+
const SDValue &getValue() const { return getOperand(1); }
static bool classof(const SDNode *N) {
@@ -2655,8 +2655,8 @@ template <> struct GraphTraits<SDNode*> {
/// with 4 and 8 byte pointer alignment, respectively.
using LargestSDNode = AlignedCharArrayUnion<AtomicSDNode, TargetIndexSDNode,
BlockAddressSDNode,
- GlobalAddressSDNode,
- PseudoProbeSDNode>;
+ GlobalAddressSDNode,
+ PseudoProbeSDNode>;
/// The SDNode class with the greatest alignment requirement.
using MostAlignedSDNode = GlobalAddressSDNode;
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/SelectionDAGTargetInfo.h b/contrib/libs/llvm12/include/llvm/CodeGen/SelectionDAGTargetInfo.h
index 75cf58105b..ea589cf12a 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/SelectionDAGTargetInfo.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/SelectionDAGTargetInfo.h
@@ -92,7 +92,7 @@ public:
return SDValue();
}
- /// Emit target-specific code that performs a memcmp/bcmp, in cases where that is
+ /// Emit target-specific code that performs a memcmp/bcmp, in cases where that is
/// faster than a libcall. The first returned SDValue is the result of the
/// memcmp and the second is the chain. Both SDValues can be null if a normal
/// libcall should be used.
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/SlotIndexes.h b/contrib/libs/llvm12/include/llvm/CodeGen/SlotIndexes.h
index 9b7b676bfc..c25f9ec9a3 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/SlotIndexes.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/SlotIndexes.h
@@ -611,23 +611,23 @@ class raw_ostream;
}
/// Add the given MachineBasicBlock into the maps.
- /// If it contains any instructions then they must already be in the maps.
- /// This is used after a block has been split by moving some suffix of its
- /// instructions into a newly created block.
- void insertMBBInMaps(MachineBasicBlock *mbb) {
- assert(mbb != &mbb->getParent()->front() &&
- "Can't insert a new block at the beginning of a function.");
- auto prevMBB = std::prev(MachineFunction::iterator(mbb));
-
- // Create a new entry to be used for the start of mbb and the end of
- // prevMBB.
- IndexListEntry *startEntry = createEntry(nullptr, 0);
- IndexListEntry *endEntry = getMBBEndIdx(&*prevMBB).listEntry();
- IndexListEntry *insEntry =
- mbb->empty() ? endEntry
- : getInstructionIndex(mbb->front()).listEntry();
- IndexList::iterator newItr =
- indexList.insert(insEntry->getIterator(), startEntry);
+ /// If it contains any instructions then they must already be in the maps.
+ /// This is used after a block has been split by moving some suffix of its
+ /// instructions into a newly created block.
+ void insertMBBInMaps(MachineBasicBlock *mbb) {
+ assert(mbb != &mbb->getParent()->front() &&
+ "Can't insert a new block at the beginning of a function.");
+ auto prevMBB = std::prev(MachineFunction::iterator(mbb));
+
+ // Create a new entry to be used for the start of mbb and the end of
+ // prevMBB.
+ IndexListEntry *startEntry = createEntry(nullptr, 0);
+ IndexListEntry *endEntry = getMBBEndIdx(&*prevMBB).listEntry();
+ IndexListEntry *insEntry =
+ mbb->empty() ? endEntry
+ : getInstructionIndex(mbb->front()).listEntry();
+ IndexList::iterator newItr =
+ indexList.insert(insEntry->getIterator(), startEntry);
SlotIndex startIdx(startEntry, SlotIndex::Slot_Block);
SlotIndex endIdx(endEntry, SlotIndex::Slot_Block);
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/StableHashing.h b/contrib/libs/llvm12/include/llvm/CodeGen/StableHashing.h
index a108bd88d1..f8a8c2f18f 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/StableHashing.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/StableHashing.h
@@ -1,123 +1,123 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- llvm/CodeGen/StableHashing.h - Utilities for stable hashing * C++ *-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides types and functions for computing and combining stable
-// hashes. Stable hashes can be useful for hashing across different modules,
-// processes, or compiler runs.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_STABLEHASHING_H
-#define LLVM_CODEGEN_STABLEHASHING_H
-
-#include "llvm/ADT/StringRef.h"
-
-namespace llvm {
-
-/// An opaque object representing a stable hash code. It can be serialized,
-/// deserialized, and is stable across processes and executions.
-using stable_hash = uint64_t;
-
-// Implementation details
-namespace hashing {
-namespace detail {
-
-// Stable hashes are based on the 64-bit FNV-1 hash:
-// https://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function
-
-const uint64_t FNV_PRIME_64 = 1099511628211u;
-const uint64_t FNV_OFFSET_64 = 14695981039346656037u;
-
-inline void stable_hash_append(stable_hash &Hash, const char Value) {
- Hash = Hash ^ (Value & 0xFF);
- Hash = Hash * FNV_PRIME_64;
-}
-
-inline void stable_hash_append(stable_hash &Hash, stable_hash Value) {
- for (unsigned I = 0; I < 8; ++I) {
- stable_hash_append(Hash, static_cast<char>(Value));
- Value >>= 8;
- }
-}
-
-} // namespace detail
-} // namespace hashing
-
-inline stable_hash stable_hash_combine(stable_hash A, stable_hash B) {
- stable_hash Hash = hashing::detail::FNV_OFFSET_64;
- hashing::detail::stable_hash_append(Hash, A);
- hashing::detail::stable_hash_append(Hash, B);
- return Hash;
-}
-
-inline stable_hash stable_hash_combine(stable_hash A, stable_hash B,
- stable_hash C) {
- stable_hash Hash = hashing::detail::FNV_OFFSET_64;
- hashing::detail::stable_hash_append(Hash, A);
- hashing::detail::stable_hash_append(Hash, B);
- hashing::detail::stable_hash_append(Hash, C);
- return Hash;
-}
-
-inline stable_hash stable_hash_combine(stable_hash A, stable_hash B,
- stable_hash C, stable_hash D) {
- stable_hash Hash = hashing::detail::FNV_OFFSET_64;
- hashing::detail::stable_hash_append(Hash, A);
- hashing::detail::stable_hash_append(Hash, B);
- hashing::detail::stable_hash_append(Hash, C);
- hashing::detail::stable_hash_append(Hash, D);
- return Hash;
-}
-
-/// Compute a stable_hash for a sequence of values.
-///
-/// This hashes a sequence of values. It produces the same stable_hash as
-/// 'stable_hash_combine(a, b, c, ...)', but can run over arbitrary sized
-/// sequences and is significantly faster given pointers and types which
-/// can be hashed as a sequence of bytes.
-template <typename InputIteratorT>
-stable_hash stable_hash_combine_range(InputIteratorT First,
- InputIteratorT Last) {
- stable_hash Hash = hashing::detail::FNV_OFFSET_64;
- for (auto I = First; I != Last; ++I)
- hashing::detail::stable_hash_append(Hash, *I);
- return Hash;
-}
-
-inline stable_hash stable_hash_combine_array(const stable_hash *P, size_t C) {
- stable_hash Hash = hashing::detail::FNV_OFFSET_64;
- for (size_t I = 0; I < C; ++I)
- hashing::detail::stable_hash_append(Hash, P[I]);
- return Hash;
-}
-
-inline stable_hash stable_hash_combine_string(const StringRef &S) {
- return stable_hash_combine_range(S.begin(), S.end());
-}
-
-inline stable_hash stable_hash_combine_string(const char *C) {
- stable_hash Hash = hashing::detail::FNV_OFFSET_64;
- while (*C)
- hashing::detail::stable_hash_append(Hash, *(C++));
- return Hash;
-}
-
-} // namespace llvm
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- llvm/CodeGen/StableHashing.h - Utilities for stable hashing * C++ *-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides types and functions for computing and combining stable
+// hashes. Stable hashes can be useful for hashing across different modules,
+// processes, or compiler runs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_STABLEHASHING_H
+#define LLVM_CODEGEN_STABLEHASHING_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+/// An opaque object representing a stable hash code. It can be serialized,
+/// deserialized, and is stable across processes and executions.
+using stable_hash = uint64_t;
+
+// Implementation details
+namespace hashing {
+namespace detail {
+
+// Stable hashes are based on the 64-bit FNV-1 hash:
+// https://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function
+
+const uint64_t FNV_PRIME_64 = 1099511628211u;
+const uint64_t FNV_OFFSET_64 = 14695981039346656037u;
+
+inline void stable_hash_append(stable_hash &Hash, const char Value) {
+ Hash = Hash ^ (Value & 0xFF);
+ Hash = Hash * FNV_PRIME_64;
+}
+
+inline void stable_hash_append(stable_hash &Hash, stable_hash Value) {
+ for (unsigned I = 0; I < 8; ++I) {
+ stable_hash_append(Hash, static_cast<char>(Value));
+ Value >>= 8;
+ }
+}
+
+} // namespace detail
+} // namespace hashing
+
+inline stable_hash stable_hash_combine(stable_hash A, stable_hash B) {
+ stable_hash Hash = hashing::detail::FNV_OFFSET_64;
+ hashing::detail::stable_hash_append(Hash, A);
+ hashing::detail::stable_hash_append(Hash, B);
+ return Hash;
+}
+
+inline stable_hash stable_hash_combine(stable_hash A, stable_hash B,
+ stable_hash C) {
+ stable_hash Hash = hashing::detail::FNV_OFFSET_64;
+ hashing::detail::stable_hash_append(Hash, A);
+ hashing::detail::stable_hash_append(Hash, B);
+ hashing::detail::stable_hash_append(Hash, C);
+ return Hash;
+}
+
+inline stable_hash stable_hash_combine(stable_hash A, stable_hash B,
+ stable_hash C, stable_hash D) {
+ stable_hash Hash = hashing::detail::FNV_OFFSET_64;
+ hashing::detail::stable_hash_append(Hash, A);
+ hashing::detail::stable_hash_append(Hash, B);
+ hashing::detail::stable_hash_append(Hash, C);
+ hashing::detail::stable_hash_append(Hash, D);
+ return Hash;
+}
+
+/// Compute a stable_hash for a sequence of values.
+///
+/// This hashes a sequence of values. It produces the same stable_hash as
+/// 'stable_hash_combine(a, b, c, ...)', but can run over arbitrary sized
+/// sequences and is significantly faster given pointers and types which
+/// can be hashed as a sequence of bytes.
+template <typename InputIteratorT>
+stable_hash stable_hash_combine_range(InputIteratorT First,
+ InputIteratorT Last) {
+ stable_hash Hash = hashing::detail::FNV_OFFSET_64;
+ for (auto I = First; I != Last; ++I)
+ hashing::detail::stable_hash_append(Hash, *I);
+ return Hash;
+}
+
+inline stable_hash stable_hash_combine_array(const stable_hash *P, size_t C) {
+ stable_hash Hash = hashing::detail::FNV_OFFSET_64;
+ for (size_t I = 0; I < C; ++I)
+ hashing::detail::stable_hash_append(Hash, P[I]);
+ return Hash;
+}
+
+inline stable_hash stable_hash_combine_string(const StringRef &S) {
+ return stable_hash_combine_range(S.begin(), S.end());
+}
+
+inline stable_hash stable_hash_combine_string(const char *C) {
+ stable_hash Hash = hashing::detail::FNV_OFFSET_64;
+ while (*C)
+ hashing::detail::stable_hash_append(Hash, *(C++));
+ return Hash;
+}
+
+} // namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/StackMaps.h b/contrib/libs/llvm12/include/llvm/CodeGen/StackMaps.h
index 4453c25b1f..4f7c32e0a3 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/StackMaps.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/StackMaps.h
@@ -155,13 +155,13 @@ public:
/// <StackMaps::ConstantOp>, <calling convention>,
/// <StackMaps::ConstantOp>, <statepoint flags>,
/// <StackMaps::ConstantOp>, <num deopt args>, [deopt args...],
-/// <StackMaps::ConstantOp>, <num gc pointer args>, [gc pointer args...],
-/// <StackMaps::ConstantOp>, <num gc allocas>, [gc allocas args...],
-/// <StackMaps::ConstantOp>, <num entries in gc map>, [base/derived pairs]
-/// base/derived pairs in gc map are logical indices into <gc pointer args>
-/// section.
-/// All gc pointers assigned to VRegs produce new value (in form of MI Def
-/// operand) and are tied to it.
+/// <StackMaps::ConstantOp>, <num gc pointer args>, [gc pointer args...],
+/// <StackMaps::ConstantOp>, <num gc allocas>, [gc allocas args...],
+/// <StackMaps::ConstantOp>, <num entries in gc map>, [base/derived pairs]
+/// base/derived pairs in gc map are logical indices into <gc pointer args>
+/// section.
+/// All gc pointers assigned to VRegs produce new value (in form of MI Def
+/// operand) and are tied to it.
class StatepointOpers {
// TODO:: we should change the STATEPOINT representation so that CC and
// Flags should be part of meta operands, with args and deopt operands, and
@@ -177,23 +177,23 @@ class StatepointOpers {
enum { CCOffset = 1, FlagsOffset = 3, NumDeoptOperandsOffset = 5 };
public:
- explicit StatepointOpers(const MachineInstr *MI) : MI(MI) {
- NumDefs = MI->getNumDefs();
- }
+ explicit StatepointOpers(const MachineInstr *MI) : MI(MI) {
+ NumDefs = MI->getNumDefs();
+ }
/// Get index of statepoint ID operand.
- unsigned getIDPos() const { return NumDefs + IDPos; }
+ unsigned getIDPos() const { return NumDefs + IDPos; }
/// Get index of Num Patch Bytes operand.
- unsigned getNBytesPos() const { return NumDefs + NBytesPos; }
+ unsigned getNBytesPos() const { return NumDefs + NBytesPos; }
/// Get index of Num Call Arguments operand.
- unsigned getNCallArgsPos() const { return NumDefs + NCallArgsPos; }
+ unsigned getNCallArgsPos() const { return NumDefs + NCallArgsPos; }
/// Get starting index of non call related arguments
/// (calling convention, statepoint flags, vm state and gc state).
unsigned getVarIdx() const {
- return MI->getOperand(NumDefs + NCallArgsPos).getImm() + MetaEnd + NumDefs;
+ return MI->getOperand(NumDefs + NCallArgsPos).getImm() + MetaEnd + NumDefs;
}
/// Get index of Calling Convention operand.
@@ -208,16 +208,16 @@ public:
}
/// Return the ID for the given statepoint.
- uint64_t getID() const { return MI->getOperand(NumDefs + IDPos).getImm(); }
+ uint64_t getID() const { return MI->getOperand(NumDefs + IDPos).getImm(); }
/// Return the number of patchable bytes the given statepoint should emit.
uint32_t getNumPatchBytes() const {
- return MI->getOperand(NumDefs + NBytesPos).getImm();
+ return MI->getOperand(NumDefs + NBytesPos).getImm();
}
/// Return the target of the underlying call.
const MachineOperand &getCallTarget() const {
- return MI->getOperand(NumDefs + CallTargetPos);
+ return MI->getOperand(NumDefs + CallTargetPos);
}
/// Return the calling convention.
@@ -228,31 +228,31 @@ public:
/// Return the statepoint flags.
uint64_t getFlags() const { return MI->getOperand(getFlagsIdx()).getImm(); }
- uint64_t getNumDeoptArgs() const {
- return MI->getOperand(getNumDeoptArgsIdx()).getImm();
- }
-
- /// Get index of number of gc map entries.
- unsigned getNumGcMapEntriesIdx();
-
- /// Get index of number of gc allocas.
- unsigned getNumAllocaIdx();
-
- /// Get index of number of GC pointers.
- unsigned getNumGCPtrIdx();
-
- /// Get index of first GC pointer operand of -1 if there are none.
- int getFirstGCPtrIdx();
-
- /// Get vector of base/derived pairs from statepoint.
- /// Elements are indices into GC Pointer operand list (logical).
- /// Returns number of elements in GCMap.
- unsigned
- getGCPointerMap(SmallVectorImpl<std::pair<unsigned, unsigned>> &GCMap);
-
+ uint64_t getNumDeoptArgs() const {
+ return MI->getOperand(getNumDeoptArgsIdx()).getImm();
+ }
+
+ /// Get index of number of gc map entries.
+ unsigned getNumGcMapEntriesIdx();
+
+ /// Get index of number of gc allocas.
+ unsigned getNumAllocaIdx();
+
+ /// Get index of number of GC pointers.
+ unsigned getNumGCPtrIdx();
+
+ /// Get index of first GC pointer operand of -1 if there are none.
+ int getFirstGCPtrIdx();
+
+ /// Get vector of base/derived pairs from statepoint.
+ /// Elements are indices into GC Pointer operand list (logical).
+ /// Returns number of elements in GCMap.
+ unsigned
+ getGCPointerMap(SmallVectorImpl<std::pair<unsigned, unsigned>> &GCMap);
+
private:
const MachineInstr *MI;
- unsigned NumDefs;
+ unsigned NumDefs;
};
class StackMaps {
@@ -294,10 +294,10 @@ public:
StackMaps(AsmPrinter &AP);
- /// Get index of next meta operand.
- /// Similar to parseOperand, but does not actually parses operand meaning.
- static unsigned getNextMetaArgIdx(const MachineInstr *MI, unsigned CurIdx);
-
+ /// Get index of next meta operand.
+ /// Similar to parseOperand, but does not actually parses operand meaning.
+ static unsigned getNextMetaArgIdx(const MachineInstr *MI, unsigned CurIdx);
+
void reset() {
CSInfos.clear();
ConstPool.clear();
@@ -370,13 +370,13 @@ private:
MachineInstr::const_mop_iterator MOE, LocationVec &Locs,
LiveOutVec &LiveOuts) const;
- /// Specialized parser of statepoint operands.
- /// They do not directly correspond to StackMap record entries.
- void parseStatepointOpers(const MachineInstr &MI,
- MachineInstr::const_mop_iterator MOI,
- MachineInstr::const_mop_iterator MOE,
- LocationVec &Locations, LiveOutVec &LiveOuts);
-
+ /// Specialized parser of statepoint operands.
+ /// They do not directly correspond to StackMap record entries.
+ void parseStatepointOpers(const MachineInstr &MI,
+ MachineInstr::const_mop_iterator MOI,
+ MachineInstr::const_mop_iterator MOE,
+ LocationVec &Locations, LiveOutVec &LiveOuts);
+
/// Create a live-out register record for the given register @p Reg.
LiveOutReg createLiveOutReg(unsigned Reg,
const TargetRegisterInfo *TRI) const;
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/SwitchLoweringUtils.h b/contrib/libs/llvm12/include/llvm/CodeGen/SwitchLoweringUtils.h
index 0589b8cfa9..c2c565d9e7 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/SwitchLoweringUtils.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/SwitchLoweringUtils.h
@@ -17,21 +17,21 @@
#define LLVM_CODEGEN_SWITCHLOWERINGUTILS_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
-#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/Support/BranchProbability.h"
-#include <vector>
+#include <vector>
namespace llvm {
-class BlockFrequencyInfo;
-class ConstantInt;
+class BlockFrequencyInfo;
+class ConstantInt;
class FunctionLoweringInfo;
class MachineBasicBlock;
-class ProfileSummaryInfo;
-class TargetLowering;
-class TargetMachine;
+class ProfileSummaryInfo;
+class TargetLowering;
+class TargetMachine;
namespace SwitchCG {
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/TargetCallingConv.h b/contrib/libs/llvm12/include/llvm/CodeGen/TargetCallingConv.h
index 1133bb8844..fde9c476e3 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/TargetCallingConv.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/TargetCallingConv.h
@@ -38,7 +38,7 @@ namespace ISD {
unsigned IsInReg : 1; ///< Passed in register
unsigned IsSRet : 1; ///< Hidden struct-ret ptr
unsigned IsByVal : 1; ///< Struct passed by value
- unsigned IsByRef : 1; ///< Passed in memory
+ unsigned IsByRef : 1; ///< Passed in memory
unsigned IsNest : 1; ///< Nested fn static chain
unsigned IsReturned : 1; ///< Always returned
unsigned IsSplit : 1;
@@ -51,31 +51,31 @@ namespace ISD {
unsigned IsHva : 1; ///< HVA field for
unsigned IsHvaStart : 1; ///< HVA structure start
unsigned IsSecArgPass : 1; ///< Second argument
- unsigned ByValOrByRefAlign : 4; ///< Log 2 of byval/byref alignment
+ unsigned ByValOrByRefAlign : 4; ///< Log 2 of byval/byref alignment
unsigned OrigAlign : 5; ///< Log 2 of original alignment
unsigned IsInConsecutiveRegsLast : 1;
unsigned IsInConsecutiveRegs : 1;
unsigned IsCopyElisionCandidate : 1; ///< Argument copy elision candidate
unsigned IsPointer : 1;
- unsigned ByValOrByRefSize; ///< Byval or byref struct size
+ unsigned ByValOrByRefSize; ///< Byval or byref struct size
unsigned PointerAddrSpace; ///< Address space of pointer argument
- /// Set the alignment used by byref or byval parameters.
- void setAlignImpl(Align A) {
- ByValOrByRefAlign = encode(A);
- assert(getNonZeroByValAlign() == A && "bitfield overflow");
- }
-
+ /// Set the alignment used by byref or byval parameters.
+ void setAlignImpl(Align A) {
+ ByValOrByRefAlign = encode(A);
+ assert(getNonZeroByValAlign() == A && "bitfield overflow");
+ }
+
public:
ArgFlagsTy()
- : IsZExt(0), IsSExt(0), IsInReg(0), IsSRet(0), IsByVal(0), IsByRef(0),
- IsNest(0), IsReturned(0), IsSplit(0), IsInAlloca(0), IsPreallocated(0),
+ : IsZExt(0), IsSExt(0), IsInReg(0), IsSRet(0), IsByVal(0), IsByRef(0),
+ IsNest(0), IsReturned(0), IsSplit(0), IsInAlloca(0), IsPreallocated(0),
IsSplitEnd(0), IsSwiftSelf(0), IsSwiftError(0), IsCFGuardTarget(0),
- IsHva(0), IsHvaStart(0), IsSecArgPass(0), ByValOrByRefAlign(0),
- OrigAlign(0), IsInConsecutiveRegsLast(0), IsInConsecutiveRegs(0),
- IsCopyElisionCandidate(0), IsPointer(0), ByValOrByRefSize(0),
+ IsHva(0), IsHvaStart(0), IsSecArgPass(0), ByValOrByRefAlign(0),
+ OrigAlign(0), IsInConsecutiveRegsLast(0), IsInConsecutiveRegs(0),
+ IsCopyElisionCandidate(0), IsPointer(0), ByValOrByRefSize(0),
PointerAddrSpace(0) {
static_assert(sizeof(*this) == 3 * sizeof(unsigned), "flags are too big");
}
@@ -95,9 +95,9 @@ namespace ISD {
bool isByVal() const { return IsByVal; }
void setByVal() { IsByVal = 1; }
- bool isByRef() const { return IsByRef; }
- void setByRef() { IsByRef = 1; }
-
+ bool isByRef() const { return IsByRef; }
+ void setByRef() { IsByRef = 1; }
+
bool isInAlloca() const { return IsInAlloca; }
void setInAlloca() { IsInAlloca = 1; }
@@ -129,12 +129,12 @@ namespace ISD {
void setReturned() { IsReturned = 1; }
bool isInConsecutiveRegs() const { return IsInConsecutiveRegs; }
- void setInConsecutiveRegs(bool Flag = true) { IsInConsecutiveRegs = Flag; }
+ void setInConsecutiveRegs(bool Flag = true) { IsInConsecutiveRegs = Flag; }
bool isInConsecutiveRegsLast() const { return IsInConsecutiveRegsLast; }
- void setInConsecutiveRegsLast(bool Flag = true) {
- IsInConsecutiveRegsLast = Flag;
- }
+ void setInConsecutiveRegsLast(bool Flag = true) {
+ IsInConsecutiveRegsLast = Flag;
+ }
bool isSplit() const { return IsSplit; }
void setSplit() { IsSplit = 1; }
@@ -150,24 +150,24 @@ namespace ISD {
LLVM_ATTRIBUTE_DEPRECATED(unsigned getByValAlign() const,
"Use getNonZeroByValAlign() instead") {
- MaybeAlign A = decodeMaybeAlign(ByValOrByRefAlign);
+ MaybeAlign A = decodeMaybeAlign(ByValOrByRefAlign);
return A ? A->value() : 0;
}
Align getNonZeroByValAlign() const {
- MaybeAlign A = decodeMaybeAlign(ByValOrByRefAlign);
+ MaybeAlign A = decodeMaybeAlign(ByValOrByRefAlign);
assert(A && "ByValAlign must be defined");
return *A;
}
void setByValAlign(Align A) {
- assert(isByVal() && !isByRef());
- setAlignImpl(A);
+ assert(isByVal() && !isByRef());
+ setAlignImpl(A);
+ }
+
+ void setByRefAlign(Align A) {
+ assert(!isByVal() && isByRef());
+ setAlignImpl(A);
}
- void setByRefAlign(Align A) {
- assert(!isByVal() && isByRef());
- setAlignImpl(A);
- }
-
LLVM_ATTRIBUTE_DEPRECATED(unsigned getOrigAlign() const,
"Use getNonZeroOrigAlign() instead") {
MaybeAlign A = decodeMaybeAlign(OrigAlign);
@@ -181,24 +181,24 @@ namespace ISD {
assert(getNonZeroOrigAlign() == A && "bitfield overflow");
}
- unsigned getByValSize() const {
- assert(isByVal() && !isByRef());
- return ByValOrByRefSize;
- }
- void setByValSize(unsigned S) {
- assert(isByVal() && !isByRef());
- ByValOrByRefSize = S;
- }
-
- unsigned getByRefSize() const {
- assert(!isByVal() && isByRef());
- return ByValOrByRefSize;
- }
- void setByRefSize(unsigned S) {
- assert(!isByVal() && isByRef());
- ByValOrByRefSize = S;
- }
-
+ unsigned getByValSize() const {
+ assert(isByVal() && !isByRef());
+ return ByValOrByRefSize;
+ }
+ void setByValSize(unsigned S) {
+ assert(isByVal() && !isByRef());
+ ByValOrByRefSize = S;
+ }
+
+ unsigned getByRefSize() const {
+ assert(!isByVal() && isByRef());
+ return ByValOrByRefSize;
+ }
+ void setByRefSize(unsigned S) {
+ assert(!isByVal() && isByRef());
+ ByValOrByRefSize = S;
+ }
+
unsigned getPointerAddrSpace() const { return PointerAddrSpace; }
void setPointerAddrSpace(unsigned AS) { PointerAddrSpace = AS; }
};
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/TargetFrameLowering.h b/contrib/libs/llvm12/include/llvm/CodeGen/TargetFrameLowering.h
index a53e3093d0..54d4c624d2 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/TargetFrameLowering.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/TargetFrameLowering.h
@@ -21,7 +21,7 @@
#define LLVM_CODEGEN_TARGETFRAMELOWERING_H
#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/Support/TypeSize.h"
+#include "llvm/Support/TypeSize.h"
#include <vector>
namespace llvm {
@@ -34,7 +34,7 @@ namespace TargetStackID {
enum Value {
Default = 0,
SGPRSpill = 1,
- ScalableVector = 2,
+ ScalableVector = 2,
NoAlloc = 255
};
}
@@ -305,8 +305,8 @@ public:
/// getFrameIndexReference - This method should return the base register
/// and offset used to reference a frame index location. The offset is
/// returned directly, and the base register is returned via FrameReg.
- virtual StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
- Register &FrameReg) const;
+ virtual StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
+ Register &FrameReg) const;
/// Same as \c getFrameIndexReference, except that the stack pointer (as
/// opposed to the frame pointer) will be the preferred value for \p
@@ -314,10 +314,10 @@ public:
/// use offsets from RSP. If \p IgnoreSPUpdates is true, the returned
/// offset is only guaranteed to be valid with respect to the value of SP at
/// the end of the prologue.
- virtual StackOffset
- getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI,
- Register &FrameReg,
- bool IgnoreSPUpdates) const {
+ virtual StackOffset
+ getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI,
+ Register &FrameReg,
+ bool IgnoreSPUpdates) const {
// Always safe to dispatch to getFrameIndexReference.
return getFrameIndexReference(MF, FI, FrameReg);
}
@@ -325,8 +325,8 @@ public:
/// getNonLocalFrameIndexReference - This method returns the offset used to
/// reference a frame index location. The offset can be from either FP/BP/SP
/// based on which base register is returned by llvm.localaddress.
- virtual StackOffset getNonLocalFrameIndexReference(const MachineFunction &MF,
- int FI) const {
+ virtual StackOffset getNonLocalFrameIndexReference(const MachineFunction &MF,
+ int FI) const {
// By default, dispatch to getFrameIndexReference. Interested targets can
// override this.
Register FrameReg;
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/TargetInstrInfo.h b/contrib/libs/llvm12/include/llvm/CodeGen/TargetInstrInfo.h
index a85ad4f600..7db4e4a6e8 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/TargetInstrInfo.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/TargetInstrInfo.h
@@ -32,7 +32,7 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineOutliner.h"
-#include "llvm/CodeGen/RegisterClassInfo.h"
+#include "llvm/CodeGen/RegisterClassInfo.h"
#include "llvm/CodeGen/VirtRegMap.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/Support/BranchProbability.h"
@@ -88,15 +88,15 @@ struct RegImmPair {
RegImmPair(Register Reg, int64_t Imm) : Reg(Reg), Imm(Imm) {}
};
-/// Used to describe addressing mode similar to ExtAddrMode in CodeGenPrepare.
-/// It holds the register values, the scale value and the displacement.
-struct ExtAddrMode {
- Register BaseReg;
- Register ScaledReg;
- int64_t Scale;
- int64_t Displacement;
-};
-
+/// Used to describe addressing mode similar to ExtAddrMode in CodeGenPrepare.
+/// It holds the register values, the scale value and the displacement.
+struct ExtAddrMode {
+ Register BaseReg;
+ Register ScaledReg;
+ int64_t Scale;
+ int64_t Displacement;
+};
+
//---------------------------------------------------------------------------
///
/// TargetInstrInfo - Interface to description of machine instruction set
@@ -356,12 +356,12 @@ public:
unsigned &Size, unsigned &Offset,
const MachineFunction &MF) const;
- /// Return true if the given instruction is terminator that is unspillable,
- /// according to isUnspillableTerminatorImpl.
- bool isUnspillableTerminator(const MachineInstr *MI) const {
- return MI->isTerminator() && isUnspillableTerminatorImpl(MI);
- }
-
+ /// Return true if the given instruction is terminator that is unspillable,
+ /// according to isUnspillableTerminatorImpl.
+ bool isUnspillableTerminator(const MachineInstr *MI) const {
+ return MI->isTerminator() && isUnspillableTerminatorImpl(MI);
+ }
+
/// Returns the size in bytes of the specified MachineInstr, or ~0U
/// when this function is not implemented by a target.
virtual unsigned getInstSizeInBytes(const MachineInstr &MI) const {
@@ -747,7 +747,7 @@ public:
return nullptr;
}
- /// Analyze the loop code, return true if it cannot be understood. Upon
+ /// Analyze the loop code, return true if it cannot be understood. Upon
/// success, this function returns false and returns information about the
/// induction variable and compare instruction used at the end.
virtual bool analyzeLoop(MachineLoop &L, MachineInstr *&IndVarInst,
@@ -794,7 +794,7 @@ public:
/// Second variant of isProfitableToIfCvt. This one
/// checks for the case where two basic blocks from true and false path
- /// of a if-then-else (diamond) are predicated on mutually exclusive
+ /// of a if-then-else (diamond) are predicated on mutually exclusive
/// predicates, where the probability of the true path being taken is given
/// by Probability, and Confidence is a measure of our confidence that it
/// will be properly predicted.
@@ -968,17 +968,17 @@ protected:
return None;
}
- /// Return true if the given terminator MI is not expected to spill. This
- /// sets the live interval as not spillable and adjusts phi node lowering to
- /// not introduce copies after the terminator. Use with care, these are
- /// currently used for hardware loop intrinsics in very controlled situations,
- /// created prior to registry allocation in loops that only have single phi
- /// users for the terminators value. They may run out of registers if not used
- /// carefully.
- virtual bool isUnspillableTerminatorImpl(const MachineInstr *MI) const {
- return false;
- }
-
+ /// Return true if the given terminator MI is not expected to spill. This
+ /// sets the live interval as not spillable and adjusts phi node lowering to
+ /// not introduce copies after the terminator. Use with care, these are
+ /// currently used for hardware loop intrinsics in very controlled situations,
+ /// created prior to registry allocation in loops that only have single phi
+ /// users for the terminators value. They may run out of registers if not used
+ /// carefully.
+ virtual bool isUnspillableTerminatorImpl(const MachineInstr *MI) const {
+ return false;
+ }
+
public:
/// If the specific machine instruction is a instruction that moves/copies
/// value from one register to another register return destination and source
@@ -1002,15 +1002,15 @@ public:
return None;
}
- /// Returns true if MI is an instruction that defines Reg to have a constant
- /// value and the value is recorded in ImmVal. The ImmVal is a result that
- /// should be interpreted as modulo size of Reg.
- virtual bool getConstValDefinedInReg(const MachineInstr &MI,
- const Register Reg,
- int64_t &ImmVal) const {
- return false;
- }
-
+ /// Returns true if MI is an instruction that defines Reg to have a constant
+ /// value and the value is recorded in ImmVal. The ImmVal is a result that
+ /// should be interpreted as modulo size of Reg.
+ virtual bool getConstValDefinedInReg(const MachineInstr &MI,
+ const Register Reg,
+ int64_t &ImmVal) 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
@@ -1084,24 +1084,24 @@ public:
/// faster sequence.
/// \param Root - Instruction that could be combined with one of its operands
/// \param Patterns - Vector of possible combination patterns
- virtual bool
- getMachineCombinerPatterns(MachineInstr &Root,
- SmallVectorImpl<MachineCombinerPattern> &Patterns,
- bool DoRegPressureReduce) const;
-
- /// Return true if target supports reassociation of instructions in machine
- /// combiner pass to reduce register pressure for a given BB.
- virtual bool
- shouldReduceRegisterPressure(MachineBasicBlock *MBB,
- RegisterClassInfo *RegClassInfo) const {
- return false;
- }
-
- /// Fix up the placeholder we may add in genAlternativeCodeSequence().
- virtual void
- finalizeInsInstrs(MachineInstr &Root, MachineCombinerPattern &P,
- SmallVectorImpl<MachineInstr *> &InsInstrs) const {}
-
+ virtual bool
+ getMachineCombinerPatterns(MachineInstr &Root,
+ SmallVectorImpl<MachineCombinerPattern> &Patterns,
+ bool DoRegPressureReduce) const;
+
+ /// Return true if target supports reassociation of instructions in machine
+ /// combiner pass to reduce register pressure for a given BB.
+ virtual bool
+ shouldReduceRegisterPressure(MachineBasicBlock *MBB,
+ RegisterClassInfo *RegClassInfo) const {
+ return false;
+ }
+
+ /// Fix up the placeholder we may add in genAlternativeCodeSequence().
+ virtual void
+ finalizeInsInstrs(MachineInstr &Root, MachineCombinerPattern &P,
+ SmallVectorImpl<MachineInstr *> &InsInstrs) const {}
+
/// Return true when a code sequence can improve throughput. It
/// should be called only for instructions in loops.
/// \param Pattern - combiner pattern
@@ -1305,11 +1305,11 @@ public:
bool &OffsetIsScalable,
const TargetRegisterInfo *TRI) const;
- /// Get zero or more base operands and the byte offset of an instruction that
- /// reads/writes memory. Note that there may be zero base operands if the
- /// instruction accesses a constant address.
+ /// Get zero or more base operands and the byte offset of an instruction that
+ /// reads/writes memory. Note that there may be zero base operands if the
+ /// instruction accesses a constant address.
/// It returns false if MI does not read/write memory.
- /// It returns false if base operands and offset could not be determined.
+ /// It returns false if base operands and offset could not be determined.
/// It is not guaranteed to always recognize base operands and offsets in all
/// cases.
virtual bool getMemOperandsWithOffsetWidth(
@@ -1328,27 +1328,27 @@ public:
return false;
}
- /// Target dependent implementation to get the values constituting the address
- /// MachineInstr that is accessing memory. These values are returned as a
- /// struct ExtAddrMode which contains all relevant information to make up the
- /// address.
- virtual Optional<ExtAddrMode>
- getAddrModeFromMemoryOp(const MachineInstr &MemI,
- const TargetRegisterInfo *TRI) const {
- return None;
- }
-
- /// Returns true if MI's Def is NullValueReg, and the MI
- /// does not change the Zero value. i.e. cases such as rax = shr rax, X where
- /// NullValueReg = rax. Note that if the NullValueReg is non-zero, this
- /// function can return true even if becomes zero. Specifically cases such as
- /// NullValueReg = shl NullValueReg, 63.
- virtual bool preservesZeroValueInReg(const MachineInstr *MI,
- const Register NullValueReg,
- const TargetRegisterInfo *TRI) const {
- return false;
- }
-
+ /// Target dependent implementation to get the values constituting the address
+ /// MachineInstr that is accessing memory. These values are returned as a
+ /// struct ExtAddrMode which contains all relevant information to make up the
+ /// address.
+ virtual Optional<ExtAddrMode>
+ getAddrModeFromMemoryOp(const MachineInstr &MemI,
+ const TargetRegisterInfo *TRI) const {
+ return None;
+ }
+
+ /// Returns true if MI's Def is NullValueReg, and the MI
+ /// does not change the Zero value. i.e. cases such as rax = shr rax, X where
+ /// NullValueReg = rax. Note that if the NullValueReg is non-zero, this
+ /// function can return true even if becomes zero. Specifically cases such as
+ /// NullValueReg = shl NullValueReg, 63.
+ virtual bool preservesZeroValueInReg(const MachineInstr *MI,
+ const Register NullValueReg,
+ const TargetRegisterInfo *TRI) const {
+ return false;
+ }
+
/// If the instruction is an increment of a constant value, return the amount.
virtual bool getIncrementValue(const MachineInstr &MI, int &Value) const {
return false;
@@ -1383,11 +1383,11 @@ public:
virtual void insertNoop(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const;
- /// Insert noops into the instruction stream at the specified point.
- virtual void insertNoops(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI,
- unsigned Quantity) const;
-
+ /// Insert noops into the instruction stream at the specified point.
+ virtual void insertNoops(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ unsigned Quantity) const;
+
/// Return the noop instruction to use for a noop.
virtual void getNoop(MCInst &NopInst) const;
@@ -1439,13 +1439,13 @@ public:
/// If the specified instruction defines any predicate
/// or condition code register(s) used for predication, returns true as well
/// as the definition predicate(s) by reference.
- /// SkipDead should be set to false at any point that dead
- /// predicate instructions should be considered as being defined.
- /// A dead predicate instruction is one that is guaranteed to be removed
- /// after a call to PredicateInstruction.
- virtual bool ClobbersPredicate(MachineInstr &MI,
- std::vector<MachineOperand> &Pred,
- bool SkipDead) const {
+ /// SkipDead should be set to false at any point that dead
+ /// predicate instructions should be considered as being defined.
+ /// A dead predicate instruction is one that is guaranteed to be removed
+ /// after a call to PredicateInstruction.
+ virtual bool ClobbersPredicate(MachineInstr &MI,
+ std::vector<MachineOperand> &Pred,
+ bool SkipDead) const {
return false;
}
@@ -1531,7 +1531,7 @@ public:
/// the machine instruction generated due to folding.
virtual MachineInstr *optimizeLoadInstr(MachineInstr &MI,
const MachineRegisterInfo *MRI,
- Register &FoldAsLoadDefReg,
+ Register &FoldAsLoadDefReg,
MachineInstr *&DefMI) const {
return nullptr;
}
@@ -1716,7 +1716,7 @@ public:
/// This hook works similarly to getPartialRegUpdateClearance, except that it
/// does not take an operand index. Instead sets \p OpNum to the index of the
/// unused register.
- virtual unsigned getUndefRegClearance(const MachineInstr &MI, unsigned OpNum,
+ virtual unsigned getUndefRegClearance(const MachineInstr &MI, unsigned OpNum,
const TargetRegisterInfo *TRI) const {
// The default implementation returns 0 for no undef register dependency.
return 0;
@@ -1777,21 +1777,21 @@ public:
return 5;
}
- /// Return the maximal number of alias checks on memory operands. For
- /// instructions with more than one memory operands, the alias check on a
- /// single MachineInstr pair has quadratic overhead and results in
- /// unacceptable performance in the worst case. The limit here is to clamp
- /// that maximal checks performed. Usually, that's the product of memory
- /// operand numbers from that pair of MachineInstr to be checked. For
- /// instance, with two MachineInstrs with 4 and 5 memory operands
- /// correspondingly, a total of 20 checks are required. With this limit set to
- /// 16, their alias check is skipped. We choose to limit the product instead
- /// of the individual instruction as targets may have special MachineInstrs
- /// with a considerably high number of memory operands, such as `ldm` in ARM.
- /// Setting this limit per MachineInstr would result in either too high
- /// overhead or too rigid restriction.
- virtual unsigned getMemOperandAACheckLimit() const { return 16; }
-
+ /// Return the maximal number of alias checks on memory operands. For
+ /// instructions with more than one memory operands, the alias check on a
+ /// single MachineInstr pair has quadratic overhead and results in
+ /// unacceptable performance in the worst case. The limit here is to clamp
+ /// that maximal checks performed. Usually, that's the product of memory
+ /// operand numbers from that pair of MachineInstr to be checked. For
+ /// instance, with two MachineInstrs with 4 and 5 memory operands
+ /// correspondingly, a total of 20 checks are required. With this limit set to
+ /// 16, their alias check is skipped. We choose to limit the product instead
+ /// of the individual instruction as targets may have special MachineInstrs
+ /// with a considerably high number of memory operands, such as `ldm` in ARM.
+ /// Setting this limit per MachineInstr would result in either too high
+ /// overhead or too rigid restriction.
+ virtual unsigned getMemOperandAACheckLimit() const { return 16; }
+
/// Return an array that contains the ids of the target indices (used for the
/// TargetIndex machine operand) and their names.
///
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/TargetLowering.h b/contrib/libs/llvm12/include/llvm/CodeGen/TargetLowering.h
index d9c9c6f0cf..ae06e715a0 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/TargetLowering.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/TargetLowering.h
@@ -285,7 +285,7 @@ public:
bool IsSRet : 1;
bool IsNest : 1;
bool IsByVal : 1;
- bool IsByRef : 1;
+ bool IsByRef : 1;
bool IsInAlloca : 1;
bool IsPreallocated : 1;
bool IsReturned : 1;
@@ -298,7 +298,7 @@ public:
ArgListEntry()
: IsSExt(false), IsZExt(false), IsInReg(false), IsSRet(false),
- IsNest(false), IsByVal(false), IsByRef(false), IsInAlloca(false),
+ IsNest(false), IsByVal(false), IsByRef(false), IsInAlloca(false),
IsPreallocated(false), IsReturned(false), IsSwiftSelf(false),
IsSwiftError(false), IsCFGuardTarget(false) {}
@@ -382,13 +382,13 @@ public:
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL,
bool LegalTypes = true) const;
- /// Return the preferred type to use for a shift opcode, given the shifted
- /// amount type is \p ShiftValueTy.
- LLVM_READONLY
- virtual LLT getPreferredShiftAmountTy(LLT ShiftValueTy) const {
- return ShiftValueTy;
- }
-
+ /// Return the preferred type to use for a shift opcode, given the shifted
+ /// amount type is \p ShiftValueTy.
+ LLVM_READONLY
+ virtual LLT getPreferredShiftAmountTy(LLT ShiftValueTy) const {
+ return ShiftValueTy;
+ }
+
/// Returns the type to be used for the index operand of:
/// ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT,
/// ISD::INSERT_SUBVECTOR, and ISD::EXTRACT_SUBVECTOR
@@ -434,7 +434,7 @@ public:
virtual TargetLoweringBase::LegalizeTypeAction
getPreferredVectorAction(MVT VT) const {
// The default action for one element vectors is to scalarize
- if (VT.getVectorElementCount().isScalar())
+ if (VT.getVectorElementCount().isScalar())
return TypeScalarizeVector;
// The default action for an odd-width vector is to widen.
if (!VT.isPow2VectorType())
@@ -612,12 +612,12 @@ public:
return false;
}
- /// Return the maximum number of "x & (x - 1)" operations that can be done
- /// instead of deferring to a custom CTPOP.
- virtual unsigned getCustomCtpopCost(EVT VT, ISD::CondCode Cond) const {
- return 1;
- }
-
+ /// Return the maximum number of "x & (x - 1)" operations that can be done
+ /// instead of deferring to a custom CTPOP.
+ virtual unsigned getCustomCtpopCost(EVT VT, ISD::CondCode Cond) const {
+ return 1;
+ }
+
/// Return true if instruction generated for equality comparison is folded
/// with instruction generated for signed comparison.
virtual bool isEqualityCmpFoldedWithSignedCmp() const { return true; }
@@ -1106,13 +1106,13 @@ public:
/// 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. LegalOnly is an optional convenience for code paths
- /// traversed pre and post legalisation.
- bool isOperationLegalOrCustom(unsigned Op, EVT VT,
- bool LegalOnly = false) const {
- if (LegalOnly)
- return isOperationLegal(Op, VT);
-
+ /// lowering decisions. LegalOnly is an optional convenience for code paths
+ /// traversed pre and post legalisation.
+ bool isOperationLegalOrCustom(unsigned Op, EVT VT,
+ bool LegalOnly = false) const {
+ if (LegalOnly)
+ return isOperationLegal(Op, VT);
+
return (VT == MVT::Other || isTypeLegal(VT)) &&
(getOperationAction(Op, VT) == Legal ||
getOperationAction(Op, VT) == Custom);
@@ -1120,13 +1120,13 @@ public:
/// Return true if the specified operation is legal on this target or can be
/// made legal using promotion. This is used to help guide high-level lowering
- /// decisions. LegalOnly is an optional convenience for code paths traversed
- /// pre and post legalisation.
- bool isOperationLegalOrPromote(unsigned Op, EVT VT,
- bool LegalOnly = false) const {
- if (LegalOnly)
- return isOperationLegal(Op, VT);
-
+ /// decisions. LegalOnly is an optional convenience for code paths traversed
+ /// pre and post legalisation.
+ bool isOperationLegalOrPromote(unsigned Op, EVT VT,
+ bool LegalOnly = false) const {
+ if (LegalOnly)
+ return isOperationLegal(Op, VT);
+
return (VT == MVT::Other || isTypeLegal(VT)) &&
(getOperationAction(Op, VT) == Legal ||
getOperationAction(Op, VT) == Promote);
@@ -1134,13 +1134,13 @@ public:
/// Return true if the specified operation is legal on this target or can be
/// made legal with custom lowering or using promotion. This is used to help
- /// guide high-level lowering decisions. LegalOnly is an optional convenience
- /// for code paths traversed pre and post legalisation.
- bool isOperationLegalOrCustomOrPromote(unsigned Op, EVT VT,
- bool LegalOnly = false) const {
- if (LegalOnly)
- return isOperationLegal(Op, VT);
-
+ /// guide high-level lowering decisions. LegalOnly is an optional convenience
+ /// for code paths traversed pre and post legalisation.
+ bool isOperationLegalOrCustomOrPromote(unsigned Op, EVT VT,
+ bool LegalOnly = false) const {
+ if (LegalOnly)
+ return isOperationLegal(Op, VT);
+
return (VT == MVT::Other || isTypeLegal(VT)) &&
(getOperationAction(Op, VT) == Legal ||
getOperationAction(Op, VT) == Custom ||
@@ -1325,10 +1325,10 @@ public:
getIndexedMaskedStoreAction(IdxMode, VT.getSimpleVT()) == Custom);
}
- // Returns true if VT is a legal index type for masked gathers/scatters
- // on this target
- virtual bool shouldRemoveExtendFromGSIndex(EVT VT) const { return false; }
-
+ // Returns true if VT is a legal index type for masked gathers/scatters
+ // on this target
+ virtual bool shouldRemoveExtendFromGSIndex(EVT VT) const { return false; }
+
/// Return how the condition code should be treated: either it is legal, needs
/// to be expanded to some other code sequence, or the target has a custom
/// expander for it.
@@ -1665,11 +1665,11 @@ public:
const MachineMemOperand &MMO,
bool *Fast = nullptr) const;
- /// LLT handling variant.
- bool allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, LLT Ty,
- const MachineMemOperand &MMO,
- bool *Fast = nullptr) const;
-
+ /// LLT handling variant.
+ bool allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, LLT Ty,
+ const MachineMemOperand &MMO,
+ bool *Fast = nullptr) const;
+
/// Returns the target specific optimal type for load and store operations as
/// a result of memset, memcpy, and memmove lowering.
/// It returns EVT::Other if the type should be determined using generic
@@ -1710,7 +1710,7 @@ public:
/// If a physical register, this specifies the register that
/// llvm.savestack/llvm.restorestack should save and restore.
- Register getStackPointerRegisterToSaveRestore() const {
+ Register getStackPointerRegisterToSaveRestore() const {
return StackPointerRegisterToSaveRestore;
}
@@ -1802,7 +1802,7 @@ public:
/// Returns true if a cast from SrcAS to DestAS is "cheap", such that e.g. we
/// are happy to sink it into basic blocks. A cast may be free, but not
/// necessarily a no-op. e.g. a free truncate from a 64-bit to 32-bit pointer.
- virtual bool isFreeAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const;
+ virtual bool isFreeAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const;
/// Return true if the pointer arguments to CI should be aligned by aligning
/// the object whose address is being passed. If so then MinSize is set to the
@@ -2792,10 +2792,10 @@ public:
return false;
}
- /// Does this target require the clearing of high-order bits in a register
- /// passed to the fp16 to fp conversion library function.
- virtual bool shouldKeepZExtForFP16Conv() const { return false; }
-
+ /// Does this target require the clearing of high-order bits in a register
+ /// passed to the fp16 to fp conversion library function.
+ virtual bool shouldKeepZExtForFP16Conv() const { return false; }
+
//===--------------------------------------------------------------------===//
// Runtime Library hooks
//
@@ -4216,7 +4216,7 @@ public:
// Lower custom output constraints. If invalid, return SDValue().
virtual SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue &Flag,
- const SDLoc &DL,
+ const SDLoc &DL,
const AsmOperandInfo &OpInfo,
SelectionDAG &DAG) const;
@@ -4283,20 +4283,20 @@ public:
return SDValue();
}
- /// Return a target-dependent comparison result if the input operand is
- /// suitable for use with a square root estimate calculation. For example, the
- /// comparison may check if the operand is NAN, INF, zero, normal, etc. The
- /// result should be used as the condition operand for a select or branch.
- virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG,
- const DenormalMode &Mode) const;
-
- /// Return a target-dependent result if the input operand is not suitable for
- /// use with a square root estimate calculation.
- virtual SDValue getSqrtResultForDenormInput(SDValue Operand,
- SelectionDAG &DAG) const {
- return DAG.getConstantFP(0.0, SDLoc(Operand), Operand.getValueType());
- }
-
+ /// Return a target-dependent comparison result if the input operand is
+ /// suitable for use with a square root estimate calculation. For example, the
+ /// comparison may check if the operand is NAN, INF, zero, normal, etc. The
+ /// result should be used as the condition operand for a select or branch.
+ virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG,
+ const DenormalMode &Mode) const;
+
+ /// Return a target-dependent result if the input operand is not suitable for
+ /// use with a square root estimate calculation.
+ virtual SDValue getSqrtResultForDenormInput(SDValue Operand,
+ SelectionDAG &DAG) const {
+ return DAG.getConstantFP(0.0, SDLoc(Operand), Operand.getValueType());
+ }
+
//===--------------------------------------------------------------------===//
// Legalization utility functions
//
@@ -4311,7 +4311,7 @@ public:
/// \param RL Low bits of the RHS of the MUL. See LL for meaning
/// \param RH High bits of the RHS of the MUL. See LL for meaning.
/// \returns true if the node has been expanded, false if it has not
- bool expandMUL_LOHI(unsigned Opcode, EVT VT, const SDLoc &dl, SDValue LHS,
+ bool expandMUL_LOHI(unsigned Opcode, EVT VT, const SDLoc &dl, SDValue LHS,
SDValue RHS, SmallVectorImpl<SDValue> &Result, EVT HiLoVT,
SelectionDAG &DAG, MulExpansionKind Kind,
SDValue LL = SDValue(), SDValue LH = SDValue(),
@@ -4339,12 +4339,12 @@ public:
/// Expand rotations.
/// \param N Node to expand
- /// \param AllowVectorOps expand vector rotate, this should only be performed
- /// if the legalization is happening outside of LegalizeVectorOps
+ /// \param AllowVectorOps expand vector rotate, this should only be performed
+ /// if the legalization is happening outside of LegalizeVectorOps
/// \param Result output after conversion
/// \returns True, if the expansion was successful, false otherwise
- bool expandROT(SDNode *N, bool AllowVectorOps, SDValue &Result,
- SelectionDAG &DAG) const;
+ bool expandROT(SDNode *N, bool AllowVectorOps, SDValue &Result,
+ SelectionDAG &DAG) const;
/// Expand float(f32) to SINT(i64) conversion
/// \param N Node to expand
@@ -4371,11 +4371,11 @@ public:
/// Expand fminnum/fmaxnum into fminnum_ieee/fmaxnum_ieee with quieted inputs.
SDValue expandFMINNUM_FMAXNUM(SDNode *N, SelectionDAG &DAG) const;
- /// Expand FP_TO_[US]INT_SAT into FP_TO_[US]INT and selects or min/max.
- /// \param N Node to expand
- /// \returns The expansion result
- SDValue expandFP_TO_INT_SAT(SDNode *N, SelectionDAG &DAG) const;
-
+ /// Expand FP_TO_[US]INT_SAT into FP_TO_[US]INT and selects or min/max.
+ /// \param N Node to expand
+ /// \returns The expansion result
+ SDValue expandFP_TO_INT_SAT(SDNode *N, SelectionDAG &DAG) const;
+
/// Expand CTPOP nodes. Expands vector/scalar CTPOP nodes,
/// vector nodes can only succeed if all operations are legal/custom.
/// \param N Node to expand
@@ -4402,10 +4402,10 @@ public:
/// (ABS x) -> (XOR (ADD x, (SRA x, type_size)), (SRA x, type_size))
/// \param N Node to expand
/// \param Result output after conversion
- /// \param IsNegative indicate negated abs
+ /// \param IsNegative indicate negated abs
/// \returns True, if the expansion was successful, false otherwise
- bool expandABS(SDNode *N, SDValue &Result, SelectionDAG &DAG,
- bool IsNegative = false) const;
+ bool expandABS(SDNode *N, SDValue &Result, SelectionDAG &DAG,
+ bool IsNegative = false) const;
/// Turn load of vector type into a load of the individual elements.
/// \param LD load to expand
@@ -4445,18 +4445,18 @@ public:
SDValue getVectorElementPointer(SelectionDAG &DAG, SDValue VecPtr, EVT VecVT,
SDValue Index) const;
- /// Method for building the DAG expansion of ISD::[US][MIN|MAX]. This
- /// method accepts integers as its arguments.
- SDValue expandIntMINMAX(SDNode *Node, SelectionDAG &DAG) const;
-
+ /// Method for building the DAG expansion of ISD::[US][MIN|MAX]. This
+ /// method accepts integers as its arguments.
+ SDValue expandIntMINMAX(SDNode *Node, SelectionDAG &DAG) const;
+
/// Method for building the DAG expansion of ISD::[US][ADD|SUB]SAT. This
/// method accepts integers as its arguments.
SDValue expandAddSubSat(SDNode *Node, SelectionDAG &DAG) const;
- /// Method for building the DAG expansion of ISD::[US]SHLSAT. This
- /// method accepts integers as its arguments.
- SDValue expandShlSat(SDNode *Node, SelectionDAG &DAG) const;
-
+ /// Method for building the DAG expansion of ISD::[US]SHLSAT. This
+ /// method accepts integers as its arguments.
+ SDValue expandShlSat(SDNode *Node, SelectionDAG &DAG) const;
+
/// Method for building the DAG expansion of ISD::[U|S]MULFIX[SAT]. This
/// method accepts integers as its arguments.
SDValue expandFixedPointMul(SDNode *Node, SelectionDAG &DAG) const;
@@ -4488,9 +4488,9 @@ public:
/// only the first Count elements of the vector are used.
SDValue expandVecReduce(SDNode *Node, SelectionDAG &DAG) const;
- /// Expand a VECREDUCE_SEQ_* into an explicit ordered calculation.
- SDValue expandVecReduceSeq(SDNode *Node, SelectionDAG &DAG) const;
-
+ /// Expand a VECREDUCE_SEQ_* into an explicit ordered calculation.
+ SDValue expandVecReduceSeq(SDNode *Node, SelectionDAG &DAG) const;
+
/// Expand an SREM or UREM using SDIV/UDIV or SDIVREM/UDIVREM, if legal.
/// Returns true if the expansion was successful.
bool expandREM(SDNode *Node, SDValue &Result, SelectionDAG &DAG) const;
@@ -4545,10 +4545,10 @@ public:
// combiner can fold the new nodes.
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const;
- /// Give targets the chance to reduce the number of distinct addresing modes.
- ISD::MemIndexType getCanonicalIndexType(ISD::MemIndexType IndexType,
- EVT MemVT, SDValue Offsets) const;
-
+ /// Give targets the chance to reduce the number of distinct addresing modes.
+ ISD::MemIndexType getCanonicalIndexType(ISD::MemIndexType IndexType,
+ EVT MemVT, SDValue Offsets) const;
+
private:
SDValue foldSetCCWithAnd(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond,
const SDLoc &DL, DAGCombinerInfo &DCI) const;
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/contrib/libs/llvm12/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index c8ca33fd39..a53f94ddba 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -28,7 +28,7 @@ namespace llvm {
class GlobalValue;
class MachineModuleInfo;
-class MachineFunction;
+class MachineFunction;
class MCContext;
class MCExpr;
class MCSection;
@@ -45,7 +45,7 @@ protected:
MCSymbolRefExpr::VK_None;
public:
- TargetLoweringObjectFileELF();
+ TargetLoweringObjectFileELF();
~TargetLoweringObjectFileELF() override = default;
void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
@@ -70,8 +70,8 @@ public:
MCSection *getSectionForJumpTable(const Function &F,
const TargetMachine &TM) const override;
- MCSection *getSectionForLSDA(const Function &F,
- const TargetMachine &TM) const override;
+ MCSection *getSectionForLSDA(const Function &F,
+ const TargetMachine &TM) const override;
MCSection *
getSectionForMachineBasicBlock(const Function &F,
@@ -104,9 +104,9 @@ public:
const GlobalValue *RHS,
const TargetMachine &TM) const override;
- const MCExpr *lowerDSOLocalEquivalent(const DSOLocalEquivalent *Equiv,
- const TargetMachine &TM) const override;
-
+ const MCExpr *lowerDSOLocalEquivalent(const DSOLocalEquivalent *Equiv,
+ const TargetMachine &TM) const override;
+
MCSection *getSectionForCommandLines() const override;
};
@@ -155,7 +155,7 @@ public:
class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
mutable unsigned NextUniqueID = 0;
- const TargetMachine *TM = nullptr;
+ const TargetMachine *TM = nullptr;
public:
~TargetLoweringObjectFileCOFF() override = default;
@@ -190,9 +190,9 @@ public:
MCSection *getSectionForConstant(const DataLayout &DL, SectionKind Kind,
const Constant *C,
Align &Alignment) const override;
-
-private:
- void emitLinkerDirectives(MCStreamer &Streamer, Module &M) const;
+
+private:
+ void emitLinkerDirectives(MCStreamer &Streamer, Module &M) const;
};
class TargetLoweringObjectFileWasm : public TargetLoweringObjectFile {
@@ -227,10 +227,10 @@ public:
TargetLoweringObjectFileXCOFF() = default;
~TargetLoweringObjectFileXCOFF() override = default;
- static bool ShouldEmitEHBlock(const MachineFunction *MF);
-
- static MCSymbol *getEHInfoTableSymbol(const MachineFunction *MF);
-
+ static bool ShouldEmitEHBlock(const MachineFunction *MF);
+
+ static MCSymbol *getEHInfoTableSymbol(const MachineFunction *MF);
+
void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,
@@ -260,13 +260,13 @@ public:
const Constant *C,
Align &Alignment) const override;
- static XCOFF::StorageClass getStorageClassForGlobal(const GlobalValue *GV);
+ static XCOFF::StorageClass getStorageClassForGlobal(const GlobalValue *GV);
MCSection *
getSectionForFunctionDescriptor(const Function *F,
const TargetMachine &TM) const override;
- MCSection *getSectionForTOCEntry(const MCSymbol *Sym,
- const TargetMachine &TM) const override;
+ MCSection *getSectionForTOCEntry(const MCSymbol *Sym,
+ const TargetMachine &TM) const override;
/// For external functions, this will always return a function descriptor
/// csect.
@@ -278,7 +278,7 @@ public:
MCSymbol *getTargetSymbol(const GlobalValue *GV,
const TargetMachine &TM) const override;
- MCSymbol *getFunctionEntryPointSymbol(const GlobalValue *Func,
+ MCSymbol *getFunctionEntryPointSymbol(const GlobalValue *Func,
const TargetMachine &TM) const override;
};
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/TargetPassConfig.h b/contrib/libs/llvm12/include/llvm/CodeGen/TargetPassConfig.h
index d15c47c1d0..5137f56968 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/TargetPassConfig.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/TargetPassConfig.h
@@ -32,7 +32,7 @@ struct MachineSchedContext;
class PassConfigImpl;
class ScheduleDAGInstrs;
class CSEConfigBase;
-class PassInstrumentationCallbacks;
+class PassInstrumentationCallbacks;
// The old pass manager infrastructure is hidden in a legacy namespace now.
namespace legacy {
@@ -195,7 +195,7 @@ public:
/// Insert InsertedPassID pass after TargetPassID pass.
void insertPass(AnalysisID TargetPassID, IdentifyingPassPtr InsertedPassID,
- bool VerifyAfter = true);
+ bool VerifyAfter = true);
/// Allow the target to enable a specific standard pass by default.
void enablePass(AnalysisID PassID) { substitutePass(PassID, PassID); }
@@ -321,17 +321,17 @@ public:
/// Add a pass to remove debug info from the MIR.
void addStripDebugPass();
- /// Add a pass to check synthesized debug info for MIR.
- void addCheckDebugPass();
-
+ /// Add a pass to check synthesized debug info for MIR.
+ void addCheckDebugPass();
+
/// Add standard passes before a pass that's about to be added. For example,
/// the DebugifyMachineModulePass if it is enabled.
void addMachinePrePasses(bool AllowDebugify = true);
/// Add standard passes after a pass that has just been added. For example,
/// the MachineVerifier if it is enabled.
- void addMachinePostPasses(const std::string &Banner, bool AllowVerify = true,
- bool AllowStrip = true);
+ void addMachinePostPasses(const std::string &Banner, bool AllowVerify = true,
+ bool AllowStrip = true);
/// Check whether or not GlobalISel should abort on error.
/// When this is disabled, GlobalISel will fall back on SDISel instead of
@@ -454,28 +454,28 @@ protected:
/// Return the pass that was added, or zero if no pass was added.
/// @p verifyAfter if true and adding a machine function pass add an extra
/// machine verification pass afterwards.
- AnalysisID addPass(AnalysisID PassID, bool verifyAfter = true);
+ AnalysisID addPass(AnalysisID PassID, bool verifyAfter = true);
/// Add a pass to the PassManager if that pass is supposed to be run, as
/// determined by the StartAfter and StopAfter options. Takes ownership of the
/// pass.
/// @p verifyAfter if true and adding a machine function pass add an extra
/// machine verification pass afterwards.
- void addPass(Pass *P, bool verifyAfter = true);
+ void addPass(Pass *P, bool verifyAfter = true);
/// addMachinePasses helper to create the target-selected or overriden
/// regalloc pass.
virtual FunctionPass *createRegAllocPass(bool Optimized);
- /// Add core register allocator passes which do the actual register assignment
+ /// Add core register allocator passes which do the actual register assignment
/// and rewriting. \returns true if any passes were added.
- virtual bool addRegAssignAndRewriteFast();
- virtual bool addRegAssignAndRewriteOptimized();
+ virtual bool addRegAssignAndRewriteFast();
+ virtual bool addRegAssignAndRewriteOptimized();
};
-void registerCodeGenCallback(PassInstrumentationCallbacks &PIC,
- LLVMTargetMachine &);
-
+void registerCodeGenCallback(PassInstrumentationCallbacks &PIC,
+ LLVMTargetMachine &);
+
} // end namespace llvm
#endif // LLVM_CODEGEN_TARGETPASSCONFIG_H
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/TargetRegisterInfo.h b/contrib/libs/llvm12/include/llvm/CodeGen/TargetRegisterInfo.h
index 9b7248afd3..66f6653835 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -41,7 +41,7 @@
namespace llvm {
class BitVector;
-class DIExpression;
+class DIExpression;
class LiveRegMatrix;
class MachineFunction;
class MachineInstr;
@@ -95,21 +95,21 @@ public:
/// Return true if the specified register is included in this register class.
/// This does not include virtual registers.
- bool contains(Register Reg) const {
+ bool contains(Register Reg) const {
/// FIXME: Historically this function has returned false when given vregs
/// but it should probably only receive physical registers
- if (!Reg.isPhysical())
+ if (!Reg.isPhysical())
return false;
- return MC->contains(Reg.asMCReg());
+ return MC->contains(Reg.asMCReg());
}
/// Return true if both registers are in this class.
- bool contains(Register Reg1, Register Reg2) const {
+ bool contains(Register Reg1, Register Reg2) const {
/// FIXME: Historically this function has returned false when given a vregs
/// but it should probably only receive physical registers
- if (!Reg1.isPhysical() || !Reg2.isPhysical())
+ if (!Reg1.isPhysical() || !Reg2.isPhysical())
return false;
- return MC->contains(Reg1.asMCReg(), Reg2.asMCReg());
+ return MC->contains(Reg1.asMCReg(), Reg2.asMCReg());
}
/// Return the cost of copying a value between two registers in this class.
@@ -393,12 +393,12 @@ public:
/// The registers may be virtual registers.
bool regsOverlap(Register regA, Register regB) const {
if (regA == regB) return true;
- if (!regA.isPhysical() || !regB.isPhysical())
+ if (!regA.isPhysical() || !regB.isPhysical())
return false;
// Regunits are numerically ordered. Find a common unit.
- MCRegUnitIterator RUA(regA.asMCReg(), this);
- MCRegUnitIterator RUB(regB.asMCReg(), this);
+ MCRegUnitIterator RUA(regA.asMCReg(), this);
+ MCRegUnitIterator RUB(regB.asMCReg(), this);
do {
if (*RUA == *RUB) return true;
if (*RUA < *RUB) ++RUA;
@@ -408,9 +408,9 @@ public:
}
/// Returns true if Reg contains RegUnit.
- bool hasRegUnit(MCRegister Reg, Register RegUnit) const {
+ bool hasRegUnit(MCRegister Reg, Register RegUnit) const {
for (MCRegUnitIterator Units(Reg, this); Units.isValid(); ++Units)
- if (Register(*Units) == RegUnit)
+ if (Register(*Units) == RegUnit)
return true;
return false;
}
@@ -422,16 +422,16 @@ public:
virtual Register lookThruCopyLike(Register SrcReg,
const MachineRegisterInfo *MRI) const;
- /// Find the original SrcReg unless it is the target of a copy-like operation,
- /// in which case we chain backwards through all such operations to the
- /// ultimate source register. If a physical register is encountered, we stop
- /// the search.
- /// Return the original SrcReg if all the definitions in the chain only have
- /// one user and not a physical register.
- virtual Register
- lookThruSingleUseCopyChain(Register SrcReg,
- const MachineRegisterInfo *MRI) const;
-
+ /// Find the original SrcReg unless it is the target of a copy-like operation,
+ /// in which case we chain backwards through all such operations to the
+ /// ultimate source register. If a physical register is encountered, we stop
+ /// the search.
+ /// Return the original SrcReg if all the definitions in the chain only have
+ /// one user and not a physical register.
+ virtual Register
+ lookThruSingleUseCopyChain(Register SrcReg,
+ const MachineRegisterInfo *MRI) const;
+
/// Return a null-terminated list of all of the callee-saved registers on
/// this target. The register should be in the order of desired callee-save
/// stack frame offset. The first register is closest to the incoming stack
@@ -466,13 +466,13 @@ public:
return nullptr;
}
- /// Return a register mask for the registers preserved by the unwinder,
- /// or nullptr if no custom mask is needed.
- virtual const uint32_t *
- getCustomEHPadPreservedMask(const MachineFunction &MF) const {
- return nullptr;
- }
-
+ /// Return a register mask for the registers preserved by the unwinder,
+ /// or nullptr if no custom mask is needed.
+ virtual const uint32_t *
+ getCustomEHPadPreservedMask(const MachineFunction &MF) const {
+ return nullptr;
+ }
+
/// Return a register mask that clobbers everything.
virtual const uint32_t *getNoPreservedMask() const {
llvm_unreachable("target does not provide no preserved mask");
@@ -918,11 +918,11 @@ public:
return false;
}
- /// Insert defining instruction(s) for a pointer to FrameIdx before
- /// insertion point I. Return materialized frame pointer.
- virtual Register materializeFrameBaseRegister(MachineBasicBlock *MBB,
- int FrameIdx,
- int64_t Offset) const {
+ /// Insert defining instruction(s) for a pointer to FrameIdx before
+ /// insertion point I. Return materialized frame pointer.
+ virtual Register materializeFrameBaseRegister(MachineBasicBlock *MBB,
+ int FrameIdx,
+ int64_t Offset) const {
llvm_unreachable("materializeFrameBaseRegister does not exist on this "
"target");
}
@@ -941,15 +941,15 @@ public:
llvm_unreachable("isFrameOffsetLegal does not exist on this target");
}
- /// Gets the DWARF expression opcodes for \p Offset.
- virtual void getOffsetOpcodes(const StackOffset &Offset,
- SmallVectorImpl<uint64_t> &Ops) const;
-
- /// Prepends a DWARF expression for \p Offset to DIExpression \p Expr.
- DIExpression *
- prependOffsetExpression(const DIExpression *Expr, unsigned PrependFlags,
- const StackOffset &Offset) const;
-
+ /// Gets the DWARF expression opcodes for \p Offset.
+ virtual void getOffsetOpcodes(const StackOffset &Offset,
+ SmallVectorImpl<uint64_t> &Ops) const;
+
+ /// Prepends a DWARF expression for \p Offset to DIExpression \p Expr.
+ DIExpression *
+ prependOffsetExpression(const DIExpression *Expr, unsigned PrependFlags,
+ const StackOffset &Offset) const;
+
/// Spill the register so it can be used by the register scavenger.
/// Return true if the register was spilled, false otherwise.
/// If this function does not spill the register, the scavenger
@@ -1003,36 +1003,36 @@ public:
virtual bool shouldRegionSplitForVirtReg(const MachineFunction &MF,
const LiveInterval &VirtReg) const;
- /// Last chance recoloring has a high compile time cost especially for
- /// targets with a lot of registers.
- /// This method is used to decide whether or not \p VirtReg should
- /// go through this expensive heuristic.
- /// When this target hook is hit, by returning false, there is a high
- /// chance that the register allocation will fail altogether (usually with
- /// "ran out of registers").
- /// That said, this error usually points to another problem in the
- /// optimization pipeline.
- virtual bool
- shouldUseLastChanceRecoloringForVirtReg(const MachineFunction &MF,
- const LiveInterval &VirtReg) const {
- return true;
- }
-
- /// Deferred spilling delays the spill insertion of a virtual register
- /// after every other allocation. By deferring the spilling, it is
- /// sometimes possible to eliminate that spilling altogether because
- /// something else could have been eliminated, thus leaving some space
- /// for the virtual register.
- /// However, this comes with a compile time impact because it adds one
- /// more stage to the greedy register allocator.
- /// This method is used to decide whether \p VirtReg should use the deferred
- /// spilling stage instead of being spilled right away.
- virtual bool
- shouldUseDeferredSpillingForVirtReg(const MachineFunction &MF,
- const LiveInterval &VirtReg) const {
- return false;
- }
-
+ /// Last chance recoloring has a high compile time cost especially for
+ /// targets with a lot of registers.
+ /// This method is used to decide whether or not \p VirtReg should
+ /// go through this expensive heuristic.
+ /// When this target hook is hit, by returning false, there is a high
+ /// chance that the register allocation will fail altogether (usually with
+ /// "ran out of registers").
+ /// That said, this error usually points to another problem in the
+ /// optimization pipeline.
+ virtual bool
+ shouldUseLastChanceRecoloringForVirtReg(const MachineFunction &MF,
+ const LiveInterval &VirtReg) const {
+ return true;
+ }
+
+ /// Deferred spilling delays the spill insertion of a virtual register
+ /// after every other allocation. By deferring the spilling, it is
+ /// sometimes possible to eliminate that spilling altogether because
+ /// something else could have been eliminated, thus leaving some space
+ /// for the virtual register.
+ /// However, this comes with a compile time impact because it adds one
+ /// more stage to the greedy register allocator.
+ /// This method is used to decide whether \p VirtReg should use the deferred
+ /// spilling stage instead of being spilled right away.
+ virtual bool
+ shouldUseDeferredSpillingForVirtReg(const MachineFunction &MF,
+ const LiveInterval &VirtReg) const {
+ return false;
+ }
+
//===--------------------------------------------------------------------===//
/// Debug information queries.
@@ -1057,7 +1057,7 @@ public:
/// Returns the physical register number of sub-register "Index"
/// for physical register RegNo. Return zero if the sub-register does not
/// exist.
- inline MCRegister getSubReg(MCRegister Reg, unsigned Idx) const {
+ inline MCRegister getSubReg(MCRegister Reg, unsigned Idx) const {
return static_cast<const MCRegisterInfo *>(this)->getSubReg(Reg, Idx);
}
};
@@ -1209,8 +1209,8 @@ public:
// This is useful when building IndexedMaps keyed on virtual registers
struct VirtReg2IndexFunctor {
- using argument_type = Register;
- unsigned operator()(Register Reg) const {
+ using argument_type = Register;
+ unsigned operator()(Register Reg) const {
return Register::virtReg2Index(Reg);
}
};
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/TargetSubtargetInfo.h b/contrib/libs/llvm12/include/llvm/CodeGen/TargetSubtargetInfo.h
index 9d7c5055c4..25d84d7cf4 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/TargetSubtargetInfo.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/TargetSubtargetInfo.h
@@ -65,8 +65,8 @@ class Triple;
///
class TargetSubtargetInfo : public MCSubtargetInfo {
protected: // Can only create subclasses...
- TargetSubtargetInfo(const Triple &TT, StringRef CPU, StringRef TuneCPU,
- StringRef FS, ArrayRef<SubtargetFeatureKV> PF,
+ TargetSubtargetInfo(const Triple &TT, StringRef CPU, StringRef TuneCPU,
+ StringRef FS, ArrayRef<SubtargetFeatureKV> PF,
ArrayRef<SubtargetSubTypeKV> PD,
const MCWriteProcResEntry *WPR,
const MCWriteLatencyEntry *WL,
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/TileShapeInfo.h b/contrib/libs/llvm12/include/llvm/CodeGen/TileShapeInfo.h
index 083a3bd4e9..c1d21411f8 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/TileShapeInfo.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/TileShapeInfo.h
@@ -1,108 +1,108 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- llvm/CodeGen/TileShapeInfo.h - ---------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file Shape utility for AMX.
-/// AMX hardware requires to config the shape of tile data register before use.
-/// The 2D shape includes row and column. In AMX intrinsics interface the shape
-/// is passed as 1st and 2nd parameter and they are lowered as the 1st and 2nd
-/// machine operand of AMX pseudo instructions. ShapeT class is to facilitate
-/// tile config and register allocator. The row and column are machine operand
-/// of AMX pseudo instructions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_TILESHAPEINFO_H
-#define LLVM_CODEGEN_TILESHAPEINFO_H
-
-#include "llvm/ADT/DenseMapInfo.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineOperand.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/Register.h"
-#include <utility>
-
-namespace llvm {
-
-class ShapeT {
-public:
- ShapeT(MachineOperand *Row, MachineOperand *Col,
- const MachineRegisterInfo *MRI = nullptr)
- : Row(Row), Col(Col) {
- if (MRI)
- deduceImm(MRI);
- }
- ShapeT()
- : Row(nullptr), Col(nullptr), RowImm(InvalidImmShape),
- ColImm(InvalidImmShape) {}
- bool operator==(const ShapeT &Shape) {
- MachineOperand *R = Shape.Row;
- MachineOperand *C = Shape.Col;
- if (!R || !C)
- return false;
- if (!Row || !Col)
- return false;
- if (Row->getReg() == R->getReg() && Col->getReg() == C->getReg())
- return true;
- if ((RowImm != InvalidImmShape) && (ColImm != InvalidImmShape))
- return RowImm == Shape.getRowImm() && ColImm == Shape.getColImm();
- return false;
- }
-
- bool operator!=(const ShapeT &Shape) { return !(*this == Shape); }
-
- MachineOperand *getRow() const { return Row; }
-
- MachineOperand *getCol() const { return Col; }
-
- int64_t getRowImm() const { return RowImm; }
-
- int64_t getColImm() const { return ColImm; }
-
- bool isValid() { return (Row != nullptr) && (Col != nullptr); }
-
- void deduceImm(const MachineRegisterInfo *MRI) {
- // All def must be the same value, otherwise it is invalid MIs.
- // Find the immediate.
- // TODO copy propagation.
- auto GetImm = [&](Register Reg) {
- int64_t Imm = InvalidImmShape;
- for (const MachineOperand &DefMO : MRI->def_operands(Reg)) {
- const auto *MI = DefMO.getParent();
- if (MI->isMoveImmediate()) {
- Imm = MI->getOperand(1).getImm();
- break;
- }
- }
- return Imm;
- };
- RowImm = GetImm(Row->getReg());
- ColImm = GetImm(Col->getReg());
- }
-
-private:
- static constexpr int64_t InvalidImmShape = -1;
- MachineOperand *Row;
- MachineOperand *Col;
- int64_t RowImm;
- int64_t ColImm;
-};
-
-} // namespace llvm
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- llvm/CodeGen/TileShapeInfo.h - ---------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file Shape utility for AMX.
+/// AMX hardware requires to config the shape of tile data register before use.
+/// The 2D shape includes row and column. In AMX intrinsics interface the shape
+/// is passed as 1st and 2nd parameter and they are lowered as the 1st and 2nd
+/// machine operand of AMX pseudo instructions. ShapeT class is to facilitate
+/// tile config and register allocator. The row and column are machine operand
+/// of AMX pseudo instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_TILESHAPEINFO_H
+#define LLVM_CODEGEN_TILESHAPEINFO_H
+
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/Register.h"
+#include <utility>
+
+namespace llvm {
+
+class ShapeT {
+public:
+ ShapeT(MachineOperand *Row, MachineOperand *Col,
+ const MachineRegisterInfo *MRI = nullptr)
+ : Row(Row), Col(Col) {
+ if (MRI)
+ deduceImm(MRI);
+ }
+ ShapeT()
+ : Row(nullptr), Col(nullptr), RowImm(InvalidImmShape),
+ ColImm(InvalidImmShape) {}
+ bool operator==(const ShapeT &Shape) {
+ MachineOperand *R = Shape.Row;
+ MachineOperand *C = Shape.Col;
+ if (!R || !C)
+ return false;
+ if (!Row || !Col)
+ return false;
+ if (Row->getReg() == R->getReg() && Col->getReg() == C->getReg())
+ return true;
+ if ((RowImm != InvalidImmShape) && (ColImm != InvalidImmShape))
+ return RowImm == Shape.getRowImm() && ColImm == Shape.getColImm();
+ return false;
+ }
+
+ bool operator!=(const ShapeT &Shape) { return !(*this == Shape); }
+
+ MachineOperand *getRow() const { return Row; }
+
+ MachineOperand *getCol() const { return Col; }
+
+ int64_t getRowImm() const { return RowImm; }
+
+ int64_t getColImm() const { return ColImm; }
+
+ bool isValid() { return (Row != nullptr) && (Col != nullptr); }
+
+ void deduceImm(const MachineRegisterInfo *MRI) {
+ // All def must be the same value, otherwise it is invalid MIs.
+ // Find the immediate.
+ // TODO copy propagation.
+ auto GetImm = [&](Register Reg) {
+ int64_t Imm = InvalidImmShape;
+ for (const MachineOperand &DefMO : MRI->def_operands(Reg)) {
+ const auto *MI = DefMO.getParent();
+ if (MI->isMoveImmediate()) {
+ Imm = MI->getOperand(1).getImm();
+ break;
+ }
+ }
+ return Imm;
+ };
+ RowImm = GetImm(Row->getReg());
+ ColImm = GetImm(Col->getReg());
+ }
+
+private:
+ static constexpr int64_t InvalidImmShape = -1;
+ MachineOperand *Row;
+ MachineOperand *Col;
+ int64_t RowImm;
+ int64_t ColImm;
+};
+
+} // namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/ValueTypes.h b/contrib/libs/llvm12/include/llvm/CodeGen/ValueTypes.h
index 08d16a7a1d..a442a4cc2d 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/ValueTypes.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/ValueTypes.h
@@ -99,17 +99,17 @@ namespace llvm {
/// with the element type converted to an integer type with the same
/// bitwidth.
EVT changeVectorElementTypeToInteger() const {
- if (isSimple())
- return getSimpleVT().changeVectorElementTypeToInteger();
- return changeExtendedVectorElementTypeToInteger();
+ if (isSimple())
+ return getSimpleVT().changeVectorElementTypeToInteger();
+ return changeExtendedVectorElementTypeToInteger();
}
/// Return a VT for a vector type whose attributes match ourselves
/// with the exception of the element type that is chosen by the caller.
EVT changeVectorElementType(EVT EltVT) const {
- if (isSimple() && EltVT.isSimple())
- return getSimpleVT().changeVectorElementType(EltVT.getSimpleVT());
- return changeExtendedVectorElementType(EltVT);
+ if (isSimple() && EltVT.isSimple())
+ return getSimpleVT().changeVectorElementType(EltVT.getSimpleVT());
+ return changeExtendedVectorElementType(EltVT);
}
/// Return the type converted to an equivalently sized integer or vector
@@ -120,7 +120,7 @@ namespace llvm {
return changeVectorElementTypeToInteger();
if (isSimple())
- return getSimpleVT().changeTypeToInteger();
+ return getSimpleVT().changeTypeToInteger();
return changeExtendedTypeToInteger();
}
@@ -211,7 +211,7 @@ namespace llvm {
}
/// Return true if the bit size is a multiple of 8.
- bool isByteSized() const { return getSizeInBits().isKnownMultipleOf(8); }
+ bool isByteSized() const { return getSizeInBits().isKnownMultipleOf(8); }
/// Return true if the size is a power-of-two number of bytes.
bool isRound() const {
@@ -227,58 +227,58 @@ namespace llvm {
return getSizeInBits() == VT.getSizeInBits();
}
- /// Return true if we know at compile time this has more bits than VT.
- bool knownBitsGT(EVT VT) const {
- return TypeSize::isKnownGT(getSizeInBits(), VT.getSizeInBits());
- }
-
- /// Return true if we know at compile time this has more than or the same
- /// bits as VT.
- bool knownBitsGE(EVT VT) const {
- return TypeSize::isKnownGE(getSizeInBits(), VT.getSizeInBits());
- }
-
- /// Return true if we know at compile time this has fewer bits than VT.
- bool knownBitsLT(EVT VT) const {
- return TypeSize::isKnownLT(getSizeInBits(), VT.getSizeInBits());
- }
-
- /// Return true if we know at compile time this has fewer than or the same
- /// bits as VT.
- bool knownBitsLE(EVT VT) const {
- return TypeSize::isKnownLE(getSizeInBits(), VT.getSizeInBits());
- }
-
+ /// Return true if we know at compile time this has more bits than VT.
+ bool knownBitsGT(EVT VT) const {
+ return TypeSize::isKnownGT(getSizeInBits(), VT.getSizeInBits());
+ }
+
+ /// Return true if we know at compile time this has more than or the same
+ /// bits as VT.
+ bool knownBitsGE(EVT VT) const {
+ return TypeSize::isKnownGE(getSizeInBits(), VT.getSizeInBits());
+ }
+
+ /// Return true if we know at compile time this has fewer bits than VT.
+ bool knownBitsLT(EVT VT) const {
+ return TypeSize::isKnownLT(getSizeInBits(), VT.getSizeInBits());
+ }
+
+ /// Return true if we know at compile time this has fewer than or the same
+ /// bits as VT.
+ bool knownBitsLE(EVT VT) const {
+ return TypeSize::isKnownLE(getSizeInBits(), VT.getSizeInBits());
+ }
+
/// Return true if this has more bits than VT.
bool bitsGT(EVT VT) const {
if (EVT::operator==(VT)) return false;
- assert(isScalableVector() == VT.isScalableVector() &&
- "Comparison between scalable and fixed types");
- return knownBitsGT(VT);
+ assert(isScalableVector() == VT.isScalableVector() &&
+ "Comparison between scalable and fixed types");
+ return knownBitsGT(VT);
}
/// Return true if this has no less bits than VT.
bool bitsGE(EVT VT) const {
if (EVT::operator==(VT)) return true;
- assert(isScalableVector() == VT.isScalableVector() &&
- "Comparison between scalable and fixed types");
- return knownBitsGE(VT);
+ assert(isScalableVector() == VT.isScalableVector() &&
+ "Comparison between scalable and fixed types");
+ return knownBitsGE(VT);
}
/// Return true if this has less bits than VT.
bool bitsLT(EVT VT) const {
if (EVT::operator==(VT)) return false;
- assert(isScalableVector() == VT.isScalableVector() &&
- "Comparison between scalable and fixed types");
- return knownBitsLT(VT);
+ assert(isScalableVector() == VT.isScalableVector() &&
+ "Comparison between scalable and fixed types");
+ return knownBitsLT(VT);
}
/// Return true if this has no more bits than VT.
bool bitsLE(EVT VT) const {
if (EVT::operator==(VT)) return true;
- assert(isScalableVector() == VT.isScalableVector() &&
- "Comparison between scalable and fixed types");
- return knownBitsLE(VT);
+ assert(isScalableVector() == VT.isScalableVector() &&
+ "Comparison between scalable and fixed types");
+ return knownBitsLE(VT);
}
/// Return the SimpleValueType held in the specified simple EVT.
@@ -310,7 +310,7 @@ namespace llvm {
if (isScalableVector())
WithColor::warning()
<< "Possible incorrect use of EVT::getVectorNumElements() for "
- "scalable vector. Scalable flag may be dropped, use "
+ "scalable vector. Scalable flag may be dropped, use "
"EVT::getVectorElementCount() instead\n";
#endif
if (isSimple())
@@ -329,7 +329,7 @@ namespace llvm {
/// Given a vector type, return the minimum number of elements it contains.
unsigned getVectorMinNumElements() const {
- return getVectorElementCount().getKnownMinValue();
+ return getVectorElementCount().getKnownMinValue();
}
/// Return the size of the specified value type in bits.
@@ -343,16 +343,16 @@ namespace llvm {
return getExtendedSizeInBits();
}
- /// Return the size of the specified fixed width value type in bits. The
- /// function will assert if the type is scalable.
- uint64_t getFixedSizeInBits() const {
- return getSizeInBits().getFixedSize();
+ /// Return the size of the specified fixed width value type in bits. The
+ /// function will assert if the type is scalable.
+ uint64_t getFixedSizeInBits() const {
+ return getSizeInBits().getFixedSize();
+ }
+
+ uint64_t getScalarSizeInBits() const {
+ return getScalarType().getSizeInBits().getFixedSize();
}
- uint64_t getScalarSizeInBits() const {
- return getScalarType().getSizeInBits().getFixedSize();
- }
-
/// Return the number of bytes overwritten by a store of the specified value
/// type.
///
@@ -414,19 +414,19 @@ namespace llvm {
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const {
EVT EltVT = getVectorElementType();
auto EltCnt = getVectorElementCount();
- assert(EltCnt.isKnownEven() && "Splitting vector, but not in half!");
- return EVT::getVectorVT(Context, EltVT, EltCnt.divideCoefficientBy(2));
- }
-
- // Return a VT for a vector type with the same element type but
- // double the number of elements. The type returned may be an
- // extended type.
- EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const {
- EVT EltVT = getVectorElementType();
- auto EltCnt = getVectorElementCount();
- return EVT::getVectorVT(Context, EltVT, EltCnt * 2);
- }
-
+ assert(EltCnt.isKnownEven() && "Splitting vector, but not in half!");
+ return EVT::getVectorVT(Context, EltVT, EltCnt.divideCoefficientBy(2));
+ }
+
+ // Return a VT for a vector type with the same element type but
+ // double the number of elements. The type returned may be an
+ // extended type.
+ EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const {
+ EVT EltVT = getVectorElementType();
+ auto EltCnt = getVectorElementCount();
+ return EVT::getVectorVT(Context, EltVT, EltCnt * 2);
+ }
+
/// Returns true if the given vector is a power of 2.
bool isPow2VectorType() const {
unsigned NElts = getVectorMinNumElements();
@@ -438,8 +438,8 @@ namespace llvm {
EVT getPow2VectorType(LLVMContext &Context) const {
if (!isPow2VectorType()) {
ElementCount NElts = getVectorElementCount();
- unsigned NewMinCount = 1 << Log2_32_Ceil(NElts.getKnownMinValue());
- NElts = ElementCount::get(NewMinCount, NElts.isScalable());
+ unsigned NewMinCount = 1 << Log2_32_Ceil(NElts.getKnownMinValue());
+ NElts = ElementCount::get(NewMinCount, NElts.isScalable());
return EVT::getVectorVT(Context, getVectorElementType(), NElts);
}
else {
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/ValueTypes.td b/contrib/libs/llvm12/include/llvm/CodeGen/ValueTypes.td
index c138d52700..d13d0a7772 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/ValueTypes.td
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/ValueTypes.td
@@ -87,117 +87,117 @@ def v4i64 : ValueType<256, 60>; // 4 x i64 vector value
def v8i64 : ValueType<512, 61>; // 8 x i64 vector value
def v16i64 : ValueType<1024,62>; // 16 x i64 vector value
def v32i64 : ValueType<2048,63>; // 32 x i64 vector value
-def v64i64 : ValueType<4096,64>; // 64 x i64 vector value
-def v128i64: ValueType<8192,65>; // 128 x i64 vector value
-def v256i64: ValueType<16384,66>; // 256 x i64 vector value
-
-def v1i128 : ValueType<128, 67>; // 1 x i128 vector value
-
-def v2f16 : ValueType<32 , 68>; // 2 x f16 vector value
-def v3f16 : ValueType<48 , 69>; // 3 x f16 vector value
-def v4f16 : ValueType<64 , 70>; // 4 x f16 vector value
-def v8f16 : ValueType<128, 71>; // 8 x f16 vector value
-def v16f16 : ValueType<256, 72>; // 16 x f16 vector value
-def v32f16 : ValueType<512, 73>; // 32 x f16 vector value
-def v64f16 : ValueType<1024, 74>; // 64 x f16 vector value
-def v128f16 : ValueType<2048, 75>; // 128 x f16 vector value
-def v2bf16 : ValueType<32 , 76>; // 2 x bf16 vector value
-def v3bf16 : ValueType<48 , 77>; // 3 x bf16 vector value
-def v4bf16 : ValueType<64 , 78>; // 4 x bf16 vector value
-def v8bf16 : ValueType<128, 79>; // 8 x bf16 vector value
-def v16bf16 : ValueType<256, 80>; // 16 x bf16 vector value
-def v32bf16 : ValueType<512, 81>; // 32 x bf16 vector value
-def v64bf16 : ValueType<1024, 82>; // 64 x bf16 vector value
-def v128bf16 : ValueType<2048, 83>; // 128 x bf16 vector value
-def v1f32 : ValueType<32 , 84>; // 1 x f32 vector value
-def v2f32 : ValueType<64 , 85>; // 2 x f32 vector value
-def v3f32 : ValueType<96 , 86>; // 3 x f32 vector value
-def v4f32 : ValueType<128, 87>; // 4 x f32 vector value
-def v5f32 : ValueType<160, 88>; // 5 x f32 vector value
-def v8f32 : ValueType<256, 89>; // 8 x f32 vector value
-def v16f32 : ValueType<512, 90>; // 16 x f32 vector value
-def v32f32 : ValueType<1024, 91>; // 32 x f32 vector value
-def v64f32 : ValueType<2048, 92>; // 64 x f32 vector value
-def v128f32 : ValueType<4096, 93>; // 128 x f32 vector value
-def v256f32 : ValueType<8182, 94>; // 256 x f32 vector value
-def v512f32 : ValueType<16384, 95>; // 512 x f32 vector value
-def v1024f32 : ValueType<32768, 96>; // 1024 x f32 vector value
-def v2048f32 : ValueType<65536, 97>; // 2048 x f32 vector value
-def v1f64 : ValueType<64, 98>; // 1 x f64 vector value
-def v2f64 : ValueType<128, 99>; // 2 x f64 vector value
-def v4f64 : ValueType<256, 100>; // 4 x f64 vector value
-def v8f64 : ValueType<512, 101>; // 8 x f64 vector value
-def v16f64 : ValueType<1024, 102>; // 16 x f64 vector value
-def v32f64 : ValueType<2048, 103>; // 32 x f64 vector value
-def v64f64 : ValueType<4096, 104>; // 64 x f64 vector value
-def v128f64 : ValueType<8192, 105>; // 128 x f64 vector value
-def v256f64 : ValueType<16384, 106>; // 256 x f64 vector value
-
-def nxv1i1 : ValueType<1, 107>; // n x 1 x i1 vector value
-def nxv2i1 : ValueType<2, 108>; // n x 2 x i1 vector value
-def nxv4i1 : ValueType<4, 109>; // n x 4 x i1 vector value
-def nxv8i1 : ValueType<8, 110>; // n x 8 x i1 vector value
-def nxv16i1 : ValueType<16, 111>; // n x 16 x i1 vector value
-def nxv32i1 : ValueType<32, 112>; // n x 32 x i1 vector value
-def nxv64i1 : ValueType<64,113>; // n x 64 x i1 vector value
-
-def nxv1i8 : ValueType<8, 114>; // n x 1 x i8 vector value
-def nxv2i8 : ValueType<16, 115>; // n x 2 x i8 vector value
-def nxv4i8 : ValueType<32, 116>; // n x 4 x i8 vector value
-def nxv8i8 : ValueType<64, 117>; // n x 8 x i8 vector value
-def nxv16i8 : ValueType<128, 118>; // n x 16 x i8 vector value
-def nxv32i8 : ValueType<256, 119>; // n x 32 x i8 vector value
-def nxv64i8 : ValueType<512, 120>; // n x 64 x i8 vector value
-
-def nxv1i16 : ValueType<16, 121>; // n x 1 x i16 vector value
-def nxv2i16 : ValueType<32, 122>; // n x 2 x i16 vector value
-def nxv4i16 : ValueType<64, 123>; // n x 4 x i16 vector value
-def nxv8i16 : ValueType<128, 124>; // n x 8 x i16 vector value
-def nxv16i16: ValueType<256, 125>; // n x 16 x i16 vector value
-def nxv32i16: ValueType<512, 126>; // n x 32 x i16 vector value
-
-def nxv1i32 : ValueType<32, 127>; // n x 1 x i32 vector value
-def nxv2i32 : ValueType<64, 128>; // n x 2 x i32 vector value
-def nxv4i32 : ValueType<128, 129>; // n x 4 x i32 vector value
-def nxv8i32 : ValueType<256, 130>; // n x 8 x i32 vector value
-def nxv16i32: ValueType<512, 131>; // n x 16 x i32 vector value
-def nxv32i32: ValueType<1024,132>; // n x 32 x i32 vector value
-
-def nxv1i64 : ValueType<64, 133>; // n x 1 x i64 vector value
-def nxv2i64 : ValueType<128, 134>; // n x 2 x i64 vector value
-def nxv4i64 : ValueType<256, 135>; // n x 4 x i64 vector value
-def nxv8i64 : ValueType<512, 136>; // n x 8 x i64 vector value
-def nxv16i64: ValueType<1024,137>; // n x 16 x i64 vector value
-def nxv32i64: ValueType<2048,138>; // n x 32 x i64 vector value
-
-def nxv1f16 : ValueType<32, 139>; // n x 1 x f16 vector value
-def nxv2f16 : ValueType<32 , 140>; // n x 2 x f16 vector value
-def nxv4f16 : ValueType<64 , 141>; // n x 4 x f16 vector value
-def nxv8f16 : ValueType<128, 142>; // n x 8 x f16 vector value
-def nxv16f16 : ValueType<256,143>; // n x 16 x f16 vector value
-def nxv32f16 : ValueType<512,144>; // n x 32 x f16 vector value
-def nxv2bf16 : ValueType<32 , 145>; // n x 2 x bf16 vector value
-def nxv4bf16 : ValueType<64 , 146>; // n x 4 x bf16 vector value
-def nxv8bf16 : ValueType<128, 147>; // n x 8 x bf16 vector value
-def nxv1f32 : ValueType<32 , 148>; // n x 1 x f32 vector value
-def nxv2f32 : ValueType<64 , 149>; // n x 2 x f32 vector value
-def nxv4f32 : ValueType<128, 150>; // n x 4 x f32 vector value
-def nxv8f32 : ValueType<256, 151>; // n x 8 x f32 vector value
-def nxv16f32 : ValueType<512, 152>; // n x 16 x f32 vector value
-def nxv1f64 : ValueType<64, 153>; // n x 1 x f64 vector value
-def nxv2f64 : ValueType<128, 154>; // n x 2 x f64 vector value
-def nxv4f64 : ValueType<256, 155>; // n x 4 x f64 vector value
-def nxv8f64 : ValueType<512, 156>; // n x 8 x f64 vector value
-
-def x86mmx : ValueType<64 , 157>; // X86 MMX value
-def FlagVT : ValueType<0 , 158>; // Pre-RA sched glue
-def isVoid : ValueType<0 , 159>; // Produces no value
-def untyped: ValueType<8 , 160>; // Produces an untyped value
-def funcref : ValueType<0 , 161>; // WebAssembly's funcref type
-def externref : ValueType<0 , 162>; // WebAssembly's externref type
-def x86amx : ValueType<8192, 163>; // X86 AMX value
-
-
+def v64i64 : ValueType<4096,64>; // 64 x i64 vector value
+def v128i64: ValueType<8192,65>; // 128 x i64 vector value
+def v256i64: ValueType<16384,66>; // 256 x i64 vector value
+
+def v1i128 : ValueType<128, 67>; // 1 x i128 vector value
+
+def v2f16 : ValueType<32 , 68>; // 2 x f16 vector value
+def v3f16 : ValueType<48 , 69>; // 3 x f16 vector value
+def v4f16 : ValueType<64 , 70>; // 4 x f16 vector value
+def v8f16 : ValueType<128, 71>; // 8 x f16 vector value
+def v16f16 : ValueType<256, 72>; // 16 x f16 vector value
+def v32f16 : ValueType<512, 73>; // 32 x f16 vector value
+def v64f16 : ValueType<1024, 74>; // 64 x f16 vector value
+def v128f16 : ValueType<2048, 75>; // 128 x f16 vector value
+def v2bf16 : ValueType<32 , 76>; // 2 x bf16 vector value
+def v3bf16 : ValueType<48 , 77>; // 3 x bf16 vector value
+def v4bf16 : ValueType<64 , 78>; // 4 x bf16 vector value
+def v8bf16 : ValueType<128, 79>; // 8 x bf16 vector value
+def v16bf16 : ValueType<256, 80>; // 16 x bf16 vector value
+def v32bf16 : ValueType<512, 81>; // 32 x bf16 vector value
+def v64bf16 : ValueType<1024, 82>; // 64 x bf16 vector value
+def v128bf16 : ValueType<2048, 83>; // 128 x bf16 vector value
+def v1f32 : ValueType<32 , 84>; // 1 x f32 vector value
+def v2f32 : ValueType<64 , 85>; // 2 x f32 vector value
+def v3f32 : ValueType<96 , 86>; // 3 x f32 vector value
+def v4f32 : ValueType<128, 87>; // 4 x f32 vector value
+def v5f32 : ValueType<160, 88>; // 5 x f32 vector value
+def v8f32 : ValueType<256, 89>; // 8 x f32 vector value
+def v16f32 : ValueType<512, 90>; // 16 x f32 vector value
+def v32f32 : ValueType<1024, 91>; // 32 x f32 vector value
+def v64f32 : ValueType<2048, 92>; // 64 x f32 vector value
+def v128f32 : ValueType<4096, 93>; // 128 x f32 vector value
+def v256f32 : ValueType<8182, 94>; // 256 x f32 vector value
+def v512f32 : ValueType<16384, 95>; // 512 x f32 vector value
+def v1024f32 : ValueType<32768, 96>; // 1024 x f32 vector value
+def v2048f32 : ValueType<65536, 97>; // 2048 x f32 vector value
+def v1f64 : ValueType<64, 98>; // 1 x f64 vector value
+def v2f64 : ValueType<128, 99>; // 2 x f64 vector value
+def v4f64 : ValueType<256, 100>; // 4 x f64 vector value
+def v8f64 : ValueType<512, 101>; // 8 x f64 vector value
+def v16f64 : ValueType<1024, 102>; // 16 x f64 vector value
+def v32f64 : ValueType<2048, 103>; // 32 x f64 vector value
+def v64f64 : ValueType<4096, 104>; // 64 x f64 vector value
+def v128f64 : ValueType<8192, 105>; // 128 x f64 vector value
+def v256f64 : ValueType<16384, 106>; // 256 x f64 vector value
+
+def nxv1i1 : ValueType<1, 107>; // n x 1 x i1 vector value
+def nxv2i1 : ValueType<2, 108>; // n x 2 x i1 vector value
+def nxv4i1 : ValueType<4, 109>; // n x 4 x i1 vector value
+def nxv8i1 : ValueType<8, 110>; // n x 8 x i1 vector value
+def nxv16i1 : ValueType<16, 111>; // n x 16 x i1 vector value
+def nxv32i1 : ValueType<32, 112>; // n x 32 x i1 vector value
+def nxv64i1 : ValueType<64,113>; // n x 64 x i1 vector value
+
+def nxv1i8 : ValueType<8, 114>; // n x 1 x i8 vector value
+def nxv2i8 : ValueType<16, 115>; // n x 2 x i8 vector value
+def nxv4i8 : ValueType<32, 116>; // n x 4 x i8 vector value
+def nxv8i8 : ValueType<64, 117>; // n x 8 x i8 vector value
+def nxv16i8 : ValueType<128, 118>; // n x 16 x i8 vector value
+def nxv32i8 : ValueType<256, 119>; // n x 32 x i8 vector value
+def nxv64i8 : ValueType<512, 120>; // n x 64 x i8 vector value
+
+def nxv1i16 : ValueType<16, 121>; // n x 1 x i16 vector value
+def nxv2i16 : ValueType<32, 122>; // n x 2 x i16 vector value
+def nxv4i16 : ValueType<64, 123>; // n x 4 x i16 vector value
+def nxv8i16 : ValueType<128, 124>; // n x 8 x i16 vector value
+def nxv16i16: ValueType<256, 125>; // n x 16 x i16 vector value
+def nxv32i16: ValueType<512, 126>; // n x 32 x i16 vector value
+
+def nxv1i32 : ValueType<32, 127>; // n x 1 x i32 vector value
+def nxv2i32 : ValueType<64, 128>; // n x 2 x i32 vector value
+def nxv4i32 : ValueType<128, 129>; // n x 4 x i32 vector value
+def nxv8i32 : ValueType<256, 130>; // n x 8 x i32 vector value
+def nxv16i32: ValueType<512, 131>; // n x 16 x i32 vector value
+def nxv32i32: ValueType<1024,132>; // n x 32 x i32 vector value
+
+def nxv1i64 : ValueType<64, 133>; // n x 1 x i64 vector value
+def nxv2i64 : ValueType<128, 134>; // n x 2 x i64 vector value
+def nxv4i64 : ValueType<256, 135>; // n x 4 x i64 vector value
+def nxv8i64 : ValueType<512, 136>; // n x 8 x i64 vector value
+def nxv16i64: ValueType<1024,137>; // n x 16 x i64 vector value
+def nxv32i64: ValueType<2048,138>; // n x 32 x i64 vector value
+
+def nxv1f16 : ValueType<32, 139>; // n x 1 x f16 vector value
+def nxv2f16 : ValueType<32 , 140>; // n x 2 x f16 vector value
+def nxv4f16 : ValueType<64 , 141>; // n x 4 x f16 vector value
+def nxv8f16 : ValueType<128, 142>; // n x 8 x f16 vector value
+def nxv16f16 : ValueType<256,143>; // n x 16 x f16 vector value
+def nxv32f16 : ValueType<512,144>; // n x 32 x f16 vector value
+def nxv2bf16 : ValueType<32 , 145>; // n x 2 x bf16 vector value
+def nxv4bf16 : ValueType<64 , 146>; // n x 4 x bf16 vector value
+def nxv8bf16 : ValueType<128, 147>; // n x 8 x bf16 vector value
+def nxv1f32 : ValueType<32 , 148>; // n x 1 x f32 vector value
+def nxv2f32 : ValueType<64 , 149>; // n x 2 x f32 vector value
+def nxv4f32 : ValueType<128, 150>; // n x 4 x f32 vector value
+def nxv8f32 : ValueType<256, 151>; // n x 8 x f32 vector value
+def nxv16f32 : ValueType<512, 152>; // n x 16 x f32 vector value
+def nxv1f64 : ValueType<64, 153>; // n x 1 x f64 vector value
+def nxv2f64 : ValueType<128, 154>; // n x 2 x f64 vector value
+def nxv4f64 : ValueType<256, 155>; // n x 4 x f64 vector value
+def nxv8f64 : ValueType<512, 156>; // n x 8 x f64 vector value
+
+def x86mmx : ValueType<64 , 157>; // X86 MMX value
+def FlagVT : ValueType<0 , 158>; // Pre-RA sched glue
+def isVoid : ValueType<0 , 159>; // Produces no value
+def untyped: ValueType<8 , 160>; // Produces an untyped value
+def funcref : ValueType<0 , 161>; // WebAssembly's funcref type
+def externref : ValueType<0 , 162>; // WebAssembly's externref type
+def x86amx : ValueType<8192, 163>; // X86 AMX value
+
+
def token : ValueType<0 , 248>; // TokenTy
def MetadataVT: ValueType<0, 249>; // Metadata
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/VirtRegMap.h b/contrib/libs/llvm12/include/llvm/CodeGen/VirtRegMap.h
index bd0ff64222..b4e39214c9 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/VirtRegMap.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/VirtRegMap.h
@@ -26,7 +26,7 @@
#include "llvm/ADT/IndexedMap.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
-#include "llvm/CodeGen/TileShapeInfo.h"
+#include "llvm/CodeGen/TileShapeInfo.h"
#include "llvm/Pass.h"
#include <cassert>
@@ -68,10 +68,10 @@ class TargetInstrInfo;
/// mapping.
IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2SplitMap;
- /// Virt2ShapeMap - For X86 AMX register whose register is bound shape
- /// information.
- DenseMap<unsigned, ShapeT> Virt2ShapeMap;
-
+ /// Virt2ShapeMap - For X86 AMX register whose register is bound shape
+ /// information.
+ DenseMap<unsigned, ShapeT> Virt2ShapeMap;
+
/// createSpillSlot - Allocate a spill slot for RC from MFI.
unsigned createSpillSlot(const TargetRegisterClass *RC);
@@ -110,30 +110,30 @@ class TargetInstrInfo;
/// returns the physical register mapped to the specified
/// virtual register
- MCRegister getPhys(Register virtReg) const {
+ MCRegister getPhys(Register virtReg) const {
assert(virtReg.isVirtual());
- return MCRegister::from(Virt2PhysMap[virtReg.id()]);
+ return MCRegister::from(Virt2PhysMap[virtReg.id()]);
}
/// creates a mapping for the specified virtual register to
/// the specified physical register
void assignVirt2Phys(Register virtReg, MCPhysReg physReg);
- bool isShapeMapEmpty() const { return Virt2ShapeMap.empty(); }
-
- bool hasShape(Register virtReg) const {
- return getShape(virtReg).isValid();
- }
-
- ShapeT getShape(Register virtReg) const {
- assert(virtReg.isVirtual());
- return Virt2ShapeMap.lookup(virtReg);
- }
-
- void assignVirt2Shape(Register virtReg, ShapeT shape) {
- Virt2ShapeMap[virtReg.id()] = shape;
- }
-
+ bool isShapeMapEmpty() const { return Virt2ShapeMap.empty(); }
+
+ bool hasShape(Register virtReg) const {
+ return getShape(virtReg).isValid();
+ }
+
+ ShapeT getShape(Register virtReg) const {
+ assert(virtReg.isVirtual());
+ return Virt2ShapeMap.lookup(virtReg);
+ }
+
+ void assignVirt2Shape(Register virtReg, ShapeT shape) {
+ Virt2ShapeMap[virtReg.id()] = shape;
+ }
+
/// clears the specified virtual register's, physical
/// register mapping
void clearVirt(Register virtReg) {
@@ -158,15 +158,15 @@ class TargetInstrInfo;
bool hasKnownPreference(Register VirtReg);
/// records virtReg is a split live interval from SReg.
- void setIsSplitFromReg(Register virtReg, Register SReg) {
+ void setIsSplitFromReg(Register virtReg, Register SReg) {
Virt2SplitMap[virtReg.id()] = SReg;
- if (hasShape(SReg)) {
- Virt2ShapeMap[virtReg.id()] = getShape(SReg);
- }
+ if (hasShape(SReg)) {
+ Virt2ShapeMap[virtReg.id()] = getShape(SReg);
+ }
}
/// returns the live interval virtReg is split from.
- Register getPreSplitReg(Register virtReg) const {
+ Register getPreSplitReg(Register virtReg) const {
return Virt2SplitMap[virtReg.id()];
}
@@ -174,8 +174,8 @@ class TargetInstrInfo;
/// from through splitting.
/// A register that was not created by splitting is its own original.
/// This operation is idempotent.
- Register getOriginal(Register VirtReg) const {
- Register Orig = getPreSplitReg(VirtReg);
+ Register getOriginal(Register VirtReg) const {
+ Register Orig = getPreSplitReg(VirtReg);
return Orig ? Orig : VirtReg;
}
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/WasmEHFuncInfo.h b/contrib/libs/llvm12/include/llvm/CodeGen/WasmEHFuncInfo.h
index 7ecb43d534..1e5377d30f 100644
--- a/contrib/libs/llvm12/include/llvm/CodeGen/WasmEHFuncInfo.h
+++ b/contrib/libs/llvm12/include/llvm/CodeGen/WasmEHFuncInfo.h
@@ -29,9 +29,9 @@ class BasicBlock;
class Function;
class MachineBasicBlock;
-namespace WebAssembly {
+namespace WebAssembly {
enum EventTag { CPP_EXCEPTION = 0, C_LONGJMP = 1 };
-}
+}
using BBOrMBB = PointerUnion<const BasicBlock *, MachineBasicBlock *>;
diff --git a/contrib/libs/llvm12/include/llvm/Config/abi-breaking.h b/contrib/libs/llvm12/include/llvm/Config/abi-breaking.h
index 0c784ce2e7..c52b41f02c 100644
--- a/contrib/libs/llvm12/include/llvm/Config/abi-breaking.h
+++ b/contrib/libs/llvm12/include/llvm/Config/abi-breaking.h
@@ -27,7 +27,7 @@
/* Allow selectively disabling link-time mismatch checking so that header-only
ADT content from LLVM can be used without linking libSupport. */
-#if !defined(LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING) || !LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING
+#if !defined(LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING) || !LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING
// ABI_BREAKING_CHECKS protection: provides link-time failure when clients build
// mismatch with LLVM
diff --git a/contrib/libs/llvm12/include/llvm/Config/abi-breaking.h.cmake b/contrib/libs/llvm12/include/llvm/Config/abi-breaking.h.cmake
index a9ee788699..2d27e02b1d 100644
--- a/contrib/libs/llvm12/include/llvm/Config/abi-breaking.h.cmake
+++ b/contrib/libs/llvm12/include/llvm/Config/abi-breaking.h.cmake
@@ -20,7 +20,7 @@
/* Allow selectively disabling link-time mismatch checking so that header-only
ADT content from LLVM can be used without linking libSupport. */
-#if !defined(LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING) || !LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING
+#if !defined(LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING) || !LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING
// ABI_BREAKING_CHECKS protection: provides link-time failure when clients build
// mismatch with LLVM
diff --git a/contrib/libs/llvm12/include/llvm/Config/config-linux.h b/contrib/libs/llvm12/include/llvm/Config/config-linux.h
index b0281c2af3..4532972453 100644
--- a/contrib/libs/llvm12/include/llvm/Config/config-linux.h
+++ b/contrib/libs/llvm12/include/llvm/Config/config-linux.h
@@ -65,12 +65,12 @@
/* Define if dladdr() is available on this platform. */
/* #undef HAVE_DLADDR */
-/* Define to 1 if we can register EH frames on this platform. */
-#define HAVE_REGISTER_FRAME 1
-
-/* Define to 1 if we can deregister EH frames on this platform. */
-#define HAVE_DEREGISTER_FRAME 1
-
+/* Define to 1 if we can register EH frames on this platform. */
+#define HAVE_REGISTER_FRAME 1
+
+/* Define to 1 if we can deregister EH frames on this platform. */
+#define HAVE_DEREGISTER_FRAME 1
+
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
@@ -113,9 +113,9 @@
/* Define to 1 if you have the `pfm' library (-lpfm). */
/* #undef HAVE_LIBPFM */
-/* Define to 1 if the `perf_branch_entry' struct has field cycles. */
-/* #undef LIBPFM_HAS_FIELD_CYCLES */
-
+/* Define to 1 if the `perf_branch_entry' struct has field cycles. */
+/* #undef LIBPFM_HAS_FIELD_CYCLES */
+
/* Define to 1 if you have the `psapi' library (-lpsapi). */
/* #undef HAVE_LIBPSAPI */
@@ -222,7 +222,7 @@
#define HAVE_SYS_TYPES_H 1
/* Define if the setupterm() function is supported this platform. */
-/* #undef LLVM_ENABLE_TERMINFO */
+/* #undef LLVM_ENABLE_TERMINFO */
/* Define if the xar_open() function is supported this platform. */
/* #undef HAVE_LIBXAR */
@@ -316,7 +316,7 @@
#define LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO 1
/* Define if libxml2 is supported on this platform. */
-/* #undef LLVM_ENABLE_LIBXML2 */
+/* #undef LLVM_ENABLE_LIBXML2 */
/* Define to the extension used for shared libraries, say, ".so". */
#define LTDL_SHLIB_EXT ".so"
@@ -328,10 +328,10 @@
#define PACKAGE_NAME "LLVM"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "LLVM 12.0.1"
+#define PACKAGE_STRING "LLVM 12.0.1"
/* Define to the version of this package. */
-#define PACKAGE_VERSION "12.0.1"
+#define PACKAGE_VERSION "12.0.1"
/* Define to the vendor of this package. */
/* #undef PACKAGE_VENDOR */
diff --git a/contrib/libs/llvm12/include/llvm/Config/config-osx.h b/contrib/libs/llvm12/include/llvm/Config/config-osx.h
index dae0be82d2..33609f6599 100644
--- a/contrib/libs/llvm12/include/llvm/Config/config-osx.h
+++ b/contrib/libs/llvm12/include/llvm/Config/config-osx.h
@@ -321,10 +321,10 @@
#define PACKAGE_NAME "LLVM"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "LLVM 12.0.1"
+#define PACKAGE_STRING "LLVM 12.0.1"
/* Define to the version of this package. */
-#define PACKAGE_VERSION "12.0.1"
+#define PACKAGE_VERSION "12.0.1"
/* Define to the vendor of this package. */
/* #undef PACKAGE_VENDOR */
diff --git a/contrib/libs/llvm12/include/llvm/Config/config-win.h b/contrib/libs/llvm12/include/llvm/Config/config-win.h
index 2f0dd206a9..86c16fb4d1 100644
--- a/contrib/libs/llvm12/include/llvm/Config/config-win.h
+++ b/contrib/libs/llvm12/include/llvm/Config/config-win.h
@@ -321,10 +321,10 @@
#define PACKAGE_NAME "LLVM"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "LLVM 12.0.1"
+#define PACKAGE_STRING "LLVM 12.0.1"
/* Define to the version of this package. */
-#define PACKAGE_VERSION "12.0.1"
+#define PACKAGE_VERSION "12.0.1"
/* Define to the vendor of this package. */
/* #undef PACKAGE_VENDOR */
diff --git a/contrib/libs/llvm12/include/llvm/Config/config.h.cmake b/contrib/libs/llvm12/include/llvm/Config/config.h.cmake
index c8a206fb23..6664ad3355 100644
--- a/contrib/libs/llvm12/include/llvm/Config/config.h.cmake
+++ b/contrib/libs/llvm12/include/llvm/Config/config.h.cmake
@@ -58,12 +58,12 @@
/* Define if dladdr() is available on this platform. */
#cmakedefine HAVE_DLADDR ${HAVE_DLADDR}
-/* Define to 1 if we can register EH frames on this platform. */
-#cmakedefine HAVE_REGISTER_FRAME ${HAVE_REGISTER_FRAME}
-
-/* Define to 1 if we can deregister EH frames on this platform. */
-#cmakedefine HAVE_DEREGISTER_FRAME ${HAVE_DEREGISTER_FRAME}
-
+/* Define to 1 if we can register EH frames on this platform. */
+#cmakedefine HAVE_REGISTER_FRAME ${HAVE_REGISTER_FRAME}
+
+/* Define to 1 if we can deregister EH frames on this platform. */
+#cmakedefine HAVE_DEREGISTER_FRAME ${HAVE_DEREGISTER_FRAME}
+
/* Define to 1 if you have the <errno.h> header file. */
#cmakedefine HAVE_ERRNO_H ${HAVE_ERRNO_H}
@@ -106,9 +106,9 @@
/* Define to 1 if you have the `pfm' library (-lpfm). */
#cmakedefine HAVE_LIBPFM ${HAVE_LIBPFM}
-/* Define to 1 if the `perf_branch_entry' struct has field cycles. */
-#cmakedefine LIBPFM_HAS_FIELD_CYCLES ${LIBPFM_HAS_FIELD_CYCLES}
-
+/* Define to 1 if the `perf_branch_entry' struct has field cycles. */
+#cmakedefine LIBPFM_HAS_FIELD_CYCLES ${LIBPFM_HAS_FIELD_CYCLES}
+
/* Define to 1 if you have the `psapi' library (-lpsapi). */
#cmakedefine HAVE_LIBPSAPI ${HAVE_LIBPSAPI}
@@ -215,7 +215,7 @@
#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H}
/* Define if the setupterm() function is supported this platform. */
-#cmakedefine LLVM_ENABLE_TERMINFO ${LLVM_ENABLE_TERMINFO}
+#cmakedefine LLVM_ENABLE_TERMINFO ${LLVM_ENABLE_TERMINFO}
/* Define if the xar_open() function is supported this platform. */
#cmakedefine HAVE_LIBXAR ${HAVE_LIBXAR}
@@ -309,7 +309,7 @@
#cmakedefine01 LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO
/* Define if libxml2 is supported on this platform. */
-#cmakedefine LLVM_ENABLE_LIBXML2 ${LLVM_ENABLE_LIBXML2}
+#cmakedefine LLVM_ENABLE_LIBXML2 ${LLVM_ENABLE_LIBXML2}
/* Define to the extension used for shared libraries, say, ".so". */
#cmakedefine LTDL_SHLIB_EXT "${LTDL_SHLIB_EXT}"
diff --git a/contrib/libs/llvm12/include/llvm/Config/llvm-config-linux.h b/contrib/libs/llvm12/include/llvm/Config/llvm-config-linux.h
index 98d7238363..bbfa47d111 100644
--- a/contrib/libs/llvm12/include/llvm/Config/llvm-config-linux.h
+++ b/contrib/libs/llvm12/include/llvm/Config/llvm-config-linux.h
@@ -70,16 +70,16 @@
#define LLVM_USE_PERF 1
/* Major version of the LLVM API */
-#define LLVM_VERSION_MAJOR 12
+#define LLVM_VERSION_MAJOR 12
/* Minor version of the LLVM API */
-#define LLVM_VERSION_MINOR 0
+#define LLVM_VERSION_MINOR 0
/* Patch version of the LLVM API */
-#define LLVM_VERSION_PATCH 1
+#define LLVM_VERSION_PATCH 1
/* LLVM version string */
-#define LLVM_VERSION_STRING "12.0.1"
+#define LLVM_VERSION_STRING "12.0.1"
/* Whether LLVM records statistics for use with GetStatistics(),
* PrintStatistics() or PrintStatisticsJSON()
@@ -92,15 +92,15 @@
/* Define if LLVM was built with a dependency to the libtensorflow dynamic library */
/* #undef LLVM_HAVE_TF_API */
-/* Define if LLVM was built with a dependency to the tensorflow compiler */
-/* #undef LLVM_HAVE_TF_AOT */
-
-/* Define to 1 if you have the <sysexits.h> header file. */
-#define HAVE_SYSEXITS_H 1
-
-/* Define to 1 to enable the experimental new pass manager by default */
-#define LLVM_ENABLE_NEW_PASS_MANAGER 0
-
+/* Define if LLVM was built with a dependency to the tensorflow compiler */
+/* #undef LLVM_HAVE_TF_AOT */
+
+/* Define to 1 if you have the <sysexits.h> header file. */
+#define HAVE_SYSEXITS_H 1
+
+/* Define to 1 to enable the experimental new pass manager by default */
+#define LLVM_ENABLE_NEW_PASS_MANAGER 0
+
#endif
#ifdef __GNUC__
diff --git a/contrib/libs/llvm12/include/llvm/Config/llvm-config-osx.h b/contrib/libs/llvm12/include/llvm/Config/llvm-config-osx.h
index e3d01ef674..b79ed716ab 100644
--- a/contrib/libs/llvm12/include/llvm/Config/llvm-config-osx.h
+++ b/contrib/libs/llvm12/include/llvm/Config/llvm-config-osx.h
@@ -63,35 +63,35 @@
#define LLVM_USE_PERF 0
/* Major version of the LLVM API */
-#define LLVM_VERSION_MAJOR 12
+#define LLVM_VERSION_MAJOR 12
/* Minor version of the LLVM API */
-#define LLVM_VERSION_MINOR 0
+#define LLVM_VERSION_MINOR 0
/* Patch version of the LLVM API */
-#define LLVM_VERSION_PATCH 1
+#define LLVM_VERSION_PATCH 1
/* LLVM version string */
-#define LLVM_VERSION_STRING "12.0.1"
+#define LLVM_VERSION_STRING "12.0.1"
/* Whether LLVM records statistics for use with GetStatistics(),
* PrintStatistics() or PrintStatisticsJSON()
*/
#define LLVM_FORCE_ENABLE_STATS 0
-/* Define if we have z3 and want to build it */
-/* #undef LLVM_WITH_Z3 */
-
-/* Define if LLVM was built with a dependency to the libtensorflow dynamic library */
-/* #undef LLVM_HAVE_TF_API */
-
-/* Define if LLVM was built with a dependency to the tensorflow compiler */
-/* #undef LLVM_HAVE_TF_AOT */
-
-/* Define to 1 if you have the <sysexits.h> header file. */
-#define HAVE_SYSEXITS_H 1
-
-/* Define to 1 to enable the experimental new pass manager by default */
-#define LLVM_ENABLE_NEW_PASS_MANAGER 0
-
+/* Define if we have z3 and want to build it */
+/* #undef LLVM_WITH_Z3 */
+
+/* Define if LLVM was built with a dependency to the libtensorflow dynamic library */
+/* #undef LLVM_HAVE_TF_API */
+
+/* Define if LLVM was built with a dependency to the tensorflow compiler */
+/* #undef LLVM_HAVE_TF_AOT */
+
+/* Define to 1 if you have the <sysexits.h> header file. */
+#define HAVE_SYSEXITS_H 1
+
+/* Define to 1 to enable the experimental new pass manager by default */
+#define LLVM_ENABLE_NEW_PASS_MANAGER 0
+
#endif
diff --git a/contrib/libs/llvm12/include/llvm/Config/llvm-config-win.h b/contrib/libs/llvm12/include/llvm/Config/llvm-config-win.h
index 3a5c79307a..9837c1dad0 100644
--- a/contrib/libs/llvm12/include/llvm/Config/llvm-config-win.h
+++ b/contrib/libs/llvm12/include/llvm/Config/llvm-config-win.h
@@ -63,35 +63,35 @@
#define LLVM_USE_PERF 0
/* Major version of the LLVM API */
-#define LLVM_VERSION_MAJOR 12
+#define LLVM_VERSION_MAJOR 12
/* Minor version of the LLVM API */
-#define LLVM_VERSION_MINOR 0
+#define LLVM_VERSION_MINOR 0
/* Patch version of the LLVM API */
-#define LLVM_VERSION_PATCH 1
+#define LLVM_VERSION_PATCH 1
/* LLVM version string */
-#define LLVM_VERSION_STRING "12.0.1"
+#define LLVM_VERSION_STRING "12.0.1"
/* Whether LLVM records statistics for use with GetStatistics(),
* PrintStatistics() or PrintStatisticsJSON()
*/
#define LLVM_FORCE_ENABLE_STATS 0
-/* Define if we have z3 and want to build it */
-/* #undef LLVM_WITH_Z3 */
-
-/* Define if LLVM was built with a dependency to the libtensorflow dynamic library */
-/* #undef LLVM_HAVE_TF_API */
-
-/* Define if LLVM was built with a dependency to the tensorflow compiler */
-/* #undef LLVM_HAVE_TF_AOT */
-
-/* Define to 1 if you have the <sysexits.h> header file. */
-/* #undef HAVE_SYSEXITS_H 1 */
-
-/* Define to 1 to enable the experimental new pass manager by default */
-#define LLVM_ENABLE_NEW_PASS_MANAGER 0
-
+/* Define if we have z3 and want to build it */
+/* #undef LLVM_WITH_Z3 */
+
+/* Define if LLVM was built with a dependency to the libtensorflow dynamic library */
+/* #undef LLVM_HAVE_TF_API */
+
+/* Define if LLVM was built with a dependency to the tensorflow compiler */
+/* #undef LLVM_HAVE_TF_AOT */
+
+/* Define to 1 if you have the <sysexits.h> header file. */
+/* #undef HAVE_SYSEXITS_H 1 */
+
+/* Define to 1 to enable the experimental new pass manager by default */
+#define LLVM_ENABLE_NEW_PASS_MANAGER 0
+
#endif
diff --git a/contrib/libs/llvm12/include/llvm/Config/llvm-config.h.cmake b/contrib/libs/llvm12/include/llvm/Config/llvm-config.h.cmake
index 19369a5620..b5fa20f789 100644
--- a/contrib/libs/llvm12/include/llvm/Config/llvm-config.h.cmake
+++ b/contrib/libs/llvm12/include/llvm/Config/llvm-config.h.cmake
@@ -85,13 +85,13 @@
/* Define if LLVM was built with a dependency to the libtensorflow dynamic library */
#cmakedefine LLVM_HAVE_TF_API
-/* Define if LLVM was built with a dependency to the tensorflow compiler */
-#cmakedefine LLVM_HAVE_TF_AOT
-
-/* Define to 1 if you have the <sysexits.h> header file. */
-#cmakedefine HAVE_SYSEXITS_H ${HAVE_SYSEXITS_H}
-
-/* Define to 1 to enable the experimental new pass manager by default */
-#cmakedefine01 LLVM_ENABLE_NEW_PASS_MANAGER
-
+/* Define if LLVM was built with a dependency to the tensorflow compiler */
+#cmakedefine LLVM_HAVE_TF_AOT
+
+/* Define to 1 if you have the <sysexits.h> header file. */
+#cmakedefine HAVE_SYSEXITS_H ${HAVE_SYSEXITS_H}
+
+/* Define to 1 to enable the experimental new pass manager by default */
+#cmakedefine01 LLVM_ENABLE_NEW_PASS_MANAGER
+
#endif
diff --git a/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinker.h b/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinker.h
index fdc8be13fb..f6007dfbec 100644
--- a/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinker.h
+++ b/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinker.h
@@ -71,18 +71,18 @@ public:
/// section. Reset current relocation pointer if neccessary.
virtual bool hasValidRelocs(bool ResetRelocsPtr = true) = 0;
- /// Checks that the specified DIE has a DW_AT_Location attribute
- /// that references into a live code section. This function
- /// must be called with DIE offsets in strictly ascending order.
- virtual bool hasLiveMemoryLocation(const DWARFDie &DIE,
- CompileUnit::DIEInfo &Info) = 0;
-
- /// Checks that the specified DIE has a DW_AT_Low_pc attribute
- /// that references into a live code section. This function
- /// must be called with DIE offsets in strictly ascending order.
- virtual bool hasLiveAddressRange(const DWARFDie &DIE,
- CompileUnit::DIEInfo &Info) = 0;
-
+ /// Checks that the specified DIE has a DW_AT_Location attribute
+ /// that references into a live code section. This function
+ /// must be called with DIE offsets in strictly ascending order.
+ virtual bool hasLiveMemoryLocation(const DWARFDie &DIE,
+ CompileUnit::DIEInfo &Info) = 0;
+
+ /// Checks that the specified DIE has a DW_AT_Low_pc attribute
+ /// that references into a live code section. This function
+ /// must be called with DIE offsets in strictly ascending order.
+ virtual bool hasLiveAddressRange(const DWARFDie &DIE,
+ CompileUnit::DIEInfo &Info) = 0;
+
/// Apply the valid relocations to the buffer \p Data, taking into
/// account that Data is at \p BaseOffset in the debug_info section.
///
@@ -92,9 +92,9 @@ public:
virtual bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
bool IsLittleEndian) = 0;
- /// Relocate the given address offset if a valid relocation exists.
- virtual llvm::Expected<uint64_t> relocateIndexedAddr(uint64_t Offset) = 0;
-
+ /// Relocate the given address offset if a valid relocation exists.
+ virtual llvm::Expected<uint64_t> relocateIndexedAddr(uint64_t Offset) = 0;
+
/// Returns all valid functions address ranges(i.e., those ranges
/// which points to sections with code).
virtual RangesTy &getValidAddressRanges() = 0;
@@ -193,8 +193,8 @@ public:
///
/// As a side effect, this also switches the current Dwarf version
/// of the MC layer to the one of U.getOrigUnit().
- virtual void emitCompileUnitHeader(CompileUnit &Unit,
- unsigned DwarfVersion) = 0;
+ virtual void emitCompileUnitHeader(CompileUnit &Unit,
+ unsigned DwarfVersion) = 0;
/// Recursively emit the DIE tree rooted at \p Die.
virtual void emitDIE(DIE &Die) = 0;
@@ -216,9 +216,9 @@ using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>;
/// this class represents DWARF information for source file
/// and it`s address map.
-class DWARFFile {
+class DWARFFile {
public:
- DWARFFile(StringRef Name, DWARFContext *Dwarf, AddressesMap *Addresses,
+ DWARFFile(StringRef Name, DWARFContext *Dwarf, AddressesMap *Addresses,
const std::vector<std::string> &Warnings)
: FileName(Name), Dwarf(Dwarf), Addresses(Addresses), Warnings(Warnings) {
}
@@ -236,7 +236,7 @@ public:
typedef std::function<void(const Twine &Warning, StringRef Context,
const DWARFDie *DIE)>
messageHandler;
-typedef std::function<ErrorOr<DWARFFile &>(StringRef ContainerName,
+typedef std::function<ErrorOr<DWARFFile &>(StringRef ContainerName,
StringRef Path)>
objFileLoader;
typedef std::map<std::string, std::string> swiftInterfacesMap;
@@ -263,7 +263,7 @@ public:
: TheDwarfEmitter(Emitter), DwarfLinkerClientID(ClientID) {}
/// Add object file to be linked.
- void addObjectFile(DWARFFile &File);
+ void addObjectFile(DWARFFile &File);
/// Link debug info for added objFiles. Object
/// files are linked all together.
@@ -367,38 +367,38 @@ private:
/// of work needs to be performed when processing the current item. The flags
/// and info fields are optional based on the type.
struct WorklistItem {
- DWARFDie Die;
+ DWARFDie Die;
WorklistItemType Type;
CompileUnit &CU;
unsigned Flags;
- union {
- const unsigned AncestorIdx;
- CompileUnit::DIEInfo *OtherInfo;
- };
+ union {
+ const unsigned AncestorIdx;
+ CompileUnit::DIEInfo *OtherInfo;
+ };
WorklistItem(DWARFDie Die, CompileUnit &CU, unsigned Flags,
WorklistItemType T = WorklistItemType::LookForDIEsToKeep)
- : Die(Die), Type(T), CU(CU), Flags(Flags), AncestorIdx(0) {}
+ : Die(Die), Type(T), CU(CU), Flags(Flags), AncestorIdx(0) {}
WorklistItem(DWARFDie Die, CompileUnit &CU, WorklistItemType T,
CompileUnit::DIEInfo *OtherInfo = nullptr)
- : Die(Die), Type(T), CU(CU), Flags(0), OtherInfo(OtherInfo) {}
+ : Die(Die), Type(T), CU(CU), Flags(0), OtherInfo(OtherInfo) {}
WorklistItem(unsigned AncestorIdx, CompileUnit &CU, unsigned Flags)
- : Die(), Type(WorklistItemType::LookForParentDIEsToKeep), CU(CU),
- Flags(Flags), AncestorIdx(AncestorIdx) {}
+ : Die(), Type(WorklistItemType::LookForParentDIEsToKeep), CU(CU),
+ Flags(Flags), AncestorIdx(AncestorIdx) {}
};
/// returns true if we need to translate strings.
bool needToTranslateStrings() { return StringsTranslator != nullptr; }
- void reportWarning(const Twine &Warning, const DWARFFile &File,
+ void reportWarning(const Twine &Warning, const DWARFFile &File,
const DWARFDie *DIE = nullptr) const {
if (Options.WarningHandler != nullptr)
Options.WarningHandler(Warning, File.FileName, DIE);
}
- void reportError(const Twine &Warning, const DWARFFile &File,
+ void reportError(const Twine &Warning, const DWARFFile &File,
const DWARFDie *DIE = nullptr) const {
if (Options.ErrorHandler != nullptr)
Options.ErrorHandler(Warning, File.FileName, DIE);
@@ -414,18 +414,18 @@ private:
void updateAccelKind(DWARFContext &Dwarf);
/// Emit warnings as Dwarf compile units to leave a trail after linking.
- bool emitPaperTrailWarnings(const DWARFFile &File,
+ bool emitPaperTrailWarnings(const DWARFFile &File,
OffsetsStringPool &StringPool);
void copyInvariantDebugSection(DWARFContext &Dwarf);
/// Keeps track of data associated with one object during linking.
struct LinkContext {
- DWARFFile &File;
+ DWARFFile &File;
UnitListTy CompileUnits;
bool Skip = false;
- LinkContext(DWARFFile &File) : File(File) {}
+ LinkContext(DWARFFile &File) : File(File) {}
/// Clear part of the context that's no longer needed when we're done with
/// the debug object.
@@ -454,7 +454,7 @@ private:
/// kept. All DIEs referenced though attributes should be kept.
void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
unsigned Flags, const UnitListTy &Units,
- const DWARFFile &File,
+ const DWARFFile &File,
SmallVectorImpl<WorklistItem> &Worklist);
/// \defgroup FindRootDIEs Find DIEs corresponding to Address map entries.
@@ -466,7 +466,7 @@ private:
/// The return value indicates whether the DIE is incomplete.
void lookForDIEsToKeep(AddressesMap &RelocMgr, RangesTy &Ranges,
const UnitListTy &Units, const DWARFDie &DIE,
- const DWARFFile &File, CompileUnit &CU,
+ const DWARFFile &File, CompileUnit &CU,
unsigned Flags);
/// If this compile unit is really a skeleton CU that points to a
@@ -476,7 +476,7 @@ private:
/// pointing to the module, and a DW_AT_gnu_dwo_id with the module
/// hash.
bool registerModuleReference(DWARFDie CUDie, const DWARFUnit &Unit,
- const DWARFFile &File,
+ const DWARFFile &File,
OffsetsStringPool &OffsetsStringPool,
DeclContextTree &ODRContexts,
uint64_t ModulesEndOffset, unsigned &UnitID,
@@ -488,7 +488,7 @@ private:
/// to Units.
Error loadClangModule(DWARFDie CUDie, StringRef FilePath,
StringRef ModuleName, uint64_t DwoId,
- const DWARFFile &File,
+ const DWARFFile &File,
OffsetsStringPool &OffsetsStringPool,
DeclContextTree &ODRContexts, uint64_t ModulesEndOffset,
unsigned &UnitID, bool IsLittleEndian,
@@ -498,11 +498,11 @@ private:
void keepDIEAndDependencies(AddressesMap &RelocMgr, RangesTy &Ranges,
const UnitListTy &Units, const DWARFDie &DIE,
CompileUnit::DIEInfo &MyInfo,
- const DWARFFile &File, CompileUnit &CU,
+ const DWARFFile &File, CompileUnit &CU,
bool UseODR);
unsigned shouldKeepDIE(AddressesMap &RelocMgr, RangesTy &Ranges,
- const DWARFDie &DIE, const DWARFFile &File,
+ const DWARFDie &DIE, const DWARFFile &File,
CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo,
unsigned Flags);
@@ -512,7 +512,7 @@ private:
CompileUnit::DIEInfo &MyInfo, unsigned Flags);
unsigned shouldKeepSubprogramDIE(AddressesMap &RelocMgr, RangesTy &Ranges,
- const DWARFDie &DIE, const DWARFFile &File,
+ const DWARFDie &DIE, const DWARFFile &File,
CompileUnit &Unit,
CompileUnit::DIEInfo &MyInfo,
unsigned Flags);
@@ -521,7 +521,7 @@ private:
/// RefValue. The resulting DIE might be in another CompileUnit which is
/// stored into \p ReferencedCU. \returns null if resolving fails for any
/// reason.
- DWARFDie resolveDIEReference(const DWARFFile &File, const UnitListTy &Units,
+ DWARFDie resolveDIEReference(const DWARFFile &File, const UnitListTy &Units,
const DWARFFormValue &RefValue,
const DWARFDie &DIE, CompileUnit *&RefCU);
@@ -536,7 +536,7 @@ private:
class DIECloner {
DWARFLinker &Linker;
DwarfEmitter *Emitter;
- DWARFFile &ObjFile;
+ DWARFFile &ObjFile;
/// Allocator used for all the DIEValue objects.
BumpPtrAllocator &DIEAlloc;
@@ -546,7 +546,7 @@ private:
bool Update;
public:
- DIECloner(DWARFLinker &Linker, DwarfEmitter *Emitter, DWARFFile &ObjFile,
+ DIECloner(DWARFLinker &Linker, DwarfEmitter *Emitter, DWARFFile &ObjFile,
BumpPtrAllocator &DIEAlloc,
std::vector<std::unique_ptr<CompileUnit>> &CompileUnits,
bool Update)
@@ -564,7 +564,7 @@ private:
/// applied to the entry point of the function to get the linked address.
/// \param Die the output DIE to use, pass NULL to create one.
/// \returns the root of the cloned tree or null if nothing was selected.
- DIE *cloneDIE(const DWARFDie &InputDIE, const DWARFFile &File,
+ DIE *cloneDIE(const DWARFDie &InputDIE, const DWARFFile &File,
CompileUnit &U, OffsetsStringPool &StringPool,
int64_t PCOffset, uint32_t OutOffset, unsigned Flags,
bool IsLittleEndian, DIE *Die = nullptr);
@@ -573,7 +573,7 @@ private:
/// chose to keep above. If there are no valid relocs, then there's
/// nothing to clone/emit.
uint64_t cloneAllCompileUnits(DWARFContext &DwarfContext,
- const DWARFFile &File,
+ const DWARFFile &File,
OffsetsStringPool &StringPool,
bool IsLittleEndian);
@@ -619,7 +619,7 @@ private:
/// Helper for cloneDIE.
unsigned cloneAttribute(DIE &Die, const DWARFDie &InputDIE,
- const DWARFFile &File, CompileUnit &U,
+ const DWARFFile &File, CompileUnit &U,
OffsetsStringPool &StringPool,
const DWARFFormValue &Val,
const AttributeSpec AttrSpec, unsigned AttrSize,
@@ -640,18 +640,18 @@ private:
AttributeSpec AttrSpec,
unsigned AttrSize,
const DWARFFormValue &Val,
- const DWARFFile &File,
+ const DWARFFile &File,
CompileUnit &Unit);
/// Clone a DWARF expression that may be referencing another DIE.
void cloneExpression(DataExtractor &Data, DWARFExpression Expression,
- const DWARFFile &File, CompileUnit &Unit,
+ const DWARFFile &File, CompileUnit &Unit,
SmallVectorImpl<uint8_t> &OutputBuffer);
/// Clone an attribute referencing another DIE and add
/// it to \p Die.
/// \returns the size of the new attribute.
- unsigned cloneBlockAttribute(DIE &Die, const DWARFFile &File,
+ unsigned cloneBlockAttribute(DIE &Die, const DWARFFile &File,
CompileUnit &Unit, AttributeSpec AttrSpec,
const DWARFFormValue &Val, unsigned AttrSize,
bool IsLittleEndian);
@@ -667,7 +667,7 @@ private:
/// Clone a scalar attribute and add it to \p Die.
/// \returns the size of the new attribute.
unsigned cloneScalarAttribute(DIE &Die, const DWARFDie &InputDIE,
- const DWARFFile &File, CompileUnit &U,
+ const DWARFFile &File, CompileUnit &U,
AttributeSpec AttrSpec,
const DWARFFormValue &Val, unsigned AttrSize,
AttributesInfo &Info);
@@ -683,7 +683,7 @@ private:
void copyAbbrev(const DWARFAbbreviationDeclaration &Abbrev, bool hasODR);
uint32_t hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U,
- const DWARFFile &File,
+ const DWARFFile &File,
int RecurseDepth = 0);
/// Helper for cloneDIE.
@@ -698,7 +698,7 @@ private:
/// Compute and emit debug_ranges section for \p Unit, and
/// patch the attributes referencing it.
void patchRangesForUnit(const CompileUnit &Unit, DWARFContext &Dwarf,
- const DWARFFile &File) const;
+ const DWARFFile &File) const;
/// Generate and emit the DW_AT_ranges attribute for a compile_unit if it had
/// one.
@@ -708,7 +708,7 @@ private:
/// parts according to the linked function ranges and emit the result in the
/// debug_line section.
void patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf,
- const DWARFFile &File);
+ const DWARFFile &File);
/// Emit the accelerator entries for \p Unit.
void emitAcceleratorEntriesForUnit(CompileUnit &Unit);
@@ -716,7 +716,7 @@ private:
void emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit);
/// Patch the frame info for an object file and emit it.
- void patchFrameInfoForObject(const DWARFFile &, RangesTy &Ranges,
+ void patchFrameInfoForObject(const DWARFFile &, RangesTy &Ranges,
DWARFContext &, unsigned AddressSize);
/// FoldingSet that uniques the abbreviations.
diff --git a/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h b/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
index 14628a496e..3e168e217f 100644
--- a/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
+++ b/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
@@ -108,7 +108,7 @@ public:
unsigned getUniqueID() const { return ID; }
- void createOutputDIE() { NewUnit.emplace(OrigUnit.getUnitDIE().getTag()); }
+ void createOutputDIE() { NewUnit.emplace(OrigUnit.getUnitDIE().getTag()); }
DIE *getOutputUnitDIE() const {
if (NewUnit)
@@ -127,11 +127,11 @@ public:
DIEInfo &getInfo(unsigned Idx) { return Info[Idx]; }
const DIEInfo &getInfo(unsigned Idx) const { return Info[Idx]; }
- DIEInfo &getInfo(const DWARFDie &Die) {
- unsigned Idx = getOrigUnit().getDIEIndex(Die);
- return Info[Idx];
- }
-
+ DIEInfo &getInfo(const DWARFDie &Die) {
+ unsigned Idx = getOrigUnit().getDIEIndex(Die);
+ return Info[Idx];
+ }
+
uint64_t getStartOffset() const { return StartOffset; }
uint64_t getNextUnitOffset() const { return NextUnitOffset; }
void setStartOffset(uint64_t DebugInfoSize) { StartOffset = DebugInfoSize; }
@@ -166,7 +166,7 @@ public:
/// Compute the end offset for this unit. Must be called after the CU's DIEs
/// have been cloned. \returns the next unit offset (which is also the
/// current debug_info section size).
- uint64_t computeNextUnitOffset(uint16_t DwarfVersion);
+ uint64_t computeNextUnitOffset(uint16_t DwarfVersion);
/// Keep track of a forward reference to DIE \p Die in \p RefUnit by \p
/// Attr. The attribute should be fixed up later to point to the absolute
diff --git a/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinkerDeclContext.h b/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinkerDeclContext.h
index 5e86f3898a..454d1fa7a9 100644
--- a/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinkerDeclContext.h
+++ b/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinkerDeclContext.h
@@ -22,7 +22,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/NonRelocatableStringpool.h"
#include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
@@ -39,18 +39,18 @@ class CachedPathResolver {
public:
/// Resolve a path by calling realpath and cache its result. The returned
/// StringRef is interned in the given \p StringPool.
- StringRef resolve(const std::string &Path,
- NonRelocatableStringpool &StringPool) {
+ StringRef resolve(const std::string &Path,
+ NonRelocatableStringpool &StringPool) {
StringRef FileName = sys::path::filename(Path);
- StringRef ParentPath = sys::path::parent_path(Path);
+ StringRef ParentPath = sys::path::parent_path(Path);
// If the ParentPath has not yet been resolved, resolve and cache it for
// future look-ups.
if (!ResolvedPaths.count(ParentPath)) {
SmallString<256> RealPath;
sys::fs::real_path(ParentPath, RealPath);
- ResolvedPaths.insert(
- {ParentPath, std::string(RealPath.c_str(), RealPath.size())});
+ ResolvedPaths.insert(
+ {ParentPath, std::string(RealPath.c_str(), RealPath.size())});
}
// Join the file name again with the resolved path.
@@ -138,10 +138,10 @@ public:
///
/// FIXME: The invalid bit along the return value is to emulate some
/// dsymutil-classic functionality.
- PointerIntPair<DeclContext *, 1> getChildDeclContext(DeclContext &Context,
- const DWARFDie &DIE,
- CompileUnit &Unit,
- bool InClangModule);
+ PointerIntPair<DeclContext *, 1> getChildDeclContext(DeclContext &Context,
+ const DWARFDie &DIE,
+ CompileUnit &Unit,
+ bool InClangModule);
DeclContext &getRoot() { return Root; }
@@ -150,19 +150,19 @@ private:
DeclContext Root;
DeclContext::Map Contexts;
- /// Cached resolved paths from the line table.
- /// The key is <UniqueUnitID, FileIdx>.
- using ResolvedPathsMap = DenseMap<std::pair<unsigned, unsigned>, StringRef>;
- ResolvedPathsMap ResolvedPaths;
-
- /// Helper that resolves and caches fragments of file paths.
+ /// Cached resolved paths from the line table.
+ /// The key is <UniqueUnitID, FileIdx>.
+ using ResolvedPathsMap = DenseMap<std::pair<unsigned, unsigned>, StringRef>;
+ ResolvedPathsMap ResolvedPaths;
+
+ /// Helper that resolves and caches fragments of file paths.
CachedPathResolver PathResolver;
-
- /// String pool keeping real path bodies.
- NonRelocatableStringpool StringPool;
-
- StringRef getResolvedPath(CompileUnit &CU, unsigned FileNum,
- const DWARFDebugLine::LineTable &LineTable);
+
+ /// String pool keeping real path bodies.
+ NonRelocatableStringpool StringPool;
+
+ StringRef getResolvedPath(CompileUnit &CU, unsigned FileNum,
+ const DWARFDebugLine::LineTable &LineTable);
};
/// Info type for the DenseMap storing the DeclContext pointers.
diff --git a/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFStreamer.h b/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFStreamer.h
index 3ef665c37a..ac5f5d45be 100644
--- a/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFStreamer.h
+++ b/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFStreamer.h
@@ -71,7 +71,7 @@ public:
///
/// As a side effect, this also switches the current Dwarf version
/// of the MC layer to the one of U.getOrigUnit().
- void emitCompileUnitHeader(CompileUnit &Unit, unsigned DwarfVersion) override;
+ void emitCompileUnitHeader(CompileUnit &Unit, unsigned DwarfVersion) override;
/// Recursively emit the DIE tree rooted at \p Die.
void emitDIE(DIE &Die) override;
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/CVRecord.h b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/CVRecord.h
index ee0b672695..37e2e918e0 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/CVRecord.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/CVRecord.h
@@ -18,7 +18,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/Support/BinaryStreamReader.h"
@@ -68,9 +68,9 @@ public:
ArrayRef<uint8_t> RecordData;
};
-// There are two kinds of codeview records: type and symbol records.
-using CVType = CVRecord<TypeLeafKind>;
-using CVSymbol = CVRecord<SymbolKind>;
+// There are two kinds of codeview records: type and symbol records.
+using CVType = CVRecord<TypeLeafKind>;
+using CVSymbol = CVRecord<SymbolKind>;
template <typename Record, typename Func>
Error forEachCodeViewRecord(ArrayRef<uint8_t> StreamBuffer, Func F) {
@@ -130,12 +130,12 @@ struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> {
}
};
-namespace codeview {
-using CVSymbolArray = VarStreamArray<CVSymbol>;
-using CVTypeArray = VarStreamArray<CVType>;
-using CVTypeRange = iterator_range<CVTypeArray::Iterator>;
-} // namespace codeview
-
+namespace codeview {
+using CVSymbolArray = VarStreamArray<CVSymbol>;
+using CVTypeArray = VarStreamArray<CVType>;
+using CVTypeRange = iterator_range<CVTypeArray::Iterator>;
+} // namespace codeview
+
} // end namespace llvm
#endif // LLVM_DEBUGINFO_CODEVIEW_RECORDITERATOR_H
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
index 5c0b0a5d19..f21d24d0ba 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
@@ -22,8 +22,8 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
-#include "llvm/DebugInfo/CodeView/GUID.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/GUID.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Error.h"
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def
index cf988a9539..48ea7e52c1 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def
@@ -15,7 +15,7 @@
#endif
#if !defined(CV_REGISTERS_ALL) && !defined(CV_REGISTERS_X86) && \
- !defined(CV_REGISTERS_ARM) && \
+ !defined(CV_REGISTERS_ARM) && \
!defined(CV_REGISTERS_ARM64)
#error Need include at least one register set.
#endif
@@ -394,46 +394,46 @@ CV_REGISTER(ARM_PC, 25)
// Status register
-CV_REGISTER(ARM_CPSR, 26)
+CV_REGISTER(ARM_CPSR, 26)
// ARM VFPv1 registers
CV_REGISTER(ARM_FPSCR, 40)
CV_REGISTER(ARM_FPEXC, 41)
-CV_REGISTER(ARM_FS0, 50)
-CV_REGISTER(ARM_FS1, 51)
-CV_REGISTER(ARM_FS2, 52)
-CV_REGISTER(ARM_FS3, 53)
-CV_REGISTER(ARM_FS4, 54)
-CV_REGISTER(ARM_FS5, 55)
-CV_REGISTER(ARM_FS6, 56)
-CV_REGISTER(ARM_FS7, 57)
-CV_REGISTER(ARM_FS8, 58)
-CV_REGISTER(ARM_FS9, 59)
-CV_REGISTER(ARM_FS10, 60)
-CV_REGISTER(ARM_FS11, 61)
-CV_REGISTER(ARM_FS12, 62)
-CV_REGISTER(ARM_FS13, 63)
-CV_REGISTER(ARM_FS14, 64)
-CV_REGISTER(ARM_FS15, 65)
-CV_REGISTER(ARM_FS16, 66)
-CV_REGISTER(ARM_FS17, 67)
-CV_REGISTER(ARM_FS18, 68)
-CV_REGISTER(ARM_FS19, 69)
-CV_REGISTER(ARM_FS20, 70)
-CV_REGISTER(ARM_FS21, 71)
-CV_REGISTER(ARM_FS22, 72)
-CV_REGISTER(ARM_FS23, 73)
-CV_REGISTER(ARM_FS24, 74)
-CV_REGISTER(ARM_FS25, 75)
-CV_REGISTER(ARM_FS26, 76)
-CV_REGISTER(ARM_FS27, 77)
-CV_REGISTER(ARM_FS28, 78)
-CV_REGISTER(ARM_FS29, 79)
-CV_REGISTER(ARM_FS30, 80)
-CV_REGISTER(ARM_FS31, 81)
-
+CV_REGISTER(ARM_FS0, 50)
+CV_REGISTER(ARM_FS1, 51)
+CV_REGISTER(ARM_FS2, 52)
+CV_REGISTER(ARM_FS3, 53)
+CV_REGISTER(ARM_FS4, 54)
+CV_REGISTER(ARM_FS5, 55)
+CV_REGISTER(ARM_FS6, 56)
+CV_REGISTER(ARM_FS7, 57)
+CV_REGISTER(ARM_FS8, 58)
+CV_REGISTER(ARM_FS9, 59)
+CV_REGISTER(ARM_FS10, 60)
+CV_REGISTER(ARM_FS11, 61)
+CV_REGISTER(ARM_FS12, 62)
+CV_REGISTER(ARM_FS13, 63)
+CV_REGISTER(ARM_FS14, 64)
+CV_REGISTER(ARM_FS15, 65)
+CV_REGISTER(ARM_FS16, 66)
+CV_REGISTER(ARM_FS17, 67)
+CV_REGISTER(ARM_FS18, 68)
+CV_REGISTER(ARM_FS19, 69)
+CV_REGISTER(ARM_FS20, 70)
+CV_REGISTER(ARM_FS21, 71)
+CV_REGISTER(ARM_FS22, 72)
+CV_REGISTER(ARM_FS23, 73)
+CV_REGISTER(ARM_FS24, 74)
+CV_REGISTER(ARM_FS25, 75)
+CV_REGISTER(ARM_FS26, 76)
+CV_REGISTER(ARM_FS27, 77)
+CV_REGISTER(ARM_FS28, 78)
+CV_REGISTER(ARM_FS29, 79)
+CV_REGISTER(ARM_FS30, 80)
+CV_REGISTER(ARM_FS31, 81)
+
// ARM VFPv3/NEON registers
CV_REGISTER(ARM_FS32, 200)
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h
index 6de74e8670..a04b6a0f3e 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h
@@ -16,7 +16,7 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLSSUBSECTION_H
#define LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLSSUBSECTION_H
-#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
#include "llvm/Support/Error.h"
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/SymbolDumper.h b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/SymbolDumper.h
index ce8b0b2c4d..2191657b0f 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/SymbolDumper.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/SymbolDumper.h
@@ -18,7 +18,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringSet.h"
-#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/SymbolRecordHelpers.h b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/SymbolRecordHelpers.h
index f85d8558eb..db805026eb 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/SymbolRecordHelpers.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/SymbolRecordHelpers.h
@@ -16,8 +16,8 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORDHELPERS_H
#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORDHELPERS_H
-#include "llvm/DebugInfo/CodeView/CVRecord.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
namespace llvm {
namespace codeview {
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeCollection.h b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeCollection.h
index 193d2ca528..6bb3a1f0c5 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeCollection.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeCollection.h
@@ -17,7 +17,7 @@
#define LLVM_DEBUGINFO_CODEVIEW_TYPECOLLECTION_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
namespace llvm {
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeHashing.h b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeHashing.h
index 30e5dcb43f..b0b784aef0 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeHashing.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeHashing.h
@@ -93,16 +93,16 @@ struct GloballyHashedType {
bool empty() const { return *(const uint64_t*)Hash.data() == 0; }
- friend inline bool operator==(const GloballyHashedType &L,
- const GloballyHashedType &R) {
- return L.Hash == R.Hash;
- }
-
- friend inline bool operator!=(const GloballyHashedType &L,
- const GloballyHashedType &R) {
- return !(L.Hash == R.Hash);
- }
-
+ friend inline bool operator==(const GloballyHashedType &L,
+ const GloballyHashedType &R) {
+ return L.Hash == R.Hash;
+ }
+
+ friend inline bool operator!=(const GloballyHashedType &L,
+ const GloballyHashedType &R) {
+ return !(L.Hash == R.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
/// of referenced records, this function requires a list of types and ids
@@ -218,7 +218,7 @@ template <> struct DenseMapInfo<codeview::GloballyHashedType> {
static bool isEqual(codeview::GloballyHashedType LHS,
codeview::GloballyHashedType RHS) {
- return LHS == RHS;
+ return LHS == RHS;
}
};
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeIndex.h b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeIndex.h
index 087d4ec3c7..498a353d2b 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeIndex.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeIndex.h
@@ -123,22 +123,22 @@ public:
uint32_t toArrayIndex() const {
assert(!isSimple());
- return (getIndex() & ~DecoratedItemIdMask) - FirstNonSimpleIndex;
+ return (getIndex() & ~DecoratedItemIdMask) - FirstNonSimpleIndex;
}
static TypeIndex fromArrayIndex(uint32_t Index) {
return TypeIndex(Index + FirstNonSimpleIndex);
}
- static TypeIndex fromDecoratedArrayIndex(bool IsItem, uint32_t Index) {
- return TypeIndex((Index + FirstNonSimpleIndex) |
- (IsItem ? DecoratedItemIdMask : 0));
- }
-
- TypeIndex removeDecoration() {
- return TypeIndex(Index & ~DecoratedItemIdMask);
- }
-
+ static TypeIndex fromDecoratedArrayIndex(bool IsItem, uint32_t Index) {
+ return TypeIndex((Index + FirstNonSimpleIndex) |
+ (IsItem ? DecoratedItemIdMask : 0));
+ }
+
+ TypeIndex removeDecoration() {
+ return TypeIndex(Index & ~DecoratedItemIdMask);
+ }
+
SimpleTypeKind getSimpleKind() const {
assert(isSimple());
return static_cast<SimpleTypeKind>(Index & SimpleKindMask);
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h
index a34f6b7167..4116cb7942 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h
@@ -17,8 +17,8 @@
#define LLVM_DEBUGINFO_CODEVIEW_TYPEINDEXDISCOVERY_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/DebugInfo/CodeView/CVRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/Support/Error.h"
namespace llvm {
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeRecord.h b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeRecord.h
index 10332368b6..d1a26a4ea3 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeRecord.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeRecord.h
@@ -704,7 +704,7 @@ public:
: TypeRecord(TypeRecordKind::VFTable), CompleteClass(CompleteClass),
OverriddenVFTable(OverriddenVFTable), VFPtrOffset(VFPtrOffset) {
MethodNames.push_back(Name);
- llvm::append_range(MethodNames, Methods);
+ llvm::append_range(MethodNames, Methods);
}
TypeIndex getCompleteClass() const { return CompleteClass; }
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeRecordHelpers.h b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeRecordHelpers.h
index f8edffa574..a396b0d824 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeRecordHelpers.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeRecordHelpers.h
@@ -16,8 +16,8 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPERECORDHELPERS_H
#define LLVM_DEBUGINFO_CODEVIEW_TYPERECORDHELPERS_H
-#include "llvm/DebugInfo/CodeView/CVRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
namespace llvm {
namespace codeview {
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h
index 1a1459f707..66de771e52 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h
@@ -18,7 +18,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/Support/Error.h"
namespace llvm {
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/DIContext.h b/contrib/libs/llvm12/include/llvm/DebugInfo/DIContext.h
index ae901133c0..5be5936216 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/DIContext.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/DIContext.h
@@ -42,7 +42,7 @@ struct DILineInfo {
static constexpr const char *const Addr2LineBadString = "??";
std::string FileName;
std::string FunctionName;
- std::string StartFileName;
+ std::string StartFileName;
Optional<StringRef> Source;
uint32_t Line = 0;
uint32_t Column = 0;
@@ -51,15 +51,15 @@ struct DILineInfo {
// DWARF-specific.
uint32_t Discriminator = 0;
- DILineInfo()
- : FileName(BadString), FunctionName(BadString), StartFileName(BadString) {
- }
+ DILineInfo()
+ : FileName(BadString), FunctionName(BadString), StartFileName(BadString) {
+ }
bool operator==(const DILineInfo &RHS) const {
return Line == RHS.Line && Column == RHS.Column &&
FileName == RHS.FileName && FunctionName == RHS.FunctionName &&
- StartFileName == RHS.StartFileName && StartLine == RHS.StartLine &&
- Discriminator == RHS.Discriminator;
+ StartFileName == RHS.StartFileName && StartLine == RHS.StartLine &&
+ Discriminator == RHS.Discriminator;
}
bool operator!=(const DILineInfo &RHS) const {
@@ -67,10 +67,10 @@ struct DILineInfo {
}
bool operator<(const DILineInfo &RHS) const {
- return std::tie(FileName, FunctionName, StartFileName, Line, Column,
- StartLine, Discriminator) <
- std::tie(RHS.FileName, RHS.FunctionName, RHS.StartFileName, RHS.Line,
- RHS.Column, RHS.StartLine, RHS.Discriminator);
+ return std::tie(FileName, FunctionName, StartFileName, Line, Column,
+ StartLine, Discriminator) <
+ std::tie(RHS.FileName, RHS.FunctionName, RHS.StartFileName, RHS.Line,
+ RHS.Column, RHS.StartLine, RHS.Discriminator);
}
explicit operator bool() const { return *this != DILineInfo(); }
@@ -83,8 +83,8 @@ struct DILineInfo {
OS << "function '" << FunctionName << "', ";
OS << "line " << Line << ", ";
OS << "column " << Column << ", ";
- if (StartFileName != BadString)
- OS << "start file '" << StartFileName << "', ";
+ if (StartFileName != BadString)
+ OS << "start file '" << StartFileName << "', ";
OS << "start line " << StartLine << '\n';
}
};
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h
index 13d3250535..930cfeb651 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h
@@ -118,16 +118,16 @@ public:
return AttributeSpecs[idx].Attr;
}
- bool getAttrIsImplicitConstByIndex(uint32_t idx) const {
- assert(idx < AttributeSpecs.size());
- return AttributeSpecs[idx].isImplicitConst();
- }
-
- int64_t getAttrImplicitConstValueByIndex(uint32_t idx) const {
- assert(idx < AttributeSpecs.size());
- return AttributeSpecs[idx].getImplicitConstValue();
- }
-
+ bool getAttrIsImplicitConstByIndex(uint32_t idx) const {
+ assert(idx < AttributeSpecs.size());
+ return AttributeSpecs[idx].isImplicitConst();
+ }
+
+ int64_t getAttrImplicitConstValueByIndex(uint32_t idx) const {
+ assert(idx < AttributeSpecs.size());
+ return AttributeSpecs[idx].getImplicitConstValue();
+ }
+
/// Get the index of the specified attribute.
///
/// Searches the this abbreviation declaration for the index of the specified
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFContext.h b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFContext.h
index aeb266e53e..e382fe4aa2 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -153,7 +153,7 @@ public:
bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;
using unit_iterator_range = DWARFUnitVector::iterator_range;
- using compile_unit_range = DWARFUnitVector::compile_unit_range;
+ using compile_unit_range = DWARFUnitVector::compile_unit_range;
/// Get units from .debug_info in this context.
unit_iterator_range info_section_units() {
@@ -171,12 +171,12 @@ public:
}
/// Get compile units in this context.
- compile_unit_range compile_units() {
- return make_filter_range(info_section_units(), isCompileUnit);
- }
+ compile_unit_range compile_units() {
+ return make_filter_range(info_section_units(), isCompileUnit);
+ }
- // If you want type_units(), it'll need to be a concat iterator of a filter of
- // TUs in info_section + all the (all type) units in types_section
+ // If you want type_units(), it'll need to be a concat iterator of a filter of
+ // TUs in info_section + all the (all type) units in types_section
/// Get all normal compile/type units in this context.
unit_iterator_range normal_units() {
@@ -199,13 +199,13 @@ public:
}
/// Get compile units in the DWO context.
- compile_unit_range dwo_compile_units() {
- return make_filter_range(dwo_info_section_units(), isCompileUnit);
- }
+ compile_unit_range dwo_compile_units() {
+ return make_filter_range(dwo_info_section_units(), isCompileUnit);
+ }
- // If you want dwo_type_units(), it'll need to be a concat iterator of a
- // filter of TUs in dwo_info_section + all the (all type) units in
- // dwo_types_section.
+ // If you want dwo_type_units(), it'll need to be a concat iterator of a
+ // filter of TUs in dwo_info_section + all the (all type) units in
+ // dwo_types_section.
/// Get all units in the DWO context.
unit_iterator_range dwo_units() {
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h
index 71e6bc5c41..ca499104dc 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h
@@ -81,24 +81,24 @@ public:
/// Return the full length of this table, including the length field.
/// Return None if the length cannot be identified reliably.
Optional<uint64_t> getFullLength() const;
-
- /// Return the DWARF format of this table.
- dwarf::DwarfFormat getFormat() const { return Format; }
-
- /// Return the length of this table.
- uint64_t getLength() const { return Length; }
-
- /// Return the version of this table.
- uint16_t getVersion() const { return Version; }
-
- /// Return the address size of this table.
- uint8_t getAddressSize() const { return AddrSize; }
-
- /// Return the segment selector size of this table.
- uint8_t getSegmentSelectorSize() const { return SegSize; }
-
- /// Return the parsed addresses of this table.
- ArrayRef<uint64_t> getAddressEntries() const { return Addrs; }
+
+ /// Return the DWARF format of this table.
+ dwarf::DwarfFormat getFormat() const { return Format; }
+
+ /// Return the length of this table.
+ uint64_t getLength() const { return Length; }
+
+ /// Return the version of this table.
+ uint16_t getVersion() const { return Version; }
+
+ /// Return the address size of this table.
+ uint8_t getAddressSize() const { return AddrSize; }
+
+ /// Return the segment selector size of this table.
+ uint8_t getSegmentSelectorSize() const { return SegSize; }
+
+ /// Return the parsed addresses of this table.
+ ArrayRef<uint64_t> getAddressEntries() const { return Addrs; }
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h
index cdd377bf24..01d88a2f24 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h
@@ -67,8 +67,8 @@ public:
DWARFDebugArangeSet() { clear(); }
void clear();
- Error extract(DWARFDataExtractor data, uint64_t *offset_ptr,
- function_ref<void(Error)> WarningHandler);
+ Error extract(DWARFDataExtractor data, uint64_t *offset_ptr,
+ function_ref<void(Error)> WarningHandler);
void dump(raw_ostream &OS) const;
uint64_t getCompileUnitDIEOffset() const { return HeaderData.CuOffset; }
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
index f46f9394de..b5824ba1c9 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
@@ -78,8 +78,8 @@ public:
/// where a problem occurred in case an error is returned.
Error parse(DWARFDataExtractor Data, uint64_t *Offset, uint64_t EndOffset);
- void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI,
- bool IsEH, unsigned IndentLevel = 1) const;
+ void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI,
+ bool IsEH, unsigned IndentLevel = 1) const;
private:
std::vector<Instruction> Instructions;
@@ -128,8 +128,8 @@ private:
static ArrayRef<OperandType[2]> getOperandTypes();
/// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
- void printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
- const MCRegisterInfo *MRI, bool IsEH,
+ void printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
+ const MCRegisterInfo *MRI, bool IsEH,
const Instruction &Instr, unsigned OperandIdx,
uint64_t Operand) const;
};
@@ -154,8 +154,8 @@ public:
CFIProgram &cfis() { return CFIs; }
/// Dump the instructions in this CFI fragment
- virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts,
- const MCRegisterInfo *MRI, bool IsEH) const = 0;
+ virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts,
+ const MCRegisterInfo *MRI, bool IsEH) const = 0;
protected:
const FrameKind Kind;
@@ -209,7 +209,7 @@ public:
uint32_t getLSDAPointerEncoding() const { return LSDAPointerEncoding; }
- void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI,
+ void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI,
bool IsEH) const override;
private:
@@ -250,7 +250,7 @@ public:
uint64_t getAddressRange() const { return AddressRange; }
Optional<uint64_t> getLSDAAddress() const { return LSDAAddress; }
- void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI,
+ void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI,
bool IsEH) const override;
static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_FDE; }
@@ -293,7 +293,7 @@ public:
~DWARFDebugFrame();
/// Dump the section data into the given stream.
- void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI,
+ void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI,
Optional<uint64_t> Offset) const;
/// Parse the section from raw data. \p Data is assumed to contain the whole
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
index 9997a0fae5..d3ef09da62 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
@@ -128,8 +128,8 @@ public:
bool hasFileAtIndex(uint64_t FileIndex) const;
- Optional<uint64_t> getLastValidFileIndex() const;
-
+ Optional<uint64_t> getLastValidFileIndex() const;
+
bool
getFileNameByIndex(uint64_t FileIndex, StringRef CompDir,
DILineInfoSpecifier::FileLineInfoKind Kind,
@@ -260,10 +260,10 @@ public:
return Prologue.hasFileAtIndex(FileIndex);
}
- Optional<uint64_t> getLastValidFileIndex() const {
- return Prologue.getLastValidFileIndex();
- }
-
+ Optional<uint64_t> getLastValidFileIndex() const {
+ return Prologue.getLastValidFileIndex();
+ }
+
/// Extracts filename by its index in filename table in prologue.
/// In Dwarf 4, the files are 1-indexed and the current compilation file
/// name is not represented in the list. In DWARF v5, the files are
@@ -324,8 +324,8 @@ public:
public:
using LineToUnitMap = std::map<uint64_t, DWARFUnit *>;
- SectionParser(DWARFDataExtractor &Data, const DWARFContext &C,
- DWARFUnitVector::iterator_range Units);
+ SectionParser(DWARFDataExtractor &Data, const DWARFContext &C,
+ DWARFUnitVector::iterator_range Units);
/// Get the next line table from the section. Report any issues via the
/// handlers.
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
index 82dc903921..8346f891c2 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
@@ -79,8 +79,8 @@ public:
std::function<Optional<object::SectionedAddress>(uint32_t)> LookupAddr,
function_ref<bool(Expected<DWARFLocationExpression>)> Callback) const;
- const DWARFDataExtractor &getData() { return Data; }
-
+ const DWARFDataExtractor &getData() { return Data; }
+
protected:
DWARFDataExtractor Data;
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
index 1da1ebed67..f731a7f8b3 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
@@ -103,9 +103,9 @@ class DWARFDebugMacro {
MacroHeader Header;
SmallVector<Entry, 4> Macros;
uint64_t Offset;
-
- /// Whether or not this is a .debug_macro section.
- bool IsDebugMacro;
+
+ /// Whether or not this is a .debug_macro section.
+ bool IsDebugMacro;
};
/// A list of all the macro entries in the debug_macinfo section.
@@ -117,7 +117,7 @@ public:
/// Print the macro list found within the debug_macinfo/debug_macro section.
void dump(raw_ostream &OS) const;
- Error parseMacro(DWARFUnitVector::compile_unit_range Units,
+ Error parseMacro(DWARFUnitVector::compile_unit_range Units,
DataExtractor StringExtractor,
DWARFDataExtractor MacroData) {
return parseImpl(Units, StringExtractor, MacroData, /*IsMacro=*/true);
@@ -133,7 +133,7 @@ public:
private:
/// Parse the debug_macinfo/debug_macro section accessible via the 'MacroData'
/// parameter.
- Error parseImpl(Optional<DWARFUnitVector::compile_unit_range> Units,
+ Error parseImpl(Optional<DWARFUnitVector::compile_unit_range> Units,
Optional<DataExtractor> StringExtractor,
DWARFDataExtractor Data, bool IsMacro);
};
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
index fd15c6a097..e2fe8a3953 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
@@ -41,7 +41,7 @@ struct RangeListEntry : public DWARFListEntryBase {
uint64_t Value0;
uint64_t Value1;
- Error extract(DWARFDataExtractor Data, uint64_t *OffsetPtr);
+ Error extract(DWARFDataExtractor Data, uint64_t *OffsetPtr);
void dump(raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength,
uint64_t &CurrentBase, DIDumpOptions DumpOpts,
llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
@@ -55,7 +55,7 @@ public:
/// Build a DWARFAddressRangesVector from a rangelist.
DWARFAddressRangesVector
getAbsoluteRanges(Optional<object::SectionedAddress> BaseAddr,
- uint8_t AddressByteSize,
+ uint8_t AddressByteSize,
function_ref<Optional<object::SectionedAddress>(uint32_t)>
LookupPooledAddress) const;
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDie.h b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDie.h
index 6f656fdd16..e2b027fa8a 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDie.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFDie.h
@@ -269,7 +269,7 @@ public:
/// for this subprogram by resolving DW_AT_sepcification or
/// DW_AT_abstract_origin references if necessary.
uint64_t getDeclLine() const;
- std::string getDeclFile(DILineInfoSpecifier::FileLineInfoKind Kind) const;
+ std::string getDeclFile(DILineInfoSpecifier::FileLineInfoKind Kind) const;
/// Retrieves values of DW_AT_call_file, DW_AT_call_line and DW_AT_call_column
/// from DIE (or zeroes if they are missing). This function looks for
@@ -470,11 +470,11 @@ inline bool operator==(const std::reverse_iterator<DWARFDie::iterator> &LHS,
return LHS.equals(RHS);
}
-inline bool operator!=(const std::reverse_iterator<DWARFDie::iterator> &LHS,
- const std::reverse_iterator<DWARFDie::iterator> &RHS) {
- return !(LHS == RHS);
-}
-
+inline bool operator!=(const std::reverse_iterator<DWARFDie::iterator> &LHS,
+ const std::reverse_iterator<DWARFDie::iterator> &RHS) {
+ return !(LHS == RHS);
+}
+
inline std::reverse_iterator<DWARFDie::iterator> DWARFDie::rbegin() const {
return llvm::make_reverse_iterator(end());
}
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFExpression.h b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFExpression.h
index 46d1843370..3e975179a8 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFExpression.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFExpression.h
@@ -17,11 +17,11 @@
#define LLVM_DEBUGINFO_DWARFEXPRESSION_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/DebugInfo/DIContext.h"
#include "llvm/Support/DataExtractor.h"
namespace llvm {
@@ -101,9 +101,9 @@ public:
bool extract(DataExtractor Data, uint8_t AddressSize, uint64_t Offset,
Optional<dwarf::DwarfFormat> Format);
bool isError() { return Error; }
- bool print(raw_ostream &OS, DIDumpOptions DumpOpts,
- const DWARFExpression *Expr, const MCRegisterInfo *RegInfo,
- DWARFUnit *U, bool isEH);
+ bool print(raw_ostream &OS, DIDumpOptions DumpOpts,
+ const DWARFExpression *Expr, const MCRegisterInfo *RegInfo,
+ DWARFUnit *U, bool isEH);
bool verify(DWARFUnit *U);
};
@@ -152,8 +152,8 @@ public:
iterator begin() const { return iterator(this, 0); }
iterator end() const { return iterator(this, Data.getData().size()); }
- void print(raw_ostream &OS, DIDumpOptions DumpOpts,
- const MCRegisterInfo *RegInfo, DWARFUnit *U,
+ void print(raw_ostream &OS, DIDumpOptions DumpOpts,
+ const MCRegisterInfo *RegInfo, DWARFUnit *U,
bool IsEH = false) const;
/// Print the expression in a format intended to be compact and useful to a
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
index e9c717f64d..87183efe5d 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
@@ -89,9 +89,9 @@ public:
void dump(raw_ostream &OS, DIDumpOptions DumpOpts = DIDumpOptions()) const;
void dumpSectionedAddress(raw_ostream &OS, DIDumpOptions DumpOpts,
object::SectionedAddress SA) const;
- void dumpAddress(raw_ostream &OS, uint64_t Address) const;
- static void dumpAddress(raw_ostream &OS, uint8_t AddressSize,
- uint64_t Address);
+ void dumpAddress(raw_ostream &OS, uint64_t Address) const;
+ static void dumpAddress(raw_ostream &OS, uint8_t AddressSize,
+ uint64_t Address);
static void dumpAddressSection(const DWARFObject &Obj, raw_ostream &OS,
DIDumpOptions DumpOpts, uint64_t SectionIndex);
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFListTable.h b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFListTable.h
index f4f775c4dc..a6a761f5f5 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFListTable.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFListTable.h
@@ -53,7 +53,7 @@ public:
const ListEntries &getEntries() const { return Entries; }
bool empty() const { return Entries.empty(); }
void clear() { Entries.clear(); }
- Error extract(DWARFDataExtractor Data, uint64_t HeaderOffset,
+ Error extract(DWARFDataExtractor Data, uint64_t HeaderOffset,
uint64_t *OffsetPtr, StringRef SectionName,
StringRef ListStringName);
};
@@ -117,25 +117,25 @@ public:
llvm_unreachable("Invalid DWARF format (expected DWARF32 or DWARF64");
}
- void dump(DataExtractor Data, raw_ostream &OS,
- DIDumpOptions DumpOpts = {}) const;
- Optional<uint64_t> getOffsetEntry(DataExtractor Data, uint32_t Index) const {
- if (Index > HeaderData.OffsetEntryCount)
- return None;
-
- return getOffsetEntry(Data, getHeaderOffset() + getHeaderSize(Format), Format, Index);
+ void dump(DataExtractor Data, raw_ostream &OS,
+ DIDumpOptions DumpOpts = {}) const;
+ Optional<uint64_t> getOffsetEntry(DataExtractor Data, uint32_t Index) const {
+ if (Index > HeaderData.OffsetEntryCount)
+ return None;
+
+ return getOffsetEntry(Data, getHeaderOffset() + getHeaderSize(Format), Format, Index);
+ }
+
+ static Optional<uint64_t> getOffsetEntry(DataExtractor Data,
+ uint64_t OffsetTableOffset,
+ dwarf::DwarfFormat Format,
+ uint32_t Index) {
+ uint8_t OffsetByteSize = Format == dwarf::DWARF64 ? 8 : 4;
+ uint64_t Offset = OffsetTableOffset + OffsetByteSize * Index;
+ auto R = Data.getUnsigned(&Offset, OffsetByteSize);
+ return R;
}
- static Optional<uint64_t> getOffsetEntry(DataExtractor Data,
- uint64_t OffsetTableOffset,
- dwarf::DwarfFormat Format,
- uint32_t Index) {
- uint8_t OffsetByteSize = Format == dwarf::DWARF64 ? 8 : 4;
- uint64_t Offset = OffsetTableOffset + OffsetByteSize * Index;
- auto R = Data.getUnsigned(&Offset, OffsetByteSize);
- return R;
- }
-
/// Extract the table header and the array of offsets.
Error extract(DWARFDataExtractor Data, uint64_t *OffsetPtr);
@@ -183,14 +183,14 @@ public:
uint8_t getAddrSize() const { return Header.getAddrSize(); }
dwarf::DwarfFormat getFormat() const { return Header.getFormat(); }
- void dump(DWARFDataExtractor Data, raw_ostream &OS,
+ void dump(DWARFDataExtractor Data, raw_ostream &OS,
llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
LookupPooledAddress,
DIDumpOptions DumpOpts = {}) const;
/// Return the contents of the offset entry designated by a given index.
- Optional<uint64_t> getOffsetEntry(DataExtractor Data, uint32_t Index) const {
- return Header.getOffsetEntry(Data, Index);
+ Optional<uint64_t> getOffsetEntry(DataExtractor Data, uint32_t Index) const {
+ return Header.getOffsetEntry(Data, Index);
}
/// 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
@@ -210,18 +210,18 @@ Error DWARFListTableBase<DWARFListType>::extract(DWARFDataExtractor Data,
return E;
Data.setAddressSize(Header.getAddrSize());
- Data = DWARFDataExtractor(Data, getHeaderOffset() + Header.length());
- while (Data.isValidOffset(*OffsetPtr)) {
+ Data = DWARFDataExtractor(Data, getHeaderOffset() + Header.length());
+ while (Data.isValidOffset(*OffsetPtr)) {
DWARFListType CurrentList;
uint64_t Off = *OffsetPtr;
- if (Error E = CurrentList.extract(Data, getHeaderOffset(), OffsetPtr,
+ if (Error E = CurrentList.extract(Data, getHeaderOffset(), OffsetPtr,
Header.getSectionName(),
Header.getListTypeString()))
return E;
ListMap[Off] = CurrentList;
}
- assert(*OffsetPtr == Data.size() &&
+ assert(*OffsetPtr == Data.size() &&
"mismatch between expected length of table and length "
"of extracted data");
return Error::success();
@@ -229,18 +229,18 @@ Error DWARFListTableBase<DWARFListType>::extract(DWARFDataExtractor Data,
template <typename ListEntryType>
Error DWARFListType<ListEntryType>::extract(DWARFDataExtractor Data,
- uint64_t HeaderOffset,
+ uint64_t HeaderOffset,
uint64_t *OffsetPtr,
StringRef SectionName,
StringRef ListTypeString) {
- if (*OffsetPtr < HeaderOffset || *OffsetPtr >= Data.size())
+ if (*OffsetPtr < HeaderOffset || *OffsetPtr >= Data.size())
return createStringError(errc::invalid_argument,
"invalid %s list offset 0x%" PRIx64,
ListTypeString.data(), *OffsetPtr);
Entries.clear();
- while (Data.isValidOffset(*OffsetPtr)) {
+ while (Data.isValidOffset(*OffsetPtr)) {
ListEntryType Entry;
- if (Error E = Entry.extract(Data, OffsetPtr))
+ if (Error E = Entry.extract(Data, OffsetPtr))
return E;
Entries.push_back(Entry);
if (Entry.isSentinel())
@@ -254,11 +254,11 @@ Error DWARFListType<ListEntryType>::extract(DWARFDataExtractor Data,
template <typename DWARFListType>
void DWARFListTableBase<DWARFListType>::dump(
- DWARFDataExtractor Data, raw_ostream &OS,
+ DWARFDataExtractor Data, raw_ostream &OS,
llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
LookupPooledAddress,
DIDumpOptions DumpOpts) const {
- Header.dump(Data, OS, DumpOpts);
+ Header.dump(Data, OS, DumpOpts);
OS << HeaderString << "\n";
// Determine the length of the longest encoding string we have in the table,
@@ -285,10 +285,10 @@ DWARFListTableBase<DWARFListType>::findList(DWARFDataExtractor Data,
uint64_t Offset) {
// Extract the list from the section and enter it into the list map.
DWARFListType List;
- if (Header.length())
- Data = DWARFDataExtractor(Data, getHeaderOffset() + Header.length());
+ if (Header.length())
+ Data = DWARFDataExtractor(Data, getHeaderOffset() + Header.length());
if (Error E =
- List.extract(Data, Header.length() ? getHeaderOffset() : 0, &Offset,
+ List.extract(Data, Header.length() ? getHeaderOffset() : 0, &Offset,
Header.getSectionName(), Header.getListTypeString()))
return std::move(E);
return List;
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index e519fa7185..e8d37922b7 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -120,8 +120,8 @@ public:
const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
DWARFSectionKind Kind);
-bool isCompileUnit(const std::unique_ptr<DWARFUnit> &U);
-
+bool isCompileUnit(const std::unique_ptr<DWARFUnit> &U);
+
/// Describe a collection of units. Intended to hold all units either from
/// .debug_info and .debug_types, or from .debug_info.dwo and .debug_types.dwo.
class DWARFUnitVector final : public SmallVector<std::unique_ptr<DWARFUnit>, 1> {
@@ -136,9 +136,9 @@ public:
using iterator = typename UnitVector::iterator;
using iterator_range = llvm::iterator_range<typename UnitVector::iterator>;
- using compile_unit_range =
- decltype(make_filter_range(std::declval<iterator_range>(), isCompileUnit));
-
+ using compile_unit_range =
+ decltype(make_filter_range(std::declval<iterator_range>(), isCompileUnit));
+
DWARFUnit *getUnitForOffset(uint64_t Offset) const;
DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E);
@@ -301,7 +301,7 @@ public:
dwarf::DwarfFormat getFormat() const { return Header.getFormat(); }
uint8_t getUnitType() const { return Header.getUnitType(); }
bool isTypeUnit() const { return Header.isTypeUnit(); }
- uint64_t getAbbrOffset() const { return Header.getAbbrOffset(); }
+ uint64_t getAbbrOffset() const { return Header.getAbbrOffset(); }
uint64_t getNextUnitOffset() const { return Header.getNextUnitOffset(); }
const DWARFSection &getLineSection() const { return LineSection; }
StringRef getStringSection() const { return StringSection; }
@@ -415,10 +415,10 @@ public:
/// 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<uint64_t> getRnglistOffset(uint32_t Index);
+ Optional<uint64_t> getRnglistOffset(uint32_t Index);
+
+ Optional<uint64_t> getLoclistOffset(uint32_t Index);
- Optional<uint64_t> getLoclistOffset(uint32_t Index);
-
Expected<DWARFAddressRangesVector> collectAddressRanges();
Expected<DWARFLocationExpressionsVector>
@@ -521,10 +521,10 @@ private:
bool parseDWO();
};
-inline bool isCompileUnit(const std::unique_ptr<DWARFUnit> &U) {
- return !U->isTypeUnit();
-}
-
+inline bool isCompileUnit(const std::unique_ptr<DWARFUnit> &U) {
+ return !U->isTypeUnit();
+}
+
} // end namespace llvm
#endif // LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFVerifier.h b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
index 6071eb8a63..2bc2b954c1 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
@@ -27,14 +27,14 @@
namespace llvm {
class raw_ostream;
-struct DWARFAddressRange;
+struct DWARFAddressRange;
struct DWARFAttribute;
class DWARFContext;
class DWARFDataExtractor;
class DWARFDebugAbbrev;
class DataExtractor;
struct DWARFSection;
-class DWARFUnit;
+class DWARFUnit;
/// A class that verifies DWARF debug information given a DWARF Context.
class DWARFVerifier {
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/DIA/DIASession.h b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/DIA/DIASession.h
index 0452ab767a..48b167843f 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/DIA/DIASession.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/DIA/DIASession.h
@@ -1,104 +1,104 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- DIASession.h - DIA implementation of IPDBSession ---------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_PDB_DIA_DIASESSION_H
-#define LLVM_DEBUGINFO_PDB_DIA_DIASESSION_H
-
-#include "DIASupport.h"
-#include "llvm/DebugInfo/PDB/IPDBSession.h"
-#include "llvm/Support/Error.h"
-
-#include <system_error>
-
-namespace llvm {
-class StringRef;
-
-namespace pdb {
-class DIASession : public IPDBSession {
-public:
- explicit DIASession(CComPtr<IDiaSession> DiaSession);
-
- static Error createFromPdb(StringRef Path,
- std::unique_ptr<IPDBSession> &Session);
- static Error createFromExe(StringRef Path,
- std::unique_ptr<IPDBSession> &Session);
-
- uint64_t getLoadAddress() const override;
- bool setLoadAddress(uint64_t Address) override;
- std::unique_ptr<PDBSymbolExe> getGlobalScope() override;
- std::unique_ptr<PDBSymbol> getSymbolById(SymIndexId SymbolId) const override;
-
- bool addressForVA(uint64_t VA, uint32_t &Section,
- uint32_t &Offset) const override;
- bool addressForRVA(uint32_t RVA, uint32_t &Section,
- uint32_t &Offset) const override;
-
- std::unique_ptr<PDBSymbol> findSymbolByAddress(uint64_t Address,
- PDB_SymType Type) override;
- std::unique_ptr<PDBSymbol> findSymbolByRVA(uint32_t RVA,
- PDB_SymType Type) override;
- std::unique_ptr<PDBSymbol> findSymbolBySectOffset(uint32_t Section,
- uint32_t Offset,
- PDB_SymType Type) override;
-
- std::unique_ptr<IPDBEnumLineNumbers>
- findLineNumbers(const PDBSymbolCompiland &Compiland,
- const IPDBSourceFile &File) const override;
- std::unique_ptr<IPDBEnumLineNumbers>
- findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override;
- std::unique_ptr<IPDBEnumLineNumbers>
- findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const override;
- std::unique_ptr<IPDBEnumLineNumbers>
- findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset,
- uint32_t Length) const override;
-
- std::unique_ptr<IPDBEnumSourceFiles>
- findSourceFiles(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern,
- PDB_NameSearchFlags Flags) const override;
- std::unique_ptr<IPDBSourceFile>
- findOneSourceFile(const PDBSymbolCompiland *Compiland,
- llvm::StringRef Pattern,
- PDB_NameSearchFlags Flags) const override;
- std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
- findCompilandsForSourceFile(llvm::StringRef Pattern,
- PDB_NameSearchFlags Flags) const override;
- std::unique_ptr<PDBSymbolCompiland>
- findOneCompilandForSourceFile(llvm::StringRef Pattern,
- PDB_NameSearchFlags Flags) const override;
- std::unique_ptr<IPDBEnumSourceFiles> getAllSourceFiles() const override;
- std::unique_ptr<IPDBEnumSourceFiles> getSourceFilesForCompiland(
- const PDBSymbolCompiland &Compiland) const override;
- std::unique_ptr<IPDBSourceFile>
- getSourceFileById(uint32_t FileId) const override;
-
- std::unique_ptr<IPDBEnumDataStreams> getDebugStreams() const override;
-
- std::unique_ptr<IPDBEnumTables> getEnumTables() const override;
-
- std::unique_ptr<IPDBEnumInjectedSources> getInjectedSources() const override;
-
- std::unique_ptr<IPDBEnumSectionContribs> getSectionContribs() const override;
-
- std::unique_ptr<IPDBEnumFrameData> getFrameData() const override;
-private:
- CComPtr<IDiaSession> Session;
-};
-} // namespace pdb
-} // namespace llvm
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- DIASession.h - DIA implementation of IPDBSession ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_DIA_DIASESSION_H
+#define LLVM_DEBUGINFO_PDB_DIA_DIASESSION_H
+
+#include "DIASupport.h"
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/Support/Error.h"
+
+#include <system_error>
+
+namespace llvm {
+class StringRef;
+
+namespace pdb {
+class DIASession : public IPDBSession {
+public:
+ explicit DIASession(CComPtr<IDiaSession> DiaSession);
+
+ static Error createFromPdb(StringRef Path,
+ std::unique_ptr<IPDBSession> &Session);
+ static Error createFromExe(StringRef Path,
+ std::unique_ptr<IPDBSession> &Session);
+
+ uint64_t getLoadAddress() const override;
+ bool setLoadAddress(uint64_t Address) override;
+ std::unique_ptr<PDBSymbolExe> getGlobalScope() override;
+ std::unique_ptr<PDBSymbol> getSymbolById(SymIndexId SymbolId) const override;
+
+ bool addressForVA(uint64_t VA, uint32_t &Section,
+ uint32_t &Offset) const override;
+ bool addressForRVA(uint32_t RVA, uint32_t &Section,
+ uint32_t &Offset) const override;
+
+ std::unique_ptr<PDBSymbol> findSymbolByAddress(uint64_t Address,
+ PDB_SymType Type) override;
+ std::unique_ptr<PDBSymbol> findSymbolByRVA(uint32_t RVA,
+ PDB_SymType Type) override;
+ std::unique_ptr<PDBSymbol> findSymbolBySectOffset(uint32_t Section,
+ uint32_t Offset,
+ PDB_SymType Type) override;
+
+ std::unique_ptr<IPDBEnumLineNumbers>
+ findLineNumbers(const PDBSymbolCompiland &Compiland,
+ const IPDBSourceFile &File) const override;
+ std::unique_ptr<IPDBEnumLineNumbers>
+ findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override;
+ std::unique_ptr<IPDBEnumLineNumbers>
+ findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const override;
+ std::unique_ptr<IPDBEnumLineNumbers>
+ findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset,
+ uint32_t Length) const override;
+
+ std::unique_ptr<IPDBEnumSourceFiles>
+ findSourceFiles(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern,
+ PDB_NameSearchFlags Flags) const override;
+ std::unique_ptr<IPDBSourceFile>
+ findOneSourceFile(const PDBSymbolCompiland *Compiland,
+ llvm::StringRef Pattern,
+ PDB_NameSearchFlags Flags) const override;
+ std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
+ findCompilandsForSourceFile(llvm::StringRef Pattern,
+ PDB_NameSearchFlags Flags) const override;
+ std::unique_ptr<PDBSymbolCompiland>
+ findOneCompilandForSourceFile(llvm::StringRef Pattern,
+ PDB_NameSearchFlags Flags) const override;
+ std::unique_ptr<IPDBEnumSourceFiles> getAllSourceFiles() const override;
+ std::unique_ptr<IPDBEnumSourceFiles> getSourceFilesForCompiland(
+ const PDBSymbolCompiland &Compiland) const override;
+ std::unique_ptr<IPDBSourceFile>
+ getSourceFileById(uint32_t FileId) const override;
+
+ std::unique_ptr<IPDBEnumDataStreams> getDebugStreams() const override;
+
+ std::unique_ptr<IPDBEnumTables> getEnumTables() const override;
+
+ std::unique_ptr<IPDBEnumInjectedSources> getInjectedSources() const override;
+
+ std::unique_ptr<IPDBEnumSectionContribs> getSectionContribs() const override;
+
+ std::unique_ptr<IPDBEnumFrameData> getFrameData() const override;
+private:
+ CComPtr<IDiaSession> Session;
+};
+} // namespace pdb
+} // namespace llvm
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
index 52147c36fa..3b3598fc27 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
@@ -41,34 +41,34 @@ struct MSFLayout;
}
namespace pdb {
-// Represents merged or unmerged symbols. Merged symbols can be written to the
-// output file as is, but unmerged symbols must be rewritten first. In either
-// case, the size must be known up front.
-struct SymbolListWrapper {
- explicit SymbolListWrapper(ArrayRef<uint8_t> Syms)
- : SymPtr(const_cast<uint8_t *>(Syms.data())), SymSize(Syms.size()),
- NeedsToBeMerged(false) {}
- explicit SymbolListWrapper(void *SymSrc, uint32_t Length)
- : SymPtr(SymSrc), SymSize(Length), NeedsToBeMerged(true) {}
-
- ArrayRef<uint8_t> asArray() const {
- return ArrayRef<uint8_t>(static_cast<const uint8_t *>(SymPtr), SymSize);
- }
-
- uint32_t size() const { return SymSize; }
-
- void *SymPtr = nullptr;
- uint32_t SymSize = 0;
- bool NeedsToBeMerged = false;
-};
-
-/// Represents a string table reference at some offset in the module symbol
-/// stream.
-struct StringTableFixup {
- uint32_t StrTabOffset = 0;
- uint32_t SymOffsetOfReference = 0;
-};
-
+// Represents merged or unmerged symbols. Merged symbols can be written to the
+// output file as is, but unmerged symbols must be rewritten first. In either
+// case, the size must be known up front.
+struct SymbolListWrapper {
+ explicit SymbolListWrapper(ArrayRef<uint8_t> Syms)
+ : SymPtr(const_cast<uint8_t *>(Syms.data())), SymSize(Syms.size()),
+ NeedsToBeMerged(false) {}
+ explicit SymbolListWrapper(void *SymSrc, uint32_t Length)
+ : SymPtr(SymSrc), SymSize(Length), NeedsToBeMerged(true) {}
+
+ ArrayRef<uint8_t> asArray() const {
+ return ArrayRef<uint8_t>(static_cast<const uint8_t *>(SymPtr), SymSize);
+ }
+
+ uint32_t size() const { return SymSize; }
+
+ void *SymPtr = nullptr;
+ uint32_t SymSize = 0;
+ bool NeedsToBeMerged = false;
+};
+
+/// Represents a string table reference at some offset in the module symbol
+/// stream.
+struct StringTableFixup {
+ uint32_t StrTabOffset = 0;
+ uint32_t SymOffsetOfReference = 0;
+};
+
class DbiModuleDescriptorBuilder {
friend class DbiStreamBuilder;
@@ -83,28 +83,28 @@ public:
void setPdbFilePathNI(uint32_t NI);
void setObjFileName(StringRef Name);
-
- // Callback to merge one source of unmerged symbols.
- using MergeSymbolsCallback = Error (*)(void *Ctx, void *Symbols,
- BinaryStreamWriter &Writer);
-
- void setMergeSymbolsCallback(void *Ctx, MergeSymbolsCallback Callback) {
- MergeSymsCtx = Ctx;
- MergeSymsCallback = Callback;
- }
-
- void setStringTableFixups(std::vector<StringTableFixup> &&Fixups) {
- StringTableFixups = std::move(Fixups);
- }
-
+
+ // Callback to merge one source of unmerged symbols.
+ using MergeSymbolsCallback = Error (*)(void *Ctx, void *Symbols,
+ BinaryStreamWriter &Writer);
+
+ void setMergeSymbolsCallback(void *Ctx, MergeSymbolsCallback Callback) {
+ MergeSymsCtx = Ctx;
+ MergeSymsCallback = Callback;
+ }
+
+ void setStringTableFixups(std::vector<StringTableFixup> &&Fixups) {
+ StringTableFixups = std::move(Fixups);
+ }
+
void setFirstSectionContrib(const SectionContrib &SC);
void addSymbol(codeview::CVSymbol Symbol);
void addSymbolsInBulk(ArrayRef<uint8_t> BulkSymbols);
- // Add symbols of known size which will be merged (rewritten) when committing
- // the PDB to disk.
- void addUnmergedSymbols(void *SymSrc, uint32_t SymLength);
-
+ // Add symbols of known size which will be merged (rewritten) when committing
+ // the PDB to disk.
+ void addUnmergedSymbols(void *SymSrc, uint32_t SymLength);
+
void
addDebugSubsection(std::shared_ptr<codeview::DebugSubsection> Subsection);
@@ -130,15 +130,15 @@ public:
void finalize();
Error finalizeMsfLayout();
- /// Commit the DBI descriptor to the DBI stream.
- Error commit(BinaryStreamWriter &ModiWriter);
+ /// Commit the DBI descriptor to the DBI stream.
+ Error commit(BinaryStreamWriter &ModiWriter);
+
+ /// Commit the accumulated symbols to the module symbol stream. Safe to call
+ /// in parallel on different DbiModuleDescriptorBuilder objects. Only modifies
+ /// the pre-allocated stream in question.
+ Error commitSymbolStream(const msf::MSFLayout &MsfLayout,
+ WritableBinaryStreamRef MsfBuffer);
- /// Commit the accumulated symbols to the module symbol stream. Safe to call
- /// in parallel on different DbiModuleDescriptorBuilder objects. Only modifies
- /// the pre-allocated stream in question.
- Error commitSymbolStream(const msf::MSFLayout &MsfLayout,
- WritableBinaryStreamRef MsfBuffer);
-
private:
uint32_t calculateC13DebugInfoSize() const;
@@ -150,13 +150,13 @@ private:
std::string ModuleName;
std::string ObjFileName;
std::vector<std::string> SourceFiles;
- std::vector<SymbolListWrapper> Symbols;
+ std::vector<SymbolListWrapper> Symbols;
+
+ void *MergeSymsCtx = nullptr;
+ MergeSymbolsCallback MergeSymsCallback = nullptr;
+
+ std::vector<StringTableFixup> StringTableFixups;
- void *MergeSymsCtx = nullptr;
- MergeSymbolsCallback MergeSymsCallback = nullptr;
-
- std::vector<StringTableFixup> StringTableFixups;
-
std::vector<codeview::DebugSubsectionRecordBuilder> C13Builders;
ModuleInfoHeader Layout;
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h
index 76de64f03c..54e3b02876 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h
@@ -1,52 +1,52 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//==- NativeEnumSymbols.h - Native Symbols Enumerator impl -------*- C++ -*-==//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMSYMBOLS_H
-#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMSYMBOLS_H
-
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <vector>
-
-namespace llvm {
-namespace pdb {
-
-class NativeSession;
-
-class NativeEnumSymbols : public IPDBEnumChildren<PDBSymbol> {
-public:
- NativeEnumSymbols(NativeSession &Session, std::vector<SymIndexId> Symbols);
-
- uint32_t getChildCount() const override;
- std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override;
- std::unique_ptr<PDBSymbol> getNext() override;
- void reset() override;
-
-private:
- std::vector<SymIndexId> Symbols;
- uint32_t Index;
- NativeSession &Session;
-};
-
-} // namespace pdb
-} // namespace llvm
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//==- NativeEnumSymbols.h - Native Symbols Enumerator impl -------*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMSYMBOLS_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMSYMBOLS_H
+
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+#include <vector>
+
+namespace llvm {
+namespace pdb {
+
+class NativeSession;
+
+class NativeEnumSymbols : public IPDBEnumChildren<PDBSymbol> {
+public:
+ NativeEnumSymbols(NativeSession &Session, std::vector<SymIndexId> Symbols);
+
+ uint32_t getChildCount() const override;
+ std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override;
+ std::unique_ptr<PDBSymbol> getNext() override;
+ void reset() override;
+
+private:
+ std::vector<SymIndexId> Symbols;
+ uint32_t Index;
+ NativeSession &Session;
+};
+
+} // namespace pdb
+} // namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h
index aa2fa7cea3..cb9599004e 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h
@@ -27,7 +27,7 @@ namespace pdb {
class NativeFunctionSymbol : public NativeRawSymbol {
public:
NativeFunctionSymbol(NativeSession &Session, SymIndexId Id,
- const codeview::ProcSym &Sym, uint32_t RecordOffset);
+ const codeview::ProcSym &Sym, uint32_t RecordOffset);
~NativeFunctionSymbol() override;
@@ -40,12 +40,12 @@ public:
uint64_t getLength() const override;
uint32_t getRelativeVirtualAddress() const override;
uint64_t getVirtualAddress() const override;
- std::unique_ptr<IPDBEnumSymbols>
- findInlineFramesByVA(uint64_t VA) const override;
+ std::unique_ptr<IPDBEnumSymbols>
+ findInlineFramesByVA(uint64_t VA) const override;
protected:
const codeview::ProcSym Sym;
- uint32_t RecordOffset = 0;
+ uint32_t RecordOffset = 0;
};
} // namespace pdb
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeInlineSiteSymbol.h b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeInlineSiteSymbol.h
index 8c70920066..1cc64ca303 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeInlineSiteSymbol.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeInlineSiteSymbol.h
@@ -1,57 +1,57 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- NativeInlineSiteSymbol.h - info about inline sites -------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEINLINESITESYMBOL_H
-#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEINLINESITESYMBOL_H
-
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
-#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
-
-namespace llvm {
-namespace pdb {
-
-class NativeInlineSiteSymbol : public NativeRawSymbol {
-public:
- NativeInlineSiteSymbol(NativeSession &Session, SymIndexId Id,
- const codeview::InlineSiteSym &Sym,
- uint64_t ParentAddr);
-
- ~NativeInlineSiteSymbol() override;
-
- void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields,
- PdbSymbolIdField RecurseIdFields) const override;
-
- std::string getName() const override;
- std::unique_ptr<IPDBEnumLineNumbers>
- findInlineeLinesByVA(uint64_t VA, uint32_t Length) const override;
-
-private:
- const codeview::InlineSiteSym Sym;
- uint64_t ParentAddr;
-
- void getLineOffset(uint32_t OffsetInFunc, uint32_t &LineOffset,
- uint32_t &FileOffset) const;
-};
-
-} // namespace pdb
-} // namespace llvm
-
-#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVEINLINESITESYMBOL_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- NativeInlineSiteSymbol.h - info about inline sites -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEINLINESITESYMBOL_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEINLINESITESYMBOL_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+
+namespace llvm {
+namespace pdb {
+
+class NativeInlineSiteSymbol : public NativeRawSymbol {
+public:
+ NativeInlineSiteSymbol(NativeSession &Session, SymIndexId Id,
+ const codeview::InlineSiteSym &Sym,
+ uint64_t ParentAddr);
+
+ ~NativeInlineSiteSymbol() override;
+
+ void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const override;
+
+ std::string getName() const override;
+ std::unique_ptr<IPDBEnumLineNumbers>
+ findInlineeLinesByVA(uint64_t VA, uint32_t Length) const override;
+
+private:
+ const codeview::InlineSiteSym Sym;
+ uint64_t ParentAddr;
+
+ void getLineOffset(uint32_t OffsetInFunc, uint32_t &LineOffset,
+ uint32_t &FileOffset) const;
+};
+
+} // namespace pdb
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVEINLINESITESYMBOL_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h
index b6c58baee9..f9bd5157ed 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h
@@ -29,7 +29,7 @@ public:
const codeview::LineInfo Line,
uint32_t ColumnNumber, uint32_t Length,
uint32_t Section, uint32_t Offset,
- uint32_t SrcFileId, uint32_t CompilandId);
+ uint32_t SrcFileId, uint32_t CompilandId);
uint32_t getLineNumber() const override;
uint32_t getLineNumberEnd() const override;
@@ -52,7 +52,7 @@ private:
uint32_t Offset;
uint32_t Length;
uint32_t SrcFileId;
- uint32_t CompilandId;
+ uint32_t CompilandId;
};
} // namespace pdb
} // namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeSession.h b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeSession.h
index 5033c58150..37222ba4bf 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeSession.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/NativeSession.h
@@ -117,14 +117,14 @@ public:
const SymbolCache &getSymbolCache() const { return Cache; }
uint32_t getRVAFromSectOffset(uint32_t Section, uint32_t Offset) const;
uint64_t getVAFromSectOffset(uint32_t Section, uint32_t Offset) const;
- bool moduleIndexForVA(uint64_t VA, uint16_t &ModuleIndex) const;
- bool moduleIndexForSectOffset(uint32_t Sect, uint32_t Offset,
- uint16_t &ModuleIndex) const;
- Expected<ModuleDebugStreamRef> getModuleDebugStream(uint32_t Index) const;
+ bool moduleIndexForVA(uint64_t VA, uint16_t &ModuleIndex) const;
+ bool moduleIndexForSectOffset(uint32_t Sect, uint32_t Offset,
+ uint16_t &ModuleIndex) const;
+ Expected<ModuleDebugStreamRef> getModuleDebugStream(uint32_t Index) const;
private:
void initializeExeSymbol();
- void parseSectionContribs();
+ void parseSectionContribs();
std::unique_ptr<PDBFile> Pdb;
std::unique_ptr<BumpPtrAllocator> Allocator;
@@ -132,12 +132,12 @@ private:
SymbolCache Cache;
SymIndexId ExeSymbol = 0;
uint64_t LoadAddress = 0;
-
- /// Map from virtual address to module index.
- using IMap =
- IntervalMap<uint64_t, uint16_t, 8, IntervalMapHalfOpenInfo<uint64_t>>;
- IMap::Allocator IMapAllocator;
- IMap AddrToModuleIndex;
+
+ /// Map from virtual address to module index.
+ using IMap =
+ IntervalMap<uint64_t, uint16_t, 8, IntervalMapHalfOpenInfo<uint64_t>>;
+ IMap::Allocator IMapAllocator;
+ IMap AddrToModuleIndex;
};
} // namespace pdb
} // namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/SymbolCache.h b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
index b9ae7930d9..730142f3c7 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
@@ -44,40 +44,40 @@ class SymbolCache {
/// an Id. Id allocation is an implementation, with the only guarantee
/// being that once an Id is allocated, the symbol can be assumed to be
/// cached.
- mutable std::vector<std::unique_ptr<NativeRawSymbol>> Cache;
+ mutable std::vector<std::unique_ptr<NativeRawSymbol>> Cache;
/// For type records from the TPI stream which have been paresd and cached,
/// stores a mapping to SymIndexId of the cached symbol.
- mutable DenseMap<codeview::TypeIndex, SymIndexId> TypeIndexToSymbolId;
+ mutable DenseMap<codeview::TypeIndex, SymIndexId> TypeIndexToSymbolId;
/// For field list members which have been parsed and cached, stores a mapping
/// from (IndexOfClass, MemberIndex) to the corresponding SymIndexId of the
/// cached symbol.
- mutable DenseMap<std::pair<codeview::TypeIndex, uint32_t>, SymIndexId>
+ mutable DenseMap<std::pair<codeview::TypeIndex, uint32_t>, SymIndexId>
FieldListMembersToSymbolId;
/// List of SymIndexIds for each compiland, indexed by compiland index as they
/// appear in the PDB file.
- mutable std::vector<SymIndexId> Compilands;
+ mutable std::vector<SymIndexId> Compilands;
/// List of source files, indexed by unique source file index.
mutable std::vector<std::unique_ptr<NativeSourceFile>> SourceFiles;
-
- /// Map from string table offset to source file Id.
+
+ /// Map from string table offset to source file Id.
mutable DenseMap<uint32_t, SymIndexId> FileNameOffsetToId;
/// Map from global symbol offset to SymIndexId.
- mutable DenseMap<uint32_t, SymIndexId> GlobalOffsetToSymbolId;
+ mutable DenseMap<uint32_t, SymIndexId> GlobalOffsetToSymbolId;
- /// Map from segment and code offset to function symbols.
- mutable DenseMap<std::pair<uint32_t, uint32_t>, SymIndexId> AddressToSymbolId;
- /// Map from segment and code offset to public symbols.
- mutable DenseMap<std::pair<uint32_t, uint32_t>, SymIndexId>
- AddressToPublicSymId;
+ /// Map from segment and code offset to function symbols.
+ mutable DenseMap<std::pair<uint32_t, uint32_t>, SymIndexId> AddressToSymbolId;
+ /// Map from segment and code offset to public symbols.
+ mutable DenseMap<std::pair<uint32_t, uint32_t>, SymIndexId>
+ AddressToPublicSymId;
- /// Map from module index and symbol table offset to SymIndexId.
- mutable DenseMap<std::pair<uint16_t, uint32_t>, SymIndexId>
- SymTabOffsetToSymbolId;
+ /// Map from module index and symbol table offset to SymIndexId.
+ mutable DenseMap<std::pair<uint16_t, uint32_t>, SymIndexId>
+ SymTabOffsetToSymbolId;
struct LineTableEntry {
uint64_t Addr;
@@ -90,7 +90,7 @@ class SymbolCache {
std::vector<LineTableEntry> findLineTable(uint16_t Modi) const;
mutable DenseMap<uint16_t, std::vector<LineTableEntry>> LineTable;
- SymIndexId createSymbolPlaceholder() const {
+ SymIndexId createSymbolPlaceholder() const {
SymIndexId Id = Cache.size();
Cache.push_back(nullptr);
return Id;
@@ -98,7 +98,7 @@ class SymbolCache {
template <typename ConcreteSymbolT, typename CVRecordT, typename... Args>
SymIndexId createSymbolForType(codeview::TypeIndex TI, codeview::CVType CVT,
- Args &&...ConstructorArgs) const {
+ Args &&...ConstructorArgs) const {
CVRecordT Record;
if (auto EC =
codeview::TypeDeserializer::deserializeAs<CVRecordT>(CVT, Record)) {
@@ -111,10 +111,10 @@ class SymbolCache {
}
SymIndexId createSymbolForModifiedType(codeview::TypeIndex ModifierTI,
- codeview::CVType CVT) const;
+ codeview::CVType CVT) const;
SymIndexId createSimpleType(codeview::TypeIndex TI,
- codeview::ModifierOptions Mods) const;
+ codeview::ModifierOptions Mods) const;
std::unique_ptr<PDBSymbol> findFunctionSymbolBySectOffset(uint32_t Sect,
uint32_t Offset);
@@ -125,7 +125,7 @@ public:
SymbolCache(NativeSession &Session, DbiStream *Dbi);
template <typename ConcreteSymbolT, typename... Args>
- SymIndexId createSymbol(Args &&...ConstructorArgs) const {
+ SymIndexId createSymbol(Args &&...ConstructorArgs) const {
SymIndexId Id = Cache.size();
// Initial construction must not access the cache, since it must be done
@@ -152,7 +152,7 @@ public:
std::unique_ptr<IPDBEnumSymbols>
createGlobalsEnumerator(codeview::SymbolKind Kind);
- SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI) const;
+ SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI) const;
template <typename ConcreteSymbolT, typename... Args>
SymIndexId getOrCreateFieldListMember(codeview::TypeIndex FieldListTI,
@@ -170,9 +170,9 @@ public:
}
SymIndexId getOrCreateGlobalSymbolByOffset(uint32_t Offset);
- SymIndexId getOrCreateInlineSymbol(codeview::InlineSiteSym Sym,
- uint64_t ParentAddr, uint16_t Modi,
- uint32_t RecordOffset) const;
+ SymIndexId getOrCreateInlineSymbol(codeview::InlineSiteSym Sym,
+ uint64_t ParentAddr, uint16_t Modi,
+ uint32_t RecordOffset) const;
std::unique_ptr<PDBSymbol>
findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, PDB_SymType Type);
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/TpiStream.h b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/TpiStream.h
index 8fa7b01ef0..4b2d9854a8 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/TpiStream.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/TpiStream.h
@@ -16,7 +16,7 @@
#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBTPISTREAM_H
#define LLVM_DEBUGINFO_PDB_RAW_PDBTPISTREAM_H
-#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/PDB/Native/HashTable.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h
index deb0032172..8cfb4ff501 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h
@@ -61,20 +61,20 @@ public:
void setVersionHeader(PdbRaw_TpiVer Version);
void addTypeRecord(ArrayRef<uint8_t> Type, Optional<uint32_t> Hash);
- void addTypeRecords(ArrayRef<uint8_t> Types, ArrayRef<uint16_t> Sizes,
- ArrayRef<uint32_t> Hashes);
+ void addTypeRecords(ArrayRef<uint8_t> Types, ArrayRef<uint16_t> Sizes,
+ ArrayRef<uint32_t> Hashes);
Error finalizeMsfLayout();
- uint32_t getRecordCount() const { return TypeRecordCount; }
+ uint32_t getRecordCount() const { return TypeRecordCount; }
Error commit(const msf::MSFLayout &Layout, WritableBinaryStreamRef Buffer);
uint32_t calculateSerializedLength();
private:
- void updateTypeIndexOffsets(ArrayRef<uint16_t> Sizes);
-
+ void updateTypeIndexOffsets(ArrayRef<uint16_t> Sizes);
+
uint32_t calculateHashBufferSize() const;
uint32_t calculateIndexOffsetSize() const;
Error finalize();
@@ -82,11 +82,11 @@ private:
msf::MSFBuilder &Msf;
BumpPtrAllocator &Allocator;
- uint32_t TypeRecordCount = 0;
+ uint32_t TypeRecordCount = 0;
size_t TypeRecordBytes = 0;
PdbRaw_TpiVer VerHeader = PdbRaw_TpiVer::PdbTpiV80;
- std::vector<ArrayRef<uint8_t>> TypeRecBuffers;
+ std::vector<ArrayRef<uint8_t>> TypeRecBuffers;
std::vector<uint32_t> TypeHashes;
std::vector<codeview::TypeIndexOffset> TypeIndexOffsets;
uint32_t HashStreamIndex = kInvalidStreamIndex;
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/PDBExtras.h b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/PDBExtras.h
index 52b91b1fd2..7b5e4b5de2 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/PDBExtras.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/PDBExtras.h
@@ -16,11 +16,11 @@
#ifndef LLVM_DEBUGINFO_PDB_PDBEXTRAS_H
#define LLVM_DEBUGINFO_PDB_PDBEXTRAS_H
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
#include "llvm/Support/raw_ostream.h"
-#include <cstdint>
+#include <cstdint>
#include <unordered_map>
namespace llvm {
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/PDBSymbol.h b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/PDBSymbol.h
index ced7157701..1154cc660b 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/PDBSymbol.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/PDB/PDBSymbol.h
@@ -147,15 +147,15 @@ public:
StringRef Name,
PDB_NameSearchFlags Flags,
uint32_t RVA) const;
- std::unique_ptr<IPDBEnumSymbols> findInlineFramesByVA(uint64_t VA) const;
+ std::unique_ptr<IPDBEnumSymbols> findInlineFramesByVA(uint64_t VA) const;
std::unique_ptr<IPDBEnumSymbols> findInlineFramesByRVA(uint32_t RVA) const;
- std::unique_ptr<IPDBEnumLineNumbers>
- findInlineeLinesByVA(uint64_t VA, uint32_t Length) const;
- std::unique_ptr<IPDBEnumLineNumbers>
- findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const;
+ std::unique_ptr<IPDBEnumLineNumbers>
+ findInlineeLinesByVA(uint64_t VA, uint32_t Length) const;
+ std::unique_ptr<IPDBEnumLineNumbers>
+ findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const;
+
+ std::string getName() const;
- std::string getName() const;
-
const IPDBRawSymbol &getRawSymbol() const { return *RawSymbol; }
IPDBRawSymbol &getRawSymbol() { return *RawSymbol; }
diff --git a/contrib/libs/llvm12/include/llvm/DebugInfo/Symbolize/Symbolize.h b/contrib/libs/llvm12/include/llvm/DebugInfo/Symbolize/Symbolize.h
index 503addbf68..d141990421 100644
--- a/contrib/libs/llvm12/include/llvm/DebugInfo/Symbolize/Symbolize.h
+++ b/contrib/libs/llvm12/include/llvm/DebugInfo/Symbolize/Symbolize.h
@@ -50,7 +50,7 @@ public:
bool Demangle = true;
bool RelativeAddresses = false;
bool UntagAddresses = false;
- bool UseDIA = false;
+ bool UseDIA = false;
std::string DefaultArch;
std::vector<std::string> DsymHints;
std::string FallbackDebugPath;
diff --git a/contrib/libs/llvm12/include/llvm/Demangle/ItaniumDemangle.h b/contrib/libs/llvm12/include/llvm/Demangle/ItaniumDemangle.h
index da87cd2d14..09d4e42b85 100644
--- a/contrib/libs/llvm12/include/llvm/Demangle/ItaniumDemangle.h
+++ b/contrib/libs/llvm12/include/llvm/Demangle/ItaniumDemangle.h
@@ -89,7 +89,7 @@
X(PostfixExpr) \
X(ConditionalExpr) \
X(MemberExpr) \
- X(SubobjectExpr) \
+ X(SubobjectExpr) \
X(EnclosingExpr) \
X(CastExpr) \
X(SizeofParamPackExpr) \
@@ -99,7 +99,7 @@
X(PrefixExpr) \
X(FunctionParam) \
X(ConversionExpr) \
- X(PointerToMemberConversionExpr) \
+ X(PointerToMemberConversionExpr) \
X(InitListExpr) \
X(FoldExpr) \
X(ThrowExpr) \
@@ -1671,40 +1671,40 @@ public:
}
};
-class SubobjectExpr : public Node {
- const Node *Type;
- const Node *SubExpr;
- StringView Offset;
- NodeArray UnionSelectors;
- bool OnePastTheEnd;
-
-public:
- SubobjectExpr(const Node *Type_, const Node *SubExpr_, StringView Offset_,
- NodeArray UnionSelectors_, bool OnePastTheEnd_)
- : Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_),
- UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {}
-
- template<typename Fn> void match(Fn F) const {
- F(Type, SubExpr, Offset, UnionSelectors, OnePastTheEnd);
- }
-
- void printLeft(OutputStream &S) const override {
- SubExpr->print(S);
- S += ".<";
- Type->print(S);
- S += " at offset ";
- if (Offset.empty()) {
- S += "0";
- } else if (Offset[0] == 'n') {
- S += "-";
- S += Offset.dropFront();
- } else {
- S += Offset;
- }
- S += ">";
- }
-};
-
+class SubobjectExpr : public Node {
+ const Node *Type;
+ const Node *SubExpr;
+ StringView Offset;
+ NodeArray UnionSelectors;
+ bool OnePastTheEnd;
+
+public:
+ SubobjectExpr(const Node *Type_, const Node *SubExpr_, StringView Offset_,
+ NodeArray UnionSelectors_, bool OnePastTheEnd_)
+ : Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_),
+ UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {}
+
+ template<typename Fn> void match(Fn F) const {
+ F(Type, SubExpr, Offset, UnionSelectors, OnePastTheEnd);
+ }
+
+ void printLeft(OutputStream &S) const override {
+ SubExpr->print(S);
+ S += ".<";
+ Type->print(S);
+ S += " at offset ";
+ if (Offset.empty()) {
+ S += "0";
+ } else if (Offset[0] == 'n') {
+ S += "-";
+ S += Offset.dropFront();
+ } else {
+ S += Offset;
+ }
+ S += ">";
+ }
+};
+
class EnclosingExpr : public Node {
const StringView Prefix;
const Node *Infix;
@@ -1892,28 +1892,28 @@ public:
}
};
-class PointerToMemberConversionExpr : public Node {
- const Node *Type;
- const Node *SubExpr;
- StringView Offset;
-
-public:
- PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_,
- StringView Offset_)
- : Node(KPointerToMemberConversionExpr), Type(Type_), SubExpr(SubExpr_),
- Offset(Offset_) {}
-
- template<typename Fn> void match(Fn F) const { F(Type, SubExpr, Offset); }
-
- void printLeft(OutputStream &S) const override {
- S += "(";
- Type->print(S);
- S += ")(";
- SubExpr->print(S);
- S += ")";
- }
-};
-
+class PointerToMemberConversionExpr : public Node {
+ const Node *Type;
+ const Node *SubExpr;
+ StringView Offset;
+
+public:
+ PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_,
+ StringView Offset_)
+ : Node(KPointerToMemberConversionExpr), Type(Type_), SubExpr(SubExpr_),
+ Offset(Offset_) {}
+
+ template<typename Fn> void match(Fn F) const { F(Type, SubExpr, Offset); }
+
+ void printLeft(OutputStream &S) const override {
+ S += "(";
+ Type->print(S);
+ S += ")(";
+ SubExpr->print(S);
+ S += ")";
+ }
+};
+
class InitListExpr : public Node {
const Node *Ty;
NodeArray Inits;
@@ -2369,9 +2369,9 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
TemplateParamList Params;
public:
- ScopedTemplateParamList(AbstractManglingParser *TheParser)
- : Parser(TheParser),
- OldNumTemplateParamLists(TheParser->TemplateParams.size()) {
+ ScopedTemplateParamList(AbstractManglingParser *TheParser)
+ : Parser(TheParser),
+ OldNumTemplateParamLists(TheParser->TemplateParams.size()) {
Parser->TemplateParams.push_back(&Params);
}
~ScopedTemplateParamList() {
@@ -2493,8 +2493,8 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
Node *parseConversionExpr();
Node *parseBracedExpr();
Node *parseFoldExpr();
- Node *parsePointerToMemberConversionExpr();
- Node *parseSubobjectExpr();
+ Node *parsePointerToMemberConversionExpr();
+ Node *parseSubobjectExpr();
/// Parse the <type> production.
Node *parseType();
@@ -4462,50 +4462,50 @@ Node *AbstractManglingParser<Derived, Alloc>::parseFoldExpr() {
return make<FoldExpr>(IsLeftFold, OperatorName, Pack, Init);
}
-// <expression> ::= mc <parameter type> <expr> [<offset number>] E
-//
-// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
-template <typename Derived, typename Alloc>
-Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberConversionExpr() {
- Node *Ty = getDerived().parseType();
- if (!Ty)
- return nullptr;
- Node *Expr = getDerived().parseExpr();
- if (!Expr)
- return nullptr;
- StringView Offset = getDerived().parseNumber(true);
- if (!consumeIf('E'))
- return nullptr;
- return make<PointerToMemberConversionExpr>(Ty, Expr, Offset);
-}
-
-// <expression> ::= so <referent type> <expr> [<offset number>] <union-selector>* [p] E
-// <union-selector> ::= _ [<number>]
-//
-// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
-template <typename Derived, typename Alloc>
-Node *AbstractManglingParser<Derived, Alloc>::parseSubobjectExpr() {
- Node *Ty = getDerived().parseType();
- if (!Ty)
- return nullptr;
- Node *Expr = getDerived().parseExpr();
- if (!Expr)
- return nullptr;
- StringView Offset = getDerived().parseNumber(true);
- size_t SelectorsBegin = Names.size();
- while (consumeIf('_')) {
- Node *Selector = make<NameType>(parseNumber());
- if (!Selector)
- return nullptr;
- Names.push_back(Selector);
- }
- bool OnePastTheEnd = consumeIf('p');
- if (!consumeIf('E'))
- return nullptr;
- return make<SubobjectExpr>(
- Ty, Expr, Offset, popTrailingNodeArray(SelectorsBegin), OnePastTheEnd);
-}
-
+// <expression> ::= mc <parameter type> <expr> [<offset number>] E
+//
+// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
+template <typename Derived, typename Alloc>
+Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberConversionExpr() {
+ Node *Ty = getDerived().parseType();
+ if (!Ty)
+ return nullptr;
+ Node *Expr = getDerived().parseExpr();
+ if (!Expr)
+ return nullptr;
+ StringView Offset = getDerived().parseNumber(true);
+ if (!consumeIf('E'))
+ return nullptr;
+ return make<PointerToMemberConversionExpr>(Ty, Expr, Offset);
+}
+
+// <expression> ::= so <referent type> <expr> [<offset number>] <union-selector>* [p] E
+// <union-selector> ::= _ [<number>]
+//
+// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
+template <typename Derived, typename Alloc>
+Node *AbstractManglingParser<Derived, Alloc>::parseSubobjectExpr() {
+ Node *Ty = getDerived().parseType();
+ if (!Ty)
+ return nullptr;
+ Node *Expr = getDerived().parseExpr();
+ if (!Expr)
+ return nullptr;
+ StringView Offset = getDerived().parseNumber(true);
+ size_t SelectorsBegin = Names.size();
+ while (consumeIf('_')) {
+ Node *Selector = make<NameType>(parseNumber());
+ if (!Selector)
+ return nullptr;
+ Names.push_back(Selector);
+ }
+ bool OnePastTheEnd = consumeIf('p');
+ if (!consumeIf('E'))
+ return nullptr;
+ return make<SubobjectExpr>(
+ Ty, Expr, Offset, popTrailingNodeArray(SelectorsBegin), OnePastTheEnd);
+}
+
// <expression> ::= <unary operator-name> <expression>
// ::= <binary operator-name> <expression> <expression>
// ::= <ternary operator-name> <expression> <expression> <expression>
@@ -4763,9 +4763,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
return nullptr;
case 'm':
switch (First[1]) {
- case 'c':
- First += 2;
- return parsePointerToMemberConversionExpr();
+ case 'c':
+ First += 2;
+ return parsePointerToMemberConversionExpr();
case 'i':
First += 2;
return getDerived().parseBinaryExpr("-");
@@ -4913,9 +4913,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
return Ex;
return make<CastExpr>("static_cast", T, Ex);
}
- case 'o':
- First += 2;
- return parseSubobjectExpr();
+ case 'o':
+ First += 2;
+ return parseSubobjectExpr();
case 'p': {
First += 2;
Node *Child = getDerived().parseExpr();
@@ -5011,43 +5011,43 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
}
}
return nullptr;
- case 'u': {
- ++First;
- Node *Name = getDerived().parseSourceName(/*NameState=*/nullptr);
- if (!Name)
- return nullptr;
- // Special case legacy __uuidof mangling. The 't' and 'z' appear where the
- // standard encoding expects a <template-arg>, and would be otherwise be
- // interpreted as <type> node 'short' or 'ellipsis'. However, neither
- // __uuidof(short) nor __uuidof(...) can actually appear, so there is no
- // actual conflict here.
- if (Name->getBaseName() == "__uuidof") {
- if (numLeft() < 2)
- return nullptr;
- if (*First == 't') {
- ++First;
- Node *Ty = getDerived().parseType();
- if (!Ty)
- return nullptr;
- return make<CallExpr>(Name, makeNodeArray(&Ty, &Ty + 1));
- }
- if (*First == 'z') {
- ++First;
- Node *Ex = getDerived().parseExpr();
- if (!Ex)
- return nullptr;
- return make<CallExpr>(Name, makeNodeArray(&Ex, &Ex + 1));
- }
- }
- size_t ExprsBegin = Names.size();
- while (!consumeIf('E')) {
- Node *E = getDerived().parseTemplateArg();
- if (E == nullptr)
- return E;
- Names.push_back(E);
- }
- return make<CallExpr>(Name, popTrailingNodeArray(ExprsBegin));
- }
+ case 'u': {
+ ++First;
+ Node *Name = getDerived().parseSourceName(/*NameState=*/nullptr);
+ if (!Name)
+ return nullptr;
+ // Special case legacy __uuidof mangling. The 't' and 'z' appear where the
+ // standard encoding expects a <template-arg>, and would be otherwise be
+ // interpreted as <type> node 'short' or 'ellipsis'. However, neither
+ // __uuidof(short) nor __uuidof(...) can actually appear, so there is no
+ // actual conflict here.
+ if (Name->getBaseName() == "__uuidof") {
+ if (numLeft() < 2)
+ return nullptr;
+ if (*First == 't') {
+ ++First;
+ Node *Ty = getDerived().parseType();
+ if (!Ty)
+ return nullptr;
+ return make<CallExpr>(Name, makeNodeArray(&Ty, &Ty + 1));
+ }
+ if (*First == 'z') {
+ ++First;
+ Node *Ex = getDerived().parseExpr();
+ if (!Ex)
+ return nullptr;
+ return make<CallExpr>(Name, makeNodeArray(&Ex, &Ex + 1));
+ }
+ }
+ size_t ExprsBegin = Names.size();
+ while (!consumeIf('E')) {
+ Node *E = getDerived().parseTemplateArg();
+ if (E == nullptr)
+ return E;
+ Names.push_back(E);
+ }
+ return make<CallExpr>(Name, popTrailingNodeArray(ExprsBegin));
+ }
case '1':
case '2':
case '3':
@@ -5105,16 +5105,16 @@ Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
switch (look()) {
case 'T':
switch (look(1)) {
- // TA <template-arg> # template parameter object
- //
- // Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/63
- case 'A': {
- First += 2;
- Node *Arg = getDerived().parseTemplateArg();
- if (Arg == nullptr)
- return nullptr;
- return make<SpecialName>("template parameter object for ", Arg);
- }
+ // TA <template-arg> # template parameter object
+ //
+ // Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/63
+ case 'A': {
+ First += 2;
+ Node *Arg = getDerived().parseTemplateArg();
+ if (Arg == nullptr)
+ return nullptr;
+ return make<SpecialName>("template parameter object for ", Arg);
+ }
// TV <type> # virtual table
case 'V': {
First += 2;
@@ -5243,7 +5243,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseEncoding() {
decltype(TemplateParams) OldParams;
public:
- SaveTemplateParams(AbstractManglingParser *TheParser) : Parser(TheParser) {
+ SaveTemplateParams(AbstractManglingParser *TheParser) : Parser(TheParser) {
OldParams = std::move(Parser->TemplateParams);
Parser->TemplateParams.clear();
}
@@ -5343,12 +5343,12 @@ struct FloatData<long double>
#else
static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms
#endif
- // `-0x1.ffffffffffffffffffffffffffffp+16383` + 'L' + '\0' == 42 bytes.
- // 28 'f's * 4 bits == 112 bits, which is the number of mantissa bits.
- // Negatives are one character longer than positives.
- // `0x1.` and `p` are constant, and exponents `+16383` and `-16382` are the
- // same length. 1 sign bit, 112 mantissa bits, and 15 exponent bits == 128.
- static const size_t max_demangled_size = 42;
+ // `-0x1.ffffffffffffffffffffffffffffp+16383` + 'L' + '\0' == 42 bytes.
+ // 28 'f's * 4 bits == 112 bits, which is the number of mantissa bits.
+ // Negatives are one character longer than positives.
+ // `0x1.` and `p` are constant, and exponents `+16383` and `-16382` are the
+ // same length. 1 sign bit, 112 mantissa bits, and 15 exponent bits == 128.
+ static const size_t max_demangled_size = 42;
static constexpr const char *spec = "%LaL";
};
diff --git a/contrib/libs/llvm12/include/llvm/Demangle/Utility.h b/contrib/libs/llvm12/include/llvm/Demangle/Utility.h
index 36ab3deff5..5b3d7575a6 100644
--- a/contrib/libs/llvm12/include/llvm/Demangle/Utility.h
+++ b/contrib/libs/llvm12/include/llvm/Demangle/Utility.h
@@ -59,7 +59,7 @@ class OutputStream {
char *TempPtr = std::end(Temp);
while (N) {
- *--TempPtr = char('0' + N % 10);
+ *--TempPtr = char('0' + N % 10);
N /= 10;
}
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h
index fa8859133e..2e5bb609fe 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h
@@ -42,10 +42,10 @@ public:
class InProcessEHFrameRegistrar final : public EHFrameRegistrar {
public:
Error registerEHFrames(JITTargetAddress EHFrameSectionAddr,
- size_t EHFrameSectionSize) override;
+ size_t EHFrameSectionSize) override;
Error deregisterEHFrames(JITTargetAddress EHFrameSectionAddr,
- size_t EHFrameSectionSize) override;
+ size_t EHFrameSectionSize) override;
};
using StoreFrameRangeFunction =
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/ELF.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/ELF.h
index a2144ab1dd..4a042fbd49 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/ELF.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/ELF.h
@@ -26,20 +26,20 @@
namespace llvm {
namespace jitlink {
-/// Create a LinkGraph from an ELF relocatable object.
+/// Create a LinkGraph from an ELF relocatable object.
+///
+/// Note: The graph does not take ownership of the underlying buffer, nor copy
+/// its contents. The caller is responsible for ensuring that the object buffer
+/// outlives the graph.
+Expected<std::unique_ptr<LinkGraph>>
+createLinkGraphFromELFObject(MemoryBufferRef ObjectBuffer);
+
+/// Link the given graph.
///
-/// Note: The graph does not take ownership of the underlying buffer, nor copy
-/// its contents. The caller is responsible for ensuring that the object buffer
-/// outlives the graph.
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject(MemoryBufferRef ObjectBuffer);
-
-/// Link the given graph.
-///
/// Uses conservative defaults for GOT and stub handling based on the target
/// platform.
-void link_ELF(std::unique_ptr<LinkGraph> G,
- std::unique_ptr<JITLinkContext> Ctx);
+void link_ELF(std::unique_ptr<LinkGraph> G,
+ std::unique_ptr<JITLinkContext> Ctx);
} // end namespace jitlink
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h
index 2c2d8ba8e9..de62f02876 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h
@@ -51,20 +51,20 @@ enum ELFX86RelocationKind : Edge::Kind {
} // end namespace ELF_x86_64_Edges
-/// Create a LinkGraph from an ELF/x86-64 relocatable object.
-///
-/// Note: The graph does not take ownership of the underlying buffer, nor copy
-/// its contents. The caller is responsible for ensuring that the object buffer
-/// outlives the graph.
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_x86_64(MemoryBufferRef ObjectBuffer);
-
+/// Create a LinkGraph from an ELF/x86-64 relocatable object.
+///
+/// Note: The graph does not take ownership of the underlying buffer, nor copy
+/// its contents. The caller is responsible for ensuring that the object buffer
+/// outlives the graph.
+Expected<std::unique_ptr<LinkGraph>>
+createLinkGraphFromELFObject_x86_64(MemoryBufferRef ObjectBuffer);
+
/// jit-link the given object buffer, which must be a ELF x86-64 object file.
-void link_ELF_x86_64(std::unique_ptr<LinkGraph> G,
- std::unique_ptr<JITLinkContext> Ctx);
-
-/// Return the string name of the given ELF x86-64 edge kind.
-StringRef getELFX86RelocationKindName(Edge::Kind R);
+void link_ELF_x86_64(std::unique_ptr<LinkGraph> G,
+ std::unique_ptr<JITLinkContext> Ctx);
+
+/// Return the string name of the given ELF x86-64 edge kind.
+StringRef getELFX86RelocationKindName(Edge::Kind R);
} // end namespace jitlink
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/JITLink.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/JITLink.h
index e464ede4e5..43d567880a 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/JITLink.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/JITLink.h
@@ -402,10 +402,10 @@ public:
return Name;
}
- /// Rename this symbol. The client is responsible for updating scope and
- /// linkage if this name-change requires it.
- void setName(StringRef Name) { this->Name = Name; }
-
+ /// Rename this symbol. The client is responsible for updating scope and
+ /// linkage if this name-change requires it.
+ void setName(StringRef Name) { this->Name = Name; }
+
/// Returns true if this Symbol has content (potentially) defined within this
/// object file (i.e. is anything but an external or absolute symbol).
bool isDefined() const {
@@ -793,48 +793,48 @@ public:
Section::const_block_iterator, const Block *,
getSectionConstBlocks>;
- LinkGraph(std::string Name, const Triple &TT, unsigned PointerSize,
+ LinkGraph(std::string Name, const Triple &TT, unsigned PointerSize,
support::endianness Endianness)
- : Name(std::move(Name)), TT(TT), PointerSize(PointerSize),
+ : Name(std::move(Name)), TT(TT), PointerSize(PointerSize),
Endianness(Endianness) {}
/// Returns the name of this graph (usually the name of the original
/// underlying MemoryBuffer).
const std::string &getName() { return Name; }
- /// Returns the target triple for this Graph.
- const Triple &getTargetTriple() const { return TT; }
-
+ /// Returns the target triple for this Graph.
+ const Triple &getTargetTriple() const { return TT; }
+
/// Returns the pointer size for use in this graph.
unsigned getPointerSize() const { return PointerSize; }
/// Returns the endianness of content in this graph.
support::endianness getEndianness() const { return Endianness; }
- /// Allocate a copy of the given string using the LinkGraph's allocator.
- /// This can be useful when renaming symbols or adding new content to the
- /// graph.
- StringRef allocateString(StringRef Source) {
- auto *AllocatedBuffer = Allocator.Allocate<char>(Source.size());
- llvm::copy(Source, AllocatedBuffer);
- return StringRef(AllocatedBuffer, Source.size());
- }
-
- /// Allocate a copy of the given string using the LinkGraph's allocator.
- /// This can be useful when renaming symbols or adding new content to the
- /// graph.
- ///
- /// Note: This Twine-based overload requires an extra string copy and an
- /// extra heap allocation for large strings. The StringRef overload should
- /// be preferred where possible.
- StringRef allocateString(Twine Source) {
- SmallString<256> TmpBuffer;
- auto SourceStr = Source.toStringRef(TmpBuffer);
- auto *AllocatedBuffer = Allocator.Allocate<char>(SourceStr.size());
- llvm::copy(SourceStr, AllocatedBuffer);
- return StringRef(AllocatedBuffer, SourceStr.size());
- }
-
+ /// Allocate a copy of the given string using the LinkGraph's allocator.
+ /// This can be useful when renaming symbols or adding new content to the
+ /// graph.
+ StringRef allocateString(StringRef Source) {
+ auto *AllocatedBuffer = Allocator.Allocate<char>(Source.size());
+ llvm::copy(Source, AllocatedBuffer);
+ return StringRef(AllocatedBuffer, Source.size());
+ }
+
+ /// Allocate a copy of the given string using the LinkGraph's allocator.
+ /// This can be useful when renaming symbols or adding new content to the
+ /// graph.
+ ///
+ /// Note: This Twine-based overload requires an extra string copy and an
+ /// extra heap allocation for large strings. The StringRef overload should
+ /// be preferred where possible.
+ StringRef allocateString(Twine Source) {
+ SmallString<256> TmpBuffer;
+ auto SourceStr = Source.toStringRef(TmpBuffer);
+ auto *AllocatedBuffer = Allocator.Allocate<char>(SourceStr.size());
+ llvm::copy(SourceStr, AllocatedBuffer);
+ return StringRef(AllocatedBuffer, SourceStr.size());
+ }
+
/// Create a section with the given name, protection flags, and alignment.
Section &createSection(StringRef Name, sys::Memory::ProtectionFlags Prot) {
std::unique_ptr<Section> Sec(new Section(Name, Prot, Sections.size()));
@@ -997,7 +997,7 @@ public:
Section &Sec = Sym.getBlock().getSection();
Sec.removeSymbol(Sym);
}
- Sym.makeExternal(createAddressable(0, false));
+ Sym.makeExternal(createAddressable(0, false));
ExternalSymbols.insert(&Sym);
}
@@ -1057,7 +1057,7 @@ private:
BumpPtrAllocator Allocator;
std::string Name;
- Triple TT;
+ Triple TT;
unsigned PointerSize;
support::endianness Endianness;
SectionList Sections;
@@ -1230,31 +1230,31 @@ struct PassConfiguration {
/// Notable use cases: Building GOT, stub, and TLV symbols.
LinkGraphPassList PostPrunePasses;
- /// Post-allocation passes.
- ///
- /// These passes are called on the graph after memory has been allocated and
- /// defined nodes have been assigned their final addresses, but before the
- /// context has been notified of these addresses. At this point externals
- /// have not been resolved, and symbol content has not yet been copied into
- /// working memory.
- ///
- /// Notable use cases: Setting up data structures associated with addresses
- /// of defined symbols (e.g. a mapping of __dso_handle to JITDylib* for the
- /// JIT runtime) -- using a PostAllocationPass for this ensures that the
- /// data structures are in-place before any query for resolved symbols
- /// can complete.
- LinkGraphPassList PostAllocationPasses;
-
+ /// Post-allocation passes.
+ ///
+ /// These passes are called on the graph after memory has been allocated and
+ /// defined nodes have been assigned their final addresses, but before the
+ /// context has been notified of these addresses. At this point externals
+ /// have not been resolved, and symbol content has not yet been copied into
+ /// working memory.
+ ///
+ /// Notable use cases: Setting up data structures associated with addresses
+ /// of defined symbols (e.g. a mapping of __dso_handle to JITDylib* for the
+ /// JIT runtime) -- using a PostAllocationPass for this ensures that the
+ /// data structures are in-place before any query for resolved symbols
+ /// can complete.
+ LinkGraphPassList PostAllocationPasses;
+
/// Pre-fixup passes.
///
/// These passes are called on the graph after memory has been allocated,
- /// content copied into working memory, and all nodes (including externals)
- /// have been assigned their final addresses, but before any fixups have been
- /// applied.
+ /// content copied into working memory, and all nodes (including externals)
+ /// have been assigned their final addresses, but before any fixups have been
+ /// applied.
///
/// Notable use cases: Late link-time optimizations like GOT and stub
/// elimination.
- LinkGraphPassList PreFixupPasses;
+ LinkGraphPassList PreFixupPasses;
/// Post-fixup passes.
///
@@ -1310,15 +1310,15 @@ class JITLinkContext {
public:
using LookupMap = DenseMap<StringRef, SymbolLookupFlags>;
- /// Create a JITLinkContext.
- JITLinkContext(const JITLinkDylib *JD) : JD(JD) {}
-
+ /// Create a JITLinkContext.
+ JITLinkContext(const JITLinkDylib *JD) : JD(JD) {}
+
/// Destroy a JITLinkContext.
virtual ~JITLinkContext();
- /// Return the JITLinkDylib that this link is targeting, if any.
- const JITLinkDylib *getJITLinkDylib() const { return JD; }
-
+ /// Return the JITLinkDylib that this link is targeting, if any.
+ const JITLinkDylib *getJITLinkDylib() const { return JD; }
+
/// Return the MemoryManager to be used for this link.
virtual JITLinkMemoryManager &getMemoryManager() = 0;
@@ -1336,11 +1336,11 @@ public:
/// their final memory locations in the target process. At this point the
/// LinkGraph can be inspected to build a symbol table, however the block
/// content will not generally have been copied to the target location yet.
- ///
- /// If the client detects an error in the LinkGraph state (e.g. unexpected or
- /// missing symbols) they may return an error here. The error will be
- /// propagated to notifyFailed and the linker will bail out.
- virtual Error notifyResolved(LinkGraph &G) = 0;
+ ///
+ /// If the client detects an error in the LinkGraph state (e.g. unexpected or
+ /// missing symbols) they may return an error here. The error will be
+ /// propagated to notifyFailed and the linker will bail out.
+ virtual Error notifyResolved(LinkGraph &G) = 0;
/// Called by JITLink to notify the context that the object has been
/// finalized (i.e. emitted to memory and memory permissions set). If all of
@@ -1366,26 +1366,26 @@ public:
/// Called by JITLink to modify the pass pipeline prior to linking.
/// The default version performs no modification.
virtual Error modifyPassConfig(const Triple &TT, PassConfiguration &Config);
-
-private:
- const JITLinkDylib *JD = nullptr;
+
+private:
+ const JITLinkDylib *JD = nullptr;
};
/// Marks all symbols in a graph live. This can be used as a default,
/// conservative mark-live implementation.
Error markAllSymbolsLive(LinkGraph &G);
-/// Create a LinkGraph from the given object buffer.
+/// Create a LinkGraph from the given object buffer.
///
-/// Note: The graph does not take ownership of the underlying buffer, nor copy
-/// its contents. The caller is responsible for ensuring that the object buffer
-/// outlives the graph.
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromObject(MemoryBufferRef ObjectBuffer);
-
-/// Link the given graph.
-void link(std::unique_ptr<LinkGraph> G, std::unique_ptr<JITLinkContext> Ctx);
-
+/// Note: The graph does not take ownership of the underlying buffer, nor copy
+/// its contents. The caller is responsible for ensuring that the object buffer
+/// outlives the graph.
+Expected<std::unique_ptr<LinkGraph>>
+createLinkGraphFromObject(MemoryBufferRef ObjectBuffer);
+
+/// Link the given graph.
+void link(std::unique_ptr<LinkGraph> G, std::unique_ptr<JITLinkContext> Ctx);
+
} // end namespace jitlink
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/JITLinkDylib.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/JITLinkDylib.h
index f6e94e909b..bd04937b1f 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/JITLinkDylib.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/JITLinkDylib.h
@@ -1,35 +1,35 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===-- JITLinkDylib.h - JITLink Dylib type ---------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Defines the JITLinkDylib API.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_JITLINK_JITLINKDYLIB_H
-#define LLVM_EXECUTIONENGINE_JITLINK_JITLINKDYLIB_H
-
-namespace llvm {
-namespace jitlink {
-
-class JITLinkDylib {};
-
-} // end namespace jitlink
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_JITLINK_JITLINKDYLIB_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===-- JITLinkDylib.h - JITLink Dylib type ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines the JITLinkDylib API.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_JITLINK_JITLINKDYLIB_H
+#define LLVM_EXECUTIONENGINE_JITLINK_JITLINKDYLIB_H
+
+namespace llvm {
+namespace jitlink {
+
+class JITLinkDylib {};
+
+} // end namespace jitlink
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_JITLINK_JITLINKDYLIB_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h
index 0d5269ddec..0cf8555b15 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h
@@ -21,10 +21,10 @@
#define LLVM_EXECUTIONENGINE_JITLINK_JITLINKMEMORYMANAGER_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ExecutionEngine/JITLink/JITLinkDylib.h"
+#include "llvm/ExecutionEngine/JITLink/JITLinkDylib.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/Support/Error.h"
-#include "llvm/Support/MSVCErrorWorkarounds.h"
+#include "llvm/Support/MSVCErrorWorkarounds.h"
#include "llvm/Support/Memory.h"
#include <cstdint>
@@ -101,31 +101,31 @@ public:
virtual ~JITLinkMemoryManager();
/// Create an Allocation object.
- ///
- /// The JD argument represents the target JITLinkDylib, and can be used by
- /// JITLinkMemoryManager implementers to manage per-dylib allocation pools
- /// (e.g. one pre-reserved address space slab per dylib to ensure that all
- /// allocations for the dylib are within a certain range). The JD argument
- /// may be null (representing an allocation not associated with any
- /// JITDylib.
- ///
- /// The request argument describes the segment sizes and permisssions being
- /// requested.
+ ///
+ /// The JD argument represents the target JITLinkDylib, and can be used by
+ /// JITLinkMemoryManager implementers to manage per-dylib allocation pools
+ /// (e.g. one pre-reserved address space slab per dylib to ensure that all
+ /// allocations for the dylib are within a certain range). The JD argument
+ /// may be null (representing an allocation not associated with any
+ /// JITDylib.
+ ///
+ /// The request argument describes the segment sizes and permisssions being
+ /// requested.
virtual Expected<std::unique_ptr<Allocation>>
- allocate(const JITLinkDylib *JD, const SegmentsRequestMap &Request) = 0;
+ allocate(const JITLinkDylib *JD, const SegmentsRequestMap &Request) = 0;
};
/// A JITLinkMemoryManager that allocates in-process memory.
class InProcessMemoryManager : public JITLinkMemoryManager {
public:
Expected<std::unique_ptr<Allocation>>
- allocate(const JITLinkDylib *JD, const SegmentsRequestMap &Request) override;
+ allocate(const JITLinkDylib *JD, const SegmentsRequestMap &Request) override;
};
} // end namespace jitlink
} // end namespace llvm
-#endif // LLVM_EXECUTIONENGINE_JITLINK_JITLINKMEMORYMANAGER_H
+#endif // LLVM_EXECUTIONENGINE_JITLINK_JITLINKMEMORYMANAGER_H
#ifdef __GNUC__
#pragma GCC diagnostic pop
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/MachO.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/MachO.h
index 97085a6fa3..c73d7b9111 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/MachO.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/MachO.h
@@ -25,20 +25,20 @@
namespace llvm {
namespace jitlink {
-/// Create a LinkGraph from a MachO relocatable object.
-///
-/// Note: The graph does not take ownership of the underlying buffer, nor copy
-/// its contents. The caller is responsible for ensuring that the object buffer
-/// outlives the graph.
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromMachOObject(MemoryBufferRef ObjectBuffer);
-
+/// Create a LinkGraph from a MachO relocatable object.
+///
+/// Note: The graph does not take ownership of the underlying buffer, nor copy
+/// its contents. The caller is responsible for ensuring that the object buffer
+/// outlives the graph.
+Expected<std::unique_ptr<LinkGraph>>
+createLinkGraphFromMachOObject(MemoryBufferRef ObjectBuffer);
+
/// jit-link the given ObjBuffer, which must be a MachO object file.
///
/// Uses conservative defaults for GOT and stub handling based on the target
/// platform.
-void link_MachO(std::unique_ptr<LinkGraph> G,
- std::unique_ptr<JITLinkContext> Ctx);
+void link_MachO(std::unique_ptr<LinkGraph> G,
+ std::unique_ptr<JITLinkContext> Ctx);
} // end namespace jitlink
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/MachO_arm64.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/MachO_arm64.h
index f374e62feb..e611fb78e4 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/MachO_arm64.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/MachO_arm64.h
@@ -47,14 +47,14 @@ enum MachOARM64RelocationKind : Edge::Kind {
} // namespace MachO_arm64_Edges
-/// Create a LinkGraph from a MachO/arm64 relocatable object.
-///
-/// Note: The graph does not take ownership of the underlying buffer, nor copy
-/// its contents. The caller is responsible for ensuring that the object buffer
-/// outlives the graph.
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromMachOObject_arm64(MemoryBufferRef ObjectBuffer);
-
+/// Create a LinkGraph from a MachO/arm64 relocatable object.
+///
+/// Note: The graph does not take ownership of the underlying buffer, nor copy
+/// its contents. The caller is responsible for ensuring that the object buffer
+/// outlives the graph.
+Expected<std::unique_ptr<LinkGraph>>
+createLinkGraphFromMachOObject_arm64(MemoryBufferRef ObjectBuffer);
+
/// jit-link the given object buffer, which must be a MachO arm64 object file.
///
/// If PrePrunePasses is empty then a default mark-live pass will be inserted
@@ -64,8 +64,8 @@ createLinkGraphFromMachOObject_arm64(MemoryBufferRef ObjectBuffer);
/// If PostPrunePasses is empty then a default GOT-and-stubs insertion pass will
/// be inserted. If PostPrunePasses is not empty then the caller is responsible
/// for including a pass to insert GOT and stub edges.
-void link_MachO_arm64(std::unique_ptr<LinkGraph> G,
- std::unique_ptr<JITLinkContext> Ctx);
+void link_MachO_arm64(std::unique_ptr<LinkGraph> G,
+ std::unique_ptr<JITLinkContext> Ctx);
/// Return the string name of the given MachO arm64 edge kind.
StringRef getMachOARM64RelocationKindName(Edge::Kind R);
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h
index f3647c6497..2edeb6869c 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h
@@ -52,16 +52,16 @@ enum MachOX86RelocationKind : Edge::Kind {
} // namespace MachO_x86_64_Edges
-/// Create a LinkGraph from a MachO/x86-64 relocatable object.
+/// Create a LinkGraph from a MachO/x86-64 relocatable object.
+///
+/// Note: The graph does not take ownership of the underlying buffer, nor copy
+/// its contents. The caller is responsible for ensuring that the object buffer
+/// outlives the graph.
+Expected<std::unique_ptr<LinkGraph>>
+createLinkGraphFromMachOObject_x86_64(MemoryBufferRef ObjectBuffer);
+
+/// jit-link the given LinkGraph.
///
-/// Note: The graph does not take ownership of the underlying buffer, nor copy
-/// its contents. The caller is responsible for ensuring that the object buffer
-/// outlives the graph.
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromMachOObject_x86_64(MemoryBufferRef ObjectBuffer);
-
-/// jit-link the given LinkGraph.
-///
/// If PrePrunePasses is empty then a default mark-live pass will be inserted
/// that will mark all exported atoms live. If PrePrunePasses is not empty, the
/// caller is responsible for including a pass to mark atoms as live.
@@ -69,8 +69,8 @@ createLinkGraphFromMachOObject_x86_64(MemoryBufferRef ObjectBuffer);
/// If PostPrunePasses is empty then a default GOT-and-stubs insertion pass will
/// be inserted. If PostPrunePasses is not empty then the caller is responsible
/// for including a pass to insert GOT and stub edges.
-void link_MachO_x86_64(std::unique_ptr<LinkGraph> G,
- std::unique_ptr<JITLinkContext> Ctx);
+void link_MachO_x86_64(std::unique_ptr<LinkGraph> G,
+ std::unique_ptr<JITLinkContext> Ctx);
/// Return the string name of the given MachO x86-64 edge kind.
StringRef getMachOX86RelocationKindName(Edge::Kind R);
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITSymbol.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITSymbol.h
index 0a960b73e9..86ddb15a97 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITSymbol.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/JITSymbol.h
@@ -436,7 +436,7 @@ public:
virtual JITSymbol findSymbol(const std::string &Name) = 0;
private:
- void anchor() override;
+ void anchor() override;
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
index abfc9333d8..aa58b3d35f 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
@@ -30,7 +30,7 @@
#include "llvm/ExecutionEngine/Orc/Layer.h"
#include "llvm/ExecutionEngine/Orc/LazyReexports.h"
#include "llvm/ExecutionEngine/Orc/Speculation.h"
-#include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
+#include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Constant.h"
@@ -101,8 +101,8 @@ public:
/// Emits the given module. This should not be called by clients: it will be
/// called by the JIT when a definition added via the add method is requested.
- void emit(std::unique_ptr<MaterializationResponsibility> R,
- ThreadSafeModule TSM) override;
+ void emit(std::unique_ptr<MaterializationResponsibility> R,
+ ThreadSafeModule TSM) override;
private:
struct PerDylibResources {
@@ -126,8 +126,8 @@ private:
void expandPartition(GlobalValueSet &Partition);
- void emitPartition(std::unique_ptr<MaterializationResponsibility> R,
- ThreadSafeModule TSM,
+ void emitPartition(std::unique_ptr<MaterializationResponsibility> R,
+ ThreadSafeModule TSM,
IRMaterializationUnit::SymbolNameToDefinitionMap Defs);
mutable std::mutex CODLayerMutex;
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Core.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Core.h
index 08ada986f3..3a51e885ae 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Core.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Core.h
@@ -23,14 +23,14 @@
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FunctionExtras.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ExecutionEngine/JITLink/JITLinkDylib.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ExecutionEngine/JITLink/JITLinkDylib.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
#include "llvm/ExecutionEngine/OrcV1Deprecation.h"
#include "llvm/Support/Debug.h"
-#include <atomic>
+#include <atomic>
#include <memory>
#include <vector>
@@ -43,68 +43,68 @@ class ExecutionSession;
class MaterializationUnit;
class MaterializationResponsibility;
class JITDylib;
-class ResourceTracker;
-class InProgressLookupState;
-
+class ResourceTracker;
+class InProgressLookupState;
+
enum class SymbolState : uint8_t;
-using ResourceTrackerSP = IntrusiveRefCntPtr<ResourceTracker>;
-using JITDylibSP = IntrusiveRefCntPtr<JITDylib>;
-
-using ResourceKey = uintptr_t;
-
-/// API to remove / transfer ownership of JIT resources.
-class ResourceTracker : public ThreadSafeRefCountedBase<ResourceTracker> {
-private:
- friend class ExecutionSession;
- friend class JITDylib;
- friend class MaterializationResponsibility;
-
-public:
- ResourceTracker(const ResourceTracker &) = delete;
- ResourceTracker &operator=(const ResourceTracker &) = delete;
- ResourceTracker(ResourceTracker &&) = delete;
- ResourceTracker &operator=(ResourceTracker &&) = delete;
-
- ~ResourceTracker();
-
- /// Return the JITDylib targeted by this tracker.
- JITDylib &getJITDylib() const {
- return *reinterpret_cast<JITDylib *>(JDAndFlag.load() &
- ~static_cast<uintptr_t>(1));
- }
-
- /// Remove all resources associated with this key.
- Error remove();
-
- /// Transfer all resources associated with this key to the given
- /// tracker, which must target the same JITDylib as this one.
- void transferTo(ResourceTracker &DstRT);
-
- /// Return true if this tracker has become defunct.
- bool isDefunct() const { return JDAndFlag.load() & 0x1; }
-
- /// Returns the key associated with this tracker.
- /// This method should not be used except for debug logging: there is no
- /// guarantee that the returned value will remain valid.
- ResourceKey getKeyUnsafe() const { return reinterpret_cast<uintptr_t>(this); }
-
-private:
- ResourceTracker(JITDylibSP JD);
-
- void makeDefunct();
-
- std::atomic_uintptr_t JDAndFlag;
-};
-
-/// Listens for ResourceTracker operations.
-class ResourceManager {
-public:
- virtual ~ResourceManager();
- virtual Error handleRemoveResources(ResourceKey K) = 0;
- virtual void handleTransferResources(ResourceKey DstK, ResourceKey SrcK) = 0;
-};
-
+using ResourceTrackerSP = IntrusiveRefCntPtr<ResourceTracker>;
+using JITDylibSP = IntrusiveRefCntPtr<JITDylib>;
+
+using ResourceKey = uintptr_t;
+
+/// API to remove / transfer ownership of JIT resources.
+class ResourceTracker : public ThreadSafeRefCountedBase<ResourceTracker> {
+private:
+ friend class ExecutionSession;
+ friend class JITDylib;
+ friend class MaterializationResponsibility;
+
+public:
+ ResourceTracker(const ResourceTracker &) = delete;
+ ResourceTracker &operator=(const ResourceTracker &) = delete;
+ ResourceTracker(ResourceTracker &&) = delete;
+ ResourceTracker &operator=(ResourceTracker &&) = delete;
+
+ ~ResourceTracker();
+
+ /// Return the JITDylib targeted by this tracker.
+ JITDylib &getJITDylib() const {
+ return *reinterpret_cast<JITDylib *>(JDAndFlag.load() &
+ ~static_cast<uintptr_t>(1));
+ }
+
+ /// Remove all resources associated with this key.
+ Error remove();
+
+ /// Transfer all resources associated with this key to the given
+ /// tracker, which must target the same JITDylib as this one.
+ void transferTo(ResourceTracker &DstRT);
+
+ /// Return true if this tracker has become defunct.
+ bool isDefunct() const { return JDAndFlag.load() & 0x1; }
+
+ /// Returns the key associated with this tracker.
+ /// This method should not be used except for debug logging: there is no
+ /// guarantee that the returned value will remain valid.
+ ResourceKey getKeyUnsafe() const { return reinterpret_cast<uintptr_t>(this); }
+
+private:
+ ResourceTracker(JITDylibSP JD);
+
+ void makeDefunct();
+
+ std::atomic_uintptr_t JDAndFlag;
+};
+
+/// Listens for ResourceTracker operations.
+class ResourceManager {
+public:
+ virtual ~ResourceManager();
+ virtual Error handleRemoveResources(ResourceKey K) = 0;
+ virtual void handleTransferResources(ResourceKey DstK, ResourceKey SrcK) = 0;
+};
+
/// A set of symbol names (represented by SymbolStringPtrs for
// efficiency).
using SymbolNameSet = DenseSet<SymbolStringPtr>;
@@ -224,21 +224,21 @@ public:
/// Add an element to the set. The client is responsible for checking that
/// duplicates are not added.
- SymbolLookupSet &
- add(SymbolStringPtr Name,
- SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
+ SymbolLookupSet &
+ add(SymbolStringPtr Name,
+ SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
Symbols.push_back(std::make_pair(std::move(Name), Flags));
- return *this;
+ return *this;
+ }
+
+ /// Quickly append one lookup set to another.
+ SymbolLookupSet &append(SymbolLookupSet Other) {
+ Symbols.reserve(Symbols.size() + Other.size());
+ for (auto &KV : Other)
+ Symbols.push_back(std::move(KV));
+ return *this;
}
- /// Quickly append one lookup set to another.
- SymbolLookupSet &append(SymbolLookupSet Other) {
- Symbols.reserve(Symbols.size() + Other.size());
- for (auto &KV : Other)
- Symbols.push_back(std::move(KV));
- return *this;
- }
-
bool empty() const { return Symbols.empty(); }
UnderlyingVector::size_type size() const { return Symbols.size(); }
iterator begin() { return Symbols.begin(); }
@@ -363,7 +363,7 @@ public:
for (UnderlyingVector::size_type I = 1; I != Symbols.size(); ++I)
if (Symbols[I].first == Symbols[I - 1].first)
return true;
- return false;
+ return false;
}
#endif
@@ -394,18 +394,18 @@ using RegisterDependenciesFunction =
/// are no dependants to register with.
extern RegisterDependenciesFunction NoDependenciesToRegister;
-class ResourceTrackerDefunct : public ErrorInfo<ResourceTrackerDefunct> {
-public:
- static char ID;
-
- ResourceTrackerDefunct(ResourceTrackerSP RT);
- std::error_code convertToErrorCode() const override;
- void log(raw_ostream &OS) const override;
-
-private:
- ResourceTrackerSP RT;
-};
-
+class ResourceTrackerDefunct : public ErrorInfo<ResourceTrackerDefunct> {
+public:
+ static char ID;
+
+ ResourceTrackerDefunct(ResourceTrackerSP RT);
+ std::error_code convertToErrorCode() const override;
+ void log(raw_ostream &OS) const override;
+
+private:
+ ResourceTrackerSP RT;
+};
+
/// Used to notify a JITDylib that the given set of symbols failed to
/// materialize.
class FailedToMaterialize : public ErrorInfo<FailedToMaterialize> {
@@ -496,10 +496,10 @@ private:
/// emit symbols, or abandon materialization by notifying any unmaterialized
/// symbols of an error.
class MaterializationResponsibility {
- friend class ExecutionSession;
-
+ friend class ExecutionSession;
+
public:
- MaterializationResponsibility(MaterializationResponsibility &&) = delete;
+ MaterializationResponsibility(MaterializationResponsibility &&) = delete;
MaterializationResponsibility &
operator=(MaterializationResponsibility &&) = delete;
@@ -508,15 +508,15 @@ public:
/// emitted or notified of an error.
~MaterializationResponsibility();
- /// Returns the ResourceTracker for this instance.
- template <typename Func> Error withResourceKeyDo(Func &&F) const;
-
+ /// Returns the ResourceTracker for this instance.
+ template <typename Func> Error withResourceKeyDo(Func &&F) const;
+
/// Returns the target JITDylib that these symbols are being materialized
/// into.
JITDylib &getTargetJITDylib() const { return *JD; }
- /// Returns the ExecutionSession for this instance.
- ExecutionSession &getExecutionSession();
+ /// Returns the ExecutionSession for this instance.
+ ExecutionSession &getExecutionSession();
/// Returns the symbol flags map for this responsibility instance.
/// Note: The returned flags may have transient flags (Lazy, Materializing)
@@ -601,13 +601,13 @@ public:
/// 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).
- Error replace(std::unique_ptr<MaterializationUnit> MU);
+ Error replace(std::unique_ptr<MaterializationUnit> MU);
/// Delegates responsibility for the given symbols to the returned
/// materialization responsibility. Useful for breaking up work between
/// threads, or different kinds of materialization processes.
- Expected<std::unique_ptr<MaterializationResponsibility>>
- delegate(const SymbolNameSet &Symbols);
+ Expected<std::unique_ptr<MaterializationResponsibility>>
+ delegate(const SymbolNameSet &Symbols);
void addDependencies(const SymbolStringPtr &Name,
const SymbolDependenceMap &Dependencies);
@@ -618,15 +618,15 @@ public:
private:
/// Create a MaterializationResponsibility for the given JITDylib and
/// initial symbols.
- MaterializationResponsibility(JITDylibSP JD, SymbolFlagsMap SymbolFlags,
- SymbolStringPtr InitSymbol)
+ MaterializationResponsibility(JITDylibSP JD, SymbolFlagsMap SymbolFlags,
+ SymbolStringPtr InitSymbol)
: JD(std::move(JD)), SymbolFlags(std::move(SymbolFlags)),
- InitSymbol(std::move(InitSymbol)) {
- assert(this->JD && "Cannot initialize with null JITDylib");
+ InitSymbol(std::move(InitSymbol)) {
+ assert(this->JD && "Cannot initialize with null JITDylib");
assert(!this->SymbolFlags.empty() && "Materializing nothing?");
}
- JITDylibSP JD;
+ JITDylibSP JD;
SymbolFlagsMap SymbolFlags;
SymbolStringPtr InitSymbol;
};
@@ -645,9 +645,9 @@ class MaterializationUnit {
public:
MaterializationUnit(SymbolFlagsMap InitalSymbolFlags,
- SymbolStringPtr InitSymbol)
+ SymbolStringPtr InitSymbol)
: SymbolFlags(std::move(InitalSymbolFlags)),
- InitSymbol(std::move(InitSymbol)) {
+ InitSymbol(std::move(InitSymbol)) {
assert((!this->InitSymbol || this->SymbolFlags.count(this->InitSymbol)) &&
"If set, InitSymbol should appear in InitialSymbolFlags map");
}
@@ -667,8 +667,8 @@ public:
/// Implementations of this method should materialize all symbols
/// in the materialzation unit, except for those that have been
/// previously discarded.
- virtual void
- materialize(std::unique_ptr<MaterializationResponsibility> R) = 0;
+ virtual void
+ materialize(std::unique_ptr<MaterializationResponsibility> R) = 0;
/// Called by JITDylibs to notify MaterializationUnits that the given symbol
/// has been overridden.
@@ -697,12 +697,12 @@ private:
/// materialized.
class AbsoluteSymbolsMaterializationUnit : public MaterializationUnit {
public:
- AbsoluteSymbolsMaterializationUnit(SymbolMap Symbols);
+ AbsoluteSymbolsMaterializationUnit(SymbolMap Symbols);
StringRef getName() const override;
private:
- void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
+ void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
static SymbolFlagsMap extractFlags(const SymbolMap &Symbols);
@@ -720,9 +720,9 @@ private:
/// \endcode
///
inline std::unique_ptr<AbsoluteSymbolsMaterializationUnit>
-absoluteSymbols(SymbolMap Symbols) {
+absoluteSymbols(SymbolMap Symbols) {
return std::make_unique<AbsoluteSymbolsMaterializationUnit>(
- std::move(Symbols));
+ std::move(Symbols));
}
/// A materialization unit for symbol aliases. Allows existing symbols to be
@@ -739,12 +739,12 @@ public:
/// resolved.
ReExportsMaterializationUnit(JITDylib *SourceJD,
JITDylibLookupFlags SourceJDLookupFlags,
- SymbolAliasMap Aliases);
+ SymbolAliasMap Aliases);
StringRef getName() const override;
private:
- void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
+ void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases);
@@ -765,9 +765,9 @@ private:
/// return Err;
/// \endcode
inline std::unique_ptr<ReExportsMaterializationUnit>
-symbolAliases(SymbolAliasMap Aliases) {
+symbolAliases(SymbolAliasMap Aliases) {
return std::make_unique<ReExportsMaterializationUnit>(
- nullptr, JITDylibLookupFlags::MatchAllSymbols, std::move(Aliases));
+ nullptr, JITDylibLookupFlags::MatchAllSymbols, std::move(Aliases));
}
/// Create a materialization unit for re-exporting symbols from another JITDylib
@@ -776,9 +776,9 @@ symbolAliases(SymbolAliasMap Aliases) {
inline std::unique_ptr<ReExportsMaterializationUnit>
reexports(JITDylib &SourceJD, SymbolAliasMap Aliases,
JITDylibLookupFlags SourceJDLookupFlags =
- JITDylibLookupFlags::MatchExportedSymbolsOnly) {
+ JITDylibLookupFlags::MatchExportedSymbolsOnly) {
return std::make_unique<ReExportsMaterializationUnit>(
- &SourceJD, SourceJDLookupFlags, std::move(Aliases));
+ &SourceJD, SourceJDLookupFlags, std::move(Aliases));
}
/// Build a SymbolAliasMap for the common case where you want to re-export
@@ -802,10 +802,10 @@ enum class SymbolState : uint8_t {
/// makes a callback when all symbols are available.
class AsynchronousSymbolQuery {
friend class ExecutionSession;
- friend class InProgressFullLookupState;
+ friend class InProgressFullLookupState;
friend class JITDylib;
friend class JITSymbolResolverAdapter;
- friend class MaterializationResponsibility;
+ friend class MaterializationResponsibility;
public:
/// Create a query for the given symbols. The NotifyComplete
@@ -849,57 +849,57 @@ private:
SymbolState RequiredState;
};
-/// Wraps state for a lookup-in-progress.
-/// DefinitionGenerators can optionally take ownership of a LookupState object
-/// to suspend a lookup-in-progress while they search for definitions.
-class LookupState {
- friend class OrcV2CAPIHelper;
- friend class ExecutionSession;
-
-public:
- LookupState();
- LookupState(LookupState &&);
- LookupState &operator=(LookupState &&);
- ~LookupState();
-
- /// Continue the lookup. This can be called by DefinitionGenerators
- /// to re-start a captured query-application operation.
- void continueLookup(Error Err);
-
-private:
- LookupState(std::unique_ptr<InProgressLookupState> IPLS);
-
- // For C API.
- void reset(InProgressLookupState *IPLS);
-
- std::unique_ptr<InProgressLookupState> IPLS;
-};
-
-/// Definition generators can be attached to JITDylibs to generate new
-/// definitions for otherwise unresolved symbols during lookup.
-class DefinitionGenerator {
-public:
- virtual ~DefinitionGenerator();
-
- /// DefinitionGenerators should override this method to insert new
- /// definitions into the parent JITDylib. K specifies the kind of this
- /// lookup. JD specifies the target JITDylib being searched, and
- /// JDLookupFlags specifies whether the search should match against
- /// hidden symbols. Finally, Symbols describes the set of unresolved
- /// symbols and their associated lookup flags.
- virtual Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
- JITDylibLookupFlags JDLookupFlags,
- const SymbolLookupSet &LookupSet) = 0;
-};
-
+/// Wraps state for a lookup-in-progress.
+/// DefinitionGenerators can optionally take ownership of a LookupState object
+/// to suspend a lookup-in-progress while they search for definitions.
+class LookupState {
+ friend class OrcV2CAPIHelper;
+ friend class ExecutionSession;
+
+public:
+ LookupState();
+ LookupState(LookupState &&);
+ LookupState &operator=(LookupState &&);
+ ~LookupState();
+
+ /// Continue the lookup. This can be called by DefinitionGenerators
+ /// to re-start a captured query-application operation.
+ void continueLookup(Error Err);
+
+private:
+ LookupState(std::unique_ptr<InProgressLookupState> IPLS);
+
+ // For C API.
+ void reset(InProgressLookupState *IPLS);
+
+ std::unique_ptr<InProgressLookupState> IPLS;
+};
+
+/// Definition generators can be attached to JITDylibs to generate new
+/// definitions for otherwise unresolved symbols during lookup.
+class DefinitionGenerator {
+public:
+ virtual ~DefinitionGenerator();
+
+ /// DefinitionGenerators should override this method to insert new
+ /// definitions into the parent JITDylib. K specifies the kind of this
+ /// lookup. JD specifies the target JITDylib being searched, and
+ /// JDLookupFlags specifies whether the search should match against
+ /// hidden symbols. Finally, Symbols describes the set of unresolved
+ /// symbols and their associated lookup flags.
+ virtual Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
+ JITDylibLookupFlags JDLookupFlags,
+ const SymbolLookupSet &LookupSet) = 0;
+};
+
/// A symbol table that supports asynchoronous symbol queries.
///
/// Represents a virtual shared object. Instances can not be copied or moved, so
/// their addresses may be used as keys for resource management.
/// JITDylib state changes must be made via an ExecutionSession to guarantee
/// that they are synchronized with respect to other JITDylib operations.
-class JITDylib : public ThreadSafeRefCountedBase<JITDylib>,
- public jitlink::JITLinkDylib {
+class JITDylib : public ThreadSafeRefCountedBase<JITDylib>,
+ public jitlink::JITLinkDylib {
friend class AsynchronousSymbolQuery;
friend class ExecutionSession;
friend class Platform;
@@ -920,21 +920,21 @@ public:
/// Get a reference to the ExecutionSession for this JITDylib.
ExecutionSession &getExecutionSession() const { return ES; }
- /// Calls remove on all trackers currently associated with this JITDylib.
- /// Does not run static deinits.
- ///
- /// Note that removal happens outside the session lock, so new code may be
- /// added concurrently while the clear is underway, and the newly added
- /// code will *not* be cleared. Adding new code concurrently with a clear
- /// is usually a bug and should be avoided.
- Error clear();
-
- /// Get the default resource tracker for this JITDylib.
- ResourceTrackerSP getDefaultResourceTracker();
-
- /// Create a resource tracker for this JITDylib.
- ResourceTrackerSP createResourceTracker();
-
+ /// Calls remove on all trackers currently associated with this JITDylib.
+ /// Does not run static deinits.
+ ///
+ /// Note that removal happens outside the session lock, so new code may be
+ /// added concurrently while the clear is underway, and the newly added
+ /// code will *not* be cleared. Adding new code concurrently with a clear
+ /// is usually a bug and should be avoided.
+ Error clear();
+
+ /// Get the default resource tracker for this JITDylib.
+ ResourceTrackerSP getDefaultResourceTracker();
+
+ /// Create a resource tracker for this JITDylib.
+ ResourceTrackerSP createResourceTracker();
+
/// Adds a definition generator to this JITDylib and returns a referenece to
/// it.
///
@@ -995,13 +995,13 @@ public:
/// Define all symbols provided by the materialization unit to be part of this
/// JITDylib.
///
- /// If RT is not specified then the default resource tracker will be used.
- ///
+ /// If RT is not specified then the default resource tracker will be used.
+ ///
/// This overload always takes ownership of the MaterializationUnit. If any
/// errors occur, the MaterializationUnit consumed.
template <typename MaterializationUnitType>
- Error define(std::unique_ptr<MaterializationUnitType> &&MU,
- ResourceTrackerSP RT = nullptr);
+ Error define(std::unique_ptr<MaterializationUnitType> &&MU,
+ ResourceTrackerSP RT = nullptr);
/// Define all symbols provided by the materialization unit to be part of this
/// JITDylib.
@@ -1011,8 +1011,8 @@ public:
/// may allow the caller to modify the MaterializationUnit to correct the
/// issue, then re-call define.
template <typename MaterializationUnitType>
- Error define(std::unique_ptr<MaterializationUnitType> &MU,
- ResourceTrackerSP RT = nullptr);
+ Error define(std::unique_ptr<MaterializationUnitType> &MU,
+ ResourceTrackerSP RT = nullptr);
/// Tries to remove the given symbols.
///
@@ -1029,44 +1029,44 @@ public:
/// Dump current JITDylib state to OS.
void dump(raw_ostream &OS);
- /// Returns the given JITDylibs and all of their transitive dependencies in
- /// DFS order (based on linkage relationships). Each JITDylib will appear
- /// only once.
- static std::vector<JITDylibSP> getDFSLinkOrder(ArrayRef<JITDylibSP> JDs);
-
- /// Returns the given JITDylibs and all of their transitive dependensies in
- /// reverse DFS order (based on linkage relationships). Each JITDylib will
- /// appear only once.
- static std::vector<JITDylibSP>
- getReverseDFSLinkOrder(ArrayRef<JITDylibSP> JDs);
-
- /// Return this JITDylib and its transitive dependencies in DFS order
- /// based on linkage relationships.
- std::vector<JITDylibSP> getDFSLinkOrder();
-
- /// Rteurn this JITDylib and its transitive dependencies in reverse DFS order
- /// based on linkage relationships.
- std::vector<JITDylibSP> getReverseDFSLinkOrder();
-
+ /// Returns the given JITDylibs and all of their transitive dependencies in
+ /// DFS order (based on linkage relationships). Each JITDylib will appear
+ /// only once.
+ static std::vector<JITDylibSP> getDFSLinkOrder(ArrayRef<JITDylibSP> JDs);
+
+ /// Returns the given JITDylibs and all of their transitive dependensies in
+ /// reverse DFS order (based on linkage relationships). Each JITDylib will
+ /// appear only once.
+ static std::vector<JITDylibSP>
+ getReverseDFSLinkOrder(ArrayRef<JITDylibSP> JDs);
+
+ /// Return this JITDylib and its transitive dependencies in DFS order
+ /// based on linkage relationships.
+ std::vector<JITDylibSP> getDFSLinkOrder();
+
+ /// Rteurn this JITDylib and its transitive dependencies in reverse DFS order
+ /// based on linkage relationships.
+ std::vector<JITDylibSP> getReverseDFSLinkOrder();
+
private:
using AsynchronousSymbolQueryList =
std::vector<std::shared_ptr<AsynchronousSymbolQuery>>;
struct UnmaterializedInfo {
- UnmaterializedInfo(std::unique_ptr<MaterializationUnit> MU,
- ResourceTracker *RT)
- : MU(std::move(MU)), RT(RT) {}
+ UnmaterializedInfo(std::unique_ptr<MaterializationUnit> MU,
+ ResourceTracker *RT)
+ : MU(std::move(MU)), RT(RT) {}
std::unique_ptr<MaterializationUnit> MU;
- ResourceTracker *RT;
+ ResourceTracker *RT;
};
using UnmaterializedInfosMap =
DenseMap<SymbolStringPtr, std::shared_ptr<UnmaterializedInfo>>;
- using UnmaterializedInfosList =
- std::vector<std::shared_ptr<UnmaterializedInfo>>;
-
+ using UnmaterializedInfosList =
+ std::vector<std::shared_ptr<UnmaterializedInfo>>;
+
struct MaterializingInfo {
SymbolDependenceMap Dependants;
SymbolDependenceMap UnemittedDependencies;
@@ -1133,16 +1133,16 @@ private:
JITDylib(ExecutionSession &ES, std::string Name);
- ResourceTrackerSP getTracker(MaterializationResponsibility &MR);
- std::pair<AsynchronousSymbolQuerySet, std::shared_ptr<SymbolDependenceMap>>
- removeTracker(ResourceTracker &RT);
+ ResourceTrackerSP getTracker(MaterializationResponsibility &MR);
+ std::pair<AsynchronousSymbolQuerySet, std::shared_ptr<SymbolDependenceMap>>
+ removeTracker(ResourceTracker &RT);
- void transferTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT);
+ void transferTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT);
- Error defineImpl(MaterializationUnit &MU);
+ Error defineImpl(MaterializationUnit &MU);
- void installMaterializationUnit(std::unique_ptr<MaterializationUnit> MU,
- ResourceTracker &RT);
+ void installMaterializationUnit(std::unique_ptr<MaterializationUnit> MU,
+ ResourceTracker &RT);
void detachQueryHelper(AsynchronousSymbolQuery &Q,
const SymbolNameSet &QuerySymbols);
@@ -1153,45 +1153,45 @@ private:
Expected<SymbolFlagsMap> defineMaterializing(SymbolFlagsMap SymbolFlags);
- Error replace(MaterializationResponsibility &FromMR,
- std::unique_ptr<MaterializationUnit> MU);
+ Error replace(MaterializationResponsibility &FromMR,
+ std::unique_ptr<MaterializationUnit> MU);
+
+ Expected<std::unique_ptr<MaterializationResponsibility>>
+ delegate(MaterializationResponsibility &FromMR, SymbolFlagsMap SymbolFlags,
+ SymbolStringPtr InitSymbol);
- Expected<std::unique_ptr<MaterializationResponsibility>>
- delegate(MaterializationResponsibility &FromMR, SymbolFlagsMap SymbolFlags,
- SymbolStringPtr InitSymbol);
-
SymbolNameSet getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) const;
void addDependencies(const SymbolStringPtr &Name,
const SymbolDependenceMap &Dependants);
- Error resolve(MaterializationResponsibility &MR, const SymbolMap &Resolved);
+ Error resolve(MaterializationResponsibility &MR, const SymbolMap &Resolved);
+
+ Error emit(MaterializationResponsibility &MR, const SymbolFlagsMap &Emitted);
- Error emit(MaterializationResponsibility &MR, const SymbolFlagsMap &Emitted);
+ void unlinkMaterializationResponsibility(MaterializationResponsibility &MR);
- void unlinkMaterializationResponsibility(MaterializationResponsibility &MR);
-
using FailedSymbolsWorklist =
std::vector<std::pair<JITDylib *, SymbolStringPtr>>;
- static std::pair<AsynchronousSymbolQuerySet,
- std::shared_ptr<SymbolDependenceMap>>
- failSymbols(FailedSymbolsWorklist);
-
+ static std::pair<AsynchronousSymbolQuerySet,
+ std::shared_ptr<SymbolDependenceMap>>
+ failSymbols(FailedSymbolsWorklist);
+
ExecutionSession &ES;
std::string JITDylibName;
- std::mutex GeneratorsMutex;
+ std::mutex GeneratorsMutex;
bool Open = true;
SymbolTable Symbols;
UnmaterializedInfosMap UnmaterializedInfos;
MaterializingInfosMap MaterializingInfos;
- std::vector<std::shared_ptr<DefinitionGenerator>> DefGenerators;
+ std::vector<std::shared_ptr<DefinitionGenerator>> DefGenerators;
JITDylibSearchOrder LinkOrder;
- ResourceTrackerSP DefaultTracker;
-
- // Map trackers to sets of symbols tracked.
- DenseMap<ResourceTracker *, SymbolNameVector> TrackerSymbols;
- DenseMap<MaterializationResponsibility *, ResourceTracker *> MRTrackers;
+ ResourceTrackerSP DefaultTracker;
+
+ // Map trackers to sets of symbols tracked.
+ DenseMap<ResourceTracker *, SymbolNameVector> TrackerSymbols;
+ DenseMap<MaterializationResponsibility *, ResourceTracker *> MRTrackers;
};
/// Platforms set up standard symbols and mediate interactions between dynamic
@@ -1210,12 +1210,12 @@ public:
/// This method will be called under the ExecutionSession lock each time a
/// MaterializationUnit is added to a JITDylib.
- virtual Error notifyAdding(ResourceTracker &RT,
- const MaterializationUnit &MU) = 0;
+ virtual Error notifyAdding(ResourceTracker &RT,
+ const MaterializationUnit &MU) = 0;
/// This method will be called under the ExecutionSession lock when a
- /// ResourceTracker is removed.
- virtual Error notifyRemoving(ResourceTracker &RT) = 0;
+ /// ResourceTracker is removed.
+ virtual Error notifyRemoving(ResourceTracker &RT) = 0;
/// A utility function for looking up initializer symbols. Performs a blocking
/// lookup for the given symbols in each of the given JITDylibs.
@@ -1226,12 +1226,12 @@ public:
/// An ExecutionSession represents a running JIT program.
class ExecutionSession {
- friend class InProgressLookupFlagsState;
- friend class InProgressFullLookupState;
+ friend class InProgressLookupFlagsState;
+ friend class InProgressFullLookupState;
friend class JITDylib;
- friend class LookupState;
- friend class MaterializationResponsibility;
- friend class ResourceTracker;
+ friend class LookupState;
+ friend class MaterializationResponsibility;
+ friend class ResourceTracker;
public:
/// For reporting errors.
@@ -1240,16 +1240,16 @@ public:
/// For dispatching MaterializationUnit::materialize calls.
using DispatchMaterializationFunction =
std::function<void(std::unique_ptr<MaterializationUnit> MU,
- std::unique_ptr<MaterializationResponsibility> MR)>;
+ std::unique_ptr<MaterializationResponsibility> MR)>;
/// Construct an ExecutionSession.
///
/// SymbolStringPools may be shared between ExecutionSessions.
ExecutionSession(std::shared_ptr<SymbolStringPool> SSP = nullptr);
- /// End the session. Closes all JITDylibs.
- Error endSession();
-
+ /// End the session. Closes all JITDylibs.
+ Error endSession();
+
/// Add a symbol name to the SymbolStringPool and return a pointer to it.
SymbolStringPtr intern(StringRef SymName) { return SSP->intern(SymName); }
@@ -1269,14 +1269,14 @@ public:
return F();
}
- /// Register the given ResourceManager with this ExecutionSession.
- /// Managers will be notified of events in reverse order of registration.
- void registerResourceManager(ResourceManager &RM);
-
- /// Deregister the given ResourceManager with this ExecutionSession.
- /// Manager must have been previously registered.
- void deregisterResourceManager(ResourceManager &RM);
-
+ /// Register the given ResourceManager with this ExecutionSession.
+ /// Managers will be notified of events in reverse order of registration.
+ void registerResourceManager(ResourceManager &RM);
+
+ /// Deregister the given ResourceManager with this ExecutionSession.
+ /// Manager must have been previously registered.
+ void deregisterResourceManager(ResourceManager &RM);
+
/// Return a pointer to the "name" JITDylib.
/// Ownership of JITDylib remains within Execution Session
JITDylib *getJITDylibByName(StringRef Name);
@@ -1320,18 +1320,18 @@ public:
return *this;
}
- /// Search the given JITDylibs to find the flags associated with each of the
- /// given symbols.
- void lookupFlags(LookupKind K, JITDylibSearchOrder SearchOrder,
- SymbolLookupSet Symbols,
- unique_function<void(Expected<SymbolFlagsMap>)> OnComplete);
+ /// Search the given JITDylibs to find the flags associated with each of the
+ /// given symbols.
+ void lookupFlags(LookupKind K, JITDylibSearchOrder SearchOrder,
+ SymbolLookupSet Symbols,
+ unique_function<void(Expected<SymbolFlagsMap>)> OnComplete);
- /// Blocking version of lookupFlags.
- Expected<SymbolFlagsMap> lookupFlags(LookupKind K,
- JITDylibSearchOrder SearchOrder,
- SymbolLookupSet Symbols);
+ /// Blocking version of lookupFlags.
+ Expected<SymbolFlagsMap> lookupFlags(LookupKind K,
+ JITDylibSearchOrder SearchOrder,
+ SymbolLookupSet Symbols);
- /// Search the given JITDylibs for the given symbols.
+ /// Search the given JITDylibs for the given symbols.
///
/// SearchOrder lists the JITDylibs to search. For each dylib, the associated
/// boolean indicates whether the search should match against non-exported
@@ -1391,11 +1391,11 @@ public:
SymbolState RequiredState = SymbolState::Ready);
/// Materialize the given unit.
- void
- dispatchMaterialization(std::unique_ptr<MaterializationUnit> MU,
- std::unique_ptr<MaterializationResponsibility> MR) {
+ void
+ dispatchMaterialization(std::unique_ptr<MaterializationUnit> MU,
+ std::unique_ptr<MaterializationResponsibility> MR) {
assert(MU && "MU must be non-null");
- DEBUG_WITH_TYPE("orc", dumpDispatchInfo(MR->getTargetJITDylib(), *MU));
+ DEBUG_WITH_TYPE("orc", dumpDispatchInfo(MR->getTargetJITDylib(), *MU));
DispatchMaterialization(std::move(MU), std::move(MR));
}
@@ -1407,124 +1407,124 @@ private:
logAllUnhandledErrors(std::move(Err), errs(), "JIT session error: ");
}
- static void materializeOnCurrentThread(
- std::unique_ptr<MaterializationUnit> MU,
- std::unique_ptr<MaterializationResponsibility> MR) {
+ static void materializeOnCurrentThread(
+ std::unique_ptr<MaterializationUnit> MU,
+ std::unique_ptr<MaterializationResponsibility> MR) {
MU->materialize(std::move(MR));
}
- void dispatchOutstandingMUs();
-
- static std::unique_ptr<MaterializationResponsibility>
- createMaterializationResponsibility(ResourceTracker &RT,
- SymbolFlagsMap Symbols,
- SymbolStringPtr InitSymbol) {
- auto &JD = RT.getJITDylib();
- std::unique_ptr<MaterializationResponsibility> MR(
- new MaterializationResponsibility(&JD, std::move(Symbols),
- std::move(InitSymbol)));
- JD.MRTrackers[MR.get()] = &RT;
- return MR;
- }
-
- Error removeResourceTracker(ResourceTracker &RT);
- void transferResourceTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT);
- void destroyResourceTracker(ResourceTracker &RT);
-
- // State machine functions for query application..
-
- /// IL_updateCandidatesFor is called to remove already-defined symbols that
- /// match a given query from the set of candidate symbols to generate
- /// definitions for (no need to generate a definition if one already exists).
- Error IL_updateCandidatesFor(JITDylib &JD, JITDylibLookupFlags JDLookupFlags,
- SymbolLookupSet &Candidates,
- SymbolLookupSet *NonCandidates);
-
- /// OL_applyQueryPhase1 is an optionally re-startable loop for triggering
- /// definition generation. It is called when a lookup is performed, and again
- /// each time that LookupState::continueLookup is called.
- void OL_applyQueryPhase1(std::unique_ptr<InProgressLookupState> IPLS,
- Error Err);
-
- /// OL_completeLookup is run once phase 1 successfully completes for a lookup
- /// call. It attempts to attach the symbol to all symbol table entries and
- /// collect all MaterializationUnits to dispatch. If this method fails then
- /// all MaterializationUnits will be left un-materialized.
- void OL_completeLookup(std::unique_ptr<InProgressLookupState> IPLS,
- std::shared_ptr<AsynchronousSymbolQuery> Q,
- RegisterDependenciesFunction RegisterDependencies);
-
- /// OL_completeLookupFlags is run once phase 1 successfully completes for a
- /// lookupFlags call.
- void OL_completeLookupFlags(
- std::unique_ptr<InProgressLookupState> IPLS,
- unique_function<void(Expected<SymbolFlagsMap>)> OnComplete);
-
- // State machine functions for MaterializationResponsibility.
- void OL_destroyMaterializationResponsibility(
- MaterializationResponsibility &MR);
- SymbolNameSet OL_getRequestedSymbols(const MaterializationResponsibility &MR);
- Error OL_notifyResolved(MaterializationResponsibility &MR,
- const SymbolMap &Symbols);
- Error OL_notifyEmitted(MaterializationResponsibility &MR);
- Error OL_defineMaterializing(MaterializationResponsibility &MR,
- SymbolFlagsMap SymbolFlags);
- void OL_notifyFailed(MaterializationResponsibility &MR);
- Error OL_replace(MaterializationResponsibility &MR,
- std::unique_ptr<MaterializationUnit> MU);
- Expected<std::unique_ptr<MaterializationResponsibility>>
- OL_delegate(MaterializationResponsibility &MR, const SymbolNameSet &Symbols);
- void OL_addDependencies(MaterializationResponsibility &MR,
- const SymbolStringPtr &Name,
- const SymbolDependenceMap &Dependencies);
- void OL_addDependenciesForAll(MaterializationResponsibility &MR,
- const SymbolDependenceMap &Dependencies);
-
+ void dispatchOutstandingMUs();
+
+ static std::unique_ptr<MaterializationResponsibility>
+ createMaterializationResponsibility(ResourceTracker &RT,
+ SymbolFlagsMap Symbols,
+ SymbolStringPtr InitSymbol) {
+ auto &JD = RT.getJITDylib();
+ std::unique_ptr<MaterializationResponsibility> MR(
+ new MaterializationResponsibility(&JD, std::move(Symbols),
+ std::move(InitSymbol)));
+ JD.MRTrackers[MR.get()] = &RT;
+ return MR;
+ }
+
+ Error removeResourceTracker(ResourceTracker &RT);
+ void transferResourceTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT);
+ void destroyResourceTracker(ResourceTracker &RT);
+
+ // State machine functions for query application..
+
+ /// IL_updateCandidatesFor is called to remove already-defined symbols that
+ /// match a given query from the set of candidate symbols to generate
+ /// definitions for (no need to generate a definition if one already exists).
+ Error IL_updateCandidatesFor(JITDylib &JD, JITDylibLookupFlags JDLookupFlags,
+ SymbolLookupSet &Candidates,
+ SymbolLookupSet *NonCandidates);
+
+ /// OL_applyQueryPhase1 is an optionally re-startable loop for triggering
+ /// definition generation. It is called when a lookup is performed, and again
+ /// each time that LookupState::continueLookup is called.
+ void OL_applyQueryPhase1(std::unique_ptr<InProgressLookupState> IPLS,
+ Error Err);
+
+ /// OL_completeLookup is run once phase 1 successfully completes for a lookup
+ /// call. It attempts to attach the symbol to all symbol table entries and
+ /// collect all MaterializationUnits to dispatch. If this method fails then
+ /// all MaterializationUnits will be left un-materialized.
+ void OL_completeLookup(std::unique_ptr<InProgressLookupState> IPLS,
+ std::shared_ptr<AsynchronousSymbolQuery> Q,
+ RegisterDependenciesFunction RegisterDependencies);
+
+ /// OL_completeLookupFlags is run once phase 1 successfully completes for a
+ /// lookupFlags call.
+ void OL_completeLookupFlags(
+ std::unique_ptr<InProgressLookupState> IPLS,
+ unique_function<void(Expected<SymbolFlagsMap>)> OnComplete);
+
+ // State machine functions for MaterializationResponsibility.
+ void OL_destroyMaterializationResponsibility(
+ MaterializationResponsibility &MR);
+ SymbolNameSet OL_getRequestedSymbols(const MaterializationResponsibility &MR);
+ Error OL_notifyResolved(MaterializationResponsibility &MR,
+ const SymbolMap &Symbols);
+ Error OL_notifyEmitted(MaterializationResponsibility &MR);
+ Error OL_defineMaterializing(MaterializationResponsibility &MR,
+ SymbolFlagsMap SymbolFlags);
+ void OL_notifyFailed(MaterializationResponsibility &MR);
+ Error OL_replace(MaterializationResponsibility &MR,
+ std::unique_ptr<MaterializationUnit> MU);
+ Expected<std::unique_ptr<MaterializationResponsibility>>
+ OL_delegate(MaterializationResponsibility &MR, const SymbolNameSet &Symbols);
+ void OL_addDependencies(MaterializationResponsibility &MR,
+ const SymbolStringPtr &Name,
+ const SymbolDependenceMap &Dependencies);
+ void OL_addDependenciesForAll(MaterializationResponsibility &MR,
+ const SymbolDependenceMap &Dependencies);
+
#ifndef NDEBUG
void dumpDispatchInfo(JITDylib &JD, MaterializationUnit &MU);
#endif // NDEBUG
mutable std::recursive_mutex SessionMutex;
- bool SessionOpen = true;
+ bool SessionOpen = true;
std::shared_ptr<SymbolStringPool> SSP;
std::unique_ptr<Platform> P;
ErrorReporter ReportError = logErrorsToStdErr;
DispatchMaterializationFunction DispatchMaterialization =
materializeOnCurrentThread;
- std::vector<ResourceManager *> ResourceManagers;
+ std::vector<ResourceManager *> ResourceManagers;
+
+ std::vector<JITDylibSP> JDs;
- std::vector<JITDylibSP> JDs;
-
// FIXME: Remove this (and runOutstandingMUs) once the linking layer works
// with callbacks from asynchronous queries.
mutable std::recursive_mutex OutstandingMUsMutex;
std::vector<std::pair<std::unique_ptr<MaterializationUnit>,
- std::unique_ptr<MaterializationResponsibility>>>
+ std::unique_ptr<MaterializationResponsibility>>>
OutstandingMUs;
};
-inline ExecutionSession &MaterializationResponsibility::getExecutionSession() {
- return JD->getExecutionSession();
-}
-
-template <typename Func>
-Error MaterializationResponsibility::withResourceKeyDo(Func &&F) const {
- return JD->getExecutionSession().runSessionLocked([&]() -> Error {
- auto I = JD->MRTrackers.find(this);
- assert(I != JD->MRTrackers.end() && "No tracker for this MR");
- if (I->second->isDefunct())
- return make_error<ResourceTrackerDefunct>(I->second);
- F(I->second->getKeyUnsafe());
- return Error::success();
- });
-}
-
+inline ExecutionSession &MaterializationResponsibility::getExecutionSession() {
+ return JD->getExecutionSession();
+}
+
+template <typename Func>
+Error MaterializationResponsibility::withResourceKeyDo(Func &&F) const {
+ return JD->getExecutionSession().runSessionLocked([&]() -> Error {
+ auto I = JD->MRTrackers.find(this);
+ assert(I != JD->MRTrackers.end() && "No tracker for this MR");
+ if (I->second->isDefunct())
+ return make_error<ResourceTrackerDefunct>(I->second);
+ F(I->second->getKeyUnsafe());
+ return Error::success();
+ });
+}
+
template <typename GeneratorT>
GeneratorT &JITDylib::addGenerator(std::unique_ptr<GeneratorT> DefGenerator) {
auto &G = *DefGenerator;
- std::lock_guard<std::mutex> Lock(GeneratorsMutex);
- DefGenerators.push_back(std::move(DefGenerator));
+ std::lock_guard<std::mutex> Lock(GeneratorsMutex);
+ DefGenerators.push_back(std::move(DefGenerator));
return G;
}
@@ -1535,8 +1535,8 @@ auto JITDylib::withLinkOrderDo(Func &&F)
}
template <typename MaterializationUnitType>
-Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &&MU,
- ResourceTrackerSP RT) {
+Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &&MU,
+ ResourceTrackerSP RT) {
assert(MU && "Can not define with a null MU");
if (MU->getSymbols().empty()) {
@@ -1548,36 +1548,36 @@ Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &&MU,
return Error::success();
} else
DEBUG_WITH_TYPE("orc", {
- dbgs() << "Defining MU " << MU->getName() << " for " << getName()
- << " (tracker: ";
- if (RT == getDefaultResourceTracker())
- dbgs() << "default)";
- else if (RT)
- dbgs() << RT.get() << ")\n";
- else
- dbgs() << "0x0, default will be used)\n";
+ dbgs() << "Defining MU " << MU->getName() << " for " << getName()
+ << " (tracker: ";
+ if (RT == getDefaultResourceTracker())
+ dbgs() << "default)";
+ else if (RT)
+ dbgs() << RT.get() << ")\n";
+ else
+ dbgs() << "0x0, default will be used)\n";
});
return ES.runSessionLocked([&, this]() -> Error {
if (auto Err = defineImpl(*MU))
return Err;
- if (!RT)
- RT = getDefaultResourceTracker();
-
+ if (!RT)
+ RT = getDefaultResourceTracker();
+
if (auto *P = ES.getPlatform()) {
- if (auto Err = P->notifyAdding(*RT, *MU))
+ if (auto Err = P->notifyAdding(*RT, *MU))
return Err;
}
- installMaterializationUnit(std::move(MU), *RT);
+ installMaterializationUnit(std::move(MU), *RT);
return Error::success();
});
}
template <typename MaterializationUnitType>
-Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &MU,
- ResourceTrackerSP RT) {
+Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &MU,
+ ResourceTrackerSP RT) {
assert(MU && "Can not define with a null MU");
if (MU->getSymbols().empty()) {
@@ -1589,36 +1589,36 @@ Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &MU,
return Error::success();
} else
DEBUG_WITH_TYPE("orc", {
- dbgs() << "Defining MU " << MU->getName() << " for " << getName()
- << " (tracker: ";
- if (RT == getDefaultResourceTracker())
- dbgs() << "default)";
- else if (RT)
- dbgs() << RT.get() << ")\n";
- else
- dbgs() << "0x0, default will be used)\n";
+ dbgs() << "Defining MU " << MU->getName() << " for " << getName()
+ << " (tracker: ";
+ if (RT == getDefaultResourceTracker())
+ dbgs() << "default)";
+ else if (RT)
+ dbgs() << RT.get() << ")\n";
+ else
+ dbgs() << "0x0, default will be used)\n";
});
return ES.runSessionLocked([&, this]() -> Error {
if (auto Err = defineImpl(*MU))
return Err;
- if (!RT)
- RT = getDefaultResourceTracker();
-
+ if (!RT)
+ RT = getDefaultResourceTracker();
+
if (auto *P = ES.getPlatform()) {
- if (auto Err = P->notifyAdding(*RT, *MU))
+ if (auto Err = P->notifyAdding(*RT, *MU))
return Err;
}
- installMaterializationUnit(std::move(MU), *RT);
+ installMaterializationUnit(std::move(MU), *RT);
return Error::success();
});
}
/// ReexportsGenerator can be used with JITDylib::addGenerator to automatically
/// re-export a subset of the source JITDylib's symbols in the target.
-class ReexportsGenerator : public DefinitionGenerator {
+class ReexportsGenerator : public DefinitionGenerator {
public:
using SymbolPredicate = std::function<bool(SymbolStringPtr)>;
@@ -1629,7 +1629,7 @@ public:
JITDylibLookupFlags SourceJDLookupFlags,
SymbolPredicate Allow = SymbolPredicate());
- Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
+ Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
JITDylibLookupFlags JDLookupFlags,
const SymbolLookupSet &LookupSet) override;
@@ -1639,57 +1639,57 @@ private:
SymbolPredicate Allow;
};
-// --------------- IMPLEMENTATION --------------
-// Implementations for inline functions/methods.
-// ---------------------------------------------
-
-inline MaterializationResponsibility::~MaterializationResponsibility() {
- JD->getExecutionSession().OL_destroyMaterializationResponsibility(*this);
-}
-
-inline SymbolNameSet MaterializationResponsibility::getRequestedSymbols() const {
- return JD->getExecutionSession().OL_getRequestedSymbols(*this);
-}
-
-inline Error MaterializationResponsibility::notifyResolved(
- const SymbolMap &Symbols) {
- return JD->getExecutionSession().OL_notifyResolved(*this, Symbols);
-}
-
-inline Error MaterializationResponsibility::notifyEmitted() {
- return JD->getExecutionSession().OL_notifyEmitted(*this);
-}
-
-inline Error MaterializationResponsibility::defineMaterializing(
- SymbolFlagsMap SymbolFlags) {
- return JD->getExecutionSession().OL_defineMaterializing(
- *this, std::move(SymbolFlags));
-}
-
-inline void MaterializationResponsibility::failMaterialization() {
- JD->getExecutionSession().OL_notifyFailed(*this);
-}
-
-inline Error MaterializationResponsibility::replace(
- std::unique_ptr<MaterializationUnit> MU) {
- return JD->getExecutionSession().OL_replace(*this, std::move(MU));
-}
-
-inline Expected<std::unique_ptr<MaterializationResponsibility>>
-MaterializationResponsibility::delegate(const SymbolNameSet &Symbols) {
- return JD->getExecutionSession().OL_delegate(*this, Symbols);
-}
-
-inline void MaterializationResponsibility::addDependencies(
- const SymbolStringPtr &Name, const SymbolDependenceMap &Dependencies) {
- JD->getExecutionSession().OL_addDependencies(*this, Name, Dependencies);
-}
-
-inline void MaterializationResponsibility::addDependenciesForAll(
- const SymbolDependenceMap &Dependencies) {
- JD->getExecutionSession().OL_addDependenciesForAll(*this, Dependencies);
-}
-
+// --------------- IMPLEMENTATION --------------
+// Implementations for inline functions/methods.
+// ---------------------------------------------
+
+inline MaterializationResponsibility::~MaterializationResponsibility() {
+ JD->getExecutionSession().OL_destroyMaterializationResponsibility(*this);
+}
+
+inline SymbolNameSet MaterializationResponsibility::getRequestedSymbols() const {
+ return JD->getExecutionSession().OL_getRequestedSymbols(*this);
+}
+
+inline Error MaterializationResponsibility::notifyResolved(
+ const SymbolMap &Symbols) {
+ return JD->getExecutionSession().OL_notifyResolved(*this, Symbols);
+}
+
+inline Error MaterializationResponsibility::notifyEmitted() {
+ return JD->getExecutionSession().OL_notifyEmitted(*this);
+}
+
+inline Error MaterializationResponsibility::defineMaterializing(
+ SymbolFlagsMap SymbolFlags) {
+ return JD->getExecutionSession().OL_defineMaterializing(
+ *this, std::move(SymbolFlags));
+}
+
+inline void MaterializationResponsibility::failMaterialization() {
+ JD->getExecutionSession().OL_notifyFailed(*this);
+}
+
+inline Error MaterializationResponsibility::replace(
+ std::unique_ptr<MaterializationUnit> MU) {
+ return JD->getExecutionSession().OL_replace(*this, std::move(MU));
+}
+
+inline Expected<std::unique_ptr<MaterializationResponsibility>>
+MaterializationResponsibility::delegate(const SymbolNameSet &Symbols) {
+ return JD->getExecutionSession().OL_delegate(*this, Symbols);
+}
+
+inline void MaterializationResponsibility::addDependencies(
+ const SymbolStringPtr &Name, const SymbolDependenceMap &Dependencies) {
+ JD->getExecutionSession().OL_addDependencies(*this, Name, Dependencies);
+}
+
+inline void MaterializationResponsibility::addDependenciesForAll(
+ const SymbolDependenceMap &Dependencies) {
+ JD->getExecutionSession().OL_addDependenciesForAll(*this, Dependencies);
+}
+
} // End namespace orc
} // End namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
index 334677e783..1c94201394 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
@@ -25,7 +25,7 @@
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/Mangling.h"
-#include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
+#include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/Object/Archive.h"
#include "llvm/Support/DynamicLibrary.h"
@@ -222,7 +222,7 @@ private:
/// If an instance of this class is attached to a JITDylib as a fallback
/// definition generator, then any symbol found in the given DynamicLibrary that
/// passes the 'Allow' predicate will be added to the JITDylib.
-class DynamicLibrarySearchGenerator : public DefinitionGenerator {
+class DynamicLibrarySearchGenerator : public DefinitionGenerator {
public:
using SymbolPredicate = std::function<bool(const SymbolStringPtr &)>;
@@ -250,7 +250,7 @@ public:
return Load(nullptr, GlobalPrefix, std::move(Allow));
}
- Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
+ Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
JITDylibLookupFlags JDLookupFlags,
const SymbolLookupSet &Symbols) override;
@@ -265,7 +265,7 @@ private:
/// If an instance of this class is attached to a JITDylib as a fallback
/// definition generator, then any symbol found in the archive will result in
/// the containing object being added to the JITDylib.
-class StaticLibraryDefinitionGenerator : public DefinitionGenerator {
+class StaticLibraryDefinitionGenerator : public DefinitionGenerator {
public:
/// Try to create a StaticLibraryDefinitionGenerator from the given path.
///
@@ -288,7 +288,7 @@ public:
static Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
Create(ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer);
- Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
+ Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
JITDylibLookupFlags JDLookupFlags,
const SymbolLookupSet &Symbols) override;
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
index b4c4565f5b..fd729bf7e5 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
@@ -52,8 +52,8 @@ public:
IRSymbolMapper::ManglingOptions MO;
};
- using NotifyCompiledFunction = std::function<void(
- MaterializationResponsibility &R, ThreadSafeModule TSM)>;
+ using NotifyCompiledFunction = std::function<void(
+ MaterializationResponsibility &R, ThreadSafeModule TSM)>;
IRCompileLayer(ExecutionSession &ES, ObjectLayer &BaseLayer,
std::unique_ptr<IRCompiler> Compile);
@@ -62,8 +62,8 @@ public:
void setNotifyCompiled(NotifyCompiledFunction NotifyCompiled);
- void emit(std::unique_ptr<MaterializationResponsibility> R,
- ThreadSafeModule TSM) override;
+ void emit(std::unique_ptr<MaterializationResponsibility> R,
+ ThreadSafeModule TSM) override;
private:
mutable std::mutex IRLayerMutex;
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
index 03a35bb841..7ea7ee2a62 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
@@ -20,7 +20,7 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
#define LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
-#include "llvm/ADT/FunctionExtras.h"
+#include "llvm/ADT/FunctionExtras.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/Layer.h"
#include <memory>
@@ -35,7 +35,7 @@ namespace orc {
/// before operating on the module.
class IRTransformLayer : public IRLayer {
public:
- using TransformFunction = unique_function<Expected<ThreadSafeModule>(
+ using TransformFunction = unique_function<Expected<ThreadSafeModule>(
ThreadSafeModule, MaterializationResponsibility &R)>;
IRTransformLayer(ExecutionSession &ES, IRLayer &BaseLayer,
@@ -45,8 +45,8 @@ public:
this->Transform = std::move(Transform);
}
- void emit(std::unique_ptr<MaterializationResponsibility> R,
- ThreadSafeModule TSM) override;
+ void emit(std::unique_ptr<MaterializationResponsibility> R,
+ ThreadSafeModule TSM) override;
static ThreadSafeModule identityTransform(ThreadSafeModule TSM,
MaterializationResponsibility &R) {
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
index f262d603f4..1ba1a2945d 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
@@ -69,33 +69,33 @@ public:
JITTargetAddress TrampolineAddr,
NotifyLandingResolvedFunction OnLandingResolved) const>;
- virtual ~TrampolinePool();
+ virtual ~TrampolinePool();
/// Get an available trampoline address.
/// Returns an error if no trampoline can be created.
- Expected<JITTargetAddress> getTrampoline() {
- std::lock_guard<std::mutex> Lock(TPMutex);
- if (AvailableTrampolines.empty()) {
- if (auto Err = grow())
- return std::move(Err);
- }
- assert(!AvailableTrampolines.empty() && "Failed to grow trampoline pool");
- auto TrampolineAddr = AvailableTrampolines.back();
- AvailableTrampolines.pop_back();
- return TrampolineAddr;
- }
-
- /// Returns the given trampoline to the pool for re-use.
- void releaseTrampoline(JITTargetAddress TrampolineAddr) {
- std::lock_guard<std::mutex> Lock(TPMutex);
- AvailableTrampolines.push_back(TrampolineAddr);
- }
-
-protected:
- virtual Error grow() = 0;
-
- std::mutex TPMutex;
- std::vector<JITTargetAddress> AvailableTrampolines;
+ Expected<JITTargetAddress> getTrampoline() {
+ std::lock_guard<std::mutex> Lock(TPMutex);
+ if (AvailableTrampolines.empty()) {
+ if (auto Err = grow())
+ return std::move(Err);
+ }
+ assert(!AvailableTrampolines.empty() && "Failed to grow trampoline pool");
+ auto TrampolineAddr = AvailableTrampolines.back();
+ AvailableTrampolines.pop_back();
+ return TrampolineAddr;
+ }
+
+ /// Returns the given trampoline to the pool for re-use.
+ void releaseTrampoline(JITTargetAddress TrampolineAddr) {
+ std::lock_guard<std::mutex> Lock(TPMutex);
+ AvailableTrampolines.push_back(TrampolineAddr);
+ }
+
+protected:
+ virtual Error grow() = 0;
+
+ std::mutex TPMutex;
+ std::vector<JITTargetAddress> AvailableTrampolines;
};
/// A trampoline pool for trampolines within the current process.
@@ -160,8 +160,8 @@ private:
}
}
- Error grow() override {
- assert(AvailableTrampolines.empty() && "Growing prematurely?");
+ Error grow() override {
+ assert(AvailableTrampolines.empty() && "Growing prematurely?");
std::error_code EC;
auto TrampolineBlock =
@@ -181,7 +181,7 @@ private:
pointerToJITTargetAddress(ResolverBlock.base()), NumTrampolines);
for (unsigned I = 0; I < NumTrampolines; ++I)
- AvailableTrampolines.push_back(pointerToJITTargetAddress(
+ AvailableTrampolines.push_back(pointerToJITTargetAddress(
TrampolineMem + (I * ORCABI::TrampolineSize)));
if (auto EC = sys::Memory::protectMappedMemory(
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/LLJIT.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/LLJIT.h
index 565340c68e..d27b2d3036 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/LLJIT.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/LLJIT.h
@@ -35,8 +35,8 @@ namespace orc {
class LLJITBuilderState;
class LLLazyJITBuilderState;
-class ObjectTransformLayer;
-class TargetProcessControl;
+class ObjectTransformLayer;
+class TargetProcessControl;
/// A pre-fabricated ORC JIT stack that can serve as an alternative to MCJIT.
///
@@ -93,8 +93,8 @@ public:
return ES->createJITDylib(std::move(Name));
}
- /// Adds an IR module with the given ResourceTracker.
- Error addIRModule(ResourceTrackerSP RT, ThreadSafeModule TSM);
+ /// Adds an IR module with the given ResourceTracker.
+ Error addIRModule(ResourceTrackerSP RT, ThreadSafeModule TSM);
/// Adds an IR module to the given JITDylib.
Error addIRModule(JITDylib &JD, ThreadSafeModule TSM);
@@ -105,9 +105,9 @@ public:
}
/// Adds an object file to the given JITDylib.
- Error addObjectFile(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> Obj);
-
- /// Adds an object file to the given JITDylib.
+ Error addObjectFile(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> Obj);
+
+ /// Adds an object file to the given JITDylib.
Error addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj);
/// Adds an object file to the given JITDylib.
@@ -176,7 +176,7 @@ public:
ObjectLayer &getObjLinkingLayer() { return *ObjLinkingLayer; }
/// Returns a reference to the object transform layer.
- ObjectTransformLayer &getObjTransformLayer() { return *ObjTransformLayer; }
+ ObjectTransformLayer &getObjTransformLayer() { return *ObjTransformLayer; }
/// Returns a reference to the IR transform layer.
IRTransformLayer &getIRTransformLayer() { return *TransformLayer; }
@@ -193,7 +193,7 @@ public:
}
protected:
- static Expected<std::unique_ptr<ObjectLayer>>
+ static Expected<std::unique_ptr<ObjectLayer>>
createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES);
static Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>
@@ -216,7 +216,7 @@ protected:
std::unique_ptr<ThreadPool> CompileThreads;
std::unique_ptr<ObjectLayer> ObjLinkingLayer;
- std::unique_ptr<ObjectTransformLayer> ObjTransformLayer;
+ std::unique_ptr<ObjectTransformLayer> ObjTransformLayer;
std::unique_ptr<IRCompileLayer> CompileLayer;
std::unique_ptr<IRTransformLayer> TransformLayer;
std::unique_ptr<IRTransformLayer> InitHelperTransformLayer;
@@ -235,9 +235,9 @@ public:
CODLayer->setPartitionFunction(std::move(Partition));
}
- /// Returns a reference to the on-demand layer.
- CompileOnDemandLayer &getCompileOnDemandLayer() { return *CODLayer; }
-
+ /// Returns a reference to the on-demand layer.
+ CompileOnDemandLayer &getCompileOnDemandLayer() { return *CODLayer; }
+
/// Add a module to be lazily compiled to JITDylib JD.
Error addLazyIRModule(JITDylib &JD, ThreadSafeModule M);
@@ -257,9 +257,9 @@ private:
class LLJITBuilderState {
public:
- using ObjectLinkingLayerCreator =
- std::function<Expected<std::unique_ptr<ObjectLayer>>(ExecutionSession &,
- const Triple &)>;
+ using ObjectLinkingLayerCreator =
+ std::function<Expected<std::unique_ptr<ObjectLayer>>(ExecutionSession &,
+ const Triple &)>;
using CompileFunctionCreator =
std::function<Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>(
@@ -274,7 +274,7 @@ public:
CompileFunctionCreator CreateCompileFunction;
PlatformSetupFunction SetUpPlatform;
unsigned NumCompileThreads = 0;
- TargetProcessControl *TPC = nullptr;
+ TargetProcessControl *TPC = nullptr;
/// Called prior to JIT class construcion to fix up defaults.
Error prepareForConstruction();
@@ -357,17 +357,17 @@ public:
return impl();
}
- /// Set a TargetProcessControl object.
- ///
- /// If the platform uses ObjectLinkingLayer by default and no
- /// ObjectLinkingLayerCreator has been set then the TargetProcessControl
- /// object will be used to supply the memory manager for the
- /// ObjectLinkingLayer.
- SetterImpl &setTargetProcessControl(TargetProcessControl &TPC) {
- impl().TPC = &TPC;
- return impl();
- }
-
+ /// Set a TargetProcessControl object.
+ ///
+ /// If the platform uses ObjectLinkingLayer by default and no
+ /// ObjectLinkingLayerCreator has been set then the TargetProcessControl
+ /// object will be used to supply the memory manager for the
+ /// ObjectLinkingLayer.
+ SetterImpl &setTargetProcessControl(TargetProcessControl &TPC) {
+ impl().TPC = &TPC;
+ return impl();
+ }
+
/// Create an instance of the JIT.
Expected<std::unique_ptr<JITType>> create() {
if (auto Err = impl().prepareForConstruction())
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Layer.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Layer.h
index 7fe794009d..3d315e52f4 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Layer.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Layer.h
@@ -41,15 +41,15 @@ public:
/// SymbolFlags and SymbolToDefinition maps.
IRMaterializationUnit(ExecutionSession &ES,
const IRSymbolMapper::ManglingOptions &MO,
- ThreadSafeModule TSM);
+ ThreadSafeModule TSM);
/// 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(ThreadSafeModule TSM, SymbolFlagsMap SymbolFlags,
- SymbolStringPtr InitSymbol,
+ IRMaterializationUnit(ThreadSafeModule TSM, SymbolFlagsMap SymbolFlags,
+ SymbolStringPtr InitSymbol,
SymbolNameToDefinitionMap SymbolToDefinition);
/// Return the ModuleIdentifier as the name for this MaterializationUnit.
@@ -101,19 +101,19 @@ public:
/// Returns the current value of the CloneToNewContextOnEmit flag.
bool getCloneToNewContextOnEmit() const { return CloneToNewContextOnEmit; }
- /// Add a MaterializatinoUnit representing the given IR to the JITDylib
- /// targeted by the given tracker.
- virtual Error add(ResourceTrackerSP RT, ThreadSafeModule TSM);
-
+ /// Add a MaterializatinoUnit representing the given IR to the JITDylib
+ /// targeted by the given tracker.
+ virtual Error add(ResourceTrackerSP RT, ThreadSafeModule TSM);
+
/// Adds a MaterializationUnit representing the given IR to the given
- /// JITDylib. If RT is not specif
- Error add(JITDylib &JD, ThreadSafeModule TSM) {
- return add(JD.getDefaultResourceTracker(), std::move(TSM));
- }
+ /// JITDylib. If RT is not specif
+ Error add(JITDylib &JD, ThreadSafeModule TSM) {
+ return add(JD.getDefaultResourceTracker(), std::move(TSM));
+ }
/// Emit should materialize the given IR.
- virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
- ThreadSafeModule TSM) = 0;
+ virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
+ ThreadSafeModule TSM) = 0;
private:
bool CloneToNewContextOnEmit = false;
@@ -127,10 +127,10 @@ class BasicIRLayerMaterializationUnit : public IRMaterializationUnit {
public:
BasicIRLayerMaterializationUnit(IRLayer &L,
const IRSymbolMapper::ManglingOptions &MO,
- ThreadSafeModule TSM);
+ ThreadSafeModule TSM);
private:
- void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
+ void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
IRLayer &L;
};
@@ -146,14 +146,14 @@ public:
/// Adds a MaterializationUnit representing the given IR to the given
/// JITDylib.
- virtual Error add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O);
+ virtual Error add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O);
+
+ Error add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O) {
+ return add(JD.getDefaultResourceTracker(), std::move(O));
+ }
- Error add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O) {
- return add(JD.getDefaultResourceTracker(), std::move(O));
- }
-
/// Emit should materialize the given IR.
- virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
+ virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
std::unique_ptr<MemoryBuffer> O) = 0;
private:
@@ -165,9 +165,9 @@ private:
class BasicObjectLayerMaterializationUnit : public MaterializationUnit {
public:
static Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>>
- Create(ObjectLayer &L, std::unique_ptr<MemoryBuffer> O);
+ Create(ObjectLayer &L, std::unique_ptr<MemoryBuffer> O);
- BasicObjectLayerMaterializationUnit(ObjectLayer &L,
+ BasicObjectLayerMaterializationUnit(ObjectLayer &L,
std::unique_ptr<MemoryBuffer> O,
SymbolFlagsMap SymbolFlags,
SymbolStringPtr InitSymbol);
@@ -176,7 +176,7 @@ public:
StringRef getName() const override;
private:
- void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
+ void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
ObjectLayer &L;
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/LazyReexports.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/LazyReexports.h
index 4f4d089463..71b5831d32 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/LazyReexports.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/LazyReexports.h
@@ -47,9 +47,9 @@ public:
using NotifyResolvedFunction =
unique_function<Error(JITTargetAddress ResolvedAddr)>;
- LazyCallThroughManager(ExecutionSession &ES,
- JITTargetAddress ErrorHandlerAddr, TrampolinePool *TP);
-
+ LazyCallThroughManager(ExecutionSession &ES,
+ JITTargetAddress ErrorHandlerAddr, TrampolinePool *TP);
+
// Return a free call-through trampoline and bind it to look up and call
// through to the given symbol.
Expected<JITTargetAddress>
@@ -151,12 +151,12 @@ public:
IndirectStubsManager &ISManager,
JITDylib &SourceJD,
SymbolAliasMap CallableAliases,
- ImplSymbolMap *SrcJDLoc);
+ ImplSymbolMap *SrcJDLoc);
StringRef getName() const override;
private:
- void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
+ void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases);
@@ -173,10 +173,10 @@ private:
inline std::unique_ptr<LazyReexportsMaterializationUnit>
lazyReexports(LazyCallThroughManager &LCTManager,
IndirectStubsManager &ISManager, JITDylib &SourceJD,
- SymbolAliasMap CallableAliases,
- ImplSymbolMap *SrcJDLoc = nullptr) {
+ SymbolAliasMap CallableAliases,
+ ImplSymbolMap *SrcJDLoc = nullptr) {
return std::make_unique<LazyReexportsMaterializationUnit>(
- LCTManager, ISManager, SourceJD, std::move(CallableAliases), SrcJDLoc);
+ LCTManager, ISManager, SourceJD, std::move(CallableAliases), SrcJDLoc);
}
} // End namespace orc
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/MachOPlatform.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
index 997a0aca6e..6e83f86621 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
@@ -105,9 +105,9 @@ public:
ExecutionSession &getExecutionSession() const { return ES; }
Error setupJITDylib(JITDylib &JD) override;
- Error notifyAdding(ResourceTracker &RT,
- const MaterializationUnit &MU) override;
- Error notifyRemoving(ResourceTracker &RT) override;
+ Error notifyAdding(ResourceTracker &RT,
+ const MaterializationUnit &MU) override;
+ Error notifyRemoving(ResourceTracker &RT) override;
Expected<InitializerSequence> getInitializerSequence(JITDylib &JD);
@@ -127,19 +127,19 @@ private:
LocalDependenciesMap getSyntheticSymbolLocalDependencies(
MaterializationResponsibility &MR) override;
- // FIXME: We should be tentatively tracking scraped sections and discarding
- // if the MR fails.
- Error notifyFailed(MaterializationResponsibility &MR) override {
- return Error::success();
- }
-
- Error notifyRemovingResources(ResourceKey K) override {
- return Error::success();
- }
-
- void notifyTransferringResources(ResourceKey DstKey,
- ResourceKey SrcKey) override {}
-
+ // FIXME: We should be tentatively tracking scraped sections and discarding
+ // if the MR fails.
+ Error notifyFailed(MaterializationResponsibility &MR) override {
+ return Error::success();
+ }
+
+ Error notifyRemovingResources(ResourceKey K) override {
+ return Error::success();
+ }
+
+ void notifyTransferringResources(ResourceKey DstKey,
+ ResourceKey SrcKey) override {}
+
private:
using InitSymbolDepMap =
DenseMap<MaterializationResponsibility *, JITLinkSymbolVector>;
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
index 0c16ece95a..f9aa582b31 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
@@ -42,7 +42,7 @@ namespace llvm {
namespace jitlink {
class EHFrameRegistrar;
-class LinkGraph;
+class LinkGraph;
class Symbol;
} // namespace jitlink
@@ -59,7 +59,7 @@ class ObjectLinkingLayerJITLinkContext;
/// Clients can use this class to add relocatable object files to an
/// ExecutionSession, and it typically serves as the base layer (underneath
/// a compiling layer like IRCompileLayer) for the rest of the JIT.
-class ObjectLinkingLayer : public ObjectLayer, private ResourceManager {
+class ObjectLinkingLayer : public ObjectLayer, private ResourceManager {
friend class ObjectLinkingLayerJITLinkContext;
public:
@@ -80,10 +80,10 @@ public:
virtual Error notifyEmitted(MaterializationResponsibility &MR) {
return Error::success();
}
- virtual Error notifyFailed(MaterializationResponsibility &MR) = 0;
- virtual Error notifyRemovingResources(ResourceKey K) = 0;
- virtual void notifyTransferringResources(ResourceKey DstKey,
- ResourceKey SrcKey) = 0;
+ virtual Error notifyFailed(MaterializationResponsibility &MR) = 0;
+ virtual Error notifyRemovingResources(ResourceKey K) = 0;
+ virtual void notifyTransferringResources(ResourceKey DstKey,
+ ResourceKey SrcKey) = 0;
/// Return any dependencies that synthetic symbols (e.g. init symbols)
/// have on locally scoped jitlink::Symbols. This is used by the
@@ -98,15 +98,15 @@ public:
using ReturnObjectBufferFunction =
std::function<void(std::unique_ptr<MemoryBuffer>)>;
- /// Construct an ObjectLinkingLayer.
+ /// Construct an ObjectLinkingLayer.
+ ObjectLinkingLayer(ExecutionSession &ES,
+ jitlink::JITLinkMemoryManager &MemMgr);
+
+ /// Construct an ObjectLinkingLayer. Takes ownership of the given
+ /// JITLinkMemoryManager. This method is a temporary hack to simplify
+ /// co-existence with RTDyldObjectLinkingLayer (which also owns its
+ /// allocators).
ObjectLinkingLayer(ExecutionSession &ES,
- jitlink::JITLinkMemoryManager &MemMgr);
-
- /// Construct an ObjectLinkingLayer. Takes ownership of the given
- /// JITLinkMemoryManager. This method is a temporary hack to simplify
- /// co-existence with RTDyldObjectLinkingLayer (which also owns its
- /// allocators).
- ObjectLinkingLayer(ExecutionSession &ES,
std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr);
/// Destruct an ObjectLinkingLayer.
@@ -126,14 +126,14 @@ public:
return *this;
}
- /// Emit an object file.
- void emit(std::unique_ptr<MaterializationResponsibility> R,
+ /// Emit an object file.
+ void emit(std::unique_ptr<MaterializationResponsibility> R,
std::unique_ptr<MemoryBuffer> O) override;
- /// Emit a LinkGraph.
- void emit(std::unique_ptr<MaterializationResponsibility> R,
- std::unique_ptr<jitlink::LinkGraph> G);
-
+ /// Emit a LinkGraph.
+ void emit(std::unique_ptr<MaterializationResponsibility> R,
+ std::unique_ptr<jitlink::LinkGraph> G);
+
/// Instructs this ObjectLinkingLayer instance to override the symbol flags
/// found in the AtomGraph with the flags supplied by the
/// MaterializationResponsibility instance. This is a workaround to support
@@ -173,31 +173,31 @@ private:
void notifyLoaded(MaterializationResponsibility &MR);
Error notifyEmitted(MaterializationResponsibility &MR, AllocPtr Alloc);
- Error handleRemoveResources(ResourceKey K) override;
- void handleTransferResources(ResourceKey DstKey, ResourceKey SrcKey) override;
+ Error handleRemoveResources(ResourceKey K) override;
+ void handleTransferResources(ResourceKey DstKey, ResourceKey SrcKey) override;
mutable std::mutex LayerMutex;
- jitlink::JITLinkMemoryManager &MemMgr;
- std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgrOwnership;
+ jitlink::JITLinkMemoryManager &MemMgr;
+ std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgrOwnership;
bool OverrideObjectFlags = false;
bool AutoClaimObjectSymbols = false;
ReturnObjectBufferFunction ReturnObjectBuffer;
- DenseMap<ResourceKey, std::vector<AllocPtr>> Allocs;
+ DenseMap<ResourceKey, std::vector<AllocPtr>> Allocs;
std::vector<std::unique_ptr<Plugin>> Plugins;
};
class EHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin {
public:
- EHFrameRegistrationPlugin(
- ExecutionSession &ES,
- std::unique_ptr<jitlink::EHFrameRegistrar> Registrar);
+ EHFrameRegistrationPlugin(
+ ExecutionSession &ES,
+ std::unique_ptr<jitlink::EHFrameRegistrar> Registrar);
void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
jitlink::PassConfiguration &PassConfig) override;
- Error notifyEmitted(MaterializationResponsibility &MR) override;
- Error notifyFailed(MaterializationResponsibility &MR) override;
- Error notifyRemovingResources(ResourceKey K) override;
- void notifyTransferringResources(ResourceKey DstKey,
- ResourceKey SrcKey) override;
+ Error notifyEmitted(MaterializationResponsibility &MR) override;
+ Error notifyFailed(MaterializationResponsibility &MR) override;
+ Error notifyRemovingResources(ResourceKey K) override;
+ void notifyTransferringResources(ResourceKey DstKey,
+ ResourceKey SrcKey) override;
private:
@@ -207,10 +207,10 @@ private:
};
std::mutex EHFramePluginMutex;
- ExecutionSession &ES;
- std::unique_ptr<jitlink::EHFrameRegistrar> Registrar;
+ ExecutionSession &ES;
+ std::unique_ptr<jitlink::EHFrameRegistrar> Registrar;
DenseMap<MaterializationResponsibility *, EHFrameRange> InProcessLinks;
- DenseMap<ResourceKey, std::vector<EHFrameRange>> EHFrameRanges;
+ DenseMap<ResourceKey, std::vector<EHFrameRange>> EHFrameRanges;
};
} // end namespace orc
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h
index e1ec55031b..d37ff22757 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h
@@ -38,7 +38,7 @@ public:
ObjectTransformLayer(ExecutionSession &ES, ObjectLayer &BaseLayer,
TransformFunction Transform = TransformFunction());
- void emit(std::unique_ptr<MaterializationResponsibility> R,
+ void emit(std::unique_ptr<MaterializationResponsibility> R,
std::unique_ptr<MemoryBuffer> O) override;
void setTransform(TransformFunction Transform) {
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRPCTargetProcessControl.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRPCTargetProcessControl.h
index 80142adcdf..1b6578db1c 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRPCTargetProcessControl.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRPCTargetProcessControl.h
@@ -1,426 +1,426 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===--- OrcRPCTargetProcessControl.h - Remote target control ---*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Utilities for interacting with target processes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_ORCRPCTARGETPROCESSCONTROL_H
-#define LLVM_EXECUTIONENGINE_ORC_ORCRPCTARGETPROCESSCONTROL_H
-
-#include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h"
-#include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h"
-#include "llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h"
-#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
-#include "llvm/Support/MSVCErrorWorkarounds.h"
-
-namespace llvm {
-namespace orc {
-
-/// JITLinkMemoryManager implementation for a process connected via an ORC RPC
-/// endpoint.
-template <typename OrcRPCTPCImplT>
-class OrcRPCTPCJITLinkMemoryManager : public jitlink::JITLinkMemoryManager {
-private:
- struct HostAlloc {
- std::unique_ptr<char[]> Mem;
- uint64_t Size;
- };
-
- struct TargetAlloc {
- JITTargetAddress Address = 0;
- uint64_t AllocatedSize = 0;
- };
-
- using HostAllocMap = DenseMap<int, HostAlloc>;
- using TargetAllocMap = DenseMap<int, TargetAlloc>;
-
-public:
- class OrcRPCAllocation : public Allocation {
- public:
- OrcRPCAllocation(OrcRPCTPCJITLinkMemoryManager<OrcRPCTPCImplT> &Parent,
- HostAllocMap HostAllocs, TargetAllocMap TargetAllocs)
- : Parent(Parent), HostAllocs(std::move(HostAllocs)),
- TargetAllocs(std::move(TargetAllocs)) {
- assert(HostAllocs.size() == TargetAllocs.size() &&
- "HostAllocs size should match TargetAllocs");
- }
-
- ~OrcRPCAllocation() override {
- assert(TargetAllocs.empty() && "failed to deallocate");
- }
-
- MutableArrayRef<char> getWorkingMemory(ProtectionFlags Seg) override {
- auto I = HostAllocs.find(Seg);
- assert(I != HostAllocs.end() && "No host allocation for segment");
- auto &HA = I->second;
- return {HA.Mem.get(), static_cast<size_t>(HA.Size)};
- }
-
- JITTargetAddress getTargetMemory(ProtectionFlags Seg) override {
- auto I = TargetAllocs.find(Seg);
- assert(I != TargetAllocs.end() && "No target allocation for segment");
- return I->second.Address;
- }
-
- void finalizeAsync(FinalizeContinuation OnFinalize) override {
-
- std::vector<tpctypes::BufferWrite> BufferWrites;
- orcrpctpc::ReleaseOrFinalizeMemRequest FMR;
-
- for (auto &KV : HostAllocs) {
- assert(TargetAllocs.count(KV.first) &&
- "No target allocation for buffer");
- auto &HA = KV.second;
- auto &TA = TargetAllocs[KV.first];
- BufferWrites.push_back({TA.Address, StringRef(HA.Mem.get(), HA.Size)});
- FMR.push_back({orcrpctpc::toWireProtectionFlags(
- static_cast<sys::Memory::ProtectionFlags>(KV.first)),
- TA.Address, TA.AllocatedSize});
- }
-
- DEBUG_WITH_TYPE("orc", {
- dbgs() << "finalizeAsync " << (void *)this << ":\n";
- auto FMRI = FMR.begin();
- for (auto &B : BufferWrites) {
- auto Prot = FMRI->Prot;
- ++FMRI;
- dbgs() << " Writing " << formatv("{0:x16}", B.Buffer.size())
- << " bytes to " << ((Prot & orcrpctpc::WPF_Read) ? 'R' : '-')
- << ((Prot & orcrpctpc::WPF_Write) ? 'W' : '-')
- << ((Prot & orcrpctpc::WPF_Exec) ? 'X' : '-')
- << " segment: local " << (const void *)B.Buffer.data()
- << " -> target " << formatv("{0:x16}", B.Address) << "\n";
- }
- });
- if (auto Err =
- Parent.Parent.getMemoryAccess().writeBuffers(BufferWrites)) {
- OnFinalize(std::move(Err));
- return;
- }
-
- DEBUG_WITH_TYPE("orc", dbgs() << " Applying permissions...\n");
- if (auto Err =
- Parent.getEndpoint().template callAsync<orcrpctpc::FinalizeMem>(
- [OF = std::move(OnFinalize)](Error Err2) {
- // FIXME: Dispatch to work queue.
- std::thread([OF = std::move(OF),
- Err3 = std::move(Err2)]() mutable {
- DEBUG_WITH_TYPE(
- "orc", { dbgs() << " finalizeAsync complete\n"; });
- OF(std::move(Err3));
- }).detach();
- return Error::success();
- },
- FMR)) {
- DEBUG_WITH_TYPE("orc", dbgs() << " failed.\n");
- Parent.getEndpoint().abandonPendingResponses();
- Parent.reportError(std::move(Err));
- }
- DEBUG_WITH_TYPE("orc", {
- dbgs() << "Leaving finalizeAsync (finalization may continue in "
- "background)\n";
- });
- }
-
- Error deallocate() override {
- orcrpctpc::ReleaseOrFinalizeMemRequest RMR;
- for (auto &KV : TargetAllocs)
- RMR.push_back({orcrpctpc::toWireProtectionFlags(
- static_cast<sys::Memory::ProtectionFlags>(KV.first)),
- KV.second.Address, KV.second.AllocatedSize});
- TargetAllocs.clear();
-
- return Parent.getEndpoint().template callB<orcrpctpc::ReleaseMem>(RMR);
- }
-
- private:
- OrcRPCTPCJITLinkMemoryManager<OrcRPCTPCImplT> &Parent;
- HostAllocMap HostAllocs;
- TargetAllocMap TargetAllocs;
- };
-
- OrcRPCTPCJITLinkMemoryManager(OrcRPCTPCImplT &Parent) : Parent(Parent) {}
-
- Expected<std::unique_ptr<Allocation>>
- allocate(const jitlink::JITLinkDylib *JD,
- const SegmentsRequestMap &Request) override {
- orcrpctpc::ReserveMemRequest RMR;
- HostAllocMap HostAllocs;
-
- for (auto &KV : Request) {
- assert(KV.second.getContentSize() <= std::numeric_limits<size_t>::max() &&
- "Content size is out-of-range for host");
-
- RMR.push_back({orcrpctpc::toWireProtectionFlags(
- static_cast<sys::Memory::ProtectionFlags>(KV.first)),
- KV.second.getContentSize() + KV.second.getZeroFillSize(),
- KV.second.getAlignment()});
- HostAllocs[KV.first] = {
- std::make_unique<char[]>(KV.second.getContentSize()),
- KV.second.getContentSize()};
- }
-
- DEBUG_WITH_TYPE("orc", {
- dbgs() << "Orc remote memmgr got request:\n";
- for (auto &KV : Request)
- dbgs() << " permissions: "
- << ((KV.first & sys::Memory::MF_READ) ? 'R' : '-')
- << ((KV.first & sys::Memory::MF_WRITE) ? 'W' : '-')
- << ((KV.first & sys::Memory::MF_EXEC) ? 'X' : '-')
- << ", content size: "
- << formatv("{0:x16}", KV.second.getContentSize())
- << " + zero-fill-size: "
- << formatv("{0:x16}", KV.second.getZeroFillSize())
- << ", align: " << KV.second.getAlignment() << "\n";
- });
-
- // FIXME: LLVM RPC needs to be fixed to support alt
- // serialization/deserialization on return types. For now just
- // translate from std::map to DenseMap manually.
- auto TmpTargetAllocs =
- Parent.getEndpoint().template callB<orcrpctpc::ReserveMem>(RMR);
- if (!TmpTargetAllocs)
- return TmpTargetAllocs.takeError();
-
- if (TmpTargetAllocs->size() != RMR.size())
- return make_error<StringError>(
- "Number of target allocations does not match request",
- inconvertibleErrorCode());
-
- TargetAllocMap TargetAllocs;
- for (auto &E : *TmpTargetAllocs)
- TargetAllocs[orcrpctpc::fromWireProtectionFlags(E.Prot)] = {
- E.Address, E.AllocatedSize};
-
- DEBUG_WITH_TYPE("orc", {
- auto HAI = HostAllocs.begin();
- for (auto &KV : TargetAllocs)
- dbgs() << " permissions: "
- << ((KV.first & sys::Memory::MF_READ) ? 'R' : '-')
- << ((KV.first & sys::Memory::MF_WRITE) ? 'W' : '-')
- << ((KV.first & sys::Memory::MF_EXEC) ? 'X' : '-')
- << " assigned local " << (void *)HAI->second.Mem.get()
- << ", target " << formatv("{0:x16}", KV.second.Address) << "\n";
- });
-
- return std::make_unique<OrcRPCAllocation>(*this, std::move(HostAllocs),
- std::move(TargetAllocs));
- }
-
-private:
- void reportError(Error Err) { Parent.reportError(std::move(Err)); }
-
- decltype(std::declval<OrcRPCTPCImplT>().getEndpoint()) getEndpoint() {
- return Parent.getEndpoint();
- }
-
- OrcRPCTPCImplT &Parent;
-};
-
-/// TargetProcessControl::MemoryAccess implementation for a process connected
-/// via an ORC RPC endpoint.
-template <typename OrcRPCTPCImplT>
-class OrcRPCTPCMemoryAccess : public TargetProcessControl::MemoryAccess {
-public:
- OrcRPCTPCMemoryAccess(OrcRPCTPCImplT &Parent) : Parent(Parent) {}
-
- void writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws,
- WriteResultFn OnWriteComplete) override {
- writeViaRPC<orcrpctpc::WriteUInt8s>(Ws, std::move(OnWriteComplete));
- }
-
- void writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws,
- WriteResultFn OnWriteComplete) override {
- writeViaRPC<orcrpctpc::WriteUInt16s>(Ws, std::move(OnWriteComplete));
- }
-
- void writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws,
- WriteResultFn OnWriteComplete) override {
- writeViaRPC<orcrpctpc::WriteUInt32s>(Ws, std::move(OnWriteComplete));
- }
-
- void writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws,
- WriteResultFn OnWriteComplete) override {
- writeViaRPC<orcrpctpc::WriteUInt64s>(Ws, std::move(OnWriteComplete));
- }
-
- void writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws,
- WriteResultFn OnWriteComplete) override {
- writeViaRPC<orcrpctpc::WriteBuffers>(Ws, std::move(OnWriteComplete));
- }
-
-private:
- template <typename WriteRPCFunction, typename WriteElementT>
- void writeViaRPC(ArrayRef<WriteElementT> Ws, WriteResultFn OnWriteComplete) {
- if (auto Err = Parent.getEndpoint().template callAsync<WriteRPCFunction>(
- [OWC = std::move(OnWriteComplete)](Error Err2) mutable -> Error {
- OWC(std::move(Err2));
- return Error::success();
- },
- Ws)) {
- Parent.reportError(std::move(Err));
- Parent.getEndpoint().abandonPendingResponses();
- }
- }
-
- OrcRPCTPCImplT &Parent;
-};
-
-// TargetProcessControl for a process connected via an ORC RPC Endpoint.
-template <typename RPCEndpointT>
-class OrcRPCTargetProcessControlBase : public TargetProcessControl {
-public:
- using ErrorReporter = unique_function<void(Error)>;
-
- using OnCloseConnectionFunction = unique_function<Error(Error)>;
-
- OrcRPCTargetProcessControlBase(std::shared_ptr<SymbolStringPool> SSP,
- RPCEndpointT &EP, ErrorReporter ReportError)
- : TargetProcessControl(std::move(SSP)),
- ReportError(std::move(ReportError)), EP(EP) {}
-
- void reportError(Error Err) { ReportError(std::move(Err)); }
-
- RPCEndpointT &getEndpoint() { return EP; }
-
- Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override {
- DEBUG_WITH_TYPE("orc", {
- dbgs() << "Loading dylib \"" << (DylibPath ? DylibPath : "") << "\" ";
- if (!DylibPath)
- dbgs() << "(process symbols)";
- dbgs() << "\n";
- });
- if (!DylibPath)
- DylibPath = "";
- auto H = EP.template callB<orcrpctpc::LoadDylib>(DylibPath);
- DEBUG_WITH_TYPE("orc", {
- if (H)
- dbgs() << " got handle " << formatv("{0:x16}", *H) << "\n";
- else
- dbgs() << " error, unable to load\n";
- });
- return H;
- }
-
- Expected<std::vector<tpctypes::LookupResult>>
- lookupSymbols(ArrayRef<LookupRequest> Request) override {
- std::vector<orcrpctpc::RemoteLookupRequest> RR;
- for (auto &E : Request) {
- RR.push_back({});
- RR.back().first = E.Handle;
- for (auto &KV : E.Symbols)
- RR.back().second.push_back(
- {(*KV.first).str(),
- KV.second == SymbolLookupFlags::WeaklyReferencedSymbol});
- }
- DEBUG_WITH_TYPE("orc", {
- dbgs() << "Compound lookup:\n";
- for (auto &R : Request) {
- dbgs() << " In " << formatv("{0:x16}", R.Handle) << ": {";
- bool First = true;
- for (auto &KV : R.Symbols) {
- dbgs() << (First ? "" : ",") << " " << *KV.first;
- First = false;
- }
- dbgs() << " }\n";
- }
- });
- return EP.template callB<orcrpctpc::LookupSymbols>(RR);
- }
-
- Expected<int32_t> runAsMain(JITTargetAddress MainFnAddr,
- ArrayRef<std::string> Args) override {
- DEBUG_WITH_TYPE("orc", {
- dbgs() << "Running as main: " << formatv("{0:x16}", MainFnAddr)
- << ", args = [";
- for (unsigned I = 0; I != Args.size(); ++I)
- dbgs() << (I ? "," : "") << " \"" << Args[I] << "\"";
- dbgs() << "]\n";
- });
- auto Result = EP.template callB<orcrpctpc::RunMain>(MainFnAddr, Args);
- DEBUG_WITH_TYPE("orc", {
- dbgs() << " call to " << formatv("{0:x16}", MainFnAddr);
- if (Result)
- dbgs() << " returned result " << *Result << "\n";
- else
- dbgs() << " failed\n";
- });
- return Result;
- }
-
- Expected<tpctypes::WrapperFunctionResult>
- runWrapper(JITTargetAddress WrapperFnAddr,
- ArrayRef<uint8_t> ArgBuffer) override {
- DEBUG_WITH_TYPE("orc", {
- dbgs() << "Running as wrapper function "
- << formatv("{0:x16}", WrapperFnAddr) << " with "
- << formatv("{0:x16}", ArgBuffer.size()) << " argument buffer\n";
- });
- auto Result =
- EP.template callB<orcrpctpc::RunWrapper>(WrapperFnAddr, ArgBuffer);
- // dbgs() << "Returned from runWrapper...\n";
- return Result;
- }
-
- Error closeConnection(OnCloseConnectionFunction OnCloseConnection) {
- DEBUG_WITH_TYPE("orc", dbgs() << "Closing connection to remote\n");
- return EP.template callAsync<orcrpctpc::CloseConnection>(
- std::move(OnCloseConnection));
- }
-
- Error closeConnectionAndWait() {
- std::promise<MSVCPError> P;
- auto F = P.get_future();
- if (auto Err = closeConnection([&](Error Err2) -> Error {
- P.set_value(std::move(Err2));
- return Error::success();
- })) {
- EP.abandonAllPendingResponses();
- return joinErrors(std::move(Err), F.get());
- }
- return F.get();
- }
-
-protected:
- /// Subclasses must call this during construction to initialize the
- /// TargetTriple and PageSize members.
- Error initializeORCRPCTPCBase() {
- if (auto TripleOrErr = EP.template callB<orcrpctpc::GetTargetTriple>())
- TargetTriple = Triple(*TripleOrErr);
- else
- return TripleOrErr.takeError();
-
- if (auto PageSizeOrErr = EP.template callB<orcrpctpc::GetPageSize>())
- PageSize = *PageSizeOrErr;
- else
- return PageSizeOrErr.takeError();
-
- return Error::success();
- }
-
-private:
- ErrorReporter ReportError;
- RPCEndpointT &EP;
-};
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_ORCRPCTARGETPROCESSCONTROL_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===--- OrcRPCTargetProcessControl.h - Remote target control ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities for interacting with target processes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_ORCRPCTARGETPROCESSCONTROL_H
+#define LLVM_EXECUTIONENGINE_ORC_ORCRPCTARGETPROCESSCONTROL_H
+
+#include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h"
+#include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
+#include "llvm/Support/MSVCErrorWorkarounds.h"
+
+namespace llvm {
+namespace orc {
+
+/// JITLinkMemoryManager implementation for a process connected via an ORC RPC
+/// endpoint.
+template <typename OrcRPCTPCImplT>
+class OrcRPCTPCJITLinkMemoryManager : public jitlink::JITLinkMemoryManager {
+private:
+ struct HostAlloc {
+ std::unique_ptr<char[]> Mem;
+ uint64_t Size;
+ };
+
+ struct TargetAlloc {
+ JITTargetAddress Address = 0;
+ uint64_t AllocatedSize = 0;
+ };
+
+ using HostAllocMap = DenseMap<int, HostAlloc>;
+ using TargetAllocMap = DenseMap<int, TargetAlloc>;
+
+public:
+ class OrcRPCAllocation : public Allocation {
+ public:
+ OrcRPCAllocation(OrcRPCTPCJITLinkMemoryManager<OrcRPCTPCImplT> &Parent,
+ HostAllocMap HostAllocs, TargetAllocMap TargetAllocs)
+ : Parent(Parent), HostAllocs(std::move(HostAllocs)),
+ TargetAllocs(std::move(TargetAllocs)) {
+ assert(HostAllocs.size() == TargetAllocs.size() &&
+ "HostAllocs size should match TargetAllocs");
+ }
+
+ ~OrcRPCAllocation() override {
+ assert(TargetAllocs.empty() && "failed to deallocate");
+ }
+
+ MutableArrayRef<char> getWorkingMemory(ProtectionFlags Seg) override {
+ auto I = HostAllocs.find(Seg);
+ assert(I != HostAllocs.end() && "No host allocation for segment");
+ auto &HA = I->second;
+ return {HA.Mem.get(), static_cast<size_t>(HA.Size)};
+ }
+
+ JITTargetAddress getTargetMemory(ProtectionFlags Seg) override {
+ auto I = TargetAllocs.find(Seg);
+ assert(I != TargetAllocs.end() && "No target allocation for segment");
+ return I->second.Address;
+ }
+
+ void finalizeAsync(FinalizeContinuation OnFinalize) override {
+
+ std::vector<tpctypes::BufferWrite> BufferWrites;
+ orcrpctpc::ReleaseOrFinalizeMemRequest FMR;
+
+ for (auto &KV : HostAllocs) {
+ assert(TargetAllocs.count(KV.first) &&
+ "No target allocation for buffer");
+ auto &HA = KV.second;
+ auto &TA = TargetAllocs[KV.first];
+ BufferWrites.push_back({TA.Address, StringRef(HA.Mem.get(), HA.Size)});
+ FMR.push_back({orcrpctpc::toWireProtectionFlags(
+ static_cast<sys::Memory::ProtectionFlags>(KV.first)),
+ TA.Address, TA.AllocatedSize});
+ }
+
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "finalizeAsync " << (void *)this << ":\n";
+ auto FMRI = FMR.begin();
+ for (auto &B : BufferWrites) {
+ auto Prot = FMRI->Prot;
+ ++FMRI;
+ dbgs() << " Writing " << formatv("{0:x16}", B.Buffer.size())
+ << " bytes to " << ((Prot & orcrpctpc::WPF_Read) ? 'R' : '-')
+ << ((Prot & orcrpctpc::WPF_Write) ? 'W' : '-')
+ << ((Prot & orcrpctpc::WPF_Exec) ? 'X' : '-')
+ << " segment: local " << (const void *)B.Buffer.data()
+ << " -> target " << formatv("{0:x16}", B.Address) << "\n";
+ }
+ });
+ if (auto Err =
+ Parent.Parent.getMemoryAccess().writeBuffers(BufferWrites)) {
+ OnFinalize(std::move(Err));
+ return;
+ }
+
+ DEBUG_WITH_TYPE("orc", dbgs() << " Applying permissions...\n");
+ if (auto Err =
+ Parent.getEndpoint().template callAsync<orcrpctpc::FinalizeMem>(
+ [OF = std::move(OnFinalize)](Error Err2) {
+ // FIXME: Dispatch to work queue.
+ std::thread([OF = std::move(OF),
+ Err3 = std::move(Err2)]() mutable {
+ DEBUG_WITH_TYPE(
+ "orc", { dbgs() << " finalizeAsync complete\n"; });
+ OF(std::move(Err3));
+ }).detach();
+ return Error::success();
+ },
+ FMR)) {
+ DEBUG_WITH_TYPE("orc", dbgs() << " failed.\n");
+ Parent.getEndpoint().abandonPendingResponses();
+ Parent.reportError(std::move(Err));
+ }
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "Leaving finalizeAsync (finalization may continue in "
+ "background)\n";
+ });
+ }
+
+ Error deallocate() override {
+ orcrpctpc::ReleaseOrFinalizeMemRequest RMR;
+ for (auto &KV : TargetAllocs)
+ RMR.push_back({orcrpctpc::toWireProtectionFlags(
+ static_cast<sys::Memory::ProtectionFlags>(KV.first)),
+ KV.second.Address, KV.second.AllocatedSize});
+ TargetAllocs.clear();
+
+ return Parent.getEndpoint().template callB<orcrpctpc::ReleaseMem>(RMR);
+ }
+
+ private:
+ OrcRPCTPCJITLinkMemoryManager<OrcRPCTPCImplT> &Parent;
+ HostAllocMap HostAllocs;
+ TargetAllocMap TargetAllocs;
+ };
+
+ OrcRPCTPCJITLinkMemoryManager(OrcRPCTPCImplT &Parent) : Parent(Parent) {}
+
+ Expected<std::unique_ptr<Allocation>>
+ allocate(const jitlink::JITLinkDylib *JD,
+ const SegmentsRequestMap &Request) override {
+ orcrpctpc::ReserveMemRequest RMR;
+ HostAllocMap HostAllocs;
+
+ for (auto &KV : Request) {
+ assert(KV.second.getContentSize() <= std::numeric_limits<size_t>::max() &&
+ "Content size is out-of-range for host");
+
+ RMR.push_back({orcrpctpc::toWireProtectionFlags(
+ static_cast<sys::Memory::ProtectionFlags>(KV.first)),
+ KV.second.getContentSize() + KV.second.getZeroFillSize(),
+ KV.second.getAlignment()});
+ HostAllocs[KV.first] = {
+ std::make_unique<char[]>(KV.second.getContentSize()),
+ KV.second.getContentSize()};
+ }
+
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "Orc remote memmgr got request:\n";
+ for (auto &KV : Request)
+ dbgs() << " permissions: "
+ << ((KV.first & sys::Memory::MF_READ) ? 'R' : '-')
+ << ((KV.first & sys::Memory::MF_WRITE) ? 'W' : '-')
+ << ((KV.first & sys::Memory::MF_EXEC) ? 'X' : '-')
+ << ", content size: "
+ << formatv("{0:x16}", KV.second.getContentSize())
+ << " + zero-fill-size: "
+ << formatv("{0:x16}", KV.second.getZeroFillSize())
+ << ", align: " << KV.second.getAlignment() << "\n";
+ });
+
+ // FIXME: LLVM RPC needs to be fixed to support alt
+ // serialization/deserialization on return types. For now just
+ // translate from std::map to DenseMap manually.
+ auto TmpTargetAllocs =
+ Parent.getEndpoint().template callB<orcrpctpc::ReserveMem>(RMR);
+ if (!TmpTargetAllocs)
+ return TmpTargetAllocs.takeError();
+
+ if (TmpTargetAllocs->size() != RMR.size())
+ return make_error<StringError>(
+ "Number of target allocations does not match request",
+ inconvertibleErrorCode());
+
+ TargetAllocMap TargetAllocs;
+ for (auto &E : *TmpTargetAllocs)
+ TargetAllocs[orcrpctpc::fromWireProtectionFlags(E.Prot)] = {
+ E.Address, E.AllocatedSize};
+
+ DEBUG_WITH_TYPE("orc", {
+ auto HAI = HostAllocs.begin();
+ for (auto &KV : TargetAllocs)
+ dbgs() << " permissions: "
+ << ((KV.first & sys::Memory::MF_READ) ? 'R' : '-')
+ << ((KV.first & sys::Memory::MF_WRITE) ? 'W' : '-')
+ << ((KV.first & sys::Memory::MF_EXEC) ? 'X' : '-')
+ << " assigned local " << (void *)HAI->second.Mem.get()
+ << ", target " << formatv("{0:x16}", KV.second.Address) << "\n";
+ });
+
+ return std::make_unique<OrcRPCAllocation>(*this, std::move(HostAllocs),
+ std::move(TargetAllocs));
+ }
+
+private:
+ void reportError(Error Err) { Parent.reportError(std::move(Err)); }
+
+ decltype(std::declval<OrcRPCTPCImplT>().getEndpoint()) getEndpoint() {
+ return Parent.getEndpoint();
+ }
+
+ OrcRPCTPCImplT &Parent;
+};
+
+/// TargetProcessControl::MemoryAccess implementation for a process connected
+/// via an ORC RPC endpoint.
+template <typename OrcRPCTPCImplT>
+class OrcRPCTPCMemoryAccess : public TargetProcessControl::MemoryAccess {
+public:
+ OrcRPCTPCMemoryAccess(OrcRPCTPCImplT &Parent) : Parent(Parent) {}
+
+ void writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws,
+ WriteResultFn OnWriteComplete) override {
+ writeViaRPC<orcrpctpc::WriteUInt8s>(Ws, std::move(OnWriteComplete));
+ }
+
+ void writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws,
+ WriteResultFn OnWriteComplete) override {
+ writeViaRPC<orcrpctpc::WriteUInt16s>(Ws, std::move(OnWriteComplete));
+ }
+
+ void writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws,
+ WriteResultFn OnWriteComplete) override {
+ writeViaRPC<orcrpctpc::WriteUInt32s>(Ws, std::move(OnWriteComplete));
+ }
+
+ void writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws,
+ WriteResultFn OnWriteComplete) override {
+ writeViaRPC<orcrpctpc::WriteUInt64s>(Ws, std::move(OnWriteComplete));
+ }
+
+ void writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws,
+ WriteResultFn OnWriteComplete) override {
+ writeViaRPC<orcrpctpc::WriteBuffers>(Ws, std::move(OnWriteComplete));
+ }
+
+private:
+ template <typename WriteRPCFunction, typename WriteElementT>
+ void writeViaRPC(ArrayRef<WriteElementT> Ws, WriteResultFn OnWriteComplete) {
+ if (auto Err = Parent.getEndpoint().template callAsync<WriteRPCFunction>(
+ [OWC = std::move(OnWriteComplete)](Error Err2) mutable -> Error {
+ OWC(std::move(Err2));
+ return Error::success();
+ },
+ Ws)) {
+ Parent.reportError(std::move(Err));
+ Parent.getEndpoint().abandonPendingResponses();
+ }
+ }
+
+ OrcRPCTPCImplT &Parent;
+};
+
+// TargetProcessControl for a process connected via an ORC RPC Endpoint.
+template <typename RPCEndpointT>
+class OrcRPCTargetProcessControlBase : public TargetProcessControl {
+public:
+ using ErrorReporter = unique_function<void(Error)>;
+
+ using OnCloseConnectionFunction = unique_function<Error(Error)>;
+
+ OrcRPCTargetProcessControlBase(std::shared_ptr<SymbolStringPool> SSP,
+ RPCEndpointT &EP, ErrorReporter ReportError)
+ : TargetProcessControl(std::move(SSP)),
+ ReportError(std::move(ReportError)), EP(EP) {}
+
+ void reportError(Error Err) { ReportError(std::move(Err)); }
+
+ RPCEndpointT &getEndpoint() { return EP; }
+
+ Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override {
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "Loading dylib \"" << (DylibPath ? DylibPath : "") << "\" ";
+ if (!DylibPath)
+ dbgs() << "(process symbols)";
+ dbgs() << "\n";
+ });
+ if (!DylibPath)
+ DylibPath = "";
+ auto H = EP.template callB<orcrpctpc::LoadDylib>(DylibPath);
+ DEBUG_WITH_TYPE("orc", {
+ if (H)
+ dbgs() << " got handle " << formatv("{0:x16}", *H) << "\n";
+ else
+ dbgs() << " error, unable to load\n";
+ });
+ return H;
+ }
+
+ Expected<std::vector<tpctypes::LookupResult>>
+ lookupSymbols(ArrayRef<LookupRequest> Request) override {
+ std::vector<orcrpctpc::RemoteLookupRequest> RR;
+ for (auto &E : Request) {
+ RR.push_back({});
+ RR.back().first = E.Handle;
+ for (auto &KV : E.Symbols)
+ RR.back().second.push_back(
+ {(*KV.first).str(),
+ KV.second == SymbolLookupFlags::WeaklyReferencedSymbol});
+ }
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "Compound lookup:\n";
+ for (auto &R : Request) {
+ dbgs() << " In " << formatv("{0:x16}", R.Handle) << ": {";
+ bool First = true;
+ for (auto &KV : R.Symbols) {
+ dbgs() << (First ? "" : ",") << " " << *KV.first;
+ First = false;
+ }
+ dbgs() << " }\n";
+ }
+ });
+ return EP.template callB<orcrpctpc::LookupSymbols>(RR);
+ }
+
+ Expected<int32_t> runAsMain(JITTargetAddress MainFnAddr,
+ ArrayRef<std::string> Args) override {
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "Running as main: " << formatv("{0:x16}", MainFnAddr)
+ << ", args = [";
+ for (unsigned I = 0; I != Args.size(); ++I)
+ dbgs() << (I ? "," : "") << " \"" << Args[I] << "\"";
+ dbgs() << "]\n";
+ });
+ auto Result = EP.template callB<orcrpctpc::RunMain>(MainFnAddr, Args);
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << " call to " << formatv("{0:x16}", MainFnAddr);
+ if (Result)
+ dbgs() << " returned result " << *Result << "\n";
+ else
+ dbgs() << " failed\n";
+ });
+ return Result;
+ }
+
+ Expected<tpctypes::WrapperFunctionResult>
+ runWrapper(JITTargetAddress WrapperFnAddr,
+ ArrayRef<uint8_t> ArgBuffer) override {
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "Running as wrapper function "
+ << formatv("{0:x16}", WrapperFnAddr) << " with "
+ << formatv("{0:x16}", ArgBuffer.size()) << " argument buffer\n";
+ });
+ auto Result =
+ EP.template callB<orcrpctpc::RunWrapper>(WrapperFnAddr, ArgBuffer);
+ // dbgs() << "Returned from runWrapper...\n";
+ return Result;
+ }
+
+ Error closeConnection(OnCloseConnectionFunction OnCloseConnection) {
+ DEBUG_WITH_TYPE("orc", dbgs() << "Closing connection to remote\n");
+ return EP.template callAsync<orcrpctpc::CloseConnection>(
+ std::move(OnCloseConnection));
+ }
+
+ Error closeConnectionAndWait() {
+ std::promise<MSVCPError> P;
+ auto F = P.get_future();
+ if (auto Err = closeConnection([&](Error Err2) -> Error {
+ P.set_value(std::move(Err2));
+ return Error::success();
+ })) {
+ EP.abandonAllPendingResponses();
+ return joinErrors(std::move(Err), F.get());
+ }
+ return F.get();
+ }
+
+protected:
+ /// Subclasses must call this during construction to initialize the
+ /// TargetTriple and PageSize members.
+ Error initializeORCRPCTPCBase() {
+ if (auto TripleOrErr = EP.template callB<orcrpctpc::GetTargetTriple>())
+ TargetTriple = Triple(*TripleOrErr);
+ else
+ return TripleOrErr.takeError();
+
+ if (auto PageSizeOrErr = EP.template callB<orcrpctpc::GetPageSize>())
+ PageSize = *PageSizeOrErr;
+ else
+ return PageSizeOrErr.takeError();
+
+ return Error::success();
+ }
+
+private:
+ ErrorReporter ReportError;
+ RPCEndpointT &EP;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_ORCRPCTARGETPROCESSCONTROL_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
index 508d7b92da..e639958887 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
@@ -27,7 +27,7 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
-#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
+#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
@@ -61,7 +61,7 @@ namespace remote {
/// OrcRemoteTargetServer class) via an RPC system (see RPCUtils.h) to carry out
/// its actions.
class OrcRemoteTargetClient
- : public shared::SingleThreadedRPCEndpoint<shared::RawByteChannel> {
+ : public shared::SingleThreadedRPCEndpoint<shared::RawByteChannel> {
public:
/// Remote-mapped RuntimeDyld-compatible memory manager.
class RemoteRTDyldMemoryManager : public RuntimeDyld::MemoryManager {
@@ -337,221 +337,221 @@ public:
std::vector<EHFrame> RegisteredEHFrames;
};
- class RPCMMAlloc : public jitlink::JITLinkMemoryManager::Allocation {
- using AllocationMap = DenseMap<unsigned, sys::MemoryBlock>;
- using FinalizeContinuation =
- jitlink::JITLinkMemoryManager::Allocation::FinalizeContinuation;
- using ProtectionFlags = sys::Memory::ProtectionFlags;
- using SegmentsRequestMap =
- DenseMap<unsigned, jitlink::JITLinkMemoryManager::SegmentRequest>;
-
- RPCMMAlloc(OrcRemoteTargetClient &Client, ResourceIdMgr::ResourceId Id)
- : Client(Client), Id(Id) {}
-
- public:
- static Expected<std::unique_ptr<RPCMMAlloc>>
- Create(OrcRemoteTargetClient &Client, ResourceIdMgr::ResourceId Id,
- const SegmentsRequestMap &Request) {
- auto *MM = new RPCMMAlloc(Client, Id);
-
- if (Error Err = MM->allocateHostBlocks(Request))
- return std::move(Err);
-
- if (Error Err = MM->allocateTargetBlocks())
- return std::move(Err);
-
- return std::unique_ptr<RPCMMAlloc>(MM);
- }
-
- MutableArrayRef<char> getWorkingMemory(ProtectionFlags Seg) override {
- assert(HostSegBlocks.count(Seg) && "No allocation for segment");
- return {static_cast<char *>(HostSegBlocks[Seg].base()),
- HostSegBlocks[Seg].allocatedSize()};
- }
-
- JITTargetAddress getTargetMemory(ProtectionFlags Seg) override {
- assert(TargetSegBlocks.count(Seg) && "No allocation for segment");
- return pointerToJITTargetAddress(TargetSegBlocks[Seg].base());
- }
-
- void finalizeAsync(FinalizeContinuation OnFinalize) override {
- // Host allocations (working memory) remain ReadWrite.
- OnFinalize(copyAndProtect());
- }
-
- Error deallocate() override {
- // TODO: Cannot release target allocation. RPCAPI has no function
- // symmetric to reserveMem(). Add RPC call like freeMem()?
- return errorCodeToError(sys::Memory::releaseMappedMemory(HostAllocation));
- }
-
- private:
- OrcRemoteTargetClient &Client;
- ResourceIdMgr::ResourceId Id;
- AllocationMap HostSegBlocks;
- AllocationMap TargetSegBlocks;
- JITTargetAddress TargetSegmentAddr;
- sys::MemoryBlock HostAllocation;
-
- Error allocateHostBlocks(const SegmentsRequestMap &Request) {
- unsigned TargetPageSize = Client.getPageSize();
-
- if (!isPowerOf2_64(static_cast<uint64_t>(TargetPageSize)))
- return make_error<StringError>("Host page size is not a power of 2",
- inconvertibleErrorCode());
-
- auto TotalSize = calcTotalAllocSize(Request, TargetPageSize);
- if (!TotalSize)
- return TotalSize.takeError();
-
- // Allocate one slab to cover all the segments.
- const sys::Memory::ProtectionFlags ReadWrite =
- static_cast<sys::Memory::ProtectionFlags>(sys::Memory::MF_READ |
- sys::Memory::MF_WRITE);
- std::error_code EC;
- HostAllocation =
- sys::Memory::allocateMappedMemory(*TotalSize, nullptr, ReadWrite, EC);
- if (EC)
- return errorCodeToError(EC);
-
- char *SlabAddr = static_cast<char *>(HostAllocation.base());
-#ifndef NDEBUG
- char *SlabAddrEnd = SlabAddr + HostAllocation.allocatedSize();
-#endif
-
- // Allocate segment memory from the slab.
- for (auto &KV : Request) {
- const auto &Seg = KV.second;
-
- uint64_t SegmentSize = Seg.getContentSize() + Seg.getZeroFillSize();
- uint64_t AlignedSegmentSize = alignTo(SegmentSize, TargetPageSize);
-
- // Zero out zero-fill memory.
- char *ZeroFillBegin = SlabAddr + Seg.getContentSize();
- memset(ZeroFillBegin, 0, Seg.getZeroFillSize());
-
- // Record the block for this segment.
- HostSegBlocks[KV.first] =
- sys::MemoryBlock(SlabAddr, AlignedSegmentSize);
-
- SlabAddr += AlignedSegmentSize;
- assert(SlabAddr <= SlabAddrEnd && "Out of range");
- }
-
- return Error::success();
- }
-
- Error allocateTargetBlocks() {
- // Reserve memory for all blocks on the target. We need as much space on
- // the target as we allocated on the host.
- TargetSegmentAddr = Client.reserveMem(Id, HostAllocation.allocatedSize(),
- Client.getPageSize());
- if (!TargetSegmentAddr)
- return make_error<StringError>("Failed to reserve memory on the target",
- inconvertibleErrorCode());
-
- // Map memory blocks into the allocation, that match the host allocation.
- JITTargetAddress TargetAllocAddr = TargetSegmentAddr;
- for (const auto &KV : HostSegBlocks) {
- size_t TargetAllocSize = KV.second.allocatedSize();
-
- TargetSegBlocks[KV.first] =
- sys::MemoryBlock(jitTargetAddressToPointer<void *>(TargetAllocAddr),
- TargetAllocSize);
-
- TargetAllocAddr += TargetAllocSize;
- assert(TargetAllocAddr - TargetSegmentAddr <=
- HostAllocation.allocatedSize() &&
- "Out of range on target");
- }
-
- return Error::success();
- }
-
- Error copyAndProtect() {
- unsigned Permissions = 0u;
-
- // Copy segments one by one.
- for (auto &KV : TargetSegBlocks) {
- Permissions |= KV.first;
-
- const sys::MemoryBlock &TargetBlock = KV.second;
- const sys::MemoryBlock &HostBlock = HostSegBlocks.lookup(KV.first);
-
- size_t TargetAllocSize = TargetBlock.allocatedSize();
- auto TargetAllocAddr = pointerToJITTargetAddress(TargetBlock.base());
- auto *HostAllocBegin = static_cast<const char *>(HostBlock.base());
-
- bool CopyErr =
- Client.writeMem(TargetAllocAddr, HostAllocBegin, TargetAllocSize);
- if (CopyErr)
- return createStringError(inconvertibleErrorCode(),
- "Failed to copy %d segment to the target",
- KV.first);
- }
-
- // Set permission flags for all segments at once.
- bool ProtectErr =
- Client.setProtections(Id, TargetSegmentAddr, Permissions);
- if (ProtectErr)
- return createStringError(inconvertibleErrorCode(),
- "Failed to apply permissions for %d segment "
- "on the target",
- Permissions);
- return Error::success();
- }
-
- static Expected<size_t>
- calcTotalAllocSize(const SegmentsRequestMap &Request,
- unsigned TargetPageSize) {
- size_t TotalSize = 0;
- for (const auto &KV : Request) {
- const auto &Seg = KV.second;
-
- if (Seg.getAlignment() > TargetPageSize)
- return make_error<StringError>("Cannot request alignment higher than "
- "page alignment on target",
- inconvertibleErrorCode());
-
- TotalSize = alignTo(TotalSize, TargetPageSize);
- TotalSize += Seg.getContentSize();
- TotalSize += Seg.getZeroFillSize();
- }
-
- return TotalSize;
- }
- };
-
- class RemoteJITLinkMemoryManager : public jitlink::JITLinkMemoryManager {
- public:
- RemoteJITLinkMemoryManager(OrcRemoteTargetClient &Client,
- ResourceIdMgr::ResourceId Id)
- : Client(Client), Id(Id) {}
-
- RemoteJITLinkMemoryManager(const RemoteJITLinkMemoryManager &) = delete;
- RemoteJITLinkMemoryManager(RemoteJITLinkMemoryManager &&) = default;
-
- RemoteJITLinkMemoryManager &
- operator=(const RemoteJITLinkMemoryManager &) = delete;
- RemoteJITLinkMemoryManager &
- operator=(RemoteJITLinkMemoryManager &&) = delete;
-
- ~RemoteJITLinkMemoryManager() {
- Client.destroyRemoteAllocator(Id);
- LLVM_DEBUG(dbgs() << "Destroyed remote allocator " << Id << "\n");
- }
-
- Expected<std::unique_ptr<Allocation>>
- allocate(const jitlink::JITLinkDylib *JD,
- const SegmentsRequestMap &Request) override {
- return RPCMMAlloc::Create(Client, Id, Request);
- }
-
- private:
- OrcRemoteTargetClient &Client;
- ResourceIdMgr::ResourceId Id;
- };
-
+ class RPCMMAlloc : public jitlink::JITLinkMemoryManager::Allocation {
+ using AllocationMap = DenseMap<unsigned, sys::MemoryBlock>;
+ using FinalizeContinuation =
+ jitlink::JITLinkMemoryManager::Allocation::FinalizeContinuation;
+ using ProtectionFlags = sys::Memory::ProtectionFlags;
+ using SegmentsRequestMap =
+ DenseMap<unsigned, jitlink::JITLinkMemoryManager::SegmentRequest>;
+
+ RPCMMAlloc(OrcRemoteTargetClient &Client, ResourceIdMgr::ResourceId Id)
+ : Client(Client), Id(Id) {}
+
+ public:
+ static Expected<std::unique_ptr<RPCMMAlloc>>
+ Create(OrcRemoteTargetClient &Client, ResourceIdMgr::ResourceId Id,
+ const SegmentsRequestMap &Request) {
+ auto *MM = new RPCMMAlloc(Client, Id);
+
+ if (Error Err = MM->allocateHostBlocks(Request))
+ return std::move(Err);
+
+ if (Error Err = MM->allocateTargetBlocks())
+ return std::move(Err);
+
+ return std::unique_ptr<RPCMMAlloc>(MM);
+ }
+
+ MutableArrayRef<char> getWorkingMemory(ProtectionFlags Seg) override {
+ assert(HostSegBlocks.count(Seg) && "No allocation for segment");
+ return {static_cast<char *>(HostSegBlocks[Seg].base()),
+ HostSegBlocks[Seg].allocatedSize()};
+ }
+
+ JITTargetAddress getTargetMemory(ProtectionFlags Seg) override {
+ assert(TargetSegBlocks.count(Seg) && "No allocation for segment");
+ return pointerToJITTargetAddress(TargetSegBlocks[Seg].base());
+ }
+
+ void finalizeAsync(FinalizeContinuation OnFinalize) override {
+ // Host allocations (working memory) remain ReadWrite.
+ OnFinalize(copyAndProtect());
+ }
+
+ Error deallocate() override {
+ // TODO: Cannot release target allocation. RPCAPI has no function
+ // symmetric to reserveMem(). Add RPC call like freeMem()?
+ return errorCodeToError(sys::Memory::releaseMappedMemory(HostAllocation));
+ }
+
+ private:
+ OrcRemoteTargetClient &Client;
+ ResourceIdMgr::ResourceId Id;
+ AllocationMap HostSegBlocks;
+ AllocationMap TargetSegBlocks;
+ JITTargetAddress TargetSegmentAddr;
+ sys::MemoryBlock HostAllocation;
+
+ Error allocateHostBlocks(const SegmentsRequestMap &Request) {
+ unsigned TargetPageSize = Client.getPageSize();
+
+ if (!isPowerOf2_64(static_cast<uint64_t>(TargetPageSize)))
+ return make_error<StringError>("Host page size is not a power of 2",
+ inconvertibleErrorCode());
+
+ auto TotalSize = calcTotalAllocSize(Request, TargetPageSize);
+ if (!TotalSize)
+ return TotalSize.takeError();
+
+ // Allocate one slab to cover all the segments.
+ const sys::Memory::ProtectionFlags ReadWrite =
+ static_cast<sys::Memory::ProtectionFlags>(sys::Memory::MF_READ |
+ sys::Memory::MF_WRITE);
+ std::error_code EC;
+ HostAllocation =
+ sys::Memory::allocateMappedMemory(*TotalSize, nullptr, ReadWrite, EC);
+ if (EC)
+ return errorCodeToError(EC);
+
+ char *SlabAddr = static_cast<char *>(HostAllocation.base());
+#ifndef NDEBUG
+ char *SlabAddrEnd = SlabAddr + HostAllocation.allocatedSize();
+#endif
+
+ // Allocate segment memory from the slab.
+ for (auto &KV : Request) {
+ const auto &Seg = KV.second;
+
+ uint64_t SegmentSize = Seg.getContentSize() + Seg.getZeroFillSize();
+ uint64_t AlignedSegmentSize = alignTo(SegmentSize, TargetPageSize);
+
+ // Zero out zero-fill memory.
+ char *ZeroFillBegin = SlabAddr + Seg.getContentSize();
+ memset(ZeroFillBegin, 0, Seg.getZeroFillSize());
+
+ // Record the block for this segment.
+ HostSegBlocks[KV.first] =
+ sys::MemoryBlock(SlabAddr, AlignedSegmentSize);
+
+ SlabAddr += AlignedSegmentSize;
+ assert(SlabAddr <= SlabAddrEnd && "Out of range");
+ }
+
+ return Error::success();
+ }
+
+ Error allocateTargetBlocks() {
+ // Reserve memory for all blocks on the target. We need as much space on
+ // the target as we allocated on the host.
+ TargetSegmentAddr = Client.reserveMem(Id, HostAllocation.allocatedSize(),
+ Client.getPageSize());
+ if (!TargetSegmentAddr)
+ return make_error<StringError>("Failed to reserve memory on the target",
+ inconvertibleErrorCode());
+
+ // Map memory blocks into the allocation, that match the host allocation.
+ JITTargetAddress TargetAllocAddr = TargetSegmentAddr;
+ for (const auto &KV : HostSegBlocks) {
+ size_t TargetAllocSize = KV.second.allocatedSize();
+
+ TargetSegBlocks[KV.first] =
+ sys::MemoryBlock(jitTargetAddressToPointer<void *>(TargetAllocAddr),
+ TargetAllocSize);
+
+ TargetAllocAddr += TargetAllocSize;
+ assert(TargetAllocAddr - TargetSegmentAddr <=
+ HostAllocation.allocatedSize() &&
+ "Out of range on target");
+ }
+
+ return Error::success();
+ }
+
+ Error copyAndProtect() {
+ unsigned Permissions = 0u;
+
+ // Copy segments one by one.
+ for (auto &KV : TargetSegBlocks) {
+ Permissions |= KV.first;
+
+ const sys::MemoryBlock &TargetBlock = KV.second;
+ const sys::MemoryBlock &HostBlock = HostSegBlocks.lookup(KV.first);
+
+ size_t TargetAllocSize = TargetBlock.allocatedSize();
+ auto TargetAllocAddr = pointerToJITTargetAddress(TargetBlock.base());
+ auto *HostAllocBegin = static_cast<const char *>(HostBlock.base());
+
+ bool CopyErr =
+ Client.writeMem(TargetAllocAddr, HostAllocBegin, TargetAllocSize);
+ if (CopyErr)
+ return createStringError(inconvertibleErrorCode(),
+ "Failed to copy %d segment to the target",
+ KV.first);
+ }
+
+ // Set permission flags for all segments at once.
+ bool ProtectErr =
+ Client.setProtections(Id, TargetSegmentAddr, Permissions);
+ if (ProtectErr)
+ return createStringError(inconvertibleErrorCode(),
+ "Failed to apply permissions for %d segment "
+ "on the target",
+ Permissions);
+ return Error::success();
+ }
+
+ static Expected<size_t>
+ calcTotalAllocSize(const SegmentsRequestMap &Request,
+ unsigned TargetPageSize) {
+ size_t TotalSize = 0;
+ for (const auto &KV : Request) {
+ const auto &Seg = KV.second;
+
+ if (Seg.getAlignment() > TargetPageSize)
+ return make_error<StringError>("Cannot request alignment higher than "
+ "page alignment on target",
+ inconvertibleErrorCode());
+
+ TotalSize = alignTo(TotalSize, TargetPageSize);
+ TotalSize += Seg.getContentSize();
+ TotalSize += Seg.getZeroFillSize();
+ }
+
+ return TotalSize;
+ }
+ };
+
+ class RemoteJITLinkMemoryManager : public jitlink::JITLinkMemoryManager {
+ public:
+ RemoteJITLinkMemoryManager(OrcRemoteTargetClient &Client,
+ ResourceIdMgr::ResourceId Id)
+ : Client(Client), Id(Id) {}
+
+ RemoteJITLinkMemoryManager(const RemoteJITLinkMemoryManager &) = delete;
+ RemoteJITLinkMemoryManager(RemoteJITLinkMemoryManager &&) = default;
+
+ RemoteJITLinkMemoryManager &
+ operator=(const RemoteJITLinkMemoryManager &) = delete;
+ RemoteJITLinkMemoryManager &
+ operator=(RemoteJITLinkMemoryManager &&) = delete;
+
+ ~RemoteJITLinkMemoryManager() {
+ Client.destroyRemoteAllocator(Id);
+ LLVM_DEBUG(dbgs() << "Destroyed remote allocator " << Id << "\n");
+ }
+
+ Expected<std::unique_ptr<Allocation>>
+ allocate(const jitlink::JITLinkDylib *JD,
+ const SegmentsRequestMap &Request) override {
+ return RPCMMAlloc::Create(Client, Id, Request);
+ }
+
+ private:
+ OrcRemoteTargetClient &Client;
+ ResourceIdMgr::ResourceId Id;
+ };
+
/// Remote indirect stubs manager.
class RemoteIndirectStubsManager : public IndirectStubsManager {
public:
@@ -677,7 +677,7 @@ public:
RemoteTrampolinePool(OrcRemoteTargetClient &Client) : Client(Client) {}
private:
- Error grow() override {
+ Error grow() override {
JITTargetAddress BlockAddr = 0;
uint32_t NumTrampolines = 0;
if (auto TrampolineInfoOrErr = Client.emitTrampolineBlock())
@@ -687,7 +687,7 @@ public:
uint32_t TrampolineSize = Client.getTrampolineSize();
for (unsigned I = 0; I < NumTrampolines; ++I)
- AvailableTrampolines.push_back(BlockAddr + (I * TrampolineSize));
+ AvailableTrampolines.push_back(BlockAddr + (I * TrampolineSize));
return Error::success();
}
@@ -710,7 +710,7 @@ 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<std::unique_ptr<OrcRemoteTargetClient>>
- Create(shared::RawByteChannel &Channel, ExecutionSession &ES) {
+ Create(shared::RawByteChannel &Channel, ExecutionSession &ES) {
Error Err = Error::success();
auto Client = std::unique_ptr<OrcRemoteTargetClient>(
new OrcRemoteTargetClient(Channel, ES, Err));
@@ -727,14 +727,14 @@ public:
return callB<exec::CallIntVoid>(Addr);
}
- /// Call the int(int) function at the given address in the target and return
- /// its result.
- Expected<int> callIntInt(JITTargetAddress Addr, int Arg) {
- LLVM_DEBUG(dbgs() << "Calling int(*)(int) " << format("0x%016" PRIx64, Addr)
- << "\n");
- return callB<exec::CallIntInt>(Addr, Arg);
- }
-
+ /// Call the int(int) function at the given address in the target and return
+ /// its result.
+ Expected<int> callIntInt(JITTargetAddress Addr, int Arg) {
+ LLVM_DEBUG(dbgs() << "Calling int(*)(int) " << format("0x%016" PRIx64, Addr)
+ << "\n");
+ return callB<exec::CallIntInt>(Addr, Arg);
+ }
+
/// Call the int(int, char*[]) function at the given address in the target and
/// return its result.
Expected<int> callMain(JITTargetAddress Addr,
@@ -763,18 +763,18 @@ public:
new RemoteRTDyldMemoryManager(*this, Id));
}
- /// Create a JITLink-compatible memory manager which will allocate working
- /// memory on the host and target memory on the remote target.
- Expected<std::unique_ptr<RemoteJITLinkMemoryManager>>
- createRemoteJITLinkMemoryManager() {
- auto Id = AllocatorIds.getNext();
- if (auto Err = callB<mem::CreateRemoteAllocator>(Id))
- return std::move(Err);
- LLVM_DEBUG(dbgs() << "Created remote allocator " << Id << "\n");
- return std::unique_ptr<RemoteJITLinkMemoryManager>(
- new RemoteJITLinkMemoryManager(*this, Id));
- }
-
+ /// Create a JITLink-compatible memory manager which will allocate working
+ /// memory on the host and target memory on the remote target.
+ Expected<std::unique_ptr<RemoteJITLinkMemoryManager>>
+ createRemoteJITLinkMemoryManager() {
+ auto Id = AllocatorIds.getNext();
+ if (auto Err = callB<mem::CreateRemoteAllocator>(Id))
+ return std::move(Err);
+ LLVM_DEBUG(dbgs() << "Created remote allocator " << Id << "\n");
+ return std::unique_ptr<RemoteJITLinkMemoryManager>(
+ new RemoteJITLinkMemoryManager(*this, Id));
+ }
+
/// Create an RCIndirectStubsManager that will allocate stubs on the remote
/// target.
Expected<std::unique_ptr<RemoteIndirectStubsManager>>
@@ -812,10 +812,10 @@ public:
Error terminateSession() { return callB<utils::TerminateSession>(); }
private:
- OrcRemoteTargetClient(shared::RawByteChannel &Channel, ExecutionSession &ES,
+ OrcRemoteTargetClient(shared::RawByteChannel &Channel, ExecutionSession &ES,
Error &Err)
- : shared::SingleThreadedRPCEndpoint<shared::RawByteChannel>(Channel,
- true),
+ : shared::SingleThreadedRPCEndpoint<shared::RawByteChannel>(Channel,
+ true),
ES(ES) {
ErrorAsOutParameter EAO(&Err);
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
index 95f7205c06..ff0dc7d33f 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
@@ -23,8 +23,8 @@
#define LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETRPCAPI_H
#include "llvm/ExecutionEngine/JITSymbol.h"
-#include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h"
-#include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h"
+#include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h"
+#include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h"
namespace llvm {
namespace orc {
@@ -80,9 +80,9 @@ private:
} // end namespace remote
-namespace shared {
+namespace shared {
-template <> class SerializationTypeName<JITSymbolFlags> {
+template <> class SerializationTypeName<JITSymbolFlags> {
public:
static const char *getName() { return "JITSymbolFlags"; }
};
@@ -106,7 +106,7 @@ public:
}
};
-template <> class SerializationTypeName<remote::DirectBufferWriter> {
+template <> class SerializationTypeName<remote::DirectBufferWriter> {
public:
static const char *getName() { return "DirectBufferWriter"; }
};
@@ -139,7 +139,7 @@ public:
}
};
-} // end namespace shared
+} // end namespace shared
namespace remote {
@@ -173,20 +173,20 @@ private:
namespace eh {
/// Registers EH frames on the remote.
-class RegisterEHFrames
- : public shared::RPCFunction<RegisterEHFrames,
- void(JITTargetAddress Addr, uint32_t Size)> {
-public:
- static const char *getName() { return "RegisterEHFrames"; }
-};
+class RegisterEHFrames
+ : public shared::RPCFunction<RegisterEHFrames,
+ void(JITTargetAddress Addr, uint32_t Size)> {
+public:
+ static const char *getName() { return "RegisterEHFrames"; }
+};
/// Deregisters EH frames on the remote.
-class DeregisterEHFrames
- : public shared::RPCFunction<DeregisterEHFrames,
- void(JITTargetAddress Addr, uint32_t Size)> {
-public:
- static const char *getName() { return "DeregisterEHFrames"; }
-};
+class DeregisterEHFrames
+ : public shared::RPCFunction<DeregisterEHFrames,
+ void(JITTargetAddress Addr, uint32_t Size)> {
+public:
+ static const char *getName() { return "DeregisterEHFrames"; }
+};
} // end namespace eh
@@ -195,38 +195,38 @@ namespace exec {
/// Call an 'int32_t()'-type function on the remote, returns the called
/// function's return value.
-class CallIntVoid
- : public shared::RPCFunction<CallIntVoid, int32_t(JITTargetAddress Addr)> {
-public:
- static const char *getName() { return "CallIntVoid"; }
-};
-
- /// Call an 'int32_t(int32_t)'-type function on the remote, returns the called
- /// function's return value.
-class CallIntInt
- : public shared::RPCFunction<CallIntInt,
- int32_t(JITTargetAddress Addr, int)> {
-public:
- static const char *getName() { return "CallIntInt"; }
-};
-
+class CallIntVoid
+ : public shared::RPCFunction<CallIntVoid, int32_t(JITTargetAddress Addr)> {
+public:
+ static const char *getName() { return "CallIntVoid"; }
+};
+
+ /// Call an 'int32_t(int32_t)'-type function on the remote, returns the called
+ /// function's return value.
+class CallIntInt
+ : public shared::RPCFunction<CallIntInt,
+ int32_t(JITTargetAddress Addr, int)> {
+public:
+ static const char *getName() { return "CallIntInt"; }
+};
+
/// Call an 'int32_t(int32_t, char**)'-type function on the remote, returns the
/// called function's return value.
-class CallMain
- : public shared::RPCFunction<CallMain,
- int32_t(JITTargetAddress Addr,
- std::vector<std::string> Args)> {
-public:
- static const char *getName() { return "CallMain"; }
-};
+class CallMain
+ : public shared::RPCFunction<CallMain,
+ int32_t(JITTargetAddress Addr,
+ std::vector<std::string> Args)> {
+public:
+ static const char *getName() { return "CallMain"; }
+};
/// Calls a 'void()'-type function on the remote, returns when the called
/// function completes.
-class CallVoidVoid
- : public shared::RPCFunction<CallVoidVoid, void(JITTargetAddress FnAddr)> {
-public:
- static const char *getName() { return "CallVoidVoid"; }
-};
+class CallVoidVoid
+ : public shared::RPCFunction<CallVoidVoid, void(JITTargetAddress FnAddr)> {
+public:
+ static const char *getName() { return "CallVoidVoid"; }
+};
} // end namespace exec
@@ -234,62 +234,62 @@ public:
namespace mem {
/// Creates a memory allocator on the remote.
-class CreateRemoteAllocator
- : public shared::RPCFunction<CreateRemoteAllocator,
- void(ResourceIdMgr::ResourceId AllocatorID)> {
-public:
- static const char *getName() { return "CreateRemoteAllocator"; }
-};
+class CreateRemoteAllocator
+ : public shared::RPCFunction<CreateRemoteAllocator,
+ void(ResourceIdMgr::ResourceId AllocatorID)> {
+public:
+ static const char *getName() { return "CreateRemoteAllocator"; }
+};
/// Destroys a remote allocator, freeing any memory allocated by it.
-class DestroyRemoteAllocator
- : public shared::RPCFunction<DestroyRemoteAllocator,
- void(ResourceIdMgr::ResourceId AllocatorID)> {
-public:
- static const char *getName() { return "DestroyRemoteAllocator"; }
-};
+class DestroyRemoteAllocator
+ : public shared::RPCFunction<DestroyRemoteAllocator,
+ void(ResourceIdMgr::ResourceId AllocatorID)> {
+public:
+ static const char *getName() { return "DestroyRemoteAllocator"; }
+};
/// Read a remote memory block.
-class ReadMem
- : public shared::RPCFunction<
- ReadMem, std::vector<uint8_t>(JITTargetAddress Src, uint64_t Size)> {
-public:
- static const char *getName() { return "ReadMem"; }
-};
+class ReadMem
+ : public shared::RPCFunction<
+ ReadMem, std::vector<uint8_t>(JITTargetAddress Src, uint64_t Size)> {
+public:
+ static const char *getName() { return "ReadMem"; }
+};
/// Reserve a block of memory on the remote via the given allocator.
-class ReserveMem
- : public shared::RPCFunction<
- ReserveMem, JITTargetAddress(ResourceIdMgr::ResourceId AllocID,
- uint64_t Size, uint32_t Align)> {
-public:
- static const char *getName() { return "ReserveMem"; }
-};
+class ReserveMem
+ : public shared::RPCFunction<
+ ReserveMem, JITTargetAddress(ResourceIdMgr::ResourceId AllocID,
+ uint64_t Size, uint32_t Align)> {
+public:
+ static const char *getName() { return "ReserveMem"; }
+};
/// Set the memory protection on a memory block.
-class SetProtections
- : public shared::RPCFunction<
- SetProtections, void(ResourceIdMgr::ResourceId AllocID,
- JITTargetAddress Dst, uint32_t ProtFlags)> {
-public:
- static const char *getName() { return "SetProtections"; }
-};
+class SetProtections
+ : public shared::RPCFunction<
+ SetProtections, void(ResourceIdMgr::ResourceId AllocID,
+ JITTargetAddress Dst, uint32_t ProtFlags)> {
+public:
+ static const char *getName() { return "SetProtections"; }
+};
/// Write to a remote memory block.
-class WriteMem
- : public shared::RPCFunction<WriteMem,
- void(remote::DirectBufferWriter DB)> {
-public:
- static const char *getName() { return "WriteMem"; }
-};
+class WriteMem
+ : public shared::RPCFunction<WriteMem,
+ void(remote::DirectBufferWriter DB)> {
+public:
+ static const char *getName() { return "WriteMem"; }
+};
/// Write to a remote pointer.
-class WritePtr
- : public shared::RPCFunction<WritePtr, void(JITTargetAddress Dst,
- JITTargetAddress Val)> {
-public:
- static const char *getName() { return "WritePtr"; }
-};
+class WritePtr
+ : public shared::RPCFunction<WritePtr, void(JITTargetAddress Dst,
+ JITTargetAddress Val)> {
+public:
+ static const char *getName() { return "WritePtr"; }
+};
} // end namespace mem
@@ -297,46 +297,46 @@ public:
namespace stubs {
/// Creates an indirect stub owner on the remote.
-class CreateIndirectStubsOwner
- : public shared::RPCFunction<CreateIndirectStubsOwner,
- void(ResourceIdMgr::ResourceId StubOwnerID)> {
-public:
- static const char *getName() { return "CreateIndirectStubsOwner"; }
-};
+class CreateIndirectStubsOwner
+ : public shared::RPCFunction<CreateIndirectStubsOwner,
+ void(ResourceIdMgr::ResourceId StubOwnerID)> {
+public:
+ static const char *getName() { return "CreateIndirectStubsOwner"; }
+};
/// RPC function for destroying an indirect stubs owner.
-class DestroyIndirectStubsOwner
- : public shared::RPCFunction<DestroyIndirectStubsOwner,
- void(ResourceIdMgr::ResourceId StubsOwnerID)> {
-public:
- static const char *getName() { return "DestroyIndirectStubsOwner"; }
-};
+class DestroyIndirectStubsOwner
+ : public shared::RPCFunction<DestroyIndirectStubsOwner,
+ void(ResourceIdMgr::ResourceId StubsOwnerID)> {
+public:
+ static const char *getName() { return "DestroyIndirectStubsOwner"; }
+};
/// EmitIndirectStubs result is (StubsBase, PtrsBase, NumStubsEmitted).
-class EmitIndirectStubs
- : public shared::RPCFunction<
- EmitIndirectStubs,
- std::tuple<JITTargetAddress, JITTargetAddress, uint32_t>(
- ResourceIdMgr::ResourceId StubsOwnerID,
- uint32_t NumStubsRequired)> {
-public:
- static const char *getName() { return "EmitIndirectStubs"; }
-};
+class EmitIndirectStubs
+ : public shared::RPCFunction<
+ EmitIndirectStubs,
+ std::tuple<JITTargetAddress, JITTargetAddress, uint32_t>(
+ ResourceIdMgr::ResourceId StubsOwnerID,
+ uint32_t NumStubsRequired)> {
+public:
+ static const char *getName() { return "EmitIndirectStubs"; }
+};
/// RPC function to emit the resolver block and return its address.
-class EmitResolverBlock
- : public shared::RPCFunction<EmitResolverBlock, void()> {
-public:
- static const char *getName() { return "EmitResolverBlock"; }
-};
+class EmitResolverBlock
+ : public shared::RPCFunction<EmitResolverBlock, void()> {
+public:
+ static const char *getName() { return "EmitResolverBlock"; }
+};
/// EmitTrampolineBlock result is (BlockAddr, NumTrampolines).
-class EmitTrampolineBlock
- : public shared::RPCFunction<EmitTrampolineBlock,
- std::tuple<JITTargetAddress, uint32_t>()> {
-public:
- static const char *getName() { return "EmitTrampolineBlock"; }
-};
+class EmitTrampolineBlock
+ : public shared::RPCFunction<EmitTrampolineBlock,
+ std::tuple<JITTargetAddress, uint32_t>()> {
+public:
+ static const char *getName() { return "EmitTrampolineBlock"; }
+};
} // end namespace stubs
@@ -345,44 +345,44 @@ namespace utils {
/// GetRemoteInfo result is (Triple, PointerSize, PageSize, TrampolineSize,
/// IndirectStubsSize).
-class GetRemoteInfo
- : public shared::RPCFunction<
- GetRemoteInfo,
- std::tuple<std::string, uint32_t, uint32_t, uint32_t, uint32_t>()> {
-public:
- static const char *getName() { return "GetRemoteInfo"; }
-};
+class GetRemoteInfo
+ : public shared::RPCFunction<
+ GetRemoteInfo,
+ std::tuple<std::string, uint32_t, uint32_t, uint32_t, uint32_t>()> {
+public:
+ static const char *getName() { return "GetRemoteInfo"; }
+};
/// Get the address of a remote symbol.
-class GetSymbolAddress
- : public shared::RPCFunction<GetSymbolAddress,
- JITTargetAddress(std::string SymbolName)> {
-public:
- static const char *getName() { return "GetSymbolAddress"; }
-};
+class GetSymbolAddress
+ : public shared::RPCFunction<GetSymbolAddress,
+ JITTargetAddress(std::string SymbolName)> {
+public:
+ static const char *getName() { return "GetSymbolAddress"; }
+};
/// Request that the host execute a compile callback.
-class RequestCompile
- : public shared::RPCFunction<
- RequestCompile, JITTargetAddress(JITTargetAddress TrampolineAddr)> {
-public:
- static const char *getName() { return "RequestCompile"; }
-};
+class RequestCompile
+ : public shared::RPCFunction<
+ RequestCompile, JITTargetAddress(JITTargetAddress TrampolineAddr)> {
+public:
+ static const char *getName() { return "RequestCompile"; }
+};
/// Notify the remote and terminate the session.
-class TerminateSession : public shared::RPCFunction<TerminateSession, void()> {
-public:
- static const char *getName() { return "TerminateSession"; }
-};
+class TerminateSession : public shared::RPCFunction<TerminateSession, void()> {
+public:
+ static const char *getName() { return "TerminateSession"; }
+};
} // namespace utils
class OrcRemoteTargetRPCAPI
- : public shared::SingleThreadedRPCEndpoint<shared::RawByteChannel> {
+ : public shared::SingleThreadedRPCEndpoint<shared::RawByteChannel> {
public:
// FIXME: Remove constructors once MSVC supports synthesizing move-ops.
- OrcRemoteTargetRPCAPI(shared::RawByteChannel &C)
- : shared::SingleThreadedRPCEndpoint<shared::RawByteChannel>(C, true) {}
+ OrcRemoteTargetRPCAPI(shared::RawByteChannel &C)
+ : shared::SingleThreadedRPCEndpoint<shared::RawByteChannel>(C, true) {}
};
} // end namespace remote
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
index 1002264934..d7bb4f591a 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
@@ -24,7 +24,7 @@
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h"
-#include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
+#include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Format.h"
@@ -53,7 +53,7 @@ namespace remote {
template <typename ChannelT, typename TargetT>
class OrcRemoteTargetServer
- : public shared::SingleThreadedRPCEndpoint<shared::RawByteChannel> {
+ : public shared::SingleThreadedRPCEndpoint<shared::RawByteChannel> {
public:
using SymbolLookupFtor =
std::function<JITTargetAddress(const std::string &Name)>;
@@ -64,14 +64,14 @@ public:
OrcRemoteTargetServer(ChannelT &Channel, SymbolLookupFtor SymbolLookup,
EHFrameRegistrationFtor EHFramesRegister,
EHFrameRegistrationFtor EHFramesDeregister)
- : shared::SingleThreadedRPCEndpoint<shared::RawByteChannel>(Channel,
- true),
+ : shared::SingleThreadedRPCEndpoint<shared::RawByteChannel>(Channel,
+ true),
SymbolLookup(std::move(SymbolLookup)),
EHFramesRegister(std::move(EHFramesRegister)),
EHFramesDeregister(std::move(EHFramesDeregister)) {
using ThisT = std::remove_reference_t<decltype(*this)>;
addHandler<exec::CallIntVoid>(*this, &ThisT::handleCallIntVoid);
- addHandler<exec::CallIntInt>(*this, &ThisT::handleCallIntInt);
+ addHandler<exec::CallIntInt>(*this, &ThisT::handleCallIntInt);
addHandler<exec::CallMain>(*this, &ThisT::handleCallMain);
addHandler<exec::CallVoidVoid>(*this, &ThisT::handleCallVoidVoid);
addHandler<mem::CreateRemoteAllocator>(*this,
@@ -177,19 +177,19 @@ private:
return Result;
}
- Expected<int32_t> handleCallIntInt(JITTargetAddress Addr, int Arg) {
- using IntIntFnTy = int (*)(int);
-
- IntIntFnTy Fn = reinterpret_cast<IntIntFnTy>(static_cast<uintptr_t>(Addr));
-
- LLVM_DEBUG(dbgs() << " Calling " << format("0x%016x", Addr)
- << " with argument " << Arg << "\n");
- int Result = Fn(Arg);
- LLVM_DEBUG(dbgs() << " Result = " << Result << "\n");
-
- return Result;
- }
-
+ Expected<int32_t> handleCallIntInt(JITTargetAddress Addr, int Arg) {
+ using IntIntFnTy = int (*)(int);
+
+ IntIntFnTy Fn = reinterpret_cast<IntIntFnTy>(static_cast<uintptr_t>(Addr));
+
+ LLVM_DEBUG(dbgs() << " Calling " << format("0x%016x", Addr)
+ << " with argument " << Arg << "\n");
+ int Result = Fn(Arg);
+ LLVM_DEBUG(dbgs() << " Result = " << Result << "\n");
+
+ return Result;
+ }
+
Expected<int32_t> handleCallMain(JITTargetAddress Addr,
std::vector<std::string> Args) {
using MainFnTy = int (*)(int, const char *[]);
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
index d7531d1087..cb1755e21e 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
@@ -42,16 +42,16 @@
namespace llvm {
namespace orc {
-class RTDyldObjectLinkingLayer : public ObjectLayer, private ResourceManager {
+class RTDyldObjectLinkingLayer : public ObjectLayer, private ResourceManager {
public:
/// Functor for receiving object-loaded notifications.
- using NotifyLoadedFunction = std::function<void(
- MaterializationResponsibility &R, const object::ObjectFile &Obj,
- const RuntimeDyld::LoadedObjectInfo &)>;
+ using NotifyLoadedFunction = std::function<void(
+ MaterializationResponsibility &R, const object::ObjectFile &Obj,
+ const RuntimeDyld::LoadedObjectInfo &)>;
/// Functor for receiving finalization notifications.
- using NotifyEmittedFunction = std::function<void(
- MaterializationResponsibility &R, std::unique_ptr<MemoryBuffer>)>;
+ using NotifyEmittedFunction = std::function<void(
+ MaterializationResponsibility &R, std::unique_ptr<MemoryBuffer>)>;
using GetMemoryManagerFunction =
std::function<std::unique_ptr<RuntimeDyld::MemoryManager>()>;
@@ -64,7 +64,7 @@ public:
~RTDyldObjectLinkingLayer();
/// Emit the object.
- void emit(std::unique_ptr<MaterializationResponsibility> R,
+ void emit(std::unique_ptr<MaterializationResponsibility> R,
std::unique_ptr<MemoryBuffer> O) override;
/// Set the NotifyLoaded callback.
@@ -129,24 +129,24 @@ public:
void unregisterJITEventListener(JITEventListener &L);
private:
- using MemoryManagerUP = std::unique_ptr<RuntimeDyld::MemoryManager>;
-
- Error onObjLoad(MaterializationResponsibility &R,
+ using MemoryManagerUP = std::unique_ptr<RuntimeDyld::MemoryManager>;
+
+ Error onObjLoad(MaterializationResponsibility &R,
const object::ObjectFile &Obj,
- RuntimeDyld::MemoryManager &MemMgr,
- RuntimeDyld::LoadedObjectInfo &LoadedObjInfo,
+ RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::LoadedObjectInfo &LoadedObjInfo,
std::map<StringRef, JITEvaluatedSymbol> Resolved,
std::set<StringRef> &InternalSymbols);
- void onObjEmit(MaterializationResponsibility &R,
+ void onObjEmit(MaterializationResponsibility &R,
object::OwningBinary<object::ObjectFile> O,
- std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
- std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
- Error Err);
+ std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
+ std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
+ Error Err);
+
+ Error handleRemoveResources(ResourceKey K) override;
+ void handleTransferResources(ResourceKey DstKey, ResourceKey SrcKey) override;
- Error handleRemoveResources(ResourceKey K) override;
- void handleTransferResources(ResourceKey DstKey, ResourceKey SrcKey) override;
-
mutable std::mutex RTDyldLayerMutex;
GetMemoryManagerFunction GetMemoryManager;
NotifyLoadedFunction NotifyLoaded;
@@ -154,7 +154,7 @@ private:
bool ProcessAllSections = false;
bool OverrideObjectFlags = false;
bool AutoClaimObjectSymbols = false;
- DenseMap<ResourceKey, std::vector<MemoryManagerUP>> MemMgrs;
+ DenseMap<ResourceKey, std::vector<MemoryManagerUP>> MemMgrs;
std::vector<JITEventListener *> EventListeners;
};
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h
index d4aa712442..e1a376bc6b 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h
@@ -1,90 +1,90 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- FDRawByteChannel.h - File descriptor based byte-channel -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// File descriptor based RawByteChannel.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_FDRAWBYTECHANNEL_H
-#define LLVM_EXECUTIONENGINE_ORC_SHARED_FDRAWBYTECHANNEL_H
-
-#include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h"
-
-#if !defined(_MSC_VER) && !defined(__MINGW32__)
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-
-namespace llvm {
-namespace orc {
-namespace shared {
-
-/// Serialization channel that reads from and writes from file descriptors.
-class FDRawByteChannel final : public RawByteChannel {
-public:
- FDRawByteChannel(int InFD, int OutFD) : InFD(InFD), OutFD(OutFD) {}
-
- llvm::Error readBytes(char *Dst, unsigned Size) override {
- assert(Dst && "Attempt to read into null.");
- ssize_t Completed = 0;
- while (Completed < static_cast<ssize_t>(Size)) {
- ssize_t Read = ::read(InFD, Dst + Completed, Size - Completed);
- if (Read <= 0) {
- auto ErrNo = errno;
- if (ErrNo == EAGAIN || ErrNo == EINTR)
- continue;
- else
- return llvm::errorCodeToError(
- std::error_code(errno, std::generic_category()));
- }
- Completed += Read;
- }
- return llvm::Error::success();
- }
-
- llvm::Error appendBytes(const char *Src, unsigned Size) override {
- assert(Src && "Attempt to append from null.");
- ssize_t Completed = 0;
- while (Completed < static_cast<ssize_t>(Size)) {
- ssize_t Written = ::write(OutFD, Src + Completed, Size - Completed);
- if (Written < 0) {
- auto ErrNo = errno;
- if (ErrNo == EAGAIN || ErrNo == EINTR)
- continue;
- else
- return llvm::errorCodeToError(
- std::error_code(errno, std::generic_category()));
- }
- Completed += Written;
- }
- return llvm::Error::success();
- }
-
- llvm::Error send() override { return llvm::Error::success(); }
-
-private:
- int InFD, OutFD;
-};
-
-} // namespace shared
-} // namespace orc
-} // namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_FDRAWBYTECHANNEL_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- FDRawByteChannel.h - File descriptor based byte-channel -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// File descriptor based RawByteChannel.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_FDRAWBYTECHANNEL_H
+#define LLVM_EXECUTIONENGINE_ORC_SHARED_FDRAWBYTECHANNEL_H
+
+#include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h"
+
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+
+namespace llvm {
+namespace orc {
+namespace shared {
+
+/// Serialization channel that reads from and writes from file descriptors.
+class FDRawByteChannel final : public RawByteChannel {
+public:
+ FDRawByteChannel(int InFD, int OutFD) : InFD(InFD), OutFD(OutFD) {}
+
+ llvm::Error readBytes(char *Dst, unsigned Size) override {
+ assert(Dst && "Attempt to read into null.");
+ ssize_t Completed = 0;
+ while (Completed < static_cast<ssize_t>(Size)) {
+ ssize_t Read = ::read(InFD, Dst + Completed, Size - Completed);
+ if (Read <= 0) {
+ auto ErrNo = errno;
+ if (ErrNo == EAGAIN || ErrNo == EINTR)
+ continue;
+ else
+ return llvm::errorCodeToError(
+ std::error_code(errno, std::generic_category()));
+ }
+ Completed += Read;
+ }
+ return llvm::Error::success();
+ }
+
+ llvm::Error appendBytes(const char *Src, unsigned Size) override {
+ assert(Src && "Attempt to append from null.");
+ ssize_t Completed = 0;
+ while (Completed < static_cast<ssize_t>(Size)) {
+ ssize_t Written = ::write(OutFD, Src + Completed, Size - Completed);
+ if (Written < 0) {
+ auto ErrNo = errno;
+ if (ErrNo == EAGAIN || ErrNo == EINTR)
+ continue;
+ else
+ return llvm::errorCodeToError(
+ std::error_code(errno, std::generic_category()));
+ }
+ Completed += Written;
+ }
+ return llvm::Error::success();
+ }
+
+ llvm::Error send() override { return llvm::Error::success(); }
+
+private:
+ int InFD, OutFD;
+};
+
+} // namespace shared
+} // namespace orc
+} // namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_FDRAWBYTECHANNEL_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/OrcError.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/OrcError.h
index 172c35a221..2dde3afdce 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/OrcError.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/OrcError.h
@@ -1,85 +1,85 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===------ OrcError.h - Reject symbol lookup requests ------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Define an error category, error codes, and helper utilities for Orc.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_ORCERROR_H
-#define LLVM_EXECUTIONENGINE_ORC_ORCERROR_H
-
-#include "llvm/Support/Error.h"
-#include "llvm/Support/raw_ostream.h"
-#include <string>
-#include <system_error>
-
-namespace llvm {
-namespace orc {
-
-enum class OrcErrorCode : int {
- // RPC Errors
- UnknownORCError = 1,
- DuplicateDefinition,
- JITSymbolNotFound,
- RemoteAllocatorDoesNotExist,
- RemoteAllocatorIdAlreadyInUse,
- RemoteMProtectAddrUnrecognized,
- RemoteIndirectStubsOwnerDoesNotExist,
- RemoteIndirectStubsOwnerIdAlreadyInUse,
- RPCConnectionClosed,
- RPCCouldNotNegotiateFunction,
- RPCResponseAbandoned,
- UnexpectedRPCCall,
- UnexpectedRPCResponse,
- UnknownErrorCodeFromRemote,
- UnknownResourceHandle,
- MissingSymbolDefinitions,
- UnexpectedSymbolDefinitions,
-};
-
-std::error_code orcError(OrcErrorCode ErrCode);
-
-class DuplicateDefinition : public ErrorInfo<DuplicateDefinition> {
-public:
- static char ID;
-
- DuplicateDefinition(std::string SymbolName);
- std::error_code convertToErrorCode() const override;
- void log(raw_ostream &OS) const override;
- const std::string &getSymbolName() const;
-private:
- std::string SymbolName;
-};
-
-class JITSymbolNotFound : public ErrorInfo<JITSymbolNotFound> {
-public:
- static char ID;
-
- JITSymbolNotFound(std::string SymbolName);
- std::error_code convertToErrorCode() const override;
- void log(raw_ostream &OS) const override;
- const std::string &getSymbolName() const;
-private:
- std::string SymbolName;
-};
-
-} // End namespace orc.
-} // End namespace llvm.
-
-#endif // LLVM_EXECUTIONENGINE_ORC_ORCERROR_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===------ OrcError.h - Reject symbol lookup requests ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Define an error category, error codes, and helper utilities for Orc.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_ORCERROR_H
+#define LLVM_EXECUTIONENGINE_ORC_ORCERROR_H
+
+#include "llvm/Support/Error.h"
+#include "llvm/Support/raw_ostream.h"
+#include <string>
+#include <system_error>
+
+namespace llvm {
+namespace orc {
+
+enum class OrcErrorCode : int {
+ // RPC Errors
+ UnknownORCError = 1,
+ DuplicateDefinition,
+ JITSymbolNotFound,
+ RemoteAllocatorDoesNotExist,
+ RemoteAllocatorIdAlreadyInUse,
+ RemoteMProtectAddrUnrecognized,
+ RemoteIndirectStubsOwnerDoesNotExist,
+ RemoteIndirectStubsOwnerIdAlreadyInUse,
+ RPCConnectionClosed,
+ RPCCouldNotNegotiateFunction,
+ RPCResponseAbandoned,
+ UnexpectedRPCCall,
+ UnexpectedRPCResponse,
+ UnknownErrorCodeFromRemote,
+ UnknownResourceHandle,
+ MissingSymbolDefinitions,
+ UnexpectedSymbolDefinitions,
+};
+
+std::error_code orcError(OrcErrorCode ErrCode);
+
+class DuplicateDefinition : public ErrorInfo<DuplicateDefinition> {
+public:
+ static char ID;
+
+ DuplicateDefinition(std::string SymbolName);
+ std::error_code convertToErrorCode() const override;
+ void log(raw_ostream &OS) const override;
+ const std::string &getSymbolName() const;
+private:
+ std::string SymbolName;
+};
+
+class JITSymbolNotFound : public ErrorInfo<JITSymbolNotFound> {
+public:
+ static char ID;
+
+ JITSymbolNotFound(std::string SymbolName);
+ std::error_code convertToErrorCode() const override;
+ void log(raw_ostream &OS) const override;
+ const std::string &getSymbolName() const;
+private:
+ std::string SymbolName;
+};
+
+} // End namespace orc.
+} // End namespace llvm.
+
+#endif // LLVM_EXECUTIONENGINE_ORC_ORCERROR_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/RPCUtils.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/RPCUtils.h
index 26b64ee2db..4bc6d3577b 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/RPCUtils.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/RPCUtils.h
@@ -1,1668 +1,1668 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- RPCUtils.h - Utilities for building RPC APIs -------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Utilities to support construction of simple RPC APIs.
-//
-// The RPC utilities aim for ease of use (minimal conceptual overhead) for C++
-// programmers, high performance, low memory overhead, and efficient use of the
-// communications channel.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_RPCUTILS_H
-#define LLVM_EXECUTIONENGINE_ORC_SHARED_RPCUTILS_H
-
-#include <map>
-#include <thread>
-#include <vector>
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
-#include "llvm/ExecutionEngine/Orc/Shared/Serialization.h"
-#include "llvm/Support/MSVCErrorWorkarounds.h"
-
-#include <future>
-
-namespace llvm {
-namespace orc {
-namespace shared {
-
-/// Base class of all fatal RPC errors (those that necessarily result in the
-/// termination of the RPC session).
-class RPCFatalError : public ErrorInfo<RPCFatalError> {
-public:
- static char ID;
-};
-
-/// RPCConnectionClosed is returned from RPC operations if the RPC connection
-/// has already been closed due to either an error or graceful disconnection.
-class ConnectionClosed : public ErrorInfo<ConnectionClosed> {
-public:
- static char ID;
- std::error_code convertToErrorCode() const override;
- void log(raw_ostream &OS) const override;
-};
-
-/// BadFunctionCall is returned from handleOne when the remote makes a call with
-/// an unrecognized function id.
-///
-/// This error is fatal because Orc RPC needs to know how to parse a function
-/// call to know where the next call starts, and if it doesn't recognize the
-/// function id it cannot parse the call.
-template <typename FnIdT, typename SeqNoT>
-class BadFunctionCall
- : public ErrorInfo<BadFunctionCall<FnIdT, SeqNoT>, RPCFatalError> {
-public:
- static char ID;
-
- BadFunctionCall(FnIdT FnId, SeqNoT SeqNo)
- : FnId(std::move(FnId)), SeqNo(std::move(SeqNo)) {}
-
- std::error_code convertToErrorCode() const override {
- return orcError(OrcErrorCode::UnexpectedRPCCall);
- }
-
- void log(raw_ostream &OS) const override {
- OS << "Call to invalid RPC function id '" << FnId
- << "' with "
- "sequence number "
- << SeqNo;
- }
-
-private:
- FnIdT FnId;
- SeqNoT SeqNo;
-};
-
-template <typename FnIdT, typename SeqNoT>
-char BadFunctionCall<FnIdT, SeqNoT>::ID = 0;
-
-/// InvalidSequenceNumberForResponse is returned from handleOne when a response
-/// call arrives with a sequence number that doesn't correspond to any in-flight
-/// function call.
-///
-/// This error is fatal because Orc RPC needs to know how to parse the rest of
-/// the response call to know where the next call starts, and if it doesn't have
-/// a result parser for this sequence number it can't do that.
-template <typename SeqNoT>
-class InvalidSequenceNumberForResponse
- : public ErrorInfo<InvalidSequenceNumberForResponse<SeqNoT>,
- RPCFatalError> {
-public:
- static char ID;
-
- InvalidSequenceNumberForResponse(SeqNoT SeqNo) : SeqNo(std::move(SeqNo)) {}
-
- std::error_code convertToErrorCode() const override {
- return orcError(OrcErrorCode::UnexpectedRPCCall);
- };
-
- void log(raw_ostream &OS) const override {
- OS << "Response has unknown sequence number " << SeqNo;
- }
-
-private:
- SeqNoT SeqNo;
-};
-
-template <typename SeqNoT>
-char InvalidSequenceNumberForResponse<SeqNoT>::ID = 0;
-
-/// This non-fatal error will be passed to asynchronous result handlers in place
-/// of a result if the connection goes down before a result returns, or if the
-/// function to be called cannot be negotiated with the remote.
-class ResponseAbandoned : public ErrorInfo<ResponseAbandoned> {
-public:
- static char ID;
-
- std::error_code convertToErrorCode() const override;
- void log(raw_ostream &OS) const override;
-};
-
-/// This error is returned if the remote does not have a handler installed for
-/// the given RPC function.
-class CouldNotNegotiate : public ErrorInfo<CouldNotNegotiate> {
-public:
- static char ID;
-
- CouldNotNegotiate(std::string Signature);
- std::error_code convertToErrorCode() const override;
- void log(raw_ostream &OS) const override;
- const std::string &getSignature() const { return Signature; }
-
-private:
- std::string Signature;
-};
-
-template <typename DerivedFunc, typename FnT> class RPCFunction;
-
-// RPC Function class.
-// DerivedFunc should be a user defined class with a static 'getName()' method
-// returning a const char* representing the function's name.
-template <typename DerivedFunc, typename RetT, typename... ArgTs>
-class RPCFunction<DerivedFunc, RetT(ArgTs...)> {
-public:
- /// User defined function type.
- using Type = RetT(ArgTs...);
-
- /// Return type.
- using ReturnType = RetT;
-
- /// Returns the full function prototype as a string.
- static const char *getPrototype() {
- static std::string Name = [] {
- std::string Name;
- raw_string_ostream(Name)
- << SerializationTypeName<RetT>::getName() << " "
- << DerivedFunc::getName() << "("
- << SerializationTypeNameSequence<ArgTs...>() << ")";
- return Name;
- }();
- return Name.data();
- }
-};
-
-/// Allocates RPC function ids during autonegotiation.
-/// Specializations of this class must provide four members:
-///
-/// static T getInvalidId():
-/// Should return a reserved id that will be used to represent missing
-/// functions during autonegotiation.
-///
-/// static T getResponseId():
-/// Should return a reserved id that will be used to send function responses
-/// (return values).
-///
-/// static T getNegotiateId():
-/// Should return a reserved id for the negotiate function, which will be used
-/// to negotiate ids for user defined functions.
-///
-/// template <typename Func> T allocate():
-/// Allocate a unique id for function Func.
-template <typename T, typename = void> class RPCFunctionIdAllocator;
-
-/// This specialization of RPCFunctionIdAllocator provides a default
-/// implementation for integral types.
-template <typename T>
-class RPCFunctionIdAllocator<T, std::enable_if_t<std::is_integral<T>::value>> {
-public:
- static T getInvalidId() { return T(0); }
- static T getResponseId() { return T(1); }
- static T getNegotiateId() { return T(2); }
-
- template <typename Func> T allocate() { return NextId++; }
-
-private:
- T NextId = 3;
-};
-
-namespace detail {
-
-/// Provides a typedef for a tuple containing the decayed argument types.
-template <typename T> class RPCFunctionArgsTuple;
-
-template <typename RetT, typename... ArgTs>
-class RPCFunctionArgsTuple<RetT(ArgTs...)> {
-public:
- using Type = std::tuple<std::decay_t<std::remove_reference_t<ArgTs>>...>;
-};
-
-// ResultTraits provides typedefs and utilities specific to the return type
-// of functions.
-template <typename RetT> class ResultTraits {
-public:
- // The return type wrapped in llvm::Expected.
- using ErrorReturnType = Expected<RetT>;
-
-#ifdef _MSC_VER
- // The ErrorReturnType wrapped in a std::promise.
- using ReturnPromiseType = std::promise<MSVCPExpected<RetT>>;
-
- // The ErrorReturnType wrapped in a std::future.
- using ReturnFutureType = std::future<MSVCPExpected<RetT>>;
-#else
- // The ErrorReturnType wrapped in a std::promise.
- using ReturnPromiseType = std::promise<ErrorReturnType>;
-
- // The ErrorReturnType wrapped in a std::future.
- using ReturnFutureType = std::future<ErrorReturnType>;
-#endif
-
- // Create a 'blank' value of the ErrorReturnType, ready and safe to
- // overwrite.
- static ErrorReturnType createBlankErrorReturnValue() {
- return ErrorReturnType(RetT());
- }
-
- // Consume an abandoned ErrorReturnType.
- static void consumeAbandoned(ErrorReturnType RetOrErr) {
- consumeError(RetOrErr.takeError());
- }
-};
-
-// ResultTraits specialization for void functions.
-template <> class ResultTraits<void> {
-public:
- // For void functions, ErrorReturnType is llvm::Error.
- using ErrorReturnType = Error;
-
-#ifdef _MSC_VER
- // The ErrorReturnType wrapped in a std::promise.
- using ReturnPromiseType = std::promise<MSVCPError>;
-
- // The ErrorReturnType wrapped in a std::future.
- using ReturnFutureType = std::future<MSVCPError>;
-#else
- // The ErrorReturnType wrapped in a std::promise.
- using ReturnPromiseType = std::promise<ErrorReturnType>;
-
- // The ErrorReturnType wrapped in a std::future.
- using ReturnFutureType = std::future<ErrorReturnType>;
-#endif
-
- // Create a 'blank' value of the ErrorReturnType, ready and safe to
- // overwrite.
- static ErrorReturnType createBlankErrorReturnValue() {
- return ErrorReturnType::success();
- }
-
- // Consume an abandoned ErrorReturnType.
- static void consumeAbandoned(ErrorReturnType Err) {
- consumeError(std::move(Err));
- }
-};
-
-// ResultTraits<Error> is equivalent to ResultTraits<void>. This allows
-// handlers for void RPC functions to return either void (in which case they
-// implicitly succeed) or Error (in which case their error return is
-// propagated). See usage in HandlerTraits::runHandlerHelper.
-template <> class ResultTraits<Error> : public ResultTraits<void> {};
-
-// ResultTraits<Expected<T>> is equivalent to ResultTraits<T>. This allows
-// handlers for RPC functions returning a T to return either a T (in which
-// case they implicitly succeed) or Expected<T> (in which case their error
-// return is propagated). See usage in HandlerTraits::runHandlerHelper.
-template <typename RetT>
-class ResultTraits<Expected<RetT>> : public ResultTraits<RetT> {};
-
-// Determines whether an RPC function's defined error return type supports
-// error return value.
-template <typename T> class SupportsErrorReturn {
-public:
- static const bool value = false;
-};
-
-template <> class SupportsErrorReturn<Error> {
-public:
- static const bool value = true;
-};
-
-template <typename T> class SupportsErrorReturn<Expected<T>> {
-public:
- static const bool value = true;
-};
-
-// RespondHelper packages return values based on whether or not the declared
-// RPC function return type supports error returns.
-template <bool FuncSupportsErrorReturn> class RespondHelper;
-
-// RespondHelper specialization for functions that support error returns.
-template <> class RespondHelper<true> {
-public:
- // Send Expected<T>.
- template <typename WireRetT, typename HandlerRetT, typename ChannelT,
- typename FunctionIdT, typename SequenceNumberT>
- static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
- SequenceNumberT SeqNo,
- Expected<HandlerRetT> ResultOrErr) {
- if (!ResultOrErr && ResultOrErr.template errorIsA<RPCFatalError>())
- return ResultOrErr.takeError();
-
- // Open the response message.
- if (auto Err = C.startSendMessage(ResponseId, SeqNo))
- return Err;
-
- // Serialize the result.
- if (auto Err =
- SerializationTraits<ChannelT, WireRetT, Expected<HandlerRetT>>::
- serialize(C, std::move(ResultOrErr)))
- return Err;
-
- // Close the response message.
- if (auto Err = C.endSendMessage())
- return Err;
- return C.send();
- }
-
- template <typename ChannelT, typename FunctionIdT, typename SequenceNumberT>
- static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
- SequenceNumberT SeqNo, Error Err) {
- if (Err && Err.isA<RPCFatalError>())
- return Err;
- if (auto Err2 = C.startSendMessage(ResponseId, SeqNo))
- return Err2;
- if (auto Err2 = serializeSeq(C, std::move(Err)))
- return Err2;
- if (auto Err2 = C.endSendMessage())
- return Err2;
- return C.send();
- }
-};
-
-// RespondHelper specialization for functions that do not support error returns.
-template <> class RespondHelper<false> {
-public:
- template <typename WireRetT, typename HandlerRetT, typename ChannelT,
- typename FunctionIdT, typename SequenceNumberT>
- static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
- SequenceNumberT SeqNo,
- Expected<HandlerRetT> ResultOrErr) {
- if (auto Err = ResultOrErr.takeError())
- return Err;
-
- // Open the response message.
- if (auto Err = C.startSendMessage(ResponseId, SeqNo))
- return Err;
-
- // Serialize the result.
- if (auto Err =
- SerializationTraits<ChannelT, WireRetT, HandlerRetT>::serialize(
- C, *ResultOrErr))
- return Err;
-
- // End the response message.
- if (auto Err = C.endSendMessage())
- return Err;
-
- return C.send();
- }
-
- template <typename ChannelT, typename FunctionIdT, typename SequenceNumberT>
- static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
- SequenceNumberT SeqNo, Error Err) {
- if (Err)
- return Err;
- if (auto Err2 = C.startSendMessage(ResponseId, SeqNo))
- return Err2;
- if (auto Err2 = C.endSendMessage())
- return Err2;
- return C.send();
- }
-};
-
-// Send a response of the given wire return type (WireRetT) over the
-// channel, with the given sequence number.
-template <typename WireRetT, typename HandlerRetT, typename ChannelT,
- typename FunctionIdT, typename SequenceNumberT>
-Error respond(ChannelT &C, const FunctionIdT &ResponseId, SequenceNumberT SeqNo,
- Expected<HandlerRetT> ResultOrErr) {
- return RespondHelper<SupportsErrorReturn<WireRetT>::value>::
- template sendResult<WireRetT>(C, ResponseId, SeqNo,
- std::move(ResultOrErr));
-}
-
-// Send an empty response message on the given channel to indicate that
-// the handler ran.
-template <typename WireRetT, typename ChannelT, typename FunctionIdT,
- typename SequenceNumberT>
-Error respond(ChannelT &C, const FunctionIdT &ResponseId, SequenceNumberT SeqNo,
- Error Err) {
- return RespondHelper<SupportsErrorReturn<WireRetT>::value>::sendResult(
- C, ResponseId, SeqNo, std::move(Err));
-}
-
-// Converts a given type to the equivalent error return type.
-template <typename T> class WrappedHandlerReturn {
-public:
- using Type = Expected<T>;
-};
-
-template <typename T> class WrappedHandlerReturn<Expected<T>> {
-public:
- using Type = Expected<T>;
-};
-
-template <> class WrappedHandlerReturn<void> {
-public:
- using Type = Error;
-};
-
-template <> class WrappedHandlerReturn<Error> {
-public:
- using Type = Error;
-};
-
-template <> class WrappedHandlerReturn<ErrorSuccess> {
-public:
- using Type = Error;
-};
-
-// Traits class that strips the response function from the list of handler
-// arguments.
-template <typename FnT> class AsyncHandlerTraits;
-
-template <typename ResultT, typename... ArgTs>
-class AsyncHandlerTraits<Error(std::function<Error(Expected<ResultT>)>,
- ArgTs...)> {
-public:
- using Type = Error(ArgTs...);
- using ResultType = Expected<ResultT>;
-};
-
-template <typename... ArgTs>
-class AsyncHandlerTraits<Error(std::function<Error(Error)>, ArgTs...)> {
-public:
- using Type = Error(ArgTs...);
- using ResultType = Error;
-};
-
-template <typename... ArgTs>
-class AsyncHandlerTraits<ErrorSuccess(std::function<Error(Error)>, ArgTs...)> {
-public:
- using Type = Error(ArgTs...);
- using ResultType = Error;
-};
-
-template <typename... ArgTs>
-class AsyncHandlerTraits<void(std::function<Error(Error)>, ArgTs...)> {
-public:
- using Type = Error(ArgTs...);
- using ResultType = Error;
-};
-
-template <typename ResponseHandlerT, typename... ArgTs>
-class AsyncHandlerTraits<Error(ResponseHandlerT, ArgTs...)>
- : public AsyncHandlerTraits<Error(std::decay_t<ResponseHandlerT>,
- ArgTs...)> {};
-
-// This template class provides utilities related to RPC function handlers.
-// The base case applies to non-function types (the template class is
-// specialized for function types) and inherits from the appropriate
-// speciilization for the given non-function type's call operator.
-template <typename HandlerT>
-class HandlerTraits
- : public HandlerTraits<
- decltype(&std::remove_reference<HandlerT>::type::operator())> {};
-
-// Traits for handlers with a given function type.
-template <typename RetT, typename... ArgTs>
-class HandlerTraits<RetT(ArgTs...)> {
-public:
- // Function type of the handler.
- using Type = RetT(ArgTs...);
-
- // Return type of the handler.
- using ReturnType = RetT;
-
- // Call the given handler with the given arguments.
- template <typename HandlerT, typename... TArgTs>
- static typename WrappedHandlerReturn<RetT>::Type
- unpackAndRun(HandlerT &Handler, std::tuple<TArgTs...> &Args) {
- return unpackAndRunHelper(Handler, Args,
- std::index_sequence_for<TArgTs...>());
- }
-
- // Call the given handler with the given arguments.
- template <typename HandlerT, typename ResponderT, typename... TArgTs>
- static Error unpackAndRunAsync(HandlerT &Handler, ResponderT &Responder,
- std::tuple<TArgTs...> &Args) {
- return unpackAndRunAsyncHelper(Handler, Responder, Args,
- std::index_sequence_for<TArgTs...>());
- }
-
- // Call the given handler with the given arguments.
- template <typename HandlerT>
- static std::enable_if_t<
- std::is_void<typename HandlerTraits<HandlerT>::ReturnType>::value, Error>
- run(HandlerT &Handler, ArgTs &&...Args) {
- Handler(std::move(Args)...);
- return Error::success();
- }
-
- template <typename HandlerT, typename... TArgTs>
- static std::enable_if_t<
- !std::is_void<typename HandlerTraits<HandlerT>::ReturnType>::value,
- typename HandlerTraits<HandlerT>::ReturnType>
- run(HandlerT &Handler, TArgTs... Args) {
- return Handler(std::move(Args)...);
- }
-
- // Serialize arguments to the channel.
- template <typename ChannelT, typename... CArgTs>
- static Error serializeArgs(ChannelT &C, const CArgTs... CArgs) {
- return SequenceSerialization<ChannelT, ArgTs...>::serialize(C, CArgs...);
- }
-
- // Deserialize arguments from the channel.
- template <typename ChannelT, typename... CArgTs>
- static Error deserializeArgs(ChannelT &C, std::tuple<CArgTs...> &Args) {
- return deserializeArgsHelper(C, Args, std::index_sequence_for<CArgTs...>());
- }
-
-private:
- template <typename ChannelT, typename... CArgTs, size_t... Indexes>
- static Error deserializeArgsHelper(ChannelT &C, std::tuple<CArgTs...> &Args,
- std::index_sequence<Indexes...> _) {
- return SequenceSerialization<ChannelT, ArgTs...>::deserialize(
- C, std::get<Indexes>(Args)...);
- }
-
- template <typename HandlerT, typename ArgTuple, size_t... Indexes>
- static typename WrappedHandlerReturn<
- typename HandlerTraits<HandlerT>::ReturnType>::Type
- unpackAndRunHelper(HandlerT &Handler, ArgTuple &Args,
- std::index_sequence<Indexes...>) {
- return run(Handler, std::move(std::get<Indexes>(Args))...);
- }
-
- template <typename HandlerT, typename ResponderT, typename ArgTuple,
- size_t... Indexes>
- static typename WrappedHandlerReturn<
- typename HandlerTraits<HandlerT>::ReturnType>::Type
- unpackAndRunAsyncHelper(HandlerT &Handler, ResponderT &Responder,
- ArgTuple &Args, std::index_sequence<Indexes...>) {
- return run(Handler, Responder, std::move(std::get<Indexes>(Args))...);
- }
-};
-
-// Handler traits for free functions.
-template <typename RetT, typename... ArgTs>
-class HandlerTraits<RetT (*)(ArgTs...)> : public HandlerTraits<RetT(ArgTs...)> {
-};
-
-// Handler traits for class methods (especially call operators for lambdas).
-template <typename Class, typename RetT, typename... ArgTs>
-class HandlerTraits<RetT (Class::*)(ArgTs...)>
- : public HandlerTraits<RetT(ArgTs...)> {};
-
-// Handler traits for const class methods (especially call operators for
-// lambdas).
-template <typename Class, typename RetT, typename... ArgTs>
-class HandlerTraits<RetT (Class::*)(ArgTs...) const>
- : public HandlerTraits<RetT(ArgTs...)> {};
-
-// Utility to peel the Expected wrapper off a response handler error type.
-template <typename HandlerT> class ResponseHandlerArg;
-
-template <typename ArgT> class ResponseHandlerArg<Error(Expected<ArgT>)> {
-public:
- using ArgType = Expected<ArgT>;
- using UnwrappedArgType = ArgT;
-};
-
-template <typename ArgT>
-class ResponseHandlerArg<ErrorSuccess(Expected<ArgT>)> {
-public:
- using ArgType = Expected<ArgT>;
- using UnwrappedArgType = ArgT;
-};
-
-template <> class ResponseHandlerArg<Error(Error)> {
-public:
- using ArgType = Error;
-};
-
-template <> class ResponseHandlerArg<ErrorSuccess(Error)> {
-public:
- using ArgType = Error;
-};
-
-// ResponseHandler represents a handler for a not-yet-received function call
-// result.
-template <typename ChannelT> class ResponseHandler {
-public:
- virtual ~ResponseHandler() {}
-
- // Reads the function result off the wire and acts on it. The meaning of
- // "act" will depend on how this method is implemented in any given
- // ResponseHandler subclass but could, for example, mean running a
- // user-specified handler or setting a promise value.
- virtual Error handleResponse(ChannelT &C) = 0;
-
- // Abandons this outstanding result.
- virtual void abandon() = 0;
-
- // Create an error instance representing an abandoned response.
- static Error createAbandonedResponseError() {
- return make_error<ResponseAbandoned>();
- }
-};
-
-// ResponseHandler subclass for RPC functions with non-void returns.
-template <typename ChannelT, typename FuncRetT, typename HandlerT>
-class ResponseHandlerImpl : public ResponseHandler<ChannelT> {
-public:
- ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
-
- // Handle the result by deserializing it from the channel then passing it
- // to the user defined handler.
- Error handleResponse(ChannelT &C) override {
- using UnwrappedArgType = typename ResponseHandlerArg<
- typename HandlerTraits<HandlerT>::Type>::UnwrappedArgType;
- UnwrappedArgType Result;
- if (auto Err =
- SerializationTraits<ChannelT, FuncRetT,
- UnwrappedArgType>::deserialize(C, Result))
- return Err;
- if (auto Err = C.endReceiveMessage())
- return Err;
- return Handler(std::move(Result));
- }
-
- // Abandon this response by calling the handler with an 'abandoned response'
- // error.
- void abandon() override {
- if (auto Err = Handler(this->createAbandonedResponseError())) {
- // Handlers should not fail when passed an abandoned response error.
- report_fatal_error(std::move(Err));
- }
- }
-
-private:
- HandlerT Handler;
-};
-
-// ResponseHandler subclass for RPC functions with void returns.
-template <typename ChannelT, typename HandlerT>
-class ResponseHandlerImpl<ChannelT, void, HandlerT>
- : public ResponseHandler<ChannelT> {
-public:
- ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
-
- // Handle the result (no actual value, just a notification that the function
- // has completed on the remote end) by calling the user-defined handler with
- // Error::success().
- Error handleResponse(ChannelT &C) override {
- if (auto Err = C.endReceiveMessage())
- return Err;
- return Handler(Error::success());
- }
-
- // Abandon this response by calling the handler with an 'abandoned response'
- // error.
- void abandon() override {
- if (auto Err = Handler(this->createAbandonedResponseError())) {
- // Handlers should not fail when passed an abandoned response error.
- report_fatal_error(std::move(Err));
- }
- }
-
-private:
- HandlerT Handler;
-};
-
-template <typename ChannelT, typename FuncRetT, typename HandlerT>
-class ResponseHandlerImpl<ChannelT, Expected<FuncRetT>, HandlerT>
- : public ResponseHandler<ChannelT> {
-public:
- ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
-
- // Handle the result by deserializing it from the channel then passing it
- // to the user defined handler.
- Error handleResponse(ChannelT &C) override {
- using HandlerArgType = typename ResponseHandlerArg<
- typename HandlerTraits<HandlerT>::Type>::ArgType;
- HandlerArgType Result((typename HandlerArgType::value_type()));
-
- if (auto Err = SerializationTraits<ChannelT, Expected<FuncRetT>,
- HandlerArgType>::deserialize(C, Result))
- return Err;
- if (auto Err = C.endReceiveMessage())
- return Err;
- return Handler(std::move(Result));
- }
-
- // Abandon this response by calling the handler with an 'abandoned response'
- // error.
- void abandon() override {
- if (auto Err = Handler(this->createAbandonedResponseError())) {
- // Handlers should not fail when passed an abandoned response error.
- report_fatal_error(std::move(Err));
- }
- }
-
-private:
- HandlerT Handler;
-};
-
-template <typename ChannelT, typename HandlerT>
-class ResponseHandlerImpl<ChannelT, Error, HandlerT>
- : public ResponseHandler<ChannelT> {
-public:
- ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
-
- // Handle the result by deserializing it from the channel then passing it
- // to the user defined handler.
- Error handleResponse(ChannelT &C) override {
- Error Result = Error::success();
- if (auto Err = SerializationTraits<ChannelT, Error, Error>::deserialize(
- C, Result)) {
- consumeError(std::move(Result));
- return Err;
- }
- if (auto Err = C.endReceiveMessage()) {
- consumeError(std::move(Result));
- return Err;
- }
- return Handler(std::move(Result));
- }
-
- // Abandon this response by calling the handler with an 'abandoned response'
- // error.
- void abandon() override {
- if (auto Err = Handler(this->createAbandonedResponseError())) {
- // Handlers should not fail when passed an abandoned response error.
- report_fatal_error(std::move(Err));
- }
- }
-
-private:
- HandlerT Handler;
-};
-
-// Create a ResponseHandler from a given user handler.
-template <typename ChannelT, typename FuncRetT, typename HandlerT>
-std::unique_ptr<ResponseHandler<ChannelT>> createResponseHandler(HandlerT H) {
- return std::make_unique<ResponseHandlerImpl<ChannelT, FuncRetT, HandlerT>>(
- std::move(H));
-}
-
-// Helper for wrapping member functions up as functors. This is useful for
-// installing methods as result handlers.
-template <typename ClassT, typename RetT, typename... ArgTs>
-class MemberFnWrapper {
-public:
- using MethodT = RetT (ClassT::*)(ArgTs...);
- MemberFnWrapper(ClassT &Instance, MethodT Method)
- : Instance(Instance), Method(Method) {}
- RetT operator()(ArgTs &&...Args) {
- return (Instance.*Method)(std::move(Args)...);
- }
-
-private:
- ClassT &Instance;
- MethodT Method;
-};
-
-// Helper that provides a Functor for deserializing arguments.
-template <typename... ArgTs> class ReadArgs {
-public:
- Error operator()() { return Error::success(); }
-};
-
-template <typename ArgT, typename... ArgTs>
-class ReadArgs<ArgT, ArgTs...> : public ReadArgs<ArgTs...> {
-public:
- ReadArgs(ArgT &Arg, ArgTs &...Args) : ReadArgs<ArgTs...>(Args...), Arg(Arg) {}
-
- Error operator()(ArgT &ArgVal, ArgTs &...ArgVals) {
- this->Arg = std::move(ArgVal);
- return ReadArgs<ArgTs...>::operator()(ArgVals...);
- }
-
-private:
- ArgT &Arg;
-};
-
-// Manage sequence numbers.
-template <typename SequenceNumberT> class SequenceNumberManager {
-public:
- // Reset, making all sequence numbers available.
- void reset() {
- std::lock_guard<std::mutex> Lock(SeqNoLock);
- NextSequenceNumber = 0;
- FreeSequenceNumbers.clear();
- }
-
- // Get the next available sequence number. Will re-use numbers that have
- // been released.
- SequenceNumberT getSequenceNumber() {
- std::lock_guard<std::mutex> Lock(SeqNoLock);
- if (FreeSequenceNumbers.empty())
- return NextSequenceNumber++;
- auto SequenceNumber = FreeSequenceNumbers.back();
- FreeSequenceNumbers.pop_back();
- return SequenceNumber;
- }
-
- // Release a sequence number, making it available for re-use.
- void releaseSequenceNumber(SequenceNumberT SequenceNumber) {
- std::lock_guard<std::mutex> Lock(SeqNoLock);
- FreeSequenceNumbers.push_back(SequenceNumber);
- }
-
-private:
- std::mutex SeqNoLock;
- SequenceNumberT NextSequenceNumber = 0;
- std::vector<SequenceNumberT> FreeSequenceNumbers;
-};
-
-// Checks that predicate P holds for each corresponding pair of type arguments
-// from T1 and T2 tuple.
-template <template <class, class> class P, typename T1Tuple, typename T2Tuple>
-class RPCArgTypeCheckHelper;
-
-template <template <class, class> class P>
-class RPCArgTypeCheckHelper<P, std::tuple<>, std::tuple<>> {
-public:
- static const bool value = true;
-};
-
-template <template <class, class> class P, typename T, typename... Ts,
- typename U, typename... Us>
-class RPCArgTypeCheckHelper<P, std::tuple<T, Ts...>, std::tuple<U, Us...>> {
-public:
- static const bool value =
- P<T, U>::value &&
- RPCArgTypeCheckHelper<P, std::tuple<Ts...>, std::tuple<Us...>>::value;
-};
-
-template <template <class, class> class P, typename T1Sig, typename T2Sig>
-class RPCArgTypeCheck {
-public:
- using T1Tuple = typename RPCFunctionArgsTuple<T1Sig>::Type;
- using T2Tuple = typename RPCFunctionArgsTuple<T2Sig>::Type;
-
- static_assert(std::tuple_size<T1Tuple>::value >=
- std::tuple_size<T2Tuple>::value,
- "Too many arguments to RPC call");
- static_assert(std::tuple_size<T1Tuple>::value <=
- std::tuple_size<T2Tuple>::value,
- "Too few arguments to RPC call");
-
- static const bool value = RPCArgTypeCheckHelper<P, T1Tuple, T2Tuple>::value;
-};
-
-template <typename ChannelT, typename WireT, typename ConcreteT>
-class CanSerialize {
-private:
- using S = SerializationTraits<ChannelT, WireT, ConcreteT>;
-
- template <typename T>
- static std::true_type check(
- std::enable_if_t<std::is_same<decltype(T::serialize(
- std::declval<ChannelT &>(),
- std::declval<const ConcreteT &>())),
- Error>::value,
- void *>);
-
- template <typename> static std::false_type check(...);
-
-public:
- static const bool value = decltype(check<S>(0))::value;
-};
-
-template <typename ChannelT, typename WireT, typename ConcreteT>
-class CanDeserialize {
-private:
- using S = SerializationTraits<ChannelT, WireT, ConcreteT>;
-
- template <typename T>
- static std::true_type
- check(std::enable_if_t<
- std::is_same<decltype(T::deserialize(std::declval<ChannelT &>(),
- std::declval<ConcreteT &>())),
- Error>::value,
- void *>);
-
- template <typename> static std::false_type check(...);
-
-public:
- static const bool value = decltype(check<S>(0))::value;
-};
-
-/// Contains primitive utilities for defining, calling and handling calls to
-/// remote procedures. ChannelT is a bidirectional stream conforming to the
-/// RPCChannel interface (see RPCChannel.h), FunctionIdT is a procedure
-/// identifier type that must be serializable on ChannelT, and SequenceNumberT
-/// is an integral type that will be used to number in-flight function calls.
-///
-/// These utilities support the construction of very primitive RPC utilities.
-/// Their intent is to ensure correct serialization and deserialization of
-/// procedure arguments, and to keep the client and server's view of the API in
-/// sync.
-template <typename ImplT, typename ChannelT, typename FunctionIdT,
- typename SequenceNumberT>
-class RPCEndpointBase {
-protected:
- class OrcRPCInvalid : public RPCFunction<OrcRPCInvalid, void()> {
- public:
- static const char *getName() { return "__orc_rpc$invalid"; }
- };
-
- class OrcRPCResponse : public RPCFunction<OrcRPCResponse, void()> {
- public:
- static const char *getName() { return "__orc_rpc$response"; }
- };
-
- class OrcRPCNegotiate
- : public RPCFunction<OrcRPCNegotiate, FunctionIdT(std::string)> {
- public:
- static const char *getName() { return "__orc_rpc$negotiate"; }
- };
-
- // Helper predicate for testing for the presence of SerializeTraits
- // serializers.
- template <typename WireT, typename ConcreteT>
- class CanSerializeCheck : detail::CanSerialize<ChannelT, WireT, ConcreteT> {
- public:
- using detail::CanSerialize<ChannelT, WireT, ConcreteT>::value;
-
- static_assert(value, "Missing serializer for argument (Can't serialize the "
- "first template type argument of CanSerializeCheck "
- "from the second)");
- };
-
- // Helper predicate for testing for the presence of SerializeTraits
- // deserializers.
- template <typename WireT, typename ConcreteT>
- class CanDeserializeCheck
- : detail::CanDeserialize<ChannelT, WireT, ConcreteT> {
- public:
- using detail::CanDeserialize<ChannelT, WireT, ConcreteT>::value;
-
- static_assert(value, "Missing deserializer for argument (Can't deserialize "
- "the second template type argument of "
- "CanDeserializeCheck from the first)");
- };
-
-public:
- /// Construct an RPC instance on a channel.
- RPCEndpointBase(ChannelT &C, bool LazyAutoNegotiation)
- : C(C), LazyAutoNegotiation(LazyAutoNegotiation) {
- // Hold ResponseId in a special variable, since we expect Response to be
- // called relatively frequently, and want to avoid the map lookup.
- ResponseId = FnIdAllocator.getResponseId();
- RemoteFunctionIds[OrcRPCResponse::getPrototype()] = ResponseId;
-
- // Register the negotiate function id and handler.
- auto NegotiateId = FnIdAllocator.getNegotiateId();
- RemoteFunctionIds[OrcRPCNegotiate::getPrototype()] = NegotiateId;
- Handlers[NegotiateId] = wrapHandler<OrcRPCNegotiate>(
- [this](const std::string &Name) { return handleNegotiate(Name); });
- }
-
- /// Negotiate a function id for Func with the other end of the channel.
- template <typename Func> Error negotiateFunction(bool Retry = false) {
- return getRemoteFunctionId<Func>(true, Retry).takeError();
- }
-
- /// Append a call Func, does not call send on the channel.
- /// The first argument specifies a user-defined handler to be run when the
- /// function returns. The handler should take an Expected<Func::ReturnType>,
- /// or an Error (if Func::ReturnType is void). The handler will be called
- /// with an error if the return value is abandoned due to a channel error.
- template <typename Func, typename HandlerT, typename... ArgTs>
- Error appendCallAsync(HandlerT Handler, const ArgTs &...Args) {
-
- static_assert(
- detail::RPCArgTypeCheck<CanSerializeCheck, typename Func::Type,
- void(ArgTs...)>::value,
- "");
-
- // Look up the function ID.
- FunctionIdT FnId;
- if (auto FnIdOrErr = getRemoteFunctionId<Func>(LazyAutoNegotiation, false))
- FnId = *FnIdOrErr;
- else {
- // Negotiation failed. Notify the handler then return the negotiate-failed
- // error.
- cantFail(Handler(make_error<ResponseAbandoned>()));
- return FnIdOrErr.takeError();
- }
-
- SequenceNumberT SeqNo; // initialized in locked scope below.
- {
- // Lock the pending responses map and sequence number manager.
- std::lock_guard<std::mutex> Lock(ResponsesMutex);
-
- // Allocate a sequence number.
- SeqNo = SequenceNumberMgr.getSequenceNumber();
- assert(!PendingResponses.count(SeqNo) &&
- "Sequence number already allocated");
-
- // Install the user handler.
- PendingResponses[SeqNo] =
- detail::createResponseHandler<ChannelT, typename Func::ReturnType>(
- std::move(Handler));
- }
-
- // Open the function call message.
- if (auto Err = C.startSendMessage(FnId, SeqNo)) {
- abandonPendingResponses();
- return Err;
- }
-
- // Serialize the call arguments.
- if (auto Err = detail::HandlerTraits<typename Func::Type>::serializeArgs(
- C, Args...)) {
- abandonPendingResponses();
- return Err;
- }
-
- // Close the function call messagee.
- if (auto Err = C.endSendMessage()) {
- abandonPendingResponses();
- return Err;
- }
-
- return Error::success();
- }
-
- Error sendAppendedCalls() { return C.send(); };
-
- template <typename Func, typename HandlerT, typename... ArgTs>
- Error callAsync(HandlerT Handler, const ArgTs &...Args) {
- if (auto Err = appendCallAsync<Func>(std::move(Handler), Args...))
- return Err;
- return C.send();
- }
-
- /// Handle one incoming call.
- Error handleOne() {
- FunctionIdT FnId;
- SequenceNumberT SeqNo;
- if (auto Err = C.startReceiveMessage(FnId, SeqNo)) {
- abandonPendingResponses();
- return Err;
- }
- if (FnId == ResponseId)
- return handleResponse(SeqNo);
- auto I = Handlers.find(FnId);
- if (I != Handlers.end())
- return I->second(C, SeqNo);
-
- // else: No handler found. Report error to client?
- return make_error<BadFunctionCall<FunctionIdT, SequenceNumberT>>(FnId,
- SeqNo);
- }
-
- /// Helper for handling setter procedures - this method returns a functor that
- /// sets the variables referred to by Args... to values deserialized from the
- /// channel.
- /// E.g.
- ///
- /// typedef Function<0, bool, int> Func1;
- ///
- /// ...
- /// bool B;
- /// int I;
- /// if (auto Err = expect<Func1>(Channel, readArgs(B, I)))
- /// /* Handle Args */ ;
- ///
- template <typename... ArgTs>
- static detail::ReadArgs<ArgTs...> readArgs(ArgTs &...Args) {
- return detail::ReadArgs<ArgTs...>(Args...);
- }
-
- /// Abandon all outstanding result handlers.
- ///
- /// This will call all currently registered result handlers to receive an
- /// "abandoned" error as their argument. This is used internally by the RPC
- /// in error situations, but can also be called directly by clients who are
- /// disconnecting from the remote and don't or can't expect responses to their
- /// outstanding calls. (Especially for outstanding blocking calls, calling
- /// this function may be necessary to avoid dead threads).
- void abandonPendingResponses() {
- // Lock the pending responses map and sequence number manager.
- std::lock_guard<std::mutex> Lock(ResponsesMutex);
-
- for (auto &KV : PendingResponses)
- KV.second->abandon();
- PendingResponses.clear();
- SequenceNumberMgr.reset();
- }
-
- /// Remove the handler for the given function.
- /// A handler must currently be registered for this function.
- template <typename Func> void removeHandler() {
- auto IdItr = LocalFunctionIds.find(Func::getPrototype());
- assert(IdItr != LocalFunctionIds.end() &&
- "Function does not have a registered handler");
- auto HandlerItr = Handlers.find(IdItr->second);
- assert(HandlerItr != Handlers.end() &&
- "Function does not have a registered handler");
- Handlers.erase(HandlerItr);
- }
-
- /// Clear all handlers.
- void clearHandlers() { Handlers.clear(); }
-
-protected:
- FunctionIdT getInvalidFunctionId() const {
- return FnIdAllocator.getInvalidId();
- }
-
- /// Add the given handler to the handler map and make it available for
- /// autonegotiation and execution.
- template <typename Func, typename HandlerT>
- void addHandlerImpl(HandlerT Handler) {
-
- static_assert(detail::RPCArgTypeCheck<
- CanDeserializeCheck, typename Func::Type,
- typename detail::HandlerTraits<HandlerT>::Type>::value,
- "");
-
- FunctionIdT NewFnId = FnIdAllocator.template allocate<Func>();
- LocalFunctionIds[Func::getPrototype()] = NewFnId;
- Handlers[NewFnId] = wrapHandler<Func>(std::move(Handler));
- }
-
- template <typename Func, typename HandlerT>
- void addAsyncHandlerImpl(HandlerT Handler) {
-
- static_assert(
- detail::RPCArgTypeCheck<
- CanDeserializeCheck, typename Func::Type,
- typename detail::AsyncHandlerTraits<
- typename detail::HandlerTraits<HandlerT>::Type>::Type>::value,
- "");
-
- FunctionIdT NewFnId = FnIdAllocator.template allocate<Func>();
- LocalFunctionIds[Func::getPrototype()] = NewFnId;
- Handlers[NewFnId] = wrapAsyncHandler<Func>(std::move(Handler));
- }
-
- Error handleResponse(SequenceNumberT SeqNo) {
- using Handler = typename decltype(PendingResponses)::mapped_type;
- Handler PRHandler;
-
- {
- // Lock the pending responses map and sequence number manager.
- std::unique_lock<std::mutex> Lock(ResponsesMutex);
- auto I = PendingResponses.find(SeqNo);
-
- if (I != PendingResponses.end()) {
- PRHandler = std::move(I->second);
- PendingResponses.erase(I);
- SequenceNumberMgr.releaseSequenceNumber(SeqNo);
- } else {
- // Unlock the pending results map to prevent recursive lock.
- Lock.unlock();
- abandonPendingResponses();
- return make_error<InvalidSequenceNumberForResponse<SequenceNumberT>>(
- SeqNo);
- }
- }
-
- assert(PRHandler &&
- "If we didn't find a response handler we should have bailed out");
-
- if (auto Err = PRHandler->handleResponse(C)) {
- abandonPendingResponses();
- return Err;
- }
-
- return Error::success();
- }
-
- FunctionIdT handleNegotiate(const std::string &Name) {
- auto I = LocalFunctionIds.find(Name);
- if (I == LocalFunctionIds.end())
- return getInvalidFunctionId();
- return I->second;
- }
-
- // Find the remote FunctionId for the given function.
- template <typename Func>
- Expected<FunctionIdT> getRemoteFunctionId(bool NegotiateIfNotInMap,
- bool NegotiateIfInvalid) {
- bool DoNegotiate;
-
- // Check if we already have a function id...
- auto I = RemoteFunctionIds.find(Func::getPrototype());
- if (I != RemoteFunctionIds.end()) {
- // If it's valid there's nothing left to do.
- if (I->second != getInvalidFunctionId())
- return I->second;
- DoNegotiate = NegotiateIfInvalid;
- } else
- DoNegotiate = NegotiateIfNotInMap;
-
- // We don't have a function id for Func yet, but we're allowed to try to
- // negotiate one.
- if (DoNegotiate) {
- auto &Impl = static_cast<ImplT &>(*this);
- if (auto RemoteIdOrErr =
- Impl.template callB<OrcRPCNegotiate>(Func::getPrototype())) {
- RemoteFunctionIds[Func::getPrototype()] = *RemoteIdOrErr;
- if (*RemoteIdOrErr == getInvalidFunctionId())
- return make_error<CouldNotNegotiate>(Func::getPrototype());
- return *RemoteIdOrErr;
- } else
- return RemoteIdOrErr.takeError();
- }
-
- // No key was available in the map and we weren't allowed to try to
- // negotiate one, so return an unknown function error.
- return make_error<CouldNotNegotiate>(Func::getPrototype());
- }
-
- using WrappedHandlerFn = std::function<Error(ChannelT &, SequenceNumberT)>;
-
- // Wrap the given user handler in the necessary argument-deserialization code,
- // result-serialization code, and call to the launch policy (if present).
- template <typename Func, typename HandlerT>
- WrappedHandlerFn wrapHandler(HandlerT Handler) {
- return [this, Handler](ChannelT &Channel,
- SequenceNumberT SeqNo) mutable -> Error {
- // Start by deserializing the arguments.
- using ArgsTuple = typename detail::RPCFunctionArgsTuple<
- typename detail::HandlerTraits<HandlerT>::Type>::Type;
- auto Args = std::make_shared<ArgsTuple>();
-
- if (auto Err =
- detail::HandlerTraits<typename Func::Type>::deserializeArgs(
- Channel, *Args))
- return Err;
-
- // GCC 4.7 and 4.8 incorrectly issue a -Wunused-but-set-variable warning
- // for RPCArgs. Void cast RPCArgs to work around this for now.
- // FIXME: Remove this workaround once we can assume a working GCC version.
- (void)Args;
-
- // End receieve message, unlocking the channel for reading.
- if (auto Err = Channel.endReceiveMessage())
- return Err;
-
- using HTraits = detail::HandlerTraits<HandlerT>;
- using FuncReturn = typename Func::ReturnType;
- return detail::respond<FuncReturn>(Channel, ResponseId, SeqNo,
- HTraits::unpackAndRun(Handler, *Args));
- };
- }
-
- // Wrap the given user handler in the necessary argument-deserialization code,
- // result-serialization code, and call to the launch policy (if present).
- template <typename Func, typename HandlerT>
- WrappedHandlerFn wrapAsyncHandler(HandlerT Handler) {
- return [this, Handler](ChannelT &Channel,
- SequenceNumberT SeqNo) mutable -> Error {
- // Start by deserializing the arguments.
- using AHTraits = detail::AsyncHandlerTraits<
- typename detail::HandlerTraits<HandlerT>::Type>;
- using ArgsTuple =
- typename detail::RPCFunctionArgsTuple<typename AHTraits::Type>::Type;
- auto Args = std::make_shared<ArgsTuple>();
-
- if (auto Err =
- detail::HandlerTraits<typename Func::Type>::deserializeArgs(
- Channel, *Args))
- return Err;
-
- // GCC 4.7 and 4.8 incorrectly issue a -Wunused-but-set-variable warning
- // for RPCArgs. Void cast RPCArgs to work around this for now.
- // FIXME: Remove this workaround once we can assume a working GCC version.
- (void)Args;
-
- // End receieve message, unlocking the channel for reading.
- if (auto Err = Channel.endReceiveMessage())
- return Err;
-
- using HTraits = detail::HandlerTraits<HandlerT>;
- using FuncReturn = typename Func::ReturnType;
- auto Responder = [this,
- SeqNo](typename AHTraits::ResultType RetVal) -> Error {
- return detail::respond<FuncReturn>(C, ResponseId, SeqNo,
- std::move(RetVal));
- };
-
- return HTraits::unpackAndRunAsync(Handler, Responder, *Args);
- };
- }
-
- ChannelT &C;
-
- bool LazyAutoNegotiation;
-
- RPCFunctionIdAllocator<FunctionIdT> FnIdAllocator;
-
- FunctionIdT ResponseId;
- std::map<std::string, FunctionIdT> LocalFunctionIds;
- std::map<const char *, FunctionIdT> RemoteFunctionIds;
-
- std::map<FunctionIdT, WrappedHandlerFn> Handlers;
-
- std::mutex ResponsesMutex;
- detail::SequenceNumberManager<SequenceNumberT> SequenceNumberMgr;
- std::map<SequenceNumberT, std::unique_ptr<detail::ResponseHandler<ChannelT>>>
- PendingResponses;
-};
-
-} // end namespace detail
-
-template <typename ChannelT, typename FunctionIdT = uint32_t,
- typename SequenceNumberT = uint32_t>
-class MultiThreadedRPCEndpoint
- : public detail::RPCEndpointBase<
- MultiThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
- ChannelT, FunctionIdT, SequenceNumberT> {
-private:
- using BaseClass = detail::RPCEndpointBase<
- MultiThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
- ChannelT, FunctionIdT, SequenceNumberT>;
-
-public:
- MultiThreadedRPCEndpoint(ChannelT &C, bool LazyAutoNegotiation)
- : BaseClass(C, LazyAutoNegotiation) {}
-
- /// Add a handler for the given RPC function.
- /// This installs the given handler functor for the given RPCFunction, and
- /// makes the RPC function available for negotiation/calling from the remote.
- template <typename Func, typename HandlerT>
- void addHandler(HandlerT Handler) {
- return this->template addHandlerImpl<Func>(std::move(Handler));
- }
-
- /// Add a class-method as a handler.
- template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
- void addHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
- addHandler<Func>(
- detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
- }
-
- template <typename Func, typename HandlerT>
- void addAsyncHandler(HandlerT Handler) {
- return this->template addAsyncHandlerImpl<Func>(std::move(Handler));
- }
-
- /// Add a class-method as a handler.
- template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
- void addAsyncHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
- addAsyncHandler<Func>(
- detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
- }
-
- /// Return type for non-blocking call primitives.
- template <typename Func>
- using NonBlockingCallResult = typename detail::ResultTraits<
- typename Func::ReturnType>::ReturnFutureType;
-
- /// Call Func on Channel C. Does not block, does not call send. Returns a pair
- /// of a future result and the sequence number assigned to the result.
- ///
- /// This utility function is primarily used for single-threaded mode support,
- /// where the sequence number can be used to wait for the corresponding
- /// result. In multi-threaded mode the appendCallNB method, which does not
- /// return the sequence numeber, should be preferred.
- template <typename Func, typename... ArgTs>
- Expected<NonBlockingCallResult<Func>> appendCallNB(const ArgTs &...Args) {
- using RTraits = detail::ResultTraits<typename Func::ReturnType>;
- using ErrorReturn = typename RTraits::ErrorReturnType;
- using ErrorReturnPromise = typename RTraits::ReturnPromiseType;
-
- ErrorReturnPromise Promise;
- auto FutureResult = Promise.get_future();
-
- if (auto Err = this->template appendCallAsync<Func>(
- [Promise = std::move(Promise)](ErrorReturn RetOrErr) mutable {
- Promise.set_value(std::move(RetOrErr));
- return Error::success();
- },
- Args...)) {
- RTraits::consumeAbandoned(FutureResult.get());
- return std::move(Err);
- }
- return std::move(FutureResult);
- }
-
- /// The same as appendCallNBWithSeq, except that it calls C.send() to
- /// flush the channel after serializing the call.
- template <typename Func, typename... ArgTs>
- Expected<NonBlockingCallResult<Func>> callNB(const ArgTs &...Args) {
- auto Result = appendCallNB<Func>(Args...);
- if (!Result)
- return Result;
- if (auto Err = this->C.send()) {
- this->abandonPendingResponses();
- detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
- std::move(Result->get()));
- return std::move(Err);
- }
- return Result;
- }
-
- /// Call Func on Channel C. Blocks waiting for a result. Returns an Error
- /// for void functions or an Expected<T> for functions returning a T.
- ///
- /// This function is for use in threaded code where another thread is
- /// handling responses and incoming calls.
- template <typename Func, typename... ArgTs,
- typename AltRetT = typename Func::ReturnType>
- typename detail::ResultTraits<AltRetT>::ErrorReturnType
- callB(const ArgTs &...Args) {
- if (auto FutureResOrErr = callNB<Func>(Args...))
- return FutureResOrErr->get();
- else
- return FutureResOrErr.takeError();
- }
-
- /// Handle incoming RPC calls.
- Error handlerLoop() {
- while (true)
- if (auto Err = this->handleOne())
- return Err;
- return Error::success();
- }
-};
-
-template <typename ChannelT, typename FunctionIdT = uint32_t,
- typename SequenceNumberT = uint32_t>
-class SingleThreadedRPCEndpoint
- : public detail::RPCEndpointBase<
- SingleThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
- ChannelT, FunctionIdT, SequenceNumberT> {
-private:
- using BaseClass = detail::RPCEndpointBase<
- SingleThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
- ChannelT, FunctionIdT, SequenceNumberT>;
-
-public:
- SingleThreadedRPCEndpoint(ChannelT &C, bool LazyAutoNegotiation)
- : BaseClass(C, LazyAutoNegotiation) {}
-
- template <typename Func, typename HandlerT>
- void addHandler(HandlerT Handler) {
- return this->template addHandlerImpl<Func>(std::move(Handler));
- }
-
- template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
- void addHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
- addHandler<Func>(
- detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
- }
-
- template <typename Func, typename HandlerT>
- void addAsyncHandler(HandlerT Handler) {
- return this->template addAsyncHandlerImpl<Func>(std::move(Handler));
- }
-
- /// Add a class-method as a handler.
- template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
- void addAsyncHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
- addAsyncHandler<Func>(
- detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
- }
-
- template <typename Func, typename... ArgTs,
- typename AltRetT = typename Func::ReturnType>
- typename detail::ResultTraits<AltRetT>::ErrorReturnType
- callB(const ArgTs &...Args) {
- bool ReceivedResponse = false;
- using ResultType = typename detail::ResultTraits<AltRetT>::ErrorReturnType;
- auto Result = detail::ResultTraits<AltRetT>::createBlankErrorReturnValue();
-
- // We have to 'Check' result (which we know is in a success state at this
- // point) so that it can be overwritten in the async handler.
- (void)!!Result;
-
- if (auto Err = this->template appendCallAsync<Func>(
- [&](ResultType R) {
- Result = std::move(R);
- ReceivedResponse = true;
- return Error::success();
- },
- Args...)) {
- detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
- std::move(Result));
- return std::move(Err);
- }
-
- if (auto Err = this->C.send()) {
- detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
- std::move(Result));
- return std::move(Err);
- }
-
- while (!ReceivedResponse) {
- if (auto Err = this->handleOne()) {
- detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
- std::move(Result));
- return std::move(Err);
- }
- }
-
- return Result;
- }
-};
-
-/// Asynchronous dispatch for a function on an RPC endpoint.
-template <typename RPCClass, typename Func> class RPCAsyncDispatch {
-public:
- RPCAsyncDispatch(RPCClass &Endpoint) : Endpoint(Endpoint) {}
-
- template <typename HandlerT, typename... ArgTs>
- Error operator()(HandlerT Handler, const ArgTs &...Args) const {
- return Endpoint.template appendCallAsync<Func>(std::move(Handler), Args...);
- }
-
-private:
- RPCClass &Endpoint;
-};
-
-/// Construct an asynchronous dispatcher from an RPC endpoint and a Func.
-template <typename Func, typename RPCEndpointT>
-RPCAsyncDispatch<RPCEndpointT, Func> rpcAsyncDispatch(RPCEndpointT &Endpoint) {
- return RPCAsyncDispatch<RPCEndpointT, Func>(Endpoint);
-}
-
-/// Allows a set of asynchrounous calls to be dispatched, and then
-/// waited on as a group.
-class ParallelCallGroup {
-public:
- ParallelCallGroup() = default;
- ParallelCallGroup(const ParallelCallGroup &) = delete;
- ParallelCallGroup &operator=(const ParallelCallGroup &) = delete;
-
- /// Make as asynchronous call.
- template <typename AsyncDispatcher, typename HandlerT, typename... ArgTs>
- Error call(const AsyncDispatcher &AsyncDispatch, HandlerT Handler,
- const ArgTs &...Args) {
- // Increment the count of outstanding calls. This has to happen before
- // we invoke the call, as the handler may (depending on scheduling)
- // be run immediately on another thread, and we don't want the decrement
- // in the wrapped handler below to run before the increment.
- {
- std::unique_lock<std::mutex> Lock(M);
- ++NumOutstandingCalls;
- }
-
- // Wrap the user handler in a lambda that will decrement the
- // outstanding calls count, then poke the condition variable.
- using ArgType = typename detail::ResponseHandlerArg<
- typename detail::HandlerTraits<HandlerT>::Type>::ArgType;
- auto WrappedHandler = [this, Handler = std::move(Handler)](ArgType Arg) {
- auto Err = Handler(std::move(Arg));
- std::unique_lock<std::mutex> Lock(M);
- --NumOutstandingCalls;
- CV.notify_all();
- return Err;
- };
-
- return AsyncDispatch(std::move(WrappedHandler), Args...);
- }
-
- /// Blocks until all calls have been completed and their return value
- /// handlers run.
- void wait() {
- std::unique_lock<std::mutex> Lock(M);
- while (NumOutstandingCalls > 0)
- CV.wait(Lock);
- }
-
-private:
- std::mutex M;
- std::condition_variable CV;
- uint32_t NumOutstandingCalls = 0;
-};
-
-/// Convenience class for grouping RPCFunctions into APIs that can be
-/// negotiated as a block.
-///
-template <typename... Funcs> class APICalls {
-public:
- /// Test whether this API contains Function F.
- template <typename F> class Contains {
- public:
- static const bool value = false;
- };
-
- /// Negotiate all functions in this API.
- template <typename RPCEndpoint> static Error negotiate(RPCEndpoint &R) {
- return Error::success();
- }
-};
-
-template <typename Func, typename... Funcs> class APICalls<Func, Funcs...> {
-public:
- template <typename F> class Contains {
- public:
- static const bool value = std::is_same<F, Func>::value |
- APICalls<Funcs...>::template Contains<F>::value;
- };
-
- template <typename RPCEndpoint> static Error negotiate(RPCEndpoint &R) {
- if (auto Err = R.template negotiateFunction<Func>())
- return Err;
- return APICalls<Funcs...>::negotiate(R);
- }
-};
-
-template <typename... InnerFuncs, typename... Funcs>
-class APICalls<APICalls<InnerFuncs...>, Funcs...> {
-public:
- template <typename F> class Contains {
- public:
- static const bool value =
- APICalls<InnerFuncs...>::template Contains<F>::value |
- APICalls<Funcs...>::template Contains<F>::value;
- };
-
- template <typename RPCEndpoint> static Error negotiate(RPCEndpoint &R) {
- if (auto Err = APICalls<InnerFuncs...>::negotiate(R))
- return Err;
- return APICalls<Funcs...>::negotiate(R);
- }
-};
-
-} // end namespace shared
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_RPCUTILS_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- RPCUtils.h - Utilities for building RPC APIs -------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities to support construction of simple RPC APIs.
+//
+// The RPC utilities aim for ease of use (minimal conceptual overhead) for C++
+// programmers, high performance, low memory overhead, and efficient use of the
+// communications channel.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_RPCUTILS_H
+#define LLVM_EXECUTIONENGINE_ORC_SHARED_RPCUTILS_H
+
+#include <map>
+#include <thread>
+#include <vector>
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
+#include "llvm/ExecutionEngine/Orc/Shared/Serialization.h"
+#include "llvm/Support/MSVCErrorWorkarounds.h"
+
+#include <future>
+
+namespace llvm {
+namespace orc {
+namespace shared {
+
+/// Base class of all fatal RPC errors (those that necessarily result in the
+/// termination of the RPC session).
+class RPCFatalError : public ErrorInfo<RPCFatalError> {
+public:
+ static char ID;
+};
+
+/// RPCConnectionClosed is returned from RPC operations if the RPC connection
+/// has already been closed due to either an error or graceful disconnection.
+class ConnectionClosed : public ErrorInfo<ConnectionClosed> {
+public:
+ static char ID;
+ std::error_code convertToErrorCode() const override;
+ void log(raw_ostream &OS) const override;
+};
+
+/// BadFunctionCall is returned from handleOne when the remote makes a call with
+/// an unrecognized function id.
+///
+/// This error is fatal because Orc RPC needs to know how to parse a function
+/// call to know where the next call starts, and if it doesn't recognize the
+/// function id it cannot parse the call.
+template <typename FnIdT, typename SeqNoT>
+class BadFunctionCall
+ : public ErrorInfo<BadFunctionCall<FnIdT, SeqNoT>, RPCFatalError> {
+public:
+ static char ID;
+
+ BadFunctionCall(FnIdT FnId, SeqNoT SeqNo)
+ : FnId(std::move(FnId)), SeqNo(std::move(SeqNo)) {}
+
+ std::error_code convertToErrorCode() const override {
+ return orcError(OrcErrorCode::UnexpectedRPCCall);
+ }
+
+ void log(raw_ostream &OS) const override {
+ OS << "Call to invalid RPC function id '" << FnId
+ << "' with "
+ "sequence number "
+ << SeqNo;
+ }
+
+private:
+ FnIdT FnId;
+ SeqNoT SeqNo;
+};
+
+template <typename FnIdT, typename SeqNoT>
+char BadFunctionCall<FnIdT, SeqNoT>::ID = 0;
+
+/// InvalidSequenceNumberForResponse is returned from handleOne when a response
+/// call arrives with a sequence number that doesn't correspond to any in-flight
+/// function call.
+///
+/// This error is fatal because Orc RPC needs to know how to parse the rest of
+/// the response call to know where the next call starts, and if it doesn't have
+/// a result parser for this sequence number it can't do that.
+template <typename SeqNoT>
+class InvalidSequenceNumberForResponse
+ : public ErrorInfo<InvalidSequenceNumberForResponse<SeqNoT>,
+ RPCFatalError> {
+public:
+ static char ID;
+
+ InvalidSequenceNumberForResponse(SeqNoT SeqNo) : SeqNo(std::move(SeqNo)) {}
+
+ std::error_code convertToErrorCode() const override {
+ return orcError(OrcErrorCode::UnexpectedRPCCall);
+ };
+
+ void log(raw_ostream &OS) const override {
+ OS << "Response has unknown sequence number " << SeqNo;
+ }
+
+private:
+ SeqNoT SeqNo;
+};
+
+template <typename SeqNoT>
+char InvalidSequenceNumberForResponse<SeqNoT>::ID = 0;
+
+/// This non-fatal error will be passed to asynchronous result handlers in place
+/// of a result if the connection goes down before a result returns, or if the
+/// function to be called cannot be negotiated with the remote.
+class ResponseAbandoned : public ErrorInfo<ResponseAbandoned> {
+public:
+ static char ID;
+
+ std::error_code convertToErrorCode() const override;
+ void log(raw_ostream &OS) const override;
+};
+
+/// This error is returned if the remote does not have a handler installed for
+/// the given RPC function.
+class CouldNotNegotiate : public ErrorInfo<CouldNotNegotiate> {
+public:
+ static char ID;
+
+ CouldNotNegotiate(std::string Signature);
+ std::error_code convertToErrorCode() const override;
+ void log(raw_ostream &OS) const override;
+ const std::string &getSignature() const { return Signature; }
+
+private:
+ std::string Signature;
+};
+
+template <typename DerivedFunc, typename FnT> class RPCFunction;
+
+// RPC Function class.
+// DerivedFunc should be a user defined class with a static 'getName()' method
+// returning a const char* representing the function's name.
+template <typename DerivedFunc, typename RetT, typename... ArgTs>
+class RPCFunction<DerivedFunc, RetT(ArgTs...)> {
+public:
+ /// User defined function type.
+ using Type = RetT(ArgTs...);
+
+ /// Return type.
+ using ReturnType = RetT;
+
+ /// Returns the full function prototype as a string.
+ static const char *getPrototype() {
+ static std::string Name = [] {
+ std::string Name;
+ raw_string_ostream(Name)
+ << SerializationTypeName<RetT>::getName() << " "
+ << DerivedFunc::getName() << "("
+ << SerializationTypeNameSequence<ArgTs...>() << ")";
+ return Name;
+ }();
+ return Name.data();
+ }
+};
+
+/// Allocates RPC function ids during autonegotiation.
+/// Specializations of this class must provide four members:
+///
+/// static T getInvalidId():
+/// Should return a reserved id that will be used to represent missing
+/// functions during autonegotiation.
+///
+/// static T getResponseId():
+/// Should return a reserved id that will be used to send function responses
+/// (return values).
+///
+/// static T getNegotiateId():
+/// Should return a reserved id for the negotiate function, which will be used
+/// to negotiate ids for user defined functions.
+///
+/// template <typename Func> T allocate():
+/// Allocate a unique id for function Func.
+template <typename T, typename = void> class RPCFunctionIdAllocator;
+
+/// This specialization of RPCFunctionIdAllocator provides a default
+/// implementation for integral types.
+template <typename T>
+class RPCFunctionIdAllocator<T, std::enable_if_t<std::is_integral<T>::value>> {
+public:
+ static T getInvalidId() { return T(0); }
+ static T getResponseId() { return T(1); }
+ static T getNegotiateId() { return T(2); }
+
+ template <typename Func> T allocate() { return NextId++; }
+
+private:
+ T NextId = 3;
+};
+
+namespace detail {
+
+/// Provides a typedef for a tuple containing the decayed argument types.
+template <typename T> class RPCFunctionArgsTuple;
+
+template <typename RetT, typename... ArgTs>
+class RPCFunctionArgsTuple<RetT(ArgTs...)> {
+public:
+ using Type = std::tuple<std::decay_t<std::remove_reference_t<ArgTs>>...>;
+};
+
+// ResultTraits provides typedefs and utilities specific to the return type
+// of functions.
+template <typename RetT> class ResultTraits {
+public:
+ // The return type wrapped in llvm::Expected.
+ using ErrorReturnType = Expected<RetT>;
+
+#ifdef _MSC_VER
+ // The ErrorReturnType wrapped in a std::promise.
+ using ReturnPromiseType = std::promise<MSVCPExpected<RetT>>;
+
+ // The ErrorReturnType wrapped in a std::future.
+ using ReturnFutureType = std::future<MSVCPExpected<RetT>>;
+#else
+ // The ErrorReturnType wrapped in a std::promise.
+ using ReturnPromiseType = std::promise<ErrorReturnType>;
+
+ // The ErrorReturnType wrapped in a std::future.
+ using ReturnFutureType = std::future<ErrorReturnType>;
+#endif
+
+ // Create a 'blank' value of the ErrorReturnType, ready and safe to
+ // overwrite.
+ static ErrorReturnType createBlankErrorReturnValue() {
+ return ErrorReturnType(RetT());
+ }
+
+ // Consume an abandoned ErrorReturnType.
+ static void consumeAbandoned(ErrorReturnType RetOrErr) {
+ consumeError(RetOrErr.takeError());
+ }
+};
+
+// ResultTraits specialization for void functions.
+template <> class ResultTraits<void> {
+public:
+ // For void functions, ErrorReturnType is llvm::Error.
+ using ErrorReturnType = Error;
+
+#ifdef _MSC_VER
+ // The ErrorReturnType wrapped in a std::promise.
+ using ReturnPromiseType = std::promise<MSVCPError>;
+
+ // The ErrorReturnType wrapped in a std::future.
+ using ReturnFutureType = std::future<MSVCPError>;
+#else
+ // The ErrorReturnType wrapped in a std::promise.
+ using ReturnPromiseType = std::promise<ErrorReturnType>;
+
+ // The ErrorReturnType wrapped in a std::future.
+ using ReturnFutureType = std::future<ErrorReturnType>;
+#endif
+
+ // Create a 'blank' value of the ErrorReturnType, ready and safe to
+ // overwrite.
+ static ErrorReturnType createBlankErrorReturnValue() {
+ return ErrorReturnType::success();
+ }
+
+ // Consume an abandoned ErrorReturnType.
+ static void consumeAbandoned(ErrorReturnType Err) {
+ consumeError(std::move(Err));
+ }
+};
+
+// ResultTraits<Error> is equivalent to ResultTraits<void>. This allows
+// handlers for void RPC functions to return either void (in which case they
+// implicitly succeed) or Error (in which case their error return is
+// propagated). See usage in HandlerTraits::runHandlerHelper.
+template <> class ResultTraits<Error> : public ResultTraits<void> {};
+
+// ResultTraits<Expected<T>> is equivalent to ResultTraits<T>. This allows
+// handlers for RPC functions returning a T to return either a T (in which
+// case they implicitly succeed) or Expected<T> (in which case their error
+// return is propagated). See usage in HandlerTraits::runHandlerHelper.
+template <typename RetT>
+class ResultTraits<Expected<RetT>> : public ResultTraits<RetT> {};
+
+// Determines whether an RPC function's defined error return type supports
+// error return value.
+template <typename T> class SupportsErrorReturn {
+public:
+ static const bool value = false;
+};
+
+template <> class SupportsErrorReturn<Error> {
+public:
+ static const bool value = true;
+};
+
+template <typename T> class SupportsErrorReturn<Expected<T>> {
+public:
+ static const bool value = true;
+};
+
+// RespondHelper packages return values based on whether or not the declared
+// RPC function return type supports error returns.
+template <bool FuncSupportsErrorReturn> class RespondHelper;
+
+// RespondHelper specialization for functions that support error returns.
+template <> class RespondHelper<true> {
+public:
+ // Send Expected<T>.
+ template <typename WireRetT, typename HandlerRetT, typename ChannelT,
+ typename FunctionIdT, typename SequenceNumberT>
+ static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
+ SequenceNumberT SeqNo,
+ Expected<HandlerRetT> ResultOrErr) {
+ if (!ResultOrErr && ResultOrErr.template errorIsA<RPCFatalError>())
+ return ResultOrErr.takeError();
+
+ // Open the response message.
+ if (auto Err = C.startSendMessage(ResponseId, SeqNo))
+ return Err;
+
+ // Serialize the result.
+ if (auto Err =
+ SerializationTraits<ChannelT, WireRetT, Expected<HandlerRetT>>::
+ serialize(C, std::move(ResultOrErr)))
+ return Err;
+
+ // Close the response message.
+ if (auto Err = C.endSendMessage())
+ return Err;
+ return C.send();
+ }
+
+ template <typename ChannelT, typename FunctionIdT, typename SequenceNumberT>
+ static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
+ SequenceNumberT SeqNo, Error Err) {
+ if (Err && Err.isA<RPCFatalError>())
+ return Err;
+ if (auto Err2 = C.startSendMessage(ResponseId, SeqNo))
+ return Err2;
+ if (auto Err2 = serializeSeq(C, std::move(Err)))
+ return Err2;
+ if (auto Err2 = C.endSendMessage())
+ return Err2;
+ return C.send();
+ }
+};
+
+// RespondHelper specialization for functions that do not support error returns.
+template <> class RespondHelper<false> {
+public:
+ template <typename WireRetT, typename HandlerRetT, typename ChannelT,
+ typename FunctionIdT, typename SequenceNumberT>
+ static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
+ SequenceNumberT SeqNo,
+ Expected<HandlerRetT> ResultOrErr) {
+ if (auto Err = ResultOrErr.takeError())
+ return Err;
+
+ // Open the response message.
+ if (auto Err = C.startSendMessage(ResponseId, SeqNo))
+ return Err;
+
+ // Serialize the result.
+ if (auto Err =
+ SerializationTraits<ChannelT, WireRetT, HandlerRetT>::serialize(
+ C, *ResultOrErr))
+ return Err;
+
+ // End the response message.
+ if (auto Err = C.endSendMessage())
+ return Err;
+
+ return C.send();
+ }
+
+ template <typename ChannelT, typename FunctionIdT, typename SequenceNumberT>
+ static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
+ SequenceNumberT SeqNo, Error Err) {
+ if (Err)
+ return Err;
+ if (auto Err2 = C.startSendMessage(ResponseId, SeqNo))
+ return Err2;
+ if (auto Err2 = C.endSendMessage())
+ return Err2;
+ return C.send();
+ }
+};
+
+// Send a response of the given wire return type (WireRetT) over the
+// channel, with the given sequence number.
+template <typename WireRetT, typename HandlerRetT, typename ChannelT,
+ typename FunctionIdT, typename SequenceNumberT>
+Error respond(ChannelT &C, const FunctionIdT &ResponseId, SequenceNumberT SeqNo,
+ Expected<HandlerRetT> ResultOrErr) {
+ return RespondHelper<SupportsErrorReturn<WireRetT>::value>::
+ template sendResult<WireRetT>(C, ResponseId, SeqNo,
+ std::move(ResultOrErr));
+}
+
+// Send an empty response message on the given channel to indicate that
+// the handler ran.
+template <typename WireRetT, typename ChannelT, typename FunctionIdT,
+ typename SequenceNumberT>
+Error respond(ChannelT &C, const FunctionIdT &ResponseId, SequenceNumberT SeqNo,
+ Error Err) {
+ return RespondHelper<SupportsErrorReturn<WireRetT>::value>::sendResult(
+ C, ResponseId, SeqNo, std::move(Err));
+}
+
+// Converts a given type to the equivalent error return type.
+template <typename T> class WrappedHandlerReturn {
+public:
+ using Type = Expected<T>;
+};
+
+template <typename T> class WrappedHandlerReturn<Expected<T>> {
+public:
+ using Type = Expected<T>;
+};
+
+template <> class WrappedHandlerReturn<void> {
+public:
+ using Type = Error;
+};
+
+template <> class WrappedHandlerReturn<Error> {
+public:
+ using Type = Error;
+};
+
+template <> class WrappedHandlerReturn<ErrorSuccess> {
+public:
+ using Type = Error;
+};
+
+// Traits class that strips the response function from the list of handler
+// arguments.
+template <typename FnT> class AsyncHandlerTraits;
+
+template <typename ResultT, typename... ArgTs>
+class AsyncHandlerTraits<Error(std::function<Error(Expected<ResultT>)>,
+ ArgTs...)> {
+public:
+ using Type = Error(ArgTs...);
+ using ResultType = Expected<ResultT>;
+};
+
+template <typename... ArgTs>
+class AsyncHandlerTraits<Error(std::function<Error(Error)>, ArgTs...)> {
+public:
+ using Type = Error(ArgTs...);
+ using ResultType = Error;
+};
+
+template <typename... ArgTs>
+class AsyncHandlerTraits<ErrorSuccess(std::function<Error(Error)>, ArgTs...)> {
+public:
+ using Type = Error(ArgTs...);
+ using ResultType = Error;
+};
+
+template <typename... ArgTs>
+class AsyncHandlerTraits<void(std::function<Error(Error)>, ArgTs...)> {
+public:
+ using Type = Error(ArgTs...);
+ using ResultType = Error;
+};
+
+template <typename ResponseHandlerT, typename... ArgTs>
+class AsyncHandlerTraits<Error(ResponseHandlerT, ArgTs...)>
+ : public AsyncHandlerTraits<Error(std::decay_t<ResponseHandlerT>,
+ ArgTs...)> {};
+
+// This template class provides utilities related to RPC function handlers.
+// The base case applies to non-function types (the template class is
+// specialized for function types) and inherits from the appropriate
+// speciilization for the given non-function type's call operator.
+template <typename HandlerT>
+class HandlerTraits
+ : public HandlerTraits<
+ decltype(&std::remove_reference<HandlerT>::type::operator())> {};
+
+// Traits for handlers with a given function type.
+template <typename RetT, typename... ArgTs>
+class HandlerTraits<RetT(ArgTs...)> {
+public:
+ // Function type of the handler.
+ using Type = RetT(ArgTs...);
+
+ // Return type of the handler.
+ using ReturnType = RetT;
+
+ // Call the given handler with the given arguments.
+ template <typename HandlerT, typename... TArgTs>
+ static typename WrappedHandlerReturn<RetT>::Type
+ unpackAndRun(HandlerT &Handler, std::tuple<TArgTs...> &Args) {
+ return unpackAndRunHelper(Handler, Args,
+ std::index_sequence_for<TArgTs...>());
+ }
+
+ // Call the given handler with the given arguments.
+ template <typename HandlerT, typename ResponderT, typename... TArgTs>
+ static Error unpackAndRunAsync(HandlerT &Handler, ResponderT &Responder,
+ std::tuple<TArgTs...> &Args) {
+ return unpackAndRunAsyncHelper(Handler, Responder, Args,
+ std::index_sequence_for<TArgTs...>());
+ }
+
+ // Call the given handler with the given arguments.
+ template <typename HandlerT>
+ static std::enable_if_t<
+ std::is_void<typename HandlerTraits<HandlerT>::ReturnType>::value, Error>
+ run(HandlerT &Handler, ArgTs &&...Args) {
+ Handler(std::move(Args)...);
+ return Error::success();
+ }
+
+ template <typename HandlerT, typename... TArgTs>
+ static std::enable_if_t<
+ !std::is_void<typename HandlerTraits<HandlerT>::ReturnType>::value,
+ typename HandlerTraits<HandlerT>::ReturnType>
+ run(HandlerT &Handler, TArgTs... Args) {
+ return Handler(std::move(Args)...);
+ }
+
+ // Serialize arguments to the channel.
+ template <typename ChannelT, typename... CArgTs>
+ static Error serializeArgs(ChannelT &C, const CArgTs... CArgs) {
+ return SequenceSerialization<ChannelT, ArgTs...>::serialize(C, CArgs...);
+ }
+
+ // Deserialize arguments from the channel.
+ template <typename ChannelT, typename... CArgTs>
+ static Error deserializeArgs(ChannelT &C, std::tuple<CArgTs...> &Args) {
+ return deserializeArgsHelper(C, Args, std::index_sequence_for<CArgTs...>());
+ }
+
+private:
+ template <typename ChannelT, typename... CArgTs, size_t... Indexes>
+ static Error deserializeArgsHelper(ChannelT &C, std::tuple<CArgTs...> &Args,
+ std::index_sequence<Indexes...> _) {
+ return SequenceSerialization<ChannelT, ArgTs...>::deserialize(
+ C, std::get<Indexes>(Args)...);
+ }
+
+ template <typename HandlerT, typename ArgTuple, size_t... Indexes>
+ static typename WrappedHandlerReturn<
+ typename HandlerTraits<HandlerT>::ReturnType>::Type
+ unpackAndRunHelper(HandlerT &Handler, ArgTuple &Args,
+ std::index_sequence<Indexes...>) {
+ return run(Handler, std::move(std::get<Indexes>(Args))...);
+ }
+
+ template <typename HandlerT, typename ResponderT, typename ArgTuple,
+ size_t... Indexes>
+ static typename WrappedHandlerReturn<
+ typename HandlerTraits<HandlerT>::ReturnType>::Type
+ unpackAndRunAsyncHelper(HandlerT &Handler, ResponderT &Responder,
+ ArgTuple &Args, std::index_sequence<Indexes...>) {
+ return run(Handler, Responder, std::move(std::get<Indexes>(Args))...);
+ }
+};
+
+// Handler traits for free functions.
+template <typename RetT, typename... ArgTs>
+class HandlerTraits<RetT (*)(ArgTs...)> : public HandlerTraits<RetT(ArgTs...)> {
+};
+
+// Handler traits for class methods (especially call operators for lambdas).
+template <typename Class, typename RetT, typename... ArgTs>
+class HandlerTraits<RetT (Class::*)(ArgTs...)>
+ : public HandlerTraits<RetT(ArgTs...)> {};
+
+// Handler traits for const class methods (especially call operators for
+// lambdas).
+template <typename Class, typename RetT, typename... ArgTs>
+class HandlerTraits<RetT (Class::*)(ArgTs...) const>
+ : public HandlerTraits<RetT(ArgTs...)> {};
+
+// Utility to peel the Expected wrapper off a response handler error type.
+template <typename HandlerT> class ResponseHandlerArg;
+
+template <typename ArgT> class ResponseHandlerArg<Error(Expected<ArgT>)> {
+public:
+ using ArgType = Expected<ArgT>;
+ using UnwrappedArgType = ArgT;
+};
+
+template <typename ArgT>
+class ResponseHandlerArg<ErrorSuccess(Expected<ArgT>)> {
+public:
+ using ArgType = Expected<ArgT>;
+ using UnwrappedArgType = ArgT;
+};
+
+template <> class ResponseHandlerArg<Error(Error)> {
+public:
+ using ArgType = Error;
+};
+
+template <> class ResponseHandlerArg<ErrorSuccess(Error)> {
+public:
+ using ArgType = Error;
+};
+
+// ResponseHandler represents a handler for a not-yet-received function call
+// result.
+template <typename ChannelT> class ResponseHandler {
+public:
+ virtual ~ResponseHandler() {}
+
+ // Reads the function result off the wire and acts on it. The meaning of
+ // "act" will depend on how this method is implemented in any given
+ // ResponseHandler subclass but could, for example, mean running a
+ // user-specified handler or setting a promise value.
+ virtual Error handleResponse(ChannelT &C) = 0;
+
+ // Abandons this outstanding result.
+ virtual void abandon() = 0;
+
+ // Create an error instance representing an abandoned response.
+ static Error createAbandonedResponseError() {
+ return make_error<ResponseAbandoned>();
+ }
+};
+
+// ResponseHandler subclass for RPC functions with non-void returns.
+template <typename ChannelT, typename FuncRetT, typename HandlerT>
+class ResponseHandlerImpl : public ResponseHandler<ChannelT> {
+public:
+ ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
+
+ // Handle the result by deserializing it from the channel then passing it
+ // to the user defined handler.
+ Error handleResponse(ChannelT &C) override {
+ using UnwrappedArgType = typename ResponseHandlerArg<
+ typename HandlerTraits<HandlerT>::Type>::UnwrappedArgType;
+ UnwrappedArgType Result;
+ if (auto Err =
+ SerializationTraits<ChannelT, FuncRetT,
+ UnwrappedArgType>::deserialize(C, Result))
+ return Err;
+ if (auto Err = C.endReceiveMessage())
+ return Err;
+ return Handler(std::move(Result));
+ }
+
+ // Abandon this response by calling the handler with an 'abandoned response'
+ // error.
+ void abandon() override {
+ if (auto Err = Handler(this->createAbandonedResponseError())) {
+ // Handlers should not fail when passed an abandoned response error.
+ report_fatal_error(std::move(Err));
+ }
+ }
+
+private:
+ HandlerT Handler;
+};
+
+// ResponseHandler subclass for RPC functions with void returns.
+template <typename ChannelT, typename HandlerT>
+class ResponseHandlerImpl<ChannelT, void, HandlerT>
+ : public ResponseHandler<ChannelT> {
+public:
+ ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
+
+ // Handle the result (no actual value, just a notification that the function
+ // has completed on the remote end) by calling the user-defined handler with
+ // Error::success().
+ Error handleResponse(ChannelT &C) override {
+ if (auto Err = C.endReceiveMessage())
+ return Err;
+ return Handler(Error::success());
+ }
+
+ // Abandon this response by calling the handler with an 'abandoned response'
+ // error.
+ void abandon() override {
+ if (auto Err = Handler(this->createAbandonedResponseError())) {
+ // Handlers should not fail when passed an abandoned response error.
+ report_fatal_error(std::move(Err));
+ }
+ }
+
+private:
+ HandlerT Handler;
+};
+
+template <typename ChannelT, typename FuncRetT, typename HandlerT>
+class ResponseHandlerImpl<ChannelT, Expected<FuncRetT>, HandlerT>
+ : public ResponseHandler<ChannelT> {
+public:
+ ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
+
+ // Handle the result by deserializing it from the channel then passing it
+ // to the user defined handler.
+ Error handleResponse(ChannelT &C) override {
+ using HandlerArgType = typename ResponseHandlerArg<
+ typename HandlerTraits<HandlerT>::Type>::ArgType;
+ HandlerArgType Result((typename HandlerArgType::value_type()));
+
+ if (auto Err = SerializationTraits<ChannelT, Expected<FuncRetT>,
+ HandlerArgType>::deserialize(C, Result))
+ return Err;
+ if (auto Err = C.endReceiveMessage())
+ return Err;
+ return Handler(std::move(Result));
+ }
+
+ // Abandon this response by calling the handler with an 'abandoned response'
+ // error.
+ void abandon() override {
+ if (auto Err = Handler(this->createAbandonedResponseError())) {
+ // Handlers should not fail when passed an abandoned response error.
+ report_fatal_error(std::move(Err));
+ }
+ }
+
+private:
+ HandlerT Handler;
+};
+
+template <typename ChannelT, typename HandlerT>
+class ResponseHandlerImpl<ChannelT, Error, HandlerT>
+ : public ResponseHandler<ChannelT> {
+public:
+ ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
+
+ // Handle the result by deserializing it from the channel then passing it
+ // to the user defined handler.
+ Error handleResponse(ChannelT &C) override {
+ Error Result = Error::success();
+ if (auto Err = SerializationTraits<ChannelT, Error, Error>::deserialize(
+ C, Result)) {
+ consumeError(std::move(Result));
+ return Err;
+ }
+ if (auto Err = C.endReceiveMessage()) {
+ consumeError(std::move(Result));
+ return Err;
+ }
+ return Handler(std::move(Result));
+ }
+
+ // Abandon this response by calling the handler with an 'abandoned response'
+ // error.
+ void abandon() override {
+ if (auto Err = Handler(this->createAbandonedResponseError())) {
+ // Handlers should not fail when passed an abandoned response error.
+ report_fatal_error(std::move(Err));
+ }
+ }
+
+private:
+ HandlerT Handler;
+};
+
+// Create a ResponseHandler from a given user handler.
+template <typename ChannelT, typename FuncRetT, typename HandlerT>
+std::unique_ptr<ResponseHandler<ChannelT>> createResponseHandler(HandlerT H) {
+ return std::make_unique<ResponseHandlerImpl<ChannelT, FuncRetT, HandlerT>>(
+ std::move(H));
+}
+
+// Helper for wrapping member functions up as functors. This is useful for
+// installing methods as result handlers.
+template <typename ClassT, typename RetT, typename... ArgTs>
+class MemberFnWrapper {
+public:
+ using MethodT = RetT (ClassT::*)(ArgTs...);
+ MemberFnWrapper(ClassT &Instance, MethodT Method)
+ : Instance(Instance), Method(Method) {}
+ RetT operator()(ArgTs &&...Args) {
+ return (Instance.*Method)(std::move(Args)...);
+ }
+
+private:
+ ClassT &Instance;
+ MethodT Method;
+};
+
+// Helper that provides a Functor for deserializing arguments.
+template <typename... ArgTs> class ReadArgs {
+public:
+ Error operator()() { return Error::success(); }
+};
+
+template <typename ArgT, typename... ArgTs>
+class ReadArgs<ArgT, ArgTs...> : public ReadArgs<ArgTs...> {
+public:
+ ReadArgs(ArgT &Arg, ArgTs &...Args) : ReadArgs<ArgTs...>(Args...), Arg(Arg) {}
+
+ Error operator()(ArgT &ArgVal, ArgTs &...ArgVals) {
+ this->Arg = std::move(ArgVal);
+ return ReadArgs<ArgTs...>::operator()(ArgVals...);
+ }
+
+private:
+ ArgT &Arg;
+};
+
+// Manage sequence numbers.
+template <typename SequenceNumberT> class SequenceNumberManager {
+public:
+ // Reset, making all sequence numbers available.
+ void reset() {
+ std::lock_guard<std::mutex> Lock(SeqNoLock);
+ NextSequenceNumber = 0;
+ FreeSequenceNumbers.clear();
+ }
+
+ // Get the next available sequence number. Will re-use numbers that have
+ // been released.
+ SequenceNumberT getSequenceNumber() {
+ std::lock_guard<std::mutex> Lock(SeqNoLock);
+ if (FreeSequenceNumbers.empty())
+ return NextSequenceNumber++;
+ auto SequenceNumber = FreeSequenceNumbers.back();
+ FreeSequenceNumbers.pop_back();
+ return SequenceNumber;
+ }
+
+ // Release a sequence number, making it available for re-use.
+ void releaseSequenceNumber(SequenceNumberT SequenceNumber) {
+ std::lock_guard<std::mutex> Lock(SeqNoLock);
+ FreeSequenceNumbers.push_back(SequenceNumber);
+ }
+
+private:
+ std::mutex SeqNoLock;
+ SequenceNumberT NextSequenceNumber = 0;
+ std::vector<SequenceNumberT> FreeSequenceNumbers;
+};
+
+// Checks that predicate P holds for each corresponding pair of type arguments
+// from T1 and T2 tuple.
+template <template <class, class> class P, typename T1Tuple, typename T2Tuple>
+class RPCArgTypeCheckHelper;
+
+template <template <class, class> class P>
+class RPCArgTypeCheckHelper<P, std::tuple<>, std::tuple<>> {
+public:
+ static const bool value = true;
+};
+
+template <template <class, class> class P, typename T, typename... Ts,
+ typename U, typename... Us>
+class RPCArgTypeCheckHelper<P, std::tuple<T, Ts...>, std::tuple<U, Us...>> {
+public:
+ static const bool value =
+ P<T, U>::value &&
+ RPCArgTypeCheckHelper<P, std::tuple<Ts...>, std::tuple<Us...>>::value;
+};
+
+template <template <class, class> class P, typename T1Sig, typename T2Sig>
+class RPCArgTypeCheck {
+public:
+ using T1Tuple = typename RPCFunctionArgsTuple<T1Sig>::Type;
+ using T2Tuple = typename RPCFunctionArgsTuple<T2Sig>::Type;
+
+ static_assert(std::tuple_size<T1Tuple>::value >=
+ std::tuple_size<T2Tuple>::value,
+ "Too many arguments to RPC call");
+ static_assert(std::tuple_size<T1Tuple>::value <=
+ std::tuple_size<T2Tuple>::value,
+ "Too few arguments to RPC call");
+
+ static const bool value = RPCArgTypeCheckHelper<P, T1Tuple, T2Tuple>::value;
+};
+
+template <typename ChannelT, typename WireT, typename ConcreteT>
+class CanSerialize {
+private:
+ using S = SerializationTraits<ChannelT, WireT, ConcreteT>;
+
+ template <typename T>
+ static std::true_type check(
+ std::enable_if_t<std::is_same<decltype(T::serialize(
+ std::declval<ChannelT &>(),
+ std::declval<const ConcreteT &>())),
+ Error>::value,
+ void *>);
+
+ template <typename> static std::false_type check(...);
+
+public:
+ static const bool value = decltype(check<S>(0))::value;
+};
+
+template <typename ChannelT, typename WireT, typename ConcreteT>
+class CanDeserialize {
+private:
+ using S = SerializationTraits<ChannelT, WireT, ConcreteT>;
+
+ template <typename T>
+ static std::true_type
+ check(std::enable_if_t<
+ std::is_same<decltype(T::deserialize(std::declval<ChannelT &>(),
+ std::declval<ConcreteT &>())),
+ Error>::value,
+ void *>);
+
+ template <typename> static std::false_type check(...);
+
+public:
+ static const bool value = decltype(check<S>(0))::value;
+};
+
+/// Contains primitive utilities for defining, calling and handling calls to
+/// remote procedures. ChannelT is a bidirectional stream conforming to the
+/// RPCChannel interface (see RPCChannel.h), FunctionIdT is a procedure
+/// identifier type that must be serializable on ChannelT, and SequenceNumberT
+/// is an integral type that will be used to number in-flight function calls.
+///
+/// These utilities support the construction of very primitive RPC utilities.
+/// Their intent is to ensure correct serialization and deserialization of
+/// procedure arguments, and to keep the client and server's view of the API in
+/// sync.
+template <typename ImplT, typename ChannelT, typename FunctionIdT,
+ typename SequenceNumberT>
+class RPCEndpointBase {
+protected:
+ class OrcRPCInvalid : public RPCFunction<OrcRPCInvalid, void()> {
+ public:
+ static const char *getName() { return "__orc_rpc$invalid"; }
+ };
+
+ class OrcRPCResponse : public RPCFunction<OrcRPCResponse, void()> {
+ public:
+ static const char *getName() { return "__orc_rpc$response"; }
+ };
+
+ class OrcRPCNegotiate
+ : public RPCFunction<OrcRPCNegotiate, FunctionIdT(std::string)> {
+ public:
+ static const char *getName() { return "__orc_rpc$negotiate"; }
+ };
+
+ // Helper predicate for testing for the presence of SerializeTraits
+ // serializers.
+ template <typename WireT, typename ConcreteT>
+ class CanSerializeCheck : detail::CanSerialize<ChannelT, WireT, ConcreteT> {
+ public:
+ using detail::CanSerialize<ChannelT, WireT, ConcreteT>::value;
+
+ static_assert(value, "Missing serializer for argument (Can't serialize the "
+ "first template type argument of CanSerializeCheck "
+ "from the second)");
+ };
+
+ // Helper predicate for testing for the presence of SerializeTraits
+ // deserializers.
+ template <typename WireT, typename ConcreteT>
+ class CanDeserializeCheck
+ : detail::CanDeserialize<ChannelT, WireT, ConcreteT> {
+ public:
+ using detail::CanDeserialize<ChannelT, WireT, ConcreteT>::value;
+
+ static_assert(value, "Missing deserializer for argument (Can't deserialize "
+ "the second template type argument of "
+ "CanDeserializeCheck from the first)");
+ };
+
+public:
+ /// Construct an RPC instance on a channel.
+ RPCEndpointBase(ChannelT &C, bool LazyAutoNegotiation)
+ : C(C), LazyAutoNegotiation(LazyAutoNegotiation) {
+ // Hold ResponseId in a special variable, since we expect Response to be
+ // called relatively frequently, and want to avoid the map lookup.
+ ResponseId = FnIdAllocator.getResponseId();
+ RemoteFunctionIds[OrcRPCResponse::getPrototype()] = ResponseId;
+
+ // Register the negotiate function id and handler.
+ auto NegotiateId = FnIdAllocator.getNegotiateId();
+ RemoteFunctionIds[OrcRPCNegotiate::getPrototype()] = NegotiateId;
+ Handlers[NegotiateId] = wrapHandler<OrcRPCNegotiate>(
+ [this](const std::string &Name) { return handleNegotiate(Name); });
+ }
+
+ /// Negotiate a function id for Func with the other end of the channel.
+ template <typename Func> Error negotiateFunction(bool Retry = false) {
+ return getRemoteFunctionId<Func>(true, Retry).takeError();
+ }
+
+ /// Append a call Func, does not call send on the channel.
+ /// The first argument specifies a user-defined handler to be run when the
+ /// function returns. The handler should take an Expected<Func::ReturnType>,
+ /// or an Error (if Func::ReturnType is void). The handler will be called
+ /// with an error if the return value is abandoned due to a channel error.
+ template <typename Func, typename HandlerT, typename... ArgTs>
+ Error appendCallAsync(HandlerT Handler, const ArgTs &...Args) {
+
+ static_assert(
+ detail::RPCArgTypeCheck<CanSerializeCheck, typename Func::Type,
+ void(ArgTs...)>::value,
+ "");
+
+ // Look up the function ID.
+ FunctionIdT FnId;
+ if (auto FnIdOrErr = getRemoteFunctionId<Func>(LazyAutoNegotiation, false))
+ FnId = *FnIdOrErr;
+ else {
+ // Negotiation failed. Notify the handler then return the negotiate-failed
+ // error.
+ cantFail(Handler(make_error<ResponseAbandoned>()));
+ return FnIdOrErr.takeError();
+ }
+
+ SequenceNumberT SeqNo; // initialized in locked scope below.
+ {
+ // Lock the pending responses map and sequence number manager.
+ std::lock_guard<std::mutex> Lock(ResponsesMutex);
+
+ // Allocate a sequence number.
+ SeqNo = SequenceNumberMgr.getSequenceNumber();
+ assert(!PendingResponses.count(SeqNo) &&
+ "Sequence number already allocated");
+
+ // Install the user handler.
+ PendingResponses[SeqNo] =
+ detail::createResponseHandler<ChannelT, typename Func::ReturnType>(
+ std::move(Handler));
+ }
+
+ // Open the function call message.
+ if (auto Err = C.startSendMessage(FnId, SeqNo)) {
+ abandonPendingResponses();
+ return Err;
+ }
+
+ // Serialize the call arguments.
+ if (auto Err = detail::HandlerTraits<typename Func::Type>::serializeArgs(
+ C, Args...)) {
+ abandonPendingResponses();
+ return Err;
+ }
+
+ // Close the function call messagee.
+ if (auto Err = C.endSendMessage()) {
+ abandonPendingResponses();
+ return Err;
+ }
+
+ return Error::success();
+ }
+
+ Error sendAppendedCalls() { return C.send(); };
+
+ template <typename Func, typename HandlerT, typename... ArgTs>
+ Error callAsync(HandlerT Handler, const ArgTs &...Args) {
+ if (auto Err = appendCallAsync<Func>(std::move(Handler), Args...))
+ return Err;
+ return C.send();
+ }
+
+ /// Handle one incoming call.
+ Error handleOne() {
+ FunctionIdT FnId;
+ SequenceNumberT SeqNo;
+ if (auto Err = C.startReceiveMessage(FnId, SeqNo)) {
+ abandonPendingResponses();
+ return Err;
+ }
+ if (FnId == ResponseId)
+ return handleResponse(SeqNo);
+ auto I = Handlers.find(FnId);
+ if (I != Handlers.end())
+ return I->second(C, SeqNo);
+
+ // else: No handler found. Report error to client?
+ return make_error<BadFunctionCall<FunctionIdT, SequenceNumberT>>(FnId,
+ SeqNo);
+ }
+
+ /// Helper for handling setter procedures - this method returns a functor that
+ /// sets the variables referred to by Args... to values deserialized from the
+ /// channel.
+ /// E.g.
+ ///
+ /// typedef Function<0, bool, int> Func1;
+ ///
+ /// ...
+ /// bool B;
+ /// int I;
+ /// if (auto Err = expect<Func1>(Channel, readArgs(B, I)))
+ /// /* Handle Args */ ;
+ ///
+ template <typename... ArgTs>
+ static detail::ReadArgs<ArgTs...> readArgs(ArgTs &...Args) {
+ return detail::ReadArgs<ArgTs...>(Args...);
+ }
+
+ /// Abandon all outstanding result handlers.
+ ///
+ /// This will call all currently registered result handlers to receive an
+ /// "abandoned" error as their argument. This is used internally by the RPC
+ /// in error situations, but can also be called directly by clients who are
+ /// disconnecting from the remote and don't or can't expect responses to their
+ /// outstanding calls. (Especially for outstanding blocking calls, calling
+ /// this function may be necessary to avoid dead threads).
+ void abandonPendingResponses() {
+ // Lock the pending responses map and sequence number manager.
+ std::lock_guard<std::mutex> Lock(ResponsesMutex);
+
+ for (auto &KV : PendingResponses)
+ KV.second->abandon();
+ PendingResponses.clear();
+ SequenceNumberMgr.reset();
+ }
+
+ /// Remove the handler for the given function.
+ /// A handler must currently be registered for this function.
+ template <typename Func> void removeHandler() {
+ auto IdItr = LocalFunctionIds.find(Func::getPrototype());
+ assert(IdItr != LocalFunctionIds.end() &&
+ "Function does not have a registered handler");
+ auto HandlerItr = Handlers.find(IdItr->second);
+ assert(HandlerItr != Handlers.end() &&
+ "Function does not have a registered handler");
+ Handlers.erase(HandlerItr);
+ }
+
+ /// Clear all handlers.
+ void clearHandlers() { Handlers.clear(); }
+
+protected:
+ FunctionIdT getInvalidFunctionId() const {
+ return FnIdAllocator.getInvalidId();
+ }
+
+ /// Add the given handler to the handler map and make it available for
+ /// autonegotiation and execution.
+ template <typename Func, typename HandlerT>
+ void addHandlerImpl(HandlerT Handler) {
+
+ static_assert(detail::RPCArgTypeCheck<
+ CanDeserializeCheck, typename Func::Type,
+ typename detail::HandlerTraits<HandlerT>::Type>::value,
+ "");
+
+ FunctionIdT NewFnId = FnIdAllocator.template allocate<Func>();
+ LocalFunctionIds[Func::getPrototype()] = NewFnId;
+ Handlers[NewFnId] = wrapHandler<Func>(std::move(Handler));
+ }
+
+ template <typename Func, typename HandlerT>
+ void addAsyncHandlerImpl(HandlerT Handler) {
+
+ static_assert(
+ detail::RPCArgTypeCheck<
+ CanDeserializeCheck, typename Func::Type,
+ typename detail::AsyncHandlerTraits<
+ typename detail::HandlerTraits<HandlerT>::Type>::Type>::value,
+ "");
+
+ FunctionIdT NewFnId = FnIdAllocator.template allocate<Func>();
+ LocalFunctionIds[Func::getPrototype()] = NewFnId;
+ Handlers[NewFnId] = wrapAsyncHandler<Func>(std::move(Handler));
+ }
+
+ Error handleResponse(SequenceNumberT SeqNo) {
+ using Handler = typename decltype(PendingResponses)::mapped_type;
+ Handler PRHandler;
+
+ {
+ // Lock the pending responses map and sequence number manager.
+ std::unique_lock<std::mutex> Lock(ResponsesMutex);
+ auto I = PendingResponses.find(SeqNo);
+
+ if (I != PendingResponses.end()) {
+ PRHandler = std::move(I->second);
+ PendingResponses.erase(I);
+ SequenceNumberMgr.releaseSequenceNumber(SeqNo);
+ } else {
+ // Unlock the pending results map to prevent recursive lock.
+ Lock.unlock();
+ abandonPendingResponses();
+ return make_error<InvalidSequenceNumberForResponse<SequenceNumberT>>(
+ SeqNo);
+ }
+ }
+
+ assert(PRHandler &&
+ "If we didn't find a response handler we should have bailed out");
+
+ if (auto Err = PRHandler->handleResponse(C)) {
+ abandonPendingResponses();
+ return Err;
+ }
+
+ return Error::success();
+ }
+
+ FunctionIdT handleNegotiate(const std::string &Name) {
+ auto I = LocalFunctionIds.find(Name);
+ if (I == LocalFunctionIds.end())
+ return getInvalidFunctionId();
+ return I->second;
+ }
+
+ // Find the remote FunctionId for the given function.
+ template <typename Func>
+ Expected<FunctionIdT> getRemoteFunctionId(bool NegotiateIfNotInMap,
+ bool NegotiateIfInvalid) {
+ bool DoNegotiate;
+
+ // Check if we already have a function id...
+ auto I = RemoteFunctionIds.find(Func::getPrototype());
+ if (I != RemoteFunctionIds.end()) {
+ // If it's valid there's nothing left to do.
+ if (I->second != getInvalidFunctionId())
+ return I->second;
+ DoNegotiate = NegotiateIfInvalid;
+ } else
+ DoNegotiate = NegotiateIfNotInMap;
+
+ // We don't have a function id for Func yet, but we're allowed to try to
+ // negotiate one.
+ if (DoNegotiate) {
+ auto &Impl = static_cast<ImplT &>(*this);
+ if (auto RemoteIdOrErr =
+ Impl.template callB<OrcRPCNegotiate>(Func::getPrototype())) {
+ RemoteFunctionIds[Func::getPrototype()] = *RemoteIdOrErr;
+ if (*RemoteIdOrErr == getInvalidFunctionId())
+ return make_error<CouldNotNegotiate>(Func::getPrototype());
+ return *RemoteIdOrErr;
+ } else
+ return RemoteIdOrErr.takeError();
+ }
+
+ // No key was available in the map and we weren't allowed to try to
+ // negotiate one, so return an unknown function error.
+ return make_error<CouldNotNegotiate>(Func::getPrototype());
+ }
+
+ using WrappedHandlerFn = std::function<Error(ChannelT &, SequenceNumberT)>;
+
+ // Wrap the given user handler in the necessary argument-deserialization code,
+ // result-serialization code, and call to the launch policy (if present).
+ template <typename Func, typename HandlerT>
+ WrappedHandlerFn wrapHandler(HandlerT Handler) {
+ return [this, Handler](ChannelT &Channel,
+ SequenceNumberT SeqNo) mutable -> Error {
+ // Start by deserializing the arguments.
+ using ArgsTuple = typename detail::RPCFunctionArgsTuple<
+ typename detail::HandlerTraits<HandlerT>::Type>::Type;
+ auto Args = std::make_shared<ArgsTuple>();
+
+ if (auto Err =
+ detail::HandlerTraits<typename Func::Type>::deserializeArgs(
+ Channel, *Args))
+ return Err;
+
+ // GCC 4.7 and 4.8 incorrectly issue a -Wunused-but-set-variable warning
+ // for RPCArgs. Void cast RPCArgs to work around this for now.
+ // FIXME: Remove this workaround once we can assume a working GCC version.
+ (void)Args;
+
+ // End receieve message, unlocking the channel for reading.
+ if (auto Err = Channel.endReceiveMessage())
+ return Err;
+
+ using HTraits = detail::HandlerTraits<HandlerT>;
+ using FuncReturn = typename Func::ReturnType;
+ return detail::respond<FuncReturn>(Channel, ResponseId, SeqNo,
+ HTraits::unpackAndRun(Handler, *Args));
+ };
+ }
+
+ // Wrap the given user handler in the necessary argument-deserialization code,
+ // result-serialization code, and call to the launch policy (if present).
+ template <typename Func, typename HandlerT>
+ WrappedHandlerFn wrapAsyncHandler(HandlerT Handler) {
+ return [this, Handler](ChannelT &Channel,
+ SequenceNumberT SeqNo) mutable -> Error {
+ // Start by deserializing the arguments.
+ using AHTraits = detail::AsyncHandlerTraits<
+ typename detail::HandlerTraits<HandlerT>::Type>;
+ using ArgsTuple =
+ typename detail::RPCFunctionArgsTuple<typename AHTraits::Type>::Type;
+ auto Args = std::make_shared<ArgsTuple>();
+
+ if (auto Err =
+ detail::HandlerTraits<typename Func::Type>::deserializeArgs(
+ Channel, *Args))
+ return Err;
+
+ // GCC 4.7 and 4.8 incorrectly issue a -Wunused-but-set-variable warning
+ // for RPCArgs. Void cast RPCArgs to work around this for now.
+ // FIXME: Remove this workaround once we can assume a working GCC version.
+ (void)Args;
+
+ // End receieve message, unlocking the channel for reading.
+ if (auto Err = Channel.endReceiveMessage())
+ return Err;
+
+ using HTraits = detail::HandlerTraits<HandlerT>;
+ using FuncReturn = typename Func::ReturnType;
+ auto Responder = [this,
+ SeqNo](typename AHTraits::ResultType RetVal) -> Error {
+ return detail::respond<FuncReturn>(C, ResponseId, SeqNo,
+ std::move(RetVal));
+ };
+
+ return HTraits::unpackAndRunAsync(Handler, Responder, *Args);
+ };
+ }
+
+ ChannelT &C;
+
+ bool LazyAutoNegotiation;
+
+ RPCFunctionIdAllocator<FunctionIdT> FnIdAllocator;
+
+ FunctionIdT ResponseId;
+ std::map<std::string, FunctionIdT> LocalFunctionIds;
+ std::map<const char *, FunctionIdT> RemoteFunctionIds;
+
+ std::map<FunctionIdT, WrappedHandlerFn> Handlers;
+
+ std::mutex ResponsesMutex;
+ detail::SequenceNumberManager<SequenceNumberT> SequenceNumberMgr;
+ std::map<SequenceNumberT, std::unique_ptr<detail::ResponseHandler<ChannelT>>>
+ PendingResponses;
+};
+
+} // end namespace detail
+
+template <typename ChannelT, typename FunctionIdT = uint32_t,
+ typename SequenceNumberT = uint32_t>
+class MultiThreadedRPCEndpoint
+ : public detail::RPCEndpointBase<
+ MultiThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
+ ChannelT, FunctionIdT, SequenceNumberT> {
+private:
+ using BaseClass = detail::RPCEndpointBase<
+ MultiThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
+ ChannelT, FunctionIdT, SequenceNumberT>;
+
+public:
+ MultiThreadedRPCEndpoint(ChannelT &C, bool LazyAutoNegotiation)
+ : BaseClass(C, LazyAutoNegotiation) {}
+
+ /// Add a handler for the given RPC function.
+ /// This installs the given handler functor for the given RPCFunction, and
+ /// makes the RPC function available for negotiation/calling from the remote.
+ template <typename Func, typename HandlerT>
+ void addHandler(HandlerT Handler) {
+ return this->template addHandlerImpl<Func>(std::move(Handler));
+ }
+
+ /// Add a class-method as a handler.
+ template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
+ void addHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
+ addHandler<Func>(
+ detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
+ }
+
+ template <typename Func, typename HandlerT>
+ void addAsyncHandler(HandlerT Handler) {
+ return this->template addAsyncHandlerImpl<Func>(std::move(Handler));
+ }
+
+ /// Add a class-method as a handler.
+ template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
+ void addAsyncHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
+ addAsyncHandler<Func>(
+ detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
+ }
+
+ /// Return type for non-blocking call primitives.
+ template <typename Func>
+ using NonBlockingCallResult = typename detail::ResultTraits<
+ typename Func::ReturnType>::ReturnFutureType;
+
+ /// Call Func on Channel C. Does not block, does not call send. Returns a pair
+ /// of a future result and the sequence number assigned to the result.
+ ///
+ /// This utility function is primarily used for single-threaded mode support,
+ /// where the sequence number can be used to wait for the corresponding
+ /// result. In multi-threaded mode the appendCallNB method, which does not
+ /// return the sequence numeber, should be preferred.
+ template <typename Func, typename... ArgTs>
+ Expected<NonBlockingCallResult<Func>> appendCallNB(const ArgTs &...Args) {
+ using RTraits = detail::ResultTraits<typename Func::ReturnType>;
+ using ErrorReturn = typename RTraits::ErrorReturnType;
+ using ErrorReturnPromise = typename RTraits::ReturnPromiseType;
+
+ ErrorReturnPromise Promise;
+ auto FutureResult = Promise.get_future();
+
+ if (auto Err = this->template appendCallAsync<Func>(
+ [Promise = std::move(Promise)](ErrorReturn RetOrErr) mutable {
+ Promise.set_value(std::move(RetOrErr));
+ return Error::success();
+ },
+ Args...)) {
+ RTraits::consumeAbandoned(FutureResult.get());
+ return std::move(Err);
+ }
+ return std::move(FutureResult);
+ }
+
+ /// The same as appendCallNBWithSeq, except that it calls C.send() to
+ /// flush the channel after serializing the call.
+ template <typename Func, typename... ArgTs>
+ Expected<NonBlockingCallResult<Func>> callNB(const ArgTs &...Args) {
+ auto Result = appendCallNB<Func>(Args...);
+ if (!Result)
+ return Result;
+ if (auto Err = this->C.send()) {
+ this->abandonPendingResponses();
+ detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
+ std::move(Result->get()));
+ return std::move(Err);
+ }
+ return Result;
+ }
+
+ /// Call Func on Channel C. Blocks waiting for a result. Returns an Error
+ /// for void functions or an Expected<T> for functions returning a T.
+ ///
+ /// This function is for use in threaded code where another thread is
+ /// handling responses and incoming calls.
+ template <typename Func, typename... ArgTs,
+ typename AltRetT = typename Func::ReturnType>
+ typename detail::ResultTraits<AltRetT>::ErrorReturnType
+ callB(const ArgTs &...Args) {
+ if (auto FutureResOrErr = callNB<Func>(Args...))
+ return FutureResOrErr->get();
+ else
+ return FutureResOrErr.takeError();
+ }
+
+ /// Handle incoming RPC calls.
+ Error handlerLoop() {
+ while (true)
+ if (auto Err = this->handleOne())
+ return Err;
+ return Error::success();
+ }
+};
+
+template <typename ChannelT, typename FunctionIdT = uint32_t,
+ typename SequenceNumberT = uint32_t>
+class SingleThreadedRPCEndpoint
+ : public detail::RPCEndpointBase<
+ SingleThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
+ ChannelT, FunctionIdT, SequenceNumberT> {
+private:
+ using BaseClass = detail::RPCEndpointBase<
+ SingleThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
+ ChannelT, FunctionIdT, SequenceNumberT>;
+
+public:
+ SingleThreadedRPCEndpoint(ChannelT &C, bool LazyAutoNegotiation)
+ : BaseClass(C, LazyAutoNegotiation) {}
+
+ template <typename Func, typename HandlerT>
+ void addHandler(HandlerT Handler) {
+ return this->template addHandlerImpl<Func>(std::move(Handler));
+ }
+
+ template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
+ void addHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
+ addHandler<Func>(
+ detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
+ }
+
+ template <typename Func, typename HandlerT>
+ void addAsyncHandler(HandlerT Handler) {
+ return this->template addAsyncHandlerImpl<Func>(std::move(Handler));
+ }
+
+ /// Add a class-method as a handler.
+ template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
+ void addAsyncHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
+ addAsyncHandler<Func>(
+ detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
+ }
+
+ template <typename Func, typename... ArgTs,
+ typename AltRetT = typename Func::ReturnType>
+ typename detail::ResultTraits<AltRetT>::ErrorReturnType
+ callB(const ArgTs &...Args) {
+ bool ReceivedResponse = false;
+ using ResultType = typename detail::ResultTraits<AltRetT>::ErrorReturnType;
+ auto Result = detail::ResultTraits<AltRetT>::createBlankErrorReturnValue();
+
+ // We have to 'Check' result (which we know is in a success state at this
+ // point) so that it can be overwritten in the async handler.
+ (void)!!Result;
+
+ if (auto Err = this->template appendCallAsync<Func>(
+ [&](ResultType R) {
+ Result = std::move(R);
+ ReceivedResponse = true;
+ return Error::success();
+ },
+ Args...)) {
+ detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
+ std::move(Result));
+ return std::move(Err);
+ }
+
+ if (auto Err = this->C.send()) {
+ detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
+ std::move(Result));
+ return std::move(Err);
+ }
+
+ while (!ReceivedResponse) {
+ if (auto Err = this->handleOne()) {
+ detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
+ std::move(Result));
+ return std::move(Err);
+ }
+ }
+
+ return Result;
+ }
+};
+
+/// Asynchronous dispatch for a function on an RPC endpoint.
+template <typename RPCClass, typename Func> class RPCAsyncDispatch {
+public:
+ RPCAsyncDispatch(RPCClass &Endpoint) : Endpoint(Endpoint) {}
+
+ template <typename HandlerT, typename... ArgTs>
+ Error operator()(HandlerT Handler, const ArgTs &...Args) const {
+ return Endpoint.template appendCallAsync<Func>(std::move(Handler), Args...);
+ }
+
+private:
+ RPCClass &Endpoint;
+};
+
+/// Construct an asynchronous dispatcher from an RPC endpoint and a Func.
+template <typename Func, typename RPCEndpointT>
+RPCAsyncDispatch<RPCEndpointT, Func> rpcAsyncDispatch(RPCEndpointT &Endpoint) {
+ return RPCAsyncDispatch<RPCEndpointT, Func>(Endpoint);
+}
+
+/// Allows a set of asynchrounous calls to be dispatched, and then
+/// waited on as a group.
+class ParallelCallGroup {
+public:
+ ParallelCallGroup() = default;
+ ParallelCallGroup(const ParallelCallGroup &) = delete;
+ ParallelCallGroup &operator=(const ParallelCallGroup &) = delete;
+
+ /// Make as asynchronous call.
+ template <typename AsyncDispatcher, typename HandlerT, typename... ArgTs>
+ Error call(const AsyncDispatcher &AsyncDispatch, HandlerT Handler,
+ const ArgTs &...Args) {
+ // Increment the count of outstanding calls. This has to happen before
+ // we invoke the call, as the handler may (depending on scheduling)
+ // be run immediately on another thread, and we don't want the decrement
+ // in the wrapped handler below to run before the increment.
+ {
+ std::unique_lock<std::mutex> Lock(M);
+ ++NumOutstandingCalls;
+ }
+
+ // Wrap the user handler in a lambda that will decrement the
+ // outstanding calls count, then poke the condition variable.
+ using ArgType = typename detail::ResponseHandlerArg<
+ typename detail::HandlerTraits<HandlerT>::Type>::ArgType;
+ auto WrappedHandler = [this, Handler = std::move(Handler)](ArgType Arg) {
+ auto Err = Handler(std::move(Arg));
+ std::unique_lock<std::mutex> Lock(M);
+ --NumOutstandingCalls;
+ CV.notify_all();
+ return Err;
+ };
+
+ return AsyncDispatch(std::move(WrappedHandler), Args...);
+ }
+
+ /// Blocks until all calls have been completed and their return value
+ /// handlers run.
+ void wait() {
+ std::unique_lock<std::mutex> Lock(M);
+ while (NumOutstandingCalls > 0)
+ CV.wait(Lock);
+ }
+
+private:
+ std::mutex M;
+ std::condition_variable CV;
+ uint32_t NumOutstandingCalls = 0;
+};
+
+/// Convenience class for grouping RPCFunctions into APIs that can be
+/// negotiated as a block.
+///
+template <typename... Funcs> class APICalls {
+public:
+ /// Test whether this API contains Function F.
+ template <typename F> class Contains {
+ public:
+ static const bool value = false;
+ };
+
+ /// Negotiate all functions in this API.
+ template <typename RPCEndpoint> static Error negotiate(RPCEndpoint &R) {
+ return Error::success();
+ }
+};
+
+template <typename Func, typename... Funcs> class APICalls<Func, Funcs...> {
+public:
+ template <typename F> class Contains {
+ public:
+ static const bool value = std::is_same<F, Func>::value |
+ APICalls<Funcs...>::template Contains<F>::value;
+ };
+
+ template <typename RPCEndpoint> static Error negotiate(RPCEndpoint &R) {
+ if (auto Err = R.template negotiateFunction<Func>())
+ return Err;
+ return APICalls<Funcs...>::negotiate(R);
+ }
+};
+
+template <typename... InnerFuncs, typename... Funcs>
+class APICalls<APICalls<InnerFuncs...>, Funcs...> {
+public:
+ template <typename F> class Contains {
+ public:
+ static const bool value =
+ APICalls<InnerFuncs...>::template Contains<F>::value |
+ APICalls<Funcs...>::template Contains<F>::value;
+ };
+
+ template <typename RPCEndpoint> static Error negotiate(RPCEndpoint &R) {
+ if (auto Err = APICalls<InnerFuncs...>::negotiate(R))
+ return Err;
+ return APICalls<Funcs...>::negotiate(R);
+ }
+};
+
+} // end namespace shared
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_RPCUTILS_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h
index 4f6175af33..94bb6c7739 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h
@@ -1,194 +1,194 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- RawByteChannel.h -----------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_RAWBYTECHANNEL_H
-#define LLVM_EXECUTIONENGINE_ORC_SHARED_RAWBYTECHANNEL_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ExecutionEngine/Orc/Shared/Serialization.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <cstdint>
-#include <mutex>
-#include <string>
-#include <type_traits>
-
-namespace llvm {
-namespace orc {
-namespace shared {
-
-/// Interface for byte-streams to be used with ORC Serialization.
-class RawByteChannel {
-public:
- virtual ~RawByteChannel() = default;
-
- /// Read Size bytes from the stream into *Dst.
- virtual Error readBytes(char *Dst, unsigned Size) = 0;
-
- /// Read size bytes from *Src and append them to the stream.
- virtual Error appendBytes(const char *Src, unsigned Size) = 0;
-
- /// Flush the stream if possible.
- virtual Error send() = 0;
-
- /// Notify the channel that we're starting a message send.
- /// Locks the channel for writing.
- template <typename FunctionIdT, typename SequenceIdT>
- Error startSendMessage(const FunctionIdT &FnId, const SequenceIdT &SeqNo) {
- writeLock.lock();
- if (auto Err = serializeSeq(*this, FnId, SeqNo)) {
- writeLock.unlock();
- return Err;
- }
- return Error::success();
- }
-
- /// Notify the channel that we're ending a message send.
- /// Unlocks the channel for writing.
- Error endSendMessage() {
- writeLock.unlock();
- return Error::success();
- }
-
- /// Notify the channel that we're starting a message receive.
- /// Locks the channel for reading.
- template <typename FunctionIdT, typename SequenceNumberT>
- Error startReceiveMessage(FunctionIdT &FnId, SequenceNumberT &SeqNo) {
- readLock.lock();
- if (auto Err = deserializeSeq(*this, FnId, SeqNo)) {
- readLock.unlock();
- return Err;
- }
- return Error::success();
- }
-
- /// Notify the channel that we're ending a message receive.
- /// Unlocks the channel for reading.
- Error endReceiveMessage() {
- readLock.unlock();
- return Error::success();
- }
-
- /// Get the lock for stream reading.
- std::mutex &getReadLock() { return readLock; }
-
- /// Get the lock for stream writing.
- std::mutex &getWriteLock() { return writeLock; }
-
-private:
- std::mutex readLock, writeLock;
-};
-
-template <typename ChannelT, typename T>
-class SerializationTraits<
- ChannelT, T, T,
- std::enable_if_t<
- std::is_base_of<RawByteChannel, ChannelT>::value &&
- (std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value ||
- std::is_same<T, uint16_t>::value || std::is_same<T, int16_t>::value ||
- std::is_same<T, uint32_t>::value || std::is_same<T, int32_t>::value ||
- std::is_same<T, uint64_t>::value || std::is_same<T, int64_t>::value ||
- std::is_same<T, char>::value)>> {
-public:
- static Error serialize(ChannelT &C, T V) {
- support::endian::byte_swap<T, support::big>(V);
- return C.appendBytes(reinterpret_cast<const char *>(&V), sizeof(T));
- };
-
- static Error deserialize(ChannelT &C, T &V) {
- if (auto Err = C.readBytes(reinterpret_cast<char *>(&V), sizeof(T)))
- return Err;
- support::endian::byte_swap<T, support::big>(V);
- return Error::success();
- };
-};
-
-template <typename ChannelT>
-class SerializationTraits<
- ChannelT, bool, bool,
- std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
-public:
- static Error serialize(ChannelT &C, bool V) {
- uint8_t Tmp = V ? 1 : 0;
- if (auto Err = C.appendBytes(reinterpret_cast<const char *>(&Tmp), 1))
- return Err;
- return Error::success();
- }
-
- static Error deserialize(ChannelT &C, bool &V) {
- uint8_t Tmp = 0;
- if (auto Err = C.readBytes(reinterpret_cast<char *>(&Tmp), 1))
- return Err;
- V = Tmp != 0;
- return Error::success();
- }
-};
-
-template <typename ChannelT>
-class SerializationTraits<
- ChannelT, std::string, StringRef,
- std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
-public:
- /// Serialization channel serialization for std::strings.
- static Error serialize(RawByteChannel &C, StringRef S) {
- if (auto Err = serializeSeq(C, static_cast<uint64_t>(S.size())))
- return Err;
- return C.appendBytes((const char *)S.data(), S.size());
- }
-};
-
-template <typename ChannelT, typename T>
-class SerializationTraits<
- ChannelT, std::string, T,
- std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value &&
- (std::is_same<T, const char *>::value ||
- std::is_same<T, char *>::value)>> {
-public:
- static Error serialize(RawByteChannel &C, const char *S) {
- return SerializationTraits<ChannelT, std::string, StringRef>::serialize(C,
- S);
- }
-};
-
-template <typename ChannelT>
-class SerializationTraits<
- ChannelT, std::string, std::string,
- std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
-public:
- /// Serialization channel serialization for std::strings.
- static Error serialize(RawByteChannel &C, const std::string &S) {
- return SerializationTraits<ChannelT, std::string, StringRef>::serialize(C,
- S);
- }
-
- /// Serialization channel deserialization for std::strings.
- static Error deserialize(RawByteChannel &C, std::string &S) {
- uint64_t Count = 0;
- if (auto Err = deserializeSeq(C, Count))
- return Err;
- S.resize(Count);
- return C.readBytes(&S[0], Count);
- }
-};
-
-} // end namespace shared
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_RAWBYTECHANNEL_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- RawByteChannel.h -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_RAWBYTECHANNEL_H
+#define LLVM_EXECUTIONENGINE_ORC_SHARED_RAWBYTECHANNEL_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/Orc/Shared/Serialization.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <mutex>
+#include <string>
+#include <type_traits>
+
+namespace llvm {
+namespace orc {
+namespace shared {
+
+/// Interface for byte-streams to be used with ORC Serialization.
+class RawByteChannel {
+public:
+ virtual ~RawByteChannel() = default;
+
+ /// Read Size bytes from the stream into *Dst.
+ virtual Error readBytes(char *Dst, unsigned Size) = 0;
+
+ /// Read size bytes from *Src and append them to the stream.
+ virtual Error appendBytes(const char *Src, unsigned Size) = 0;
+
+ /// Flush the stream if possible.
+ virtual Error send() = 0;
+
+ /// Notify the channel that we're starting a message send.
+ /// Locks the channel for writing.
+ template <typename FunctionIdT, typename SequenceIdT>
+ Error startSendMessage(const FunctionIdT &FnId, const SequenceIdT &SeqNo) {
+ writeLock.lock();
+ if (auto Err = serializeSeq(*this, FnId, SeqNo)) {
+ writeLock.unlock();
+ return Err;
+ }
+ return Error::success();
+ }
+
+ /// Notify the channel that we're ending a message send.
+ /// Unlocks the channel for writing.
+ Error endSendMessage() {
+ writeLock.unlock();
+ return Error::success();
+ }
+
+ /// Notify the channel that we're starting a message receive.
+ /// Locks the channel for reading.
+ template <typename FunctionIdT, typename SequenceNumberT>
+ Error startReceiveMessage(FunctionIdT &FnId, SequenceNumberT &SeqNo) {
+ readLock.lock();
+ if (auto Err = deserializeSeq(*this, FnId, SeqNo)) {
+ readLock.unlock();
+ return Err;
+ }
+ return Error::success();
+ }
+
+ /// Notify the channel that we're ending a message receive.
+ /// Unlocks the channel for reading.
+ Error endReceiveMessage() {
+ readLock.unlock();
+ return Error::success();
+ }
+
+ /// Get the lock for stream reading.
+ std::mutex &getReadLock() { return readLock; }
+
+ /// Get the lock for stream writing.
+ std::mutex &getWriteLock() { return writeLock; }
+
+private:
+ std::mutex readLock, writeLock;
+};
+
+template <typename ChannelT, typename T>
+class SerializationTraits<
+ ChannelT, T, T,
+ std::enable_if_t<
+ std::is_base_of<RawByteChannel, ChannelT>::value &&
+ (std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value ||
+ std::is_same<T, uint16_t>::value || std::is_same<T, int16_t>::value ||
+ std::is_same<T, uint32_t>::value || std::is_same<T, int32_t>::value ||
+ std::is_same<T, uint64_t>::value || std::is_same<T, int64_t>::value ||
+ std::is_same<T, char>::value)>> {
+public:
+ static Error serialize(ChannelT &C, T V) {
+ support::endian::byte_swap<T, support::big>(V);
+ return C.appendBytes(reinterpret_cast<const char *>(&V), sizeof(T));
+ };
+
+ static Error deserialize(ChannelT &C, T &V) {
+ if (auto Err = C.readBytes(reinterpret_cast<char *>(&V), sizeof(T)))
+ return Err;
+ support::endian::byte_swap<T, support::big>(V);
+ return Error::success();
+ };
+};
+
+template <typename ChannelT>
+class SerializationTraits<
+ ChannelT, bool, bool,
+ std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
+public:
+ static Error serialize(ChannelT &C, bool V) {
+ uint8_t Tmp = V ? 1 : 0;
+ if (auto Err = C.appendBytes(reinterpret_cast<const char *>(&Tmp), 1))
+ return Err;
+ return Error::success();
+ }
+
+ static Error deserialize(ChannelT &C, bool &V) {
+ uint8_t Tmp = 0;
+ if (auto Err = C.readBytes(reinterpret_cast<char *>(&Tmp), 1))
+ return Err;
+ V = Tmp != 0;
+ return Error::success();
+ }
+};
+
+template <typename ChannelT>
+class SerializationTraits<
+ ChannelT, std::string, StringRef,
+ std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
+public:
+ /// Serialization channel serialization for std::strings.
+ static Error serialize(RawByteChannel &C, StringRef S) {
+ if (auto Err = serializeSeq(C, static_cast<uint64_t>(S.size())))
+ return Err;
+ return C.appendBytes((const char *)S.data(), S.size());
+ }
+};
+
+template <typename ChannelT, typename T>
+class SerializationTraits<
+ ChannelT, std::string, T,
+ std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value &&
+ (std::is_same<T, const char *>::value ||
+ std::is_same<T, char *>::value)>> {
+public:
+ static Error serialize(RawByteChannel &C, const char *S) {
+ return SerializationTraits<ChannelT, std::string, StringRef>::serialize(C,
+ S);
+ }
+};
+
+template <typename ChannelT>
+class SerializationTraits<
+ ChannelT, std::string, std::string,
+ std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
+public:
+ /// Serialization channel serialization for std::strings.
+ static Error serialize(RawByteChannel &C, const std::string &S) {
+ return SerializationTraits<ChannelT, std::string, StringRef>::serialize(C,
+ S);
+ }
+
+ /// Serialization channel deserialization for std::strings.
+ static Error deserialize(RawByteChannel &C, std::string &S) {
+ uint64_t Count = 0;
+ if (auto Err = deserializeSeq(C, Count))
+ return Err;
+ S.resize(Count);
+ return C.readBytes(&S[0], Count);
+ }
+};
+
+} // end namespace shared
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_RAWBYTECHANNEL_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/Serialization.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/Serialization.h
index fa48a7af43..5f4e2767f0 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/Serialization.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/Serialization.h
@@ -1,780 +1,780 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- Serialization.h ------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_SERIALIZATION_H
-#define LLVM_EXECUTIONENGINE_ORC_SHARED_SERIALIZATION_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
-#include "llvm/Support/thread.h"
-#include <map>
-#include <mutex>
-#include <set>
-#include <sstream>
-#include <string>
-#include <vector>
-
-namespace llvm {
-namespace orc {
-namespace shared {
-
-template <typename T> class SerializationTypeName;
-
-/// TypeNameSequence is a utility for rendering sequences of types to a string
-/// by rendering each type, separated by ", ".
-template <typename... ArgTs> class SerializationTypeNameSequence {};
-
-/// Render an empty TypeNameSequence to an ostream.
-template <typename OStream>
-OStream &operator<<(OStream &OS, const SerializationTypeNameSequence<> &V) {
- return OS;
-}
-
-/// Render a TypeNameSequence of a single type to an ostream.
-template <typename OStream, typename ArgT>
-OStream &operator<<(OStream &OS, const SerializationTypeNameSequence<ArgT> &V) {
- OS << SerializationTypeName<ArgT>::getName();
- return OS;
-}
-
-/// Render a TypeNameSequence of more than one type to an ostream.
-template <typename OStream, typename ArgT1, typename ArgT2, typename... ArgTs>
-OStream &
-operator<<(OStream &OS,
- const SerializationTypeNameSequence<ArgT1, ArgT2, ArgTs...> &V) {
- OS << SerializationTypeName<ArgT1>::getName() << ", "
- << SerializationTypeNameSequence<ArgT2, ArgTs...>();
- return OS;
-}
-
-template <> class SerializationTypeName<void> {
-public:
- static const char *getName() { return "void"; }
-};
-
-template <> class SerializationTypeName<int8_t> {
-public:
- static const char *getName() { return "int8_t"; }
-};
-
-template <> class SerializationTypeName<uint8_t> {
-public:
- static const char *getName() { return "uint8_t"; }
-};
-
-template <> class SerializationTypeName<int16_t> {
-public:
- static const char *getName() { return "int16_t"; }
-};
-
-template <> class SerializationTypeName<uint16_t> {
-public:
- static const char *getName() { return "uint16_t"; }
-};
-
-template <> class SerializationTypeName<int32_t> {
-public:
- static const char *getName() { return "int32_t"; }
-};
-
-template <> class SerializationTypeName<uint32_t> {
-public:
- static const char *getName() { return "uint32_t"; }
-};
-
-template <> class SerializationTypeName<int64_t> {
-public:
- static const char *getName() { return "int64_t"; }
-};
-
-template <> class SerializationTypeName<uint64_t> {
-public:
- static const char *getName() { return "uint64_t"; }
-};
-
-template <> class SerializationTypeName<bool> {
-public:
- static const char *getName() { return "bool"; }
-};
-
-template <> class SerializationTypeName<std::string> {
-public:
- static const char *getName() { return "std::string"; }
-};
-
-template <> class SerializationTypeName<Error> {
-public:
- static const char *getName() { return "Error"; }
-};
-
-template <typename T> class SerializationTypeName<Expected<T>> {
-public:
- static const char *getName() {
- static std::string Name = [] {
- std::string Name;
- raw_string_ostream(Name)
- << "Expected<" << SerializationTypeNameSequence<T>() << ">";
- return Name;
- }();
- return Name.data();
- }
-};
-
-template <typename T1, typename T2>
-class SerializationTypeName<std::pair<T1, T2>> {
-public:
- static const char *getName() {
- static std::string Name = [] {
- std::string Name;
- raw_string_ostream(Name)
- << "std::pair<" << SerializationTypeNameSequence<T1, T2>() << ">";
- return Name;
- }();
- return Name.data();
- }
-};
-
-template <typename... ArgTs> class SerializationTypeName<std::tuple<ArgTs...>> {
-public:
- static const char *getName() {
- static std::string Name = [] {
- std::string Name;
- raw_string_ostream(Name)
- << "std::tuple<" << SerializationTypeNameSequence<ArgTs...>() << ">";
- return Name;
- }();
- return Name.data();
- }
-};
-
-template <typename T> class SerializationTypeName<Optional<T>> {
-public:
- static const char *getName() {
- static std::string Name = [] {
- std::string Name;
- raw_string_ostream(Name)
- << "Optional<" << SerializationTypeName<T>::getName() << ">";
- return Name;
- }();
- return Name.data();
- }
-};
-
-template <typename T> class SerializationTypeName<std::vector<T>> {
-public:
- static const char *getName() {
- static std::string Name = [] {
- std::string Name;
- raw_string_ostream(Name)
- << "std::vector<" << SerializationTypeName<T>::getName() << ">";
- return Name;
- }();
- return Name.data();
- }
-};
-
-template <typename T> class SerializationTypeName<std::set<T>> {
-public:
- static const char *getName() {
- static std::string Name = [] {
- std::string Name;
- raw_string_ostream(Name)
- << "std::set<" << SerializationTypeName<T>::getName() << ">";
- return Name;
- }();
- return Name.data();
- }
-};
-
-template <typename K, typename V> class SerializationTypeName<std::map<K, V>> {
-public:
- static const char *getName() {
- static std::string Name = [] {
- std::string Name;
- raw_string_ostream(Name)
- << "std::map<" << SerializationTypeNameSequence<K, V>() << ">";
- return Name;
- }();
- return Name.data();
- }
-};
-
-/// The SerializationTraits<ChannelT, T> class describes how to serialize and
-/// deserialize an instance of type T to/from an abstract channel of type
-/// ChannelT. It also provides a representation of the type's name via the
-/// getName method.
-///
-/// Specializations of this class should provide the following functions:
-///
-/// @code{.cpp}
-///
-/// static const char* getName();
-/// static Error serialize(ChannelT&, const T&);
-/// static Error deserialize(ChannelT&, T&);
-///
-/// @endcode
-///
-/// The third argument of SerializationTraits is intended to support SFINAE.
-/// E.g.:
-///
-/// @code{.cpp}
-///
-/// class MyVirtualChannel { ... };
-///
-/// template <DerivedChannelT>
-/// class SerializationTraits<DerivedChannelT, bool,
-/// std::enable_if_t<
-/// std::is_base_of<VirtChannel, DerivedChannel>::value
-/// >> {
-/// public:
-/// static const char* getName() { ... };
-/// }
-///
-/// @endcode
-template <typename ChannelT, typename WireType,
- typename ConcreteType = WireType, typename = void>
-class SerializationTraits;
-
-template <typename ChannelT> class SequenceTraits {
-public:
- static Error emitSeparator(ChannelT &C) { return Error::success(); }
- static Error consumeSeparator(ChannelT &C) { return Error::success(); }
-};
-
-/// Utility class for serializing sequences of values of varying types.
-/// Specializations of this class contain 'serialize' and 'deserialize' methods
-/// for the given channel. The ArgTs... list will determine the "over-the-wire"
-/// types to be serialized. The serialize and deserialize methods take a list
-/// CArgTs... ("caller arg types") which must be the same length as ArgTs...,
-/// but may be different types from ArgTs, provided that for each CArgT there
-/// is a SerializationTraits specialization
-/// SerializeTraits<ChannelT, ArgT, CArgT> with methods that can serialize the
-/// caller argument to over-the-wire value.
-template <typename ChannelT, typename... ArgTs> class SequenceSerialization;
-
-template <typename ChannelT> class SequenceSerialization<ChannelT> {
-public:
- static Error serialize(ChannelT &C) { return Error::success(); }
- static Error deserialize(ChannelT &C) { return Error::success(); }
-};
-
-template <typename ChannelT, typename ArgT>
-class SequenceSerialization<ChannelT, ArgT> {
-public:
- template <typename CArgT> static Error serialize(ChannelT &C, CArgT &&CArg) {
- return SerializationTraits<ChannelT, ArgT, std::decay_t<CArgT>>::serialize(
- C, std::forward<CArgT>(CArg));
- }
-
- template <typename CArgT> static Error deserialize(ChannelT &C, CArgT &CArg) {
- return SerializationTraits<ChannelT, ArgT, CArgT>::deserialize(C, CArg);
- }
-};
-
-template <typename ChannelT, typename ArgT, typename... ArgTs>
-class SequenceSerialization<ChannelT, ArgT, ArgTs...> {
-public:
- template <typename CArgT, typename... CArgTs>
- static Error serialize(ChannelT &C, CArgT &&CArg, CArgTs &&...CArgs) {
- if (auto Err =
- SerializationTraits<ChannelT, ArgT, std::decay_t<CArgT>>::serialize(
- C, std::forward<CArgT>(CArg)))
- return Err;
- if (auto Err = SequenceTraits<ChannelT>::emitSeparator(C))
- return Err;
- return SequenceSerialization<ChannelT, ArgTs...>::serialize(
- C, std::forward<CArgTs>(CArgs)...);
- }
-
- template <typename CArgT, typename... CArgTs>
- static Error deserialize(ChannelT &C, CArgT &CArg, CArgTs &...CArgs) {
- if (auto Err =
- SerializationTraits<ChannelT, ArgT, CArgT>::deserialize(C, CArg))
- return Err;
- if (auto Err = SequenceTraits<ChannelT>::consumeSeparator(C))
- return Err;
- return SequenceSerialization<ChannelT, ArgTs...>::deserialize(C, CArgs...);
- }
-};
-
-template <typename ChannelT, typename... ArgTs>
-Error serializeSeq(ChannelT &C, ArgTs &&...Args) {
- return SequenceSerialization<ChannelT, std::decay_t<ArgTs>...>::serialize(
- C, std::forward<ArgTs>(Args)...);
-}
-
-template <typename ChannelT, typename... ArgTs>
-Error deserializeSeq(ChannelT &C, ArgTs &...Args) {
- return SequenceSerialization<ChannelT, ArgTs...>::deserialize(C, Args...);
-}
-
-template <typename ChannelT> class SerializationTraits<ChannelT, Error> {
-public:
- using WrappedErrorSerializer =
- std::function<Error(ChannelT &C, const ErrorInfoBase &)>;
-
- using WrappedErrorDeserializer =
- std::function<Error(ChannelT &C, Error &Err)>;
-
- template <typename ErrorInfoT, typename SerializeFtor,
- typename DeserializeFtor>
- static void registerErrorType(std::string Name, SerializeFtor Serialize,
- DeserializeFtor Deserialize) {
- assert(!Name.empty() &&
- "The empty string is reserved for the Success value");
-
- const std::string *KeyName = nullptr;
- {
- // We're abusing the stability of std::map here: We take a reference to
- // the key of the deserializers map to save us from duplicating the string
- // in the serializer. This should be changed to use a stringpool if we
- // switch to a map type that may move keys in memory.
- std::lock_guard<std::recursive_mutex> Lock(DeserializersMutex);
- auto I = Deserializers.insert(
- Deserializers.begin(),
- std::make_pair(std::move(Name), std::move(Deserialize)));
- KeyName = &I->first;
- }
-
- {
- assert(KeyName != nullptr && "No keyname pointer");
- std::lock_guard<std::recursive_mutex> Lock(SerializersMutex);
- Serializers[ErrorInfoT::classID()] =
- [KeyName, Serialize = std::move(Serialize)](
- ChannelT &C, const ErrorInfoBase &EIB) -> Error {
- assert(EIB.dynamicClassID() == ErrorInfoT::classID() &&
- "Serializer called for wrong error type");
- if (auto Err = serializeSeq(C, *KeyName))
- return Err;
- return Serialize(C, static_cast<const ErrorInfoT &>(EIB));
- };
- }
- }
-
- static Error serialize(ChannelT &C, Error &&Err) {
- std::lock_guard<std::recursive_mutex> Lock(SerializersMutex);
-
- if (!Err)
- return serializeSeq(C, std::string());
-
- return handleErrors(std::move(Err), [&C](const ErrorInfoBase &EIB) {
- auto SI = Serializers.find(EIB.dynamicClassID());
- if (SI == Serializers.end())
- return serializeAsStringError(C, EIB);
- return (SI->second)(C, EIB);
- });
- }
-
- static Error deserialize(ChannelT &C, Error &Err) {
- std::lock_guard<std::recursive_mutex> Lock(DeserializersMutex);
-
- std::string Key;
- if (auto Err = deserializeSeq(C, Key))
- return Err;
-
- if (Key.empty()) {
- ErrorAsOutParameter EAO(&Err);
- Err = Error::success();
- return Error::success();
- }
-
- auto DI = Deserializers.find(Key);
- assert(DI != Deserializers.end() && "No deserializer for error type");
- return (DI->second)(C, Err);
- }
-
-private:
- static Error serializeAsStringError(ChannelT &C, const ErrorInfoBase &EIB) {
- std::string ErrMsg;
- {
- raw_string_ostream ErrMsgStream(ErrMsg);
- EIB.log(ErrMsgStream);
- }
- return serialize(C, make_error<StringError>(std::move(ErrMsg),
- inconvertibleErrorCode()));
- }
-
- static std::recursive_mutex SerializersMutex;
- static std::recursive_mutex DeserializersMutex;
- static std::map<const void *, WrappedErrorSerializer> Serializers;
- static std::map<std::string, WrappedErrorDeserializer> Deserializers;
-};
-
-template <typename ChannelT>
-std::recursive_mutex SerializationTraits<ChannelT, Error>::SerializersMutex;
-
-template <typename ChannelT>
-std::recursive_mutex SerializationTraits<ChannelT, Error>::DeserializersMutex;
-
-template <typename ChannelT>
-std::map<const void *,
- typename SerializationTraits<ChannelT, Error>::WrappedErrorSerializer>
- SerializationTraits<ChannelT, Error>::Serializers;
-
-template <typename ChannelT>
-std::map<std::string, typename SerializationTraits<
- ChannelT, Error>::WrappedErrorDeserializer>
- SerializationTraits<ChannelT, Error>::Deserializers;
-
-/// Registers a serializer and deserializer for the given error type on the
-/// given channel type.
-template <typename ChannelT, typename ErrorInfoT, typename SerializeFtor,
- typename DeserializeFtor>
-void registerErrorSerialization(std::string Name, SerializeFtor &&Serialize,
- DeserializeFtor &&Deserialize) {
- SerializationTraits<ChannelT, Error>::template registerErrorType<ErrorInfoT>(
- std::move(Name), std::forward<SerializeFtor>(Serialize),
- std::forward<DeserializeFtor>(Deserialize));
-}
-
-/// Registers serialization/deserialization for StringError.
-template <typename ChannelT> void registerStringError() {
- static bool AlreadyRegistered = false;
- if (!AlreadyRegistered) {
- registerErrorSerialization<ChannelT, StringError>(
- "StringError",
- [](ChannelT &C, const StringError &SE) {
- return serializeSeq(C, SE.getMessage());
- },
- [](ChannelT &C, Error &Err) -> Error {
- ErrorAsOutParameter EAO(&Err);
- std::string Msg;
- if (auto E2 = deserializeSeq(C, Msg))
- return E2;
- Err = make_error<StringError>(
- std::move(Msg),
- orcError(OrcErrorCode::UnknownErrorCodeFromRemote));
- return Error::success();
- });
- AlreadyRegistered = true;
- }
-}
-
-/// SerializationTraits for Expected<T1> from an Expected<T2>.
-template <typename ChannelT, typename T1, typename T2>
-class SerializationTraits<ChannelT, Expected<T1>, Expected<T2>> {
-public:
- static Error serialize(ChannelT &C, Expected<T2> &&ValOrErr) {
- if (ValOrErr) {
- if (auto Err = serializeSeq(C, true))
- return Err;
- return SerializationTraits<ChannelT, T1, T2>::serialize(C, *ValOrErr);
- }
- if (auto Err = serializeSeq(C, false))
- return Err;
- return serializeSeq(C, ValOrErr.takeError());
- }
-
- static Error deserialize(ChannelT &C, Expected<T2> &ValOrErr) {
- ExpectedAsOutParameter<T2> EAO(&ValOrErr);
- bool HasValue;
- if (auto Err = deserializeSeq(C, HasValue))
- return Err;
- if (HasValue)
- return SerializationTraits<ChannelT, T1, T2>::deserialize(C, *ValOrErr);
- Error Err = Error::success();
- if (auto E2 = deserializeSeq(C, Err))
- return E2;
- ValOrErr = std::move(Err);
- return Error::success();
- }
-};
-
-/// SerializationTraits for Expected<T1> from a T2.
-template <typename ChannelT, typename T1, typename T2>
-class SerializationTraits<ChannelT, Expected<T1>, T2> {
-public:
- static Error serialize(ChannelT &C, T2 &&Val) {
- return serializeSeq(C, Expected<T2>(std::forward<T2>(Val)));
- }
-};
-
-/// SerializationTraits for Expected<T1> from an Error.
-template <typename ChannelT, typename T>
-class SerializationTraits<ChannelT, Expected<T>, Error> {
-public:
- static Error serialize(ChannelT &C, Error &&Err) {
- return serializeSeq(C, Expected<T>(std::move(Err)));
- }
-};
-
-/// SerializationTraits default specialization for std::pair.
-template <typename ChannelT, typename T1, typename T2, typename T3, typename T4>
-class SerializationTraits<ChannelT, std::pair<T1, T2>, std::pair<T3, T4>> {
-public:
- static Error serialize(ChannelT &C, const std::pair<T3, T4> &V) {
- if (auto Err = SerializationTraits<ChannelT, T1, T3>::serialize(C, V.first))
- return Err;
- return SerializationTraits<ChannelT, T2, T4>::serialize(C, V.second);
- }
-
- static Error deserialize(ChannelT &C, std::pair<T3, T4> &V) {
- if (auto Err =
- SerializationTraits<ChannelT, T1, T3>::deserialize(C, V.first))
- return Err;
- return SerializationTraits<ChannelT, T2, T4>::deserialize(C, V.second);
- }
-};
-
-/// SerializationTraits default specialization for std::tuple.
-template <typename ChannelT, typename... ArgTs>
-class SerializationTraits<ChannelT, std::tuple<ArgTs...>> {
-public:
- /// RPC channel serialization for std::tuple.
- static Error serialize(ChannelT &C, const std::tuple<ArgTs...> &V) {
- return serializeTupleHelper(C, V, std::index_sequence_for<ArgTs...>());
- }
-
- /// RPC channel deserialization for std::tuple.
- static Error deserialize(ChannelT &C, std::tuple<ArgTs...> &V) {
- return deserializeTupleHelper(C, V, std::index_sequence_for<ArgTs...>());
- }
-
-private:
- // Serialization helper for std::tuple.
- template <size_t... Is>
- static Error serializeTupleHelper(ChannelT &C, const std::tuple<ArgTs...> &V,
- std::index_sequence<Is...> _) {
- return serializeSeq(C, std::get<Is>(V)...);
- }
-
- // Serialization helper for std::tuple.
- template <size_t... Is>
- static Error deserializeTupleHelper(ChannelT &C, std::tuple<ArgTs...> &V,
- std::index_sequence<Is...> _) {
- return deserializeSeq(C, std::get<Is>(V)...);
- }
-};
-
-template <typename ChannelT, typename T>
-class SerializationTraits<ChannelT, Optional<T>> {
-public:
- /// Serialize an Optional<T>.
- static Error serialize(ChannelT &C, const Optional<T> &O) {
- if (auto Err = serializeSeq(C, O != None))
- return Err;
- if (O)
- if (auto Err = serializeSeq(C, *O))
- return Err;
- return Error::success();
- }
-
- /// Deserialize an Optional<T>.
- static Error deserialize(ChannelT &C, Optional<T> &O) {
- bool HasValue = false;
- if (auto Err = deserializeSeq(C, HasValue))
- return Err;
- if (HasValue)
- if (auto Err = deserializeSeq(C, *O))
- return Err;
- return Error::success();
- };
-};
-
-/// SerializationTraits default specialization for std::vector.
-template <typename ChannelT, typename T>
-class SerializationTraits<ChannelT, std::vector<T>> {
-public:
- /// Serialize a std::vector<T> from std::vector<T>.
- static Error serialize(ChannelT &C, const std::vector<T> &V) {
- if (auto Err = serializeSeq(C, static_cast<uint64_t>(V.size())))
- return Err;
-
- for (const auto &E : V)
- if (auto Err = serializeSeq(C, E))
- return Err;
-
- return Error::success();
- }
-
- /// Deserialize a std::vector<T> to a std::vector<T>.
- static Error deserialize(ChannelT &C, std::vector<T> &V) {
- assert(V.empty() &&
- "Expected default-constructed vector to deserialize into");
-
- uint64_t Count = 0;
- if (auto Err = deserializeSeq(C, Count))
- return Err;
-
- V.resize(Count);
- for (auto &E : V)
- if (auto Err = deserializeSeq(C, E))
- return Err;
-
- return Error::success();
- }
-};
-
-/// Enable vector serialization from an ArrayRef.
-template <typename ChannelT, typename T>
-class SerializationTraits<ChannelT, std::vector<T>, ArrayRef<T>> {
-public:
- static Error serialize(ChannelT &C, ArrayRef<T> V) {
- if (auto Err = serializeSeq(C, static_cast<uint64_t>(V.size())))
- return Err;
-
- for (const auto &E : V)
- if (auto Err = serializeSeq(C, E))
- return Err;
-
- return Error::success();
- }
-};
-
-template <typename ChannelT, typename T, typename T2>
-class SerializationTraits<ChannelT, std::set<T>, std::set<T2>> {
-public:
- /// Serialize a std::set<T> from std::set<T2>.
- static Error serialize(ChannelT &C, const std::set<T2> &S) {
- if (auto Err = serializeSeq(C, static_cast<uint64_t>(S.size())))
- return Err;
-
- for (const auto &E : S)
- if (auto Err = SerializationTraits<ChannelT, T, T2>::serialize(C, E))
- return Err;
-
- return Error::success();
- }
-
- /// Deserialize a std::set<T> to a std::set<T>.
- static Error deserialize(ChannelT &C, std::set<T2> &S) {
- assert(S.empty() && "Expected default-constructed set to deserialize into");
-
- uint64_t Count = 0;
- if (auto Err = deserializeSeq(C, Count))
- return Err;
-
- while (Count-- != 0) {
- T2 Val;
- if (auto Err = SerializationTraits<ChannelT, T, T2>::deserialize(C, Val))
- return Err;
-
- auto Added = S.insert(Val).second;
- if (!Added)
- return make_error<StringError>("Duplicate element in deserialized set",
- orcError(OrcErrorCode::UnknownORCError));
- }
-
- return Error::success();
- }
-};
-
-template <typename ChannelT, typename K, typename V, typename K2, typename V2>
-class SerializationTraits<ChannelT, std::map<K, V>, std::map<K2, V2>> {
-public:
- /// Serialize a std::map<K, V> from std::map<K2, V2>.
- static Error serialize(ChannelT &C, const std::map<K2, V2> &M) {
- if (auto Err = serializeSeq(C, static_cast<uint64_t>(M.size())))
- return Err;
-
- for (const auto &E : M) {
- if (auto Err =
- SerializationTraits<ChannelT, K, K2>::serialize(C, E.first))
- return Err;
- if (auto Err =
- SerializationTraits<ChannelT, V, V2>::serialize(C, E.second))
- return Err;
- }
-
- return Error::success();
- }
-
- /// Deserialize a std::map<K, V> to a std::map<K, V>.
- static Error deserialize(ChannelT &C, std::map<K2, V2> &M) {
- assert(M.empty() && "Expected default-constructed map to deserialize into");
-
- uint64_t Count = 0;
- if (auto Err = deserializeSeq(C, Count))
- return Err;
-
- while (Count-- != 0) {
- std::pair<K2, V2> Val;
- if (auto Err =
- SerializationTraits<ChannelT, K, K2>::deserialize(C, Val.first))
- return Err;
-
- if (auto Err =
- SerializationTraits<ChannelT, V, V2>::deserialize(C, Val.second))
- return Err;
-
- auto Added = M.insert(Val).second;
- if (!Added)
- return make_error<StringError>("Duplicate element in deserialized map",
- orcError(OrcErrorCode::UnknownORCError));
- }
-
- return Error::success();
- }
-};
-
-template <typename ChannelT, typename K, typename V, typename K2, typename V2>
-class SerializationTraits<ChannelT, std::map<K, V>, DenseMap<K2, V2>> {
-public:
- /// Serialize a std::map<K, V> from DenseMap<K2, V2>.
- static Error serialize(ChannelT &C, const DenseMap<K2, V2> &M) {
- if (auto Err = serializeSeq(C, static_cast<uint64_t>(M.size())))
- return Err;
-
- for (auto &E : M) {
- if (auto Err =
- SerializationTraits<ChannelT, K, K2>::serialize(C, E.first))
- return Err;
-
- if (auto Err =
- SerializationTraits<ChannelT, V, V2>::serialize(C, E.second))
- return Err;
- }
-
- return Error::success();
- }
-
- /// Serialize a std::map<K, V> from DenseMap<K2, V2>.
- static Error deserialize(ChannelT &C, DenseMap<K2, V2> &M) {
- assert(M.empty() && "Expected default-constructed map to deserialize into");
-
- uint64_t Count = 0;
- if (auto Err = deserializeSeq(C, Count))
- return Err;
-
- while (Count-- != 0) {
- std::pair<K2, V2> Val;
- if (auto Err =
- SerializationTraits<ChannelT, K, K2>::deserialize(C, Val.first))
- return Err;
-
- if (auto Err =
- SerializationTraits<ChannelT, V, V2>::deserialize(C, Val.second))
- return Err;
-
- auto Added = M.insert(Val).second;
- if (!Added)
- return make_error<StringError>("Duplicate element in deserialized map",
- orcError(OrcErrorCode::UnknownORCError));
- }
-
- return Error::success();
- }
-};
-
-} // namespace shared
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_RPC_RPCSERIALIZATION_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- Serialization.h ------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_SERIALIZATION_H
+#define LLVM_EXECUTIONENGINE_ORC_SHARED_SERIALIZATION_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
+#include "llvm/Support/thread.h"
+#include <map>
+#include <mutex>
+#include <set>
+#include <sstream>
+#include <string>
+#include <vector>
+
+namespace llvm {
+namespace orc {
+namespace shared {
+
+template <typename T> class SerializationTypeName;
+
+/// TypeNameSequence is a utility for rendering sequences of types to a string
+/// by rendering each type, separated by ", ".
+template <typename... ArgTs> class SerializationTypeNameSequence {};
+
+/// Render an empty TypeNameSequence to an ostream.
+template <typename OStream>
+OStream &operator<<(OStream &OS, const SerializationTypeNameSequence<> &V) {
+ return OS;
+}
+
+/// Render a TypeNameSequence of a single type to an ostream.
+template <typename OStream, typename ArgT>
+OStream &operator<<(OStream &OS, const SerializationTypeNameSequence<ArgT> &V) {
+ OS << SerializationTypeName<ArgT>::getName();
+ return OS;
+}
+
+/// Render a TypeNameSequence of more than one type to an ostream.
+template <typename OStream, typename ArgT1, typename ArgT2, typename... ArgTs>
+OStream &
+operator<<(OStream &OS,
+ const SerializationTypeNameSequence<ArgT1, ArgT2, ArgTs...> &V) {
+ OS << SerializationTypeName<ArgT1>::getName() << ", "
+ << SerializationTypeNameSequence<ArgT2, ArgTs...>();
+ return OS;
+}
+
+template <> class SerializationTypeName<void> {
+public:
+ static const char *getName() { return "void"; }
+};
+
+template <> class SerializationTypeName<int8_t> {
+public:
+ static const char *getName() { return "int8_t"; }
+};
+
+template <> class SerializationTypeName<uint8_t> {
+public:
+ static const char *getName() { return "uint8_t"; }
+};
+
+template <> class SerializationTypeName<int16_t> {
+public:
+ static const char *getName() { return "int16_t"; }
+};
+
+template <> class SerializationTypeName<uint16_t> {
+public:
+ static const char *getName() { return "uint16_t"; }
+};
+
+template <> class SerializationTypeName<int32_t> {
+public:
+ static const char *getName() { return "int32_t"; }
+};
+
+template <> class SerializationTypeName<uint32_t> {
+public:
+ static const char *getName() { return "uint32_t"; }
+};
+
+template <> class SerializationTypeName<int64_t> {
+public:
+ static const char *getName() { return "int64_t"; }
+};
+
+template <> class SerializationTypeName<uint64_t> {
+public:
+ static const char *getName() { return "uint64_t"; }
+};
+
+template <> class SerializationTypeName<bool> {
+public:
+ static const char *getName() { return "bool"; }
+};
+
+template <> class SerializationTypeName<std::string> {
+public:
+ static const char *getName() { return "std::string"; }
+};
+
+template <> class SerializationTypeName<Error> {
+public:
+ static const char *getName() { return "Error"; }
+};
+
+template <typename T> class SerializationTypeName<Expected<T>> {
+public:
+ static const char *getName() {
+ static std::string Name = [] {
+ std::string Name;
+ raw_string_ostream(Name)
+ << "Expected<" << SerializationTypeNameSequence<T>() << ">";
+ return Name;
+ }();
+ return Name.data();
+ }
+};
+
+template <typename T1, typename T2>
+class SerializationTypeName<std::pair<T1, T2>> {
+public:
+ static const char *getName() {
+ static std::string Name = [] {
+ std::string Name;
+ raw_string_ostream(Name)
+ << "std::pair<" << SerializationTypeNameSequence<T1, T2>() << ">";
+ return Name;
+ }();
+ return Name.data();
+ }
+};
+
+template <typename... ArgTs> class SerializationTypeName<std::tuple<ArgTs...>> {
+public:
+ static const char *getName() {
+ static std::string Name = [] {
+ std::string Name;
+ raw_string_ostream(Name)
+ << "std::tuple<" << SerializationTypeNameSequence<ArgTs...>() << ">";
+ return Name;
+ }();
+ return Name.data();
+ }
+};
+
+template <typename T> class SerializationTypeName<Optional<T>> {
+public:
+ static const char *getName() {
+ static std::string Name = [] {
+ std::string Name;
+ raw_string_ostream(Name)
+ << "Optional<" << SerializationTypeName<T>::getName() << ">";
+ return Name;
+ }();
+ return Name.data();
+ }
+};
+
+template <typename T> class SerializationTypeName<std::vector<T>> {
+public:
+ static const char *getName() {
+ static std::string Name = [] {
+ std::string Name;
+ raw_string_ostream(Name)
+ << "std::vector<" << SerializationTypeName<T>::getName() << ">";
+ return Name;
+ }();
+ return Name.data();
+ }
+};
+
+template <typename T> class SerializationTypeName<std::set<T>> {
+public:
+ static const char *getName() {
+ static std::string Name = [] {
+ std::string Name;
+ raw_string_ostream(Name)
+ << "std::set<" << SerializationTypeName<T>::getName() << ">";
+ return Name;
+ }();
+ return Name.data();
+ }
+};
+
+template <typename K, typename V> class SerializationTypeName<std::map<K, V>> {
+public:
+ static const char *getName() {
+ static std::string Name = [] {
+ std::string Name;
+ raw_string_ostream(Name)
+ << "std::map<" << SerializationTypeNameSequence<K, V>() << ">";
+ return Name;
+ }();
+ return Name.data();
+ }
+};
+
+/// The SerializationTraits<ChannelT, T> class describes how to serialize and
+/// deserialize an instance of type T to/from an abstract channel of type
+/// ChannelT. It also provides a representation of the type's name via the
+/// getName method.
+///
+/// Specializations of this class should provide the following functions:
+///
+/// @code{.cpp}
+///
+/// static const char* getName();
+/// static Error serialize(ChannelT&, const T&);
+/// static Error deserialize(ChannelT&, T&);
+///
+/// @endcode
+///
+/// The third argument of SerializationTraits is intended to support SFINAE.
+/// E.g.:
+///
+/// @code{.cpp}
+///
+/// class MyVirtualChannel { ... };
+///
+/// template <DerivedChannelT>
+/// class SerializationTraits<DerivedChannelT, bool,
+/// std::enable_if_t<
+/// std::is_base_of<VirtChannel, DerivedChannel>::value
+/// >> {
+/// public:
+/// static const char* getName() { ... };
+/// }
+///
+/// @endcode
+template <typename ChannelT, typename WireType,
+ typename ConcreteType = WireType, typename = void>
+class SerializationTraits;
+
+template <typename ChannelT> class SequenceTraits {
+public:
+ static Error emitSeparator(ChannelT &C) { return Error::success(); }
+ static Error consumeSeparator(ChannelT &C) { return Error::success(); }
+};
+
+/// Utility class for serializing sequences of values of varying types.
+/// Specializations of this class contain 'serialize' and 'deserialize' methods
+/// for the given channel. The ArgTs... list will determine the "over-the-wire"
+/// types to be serialized. The serialize and deserialize methods take a list
+/// CArgTs... ("caller arg types") which must be the same length as ArgTs...,
+/// but may be different types from ArgTs, provided that for each CArgT there
+/// is a SerializationTraits specialization
+/// SerializeTraits<ChannelT, ArgT, CArgT> with methods that can serialize the
+/// caller argument to over-the-wire value.
+template <typename ChannelT, typename... ArgTs> class SequenceSerialization;
+
+template <typename ChannelT> class SequenceSerialization<ChannelT> {
+public:
+ static Error serialize(ChannelT &C) { return Error::success(); }
+ static Error deserialize(ChannelT &C) { return Error::success(); }
+};
+
+template <typename ChannelT, typename ArgT>
+class SequenceSerialization<ChannelT, ArgT> {
+public:
+ template <typename CArgT> static Error serialize(ChannelT &C, CArgT &&CArg) {
+ return SerializationTraits<ChannelT, ArgT, std::decay_t<CArgT>>::serialize(
+ C, std::forward<CArgT>(CArg));
+ }
+
+ template <typename CArgT> static Error deserialize(ChannelT &C, CArgT &CArg) {
+ return SerializationTraits<ChannelT, ArgT, CArgT>::deserialize(C, CArg);
+ }
+};
+
+template <typename ChannelT, typename ArgT, typename... ArgTs>
+class SequenceSerialization<ChannelT, ArgT, ArgTs...> {
+public:
+ template <typename CArgT, typename... CArgTs>
+ static Error serialize(ChannelT &C, CArgT &&CArg, CArgTs &&...CArgs) {
+ if (auto Err =
+ SerializationTraits<ChannelT, ArgT, std::decay_t<CArgT>>::serialize(
+ C, std::forward<CArgT>(CArg)))
+ return Err;
+ if (auto Err = SequenceTraits<ChannelT>::emitSeparator(C))
+ return Err;
+ return SequenceSerialization<ChannelT, ArgTs...>::serialize(
+ C, std::forward<CArgTs>(CArgs)...);
+ }
+
+ template <typename CArgT, typename... CArgTs>
+ static Error deserialize(ChannelT &C, CArgT &CArg, CArgTs &...CArgs) {
+ if (auto Err =
+ SerializationTraits<ChannelT, ArgT, CArgT>::deserialize(C, CArg))
+ return Err;
+ if (auto Err = SequenceTraits<ChannelT>::consumeSeparator(C))
+ return Err;
+ return SequenceSerialization<ChannelT, ArgTs...>::deserialize(C, CArgs...);
+ }
+};
+
+template <typename ChannelT, typename... ArgTs>
+Error serializeSeq(ChannelT &C, ArgTs &&...Args) {
+ return SequenceSerialization<ChannelT, std::decay_t<ArgTs>...>::serialize(
+ C, std::forward<ArgTs>(Args)...);
+}
+
+template <typename ChannelT, typename... ArgTs>
+Error deserializeSeq(ChannelT &C, ArgTs &...Args) {
+ return SequenceSerialization<ChannelT, ArgTs...>::deserialize(C, Args...);
+}
+
+template <typename ChannelT> class SerializationTraits<ChannelT, Error> {
+public:
+ using WrappedErrorSerializer =
+ std::function<Error(ChannelT &C, const ErrorInfoBase &)>;
+
+ using WrappedErrorDeserializer =
+ std::function<Error(ChannelT &C, Error &Err)>;
+
+ template <typename ErrorInfoT, typename SerializeFtor,
+ typename DeserializeFtor>
+ static void registerErrorType(std::string Name, SerializeFtor Serialize,
+ DeserializeFtor Deserialize) {
+ assert(!Name.empty() &&
+ "The empty string is reserved for the Success value");
+
+ const std::string *KeyName = nullptr;
+ {
+ // We're abusing the stability of std::map here: We take a reference to
+ // the key of the deserializers map to save us from duplicating the string
+ // in the serializer. This should be changed to use a stringpool if we
+ // switch to a map type that may move keys in memory.
+ std::lock_guard<std::recursive_mutex> Lock(DeserializersMutex);
+ auto I = Deserializers.insert(
+ Deserializers.begin(),
+ std::make_pair(std::move(Name), std::move(Deserialize)));
+ KeyName = &I->first;
+ }
+
+ {
+ assert(KeyName != nullptr && "No keyname pointer");
+ std::lock_guard<std::recursive_mutex> Lock(SerializersMutex);
+ Serializers[ErrorInfoT::classID()] =
+ [KeyName, Serialize = std::move(Serialize)](
+ ChannelT &C, const ErrorInfoBase &EIB) -> Error {
+ assert(EIB.dynamicClassID() == ErrorInfoT::classID() &&
+ "Serializer called for wrong error type");
+ if (auto Err = serializeSeq(C, *KeyName))
+ return Err;
+ return Serialize(C, static_cast<const ErrorInfoT &>(EIB));
+ };
+ }
+ }
+
+ static Error serialize(ChannelT &C, Error &&Err) {
+ std::lock_guard<std::recursive_mutex> Lock(SerializersMutex);
+
+ if (!Err)
+ return serializeSeq(C, std::string());
+
+ return handleErrors(std::move(Err), [&C](const ErrorInfoBase &EIB) {
+ auto SI = Serializers.find(EIB.dynamicClassID());
+ if (SI == Serializers.end())
+ return serializeAsStringError(C, EIB);
+ return (SI->second)(C, EIB);
+ });
+ }
+
+ static Error deserialize(ChannelT &C, Error &Err) {
+ std::lock_guard<std::recursive_mutex> Lock(DeserializersMutex);
+
+ std::string Key;
+ if (auto Err = deserializeSeq(C, Key))
+ return Err;
+
+ if (Key.empty()) {
+ ErrorAsOutParameter EAO(&Err);
+ Err = Error::success();
+ return Error::success();
+ }
+
+ auto DI = Deserializers.find(Key);
+ assert(DI != Deserializers.end() && "No deserializer for error type");
+ return (DI->second)(C, Err);
+ }
+
+private:
+ static Error serializeAsStringError(ChannelT &C, const ErrorInfoBase &EIB) {
+ std::string ErrMsg;
+ {
+ raw_string_ostream ErrMsgStream(ErrMsg);
+ EIB.log(ErrMsgStream);
+ }
+ return serialize(C, make_error<StringError>(std::move(ErrMsg),
+ inconvertibleErrorCode()));
+ }
+
+ static std::recursive_mutex SerializersMutex;
+ static std::recursive_mutex DeserializersMutex;
+ static std::map<const void *, WrappedErrorSerializer> Serializers;
+ static std::map<std::string, WrappedErrorDeserializer> Deserializers;
+};
+
+template <typename ChannelT>
+std::recursive_mutex SerializationTraits<ChannelT, Error>::SerializersMutex;
+
+template <typename ChannelT>
+std::recursive_mutex SerializationTraits<ChannelT, Error>::DeserializersMutex;
+
+template <typename ChannelT>
+std::map<const void *,
+ typename SerializationTraits<ChannelT, Error>::WrappedErrorSerializer>
+ SerializationTraits<ChannelT, Error>::Serializers;
+
+template <typename ChannelT>
+std::map<std::string, typename SerializationTraits<
+ ChannelT, Error>::WrappedErrorDeserializer>
+ SerializationTraits<ChannelT, Error>::Deserializers;
+
+/// Registers a serializer and deserializer for the given error type on the
+/// given channel type.
+template <typename ChannelT, typename ErrorInfoT, typename SerializeFtor,
+ typename DeserializeFtor>
+void registerErrorSerialization(std::string Name, SerializeFtor &&Serialize,
+ DeserializeFtor &&Deserialize) {
+ SerializationTraits<ChannelT, Error>::template registerErrorType<ErrorInfoT>(
+ std::move(Name), std::forward<SerializeFtor>(Serialize),
+ std::forward<DeserializeFtor>(Deserialize));
+}
+
+/// Registers serialization/deserialization for StringError.
+template <typename ChannelT> void registerStringError() {
+ static bool AlreadyRegistered = false;
+ if (!AlreadyRegistered) {
+ registerErrorSerialization<ChannelT, StringError>(
+ "StringError",
+ [](ChannelT &C, const StringError &SE) {
+ return serializeSeq(C, SE.getMessage());
+ },
+ [](ChannelT &C, Error &Err) -> Error {
+ ErrorAsOutParameter EAO(&Err);
+ std::string Msg;
+ if (auto E2 = deserializeSeq(C, Msg))
+ return E2;
+ Err = make_error<StringError>(
+ std::move(Msg),
+ orcError(OrcErrorCode::UnknownErrorCodeFromRemote));
+ return Error::success();
+ });
+ AlreadyRegistered = true;
+ }
+}
+
+/// SerializationTraits for Expected<T1> from an Expected<T2>.
+template <typename ChannelT, typename T1, typename T2>
+class SerializationTraits<ChannelT, Expected<T1>, Expected<T2>> {
+public:
+ static Error serialize(ChannelT &C, Expected<T2> &&ValOrErr) {
+ if (ValOrErr) {
+ if (auto Err = serializeSeq(C, true))
+ return Err;
+ return SerializationTraits<ChannelT, T1, T2>::serialize(C, *ValOrErr);
+ }
+ if (auto Err = serializeSeq(C, false))
+ return Err;
+ return serializeSeq(C, ValOrErr.takeError());
+ }
+
+ static Error deserialize(ChannelT &C, Expected<T2> &ValOrErr) {
+ ExpectedAsOutParameter<T2> EAO(&ValOrErr);
+ bool HasValue;
+ if (auto Err = deserializeSeq(C, HasValue))
+ return Err;
+ if (HasValue)
+ return SerializationTraits<ChannelT, T1, T2>::deserialize(C, *ValOrErr);
+ Error Err = Error::success();
+ if (auto E2 = deserializeSeq(C, Err))
+ return E2;
+ ValOrErr = std::move(Err);
+ return Error::success();
+ }
+};
+
+/// SerializationTraits for Expected<T1> from a T2.
+template <typename ChannelT, typename T1, typename T2>
+class SerializationTraits<ChannelT, Expected<T1>, T2> {
+public:
+ static Error serialize(ChannelT &C, T2 &&Val) {
+ return serializeSeq(C, Expected<T2>(std::forward<T2>(Val)));
+ }
+};
+
+/// SerializationTraits for Expected<T1> from an Error.
+template <typename ChannelT, typename T>
+class SerializationTraits<ChannelT, Expected<T>, Error> {
+public:
+ static Error serialize(ChannelT &C, Error &&Err) {
+ return serializeSeq(C, Expected<T>(std::move(Err)));
+ }
+};
+
+/// SerializationTraits default specialization for std::pair.
+template <typename ChannelT, typename T1, typename T2, typename T3, typename T4>
+class SerializationTraits<ChannelT, std::pair<T1, T2>, std::pair<T3, T4>> {
+public:
+ static Error serialize(ChannelT &C, const std::pair<T3, T4> &V) {
+ if (auto Err = SerializationTraits<ChannelT, T1, T3>::serialize(C, V.first))
+ return Err;
+ return SerializationTraits<ChannelT, T2, T4>::serialize(C, V.second);
+ }
+
+ static Error deserialize(ChannelT &C, std::pair<T3, T4> &V) {
+ if (auto Err =
+ SerializationTraits<ChannelT, T1, T3>::deserialize(C, V.first))
+ return Err;
+ return SerializationTraits<ChannelT, T2, T4>::deserialize(C, V.second);
+ }
+};
+
+/// SerializationTraits default specialization for std::tuple.
+template <typename ChannelT, typename... ArgTs>
+class SerializationTraits<ChannelT, std::tuple<ArgTs...>> {
+public:
+ /// RPC channel serialization for std::tuple.
+ static Error serialize(ChannelT &C, const std::tuple<ArgTs...> &V) {
+ return serializeTupleHelper(C, V, std::index_sequence_for<ArgTs...>());
+ }
+
+ /// RPC channel deserialization for std::tuple.
+ static Error deserialize(ChannelT &C, std::tuple<ArgTs...> &V) {
+ return deserializeTupleHelper(C, V, std::index_sequence_for<ArgTs...>());
+ }
+
+private:
+ // Serialization helper for std::tuple.
+ template <size_t... Is>
+ static Error serializeTupleHelper(ChannelT &C, const std::tuple<ArgTs...> &V,
+ std::index_sequence<Is...> _) {
+ return serializeSeq(C, std::get<Is>(V)...);
+ }
+
+ // Serialization helper for std::tuple.
+ template <size_t... Is>
+ static Error deserializeTupleHelper(ChannelT &C, std::tuple<ArgTs...> &V,
+ std::index_sequence<Is...> _) {
+ return deserializeSeq(C, std::get<Is>(V)...);
+ }
+};
+
+template <typename ChannelT, typename T>
+class SerializationTraits<ChannelT, Optional<T>> {
+public:
+ /// Serialize an Optional<T>.
+ static Error serialize(ChannelT &C, const Optional<T> &O) {
+ if (auto Err = serializeSeq(C, O != None))
+ return Err;
+ if (O)
+ if (auto Err = serializeSeq(C, *O))
+ return Err;
+ return Error::success();
+ }
+
+ /// Deserialize an Optional<T>.
+ static Error deserialize(ChannelT &C, Optional<T> &O) {
+ bool HasValue = false;
+ if (auto Err = deserializeSeq(C, HasValue))
+ return Err;
+ if (HasValue)
+ if (auto Err = deserializeSeq(C, *O))
+ return Err;
+ return Error::success();
+ };
+};
+
+/// SerializationTraits default specialization for std::vector.
+template <typename ChannelT, typename T>
+class SerializationTraits<ChannelT, std::vector<T>> {
+public:
+ /// Serialize a std::vector<T> from std::vector<T>.
+ static Error serialize(ChannelT &C, const std::vector<T> &V) {
+ if (auto Err = serializeSeq(C, static_cast<uint64_t>(V.size())))
+ return Err;
+
+ for (const auto &E : V)
+ if (auto Err = serializeSeq(C, E))
+ return Err;
+
+ return Error::success();
+ }
+
+ /// Deserialize a std::vector<T> to a std::vector<T>.
+ static Error deserialize(ChannelT &C, std::vector<T> &V) {
+ assert(V.empty() &&
+ "Expected default-constructed vector to deserialize into");
+
+ uint64_t Count = 0;
+ if (auto Err = deserializeSeq(C, Count))
+ return Err;
+
+ V.resize(Count);
+ for (auto &E : V)
+ if (auto Err = deserializeSeq(C, E))
+ return Err;
+
+ return Error::success();
+ }
+};
+
+/// Enable vector serialization from an ArrayRef.
+template <typename ChannelT, typename T>
+class SerializationTraits<ChannelT, std::vector<T>, ArrayRef<T>> {
+public:
+ static Error serialize(ChannelT &C, ArrayRef<T> V) {
+ if (auto Err = serializeSeq(C, static_cast<uint64_t>(V.size())))
+ return Err;
+
+ for (const auto &E : V)
+ if (auto Err = serializeSeq(C, E))
+ return Err;
+
+ return Error::success();
+ }
+};
+
+template <typename ChannelT, typename T, typename T2>
+class SerializationTraits<ChannelT, std::set<T>, std::set<T2>> {
+public:
+ /// Serialize a std::set<T> from std::set<T2>.
+ static Error serialize(ChannelT &C, const std::set<T2> &S) {
+ if (auto Err = serializeSeq(C, static_cast<uint64_t>(S.size())))
+ return Err;
+
+ for (const auto &E : S)
+ if (auto Err = SerializationTraits<ChannelT, T, T2>::serialize(C, E))
+ return Err;
+
+ return Error::success();
+ }
+
+ /// Deserialize a std::set<T> to a std::set<T>.
+ static Error deserialize(ChannelT &C, std::set<T2> &S) {
+ assert(S.empty() && "Expected default-constructed set to deserialize into");
+
+ uint64_t Count = 0;
+ if (auto Err = deserializeSeq(C, Count))
+ return Err;
+
+ while (Count-- != 0) {
+ T2 Val;
+ if (auto Err = SerializationTraits<ChannelT, T, T2>::deserialize(C, Val))
+ return Err;
+
+ auto Added = S.insert(Val).second;
+ if (!Added)
+ return make_error<StringError>("Duplicate element in deserialized set",
+ orcError(OrcErrorCode::UnknownORCError));
+ }
+
+ return Error::success();
+ }
+};
+
+template <typename ChannelT, typename K, typename V, typename K2, typename V2>
+class SerializationTraits<ChannelT, std::map<K, V>, std::map<K2, V2>> {
+public:
+ /// Serialize a std::map<K, V> from std::map<K2, V2>.
+ static Error serialize(ChannelT &C, const std::map<K2, V2> &M) {
+ if (auto Err = serializeSeq(C, static_cast<uint64_t>(M.size())))
+ return Err;
+
+ for (const auto &E : M) {
+ if (auto Err =
+ SerializationTraits<ChannelT, K, K2>::serialize(C, E.first))
+ return Err;
+ if (auto Err =
+ SerializationTraits<ChannelT, V, V2>::serialize(C, E.second))
+ return Err;
+ }
+
+ return Error::success();
+ }
+
+ /// Deserialize a std::map<K, V> to a std::map<K, V>.
+ static Error deserialize(ChannelT &C, std::map<K2, V2> &M) {
+ assert(M.empty() && "Expected default-constructed map to deserialize into");
+
+ uint64_t Count = 0;
+ if (auto Err = deserializeSeq(C, Count))
+ return Err;
+
+ while (Count-- != 0) {
+ std::pair<K2, V2> Val;
+ if (auto Err =
+ SerializationTraits<ChannelT, K, K2>::deserialize(C, Val.first))
+ return Err;
+
+ if (auto Err =
+ SerializationTraits<ChannelT, V, V2>::deserialize(C, Val.second))
+ return Err;
+
+ auto Added = M.insert(Val).second;
+ if (!Added)
+ return make_error<StringError>("Duplicate element in deserialized map",
+ orcError(OrcErrorCode::UnknownORCError));
+ }
+
+ return Error::success();
+ }
+};
+
+template <typename ChannelT, typename K, typename V, typename K2, typename V2>
+class SerializationTraits<ChannelT, std::map<K, V>, DenseMap<K2, V2>> {
+public:
+ /// Serialize a std::map<K, V> from DenseMap<K2, V2>.
+ static Error serialize(ChannelT &C, const DenseMap<K2, V2> &M) {
+ if (auto Err = serializeSeq(C, static_cast<uint64_t>(M.size())))
+ return Err;
+
+ for (auto &E : M) {
+ if (auto Err =
+ SerializationTraits<ChannelT, K, K2>::serialize(C, E.first))
+ return Err;
+
+ if (auto Err =
+ SerializationTraits<ChannelT, V, V2>::serialize(C, E.second))
+ return Err;
+ }
+
+ return Error::success();
+ }
+
+ /// Serialize a std::map<K, V> from DenseMap<K2, V2>.
+ static Error deserialize(ChannelT &C, DenseMap<K2, V2> &M) {
+ assert(M.empty() && "Expected default-constructed map to deserialize into");
+
+ uint64_t Count = 0;
+ if (auto Err = deserializeSeq(C, Count))
+ return Err;
+
+ while (Count-- != 0) {
+ std::pair<K2, V2> Val;
+ if (auto Err =
+ SerializationTraits<ChannelT, K, K2>::deserialize(C, Val.first))
+ return Err;
+
+ if (auto Err =
+ SerializationTraits<ChannelT, V, V2>::deserialize(C, Val.second))
+ return Err;
+
+ auto Added = M.insert(Val).second;
+ if (!Added)
+ return make_error<StringError>("Duplicate element in deserialized map",
+ orcError(OrcErrorCode::UnknownORCError));
+ }
+
+ return Error::success();
+ }
+};
+
+} // namespace shared
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_RPC_RPCSERIALIZATION_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h
index 9fc8dfaead..c3dce579d7 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h
@@ -1,176 +1,176 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===--- TargetProcessControlTypes.h -- Shared Core/TPC types ---*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// TargetProcessControl types that are used by both the Orc and
-// OrcTargetProcess libraries.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H
-#define LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ExecutionEngine/JITSymbol.h"
-
-#include <vector>
-
-namespace llvm {
-namespace orc {
-namespace tpctypes {
-
-template <typename T> struct UIntWrite {
- UIntWrite() = default;
- UIntWrite(JITTargetAddress Address, T Value)
- : Address(Address), Value(Value) {}
-
- JITTargetAddress Address = 0;
- T Value = 0;
-};
-
-/// Describes a write to a uint8_t.
-using UInt8Write = UIntWrite<uint8_t>;
-
-/// Describes a write to a uint16_t.
-using UInt16Write = UIntWrite<uint16_t>;
-
-/// Describes a write to a uint32_t.
-using UInt32Write = UIntWrite<uint32_t>;
-
-/// Describes a write to a uint64_t.
-using UInt64Write = UIntWrite<uint64_t>;
-
-/// Describes a write to a buffer.
-/// For use with TargetProcessControl::MemoryAccess objects.
-struct BufferWrite {
- BufferWrite() = default;
- BufferWrite(JITTargetAddress Address, StringRef Buffer)
- : Address(Address), Buffer(Buffer) {}
-
- JITTargetAddress Address = 0;
- StringRef Buffer;
-};
-
-/// A handle used to represent a loaded dylib in the target process.
-using DylibHandle = JITTargetAddress;
-
-using LookupResult = std::vector<JITTargetAddress>;
-
-/// Either a uint8_t array or a uint8_t*.
-union CWrapperFunctionResultData {
- uint8_t Value[8];
- uint8_t *ValuePtr;
-};
-
-/// C ABI compatible wrapper function result.
-///
-/// This can be safely returned from extern "C" functions, but should be used
-/// to construct a WrapperFunctionResult for safety.
-struct CWrapperFunctionResult {
- uint64_t Size;
- CWrapperFunctionResultData Data;
- void (*Destroy)(CWrapperFunctionResultData Data, uint64_t Size);
-};
-
-/// C++ wrapper function result: Same as CWrapperFunctionResult but
-/// auto-releases memory.
-class WrapperFunctionResult {
-public:
- /// Create a default WrapperFunctionResult.
- WrapperFunctionResult() { zeroInit(R); }
-
- /// Create a WrapperFunctionResult from a CWrapperFunctionResult. This
- /// instance takes ownership of the result object and will automatically
- /// call the Destroy member upon destruction.
- WrapperFunctionResult(CWrapperFunctionResult R) : R(R) {}
-
- WrapperFunctionResult(const WrapperFunctionResult &) = delete;
- WrapperFunctionResult &operator=(const WrapperFunctionResult &) = delete;
-
- WrapperFunctionResult(WrapperFunctionResult &&Other) {
- zeroInit(R);
- std::swap(R, Other.R);
- }
-
- WrapperFunctionResult &operator=(WrapperFunctionResult &&Other) {
- CWrapperFunctionResult Tmp;
- zeroInit(Tmp);
- std::swap(Tmp, Other.R);
- std::swap(R, Tmp);
- return *this;
- }
-
- ~WrapperFunctionResult() {
- if (R.Destroy)
- R.Destroy(R.Data, R.Size);
- }
-
- /// Relinquish ownership of and return the CWrapperFunctionResult.
- CWrapperFunctionResult release() {
- CWrapperFunctionResult Tmp;
- zeroInit(Tmp);
- std::swap(R, Tmp);
- return Tmp;
- }
-
- /// Get an ArrayRef covering the data in the result.
- ArrayRef<uint8_t> getData() const {
- if (R.Size <= 8)
- return ArrayRef<uint8_t>(R.Data.Value, R.Size);
- return ArrayRef<uint8_t>(R.Data.ValuePtr, R.Size);
- }
-
- /// Create a WrapperFunctionResult from the given integer, provided its
- /// size is no greater than 64 bits.
- template <typename T,
- typename _ = std::enable_if_t<std::is_integral<T>::value &&
- sizeof(T) <= sizeof(uint64_t)>>
- static WrapperFunctionResult from(T Value) {
- CWrapperFunctionResult R;
- R.Size = sizeof(T);
- memcpy(&R.Data.Value, Value, R.Size);
- R.Destroy = nullptr;
- return R;
- }
-
- /// Create a WrapperFunctionResult from the given string.
- static WrapperFunctionResult from(StringRef S);
-
- /// Always free Data.ValuePtr by calling free on it.
- static void destroyWithFree(CWrapperFunctionResultData Data, uint64_t Size);
-
- /// Always free Data.ValuePtr by calling delete[] on it.
- static void destroyWithDeleteArray(CWrapperFunctionResultData Data,
- uint64_t Size);
-
-private:
- static void zeroInit(CWrapperFunctionResult &R) {
- R.Size = 0;
- R.Data.ValuePtr = nullptr;
- R.Destroy = nullptr;
- }
-
- CWrapperFunctionResult R;
-};
-
-} // end namespace tpctypes
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===--- TargetProcessControlTypes.h -- Shared Core/TPC types ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// TargetProcessControl types that are used by both the Orc and
+// OrcTargetProcess libraries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H
+#define LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/JITSymbol.h"
+
+#include <vector>
+
+namespace llvm {
+namespace orc {
+namespace tpctypes {
+
+template <typename T> struct UIntWrite {
+ UIntWrite() = default;
+ UIntWrite(JITTargetAddress Address, T Value)
+ : Address(Address), Value(Value) {}
+
+ JITTargetAddress Address = 0;
+ T Value = 0;
+};
+
+/// Describes a write to a uint8_t.
+using UInt8Write = UIntWrite<uint8_t>;
+
+/// Describes a write to a uint16_t.
+using UInt16Write = UIntWrite<uint16_t>;
+
+/// Describes a write to a uint32_t.
+using UInt32Write = UIntWrite<uint32_t>;
+
+/// Describes a write to a uint64_t.
+using UInt64Write = UIntWrite<uint64_t>;
+
+/// Describes a write to a buffer.
+/// For use with TargetProcessControl::MemoryAccess objects.
+struct BufferWrite {
+ BufferWrite() = default;
+ BufferWrite(JITTargetAddress Address, StringRef Buffer)
+ : Address(Address), Buffer(Buffer) {}
+
+ JITTargetAddress Address = 0;
+ StringRef Buffer;
+};
+
+/// A handle used to represent a loaded dylib in the target process.
+using DylibHandle = JITTargetAddress;
+
+using LookupResult = std::vector<JITTargetAddress>;
+
+/// Either a uint8_t array or a uint8_t*.
+union CWrapperFunctionResultData {
+ uint8_t Value[8];
+ uint8_t *ValuePtr;
+};
+
+/// C ABI compatible wrapper function result.
+///
+/// This can be safely returned from extern "C" functions, but should be used
+/// to construct a WrapperFunctionResult for safety.
+struct CWrapperFunctionResult {
+ uint64_t Size;
+ CWrapperFunctionResultData Data;
+ void (*Destroy)(CWrapperFunctionResultData Data, uint64_t Size);
+};
+
+/// C++ wrapper function result: Same as CWrapperFunctionResult but
+/// auto-releases memory.
+class WrapperFunctionResult {
+public:
+ /// Create a default WrapperFunctionResult.
+ WrapperFunctionResult() { zeroInit(R); }
+
+ /// Create a WrapperFunctionResult from a CWrapperFunctionResult. This
+ /// instance takes ownership of the result object and will automatically
+ /// call the Destroy member upon destruction.
+ WrapperFunctionResult(CWrapperFunctionResult R) : R(R) {}
+
+ WrapperFunctionResult(const WrapperFunctionResult &) = delete;
+ WrapperFunctionResult &operator=(const WrapperFunctionResult &) = delete;
+
+ WrapperFunctionResult(WrapperFunctionResult &&Other) {
+ zeroInit(R);
+ std::swap(R, Other.R);
+ }
+
+ WrapperFunctionResult &operator=(WrapperFunctionResult &&Other) {
+ CWrapperFunctionResult Tmp;
+ zeroInit(Tmp);
+ std::swap(Tmp, Other.R);
+ std::swap(R, Tmp);
+ return *this;
+ }
+
+ ~WrapperFunctionResult() {
+ if (R.Destroy)
+ R.Destroy(R.Data, R.Size);
+ }
+
+ /// Relinquish ownership of and return the CWrapperFunctionResult.
+ CWrapperFunctionResult release() {
+ CWrapperFunctionResult Tmp;
+ zeroInit(Tmp);
+ std::swap(R, Tmp);
+ return Tmp;
+ }
+
+ /// Get an ArrayRef covering the data in the result.
+ ArrayRef<uint8_t> getData() const {
+ if (R.Size <= 8)
+ return ArrayRef<uint8_t>(R.Data.Value, R.Size);
+ return ArrayRef<uint8_t>(R.Data.ValuePtr, R.Size);
+ }
+
+ /// Create a WrapperFunctionResult from the given integer, provided its
+ /// size is no greater than 64 bits.
+ template <typename T,
+ typename _ = std::enable_if_t<std::is_integral<T>::value &&
+ sizeof(T) <= sizeof(uint64_t)>>
+ static WrapperFunctionResult from(T Value) {
+ CWrapperFunctionResult R;
+ R.Size = sizeof(T);
+ memcpy(&R.Data.Value, Value, R.Size);
+ R.Destroy = nullptr;
+ return R;
+ }
+
+ /// Create a WrapperFunctionResult from the given string.
+ static WrapperFunctionResult from(StringRef S);
+
+ /// Always free Data.ValuePtr by calling free on it.
+ static void destroyWithFree(CWrapperFunctionResultData Data, uint64_t Size);
+
+ /// Always free Data.ValuePtr by calling delete[] on it.
+ static void destroyWithDeleteArray(CWrapperFunctionResultData Data,
+ uint64_t Size);
+
+private:
+ static void zeroInit(CWrapperFunctionResult &R) {
+ R.Size = 0;
+ R.Data.ValuePtr = nullptr;
+ R.Destroy = nullptr;
+ }
+
+ CWrapperFunctionResult R;
+};
+
+} // end namespace tpctypes
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Speculation.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Speculation.h
index b2b091fb89..f4193ff075 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Speculation.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/Speculation.h
@@ -188,8 +188,8 @@ public:
: IRLayer(ES, BaseLayer.getManglingOptions()), NextLayer(BaseLayer),
S(Spec), Mangle(Mangle), QueryAnalysis(Interpreter) {}
- void emit(std::unique_ptr<MaterializationResponsibility> R,
- ThreadSafeModule TSM) override;
+ void emit(std::unique_ptr<MaterializationResponsibility> R,
+ ThreadSafeModule TSM) override;
private:
TargetAndLikelies
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h
index 95d3c02a54..8ef5804bf6 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h
@@ -1,77 +1,77 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===------------ TPCDynamicLibrarySearchGenerator.h ------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Support loading and searching of dynamic libraries in a target process via
-// the TargetProcessControl class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H
-#define LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H
-
-#include "llvm/ADT/FunctionExtras.h"
-#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
-
-namespace llvm {
-namespace orc {
-
-class TPCDynamicLibrarySearchGenerator : public DefinitionGenerator {
-public:
- using SymbolPredicate = unique_function<bool(const SymbolStringPtr &)>;
-
- /// Create a DynamicLibrarySearchGenerator that searches for symbols in the
- /// library with the given handle.
- ///
- /// If the Allow predicate is given then only symbols matching the predicate
- /// will be searched for. If the predicate is not given then all symbols will
- /// be searched for.
- TPCDynamicLibrarySearchGenerator(TargetProcessControl &TPC,
- tpctypes::DylibHandle H,
- SymbolPredicate Allow = SymbolPredicate())
- : TPC(TPC), H(H), Allow(std::move(Allow)) {}
-
- /// Permanently loads the library at the given path and, on success, returns
- /// a DynamicLibrarySearchGenerator that will search it for symbol definitions
- /// in the library. On failure returns the reason the library failed to load.
- static Expected<std::unique_ptr<TPCDynamicLibrarySearchGenerator>>
- Load(TargetProcessControl &TPC, const char *LibraryPath,
- SymbolPredicate Allow = SymbolPredicate());
-
- /// Creates a TPCDynamicLibrarySearchGenerator that searches for symbols in
- /// the target process.
- static Expected<std::unique_ptr<TPCDynamicLibrarySearchGenerator>>
- GetForTargetProcess(TargetProcessControl &TPC,
- SymbolPredicate Allow = SymbolPredicate()) {
- return Load(TPC, nullptr, std::move(Allow));
- }
-
- Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
- JITDylibLookupFlags JDLookupFlags,
- const SymbolLookupSet &Symbols) override;
-
-private:
- TargetProcessControl &TPC;
- tpctypes::DylibHandle H;
- SymbolPredicate Allow;
-};
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===------------ TPCDynamicLibrarySearchGenerator.h ------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Support loading and searching of dynamic libraries in a target process via
+// the TargetProcessControl class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H
+#define LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H
+
+#include "llvm/ADT/FunctionExtras.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
+
+namespace llvm {
+namespace orc {
+
+class TPCDynamicLibrarySearchGenerator : public DefinitionGenerator {
+public:
+ using SymbolPredicate = unique_function<bool(const SymbolStringPtr &)>;
+
+ /// Create a DynamicLibrarySearchGenerator that searches for symbols in the
+ /// library with the given handle.
+ ///
+ /// If the Allow predicate is given then only symbols matching the predicate
+ /// will be searched for. If the predicate is not given then all symbols will
+ /// be searched for.
+ TPCDynamicLibrarySearchGenerator(TargetProcessControl &TPC,
+ tpctypes::DylibHandle H,
+ SymbolPredicate Allow = SymbolPredicate())
+ : TPC(TPC), H(H), Allow(std::move(Allow)) {}
+
+ /// Permanently loads the library at the given path and, on success, returns
+ /// a DynamicLibrarySearchGenerator that will search it for symbol definitions
+ /// in the library. On failure returns the reason the library failed to load.
+ static Expected<std::unique_ptr<TPCDynamicLibrarySearchGenerator>>
+ Load(TargetProcessControl &TPC, const char *LibraryPath,
+ SymbolPredicate Allow = SymbolPredicate());
+
+ /// Creates a TPCDynamicLibrarySearchGenerator that searches for symbols in
+ /// the target process.
+ static Expected<std::unique_ptr<TPCDynamicLibrarySearchGenerator>>
+ GetForTargetProcess(TargetProcessControl &TPC,
+ SymbolPredicate Allow = SymbolPredicate()) {
+ return Load(TPC, nullptr, std::move(Allow));
+ }
+
+ Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
+ JITDylibLookupFlags JDLookupFlags,
+ const SymbolLookupSet &Symbols) override;
+
+private:
+ TargetProcessControl &TPC;
+ tpctypes::DylibHandle H;
+ SymbolPredicate Allow;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TPCEHFrameRegistrar.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TPCEHFrameRegistrar.h
index 9f9eb8420b..15716d9ff0 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TPCEHFrameRegistrar.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TPCEHFrameRegistrar.h
@@ -1,65 +1,65 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===-- TPCEHFrameRegistrar.h - TPC based eh-frame registration -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// TargetProcessControl based eh-frame registration.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_TPCEHFRAMEREGISTRAR_H
-#define LLVM_EXECUTIONENGINE_ORC_TPCEHFRAMEREGISTRAR_H
-
-#include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"
-#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
-
-namespace llvm {
-namespace orc {
-
-/// Register/Deregisters EH frames in a remote process via a
-/// TargetProcessControl instance.
-class TPCEHFrameRegistrar : public jitlink::EHFrameRegistrar {
-public:
- /// Create from a TargetProcessControl instance alone. This will use
- /// the TPC's lookupSymbols method to find the registration/deregistration
- /// funciton addresses by name.
- static Expected<std::unique_ptr<TPCEHFrameRegistrar>>
- Create(TargetProcessControl &TPC);
-
- /// Create a TPCEHFrameRegistrar with the given TargetProcessControl
- /// object and registration/deregistration function addresses.
- TPCEHFrameRegistrar(TargetProcessControl &TPC,
- JITTargetAddress RegisterEHFrameWrapperFnAddr,
- JITTargetAddress DeregisterEHFRameWrapperFnAddr)
- : TPC(TPC), RegisterEHFrameWrapperFnAddr(RegisterEHFrameWrapperFnAddr),
- DeregisterEHFrameWrapperFnAddr(DeregisterEHFRameWrapperFnAddr) {}
-
- Error registerEHFrames(JITTargetAddress EHFrameSectionAddr,
- size_t EHFrameSectionSize) override;
- Error deregisterEHFrames(JITTargetAddress EHFrameSectionAddr,
- size_t EHFrameSectionSize) override;
-
-private:
- TargetProcessControl &TPC;
- JITTargetAddress RegisterEHFrameWrapperFnAddr;
- JITTargetAddress DeregisterEHFrameWrapperFnAddr;
-};
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_TPCEHFRAMEREGISTRAR_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===-- TPCEHFrameRegistrar.h - TPC based eh-frame registration -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// TargetProcessControl based eh-frame registration.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TPCEHFRAMEREGISTRAR_H
+#define LLVM_EXECUTIONENGINE_ORC_TPCEHFRAMEREGISTRAR_H
+
+#include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
+
+namespace llvm {
+namespace orc {
+
+/// Register/Deregisters EH frames in a remote process via a
+/// TargetProcessControl instance.
+class TPCEHFrameRegistrar : public jitlink::EHFrameRegistrar {
+public:
+ /// Create from a TargetProcessControl instance alone. This will use
+ /// the TPC's lookupSymbols method to find the registration/deregistration
+ /// funciton addresses by name.
+ static Expected<std::unique_ptr<TPCEHFrameRegistrar>>
+ Create(TargetProcessControl &TPC);
+
+ /// Create a TPCEHFrameRegistrar with the given TargetProcessControl
+ /// object and registration/deregistration function addresses.
+ TPCEHFrameRegistrar(TargetProcessControl &TPC,
+ JITTargetAddress RegisterEHFrameWrapperFnAddr,
+ JITTargetAddress DeregisterEHFRameWrapperFnAddr)
+ : TPC(TPC), RegisterEHFrameWrapperFnAddr(RegisterEHFrameWrapperFnAddr),
+ DeregisterEHFrameWrapperFnAddr(DeregisterEHFRameWrapperFnAddr) {}
+
+ Error registerEHFrames(JITTargetAddress EHFrameSectionAddr,
+ size_t EHFrameSectionSize) override;
+ Error deregisterEHFrames(JITTargetAddress EHFrameSectionAddr,
+ size_t EHFrameSectionSize) override;
+
+private:
+ TargetProcessControl &TPC;
+ JITTargetAddress RegisterEHFrameWrapperFnAddr;
+ JITTargetAddress DeregisterEHFrameWrapperFnAddr;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TPCEHFRAMEREGISTRAR_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h
index 30643b4eaa..0d4de7bfe4 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h
@@ -1,233 +1,233 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===--- TPCIndirectionUtils.h - TPC based indirection utils ----*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Indirection utilities (stubs, trampolines, lazy call-throughs) that use the
-// TargetProcessControl API to interact with the target process.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_TPCINDIRECTIONUTILS_H
-#define LLVM_EXECUTIONENGINE_ORC_TPCINDIRECTIONUTILS_H
-
-#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
-#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
-#include "llvm/ExecutionEngine/Orc/LazyReexports.h"
-
-#include <mutex>
-
-namespace llvm {
-namespace orc {
-
-class TargetProcessControl;
-
-/// Provides TargetProcessControl based indirect stubs, trampoline pool and
-/// lazy call through manager.
-class TPCIndirectionUtils {
- friend class TPCIndirectionUtilsAccess;
-
-public:
- /// ABI support base class. Used to write resolver, stub, and trampoline
- /// blocks.
- class ABISupport {
- protected:
- ABISupport(unsigned PointerSize, unsigned TrampolineSize, unsigned StubSize,
- unsigned StubToPointerMaxDisplacement, unsigned ResolverCodeSize)
- : PointerSize(PointerSize), TrampolineSize(TrampolineSize),
- StubSize(StubSize),
- StubToPointerMaxDisplacement(StubToPointerMaxDisplacement),
- ResolverCodeSize(ResolverCodeSize) {}
-
- public:
- virtual ~ABISupport();
-
- unsigned getPointerSize() const { return PointerSize; }
- unsigned getTrampolineSize() const { return TrampolineSize; }
- unsigned getStubSize() const { return StubSize; }
- unsigned getStubToPointerMaxDisplacement() const {
- return StubToPointerMaxDisplacement;
- }
- unsigned getResolverCodeSize() const { return ResolverCodeSize; }
-
- virtual void writeResolverCode(char *ResolverWorkingMem,
- JITTargetAddress ResolverTargetAddr,
- JITTargetAddress ReentryFnAddr,
- JITTargetAddress ReentryCtxAddr) const = 0;
-
- virtual void writeTrampolines(char *TrampolineBlockWorkingMem,
- JITTargetAddress TrampolineBlockTragetAddr,
- JITTargetAddress ResolverAddr,
- unsigned NumTrampolines) const = 0;
-
- virtual void
- writeIndirectStubsBlock(char *StubsBlockWorkingMem,
- JITTargetAddress StubsBlockTargetAddress,
- JITTargetAddress PointersBlockTargetAddress,
- unsigned NumStubs) const = 0;
-
- private:
- unsigned PointerSize = 0;
- unsigned TrampolineSize = 0;
- unsigned StubSize = 0;
- unsigned StubToPointerMaxDisplacement = 0;
- unsigned ResolverCodeSize = 0;
- };
-
- /// Create using the given ABI class.
- template <typename ORCABI>
- static std::unique_ptr<TPCIndirectionUtils>
- CreateWithABI(TargetProcessControl &TPC);
-
- /// Create based on the TargetProcessControl triple.
- static Expected<std::unique_ptr<TPCIndirectionUtils>>
- Create(TargetProcessControl &TPC);
-
- /// Return a reference to the TargetProcessControl object.
- TargetProcessControl &getTargetProcessControl() const { return TPC; }
-
- /// Return a reference to the ABISupport object for this instance.
- ABISupport &getABISupport() const { return *ABI; }
-
- /// Release memory for resources held by this instance. This *must* be called
- /// prior to destruction of the class.
- Error cleanup();
-
- /// Write resolver code to the target process and return its address.
- /// This must be called before any call to createTrampolinePool or
- /// createLazyCallThroughManager.
- Expected<JITTargetAddress>
- writeResolverBlock(JITTargetAddress ReentryFnAddr,
- JITTargetAddress ReentryCtxAddr);
-
- /// Returns the address of the Resolver block. Returns zero if the
- /// writeResolverBlock method has not previously been called.
- JITTargetAddress getResolverBlockAddress() const { return ResolverBlockAddr; }
-
- /// Create an IndirectStubsManager for the target process.
- std::unique_ptr<IndirectStubsManager> createIndirectStubsManager();
-
- /// Create a TrampolinePool for the target process.
- TrampolinePool &getTrampolinePool();
-
- /// Create a LazyCallThroughManager.
- /// This function should only be called once.
- LazyCallThroughManager &
- createLazyCallThroughManager(ExecutionSession &ES,
- JITTargetAddress ErrorHandlerAddr);
-
- /// Create a LazyCallThroughManager for the target process.
- LazyCallThroughManager &getLazyCallThroughManager() {
- assert(LCTM && "createLazyCallThroughManager must be called first");
- return *LCTM;
- }
-
-private:
- using Allocation = jitlink::JITLinkMemoryManager::Allocation;
-
- struct IndirectStubInfo {
- IndirectStubInfo() = default;
- IndirectStubInfo(JITTargetAddress StubAddress,
- JITTargetAddress PointerAddress)
- : StubAddress(StubAddress), PointerAddress(PointerAddress) {}
- JITTargetAddress StubAddress = 0;
- JITTargetAddress PointerAddress = 0;
- };
-
- using IndirectStubInfoVector = std::vector<IndirectStubInfo>;
-
- /// Create a TPCIndirectionUtils instance.
- TPCIndirectionUtils(TargetProcessControl &TPC,
- std::unique_ptr<ABISupport> ABI);
-
- Expected<IndirectStubInfoVector> getIndirectStubs(unsigned NumStubs);
-
- std::mutex TPCUIMutex;
- TargetProcessControl &TPC;
- std::unique_ptr<ABISupport> ABI;
- JITTargetAddress ResolverBlockAddr;
- std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation> ResolverBlock;
- std::unique_ptr<TrampolinePool> TP;
- std::unique_ptr<LazyCallThroughManager> LCTM;
-
- std::vector<IndirectStubInfo> AvailableIndirectStubs;
- std::vector<std::unique_ptr<Allocation>> IndirectStubAllocs;
-};
-
-/// This will call writeResolver on the given TPCIndirectionUtils instance
-/// to set up re-entry via a function that will directly return the trampoline
-/// landing address.
-///
-/// The TPCIndirectionUtils' LazyCallThroughManager must have been previously
-/// created via TPCIndirectionUtils::createLazyCallThroughManager.
-///
-/// The TPCIndirectionUtils' writeResolver method must not have been previously
-/// called.
-///
-/// This function is experimental and likely subject to revision.
-Error setUpInProcessLCTMReentryViaTPCIU(TPCIndirectionUtils &TPCIU);
-
-namespace detail {
-
-template <typename ORCABI>
-class ABISupportImpl : public TPCIndirectionUtils::ABISupport {
-public:
- ABISupportImpl()
- : ABISupport(ORCABI::PointerSize, ORCABI::TrampolineSize,
- ORCABI::StubSize, ORCABI::StubToPointerMaxDisplacement,
- ORCABI::ResolverCodeSize) {}
-
- void writeResolverCode(char *ResolverWorkingMem,
- JITTargetAddress ResolverTargetAddr,
- JITTargetAddress ReentryFnAddr,
- JITTargetAddress ReentryCtxAddr) const override {
- ORCABI::writeResolverCode(ResolverWorkingMem, ResolverTargetAddr,
- ReentryFnAddr, ReentryCtxAddr);
- }
-
- void writeTrampolines(char *TrampolineBlockWorkingMem,
- JITTargetAddress TrampolineBlockTargetAddr,
- JITTargetAddress ResolverAddr,
- unsigned NumTrampolines) const override {
- ORCABI::writeTrampolines(TrampolineBlockWorkingMem,
- TrampolineBlockTargetAddr, ResolverAddr,
- NumTrampolines);
- }
-
- void writeIndirectStubsBlock(char *StubsBlockWorkingMem,
- JITTargetAddress StubsBlockTargetAddress,
- JITTargetAddress PointersBlockTargetAddress,
- unsigned NumStubs) const override {
- ORCABI::writeIndirectStubsBlock(StubsBlockWorkingMem,
- StubsBlockTargetAddress,
- PointersBlockTargetAddress, NumStubs);
- }
-};
-
-} // end namespace detail
-
-template <typename ORCABI>
-std::unique_ptr<TPCIndirectionUtils>
-TPCIndirectionUtils::CreateWithABI(TargetProcessControl &TPC) {
- return std::unique_ptr<TPCIndirectionUtils>(new TPCIndirectionUtils(
- TPC, std::make_unique<detail::ABISupportImpl<ORCABI>>()));
-}
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_TPCINDIRECTIONUTILS_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===--- TPCIndirectionUtils.h - TPC based indirection utils ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Indirection utilities (stubs, trampolines, lazy call-throughs) that use the
+// TargetProcessControl API to interact with the target process.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TPCINDIRECTIONUTILS_H
+#define LLVM_EXECUTIONENGINE_ORC_TPCINDIRECTIONUTILS_H
+
+#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
+#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
+#include "llvm/ExecutionEngine/Orc/LazyReexports.h"
+
+#include <mutex>
+
+namespace llvm {
+namespace orc {
+
+class TargetProcessControl;
+
+/// Provides TargetProcessControl based indirect stubs, trampoline pool and
+/// lazy call through manager.
+class TPCIndirectionUtils {
+ friend class TPCIndirectionUtilsAccess;
+
+public:
+ /// ABI support base class. Used to write resolver, stub, and trampoline
+ /// blocks.
+ class ABISupport {
+ protected:
+ ABISupport(unsigned PointerSize, unsigned TrampolineSize, unsigned StubSize,
+ unsigned StubToPointerMaxDisplacement, unsigned ResolverCodeSize)
+ : PointerSize(PointerSize), TrampolineSize(TrampolineSize),
+ StubSize(StubSize),
+ StubToPointerMaxDisplacement(StubToPointerMaxDisplacement),
+ ResolverCodeSize(ResolverCodeSize) {}
+
+ public:
+ virtual ~ABISupport();
+
+ unsigned getPointerSize() const { return PointerSize; }
+ unsigned getTrampolineSize() const { return TrampolineSize; }
+ unsigned getStubSize() const { return StubSize; }
+ unsigned getStubToPointerMaxDisplacement() const {
+ return StubToPointerMaxDisplacement;
+ }
+ unsigned getResolverCodeSize() const { return ResolverCodeSize; }
+
+ virtual void writeResolverCode(char *ResolverWorkingMem,
+ JITTargetAddress ResolverTargetAddr,
+ JITTargetAddress ReentryFnAddr,
+ JITTargetAddress ReentryCtxAddr) const = 0;
+
+ virtual void writeTrampolines(char *TrampolineBlockWorkingMem,
+ JITTargetAddress TrampolineBlockTragetAddr,
+ JITTargetAddress ResolverAddr,
+ unsigned NumTrampolines) const = 0;
+
+ virtual void
+ writeIndirectStubsBlock(char *StubsBlockWorkingMem,
+ JITTargetAddress StubsBlockTargetAddress,
+ JITTargetAddress PointersBlockTargetAddress,
+ unsigned NumStubs) const = 0;
+
+ private:
+ unsigned PointerSize = 0;
+ unsigned TrampolineSize = 0;
+ unsigned StubSize = 0;
+ unsigned StubToPointerMaxDisplacement = 0;
+ unsigned ResolverCodeSize = 0;
+ };
+
+ /// Create using the given ABI class.
+ template <typename ORCABI>
+ static std::unique_ptr<TPCIndirectionUtils>
+ CreateWithABI(TargetProcessControl &TPC);
+
+ /// Create based on the TargetProcessControl triple.
+ static Expected<std::unique_ptr<TPCIndirectionUtils>>
+ Create(TargetProcessControl &TPC);
+
+ /// Return a reference to the TargetProcessControl object.
+ TargetProcessControl &getTargetProcessControl() const { return TPC; }
+
+ /// Return a reference to the ABISupport object for this instance.
+ ABISupport &getABISupport() const { return *ABI; }
+
+ /// Release memory for resources held by this instance. This *must* be called
+ /// prior to destruction of the class.
+ Error cleanup();
+
+ /// Write resolver code to the target process and return its address.
+ /// This must be called before any call to createTrampolinePool or
+ /// createLazyCallThroughManager.
+ Expected<JITTargetAddress>
+ writeResolverBlock(JITTargetAddress ReentryFnAddr,
+ JITTargetAddress ReentryCtxAddr);
+
+ /// Returns the address of the Resolver block. Returns zero if the
+ /// writeResolverBlock method has not previously been called.
+ JITTargetAddress getResolverBlockAddress() const { return ResolverBlockAddr; }
+
+ /// Create an IndirectStubsManager for the target process.
+ std::unique_ptr<IndirectStubsManager> createIndirectStubsManager();
+
+ /// Create a TrampolinePool for the target process.
+ TrampolinePool &getTrampolinePool();
+
+ /// Create a LazyCallThroughManager.
+ /// This function should only be called once.
+ LazyCallThroughManager &
+ createLazyCallThroughManager(ExecutionSession &ES,
+ JITTargetAddress ErrorHandlerAddr);
+
+ /// Create a LazyCallThroughManager for the target process.
+ LazyCallThroughManager &getLazyCallThroughManager() {
+ assert(LCTM && "createLazyCallThroughManager must be called first");
+ return *LCTM;
+ }
+
+private:
+ using Allocation = jitlink::JITLinkMemoryManager::Allocation;
+
+ struct IndirectStubInfo {
+ IndirectStubInfo() = default;
+ IndirectStubInfo(JITTargetAddress StubAddress,
+ JITTargetAddress PointerAddress)
+ : StubAddress(StubAddress), PointerAddress(PointerAddress) {}
+ JITTargetAddress StubAddress = 0;
+ JITTargetAddress PointerAddress = 0;
+ };
+
+ using IndirectStubInfoVector = std::vector<IndirectStubInfo>;
+
+ /// Create a TPCIndirectionUtils instance.
+ TPCIndirectionUtils(TargetProcessControl &TPC,
+ std::unique_ptr<ABISupport> ABI);
+
+ Expected<IndirectStubInfoVector> getIndirectStubs(unsigned NumStubs);
+
+ std::mutex TPCUIMutex;
+ TargetProcessControl &TPC;
+ std::unique_ptr<ABISupport> ABI;
+ JITTargetAddress ResolverBlockAddr;
+ std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation> ResolverBlock;
+ std::unique_ptr<TrampolinePool> TP;
+ std::unique_ptr<LazyCallThroughManager> LCTM;
+
+ std::vector<IndirectStubInfo> AvailableIndirectStubs;
+ std::vector<std::unique_ptr<Allocation>> IndirectStubAllocs;
+};
+
+/// This will call writeResolver on the given TPCIndirectionUtils instance
+/// to set up re-entry via a function that will directly return the trampoline
+/// landing address.
+///
+/// The TPCIndirectionUtils' LazyCallThroughManager must have been previously
+/// created via TPCIndirectionUtils::createLazyCallThroughManager.
+///
+/// The TPCIndirectionUtils' writeResolver method must not have been previously
+/// called.
+///
+/// This function is experimental and likely subject to revision.
+Error setUpInProcessLCTMReentryViaTPCIU(TPCIndirectionUtils &TPCIU);
+
+namespace detail {
+
+template <typename ORCABI>
+class ABISupportImpl : public TPCIndirectionUtils::ABISupport {
+public:
+ ABISupportImpl()
+ : ABISupport(ORCABI::PointerSize, ORCABI::TrampolineSize,
+ ORCABI::StubSize, ORCABI::StubToPointerMaxDisplacement,
+ ORCABI::ResolverCodeSize) {}
+
+ void writeResolverCode(char *ResolverWorkingMem,
+ JITTargetAddress ResolverTargetAddr,
+ JITTargetAddress ReentryFnAddr,
+ JITTargetAddress ReentryCtxAddr) const override {
+ ORCABI::writeResolverCode(ResolverWorkingMem, ResolverTargetAddr,
+ ReentryFnAddr, ReentryCtxAddr);
+ }
+
+ void writeTrampolines(char *TrampolineBlockWorkingMem,
+ JITTargetAddress TrampolineBlockTargetAddr,
+ JITTargetAddress ResolverAddr,
+ unsigned NumTrampolines) const override {
+ ORCABI::writeTrampolines(TrampolineBlockWorkingMem,
+ TrampolineBlockTargetAddr, ResolverAddr,
+ NumTrampolines);
+ }
+
+ void writeIndirectStubsBlock(char *StubsBlockWorkingMem,
+ JITTargetAddress StubsBlockTargetAddress,
+ JITTargetAddress PointersBlockTargetAddress,
+ unsigned NumStubs) const override {
+ ORCABI::writeIndirectStubsBlock(StubsBlockWorkingMem,
+ StubsBlockTargetAddress,
+ PointersBlockTargetAddress, NumStubs);
+ }
+};
+
+} // end namespace detail
+
+template <typename ORCABI>
+std::unique_ptr<TPCIndirectionUtils>
+TPCIndirectionUtils::CreateWithABI(TargetProcessControl &TPC) {
+ return std::unique_ptr<TPCIndirectionUtils>(new TPCIndirectionUtils(
+ TPC, std::make_unique<detail::ABISupportImpl<ORCABI>>()));
+}
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TPCINDIRECTIONUTILS_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h
index f4cf20aac3..763b08fbcd 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h
@@ -1,631 +1,631 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===-- OrcRPCTPCServer.h -- OrcRPCTargetProcessControl Server --*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// OrcRPCTargetProcessControl server class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_ORCRPCTPCSERVER_H
-#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_ORCRPCTPCSERVER_H
-
-#include "llvm/ADT/BitmaskEnum.h"
-#include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h"
-#include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h"
-#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
-#include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"
-#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
-#include "llvm/Support/DynamicLibrary.h"
-#include "llvm/Support/FormatVariadic.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/Memory.h"
-#include "llvm/Support/Process.h"
-
-#include <atomic>
-
-namespace llvm {
-namespace orc {
-
-namespace orcrpctpc {
-
-enum WireProtectionFlags : uint8_t {
- WPF_None = 0,
- WPF_Read = 1U << 0,
- WPF_Write = 1U << 1,
- WPF_Exec = 1U << 2,
- LLVM_MARK_AS_BITMASK_ENUM(WPF_Exec)
-};
-
-/// Convert from sys::Memory::ProtectionFlags
-inline WireProtectionFlags
-toWireProtectionFlags(sys::Memory::ProtectionFlags PF) {
- WireProtectionFlags WPF = WPF_None;
- if (PF & sys::Memory::MF_READ)
- WPF |= WPF_Read;
- if (PF & sys::Memory::MF_WRITE)
- WPF |= WPF_Write;
- if (PF & sys::Memory::MF_EXEC)
- WPF |= WPF_Exec;
- return WPF;
-}
-
-inline sys::Memory::ProtectionFlags
-fromWireProtectionFlags(WireProtectionFlags WPF) {
- int PF = 0;
- if (WPF & WPF_Read)
- PF |= sys::Memory::MF_READ;
- if (WPF & WPF_Write)
- PF |= sys::Memory::MF_WRITE;
- if (WPF & WPF_Exec)
- PF |= sys::Memory::MF_EXEC;
- return static_cast<sys::Memory::ProtectionFlags>(PF);
-}
-
-struct ReserveMemRequestElement {
- WireProtectionFlags Prot = WPF_None;
- uint64_t Size = 0;
- uint64_t Alignment = 0;
-};
-
-using ReserveMemRequest = std::vector<ReserveMemRequestElement>;
-
-struct ReserveMemResultElement {
- WireProtectionFlags Prot = WPF_None;
- JITTargetAddress Address = 0;
- uint64_t AllocatedSize = 0;
-};
-
-using ReserveMemResult = std::vector<ReserveMemResultElement>;
-
-struct ReleaseOrFinalizeMemRequestElement {
- WireProtectionFlags Prot = WPF_None;
- JITTargetAddress Address = 0;
- uint64_t Size = 0;
-};
-
-using ReleaseOrFinalizeMemRequest =
- std::vector<ReleaseOrFinalizeMemRequestElement>;
-
-} // end namespace orcrpctpc
-
-namespace shared {
-
-template <> class SerializationTypeName<tpctypes::UInt8Write> {
-public:
- static const char *getName() { return "UInt8Write"; }
-};
-
-template <> class SerializationTypeName<tpctypes::UInt16Write> {
-public:
- static const char *getName() { return "UInt16Write"; }
-};
-
-template <> class SerializationTypeName<tpctypes::UInt32Write> {
-public:
- static const char *getName() { return "UInt32Write"; }
-};
-
-template <> class SerializationTypeName<tpctypes::UInt64Write> {
-public:
- static const char *getName() { return "UInt64Write"; }
-};
-
-template <> class SerializationTypeName<tpctypes::BufferWrite> {
-public:
- static const char *getName() { return "BufferWrite"; }
-};
-
-template <> class SerializationTypeName<orcrpctpc::ReserveMemRequestElement> {
-public:
- static const char *getName() { return "ReserveMemRequestElement"; }
-};
-
-template <> class SerializationTypeName<orcrpctpc::ReserveMemResultElement> {
-public:
- static const char *getName() { return "ReserveMemResultElement"; }
-};
-
-template <>
-class SerializationTypeName<orcrpctpc::ReleaseOrFinalizeMemRequestElement> {
-public:
- static const char *getName() { return "ReleaseOrFinalizeMemRequestElement"; }
-};
-
-template <> class SerializationTypeName<tpctypes::WrapperFunctionResult> {
-public:
- static const char *getName() { return "WrapperFunctionResult"; }
-};
-
-template <typename ChannelT, typename WriteT>
-class SerializationTraits<
- ChannelT, WriteT, WriteT,
- std::enable_if_t<std::is_same<WriteT, tpctypes::UInt8Write>::value ||
- std::is_same<WriteT, tpctypes::UInt16Write>::value ||
- std::is_same<WriteT, tpctypes::UInt32Write>::value ||
- std::is_same<WriteT, tpctypes::UInt64Write>::value>> {
-public:
- static Error serialize(ChannelT &C, const WriteT &W) {
- return serializeSeq(C, W.Address, W.Value);
- }
- static Error deserialize(ChannelT &C, WriteT &W) {
- return deserializeSeq(C, W.Address, W.Value);
- }
-};
-
-template <typename ChannelT>
-class SerializationTraits<
- ChannelT, tpctypes::BufferWrite, tpctypes::BufferWrite,
- std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
-public:
- static Error serialize(ChannelT &C, const tpctypes::BufferWrite &W) {
- uint64_t Size = W.Buffer.size();
- if (auto Err = serializeSeq(C, W.Address, Size))
- return Err;
-
- return C.appendBytes(W.Buffer.data(), Size);
- }
- static Error deserialize(ChannelT &C, tpctypes::BufferWrite &W) {
- JITTargetAddress Address;
- uint64_t Size;
-
- if (auto Err = deserializeSeq(C, Address, Size))
- return Err;
-
- char *Buffer = jitTargetAddressToPointer<char *>(Address);
-
- if (auto Err = C.readBytes(Buffer, Size))
- return Err;
-
- W = {Address, StringRef(Buffer, Size)};
- return Error::success();
- }
-};
-
-template <typename ChannelT>
-class SerializationTraits<ChannelT, orcrpctpc::ReserveMemRequestElement> {
-public:
- static Error serialize(ChannelT &C,
- const orcrpctpc::ReserveMemRequestElement &E) {
- return serializeSeq(C, static_cast<uint8_t>(E.Prot), E.Size, E.Alignment);
- }
-
- static Error deserialize(ChannelT &C,
- orcrpctpc::ReserveMemRequestElement &E) {
- return deserializeSeq(C, *reinterpret_cast<uint8_t *>(&E.Prot), E.Size,
- E.Alignment);
- }
-};
-
-template <typename ChannelT>
-class SerializationTraits<ChannelT, orcrpctpc::ReserveMemResultElement> {
-public:
- static Error serialize(ChannelT &C,
- const orcrpctpc::ReserveMemResultElement &E) {
- return serializeSeq(C, static_cast<uint8_t>(E.Prot), E.Address,
- E.AllocatedSize);
- }
-
- static Error deserialize(ChannelT &C, orcrpctpc::ReserveMemResultElement &E) {
- return deserializeSeq(C, *reinterpret_cast<uint8_t *>(&E.Prot), E.Address,
- E.AllocatedSize);
- }
-};
-
-template <typename ChannelT>
-class SerializationTraits<ChannelT,
- orcrpctpc::ReleaseOrFinalizeMemRequestElement> {
-public:
- static Error
- serialize(ChannelT &C,
- const orcrpctpc::ReleaseOrFinalizeMemRequestElement &E) {
- return serializeSeq(C, static_cast<uint8_t>(E.Prot), E.Address, E.Size);
- }
-
- static Error deserialize(ChannelT &C,
- orcrpctpc::ReleaseOrFinalizeMemRequestElement &E) {
- return deserializeSeq(C, *reinterpret_cast<uint8_t *>(&E.Prot), E.Address,
- E.Size);
- }
-};
-
-template <typename ChannelT>
-class SerializationTraits<
- ChannelT, tpctypes::WrapperFunctionResult, tpctypes::WrapperFunctionResult,
- std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
-public:
- static Error serialize(ChannelT &C,
- const tpctypes::WrapperFunctionResult &E) {
- auto Data = E.getData();
- if (auto Err = serializeSeq(C, static_cast<uint64_t>(Data.size())))
- return Err;
- if (Data.size() == 0)
- return Error::success();
- return C.appendBytes(reinterpret_cast<const char *>(Data.data()),
- Data.size());
- }
-
- static Error deserialize(ChannelT &C, tpctypes::WrapperFunctionResult &E) {
- tpctypes::CWrapperFunctionResult R;
-
- R.Size = 0;
- R.Data.ValuePtr = nullptr;
- R.Destroy = nullptr;
-
- if (auto Err = deserializeSeq(C, R.Size))
- return Err;
- if (R.Size == 0)
- return Error::success();
- R.Data.ValuePtr = new uint8_t[R.Size];
- if (auto Err =
- C.readBytes(reinterpret_cast<char *>(R.Data.ValuePtr), R.Size)) {
- R.Destroy = tpctypes::WrapperFunctionResult::destroyWithDeleteArray;
- return Err;
- }
-
- E = tpctypes::WrapperFunctionResult(R);
- return Error::success();
- }
-};
-
-} // end namespace shared
-
-namespace orcrpctpc {
-
-using RemoteSymbolLookupSet = std::vector<std::pair<std::string, bool>>;
-using RemoteLookupRequest =
- std::pair<tpctypes::DylibHandle, RemoteSymbolLookupSet>;
-
-class GetTargetTriple
- : public shared::RPCFunction<GetTargetTriple, std::string()> {
-public:
- static const char *getName() { return "GetTargetTriple"; }
-};
-
-class GetPageSize : public shared::RPCFunction<GetPageSize, uint64_t()> {
-public:
- static const char *getName() { return "GetPageSize"; }
-};
-
-class ReserveMem
- : public shared::RPCFunction<ReserveMem, Expected<ReserveMemResult>(
- ReserveMemRequest)> {
-public:
- static const char *getName() { return "ReserveMem"; }
-};
-
-class FinalizeMem
- : public shared::RPCFunction<FinalizeMem,
- Error(ReleaseOrFinalizeMemRequest)> {
-public:
- static const char *getName() { return "FinalizeMem"; }
-};
-
-class ReleaseMem
- : public shared::RPCFunction<ReleaseMem,
- Error(ReleaseOrFinalizeMemRequest)> {
-public:
- static const char *getName() { return "ReleaseMem"; }
-};
-
-class WriteUInt8s
- : public shared::RPCFunction<WriteUInt8s,
- Error(std::vector<tpctypes::UInt8Write>)> {
-public:
- static const char *getName() { return "WriteUInt8s"; }
-};
-
-class WriteUInt16s
- : public shared::RPCFunction<WriteUInt16s,
- Error(std::vector<tpctypes::UInt16Write>)> {
-public:
- static const char *getName() { return "WriteUInt16s"; }
-};
-
-class WriteUInt32s
- : public shared::RPCFunction<WriteUInt32s,
- Error(std::vector<tpctypes::UInt32Write>)> {
-public:
- static const char *getName() { return "WriteUInt32s"; }
-};
-
-class WriteUInt64s
- : public shared::RPCFunction<WriteUInt64s,
- Error(std::vector<tpctypes::UInt64Write>)> {
-public:
- static const char *getName() { return "WriteUInt64s"; }
-};
-
-class WriteBuffers
- : public shared::RPCFunction<WriteBuffers,
- Error(std::vector<tpctypes::BufferWrite>)> {
-public:
- static const char *getName() { return "WriteBuffers"; }
-};
-
-class LoadDylib
- : public shared::RPCFunction<LoadDylib, Expected<tpctypes::DylibHandle>(
- std::string DylibPath)> {
-public:
- static const char *getName() { return "LoadDylib"; }
-};
-
-class LookupSymbols
- : public shared::RPCFunction<LookupSymbols,
- Expected<std::vector<tpctypes::LookupResult>>(
- std::vector<RemoteLookupRequest>)> {
-public:
- static const char *getName() { return "LookupSymbols"; }
-};
-
-class RunMain
- : public shared::RPCFunction<RunMain,
- int32_t(JITTargetAddress MainAddr,
- std::vector<std::string> Args)> {
-public:
- static const char *getName() { return "RunMain"; }
-};
-
-class RunWrapper
- : public shared::RPCFunction<RunWrapper,
- tpctypes::WrapperFunctionResult(
- JITTargetAddress, std::vector<uint8_t>)> {
-public:
- static const char *getName() { return "RunWrapper"; }
-};
-
-class CloseConnection : public shared::RPCFunction<CloseConnection, void()> {
-public:
- static const char *getName() { return "CloseConnection"; }
-};
-
-} // end namespace orcrpctpc
-
-/// TargetProcessControl for a process connected via an ORC RPC Endpoint.
-template <typename RPCEndpointT> class OrcRPCTPCServer {
-public:
- /// Create an OrcRPCTPCServer from the given endpoint.
- OrcRPCTPCServer(RPCEndpointT &EP) : EP(EP) {
- using ThisT = OrcRPCTPCServer<RPCEndpointT>;
-
- TripleStr = sys::getProcessTriple();
- PageSize = sys::Process::getPageSizeEstimate();
-
- EP.template addHandler<orcrpctpc::GetTargetTriple>(*this,
- &ThisT::getTargetTriple);
- EP.template addHandler<orcrpctpc::GetPageSize>(*this, &ThisT::getPageSize);
-
- EP.template addHandler<orcrpctpc::ReserveMem>(*this, &ThisT::reserveMemory);
- EP.template addHandler<orcrpctpc::FinalizeMem>(*this,
- &ThisT::finalizeMemory);
- EP.template addHandler<orcrpctpc::ReleaseMem>(*this, &ThisT::releaseMemory);
-
- EP.template addHandler<orcrpctpc::WriteUInt8s>(
- handleWriteUInt<tpctypes::UInt8Write>);
- EP.template addHandler<orcrpctpc::WriteUInt16s>(
- handleWriteUInt<tpctypes::UInt16Write>);
- EP.template addHandler<orcrpctpc::WriteUInt32s>(
- handleWriteUInt<tpctypes::UInt32Write>);
- EP.template addHandler<orcrpctpc::WriteUInt64s>(
- handleWriteUInt<tpctypes::UInt64Write>);
- EP.template addHandler<orcrpctpc::WriteBuffers>(handleWriteBuffer);
-
- EP.template addHandler<orcrpctpc::LoadDylib>(*this, &ThisT::loadDylib);
- EP.template addHandler<orcrpctpc::LookupSymbols>(*this,
- &ThisT::lookupSymbols);
-
- EP.template addHandler<orcrpctpc::RunMain>(*this, &ThisT::runMain);
- EP.template addHandler<orcrpctpc::RunWrapper>(*this, &ThisT::runWrapper);
-
- EP.template addHandler<orcrpctpc::CloseConnection>(*this,
- &ThisT::closeConnection);
- }
-
- /// Set the ProgramName to be used as the first argv element when running
- /// functions via runAsMain.
- void setProgramName(Optional<std::string> ProgramName = None) {
- this->ProgramName = std::move(ProgramName);
- }
-
- /// Get the RPC endpoint for this server.
- RPCEndpointT &getEndpoint() { return EP; }
-
- /// Run the server loop.
- Error run() {
- while (!Finished) {
- if (auto Err = EP.handleOne())
- return Err;
- }
- return Error::success();
- }
-
-private:
- std::string getTargetTriple() { return TripleStr; }
- uint64_t getPageSize() { return PageSize; }
-
- template <typename WriteT>
- static void handleWriteUInt(const std::vector<WriteT> &Ws) {
- using ValueT = decltype(std::declval<WriteT>().Value);
- for (auto &W : Ws)
- *jitTargetAddressToPointer<ValueT *>(W.Address) = W.Value;
- }
-
- std::string getProtStr(orcrpctpc::WireProtectionFlags WPF) {
- std::string Result;
- Result += (WPF & orcrpctpc::WPF_Read) ? 'R' : '-';
- Result += (WPF & orcrpctpc::WPF_Write) ? 'W' : '-';
- Result += (WPF & orcrpctpc::WPF_Exec) ? 'X' : '-';
- return Result;
- }
-
- static void handleWriteBuffer(const std::vector<tpctypes::BufferWrite> &Ws) {
- for (auto &W : Ws) {
- memcpy(jitTargetAddressToPointer<char *>(W.Address), W.Buffer.data(),
- W.Buffer.size());
- }
- }
-
- Expected<orcrpctpc::ReserveMemResult>
- reserveMemory(const orcrpctpc::ReserveMemRequest &Request) {
- orcrpctpc::ReserveMemResult Allocs;
- auto PF = sys::Memory::MF_READ | sys::Memory::MF_WRITE;
-
- uint64_t TotalSize = 0;
-
- for (const auto &E : Request) {
- uint64_t Size = alignTo(E.Size, PageSize);
- uint16_t Align = E.Alignment;
-
- if ((Align > PageSize) || (PageSize % Align))
- return make_error<StringError>(
- "Page alignmen does not satisfy requested alignment",
- inconvertibleErrorCode());
-
- TotalSize += Size;
- }
-
- // Allocate memory slab.
- std::error_code EC;
- auto MB = sys::Memory::allocateMappedMemory(TotalSize, nullptr, PF, EC);
- if (EC)
- return make_error<StringError>("Unable to allocate memory: " +
- EC.message(),
- inconvertibleErrorCode());
-
- // Zero-fill the whole thing.
- memset(MB.base(), 0, MB.allocatedSize());
-
- // Carve up sections to return.
- uint64_t SectionBase = 0;
- for (const auto &E : Request) {
- uint64_t SectionSize = alignTo(E.Size, PageSize);
- Allocs.push_back({E.Prot,
- pointerToJITTargetAddress(MB.base()) + SectionBase,
- SectionSize});
- SectionBase += SectionSize;
- }
-
- return Allocs;
- }
-
- Error finalizeMemory(const orcrpctpc::ReleaseOrFinalizeMemRequest &FMR) {
- for (const auto &E : FMR) {
- sys::MemoryBlock MB(jitTargetAddressToPointer<void *>(E.Address), E.Size);
-
- auto PF = orcrpctpc::fromWireProtectionFlags(E.Prot);
- if (auto EC =
- sys::Memory::protectMappedMemory(MB, static_cast<unsigned>(PF)))
- return make_error<StringError>("error protecting memory: " +
- EC.message(),
- inconvertibleErrorCode());
- }
- return Error::success();
- }
-
- Error releaseMemory(const orcrpctpc::ReleaseOrFinalizeMemRequest &RMR) {
- for (const auto &E : RMR) {
- sys::MemoryBlock MB(jitTargetAddressToPointer<void *>(E.Address), E.Size);
-
- if (auto EC = sys::Memory::releaseMappedMemory(MB))
- return make_error<StringError>("error release memory: " + EC.message(),
- inconvertibleErrorCode());
- }
- return Error::success();
- }
-
- Expected<tpctypes::DylibHandle> loadDylib(const std::string &Path) {
- std::string ErrMsg;
- const char *DLPath = !Path.empty() ? Path.c_str() : nullptr;
- auto DL = sys::DynamicLibrary::getPermanentLibrary(DLPath, &ErrMsg);
- if (!DL.isValid())
- return make_error<StringError>(std::move(ErrMsg),
- inconvertibleErrorCode());
-
- tpctypes::DylibHandle H = Dylibs.size();
- Dylibs[H] = std::move(DL);
- return H;
- }
-
- Expected<std::vector<tpctypes::LookupResult>>
- lookupSymbols(const std::vector<orcrpctpc::RemoteLookupRequest> &Request) {
- std::vector<tpctypes::LookupResult> Result;
-
- for (const auto &E : Request) {
- auto I = Dylibs.find(E.first);
- if (I == Dylibs.end())
- return make_error<StringError>("Unrecognized handle",
- inconvertibleErrorCode());
- auto &DL = I->second;
- Result.push_back({});
-
- for (const auto &KV : E.second) {
- auto &SymString = KV.first;
- bool WeakReference = KV.second;
-
- const char *Sym = SymString.c_str();
-#ifdef __APPLE__
- if (*Sym == '_')
- ++Sym;
-#endif
-
- void *Addr = DL.getAddressOfSymbol(Sym);
- if (!Addr && !WeakReference)
- return make_error<StringError>(Twine("Missing definition for ") + Sym,
- inconvertibleErrorCode());
-
- Result.back().push_back(pointerToJITTargetAddress(Addr));
- }
- }
-
- return Result;
- }
-
- int32_t runMain(JITTargetAddress MainFnAddr,
- const std::vector<std::string> &Args) {
- Optional<StringRef> ProgramNameOverride;
- if (ProgramName)
- ProgramNameOverride = *ProgramName;
-
- return runAsMain(
- jitTargetAddressToFunction<int (*)(int, char *[])>(MainFnAddr), Args,
- ProgramNameOverride);
- }
-
- tpctypes::WrapperFunctionResult
- runWrapper(JITTargetAddress WrapperFnAddr,
- const std::vector<uint8_t> &ArgBuffer) {
- using WrapperFnTy = tpctypes::CWrapperFunctionResult (*)(
- const uint8_t *Data, uint64_t Size);
- auto *WrapperFn = jitTargetAddressToFunction<WrapperFnTy>(WrapperFnAddr);
- return WrapperFn(ArgBuffer.data(), ArgBuffer.size());
- }
-
- void closeConnection() { Finished = true; }
-
- std::string TripleStr;
- uint64_t PageSize = 0;
- Optional<std::string> ProgramName;
- RPCEndpointT &EP;
- std::atomic<bool> Finished{false};
- DenseMap<tpctypes::DylibHandle, sys::DynamicLibrary> Dylibs;
-};
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_ORCRPCTPCSERVER_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===-- OrcRPCTPCServer.h -- OrcRPCTargetProcessControl Server --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// OrcRPCTargetProcessControl server class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_ORCRPCTPCSERVER_H
+#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_ORCRPCTPCSERVER_H
+
+#include "llvm/ADT/BitmaskEnum.h"
+#include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h"
+#include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h"
+#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Memory.h"
+#include "llvm/Support/Process.h"
+
+#include <atomic>
+
+namespace llvm {
+namespace orc {
+
+namespace orcrpctpc {
+
+enum WireProtectionFlags : uint8_t {
+ WPF_None = 0,
+ WPF_Read = 1U << 0,
+ WPF_Write = 1U << 1,
+ WPF_Exec = 1U << 2,
+ LLVM_MARK_AS_BITMASK_ENUM(WPF_Exec)
+};
+
+/// Convert from sys::Memory::ProtectionFlags
+inline WireProtectionFlags
+toWireProtectionFlags(sys::Memory::ProtectionFlags PF) {
+ WireProtectionFlags WPF = WPF_None;
+ if (PF & sys::Memory::MF_READ)
+ WPF |= WPF_Read;
+ if (PF & sys::Memory::MF_WRITE)
+ WPF |= WPF_Write;
+ if (PF & sys::Memory::MF_EXEC)
+ WPF |= WPF_Exec;
+ return WPF;
+}
+
+inline sys::Memory::ProtectionFlags
+fromWireProtectionFlags(WireProtectionFlags WPF) {
+ int PF = 0;
+ if (WPF & WPF_Read)
+ PF |= sys::Memory::MF_READ;
+ if (WPF & WPF_Write)
+ PF |= sys::Memory::MF_WRITE;
+ if (WPF & WPF_Exec)
+ PF |= sys::Memory::MF_EXEC;
+ return static_cast<sys::Memory::ProtectionFlags>(PF);
+}
+
+struct ReserveMemRequestElement {
+ WireProtectionFlags Prot = WPF_None;
+ uint64_t Size = 0;
+ uint64_t Alignment = 0;
+};
+
+using ReserveMemRequest = std::vector<ReserveMemRequestElement>;
+
+struct ReserveMemResultElement {
+ WireProtectionFlags Prot = WPF_None;
+ JITTargetAddress Address = 0;
+ uint64_t AllocatedSize = 0;
+};
+
+using ReserveMemResult = std::vector<ReserveMemResultElement>;
+
+struct ReleaseOrFinalizeMemRequestElement {
+ WireProtectionFlags Prot = WPF_None;
+ JITTargetAddress Address = 0;
+ uint64_t Size = 0;
+};
+
+using ReleaseOrFinalizeMemRequest =
+ std::vector<ReleaseOrFinalizeMemRequestElement>;
+
+} // end namespace orcrpctpc
+
+namespace shared {
+
+template <> class SerializationTypeName<tpctypes::UInt8Write> {
+public:
+ static const char *getName() { return "UInt8Write"; }
+};
+
+template <> class SerializationTypeName<tpctypes::UInt16Write> {
+public:
+ static const char *getName() { return "UInt16Write"; }
+};
+
+template <> class SerializationTypeName<tpctypes::UInt32Write> {
+public:
+ static const char *getName() { return "UInt32Write"; }
+};
+
+template <> class SerializationTypeName<tpctypes::UInt64Write> {
+public:
+ static const char *getName() { return "UInt64Write"; }
+};
+
+template <> class SerializationTypeName<tpctypes::BufferWrite> {
+public:
+ static const char *getName() { return "BufferWrite"; }
+};
+
+template <> class SerializationTypeName<orcrpctpc::ReserveMemRequestElement> {
+public:
+ static const char *getName() { return "ReserveMemRequestElement"; }
+};
+
+template <> class SerializationTypeName<orcrpctpc::ReserveMemResultElement> {
+public:
+ static const char *getName() { return "ReserveMemResultElement"; }
+};
+
+template <>
+class SerializationTypeName<orcrpctpc::ReleaseOrFinalizeMemRequestElement> {
+public:
+ static const char *getName() { return "ReleaseOrFinalizeMemRequestElement"; }
+};
+
+template <> class SerializationTypeName<tpctypes::WrapperFunctionResult> {
+public:
+ static const char *getName() { return "WrapperFunctionResult"; }
+};
+
+template <typename ChannelT, typename WriteT>
+class SerializationTraits<
+ ChannelT, WriteT, WriteT,
+ std::enable_if_t<std::is_same<WriteT, tpctypes::UInt8Write>::value ||
+ std::is_same<WriteT, tpctypes::UInt16Write>::value ||
+ std::is_same<WriteT, tpctypes::UInt32Write>::value ||
+ std::is_same<WriteT, tpctypes::UInt64Write>::value>> {
+public:
+ static Error serialize(ChannelT &C, const WriteT &W) {
+ return serializeSeq(C, W.Address, W.Value);
+ }
+ static Error deserialize(ChannelT &C, WriteT &W) {
+ return deserializeSeq(C, W.Address, W.Value);
+ }
+};
+
+template <typename ChannelT>
+class SerializationTraits<
+ ChannelT, tpctypes::BufferWrite, tpctypes::BufferWrite,
+ std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
+public:
+ static Error serialize(ChannelT &C, const tpctypes::BufferWrite &W) {
+ uint64_t Size = W.Buffer.size();
+ if (auto Err = serializeSeq(C, W.Address, Size))
+ return Err;
+
+ return C.appendBytes(W.Buffer.data(), Size);
+ }
+ static Error deserialize(ChannelT &C, tpctypes::BufferWrite &W) {
+ JITTargetAddress Address;
+ uint64_t Size;
+
+ if (auto Err = deserializeSeq(C, Address, Size))
+ return Err;
+
+ char *Buffer = jitTargetAddressToPointer<char *>(Address);
+
+ if (auto Err = C.readBytes(Buffer, Size))
+ return Err;
+
+ W = {Address, StringRef(Buffer, Size)};
+ return Error::success();
+ }
+};
+
+template <typename ChannelT>
+class SerializationTraits<ChannelT, orcrpctpc::ReserveMemRequestElement> {
+public:
+ static Error serialize(ChannelT &C,
+ const orcrpctpc::ReserveMemRequestElement &E) {
+ return serializeSeq(C, static_cast<uint8_t>(E.Prot), E.Size, E.Alignment);
+ }
+
+ static Error deserialize(ChannelT &C,
+ orcrpctpc::ReserveMemRequestElement &E) {
+ return deserializeSeq(C, *reinterpret_cast<uint8_t *>(&E.Prot), E.Size,
+ E.Alignment);
+ }
+};
+
+template <typename ChannelT>
+class SerializationTraits<ChannelT, orcrpctpc::ReserveMemResultElement> {
+public:
+ static Error serialize(ChannelT &C,
+ const orcrpctpc::ReserveMemResultElement &E) {
+ return serializeSeq(C, static_cast<uint8_t>(E.Prot), E.Address,
+ E.AllocatedSize);
+ }
+
+ static Error deserialize(ChannelT &C, orcrpctpc::ReserveMemResultElement &E) {
+ return deserializeSeq(C, *reinterpret_cast<uint8_t *>(&E.Prot), E.Address,
+ E.AllocatedSize);
+ }
+};
+
+template <typename ChannelT>
+class SerializationTraits<ChannelT,
+ orcrpctpc::ReleaseOrFinalizeMemRequestElement> {
+public:
+ static Error
+ serialize(ChannelT &C,
+ const orcrpctpc::ReleaseOrFinalizeMemRequestElement &E) {
+ return serializeSeq(C, static_cast<uint8_t>(E.Prot), E.Address, E.Size);
+ }
+
+ static Error deserialize(ChannelT &C,
+ orcrpctpc::ReleaseOrFinalizeMemRequestElement &E) {
+ return deserializeSeq(C, *reinterpret_cast<uint8_t *>(&E.Prot), E.Address,
+ E.Size);
+ }
+};
+
+template <typename ChannelT>
+class SerializationTraits<
+ ChannelT, tpctypes::WrapperFunctionResult, tpctypes::WrapperFunctionResult,
+ std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
+public:
+ static Error serialize(ChannelT &C,
+ const tpctypes::WrapperFunctionResult &E) {
+ auto Data = E.getData();
+ if (auto Err = serializeSeq(C, static_cast<uint64_t>(Data.size())))
+ return Err;
+ if (Data.size() == 0)
+ return Error::success();
+ return C.appendBytes(reinterpret_cast<const char *>(Data.data()),
+ Data.size());
+ }
+
+ static Error deserialize(ChannelT &C, tpctypes::WrapperFunctionResult &E) {
+ tpctypes::CWrapperFunctionResult R;
+
+ R.Size = 0;
+ R.Data.ValuePtr = nullptr;
+ R.Destroy = nullptr;
+
+ if (auto Err = deserializeSeq(C, R.Size))
+ return Err;
+ if (R.Size == 0)
+ return Error::success();
+ R.Data.ValuePtr = new uint8_t[R.Size];
+ if (auto Err =
+ C.readBytes(reinterpret_cast<char *>(R.Data.ValuePtr), R.Size)) {
+ R.Destroy = tpctypes::WrapperFunctionResult::destroyWithDeleteArray;
+ return Err;
+ }
+
+ E = tpctypes::WrapperFunctionResult(R);
+ return Error::success();
+ }
+};
+
+} // end namespace shared
+
+namespace orcrpctpc {
+
+using RemoteSymbolLookupSet = std::vector<std::pair<std::string, bool>>;
+using RemoteLookupRequest =
+ std::pair<tpctypes::DylibHandle, RemoteSymbolLookupSet>;
+
+class GetTargetTriple
+ : public shared::RPCFunction<GetTargetTriple, std::string()> {
+public:
+ static const char *getName() { return "GetTargetTriple"; }
+};
+
+class GetPageSize : public shared::RPCFunction<GetPageSize, uint64_t()> {
+public:
+ static const char *getName() { return "GetPageSize"; }
+};
+
+class ReserveMem
+ : public shared::RPCFunction<ReserveMem, Expected<ReserveMemResult>(
+ ReserveMemRequest)> {
+public:
+ static const char *getName() { return "ReserveMem"; }
+};
+
+class FinalizeMem
+ : public shared::RPCFunction<FinalizeMem,
+ Error(ReleaseOrFinalizeMemRequest)> {
+public:
+ static const char *getName() { return "FinalizeMem"; }
+};
+
+class ReleaseMem
+ : public shared::RPCFunction<ReleaseMem,
+ Error(ReleaseOrFinalizeMemRequest)> {
+public:
+ static const char *getName() { return "ReleaseMem"; }
+};
+
+class WriteUInt8s
+ : public shared::RPCFunction<WriteUInt8s,
+ Error(std::vector<tpctypes::UInt8Write>)> {
+public:
+ static const char *getName() { return "WriteUInt8s"; }
+};
+
+class WriteUInt16s
+ : public shared::RPCFunction<WriteUInt16s,
+ Error(std::vector<tpctypes::UInt16Write>)> {
+public:
+ static const char *getName() { return "WriteUInt16s"; }
+};
+
+class WriteUInt32s
+ : public shared::RPCFunction<WriteUInt32s,
+ Error(std::vector<tpctypes::UInt32Write>)> {
+public:
+ static const char *getName() { return "WriteUInt32s"; }
+};
+
+class WriteUInt64s
+ : public shared::RPCFunction<WriteUInt64s,
+ Error(std::vector<tpctypes::UInt64Write>)> {
+public:
+ static const char *getName() { return "WriteUInt64s"; }
+};
+
+class WriteBuffers
+ : public shared::RPCFunction<WriteBuffers,
+ Error(std::vector<tpctypes::BufferWrite>)> {
+public:
+ static const char *getName() { return "WriteBuffers"; }
+};
+
+class LoadDylib
+ : public shared::RPCFunction<LoadDylib, Expected<tpctypes::DylibHandle>(
+ std::string DylibPath)> {
+public:
+ static const char *getName() { return "LoadDylib"; }
+};
+
+class LookupSymbols
+ : public shared::RPCFunction<LookupSymbols,
+ Expected<std::vector<tpctypes::LookupResult>>(
+ std::vector<RemoteLookupRequest>)> {
+public:
+ static const char *getName() { return "LookupSymbols"; }
+};
+
+class RunMain
+ : public shared::RPCFunction<RunMain,
+ int32_t(JITTargetAddress MainAddr,
+ std::vector<std::string> Args)> {
+public:
+ static const char *getName() { return "RunMain"; }
+};
+
+class RunWrapper
+ : public shared::RPCFunction<RunWrapper,
+ tpctypes::WrapperFunctionResult(
+ JITTargetAddress, std::vector<uint8_t>)> {
+public:
+ static const char *getName() { return "RunWrapper"; }
+};
+
+class CloseConnection : public shared::RPCFunction<CloseConnection, void()> {
+public:
+ static const char *getName() { return "CloseConnection"; }
+};
+
+} // end namespace orcrpctpc
+
+/// TargetProcessControl for a process connected via an ORC RPC Endpoint.
+template <typename RPCEndpointT> class OrcRPCTPCServer {
+public:
+ /// Create an OrcRPCTPCServer from the given endpoint.
+ OrcRPCTPCServer(RPCEndpointT &EP) : EP(EP) {
+ using ThisT = OrcRPCTPCServer<RPCEndpointT>;
+
+ TripleStr = sys::getProcessTriple();
+ PageSize = sys::Process::getPageSizeEstimate();
+
+ EP.template addHandler<orcrpctpc::GetTargetTriple>(*this,
+ &ThisT::getTargetTriple);
+ EP.template addHandler<orcrpctpc::GetPageSize>(*this, &ThisT::getPageSize);
+
+ EP.template addHandler<orcrpctpc::ReserveMem>(*this, &ThisT::reserveMemory);
+ EP.template addHandler<orcrpctpc::FinalizeMem>(*this,
+ &ThisT::finalizeMemory);
+ EP.template addHandler<orcrpctpc::ReleaseMem>(*this, &ThisT::releaseMemory);
+
+ EP.template addHandler<orcrpctpc::WriteUInt8s>(
+ handleWriteUInt<tpctypes::UInt8Write>);
+ EP.template addHandler<orcrpctpc::WriteUInt16s>(
+ handleWriteUInt<tpctypes::UInt16Write>);
+ EP.template addHandler<orcrpctpc::WriteUInt32s>(
+ handleWriteUInt<tpctypes::UInt32Write>);
+ EP.template addHandler<orcrpctpc::WriteUInt64s>(
+ handleWriteUInt<tpctypes::UInt64Write>);
+ EP.template addHandler<orcrpctpc::WriteBuffers>(handleWriteBuffer);
+
+ EP.template addHandler<orcrpctpc::LoadDylib>(*this, &ThisT::loadDylib);
+ EP.template addHandler<orcrpctpc::LookupSymbols>(*this,
+ &ThisT::lookupSymbols);
+
+ EP.template addHandler<orcrpctpc::RunMain>(*this, &ThisT::runMain);
+ EP.template addHandler<orcrpctpc::RunWrapper>(*this, &ThisT::runWrapper);
+
+ EP.template addHandler<orcrpctpc::CloseConnection>(*this,
+ &ThisT::closeConnection);
+ }
+
+ /// Set the ProgramName to be used as the first argv element when running
+ /// functions via runAsMain.
+ void setProgramName(Optional<std::string> ProgramName = None) {
+ this->ProgramName = std::move(ProgramName);
+ }
+
+ /// Get the RPC endpoint for this server.
+ RPCEndpointT &getEndpoint() { return EP; }
+
+ /// Run the server loop.
+ Error run() {
+ while (!Finished) {
+ if (auto Err = EP.handleOne())
+ return Err;
+ }
+ return Error::success();
+ }
+
+private:
+ std::string getTargetTriple() { return TripleStr; }
+ uint64_t getPageSize() { return PageSize; }
+
+ template <typename WriteT>
+ static void handleWriteUInt(const std::vector<WriteT> &Ws) {
+ using ValueT = decltype(std::declval<WriteT>().Value);
+ for (auto &W : Ws)
+ *jitTargetAddressToPointer<ValueT *>(W.Address) = W.Value;
+ }
+
+ std::string getProtStr(orcrpctpc::WireProtectionFlags WPF) {
+ std::string Result;
+ Result += (WPF & orcrpctpc::WPF_Read) ? 'R' : '-';
+ Result += (WPF & orcrpctpc::WPF_Write) ? 'W' : '-';
+ Result += (WPF & orcrpctpc::WPF_Exec) ? 'X' : '-';
+ return Result;
+ }
+
+ static void handleWriteBuffer(const std::vector<tpctypes::BufferWrite> &Ws) {
+ for (auto &W : Ws) {
+ memcpy(jitTargetAddressToPointer<char *>(W.Address), W.Buffer.data(),
+ W.Buffer.size());
+ }
+ }
+
+ Expected<orcrpctpc::ReserveMemResult>
+ reserveMemory(const orcrpctpc::ReserveMemRequest &Request) {
+ orcrpctpc::ReserveMemResult Allocs;
+ auto PF = sys::Memory::MF_READ | sys::Memory::MF_WRITE;
+
+ uint64_t TotalSize = 0;
+
+ for (const auto &E : Request) {
+ uint64_t Size = alignTo(E.Size, PageSize);
+ uint16_t Align = E.Alignment;
+
+ if ((Align > PageSize) || (PageSize % Align))
+ return make_error<StringError>(
+ "Page alignmen does not satisfy requested alignment",
+ inconvertibleErrorCode());
+
+ TotalSize += Size;
+ }
+
+ // Allocate memory slab.
+ std::error_code EC;
+ auto MB = sys::Memory::allocateMappedMemory(TotalSize, nullptr, PF, EC);
+ if (EC)
+ return make_error<StringError>("Unable to allocate memory: " +
+ EC.message(),
+ inconvertibleErrorCode());
+
+ // Zero-fill the whole thing.
+ memset(MB.base(), 0, MB.allocatedSize());
+
+ // Carve up sections to return.
+ uint64_t SectionBase = 0;
+ for (const auto &E : Request) {
+ uint64_t SectionSize = alignTo(E.Size, PageSize);
+ Allocs.push_back({E.Prot,
+ pointerToJITTargetAddress(MB.base()) + SectionBase,
+ SectionSize});
+ SectionBase += SectionSize;
+ }
+
+ return Allocs;
+ }
+
+ Error finalizeMemory(const orcrpctpc::ReleaseOrFinalizeMemRequest &FMR) {
+ for (const auto &E : FMR) {
+ sys::MemoryBlock MB(jitTargetAddressToPointer<void *>(E.Address), E.Size);
+
+ auto PF = orcrpctpc::fromWireProtectionFlags(E.Prot);
+ if (auto EC =
+ sys::Memory::protectMappedMemory(MB, static_cast<unsigned>(PF)))
+ return make_error<StringError>("error protecting memory: " +
+ EC.message(),
+ inconvertibleErrorCode());
+ }
+ return Error::success();
+ }
+
+ Error releaseMemory(const orcrpctpc::ReleaseOrFinalizeMemRequest &RMR) {
+ for (const auto &E : RMR) {
+ sys::MemoryBlock MB(jitTargetAddressToPointer<void *>(E.Address), E.Size);
+
+ if (auto EC = sys::Memory::releaseMappedMemory(MB))
+ return make_error<StringError>("error release memory: " + EC.message(),
+ inconvertibleErrorCode());
+ }
+ return Error::success();
+ }
+
+ Expected<tpctypes::DylibHandle> loadDylib(const std::string &Path) {
+ std::string ErrMsg;
+ const char *DLPath = !Path.empty() ? Path.c_str() : nullptr;
+ auto DL = sys::DynamicLibrary::getPermanentLibrary(DLPath, &ErrMsg);
+ if (!DL.isValid())
+ return make_error<StringError>(std::move(ErrMsg),
+ inconvertibleErrorCode());
+
+ tpctypes::DylibHandle H = Dylibs.size();
+ Dylibs[H] = std::move(DL);
+ return H;
+ }
+
+ Expected<std::vector<tpctypes::LookupResult>>
+ lookupSymbols(const std::vector<orcrpctpc::RemoteLookupRequest> &Request) {
+ std::vector<tpctypes::LookupResult> Result;
+
+ for (const auto &E : Request) {
+ auto I = Dylibs.find(E.first);
+ if (I == Dylibs.end())
+ return make_error<StringError>("Unrecognized handle",
+ inconvertibleErrorCode());
+ auto &DL = I->second;
+ Result.push_back({});
+
+ for (const auto &KV : E.second) {
+ auto &SymString = KV.first;
+ bool WeakReference = KV.second;
+
+ const char *Sym = SymString.c_str();
+#ifdef __APPLE__
+ if (*Sym == '_')
+ ++Sym;
+#endif
+
+ void *Addr = DL.getAddressOfSymbol(Sym);
+ if (!Addr && !WeakReference)
+ return make_error<StringError>(Twine("Missing definition for ") + Sym,
+ inconvertibleErrorCode());
+
+ Result.back().push_back(pointerToJITTargetAddress(Addr));
+ }
+ }
+
+ return Result;
+ }
+
+ int32_t runMain(JITTargetAddress MainFnAddr,
+ const std::vector<std::string> &Args) {
+ Optional<StringRef> ProgramNameOverride;
+ if (ProgramName)
+ ProgramNameOverride = *ProgramName;
+
+ return runAsMain(
+ jitTargetAddressToFunction<int (*)(int, char *[])>(MainFnAddr), Args,
+ ProgramNameOverride);
+ }
+
+ tpctypes::WrapperFunctionResult
+ runWrapper(JITTargetAddress WrapperFnAddr,
+ const std::vector<uint8_t> &ArgBuffer) {
+ using WrapperFnTy = tpctypes::CWrapperFunctionResult (*)(
+ const uint8_t *Data, uint64_t Size);
+ auto *WrapperFn = jitTargetAddressToFunction<WrapperFnTy>(WrapperFnAddr);
+ return WrapperFn(ArgBuffer.data(), ArgBuffer.size());
+ }
+
+ void closeConnection() { Finished = true; }
+
+ std::string TripleStr;
+ uint64_t PageSize = 0;
+ Optional<std::string> ProgramName;
+ RPCEndpointT &EP;
+ std::atomic<bool> Finished{false};
+ DenseMap<tpctypes::DylibHandle, sys::DynamicLibrary> Dylibs;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_ORCRPCTPCSERVER_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h
index a178dc7df1..b784287fb8 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h
@@ -1,52 +1,52 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===----- RegisterEHFrames.h -- Register EH frame sections -----*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Support for dynamically registering and deregistering eh-frame sections
-// in-process via libunwind.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_REGISTEREHFRAMES_H
-#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_REGISTEREHFRAMES_H
-
-#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
-#include "llvm/Support/Error.h"
-#include <vector>
-
-namespace llvm {
-namespace orc {
-
-/// Register frames in the given eh-frame section with libunwind.
-Error registerEHFrameSection(const void *EHFrameSectionAddr,
- size_t EHFrameSectionSize);
-
-/// Unregister frames in the given eh-frame section with libunwind.
-Error deregisterEHFrameSection(const void *EHFrameSectionAddr,
- size_t EHFrameSectionSize);
-
-} // end namespace orc
-} // end namespace llvm
-
-extern "C" llvm::orc::tpctypes::CWrapperFunctionResult
-llvm_orc_registerEHFrameSectionWrapper(uint8_t *Data, uint64_t Size);
-
-extern "C" llvm::orc::tpctypes::CWrapperFunctionResult
-llvm_orc_deregisterEHFrameSectionWrapper(uint8_t *Data, uint64_t Size);
-
-#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_REGISTEREHFRAMES_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===----- RegisterEHFrames.h -- Register EH frame sections -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Support for dynamically registering and deregistering eh-frame sections
+// in-process via libunwind.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_REGISTEREHFRAMES_H
+#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_REGISTEREHFRAMES_H
+
+#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
+#include "llvm/Support/Error.h"
+#include <vector>
+
+namespace llvm {
+namespace orc {
+
+/// Register frames in the given eh-frame section with libunwind.
+Error registerEHFrameSection(const void *EHFrameSectionAddr,
+ size_t EHFrameSectionSize);
+
+/// Unregister frames in the given eh-frame section with libunwind.
+Error deregisterEHFrameSection(const void *EHFrameSectionAddr,
+ size_t EHFrameSectionSize);
+
+} // end namespace orc
+} // end namespace llvm
+
+extern "C" llvm::orc::tpctypes::CWrapperFunctionResult
+llvm_orc_registerEHFrameSectionWrapper(uint8_t *Data, uint64_t Size);
+
+extern "C" llvm::orc::tpctypes::CWrapperFunctionResult
+llvm_orc_deregisterEHFrameSectionWrapper(uint8_t *Data, uint64_t Size);
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_REGISTEREHFRAMES_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h
index 334660f4a9..15a354dd34 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h
@@ -1,49 +1,49 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===-- TargetExecutionUtils.h - Utils for execution in target --*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Utilities for execution in the target process.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_TARGETEXECUTIONUTILS_H
-#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_TARGETEXECUTIONUTILS_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringRef.h"
-#include <string>
-
-namespace llvm {
-namespace orc {
-
-/// Run a main function, returning the result.
-///
-/// If the optional ProgramName argument is given then it will be inserted
-/// before the strings in Args as the first argument to the called function.
-///
-/// It is legal to have an empty argument list and no program name, however
-/// many main functions will expect a name argument at least, and will fail
-/// if none is provided.
-int runAsMain(int (*Main)(int, char *[]), ArrayRef<std::string> Args,
- Optional<StringRef> ProgramName = None);
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_TARGETEXECUTIONUTILS_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===-- TargetExecutionUtils.h - Utils for execution in target --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities for execution in the target process.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_TARGETEXECUTIONUTILS_H
+#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_TARGETEXECUTIONUTILS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+
+namespace llvm {
+namespace orc {
+
+/// Run a main function, returning the result.
+///
+/// If the optional ProgramName argument is given then it will be inserted
+/// before the strings in Args as the first argument to the called function.
+///
+/// It is legal to have an empty argument list and no program name, however
+/// many main functions will expect a name argument at least, and will fail
+/// if none is provided.
+int runAsMain(int (*Main)(int, char *[]), ArrayRef<std::string> Args,
+ Optional<StringRef> ProgramName = None);
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_TARGETEXECUTIONUTILS_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h
index 2c2e62ae64..952bcc2a33 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h
@@ -1,229 +1,229 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===--- TargetProcessControl.h - Target process control APIs ---*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Utilities for interacting with target processes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESSCONTROL_H
-#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESSCONTROL_H
-
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
-#include "llvm/ExecutionEngine/Orc/Core.h"
-#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
-#include "llvm/Support/DynamicLibrary.h"
-#include "llvm/Support/MSVCErrorWorkarounds.h"
-
-#include <future>
-#include <vector>
-
-namespace llvm {
-namespace orc {
-
-/// TargetProcessControl supports interaction with a JIT target process.
-class TargetProcessControl {
-public:
- /// APIs for manipulating memory in the target process.
- class MemoryAccess {
- public:
- /// Callback function for asynchronous writes.
- using WriteResultFn = unique_function<void(Error)>;
-
- virtual ~MemoryAccess();
-
- virtual void writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws,
- WriteResultFn OnWriteComplete) = 0;
-
- virtual void writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws,
- WriteResultFn OnWriteComplete) = 0;
-
- virtual void writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws,
- WriteResultFn OnWriteComplete) = 0;
-
- virtual void writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws,
- WriteResultFn OnWriteComplete) = 0;
-
- virtual void writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws,
- WriteResultFn OnWriteComplete) = 0;
-
- Error writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws) {
- std::promise<MSVCPError> ResultP;
- auto ResultF = ResultP.get_future();
- writeUInt8s(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
- return ResultF.get();
- }
-
- Error writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws) {
- std::promise<MSVCPError> ResultP;
- auto ResultF = ResultP.get_future();
- writeUInt16s(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
- return ResultF.get();
- }
-
- Error writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws) {
- std::promise<MSVCPError> ResultP;
- auto ResultF = ResultP.get_future();
- writeUInt32s(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
- return ResultF.get();
- }
-
- Error writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws) {
- std::promise<MSVCPError> ResultP;
- auto ResultF = ResultP.get_future();
- writeUInt64s(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
- return ResultF.get();
- }
-
- Error writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws) {
- std::promise<MSVCPError> ResultP;
- auto ResultF = ResultP.get_future();
- writeBuffers(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
- return ResultF.get();
- }
- };
-
- /// A pair of a dylib and a set of symbols to be looked up.
- struct LookupRequest {
- LookupRequest(tpctypes::DylibHandle Handle, const SymbolLookupSet &Symbols)
- : Handle(Handle), Symbols(Symbols) {}
- tpctypes::DylibHandle Handle;
- const SymbolLookupSet &Symbols;
- };
-
- virtual ~TargetProcessControl();
-
- /// Intern a symbol name in the SymbolStringPool.
- SymbolStringPtr intern(StringRef SymName) { return SSP->intern(SymName); }
-
- /// Return a shared pointer to the SymbolStringPool for this instance.
- std::shared_ptr<SymbolStringPool> getSymbolStringPool() const { return SSP; }
-
- /// Return the Triple for the target process.
- const Triple &getTargetTriple() const { return TargetTriple; }
-
- /// Get the page size for the target process.
- unsigned getPageSize() const { return PageSize; }
-
- /// Return a MemoryAccess object for the target process.
- MemoryAccess &getMemoryAccess() const { return *MemAccess; }
-
- /// Return a JITLinkMemoryManager for the target process.
- jitlink::JITLinkMemoryManager &getMemMgr() const { return *MemMgr; }
-
- /// Load the dynamic library at the given path and return a handle to it.
- /// If LibraryPath is null this function will return the global handle for
- /// the target process.
- virtual Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) = 0;
-
- /// Search for symbols in the target process.
- ///
- /// The result of the lookup is a 2-dimentional array of target addresses
- /// that correspond to the lookup order. If a required symbol is not
- /// found then this method will return an error. If a weakly referenced
- /// symbol is not found then it be assigned a '0' value in the result.
- /// that correspond to the lookup order.
- virtual Expected<std::vector<tpctypes::LookupResult>>
- lookupSymbols(ArrayRef<LookupRequest> Request) = 0;
-
- /// Run function with a main-like signature.
- virtual Expected<int32_t> runAsMain(JITTargetAddress MainFnAddr,
- ArrayRef<std::string> Args) = 0;
-
- /// Run a wrapper function with signature:
- ///
- /// \code{.cpp}
- /// CWrapperFunctionResult fn(uint8_t *Data, uint64_t Size);
- /// \endcode{.cpp}
- ///
- virtual Expected<tpctypes::WrapperFunctionResult>
- runWrapper(JITTargetAddress WrapperFnAddr, ArrayRef<uint8_t> ArgBuffer) = 0;
-
- /// Disconnect from the target process.
- ///
- /// This should be called after the JIT session is shut down.
- virtual Error disconnect() = 0;
-
-protected:
- TargetProcessControl(std::shared_ptr<SymbolStringPool> SSP)
- : SSP(std::move(SSP)) {}
-
- std::shared_ptr<SymbolStringPool> SSP;
- Triple TargetTriple;
- unsigned PageSize = 0;
- MemoryAccess *MemAccess = nullptr;
- jitlink::JITLinkMemoryManager *MemMgr = nullptr;
-};
-
-/// A TargetProcessControl implementation targeting the current process.
-class SelfTargetProcessControl : public TargetProcessControl,
- private TargetProcessControl::MemoryAccess {
-public:
- SelfTargetProcessControl(
- std::shared_ptr<SymbolStringPool> SSP, Triple TargetTriple,
- unsigned PageSize, std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr);
-
- /// Create a SelfTargetProcessControl with the given memory manager.
- /// If no memory manager is given a jitlink::InProcessMemoryManager will
- /// be used by default.
- static Expected<std::unique_ptr<SelfTargetProcessControl>>
- Create(std::shared_ptr<SymbolStringPool> SSP,
- std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr = nullptr);
-
- Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override;
-
- Expected<std::vector<tpctypes::LookupResult>>
- lookupSymbols(ArrayRef<LookupRequest> Request) override;
-
- Expected<int32_t> runAsMain(JITTargetAddress MainFnAddr,
- ArrayRef<std::string> Args) override;
-
- Expected<tpctypes::WrapperFunctionResult>
- runWrapper(JITTargetAddress WrapperFnAddr,
- ArrayRef<uint8_t> ArgBuffer) override;
-
- Error disconnect() override;
-
-private:
- void writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws,
- WriteResultFn OnWriteComplete) override;
-
- void writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws,
- WriteResultFn OnWriteComplete) override;
-
- void writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws,
- WriteResultFn OnWriteComplete) override;
-
- void writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws,
- WriteResultFn OnWriteComplete) override;
-
- void writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws,
- WriteResultFn OnWriteComplete) override;
-
- std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr;
- char GlobalManglingPrefix = 0;
- std::vector<std::unique_ptr<sys::DynamicLibrary>> DynamicLibraries;
-};
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESSCONTROL_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===--- TargetProcessControl.h - Target process control APIs ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities for interacting with target processes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESSCONTROL_H
+#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESSCONTROL_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
+#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/MSVCErrorWorkarounds.h"
+
+#include <future>
+#include <vector>
+
+namespace llvm {
+namespace orc {
+
+/// TargetProcessControl supports interaction with a JIT target process.
+class TargetProcessControl {
+public:
+ /// APIs for manipulating memory in the target process.
+ class MemoryAccess {
+ public:
+ /// Callback function for asynchronous writes.
+ using WriteResultFn = unique_function<void(Error)>;
+
+ virtual ~MemoryAccess();
+
+ virtual void writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws,
+ WriteResultFn OnWriteComplete) = 0;
+
+ virtual void writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws,
+ WriteResultFn OnWriteComplete) = 0;
+
+ virtual void writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws,
+ WriteResultFn OnWriteComplete) = 0;
+
+ virtual void writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws,
+ WriteResultFn OnWriteComplete) = 0;
+
+ virtual void writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws,
+ WriteResultFn OnWriteComplete) = 0;
+
+ Error writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws) {
+ std::promise<MSVCPError> ResultP;
+ auto ResultF = ResultP.get_future();
+ writeUInt8s(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
+ return ResultF.get();
+ }
+
+ Error writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws) {
+ std::promise<MSVCPError> ResultP;
+ auto ResultF = ResultP.get_future();
+ writeUInt16s(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
+ return ResultF.get();
+ }
+
+ Error writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws) {
+ std::promise<MSVCPError> ResultP;
+ auto ResultF = ResultP.get_future();
+ writeUInt32s(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
+ return ResultF.get();
+ }
+
+ Error writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws) {
+ std::promise<MSVCPError> ResultP;
+ auto ResultF = ResultP.get_future();
+ writeUInt64s(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
+ return ResultF.get();
+ }
+
+ Error writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws) {
+ std::promise<MSVCPError> ResultP;
+ auto ResultF = ResultP.get_future();
+ writeBuffers(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
+ return ResultF.get();
+ }
+ };
+
+ /// A pair of a dylib and a set of symbols to be looked up.
+ struct LookupRequest {
+ LookupRequest(tpctypes::DylibHandle Handle, const SymbolLookupSet &Symbols)
+ : Handle(Handle), Symbols(Symbols) {}
+ tpctypes::DylibHandle Handle;
+ const SymbolLookupSet &Symbols;
+ };
+
+ virtual ~TargetProcessControl();
+
+ /// Intern a symbol name in the SymbolStringPool.
+ SymbolStringPtr intern(StringRef SymName) { return SSP->intern(SymName); }
+
+ /// Return a shared pointer to the SymbolStringPool for this instance.
+ std::shared_ptr<SymbolStringPool> getSymbolStringPool() const { return SSP; }
+
+ /// Return the Triple for the target process.
+ const Triple &getTargetTriple() const { return TargetTriple; }
+
+ /// Get the page size for the target process.
+ unsigned getPageSize() const { return PageSize; }
+
+ /// Return a MemoryAccess object for the target process.
+ MemoryAccess &getMemoryAccess() const { return *MemAccess; }
+
+ /// Return a JITLinkMemoryManager for the target process.
+ jitlink::JITLinkMemoryManager &getMemMgr() const { return *MemMgr; }
+
+ /// Load the dynamic library at the given path and return a handle to it.
+ /// If LibraryPath is null this function will return the global handle for
+ /// the target process.
+ virtual Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) = 0;
+
+ /// Search for symbols in the target process.
+ ///
+ /// The result of the lookup is a 2-dimentional array of target addresses
+ /// that correspond to the lookup order. If a required symbol is not
+ /// found then this method will return an error. If a weakly referenced
+ /// symbol is not found then it be assigned a '0' value in the result.
+ /// that correspond to the lookup order.
+ virtual Expected<std::vector<tpctypes::LookupResult>>
+ lookupSymbols(ArrayRef<LookupRequest> Request) = 0;
+
+ /// Run function with a main-like signature.
+ virtual Expected<int32_t> runAsMain(JITTargetAddress MainFnAddr,
+ ArrayRef<std::string> Args) = 0;
+
+ /// Run a wrapper function with signature:
+ ///
+ /// \code{.cpp}
+ /// CWrapperFunctionResult fn(uint8_t *Data, uint64_t Size);
+ /// \endcode{.cpp}
+ ///
+ virtual Expected<tpctypes::WrapperFunctionResult>
+ runWrapper(JITTargetAddress WrapperFnAddr, ArrayRef<uint8_t> ArgBuffer) = 0;
+
+ /// Disconnect from the target process.
+ ///
+ /// This should be called after the JIT session is shut down.
+ virtual Error disconnect() = 0;
+
+protected:
+ TargetProcessControl(std::shared_ptr<SymbolStringPool> SSP)
+ : SSP(std::move(SSP)) {}
+
+ std::shared_ptr<SymbolStringPool> SSP;
+ Triple TargetTriple;
+ unsigned PageSize = 0;
+ MemoryAccess *MemAccess = nullptr;
+ jitlink::JITLinkMemoryManager *MemMgr = nullptr;
+};
+
+/// A TargetProcessControl implementation targeting the current process.
+class SelfTargetProcessControl : public TargetProcessControl,
+ private TargetProcessControl::MemoryAccess {
+public:
+ SelfTargetProcessControl(
+ std::shared_ptr<SymbolStringPool> SSP, Triple TargetTriple,
+ unsigned PageSize, std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr);
+
+ /// Create a SelfTargetProcessControl with the given memory manager.
+ /// If no memory manager is given a jitlink::InProcessMemoryManager will
+ /// be used by default.
+ static Expected<std::unique_ptr<SelfTargetProcessControl>>
+ Create(std::shared_ptr<SymbolStringPool> SSP,
+ std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr = nullptr);
+
+ Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override;
+
+ Expected<std::vector<tpctypes::LookupResult>>
+ lookupSymbols(ArrayRef<LookupRequest> Request) override;
+
+ Expected<int32_t> runAsMain(JITTargetAddress MainFnAddr,
+ ArrayRef<std::string> Args) override;
+
+ Expected<tpctypes::WrapperFunctionResult>
+ runWrapper(JITTargetAddress WrapperFnAddr,
+ ArrayRef<uint8_t> ArgBuffer) override;
+
+ Error disconnect() override;
+
+private:
+ void writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws,
+ WriteResultFn OnWriteComplete) override;
+
+ void writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws,
+ WriteResultFn OnWriteComplete) override;
+
+ void writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws,
+ WriteResultFn OnWriteComplete) override;
+
+ void writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws,
+ WriteResultFn OnWriteComplete) override;
+
+ void writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws,
+ WriteResultFn OnWriteComplete) override;
+
+ std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr;
+ char GlobalManglingPrefix = 0;
+ std::vector<std::unique_ptr<sys::DynamicLibrary>> DynamicLibraries;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESSCONTROL_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
index 3e412f3385..d1b0e81018 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
@@ -169,7 +169,7 @@ using GVModifier = std::function<void(GlobalValue &)>;
/// Clones the given module on to a new context.
ThreadSafeModule
-cloneToNewContext(const ThreadSafeModule &TSMW,
+cloneToNewContext(const ThreadSafeModule &TSMW,
GVPredicate ShouldCloneDef = GVPredicate(),
GVModifier UpdateClonedDefSource = GVModifier());
diff --git a/contrib/libs/llvm12/include/llvm/ExecutionEngine/RuntimeDyld.h b/contrib/libs/llvm12/include/llvm/ExecutionEngine/RuntimeDyld.h
index e3aab19ac6..c3bf3d3ec4 100644
--- a/contrib/libs/llvm12/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/contrib/libs/llvm12/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -278,11 +278,11 @@ private:
object::OwningBinary<object::ObjectFile> O,
RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver,
bool ProcessAllSections,
- unique_function<Error(const object::ObjectFile &Obj, LoadedObjectInfo &,
+ unique_function<Error(const object::ObjectFile &Obj, LoadedObjectInfo &,
std::map<StringRef, JITEvaluatedSymbol>)>
OnLoaded,
- unique_function<void(object::OwningBinary<object::ObjectFile> O,
- std::unique_ptr<LoadedObjectInfo>, Error)>
+ unique_function<void(object::OwningBinary<object::ObjectFile> O,
+ std::unique_ptr<LoadedObjectInfo>, Error)>
OnEmitted);
// RuntimeDyldImpl is the actual class. RuntimeDyld is just the public
@@ -305,11 +305,11 @@ void jitLinkForORC(
RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver,
bool ProcessAllSections,
unique_function<Error(const object::ObjectFile &Obj,
- RuntimeDyld::LoadedObjectInfo &,
+ RuntimeDyld::LoadedObjectInfo &,
std::map<StringRef, JITEvaluatedSymbol>)>
OnLoaded,
- unique_function<void(object::OwningBinary<object::ObjectFile>,
- std::unique_ptr<RuntimeDyld::LoadedObjectInfo>, Error)>
+ unique_function<void(object::OwningBinary<object::ObjectFile>,
+ std::unique_ptr<RuntimeDyld::LoadedObjectInfo>, Error)>
OnEmitted);
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/FileCheck/FileCheck.h b/contrib/libs/llvm12/include/llvm/FileCheck/FileCheck.h
index 909c719bdd..a0436630d7 100644
--- a/contrib/libs/llvm12/include/llvm/FileCheck/FileCheck.h
+++ b/contrib/libs/llvm12/include/llvm/FileCheck/FileCheck.h
@@ -1,227 +1,227 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//==-- llvm/FileCheck/FileCheck.h --------------------------------*- C++ -*-==//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file This file has some utilities to use FileCheck as an API
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_FILECHECK_FILECHECK_H
-#define LLVM_FILECHECK_FILECHECK_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Regex.h"
-#include "llvm/Support/SourceMgr.h"
-#include <bitset>
-#include <string>
-#include <vector>
-
-namespace llvm {
-
-/// Contains info about various FileCheck options.
-struct FileCheckRequest {
- std::vector<StringRef> CheckPrefixes;
- std::vector<StringRef> CommentPrefixes;
- bool NoCanonicalizeWhiteSpace = false;
- std::vector<StringRef> ImplicitCheckNot;
- std::vector<StringRef> GlobalDefines;
- bool AllowEmptyInput = false;
- bool AllowUnusedPrefixes = false;
- bool MatchFullLines = false;
- bool IgnoreCase = false;
- bool IsDefaultCheckPrefix = false;
- bool EnableVarScope = false;
- bool AllowDeprecatedDagOverlap = false;
- bool Verbose = false;
- bool VerboseVerbose = false;
-};
-
-namespace Check {
-
-enum FileCheckKind {
- CheckNone = 0,
- CheckPlain,
- CheckNext,
- CheckSame,
- CheckNot,
- CheckDAG,
- CheckLabel,
- CheckEmpty,
- CheckComment,
-
- /// Indicates the pattern only matches the end of file. This is used for
- /// trailing CHECK-NOTs.
- CheckEOF,
-
- /// Marks when parsing found a -NOT check combined with another CHECK suffix.
- CheckBadNot,
-
- /// Marks when parsing found a -COUNT directive with invalid count value.
- CheckBadCount
-};
-
-enum FileCheckKindModifier {
- /// Modifies directive to perform literal match.
- ModifierLiteral = 0,
-
- // The number of modifier.
- Size
-};
-
-class FileCheckType {
- FileCheckKind Kind;
- int Count; ///< optional Count for some checks
- /// Modifers for the check directive.
- std::bitset<FileCheckKindModifier::Size> Modifiers;
-
-public:
- FileCheckType(FileCheckKind Kind = CheckNone)
- : Kind(Kind), Count(1), Modifiers() {}
- FileCheckType(const FileCheckType &) = default;
- FileCheckType &operator=(const FileCheckType &) = default;
-
- operator FileCheckKind() const { return Kind; }
-
- int getCount() const { return Count; }
- FileCheckType &setCount(int C);
-
- bool isLiteralMatch() const {
- return Modifiers[FileCheckKindModifier::ModifierLiteral];
- }
- FileCheckType &setLiteralMatch(bool Literal = true) {
- Modifiers.set(FileCheckKindModifier::ModifierLiteral, Literal);
- return *this;
- }
-
- // \returns a description of \p Prefix.
- std::string getDescription(StringRef Prefix) const;
-
- // \returns a description of \p Modifiers.
- std::string getModifiersDescription() const;
-};
-} // namespace Check
-
-/// Summary of a FileCheck diagnostic.
-struct FileCheckDiag {
- /// What is the FileCheck directive for this diagnostic?
- Check::FileCheckType CheckTy;
- /// Where is the FileCheck directive for this diagnostic?
- SMLoc CheckLoc;
- /// What type of match result does this diagnostic describe?
- ///
- /// A directive's supplied pattern is said to be either expected or excluded
- /// depending on whether the pattern must have or must not have a match in
- /// order for the directive to succeed. For example, a CHECK directive's
- /// pattern is expected, and a CHECK-NOT directive's pattern is excluded.
- /// All match result types whose names end with "Excluded" are for excluded
- /// patterns, and all others are for expected patterns.
- ///
- /// There might be more than one match result for a single pattern. For
- /// example, there might be several discarded matches
- /// (MatchFoundButDiscarded) before either a good match
- /// (MatchFoundAndExpected) or a failure to match (MatchNoneButExpected),
- /// and there might be a fuzzy match (MatchFuzzy) after the latter.
- enum MatchType {
- /// Indicates a good match for an expected pattern.
- MatchFoundAndExpected,
- /// Indicates a match for an excluded pattern.
- MatchFoundButExcluded,
- /// Indicates a match for an expected pattern, but the match is on the
- /// wrong line.
- MatchFoundButWrongLine,
- /// Indicates a discarded match for an expected pattern.
- MatchFoundButDiscarded,
- /// Indicates no match for an excluded pattern.
- MatchNoneAndExcluded,
- /// Indicates no match for an expected pattern, but this might follow good
- /// matches when multiple matches are expected for the pattern, or it might
- /// follow discarded matches for the pattern.
- MatchNoneButExpected,
- /// Indicates a fuzzy match that serves as a suggestion for the next
- /// intended match for an expected pattern with too few or no good matches.
- MatchFuzzy,
- } MatchTy;
- /// The search range if MatchTy is MatchNoneAndExcluded or
- /// MatchNoneButExpected, or the match range otherwise.
- unsigned InputStartLine;
- unsigned InputStartCol;
- unsigned InputEndLine;
- unsigned InputEndCol;
- /// A note to replace the one normally indicated by MatchTy, or the empty
- /// string if none.
- std::string Note;
- FileCheckDiag(const SourceMgr &SM, const Check::FileCheckType &CheckTy,
- SMLoc CheckLoc, MatchType MatchTy, SMRange InputRange,
- StringRef Note = "");
-};
-
-class FileCheckPatternContext;
-struct FileCheckString;
-
-/// FileCheck class takes the request and exposes various methods that
-/// use information from the request.
-class FileCheck {
- FileCheckRequest Req;
- std::unique_ptr<FileCheckPatternContext> PatternContext;
- // C++17 TODO: make this a plain std::vector.
- std::unique_ptr<std::vector<FileCheckString>> CheckStrings;
-
-public:
- explicit FileCheck(FileCheckRequest Req);
- ~FileCheck();
-
- // Combines the check prefixes into a single regex so that we can efficiently
- // scan for any of the set.
- //
- // The semantics are that the longest-match wins which matches our regex
- // library.
- Regex buildCheckPrefixRegex();
-
- /// Reads the check file from \p Buffer and records the expected strings it
- /// contains. Errors are reported against \p SM.
- ///
- /// Only expected strings whose prefix is one of those listed in \p PrefixRE
- /// are recorded. \returns true in case of an error, false otherwise.
- ///
- /// If \p ImpPatBufferIDRange, then the range (inclusive start, exclusive end)
- /// of IDs for source buffers added to \p SM for implicit patterns are
- /// recorded in it. The range is empty if there are none.
- bool
- readCheckFile(SourceMgr &SM, StringRef Buffer, Regex &PrefixRE,
- std::pair<unsigned, unsigned> *ImpPatBufferIDRange = nullptr);
-
- bool ValidateCheckPrefixes();
-
- /// Canonicalizes whitespaces in the file. Line endings are replaced with
- /// UNIX-style '\n'.
- StringRef CanonicalizeFile(MemoryBuffer &MB,
- SmallVectorImpl<char> &OutputBuffer);
-
- /// Checks the input to FileCheck provided in the \p Buffer against the
- /// expected strings read from the check file and record diagnostics emitted
- /// in \p Diags. Errors are recorded against \p SM.
- ///
- /// \returns false if the input fails to satisfy the checks.
- bool checkInput(SourceMgr &SM, StringRef Buffer,
- std::vector<FileCheckDiag> *Diags = nullptr);
-};
-
-} // namespace llvm
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//==-- llvm/FileCheck/FileCheck.h --------------------------------*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file This file has some utilities to use FileCheck as an API
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FILECHECK_FILECHECK_H
+#define LLVM_FILECHECK_FILECHECK_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/SourceMgr.h"
+#include <bitset>
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+/// Contains info about various FileCheck options.
+struct FileCheckRequest {
+ std::vector<StringRef> CheckPrefixes;
+ std::vector<StringRef> CommentPrefixes;
+ bool NoCanonicalizeWhiteSpace = false;
+ std::vector<StringRef> ImplicitCheckNot;
+ std::vector<StringRef> GlobalDefines;
+ bool AllowEmptyInput = false;
+ bool AllowUnusedPrefixes = false;
+ bool MatchFullLines = false;
+ bool IgnoreCase = false;
+ bool IsDefaultCheckPrefix = false;
+ bool EnableVarScope = false;
+ bool AllowDeprecatedDagOverlap = false;
+ bool Verbose = false;
+ bool VerboseVerbose = false;
+};
+
+namespace Check {
+
+enum FileCheckKind {
+ CheckNone = 0,
+ CheckPlain,
+ CheckNext,
+ CheckSame,
+ CheckNot,
+ CheckDAG,
+ CheckLabel,
+ CheckEmpty,
+ CheckComment,
+
+ /// Indicates the pattern only matches the end of file. This is used for
+ /// trailing CHECK-NOTs.
+ CheckEOF,
+
+ /// Marks when parsing found a -NOT check combined with another CHECK suffix.
+ CheckBadNot,
+
+ /// Marks when parsing found a -COUNT directive with invalid count value.
+ CheckBadCount
+};
+
+enum FileCheckKindModifier {
+ /// Modifies directive to perform literal match.
+ ModifierLiteral = 0,
+
+ // The number of modifier.
+ Size
+};
+
+class FileCheckType {
+ FileCheckKind Kind;
+ int Count; ///< optional Count for some checks
+ /// Modifers for the check directive.
+ std::bitset<FileCheckKindModifier::Size> Modifiers;
+
+public:
+ FileCheckType(FileCheckKind Kind = CheckNone)
+ : Kind(Kind), Count(1), Modifiers() {}
+ FileCheckType(const FileCheckType &) = default;
+ FileCheckType &operator=(const FileCheckType &) = default;
+
+ operator FileCheckKind() const { return Kind; }
+
+ int getCount() const { return Count; }
+ FileCheckType &setCount(int C);
+
+ bool isLiteralMatch() const {
+ return Modifiers[FileCheckKindModifier::ModifierLiteral];
+ }
+ FileCheckType &setLiteralMatch(bool Literal = true) {
+ Modifiers.set(FileCheckKindModifier::ModifierLiteral, Literal);
+ return *this;
+ }
+
+ // \returns a description of \p Prefix.
+ std::string getDescription(StringRef Prefix) const;
+
+ // \returns a description of \p Modifiers.
+ std::string getModifiersDescription() const;
+};
+} // namespace Check
+
+/// Summary of a FileCheck diagnostic.
+struct FileCheckDiag {
+ /// What is the FileCheck directive for this diagnostic?
+ Check::FileCheckType CheckTy;
+ /// Where is the FileCheck directive for this diagnostic?
+ SMLoc CheckLoc;
+ /// What type of match result does this diagnostic describe?
+ ///
+ /// A directive's supplied pattern is said to be either expected or excluded
+ /// depending on whether the pattern must have or must not have a match in
+ /// order for the directive to succeed. For example, a CHECK directive's
+ /// pattern is expected, and a CHECK-NOT directive's pattern is excluded.
+ /// All match result types whose names end with "Excluded" are for excluded
+ /// patterns, and all others are for expected patterns.
+ ///
+ /// There might be more than one match result for a single pattern. For
+ /// example, there might be several discarded matches
+ /// (MatchFoundButDiscarded) before either a good match
+ /// (MatchFoundAndExpected) or a failure to match (MatchNoneButExpected),
+ /// and there might be a fuzzy match (MatchFuzzy) after the latter.
+ enum MatchType {
+ /// Indicates a good match for an expected pattern.
+ MatchFoundAndExpected,
+ /// Indicates a match for an excluded pattern.
+ MatchFoundButExcluded,
+ /// Indicates a match for an expected pattern, but the match is on the
+ /// wrong line.
+ MatchFoundButWrongLine,
+ /// Indicates a discarded match for an expected pattern.
+ MatchFoundButDiscarded,
+ /// Indicates no match for an excluded pattern.
+ MatchNoneAndExcluded,
+ /// Indicates no match for an expected pattern, but this might follow good
+ /// matches when multiple matches are expected for the pattern, or it might
+ /// follow discarded matches for the pattern.
+ MatchNoneButExpected,
+ /// Indicates a fuzzy match that serves as a suggestion for the next
+ /// intended match for an expected pattern with too few or no good matches.
+ MatchFuzzy,
+ } MatchTy;
+ /// The search range if MatchTy is MatchNoneAndExcluded or
+ /// MatchNoneButExpected, or the match range otherwise.
+ unsigned InputStartLine;
+ unsigned InputStartCol;
+ unsigned InputEndLine;
+ unsigned InputEndCol;
+ /// A note to replace the one normally indicated by MatchTy, or the empty
+ /// string if none.
+ std::string Note;
+ FileCheckDiag(const SourceMgr &SM, const Check::FileCheckType &CheckTy,
+ SMLoc CheckLoc, MatchType MatchTy, SMRange InputRange,
+ StringRef Note = "");
+};
+
+class FileCheckPatternContext;
+struct FileCheckString;
+
+/// FileCheck class takes the request and exposes various methods that
+/// use information from the request.
+class FileCheck {
+ FileCheckRequest Req;
+ std::unique_ptr<FileCheckPatternContext> PatternContext;
+ // C++17 TODO: make this a plain std::vector.
+ std::unique_ptr<std::vector<FileCheckString>> CheckStrings;
+
+public:
+ explicit FileCheck(FileCheckRequest Req);
+ ~FileCheck();
+
+ // Combines the check prefixes into a single regex so that we can efficiently
+ // scan for any of the set.
+ //
+ // The semantics are that the longest-match wins which matches our regex
+ // library.
+ Regex buildCheckPrefixRegex();
+
+ /// Reads the check file from \p Buffer and records the expected strings it
+ /// contains. Errors are reported against \p SM.
+ ///
+ /// Only expected strings whose prefix is one of those listed in \p PrefixRE
+ /// are recorded. \returns true in case of an error, false otherwise.
+ ///
+ /// If \p ImpPatBufferIDRange, then the range (inclusive start, exclusive end)
+ /// of IDs for source buffers added to \p SM for implicit patterns are
+ /// recorded in it. The range is empty if there are none.
+ bool
+ readCheckFile(SourceMgr &SM, StringRef Buffer, Regex &PrefixRE,
+ std::pair<unsigned, unsigned> *ImpPatBufferIDRange = nullptr);
+
+ bool ValidateCheckPrefixes();
+
+ /// Canonicalizes whitespaces in the file. Line endings are replaced with
+ /// UNIX-style '\n'.
+ StringRef CanonicalizeFile(MemoryBuffer &MB,
+ SmallVectorImpl<char> &OutputBuffer);
+
+ /// Checks the input to FileCheck provided in the \p Buffer against the
+ /// expected strings read from the check file and record diagnostics emitted
+ /// in \p Diags. Errors are recorded against \p SM.
+ ///
+ /// \returns false if the input fails to satisfy the checks.
+ bool checkInput(SourceMgr &SM, StringRef Buffer,
+ std::vector<FileCheckDiag> *Diags = nullptr);
+};
+
+} // namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Frontend/Directive/DirectiveBase.td b/contrib/libs/llvm12/include/llvm/Frontend/Directive/DirectiveBase.td
index ca5cc02b1a..e40f40f74c 100644
--- a/contrib/libs/llvm12/include/llvm/Frontend/Directive/DirectiveBase.td
+++ b/contrib/libs/llvm12/include/llvm/Frontend/Directive/DirectiveBase.td
@@ -35,10 +35,10 @@ class DirectiveLanguage {
// Make the enum values available in the namespace. This allows us to
// write something like Enum_X if we have a `using namespace cppNamespace`.
- bit makeEnumAvailableInNamespace = false;
+ bit makeEnumAvailableInNamespace = false;
// Generate include and macro to enable LLVM BitmaskEnum.
- bit enableBitmaskEnumInNamespace = false;
+ bit enableBitmaskEnumInNamespace = false;
// Header file included in the implementation code generated. Ususally the
// output file of the declaration code generation. Can be left blank.
@@ -46,26 +46,26 @@ class DirectiveLanguage {
// EnumSet class name used for clauses to generated the allowed clauses map.
string clauseEnumSetClass = "";
-
- // Class holding the clauses in the flang parse-tree.
- string flangClauseBaseClass = "";
+
+ // Class holding the clauses in the flang parse-tree.
+ string flangClauseBaseClass = "";
+}
+
+// Information about values accepted by enum-like clauses
+class ClauseVal<string n, int v, bit uv> {
+ // Name of the clause value.
+ string name = n;
+
+ // Integer value of the clause.
+ int value = v;
+
+ // Can user specify this value?
+ bit isUserValue = uv;
+
+ // Set clause value used by default when unknown.
+ bit isDefault = false;
}
-// Information about values accepted by enum-like clauses
-class ClauseVal<string n, int v, bit uv> {
- // Name of the clause value.
- string name = n;
-
- // Integer value of the clause.
- int value = v;
-
- // Can user specify this value?
- bit isUserValue = uv;
-
- // Set clause value used by default when unknown.
- bit isDefault = false;
-}
-
// Information about a specific clause.
class Clause<string c> {
// Name of the clause.
@@ -75,32 +75,32 @@ class Clause<string c> {
string alternativeName = "";
// Optional class holding value of the clause in clang AST.
- string clangClass = "";
+ string clangClass = "";
// Optional class holding value of the clause in flang AST.
- string flangClass = "";
-
- // If set to true, value is optional. Not optional by default.
- bit isValueOptional = false;
-
- // Name of enum when there is a list of allowed clause values.
- string enumClauseValue = "";
-
- // List of allowed clause values
- list<ClauseVal> allowedClauseValues = [];
- // If set to true, value class is part of a list. Single class by default.
- bit isValueList = false;
-
- // Define a default value such as "*".
- string defaultValue = "";
-
+ string flangClass = "";
+
+ // If set to true, value is optional. Not optional by default.
+ bit isValueOptional = false;
+
+ // Name of enum when there is a list of allowed clause values.
+ string enumClauseValue = "";
+
+ // List of allowed clause values
+ list<ClauseVal> allowedClauseValues = [];
+ // If set to true, value class is part of a list. Single class by default.
+ bit isValueList = false;
+
+ // Define a default value such as "*".
+ string defaultValue = "";
+
// Is clause implicit? If clause is set as implicit, the default kind will
// be return in get<LanguageName>ClauseKind instead of their own kind.
- bit isImplicit = false;
+ bit isImplicit = false;
- // Set clause used by default when unknown. Function returning the kind
+ // Set clause used by default when unknown. Function returning the kind
// of enumeration will use this clause as the default.
- bit isDefault = false;
+ bit isDefault = false;
}
// Hold information about clause validity by version.
@@ -124,10 +124,10 @@ class Directive<string d> {
// function.
string alternativeName = "";
- // Clauses cannot appear twice in the three allowed lists below. Also, since
- // required implies allowed, the same clause cannot appear in both the
- // allowedClauses and requiredClauses lists.
-
+ // Clauses cannot appear twice in the three allowed lists below. Also, since
+ // required implies allowed, the same clause cannot appear in both the
+ // allowedClauses and requiredClauses lists.
+
// List of allowed clauses for the directive.
list<VersionedClause> allowedClauses = [];
@@ -141,5 +141,5 @@ class Directive<string d> {
list<VersionedClause> requiredClauses = [];
// Set directive used by default when unknown.
- bit isDefault = false;
+ bit isDefault = false;
}
diff --git a/contrib/libs/llvm12/include/llvm/Frontend/OpenACC/ACC.td b/contrib/libs/llvm12/include/llvm/Frontend/OpenACC/ACC.td
index a18af1843f..6045a9ac2a 100644
--- a/contrib/libs/llvm12/include/llvm/Frontend/OpenACC/ACC.td
+++ b/contrib/libs/llvm12/include/llvm/Frontend/OpenACC/ACC.td
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This is the definition file for OpenACC 3.1 directives and clauses.
+// This is the definition file for OpenACC 3.1 directives and clauses.
//
//===----------------------------------------------------------------------===//
@@ -21,11 +21,11 @@ def OpenACC : DirectiveLanguage {
let cppNamespace = "acc"; // final namespace will be llvm::acc
let directivePrefix = "ACCD_";
let clausePrefix = "ACCC_";
- let makeEnumAvailableInNamespace = true;
- let enableBitmaskEnumInNamespace = true;
+ let makeEnumAvailableInNamespace = true;
+ let enableBitmaskEnumInNamespace = true;
let includeHeader = "llvm/Frontend/OpenACC/ACC.h.inc";
let clauseEnumSetClass = "AccClauseSet";
- let flangClauseBaseClass = "AccClause";
+ let flangClauseBaseClass = "AccClause";
}
//===----------------------------------------------------------------------===//
@@ -34,21 +34,21 @@ def OpenACC : DirectiveLanguage {
// 2.16.1
def ACCC_Async : Clause<"async"> {
- let flangClass = "ScalarIntExpr";
- let isValueOptional = true;
+ let flangClass = "ScalarIntExpr";
+ let isValueOptional = true;
}
-// 2.9.7
-def ACCC_Auto : Clause<"auto"> {}
-
-// 2.7.12
+// 2.9.7
+def ACCC_Auto : Clause<"auto"> {}
+
+// 2.7.12
def ACCC_Attach : Clause<"attach"> {
let flangClass = "AccObjectList";
}
// 2.15.1
def ACCC_Bind : Clause<"bind"> {
- let flangClass = "AccBindClause";
+ let flangClass = "AccBindClause";
}
// 2.12
@@ -60,49 +60,49 @@ def ACCC_Collapse : Clause<"collapse"> {
let flangClass = "ScalarIntConstantExpr";
}
-// 2.7.6
+// 2.7.6
def ACCC_Copy : Clause<"copy"> {
let flangClass = "AccObjectList";
}
-// 2.7.7
+// 2.7.7
def ACCC_Copyin : Clause<"copyin"> {
let flangClass = "AccObjectListWithModifier";
}
-// 2.7.8
+// 2.7.8
def ACCC_Copyout : Clause<"copyout"> {
let flangClass = "AccObjectListWithModifier";
}
-// 2.7.9
+// 2.7.9
def ACCC_Create : Clause<"create"> {
let flangClass = "AccObjectListWithModifier";
}
-// 2.5.15
-def ACC_Default_none : ClauseVal<"none", 1, 1> { let isDefault = 1; }
-def ACC_Default_present : ClauseVal<"present", 0, 1> {}
-
+// 2.5.15
+def ACC_Default_none : ClauseVal<"none", 1, 1> { let isDefault = 1; }
+def ACC_Default_present : ClauseVal<"present", 0, 1> {}
+
def ACCC_Default : Clause<"default"> {
let flangClass = "AccDefaultClause";
- let enumClauseValue = "DefaultValue";
- let allowedClauseValues = [
- ACC_Default_present,
- ACC_Default_none
- ];
+ let enumClauseValue = "DefaultValue";
+ let allowedClauseValues = [
+ ACC_Default_present,
+ ACC_Default_none
+ ];
}
-// 2.14.3
+// 2.14.3
def ACCC_DefaultAsync : Clause<"default_async"> {
let flangClass = "ScalarIntExpr";
}
-// 2.7.11
+// 2.7.11
def ACCC_Delete : Clause<"delete"> {
let flangClass = "AccObjectList";
}
-// 2.7.13
+// 2.7.13
def ACCC_Detach : Clause<"detach"> {
let flangClass = "AccObjectList";
}
@@ -112,41 +112,41 @@ def ACCC_Device : Clause<"device"> {
let flangClass = "AccObjectList";
}
-// 2.14.1 - 2.14.2
+// 2.14.1 - 2.14.2
def ACCC_DeviceNum : Clause<"device_num"> {
- let flangClass = "ScalarIntExpr";
+ let flangClass = "ScalarIntExpr";
}
-// 2.7.4
+// 2.7.4
def ACCC_DevicePtr : Clause<"deviceptr"> {
let flangClass = "AccObjectList";
}
-// 2.13.1
+// 2.13.1
def ACCC_DeviceResident : Clause<"device_resident"> {
let flangClass = "AccObjectList";
}
// 2.4
def ACCC_DeviceType : Clause<"device_type"> {
- let flangClass = "ScalarIntExpr";
- let defaultValue = "*";
- let isValueOptional = true;
- let isValueList = true;
+ let flangClass = "ScalarIntExpr";
+ let defaultValue = "*";
+ let isValueOptional = true;
+ let isValueList = true;
}
// 2.6.6
def ACCC_Finalize : Clause<"finalize"> {}
-// 2.5.13
+// 2.5.13
def ACCC_FirstPrivate : Clause<"firstprivate"> {
let flangClass = "AccObjectList";
}
// 2.9.2
def ACCC_Gang : Clause<"gang"> {
- let flangClass = "AccGangArgument";
- let isValueOptional = true;
+ let flangClass = "AccGangArgument";
+ let isValueOptional = true;
}
// 2.14.4
@@ -154,7 +154,7 @@ def ACCC_Host : Clause<"host"> {
let flangClass = "AccObjectList";
}
-// 2.5.5
+// 2.5.5
def ACCC_If : Clause <"if"> {
let flangClass = "ScalarLogicalExpr";
}
@@ -162,15 +162,15 @@ def ACCC_If : Clause <"if"> {
// 2.14.4
def ACCC_IfPresent : Clause<"if_present"> {}
-// 2.9.6
+// 2.9.6
def ACCC_Independent : Clause<"independent"> {}
-// 2.13.3
+// 2.13.3
def ACCC_Link : Clause<"link"> {
let flangClass = "AccObjectList";
}
-// 2.7.10
+// 2.7.10
def ACCC_NoCreate : Clause<"no_create"> {
let flangClass = "AccObjectList";
}
@@ -178,29 +178,29 @@ def ACCC_NoCreate : Clause<"no_create"> {
// 2.15.1
def ACCC_NoHost : Clause<"nohost"> {}
-// 2.5.9
+// 2.5.9
def ACCC_NumGangs : Clause<"num_gangs"> {
let flangClass = "ScalarIntExpr";
}
-// 2.5.10
+// 2.5.10
def ACCC_NumWorkers : Clause<"num_workers"> {
let flangClass = "ScalarIntExpr";
}
-// 2.7.5
+// 2.7.5
def ACCC_Present : Clause<"present"> {
let flangClass = "AccObjectList";
}
-// 2.5.12
+// 2.5.12
def ACCC_Private : Clause<"private"> {
let flangClass = "AccObjectList";
}
-// 2.9.8
+// 2.9.8
def ACCC_Tile : Clause <"tile"> {
- let flangClass = "AccTileExprList";
+ let flangClass = "AccTileExprList";
}
// 2.8.1
@@ -211,14 +211,14 @@ def ACCC_UseDevice : Clause <"use_device"> {
// 2.12
def ACCC_Read : Clause<"read"> {}
-// 2.5.14
+// 2.5.14
def ACCC_Reduction : Clause<"reduction"> {
let flangClass = "AccObjectListWithReduction";
}
-// 2.5.6
+// 2.5.6
def ACCC_Self : Clause<"self"> {
- let flangClass = "AccSelfClause";
+ let flangClass = "AccSelfClause";
}
// 2.9.5
@@ -226,32 +226,32 @@ def ACCC_Seq : Clause<"seq"> {}
// 2.9.4
def ACCC_Vector : Clause<"vector"> {
- let flangClass = "ScalarIntExpr";
- let isValueOptional = true;
+ let flangClass = "ScalarIntExpr";
+ let isValueOptional = true;
}
-// 2.5.11
+// 2.5.11
def ACCC_VectorLength : Clause<"vector_length"> {
let flangClass = "ScalarIntExpr";
}
// 2.16.2
def ACCC_Wait : Clause<"wait"> {
- let flangClass = "AccWaitArgument";
- let isValueOptional = true;
+ let flangClass = "AccWaitArgument";
+ let isValueOptional = true;
}
// 2.9.3
def ACCC_Worker: Clause<"worker"> {
- let flangClass = "ScalarIntExpr";
- let isValueOptional = true;
+ let flangClass = "ScalarIntExpr";
+ let isValueOptional = true;
}
// 2.12
def ACCC_Write : Clause<"write"> {}
def ACCC_Unknown : Clause<"unknown"> {
- let isDefault = true;
+ let isDefault = true;
}
//===----------------------------------------------------------------------===//
@@ -264,8 +264,8 @@ def ACC_Atomic : Directive<"atomic"> {}
// 2.6.5
def ACC_Data : Directive<"data"> {
let allowedOnceClauses = [
- VersionedClause<ACCC_If>,
- VersionedClause<ACCC_Default>
+ VersionedClause<ACCC_If>,
+ VersionedClause<ACCC_Default>
];
let requiredClauses = [
VersionedClause<ACCC_Attach>,
@@ -294,7 +294,7 @@ def ACC_Declare : Directive<"declare"> {
];
}
-// 2.5.3
+// 2.5.3
def ACC_Kernels : Directive<"kernels"> {
let allowedClauses = [
VersionedClause<ACCC_Attach>,
@@ -305,8 +305,8 @@ def ACC_Kernels : Directive<"kernels"> {
VersionedClause<ACCC_DeviceType>,
VersionedClause<ACCC_NoCreate>,
VersionedClause<ACCC_Present>,
- VersionedClause<ACCC_DevicePtr>,
- VersionedClause<ACCC_Wait>
+ VersionedClause<ACCC_DevicePtr>,
+ VersionedClause<ACCC_Wait>
];
let allowedOnceClauses = [
VersionedClause<ACCC_Async>,
@@ -315,7 +315,7 @@ def ACC_Kernels : Directive<"kernels"> {
VersionedClause<ACCC_NumGangs>,
VersionedClause<ACCC_NumWorkers>,
VersionedClause<ACCC_Self>,
- VersionedClause<ACCC_VectorLength>
+ VersionedClause<ACCC_VectorLength>
];
}
@@ -347,10 +347,10 @@ def ACC_Parallel : Directive<"parallel"> {
];
}
-// 2.5.2
+// 2.5.2
def ACC_Serial : Directive<"serial"> {
- // Spec line 950-951: clause is as for the parallel construct except that the
- // num_gangs, num_workers, and vector_length clauses are not permitted.
+ // Spec line 950-951: clause is as for the parallel construct except that the
+ // num_gangs, num_workers, and vector_length clauses are not permitted.
let allowedClauses = [
VersionedClause<ACCC_Attach>,
VersionedClause<ACCC_Copy>,
@@ -362,7 +362,7 @@ def ACC_Serial : Directive<"serial"> {
VersionedClause<ACCC_NoCreate>,
VersionedClause<ACCC_Present>,
VersionedClause<ACCC_Private>,
- VersionedClause<ACCC_FirstPrivate>,
+ VersionedClause<ACCC_FirstPrivate>,
VersionedClause<ACCC_Wait>
];
let allowedOnceClauses = [
@@ -425,15 +425,15 @@ def ACC_Routine : Directive<"routine"> {
// 2.14.3
def ACC_Set : Directive<"set"> {
let allowedOnceClauses = [
- VersionedClause<ACCC_DefaultAsync>,
- VersionedClause<ACCC_DeviceNum>,
- VersionedClause<ACCC_DeviceType>,
+ VersionedClause<ACCC_DefaultAsync>,
+ VersionedClause<ACCC_DeviceNum>,
+ VersionedClause<ACCC_DeviceType>,
VersionedClause<ACCC_If>
];
let requiredClauses = [
- // The three following clauses are also in allowedOnceClauses list due to
- // restriction 2255 - Two instances of the same clause may not appear on the
- // same directive.
+ // The three following clauses are also in allowedOnceClauses list due to
+ // restriction 2255 - Two instances of the same clause may not appear on the
+ // same directive.
VersionedClause<ACCC_DefaultAsync>,
VersionedClause<ACCC_DeviceNum>,
VersionedClause<ACCC_DeviceType>
@@ -503,8 +503,8 @@ def ACC_ExitData : Directive<"exit data"> {
VersionedClause<ACCC_Detach>
];
}
-
-// 2.8
+
+// 2.8
def ACC_HostData : Directive<"host_data"> {
let allowedClauses = [
VersionedClause<ACCC_If>,
@@ -626,5 +626,5 @@ def ACC_SerialLoop : Directive<"serial loop"> {
}
def ACC_Unknown : Directive<"unknown"> {
- let isDefault = true;
-}
+ let isDefault = true;
+}
diff --git a/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMP.inc b/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMP.inc
index 6ed64989bc..390fac5410 100644
--- a/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMP.inc
+++ b/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMP.inc
@@ -1,3507 +1,3507 @@
-#ifdef GEN_FLANG_DIRECTIVE_CLAUSE_SETS
-#undef GEN_FLANG_DIRECTIVE_CLAUSE_SETS
-
-namespace llvm {
-namespace omp {
-
- // Sets for allocate
-
- static OmpClauseSet allowedClauses_OMPD_allocate {
- llvm::omp::Clause::OMPC_allocator,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_allocate {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_allocate {
- };
-
- static OmpClauseSet requiredClauses_OMPD_allocate {
- };
-
- // Sets for assumes
-
- static OmpClauseSet allowedClauses_OMPD_assumes {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_assumes {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_assumes {
- };
-
- static OmpClauseSet requiredClauses_OMPD_assumes {
- };
-
- // Sets for atomic
-
- static OmpClauseSet allowedClauses_OMPD_atomic {
- llvm::omp::Clause::OMPC_read,
- llvm::omp::Clause::OMPC_write,
- llvm::omp::Clause::OMPC_update,
- llvm::omp::Clause::OMPC_capture,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_atomic {
- llvm::omp::Clause::OMPC_seq_cst,
- llvm::omp::Clause::OMPC_acq_rel,
- llvm::omp::Clause::OMPC_acquire,
- llvm::omp::Clause::OMPC_release,
- llvm::omp::Clause::OMPC_relaxed,
- llvm::omp::Clause::OMPC_hint,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_atomic {
- };
-
- static OmpClauseSet requiredClauses_OMPD_atomic {
- };
-
- // Sets for barrier
-
- static OmpClauseSet allowedClauses_OMPD_barrier {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_barrier {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_barrier {
- };
-
- static OmpClauseSet requiredClauses_OMPD_barrier {
- };
-
- // Sets for begin assumes
-
- static OmpClauseSet allowedClauses_OMPD_begin_assumes {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_begin_assumes {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_begin_assumes {
- };
-
- static OmpClauseSet requiredClauses_OMPD_begin_assumes {
- };
-
- // Sets for begin declare variant
-
- static OmpClauseSet allowedClauses_OMPD_begin_declare_variant {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_begin_declare_variant {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_begin_declare_variant {
- };
-
- static OmpClauseSet requiredClauses_OMPD_begin_declare_variant {
- };
-
- // Sets for cancel
-
- static OmpClauseSet allowedClauses_OMPD_cancel {
- llvm::omp::Clause::OMPC_if,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_cancel {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_cancel {
- };
-
- static OmpClauseSet requiredClauses_OMPD_cancel {
- };
-
- // Sets for cancellation point
-
- static OmpClauseSet allowedClauses_OMPD_cancellation_point {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_cancellation_point {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_cancellation_point {
- };
-
- static OmpClauseSet requiredClauses_OMPD_cancellation_point {
- };
-
- // Sets for critical
-
- static OmpClauseSet allowedClauses_OMPD_critical {
- llvm::omp::Clause::OMPC_hint,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_critical {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_critical {
- };
-
- static OmpClauseSet requiredClauses_OMPD_critical {
- };
-
- // Sets for declare mapper
-
- static OmpClauseSet allowedClauses_OMPD_declare_mapper {
- llvm::omp::Clause::OMPC_map,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_declare_mapper {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_declare_mapper {
- };
-
- static OmpClauseSet requiredClauses_OMPD_declare_mapper {
- };
-
- // Sets for declare reduction
-
- static OmpClauseSet allowedClauses_OMPD_declare_reduction {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_declare_reduction {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_declare_reduction {
- };
-
- static OmpClauseSet requiredClauses_OMPD_declare_reduction {
- };
-
- // Sets for declare simd
-
- static OmpClauseSet allowedClauses_OMPD_declare_simd {
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_uniform,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_declare_simd {
- llvm::omp::Clause::OMPC_simdlen,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_declare_simd {
- llvm::omp::Clause::OMPC_inbranch,
- llvm::omp::Clause::OMPC_notinbranch,
- };
-
- static OmpClauseSet requiredClauses_OMPD_declare_simd {
- };
-
- // Sets for declare target
-
- static OmpClauseSet allowedClauses_OMPD_declare_target {
- llvm::omp::Clause::OMPC_to,
- llvm::omp::Clause::OMPC_link,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_declare_target {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_declare_target {
- };
-
- static OmpClauseSet requiredClauses_OMPD_declare_target {
- };
-
- // Sets for declare variant
-
- static OmpClauseSet allowedClauses_OMPD_declare_variant {
- llvm::omp::Clause::OMPC_match,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_declare_variant {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_declare_variant {
- };
-
- static OmpClauseSet requiredClauses_OMPD_declare_variant {
- };
-
- // Sets for depobj
-
- static OmpClauseSet allowedClauses_OMPD_depobj {
- llvm::omp::Clause::OMPC_depend,
- llvm::omp::Clause::OMPC_destroy,
- llvm::omp::Clause::OMPC_update,
- llvm::omp::Clause::OMPC_depobj,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_depobj {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_depobj {
- };
-
- static OmpClauseSet requiredClauses_OMPD_depobj {
- };
-
- // Sets for distribute
-
- static OmpClauseSet allowedClauses_OMPD_distribute {
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_allocate,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_distribute {
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_dist_schedule,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_distribute {
- };
-
- static OmpClauseSet requiredClauses_OMPD_distribute {
- };
-
- // Sets for distribute parallel do
-
- static OmpClauseSet allowedClauses_OMPD_distribute_parallel_do {
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_order,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_linear,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_distribute_parallel_do {
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_dist_schedule,
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_ordered,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_distribute_parallel_do {
- };
-
- static OmpClauseSet requiredClauses_OMPD_distribute_parallel_do {
- };
-
- // Sets for distribute parallel do simd
-
- static OmpClauseSet allowedClauses_OMPD_distribute_parallel_do_simd {
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_dist_schedule,
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_nontemporal,
- llvm::omp::Clause::OMPC_order,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_distribute_parallel_do_simd {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_distribute_parallel_do_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_distribute_parallel_do_simd {
- };
-
- // Sets for distribute parallel for
-
- static OmpClauseSet allowedClauses_OMPD_distribute_parallel_for {
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_dist_schedule,
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_order,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_distribute_parallel_for {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_distribute_parallel_for {
- };
-
- static OmpClauseSet requiredClauses_OMPD_distribute_parallel_for {
- };
-
- // Sets for distribute parallel for simd
-
- static OmpClauseSet allowedClauses_OMPD_distribute_parallel_for_simd {
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_dist_schedule,
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_nontemporal,
- llvm::omp::Clause::OMPC_order,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_distribute_parallel_for_simd {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_distribute_parallel_for_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_distribute_parallel_for_simd {
- };
-
- // Sets for distribute simd
-
- static OmpClauseSet allowedClauses_OMPD_distribute_simd {
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_nontemporal,
- llvm::omp::Clause::OMPC_order,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_reduction,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_distribute_simd {
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_dist_schedule,
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_ordered,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_distribute_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_distribute_simd {
- };
-
- // Sets for do
-
- static OmpClauseSet allowedClauses_OMPD_do {
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_reduction,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_do {
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_ordered,
- llvm::omp::Clause::OMPC_nowait,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_do {
- };
-
- static OmpClauseSet requiredClauses_OMPD_do {
- };
-
- // Sets for do simd
-
- static OmpClauseSet allowedClauses_OMPD_do_simd {
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_reduction,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_do_simd {
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_ordered,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- llvm::omp::Clause::OMPC_nowait,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_do_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_do_simd {
- };
-
- // Sets for end assumes
-
- static OmpClauseSet allowedClauses_OMPD_end_assumes {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_end_assumes {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_end_assumes {
- };
-
- static OmpClauseSet requiredClauses_OMPD_end_assumes {
- };
-
- // Sets for end declare target
-
- static OmpClauseSet allowedClauses_OMPD_end_declare_target {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_end_declare_target {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_end_declare_target {
- };
-
- static OmpClauseSet requiredClauses_OMPD_end_declare_target {
- };
-
- // Sets for end declare variant
-
- static OmpClauseSet allowedClauses_OMPD_end_declare_variant {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_end_declare_variant {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_end_declare_variant {
- };
-
- static OmpClauseSet requiredClauses_OMPD_end_declare_variant {
- };
-
- // Sets for end do
-
- static OmpClauseSet allowedClauses_OMPD_end_do {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_end_do {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_end_do {
- };
-
- static OmpClauseSet requiredClauses_OMPD_end_do {
- };
-
- // Sets for end do simd
-
- static OmpClauseSet allowedClauses_OMPD_end_do_simd {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_end_do_simd {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_end_do_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_end_do_simd {
- };
-
- // Sets for end sections
-
- static OmpClauseSet allowedClauses_OMPD_end_sections {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_end_sections {
- llvm::omp::Clause::OMPC_nowait,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_end_sections {
- };
-
- static OmpClauseSet requiredClauses_OMPD_end_sections {
- };
-
- // Sets for end single
-
- static OmpClauseSet allowedClauses_OMPD_end_single {
- llvm::omp::Clause::OMPC_copyprivate,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_end_single {
- llvm::omp::Clause::OMPC_nowait,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_end_single {
- };
-
- static OmpClauseSet requiredClauses_OMPD_end_single {
- };
-
- // Sets for end workshare
-
- static OmpClauseSet allowedClauses_OMPD_end_workshare {
- llvm::omp::Clause::OMPC_nowait,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_end_workshare {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_end_workshare {
- };
-
- static OmpClauseSet requiredClauses_OMPD_end_workshare {
- };
-
- // Sets for flush
-
- static OmpClauseSet allowedClauses_OMPD_flush {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_flush {
- llvm::omp::Clause::OMPC_acq_rel,
- llvm::omp::Clause::OMPC_acquire,
- llvm::omp::Clause::OMPC_release,
- llvm::omp::Clause::OMPC_flush,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_flush {
- };
-
- static OmpClauseSet requiredClauses_OMPD_flush {
- };
-
- // Sets for for
-
- static OmpClauseSet allowedClauses_OMPD_for {
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_ordered,
- llvm::omp::Clause::OMPC_nowait,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_order,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_for {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_for {
- };
-
- static OmpClauseSet requiredClauses_OMPD_for {
- };
-
- // Sets for for simd
-
- static OmpClauseSet allowedClauses_OMPD_for_simd {
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_nowait,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_ordered,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_nontemporal,
- llvm::omp::Clause::OMPC_order,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_for_simd {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_for_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_for_simd {
- };
-
- // Sets for master
-
- static OmpClauseSet allowedClauses_OMPD_master {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_master {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_master {
- };
-
- static OmpClauseSet requiredClauses_OMPD_master {
- };
-
- // Sets for master taskloop
-
- static OmpClauseSet allowedClauses_OMPD_master_taskloop {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_final,
- llvm::omp::Clause::OMPC_untied,
- llvm::omp::Clause::OMPC_mergeable,
- llvm::omp::Clause::OMPC_priority,
- llvm::omp::Clause::OMPC_grainsize,
- llvm::omp::Clause::OMPC_nogroup,
- llvm::omp::Clause::OMPC_num_tasks,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_in_reduction,
- llvm::omp::Clause::OMPC_allocate,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_master_taskloop {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_master_taskloop {
- };
-
- static OmpClauseSet requiredClauses_OMPD_master_taskloop {
- };
-
- // Sets for master taskloop simd
-
- static OmpClauseSet allowedClauses_OMPD_master_taskloop_simd {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_final,
- llvm::omp::Clause::OMPC_untied,
- llvm::omp::Clause::OMPC_mergeable,
- llvm::omp::Clause::OMPC_priority,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- llvm::omp::Clause::OMPC_grainsize,
- llvm::omp::Clause::OMPC_nogroup,
- llvm::omp::Clause::OMPC_num_tasks,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_in_reduction,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_nontemporal,
- llvm::omp::Clause::OMPC_order,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_master_taskloop_simd {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_master_taskloop_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_master_taskloop_simd {
- };
-
- // Sets for ordered
-
- static OmpClauseSet allowedClauses_OMPD_ordered {
- llvm::omp::Clause::OMPC_threads,
- llvm::omp::Clause::OMPC_simd,
- llvm::omp::Clause::OMPC_depend,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_ordered {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_ordered {
- };
-
- static OmpClauseSet requiredClauses_OMPD_ordered {
- };
-
- // Sets for parallel
-
- static OmpClauseSet allowedClauses_OMPD_parallel {
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_allocate,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_parallel {
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_proc_bind,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_parallel {
- };
-
- static OmpClauseSet requiredClauses_OMPD_parallel {
- };
-
- // Sets for parallel do
-
- static OmpClauseSet allowedClauses_OMPD_parallel_do {
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_linear,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_parallel_do {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_ordered,
- llvm::omp::Clause::OMPC_collapse,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_parallel_do {
- };
-
- static OmpClauseSet requiredClauses_OMPD_parallel_do {
- };
-
- // Sets for parallel do simd
-
- static OmpClauseSet allowedClauses_OMPD_parallel_do_simd {
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_nontemporal,
- llvm::omp::Clause::OMPC_order,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_parallel_do_simd {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_ordered,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_parallel_do_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_parallel_do_simd {
- };
-
- // Sets for parallel for
-
- static OmpClauseSet allowedClauses_OMPD_parallel_for {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_ordered,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_order,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_parallel_for {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_parallel_for {
- };
-
- static OmpClauseSet requiredClauses_OMPD_parallel_for {
- };
-
- // Sets for parallel for simd
-
- static OmpClauseSet allowedClauses_OMPD_parallel_for_simd {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_ordered,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_nontemporal,
- llvm::omp::Clause::OMPC_order,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_parallel_for_simd {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_parallel_for_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_parallel_for_simd {
- };
-
- // Sets for parallel master
-
- static OmpClauseSet allowedClauses_OMPD_parallel_master {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_allocate,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_parallel_master {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_parallel_master {
- };
-
- static OmpClauseSet requiredClauses_OMPD_parallel_master {
- };
-
- // Sets for parallel master taskloop
-
- static OmpClauseSet allowedClauses_OMPD_parallel_master_taskloop {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_final,
- llvm::omp::Clause::OMPC_untied,
- llvm::omp::Clause::OMPC_mergeable,
- llvm::omp::Clause::OMPC_priority,
- llvm::omp::Clause::OMPC_grainsize,
- llvm::omp::Clause::OMPC_nogroup,
- llvm::omp::Clause::OMPC_num_tasks,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_copyin,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_parallel_master_taskloop {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_parallel_master_taskloop {
- };
-
- static OmpClauseSet requiredClauses_OMPD_parallel_master_taskloop {
- };
-
- // Sets for parallel master taskloop simd
-
- static OmpClauseSet allowedClauses_OMPD_parallel_master_taskloop_simd {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_final,
- llvm::omp::Clause::OMPC_untied,
- llvm::omp::Clause::OMPC_mergeable,
- llvm::omp::Clause::OMPC_priority,
- llvm::omp::Clause::OMPC_grainsize,
- llvm::omp::Clause::OMPC_nogroup,
- llvm::omp::Clause::OMPC_num_tasks,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- llvm::omp::Clause::OMPC_nontemporal,
- llvm::omp::Clause::OMPC_order,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_parallel_master_taskloop_simd {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_parallel_master_taskloop_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_parallel_master_taskloop_simd {
- };
-
- // Sets for parallel sections
-
- static OmpClauseSet allowedClauses_OMPD_parallel_sections {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_allocate,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_parallel_sections {
- llvm::omp::Clause::OMPC_num_threads,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_parallel_sections {
- };
-
- static OmpClauseSet requiredClauses_OMPD_parallel_sections {
- };
-
- // Sets for parallel workshare
-
- static OmpClauseSet allowedClauses_OMPD_parallel_workshare {
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_shared,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_parallel_workshare {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_proc_bind,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_parallel_workshare {
- };
-
- static OmpClauseSet requiredClauses_OMPD_parallel_workshare {
- };
-
- // Sets for requires
-
- static OmpClauseSet allowedClauses_OMPD_requires {
- llvm::omp::Clause::OMPC_unified_address,
- llvm::omp::Clause::OMPC_unified_shared_memory,
- llvm::omp::Clause::OMPC_reverse_offload,
- llvm::omp::Clause::OMPC_dynamic_allocators,
- llvm::omp::Clause::OMPC_atomic_default_mem_order,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_requires {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_requires {
- };
-
- static OmpClauseSet requiredClauses_OMPD_requires {
- };
-
- // Sets for scan
-
- static OmpClauseSet allowedClauses_OMPD_scan {
- llvm::omp::Clause::OMPC_inclusive,
- llvm::omp::Clause::OMPC_exclusive,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_scan {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_scan {
- };
-
- static OmpClauseSet requiredClauses_OMPD_scan {
- };
-
- // Sets for section
-
- static OmpClauseSet allowedClauses_OMPD_section {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_section {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_section {
- };
-
- static OmpClauseSet requiredClauses_OMPD_section {
- };
-
- // Sets for sections
-
- static OmpClauseSet allowedClauses_OMPD_sections {
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_nowait,
- llvm::omp::Clause::OMPC_allocate,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_sections {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_sections {
- };
-
- static OmpClauseSet requiredClauses_OMPD_sections {
- };
-
- // Sets for simd
-
- static OmpClauseSet allowedClauses_OMPD_simd {
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_nontemporal,
- llvm::omp::Clause::OMPC_order,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_simd {
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- llvm::omp::Clause::OMPC_if,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_simd {
- };
-
- // Sets for single
-
- static OmpClauseSet allowedClauses_OMPD_single {
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_copyprivate,
- llvm::omp::Clause::OMPC_nowait,
- llvm::omp::Clause::OMPC_allocate,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_single {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_single {
- };
-
- static OmpClauseSet requiredClauses_OMPD_single {
- };
-
- // Sets for target
-
- static OmpClauseSet allowedClauses_OMPD_target {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_map,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_depend,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_is_device_ptr,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_uses_allocators,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_target {
- llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_defaultmap,
- llvm::omp::Clause::OMPC_nowait,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_target {
- };
-
- static OmpClauseSet requiredClauses_OMPD_target {
- };
-
- // Sets for target data
-
- static OmpClauseSet allowedClauses_OMPD_target_data {
- llvm::omp::Clause::OMPC_use_device_ptr,
- llvm::omp::Clause::OMPC_use_device_addr,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_target_data {
- llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_if,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_target_data {
- };
-
- static OmpClauseSet requiredClauses_OMPD_target_data {
- llvm::omp::Clause::OMPC_map,
- };
-
- // Sets for target enter data
-
- static OmpClauseSet allowedClauses_OMPD_target_enter_data {
- llvm::omp::Clause::OMPC_depend,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_target_enter_data {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_nowait,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_target_enter_data {
- };
-
- static OmpClauseSet requiredClauses_OMPD_target_enter_data {
- llvm::omp::Clause::OMPC_map,
- };
-
- // Sets for target exit data
-
- static OmpClauseSet allowedClauses_OMPD_target_exit_data {
- llvm::omp::Clause::OMPC_depend,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_target_exit_data {
- llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_nowait,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_target_exit_data {
- };
-
- static OmpClauseSet requiredClauses_OMPD_target_exit_data {
- llvm::omp::Clause::OMPC_map,
- };
-
- // Sets for target parallel
-
- static OmpClauseSet allowedClauses_OMPD_target_parallel {
- llvm::omp::Clause::OMPC_map,
- llvm::omp::Clause::OMPC_nowait,
- llvm::omp::Clause::OMPC_depend,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_is_device_ptr,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_uses_allocators,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_target_parallel {
- llvm::omp::Clause::OMPC_defaultmap,
- llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_proc_bind,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_target_parallel {
- };
-
- static OmpClauseSet requiredClauses_OMPD_target_parallel {
- };
-
- // Sets for target parallel do
-
- static OmpClauseSet allowedClauses_OMPD_target_parallel_do {
- llvm::omp::Clause::OMPC_map,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_depend,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_is_device_ptr,
- llvm::omp::Clause::OMPC_allocator,
- llvm::omp::Clause::OMPC_order,
- llvm::omp::Clause::OMPC_uses_allocators,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_copyin,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_target_parallel_do {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_defaultmap,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_ordered,
- llvm::omp::Clause::OMPC_nowait,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_target_parallel_do {
- };
-
- static OmpClauseSet requiredClauses_OMPD_target_parallel_do {
- };
-
- // Sets for target parallel do simd
-
- static OmpClauseSet allowedClauses_OMPD_target_parallel_do_simd {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_map,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_nowait,
- llvm::omp::Clause::OMPC_depend,
- llvm::omp::Clause::OMPC_defaultmap,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_ordered,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_is_device_ptr,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_nontemporal,
- llvm::omp::Clause::OMPC_order,
- llvm::omp::Clause::OMPC_uses_allocators,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_target_parallel_do_simd {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_target_parallel_do_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_target_parallel_do_simd {
- };
-
- // Sets for target parallel for
-
- static OmpClauseSet allowedClauses_OMPD_target_parallel_for {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_map,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_nowait,
- llvm::omp::Clause::OMPC_depend,
- llvm::omp::Clause::OMPC_defaultmap,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_ordered,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_is_device_ptr,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_order,
- llvm::omp::Clause::OMPC_uses_allocators,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_target_parallel_for {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_target_parallel_for {
- };
-
- static OmpClauseSet requiredClauses_OMPD_target_parallel_for {
- };
-
- // Sets for target parallel for simd
-
- static OmpClauseSet allowedClauses_OMPD_target_parallel_for_simd {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_map,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_nowait,
- llvm::omp::Clause::OMPC_depend,
- llvm::omp::Clause::OMPC_defaultmap,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_ordered,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_is_device_ptr,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_nontemporal,
- llvm::omp::Clause::OMPC_order,
- llvm::omp::Clause::OMPC_uses_allocators,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_target_parallel_for_simd {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_target_parallel_for_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_target_parallel_for_simd {
- };
-
- // Sets for target simd
-
- static OmpClauseSet allowedClauses_OMPD_target_simd {
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_depend,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_is_device_ptr,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_map,
- llvm::omp::Clause::OMPC_nontemporal,
- llvm::omp::Clause::OMPC_nowait,
- llvm::omp::Clause::OMPC_order,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_uses_allocators,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_target_simd {
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_defaultmap,
- llvm::omp::Clause::OMPC_schedule,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_target_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_target_simd {
- };
-
- // Sets for target teams
-
- static OmpClauseSet allowedClauses_OMPD_target_teams {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_map,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_depend,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_is_device_ptr,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_uses_allocators,
- llvm::omp::Clause::OMPC_shared,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_target_teams {
- llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_nowait,
- llvm::omp::Clause::OMPC_defaultmap,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_num_teams,
- llvm::omp::Clause::OMPC_thread_limit,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_target_teams {
- };
-
- static OmpClauseSet requiredClauses_OMPD_target_teams {
- };
-
- // Sets for target teams distribute
-
- static OmpClauseSet allowedClauses_OMPD_target_teams_distribute {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_map,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_depend,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_is_device_ptr,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_uses_allocators,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_lastprivate,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_target_teams_distribute {
- llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_nowait,
- llvm::omp::Clause::OMPC_defaultmap,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_num_teams,
- llvm::omp::Clause::OMPC_thread_limit,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_dist_schedule,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_target_teams_distribute {
- };
-
- static OmpClauseSet requiredClauses_OMPD_target_teams_distribute {
- };
-
- // Sets for target teams distribute parallel do
-
- static OmpClauseSet allowedClauses_OMPD_target_teams_distribute_parallel_do {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_map,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_depend,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_is_device_ptr,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_uses_allocators,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_ordered,
- llvm::omp::Clause::OMPC_order,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_target_teams_distribute_parallel_do {
- llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_defaultmap,
- llvm::omp::Clause::OMPC_nowait,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_num_teams,
- llvm::omp::Clause::OMPC_thread_limit,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_dist_schedule,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_schedule,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_target_teams_distribute_parallel_do {
- };
-
- static OmpClauseSet requiredClauses_OMPD_target_teams_distribute_parallel_do {
- };
-
- // Sets for target teams distribute parallel do simd
-
- static OmpClauseSet allowedClauses_OMPD_target_teams_distribute_parallel_do_simd {
- llvm::omp::Clause::OMPC_map,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_depend,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_is_device_ptr,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_uses_allocators,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_ordered,
- llvm::omp::Clause::OMPC_order,
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_nontemporal,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_target_teams_distribute_parallel_do_simd {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_nowait,
- llvm::omp::Clause::OMPC_defaultmap,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_num_teams,
- llvm::omp::Clause::OMPC_thread_limit,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_dist_schedule,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_target_teams_distribute_parallel_do_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_target_teams_distribute_parallel_do_simd {
- };
-
- // Sets for target teams distribute parallel for
-
- static OmpClauseSet allowedClauses_OMPD_target_teams_distribute_parallel_for {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_map,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_nowait,
- llvm::omp::Clause::OMPC_depend,
- llvm::omp::Clause::OMPC_defaultmap,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_is_device_ptr,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_num_teams,
- llvm::omp::Clause::OMPC_thread_limit,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_dist_schedule,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_order,
- llvm::omp::Clause::OMPC_uses_allocators,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_target_teams_distribute_parallel_for {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_target_teams_distribute_parallel_for {
- };
-
- static OmpClauseSet requiredClauses_OMPD_target_teams_distribute_parallel_for {
- };
-
- // Sets for target teams distribute parallel for simd
-
- static OmpClauseSet allowedClauses_OMPD_target_teams_distribute_parallel_for_simd {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_map,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_nowait,
- llvm::omp::Clause::OMPC_depend,
- llvm::omp::Clause::OMPC_defaultmap,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_is_device_ptr,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_num_teams,
- llvm::omp::Clause::OMPC_thread_limit,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_dist_schedule,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_nontemporal,
- llvm::omp::Clause::OMPC_order,
- llvm::omp::Clause::OMPC_uses_allocators,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_target_teams_distribute_parallel_for_simd {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_target_teams_distribute_parallel_for_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_target_teams_distribute_parallel_for_simd {
- };
-
- // Sets for target teams distribute simd
-
- static OmpClauseSet allowedClauses_OMPD_target_teams_distribute_simd {
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_depend,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_is_device_ptr,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_map,
- llvm::omp::Clause::OMPC_nontemporal,
- llvm::omp::Clause::OMPC_order,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_uses_allocators,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_target_teams_distribute_simd {
- llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_defaultmap,
- llvm::omp::Clause::OMPC_nowait,
- llvm::omp::Clause::OMPC_num_teams,
- llvm::omp::Clause::OMPC_thread_limit,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_dist_schedule,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_target_teams_distribute_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_target_teams_distribute_simd {
- };
-
- // Sets for target update
-
- static OmpClauseSet allowedClauses_OMPD_target_update {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_to,
- llvm::omp::Clause::OMPC_from,
- llvm::omp::Clause::OMPC_nowait,
- llvm::omp::Clause::OMPC_depend,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_target_update {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_target_update {
- };
-
- static OmpClauseSet requiredClauses_OMPD_target_update {
- };
-
- // Sets for task
-
- static OmpClauseSet allowedClauses_OMPD_task {
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_untied,
- llvm::omp::Clause::OMPC_mergeable,
- llvm::omp::Clause::OMPC_depend,
- llvm::omp::Clause::OMPC_in_reduction,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_detach,
- llvm::omp::Clause::OMPC_affinity,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_task {
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_final,
- llvm::omp::Clause::OMPC_priority,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_task {
- };
-
- static OmpClauseSet requiredClauses_OMPD_task {
- };
-
- // Sets for taskgroup
-
- static OmpClauseSet allowedClauses_OMPD_taskgroup {
- llvm::omp::Clause::OMPC_task_reduction,
- llvm::omp::Clause::OMPC_allocate,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_taskgroup {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_taskgroup {
- };
-
- static OmpClauseSet requiredClauses_OMPD_taskgroup {
- };
-
- // Sets for taskloop
-
- static OmpClauseSet allowedClauses_OMPD_taskloop {
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_untied,
- llvm::omp::Clause::OMPC_mergeable,
- llvm::omp::Clause::OMPC_nogroup,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_in_reduction,
- llvm::omp::Clause::OMPC_allocate,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_taskloop {
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_final,
- llvm::omp::Clause::OMPC_priority,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_taskloop {
- llvm::omp::Clause::OMPC_grainsize,
- llvm::omp::Clause::OMPC_num_tasks,
- };
-
- static OmpClauseSet requiredClauses_OMPD_taskloop {
- };
-
- // Sets for taskloop simd
-
- static OmpClauseSet allowedClauses_OMPD_taskloop_simd {
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_in_reduction,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_mergeable,
- llvm::omp::Clause::OMPC_nogroup,
- llvm::omp::Clause::OMPC_nontemporal,
- llvm::omp::Clause::OMPC_order,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_untied,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_taskloop_simd {
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- llvm::omp::Clause::OMPC_final,
- llvm::omp::Clause::OMPC_priority,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_taskloop_simd {
- llvm::omp::Clause::OMPC_grainsize,
- llvm::omp::Clause::OMPC_num_tasks,
- };
-
- static OmpClauseSet requiredClauses_OMPD_taskloop_simd {
- };
-
- // Sets for taskwait
-
- static OmpClauseSet allowedClauses_OMPD_taskwait {
- llvm::omp::Clause::OMPC_depend,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_taskwait {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_taskwait {
- };
-
- static OmpClauseSet requiredClauses_OMPD_taskwait {
- };
-
- // Sets for taskyield
-
- static OmpClauseSet allowedClauses_OMPD_taskyield {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_taskyield {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_taskyield {
- };
-
- static OmpClauseSet requiredClauses_OMPD_taskyield {
- };
-
- // Sets for teams
-
- static OmpClauseSet allowedClauses_OMPD_teams {
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_allocate,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_teams {
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_num_teams,
- llvm::omp::Clause::OMPC_thread_limit,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_teams {
- };
-
- static OmpClauseSet requiredClauses_OMPD_teams {
- };
-
- // Sets for teams distribute
-
- static OmpClauseSet allowedClauses_OMPD_teams_distribute {
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_num_teams,
- llvm::omp::Clause::OMPC_thread_limit,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_dist_schedule,
- llvm::omp::Clause::OMPC_allocate,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_teams_distribute {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_teams_distribute {
- };
-
- static OmpClauseSet requiredClauses_OMPD_teams_distribute {
- };
-
- // Sets for teams distribute parallel do
-
- static OmpClauseSet allowedClauses_OMPD_teams_distribute_parallel_do {
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_linear,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_teams_distribute_parallel_do {
- llvm::omp::Clause::OMPC_num_teams,
- llvm::omp::Clause::OMPC_thread_limit,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_dist_schedule,
- llvm::omp::Clause::OMPC_ordered,
- llvm::omp::Clause::OMPC_order,
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_schedule,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_teams_distribute_parallel_do {
- };
-
- static OmpClauseSet requiredClauses_OMPD_teams_distribute_parallel_do {
- };
-
- // Sets for teams distribute parallel do simd
-
- static OmpClauseSet allowedClauses_OMPD_teams_distribute_parallel_do_simd {
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_order,
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_nontemporal,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_teams_distribute_parallel_do_simd {
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_num_teams,
- llvm::omp::Clause::OMPC_thread_limit,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_dist_schedule,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- llvm::omp::Clause::OMPC_if,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_teams_distribute_parallel_do_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_teams_distribute_parallel_do_simd {
- };
-
- // Sets for teams distribute parallel for
-
- static OmpClauseSet allowedClauses_OMPD_teams_distribute_parallel_for {
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_dist_schedule,
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_num_teams,
- llvm::omp::Clause::OMPC_thread_limit,
- llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_order,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_teams_distribute_parallel_for {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_teams_distribute_parallel_for {
- };
-
- static OmpClauseSet requiredClauses_OMPD_teams_distribute_parallel_for {
- };
-
- // Sets for teams distribute parallel for simd
-
- static OmpClauseSet allowedClauses_OMPD_teams_distribute_parallel_for_simd {
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_dist_schedule,
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_proc_bind,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- llvm::omp::Clause::OMPC_num_teams,
- llvm::omp::Clause::OMPC_thread_limit,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_nontemporal,
- llvm::omp::Clause::OMPC_order,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_teams_distribute_parallel_for_simd {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_teams_distribute_parallel_for_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_teams_distribute_parallel_for_simd {
- };
-
- // Sets for teams distribute simd
-
- static OmpClauseSet allowedClauses_OMPD_teams_distribute_simd {
- llvm::omp::Clause::OMPC_aligned,
- llvm::omp::Clause::OMPC_allocate,
- llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_nontemporal,
- llvm::omp::Clause::OMPC_order,
- llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_reduction,
- llvm::omp::Clause::OMPC_shared,
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_teams_distribute_simd {
- llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_dist_schedule,
- llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_teams,
- llvm::omp::Clause::OMPC_safelen,
- llvm::omp::Clause::OMPC_simdlen,
- llvm::omp::Clause::OMPC_thread_limit,
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_teams_distribute_simd {
- };
-
- static OmpClauseSet requiredClauses_OMPD_teams_distribute_simd {
- };
-
- // Sets for threadprivate
-
- static OmpClauseSet allowedClauses_OMPD_threadprivate {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_threadprivate {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_threadprivate {
- };
-
- static OmpClauseSet requiredClauses_OMPD_threadprivate {
- };
-
- // Sets for unknown
-
- static OmpClauseSet allowedClauses_OMPD_unknown {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_unknown {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_unknown {
- };
-
- static OmpClauseSet requiredClauses_OMPD_unknown {
- };
-
- // Sets for workshare
-
- static OmpClauseSet allowedClauses_OMPD_workshare {
- };
-
- static OmpClauseSet allowedOnceClauses_OMPD_workshare {
- };
-
- static OmpClauseSet allowedExclusiveClauses_OMPD_workshare {
- };
-
- static OmpClauseSet requiredClauses_OMPD_workshare {
- };
-} // namespace omp
-} // namespace llvm
-
-#endif // GEN_FLANG_DIRECTIVE_CLAUSE_SETS
-
-#ifdef GEN_FLANG_DIRECTIVE_CLAUSE_MAP
-#undef GEN_FLANG_DIRECTIVE_CLAUSE_MAP
-
-{
- {llvm::omp::Directive::OMPD_allocate,
- {
- llvm::omp::allowedClauses_OMPD_allocate,
- llvm::omp::allowedOnceClauses_OMPD_allocate,
- llvm::omp::allowedExclusiveClauses_OMPD_allocate,
- llvm::omp::requiredClauses_OMPD_allocate,
- }
- },
- {llvm::omp::Directive::OMPD_assumes,
- {
- llvm::omp::allowedClauses_OMPD_assumes,
- llvm::omp::allowedOnceClauses_OMPD_assumes,
- llvm::omp::allowedExclusiveClauses_OMPD_assumes,
- llvm::omp::requiredClauses_OMPD_assumes,
- }
- },
- {llvm::omp::Directive::OMPD_atomic,
- {
- llvm::omp::allowedClauses_OMPD_atomic,
- llvm::omp::allowedOnceClauses_OMPD_atomic,
- llvm::omp::allowedExclusiveClauses_OMPD_atomic,
- llvm::omp::requiredClauses_OMPD_atomic,
- }
- },
- {llvm::omp::Directive::OMPD_barrier,
- {
- llvm::omp::allowedClauses_OMPD_barrier,
- llvm::omp::allowedOnceClauses_OMPD_barrier,
- llvm::omp::allowedExclusiveClauses_OMPD_barrier,
- llvm::omp::requiredClauses_OMPD_barrier,
- }
- },
- {llvm::omp::Directive::OMPD_begin_assumes,
- {
- llvm::omp::allowedClauses_OMPD_begin_assumes,
- llvm::omp::allowedOnceClauses_OMPD_begin_assumes,
- llvm::omp::allowedExclusiveClauses_OMPD_begin_assumes,
- llvm::omp::requiredClauses_OMPD_begin_assumes,
- }
- },
- {llvm::omp::Directive::OMPD_begin_declare_variant,
- {
- llvm::omp::allowedClauses_OMPD_begin_declare_variant,
- llvm::omp::allowedOnceClauses_OMPD_begin_declare_variant,
- llvm::omp::allowedExclusiveClauses_OMPD_begin_declare_variant,
- llvm::omp::requiredClauses_OMPD_begin_declare_variant,
- }
- },
- {llvm::omp::Directive::OMPD_cancel,
- {
- llvm::omp::allowedClauses_OMPD_cancel,
- llvm::omp::allowedOnceClauses_OMPD_cancel,
- llvm::omp::allowedExclusiveClauses_OMPD_cancel,
- llvm::omp::requiredClauses_OMPD_cancel,
- }
- },
- {llvm::omp::Directive::OMPD_cancellation_point,
- {
- llvm::omp::allowedClauses_OMPD_cancellation_point,
- llvm::omp::allowedOnceClauses_OMPD_cancellation_point,
- llvm::omp::allowedExclusiveClauses_OMPD_cancellation_point,
- llvm::omp::requiredClauses_OMPD_cancellation_point,
- }
- },
- {llvm::omp::Directive::OMPD_critical,
- {
- llvm::omp::allowedClauses_OMPD_critical,
- llvm::omp::allowedOnceClauses_OMPD_critical,
- llvm::omp::allowedExclusiveClauses_OMPD_critical,
- llvm::omp::requiredClauses_OMPD_critical,
- }
- },
- {llvm::omp::Directive::OMPD_declare_mapper,
- {
- llvm::omp::allowedClauses_OMPD_declare_mapper,
- llvm::omp::allowedOnceClauses_OMPD_declare_mapper,
- llvm::omp::allowedExclusiveClauses_OMPD_declare_mapper,
- llvm::omp::requiredClauses_OMPD_declare_mapper,
- }
- },
- {llvm::omp::Directive::OMPD_declare_reduction,
- {
- llvm::omp::allowedClauses_OMPD_declare_reduction,
- llvm::omp::allowedOnceClauses_OMPD_declare_reduction,
- llvm::omp::allowedExclusiveClauses_OMPD_declare_reduction,
- llvm::omp::requiredClauses_OMPD_declare_reduction,
- }
- },
- {llvm::omp::Directive::OMPD_declare_simd,
- {
- llvm::omp::allowedClauses_OMPD_declare_simd,
- llvm::omp::allowedOnceClauses_OMPD_declare_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_declare_simd,
- llvm::omp::requiredClauses_OMPD_declare_simd,
- }
- },
- {llvm::omp::Directive::OMPD_declare_target,
- {
- llvm::omp::allowedClauses_OMPD_declare_target,
- llvm::omp::allowedOnceClauses_OMPD_declare_target,
- llvm::omp::allowedExclusiveClauses_OMPD_declare_target,
- llvm::omp::requiredClauses_OMPD_declare_target,
- }
- },
- {llvm::omp::Directive::OMPD_declare_variant,
- {
- llvm::omp::allowedClauses_OMPD_declare_variant,
- llvm::omp::allowedOnceClauses_OMPD_declare_variant,
- llvm::omp::allowedExclusiveClauses_OMPD_declare_variant,
- llvm::omp::requiredClauses_OMPD_declare_variant,
- }
- },
- {llvm::omp::Directive::OMPD_depobj,
- {
- llvm::omp::allowedClauses_OMPD_depobj,
- llvm::omp::allowedOnceClauses_OMPD_depobj,
- llvm::omp::allowedExclusiveClauses_OMPD_depobj,
- llvm::omp::requiredClauses_OMPD_depobj,
- }
- },
- {llvm::omp::Directive::OMPD_distribute,
- {
- llvm::omp::allowedClauses_OMPD_distribute,
- llvm::omp::allowedOnceClauses_OMPD_distribute,
- llvm::omp::allowedExclusiveClauses_OMPD_distribute,
- llvm::omp::requiredClauses_OMPD_distribute,
- }
- },
- {llvm::omp::Directive::OMPD_distribute_parallel_do,
- {
- llvm::omp::allowedClauses_OMPD_distribute_parallel_do,
- llvm::omp::allowedOnceClauses_OMPD_distribute_parallel_do,
- llvm::omp::allowedExclusiveClauses_OMPD_distribute_parallel_do,
- llvm::omp::requiredClauses_OMPD_distribute_parallel_do,
- }
- },
- {llvm::omp::Directive::OMPD_distribute_parallel_do_simd,
- {
- llvm::omp::allowedClauses_OMPD_distribute_parallel_do_simd,
- llvm::omp::allowedOnceClauses_OMPD_distribute_parallel_do_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_distribute_parallel_do_simd,
- llvm::omp::requiredClauses_OMPD_distribute_parallel_do_simd,
- }
- },
- {llvm::omp::Directive::OMPD_distribute_parallel_for,
- {
- llvm::omp::allowedClauses_OMPD_distribute_parallel_for,
- llvm::omp::allowedOnceClauses_OMPD_distribute_parallel_for,
- llvm::omp::allowedExclusiveClauses_OMPD_distribute_parallel_for,
- llvm::omp::requiredClauses_OMPD_distribute_parallel_for,
- }
- },
- {llvm::omp::Directive::OMPD_distribute_parallel_for_simd,
- {
- llvm::omp::allowedClauses_OMPD_distribute_parallel_for_simd,
- llvm::omp::allowedOnceClauses_OMPD_distribute_parallel_for_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_distribute_parallel_for_simd,
- llvm::omp::requiredClauses_OMPD_distribute_parallel_for_simd,
- }
- },
- {llvm::omp::Directive::OMPD_distribute_simd,
- {
- llvm::omp::allowedClauses_OMPD_distribute_simd,
- llvm::omp::allowedOnceClauses_OMPD_distribute_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_distribute_simd,
- llvm::omp::requiredClauses_OMPD_distribute_simd,
- }
- },
- {llvm::omp::Directive::OMPD_do,
- {
- llvm::omp::allowedClauses_OMPD_do,
- llvm::omp::allowedOnceClauses_OMPD_do,
- llvm::omp::allowedExclusiveClauses_OMPD_do,
- llvm::omp::requiredClauses_OMPD_do,
- }
- },
- {llvm::omp::Directive::OMPD_do_simd,
- {
- llvm::omp::allowedClauses_OMPD_do_simd,
- llvm::omp::allowedOnceClauses_OMPD_do_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_do_simd,
- llvm::omp::requiredClauses_OMPD_do_simd,
- }
- },
- {llvm::omp::Directive::OMPD_end_assumes,
- {
- llvm::omp::allowedClauses_OMPD_end_assumes,
- llvm::omp::allowedOnceClauses_OMPD_end_assumes,
- llvm::omp::allowedExclusiveClauses_OMPD_end_assumes,
- llvm::omp::requiredClauses_OMPD_end_assumes,
- }
- },
- {llvm::omp::Directive::OMPD_end_declare_target,
- {
- llvm::omp::allowedClauses_OMPD_end_declare_target,
- llvm::omp::allowedOnceClauses_OMPD_end_declare_target,
- llvm::omp::allowedExclusiveClauses_OMPD_end_declare_target,
- llvm::omp::requiredClauses_OMPD_end_declare_target,
- }
- },
- {llvm::omp::Directive::OMPD_end_declare_variant,
- {
- llvm::omp::allowedClauses_OMPD_end_declare_variant,
- llvm::omp::allowedOnceClauses_OMPD_end_declare_variant,
- llvm::omp::allowedExclusiveClauses_OMPD_end_declare_variant,
- llvm::omp::requiredClauses_OMPD_end_declare_variant,
- }
- },
- {llvm::omp::Directive::OMPD_end_do,
- {
- llvm::omp::allowedClauses_OMPD_end_do,
- llvm::omp::allowedOnceClauses_OMPD_end_do,
- llvm::omp::allowedExclusiveClauses_OMPD_end_do,
- llvm::omp::requiredClauses_OMPD_end_do,
- }
- },
- {llvm::omp::Directive::OMPD_end_do_simd,
- {
- llvm::omp::allowedClauses_OMPD_end_do_simd,
- llvm::omp::allowedOnceClauses_OMPD_end_do_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_end_do_simd,
- llvm::omp::requiredClauses_OMPD_end_do_simd,
- }
- },
- {llvm::omp::Directive::OMPD_end_sections,
- {
- llvm::omp::allowedClauses_OMPD_end_sections,
- llvm::omp::allowedOnceClauses_OMPD_end_sections,
- llvm::omp::allowedExclusiveClauses_OMPD_end_sections,
- llvm::omp::requiredClauses_OMPD_end_sections,
- }
- },
- {llvm::omp::Directive::OMPD_end_single,
- {
- llvm::omp::allowedClauses_OMPD_end_single,
- llvm::omp::allowedOnceClauses_OMPD_end_single,
- llvm::omp::allowedExclusiveClauses_OMPD_end_single,
- llvm::omp::requiredClauses_OMPD_end_single,
- }
- },
- {llvm::omp::Directive::OMPD_end_workshare,
- {
- llvm::omp::allowedClauses_OMPD_end_workshare,
- llvm::omp::allowedOnceClauses_OMPD_end_workshare,
- llvm::omp::allowedExclusiveClauses_OMPD_end_workshare,
- llvm::omp::requiredClauses_OMPD_end_workshare,
- }
- },
- {llvm::omp::Directive::OMPD_flush,
- {
- llvm::omp::allowedClauses_OMPD_flush,
- llvm::omp::allowedOnceClauses_OMPD_flush,
- llvm::omp::allowedExclusiveClauses_OMPD_flush,
- llvm::omp::requiredClauses_OMPD_flush,
- }
- },
- {llvm::omp::Directive::OMPD_for,
- {
- llvm::omp::allowedClauses_OMPD_for,
- llvm::omp::allowedOnceClauses_OMPD_for,
- llvm::omp::allowedExclusiveClauses_OMPD_for,
- llvm::omp::requiredClauses_OMPD_for,
- }
- },
- {llvm::omp::Directive::OMPD_for_simd,
- {
- llvm::omp::allowedClauses_OMPD_for_simd,
- llvm::omp::allowedOnceClauses_OMPD_for_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_for_simd,
- llvm::omp::requiredClauses_OMPD_for_simd,
- }
- },
- {llvm::omp::Directive::OMPD_master,
- {
- llvm::omp::allowedClauses_OMPD_master,
- llvm::omp::allowedOnceClauses_OMPD_master,
- llvm::omp::allowedExclusiveClauses_OMPD_master,
- llvm::omp::requiredClauses_OMPD_master,
- }
- },
- {llvm::omp::Directive::OMPD_master_taskloop,
- {
- llvm::omp::allowedClauses_OMPD_master_taskloop,
- llvm::omp::allowedOnceClauses_OMPD_master_taskloop,
- llvm::omp::allowedExclusiveClauses_OMPD_master_taskloop,
- llvm::omp::requiredClauses_OMPD_master_taskloop,
- }
- },
- {llvm::omp::Directive::OMPD_master_taskloop_simd,
- {
- llvm::omp::allowedClauses_OMPD_master_taskloop_simd,
- llvm::omp::allowedOnceClauses_OMPD_master_taskloop_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_master_taskloop_simd,
- llvm::omp::requiredClauses_OMPD_master_taskloop_simd,
- }
- },
- {llvm::omp::Directive::OMPD_ordered,
- {
- llvm::omp::allowedClauses_OMPD_ordered,
- llvm::omp::allowedOnceClauses_OMPD_ordered,
- llvm::omp::allowedExclusiveClauses_OMPD_ordered,
- llvm::omp::requiredClauses_OMPD_ordered,
- }
- },
- {llvm::omp::Directive::OMPD_parallel,
- {
- llvm::omp::allowedClauses_OMPD_parallel,
- llvm::omp::allowedOnceClauses_OMPD_parallel,
- llvm::omp::allowedExclusiveClauses_OMPD_parallel,
- llvm::omp::requiredClauses_OMPD_parallel,
- }
- },
- {llvm::omp::Directive::OMPD_parallel_do,
- {
- llvm::omp::allowedClauses_OMPD_parallel_do,
- llvm::omp::allowedOnceClauses_OMPD_parallel_do,
- llvm::omp::allowedExclusiveClauses_OMPD_parallel_do,
- llvm::omp::requiredClauses_OMPD_parallel_do,
- }
- },
- {llvm::omp::Directive::OMPD_parallel_do_simd,
- {
- llvm::omp::allowedClauses_OMPD_parallel_do_simd,
- llvm::omp::allowedOnceClauses_OMPD_parallel_do_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_parallel_do_simd,
- llvm::omp::requiredClauses_OMPD_parallel_do_simd,
- }
- },
- {llvm::omp::Directive::OMPD_parallel_for,
- {
- llvm::omp::allowedClauses_OMPD_parallel_for,
- llvm::omp::allowedOnceClauses_OMPD_parallel_for,
- llvm::omp::allowedExclusiveClauses_OMPD_parallel_for,
- llvm::omp::requiredClauses_OMPD_parallel_for,
- }
- },
- {llvm::omp::Directive::OMPD_parallel_for_simd,
- {
- llvm::omp::allowedClauses_OMPD_parallel_for_simd,
- llvm::omp::allowedOnceClauses_OMPD_parallel_for_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_parallel_for_simd,
- llvm::omp::requiredClauses_OMPD_parallel_for_simd,
- }
- },
- {llvm::omp::Directive::OMPD_parallel_master,
- {
- llvm::omp::allowedClauses_OMPD_parallel_master,
- llvm::omp::allowedOnceClauses_OMPD_parallel_master,
- llvm::omp::allowedExclusiveClauses_OMPD_parallel_master,
- llvm::omp::requiredClauses_OMPD_parallel_master,
- }
- },
- {llvm::omp::Directive::OMPD_parallel_master_taskloop,
- {
- llvm::omp::allowedClauses_OMPD_parallel_master_taskloop,
- llvm::omp::allowedOnceClauses_OMPD_parallel_master_taskloop,
- llvm::omp::allowedExclusiveClauses_OMPD_parallel_master_taskloop,
- llvm::omp::requiredClauses_OMPD_parallel_master_taskloop,
- }
- },
- {llvm::omp::Directive::OMPD_parallel_master_taskloop_simd,
- {
- llvm::omp::allowedClauses_OMPD_parallel_master_taskloop_simd,
- llvm::omp::allowedOnceClauses_OMPD_parallel_master_taskloop_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_parallel_master_taskloop_simd,
- llvm::omp::requiredClauses_OMPD_parallel_master_taskloop_simd,
- }
- },
- {llvm::omp::Directive::OMPD_parallel_sections,
- {
- llvm::omp::allowedClauses_OMPD_parallel_sections,
- llvm::omp::allowedOnceClauses_OMPD_parallel_sections,
- llvm::omp::allowedExclusiveClauses_OMPD_parallel_sections,
- llvm::omp::requiredClauses_OMPD_parallel_sections,
- }
- },
- {llvm::omp::Directive::OMPD_parallel_workshare,
- {
- llvm::omp::allowedClauses_OMPD_parallel_workshare,
- llvm::omp::allowedOnceClauses_OMPD_parallel_workshare,
- llvm::omp::allowedExclusiveClauses_OMPD_parallel_workshare,
- llvm::omp::requiredClauses_OMPD_parallel_workshare,
- }
- },
- {llvm::omp::Directive::OMPD_requires,
- {
- llvm::omp::allowedClauses_OMPD_requires,
- llvm::omp::allowedOnceClauses_OMPD_requires,
- llvm::omp::allowedExclusiveClauses_OMPD_requires,
- llvm::omp::requiredClauses_OMPD_requires,
- }
- },
- {llvm::omp::Directive::OMPD_scan,
- {
- llvm::omp::allowedClauses_OMPD_scan,
- llvm::omp::allowedOnceClauses_OMPD_scan,
- llvm::omp::allowedExclusiveClauses_OMPD_scan,
- llvm::omp::requiredClauses_OMPD_scan,
- }
- },
- {llvm::omp::Directive::OMPD_section,
- {
- llvm::omp::allowedClauses_OMPD_section,
- llvm::omp::allowedOnceClauses_OMPD_section,
- llvm::omp::allowedExclusiveClauses_OMPD_section,
- llvm::omp::requiredClauses_OMPD_section,
- }
- },
- {llvm::omp::Directive::OMPD_sections,
- {
- llvm::omp::allowedClauses_OMPD_sections,
- llvm::omp::allowedOnceClauses_OMPD_sections,
- llvm::omp::allowedExclusiveClauses_OMPD_sections,
- llvm::omp::requiredClauses_OMPD_sections,
- }
- },
- {llvm::omp::Directive::OMPD_simd,
- {
- llvm::omp::allowedClauses_OMPD_simd,
- llvm::omp::allowedOnceClauses_OMPD_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_simd,
- llvm::omp::requiredClauses_OMPD_simd,
- }
- },
- {llvm::omp::Directive::OMPD_single,
- {
- llvm::omp::allowedClauses_OMPD_single,
- llvm::omp::allowedOnceClauses_OMPD_single,
- llvm::omp::allowedExclusiveClauses_OMPD_single,
- llvm::omp::requiredClauses_OMPD_single,
- }
- },
- {llvm::omp::Directive::OMPD_target,
- {
- llvm::omp::allowedClauses_OMPD_target,
- llvm::omp::allowedOnceClauses_OMPD_target,
- llvm::omp::allowedExclusiveClauses_OMPD_target,
- llvm::omp::requiredClauses_OMPD_target,
- }
- },
- {llvm::omp::Directive::OMPD_target_data,
- {
- llvm::omp::allowedClauses_OMPD_target_data,
- llvm::omp::allowedOnceClauses_OMPD_target_data,
- llvm::omp::allowedExclusiveClauses_OMPD_target_data,
- llvm::omp::requiredClauses_OMPD_target_data,
- }
- },
- {llvm::omp::Directive::OMPD_target_enter_data,
- {
- llvm::omp::allowedClauses_OMPD_target_enter_data,
- llvm::omp::allowedOnceClauses_OMPD_target_enter_data,
- llvm::omp::allowedExclusiveClauses_OMPD_target_enter_data,
- llvm::omp::requiredClauses_OMPD_target_enter_data,
- }
- },
- {llvm::omp::Directive::OMPD_target_exit_data,
- {
- llvm::omp::allowedClauses_OMPD_target_exit_data,
- llvm::omp::allowedOnceClauses_OMPD_target_exit_data,
- llvm::omp::allowedExclusiveClauses_OMPD_target_exit_data,
- llvm::omp::requiredClauses_OMPD_target_exit_data,
- }
- },
- {llvm::omp::Directive::OMPD_target_parallel,
- {
- llvm::omp::allowedClauses_OMPD_target_parallel,
- llvm::omp::allowedOnceClauses_OMPD_target_parallel,
- llvm::omp::allowedExclusiveClauses_OMPD_target_parallel,
- llvm::omp::requiredClauses_OMPD_target_parallel,
- }
- },
- {llvm::omp::Directive::OMPD_target_parallel_do,
- {
- llvm::omp::allowedClauses_OMPD_target_parallel_do,
- llvm::omp::allowedOnceClauses_OMPD_target_parallel_do,
- llvm::omp::allowedExclusiveClauses_OMPD_target_parallel_do,
- llvm::omp::requiredClauses_OMPD_target_parallel_do,
- }
- },
- {llvm::omp::Directive::OMPD_target_parallel_do_simd,
- {
- llvm::omp::allowedClauses_OMPD_target_parallel_do_simd,
- llvm::omp::allowedOnceClauses_OMPD_target_parallel_do_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_target_parallel_do_simd,
- llvm::omp::requiredClauses_OMPD_target_parallel_do_simd,
- }
- },
- {llvm::omp::Directive::OMPD_target_parallel_for,
- {
- llvm::omp::allowedClauses_OMPD_target_parallel_for,
- llvm::omp::allowedOnceClauses_OMPD_target_parallel_for,
- llvm::omp::allowedExclusiveClauses_OMPD_target_parallel_for,
- llvm::omp::requiredClauses_OMPD_target_parallel_for,
- }
- },
- {llvm::omp::Directive::OMPD_target_parallel_for_simd,
- {
- llvm::omp::allowedClauses_OMPD_target_parallel_for_simd,
- llvm::omp::allowedOnceClauses_OMPD_target_parallel_for_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_target_parallel_for_simd,
- llvm::omp::requiredClauses_OMPD_target_parallel_for_simd,
- }
- },
- {llvm::omp::Directive::OMPD_target_simd,
- {
- llvm::omp::allowedClauses_OMPD_target_simd,
- llvm::omp::allowedOnceClauses_OMPD_target_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_target_simd,
- llvm::omp::requiredClauses_OMPD_target_simd,
- }
- },
- {llvm::omp::Directive::OMPD_target_teams,
- {
- llvm::omp::allowedClauses_OMPD_target_teams,
- llvm::omp::allowedOnceClauses_OMPD_target_teams,
- llvm::omp::allowedExclusiveClauses_OMPD_target_teams,
- llvm::omp::requiredClauses_OMPD_target_teams,
- }
- },
- {llvm::omp::Directive::OMPD_target_teams_distribute,
- {
- llvm::omp::allowedClauses_OMPD_target_teams_distribute,
- llvm::omp::allowedOnceClauses_OMPD_target_teams_distribute,
- llvm::omp::allowedExclusiveClauses_OMPD_target_teams_distribute,
- llvm::omp::requiredClauses_OMPD_target_teams_distribute,
- }
- },
- {llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do,
- {
- llvm::omp::allowedClauses_OMPD_target_teams_distribute_parallel_do,
- llvm::omp::allowedOnceClauses_OMPD_target_teams_distribute_parallel_do,
- llvm::omp::allowedExclusiveClauses_OMPD_target_teams_distribute_parallel_do,
- llvm::omp::requiredClauses_OMPD_target_teams_distribute_parallel_do,
- }
- },
- {llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do_simd,
- {
- llvm::omp::allowedClauses_OMPD_target_teams_distribute_parallel_do_simd,
- llvm::omp::allowedOnceClauses_OMPD_target_teams_distribute_parallel_do_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_target_teams_distribute_parallel_do_simd,
- llvm::omp::requiredClauses_OMPD_target_teams_distribute_parallel_do_simd,
- }
- },
- {llvm::omp::Directive::OMPD_target_teams_distribute_parallel_for,
- {
- llvm::omp::allowedClauses_OMPD_target_teams_distribute_parallel_for,
- llvm::omp::allowedOnceClauses_OMPD_target_teams_distribute_parallel_for,
- llvm::omp::allowedExclusiveClauses_OMPD_target_teams_distribute_parallel_for,
- llvm::omp::requiredClauses_OMPD_target_teams_distribute_parallel_for,
- }
- },
- {llvm::omp::Directive::OMPD_target_teams_distribute_parallel_for_simd,
- {
- llvm::omp::allowedClauses_OMPD_target_teams_distribute_parallel_for_simd,
- llvm::omp::allowedOnceClauses_OMPD_target_teams_distribute_parallel_for_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_target_teams_distribute_parallel_for_simd,
- llvm::omp::requiredClauses_OMPD_target_teams_distribute_parallel_for_simd,
- }
- },
- {llvm::omp::Directive::OMPD_target_teams_distribute_simd,
- {
- llvm::omp::allowedClauses_OMPD_target_teams_distribute_simd,
- llvm::omp::allowedOnceClauses_OMPD_target_teams_distribute_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_target_teams_distribute_simd,
- llvm::omp::requiredClauses_OMPD_target_teams_distribute_simd,
- }
- },
- {llvm::omp::Directive::OMPD_target_update,
- {
- llvm::omp::allowedClauses_OMPD_target_update,
- llvm::omp::allowedOnceClauses_OMPD_target_update,
- llvm::omp::allowedExclusiveClauses_OMPD_target_update,
- llvm::omp::requiredClauses_OMPD_target_update,
- }
- },
- {llvm::omp::Directive::OMPD_task,
- {
- llvm::omp::allowedClauses_OMPD_task,
- llvm::omp::allowedOnceClauses_OMPD_task,
- llvm::omp::allowedExclusiveClauses_OMPD_task,
- llvm::omp::requiredClauses_OMPD_task,
- }
- },
- {llvm::omp::Directive::OMPD_taskgroup,
- {
- llvm::omp::allowedClauses_OMPD_taskgroup,
- llvm::omp::allowedOnceClauses_OMPD_taskgroup,
- llvm::omp::allowedExclusiveClauses_OMPD_taskgroup,
- llvm::omp::requiredClauses_OMPD_taskgroup,
- }
- },
- {llvm::omp::Directive::OMPD_taskloop,
- {
- llvm::omp::allowedClauses_OMPD_taskloop,
- llvm::omp::allowedOnceClauses_OMPD_taskloop,
- llvm::omp::allowedExclusiveClauses_OMPD_taskloop,
- llvm::omp::requiredClauses_OMPD_taskloop,
- }
- },
- {llvm::omp::Directive::OMPD_taskloop_simd,
- {
- llvm::omp::allowedClauses_OMPD_taskloop_simd,
- llvm::omp::allowedOnceClauses_OMPD_taskloop_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_taskloop_simd,
- llvm::omp::requiredClauses_OMPD_taskloop_simd,
- }
- },
- {llvm::omp::Directive::OMPD_taskwait,
- {
- llvm::omp::allowedClauses_OMPD_taskwait,
- llvm::omp::allowedOnceClauses_OMPD_taskwait,
- llvm::omp::allowedExclusiveClauses_OMPD_taskwait,
- llvm::omp::requiredClauses_OMPD_taskwait,
- }
- },
- {llvm::omp::Directive::OMPD_taskyield,
- {
- llvm::omp::allowedClauses_OMPD_taskyield,
- llvm::omp::allowedOnceClauses_OMPD_taskyield,
- llvm::omp::allowedExclusiveClauses_OMPD_taskyield,
- llvm::omp::requiredClauses_OMPD_taskyield,
- }
- },
- {llvm::omp::Directive::OMPD_teams,
- {
- llvm::omp::allowedClauses_OMPD_teams,
- llvm::omp::allowedOnceClauses_OMPD_teams,
- llvm::omp::allowedExclusiveClauses_OMPD_teams,
- llvm::omp::requiredClauses_OMPD_teams,
- }
- },
- {llvm::omp::Directive::OMPD_teams_distribute,
- {
- llvm::omp::allowedClauses_OMPD_teams_distribute,
- llvm::omp::allowedOnceClauses_OMPD_teams_distribute,
- llvm::omp::allowedExclusiveClauses_OMPD_teams_distribute,
- llvm::omp::requiredClauses_OMPD_teams_distribute,
- }
- },
- {llvm::omp::Directive::OMPD_teams_distribute_parallel_do,
- {
- llvm::omp::allowedClauses_OMPD_teams_distribute_parallel_do,
- llvm::omp::allowedOnceClauses_OMPD_teams_distribute_parallel_do,
- llvm::omp::allowedExclusiveClauses_OMPD_teams_distribute_parallel_do,
- llvm::omp::requiredClauses_OMPD_teams_distribute_parallel_do,
- }
- },
- {llvm::omp::Directive::OMPD_teams_distribute_parallel_do_simd,
- {
- llvm::omp::allowedClauses_OMPD_teams_distribute_parallel_do_simd,
- llvm::omp::allowedOnceClauses_OMPD_teams_distribute_parallel_do_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_teams_distribute_parallel_do_simd,
- llvm::omp::requiredClauses_OMPD_teams_distribute_parallel_do_simd,
- }
- },
- {llvm::omp::Directive::OMPD_teams_distribute_parallel_for,
- {
- llvm::omp::allowedClauses_OMPD_teams_distribute_parallel_for,
- llvm::omp::allowedOnceClauses_OMPD_teams_distribute_parallel_for,
- llvm::omp::allowedExclusiveClauses_OMPD_teams_distribute_parallel_for,
- llvm::omp::requiredClauses_OMPD_teams_distribute_parallel_for,
- }
- },
- {llvm::omp::Directive::OMPD_teams_distribute_parallel_for_simd,
- {
- llvm::omp::allowedClauses_OMPD_teams_distribute_parallel_for_simd,
- llvm::omp::allowedOnceClauses_OMPD_teams_distribute_parallel_for_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_teams_distribute_parallel_for_simd,
- llvm::omp::requiredClauses_OMPD_teams_distribute_parallel_for_simd,
- }
- },
- {llvm::omp::Directive::OMPD_teams_distribute_simd,
- {
- llvm::omp::allowedClauses_OMPD_teams_distribute_simd,
- llvm::omp::allowedOnceClauses_OMPD_teams_distribute_simd,
- llvm::omp::allowedExclusiveClauses_OMPD_teams_distribute_simd,
- llvm::omp::requiredClauses_OMPD_teams_distribute_simd,
- }
- },
- {llvm::omp::Directive::OMPD_threadprivate,
- {
- llvm::omp::allowedClauses_OMPD_threadprivate,
- llvm::omp::allowedOnceClauses_OMPD_threadprivate,
- llvm::omp::allowedExclusiveClauses_OMPD_threadprivate,
- llvm::omp::requiredClauses_OMPD_threadprivate,
- }
- },
- {llvm::omp::Directive::OMPD_unknown,
- {
- llvm::omp::allowedClauses_OMPD_unknown,
- llvm::omp::allowedOnceClauses_OMPD_unknown,
- llvm::omp::allowedExclusiveClauses_OMPD_unknown,
- llvm::omp::requiredClauses_OMPD_unknown,
- }
- },
- {llvm::omp::Directive::OMPD_workshare,
- {
- llvm::omp::allowedClauses_OMPD_workshare,
- llvm::omp::allowedOnceClauses_OMPD_workshare,
- llvm::omp::allowedExclusiveClauses_OMPD_workshare,
- llvm::omp::requiredClauses_OMPD_workshare,
- }
- },
-}
-
-#endif // GEN_FLANG_DIRECTIVE_CLAUSE_MAP
-
-#ifdef GEN_FLANG_CLAUSE_PARSER_CLASSES
-#undef GEN_FLANG_CLAUSE_PARSER_CLASSES
-
-EMPTY_CLASS(AcqRel);
-EMPTY_CLASS(Acquire);
-EMPTY_CLASS(Affinity);
-WRAPPER_CLASS(Aligned, OmpAlignedClause);
-WRAPPER_CLASS(Allocate, OmpAllocateClause);
-WRAPPER_CLASS(Allocator, ScalarIntExpr);
-EMPTY_CLASS(AtomicDefaultMemOrder);
-EMPTY_CLASS(Capture);
-WRAPPER_CLASS(Collapse, ScalarIntConstantExpr);
-WRAPPER_CLASS(Copyprivate, OmpObjectList);
-WRAPPER_CLASS(Copyin, OmpObjectList);
-WRAPPER_CLASS(Default, OmpDefaultClause);
-WRAPPER_CLASS(Defaultmap, OmpDefaultmapClause);
-WRAPPER_CLASS(Depend, OmpDependClause);
-EMPTY_CLASS(Depobj);
-EMPTY_CLASS(Destroy);
-EMPTY_CLASS(Detach);
-WRAPPER_CLASS(Device, ScalarIntExpr);
-EMPTY_CLASS(DeviceType);
-WRAPPER_CLASS(DistSchedule, std::optional<ScalarIntExpr>);
-EMPTY_CLASS(DynamicAllocators);
-EMPTY_CLASS(Exclusive);
-WRAPPER_CLASS(Final, ScalarLogicalExpr);
-WRAPPER_CLASS(Firstprivate, OmpObjectList);
-EMPTY_CLASS(Flush);
-WRAPPER_CLASS(From, OmpObjectList);
-WRAPPER_CLASS(Grainsize, ScalarIntExpr);
-WRAPPER_CLASS(Hint, ConstantExpr);
-WRAPPER_CLASS(If, OmpIfClause);
-EMPTY_CLASS(InReduction);
-EMPTY_CLASS(Inbranch);
-EMPTY_CLASS(Inclusive);
-WRAPPER_CLASS(IsDevicePtr, std::list<Name>);
-WRAPPER_CLASS(Lastprivate, OmpObjectList);
-WRAPPER_CLASS(Linear, OmpLinearClause);
-WRAPPER_CLASS(Link, OmpObjectList);
-WRAPPER_CLASS(Map, OmpMapClause);
-EMPTY_CLASS(Match);
-EMPTY_CLASS(Mergeable);
-EMPTY_CLASS(Nogroup);
-EMPTY_CLASS(Nowait);
-EMPTY_CLASS(Nontemporal);
-EMPTY_CLASS(Notinbranch);
-WRAPPER_CLASS(NumTasks, ScalarIntExpr);
-WRAPPER_CLASS(NumTeams, ScalarIntExpr);
-WRAPPER_CLASS(NumThreads, ScalarIntExpr);
-EMPTY_CLASS(Order);
-WRAPPER_CLASS(Ordered, std::optional<ScalarIntConstantExpr>);
-WRAPPER_CLASS(Priority, ScalarIntExpr);
-WRAPPER_CLASS(Private, OmpObjectList);
-WRAPPER_CLASS(ProcBind, OmpProcBindClause);
-EMPTY_CLASS(Read);
-WRAPPER_CLASS(Reduction, OmpReductionClause);
-EMPTY_CLASS(Relaxed);
-EMPTY_CLASS(Release);
-EMPTY_CLASS(ReverseOffload);
-WRAPPER_CLASS(Safelen, ScalarIntConstantExpr);
-WRAPPER_CLASS(Schedule, OmpScheduleClause);
-EMPTY_CLASS(SeqCst);
-WRAPPER_CLASS(Shared, OmpObjectList);
-EMPTY_CLASS(Simd);
-WRAPPER_CLASS(Simdlen, ScalarIntConstantExpr);
-WRAPPER_CLASS(TaskReduction, OmpReductionClause);
-WRAPPER_CLASS(ThreadLimit, ScalarIntExpr);
-EMPTY_CLASS(Threadprivate);
-EMPTY_CLASS(Threads);
-WRAPPER_CLASS(To, OmpObjectList);
-EMPTY_CLASS(UnifiedAddress);
-EMPTY_CLASS(UnifiedSharedMemory);
-WRAPPER_CLASS(Uniform, std::list<Name>);
-EMPTY_CLASS(Unknown);
-EMPTY_CLASS(Untied);
-EMPTY_CLASS(Update);
-EMPTY_CLASS(UseDeviceAddr);
-WRAPPER_CLASS(UseDevicePtr, std::list<Name>);
-EMPTY_CLASS(UsesAllocators);
-EMPTY_CLASS(Write);
-
-#endif // GEN_FLANG_CLAUSE_PARSER_CLASSES
-
-#ifdef GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST
-#undef GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST
-
-AcqRel
-, Acquire
-, Affinity
-, Aligned
-, Allocate
-, Allocator
-, AtomicDefaultMemOrder
-, Capture
-, Collapse
-, Copyprivate
-, Copyin
-, Default
-, Defaultmap
-, Depend
-, Depobj
-, Destroy
-, Detach
-, Device
-, DeviceType
-, DistSchedule
-, DynamicAllocators
-, Exclusive
-, Final
-, Firstprivate
-, Flush
-, From
-, Grainsize
-, Hint
-, If
-, InReduction
-, Inbranch
-, Inclusive
-, IsDevicePtr
-, Lastprivate
-, Linear
-, Link
-, Map
-, Match
-, Mergeable
-, Nogroup
-, Nowait
-, Nontemporal
-, Notinbranch
-, NumTasks
-, NumTeams
-, NumThreads
-, Order
-, Ordered
-, Priority
-, Private
-, ProcBind
-, Read
-, Reduction
-, Relaxed
-, Release
-, ReverseOffload
-, Safelen
-, Schedule
-, SeqCst
-, Shared
-, Simd
-, Simdlen
-, TaskReduction
-, ThreadLimit
-, Threadprivate
-, Threads
-, To
-, UnifiedAddress
-, UnifiedSharedMemory
-, Uniform
-, Unknown
-, Untied
-, Update
-, UseDeviceAddr
-, UseDevicePtr
-, UsesAllocators
-, Write
-
-#endif // GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST
-
-#ifdef GEN_FLANG_DUMP_PARSE_TREE_CLAUSES
-#undef GEN_FLANG_DUMP_PARSE_TREE_CLAUSES
-
-NODE(OmpClause, AcqRel)
-NODE(OmpClause, Acquire)
-NODE(OmpClause, Affinity)
-NODE(OmpClause, Aligned)
-NODE(OmpClause, Allocate)
-NODE(OmpClause, Allocator)
-NODE(OmpClause, AtomicDefaultMemOrder)
-NODE(OmpClause, Capture)
-NODE(OmpClause, Collapse)
-NODE(OmpClause, Copyprivate)
-NODE(OmpClause, Copyin)
-NODE(OmpClause, Default)
-NODE(OmpClause, Defaultmap)
-NODE(OmpClause, Depend)
-NODE(OmpClause, Depobj)
-NODE(OmpClause, Destroy)
-NODE(OmpClause, Detach)
-NODE(OmpClause, Device)
-NODE(OmpClause, DeviceType)
-NODE(OmpClause, DistSchedule)
-NODE(OmpClause, DynamicAllocators)
-NODE(OmpClause, Exclusive)
-NODE(OmpClause, Final)
-NODE(OmpClause, Firstprivate)
-NODE(OmpClause, Flush)
-NODE(OmpClause, From)
-NODE(OmpClause, Grainsize)
-NODE(OmpClause, Hint)
-NODE(OmpClause, If)
-NODE(OmpClause, InReduction)
-NODE(OmpClause, Inbranch)
-NODE(OmpClause, Inclusive)
-NODE(OmpClause, IsDevicePtr)
-NODE(OmpClause, Lastprivate)
-NODE(OmpClause, Linear)
-NODE(OmpClause, Link)
-NODE(OmpClause, Map)
-NODE(OmpClause, Match)
-NODE(OmpClause, Mergeable)
-NODE(OmpClause, Nogroup)
-NODE(OmpClause, Nowait)
-NODE(OmpClause, Nontemporal)
-NODE(OmpClause, Notinbranch)
-NODE(OmpClause, NumTasks)
-NODE(OmpClause, NumTeams)
-NODE(OmpClause, NumThreads)
-NODE(OmpClause, Order)
-NODE(OmpClause, Ordered)
-NODE(OmpClause, Priority)
-NODE(OmpClause, Private)
-NODE(OmpClause, ProcBind)
-NODE(OmpClause, Read)
-NODE(OmpClause, Reduction)
-NODE(OmpClause, Relaxed)
-NODE(OmpClause, Release)
-NODE(OmpClause, ReverseOffload)
-NODE(OmpClause, Safelen)
-NODE(OmpClause, Schedule)
-NODE(OmpClause, SeqCst)
-NODE(OmpClause, Shared)
-NODE(OmpClause, Simd)
-NODE(OmpClause, Simdlen)
-NODE(OmpClause, TaskReduction)
-NODE(OmpClause, ThreadLimit)
-NODE(OmpClause, Threadprivate)
-NODE(OmpClause, Threads)
-NODE(OmpClause, To)
-NODE(OmpClause, UnifiedAddress)
-NODE(OmpClause, UnifiedSharedMemory)
-NODE(OmpClause, Uniform)
-NODE(OmpClause, Unknown)
-NODE(OmpClause, Untied)
-NODE(OmpClause, Update)
-NODE(OmpClause, UseDeviceAddr)
-NODE(OmpClause, UseDevicePtr)
-NODE(OmpClause, UsesAllocators)
-NODE(OmpClause, Write)
-
-#endif // GEN_FLANG_DUMP_PARSE_TREE_CLAUSES
-
-#ifdef GEN_FLANG_CLAUSE_UNPARSE
-#undef GEN_FLANG_CLAUSE_UNPARSE
-
-void Before(const OmpClause::AcqRel &) { Word("ACQ_REL"); }
-void Before(const OmpClause::Acquire &) { Word("ACQUIRE"); }
-void Before(const OmpClause::Affinity &) { Word("AFFINITY"); }
-void Unparse(const OmpClause::Aligned &x) {
- Word("ALIGNED");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::Allocate &x) {
- Word("ALLOCATE");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::Allocator &x) {
- Word("ALLOCATOR");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Before(const OmpClause::AtomicDefaultMemOrder &) { Word("ATOMIC_DEFAULT_MEM_ORDER"); }
-void Before(const OmpClause::Capture &) { Word("CAPTURE"); }
-void Unparse(const OmpClause::Collapse &x) {
- Word("COLLAPSE");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::Copyprivate &x) {
- Word("COPYPRIVATE");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::Copyin &x) {
- Word("COPYIN");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::Default &x) {
- Word("DEFAULT");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::Defaultmap &x) {
- Word("DEFAULTMAP");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::Depend &x) {
- Word("DEPEND");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Before(const OmpClause::Depobj &) { Word("DEPOBJ"); }
-void Before(const OmpClause::Destroy &) { Word("DESTROY"); }
-void Before(const OmpClause::Detach &) { Word("DETACH"); }
-void Unparse(const OmpClause::Device &x) {
- Word("DEVICE");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Before(const OmpClause::DeviceType &) { Word("DEVICE_TYPE"); }
-void Unparse(const OmpClause::DistSchedule &x) {
- Word("DIST_SCHEDULE");
- Walk("(", x.v, ")");
-}
-void Before(const OmpClause::DynamicAllocators &) { Word("DYNAMIC_ALLOCATORS"); }
-void Before(const OmpClause::Exclusive &) { Word("EXCLUSIVE"); }
-void Unparse(const OmpClause::Final &x) {
- Word("FINAL");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::Firstprivate &x) {
- Word("FIRSTPRIVATE");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Before(const OmpClause::Flush &) { Word("FLUSH"); }
-void Unparse(const OmpClause::From &x) {
- Word("FROM");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::Grainsize &x) {
- Word("GRAINSIZE");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::Hint &x) {
- Word("HINT");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::If &x) {
- Word("IF");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Before(const OmpClause::InReduction &) { Word("IN_REDUCTION"); }
-void Before(const OmpClause::Inbranch &) { Word("INBRANCH"); }
-void Before(const OmpClause::Inclusive &) { Word("INCLUSIVE"); }
-void Unparse(const OmpClause::IsDevicePtr &x) {
- Word("IS_DEVICE_PTR");
- Put("(");
- Walk(x.v, ",");
- Put(")");
-}
-void Unparse(const OmpClause::Lastprivate &x) {
- Word("LASTPRIVATE");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::Linear &x) {
- Word("LINEAR");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::Link &x) {
- Word("LINK");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::Map &x) {
- Word("MAP");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Before(const OmpClause::Match &) { Word("MATCH"); }
-void Before(const OmpClause::Mergeable &) { Word("MERGEABLE"); }
-void Before(const OmpClause::Nogroup &) { Word("NOGROUP"); }
-void Before(const OmpClause::Nowait &) { Word("NOWAIT"); }
-void Before(const OmpClause::Nontemporal &) { Word("NONTEMPORAL"); }
-void Before(const OmpClause::Notinbranch &) { Word("NOTINBRANCH"); }
-void Unparse(const OmpClause::NumTasks &x) {
- Word("NUM_TASKS");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::NumTeams &x) {
- Word("NUM_TEAMS");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::NumThreads &x) {
- Word("NUM_THREADS");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Before(const OmpClause::Order &) { Word("ORDER"); }
-void Unparse(const OmpClause::Ordered &x) {
- Word("ORDERED");
- Walk("(", x.v, ")");
-}
-void Unparse(const OmpClause::Priority &x) {
- Word("PRIORITY");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::Private &x) {
- Word("PRIVATE");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::ProcBind &x) {
- Word("PROC_BIND");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Before(const OmpClause::Read &) { Word("READ"); }
-void Unparse(const OmpClause::Reduction &x) {
- Word("REDUCTION");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Before(const OmpClause::Relaxed &) { Word("RELAXED"); }
-void Before(const OmpClause::Release &) { Word("RELEASE"); }
-void Before(const OmpClause::ReverseOffload &) { Word("REVERSE_OFFLOAD"); }
-void Unparse(const OmpClause::Safelen &x) {
- Word("SAFELEN");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::Schedule &x) {
- Word("SCHEDULE");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Before(const OmpClause::SeqCst &) { Word("SEQ_CST"); }
-void Unparse(const OmpClause::Shared &x) {
- Word("SHARED");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Before(const OmpClause::Simd &) { Word("SIMD"); }
-void Unparse(const OmpClause::Simdlen &x) {
- Word("SIMDLEN");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::TaskReduction &x) {
- Word("TASK_REDUCTION");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Unparse(const OmpClause::ThreadLimit &x) {
- Word("THREAD_LIMIT");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Before(const OmpClause::Threadprivate &) { Word("THREADPRIVATE"); }
-void Before(const OmpClause::Threads &) { Word("THREADS"); }
-void Unparse(const OmpClause::To &x) {
- Word("TO");
- Put("(");
- Walk(x.v);
- Put(")");
-}
-void Before(const OmpClause::UnifiedAddress &) { Word("UNIFIED_ADDRESS"); }
-void Before(const OmpClause::UnifiedSharedMemory &) { Word("UNIFIED_SHARED_MEMORY"); }
-void Unparse(const OmpClause::Uniform &x) {
- Word("UNIFORM");
- Put("(");
- Walk(x.v, ",");
- Put(")");
-}
-void Before(const OmpClause::Unknown &) { Word("UNKNOWN"); }
-void Before(const OmpClause::Untied &) { Word("UNTIED"); }
-void Before(const OmpClause::Update &) { Word("UPDATE"); }
-void Before(const OmpClause::UseDeviceAddr &) { Word("USE_DEVICE_ADDR"); }
-void Unparse(const OmpClause::UseDevicePtr &x) {
- Word("USE_DEVICE_PTR");
- Put("(");
- Walk(x.v, ",");
- Put(")");
-}
-void Before(const OmpClause::UsesAllocators &) { Word("USES_ALLOCATORS"); }
-void Before(const OmpClause::Write &) { Word("WRITE"); }
-
-#endif // GEN_FLANG_CLAUSE_UNPARSE
-
-#ifdef GEN_CLANG_CLAUSE_CLASS
-#undef GEN_CLANG_CLAUSE_CLASS
-
-#ifndef CLAUSE
-#define CLAUSE(Enum, Str, Implicit)
-#endif
-#ifndef CLAUSE_CLASS
-#define CLAUSE_CLASS(Enum, Str, Class)
-#endif
-#ifndef CLAUSE_NO_CLASS
-#define CLAUSE_NO_CLASS(Enum, Str)
-#endif
-
-#define __CLAUSE(Name, Class) \
- CLAUSE(OMPC_##Name, #Name, /* Implicit */ false) \
- CLAUSE_CLASS(OMPC_##Name, #Name, Class)
-#define __CLAUSE_NO_CLASS(Name) \
- CLAUSE(OMPC_##Name, #Name, /* Implicit */ false) \
- CLAUSE_NO_CLASS(OMPC_##Name, #Name)
-#define __IMPLICIT_CLAUSE_CLASS(Name, Str, Class) \
- CLAUSE(OMPC_##Name, Str, /* Implicit */ true) \
- CLAUSE_CLASS(OMPC_##Name, Str, Class)
-#define __IMPLICIT_CLAUSE_NO_CLASS(Name, Str) \
- CLAUSE(OMPC_##Name, Str, /* Implicit */ true) \
- CLAUSE_NO_CLASS(OMPC_##Name, Str)
-
-__CLAUSE(acq_rel, OMPAcqRelClause)
-__CLAUSE(acquire, OMPAcquireClause)
-__CLAUSE(affinity, OMPAffinityClause)
-__CLAUSE(aligned, OMPAlignedClause)
-__CLAUSE(allocate, OMPAllocateClause)
-__CLAUSE(allocator, OMPAllocatorClause)
-__CLAUSE(atomic_default_mem_order, OMPAtomicDefaultMemOrderClause)
-__CLAUSE(capture, OMPCaptureClause)
-__CLAUSE(collapse, OMPCollapseClause)
-__CLAUSE(copyprivate, OMPCopyprivateClause)
-__CLAUSE(copyin, OMPCopyinClause)
-__CLAUSE(default, OMPDefaultClause)
-__CLAUSE(defaultmap, OMPDefaultmapClause)
-__CLAUSE(depend, OMPDependClause)
-__IMPLICIT_CLAUSE_CLASS(depobj, "depobj", OMPDepobjClause)
-__CLAUSE(destroy, OMPDestroyClause)
-__CLAUSE(detach, OMPDetachClause)
-__CLAUSE(device, OMPDeviceClause)
-__CLAUSE_NO_CLASS(device_type)
-__CLAUSE(dist_schedule, OMPDistScheduleClause)
-__CLAUSE(dynamic_allocators, OMPDynamicAllocatorsClause)
-__CLAUSE(exclusive, OMPExclusiveClause)
-__CLAUSE(final, OMPFinalClause)
-__CLAUSE(firstprivate, OMPFirstprivateClause)
-__IMPLICIT_CLAUSE_CLASS(flush, "flush", OMPFlushClause)
-__CLAUSE(from, OMPFromClause)
-__CLAUSE(grainsize, OMPGrainsizeClause)
-__CLAUSE(hint, OMPHintClause)
-__CLAUSE(if, OMPIfClause)
-__CLAUSE(in_reduction, OMPInReductionClause)
-__CLAUSE_NO_CLASS(inbranch)
-__CLAUSE(inclusive, OMPInclusiveClause)
-__CLAUSE(is_device_ptr, OMPIsDevicePtrClause)
-__CLAUSE(lastprivate, OMPLastprivateClause)
-__CLAUSE(linear, OMPLinearClause)
-__CLAUSE_NO_CLASS(link)
-__CLAUSE(map, OMPMapClause)
-__CLAUSE_NO_CLASS(match)
-__CLAUSE(mergeable, OMPMergeableClause)
-__CLAUSE(nogroup, OMPNogroupClause)
-__CLAUSE(nowait, OMPNowaitClause)
-__CLAUSE(nontemporal, OMPNontemporalClause)
-__CLAUSE_NO_CLASS(notinbranch)
-__CLAUSE(num_tasks, OMPNumTasksClause)
-__CLAUSE(num_teams, OMPNumTeamsClause)
-__CLAUSE(num_threads, OMPNumThreadsClause)
-__CLAUSE(order, OMPOrderClause)
-__CLAUSE(ordered, OMPOrderedClause)
-__CLAUSE(priority, OMPPriorityClause)
-__CLAUSE(private, OMPPrivateClause)
-__CLAUSE(proc_bind, OMPProcBindClause)
-__CLAUSE(read, OMPReadClause)
-__CLAUSE(reduction, OMPReductionClause)
-__CLAUSE(relaxed, OMPRelaxedClause)
-__CLAUSE(release, OMPReleaseClause)
-__CLAUSE(reverse_offload, OMPReverseOffloadClause)
-__CLAUSE(safelen, OMPSafelenClause)
-__CLAUSE(schedule, OMPScheduleClause)
-__CLAUSE(seq_cst, OMPSeqCstClause)
-__CLAUSE(shared, OMPSharedClause)
-__CLAUSE(simd, OMPSIMDClause)
-__CLAUSE(simdlen, OMPSimdlenClause)
-__CLAUSE(task_reduction, OMPTaskReductionClause)
-__CLAUSE(thread_limit, OMPThreadLimitClause)
-__IMPLICIT_CLAUSE_NO_CLASS(threadprivate, "threadprivate")
-__CLAUSE(threads, OMPThreadsClause)
-__CLAUSE(to, OMPToClause)
-__CLAUSE(unified_address, OMPUnifiedAddressClause)
-__CLAUSE(unified_shared_memory, OMPUnifiedSharedMemoryClause)
-__CLAUSE_NO_CLASS(uniform)
-__IMPLICIT_CLAUSE_NO_CLASS(unknown, "unknown")
-__CLAUSE(untied, OMPUntiedClause)
-__CLAUSE(update, OMPUpdateClause)
-__CLAUSE(use_device_addr, OMPUseDeviceAddrClause)
-__CLAUSE(use_device_ptr, OMPUseDevicePtrClause)
-__CLAUSE(uses_allocators, OMPUsesAllocatorsClause)
-__CLAUSE(write, OMPWriteClause)
-
-#undef __IMPLICIT_CLAUSE_NO_CLASS
-#undef __IMPLICIT_CLAUSE_CLASS
-#undef __CLAUSE
-#undef CLAUSE_NO_CLASS
-#undef CLAUSE_CLASS
-#undef CLAUSE
-
-#endif // GEN_CLANG_CLAUSE_CLASS
-
+#ifdef GEN_FLANG_DIRECTIVE_CLAUSE_SETS
+#undef GEN_FLANG_DIRECTIVE_CLAUSE_SETS
+
+namespace llvm {
+namespace omp {
+
+ // Sets for allocate
+
+ static OmpClauseSet allowedClauses_OMPD_allocate {
+ llvm::omp::Clause::OMPC_allocator,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_allocate {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_allocate {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_allocate {
+ };
+
+ // Sets for assumes
+
+ static OmpClauseSet allowedClauses_OMPD_assumes {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_assumes {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_assumes {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_assumes {
+ };
+
+ // Sets for atomic
+
+ static OmpClauseSet allowedClauses_OMPD_atomic {
+ llvm::omp::Clause::OMPC_read,
+ llvm::omp::Clause::OMPC_write,
+ llvm::omp::Clause::OMPC_update,
+ llvm::omp::Clause::OMPC_capture,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_atomic {
+ llvm::omp::Clause::OMPC_seq_cst,
+ llvm::omp::Clause::OMPC_acq_rel,
+ llvm::omp::Clause::OMPC_acquire,
+ llvm::omp::Clause::OMPC_release,
+ llvm::omp::Clause::OMPC_relaxed,
+ llvm::omp::Clause::OMPC_hint,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_atomic {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_atomic {
+ };
+
+ // Sets for barrier
+
+ static OmpClauseSet allowedClauses_OMPD_barrier {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_barrier {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_barrier {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_barrier {
+ };
+
+ // Sets for begin assumes
+
+ static OmpClauseSet allowedClauses_OMPD_begin_assumes {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_begin_assumes {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_begin_assumes {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_begin_assumes {
+ };
+
+ // Sets for begin declare variant
+
+ static OmpClauseSet allowedClauses_OMPD_begin_declare_variant {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_begin_declare_variant {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_begin_declare_variant {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_begin_declare_variant {
+ };
+
+ // Sets for cancel
+
+ static OmpClauseSet allowedClauses_OMPD_cancel {
+ llvm::omp::Clause::OMPC_if,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_cancel {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_cancel {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_cancel {
+ };
+
+ // Sets for cancellation point
+
+ static OmpClauseSet allowedClauses_OMPD_cancellation_point {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_cancellation_point {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_cancellation_point {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_cancellation_point {
+ };
+
+ // Sets for critical
+
+ static OmpClauseSet allowedClauses_OMPD_critical {
+ llvm::omp::Clause::OMPC_hint,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_critical {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_critical {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_critical {
+ };
+
+ // Sets for declare mapper
+
+ static OmpClauseSet allowedClauses_OMPD_declare_mapper {
+ llvm::omp::Clause::OMPC_map,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_declare_mapper {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_declare_mapper {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_declare_mapper {
+ };
+
+ // Sets for declare reduction
+
+ static OmpClauseSet allowedClauses_OMPD_declare_reduction {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_declare_reduction {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_declare_reduction {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_declare_reduction {
+ };
+
+ // Sets for declare simd
+
+ static OmpClauseSet allowedClauses_OMPD_declare_simd {
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_uniform,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_declare_simd {
+ llvm::omp::Clause::OMPC_simdlen,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_declare_simd {
+ llvm::omp::Clause::OMPC_inbranch,
+ llvm::omp::Clause::OMPC_notinbranch,
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_declare_simd {
+ };
+
+ // Sets for declare target
+
+ static OmpClauseSet allowedClauses_OMPD_declare_target {
+ llvm::omp::Clause::OMPC_to,
+ llvm::omp::Clause::OMPC_link,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_declare_target {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_declare_target {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_declare_target {
+ };
+
+ // Sets for declare variant
+
+ static OmpClauseSet allowedClauses_OMPD_declare_variant {
+ llvm::omp::Clause::OMPC_match,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_declare_variant {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_declare_variant {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_declare_variant {
+ };
+
+ // Sets for depobj
+
+ static OmpClauseSet allowedClauses_OMPD_depobj {
+ llvm::omp::Clause::OMPC_depend,
+ llvm::omp::Clause::OMPC_destroy,
+ llvm::omp::Clause::OMPC_update,
+ llvm::omp::Clause::OMPC_depobj,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_depobj {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_depobj {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_depobj {
+ };
+
+ // Sets for distribute
+
+ static OmpClauseSet allowedClauses_OMPD_distribute {
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_allocate,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_distribute {
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_dist_schedule,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_distribute {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_distribute {
+ };
+
+ // Sets for distribute parallel do
+
+ static OmpClauseSet allowedClauses_OMPD_distribute_parallel_do {
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_order,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_copyin,
+ llvm::omp::Clause::OMPC_linear,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_distribute_parallel_do {
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_dist_schedule,
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_ordered,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_distribute_parallel_do {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_distribute_parallel_do {
+ };
+
+ // Sets for distribute parallel do simd
+
+ static OmpClauseSet allowedClauses_OMPD_distribute_parallel_do_simd {
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_dist_schedule,
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_copyin,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_nontemporal,
+ llvm::omp::Clause::OMPC_order,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_distribute_parallel_do_simd {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_distribute_parallel_do_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_distribute_parallel_do_simd {
+ };
+
+ // Sets for distribute parallel for
+
+ static OmpClauseSet allowedClauses_OMPD_distribute_parallel_for {
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_dist_schedule,
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_copyin,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_order,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_distribute_parallel_for {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_distribute_parallel_for {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_distribute_parallel_for {
+ };
+
+ // Sets for distribute parallel for simd
+
+ static OmpClauseSet allowedClauses_OMPD_distribute_parallel_for_simd {
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_dist_schedule,
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_copyin,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_nontemporal,
+ llvm::omp::Clause::OMPC_order,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_distribute_parallel_for_simd {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_distribute_parallel_for_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_distribute_parallel_for_simd {
+ };
+
+ // Sets for distribute simd
+
+ static OmpClauseSet allowedClauses_OMPD_distribute_simd {
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_copyin,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_nontemporal,
+ llvm::omp::Clause::OMPC_order,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_reduction,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_distribute_simd {
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_dist_schedule,
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_ordered,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_distribute_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_distribute_simd {
+ };
+
+ // Sets for do
+
+ static OmpClauseSet allowedClauses_OMPD_do {
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_reduction,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_do {
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_ordered,
+ llvm::omp::Clause::OMPC_nowait,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_do {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_do {
+ };
+
+ // Sets for do simd
+
+ static OmpClauseSet allowedClauses_OMPD_do_simd {
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_reduction,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_do_simd {
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_ordered,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ llvm::omp::Clause::OMPC_nowait,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_do_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_do_simd {
+ };
+
+ // Sets for end assumes
+
+ static OmpClauseSet allowedClauses_OMPD_end_assumes {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_end_assumes {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_end_assumes {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_end_assumes {
+ };
+
+ // Sets for end declare target
+
+ static OmpClauseSet allowedClauses_OMPD_end_declare_target {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_end_declare_target {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_end_declare_target {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_end_declare_target {
+ };
+
+ // Sets for end declare variant
+
+ static OmpClauseSet allowedClauses_OMPD_end_declare_variant {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_end_declare_variant {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_end_declare_variant {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_end_declare_variant {
+ };
+
+ // Sets for end do
+
+ static OmpClauseSet allowedClauses_OMPD_end_do {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_end_do {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_end_do {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_end_do {
+ };
+
+ // Sets for end do simd
+
+ static OmpClauseSet allowedClauses_OMPD_end_do_simd {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_end_do_simd {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_end_do_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_end_do_simd {
+ };
+
+ // Sets for end sections
+
+ static OmpClauseSet allowedClauses_OMPD_end_sections {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_end_sections {
+ llvm::omp::Clause::OMPC_nowait,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_end_sections {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_end_sections {
+ };
+
+ // Sets for end single
+
+ static OmpClauseSet allowedClauses_OMPD_end_single {
+ llvm::omp::Clause::OMPC_copyprivate,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_end_single {
+ llvm::omp::Clause::OMPC_nowait,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_end_single {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_end_single {
+ };
+
+ // Sets for end workshare
+
+ static OmpClauseSet allowedClauses_OMPD_end_workshare {
+ llvm::omp::Clause::OMPC_nowait,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_end_workshare {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_end_workshare {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_end_workshare {
+ };
+
+ // Sets for flush
+
+ static OmpClauseSet allowedClauses_OMPD_flush {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_flush {
+ llvm::omp::Clause::OMPC_acq_rel,
+ llvm::omp::Clause::OMPC_acquire,
+ llvm::omp::Clause::OMPC_release,
+ llvm::omp::Clause::OMPC_flush,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_flush {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_flush {
+ };
+
+ // Sets for for
+
+ static OmpClauseSet allowedClauses_OMPD_for {
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_ordered,
+ llvm::omp::Clause::OMPC_nowait,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_order,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_for {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_for {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_for {
+ };
+
+ // Sets for for simd
+
+ static OmpClauseSet allowedClauses_OMPD_for_simd {
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_nowait,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_ordered,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_nontemporal,
+ llvm::omp::Clause::OMPC_order,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_for_simd {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_for_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_for_simd {
+ };
+
+ // Sets for master
+
+ static OmpClauseSet allowedClauses_OMPD_master {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_master {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_master {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_master {
+ };
+
+ // Sets for master taskloop
+
+ static OmpClauseSet allowedClauses_OMPD_master_taskloop {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_final,
+ llvm::omp::Clause::OMPC_untied,
+ llvm::omp::Clause::OMPC_mergeable,
+ llvm::omp::Clause::OMPC_priority,
+ llvm::omp::Clause::OMPC_grainsize,
+ llvm::omp::Clause::OMPC_nogroup,
+ llvm::omp::Clause::OMPC_num_tasks,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_in_reduction,
+ llvm::omp::Clause::OMPC_allocate,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_master_taskloop {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_master_taskloop {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_master_taskloop {
+ };
+
+ // Sets for master taskloop simd
+
+ static OmpClauseSet allowedClauses_OMPD_master_taskloop_simd {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_final,
+ llvm::omp::Clause::OMPC_untied,
+ llvm::omp::Clause::OMPC_mergeable,
+ llvm::omp::Clause::OMPC_priority,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ llvm::omp::Clause::OMPC_grainsize,
+ llvm::omp::Clause::OMPC_nogroup,
+ llvm::omp::Clause::OMPC_num_tasks,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_in_reduction,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_nontemporal,
+ llvm::omp::Clause::OMPC_order,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_master_taskloop_simd {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_master_taskloop_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_master_taskloop_simd {
+ };
+
+ // Sets for ordered
+
+ static OmpClauseSet allowedClauses_OMPD_ordered {
+ llvm::omp::Clause::OMPC_threads,
+ llvm::omp::Clause::OMPC_simd,
+ llvm::omp::Clause::OMPC_depend,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_ordered {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_ordered {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_ordered {
+ };
+
+ // Sets for parallel
+
+ static OmpClauseSet allowedClauses_OMPD_parallel {
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_copyin,
+ llvm::omp::Clause::OMPC_allocate,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_parallel {
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_proc_bind,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_parallel {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_parallel {
+ };
+
+ // Sets for parallel do
+
+ static OmpClauseSet allowedClauses_OMPD_parallel_do {
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_copyin,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_linear,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_parallel_do {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_ordered,
+ llvm::omp::Clause::OMPC_collapse,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_parallel_do {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_parallel_do {
+ };
+
+ // Sets for parallel do simd
+
+ static OmpClauseSet allowedClauses_OMPD_parallel_do_simd {
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_copyin,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_nontemporal,
+ llvm::omp::Clause::OMPC_order,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_parallel_do_simd {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_ordered,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_parallel_do_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_parallel_do_simd {
+ };
+
+ // Sets for parallel for
+
+ static OmpClauseSet allowedClauses_OMPD_parallel_for {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_copyin,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_ordered,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_order,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_parallel_for {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_parallel_for {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_parallel_for {
+ };
+
+ // Sets for parallel for simd
+
+ static OmpClauseSet allowedClauses_OMPD_parallel_for_simd {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_copyin,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_ordered,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_nontemporal,
+ llvm::omp::Clause::OMPC_order,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_parallel_for_simd {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_parallel_for_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_parallel_for_simd {
+ };
+
+ // Sets for parallel master
+
+ static OmpClauseSet allowedClauses_OMPD_parallel_master {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_copyin,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_allocate,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_parallel_master {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_parallel_master {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_parallel_master {
+ };
+
+ // Sets for parallel master taskloop
+
+ static OmpClauseSet allowedClauses_OMPD_parallel_master_taskloop {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_final,
+ llvm::omp::Clause::OMPC_untied,
+ llvm::omp::Clause::OMPC_mergeable,
+ llvm::omp::Clause::OMPC_priority,
+ llvm::omp::Clause::OMPC_grainsize,
+ llvm::omp::Clause::OMPC_nogroup,
+ llvm::omp::Clause::OMPC_num_tasks,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_copyin,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_parallel_master_taskloop {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_parallel_master_taskloop {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_parallel_master_taskloop {
+ };
+
+ // Sets for parallel master taskloop simd
+
+ static OmpClauseSet allowedClauses_OMPD_parallel_master_taskloop_simd {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_final,
+ llvm::omp::Clause::OMPC_untied,
+ llvm::omp::Clause::OMPC_mergeable,
+ llvm::omp::Clause::OMPC_priority,
+ llvm::omp::Clause::OMPC_grainsize,
+ llvm::omp::Clause::OMPC_nogroup,
+ llvm::omp::Clause::OMPC_num_tasks,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_copyin,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ llvm::omp::Clause::OMPC_nontemporal,
+ llvm::omp::Clause::OMPC_order,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_parallel_master_taskloop_simd {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_parallel_master_taskloop_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_parallel_master_taskloop_simd {
+ };
+
+ // Sets for parallel sections
+
+ static OmpClauseSet allowedClauses_OMPD_parallel_sections {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_copyin,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_allocate,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_parallel_sections {
+ llvm::omp::Clause::OMPC_num_threads,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_parallel_sections {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_parallel_sections {
+ };
+
+ // Sets for parallel workshare
+
+ static OmpClauseSet allowedClauses_OMPD_parallel_workshare {
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_copyin,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_shared,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_parallel_workshare {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_proc_bind,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_parallel_workshare {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_parallel_workshare {
+ };
+
+ // Sets for requires
+
+ static OmpClauseSet allowedClauses_OMPD_requires {
+ llvm::omp::Clause::OMPC_unified_address,
+ llvm::omp::Clause::OMPC_unified_shared_memory,
+ llvm::omp::Clause::OMPC_reverse_offload,
+ llvm::omp::Clause::OMPC_dynamic_allocators,
+ llvm::omp::Clause::OMPC_atomic_default_mem_order,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_requires {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_requires {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_requires {
+ };
+
+ // Sets for scan
+
+ static OmpClauseSet allowedClauses_OMPD_scan {
+ llvm::omp::Clause::OMPC_inclusive,
+ llvm::omp::Clause::OMPC_exclusive,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_scan {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_scan {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_scan {
+ };
+
+ // Sets for section
+
+ static OmpClauseSet allowedClauses_OMPD_section {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_section {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_section {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_section {
+ };
+
+ // Sets for sections
+
+ static OmpClauseSet allowedClauses_OMPD_sections {
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_nowait,
+ llvm::omp::Clause::OMPC_allocate,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_sections {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_sections {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_sections {
+ };
+
+ // Sets for simd
+
+ static OmpClauseSet allowedClauses_OMPD_simd {
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_nontemporal,
+ llvm::omp::Clause::OMPC_order,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_simd {
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ llvm::omp::Clause::OMPC_if,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_simd {
+ };
+
+ // Sets for single
+
+ static OmpClauseSet allowedClauses_OMPD_single {
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_copyprivate,
+ llvm::omp::Clause::OMPC_nowait,
+ llvm::omp::Clause::OMPC_allocate,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_single {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_single {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_single {
+ };
+
+ // Sets for target
+
+ static OmpClauseSet allowedClauses_OMPD_target {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_map,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_depend,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_is_device_ptr,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_uses_allocators,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_target {
+ llvm::omp::Clause::OMPC_device,
+ llvm::omp::Clause::OMPC_defaultmap,
+ llvm::omp::Clause::OMPC_nowait,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_target {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_target {
+ };
+
+ // Sets for target data
+
+ static OmpClauseSet allowedClauses_OMPD_target_data {
+ llvm::omp::Clause::OMPC_use_device_ptr,
+ llvm::omp::Clause::OMPC_use_device_addr,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_target_data {
+ llvm::omp::Clause::OMPC_device,
+ llvm::omp::Clause::OMPC_if,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_target_data {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_target_data {
+ llvm::omp::Clause::OMPC_map,
+ };
+
+ // Sets for target enter data
+
+ static OmpClauseSet allowedClauses_OMPD_target_enter_data {
+ llvm::omp::Clause::OMPC_depend,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_target_enter_data {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_device,
+ llvm::omp::Clause::OMPC_nowait,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_target_enter_data {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_target_enter_data {
+ llvm::omp::Clause::OMPC_map,
+ };
+
+ // Sets for target exit data
+
+ static OmpClauseSet allowedClauses_OMPD_target_exit_data {
+ llvm::omp::Clause::OMPC_depend,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_target_exit_data {
+ llvm::omp::Clause::OMPC_device,
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_nowait,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_target_exit_data {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_target_exit_data {
+ llvm::omp::Clause::OMPC_map,
+ };
+
+ // Sets for target parallel
+
+ static OmpClauseSet allowedClauses_OMPD_target_parallel {
+ llvm::omp::Clause::OMPC_map,
+ llvm::omp::Clause::OMPC_nowait,
+ llvm::omp::Clause::OMPC_depend,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_is_device_ptr,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_uses_allocators,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_target_parallel {
+ llvm::omp::Clause::OMPC_defaultmap,
+ llvm::omp::Clause::OMPC_device,
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_proc_bind,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_target_parallel {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_target_parallel {
+ };
+
+ // Sets for target parallel do
+
+ static OmpClauseSet allowedClauses_OMPD_target_parallel_do {
+ llvm::omp::Clause::OMPC_map,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_depend,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_is_device_ptr,
+ llvm::omp::Clause::OMPC_allocator,
+ llvm::omp::Clause::OMPC_order,
+ llvm::omp::Clause::OMPC_uses_allocators,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_copyin,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_target_parallel_do {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_device,
+ llvm::omp::Clause::OMPC_defaultmap,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_ordered,
+ llvm::omp::Clause::OMPC_nowait,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_target_parallel_do {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_target_parallel_do {
+ };
+
+ // Sets for target parallel do simd
+
+ static OmpClauseSet allowedClauses_OMPD_target_parallel_do_simd {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_device,
+ llvm::omp::Clause::OMPC_map,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_nowait,
+ llvm::omp::Clause::OMPC_depend,
+ llvm::omp::Clause::OMPC_defaultmap,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_ordered,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_is_device_ptr,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_nontemporal,
+ llvm::omp::Clause::OMPC_order,
+ llvm::omp::Clause::OMPC_uses_allocators,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_target_parallel_do_simd {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_target_parallel_do_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_target_parallel_do_simd {
+ };
+
+ // Sets for target parallel for
+
+ static OmpClauseSet allowedClauses_OMPD_target_parallel_for {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_device,
+ llvm::omp::Clause::OMPC_map,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_nowait,
+ llvm::omp::Clause::OMPC_depend,
+ llvm::omp::Clause::OMPC_defaultmap,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_ordered,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_is_device_ptr,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_order,
+ llvm::omp::Clause::OMPC_uses_allocators,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_target_parallel_for {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_target_parallel_for {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_target_parallel_for {
+ };
+
+ // Sets for target parallel for simd
+
+ static OmpClauseSet allowedClauses_OMPD_target_parallel_for_simd {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_device,
+ llvm::omp::Clause::OMPC_map,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_nowait,
+ llvm::omp::Clause::OMPC_depend,
+ llvm::omp::Clause::OMPC_defaultmap,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_ordered,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_is_device_ptr,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_nontemporal,
+ llvm::omp::Clause::OMPC_order,
+ llvm::omp::Clause::OMPC_uses_allocators,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_target_parallel_for_simd {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_target_parallel_for_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_target_parallel_for_simd {
+ };
+
+ // Sets for target simd
+
+ static OmpClauseSet allowedClauses_OMPD_target_simd {
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_depend,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_is_device_ptr,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_map,
+ llvm::omp::Clause::OMPC_nontemporal,
+ llvm::omp::Clause::OMPC_nowait,
+ llvm::omp::Clause::OMPC_order,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_uses_allocators,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_target_simd {
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_device,
+ llvm::omp::Clause::OMPC_defaultmap,
+ llvm::omp::Clause::OMPC_schedule,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_target_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_target_simd {
+ };
+
+ // Sets for target teams
+
+ static OmpClauseSet allowedClauses_OMPD_target_teams {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_map,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_depend,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_is_device_ptr,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_uses_allocators,
+ llvm::omp::Clause::OMPC_shared,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_target_teams {
+ llvm::omp::Clause::OMPC_device,
+ llvm::omp::Clause::OMPC_nowait,
+ llvm::omp::Clause::OMPC_defaultmap,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_num_teams,
+ llvm::omp::Clause::OMPC_thread_limit,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_target_teams {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_target_teams {
+ };
+
+ // Sets for target teams distribute
+
+ static OmpClauseSet allowedClauses_OMPD_target_teams_distribute {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_map,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_depend,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_is_device_ptr,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_uses_allocators,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_lastprivate,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_target_teams_distribute {
+ llvm::omp::Clause::OMPC_device,
+ llvm::omp::Clause::OMPC_nowait,
+ llvm::omp::Clause::OMPC_defaultmap,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_num_teams,
+ llvm::omp::Clause::OMPC_thread_limit,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_dist_schedule,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_target_teams_distribute {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_target_teams_distribute {
+ };
+
+ // Sets for target teams distribute parallel do
+
+ static OmpClauseSet allowedClauses_OMPD_target_teams_distribute_parallel_do {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_map,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_depend,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_is_device_ptr,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_uses_allocators,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_copyin,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_ordered,
+ llvm::omp::Clause::OMPC_order,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_target_teams_distribute_parallel_do {
+ llvm::omp::Clause::OMPC_device,
+ llvm::omp::Clause::OMPC_defaultmap,
+ llvm::omp::Clause::OMPC_nowait,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_num_teams,
+ llvm::omp::Clause::OMPC_thread_limit,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_dist_schedule,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_schedule,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_target_teams_distribute_parallel_do {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_target_teams_distribute_parallel_do {
+ };
+
+ // Sets for target teams distribute parallel do simd
+
+ static OmpClauseSet allowedClauses_OMPD_target_teams_distribute_parallel_do_simd {
+ llvm::omp::Clause::OMPC_map,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_depend,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_is_device_ptr,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_uses_allocators,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_copyin,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_ordered,
+ llvm::omp::Clause::OMPC_order,
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_nontemporal,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_target_teams_distribute_parallel_do_simd {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_device,
+ llvm::omp::Clause::OMPC_nowait,
+ llvm::omp::Clause::OMPC_defaultmap,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_num_teams,
+ llvm::omp::Clause::OMPC_thread_limit,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_dist_schedule,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_target_teams_distribute_parallel_do_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_target_teams_distribute_parallel_do_simd {
+ };
+
+ // Sets for target teams distribute parallel for
+
+ static OmpClauseSet allowedClauses_OMPD_target_teams_distribute_parallel_for {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_device,
+ llvm::omp::Clause::OMPC_map,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_nowait,
+ llvm::omp::Clause::OMPC_depend,
+ llvm::omp::Clause::OMPC_defaultmap,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_is_device_ptr,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_num_teams,
+ llvm::omp::Clause::OMPC_thread_limit,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_dist_schedule,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_order,
+ llvm::omp::Clause::OMPC_uses_allocators,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_target_teams_distribute_parallel_for {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_target_teams_distribute_parallel_for {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_target_teams_distribute_parallel_for {
+ };
+
+ // Sets for target teams distribute parallel for simd
+
+ static OmpClauseSet allowedClauses_OMPD_target_teams_distribute_parallel_for_simd {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_device,
+ llvm::omp::Clause::OMPC_map,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_nowait,
+ llvm::omp::Clause::OMPC_depend,
+ llvm::omp::Clause::OMPC_defaultmap,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_is_device_ptr,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_num_teams,
+ llvm::omp::Clause::OMPC_thread_limit,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_dist_schedule,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_nontemporal,
+ llvm::omp::Clause::OMPC_order,
+ llvm::omp::Clause::OMPC_uses_allocators,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_target_teams_distribute_parallel_for_simd {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_target_teams_distribute_parallel_for_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_target_teams_distribute_parallel_for_simd {
+ };
+
+ // Sets for target teams distribute simd
+
+ static OmpClauseSet allowedClauses_OMPD_target_teams_distribute_simd {
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_depend,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_is_device_ptr,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_map,
+ llvm::omp::Clause::OMPC_nontemporal,
+ llvm::omp::Clause::OMPC_order,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_uses_allocators,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_target_teams_distribute_simd {
+ llvm::omp::Clause::OMPC_device,
+ llvm::omp::Clause::OMPC_defaultmap,
+ llvm::omp::Clause::OMPC_nowait,
+ llvm::omp::Clause::OMPC_num_teams,
+ llvm::omp::Clause::OMPC_thread_limit,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_dist_schedule,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_target_teams_distribute_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_target_teams_distribute_simd {
+ };
+
+ // Sets for target update
+
+ static OmpClauseSet allowedClauses_OMPD_target_update {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_device,
+ llvm::omp::Clause::OMPC_to,
+ llvm::omp::Clause::OMPC_from,
+ llvm::omp::Clause::OMPC_nowait,
+ llvm::omp::Clause::OMPC_depend,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_target_update {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_target_update {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_target_update {
+ };
+
+ // Sets for task
+
+ static OmpClauseSet allowedClauses_OMPD_task {
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_untied,
+ llvm::omp::Clause::OMPC_mergeable,
+ llvm::omp::Clause::OMPC_depend,
+ llvm::omp::Clause::OMPC_in_reduction,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_detach,
+ llvm::omp::Clause::OMPC_affinity,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_task {
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_final,
+ llvm::omp::Clause::OMPC_priority,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_task {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_task {
+ };
+
+ // Sets for taskgroup
+
+ static OmpClauseSet allowedClauses_OMPD_taskgroup {
+ llvm::omp::Clause::OMPC_task_reduction,
+ llvm::omp::Clause::OMPC_allocate,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_taskgroup {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_taskgroup {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_taskgroup {
+ };
+
+ // Sets for taskloop
+
+ static OmpClauseSet allowedClauses_OMPD_taskloop {
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_untied,
+ llvm::omp::Clause::OMPC_mergeable,
+ llvm::omp::Clause::OMPC_nogroup,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_in_reduction,
+ llvm::omp::Clause::OMPC_allocate,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_taskloop {
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_final,
+ llvm::omp::Clause::OMPC_priority,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_taskloop {
+ llvm::omp::Clause::OMPC_grainsize,
+ llvm::omp::Clause::OMPC_num_tasks,
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_taskloop {
+ };
+
+ // Sets for taskloop simd
+
+ static OmpClauseSet allowedClauses_OMPD_taskloop_simd {
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_in_reduction,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_mergeable,
+ llvm::omp::Clause::OMPC_nogroup,
+ llvm::omp::Clause::OMPC_nontemporal,
+ llvm::omp::Clause::OMPC_order,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_untied,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_taskloop_simd {
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ llvm::omp::Clause::OMPC_final,
+ llvm::omp::Clause::OMPC_priority,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_taskloop_simd {
+ llvm::omp::Clause::OMPC_grainsize,
+ llvm::omp::Clause::OMPC_num_tasks,
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_taskloop_simd {
+ };
+
+ // Sets for taskwait
+
+ static OmpClauseSet allowedClauses_OMPD_taskwait {
+ llvm::omp::Clause::OMPC_depend,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_taskwait {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_taskwait {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_taskwait {
+ };
+
+ // Sets for taskyield
+
+ static OmpClauseSet allowedClauses_OMPD_taskyield {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_taskyield {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_taskyield {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_taskyield {
+ };
+
+ // Sets for teams
+
+ static OmpClauseSet allowedClauses_OMPD_teams {
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_allocate,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_teams {
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_num_teams,
+ llvm::omp::Clause::OMPC_thread_limit,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_teams {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_teams {
+ };
+
+ // Sets for teams distribute
+
+ static OmpClauseSet allowedClauses_OMPD_teams_distribute {
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_num_teams,
+ llvm::omp::Clause::OMPC_thread_limit,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_dist_schedule,
+ llvm::omp::Clause::OMPC_allocate,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_teams_distribute {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_teams_distribute {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_teams_distribute {
+ };
+
+ // Sets for teams distribute parallel do
+
+ static OmpClauseSet allowedClauses_OMPD_teams_distribute_parallel_do {
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_copyin,
+ llvm::omp::Clause::OMPC_linear,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_teams_distribute_parallel_do {
+ llvm::omp::Clause::OMPC_num_teams,
+ llvm::omp::Clause::OMPC_thread_limit,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_dist_schedule,
+ llvm::omp::Clause::OMPC_ordered,
+ llvm::omp::Clause::OMPC_order,
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_schedule,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_teams_distribute_parallel_do {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_teams_distribute_parallel_do {
+ };
+
+ // Sets for teams distribute parallel do simd
+
+ static OmpClauseSet allowedClauses_OMPD_teams_distribute_parallel_do_simd {
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_order,
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_nontemporal,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_teams_distribute_parallel_do_simd {
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_num_teams,
+ llvm::omp::Clause::OMPC_thread_limit,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_dist_schedule,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ llvm::omp::Clause::OMPC_if,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_teams_distribute_parallel_do_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_teams_distribute_parallel_do_simd {
+ };
+
+ // Sets for teams distribute parallel for
+
+ static OmpClauseSet allowedClauses_OMPD_teams_distribute_parallel_for {
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_dist_schedule,
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_num_teams,
+ llvm::omp::Clause::OMPC_thread_limit,
+ llvm::omp::Clause::OMPC_copyin,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_order,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_teams_distribute_parallel_for {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_teams_distribute_parallel_for {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_teams_distribute_parallel_for {
+ };
+
+ // Sets for teams distribute parallel for simd
+
+ static OmpClauseSet allowedClauses_OMPD_teams_distribute_parallel_for_simd {
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_dist_schedule,
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_threads,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_proc_bind,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_shared,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_schedule,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ llvm::omp::Clause::OMPC_num_teams,
+ llvm::omp::Clause::OMPC_thread_limit,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_nontemporal,
+ llvm::omp::Clause::OMPC_order,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_teams_distribute_parallel_for_simd {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_teams_distribute_parallel_for_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_teams_distribute_parallel_for_simd {
+ };
+
+ // Sets for teams distribute simd
+
+ static OmpClauseSet allowedClauses_OMPD_teams_distribute_simd {
+ llvm::omp::Clause::OMPC_aligned,
+ llvm::omp::Clause::OMPC_allocate,
+ llvm::omp::Clause::OMPC_firstprivate,
+ llvm::omp::Clause::OMPC_lastprivate,
+ llvm::omp::Clause::OMPC_linear,
+ llvm::omp::Clause::OMPC_nontemporal,
+ llvm::omp::Clause::OMPC_order,
+ llvm::omp::Clause::OMPC_private,
+ llvm::omp::Clause::OMPC_reduction,
+ llvm::omp::Clause::OMPC_shared,
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_teams_distribute_simd {
+ llvm::omp::Clause::OMPC_collapse,
+ llvm::omp::Clause::OMPC_default,
+ llvm::omp::Clause::OMPC_dist_schedule,
+ llvm::omp::Clause::OMPC_if,
+ llvm::omp::Clause::OMPC_num_teams,
+ llvm::omp::Clause::OMPC_safelen,
+ llvm::omp::Clause::OMPC_simdlen,
+ llvm::omp::Clause::OMPC_thread_limit,
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_teams_distribute_simd {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_teams_distribute_simd {
+ };
+
+ // Sets for threadprivate
+
+ static OmpClauseSet allowedClauses_OMPD_threadprivate {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_threadprivate {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_threadprivate {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_threadprivate {
+ };
+
+ // Sets for unknown
+
+ static OmpClauseSet allowedClauses_OMPD_unknown {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_unknown {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_unknown {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_unknown {
+ };
+
+ // Sets for workshare
+
+ static OmpClauseSet allowedClauses_OMPD_workshare {
+ };
+
+ static OmpClauseSet allowedOnceClauses_OMPD_workshare {
+ };
+
+ static OmpClauseSet allowedExclusiveClauses_OMPD_workshare {
+ };
+
+ static OmpClauseSet requiredClauses_OMPD_workshare {
+ };
+} // namespace omp
+} // namespace llvm
+
+#endif // GEN_FLANG_DIRECTIVE_CLAUSE_SETS
+
+#ifdef GEN_FLANG_DIRECTIVE_CLAUSE_MAP
+#undef GEN_FLANG_DIRECTIVE_CLAUSE_MAP
+
+{
+ {llvm::omp::Directive::OMPD_allocate,
+ {
+ llvm::omp::allowedClauses_OMPD_allocate,
+ llvm::omp::allowedOnceClauses_OMPD_allocate,
+ llvm::omp::allowedExclusiveClauses_OMPD_allocate,
+ llvm::omp::requiredClauses_OMPD_allocate,
+ }
+ },
+ {llvm::omp::Directive::OMPD_assumes,
+ {
+ llvm::omp::allowedClauses_OMPD_assumes,
+ llvm::omp::allowedOnceClauses_OMPD_assumes,
+ llvm::omp::allowedExclusiveClauses_OMPD_assumes,
+ llvm::omp::requiredClauses_OMPD_assumes,
+ }
+ },
+ {llvm::omp::Directive::OMPD_atomic,
+ {
+ llvm::omp::allowedClauses_OMPD_atomic,
+ llvm::omp::allowedOnceClauses_OMPD_atomic,
+ llvm::omp::allowedExclusiveClauses_OMPD_atomic,
+ llvm::omp::requiredClauses_OMPD_atomic,
+ }
+ },
+ {llvm::omp::Directive::OMPD_barrier,
+ {
+ llvm::omp::allowedClauses_OMPD_barrier,
+ llvm::omp::allowedOnceClauses_OMPD_barrier,
+ llvm::omp::allowedExclusiveClauses_OMPD_barrier,
+ llvm::omp::requiredClauses_OMPD_barrier,
+ }
+ },
+ {llvm::omp::Directive::OMPD_begin_assumes,
+ {
+ llvm::omp::allowedClauses_OMPD_begin_assumes,
+ llvm::omp::allowedOnceClauses_OMPD_begin_assumes,
+ llvm::omp::allowedExclusiveClauses_OMPD_begin_assumes,
+ llvm::omp::requiredClauses_OMPD_begin_assumes,
+ }
+ },
+ {llvm::omp::Directive::OMPD_begin_declare_variant,
+ {
+ llvm::omp::allowedClauses_OMPD_begin_declare_variant,
+ llvm::omp::allowedOnceClauses_OMPD_begin_declare_variant,
+ llvm::omp::allowedExclusiveClauses_OMPD_begin_declare_variant,
+ llvm::omp::requiredClauses_OMPD_begin_declare_variant,
+ }
+ },
+ {llvm::omp::Directive::OMPD_cancel,
+ {
+ llvm::omp::allowedClauses_OMPD_cancel,
+ llvm::omp::allowedOnceClauses_OMPD_cancel,
+ llvm::omp::allowedExclusiveClauses_OMPD_cancel,
+ llvm::omp::requiredClauses_OMPD_cancel,
+ }
+ },
+ {llvm::omp::Directive::OMPD_cancellation_point,
+ {
+ llvm::omp::allowedClauses_OMPD_cancellation_point,
+ llvm::omp::allowedOnceClauses_OMPD_cancellation_point,
+ llvm::omp::allowedExclusiveClauses_OMPD_cancellation_point,
+ llvm::omp::requiredClauses_OMPD_cancellation_point,
+ }
+ },
+ {llvm::omp::Directive::OMPD_critical,
+ {
+ llvm::omp::allowedClauses_OMPD_critical,
+ llvm::omp::allowedOnceClauses_OMPD_critical,
+ llvm::omp::allowedExclusiveClauses_OMPD_critical,
+ llvm::omp::requiredClauses_OMPD_critical,
+ }
+ },
+ {llvm::omp::Directive::OMPD_declare_mapper,
+ {
+ llvm::omp::allowedClauses_OMPD_declare_mapper,
+ llvm::omp::allowedOnceClauses_OMPD_declare_mapper,
+ llvm::omp::allowedExclusiveClauses_OMPD_declare_mapper,
+ llvm::omp::requiredClauses_OMPD_declare_mapper,
+ }
+ },
+ {llvm::omp::Directive::OMPD_declare_reduction,
+ {
+ llvm::omp::allowedClauses_OMPD_declare_reduction,
+ llvm::omp::allowedOnceClauses_OMPD_declare_reduction,
+ llvm::omp::allowedExclusiveClauses_OMPD_declare_reduction,
+ llvm::omp::requiredClauses_OMPD_declare_reduction,
+ }
+ },
+ {llvm::omp::Directive::OMPD_declare_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_declare_simd,
+ llvm::omp::allowedOnceClauses_OMPD_declare_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_declare_simd,
+ llvm::omp::requiredClauses_OMPD_declare_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_declare_target,
+ {
+ llvm::omp::allowedClauses_OMPD_declare_target,
+ llvm::omp::allowedOnceClauses_OMPD_declare_target,
+ llvm::omp::allowedExclusiveClauses_OMPD_declare_target,
+ llvm::omp::requiredClauses_OMPD_declare_target,
+ }
+ },
+ {llvm::omp::Directive::OMPD_declare_variant,
+ {
+ llvm::omp::allowedClauses_OMPD_declare_variant,
+ llvm::omp::allowedOnceClauses_OMPD_declare_variant,
+ llvm::omp::allowedExclusiveClauses_OMPD_declare_variant,
+ llvm::omp::requiredClauses_OMPD_declare_variant,
+ }
+ },
+ {llvm::omp::Directive::OMPD_depobj,
+ {
+ llvm::omp::allowedClauses_OMPD_depobj,
+ llvm::omp::allowedOnceClauses_OMPD_depobj,
+ llvm::omp::allowedExclusiveClauses_OMPD_depobj,
+ llvm::omp::requiredClauses_OMPD_depobj,
+ }
+ },
+ {llvm::omp::Directive::OMPD_distribute,
+ {
+ llvm::omp::allowedClauses_OMPD_distribute,
+ llvm::omp::allowedOnceClauses_OMPD_distribute,
+ llvm::omp::allowedExclusiveClauses_OMPD_distribute,
+ llvm::omp::requiredClauses_OMPD_distribute,
+ }
+ },
+ {llvm::omp::Directive::OMPD_distribute_parallel_do,
+ {
+ llvm::omp::allowedClauses_OMPD_distribute_parallel_do,
+ llvm::omp::allowedOnceClauses_OMPD_distribute_parallel_do,
+ llvm::omp::allowedExclusiveClauses_OMPD_distribute_parallel_do,
+ llvm::omp::requiredClauses_OMPD_distribute_parallel_do,
+ }
+ },
+ {llvm::omp::Directive::OMPD_distribute_parallel_do_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_distribute_parallel_do_simd,
+ llvm::omp::allowedOnceClauses_OMPD_distribute_parallel_do_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_distribute_parallel_do_simd,
+ llvm::omp::requiredClauses_OMPD_distribute_parallel_do_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_distribute_parallel_for,
+ {
+ llvm::omp::allowedClauses_OMPD_distribute_parallel_for,
+ llvm::omp::allowedOnceClauses_OMPD_distribute_parallel_for,
+ llvm::omp::allowedExclusiveClauses_OMPD_distribute_parallel_for,
+ llvm::omp::requiredClauses_OMPD_distribute_parallel_for,
+ }
+ },
+ {llvm::omp::Directive::OMPD_distribute_parallel_for_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_distribute_parallel_for_simd,
+ llvm::omp::allowedOnceClauses_OMPD_distribute_parallel_for_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_distribute_parallel_for_simd,
+ llvm::omp::requiredClauses_OMPD_distribute_parallel_for_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_distribute_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_distribute_simd,
+ llvm::omp::allowedOnceClauses_OMPD_distribute_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_distribute_simd,
+ llvm::omp::requiredClauses_OMPD_distribute_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_do,
+ {
+ llvm::omp::allowedClauses_OMPD_do,
+ llvm::omp::allowedOnceClauses_OMPD_do,
+ llvm::omp::allowedExclusiveClauses_OMPD_do,
+ llvm::omp::requiredClauses_OMPD_do,
+ }
+ },
+ {llvm::omp::Directive::OMPD_do_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_do_simd,
+ llvm::omp::allowedOnceClauses_OMPD_do_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_do_simd,
+ llvm::omp::requiredClauses_OMPD_do_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_end_assumes,
+ {
+ llvm::omp::allowedClauses_OMPD_end_assumes,
+ llvm::omp::allowedOnceClauses_OMPD_end_assumes,
+ llvm::omp::allowedExclusiveClauses_OMPD_end_assumes,
+ llvm::omp::requiredClauses_OMPD_end_assumes,
+ }
+ },
+ {llvm::omp::Directive::OMPD_end_declare_target,
+ {
+ llvm::omp::allowedClauses_OMPD_end_declare_target,
+ llvm::omp::allowedOnceClauses_OMPD_end_declare_target,
+ llvm::omp::allowedExclusiveClauses_OMPD_end_declare_target,
+ llvm::omp::requiredClauses_OMPD_end_declare_target,
+ }
+ },
+ {llvm::omp::Directive::OMPD_end_declare_variant,
+ {
+ llvm::omp::allowedClauses_OMPD_end_declare_variant,
+ llvm::omp::allowedOnceClauses_OMPD_end_declare_variant,
+ llvm::omp::allowedExclusiveClauses_OMPD_end_declare_variant,
+ llvm::omp::requiredClauses_OMPD_end_declare_variant,
+ }
+ },
+ {llvm::omp::Directive::OMPD_end_do,
+ {
+ llvm::omp::allowedClauses_OMPD_end_do,
+ llvm::omp::allowedOnceClauses_OMPD_end_do,
+ llvm::omp::allowedExclusiveClauses_OMPD_end_do,
+ llvm::omp::requiredClauses_OMPD_end_do,
+ }
+ },
+ {llvm::omp::Directive::OMPD_end_do_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_end_do_simd,
+ llvm::omp::allowedOnceClauses_OMPD_end_do_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_end_do_simd,
+ llvm::omp::requiredClauses_OMPD_end_do_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_end_sections,
+ {
+ llvm::omp::allowedClauses_OMPD_end_sections,
+ llvm::omp::allowedOnceClauses_OMPD_end_sections,
+ llvm::omp::allowedExclusiveClauses_OMPD_end_sections,
+ llvm::omp::requiredClauses_OMPD_end_sections,
+ }
+ },
+ {llvm::omp::Directive::OMPD_end_single,
+ {
+ llvm::omp::allowedClauses_OMPD_end_single,
+ llvm::omp::allowedOnceClauses_OMPD_end_single,
+ llvm::omp::allowedExclusiveClauses_OMPD_end_single,
+ llvm::omp::requiredClauses_OMPD_end_single,
+ }
+ },
+ {llvm::omp::Directive::OMPD_end_workshare,
+ {
+ llvm::omp::allowedClauses_OMPD_end_workshare,
+ llvm::omp::allowedOnceClauses_OMPD_end_workshare,
+ llvm::omp::allowedExclusiveClauses_OMPD_end_workshare,
+ llvm::omp::requiredClauses_OMPD_end_workshare,
+ }
+ },
+ {llvm::omp::Directive::OMPD_flush,
+ {
+ llvm::omp::allowedClauses_OMPD_flush,
+ llvm::omp::allowedOnceClauses_OMPD_flush,
+ llvm::omp::allowedExclusiveClauses_OMPD_flush,
+ llvm::omp::requiredClauses_OMPD_flush,
+ }
+ },
+ {llvm::omp::Directive::OMPD_for,
+ {
+ llvm::omp::allowedClauses_OMPD_for,
+ llvm::omp::allowedOnceClauses_OMPD_for,
+ llvm::omp::allowedExclusiveClauses_OMPD_for,
+ llvm::omp::requiredClauses_OMPD_for,
+ }
+ },
+ {llvm::omp::Directive::OMPD_for_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_for_simd,
+ llvm::omp::allowedOnceClauses_OMPD_for_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_for_simd,
+ llvm::omp::requiredClauses_OMPD_for_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_master,
+ {
+ llvm::omp::allowedClauses_OMPD_master,
+ llvm::omp::allowedOnceClauses_OMPD_master,
+ llvm::omp::allowedExclusiveClauses_OMPD_master,
+ llvm::omp::requiredClauses_OMPD_master,
+ }
+ },
+ {llvm::omp::Directive::OMPD_master_taskloop,
+ {
+ llvm::omp::allowedClauses_OMPD_master_taskloop,
+ llvm::omp::allowedOnceClauses_OMPD_master_taskloop,
+ llvm::omp::allowedExclusiveClauses_OMPD_master_taskloop,
+ llvm::omp::requiredClauses_OMPD_master_taskloop,
+ }
+ },
+ {llvm::omp::Directive::OMPD_master_taskloop_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_master_taskloop_simd,
+ llvm::omp::allowedOnceClauses_OMPD_master_taskloop_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_master_taskloop_simd,
+ llvm::omp::requiredClauses_OMPD_master_taskloop_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_ordered,
+ {
+ llvm::omp::allowedClauses_OMPD_ordered,
+ llvm::omp::allowedOnceClauses_OMPD_ordered,
+ llvm::omp::allowedExclusiveClauses_OMPD_ordered,
+ llvm::omp::requiredClauses_OMPD_ordered,
+ }
+ },
+ {llvm::omp::Directive::OMPD_parallel,
+ {
+ llvm::omp::allowedClauses_OMPD_parallel,
+ llvm::omp::allowedOnceClauses_OMPD_parallel,
+ llvm::omp::allowedExclusiveClauses_OMPD_parallel,
+ llvm::omp::requiredClauses_OMPD_parallel,
+ }
+ },
+ {llvm::omp::Directive::OMPD_parallel_do,
+ {
+ llvm::omp::allowedClauses_OMPD_parallel_do,
+ llvm::omp::allowedOnceClauses_OMPD_parallel_do,
+ llvm::omp::allowedExclusiveClauses_OMPD_parallel_do,
+ llvm::omp::requiredClauses_OMPD_parallel_do,
+ }
+ },
+ {llvm::omp::Directive::OMPD_parallel_do_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_parallel_do_simd,
+ llvm::omp::allowedOnceClauses_OMPD_parallel_do_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_parallel_do_simd,
+ llvm::omp::requiredClauses_OMPD_parallel_do_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_parallel_for,
+ {
+ llvm::omp::allowedClauses_OMPD_parallel_for,
+ llvm::omp::allowedOnceClauses_OMPD_parallel_for,
+ llvm::omp::allowedExclusiveClauses_OMPD_parallel_for,
+ llvm::omp::requiredClauses_OMPD_parallel_for,
+ }
+ },
+ {llvm::omp::Directive::OMPD_parallel_for_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_parallel_for_simd,
+ llvm::omp::allowedOnceClauses_OMPD_parallel_for_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_parallel_for_simd,
+ llvm::omp::requiredClauses_OMPD_parallel_for_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_parallel_master,
+ {
+ llvm::omp::allowedClauses_OMPD_parallel_master,
+ llvm::omp::allowedOnceClauses_OMPD_parallel_master,
+ llvm::omp::allowedExclusiveClauses_OMPD_parallel_master,
+ llvm::omp::requiredClauses_OMPD_parallel_master,
+ }
+ },
+ {llvm::omp::Directive::OMPD_parallel_master_taskloop,
+ {
+ llvm::omp::allowedClauses_OMPD_parallel_master_taskloop,
+ llvm::omp::allowedOnceClauses_OMPD_parallel_master_taskloop,
+ llvm::omp::allowedExclusiveClauses_OMPD_parallel_master_taskloop,
+ llvm::omp::requiredClauses_OMPD_parallel_master_taskloop,
+ }
+ },
+ {llvm::omp::Directive::OMPD_parallel_master_taskloop_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_parallel_master_taskloop_simd,
+ llvm::omp::allowedOnceClauses_OMPD_parallel_master_taskloop_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_parallel_master_taskloop_simd,
+ llvm::omp::requiredClauses_OMPD_parallel_master_taskloop_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_parallel_sections,
+ {
+ llvm::omp::allowedClauses_OMPD_parallel_sections,
+ llvm::omp::allowedOnceClauses_OMPD_parallel_sections,
+ llvm::omp::allowedExclusiveClauses_OMPD_parallel_sections,
+ llvm::omp::requiredClauses_OMPD_parallel_sections,
+ }
+ },
+ {llvm::omp::Directive::OMPD_parallel_workshare,
+ {
+ llvm::omp::allowedClauses_OMPD_parallel_workshare,
+ llvm::omp::allowedOnceClauses_OMPD_parallel_workshare,
+ llvm::omp::allowedExclusiveClauses_OMPD_parallel_workshare,
+ llvm::omp::requiredClauses_OMPD_parallel_workshare,
+ }
+ },
+ {llvm::omp::Directive::OMPD_requires,
+ {
+ llvm::omp::allowedClauses_OMPD_requires,
+ llvm::omp::allowedOnceClauses_OMPD_requires,
+ llvm::omp::allowedExclusiveClauses_OMPD_requires,
+ llvm::omp::requiredClauses_OMPD_requires,
+ }
+ },
+ {llvm::omp::Directive::OMPD_scan,
+ {
+ llvm::omp::allowedClauses_OMPD_scan,
+ llvm::omp::allowedOnceClauses_OMPD_scan,
+ llvm::omp::allowedExclusiveClauses_OMPD_scan,
+ llvm::omp::requiredClauses_OMPD_scan,
+ }
+ },
+ {llvm::omp::Directive::OMPD_section,
+ {
+ llvm::omp::allowedClauses_OMPD_section,
+ llvm::omp::allowedOnceClauses_OMPD_section,
+ llvm::omp::allowedExclusiveClauses_OMPD_section,
+ llvm::omp::requiredClauses_OMPD_section,
+ }
+ },
+ {llvm::omp::Directive::OMPD_sections,
+ {
+ llvm::omp::allowedClauses_OMPD_sections,
+ llvm::omp::allowedOnceClauses_OMPD_sections,
+ llvm::omp::allowedExclusiveClauses_OMPD_sections,
+ llvm::omp::requiredClauses_OMPD_sections,
+ }
+ },
+ {llvm::omp::Directive::OMPD_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_simd,
+ llvm::omp::allowedOnceClauses_OMPD_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_simd,
+ llvm::omp::requiredClauses_OMPD_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_single,
+ {
+ llvm::omp::allowedClauses_OMPD_single,
+ llvm::omp::allowedOnceClauses_OMPD_single,
+ llvm::omp::allowedExclusiveClauses_OMPD_single,
+ llvm::omp::requiredClauses_OMPD_single,
+ }
+ },
+ {llvm::omp::Directive::OMPD_target,
+ {
+ llvm::omp::allowedClauses_OMPD_target,
+ llvm::omp::allowedOnceClauses_OMPD_target,
+ llvm::omp::allowedExclusiveClauses_OMPD_target,
+ llvm::omp::requiredClauses_OMPD_target,
+ }
+ },
+ {llvm::omp::Directive::OMPD_target_data,
+ {
+ llvm::omp::allowedClauses_OMPD_target_data,
+ llvm::omp::allowedOnceClauses_OMPD_target_data,
+ llvm::omp::allowedExclusiveClauses_OMPD_target_data,
+ llvm::omp::requiredClauses_OMPD_target_data,
+ }
+ },
+ {llvm::omp::Directive::OMPD_target_enter_data,
+ {
+ llvm::omp::allowedClauses_OMPD_target_enter_data,
+ llvm::omp::allowedOnceClauses_OMPD_target_enter_data,
+ llvm::omp::allowedExclusiveClauses_OMPD_target_enter_data,
+ llvm::omp::requiredClauses_OMPD_target_enter_data,
+ }
+ },
+ {llvm::omp::Directive::OMPD_target_exit_data,
+ {
+ llvm::omp::allowedClauses_OMPD_target_exit_data,
+ llvm::omp::allowedOnceClauses_OMPD_target_exit_data,
+ llvm::omp::allowedExclusiveClauses_OMPD_target_exit_data,
+ llvm::omp::requiredClauses_OMPD_target_exit_data,
+ }
+ },
+ {llvm::omp::Directive::OMPD_target_parallel,
+ {
+ llvm::omp::allowedClauses_OMPD_target_parallel,
+ llvm::omp::allowedOnceClauses_OMPD_target_parallel,
+ llvm::omp::allowedExclusiveClauses_OMPD_target_parallel,
+ llvm::omp::requiredClauses_OMPD_target_parallel,
+ }
+ },
+ {llvm::omp::Directive::OMPD_target_parallel_do,
+ {
+ llvm::omp::allowedClauses_OMPD_target_parallel_do,
+ llvm::omp::allowedOnceClauses_OMPD_target_parallel_do,
+ llvm::omp::allowedExclusiveClauses_OMPD_target_parallel_do,
+ llvm::omp::requiredClauses_OMPD_target_parallel_do,
+ }
+ },
+ {llvm::omp::Directive::OMPD_target_parallel_do_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_target_parallel_do_simd,
+ llvm::omp::allowedOnceClauses_OMPD_target_parallel_do_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_target_parallel_do_simd,
+ llvm::omp::requiredClauses_OMPD_target_parallel_do_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_target_parallel_for,
+ {
+ llvm::omp::allowedClauses_OMPD_target_parallel_for,
+ llvm::omp::allowedOnceClauses_OMPD_target_parallel_for,
+ llvm::omp::allowedExclusiveClauses_OMPD_target_parallel_for,
+ llvm::omp::requiredClauses_OMPD_target_parallel_for,
+ }
+ },
+ {llvm::omp::Directive::OMPD_target_parallel_for_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_target_parallel_for_simd,
+ llvm::omp::allowedOnceClauses_OMPD_target_parallel_for_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_target_parallel_for_simd,
+ llvm::omp::requiredClauses_OMPD_target_parallel_for_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_target_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_target_simd,
+ llvm::omp::allowedOnceClauses_OMPD_target_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_target_simd,
+ llvm::omp::requiredClauses_OMPD_target_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_target_teams,
+ {
+ llvm::omp::allowedClauses_OMPD_target_teams,
+ llvm::omp::allowedOnceClauses_OMPD_target_teams,
+ llvm::omp::allowedExclusiveClauses_OMPD_target_teams,
+ llvm::omp::requiredClauses_OMPD_target_teams,
+ }
+ },
+ {llvm::omp::Directive::OMPD_target_teams_distribute,
+ {
+ llvm::omp::allowedClauses_OMPD_target_teams_distribute,
+ llvm::omp::allowedOnceClauses_OMPD_target_teams_distribute,
+ llvm::omp::allowedExclusiveClauses_OMPD_target_teams_distribute,
+ llvm::omp::requiredClauses_OMPD_target_teams_distribute,
+ }
+ },
+ {llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do,
+ {
+ llvm::omp::allowedClauses_OMPD_target_teams_distribute_parallel_do,
+ llvm::omp::allowedOnceClauses_OMPD_target_teams_distribute_parallel_do,
+ llvm::omp::allowedExclusiveClauses_OMPD_target_teams_distribute_parallel_do,
+ llvm::omp::requiredClauses_OMPD_target_teams_distribute_parallel_do,
+ }
+ },
+ {llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_target_teams_distribute_parallel_do_simd,
+ llvm::omp::allowedOnceClauses_OMPD_target_teams_distribute_parallel_do_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_target_teams_distribute_parallel_do_simd,
+ llvm::omp::requiredClauses_OMPD_target_teams_distribute_parallel_do_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_target_teams_distribute_parallel_for,
+ {
+ llvm::omp::allowedClauses_OMPD_target_teams_distribute_parallel_for,
+ llvm::omp::allowedOnceClauses_OMPD_target_teams_distribute_parallel_for,
+ llvm::omp::allowedExclusiveClauses_OMPD_target_teams_distribute_parallel_for,
+ llvm::omp::requiredClauses_OMPD_target_teams_distribute_parallel_for,
+ }
+ },
+ {llvm::omp::Directive::OMPD_target_teams_distribute_parallel_for_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_target_teams_distribute_parallel_for_simd,
+ llvm::omp::allowedOnceClauses_OMPD_target_teams_distribute_parallel_for_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_target_teams_distribute_parallel_for_simd,
+ llvm::omp::requiredClauses_OMPD_target_teams_distribute_parallel_for_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_target_teams_distribute_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_target_teams_distribute_simd,
+ llvm::omp::allowedOnceClauses_OMPD_target_teams_distribute_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_target_teams_distribute_simd,
+ llvm::omp::requiredClauses_OMPD_target_teams_distribute_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_target_update,
+ {
+ llvm::omp::allowedClauses_OMPD_target_update,
+ llvm::omp::allowedOnceClauses_OMPD_target_update,
+ llvm::omp::allowedExclusiveClauses_OMPD_target_update,
+ llvm::omp::requiredClauses_OMPD_target_update,
+ }
+ },
+ {llvm::omp::Directive::OMPD_task,
+ {
+ llvm::omp::allowedClauses_OMPD_task,
+ llvm::omp::allowedOnceClauses_OMPD_task,
+ llvm::omp::allowedExclusiveClauses_OMPD_task,
+ llvm::omp::requiredClauses_OMPD_task,
+ }
+ },
+ {llvm::omp::Directive::OMPD_taskgroup,
+ {
+ llvm::omp::allowedClauses_OMPD_taskgroup,
+ llvm::omp::allowedOnceClauses_OMPD_taskgroup,
+ llvm::omp::allowedExclusiveClauses_OMPD_taskgroup,
+ llvm::omp::requiredClauses_OMPD_taskgroup,
+ }
+ },
+ {llvm::omp::Directive::OMPD_taskloop,
+ {
+ llvm::omp::allowedClauses_OMPD_taskloop,
+ llvm::omp::allowedOnceClauses_OMPD_taskloop,
+ llvm::omp::allowedExclusiveClauses_OMPD_taskloop,
+ llvm::omp::requiredClauses_OMPD_taskloop,
+ }
+ },
+ {llvm::omp::Directive::OMPD_taskloop_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_taskloop_simd,
+ llvm::omp::allowedOnceClauses_OMPD_taskloop_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_taskloop_simd,
+ llvm::omp::requiredClauses_OMPD_taskloop_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_taskwait,
+ {
+ llvm::omp::allowedClauses_OMPD_taskwait,
+ llvm::omp::allowedOnceClauses_OMPD_taskwait,
+ llvm::omp::allowedExclusiveClauses_OMPD_taskwait,
+ llvm::omp::requiredClauses_OMPD_taskwait,
+ }
+ },
+ {llvm::omp::Directive::OMPD_taskyield,
+ {
+ llvm::omp::allowedClauses_OMPD_taskyield,
+ llvm::omp::allowedOnceClauses_OMPD_taskyield,
+ llvm::omp::allowedExclusiveClauses_OMPD_taskyield,
+ llvm::omp::requiredClauses_OMPD_taskyield,
+ }
+ },
+ {llvm::omp::Directive::OMPD_teams,
+ {
+ llvm::omp::allowedClauses_OMPD_teams,
+ llvm::omp::allowedOnceClauses_OMPD_teams,
+ llvm::omp::allowedExclusiveClauses_OMPD_teams,
+ llvm::omp::requiredClauses_OMPD_teams,
+ }
+ },
+ {llvm::omp::Directive::OMPD_teams_distribute,
+ {
+ llvm::omp::allowedClauses_OMPD_teams_distribute,
+ llvm::omp::allowedOnceClauses_OMPD_teams_distribute,
+ llvm::omp::allowedExclusiveClauses_OMPD_teams_distribute,
+ llvm::omp::requiredClauses_OMPD_teams_distribute,
+ }
+ },
+ {llvm::omp::Directive::OMPD_teams_distribute_parallel_do,
+ {
+ llvm::omp::allowedClauses_OMPD_teams_distribute_parallel_do,
+ llvm::omp::allowedOnceClauses_OMPD_teams_distribute_parallel_do,
+ llvm::omp::allowedExclusiveClauses_OMPD_teams_distribute_parallel_do,
+ llvm::omp::requiredClauses_OMPD_teams_distribute_parallel_do,
+ }
+ },
+ {llvm::omp::Directive::OMPD_teams_distribute_parallel_do_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_teams_distribute_parallel_do_simd,
+ llvm::omp::allowedOnceClauses_OMPD_teams_distribute_parallel_do_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_teams_distribute_parallel_do_simd,
+ llvm::omp::requiredClauses_OMPD_teams_distribute_parallel_do_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_teams_distribute_parallel_for,
+ {
+ llvm::omp::allowedClauses_OMPD_teams_distribute_parallel_for,
+ llvm::omp::allowedOnceClauses_OMPD_teams_distribute_parallel_for,
+ llvm::omp::allowedExclusiveClauses_OMPD_teams_distribute_parallel_for,
+ llvm::omp::requiredClauses_OMPD_teams_distribute_parallel_for,
+ }
+ },
+ {llvm::omp::Directive::OMPD_teams_distribute_parallel_for_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_teams_distribute_parallel_for_simd,
+ llvm::omp::allowedOnceClauses_OMPD_teams_distribute_parallel_for_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_teams_distribute_parallel_for_simd,
+ llvm::omp::requiredClauses_OMPD_teams_distribute_parallel_for_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_teams_distribute_simd,
+ {
+ llvm::omp::allowedClauses_OMPD_teams_distribute_simd,
+ llvm::omp::allowedOnceClauses_OMPD_teams_distribute_simd,
+ llvm::omp::allowedExclusiveClauses_OMPD_teams_distribute_simd,
+ llvm::omp::requiredClauses_OMPD_teams_distribute_simd,
+ }
+ },
+ {llvm::omp::Directive::OMPD_threadprivate,
+ {
+ llvm::omp::allowedClauses_OMPD_threadprivate,
+ llvm::omp::allowedOnceClauses_OMPD_threadprivate,
+ llvm::omp::allowedExclusiveClauses_OMPD_threadprivate,
+ llvm::omp::requiredClauses_OMPD_threadprivate,
+ }
+ },
+ {llvm::omp::Directive::OMPD_unknown,
+ {
+ llvm::omp::allowedClauses_OMPD_unknown,
+ llvm::omp::allowedOnceClauses_OMPD_unknown,
+ llvm::omp::allowedExclusiveClauses_OMPD_unknown,
+ llvm::omp::requiredClauses_OMPD_unknown,
+ }
+ },
+ {llvm::omp::Directive::OMPD_workshare,
+ {
+ llvm::omp::allowedClauses_OMPD_workshare,
+ llvm::omp::allowedOnceClauses_OMPD_workshare,
+ llvm::omp::allowedExclusiveClauses_OMPD_workshare,
+ llvm::omp::requiredClauses_OMPD_workshare,
+ }
+ },
+}
+
+#endif // GEN_FLANG_DIRECTIVE_CLAUSE_MAP
+
+#ifdef GEN_FLANG_CLAUSE_PARSER_CLASSES
+#undef GEN_FLANG_CLAUSE_PARSER_CLASSES
+
+EMPTY_CLASS(AcqRel);
+EMPTY_CLASS(Acquire);
+EMPTY_CLASS(Affinity);
+WRAPPER_CLASS(Aligned, OmpAlignedClause);
+WRAPPER_CLASS(Allocate, OmpAllocateClause);
+WRAPPER_CLASS(Allocator, ScalarIntExpr);
+EMPTY_CLASS(AtomicDefaultMemOrder);
+EMPTY_CLASS(Capture);
+WRAPPER_CLASS(Collapse, ScalarIntConstantExpr);
+WRAPPER_CLASS(Copyprivate, OmpObjectList);
+WRAPPER_CLASS(Copyin, OmpObjectList);
+WRAPPER_CLASS(Default, OmpDefaultClause);
+WRAPPER_CLASS(Defaultmap, OmpDefaultmapClause);
+WRAPPER_CLASS(Depend, OmpDependClause);
+EMPTY_CLASS(Depobj);
+EMPTY_CLASS(Destroy);
+EMPTY_CLASS(Detach);
+WRAPPER_CLASS(Device, ScalarIntExpr);
+EMPTY_CLASS(DeviceType);
+WRAPPER_CLASS(DistSchedule, std::optional<ScalarIntExpr>);
+EMPTY_CLASS(DynamicAllocators);
+EMPTY_CLASS(Exclusive);
+WRAPPER_CLASS(Final, ScalarLogicalExpr);
+WRAPPER_CLASS(Firstprivate, OmpObjectList);
+EMPTY_CLASS(Flush);
+WRAPPER_CLASS(From, OmpObjectList);
+WRAPPER_CLASS(Grainsize, ScalarIntExpr);
+WRAPPER_CLASS(Hint, ConstantExpr);
+WRAPPER_CLASS(If, OmpIfClause);
+EMPTY_CLASS(InReduction);
+EMPTY_CLASS(Inbranch);
+EMPTY_CLASS(Inclusive);
+WRAPPER_CLASS(IsDevicePtr, std::list<Name>);
+WRAPPER_CLASS(Lastprivate, OmpObjectList);
+WRAPPER_CLASS(Linear, OmpLinearClause);
+WRAPPER_CLASS(Link, OmpObjectList);
+WRAPPER_CLASS(Map, OmpMapClause);
+EMPTY_CLASS(Match);
+EMPTY_CLASS(Mergeable);
+EMPTY_CLASS(Nogroup);
+EMPTY_CLASS(Nowait);
+EMPTY_CLASS(Nontemporal);
+EMPTY_CLASS(Notinbranch);
+WRAPPER_CLASS(NumTasks, ScalarIntExpr);
+WRAPPER_CLASS(NumTeams, ScalarIntExpr);
+WRAPPER_CLASS(NumThreads, ScalarIntExpr);
+EMPTY_CLASS(Order);
+WRAPPER_CLASS(Ordered, std::optional<ScalarIntConstantExpr>);
+WRAPPER_CLASS(Priority, ScalarIntExpr);
+WRAPPER_CLASS(Private, OmpObjectList);
+WRAPPER_CLASS(ProcBind, OmpProcBindClause);
+EMPTY_CLASS(Read);
+WRAPPER_CLASS(Reduction, OmpReductionClause);
+EMPTY_CLASS(Relaxed);
+EMPTY_CLASS(Release);
+EMPTY_CLASS(ReverseOffload);
+WRAPPER_CLASS(Safelen, ScalarIntConstantExpr);
+WRAPPER_CLASS(Schedule, OmpScheduleClause);
+EMPTY_CLASS(SeqCst);
+WRAPPER_CLASS(Shared, OmpObjectList);
+EMPTY_CLASS(Simd);
+WRAPPER_CLASS(Simdlen, ScalarIntConstantExpr);
+WRAPPER_CLASS(TaskReduction, OmpReductionClause);
+WRAPPER_CLASS(ThreadLimit, ScalarIntExpr);
+EMPTY_CLASS(Threadprivate);
+EMPTY_CLASS(Threads);
+WRAPPER_CLASS(To, OmpObjectList);
+EMPTY_CLASS(UnifiedAddress);
+EMPTY_CLASS(UnifiedSharedMemory);
+WRAPPER_CLASS(Uniform, std::list<Name>);
+EMPTY_CLASS(Unknown);
+EMPTY_CLASS(Untied);
+EMPTY_CLASS(Update);
+EMPTY_CLASS(UseDeviceAddr);
+WRAPPER_CLASS(UseDevicePtr, std::list<Name>);
+EMPTY_CLASS(UsesAllocators);
+EMPTY_CLASS(Write);
+
+#endif // GEN_FLANG_CLAUSE_PARSER_CLASSES
+
+#ifdef GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST
+#undef GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST
+
+AcqRel
+, Acquire
+, Affinity
+, Aligned
+, Allocate
+, Allocator
+, AtomicDefaultMemOrder
+, Capture
+, Collapse
+, Copyprivate
+, Copyin
+, Default
+, Defaultmap
+, Depend
+, Depobj
+, Destroy
+, Detach
+, Device
+, DeviceType
+, DistSchedule
+, DynamicAllocators
+, Exclusive
+, Final
+, Firstprivate
+, Flush
+, From
+, Grainsize
+, Hint
+, If
+, InReduction
+, Inbranch
+, Inclusive
+, IsDevicePtr
+, Lastprivate
+, Linear
+, Link
+, Map
+, Match
+, Mergeable
+, Nogroup
+, Nowait
+, Nontemporal
+, Notinbranch
+, NumTasks
+, NumTeams
+, NumThreads
+, Order
+, Ordered
+, Priority
+, Private
+, ProcBind
+, Read
+, Reduction
+, Relaxed
+, Release
+, ReverseOffload
+, Safelen
+, Schedule
+, SeqCst
+, Shared
+, Simd
+, Simdlen
+, TaskReduction
+, ThreadLimit
+, Threadprivate
+, Threads
+, To
+, UnifiedAddress
+, UnifiedSharedMemory
+, Uniform
+, Unknown
+, Untied
+, Update
+, UseDeviceAddr
+, UseDevicePtr
+, UsesAllocators
+, Write
+
+#endif // GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST
+
+#ifdef GEN_FLANG_DUMP_PARSE_TREE_CLAUSES
+#undef GEN_FLANG_DUMP_PARSE_TREE_CLAUSES
+
+NODE(OmpClause, AcqRel)
+NODE(OmpClause, Acquire)
+NODE(OmpClause, Affinity)
+NODE(OmpClause, Aligned)
+NODE(OmpClause, Allocate)
+NODE(OmpClause, Allocator)
+NODE(OmpClause, AtomicDefaultMemOrder)
+NODE(OmpClause, Capture)
+NODE(OmpClause, Collapse)
+NODE(OmpClause, Copyprivate)
+NODE(OmpClause, Copyin)
+NODE(OmpClause, Default)
+NODE(OmpClause, Defaultmap)
+NODE(OmpClause, Depend)
+NODE(OmpClause, Depobj)
+NODE(OmpClause, Destroy)
+NODE(OmpClause, Detach)
+NODE(OmpClause, Device)
+NODE(OmpClause, DeviceType)
+NODE(OmpClause, DistSchedule)
+NODE(OmpClause, DynamicAllocators)
+NODE(OmpClause, Exclusive)
+NODE(OmpClause, Final)
+NODE(OmpClause, Firstprivate)
+NODE(OmpClause, Flush)
+NODE(OmpClause, From)
+NODE(OmpClause, Grainsize)
+NODE(OmpClause, Hint)
+NODE(OmpClause, If)
+NODE(OmpClause, InReduction)
+NODE(OmpClause, Inbranch)
+NODE(OmpClause, Inclusive)
+NODE(OmpClause, IsDevicePtr)
+NODE(OmpClause, Lastprivate)
+NODE(OmpClause, Linear)
+NODE(OmpClause, Link)
+NODE(OmpClause, Map)
+NODE(OmpClause, Match)
+NODE(OmpClause, Mergeable)
+NODE(OmpClause, Nogroup)
+NODE(OmpClause, Nowait)
+NODE(OmpClause, Nontemporal)
+NODE(OmpClause, Notinbranch)
+NODE(OmpClause, NumTasks)
+NODE(OmpClause, NumTeams)
+NODE(OmpClause, NumThreads)
+NODE(OmpClause, Order)
+NODE(OmpClause, Ordered)
+NODE(OmpClause, Priority)
+NODE(OmpClause, Private)
+NODE(OmpClause, ProcBind)
+NODE(OmpClause, Read)
+NODE(OmpClause, Reduction)
+NODE(OmpClause, Relaxed)
+NODE(OmpClause, Release)
+NODE(OmpClause, ReverseOffload)
+NODE(OmpClause, Safelen)
+NODE(OmpClause, Schedule)
+NODE(OmpClause, SeqCst)
+NODE(OmpClause, Shared)
+NODE(OmpClause, Simd)
+NODE(OmpClause, Simdlen)
+NODE(OmpClause, TaskReduction)
+NODE(OmpClause, ThreadLimit)
+NODE(OmpClause, Threadprivate)
+NODE(OmpClause, Threads)
+NODE(OmpClause, To)
+NODE(OmpClause, UnifiedAddress)
+NODE(OmpClause, UnifiedSharedMemory)
+NODE(OmpClause, Uniform)
+NODE(OmpClause, Unknown)
+NODE(OmpClause, Untied)
+NODE(OmpClause, Update)
+NODE(OmpClause, UseDeviceAddr)
+NODE(OmpClause, UseDevicePtr)
+NODE(OmpClause, UsesAllocators)
+NODE(OmpClause, Write)
+
+#endif // GEN_FLANG_DUMP_PARSE_TREE_CLAUSES
+
+#ifdef GEN_FLANG_CLAUSE_UNPARSE
+#undef GEN_FLANG_CLAUSE_UNPARSE
+
+void Before(const OmpClause::AcqRel &) { Word("ACQ_REL"); }
+void Before(const OmpClause::Acquire &) { Word("ACQUIRE"); }
+void Before(const OmpClause::Affinity &) { Word("AFFINITY"); }
+void Unparse(const OmpClause::Aligned &x) {
+ Word("ALIGNED");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::Allocate &x) {
+ Word("ALLOCATE");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::Allocator &x) {
+ Word("ALLOCATOR");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Before(const OmpClause::AtomicDefaultMemOrder &) { Word("ATOMIC_DEFAULT_MEM_ORDER"); }
+void Before(const OmpClause::Capture &) { Word("CAPTURE"); }
+void Unparse(const OmpClause::Collapse &x) {
+ Word("COLLAPSE");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::Copyprivate &x) {
+ Word("COPYPRIVATE");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::Copyin &x) {
+ Word("COPYIN");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::Default &x) {
+ Word("DEFAULT");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::Defaultmap &x) {
+ Word("DEFAULTMAP");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::Depend &x) {
+ Word("DEPEND");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Before(const OmpClause::Depobj &) { Word("DEPOBJ"); }
+void Before(const OmpClause::Destroy &) { Word("DESTROY"); }
+void Before(const OmpClause::Detach &) { Word("DETACH"); }
+void Unparse(const OmpClause::Device &x) {
+ Word("DEVICE");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Before(const OmpClause::DeviceType &) { Word("DEVICE_TYPE"); }
+void Unparse(const OmpClause::DistSchedule &x) {
+ Word("DIST_SCHEDULE");
+ Walk("(", x.v, ")");
+}
+void Before(const OmpClause::DynamicAllocators &) { Word("DYNAMIC_ALLOCATORS"); }
+void Before(const OmpClause::Exclusive &) { Word("EXCLUSIVE"); }
+void Unparse(const OmpClause::Final &x) {
+ Word("FINAL");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::Firstprivate &x) {
+ Word("FIRSTPRIVATE");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Before(const OmpClause::Flush &) { Word("FLUSH"); }
+void Unparse(const OmpClause::From &x) {
+ Word("FROM");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::Grainsize &x) {
+ Word("GRAINSIZE");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::Hint &x) {
+ Word("HINT");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::If &x) {
+ Word("IF");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Before(const OmpClause::InReduction &) { Word("IN_REDUCTION"); }
+void Before(const OmpClause::Inbranch &) { Word("INBRANCH"); }
+void Before(const OmpClause::Inclusive &) { Word("INCLUSIVE"); }
+void Unparse(const OmpClause::IsDevicePtr &x) {
+ Word("IS_DEVICE_PTR");
+ Put("(");
+ Walk(x.v, ",");
+ Put(")");
+}
+void Unparse(const OmpClause::Lastprivate &x) {
+ Word("LASTPRIVATE");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::Linear &x) {
+ Word("LINEAR");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::Link &x) {
+ Word("LINK");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::Map &x) {
+ Word("MAP");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Before(const OmpClause::Match &) { Word("MATCH"); }
+void Before(const OmpClause::Mergeable &) { Word("MERGEABLE"); }
+void Before(const OmpClause::Nogroup &) { Word("NOGROUP"); }
+void Before(const OmpClause::Nowait &) { Word("NOWAIT"); }
+void Before(const OmpClause::Nontemporal &) { Word("NONTEMPORAL"); }
+void Before(const OmpClause::Notinbranch &) { Word("NOTINBRANCH"); }
+void Unparse(const OmpClause::NumTasks &x) {
+ Word("NUM_TASKS");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::NumTeams &x) {
+ Word("NUM_TEAMS");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::NumThreads &x) {
+ Word("NUM_THREADS");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Before(const OmpClause::Order &) { Word("ORDER"); }
+void Unparse(const OmpClause::Ordered &x) {
+ Word("ORDERED");
+ Walk("(", x.v, ")");
+}
+void Unparse(const OmpClause::Priority &x) {
+ Word("PRIORITY");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::Private &x) {
+ Word("PRIVATE");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::ProcBind &x) {
+ Word("PROC_BIND");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Before(const OmpClause::Read &) { Word("READ"); }
+void Unparse(const OmpClause::Reduction &x) {
+ Word("REDUCTION");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Before(const OmpClause::Relaxed &) { Word("RELAXED"); }
+void Before(const OmpClause::Release &) { Word("RELEASE"); }
+void Before(const OmpClause::ReverseOffload &) { Word("REVERSE_OFFLOAD"); }
+void Unparse(const OmpClause::Safelen &x) {
+ Word("SAFELEN");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::Schedule &x) {
+ Word("SCHEDULE");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Before(const OmpClause::SeqCst &) { Word("SEQ_CST"); }
+void Unparse(const OmpClause::Shared &x) {
+ Word("SHARED");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Before(const OmpClause::Simd &) { Word("SIMD"); }
+void Unparse(const OmpClause::Simdlen &x) {
+ Word("SIMDLEN");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::TaskReduction &x) {
+ Word("TASK_REDUCTION");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Unparse(const OmpClause::ThreadLimit &x) {
+ Word("THREAD_LIMIT");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Before(const OmpClause::Threadprivate &) { Word("THREADPRIVATE"); }
+void Before(const OmpClause::Threads &) { Word("THREADS"); }
+void Unparse(const OmpClause::To &x) {
+ Word("TO");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+}
+void Before(const OmpClause::UnifiedAddress &) { Word("UNIFIED_ADDRESS"); }
+void Before(const OmpClause::UnifiedSharedMemory &) { Word("UNIFIED_SHARED_MEMORY"); }
+void Unparse(const OmpClause::Uniform &x) {
+ Word("UNIFORM");
+ Put("(");
+ Walk(x.v, ",");
+ Put(")");
+}
+void Before(const OmpClause::Unknown &) { Word("UNKNOWN"); }
+void Before(const OmpClause::Untied &) { Word("UNTIED"); }
+void Before(const OmpClause::Update &) { Word("UPDATE"); }
+void Before(const OmpClause::UseDeviceAddr &) { Word("USE_DEVICE_ADDR"); }
+void Unparse(const OmpClause::UseDevicePtr &x) {
+ Word("USE_DEVICE_PTR");
+ Put("(");
+ Walk(x.v, ",");
+ Put(")");
+}
+void Before(const OmpClause::UsesAllocators &) { Word("USES_ALLOCATORS"); }
+void Before(const OmpClause::Write &) { Word("WRITE"); }
+
+#endif // GEN_FLANG_CLAUSE_UNPARSE
+
+#ifdef GEN_CLANG_CLAUSE_CLASS
+#undef GEN_CLANG_CLAUSE_CLASS
+
+#ifndef CLAUSE
+#define CLAUSE(Enum, Str, Implicit)
+#endif
+#ifndef CLAUSE_CLASS
+#define CLAUSE_CLASS(Enum, Str, Class)
+#endif
+#ifndef CLAUSE_NO_CLASS
+#define CLAUSE_NO_CLASS(Enum, Str)
+#endif
+
+#define __CLAUSE(Name, Class) \
+ CLAUSE(OMPC_##Name, #Name, /* Implicit */ false) \
+ CLAUSE_CLASS(OMPC_##Name, #Name, Class)
+#define __CLAUSE_NO_CLASS(Name) \
+ CLAUSE(OMPC_##Name, #Name, /* Implicit */ false) \
+ CLAUSE_NO_CLASS(OMPC_##Name, #Name)
+#define __IMPLICIT_CLAUSE_CLASS(Name, Str, Class) \
+ CLAUSE(OMPC_##Name, Str, /* Implicit */ true) \
+ CLAUSE_CLASS(OMPC_##Name, Str, Class)
+#define __IMPLICIT_CLAUSE_NO_CLASS(Name, Str) \
+ CLAUSE(OMPC_##Name, Str, /* Implicit */ true) \
+ CLAUSE_NO_CLASS(OMPC_##Name, Str)
+
+__CLAUSE(acq_rel, OMPAcqRelClause)
+__CLAUSE(acquire, OMPAcquireClause)
+__CLAUSE(affinity, OMPAffinityClause)
+__CLAUSE(aligned, OMPAlignedClause)
+__CLAUSE(allocate, OMPAllocateClause)
+__CLAUSE(allocator, OMPAllocatorClause)
+__CLAUSE(atomic_default_mem_order, OMPAtomicDefaultMemOrderClause)
+__CLAUSE(capture, OMPCaptureClause)
+__CLAUSE(collapse, OMPCollapseClause)
+__CLAUSE(copyprivate, OMPCopyprivateClause)
+__CLAUSE(copyin, OMPCopyinClause)
+__CLAUSE(default, OMPDefaultClause)
+__CLAUSE(defaultmap, OMPDefaultmapClause)
+__CLAUSE(depend, OMPDependClause)
+__IMPLICIT_CLAUSE_CLASS(depobj, "depobj", OMPDepobjClause)
+__CLAUSE(destroy, OMPDestroyClause)
+__CLAUSE(detach, OMPDetachClause)
+__CLAUSE(device, OMPDeviceClause)
+__CLAUSE_NO_CLASS(device_type)
+__CLAUSE(dist_schedule, OMPDistScheduleClause)
+__CLAUSE(dynamic_allocators, OMPDynamicAllocatorsClause)
+__CLAUSE(exclusive, OMPExclusiveClause)
+__CLAUSE(final, OMPFinalClause)
+__CLAUSE(firstprivate, OMPFirstprivateClause)
+__IMPLICIT_CLAUSE_CLASS(flush, "flush", OMPFlushClause)
+__CLAUSE(from, OMPFromClause)
+__CLAUSE(grainsize, OMPGrainsizeClause)
+__CLAUSE(hint, OMPHintClause)
+__CLAUSE(if, OMPIfClause)
+__CLAUSE(in_reduction, OMPInReductionClause)
+__CLAUSE_NO_CLASS(inbranch)
+__CLAUSE(inclusive, OMPInclusiveClause)
+__CLAUSE(is_device_ptr, OMPIsDevicePtrClause)
+__CLAUSE(lastprivate, OMPLastprivateClause)
+__CLAUSE(linear, OMPLinearClause)
+__CLAUSE_NO_CLASS(link)
+__CLAUSE(map, OMPMapClause)
+__CLAUSE_NO_CLASS(match)
+__CLAUSE(mergeable, OMPMergeableClause)
+__CLAUSE(nogroup, OMPNogroupClause)
+__CLAUSE(nowait, OMPNowaitClause)
+__CLAUSE(nontemporal, OMPNontemporalClause)
+__CLAUSE_NO_CLASS(notinbranch)
+__CLAUSE(num_tasks, OMPNumTasksClause)
+__CLAUSE(num_teams, OMPNumTeamsClause)
+__CLAUSE(num_threads, OMPNumThreadsClause)
+__CLAUSE(order, OMPOrderClause)
+__CLAUSE(ordered, OMPOrderedClause)
+__CLAUSE(priority, OMPPriorityClause)
+__CLAUSE(private, OMPPrivateClause)
+__CLAUSE(proc_bind, OMPProcBindClause)
+__CLAUSE(read, OMPReadClause)
+__CLAUSE(reduction, OMPReductionClause)
+__CLAUSE(relaxed, OMPRelaxedClause)
+__CLAUSE(release, OMPReleaseClause)
+__CLAUSE(reverse_offload, OMPReverseOffloadClause)
+__CLAUSE(safelen, OMPSafelenClause)
+__CLAUSE(schedule, OMPScheduleClause)
+__CLAUSE(seq_cst, OMPSeqCstClause)
+__CLAUSE(shared, OMPSharedClause)
+__CLAUSE(simd, OMPSIMDClause)
+__CLAUSE(simdlen, OMPSimdlenClause)
+__CLAUSE(task_reduction, OMPTaskReductionClause)
+__CLAUSE(thread_limit, OMPThreadLimitClause)
+__IMPLICIT_CLAUSE_NO_CLASS(threadprivate, "threadprivate")
+__CLAUSE(threads, OMPThreadsClause)
+__CLAUSE(to, OMPToClause)
+__CLAUSE(unified_address, OMPUnifiedAddressClause)
+__CLAUSE(unified_shared_memory, OMPUnifiedSharedMemoryClause)
+__CLAUSE_NO_CLASS(uniform)
+__IMPLICIT_CLAUSE_NO_CLASS(unknown, "unknown")
+__CLAUSE(untied, OMPUntiedClause)
+__CLAUSE(update, OMPUpdateClause)
+__CLAUSE(use_device_addr, OMPUseDeviceAddrClause)
+__CLAUSE(use_device_ptr, OMPUseDevicePtrClause)
+__CLAUSE(uses_allocators, OMPUsesAllocatorsClause)
+__CLAUSE(write, OMPWriteClause)
+
+#undef __IMPLICIT_CLAUSE_NO_CLASS
+#undef __IMPLICIT_CLAUSE_CLASS
+#undef __CLAUSE
+#undef CLAUSE_NO_CLASS
+#undef CLAUSE_CLASS
+#undef CLAUSE
+
+#endif // GEN_CLANG_CLAUSE_CLASS
+
diff --git a/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMP.td b/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMP.td
index d953e49696..10fa5a37b8 100644
--- a/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMP.td
+++ b/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMP.td
@@ -21,11 +21,11 @@ def OpenMP : DirectiveLanguage {
let cppNamespace = "omp"; // final namespace will be llvm::omp
let directivePrefix = "OMPD_";
let clausePrefix = "OMPC_";
- let makeEnumAvailableInNamespace = true;
- let enableBitmaskEnumInNamespace = true;
+ let makeEnumAvailableInNamespace = true;
+ let enableBitmaskEnumInNamespace = true;
let includeHeader = "llvm/Frontend/OpenMP/OMP.h.inc";
let clauseEnumSetClass = "OmpClauseSet";
- let flangClauseBaseClass = "OmpClause";
+ let flangClauseBaseClass = "OmpClause";
}
//===----------------------------------------------------------------------===//
@@ -34,120 +34,120 @@ def OpenMP : DirectiveLanguage {
def OMPC_Allocator : Clause<"allocator"> {
let clangClass = "OMPAllocatorClause";
- let flangClass = "ScalarIntExpr";
-}
-def OMPC_If : Clause<"if"> {
- let clangClass = "OMPIfClause";
- let flangClass = "OmpIfClause";
-}
-def OMPC_Final : Clause<"final"> {
- let clangClass = "OMPFinalClause";
- let flangClass = "ScalarLogicalExpr";
-}
+ let flangClass = "ScalarIntExpr";
+}
+def OMPC_If : Clause<"if"> {
+ let clangClass = "OMPIfClause";
+ let flangClass = "OmpIfClause";
+}
+def OMPC_Final : Clause<"final"> {
+ let clangClass = "OMPFinalClause";
+ let flangClass = "ScalarLogicalExpr";
+}
def OMPC_NumThreads : Clause<"num_threads"> {
let clangClass = "OMPNumThreadsClause";
- let flangClass = "ScalarIntExpr";
-}
-def OMPC_SafeLen : Clause<"safelen"> {
- let clangClass = "OMPSafelenClause";
- let flangClass = "ScalarIntConstantExpr";
-}
-def OMPC_SimdLen : Clause<"simdlen"> {
- let clangClass = "OMPSimdlenClause";
- let flangClass = "ScalarIntConstantExpr";
-}
-def OMPC_Collapse : Clause<"collapse"> {
- let clangClass = "OMPCollapseClause";
- let flangClass = "ScalarIntConstantExpr";
-}
-def OMPC_Default : Clause<"default"> {
- let clangClass = "OMPDefaultClause";
- let flangClass = "OmpDefaultClause";
-}
-def OMPC_Private : Clause<"private"> {
- let clangClass = "OMPPrivateClause";
- let flangClass = "OmpObjectList";
-}
+ let flangClass = "ScalarIntExpr";
+}
+def OMPC_SafeLen : Clause<"safelen"> {
+ let clangClass = "OMPSafelenClause";
+ let flangClass = "ScalarIntConstantExpr";
+}
+def OMPC_SimdLen : Clause<"simdlen"> {
+ let clangClass = "OMPSimdlenClause";
+ let flangClass = "ScalarIntConstantExpr";
+}
+def OMPC_Collapse : Clause<"collapse"> {
+ let clangClass = "OMPCollapseClause";
+ let flangClass = "ScalarIntConstantExpr";
+}
+def OMPC_Default : Clause<"default"> {
+ let clangClass = "OMPDefaultClause";
+ let flangClass = "OmpDefaultClause";
+}
+def OMPC_Private : Clause<"private"> {
+ let clangClass = "OMPPrivateClause";
+ let flangClass = "OmpObjectList";
+}
def OMPC_FirstPrivate : Clause<"firstprivate"> {
let clangClass = "OMPFirstprivateClause";
- let flangClass = "OmpObjectList";
+ let flangClass = "OmpObjectList";
}
def OMPC_LastPrivate : Clause<"lastprivate"> {
let clangClass = "OMPLastprivateClause";
- let flangClass = "OmpObjectList";
+ let flangClass = "OmpObjectList";
+}
+def OMPC_Shared : Clause<"shared"> {
+ let clangClass = "OMPSharedClause";
+ let flangClass = "OmpObjectList";
}
-def OMPC_Shared : Clause<"shared"> {
- let clangClass = "OMPSharedClause";
- let flangClass = "OmpObjectList";
-}
def OMPC_Reduction : Clause<"reduction"> {
let clangClass = "OMPReductionClause";
- let flangClass = "OmpReductionClause";
-}
-def OMPC_Linear : Clause<"linear"> {
- let clangClass = "OMPLinearClause";
- let flangClass = "OmpLinearClause";
-}
-def OMPC_Aligned : Clause<"aligned"> {
- let clangClass = "OMPAlignedClause";
- let flangClass = "OmpAlignedClause";
-}
-def OMPC_Copyin : Clause<"copyin"> {
- let clangClass = "OMPCopyinClause";
- let flangClass = "OmpObjectList";
-}
+ let flangClass = "OmpReductionClause";
+}
+def OMPC_Linear : Clause<"linear"> {
+ let clangClass = "OMPLinearClause";
+ let flangClass = "OmpLinearClause";
+}
+def OMPC_Aligned : Clause<"aligned"> {
+ let clangClass = "OMPAlignedClause";
+ let flangClass = "OmpAlignedClause";
+}
+def OMPC_Copyin : Clause<"copyin"> {
+ let clangClass = "OMPCopyinClause";
+ let flangClass = "OmpObjectList";
+}
def OMPC_CopyPrivate : Clause<"copyprivate"> {
let clangClass = "OMPCopyprivateClause";
- let flangClass = "OmpObjectList";
+ let flangClass = "OmpObjectList";
}
-def OMP_PROC_BIND_master : ClauseVal<"master",2,1> {}
-def OMP_PROC_BIND_close : ClauseVal<"close",3,1> {}
-def OMP_PROC_BIND_spread : ClauseVal<"spread",4,1> {}
-def OMP_PROC_BIND_default : ClauseVal<"default",5,0> {}
-def OMP_PROC_BIND_unknown : ClauseVal<"unknown",6,0> { let isDefault = true; }
+def OMP_PROC_BIND_master : ClauseVal<"master",2,1> {}
+def OMP_PROC_BIND_close : ClauseVal<"close",3,1> {}
+def OMP_PROC_BIND_spread : ClauseVal<"spread",4,1> {}
+def OMP_PROC_BIND_default : ClauseVal<"default",5,0> {}
+def OMP_PROC_BIND_unknown : ClauseVal<"unknown",6,0> { let isDefault = true; }
def OMPC_ProcBind : Clause<"proc_bind"> {
let clangClass = "OMPProcBindClause";
- let flangClass = "OmpProcBindClause";
- let enumClauseValue = "ProcBindKind";
- let allowedClauseValues = [
- OMP_PROC_BIND_master,
- OMP_PROC_BIND_close,
- OMP_PROC_BIND_spread,
- OMP_PROC_BIND_default,
- OMP_PROC_BIND_unknown
- ];
-}
-
-// static and auto are C++ keywords so need a capital to disambiguate.
-def OMP_SCHEDULE_Static : ClauseVal<"Static", 2, 1> {}
-def OMP_SCHEDULE_Dynamic : ClauseVal<"Dynamic", 3, 1> {}
-def OMP_SCHEDULE_Guided : ClauseVal<"Guided", 4, 1> {}
-def OMP_SCHEDULE_Auto : ClauseVal<"Auto", 5, 1> {}
-def OMP_SCHEDULE_Runtime : ClauseVal<"Runtime", 6, 1> {}
-def OMP_SCHEDULE_Default : ClauseVal<"Default", 7, 0> { let isDefault = 1; }
-
-def OMPC_Schedule : Clause<"schedule"> {
- let clangClass = "OMPScheduleClause";
- let flangClass = "OmpScheduleClause";
- let enumClauseValue = "ScheduleKind";
- let allowedClauseValues = [
- OMP_SCHEDULE_Static,
- OMP_SCHEDULE_Dynamic,
- OMP_SCHEDULE_Guided,
- OMP_SCHEDULE_Auto,
- OMP_SCHEDULE_Runtime,
- OMP_SCHEDULE_Default
- ];
-}
-
-def OMPC_Ordered : Clause<"ordered"> {
- let clangClass = "OMPOrderedClause";
- let flangClass = "ScalarIntConstantExpr";
- let isValueOptional = true;
-}
-def OMPC_NoWait : Clause<"nowait"> {
- let clangClass = "OMPNowaitClause";
-}
+ let flangClass = "OmpProcBindClause";
+ let enumClauseValue = "ProcBindKind";
+ let allowedClauseValues = [
+ OMP_PROC_BIND_master,
+ OMP_PROC_BIND_close,
+ OMP_PROC_BIND_spread,
+ OMP_PROC_BIND_default,
+ OMP_PROC_BIND_unknown
+ ];
+}
+
+// static and auto are C++ keywords so need a capital to disambiguate.
+def OMP_SCHEDULE_Static : ClauseVal<"Static", 2, 1> {}
+def OMP_SCHEDULE_Dynamic : ClauseVal<"Dynamic", 3, 1> {}
+def OMP_SCHEDULE_Guided : ClauseVal<"Guided", 4, 1> {}
+def OMP_SCHEDULE_Auto : ClauseVal<"Auto", 5, 1> {}
+def OMP_SCHEDULE_Runtime : ClauseVal<"Runtime", 6, 1> {}
+def OMP_SCHEDULE_Default : ClauseVal<"Default", 7, 0> { let isDefault = 1; }
+
+def OMPC_Schedule : Clause<"schedule"> {
+ let clangClass = "OMPScheduleClause";
+ let flangClass = "OmpScheduleClause";
+ let enumClauseValue = "ScheduleKind";
+ let allowedClauseValues = [
+ OMP_SCHEDULE_Static,
+ OMP_SCHEDULE_Dynamic,
+ OMP_SCHEDULE_Guided,
+ OMP_SCHEDULE_Auto,
+ OMP_SCHEDULE_Runtime,
+ OMP_SCHEDULE_Default
+ ];
+}
+
+def OMPC_Ordered : Clause<"ordered"> {
+ let clangClass = "OMPOrderedClause";
+ let flangClass = "ScalarIntConstantExpr";
+ let isValueOptional = true;
+}
+def OMPC_NoWait : Clause<"nowait"> {
+ let clangClass = "OMPNowaitClause";
+}
def OMPC_Untied : Clause<"untied"> { let clangClass = "OMPUntiedClause"; }
def OMPC_Mergeable : Clause<"mergeable"> {
let clangClass = "OMPMergeableClause";
@@ -161,77 +161,77 @@ def OMPC_AcqRel : Clause<"acq_rel"> { let clangClass = "OMPAcqRelClause"; }
def OMPC_Acquire : Clause<"acquire"> { let clangClass = "OMPAcquireClause"; }
def OMPC_Release : Clause<"release"> { let clangClass = "OMPReleaseClause"; }
def OMPC_Relaxed : Clause<"relaxed"> { let clangClass = "OMPRelaxedClause"; }
-def OMPC_Depend : Clause<"depend"> {
- let clangClass = "OMPDependClause";
- let flangClass = "OmpDependClause";
-}
-def OMPC_Device : Clause<"device"> {
- let clangClass = "OMPDeviceClause";
- let flangClass = "ScalarIntExpr";
-}
+def OMPC_Depend : Clause<"depend"> {
+ let clangClass = "OMPDependClause";
+ let flangClass = "OmpDependClause";
+}
+def OMPC_Device : Clause<"device"> {
+ let clangClass = "OMPDeviceClause";
+ let flangClass = "ScalarIntExpr";
+}
def OMPC_Threads : Clause<"threads"> { let clangClass = "OMPThreadsClause"; }
def OMPC_Simd : Clause<"simd"> { let clangClass = "OMPSIMDClause"; }
-def OMPC_Map : Clause<"map"> {
- let clangClass = "OMPMapClause";
- let flangClass = "OmpMapClause";
-}
+def OMPC_Map : Clause<"map"> {
+ let clangClass = "OMPMapClause";
+ let flangClass = "OmpMapClause";
+}
def OMPC_NumTeams : Clause<"num_teams"> {
let clangClass = "OMPNumTeamsClause";
- let flangClass = "ScalarIntExpr";
+ let flangClass = "ScalarIntExpr";
}
def OMPC_ThreadLimit : Clause<"thread_limit"> {
let clangClass = "OMPThreadLimitClause";
- let flangClass = "ScalarIntExpr";
+ let flangClass = "ScalarIntExpr";
}
def OMPC_Priority : Clause<"priority"> {
let clangClass = "OMPPriorityClause";
- let flangClass = "ScalarIntExpr";
+ let flangClass = "ScalarIntExpr";
}
def OMPC_GrainSize : Clause<"grainsize"> {
let clangClass = "OMPGrainsizeClause";
- let flangClass = "ScalarIntExpr";
+ let flangClass = "ScalarIntExpr";
}
def OMPC_NoGroup : Clause<"nogroup"> {
let clangClass = "OMPNogroupClause";
}
def OMPC_NumTasks : Clause<"num_tasks"> {
let clangClass = "OMPNumTasksClause";
- let flangClass = "ScalarIntExpr";
+ let flangClass = "ScalarIntExpr";
}
def OMPC_Hint : Clause<"hint"> {
let clangClass = "OMPHintClause";
- let flangClass = "ConstantExpr";
+ let flangClass = "ConstantExpr";
}
def OMPC_DistSchedule : Clause<"dist_schedule"> {
let clangClass = "OMPDistScheduleClause";
- let flangClass = "ScalarIntExpr";
- let isValueOptional = true;
+ let flangClass = "ScalarIntExpr";
+ let isValueOptional = true;
}
def OMPC_DefaultMap : Clause<"defaultmap"> {
let clangClass = "OMPDefaultmapClause";
- let flangClass = "OmpDefaultmapClause";
+ let flangClass = "OmpDefaultmapClause";
}
def OMPC_To : Clause<"to"> {
let clangClass = "OMPToClause";
- let flangClass = "OmpObjectList";
+ let flangClass = "OmpObjectList";
+}
+def OMPC_From : Clause<"from"> {
+ let clangClass = "OMPFromClause";
+ let flangClass = "OmpObjectList";
}
-def OMPC_From : Clause<"from"> {
- let clangClass = "OMPFromClause";
- let flangClass = "OmpObjectList";
-}
def OMPC_UseDevicePtr : Clause<"use_device_ptr"> {
let clangClass = "OMPUseDevicePtrClause";
- let flangClass = "Name";
- let isValueList = true;
+ let flangClass = "Name";
+ let isValueList = true;
}
def OMPC_IsDevicePtr : Clause<"is_device_ptr"> {
let clangClass = "OMPIsDevicePtrClause";
- let flangClass = "Name";
- let isValueList = true;
+ let flangClass = "Name";
+ let isValueList = true;
}
def OMPC_TaskReduction : Clause<"task_reduction"> {
let clangClass = "OMPTaskReductionClause";
- let flangClass = "OmpReductionClause";
+ let flangClass = "OmpReductionClause";
}
def OMPC_InReduction : Clause<"in_reduction"> {
let clangClass = "OMPInReductionClause";
@@ -253,19 +253,19 @@ def OMPC_AtomicDefaultMemOrder : Clause<"atomic_default_mem_order"> {
}
def OMPC_Allocate : Clause<"allocate"> {
let clangClass = "OMPAllocateClause";
- let flangClass = "OmpAllocateClause";
+ let flangClass = "OmpAllocateClause";
}
def OMPC_NonTemporal : Clause<"nontemporal"> {
let clangClass = "OMPNontemporalClause";
}
-
-def OMP_ORDER_concurrent : ClauseVal<"default",2,0> { let isDefault = 1; }
+
+def OMP_ORDER_concurrent : ClauseVal<"default",2,0> { let isDefault = 1; }
def OMPC_Order : Clause<"order"> {
let clangClass = "OMPOrderClause";
- let enumClauseValue = "OrderKind";
- let allowedClauseValues = [
- OMP_ORDER_concurrent
- ];
+ let enumClauseValue = "OrderKind";
+ let allowedClauseValues = [
+ OMP_ORDER_concurrent
+ ];
}
def OMPC_Destroy : Clause<"destroy"> {
let clangClass = "OMPDestroyClause";
@@ -288,31 +288,31 @@ def OMPC_Affinity : Clause<"affinity"> {
def OMPC_UseDeviceAddr : Clause<"use_device_addr"> {
let clangClass = "OMPUseDeviceAddrClause";
}
-def OMPC_Uniform : Clause<"uniform"> {
- let flangClass = "Name";
- let isValueList = true;
-}
+def OMPC_Uniform : Clause<"uniform"> {
+ let flangClass = "Name";
+ let isValueList = true;
+}
def OMPC_DeviceType : Clause<"device_type"> {}
def OMPC_Match : Clause<"match"> {}
def OMPC_Depobj : Clause<"depobj"> {
let clangClass = "OMPDepobjClause";
- let isImplicit = true;
+ let isImplicit = true;
}
def OMPC_Flush : Clause<"flush"> {
let clangClass = "OMPFlushClause";
- let isImplicit = true;
+ let isImplicit = true;
}
def OMPC_ThreadPrivate : Clause<"threadprivate"> {
let alternativeName = "threadprivate or thread local";
- let isImplicit = true;
+ let isImplicit = true;
}
def OMPC_Unknown : Clause<"unknown"> {
- let isImplicit = true;
- let isDefault = true;
+ let isImplicit = true;
+ let isDefault = true;
+}
+def OMPC_Link : Clause<"link"> {
+ let flangClass = "OmpObjectList";
}
-def OMPC_Link : Clause<"link"> {
- let flangClass = "OmpObjectList";
-}
def OMPC_Inbranch : Clause<"inbranch"> {}
def OMPC_Notinbranch : Clause<"notinbranch"> {}
@@ -331,7 +331,7 @@ def OMP_Parallel : Directive<"parallel"> {
VersionedClause<OMPC_Allocate>
];
let allowedOnceClauses = [
- VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Default>,
VersionedClause<OMPC_If>,
VersionedClause<OMPC_NumThreads>,
VersionedClause<OMPC_ProcBind>,
@@ -351,7 +351,7 @@ def OMP_Task : Directive<"task"> {
VersionedClause<OMPC_Affinity, 50>
];
let allowedOnceClauses = [
- VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Default>,
VersionedClause<OMPC_If>,
VersionedClause<OMPC_Final>,
VersionedClause<OMPC_Priority>
@@ -433,11 +433,11 @@ def OMP_Critical : Directive<"critical"> {
}
def OMP_TaskYield : Directive<"taskyield"> {}
def OMP_Barrier : Directive<"barrier"> {}
-def OMP_TaskWait : Directive<"taskwait"> {
- let allowedClauses = [
- VersionedClause<OMPC_Depend, 50>
- ];
-}
+def OMP_TaskWait : Directive<"taskwait"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Depend, 50>
+ ];
+}
def OMP_TaskGroup : Directive<"taskgroup"> {
let allowedClauses = [
VersionedClause<OMPC_TaskReduction>,
@@ -445,7 +445,7 @@ def OMP_TaskGroup : Directive<"taskgroup"> {
];
}
def OMP_Flush : Directive<"flush"> {
- let allowedOnceClauses = [
+ let allowedOnceClauses = [
VersionedClause<OMPC_AcqRel, 50>,
VersionedClause<OMPC_Acquire, 50>,
VersionedClause<OMPC_Release, 50>,
@@ -467,8 +467,8 @@ def OMP_Atomic : Directive<"atomic"> {
VersionedClause<OMPC_Write>,
VersionedClause<OMPC_Update>,
VersionedClause<OMPC_Capture>,
- ];
- let allowedOnceClauses = [
+ ];
+ let allowedOnceClauses = [
VersionedClause<OMPC_SeqCst>,
VersionedClause<OMPC_AcqRel, 50>,
VersionedClause<OMPC_Acquire, 50>,
@@ -538,20 +538,20 @@ def OMP_TargetData : Directive<"target data"> {
}
def OMP_TargetEnterData : Directive<"target enter data"> {
let allowedClauses = [
- VersionedClause<OMPC_Depend>
+ VersionedClause<OMPC_Depend>
];
let allowedOnceClauses = [
VersionedClause<OMPC_If>,
VersionedClause<OMPC_Device>,
VersionedClause<OMPC_NoWait>
];
- let requiredClauses = [
- VersionedClause<OMPC_Map>
- ];
+ let requiredClauses = [
+ VersionedClause<OMPC_Map>
+ ];
}
def OMP_TargetExitData : Directive<"target exit data"> {
let allowedClauses = [
- VersionedClause<OMPC_Depend>
+ VersionedClause<OMPC_Depend>
];
let allowedOnceClauses = [
VersionedClause<OMPC_Device>,
@@ -843,7 +843,7 @@ def OMP_TaskLoop : Directive<"taskloop"> {
VersionedClause<OMPC_Allocate>
];
let allowedOnceClauses = [
- VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Default>,
VersionedClause<OMPC_If>,
VersionedClause<OMPC_Collapse>,
VersionedClause<OMPC_Final>,
@@ -897,12 +897,12 @@ def OMP_Distribute : Directive<"distribute"> {
VersionedClause<OMPC_DistSchedule>
];
}
-def OMP_DeclareTarget : Directive<"declare target"> {
- let allowedClauses = [
- VersionedClause<OMPC_To>,
- VersionedClause<OMPC_Link>
- ];
-}
+def OMP_DeclareTarget : Directive<"declare target"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_To>,
+ VersionedClause<OMPC_Link>
+ ];
+}
def OMP_EndDeclareTarget : Directive<"end declare target"> {}
def OMP_DistributeParallelFor : Directive<"distribute parallel for"> {
let allowedClauses = [
@@ -1592,9 +1592,9 @@ def OMP_Scan : Directive<"scan"> {
VersionedClause<OMPC_Exclusive, 50>
];
}
-def OMP_Assumes : Directive<"assumes"> {}
-def OMP_BeginAssumes : Directive<"begin assumes"> {}
-def OMP_EndAssumes : Directive<"end assumes"> {}
+def OMP_Assumes : Directive<"assumes"> {}
+def OMP_BeginAssumes : Directive<"begin assumes"> {}
+def OMP_EndAssumes : Directive<"end assumes"> {}
def OMP_BeginDeclareVariant : Directive<"begin declare variant"> {}
def OMP_EndDeclareVariant : Directive<"end declare variant"> {}
def OMP_ParallelWorkshare : Directive<"parallel workshare"> {
@@ -1616,24 +1616,24 @@ def OMP_ParallelWorkshare : Directive<"parallel workshare"> {
def OMP_Workshare : Directive<"workshare"> {}
def OMP_EndDo : Directive<"end do"> {}
def OMP_EndDoSimd : Directive<"end do simd"> {}
-def OMP_EndSections : Directive<"end sections"> {
- let allowedOnceClauses = [
- VersionedClause<OMPC_NoWait>
- ];
-}
-def OMP_EndSingle : Directive<"end single"> {
- let allowedClauses = [
- VersionedClause<OMPC_CopyPrivate>
- ];
- let allowedOnceClauses = [
- VersionedClause<OMPC_NoWait>
- ];
-}
-def OMP_EndWorkshare : Directive<"end workshare"> {
- let allowedClauses = [
- VersionedClause<OMPC_NoWait>
- ];
-}
+def OMP_EndSections : Directive<"end sections"> {
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_NoWait>
+ ];
+}
+def OMP_EndSingle : Directive<"end single"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_CopyPrivate>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_NoWait>
+ ];
+}
+def OMP_EndWorkshare : Directive<"end workshare"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_NoWait>
+ ];
+}
def OMP_Unknown : Directive<"unknown"> {
- let isDefault = true;
+ let isDefault = true;
}
diff --git a/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPConstants.h b/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPConstants.h
index 197ddf0ed1..953321d47c 100644
--- a/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPConstants.h
+++ b/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPConstants.h
@@ -23,7 +23,7 @@
#include "llvm/ADT/BitmaskEnum.h"
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Frontend/OpenMP/OMP.h.inc"
namespace llvm {
@@ -49,12 +49,12 @@ enum class InternalControlVar {
#include "llvm/Frontend/OpenMP/OMPKinds.def"
enum class ICVInitValue {
-#define ICV_INIT_VALUE(Enum, Name) Enum,
+#define ICV_INIT_VALUE(Enum, Name) Enum,
#include "llvm/Frontend/OpenMP/OMPKinds.def"
};
-#define ICV_INIT_VALUE(Enum, Name) \
- constexpr auto Enum = omp::ICVInitValue::Enum;
+#define ICV_INIT_VALUE(Enum, Name) \
+ constexpr auto Enum = omp::ICVInitValue::Enum;
#include "llvm/Frontend/OpenMP/OMPKinds.def"
/// IDs for all omp runtime library (RTL) functions.
@@ -87,33 +87,33 @@ enum class IdentFlag {
#define OMP_IDENT_FLAG(Enum, ...) constexpr auto Enum = omp::IdentFlag::Enum;
#include "llvm/Frontend/OpenMP/OMPKinds.def"
-/// Helper to describe assume clauses.
-struct AssumptionClauseMappingInfo {
- /// The identifier describing the (beginning of the) clause.
- llvm::StringLiteral Identifier;
- /// Flag to determine if the identifier is a full name or the start of a name.
- bool StartsWith;
- /// Flag to determine if a directive lists follows.
- bool HasDirectiveList;
- /// Flag to determine if an expression follows.
- bool HasExpression;
-};
-
-/// All known assume clauses.
-static constexpr AssumptionClauseMappingInfo AssumptionClauseMappings[] = {
-#define OMP_ASSUME_CLAUSE(Identifier, StartsWith, HasDirectiveList, \
- HasExpression) \
- {Identifier, StartsWith, HasDirectiveList, HasExpression},
-#include "llvm/Frontend/OpenMP/OMPKinds.def"
-};
-
-inline std::string getAllAssumeClauseOptions() {
- std::string S;
- for (const AssumptionClauseMappingInfo &ACMI : AssumptionClauseMappings)
- S += (S.empty() ? "'" : "', '") + ACMI.Identifier.str();
- return S + "'";
-}
-
+/// Helper to describe assume clauses.
+struct AssumptionClauseMappingInfo {
+ /// The identifier describing the (beginning of the) clause.
+ llvm::StringLiteral Identifier;
+ /// Flag to determine if the identifier is a full name or the start of a name.
+ bool StartsWith;
+ /// Flag to determine if a directive lists follows.
+ bool HasDirectiveList;
+ /// Flag to determine if an expression follows.
+ bool HasExpression;
+};
+
+/// All known assume clauses.
+static constexpr AssumptionClauseMappingInfo AssumptionClauseMappings[] = {
+#define OMP_ASSUME_CLAUSE(Identifier, StartsWith, HasDirectiveList, \
+ HasExpression) \
+ {Identifier, StartsWith, HasDirectiveList, HasExpression},
+#include "llvm/Frontend/OpenMP/OMPKinds.def"
+};
+
+inline std::string getAllAssumeClauseOptions() {
+ std::string S;
+ for (const AssumptionClauseMappingInfo &ACMI : AssumptionClauseMappings)
+ S += (S.empty() ? "'" : "', '") + ACMI.Identifier.str();
+ return S + "'";
+}
+
} // end namespace omp
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPContext.h b/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPContext.h
index a707fc7d72..4031468da9 100644
--- a/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPContext.h
+++ b/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPContext.h
@@ -77,20 +77,20 @@ TraitSelector getOpenMPContextTraitSelectorForProperty(TraitProperty Property);
/// Return a textual representation of the trait selector \p Kind.
StringRef getOpenMPContextTraitSelectorName(TraitSelector Kind);
-/// Parse \p Str and return the trait property it matches in the set \p Set and
-/// selector \p Selector or TraitProperty::invalid.
-TraitProperty getOpenMPContextTraitPropertyKind(TraitSet Set,
- TraitSelector Selector,
- StringRef Str);
+/// Parse \p Str and return the trait property it matches in the set \p Set and
+/// selector \p Selector or TraitProperty::invalid.
+TraitProperty getOpenMPContextTraitPropertyKind(TraitSet Set,
+ TraitSelector Selector,
+ StringRef Str);
/// Return the trait property for a singleton selector \p Selector.
TraitProperty getOpenMPContextTraitPropertyForSelector(TraitSelector Selector);
-/// Return a textual representation of the trait property \p Kind, which might
-/// be the raw string we parsed (\p RawString) if we do not translate the
-/// property into a (distinct) enum.
-StringRef getOpenMPContextTraitPropertyName(TraitProperty Kind,
- StringRef RawString);
+/// Return a textual representation of the trait property \p Kind, which might
+/// be the raw string we parsed (\p RawString) if we do not translate the
+/// property into a (distinct) enum.
+StringRef getOpenMPContextTraitPropertyName(TraitProperty Kind,
+ StringRef RawString);
/// Return a textual representation of the trait property \p Kind with selector
/// and set name included.
@@ -124,36 +124,36 @@ bool isValidTraitPropertyForTraitSetAndSelector(TraitProperty Property,
/// scored (via the ScoresMap). In addition, the required consturct nesting is
/// decribed as well.
struct VariantMatchInfo {
- /// Add the trait \p Property to the required trait set. \p RawString is the
- /// string we parsed and derived \p Property from. If \p Score is not null, it
- /// recorded as well. If \p Property is in the `construct` set it is recorded
- /// in-order in the ConstructTraits as well.
- void addTrait(TraitProperty Property, StringRef RawString,
- APInt *Score = nullptr) {
- addTrait(getOpenMPContextTraitSetForProperty(Property), Property, RawString,
- Score);
+ /// Add the trait \p Property to the required trait set. \p RawString is the
+ /// string we parsed and derived \p Property from. If \p Score is not null, it
+ /// recorded as well. If \p Property is in the `construct` set it is recorded
+ /// in-order in the ConstructTraits as well.
+ void addTrait(TraitProperty Property, StringRef RawString,
+ APInt *Score = nullptr) {
+ addTrait(getOpenMPContextTraitSetForProperty(Property), Property, RawString,
+ Score);
}
/// Add the trait \p Property which is in set \p Set to the required trait
- /// set. \p RawString is the string we parsed and derived \p Property from. If
- /// \p Score is not null, it recorded as well. If \p Set is the `construct`
- /// set it is recorded in-order in the ConstructTraits as well.
- void addTrait(TraitSet Set, TraitProperty Property, StringRef RawString,
- APInt *Score = nullptr) {
+ /// set. \p RawString is the string we parsed and derived \p Property from. If
+ /// \p Score is not null, it recorded as well. If \p Set is the `construct`
+ /// set it is recorded in-order in the ConstructTraits as well.
+ void addTrait(TraitSet Set, TraitProperty Property, StringRef RawString,
+ APInt *Score = nullptr) {
if (Score)
ScoreMap[Property] = *Score;
-
- // Special handling for `device={isa(...)}` as we do not match the enum but
- // the raw string.
- if (Property == TraitProperty::device_isa___ANY)
- ISATraits.push_back(RawString);
-
+
+ // Special handling for `device={isa(...)}` as we do not match the enum but
+ // the raw string.
+ if (Property == TraitProperty::device_isa___ANY)
+ ISATraits.push_back(RawString);
+
RequiredTraits.set(unsigned(Property));
if (Set == TraitSet::construct)
ConstructTraits.push_back(Property);
}
BitVector RequiredTraits = BitVector(unsigned(TraitProperty::Last) + 1);
- SmallVector<StringRef, 8> ISATraits;
+ SmallVector<StringRef, 8> ISATraits;
SmallVector<TraitProperty, 8> ConstructTraits;
SmallDenseMap<TraitProperty, APInt> ScoreMap;
};
@@ -163,7 +163,7 @@ struct VariantMatchInfo {
/// in OpenMP constructs at the location.
struct OMPContext {
OMPContext(bool IsDeviceCompilation, Triple TargetTriple);
- virtual ~OMPContext() = default;
+ virtual ~OMPContext() = default;
void addTrait(TraitProperty Property) {
addTrait(getOpenMPContextTraitSetForProperty(Property), Property);
@@ -174,11 +174,11 @@ struct OMPContext {
ConstructTraits.push_back(Property);
}
- /// Hook for users to check if an ISA trait matches. The trait is described as
- /// the string that got parsed and it depends on the target and context if
- /// this matches or not.
- virtual bool matchesISATrait(StringRef) const { return false; }
-
+ /// Hook for users to check if an ISA trait matches. The trait is described as
+ /// the string that got parsed and it depends on the target and context if
+ /// this matches or not.
+ virtual bool matchesISATrait(StringRef) const { return false; }
+
BitVector ActiveTraits = BitVector(unsigned(TraitProperty::Last) + 1);
SmallVector<TraitProperty, 8> ConstructTraits;
};
diff --git a/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPGridValues.h b/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPGridValues.h
index 4662312b4d..da0c4d1f3f 100644
--- a/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPGridValues.h
+++ b/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPGridValues.h
@@ -7,9 +7,9 @@
//====--- OMPGridValues.h - Language-specific address spaces --*- C++ -*-====//
//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
@@ -35,30 +35,30 @@ namespace omp {
/// use the new array name.
///
/// Example usage in clang:
-/// const unsigned slot_size =
-/// ctx.GetTargetInfo().getGridValue(llvm::omp::GVIDX::GV_Warp_Size);
+/// const unsigned slot_size =
+/// ctx.GetTargetInfo().getGridValue(llvm::omp::GVIDX::GV_Warp_Size);
///
/// Example usage in libomptarget/deviceRTLs:
-/// #include "llvm/Frontend/OpenMP/OMPGridValues.h"
+/// #include "llvm/Frontend/OpenMP/OMPGridValues.h"
/// #ifdef __AMDGPU__
/// #define GRIDVAL AMDGPUGpuGridValues
/// #else
/// #define GRIDVAL NVPTXGpuGridValues
/// #endif
/// ... Then use this reference for GV_Warp_Size in the deviceRTL source.
-/// llvm::omp::GRIDVAL[llvm::omp::GVIDX::GV_Warp_Size]
+/// llvm::omp::GRIDVAL[llvm::omp::GVIDX::GV_Warp_Size]
///
/// Example usage in libomptarget hsa plugin:
-/// #include "llvm/Frontend/OpenMP/OMPGridValues.h"
+/// #include "llvm/Frontend/OpenMP/OMPGridValues.h"
/// #define GRIDVAL AMDGPUGpuGridValues
/// ... Then use this reference to access GV_Warp_Size in the hsa plugin.
-/// llvm::omp::GRIDVAL[llvm::omp::GVIDX::GV_Warp_Size]
+/// llvm::omp::GRIDVAL[llvm::omp::GVIDX::GV_Warp_Size]
///
/// Example usage in libomptarget cuda plugin:
-/// #include "llvm/Frontend/OpenMP/OMPGridValues.h"
+/// #include "llvm/Frontend/OpenMP/OMPGridValues.h"
/// #define GRIDVAL NVPTXGpuGridValues
/// ... Then use this reference to access GV_Warp_Size in the cuda plugin.
-/// llvm::omp::GRIDVAL[llvm::omp::GVIDX::GV_Warp_Size]
+/// llvm::omp::GRIDVAL[llvm::omp::GVIDX::GV_Warp_Size]
///
enum GVIDX {
/// The maximum number of workers in a kernel.
diff --git a/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPIRBuilder.h b/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
index 8157864835..612e362800 100644
--- a/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
+++ b/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
@@ -25,10 +25,10 @@
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/Allocator.h"
-#include <forward_list>
+#include <forward_list>
namespace llvm {
-class CanonicalLoopInfo;
+class CanonicalLoopInfo;
/// An interface to create LLVM-IR for OpenMP directives.
///
@@ -45,10 +45,10 @@ public:
void initialize();
/// Finalize the underlying module, e.g., by outlining regions.
- /// \param AllowExtractorSinking Flag to include sinking instructions,
- /// emitted by CodeExtractor, in the
- /// outlined region. Default is false.
- void finalize(bool AllowExtractorSinking = false);
+ /// \param AllowExtractorSinking Flag to include sinking instructions,
+ /// emitted by CodeExtractor, in the
+ /// outlined region. Default is false.
+ void finalize(bool AllowExtractorSinking = false);
/// Add attributes known for \p FnID to \p Fn.
void addAttributes(omp::RuntimeFunction FnID, Function &Fn);
@@ -68,7 +68,7 @@ public:
struct FinalizationInfo {
/// The finalization callback provided by the last in-flight invocation of
- /// createXXXX for the directive of kind DK.
+ /// createXXXX for the directive of kind DK.
FinalizeCallbackTy FiniCB;
/// The directive kind of the innermost directive that has an associated
@@ -108,17 +108,17 @@ public:
function_ref<void(InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
BasicBlock &ContinuationBB)>;
- /// Callback type for loop body code generation.
- ///
- /// \param CodeGenIP is the insertion point where the loop's body code must be
- /// placed. This will be a dedicated BasicBlock with a
- /// conditional branch from the loop condition check and
- /// terminated with an unconditional branch to the loop
- /// latch.
- /// \param IndVar is the induction variable usable at the insertion point.
- using LoopBodyGenCallbackTy =
- function_ref<void(InsertPointTy CodeGenIP, Value *IndVar)>;
-
+ /// Callback type for loop body code generation.
+ ///
+ /// \param CodeGenIP is the insertion point where the loop's body code must be
+ /// placed. This will be a dedicated BasicBlock with a
+ /// conditional branch from the loop condition check and
+ /// terminated with an unconditional branch to the loop
+ /// latch.
+ /// \param IndVar is the induction variable usable at the insertion point.
+ using LoopBodyGenCallbackTy =
+ function_ref<void(InsertPointTy CodeGenIP, Value *IndVar)>;
+
/// Callback type for variable privatization (think copy & default
/// constructor).
///
@@ -126,20 +126,20 @@ public:
/// should be placed.
/// \param CodeGenIP is the insertion point at which the privatization code
/// should be placed.
- /// \param Original The value being copied/created, should not be used in the
- /// generated IR.
- /// \param Inner The equivalent of \p Original that should be used in the
- /// generated IR; this is equal to \p Original if the value is
- /// a pointer and can thus be passed directly, otherwise it is
- /// an equivalent but different value.
+ /// \param Original The value being copied/created, should not be used in the
+ /// generated IR.
+ /// \param Inner The equivalent of \p Original that should be used in the
+ /// generated IR; this is equal to \p Original if the value is
+ /// a pointer and can thus be passed directly, otherwise it is
+ /// an equivalent but different value.
/// \param ReplVal The replacement value, thus a copy or new created version
- /// of \p Inner.
+ /// of \p Inner.
///
/// \returns The new insertion point where code generation continues and
- /// \p ReplVal the replacement value.
+ /// \p ReplVal the replacement value.
using PrivatizeCallbackTy = function_ref<InsertPointTy(
- InsertPointTy AllocaIP, InsertPointTy CodeGenIP, Value &Original,
- Value &Inner, Value *&ReplVal)>;
+ InsertPointTy AllocaIP, InsertPointTy CodeGenIP, Value &Original,
+ Value &Inner, Value *&ReplVal)>;
/// Description of a LLVM-IR insertion point (IP) and a debug/source location
/// (filename, line, column, ...).
@@ -167,7 +167,7 @@ public:
/// should be checked and acted upon.
///
/// \returns The insertion point after the barrier.
- InsertPointTy createBarrier(const LocationDescription &Loc, omp::Directive DK,
+ InsertPointTy createBarrier(const LocationDescription &Loc, omp::Directive DK,
bool ForceSimpleCall = false,
bool CheckCancelFlag = true);
@@ -178,13 +178,13 @@ public:
/// \param CanceledDirective The kind of directive that is cancled.
///
/// \returns The insertion point after the barrier.
- InsertPointTy createCancel(const LocationDescription &Loc, Value *IfCondition,
+ InsertPointTy createCancel(const LocationDescription &Loc, Value *IfCondition,
omp::Directive CanceledDirective);
/// Generator for '#omp parallel'
///
/// \param Loc The insert and source location description.
- /// \param AllocaIP The insertion points to be used for alloca instructions.
+ /// \param AllocaIP The insertion points to be used for alloca instructions.
/// \param BodyGenCB Callback that will generate the region code.
/// \param PrivCB Callback to copy a given variable (think copy constructor).
/// \param FiniCB Callback to finalize variable copies.
@@ -195,179 +195,179 @@ public:
///
/// \returns The insertion position *after* the parallel.
IRBuilder<>::InsertPoint
- createParallel(const LocationDescription &Loc, InsertPointTy AllocaIP,
- BodyGenCallbackTy BodyGenCB, PrivatizeCallbackTy PrivCB,
- FinalizeCallbackTy FiniCB, Value *IfCondition,
- Value *NumThreads, omp::ProcBindKind ProcBind,
- bool IsCancellable);
-
- /// Generator for the control flow structure of an OpenMP canonical loop.
- ///
- /// This generator operates on the logical iteration space of the loop, i.e.
- /// the caller only has to provide a loop trip count of the loop as defined by
- /// base language semantics. The trip count is interpreted as an unsigned
- /// integer. The induction variable passed to \p BodyGenCB will be of the same
- /// type and run from 0 to \p TripCount - 1. It is up to the callback to
- /// convert the logical iteration variable to the loop counter variable in the
- /// loop body.
- ///
- /// \param Loc The insert and source location description. The insert
- /// location can be between two instructions or the end of a
- /// degenerate block (e.g. a BB under construction).
- /// \param BodyGenCB Callback that will generate the loop body code.
- /// \param TripCount Number of iterations the loop body is executed.
- /// \param Name Base name used to derive BB and instruction names.
- ///
- /// \returns An object representing the created control flow structure which
- /// can be used for loop-associated directives.
- CanonicalLoopInfo *createCanonicalLoop(const LocationDescription &Loc,
- LoopBodyGenCallbackTy BodyGenCB,
- Value *TripCount,
- const Twine &Name = "loop");
-
- /// Generator for the control flow structure of an OpenMP canonical loop.
- ///
- /// Instead of a logical iteration space, this allows specifying user-defined
- /// loop counter values using increment, upper- and lower bounds. To
- /// disambiguate the terminology when counting downwards, instead of lower
- /// bounds we use \p Start for the loop counter value in the first body
- /// iteration.
- ///
- /// Consider the following limitations:
- ///
- /// * A loop counter space over all integer values of its bit-width cannot be
- /// represented. E.g using uint8_t, its loop trip count of 256 cannot be
- /// stored into an 8 bit integer):
- ///
- /// DO I = 0, 255, 1
- ///
- /// * Unsigned wrapping is only supported when wrapping only "once"; E.g.
- /// effectively counting downwards:
- ///
- /// for (uint8_t i = 100u; i > 0; i += 127u)
- ///
- ///
- /// TODO: May need to add additional parameters to represent:
- ///
- /// * Allow representing downcounting with unsigned integers.
- ///
- /// * Sign of the step and the comparison operator might disagree:
- ///
- /// for (int i = 0; i < 42; --i)
- ///
- //
- /// \param Loc The insert and source location description.
- /// \param BodyGenCB Callback that will generate the loop body code.
- /// \param Start Value of the loop counter for the first iterations.
- /// \param Stop Loop counter values past this will stop the the
- /// iterations.
- /// \param Step Loop counter increment after each iteration; negative
- /// means counting down. \param IsSigned Whether Start, Stop
- /// and Stop are signed integers.
- /// \param InclusiveStop Whether \p Stop itself is a valid value for the loop
- /// counter.
- /// \param ComputeIP Insertion point for instructions computing the trip
- /// count. Can be used to ensure the trip count is available
- /// at the outermost loop of a loop nest. If not set,
- /// defaults to the preheader of the generated loop.
- /// \param Name Base name used to derive BB and instruction names.
- ///
- /// \returns An object representing the created control flow structure which
- /// can be used for loop-associated directives.
- CanonicalLoopInfo *createCanonicalLoop(const LocationDescription &Loc,
- LoopBodyGenCallbackTy BodyGenCB,
- Value *Start, Value *Stop, Value *Step,
- bool IsSigned, bool InclusiveStop,
- InsertPointTy ComputeIP = {},
- const Twine &Name = "loop");
-
- /// Modifies the canonical loop to be a statically-scheduled workshare loop.
- ///
- /// This takes a \p LoopInfo representing a canonical loop, such as the one
- /// created by \p createCanonicalLoop and emits additional instructions to
- /// turn it into a workshare loop. In particular, it calls to an OpenMP
- /// runtime function in the preheader to obtain the loop bounds to be used in
- /// the current thread, updates the relevant instructions in the canonical
- /// loop and calls to an OpenMP runtime finalization function after the loop.
- ///
- /// \param Loc The source location description, the insertion location
- /// is not used.
- /// \param CLI A descriptor of the canonical loop to workshare.
- /// \param AllocaIP An insertion point for Alloca instructions usable in the
- /// preheader of the loop.
- /// \param NeedsBarrier Indicates whether a barrier must be insterted after
- /// the loop.
- /// \param Chunk The size of loop chunk considered as a unit when
- /// scheduling. If \p nullptr, defaults to 1.
- ///
- /// \returns Updated CanonicalLoopInfo.
- CanonicalLoopInfo *createStaticWorkshareLoop(const LocationDescription &Loc,
- CanonicalLoopInfo *CLI,
- InsertPointTy AllocaIP,
- bool NeedsBarrier,
- Value *Chunk = nullptr);
-
- /// Tile a loop nest.
- ///
- /// Tiles the loops of \p Loops by the tile sizes in \p TileSizes. Loops in
- /// \p/ Loops must be perfectly nested, from outermost to innermost loop
- /// (i.e. Loops.front() is the outermost loop). The trip count llvm::Value
- /// of every loop and every tile sizes must be usable in the outermost
- /// loop's preheader. This implies that the loop nest is rectangular.
- ///
- /// Example:
- /// \code
- /// for (int i = 0; i < 15; ++i) // Canonical loop "i"
- /// for (int j = 0; j < 14; ++j) // Canonical loop "j"
- /// body(i, j);
- /// \endcode
- ///
- /// After tiling with Loops={i,j} and TileSizes={5,7}, the loop is changed to
- /// \code
- /// for (int i1 = 0; i1 < 3; ++i1)
- /// for (int j1 = 0; j1 < 2; ++j1)
- /// for (int i2 = 0; i2 < 5; ++i2)
- /// for (int j2 = 0; j2 < 7; ++j2)
- /// body(i1*3+i2, j1*3+j2);
- /// \endcode
- ///
- /// The returned vector are the loops {i1,j1,i2,j2}. The loops i1 and j1 are
- /// referred to the floor, and the loops i2 and j2 are the tiles. Tiling also
- /// handles non-constant trip counts, non-constant tile sizes and trip counts
- /// that are not multiples of the tile size. In the latter case the tile loop
- /// of the last floor-loop iteration will have fewer iterations than specified
- /// as its tile size.
- ///
- ///
- /// @param DL Debug location for instructions added by tiling, for
- /// instance the floor- and tile trip count computation.
- /// @param Loops Loops to tile. The CanonicalLoopInfo objects are
- /// invalidated by this method, i.e. should not used after
- /// tiling.
- /// @param TileSizes For each loop in \p Loops, the tile size for that
- /// dimensions.
- ///
- /// \returns A list of generated loops. Contains twice as many loops as the
- /// input loop nest; the first half are the floor loops and the
- /// second half are the tile loops.
- std::vector<CanonicalLoopInfo *>
- tileLoops(DebugLoc DL, ArrayRef<CanonicalLoopInfo *> Loops,
- ArrayRef<Value *> TileSizes);
-
+ createParallel(const LocationDescription &Loc, InsertPointTy AllocaIP,
+ BodyGenCallbackTy BodyGenCB, PrivatizeCallbackTy PrivCB,
+ FinalizeCallbackTy FiniCB, Value *IfCondition,
+ Value *NumThreads, omp::ProcBindKind ProcBind,
+ bool IsCancellable);
+
+ /// Generator for the control flow structure of an OpenMP canonical loop.
+ ///
+ /// This generator operates on the logical iteration space of the loop, i.e.
+ /// the caller only has to provide a loop trip count of the loop as defined by
+ /// base language semantics. The trip count is interpreted as an unsigned
+ /// integer. The induction variable passed to \p BodyGenCB will be of the same
+ /// type and run from 0 to \p TripCount - 1. It is up to the callback to
+ /// convert the logical iteration variable to the loop counter variable in the
+ /// loop body.
+ ///
+ /// \param Loc The insert and source location description. The insert
+ /// location can be between two instructions or the end of a
+ /// degenerate block (e.g. a BB under construction).
+ /// \param BodyGenCB Callback that will generate the loop body code.
+ /// \param TripCount Number of iterations the loop body is executed.
+ /// \param Name Base name used to derive BB and instruction names.
+ ///
+ /// \returns An object representing the created control flow structure which
+ /// can be used for loop-associated directives.
+ CanonicalLoopInfo *createCanonicalLoop(const LocationDescription &Loc,
+ LoopBodyGenCallbackTy BodyGenCB,
+ Value *TripCount,
+ const Twine &Name = "loop");
+
+ /// Generator for the control flow structure of an OpenMP canonical loop.
+ ///
+ /// Instead of a logical iteration space, this allows specifying user-defined
+ /// loop counter values using increment, upper- and lower bounds. To
+ /// disambiguate the terminology when counting downwards, instead of lower
+ /// bounds we use \p Start for the loop counter value in the first body
+ /// iteration.
+ ///
+ /// Consider the following limitations:
+ ///
+ /// * A loop counter space over all integer values of its bit-width cannot be
+ /// represented. E.g using uint8_t, its loop trip count of 256 cannot be
+ /// stored into an 8 bit integer):
+ ///
+ /// DO I = 0, 255, 1
+ ///
+ /// * Unsigned wrapping is only supported when wrapping only "once"; E.g.
+ /// effectively counting downwards:
+ ///
+ /// for (uint8_t i = 100u; i > 0; i += 127u)
+ ///
+ ///
+ /// TODO: May need to add additional parameters to represent:
+ ///
+ /// * Allow representing downcounting with unsigned integers.
+ ///
+ /// * Sign of the step and the comparison operator might disagree:
+ ///
+ /// for (int i = 0; i < 42; --i)
+ ///
+ //
+ /// \param Loc The insert and source location description.
+ /// \param BodyGenCB Callback that will generate the loop body code.
+ /// \param Start Value of the loop counter for the first iterations.
+ /// \param Stop Loop counter values past this will stop the the
+ /// iterations.
+ /// \param Step Loop counter increment after each iteration; negative
+ /// means counting down. \param IsSigned Whether Start, Stop
+ /// and Stop are signed integers.
+ /// \param InclusiveStop Whether \p Stop itself is a valid value for the loop
+ /// counter.
+ /// \param ComputeIP Insertion point for instructions computing the trip
+ /// count. Can be used to ensure the trip count is available
+ /// at the outermost loop of a loop nest. If not set,
+ /// defaults to the preheader of the generated loop.
+ /// \param Name Base name used to derive BB and instruction names.
+ ///
+ /// \returns An object representing the created control flow structure which
+ /// can be used for loop-associated directives.
+ CanonicalLoopInfo *createCanonicalLoop(const LocationDescription &Loc,
+ LoopBodyGenCallbackTy BodyGenCB,
+ Value *Start, Value *Stop, Value *Step,
+ bool IsSigned, bool InclusiveStop,
+ InsertPointTy ComputeIP = {},
+ const Twine &Name = "loop");
+
+ /// Modifies the canonical loop to be a statically-scheduled workshare loop.
+ ///
+ /// This takes a \p LoopInfo representing a canonical loop, such as the one
+ /// created by \p createCanonicalLoop and emits additional instructions to
+ /// turn it into a workshare loop. In particular, it calls to an OpenMP
+ /// runtime function in the preheader to obtain the loop bounds to be used in
+ /// the current thread, updates the relevant instructions in the canonical
+ /// loop and calls to an OpenMP runtime finalization function after the loop.
+ ///
+ /// \param Loc The source location description, the insertion location
+ /// is not used.
+ /// \param CLI A descriptor of the canonical loop to workshare.
+ /// \param AllocaIP An insertion point for Alloca instructions usable in the
+ /// preheader of the loop.
+ /// \param NeedsBarrier Indicates whether a barrier must be insterted after
+ /// the loop.
+ /// \param Chunk The size of loop chunk considered as a unit when
+ /// scheduling. If \p nullptr, defaults to 1.
+ ///
+ /// \returns Updated CanonicalLoopInfo.
+ CanonicalLoopInfo *createStaticWorkshareLoop(const LocationDescription &Loc,
+ CanonicalLoopInfo *CLI,
+ InsertPointTy AllocaIP,
+ bool NeedsBarrier,
+ Value *Chunk = nullptr);
+
+ /// Tile a loop nest.
+ ///
+ /// Tiles the loops of \p Loops by the tile sizes in \p TileSizes. Loops in
+ /// \p/ Loops must be perfectly nested, from outermost to innermost loop
+ /// (i.e. Loops.front() is the outermost loop). The trip count llvm::Value
+ /// of every loop and every tile sizes must be usable in the outermost
+ /// loop's preheader. This implies that the loop nest is rectangular.
+ ///
+ /// Example:
+ /// \code
+ /// for (int i = 0; i < 15; ++i) // Canonical loop "i"
+ /// for (int j = 0; j < 14; ++j) // Canonical loop "j"
+ /// body(i, j);
+ /// \endcode
+ ///
+ /// After tiling with Loops={i,j} and TileSizes={5,7}, the loop is changed to
+ /// \code
+ /// for (int i1 = 0; i1 < 3; ++i1)
+ /// for (int j1 = 0; j1 < 2; ++j1)
+ /// for (int i2 = 0; i2 < 5; ++i2)
+ /// for (int j2 = 0; j2 < 7; ++j2)
+ /// body(i1*3+i2, j1*3+j2);
+ /// \endcode
+ ///
+ /// The returned vector are the loops {i1,j1,i2,j2}. The loops i1 and j1 are
+ /// referred to the floor, and the loops i2 and j2 are the tiles. Tiling also
+ /// handles non-constant trip counts, non-constant tile sizes and trip counts
+ /// that are not multiples of the tile size. In the latter case the tile loop
+ /// of the last floor-loop iteration will have fewer iterations than specified
+ /// as its tile size.
+ ///
+ ///
+ /// @param DL Debug location for instructions added by tiling, for
+ /// instance the floor- and tile trip count computation.
+ /// @param Loops Loops to tile. The CanonicalLoopInfo objects are
+ /// invalidated by this method, i.e. should not used after
+ /// tiling.
+ /// @param TileSizes For each loop in \p Loops, the tile size for that
+ /// dimensions.
+ ///
+ /// \returns A list of generated loops. Contains twice as many loops as the
+ /// input loop nest; the first half are the floor loops and the
+ /// second half are the tile loops.
+ std::vector<CanonicalLoopInfo *>
+ tileLoops(DebugLoc DL, ArrayRef<CanonicalLoopInfo *> Loops,
+ ArrayRef<Value *> TileSizes);
+
/// Generator for '#omp flush'
///
/// \param Loc The location where the flush directive was encountered
- void createFlush(const LocationDescription &Loc);
+ void createFlush(const LocationDescription &Loc);
/// Generator for '#omp taskwait'
///
/// \param Loc The location where the taskwait directive was encountered.
- void createTaskwait(const LocationDescription &Loc);
+ void createTaskwait(const LocationDescription &Loc);
/// Generator for '#omp taskyield'
///
/// \param Loc The location where the taskyield directive was encountered.
- void createTaskyield(const LocationDescription &Loc);
+ void createTaskyield(const LocationDescription &Loc);
///}
@@ -407,9 +407,9 @@ public:
omp::IdentFlag Flags = omp::IdentFlag(0),
unsigned Reserve2Flags = 0);
- // Get the type corresponding to __kmpc_impl_lanemask_t from the deviceRTL
- Type *getLanemaskType();
-
+ // Get the type corresponding to __kmpc_impl_lanemask_t from the deviceRTL
+ Type *getLanemaskType();
+
/// Generate control flow and cleanup for cancellation.
///
/// \param CancelFlag Flag indicating if the cancellation is performed.
@@ -491,10 +491,10 @@ public:
/// Collection of regions that need to be outlined during finalization.
SmallVector<OutlineInfo, 16> OutlineInfos;
- /// Collection of owned canonical loop objects that eventually need to be
- /// free'd.
- std::forward_list<CanonicalLoopInfo> LoopInfos;
-
+ /// Collection of owned canonical loop objects that eventually need to be
+ /// free'd.
+ std::forward_list<CanonicalLoopInfo> LoopInfos;
+
/// Add a new region that will be outlined later.
void addOutlineInfo(OutlineInfo &&OI) { OutlineInfos.emplace_back(OI); }
@@ -506,32 +506,32 @@ public:
StringMap<AssertingVH<Constant>, BumpPtrAllocator> InternalVars;
public:
- /// Generator for __kmpc_copyprivate
- ///
- /// \param Loc The source location description.
- /// \param BufSize Number of elements in the buffer.
- /// \param CpyBuf List of pointers to data to be copied.
- /// \param CpyFn function to call for copying data.
- /// \param DidIt flag variable; 1 for 'single' thread, 0 otherwise.
- ///
- /// \return The insertion position *after* the CopyPrivate call.
-
- InsertPointTy createCopyPrivate(const LocationDescription &Loc,
- llvm::Value *BufSize, llvm::Value *CpyBuf,
- llvm::Value *CpyFn, llvm::Value *DidIt);
-
- /// Generator for '#omp single'
- ///
- /// \param Loc The source location description.
- /// \param BodyGenCB Callback that will generate the region code.
- /// \param FiniCB Callback to finalize variable copies.
- /// \param DidIt Local variable used as a flag to indicate 'single' thread
- ///
- /// \returns The insertion position *after* the single call.
- InsertPointTy createSingle(const LocationDescription &Loc,
- BodyGenCallbackTy BodyGenCB,
- FinalizeCallbackTy FiniCB, llvm::Value *DidIt);
-
+ /// Generator for __kmpc_copyprivate
+ ///
+ /// \param Loc The source location description.
+ /// \param BufSize Number of elements in the buffer.
+ /// \param CpyBuf List of pointers to data to be copied.
+ /// \param CpyFn function to call for copying data.
+ /// \param DidIt flag variable; 1 for 'single' thread, 0 otherwise.
+ ///
+ /// \return The insertion position *after* the CopyPrivate call.
+
+ InsertPointTy createCopyPrivate(const LocationDescription &Loc,
+ llvm::Value *BufSize, llvm::Value *CpyBuf,
+ llvm::Value *CpyFn, llvm::Value *DidIt);
+
+ /// Generator for '#omp single'
+ ///
+ /// \param Loc The source location description.
+ /// \param BodyGenCB Callback that will generate the region code.
+ /// \param FiniCB Callback to finalize variable copies.
+ /// \param DidIt Local variable used as a flag to indicate 'single' thread
+ ///
+ /// \returns The insertion position *after* the single call.
+ InsertPointTy createSingle(const LocationDescription &Loc,
+ BodyGenCallbackTy BodyGenCB,
+ FinalizeCallbackTy FiniCB, llvm::Value *DidIt);
+
/// Generator for '#omp master'
///
/// \param Loc The insert and source location description.
@@ -539,7 +539,7 @@ public:
/// \param FiniCB Callback to finalize variable copies.
///
/// \returns The insertion position *after* the master.
- InsertPointTy createMaster(const LocationDescription &Loc,
+ InsertPointTy createMaster(const LocationDescription &Loc,
BodyGenCallbackTy BodyGenCB,
FinalizeCallbackTy FiniCB);
@@ -552,7 +552,7 @@ public:
/// \param HintInst Hint Instruction for hint clause associated with critical
///
/// \returns The insertion position *after* the master.
- InsertPointTy createCritical(const LocationDescription &Loc,
+ InsertPointTy createCritical(const LocationDescription &Loc,
BodyGenCallbackTy BodyGenCB,
FinalizeCallbackTy FiniCB,
StringRef CriticalName, Value *HintInst);
@@ -569,7 +569,7 @@ public:
// and copy.in.end block
///
/// \returns The insertion point where copying operation to be emitted.
- InsertPointTy createCopyinClauseBlocks(InsertPointTy IP, Value *MasterAddr,
+ InsertPointTy createCopyinClauseBlocks(InsertPointTy IP, Value *MasterAddr,
Value *PrivateAddr,
llvm::IntegerType *IntPtrTy,
bool BranchtoEnd = true);
@@ -582,7 +582,7 @@ public:
/// \param Name Name of call Instruction for OMP_alloc
///
/// \returns CallInst to the OMP_Alloc call
- CallInst *createOMPAlloc(const LocationDescription &Loc, Value *Size,
+ CallInst *createOMPAlloc(const LocationDescription &Loc, Value *Size,
Value *Allocator, std::string Name = "");
/// Create a runtime call for kmpc_free
@@ -593,7 +593,7 @@ public:
/// \param Name Name of call Instruction for OMP_Free
///
/// \returns CallInst to the OMP_Free call
- CallInst *createOMPFree(const LocationDescription &Loc, Value *Addr,
+ CallInst *createOMPFree(const LocationDescription &Loc, Value *Addr,
Value *Allocator, std::string Name = "");
/// Create a runtime call for kmpc_threadprivate_cached
@@ -604,7 +604,7 @@ public:
/// \param Name Name of call Instruction for callinst
///
/// \returns CallInst to the thread private cache call.
- CallInst *createCachedThreadPrivate(const LocationDescription &Loc,
+ CallInst *createCachedThreadPrivate(const LocationDescription &Loc,
llvm::Value *Pointer,
llvm::ConstantInt *Size,
const llvm::Twine &Name = Twine(""));
@@ -712,157 +712,157 @@ private:
/// \param CriticalName Name of the critical region.
///
Value *getOMPCriticalRegionLock(StringRef CriticalName);
-
- /// Create the control flow structure of a canonical OpenMP loop.
- ///
- /// The emitted loop will be disconnected, i.e. no edge to the loop's
- /// preheader and no terminator in the AfterBB. The OpenMPIRBuilder's
- /// IRBuilder location is not preserved.
- ///
- /// \param DL DebugLoc used for the instructions in the skeleton.
- /// \param TripCount Value to be used for the trip count.
- /// \param F Function in which to insert the BasicBlocks.
- /// \param PreInsertBefore Where to insert BBs that execute before the body,
- /// typically the body itself.
- /// \param PostInsertBefore Where to insert BBs that execute after the body.
- /// \param Name Base name used to derive BB
- /// and instruction names.
- ///
- /// \returns The CanonicalLoopInfo that represents the emitted loop.
- CanonicalLoopInfo *createLoopSkeleton(DebugLoc DL, Value *TripCount,
- Function *F,
- BasicBlock *PreInsertBefore,
- BasicBlock *PostInsertBefore,
- const Twine &Name = {});
+
+ /// Create the control flow structure of a canonical OpenMP loop.
+ ///
+ /// The emitted loop will be disconnected, i.e. no edge to the loop's
+ /// preheader and no terminator in the AfterBB. The OpenMPIRBuilder's
+ /// IRBuilder location is not preserved.
+ ///
+ /// \param DL DebugLoc used for the instructions in the skeleton.
+ /// \param TripCount Value to be used for the trip count.
+ /// \param F Function in which to insert the BasicBlocks.
+ /// \param PreInsertBefore Where to insert BBs that execute before the body,
+ /// typically the body itself.
+ /// \param PostInsertBefore Where to insert BBs that execute after the body.
+ /// \param Name Base name used to derive BB
+ /// and instruction names.
+ ///
+ /// \returns The CanonicalLoopInfo that represents the emitted loop.
+ CanonicalLoopInfo *createLoopSkeleton(DebugLoc DL, Value *TripCount,
+ Function *F,
+ BasicBlock *PreInsertBefore,
+ BasicBlock *PostInsertBefore,
+ const Twine &Name = {});
+};
+
+/// Class to represented the control flow structure of an OpenMP canonical loop.
+///
+/// The control-flow structure is standardized for easy consumption by
+/// directives associated with loops. For instance, the worksharing-loop
+/// construct may change this control flow such that each loop iteration is
+/// executed on only one thread.
+///
+/// The control flow can be described as follows:
+///
+/// Preheader
+/// |
+/// /-> Header
+/// | |
+/// | Cond---\
+/// | | |
+/// | Body |
+/// | | | |
+/// | <...> |
+/// | | | |
+/// \--Latch |
+/// |
+/// Exit
+/// |
+/// After
+///
+/// Code in the header, condition block, latch and exit block must not have any
+/// side-effect. The body block is the single entry point into the loop body,
+/// which may contain arbitrary control flow as long as all control paths
+/// eventually branch to the latch block.
+///
+/// Defined outside OpenMPIRBuilder because one cannot forward-declare nested
+/// classes.
+class CanonicalLoopInfo {
+ friend class OpenMPIRBuilder;
+
+private:
+ /// Whether this object currently represents a loop.
+ bool IsValid = false;
+
+ BasicBlock *Preheader;
+ BasicBlock *Header;
+ BasicBlock *Cond;
+ BasicBlock *Body;
+ BasicBlock *Latch;
+ BasicBlock *Exit;
+ BasicBlock *After;
+
+ /// Add the control blocks of this loop to \p BBs.
+ ///
+ /// This does not include any block from the body, including the one returned
+ /// by getBody().
+ void collectControlBlocks(SmallVectorImpl<BasicBlock *> &BBs);
+
+public:
+ /// The preheader ensures that there is only a single edge entering the loop.
+ /// Code that must be execute before any loop iteration can be emitted here,
+ /// such as computing the loop trip count and begin lifetime markers. Code in
+ /// the preheader is not considered part of the canonical loop.
+ BasicBlock *getPreheader() const { return Preheader; }
+
+ /// The header is the entry for each iteration. In the canonical control flow,
+ /// it only contains the PHINode for the induction variable.
+ BasicBlock *getHeader() const { return Header; }
+
+ /// The condition block computes whether there is another loop iteration. If
+ /// yes, branches to the body; otherwise to the exit block.
+ BasicBlock *getCond() const { return Cond; }
+
+ /// The body block is the single entry for a loop iteration and not controlled
+ /// by CanonicalLoopInfo. It can contain arbitrary control flow but must
+ /// eventually branch to the \p Latch block.
+ BasicBlock *getBody() const { return Body; }
+
+ /// Reaching the latch indicates the end of the loop body code. In the
+ /// canonical control flow, it only contains the increment of the induction
+ /// variable.
+ BasicBlock *getLatch() const { return Latch; }
+
+ /// Reaching the exit indicates no more iterations are being executed.
+ BasicBlock *getExit() const { return Exit; }
+
+ /// The after block is intended for clean-up code such as lifetime end
+ /// markers. It is separate from the exit block to ensure, analogous to the
+ /// preheader, it having just a single entry edge and being free from PHI
+ /// nodes should there be multiple loop exits (such as from break
+ /// statements/cancellations).
+ BasicBlock *getAfter() const { return After; }
+
+ /// Returns the llvm::Value containing the number of loop iterations. It must
+ /// be valid in the preheader and always interpreted as an unsigned integer of
+ /// any bit-width.
+ Value *getTripCount() const {
+ Instruction *CmpI = &Cond->front();
+ assert(isa<CmpInst>(CmpI) && "First inst must compare IV with TripCount");
+ return CmpI->getOperand(1);
+ }
+
+ /// Returns the instruction representing the current logical induction
+ /// variable. Always unsigned, always starting at 0 with an increment of one.
+ Instruction *getIndVar() const {
+ Instruction *IndVarPHI = &Header->front();
+ assert(isa<PHINode>(IndVarPHI) && "First inst must be the IV PHI");
+ return IndVarPHI;
+ }
+
+ /// Return the type of the induction variable (and the trip count).
+ Type *getIndVarType() const { return getIndVar()->getType(); }
+
+ /// Return the insertion point for user code before the loop.
+ OpenMPIRBuilder::InsertPointTy getPreheaderIP() const {
+ return {Preheader, std::prev(Preheader->end())};
+ };
+
+ /// Return the insertion point for user code in the body.
+ OpenMPIRBuilder::InsertPointTy getBodyIP() const {
+ return {Body, Body->begin()};
+ };
+
+ /// Return the insertion point for user code after the loop.
+ OpenMPIRBuilder::InsertPointTy getAfterIP() const {
+ return {After, After->begin()};
+ };
+
+ /// Consistency self-check.
+ void assertOK() const;
};
-/// Class to represented the control flow structure of an OpenMP canonical loop.
-///
-/// The control-flow structure is standardized for easy consumption by
-/// directives associated with loops. For instance, the worksharing-loop
-/// construct may change this control flow such that each loop iteration is
-/// executed on only one thread.
-///
-/// The control flow can be described as follows:
-///
-/// Preheader
-/// |
-/// /-> Header
-/// | |
-/// | Cond---\
-/// | | |
-/// | Body |
-/// | | | |
-/// | <...> |
-/// | | | |
-/// \--Latch |
-/// |
-/// Exit
-/// |
-/// After
-///
-/// Code in the header, condition block, latch and exit block must not have any
-/// side-effect. The body block is the single entry point into the loop body,
-/// which may contain arbitrary control flow as long as all control paths
-/// eventually branch to the latch block.
-///
-/// Defined outside OpenMPIRBuilder because one cannot forward-declare nested
-/// classes.
-class CanonicalLoopInfo {
- friend class OpenMPIRBuilder;
-
-private:
- /// Whether this object currently represents a loop.
- bool IsValid = false;
-
- BasicBlock *Preheader;
- BasicBlock *Header;
- BasicBlock *Cond;
- BasicBlock *Body;
- BasicBlock *Latch;
- BasicBlock *Exit;
- BasicBlock *After;
-
- /// Add the control blocks of this loop to \p BBs.
- ///
- /// This does not include any block from the body, including the one returned
- /// by getBody().
- void collectControlBlocks(SmallVectorImpl<BasicBlock *> &BBs);
-
-public:
- /// The preheader ensures that there is only a single edge entering the loop.
- /// Code that must be execute before any loop iteration can be emitted here,
- /// such as computing the loop trip count and begin lifetime markers. Code in
- /// the preheader is not considered part of the canonical loop.
- BasicBlock *getPreheader() const { return Preheader; }
-
- /// The header is the entry for each iteration. In the canonical control flow,
- /// it only contains the PHINode for the induction variable.
- BasicBlock *getHeader() const { return Header; }
-
- /// The condition block computes whether there is another loop iteration. If
- /// yes, branches to the body; otherwise to the exit block.
- BasicBlock *getCond() const { return Cond; }
-
- /// The body block is the single entry for a loop iteration and not controlled
- /// by CanonicalLoopInfo. It can contain arbitrary control flow but must
- /// eventually branch to the \p Latch block.
- BasicBlock *getBody() const { return Body; }
-
- /// Reaching the latch indicates the end of the loop body code. In the
- /// canonical control flow, it only contains the increment of the induction
- /// variable.
- BasicBlock *getLatch() const { return Latch; }
-
- /// Reaching the exit indicates no more iterations are being executed.
- BasicBlock *getExit() const { return Exit; }
-
- /// The after block is intended for clean-up code such as lifetime end
- /// markers. It is separate from the exit block to ensure, analogous to the
- /// preheader, it having just a single entry edge and being free from PHI
- /// nodes should there be multiple loop exits (such as from break
- /// statements/cancellations).
- BasicBlock *getAfter() const { return After; }
-
- /// Returns the llvm::Value containing the number of loop iterations. It must
- /// be valid in the preheader and always interpreted as an unsigned integer of
- /// any bit-width.
- Value *getTripCount() const {
- Instruction *CmpI = &Cond->front();
- assert(isa<CmpInst>(CmpI) && "First inst must compare IV with TripCount");
- return CmpI->getOperand(1);
- }
-
- /// Returns the instruction representing the current logical induction
- /// variable. Always unsigned, always starting at 0 with an increment of one.
- Instruction *getIndVar() const {
- Instruction *IndVarPHI = &Header->front();
- assert(isa<PHINode>(IndVarPHI) && "First inst must be the IV PHI");
- return IndVarPHI;
- }
-
- /// Return the type of the induction variable (and the trip count).
- Type *getIndVarType() const { return getIndVar()->getType(); }
-
- /// Return the insertion point for user code before the loop.
- OpenMPIRBuilder::InsertPointTy getPreheaderIP() const {
- return {Preheader, std::prev(Preheader->end())};
- };
-
- /// Return the insertion point for user code in the body.
- OpenMPIRBuilder::InsertPointTy getBodyIP() const {
- return {Body, Body->begin()};
- };
-
- /// Return the insertion point for user code after the loop.
- OpenMPIRBuilder::InsertPointTy getAfterIP() const {
- return {After, After->begin()};
- };
-
- /// Consistency self-check.
- void assertOK() const;
-};
-
} // end namespace llvm
#endif // LLVM_IR_IRBUILDER_H
diff --git a/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPKinds.def b/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPKinds.def
index 58c23c20fb..75d360bf42 100644
--- a/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPKinds.def
+++ b/contrib/libs/llvm12/include/llvm/Frontend/OpenMP/OMPKinds.def
@@ -7,15 +7,15 @@
//===----------------------------------------------------------------------===//
/// \file
///
-/// This file defines the list of supported OpenMP runtime
+/// This file defines the list of supported OpenMP runtime
/// calls, and other things that need to be listed in enums.
///
-/// This file is under transition to OMP.td with TableGen code generation.
-///
+/// This file is under transition to OMP.td with TableGen code generation.
+///
//===----------------------------------------------------------------------===//
-/// OpenMP Directives, combined directives and Clauses
-/// - Moved to OMP.td
+/// OpenMP Directives, combined directives and Clauses
+/// - Moved to OMP.td
/// Types used in runtime structs or runtime functions
///
@@ -30,16 +30,16 @@
__OMP_TYPE(Void)
__OMP_TYPE(Int1)
__OMP_TYPE(Int8)
-__OMP_TYPE(Int16)
+__OMP_TYPE(Int16)
__OMP_TYPE(Int32)
__OMP_TYPE(Int64)
__OMP_TYPE(Int8Ptr)
-__OMP_TYPE(Int16Ptr)
+__OMP_TYPE(Int16Ptr)
__OMP_TYPE(Int32Ptr)
__OMP_TYPE(Int64Ptr)
OMP_TYPE(SizeTy, M.getDataLayout().getIntPtrType(Ctx))
-OMP_TYPE(LanemaskTy, getLanemaskType())
+OMP_TYPE(LanemaskTy, getLanemaskType())
#define __OMP_PTR_TYPE(NAME, BASE) OMP_TYPE(NAME, BASE->getPointerTo())
@@ -87,7 +87,7 @@ __OMP_ARRAY_TYPE(KmpCriticalName, Int32, 8)
OMP_STRUCT_TYPE(VarName, "struct." #Name, __VA_ARGS__)
__OMP_STRUCT_TYPE(Ident, ident_t, Int32, Int32, Int32, Int32, Int8Ptr)
-__OMP_STRUCT_TYPE(AsyncInfo, __tgt_async_info, Int8Ptr)
+__OMP_STRUCT_TYPE(AsyncInfo, __tgt_async_info, Int8Ptr)
#undef __OMP_STRUCT_TYPE
#undef OMP_STRUCT_TYPE
@@ -107,9 +107,9 @@ __OMP_FUNCTION_TYPE(KmpcDtor, false, Void, VoidPtr)
__OMP_FUNCTION_TYPE(KmpcCopyCtor, false, VoidPtr, VoidPtr, VoidPtr)
__OMP_FUNCTION_TYPE(TaskRoutineEntry, false, Int32, Int32,
/* kmp_task_t */ VoidPtr)
-__OMP_FUNCTION_TYPE(ShuffleReduce, false, Void, VoidPtr, Int16, Int16, Int16)
-__OMP_FUNCTION_TYPE(InterWarpCopy, false, Void, VoidPtr, Int32)
-__OMP_FUNCTION_TYPE(GlobalList, false, Void, VoidPtr, Int32, VoidPtr)
+__OMP_FUNCTION_TYPE(ShuffleReduce, false, Void, VoidPtr, Int16, Int16, Int16)
+__OMP_FUNCTION_TYPE(InterWarpCopy, false, Void, VoidPtr, Int32)
+__OMP_FUNCTION_TYPE(GlobalList, false, Void, VoidPtr, Int32, VoidPtr)
#undef __OMP_FUNCTION_TYPE
#undef OMP_FUNCTION_TYPE
@@ -120,20 +120,20 @@ __OMP_FUNCTION_TYPE(GlobalList, false, Void, VoidPtr, Int32, VoidPtr)
///
///{
-#ifndef ICV_INIT_VALUE
-#define ICV_INIT_VALUE(Enum, Name)
-#endif
-
-#define __ICV_INIT_VALUE(Name) ICV_INIT_VALUE(ICV_##Name, #Name)
-
-__ICV_INIT_VALUE(ZERO)
-__ICV_INIT_VALUE(FALSE)
-__ICV_INIT_VALUE(IMPLEMENTATION_DEFINED)
-__ICV_INIT_VALUE(LAST)
-
-#undef __ICV_INIT_VALUE
-#undef ICV_INIT_VALUE
-
+#ifndef ICV_INIT_VALUE
+#define ICV_INIT_VALUE(Enum, Name)
+#endif
+
+#define __ICV_INIT_VALUE(Name) ICV_INIT_VALUE(ICV_##Name, #Name)
+
+__ICV_INIT_VALUE(ZERO)
+__ICV_INIT_VALUE(FALSE)
+__ICV_INIT_VALUE(IMPLEMENTATION_DEFINED)
+__ICV_INIT_VALUE(LAST)
+
+#undef __ICV_INIT_VALUE
+#undef ICV_INIT_VALUE
+
#ifndef ICV_DATA_ENV
#define ICV_DATA_ENV(Enum, Name, EnvVarName, Init)
#endif
@@ -144,7 +144,7 @@ __ICV_INIT_VALUE(LAST)
__ICV_DATA_ENV(nthreads, OMP_NUM_THREADS, ICV_IMPLEMENTATION_DEFINED)
__ICV_DATA_ENV(active_levels, NONE, ICV_ZERO)
__ICV_DATA_ENV(cancel, OMP_CANCELLATION, ICV_FALSE)
-__ICV_DATA_ENV(proc_bind, OMP_PROC_BIND, ICV_IMPLEMENTATION_DEFINED)
+__ICV_DATA_ENV(proc_bind, OMP_PROC_BIND, ICV_IMPLEMENTATION_DEFINED)
__ICV_DATA_ENV(__last, last, ICV_LAST)
#undef __ICV_DATA_ENV
@@ -170,7 +170,7 @@ __ICV_RT_SET(nthreads, omp_set_num_threads)
__ICV_RT_GET(nthreads, omp_get_max_threads)
__ICV_RT_GET(active_levels, omp_get_active_level)
__ICV_RT_GET(cancel, omp_get_cancellation)
-__ICV_RT_GET(proc_bind, omp_get_proc_bind)
+__ICV_RT_GET(proc_bind, omp_get_proc_bind)
#undef __ICV_RT_GET
#undef ICV_RT_GET
@@ -202,8 +202,8 @@ __OMP_RTL(__kmpc_push_num_threads, false, Void, IdentPtr, Int32,
/* Int */ Int32)
__OMP_RTL(__kmpc_push_proc_bind, false, Void, IdentPtr, Int32, /* Int */ Int32)
__OMP_RTL(__kmpc_omp_reg_task_with_affinity, false, Int32, IdentPtr, Int32,
- /* kmp_task_t */ VoidPtr, Int32,
- /* kmp_task_affinity_info_t */ VoidPtr)
+ /* kmp_task_t */ VoidPtr, Int32,
+ /* kmp_task_affinity_info_t */ VoidPtr)
__OMP_RTL(omp_get_thread_num, false, Int32, )
__OMP_RTL(omp_get_num_threads, false, Int32, )
@@ -250,7 +250,7 @@ __OMP_RTL(__kmpc_reduce, false, Int32, IdentPtr, Int32, Int32, SizeTy, VoidPtr,
ReduceFunctionPtr, KmpCriticalNamePtrTy)
__OMP_RTL(__kmpc_reduce_nowait, false, Int32, IdentPtr, Int32, Int32, SizeTy,
VoidPtr, ReduceFunctionPtr, KmpCriticalNamePtrTy)
-__OMP_RTL(__kmpc_end_reduce, false, Void, IdentPtr, Int32, KmpCriticalNamePtrTy)
+__OMP_RTL(__kmpc_end_reduce, false, Void, IdentPtr, Int32, KmpCriticalNamePtrTy)
__OMP_RTL(__kmpc_end_reduce_nowait, false, Void, IdentPtr, Int32,
KmpCriticalNamePtrTy)
@@ -333,10 +333,10 @@ __OMP_RTL(__kmpc_taskloop, false, Void, IdentPtr, /* Int */ Int32, VoidPtr,
/* Int */ Int32, Int64, VoidPtr)
__OMP_RTL(__kmpc_omp_target_task_alloc, false, /* kmp_task_t */ VoidPtr,
IdentPtr, Int32, Int32, SizeTy, SizeTy, TaskRoutineEntryPtr, Int64)
-__OMP_RTL(__kmpc_taskred_modifier_init, false, /* kmp_taskgroup */ VoidPtr,
- IdentPtr, /* Int */ Int32, /* Int */ Int32, /* Int */ Int32, VoidPtr)
-__OMP_RTL(__kmpc_taskred_init, false, /* kmp_taskgroup */ VoidPtr,
- /* Int */ Int32, /* Int */ Int32, VoidPtr)
+__OMP_RTL(__kmpc_taskred_modifier_init, false, /* kmp_taskgroup */ VoidPtr,
+ IdentPtr, /* Int */ Int32, /* Int */ Int32, /* Int */ Int32, VoidPtr)
+__OMP_RTL(__kmpc_taskred_init, false, /* kmp_taskgroup */ VoidPtr,
+ /* Int */ Int32, /* Int */ Int32, VoidPtr)
__OMP_RTL(__kmpc_task_reduction_modifier_fini, false, Void, IdentPtr,
/* Int */ Int32, /* Int */ Int32)
__OMP_RTL(__kmpc_task_reduction_get_th_data, false, VoidPtr, Int32, VoidPtr,
@@ -375,83 +375,83 @@ __OMP_RTL(__kmpc_init_allocator, false, /* omp_allocator_handle_t */ VoidPtr,
__OMP_RTL(__kmpc_destroy_allocator, false, Void, /* Int */ Int32,
/* omp_allocator_handle_t */ VoidPtr)
-__OMP_RTL(__kmpc_push_target_tripcount_mapper, false, Void, IdentPtr, Int64, Int64)
-__OMP_RTL(__tgt_target_mapper, false, Int32, IdentPtr, Int64, VoidPtr, Int32, VoidPtrPtr,
- VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr)
-__OMP_RTL(__tgt_target_nowait_mapper, false, Int32, IdentPtr, Int64, VoidPtr, Int32,
- VoidPtrPtr, VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr)
-__OMP_RTL(__tgt_target_teams_mapper, false, Int32, IdentPtr, Int64, VoidPtr, Int32,
- VoidPtrPtr, VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr, Int32, Int32)
-__OMP_RTL(__tgt_target_teams_nowait_mapper, false, Int32, IdentPtr, Int64, VoidPtr, Int32,
- VoidPtrPtr, VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr, Int32, Int32)
+__OMP_RTL(__kmpc_push_target_tripcount_mapper, false, Void, IdentPtr, Int64, Int64)
+__OMP_RTL(__tgt_target_mapper, false, Int32, IdentPtr, Int64, VoidPtr, Int32, VoidPtrPtr,
+ VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr)
+__OMP_RTL(__tgt_target_nowait_mapper, false, Int32, IdentPtr, Int64, VoidPtr, Int32,
+ VoidPtrPtr, VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr)
+__OMP_RTL(__tgt_target_teams_mapper, false, Int32, IdentPtr, Int64, VoidPtr, Int32,
+ VoidPtrPtr, VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr, Int32, Int32)
+__OMP_RTL(__tgt_target_teams_nowait_mapper, false, Int32, IdentPtr, Int64, VoidPtr, Int32,
+ VoidPtrPtr, VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr, Int32, Int32)
__OMP_RTL(__tgt_register_requires, false, Void, Int64)
-__OMP_RTL(__tgt_target_data_begin_mapper, false, Void, IdentPtr, Int64, Int32, VoidPtrPtr,
- VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr)
-__OMP_RTL(__tgt_target_data_begin_nowait_mapper, false, Void, IdentPtr, Int64, Int32,
- VoidPtrPtr, VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr)
-__OMP_RTL(__tgt_target_data_begin_mapper_issue, false, Void, IdentPtr, Int64, Int32,
- VoidPtrPtr, VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr, AsyncInfoPtr)
-__OMP_RTL(__tgt_target_data_begin_mapper_wait, false, Void, Int64, AsyncInfoPtr)
-__OMP_RTL(__tgt_target_data_end_mapper, false, Void, IdentPtr, Int64, Int32, VoidPtrPtr,
- VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr)
-__OMP_RTL(__tgt_target_data_end_nowait_mapper, false, Void, IdentPtr, Int64, Int32,
- VoidPtrPtr, VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr)
-__OMP_RTL(__tgt_target_data_update_mapper, false, Void, IdentPtr, Int64, Int32,
- VoidPtrPtr, VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr)
-__OMP_RTL(__tgt_target_data_update_nowait_mapper, false, Void, IdentPtr, Int64, Int32,
- VoidPtrPtr, VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr)
+__OMP_RTL(__tgt_target_data_begin_mapper, false, Void, IdentPtr, Int64, Int32, VoidPtrPtr,
+ VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr)
+__OMP_RTL(__tgt_target_data_begin_nowait_mapper, false, Void, IdentPtr, Int64, Int32,
+ VoidPtrPtr, VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr)
+__OMP_RTL(__tgt_target_data_begin_mapper_issue, false, Void, IdentPtr, Int64, Int32,
+ VoidPtrPtr, VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr, AsyncInfoPtr)
+__OMP_RTL(__tgt_target_data_begin_mapper_wait, false, Void, Int64, AsyncInfoPtr)
+__OMP_RTL(__tgt_target_data_end_mapper, false, Void, IdentPtr, Int64, Int32, VoidPtrPtr,
+ VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr)
+__OMP_RTL(__tgt_target_data_end_nowait_mapper, false, Void, IdentPtr, Int64, Int32,
+ VoidPtrPtr, VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr)
+__OMP_RTL(__tgt_target_data_update_mapper, false, Void, IdentPtr, Int64, Int32,
+ VoidPtrPtr, VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr)
+__OMP_RTL(__tgt_target_data_update_nowait_mapper, false, Void, IdentPtr, Int64, Int32,
+ VoidPtrPtr, VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr)
__OMP_RTL(__tgt_mapper_num_components, false, Int64, VoidPtr)
__OMP_RTL(__tgt_push_mapper_component, false, Void, VoidPtr, VoidPtr, VoidPtr,
- Int64, Int64, VoidPtr)
+ Int64, Int64, VoidPtr)
__OMP_RTL(__kmpc_task_allow_completion_event, false, VoidPtr, IdentPtr,
/* Int */ Int32, /* kmp_task_t */ VoidPtr)
-/// OpenMP Device runtime functions
-__OMP_RTL(__kmpc_kernel_init, false, Void, Int32, Int16)
-__OMP_RTL(__kmpc_kernel_deinit, false, Void, Int16)
-__OMP_RTL(__kmpc_spmd_kernel_init, false, Void, Int32, Int16)
-__OMP_RTL(__kmpc_spmd_kernel_deinit_v2, false, Void, Int16)
-__OMP_RTL(__kmpc_kernel_prepare_parallel, false, Void, VoidPtr)
+/// OpenMP Device runtime functions
+__OMP_RTL(__kmpc_kernel_init, false, Void, Int32, Int16)
+__OMP_RTL(__kmpc_kernel_deinit, false, Void, Int16)
+__OMP_RTL(__kmpc_spmd_kernel_init, false, Void, Int32, Int16)
+__OMP_RTL(__kmpc_spmd_kernel_deinit_v2, false, Void, Int16)
+__OMP_RTL(__kmpc_kernel_prepare_parallel, false, Void, VoidPtr)
__OMP_RTL(__kmpc_kernel_parallel, false, Int1, VoidPtrPtr)
-__OMP_RTL(__kmpc_kernel_end_parallel, false, Void, )
-__OMP_RTL(__kmpc_serialized_parallel, false, Void, IdentPtr, Int32)
-__OMP_RTL(__kmpc_end_serialized_parallel, false, Void, IdentPtr, Int32)
-__OMP_RTL(__kmpc_shuffle_int32, false, Int32, Int32, Int16, Int16)
-__OMP_RTL(__kmpc_nvptx_parallel_reduce_nowait_v2, false, Int32, IdentPtr, Int32,
- Int32, SizeTy, VoidPtr, ShuffleReducePtr, InterWarpCopyPtr)
-__OMP_RTL(__kmpc_nvptx_end_reduce_nowait, false, Void, Int32)
-__OMP_RTL(__kmpc_nvptx_teams_reduce_nowait_v2, false, Int32, IdentPtr, Int32,
- VoidPtr, Int32, VoidPtr, ShuffleReducePtr, InterWarpCopyPtr,
- GlobalListPtr, GlobalListPtr, GlobalListPtr, GlobalListPtr)
-
-__OMP_RTL(__kmpc_shuffle_int64, false, Int64, Int64, Int16, Int16)
-__OMP_RTL(__kmpc_data_sharing_init_stack, false, Void, )
-__OMP_RTL(__kmpc_data_sharing_init_stack_spmd, false, Void, )
-
-__OMP_RTL(__kmpc_data_sharing_coalesced_push_stack, false, VoidPtr, SizeTy, Int16)
-__OMP_RTL(__kmpc_data_sharing_push_stack, false, VoidPtr, SizeTy, Int16)
-__OMP_RTL(__kmpc_data_sharing_pop_stack, false, Void, VoidPtr)
-__OMP_RTL(__kmpc_begin_sharing_variables, false, Void, VoidPtrPtrPtr, SizeTy)
-__OMP_RTL(__kmpc_end_sharing_variables, false, Void, )
-__OMP_RTL(__kmpc_get_shared_variables, false, Void, VoidPtrPtrPtr)
-__OMP_RTL(__kmpc_parallel_level, false, Int16, IdentPtr, Int32)
-__OMP_RTL(__kmpc_is_spmd_exec_mode, false, Int8, )
-__OMP_RTL(__kmpc_get_team_static_memory, false, Void, Int16, VoidPtr, SizeTy,
- Int16, VoidPtrPtr)
-__OMP_RTL(__kmpc_restore_team_static_memory, false, Void, Int16, Int16)
-__OMP_RTL(__kmpc_barrier_simple_spmd, false, Void, IdentPtr, Int32)
-
-__OMP_RTL(__kmpc_warp_active_thread_mask, false, LanemaskTy,)
-__OMP_RTL(__kmpc_syncwarp, false, Void, LanemaskTy)
-
+__OMP_RTL(__kmpc_kernel_end_parallel, false, Void, )
+__OMP_RTL(__kmpc_serialized_parallel, false, Void, IdentPtr, Int32)
+__OMP_RTL(__kmpc_end_serialized_parallel, false, Void, IdentPtr, Int32)
+__OMP_RTL(__kmpc_shuffle_int32, false, Int32, Int32, Int16, Int16)
+__OMP_RTL(__kmpc_nvptx_parallel_reduce_nowait_v2, false, Int32, IdentPtr, Int32,
+ Int32, SizeTy, VoidPtr, ShuffleReducePtr, InterWarpCopyPtr)
+__OMP_RTL(__kmpc_nvptx_end_reduce_nowait, false, Void, Int32)
+__OMP_RTL(__kmpc_nvptx_teams_reduce_nowait_v2, false, Int32, IdentPtr, Int32,
+ VoidPtr, Int32, VoidPtr, ShuffleReducePtr, InterWarpCopyPtr,
+ GlobalListPtr, GlobalListPtr, GlobalListPtr, GlobalListPtr)
+
+__OMP_RTL(__kmpc_shuffle_int64, false, Int64, Int64, Int16, Int16)
+__OMP_RTL(__kmpc_data_sharing_init_stack, false, Void, )
+__OMP_RTL(__kmpc_data_sharing_init_stack_spmd, false, Void, )
+
+__OMP_RTL(__kmpc_data_sharing_coalesced_push_stack, false, VoidPtr, SizeTy, Int16)
+__OMP_RTL(__kmpc_data_sharing_push_stack, false, VoidPtr, SizeTy, Int16)
+__OMP_RTL(__kmpc_data_sharing_pop_stack, false, Void, VoidPtr)
+__OMP_RTL(__kmpc_begin_sharing_variables, false, Void, VoidPtrPtrPtr, SizeTy)
+__OMP_RTL(__kmpc_end_sharing_variables, false, Void, )
+__OMP_RTL(__kmpc_get_shared_variables, false, Void, VoidPtrPtrPtr)
+__OMP_RTL(__kmpc_parallel_level, false, Int16, IdentPtr, Int32)
+__OMP_RTL(__kmpc_is_spmd_exec_mode, false, Int8, )
+__OMP_RTL(__kmpc_get_team_static_memory, false, Void, Int16, VoidPtr, SizeTy,
+ Int16, VoidPtrPtr)
+__OMP_RTL(__kmpc_restore_team_static_memory, false, Void, Int16, Int16)
+__OMP_RTL(__kmpc_barrier_simple_spmd, false, Void, IdentPtr, Int32)
+
+__OMP_RTL(__kmpc_warp_active_thread_mask, false, LanemaskTy,)
+__OMP_RTL(__kmpc_syncwarp, false, Void, LanemaskTy)
+
__OMP_RTL(__last, false, Void, )
#undef __OMP_RTL
#undef OMP_RTL
-#define ParamAttrs(...) ArrayRef<AttributeSet>({__VA_ARGS__})
+#define ParamAttrs(...) ArrayRef<AttributeSet>({__VA_ARGS__})
#define EnumAttr(Kind) Attribute::get(Ctx, Attribute::AttrKind::Kind)
-#define EnumAttrInt(Kind, N) Attribute::get(Ctx, Attribute::AttrKind::Kind, N)
+#define EnumAttrInt(Kind, N) Attribute::get(Ctx, Attribute::AttrKind::Kind, N)
#define AttributeSet(...) \
AttributeSet::get(Ctx, ArrayRef<Attribute>({__VA_ARGS__}))
@@ -464,94 +464,94 @@ __OMP_RTL(__last, false, Void, )
__OMP_ATTRS_SET(GetterAttrs,
OptimisticAttributes
? AttributeSet(EnumAttr(NoUnwind), EnumAttr(ReadOnly),
- EnumAttr(NoSync), EnumAttr(NoFree),
- EnumAttr(InaccessibleMemOnly),
- EnumAttr(WillReturn))
+ EnumAttr(NoSync), EnumAttr(NoFree),
+ EnumAttr(InaccessibleMemOnly),
+ EnumAttr(WillReturn))
: AttributeSet(EnumAttr(NoUnwind)))
__OMP_ATTRS_SET(GetterArgWriteAttrs,
OptimisticAttributes
? AttributeSet(EnumAttr(NoUnwind), EnumAttr(NoSync),
- EnumAttr(NoFree),
- EnumAttr(InaccessibleMemOrArgMemOnly),
- EnumAttr(WillReturn))
+ EnumAttr(NoFree),
+ EnumAttr(InaccessibleMemOrArgMemOnly),
+ EnumAttr(WillReturn))
: AttributeSet(EnumAttr(NoUnwind)))
__OMP_ATTRS_SET(SetterAttrs,
OptimisticAttributes
? AttributeSet(EnumAttr(NoUnwind), EnumAttr(WriteOnly),
- EnumAttr(NoSync), EnumAttr(NoFree),
- EnumAttr(InaccessibleMemOnly),
- EnumAttr(WillReturn))
+ EnumAttr(NoSync), EnumAttr(NoFree),
+ EnumAttr(InaccessibleMemOnly),
+ EnumAttr(WillReturn))
+ : AttributeSet(EnumAttr(NoUnwind)))
+
+__OMP_ATTRS_SET(DefaultAttrs,
+ OptimisticAttributes
+ ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(NoSync),
+ EnumAttr(WillReturn), EnumAttr(NoFree))
+ : AttributeSet(EnumAttr(NoUnwind)))
+
+__OMP_ATTRS_SET(BarrierAttrs,
+ OptimisticAttributes
+ ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(Convergent))
+ : AttributeSet(EnumAttr(NoUnwind), EnumAttr(Convergent)))
+
+__OMP_ATTRS_SET(InaccessibleArgOnlyAttrs,
+ OptimisticAttributes
+ ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(NoSync),
+ EnumAttr(InaccessibleMemOrArgMemOnly),
+ EnumAttr(WillReturn), EnumAttr(NoFree))
+ : AttributeSet(EnumAttr(NoUnwind)))
+
+#if 0
+__OMP_ATTRS_SET(InaccessibleOnlyAttrs,
+ OptimisticAttributes
+ ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(NoSync),
+ EnumAttr(InaccessibleMemOnly),
+ EnumAttr(WillReturn), EnumAttr(NoFree))
+ : AttributeSet(EnumAttr(NoUnwind)))
+#endif
+
+__OMP_ATTRS_SET(AllocAttrs,
+ OptimisticAttributes
+ ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(NoSync),
+ EnumAttr(WillReturn))
: AttributeSet(EnumAttr(NoUnwind)))
-__OMP_ATTRS_SET(DefaultAttrs,
- OptimisticAttributes
- ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(NoSync),
- EnumAttr(WillReturn), EnumAttr(NoFree))
- : AttributeSet(EnumAttr(NoUnwind)))
-
-__OMP_ATTRS_SET(BarrierAttrs,
- OptimisticAttributes
- ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(Convergent))
- : AttributeSet(EnumAttr(NoUnwind), EnumAttr(Convergent)))
-
-__OMP_ATTRS_SET(InaccessibleArgOnlyAttrs,
- OptimisticAttributes
- ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(NoSync),
- EnumAttr(InaccessibleMemOrArgMemOnly),
- EnumAttr(WillReturn), EnumAttr(NoFree))
- : AttributeSet(EnumAttr(NoUnwind)))
-
-#if 0
-__OMP_ATTRS_SET(InaccessibleOnlyAttrs,
- OptimisticAttributes
- ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(NoSync),
- EnumAttr(InaccessibleMemOnly),
- EnumAttr(WillReturn), EnumAttr(NoFree))
- : AttributeSet(EnumAttr(NoUnwind)))
-#endif
-
-__OMP_ATTRS_SET(AllocAttrs,
- OptimisticAttributes
- ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(NoSync),
- EnumAttr(WillReturn))
- : AttributeSet(EnumAttr(NoUnwind)))
-
-__OMP_ATTRS_SET(ForkAttrs, OptimisticAttributes
- ? AttributeSet(EnumAttr(NoUnwind))
- : AttributeSet(EnumAttr(NoUnwind)))
-
-__OMP_ATTRS_SET(ReadOnlyPtrAttrs,
- OptimisticAttributes
- ? AttributeSet(EnumAttr(ReadOnly), EnumAttr(NoFree),
- EnumAttr(NoCapture))
- : AttributeSet())
-
-#if 0
-__OMP_ATTRS_SET(WriteOnlyPtrAttrs,
- OptimisticAttributes
- ? AttributeSet(EnumAttr(WriteOnly), EnumAttr(NoFree),
- EnumAttr(NoCapture))
- : AttributeSet())
-#endif
-
-__OMP_ATTRS_SET(ArgPtrAttrs,
- OptimisticAttributes
- ? AttributeSet(EnumAttr(NoCapture), EnumAttr(NoFree))
- : AttributeSet())
-
-__OMP_ATTRS_SET(ReturnPtrAttrs,
- OptimisticAttributes
- ? AttributeSet(EnumAttr(NoAlias))
- : AttributeSet())
-
-#if 0
-__OMP_ATTRS_SET(ReturnAlignedPtrAttrs,
- OptimisticAttributes
- ? AttributeSet(EnumAttr(NoAlias), EnumAttrInt(Alignment, 8),
- EnumAttrInt(DereferenceableOrNull, 8))
- : AttributeSet())
-#endif
-
+__OMP_ATTRS_SET(ForkAttrs, OptimisticAttributes
+ ? AttributeSet(EnumAttr(NoUnwind))
+ : AttributeSet(EnumAttr(NoUnwind)))
+
+__OMP_ATTRS_SET(ReadOnlyPtrAttrs,
+ OptimisticAttributes
+ ? AttributeSet(EnumAttr(ReadOnly), EnumAttr(NoFree),
+ EnumAttr(NoCapture))
+ : AttributeSet())
+
+#if 0
+__OMP_ATTRS_SET(WriteOnlyPtrAttrs,
+ OptimisticAttributes
+ ? AttributeSet(EnumAttr(WriteOnly), EnumAttr(NoFree),
+ EnumAttr(NoCapture))
+ : AttributeSet())
+#endif
+
+__OMP_ATTRS_SET(ArgPtrAttrs,
+ OptimisticAttributes
+ ? AttributeSet(EnumAttr(NoCapture), EnumAttr(NoFree))
+ : AttributeSet())
+
+__OMP_ATTRS_SET(ReturnPtrAttrs,
+ OptimisticAttributes
+ ? AttributeSet(EnumAttr(NoAlias))
+ : AttributeSet())
+
+#if 0
+__OMP_ATTRS_SET(ReturnAlignedPtrAttrs,
+ OptimisticAttributes
+ ? AttributeSet(EnumAttr(NoAlias), EnumAttrInt(Alignment, 8),
+ EnumAttrInt(DereferenceableOrNull, 8))
+ : AttributeSet())
+#endif
+
#undef __OMP_ATTRS_SET
#undef OMP_ATTRS_SET
@@ -562,314 +562,314 @@ __OMP_ATTRS_SET(ReturnAlignedPtrAttrs,
#define __OMP_RTL_ATTRS(Name, FnAttrSet, RetAttrSet, ArgAttrSets) \
OMP_RTL_ATTRS(OMPRTL_##Name, FnAttrSet, RetAttrSet, ArgAttrSets)
-__OMP_RTL_ATTRS(__kmpc_barrier, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_barrier_simple_spmd, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_warp_active_thread_mask, BarrierAttrs, AttributeSet(),
- ParamAttrs())
-__OMP_RTL_ATTRS(__kmpc_syncwarp, BarrierAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(__kmpc_cancel, InaccessibleArgOnlyAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_cancel_barrier, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_flush, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_global_thread_num, GetterAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_fork_call, ForkAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_omp_taskwait, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_omp_taskyield, InaccessibleArgOnlyAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_push_num_threads, InaccessibleArgOnlyAttrs,
- AttributeSet(), ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_push_proc_bind, InaccessibleArgOnlyAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_serialized_parallel, InaccessibleArgOnlyAttrs,
- AttributeSet(), ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_end_serialized_parallel, InaccessibleArgOnlyAttrs,
- AttributeSet(), ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_omp_reg_task_with_affinity, DefaultAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ReadOnlyPtrAttrs,
- AttributeSet(), ReadOnlyPtrAttrs))
-
-__OMP_RTL_ATTRS(omp_get_thread_num, GetterAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(omp_get_num_threads, GetterAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(omp_get_max_threads, GetterAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(omp_in_parallel, GetterAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(omp_get_dynamic, GetterAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(omp_get_cancellation, GetterAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(omp_get_nested, GetterAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(
- omp_get_schedule, GetterArgWriteAttrs, AttributeSet(),
- ParamAttrs(AttributeSet(EnumAttr(NoCapture), EnumAttr(WriteOnly)),
- AttributeSet(EnumAttr(NoCapture), EnumAttr(WriteOnly))))
-__OMP_RTL_ATTRS(omp_get_thread_limit, GetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(__kmpc_barrier, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_barrier_simple_spmd, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_warp_active_thread_mask, BarrierAttrs, AttributeSet(),
+ ParamAttrs())
+__OMP_RTL_ATTRS(__kmpc_syncwarp, BarrierAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(__kmpc_cancel, InaccessibleArgOnlyAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_cancel_barrier, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_flush, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_global_thread_num, GetterAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_fork_call, ForkAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_omp_taskwait, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_omp_taskyield, InaccessibleArgOnlyAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_push_num_threads, InaccessibleArgOnlyAttrs,
+ AttributeSet(), ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_push_proc_bind, InaccessibleArgOnlyAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_serialized_parallel, InaccessibleArgOnlyAttrs,
+ AttributeSet(), ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_end_serialized_parallel, InaccessibleArgOnlyAttrs,
+ AttributeSet(), ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_omp_reg_task_with_affinity, DefaultAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ReadOnlyPtrAttrs,
+ AttributeSet(), ReadOnlyPtrAttrs))
+
+__OMP_RTL_ATTRS(omp_get_thread_num, GetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(omp_get_num_threads, GetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(omp_get_max_threads, GetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(omp_in_parallel, GetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(omp_get_dynamic, GetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(omp_get_cancellation, GetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(omp_get_nested, GetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(
+ omp_get_schedule, GetterArgWriteAttrs, AttributeSet(),
+ ParamAttrs(AttributeSet(EnumAttr(NoCapture), EnumAttr(WriteOnly)),
+ AttributeSet(EnumAttr(NoCapture), EnumAttr(WriteOnly))))
+__OMP_RTL_ATTRS(omp_get_thread_limit, GetterAttrs, AttributeSet(), ParamAttrs())
__OMP_RTL_ATTRS(omp_get_supported_active_levels, GetterAttrs, AttributeSet(),
- ParamAttrs())
-__OMP_RTL_ATTRS(omp_get_max_active_levels, GetterAttrs, AttributeSet(),
- ParamAttrs())
-__OMP_RTL_ATTRS(omp_get_level, GetterAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(omp_get_ancestor_thread_num, GetterAttrs, AttributeSet(),
- ParamAttrs())
-__OMP_RTL_ATTRS(omp_get_team_size, GetterAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(omp_get_active_level, GetterAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(omp_in_final, GetterAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(omp_get_proc_bind, GetterAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(omp_get_num_places, GetterAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(omp_get_num_procs, GetterAttrs, AttributeSet(), ParamAttrs())
+ ParamAttrs())
+__OMP_RTL_ATTRS(omp_get_max_active_levels, GetterAttrs, AttributeSet(),
+ ParamAttrs())
+__OMP_RTL_ATTRS(omp_get_level, GetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(omp_get_ancestor_thread_num, GetterAttrs, AttributeSet(),
+ ParamAttrs())
+__OMP_RTL_ATTRS(omp_get_team_size, GetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(omp_get_active_level, GetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(omp_in_final, GetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(omp_get_proc_bind, GetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(omp_get_num_places, GetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(omp_get_num_procs, GetterAttrs, AttributeSet(), ParamAttrs())
__OMP_RTL_ATTRS(omp_get_place_proc_ids, GetterArgWriteAttrs, AttributeSet(),
- ParamAttrs(AttributeSet(), AttributeSet(EnumAttr(NoCapture),
- EnumAttr(WriteOnly))))
-__OMP_RTL_ATTRS(omp_get_place_num, GetterAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(omp_get_partition_num_places, GetterAttrs, AttributeSet(),
- ParamAttrs())
-__OMP_RTL_ATTRS(omp_get_partition_place_nums, GetterAttrs, AttributeSet(),
- ParamAttrs())
-
-__OMP_RTL_ATTRS(omp_set_num_threads, SetterAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(omp_set_dynamic, SetterAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(omp_set_nested, SetterAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(omp_set_schedule, SetterAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(omp_set_max_active_levels, SetterAttrs, AttributeSet(),
- ParamAttrs())
-
-__OMP_RTL_ATTRS(__kmpc_master, InaccessibleArgOnlyAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_end_master, InaccessibleArgOnlyAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_critical, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet()))
-__OMP_RTL_ATTRS(__kmpc_critical_with_hint, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- AttributeSet()))
-__OMP_RTL_ATTRS(__kmpc_end_critical, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet()))
-
-__OMP_RTL_ATTRS(__kmpc_begin, DefaultAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_end, DefaultAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-
-__OMP_RTL_ATTRS(__kmpc_reduce, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- AttributeSet(), ReadOnlyPtrAttrs, AttributeSet()))
-__OMP_RTL_ATTRS(__kmpc_reduce_nowait, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- AttributeSet(), ReadOnlyPtrAttrs, AttributeSet()))
-__OMP_RTL_ATTRS(__kmpc_end_reduce, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet()))
-__OMP_RTL_ATTRS(__kmpc_end_reduce_nowait, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet()))
-
-__OMP_RTL_ATTRS(__kmpc_ordered, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_end_ordered, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-
-__OMP_RTL_ATTRS(__kmpc_for_static_init_4, GetterArgWriteAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs,
- AttributeSet(), AttributeSet()))
-__OMP_RTL_ATTRS(__kmpc_for_static_init_4u, GetterArgWriteAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs,
- AttributeSet(), AttributeSet()))
-__OMP_RTL_ATTRS(__kmpc_for_static_init_8, GetterArgWriteAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs,
- AttributeSet(), AttributeSet()))
-__OMP_RTL_ATTRS(__kmpc_for_static_init_8u, GetterArgWriteAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs,
- AttributeSet(), AttributeSet()))
-__OMP_RTL_ATTRS(__kmpc_for_static_fini, InaccessibleArgOnlyAttrs,
- AttributeSet(), ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dist_dispatch_init_4, GetterArgWriteAttrs,
- AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- ArgPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dist_dispatch_init_4u, GetterArgWriteAttrs,
- AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- ArgPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dist_dispatch_init_8, GetterArgWriteAttrs,
- AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- ArgPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dist_dispatch_init_8u, GetterArgWriteAttrs,
- AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- ArgPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dispatch_init_4, GetterArgWriteAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dispatch_init_4u, GetterArgWriteAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dispatch_init_8, GetterArgWriteAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dispatch_init_8u, GetterArgWriteAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dispatch_next_4, GetterArgWriteAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ArgPtrAttrs,
- ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dispatch_next_4u, GetterArgWriteAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ArgPtrAttrs,
- ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dispatch_next_8, GetterArgWriteAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ArgPtrAttrs,
- ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dispatch_next_8u, GetterArgWriteAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ArgPtrAttrs,
- ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dispatch_fini_4, InaccessibleArgOnlyAttrs,
- AttributeSet(), ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dispatch_fini_4u, InaccessibleArgOnlyAttrs,
- AttributeSet(), ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dispatch_fini_8, InaccessibleArgOnlyAttrs,
- AttributeSet(), ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dispatch_fini_8u, InaccessibleArgOnlyAttrs,
- AttributeSet(), ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_team_static_init_4, GetterArgWriteAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ArgPtrAttrs,
- ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_team_static_init_4u, GetterArgWriteAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ArgPtrAttrs,
- ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_team_static_init_8, GetterArgWriteAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ArgPtrAttrs,
- ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_team_static_init_8u, GetterArgWriteAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ArgPtrAttrs,
- ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dist_for_static_init_4, GetterArgWriteAttrs,
- AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs,
- ArgPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dist_for_static_init_4u, GetterArgWriteAttrs,
- AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs,
- ArgPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dist_for_static_init_8, GetterArgWriteAttrs,
- AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs,
- ArgPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_dist_for_static_init_8u, GetterArgWriteAttrs,
- AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs,
- ArgPtrAttrs))
-
-__OMP_RTL_ATTRS(__kmpc_single, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_end_single, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-
-__OMP_RTL_ATTRS(__kmpc_omp_task_alloc, DefaultAttrs, ReturnPtrAttrs,
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- AttributeSet(), AttributeSet(), ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_omp_task, DefaultAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet()))
-__OMP_RTL_ATTRS(__kmpc_end_taskgroup, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_taskgroup, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_omp_task_begin_if0, DefaultAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_omp_task_complete_if0, DefaultAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_omp_task_with_deps, DefaultAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- AttributeSet(), ReadOnlyPtrAttrs, AttributeSet(),
- ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_taskloop, DefaultAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- AttributeSet(), ArgPtrAttrs, ArgPtrAttrs,
- AttributeSet(), AttributeSet(), AttributeSet(),
- AttributeSet(), AttributeSet()))
-__OMP_RTL_ATTRS(__kmpc_omp_target_task_alloc, DefaultAttrs, ReturnPtrAttrs,
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- AttributeSet(), AttributeSet(), ReadOnlyPtrAttrs,
- AttributeSet()))
-__OMP_RTL_ATTRS(__kmpc_taskred_modifier_init, DefaultAttrs, ReturnPtrAttrs,
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_taskred_init, DefaultAttrs, AttributeSet(), ParamAttrs())
-__OMP_RTL_ATTRS(__kmpc_task_reduction_modifier_fini, BarrierAttrs,
- AttributeSet(), ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_task_reduction_get_th_data, DefaultAttrs, ReturnPtrAttrs,
- ParamAttrs())
-__OMP_RTL_ATTRS(__kmpc_task_reduction_init, DefaultAttrs, ReturnPtrAttrs,
- ParamAttrs())
-__OMP_RTL_ATTRS(__kmpc_task_reduction_modifier_init, DefaultAttrs,
- ReturnPtrAttrs, ParamAttrs())
-__OMP_RTL_ATTRS(__kmpc_proxy_task_completed_ooo, DefaultAttrs, AttributeSet(),
- ParamAttrs())
-
-__OMP_RTL_ATTRS(__kmpc_omp_wait_deps, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_cancellationpoint, DefaultAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-
-__OMP_RTL_ATTRS(__kmpc_fork_teams, ForkAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_push_num_teams, InaccessibleArgOnlyAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-
-__OMP_RTL_ATTRS(__kmpc_copyprivate, DefaultAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
- ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_threadprivate_cached, DefaultAttrs, ReturnPtrAttrs,
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_threadprivate_register, DefaultAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ReadOnlyPtrAttrs,
- ReadOnlyPtrAttrs, ReadOnlyPtrAttrs))
-
-__OMP_RTL_ATTRS(__kmpc_doacross_init, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_doacross_post, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_doacross_wait, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ReadOnlyPtrAttrs))
-__OMP_RTL_ATTRS(__kmpc_doacross_fini, BarrierAttrs, AttributeSet(),
- ParamAttrs(ReadOnlyPtrAttrs))
-
-__OMP_RTL_ATTRS(__kmpc_alloc, DefaultAttrs, ReturnPtrAttrs, {})
-__OMP_RTL_ATTRS(__kmpc_free, AllocAttrs, AttributeSet(), {})
-
-__OMP_RTL_ATTRS(__kmpc_init_allocator, DefaultAttrs, ReturnPtrAttrs, {})
-__OMP_RTL_ATTRS(__kmpc_destroy_allocator, AllocAttrs, AttributeSet(), {})
-
-__OMP_RTL_ATTRS(__kmpc_push_target_tripcount_mapper, SetterAttrs, AttributeSet(), {})
-__OMP_RTL_ATTRS(__tgt_target_mapper, ForkAttrs, AttributeSet(), {})
-__OMP_RTL_ATTRS(__tgt_target_nowait_mapper, ForkAttrs, AttributeSet(), {})
-__OMP_RTL_ATTRS(__tgt_target_teams_mapper, ForkAttrs, AttributeSet(), {})
-__OMP_RTL_ATTRS(__tgt_target_teams_nowait_mapper, ForkAttrs, AttributeSet(), {})
-__OMP_RTL_ATTRS(__tgt_register_requires, ForkAttrs, AttributeSet(), {})
-__OMP_RTL_ATTRS(__tgt_target_data_begin_mapper, ForkAttrs, AttributeSet(), {})
-__OMP_RTL_ATTRS(__tgt_target_data_begin_nowait_mapper, ForkAttrs,
- AttributeSet(), {})
-__OMP_RTL_ATTRS(__tgt_target_data_end_mapper, ForkAttrs, AttributeSet(), {})
-__OMP_RTL_ATTRS(__tgt_target_data_end_nowait_mapper, ForkAttrs,
- AttributeSet(), {})
-__OMP_RTL_ATTRS(__tgt_target_data_update_mapper, ForkAttrs, AttributeSet(), {})
-__OMP_RTL_ATTRS(__tgt_target_data_update_nowait_mapper, ForkAttrs,
- AttributeSet(), {})
-__OMP_RTL_ATTRS(__tgt_mapper_num_components, ForkAttrs, AttributeSet(), {})
-__OMP_RTL_ATTRS(__tgt_push_mapper_component, ForkAttrs, AttributeSet(), {})
-__OMP_RTL_ATTRS(__kmpc_task_allow_completion_event, DefaultAttrs,
- ReturnPtrAttrs, ParamAttrs(ReadOnlyPtrAttrs))
+ ParamAttrs(AttributeSet(), AttributeSet(EnumAttr(NoCapture),
+ EnumAttr(WriteOnly))))
+__OMP_RTL_ATTRS(omp_get_place_num, GetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(omp_get_partition_num_places, GetterAttrs, AttributeSet(),
+ ParamAttrs())
+__OMP_RTL_ATTRS(omp_get_partition_place_nums, GetterAttrs, AttributeSet(),
+ ParamAttrs())
+
+__OMP_RTL_ATTRS(omp_set_num_threads, SetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(omp_set_dynamic, SetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(omp_set_nested, SetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(omp_set_schedule, SetterAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(omp_set_max_active_levels, SetterAttrs, AttributeSet(),
+ ParamAttrs())
+
+__OMP_RTL_ATTRS(__kmpc_master, InaccessibleArgOnlyAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_end_master, InaccessibleArgOnlyAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_critical, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet()))
+__OMP_RTL_ATTRS(__kmpc_critical_with_hint, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ AttributeSet()))
+__OMP_RTL_ATTRS(__kmpc_end_critical, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet()))
+
+__OMP_RTL_ATTRS(__kmpc_begin, DefaultAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_end, DefaultAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+
+__OMP_RTL_ATTRS(__kmpc_reduce, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ AttributeSet(), ReadOnlyPtrAttrs, AttributeSet()))
+__OMP_RTL_ATTRS(__kmpc_reduce_nowait, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ AttributeSet(), ReadOnlyPtrAttrs, AttributeSet()))
+__OMP_RTL_ATTRS(__kmpc_end_reduce, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet()))
+__OMP_RTL_ATTRS(__kmpc_end_reduce_nowait, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet()))
+
+__OMP_RTL_ATTRS(__kmpc_ordered, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_end_ordered, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+
+__OMP_RTL_ATTRS(__kmpc_for_static_init_4, GetterArgWriteAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs,
+ AttributeSet(), AttributeSet()))
+__OMP_RTL_ATTRS(__kmpc_for_static_init_4u, GetterArgWriteAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs,
+ AttributeSet(), AttributeSet()))
+__OMP_RTL_ATTRS(__kmpc_for_static_init_8, GetterArgWriteAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs,
+ AttributeSet(), AttributeSet()))
+__OMP_RTL_ATTRS(__kmpc_for_static_init_8u, GetterArgWriteAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs,
+ AttributeSet(), AttributeSet()))
+__OMP_RTL_ATTRS(__kmpc_for_static_fini, InaccessibleArgOnlyAttrs,
+ AttributeSet(), ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dist_dispatch_init_4, GetterArgWriteAttrs,
+ AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ ArgPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dist_dispatch_init_4u, GetterArgWriteAttrs,
+ AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ ArgPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dist_dispatch_init_8, GetterArgWriteAttrs,
+ AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ ArgPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dist_dispatch_init_8u, GetterArgWriteAttrs,
+ AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ ArgPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dispatch_init_4, GetterArgWriteAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dispatch_init_4u, GetterArgWriteAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dispatch_init_8, GetterArgWriteAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dispatch_init_8u, GetterArgWriteAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dispatch_next_4, GetterArgWriteAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ArgPtrAttrs,
+ ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dispatch_next_4u, GetterArgWriteAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ArgPtrAttrs,
+ ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dispatch_next_8, GetterArgWriteAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ArgPtrAttrs,
+ ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dispatch_next_8u, GetterArgWriteAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ArgPtrAttrs,
+ ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dispatch_fini_4, InaccessibleArgOnlyAttrs,
+ AttributeSet(), ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dispatch_fini_4u, InaccessibleArgOnlyAttrs,
+ AttributeSet(), ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dispatch_fini_8, InaccessibleArgOnlyAttrs,
+ AttributeSet(), ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dispatch_fini_8u, InaccessibleArgOnlyAttrs,
+ AttributeSet(), ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_team_static_init_4, GetterArgWriteAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ArgPtrAttrs,
+ ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_team_static_init_4u, GetterArgWriteAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ArgPtrAttrs,
+ ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_team_static_init_8, GetterArgWriteAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ArgPtrAttrs,
+ ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_team_static_init_8u, GetterArgWriteAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ArgPtrAttrs,
+ ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dist_for_static_init_4, GetterArgWriteAttrs,
+ AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs,
+ ArgPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dist_for_static_init_4u, GetterArgWriteAttrs,
+ AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs,
+ ArgPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dist_for_static_init_8, GetterArgWriteAttrs,
+ AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs,
+ ArgPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_dist_for_static_init_8u, GetterArgWriteAttrs,
+ AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs, ArgPtrAttrs,
+ ArgPtrAttrs))
+
+__OMP_RTL_ATTRS(__kmpc_single, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_end_single, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+
+__OMP_RTL_ATTRS(__kmpc_omp_task_alloc, DefaultAttrs, ReturnPtrAttrs,
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ AttributeSet(), AttributeSet(), ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_omp_task, DefaultAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet()))
+__OMP_RTL_ATTRS(__kmpc_end_taskgroup, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_taskgroup, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_omp_task_begin_if0, DefaultAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_omp_task_complete_if0, DefaultAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_omp_task_with_deps, DefaultAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ AttributeSet(), ReadOnlyPtrAttrs, AttributeSet(),
+ ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_taskloop, DefaultAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ AttributeSet(), ArgPtrAttrs, ArgPtrAttrs,
+ AttributeSet(), AttributeSet(), AttributeSet(),
+ AttributeSet(), AttributeSet()))
+__OMP_RTL_ATTRS(__kmpc_omp_target_task_alloc, DefaultAttrs, ReturnPtrAttrs,
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ AttributeSet(), AttributeSet(), ReadOnlyPtrAttrs,
+ AttributeSet()))
+__OMP_RTL_ATTRS(__kmpc_taskred_modifier_init, DefaultAttrs, ReturnPtrAttrs,
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_taskred_init, DefaultAttrs, AttributeSet(), ParamAttrs())
+__OMP_RTL_ATTRS(__kmpc_task_reduction_modifier_fini, BarrierAttrs,
+ AttributeSet(), ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_task_reduction_get_th_data, DefaultAttrs, ReturnPtrAttrs,
+ ParamAttrs())
+__OMP_RTL_ATTRS(__kmpc_task_reduction_init, DefaultAttrs, ReturnPtrAttrs,
+ ParamAttrs())
+__OMP_RTL_ATTRS(__kmpc_task_reduction_modifier_init, DefaultAttrs,
+ ReturnPtrAttrs, ParamAttrs())
+__OMP_RTL_ATTRS(__kmpc_proxy_task_completed_ooo, DefaultAttrs, AttributeSet(),
+ ParamAttrs())
+
+__OMP_RTL_ATTRS(__kmpc_omp_wait_deps, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_cancellationpoint, DefaultAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+
+__OMP_RTL_ATTRS(__kmpc_fork_teams, ForkAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_push_num_teams, InaccessibleArgOnlyAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+
+__OMP_RTL_ATTRS(__kmpc_copyprivate, DefaultAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), AttributeSet(),
+ ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_threadprivate_cached, DefaultAttrs, ReturnPtrAttrs,
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_threadprivate_register, DefaultAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ReadOnlyPtrAttrs,
+ ReadOnlyPtrAttrs, ReadOnlyPtrAttrs))
+
+__OMP_RTL_ATTRS(__kmpc_doacross_init, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_doacross_post, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_doacross_wait, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs, AttributeSet(), ReadOnlyPtrAttrs))
+__OMP_RTL_ATTRS(__kmpc_doacross_fini, BarrierAttrs, AttributeSet(),
+ ParamAttrs(ReadOnlyPtrAttrs))
+
+__OMP_RTL_ATTRS(__kmpc_alloc, DefaultAttrs, ReturnPtrAttrs, {})
+__OMP_RTL_ATTRS(__kmpc_free, AllocAttrs, AttributeSet(), {})
+
+__OMP_RTL_ATTRS(__kmpc_init_allocator, DefaultAttrs, ReturnPtrAttrs, {})
+__OMP_RTL_ATTRS(__kmpc_destroy_allocator, AllocAttrs, AttributeSet(), {})
+
+__OMP_RTL_ATTRS(__kmpc_push_target_tripcount_mapper, SetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_mapper, ForkAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_nowait_mapper, ForkAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_teams_mapper, ForkAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_teams_nowait_mapper, ForkAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_register_requires, ForkAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_data_begin_mapper, ForkAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_data_begin_nowait_mapper, ForkAttrs,
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_data_end_mapper, ForkAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_data_end_nowait_mapper, ForkAttrs,
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_data_update_mapper, ForkAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_data_update_nowait_mapper, ForkAttrs,
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_mapper_num_components, ForkAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_push_mapper_component, ForkAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_task_allow_completion_event, DefaultAttrs,
+ ReturnPtrAttrs, ParamAttrs(ReadOnlyPtrAttrs))
#undef __OMP_RTL_ATTRS
#undef OMP_RTL_ATTRS
#undef AttributeSet
#undef EnumAttr
-#undef EnumAttrInt
-#undef ParamAttrs
+#undef EnumAttrInt
+#undef ParamAttrs
///}
@@ -1025,7 +1025,7 @@ __OMP_TRAIT_PROPERTY(device, arch, aarch64)
__OMP_TRAIT_PROPERTY(device, arch, aarch64_be)
__OMP_TRAIT_PROPERTY(device, arch, aarch64_32)
__OMP_TRAIT_PROPERTY(device, arch, ppc)
-__OMP_TRAIT_PROPERTY(device, arch, ppcle)
+__OMP_TRAIT_PROPERTY(device, arch, ppcle)
__OMP_TRAIT_PROPERTY(device, arch, ppc64)
__OMP_TRAIT_PROPERTY(device, arch, ppc64le)
__OMP_TRAIT_PROPERTY(device, arch, x86)
@@ -1055,8 +1055,8 @@ __OMP_TRAIT_SELECTOR(implementation, extension, true)
__OMP_TRAIT_PROPERTY(implementation, extension, match_all)
__OMP_TRAIT_PROPERTY(implementation, extension, match_any)
__OMP_TRAIT_PROPERTY(implementation, extension, match_none)
-__OMP_TRAIT_PROPERTY(implementation, extension, disable_implicit_base)
-__OMP_TRAIT_PROPERTY(implementation, extension, allow_templates)
+__OMP_TRAIT_PROPERTY(implementation, extension, disable_implicit_base)
+__OMP_TRAIT_PROPERTY(implementation, extension, allow_templates)
__OMP_TRAIT_SET(user)
@@ -1066,18 +1066,18 @@ __OMP_TRAIT_PROPERTY(user, condition, true)
__OMP_TRAIT_PROPERTY(user, condition, false)
__OMP_TRAIT_PROPERTY(user, condition, unknown)
-
-// Note that we put isa last so that the other conditions are checked first.
-// This allows us to issue warnings wrt. isa only if we match otherwise.
-__OMP_TRAIT_SELECTOR(device, isa, true)
-
-// We use "__ANY" as a placeholder in the isa property to denote the
-// conceptual "any", not the literal `any` used in kind. The string we
-// we use is not important except that it will show up in diagnostics.
-OMP_TRAIT_PROPERTY(device_isa___ANY, device, device_isa,
- "<any, entirely target dependent>")
-
-
+
+// Note that we put isa last so that the other conditions are checked first.
+// This allows us to issue warnings wrt. isa only if we match otherwise.
+__OMP_TRAIT_SELECTOR(device, isa, true)
+
+// We use "__ANY" as a placeholder in the isa property to denote the
+// conceptual "any", not the literal `any` used in kind. The string we
+// we use is not important except that it will show up in diagnostics.
+OMP_TRAIT_PROPERTY(device_isa___ANY, device, device_isa,
+ "<any, entirely target dependent>")
+
+
#undef OMP_TRAIT_SET
#undef __OMP_TRAIT_SET
///}
@@ -1115,27 +1115,27 @@ OMP_LAST_TRAIT_PROPERTY(
#undef __OMP_REQUIRES_TRAIT
#undef OMP_REQUIRES_TRAIT
///}
-
-
-/// Assumption clauses
-///
-///{
-
-#ifdef OMP_ASSUME_CLAUSE
-#define __OMP_ASSUME_CLAUSE(Identifier, StartsWith, HasDirectiveList, HasExpression) \
-OMP_ASSUME_CLAUSE(Identifier, StartsWith, HasDirectiveList, HasExpression)
-#else
-#define __OMP_ASSUME_CLAUSE(...)
-#endif
-
-__OMP_ASSUME_CLAUSE(llvm::StringLiteral("ext_"), true, false, false)
-__OMP_ASSUME_CLAUSE(llvm::StringLiteral("absent"), false, true, false)
-__OMP_ASSUME_CLAUSE(llvm::StringLiteral("contains"), false, true, false)
-__OMP_ASSUME_CLAUSE(llvm::StringLiteral("holds"), false, false, true)
-__OMP_ASSUME_CLAUSE(llvm::StringLiteral("no_openmp"), false, false, false)
-__OMP_ASSUME_CLAUSE(llvm::StringLiteral("no_openmp_routines"), false, false, false)
-__OMP_ASSUME_CLAUSE(llvm::StringLiteral("no_parallelism"), false, false, false)
-
-#undef __OMP_ASSUME_CLAUSE
-#undef OMP_ASSUME_CLAUSE
-///}
+
+
+/// Assumption clauses
+///
+///{
+
+#ifdef OMP_ASSUME_CLAUSE
+#define __OMP_ASSUME_CLAUSE(Identifier, StartsWith, HasDirectiveList, HasExpression) \
+OMP_ASSUME_CLAUSE(Identifier, StartsWith, HasDirectiveList, HasExpression)
+#else
+#define __OMP_ASSUME_CLAUSE(...)
+#endif
+
+__OMP_ASSUME_CLAUSE(llvm::StringLiteral("ext_"), true, false, false)
+__OMP_ASSUME_CLAUSE(llvm::StringLiteral("absent"), false, true, false)
+__OMP_ASSUME_CLAUSE(llvm::StringLiteral("contains"), false, true, false)
+__OMP_ASSUME_CLAUSE(llvm::StringLiteral("holds"), false, false, true)
+__OMP_ASSUME_CLAUSE(llvm::StringLiteral("no_openmp"), false, false, false)
+__OMP_ASSUME_CLAUSE(llvm::StringLiteral("no_openmp_routines"), false, false, false)
+__OMP_ASSUME_CLAUSE(llvm::StringLiteral("no_parallelism"), false, false, false)
+
+#undef __OMP_ASSUME_CLAUSE
+#undef OMP_ASSUME_CLAUSE
+///}
diff --git a/contrib/libs/llvm12/include/llvm/FuzzMutate/IRMutator.h b/contrib/libs/llvm12/include/llvm/FuzzMutate/IRMutator.h
index 504097e7b8..48bf5f18a5 100644
--- a/contrib/libs/llvm12/include/llvm/FuzzMutate/IRMutator.h
+++ b/contrib/libs/llvm12/include/llvm/FuzzMutate/IRMutator.h
@@ -109,17 +109,17 @@ public:
void mutate(Instruction &Inst, RandomIRBuilder &IB) override;
};
-class InstModificationIRStrategy : public IRMutationStrategy {
-public:
- uint64_t getWeight(size_t CurrentSize, size_t MaxSize,
- uint64_t CurrentWeight) override {
- return 4;
- }
-
- using IRMutationStrategy::mutate;
- void mutate(Instruction &Inst, RandomIRBuilder &IB) override;
-};
-
+class InstModificationIRStrategy : public IRMutationStrategy {
+public:
+ uint64_t getWeight(size_t CurrentSize, size_t MaxSize,
+ uint64_t CurrentWeight) override {
+ return 4;
+ }
+
+ using IRMutationStrategy::mutate;
+ void mutate(Instruction &Inst, RandomIRBuilder &IB) override;
+};
+
} // end llvm namespace
#endif // LLVM_FUZZMUTATE_IRMUTATOR_H
diff --git a/contrib/libs/llvm12/include/llvm/IR/Argument.h b/contrib/libs/llvm12/include/llvm/IR/Argument.h
index 6bf6d58a00..d555c67051 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Argument.h
+++ b/contrib/libs/llvm12/include/llvm/IR/Argument.h
@@ -59,9 +59,9 @@ public:
/// Return true if this argument has the nonnull attribute. Also returns true
/// if at least one byte is known to be dereferenceable and the pointer is in
/// addrspace(0).
- /// If AllowUndefOrPoison is true, respect the semantics of nonnull attribute
- /// and return true even if the argument can be undef or poison.
- bool hasNonNullAttr(bool AllowUndefOrPoison = true) const;
+ /// If AllowUndefOrPoison is true, respect the semantics of nonnull attribute
+ /// and return true even if the argument can be undef or poison.
+ bool hasNonNullAttr(bool AllowUndefOrPoison = true) const;
/// If this argument has the dereferenceable attribute, return the number of
/// bytes known to be dereferenceable. Otherwise, zero is returned.
@@ -74,9 +74,9 @@ public:
/// Return true if this argument has the byval attribute.
bool hasByValAttr() const;
- /// Return true if this argument has the byref attribute.
- bool hasByRefAttr() const;
-
+ /// Return true if this argument has the byref attribute.
+ bool hasByRefAttr() const;
+
/// Return true if this argument has the swiftself attribute.
bool hasSwiftSelfAttr() const;
@@ -84,23 +84,23 @@ public:
bool hasSwiftErrorAttr() const;
/// Return true if this argument has the byval, inalloca, or preallocated
- /// attribute. These attributes represent arguments being passed by value,
- /// with an associated copy between the caller and callee
- bool hasPassPointeeByValueCopyAttr() const;
+ /// attribute. These attributes represent arguments being passed by value,
+ /// with an associated copy between the caller and callee
+ bool hasPassPointeeByValueCopyAttr() const;
/// If this argument satisfies has hasPassPointeeByValueAttr, return the
/// in-memory ABI size copied to the stack for the call. Otherwise, return 0.
uint64_t getPassPointeeByValueCopySize(const DataLayout &DL) const;
- /// Return true if this argument has the byval, sret, inalloca, preallocated,
- /// or byref attribute. These attributes represent arguments being passed by
- /// value (which may or may not involve a stack copy)
- bool hasPointeeInMemoryValueAttr() const;
-
- /// If hasPointeeInMemoryValueAttr returns true, the in-memory ABI type is
- /// returned. Otherwise, nullptr.
- Type *getPointeeInMemoryValueType() const;
-
+ /// Return true if this argument has the byval, sret, inalloca, preallocated,
+ /// or byref attribute. These attributes represent arguments being passed by
+ /// value (which may or may not involve a stack copy)
+ bool hasPointeeInMemoryValueAttr() const;
+
+ /// If hasPointeeInMemoryValueAttr returns true, the in-memory ABI type is
+ /// returned. Otherwise, nullptr.
+ Type *getPointeeInMemoryValueType() const;
+
/// If this is a byval or inalloca argument, return its alignment.
/// FIXME: Remove this function once transition to Align is over.
/// Use getParamAlign() instead.
@@ -112,12 +112,12 @@ public:
/// If this is a byval argument, return its type.
Type *getParamByValType() const;
- /// If this is an sret argument, return its type.
- Type *getParamStructRetType() const;
-
- /// If this is a byref argument, return its type.
- Type *getParamByRefType() const;
-
+ /// If this is an sret argument, return its type.
+ Type *getParamStructRetType() const;
+
+ /// If this is a byref argument, return its type.
+ Type *getParamByRefType() const;
+
/// Return true if this argument has the nest attribute.
bool hasNestAttr() const;
diff --git a/contrib/libs/llvm12/include/llvm/IR/Assumptions.h b/contrib/libs/llvm12/include/llvm/IR/Assumptions.h
index aa08402473..01729f36e0 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Assumptions.h
+++ b/contrib/libs/llvm12/include/llvm/IR/Assumptions.h
@@ -1,61 +1,61 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===--- Assumptions.h - Assumption handling and organization ---*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// String assumptions that are known to optimization passes should be placed in
-// the KnownAssumptionStrings set. This can be done in various ways, i.a.,
-// via a static KnownAssumptionString object.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_IR_ASSUMPTIONS_H
-#define LLVM_IR_ASSUMPTIONS_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSet.h"
-
-namespace llvm {
-
-class Function;
-
-/// The key we use for assumption attributes.
-constexpr StringRef AssumptionAttrKey = "llvm.assume";
-
-/// A set of known assumption strings that are accepted without warning and
-/// which can be recommended as typo correction.
-extern StringSet<> KnownAssumptionStrings;
-
-/// Helper that allows to insert a new assumption string in the known assumption
-/// set by creating a (static) object.
-struct KnownAssumptionString {
- KnownAssumptionString(StringRef AssumptionStr)
- : AssumptionStr(AssumptionStr) {
- KnownAssumptionStrings.insert(AssumptionStr);
- }
- operator StringRef() const { return AssumptionStr; }
-
-private:
- StringRef AssumptionStr;
-};
-
-/// Return true if \p F has the assumption \p AssumptionStr attached.
-bool hasAssumption(Function &F, const KnownAssumptionString &AssumptionStr);
-
-} // namespace llvm
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===--- Assumptions.h - Assumption handling and organization ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// String assumptions that are known to optimization passes should be placed in
+// the KnownAssumptionStrings set. This can be done in various ways, i.a.,
+// via a static KnownAssumptionString object.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_ASSUMPTIONS_H
+#define LLVM_IR_ASSUMPTIONS_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
+
+namespace llvm {
+
+class Function;
+
+/// The key we use for assumption attributes.
+constexpr StringRef AssumptionAttrKey = "llvm.assume";
+
+/// A set of known assumption strings that are accepted without warning and
+/// which can be recommended as typo correction.
+extern StringSet<> KnownAssumptionStrings;
+
+/// Helper that allows to insert a new assumption string in the known assumption
+/// set by creating a (static) object.
+struct KnownAssumptionString {
+ KnownAssumptionString(StringRef AssumptionStr)
+ : AssumptionStr(AssumptionStr) {
+ KnownAssumptionStrings.insert(AssumptionStr);
+ }
+ operator StringRef() const { return AssumptionStr; }
+
+private:
+ StringRef AssumptionStr;
+};
+
+/// Return true if \p F has the assumption \p AssumptionStr attached.
+bool hasAssumption(Function &F, const KnownAssumptionString &AssumptionStr);
+
+} // namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/IR/Attributes.h b/contrib/libs/llvm12/include/llvm/IR/Attributes.h
index 75510c5195..f45741edc2 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Attributes.h
+++ b/contrib/libs/llvm12/include/llvm/IR/Attributes.h
@@ -115,17 +115,17 @@ public:
unsigned ElemSizeArg,
const Optional<unsigned> &NumElemsArg);
static Attribute getWithByValType(LLVMContext &Context, Type *Ty);
- static Attribute getWithStructRetType(LLVMContext &Context, Type *Ty);
- static Attribute getWithByRefType(LLVMContext &Context, Type *Ty);
+ static Attribute getWithStructRetType(LLVMContext &Context, Type *Ty);
+ static Attribute getWithByRefType(LLVMContext &Context, Type *Ty);
static Attribute getWithPreallocatedType(LLVMContext &Context, Type *Ty);
- /// For a typed attribute, return the equivalent attribute with the type
- /// changed to \p ReplacementTy.
- Attribute getWithNewType(LLVMContext &Context, Type *ReplacementTy) {
- assert(isTypeAttribute() && "this requires a typed attribute");
- return get(Context, getKindAsEnum(), ReplacementTy);
- }
-
+ /// For a typed attribute, return the equivalent attribute with the type
+ /// changed to \p ReplacementTy.
+ Attribute getWithNewType(LLVMContext &Context, Type *ReplacementTy) {
+ assert(isTypeAttribute() && "this requires a typed attribute");
+ return get(Context, getKindAsEnum(), ReplacementTy);
+ }
+
static Attribute::AttrKind getAttrKindFromName(StringRef AttrName);
static StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind);
@@ -154,9 +154,9 @@ public:
/// Return true if the attribute is a type attribute.
bool isTypeAttribute() const;
- /// Return true if the attribute is any kind of attribute.
- bool isValid() const { return pImpl; }
-
+ /// Return true if the attribute is any kind of attribute.
+ bool isValid() const { return pImpl; }
+
/// Return true if the attribute is present.
bool hasAttribute(AttrKind Val) const;
@@ -322,8 +322,8 @@ public:
uint64_t getDereferenceableBytes() const;
uint64_t getDereferenceableOrNullBytes() const;
Type *getByValType() const;
- Type *getStructRetType() const;
- Type *getByRefType() const;
+ Type *getStructRetType() const;
+ Type *getByRefType() const;
Type *getPreallocatedType() const;
std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
std::string getAsString(bool InAttrGrp = false) const;
@@ -406,9 +406,9 @@ private:
static AttributeList getImpl(LLVMContext &C, ArrayRef<AttributeSet> AttrSets);
- AttributeList setAttributes(LLVMContext &C, unsigned Index,
- AttributeSet Attrs) const;
-
+ AttributeList setAttributes(LLVMContext &C, unsigned Index,
+ AttributeSet Attrs) const;
+
public:
AttributeList() = default;
@@ -527,17 +527,17 @@ public:
return removeAttributes(C, ArgNo + FirstArgIndex);
}
- /// Replace the type contained by attribute \p AttrKind at index \p ArgNo wih
- /// \p ReplacementTy, preserving all other attributes.
- LLVM_NODISCARD AttributeList replaceAttributeType(LLVMContext &C,
- unsigned ArgNo,
- Attribute::AttrKind Kind,
- Type *ReplacementTy) const {
- Attribute Attr = getAttribute(ArgNo, Kind);
- auto Attrs = removeAttribute(C, ArgNo, Kind);
- return Attrs.addAttribute(C, ArgNo, Attr.getWithNewType(C, ReplacementTy));
- }
-
+ /// Replace the type contained by attribute \p AttrKind at index \p ArgNo wih
+ /// \p ReplacementTy, preserving all other attributes.
+ LLVM_NODISCARD AttributeList replaceAttributeType(LLVMContext &C,
+ unsigned ArgNo,
+ Attribute::AttrKind Kind,
+ Type *ReplacementTy) const {
+ Attribute Attr = getAttribute(ArgNo, Kind);
+ auto Attrs = removeAttribute(C, ArgNo, Kind);
+ return Attrs.addAttribute(C, ArgNo, Attr.getWithNewType(C, ReplacementTy));
+ }
+
/// \brief Add the dereferenceable attribute to the attribute set at the given
/// index. Returns a new list because attribute lists are immutable.
LLVM_NODISCARD AttributeList addDereferenceableAttr(LLVMContext &C,
@@ -661,12 +661,12 @@ public:
/// Return the byval type for the specified function parameter.
Type *getParamByValType(unsigned ArgNo) const;
- /// Return the sret type for the specified function parameter.
- Type *getParamStructRetType(unsigned ArgNo) const;
-
- /// Return the byref type for the specified function parameter.
- Type *getParamByRefType(unsigned ArgNo) const;
-
+ /// Return the sret type for the specified function parameter.
+ Type *getParamStructRetType(unsigned ArgNo) const;
+
+ /// Return the byref type for the specified function parameter.
+ Type *getParamByRefType(unsigned ArgNo) const;
+
/// Return the preallocated type for the specified function parameter.
Type *getParamPreallocatedType(unsigned ArgNo) const;
@@ -770,8 +770,8 @@ class AttrBuilder {
uint64_t DerefOrNullBytes = 0;
uint64_t AllocSizeArgs = 0;
Type *ByValType = nullptr;
- Type *StructRetType = nullptr;
- Type *ByRefType = nullptr;
+ Type *StructRetType = nullptr;
+ Type *ByRefType = nullptr;
Type *PreallocatedType = nullptr;
public:
@@ -787,14 +787,14 @@ public:
void clear();
/// Add an attribute to the builder.
- AttrBuilder &addAttribute(Attribute::AttrKind Val) {
- assert((unsigned)Val < Attribute::EndAttrKinds &&
- "Attribute out of range!");
- assert(!Attribute::doesAttrKindHaveArgument(Val) &&
- "Adding integer attribute without adding a value!");
- Attrs[Val] = true;
- return *this;
- }
+ AttrBuilder &addAttribute(Attribute::AttrKind Val) {
+ assert((unsigned)Val < Attribute::EndAttrKinds &&
+ "Attribute out of range!");
+ assert(!Attribute::doesAttrKindHaveArgument(Val) &&
+ "Adding integer attribute without adding a value!");
+ Attrs[Val] = true;
+ return *this;
+ }
/// Add the Attribute object to the builder.
AttrBuilder &addAttribute(Attribute A);
@@ -858,12 +858,12 @@ public:
/// Retrieve the byval type.
Type *getByValType() const { return ByValType; }
- /// Retrieve the sret type.
- Type *getStructRetType() const { return StructRetType; }
-
- /// Retrieve the byref type.
- Type *getByRefType() const { return ByRefType; }
-
+ /// Retrieve the sret type.
+ Type *getStructRetType() const { return StructRetType; }
+
+ /// Retrieve the byref type.
+ Type *getByRefType() const { return ByRefType; }
+
/// Retrieve the preallocated type.
Type *getPreallocatedType() const { return PreallocatedType; }
@@ -910,12 +910,12 @@ public:
/// This turns a byval type into the form used internally in Attribute.
AttrBuilder &addByValAttr(Type *Ty);
- /// This turns a sret type into the form used internally in Attribute.
- AttrBuilder &addStructRetAttr(Type *Ty);
-
- /// This turns a byref type into the form used internally in Attribute.
- AttrBuilder &addByRefAttr(Type *Ty);
-
+ /// This turns a sret type into the form used internally in Attribute.
+ AttrBuilder &addStructRetAttr(Type *Ty);
+
+ /// This turns a byref type into the form used internally in Attribute.
+ AttrBuilder &addByRefAttr(Type *Ty);
+
/// This turns a preallocated type into the form used internally in Attribute.
AttrBuilder &addPreallocatedAttr(Type *Ty);
@@ -961,24 +961,24 @@ AttrBuilder typeIncompatible(Type *Ty);
/// attributes for inlining purposes.
bool areInlineCompatible(const Function &Caller, const Function &Callee);
-
-/// Checks if there are any incompatible function attributes between
-/// \p A and \p B.
-///
-/// \param [in] A - The first function to be compared with.
-/// \param [in] B - The second function to be compared with.
-/// \returns true if the functions have compatible attributes.
-bool areOutlineCompatible(const Function &A, const Function &B);
-
+
+/// Checks if there are any incompatible function attributes between
+/// \p A and \p B.
+///
+/// \param [in] A - The first function to be compared with.
+/// \param [in] B - The second function to be compared with.
+/// \returns true if the functions have compatible attributes.
+bool areOutlineCompatible(const Function &A, const Function &B);
+
/// Merge caller's and callee's attributes.
void mergeAttributesForInlining(Function &Caller, const Function &Callee);
-/// Merges the functions attributes from \p ToMerge into function \p Base.
-///
-/// \param [in,out] Base - The function being merged into.
-/// \param [in] ToMerge - The function to merge attributes from.
-void mergeAttributesForOutlining(Function &Base, const Function &ToMerge);
-
+/// Merges the functions attributes from \p ToMerge into function \p Base.
+///
+/// \param [in,out] Base - The function being merged into.
+/// \param [in] ToMerge - The function to merge attributes from.
+void mergeAttributesForOutlining(Function &Base, const Function &ToMerge);
+
} // end namespace AttributeFuncs
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/IR/Attributes.td b/contrib/libs/llvm12/include/llvm/IR/Attributes.td
index dc4840f848..f7ffc888c6 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Attributes.td
+++ b/contrib/libs/llvm12/include/llvm/IR/Attributes.td
@@ -1,15 +1,15 @@
-//===- Attributes.td - Defines all LLVM attributes ---------*- tablegen -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines all the LLVM attributes.
-//
-//===----------------------------------------------------------------------===//
-
+//===- Attributes.td - Defines all LLVM attributes ---------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all the LLVM attributes.
+//
+//===----------------------------------------------------------------------===//
+
/// Attribute base class.
class Attr<string S> {
// String representation of this attribute in the IR.
@@ -51,9 +51,9 @@ def Builtin : EnumAttr<"builtin">;
/// Pass structure by value.
def ByVal : TypeAttr<"byval">;
-/// Mark in-memory ABI type.
-def ByRef : TypeAttr<"byref">;
-
+/// Mark in-memory ABI type.
+def ByRef : TypeAttr<"byref">;
+
/// Parameter or return value may not contain uninitialized or poison bits.
def NoUndef : EnumAttr<"noundef">;
@@ -63,9 +63,9 @@ def Cold : EnumAttr<"cold">;
/// Can only be moved to control-equivalent blocks.
def Convergent : EnumAttr<"convergent">;
-/// Marks function as being in a hot path and frequently called.
-def Hot: EnumAttr<"hot">;
-
+/// Marks function as being in a hot path and frequently called.
+def Hot: EnumAttr<"hot">;
+
/// Pointer is known to be dereferenceable.
def Dereferenceable : IntAttr<"dereferenceable">;
@@ -106,9 +106,9 @@ def NoAlias : EnumAttr<"noalias">;
/// Callee isn't recognized as a builtin.
def NoBuiltin : EnumAttr<"nobuiltin">;
-/// Function cannot enter into caller's translation unit.
-def NoCallback : EnumAttr<"nocallback">;
-
+/// Function cannot enter into caller's translation unit.
+def NoCallback : EnumAttr<"nocallback">;
+
/// Function creates no aliases of pointer.
def NoCapture : EnumAttr<"nocapture">;
@@ -127,7 +127,7 @@ def NoInline : EnumAttr<"noinline">;
/// Function is called early and/or often, so lazy binding isn't worthwhile.
def NonLazyBind : EnumAttr<"nonlazybind">;
-/// Disable merging for specified functions or call sites.
+/// Disable merging for specified functions or call sites.
def NoMerge : EnumAttr<"nomerge">;
/// Pointer is known to be not null.
@@ -148,9 +148,9 @@ def NoSync : EnumAttr<"nosync">;
/// Disable Indirect Branch Tracking.
def NoCfCheck : EnumAttr<"nocf_check">;
-/// Function should be instrumented.
-def NoProfile : EnumAttr<"noprofile">;
-
+/// Function should be instrumented.
+def NoProfile : EnumAttr<"noprofile">;
+
/// Function doesn't unwind stack.
def NoUnwind : EnumAttr<"nounwind">;
@@ -213,7 +213,7 @@ def StackProtectStrong : EnumAttr<"sspstrong">;
def StrictFP : EnumAttr<"strictfp">;
/// Hidden pointer to structure to return.
-def StructRet : TypeAttr<"sret">;
+def StructRet : TypeAttr<"sret">;
/// AddressSanitizer is on.
def SanitizeAddress : EnumAttr<"sanitize_address">;
@@ -256,9 +256,9 @@ def WriteOnly : EnumAttr<"writeonly">;
/// Zero extended before/after call.
def ZExt : EnumAttr<"zeroext">;
-/// Function is required to make Forward Progress.
-def MustProgress : TypeAttr<"mustprogress">;
-
+/// Function is required to make Forward Progress.
+def MustProgress : TypeAttr<"mustprogress">;
+
/// Target-independent string attributes.
def LessPreciseFPMAD : StrBoolAttr<"less-precise-fpmad">;
def NoInfsFPMath : StrBoolAttr<"no-infs-fp-math">;
@@ -312,4 +312,4 @@ def : MergeRule<"adjustCallerStackProbes">;
def : MergeRule<"adjustCallerStackProbeSize">;
def : MergeRule<"adjustMinLegalVectorWidth">;
def : MergeRule<"adjustNullPointerValidAttr">;
-def : MergeRule<"setAND<MustProgressAttr>">;
+def : MergeRule<"setAND<MustProgressAttr>">;
diff --git a/contrib/libs/llvm12/include/llvm/IR/BasicBlock.h b/contrib/libs/llvm12/include/llvm/IR/BasicBlock.h
index b79477c0b3..4a8e282ec2 100644
--- a/contrib/libs/llvm12/include/llvm/IR/BasicBlock.h
+++ b/contrib/libs/llvm12/include/llvm/IR/BasicBlock.h
@@ -172,24 +172,24 @@ public:
}
/// Returns a pointer to the first instruction in this block that is not a
- /// PHINode or a debug intrinsic, or any pseudo operation if \c SkipPseudoOp
- /// is true.
- const Instruction *getFirstNonPHIOrDbg(bool SkipPseudoOp = false) const;
- Instruction *getFirstNonPHIOrDbg(bool SkipPseudoOp = false) {
+ /// PHINode or a debug intrinsic, or any pseudo operation if \c SkipPseudoOp
+ /// is true.
+ const Instruction *getFirstNonPHIOrDbg(bool SkipPseudoOp = false) const;
+ Instruction *getFirstNonPHIOrDbg(bool SkipPseudoOp = false) {
return const_cast<Instruction *>(
- static_cast<const BasicBlock *>(this)->getFirstNonPHIOrDbg(
- SkipPseudoOp));
+ static_cast<const BasicBlock *>(this)->getFirstNonPHIOrDbg(
+ SkipPseudoOp));
}
/// Returns a pointer to the first instruction in this block that is not a
- /// PHINode, a debug intrinsic, or a lifetime intrinsic, or any pseudo
- /// operation if \c SkipPseudoOp is true.
- const Instruction *
- getFirstNonPHIOrDbgOrLifetime(bool SkipPseudoOp = false) const;
- Instruction *getFirstNonPHIOrDbgOrLifetime(bool SkipPseudoOp = false) {
+ /// PHINode, a debug intrinsic, or a lifetime intrinsic, or any pseudo
+ /// operation if \c SkipPseudoOp is true.
+ const Instruction *
+ getFirstNonPHIOrDbgOrLifetime(bool SkipPseudoOp = false) const;
+ Instruction *getFirstNonPHIOrDbgOrLifetime(bool SkipPseudoOp = false) {
return const_cast<Instruction *>(
- static_cast<const BasicBlock *>(this)->getFirstNonPHIOrDbgOrLifetime(
- SkipPseudoOp));
+ static_cast<const BasicBlock *>(this)->getFirstNonPHIOrDbgOrLifetime(
+ SkipPseudoOp));
}
/// Returns an iterator to the first instruction in this block that is
@@ -203,18 +203,18 @@ public:
}
/// Return a const iterator range over the instructions in the block, skipping
- /// any debug instructions. Skip any pseudo operations as well if \c
- /// SkipPseudoOp is true.
+ /// any debug instructions. Skip any pseudo operations as well if \c
+ /// SkipPseudoOp is true.
iterator_range<filter_iterator<BasicBlock::const_iterator,
std::function<bool(const Instruction &)>>>
- instructionsWithoutDebug(bool SkipPseudoOp = false) const;
+ instructionsWithoutDebug(bool SkipPseudoOp = false) const;
/// Return an iterator range over the instructions in the block, skipping any
- /// debug instructions. Skip and any pseudo operations as well if \c
- /// SkipPseudoOp is true.
- iterator_range<
- filter_iterator<BasicBlock::iterator, std::function<bool(Instruction &)>>>
- instructionsWithoutDebug(bool SkipPseudoOp = false);
+ /// debug instructions. Skip and any pseudo operations as well if \c
+ /// SkipPseudoOp is true.
+ iterator_range<
+ filter_iterator<BasicBlock::iterator, std::function<bool(Instruction &)>>>
+ instructionsWithoutDebug(bool SkipPseudoOp = false);
/// Return the size of the basic block ignoring debug instructions
filter_iterator<BasicBlock::const_iterator,
@@ -405,51 +405,51 @@ public:
/// Split the basic block into two basic blocks at the specified instruction.
///
- /// If \p Before is true, splitBasicBlockBefore handles the
- /// block splitting. Otherwise, execution proceeds as described below.
+ /// If \p Before is true, splitBasicBlockBefore handles the
+ /// block splitting. Otherwise, execution proceeds as described below.
+ ///
+ /// Note that all instructions BEFORE the specified iterator
+ /// stay as part of the original basic block, an unconditional branch is added
+ /// to the original BB, and the rest of the instructions in the BB are moved
+ /// to the new BB, including the old terminator. The newly formed basic block
+ /// is returned. This function invalidates the specified iterator.
///
- /// Note that all instructions BEFORE the specified iterator
- /// stay as part of the original basic block, an unconditional branch is added
- /// to the original BB, and the rest of the instructions in the BB are moved
- /// to the new BB, including the old terminator. The newly formed basic block
- /// is returned. This function invalidates the specified iterator.
- ///
/// Note that this only works on well formed basic blocks (must have a
- /// terminator), and \p 'I' must not be the end of instruction list (which
- /// would cause a degenerate basic block to be formed, having a terminator
- /// inside of the basic block).
+ /// terminator), and \p 'I' must not be the end of instruction list (which
+ /// would cause a degenerate basic block to be formed, having a terminator
+ /// inside of the basic block).
///
/// Also note that this doesn't preserve any passes. To split blocks while
/// keeping loop information consistent, use the SplitBlock utility function.
- BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = "",
- bool Before = false);
- BasicBlock *splitBasicBlock(Instruction *I, const Twine &BBName = "",
- bool Before = false) {
- return splitBasicBlock(I->getIterator(), BBName, Before);
+ BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = "",
+ bool Before = false);
+ BasicBlock *splitBasicBlock(Instruction *I, const Twine &BBName = "",
+ bool Before = false) {
+ return splitBasicBlock(I->getIterator(), BBName, Before);
+ }
+
+ /// Split the basic block into two basic blocks at the specified instruction
+ /// and insert the new basic blocks as the predecessor of the current block.
+ ///
+ /// This function ensures all instructions AFTER and including the specified
+ /// iterator \p I are part of the original basic block. All Instructions
+ /// BEFORE the iterator \p I are moved to the new BB and an unconditional
+ /// branch is added to the new BB. The new basic block is returned.
+ ///
+ /// Note that this only works on well formed basic blocks (must have a
+ /// terminator), and \p 'I' must not be the end of instruction list (which
+ /// would cause a degenerate basic block to be formed, having a terminator
+ /// inside of the basic block). \p 'I' cannot be a iterator for a PHINode
+ /// with multiple incoming blocks.
+ ///
+ /// Also note that this doesn't preserve any passes. To split blocks while
+ /// keeping loop information consistent, use the SplitBlockBefore utility
+ /// function.
+ BasicBlock *splitBasicBlockBefore(iterator I, const Twine &BBName = "");
+ BasicBlock *splitBasicBlockBefore(Instruction *I, const Twine &BBName = "") {
+ return splitBasicBlockBefore(I->getIterator(), BBName);
}
- /// Split the basic block into two basic blocks at the specified instruction
- /// and insert the new basic blocks as the predecessor of the current block.
- ///
- /// This function ensures all instructions AFTER and including the specified
- /// iterator \p I are part of the original basic block. All Instructions
- /// BEFORE the iterator \p I are moved to the new BB and an unconditional
- /// branch is added to the new BB. The new basic block is returned.
- ///
- /// Note that this only works on well formed basic blocks (must have a
- /// terminator), and \p 'I' must not be the end of instruction list (which
- /// would cause a degenerate basic block to be formed, having a terminator
- /// inside of the basic block). \p 'I' cannot be a iterator for a PHINode
- /// with multiple incoming blocks.
- ///
- /// Also note that this doesn't preserve any passes. To split blocks while
- /// keeping loop information consistent, use the SplitBlockBefore utility
- /// function.
- BasicBlock *splitBasicBlockBefore(iterator I, const Twine &BBName = "");
- BasicBlock *splitBasicBlockBefore(Instruction *I, const Twine &BBName = "") {
- return splitBasicBlockBefore(I->getIterator(), BBName);
- }
-
/// Returns true if there are any uses of this basic block other than
/// direct branches, switches, etc. to it.
bool hasAddressTaken() const {
diff --git a/contrib/libs/llvm12/include/llvm/IR/CallingConv.h b/contrib/libs/llvm12/include/llvm/IR/CallingConv.h
index e88cf50337..42ee32fc24 100644
--- a/contrib/libs/llvm12/include/llvm/IR/CallingConv.h
+++ b/contrib/libs/llvm12/include/llvm/IR/CallingConv.h
@@ -248,9 +248,9 @@ namespace CallingConv {
/// The remainder matches the regular calling convention.
WASM_EmscriptenInvoke = 99,
- /// Calling convention used for AMD graphics targets.
- AMDGPU_Gfx = 100,
-
+ /// Calling convention used for AMD graphics targets.
+ AMDGPU_Gfx = 100,
+
/// The highest possible calling convention ID. Must be some 2^k - 1.
MaxID = 1023
};
diff --git a/contrib/libs/llvm12/include/llvm/IR/Constant.h b/contrib/libs/llvm12/include/llvm/IR/Constant.h
index 99b261e102..dea76a6253 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Constant.h
+++ b/contrib/libs/llvm12/include/llvm/IR/Constant.h
@@ -85,13 +85,13 @@ public:
bool isMinSignedValue() const;
/// Return true if this is a finite and non-zero floating-point scalar
- /// constant or a fixed width vector constant with all finite and non-zero
- /// elements.
+ /// constant or a fixed width vector constant with all finite and non-zero
+ /// elements.
bool isFiniteNonZeroFP() const;
- /// Return true if this is a normal (as opposed to denormal, infinity, nan,
- /// or zero) floating-point scalar constant or a vector constant with all
- /// normal elements. See APFloat::isNormal.
+ /// Return true if this is a normal (as opposed to denormal, infinity, nan,
+ /// or zero) floating-point scalar constant or a vector constant with all
+ /// normal elements. See APFloat::isNormal.
bool isNormalFP() const;
/// Return true if this scalar has an exact multiplicative inverse or this
@@ -108,18 +108,18 @@ public:
/// lane, the constants still match.
bool isElementWiseEqual(Value *Y) const;
- /// Return true if this is a vector constant that includes any undef or
- /// poison elements. Since it is impossible to inspect a scalable vector
- /// element- wise at compile time, this function returns true only if the
- /// entire vector is undef or poison.
- bool containsUndefOrPoisonElement() const;
-
- /// Return true if this is a vector constant that includes any poison
+ /// Return true if this is a vector constant that includes any undef or
+ /// poison elements. Since it is impossible to inspect a scalable vector
+ /// element- wise at compile time, this function returns true only if the
+ /// entire vector is undef or poison.
+ bool containsUndefOrPoisonElement() const;
+
+ /// Return true if this is a vector constant that includes any poison
/// elements.
- bool containsPoisonElement() const;
+ bool containsPoisonElement() const;
- /// Return true if this is a fixed width vector constant that includes
- /// any constant expressions.
+ /// Return true if this is a fixed width vector constant that includes
+ /// any constant expressions.
bool containsConstantExpression() const;
/// Return true if evaluation of this constant could trap. This is true for
@@ -215,16 +215,16 @@ public:
/// Try to replace undefined constant C or undefined elements in C with
/// Replacement. If no changes are made, the constant C is returned.
static Constant *replaceUndefsWith(Constant *C, Constant *Replacement);
-
- /// Merges undefs of a Constant with another Constant, along with the
- /// undefs already present. Other doesn't have to be the same type as C, but
- /// both must either be scalars or vectors with the same element count. If no
- /// changes are made, the constant C is returned.
- static Constant *mergeUndefsWith(Constant *C, Constant *Other);
-
- /// Return true if a constant is ConstantData or a ConstantAggregate or
- /// ConstantExpr that contain only ConstantData.
- bool isManifestConstant() const;
+
+ /// Merges undefs of a Constant with another Constant, along with the
+ /// undefs already present. Other doesn't have to be the same type as C, but
+ /// both must either be scalars or vectors with the same element count. If no
+ /// changes are made, the constant C is returned.
+ static Constant *mergeUndefsWith(Constant *C, Constant *Other);
+
+ /// Return true if a constant is ConstantData or a ConstantAggregate or
+ /// ConstantExpr that contain only ConstantData.
+ bool isManifestConstant() const;
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/IR/ConstantRange.h b/contrib/libs/llvm12/include/llvm/IR/ConstantRange.h
index 5393a3f92c..b1669359db 100644
--- a/contrib/libs/llvm12/include/llvm/IR/ConstantRange.h
+++ b/contrib/libs/llvm12/include/llvm/IR/ConstantRange.h
@@ -157,14 +157,14 @@ public:
const APInt &Other,
unsigned NoWrapKind);
- /// Returns true if ConstantRange calculations are supported for intrinsic
- /// with \p IntrinsicID.
- static bool isIntrinsicSupported(Intrinsic::ID IntrinsicID);
-
- /// Compute range of intrinsic result for the given operand ranges.
- static ConstantRange intrinsic(Intrinsic::ID IntrinsicID,
- ArrayRef<ConstantRange> Ops);
-
+ /// Returns true if ConstantRange calculations are supported for intrinsic
+ /// with \p IntrinsicID.
+ static bool isIntrinsicSupported(Intrinsic::ID IntrinsicID);
+
+ /// Compute range of intrinsic result for the given operand ranges.
+ static ConstantRange intrinsic(Intrinsic::ID IntrinsicID,
+ ArrayRef<ConstantRange> Ops);
+
/// Set up \p Pred and \p RHS such that
/// ConstantRange::makeExactICmpRegion(Pred, RHS) == *this. Return true if
/// successful.
@@ -268,14 +268,14 @@ public:
return !operator==(CR);
}
- /// Compute the maximal number of active bits needed to represent every value
- /// in this range.
- unsigned getActiveBits() const;
-
- /// Compute the maximal number of bits needed to represent every value
- /// in this signed range.
- unsigned getMinSignedBits() const;
-
+ /// Compute the maximal number of active bits needed to represent every value
+ /// in this range.
+ unsigned getActiveBits() const;
+
+ /// Compute the maximal number of bits needed to represent every value
+ /// in this signed range.
+ unsigned getMinSignedBits() const;
+
/// Subtract the specified constant from the endpoints of this constant range.
ConstantRange subtract(const APInt &CI) const;
@@ -424,11 +424,11 @@ public:
/// value in \p Other.
ConstantRange srem(const ConstantRange &Other) const;
- /// Return a new range representing the possible values resulting from
- /// a binary-xor of a value in this range by an all-one value,
- /// aka bitwise complement operation.
- ConstantRange binaryNot() const;
-
+ /// Return a new range representing the possible values resulting from
+ /// a binary-xor of a value in this range by an all-one value,
+ /// aka bitwise complement operation.
+ ConstantRange binaryNot() const;
+
/// Return a new range representing the possible values resulting
/// from a binary-and of a value in this range by a value in \p Other.
ConstantRange binaryAnd(const ConstantRange &Other) const;
@@ -484,9 +484,9 @@ public:
ConstantRange inverse() const;
/// Calculate absolute value range. If the original range contains signed
- /// min, then the resulting range will contain signed min if and only if
- /// \p IntMinIsPoison is false.
- ConstantRange abs(bool IntMinIsPoison = false) const;
+ /// min, then the resulting range will contain signed min if and only if
+ /// \p IntMinIsPoison is false.
+ ConstantRange abs(bool IntMinIsPoison = false) const;
/// Represents whether an operation on the given constant range is known to
/// always or never overflow.
diff --git a/contrib/libs/llvm12/include/llvm/IR/Constants.h b/contrib/libs/llvm12/include/llvm/IR/Constants.h
index 33bc771f8e..284e4320cd 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Constants.h
+++ b/contrib/libs/llvm12/include/llvm/IR/Constants.h
@@ -95,10 +95,10 @@ public:
static ConstantInt *getTrue(LLVMContext &Context);
static ConstantInt *getFalse(LLVMContext &Context);
- static ConstantInt *getBool(LLVMContext &Context, bool V);
+ static ConstantInt *getBool(LLVMContext &Context, bool V);
static Constant *getTrue(Type *Ty);
static Constant *getFalse(Type *Ty);
- static Constant *getBool(Type *Ty, bool V);
+ static Constant *getBool(Type *Ty, bool V);
/// If Ty is a vector type, return a Constant with a splat of the given
/// value. Otherwise return a ConstantInt for the given value.
@@ -601,13 +601,13 @@ class ConstantDataSequential : public ConstantData {
/// the same value but different type. For example, 0,0,0,1 could be a 4
/// element array of i8, or a 1-element array of i32. They'll both end up in
/// the same StringMap bucket, linked up.
- std::unique_ptr<ConstantDataSequential> Next;
+ std::unique_ptr<ConstantDataSequential> Next;
void destroyConstantImpl();
protected:
explicit ConstantDataSequential(Type *ty, ValueTy VT, const char *Data)
- : ConstantData(ty, VT), DataElements(Data) {}
+ : ConstantData(ty, VT), DataElements(Data) {}
static Constant *getImpl(StringRef Bytes, Type *Ty);
@@ -897,42 +897,42 @@ struct OperandTraits<BlockAddress> :
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BlockAddress, Value)
-/// Wrapper for a function that represents a value that
-/// functionally represents the original function. This can be a function,
-/// global alias to a function, or an ifunc.
-class DSOLocalEquivalent final : public Constant {
- friend class Constant;
-
- DSOLocalEquivalent(GlobalValue *GV);
-
- void *operator new(size_t s) { return User::operator new(s, 1); }
-
- void destroyConstantImpl();
- Value *handleOperandChangeImpl(Value *From, Value *To);
-
-public:
- /// Return a DSOLocalEquivalent for the specified global value.
- static DSOLocalEquivalent *get(GlobalValue *GV);
-
- /// Transparently provide more efficient getOperand methods.
- DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
-
- GlobalValue *getGlobalValue() const {
- return cast<GlobalValue>(Op<0>().get());
- }
-
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const Value *V) {
- return V->getValueID() == DSOLocalEquivalentVal;
- }
-};
-
-template <>
-struct OperandTraits<DSOLocalEquivalent>
- : public FixedNumOperandTraits<DSOLocalEquivalent, 1> {};
-
-DEFINE_TRANSPARENT_OPERAND_ACCESSORS(DSOLocalEquivalent, Value)
-
+/// Wrapper for a function that represents a value that
+/// functionally represents the original function. This can be a function,
+/// global alias to a function, or an ifunc.
+class DSOLocalEquivalent final : public Constant {
+ friend class Constant;
+
+ DSOLocalEquivalent(GlobalValue *GV);
+
+ void *operator new(size_t s) { return User::operator new(s, 1); }
+
+ void destroyConstantImpl();
+ Value *handleOperandChangeImpl(Value *From, Value *To);
+
+public:
+ /// Return a DSOLocalEquivalent for the specified global value.
+ static DSOLocalEquivalent *get(GlobalValue *GV);
+
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ GlobalValue *getGlobalValue() const {
+ return cast<GlobalValue>(Op<0>().get());
+ }
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const Value *V) {
+ return V->getValueID() == DSOLocalEquivalentVal;
+ }
+};
+
+template <>
+struct OperandTraits<DSOLocalEquivalent>
+ : public FixedNumOperandTraits<DSOLocalEquivalent, 1> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(DSOLocalEquivalent, Value)
+
//===----------------------------------------------------------------------===//
/// A constant value that is initialized with an expression using
/// other constant values.
@@ -1003,7 +1003,7 @@ public:
static Constant *getAnd(Constant *C1, Constant *C2);
static Constant *getOr(Constant *C1, Constant *C2);
static Constant *getXor(Constant *C1, Constant *C2);
- static Constant *getUMin(Constant *C1, Constant *C2);
+ static Constant *getUMin(Constant *C1, Constant *C2);
static Constant *getShl(Constant *C1, Constant *C2,
bool HasNUW = false, bool HasNSW = false);
static Constant *getLShr(Constant *C1, Constant *C2, bool isExact = false);
@@ -1079,12 +1079,12 @@ public:
return getLShr(C1, C2, true);
}
- /// If C is a scalar/fixed width vector of known powers of 2, then this
- /// function returns a new scalar/fixed width vector obtained from logBase2
- /// of C. Undef vector elements are set to zero.
- /// Return a null pointer otherwise.
- static Constant *getExactLogBase2(Constant *C);
-
+ /// If C is a scalar/fixed width vector of known powers of 2, then this
+ /// function returns a new scalar/fixed width vector obtained from logBase2
+ /// of C. Undef vector elements are set to zero.
+ /// Return a null pointer otherwise.
+ static Constant *getExactLogBase2(Constant *C);
+
/// Return the identity constant for a binary opcode.
/// The identity constant C is defined as X op C = X and C op X = X for every
/// X when the binary operation is commutative. If the binop is not
@@ -1357,16 +1357,16 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantExpr, Constant)
/// can appear to have different bit patterns at each use. See
/// LangRef.html#undefvalues for details.
///
-class UndefValue : public ConstantData {
+class UndefValue : public ConstantData {
friend class Constant;
explicit UndefValue(Type *T) : ConstantData(T, UndefValueVal) {}
void destroyConstantImpl();
-protected:
- explicit UndefValue(Type *T, ValueTy vty) : ConstantData(T, vty) {}
-
+protected:
+ explicit UndefValue(Type *T, ValueTy vty) : ConstantData(T, vty) {}
+
public:
UndefValue(const UndefValue &) = delete;
@@ -1393,52 +1393,52 @@ public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *V) {
- return V->getValueID() == UndefValueVal ||
- V->getValueID() == PoisonValueVal;
+ return V->getValueID() == UndefValueVal ||
+ V->getValueID() == PoisonValueVal;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// In order to facilitate speculative execution, many instructions do not
+/// invoke immediate undefined behavior when provided with illegal operands,
+/// and return a poison value instead.
+///
+/// see LangRef.html#poisonvalues for details.
+///
+class PoisonValue final : public UndefValue {
+ friend class Constant;
+
+ explicit PoisonValue(Type *T) : UndefValue(T, PoisonValueVal) {}
+
+ void destroyConstantImpl();
+
+public:
+ PoisonValue(const PoisonValue &) = delete;
+
+ /// Static factory methods - Return an 'poison' object of the specified type.
+ static PoisonValue *get(Type *T);
+
+ /// If this poison has array or vector type, return a poison with the right
+ /// element type.
+ PoisonValue *getSequentialElement() const;
+
+ /// If this poison has struct type, return a poison with the right element
+ /// type for the specified element.
+ PoisonValue *getStructElement(unsigned Elt) const;
+
+ /// Return an poison of the right value for the specified GEP index if we can,
+ /// otherwise return null (e.g. if C is a ConstantExpr).
+ PoisonValue *getElementValue(Constant *C) const;
+
+ /// Return an poison of the right value for the specified GEP index.
+ PoisonValue *getElementValue(unsigned Idx) const;
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const Value *V) {
+ return V->getValueID() == PoisonValueVal;
}
};
-//===----------------------------------------------------------------------===//
-/// In order to facilitate speculative execution, many instructions do not
-/// invoke immediate undefined behavior when provided with illegal operands,
-/// and return a poison value instead.
-///
-/// see LangRef.html#poisonvalues for details.
-///
-class PoisonValue final : public UndefValue {
- friend class Constant;
-
- explicit PoisonValue(Type *T) : UndefValue(T, PoisonValueVal) {}
-
- void destroyConstantImpl();
-
-public:
- PoisonValue(const PoisonValue &) = delete;
-
- /// Static factory methods - Return an 'poison' object of the specified type.
- static PoisonValue *get(Type *T);
-
- /// If this poison has array or vector type, return a poison with the right
- /// element type.
- PoisonValue *getSequentialElement() const;
-
- /// If this poison has struct type, return a poison with the right element
- /// type for the specified element.
- PoisonValue *getStructElement(unsigned Elt) const;
-
- /// Return an poison of the right value for the specified GEP index if we can,
- /// otherwise return null (e.g. if C is a ConstantExpr).
- PoisonValue *getElementValue(Constant *C) const;
-
- /// Return an poison of the right value for the specified GEP index.
- PoisonValue *getElementValue(unsigned Idx) const;
-
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const Value *V) {
- return V->getValueID() == PoisonValueVal;
- }
-};
-
} // end namespace llvm
#endif // LLVM_IR_CONSTANTS_H
diff --git a/contrib/libs/llvm12/include/llvm/IR/DIBuilder.h b/contrib/libs/llvm12/include/llvm/IR/DIBuilder.h
index d869947574..3c925b80f4 100644
--- a/contrib/libs/llvm12/include/llvm/IR/DIBuilder.h
+++ b/contrib/libs/llvm12/include/llvm/IR/DIBuilder.h
@@ -206,12 +206,12 @@ namespace llvm {
unsigned Encoding,
DINode::DIFlags Flags = DINode::FlagZero);
- /// Create debugging information entry for a string
- /// type.
- /// \param Name Type name.
- /// \param SizeInBits Size of the type.
- DIStringType *createStringType(StringRef Name, uint64_t SizeInBits);
-
+ /// Create debugging information entry for a string
+ /// type.
+ /// \param Name Type name.
+ /// \param SizeInBits Size of the type.
+ DIStringType *createStringType(StringRef Name, uint64_t SizeInBits);
+
/// Create debugging information entry for a qualified
/// type, e.g. 'const int'.
/// \param Tag Tag identifing type, e.g. dwarf::TAG_volatile_type
@@ -501,24 +501,24 @@ namespace llvm {
/// \param AlignInBits Alignment.
/// \param Ty Element type.
/// \param Subscripts Subscripts.
- /// \param DataLocation The location of the raw data of a descriptor-based
- /// Fortran array, either a DIExpression* or
- /// a DIVariable*.
- /// \param Associated The associated attribute of a descriptor-based
- /// Fortran array, either a DIExpression* or
- /// a DIVariable*.
- /// \param Allocated The allocated attribute of a descriptor-based
- /// Fortran array, either a DIExpression* or
- /// a DIVariable*.
- /// \param Rank The rank attribute of a descriptor-based
- /// Fortran array, either a DIExpression* or
- /// a DIVariable*.
- DICompositeType *createArrayType(
- uint64_t Size, uint32_t AlignInBits, DIType *Ty, DINodeArray Subscripts,
- PointerUnion<DIExpression *, DIVariable *> DataLocation = nullptr,
- PointerUnion<DIExpression *, DIVariable *> Associated = nullptr,
- PointerUnion<DIExpression *, DIVariable *> Allocated = nullptr,
- PointerUnion<DIExpression *, DIVariable *> Rank = nullptr);
+ /// \param DataLocation The location of the raw data of a descriptor-based
+ /// Fortran array, either a DIExpression* or
+ /// a DIVariable*.
+ /// \param Associated The associated attribute of a descriptor-based
+ /// Fortran array, either a DIExpression* or
+ /// a DIVariable*.
+ /// \param Allocated The allocated attribute of a descriptor-based
+ /// Fortran array, either a DIExpression* or
+ /// a DIVariable*.
+ /// \param Rank The rank attribute of a descriptor-based
+ /// Fortran array, either a DIExpression* or
+ /// a DIVariable*.
+ DICompositeType *createArrayType(
+ uint64_t Size, uint32_t AlignInBits, DIType *Ty, DINodeArray Subscripts,
+ PointerUnion<DIExpression *, DIVariable *> DataLocation = nullptr,
+ PointerUnion<DIExpression *, DIVariable *> Associated = nullptr,
+ PointerUnion<DIExpression *, DIVariable *> Allocated = nullptr,
+ PointerUnion<DIExpression *, DIVariable *> Rank = nullptr);
/// Create debugging information entry for a vector type.
/// \param Size Array size.
@@ -605,12 +605,12 @@ namespace llvm {
DISubrange *getOrCreateSubrange(Metadata *Count, Metadata *LowerBound,
Metadata *UpperBound, Metadata *Stride);
- DIGenericSubrange *
- getOrCreateGenericSubrange(DIGenericSubrange::BoundType Count,
- DIGenericSubrange::BoundType LowerBound,
- DIGenericSubrange::BoundType UpperBound,
- DIGenericSubrange::BoundType Stride);
-
+ DIGenericSubrange *
+ getOrCreateGenericSubrange(DIGenericSubrange::BoundType Count,
+ DIGenericSubrange::BoundType LowerBound,
+ DIGenericSubrange::BoundType UpperBound,
+ DIGenericSubrange::BoundType Stride);
+
/// Create a new descriptor for the specified variable.
/// \param Context Variable scope.
/// \param Name Name of the variable.
@@ -779,18 +779,18 @@ namespace llvm {
/// definitions as they would appear on a command line.
/// \param IncludePath The path to the module map file.
/// \param APINotesFile The path to an API notes file for this module.
- /// \param File Source file of the module.
+ /// \param File Source file of the module.
+ /// Used for Fortran modules.
+ /// \param LineNo Source line number of the module.
/// Used for Fortran modules.
- /// \param LineNo Source line number of the module.
- /// Used for Fortran modules.
- /// \param IsDecl This is a module declaration; default to false;
- /// when set to true, only Scope and Name are required
- /// as this entry is just a hint for the debugger to find
- /// the corresponding definition in the global scope.
+ /// \param IsDecl This is a module declaration; default to false;
+ /// when set to true, only Scope and Name are required
+ /// as this entry is just a hint for the debugger to find
+ /// the corresponding definition in the global scope.
DIModule *createModule(DIScope *Scope, StringRef Name,
StringRef ConfigurationMacros, StringRef IncludePath,
StringRef APINotesFile = {}, DIFile *File = nullptr,
- unsigned LineNo = 0, bool IsDecl = false);
+ unsigned LineNo = 0, bool IsDecl = false);
/// This creates a descriptor for a lexical block with a new file
/// attached. This merely extends the existing
diff --git a/contrib/libs/llvm12/include/llvm/IR/DataLayout.h b/contrib/libs/llvm12/include/llvm/IR/DataLayout.h
index e5ff76cea2..7f44dc23bf 100644
--- a/contrib/libs/llvm12/include/llvm/IR/DataLayout.h
+++ b/contrib/libs/llvm12/include/llvm/IR/DataLayout.h
@@ -130,7 +130,7 @@ private:
unsigned AllocaAddrSpace;
MaybeAlign StackNaturalAlign;
unsigned ProgramAddrSpace;
- unsigned DefaultGlobalsAddrSpace;
+ unsigned DefaultGlobalsAddrSpace;
MaybeAlign FunctionPtrAlign;
FunctionPtrAlignType TheFunctionPtrAlignType;
@@ -168,7 +168,7 @@ private:
using PointersTy = SmallVector<PointerAlignElem, 8>;
PointersTy Pointers;
- const PointerAlignElem &getPointerAlignElem(uint32_t AddressSpace) const;
+ const PointerAlignElem &getPointerAlignElem(uint32_t AddressSpace) const;
// The StructType -> StructLayout map.
mutable void *LayoutMap = nullptr;
@@ -177,25 +177,25 @@ private:
/// well-defined bitwise representation.
SmallVector<unsigned, 8> NonIntegralAddressSpaces;
- /// Attempts to set the alignment of the given type. Returns an error
- /// description on failure.
- Error setAlignment(AlignTypeEnum align_type, Align abi_align,
- Align pref_align, uint32_t bit_width);
-
- /// Attempts to set the alignment of a pointer in the given address space.
- /// Returns an error description on failure.
- Error setPointerAlignment(uint32_t AddrSpace, Align ABIAlign, Align PrefAlign,
- uint32_t TypeByteWidth, uint32_t IndexWidth);
-
- /// Internal helper to get alignment for integer of given bitwidth.
- Align getIntegerAlignment(uint32_t BitWidth, bool abi_or_pref) const;
-
+ /// Attempts to set the alignment of the given type. Returns an error
+ /// description on failure.
+ Error setAlignment(AlignTypeEnum align_type, Align abi_align,
+ Align pref_align, uint32_t bit_width);
+
+ /// Attempts to set the alignment of a pointer in the given address space.
+ /// Returns an error description on failure.
+ Error setPointerAlignment(uint32_t AddrSpace, Align ABIAlign, Align PrefAlign,
+ uint32_t TypeByteWidth, uint32_t IndexWidth);
+
+ /// Internal helper to get alignment for integer of given bitwidth.
+ Align getIntegerAlignment(uint32_t BitWidth, bool abi_or_pref) const;
+
/// Internal helper method that returns requested alignment for type.
Align getAlignment(Type *Ty, bool abi_or_pref) const;
- /// Attempts to parse a target data specification string and reports an error
- /// if the string is malformed.
- Error parseSpecifier(StringRef Desc);
+ /// Attempts to parse a target data specification string and reports an error
+ /// if the string is malformed.
+ Error parseSpecifier(StringRef Desc);
// Free all internal data structures.
void clear();
@@ -222,7 +222,7 @@ public:
FunctionPtrAlign = DL.FunctionPtrAlign;
TheFunctionPtrAlignType = DL.TheFunctionPtrAlignType;
ProgramAddrSpace = DL.ProgramAddrSpace;
- DefaultGlobalsAddrSpace = DL.DefaultGlobalsAddrSpace;
+ DefaultGlobalsAddrSpace = DL.DefaultGlobalsAddrSpace;
ManglingMode = DL.ManglingMode;
LegalIntWidths = DL.LegalIntWidths;
Alignments = DL.Alignments;
@@ -239,10 +239,10 @@ public:
/// Parse a data layout string (with fallback to default values).
void reset(StringRef LayoutDescription);
- /// Parse a data layout string and return the layout. Return an error
- /// description on failure.
- static Expected<DataLayout> parse(StringRef LayoutDescription);
-
+ /// Parse a data layout string and return the layout. Return an error
+ /// description on failure.
+ static Expected<DataLayout> parse(StringRef LayoutDescription);
+
/// Layout endianness...
bool isLittleEndian() const { return !BigEndian; }
bool isBigEndian() const { return BigEndian; }
@@ -299,9 +299,9 @@ public:
}
unsigned getProgramAddressSpace() const { return ProgramAddrSpace; }
- unsigned getDefaultGlobalsAddressSpace() const {
- return DefaultGlobalsAddrSpace;
- }
+ unsigned getDefaultGlobalsAddressSpace() const {
+ return DefaultGlobalsAddrSpace;
+ }
bool hasMicrosoftFastStdCallMangling() const {
return ManglingMode == MM_WinCOFFX86;
@@ -395,7 +395,7 @@ public:
bool isNonIntegralAddressSpace(unsigned AddrSpace) const {
ArrayRef<unsigned> NonIntegralSpaces = getNonIntegralAddressSpaces();
- return is_contained(NonIntegralSpaces, AddrSpace);
+ return is_contained(NonIntegralSpaces, AddrSpace);
}
bool isNonIntegralPointerType(PointerType *PT) const {
@@ -537,9 +537,9 @@ public:
/// Returns the minimum ABI-required alignment for an integer type of
/// the specified bitwidth.
- Align getABIIntegerTypeAlignment(unsigned BitWidth) const {
- return getIntegerAlignment(BitWidth, /* abi_or_pref */ true);
- }
+ Align getABIIntegerTypeAlignment(unsigned BitWidth) const {
+ return getIntegerAlignment(BitWidth, /* abi_or_pref */ true);
+ }
/// Returns the preferred stack/global alignment for the specified
/// type.
@@ -697,8 +697,8 @@ inline TypeSize DataLayout::getTypeSizeInBits(Type *Ty) const {
case Type::PPC_FP128TyID:
case Type::FP128TyID:
return TypeSize::Fixed(128);
- case Type::X86_AMXTyID:
- return TypeSize::Fixed(8192);
+ case Type::X86_AMXTyID:
+ return TypeSize::Fixed(8192);
// In memory objects this is always aligned to a higher boundary, but
// only 80 bits contain information.
case Type::X86_FP80TyID:
@@ -707,9 +707,9 @@ inline TypeSize DataLayout::getTypeSizeInBits(Type *Ty) const {
case Type::ScalableVectorTyID: {
VectorType *VTy = cast<VectorType>(Ty);
auto EltCnt = VTy->getElementCount();
- uint64_t MinBits = EltCnt.getKnownMinValue() *
- getTypeSizeInBits(VTy->getElementType()).getFixedSize();
- return TypeSize(MinBits, EltCnt.isScalable());
+ uint64_t MinBits = EltCnt.getKnownMinValue() *
+ getTypeSizeInBits(VTy->getElementType()).getFixedSize();
+ return TypeSize(MinBits, EltCnt.isScalable());
}
default:
llvm_unreachable("DataLayout::getTypeSizeInBits(): Unsupported type");
diff --git a/contrib/libs/llvm12/include/llvm/IR/DebugInfoMetadata.h b/contrib/libs/llvm12/include/llvm/IR/DebugInfoMetadata.h
index 267a9830ba..3576a8171c 100644
--- a/contrib/libs/llvm12/include/llvm/IR/DebugInfoMetadata.h
+++ b/contrib/libs/llvm12/include/llvm/IR/DebugInfoMetadata.h
@@ -189,7 +189,7 @@ public:
case DISubrangeKind:
case DIEnumeratorKind:
case DIBasicTypeKind:
- case DIStringTypeKind:
+ case DIStringTypeKind:
case DIDerivedTypeKind:
case DICompositeTypeKind:
case DISubroutineTypeKind:
@@ -208,7 +208,7 @@ public:
case DIObjCPropertyKind:
case DIImportedEntityKind:
case DIModuleKind:
- case DIGenericSubrangeKind:
+ case DIGenericSubrangeKind:
return true;
}
}
@@ -247,8 +247,8 @@ class GenericDINode : public DINode {
StorageType Storage, bool ShouldCreate = true);
TempGenericDINode cloneImpl() const {
- return getTemporary(getContext(), getTag(), getHeader(),
- SmallVector<Metadata *, 4>(dwarf_operands()));
+ return getTemporary(getContext(), getTag(), getHeader(),
+ SmallVector<Metadata *, 4>(dwarf_operands()));
}
public:
@@ -358,52 +358,52 @@ public:
}
};
-class DIGenericSubrange : public DINode {
- friend class LLVMContextImpl;
- friend class MDNode;
-
- DIGenericSubrange(LLVMContext &C, StorageType Storage,
- ArrayRef<Metadata *> Ops)
- : DINode(C, DIGenericSubrangeKind, Storage,
- dwarf::DW_TAG_generic_subrange, Ops) {}
-
- ~DIGenericSubrange() = default;
-
- static DIGenericSubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
- Metadata *LowerBound, Metadata *UpperBound,
- Metadata *Stride, StorageType Storage,
- bool ShouldCreate = true);
-
- TempDIGenericSubrange cloneImpl() const {
- return getTemporary(getContext(), getRawCountNode(), getRawLowerBound(),
- getRawUpperBound(), getRawStride());
- }
-
-public:
- DEFINE_MDNODE_GET(DIGenericSubrange,
- (Metadata * CountNode, Metadata *LowerBound,
- Metadata *UpperBound, Metadata *Stride),
- (CountNode, LowerBound, UpperBound, Stride))
-
- TempDIGenericSubrange clone() const { return cloneImpl(); }
-
- Metadata *getRawCountNode() const { return getOperand(0).get(); }
- Metadata *getRawLowerBound() const { return getOperand(1).get(); }
- Metadata *getRawUpperBound() const { return getOperand(2).get(); }
- Metadata *getRawStride() const { return getOperand(3).get(); }
-
- using BoundType = PointerUnion<DIVariable *, DIExpression *>;
-
- BoundType getCount() const;
- BoundType getLowerBound() const;
- BoundType getUpperBound() const;
- BoundType getStride() const;
-
- static bool classof(const Metadata *MD) {
- return MD->getMetadataID() == DIGenericSubrangeKind;
- }
-};
-
+class DIGenericSubrange : public DINode {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ DIGenericSubrange(LLVMContext &C, StorageType Storage,
+ ArrayRef<Metadata *> Ops)
+ : DINode(C, DIGenericSubrangeKind, Storage,
+ dwarf::DW_TAG_generic_subrange, Ops) {}
+
+ ~DIGenericSubrange() = default;
+
+ static DIGenericSubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
+ Metadata *LowerBound, Metadata *UpperBound,
+ Metadata *Stride, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempDIGenericSubrange cloneImpl() const {
+ return getTemporary(getContext(), getRawCountNode(), getRawLowerBound(),
+ getRawUpperBound(), getRawStride());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DIGenericSubrange,
+ (Metadata * CountNode, Metadata *LowerBound,
+ Metadata *UpperBound, Metadata *Stride),
+ (CountNode, LowerBound, UpperBound, Stride))
+
+ TempDIGenericSubrange clone() const { return cloneImpl(); }
+
+ Metadata *getRawCountNode() const { return getOperand(0).get(); }
+ Metadata *getRawLowerBound() const { return getOperand(1).get(); }
+ Metadata *getRawUpperBound() const { return getOperand(2).get(); }
+ Metadata *getRawStride() const { return getOperand(3).get(); }
+
+ using BoundType = PointerUnion<DIVariable *, DIExpression *>;
+
+ BoundType getCount() const;
+ BoundType getLowerBound() const;
+ BoundType getUpperBound() const;
+ BoundType getStride() const;
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DIGenericSubrangeKind;
+ }
+};
+
/// Enumeration value.
///
/// TODO: Add a pointer to the context (DW_TAG_enumeration_type) once that no
@@ -505,7 +505,7 @@ public:
default:
return false;
case DIBasicTypeKind:
- case DIStringTypeKind:
+ case DIStringTypeKind:
case DIDerivedTypeKind:
case DICompositeTypeKind:
case DISubroutineTypeKind:
@@ -752,7 +752,7 @@ public:
default:
return false;
case DIBasicTypeKind:
- case DIStringTypeKind:
+ case DIStringTypeKind:
case DIDerivedTypeKind:
case DICompositeTypeKind:
case DISubroutineTypeKind:
@@ -803,12 +803,12 @@ public:
DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name),
(Tag, Name, 0, 0, 0, FlagZero))
DEFINE_MDNODE_GET(DIBasicType,
- (unsigned Tag, StringRef Name, uint64_t SizeInBits),
- (Tag, Name, SizeInBits, 0, 0, FlagZero))
- DEFINE_MDNODE_GET(DIBasicType,
- (unsigned Tag, MDString *Name, uint64_t SizeInBits),
- (Tag, Name, SizeInBits, 0, 0, FlagZero))
- DEFINE_MDNODE_GET(DIBasicType,
+ (unsigned Tag, StringRef Name, uint64_t SizeInBits),
+ (Tag, Name, SizeInBits, 0, 0, FlagZero))
+ DEFINE_MDNODE_GET(DIBasicType,
+ (unsigned Tag, MDString *Name, uint64_t SizeInBits),
+ (Tag, Name, SizeInBits, 0, 0, FlagZero))
+ DEFINE_MDNODE_GET(DIBasicType,
(unsigned Tag, StringRef Name, uint64_t SizeInBits,
uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
(Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
@@ -832,81 +832,81 @@ public:
}
};
-/// String type, Fortran CHARACTER(n)
-class DIStringType : public DIType {
- friend class LLVMContextImpl;
- friend class MDNode;
-
- unsigned Encoding;
-
- DIStringType(LLVMContext &C, StorageType Storage, unsigned Tag,
- uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
- ArrayRef<Metadata *> Ops)
- : DIType(C, DIStringTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
- FlagZero, Ops),
- Encoding(Encoding) {}
- ~DIStringType() = default;
-
- static DIStringType *getImpl(LLVMContext &Context, unsigned Tag,
- StringRef Name, Metadata *StringLength,
- Metadata *StrLenExp, uint64_t SizeInBits,
- uint32_t AlignInBits, unsigned Encoding,
- StorageType Storage, bool ShouldCreate = true) {
- return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
- StringLength, StrLenExp, SizeInBits, AlignInBits, Encoding,
- Storage, ShouldCreate);
- }
- static DIStringType *getImpl(LLVMContext &Context, unsigned Tag,
- MDString *Name, Metadata *StringLength,
- Metadata *StrLenExp, uint64_t SizeInBits,
- uint32_t AlignInBits, unsigned Encoding,
- StorageType Storage, bool ShouldCreate = true);
-
- TempDIStringType cloneImpl() const {
- return getTemporary(getContext(), getTag(), getRawName(),
- getRawStringLength(), getRawStringLengthExp(),
- getSizeInBits(), getAlignInBits(), getEncoding());
- }
-
-public:
- DEFINE_MDNODE_GET(DIStringType,
- (unsigned Tag, StringRef Name, uint64_t SizeInBits,
- uint32_t AlignInBits),
- (Tag, Name, nullptr, nullptr, SizeInBits, AlignInBits, 0))
- DEFINE_MDNODE_GET(DIStringType,
- (unsigned Tag, MDString *Name, Metadata *StringLength,
- Metadata *StringLengthExp, uint64_t SizeInBits,
- uint32_t AlignInBits, unsigned Encoding),
- (Tag, Name, StringLength, StringLengthExp, SizeInBits,
- AlignInBits, Encoding))
- DEFINE_MDNODE_GET(DIStringType,
- (unsigned Tag, StringRef Name, Metadata *StringLength,
- Metadata *StringLengthExp, uint64_t SizeInBits,
- uint32_t AlignInBits, unsigned Encoding),
- (Tag, Name, StringLength, StringLengthExp, SizeInBits,
- AlignInBits, Encoding))
-
- TempDIStringType clone() const { return cloneImpl(); }
-
- static bool classof(const Metadata *MD) {
- return MD->getMetadataID() == DIStringTypeKind;
- }
-
- DIVariable *getStringLength() const {
- return cast_or_null<DIVariable>(getRawStringLength());
- }
-
- DIExpression *getStringLengthExp() const {
- return cast_or_null<DIExpression>(getRawStringLengthExp());
- }
-
- unsigned getEncoding() const { return Encoding; }
-
- Metadata *getRawStringLength() const { return getOperand(3); }
-
- Metadata *getRawStringLengthExp() const { return getOperand(4); }
-};
-
+/// String type, Fortran CHARACTER(n)
+class DIStringType : public DIType {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned Encoding;
+
+ DIStringType(LLVMContext &C, StorageType Storage, unsigned Tag,
+ uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
+ ArrayRef<Metadata *> Ops)
+ : DIType(C, DIStringTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
+ FlagZero, Ops),
+ Encoding(Encoding) {}
+ ~DIStringType() = default;
+
+ static DIStringType *getImpl(LLVMContext &Context, unsigned Tag,
+ StringRef Name, Metadata *StringLength,
+ Metadata *StrLenExp, uint64_t SizeInBits,
+ uint32_t AlignInBits, unsigned Encoding,
+ StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
+ StringLength, StrLenExp, SizeInBits, AlignInBits, Encoding,
+ Storage, ShouldCreate);
+ }
+ static DIStringType *getImpl(LLVMContext &Context, unsigned Tag,
+ MDString *Name, Metadata *StringLength,
+ Metadata *StrLenExp, uint64_t SizeInBits,
+ uint32_t AlignInBits, unsigned Encoding,
+ StorageType Storage, bool ShouldCreate = true);
+
+ TempDIStringType cloneImpl() const {
+ return getTemporary(getContext(), getTag(), getRawName(),
+ getRawStringLength(), getRawStringLengthExp(),
+ getSizeInBits(), getAlignInBits(), getEncoding());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DIStringType,
+ (unsigned Tag, StringRef Name, uint64_t SizeInBits,
+ uint32_t AlignInBits),
+ (Tag, Name, nullptr, nullptr, SizeInBits, AlignInBits, 0))
+ DEFINE_MDNODE_GET(DIStringType,
+ (unsigned Tag, MDString *Name, Metadata *StringLength,
+ Metadata *StringLengthExp, uint64_t SizeInBits,
+ uint32_t AlignInBits, unsigned Encoding),
+ (Tag, Name, StringLength, StringLengthExp, SizeInBits,
+ AlignInBits, Encoding))
+ DEFINE_MDNODE_GET(DIStringType,
+ (unsigned Tag, StringRef Name, Metadata *StringLength,
+ Metadata *StringLengthExp, uint64_t SizeInBits,
+ uint32_t AlignInBits, unsigned Encoding),
+ (Tag, Name, StringLength, StringLengthExp, SizeInBits,
+ AlignInBits, Encoding))
+
+ TempDIStringType clone() const { return cloneImpl(); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DIStringTypeKind;
+ }
+
+ DIVariable *getStringLength() const {
+ return cast_or_null<DIVariable>(getRawStringLength());
+ }
+
+ DIExpression *getStringLengthExp() const {
+ return cast_or_null<DIExpression>(getRawStringLengthExp());
+ }
+
+ unsigned getEncoding() const { return Encoding; }
+
+ Metadata *getRawStringLength() const { return getOperand(3); }
+
+ Metadata *getRawStringLengthExp() const { return getOperand(4); }
+};
+
/// Derived types.
///
/// This includes qualified types, pointers, references, friends, typedefs, and
@@ -1079,14 +1079,14 @@ class DICompositeType : public DIType {
DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
DITemplateParameterArray TemplateParams, StringRef Identifier,
DIDerivedType *Discriminator, Metadata *DataLocation,
- Metadata *Associated, Metadata *Allocated, Metadata *Rank,
+ Metadata *Associated, Metadata *Allocated, Metadata *Rank,
StorageType Storage, bool ShouldCreate = true) {
- return getImpl(
- Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
- BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
- RuntimeLang, VTableHolder, TemplateParams.get(),
- getCanonicalMDString(Context, Identifier), Discriminator, DataLocation,
- Associated, Allocated, Rank, Storage, ShouldCreate);
+ return getImpl(
+ Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
+ RuntimeLang, VTableHolder, TemplateParams.get(),
+ getCanonicalMDString(Context, Identifier), Discriminator, DataLocation,
+ Associated, Allocated, Rank, Storage, ShouldCreate);
}
static DICompositeType *
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
@@ -1095,7 +1095,7 @@ class DICompositeType : public DIType {
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
Metadata *VTableHolder, Metadata *TemplateParams,
MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation,
- Metadata *Associated, Metadata *Allocated, Metadata *Rank,
+ Metadata *Associated, Metadata *Allocated, Metadata *Rank,
StorageType Storage, bool ShouldCreate = true);
TempDICompositeType cloneImpl() const {
@@ -1104,8 +1104,8 @@ class DICompositeType : public DIType {
getAlignInBits(), getOffsetInBits(), getFlags(),
getElements(), getRuntimeLang(), getVTableHolder(),
getTemplateParams(), getIdentifier(),
- getDiscriminator(), getRawDataLocation(),
- getRawAssociated(), getRawAllocated(), getRawRank());
+ getDiscriminator(), getRawDataLocation(),
+ getRawAssociated(), getRawAllocated(), getRawRank());
}
public:
@@ -1117,11 +1117,11 @@ public:
DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
DITemplateParameterArray TemplateParams = nullptr,
StringRef Identifier = "", DIDerivedType *Discriminator = nullptr,
- Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
- Metadata *Allocated = nullptr, Metadata *Rank = nullptr),
+ Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
+ Metadata *Allocated = nullptr, Metadata *Rank = nullptr),
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
- Identifier, Discriminator, DataLocation, Associated, Allocated, Rank))
+ Identifier, Discriminator, DataLocation, Associated, Allocated, Rank))
DEFINE_MDNODE_GET(
DICompositeType,
(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
@@ -1129,12 +1129,12 @@ public:
uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
Metadata *TemplateParams = nullptr, MDString *Identifier = nullptr,
- Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr,
- Metadata *Associated = nullptr, Metadata *Allocated = nullptr,
- Metadata *Rank = nullptr),
+ Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr,
+ Metadata *Associated = nullptr, Metadata *Allocated = nullptr,
+ Metadata *Rank = nullptr),
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
- Identifier, Discriminator, DataLocation, Associated, Allocated, Rank))
+ Identifier, Discriminator, DataLocation, Associated, Allocated, Rank))
TempDICompositeType clone() const { return cloneImpl(); }
@@ -1152,8 +1152,8 @@ public:
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
unsigned RuntimeLang, Metadata *VTableHolder,
Metadata *TemplateParams, Metadata *Discriminator,
- Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
- Metadata *Rank);
+ Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
+ Metadata *Rank);
static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
MDString &Identifier);
@@ -1173,8 +1173,8 @@ public:
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
unsigned RuntimeLang, Metadata *VTableHolder,
Metadata *TemplateParams, Metadata *Discriminator,
- Metadata *DataLocation, Metadata *Associated,
- Metadata *Allocated, Metadata *Rank);
+ Metadata *DataLocation, Metadata *Associated,
+ Metadata *Allocated, Metadata *Rank);
DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
DINodeArray getElements() const {
@@ -1203,29 +1203,29 @@ public:
DIExpression *getDataLocationExp() const {
return dyn_cast_or_null<DIExpression>(getRawDataLocation());
}
- Metadata *getRawAssociated() const { return getOperand(10); }
- DIVariable *getAssociated() const {
- return dyn_cast_or_null<DIVariable>(getRawAssociated());
- }
- DIExpression *getAssociatedExp() const {
- return dyn_cast_or_null<DIExpression>(getRawAssociated());
- }
- Metadata *getRawAllocated() const { return getOperand(11); }
- DIVariable *getAllocated() const {
- return dyn_cast_or_null<DIVariable>(getRawAllocated());
- }
- DIExpression *getAllocatedExp() const {
- return dyn_cast_or_null<DIExpression>(getRawAllocated());
- }
- Metadata *getRawRank() const { return getOperand(12); }
- ConstantInt *getRankConst() const {
- if (auto *MD = dyn_cast_or_null<ConstantAsMetadata>(getRawRank()))
- return dyn_cast_or_null<ConstantInt>(MD->getValue());
- return nullptr;
- }
- DIExpression *getRankExp() const {
- return dyn_cast_or_null<DIExpression>(getRawRank());
- }
+ Metadata *getRawAssociated() const { return getOperand(10); }
+ DIVariable *getAssociated() const {
+ return dyn_cast_or_null<DIVariable>(getRawAssociated());
+ }
+ DIExpression *getAssociatedExp() const {
+ return dyn_cast_or_null<DIExpression>(getRawAssociated());
+ }
+ Metadata *getRawAllocated() const { return getOperand(11); }
+ DIVariable *getAllocated() const {
+ return dyn_cast_or_null<DIVariable>(getRawAllocated());
+ }
+ DIExpression *getAllocatedExp() const {
+ return dyn_cast_or_null<DIExpression>(getRawAllocated());
+ }
+ Metadata *getRawRank() const { return getOperand(12); }
+ ConstantInt *getRankConst() const {
+ if (auto *MD = dyn_cast_or_null<ConstantAsMetadata>(getRawRank()))
+ return dyn_cast_or_null<ConstantInt>(MD->getValue());
+ return nullptr;
+ }
+ DIExpression *getRankExp() const {
+ return dyn_cast_or_null<DIExpression>(getRawRank());
+ }
/// Replace operands.
///
@@ -1704,18 +1704,18 @@ public:
inline unsigned getDiscriminator() const;
- // For the regular discriminator, it stands for all empty components if all
- // the lowest 3 bits are non-zero and all higher 29 bits are unused(zero by
- // default). Here we fully leverage the higher 29 bits for pseudo probe use.
- // This is the format:
- // [2:0] - 0x7
- // [31:3] - pseudo probe fields guaranteed to be non-zero as a whole
- // So if the lower 3 bits is non-zero and the others has at least one
- // non-zero bit, it guarantees to be a pseudo probe discriminator
- inline static bool isPseudoProbeDiscriminator(unsigned Discriminator) {
- return ((Discriminator & 0x7) == 0x7) && (Discriminator & 0xFFFFFFF8);
- }
-
+ // For the regular discriminator, it stands for all empty components if all
+ // the lowest 3 bits are non-zero and all higher 29 bits are unused(zero by
+ // default). Here we fully leverage the higher 29 bits for pseudo probe use.
+ // This is the format:
+ // [2:0] - 0x7
+ // [31:3] - pseudo probe fields guaranteed to be non-zero as a whole
+ // So if the lower 3 bits is non-zero and the others has at least one
+ // non-zero bit, it guarantees to be a pseudo probe discriminator
+ inline static bool isPseudoProbeDiscriminator(unsigned Discriminator) {
+ return ((Discriminator & 0x7) == 0x7) && (Discriminator & 0xFFFFFFF8);
+ }
+
/// Returns a new DILocation with updated \p Discriminator.
inline const DILocation *cloneWithDiscriminator(unsigned Discriminator) const;
@@ -2059,10 +2059,10 @@ public:
return getNumOperands() > 10 ? getOperandAs<Metadata>(10) : nullptr;
}
- void replaceRawLinkageName(MDString *LinkageName) {
- replaceOperandWith(3, LinkageName);
- }
-
+ void replaceRawLinkageName(MDString *LinkageName) {
+ replaceOperandWith(3, LinkageName);
+ }
+
/// Check if this subprogram describes the given function.
///
/// FIXME: Should this be looking through bitcasts?
@@ -2307,52 +2307,52 @@ class DIModule : public DIScope {
friend class LLVMContextImpl;
friend class MDNode;
unsigned LineNo;
- bool IsDecl;
+ bool IsDecl;
DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo,
- bool IsDecl, ArrayRef<Metadata *> Ops)
+ bool IsDecl, ArrayRef<Metadata *> Ops)
: DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops),
- LineNo(LineNo), IsDecl(IsDecl) {}
+ LineNo(LineNo), IsDecl(IsDecl) {}
~DIModule() = default;
static DIModule *getImpl(LLVMContext &Context, DIFile *File, DIScope *Scope,
StringRef Name, StringRef ConfigurationMacros,
StringRef IncludePath, StringRef APINotesFile,
- unsigned LineNo, bool IsDecl, StorageType Storage,
+ unsigned LineNo, bool IsDecl, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, File, Scope, getCanonicalMDString(Context, Name),
getCanonicalMDString(Context, ConfigurationMacros),
getCanonicalMDString(Context, IncludePath),
- getCanonicalMDString(Context, APINotesFile), LineNo, IsDecl,
- Storage, ShouldCreate);
+ getCanonicalMDString(Context, APINotesFile), LineNo, IsDecl,
+ Storage, ShouldCreate);
}
static DIModule *getImpl(LLVMContext &Context, Metadata *File,
Metadata *Scope, MDString *Name,
MDString *ConfigurationMacros, MDString *IncludePath,
- MDString *APINotesFile, unsigned LineNo, bool IsDecl,
+ MDString *APINotesFile, unsigned LineNo, bool IsDecl,
StorageType Storage, bool ShouldCreate = true);
TempDIModule cloneImpl() const {
return getTemporary(getContext(), getFile(), getScope(), getName(),
getConfigurationMacros(), getIncludePath(),
- getAPINotesFile(), getLineNo(), getIsDecl());
+ getAPINotesFile(), getLineNo(), getIsDecl());
}
public:
DEFINE_MDNODE_GET(DIModule,
(DIFile * File, DIScope *Scope, StringRef Name,
StringRef ConfigurationMacros, StringRef IncludePath,
- StringRef APINotesFile, unsigned LineNo,
- bool IsDecl = false),
+ StringRef APINotesFile, unsigned LineNo,
+ bool IsDecl = false),
(File, Scope, Name, ConfigurationMacros, IncludePath,
- APINotesFile, LineNo, IsDecl))
+ APINotesFile, LineNo, IsDecl))
DEFINE_MDNODE_GET(DIModule,
(Metadata * File, Metadata *Scope, MDString *Name,
MDString *ConfigurationMacros, MDString *IncludePath,
- MDString *APINotesFile, unsigned LineNo,
- bool IsDecl = false),
+ MDString *APINotesFile, unsigned LineNo,
+ bool IsDecl = false),
(File, Scope, Name, ConfigurationMacros, IncludePath,
- APINotesFile, LineNo, IsDecl))
+ APINotesFile, LineNo, IsDecl))
TempDIModule clone() const { return cloneImpl(); }
@@ -2362,7 +2362,7 @@ public:
StringRef getIncludePath() const { return getStringOperand(4); }
StringRef getAPINotesFile() const { return getStringOperand(5); }
unsigned getLineNo() const { return LineNo; }
- bool getIsDecl() const { return IsDecl; }
+ bool getIsDecl() const { return IsDecl; }
Metadata *getRawScope() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); }
@@ -2597,9 +2597,9 @@ public:
/// Determine whether this represents a standalone constant value.
bool isConstant() const;
- /// Determine whether this represents a standalone signed constant value.
- bool isSignedConstant() const;
-
+ /// Determine whether this represents a standalone signed constant value.
+ bool isSignedConstant() const;
+
using element_iterator = ArrayRef<uint64_t>::iterator;
element_iterator elements_begin() const { return getElements().begin(); }
diff --git a/contrib/libs/llvm12/include/llvm/IR/DebugLoc.h b/contrib/libs/llvm12/include/llvm/IR/DebugLoc.h
index 2abf29f04c..afcef7a1c7 100644
--- a/contrib/libs/llvm12/include/llvm/IR/DebugLoc.h
+++ b/contrib/libs/llvm12/include/llvm/IR/DebugLoc.h
@@ -81,7 +81,7 @@ namespace llvm {
/// \param InlinedAt The new outermost inlined-at in the chain.
static DebugLoc appendInlinedAt(const DebugLoc &DL, DILocation *InlinedAt,
LLVMContext &Ctx,
- DenseMap<const MDNode *, MDNode *> &Cache);
+ DenseMap<const MDNode *, MDNode *> &Cache);
unsigned getLine() const;
unsigned getCol() const;
diff --git a/contrib/libs/llvm12/include/llvm/IR/DerivedTypes.h b/contrib/libs/llvm12/include/llvm/IR/DerivedTypes.h
index 80844697a1..b941f64041 100644
--- a/contrib/libs/llvm12/include/llvm/IR/DerivedTypes.h
+++ b/contrib/libs/llvm12/include/llvm/IR/DerivedTypes.h
@@ -274,10 +274,10 @@ public:
return llvm::StructType::get(Ctx, StructFields);
}
- /// Return the type with the specified name, or null if there is none by that
- /// name.
- static StructType *getTypeByName(LLVMContext &C, StringRef Name);
-
+ /// Return the type with the specified name, or null if there is none by that
+ /// name.
+ static StructType *getTypeByName(LLVMContext &C, StringRef Name);
+
bool isPacked() const { return (getSubclassData() & SCDB_Packed) != 0; }
/// Return true if this type is uniqued by structural equivalence, false if it
@@ -291,9 +291,9 @@ public:
/// isSized - Return true if this is a sized type.
bool isSized(SmallPtrSetImpl<Type *> *Visited = nullptr) const;
- /// Returns true if this struct contains a scalable vector.
- bool containsScalableVectorType() const;
-
+ /// Returns true if this struct contains a scalable vector.
+ bool containsScalableVectorType() const;
+
/// Return true if this is a named struct that has a non-empty name.
bool hasName() const { return SymbolTableEntry != nullptr; }
@@ -431,11 +431,11 @@ public:
/// Get the number of elements in this vector. It does not make sense to call
/// this function on a scalable vector, and this will be moved into
/// FixedVectorType in a future commit
- LLVM_ATTRIBUTE_DEPRECATED(
- inline unsigned getNumElements() const,
- "Calling this function via a base VectorType is deprecated. Either call "
- "getElementCount() and handle the case where Scalable is true or cast to "
- "FixedVectorType.");
+ LLVM_ATTRIBUTE_DEPRECATED(
+ inline unsigned getNumElements() const,
+ "Calling this function via a base VectorType is deprecated. Either call "
+ "getElementCount() and handle the case where Scalable is true or cast to "
+ "FixedVectorType.");
Type *getElementType() const { return ContainedType; }
@@ -444,8 +444,8 @@ public:
static VectorType *get(Type *ElementType, unsigned NumElements,
bool Scalable) {
- return VectorType::get(ElementType,
- ElementCount::get(NumElements, Scalable));
+ return VectorType::get(ElementType,
+ ElementCount::get(NumElements, Scalable));
}
static VectorType *get(Type *ElementType, const VectorType *Other) {
@@ -510,18 +510,18 @@ public:
/// input type and the same element type.
static VectorType *getHalfElementsVectorType(VectorType *VTy) {
auto EltCnt = VTy->getElementCount();
- assert(EltCnt.isKnownEven() &&
- "Cannot halve vector with odd number of elements.");
- return VectorType::get(VTy->getElementType(),
- EltCnt.divideCoefficientBy(2));
+ assert(EltCnt.isKnownEven() &&
+ "Cannot halve vector with odd number of elements.");
+ return VectorType::get(VTy->getElementType(),
+ EltCnt.divideCoefficientBy(2));
}
/// This static method returns a VectorType with twice as many elements as the
/// input type and the same element type.
static VectorType *getDoubleElementsVectorType(VectorType *VTy) {
auto EltCnt = VTy->getElementCount();
- assert((EltCnt.getKnownMinValue() * 2ull) <= UINT_MAX &&
- "Too many elements in vector");
+ assert((EltCnt.getKnownMinValue() * 2ull) <= UINT_MAX &&
+ "Too many elements in vector");
return VectorType::get(VTy->getElementType(), EltCnt * 2);
}
@@ -539,19 +539,19 @@ public:
}
};
-unsigned VectorType::getNumElements() const {
- ElementCount EC = getElementCount();
-#ifdef STRICT_FIXED_SIZE_VECTORS
- assert(!EC.isScalable() &&
- "Request for fixed number of elements from scalable vector");
-#else
- if (EC.isScalable())
- WithColor::warning()
- << "The code that requested the fixed number of elements has made the "
- "assumption that this vector is not scalable. This assumption was "
- "not correct, and this may lead to broken code\n";
-#endif
- return EC.getKnownMinValue();
+unsigned VectorType::getNumElements() const {
+ ElementCount EC = getElementCount();
+#ifdef STRICT_FIXED_SIZE_VECTORS
+ assert(!EC.isScalable() &&
+ "Request for fixed number of elements from scalable vector");
+#else
+ if (EC.isScalable())
+ WithColor::warning()
+ << "The code that requested the fixed number of elements has made the "
+ "assumption that this vector is not scalable. This assumption was "
+ "not correct, and this may lead to broken code\n";
+#endif
+ return EC.getKnownMinValue();
}
/// Class to represent fixed width SIMD vectors
@@ -597,8 +597,8 @@ public:
static bool classof(const Type *T) {
return T->getTypeID() == FixedVectorTyID;
}
-
- unsigned getNumElements() const { return ElementQuantity; }
+
+ unsigned getNumElements() const { return ElementQuantity; }
};
/// Class to represent scalable SIMD vectors
@@ -658,7 +658,7 @@ public:
};
inline ElementCount VectorType::getElementCount() const {
- return ElementCount::get(ElementQuantity, isa<ScalableVectorType>(this));
+ return ElementCount::get(ElementQuantity, isa<ScalableVectorType>(this));
}
/// Class to represent pointers.
diff --git a/contrib/libs/llvm12/include/llvm/IR/DiagnosticInfo.h b/contrib/libs/llvm12/include/llvm/IR/DiagnosticInfo.h
index e9afb40e8f..d1cd27e15c 100644
--- a/contrib/libs/llvm12/include/llvm/IR/DiagnosticInfo.h
+++ b/contrib/libs/llvm12/include/llvm/IR/DiagnosticInfo.h
@@ -28,7 +28,7 @@
#include "llvm/ADT/Twine.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/Support/CBindingWrapping.h"
-#include "llvm/Support/TypeSize.h"
+#include "llvm/Support/TypeSize.h"
#include "llvm/Support/YAMLTraits.h"
#include <algorithm>
#include <cstdint>
@@ -42,7 +42,7 @@ namespace llvm {
class DiagnosticPrinter;
class Function;
class Instruction;
-class InstructionCost;
+class InstructionCost;
class LLVMContext;
class Module;
class SMDiagnostic;
@@ -442,10 +442,10 @@ public:
Argument(StringRef Key, unsigned N);
Argument(StringRef Key, unsigned long N);
Argument(StringRef Key, unsigned long long N);
- Argument(StringRef Key, ElementCount EC);
+ Argument(StringRef Key, ElementCount EC);
Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
Argument(StringRef Key, DebugLoc dl);
- Argument(StringRef Key, InstructionCost C);
+ Argument(StringRef Key, InstructionCost C);
};
/// \p PassName is the name of the pass emitting this diagnostic. \p
diff --git a/contrib/libs/llvm12/include/llvm/IR/Dominators.h b/contrib/libs/llvm12/include/llvm/IR/Dominators.h
index 5eee5d70e1..bab2ec18c0 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Dominators.h
+++ b/contrib/libs/llvm12/include/llvm/IR/Dominators.h
@@ -51,9 +51,9 @@ using BBPostDomTree = PostDomTreeBase<BasicBlock>;
using BBUpdates = ArrayRef<llvm::cfg::Update<BasicBlock *>>;
-using BBDomTreeGraphDiff = GraphDiff<BasicBlock *, false>;
-using BBPostDomTreeGraphDiff = GraphDiff<BasicBlock *, true>;
-
+using BBDomTreeGraphDiff = GraphDiff<BasicBlock *, false>;
+using BBPostDomTreeGraphDiff = GraphDiff<BasicBlock *, true>;
+
extern template void Calculate<BBDomTree>(BBDomTree &DT);
extern template void CalculateWithUpdates<BBDomTree>(BBDomTree &DT,
BBUpdates U);
@@ -72,12 +72,12 @@ extern template void DeleteEdge<BBPostDomTree>(BBPostDomTree &DT,
BasicBlock *From,
BasicBlock *To);
-extern template void ApplyUpdates<BBDomTree>(BBDomTree &DT,
- BBDomTreeGraphDiff &,
- BBDomTreeGraphDiff *);
-extern template void ApplyUpdates<BBPostDomTree>(BBPostDomTree &DT,
- BBPostDomTreeGraphDiff &,
- BBPostDomTreeGraphDiff *);
+extern template void ApplyUpdates<BBDomTree>(BBDomTree &DT,
+ BBDomTreeGraphDiff &,
+ BBDomTreeGraphDiff *);
+extern template void ApplyUpdates<BBPostDomTree>(BBPostDomTree &DT,
+ BBPostDomTreeGraphDiff &,
+ BBPostDomTreeGraphDiff *);
extern template bool Verify<BBDomTree>(const BBDomTree &DT,
BBDomTree::VerificationLevel VL);
@@ -172,21 +172,21 @@ class DominatorTree : public DominatorTreeBase<BasicBlock, false> {
// Ensure base-class overloads are visible.
using Base::dominates;
- /// Return true if value Def dominates use U, in the sense that Def is
- /// available at U, and could be substituted as the used value without
- /// violating the SSA dominance requirement.
+ /// Return true if value Def dominates use U, in the sense that Def is
+ /// available at U, and could be substituted as the used value without
+ /// violating the SSA dominance requirement.
///
- /// In particular, it is worth noting that:
- /// * Non-instruction Defs dominate everything.
- /// * Def does not dominate a use in Def itself (outside of degenerate cases
- /// like unreachable code or trivial phi cycles).
- /// * Invoke/callbr Defs only dominate uses in their default destination.
- bool dominates(const Value *Def, const Use &U) const;
- /// Return true if value Def dominates all possible uses inside instruction
- /// User. Same comments as for the Use-based API apply.
- bool dominates(const Value *Def, const Instruction *User) const;
- // Does not accept Value to avoid ambiguity with dominance checks between
- // two basic blocks.
+ /// In particular, it is worth noting that:
+ /// * Non-instruction Defs dominate everything.
+ /// * Def does not dominate a use in Def itself (outside of degenerate cases
+ /// like unreachable code or trivial phi cycles).
+ /// * Invoke/callbr Defs only dominate uses in their default destination.
+ bool dominates(const Value *Def, const Use &U) const;
+ /// Return true if value Def dominates all possible uses inside instruction
+ /// User. Same comments as for the Use-based API apply.
+ bool dominates(const Value *Def, const Instruction *User) const;
+ // Does not accept Value to avoid ambiguity with dominance checks between
+ // two basic blocks.
bool dominates(const Instruction *Def, const BasicBlock *BB) const;
/// Return true if an edge dominates a use.
diff --git a/contrib/libs/llvm12/include/llvm/IR/FixedMetadataKinds.def b/contrib/libs/llvm12/include/llvm/IR/FixedMetadataKinds.def
index 6a6aeed203..31979cd2f9 100644
--- a/contrib/libs/llvm12/include/llvm/IR/FixedMetadataKinds.def
+++ b/contrib/libs/llvm12/include/llvm/IR/FixedMetadataKinds.def
@@ -39,6 +39,6 @@ LLVM_FIXED_MD_KIND(MD_irr_loop, "irr_loop", 24)
LLVM_FIXED_MD_KIND(MD_access_group, "llvm.access.group", 25)
LLVM_FIXED_MD_KIND(MD_callback, "callback", 26)
LLVM_FIXED_MD_KIND(MD_preserve_access_index, "llvm.preserve.access.index", 27)
-LLVM_FIXED_MD_KIND(MD_vcall_visibility, "vcall_visibility", 28)
-LLVM_FIXED_MD_KIND(MD_noundef, "noundef", 29)
-LLVM_FIXED_MD_KIND(MD_annotation, "annotation", 30)
+LLVM_FIXED_MD_KIND(MD_vcall_visibility, "vcall_visibility", 28)
+LLVM_FIXED_MD_KIND(MD_noundef, "noundef", 29)
+LLVM_FIXED_MD_KIND(MD_annotation, "annotation", 30)
diff --git a/contrib/libs/llvm12/include/llvm/IR/FixedPointBuilder.h b/contrib/libs/llvm12/include/llvm/IR/FixedPointBuilder.h
index f457cd8817..1c4b0332d1 100644
--- a/contrib/libs/llvm12/include/llvm/IR/FixedPointBuilder.h
+++ b/contrib/libs/llvm12/include/llvm/IR/FixedPointBuilder.h
@@ -1,476 +1,476 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- llvm/FixedPointBuilder.h - Builder for fixed-point ops ---*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the FixedPointBuilder class, which is used as a convenient
-// way to lower fixed-point arithmetic operations to LLVM IR.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_IR_FIXEDPOINTBUILDER_H
-#define LLVM_IR_FIXEDPOINTBUILDER_H
-
-#include "llvm/ADT/APFixedPoint.h"
-#include "llvm/IR/Constant.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/InstrTypes.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/Intrinsics.h"
-#include "llvm/IR/Type.h"
-#include "llvm/IR/Value.h"
-
-namespace llvm {
-
-template <class IRBuilderTy> class FixedPointBuilder {
- IRBuilderTy &B;
-
- Value *Convert(Value *Src, const FixedPointSemantics &SrcSema,
- const FixedPointSemantics &DstSema, bool DstIsInteger) {
- unsigned SrcWidth = SrcSema.getWidth();
- unsigned DstWidth = DstSema.getWidth();
- unsigned SrcScale = SrcSema.getScale();
- unsigned DstScale = DstSema.getScale();
- bool SrcIsSigned = SrcSema.isSigned();
- bool DstIsSigned = DstSema.isSigned();
-
- Type *DstIntTy = B.getIntNTy(DstWidth);
-
- Value *Result = Src;
- unsigned ResultWidth = SrcWidth;
-
- // Downscale.
- if (DstScale < SrcScale) {
- // When converting to integers, we round towards zero. For negative
- // numbers, right shifting rounds towards negative infinity. In this case,
- // we can just round up before shifting.
- if (DstIsInteger && SrcIsSigned) {
- Value *Zero = Constant::getNullValue(Result->getType());
- Value *IsNegative = B.CreateICmpSLT(Result, Zero);
- Value *LowBits = ConstantInt::get(
- B.getContext(), APInt::getLowBitsSet(ResultWidth, SrcScale));
- Value *Rounded = B.CreateAdd(Result, LowBits);
- Result = B.CreateSelect(IsNegative, Rounded, Result);
- }
-
- Result = SrcIsSigned
- ? B.CreateAShr(Result, SrcScale - DstScale, "downscale")
- : B.CreateLShr(Result, SrcScale - DstScale, "downscale");
- }
-
- if (!DstSema.isSaturated()) {
- // Resize.
- Result = B.CreateIntCast(Result, DstIntTy, SrcIsSigned, "resize");
-
- // Upscale.
- if (DstScale > SrcScale)
- Result = B.CreateShl(Result, DstScale - SrcScale, "upscale");
- } else {
- // Adjust the number of fractional bits.
- if (DstScale > SrcScale) {
- // Compare to DstWidth to prevent resizing twice.
- ResultWidth = std::max(SrcWidth + DstScale - SrcScale, DstWidth);
- Type *UpscaledTy = B.getIntNTy(ResultWidth);
- Result = B.CreateIntCast(Result, UpscaledTy, SrcIsSigned, "resize");
- Result = B.CreateShl(Result, DstScale - SrcScale, "upscale");
- }
-
- // Handle saturation.
- bool LessIntBits = DstSema.getIntegralBits() < SrcSema.getIntegralBits();
- if (LessIntBits) {
- Value *Max = ConstantInt::get(
- B.getContext(),
- APFixedPoint::getMax(DstSema).getValue().extOrTrunc(ResultWidth));
- Value *TooHigh = SrcIsSigned ? B.CreateICmpSGT(Result, Max)
- : B.CreateICmpUGT(Result, Max);
- Result = B.CreateSelect(TooHigh, Max, Result, "satmax");
- }
- // Cannot overflow min to dest type if src is unsigned since all fixed
- // point types can cover the unsigned min of 0.
- if (SrcIsSigned && (LessIntBits || !DstIsSigned)) {
- Value *Min = ConstantInt::get(
- B.getContext(),
- APFixedPoint::getMin(DstSema).getValue().extOrTrunc(ResultWidth));
- Value *TooLow = B.CreateICmpSLT(Result, Min);
- Result = B.CreateSelect(TooLow, Min, Result, "satmin");
- }
-
- // Resize the integer part to get the final destination size.
- if (ResultWidth != DstWidth)
- Result = B.CreateIntCast(Result, DstIntTy, SrcIsSigned, "resize");
- }
- return Result;
- }
-
- /// Get the common semantic for two semantics, with the added imposition that
- /// saturated padded types retain the padding bit.
- FixedPointSemantics
- getCommonBinopSemantic(const FixedPointSemantics &LHSSema,
- const FixedPointSemantics &RHSSema) {
- auto C = LHSSema.getCommonSemantics(RHSSema);
- bool BothPadded =
- LHSSema.hasUnsignedPadding() && RHSSema.hasUnsignedPadding();
- return FixedPointSemantics(
- C.getWidth() + (unsigned)(BothPadded && C.isSaturated()), C.getScale(),
- C.isSigned(), C.isSaturated(), BothPadded);
- }
-
- /// Given a floating point type and a fixed-point semantic, return a floating
- /// point type which can accommodate the fixed-point semantic. This is either
- /// \p Ty, or a floating point type with a larger exponent than Ty.
- Type *getAccommodatingFloatType(Type *Ty, const FixedPointSemantics &Sema) {
- const fltSemantics *FloatSema = &Ty->getFltSemantics();
- while (!Sema.fitsInFloatSemantics(*FloatSema))
- FloatSema = APFixedPoint::promoteFloatSemantics(FloatSema);
- return Type::getFloatingPointTy(Ty->getContext(), *FloatSema);
- }
-
-public:
- FixedPointBuilder(IRBuilderTy &Builder) : B(Builder) {}
-
- /// Convert an integer value representing a fixed-point number from one
- /// fixed-point semantic to another fixed-point semantic.
- /// \p Src - The source value
- /// \p SrcSema - The fixed-point semantic of the source value
- /// \p DstSema - The resulting fixed-point semantic
- Value *CreateFixedToFixed(Value *Src, const FixedPointSemantics &SrcSema,
- const FixedPointSemantics &DstSema) {
- return Convert(Src, SrcSema, DstSema, false);
- }
-
- /// Convert an integer value representing a fixed-point number to an integer
- /// with the given bit width and signedness.
- /// \p Src - The source value
- /// \p SrcSema - The fixed-point semantic of the source value
- /// \p DstWidth - The bit width of the result value
- /// \p DstIsSigned - The signedness of the result value
- Value *CreateFixedToInteger(Value *Src, const FixedPointSemantics &SrcSema,
- unsigned DstWidth, bool DstIsSigned) {
- return Convert(
- Src, SrcSema,
- FixedPointSemantics::GetIntegerSemantics(DstWidth, DstIsSigned), true);
- }
-
- /// Convert an integer value with the given signedness to an integer value
- /// representing the given fixed-point semantic.
- /// \p Src - The source value
- /// \p SrcIsSigned - The signedness of the source value
- /// \p DstSema - The resulting fixed-point semantic
- Value *CreateIntegerToFixed(Value *Src, unsigned SrcIsSigned,
- const FixedPointSemantics &DstSema) {
- return Convert(Src,
- FixedPointSemantics::GetIntegerSemantics(
- Src->getType()->getScalarSizeInBits(), SrcIsSigned),
- DstSema, false);
- }
-
- Value *CreateFixedToFloating(Value *Src, const FixedPointSemantics &SrcSema,
- Type *DstTy) {
- Value *Result;
- Type *OpTy = getAccommodatingFloatType(DstTy, SrcSema);
- // Convert the raw fixed-point value directly to floating point. If the
- // value is too large to fit, it will be rounded, not truncated.
- Result = SrcSema.isSigned() ? B.CreateSIToFP(Src, OpTy)
- : B.CreateUIToFP(Src, OpTy);
- // Rescale the integral-in-floating point by the scaling factor. This is
- // lossless, except for overflow to infinity which is unlikely.
- Result = B.CreateFMul(Result,
- ConstantFP::get(OpTy, std::pow(2, -(int)SrcSema.getScale())));
- if (OpTy != DstTy)
- Result = B.CreateFPTrunc(Result, DstTy);
- return Result;
- }
-
- Value *CreateFloatingToFixed(Value *Src, const FixedPointSemantics &DstSema) {
- bool UseSigned = DstSema.isSigned() || DstSema.hasUnsignedPadding();
- Value *Result = Src;
- Type *OpTy = getAccommodatingFloatType(Src->getType(), DstSema);
- if (OpTy != Src->getType())
- Result = B.CreateFPExt(Result, OpTy);
- // Rescale the floating point value so that its significant bits (for the
- // purposes of the conversion) are in the integral range.
- Result = B.CreateFMul(Result,
- ConstantFP::get(OpTy, std::pow(2, DstSema.getScale())));
-
- Type *ResultTy = B.getIntNTy(DstSema.getWidth());
- if (DstSema.isSaturated()) {
- Intrinsic::ID IID =
- UseSigned ? Intrinsic::fptosi_sat : Intrinsic::fptoui_sat;
- Result = B.CreateIntrinsic(IID, {ResultTy, OpTy}, {Result});
- } else {
- Result = UseSigned ? B.CreateFPToSI(Result, ResultTy)
- : B.CreateFPToUI(Result, ResultTy);
- }
-
- // When saturating unsigned-with-padding using signed operations, we may
- // get negative values. Emit an extra clamp to zero.
- if (DstSema.isSaturated() && DstSema.hasUnsignedPadding()) {
- Constant *Zero = Constant::getNullValue(Result->getType());
- Result =
- B.CreateSelect(B.CreateICmpSLT(Result, Zero), Zero, Result, "satmin");
- }
-
- return Result;
- }
-
- /// Add two fixed-point values and return the result in their common semantic.
- /// \p LHS - The left hand side
- /// \p LHSSema - The semantic of the left hand side
- /// \p RHS - The right hand side
- /// \p RHSSema - The semantic of the right hand side
- Value *CreateAdd(Value *LHS, const FixedPointSemantics &LHSSema,
- Value *RHS, const FixedPointSemantics &RHSSema) {
- auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
- bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();
-
- Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
- Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
-
- Value *Result;
- if (CommonSema.isSaturated()) {
- Intrinsic::ID IID = UseSigned ? Intrinsic::sadd_sat : Intrinsic::uadd_sat;
- Result = B.CreateBinaryIntrinsic(IID, WideLHS, WideRHS);
- } else {
- Result = B.CreateAdd(WideLHS, WideRHS);
- }
-
- return CreateFixedToFixed(Result, CommonSema,
- LHSSema.getCommonSemantics(RHSSema));
- }
-
- /// Subtract two fixed-point values and return the result in their common
- /// semantic.
- /// \p LHS - The left hand side
- /// \p LHSSema - The semantic of the left hand side
- /// \p RHS - The right hand side
- /// \p RHSSema - The semantic of the right hand side
- Value *CreateSub(Value *LHS, const FixedPointSemantics &LHSSema,
- Value *RHS, const FixedPointSemantics &RHSSema) {
- auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
- bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();
-
- Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
- Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
-
- Value *Result;
- if (CommonSema.isSaturated()) {
- Intrinsic::ID IID = UseSigned ? Intrinsic::ssub_sat : Intrinsic::usub_sat;
- Result = B.CreateBinaryIntrinsic(IID, WideLHS, WideRHS);
- } else {
- Result = B.CreateSub(WideLHS, WideRHS);
- }
-
- // Subtraction can end up below 0 for padded unsigned operations, so emit
- // an extra clamp in that case.
- if (CommonSema.isSaturated() && CommonSema.hasUnsignedPadding()) {
- Constant *Zero = Constant::getNullValue(Result->getType());
- Result =
- B.CreateSelect(B.CreateICmpSLT(Result, Zero), Zero, Result, "satmin");
- }
-
- return CreateFixedToFixed(Result, CommonSema,
- LHSSema.getCommonSemantics(RHSSema));
- }
-
- /// Multiply two fixed-point values and return the result in their common
- /// semantic.
- /// \p LHS - The left hand side
- /// \p LHSSema - The semantic of the left hand side
- /// \p RHS - The right hand side
- /// \p RHSSema - The semantic of the right hand side
- Value *CreateMul(Value *LHS, const FixedPointSemantics &LHSSema,
- Value *RHS, const FixedPointSemantics &RHSSema) {
- auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
- bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();
-
- Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
- Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
-
- Intrinsic::ID IID;
- if (CommonSema.isSaturated()) {
- IID = UseSigned ? Intrinsic::smul_fix_sat : Intrinsic::umul_fix_sat;
- } else {
- IID = UseSigned ? Intrinsic::smul_fix : Intrinsic::umul_fix;
- }
- Value *Result = B.CreateIntrinsic(
- IID, {WideLHS->getType()},
- {WideLHS, WideRHS, B.getInt32(CommonSema.getScale())});
-
- return CreateFixedToFixed(Result, CommonSema,
- LHSSema.getCommonSemantics(RHSSema));
- }
-
- /// Divide two fixed-point values and return the result in their common
- /// semantic.
- /// \p LHS - The left hand side
- /// \p LHSSema - The semantic of the left hand side
- /// \p RHS - The right hand side
- /// \p RHSSema - The semantic of the right hand side
- Value *CreateDiv(Value *LHS, const FixedPointSemantics &LHSSema,
- Value *RHS, const FixedPointSemantics &RHSSema) {
- auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
- bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();
-
- Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
- Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
-
- Intrinsic::ID IID;
- if (CommonSema.isSaturated()) {
- IID = UseSigned ? Intrinsic::sdiv_fix_sat : Intrinsic::udiv_fix_sat;
- } else {
- IID = UseSigned ? Intrinsic::sdiv_fix : Intrinsic::udiv_fix;
- }
- Value *Result = B.CreateIntrinsic(
- IID, {WideLHS->getType()},
- {WideLHS, WideRHS, B.getInt32(CommonSema.getScale())});
-
- return CreateFixedToFixed(Result, CommonSema,
- LHSSema.getCommonSemantics(RHSSema));
- }
-
- /// Left shift a fixed-point value by an unsigned integer value. The integer
- /// value can be any bit width.
- /// \p LHS - The left hand side
- /// \p LHSSema - The semantic of the left hand side
- /// \p RHS - The right hand side
- Value *CreateShl(Value *LHS, const FixedPointSemantics &LHSSema, Value *RHS) {
- bool UseSigned = LHSSema.isSigned() || LHSSema.hasUnsignedPadding();
-
- RHS = B.CreateIntCast(RHS, LHS->getType(), /*IsSigned=*/false);
-
- Value *Result;
- if (LHSSema.isSaturated()) {
- Intrinsic::ID IID = UseSigned ? Intrinsic::sshl_sat : Intrinsic::ushl_sat;
- Result = B.CreateBinaryIntrinsic(IID, LHS, RHS);
- } else {
- Result = B.CreateShl(LHS, RHS);
- }
-
- return Result;
- }
-
- /// Right shift a fixed-point value by an unsigned integer value. The integer
- /// value can be any bit width.
- /// \p LHS - The left hand side
- /// \p LHSSema - The semantic of the left hand side
- /// \p RHS - The right hand side
- Value *CreateShr(Value *LHS, const FixedPointSemantics &LHSSema, Value *RHS) {
- RHS = B.CreateIntCast(RHS, LHS->getType(), false);
-
- return LHSSema.isSigned() ? B.CreateAShr(LHS, RHS) : B.CreateLShr(LHS, RHS);
- }
-
- /// Compare two fixed-point values for equality.
- /// \p LHS - The left hand side
- /// \p LHSSema - The semantic of the left hand side
- /// \p RHS - The right hand side
- /// \p RHSSema - The semantic of the right hand side
- Value *CreateEQ(Value *LHS, const FixedPointSemantics &LHSSema,
- Value *RHS, const FixedPointSemantics &RHSSema) {
- auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
-
- Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
- Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
-
- return B.CreateICmpEQ(WideLHS, WideRHS);
- }
-
- /// Compare two fixed-point values for inequality.
- /// \p LHS - The left hand side
- /// \p LHSSema - The semantic of the left hand side
- /// \p RHS - The right hand side
- /// \p RHSSema - The semantic of the right hand side
- Value *CreateNE(Value *LHS, const FixedPointSemantics &LHSSema,
- Value *RHS, const FixedPointSemantics &RHSSema) {
- auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
-
- Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
- Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
-
- return B.CreateICmpNE(WideLHS, WideRHS);
- }
-
- /// Compare two fixed-point values as LHS < RHS.
- /// \p LHS - The left hand side
- /// \p LHSSema - The semantic of the left hand side
- /// \p RHS - The right hand side
- /// \p RHSSema - The semantic of the right hand side
- Value *CreateLT(Value *LHS, const FixedPointSemantics &LHSSema,
- Value *RHS, const FixedPointSemantics &RHSSema) {
- auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
-
- Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
- Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
-
- return CommonSema.isSigned() ? B.CreateICmpSLT(WideLHS, WideRHS)
- : B.CreateICmpULT(WideLHS, WideRHS);
- }
-
- /// Compare two fixed-point values as LHS <= RHS.
- /// \p LHS - The left hand side
- /// \p LHSSema - The semantic of the left hand side
- /// \p RHS - The right hand side
- /// \p RHSSema - The semantic of the right hand side
- Value *CreateLE(Value *LHS, const FixedPointSemantics &LHSSema,
- Value *RHS, const FixedPointSemantics &RHSSema) {
- auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
-
- Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
- Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
-
- return CommonSema.isSigned() ? B.CreateICmpSLE(WideLHS, WideRHS)
- : B.CreateICmpULE(WideLHS, WideRHS);
- }
-
- /// Compare two fixed-point values as LHS > RHS.
- /// \p LHS - The left hand side
- /// \p LHSSema - The semantic of the left hand side
- /// \p RHS - The right hand side
- /// \p RHSSema - The semantic of the right hand side
- Value *CreateGT(Value *LHS, const FixedPointSemantics &LHSSema,
- Value *RHS, const FixedPointSemantics &RHSSema) {
- auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
-
- Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
- Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
-
- return CommonSema.isSigned() ? B.CreateICmpSGT(WideLHS, WideRHS)
- : B.CreateICmpUGT(WideLHS, WideRHS);
- }
-
- /// Compare two fixed-point values as LHS >= RHS.
- /// \p LHS - The left hand side
- /// \p LHSSema - The semantic of the left hand side
- /// \p RHS - The right hand side
- /// \p RHSSema - The semantic of the right hand side
- Value *CreateGE(Value *LHS, const FixedPointSemantics &LHSSema,
- Value *RHS, const FixedPointSemantics &RHSSema) {
- auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
-
- Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
- Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
-
- return CommonSema.isSigned() ? B.CreateICmpSGE(WideLHS, WideRHS)
- : B.CreateICmpUGE(WideLHS, WideRHS);
- }
-};
-
-} // end namespace llvm
-
-#endif // LLVM_IR_FIXEDPOINTBUILDER_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- llvm/FixedPointBuilder.h - Builder for fixed-point ops ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the FixedPointBuilder class, which is used as a convenient
+// way to lower fixed-point arithmetic operations to LLVM IR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_FIXEDPOINTBUILDER_H
+#define LLVM_IR_FIXEDPOINTBUILDER_H
+
+#include "llvm/ADT/APFixedPoint.h"
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Value.h"
+
+namespace llvm {
+
+template <class IRBuilderTy> class FixedPointBuilder {
+ IRBuilderTy &B;
+
+ Value *Convert(Value *Src, const FixedPointSemantics &SrcSema,
+ const FixedPointSemantics &DstSema, bool DstIsInteger) {
+ unsigned SrcWidth = SrcSema.getWidth();
+ unsigned DstWidth = DstSema.getWidth();
+ unsigned SrcScale = SrcSema.getScale();
+ unsigned DstScale = DstSema.getScale();
+ bool SrcIsSigned = SrcSema.isSigned();
+ bool DstIsSigned = DstSema.isSigned();
+
+ Type *DstIntTy = B.getIntNTy(DstWidth);
+
+ Value *Result = Src;
+ unsigned ResultWidth = SrcWidth;
+
+ // Downscale.
+ if (DstScale < SrcScale) {
+ // When converting to integers, we round towards zero. For negative
+ // numbers, right shifting rounds towards negative infinity. In this case,
+ // we can just round up before shifting.
+ if (DstIsInteger && SrcIsSigned) {
+ Value *Zero = Constant::getNullValue(Result->getType());
+ Value *IsNegative = B.CreateICmpSLT(Result, Zero);
+ Value *LowBits = ConstantInt::get(
+ B.getContext(), APInt::getLowBitsSet(ResultWidth, SrcScale));
+ Value *Rounded = B.CreateAdd(Result, LowBits);
+ Result = B.CreateSelect(IsNegative, Rounded, Result);
+ }
+
+ Result = SrcIsSigned
+ ? B.CreateAShr(Result, SrcScale - DstScale, "downscale")
+ : B.CreateLShr(Result, SrcScale - DstScale, "downscale");
+ }
+
+ if (!DstSema.isSaturated()) {
+ // Resize.
+ Result = B.CreateIntCast(Result, DstIntTy, SrcIsSigned, "resize");
+
+ // Upscale.
+ if (DstScale > SrcScale)
+ Result = B.CreateShl(Result, DstScale - SrcScale, "upscale");
+ } else {
+ // Adjust the number of fractional bits.
+ if (DstScale > SrcScale) {
+ // Compare to DstWidth to prevent resizing twice.
+ ResultWidth = std::max(SrcWidth + DstScale - SrcScale, DstWidth);
+ Type *UpscaledTy = B.getIntNTy(ResultWidth);
+ Result = B.CreateIntCast(Result, UpscaledTy, SrcIsSigned, "resize");
+ Result = B.CreateShl(Result, DstScale - SrcScale, "upscale");
+ }
+
+ // Handle saturation.
+ bool LessIntBits = DstSema.getIntegralBits() < SrcSema.getIntegralBits();
+ if (LessIntBits) {
+ Value *Max = ConstantInt::get(
+ B.getContext(),
+ APFixedPoint::getMax(DstSema).getValue().extOrTrunc(ResultWidth));
+ Value *TooHigh = SrcIsSigned ? B.CreateICmpSGT(Result, Max)
+ : B.CreateICmpUGT(Result, Max);
+ Result = B.CreateSelect(TooHigh, Max, Result, "satmax");
+ }
+ // Cannot overflow min to dest type if src is unsigned since all fixed
+ // point types can cover the unsigned min of 0.
+ if (SrcIsSigned && (LessIntBits || !DstIsSigned)) {
+ Value *Min = ConstantInt::get(
+ B.getContext(),
+ APFixedPoint::getMin(DstSema).getValue().extOrTrunc(ResultWidth));
+ Value *TooLow = B.CreateICmpSLT(Result, Min);
+ Result = B.CreateSelect(TooLow, Min, Result, "satmin");
+ }
+
+ // Resize the integer part to get the final destination size.
+ if (ResultWidth != DstWidth)
+ Result = B.CreateIntCast(Result, DstIntTy, SrcIsSigned, "resize");
+ }
+ return Result;
+ }
+
+ /// Get the common semantic for two semantics, with the added imposition that
+ /// saturated padded types retain the padding bit.
+ FixedPointSemantics
+ getCommonBinopSemantic(const FixedPointSemantics &LHSSema,
+ const FixedPointSemantics &RHSSema) {
+ auto C = LHSSema.getCommonSemantics(RHSSema);
+ bool BothPadded =
+ LHSSema.hasUnsignedPadding() && RHSSema.hasUnsignedPadding();
+ return FixedPointSemantics(
+ C.getWidth() + (unsigned)(BothPadded && C.isSaturated()), C.getScale(),
+ C.isSigned(), C.isSaturated(), BothPadded);
+ }
+
+ /// Given a floating point type and a fixed-point semantic, return a floating
+ /// point type which can accommodate the fixed-point semantic. This is either
+ /// \p Ty, or a floating point type with a larger exponent than Ty.
+ Type *getAccommodatingFloatType(Type *Ty, const FixedPointSemantics &Sema) {
+ const fltSemantics *FloatSema = &Ty->getFltSemantics();
+ while (!Sema.fitsInFloatSemantics(*FloatSema))
+ FloatSema = APFixedPoint::promoteFloatSemantics(FloatSema);
+ return Type::getFloatingPointTy(Ty->getContext(), *FloatSema);
+ }
+
+public:
+ FixedPointBuilder(IRBuilderTy &Builder) : B(Builder) {}
+
+ /// Convert an integer value representing a fixed-point number from one
+ /// fixed-point semantic to another fixed-point semantic.
+ /// \p Src - The source value
+ /// \p SrcSema - The fixed-point semantic of the source value
+ /// \p DstSema - The resulting fixed-point semantic
+ Value *CreateFixedToFixed(Value *Src, const FixedPointSemantics &SrcSema,
+ const FixedPointSemantics &DstSema) {
+ return Convert(Src, SrcSema, DstSema, false);
+ }
+
+ /// Convert an integer value representing a fixed-point number to an integer
+ /// with the given bit width and signedness.
+ /// \p Src - The source value
+ /// \p SrcSema - The fixed-point semantic of the source value
+ /// \p DstWidth - The bit width of the result value
+ /// \p DstIsSigned - The signedness of the result value
+ Value *CreateFixedToInteger(Value *Src, const FixedPointSemantics &SrcSema,
+ unsigned DstWidth, bool DstIsSigned) {
+ return Convert(
+ Src, SrcSema,
+ FixedPointSemantics::GetIntegerSemantics(DstWidth, DstIsSigned), true);
+ }
+
+ /// Convert an integer value with the given signedness to an integer value
+ /// representing the given fixed-point semantic.
+ /// \p Src - The source value
+ /// \p SrcIsSigned - The signedness of the source value
+ /// \p DstSema - The resulting fixed-point semantic
+ Value *CreateIntegerToFixed(Value *Src, unsigned SrcIsSigned,
+ const FixedPointSemantics &DstSema) {
+ return Convert(Src,
+ FixedPointSemantics::GetIntegerSemantics(
+ Src->getType()->getScalarSizeInBits(), SrcIsSigned),
+ DstSema, false);
+ }
+
+ Value *CreateFixedToFloating(Value *Src, const FixedPointSemantics &SrcSema,
+ Type *DstTy) {
+ Value *Result;
+ Type *OpTy = getAccommodatingFloatType(DstTy, SrcSema);
+ // Convert the raw fixed-point value directly to floating point. If the
+ // value is too large to fit, it will be rounded, not truncated.
+ Result = SrcSema.isSigned() ? B.CreateSIToFP(Src, OpTy)
+ : B.CreateUIToFP(Src, OpTy);
+ // Rescale the integral-in-floating point by the scaling factor. This is
+ // lossless, except for overflow to infinity which is unlikely.
+ Result = B.CreateFMul(Result,
+ ConstantFP::get(OpTy, std::pow(2, -(int)SrcSema.getScale())));
+ if (OpTy != DstTy)
+ Result = B.CreateFPTrunc(Result, DstTy);
+ return Result;
+ }
+
+ Value *CreateFloatingToFixed(Value *Src, const FixedPointSemantics &DstSema) {
+ bool UseSigned = DstSema.isSigned() || DstSema.hasUnsignedPadding();
+ Value *Result = Src;
+ Type *OpTy = getAccommodatingFloatType(Src->getType(), DstSema);
+ if (OpTy != Src->getType())
+ Result = B.CreateFPExt(Result, OpTy);
+ // Rescale the floating point value so that its significant bits (for the
+ // purposes of the conversion) are in the integral range.
+ Result = B.CreateFMul(Result,
+ ConstantFP::get(OpTy, std::pow(2, DstSema.getScale())));
+
+ Type *ResultTy = B.getIntNTy(DstSema.getWidth());
+ if (DstSema.isSaturated()) {
+ Intrinsic::ID IID =
+ UseSigned ? Intrinsic::fptosi_sat : Intrinsic::fptoui_sat;
+ Result = B.CreateIntrinsic(IID, {ResultTy, OpTy}, {Result});
+ } else {
+ Result = UseSigned ? B.CreateFPToSI(Result, ResultTy)
+ : B.CreateFPToUI(Result, ResultTy);
+ }
+
+ // When saturating unsigned-with-padding using signed operations, we may
+ // get negative values. Emit an extra clamp to zero.
+ if (DstSema.isSaturated() && DstSema.hasUnsignedPadding()) {
+ Constant *Zero = Constant::getNullValue(Result->getType());
+ Result =
+ B.CreateSelect(B.CreateICmpSLT(Result, Zero), Zero, Result, "satmin");
+ }
+
+ return Result;
+ }
+
+ /// Add two fixed-point values and return the result in their common semantic.
+ /// \p LHS - The left hand side
+ /// \p LHSSema - The semantic of the left hand side
+ /// \p RHS - The right hand side
+ /// \p RHSSema - The semantic of the right hand side
+ Value *CreateAdd(Value *LHS, const FixedPointSemantics &LHSSema,
+ Value *RHS, const FixedPointSemantics &RHSSema) {
+ auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
+ bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();
+
+ Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
+ Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
+
+ Value *Result;
+ if (CommonSema.isSaturated()) {
+ Intrinsic::ID IID = UseSigned ? Intrinsic::sadd_sat : Intrinsic::uadd_sat;
+ Result = B.CreateBinaryIntrinsic(IID, WideLHS, WideRHS);
+ } else {
+ Result = B.CreateAdd(WideLHS, WideRHS);
+ }
+
+ return CreateFixedToFixed(Result, CommonSema,
+ LHSSema.getCommonSemantics(RHSSema));
+ }
+
+ /// Subtract two fixed-point values and return the result in their common
+ /// semantic.
+ /// \p LHS - The left hand side
+ /// \p LHSSema - The semantic of the left hand side
+ /// \p RHS - The right hand side
+ /// \p RHSSema - The semantic of the right hand side
+ Value *CreateSub(Value *LHS, const FixedPointSemantics &LHSSema,
+ Value *RHS, const FixedPointSemantics &RHSSema) {
+ auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
+ bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();
+
+ Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
+ Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
+
+ Value *Result;
+ if (CommonSema.isSaturated()) {
+ Intrinsic::ID IID = UseSigned ? Intrinsic::ssub_sat : Intrinsic::usub_sat;
+ Result = B.CreateBinaryIntrinsic(IID, WideLHS, WideRHS);
+ } else {
+ Result = B.CreateSub(WideLHS, WideRHS);
+ }
+
+ // Subtraction can end up below 0 for padded unsigned operations, so emit
+ // an extra clamp in that case.
+ if (CommonSema.isSaturated() && CommonSema.hasUnsignedPadding()) {
+ Constant *Zero = Constant::getNullValue(Result->getType());
+ Result =
+ B.CreateSelect(B.CreateICmpSLT(Result, Zero), Zero, Result, "satmin");
+ }
+
+ return CreateFixedToFixed(Result, CommonSema,
+ LHSSema.getCommonSemantics(RHSSema));
+ }
+
+ /// Multiply two fixed-point values and return the result in their common
+ /// semantic.
+ /// \p LHS - The left hand side
+ /// \p LHSSema - The semantic of the left hand side
+ /// \p RHS - The right hand side
+ /// \p RHSSema - The semantic of the right hand side
+ Value *CreateMul(Value *LHS, const FixedPointSemantics &LHSSema,
+ Value *RHS, const FixedPointSemantics &RHSSema) {
+ auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
+ bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();
+
+ Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
+ Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
+
+ Intrinsic::ID IID;
+ if (CommonSema.isSaturated()) {
+ IID = UseSigned ? Intrinsic::smul_fix_sat : Intrinsic::umul_fix_sat;
+ } else {
+ IID = UseSigned ? Intrinsic::smul_fix : Intrinsic::umul_fix;
+ }
+ Value *Result = B.CreateIntrinsic(
+ IID, {WideLHS->getType()},
+ {WideLHS, WideRHS, B.getInt32(CommonSema.getScale())});
+
+ return CreateFixedToFixed(Result, CommonSema,
+ LHSSema.getCommonSemantics(RHSSema));
+ }
+
+ /// Divide two fixed-point values and return the result in their common
+ /// semantic.
+ /// \p LHS - The left hand side
+ /// \p LHSSema - The semantic of the left hand side
+ /// \p RHS - The right hand side
+ /// \p RHSSema - The semantic of the right hand side
+ Value *CreateDiv(Value *LHS, const FixedPointSemantics &LHSSema,
+ Value *RHS, const FixedPointSemantics &RHSSema) {
+ auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
+ bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();
+
+ Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
+ Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
+
+ Intrinsic::ID IID;
+ if (CommonSema.isSaturated()) {
+ IID = UseSigned ? Intrinsic::sdiv_fix_sat : Intrinsic::udiv_fix_sat;
+ } else {
+ IID = UseSigned ? Intrinsic::sdiv_fix : Intrinsic::udiv_fix;
+ }
+ Value *Result = B.CreateIntrinsic(
+ IID, {WideLHS->getType()},
+ {WideLHS, WideRHS, B.getInt32(CommonSema.getScale())});
+
+ return CreateFixedToFixed(Result, CommonSema,
+ LHSSema.getCommonSemantics(RHSSema));
+ }
+
+ /// Left shift a fixed-point value by an unsigned integer value. The integer
+ /// value can be any bit width.
+ /// \p LHS - The left hand side
+ /// \p LHSSema - The semantic of the left hand side
+ /// \p RHS - The right hand side
+ Value *CreateShl(Value *LHS, const FixedPointSemantics &LHSSema, Value *RHS) {
+ bool UseSigned = LHSSema.isSigned() || LHSSema.hasUnsignedPadding();
+
+ RHS = B.CreateIntCast(RHS, LHS->getType(), /*IsSigned=*/false);
+
+ Value *Result;
+ if (LHSSema.isSaturated()) {
+ Intrinsic::ID IID = UseSigned ? Intrinsic::sshl_sat : Intrinsic::ushl_sat;
+ Result = B.CreateBinaryIntrinsic(IID, LHS, RHS);
+ } else {
+ Result = B.CreateShl(LHS, RHS);
+ }
+
+ return Result;
+ }
+
+ /// Right shift a fixed-point value by an unsigned integer value. The integer
+ /// value can be any bit width.
+ /// \p LHS - The left hand side
+ /// \p LHSSema - The semantic of the left hand side
+ /// \p RHS - The right hand side
+ Value *CreateShr(Value *LHS, const FixedPointSemantics &LHSSema, Value *RHS) {
+ RHS = B.CreateIntCast(RHS, LHS->getType(), false);
+
+ return LHSSema.isSigned() ? B.CreateAShr(LHS, RHS) : B.CreateLShr(LHS, RHS);
+ }
+
+ /// Compare two fixed-point values for equality.
+ /// \p LHS - The left hand side
+ /// \p LHSSema - The semantic of the left hand side
+ /// \p RHS - The right hand side
+ /// \p RHSSema - The semantic of the right hand side
+ Value *CreateEQ(Value *LHS, const FixedPointSemantics &LHSSema,
+ Value *RHS, const FixedPointSemantics &RHSSema) {
+ auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
+
+ Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
+ Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
+
+ return B.CreateICmpEQ(WideLHS, WideRHS);
+ }
+
+ /// Compare two fixed-point values for inequality.
+ /// \p LHS - The left hand side
+ /// \p LHSSema - The semantic of the left hand side
+ /// \p RHS - The right hand side
+ /// \p RHSSema - The semantic of the right hand side
+ Value *CreateNE(Value *LHS, const FixedPointSemantics &LHSSema,
+ Value *RHS, const FixedPointSemantics &RHSSema) {
+ auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
+
+ Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
+ Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
+
+ return B.CreateICmpNE(WideLHS, WideRHS);
+ }
+
+ /// Compare two fixed-point values as LHS < RHS.
+ /// \p LHS - The left hand side
+ /// \p LHSSema - The semantic of the left hand side
+ /// \p RHS - The right hand side
+ /// \p RHSSema - The semantic of the right hand side
+ Value *CreateLT(Value *LHS, const FixedPointSemantics &LHSSema,
+ Value *RHS, const FixedPointSemantics &RHSSema) {
+ auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
+
+ Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
+ Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
+
+ return CommonSema.isSigned() ? B.CreateICmpSLT(WideLHS, WideRHS)
+ : B.CreateICmpULT(WideLHS, WideRHS);
+ }
+
+ /// Compare two fixed-point values as LHS <= RHS.
+ /// \p LHS - The left hand side
+ /// \p LHSSema - The semantic of the left hand side
+ /// \p RHS - The right hand side
+ /// \p RHSSema - The semantic of the right hand side
+ Value *CreateLE(Value *LHS, const FixedPointSemantics &LHSSema,
+ Value *RHS, const FixedPointSemantics &RHSSema) {
+ auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
+
+ Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
+ Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
+
+ return CommonSema.isSigned() ? B.CreateICmpSLE(WideLHS, WideRHS)
+ : B.CreateICmpULE(WideLHS, WideRHS);
+ }
+
+ /// Compare two fixed-point values as LHS > RHS.
+ /// \p LHS - The left hand side
+ /// \p LHSSema - The semantic of the left hand side
+ /// \p RHS - The right hand side
+ /// \p RHSSema - The semantic of the right hand side
+ Value *CreateGT(Value *LHS, const FixedPointSemantics &LHSSema,
+ Value *RHS, const FixedPointSemantics &RHSSema) {
+ auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
+
+ Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
+ Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
+
+ return CommonSema.isSigned() ? B.CreateICmpSGT(WideLHS, WideRHS)
+ : B.CreateICmpUGT(WideLHS, WideRHS);
+ }
+
+ /// Compare two fixed-point values as LHS >= RHS.
+ /// \p LHS - The left hand side
+ /// \p LHSSema - The semantic of the left hand side
+ /// \p RHS - The right hand side
+ /// \p RHSSema - The semantic of the right hand side
+ Value *CreateGE(Value *LHS, const FixedPointSemantics &LHSSema,
+ Value *RHS, const FixedPointSemantics &RHSSema) {
+ auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
+
+ Value *WideLHS = CreateFixedToFixed(LHS, LHSSema, CommonSema);
+ Value *WideRHS = CreateFixedToFixed(RHS, RHSSema, CommonSema);
+
+ return CommonSema.isSigned() ? B.CreateICmpSGE(WideLHS, WideRHS)
+ : B.CreateICmpUGE(WideLHS, WideRHS);
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_IR_FIXEDPOINTBUILDER_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/IR/Function.h b/contrib/libs/llvm12/include/llvm/IR/Function.h
index 44451b9bd6..3e5a42b325 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Function.h
+++ b/contrib/libs/llvm12/include/llvm/IR/Function.h
@@ -206,15 +206,15 @@ public:
/// returns Intrinsic::not_intrinsic!
bool isIntrinsic() const { return HasLLVMReservedName; }
- /// isTargetIntrinsic - Returns true if IID is an intrinsic specific to a
- /// certain target. If it is a generic intrinsic false is returned.
- static bool isTargetIntrinsic(Intrinsic::ID IID);
-
- /// isTargetIntrinsic - Returns true if this function is an intrinsic and the
- /// intrinsic is specific to a certain target. If this is not an intrinsic
- /// or a generic intrinsic, false is returned.
- bool isTargetIntrinsic() const;
-
+ /// isTargetIntrinsic - Returns true if IID is an intrinsic specific to a
+ /// certain target. If it is a generic intrinsic false is returned.
+ static bool isTargetIntrinsic(Intrinsic::ID IID);
+
+ /// isTargetIntrinsic - Returns true if this function is an intrinsic and the
+ /// intrinsic is specific to a certain target. If this is not an intrinsic
+ /// or a generic intrinsic, false is returned.
+ bool isTargetIntrinsic() const;
+
/// Returns true if the function is one of the "Constrained Floating-Point
/// Intrinsics". Returns false if not, and returns false when
/// getIntrinsicID() returns Intrinsic::not_intrinsic.
@@ -275,12 +275,12 @@ public:
getContext(), AttributeList::FunctionIndex, Kind));
}
- /// A function will have the "coroutine.presplit" attribute if it's
- /// a coroutine and has not gone through full CoroSplit pass.
- bool isPresplitCoroutine() const {
- return hasFnAttribute("coroutine.presplit");
- }
-
+ /// A function will have the "coroutine.presplit" attribute if it's
+ /// a coroutine and has not gone through full CoroSplit pass.
+ bool isPresplitCoroutine() const {
+ return hasFnAttribute("coroutine.presplit");
+ }
+
enum ProfileCountType { PCT_Invalid, PCT_Real, PCT_Synthetic };
/// Class to represent profile counts.
@@ -394,9 +394,9 @@ public:
void setGC(std::string Str);
void clearGC();
- /// Returns true if the function has ssp, sspstrong, or sspreq fn attrs.
- bool hasStackProtectorFnAttr() const;
-
+ /// Returns true if the function has ssp, sspstrong, or sspreq fn attrs.
+ bool hasStackProtectorFnAttr() const;
+
/// adds the attribute to the list of attributes.
void addAttribute(unsigned i, Attribute::AttrKind Kind);
@@ -488,19 +488,19 @@ public:
/// Extract the byval type for a parameter.
Type *getParamByValType(unsigned ArgNo) const {
- return AttributeSets.getParamByValType(ArgNo);
- }
-
- /// Extract the sret type for a parameter.
- Type *getParamStructRetType(unsigned ArgNo) const {
- return AttributeSets.getParamStructRetType(ArgNo);
- }
-
- /// Extract the byref type for a parameter.
- Type *getParamByRefType(unsigned ArgNo) const {
- return AttributeSets.getParamByRefType(ArgNo);
- }
-
+ return AttributeSets.getParamByValType(ArgNo);
+ }
+
+ /// Extract the sret type for a parameter.
+ Type *getParamStructRetType(unsigned ArgNo) const {
+ return AttributeSets.getParamStructRetType(ArgNo);
+ }
+
+ /// Extract the byref type for a parameter.
+ Type *getParamByRefType(unsigned ArgNo) const {
+ return AttributeSets.getParamByRefType(ArgNo);
+ }
+
/// Extract the number of dereferenceable bytes for a call or
/// parameter (0=unknown).
/// @param i AttributeList index, referring to a return value or argument.
@@ -640,17 +640,17 @@ public:
addFnAttr(Attribute::NoRecurse);
}
- /// Determine if the function is required to make forward progress.
- bool mustProgress() const {
- return hasFnAttribute(Attribute::MustProgress) ||
- hasFnAttribute(Attribute::WillReturn);
- }
- void setMustProgress() { addFnAttr(Attribute::MustProgress); }
-
- /// Determine if the function will return.
- bool willReturn() const { return hasFnAttribute(Attribute::WillReturn); }
- void setWillReturn() { addFnAttr(Attribute::WillReturn); }
-
+ /// Determine if the function is required to make forward progress.
+ bool mustProgress() const {
+ return hasFnAttribute(Attribute::MustProgress) ||
+ hasFnAttribute(Attribute::WillReturn);
+ }
+ void setMustProgress() { addFnAttr(Attribute::MustProgress); }
+
+ /// Determine if the function will return.
+ bool willReturn() const { return hasFnAttribute(Attribute::WillReturn); }
+ void setWillReturn() { addFnAttr(Attribute::WillReturn); }
+
/// True if the ABI mandates (or the user requested) that this
/// function be in a unwind table.
bool hasUWTable() const {
@@ -693,10 +693,10 @@ public:
return hasFnAttribute(Attribute::OptimizeForSize) || hasMinSize();
}
- /// Returns the denormal handling type for the default rounding mode of the
- /// function.
- DenormalMode getDenormalMode(const fltSemantics &FPType) const;
-
+ /// Returns the denormal handling type for the default rounding mode of the
+ /// function.
+ DenormalMode getDenormalMode(const fltSemantics &FPType) const;
+
/// copyAttributesFrom - copy all additional attributes (those not needed to
/// create a Function) from the Function Src to this one.
void copyAttributesFrom(const Function *Src);
diff --git a/contrib/libs/llvm12/include/llvm/IR/GetElementPtrTypeIterator.h b/contrib/libs/llvm12/include/llvm/IR/GetElementPtrTypeIterator.h
index 8e9aca2c43..ed9fe2a471 100644
--- a/contrib/libs/llvm12/include/llvm/IR/GetElementPtrTypeIterator.h
+++ b/contrib/libs/llvm12/include/llvm/IR/GetElementPtrTypeIterator.h
@@ -90,7 +90,7 @@ namespace llvm {
if (isa<ScalableVectorType>(VTy))
NumElements = Unbounded;
else
- NumElements = cast<FixedVectorType>(VTy)->getNumElements();
+ NumElements = cast<FixedVectorType>(VTy)->getNumElements();
} else
CurTy = dyn_cast<StructType>(Ty);
++OpIt;
diff --git a/contrib/libs/llvm12/include/llvm/IR/GlobalObject.h b/contrib/libs/llvm12/include/llvm/IR/GlobalObject.h
index 4bfea8e029..42bc1cd42c 100644
--- a/contrib/libs/llvm12/include/llvm/IR/GlobalObject.h
+++ b/contrib/libs/llvm12/include/llvm/IR/GlobalObject.h
@@ -133,13 +133,13 @@ public:
Comdat *getComdat() { return ObjComdat; }
void setComdat(Comdat *C) { ObjComdat = C; }
- using Value::addMetadata;
- using Value::clearMetadata;
- using Value::eraseMetadata;
- using Value::getAllMetadata;
- using Value::getMetadata;
- using Value::hasMetadata;
- using Value::setMetadata;
+ using Value::addMetadata;
+ using Value::clearMetadata;
+ using Value::eraseMetadata;
+ using Value::getAllMetadata;
+ using Value::getMetadata;
+ using Value::hasMetadata;
+ using Value::setMetadata;
/// Copy metadata from Src, adjusting offsets by Offset.
void copyMetadata(const GlobalObject *Src, unsigned Offset);
diff --git a/contrib/libs/llvm12/include/llvm/IR/GlobalVariable.h b/contrib/libs/llvm12/include/llvm/IR/GlobalVariable.h
index 47bd72d5b4..13baaf9cc8 100644
--- a/contrib/libs/llvm12/include/llvm/IR/GlobalVariable.h
+++ b/contrib/libs/llvm12/include/llvm/IR/GlobalVariable.h
@@ -63,11 +63,11 @@ public:
bool isExternallyInitialized = false);
/// GlobalVariable ctor - This creates a global and inserts it before the
/// specified other global.
- GlobalVariable(Module &M, Type *Ty, bool isConstant, LinkageTypes Linkage,
- Constant *Initializer, const Twine &Name = "",
- GlobalVariable *InsertBefore = nullptr,
- ThreadLocalMode = NotThreadLocal,
- Optional<unsigned> AddressSpace = None,
+ GlobalVariable(Module &M, Type *Ty, bool isConstant, LinkageTypes Linkage,
+ Constant *Initializer, const Twine &Name = "",
+ GlobalVariable *InsertBefore = nullptr,
+ ThreadLocalMode = NotThreadLocal,
+ Optional<unsigned> AddressSpace = None,
bool isExternallyInitialized = false);
GlobalVariable(const GlobalVariable &) = delete;
GlobalVariable &operator=(const GlobalVariable &) = delete;
diff --git a/contrib/libs/llvm12/include/llvm/IR/IRBuilder.h b/contrib/libs/llvm12/include/llvm/IR/IRBuilder.h
index bfae06872e..624d8be1f9 100644
--- a/contrib/libs/llvm12/include/llvm/IR/IRBuilder.h
+++ b/contrib/libs/llvm12/include/llvm/IR/IRBuilder.h
@@ -24,7 +24,7 @@
#include "llvm-c/Types.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/None.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/IR/BasicBlock.h"
@@ -32,7 +32,7 @@
#include "llvm/IR/ConstantFolder.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
@@ -100,29 +100,29 @@ public:
/// Common base class shared among various IRBuilders.
class IRBuilderBase {
- /// Pairs of (metadata kind, MDNode *) that should be added to all newly
- /// created instructions, like !dbg metadata.
- SmallVector<std::pair<unsigned, MDNode *>, 2> MetadataToCopy;
-
- /// Add or update the an entry (Kind, MD) to MetadataToCopy, if \p MD is not
- /// null. If \p MD is null, remove the entry with \p Kind.
- void AddOrRemoveMetadataToCopy(unsigned Kind, MDNode *MD) {
- if (!MD) {
- erase_if(MetadataToCopy, [Kind](const std::pair<unsigned, MDNode *> &KV) {
- return KV.first == Kind;
- });
- return;
- }
-
- for (auto &KV : MetadataToCopy)
- if (KV.first == Kind) {
- KV.second = MD;
- return;
- }
-
- MetadataToCopy.emplace_back(Kind, MD);
- }
-
+ /// Pairs of (metadata kind, MDNode *) that should be added to all newly
+ /// created instructions, like !dbg metadata.
+ SmallVector<std::pair<unsigned, MDNode *>, 2> MetadataToCopy;
+
+ /// Add or update the an entry (Kind, MD) to MetadataToCopy, if \p MD is not
+ /// null. If \p MD is null, remove the entry with \p Kind.
+ void AddOrRemoveMetadataToCopy(unsigned Kind, MDNode *MD) {
+ if (!MD) {
+ erase_if(MetadataToCopy, [Kind](const std::pair<unsigned, MDNode *> &KV) {
+ return KV.first == Kind;
+ });
+ return;
+ }
+
+ for (auto &KV : MetadataToCopy)
+ if (KV.first == Kind) {
+ KV.second = MD;
+ return;
+ }
+
+ MetadataToCopy.emplace_back(Kind, MD);
+ }
+
protected:
BasicBlock *BB;
BasicBlock::iterator InsertPt;
@@ -155,7 +155,7 @@ public:
template<typename InstTy>
InstTy *Insert(InstTy *I, const Twine &Name = "") const {
Inserter.InsertHelper(I, Name, BB, InsertPt);
- AddMetadataToInst(I);
+ AddMetadataToInst(I);
return I;
}
@@ -212,44 +212,44 @@ public:
}
/// Set location information used by debugging information.
- void SetCurrentDebugLocation(DebugLoc L) {
- AddOrRemoveMetadataToCopy(LLVMContext::MD_dbg, L.getAsMDNode());
- }
-
- /// Collect metadata with IDs \p MetadataKinds from \p Src which should be
- /// added to all created instructions. Entries present in MedataDataToCopy but
- /// not on \p Src will be dropped from MetadataToCopy.
- void CollectMetadataToCopy(Instruction *Src,
- ArrayRef<unsigned> MetadataKinds) {
- for (unsigned K : MetadataKinds)
- AddOrRemoveMetadataToCopy(K, Src->getMetadata(K));
- }
-
+ void SetCurrentDebugLocation(DebugLoc L) {
+ AddOrRemoveMetadataToCopy(LLVMContext::MD_dbg, L.getAsMDNode());
+ }
+
+ /// Collect metadata with IDs \p MetadataKinds from \p Src which should be
+ /// added to all created instructions. Entries present in MedataDataToCopy but
+ /// not on \p Src will be dropped from MetadataToCopy.
+ void CollectMetadataToCopy(Instruction *Src,
+ ArrayRef<unsigned> MetadataKinds) {
+ for (unsigned K : MetadataKinds)
+ AddOrRemoveMetadataToCopy(K, Src->getMetadata(K));
+ }
+
/// Get location information used by debugging information.
- DebugLoc getCurrentDebugLocation() const {
- for (auto &KV : MetadataToCopy)
- if (KV.first == LLVMContext::MD_dbg)
- return {cast<DILocation>(KV.second)};
-
- return {};
- }
-
+ DebugLoc getCurrentDebugLocation() const {
+ for (auto &KV : MetadataToCopy)
+ if (KV.first == LLVMContext::MD_dbg)
+ return {cast<DILocation>(KV.second)};
+
+ return {};
+ }
+
/// If this builder has a current debug location, set it on the
/// specified instruction.
void SetInstDebugLocation(Instruction *I) const {
- for (const auto &KV : MetadataToCopy)
- if (KV.first == LLVMContext::MD_dbg) {
- I->setDebugLoc(DebugLoc(KV.second));
- return;
- }
- }
-
- /// Add all entries in MetadataToCopy to \p I.
- void AddMetadataToInst(Instruction *I) const {
- for (auto &KV : MetadataToCopy)
- I->setMetadata(KV.first, KV.second);
- }
-
+ for (const auto &KV : MetadataToCopy)
+ if (KV.first == LLVMContext::MD_dbg) {
+ I->setDebugLoc(DebugLoc(KV.second));
+ return;
+ }
+ }
+
+ /// Add all entries in MetadataToCopy to \p I.
+ void AddMetadataToInst(Instruction *I) const {
+ for (auto &KV : MetadataToCopy)
+ I->setMetadata(KV.first, KV.second);
+ }
+
/// Get the return type of the current function that we're emitting
/// into.
Type *getCurrentFunctionReturnType() const;
@@ -322,19 +322,19 @@ public:
/// Set the exception handling to be used with constrained floating point
void setDefaultConstrainedExcept(fp::ExceptionBehavior NewExcept) {
-#ifndef NDEBUG
- Optional<StringRef> ExceptStr = ExceptionBehaviorToStr(NewExcept);
- assert(ExceptStr.hasValue() && "Garbage strict exception behavior!");
-#endif
+#ifndef NDEBUG
+ Optional<StringRef> ExceptStr = ExceptionBehaviorToStr(NewExcept);
+ assert(ExceptStr.hasValue() && "Garbage strict exception behavior!");
+#endif
DefaultConstrainedExcept = NewExcept;
}
/// Set the rounding mode handling to be used with constrained floating point
void setDefaultConstrainedRounding(RoundingMode NewRounding) {
-#ifndef NDEBUG
- Optional<StringRef> RoundingStr = RoundingModeToStr(NewRounding);
- assert(RoundingStr.hasValue() && "Garbage strict rounding mode!");
-#endif
+#ifndef NDEBUG
+ Optional<StringRef> RoundingStr = RoundingModeToStr(NewRounding);
+ assert(RoundingStr.hasValue() && "Garbage strict rounding mode!");
+#endif
DefaultConstrainedRounding = NewRounding;
}
@@ -357,8 +357,8 @@ public:
}
}
- void setConstrainedFPCallAttr(CallBase *I) {
- I->addAttribute(AttributeList::FunctionIndex, Attribute::StrictFP);
+ void setConstrainedFPCallAttr(CallBase *I) {
+ I->addAttribute(AttributeList::FunctionIndex, Attribute::StrictFP);
}
void setDefaultOperandBundles(ArrayRef<OperandBundleDef> OpBundles) {
@@ -637,22 +637,22 @@ public:
NoAliasTag);
}
- CallInst *CreateMemTransferInst(
- Intrinsic::ID IntrID, Value *Dst, MaybeAlign DstAlign, Value *Src,
- MaybeAlign SrcAlign, Value *Size, bool isVolatile = false,
- MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr,
- MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr);
-
+ CallInst *CreateMemTransferInst(
+ Intrinsic::ID IntrID, Value *Dst, MaybeAlign DstAlign, Value *Src,
+ MaybeAlign SrcAlign, Value *Size, bool isVolatile = false,
+ MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr,
+ MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr);
+
CallInst *CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src,
MaybeAlign SrcAlign, Value *Size,
bool isVolatile = false, MDNode *TBAATag = nullptr,
MDNode *TBAAStructTag = nullptr,
MDNode *ScopeTag = nullptr,
- MDNode *NoAliasTag = nullptr) {
- return CreateMemTransferInst(Intrinsic::memcpy, Dst, DstAlign, Src,
- SrcAlign, Size, isVolatile, TBAATag,
- TBAAStructTag, ScopeTag, NoAliasTag);
- }
+ MDNode *NoAliasTag = nullptr) {
+ return CreateMemTransferInst(Intrinsic::memcpy, Dst, DstAlign, Src,
+ SrcAlign, Size, isVolatile, TBAATag,
+ TBAAStructTag, ScopeTag, NoAliasTag);
+ }
CallInst *CreateMemCpyInline(Value *Dst, MaybeAlign DstAlign, Value *Src,
MaybeAlign SrcAlign, Value *Size);
@@ -786,11 +786,11 @@ public:
/// Create a vector float max reduction intrinsic of the source
/// vector.
- CallInst *CreateFPMaxReduce(Value *Src);
+ CallInst *CreateFPMaxReduce(Value *Src);
/// Create a vector float min reduction intrinsic of the source
/// vector.
- CallInst *CreateFPMinReduce(Value *Src);
+ CallInst *CreateFPMinReduce(Value *Src);
/// Create a lifetime.start intrinsic.
///
@@ -859,19 +859,19 @@ public:
/// Create an assume intrinsic call that allows the optimizer to
/// assume that the provided condition will be true.
- ///
- /// The optional argument \p OpBundles specifies operand bundles that are
- /// added to the call instruction.
- CallInst *CreateAssumption(Value *Cond,
- ArrayRef<OperandBundleDef> OpBundles = llvm::None);
-
- /// Create a llvm.experimental.noalias.scope.decl intrinsic call.
- Instruction *CreateNoAliasScopeDeclaration(Value *Scope);
- Instruction *CreateNoAliasScopeDeclaration(MDNode *ScopeTag) {
- return CreateNoAliasScopeDeclaration(
- MetadataAsValue::get(Context, ScopeTag));
- }
-
+ ///
+ /// The optional argument \p OpBundles specifies operand bundles that are
+ /// added to the call instruction.
+ CallInst *CreateAssumption(Value *Cond,
+ ArrayRef<OperandBundleDef> OpBundles = llvm::None);
+
+ /// Create a llvm.experimental.noalias.scope.decl intrinsic call.
+ Instruction *CreateNoAliasScopeDeclaration(Value *Scope);
+ Instruction *CreateNoAliasScopeDeclaration(MDNode *ScopeTag) {
+ return CreateNoAliasScopeDeclaration(
+ MetadataAsValue::get(Context, ScopeTag));
+ }
+
/// Create a call to the experimental.gc.statepoint intrinsic to
/// start a new statepoint sequence.
CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes,
@@ -885,7 +885,7 @@ public:
/// start a new statepoint sequence.
CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes,
Value *ActualCallee, uint32_t Flags,
- ArrayRef<Value *> CallArgs,
+ ArrayRef<Value *> CallArgs,
Optional<ArrayRef<Use>> TransitionArgs,
Optional<ArrayRef<Use>> DeoptArgs,
ArrayRef<Value *> GCArgs,
@@ -914,7 +914,7 @@ public:
InvokeInst *CreateGCStatepointInvoke(
uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags,
- ArrayRef<Value *> InvokeArgs, Optional<ArrayRef<Use>> TransitionArgs,
+ ArrayRef<Value *> InvokeArgs, Optional<ArrayRef<Use>> TransitionArgs,
Optional<ArrayRef<Use>> DeoptArgs, ArrayRef<Value *> GCArgs,
const Twine &Name = "");
@@ -942,10 +942,10 @@ public:
Type *ResultType,
const Twine &Name = "");
- /// Create a call to llvm.vscale, multiplied by \p Scaling. The type of VScale
- /// will be the same type as that of \p Scaling.
- Value *CreateVScale(Constant *Scaling, const Twine &Name = "");
-
+ /// Create a call to llvm.vscale, multiplied by \p Scaling. The type of VScale
+ /// will be the same type as that of \p Scaling.
+ Value *CreateVScale(Constant *Scaling, const Twine &Name = "");
+
/// Create a call to intrinsic \p ID with 1 operand which is mangled on its
/// type.
CallInst *CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V,
@@ -986,22 +986,22 @@ public:
return CreateBinaryIntrinsic(Intrinsic::maximum, LHS, RHS, nullptr, Name);
}
- /// Create a call to the experimental.vector.extract intrinsic.
- CallInst *CreateExtractVector(Type *DstType, Value *SrcVec, Value *Idx,
- const Twine &Name = "") {
- return CreateIntrinsic(Intrinsic::experimental_vector_extract,
- {DstType, SrcVec->getType()}, {SrcVec, Idx}, nullptr,
- Name);
- }
-
- /// Create a call to the experimental.vector.insert intrinsic.
- CallInst *CreateInsertVector(Type *DstType, Value *SrcVec, Value *SubVec,
- Value *Idx, const Twine &Name = "") {
- return CreateIntrinsic(Intrinsic::experimental_vector_insert,
- {DstType, SubVec->getType()}, {SrcVec, SubVec, Idx},
- nullptr, Name);
- }
-
+ /// Create a call to the experimental.vector.extract intrinsic.
+ CallInst *CreateExtractVector(Type *DstType, Value *SrcVec, Value *Idx,
+ const Twine &Name = "") {
+ return CreateIntrinsic(Intrinsic::experimental_vector_extract,
+ {DstType, SrcVec->getType()}, {SrcVec, Idx}, nullptr,
+ Name);
+ }
+
+ /// Create a call to the experimental.vector.insert intrinsic.
+ CallInst *CreateInsertVector(Type *DstType, Value *SrcVec, Value *SubVec,
+ Value *Idx, const Twine &Name = "") {
+ return CreateIntrinsic(Intrinsic::experimental_vector_insert,
+ {DstType, SubVec->getType()}, {SrcVec, SubVec, Idx},
+ nullptr, Name);
+ }
+
private:
/// Create a call to a masked intrinsic with given Id.
CallInst *CreateMaskedIntrinsic(Intrinsic::ID Id, ArrayRef<Value *> Ops,
@@ -1102,21 +1102,21 @@ public:
ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> OpBundles,
const Twine &Name = "") {
- InvokeInst *II =
- InvokeInst::Create(Ty, Callee, NormalDest, UnwindDest, Args, OpBundles);
- if (IsFPConstrained)
- setConstrainedFPCallAttr(II);
- return Insert(II, Name);
+ InvokeInst *II =
+ InvokeInst::Create(Ty, Callee, NormalDest, UnwindDest, Args, OpBundles);
+ if (IsFPConstrained)
+ setConstrainedFPCallAttr(II);
+ return Insert(II, Name);
}
InvokeInst *CreateInvoke(FunctionType *Ty, Value *Callee,
BasicBlock *NormalDest, BasicBlock *UnwindDest,
ArrayRef<Value *> Args = None,
const Twine &Name = "") {
- InvokeInst *II =
- InvokeInst::Create(Ty, Callee, NormalDest, UnwindDest, Args);
- if (IsFPConstrained)
- setConstrainedFPCallAttr(II);
- return Insert(II, Name);
+ InvokeInst *II =
+ InvokeInst::Create(Ty, Callee, NormalDest, UnwindDest, Args);
+ if (IsFPConstrained)
+ setConstrainedFPCallAttr(II);
+ return Insert(II, Name);
}
InvokeInst *CreateInvoke(FunctionCallee Callee, BasicBlock *NormalDest,
@@ -2537,13 +2537,13 @@ public:
return Insert(new ShuffleVectorInst(V1, V2, Mask), Name);
}
- /// Create a unary shuffle. The second vector operand of the IR instruction
- /// is poison.
- Value *CreateShuffleVector(Value *V, ArrayRef<int> Mask,
- const Twine &Name = "") {
- return CreateShuffleVector(V, PoisonValue::get(V->getType()), Mask, Name);
- }
-
+ /// Create a unary shuffle. The second vector operand of the IR instruction
+ /// is poison.
+ Value *CreateShuffleVector(Value *V, ArrayRef<int> Mask,
+ const Twine &Name = "") {
+ return CreateShuffleVector(V, PoisonValue::get(V->getType()), Mask, Name);
+ }
+
Value *CreateExtractValue(Value *Agg,
ArrayRef<unsigned> Idxs,
const Twine &Name = "") {
@@ -2608,10 +2608,10 @@ public:
/// NumElts elements.
Value *CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name = "");
- /// Return a vector value that contains \arg V broadcasted to \p
- /// EC elements.
- Value *CreateVectorSplat(ElementCount EC, Value *V, const Twine &Name = "");
-
+ /// Return a vector value that contains \arg V broadcasted to \p
+ /// EC elements.
+ Value *CreateVectorSplat(ElementCount EC, Value *V, const Twine &Name = "");
+
/// Return a value that has been extracted from a larger integer type.
Value *CreateExtractInteger(const DataLayout &DL, Value *From,
IntegerType *ExtractedTy, uint64_t Offset,
@@ -2630,11 +2630,11 @@ public:
private:
/// Helper function that creates an assume intrinsic call that
- /// represents an alignment assumption on the provided pointer \p PtrValue
- /// with offset \p OffsetValue and alignment value \p AlignValue.
+ /// represents an alignment assumption on the provided pointer \p PtrValue
+ /// with offset \p OffsetValue and alignment value \p AlignValue.
CallInst *CreateAlignmentAssumptionHelper(const DataLayout &DL,
- Value *PtrValue, Value *AlignValue,
- Value *OffsetValue);
+ Value *PtrValue, Value *AlignValue,
+ Value *OffsetValue);
public:
/// Create an assume intrinsic call that represents an alignment
@@ -2645,7 +2645,7 @@ public:
/// specified alignment.
CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue,
unsigned Alignment,
- Value *OffsetValue = nullptr);
+ Value *OffsetValue = nullptr);
/// Create an assume intrinsic call that represents an alignment
/// assumption on the provided pointer.
@@ -2658,7 +2658,7 @@ public:
/// on an existing value rather than a static value.
CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue,
Value *Alignment,
- Value *OffsetValue = nullptr);
+ Value *OffsetValue = nullptr);
};
/// This provides a uniform API for creating instructions and inserting
diff --git a/contrib/libs/llvm12/include/llvm/IR/IRPrintingPasses.h b/contrib/libs/llvm12/include/llvm/IR/IRPrintingPasses.h
index a6a5e0da78..aef9d56125 100644
--- a/contrib/libs/llvm12/include/llvm/IR/IRPrintingPasses.h
+++ b/contrib/libs/llvm12/include/llvm/IR/IRPrintingPasses.h
@@ -29,8 +29,8 @@
#include <string>
namespace llvm {
-class raw_ostream;
-class StringRef;
+class raw_ostream;
+class StringRef;
/// Create and return a pass that writes the module to the specified
/// \c raw_ostream.
@@ -67,7 +67,7 @@ public:
bool ShouldPreserveUseListOrder = false);
PreservedAnalyses run(Module &M, AnalysisManager<Module> &);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
};
/// Pass for printing a Function as LLVM's text IR assembly.
@@ -83,10 +83,10 @@ public:
PrintFunctionPass(raw_ostream &OS, const std::string &Banner = "");
PreservedAnalyses run(Function &F, AnalysisManager<Function> &);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
};
-} // namespace llvm
+} // namespace llvm
#endif
diff --git a/contrib/libs/llvm12/include/llvm/IR/InstrTypes.h b/contrib/libs/llvm12/include/llvm/IR/InstrTypes.h
index 06e0f773b4..a6917565bd 100644
--- a/contrib/libs/llvm12/include/llvm/IR/InstrTypes.h
+++ b/contrib/libs/llvm12/include/llvm/IR/InstrTypes.h
@@ -655,8 +655,8 @@ public:
/// DataLayout argument is to determine the pointer size when examining casts
/// 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. Note that a precondition of this method is that the cast is
- /// legal - i.e. the instruction formed with these operands would verify.
+ /// platform. Note that a precondition of this method is that the cast is
+ /// legal - i.e. the instruction formed with these operands would verify.
static bool isNoopCast(
Instruction::CastOps Opcode, ///< Opcode of cast
Type *SrcTy, ///< SrcTy of cast
@@ -696,14 +696,14 @@ public:
/// Return the destination type, as a convenience
Type* getDestTy() const { return getType(); }
- /// This method can be used to determine if a cast from SrcTy to DstTy using
+ /// This method can be used to determine if a cast from SrcTy to DstTy using
/// Opcode op is valid or not.
/// @returns true iff the proposed cast is valid.
/// Determine if a cast is valid without creating one.
- static bool castIsValid(Instruction::CastOps op, Type *SrcTy, Type *DstTy);
- static bool castIsValid(Instruction::CastOps op, Value *S, Type *DstTy) {
- return castIsValid(op, S->getType(), DstTy);
- }
+ static bool castIsValid(Instruction::CastOps op, Type *SrcTy, Type *DstTy);
+ static bool castIsValid(Instruction::CastOps op, Value *S, Type *DstTy) {
+ return castIsValid(op, S->getType(), DstTy);
+ }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Instruction *I) {
@@ -813,8 +813,8 @@ public:
void setPredicate(Predicate P) { setSubclassData<PredicateField>(P); }
static bool isFPPredicate(Predicate P) {
- static_assert(FIRST_FCMP_PREDICATE == 0,
- "FIRST_FCMP_PREDICATE is required to be 0");
+ static_assert(FIRST_FCMP_PREDICATE == 0,
+ "FIRST_FCMP_PREDICATE is required to be 0");
return P <= LAST_FCMP_PREDICATE;
}
@@ -856,38 +856,38 @@ public:
/// Return the predicate as if the operands were swapped.
static Predicate getSwappedPredicate(Predicate pred);
- /// This is a static version that you can use without an instruction
- /// available.
- /// @returns true if the comparison predicate is strict, false otherwise.
- static bool isStrictPredicate(Predicate predicate);
-
- /// @returns true if the comparison predicate is strict, false otherwise.
- /// Determine if this instruction is using an strict comparison predicate.
- bool isStrictPredicate() const { return isStrictPredicate(getPredicate()); }
-
- /// This is a static version that you can use without an instruction
- /// available.
- /// @returns true if the comparison predicate is non-strict, false otherwise.
- static bool isNonStrictPredicate(Predicate predicate);
-
- /// @returns true if the comparison predicate is non-strict, false otherwise.
- /// Determine if this instruction is using an non-strict comparison predicate.
- bool isNonStrictPredicate() const {
- return isNonStrictPredicate(getPredicate());
- }
-
- /// For example, SGE -> SGT, SLE -> SLT, ULE -> ULT, UGE -> UGT.
- /// Returns the strict version of non-strict comparisons.
- Predicate getStrictPredicate() const {
- return getStrictPredicate(getPredicate());
- }
-
/// This is a static version that you can use without an instruction
/// available.
- /// @returns the strict version of comparison provided in \p pred.
- /// If \p pred is not a strict comparison predicate, returns \p pred.
- /// Returns the strict version of non-strict comparisons.
- static Predicate getStrictPredicate(Predicate pred);
+ /// @returns true if the comparison predicate is strict, false otherwise.
+ static bool isStrictPredicate(Predicate predicate);
+
+ /// @returns true if the comparison predicate is strict, false otherwise.
+ /// Determine if this instruction is using an strict comparison predicate.
+ bool isStrictPredicate() const { return isStrictPredicate(getPredicate()); }
+
+ /// This is a static version that you can use without an instruction
+ /// available.
+ /// @returns true if the comparison predicate is non-strict, false otherwise.
+ static bool isNonStrictPredicate(Predicate predicate);
+
+ /// @returns true if the comparison predicate is non-strict, false otherwise.
+ /// Determine if this instruction is using an non-strict comparison predicate.
+ bool isNonStrictPredicate() const {
+ return isNonStrictPredicate(getPredicate());
+ }
+
+ /// For example, SGE -> SGT, SLE -> SLT, ULE -> ULT, UGE -> UGT.
+ /// Returns the strict version of non-strict comparisons.
+ Predicate getStrictPredicate() const {
+ return getStrictPredicate(getPredicate());
+ }
+
+ /// This is a static version that you can use without an instruction
+ /// available.
+ /// @returns the strict version of comparison provided in \p pred.
+ /// If \p pred is not a strict comparison predicate, returns \p pred.
+ /// Returns the strict version of non-strict comparisons.
+ static Predicate getStrictPredicate(Predicate pred);
/// For example, SGT -> SGE, SLT -> SLE, ULT -> ULE, UGT -> UGE.
/// Returns the non-strict version of strict comparisons.
@@ -902,21 +902,21 @@ public:
/// Returns the non-strict version of strict comparisons.
static Predicate getNonStrictPredicate(Predicate pred);
- /// This is a static version that you can use without an instruction
- /// available.
- /// Return the flipped strictness of predicate
- static Predicate getFlippedStrictnessPredicate(Predicate pred);
-
- /// For predicate of kind "is X or equal to 0" returns the predicate "is X".
- /// For predicate of kind "is X" returns the predicate "is X or equal to 0".
- /// does not support other kind of predicates.
- /// @returns the predicate that does not contains is equal to zero if
- /// it had and vice versa.
- /// 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.
+ /// Return the flipped strictness of predicate
+ static Predicate getFlippedStrictnessPredicate(Predicate pred);
+
+ /// For predicate of kind "is X or equal to 0" returns the predicate "is X".
+ /// For predicate of kind "is X" returns the predicate "is X or equal to 0".
+ /// does not support other kind of predicates.
+ /// @returns the predicate that does not contains is equal to zero if
+ /// it had and vice versa.
+ /// Return the flipped strictness of predicate
+ Predicate getFlippedStrictnessPredicate() const {
+ return getFlippedStrictnessPredicate(getPredicate());
+ }
+
/// Provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -930,19 +930,19 @@ public:
bool isCommutative() const;
/// Determine if this is an equals/not equals predicate.
- /// This is a static version that you can use without an instruction
- /// available.
- static bool isEquality(Predicate pred);
-
- /// Determine if this is an equals/not equals predicate.
- bool isEquality() const { return isEquality(getPredicate()); }
-
- /// Return true if the predicate is relational (not EQ or NE).
- static bool isRelational(Predicate P) { return !isEquality(P); }
-
- /// Return true if the predicate is relational (not EQ or NE).
- bool isRelational() const { return !isEquality(); }
-
+ /// This is a static version that you can use without an instruction
+ /// available.
+ static bool isEquality(Predicate pred);
+
+ /// Determine if this is an equals/not equals predicate.
+ bool isEquality() const { return isEquality(getPredicate()); }
+
+ /// Return true if the predicate is relational (not EQ or NE).
+ static bool isRelational(Predicate P) { return !isEquality(P); }
+
+ /// Return true if the predicate is relational (not EQ or NE).
+ bool isRelational() const { return !isEquality(); }
+
/// @returns true if the comparison is signed, false otherwise.
/// Determine if this instruction is using a signed comparison.
bool isSigned() const {
@@ -968,30 +968,30 @@ public:
return getSignedPredicate(getPredicate());
}
- /// For example, SLT->ULT, SLE->ULE, SGT->UGT, SGE->UGE, ULT->Failed assert
- /// @returns the unsigned version of the signed predicate pred.
- static Predicate getUnsignedPredicate(Predicate pred);
-
- /// For example, SLT->ULT, SLE->ULE, SGT->UGT, SGE->UGE, ULT->Failed assert
- /// @returns the unsigned version of the predicate for this instruction (which
- /// has to be an signed predicate).
- /// return the unsigned version of a predicate
- Predicate getUnsignedPredicate() {
- return getUnsignedPredicate(getPredicate());
- }
-
- /// For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->Failed assert
- /// @returns the unsigned version of the signed predicate pred or
- /// the signed version of the signed predicate pred.
- static Predicate getFlippedSignednessPredicate(Predicate pred);
-
- /// For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->Failed assert
- /// @returns the unsigned version of the signed predicate pred or
- /// the signed version of the signed predicate pred.
- Predicate getFlippedSignednessPredicate() {
- return getFlippedSignednessPredicate(getPredicate());
- }
-
+ /// For example, SLT->ULT, SLE->ULE, SGT->UGT, SGE->UGE, ULT->Failed assert
+ /// @returns the unsigned version of the signed predicate pred.
+ static Predicate getUnsignedPredicate(Predicate pred);
+
+ /// For example, SLT->ULT, SLE->ULE, SGT->UGT, SGE->UGE, ULT->Failed assert
+ /// @returns the unsigned version of the predicate for this instruction (which
+ /// has to be an signed predicate).
+ /// return the unsigned version of a predicate
+ Predicate getUnsignedPredicate() {
+ return getUnsignedPredicate(getPredicate());
+ }
+
+ /// For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->Failed assert
+ /// @returns the unsigned version of the signed predicate pred or
+ /// the signed version of the signed predicate pred.
+ static Predicate getFlippedSignednessPredicate(Predicate pred);
+
+ /// For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->Failed assert
+ /// @returns the unsigned version of the signed predicate pred or
+ /// the signed version of the signed predicate pred.
+ Predicate getFlippedSignednessPredicate() {
+ return getFlippedSignednessPredicate(getPredicate());
+ }
+
/// This is just a convenience.
/// Determine if this is true when both operands are the same.
bool isTrueWhenEqual() const {
@@ -1137,7 +1137,7 @@ public:
explicit OperandBundleDefT(const OperandBundleUse &OBU) {
Tag = std::string(OBU.getTagName());
- llvm::append_range(Inputs, OBU.Inputs);
+ llvm::append_range(Inputs, OBU.Inputs);
}
ArrayRef<InputTy> inputs() const { return Inputs; }
@@ -1376,7 +1376,7 @@ public:
/// Returns true if this CallSite passes the given Value* as an argument to
/// the called function.
bool hasArgument(const Value *V) const {
- return llvm::is_contained(args(), V);
+ return llvm::is_contained(args(), V);
}
Value *getCalledOperand() const { return Op<CalledOperandOpEndIdx>(); }
@@ -1468,18 +1468,18 @@ public:
///
void setAttributes(AttributeList A) { Attrs = A; }
- /// Determine whether this call has the given attribute. If it does not
- /// then determine if the called function has the attribute, but only if
- /// the attribute is allowed for the call.
+ /// Determine whether this call has the given attribute. If it does not
+ /// then determine if the called function has the attribute, but only if
+ /// the attribute is allowed for the call.
bool hasFnAttr(Attribute::AttrKind Kind) const {
assert(Kind != Attribute::NoBuiltin &&
"Use CallBase::isNoBuiltin() to check for Attribute::NoBuiltin");
return hasFnAttrImpl(Kind);
}
- /// Determine whether this call has the given attribute. If it does not
- /// then determine if the called function has the attribute, but only if
- /// the attribute is allowed for the call.
+ /// Determine whether this call has the given attribute. If it does not
+ /// then determine if the called function has the attribute, but only if
+ /// the attribute is allowed for the call.
bool hasFnAttr(StringRef Kind) const { return hasFnAttrImpl(Kind); }
/// adds the attribute to the list of attributes.
@@ -1526,12 +1526,12 @@ public:
setAttributes(PAL);
}
- void removeAttributes(unsigned i, const AttrBuilder &Attrs) {
- AttributeList PAL = getAttributes();
- PAL = PAL.removeAttributes(getContext(), i, Attrs);
- setAttributes(PAL);
- }
-
+ void removeAttributes(unsigned i, const AttrBuilder &Attrs) {
+ AttributeList PAL = getAttributes();
+ PAL = PAL.removeAttributes(getContext(), i, Attrs);
+ setAttributes(PAL);
+ }
+
/// Removes the attribute from the given argument
void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
assert(ArgNo < getNumArgOperands() && "Out of bounds");
@@ -1564,11 +1564,11 @@ public:
}
/// Determine whether the return value has the given attribute.
- bool hasRetAttr(Attribute::AttrKind Kind) const {
- return hasRetAttrImpl(Kind);
- }
- /// Determine whether the return value has the given attribute.
- bool hasRetAttr(StringRef Kind) const { return hasRetAttrImpl(Kind); }
+ bool hasRetAttr(Attribute::AttrKind Kind) const {
+ return hasRetAttrImpl(Kind);
+ }
+ /// Determine whether the return value has the given attribute.
+ bool hasRetAttr(StringRef Kind) const { return hasRetAttrImpl(Kind); }
/// Determine whether the argument or parameter has the given attribute.
bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const;
@@ -1767,7 +1767,7 @@ public:
bool onlyReadsMemory() const {
return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly);
}
-
+
void setOnlyReadsMemory() {
addAttribute(AttributeList::FunctionIndex, Attribute::ReadOnly);
}
@@ -2248,18 +2248,18 @@ private:
return hasFnAttrOnCalledFunction(Kind);
}
-
- /// Determine whether the return value has the given attribute. Supports
- /// Attribute::AttrKind and StringRef as \p AttrKind types.
- template <typename AttrKind> bool hasRetAttrImpl(AttrKind Kind) const {
- if (Attrs.hasAttribute(AttributeList::ReturnIndex, Kind))
- return true;
-
- // Look at the callee, if available.
- if (const Function *F = getCalledFunction())
- return F->getAttributes().hasAttribute(AttributeList::ReturnIndex, Kind);
- return false;
- }
+
+ /// Determine whether the return value has the given attribute. Supports
+ /// Attribute::AttrKind and StringRef as \p AttrKind types.
+ template <typename AttrKind> bool hasRetAttrImpl(AttrKind Kind) const {
+ if (Attrs.hasAttribute(AttributeList::ReturnIndex, Kind))
+ return true;
+
+ // Look at the callee, if available.
+ if (const Function *F = getCalledFunction())
+ return F->getAttributes().hasAttribute(AttributeList::ReturnIndex, Kind);
+ return false;
+ }
};
template <>
diff --git a/contrib/libs/llvm12/include/llvm/IR/Instruction.h b/contrib/libs/llvm12/include/llvm/IR/Instruction.h
index 1a3825c739..2444458978 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Instruction.h
+++ b/contrib/libs/llvm12/include/llvm/IR/Instruction.h
@@ -263,11 +263,11 @@ public:
//===--------------------------------------------------------------------===//
/// Return true if this instruction has any metadata attached to it.
- bool hasMetadata() const { return DbgLoc || Value::hasMetadata(); }
+ bool hasMetadata() const { return DbgLoc || Value::hasMetadata(); }
/// Return true if this instruction has metadata attached to it other than a
/// debug location.
- bool hasMetadataOtherThanDebugLoc() const { return Value::hasMetadata(); }
+ bool hasMetadataOtherThanDebugLoc() const { return Value::hasMetadata(); }
/// Return true if this instruction has the given type of metadata attached.
bool hasMetadata(unsigned KindID) const {
@@ -306,7 +306,7 @@ public:
/// debug location.
void getAllMetadataOtherThanDebugLoc(
SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const {
- Value::getAllMetadata(MDs);
+ Value::getAllMetadata(MDs);
}
/// Fills the AAMDNodes structure with AA metadata from this instruction.
@@ -347,11 +347,11 @@ public:
}
/// @}
- /// Adds an !annotation metadata node with \p Annotation to this instruction.
- /// If this instruction already has !annotation metadata, append \p Annotation
- /// to the existing node.
- void addAnnotationMetadata(StringRef Annotation);
-
+ /// Adds an !annotation metadata node with \p Annotation to this instruction.
+ /// If this instruction already has !annotation metadata, append \p Annotation
+ /// to the existing node.
+ void addAnnotationMetadata(StringRef Annotation);
+
/// Sets the metadata on this instruction from the AAMDNodes structure.
void setAAMetadata(const AAMDNodes &N);
@@ -501,20 +501,20 @@ public:
/// merged DebugLoc.
void applyMergedLocation(const DILocation *LocA, const DILocation *LocB);
- /// Updates the debug location given that the instruction has been hoisted
- /// from a block to a predecessor of that block.
- /// Note: it is undefined behavior to call this on an instruction not
- /// currently inserted into a function.
- void updateLocationAfterHoist();
-
- /// Drop the instruction's debug location. This does not guarantee removal
- /// of the !dbg source location attachment, as it must set a line 0 location
- /// with scope information attached on call instructions. To guarantee
- /// removal of the !dbg attachment, use the \ref setDebugLoc() API.
- /// Note: it is undefined behavior to call this on an instruction not
- /// currently inserted into a function.
- void dropLocation();
-
+ /// Updates the debug location given that the instruction has been hoisted
+ /// from a block to a predecessor of that block.
+ /// Note: it is undefined behavior to call this on an instruction not
+ /// currently inserted into a function.
+ void updateLocationAfterHoist();
+
+ /// Drop the instruction's debug location. This does not guarantee removal
+ /// of the !dbg source location attachment, as it must set a line 0 location
+ /// with scope information attached on call instructions. To guarantee
+ /// removal of the !dbg attachment, use the \ref setDebugLoc() API.
+ /// Note: it is undefined behavior to call this on an instruction not
+ /// currently inserted into a function.
+ void dropLocation();
+
private:
// These are all implemented in Metadata.cpp.
MDNode *getMetadataImpl(unsigned KindID) const;
@@ -546,7 +546,7 @@ public:
/// In LLVM, these are the commutative operators, plus SetEQ and SetNE, when
/// applied to any type.
///
- bool isCommutative() const LLVM_READONLY;
+ bool isCommutative() const LLVM_READONLY;
static bool isCommutative(unsigned Opcode) {
switch (Opcode) {
case Add: case FAdd:
@@ -640,10 +640,10 @@ public:
/// generated program.
bool isSafeToRemove() const;
- /// Return true if the instruction will return (unwinding is considered as
- /// a form of returning control flow here).
- bool willReturn() const;
-
+ /// Return true if the instruction will return (unwinding is considered as
+ /// a form of returning control flow here).
+ bool willReturn() const;
+
/// Return true if the instruction is a variety of EH-block.
bool isEHPad() const {
switch (getOpcode()) {
@@ -661,29 +661,29 @@ public:
/// llvm.lifetime.end marker.
bool isLifetimeStartOrEnd() const;
- /// Return true if the instruction is a DbgInfoIntrinsic or PseudoProbeInst.
- bool isDebugOrPseudoInst() const;
-
+ /// Return true if the instruction is a DbgInfoIntrinsic or PseudoProbeInst.
+ bool isDebugOrPseudoInst() const;
+
/// Return a pointer to the next non-debug instruction in the same basic
- /// block as 'this', or nullptr if no such instruction exists. Skip any pseudo
- /// operations if \c SkipPseudoOp is true.
- const Instruction *
- getNextNonDebugInstruction(bool SkipPseudoOp = false) const;
- Instruction *getNextNonDebugInstruction(bool SkipPseudoOp = false) {
+ /// block as 'this', or nullptr if no such instruction exists. Skip any pseudo
+ /// operations if \c SkipPseudoOp is true.
+ const Instruction *
+ getNextNonDebugInstruction(bool SkipPseudoOp = false) const;
+ Instruction *getNextNonDebugInstruction(bool SkipPseudoOp = false) {
return const_cast<Instruction *>(
- static_cast<const Instruction *>(this)->getNextNonDebugInstruction(
- SkipPseudoOp));
+ static_cast<const Instruction *>(this)->getNextNonDebugInstruction(
+ SkipPseudoOp));
}
/// Return a pointer to the previous non-debug instruction in the same basic
- /// block as 'this', or nullptr if no such instruction exists. Skip any pseudo
- /// operations if \c SkipPseudoOp is true.
- const Instruction *
- getPrevNonDebugInstruction(bool SkipPseudoOp = false) const;
- Instruction *getPrevNonDebugInstruction(bool SkipPseudoOp = false) {
+ /// block as 'this', or nullptr if no such instruction exists. Skip any pseudo
+ /// operations if \c SkipPseudoOp is true.
+ const Instruction *
+ getPrevNonDebugInstruction(bool SkipPseudoOp = false) const;
+ Instruction *getPrevNonDebugInstruction(bool SkipPseudoOp = false) {
return const_cast<Instruction *>(
- static_cast<const Instruction *>(this)->getPrevNonDebugInstruction(
- SkipPseudoOp));
+ static_cast<const Instruction *>(this)->getPrevNonDebugInstruction(
+ SkipPseudoOp));
}
/// Create a copy of 'this' instruction that is identical in all ways except
diff --git a/contrib/libs/llvm12/include/llvm/IR/Instructions.h b/contrib/libs/llvm12/include/llvm/IR/Instructions.h
index 954cac65cd..5c5842f214 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Instructions.h
+++ b/contrib/libs/llvm12/include/llvm/IR/Instructions.h
@@ -34,7 +34,7 @@
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallingConv.h"
-#include "llvm/IR/CFG.h"
+#include "llvm/IR/CFG.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
@@ -113,7 +113,7 @@ public:
/// Get allocation size in bits. Returns None if size can't be determined,
/// e.g. in case of a VLA.
- Optional<TypeSize> getAllocationSizeInBits(const DataLayout &DL) const;
+ Optional<TypeSize> getAllocationSizeInBits(const DataLayout &DL) const;
/// Return the type that is being allocated by the instruction.
Type *getAllocatedType() const { return AllocatedType; }
@@ -1314,30 +1314,30 @@ public:
return !isEquality(P);
}
- /// Return true if the predicate is SGT or UGT.
- ///
- static bool isGT(Predicate P) {
- return P == ICMP_SGT || P == ICMP_UGT;
- }
-
- /// Return true if the predicate is SLT or ULT.
- ///
- static bool isLT(Predicate P) {
- return P == ICMP_SLT || P == ICMP_ULT;
- }
-
- /// Return true if the predicate is SGE or UGE.
- ///
- static bool isGE(Predicate P) {
- return P == ICMP_SGE || P == ICMP_UGE;
- }
-
- /// Return true if the predicate is SLE or ULE.
- ///
- static bool isLE(Predicate P) {
- return P == ICMP_SLE || P == ICMP_ULE;
- }
-
+ /// Return true if the predicate is SGT or UGT.
+ ///
+ static bool isGT(Predicate P) {
+ return P == ICMP_SGT || P == ICMP_UGT;
+ }
+
+ /// Return true if the predicate is SLT or ULT.
+ ///
+ static bool isLT(Predicate P) {
+ return P == ICMP_SLT || P == ICMP_ULT;
+ }
+
+ /// Return true if the predicate is SGE or UGE.
+ ///
+ static bool isGE(Predicate P) {
+ return P == ICMP_SGE || P == ICMP_UGE;
+ }
+
+ /// Return true if the predicate is SLE or ULE.
+ ///
+ static bool isLE(Predicate P) {
+ return P == ICMP_SLE || P == ICMP_ULE;
+ }
+
/// Exchange the two operands to this instruction in such a way that it does
/// not modify the semantics of the instruction. The predicate value may be
/// changed to retain the same result if the predicate is order dependent
@@ -1661,16 +1661,16 @@ public:
static CallInst *Create(CallInst *CI, ArrayRef<OperandBundleDef> Bundles,
Instruction *InsertPt = nullptr);
- /// Create a clone of \p CI with a different set of operand bundles and
- /// insert it before \p InsertPt.
- ///
- /// The returned call instruction is identical \p CI in every way except that
- /// the operand bundle for the new instruction is set to the operand bundle
- /// in \p Bundle.
- static CallInst *CreateWithReplacedBundle(CallInst *CI,
- OperandBundleDef Bundle,
- Instruction *InsertPt = nullptr);
-
+ /// Create a clone of \p CI with a different set of operand bundles and
+ /// insert it before \p InsertPt.
+ ///
+ /// The returned call instruction is identical \p CI in every way except that
+ /// the operand bundle for the new instruction is set to the operand bundle
+ /// in \p Bundle.
+ static CallInst *CreateWithReplacedBundle(CallInst *CI,
+ OperandBundleDef Bundle,
+ Instruction *InsertPt = nullptr);
+
/// Generate the IR for a call to malloc:
/// 1. Compute the malloc call's argument as the specified type's size,
/// possibly multiplied by the array size if the array size is not
@@ -2146,9 +2146,9 @@ public:
/// Examples: shufflevector <4 x n> A, <4 x n> B, <1,2,3>
/// shufflevector <4 x n> A, <4 x n> B, <1,2,3,4,5>
bool changesLength() const {
- unsigned NumSourceElts = cast<VectorType>(Op<0>()->getType())
- ->getElementCount()
- .getKnownMinValue();
+ unsigned NumSourceElts = cast<VectorType>(Op<0>()->getType())
+ ->getElementCount()
+ .getKnownMinValue();
unsigned NumMaskElts = ShuffleMask.size();
return NumSourceElts != NumMaskElts;
}
@@ -2157,9 +2157,9 @@ public:
/// elements than its source vectors.
/// Example: shufflevector <2 x n> A, <2 x n> B, <1,2,3>
bool increasesLength() const {
- unsigned NumSourceElts = cast<VectorType>(Op<0>()->getType())
- ->getElementCount()
- .getKnownMinValue();
+ unsigned NumSourceElts = cast<VectorType>(Op<0>()->getType())
+ ->getElementCount()
+ .getKnownMinValue();
unsigned NumMaskElts = ShuffleMask.size();
return NumSourceElts < NumMaskElts;
}
@@ -2345,10 +2345,10 @@ public:
static bool isExtractSubvectorMask(const Constant *Mask, int NumSrcElts,
int &Index) {
assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant.");
- // Not possible to express a shuffle mask for a scalable vector for this
- // case.
- if (isa<ScalableVectorType>(Mask->getType()))
- return false;
+ // Not possible to express a shuffle mask for a scalable vector for this
+ // case.
+ if (isa<ScalableVectorType>(Mask->getType()))
+ return false;
SmallVector<int, 16> MaskAsInts;
getShuffleMask(Mask, MaskAsInts);
return isExtractSubvectorMask(MaskAsInts, NumSrcElts, Index);
@@ -2356,13 +2356,13 @@ public:
/// Return true if this shuffle mask is an extract subvector mask.
bool isExtractSubvectorMask(int &Index) const {
- // Not possible to express a shuffle mask for a scalable vector for this
- // case.
- if (isa<ScalableVectorType>(getType()))
- return false;
-
- int NumSrcElts =
- cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
+ // Not possible to express a shuffle mask for a scalable vector for this
+ // case.
+ if (isa<ScalableVectorType>(getType()))
+ return false;
+
+ int NumSrcElts =
+ cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
return isExtractSubvectorMask(ShuffleMask, NumSrcElts, Index);
}
@@ -2866,15 +2866,15 @@ public:
/// non-undef value.
bool hasConstantOrUndefValue() const;
- /// If the PHI node is complete which means all of its parent's predecessors
- /// have incoming value in this PHI, return true, otherwise return false.
- bool isComplete() const {
- return llvm::all_of(predecessors(getParent()),
- [this](const BasicBlock *Pred) {
- return getBasicBlockIndex(Pred) >= 0;
- });
- }
-
+ /// If the PHI node is complete which means all of its parent's predecessors
+ /// have incoming value in this PHI, return true, otherwise return false.
+ bool isComplete() const {
+ return llvm::all_of(predecessors(getParent()),
+ [this](const BasicBlock *Pred) {
+ return getBasicBlockIndex(Pred) >= 0;
+ });
+ }
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::PHI;
@@ -3900,16 +3900,16 @@ public:
static InvokeInst *Create(InvokeInst *II, ArrayRef<OperandBundleDef> Bundles,
Instruction *InsertPt = nullptr);
- /// Create a clone of \p II with a different set of operand bundles and
- /// insert it before \p InsertPt.
- ///
- /// The returned invoke instruction is identical to \p II in every way except
- /// that the operand bundle for the new instruction is set to the operand
- /// bundle in \p Bundle.
- static InvokeInst *CreateWithReplacedBundle(InvokeInst *II,
- OperandBundleDef Bundles,
- Instruction *InsertPt = nullptr);
-
+ /// Create a clone of \p II with a different set of operand bundles and
+ /// insert it before \p InsertPt.
+ ///
+ /// The returned invoke instruction is identical to \p II in every way except
+ /// that the operand bundle for the new instruction is set to the operand
+ /// bundle in \p Bundle.
+ static InvokeInst *CreateWithReplacedBundle(InvokeInst *II,
+ OperandBundleDef Bundles,
+ Instruction *InsertPt = nullptr);
+
// get*Dest - Return the destination basic blocks...
BasicBlock *getNormalDest() const {
return cast<BasicBlock>(Op<NormalDestOpEndIdx>());
diff --git a/contrib/libs/llvm12/include/llvm/IR/IntrinsicInst.h b/contrib/libs/llvm12/include/llvm/IR/IntrinsicInst.h
index 48d7d32a2f..c0a4dfc993 100644
--- a/contrib/libs/llvm12/include/llvm/IR/IntrinsicInst.h
+++ b/contrib/libs/llvm12/include/llvm/IR/IntrinsicInst.h
@@ -59,36 +59,36 @@ public:
return getCalledFunction()->getIntrinsicID();
}
- /// Return true if swapping the first two arguments to the intrinsic produces
- /// the same result.
- bool isCommutative() const {
- switch (getIntrinsicID()) {
- case Intrinsic::maxnum:
- case Intrinsic::minnum:
- case Intrinsic::maximum:
- case Intrinsic::minimum:
- case Intrinsic::smax:
- case Intrinsic::smin:
- case Intrinsic::umax:
- case Intrinsic::umin:
- case Intrinsic::sadd_sat:
- case Intrinsic::uadd_sat:
- case Intrinsic::sadd_with_overflow:
- case Intrinsic::uadd_with_overflow:
- case Intrinsic::smul_with_overflow:
- case Intrinsic::umul_with_overflow:
- case Intrinsic::smul_fix:
- case Intrinsic::umul_fix:
- case Intrinsic::smul_fix_sat:
- case Intrinsic::umul_fix_sat:
- case Intrinsic::fma:
- case Intrinsic::fmuladd:
- return true;
- default:
- return false;
- }
- }
-
+ /// Return true if swapping the first two arguments to the intrinsic produces
+ /// the same result.
+ bool isCommutative() const {
+ switch (getIntrinsicID()) {
+ case Intrinsic::maxnum:
+ case Intrinsic::minnum:
+ case Intrinsic::maximum:
+ case Intrinsic::minimum:
+ case Intrinsic::smax:
+ case Intrinsic::smin:
+ case Intrinsic::umax:
+ case Intrinsic::umin:
+ case Intrinsic::sadd_sat:
+ case Intrinsic::uadd_sat:
+ case Intrinsic::sadd_with_overflow:
+ case Intrinsic::uadd_with_overflow:
+ case Intrinsic::smul_with_overflow:
+ case Intrinsic::umul_with_overflow:
+ case Intrinsic::smul_fix:
+ case Intrinsic::umul_fix:
+ case Intrinsic::smul_fix_sat:
+ case Intrinsic::umul_fix_sat:
+ case Intrinsic::fma:
+ case Intrinsic::fmuladd:
+ return true;
+ default:
+ return false;
+ }
+ }
+
// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const CallInst *I) {
if (const Function *CF = I->getCalledFunction())
@@ -974,55 +974,55 @@ public:
}
};
-class PseudoProbeInst : public IntrinsicInst {
-public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::pseudoprobe;
- }
-
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
-
- ConstantInt *getFuncGuid() const {
- return cast<ConstantInt>(const_cast<Value *>(getArgOperand(0)));
- }
-
- ConstantInt *getIndex() const {
- return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
- }
-
- ConstantInt *getAttributes() const {
- return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2)));
- }
-
- ConstantInt *getFactor() const {
- return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
- }
-};
-
-class NoAliasScopeDeclInst : public IntrinsicInst {
-public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::experimental_noalias_scope_decl;
- }
-
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
-
- MDNode *getScopeList() const {
- auto *MV =
- cast<MetadataAsValue>(getOperand(Intrinsic::NoAliasScopeDeclScopeArg));
- return cast<MDNode>(MV->getMetadata());
- }
-
- void setScopeList(MDNode *ScopeList) {
- setOperand(Intrinsic::NoAliasScopeDeclScopeArg,
- MetadataAsValue::get(getContext(), ScopeList));
- }
-};
-
+class PseudoProbeInst : public IntrinsicInst {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::pseudoprobe;
+ }
+
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+
+ ConstantInt *getFuncGuid() const {
+ return cast<ConstantInt>(const_cast<Value *>(getArgOperand(0)));
+ }
+
+ ConstantInt *getIndex() const {
+ return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
+ }
+
+ ConstantInt *getAttributes() const {
+ return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2)));
+ }
+
+ ConstantInt *getFactor() const {
+ return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
+ }
+};
+
+class NoAliasScopeDeclInst : public IntrinsicInst {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::experimental_noalias_scope_decl;
+ }
+
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+
+ MDNode *getScopeList() const {
+ auto *MV =
+ cast<MetadataAsValue>(getOperand(Intrinsic::NoAliasScopeDeclScopeArg));
+ return cast<MDNode>(MV->getMetadata());
+ }
+
+ void setScopeList(MDNode *ScopeList) {
+ setOperand(Intrinsic::NoAliasScopeDeclScopeArg,
+ MetadataAsValue::get(getContext(), ScopeList));
+ }
+};
+
} // end namespace llvm
#endif // LLVM_IR_INTRINSICINST_H
diff --git a/contrib/libs/llvm12/include/llvm/IR/Intrinsics.h b/contrib/libs/llvm12/include/llvm/IR/Intrinsics.h
index e1b4e8e8d8..9b91cfb2af 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Intrinsics.h
+++ b/contrib/libs/llvm12/include/llvm/IR/Intrinsics.h
@@ -41,9 +41,9 @@ class AttributeList;
/// function known by LLVM. The enum values are returned by
/// Function::getIntrinsicID().
namespace Intrinsic {
- // Abstraction for the arguments of the noalias intrinsics
- static const int NoAliasScopeDeclScopeArg = 0;
-
+ // Abstraction for the arguments of the noalias intrinsics
+ static const int NoAliasScopeDeclScopeArg = 0;
+
// Intrinsic ID type. This is an opaque typedef to facilitate splitting up
// the enum into target-specific enums.
typedef unsigned ID;
@@ -135,8 +135,8 @@ namespace Intrinsic {
VecElementArgument,
Subdivide2Argument,
Subdivide4Argument,
- VecOfBitcastsToInt,
- AMX
+ VecOfBitcastsToInt,
+ AMX
} Kind;
union {
@@ -199,8 +199,8 @@ namespace Intrinsic {
}
static IITDescriptor getVector(unsigned Width, bool IsScalable) {
- IITDescriptor Result = {Vector, {0}};
- Result.Vector_Width = ElementCount::get(Width, IsScalable);
+ IITDescriptor Result = {Vector, {0}};
+ Result.Vector_Width = ElementCount::get(Width, IsScalable);
return Result;
}
};
diff --git a/contrib/libs/llvm12/include/llvm/IR/Intrinsics.td b/contrib/libs/llvm12/include/llvm/IR/Intrinsics.td
index 751d67347c..21307ed1bd 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Intrinsics.td
+++ b/contrib/libs/llvm12/include/llvm/IR/Intrinsics.td
@@ -17,9 +17,9 @@ include "llvm/CodeGen/SDNodeProperties.td"
// Properties we keep track of for intrinsics.
//===----------------------------------------------------------------------===//
-class IntrinsicProperty<bit is_default = false> {
- bit IsDefault = is_default;
-}
+class IntrinsicProperty<bit is_default = false> {
+ bit IsDefault = is_default;
+}
// Intr*Mem - Memory properties. If no property is set, the worst case
// is assumed (it may read and write any memory it can get access to and it may
@@ -79,11 +79,11 @@ class NoAlias<AttrIndex idx> : IntrinsicProperty {
int ArgNo = idx.Value;
}
-// NoUndef - The specified argument is neither undef nor poison.
-class NoUndef<AttrIndex idx> : IntrinsicProperty {
- int ArgNo = idx.Value;
-}
-
+// NoUndef - The specified argument is neither undef nor poison.
+class NoUndef<AttrIndex idx> : IntrinsicProperty {
+ int ArgNo = idx.Value;
+}
+
class Align<AttrIndex idx, int align> : IntrinsicProperty {
int ArgNo = idx.Value;
int Align = align;
@@ -120,16 +120,16 @@ class ReadNone<AttrIndex idx> : IntrinsicProperty {
def IntrNoReturn : IntrinsicProperty;
-// IntrNoSync - Threads executing the intrinsic will not synchronize using
-// memory or other means. Applied by default.
-def IntrNoSync : IntrinsicProperty<1>;
+// IntrNoSync - Threads executing the intrinsic will not synchronize using
+// memory or other means. Applied by default.
+def IntrNoSync : IntrinsicProperty<1>;
-// Applied by default.
-def IntrNoFree : IntrinsicProperty<1>;
+// Applied by default.
+def IntrNoFree : IntrinsicProperty<1>;
+
+// Applied by default.
+def IntrWillReturn : IntrinsicProperty<1>;
-// Applied by default.
-def IntrWillReturn : IntrinsicProperty<1>;
-
// IntrCold - Calls to this intrinsic are cold.
// Parallels the cold attribute on LLVM IR functions.
def IntrCold : IntrinsicProperty;
@@ -161,7 +161,7 @@ def IntrHasSideEffects : IntrinsicProperty;
class LLVMType<ValueType vt> {
ValueType VT = vt;
- int isAny = false;
+ int isAny = false;
}
class LLVMQualPointerType<LLVMType elty, int addrspace>
@@ -177,7 +177,7 @@ class LLVMAnyPointerType<LLVMType elty>
: LLVMType<iPTRAny>{
LLVMType ElTy = elty;
- let isAny = true;
+ let isAny = true;
}
// Match the type of another intrinsic parameter. Number is an index into the
@@ -226,7 +226,7 @@ class LLVMSubdivide4VectorType<int num> : LLVMMatchType<num>;
class LLVMVectorOfBitcastsToInt<int num> : LLVMMatchType<num>;
def llvm_void_ty : LLVMType<isVoid>;
-let isAny = true in {
+let isAny = true in {
def llvm_any_ty : LLVMType<Any>;
def llvm_anyint_ty : LLVMType<iAny>;
def llvm_anyfloat_ty : LLVMType<fAny>;
@@ -255,8 +255,8 @@ def llvm_token_ty : LLVMType<token>; // token
def llvm_x86mmx_ty : LLVMType<x86mmx>;
def llvm_ptrx86mmx_ty : LLVMPointerType<llvm_x86mmx_ty>; // <1 x i64>*
-def llvm_x86amx_ty : LLVMType<x86amx>;
-
+def llvm_x86amx_ty : LLVMType<x86amx>;
+
def llvm_v2i1_ty : LLVMType<v2i1>; // 2 x i1
def llvm_v4i1_ty : LLVMType<v4i1>; // 4 x i1
def llvm_v8i1_ty : LLVMType<v8i1>; // 8 x i1
@@ -264,7 +264,7 @@ def llvm_v16i1_ty : LLVMType<v16i1>; // 16 x i1
def llvm_v32i1_ty : LLVMType<v32i1>; // 32 x i1
def llvm_v64i1_ty : LLVMType<v64i1>; // 64 x i1
def llvm_v128i1_ty : LLVMType<v128i1>; // 128 x i1
-def llvm_v256i1_ty : LLVMType<v256i1>; // 256 x i1
+def llvm_v256i1_ty : LLVMType<v256i1>; // 256 x i1
def llvm_v512i1_ty : LLVMType<v512i1>; // 512 x i1
def llvm_v1024i1_ty : LLVMType<v1024i1>; //1024 x i1
@@ -294,7 +294,7 @@ def llvm_v8i32_ty : LLVMType<v8i32>; // 8 x i32
def llvm_v16i32_ty : LLVMType<v16i32>; // 16 x i32
def llvm_v32i32_ty : LLVMType<v32i32>; // 32 x i32
def llvm_v64i32_ty : LLVMType<v64i32>; // 64 x i32
-def llvm_v256i32_ty : LLVMType<v256i32>; //256 x i32
+def llvm_v256i32_ty : LLVMType<v256i32>; //256 x i32
def llvm_v1i64_ty : LLVMType<v1i64>; // 1 x i64
def llvm_v2i64_ty : LLVMType<v2i64>; // 2 x i64
@@ -344,8 +344,8 @@ class Intrinsic<list<LLVMType> ret_types,
list<LLVMType> param_types = [],
list<IntrinsicProperty> intr_properties = [],
string name = "",
- list<SDNodeProperty> sd_properties = [],
- bit disable_default_attributes = true> : SDPatternOperator {
+ list<SDNodeProperty> sd_properties = [],
+ bit disable_default_attributes = true> : SDPatternOperator {
string LLVMName = name;
string TargetPrefix = ""; // Set to a prefix for target-specific intrinsics.
list<LLVMType> RetTypes = ret_types;
@@ -353,23 +353,23 @@ class Intrinsic<list<LLVMType> ret_types,
list<IntrinsicProperty> IntrProperties = intr_properties;
let Properties = sd_properties;
- // Disable applying IntrinsicProperties that are marked default with
- // IntrinsicProperty<1>
- bit DisableDefaultAttributes = disable_default_attributes;
-
- bit isTarget = false;
+ // Disable applying IntrinsicProperties that are marked default with
+ // IntrinsicProperty<1>
+ bit DisableDefaultAttributes = disable_default_attributes;
+
+ bit isTarget = false;
}
-// Intrinisc with default attributes (disable_default_attributes = false).
-class DefaultAttrsIntrinsic<list<LLVMType> ret_types,
- list<LLVMType> param_types = [],
- list<IntrinsicProperty> intr_properties = [],
- string name = "",
- list<SDNodeProperty> sd_properties = []>
- : Intrinsic<ret_types, param_types,
- intr_properties, name,
- sd_properties, /*disable_default_attributes*/ 0> {}
-
+// Intrinisc with default attributes (disable_default_attributes = false).
+class DefaultAttrsIntrinsic<list<LLVMType> ret_types,
+ list<LLVMType> param_types = [],
+ list<IntrinsicProperty> intr_properties = [],
+ string name = "",
+ list<SDNodeProperty> sd_properties = []>
+ : Intrinsic<ret_types, param_types,
+ intr_properties, name,
+ sd_properties, /*disable_default_attributes*/ 0> {}
+
/// GCCBuiltin - If this intrinsic exactly corresponds to a GCC builtin, this
/// specifies the name of the builtin. This provides automatic CBE and CFE
/// support.
@@ -385,10 +385,10 @@ class MSBuiltin<string name> {
//===--------------- Variable Argument Handling Intrinsics ----------------===//
//
-def int_vastart : DefaultAttrsIntrinsic<[], [llvm_ptr_ty], [], "llvm.va_start">;
-def int_vacopy : DefaultAttrsIntrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], [],
+def int_vastart : DefaultAttrsIntrinsic<[], [llvm_ptr_ty], [], "llvm.va_start">;
+def int_vacopy : DefaultAttrsIntrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], [],
"llvm.va_copy">;
-def int_vaend : DefaultAttrsIntrinsic<[], [llvm_ptr_ty], [], "llvm.va_end">;
+def int_vaend : DefaultAttrsIntrinsic<[], [llvm_ptr_ty], [], "llvm.va_end">;
//===------------------- Garbage Collection Intrinsics --------------------===//
//
@@ -476,12 +476,12 @@ def int_objc_arc_annotation_bottomup_bbend : Intrinsic<[],
//===--------------------- Code Generator Intrinsics ----------------------===//
//
-def int_returnaddress : DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_i32_ty],
+def int_returnaddress : DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<0>>]>;
-def int_addressofreturnaddress : DefaultAttrsIntrinsic<[llvm_anyptr_ty], [], [IntrNoMem]>;
-def int_frameaddress : DefaultAttrsIntrinsic<[llvm_anyptr_ty], [llvm_i32_ty],
+def int_addressofreturnaddress : DefaultAttrsIntrinsic<[llvm_anyptr_ty], [], [IntrNoMem]>;
+def int_frameaddress : DefaultAttrsIntrinsic<[llvm_anyptr_ty], [llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<0>>]>;
-def int_sponentry : DefaultAttrsIntrinsic<[llvm_anyptr_ty], [], [IntrNoMem]>;
+def int_sponentry : DefaultAttrsIntrinsic<[llvm_anyptr_ty], [], [IntrNoMem]>;
def int_read_register : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty],
[IntrReadMem], "llvm.read_register">;
def int_write_register : Intrinsic<[], [llvm_metadata_ty, llvm_anyint_ty],
@@ -492,33 +492,33 @@ def int_read_volatile_register : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty]
// Gets the address of the local variable area. This is typically a copy of the
// stack, frame, or base pointer depending on the type of prologue.
-def int_localaddress : DefaultAttrsIntrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
+def int_localaddress : DefaultAttrsIntrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
// Escapes local variables to allow access from other functions.
-def int_localescape : DefaultAttrsIntrinsic<[], [llvm_vararg_ty]>;
+def int_localescape : DefaultAttrsIntrinsic<[], [llvm_vararg_ty]>;
// Given a function and the localaddress of a parent frame, returns a pointer
// to an escaped allocation indicated by the index.
-def int_localrecover : DefaultAttrsIntrinsic<[llvm_ptr_ty],
+def int_localrecover : DefaultAttrsIntrinsic<[llvm_ptr_ty],
[llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<2>>]>;
// Given the frame pointer passed into an SEH filter function, returns a
// pointer to the local variable area suitable for use with llvm.localrecover.
-def int_eh_recoverfp : DefaultAttrsIntrinsic<[llvm_ptr_ty],
+def int_eh_recoverfp : DefaultAttrsIntrinsic<[llvm_ptr_ty],
[llvm_ptr_ty, llvm_ptr_ty],
[IntrNoMem]>;
// Note: we treat stacksave/stackrestore as writemem because we don't otherwise
// model their dependencies on allocas.
-def int_stacksave : DefaultAttrsIntrinsic<[llvm_ptr_ty]>,
+def int_stacksave : DefaultAttrsIntrinsic<[llvm_ptr_ty]>,
GCCBuiltin<"__builtin_stack_save">;
-def int_stackrestore : DefaultAttrsIntrinsic<[], [llvm_ptr_ty]>,
+def int_stackrestore : DefaultAttrsIntrinsic<[], [llvm_ptr_ty]>,
GCCBuiltin<"__builtin_stack_restore">;
-def int_get_dynamic_area_offset : DefaultAttrsIntrinsic<[llvm_anyint_ty]>;
+def int_get_dynamic_area_offset : DefaultAttrsIntrinsic<[llvm_anyint_ty]>;
-def int_thread_pointer : DefaultAttrsIntrinsic<[llvm_ptr_ty], [], [IntrNoMem]>,
+def int_thread_pointer : DefaultAttrsIntrinsic<[llvm_ptr_ty], [], [IntrNoMem]>,
GCCBuiltin<"__builtin_thread_pointer">;
// IntrInaccessibleMemOrArgMemOnly is a little more pessimistic than strictly
@@ -526,59 +526,59 @@ def int_thread_pointer : DefaultAttrsIntrinsic<[llvm_ptr_ty], [], [IntrNoMem]>,
// from being reordered overly much with respect to nearby access to the same
// memory while not impeding optimization.
def int_prefetch
- : DefaultAttrsIntrinsic<[], [ llvm_anyptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty ],
+ : DefaultAttrsIntrinsic<[], [ llvm_anyptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty ],
[IntrInaccessibleMemOrArgMemOnly, IntrWillReturn,
ReadOnly<ArgIndex<0>>, NoCapture<ArgIndex<0>>,
ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
-def int_pcmarker : DefaultAttrsIntrinsic<[], [llvm_i32_ty]>;
+def int_pcmarker : DefaultAttrsIntrinsic<[], [llvm_i32_ty]>;
-def int_readcyclecounter : DefaultAttrsIntrinsic<[llvm_i64_ty]>;
+def int_readcyclecounter : DefaultAttrsIntrinsic<[llvm_i64_ty]>;
// The assume intrinsic is marked as arbitrarily writing so that proper
// control dependencies will be maintained.
-def int_assume : DefaultAttrsIntrinsic<[], [llvm_i1_ty], [IntrWillReturn,
- NoUndef<ArgIndex<0>>]>;
-
-// 'llvm.experimental.noalias.scope.decl' intrinsic: Inserted at the location of
-// noalias scope declaration. Makes it possible to identify that a noalias scope
-// is only valid inside the body of a loop.
-//
-// Purpose of the different arguments:
-// - arg0: id.scope: metadata representing the scope declaration.
-def int_experimental_noalias_scope_decl
- : DefaultAttrsIntrinsic<[], [llvm_metadata_ty],
- [IntrInaccessibleMemOnly]>; // blocks LICM and some more
-
+def int_assume : DefaultAttrsIntrinsic<[], [llvm_i1_ty], [IntrWillReturn,
+ NoUndef<ArgIndex<0>>]>;
+
+// 'llvm.experimental.noalias.scope.decl' intrinsic: Inserted at the location of
+// noalias scope declaration. Makes it possible to identify that a noalias scope
+// is only valid inside the body of a loop.
+//
+// Purpose of the different arguments:
+// - arg0: id.scope: metadata representing the scope declaration.
+def int_experimental_noalias_scope_decl
+ : DefaultAttrsIntrinsic<[], [llvm_metadata_ty],
+ [IntrInaccessibleMemOnly]>; // blocks LICM and some more
+
// Stack Protector Intrinsic - The stackprotector intrinsic writes the stack
// guard to the correct place on the stack frame.
-def int_stackprotector : DefaultAttrsIntrinsic<[], [llvm_ptr_ty, llvm_ptrptr_ty], []>;
-def int_stackguard : DefaultAttrsIntrinsic<[llvm_ptr_ty], [], []>;
+def int_stackprotector : DefaultAttrsIntrinsic<[], [llvm_ptr_ty, llvm_ptrptr_ty], []>;
+def int_stackguard : DefaultAttrsIntrinsic<[llvm_ptr_ty], [], []>;
// A counter increment for instrumentation based profiling.
def int_instrprof_increment : Intrinsic<[],
[llvm_ptr_ty, llvm_i64_ty,
- llvm_i32_ty, llvm_i32_ty]>;
+ llvm_i32_ty, llvm_i32_ty]>;
// A counter increment with step for instrumentation based profiling.
def int_instrprof_increment_step : Intrinsic<[],
[llvm_ptr_ty, llvm_i64_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i64_ty]>;
+ llvm_i32_ty, llvm_i32_ty, llvm_i64_ty]>;
// A call to profile runtime for value profiling of target expressions
// through instrumentation based profiling.
def int_instrprof_value_profile : Intrinsic<[],
[llvm_ptr_ty, llvm_i64_ty,
llvm_i64_ty, llvm_i32_ty,
- llvm_i32_ty]>;
+ llvm_i32_ty]>;
-def int_call_preallocated_setup : DefaultAttrsIntrinsic<[llvm_token_ty], [llvm_i32_ty]>;
-def int_call_preallocated_arg : DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_i32_ty]>;
-def int_call_preallocated_teardown : DefaultAttrsIntrinsic<[], [llvm_token_ty]>;
+def int_call_preallocated_setup : DefaultAttrsIntrinsic<[llvm_token_ty], [llvm_i32_ty]>;
+def int_call_preallocated_arg : DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_i32_ty]>;
+def int_call_preallocated_teardown : DefaultAttrsIntrinsic<[], [llvm_token_ty]>;
//===------------------- Standard C Library Intrinsics --------------------===//
//
-def int_memcpy : DefaultAttrsIntrinsic<[],
+def int_memcpy : DefaultAttrsIntrinsic<[],
[llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
llvm_i1_ty],
[IntrArgMemOnly, IntrWillReturn,
@@ -592,7 +592,7 @@ def int_memcpy : DefaultAttrsIntrinsic<[],
// external function.
// The third argument (specifying the size) must be a constant.
def int_memcpy_inline
- : DefaultAttrsIntrinsic<[],
+ : DefaultAttrsIntrinsic<[],
[llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty, llvm_i1_ty],
[IntrArgMemOnly, IntrWillReturn,
NoCapture<ArgIndex<0>>, NoCapture<ArgIndex<1>>,
@@ -600,14 +600,14 @@ def int_memcpy_inline
WriteOnly<ArgIndex<0>>, ReadOnly<ArgIndex<1>>,
ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;
-def int_memmove : DefaultAttrsIntrinsic<[],
+def int_memmove : DefaultAttrsIntrinsic<[],
[llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
llvm_i1_ty],
[IntrArgMemOnly, IntrWillReturn,
NoCapture<ArgIndex<0>>, NoCapture<ArgIndex<1>>,
- WriteOnly<ArgIndex<0>>, ReadOnly<ArgIndex<1>>,
- ImmArg<ArgIndex<3>>]>;
-def int_memset : DefaultAttrsIntrinsic<[],
+ WriteOnly<ArgIndex<0>>, ReadOnly<ArgIndex<1>>,
+ ImmArg<ArgIndex<3>>]>;
+def int_memset : DefaultAttrsIntrinsic<[],
[llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty,
llvm_i1_ty],
[IntrWriteMem, IntrArgMemOnly, IntrWillReturn,
@@ -618,65 +618,65 @@ def int_memset : DefaultAttrsIntrinsic<[],
// rounding modes and FP exception handling.
let IntrProperties = [IntrNoMem, IntrSpeculatable, IntrWillReturn] in {
- def int_fma : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
+ def int_fma : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
[LLVMMatchType<0>, LLVMMatchType<0>,
LLVMMatchType<0>]>;
- def int_fmuladd : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
+ def int_fmuladd : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
[LLVMMatchType<0>, LLVMMatchType<0>,
LLVMMatchType<0>]>;
// These functions do not read memory, but are sensitive to the
// rounding mode. LLVM purposely does not model changes to the FP
// environment so they can be treated as readnone.
- def int_sqrt : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
- def int_powi : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty]>;
- def int_sin : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
- def int_cos : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
- def int_pow : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
+ def int_sqrt : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_powi : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty]>;
+ def int_sin : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_cos : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_pow : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
[LLVMMatchType<0>, LLVMMatchType<0>]>;
- def int_log : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
- def int_log10: DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
- def int_log2 : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
- def int_exp : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
- def int_exp2 : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
- def int_fabs : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
- def int_copysign : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
+ def int_log : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_log10: DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_log2 : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_exp : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_exp2 : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_fabs : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_copysign : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
[LLVMMatchType<0>, LLVMMatchType<0>]>;
- def int_floor : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
- def int_ceil : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
- def int_trunc : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
- def int_rint : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
- def int_nearbyint : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
- def int_round : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
- def int_roundeven : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
- def int_canonicalize : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>],
+ def int_floor : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_ceil : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_trunc : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_rint : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_nearbyint : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_round : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_roundeven : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_canonicalize : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>],
[IntrNoMem]>;
- def int_lround : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>;
- def int_llround : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>;
- def int_lrint : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>;
- def int_llrint : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>;
+ def int_lround : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>;
+ def int_llround : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>;
+ def int_lrint : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>;
+ def int_llrint : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>;
}
-def int_minnum : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
+def int_minnum : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem, IntrSpeculatable, IntrWillReturn, Commutative]
>;
-def int_maxnum : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
+def int_maxnum : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem, IntrSpeculatable, IntrWillReturn, Commutative]
>;
-def int_minimum : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
+def int_minimum : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem, IntrSpeculatable, IntrWillReturn, Commutative]
>;
-def int_maximum : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
+def int_maximum : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem, IntrSpeculatable, IntrWillReturn, Commutative]
>;
// Internal interface for object size checking
-def int_objectsize : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+def int_objectsize : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[llvm_anyptr_ty, llvm_i1_ty,
llvm_i1_ty, llvm_i1_ty],
[IntrNoMem, IntrSpeculatable, IntrWillReturn,
@@ -688,77 +688,77 @@ def int_objectsize : DefaultAttrsIntrinsic<[llvm_anyint_ty],
//
let IntrProperties = [IntrInaccessibleMemOnly, IntrWillReturn] in {
- def int_flt_rounds : DefaultAttrsIntrinsic<[llvm_i32_ty], []>;
+ def int_flt_rounds : DefaultAttrsIntrinsic<[llvm_i32_ty], []>;
}
//===--------------- Constrained Floating Point Intrinsics ----------------===//
//
let IntrProperties = [IntrInaccessibleMemOnly, IntrWillReturn] in {
- def int_experimental_constrained_fadd : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_fadd : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_fsub : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_fsub : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_fmul : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_fmul : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_fdiv : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_fdiv : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_frem : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_frem : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_fma : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_fma : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_fmuladd : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_fmuladd : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_fptosi : DefaultAttrsIntrinsic<[ llvm_anyint_ty ],
+ def int_experimental_constrained_fptosi : DefaultAttrsIntrinsic<[ llvm_anyint_ty ],
[ llvm_anyfloat_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_fptoui : DefaultAttrsIntrinsic<[ llvm_anyint_ty ],
+ def int_experimental_constrained_fptoui : DefaultAttrsIntrinsic<[ llvm_anyint_ty ],
[ llvm_anyfloat_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_sitofp : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_sitofp : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ llvm_anyint_ty,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_uitofp : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_uitofp : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ llvm_anyint_ty,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_fptrunc : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_fptrunc : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ llvm_anyfloat_ty,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_fpext : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_fpext : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ llvm_anyfloat_ty,
llvm_metadata_ty ]>;
@@ -766,110 +766,110 @@ let IntrProperties = [IntrInaccessibleMemOnly, IntrWillReturn] in {
// versions of each of them. When strict rounding and exception control are
// not required the non-constrained versions of these intrinsics should be
// used.
- def int_experimental_constrained_sqrt : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_sqrt : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_powi : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_powi : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
llvm_i32_ty,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_sin : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_sin : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_cos : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_cos : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_pow : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_pow : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_log : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_log : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_log10: DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_log10: DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_log2 : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_log2 : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_exp : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_exp : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_exp2 : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_exp2 : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_rint : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_rint : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_nearbyint : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_nearbyint : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_lrint : DefaultAttrsIntrinsic<[ llvm_anyint_ty ],
+ def int_experimental_constrained_lrint : DefaultAttrsIntrinsic<[ llvm_anyint_ty ],
[ llvm_anyfloat_ty,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_llrint : DefaultAttrsIntrinsic<[ llvm_anyint_ty ],
+ def int_experimental_constrained_llrint : DefaultAttrsIntrinsic<[ llvm_anyint_ty ],
[ llvm_anyfloat_ty,
llvm_metadata_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_maxnum : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_maxnum : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_metadata_ty ]>;
- def int_experimental_constrained_minnum : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_minnum : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_metadata_ty ]>;
- def int_experimental_constrained_maximum : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_maximum : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_metadata_ty ]>;
- def int_experimental_constrained_minimum : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_minimum : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_metadata_ty ]>;
- def int_experimental_constrained_ceil : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_ceil : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
llvm_metadata_ty ]>;
- def int_experimental_constrained_floor : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_floor : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
llvm_metadata_ty ]>;
- def int_experimental_constrained_lround : DefaultAttrsIntrinsic<[ llvm_anyint_ty ],
+ def int_experimental_constrained_lround : DefaultAttrsIntrinsic<[ llvm_anyint_ty ],
[ llvm_anyfloat_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_llround : DefaultAttrsIntrinsic<[ llvm_anyint_ty ],
+ def int_experimental_constrained_llround : DefaultAttrsIntrinsic<[ llvm_anyint_ty ],
[ llvm_anyfloat_ty,
llvm_metadata_ty ]>;
- def int_experimental_constrained_round : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_round : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
llvm_metadata_ty ]>;
- def int_experimental_constrained_roundeven : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_roundeven : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
llvm_metadata_ty ]>;
- def int_experimental_constrained_trunc : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
+ def int_experimental_constrained_trunc : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
llvm_metadata_ty ]>;
// Constrained floating-point comparison (quiet and signaling variants).
// Third operand is the predicate represented as a metadata string.
def int_experimental_constrained_fcmp
- : DefaultAttrsIntrinsic<[ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty> ],
+ : DefaultAttrsIntrinsic<[ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty> ],
[ llvm_anyfloat_ty, LLVMMatchType<0>,
llvm_metadata_ty, llvm_metadata_ty ]>;
def int_experimental_constrained_fcmps
- : DefaultAttrsIntrinsic<[ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty> ],
+ : DefaultAttrsIntrinsic<[ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty> ],
[ llvm_anyfloat_ty, LLVMMatchType<0>,
llvm_metadata_ty, llvm_metadata_ty ]>;
}
@@ -877,10 +877,10 @@ let IntrProperties = [IntrInaccessibleMemOnly, IntrWillReturn] in {
//===------------------------- Expect Intrinsics --------------------------===//
//
-def int_expect : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+def int_expect : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, IntrWillReturn]>;
-def int_expect_with_probability : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+def int_expect_with_probability : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_double_ty],
[IntrNoMem, IntrWillReturn]>;
@@ -889,19 +889,19 @@ def int_expect_with_probability : DefaultAttrsIntrinsic<[llvm_anyint_ty],
// None of these intrinsics accesses memory at all.
let IntrProperties = [IntrNoMem, IntrSpeculatable, IntrWillReturn] in {
- def int_bswap: DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
- def int_ctpop: DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
- def int_bitreverse : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
- def int_fshl : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+ def int_bswap: DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
+ def int_ctpop: DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
+ def int_bitreverse : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
+ def int_fshl : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>]>;
- def int_fshr : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+ def int_fshr : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>]>;
}
let IntrProperties = [IntrNoMem, IntrSpeculatable, IntrWillReturn,
ImmArg<ArgIndex<1>>] in {
- def int_ctlz : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>;
- def int_cttz : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>;
+ def int_ctlz : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>;
+ def int_cttz : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>;
}
//===------------------------ Debugger Intrinsics -------------------------===//
@@ -912,19 +912,19 @@ let IntrProperties = [IntrNoMem, IntrSpeculatable, IntrWillReturn,
// needed in a few places. These synthetic intrinsics have no
// side-effects and just mark information about their operands.
let IntrProperties = [IntrNoMem, IntrSpeculatable, IntrWillReturn] in {
- def int_dbg_declare : DefaultAttrsIntrinsic<[],
+ def int_dbg_declare : DefaultAttrsIntrinsic<[],
[llvm_metadata_ty,
llvm_metadata_ty,
llvm_metadata_ty]>;
- def int_dbg_value : DefaultAttrsIntrinsic<[],
+ def int_dbg_value : DefaultAttrsIntrinsic<[],
[llvm_metadata_ty,
llvm_metadata_ty,
llvm_metadata_ty]>;
- def int_dbg_addr : DefaultAttrsIntrinsic<[],
+ def int_dbg_addr : DefaultAttrsIntrinsic<[],
[llvm_metadata_ty,
llvm_metadata_ty,
llvm_metadata_ty]>;
- def int_dbg_label : DefaultAttrsIntrinsic<[],
+ def int_dbg_label : DefaultAttrsIntrinsic<[],
[llvm_metadata_ty]>;
}
@@ -954,9 +954,9 @@ def int_eh_unwind_init: Intrinsic<[]>,
def int_eh_dwarf_cfa : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>;
-def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
-def int_eh_sjlj_callsite : Intrinsic<[], [llvm_i32_ty], [IntrNoMem]>;
-
+def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
+def int_eh_sjlj_callsite : Intrinsic<[], [llvm_i32_ty], [IntrNoMem]>;
+
def int_eh_sjlj_functioncontext : Intrinsic<[], [llvm_ptr_ty]>;
def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty], [IntrNoReturn]>;
@@ -964,15 +964,15 @@ def int_eh_sjlj_setup_dispatch : Intrinsic<[], []>;
//===---------------- Generic Variable Attribute Intrinsics----------------===//
//
-def int_var_annotation : DefaultAttrsIntrinsic<[],
+def int_var_annotation : DefaultAttrsIntrinsic<[],
[llvm_ptr_ty, llvm_ptr_ty,
- llvm_ptr_ty, llvm_i32_ty, llvm_ptr_ty],
+ llvm_ptr_ty, llvm_i32_ty, llvm_ptr_ty],
[IntrWillReturn], "llvm.var.annotation">;
-def int_ptr_annotation : DefaultAttrsIntrinsic<[LLVMAnyPointerType<llvm_anyint_ty>],
+def int_ptr_annotation : DefaultAttrsIntrinsic<[LLVMAnyPointerType<llvm_anyint_ty>],
[LLVMMatchType<0>, llvm_ptr_ty, llvm_ptr_ty,
- llvm_i32_ty, llvm_ptr_ty],
+ llvm_i32_ty, llvm_ptr_ty],
[IntrWillReturn], "llvm.ptr.annotation">;
-def int_annotation : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+def int_annotation : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, llvm_ptr_ty,
llvm_ptr_ty, llvm_i32_ty],
[IntrWillReturn], "llvm.annotation">;
@@ -980,7 +980,7 @@ def int_annotation : DefaultAttrsIntrinsic<[llvm_anyint_ty],
// Annotates the current program point with metadata strings which are emitted
// as CodeView debug info records. This is expensive, as it disables inlining
// and is modelled as having side effects.
-def int_codeview_annotation : DefaultAttrsIntrinsic<[], [llvm_metadata_ty],
+def int_codeview_annotation : DefaultAttrsIntrinsic<[], [llvm_metadata_ty],
[IntrInaccessibleMemOnly, IntrNoDuplicate, IntrWillReturn],
"llvm.codeview.annotation">;
@@ -1000,124 +1000,124 @@ def int_adjust_trampoline : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty],
// Expose the carry flag from add operations on two integrals.
let IntrProperties = [IntrNoMem, IntrSpeculatable, IntrWillReturn] in {
- def int_sadd_with_overflow : DefaultAttrsIntrinsic<[llvm_anyint_ty,
+ def int_sadd_with_overflow : DefaultAttrsIntrinsic<[llvm_anyint_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
[LLVMMatchType<0>, LLVMMatchType<0>]>;
- def int_uadd_with_overflow : DefaultAttrsIntrinsic<[llvm_anyint_ty,
+ def int_uadd_with_overflow : DefaultAttrsIntrinsic<[llvm_anyint_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
[LLVMMatchType<0>, LLVMMatchType<0>]>;
- def int_ssub_with_overflow : DefaultAttrsIntrinsic<[llvm_anyint_ty,
+ def int_ssub_with_overflow : DefaultAttrsIntrinsic<[llvm_anyint_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
[LLVMMatchType<0>, LLVMMatchType<0>]>;
- def int_usub_with_overflow : DefaultAttrsIntrinsic<[llvm_anyint_ty,
+ def int_usub_with_overflow : DefaultAttrsIntrinsic<[llvm_anyint_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
[LLVMMatchType<0>, LLVMMatchType<0>]>;
- def int_smul_with_overflow : DefaultAttrsIntrinsic<[llvm_anyint_ty,
+ def int_smul_with_overflow : DefaultAttrsIntrinsic<[llvm_anyint_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
[LLVMMatchType<0>, LLVMMatchType<0>]>;
- def int_umul_with_overflow : DefaultAttrsIntrinsic<[llvm_anyint_ty,
+ def int_umul_with_overflow : DefaultAttrsIntrinsic<[llvm_anyint_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
[LLVMMatchType<0>, LLVMMatchType<0>]>;
}
//===------------------------- Saturation Arithmetic Intrinsics ---------------------===//
//
-def int_sadd_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+def int_sadd_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem, IntrSpeculatable, IntrWillReturn, Commutative]>;
-def int_uadd_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+def int_uadd_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem, IntrSpeculatable, IntrWillReturn, Commutative]>;
-def int_ssub_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+def int_ssub_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
+def int_usub_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
+def int_sshl_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
-def int_usub_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+def int_ushl_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
-def int_sshl_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
- [LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
-def int_ushl_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
- [LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
//===------------------------- Fixed Point Arithmetic Intrinsics ---------------------===//
//
-def int_smul_fix : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+def int_smul_fix : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
[IntrNoMem, IntrSpeculatable, IntrWillReturn,
Commutative, ImmArg<ArgIndex<2>>]>;
-def int_umul_fix : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+def int_umul_fix : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
[IntrNoMem, IntrSpeculatable, IntrWillReturn,
Commutative, ImmArg<ArgIndex<2>>]>;
-def int_sdiv_fix : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+def int_sdiv_fix : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<2>>]>;
-def int_udiv_fix : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+def int_udiv_fix : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<2>>]>;
//===------------------- Fixed Point Saturation Arithmetic Intrinsics ----------------===//
//
-def int_smul_fix_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+def int_smul_fix_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
[IntrNoMem, IntrSpeculatable, IntrWillReturn,
Commutative, ImmArg<ArgIndex<2>>]>;
-def int_umul_fix_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+def int_umul_fix_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
[IntrNoMem, IntrSpeculatable, IntrWillReturn,
Commutative, ImmArg<ArgIndex<2>>]>;
-def int_sdiv_fix_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+def int_sdiv_fix_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<2>>]>;
-def int_udiv_fix_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+def int_udiv_fix_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<2>>]>;
-//===------------------ Integer Min/Max/Abs Intrinsics --------------------===//
-//
-def int_abs : DefaultAttrsIntrinsic<
- [llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty],
- [IntrNoMem, IntrSpeculatable, IntrWillReturn, ImmArg<ArgIndex<1>>]>;
-
-def int_smax : DefaultAttrsIntrinsic<
- [llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
-def int_smin : DefaultAttrsIntrinsic<
- [llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
-def int_umax : DefaultAttrsIntrinsic<
- [llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
-def int_umin : DefaultAttrsIntrinsic<
- [llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
-
+//===------------------ Integer Min/Max/Abs Intrinsics --------------------===//
+//
+def int_abs : DefaultAttrsIntrinsic<
+ [llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty],
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn, ImmArg<ArgIndex<1>>]>;
+
+def int_smax : DefaultAttrsIntrinsic<
+ [llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
+def int_smin : DefaultAttrsIntrinsic<
+ [llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
+def int_umax : DefaultAttrsIntrinsic<
+ [llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
+def int_umin : DefaultAttrsIntrinsic<
+ [llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
+
//===------------------------- Memory Use Markers -------------------------===//
//
-def int_lifetime_start : DefaultAttrsIntrinsic<[],
+def int_lifetime_start : DefaultAttrsIntrinsic<[],
[llvm_i64_ty, llvm_anyptr_ty],
[IntrArgMemOnly, IntrWillReturn,
NoCapture<ArgIndex<1>>,
ImmArg<ArgIndex<0>>]>;
-def int_lifetime_end : DefaultAttrsIntrinsic<[],
+def int_lifetime_end : DefaultAttrsIntrinsic<[],
[llvm_i64_ty, llvm_anyptr_ty],
[IntrArgMemOnly, IntrWillReturn,
NoCapture<ArgIndex<1>>,
ImmArg<ArgIndex<0>>]>;
-def int_invariant_start : DefaultAttrsIntrinsic<[llvm_descriptor_ty],
+def int_invariant_start : DefaultAttrsIntrinsic<[llvm_descriptor_ty],
[llvm_i64_ty, llvm_anyptr_ty],
[IntrArgMemOnly, IntrWillReturn,
NoCapture<ArgIndex<1>>,
ImmArg<ArgIndex<0>>]>;
-def int_invariant_end : DefaultAttrsIntrinsic<[],
+def int_invariant_end : DefaultAttrsIntrinsic<[],
[llvm_descriptor_ty, llvm_i64_ty,
llvm_anyptr_ty],
[IntrArgMemOnly, IntrWillReturn,
@@ -1136,26 +1136,26 @@ def int_invariant_end : DefaultAttrsIntrinsic<[],
// it would remove barrier.
// Note that it is still experimental, which means that its semantics
// might change in the future.
-def int_launder_invariant_group : DefaultAttrsIntrinsic<[llvm_anyptr_ty],
+def int_launder_invariant_group : DefaultAttrsIntrinsic<[llvm_anyptr_ty],
[LLVMMatchType<0>],
[IntrInaccessibleMemOnly, IntrSpeculatable, IntrWillReturn]>;
-def int_strip_invariant_group : DefaultAttrsIntrinsic<[llvm_anyptr_ty],
+def int_strip_invariant_group : DefaultAttrsIntrinsic<[llvm_anyptr_ty],
[LLVMMatchType<0>],
[IntrSpeculatable, IntrNoMem, IntrWillReturn]>;
//===------------------------ Stackmap Intrinsics -------------------------===//
//
-def int_experimental_stackmap : DefaultAttrsIntrinsic<[],
+def int_experimental_stackmap : DefaultAttrsIntrinsic<[],
[llvm_i64_ty, llvm_i32_ty, llvm_vararg_ty],
[Throws]>;
-def int_experimental_patchpoint_void : DefaultAttrsIntrinsic<[],
+def int_experimental_patchpoint_void : DefaultAttrsIntrinsic<[],
[llvm_i64_ty, llvm_i32_ty,
llvm_ptr_ty, llvm_i32_ty,
llvm_vararg_ty],
[Throws]>;
-def int_experimental_patchpoint_i64 : DefaultAttrsIntrinsic<[llvm_i64_ty],
+def int_experimental_patchpoint_i64 : DefaultAttrsIntrinsic<[llvm_i64_ty],
[llvm_i64_ty, llvm_i32_ty,
llvm_ptr_ty, llvm_i32_ty,
llvm_vararg_ty],
@@ -1200,23 +1200,23 @@ def int_coro_id_retcon_once : Intrinsic<[llvm_token_ty],
llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty],
[]>;
def int_coro_alloc : Intrinsic<[llvm_i1_ty], [llvm_token_ty], []>;
-def int_coro_id_async : Intrinsic<[llvm_token_ty],
- [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty],
- []>;
-def int_coro_async_context_alloc : Intrinsic<[llvm_ptr_ty],
- [llvm_ptr_ty, llvm_ptr_ty],
- []>;
-def int_coro_async_context_dealloc : Intrinsic<[],
- [llvm_ptr_ty],
- []>;
-def int_coro_async_resume : Intrinsic<[llvm_ptr_ty],
- [],
- []>;
-def int_coro_suspend_async : Intrinsic<[llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty],
- [llvm_ptr_ty, llvm_ptr_ty, llvm_vararg_ty],
- []>;
-def int_coro_prepare_async : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty],
- [IntrNoMem]>;
+def int_coro_id_async : Intrinsic<[llvm_token_ty],
+ [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty],
+ []>;
+def int_coro_async_context_alloc : Intrinsic<[llvm_ptr_ty],
+ [llvm_ptr_ty, llvm_ptr_ty],
+ []>;
+def int_coro_async_context_dealloc : Intrinsic<[],
+ [llvm_ptr_ty],
+ []>;
+def int_coro_async_resume : Intrinsic<[llvm_ptr_ty],
+ [],
+ []>;
+def int_coro_suspend_async : Intrinsic<[llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty],
+ [llvm_ptr_ty, llvm_ptr_ty, llvm_vararg_ty],
+ []>;
+def int_coro_prepare_async : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty],
+ [IntrNoMem]>;
def int_coro_begin : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty],
[WriteOnly<ArgIndex<1>>]>;
@@ -1225,8 +1225,8 @@ def int_coro_free : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty],
ReadOnly<ArgIndex<1>>,
NoCapture<ArgIndex<1>>]>;
def int_coro_end : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_i1_ty], []>;
-def int_coro_end_async
- : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_i1_ty, llvm_vararg_ty], []>;
+def int_coro_end_async
+ : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_i1_ty, llvm_vararg_ty], []>;
def int_coro_frame : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
def int_coro_noop : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
@@ -1270,196 +1270,196 @@ def int_trap : Intrinsic<[], [], [IntrNoReturn, IntrCold]>,
GCCBuiltin<"__builtin_trap">;
def int_debugtrap : Intrinsic<[]>,
GCCBuiltin<"__builtin_debugtrap">;
-def int_ubsantrap : Intrinsic<[], [llvm_i8_ty],
- [IntrNoReturn, IntrCold, ImmArg<ArgIndex<0>>]>;
+def int_ubsantrap : Intrinsic<[], [llvm_i8_ty],
+ [IntrNoReturn, IntrCold, ImmArg<ArgIndex<0>>]>;
// Support for dynamic deoptimization (or de-specialization)
def int_experimental_deoptimize : Intrinsic<[llvm_any_ty], [llvm_vararg_ty],
[Throws]>;
// Support for speculative runtime guards
-def int_experimental_guard : DefaultAttrsIntrinsic<[], [llvm_i1_ty, llvm_vararg_ty],
+def int_experimental_guard : DefaultAttrsIntrinsic<[], [llvm_i1_ty, llvm_vararg_ty],
[Throws]>;
// Supports widenable conditions for guards represented as explicit branches.
-def int_experimental_widenable_condition : DefaultAttrsIntrinsic<[llvm_i1_ty], [],
+def int_experimental_widenable_condition : DefaultAttrsIntrinsic<[llvm_i1_ty], [],
[IntrInaccessibleMemOnly, IntrWillReturn, IntrSpeculatable]>;
// NOP: calls/invokes to this intrinsic are removed by codegen
-def int_donothing : DefaultAttrsIntrinsic<[], [], [IntrNoMem, IntrWillReturn]>;
+def int_donothing : DefaultAttrsIntrinsic<[], [], [IntrNoMem, IntrWillReturn]>;
// This instruction has no actual effect, though it is treated by the optimizer
// has having opaque side effects. This may be inserted into loops to ensure
// that they are not removed even if they turn out to be empty, for languages
// which specify that infinite loops must be preserved.
-def int_sideeffect : DefaultAttrsIntrinsic<[], [], [IntrInaccessibleMemOnly, IntrWillReturn]>;
-
-// The pseudoprobe intrinsic works as a place holder to the block it probes.
-// Like the sideeffect intrinsic defined above, this intrinsic is treated by the
-// optimizer as having opaque side effects so that it won't be get rid of or moved
-// out of the block it probes.
-def int_pseudoprobe : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_i64_ty],
- [IntrInaccessibleMemOnly, IntrWillReturn]>;
-
+def int_sideeffect : DefaultAttrsIntrinsic<[], [], [IntrInaccessibleMemOnly, IntrWillReturn]>;
+
+// The pseudoprobe intrinsic works as a place holder to the block it probes.
+// Like the sideeffect intrinsic defined above, this intrinsic is treated by the
+// optimizer as having opaque side effects so that it won't be get rid of or moved
+// out of the block it probes.
+def int_pseudoprobe : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_i64_ty],
+ [IntrInaccessibleMemOnly, IntrWillReturn]>;
+
// Intrinsics to support half precision floating point format
let IntrProperties = [IntrNoMem, IntrWillReturn] in {
-def int_convert_to_fp16 : DefaultAttrsIntrinsic<[llvm_i16_ty], [llvm_anyfloat_ty]>;
-def int_convert_from_fp16 : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [llvm_i16_ty]>;
+def int_convert_to_fp16 : DefaultAttrsIntrinsic<[llvm_i16_ty], [llvm_anyfloat_ty]>;
+def int_convert_from_fp16 : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [llvm_i16_ty]>;
+}
+
+// Saturating floating point to integer intrinsics
+let IntrProperties = [IntrNoMem, IntrSpeculatable, IntrWillReturn] in {
+def int_fptoui_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>;
+def int_fptosi_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>;
}
-// Saturating floating point to integer intrinsics
-let IntrProperties = [IntrNoMem, IntrSpeculatable, IntrWillReturn] in {
-def int_fptoui_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>;
-def int_fptosi_sat : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>;
-}
-
// Clear cache intrinsic, default to ignore (ie. emit nothing)
// maps to void __clear_cache() on supporting platforms
def int_clear_cache : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty],
[], "llvm.clear_cache">;
// Intrinsic to detect whether its argument is a constant.
-def int_is_constant : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty],
+def int_is_constant : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty],
[IntrNoMem, IntrWillReturn, IntrConvergent],
"llvm.is.constant">;
// Intrinsic to mask out bits of a pointer.
-def int_ptrmask: DefaultAttrsIntrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>, llvm_anyint_ty],
+def int_ptrmask: DefaultAttrsIntrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>, llvm_anyint_ty],
[IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
//===---------------- Vector Predication Intrinsics --------------===//
-// Speculatable Binary operators
-let IntrProperties = [IntrSpeculatable, IntrNoMem, IntrNoSync, IntrWillReturn] in {
- def int_vp_add : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
+// Speculatable Binary operators
+let IntrProperties = [IntrSpeculatable, IntrNoMem, IntrNoSync, IntrWillReturn] in {
+ def int_vp_add : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_i32_ty]>;
- def int_vp_sub : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
+ def int_vp_sub : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_i32_ty]>;
- def int_vp_mul : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
+ def int_vp_mul : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_i32_ty]>;
- def int_vp_ashr : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
+ def int_vp_ashr : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_i32_ty]>;
- def int_vp_lshr : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
+ def int_vp_lshr : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_i32_ty]>;
- def int_vp_shl : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
+ def int_vp_shl : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_i32_ty]>;
- def int_vp_or : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
+ def int_vp_or : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_i32_ty]>;
- def int_vp_and : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
+ def int_vp_and : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_i32_ty]>;
- def int_vp_xor : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
+ def int_vp_xor : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
[ LLVMMatchType<0>,
LLVMMatchType<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_i32_ty]>;
-}
-
-// Non-speculatable binary operators.
-let IntrProperties = [IntrNoMem, IntrNoSync, IntrWillReturn] in {
- def int_vp_sdiv : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
- [ LLVMMatchType<0>,
- LLVMMatchType<0>,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- llvm_i32_ty]>;
- def int_vp_udiv : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
- [ LLVMMatchType<0>,
- LLVMMatchType<0>,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- llvm_i32_ty]>;
- def int_vp_srem : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
- [ LLVMMatchType<0>,
- LLVMMatchType<0>,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- llvm_i32_ty]>;
- def int_vp_urem : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
- [ LLVMMatchType<0>,
- LLVMMatchType<0>,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- llvm_i32_ty]>;
+}
+
+// Non-speculatable binary operators.
+let IntrProperties = [IntrNoMem, IntrNoSync, IntrWillReturn] in {
+ def int_vp_sdiv : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_i32_ty]>;
+ def int_vp_udiv : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_i32_ty]>;
+ def int_vp_srem : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_i32_ty]>;
+ def int_vp_urem : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_i32_ty]>;
}
def int_get_active_lane_mask:
- DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[llvm_anyint_ty, LLVMMatchType<1>],
[IntrNoMem, IntrNoSync, IntrWillReturn]>;
//===-------------------------- Masked Intrinsics -------------------------===//
//
-def int_masked_load:
- DefaultAttrsIntrinsic<[llvm_anyvector_ty],
- [LLVMAnyPointerType<LLVMMatchType<0>>, llvm_i32_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<0>],
- [IntrReadMem, IntrArgMemOnly, IntrWillReturn, ImmArg<ArgIndex<1>>]>;
-
-def int_masked_store:
- DefaultAttrsIntrinsic<[],
- [llvm_anyvector_ty, LLVMAnyPointerType<LLVMMatchType<0>>,
- llvm_i32_ty, LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
- [IntrWriteMem, IntrArgMemOnly, IntrWillReturn,
- ImmArg<ArgIndex<2>>]>;
-
-def int_masked_gather:
- DefaultAttrsIntrinsic<[llvm_anyvector_ty],
- [LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<0>],
- [IntrReadMem, IntrWillReturn, ImmArg<ArgIndex<1>>]>;
-
-def int_masked_scatter:
- DefaultAttrsIntrinsic<[],
- [llvm_anyvector_ty, LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
- [IntrWriteMem, IntrWillReturn, ImmArg<ArgIndex<2>>]>;
-
-def int_masked_expandload:
- DefaultAttrsIntrinsic<[llvm_anyvector_ty],
- [LLVMPointerToElt<0>, LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- LLVMMatchType<0>],
- [IntrReadMem, IntrWillReturn]>;
-
-def int_masked_compressstore:
- DefaultAttrsIntrinsic<[],
- [llvm_anyvector_ty, LLVMPointerToElt<0>,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
- [IntrWriteMem, IntrArgMemOnly, IntrWillReturn]>;
+def int_masked_load:
+ DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ [LLVMAnyPointerType<LLVMMatchType<0>>, llvm_i32_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<0>],
+ [IntrReadMem, IntrArgMemOnly, IntrWillReturn, ImmArg<ArgIndex<1>>]>;
+
+def int_masked_store:
+ DefaultAttrsIntrinsic<[],
+ [llvm_anyvector_ty, LLVMAnyPointerType<LLVMMatchType<0>>,
+ llvm_i32_ty, LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
+ [IntrWriteMem, IntrArgMemOnly, IntrWillReturn,
+ ImmArg<ArgIndex<2>>]>;
+
+def int_masked_gather:
+ DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ [LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<0>],
+ [IntrReadMem, IntrWillReturn, ImmArg<ArgIndex<1>>]>;
+
+def int_masked_scatter:
+ DefaultAttrsIntrinsic<[],
+ [llvm_anyvector_ty, LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
+ [IntrWriteMem, IntrWillReturn, ImmArg<ArgIndex<2>>]>;
+
+def int_masked_expandload:
+ DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ [LLVMPointerToElt<0>, LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ LLVMMatchType<0>],
+ [IntrReadMem, IntrWillReturn]>;
+
+def int_masked_compressstore:
+ DefaultAttrsIntrinsic<[],
+ [llvm_anyvector_ty, LLVMPointerToElt<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
+ [IntrWriteMem, IntrArgMemOnly, IntrWillReturn]>;
// Test whether a pointer is associated with a type metadata identifier.
-def int_type_test : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_metadata_ty],
+def int_type_test : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_metadata_ty],
[IntrNoMem, IntrWillReturn]>;
// Safely loads a function pointer from a virtual table pointer using type metadata.
-def int_type_checked_load : DefaultAttrsIntrinsic<[llvm_ptr_ty, llvm_i1_ty],
+def int_type_checked_load : DefaultAttrsIntrinsic<[llvm_ptr_ty, llvm_i1_ty],
[llvm_ptr_ty, llvm_i32_ty, llvm_metadata_ty],
[IntrNoMem, IntrWillReturn]>;
// Create a branch funnel that implements an indirect call to a limited set of
// callees. This needs to be a musttail call.
-def int_icall_branch_funnel : DefaultAttrsIntrinsic<[], [llvm_vararg_ty], []>;
+def int_icall_branch_funnel : DefaultAttrsIntrinsic<[], [llvm_vararg_ty], []>;
-def int_load_relative: DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_anyint_ty],
+def int_load_relative: DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_anyint_ty],
[IntrReadMem, IntrArgMemOnly]>;
def int_hwasan_check_memaccess :
@@ -1511,55 +1511,55 @@ def int_memset_element_unordered_atomic
//===------------------------ Reduction Intrinsics ------------------------===//
//
-let IntrProperties = [IntrNoMem] in {
-
- def int_vector_reduce_fadd : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
- [LLVMVectorElementType<0>,
- llvm_anyvector_ty]>;
- def int_vector_reduce_fmul : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
- [LLVMVectorElementType<0>,
- llvm_anyvector_ty]>;
- def int_vector_reduce_add : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
- [llvm_anyvector_ty]>;
- def int_vector_reduce_mul : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
- [llvm_anyvector_ty]>;
- def int_vector_reduce_and : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
- [llvm_anyvector_ty]>;
- def int_vector_reduce_or : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
- [llvm_anyvector_ty]>;
- def int_vector_reduce_xor : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
- [llvm_anyvector_ty]>;
- def int_vector_reduce_smax : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
- [llvm_anyvector_ty]>;
- def int_vector_reduce_smin : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
- [llvm_anyvector_ty]>;
- def int_vector_reduce_umax : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
- [llvm_anyvector_ty]>;
- def int_vector_reduce_umin : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
- [llvm_anyvector_ty]>;
- def int_vector_reduce_fmax : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
- [llvm_anyvector_ty]>;
- def int_vector_reduce_fmin : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
- [llvm_anyvector_ty]>;
+let IntrProperties = [IntrNoMem] in {
+
+ def int_vector_reduce_fadd : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
+ [LLVMVectorElementType<0>,
+ llvm_anyvector_ty]>;
+ def int_vector_reduce_fmul : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
+ [LLVMVectorElementType<0>,
+ llvm_anyvector_ty]>;
+ def int_vector_reduce_add : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
+ [llvm_anyvector_ty]>;
+ def int_vector_reduce_mul : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
+ [llvm_anyvector_ty]>;
+ def int_vector_reduce_and : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
+ [llvm_anyvector_ty]>;
+ def int_vector_reduce_or : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
+ [llvm_anyvector_ty]>;
+ def int_vector_reduce_xor : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
+ [llvm_anyvector_ty]>;
+ def int_vector_reduce_smax : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
+ [llvm_anyvector_ty]>;
+ def int_vector_reduce_smin : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
+ [llvm_anyvector_ty]>;
+ def int_vector_reduce_umax : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
+ [llvm_anyvector_ty]>;
+ def int_vector_reduce_umin : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
+ [llvm_anyvector_ty]>;
+ def int_vector_reduce_fmax : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
+ [llvm_anyvector_ty]>;
+ def int_vector_reduce_fmin : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
+ [llvm_anyvector_ty]>;
}
//===----- Matrix intrinsics ---------------------------------------------===//
def int_matrix_transpose
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty],
[ IntrNoSync, IntrWillReturn, IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<1>>,
ImmArg<ArgIndex<2>>]>;
def int_matrix_multiply
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[llvm_anyvector_ty, llvm_anyvector_ty, llvm_i32_ty, llvm_i32_ty,
llvm_i32_ty],
[IntrNoSync, IntrWillReturn, IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<2>>,
ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
def int_matrix_column_major_load
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMPointerToElt<0>, llvm_i64_ty, llvm_i1_ty,
llvm_i32_ty, llvm_i32_ty],
[IntrNoSync, IntrWillReturn, IntrArgMemOnly, IntrReadMem,
@@ -1567,7 +1567,7 @@ def int_matrix_column_major_load
ImmArg<ArgIndex<4>>]>;
def int_matrix_column_major_store
- : DefaultAttrsIntrinsic<[],
+ : DefaultAttrsIntrinsic<[],
[llvm_anyvector_ty, LLVMPointerToElt<0>,
llvm_i64_ty, llvm_i1_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoSync, IntrWillReturn, IntrArgMemOnly, IntrWriteMem,
@@ -1579,23 +1579,23 @@ def int_matrix_column_major_store
// Specify that the value given is the number of iterations that the next loop
// will execute.
def int_set_loop_iterations :
- DefaultAttrsIntrinsic<[], [llvm_anyint_ty], [IntrNoDuplicate]>;
+ DefaultAttrsIntrinsic<[], [llvm_anyint_ty], [IntrNoDuplicate]>;
+
+// Same as the above, but produces a value (the same as the input operand) to
+// be fed into the loop.
+def int_start_loop_iterations :
+ DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrNoDuplicate]>;
-// Same as the above, but produces a value (the same as the input operand) to
-// be fed into the loop.
-def int_start_loop_iterations :
- DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrNoDuplicate]>;
-
// Specify that the value given is the number of iterations that the next loop
// will execute. Also test that the given count is not zero, allowing it to
// control entry to a 'while' loop.
def int_test_set_loop_iterations :
- DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_anyint_ty], [IntrNoDuplicate]>;
+ DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_anyint_ty], [IntrNoDuplicate]>;
// Decrement loop counter by the given argument. Return false if the loop
// should exit.
def int_loop_decrement :
- DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_anyint_ty], [IntrNoDuplicate]>;
+ DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_anyint_ty], [IntrNoDuplicate]>;
// Decrement the first operand (the loop counter) by the second operand (the
// maximum number of elements processed in an iteration). Return the remaining
@@ -1605,27 +1605,27 @@ def int_loop_decrement :
// it's scevable, so it's the backends responsibility to handle cases where it
// may be optimised.
def int_loop_decrement_reg :
- DefaultAttrsIntrinsic<[llvm_anyint_ty],
+ DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoDuplicate]>;
//===----- Intrinsics that are used to provide predicate information -----===//
-def int_ssa_copy : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>],
+def int_ssa_copy : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>],
[IntrNoMem, Returned<ArgIndex<0>>]>;
//===------- Intrinsics that are used to preserve debug information -------===//
-def int_preserve_array_access_index : DefaultAttrsIntrinsic<[llvm_anyptr_ty],
+def int_preserve_array_access_index : DefaultAttrsIntrinsic<[llvm_anyptr_ty],
[llvm_anyptr_ty, llvm_i32_ty,
llvm_i32_ty],
[IntrNoMem,
ImmArg<ArgIndex<1>>,
ImmArg<ArgIndex<2>>]>;
-def int_preserve_union_access_index : DefaultAttrsIntrinsic<[llvm_anyptr_ty],
+def int_preserve_union_access_index : DefaultAttrsIntrinsic<[llvm_anyptr_ty],
[llvm_anyptr_ty, llvm_i32_ty],
[IntrNoMem,
ImmArg<ArgIndex<1>>]>;
-def int_preserve_struct_access_index : DefaultAttrsIntrinsic<[llvm_anyptr_ty],
+def int_preserve_struct_access_index : DefaultAttrsIntrinsic<[llvm_anyptr_ty],
[llvm_anyptr_ty, llvm_i32_ty,
llvm_i32_ty],
[IntrNoMem,
@@ -1633,17 +1633,17 @@ def int_preserve_struct_access_index : DefaultAttrsIntrinsic<[llvm_anyptr_ty],
ImmArg<ArgIndex<2>>]>;
//===---------- Intrinsics to query properties of scalable vectors --------===//
-def int_vscale : DefaultAttrsIntrinsic<[llvm_anyint_ty], [], [IntrNoMem]>;
-
-//===---------- Intrinsics to perform subvector insertion/extraction ------===//
-def int_experimental_vector_insert : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_anyvector_ty, llvm_i64_ty],
- [IntrNoMem, ImmArg<ArgIndex<2>>]>;
-
-def int_experimental_vector_extract : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
- [llvm_anyvector_ty, llvm_i64_ty],
- [IntrNoMem, ImmArg<ArgIndex<1>>]>;
-
+def int_vscale : DefaultAttrsIntrinsic<[llvm_anyint_ty], [], [IntrNoMem]>;
+
+//===---------- Intrinsics to perform subvector insertion/extraction ------===//
+def int_experimental_vector_insert : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty, llvm_i64_ty],
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_experimental_vector_extract : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ [llvm_anyvector_ty, llvm_i64_ty],
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
@@ -1663,4 +1663,4 @@ include "llvm/IR/IntrinsicsBPF.td"
include "llvm/IR/IntrinsicsSystemZ.td"
include "llvm/IR/IntrinsicsWebAssembly.td"
include "llvm/IR/IntrinsicsRISCV.td"
-include "llvm/IR/IntrinsicsVE.td"
+include "llvm/IR/IntrinsicsVE.td"
diff --git a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsAArch64.td b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsAArch64.td
index 2ffb4acb3f..da3085171b 100644
--- a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsAArch64.td
+++ b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsAArch64.td
@@ -12,58 +12,58 @@
let TargetPrefix = "aarch64" in {
-def int_aarch64_ldxr : Intrinsic<[llvm_i64_ty], [llvm_anyptr_ty],
- [IntrNoFree, IntrWillReturn]>;
-def int_aarch64_ldaxr : Intrinsic<[llvm_i64_ty], [llvm_anyptr_ty],
- [IntrNoFree, IntrWillReturn]>;
-def int_aarch64_stxr : Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_anyptr_ty],
- [IntrNoFree, IntrWillReturn]>;
-def int_aarch64_stlxr : Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_anyptr_ty],
- [IntrNoFree, IntrWillReturn]>;
-
-def int_aarch64_ldxp : Intrinsic<[llvm_i64_ty, llvm_i64_ty], [llvm_ptr_ty],
- [IntrNoFree, IntrWillReturn]>;
-def int_aarch64_ldaxp : Intrinsic<[llvm_i64_ty, llvm_i64_ty], [llvm_ptr_ty],
- [IntrNoFree, IntrWillReturn]>;
+def int_aarch64_ldxr : Intrinsic<[llvm_i64_ty], [llvm_anyptr_ty],
+ [IntrNoFree, IntrWillReturn]>;
+def int_aarch64_ldaxr : Intrinsic<[llvm_i64_ty], [llvm_anyptr_ty],
+ [IntrNoFree, IntrWillReturn]>;
+def int_aarch64_stxr : Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_anyptr_ty],
+ [IntrNoFree, IntrWillReturn]>;
+def int_aarch64_stlxr : Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_anyptr_ty],
+ [IntrNoFree, IntrWillReturn]>;
+
+def int_aarch64_ldxp : Intrinsic<[llvm_i64_ty, llvm_i64_ty], [llvm_ptr_ty],
+ [IntrNoFree, IntrWillReturn]>;
+def int_aarch64_ldaxp : Intrinsic<[llvm_i64_ty, llvm_i64_ty], [llvm_ptr_ty],
+ [IntrNoFree, IntrWillReturn]>;
def int_aarch64_stxp : Intrinsic<[llvm_i32_ty],
- [llvm_i64_ty, llvm_i64_ty, llvm_ptr_ty],
- [IntrNoFree, IntrWillReturn]>;
+ [llvm_i64_ty, llvm_i64_ty, llvm_ptr_ty],
+ [IntrNoFree, IntrWillReturn]>;
def int_aarch64_stlxp : Intrinsic<[llvm_i32_ty],
- [llvm_i64_ty, llvm_i64_ty, llvm_ptr_ty],
- [IntrNoFree, IntrWillReturn]>;
+ [llvm_i64_ty, llvm_i64_ty, llvm_ptr_ty],
+ [IntrNoFree, IntrWillReturn]>;
def int_aarch64_clrex : Intrinsic<[]>;
-def int_aarch64_sdiv : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
+def int_aarch64_sdiv : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
LLVMMatchType<0>], [IntrNoMem]>;
-def int_aarch64_udiv : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
+def int_aarch64_udiv : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
LLVMMatchType<0>], [IntrNoMem]>;
-def int_aarch64_fjcvtzs : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+def int_aarch64_fjcvtzs : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
-def int_aarch64_cls: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
-def int_aarch64_cls64: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem]>;
+def int_aarch64_cls: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+def int_aarch64_cls64: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem]>;
//===----------------------------------------------------------------------===//
// HINT
-def int_aarch64_hint : DefaultAttrsIntrinsic<[], [llvm_i32_ty]>;
+def int_aarch64_hint : DefaultAttrsIntrinsic<[], [llvm_i32_ty]>;
//===----------------------------------------------------------------------===//
// Data Barrier Instructions
-def int_aarch64_dmb : GCCBuiltin<"__builtin_arm_dmb">, MSBuiltin<"__dmb">,
- Intrinsic<[], [llvm_i32_ty], [IntrNoFree, IntrWillReturn]>;
-def int_aarch64_dsb : GCCBuiltin<"__builtin_arm_dsb">, MSBuiltin<"__dsb">,
- Intrinsic<[], [llvm_i32_ty], [IntrNoFree, IntrWillReturn]>;
-def int_aarch64_isb : GCCBuiltin<"__builtin_arm_isb">, MSBuiltin<"__isb">,
- Intrinsic<[], [llvm_i32_ty], [IntrNoFree, IntrWillReturn]>;
+def int_aarch64_dmb : GCCBuiltin<"__builtin_arm_dmb">, MSBuiltin<"__dmb">,
+ Intrinsic<[], [llvm_i32_ty], [IntrNoFree, IntrWillReturn]>;
+def int_aarch64_dsb : GCCBuiltin<"__builtin_arm_dsb">, MSBuiltin<"__dsb">,
+ Intrinsic<[], [llvm_i32_ty], [IntrNoFree, IntrWillReturn]>;
+def int_aarch64_isb : GCCBuiltin<"__builtin_arm_isb">, MSBuiltin<"__isb">,
+ Intrinsic<[], [llvm_i32_ty], [IntrNoFree, IntrWillReturn]>;
// A space-consuming intrinsic primarily for testing block and jump table
// placements. The first argument is the number of bytes this "instruction"
// takes up, the second and return value are essentially chains, used to force
// ordering during ISel.
-def int_aarch64_space : DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i64_ty], []>;
+def int_aarch64_space : DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i64_ty], []>;
}
@@ -72,133 +72,133 @@ def int_aarch64_space : DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_
let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
class AdvSIMD_2Scalar_Float_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+ : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem]>;
class AdvSIMD_FPToIntRounding_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
class AdvSIMD_1IntArg_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrNoMem]>;
class AdvSIMD_1FloatArg_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
class AdvSIMD_1VectorArg_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>], [IntrNoMem]>;
class AdvSIMD_1VectorArg_Expand_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
class AdvSIMD_1VectorArg_Long_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMTruncatedType<0>], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMTruncatedType<0>], [IntrNoMem]>;
class AdvSIMD_1IntArg_Narrow_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyint_ty], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyint_ty], [IntrNoMem]>;
class AdvSIMD_1VectorArg_Narrow_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMExtendedType<0>], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMExtendedType<0>], [IntrNoMem]>;
class AdvSIMD_1VectorArg_Int_Across_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyvector_ty], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyvector_ty], [IntrNoMem]>;
class AdvSIMD_1VectorArg_Float_Across_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty], [IntrNoMem]>;
class AdvSIMD_2IntArg_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+ : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem]>;
class AdvSIMD_2FloatArg_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+ : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem]>;
class AdvSIMD_2VectorArg_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem]>;
class AdvSIMD_2VectorArg_Compare_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty, LLVMMatchType<1>],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty, LLVMMatchType<1>],
[IntrNoMem]>;
class AdvSIMD_2Arg_FloatCompare_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, LLVMMatchType<1>],
+ : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, LLVMMatchType<1>],
[IntrNoMem]>;
class AdvSIMD_2VectorArg_Long_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMTruncatedType<0>, LLVMTruncatedType<0>],
[IntrNoMem]>;
class AdvSIMD_2VectorArg_Wide_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, LLVMTruncatedType<0>],
[IntrNoMem]>;
class AdvSIMD_2VectorArg_Narrow_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMExtendedType<0>, LLVMExtendedType<0>],
[IntrNoMem]>;
class AdvSIMD_2Arg_Scalar_Narrow_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMExtendedType<0>, llvm_i32_ty],
[IntrNoMem]>;
class AdvSIMD_2VectorArg_Scalar_Expand_BySize_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[llvm_anyvector_ty],
[IntrNoMem]>;
class AdvSIMD_2VectorArg_Scalar_Wide_BySize_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMTruncatedType<0>],
[IntrNoMem]>;
class AdvSIMD_2VectorArg_Scalar_Wide_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMTruncatedType<0>, llvm_i32_ty],
[IntrNoMem]>;
class AdvSIMD_2VectorArg_Tied_Narrow_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMHalfElementsVectorType<0>, llvm_anyvector_ty],
[IntrNoMem]>;
class AdvSIMD_2VectorArg_Lane_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyint_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, llvm_anyint_ty, llvm_i32_ty],
[IntrNoMem]>;
class AdvSIMD_3VectorArg_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem]>;
class AdvSIMD_3VectorArg_Scalar_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
[IntrNoMem]>;
class AdvSIMD_3VectorArg_Tied_Narrow_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMHalfElementsVectorType<0>, llvm_anyvector_ty,
LLVMMatchType<1>], [IntrNoMem]>;
class AdvSIMD_3VectorArg_Scalar_Tied_Narrow_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMHalfElementsVectorType<0>, llvm_anyvector_ty, llvm_i32_ty],
[IntrNoMem]>;
class AdvSIMD_CvtFxToFP_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty, llvm_i32_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty, llvm_i32_ty],
[IntrNoMem]>;
class AdvSIMD_CvtFPToFx_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, llvm_i32_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, llvm_i32_ty],
[IntrNoMem]>;
class AdvSIMD_1Arg_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrNoMem]>;
class AdvSIMD_Dot_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<1>],
[IntrNoMem]>;
class AdvSIMD_FP16FML_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<1>],
[IntrNoMem]>;
class AdvSIMD_MatMul_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<1>],
[IntrNoMem]>;
class AdvSIMD_FML_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<1>],
[IntrNoMem]>;
- class AdvSIMD_BF16FML_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_v4f32_ty],
- [llvm_v4f32_ty, llvm_v8bf16_ty, llvm_v8bf16_ty],
- [IntrNoMem]>;
+ class AdvSIMD_BF16FML_Intrinsic
+ : DefaultAttrsIntrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_v8bf16_ty, llvm_v8bf16_ty],
+ [IntrNoMem]>;
}
// Arithmetic ops
@@ -256,7 +256,7 @@ let TargetPrefix = "aarch64", IntrProperties = [IntrNoMem] in {
// 64-bit polynomial multiply really returns an i128, which is not legal. Fake
// it with a v16i8.
def int_aarch64_neon_pmull64 :
- DefaultAttrsIntrinsic<[llvm_v16i8_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+ DefaultAttrsIntrinsic<[llvm_v16i8_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
// Vector Extending Multiply
def int_aarch64_neon_fmulx : AdvSIMD_2FloatArg_Intrinsic {
@@ -266,7 +266,7 @@ let TargetPrefix = "aarch64", IntrProperties = [IntrNoMem] in {
// Vector Saturating Doubling Long Multiply
def int_aarch64_neon_sqdmull : AdvSIMD_2VectorArg_Long_Intrinsic;
def int_aarch64_neon_sqdmulls_scalar
- : DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
// Vector Halving Subtract
def int_aarch64_neon_shsub : AdvSIMD_2VectorArg_Intrinsic;
@@ -436,9 +436,9 @@ let TargetPrefix = "aarch64", IntrProperties = [IntrNoMem] in {
// Vector Conversions Between Half-Precision and Single-Precision.
def int_aarch64_neon_vcvtfp2hf
- : DefaultAttrsIntrinsic<[llvm_v4i16_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_v4i16_ty], [llvm_v4f32_ty], [IntrNoMem]>;
def int_aarch64_neon_vcvthf2fp
- : DefaultAttrsIntrinsic<[llvm_v4f32_ty], [llvm_v4i16_ty], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_v4f32_ty], [llvm_v4i16_ty], [IntrNoMem]>;
// Vector Conversions Between Floating-point and Fixed-point.
def int_aarch64_neon_vcvtfp2fxs : AdvSIMD_CvtFPToFx_Intrinsic;
@@ -468,7 +468,7 @@ let TargetPrefix = "aarch64", IntrProperties = [IntrNoMem] in {
def int_aarch64_neon_fcvtxn : AdvSIMD_1VectorArg_Expand_Intrinsic;
// Scalar FP Inexact Narrowing
- def int_aarch64_sisd_fcvtxn : DefaultAttrsIntrinsic<[llvm_float_ty], [llvm_double_ty],
+ def int_aarch64_sisd_fcvtxn : DefaultAttrsIntrinsic<[llvm_float_ty], [llvm_double_ty],
[IntrNoMem]>;
// v8.2-A Dot Product
@@ -481,21 +481,21 @@ let TargetPrefix = "aarch64", IntrProperties = [IntrNoMem] in {
def int_aarch64_neon_usmmla : AdvSIMD_MatMul_Intrinsic;
def int_aarch64_neon_usdot : AdvSIMD_Dot_Intrinsic;
def int_aarch64_neon_bfdot : AdvSIMD_Dot_Intrinsic;
- def int_aarch64_neon_bfmmla
- : DefaultAttrsIntrinsic<[llvm_v4f32_ty],
- [llvm_v4f32_ty, llvm_v8bf16_ty, llvm_v8bf16_ty],
- [IntrNoMem]>;
- def int_aarch64_neon_bfmlalb : AdvSIMD_BF16FML_Intrinsic;
- def int_aarch64_neon_bfmlalt : AdvSIMD_BF16FML_Intrinsic;
+ def int_aarch64_neon_bfmmla
+ : DefaultAttrsIntrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_v8bf16_ty, llvm_v8bf16_ty],
+ [IntrNoMem]>;
+ def int_aarch64_neon_bfmlalb : AdvSIMD_BF16FML_Intrinsic;
+ def int_aarch64_neon_bfmlalt : AdvSIMD_BF16FML_Intrinsic;
// v8.6-A Bfloat Intrinsics
def int_aarch64_neon_bfcvt
- : DefaultAttrsIntrinsic<[llvm_bfloat_ty], [llvm_float_ty], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_bfloat_ty], [llvm_float_ty], [IntrNoMem]>;
def int_aarch64_neon_bfcvtn
- : DefaultAttrsIntrinsic<[llvm_v8bf16_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_v8bf16_ty], [llvm_v4f32_ty], [IntrNoMem]>;
def int_aarch64_neon_bfcvtn2
- : DefaultAttrsIntrinsic<[llvm_v8bf16_ty],
+ : DefaultAttrsIntrinsic<[llvm_v8bf16_ty],
[llvm_v8bf16_ty, llvm_v4f32_ty],
[IntrNoMem]>;
@@ -508,16 +508,16 @@ let TargetPrefix = "aarch64", IntrProperties = [IntrNoMem] in {
// v8.3-A Floating-point complex add
def int_aarch64_neon_vcadd_rot90 : AdvSIMD_2VectorArg_Intrinsic;
def int_aarch64_neon_vcadd_rot270 : AdvSIMD_2VectorArg_Intrinsic;
-
- def int_aarch64_neon_vcmla_rot0 : AdvSIMD_3VectorArg_Intrinsic;
- def int_aarch64_neon_vcmla_rot90 : AdvSIMD_3VectorArg_Intrinsic;
- def int_aarch64_neon_vcmla_rot180 : AdvSIMD_3VectorArg_Intrinsic;
- def int_aarch64_neon_vcmla_rot270 : AdvSIMD_3VectorArg_Intrinsic;
+
+ def int_aarch64_neon_vcmla_rot0 : AdvSIMD_3VectorArg_Intrinsic;
+ def int_aarch64_neon_vcmla_rot90 : AdvSIMD_3VectorArg_Intrinsic;
+ def int_aarch64_neon_vcmla_rot180 : AdvSIMD_3VectorArg_Intrinsic;
+ def int_aarch64_neon_vcmla_rot270 : AdvSIMD_3VectorArg_Intrinsic;
}
let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
class AdvSIMD_2Vector2Index_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[llvm_anyvector_ty, llvm_i64_ty, LLVMMatchType<0>, llvm_i64_ty],
[IntrNoMem]>;
}
@@ -527,68 +527,68 @@ def int_aarch64_neon_vcopy_lane: AdvSIMD_2Vector2Index_Intrinsic;
let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
class AdvSIMD_1Vec_Load_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMAnyPointerType<LLVMMatchType<0>>],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMAnyPointerType<LLVMMatchType<0>>],
[IntrReadMem, IntrArgMemOnly]>;
class AdvSIMD_1Vec_Store_Lane_Intrinsic
- : DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, llvm_i64_ty, llvm_anyptr_ty],
+ : DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, llvm_i64_ty, llvm_anyptr_ty],
[IntrArgMemOnly, NoCapture<ArgIndex<2>>]>;
class AdvSIMD_2Vec_Load_Intrinsic
- : DefaultAttrsIntrinsic<[LLVMMatchType<0>, llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[LLVMMatchType<0>, llvm_anyvector_ty],
[LLVMAnyPointerType<LLVMMatchType<0>>],
[IntrReadMem, IntrArgMemOnly]>;
class AdvSIMD_2Vec_Load_Lane_Intrinsic
- : DefaultAttrsIntrinsic<[LLVMMatchType<0>, LLVMMatchType<0>],
+ : DefaultAttrsIntrinsic<[LLVMMatchType<0>, LLVMMatchType<0>],
[LLVMMatchType<0>, llvm_anyvector_ty,
llvm_i64_ty, llvm_anyptr_ty],
[IntrReadMem, IntrArgMemOnly]>;
class AdvSIMD_2Vec_Store_Intrinsic
- : DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
+ : DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
LLVMAnyPointerType<LLVMMatchType<0>>],
[IntrArgMemOnly, NoCapture<ArgIndex<2>>]>;
class AdvSIMD_2Vec_Store_Lane_Intrinsic
- : DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
+ : DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
llvm_i64_ty, llvm_anyptr_ty],
[IntrArgMemOnly, NoCapture<ArgIndex<3>>]>;
class AdvSIMD_3Vec_Load_Intrinsic
- : DefaultAttrsIntrinsic<[LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyvector_ty],
[LLVMAnyPointerType<LLVMMatchType<0>>],
[IntrReadMem, IntrArgMemOnly]>;
class AdvSIMD_3Vec_Load_Lane_Intrinsic
- : DefaultAttrsIntrinsic<[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
+ : DefaultAttrsIntrinsic<[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyvector_ty,
llvm_i64_ty, llvm_anyptr_ty],
[IntrReadMem, IntrArgMemOnly]>;
class AdvSIMD_3Vec_Store_Intrinsic
- : DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
+ : DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
LLVMMatchType<0>, LLVMAnyPointerType<LLVMMatchType<0>>],
[IntrArgMemOnly, NoCapture<ArgIndex<3>>]>;
class AdvSIMD_3Vec_Store_Lane_Intrinsic
- : DefaultAttrsIntrinsic<[], [llvm_anyvector_ty,
+ : DefaultAttrsIntrinsic<[], [llvm_anyvector_ty,
LLVMMatchType<0>, LLVMMatchType<0>,
llvm_i64_ty, llvm_anyptr_ty],
[IntrArgMemOnly, NoCapture<ArgIndex<4>>]>;
class AdvSIMD_4Vec_Load_Intrinsic
- : DefaultAttrsIntrinsic<[LLVMMatchType<0>, LLVMMatchType<0>,
+ : DefaultAttrsIntrinsic<[LLVMMatchType<0>, LLVMMatchType<0>,
LLVMMatchType<0>, llvm_anyvector_ty],
[LLVMAnyPointerType<LLVMMatchType<0>>],
[IntrReadMem, IntrArgMemOnly]>;
class AdvSIMD_4Vec_Load_Lane_Intrinsic
- : DefaultAttrsIntrinsic<[LLVMMatchType<0>, LLVMMatchType<0>,
+ : DefaultAttrsIntrinsic<[LLVMMatchType<0>, LLVMMatchType<0>,
LLVMMatchType<0>, LLVMMatchType<0>],
[LLVMMatchType<0>, LLVMMatchType<0>,
LLVMMatchType<0>, llvm_anyvector_ty,
llvm_i64_ty, llvm_anyptr_ty],
[IntrReadMem, IntrArgMemOnly]>;
class AdvSIMD_4Vec_Store_Intrinsic
- : DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
+ : DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
LLVMMatchType<0>, LLVMMatchType<0>,
LLVMAnyPointerType<LLVMMatchType<0>>],
[IntrArgMemOnly, NoCapture<ArgIndex<4>>]>;
class AdvSIMD_4Vec_Store_Lane_Intrinsic
- : DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
+ : DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
LLVMMatchType<0>, LLVMMatchType<0>,
llvm_i64_ty, llvm_anyptr_ty],
[IntrArgMemOnly, NoCapture<ArgIndex<5>>]>;
@@ -626,38 +626,38 @@ def int_aarch64_neon_st4lane : AdvSIMD_4Vec_Store_Lane_Intrinsic;
let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
class AdvSIMD_Tbl1_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [llvm_v16i8_ty, LLVMMatchType<0>],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [llvm_v16i8_ty, LLVMMatchType<0>],
[IntrNoMem]>;
class AdvSIMD_Tbl2_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, LLVMMatchType<0>], [IntrNoMem]>;
class AdvSIMD_Tbl3_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty,
LLVMMatchType<0>],
[IntrNoMem]>;
class AdvSIMD_Tbl4_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty,
LLVMMatchType<0>],
[IntrNoMem]>;
class AdvSIMD_Tbx1_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, llvm_v16i8_ty, LLVMMatchType<0>],
[IntrNoMem]>;
class AdvSIMD_Tbx2_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, llvm_v16i8_ty, llvm_v16i8_ty,
LLVMMatchType<0>],
[IntrNoMem]>;
class AdvSIMD_Tbx3_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, llvm_v16i8_ty, llvm_v16i8_ty,
llvm_v16i8_ty, LLVMMatchType<0>],
[IntrNoMem]>;
class AdvSIMD_Tbx4_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, llvm_v16i8_ty, llvm_v16i8_ty,
llvm_v16i8_ty, llvm_v16i8_ty, LLVMMatchType<0>],
[IntrNoMem]>;
@@ -674,7 +674,7 @@ def int_aarch64_neon_tbx4 : AdvSIMD_Tbx4_Intrinsic;
let TargetPrefix = "aarch64" in {
class FPCR_Get_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_i64_ty], [], [IntrNoMem, IntrHasSideEffects]>;
+ : DefaultAttrsIntrinsic<[llvm_i64_ty], [], [IntrNoMem, IntrHasSideEffects]>;
}
// FPCR
@@ -682,34 +682,34 @@ def int_aarch64_get_fpcr : FPCR_Get_Intrinsic;
let TargetPrefix = "aarch64" in {
class Crypto_AES_DataKey_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
class Crypto_AES_Data_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
// SHA intrinsic taking 5 words of the hash (v4i32, i32) and 4 of the schedule
// (v4i32).
class Crypto_SHA_5Hash4Schedule_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty, llvm_v4i32_ty],
+ : DefaultAttrsIntrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
// SHA intrinsic taking 5 words of the hash (v4i32, i32) and 4 of the schedule
// (v4i32).
class Crypto_SHA_1Hash_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
// SHA intrinsic taking 8 words of the schedule
class Crypto_SHA_8Schedule_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
// SHA intrinsic taking 12 words of the schedule
class Crypto_SHA_12Schedule_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+ : DefaultAttrsIntrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
// SHA intrinsic taking 8 words of the hash and 4 of the schedule.
class Crypto_SHA_8Hash4Schedule_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+ : DefaultAttrsIntrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
}
@@ -739,96 +739,96 @@ def int_aarch64_crypto_sha256su1 : Crypto_SHA_12Schedule_Intrinsic;
let TargetPrefix = "aarch64" in {
-def int_aarch64_crc32b : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+def int_aarch64_crc32b : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
-def int_aarch64_crc32cb : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+def int_aarch64_crc32cb : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
-def int_aarch64_crc32h : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+def int_aarch64_crc32h : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
-def int_aarch64_crc32ch : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+def int_aarch64_crc32ch : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
-def int_aarch64_crc32w : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+def int_aarch64_crc32w : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
-def int_aarch64_crc32cw : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+def int_aarch64_crc32cw : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
-def int_aarch64_crc32x : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty],
+def int_aarch64_crc32x : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty],
[IntrNoMem]>;
-def int_aarch64_crc32cx : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty],
+def int_aarch64_crc32cx : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty],
[IntrNoMem]>;
}
//===----------------------------------------------------------------------===//
// Memory Tagging Extensions (MTE) Intrinsics
let TargetPrefix = "aarch64" in {
-def int_aarch64_irg : DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_i64_ty],
+def int_aarch64_irg : DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_i64_ty],
[IntrNoMem, IntrHasSideEffects]>;
-def int_aarch64_addg : DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_i64_ty],
+def int_aarch64_addg : DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_i64_ty],
[IntrNoMem]>;
-def int_aarch64_gmi : DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_ptr_ty, llvm_i64_ty],
+def int_aarch64_gmi : DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_ptr_ty, llvm_i64_ty],
[IntrNoMem]>;
-def int_aarch64_ldg : DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_ptr_ty],
+def int_aarch64_ldg : DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_ptr_ty],
[IntrReadMem]>;
-def int_aarch64_stg : DefaultAttrsIntrinsic<[], [llvm_ptr_ty, llvm_ptr_ty],
+def int_aarch64_stg : DefaultAttrsIntrinsic<[], [llvm_ptr_ty, llvm_ptr_ty],
[IntrWriteMem]>;
-def int_aarch64_subp : DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_ptr_ty, llvm_ptr_ty],
+def int_aarch64_subp : DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_ptr_ty, llvm_ptr_ty],
[IntrNoMem]>;
// The following are codegen-only intrinsics for stack instrumentation.
// Generate a randomly tagged stack base pointer.
-def int_aarch64_irg_sp : DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_i64_ty],
+def int_aarch64_irg_sp : DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_i64_ty],
[IntrNoMem, IntrHasSideEffects]>;
// Transfer pointer tag with offset.
// ptr1 = tagp(ptr0, baseptr, tag_offset) returns a pointer where
// * address is the address in ptr0
// * tag is a function of (tag in baseptr, tag_offset).
-// ** Beware, this is not the same function as implemented by the ADDG instruction!
-// Backend optimizations may change tag_offset; the only guarantee is that calls
-// to tagp with the same pair of (baseptr, tag_offset) will produce pointers
-// with the same tag value, assuming the set of excluded tags has not changed.
+// ** Beware, this is not the same function as implemented by the ADDG instruction!
+// Backend optimizations may change tag_offset; the only guarantee is that calls
+// to tagp with the same pair of (baseptr, tag_offset) will produce pointers
+// with the same tag value, assuming the set of excluded tags has not changed.
// Address bits in baseptr and tag bits in ptr0 are ignored.
// When offset between ptr0 and baseptr is a compile time constant, this can be emitted as
// ADDG ptr1, baseptr, (ptr0 - baseptr), tag_offset
// It is intended that ptr0 is an alloca address, and baseptr is the direct output of llvm.aarch64.irg.sp.
-def int_aarch64_tagp : DefaultAttrsIntrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>, llvm_ptr_ty, llvm_i64_ty],
+def int_aarch64_tagp : DefaultAttrsIntrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>, llvm_ptr_ty, llvm_i64_ty],
[IntrNoMem, ImmArg<ArgIndex<2>>]>;
// Update allocation tags for the memory range to match the tag in the pointer argument.
-def int_aarch64_settag : DefaultAttrsIntrinsic<[], [llvm_ptr_ty, llvm_i64_ty],
+def int_aarch64_settag : DefaultAttrsIntrinsic<[], [llvm_ptr_ty, llvm_i64_ty],
[IntrWriteMem, IntrArgMemOnly, NoCapture<ArgIndex<0>>, WriteOnly<ArgIndex<0>>]>;
// Update allocation tags for the memory range to match the tag in the pointer argument,
// and set memory contents to zero.
-def int_aarch64_settag_zero : DefaultAttrsIntrinsic<[], [llvm_ptr_ty, llvm_i64_ty],
+def int_aarch64_settag_zero : DefaultAttrsIntrinsic<[], [llvm_ptr_ty, llvm_i64_ty],
[IntrWriteMem, IntrArgMemOnly, NoCapture<ArgIndex<0>>, WriteOnly<ArgIndex<0>>]>;
// Update allocation tags for 16-aligned, 16-sized memory region, and store a pair 8-byte values.
-def int_aarch64_stgp : DefaultAttrsIntrinsic<[], [llvm_ptr_ty, llvm_i64_ty, llvm_i64_ty],
+def int_aarch64_stgp : DefaultAttrsIntrinsic<[], [llvm_ptr_ty, llvm_i64_ty, llvm_i64_ty],
[IntrWriteMem, IntrArgMemOnly, NoCapture<ArgIndex<0>>, WriteOnly<ArgIndex<0>>]>;
}
// Transactional Memory Extension (TME) Intrinsics
let TargetPrefix = "aarch64" in {
def int_aarch64_tstart : GCCBuiltin<"__builtin_arm_tstart">,
- Intrinsic<[llvm_i64_ty], [], [IntrWillReturn]>;
+ Intrinsic<[llvm_i64_ty], [], [IntrWillReturn]>;
-def int_aarch64_tcommit : GCCBuiltin<"__builtin_arm_tcommit">, Intrinsic<[], [], [IntrWillReturn]>;
+def int_aarch64_tcommit : GCCBuiltin<"__builtin_arm_tcommit">, Intrinsic<[], [], [IntrWillReturn]>;
def int_aarch64_tcancel : GCCBuiltin<"__builtin_arm_tcancel">,
- Intrinsic<[], [llvm_i64_ty], [IntrWillReturn, ImmArg<ArgIndex<0>>]>;
+ Intrinsic<[], [llvm_i64_ty], [IntrWillReturn, ImmArg<ArgIndex<0>>]>;
def int_aarch64_ttest : GCCBuiltin<"__builtin_arm_ttest">,
Intrinsic<[llvm_i64_ty], [],
- [IntrNoMem, IntrHasSideEffects, IntrWillReturn]>;
-
-// Armv8.7-A load/store 64-byte intrinsics
-defvar data512 = !listsplat(llvm_i64_ty, 8);
-def int_aarch64_ld64b: Intrinsic<data512, [llvm_ptr_ty]>;
-def int_aarch64_st64b: Intrinsic<[], !listconcat([llvm_ptr_ty], data512)>;
-def int_aarch64_st64bv: Intrinsic<[llvm_i64_ty], !listconcat([llvm_ptr_ty], data512)>;
-def int_aarch64_st64bv0: Intrinsic<[llvm_i64_ty], !listconcat([llvm_ptr_ty], data512)>;
-
+ [IntrNoMem, IntrHasSideEffects, IntrWillReturn]>;
+
+// Armv8.7-A load/store 64-byte intrinsics
+defvar data512 = !listsplat(llvm_i64_ty, 8);
+def int_aarch64_ld64b: Intrinsic<data512, [llvm_ptr_ty]>;
+def int_aarch64_st64b: Intrinsic<[], !listconcat([llvm_ptr_ty], data512)>;
+def int_aarch64_st64bv: Intrinsic<[llvm_i64_ty], !listconcat([llvm_ptr_ty], data512)>;
+def int_aarch64_st64bv0: Intrinsic<[llvm_i64_ty], !listconcat([llvm_ptr_ty], data512)>;
+
}
def llvm_nxv2i1_ty : LLVMType<nxv2i1>;
@@ -846,88 +846,88 @@ def llvm_nxv2f64_ty : LLVMType<nxv2f64>;
let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
class AdvSIMD_SVE_Create_2Vector_Tuple
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[llvm_anyvector_ty, LLVMMatchType<1>],
[IntrReadMem]>;
class AdvSIMD_SVE_Create_3Vector_Tuple
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[llvm_anyvector_ty, LLVMMatchType<1>, LLVMMatchType<1>],
[IntrReadMem]>;
class AdvSIMD_SVE_Create_4Vector_Tuple
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[llvm_anyvector_ty, LLVMMatchType<1>, LLVMMatchType<1>,
LLVMMatchType<1>],
[IntrReadMem]>;
class AdvSIMD_SVE_Set_Vector_Tuple
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, llvm_i32_ty, llvm_anyvector_ty],
[IntrReadMem, ImmArg<ArgIndex<1>>]>;
class AdvSIMD_SVE_Get_Vector_Tuple
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty, llvm_i32_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty, llvm_i32_ty],
[IntrReadMem, IntrArgMemOnly, ImmArg<ArgIndex<1>>]>;
class AdvSIMD_ManyVec_PredLoad_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty, LLVMPointerToElt<0>],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty, LLVMPointerToElt<0>],
[IntrReadMem, IntrArgMemOnly]>;
class AdvSIMD_1Vec_PredLoad_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMPointerToElt<0>],
[IntrReadMem, IntrArgMemOnly]>;
class AdvSIMD_1Vec_PredStore_Intrinsic
- : DefaultAttrsIntrinsic<[],
+ : DefaultAttrsIntrinsic<[],
[llvm_anyvector_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMPointerToElt<0>],
[IntrArgMemOnly, NoCapture<ArgIndex<2>>]>;
class AdvSIMD_2Vec_PredStore_Intrinsic
- : DefaultAttrsIntrinsic<[],
+ : DefaultAttrsIntrinsic<[],
[llvm_anyvector_ty, LLVMMatchType<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMPointerToElt<0>],
[IntrArgMemOnly, NoCapture<ArgIndex<3>>]>;
class AdvSIMD_3Vec_PredStore_Intrinsic
- : DefaultAttrsIntrinsic<[],
+ : DefaultAttrsIntrinsic<[],
[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMPointerToElt<0>],
[IntrArgMemOnly, NoCapture<ArgIndex<4>>]>;
class AdvSIMD_4Vec_PredStore_Intrinsic
- : DefaultAttrsIntrinsic<[],
+ : DefaultAttrsIntrinsic<[],
[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>,
LLVMMatchType<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMPointerToElt<0>],
[IntrArgMemOnly, NoCapture<ArgIndex<5>>]>;
class AdvSIMD_SVE_Index_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMVectorElementType<0>,
LLVMVectorElementType<0>],
[IntrNoMem]>;
class AdvSIMD_Merged1VectorArg_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMMatchType<0>],
[IntrNoMem]>;
class AdvSIMD_2VectorArgIndexed_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<2>>]>;
class AdvSIMD_3VectorArgIndexed_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMMatchType<0>,
LLVMMatchType<0>,
@@ -935,20 +935,20 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
[IntrNoMem, ImmArg<ArgIndex<3>>]>;
class AdvSIMD_Pred1VectorArg_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMMatchType<0>],
[IntrNoMem]>;
class AdvSIMD_Pred2VectorArg_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMMatchType<0>,
LLVMMatchType<0>],
[IntrNoMem]>;
class AdvSIMD_Pred3VectorArg_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMMatchType<0>,
LLVMMatchType<0>,
@@ -956,77 +956,77 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
[IntrNoMem]>;
class AdvSIMD_SVE_Compare_Intrinsic
- : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
+ : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_anyvector_ty,
LLVMMatchType<0>],
[IntrNoMem]>;
class AdvSIMD_SVE_CompareWide_Intrinsic
- : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
+ : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_anyvector_ty,
llvm_nxv2i64_ty],
[IntrNoMem]>;
class AdvSIMD_SVE_Saturating_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
[IntrNoMem]>;
class AdvSIMD_SVE_SaturatingWithPattern_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
llvm_i32_ty,
llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
class AdvSIMD_SVE_Saturating_N_Intrinsic<LLVMType T>
- : DefaultAttrsIntrinsic<[T],
+ : DefaultAttrsIntrinsic<[T],
[T, llvm_anyvector_ty],
[IntrNoMem]>;
class AdvSIMD_SVE_SaturatingWithPattern_N_Intrinsic<LLVMType T>
- : DefaultAttrsIntrinsic<[T],
+ : DefaultAttrsIntrinsic<[T],
[T, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
class AdvSIMD_SVE_CNT_Intrinsic
- : DefaultAttrsIntrinsic<[LLVMVectorOfBitcastsToInt<0>],
+ : DefaultAttrsIntrinsic<[LLVMVectorOfBitcastsToInt<0>],
[LLVMVectorOfBitcastsToInt<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_anyvector_ty],
[IntrNoMem]>;
class AdvSIMD_SVE_ReduceWithInit_Intrinsic
- : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
+ : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMVectorElementType<0>,
llvm_anyvector_ty],
[IntrNoMem]>;
class AdvSIMD_SVE_ShiftByImm_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMMatchType<0>,
llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<2>>]>;
class AdvSIMD_SVE_ShiftWide_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMMatchType<0>,
llvm_nxv2i64_ty],
[IntrNoMem]>;
class AdvSIMD_SVE_Unpack_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMSubdivide2VectorType<0>],
[IntrNoMem]>;
class AdvSIMD_SVE_CADD_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMMatchType<0>,
LLVMMatchType<0>,
@@ -1034,7 +1034,7 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
[IntrNoMem, ImmArg<ArgIndex<3>>]>;
class AdvSIMD_SVE_CMLA_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMMatchType<0>,
LLVMMatchType<0>,
@@ -1043,7 +1043,7 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
[IntrNoMem, ImmArg<ArgIndex<4>>]>;
class AdvSIMD_SVE_CMLA_LANE_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMMatchType<0>,
LLVMMatchType<0>,
@@ -1052,96 +1052,96 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
[IntrNoMem, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
class AdvSIMD_SVE_DUP_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMVectorElementType<0>],
[IntrNoMem]>;
class AdvSIMD_SVE_DUP_Unpred_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMVectorElementType<0>],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMVectorElementType<0>],
[IntrNoMem]>;
class AdvSIMD_SVE_DUPQ_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
llvm_i64_ty],
[IntrNoMem]>;
class AdvSIMD_SVE_EXPA_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMVectorOfBitcastsToInt<0>],
[IntrNoMem]>;
class AdvSIMD_SVE_FCVT_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_anyvector_ty],
[IntrNoMem]>;
class AdvSIMD_SVE_FCVTZS_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMVectorOfBitcastsToInt<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_anyvector_ty],
[IntrNoMem]>;
class AdvSIMD_SVE_INSR_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMVectorElementType<0>],
[IntrNoMem]>;
class AdvSIMD_SVE_PTRUE_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<0>>]>;
class AdvSIMD_SVE_PUNPKHI_Intrinsic
- : DefaultAttrsIntrinsic<[LLVMHalfElementsVectorType<0>],
+ : DefaultAttrsIntrinsic<[LLVMHalfElementsVectorType<0>],
[llvm_anyvector_ty],
[IntrNoMem]>;
class AdvSIMD_SVE_SCALE_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMMatchType<0>,
LLVMVectorOfBitcastsToInt<0>],
[IntrNoMem]>;
class AdvSIMD_SVE_SCVTF_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_anyvector_ty],
[IntrNoMem]>;
class AdvSIMD_SVE_TSMUL_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMVectorOfBitcastsToInt<0>],
[IntrNoMem]>;
class AdvSIMD_SVE_CNTB_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_i64_ty],
+ : DefaultAttrsIntrinsic<[llvm_i64_ty],
[llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<0>>]>;
class AdvSIMD_SVE_CNTP_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_i64_ty],
+ : DefaultAttrsIntrinsic<[llvm_i64_ty],
[llvm_anyvector_ty, LLVMMatchType<0>],
[IntrNoMem]>;
class AdvSIMD_SVE_DOT_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMSubdivide4VectorType<0>,
LLVMSubdivide4VectorType<0>],
[IntrNoMem]>;
class AdvSIMD_SVE_DOT_Indexed_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMSubdivide4VectorType<0>,
LLVMSubdivide4VectorType<0>,
@@ -1149,65 +1149,65 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
[IntrNoMem, ImmArg<ArgIndex<3>>]>;
class AdvSIMD_SVE_PTEST_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_i1_ty],
+ : DefaultAttrsIntrinsic<[llvm_i1_ty],
[llvm_anyvector_ty,
LLVMMatchType<0>],
[IntrNoMem]>;
class AdvSIMD_SVE_TBL_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMVectorOfBitcastsToInt<0>],
[IntrNoMem]>;
class AdvSIMD_SVE2_TBX_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMMatchType<0>,
LLVMVectorOfBitcastsToInt<0>],
[IntrNoMem]>;
class SVE2_1VectorArg_Long_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMSubdivide2VectorType<0>,
llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<1>>]>;
class SVE2_2VectorArg_Long_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMSubdivide2VectorType<0>,
LLVMSubdivide2VectorType<0>],
[IntrNoMem]>;
class SVE2_2VectorArgIndexed_Long_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMSubdivide2VectorType<0>,
LLVMSubdivide2VectorType<0>,
llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<2>>]>;
class SVE2_2VectorArg_Wide_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMSubdivide2VectorType<0>],
[IntrNoMem]>;
class SVE2_2VectorArg_Pred_Long_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMMatchType<0>,
LLVMSubdivide2VectorType<0>],
[IntrNoMem]>;
class SVE2_3VectorArg_Long_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMSubdivide2VectorType<0>,
LLVMSubdivide2VectorType<0>],
[IntrNoMem]>;
class SVE2_3VectorArgIndexed_Long_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMSubdivide2VectorType<0>,
LLVMSubdivide2VectorType<0>,
@@ -1215,45 +1215,45 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
[IntrNoMem, ImmArg<ArgIndex<3>>]>;
class SVE2_1VectorArg_Narrowing_Intrinsic
- : DefaultAttrsIntrinsic<[LLVMSubdivide2VectorType<0>],
+ : DefaultAttrsIntrinsic<[LLVMSubdivide2VectorType<0>],
[llvm_anyvector_ty],
[IntrNoMem]>;
class SVE2_Merged1VectorArg_Narrowing_Intrinsic
- : DefaultAttrsIntrinsic<[LLVMSubdivide2VectorType<0>],
+ : DefaultAttrsIntrinsic<[LLVMSubdivide2VectorType<0>],
[LLVMSubdivide2VectorType<0>,
llvm_anyvector_ty],
[IntrNoMem]>;
class SVE2_2VectorArg_Narrowing_Intrinsic
- : DefaultAttrsIntrinsic<
+ : DefaultAttrsIntrinsic<
[LLVMSubdivide2VectorType<0>],
[llvm_anyvector_ty, LLVMMatchType<0>],
[IntrNoMem]>;
class SVE2_Merged2VectorArg_Narrowing_Intrinsic
- : DefaultAttrsIntrinsic<
+ : DefaultAttrsIntrinsic<
[LLVMSubdivide2VectorType<0>],
[LLVMSubdivide2VectorType<0>, llvm_anyvector_ty, LLVMMatchType<0>],
[IntrNoMem]>;
class SVE2_1VectorArg_Imm_Narrowing_Intrinsic
- : DefaultAttrsIntrinsic<[LLVMSubdivide2VectorType<0>],
+ : DefaultAttrsIntrinsic<[LLVMSubdivide2VectorType<0>],
[llvm_anyvector_ty, llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<1>>]>;
class SVE2_2VectorArg_Imm_Narrowing_Intrinsic
- : DefaultAttrsIntrinsic<[LLVMSubdivide2VectorType<0>],
+ : DefaultAttrsIntrinsic<[LLVMSubdivide2VectorType<0>],
[LLVMSubdivide2VectorType<0>, llvm_anyvector_ty,
llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<2>>]>;
class SVE2_CONFLICT_DETECT_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMAnyPointerType<llvm_any_ty>,
LLVMMatchType<1>]>;
class SVE2_3VectorArg_Indexed_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMSubdivide2VectorType<0>,
LLVMSubdivide2VectorType<0>,
@@ -1261,7 +1261,7 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
[IntrNoMem, ImmArg<ArgIndex<3>>]>;
class AdvSIMD_SVE_CDOT_LANE_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
LLVMSubdivide4VectorType<0>,
LLVMSubdivide4VectorType<0>,
@@ -1278,7 +1278,7 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
// This class of intrinsics are not intended to be useful within LLVM IR but
// are instead here to support some of the more regid parts of the ACLE.
class Builtin_SVCVT<string name, LLVMType OUT, LLVMType PRED, LLVMType IN>
- : DefaultAttrsIntrinsic<[OUT], [OUT, PRED, IN], [IntrNoMem]>;
+ : DefaultAttrsIntrinsic<[OUT], [OUT, PRED, IN], [IntrNoMem]>;
}
//===----------------------------------------------------------------------===//
@@ -1287,24 +1287,24 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
class AdvSIMD_SVE_Reduce_Intrinsic
- : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
+ : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_anyvector_ty],
[IntrNoMem]>;
class AdvSIMD_SVE_SADDV_Reduce_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_i64_ty],
+ : DefaultAttrsIntrinsic<[llvm_i64_ty],
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_anyvector_ty],
[IntrNoMem]>;
class AdvSIMD_SVE_WHILE_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[llvm_anyint_ty, LLVMMatchType<1>],
[IntrNoMem]>;
class AdvSIMD_GatherLoad_SV_64b_Offsets_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMPointerToElt<0>,
@@ -1313,7 +1313,7 @@ class AdvSIMD_GatherLoad_SV_64b_Offsets_Intrinsic
[IntrReadMem, IntrArgMemOnly]>;
class AdvSIMD_GatherLoad_SV_32b_Offsets_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMPointerToElt<0>,
@@ -1322,16 +1322,16 @@ class AdvSIMD_GatherLoad_SV_32b_Offsets_Intrinsic
[IntrReadMem, IntrArgMemOnly]>;
class AdvSIMD_GatherLoad_VS_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_anyvector_ty,
llvm_i64_ty
],
- [IntrReadMem]>;
+ [IntrReadMem]>;
class AdvSIMD_ScatterStore_SV_64b_Offsets_Intrinsic
- : DefaultAttrsIntrinsic<[],
+ : DefaultAttrsIntrinsic<[],
[
llvm_anyvector_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
@@ -1341,7 +1341,7 @@ class AdvSIMD_ScatterStore_SV_64b_Offsets_Intrinsic
[IntrWriteMem, IntrArgMemOnly]>;
class AdvSIMD_ScatterStore_SV_32b_Offsets_Intrinsic
- : DefaultAttrsIntrinsic<[],
+ : DefaultAttrsIntrinsic<[],
[
llvm_anyvector_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
@@ -1351,17 +1351,17 @@ class AdvSIMD_ScatterStore_SV_32b_Offsets_Intrinsic
[IntrWriteMem, IntrArgMemOnly]>;
class AdvSIMD_ScatterStore_VS_Intrinsic
- : DefaultAttrsIntrinsic<[],
+ : DefaultAttrsIntrinsic<[],
[
llvm_anyvector_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_anyvector_ty, llvm_i64_ty
],
- [IntrWriteMem]>;
+ [IntrWriteMem]>;
class SVE_gather_prf_SV
- : DefaultAttrsIntrinsic<[],
+ : DefaultAttrsIntrinsic<[],
[
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, // Predicate
llvm_ptr_ty, // Base address
@@ -1371,7 +1371,7 @@ class SVE_gather_prf_SV
[IntrInaccessibleMemOrArgMemOnly, NoCapture<ArgIndex<1>>, ImmArg<ArgIndex<3>>]>;
class SVE_gather_prf_VS
- : DefaultAttrsIntrinsic<[],
+ : DefaultAttrsIntrinsic<[],
[
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, // Predicate
llvm_anyvector_ty, // Base addresses
@@ -1381,17 +1381,17 @@ class SVE_gather_prf_VS
[IntrInaccessibleMemOrArgMemOnly, ImmArg<ArgIndex<3>>]>;
class SVE_MatMul_Intrinsic
- : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+ : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, LLVMSubdivide4VectorType<0>, LLVMSubdivide4VectorType<0>],
[IntrNoMem]>;
class SVE_4Vec_BF16
- : DefaultAttrsIntrinsic<[llvm_nxv4f32_ty],
+ : DefaultAttrsIntrinsic<[llvm_nxv4f32_ty],
[llvm_nxv4f32_ty, llvm_nxv8bf16_ty, llvm_nxv8bf16_ty],
[IntrNoMem]>;
class SVE_4Vec_BF16_Indexed
- : DefaultAttrsIntrinsic<[llvm_nxv4f32_ty],
+ : DefaultAttrsIntrinsic<[llvm_nxv4f32_ty],
[llvm_nxv4f32_ty, llvm_nxv8bf16_ty, llvm_nxv8bf16_ty, llvm_i64_ty],
[IntrNoMem, ImmArg<ArgIndex<3>>]>;
@@ -1443,7 +1443,7 @@ def int_aarch64_sve_stnt1 : AdvSIMD_1Vec_PredStore_Intrinsic;
//
def int_aarch64_sve_prf
- : DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, llvm_ptr_ty, llvm_i32_ty],
+ : DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, llvm_ptr_ty, llvm_i32_ty],
[IntrArgMemOnly, ImmArg<ArgIndex<2>>]>;
// Scalar + 32-bit scaled offset vector, zero extend, packed and
@@ -1607,10 +1607,10 @@ def int_aarch64_sve_cntp : AdvSIMD_SVE_CNTP_Intrinsic;
// FFR manipulation
//
-def int_aarch64_sve_rdffr : GCCBuiltin<"__builtin_sve_svrdffr">, DefaultAttrsIntrinsic<[llvm_nxv16i1_ty], []>;
-def int_aarch64_sve_rdffr_z : GCCBuiltin<"__builtin_sve_svrdffr_z">, DefaultAttrsIntrinsic<[llvm_nxv16i1_ty], [llvm_nxv16i1_ty]>;
-def int_aarch64_sve_setffr : GCCBuiltin<"__builtin_sve_svsetffr">, DefaultAttrsIntrinsic<[], []>;
-def int_aarch64_sve_wrffr : GCCBuiltin<"__builtin_sve_svwrffr">, DefaultAttrsIntrinsic<[], [llvm_nxv16i1_ty]>;
+def int_aarch64_sve_rdffr : GCCBuiltin<"__builtin_sve_svrdffr">, DefaultAttrsIntrinsic<[llvm_nxv16i1_ty], []>;
+def int_aarch64_sve_rdffr_z : GCCBuiltin<"__builtin_sve_svrdffr_z">, DefaultAttrsIntrinsic<[llvm_nxv16i1_ty], [llvm_nxv16i1_ty]>;
+def int_aarch64_sve_setffr : GCCBuiltin<"__builtin_sve_svsetffr">, DefaultAttrsIntrinsic<[], []>;
+def int_aarch64_sve_wrffr : GCCBuiltin<"__builtin_sve_svwrffr">, DefaultAttrsIntrinsic<[], [llvm_nxv16i1_ty]>;
//
// Saturating scalar arithmetic
@@ -1923,11 +1923,11 @@ def int_aarch64_sve_ptest_last : AdvSIMD_SVE_PTEST_Intrinsic;
// Reinterpreting data
//
-def int_aarch64_sve_convert_from_svbool : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
+def int_aarch64_sve_convert_from_svbool : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
[llvm_nxv16i1_ty],
[IntrNoMem]>;
-def int_aarch64_sve_convert_to_svbool : DefaultAttrsIntrinsic<[llvm_nxv16i1_ty],
+def int_aarch64_sve_convert_to_svbool : DefaultAttrsIntrinsic<[llvm_nxv16i1_ty],
[llvm_anyvector_ty],
[IntrNoMem]>;
@@ -2342,31 +2342,31 @@ def int_aarch64_sve_xar : AdvSIMD_2VectorArgIndexed_Intrinsic;
//
def int_aarch64_sve_aesd : GCCBuiltin<"__builtin_sve_svaesd_u8">,
- DefaultAttrsIntrinsic<[llvm_nxv16i8_ty],
+ DefaultAttrsIntrinsic<[llvm_nxv16i8_ty],
[llvm_nxv16i8_ty, llvm_nxv16i8_ty],
[IntrNoMem]>;
def int_aarch64_sve_aesimc : GCCBuiltin<"__builtin_sve_svaesimc_u8">,
- DefaultAttrsIntrinsic<[llvm_nxv16i8_ty],
+ DefaultAttrsIntrinsic<[llvm_nxv16i8_ty],
[llvm_nxv16i8_ty],
[IntrNoMem]>;
def int_aarch64_sve_aese : GCCBuiltin<"__builtin_sve_svaese_u8">,
- DefaultAttrsIntrinsic<[llvm_nxv16i8_ty],
+ DefaultAttrsIntrinsic<[llvm_nxv16i8_ty],
[llvm_nxv16i8_ty, llvm_nxv16i8_ty],
[IntrNoMem]>;
def int_aarch64_sve_aesmc : GCCBuiltin<"__builtin_sve_svaesmc_u8">,
- DefaultAttrsIntrinsic<[llvm_nxv16i8_ty],
+ DefaultAttrsIntrinsic<[llvm_nxv16i8_ty],
[llvm_nxv16i8_ty],
[IntrNoMem]>;
def int_aarch64_sve_rax1 : GCCBuiltin<"__builtin_sve_svrax1_u64">,
- DefaultAttrsIntrinsic<[llvm_nxv2i64_ty],
+ DefaultAttrsIntrinsic<[llvm_nxv2i64_ty],
[llvm_nxv2i64_ty, llvm_nxv2i64_ty],
[IntrNoMem]>;
def int_aarch64_sve_sm4e : GCCBuiltin<"__builtin_sve_svsm4e_u32">,
- DefaultAttrsIntrinsic<[llvm_nxv4i32_ty],
+ DefaultAttrsIntrinsic<[llvm_nxv4i32_ty],
[llvm_nxv4i32_ty, llvm_nxv4i32_ty],
[IntrNoMem]>;
def int_aarch64_sve_sm4ekey : GCCBuiltin<"__builtin_sve_svsm4ekey_u32">,
- DefaultAttrsIntrinsic<[llvm_nxv4i32_ty],
+ DefaultAttrsIntrinsic<[llvm_nxv4i32_ty],
[llvm_nxv4i32_ty, llvm_nxv4i32_ty],
[IntrNoMem]>;
//
diff --git a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsAMDGPU.td b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsAMDGPU.td
index 4cec95a6c9..ac2291f9d4 100644
--- a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsAMDGPU.td
+++ b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsAMDGPU.td
@@ -18,7 +18,7 @@ class AMDGPUReadPreloadRegisterIntrinsicNamed<string name>
// Used to tag image and resource intrinsics with information used to generate
// mem operands.
-class AMDGPURsrcIntrinsic<int rsrcarg, bit isimage = false> {
+class AMDGPURsrcIntrinsic<int rsrcarg, bit isimage = false> {
int RsrcArg = rsrcarg;
bit IsImage = isimage;
}
@@ -182,8 +182,8 @@ def int_amdgcn_init_exec : Intrinsic<[],
// Set EXEC according to a thread count packed in an SGPR input:
// thread_count = (input >> bitoffset) & 0x7f;
// This is always moved to the beginning of the basic block.
-// Note: only inreg arguments to the parent function are valid as
-// inputs to this intrinsic, computed values cannot be used.
+// Note: only inreg arguments to the parent function are valid as
+// inputs to this intrinsic, computed values cannot be used.
def int_amdgcn_init_exec_from_input : Intrinsic<[],
[llvm_i32_ty, // 32-bit SGPR input
llvm_i32_ty], // bit offset of the thread count
@@ -257,19 +257,19 @@ def int_amdgcn_log_clamp : Intrinsic<
def int_amdgcn_fmul_legacy : GCCBuiltin<"__builtin_amdgcn_fmul_legacy">,
Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
- [IntrNoMem, IntrSpeculatable, IntrWillReturn, Commutative]
->;
-
-// Fused single-precision multiply-add with legacy behaviour for the multiply,
-// which is that +/- 0.0 * anything (even NaN or infinity) is +0.0. This is
-// intended for use on subtargets that have the v_fma_legacy_f32 and/or
-// v_fmac_legacy_f32 instructions. (Note that v_fma_legacy_f16 is unrelated and
-// has a completely different kind of legacy behaviour.)
-def int_amdgcn_fma_legacy :
- Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],
- [IntrNoMem, IntrSpeculatable, IntrWillReturn, Commutative]
->;
-
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn, Commutative]
+>;
+
+// Fused single-precision multiply-add with legacy behaviour for the multiply,
+// which is that +/- 0.0 * anything (even NaN or infinity) is +0.0. This is
+// intended for use on subtargets that have the v_fma_legacy_f32 and/or
+// v_fmac_legacy_f32 instructions. (Note that v_fma_legacy_f16 is unrelated and
+// has a completely different kind of legacy behaviour.)
+def int_amdgcn_fma_legacy :
+ Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn, Commutative]
+>;
+
def int_amdgcn_rcp : Intrinsic<
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
@@ -409,10 +409,10 @@ class AMDGPUAtomicIncIntrin : Intrinsic<[llvm_anyint_ty],
def int_amdgcn_atomic_inc : AMDGPUAtomicIncIntrin;
def int_amdgcn_atomic_dec : AMDGPUAtomicIncIntrin;
-class AMDGPULDSIntrin :
- Intrinsic<[llvm_any_ty],
- [LLVMQualPointerType<LLVMMatchType<0>, 3>,
- LLVMMatchType<0>,
+class AMDGPULDSIntrin :
+ Intrinsic<[llvm_any_ty],
+ [LLVMQualPointerType<LLVMMatchType<0>, 3>,
+ LLVMMatchType<0>,
llvm_i32_ty, // ordering
llvm_i32_ty, // scope
llvm_i1_ty], // isVolatile
@@ -457,9 +457,9 @@ def int_amdgcn_ds_ordered_swap : AMDGPUDSOrderedIntrinsic;
def int_amdgcn_ds_append : AMDGPUDSAppendConsumedIntrinsic;
def int_amdgcn_ds_consume : AMDGPUDSAppendConsumedIntrinsic;
-def int_amdgcn_ds_fadd : AMDGPULDSIntrin;
-def int_amdgcn_ds_fmin : AMDGPULDSIntrin;
-def int_amdgcn_ds_fmax : AMDGPULDSIntrin;
+def int_amdgcn_ds_fadd : AMDGPULDSIntrin;
+def int_amdgcn_ds_fmin : AMDGPULDSIntrin;
+def int_amdgcn_ds_fmax : AMDGPULDSIntrin;
} // TargetPrefix = "amdgcn"
@@ -556,7 +556,7 @@ class AMDGPUSampleVariant<string ucmod, string lcmod, list<AMDGPUArg> extra_addr
// {offset} {bias} {z-compare}
list<AMDGPUArg> ExtraAddrArgs = extra_addr;
- bit Gradients = false;
+ bit Gradients = false;
// Name of the {lod} or {clamp} argument that is appended to the coordinates,
// if any.
@@ -596,7 +596,7 @@ defset list<AMDGPUSampleVariant> AMDGPUSampleVariants = {
defm AMDGPUSample : AMDGPUSampleHelper_Compare<"_LZ", "_lz", []>;
}
- let Gradients = true in {
+ let Gradients = true in {
defm AMDGPUSample : AMDGPUSampleHelper_Clamp<"_D", "_d", []>;
defm AMDGPUSample : AMDGPUSampleHelper_Clamp<"_CD", "_cd", []>;
}
@@ -611,12 +611,12 @@ class AMDGPUDimProfile<string opmod,
string OpMod = opmod; // the corresponding instruction is named IMAGE_OpMod
// These are intended to be overwritten by subclasses
- bit IsSample = false;
- bit IsAtomic = false;
+ bit IsSample = false;
+ bit IsAtomic = false;
list<LLVMType> RetTypes = [];
list<AMDGPUArg> DataArgs = [];
list<AMDGPUArg> ExtraAddrArgs = [];
- bit Gradients = false;
+ bit Gradients = false;
string LodClampMip = "";
int NumRetAndDataAnyTypes =
@@ -627,7 +627,7 @@ class AMDGPUDimProfile<string opmod,
arglistconcat<[ExtraAddrArgs,
!if(Gradients, dim.GradientArgs, []),
!listconcat(!if(IsSample, dim.CoordSliceArgs, dim.CoordSliceIntArgs),
- !if(!empty(LodClampMip),
+ !if(!empty(LodClampMip),
[]<AMDGPUArg>,
[AMDGPUArg<LLVMMatchType<0>, LodClampMip>]))],
NumRetAndDataAnyTypes>.ret;
@@ -657,7 +657,7 @@ class AMDGPUDimProfileCopy<AMDGPUDimProfile base> : AMDGPUDimProfile<base.OpMod,
class AMDGPUDimSampleProfile<string opmod,
AMDGPUDimProps dim,
AMDGPUSampleVariant sample> : AMDGPUDimProfile<opmod, dim> {
- let IsSample = true;
+ let IsSample = true;
let RetTypes = [llvm_any_ty];
let ExtraAddrArgs = sample.ExtraAddrArgs;
let Gradients = sample.Gradients;
@@ -668,7 +668,7 @@ class AMDGPUDimNoSampleProfile<string opmod,
AMDGPUDimProps dim,
list<LLVMType> retty,
list<AMDGPUArg> dataargs,
- bit Mip = false> : AMDGPUDimProfile<opmod, dim> {
+ bit Mip = false> : AMDGPUDimProfile<opmod, dim> {
let RetTypes = retty;
let DataArgs = dataargs;
let LodClampMip = !if(Mip, "mip", "");
@@ -679,7 +679,7 @@ class AMDGPUDimAtomicProfile<string opmod,
list<AMDGPUArg> dataargs> : AMDGPUDimProfile<opmod, dim> {
let RetTypes = [llvm_anyint_ty];
let DataArgs = dataargs;
- let IsAtomic = true;
+ let IsAtomic = true;
}
class AMDGPUDimGetResInfoProfile<AMDGPUDimProps dim> : AMDGPUDimProfile<"GET_RESINFO", dim> {
@@ -692,23 +692,23 @@ class AMDGPUDimGetResInfoProfile<AMDGPUDimProps dim> : AMDGPUDimProfile<"GET_RES
// Helper class for figuring out image intrinsic argument indexes.
class AMDGPUImageDimIntrinsicEval<AMDGPUDimProfile P_> {
int NumDataArgs = !size(P_.DataArgs);
- int NumDmaskArgs = !not(P_.IsAtomic);
- int NumExtraAddrArgs = !size(P_.ExtraAddrArgs);
+ int NumDmaskArgs = !not(P_.IsAtomic);
+ int NumExtraAddrArgs = !size(P_.ExtraAddrArgs);
int NumVAddrArgs = !size(P_.AddrArgs);
- int NumGradientArgs = !if(P_.Gradients, !size(P_.Dim.GradientArgs), 0);
- int NumCoordArgs = !if(P_.IsSample, !size(P_.Dim.CoordSliceArgs), !size(P_.Dim.CoordSliceIntArgs));
+ int NumGradientArgs = !if(P_.Gradients, !size(P_.Dim.GradientArgs), 0);
+ int NumCoordArgs = !if(P_.IsSample, !size(P_.Dim.CoordSliceArgs), !size(P_.Dim.CoordSliceIntArgs));
int NumRSrcArgs = 1;
int NumSampArgs = !if(P_.IsSample, 2, 0);
int DmaskArgIndex = NumDataArgs;
- int VAddrArgIndex = !add(DmaskArgIndex, NumDmaskArgs);
- int GradientArgIndex = !add(VAddrArgIndex, NumExtraAddrArgs);
- int CoordArgIndex = !add(GradientArgIndex, NumGradientArgs);
- int LodArgIndex = !add(VAddrArgIndex, NumVAddrArgs, -1);
- int MipArgIndex = LodArgIndex;
- int RsrcArgIndex = !add(VAddrArgIndex, NumVAddrArgs);
- int SampArgIndex = !add(RsrcArgIndex, NumRSrcArgs);
- int UnormArgIndex = !add(SampArgIndex, 1);
- int TexFailCtrlArgIndex = !add(SampArgIndex, NumSampArgs);
+ int VAddrArgIndex = !add(DmaskArgIndex, NumDmaskArgs);
+ int GradientArgIndex = !add(VAddrArgIndex, NumExtraAddrArgs);
+ int CoordArgIndex = !add(GradientArgIndex, NumGradientArgs);
+ int LodArgIndex = !add(VAddrArgIndex, NumVAddrArgs, -1);
+ int MipArgIndex = LodArgIndex;
+ int RsrcArgIndex = !add(VAddrArgIndex, NumVAddrArgs);
+ int SampArgIndex = !add(RsrcArgIndex, NumRSrcArgs);
+ int UnormArgIndex = !add(SampArgIndex, 1);
+ int TexFailCtrlArgIndex = !add(SampArgIndex, NumSampArgs);
int CachePolicyArgIndex = !add(TexFailCtrlArgIndex, 1);
}
@@ -759,7 +759,7 @@ defset list<AMDGPUImageDimIntrinsic> AMDGPUImageDimIntrinsics = {
list<AMDGPUArg> dataargs,
list<IntrinsicProperty> props,
list<SDNodeProperty> sdnodeprops,
- bit Mip = false> {
+ bit Mip = false> {
foreach dim = AMDGPUDims.NoMsaa in {
def !strconcat(NAME, "_", dim.Name)
: AMDGPUImageDimIntrinsic<
@@ -773,7 +773,7 @@ defset list<AMDGPUImageDimIntrinsic> AMDGPUImageDimIntrinsics = {
list<AMDGPUArg> dataargs,
list<IntrinsicProperty> props,
list<SDNodeProperty> sdnodeprops,
- bit Mip = false> {
+ bit Mip = false> {
foreach dim = AMDGPUDims.All in {
def !strconcat(NAME, "_", dim.Name)
: AMDGPUImageDimIntrinsic<
@@ -808,7 +808,7 @@ defset list<AMDGPUImageDimIntrinsic> AMDGPUImageDimIntrinsics = {
//////////////////////////////////////////////////////////////////////////
multiclass AMDGPUImageDimSampleDims<string opmod,
AMDGPUSampleVariant sample,
- bit NoMem = false> {
+ bit NoMem = false> {
foreach dim = AMDGPUDims.NoMsaa in {
def !strconcat(NAME, "_", dim.Name) : AMDGPUImageDimIntrinsic<
AMDGPUDimSampleProfile<opmod, dim, sample>,
@@ -994,9 +994,9 @@ class AMDGPUStructBufferStore<LLVMType data_ty = llvm_any_ty> : Intrinsic <
def int_amdgcn_struct_buffer_store_format : AMDGPUStructBufferStore;
def int_amdgcn_struct_buffer_store : AMDGPUStructBufferStore;
-class AMDGPURawBufferAtomic<LLVMType data_ty = llvm_any_ty, bit NoRtn = false> : Intrinsic <
- !if(NoRtn, [], [data_ty]),
- [!if(NoRtn, data_ty, LLVMMatchType<0>), // vdata(VGPR)
+class AMDGPURawBufferAtomic<LLVMType data_ty = llvm_any_ty, bit NoRtn = false> : Intrinsic <
+ !if(NoRtn, [], [data_ty]),
+ [!if(NoRtn, data_ty, LLVMMatchType<0>), // vdata(VGPR)
llvm_v4i32_ty, // rsrc(SGPR)
llvm_i32_ty, // offset(VGPR/imm, included in bounds checking and swizzling)
llvm_i32_ty, // soffset(SGPR/imm, excluded from bounds checking and swizzling)
@@ -1026,12 +1026,12 @@ def int_amdgcn_raw_buffer_atomic_cmpswap : Intrinsic<
[ImmArg<ArgIndex<5>>, IntrWillReturn], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<2, 0>;
-// gfx908 intrinsic
-def int_amdgcn_raw_buffer_atomic_fadd : AMDGPURawBufferAtomic<llvm_anyfloat_ty>;
-
-class AMDGPUStructBufferAtomic<LLVMType data_ty = llvm_any_ty, bit NoRtn = false> : Intrinsic <
- !if(NoRtn, [], [data_ty]),
- [!if(NoRtn, data_ty, LLVMMatchType<0>), // vdata(VGPR)
+// gfx908 intrinsic
+def int_amdgcn_raw_buffer_atomic_fadd : AMDGPURawBufferAtomic<llvm_anyfloat_ty>;
+
+class AMDGPUStructBufferAtomic<LLVMType data_ty = llvm_any_ty, bit NoRtn = false> : Intrinsic <
+ !if(NoRtn, [], [data_ty]),
+ [!if(NoRtn, data_ty, LLVMMatchType<0>), // vdata(VGPR)
llvm_v4i32_ty, // rsrc(SGPR)
llvm_i32_ty, // vindex(VGPR)
llvm_i32_ty, // offset(VGPR/imm, included in bounds checking and swizzling)
@@ -1063,10 +1063,10 @@ def int_amdgcn_struct_buffer_atomic_cmpswap : Intrinsic<
[ImmArg<ArgIndex<6>>, IntrWillReturn], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<2, 0>;
-// gfx908 intrinsic
-def int_amdgcn_struct_buffer_atomic_fadd : AMDGPUStructBufferAtomic<llvm_anyfloat_ty>;
-
-
+// gfx908 intrinsic
+def int_amdgcn_struct_buffer_atomic_fadd : AMDGPUStructBufferAtomic<llvm_anyfloat_ty>;
+
+
// Obsolescent tbuffer intrinsics.
def int_amdgcn_tbuffer_load : Intrinsic <
[llvm_any_ty], // overloaded for types f32/i32, v2f32/v2i32, v4f32/v4i32
@@ -1196,19 +1196,19 @@ def int_amdgcn_buffer_atomic_cmpswap : Intrinsic<
AMDGPURsrcIntrinsic<2, 0>;
def int_amdgcn_buffer_atomic_csub : AMDGPUBufferAtomic;
-
-class AMDGPUBufferAtomicFP : Intrinsic <
- [llvm_anyfloat_ty],
- [LLVMMatchType<0>, // vdata(VGPR)
- llvm_v4i32_ty, // rsrc(SGPR)
- llvm_i32_ty, // vindex(VGPR)
- llvm_i32_ty, // offset(SGPR/VGPR/imm)
- llvm_i1_ty], // slc(imm)
- [ImmArg<ArgIndex<4>>, IntrWillReturn], "", [SDNPMemOperand]>,
- AMDGPURsrcIntrinsic<1, 0>;
-
-// Legacy form of the intrinsic. raw and struct forms should be preferred.
-def int_amdgcn_buffer_atomic_fadd : AMDGPUBufferAtomicFP;
+
+class AMDGPUBufferAtomicFP : Intrinsic <
+ [llvm_anyfloat_ty],
+ [LLVMMatchType<0>, // vdata(VGPR)
+ llvm_v4i32_ty, // rsrc(SGPR)
+ llvm_i32_ty, // vindex(VGPR)
+ llvm_i32_ty, // offset(SGPR/VGPR/imm)
+ llvm_i1_ty], // slc(imm)
+ [ImmArg<ArgIndex<4>>, IntrWillReturn], "", [SDNPMemOperand]>,
+ AMDGPURsrcIntrinsic<1, 0>;
+
+// Legacy form of the intrinsic. raw and struct forms should be preferred.
+def int_amdgcn_buffer_atomic_fadd : AMDGPUBufferAtomicFP;
} // defset AMDGPUBufferIntrinsics
// Uses that do not set the done bit should set IntrWriteMem on the
@@ -1289,7 +1289,7 @@ def int_amdgcn_s_getreg :
def int_amdgcn_s_setreg :
GCCBuiltin<"__builtin_amdgcn_s_setreg">,
Intrinsic<[], [llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrHasSideEffects, IntrWillReturn, ImmArg<ArgIndex<0>>]
+ [IntrNoMem, IntrHasSideEffects, IntrWillReturn, ImmArg<ArgIndex<0>>]
>;
// int_amdgcn_s_getpc is provided to allow a specific style of position
@@ -1332,7 +1332,7 @@ def int_amdgcn_interp_p2 :
// See int_amdgcn_v_interp_p1 for why this is IntrNoMem.
// __builtin_amdgcn_interp_p1_f16 <i>, <attr_chan>, <attr>, <high>, <m0>
-// high selects whether high or low 16-bits are loaded from LDS
+// high selects whether high or low 16-bits are loaded from LDS
def int_amdgcn_interp_p1_f16 :
GCCBuiltin<"__builtin_amdgcn_interp_p1_f16">,
Intrinsic<[llvm_float_ty],
@@ -1341,7 +1341,7 @@ def int_amdgcn_interp_p1_f16 :
ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;
// __builtin_amdgcn_interp_p2_f16 <p1>, <j>, <attr_chan>, <attr>, <high>, <m0>
-// high selects whether high or low 16-bits are loaded from LDS
+// high selects whether high or low 16-bits are loaded from LDS
def int_amdgcn_interp_p2_f16 :
GCCBuiltin<"__builtin_amdgcn_interp_p2_f16">,
Intrinsic<[llvm_half_ty],
@@ -1581,10 +1581,10 @@ def int_amdgcn_wqm_vote : Intrinsic<[llvm_i1_ty],
// FIXME: Should this be IntrNoMem, IntrHasSideEffects, or IntrWillReturn?
def int_amdgcn_kill : Intrinsic<[], [llvm_i1_ty], []>;
-def int_amdgcn_endpgm : GCCBuiltin<"__builtin_amdgcn_endpgm">,
- Intrinsic<[], [], [IntrNoReturn, IntrCold, IntrNoMem, IntrHasSideEffects]
->;
-
+def int_amdgcn_endpgm : GCCBuiltin<"__builtin_amdgcn_endpgm">,
+ Intrinsic<[], [], [IntrNoReturn, IntrCold, IntrNoMem, IntrHasSideEffects]
+>;
+
// Copies the active channels of the source value to the destination value,
// with the guarantee that the source value is computed as if the entire
// program were executed in Whole Wavefront Mode, i.e. with all channels
@@ -1714,19 +1714,19 @@ class AMDGPUGlobalAtomicRtn<LLVMType vt> : Intrinsic <
[vt],
[llvm_anyptr_ty, // vaddr
vt], // vdata(VGPR)
- [IntrArgMemOnly, IntrWillReturn, NoCapture<ArgIndex<0>>], "",
- [SDNPMemOperand]>;
+ [IntrArgMemOnly, IntrWillReturn, NoCapture<ArgIndex<0>>], "",
+ [SDNPMemOperand]>;
def int_amdgcn_global_atomic_csub : AMDGPUGlobalAtomicRtn<llvm_i32_ty>;
-// uint4 llvm.amdgcn.image.bvh.intersect.ray <node_ptr>, <ray_extent>, <ray_origin>,
-// <ray_dir>, <ray_inv_dir>, <texture_descr>
-def int_amdgcn_image_bvh_intersect_ray :
- Intrinsic<[llvm_v4i32_ty],
- [llvm_anyint_ty, llvm_float_ty, llvm_v4f32_ty, llvm_anyvector_ty,
- LLVMMatchType<1>, llvm_v4i32_ty],
- [IntrReadMem, IntrWillReturn]>;
-
+// uint4 llvm.amdgcn.image.bvh.intersect.ray <node_ptr>, <ray_extent>, <ray_origin>,
+// <ray_dir>, <ray_inv_dir>, <texture_descr>
+def int_amdgcn_image_bvh_intersect_ray :
+ Intrinsic<[llvm_v4i32_ty],
+ [llvm_anyint_ty, llvm_float_ty, llvm_v4f32_ty, llvm_anyvector_ty,
+ LLVMMatchType<1>, llvm_v4i32_ty],
+ [IntrReadMem, IntrWillReturn]>;
+
//===----------------------------------------------------------------------===//
// Deep learning intrinsics.
//===----------------------------------------------------------------------===//
@@ -1842,7 +1842,7 @@ def int_amdgcn_udot8 :
// gfx908 intrinsics
// ===----------------------------------------------------------------------===//
-def int_amdgcn_global_atomic_fadd : AMDGPUGlobalAtomicRtn<llvm_anyfloat_ty>;
+def int_amdgcn_global_atomic_fadd : AMDGPUGlobalAtomicRtn<llvm_anyfloat_ty>;
// llvm.amdgcn.mfma.f32.* vdst, srcA, srcB, srcC, cbsz, abid, blgp
def int_amdgcn_mfma_f32_32x32x1f32 : GCCBuiltin<"__builtin_amdgcn_mfma_f32_32x32x1f32">,
diff --git a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsARM.td b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsARM.td
index e2283bfd60..0eb27cc344 100644
--- a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsARM.td
+++ b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsARM.td
@@ -791,17 +791,17 @@ def int_arm_neon_vcvtbfp2bf
: Intrinsic<[llvm_bfloat_ty], [llvm_float_ty], [IntrNoMem]>;
def int_arm_neon_bfdot : Neon_Dot_Intrinsic;
-def int_arm_neon_bfmmla
- : Intrinsic<[llvm_v4f32_ty],
- [llvm_v4f32_ty, llvm_v8bf16_ty, llvm_v8bf16_ty],
- [IntrNoMem]>;
-
-class Neon_BF16FML_Intrinsic
- : Intrinsic<[llvm_v4f32_ty],
- [llvm_v4f32_ty, llvm_v8bf16_ty, llvm_v8bf16_ty],
- [IntrNoMem]>;
-def int_arm_neon_bfmlalb : Neon_BF16FML_Intrinsic;
-def int_arm_neon_bfmlalt : Neon_BF16FML_Intrinsic;
+def int_arm_neon_bfmmla
+ : Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_v8bf16_ty, llvm_v8bf16_ty],
+ [IntrNoMem]>;
+
+class Neon_BF16FML_Intrinsic
+ : Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_v8bf16_ty, llvm_v8bf16_ty],
+ [IntrNoMem]>;
+def int_arm_neon_bfmlalb : Neon_BF16FML_Intrinsic;
+def int_arm_neon_bfmlalt : Neon_BF16FML_Intrinsic;
def int_arm_cls: Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
def int_arm_cls64: Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem]>;
@@ -817,7 +817,7 @@ def int_arm_neon_vcadd_rot90 : Neon_2Arg_Intrinsic;
def int_arm_neon_vcadd_rot270 : Neon_2Arg_Intrinsic;
// GNU eabi mcount
-def int_arm_gnu_eabi_mcount : Intrinsic<[], [], []>;
+def int_arm_gnu_eabi_mcount : Intrinsic<[], [], []>;
def int_arm_mve_pred_i2v : Intrinsic<
[llvm_anyvector_ty], [llvm_i32_ty], [IntrNoMem]>;
@@ -922,7 +922,7 @@ multiclass MVEPredicatedM<list<LLVMType> rets, list<LLVMType> params,
list<IntrinsicProperty> props = [IntrNoMem]> {
def "": Intrinsic<rets, params, props>;
def _predicated: Intrinsic<rets, params # [pred,
- !if(!eq(rets[0], llvm_anyvector_ty),
+ !if(!eq(rets[0], llvm_anyvector_ty),
LLVMMatchType<0>, rets[0])], props>;
}
diff --git a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsBPF.td b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsBPF.td
index d70a9a9131..4b4dd94b15 100644
--- a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsBPF.td
+++ b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsBPF.td
@@ -24,14 +24,14 @@ let TargetPrefix = "bpf" in { // All intrinsics start with "llvm.bpf."
Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty, llvm_i64_ty],
[IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_bpf_btf_type_id : GCCBuiltin<"__builtin_bpf_btf_type_id">,
- Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i64_ty],
+ Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i64_ty],
[IntrNoMem]>;
- def int_bpf_preserve_type_info : GCCBuiltin<"__builtin_bpf_preserve_type_info">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty],
- [IntrNoMem]>;
- def int_bpf_preserve_enum_value : GCCBuiltin<"__builtin_bpf_preserve_enum_value">,
- Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_ptr_ty, llvm_i64_ty],
- [IntrNoMem]>;
- def int_bpf_passthrough : GCCBuiltin<"__builtin_bpf_passthrough">,
- Intrinsic<[llvm_any_ty], [llvm_i32_ty, llvm_any_ty], [IntrNoMem]>;
+ def int_bpf_preserve_type_info : GCCBuiltin<"__builtin_bpf_preserve_type_info">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+ def int_bpf_preserve_enum_value : GCCBuiltin<"__builtin_bpf_preserve_enum_value">,
+ Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_ptr_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+ def int_bpf_passthrough : GCCBuiltin<"__builtin_bpf_passthrough">,
+ Intrinsic<[llvm_any_ty], [llvm_i32_ty, llvm_any_ty], [IntrNoMem]>;
}
diff --git a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsNVVM.td b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsNVVM.td
index 146e1890cb..2ab48cfc4b 100644
--- a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsNVVM.td
+++ b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsNVVM.td
@@ -49,40 +49,40 @@ class WMMA_REGS<string Geom, string Frag, string PtxEltType> {
string ft = frag#":"#ptx_elt_type;
list<LLVMType> regs = !cond(
// mma.sync.m8n8k4 uses smaller a/b fragments than wmma fp ops
- !eq(gft,"m8n8k4:a:f16") : !listsplat(llvm_v2f16_ty, 2),
- !eq(gft,"m8n8k4:b:f16") : !listsplat(llvm_v2f16_ty, 2),
+ !eq(gft,"m8n8k4:a:f16") : !listsplat(llvm_v2f16_ty, 2),
+ !eq(gft,"m8n8k4:b:f16") : !listsplat(llvm_v2f16_ty, 2),
// fp16 -> fp16/fp32 @ m16n16k16/m8n32k16/m32n8k16
// All currently supported geometries use the same fragment format,
// so we only need to consider {fragment, type}.
- !eq(ft,"a:f16") : !listsplat(llvm_v2f16_ty, 8),
- !eq(ft,"b:f16") : !listsplat(llvm_v2f16_ty, 8),
- !eq(ft,"c:f16") : !listsplat(llvm_v2f16_ty, 4),
- !eq(ft,"d:f16") : !listsplat(llvm_v2f16_ty, 4),
- !eq(ft,"c:f32") : !listsplat(llvm_float_ty, 8),
- !eq(ft,"d:f32") : !listsplat(llvm_float_ty, 8),
+ !eq(ft,"a:f16") : !listsplat(llvm_v2f16_ty, 8),
+ !eq(ft,"b:f16") : !listsplat(llvm_v2f16_ty, 8),
+ !eq(ft,"c:f16") : !listsplat(llvm_v2f16_ty, 4),
+ !eq(ft,"d:f16") : !listsplat(llvm_v2f16_ty, 4),
+ !eq(ft,"c:f32") : !listsplat(llvm_float_ty, 8),
+ !eq(ft,"d:f32") : !listsplat(llvm_float_ty, 8),
// u8/s8 -> s32 @ m16n16k16/m8n32k16/m32n8k16
- !eq(gft,"m16n16k16:a:u8") : !listsplat(llvm_i32_ty, 2),
- !eq(gft,"m16n16k16:a:s8") : !listsplat(llvm_i32_ty, 2),
- !eq(gft,"m16n16k16:b:u8") : !listsplat(llvm_i32_ty, 2),
- !eq(gft,"m16n16k16:b:s8") : !listsplat(llvm_i32_ty, 2),
- !eq(gft,"m16n16k16:c:s32") : !listsplat(llvm_i32_ty, 8),
- !eq(gft,"m16n16k16:d:s32") : !listsplat(llvm_i32_ty, 8),
+ !eq(gft,"m16n16k16:a:u8") : !listsplat(llvm_i32_ty, 2),
+ !eq(gft,"m16n16k16:a:s8") : !listsplat(llvm_i32_ty, 2),
+ !eq(gft,"m16n16k16:b:u8") : !listsplat(llvm_i32_ty, 2),
+ !eq(gft,"m16n16k16:b:s8") : !listsplat(llvm_i32_ty, 2),
+ !eq(gft,"m16n16k16:c:s32") : !listsplat(llvm_i32_ty, 8),
+ !eq(gft,"m16n16k16:d:s32") : !listsplat(llvm_i32_ty, 8),
!eq(gft,"m8n32k16:a:u8") : [llvm_i32_ty],
!eq(gft,"m8n32k16:a:s8") : [llvm_i32_ty],
- !eq(gft,"m8n32k16:b:u8") : !listsplat(llvm_i32_ty, 4),
- !eq(gft,"m8n32k16:b:s8") : !listsplat(llvm_i32_ty, 4),
- !eq(gft,"m8n32k16:c:s32") : !listsplat(llvm_i32_ty, 8),
- !eq(gft,"m8n32k16:d:s32") : !listsplat(llvm_i32_ty, 8),
+ !eq(gft,"m8n32k16:b:u8") : !listsplat(llvm_i32_ty, 4),
+ !eq(gft,"m8n32k16:b:s8") : !listsplat(llvm_i32_ty, 4),
+ !eq(gft,"m8n32k16:c:s32") : !listsplat(llvm_i32_ty, 8),
+ !eq(gft,"m8n32k16:d:s32") : !listsplat(llvm_i32_ty, 8),
- !eq(gft,"m32n8k16:a:u8") : !listsplat(llvm_i32_ty, 4),
- !eq(gft,"m32n8k16:a:s8") : !listsplat(llvm_i32_ty, 4),
+ !eq(gft,"m32n8k16:a:u8") : !listsplat(llvm_i32_ty, 4),
+ !eq(gft,"m32n8k16:a:s8") : !listsplat(llvm_i32_ty, 4),
!eq(gft,"m32n8k16:b:u8") : [llvm_i32_ty],
!eq(gft,"m32n8k16:b:s8") : [llvm_i32_ty],
- !eq(gft,"m32n8k16:c:s32") : !listsplat(llvm_i32_ty, 8),
- !eq(gft,"m32n8k16:d:s32") : !listsplat(llvm_i32_ty, 8),
+ !eq(gft,"m32n8k16:c:s32") : !listsplat(llvm_i32_ty, 8),
+ !eq(gft,"m32n8k16:d:s32") : !listsplat(llvm_i32_ty, 8),
// u4/s4/b1 -> s32 @ m8n8k32 (u4/s4), m8n8k128(b1)
!eq(gft,"m8n8k128:a:b1") : [llvm_i32_ty],
@@ -91,10 +91,10 @@ class WMMA_REGS<string Geom, string Frag, string PtxEltType> {
!eq(gft,"m8n8k128:b:b1") : [llvm_i32_ty],
!eq(gft,"m8n8k32:b:u4") : [llvm_i32_ty],
!eq(gft,"m8n8k32:b:s4") : [llvm_i32_ty],
- !eq(gft,"m8n8k128:c:s32") : !listsplat(llvm_i32_ty, 2),
- !eq(gft,"m8n8k128:d:s32") : !listsplat(llvm_i32_ty, 2),
- !eq(gft,"m8n8k32:c:s32") : !listsplat(llvm_i32_ty, 2),
- !eq(gft,"m8n8k32:d:s32") : !listsplat(llvm_i32_ty, 2),
+ !eq(gft,"m8n8k128:c:s32") : !listsplat(llvm_i32_ty, 2),
+ !eq(gft,"m8n8k128:d:s32") : !listsplat(llvm_i32_ty, 2),
+ !eq(gft,"m8n8k32:c:s32") : !listsplat(llvm_i32_ty, 2),
+ !eq(gft,"m8n8k32:d:s32") : !listsplat(llvm_i32_ty, 2),
);
}
@@ -128,7 +128,7 @@ class MMA_SIGNATURE<WMMA_REGS A, WMMA_REGS B, WMMA_REGS C, WMMA_REGS D> {
!eq(A.ptx_elt_type, "u4") : [A],
!eq(A.ptx_elt_type, "b1") : [A],
// the rest are FP ops identified by accumulator & result type.
- true: [D, C]
+ true: [D, C]
);
string ret = !foldl("", id_frags, a, b, !strconcat(a, ".", b.ptx_elt_type));
}
@@ -225,17 +225,17 @@ class NVVM_MMA_OPS<int _ = 0> {
ldst_bit_ab_ops,
ldst_subint_cd_ops);
// Separate A/B/C fragments (loads) from D (stores).
- list<WMMA_REGS> all_ld_ops = !filter(op, all_ldst_ops, !ne(op.frag, "d"));
- list<WMMA_REGS> all_st_ops = !filter(op, all_ldst_ops, !eq(op.frag, "d"));
+ list<WMMA_REGS> all_ld_ops = !filter(op, all_ldst_ops, !ne(op.frag, "d"));
+ list<WMMA_REGS> all_st_ops = !filter(op, all_ldst_ops, !eq(op.frag, "d"));
}
def NVVM_MMA_OPS : NVVM_MMA_OPS;
-// Returns true if this combination of layout/satf is supported; false otherwise.
+// Returns true if this combination of layout/satf is supported; false otherwise.
// MMA ops must provide all parameters. Loads and stores -- only frags and layout_a.
// The class is used to prevent generation of records for the unsupported variants.
// E.g.
-// if NVVM_MMA_SUPPORTED<...>.ret then
+// if NVVM_MMA_SUPPORTED<...>.ret then
// def : FOO<>; // The record will only be defined for supported ops.
//
class NVVM_MMA_SUPPORTED<list<WMMA_REGS> frags, string layout_a, string layout_b="-", int satf=-1> {
@@ -261,20 +261,20 @@ class NVVM_MMA_SUPPORTED<list<WMMA_REGS> frags, string layout_a, string layout_b
# !if(!eq(!size(frags), 4),
frags[2].ptx_elt_type # frags[3].ptx_elt_type,
"?");
- bit ret = !cond(
+ bit ret = !cond(
// Sub-int MMA only supports fixed A/B layout.
// b1 does not support .satf.
- !eq(mma#":"#satf, "b1:row:col:0") : true,
+ !eq(mma#":"#satf, "b1:row:col:0") : true,
// mma.m8n8k4 has no .satf modifier.
!and(!eq(frags[0].geom, "m8n8k4"),
- !ne(satf, 0)): false,
+ !ne(satf, 0)): false,
// mma.m8n8k4 has no C=f32 D=f16 variant.
- !eq(gcd, "m8n8k4:f32f16"): false,
- !eq(mma, "s4:row:col") : true,
- !eq(mma, "u4:row:col") : true,
- !eq(mma, "s4:row:col") : true,
- !eq(mma, "u4:row:col") : true,
+ !eq(gcd, "m8n8k4:f32f16"): false,
+ !eq(mma, "s4:row:col") : true,
+ !eq(mma, "u4:row:col") : true,
+ !eq(mma, "s4:row:col") : true,
+ !eq(mma, "u4:row:col") : true,
// Sub-int load/stores have fixed layout for A and B.
!and(!eq(layout_b, "-"), // It's a Load or Store op
!or(!eq(ld, "b1:a:row"),
@@ -288,13 +288,13 @@ class NVVM_MMA_SUPPORTED<list<WMMA_REGS> frags, string layout_a, string layout_b
!eq(ld, "u4:a:row"),
!eq(ld, "u4:b:col"),
!eq(ldf, "u4:c"),
- !eq(ldf, "u4:d"))) : true,
+ !eq(ldf, "u4:d"))) : true,
// All other sub-int ops are not supported.
- !eq(t, "b1") : false,
- !eq(t, "s4") : false,
- !eq(t, "u4") : false,
+ !eq(t, "b1") : false,
+ !eq(t, "s4") : false,
+ !eq(t, "u4") : false,
// All other (non sub-int) are OK.
- true: true
+ true: true
);
}
@@ -307,8 +307,8 @@ class SHFL_INFO<bit sync, string mode, string type, bit return_pred> {
string Name = "int_nvvm_shfl_" # Suffix;
string Builtin = "__nvvm_shfl_" # Suffix;
string IntrName = "llvm.nvvm.shfl." # !subst("_",".", Suffix);
- bit withGccBuiltin = !not(return_pred);
- bit withoutGccBuiltin = return_pred;
+ bit withGccBuiltin = !not(return_pred);
+ bit withoutGccBuiltin = return_pred;
LLVMType OpType = !cond(
!eq(type,"i32"): llvm_i32_ty,
!eq(type,"f32"): llvm_float_ty);
@@ -3998,18 +3998,18 @@ def int_nvvm_read_ptx_sreg_warpsize : PTXReadSRegIntrinsic_r32<"warpsize">;
// SHUFFLE
//
// Generate intrinsics for all variants of shfl instruction.
-foreach sync = [false, true] in {
+foreach sync = [false, true] in {
foreach mode = ["up", "down", "bfly", "idx"] in {
foreach type = ["i32", "f32"] in {
- foreach return_pred = [false, true] in {
+ foreach return_pred = [false, true] in {
foreach i = [SHFL_INFO<sync, mode, type, return_pred>] in {
- if i.withGccBuiltin then {
+ if i.withGccBuiltin then {
def i.Name : GCCBuiltin<i.Builtin>,
Intrinsic<i.RetTy, i.ArgsTy,
[IntrInaccessibleMemOnly, IntrConvergent],
i.IntrName>;
}
- if i.withoutGccBuiltin then {
+ if i.withoutGccBuiltin then {
def i.Name : Intrinsic<i.RetTy, i.ArgsTy,
[IntrInaccessibleMemOnly, IntrConvergent], i.IntrName>;
}
@@ -4120,11 +4120,11 @@ class NVVM_WMMA_ST<WMMA_REGS Frag, string Layout, int WithStride>
foreach layout = ["row", "col"] in {
foreach stride = [0, 1] in {
foreach frag = NVVM_MMA_OPS.all_ld_ops in
- if NVVM_MMA_SUPPORTED<[frag], layout>.ret then
+ if NVVM_MMA_SUPPORTED<[frag], layout>.ret then
def WMMA_NAME_LDST<"load", frag, layout, stride>.record
: NVVM_WMMA_LD<frag, layout, stride>;
foreach frag = NVVM_MMA_OPS.all_st_ops in
- if NVVM_MMA_SUPPORTED<[frag], layout>.ret then
+ if NVVM_MMA_SUPPORTED<[frag], layout>.ret then
def WMMA_NAME_LDST<"store", frag, layout, stride>.record
: NVVM_WMMA_ST<frag, layout, stride>;
}
@@ -4143,7 +4143,7 @@ foreach layout_a = ["row", "col"] in {
foreach layout_b = ["row", "col"] in {
foreach satf = [0, 1] in {
foreach op = NVVM_MMA_OPS.all_mma_ops in {
- if NVVM_MMA_SUPPORTED<op, layout_a, layout_b, satf>.ret then {
+ if NVVM_MMA_SUPPORTED<op, layout_a, layout_b, satf>.ret then {
def WMMA_NAME_MMA<layout_a, layout_b, satf,
op[0], op[1], op[2], op[3]>.record
: NVVM_WMMA_MMA<layout_a, layout_b, satf,
diff --git a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsPowerPC.td b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsPowerPC.td
index 3587af5189..075b6252d9 100644
--- a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsPowerPC.td
@@ -18,12 +18,12 @@
let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
// dcba/dcbf/dcbi/dcbst/dcbt/dcbz/dcbzl(PPC970) instructions.
def int_ppc_dcba : Intrinsic<[], [llvm_ptr_ty], []>;
- def int_ppc_dcbf : GCCBuiltin<"__builtin_dcbf">,
- Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>;
- def int_ppc_dcbfl : Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>;
- def int_ppc_dcbflp : Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>;
- def int_ppc_dcbfps : Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>;
- def int_ppc_dcbstps : Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>;
+ def int_ppc_dcbf : GCCBuiltin<"__builtin_dcbf">,
+ Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>;
+ def int_ppc_dcbfl : Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>;
+ def int_ppc_dcbflp : Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>;
+ def int_ppc_dcbfps : Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>;
+ def int_ppc_dcbstps : Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>;
def int_ppc_dcbi : Intrinsic<[], [llvm_ptr_ty], []>;
def int_ppc_dcbst : Intrinsic<[], [llvm_ptr_ty], []>;
def int_ppc_dcbt : Intrinsic<[], [llvm_ptr_ty],
@@ -49,13 +49,13 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
// eieio instruction
def int_ppc_eieio : Intrinsic<[],[],[]>;
- // Get content from current FPSCR register
- def int_ppc_readflm : GCCBuiltin<"__builtin_readflm">,
- Intrinsic<[llvm_double_ty], [], [IntrNoMem]>;
- // Set FPSCR register, and return previous content
- def int_ppc_setflm : GCCBuiltin<"__builtin_setflm">,
- Intrinsic<[llvm_double_ty], [llvm_double_ty], []>;
-
+ // Get content from current FPSCR register
+ def int_ppc_readflm : GCCBuiltin<"__builtin_readflm">,
+ Intrinsic<[llvm_double_ty], [], [IntrNoMem]>;
+ // Set FPSCR register, and return previous content
+ def int_ppc_setflm : GCCBuiltin<"__builtin_setflm">,
+ Intrinsic<[llvm_double_ty], [llvm_double_ty], []>;
+
// Intrinsics for [double]word extended forms of divide instructions
def int_ppc_divwe : GCCBuiltin<"__builtin_divwe">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
@@ -70,14 +70,14 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
[IntrNoMem]>;
- // Generate a random number
- def int_ppc_darn : GCCBuiltin<"__builtin_darn">,
- Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>;
- def int_ppc_darnraw : GCCBuiltin<"__builtin_darn_raw">,
- Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>;
- def int_ppc_darn32 : GCCBuiltin<"__builtin_darn_32">,
- Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
-
+ // Generate a random number
+ def int_ppc_darn : GCCBuiltin<"__builtin_darn">,
+ Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>;
+ def int_ppc_darnraw : GCCBuiltin<"__builtin_darn_raw">,
+ Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>;
+ def int_ppc_darn32 : GCCBuiltin<"__builtin_darn_32">,
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
+
// Bit permute doubleword
def int_ppc_bpermd : GCCBuiltin<"__builtin_bpermd">,
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
@@ -152,28 +152,28 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
}
//===----------------------------------------------------------------------===//
-// PowerPC MMA Intrinsic Multi Class Definitions.
-//
-
-multiclass PowerPC_MMA_ACC_Intrinsic<list<LLVMType> args> {
- def NAME: Intrinsic<[llvm_v512i1_ty], args, [IntrNoMem]>;
- def pp : Intrinsic<[llvm_v512i1_ty], !listconcat([llvm_v512i1_ty], args),
- [IntrNoMem]>;
- def pn : Intrinsic<[llvm_v512i1_ty], !listconcat([llvm_v512i1_ty], args),
- [IntrNoMem]>;
- def np : Intrinsic<[llvm_v512i1_ty], !listconcat([llvm_v512i1_ty], args),
- [IntrNoMem]>;
- def nn : Intrinsic<[llvm_v512i1_ty], !listconcat([llvm_v512i1_ty], args),
- [IntrNoMem]>;
-}
-
-multiclass PowerPC_MMA_ACC_PP_Intrinsic<list<LLVMType> args> {
- def NAME: Intrinsic<[llvm_v512i1_ty], args, [IntrNoMem]>;
- def pp : Intrinsic<[llvm_v512i1_ty], !listconcat([llvm_v512i1_ty], args),
- [IntrNoMem]>;
-}
-
-//===----------------------------------------------------------------------===//
+// PowerPC MMA Intrinsic Multi Class Definitions.
+//
+
+multiclass PowerPC_MMA_ACC_Intrinsic<list<LLVMType> args> {
+ def NAME: Intrinsic<[llvm_v512i1_ty], args, [IntrNoMem]>;
+ def pp : Intrinsic<[llvm_v512i1_ty], !listconcat([llvm_v512i1_ty], args),
+ [IntrNoMem]>;
+ def pn : Intrinsic<[llvm_v512i1_ty], !listconcat([llvm_v512i1_ty], args),
+ [IntrNoMem]>;
+ def np : Intrinsic<[llvm_v512i1_ty], !listconcat([llvm_v512i1_ty], args),
+ [IntrNoMem]>;
+ def nn : Intrinsic<[llvm_v512i1_ty], !listconcat([llvm_v512i1_ty], args),
+ [IntrNoMem]>;
+}
+
+multiclass PowerPC_MMA_ACC_PP_Intrinsic<list<LLVMType> args> {
+ def NAME: Intrinsic<[llvm_v512i1_ty], args, [IntrNoMem]>;
+ def pp : Intrinsic<[llvm_v512i1_ty], !listconcat([llvm_v512i1_ty], args),
+ [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
// PowerPC Altivec Intrinsic Class Definitions.
//
@@ -225,13 +225,13 @@ class PowerPC_Vec_QQQ_Intrinsic<string GCCIntSuffix>
[llvm_v1i128_ty], [llvm_v1i128_ty, llvm_v1i128_ty],
[IntrNoMem]>;
-/// PowerPC_Vec_QDD_Intrinsic - A PowerPC intrinsic that takes two v2i64
-/// vectors and returns one v1i128. These intrinsics have no side effects.
-class PowerPC_Vec_QDD_Intrinsic<string GCCIntSuffix>
- : PowerPC_Vec_Intrinsic<GCCIntSuffix,
- [llvm_v1i128_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem]>;
-
+/// PowerPC_Vec_QDD_Intrinsic - A PowerPC intrinsic that takes two v2i64
+/// vectors and returns one v1i128. These intrinsics have no side effects.
+class PowerPC_Vec_QDD_Intrinsic<string GCCIntSuffix>
+ : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+ [llvm_v1i128_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+
//===----------------------------------------------------------------------===//
// PowerPC VSX Intrinsic Class Definitions.
//
@@ -285,9 +285,9 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
// VSCR access.
def int_ppc_altivec_mfvscr : GCCBuiltin<"__builtin_altivec_mfvscr">,
- Intrinsic<[llvm_v8i16_ty], [], [IntrNoMem, IntrHasSideEffects]>;
+ Intrinsic<[llvm_v8i16_ty], [], [IntrNoMem, IntrHasSideEffects]>;
def int_ppc_altivec_mtvscr : GCCBuiltin<"__builtin_altivec_mtvscr">,
- Intrinsic<[], [llvm_v4i32_ty], [IntrNoMem, IntrHasSideEffects]>;
+ Intrinsic<[], [llvm_v4i32_ty], [IntrNoMem, IntrHasSideEffects]>;
// Loads. These don't map directly to GCC builtins because they represent the
@@ -393,28 +393,28 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
[IntrNoMem]>;
- def int_ppc_altivec_vcmpequq : GCCBuiltin<"__builtin_altivec_vcmpequq">,
- Intrinsic<[llvm_v1i128_ty], [llvm_v1i128_ty, llvm_v1i128_ty],
- [IntrNoMem]>;
- def int_ppc_altivec_vcmpgtsq : GCCBuiltin<"__builtin_altivec_vcmpgtsq">,
- Intrinsic<[llvm_v1i128_ty], [llvm_v1i128_ty, llvm_v1i128_ty],
- [IntrNoMem]>;
- def int_ppc_altivec_vcmpgtuq : GCCBuiltin<"__builtin_altivec_vcmpgtuq">,
- Intrinsic<[llvm_v1i128_ty], [llvm_v1i128_ty, llvm_v1i128_ty],
- [IntrNoMem]>;
- def int_ppc_altivec_vcmpequq_p : GCCBuiltin<"__builtin_altivec_vcmpequq_p">,
- Intrinsic<[llvm_i32_ty],
- [llvm_i32_ty,llvm_v1i128_ty,llvm_v1i128_ty],
- [IntrNoMem]>;
- def int_ppc_altivec_vcmpgtsq_p : GCCBuiltin<"__builtin_altivec_vcmpgtsq_p">,
- Intrinsic<[llvm_i32_ty],
- [llvm_i32_ty,llvm_v1i128_ty,llvm_v1i128_ty],
- [IntrNoMem]>;
- def int_ppc_altivec_vcmpgtuq_p : GCCBuiltin<"__builtin_altivec_vcmpgtuq_p">,
- Intrinsic<[llvm_i32_ty],
- [llvm_i32_ty,llvm_v1i128_ty,llvm_v1i128_ty],
- [IntrNoMem]>;
-
+ def int_ppc_altivec_vcmpequq : GCCBuiltin<"__builtin_altivec_vcmpequq">,
+ Intrinsic<[llvm_v1i128_ty], [llvm_v1i128_ty, llvm_v1i128_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtsq : GCCBuiltin<"__builtin_altivec_vcmpgtsq">,
+ Intrinsic<[llvm_v1i128_ty], [llvm_v1i128_ty, llvm_v1i128_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtuq : GCCBuiltin<"__builtin_altivec_vcmpgtuq">,
+ Intrinsic<[llvm_v1i128_ty], [llvm_v1i128_ty, llvm_v1i128_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpequq_p : GCCBuiltin<"__builtin_altivec_vcmpequq_p">,
+ Intrinsic<[llvm_i32_ty],
+ [llvm_i32_ty,llvm_v1i128_ty,llvm_v1i128_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtsq_p : GCCBuiltin<"__builtin_altivec_vcmpgtsq_p">,
+ Intrinsic<[llvm_i32_ty],
+ [llvm_i32_ty,llvm_v1i128_ty,llvm_v1i128_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtuq_p : GCCBuiltin<"__builtin_altivec_vcmpgtuq_p">,
+ Intrinsic<[llvm_i32_ty],
+ [llvm_i32_ty,llvm_v1i128_ty,llvm_v1i128_ty],
+ [IntrNoMem]>;
+
// Predicate Comparisons. The first operand specifies interpretation of CR6.
def int_ppc_altivec_vcmpbfp_p : GCCBuiltin<"__builtin_altivec_vcmpbfp_p">,
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty],
@@ -497,56 +497,56 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
def int_ppc_altivec_vprtybq : GCCBuiltin<"__builtin_altivec_vprtybq">,
Intrinsic<[llvm_v1i128_ty],[llvm_v1i128_ty],[IntrNoMem]>;
- // P10 Vector Extract with Mask
- def int_ppc_altivec_vextractbm : GCCBuiltin<"__builtin_altivec_vextractbm">,
- Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>;
- def int_ppc_altivec_vextracthm : GCCBuiltin<"__builtin_altivec_vextracthm">,
- Intrinsic<[llvm_i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
- def int_ppc_altivec_vextractwm : GCCBuiltin<"__builtin_altivec_vextractwm">,
- Intrinsic<[llvm_i32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
- def int_ppc_altivec_vextractdm : GCCBuiltin<"__builtin_altivec_vextractdm">,
- Intrinsic<[llvm_i32_ty], [llvm_v2i64_ty], [IntrNoMem]>;
- def int_ppc_altivec_vextractqm : GCCBuiltin<"__builtin_altivec_vextractqm">,
- Intrinsic<[llvm_i32_ty], [llvm_v1i128_ty], [IntrNoMem]>;
-
- // P10 Vector Expand with Mask
- def int_ppc_altivec_vexpandbm : GCCBuiltin<"__builtin_altivec_vexpandbm">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
- def int_ppc_altivec_vexpandhm : GCCBuiltin<"__builtin_altivec_vexpandhm">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
- def int_ppc_altivec_vexpandwm : GCCBuiltin<"__builtin_altivec_vexpandwm">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
- def int_ppc_altivec_vexpanddm : GCCBuiltin<"__builtin_altivec_vexpanddm">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>;
- def int_ppc_altivec_vexpandqm : GCCBuiltin<"__builtin_altivec_vexpandqm">,
- Intrinsic<[llvm_v1i128_ty], [llvm_v1i128_ty], [IntrNoMem]>;
-
- // P10 Vector Count with Mask intrinsics.
- def int_ppc_altivec_vcntmbb : GCCBuiltin<"__builtin_altivec_vcntmbb">,
- Intrinsic<[llvm_i64_ty], [llvm_v16i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<ArgIndex<1>>]>;
- def int_ppc_altivec_vcntmbh : GCCBuiltin<"__builtin_altivec_vcntmbh">,
- Intrinsic<[llvm_i64_ty], [llvm_v8i16_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<ArgIndex<1>>]>;
- def int_ppc_altivec_vcntmbw : GCCBuiltin<"__builtin_altivec_vcntmbw">,
- Intrinsic<[llvm_i64_ty], [llvm_v4i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<ArgIndex<1>>]>;
- def int_ppc_altivec_vcntmbd : GCCBuiltin<"__builtin_altivec_vcntmbd">,
- Intrinsic<[llvm_i64_ty], [llvm_v2i64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<ArgIndex<1>>]>;
-
- // P10 Move to VSR with Mask Intrinsics.
- def int_ppc_altivec_mtvsrbm : GCCBuiltin<"__builtin_altivec_mtvsrbm">,
- Intrinsic<[llvm_v16i8_ty], [llvm_i64_ty], [IntrNoMem]>;
- def int_ppc_altivec_mtvsrhm : GCCBuiltin<"__builtin_altivec_mtvsrhm">,
- Intrinsic<[llvm_v8i16_ty], [llvm_i64_ty], [IntrNoMem]>;
- def int_ppc_altivec_mtvsrwm : GCCBuiltin<"__builtin_altivec_mtvsrwm">,
- Intrinsic<[llvm_v4i32_ty], [llvm_i64_ty], [IntrNoMem]>;
- def int_ppc_altivec_mtvsrdm : GCCBuiltin<"__builtin_altivec_mtvsrdm">,
- Intrinsic<[llvm_v2i64_ty], [llvm_i64_ty], [IntrNoMem]>;
- def int_ppc_altivec_mtvsrqm : GCCBuiltin<"__builtin_altivec_mtvsrqm">,
- Intrinsic<[llvm_v1i128_ty], [llvm_i64_ty], [IntrNoMem]>;
-
+ // P10 Vector Extract with Mask
+ def int_ppc_altivec_vextractbm : GCCBuiltin<"__builtin_altivec_vextractbm">,
+ Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vextracthm : GCCBuiltin<"__builtin_altivec_vextracthm">,
+ Intrinsic<[llvm_i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vextractwm : GCCBuiltin<"__builtin_altivec_vextractwm">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vextractdm : GCCBuiltin<"__builtin_altivec_vextractdm">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2i64_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vextractqm : GCCBuiltin<"__builtin_altivec_vextractqm">,
+ Intrinsic<[llvm_i32_ty], [llvm_v1i128_ty], [IntrNoMem]>;
+
+ // P10 Vector Expand with Mask
+ def int_ppc_altivec_vexpandbm : GCCBuiltin<"__builtin_altivec_vexpandbm">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vexpandhm : GCCBuiltin<"__builtin_altivec_vexpandhm">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vexpandwm : GCCBuiltin<"__builtin_altivec_vexpandwm">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vexpanddm : GCCBuiltin<"__builtin_altivec_vexpanddm">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vexpandqm : GCCBuiltin<"__builtin_altivec_vexpandqm">,
+ Intrinsic<[llvm_v1i128_ty], [llvm_v1i128_ty], [IntrNoMem]>;
+
+ // P10 Vector Count with Mask intrinsics.
+ def int_ppc_altivec_vcntmbb : GCCBuiltin<"__builtin_altivec_vcntmbb">,
+ Intrinsic<[llvm_i64_ty], [llvm_v16i8_ty, llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+ def int_ppc_altivec_vcntmbh : GCCBuiltin<"__builtin_altivec_vcntmbh">,
+ Intrinsic<[llvm_i64_ty], [llvm_v8i16_ty, llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+ def int_ppc_altivec_vcntmbw : GCCBuiltin<"__builtin_altivec_vcntmbw">,
+ Intrinsic<[llvm_i64_ty], [llvm_v4i32_ty, llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+ def int_ppc_altivec_vcntmbd : GCCBuiltin<"__builtin_altivec_vcntmbd">,
+ Intrinsic<[llvm_i64_ty], [llvm_v2i64_ty, llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+ // P10 Move to VSR with Mask Intrinsics.
+ def int_ppc_altivec_mtvsrbm : GCCBuiltin<"__builtin_altivec_mtvsrbm">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_ppc_altivec_mtvsrhm : GCCBuiltin<"__builtin_altivec_mtvsrhm">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_ppc_altivec_mtvsrwm : GCCBuiltin<"__builtin_altivec_mtvsrwm">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_ppc_altivec_mtvsrdm : GCCBuiltin<"__builtin_altivec_mtvsrdm">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_i64_ty], [IntrNoMem]>;
+ def int_ppc_altivec_mtvsrqm : GCCBuiltin<"__builtin_altivec_mtvsrqm">,
+ Intrinsic<[llvm_v1i128_ty], [llvm_i64_ty], [IntrNoMem]>;
+
// P10 Vector Parallel Bits Deposit/Extract Doubleword Builtins.
def int_ppc_altivec_vpdepd : GCCBuiltin<"__builtin_altivec_vpdepd">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
@@ -555,25 +555,25 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
[IntrNoMem]>;
- // P10 Vector String Isolate Intrinsics.
- def int_ppc_altivec_vstribr : GCCBuiltin<"__builtin_altivec_vstribr">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
- def int_ppc_altivec_vstribl : GCCBuiltin<"__builtin_altivec_vstribl">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
- def int_ppc_altivec_vstrihr : GCCBuiltin<"__builtin_altivec_vstrihr">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
- def int_ppc_altivec_vstrihl : GCCBuiltin<"__builtin_altivec_vstrihl">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
- // Predicate Intrinsics: The first operand specifies interpretation of CR6.
- def int_ppc_altivec_vstribr_p : GCCBuiltin<"__builtin_altivec_vstribr_p">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v16i8_ty], [IntrNoMem]>;
- def int_ppc_altivec_vstribl_p : GCCBuiltin<"__builtin_altivec_vstribl_p">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v16i8_ty], [IntrNoMem]>;
- def int_ppc_altivec_vstrihr_p : GCCBuiltin<"__builtin_altivec_vstrihr_p">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v8i16_ty], [IntrNoMem]>;
- def int_ppc_altivec_vstrihl_p : GCCBuiltin<"__builtin_altivec_vstrihl_p">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v8i16_ty], [IntrNoMem]>;
-
+ // P10 Vector String Isolate Intrinsics.
+ def int_ppc_altivec_vstribr : GCCBuiltin<"__builtin_altivec_vstribr">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vstribl : GCCBuiltin<"__builtin_altivec_vstribl">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vstrihr : GCCBuiltin<"__builtin_altivec_vstrihr">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vstrihl : GCCBuiltin<"__builtin_altivec_vstrihl">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ // Predicate Intrinsics: The first operand specifies interpretation of CR6.
+ def int_ppc_altivec_vstribr_p : GCCBuiltin<"__builtin_altivec_vstribr_p">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v16i8_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vstribl_p : GCCBuiltin<"__builtin_altivec_vstribl_p">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v16i8_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vstrihr_p : GCCBuiltin<"__builtin_altivec_vstrihr_p">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v8i16_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vstrihl_p : GCCBuiltin<"__builtin_altivec_vstrihl_p">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v8i16_ty], [IntrNoMem]>;
+
// P10 Vector Centrifuge Builtin.
def int_ppc_altivec_vcfuged : GCCBuiltin<"__builtin_altivec_vcfuged">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
@@ -605,27 +605,27 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
// P10 Vector Insert.
def int_ppc_altivec_vinsblx : GCCBuiltin<"__builtin_altivec_vinsblx">,
Intrinsic<[llvm_v16i8_ty],
- [llvm_v16i8_ty, llvm_i32_ty, llvm_i32_ty],
+ [llvm_v16i8_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinsbrx : GCCBuiltin<"__builtin_altivec_vinsbrx">,
Intrinsic<[llvm_v16i8_ty],
- [llvm_v16i8_ty, llvm_i32_ty, llvm_i32_ty],
+ [llvm_v16i8_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinshlx : GCCBuiltin<"__builtin_altivec_vinshlx">,
Intrinsic<[llvm_v8i16_ty],
- [llvm_v8i16_ty, llvm_i32_ty, llvm_i32_ty],
+ [llvm_v8i16_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinshrx : GCCBuiltin<"__builtin_altivec_vinshrx">,
Intrinsic<[llvm_v8i16_ty],
- [llvm_v8i16_ty, llvm_i32_ty, llvm_i32_ty],
+ [llvm_v8i16_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinswlx : GCCBuiltin<"__builtin_altivec_vinswlx">,
Intrinsic<[llvm_v4i32_ty],
- [llvm_v4i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [llvm_v4i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinswrx : GCCBuiltin<"__builtin_altivec_vinswrx">,
Intrinsic<[llvm_v4i32_ty],
- [llvm_v4i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [llvm_v4i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinsdlx : GCCBuiltin<"__builtin_altivec_vinsdlx">,
Intrinsic<[llvm_v2i64_ty],
@@ -637,70 +637,70 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
[IntrNoMem]>;
def int_ppc_altivec_vinsbvlx : GCCBuiltin<"__builtin_altivec_vinsbvlx">,
Intrinsic<[llvm_v16i8_ty],
- [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty],
+ [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinsbvrx : GCCBuiltin<"__builtin_altivec_vinsbvrx">,
Intrinsic<[llvm_v16i8_ty],
- [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty],
+ [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinshvlx : GCCBuiltin<"__builtin_altivec_vinshvlx">,
Intrinsic<[llvm_v8i16_ty],
- [llvm_v8i16_ty, llvm_i32_ty, llvm_v8i16_ty],
+ [llvm_v8i16_ty, llvm_i32_ty, llvm_v8i16_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinshvrx : GCCBuiltin<"__builtin_altivec_vinshvrx">,
Intrinsic<[llvm_v8i16_ty],
- [llvm_v8i16_ty, llvm_i32_ty, llvm_v8i16_ty],
+ [llvm_v8i16_ty, llvm_i32_ty, llvm_v8i16_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinswvlx : GCCBuiltin<"__builtin_altivec_vinswvlx">,
Intrinsic<[llvm_v4i32_ty],
- [llvm_v4i32_ty, llvm_i32_ty, llvm_v4i32_ty],
+ [llvm_v4i32_ty, llvm_i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
def int_ppc_altivec_vinswvrx : GCCBuiltin<"__builtin_altivec_vinswvrx">,
Intrinsic<[llvm_v4i32_ty],
- [llvm_v4i32_ty, llvm_i32_ty, llvm_v4i32_ty],
+ [llvm_v4i32_ty, llvm_i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
// P10 Vector Insert with immediate.
def int_ppc_altivec_vinsw :
Intrinsic<[llvm_v4i32_ty],
- [llvm_v4i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [llvm_v4i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_ppc_altivec_vinsd :
Intrinsic<[llvm_v2i64_ty],
[llvm_v2i64_ty, llvm_i64_ty, llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<2>>]>;
- // P10 Vector Extract.
- def int_ppc_altivec_vextdubvlx : GCCBuiltin<"__builtin_altivec_vextdubvlx">,
- Intrinsic<[llvm_v2i64_ty],
- [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
- [IntrNoMem]>;
- def int_ppc_altivec_vextdubvrx : GCCBuiltin<"__builtin_altivec_vextdubvrx">,
- Intrinsic<[llvm_v2i64_ty],
- [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
- [IntrNoMem]>;
- def int_ppc_altivec_vextduhvlx : GCCBuiltin<"__builtin_altivec_vextduhvlx">,
- Intrinsic<[llvm_v2i64_ty],
- [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty],
- [IntrNoMem]>;
- def int_ppc_altivec_vextduhvrx : GCCBuiltin<"__builtin_altivec_vextduhvrx">,
- Intrinsic<[llvm_v2i64_ty],
- [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty],
- [IntrNoMem]>;
- def int_ppc_altivec_vextduwvlx : GCCBuiltin<"__builtin_altivec_vextduwvlx">,
- Intrinsic<[llvm_v2i64_ty],
- [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty],
- [IntrNoMem]>;
- def int_ppc_altivec_vextduwvrx : GCCBuiltin<"__builtin_altivec_vextduwvrx">,
- Intrinsic<[llvm_v2i64_ty],
- [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty],
- [IntrNoMem]>;
- def int_ppc_altivec_vextddvlx : GCCBuiltin<"__builtin_altivec_vextddvlx">,
- Intrinsic<[llvm_v2i64_ty],
- [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
- [IntrNoMem]>;
- def int_ppc_altivec_vextddvrx : GCCBuiltin<"__builtin_altivec_vextddvrx">,
- Intrinsic<[llvm_v2i64_ty],
- [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
- [IntrNoMem]>;
+ // P10 Vector Extract.
+ def int_ppc_altivec_vextdubvlx : GCCBuiltin<"__builtin_altivec_vextdubvlx">,
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vextdubvrx : GCCBuiltin<"__builtin_altivec_vextdubvrx">,
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vextduhvlx : GCCBuiltin<"__builtin_altivec_vextduhvlx">,
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vextduhvrx : GCCBuiltin<"__builtin_altivec_vextduhvrx">,
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vextduwvlx : GCCBuiltin<"__builtin_altivec_vextduwvlx">,
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vextduwvrx : GCCBuiltin<"__builtin_altivec_vextduwvrx">,
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vextddvlx : GCCBuiltin<"__builtin_altivec_vextddvlx">,
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vextddvrx : GCCBuiltin<"__builtin_altivec_vextddvrx">,
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
+ [IntrNoMem]>;
}
// Vector average.
@@ -757,12 +757,12 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
// Saturating multiply-adds.
def int_ppc_altivec_vmhaddshs : GCCBuiltin<"__builtin_altivec_vmhaddshs">,
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
- llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem, IntrHasSideEffects]>;
+ llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem, IntrHasSideEffects]>;
def int_ppc_altivec_vmhraddshs : GCCBuiltin<"__builtin_altivec_vmhraddshs">,
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
- llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem, IntrHasSideEffects]>;
+ llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem, IntrHasSideEffects]>;
def int_ppc_altivec_vmaddfp : GCCBuiltin<"__builtin_altivec_vmaddfp">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
@@ -780,7 +780,7 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
llvm_v4i32_ty], [IntrNoMem]>;
def int_ppc_altivec_vmsumshs : GCCBuiltin<"__builtin_altivec_vmsumshs">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
- llvm_v4i32_ty], [IntrNoMem, IntrHasSideEffects]>;
+ llvm_v4i32_ty], [IntrNoMem, IntrHasSideEffects]>;
def int_ppc_altivec_vmsumubm : GCCBuiltin<"__builtin_altivec_vmsumubm">,
Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_v16i8_ty,
llvm_v4i32_ty], [IntrNoMem]>;
@@ -792,10 +792,10 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
llvm_v1i128_ty], [IntrNoMem]>;
def int_ppc_altivec_vmsumuhs : GCCBuiltin<"__builtin_altivec_vmsumuhs">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
- llvm_v4i32_ty], [IntrNoMem, IntrHasSideEffects]>;
- def int_ppc_altivec_vmsumcud : GCCBuiltin<"__builtin_altivec_vmsumcud">,
- Intrinsic<[llvm_v1i128_ty],
- [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v1i128_ty], [IntrNoMem]>;
+ llvm_v4i32_ty], [IntrNoMem, IntrHasSideEffects]>;
+ def int_ppc_altivec_vmsumcud : GCCBuiltin<"__builtin_altivec_vmsumcud">,
+ Intrinsic<[llvm_v1i128_ty],
+ [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v1i128_ty], [IntrNoMem]>;
// Vector Multiply Instructions.
def int_ppc_altivec_vmulesb : GCCBuiltin<"__builtin_altivec_vmulesb">,
@@ -807,7 +807,7 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
def int_ppc_altivec_vmulesw : GCCBuiltin<"__builtin_altivec_vmulesw">,
Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
- def int_ppc_altivec_vmulesd : PowerPC_Vec_QDD_Intrinsic<"vmulesd">;
+ def int_ppc_altivec_vmulesd : PowerPC_Vec_QDD_Intrinsic<"vmulesd">;
def int_ppc_altivec_vmuleub : GCCBuiltin<"__builtin_altivec_vmuleub">,
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
[IntrNoMem]>;
@@ -817,7 +817,7 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
def int_ppc_altivec_vmuleuw : GCCBuiltin<"__builtin_altivec_vmuleuw">,
Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
- def int_ppc_altivec_vmuleud : PowerPC_Vec_QDD_Intrinsic<"vmuleud">;
+ def int_ppc_altivec_vmuleud : PowerPC_Vec_QDD_Intrinsic<"vmuleud">;
def int_ppc_altivec_vmulosb : GCCBuiltin<"__builtin_altivec_vmulosb">,
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
@@ -828,7 +828,7 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
def int_ppc_altivec_vmulosw : GCCBuiltin<"__builtin_altivec_vmulosw">,
Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
- def int_ppc_altivec_vmulosd : PowerPC_Vec_QDD_Intrinsic<"vmulosd">;
+ def int_ppc_altivec_vmulosd : PowerPC_Vec_QDD_Intrinsic<"vmulosd">;
def int_ppc_altivec_vmuloub : GCCBuiltin<"__builtin_altivec_vmuloub">,
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
[IntrNoMem]>;
@@ -838,39 +838,39 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
def int_ppc_altivec_vmulouw : GCCBuiltin<"__builtin_altivec_vmulouw">,
Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
- def int_ppc_altivec_vmuloud : PowerPC_Vec_QDD_Intrinsic<"vmuloud">;
+ def int_ppc_altivec_vmuloud : PowerPC_Vec_QDD_Intrinsic<"vmuloud">;
// Vector Sum Instructions.
def int_ppc_altivec_vsumsws : GCCBuiltin<"__builtin_altivec_vsumsws">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem, IntrHasSideEffects]>;
+ [IntrNoMem, IntrHasSideEffects]>;
def int_ppc_altivec_vsum2sws : GCCBuiltin<"__builtin_altivec_vsum2sws">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem, IntrHasSideEffects]>;
+ [IntrNoMem, IntrHasSideEffects]>;
def int_ppc_altivec_vsum4sbs : GCCBuiltin<"__builtin_altivec_vsum4sbs">,
Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_v4i32_ty],
- [IntrNoMem, IntrHasSideEffects]>;
+ [IntrNoMem, IntrHasSideEffects]>;
def int_ppc_altivec_vsum4shs : GCCBuiltin<"__builtin_altivec_vsum4shs">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v4i32_ty],
- [IntrNoMem, IntrHasSideEffects]>;
+ [IntrNoMem, IntrHasSideEffects]>;
def int_ppc_altivec_vsum4ubs : GCCBuiltin<"__builtin_altivec_vsum4ubs">,
Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_v4i32_ty],
- [IntrNoMem, IntrHasSideEffects]>;
-
- // Vector Sign Extension Instructions
- def int_ppc_altivec_vextsb2w : GCCBuiltin<"__builtin_altivec_vextsb2w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty], [IntrNoMem]>;
- def int_ppc_altivec_vextsb2d : GCCBuiltin<"__builtin_altivec_vextsb2d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v16i8_ty], [IntrNoMem]>;
- def int_ppc_altivec_vextsh2w : GCCBuiltin<"__builtin_altivec_vextsh2w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
- def int_ppc_altivec_vextsh2d : GCCBuiltin<"__builtin_altivec_vextsh2d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v8i16_ty], [IntrNoMem]>;
- def int_ppc_altivec_vextsw2d : GCCBuiltin<"__builtin_altivec_vextsw2d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem]>;
- def int_ppc_altivec_vextsd2q : GCCBuiltin<"__builtin_altivec_vextsd2q">,
- Intrinsic<[llvm_v1i128_ty], [llvm_v2i64_ty], [IntrNoMem]>;
-
+ [IntrNoMem, IntrHasSideEffects]>;
+
+ // Vector Sign Extension Instructions
+ def int_ppc_altivec_vextsb2w : GCCBuiltin<"__builtin_altivec_vextsb2w">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vextsb2d : GCCBuiltin<"__builtin_altivec_vextsb2d">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vextsh2w : GCCBuiltin<"__builtin_altivec_vextsh2w">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vextsh2d : GCCBuiltin<"__builtin_altivec_vextsh2d">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vextsw2d : GCCBuiltin<"__builtin_altivec_vextsw2d">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vextsd2q : GCCBuiltin<"__builtin_altivec_vextsd2q">,
+ Intrinsic<[llvm_v1i128_ty], [llvm_v2i64_ty], [IntrNoMem]>;
+
// Other multiplies.
def int_ppc_altivec_vmladduhm : GCCBuiltin<"__builtin_altivec_vmladduhm">,
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
@@ -882,34 +882,34 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
[IntrNoMem]>;
def int_ppc_altivec_vpkshss : GCCBuiltin<"__builtin_altivec_vpkshss">,
Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem, IntrHasSideEffects]>;
+ [IntrNoMem, IntrHasSideEffects]>;
def int_ppc_altivec_vpkshus : GCCBuiltin<"__builtin_altivec_vpkshus">,
Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem, IntrHasSideEffects]>;
+ [IntrNoMem, IntrHasSideEffects]>;
def int_ppc_altivec_vpkswss : GCCBuiltin<"__builtin_altivec_vpkswss">,
Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem, IntrHasSideEffects]>;
+ [IntrNoMem, IntrHasSideEffects]>;
def int_ppc_altivec_vpkswus : GCCBuiltin<"__builtin_altivec_vpkswus">,
Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem, IntrHasSideEffects]>;
+ [IntrNoMem, IntrHasSideEffects]>;
def int_ppc_altivec_vpksdss : GCCBuiltin<"__builtin_altivec_vpksdss">,
Intrinsic<[llvm_v4i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem, IntrHasSideEffects]>;
+ [IntrNoMem, IntrHasSideEffects]>;
def int_ppc_altivec_vpksdus : GCCBuiltin<"__builtin_altivec_vpksdus">,
Intrinsic<[llvm_v4i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem, IntrHasSideEffects]>;
+ [IntrNoMem, IntrHasSideEffects]>;
// vpkuhum is lowered to a shuffle.
def int_ppc_altivec_vpkuhus : GCCBuiltin<"__builtin_altivec_vpkuhus">,
Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
- [IntrNoMem, IntrHasSideEffects]>;
+ [IntrNoMem, IntrHasSideEffects]>;
// vpkuwum is lowered to a shuffle.
def int_ppc_altivec_vpkuwus : GCCBuiltin<"__builtin_altivec_vpkuwus">,
Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
- [IntrNoMem, IntrHasSideEffects]>;
+ [IntrNoMem, IntrHasSideEffects]>;
// vpkudum is lowered to a shuffle.
def int_ppc_altivec_vpkudus : GCCBuiltin<"__builtin_altivec_vpkudus">,
Intrinsic<[llvm_v4i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem, IntrHasSideEffects]>;
+ [IntrNoMem, IntrHasSideEffects]>;
// Unpacks.
def int_ppc_altivec_vupkhpx : GCCBuiltin<"__builtin_altivec_vupkhpx">,
@@ -1091,29 +1091,29 @@ def int_ppc_altivec_vrldmi :
[llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
[IntrNoMem]>;
-def int_ppc_altivec_vrlqnm :
- PowerPC_Vec_Intrinsic<"vrlqnm", [llvm_v1i128_ty],
- [llvm_v1i128_ty, llvm_v1i128_ty],
- [IntrNoMem]>;
-def int_ppc_altivec_vrlqmi :
- PowerPC_Vec_Intrinsic<"vrlqmi", [llvm_v1i128_ty],
- [llvm_v1i128_ty, llvm_v1i128_ty, llvm_v1i128_ty],
- [IntrNoMem]>;
-
-// Vector Divide Extended Intrinsics.
-def int_ppc_altivec_vdivesw : PowerPC_Vec_WWW_Intrinsic<"vdivesw">;
-def int_ppc_altivec_vdiveuw : PowerPC_Vec_WWW_Intrinsic<"vdiveuw">;
-def int_ppc_altivec_vdivesd : PowerPC_Vec_DDD_Intrinsic<"vdivesd">;
-def int_ppc_altivec_vdiveud : PowerPC_Vec_DDD_Intrinsic<"vdiveud">;
-def int_ppc_altivec_vdivesq : PowerPC_Vec_QQQ_Intrinsic<"vdivesq">;
-def int_ppc_altivec_vdiveuq : PowerPC_Vec_QQQ_Intrinsic<"vdiveuq">;
-
-// Vector Multiply High Intrinsics.
-def int_ppc_altivec_vmulhsw : PowerPC_Vec_WWW_Intrinsic<"vmulhsw">;
-def int_ppc_altivec_vmulhuw : PowerPC_Vec_WWW_Intrinsic<"vmulhuw">;
-def int_ppc_altivec_vmulhsd : PowerPC_Vec_DDD_Intrinsic<"vmulhsd">;
-def int_ppc_altivec_vmulhud : PowerPC_Vec_DDD_Intrinsic<"vmulhud">;
-
+def int_ppc_altivec_vrlqnm :
+ PowerPC_Vec_Intrinsic<"vrlqnm", [llvm_v1i128_ty],
+ [llvm_v1i128_ty, llvm_v1i128_ty],
+ [IntrNoMem]>;
+def int_ppc_altivec_vrlqmi :
+ PowerPC_Vec_Intrinsic<"vrlqmi", [llvm_v1i128_ty],
+ [llvm_v1i128_ty, llvm_v1i128_ty, llvm_v1i128_ty],
+ [IntrNoMem]>;
+
+// Vector Divide Extended Intrinsics.
+def int_ppc_altivec_vdivesw : PowerPC_Vec_WWW_Intrinsic<"vdivesw">;
+def int_ppc_altivec_vdiveuw : PowerPC_Vec_WWW_Intrinsic<"vdiveuw">;
+def int_ppc_altivec_vdivesd : PowerPC_Vec_DDD_Intrinsic<"vdivesd">;
+def int_ppc_altivec_vdiveud : PowerPC_Vec_DDD_Intrinsic<"vdiveud">;
+def int_ppc_altivec_vdivesq : PowerPC_Vec_QQQ_Intrinsic<"vdivesq">;
+def int_ppc_altivec_vdiveuq : PowerPC_Vec_QQQ_Intrinsic<"vdiveuq">;
+
+// Vector Multiply High Intrinsics.
+def int_ppc_altivec_vmulhsw : PowerPC_Vec_WWW_Intrinsic<"vmulhsw">;
+def int_ppc_altivec_vmulhuw : PowerPC_Vec_WWW_Intrinsic<"vmulhuw">;
+def int_ppc_altivec_vmulhsd : PowerPC_Vec_DDD_Intrinsic<"vmulhsd">;
+def int_ppc_altivec_vmulhud : PowerPC_Vec_DDD_Intrinsic<"vmulhud">;
+
//===----------------------------------------------------------------------===//
// PowerPC VSX Intrinsic Definitions.
@@ -1134,8 +1134,8 @@ def int_ppc_vsx_lxvl :
def int_ppc_vsx_lxvll :
Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty, llvm_i64_ty], [IntrReadMem,
IntrArgMemOnly]>;
-def int_ppc_vsx_lxvp :
- Intrinsic<[llvm_v256i1_ty], [llvm_ptr_ty], [IntrReadMem, IntrArgMemOnly]>;
+def int_ppc_vsx_lxvp :
+ Intrinsic<[llvm_v256i1_ty], [llvm_ptr_ty], [IntrReadMem, IntrArgMemOnly]>;
// Vector store.
def int_ppc_vsx_stxvw4x : Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty],
@@ -1146,15 +1146,15 @@ def int_ppc_vsx_stxvw4x_be : Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty],
[IntrWriteMem, IntrArgMemOnly]>;
def int_ppc_vsx_stxvd2x_be : Intrinsic<[], [llvm_v2f64_ty, llvm_ptr_ty],
[IntrWriteMem, IntrArgMemOnly]>;
-def int_ppc_vsx_stxvl :
- Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty, llvm_i64_ty],
- [IntrWriteMem, IntrArgMemOnly]>;
-def int_ppc_vsx_stxvll :
- Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty, llvm_i64_ty],
- [IntrWriteMem, IntrArgMemOnly]>;
-def int_ppc_vsx_stxvp :
- Intrinsic<[], [llvm_v256i1_ty, llvm_ptr_ty], [IntrWriteMem,
- IntrArgMemOnly]>;
+def int_ppc_vsx_stxvl :
+ Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty, llvm_i64_ty],
+ [IntrWriteMem, IntrArgMemOnly]>;
+def int_ppc_vsx_stxvll :
+ Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty, llvm_i64_ty],
+ [IntrWriteMem, IntrArgMemOnly]>;
+def int_ppc_vsx_stxvp :
+ Intrinsic<[], [llvm_v256i1_ty, llvm_ptr_ty], [IntrWriteMem,
+ IntrArgMemOnly]>;
// Vector and scalar maximum.
def int_ppc_vsx_xvmaxdp : PowerPC_VSX_Vec_DDD_Intrinsic<"xvmaxdp">;
def int_ppc_vsx_xvmaxsp : PowerPC_VSX_Vec_FFF_Intrinsic<"xvmaxsp">;
@@ -1281,12 +1281,12 @@ def int_ppc_vsx_xvtstdcsp :
def int_ppc_vsx_xvcvhpsp :
PowerPC_VSX_Intrinsic<"xvcvhpsp", [llvm_v4f32_ty],
[llvm_v8i16_ty],[IntrNoMem]>;
-def int_ppc_vsx_xvcvspbf16 :
- PowerPC_VSX_Intrinsic<"xvcvspbf16", [llvm_v16i8_ty],
- [llvm_v16i8_ty], [IntrNoMem]>;
-def int_ppc_vsx_xvcvbf16spn :
- PowerPC_VSX_Intrinsic<"xvcvbf16spn", [llvm_v16i8_ty],
- [llvm_v16i8_ty], [IntrNoMem]>;
+def int_ppc_vsx_xvcvspbf16 :
+ PowerPC_VSX_Intrinsic<"xvcvspbf16", [llvm_v16i8_ty],
+ [llvm_v16i8_ty], [IntrNoMem]>;
+def int_ppc_vsx_xvcvbf16spn :
+ PowerPC_VSX_Intrinsic<"xvcvbf16spn", [llvm_v16i8_ty],
+ [llvm_v16i8_ty], [IntrNoMem]>;
def int_ppc_vsx_xxextractuw :
PowerPC_VSX_Intrinsic<"xxextractuw",[llvm_v2i64_ty],
[llvm_v2i64_ty,llvm_i32_ty], [IntrNoMem]>;
@@ -1296,17 +1296,17 @@ def int_ppc_vsx_xxinsertw :
[IntrNoMem]>;
def int_ppc_vsx_xvtlsbb :
PowerPC_VSX_Intrinsic<"xvtlsbb", [llvm_i32_ty],
- [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
-def int_ppc_vsx_xvtdivdp :
- PowerPC_VSX_Intrinsic<"xvtdivdp", [llvm_i32_ty],
- [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
-def int_ppc_vsx_xvtdivsp :
- PowerPC_VSX_Intrinsic<"xvtdivsp", [llvm_i32_ty],
- [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
-def int_ppc_vsx_xvtsqrtdp :
- PowerPC_VSX_Intrinsic<"xvtsqrtdp", [llvm_i32_ty], [llvm_v2f64_ty], [IntrNoMem]>;
-def int_ppc_vsx_xvtsqrtsp :
- PowerPC_VSX_Intrinsic<"xvtsqrtsp", [llvm_i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_ppc_vsx_xvtdivdp :
+ PowerPC_VSX_Intrinsic<"xvtdivdp", [llvm_i32_ty],
+ [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+def int_ppc_vsx_xvtdivsp :
+ PowerPC_VSX_Intrinsic<"xvtdivsp", [llvm_i32_ty],
+ [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_ppc_vsx_xvtsqrtdp :
+ PowerPC_VSX_Intrinsic<"xvtsqrtdp", [llvm_i32_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+def int_ppc_vsx_xvtsqrtsp :
+ PowerPC_VSX_Intrinsic<"xvtsqrtsp", [llvm_i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
def int_ppc_vsx_xxeval :
PowerPC_VSX_Intrinsic<"xxeval", [llvm_v2i64_ty],
[llvm_v2i64_ty, llvm_v2i64_ty,
@@ -1410,88 +1410,88 @@ def int_ppc_cfence : Intrinsic<[], [llvm_anyint_ty], []>;
// PowerPC set FPSCR Intrinsic Definitions.
def int_ppc_setrnd : GCCBuiltin<"__builtin_setrnd">,
Intrinsic<[llvm_double_ty], [llvm_i32_ty], []>;
-}
-
-let TargetPrefix = "ppc" in {
- def int_ppc_vsx_assemble_pair :
- Intrinsic<[llvm_v256i1_ty],
- [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
-
- def int_ppc_vsx_disassemble_pair :
- Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty],
- [llvm_v256i1_ty], [IntrNoMem]>;
-
- def int_ppc_mma_assemble_acc :
- Intrinsic<[llvm_v512i1_ty],
- [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
- [IntrNoMem]>;
-
- def int_ppc_mma_disassemble_acc :
- Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
- [llvm_v512i1_ty], [IntrNoMem]>;
-
- def int_ppc_mma_xxmtacc :
- Intrinsic<[llvm_v512i1_ty], [llvm_v512i1_ty], [IntrNoMem]>;
-
- def int_ppc_mma_xxmfacc :
- Intrinsic<[llvm_v512i1_ty], [llvm_v512i1_ty], [IntrNoMem]>;
-
- def int_ppc_mma_xxsetaccz :
- Intrinsic<[llvm_v512i1_ty], [], [IntrNoMem]>;
-
- // MMA Reduced-Precision: Outer Product Intrinsic Definitions.
- defm int_ppc_mma_xvi4ger8 :
- PowerPC_MMA_ACC_PP_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty]>;
- defm int_ppc_mma_pmxvi4ger8 :
- PowerPC_MMA_ACC_PP_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty]>;
-
- defm int_ppc_mma_xvi8ger4 :
- PowerPC_MMA_ACC_PP_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty]>;
- defm int_ppc_mma_pmxvi8ger4 :
- PowerPC_MMA_ACC_PP_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty]>;
-
- defm int_ppc_mma_xvi16ger2s :
- PowerPC_MMA_ACC_PP_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty]>;
- defm int_ppc_mma_pmxvi16ger2s :
- PowerPC_MMA_ACC_PP_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty]>;
-
- defm int_ppc_mma_xvf16ger2 :
- PowerPC_MMA_ACC_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty]>;
- defm int_ppc_mma_pmxvf16ger2 :
- PowerPC_MMA_ACC_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty]>;
- defm int_ppc_mma_xvf32ger :
- PowerPC_MMA_ACC_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty]>;
- defm int_ppc_mma_pmxvf32ger :
- PowerPC_MMA_ACC_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty,
- llvm_i32_ty]>;
- defm int_ppc_mma_xvf64ger :
- PowerPC_MMA_ACC_Intrinsic<[llvm_v256i1_ty, llvm_v16i8_ty]>;
- defm int_ppc_mma_pmxvf64ger :
- PowerPC_MMA_ACC_Intrinsic<[llvm_v256i1_ty, llvm_v16i8_ty, llvm_i32_ty,
- llvm_i32_ty]>;
-
- // MMA Reduced-Precision: bfloat16 Outer Product Intrinsic Definitions.
- defm int_ppc_mma_xvbf16ger2 :
- PowerPC_MMA_ACC_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty]>;
- defm int_ppc_mma_pmxvbf16ger2 :
- PowerPC_MMA_ACC_Intrinsic<
- [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty]>;
-
- // MMA Reduced-Precision: Missing Integer-based Outer Product Operations.
- defm int_ppc_mma_xvi16ger2 :
- PowerPC_MMA_ACC_PP_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty]>;
- defm int_ppc_mma_pmxvi16ger2 :
- PowerPC_MMA_ACC_PP_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty]>;
- def int_ppc_mma_xvi8ger4spp :
- Intrinsic<[llvm_v512i1_ty],
- [llvm_v512i1_ty, llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
- def int_ppc_mma_pmxvi8ger4spp :
- Intrinsic<[llvm_v512i1_ty],
- [llvm_v512i1_ty, llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+}
+
+let TargetPrefix = "ppc" in {
+ def int_ppc_vsx_assemble_pair :
+ Intrinsic<[llvm_v256i1_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+
+ def int_ppc_vsx_disassemble_pair :
+ Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty],
+ [llvm_v256i1_ty], [IntrNoMem]>;
+
+ def int_ppc_mma_assemble_acc :
+ Intrinsic<[llvm_v512i1_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+
+ def int_ppc_mma_disassemble_acc :
+ Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+ [llvm_v512i1_ty], [IntrNoMem]>;
+
+ def int_ppc_mma_xxmtacc :
+ Intrinsic<[llvm_v512i1_ty], [llvm_v512i1_ty], [IntrNoMem]>;
+
+ def int_ppc_mma_xxmfacc :
+ Intrinsic<[llvm_v512i1_ty], [llvm_v512i1_ty], [IntrNoMem]>;
+
+ def int_ppc_mma_xxsetaccz :
+ Intrinsic<[llvm_v512i1_ty], [], [IntrNoMem]>;
+
+ // MMA Reduced-Precision: Outer Product Intrinsic Definitions.
+ defm int_ppc_mma_xvi4ger8 :
+ PowerPC_MMA_ACC_PP_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty]>;
+ defm int_ppc_mma_pmxvi4ger8 :
+ PowerPC_MMA_ACC_PP_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty]>;
+
+ defm int_ppc_mma_xvi8ger4 :
+ PowerPC_MMA_ACC_PP_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty]>;
+ defm int_ppc_mma_pmxvi8ger4 :
+ PowerPC_MMA_ACC_PP_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty]>;
+
+ defm int_ppc_mma_xvi16ger2s :
+ PowerPC_MMA_ACC_PP_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty]>;
+ defm int_ppc_mma_pmxvi16ger2s :
+ PowerPC_MMA_ACC_PP_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty]>;
+
+ defm int_ppc_mma_xvf16ger2 :
+ PowerPC_MMA_ACC_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty]>;
+ defm int_ppc_mma_pmxvf16ger2 :
+ PowerPC_MMA_ACC_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty]>;
+ defm int_ppc_mma_xvf32ger :
+ PowerPC_MMA_ACC_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty]>;
+ defm int_ppc_mma_pmxvf32ger :
+ PowerPC_MMA_ACC_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty,
+ llvm_i32_ty]>;
+ defm int_ppc_mma_xvf64ger :
+ PowerPC_MMA_ACC_Intrinsic<[llvm_v256i1_ty, llvm_v16i8_ty]>;
+ defm int_ppc_mma_pmxvf64ger :
+ PowerPC_MMA_ACC_Intrinsic<[llvm_v256i1_ty, llvm_v16i8_ty, llvm_i32_ty,
+ llvm_i32_ty]>;
+
+ // MMA Reduced-Precision: bfloat16 Outer Product Intrinsic Definitions.
+ defm int_ppc_mma_xvbf16ger2 :
+ PowerPC_MMA_ACC_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty]>;
+ defm int_ppc_mma_pmxvbf16ger2 :
+ PowerPC_MMA_ACC_Intrinsic<
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty]>;
+
+ // MMA Reduced-Precision: Missing Integer-based Outer Product Operations.
+ defm int_ppc_mma_xvi16ger2 :
+ PowerPC_MMA_ACC_PP_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty]>;
+ defm int_ppc_mma_pmxvi16ger2 :
+ PowerPC_MMA_ACC_PP_Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty]>;
+ def int_ppc_mma_xvi8ger4spp :
+ Intrinsic<[llvm_v512i1_ty],
+ [llvm_v512i1_ty, llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+ def int_ppc_mma_pmxvi8ger4spp :
+ Intrinsic<[llvm_v512i1_ty],
+ [llvm_v512i1_ty, llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
}
diff --git a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsRISCV.td b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsRISCV.td
index 0d499e2666..c4056895f6 100644
--- a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsRISCV.td
+++ b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsRISCV.td
@@ -66,1027 +66,1027 @@ let TargetPrefix = "riscv" in {
defm int_riscv_masked_cmpxchg : MaskedAtomicRMWFiveArgIntrinsics;
} // TargetPrefix = "riscv"
-
-//===----------------------------------------------------------------------===//
-// Vectors
-
-class RISCVVIntrinsic {
- // These intrinsics may accept illegal integer values in their llvm_any_ty
- // operand, so they have to be extended. If set to zero then the intrinsic
- // does not have any operand that must be extended.
- Intrinsic IntrinsicID = !cast<Intrinsic>(NAME);
- bits<4> ExtendOperand = 0;
-}
-
-let TargetPrefix = "riscv" in {
- // We use anyint here but we only support XLen.
- def int_riscv_vsetvli : Intrinsic<[llvm_anyint_ty],
- /* AVL */ [LLVMMatchType<0>,
- /* VSEW */ LLVMMatchType<0>,
- /* VLMUL */ LLVMMatchType<0>],
- [IntrNoMem, IntrHasSideEffects,
- ImmArg<ArgIndex<1>>,
- ImmArg<ArgIndex<2>>]>;
- def int_riscv_vsetvlimax : Intrinsic<[llvm_anyint_ty],
- /* VSEW */ [LLVMMatchType<0>,
- /* VLMUL */ LLVMMatchType<0>],
- [IntrNoMem, IntrHasSideEffects,
- ImmArg<ArgIndex<0>>,
- ImmArg<ArgIndex<1>>]>;
-
- // For unit stride load
- // Input: (pointer, vl)
- class RISCVUSLoad
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMPointerType<LLVMMatchType<0>>,
- llvm_anyint_ty],
- [NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic;
- // For unit stride fault-only-first load
- // Input: (pointer, vl)
- // Output: (data, vl)
- // NOTE: We model this with default memory properties since we model writing
- // VL as a side effect. IntrReadMem, IntrHasSideEffects does not work.
- class RISCVUSLoadFF
- : Intrinsic<[llvm_anyvector_ty, llvm_anyint_ty],
- [LLVMPointerType<LLVMMatchType<0>>, LLVMMatchType<1>],
- [NoCapture<ArgIndex<0>>]>,
- RISCVVIntrinsic;
- // For unit stride load with mask
- // Input: (maskedoff, pointer, mask, vl)
- class RISCVUSLoadMask
- : Intrinsic<[llvm_anyvector_ty ],
- [LLVMMatchType<0>,
- LLVMPointerType<LLVMMatchType<0>>,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- llvm_anyint_ty],
- [NoCapture<ArgIndex<1>>, IntrReadMem]>, RISCVVIntrinsic;
- // For unit stride fault-only-first load with mask
- // Input: (maskedoff, pointer, mask, vl)
- // Output: (data, vl)
- // NOTE: We model this with default memory properties since we model writing
- // VL as a side effect. IntrReadMem, IntrHasSideEffects does not work.
- class RISCVUSLoadFFMask
- : Intrinsic<[llvm_anyvector_ty, llvm_anyint_ty],
- [LLVMMatchType<0>,
- LLVMPointerType<LLVMMatchType<0>>,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- LLVMMatchType<1>],
- [NoCapture<ArgIndex<1>>]>, RISCVVIntrinsic;
- // For strided load
- // Input: (pointer, stride, vl)
- class RISCVSLoad
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMPointerType<LLVMMatchType<0>>,
- llvm_anyint_ty, LLVMMatchType<1>],
- [NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic;
- // For strided load with mask
- // Input: (maskedoff, pointer, stride, mask, vl)
- class RISCVSLoadMask
- : Intrinsic<[llvm_anyvector_ty ],
- [LLVMMatchType<0>,
- LLVMPointerType<LLVMMatchType<0>>, llvm_anyint_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<1>],
- [NoCapture<ArgIndex<1>>, IntrReadMem]>, RISCVVIntrinsic;
- // For indexed load
- // Input: (pointer, index, vl)
- class RISCVILoad
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMPointerType<LLVMMatchType<0>>,
- llvm_anyvector_ty, llvm_anyint_ty],
- [NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic;
- // For indexed load with mask
- // Input: (maskedoff, pointer, index, mask, vl)
- class RISCVILoadMask
- : Intrinsic<[llvm_anyvector_ty ],
- [LLVMMatchType<0>,
- LLVMPointerType<LLVMMatchType<0>>, llvm_anyvector_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
- [NoCapture<ArgIndex<1>>, IntrReadMem]>, RISCVVIntrinsic;
- // For unit stride store
- // Input: (vector_in, pointer, vl)
- class RISCVUSStore
- : Intrinsic<[],
- [llvm_anyvector_ty,
- LLVMPointerType<LLVMMatchType<0>>,
- llvm_anyint_ty],
- [NoCapture<ArgIndex<1>>, IntrWriteMem]>, RISCVVIntrinsic;
- // For unit stride store with mask
- // Input: (vector_in, pointer, mask, vl)
- class RISCVUSStoreMask
- : Intrinsic<[],
- [llvm_anyvector_ty,
- LLVMPointerType<LLVMMatchType<0>>,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- llvm_anyint_ty],
- [NoCapture<ArgIndex<1>>, IntrWriteMem]>, RISCVVIntrinsic;
- // For strided store
- // Input: (vector_in, pointer, stride, vl)
- class RISCVSStore
- : Intrinsic<[],
- [llvm_anyvector_ty,
- LLVMPointerType<LLVMMatchType<0>>,
- llvm_anyint_ty, LLVMMatchType<1>],
- [NoCapture<ArgIndex<1>>, IntrWriteMem]>, RISCVVIntrinsic;
- // For stride store with mask
- // Input: (vector_in, pointer, stirde, mask, vl)
- class RISCVSStoreMask
- : Intrinsic<[],
- [llvm_anyvector_ty,
- LLVMPointerType<LLVMMatchType<0>>, llvm_anyint_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<1>],
- [NoCapture<ArgIndex<1>>, IntrWriteMem]>, RISCVVIntrinsic;
- // For indexed store
- // Input: (vector_in, pointer, index, vl)
- class RISCVIStore
- : Intrinsic<[],
- [llvm_anyvector_ty,
- LLVMPointerType<LLVMMatchType<0>>,
- llvm_anyint_ty, llvm_anyint_ty],
- [NoCapture<ArgIndex<1>>, IntrWriteMem]>, RISCVVIntrinsic;
- // For indexed store with mask
- // Input: (vector_in, pointer, index, mask, vl)
- class RISCVIStoreMask
- : Intrinsic<[],
- [llvm_anyvector_ty,
- LLVMPointerType<LLVMMatchType<0>>, llvm_anyvector_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
- [NoCapture<ArgIndex<1>>, IntrWriteMem]>, RISCVVIntrinsic;
- // For destination vector type is the same as source vector.
- // Input: (vector_in, vl)
- class RISCVUnaryAANoMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- // For destination vector type is the same as first source vector (with mask).
- // Input: (vector_in, mask, vl)
- class RISCVUnaryAAMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, LLVMMatchType<0>,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- // For destination vector type is the same as first and second source vector.
- // Input: (vector_in, vector_in, vl)
- class RISCVBinaryAAANoMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- // For destination vector type is the same as first and second source vector.
- // Input: (vector_in, vector_in, vl)
- class RISCVBinaryAAAMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, LLVMMatchType<0>,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- // For destination vector type is the same as first source vector.
- // Input: (vector_in, vector_in/scalar_in, vl)
- class RISCVBinaryAAXNoMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_any_ty, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic {
- let ExtendOperand = 2;
- }
- // For destination vector type is the same as first source vector (with mask).
- // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
- class RISCVBinaryAAXMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, LLVMMatchType<0>, llvm_any_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic {
- let ExtendOperand = 3;
- }
- // For destination vector type is NOT the same as first source vector.
- // Input: (vector_in, vector_in/scalar_in, vl)
- class RISCVBinaryABXNoMask
- : Intrinsic<[llvm_anyvector_ty],
- [llvm_anyvector_ty, llvm_any_ty, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic {
- let ExtendOperand = 2;
- }
- // For destination vector type is NOT the same as first source vector (with mask).
- // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
- class RISCVBinaryABXMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_anyvector_ty, llvm_any_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic {
- let ExtendOperand = 3;
- }
- // For binary operations with V0 as input.
- // Input: (vector_in, vector_in/scalar_in, V0, vl)
- class RISCVBinaryWithV0
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_any_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic {
- let ExtendOperand = 2;
- }
- // For binary operations with mask type output and V0 as input.
- // Output: (mask type output)
- // Input: (vector_in, vector_in/scalar_in, V0, vl)
- class RISCVBinaryMOutWithV0
- :Intrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
- [llvm_anyvector_ty, llvm_any_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic {
- let ExtendOperand = 2;
- }
- // For binary operations with mask type output.
- // Output: (mask type output)
- // Input: (vector_in, vector_in/scalar_in, vl)
- class RISCVBinaryMOut
- : Intrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
- [llvm_anyvector_ty, llvm_any_ty, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic {
- let ExtendOperand = 2;
- }
- // For binary operations with mask type output without mask.
- // Output: (mask type output)
- // Input: (vector_in, vector_in/scalar_in, vl)
- class RISCVCompareNoMask
- : Intrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
- [llvm_anyvector_ty, llvm_any_ty, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic {
- let ExtendOperand = 2;
- }
- // For binary operations with mask type output with mask.
- // Output: (mask type output)
- // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
- class RISCVCompareMask
- : Intrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
- [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- llvm_anyvector_ty, llvm_any_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic {
- let ExtendOperand = 3;
- }
- // For FP classify operations.
- // Output: (bit mask type output)
- // Input: (vector_in, vl)
- class RISCVClassifyNoMask
- : Intrinsic<[LLVMVectorOfBitcastsToInt<0>],
- [llvm_anyvector_ty, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- // For FP classify operations with mask.
- // Output: (bit mask type output)
- // Input: (maskedoff, vector_in, mask, vl)
- class RISCVClassifyMask
- : Intrinsic<[LLVMVectorOfBitcastsToInt<0>],
- [LLVMVectorOfBitcastsToInt<0>, llvm_anyvector_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- // For Saturating binary operations.
- // The destination vector type is the same as first source vector.
- // Input: (vector_in, vector_in/scalar_in, vl)
- class RISCVSaturatingBinaryAAXNoMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_any_ty, llvm_anyint_ty],
- [IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic {
- let ExtendOperand = 2;
- }
- // For Saturating binary operations with mask.
- // The destination vector type is the same as first source vector.
- // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
- class RISCVSaturatingBinaryAAXMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, LLVMMatchType<0>, llvm_any_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
- [IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic {
- let ExtendOperand = 3;
- }
- // For Saturating binary operations.
- // The destination vector type is NOT the same as first source vector.
- // Input: (vector_in, vector_in/scalar_in, vl)
- class RISCVSaturatingBinaryABXNoMask
- : Intrinsic<[llvm_anyvector_ty],
- [llvm_anyvector_ty, llvm_any_ty, llvm_anyint_ty],
- [IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic {
- let ExtendOperand = 2;
- }
- // For Saturating binary operations with mask.
- // The destination vector type is NOT the same as first source vector (with mask).
- // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
- class RISCVSaturatingBinaryABXMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_anyvector_ty, llvm_any_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
- [IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic {
- let ExtendOperand = 3;
- }
- class RISCVTernaryAAAXNoMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyint_ty,
- LLVMMatchType<1>],
- [IntrNoMem]>, RISCVVIntrinsic;
- class RISCVTernaryAAAXMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyint_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<1>],
- [IntrNoMem]>, RISCVVIntrinsic;
- class RISCVTernaryAAXANoMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_any_ty, LLVMMatchType<0>,
- llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic {
- let ExtendOperand = 2;
- }
- class RISCVTernaryAAXAMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_any_ty, LLVMMatchType<0>,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic {
- let ExtendOperand = 2;
- }
- class RISCVTernaryWideNoMask
- : Intrinsic< [llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_any_ty, llvm_anyvector_ty,
- llvm_anyint_ty],
- [IntrNoMem] >, RISCVVIntrinsic {
- let ExtendOperand = 2;
- }
- class RISCVTernaryWideMask
- : Intrinsic< [llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_any_ty, llvm_anyvector_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic {
- let ExtendOperand = 2;
- }
- // For Reduction ternary operations.
- // For destination vector type is the same as first and third source vector.
- // Input: (vector_in, vector_in, vector_in, vl)
- class RISCVReductionNoMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<0>,
- llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- // For Reduction ternary operations with mask.
- // For destination vector type is the same as first and third source vector.
- // The mask type come from second source vector.
- // Input: (maskedoff, vector_in, vector_in, vector_in, mask, vl)
- class RISCVReductionMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<0>,
- LLVMScalarOrSameVectorWidth<1, llvm_i1_ty>, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- // For unary operations with scalar type output without mask
- // Output: (scalar type)
- // Input: (vector_in, vl)
- class RISCVMaskUnarySOutNoMask
- : Intrinsic<[llvm_anyint_ty],
- [llvm_anyvector_ty, LLVMMatchType<0>],
- [IntrNoMem]>, RISCVVIntrinsic;
- // For unary operations with scalar type output with mask
- // Output: (scalar type)
- // Input: (vector_in, mask, vl)
- class RISCVMaskUnarySOutMask
- : Intrinsic<[llvm_anyint_ty],
- [llvm_anyvector_ty, LLVMMatchType<1>, LLVMMatchType<0>],
- [IntrNoMem]>, RISCVVIntrinsic;
- // For destination vector type is NOT the same as source vector.
- // Input: (vector_in, vl)
- class RISCVUnaryABNoMask
- : Intrinsic<[llvm_anyvector_ty],
- [llvm_anyvector_ty, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- // For destination vector type is NOT the same as source vector (with mask).
- // Input: (maskedoff, vector_in, mask, vl)
- class RISCVUnaryABMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_anyvector_ty,
- LLVMScalarOrSameVectorWidth<1, llvm_i1_ty>,
- llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- // For unary operations with the same vector type in/out without mask
- // Output: (vector)
- // Input: (vector_in, vl)
- class RISCVUnaryNoMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- // For mask unary operations with mask type in/out with mask
- // Output: (mask type output)
- // Input: (mask type maskedoff, mask type vector_in, mask, vl)
- class RISCVMaskUnaryMOutMask
- : Intrinsic<[llvm_anyint_ty],
- [LLVMMatchType<0>, LLVMMatchType<0>,
- LLVMMatchType<0>, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- // Output: (vector)
- // Input: (vl)
- class RISCVNullaryIntrinsic
- : Intrinsic<[llvm_anyvector_ty],
- [llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- // For Conversion unary operations.
- // Input: (vector_in, vl)
- class RISCVConversionNoMask
- : Intrinsic<[llvm_anyvector_ty],
- [llvm_anyvector_ty, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- // For Conversion unary operations with mask.
- // Input: (maskedoff, vector_in, mask, vl)
- class RISCVConversionMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_anyvector_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- // For atomic operations without mask
- // Input: (base, index, value, vl)
- class RISCVAMONoMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMPointerType<LLVMMatchType<0>>, llvm_anyvector_ty, LLVMMatchType<0>,
- llvm_anyint_ty],
- [NoCapture<ArgIndex<0>>]>, RISCVVIntrinsic;
- // For atomic operations with mask
- // Input: (base, index, value, mask, vl)
- class RISCVAMOMask
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMPointerType<LLVMMatchType<0>>, llvm_anyvector_ty, LLVMMatchType<0>,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
- [NoCapture<ArgIndex<0>>]>, RISCVVIntrinsic;
-
- // For unit stride segment load
- // Input: (pointer, vl)
- class RISCVUSSegLoad<int nf>
- : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
- !add(nf, -1))),
- [LLVMPointerToElt<0>, llvm_anyint_ty],
- [NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic;
- // For unit stride segment load with mask
- // Input: (maskedoff, pointer, mask, vl)
- class RISCVUSSegLoadMask<int nf>
- : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
- !add(nf, -1))),
- !listconcat(!listsplat(LLVMMatchType<0>, nf),
- [LLVMPointerToElt<0>,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- llvm_anyint_ty]),
- [NoCapture<ArgIndex<nf>>, IntrReadMem]>, RISCVVIntrinsic;
-
- // For unit stride fault-only-first segment load
- // Input: (pointer, vl)
- // Output: (data, vl)
- // NOTE: We model this with default memory properties since we model writing
- // VL as a side effect. IntrReadMem, IntrHasSideEffects does not work.
- class RISCVUSSegLoadFF<int nf>
- : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
- !add(nf, -1)), [llvm_anyint_ty]),
- [LLVMPointerToElt<0>, LLVMMatchType<1>],
- [NoCapture<ArgIndex<0>>]>, RISCVVIntrinsic;
- // For unit stride fault-only-first segment load with mask
- // Input: (maskedoff, pointer, mask, vl)
- // Output: (data, vl)
- // NOTE: We model this with default memory properties since we model writing
- // VL as a side effect. IntrReadMem, IntrHasSideEffects does not work.
- class RISCVUSSegLoadFFMask<int nf>
- : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
- !add(nf, -1)), [llvm_anyint_ty]),
- !listconcat(!listsplat(LLVMMatchType<0>, nf),
- [LLVMPointerToElt<0>,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- LLVMMatchType<1>]),
- [NoCapture<ArgIndex<nf>>]>, RISCVVIntrinsic;
-
- // For stride segment load
- // Input: (pointer, offset, vl)
- class RISCVSSegLoad<int nf>
- : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
- !add(nf, -1))),
- [LLVMPointerToElt<0>, llvm_anyint_ty, LLVMMatchType<1>],
- [NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic;
- // For stride segment load with mask
- // Input: (maskedoff, pointer, offset, mask, vl)
- class RISCVSSegLoadMask<int nf>
- : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
- !add(nf, -1))),
- !listconcat(!listsplat(LLVMMatchType<0>, nf),
- [LLVMPointerToElt<0>,
- llvm_anyint_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- LLVMMatchType<1>]),
- [NoCapture<ArgIndex<nf>>, IntrReadMem]>, RISCVVIntrinsic;
-
- // For indexed segment load
- // Input: (pointer, index, vl)
- class RISCVISegLoad<int nf>
- : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
- !add(nf, -1))),
- [LLVMPointerToElt<0>, llvm_anyvector_ty, llvm_anyint_ty],
- [NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic;
- // For indexed segment load with mask
- // Input: (maskedoff, pointer, index, mask, vl)
- class RISCVISegLoadMask<int nf>
- : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
- !add(nf, -1))),
- !listconcat(!listsplat(LLVMMatchType<0>, nf),
- [LLVMPointerToElt<0>,
- llvm_anyvector_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- llvm_anyint_ty]),
- [NoCapture<ArgIndex<nf>>, IntrReadMem]>, RISCVVIntrinsic;
-
- // For unit stride segment store
- // Input: (value, pointer, vl)
- class RISCVUSSegStore<int nf>
- : Intrinsic<[],
- !listconcat([llvm_anyvector_ty],
- !listsplat(LLVMMatchType<0>, !add(nf, -1)),
- [LLVMPointerToElt<0>, llvm_anyint_ty]),
- [NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
- // For unit stride segment store with mask
- // Input: (value, pointer, mask, vl)
- class RISCVUSSegStoreMask<int nf>
- : Intrinsic<[],
- !listconcat([llvm_anyvector_ty],
- !listsplat(LLVMMatchType<0>, !add(nf, -1)),
- [LLVMPointerToElt<0>,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- llvm_anyint_ty]),
- [NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
-
- // For stride segment store
- // Input: (value, pointer, offset, vl)
- class RISCVSSegStore<int nf>
- : Intrinsic<[],
- !listconcat([llvm_anyvector_ty],
- !listsplat(LLVMMatchType<0>, !add(nf, -1)),
- [LLVMPointerToElt<0>, llvm_anyint_ty,
- LLVMMatchType<1>]),
- [NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
- // For stride segment store with mask
- // Input: (value, pointer, offset, mask, vl)
- class RISCVSSegStoreMask<int nf>
- : Intrinsic<[],
- !listconcat([llvm_anyvector_ty],
- !listsplat(LLVMMatchType<0>, !add(nf, -1)),
- [LLVMPointerToElt<0>, llvm_anyint_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- LLVMMatchType<1>]),
- [NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
-
- // For indexed segment store
- // Input: (value, pointer, offset, vl)
- class RISCVISegStore<int nf>
- : Intrinsic<[],
- !listconcat([llvm_anyvector_ty],
- !listsplat(LLVMMatchType<0>, !add(nf, -1)),
- [LLVMPointerToElt<0>, llvm_anyvector_ty,
- llvm_anyint_ty]),
- [NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
- // For indexed segment store with mask
- // Input: (value, pointer, offset, mask, vl)
- class RISCVISegStoreMask<int nf>
- : Intrinsic<[],
- !listconcat([llvm_anyvector_ty],
- !listsplat(LLVMMatchType<0>, !add(nf, -1)),
- [LLVMPointerToElt<0>, llvm_anyvector_ty,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- llvm_anyint_ty]),
- [NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
-
- multiclass RISCVUSLoad {
- def "int_riscv_" # NAME : RISCVUSLoad;
- def "int_riscv_" # NAME # "_mask" : RISCVUSLoadMask;
- }
- multiclass RISCVUSLoadFF {
- def "int_riscv_" # NAME : RISCVUSLoadFF;
- def "int_riscv_" # NAME # "_mask" : RISCVUSLoadFFMask;
- }
- multiclass RISCVSLoad {
- def "int_riscv_" # NAME : RISCVSLoad;
- def "int_riscv_" # NAME # "_mask" : RISCVSLoadMask;
- }
- multiclass RISCVILoad {
- def "int_riscv_" # NAME : RISCVILoad;
- def "int_riscv_" # NAME # "_mask" : RISCVILoadMask;
- }
- multiclass RISCVUSStore {
- def "int_riscv_" # NAME : RISCVUSStore;
- def "int_riscv_" # NAME # "_mask" : RISCVUSStoreMask;
- }
- multiclass RISCVSStore {
- def "int_riscv_" # NAME : RISCVSStore;
- def "int_riscv_" # NAME # "_mask" : RISCVSStoreMask;
- }
-
- multiclass RISCVIStore {
- def "int_riscv_" # NAME : RISCVIStore;
- def "int_riscv_" # NAME # "_mask" : RISCVIStoreMask;
- }
- multiclass RISCVUnaryAA {
- def "int_riscv_" # NAME : RISCVUnaryAANoMask;
- def "int_riscv_" # NAME # "_mask" : RISCVUnaryAAMask;
- }
- multiclass RISCVUnaryAB {
- def "int_riscv_" # NAME : RISCVUnaryABNoMask;
- def "int_riscv_" # NAME # "_mask" : RISCVUnaryABMask;
- }
- // AAX means the destination type(A) is the same as the first source
- // type(A). X means any type for the second source operand.
- multiclass RISCVBinaryAAX {
- def "int_riscv_" # NAME : RISCVBinaryAAXNoMask;
- def "int_riscv_" # NAME # "_mask" : RISCVBinaryAAXMask;
- }
- // ABX means the destination type(A) is different from the first source
- // type(B). X means any type for the second source operand.
- multiclass RISCVBinaryABX {
- def "int_riscv_" # NAME : RISCVBinaryABXNoMask;
- def "int_riscv_" # NAME # "_mask" : RISCVBinaryABXMask;
- }
- multiclass RISCVBinaryWithV0 {
- def "int_riscv_" # NAME : RISCVBinaryWithV0;
- }
- multiclass RISCVBinaryMaskOutWithV0 {
- def "int_riscv_" # NAME : RISCVBinaryMOutWithV0;
- }
- multiclass RISCVBinaryMaskOut {
- def "int_riscv_" # NAME : RISCVBinaryMOut;
- }
- multiclass RISCVSaturatingBinaryAAX {
- def "int_riscv_" # NAME : RISCVSaturatingBinaryAAXNoMask;
- def "int_riscv_" # NAME # "_mask" : RISCVSaturatingBinaryAAXMask;
- }
- multiclass RISCVSaturatingBinaryABX {
- def "int_riscv_" # NAME : RISCVSaturatingBinaryABXNoMask;
- def "int_riscv_" # NAME # "_mask" : RISCVSaturatingBinaryABXMask;
- }
- multiclass RISCVTernaryAAAX {
- def "int_riscv_" # NAME : RISCVTernaryAAAXNoMask;
- def "int_riscv_" # NAME # "_mask" : RISCVTernaryAAAXMask;
- }
- multiclass RISCVTernaryAAXA {
- def "int_riscv_" # NAME : RISCVTernaryAAXANoMask;
- def "int_riscv_" # NAME # "_mask" : RISCVTernaryAAXAMask;
- }
- multiclass RISCVCompare {
- def "int_riscv_" # NAME : RISCVCompareNoMask;
- def "int_riscv_" # NAME # "_mask" : RISCVCompareMask;
- }
- multiclass RISCVClassify {
- def "int_riscv_" # NAME : RISCVClassifyNoMask;
- def "int_riscv_" # NAME # "_mask" : RISCVClassifyMask;
- }
- multiclass RISCVTernaryWide {
- def "int_riscv_" # NAME : RISCVTernaryWideNoMask;
- def "int_riscv_" # NAME # "_mask" : RISCVTernaryWideMask;
- }
- multiclass RISCVReduction {
- def "int_riscv_" # NAME : RISCVReductionNoMask;
- def "int_riscv_" # NAME # "_mask" : RISCVReductionMask;
- }
- multiclass RISCVMaskUnarySOut {
- def "int_riscv_" # NAME : RISCVMaskUnarySOutNoMask;
- def "int_riscv_" # NAME # "_mask" : RISCVMaskUnarySOutMask;
- }
- multiclass RISCVMaskUnaryMOut {
- def "int_riscv_" # NAME : RISCVUnaryNoMask;
- def "int_riscv_" # NAME # "_mask" : RISCVMaskUnaryMOutMask;
- }
- multiclass RISCVConversion {
- def "int_riscv_" #NAME :RISCVConversionNoMask;
- def "int_riscv_" # NAME # "_mask" : RISCVConversionMask;
- }
- multiclass RISCVAMO {
- def "int_riscv_" # NAME : RISCVAMONoMask;
- def "int_riscv_" # NAME # "_mask" : RISCVAMOMask;
- }
- multiclass RISCVUSSegLoad<int nf> {
- def "int_riscv_" # NAME : RISCVUSSegLoad<nf>;
- def "int_riscv_" # NAME # "_mask" : RISCVUSSegLoadMask<nf>;
- }
- multiclass RISCVUSSegLoadFF<int nf> {
- def "int_riscv_" # NAME : RISCVUSSegLoadFF<nf>;
- def "int_riscv_" # NAME # "_mask" : RISCVUSSegLoadFFMask<nf>;
- }
- multiclass RISCVSSegLoad<int nf> {
- def "int_riscv_" # NAME : RISCVSSegLoad<nf>;
- def "int_riscv_" # NAME # "_mask" : RISCVSSegLoadMask<nf>;
- }
- multiclass RISCVISegLoad<int nf> {
- def "int_riscv_" # NAME : RISCVISegLoad<nf>;
- def "int_riscv_" # NAME # "_mask" : RISCVISegLoadMask<nf>;
- }
- multiclass RISCVUSSegStore<int nf> {
- def "int_riscv_" # NAME : RISCVUSSegStore<nf>;
- def "int_riscv_" # NAME # "_mask" : RISCVUSSegStoreMask<nf>;
- }
- multiclass RISCVSSegStore<int nf> {
- def "int_riscv_" # NAME : RISCVSSegStore<nf>;
- def "int_riscv_" # NAME # "_mask" : RISCVSSegStoreMask<nf>;
- }
- multiclass RISCVISegStore<int nf> {
- def "int_riscv_" # NAME : RISCVISegStore<nf>;
- def "int_riscv_" # NAME # "_mask" : RISCVISegStoreMask<nf>;
- }
-
- defm vle : RISCVUSLoad;
- defm vleff : RISCVUSLoadFF;
- defm vse : RISCVUSStore;
- defm vlse: RISCVSLoad;
- defm vsse: RISCVSStore;
- defm vluxei : RISCVILoad;
- defm vloxei : RISCVILoad;
- defm vsoxei : RISCVIStore;
- defm vsuxei : RISCVIStore;
-
- def int_riscv_vle1 : RISCVUSLoad;
- def int_riscv_vse1 : RISCVUSStore;
-
- defm vamoswap : RISCVAMO;
- defm vamoadd : RISCVAMO;
- defm vamoxor : RISCVAMO;
- defm vamoand : RISCVAMO;
- defm vamoor : RISCVAMO;
- defm vamomin : RISCVAMO;
- defm vamomax : RISCVAMO;
- defm vamominu : RISCVAMO;
- defm vamomaxu : RISCVAMO;
-
- defm vadd : RISCVBinaryAAX;
- defm vsub : RISCVBinaryAAX;
- defm vrsub : RISCVBinaryAAX;
-
- defm vwaddu : RISCVBinaryABX;
- defm vwadd : RISCVBinaryABX;
- defm vwaddu_w : RISCVBinaryAAX;
- defm vwadd_w : RISCVBinaryAAX;
- defm vwsubu : RISCVBinaryABX;
- defm vwsub : RISCVBinaryABX;
- defm vwsubu_w : RISCVBinaryAAX;
- defm vwsub_w : RISCVBinaryAAX;
-
- defm vzext : RISCVUnaryAB;
- defm vsext : RISCVUnaryAB;
-
- defm vadc : RISCVBinaryWithV0;
- defm vmadc_carry_in : RISCVBinaryMaskOutWithV0;
- defm vmadc : RISCVBinaryMaskOut;
-
- defm vsbc : RISCVBinaryWithV0;
- defm vmsbc_borrow_in : RISCVBinaryMaskOutWithV0;
- defm vmsbc : RISCVBinaryMaskOut;
-
- defm vand : RISCVBinaryAAX;
- defm vor : RISCVBinaryAAX;
- defm vxor : RISCVBinaryAAX;
-
- defm vsll : RISCVBinaryAAX;
- defm vsrl : RISCVBinaryAAX;
- defm vsra : RISCVBinaryAAX;
-
- defm vnsrl : RISCVBinaryABX;
- defm vnsra : RISCVBinaryABX;
-
- defm vmseq : RISCVCompare;
- defm vmsne : RISCVCompare;
- defm vmsltu : RISCVCompare;
- defm vmslt : RISCVCompare;
- defm vmsleu : RISCVCompare;
- defm vmsle : RISCVCompare;
- defm vmsgtu : RISCVCompare;
- defm vmsgt : RISCVCompare;
-
- defm vminu : RISCVBinaryAAX;
- defm vmin : RISCVBinaryAAX;
- defm vmaxu : RISCVBinaryAAX;
- defm vmax : RISCVBinaryAAX;
-
- defm vmul : RISCVBinaryAAX;
- defm vmulh : RISCVBinaryAAX;
- defm vmulhu : RISCVBinaryAAX;
- defm vmulhsu : RISCVBinaryAAX;
-
- defm vdivu : RISCVBinaryAAX;
- defm vdiv : RISCVBinaryAAX;
- defm vremu : RISCVBinaryAAX;
- defm vrem : RISCVBinaryAAX;
-
- defm vwmul : RISCVBinaryABX;
- defm vwmulu : RISCVBinaryABX;
- defm vwmulsu : RISCVBinaryABX;
-
- defm vmacc : RISCVTernaryAAXA;
- defm vnmsac : RISCVTernaryAAXA;
- defm vmadd : RISCVTernaryAAXA;
- defm vnmsub : RISCVTernaryAAXA;
-
- defm vwmaccu : RISCVTernaryWide;
- defm vwmacc : RISCVTernaryWide;
- defm vwmaccus : RISCVTernaryWide;
- defm vwmaccsu : RISCVTernaryWide;
-
- defm vfadd : RISCVBinaryAAX;
- defm vfsub : RISCVBinaryAAX;
- defm vfrsub : RISCVBinaryAAX;
-
- defm vfwadd : RISCVBinaryABX;
- defm vfwsub : RISCVBinaryABX;
- defm vfwadd_w : RISCVBinaryAAX;
- defm vfwsub_w : RISCVBinaryAAX;
-
- defm vsaddu : RISCVSaturatingBinaryAAX;
- defm vsadd : RISCVSaturatingBinaryAAX;
- defm vssubu : RISCVSaturatingBinaryAAX;
- defm vssub : RISCVSaturatingBinaryAAX;
-
- def int_riscv_vmerge : RISCVBinaryWithV0;
-
- def int_riscv_vmv_v_v : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- def int_riscv_vmv_v_x : Intrinsic<[llvm_anyint_ty],
- [LLVMVectorElementType<0>, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic {
- let ExtendOperand = 1;
- }
- def int_riscv_vfmv_v_f : Intrinsic<[llvm_anyfloat_ty],
- [LLVMVectorElementType<0>, llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
-
- def int_riscv_vmv_x_s : Intrinsic<[LLVMVectorElementType<0>],
- [llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- def int_riscv_vmv_s_x : Intrinsic<[llvm_anyint_ty],
- [LLVMMatchType<0>, LLVMVectorElementType<0>,
- llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic {
- let ExtendOperand = 2;
- }
-
- def int_riscv_vfmv_f_s : Intrinsic<[LLVMVectorElementType<0>],
- [llvm_anyfloat_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- def int_riscv_vfmv_s_f : Intrinsic<[llvm_anyfloat_ty],
- [LLVMMatchType<0>, LLVMVectorElementType<0>,
- llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
-
- defm vfmul : RISCVBinaryAAX;
- defm vfdiv : RISCVBinaryAAX;
- defm vfrdiv : RISCVBinaryAAX;
-
- defm vfwmul : RISCVBinaryABX;
-
- defm vfmacc : RISCVTernaryAAXA;
- defm vfnmacc : RISCVTernaryAAXA;
- defm vfmsac : RISCVTernaryAAXA;
- defm vfnmsac : RISCVTernaryAAXA;
- defm vfmadd : RISCVTernaryAAXA;
- defm vfnmadd : RISCVTernaryAAXA;
- defm vfmsub : RISCVTernaryAAXA;
- defm vfnmsub : RISCVTernaryAAXA;
-
- defm vfwmacc : RISCVTernaryWide;
- defm vfwnmacc : RISCVTernaryWide;
- defm vfwmsac : RISCVTernaryWide;
- defm vfwnmsac : RISCVTernaryWide;
-
- defm vfsqrt : RISCVUnaryAA;
- defm vfrsqrt7 : RISCVUnaryAA;
- defm vfrec7 : RISCVUnaryAA;
-
- defm vfmin : RISCVBinaryAAX;
- defm vfmax : RISCVBinaryAAX;
-
- defm vfsgnj : RISCVBinaryAAX;
- defm vfsgnjn : RISCVBinaryAAX;
- defm vfsgnjx : RISCVBinaryAAX;
-
- defm vfclass : RISCVClassify;
-
- defm vfmerge : RISCVBinaryWithV0;
-
- defm vslideup : RISCVTernaryAAAX;
- defm vslidedown : RISCVTernaryAAAX;
-
- defm vslide1up : RISCVBinaryAAX;
- defm vslide1down : RISCVBinaryAAX;
- defm vfslide1up : RISCVBinaryAAX;
- defm vfslide1down : RISCVBinaryAAX;
-
- defm vrgather : RISCVBinaryAAX;
- defm vrgatherei16 : RISCVBinaryAAX;
-
- def "int_riscv_vcompress" : RISCVBinaryAAAMask;
-
- defm vaaddu : RISCVSaturatingBinaryAAX;
- defm vaadd : RISCVSaturatingBinaryAAX;
- defm vasubu : RISCVSaturatingBinaryAAX;
- defm vasub : RISCVSaturatingBinaryAAX;
-
- defm vsmul : RISCVSaturatingBinaryAAX;
-
- defm vssrl : RISCVSaturatingBinaryAAX;
- defm vssra : RISCVSaturatingBinaryAAX;
-
- defm vnclipu : RISCVSaturatingBinaryABX;
- defm vnclip : RISCVSaturatingBinaryABX;
-
- defm vmfeq : RISCVCompare;
- defm vmfne : RISCVCompare;
- defm vmflt : RISCVCompare;
- defm vmfle : RISCVCompare;
- defm vmfgt : RISCVCompare;
- defm vmfge : RISCVCompare;
-
- defm vredsum : RISCVReduction;
- defm vredand : RISCVReduction;
- defm vredor : RISCVReduction;
- defm vredxor : RISCVReduction;
- defm vredminu : RISCVReduction;
- defm vredmin : RISCVReduction;
- defm vredmaxu : RISCVReduction;
- defm vredmax : RISCVReduction;
-
- defm vwredsumu : RISCVReduction;
- defm vwredsum : RISCVReduction;
-
- defm vfredosum : RISCVReduction;
- defm vfredsum : RISCVReduction;
- defm vfredmin : RISCVReduction;
- defm vfredmax : RISCVReduction;
-
- defm vfwredsum : RISCVReduction;
- defm vfwredosum : RISCVReduction;
-
- def int_riscv_vmand: RISCVBinaryAAANoMask;
- def int_riscv_vmnand: RISCVBinaryAAANoMask;
- def int_riscv_vmandnot: RISCVBinaryAAANoMask;
- def int_riscv_vmxor: RISCVBinaryAAANoMask;
- def int_riscv_vmor: RISCVBinaryAAANoMask;
- def int_riscv_vmnor: RISCVBinaryAAANoMask;
- def int_riscv_vmornot: RISCVBinaryAAANoMask;
- def int_riscv_vmxnor: RISCVBinaryAAANoMask;
- def int_riscv_vmclr : RISCVNullaryIntrinsic;
- def int_riscv_vmset : RISCVNullaryIntrinsic;
-
- defm vpopc : RISCVMaskUnarySOut;
- defm vfirst : RISCVMaskUnarySOut;
- defm vmsbf : RISCVMaskUnaryMOut;
- defm vmsof : RISCVMaskUnaryMOut;
- defm vmsif : RISCVMaskUnaryMOut;
-
- defm vfcvt_xu_f_v : RISCVConversion;
- defm vfcvt_x_f_v : RISCVConversion;
- defm vfcvt_rtz_xu_f_v : RISCVConversion;
- defm vfcvt_rtz_x_f_v : RISCVConversion;
- defm vfcvt_f_xu_v : RISCVConversion;
- defm vfcvt_f_x_v : RISCVConversion;
-
- defm vfwcvt_f_xu_v : RISCVConversion;
- defm vfwcvt_f_x_v : RISCVConversion;
- defm vfwcvt_xu_f_v : RISCVConversion;
- defm vfwcvt_x_f_v : RISCVConversion;
- defm vfwcvt_rtz_xu_f_v : RISCVConversion;
- defm vfwcvt_rtz_x_f_v : RISCVConversion;
- defm vfwcvt_f_f_v : RISCVConversion;
-
- defm vfncvt_f_xu_w : RISCVConversion;
- defm vfncvt_f_x_w : RISCVConversion;
- defm vfncvt_xu_f_w : RISCVConversion;
- defm vfncvt_x_f_w : RISCVConversion;
- defm vfncvt_rtz_xu_f_w : RISCVConversion;
- defm vfncvt_rtz_x_f_w : RISCVConversion;
- defm vfncvt_f_f_w : RISCVConversion;
- defm vfncvt_rod_f_f_w : RISCVConversion;
-
- // Output: (vector)
- // Input: (mask type input, vl)
- def int_riscv_viota : Intrinsic<[llvm_anyvector_ty],
- [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- // Output: (vector)
- // Input: (maskedoff, mask type vector_in, mask, vl)
- def int_riscv_viota_mask : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
- // Output: (vector)
- // Input: (vl)
- def int_riscv_vid : RISCVNullaryIntrinsic;
-
- // Output: (vector)
- // Input: (maskedoff, mask, vl)
- def int_riscv_vid_mask : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>,
- LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- llvm_anyint_ty],
- [IntrNoMem]>, RISCVVIntrinsic;
-
- foreach nf = [2, 3, 4, 5, 6, 7, 8] in {
- defm vlseg # nf : RISCVUSSegLoad<nf>;
- defm vlseg # nf # ff : RISCVUSSegLoadFF<nf>;
- defm vlsseg # nf : RISCVSSegLoad<nf>;
- defm vloxseg # nf : RISCVISegLoad<nf>;
- defm vluxseg # nf : RISCVISegLoad<nf>;
- defm vsseg # nf : RISCVUSSegStore<nf>;
- defm vssseg # nf : RISCVSSegStore<nf>;
- defm vsoxseg # nf : RISCVISegStore<nf>;
- defm vsuxseg # nf : RISCVISegStore<nf>;
- }
-
-} // TargetPrefix = "riscv"
+
+//===----------------------------------------------------------------------===//
+// Vectors
+
+class RISCVVIntrinsic {
+ // These intrinsics may accept illegal integer values in their llvm_any_ty
+ // operand, so they have to be extended. If set to zero then the intrinsic
+ // does not have any operand that must be extended.
+ Intrinsic IntrinsicID = !cast<Intrinsic>(NAME);
+ bits<4> ExtendOperand = 0;
+}
+
+let TargetPrefix = "riscv" in {
+ // We use anyint here but we only support XLen.
+ def int_riscv_vsetvli : Intrinsic<[llvm_anyint_ty],
+ /* AVL */ [LLVMMatchType<0>,
+ /* VSEW */ LLVMMatchType<0>,
+ /* VLMUL */ LLVMMatchType<0>],
+ [IntrNoMem, IntrHasSideEffects,
+ ImmArg<ArgIndex<1>>,
+ ImmArg<ArgIndex<2>>]>;
+ def int_riscv_vsetvlimax : Intrinsic<[llvm_anyint_ty],
+ /* VSEW */ [LLVMMatchType<0>,
+ /* VLMUL */ LLVMMatchType<0>],
+ [IntrNoMem, IntrHasSideEffects,
+ ImmArg<ArgIndex<0>>,
+ ImmArg<ArgIndex<1>>]>;
+
+ // For unit stride load
+ // Input: (pointer, vl)
+ class RISCVUSLoad
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMPointerType<LLVMMatchType<0>>,
+ llvm_anyint_ty],
+ [NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic;
+ // For unit stride fault-only-first load
+ // Input: (pointer, vl)
+ // Output: (data, vl)
+ // NOTE: We model this with default memory properties since we model writing
+ // VL as a side effect. IntrReadMem, IntrHasSideEffects does not work.
+ class RISCVUSLoadFF
+ : Intrinsic<[llvm_anyvector_ty, llvm_anyint_ty],
+ [LLVMPointerType<LLVMMatchType<0>>, LLVMMatchType<1>],
+ [NoCapture<ArgIndex<0>>]>,
+ RISCVVIntrinsic;
+ // For unit stride load with mask
+ // Input: (maskedoff, pointer, mask, vl)
+ class RISCVUSLoadMask
+ : Intrinsic<[llvm_anyvector_ty ],
+ [LLVMMatchType<0>,
+ LLVMPointerType<LLVMMatchType<0>>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_anyint_ty],
+ [NoCapture<ArgIndex<1>>, IntrReadMem]>, RISCVVIntrinsic;
+ // For unit stride fault-only-first load with mask
+ // Input: (maskedoff, pointer, mask, vl)
+ // Output: (data, vl)
+ // NOTE: We model this with default memory properties since we model writing
+ // VL as a side effect. IntrReadMem, IntrHasSideEffects does not work.
+ class RISCVUSLoadFFMask
+ : Intrinsic<[llvm_anyvector_ty, llvm_anyint_ty],
+ [LLVMMatchType<0>,
+ LLVMPointerType<LLVMMatchType<0>>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ LLVMMatchType<1>],
+ [NoCapture<ArgIndex<1>>]>, RISCVVIntrinsic;
+ // For strided load
+ // Input: (pointer, stride, vl)
+ class RISCVSLoad
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMPointerType<LLVMMatchType<0>>,
+ llvm_anyint_ty, LLVMMatchType<1>],
+ [NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic;
+ // For strided load with mask
+ // Input: (maskedoff, pointer, stride, mask, vl)
+ class RISCVSLoadMask
+ : Intrinsic<[llvm_anyvector_ty ],
+ [LLVMMatchType<0>,
+ LLVMPointerType<LLVMMatchType<0>>, llvm_anyint_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<1>],
+ [NoCapture<ArgIndex<1>>, IntrReadMem]>, RISCVVIntrinsic;
+ // For indexed load
+ // Input: (pointer, index, vl)
+ class RISCVILoad
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMPointerType<LLVMMatchType<0>>,
+ llvm_anyvector_ty, llvm_anyint_ty],
+ [NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic;
+ // For indexed load with mask
+ // Input: (maskedoff, pointer, index, mask, vl)
+ class RISCVILoadMask
+ : Intrinsic<[llvm_anyvector_ty ],
+ [LLVMMatchType<0>,
+ LLVMPointerType<LLVMMatchType<0>>, llvm_anyvector_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
+ [NoCapture<ArgIndex<1>>, IntrReadMem]>, RISCVVIntrinsic;
+ // For unit stride store
+ // Input: (vector_in, pointer, vl)
+ class RISCVUSStore
+ : Intrinsic<[],
+ [llvm_anyvector_ty,
+ LLVMPointerType<LLVMMatchType<0>>,
+ llvm_anyint_ty],
+ [NoCapture<ArgIndex<1>>, IntrWriteMem]>, RISCVVIntrinsic;
+ // For unit stride store with mask
+ // Input: (vector_in, pointer, mask, vl)
+ class RISCVUSStoreMask
+ : Intrinsic<[],
+ [llvm_anyvector_ty,
+ LLVMPointerType<LLVMMatchType<0>>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_anyint_ty],
+ [NoCapture<ArgIndex<1>>, IntrWriteMem]>, RISCVVIntrinsic;
+ // For strided store
+ // Input: (vector_in, pointer, stride, vl)
+ class RISCVSStore
+ : Intrinsic<[],
+ [llvm_anyvector_ty,
+ LLVMPointerType<LLVMMatchType<0>>,
+ llvm_anyint_ty, LLVMMatchType<1>],
+ [NoCapture<ArgIndex<1>>, IntrWriteMem]>, RISCVVIntrinsic;
+ // For stride store with mask
+ // Input: (vector_in, pointer, stirde, mask, vl)
+ class RISCVSStoreMask
+ : Intrinsic<[],
+ [llvm_anyvector_ty,
+ LLVMPointerType<LLVMMatchType<0>>, llvm_anyint_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<1>],
+ [NoCapture<ArgIndex<1>>, IntrWriteMem]>, RISCVVIntrinsic;
+ // For indexed store
+ // Input: (vector_in, pointer, index, vl)
+ class RISCVIStore
+ : Intrinsic<[],
+ [llvm_anyvector_ty,
+ LLVMPointerType<LLVMMatchType<0>>,
+ llvm_anyint_ty, llvm_anyint_ty],
+ [NoCapture<ArgIndex<1>>, IntrWriteMem]>, RISCVVIntrinsic;
+ // For indexed store with mask
+ // Input: (vector_in, pointer, index, mask, vl)
+ class RISCVIStoreMask
+ : Intrinsic<[],
+ [llvm_anyvector_ty,
+ LLVMPointerType<LLVMMatchType<0>>, llvm_anyvector_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
+ [NoCapture<ArgIndex<1>>, IntrWriteMem]>, RISCVVIntrinsic;
+ // For destination vector type is the same as source vector.
+ // Input: (vector_in, vl)
+ class RISCVUnaryAANoMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // For destination vector type is the same as first source vector (with mask).
+ // Input: (vector_in, mask, vl)
+ class RISCVUnaryAAMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // For destination vector type is the same as first and second source vector.
+ // Input: (vector_in, vector_in, vl)
+ class RISCVBinaryAAANoMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // For destination vector type is the same as first and second source vector.
+ // Input: (vector_in, vector_in, vl)
+ class RISCVBinaryAAAMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // For destination vector type is the same as first source vector.
+ // Input: (vector_in, vector_in/scalar_in, vl)
+ class RISCVBinaryAAXNoMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_any_ty, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic {
+ let ExtendOperand = 2;
+ }
+ // For destination vector type is the same as first source vector (with mask).
+ // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
+ class RISCVBinaryAAXMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, llvm_any_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic {
+ let ExtendOperand = 3;
+ }
+ // For destination vector type is NOT the same as first source vector.
+ // Input: (vector_in, vector_in/scalar_in, vl)
+ class RISCVBinaryABXNoMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [llvm_anyvector_ty, llvm_any_ty, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic {
+ let ExtendOperand = 2;
+ }
+ // For destination vector type is NOT the same as first source vector (with mask).
+ // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
+ class RISCVBinaryABXMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty, llvm_any_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic {
+ let ExtendOperand = 3;
+ }
+ // For binary operations with V0 as input.
+ // Input: (vector_in, vector_in/scalar_in, V0, vl)
+ class RISCVBinaryWithV0
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_any_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic {
+ let ExtendOperand = 2;
+ }
+ // For binary operations with mask type output and V0 as input.
+ // Output: (mask type output)
+ // Input: (vector_in, vector_in/scalar_in, V0, vl)
+ class RISCVBinaryMOutWithV0
+ :Intrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
+ [llvm_anyvector_ty, llvm_any_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic {
+ let ExtendOperand = 2;
+ }
+ // For binary operations with mask type output.
+ // Output: (mask type output)
+ // Input: (vector_in, vector_in/scalar_in, vl)
+ class RISCVBinaryMOut
+ : Intrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
+ [llvm_anyvector_ty, llvm_any_ty, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic {
+ let ExtendOperand = 2;
+ }
+ // For binary operations with mask type output without mask.
+ // Output: (mask type output)
+ // Input: (vector_in, vector_in/scalar_in, vl)
+ class RISCVCompareNoMask
+ : Intrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
+ [llvm_anyvector_ty, llvm_any_ty, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic {
+ let ExtendOperand = 2;
+ }
+ // For binary operations with mask type output with mask.
+ // Output: (mask type output)
+ // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
+ class RISCVCompareMask
+ : Intrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
+ [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_anyvector_ty, llvm_any_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic {
+ let ExtendOperand = 3;
+ }
+ // For FP classify operations.
+ // Output: (bit mask type output)
+ // Input: (vector_in, vl)
+ class RISCVClassifyNoMask
+ : Intrinsic<[LLVMVectorOfBitcastsToInt<0>],
+ [llvm_anyvector_ty, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // For FP classify operations with mask.
+ // Output: (bit mask type output)
+ // Input: (maskedoff, vector_in, mask, vl)
+ class RISCVClassifyMask
+ : Intrinsic<[LLVMVectorOfBitcastsToInt<0>],
+ [LLVMVectorOfBitcastsToInt<0>, llvm_anyvector_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // For Saturating binary operations.
+ // The destination vector type is the same as first source vector.
+ // Input: (vector_in, vector_in/scalar_in, vl)
+ class RISCVSaturatingBinaryAAXNoMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_any_ty, llvm_anyint_ty],
+ [IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic {
+ let ExtendOperand = 2;
+ }
+ // For Saturating binary operations with mask.
+ // The destination vector type is the same as first source vector.
+ // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
+ class RISCVSaturatingBinaryAAXMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, llvm_any_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
+ [IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic {
+ let ExtendOperand = 3;
+ }
+ // For Saturating binary operations.
+ // The destination vector type is NOT the same as first source vector.
+ // Input: (vector_in, vector_in/scalar_in, vl)
+ class RISCVSaturatingBinaryABXNoMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [llvm_anyvector_ty, llvm_any_ty, llvm_anyint_ty],
+ [IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic {
+ let ExtendOperand = 2;
+ }
+ // For Saturating binary operations with mask.
+ // The destination vector type is NOT the same as first source vector (with mask).
+ // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl)
+ class RISCVSaturatingBinaryABXMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty, llvm_any_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
+ [IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic {
+ let ExtendOperand = 3;
+ }
+ class RISCVTernaryAAAXNoMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyint_ty,
+ LLVMMatchType<1>],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ class RISCVTernaryAAAXMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyint_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<1>],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ class RISCVTernaryAAXANoMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_any_ty, LLVMMatchType<0>,
+ llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic {
+ let ExtendOperand = 2;
+ }
+ class RISCVTernaryAAXAMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_any_ty, LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic {
+ let ExtendOperand = 2;
+ }
+ class RISCVTernaryWideNoMask
+ : Intrinsic< [llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_any_ty, llvm_anyvector_ty,
+ llvm_anyint_ty],
+ [IntrNoMem] >, RISCVVIntrinsic {
+ let ExtendOperand = 2;
+ }
+ class RISCVTernaryWideMask
+ : Intrinsic< [llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_any_ty, llvm_anyvector_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic {
+ let ExtendOperand = 2;
+ }
+ // For Reduction ternary operations.
+ // For destination vector type is the same as first and third source vector.
+ // Input: (vector_in, vector_in, vector_in, vl)
+ class RISCVReductionNoMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<0>,
+ llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // For Reduction ternary operations with mask.
+ // For destination vector type is the same as first and third source vector.
+ // The mask type come from second source vector.
+ // Input: (maskedoff, vector_in, vector_in, vector_in, mask, vl)
+ class RISCVReductionMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<1, llvm_i1_ty>, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // For unary operations with scalar type output without mask
+ // Output: (scalar type)
+ // Input: (vector_in, vl)
+ class RISCVMaskUnarySOutNoMask
+ : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyvector_ty, LLVMMatchType<0>],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // For unary operations with scalar type output with mask
+ // Output: (scalar type)
+ // Input: (vector_in, mask, vl)
+ class RISCVMaskUnarySOutMask
+ : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyvector_ty, LLVMMatchType<1>, LLVMMatchType<0>],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // For destination vector type is NOT the same as source vector.
+ // Input: (vector_in, vl)
+ class RISCVUnaryABNoMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [llvm_anyvector_ty, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // For destination vector type is NOT the same as source vector (with mask).
+ // Input: (maskedoff, vector_in, mask, vl)
+ class RISCVUnaryABMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty,
+ LLVMScalarOrSameVectorWidth<1, llvm_i1_ty>,
+ llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // For unary operations with the same vector type in/out without mask
+ // Output: (vector)
+ // Input: (vector_in, vl)
+ class RISCVUnaryNoMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // For mask unary operations with mask type in/out with mask
+ // Output: (mask type output)
+ // Input: (mask type maskedoff, mask type vector_in, mask, vl)
+ class RISCVMaskUnaryMOutMask
+ : Intrinsic<[llvm_anyint_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>,
+ LLVMMatchType<0>, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // Output: (vector)
+ // Input: (vl)
+ class RISCVNullaryIntrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // For Conversion unary operations.
+ // Input: (vector_in, vl)
+ class RISCVConversionNoMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [llvm_anyvector_ty, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // For Conversion unary operations with mask.
+ // Input: (maskedoff, vector_in, mask, vl)
+ class RISCVConversionMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // For atomic operations without mask
+ // Input: (base, index, value, vl)
+ class RISCVAMONoMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMPointerType<LLVMMatchType<0>>, llvm_anyvector_ty, LLVMMatchType<0>,
+ llvm_anyint_ty],
+ [NoCapture<ArgIndex<0>>]>, RISCVVIntrinsic;
+ // For atomic operations with mask
+ // Input: (base, index, value, mask, vl)
+ class RISCVAMOMask
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMPointerType<LLVMMatchType<0>>, llvm_anyvector_ty, LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty],
+ [NoCapture<ArgIndex<0>>]>, RISCVVIntrinsic;
+
+ // For unit stride segment load
+ // Input: (pointer, vl)
+ class RISCVUSSegLoad<int nf>
+ : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
+ !add(nf, -1))),
+ [LLVMPointerToElt<0>, llvm_anyint_ty],
+ [NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic;
+ // For unit stride segment load with mask
+ // Input: (maskedoff, pointer, mask, vl)
+ class RISCVUSSegLoadMask<int nf>
+ : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
+ !add(nf, -1))),
+ !listconcat(!listsplat(LLVMMatchType<0>, nf),
+ [LLVMPointerToElt<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_anyint_ty]),
+ [NoCapture<ArgIndex<nf>>, IntrReadMem]>, RISCVVIntrinsic;
+
+ // For unit stride fault-only-first segment load
+ // Input: (pointer, vl)
+ // Output: (data, vl)
+ // NOTE: We model this with default memory properties since we model writing
+ // VL as a side effect. IntrReadMem, IntrHasSideEffects does not work.
+ class RISCVUSSegLoadFF<int nf>
+ : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
+ !add(nf, -1)), [llvm_anyint_ty]),
+ [LLVMPointerToElt<0>, LLVMMatchType<1>],
+ [NoCapture<ArgIndex<0>>]>, RISCVVIntrinsic;
+ // For unit stride fault-only-first segment load with mask
+ // Input: (maskedoff, pointer, mask, vl)
+ // Output: (data, vl)
+ // NOTE: We model this with default memory properties since we model writing
+ // VL as a side effect. IntrReadMem, IntrHasSideEffects does not work.
+ class RISCVUSSegLoadFFMask<int nf>
+ : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
+ !add(nf, -1)), [llvm_anyint_ty]),
+ !listconcat(!listsplat(LLVMMatchType<0>, nf),
+ [LLVMPointerToElt<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ LLVMMatchType<1>]),
+ [NoCapture<ArgIndex<nf>>]>, RISCVVIntrinsic;
+
+ // For stride segment load
+ // Input: (pointer, offset, vl)
+ class RISCVSSegLoad<int nf>
+ : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
+ !add(nf, -1))),
+ [LLVMPointerToElt<0>, llvm_anyint_ty, LLVMMatchType<1>],
+ [NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic;
+ // For stride segment load with mask
+ // Input: (maskedoff, pointer, offset, mask, vl)
+ class RISCVSSegLoadMask<int nf>
+ : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
+ !add(nf, -1))),
+ !listconcat(!listsplat(LLVMMatchType<0>, nf),
+ [LLVMPointerToElt<0>,
+ llvm_anyint_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ LLVMMatchType<1>]),
+ [NoCapture<ArgIndex<nf>>, IntrReadMem]>, RISCVVIntrinsic;
+
+ // For indexed segment load
+ // Input: (pointer, index, vl)
+ class RISCVISegLoad<int nf>
+ : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
+ !add(nf, -1))),
+ [LLVMPointerToElt<0>, llvm_anyvector_ty, llvm_anyint_ty],
+ [NoCapture<ArgIndex<0>>, IntrReadMem]>, RISCVVIntrinsic;
+ // For indexed segment load with mask
+ // Input: (maskedoff, pointer, index, mask, vl)
+ class RISCVISegLoadMask<int nf>
+ : Intrinsic<!listconcat([llvm_anyvector_ty], !listsplat(LLVMMatchType<0>,
+ !add(nf, -1))),
+ !listconcat(!listsplat(LLVMMatchType<0>, nf),
+ [LLVMPointerToElt<0>,
+ llvm_anyvector_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_anyint_ty]),
+ [NoCapture<ArgIndex<nf>>, IntrReadMem]>, RISCVVIntrinsic;
+
+ // For unit stride segment store
+ // Input: (value, pointer, vl)
+ class RISCVUSSegStore<int nf>
+ : Intrinsic<[],
+ !listconcat([llvm_anyvector_ty],
+ !listsplat(LLVMMatchType<0>, !add(nf, -1)),
+ [LLVMPointerToElt<0>, llvm_anyint_ty]),
+ [NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
+ // For unit stride segment store with mask
+ // Input: (value, pointer, mask, vl)
+ class RISCVUSSegStoreMask<int nf>
+ : Intrinsic<[],
+ !listconcat([llvm_anyvector_ty],
+ !listsplat(LLVMMatchType<0>, !add(nf, -1)),
+ [LLVMPointerToElt<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_anyint_ty]),
+ [NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
+
+ // For stride segment store
+ // Input: (value, pointer, offset, vl)
+ class RISCVSSegStore<int nf>
+ : Intrinsic<[],
+ !listconcat([llvm_anyvector_ty],
+ !listsplat(LLVMMatchType<0>, !add(nf, -1)),
+ [LLVMPointerToElt<0>, llvm_anyint_ty,
+ LLVMMatchType<1>]),
+ [NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
+ // For stride segment store with mask
+ // Input: (value, pointer, offset, mask, vl)
+ class RISCVSSegStoreMask<int nf>
+ : Intrinsic<[],
+ !listconcat([llvm_anyvector_ty],
+ !listsplat(LLVMMatchType<0>, !add(nf, -1)),
+ [LLVMPointerToElt<0>, llvm_anyint_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ LLVMMatchType<1>]),
+ [NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
+
+ // For indexed segment store
+ // Input: (value, pointer, offset, vl)
+ class RISCVISegStore<int nf>
+ : Intrinsic<[],
+ !listconcat([llvm_anyvector_ty],
+ !listsplat(LLVMMatchType<0>, !add(nf, -1)),
+ [LLVMPointerToElt<0>, llvm_anyvector_ty,
+ llvm_anyint_ty]),
+ [NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
+ // For indexed segment store with mask
+ // Input: (value, pointer, offset, mask, vl)
+ class RISCVISegStoreMask<int nf>
+ : Intrinsic<[],
+ !listconcat([llvm_anyvector_ty],
+ !listsplat(LLVMMatchType<0>, !add(nf, -1)),
+ [LLVMPointerToElt<0>, llvm_anyvector_ty,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_anyint_ty]),
+ [NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
+
+ multiclass RISCVUSLoad {
+ def "int_riscv_" # NAME : RISCVUSLoad;
+ def "int_riscv_" # NAME # "_mask" : RISCVUSLoadMask;
+ }
+ multiclass RISCVUSLoadFF {
+ def "int_riscv_" # NAME : RISCVUSLoadFF;
+ def "int_riscv_" # NAME # "_mask" : RISCVUSLoadFFMask;
+ }
+ multiclass RISCVSLoad {
+ def "int_riscv_" # NAME : RISCVSLoad;
+ def "int_riscv_" # NAME # "_mask" : RISCVSLoadMask;
+ }
+ multiclass RISCVILoad {
+ def "int_riscv_" # NAME : RISCVILoad;
+ def "int_riscv_" # NAME # "_mask" : RISCVILoadMask;
+ }
+ multiclass RISCVUSStore {
+ def "int_riscv_" # NAME : RISCVUSStore;
+ def "int_riscv_" # NAME # "_mask" : RISCVUSStoreMask;
+ }
+ multiclass RISCVSStore {
+ def "int_riscv_" # NAME : RISCVSStore;
+ def "int_riscv_" # NAME # "_mask" : RISCVSStoreMask;
+ }
+
+ multiclass RISCVIStore {
+ def "int_riscv_" # NAME : RISCVIStore;
+ def "int_riscv_" # NAME # "_mask" : RISCVIStoreMask;
+ }
+ multiclass RISCVUnaryAA {
+ def "int_riscv_" # NAME : RISCVUnaryAANoMask;
+ def "int_riscv_" # NAME # "_mask" : RISCVUnaryAAMask;
+ }
+ multiclass RISCVUnaryAB {
+ def "int_riscv_" # NAME : RISCVUnaryABNoMask;
+ def "int_riscv_" # NAME # "_mask" : RISCVUnaryABMask;
+ }
+ // AAX means the destination type(A) is the same as the first source
+ // type(A). X means any type for the second source operand.
+ multiclass RISCVBinaryAAX {
+ def "int_riscv_" # NAME : RISCVBinaryAAXNoMask;
+ def "int_riscv_" # NAME # "_mask" : RISCVBinaryAAXMask;
+ }
+ // ABX means the destination type(A) is different from the first source
+ // type(B). X means any type for the second source operand.
+ multiclass RISCVBinaryABX {
+ def "int_riscv_" # NAME : RISCVBinaryABXNoMask;
+ def "int_riscv_" # NAME # "_mask" : RISCVBinaryABXMask;
+ }
+ multiclass RISCVBinaryWithV0 {
+ def "int_riscv_" # NAME : RISCVBinaryWithV0;
+ }
+ multiclass RISCVBinaryMaskOutWithV0 {
+ def "int_riscv_" # NAME : RISCVBinaryMOutWithV0;
+ }
+ multiclass RISCVBinaryMaskOut {
+ def "int_riscv_" # NAME : RISCVBinaryMOut;
+ }
+ multiclass RISCVSaturatingBinaryAAX {
+ def "int_riscv_" # NAME : RISCVSaturatingBinaryAAXNoMask;
+ def "int_riscv_" # NAME # "_mask" : RISCVSaturatingBinaryAAXMask;
+ }
+ multiclass RISCVSaturatingBinaryABX {
+ def "int_riscv_" # NAME : RISCVSaturatingBinaryABXNoMask;
+ def "int_riscv_" # NAME # "_mask" : RISCVSaturatingBinaryABXMask;
+ }
+ multiclass RISCVTernaryAAAX {
+ def "int_riscv_" # NAME : RISCVTernaryAAAXNoMask;
+ def "int_riscv_" # NAME # "_mask" : RISCVTernaryAAAXMask;
+ }
+ multiclass RISCVTernaryAAXA {
+ def "int_riscv_" # NAME : RISCVTernaryAAXANoMask;
+ def "int_riscv_" # NAME # "_mask" : RISCVTernaryAAXAMask;
+ }
+ multiclass RISCVCompare {
+ def "int_riscv_" # NAME : RISCVCompareNoMask;
+ def "int_riscv_" # NAME # "_mask" : RISCVCompareMask;
+ }
+ multiclass RISCVClassify {
+ def "int_riscv_" # NAME : RISCVClassifyNoMask;
+ def "int_riscv_" # NAME # "_mask" : RISCVClassifyMask;
+ }
+ multiclass RISCVTernaryWide {
+ def "int_riscv_" # NAME : RISCVTernaryWideNoMask;
+ def "int_riscv_" # NAME # "_mask" : RISCVTernaryWideMask;
+ }
+ multiclass RISCVReduction {
+ def "int_riscv_" # NAME : RISCVReductionNoMask;
+ def "int_riscv_" # NAME # "_mask" : RISCVReductionMask;
+ }
+ multiclass RISCVMaskUnarySOut {
+ def "int_riscv_" # NAME : RISCVMaskUnarySOutNoMask;
+ def "int_riscv_" # NAME # "_mask" : RISCVMaskUnarySOutMask;
+ }
+ multiclass RISCVMaskUnaryMOut {
+ def "int_riscv_" # NAME : RISCVUnaryNoMask;
+ def "int_riscv_" # NAME # "_mask" : RISCVMaskUnaryMOutMask;
+ }
+ multiclass RISCVConversion {
+ def "int_riscv_" #NAME :RISCVConversionNoMask;
+ def "int_riscv_" # NAME # "_mask" : RISCVConversionMask;
+ }
+ multiclass RISCVAMO {
+ def "int_riscv_" # NAME : RISCVAMONoMask;
+ def "int_riscv_" # NAME # "_mask" : RISCVAMOMask;
+ }
+ multiclass RISCVUSSegLoad<int nf> {
+ def "int_riscv_" # NAME : RISCVUSSegLoad<nf>;
+ def "int_riscv_" # NAME # "_mask" : RISCVUSSegLoadMask<nf>;
+ }
+ multiclass RISCVUSSegLoadFF<int nf> {
+ def "int_riscv_" # NAME : RISCVUSSegLoadFF<nf>;
+ def "int_riscv_" # NAME # "_mask" : RISCVUSSegLoadFFMask<nf>;
+ }
+ multiclass RISCVSSegLoad<int nf> {
+ def "int_riscv_" # NAME : RISCVSSegLoad<nf>;
+ def "int_riscv_" # NAME # "_mask" : RISCVSSegLoadMask<nf>;
+ }
+ multiclass RISCVISegLoad<int nf> {
+ def "int_riscv_" # NAME : RISCVISegLoad<nf>;
+ def "int_riscv_" # NAME # "_mask" : RISCVISegLoadMask<nf>;
+ }
+ multiclass RISCVUSSegStore<int nf> {
+ def "int_riscv_" # NAME : RISCVUSSegStore<nf>;
+ def "int_riscv_" # NAME # "_mask" : RISCVUSSegStoreMask<nf>;
+ }
+ multiclass RISCVSSegStore<int nf> {
+ def "int_riscv_" # NAME : RISCVSSegStore<nf>;
+ def "int_riscv_" # NAME # "_mask" : RISCVSSegStoreMask<nf>;
+ }
+ multiclass RISCVISegStore<int nf> {
+ def "int_riscv_" # NAME : RISCVISegStore<nf>;
+ def "int_riscv_" # NAME # "_mask" : RISCVISegStoreMask<nf>;
+ }
+
+ defm vle : RISCVUSLoad;
+ defm vleff : RISCVUSLoadFF;
+ defm vse : RISCVUSStore;
+ defm vlse: RISCVSLoad;
+ defm vsse: RISCVSStore;
+ defm vluxei : RISCVILoad;
+ defm vloxei : RISCVILoad;
+ defm vsoxei : RISCVIStore;
+ defm vsuxei : RISCVIStore;
+
+ def int_riscv_vle1 : RISCVUSLoad;
+ def int_riscv_vse1 : RISCVUSStore;
+
+ defm vamoswap : RISCVAMO;
+ defm vamoadd : RISCVAMO;
+ defm vamoxor : RISCVAMO;
+ defm vamoand : RISCVAMO;
+ defm vamoor : RISCVAMO;
+ defm vamomin : RISCVAMO;
+ defm vamomax : RISCVAMO;
+ defm vamominu : RISCVAMO;
+ defm vamomaxu : RISCVAMO;
+
+ defm vadd : RISCVBinaryAAX;
+ defm vsub : RISCVBinaryAAX;
+ defm vrsub : RISCVBinaryAAX;
+
+ defm vwaddu : RISCVBinaryABX;
+ defm vwadd : RISCVBinaryABX;
+ defm vwaddu_w : RISCVBinaryAAX;
+ defm vwadd_w : RISCVBinaryAAX;
+ defm vwsubu : RISCVBinaryABX;
+ defm vwsub : RISCVBinaryABX;
+ defm vwsubu_w : RISCVBinaryAAX;
+ defm vwsub_w : RISCVBinaryAAX;
+
+ defm vzext : RISCVUnaryAB;
+ defm vsext : RISCVUnaryAB;
+
+ defm vadc : RISCVBinaryWithV0;
+ defm vmadc_carry_in : RISCVBinaryMaskOutWithV0;
+ defm vmadc : RISCVBinaryMaskOut;
+
+ defm vsbc : RISCVBinaryWithV0;
+ defm vmsbc_borrow_in : RISCVBinaryMaskOutWithV0;
+ defm vmsbc : RISCVBinaryMaskOut;
+
+ defm vand : RISCVBinaryAAX;
+ defm vor : RISCVBinaryAAX;
+ defm vxor : RISCVBinaryAAX;
+
+ defm vsll : RISCVBinaryAAX;
+ defm vsrl : RISCVBinaryAAX;
+ defm vsra : RISCVBinaryAAX;
+
+ defm vnsrl : RISCVBinaryABX;
+ defm vnsra : RISCVBinaryABX;
+
+ defm vmseq : RISCVCompare;
+ defm vmsne : RISCVCompare;
+ defm vmsltu : RISCVCompare;
+ defm vmslt : RISCVCompare;
+ defm vmsleu : RISCVCompare;
+ defm vmsle : RISCVCompare;
+ defm vmsgtu : RISCVCompare;
+ defm vmsgt : RISCVCompare;
+
+ defm vminu : RISCVBinaryAAX;
+ defm vmin : RISCVBinaryAAX;
+ defm vmaxu : RISCVBinaryAAX;
+ defm vmax : RISCVBinaryAAX;
+
+ defm vmul : RISCVBinaryAAX;
+ defm vmulh : RISCVBinaryAAX;
+ defm vmulhu : RISCVBinaryAAX;
+ defm vmulhsu : RISCVBinaryAAX;
+
+ defm vdivu : RISCVBinaryAAX;
+ defm vdiv : RISCVBinaryAAX;
+ defm vremu : RISCVBinaryAAX;
+ defm vrem : RISCVBinaryAAX;
+
+ defm vwmul : RISCVBinaryABX;
+ defm vwmulu : RISCVBinaryABX;
+ defm vwmulsu : RISCVBinaryABX;
+
+ defm vmacc : RISCVTernaryAAXA;
+ defm vnmsac : RISCVTernaryAAXA;
+ defm vmadd : RISCVTernaryAAXA;
+ defm vnmsub : RISCVTernaryAAXA;
+
+ defm vwmaccu : RISCVTernaryWide;
+ defm vwmacc : RISCVTernaryWide;
+ defm vwmaccus : RISCVTernaryWide;
+ defm vwmaccsu : RISCVTernaryWide;
+
+ defm vfadd : RISCVBinaryAAX;
+ defm vfsub : RISCVBinaryAAX;
+ defm vfrsub : RISCVBinaryAAX;
+
+ defm vfwadd : RISCVBinaryABX;
+ defm vfwsub : RISCVBinaryABX;
+ defm vfwadd_w : RISCVBinaryAAX;
+ defm vfwsub_w : RISCVBinaryAAX;
+
+ defm vsaddu : RISCVSaturatingBinaryAAX;
+ defm vsadd : RISCVSaturatingBinaryAAX;
+ defm vssubu : RISCVSaturatingBinaryAAX;
+ defm vssub : RISCVSaturatingBinaryAAX;
+
+ def int_riscv_vmerge : RISCVBinaryWithV0;
+
+ def int_riscv_vmv_v_v : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ def int_riscv_vmv_v_x : Intrinsic<[llvm_anyint_ty],
+ [LLVMVectorElementType<0>, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic {
+ let ExtendOperand = 1;
+ }
+ def int_riscv_vfmv_v_f : Intrinsic<[llvm_anyfloat_ty],
+ [LLVMVectorElementType<0>, llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+
+ def int_riscv_vmv_x_s : Intrinsic<[LLVMVectorElementType<0>],
+ [llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ def int_riscv_vmv_s_x : Intrinsic<[llvm_anyint_ty],
+ [LLVMMatchType<0>, LLVMVectorElementType<0>,
+ llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic {
+ let ExtendOperand = 2;
+ }
+
+ def int_riscv_vfmv_f_s : Intrinsic<[LLVMVectorElementType<0>],
+ [llvm_anyfloat_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ def int_riscv_vfmv_s_f : Intrinsic<[llvm_anyfloat_ty],
+ [LLVMMatchType<0>, LLVMVectorElementType<0>,
+ llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+
+ defm vfmul : RISCVBinaryAAX;
+ defm vfdiv : RISCVBinaryAAX;
+ defm vfrdiv : RISCVBinaryAAX;
+
+ defm vfwmul : RISCVBinaryABX;
+
+ defm vfmacc : RISCVTernaryAAXA;
+ defm vfnmacc : RISCVTernaryAAXA;
+ defm vfmsac : RISCVTernaryAAXA;
+ defm vfnmsac : RISCVTernaryAAXA;
+ defm vfmadd : RISCVTernaryAAXA;
+ defm vfnmadd : RISCVTernaryAAXA;
+ defm vfmsub : RISCVTernaryAAXA;
+ defm vfnmsub : RISCVTernaryAAXA;
+
+ defm vfwmacc : RISCVTernaryWide;
+ defm vfwnmacc : RISCVTernaryWide;
+ defm vfwmsac : RISCVTernaryWide;
+ defm vfwnmsac : RISCVTernaryWide;
+
+ defm vfsqrt : RISCVUnaryAA;
+ defm vfrsqrt7 : RISCVUnaryAA;
+ defm vfrec7 : RISCVUnaryAA;
+
+ defm vfmin : RISCVBinaryAAX;
+ defm vfmax : RISCVBinaryAAX;
+
+ defm vfsgnj : RISCVBinaryAAX;
+ defm vfsgnjn : RISCVBinaryAAX;
+ defm vfsgnjx : RISCVBinaryAAX;
+
+ defm vfclass : RISCVClassify;
+
+ defm vfmerge : RISCVBinaryWithV0;
+
+ defm vslideup : RISCVTernaryAAAX;
+ defm vslidedown : RISCVTernaryAAAX;
+
+ defm vslide1up : RISCVBinaryAAX;
+ defm vslide1down : RISCVBinaryAAX;
+ defm vfslide1up : RISCVBinaryAAX;
+ defm vfslide1down : RISCVBinaryAAX;
+
+ defm vrgather : RISCVBinaryAAX;
+ defm vrgatherei16 : RISCVBinaryAAX;
+
+ def "int_riscv_vcompress" : RISCVBinaryAAAMask;
+
+ defm vaaddu : RISCVSaturatingBinaryAAX;
+ defm vaadd : RISCVSaturatingBinaryAAX;
+ defm vasubu : RISCVSaturatingBinaryAAX;
+ defm vasub : RISCVSaturatingBinaryAAX;
+
+ defm vsmul : RISCVSaturatingBinaryAAX;
+
+ defm vssrl : RISCVSaturatingBinaryAAX;
+ defm vssra : RISCVSaturatingBinaryAAX;
+
+ defm vnclipu : RISCVSaturatingBinaryABX;
+ defm vnclip : RISCVSaturatingBinaryABX;
+
+ defm vmfeq : RISCVCompare;
+ defm vmfne : RISCVCompare;
+ defm vmflt : RISCVCompare;
+ defm vmfle : RISCVCompare;
+ defm vmfgt : RISCVCompare;
+ defm vmfge : RISCVCompare;
+
+ defm vredsum : RISCVReduction;
+ defm vredand : RISCVReduction;
+ defm vredor : RISCVReduction;
+ defm vredxor : RISCVReduction;
+ defm vredminu : RISCVReduction;
+ defm vredmin : RISCVReduction;
+ defm vredmaxu : RISCVReduction;
+ defm vredmax : RISCVReduction;
+
+ defm vwredsumu : RISCVReduction;
+ defm vwredsum : RISCVReduction;
+
+ defm vfredosum : RISCVReduction;
+ defm vfredsum : RISCVReduction;
+ defm vfredmin : RISCVReduction;
+ defm vfredmax : RISCVReduction;
+
+ defm vfwredsum : RISCVReduction;
+ defm vfwredosum : RISCVReduction;
+
+ def int_riscv_vmand: RISCVBinaryAAANoMask;
+ def int_riscv_vmnand: RISCVBinaryAAANoMask;
+ def int_riscv_vmandnot: RISCVBinaryAAANoMask;
+ def int_riscv_vmxor: RISCVBinaryAAANoMask;
+ def int_riscv_vmor: RISCVBinaryAAANoMask;
+ def int_riscv_vmnor: RISCVBinaryAAANoMask;
+ def int_riscv_vmornot: RISCVBinaryAAANoMask;
+ def int_riscv_vmxnor: RISCVBinaryAAANoMask;
+ def int_riscv_vmclr : RISCVNullaryIntrinsic;
+ def int_riscv_vmset : RISCVNullaryIntrinsic;
+
+ defm vpopc : RISCVMaskUnarySOut;
+ defm vfirst : RISCVMaskUnarySOut;
+ defm vmsbf : RISCVMaskUnaryMOut;
+ defm vmsof : RISCVMaskUnaryMOut;
+ defm vmsif : RISCVMaskUnaryMOut;
+
+ defm vfcvt_xu_f_v : RISCVConversion;
+ defm vfcvt_x_f_v : RISCVConversion;
+ defm vfcvt_rtz_xu_f_v : RISCVConversion;
+ defm vfcvt_rtz_x_f_v : RISCVConversion;
+ defm vfcvt_f_xu_v : RISCVConversion;
+ defm vfcvt_f_x_v : RISCVConversion;
+
+ defm vfwcvt_f_xu_v : RISCVConversion;
+ defm vfwcvt_f_x_v : RISCVConversion;
+ defm vfwcvt_xu_f_v : RISCVConversion;
+ defm vfwcvt_x_f_v : RISCVConversion;
+ defm vfwcvt_rtz_xu_f_v : RISCVConversion;
+ defm vfwcvt_rtz_x_f_v : RISCVConversion;
+ defm vfwcvt_f_f_v : RISCVConversion;
+
+ defm vfncvt_f_xu_w : RISCVConversion;
+ defm vfncvt_f_x_w : RISCVConversion;
+ defm vfncvt_xu_f_w : RISCVConversion;
+ defm vfncvt_x_f_w : RISCVConversion;
+ defm vfncvt_rtz_xu_f_w : RISCVConversion;
+ defm vfncvt_rtz_x_f_w : RISCVConversion;
+ defm vfncvt_f_f_w : RISCVConversion;
+ defm vfncvt_rod_f_f_w : RISCVConversion;
+
+ // Output: (vector)
+ // Input: (mask type input, vl)
+ def int_riscv_viota : Intrinsic<[llvm_anyvector_ty],
+ [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // Output: (vector)
+ // Input: (maskedoff, mask type vector_in, mask, vl)
+ def int_riscv_viota_mask : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+ // Output: (vector)
+ // Input: (vl)
+ def int_riscv_vid : RISCVNullaryIntrinsic;
+
+ // Output: (vector)
+ // Input: (maskedoff, mask, vl)
+ def int_riscv_vid_mask : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_anyint_ty],
+ [IntrNoMem]>, RISCVVIntrinsic;
+
+ foreach nf = [2, 3, 4, 5, 6, 7, 8] in {
+ defm vlseg # nf : RISCVUSSegLoad<nf>;
+ defm vlseg # nf # ff : RISCVUSSegLoadFF<nf>;
+ defm vlsseg # nf : RISCVSSegLoad<nf>;
+ defm vloxseg # nf : RISCVISegLoad<nf>;
+ defm vluxseg # nf : RISCVISegLoad<nf>;
+ defm vsseg # nf : RISCVUSSegStore<nf>;
+ defm vssseg # nf : RISCVSSegStore<nf>;
+ defm vsoxseg # nf : RISCVISegStore<nf>;
+ defm vsuxseg # nf : RISCVISegStore<nf>;
+ }
+
+} // TargetPrefix = "riscv"
diff --git a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsVE.td b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsVE.td
index 128af17b18..be4bccef0c 100644
--- a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsVE.td
+++ b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsVE.td
@@ -1,35 +1,35 @@
-// Define intrinsics written by hand
-
-// VEL Intrinsic instructions.
-let TargetPrefix = "ve" in {
- def int_ve_vl_svob : GCCBuiltin<"__builtin_ve_vl_svob">,
- Intrinsic<[], [], [IntrHasSideEffects]>;
-
- def int_ve_vl_pack_f32p : GCCBuiltin<"__builtin_ve_vl_pack_f32p">,
- Intrinsic<[llvm_i64_ty], [llvm_ptr_ty, llvm_ptr_ty],
- [IntrReadMem]>;
- def int_ve_vl_pack_f32a : GCCBuiltin<"__builtin_ve_vl_pack_f32a">,
- Intrinsic<[llvm_i64_ty], [llvm_ptr_ty],
- [IntrReadMem]>;
-
- def int_ve_vl_extract_vm512u :
- GCCBuiltin<"__builtin_ve_vl_extract_vm512u">,
- Intrinsic<[LLVMType<v256i1>], [LLVMType<v512i1>], [IntrNoMem]>;
-
- def int_ve_vl_extract_vm512l :
- GCCBuiltin<"__builtin_ve_vl_extract_vm512l">,
- Intrinsic<[LLVMType<v256i1>], [LLVMType<v512i1>], [IntrNoMem]>;
-
- def int_ve_vl_insert_vm512u :
- GCCBuiltin<"__builtin_ve_vl_insert_vm512u">,
- Intrinsic<[LLVMType<v512i1>], [LLVMType<v512i1>, LLVMType<v256i1>],
- [IntrNoMem]>;
-
- def int_ve_vl_insert_vm512l :
- GCCBuiltin<"__builtin_ve_vl_insert_vm512l">,
- Intrinsic<[LLVMType<v512i1>], [LLVMType<v512i1>, LLVMType<v256i1>],
- [IntrNoMem]>;
-}
-
-// Define intrinsics automatically generated
-include "llvm/IR/IntrinsicsVEVL.gen.td"
+// Define intrinsics written by hand
+
+// VEL Intrinsic instructions.
+let TargetPrefix = "ve" in {
+ def int_ve_vl_svob : GCCBuiltin<"__builtin_ve_vl_svob">,
+ Intrinsic<[], [], [IntrHasSideEffects]>;
+
+ def int_ve_vl_pack_f32p : GCCBuiltin<"__builtin_ve_vl_pack_f32p">,
+ Intrinsic<[llvm_i64_ty], [llvm_ptr_ty, llvm_ptr_ty],
+ [IntrReadMem]>;
+ def int_ve_vl_pack_f32a : GCCBuiltin<"__builtin_ve_vl_pack_f32a">,
+ Intrinsic<[llvm_i64_ty], [llvm_ptr_ty],
+ [IntrReadMem]>;
+
+ def int_ve_vl_extract_vm512u :
+ GCCBuiltin<"__builtin_ve_vl_extract_vm512u">,
+ Intrinsic<[LLVMType<v256i1>], [LLVMType<v512i1>], [IntrNoMem]>;
+
+ def int_ve_vl_extract_vm512l :
+ GCCBuiltin<"__builtin_ve_vl_extract_vm512l">,
+ Intrinsic<[LLVMType<v256i1>], [LLVMType<v512i1>], [IntrNoMem]>;
+
+ def int_ve_vl_insert_vm512u :
+ GCCBuiltin<"__builtin_ve_vl_insert_vm512u">,
+ Intrinsic<[LLVMType<v512i1>], [LLVMType<v512i1>, LLVMType<v256i1>],
+ [IntrNoMem]>;
+
+ def int_ve_vl_insert_vm512l :
+ GCCBuiltin<"__builtin_ve_vl_insert_vm512l">,
+ Intrinsic<[LLVMType<v512i1>], [LLVMType<v512i1>, LLVMType<v256i1>],
+ [IntrNoMem]>;
+}
+
+// Define intrinsics automatically generated
+include "llvm/IR/IntrinsicsVEVL.gen.td"
diff --git a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsVEVL.gen.td b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsVEVL.gen.td
index 93d5f5c530..67cbd30790 100644
--- a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsVEVL.gen.td
+++ b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsVEVL.gen.td
@@ -1,1213 +1,1213 @@
-let TargetPrefix = "ve" in def int_ve_vl_vld_vssl : GCCBuiltin<"__builtin_ve_vl_vld_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vld_vssvl : GCCBuiltin<"__builtin_ve_vl_vld_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldnc_vssl : GCCBuiltin<"__builtin_ve_vl_vldnc_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldnc_vssvl : GCCBuiltin<"__builtin_ve_vl_vldnc_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldu_vssl : GCCBuiltin<"__builtin_ve_vl_vldu_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldu_vssvl : GCCBuiltin<"__builtin_ve_vl_vldu_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldunc_vssl : GCCBuiltin<"__builtin_ve_vl_vldunc_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldunc_vssvl : GCCBuiltin<"__builtin_ve_vl_vldunc_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldlsx_vssl : GCCBuiltin<"__builtin_ve_vl_vldlsx_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldlsx_vssvl : GCCBuiltin<"__builtin_ve_vl_vldlsx_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldlsxnc_vssl : GCCBuiltin<"__builtin_ve_vl_vldlsxnc_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldlsxnc_vssvl : GCCBuiltin<"__builtin_ve_vl_vldlsxnc_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldlzx_vssl : GCCBuiltin<"__builtin_ve_vl_vldlzx_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldlzx_vssvl : GCCBuiltin<"__builtin_ve_vl_vldlzx_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldlzxnc_vssl : GCCBuiltin<"__builtin_ve_vl_vldlzxnc_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldlzxnc_vssvl : GCCBuiltin<"__builtin_ve_vl_vldlzxnc_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vld2d_vssl : GCCBuiltin<"__builtin_ve_vl_vld2d_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vld2d_vssvl : GCCBuiltin<"__builtin_ve_vl_vld2d_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vld2dnc_vssl : GCCBuiltin<"__builtin_ve_vl_vld2dnc_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vld2dnc_vssvl : GCCBuiltin<"__builtin_ve_vl_vld2dnc_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldu2d_vssl : GCCBuiltin<"__builtin_ve_vl_vldu2d_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldu2d_vssvl : GCCBuiltin<"__builtin_ve_vl_vldu2d_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldu2dnc_vssl : GCCBuiltin<"__builtin_ve_vl_vldu2dnc_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldu2dnc_vssvl : GCCBuiltin<"__builtin_ve_vl_vldu2dnc_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldl2dsx_vssl : GCCBuiltin<"__builtin_ve_vl_vldl2dsx_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldl2dsx_vssvl : GCCBuiltin<"__builtin_ve_vl_vldl2dsx_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldl2dsxnc_vssl : GCCBuiltin<"__builtin_ve_vl_vldl2dsxnc_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldl2dsxnc_vssvl : GCCBuiltin<"__builtin_ve_vl_vldl2dsxnc_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldl2dzx_vssl : GCCBuiltin<"__builtin_ve_vl_vldl2dzx_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldl2dzx_vssvl : GCCBuiltin<"__builtin_ve_vl_vldl2dzx_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldl2dzxnc_vssl : GCCBuiltin<"__builtin_ve_vl_vldl2dzxnc_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vldl2dzxnc_vssvl : GCCBuiltin<"__builtin_ve_vl_vldl2dzxnc_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vst_vssl : GCCBuiltin<"__builtin_ve_vl_vst_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vst_vssml : GCCBuiltin<"__builtin_ve_vl_vst_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstnc_vssl : GCCBuiltin<"__builtin_ve_vl_vstnc_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstnc_vssml : GCCBuiltin<"__builtin_ve_vl_vstnc_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstot_vssl : GCCBuiltin<"__builtin_ve_vl_vstot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstot_vssml : GCCBuiltin<"__builtin_ve_vl_vstot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstncot_vssl : GCCBuiltin<"__builtin_ve_vl_vstncot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstncot_vssml : GCCBuiltin<"__builtin_ve_vl_vstncot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstu_vssl : GCCBuiltin<"__builtin_ve_vl_vstu_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstu_vssml : GCCBuiltin<"__builtin_ve_vl_vstu_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstunc_vssl : GCCBuiltin<"__builtin_ve_vl_vstunc_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstunc_vssml : GCCBuiltin<"__builtin_ve_vl_vstunc_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstuot_vssl : GCCBuiltin<"__builtin_ve_vl_vstuot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstuot_vssml : GCCBuiltin<"__builtin_ve_vl_vstuot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstuncot_vssl : GCCBuiltin<"__builtin_ve_vl_vstuncot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstuncot_vssml : GCCBuiltin<"__builtin_ve_vl_vstuncot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstl_vssl : GCCBuiltin<"__builtin_ve_vl_vstl_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstl_vssml : GCCBuiltin<"__builtin_ve_vl_vstl_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstlnc_vssl : GCCBuiltin<"__builtin_ve_vl_vstlnc_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstlnc_vssml : GCCBuiltin<"__builtin_ve_vl_vstlnc_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstlot_vssl : GCCBuiltin<"__builtin_ve_vl_vstlot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstlot_vssml : GCCBuiltin<"__builtin_ve_vl_vstlot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstlncot_vssl : GCCBuiltin<"__builtin_ve_vl_vstlncot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstlncot_vssml : GCCBuiltin<"__builtin_ve_vl_vstlncot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vst2d_vssl : GCCBuiltin<"__builtin_ve_vl_vst2d_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vst2d_vssml : GCCBuiltin<"__builtin_ve_vl_vst2d_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vst2dnc_vssl : GCCBuiltin<"__builtin_ve_vl_vst2dnc_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vst2dnc_vssml : GCCBuiltin<"__builtin_ve_vl_vst2dnc_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vst2dot_vssl : GCCBuiltin<"__builtin_ve_vl_vst2dot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vst2dot_vssml : GCCBuiltin<"__builtin_ve_vl_vst2dot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vst2dncot_vssl : GCCBuiltin<"__builtin_ve_vl_vst2dncot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vst2dncot_vssml : GCCBuiltin<"__builtin_ve_vl_vst2dncot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstu2d_vssl : GCCBuiltin<"__builtin_ve_vl_vstu2d_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstu2d_vssml : GCCBuiltin<"__builtin_ve_vl_vstu2d_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstu2dnc_vssl : GCCBuiltin<"__builtin_ve_vl_vstu2dnc_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstu2dnc_vssml : GCCBuiltin<"__builtin_ve_vl_vstu2dnc_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstu2dot_vssl : GCCBuiltin<"__builtin_ve_vl_vstu2dot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstu2dot_vssml : GCCBuiltin<"__builtin_ve_vl_vstu2dot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstu2dncot_vssl : GCCBuiltin<"__builtin_ve_vl_vstu2dncot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstu2dncot_vssml : GCCBuiltin<"__builtin_ve_vl_vstu2dncot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstl2d_vssl : GCCBuiltin<"__builtin_ve_vl_vstl2d_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstl2d_vssml : GCCBuiltin<"__builtin_ve_vl_vstl2d_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstl2dnc_vssl : GCCBuiltin<"__builtin_ve_vl_vstl2dnc_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstl2dnc_vssml : GCCBuiltin<"__builtin_ve_vl_vstl2dnc_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstl2dot_vssl : GCCBuiltin<"__builtin_ve_vl_vstl2dot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstl2dot_vssml : GCCBuiltin<"__builtin_ve_vl_vstl2dot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstl2dncot_vssl : GCCBuiltin<"__builtin_ve_vl_vstl2dncot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vstl2dncot_vssml : GCCBuiltin<"__builtin_ve_vl_vstl2dncot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pfchv_ssl : GCCBuiltin<"__builtin_ve_vl_pfchv_ssl">, Intrinsic<[], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrInaccessibleMemOrArgMemOnly]>;
-let TargetPrefix = "ve" in def int_ve_vl_pfchvnc_ssl : GCCBuiltin<"__builtin_ve_vl_pfchvnc_ssl">, Intrinsic<[], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrInaccessibleMemOrArgMemOnly]>;
-let TargetPrefix = "ve" in def int_ve_vl_lsv_vvss : GCCBuiltin<"__builtin_ve_vl_lsv_vvss">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<i64>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_lvsl_svs : GCCBuiltin<"__builtin_ve_vl_lvsl_svs">, Intrinsic<[LLVMType<i64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_lvsd_svs : GCCBuiltin<"__builtin_ve_vl_lvsd_svs">, Intrinsic<[LLVMType<f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_lvss_svs : GCCBuiltin<"__builtin_ve_vl_lvss_svs">, Intrinsic<[LLVMType<f32>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_lvm_mmss : GCCBuiltin<"__builtin_ve_vl_lvm_mmss">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256i1>, LLVMType<i64>, LLVMType<i64>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_lvm_MMss : GCCBuiltin<"__builtin_ve_vl_lvm_MMss">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v512i1>, LLVMType<i64>, LLVMType<i64>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_svm_sms : GCCBuiltin<"__builtin_ve_vl_svm_sms">, Intrinsic<[LLVMType<i64>], [LLVMType<v256i1>, LLVMType<i64>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_svm_sMs : GCCBuiltin<"__builtin_ve_vl_svm_sMs">, Intrinsic<[LLVMType<i64>], [LLVMType<v512i1>, LLVMType<i64>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vbrdd_vsl : GCCBuiltin<"__builtin_ve_vl_vbrdd_vsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vbrdd_vsvl : GCCBuiltin<"__builtin_ve_vl_vbrdd_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vbrdd_vsmvl : GCCBuiltin<"__builtin_ve_vl_vbrdd_vsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vbrdl_vsl : GCCBuiltin<"__builtin_ve_vl_vbrdl_vsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vbrdl_vsvl : GCCBuiltin<"__builtin_ve_vl_vbrdl_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vbrdl_vsmvl : GCCBuiltin<"__builtin_ve_vl_vbrdl_vsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vbrds_vsl : GCCBuiltin<"__builtin_ve_vl_vbrds_vsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vbrds_vsvl : GCCBuiltin<"__builtin_ve_vl_vbrds_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vbrds_vsmvl : GCCBuiltin<"__builtin_ve_vl_vbrds_vsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vbrdw_vsl : GCCBuiltin<"__builtin_ve_vl_vbrdw_vsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vbrdw_vsvl : GCCBuiltin<"__builtin_ve_vl_vbrdw_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vbrdw_vsmvl : GCCBuiltin<"__builtin_ve_vl_vbrdw_vsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvbrd_vsl : GCCBuiltin<"__builtin_ve_vl_pvbrd_vsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvbrd_vsvl : GCCBuiltin<"__builtin_ve_vl_pvbrd_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvbrd_vsMvl : GCCBuiltin<"__builtin_ve_vl_pvbrd_vsMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmv_vsvl : GCCBuiltin<"__builtin_ve_vl_vmv_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmv_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmv_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmv_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmv_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddul_vvvl : GCCBuiltin<"__builtin_ve_vl_vaddul_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddul_vvvvl : GCCBuiltin<"__builtin_ve_vl_vaddul_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddul_vsvl : GCCBuiltin<"__builtin_ve_vl_vaddul_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddul_vsvvl : GCCBuiltin<"__builtin_ve_vl_vaddul_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddul_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vaddul_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddul_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vaddul_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vadduw_vvvl : GCCBuiltin<"__builtin_ve_vl_vadduw_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vadduw_vvvvl : GCCBuiltin<"__builtin_ve_vl_vadduw_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vadduw_vsvl : GCCBuiltin<"__builtin_ve_vl_vadduw_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vadduw_vsvvl : GCCBuiltin<"__builtin_ve_vl_vadduw_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vadduw_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vadduw_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vadduw_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vadduw_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvaddu_vvvl : GCCBuiltin<"__builtin_ve_vl_pvaddu_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvaddu_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvaddu_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvaddu_vsvl : GCCBuiltin<"__builtin_ve_vl_pvaddu_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvaddu_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvaddu_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvaddu_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvaddu_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvaddu_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvaddu_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddswsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vaddswsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddswsx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vaddswsx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddswsx_vsvl : GCCBuiltin<"__builtin_ve_vl_vaddswsx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddswsx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vaddswsx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddswsx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vaddswsx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddswsx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vaddswsx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddswzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vaddswzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddswzx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vaddswzx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddswzx_vsvl : GCCBuiltin<"__builtin_ve_vl_vaddswzx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddswzx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vaddswzx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddswzx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vaddswzx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddswzx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vaddswzx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvadds_vvvl : GCCBuiltin<"__builtin_ve_vl_pvadds_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvadds_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvadds_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvadds_vsvl : GCCBuiltin<"__builtin_ve_vl_pvadds_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvadds_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvadds_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvadds_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvadds_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvadds_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvadds_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddsl_vvvl : GCCBuiltin<"__builtin_ve_vl_vaddsl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddsl_vvvvl : GCCBuiltin<"__builtin_ve_vl_vaddsl_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddsl_vsvl : GCCBuiltin<"__builtin_ve_vl_vaddsl_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddsl_vsvvl : GCCBuiltin<"__builtin_ve_vl_vaddsl_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddsl_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vaddsl_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vaddsl_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vaddsl_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubul_vvvl : GCCBuiltin<"__builtin_ve_vl_vsubul_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubul_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsubul_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubul_vsvl : GCCBuiltin<"__builtin_ve_vl_vsubul_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubul_vsvvl : GCCBuiltin<"__builtin_ve_vl_vsubul_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubul_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsubul_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubul_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vsubul_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubuw_vvvl : GCCBuiltin<"__builtin_ve_vl_vsubuw_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubuw_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsubuw_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubuw_vsvl : GCCBuiltin<"__builtin_ve_vl_vsubuw_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubuw_vsvvl : GCCBuiltin<"__builtin_ve_vl_vsubuw_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubuw_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsubuw_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubuw_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vsubuw_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsubu_vvvl : GCCBuiltin<"__builtin_ve_vl_pvsubu_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsubu_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvsubu_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsubu_vsvl : GCCBuiltin<"__builtin_ve_vl_pvsubu_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsubu_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvsubu_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsubu_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvsubu_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsubu_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvsubu_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubswsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vsubswsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubswsx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsubswsx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubswsx_vsvl : GCCBuiltin<"__builtin_ve_vl_vsubswsx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubswsx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vsubswsx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubswsx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsubswsx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubswsx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vsubswsx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubswzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vsubswzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubswzx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsubswzx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubswzx_vsvl : GCCBuiltin<"__builtin_ve_vl_vsubswzx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubswzx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vsubswzx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubswzx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsubswzx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubswzx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vsubswzx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsubs_vvvl : GCCBuiltin<"__builtin_ve_vl_pvsubs_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsubs_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvsubs_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsubs_vsvl : GCCBuiltin<"__builtin_ve_vl_pvsubs_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsubs_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvsubs_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsubs_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvsubs_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsubs_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvsubs_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubsl_vvvl : GCCBuiltin<"__builtin_ve_vl_vsubsl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubsl_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsubsl_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubsl_vsvl : GCCBuiltin<"__builtin_ve_vl_vsubsl_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubsl_vsvvl : GCCBuiltin<"__builtin_ve_vl_vsubsl_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubsl_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsubsl_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsubsl_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vsubsl_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulul_vvvl : GCCBuiltin<"__builtin_ve_vl_vmulul_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulul_vvvvl : GCCBuiltin<"__builtin_ve_vl_vmulul_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulul_vsvl : GCCBuiltin<"__builtin_ve_vl_vmulul_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulul_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmulul_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulul_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vmulul_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulul_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmulul_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmuluw_vvvl : GCCBuiltin<"__builtin_ve_vl_vmuluw_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmuluw_vvvvl : GCCBuiltin<"__builtin_ve_vl_vmuluw_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmuluw_vsvl : GCCBuiltin<"__builtin_ve_vl_vmuluw_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmuluw_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmuluw_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmuluw_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vmuluw_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmuluw_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmuluw_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulswsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vmulswsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulswsx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vmulswsx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulswsx_vsvl : GCCBuiltin<"__builtin_ve_vl_vmulswsx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulswsx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmulswsx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulswsx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vmulswsx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulswsx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmulswsx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulswzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vmulswzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulswzx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vmulswzx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulswzx_vsvl : GCCBuiltin<"__builtin_ve_vl_vmulswzx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulswzx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmulswzx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulswzx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vmulswzx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulswzx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmulswzx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulsl_vvvl : GCCBuiltin<"__builtin_ve_vl_vmulsl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulsl_vvvvl : GCCBuiltin<"__builtin_ve_vl_vmulsl_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulsl_vsvl : GCCBuiltin<"__builtin_ve_vl_vmulsl_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulsl_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmulsl_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulsl_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vmulsl_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulsl_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmulsl_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulslw_vvvl : GCCBuiltin<"__builtin_ve_vl_vmulslw_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulslw_vvvvl : GCCBuiltin<"__builtin_ve_vl_vmulslw_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulslw_vsvl : GCCBuiltin<"__builtin_ve_vl_vmulslw_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmulslw_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmulslw_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivul_vvvl : GCCBuiltin<"__builtin_ve_vl_vdivul_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivul_vvvvl : GCCBuiltin<"__builtin_ve_vl_vdivul_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivul_vsvl : GCCBuiltin<"__builtin_ve_vl_vdivul_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivul_vsvvl : GCCBuiltin<"__builtin_ve_vl_vdivul_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivul_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vdivul_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivul_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vdivul_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivuw_vvvl : GCCBuiltin<"__builtin_ve_vl_vdivuw_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivuw_vvvvl : GCCBuiltin<"__builtin_ve_vl_vdivuw_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivuw_vsvl : GCCBuiltin<"__builtin_ve_vl_vdivuw_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivuw_vsvvl : GCCBuiltin<"__builtin_ve_vl_vdivuw_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivuw_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vdivuw_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivuw_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vdivuw_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivul_vvsl : GCCBuiltin<"__builtin_ve_vl_vdivul_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivul_vvsvl : GCCBuiltin<"__builtin_ve_vl_vdivul_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivul_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vdivul_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivuw_vvsl : GCCBuiltin<"__builtin_ve_vl_vdivuw_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivuw_vvsvl : GCCBuiltin<"__builtin_ve_vl_vdivuw_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivuw_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vdivuw_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivswsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vdivswsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivswsx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vdivswsx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivswsx_vsvl : GCCBuiltin<"__builtin_ve_vl_vdivswsx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivswsx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vdivswsx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivswsx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vdivswsx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivswsx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vdivswsx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivswzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vdivswzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivswzx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vdivswzx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivswzx_vsvl : GCCBuiltin<"__builtin_ve_vl_vdivswzx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivswzx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vdivswzx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivswzx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vdivswzx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivswzx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vdivswzx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivswsx_vvsl : GCCBuiltin<"__builtin_ve_vl_vdivswsx_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivswsx_vvsvl : GCCBuiltin<"__builtin_ve_vl_vdivswsx_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivswsx_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vdivswsx_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivswzx_vvsl : GCCBuiltin<"__builtin_ve_vl_vdivswzx_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivswzx_vvsvl : GCCBuiltin<"__builtin_ve_vl_vdivswzx_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivswzx_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vdivswzx_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivsl_vvvl : GCCBuiltin<"__builtin_ve_vl_vdivsl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivsl_vvvvl : GCCBuiltin<"__builtin_ve_vl_vdivsl_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivsl_vsvl : GCCBuiltin<"__builtin_ve_vl_vdivsl_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivsl_vsvvl : GCCBuiltin<"__builtin_ve_vl_vdivsl_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivsl_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vdivsl_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivsl_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vdivsl_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivsl_vvsl : GCCBuiltin<"__builtin_ve_vl_vdivsl_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivsl_vvsvl : GCCBuiltin<"__builtin_ve_vl_vdivsl_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vdivsl_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vdivsl_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpul_vvvl : GCCBuiltin<"__builtin_ve_vl_vcmpul_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpul_vvvvl : GCCBuiltin<"__builtin_ve_vl_vcmpul_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpul_vsvl : GCCBuiltin<"__builtin_ve_vl_vcmpul_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpul_vsvvl : GCCBuiltin<"__builtin_ve_vl_vcmpul_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpul_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpul_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpul_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpul_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpuw_vvvl : GCCBuiltin<"__builtin_ve_vl_vcmpuw_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpuw_vvvvl : GCCBuiltin<"__builtin_ve_vl_vcmpuw_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpuw_vsvl : GCCBuiltin<"__builtin_ve_vl_vcmpuw_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpuw_vsvvl : GCCBuiltin<"__builtin_ve_vl_vcmpuw_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpuw_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpuw_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpuw_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpuw_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcmpu_vvvl : GCCBuiltin<"__builtin_ve_vl_pvcmpu_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcmpu_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvcmpu_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcmpu_vsvl : GCCBuiltin<"__builtin_ve_vl_pvcmpu_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcmpu_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvcmpu_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcmpu_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvcmpu_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcmpu_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvcmpu_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpswsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vcmpswsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpswsx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vcmpswsx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpswsx_vsvl : GCCBuiltin<"__builtin_ve_vl_vcmpswsx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpswsx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vcmpswsx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpswsx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpswsx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpswsx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpswsx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpswzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vcmpswzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpswzx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vcmpswzx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpswzx_vsvl : GCCBuiltin<"__builtin_ve_vl_vcmpswzx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpswzx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vcmpswzx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpswzx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpswzx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpswzx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpswzx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcmps_vvvl : GCCBuiltin<"__builtin_ve_vl_pvcmps_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcmps_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvcmps_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcmps_vsvl : GCCBuiltin<"__builtin_ve_vl_pvcmps_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcmps_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvcmps_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcmps_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvcmps_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcmps_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvcmps_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpsl_vvvl : GCCBuiltin<"__builtin_ve_vl_vcmpsl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpsl_vvvvl : GCCBuiltin<"__builtin_ve_vl_vcmpsl_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpsl_vsvl : GCCBuiltin<"__builtin_ve_vl_vcmpsl_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpsl_vsvvl : GCCBuiltin<"__builtin_ve_vl_vcmpsl_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpsl_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpsl_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcmpsl_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpsl_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmaxswsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vmaxswsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmaxswsx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vmaxswsx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmaxswsx_vsvl : GCCBuiltin<"__builtin_ve_vl_vmaxswsx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmaxswsx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmaxswsx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmaxswsx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vmaxswsx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmaxswsx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmaxswsx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmaxswzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vmaxswzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmaxswzx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vmaxswzx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmaxswzx_vsvl : GCCBuiltin<"__builtin_ve_vl_vmaxswzx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmaxswzx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmaxswzx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmaxswzx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vmaxswzx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmaxswzx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmaxswzx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvmaxs_vvvl : GCCBuiltin<"__builtin_ve_vl_pvmaxs_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvmaxs_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvmaxs_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvmaxs_vsvl : GCCBuiltin<"__builtin_ve_vl_pvmaxs_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvmaxs_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvmaxs_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvmaxs_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvmaxs_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvmaxs_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvmaxs_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vminswsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vminswsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vminswsx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vminswsx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vminswsx_vsvl : GCCBuiltin<"__builtin_ve_vl_vminswsx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vminswsx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vminswsx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vminswsx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vminswsx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vminswsx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vminswsx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vminswzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vminswzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vminswzx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vminswzx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vminswzx_vsvl : GCCBuiltin<"__builtin_ve_vl_vminswzx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vminswzx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vminswzx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vminswzx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vminswzx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vminswzx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vminswzx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvmins_vvvl : GCCBuiltin<"__builtin_ve_vl_pvmins_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvmins_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvmins_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvmins_vsvl : GCCBuiltin<"__builtin_ve_vl_pvmins_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvmins_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvmins_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvmins_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvmins_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvmins_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvmins_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmaxsl_vvvl : GCCBuiltin<"__builtin_ve_vl_vmaxsl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmaxsl_vvvvl : GCCBuiltin<"__builtin_ve_vl_vmaxsl_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmaxsl_vsvl : GCCBuiltin<"__builtin_ve_vl_vmaxsl_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmaxsl_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmaxsl_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmaxsl_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vmaxsl_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmaxsl_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmaxsl_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vminsl_vvvl : GCCBuiltin<"__builtin_ve_vl_vminsl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vminsl_vvvvl : GCCBuiltin<"__builtin_ve_vl_vminsl_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vminsl_vsvl : GCCBuiltin<"__builtin_ve_vl_vminsl_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vminsl_vsvvl : GCCBuiltin<"__builtin_ve_vl_vminsl_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vminsl_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vminsl_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vminsl_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vminsl_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vand_vvvl : GCCBuiltin<"__builtin_ve_vl_vand_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vand_vvvvl : GCCBuiltin<"__builtin_ve_vl_vand_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vand_vsvl : GCCBuiltin<"__builtin_ve_vl_vand_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vand_vsvvl : GCCBuiltin<"__builtin_ve_vl_vand_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vand_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vand_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vand_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vand_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvand_vvvl : GCCBuiltin<"__builtin_ve_vl_pvand_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvand_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvand_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvand_vsvl : GCCBuiltin<"__builtin_ve_vl_pvand_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvand_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvand_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvand_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvand_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvand_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvand_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vor_vvvl : GCCBuiltin<"__builtin_ve_vl_vor_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vor_vvvvl : GCCBuiltin<"__builtin_ve_vl_vor_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vor_vsvl : GCCBuiltin<"__builtin_ve_vl_vor_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vor_vsvvl : GCCBuiltin<"__builtin_ve_vl_vor_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vor_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vor_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vor_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vor_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvor_vvvl : GCCBuiltin<"__builtin_ve_vl_pvor_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvor_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvor_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvor_vsvl : GCCBuiltin<"__builtin_ve_vl_pvor_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvor_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvor_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvor_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvor_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvor_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvor_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vxor_vvvl : GCCBuiltin<"__builtin_ve_vl_vxor_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vxor_vvvvl : GCCBuiltin<"__builtin_ve_vl_vxor_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vxor_vsvl : GCCBuiltin<"__builtin_ve_vl_vxor_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vxor_vsvvl : GCCBuiltin<"__builtin_ve_vl_vxor_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vxor_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vxor_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vxor_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vxor_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvxor_vvvl : GCCBuiltin<"__builtin_ve_vl_pvxor_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvxor_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvxor_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvxor_vsvl : GCCBuiltin<"__builtin_ve_vl_pvxor_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvxor_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvxor_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvxor_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvxor_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvxor_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvxor_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_veqv_vvvl : GCCBuiltin<"__builtin_ve_vl_veqv_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_veqv_vvvvl : GCCBuiltin<"__builtin_ve_vl_veqv_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_veqv_vsvl : GCCBuiltin<"__builtin_ve_vl_veqv_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_veqv_vsvvl : GCCBuiltin<"__builtin_ve_vl_veqv_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_veqv_vvvmvl : GCCBuiltin<"__builtin_ve_vl_veqv_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_veqv_vsvmvl : GCCBuiltin<"__builtin_ve_vl_veqv_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pveqv_vvvl : GCCBuiltin<"__builtin_ve_vl_pveqv_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pveqv_vvvvl : GCCBuiltin<"__builtin_ve_vl_pveqv_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pveqv_vsvl : GCCBuiltin<"__builtin_ve_vl_pveqv_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pveqv_vsvvl : GCCBuiltin<"__builtin_ve_vl_pveqv_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pveqv_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pveqv_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pveqv_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pveqv_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vseq_vl : GCCBuiltin<"__builtin_ve_vl_vseq_vl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vseq_vvl : GCCBuiltin<"__builtin_ve_vl_vseq_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvseqlo_vl : GCCBuiltin<"__builtin_ve_vl_pvseqlo_vl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvseqlo_vvl : GCCBuiltin<"__builtin_ve_vl_pvseqlo_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsequp_vl : GCCBuiltin<"__builtin_ve_vl_pvsequp_vl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsequp_vvl : GCCBuiltin<"__builtin_ve_vl_pvsequp_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvseq_vl : GCCBuiltin<"__builtin_ve_vl_pvseq_vl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvseq_vvl : GCCBuiltin<"__builtin_ve_vl_pvseq_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsll_vvvl : GCCBuiltin<"__builtin_ve_vl_vsll_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsll_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsll_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsll_vvsl : GCCBuiltin<"__builtin_ve_vl_vsll_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsll_vvsvl : GCCBuiltin<"__builtin_ve_vl_vsll_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsll_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsll_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsll_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vsll_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsll_vvvl : GCCBuiltin<"__builtin_ve_vl_pvsll_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsll_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvsll_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsll_vvsl : GCCBuiltin<"__builtin_ve_vl_pvsll_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsll_vvsvl : GCCBuiltin<"__builtin_ve_vl_pvsll_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsll_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvsll_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsll_vvsMvl : GCCBuiltin<"__builtin_ve_vl_pvsll_vvsMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsrl_vvvl : GCCBuiltin<"__builtin_ve_vl_vsrl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsrl_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsrl_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsrl_vvsl : GCCBuiltin<"__builtin_ve_vl_vsrl_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsrl_vvsvl : GCCBuiltin<"__builtin_ve_vl_vsrl_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsrl_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsrl_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsrl_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vsrl_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsrl_vvvl : GCCBuiltin<"__builtin_ve_vl_pvsrl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsrl_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvsrl_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsrl_vvsl : GCCBuiltin<"__builtin_ve_vl_pvsrl_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsrl_vvsvl : GCCBuiltin<"__builtin_ve_vl_pvsrl_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsrl_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvsrl_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsrl_vvsMvl : GCCBuiltin<"__builtin_ve_vl_pvsrl_vvsMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vslawsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vslawsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vslawsx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vslawsx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vslawsx_vvsl : GCCBuiltin<"__builtin_ve_vl_vslawsx_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vslawsx_vvsvl : GCCBuiltin<"__builtin_ve_vl_vslawsx_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vslawsx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vslawsx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vslawsx_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vslawsx_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vslawzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vslawzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vslawzx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vslawzx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vslawzx_vvsl : GCCBuiltin<"__builtin_ve_vl_vslawzx_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vslawzx_vvsvl : GCCBuiltin<"__builtin_ve_vl_vslawzx_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vslawzx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vslawzx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vslawzx_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vslawzx_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsla_vvvl : GCCBuiltin<"__builtin_ve_vl_pvsla_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsla_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvsla_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsla_vvsl : GCCBuiltin<"__builtin_ve_vl_pvsla_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsla_vvsvl : GCCBuiltin<"__builtin_ve_vl_pvsla_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsla_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvsla_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsla_vvsMvl : GCCBuiltin<"__builtin_ve_vl_pvsla_vvsMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vslal_vvvl : GCCBuiltin<"__builtin_ve_vl_vslal_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vslal_vvvvl : GCCBuiltin<"__builtin_ve_vl_vslal_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vslal_vvsl : GCCBuiltin<"__builtin_ve_vl_vslal_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vslal_vvsvl : GCCBuiltin<"__builtin_ve_vl_vslal_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vslal_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vslal_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vslal_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vslal_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsrawsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vsrawsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsrawsx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsrawsx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsrawsx_vvsl : GCCBuiltin<"__builtin_ve_vl_vsrawsx_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsrawsx_vvsvl : GCCBuiltin<"__builtin_ve_vl_vsrawsx_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsrawsx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsrawsx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsrawsx_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vsrawsx_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsrawzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vsrawzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsrawzx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsrawzx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsrawzx_vvsl : GCCBuiltin<"__builtin_ve_vl_vsrawzx_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsrawzx_vvsvl : GCCBuiltin<"__builtin_ve_vl_vsrawzx_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsrawzx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsrawzx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsrawzx_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vsrawzx_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsra_vvvl : GCCBuiltin<"__builtin_ve_vl_pvsra_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsra_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvsra_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsra_vvsl : GCCBuiltin<"__builtin_ve_vl_pvsra_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsra_vvsvl : GCCBuiltin<"__builtin_ve_vl_pvsra_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsra_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvsra_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvsra_vvsMvl : GCCBuiltin<"__builtin_ve_vl_pvsra_vvsMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsral_vvvl : GCCBuiltin<"__builtin_ve_vl_vsral_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsral_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsral_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsral_vvsl : GCCBuiltin<"__builtin_ve_vl_vsral_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsral_vvsvl : GCCBuiltin<"__builtin_ve_vl_vsral_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsral_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsral_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsral_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vsral_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsfa_vvssl : GCCBuiltin<"__builtin_ve_vl_vsfa_vvssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsfa_vvssvl : GCCBuiltin<"__builtin_ve_vl_vsfa_vvssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsfa_vvssmvl : GCCBuiltin<"__builtin_ve_vl_vsfa_vvssmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfaddd_vvvl : GCCBuiltin<"__builtin_ve_vl_vfaddd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfaddd_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfaddd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfaddd_vsvl : GCCBuiltin<"__builtin_ve_vl_vfaddd_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfaddd_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfaddd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfaddd_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfaddd_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfaddd_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfaddd_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfadds_vvvl : GCCBuiltin<"__builtin_ve_vl_vfadds_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfadds_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfadds_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfadds_vsvl : GCCBuiltin<"__builtin_ve_vl_vfadds_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfadds_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfadds_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfadds_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfadds_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfadds_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfadds_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfadd_vvvl : GCCBuiltin<"__builtin_ve_vl_pvfadd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfadd_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfadd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfadd_vsvl : GCCBuiltin<"__builtin_ve_vl_pvfadd_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfadd_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfadd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfadd_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfadd_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfadd_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfadd_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsubd_vvvl : GCCBuiltin<"__builtin_ve_vl_vfsubd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsubd_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfsubd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsubd_vsvl : GCCBuiltin<"__builtin_ve_vl_vfsubd_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsubd_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfsubd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsubd_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfsubd_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsubd_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfsubd_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsubs_vvvl : GCCBuiltin<"__builtin_ve_vl_vfsubs_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsubs_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfsubs_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsubs_vsvl : GCCBuiltin<"__builtin_ve_vl_vfsubs_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsubs_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfsubs_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsubs_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfsubs_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsubs_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfsubs_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfsub_vvvl : GCCBuiltin<"__builtin_ve_vl_pvfsub_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfsub_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfsub_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfsub_vsvl : GCCBuiltin<"__builtin_ve_vl_pvfsub_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfsub_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfsub_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfsub_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfsub_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfsub_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfsub_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmuld_vvvl : GCCBuiltin<"__builtin_ve_vl_vfmuld_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmuld_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmuld_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmuld_vsvl : GCCBuiltin<"__builtin_ve_vl_vfmuld_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmuld_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmuld_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmuld_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmuld_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmuld_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmuld_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmuls_vvvl : GCCBuiltin<"__builtin_ve_vl_vfmuls_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmuls_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmuls_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmuls_vsvl : GCCBuiltin<"__builtin_ve_vl_vfmuls_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmuls_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmuls_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmuls_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmuls_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmuls_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmuls_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmul_vvvl : GCCBuiltin<"__builtin_ve_vl_pvfmul_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmul_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfmul_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmul_vsvl : GCCBuiltin<"__builtin_ve_vl_pvfmul_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmul_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfmul_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmul_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmul_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmul_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmul_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfdivd_vvvl : GCCBuiltin<"__builtin_ve_vl_vfdivd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfdivd_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfdivd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfdivd_vsvl : GCCBuiltin<"__builtin_ve_vl_vfdivd_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfdivd_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfdivd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfdivd_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfdivd_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfdivd_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfdivd_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfdivs_vvvl : GCCBuiltin<"__builtin_ve_vl_vfdivs_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfdivs_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfdivs_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfdivs_vsvl : GCCBuiltin<"__builtin_ve_vl_vfdivs_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfdivs_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfdivs_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfdivs_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfdivs_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfdivs_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfdivs_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsqrtd_vvl : GCCBuiltin<"__builtin_ve_vl_vfsqrtd_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsqrtd_vvvl : GCCBuiltin<"__builtin_ve_vl_vfsqrtd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsqrts_vvl : GCCBuiltin<"__builtin_ve_vl_vfsqrts_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsqrts_vvvl : GCCBuiltin<"__builtin_ve_vl_vfsqrts_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfcmpd_vvvl : GCCBuiltin<"__builtin_ve_vl_vfcmpd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfcmpd_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfcmpd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfcmpd_vsvl : GCCBuiltin<"__builtin_ve_vl_vfcmpd_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfcmpd_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfcmpd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfcmpd_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfcmpd_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfcmpd_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfcmpd_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfcmps_vvvl : GCCBuiltin<"__builtin_ve_vl_vfcmps_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfcmps_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfcmps_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfcmps_vsvl : GCCBuiltin<"__builtin_ve_vl_vfcmps_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfcmps_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfcmps_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfcmps_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfcmps_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfcmps_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfcmps_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfcmp_vvvl : GCCBuiltin<"__builtin_ve_vl_pvfcmp_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfcmp_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfcmp_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfcmp_vsvl : GCCBuiltin<"__builtin_ve_vl_pvfcmp_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfcmp_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfcmp_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfcmp_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfcmp_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfcmp_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfcmp_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmaxd_vvvl : GCCBuiltin<"__builtin_ve_vl_vfmaxd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmaxd_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmaxd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmaxd_vsvl : GCCBuiltin<"__builtin_ve_vl_vfmaxd_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmaxd_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmaxd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmaxd_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmaxd_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmaxd_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmaxd_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmaxs_vvvl : GCCBuiltin<"__builtin_ve_vl_vfmaxs_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmaxs_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmaxs_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmaxs_vsvl : GCCBuiltin<"__builtin_ve_vl_vfmaxs_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmaxs_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmaxs_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmaxs_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmaxs_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmaxs_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmaxs_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmax_vvvl : GCCBuiltin<"__builtin_ve_vl_pvfmax_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmax_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfmax_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmax_vsvl : GCCBuiltin<"__builtin_ve_vl_pvfmax_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmax_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfmax_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmax_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmax_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmax_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmax_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmind_vvvl : GCCBuiltin<"__builtin_ve_vl_vfmind_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmind_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmind_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmind_vsvl : GCCBuiltin<"__builtin_ve_vl_vfmind_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmind_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmind_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmind_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmind_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmind_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmind_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmins_vvvl : GCCBuiltin<"__builtin_ve_vl_vfmins_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmins_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmins_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmins_vsvl : GCCBuiltin<"__builtin_ve_vl_vfmins_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmins_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmins_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmins_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmins_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmins_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmins_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmin_vvvl : GCCBuiltin<"__builtin_ve_vl_pvfmin_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmin_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfmin_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmin_vsvl : GCCBuiltin<"__builtin_ve_vl_pvfmin_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmin_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfmin_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmin_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmin_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmin_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmin_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmadd_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmadd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmadd_vvvvvl : GCCBuiltin<"__builtin_ve_vl_vfmadd_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmadd_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmadd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmadd_vsvvvl : GCCBuiltin<"__builtin_ve_vl_vfmadd_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmadd_vvsvl : GCCBuiltin<"__builtin_ve_vl_vfmadd_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmadd_vvsvvl : GCCBuiltin<"__builtin_ve_vl_vfmadd_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmadd_vvvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmadd_vvvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmadd_vsvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmadd_vsvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmadd_vvsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmadd_vvsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmads_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmads_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmads_vvvvvl : GCCBuiltin<"__builtin_ve_vl_vfmads_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmads_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmads_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmads_vsvvvl : GCCBuiltin<"__builtin_ve_vl_vfmads_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmads_vvsvl : GCCBuiltin<"__builtin_ve_vl_vfmads_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmads_vvsvvl : GCCBuiltin<"__builtin_ve_vl_vfmads_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmads_vvvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmads_vvvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmads_vsvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmads_vsvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmads_vvsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmads_vvsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmad_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfmad_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmad_vvvvvl : GCCBuiltin<"__builtin_ve_vl_pvfmad_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmad_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfmad_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmad_vsvvvl : GCCBuiltin<"__builtin_ve_vl_pvfmad_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmad_vvsvl : GCCBuiltin<"__builtin_ve_vl_pvfmad_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmad_vvsvvl : GCCBuiltin<"__builtin_ve_vl_pvfmad_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmad_vvvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmad_vvvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmad_vsvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmad_vsvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmad_vvsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmad_vvsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmsbd_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmsbd_vvvvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbd_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmsbd_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmsbd_vsvvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbd_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmsbd_vvsvl : GCCBuiltin<"__builtin_ve_vl_vfmsbd_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmsbd_vvsvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbd_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmsbd_vvvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmsbd_vvvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmsbd_vsvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmsbd_vsvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmsbd_vvsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmsbd_vvsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmsbs_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbs_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmsbs_vvvvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbs_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmsbs_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbs_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmsbs_vsvvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbs_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmsbs_vvsvl : GCCBuiltin<"__builtin_ve_vl_vfmsbs_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmsbs_vvsvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbs_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmsbs_vvvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmsbs_vvvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmsbs_vsvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmsbs_vsvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmsbs_vvsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmsbs_vvsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmsb_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfmsb_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmsb_vvvvvl : GCCBuiltin<"__builtin_ve_vl_pvfmsb_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmsb_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfmsb_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmsb_vsvvvl : GCCBuiltin<"__builtin_ve_vl_pvfmsb_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmsb_vvsvl : GCCBuiltin<"__builtin_ve_vl_pvfmsb_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmsb_vvsvvl : GCCBuiltin<"__builtin_ve_vl_pvfmsb_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmsb_vvvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmsb_vvvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmsb_vsvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmsb_vsvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmsb_vvsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmsb_vvsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmadd_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmadd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmadd_vvvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmadd_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmadd_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfnmadd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmadd_vsvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmadd_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmadd_vvsvl : GCCBuiltin<"__builtin_ve_vl_vfnmadd_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmadd_vvsvvl : GCCBuiltin<"__builtin_ve_vl_vfnmadd_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmadd_vvvvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmadd_vvvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmadd_vsvvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmadd_vsvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmadd_vvsvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmadd_vvsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmads_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmads_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmads_vvvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmads_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmads_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfnmads_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmads_vsvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmads_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmads_vvsvl : GCCBuiltin<"__builtin_ve_vl_vfnmads_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmads_vvsvvl : GCCBuiltin<"__builtin_ve_vl_vfnmads_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmads_vvvvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmads_vvvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmads_vsvvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmads_vsvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmads_vvsvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmads_vvsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfnmad_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmad_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfnmad_vvvvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmad_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfnmad_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmad_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfnmad_vsvvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmad_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfnmad_vvsvl : GCCBuiltin<"__builtin_ve_vl_pvfnmad_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfnmad_vvsvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmad_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfnmad_vvvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfnmad_vvvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfnmad_vsvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfnmad_vsvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfnmad_vvsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfnmad_vvsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmsbd_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmsbd_vvvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbd_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmsbd_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmsbd_vsvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbd_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmsbd_vvsvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbd_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmsbd_vvsvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbd_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmsbd_vvvvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbd_vvvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmsbd_vsvvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbd_vsvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmsbd_vvsvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbd_vvsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmsbs_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbs_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmsbs_vvvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbs_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmsbs_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbs_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmsbs_vsvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbs_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmsbs_vvsvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbs_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmsbs_vvsvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbs_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmsbs_vvvvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbs_vvvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmsbs_vsvvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbs_vsvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfnmsbs_vvsvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbs_vvsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfnmsb_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmsb_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfnmsb_vvvvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmsb_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfnmsb_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmsb_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfnmsb_vsvvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmsb_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfnmsb_vvsvl : GCCBuiltin<"__builtin_ve_vl_pvfnmsb_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfnmsb_vvsvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmsb_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfnmsb_vvvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfnmsb_vvvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfnmsb_vsvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfnmsb_vsvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfnmsb_vvsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfnmsb_vvsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrcpd_vvl : GCCBuiltin<"__builtin_ve_vl_vrcpd_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrcpd_vvvl : GCCBuiltin<"__builtin_ve_vl_vrcpd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrcps_vvl : GCCBuiltin<"__builtin_ve_vl_vrcps_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrcps_vvvl : GCCBuiltin<"__builtin_ve_vl_vrcps_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvrcp_vvl : GCCBuiltin<"__builtin_ve_vl_pvrcp_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvrcp_vvvl : GCCBuiltin<"__builtin_ve_vl_pvrcp_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrsqrtd_vvl : GCCBuiltin<"__builtin_ve_vl_vrsqrtd_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrsqrtd_vvvl : GCCBuiltin<"__builtin_ve_vl_vrsqrtd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrsqrts_vvl : GCCBuiltin<"__builtin_ve_vl_vrsqrts_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrsqrts_vvvl : GCCBuiltin<"__builtin_ve_vl_vrsqrts_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvrsqrt_vvl : GCCBuiltin<"__builtin_ve_vl_pvrsqrt_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvrsqrt_vvvl : GCCBuiltin<"__builtin_ve_vl_pvrsqrt_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrsqrtdnex_vvl : GCCBuiltin<"__builtin_ve_vl_vrsqrtdnex_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrsqrtdnex_vvvl : GCCBuiltin<"__builtin_ve_vl_vrsqrtdnex_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrsqrtsnex_vvl : GCCBuiltin<"__builtin_ve_vl_vrsqrtsnex_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrsqrtsnex_vvvl : GCCBuiltin<"__builtin_ve_vl_vrsqrtsnex_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvrsqrtnex_vvl : GCCBuiltin<"__builtin_ve_vl_pvrsqrtnex_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvrsqrtnex_vvvl : GCCBuiltin<"__builtin_ve_vl_pvrsqrtnex_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwdsx_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdsx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwdsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwdsx_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdsx_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwdsxrz_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdsxrz_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwdsxrz_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdsxrz_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwdsxrz_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdsxrz_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwdzx_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdzx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwdzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwdzx_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdzx_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwdzxrz_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdzxrz_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwdzxrz_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdzxrz_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwdzxrz_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdzxrz_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwssx_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtwssx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwssx_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtwssx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwssx_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtwssx_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwssxrz_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtwssxrz_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwssxrz_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtwssxrz_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwssxrz_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtwssxrz_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwszx_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtwszx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwszx_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtwszx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwszx_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtwszx_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwszxrz_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtwszxrz_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwszxrz_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtwszxrz_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtwszxrz_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtwszxrz_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcvtws_vvl : GCCBuiltin<"__builtin_ve_vl_pvcvtws_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcvtws_vvvl : GCCBuiltin<"__builtin_ve_vl_pvcvtws_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcvtws_vvMvl : GCCBuiltin<"__builtin_ve_vl_pvcvtws_vvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcvtwsrz_vvl : GCCBuiltin<"__builtin_ve_vl_pvcvtwsrz_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcvtwsrz_vvvl : GCCBuiltin<"__builtin_ve_vl_pvcvtwsrz_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcvtwsrz_vvMvl : GCCBuiltin<"__builtin_ve_vl_pvcvtwsrz_vvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtld_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtld_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtld_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtld_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtld_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtld_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtldrz_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtldrz_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtldrz_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtldrz_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtldrz_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtldrz_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtdw_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtdw_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtdw_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtdw_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtsw_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtsw_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtsw_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtsw_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcvtsw_vvl : GCCBuiltin<"__builtin_ve_vl_pvcvtsw_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvcvtsw_vvvl : GCCBuiltin<"__builtin_ve_vl_pvcvtsw_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtdl_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtdl_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtdl_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtdl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtds_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtds_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtds_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtds_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtsd_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtsd_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcvtsd_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtsd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmrg_vvvml : GCCBuiltin<"__builtin_ve_vl_vmrg_vvvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmrg_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vmrg_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmrg_vsvml : GCCBuiltin<"__builtin_ve_vl_vmrg_vsvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmrg_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmrg_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmrgw_vvvMl : GCCBuiltin<"__builtin_ve_vl_vmrgw_vvvMl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmrgw_vvvMvl : GCCBuiltin<"__builtin_ve_vl_vmrgw_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmrgw_vsvMl : GCCBuiltin<"__builtin_ve_vl_vmrgw_vsvMl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vmrgw_vsvMvl : GCCBuiltin<"__builtin_ve_vl_vmrgw_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vshf_vvvsl : GCCBuiltin<"__builtin_ve_vl_vshf_vvvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vshf_vvvsvl : GCCBuiltin<"__builtin_ve_vl_vshf_vvvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vcp_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcp_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vex_vvmvl : GCCBuiltin<"__builtin_ve_vl_vex_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklat_ml : GCCBuiltin<"__builtin_ve_vl_vfmklat_ml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklaf_ml : GCCBuiltin<"__builtin_ve_vl_vfmklaf_ml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkat_Ml : GCCBuiltin<"__builtin_ve_vl_pvfmkat_Ml">, Intrinsic<[LLVMType<v512i1>], [LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkaf_Ml : GCCBuiltin<"__builtin_ve_vl_pvfmkaf_Ml">, Intrinsic<[LLVMType<v512i1>], [LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklgt_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklgt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklgt_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklgt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkllt_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkllt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkllt_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkllt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklne_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklne_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklne_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklne_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkleq_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkleq_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkleq_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkleq_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklge_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklge_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklge_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklge_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklle_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklle_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklle_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklle_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklnum_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklnum_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklnum_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklnum_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklgtnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklgtnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklgtnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklgtnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklltnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklltnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklltnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklltnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklnenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklnenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklnenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklnenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkleqnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkleqnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkleqnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkleqnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklgenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklgenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmklgenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklgenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkllenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkllenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkllenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkllenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwgt_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwgt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwgt_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwgt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwlt_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwlt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwlt_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwlt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwne_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwne_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwne_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwne_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkweq_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkweq_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkweq_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkweq_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwge_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwge_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwge_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwge_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwle_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwle_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwle_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwle_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwnum_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwnum_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwnum_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwnum_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwgtnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwgtnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwgtnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwgtnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwltnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwltnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwltnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwltnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwnenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwnenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwnenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwnenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkweqnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkweqnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkweqnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkweqnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwgenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwgenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwgenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwgenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwlenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwlenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkwlenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwlenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlogt_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlogt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupgt_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupgt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlogt_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlogt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupgt_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupgt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlolt_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlolt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwuplt_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwuplt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlolt_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlolt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwuplt_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwuplt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlone_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlone_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupne_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupne_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlone_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlone_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupne_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupne_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwloeq_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwloeq_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupeq_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupeq_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwloeq_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwloeq_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupeq_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupeq_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwloge_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwloge_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupge_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupge_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwloge_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwloge_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupge_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupge_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlole_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlole_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwuple_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwuple_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlole_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlole_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwuple_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwuple_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlonum_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlonum_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupnum_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupnum_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlonum_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlonum_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupnum_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupnum_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlonan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlonan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlonan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlonan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlogtnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlogtnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupgtnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupgtnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlogtnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlogtnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupgtnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupgtnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwloltnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwloltnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupltnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupltnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwloltnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwloltnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupltnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupltnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlonenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlonenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupnenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupnenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlonenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlonenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupnenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupnenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwloeqnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwloeqnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupeqnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupeqnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwloeqnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwloeqnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupeqnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupeqnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlogenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlogenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupgenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupgenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlogenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlogenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupgenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupgenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlolenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlolenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwuplenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwuplenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlolenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlolenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwuplenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwuplenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwgt_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwgt_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwgt_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwgt_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlt_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlt_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlt_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlt_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwne_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwne_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwne_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwne_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkweq_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkweq_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkweq_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkweq_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwge_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwge_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwge_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwge_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwle_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwle_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwle_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwle_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwnum_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwnum_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwnum_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwnum_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwnan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwnan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwnan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwnan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwgtnan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwgtnan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwgtnan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwgtnan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwltnan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwltnan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwltnan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwltnan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwnenan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwnenan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwnenan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwnenan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkweqnan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkweqnan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkweqnan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkweqnan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwgenan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwgenan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwgenan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwgenan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlenan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlenan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlenan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlenan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdgt_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdgt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdgt_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdgt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdlt_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdlt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdlt_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdlt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdne_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdne_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdne_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdne_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdeq_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdeq_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdeq_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdeq_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdge_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdge_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdge_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdge_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdle_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdle_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdle_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdle_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdnum_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdnum_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdnum_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdnum_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdgtnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdgtnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdgtnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdgtnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdltnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdltnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdltnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdltnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdnenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdnenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdnenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdnenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdeqnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdeqnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdeqnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdeqnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdgenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdgenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdgenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdgenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdlenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdlenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkdlenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdlenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksgt_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksgt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksgt_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksgt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkslt_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkslt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkslt_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkslt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksne_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksne_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksne_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksne_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkseq_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkseq_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkseq_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkseq_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksge_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksge_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksge_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksge_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksle_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksle_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksle_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksle_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksnum_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksnum_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksnum_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksnum_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksgtnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksgtnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksgtnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksgtnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksltnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksltnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksltnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksltnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksnenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksnenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksnenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksnenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkseqnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkseqnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkseqnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkseqnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksgenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksgenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmksgenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksgenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkslenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkslenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfmkslenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkslenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslogt_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslogt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupgt_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupgt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslogt_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslogt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupgt_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupgt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslolt_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslolt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksuplt_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksuplt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslolt_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslolt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksuplt_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksuplt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslone_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslone_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupne_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupne_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslone_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslone_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupne_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupne_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksloeq_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksloeq_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupeq_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupeq_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksloeq_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksloeq_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupeq_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupeq_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksloge_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksloge_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupge_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupge_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksloge_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksloge_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupge_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupge_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslole_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslole_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksuple_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksuple_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslole_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslole_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksuple_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksuple_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslonum_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslonum_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupnum_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupnum_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslonum_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslonum_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupnum_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupnum_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslonan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslonan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslonan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslonan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslogtnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslogtnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupgtnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupgtnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslogtnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslogtnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupgtnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupgtnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksloltnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksloltnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupltnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupltnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksloltnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksloltnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupltnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupltnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslonenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslonenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupnenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupnenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslonenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslonenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupnenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupnenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksloeqnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksloeqnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupeqnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupeqnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksloeqnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksloeqnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupeqnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupeqnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslogenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslogenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupgenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupgenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslogenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslogenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksupgenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupgenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslolenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslolenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksuplenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksuplenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslolenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslolenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksuplenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksuplenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksgt_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksgt_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksgt_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksgt_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslt_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslt_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslt_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkslt_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksne_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksne_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksne_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksne_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkseq_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkseq_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkseq_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkseq_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksge_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksge_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksge_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksge_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksle_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksle_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksle_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksle_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksnum_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksnum_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksnum_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksnum_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksnan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksnan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksnan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksnan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksgtnan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksgtnan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksgtnan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksgtnan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksltnan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksltnan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksltnan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksltnan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksnenan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksnenan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksnenan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksnenan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkseqnan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkseqnan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkseqnan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkseqnan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksgenan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksgenan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmksgenan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksgenan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslenan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslenan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pvfmkslenan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkslenan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsumwsx_vvl : GCCBuiltin<"__builtin_ve_vl_vsumwsx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsumwsx_vvml : GCCBuiltin<"__builtin_ve_vl_vsumwsx_vvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsumwzx_vvl : GCCBuiltin<"__builtin_ve_vl_vsumwzx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsumwzx_vvml : GCCBuiltin<"__builtin_ve_vl_vsumwzx_vvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsuml_vvl : GCCBuiltin<"__builtin_ve_vl_vsuml_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsuml_vvml : GCCBuiltin<"__builtin_ve_vl_vsuml_vvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsumd_vvl : GCCBuiltin<"__builtin_ve_vl_vfsumd_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsumd_vvml : GCCBuiltin<"__builtin_ve_vl_vfsumd_vvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsums_vvl : GCCBuiltin<"__builtin_ve_vl_vfsums_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfsums_vvml : GCCBuiltin<"__builtin_ve_vl_vfsums_vvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrmaxswfstsx_vvl : GCCBuiltin<"__builtin_ve_vl_vrmaxswfstsx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrmaxswfstsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vrmaxswfstsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrmaxswlstsx_vvl : GCCBuiltin<"__builtin_ve_vl_vrmaxswlstsx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrmaxswlstsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vrmaxswlstsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrmaxswfstzx_vvl : GCCBuiltin<"__builtin_ve_vl_vrmaxswfstzx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrmaxswfstzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vrmaxswfstzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrmaxswlstzx_vvl : GCCBuiltin<"__builtin_ve_vl_vrmaxswlstzx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrmaxswlstzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vrmaxswlstzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrminswfstsx_vvl : GCCBuiltin<"__builtin_ve_vl_vrminswfstsx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrminswfstsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vrminswfstsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrminswlstsx_vvl : GCCBuiltin<"__builtin_ve_vl_vrminswlstsx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrminswlstsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vrminswlstsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrminswfstzx_vvl : GCCBuiltin<"__builtin_ve_vl_vrminswfstzx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrminswfstzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vrminswfstzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrminswlstzx_vvl : GCCBuiltin<"__builtin_ve_vl_vrminswlstzx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrminswlstzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vrminswlstzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrmaxslfst_vvl : GCCBuiltin<"__builtin_ve_vl_vrmaxslfst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrmaxslfst_vvvl : GCCBuiltin<"__builtin_ve_vl_vrmaxslfst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrmaxsllst_vvl : GCCBuiltin<"__builtin_ve_vl_vrmaxsllst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrmaxsllst_vvvl : GCCBuiltin<"__builtin_ve_vl_vrmaxsllst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrminslfst_vvl : GCCBuiltin<"__builtin_ve_vl_vrminslfst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrminslfst_vvvl : GCCBuiltin<"__builtin_ve_vl_vrminslfst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrminsllst_vvl : GCCBuiltin<"__builtin_ve_vl_vrminsllst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrminsllst_vvvl : GCCBuiltin<"__builtin_ve_vl_vrminsllst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfrmaxdfst_vvl : GCCBuiltin<"__builtin_ve_vl_vfrmaxdfst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfrmaxdfst_vvvl : GCCBuiltin<"__builtin_ve_vl_vfrmaxdfst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfrmaxdlst_vvl : GCCBuiltin<"__builtin_ve_vl_vfrmaxdlst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfrmaxdlst_vvvl : GCCBuiltin<"__builtin_ve_vl_vfrmaxdlst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfrmaxsfst_vvl : GCCBuiltin<"__builtin_ve_vl_vfrmaxsfst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfrmaxsfst_vvvl : GCCBuiltin<"__builtin_ve_vl_vfrmaxsfst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfrmaxslst_vvl : GCCBuiltin<"__builtin_ve_vl_vfrmaxslst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfrmaxslst_vvvl : GCCBuiltin<"__builtin_ve_vl_vfrmaxslst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfrmindfst_vvl : GCCBuiltin<"__builtin_ve_vl_vfrmindfst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfrmindfst_vvvl : GCCBuiltin<"__builtin_ve_vl_vfrmindfst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfrmindlst_vvl : GCCBuiltin<"__builtin_ve_vl_vfrmindlst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfrmindlst_vvvl : GCCBuiltin<"__builtin_ve_vl_vfrmindlst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfrminsfst_vvl : GCCBuiltin<"__builtin_ve_vl_vfrminsfst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfrminsfst_vvvl : GCCBuiltin<"__builtin_ve_vl_vfrminsfst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfrminslst_vvl : GCCBuiltin<"__builtin_ve_vl_vfrminslst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vfrminslst_vvvl : GCCBuiltin<"__builtin_ve_vl_vfrminslst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrand_vvl : GCCBuiltin<"__builtin_ve_vl_vrand_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrand_vvml : GCCBuiltin<"__builtin_ve_vl_vrand_vvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vror_vvl : GCCBuiltin<"__builtin_ve_vl_vror_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vror_vvml : GCCBuiltin<"__builtin_ve_vl_vror_vvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrxor_vvl : GCCBuiltin<"__builtin_ve_vl_vrxor_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vrxor_vvml : GCCBuiltin<"__builtin_ve_vl_vrxor_vvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgt_vvssl : GCCBuiltin<"__builtin_ve_vl_vgt_vvssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgt_vvssvl : GCCBuiltin<"__builtin_ve_vl_vgt_vvssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgt_vvssml : GCCBuiltin<"__builtin_ve_vl_vgt_vvssml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgt_vvssmvl : GCCBuiltin<"__builtin_ve_vl_vgt_vvssmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtnc_vvssl : GCCBuiltin<"__builtin_ve_vl_vgtnc_vvssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtnc_vvssvl : GCCBuiltin<"__builtin_ve_vl_vgtnc_vvssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtnc_vvssml : GCCBuiltin<"__builtin_ve_vl_vgtnc_vvssml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtnc_vvssmvl : GCCBuiltin<"__builtin_ve_vl_vgtnc_vvssmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtu_vvssl : GCCBuiltin<"__builtin_ve_vl_vgtu_vvssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtu_vvssvl : GCCBuiltin<"__builtin_ve_vl_vgtu_vvssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtu_vvssml : GCCBuiltin<"__builtin_ve_vl_vgtu_vvssml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtu_vvssmvl : GCCBuiltin<"__builtin_ve_vl_vgtu_vvssmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtunc_vvssl : GCCBuiltin<"__builtin_ve_vl_vgtunc_vvssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtunc_vvssvl : GCCBuiltin<"__builtin_ve_vl_vgtunc_vvssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtunc_vvssml : GCCBuiltin<"__builtin_ve_vl_vgtunc_vvssml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtunc_vvssmvl : GCCBuiltin<"__builtin_ve_vl_vgtunc_vvssmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtlsx_vvssl : GCCBuiltin<"__builtin_ve_vl_vgtlsx_vvssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtlsx_vvssvl : GCCBuiltin<"__builtin_ve_vl_vgtlsx_vvssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtlsx_vvssml : GCCBuiltin<"__builtin_ve_vl_vgtlsx_vvssml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtlsx_vvssmvl : GCCBuiltin<"__builtin_ve_vl_vgtlsx_vvssmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtlsxnc_vvssl : GCCBuiltin<"__builtin_ve_vl_vgtlsxnc_vvssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtlsxnc_vvssvl : GCCBuiltin<"__builtin_ve_vl_vgtlsxnc_vvssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtlsxnc_vvssml : GCCBuiltin<"__builtin_ve_vl_vgtlsxnc_vvssml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtlsxnc_vvssmvl : GCCBuiltin<"__builtin_ve_vl_vgtlsxnc_vvssmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtlzx_vvssl : GCCBuiltin<"__builtin_ve_vl_vgtlzx_vvssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtlzx_vvssvl : GCCBuiltin<"__builtin_ve_vl_vgtlzx_vvssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtlzx_vvssml : GCCBuiltin<"__builtin_ve_vl_vgtlzx_vvssml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtlzx_vvssmvl : GCCBuiltin<"__builtin_ve_vl_vgtlzx_vvssmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtlzxnc_vvssl : GCCBuiltin<"__builtin_ve_vl_vgtlzxnc_vvssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtlzxnc_vvssvl : GCCBuiltin<"__builtin_ve_vl_vgtlzxnc_vvssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtlzxnc_vvssml : GCCBuiltin<"__builtin_ve_vl_vgtlzxnc_vvssml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vgtlzxnc_vvssmvl : GCCBuiltin<"__builtin_ve_vl_vgtlzxnc_vvssmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsc_vvssl : GCCBuiltin<"__builtin_ve_vl_vsc_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsc_vvssml : GCCBuiltin<"__builtin_ve_vl_vsc_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vscnc_vvssl : GCCBuiltin<"__builtin_ve_vl_vscnc_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vscnc_vvssml : GCCBuiltin<"__builtin_ve_vl_vscnc_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vscot_vvssl : GCCBuiltin<"__builtin_ve_vl_vscot_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vscot_vvssml : GCCBuiltin<"__builtin_ve_vl_vscot_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vscncot_vvssl : GCCBuiltin<"__builtin_ve_vl_vscncot_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vscncot_vvssml : GCCBuiltin<"__builtin_ve_vl_vscncot_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vscu_vvssl : GCCBuiltin<"__builtin_ve_vl_vscu_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vscu_vvssml : GCCBuiltin<"__builtin_ve_vl_vscu_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vscunc_vvssl : GCCBuiltin<"__builtin_ve_vl_vscunc_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vscunc_vvssml : GCCBuiltin<"__builtin_ve_vl_vscunc_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vscuot_vvssl : GCCBuiltin<"__builtin_ve_vl_vscuot_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vscuot_vvssml : GCCBuiltin<"__builtin_ve_vl_vscuot_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vscuncot_vvssl : GCCBuiltin<"__builtin_ve_vl_vscuncot_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vscuncot_vvssml : GCCBuiltin<"__builtin_ve_vl_vscuncot_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vscl_vvssl : GCCBuiltin<"__builtin_ve_vl_vscl_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vscl_vvssml : GCCBuiltin<"__builtin_ve_vl_vscl_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsclnc_vvssl : GCCBuiltin<"__builtin_ve_vl_vsclnc_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsclnc_vvssml : GCCBuiltin<"__builtin_ve_vl_vsclnc_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsclot_vvssl : GCCBuiltin<"__builtin_ve_vl_vsclot_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsclot_vvssml : GCCBuiltin<"__builtin_ve_vl_vsclot_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsclncot_vvssl : GCCBuiltin<"__builtin_ve_vl_vsclncot_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_vsclncot_vvssml : GCCBuiltin<"__builtin_ve_vl_vsclncot_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_andm_mmm : GCCBuiltin<"__builtin_ve_vl_andm_mmm">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256i1>, LLVMType<v256i1>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_andm_MMM : GCCBuiltin<"__builtin_ve_vl_andm_MMM">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v512i1>, LLVMType<v512i1>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_orm_mmm : GCCBuiltin<"__builtin_ve_vl_orm_mmm">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256i1>, LLVMType<v256i1>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_orm_MMM : GCCBuiltin<"__builtin_ve_vl_orm_MMM">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v512i1>, LLVMType<v512i1>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_xorm_mmm : GCCBuiltin<"__builtin_ve_vl_xorm_mmm">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256i1>, LLVMType<v256i1>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_xorm_MMM : GCCBuiltin<"__builtin_ve_vl_xorm_MMM">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v512i1>, LLVMType<v512i1>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_eqvm_mmm : GCCBuiltin<"__builtin_ve_vl_eqvm_mmm">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256i1>, LLVMType<v256i1>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_eqvm_MMM : GCCBuiltin<"__builtin_ve_vl_eqvm_MMM">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v512i1>, LLVMType<v512i1>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_nndm_mmm : GCCBuiltin<"__builtin_ve_vl_nndm_mmm">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256i1>, LLVMType<v256i1>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_nndm_MMM : GCCBuiltin<"__builtin_ve_vl_nndm_MMM">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v512i1>, LLVMType<v512i1>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_negm_mm : GCCBuiltin<"__builtin_ve_vl_negm_mm">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256i1>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_negm_MM : GCCBuiltin<"__builtin_ve_vl_negm_MM">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v512i1>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_pcvm_sml : GCCBuiltin<"__builtin_ve_vl_pcvm_sml">, Intrinsic<[LLVMType<i64>], [LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_lzvm_sml : GCCBuiltin<"__builtin_ve_vl_lzvm_sml">, Intrinsic<[LLVMType<i64>], [LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
-let TargetPrefix = "ve" in def int_ve_vl_tovm_sml : GCCBuiltin<"__builtin_ve_vl_tovm_sml">, Intrinsic<[LLVMType<i64>], [LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vld_vssl : GCCBuiltin<"__builtin_ve_vl_vld_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vld_vssvl : GCCBuiltin<"__builtin_ve_vl_vld_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldnc_vssl : GCCBuiltin<"__builtin_ve_vl_vldnc_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldnc_vssvl : GCCBuiltin<"__builtin_ve_vl_vldnc_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldu_vssl : GCCBuiltin<"__builtin_ve_vl_vldu_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldu_vssvl : GCCBuiltin<"__builtin_ve_vl_vldu_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldunc_vssl : GCCBuiltin<"__builtin_ve_vl_vldunc_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldunc_vssvl : GCCBuiltin<"__builtin_ve_vl_vldunc_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldlsx_vssl : GCCBuiltin<"__builtin_ve_vl_vldlsx_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldlsx_vssvl : GCCBuiltin<"__builtin_ve_vl_vldlsx_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldlsxnc_vssl : GCCBuiltin<"__builtin_ve_vl_vldlsxnc_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldlsxnc_vssvl : GCCBuiltin<"__builtin_ve_vl_vldlsxnc_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldlzx_vssl : GCCBuiltin<"__builtin_ve_vl_vldlzx_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldlzx_vssvl : GCCBuiltin<"__builtin_ve_vl_vldlzx_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldlzxnc_vssl : GCCBuiltin<"__builtin_ve_vl_vldlzxnc_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldlzxnc_vssvl : GCCBuiltin<"__builtin_ve_vl_vldlzxnc_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vld2d_vssl : GCCBuiltin<"__builtin_ve_vl_vld2d_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vld2d_vssvl : GCCBuiltin<"__builtin_ve_vl_vld2d_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vld2dnc_vssl : GCCBuiltin<"__builtin_ve_vl_vld2dnc_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vld2dnc_vssvl : GCCBuiltin<"__builtin_ve_vl_vld2dnc_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldu2d_vssl : GCCBuiltin<"__builtin_ve_vl_vldu2d_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldu2d_vssvl : GCCBuiltin<"__builtin_ve_vl_vldu2d_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldu2dnc_vssl : GCCBuiltin<"__builtin_ve_vl_vldu2dnc_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldu2dnc_vssvl : GCCBuiltin<"__builtin_ve_vl_vldu2dnc_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldl2dsx_vssl : GCCBuiltin<"__builtin_ve_vl_vldl2dsx_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldl2dsx_vssvl : GCCBuiltin<"__builtin_ve_vl_vldl2dsx_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldl2dsxnc_vssl : GCCBuiltin<"__builtin_ve_vl_vldl2dsxnc_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldl2dsxnc_vssvl : GCCBuiltin<"__builtin_ve_vl_vldl2dsxnc_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldl2dzx_vssl : GCCBuiltin<"__builtin_ve_vl_vldl2dzx_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldl2dzx_vssvl : GCCBuiltin<"__builtin_ve_vl_vldl2dzx_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldl2dzxnc_vssl : GCCBuiltin<"__builtin_ve_vl_vldl2dzxnc_vssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vldl2dzxnc_vssvl : GCCBuiltin<"__builtin_ve_vl_vldl2dzxnc_vssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, llvm_ptr_ty, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vst_vssl : GCCBuiltin<"__builtin_ve_vl_vst_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vst_vssml : GCCBuiltin<"__builtin_ve_vl_vst_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstnc_vssl : GCCBuiltin<"__builtin_ve_vl_vstnc_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstnc_vssml : GCCBuiltin<"__builtin_ve_vl_vstnc_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstot_vssl : GCCBuiltin<"__builtin_ve_vl_vstot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstot_vssml : GCCBuiltin<"__builtin_ve_vl_vstot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstncot_vssl : GCCBuiltin<"__builtin_ve_vl_vstncot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstncot_vssml : GCCBuiltin<"__builtin_ve_vl_vstncot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstu_vssl : GCCBuiltin<"__builtin_ve_vl_vstu_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstu_vssml : GCCBuiltin<"__builtin_ve_vl_vstu_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstunc_vssl : GCCBuiltin<"__builtin_ve_vl_vstunc_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstunc_vssml : GCCBuiltin<"__builtin_ve_vl_vstunc_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstuot_vssl : GCCBuiltin<"__builtin_ve_vl_vstuot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstuot_vssml : GCCBuiltin<"__builtin_ve_vl_vstuot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstuncot_vssl : GCCBuiltin<"__builtin_ve_vl_vstuncot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstuncot_vssml : GCCBuiltin<"__builtin_ve_vl_vstuncot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstl_vssl : GCCBuiltin<"__builtin_ve_vl_vstl_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstl_vssml : GCCBuiltin<"__builtin_ve_vl_vstl_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstlnc_vssl : GCCBuiltin<"__builtin_ve_vl_vstlnc_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstlnc_vssml : GCCBuiltin<"__builtin_ve_vl_vstlnc_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstlot_vssl : GCCBuiltin<"__builtin_ve_vl_vstlot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstlot_vssml : GCCBuiltin<"__builtin_ve_vl_vstlot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstlncot_vssl : GCCBuiltin<"__builtin_ve_vl_vstlncot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstlncot_vssml : GCCBuiltin<"__builtin_ve_vl_vstlncot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vst2d_vssl : GCCBuiltin<"__builtin_ve_vl_vst2d_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vst2d_vssml : GCCBuiltin<"__builtin_ve_vl_vst2d_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vst2dnc_vssl : GCCBuiltin<"__builtin_ve_vl_vst2dnc_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vst2dnc_vssml : GCCBuiltin<"__builtin_ve_vl_vst2dnc_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vst2dot_vssl : GCCBuiltin<"__builtin_ve_vl_vst2dot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vst2dot_vssml : GCCBuiltin<"__builtin_ve_vl_vst2dot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vst2dncot_vssl : GCCBuiltin<"__builtin_ve_vl_vst2dncot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vst2dncot_vssml : GCCBuiltin<"__builtin_ve_vl_vst2dncot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstu2d_vssl : GCCBuiltin<"__builtin_ve_vl_vstu2d_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstu2d_vssml : GCCBuiltin<"__builtin_ve_vl_vstu2d_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstu2dnc_vssl : GCCBuiltin<"__builtin_ve_vl_vstu2dnc_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstu2dnc_vssml : GCCBuiltin<"__builtin_ve_vl_vstu2dnc_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstu2dot_vssl : GCCBuiltin<"__builtin_ve_vl_vstu2dot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstu2dot_vssml : GCCBuiltin<"__builtin_ve_vl_vstu2dot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstu2dncot_vssl : GCCBuiltin<"__builtin_ve_vl_vstu2dncot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstu2dncot_vssml : GCCBuiltin<"__builtin_ve_vl_vstu2dncot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstl2d_vssl : GCCBuiltin<"__builtin_ve_vl_vstl2d_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstl2d_vssml : GCCBuiltin<"__builtin_ve_vl_vstl2d_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstl2dnc_vssl : GCCBuiltin<"__builtin_ve_vl_vstl2dnc_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstl2dnc_vssml : GCCBuiltin<"__builtin_ve_vl_vstl2dnc_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstl2dot_vssl : GCCBuiltin<"__builtin_ve_vl_vstl2dot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstl2dot_vssml : GCCBuiltin<"__builtin_ve_vl_vstl2dot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstl2dncot_vssl : GCCBuiltin<"__builtin_ve_vl_vstl2dncot_vssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vstl2dncot_vssml : GCCBuiltin<"__builtin_ve_vl_vstl2dncot_vssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<i64>, llvm_ptr_ty, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pfchv_ssl : GCCBuiltin<"__builtin_ve_vl_pfchv_ssl">, Intrinsic<[], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrInaccessibleMemOrArgMemOnly]>;
+let TargetPrefix = "ve" in def int_ve_vl_pfchvnc_ssl : GCCBuiltin<"__builtin_ve_vl_pfchvnc_ssl">, Intrinsic<[], [LLVMType<i64>, llvm_ptr_ty, LLVMType<i32>], [IntrInaccessibleMemOrArgMemOnly]>;
+let TargetPrefix = "ve" in def int_ve_vl_lsv_vvss : GCCBuiltin<"__builtin_ve_vl_lsv_vvss">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<i64>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_lvsl_svs : GCCBuiltin<"__builtin_ve_vl_lvsl_svs">, Intrinsic<[LLVMType<i64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_lvsd_svs : GCCBuiltin<"__builtin_ve_vl_lvsd_svs">, Intrinsic<[LLVMType<f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_lvss_svs : GCCBuiltin<"__builtin_ve_vl_lvss_svs">, Intrinsic<[LLVMType<f32>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_lvm_mmss : GCCBuiltin<"__builtin_ve_vl_lvm_mmss">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256i1>, LLVMType<i64>, LLVMType<i64>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_lvm_MMss : GCCBuiltin<"__builtin_ve_vl_lvm_MMss">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v512i1>, LLVMType<i64>, LLVMType<i64>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_svm_sms : GCCBuiltin<"__builtin_ve_vl_svm_sms">, Intrinsic<[LLVMType<i64>], [LLVMType<v256i1>, LLVMType<i64>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_svm_sMs : GCCBuiltin<"__builtin_ve_vl_svm_sMs">, Intrinsic<[LLVMType<i64>], [LLVMType<v512i1>, LLVMType<i64>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vbrdd_vsl : GCCBuiltin<"__builtin_ve_vl_vbrdd_vsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vbrdd_vsvl : GCCBuiltin<"__builtin_ve_vl_vbrdd_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vbrdd_vsmvl : GCCBuiltin<"__builtin_ve_vl_vbrdd_vsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vbrdl_vsl : GCCBuiltin<"__builtin_ve_vl_vbrdl_vsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vbrdl_vsvl : GCCBuiltin<"__builtin_ve_vl_vbrdl_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vbrdl_vsmvl : GCCBuiltin<"__builtin_ve_vl_vbrdl_vsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vbrds_vsl : GCCBuiltin<"__builtin_ve_vl_vbrds_vsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vbrds_vsvl : GCCBuiltin<"__builtin_ve_vl_vbrds_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vbrds_vsmvl : GCCBuiltin<"__builtin_ve_vl_vbrds_vsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vbrdw_vsl : GCCBuiltin<"__builtin_ve_vl_vbrdw_vsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vbrdw_vsvl : GCCBuiltin<"__builtin_ve_vl_vbrdw_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vbrdw_vsmvl : GCCBuiltin<"__builtin_ve_vl_vbrdw_vsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvbrd_vsl : GCCBuiltin<"__builtin_ve_vl_pvbrd_vsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvbrd_vsvl : GCCBuiltin<"__builtin_ve_vl_pvbrd_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvbrd_vsMvl : GCCBuiltin<"__builtin_ve_vl_pvbrd_vsMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmv_vsvl : GCCBuiltin<"__builtin_ve_vl_vmv_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmv_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmv_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmv_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmv_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddul_vvvl : GCCBuiltin<"__builtin_ve_vl_vaddul_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddul_vvvvl : GCCBuiltin<"__builtin_ve_vl_vaddul_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddul_vsvl : GCCBuiltin<"__builtin_ve_vl_vaddul_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddul_vsvvl : GCCBuiltin<"__builtin_ve_vl_vaddul_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddul_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vaddul_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddul_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vaddul_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vadduw_vvvl : GCCBuiltin<"__builtin_ve_vl_vadduw_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vadduw_vvvvl : GCCBuiltin<"__builtin_ve_vl_vadduw_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vadduw_vsvl : GCCBuiltin<"__builtin_ve_vl_vadduw_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vadduw_vsvvl : GCCBuiltin<"__builtin_ve_vl_vadduw_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vadduw_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vadduw_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vadduw_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vadduw_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvaddu_vvvl : GCCBuiltin<"__builtin_ve_vl_pvaddu_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvaddu_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvaddu_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvaddu_vsvl : GCCBuiltin<"__builtin_ve_vl_pvaddu_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvaddu_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvaddu_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvaddu_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvaddu_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvaddu_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvaddu_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddswsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vaddswsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddswsx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vaddswsx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddswsx_vsvl : GCCBuiltin<"__builtin_ve_vl_vaddswsx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddswsx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vaddswsx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddswsx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vaddswsx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddswsx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vaddswsx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddswzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vaddswzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddswzx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vaddswzx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddswzx_vsvl : GCCBuiltin<"__builtin_ve_vl_vaddswzx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddswzx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vaddswzx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddswzx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vaddswzx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddswzx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vaddswzx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvadds_vvvl : GCCBuiltin<"__builtin_ve_vl_pvadds_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvadds_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvadds_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvadds_vsvl : GCCBuiltin<"__builtin_ve_vl_pvadds_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvadds_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvadds_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvadds_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvadds_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvadds_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvadds_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddsl_vvvl : GCCBuiltin<"__builtin_ve_vl_vaddsl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddsl_vvvvl : GCCBuiltin<"__builtin_ve_vl_vaddsl_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddsl_vsvl : GCCBuiltin<"__builtin_ve_vl_vaddsl_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddsl_vsvvl : GCCBuiltin<"__builtin_ve_vl_vaddsl_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddsl_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vaddsl_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vaddsl_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vaddsl_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubul_vvvl : GCCBuiltin<"__builtin_ve_vl_vsubul_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubul_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsubul_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubul_vsvl : GCCBuiltin<"__builtin_ve_vl_vsubul_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubul_vsvvl : GCCBuiltin<"__builtin_ve_vl_vsubul_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubul_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsubul_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubul_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vsubul_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubuw_vvvl : GCCBuiltin<"__builtin_ve_vl_vsubuw_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubuw_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsubuw_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubuw_vsvl : GCCBuiltin<"__builtin_ve_vl_vsubuw_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubuw_vsvvl : GCCBuiltin<"__builtin_ve_vl_vsubuw_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubuw_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsubuw_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubuw_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vsubuw_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsubu_vvvl : GCCBuiltin<"__builtin_ve_vl_pvsubu_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsubu_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvsubu_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsubu_vsvl : GCCBuiltin<"__builtin_ve_vl_pvsubu_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsubu_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvsubu_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsubu_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvsubu_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsubu_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvsubu_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubswsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vsubswsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubswsx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsubswsx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubswsx_vsvl : GCCBuiltin<"__builtin_ve_vl_vsubswsx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubswsx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vsubswsx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubswsx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsubswsx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubswsx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vsubswsx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubswzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vsubswzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubswzx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsubswzx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubswzx_vsvl : GCCBuiltin<"__builtin_ve_vl_vsubswzx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubswzx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vsubswzx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubswzx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsubswzx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubswzx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vsubswzx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsubs_vvvl : GCCBuiltin<"__builtin_ve_vl_pvsubs_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsubs_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvsubs_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsubs_vsvl : GCCBuiltin<"__builtin_ve_vl_pvsubs_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsubs_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvsubs_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsubs_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvsubs_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsubs_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvsubs_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubsl_vvvl : GCCBuiltin<"__builtin_ve_vl_vsubsl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubsl_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsubsl_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubsl_vsvl : GCCBuiltin<"__builtin_ve_vl_vsubsl_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubsl_vsvvl : GCCBuiltin<"__builtin_ve_vl_vsubsl_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubsl_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsubsl_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsubsl_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vsubsl_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulul_vvvl : GCCBuiltin<"__builtin_ve_vl_vmulul_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulul_vvvvl : GCCBuiltin<"__builtin_ve_vl_vmulul_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulul_vsvl : GCCBuiltin<"__builtin_ve_vl_vmulul_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulul_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmulul_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulul_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vmulul_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulul_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmulul_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmuluw_vvvl : GCCBuiltin<"__builtin_ve_vl_vmuluw_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmuluw_vvvvl : GCCBuiltin<"__builtin_ve_vl_vmuluw_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmuluw_vsvl : GCCBuiltin<"__builtin_ve_vl_vmuluw_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmuluw_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmuluw_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmuluw_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vmuluw_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmuluw_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmuluw_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulswsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vmulswsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulswsx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vmulswsx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulswsx_vsvl : GCCBuiltin<"__builtin_ve_vl_vmulswsx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulswsx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmulswsx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulswsx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vmulswsx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulswsx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmulswsx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulswzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vmulswzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulswzx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vmulswzx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulswzx_vsvl : GCCBuiltin<"__builtin_ve_vl_vmulswzx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulswzx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmulswzx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulswzx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vmulswzx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulswzx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmulswzx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulsl_vvvl : GCCBuiltin<"__builtin_ve_vl_vmulsl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulsl_vvvvl : GCCBuiltin<"__builtin_ve_vl_vmulsl_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulsl_vsvl : GCCBuiltin<"__builtin_ve_vl_vmulsl_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulsl_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmulsl_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulsl_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vmulsl_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulsl_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmulsl_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulslw_vvvl : GCCBuiltin<"__builtin_ve_vl_vmulslw_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulslw_vvvvl : GCCBuiltin<"__builtin_ve_vl_vmulslw_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulslw_vsvl : GCCBuiltin<"__builtin_ve_vl_vmulslw_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmulslw_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmulslw_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivul_vvvl : GCCBuiltin<"__builtin_ve_vl_vdivul_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivul_vvvvl : GCCBuiltin<"__builtin_ve_vl_vdivul_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivul_vsvl : GCCBuiltin<"__builtin_ve_vl_vdivul_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivul_vsvvl : GCCBuiltin<"__builtin_ve_vl_vdivul_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivul_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vdivul_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivul_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vdivul_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivuw_vvvl : GCCBuiltin<"__builtin_ve_vl_vdivuw_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivuw_vvvvl : GCCBuiltin<"__builtin_ve_vl_vdivuw_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivuw_vsvl : GCCBuiltin<"__builtin_ve_vl_vdivuw_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivuw_vsvvl : GCCBuiltin<"__builtin_ve_vl_vdivuw_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivuw_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vdivuw_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivuw_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vdivuw_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivul_vvsl : GCCBuiltin<"__builtin_ve_vl_vdivul_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivul_vvsvl : GCCBuiltin<"__builtin_ve_vl_vdivul_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivul_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vdivul_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivuw_vvsl : GCCBuiltin<"__builtin_ve_vl_vdivuw_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivuw_vvsvl : GCCBuiltin<"__builtin_ve_vl_vdivuw_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivuw_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vdivuw_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivswsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vdivswsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivswsx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vdivswsx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivswsx_vsvl : GCCBuiltin<"__builtin_ve_vl_vdivswsx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivswsx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vdivswsx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivswsx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vdivswsx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivswsx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vdivswsx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivswzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vdivswzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivswzx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vdivswzx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivswzx_vsvl : GCCBuiltin<"__builtin_ve_vl_vdivswzx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivswzx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vdivswzx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivswzx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vdivswzx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivswzx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vdivswzx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivswsx_vvsl : GCCBuiltin<"__builtin_ve_vl_vdivswsx_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivswsx_vvsvl : GCCBuiltin<"__builtin_ve_vl_vdivswsx_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivswsx_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vdivswsx_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivswzx_vvsl : GCCBuiltin<"__builtin_ve_vl_vdivswzx_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivswzx_vvsvl : GCCBuiltin<"__builtin_ve_vl_vdivswzx_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivswzx_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vdivswzx_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivsl_vvvl : GCCBuiltin<"__builtin_ve_vl_vdivsl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivsl_vvvvl : GCCBuiltin<"__builtin_ve_vl_vdivsl_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivsl_vsvl : GCCBuiltin<"__builtin_ve_vl_vdivsl_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivsl_vsvvl : GCCBuiltin<"__builtin_ve_vl_vdivsl_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivsl_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vdivsl_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivsl_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vdivsl_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivsl_vvsl : GCCBuiltin<"__builtin_ve_vl_vdivsl_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivsl_vvsvl : GCCBuiltin<"__builtin_ve_vl_vdivsl_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vdivsl_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vdivsl_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpul_vvvl : GCCBuiltin<"__builtin_ve_vl_vcmpul_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpul_vvvvl : GCCBuiltin<"__builtin_ve_vl_vcmpul_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpul_vsvl : GCCBuiltin<"__builtin_ve_vl_vcmpul_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpul_vsvvl : GCCBuiltin<"__builtin_ve_vl_vcmpul_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpul_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpul_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpul_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpul_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpuw_vvvl : GCCBuiltin<"__builtin_ve_vl_vcmpuw_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpuw_vvvvl : GCCBuiltin<"__builtin_ve_vl_vcmpuw_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpuw_vsvl : GCCBuiltin<"__builtin_ve_vl_vcmpuw_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpuw_vsvvl : GCCBuiltin<"__builtin_ve_vl_vcmpuw_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpuw_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpuw_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpuw_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpuw_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcmpu_vvvl : GCCBuiltin<"__builtin_ve_vl_pvcmpu_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcmpu_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvcmpu_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcmpu_vsvl : GCCBuiltin<"__builtin_ve_vl_pvcmpu_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcmpu_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvcmpu_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcmpu_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvcmpu_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcmpu_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvcmpu_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpswsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vcmpswsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpswsx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vcmpswsx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpswsx_vsvl : GCCBuiltin<"__builtin_ve_vl_vcmpswsx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpswsx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vcmpswsx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpswsx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpswsx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpswsx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpswsx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpswzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vcmpswzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpswzx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vcmpswzx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpswzx_vsvl : GCCBuiltin<"__builtin_ve_vl_vcmpswzx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpswzx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vcmpswzx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpswzx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpswzx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpswzx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpswzx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcmps_vvvl : GCCBuiltin<"__builtin_ve_vl_pvcmps_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcmps_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvcmps_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcmps_vsvl : GCCBuiltin<"__builtin_ve_vl_pvcmps_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcmps_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvcmps_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcmps_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvcmps_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcmps_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvcmps_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpsl_vvvl : GCCBuiltin<"__builtin_ve_vl_vcmpsl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpsl_vvvvl : GCCBuiltin<"__builtin_ve_vl_vcmpsl_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpsl_vsvl : GCCBuiltin<"__builtin_ve_vl_vcmpsl_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpsl_vsvvl : GCCBuiltin<"__builtin_ve_vl_vcmpsl_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpsl_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpsl_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcmpsl_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vcmpsl_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmaxswsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vmaxswsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmaxswsx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vmaxswsx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmaxswsx_vsvl : GCCBuiltin<"__builtin_ve_vl_vmaxswsx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmaxswsx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmaxswsx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmaxswsx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vmaxswsx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmaxswsx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmaxswsx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmaxswzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vmaxswzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmaxswzx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vmaxswzx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmaxswzx_vsvl : GCCBuiltin<"__builtin_ve_vl_vmaxswzx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmaxswzx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmaxswzx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmaxswzx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vmaxswzx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmaxswzx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmaxswzx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvmaxs_vvvl : GCCBuiltin<"__builtin_ve_vl_pvmaxs_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvmaxs_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvmaxs_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvmaxs_vsvl : GCCBuiltin<"__builtin_ve_vl_pvmaxs_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvmaxs_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvmaxs_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvmaxs_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvmaxs_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvmaxs_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvmaxs_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vminswsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vminswsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vminswsx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vminswsx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vminswsx_vsvl : GCCBuiltin<"__builtin_ve_vl_vminswsx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vminswsx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vminswsx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vminswsx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vminswsx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vminswsx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vminswsx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vminswzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vminswzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vminswzx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vminswzx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vminswzx_vsvl : GCCBuiltin<"__builtin_ve_vl_vminswzx_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vminswzx_vsvvl : GCCBuiltin<"__builtin_ve_vl_vminswzx_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vminswzx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vminswzx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vminswzx_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vminswzx_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvmins_vvvl : GCCBuiltin<"__builtin_ve_vl_pvmins_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvmins_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvmins_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvmins_vsvl : GCCBuiltin<"__builtin_ve_vl_pvmins_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvmins_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvmins_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvmins_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvmins_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvmins_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvmins_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmaxsl_vvvl : GCCBuiltin<"__builtin_ve_vl_vmaxsl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmaxsl_vvvvl : GCCBuiltin<"__builtin_ve_vl_vmaxsl_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmaxsl_vsvl : GCCBuiltin<"__builtin_ve_vl_vmaxsl_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmaxsl_vsvvl : GCCBuiltin<"__builtin_ve_vl_vmaxsl_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmaxsl_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vmaxsl_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmaxsl_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmaxsl_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vminsl_vvvl : GCCBuiltin<"__builtin_ve_vl_vminsl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vminsl_vvvvl : GCCBuiltin<"__builtin_ve_vl_vminsl_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vminsl_vsvl : GCCBuiltin<"__builtin_ve_vl_vminsl_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vminsl_vsvvl : GCCBuiltin<"__builtin_ve_vl_vminsl_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vminsl_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vminsl_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vminsl_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vminsl_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vand_vvvl : GCCBuiltin<"__builtin_ve_vl_vand_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vand_vvvvl : GCCBuiltin<"__builtin_ve_vl_vand_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vand_vsvl : GCCBuiltin<"__builtin_ve_vl_vand_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vand_vsvvl : GCCBuiltin<"__builtin_ve_vl_vand_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vand_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vand_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vand_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vand_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvand_vvvl : GCCBuiltin<"__builtin_ve_vl_pvand_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvand_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvand_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvand_vsvl : GCCBuiltin<"__builtin_ve_vl_pvand_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvand_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvand_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvand_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvand_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvand_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvand_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vor_vvvl : GCCBuiltin<"__builtin_ve_vl_vor_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vor_vvvvl : GCCBuiltin<"__builtin_ve_vl_vor_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vor_vsvl : GCCBuiltin<"__builtin_ve_vl_vor_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vor_vsvvl : GCCBuiltin<"__builtin_ve_vl_vor_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vor_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vor_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vor_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vor_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvor_vvvl : GCCBuiltin<"__builtin_ve_vl_pvor_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvor_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvor_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvor_vsvl : GCCBuiltin<"__builtin_ve_vl_pvor_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvor_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvor_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvor_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvor_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvor_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvor_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vxor_vvvl : GCCBuiltin<"__builtin_ve_vl_vxor_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vxor_vvvvl : GCCBuiltin<"__builtin_ve_vl_vxor_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vxor_vsvl : GCCBuiltin<"__builtin_ve_vl_vxor_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vxor_vsvvl : GCCBuiltin<"__builtin_ve_vl_vxor_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vxor_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vxor_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vxor_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vxor_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvxor_vvvl : GCCBuiltin<"__builtin_ve_vl_pvxor_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvxor_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvxor_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvxor_vsvl : GCCBuiltin<"__builtin_ve_vl_pvxor_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvxor_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvxor_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvxor_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvxor_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvxor_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvxor_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_veqv_vvvl : GCCBuiltin<"__builtin_ve_vl_veqv_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_veqv_vvvvl : GCCBuiltin<"__builtin_ve_vl_veqv_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_veqv_vsvl : GCCBuiltin<"__builtin_ve_vl_veqv_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_veqv_vsvvl : GCCBuiltin<"__builtin_ve_vl_veqv_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_veqv_vvvmvl : GCCBuiltin<"__builtin_ve_vl_veqv_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_veqv_vsvmvl : GCCBuiltin<"__builtin_ve_vl_veqv_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pveqv_vvvl : GCCBuiltin<"__builtin_ve_vl_pveqv_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pveqv_vvvvl : GCCBuiltin<"__builtin_ve_vl_pveqv_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pveqv_vsvl : GCCBuiltin<"__builtin_ve_vl_pveqv_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pveqv_vsvvl : GCCBuiltin<"__builtin_ve_vl_pveqv_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pveqv_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pveqv_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pveqv_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pveqv_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vseq_vl : GCCBuiltin<"__builtin_ve_vl_vseq_vl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vseq_vvl : GCCBuiltin<"__builtin_ve_vl_vseq_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvseqlo_vl : GCCBuiltin<"__builtin_ve_vl_pvseqlo_vl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvseqlo_vvl : GCCBuiltin<"__builtin_ve_vl_pvseqlo_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsequp_vl : GCCBuiltin<"__builtin_ve_vl_pvsequp_vl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsequp_vvl : GCCBuiltin<"__builtin_ve_vl_pvsequp_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvseq_vl : GCCBuiltin<"__builtin_ve_vl_pvseq_vl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvseq_vvl : GCCBuiltin<"__builtin_ve_vl_pvseq_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsll_vvvl : GCCBuiltin<"__builtin_ve_vl_vsll_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsll_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsll_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsll_vvsl : GCCBuiltin<"__builtin_ve_vl_vsll_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsll_vvsvl : GCCBuiltin<"__builtin_ve_vl_vsll_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsll_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsll_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsll_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vsll_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsll_vvvl : GCCBuiltin<"__builtin_ve_vl_pvsll_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsll_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvsll_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsll_vvsl : GCCBuiltin<"__builtin_ve_vl_pvsll_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsll_vvsvl : GCCBuiltin<"__builtin_ve_vl_pvsll_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsll_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvsll_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsll_vvsMvl : GCCBuiltin<"__builtin_ve_vl_pvsll_vvsMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsrl_vvvl : GCCBuiltin<"__builtin_ve_vl_vsrl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsrl_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsrl_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsrl_vvsl : GCCBuiltin<"__builtin_ve_vl_vsrl_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsrl_vvsvl : GCCBuiltin<"__builtin_ve_vl_vsrl_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsrl_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsrl_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsrl_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vsrl_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsrl_vvvl : GCCBuiltin<"__builtin_ve_vl_pvsrl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsrl_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvsrl_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsrl_vvsl : GCCBuiltin<"__builtin_ve_vl_pvsrl_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsrl_vvsvl : GCCBuiltin<"__builtin_ve_vl_pvsrl_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsrl_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvsrl_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsrl_vvsMvl : GCCBuiltin<"__builtin_ve_vl_pvsrl_vvsMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vslawsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vslawsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vslawsx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vslawsx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vslawsx_vvsl : GCCBuiltin<"__builtin_ve_vl_vslawsx_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vslawsx_vvsvl : GCCBuiltin<"__builtin_ve_vl_vslawsx_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vslawsx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vslawsx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vslawsx_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vslawsx_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vslawzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vslawzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vslawzx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vslawzx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vslawzx_vvsl : GCCBuiltin<"__builtin_ve_vl_vslawzx_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vslawzx_vvsvl : GCCBuiltin<"__builtin_ve_vl_vslawzx_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vslawzx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vslawzx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vslawzx_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vslawzx_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsla_vvvl : GCCBuiltin<"__builtin_ve_vl_pvsla_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsla_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvsla_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsla_vvsl : GCCBuiltin<"__builtin_ve_vl_pvsla_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsla_vvsvl : GCCBuiltin<"__builtin_ve_vl_pvsla_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsla_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvsla_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsla_vvsMvl : GCCBuiltin<"__builtin_ve_vl_pvsla_vvsMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vslal_vvvl : GCCBuiltin<"__builtin_ve_vl_vslal_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vslal_vvvvl : GCCBuiltin<"__builtin_ve_vl_vslal_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vslal_vvsl : GCCBuiltin<"__builtin_ve_vl_vslal_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vslal_vvsvl : GCCBuiltin<"__builtin_ve_vl_vslal_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vslal_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vslal_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vslal_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vslal_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsrawsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vsrawsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsrawsx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsrawsx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsrawsx_vvsl : GCCBuiltin<"__builtin_ve_vl_vsrawsx_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsrawsx_vvsvl : GCCBuiltin<"__builtin_ve_vl_vsrawsx_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsrawsx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsrawsx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsrawsx_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vsrawsx_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsrawzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vsrawzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsrawzx_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsrawzx_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsrawzx_vvsl : GCCBuiltin<"__builtin_ve_vl_vsrawzx_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsrawzx_vvsvl : GCCBuiltin<"__builtin_ve_vl_vsrawzx_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsrawzx_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsrawzx_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsrawzx_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vsrawzx_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsra_vvvl : GCCBuiltin<"__builtin_ve_vl_pvsra_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsra_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvsra_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsra_vvsl : GCCBuiltin<"__builtin_ve_vl_pvsra_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsra_vvsvl : GCCBuiltin<"__builtin_ve_vl_pvsra_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsra_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvsra_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvsra_vvsMvl : GCCBuiltin<"__builtin_ve_vl_pvsra_vvsMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsral_vvvl : GCCBuiltin<"__builtin_ve_vl_vsral_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsral_vvvvl : GCCBuiltin<"__builtin_ve_vl_vsral_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsral_vvsl : GCCBuiltin<"__builtin_ve_vl_vsral_vvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsral_vvsvl : GCCBuiltin<"__builtin_ve_vl_vsral_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsral_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vsral_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsral_vvsmvl : GCCBuiltin<"__builtin_ve_vl_vsral_vvsmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsfa_vvssl : GCCBuiltin<"__builtin_ve_vl_vsfa_vvssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsfa_vvssvl : GCCBuiltin<"__builtin_ve_vl_vsfa_vvssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsfa_vvssmvl : GCCBuiltin<"__builtin_ve_vl_vsfa_vvssmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfaddd_vvvl : GCCBuiltin<"__builtin_ve_vl_vfaddd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfaddd_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfaddd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfaddd_vsvl : GCCBuiltin<"__builtin_ve_vl_vfaddd_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfaddd_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfaddd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfaddd_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfaddd_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfaddd_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfaddd_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfadds_vvvl : GCCBuiltin<"__builtin_ve_vl_vfadds_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfadds_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfadds_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfadds_vsvl : GCCBuiltin<"__builtin_ve_vl_vfadds_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfadds_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfadds_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfadds_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfadds_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfadds_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfadds_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfadd_vvvl : GCCBuiltin<"__builtin_ve_vl_pvfadd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfadd_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfadd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfadd_vsvl : GCCBuiltin<"__builtin_ve_vl_pvfadd_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfadd_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfadd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfadd_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfadd_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfadd_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfadd_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsubd_vvvl : GCCBuiltin<"__builtin_ve_vl_vfsubd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsubd_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfsubd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsubd_vsvl : GCCBuiltin<"__builtin_ve_vl_vfsubd_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsubd_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfsubd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsubd_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfsubd_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsubd_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfsubd_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsubs_vvvl : GCCBuiltin<"__builtin_ve_vl_vfsubs_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsubs_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfsubs_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsubs_vsvl : GCCBuiltin<"__builtin_ve_vl_vfsubs_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsubs_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfsubs_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsubs_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfsubs_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsubs_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfsubs_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfsub_vvvl : GCCBuiltin<"__builtin_ve_vl_pvfsub_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfsub_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfsub_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfsub_vsvl : GCCBuiltin<"__builtin_ve_vl_pvfsub_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfsub_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfsub_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfsub_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfsub_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfsub_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfsub_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmuld_vvvl : GCCBuiltin<"__builtin_ve_vl_vfmuld_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmuld_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmuld_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmuld_vsvl : GCCBuiltin<"__builtin_ve_vl_vfmuld_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmuld_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmuld_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmuld_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmuld_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmuld_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmuld_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmuls_vvvl : GCCBuiltin<"__builtin_ve_vl_vfmuls_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmuls_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmuls_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmuls_vsvl : GCCBuiltin<"__builtin_ve_vl_vfmuls_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmuls_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmuls_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmuls_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmuls_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmuls_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmuls_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmul_vvvl : GCCBuiltin<"__builtin_ve_vl_pvfmul_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmul_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfmul_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmul_vsvl : GCCBuiltin<"__builtin_ve_vl_pvfmul_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmul_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfmul_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmul_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmul_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmul_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmul_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfdivd_vvvl : GCCBuiltin<"__builtin_ve_vl_vfdivd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfdivd_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfdivd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfdivd_vsvl : GCCBuiltin<"__builtin_ve_vl_vfdivd_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfdivd_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfdivd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfdivd_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfdivd_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfdivd_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfdivd_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfdivs_vvvl : GCCBuiltin<"__builtin_ve_vl_vfdivs_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfdivs_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfdivs_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfdivs_vsvl : GCCBuiltin<"__builtin_ve_vl_vfdivs_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfdivs_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfdivs_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfdivs_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfdivs_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfdivs_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfdivs_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsqrtd_vvl : GCCBuiltin<"__builtin_ve_vl_vfsqrtd_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsqrtd_vvvl : GCCBuiltin<"__builtin_ve_vl_vfsqrtd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsqrts_vvl : GCCBuiltin<"__builtin_ve_vl_vfsqrts_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsqrts_vvvl : GCCBuiltin<"__builtin_ve_vl_vfsqrts_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfcmpd_vvvl : GCCBuiltin<"__builtin_ve_vl_vfcmpd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfcmpd_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfcmpd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfcmpd_vsvl : GCCBuiltin<"__builtin_ve_vl_vfcmpd_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfcmpd_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfcmpd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfcmpd_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfcmpd_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfcmpd_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfcmpd_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfcmps_vvvl : GCCBuiltin<"__builtin_ve_vl_vfcmps_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfcmps_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfcmps_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfcmps_vsvl : GCCBuiltin<"__builtin_ve_vl_vfcmps_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfcmps_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfcmps_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfcmps_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfcmps_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfcmps_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfcmps_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfcmp_vvvl : GCCBuiltin<"__builtin_ve_vl_pvfcmp_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfcmp_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfcmp_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfcmp_vsvl : GCCBuiltin<"__builtin_ve_vl_pvfcmp_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfcmp_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfcmp_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfcmp_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfcmp_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfcmp_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfcmp_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmaxd_vvvl : GCCBuiltin<"__builtin_ve_vl_vfmaxd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmaxd_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmaxd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmaxd_vsvl : GCCBuiltin<"__builtin_ve_vl_vfmaxd_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmaxd_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmaxd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmaxd_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmaxd_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmaxd_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmaxd_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmaxs_vvvl : GCCBuiltin<"__builtin_ve_vl_vfmaxs_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmaxs_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmaxs_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmaxs_vsvl : GCCBuiltin<"__builtin_ve_vl_vfmaxs_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmaxs_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmaxs_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmaxs_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmaxs_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmaxs_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmaxs_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmax_vvvl : GCCBuiltin<"__builtin_ve_vl_pvfmax_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmax_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfmax_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmax_vsvl : GCCBuiltin<"__builtin_ve_vl_pvfmax_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmax_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfmax_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmax_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmax_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmax_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmax_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmind_vvvl : GCCBuiltin<"__builtin_ve_vl_vfmind_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmind_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmind_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmind_vsvl : GCCBuiltin<"__builtin_ve_vl_vfmind_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmind_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmind_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmind_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmind_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmind_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmind_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmins_vvvl : GCCBuiltin<"__builtin_ve_vl_vfmins_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmins_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmins_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmins_vsvl : GCCBuiltin<"__builtin_ve_vl_vfmins_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmins_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmins_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmins_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmins_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmins_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmins_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmin_vvvl : GCCBuiltin<"__builtin_ve_vl_pvfmin_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmin_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfmin_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmin_vsvl : GCCBuiltin<"__builtin_ve_vl_pvfmin_vsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmin_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfmin_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmin_vvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmin_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmin_vsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmin_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmadd_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmadd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmadd_vvvvvl : GCCBuiltin<"__builtin_ve_vl_vfmadd_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmadd_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmadd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmadd_vsvvvl : GCCBuiltin<"__builtin_ve_vl_vfmadd_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmadd_vvsvl : GCCBuiltin<"__builtin_ve_vl_vfmadd_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmadd_vvsvvl : GCCBuiltin<"__builtin_ve_vl_vfmadd_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmadd_vvvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmadd_vvvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmadd_vsvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmadd_vsvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmadd_vvsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmadd_vvsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmads_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmads_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmads_vvvvvl : GCCBuiltin<"__builtin_ve_vl_vfmads_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmads_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmads_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmads_vsvvvl : GCCBuiltin<"__builtin_ve_vl_vfmads_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmads_vvsvl : GCCBuiltin<"__builtin_ve_vl_vfmads_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmads_vvsvvl : GCCBuiltin<"__builtin_ve_vl_vfmads_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmads_vvvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmads_vvvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmads_vsvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmads_vsvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmads_vvsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmads_vvsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmad_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfmad_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmad_vvvvvl : GCCBuiltin<"__builtin_ve_vl_pvfmad_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmad_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfmad_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmad_vsvvvl : GCCBuiltin<"__builtin_ve_vl_pvfmad_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmad_vvsvl : GCCBuiltin<"__builtin_ve_vl_pvfmad_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmad_vvsvvl : GCCBuiltin<"__builtin_ve_vl_pvfmad_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmad_vvvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmad_vvvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmad_vsvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmad_vsvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmad_vvsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmad_vvsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmsbd_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmsbd_vvvvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbd_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmsbd_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmsbd_vsvvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbd_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmsbd_vvsvl : GCCBuiltin<"__builtin_ve_vl_vfmsbd_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmsbd_vvsvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbd_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmsbd_vvvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmsbd_vvvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmsbd_vsvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmsbd_vsvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmsbd_vvsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmsbd_vvsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmsbs_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbs_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmsbs_vvvvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbs_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmsbs_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbs_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmsbs_vsvvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbs_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmsbs_vvsvl : GCCBuiltin<"__builtin_ve_vl_vfmsbs_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmsbs_vvsvvl : GCCBuiltin<"__builtin_ve_vl_vfmsbs_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmsbs_vvvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmsbs_vvvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmsbs_vsvvmvl : GCCBuiltin<"__builtin_ve_vl_vfmsbs_vsvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmsbs_vvsvmvl : GCCBuiltin<"__builtin_ve_vl_vfmsbs_vvsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmsb_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfmsb_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmsb_vvvvvl : GCCBuiltin<"__builtin_ve_vl_pvfmsb_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmsb_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfmsb_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmsb_vsvvvl : GCCBuiltin<"__builtin_ve_vl_pvfmsb_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmsb_vvsvl : GCCBuiltin<"__builtin_ve_vl_pvfmsb_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmsb_vvsvvl : GCCBuiltin<"__builtin_ve_vl_pvfmsb_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmsb_vvvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmsb_vvvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmsb_vsvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmsb_vsvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmsb_vvsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfmsb_vvsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmadd_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmadd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmadd_vvvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmadd_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmadd_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfnmadd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmadd_vsvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmadd_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmadd_vvsvl : GCCBuiltin<"__builtin_ve_vl_vfnmadd_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmadd_vvsvvl : GCCBuiltin<"__builtin_ve_vl_vfnmadd_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmadd_vvvvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmadd_vvvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmadd_vsvvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmadd_vsvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmadd_vvsvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmadd_vvsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmads_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmads_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmads_vvvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmads_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmads_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfnmads_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmads_vsvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmads_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmads_vvsvl : GCCBuiltin<"__builtin_ve_vl_vfnmads_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmads_vvsvvl : GCCBuiltin<"__builtin_ve_vl_vfnmads_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmads_vvvvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmads_vvvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmads_vsvvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmads_vsvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmads_vvsvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmads_vvsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfnmad_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmad_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfnmad_vvvvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmad_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfnmad_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmad_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfnmad_vsvvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmad_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfnmad_vvsvl : GCCBuiltin<"__builtin_ve_vl_pvfnmad_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfnmad_vvsvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmad_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfnmad_vvvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfnmad_vvvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfnmad_vsvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfnmad_vsvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfnmad_vvsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfnmad_vvsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmsbd_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbd_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmsbd_vvvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbd_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmsbd_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbd_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmsbd_vsvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbd_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmsbd_vvsvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbd_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmsbd_vvsvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbd_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmsbd_vvvvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbd_vvvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmsbd_vsvvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbd_vsvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmsbd_vvsvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbd_vvsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmsbs_vvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbs_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmsbs_vvvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbs_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmsbs_vsvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbs_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmsbs_vsvvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbs_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmsbs_vvsvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbs_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmsbs_vvsvvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbs_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmsbs_vvvvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbs_vvvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmsbs_vsvvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbs_vsvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfnmsbs_vvsvmvl : GCCBuiltin<"__builtin_ve_vl_vfnmsbs_vvsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<f32>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfnmsb_vvvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmsb_vvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfnmsb_vvvvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmsb_vvvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfnmsb_vsvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmsb_vsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfnmsb_vsvvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmsb_vsvvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfnmsb_vvsvl : GCCBuiltin<"__builtin_ve_vl_pvfnmsb_vvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfnmsb_vvsvvl : GCCBuiltin<"__builtin_ve_vl_pvfnmsb_vvsvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfnmsb_vvvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfnmsb_vvvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfnmsb_vsvvMvl : GCCBuiltin<"__builtin_ve_vl_pvfnmsb_vsvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfnmsb_vvsvMvl : GCCBuiltin<"__builtin_ve_vl_pvfnmsb_vvsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrcpd_vvl : GCCBuiltin<"__builtin_ve_vl_vrcpd_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrcpd_vvvl : GCCBuiltin<"__builtin_ve_vl_vrcpd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrcps_vvl : GCCBuiltin<"__builtin_ve_vl_vrcps_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrcps_vvvl : GCCBuiltin<"__builtin_ve_vl_vrcps_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvrcp_vvl : GCCBuiltin<"__builtin_ve_vl_pvrcp_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvrcp_vvvl : GCCBuiltin<"__builtin_ve_vl_pvrcp_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrsqrtd_vvl : GCCBuiltin<"__builtin_ve_vl_vrsqrtd_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrsqrtd_vvvl : GCCBuiltin<"__builtin_ve_vl_vrsqrtd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrsqrts_vvl : GCCBuiltin<"__builtin_ve_vl_vrsqrts_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrsqrts_vvvl : GCCBuiltin<"__builtin_ve_vl_vrsqrts_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvrsqrt_vvl : GCCBuiltin<"__builtin_ve_vl_pvrsqrt_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvrsqrt_vvvl : GCCBuiltin<"__builtin_ve_vl_pvrsqrt_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrsqrtdnex_vvl : GCCBuiltin<"__builtin_ve_vl_vrsqrtdnex_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrsqrtdnex_vvvl : GCCBuiltin<"__builtin_ve_vl_vrsqrtdnex_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrsqrtsnex_vvl : GCCBuiltin<"__builtin_ve_vl_vrsqrtsnex_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrsqrtsnex_vvvl : GCCBuiltin<"__builtin_ve_vl_vrsqrtsnex_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvrsqrtnex_vvl : GCCBuiltin<"__builtin_ve_vl_pvrsqrtnex_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvrsqrtnex_vvvl : GCCBuiltin<"__builtin_ve_vl_pvrsqrtnex_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwdsx_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdsx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwdsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwdsx_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdsx_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwdsxrz_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdsxrz_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwdsxrz_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdsxrz_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwdsxrz_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdsxrz_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwdzx_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdzx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwdzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwdzx_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdzx_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwdzxrz_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdzxrz_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwdzxrz_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdzxrz_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwdzxrz_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtwdzxrz_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwssx_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtwssx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwssx_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtwssx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwssx_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtwssx_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwssxrz_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtwssxrz_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwssxrz_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtwssxrz_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwssxrz_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtwssxrz_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwszx_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtwszx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwszx_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtwszx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwszx_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtwszx_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwszxrz_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtwszxrz_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwszxrz_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtwszxrz_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtwszxrz_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtwszxrz_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcvtws_vvl : GCCBuiltin<"__builtin_ve_vl_pvcvtws_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcvtws_vvvl : GCCBuiltin<"__builtin_ve_vl_pvcvtws_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcvtws_vvMvl : GCCBuiltin<"__builtin_ve_vl_pvcvtws_vvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcvtwsrz_vvl : GCCBuiltin<"__builtin_ve_vl_pvcvtwsrz_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcvtwsrz_vvvl : GCCBuiltin<"__builtin_ve_vl_pvcvtwsrz_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcvtwsrz_vvMvl : GCCBuiltin<"__builtin_ve_vl_pvcvtwsrz_vvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtld_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtld_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtld_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtld_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtld_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtld_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtldrz_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtldrz_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtldrz_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtldrz_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtldrz_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcvtldrz_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtdw_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtdw_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtdw_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtdw_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtsw_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtsw_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtsw_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtsw_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcvtsw_vvl : GCCBuiltin<"__builtin_ve_vl_pvcvtsw_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvcvtsw_vvvl : GCCBuiltin<"__builtin_ve_vl_pvcvtsw_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtdl_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtdl_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtdl_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtdl_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtds_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtds_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtds_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtds_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtsd_vvl : GCCBuiltin<"__builtin_ve_vl_vcvtsd_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcvtsd_vvvl : GCCBuiltin<"__builtin_ve_vl_vcvtsd_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmrg_vvvml : GCCBuiltin<"__builtin_ve_vl_vmrg_vvvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmrg_vvvmvl : GCCBuiltin<"__builtin_ve_vl_vmrg_vvvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmrg_vsvml : GCCBuiltin<"__builtin_ve_vl_vmrg_vsvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmrg_vsvmvl : GCCBuiltin<"__builtin_ve_vl_vmrg_vsvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i64>, LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmrgw_vvvMl : GCCBuiltin<"__builtin_ve_vl_vmrgw_vvvMl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmrgw_vvvMvl : GCCBuiltin<"__builtin_ve_vl_vmrgw_vvvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmrgw_vsvMl : GCCBuiltin<"__builtin_ve_vl_vmrgw_vsvMl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vmrgw_vsvMvl : GCCBuiltin<"__builtin_ve_vl_vmrgw_vsvMvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<i32>, LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vshf_vvvsl : GCCBuiltin<"__builtin_ve_vl_vshf_vvvsl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vshf_vvvsvl : GCCBuiltin<"__builtin_ve_vl_vshf_vvvsvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vcp_vvmvl : GCCBuiltin<"__builtin_ve_vl_vcp_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vex_vvmvl : GCCBuiltin<"__builtin_ve_vl_vex_vvmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklat_ml : GCCBuiltin<"__builtin_ve_vl_vfmklat_ml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklaf_ml : GCCBuiltin<"__builtin_ve_vl_vfmklaf_ml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkat_Ml : GCCBuiltin<"__builtin_ve_vl_pvfmkat_Ml">, Intrinsic<[LLVMType<v512i1>], [LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkaf_Ml : GCCBuiltin<"__builtin_ve_vl_pvfmkaf_Ml">, Intrinsic<[LLVMType<v512i1>], [LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklgt_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklgt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklgt_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklgt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkllt_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkllt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkllt_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkllt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklne_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklne_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklne_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklne_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkleq_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkleq_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkleq_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkleq_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklge_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklge_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklge_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklge_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklle_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklle_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklle_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklle_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklnum_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklnum_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklnum_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklnum_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklgtnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklgtnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklgtnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklgtnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklltnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklltnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklltnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklltnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklnenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklnenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklnenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklnenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkleqnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkleqnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkleqnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkleqnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklgenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmklgenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmklgenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmklgenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkllenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkllenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkllenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkllenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwgt_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwgt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwgt_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwgt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwlt_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwlt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwlt_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwlt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwne_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwne_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwne_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwne_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkweq_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkweq_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkweq_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkweq_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwge_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwge_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwge_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwge_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwle_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwle_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwle_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwle_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwnum_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwnum_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwnum_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwnum_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwgtnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwgtnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwgtnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwgtnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwltnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwltnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwltnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwltnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwnenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwnenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwnenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwnenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkweqnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkweqnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkweqnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkweqnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwgenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwgenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwgenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwgenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwlenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkwlenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkwlenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkwlenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlogt_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlogt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupgt_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupgt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlogt_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlogt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupgt_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupgt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlolt_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlolt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwuplt_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwuplt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlolt_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlolt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwuplt_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwuplt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlone_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlone_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupne_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupne_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlone_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlone_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupne_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupne_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwloeq_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwloeq_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupeq_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupeq_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwloeq_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwloeq_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupeq_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupeq_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwloge_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwloge_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupge_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupge_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwloge_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwloge_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupge_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupge_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlole_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlole_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwuple_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwuple_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlole_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlole_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwuple_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwuple_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlonum_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlonum_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupnum_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupnum_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlonum_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlonum_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupnum_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupnum_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlonan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlonan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlonan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlonan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlogtnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlogtnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupgtnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupgtnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlogtnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlogtnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupgtnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupgtnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwloltnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwloltnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupltnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupltnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwloltnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwloltnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupltnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupltnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlonenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlonenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupnenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupnenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlonenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlonenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupnenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupnenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwloeqnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwloeqnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupeqnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupeqnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwloeqnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwloeqnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupeqnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupeqnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlogenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlogenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupgenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwupgenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlogenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlogenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwupgenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwupgenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlolenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlolenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwuplenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwuplenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlolenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwlolenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwuplenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkwuplenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwgt_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwgt_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwgt_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwgt_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlt_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlt_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlt_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlt_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwne_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwne_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwne_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwne_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkweq_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkweq_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkweq_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkweq_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwge_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwge_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwge_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwge_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwle_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwle_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwle_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwle_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwnum_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwnum_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwnum_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwnum_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwnan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwnan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwnan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwnan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwgtnan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwgtnan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwgtnan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwgtnan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwltnan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwltnan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwltnan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwltnan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwnenan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwnenan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwnenan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwnenan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkweqnan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkweqnan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkweqnan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkweqnan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwgenan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwgenan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwgenan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwgenan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlenan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlenan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkwlenan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkwlenan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdgt_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdgt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdgt_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdgt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdlt_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdlt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdlt_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdlt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdne_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdne_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdne_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdne_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdeq_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdeq_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdeq_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdeq_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdge_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdge_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdge_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdge_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdle_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdle_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdle_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdle_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdnum_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdnum_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdnum_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdnum_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdgtnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdgtnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdgtnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdgtnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdltnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdltnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdltnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdltnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdnenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdnenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdnenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdnenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdeqnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdeqnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdeqnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdeqnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdgenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdgenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdgenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdgenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdlenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkdlenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkdlenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkdlenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksgt_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksgt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksgt_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksgt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkslt_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkslt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkslt_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkslt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksne_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksne_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksne_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksne_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkseq_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkseq_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkseq_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkseq_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksge_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksge_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksge_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksge_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksle_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksle_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksle_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksle_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksnum_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksnum_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksnum_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksnum_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksgtnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksgtnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksgtnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksgtnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksltnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksltnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksltnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksltnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksnenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksnenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksnenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksnenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkseqnan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkseqnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkseqnan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkseqnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksgenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmksgenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmksgenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmksgenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkslenan_mvl : GCCBuiltin<"__builtin_ve_vl_vfmkslenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfmkslenan_mvml : GCCBuiltin<"__builtin_ve_vl_vfmkslenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslogt_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslogt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupgt_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupgt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslogt_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslogt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupgt_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupgt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslolt_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslolt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksuplt_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksuplt_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslolt_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslolt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksuplt_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksuplt_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslone_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslone_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupne_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupne_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslone_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslone_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupne_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupne_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksloeq_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksloeq_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupeq_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupeq_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksloeq_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksloeq_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupeq_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupeq_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksloge_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksloge_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupge_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupge_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksloge_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksloge_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupge_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupge_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslole_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslole_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksuple_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksuple_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslole_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslole_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksuple_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksuple_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslonum_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslonum_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupnum_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupnum_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslonum_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslonum_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupnum_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupnum_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslonan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslonan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslonan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslonan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslogtnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslogtnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupgtnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupgtnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslogtnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslogtnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupgtnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupgtnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksloltnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksloltnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupltnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupltnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksloltnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksloltnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupltnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupltnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslonenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslonenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupnenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupnenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslonenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslonenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupnenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupnenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksloeqnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksloeqnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupeqnan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupeqnan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksloeqnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksloeqnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupeqnan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupeqnan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslogenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslogenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupgenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksupgenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslogenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslogenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksupgenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksupgenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslolenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslolenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksuplenan_mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksuplenan_mvl">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslolenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmkslolenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksuplenan_mvml : GCCBuiltin<"__builtin_ve_vl_pvfmksuplenan_mvml">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksgt_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksgt_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksgt_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksgt_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslt_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslt_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslt_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkslt_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksne_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksne_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksne_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksne_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkseq_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkseq_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkseq_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkseq_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksge_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksge_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksge_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksge_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksle_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksle_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksle_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksle_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksnum_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksnum_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksnum_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksnum_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksnan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksnan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksnan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksnan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksgtnan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksgtnan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksgtnan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksgtnan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksltnan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksltnan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksltnan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksltnan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksnenan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksnenan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksnenan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksnenan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkseqnan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkseqnan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkseqnan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkseqnan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksgenan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmksgenan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmksgenan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmksgenan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslenan_Mvl : GCCBuiltin<"__builtin_ve_vl_pvfmkslenan_Mvl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pvfmkslenan_MvMl : GCCBuiltin<"__builtin_ve_vl_pvfmkslenan_MvMl">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v256f64>, LLVMType<v512i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsumwsx_vvl : GCCBuiltin<"__builtin_ve_vl_vsumwsx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsumwsx_vvml : GCCBuiltin<"__builtin_ve_vl_vsumwsx_vvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsumwzx_vvl : GCCBuiltin<"__builtin_ve_vl_vsumwzx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsumwzx_vvml : GCCBuiltin<"__builtin_ve_vl_vsumwzx_vvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsuml_vvl : GCCBuiltin<"__builtin_ve_vl_vsuml_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsuml_vvml : GCCBuiltin<"__builtin_ve_vl_vsuml_vvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsumd_vvl : GCCBuiltin<"__builtin_ve_vl_vfsumd_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsumd_vvml : GCCBuiltin<"__builtin_ve_vl_vfsumd_vvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsums_vvl : GCCBuiltin<"__builtin_ve_vl_vfsums_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfsums_vvml : GCCBuiltin<"__builtin_ve_vl_vfsums_vvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrmaxswfstsx_vvl : GCCBuiltin<"__builtin_ve_vl_vrmaxswfstsx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrmaxswfstsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vrmaxswfstsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrmaxswlstsx_vvl : GCCBuiltin<"__builtin_ve_vl_vrmaxswlstsx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrmaxswlstsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vrmaxswlstsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrmaxswfstzx_vvl : GCCBuiltin<"__builtin_ve_vl_vrmaxswfstzx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrmaxswfstzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vrmaxswfstzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrmaxswlstzx_vvl : GCCBuiltin<"__builtin_ve_vl_vrmaxswlstzx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrmaxswlstzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vrmaxswlstzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrminswfstsx_vvl : GCCBuiltin<"__builtin_ve_vl_vrminswfstsx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrminswfstsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vrminswfstsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrminswlstsx_vvl : GCCBuiltin<"__builtin_ve_vl_vrminswlstsx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrminswlstsx_vvvl : GCCBuiltin<"__builtin_ve_vl_vrminswlstsx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrminswfstzx_vvl : GCCBuiltin<"__builtin_ve_vl_vrminswfstzx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrminswfstzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vrminswfstzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrminswlstzx_vvl : GCCBuiltin<"__builtin_ve_vl_vrminswlstzx_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrminswlstzx_vvvl : GCCBuiltin<"__builtin_ve_vl_vrminswlstzx_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrmaxslfst_vvl : GCCBuiltin<"__builtin_ve_vl_vrmaxslfst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrmaxslfst_vvvl : GCCBuiltin<"__builtin_ve_vl_vrmaxslfst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrmaxsllst_vvl : GCCBuiltin<"__builtin_ve_vl_vrmaxsllst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrmaxsllst_vvvl : GCCBuiltin<"__builtin_ve_vl_vrmaxsllst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrminslfst_vvl : GCCBuiltin<"__builtin_ve_vl_vrminslfst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrminslfst_vvvl : GCCBuiltin<"__builtin_ve_vl_vrminslfst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrminsllst_vvl : GCCBuiltin<"__builtin_ve_vl_vrminsllst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrminsllst_vvvl : GCCBuiltin<"__builtin_ve_vl_vrminsllst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfrmaxdfst_vvl : GCCBuiltin<"__builtin_ve_vl_vfrmaxdfst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfrmaxdfst_vvvl : GCCBuiltin<"__builtin_ve_vl_vfrmaxdfst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfrmaxdlst_vvl : GCCBuiltin<"__builtin_ve_vl_vfrmaxdlst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfrmaxdlst_vvvl : GCCBuiltin<"__builtin_ve_vl_vfrmaxdlst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfrmaxsfst_vvl : GCCBuiltin<"__builtin_ve_vl_vfrmaxsfst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfrmaxsfst_vvvl : GCCBuiltin<"__builtin_ve_vl_vfrmaxsfst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfrmaxslst_vvl : GCCBuiltin<"__builtin_ve_vl_vfrmaxslst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfrmaxslst_vvvl : GCCBuiltin<"__builtin_ve_vl_vfrmaxslst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfrmindfst_vvl : GCCBuiltin<"__builtin_ve_vl_vfrmindfst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfrmindfst_vvvl : GCCBuiltin<"__builtin_ve_vl_vfrmindfst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfrmindlst_vvl : GCCBuiltin<"__builtin_ve_vl_vfrmindlst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfrmindlst_vvvl : GCCBuiltin<"__builtin_ve_vl_vfrmindlst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfrminsfst_vvl : GCCBuiltin<"__builtin_ve_vl_vfrminsfst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfrminsfst_vvvl : GCCBuiltin<"__builtin_ve_vl_vfrminsfst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfrminslst_vvl : GCCBuiltin<"__builtin_ve_vl_vfrminslst_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vfrminslst_vvvl : GCCBuiltin<"__builtin_ve_vl_vfrminslst_vvvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrand_vvl : GCCBuiltin<"__builtin_ve_vl_vrand_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrand_vvml : GCCBuiltin<"__builtin_ve_vl_vrand_vvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vror_vvl : GCCBuiltin<"__builtin_ve_vl_vror_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vror_vvml : GCCBuiltin<"__builtin_ve_vl_vror_vvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrxor_vvl : GCCBuiltin<"__builtin_ve_vl_vrxor_vvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vrxor_vvml : GCCBuiltin<"__builtin_ve_vl_vrxor_vvml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgt_vvssl : GCCBuiltin<"__builtin_ve_vl_vgt_vvssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgt_vvssvl : GCCBuiltin<"__builtin_ve_vl_vgt_vvssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgt_vvssml : GCCBuiltin<"__builtin_ve_vl_vgt_vvssml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgt_vvssmvl : GCCBuiltin<"__builtin_ve_vl_vgt_vvssmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtnc_vvssl : GCCBuiltin<"__builtin_ve_vl_vgtnc_vvssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtnc_vvssvl : GCCBuiltin<"__builtin_ve_vl_vgtnc_vvssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtnc_vvssml : GCCBuiltin<"__builtin_ve_vl_vgtnc_vvssml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtnc_vvssmvl : GCCBuiltin<"__builtin_ve_vl_vgtnc_vvssmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtu_vvssl : GCCBuiltin<"__builtin_ve_vl_vgtu_vvssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtu_vvssvl : GCCBuiltin<"__builtin_ve_vl_vgtu_vvssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtu_vvssml : GCCBuiltin<"__builtin_ve_vl_vgtu_vvssml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtu_vvssmvl : GCCBuiltin<"__builtin_ve_vl_vgtu_vvssmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtunc_vvssl : GCCBuiltin<"__builtin_ve_vl_vgtunc_vvssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtunc_vvssvl : GCCBuiltin<"__builtin_ve_vl_vgtunc_vvssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtunc_vvssml : GCCBuiltin<"__builtin_ve_vl_vgtunc_vvssml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtunc_vvssmvl : GCCBuiltin<"__builtin_ve_vl_vgtunc_vvssmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtlsx_vvssl : GCCBuiltin<"__builtin_ve_vl_vgtlsx_vvssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtlsx_vvssvl : GCCBuiltin<"__builtin_ve_vl_vgtlsx_vvssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtlsx_vvssml : GCCBuiltin<"__builtin_ve_vl_vgtlsx_vvssml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtlsx_vvssmvl : GCCBuiltin<"__builtin_ve_vl_vgtlsx_vvssmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtlsxnc_vvssl : GCCBuiltin<"__builtin_ve_vl_vgtlsxnc_vvssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtlsxnc_vvssvl : GCCBuiltin<"__builtin_ve_vl_vgtlsxnc_vvssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtlsxnc_vvssml : GCCBuiltin<"__builtin_ve_vl_vgtlsxnc_vvssml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtlsxnc_vvssmvl : GCCBuiltin<"__builtin_ve_vl_vgtlsxnc_vvssmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtlzx_vvssl : GCCBuiltin<"__builtin_ve_vl_vgtlzx_vvssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtlzx_vvssvl : GCCBuiltin<"__builtin_ve_vl_vgtlzx_vvssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtlzx_vvssml : GCCBuiltin<"__builtin_ve_vl_vgtlzx_vvssml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtlzx_vvssmvl : GCCBuiltin<"__builtin_ve_vl_vgtlzx_vvssmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtlzxnc_vvssl : GCCBuiltin<"__builtin_ve_vl_vgtlzxnc_vvssl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtlzxnc_vvssvl : GCCBuiltin<"__builtin_ve_vl_vgtlzxnc_vvssvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtlzxnc_vvssml : GCCBuiltin<"__builtin_ve_vl_vgtlzxnc_vvssml">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vgtlzxnc_vvssmvl : GCCBuiltin<"__builtin_ve_vl_vgtlzxnc_vvssmvl">, Intrinsic<[LLVMType<v256f64>], [LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<v256f64>, LLVMType<i32>], [IntrReadMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsc_vvssl : GCCBuiltin<"__builtin_ve_vl_vsc_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsc_vvssml : GCCBuiltin<"__builtin_ve_vl_vsc_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vscnc_vvssl : GCCBuiltin<"__builtin_ve_vl_vscnc_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vscnc_vvssml : GCCBuiltin<"__builtin_ve_vl_vscnc_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vscot_vvssl : GCCBuiltin<"__builtin_ve_vl_vscot_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vscot_vvssml : GCCBuiltin<"__builtin_ve_vl_vscot_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vscncot_vvssl : GCCBuiltin<"__builtin_ve_vl_vscncot_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vscncot_vvssml : GCCBuiltin<"__builtin_ve_vl_vscncot_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vscu_vvssl : GCCBuiltin<"__builtin_ve_vl_vscu_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vscu_vvssml : GCCBuiltin<"__builtin_ve_vl_vscu_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vscunc_vvssl : GCCBuiltin<"__builtin_ve_vl_vscunc_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vscunc_vvssml : GCCBuiltin<"__builtin_ve_vl_vscunc_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vscuot_vvssl : GCCBuiltin<"__builtin_ve_vl_vscuot_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vscuot_vvssml : GCCBuiltin<"__builtin_ve_vl_vscuot_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vscuncot_vvssl : GCCBuiltin<"__builtin_ve_vl_vscuncot_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vscuncot_vvssml : GCCBuiltin<"__builtin_ve_vl_vscuncot_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vscl_vvssl : GCCBuiltin<"__builtin_ve_vl_vscl_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vscl_vvssml : GCCBuiltin<"__builtin_ve_vl_vscl_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsclnc_vvssl : GCCBuiltin<"__builtin_ve_vl_vsclnc_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsclnc_vvssml : GCCBuiltin<"__builtin_ve_vl_vsclnc_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsclot_vvssl : GCCBuiltin<"__builtin_ve_vl_vsclot_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsclot_vvssml : GCCBuiltin<"__builtin_ve_vl_vsclot_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsclncot_vvssl : GCCBuiltin<"__builtin_ve_vl_vsclncot_vvssl">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_vsclncot_vvssml : GCCBuiltin<"__builtin_ve_vl_vsclncot_vvssml">, Intrinsic<[], [LLVMType<v256f64>, LLVMType<v256f64>, LLVMType<i64>, LLVMType<i64>, LLVMType<v256i1>, LLVMType<i32>], [IntrWriteMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_andm_mmm : GCCBuiltin<"__builtin_ve_vl_andm_mmm">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256i1>, LLVMType<v256i1>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_andm_MMM : GCCBuiltin<"__builtin_ve_vl_andm_MMM">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v512i1>, LLVMType<v512i1>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_orm_mmm : GCCBuiltin<"__builtin_ve_vl_orm_mmm">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256i1>, LLVMType<v256i1>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_orm_MMM : GCCBuiltin<"__builtin_ve_vl_orm_MMM">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v512i1>, LLVMType<v512i1>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_xorm_mmm : GCCBuiltin<"__builtin_ve_vl_xorm_mmm">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256i1>, LLVMType<v256i1>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_xorm_MMM : GCCBuiltin<"__builtin_ve_vl_xorm_MMM">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v512i1>, LLVMType<v512i1>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_eqvm_mmm : GCCBuiltin<"__builtin_ve_vl_eqvm_mmm">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256i1>, LLVMType<v256i1>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_eqvm_MMM : GCCBuiltin<"__builtin_ve_vl_eqvm_MMM">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v512i1>, LLVMType<v512i1>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_nndm_mmm : GCCBuiltin<"__builtin_ve_vl_nndm_mmm">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256i1>, LLVMType<v256i1>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_nndm_MMM : GCCBuiltin<"__builtin_ve_vl_nndm_MMM">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v512i1>, LLVMType<v512i1>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_negm_mm : GCCBuiltin<"__builtin_ve_vl_negm_mm">, Intrinsic<[LLVMType<v256i1>], [LLVMType<v256i1>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_negm_MM : GCCBuiltin<"__builtin_ve_vl_negm_MM">, Intrinsic<[LLVMType<v512i1>], [LLVMType<v512i1>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_pcvm_sml : GCCBuiltin<"__builtin_ve_vl_pcvm_sml">, Intrinsic<[LLVMType<i64>], [LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_lzvm_sml : GCCBuiltin<"__builtin_ve_vl_lzvm_sml">, Intrinsic<[LLVMType<i64>], [LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
+let TargetPrefix = "ve" in def int_ve_vl_tovm_sml : GCCBuiltin<"__builtin_ve_vl_tovm_sml">, Intrinsic<[LLVMType<i64>], [LLVMType<v256i1>, LLVMType<i32>], [IntrNoMem]>;
diff --git a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsWebAssembly.td b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsWebAssembly.td
index dccc0ca3b4..d306d0ccb9 100644
--- a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsWebAssembly.td
+++ b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsWebAssembly.td
@@ -50,10 +50,10 @@ def int_wasm_trunc_saturate_unsigned : Intrinsic<[llvm_anyint_ty],
//===----------------------------------------------------------------------===//
// throw / rethrow
-// The immediate argument is an index to a tag, which is 0 for C++.
+// The immediate argument is an index to a tag, which is 0 for C++.
def int_wasm_throw : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty],
[Throws, IntrNoReturn, ImmArg<ArgIndex<0>>]>;
-def int_wasm_rethrow : Intrinsic<[], [], [Throws, IntrNoReturn]>;
+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.
@@ -62,12 +62,12 @@ def int_wasm_get_exception : Intrinsic<[llvm_ptr_ty], [llvm_token_ty],
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. This returns a single pointer, which is sufficient for C++
-// support. The immediate argument is an index to for a tag, which is 0 for C++.
-def int_wasm_catch : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty],
- [IntrHasSideEffects, ImmArg<ArgIndex<0>>]>;
-
+// wasm.catch returns the pointer to the exception object caught by wasm 'catch'
+// instruction. This returns a single pointer, which is sufficient for C++
+// support. The immediate argument is an index to for a tag, which is 0 for C++.
+def int_wasm_catch : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty],
+ [IntrHasSideEffects, ImmArg<ArgIndex<0>>]>;
+
// 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.
@@ -82,23 +82,23 @@ def int_wasm_lsda : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
//===----------------------------------------------------------------------===//
// wait / notify
-def int_wasm_memory_atomic_wait32 :
+def int_wasm_memory_atomic_wait32 :
Intrinsic<[llvm_i32_ty],
[LLVMPointerType<llvm_i32_ty>, llvm_i32_ty, llvm_i64_ty],
- [IntrInaccessibleMemOrArgMemOnly, ReadOnly<ArgIndex<0>>,
- NoCapture<ArgIndex<0>>, IntrHasSideEffects],
- "", [SDNPMemOperand]>;
-def int_wasm_memory_atomic_wait64 :
+ [IntrInaccessibleMemOrArgMemOnly, ReadOnly<ArgIndex<0>>,
+ NoCapture<ArgIndex<0>>, IntrHasSideEffects],
+ "", [SDNPMemOperand]>;
+def int_wasm_memory_atomic_wait64 :
Intrinsic<[llvm_i32_ty],
[LLVMPointerType<llvm_i64_ty>, llvm_i64_ty, llvm_i64_ty],
- [IntrInaccessibleMemOrArgMemOnly, ReadOnly<ArgIndex<0>>,
- NoCapture<ArgIndex<0>>, IntrHasSideEffects],
- "", [SDNPMemOperand]>;
-def int_wasm_memory_atomic_notify:
- Intrinsic<[llvm_i32_ty], [LLVMPointerType<llvm_i32_ty>, llvm_i32_ty],
- [IntrInaccessibleMemOnly, NoCapture<ArgIndex<0>>,
+ [IntrInaccessibleMemOrArgMemOnly, ReadOnly<ArgIndex<0>>,
+ NoCapture<ArgIndex<0>>, IntrHasSideEffects],
+ "", [SDNPMemOperand]>;
+def int_wasm_memory_atomic_notify:
+ Intrinsic<[llvm_i32_ty], [LLVMPointerType<llvm_i32_ty>, llvm_i32_ty],
+ [IntrInaccessibleMemOnly, NoCapture<ArgIndex<0>>,
IntrHasSideEffects],
- "", [SDNPMemOperand]>;
+ "", [SDNPMemOperand]>;
//===----------------------------------------------------------------------===//
// SIMD intrinsics
@@ -155,7 +155,7 @@ def int_wasm_dot :
Intrinsic<[llvm_v4i32_ty],
[llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem, IntrSpeculatable]>;
-
+
def int_wasm_narrow_signed :
Intrinsic<[llvm_anyvector_ty],
[llvm_anyvector_ty, LLVMMatchType<1>],
@@ -164,21 +164,21 @@ def int_wasm_narrow_unsigned :
Intrinsic<[llvm_anyvector_ty],
[llvm_anyvector_ty, LLVMMatchType<1>],
[IntrNoMem, IntrSpeculatable]>;
-
-// TODO: Replace these intrinsics with normal ISel patterns once i32x4 to i64x2
-// widening is merged to the proposal.
+
+// TODO: Replace these intrinsics with normal ISel patterns once i32x4 to i64x2
+// widening is merged to the proposal.
def int_wasm_widen_low_signed :
- Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem, IntrSpeculatable]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem, IntrSpeculatable]>;
def int_wasm_widen_high_signed :
- Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem, IntrSpeculatable]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem, IntrSpeculatable]>;
def int_wasm_widen_low_unsigned :
- Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem, IntrSpeculatable]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem, IntrSpeculatable]>;
def int_wasm_widen_high_unsigned :
- Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem, IntrSpeculatable]>;
-
-def int_wasm_q15mulr_saturate_signed :
- Intrinsic<[llvm_v8i16_ty],
- [llvm_v8i16_ty, llvm_v8i16_ty],
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem, IntrSpeculatable]>;
+
+def int_wasm_q15mulr_saturate_signed :
+ Intrinsic<[llvm_v8i16_ty],
+ [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem, IntrSpeculatable]>;
// TODO: Replace these intrinsics with normal ISel patterns
@@ -211,143 +211,143 @@ def int_wasm_nearest :
[LLVMMatchType<0>],
[IntrNoMem, IntrSpeculatable]>;
-// TODO: Replace these intrinsic with normal ISel patterns once the
-// load_zero instructions are merged to the proposal.
-def int_wasm_load32_zero :
- Intrinsic<[llvm_v4i32_ty],
- [LLVMPointerType<llvm_i32_ty>],
- [IntrReadMem, IntrArgMemOnly],
- "", [SDNPMemOperand]>;
-
-def int_wasm_load64_zero :
- Intrinsic<[llvm_v2i64_ty],
- [LLVMPointerType<llvm_i64_ty>],
- [IntrReadMem, IntrArgMemOnly],
- "", [SDNPMemOperand]>;
-
-// These intrinsics do not mark their lane index arguments as immediate because
-// that changes the corresponding SDNode from ISD::Constant to
-// ISD::TargetConstant, which would require extra complications in the ISel
-// tablegen patterns. TODO: Replace these intrinsic with normal ISel patterns
-// once the load_lane instructions are merged to the proposal.
-def int_wasm_load8_lane :
- Intrinsic<[llvm_v16i8_ty],
- [LLVMPointerType<llvm_i8_ty>, llvm_v16i8_ty, llvm_i32_ty],
- [IntrReadMem, IntrArgMemOnly],
- "", [SDNPMemOperand]>;
-def int_wasm_load16_lane :
- Intrinsic<[llvm_v8i16_ty],
- [LLVMPointerType<llvm_i16_ty>, llvm_v8i16_ty, llvm_i32_ty],
- [IntrReadMem, IntrArgMemOnly],
- "", [SDNPMemOperand]>;
-def int_wasm_load32_lane :
- Intrinsic<[llvm_v4i32_ty],
- [LLVMPointerType<llvm_i32_ty>, llvm_v4i32_ty, llvm_i32_ty],
- [IntrReadMem, IntrArgMemOnly],
- "", [SDNPMemOperand]>;
-def int_wasm_load64_lane :
- Intrinsic<[llvm_v2i64_ty],
- [LLVMPointerType<llvm_i64_ty>, llvm_v2i64_ty, llvm_i32_ty],
- [IntrReadMem, IntrArgMemOnly],
- "", [SDNPMemOperand]>;
-def int_wasm_store8_lane :
- Intrinsic<[],
- [LLVMPointerType<llvm_i8_ty>, llvm_v16i8_ty, llvm_i32_ty],
- [IntrWriteMem, IntrArgMemOnly],
- "", [SDNPMemOperand]>;
-def int_wasm_store16_lane :
- Intrinsic<[],
- [LLVMPointerType<llvm_i16_ty>, llvm_v8i16_ty, llvm_i32_ty],
- [IntrWriteMem, IntrArgMemOnly],
- "", [SDNPMemOperand]>;
-def int_wasm_store32_lane :
- Intrinsic<[],
- [LLVMPointerType<llvm_i32_ty>, llvm_v4i32_ty, llvm_i32_ty],
- [IntrWriteMem, IntrArgMemOnly],
- "", [SDNPMemOperand]>;
-def int_wasm_store64_lane :
- Intrinsic<[],
- [LLVMPointerType<llvm_i64_ty>, llvm_v2i64_ty, llvm_i32_ty],
- [IntrWriteMem, IntrArgMemOnly],
- "", [SDNPMemOperand]>;
-
-// TODO: Replace this intrinsic with normal ISel patterns once popcnt is merged
-// to the proposal.
-def int_wasm_popcnt :
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem, IntrSpeculatable]>;
-
-def int_wasm_extmul_low_signed :
- Intrinsic<[llvm_anyvector_ty],
- [LLVMSubdivide2VectorType<0>, LLVMSubdivide2VectorType<0>],
- [IntrNoMem, IntrSpeculatable]>;
-def int_wasm_extmul_high_signed :
- Intrinsic<[llvm_anyvector_ty],
- [LLVMSubdivide2VectorType<0>, LLVMSubdivide2VectorType<0>],
- [IntrNoMem, IntrSpeculatable]>;
-def int_wasm_extmul_low_unsigned :
- Intrinsic<[llvm_anyvector_ty],
- [LLVMSubdivide2VectorType<0>, LLVMSubdivide2VectorType<0>],
- [IntrNoMem, IntrSpeculatable]>;
-def int_wasm_extmul_high_unsigned :
- Intrinsic<[llvm_anyvector_ty],
- [LLVMSubdivide2VectorType<0>, LLVMSubdivide2VectorType<0>],
- [IntrNoMem, IntrSpeculatable]>;
-
-def int_wasm_extadd_pairwise_signed :
- Intrinsic<[llvm_anyvector_ty],
- [LLVMSubdivide2VectorType<0>],
- [IntrNoMem, IntrSpeculatable]>;
-def int_wasm_extadd_pairwise_unsigned :
- Intrinsic<[llvm_anyvector_ty],
- [LLVMSubdivide2VectorType<0>],
- [IntrNoMem, IntrSpeculatable]>;
-
-def int_wasm_signselect :
- Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem, IntrSpeculatable]>;
-
-// TODO: Remove this intrinsic and the associated builtin if i64x2.eq gets
-// merged to the proposal.
-def int_wasm_eq :
- Intrinsic<[llvm_v2i64_ty],
- [llvm_v2i64_ty, llvm_v2i64_ty],
- [IntrNoMem, IntrSpeculatable]>;
-
-// TODO: Remove this after experiments have been run. Use the target-agnostic
-// int_prefetch if this becomes specified at some point.
-def int_wasm_prefetch_t :
- Intrinsic<[], [llvm_ptr_ty],
- [IntrInaccessibleMemOrArgMemOnly, IntrWillReturn,
- ReadOnly<ArgIndex<0>>, NoCapture<ArgIndex<0>>],
- "", [SDNPMemOperand]>;
-
-def int_wasm_prefetch_nt :
- Intrinsic<[], [llvm_ptr_ty],
- [IntrInaccessibleMemOrArgMemOnly, IntrWillReturn,
- ReadOnly<ArgIndex<0>>, NoCapture<ArgIndex<0>>],
- "", [SDNPMemOperand]>;
-
-// TODO: Remove these if possible if they are merged to the spec.
-def int_wasm_convert_low_signed :
- Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty],
- [IntrNoMem, IntrSpeculatable]>;
-def int_wasm_convert_low_unsigned :
- Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty],
- [IntrNoMem, IntrSpeculatable]>;
-def int_wasm_trunc_saturate_zero_signed :
- Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty],
- [IntrNoMem, IntrSpeculatable]>;
-def int_wasm_trunc_saturate_zero_unsigned :
- Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty],
- [IntrNoMem, IntrSpeculatable]>;
-def int_wasm_demote_zero :
- Intrinsic<[llvm_v4f32_ty], [llvm_v2f64_ty],
- [IntrNoMem, IntrSpeculatable]>;
-def int_wasm_promote_low :
- Intrinsic<[llvm_v2f64_ty], [llvm_v4f32_ty],
- [IntrNoMem, IntrSpeculatable]>;
-
+// TODO: Replace these intrinsic with normal ISel patterns once the
+// load_zero instructions are merged to the proposal.
+def int_wasm_load32_zero :
+ Intrinsic<[llvm_v4i32_ty],
+ [LLVMPointerType<llvm_i32_ty>],
+ [IntrReadMem, IntrArgMemOnly],
+ "", [SDNPMemOperand]>;
+
+def int_wasm_load64_zero :
+ Intrinsic<[llvm_v2i64_ty],
+ [LLVMPointerType<llvm_i64_ty>],
+ [IntrReadMem, IntrArgMemOnly],
+ "", [SDNPMemOperand]>;
+
+// These intrinsics do not mark their lane index arguments as immediate because
+// that changes the corresponding SDNode from ISD::Constant to
+// ISD::TargetConstant, which would require extra complications in the ISel
+// tablegen patterns. TODO: Replace these intrinsic with normal ISel patterns
+// once the load_lane instructions are merged to the proposal.
+def int_wasm_load8_lane :
+ Intrinsic<[llvm_v16i8_ty],
+ [LLVMPointerType<llvm_i8_ty>, llvm_v16i8_ty, llvm_i32_ty],
+ [IntrReadMem, IntrArgMemOnly],
+ "", [SDNPMemOperand]>;
+def int_wasm_load16_lane :
+ Intrinsic<[llvm_v8i16_ty],
+ [LLVMPointerType<llvm_i16_ty>, llvm_v8i16_ty, llvm_i32_ty],
+ [IntrReadMem, IntrArgMemOnly],
+ "", [SDNPMemOperand]>;
+def int_wasm_load32_lane :
+ Intrinsic<[llvm_v4i32_ty],
+ [LLVMPointerType<llvm_i32_ty>, llvm_v4i32_ty, llvm_i32_ty],
+ [IntrReadMem, IntrArgMemOnly],
+ "", [SDNPMemOperand]>;
+def int_wasm_load64_lane :
+ Intrinsic<[llvm_v2i64_ty],
+ [LLVMPointerType<llvm_i64_ty>, llvm_v2i64_ty, llvm_i32_ty],
+ [IntrReadMem, IntrArgMemOnly],
+ "", [SDNPMemOperand]>;
+def int_wasm_store8_lane :
+ Intrinsic<[],
+ [LLVMPointerType<llvm_i8_ty>, llvm_v16i8_ty, llvm_i32_ty],
+ [IntrWriteMem, IntrArgMemOnly],
+ "", [SDNPMemOperand]>;
+def int_wasm_store16_lane :
+ Intrinsic<[],
+ [LLVMPointerType<llvm_i16_ty>, llvm_v8i16_ty, llvm_i32_ty],
+ [IntrWriteMem, IntrArgMemOnly],
+ "", [SDNPMemOperand]>;
+def int_wasm_store32_lane :
+ Intrinsic<[],
+ [LLVMPointerType<llvm_i32_ty>, llvm_v4i32_ty, llvm_i32_ty],
+ [IntrWriteMem, IntrArgMemOnly],
+ "", [SDNPMemOperand]>;
+def int_wasm_store64_lane :
+ Intrinsic<[],
+ [LLVMPointerType<llvm_i64_ty>, llvm_v2i64_ty, llvm_i32_ty],
+ [IntrWriteMem, IntrArgMemOnly],
+ "", [SDNPMemOperand]>;
+
+// TODO: Replace this intrinsic with normal ISel patterns once popcnt is merged
+// to the proposal.
+def int_wasm_popcnt :
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem, IntrSpeculatable]>;
+
+def int_wasm_extmul_low_signed :
+ Intrinsic<[llvm_anyvector_ty],
+ [LLVMSubdivide2VectorType<0>, LLVMSubdivide2VectorType<0>],
+ [IntrNoMem, IntrSpeculatable]>;
+def int_wasm_extmul_high_signed :
+ Intrinsic<[llvm_anyvector_ty],
+ [LLVMSubdivide2VectorType<0>, LLVMSubdivide2VectorType<0>],
+ [IntrNoMem, IntrSpeculatable]>;
+def int_wasm_extmul_low_unsigned :
+ Intrinsic<[llvm_anyvector_ty],
+ [LLVMSubdivide2VectorType<0>, LLVMSubdivide2VectorType<0>],
+ [IntrNoMem, IntrSpeculatable]>;
+def int_wasm_extmul_high_unsigned :
+ Intrinsic<[llvm_anyvector_ty],
+ [LLVMSubdivide2VectorType<0>, LLVMSubdivide2VectorType<0>],
+ [IntrNoMem, IntrSpeculatable]>;
+
+def int_wasm_extadd_pairwise_signed :
+ Intrinsic<[llvm_anyvector_ty],
+ [LLVMSubdivide2VectorType<0>],
+ [IntrNoMem, IntrSpeculatable]>;
+def int_wasm_extadd_pairwise_unsigned :
+ Intrinsic<[llvm_anyvector_ty],
+ [LLVMSubdivide2VectorType<0>],
+ [IntrNoMem, IntrSpeculatable]>;
+
+def int_wasm_signselect :
+ Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable]>;
+
+// TODO: Remove this intrinsic and the associated builtin if i64x2.eq gets
+// merged to the proposal.
+def int_wasm_eq :
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem, IntrSpeculatable]>;
+
+// TODO: Remove this after experiments have been run. Use the target-agnostic
+// int_prefetch if this becomes specified at some point.
+def int_wasm_prefetch_t :
+ Intrinsic<[], [llvm_ptr_ty],
+ [IntrInaccessibleMemOrArgMemOnly, IntrWillReturn,
+ ReadOnly<ArgIndex<0>>, NoCapture<ArgIndex<0>>],
+ "", [SDNPMemOperand]>;
+
+def int_wasm_prefetch_nt :
+ Intrinsic<[], [llvm_ptr_ty],
+ [IntrInaccessibleMemOrArgMemOnly, IntrWillReturn,
+ ReadOnly<ArgIndex<0>>, NoCapture<ArgIndex<0>>],
+ "", [SDNPMemOperand]>;
+
+// TODO: Remove these if possible if they are merged to the spec.
+def int_wasm_convert_low_signed :
+ Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty],
+ [IntrNoMem, IntrSpeculatable]>;
+def int_wasm_convert_low_unsigned :
+ Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty],
+ [IntrNoMem, IntrSpeculatable]>;
+def int_wasm_trunc_saturate_zero_signed :
+ Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty],
+ [IntrNoMem, IntrSpeculatable]>;
+def int_wasm_trunc_saturate_zero_unsigned :
+ Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty],
+ [IntrNoMem, IntrSpeculatable]>;
+def int_wasm_demote_zero :
+ Intrinsic<[llvm_v4f32_ty], [llvm_v2f64_ty],
+ [IntrNoMem, IntrSpeculatable]>;
+def int_wasm_promote_low :
+ Intrinsic<[llvm_v2f64_ty], [llvm_v4f32_ty],
+ [IntrNoMem, IntrSpeculatable]>;
+
//===----------------------------------------------------------------------===//
// Thread-local storage intrinsics
//===----------------------------------------------------------------------===//
diff --git a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsX86.td b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsX86.td
index 96b7364e00..bba1213997 100644
--- a/contrib/libs/llvm12/include/llvm/IR/IntrinsicsX86.td
+++ b/contrib/libs/llvm12/include/llvm/IR/IntrinsicsX86.td
@@ -284,9 +284,9 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse_ldmxcsr :
Intrinsic<[], [llvm_ptr_ty],
// FIXME: LDMXCSR does not actually write to memory,
- // but intrinsic properties are generated incorrectly
- // for IntrReadMem+IntrHasSideEffects.
- [/*IntrReadMem, IntrArgMemOnly,*/ IntrHasSideEffects]>;
+ // but intrinsic properties are generated incorrectly
+ // for IntrReadMem+IntrHasSideEffects.
+ [/*IntrReadMem, IntrArgMemOnly,*/ IntrHasSideEffects]>;
}
// Misc.
@@ -4748,26 +4748,26 @@ let TargetPrefix = "x86" in {
let TargetPrefix = "x86" in {
// NOTE: These comparison intrinsics are not used by clang as long as the
// distinction in signaling behaviour is not implemented.
- def int_x86_avx512_mask_cmp_ps_512 :
+ def int_x86_avx512_mask_cmp_ps_512 :
Intrinsic<[llvm_v16i1_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
- llvm_i32_ty, llvm_v16i1_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<4>>]>;
- def int_x86_avx512_mask_cmp_pd_512 :
+ llvm_i32_ty, llvm_v16i1_ty, llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<4>>]>;
+ def int_x86_avx512_mask_cmp_pd_512 :
Intrinsic<[llvm_v8i1_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
- llvm_i32_ty, llvm_v8i1_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<4>>]>;
- def int_x86_avx512_mask_cmp_ps_256 :
+ llvm_i32_ty, llvm_v8i1_ty, llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<4>>]>;
+ def int_x86_avx512_mask_cmp_ps_256 :
Intrinsic<[llvm_v8i1_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
- llvm_i32_ty, llvm_v8i1_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
- def int_x86_avx512_mask_cmp_pd_256 :
+ llvm_i32_ty, llvm_v8i1_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+ def int_x86_avx512_mask_cmp_pd_256 :
Intrinsic<[llvm_v4i1_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
- llvm_i32_ty, llvm_v4i1_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
- def int_x86_avx512_mask_cmp_ps_128 :
+ llvm_i32_ty, llvm_v4i1_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+ def int_x86_avx512_mask_cmp_ps_128 :
Intrinsic<[llvm_v4i1_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
- llvm_i32_ty, llvm_v4i1_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
- def int_x86_avx512_mask_cmp_pd_128 :
+ llvm_i32_ty, llvm_v4i1_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+ def int_x86_avx512_mask_cmp_pd_128 :
Intrinsic<[llvm_v2i1_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
- llvm_i32_ty, llvm_v2i1_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+ llvm_i32_ty, llvm_v2i1_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_mask_cmp_ss :
GCCBuiltin<"__builtin_ia32_cmpss_mask">,
@@ -4947,60 +4947,60 @@ let TargetPrefix = "x86" in {
def int_x86_xresldtrk : GCCBuiltin<"__builtin_ia32_xresldtrk">,
Intrinsic<[], [], []>;
}
-
+
+//===----------------------------------------------------------------------===//
+// Key Locker
+let TargetPrefix = "x86" in {
+ def int_x86_loadiwkey : GCCBuiltin<"__builtin_ia32_loadiwkey">,
+ Intrinsic<[], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
+ []>;
+ def int_x86_encodekey128 :
+ Intrinsic<[llvm_i32_ty, llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
+ [llvm_i32_ty, llvm_v2i64_ty], []>;
+ def int_x86_encodekey256 :
+ Intrinsic<[llvm_i32_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
+ [llvm_i32_ty, llvm_v2i64_ty, llvm_v2i64_ty], []>;
+ def int_x86_aesenc128kl :
+ Intrinsic<[llvm_i8_ty, llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty], []>;
+ def int_x86_aesdec128kl :
+ Intrinsic<[llvm_i8_ty, llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty], []>;
+ def int_x86_aesenc256kl :
+ Intrinsic<[llvm_i8_ty, llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty], []>;
+ def int_x86_aesdec256kl :
+ Intrinsic<[llvm_i8_ty, llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty], []>;
+ def int_x86_aesencwide128kl :
+ Intrinsic<[llvm_i8_ty, llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
+ [llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], []>;
+ def int_x86_aesdecwide128kl :
+ Intrinsic<[llvm_i8_ty, llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
+ [llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], []>;
+ def int_x86_aesencwide256kl :
+ Intrinsic<[llvm_i8_ty, llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
+ [llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], []>;
+ def int_x86_aesdecwide256kl :
+ Intrinsic<[llvm_i8_ty, llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
+ [llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], []>;
+}
+
//===----------------------------------------------------------------------===//
-// Key Locker
-let TargetPrefix = "x86" in {
- def int_x86_loadiwkey : GCCBuiltin<"__builtin_ia32_loadiwkey">,
- Intrinsic<[], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
- []>;
- def int_x86_encodekey128 :
- Intrinsic<[llvm_i32_ty, llvm_v2i64_ty, llvm_v2i64_ty,
- llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
- [llvm_i32_ty, llvm_v2i64_ty], []>;
- def int_x86_encodekey256 :
- Intrinsic<[llvm_i32_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty,
- llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
- [llvm_i32_ty, llvm_v2i64_ty, llvm_v2i64_ty], []>;
- def int_x86_aesenc128kl :
- Intrinsic<[llvm_i8_ty, llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty], []>;
- def int_x86_aesdec128kl :
- Intrinsic<[llvm_i8_ty, llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty], []>;
- def int_x86_aesenc256kl :
- Intrinsic<[llvm_i8_ty, llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty], []>;
- def int_x86_aesdec256kl :
- Intrinsic<[llvm_i8_ty, llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty], []>;
- def int_x86_aesencwide128kl :
- Intrinsic<[llvm_i8_ty, llvm_v2i64_ty, llvm_v2i64_ty,
- llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty,
- llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
- [llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty,
- llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty,
- llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], []>;
- def int_x86_aesdecwide128kl :
- Intrinsic<[llvm_i8_ty, llvm_v2i64_ty, llvm_v2i64_ty,
- llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty,
- llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
- [llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty,
- llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty,
- llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], []>;
- def int_x86_aesencwide256kl :
- Intrinsic<[llvm_i8_ty, llvm_v2i64_ty, llvm_v2i64_ty,
- llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty,
- llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
- [llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty,
- llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty,
- llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], []>;
- def int_x86_aesdecwide256kl :
- Intrinsic<[llvm_i8_ty, llvm_v2i64_ty, llvm_v2i64_ty,
- llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty,
- llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
- [llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty,
- llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty,
- llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], []>;
-}
-
-//===----------------------------------------------------------------------===//
// AMX - Intel AMX extensions
let TargetPrefix = "x86" in {
@@ -5011,68 +5011,68 @@ let TargetPrefix = "x86" in {
def int_x86_tilerelease : GCCBuiltin<"__builtin_ia32_tilerelease">,
Intrinsic<[], [], []>;
def int_x86_tilezero : GCCBuiltin<"__builtin_ia32_tilezero">,
- Intrinsic<[], [llvm_i8_ty], [ImmArg<ArgIndex<0>>]>;
+ Intrinsic<[], [llvm_i8_ty], [ImmArg<ArgIndex<0>>]>;
def int_x86_tileloadd64 : GCCBuiltin<"__builtin_ia32_tileloadd64">,
- Intrinsic<[], [llvm_i8_ty, llvm_ptr_ty, llvm_i64_ty],
- [ImmArg<ArgIndex<0>>]>;
+ Intrinsic<[], [llvm_i8_ty, llvm_ptr_ty, llvm_i64_ty],
+ [ImmArg<ArgIndex<0>>]>;
def int_x86_tileloaddt164 : GCCBuiltin<"__builtin_ia32_tileloaddt164">,
- Intrinsic<[], [llvm_i8_ty, llvm_ptr_ty, llvm_i64_ty],
- [ImmArg<ArgIndex<0>>]>;
+ Intrinsic<[], [llvm_i8_ty, llvm_ptr_ty, llvm_i64_ty],
+ [ImmArg<ArgIndex<0>>]>;
def int_x86_tilestored64 : GCCBuiltin<"__builtin_ia32_tilestored64">,
- Intrinsic<[], [llvm_i8_ty, llvm_ptr_ty, llvm_i64_ty],
- [ImmArg<ArgIndex<0>>]>;
+ Intrinsic<[], [llvm_i8_ty, llvm_ptr_ty, llvm_i64_ty],
+ [ImmArg<ArgIndex<0>>]>;
def int_x86_tdpbssd : GCCBuiltin<"__builtin_ia32_tdpbssd">,
- Intrinsic<[], [llvm_i8_ty, llvm_i8_ty, llvm_i8_ty],
- [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>,
- ImmArg<ArgIndex<2>>]>;
+ Intrinsic<[], [llvm_i8_ty, llvm_i8_ty, llvm_i8_ty],
+ [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>,
+ ImmArg<ArgIndex<2>>]>;
def int_x86_tdpbsud : GCCBuiltin<"__builtin_ia32_tdpbsud">,
- Intrinsic<[], [llvm_i8_ty, llvm_i8_ty, llvm_i8_ty],
- [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>,
- ImmArg<ArgIndex<2>>]>;
+ Intrinsic<[], [llvm_i8_ty, llvm_i8_ty, llvm_i8_ty],
+ [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>,
+ ImmArg<ArgIndex<2>>]>;
def int_x86_tdpbusd : GCCBuiltin<"__builtin_ia32_tdpbusd">,
- Intrinsic<[], [llvm_i8_ty, llvm_i8_ty, llvm_i8_ty],
- [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>,
- ImmArg<ArgIndex<2>>]>;
+ Intrinsic<[], [llvm_i8_ty, llvm_i8_ty, llvm_i8_ty],
+ [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>,
+ ImmArg<ArgIndex<2>>]>;
def int_x86_tdpbuud : GCCBuiltin<"__builtin_ia32_tdpbuud">,
- Intrinsic<[], [llvm_i8_ty, llvm_i8_ty, llvm_i8_ty],
- [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>,
- ImmArg<ArgIndex<2>>]>;
+ Intrinsic<[], [llvm_i8_ty, llvm_i8_ty, llvm_i8_ty],
+ [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>,
+ ImmArg<ArgIndex<2>>]>;
def int_x86_tdpbf16ps : GCCBuiltin<"__builtin_ia32_tdpbf16ps">,
- Intrinsic<[], [llvm_i8_ty, llvm_i8_ty, llvm_i8_ty],
- [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>,
- ImmArg<ArgIndex<2>>]>;
- // AMX - internal intrinsics
- def int_x86_tileloadd64_internal :
- GCCBuiltin<"__builtin_ia32_tileloadd64_internal">,
- Intrinsic<[llvm_x86amx_ty],
- [llvm_i16_ty, llvm_i16_ty, llvm_ptr_ty, llvm_i64_ty],
- []>;
- def int_x86_tdpbssd_internal :
- GCCBuiltin<"__builtin_ia32_tdpbssd_internal">,
- Intrinsic<[llvm_x86amx_ty],
- [llvm_i16_ty, llvm_i16_ty, llvm_i16_ty,
- llvm_x86amx_ty, llvm_x86amx_ty,
- llvm_x86amx_ty], []>;
- def int_x86_tilestored64_internal :
- GCCBuiltin<"__builtin_ia32_tilestored64_internal">,
- Intrinsic<[], [llvm_i16_ty, llvm_i16_ty, llvm_ptr_ty,
- llvm_i64_ty, llvm_x86amx_ty], []>;
- def int_x86_tilezero_internal :
- GCCBuiltin<"__builtin_ia32_tilezero_internal">,
- Intrinsic<[llvm_x86amx_ty], [llvm_i16_ty, llvm_i16_ty],
- []>;
+ Intrinsic<[], [llvm_i8_ty, llvm_i8_ty, llvm_i8_ty],
+ [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>,
+ ImmArg<ArgIndex<2>>]>;
+ // AMX - internal intrinsics
+ def int_x86_tileloadd64_internal :
+ GCCBuiltin<"__builtin_ia32_tileloadd64_internal">,
+ Intrinsic<[llvm_x86amx_ty],
+ [llvm_i16_ty, llvm_i16_ty, llvm_ptr_ty, llvm_i64_ty],
+ []>;
+ def int_x86_tdpbssd_internal :
+ GCCBuiltin<"__builtin_ia32_tdpbssd_internal">,
+ Intrinsic<[llvm_x86amx_ty],
+ [llvm_i16_ty, llvm_i16_ty, llvm_i16_ty,
+ llvm_x86amx_ty, llvm_x86amx_ty,
+ llvm_x86amx_ty], []>;
+ def int_x86_tilestored64_internal :
+ GCCBuiltin<"__builtin_ia32_tilestored64_internal">,
+ Intrinsic<[], [llvm_i16_ty, llvm_i16_ty, llvm_ptr_ty,
+ llvm_i64_ty, llvm_x86amx_ty], []>;
+ def int_x86_tilezero_internal :
+ GCCBuiltin<"__builtin_ia32_tilezero_internal">,
+ Intrinsic<[llvm_x86amx_ty], [llvm_i16_ty, llvm_i16_ty],
+ []>;
+}
+
+//===----------------------------------------------------------------------===//
+// UINTR - User Level Interrupt
+
+let TargetPrefix = "x86" in {
+ def int_x86_clui : GCCBuiltin<"__builtin_ia32_clui">,
+ Intrinsic<[], [], []>;
+ def int_x86_stui : GCCBuiltin<"__builtin_ia32_stui">,
+ Intrinsic<[], [], []>;
+ def int_x86_testui : GCCBuiltin<"__builtin_ia32_testui">,
+ Intrinsic<[llvm_i8_ty], [], []>;
+ def int_x86_senduipi : GCCBuiltin<"__builtin_ia32_senduipi">,
+ Intrinsic<[], [llvm_i64_ty], []>;
}
-
-//===----------------------------------------------------------------------===//
-// UINTR - User Level Interrupt
-
-let TargetPrefix = "x86" in {
- def int_x86_clui : GCCBuiltin<"__builtin_ia32_clui">,
- Intrinsic<[], [], []>;
- def int_x86_stui : GCCBuiltin<"__builtin_ia32_stui">,
- Intrinsic<[], [], []>;
- def int_x86_testui : GCCBuiltin<"__builtin_ia32_testui">,
- Intrinsic<[llvm_i8_ty], [], []>;
- def int_x86_senduipi : GCCBuiltin<"__builtin_ia32_senduipi">,
- Intrinsic<[], [llvm_i64_ty], []>;
-}
diff --git a/contrib/libs/llvm12/include/llvm/IR/LLVMContext.h b/contrib/libs/llvm12/include/llvm/IR/LLVMContext.h
index 8615a4b36e..2c7cff5184 100644
--- a/contrib/libs/llvm12/include/llvm/IR/LLVMContext.h
+++ b/contrib/libs/llvm12/include/llvm/IR/LLVMContext.h
@@ -229,24 +229,24 @@ public:
void setDiagnosticsHotnessRequested(bool Requested);
/// Return the minimum hotness value a diagnostic would need in order
- /// to be included in optimization diagnostics.
- ///
- /// Three possible return values:
- /// 0 - threshold is disabled. Everything will be printed out.
- /// positive int - threshold is set.
- /// UINT64_MAX - threshold is not yet set, and needs to be synced from
- /// profile summary. Note that in case of missing profile
- /// summary, threshold will be kept at "MAX", effectively
- /// suppresses all remarks output.
+ /// to be included in optimization diagnostics.
+ ///
+ /// Three possible return values:
+ /// 0 - threshold is disabled. Everything will be printed out.
+ /// positive int - threshold is set.
+ /// UINT64_MAX - threshold is not yet set, and needs to be synced from
+ /// profile summary. Note that in case of missing profile
+ /// summary, threshold will be kept at "MAX", effectively
+ /// suppresses all remarks output.
uint64_t getDiagnosticsHotnessThreshold() const;
/// Set the minimum hotness value a diagnostic needs in order to be
/// included in optimization diagnostics.
- void setDiagnosticsHotnessThreshold(Optional<uint64_t> Threshold);
+ void setDiagnosticsHotnessThreshold(Optional<uint64_t> Threshold);
+
+ /// Return if hotness threshold is requested from PSI.
+ bool isDiagnosticsHotnessThresholdSetFromPSI() const;
- /// Return if hotness threshold is requested from PSI.
- bool isDiagnosticsHotnessThresholdSetFromPSI() const;
-
/// The "main remark streamer" used by all the specialized remark streamers.
/// This streamer keeps generic remark metadata in memory throughout the life
/// of the LLVMContext. This metadata may be emitted in a section in object
diff --git a/contrib/libs/llvm12/include/llvm/IR/LLVMRemarkStreamer.h b/contrib/libs/llvm12/include/llvm/IR/LLVMRemarkStreamer.h
index df6f64d8d8..4402168c5c 100644
--- a/contrib/libs/llvm12/include/llvm/IR/LLVMRemarkStreamer.h
+++ b/contrib/libs/llvm12/include/llvm/IR/LLVMRemarkStreamer.h
@@ -86,15 +86,15 @@ Expected<std::unique_ptr<ToolOutputFile>>
setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
StringRef RemarksPasses, StringRef RemarksFormat,
bool RemarksWithHotness,
- Optional<uint64_t> RemarksHotnessThreshold = 0);
+ Optional<uint64_t> RemarksHotnessThreshold = 0);
/// Setup optimization remarks that output directly to a raw_ostream.
/// \p OS is managed by the caller and should be open for writing as long as \p
/// Context is streaming remarks to it.
-Error setupLLVMOptimizationRemarks(
- LLVMContext &Context, raw_ostream &OS, StringRef RemarksPasses,
- StringRef RemarksFormat, bool RemarksWithHotness,
- Optional<uint64_t> RemarksHotnessThreshold = 0);
+Error setupLLVMOptimizationRemarks(
+ LLVMContext &Context, raw_ostream &OS, StringRef RemarksPasses,
+ StringRef RemarksFormat, bool RemarksWithHotness,
+ Optional<uint64_t> RemarksHotnessThreshold = 0);
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/IR/LegacyPassManagers.h b/contrib/libs/llvm12/include/llvm/IR/LegacyPassManagers.h
index 9b64cf2a77..3bdc0d36a8 100644
--- a/contrib/libs/llvm12/include/llvm/IR/LegacyPassManagers.h
+++ b/contrib/libs/llvm12/include/llvm/IR/LegacyPassManagers.h
@@ -237,11 +237,11 @@ private:
// Map to keep track of last user of the analysis pass.
// LastUser->second is the last user of Lastuser->first.
- // This is kept in sync with InversedLastUser.
+ // This is kept in sync with InversedLastUser.
DenseMap<Pass *, Pass *> LastUser;
// Map to keep track of passes that are last used by a pass.
- // This is kept in sync with LastUser.
+ // This is kept in sync with LastUser.
DenseMap<Pass *, SmallPtrSet<Pass *, 8> > InversedLastUser;
/// Immutable passes are managed by top level manager.
diff --git a/contrib/libs/llvm12/include/llvm/IR/MDBuilder.h b/contrib/libs/llvm12/include/llvm/IR/MDBuilder.h
index 3d83554478..134d7ed105 100644
--- a/contrib/libs/llvm12/include/llvm/IR/MDBuilder.h
+++ b/contrib/libs/llvm12/include/llvm/IR/MDBuilder.h
@@ -83,8 +83,8 @@ public:
/// Return metadata containing the section prefix for a function.
MDNode *createFunctionSectionPrefix(StringRef Prefix);
- /// Return metadata containing the pseudo probe descriptor for a function.
- MDNode *createPseudoProbeDesc(uint64_t GUID, uint64_t Hash, Function *F);
+ /// Return metadata containing the pseudo probe descriptor for a function.
+ MDNode *createPseudoProbeDesc(uint64_t GUID, uint64_t Hash, Function *F);
//===------------------------------------------------------------------===//
// Range metadata.
diff --git a/contrib/libs/llvm12/include/llvm/IR/MatrixBuilder.h b/contrib/libs/llvm12/include/llvm/IR/MatrixBuilder.h
index 6e8b6354b4..c753a2031c 100644
--- a/contrib/libs/llvm12/include/llvm/IR/MatrixBuilder.h
+++ b/contrib/libs/llvm12/include/llvm/IR/MatrixBuilder.h
@@ -45,19 +45,19 @@ template <class IRBuilderTy> class MatrixBuilder {
Value *RHS) {
assert((LHS->getType()->isVectorTy() || RHS->getType()->isVectorTy()) &&
"One of the operands must be a matrix (embedded in a vector)");
- if (LHS->getType()->isVectorTy() && !RHS->getType()->isVectorTy()) {
- assert(!isa<ScalableVectorType>(LHS->getType()) &&
- "LHS Assumed to be fixed width");
+ if (LHS->getType()->isVectorTy() && !RHS->getType()->isVectorTy()) {
+ assert(!isa<ScalableVectorType>(LHS->getType()) &&
+ "LHS Assumed to be fixed width");
RHS = B.CreateVectorSplat(
- cast<VectorType>(LHS->getType())->getElementCount(), RHS,
+ cast<VectorType>(LHS->getType())->getElementCount(), RHS,
"scalar.splat");
- } else if (!LHS->getType()->isVectorTy() && RHS->getType()->isVectorTy()) {
- assert(!isa<ScalableVectorType>(RHS->getType()) &&
- "RHS Assumed to be fixed width");
+ } else if (!LHS->getType()->isVectorTy() && RHS->getType()->isVectorTy()) {
+ assert(!isa<ScalableVectorType>(RHS->getType()) &&
+ "RHS Assumed to be fixed width");
LHS = B.CreateVectorSplat(
- cast<VectorType>(RHS->getType())->getElementCount(), LHS,
+ cast<VectorType>(RHS->getType())->getElementCount(), LHS,
"scalar.splat");
- }
+ }
return {LHS, RHS};
}
@@ -167,19 +167,19 @@ public:
/// matrixes.
Value *CreateAdd(Value *LHS, Value *RHS) {
assert(LHS->getType()->isVectorTy() || RHS->getType()->isVectorTy());
- if (LHS->getType()->isVectorTy() && !RHS->getType()->isVectorTy()) {
- assert(!isa<ScalableVectorType>(LHS->getType()) &&
- "LHS Assumed to be fixed width");
+ if (LHS->getType()->isVectorTy() && !RHS->getType()->isVectorTy()) {
+ assert(!isa<ScalableVectorType>(LHS->getType()) &&
+ "LHS Assumed to be fixed width");
RHS = B.CreateVectorSplat(
- cast<VectorType>(LHS->getType())->getElementCount(), RHS,
+ cast<VectorType>(LHS->getType())->getElementCount(), RHS,
"scalar.splat");
- } else if (!LHS->getType()->isVectorTy() && RHS->getType()->isVectorTy()) {
- assert(!isa<ScalableVectorType>(RHS->getType()) &&
- "RHS Assumed to be fixed width");
+ } else if (!LHS->getType()->isVectorTy() && RHS->getType()->isVectorTy()) {
+ assert(!isa<ScalableVectorType>(RHS->getType()) &&
+ "RHS Assumed to be fixed width");
LHS = B.CreateVectorSplat(
- cast<VectorType>(RHS->getType())->getElementCount(), LHS,
+ cast<VectorType>(RHS->getType())->getElementCount(), LHS,
"scalar.splat");
- }
+ }
return cast<VectorType>(LHS->getType())
->getElementType()
@@ -192,19 +192,19 @@ public:
/// point matrixes.
Value *CreateSub(Value *LHS, Value *RHS) {
assert(LHS->getType()->isVectorTy() || RHS->getType()->isVectorTy());
- if (LHS->getType()->isVectorTy() && !RHS->getType()->isVectorTy()) {
- assert(!isa<ScalableVectorType>(LHS->getType()) &&
- "LHS Assumed to be fixed width");
+ if (LHS->getType()->isVectorTy() && !RHS->getType()->isVectorTy()) {
+ assert(!isa<ScalableVectorType>(LHS->getType()) &&
+ "LHS Assumed to be fixed width");
RHS = B.CreateVectorSplat(
- cast<VectorType>(LHS->getType())->getElementCount(), RHS,
+ cast<VectorType>(LHS->getType())->getElementCount(), RHS,
"scalar.splat");
- } else if (!LHS->getType()->isVectorTy() && RHS->getType()->isVectorTy()) {
- assert(!isa<ScalableVectorType>(RHS->getType()) &&
- "RHS Assumed to be fixed width");
+ } else if (!LHS->getType()->isVectorTy() && RHS->getType()->isVectorTy()) {
+ assert(!isa<ScalableVectorType>(RHS->getType()) &&
+ "RHS Assumed to be fixed width");
LHS = B.CreateVectorSplat(
- cast<VectorType>(RHS->getType())->getElementCount(), LHS,
+ cast<VectorType>(RHS->getType())->getElementCount(), LHS,
"scalar.splat");
- }
+ }
return cast<VectorType>(LHS->getType())
->getElementType()
diff --git a/contrib/libs/llvm12/include/llvm/IR/Metadata.def b/contrib/libs/llvm12/include/llvm/IR/Metadata.def
index fa2c8a9cc6..f31be8d1bc 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Metadata.def
+++ b/contrib/libs/llvm12/include/llvm/IR/Metadata.def
@@ -114,8 +114,8 @@ HANDLE_SPECIALIZED_MDNODE_BRANCH(DIMacroNode)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacro)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacroFile)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DICommonBlock)
-HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIStringType)
-HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIGenericSubrange)
+HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIStringType)
+HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIGenericSubrange)
#undef HANDLE_METADATA
#undef HANDLE_METADATA_LEAF
diff --git a/contrib/libs/llvm12/include/llvm/IR/Metadata.h b/contrib/libs/llvm12/include/llvm/IR/Metadata.h
index 30321d7291..fb58b5d6aa 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Metadata.h
+++ b/contrib/libs/llvm12/include/llvm/IR/Metadata.h
@@ -674,12 +674,12 @@ struct AAMDNodes {
/// The tag specifying the noalias scope.
MDNode *NoAlias = nullptr;
- // Shift tbaa Metadata node to start off bytes later
- static MDNode *ShiftTBAA(MDNode *M, size_t off);
-
- // Shift tbaa.struct Metadata node to start off bytes later
- static MDNode *ShiftTBAAStruct(MDNode *M, size_t off);
-
+ // Shift tbaa Metadata node to start off bytes later
+ static MDNode *ShiftTBAA(MDNode *M, size_t off);
+
+ // Shift tbaa.struct Metadata node to start off bytes later
+ static MDNode *ShiftTBAAStruct(MDNode *M, size_t off);
+
/// 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
@@ -693,18 +693,18 @@ struct AAMDNodes {
Result.NoAlias = Other.NoAlias == NoAlias ? NoAlias : nullptr;
return Result;
}
-
- /// Create a new AAMDNode that describes this AAMDNode after applying a
- /// constant offset to the start of the pointer
- AAMDNodes shift(size_t Offset) {
- AAMDNodes Result;
- Result.TBAA = TBAA ? ShiftTBAA(TBAA, Offset) : nullptr;
- Result.TBAAStruct =
- TBAAStruct ? ShiftTBAAStruct(TBAAStruct, Offset) : nullptr;
- Result.Scope = Scope;
- Result.NoAlias = NoAlias;
- return Result;
- }
+
+ /// Create a new AAMDNode that describes this AAMDNode after applying a
+ /// constant offset to the start of the pointer
+ AAMDNodes shift(size_t Offset) {
+ AAMDNodes Result;
+ Result.TBAA = TBAA ? ShiftTBAA(TBAA, Offset) : nullptr;
+ Result.TBAAStruct =
+ TBAAStruct ? ShiftTBAAStruct(TBAAStruct, Offset) : nullptr;
+ Result.Scope = Scope;
+ Result.NoAlias = NoAlias;
+ return Result;
+ }
};
// Specialize DenseMapInfo for AAMDNodes.
@@ -1153,7 +1153,7 @@ class MDTuple : public MDNode {
StorageType Storage, bool ShouldCreate = true);
TempMDTuple cloneImpl() const {
- return getTemporary(getContext(), SmallVector<Metadata *, 4>(operands()));
+ return getTemporary(getContext(), SmallVector<Metadata *, 4>(operands()));
}
public:
@@ -1214,33 +1214,33 @@ void TempMDNodeDeleter::operator()(MDNode *Node) const {
MDNode::deleteTemporary(Node);
}
-/// This is a simple wrapper around an MDNode which provides a higher-level
-/// interface by hiding the details of how alias analysis information is encoded
-/// in its operands.
-class AliasScopeNode {
- const MDNode *Node = nullptr;
-
-public:
- AliasScopeNode() = default;
- explicit AliasScopeNode(const MDNode *N) : Node(N) {}
-
- /// Get the MDNode for this AliasScopeNode.
- const MDNode *getNode() const { return Node; }
-
- /// Get the MDNode for this AliasScopeNode's domain.
- const MDNode *getDomain() const {
- if (Node->getNumOperands() < 2)
- return nullptr;
- return dyn_cast_or_null<MDNode>(Node->getOperand(1));
- }
- StringRef getName() const {
- if (Node->getNumOperands() > 2)
- if (MDString *N = dyn_cast_or_null<MDString>(Node->getOperand(2)))
- return N->getString();
- return StringRef();
- }
-};
-
+/// This is a simple wrapper around an MDNode which provides a higher-level
+/// interface by hiding the details of how alias analysis information is encoded
+/// in its operands.
+class AliasScopeNode {
+ const MDNode *Node = nullptr;
+
+public:
+ AliasScopeNode() = default;
+ explicit AliasScopeNode(const MDNode *N) : Node(N) {}
+
+ /// Get the MDNode for this AliasScopeNode.
+ const MDNode *getNode() const { return Node; }
+
+ /// Get the MDNode for this AliasScopeNode's domain.
+ const MDNode *getDomain() const {
+ if (Node->getNumOperands() < 2)
+ return nullptr;
+ return dyn_cast_or_null<MDNode>(Node->getOperand(1));
+ }
+ StringRef getName() const {
+ if (Node->getNumOperands() > 2)
+ if (MDString *N = dyn_cast_or_null<MDString>(Node->getOperand(2)))
+ return N->getString();
+ return StringRef();
+ }
+};
+
/// Typed iterator through MDNode operands.
///
/// An iterator that transforms an \a MDNode::iterator into an iterator over a
diff --git a/contrib/libs/llvm12/include/llvm/IR/Module.h b/contrib/libs/llvm12/include/llvm/IR/Module.h
index d55ebabd41..068ac0e66d 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Module.h
+++ b/contrib/libs/llvm12/include/llvm/IR/Module.h
@@ -857,7 +857,7 @@ public:
/// Returns profile summary metadata. When IsCS is true, use the context
/// sensitive profile summary.
- Metadata *getProfileSummary(bool IsCS) const;
+ Metadata *getProfileSummary(bool IsCS) const;
/// @}
/// Returns whether semantic interposition is to be respected.
diff --git a/contrib/libs/llvm12/include/llvm/IR/ModuleSummaryIndex.h b/contrib/libs/llvm12/include/llvm/IR/ModuleSummaryIndex.h
index cce1a038be..7c32bf84f4 100644
--- a/contrib/libs/llvm12/include/llvm/IR/ModuleSummaryIndex.h
+++ b/contrib/libs/llvm12/include/llvm/IR/ModuleSummaryIndex.h
@@ -569,11 +569,11 @@ public:
/// offsets from the beginning of the value that are passed.
struct Call {
uint64_t ParamNo = 0;
- ValueInfo Callee;
+ ValueInfo Callee;
ConstantRange Offsets{/*BitWidth=*/RangeWidth, /*isFullSet=*/true};
Call() = default;
- Call(uint64_t ParamNo, ValueInfo Callee, const ConstantRange &Offsets)
+ Call(uint64_t ParamNo, ValueInfo Callee, const ConstantRange &Offsets)
: ParamNo(ParamNo), Callee(Callee), Offsets(Offsets) {}
};
@@ -603,7 +603,7 @@ public:
GlobalValue::LinkageTypes::AvailableExternallyLinkage,
/*NotEligibleToImport=*/true, /*Live=*/true, /*IsLocal=*/false,
/*CanAutoHide=*/false),
- /*NumInsts=*/0, FunctionSummary::FFlags{}, /*EntryCount=*/0,
+ /*NumInsts=*/0, FunctionSummary::FFlags{}, /*EntryCount=*/0,
std::vector<ValueInfo>(), std::move(Edges),
std::vector<GlobalValue::GUID>(),
std::vector<FunctionSummary::VFuncId>(),
@@ -1067,9 +1067,9 @@ private:
// some were not. Set when the combined index is created during the thin link.
bool PartiallySplitLTOUnits = false;
- /// True if some of the FunctionSummary contains a ParamAccess.
- bool HasParamAccess = false;
-
+ /// True if some of the FunctionSummary contains a ParamAccess.
+ bool HasParamAccess = false;
+
std::set<std::string> CfiFunctionDefs;
std::set<std::string> CfiFunctionDecls;
@@ -1222,8 +1222,8 @@ public:
bool partiallySplitLTOUnits() const { return PartiallySplitLTOUnits; }
void setPartiallySplitLTOUnits() { PartiallySplitLTOUnits = true; }
- bool hasParamAccess() const { return HasParamAccess; }
-
+ bool hasParamAccess() const { return HasParamAccess; }
+
bool isGlobalValueLive(const GlobalValueSummary *GVS) const {
return !WithGlobalValueDeadStripping || GVS->isLive();
}
@@ -1295,8 +1295,8 @@ public:
/// Add a global value summary for the given ValueInfo.
void addGlobalValueSummary(ValueInfo VI,
std::unique_ptr<GlobalValueSummary> Summary) {
- if (const FunctionSummary *FS = dyn_cast<FunctionSummary>(Summary.get()))
- HasParamAccess |= !FS->paramAccesses().empty();
+ if (const FunctionSummary *FS = dyn_cast<FunctionSummary>(Summary.get()))
+ HasParamAccess |= !FS->paramAccesses().empty();
addOriginalName(VI.getGUID(), Summary->getOriginalName());
// Here we have a notionally const VI, but the value it points to is owned
// by the non-const *this.
diff --git a/contrib/libs/llvm12/include/llvm/IR/Operator.h b/contrib/libs/llvm12/include/llvm/IR/Operator.h
index 1ede5fdcea..a6c7b64bd4 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Operator.h
+++ b/contrib/libs/llvm12/include/llvm/IR/Operator.h
@@ -575,11 +575,11 @@ public:
bool accumulateConstantOffset(
const DataLayout &DL, APInt &Offset,
function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr) const;
-
- static bool accumulateConstantOffset(
- Type *SourceType, ArrayRef<const Value *> Index, const DataLayout &DL,
- APInt &Offset,
- function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr);
+
+ static bool accumulateConstantOffset(
+ Type *SourceType, ArrayRef<const Value *> Index, const DataLayout &DL,
+ APInt &Offset,
+ function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr);
};
class PtrToIntOperator
diff --git a/contrib/libs/llvm12/include/llvm/IR/OptBisect.h b/contrib/libs/llvm12/include/llvm/IR/OptBisect.h
index c8a6df6e49..c49f9fe1b8 100644
--- a/contrib/libs/llvm12/include/llvm/IR/OptBisect.h
+++ b/contrib/libs/llvm12/include/llvm/IR/OptBisect.h
@@ -22,7 +22,7 @@
#define LLVM_IR_OPTBISECT_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/ManagedStatic.h"
namespace llvm {
@@ -40,7 +40,7 @@ public:
return true;
}
- /// isEnabled() should return true before calling shouldRunPass().
+ /// isEnabled() should return true before calling shouldRunPass().
virtual bool isEnabled() const { return false; }
};
@@ -63,14 +63,14 @@ public:
/// Checks the bisect limit to determine if the specified pass should run.
///
- /// This forwards to checkPass().
- bool shouldRunPass(const Pass *P, StringRef IRDescription) override;
-
- /// isEnabled() should return true before calling shouldRunPass().
- bool isEnabled() const override { return BisectEnabled; }
-
- /// Checks the bisect limit to determine if the specified pass should run.
- ///
+ /// This forwards to checkPass().
+ bool shouldRunPass(const Pass *P, StringRef IRDescription) override;
+
+ /// isEnabled() should return true before calling shouldRunPass().
+ bool isEnabled() const override { return BisectEnabled; }
+
+ /// Checks the bisect limit to determine if the specified pass should run.
+ ///
/// If the bisect limit is set to -1, the function prints a message describing
/// the pass and the bisect number assigned to it and return true. Otherwise,
/// the function prints a message with the bisect number assigned to the
@@ -80,16 +80,16 @@ public:
/// Most passes should not call this routine directly. Instead, they are
/// called through helper routines provided by the pass base classes. For
/// instance, function passes should call FunctionPass::skipFunction().
- bool checkPass(const StringRef PassName, const StringRef TargetDesc);
+ bool checkPass(const StringRef PassName, const StringRef TargetDesc);
private:
bool BisectEnabled = false;
unsigned LastBisectNum = 0;
};
-/// Singleton instance of the OptBisect class, so multiple pass managers don't
-/// need to coordinate their uses of OptBisect.
-extern ManagedStatic<OptBisect> OptBisector;
+/// Singleton instance of the OptBisect class, so multiple pass managers don't
+/// need to coordinate their uses of OptBisect.
+extern ManagedStatic<OptBisect> OptBisector;
} // end namespace llvm
#endif // LLVM_IR_OPTBISECT_H
diff --git a/contrib/libs/llvm12/include/llvm/IR/PassInstrumentation.h b/contrib/libs/llvm12/include/llvm/IR/PassInstrumentation.h
index a478b7e5a5..713d449226 100644
--- a/contrib/libs/llvm12/include/llvm/IR/PassInstrumentation.h
+++ b/contrib/libs/llvm12/include/llvm/IR/PassInstrumentation.h
@@ -59,7 +59,7 @@
#include "llvm/ADT/Any.h"
#include "llvm/ADT/FunctionExtras.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringMap.h"
#include <type_traits>
namespace llvm {
@@ -75,17 +75,17 @@ public:
// to take them as constant pointers, wrapped with llvm::Any.
// For the case when IRUnit has been invalidated there is a different
// callback to use - AfterPassInvalidated.
- // We call all BeforePassFuncs to determine if a pass should run or not.
- // BeforeNonSkippedPassFuncs are called only if the pass should run.
+ // We call all BeforePassFuncs to determine if a pass should run or not.
+ // BeforeNonSkippedPassFuncs are called only if the pass should run.
// TODO: currently AfterPassInvalidated does not accept IRUnit, since passing
- // already invalidated IRUnit is unsafe. There are ways to handle invalidated
- // IRUnits in a safe way, and we might pursue that as soon as there is a
- // useful instrumentation that needs it.
+ // already invalidated IRUnit is unsafe. There are ways to handle invalidated
+ // IRUnits in a safe way, and we might pursue that as soon as there is a
+ // useful instrumentation that needs it.
using BeforePassFunc = bool(StringRef, Any);
- using BeforeSkippedPassFunc = void(StringRef, Any);
- using BeforeNonSkippedPassFunc = void(StringRef, Any);
- using AfterPassFunc = void(StringRef, Any, const PreservedAnalyses &);
- using AfterPassInvalidatedFunc = void(StringRef, const PreservedAnalyses &);
+ using BeforeSkippedPassFunc = void(StringRef, Any);
+ using BeforeNonSkippedPassFunc = void(StringRef, Any);
+ using AfterPassFunc = void(StringRef, Any, const PreservedAnalyses &);
+ using AfterPassInvalidatedFunc = void(StringRef, const PreservedAnalyses &);
using BeforeAnalysisFunc = void(StringRef, Any);
using AfterAnalysisFunc = void(StringRef, Any);
@@ -96,21 +96,21 @@ public:
PassInstrumentationCallbacks(const PassInstrumentationCallbacks &) = delete;
void operator=(const PassInstrumentationCallbacks &) = delete;
- template <typename CallableT>
- void registerShouldRunOptionalPassCallback(CallableT C) {
- ShouldRunOptionalPassCallbacks.emplace_back(std::move(C));
+ template <typename CallableT>
+ void registerShouldRunOptionalPassCallback(CallableT C) {
+ ShouldRunOptionalPassCallbacks.emplace_back(std::move(C));
+ }
+
+ template <typename CallableT>
+ void registerBeforeSkippedPassCallback(CallableT C) {
+ BeforeSkippedPassCallbacks.emplace_back(std::move(C));
+ }
+
+ template <typename CallableT>
+ void registerBeforeNonSkippedPassCallback(CallableT C) {
+ BeforeNonSkippedPassCallbacks.emplace_back(std::move(C));
}
- template <typename CallableT>
- void registerBeforeSkippedPassCallback(CallableT C) {
- BeforeSkippedPassCallbacks.emplace_back(std::move(C));
- }
-
- template <typename CallableT>
- void registerBeforeNonSkippedPassCallback(CallableT C) {
- BeforeNonSkippedPassCallbacks.emplace_back(std::move(C));
- }
-
template <typename CallableT> void registerAfterPassCallback(CallableT C) {
AfterPassCallbacks.emplace_back(std::move(C));
}
@@ -130,37 +130,37 @@ public:
AfterAnalysisCallbacks.emplace_back(std::move(C));
}
- /// Add a class name to pass name mapping for use by pass instrumentation.
- void addClassToPassName(StringRef ClassName, StringRef PassName);
- /// Get the pass name for a given pass class name.
- StringRef getPassNameForClassName(StringRef ClassName);
-
+ /// Add a class name to pass name mapping for use by pass instrumentation.
+ void addClassToPassName(StringRef ClassName, StringRef PassName);
+ /// Get the pass name for a given pass class name.
+ StringRef getPassNameForClassName(StringRef ClassName);
+
private:
friend class PassInstrumentation;
- /// These are only run on passes that are not required. They return false when
- /// an optional pass should be skipped.
- SmallVector<llvm::unique_function<BeforePassFunc>, 4>
- ShouldRunOptionalPassCallbacks;
- /// These are run on passes that are skipped.
- SmallVector<llvm::unique_function<BeforeSkippedPassFunc>, 4>
- BeforeSkippedPassCallbacks;
- /// These are run on passes that are about to be run.
- SmallVector<llvm::unique_function<BeforeNonSkippedPassFunc>, 4>
- BeforeNonSkippedPassCallbacks;
- /// These are run on passes that have just run.
+ /// These are only run on passes that are not required. They return false when
+ /// an optional pass should be skipped.
+ SmallVector<llvm::unique_function<BeforePassFunc>, 4>
+ ShouldRunOptionalPassCallbacks;
+ /// These are run on passes that are skipped.
+ SmallVector<llvm::unique_function<BeforeSkippedPassFunc>, 4>
+ BeforeSkippedPassCallbacks;
+ /// These are run on passes that are about to be run.
+ SmallVector<llvm::unique_function<BeforeNonSkippedPassFunc>, 4>
+ BeforeNonSkippedPassCallbacks;
+ /// These are run on passes that have just run.
SmallVector<llvm::unique_function<AfterPassFunc>, 4> AfterPassCallbacks;
- /// These are run passes that have just run on invalidated IR.
+ /// These are run passes that have just run on invalidated IR.
SmallVector<llvm::unique_function<AfterPassInvalidatedFunc>, 4>
AfterPassInvalidatedCallbacks;
- /// These are run on analyses that are about to be run.
+ /// These are run on analyses that are about to be run.
SmallVector<llvm::unique_function<BeforeAnalysisFunc>, 4>
BeforeAnalysisCallbacks;
- /// These are run on analyses that have been run.
+ /// These are run on analyses that have been run.
SmallVector<llvm::unique_function<AfterAnalysisFunc>, 4>
AfterAnalysisCallbacks;
-
- StringMap<std::string> ClassToPassName;
+
+ StringMap<std::string> ClassToPassName;
};
/// This class provides instrumentation entry points for the Pass Manager,
@@ -168,26 +168,26 @@ private:
class PassInstrumentation {
PassInstrumentationCallbacks *Callbacks;
- // Template argument PassT of PassInstrumentation::runBeforePass could be two
- // kinds: (1) a regular pass inherited from PassInfoMixin (happen when
- // creating a adaptor pass for a regular pass); (2) a type-erased PassConcept
- // created from (1). Here we want to make case (1) skippable unconditionally
- // since they are regular passes. We call PassConcept::isRequired to decide
- // for case (2).
- template <typename PassT>
- using has_required_t = decltype(std::declval<PassT &>().isRequired());
-
- template <typename PassT>
- static std::enable_if_t<is_detected<has_required_t, PassT>::value, bool>
- isRequired(const PassT &Pass) {
- return Pass.isRequired();
- }
- template <typename PassT>
- static std::enable_if_t<!is_detected<has_required_t, PassT>::value, bool>
- isRequired(const PassT &Pass) {
- return false;
- }
-
+ // Template argument PassT of PassInstrumentation::runBeforePass could be two
+ // kinds: (1) a regular pass inherited from PassInfoMixin (happen when
+ // creating a adaptor pass for a regular pass); (2) a type-erased PassConcept
+ // created from (1). Here we want to make case (1) skippable unconditionally
+ // since they are regular passes. We call PassConcept::isRequired to decide
+ // for case (2).
+ template <typename PassT>
+ using has_required_t = decltype(std::declval<PassT &>().isRequired());
+
+ template <typename PassT>
+ static std::enable_if_t<is_detected<has_required_t, PassT>::value, bool>
+ isRequired(const PassT &Pass) {
+ return Pass.isRequired();
+ }
+ template <typename PassT>
+ static std::enable_if_t<!is_detected<has_required_t, PassT>::value, bool>
+ isRequired(const PassT &Pass) {
+ return false;
+ }
+
public:
/// Callbacks object is not owned by PassInstrumentation, its life-time
/// should at least match the life-time of corresponding
@@ -198,28 +198,28 @@ public:
/// BeforePass instrumentation point - takes \p Pass instance to be executed
/// and constant reference to IR it operates on. \Returns true if pass is
- /// allowed to be executed. These are only run on optional pass since required
- /// passes must always be run. This allows these callbacks to print info when
- /// they want to skip a pass.
+ /// allowed to be executed. These are only run on optional pass since required
+ /// passes must always be run. This allows these callbacks to print info when
+ /// they want to skip a pass.
template <typename IRUnitT, typename PassT>
bool runBeforePass(const PassT &Pass, const IRUnitT &IR) const {
if (!Callbacks)
return true;
bool ShouldRun = true;
- if (!isRequired(Pass)) {
- for (auto &C : Callbacks->ShouldRunOptionalPassCallbacks)
- ShouldRun &= C(Pass.name(), llvm::Any(&IR));
- }
-
- if (ShouldRun) {
- for (auto &C : Callbacks->BeforeNonSkippedPassCallbacks)
- C(Pass.name(), llvm::Any(&IR));
- } else {
- for (auto &C : Callbacks->BeforeSkippedPassCallbacks)
- C(Pass.name(), llvm::Any(&IR));
- }
-
+ if (!isRequired(Pass)) {
+ for (auto &C : Callbacks->ShouldRunOptionalPassCallbacks)
+ ShouldRun &= C(Pass.name(), llvm::Any(&IR));
+ }
+
+ if (ShouldRun) {
+ for (auto &C : Callbacks->BeforeNonSkippedPassCallbacks)
+ C(Pass.name(), llvm::Any(&IR));
+ } else {
+ for (auto &C : Callbacks->BeforeSkippedPassCallbacks)
+ C(Pass.name(), llvm::Any(&IR));
+ }
+
return ShouldRun;
}
@@ -227,22 +227,22 @@ public:
/// just been executed and constant reference to \p IR it operates on.
/// \p IR is guaranteed to be valid at this point.
template <typename IRUnitT, typename PassT>
- void runAfterPass(const PassT &Pass, const IRUnitT &IR,
- const PreservedAnalyses &PA) const {
+ void runAfterPass(const PassT &Pass, const IRUnitT &IR,
+ const PreservedAnalyses &PA) const {
if (Callbacks)
for (auto &C : Callbacks->AfterPassCallbacks)
- C(Pass.name(), llvm::Any(&IR), PA);
+ C(Pass.name(), llvm::Any(&IR), PA);
}
/// AfterPassInvalidated instrumentation point - takes \p Pass instance
/// that has just been executed. For use when IR has been invalidated
/// by \p Pass execution.
template <typename IRUnitT, typename PassT>
- void runAfterPassInvalidated(const PassT &Pass,
- const PreservedAnalyses &PA) const {
+ void runAfterPassInvalidated(const PassT &Pass,
+ const PreservedAnalyses &PA) const {
if (Callbacks)
for (auto &C : Callbacks->AfterPassInvalidatedCallbacks)
- C(Pass.name(), PA);
+ C(Pass.name(), PA);
}
/// BeforeAnalysis instrumentation point - takes \p Analysis instance
@@ -273,20 +273,20 @@ public:
ExtraArgsT...) {
return false;
}
-
- template <typename CallableT>
- void pushBeforeNonSkippedPassCallback(CallableT C) {
- if (Callbacks)
- Callbacks->BeforeNonSkippedPassCallbacks.emplace_back(std::move(C));
- }
- void popBeforeNonSkippedPassCallback() {
- if (Callbacks)
- Callbacks->BeforeNonSkippedPassCallbacks.pop_back();
- }
+
+ template <typename CallableT>
+ void pushBeforeNonSkippedPassCallback(CallableT C) {
+ if (Callbacks)
+ Callbacks->BeforeNonSkippedPassCallbacks.emplace_back(std::move(C));
+ }
+ void popBeforeNonSkippedPassCallback() {
+ if (Callbacks)
+ Callbacks->BeforeNonSkippedPassCallbacks.pop_back();
+ }
};
-bool isSpecialPass(StringRef PassID, const std::vector<StringRef> &Specials);
-
+bool isSpecialPass(StringRef PassID, const std::vector<StringRef> &Specials);
+
} // namespace llvm
#endif
diff --git a/contrib/libs/llvm12/include/llvm/IR/PassManager.h b/contrib/libs/llvm12/include/llvm/IR/PassManager.h
index e942ba2110..195b4c27fa 100644
--- a/contrib/libs/llvm12/include/llvm/IR/PassManager.h
+++ b/contrib/libs/llvm12/include/llvm/IR/PassManager.h
@@ -45,7 +45,7 @@
#define LLVM_IR_PASSMANAGER_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
@@ -526,7 +526,7 @@ public:
// Call onto PassInstrumentation's AfterPass callbacks immediately after
// running the pass.
- PI.runAfterPass<IRUnitT>(*P, IR, PassPA);
+ PI.runAfterPass<IRUnitT>(*P, IR, PassPA);
// Update the analysis manager as each pass runs and potentially
// invalidates analyses.
@@ -555,9 +555,9 @@ public:
return PA;
}
- template <typename PassT>
- std::enable_if_t<!std::is_same<PassT, PassManager>::value>
- addPass(PassT Pass) {
+ template <typename PassT>
+ std::enable_if_t<!std::is_same<PassT, PassManager>::value>
+ addPass(PassT Pass) {
using PassModelT =
detail::PassModel<IRUnitT, PassT, PreservedAnalyses, AnalysisManagerT,
ExtraArgTs...>;
@@ -565,24 +565,24 @@ public:
Passes.emplace_back(new PassModelT(std::move(Pass)));
}
- /// When adding a pass manager pass that has the same type as this pass
- /// manager, simply move the passes over. This is because we don't have use
- /// cases rely on executing nested pass managers. Doing this could reduce
- /// implementation complexity and avoid potential invalidation issues that may
- /// happen with nested pass managers of the same type.
- template <typename PassT>
- std::enable_if_t<std::is_same<PassT, PassManager>::value>
- addPass(PassT &&Pass) {
- for (auto &P : Pass.Passes)
- Passes.emplace_back(std::move(P));
- }
-
- /// Returns if the pass manager contains any passes.
- bool isEmpty() const { return Passes.empty(); }
-
- static bool isRequired() { return true; }
-
-protected:
+ /// When adding a pass manager pass that has the same type as this pass
+ /// manager, simply move the passes over. This is because we don't have use
+ /// cases rely on executing nested pass managers. Doing this could reduce
+ /// implementation complexity and avoid potential invalidation issues that may
+ /// happen with nested pass managers of the same type.
+ template <typename PassT>
+ std::enable_if_t<std::is_same<PassT, PassManager>::value>
+ addPass(PassT &&Pass) {
+ for (auto &P : Pass.Passes)
+ Passes.emplace_back(std::move(P));
+ }
+
+ /// Returns if the pass manager contains any passes.
+ bool isEmpty() const { return Passes.empty(); }
+
+ static bool isRequired() { return true; }
+
+protected:
using PassConceptT =
detail::PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...>;
@@ -672,7 +672,7 @@ public:
/// when any of its embedded analysis results end up invalidated. We pass an
/// \c Invalidator object as an argument to \c invalidate() in order to let
/// the analysis results themselves define the dependency graph on the fly.
- /// This lets us avoid building an explicit representation of the
+ /// This lets us avoid building an explicit representation of the
/// dependencies between analysis results.
class Invalidator {
public:
@@ -867,7 +867,7 @@ public:
return true;
}
- /// Invalidate a specific analysis pass for an IR unit.
+ /// Invalidate a specific analysis pass for an IR unit.
///
/// Note that the analysis result can disregard invalidation, if it determines
/// it is in fact still valid.
@@ -911,7 +911,7 @@ private:
return RI == AnalysisResults.end() ? nullptr : &*RI->second->second;
}
- /// Invalidate a pass result for a IR unit.
+ /// Invalidate a pass result for a IR unit.
void invalidateImpl(AnalysisKey *ID, IRUnitT &IR) {
typename AnalysisResultMapT::iterator RI =
AnalysisResults.find({ID, &IR});
@@ -925,20 +925,20 @@ private:
AnalysisResults.erase(RI);
}
- /// Map type from analysis pass ID to pass concept pointer.
+ /// Map type from analysis pass ID to pass concept pointer.
using AnalysisPassMapT =
DenseMap<AnalysisKey *, std::unique_ptr<PassConceptT>>;
- /// Collection of analysis passes, indexed by ID.
+ /// Collection of analysis passes, indexed by ID.
AnalysisPassMapT AnalysisPasses;
- /// Map from IR unit to a list of analysis results.
+ /// Map from IR unit to a list of analysis results.
///
- /// Provides linear time removal of all analysis results for a IR unit and
+ /// Provides linear time removal of all analysis results for a IR unit and
/// the ultimate storage for a particular cached analysis result.
AnalysisResultListMapT AnalysisResultLists;
- /// Map from an analysis ID and IR unit to a particular cached
+ /// Map from an analysis ID and IR unit to a particular cached
/// analysis result.
AnalysisResultMapT AnalysisResults;
@@ -1082,16 +1082,16 @@ extern template class InnerAnalysisManagerProxy<FunctionAnalysisManager,
///
/// This proxy only exposes the const interface of the outer analysis manager,
/// to indicate that you cannot cause an outer analysis to run from within an
-/// inner pass. Instead, you must rely on the \c getCachedResult API. This is
-/// due to keeping potential future concurrency in mind. To give an example,
-/// running a module analysis before any function passes may give a different
-/// result than running it in a function pass. Both may be valid, but it would
-/// produce non-deterministic results. GlobalsAA is a good analysis example,
-/// because the cached information has the mod/ref info for all memory for each
-/// function at the time the analysis was computed. The information is still
-/// valid after a function transformation, but it may be *different* if
-/// recomputed after that transform. GlobalsAA is never invalidated.
-
+/// inner pass. Instead, you must rely on the \c getCachedResult API. This is
+/// due to keeping potential future concurrency in mind. To give an example,
+/// running a module analysis before any function passes may give a different
+/// result than running it in a function pass. Both may be valid, but it would
+/// produce non-deterministic results. GlobalsAA is a good analysis example,
+/// because the cached information has the mod/ref info for all memory for each
+/// function at the time the analysis was computed. The information is still
+/// valid after a function transformation, but it may be *different* if
+/// recomputed after that transform. GlobalsAA is never invalidated.
+
///
/// This proxy doesn't manage invalidation in any way -- that is handled by the
/// recursive return path of each layer of the pass manager. A consequence of
@@ -1136,9 +1136,9 @@ public:
for (auto &KeyValuePair : OuterAnalysisInvalidationMap) {
AnalysisKey *OuterID = KeyValuePair.first;
auto &InnerIDs = KeyValuePair.second;
- llvm::erase_if(InnerIDs, [&](AnalysisKey *InnerID) {
- return Inv.invalidate(InnerID, IRUnit, PA);
- });
+ llvm::erase_if(InnerIDs, [&](AnalysisKey *InnerID) {
+ return Inv.invalidate(InnerID, IRUnit, PA);
+ });
if (InnerIDs.empty())
DeadKeys.push_back(OuterID);
}
@@ -1162,7 +1162,7 @@ public:
// analyses that all trigger invalidation on the same outer analysis,
// this entire system should be changed to some other deterministic
// data structure such as a `SetVector` of a pair of pointers.
- if (!llvm::is_contained(InvalidatedIDList, InvalidatedID))
+ if (!llvm::is_contained(InvalidatedIDList, InvalidatedID))
InvalidatedIDList.push_back(InvalidatedID);
}
@@ -1236,33 +1236,33 @@ using ModuleAnalysisManagerFunctionProxy =
/// analyses are not invalidated while the function passes are running, so they
/// may be stale. Function analyses will not be stale.
class ModuleToFunctionPassAdaptor
- : public PassInfoMixin<ModuleToFunctionPassAdaptor> {
+ : public PassInfoMixin<ModuleToFunctionPassAdaptor> {
public:
- using PassConceptT = detail::PassConcept<Function, FunctionAnalysisManager>;
-
- explicit ModuleToFunctionPassAdaptor(std::unique_ptr<PassConceptT> Pass)
+ using PassConceptT = detail::PassConcept<Function, FunctionAnalysisManager>;
+
+ explicit ModuleToFunctionPassAdaptor(std::unique_ptr<PassConceptT> Pass)
: Pass(std::move(Pass)) {}
/// Runs the function pass across every function in the module.
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
private:
- std::unique_ptr<PassConceptT> Pass;
+ std::unique_ptr<PassConceptT> Pass;
};
/// A function to deduce a function pass type and wrap it in the
/// templated adaptor.
template <typename FunctionPassT>
-ModuleToFunctionPassAdaptor
+ModuleToFunctionPassAdaptor
createModuleToFunctionPassAdaptor(FunctionPassT Pass) {
- using PassModelT =
- detail::PassModel<Function, FunctionPassT, PreservedAnalyses,
- FunctionAnalysisManager>;
-
- return ModuleToFunctionPassAdaptor(
- std::make_unique<PassModelT>(std::move(Pass)));
+ using PassModelT =
+ detail::PassModel<Function, FunctionPassT, PreservedAnalyses,
+ FunctionAnalysisManager>;
+
+ return ModuleToFunctionPassAdaptor(
+ std::make_unique<PassModelT>(std::move(Pass)));
}
/// A utility pass template to force an analysis result to be available.
@@ -1293,7 +1293,7 @@ struct RequireAnalysisPass
return PreservedAnalyses::all();
}
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
};
/// A no-op pass template which simply forces a specific analysis result
@@ -1354,9 +1354,9 @@ public:
// false).
if (!PI.runBeforePass<IRUnitT>(P, IR))
continue;
- PreservedAnalyses IterPA = P.run(IR, AM, std::forward<Ts>(Args)...);
- PA.intersect(IterPA);
- PI.runAfterPass(P, IR, IterPA);
+ PreservedAnalyses IterPA = P.run(IR, AM, std::forward<Ts>(Args)...);
+ PA.intersect(IterPA);
+ PI.runAfterPass(P, IR, IterPA);
}
return PA;
}
diff --git a/contrib/libs/llvm12/include/llvm/IR/PassManagerInternal.h b/contrib/libs/llvm12/include/llvm/IR/PassManagerInternal.h
index 6f92b8fb54..8d5ddd82cb 100644
--- a/contrib/libs/llvm12/include/llvm/IR/PassManagerInternal.h
+++ b/contrib/libs/llvm12/include/llvm/IR/PassManagerInternal.h
@@ -55,12 +55,12 @@ struct PassConcept {
/// Polymorphic method to access the name of a pass.
virtual StringRef name() const = 0;
-
- /// Polymorphic method to to let a pass optionally exempted from skipping by
- /// PassInstrumentation.
- /// To opt-in, pass should implement `static bool isRequired()`. It's no-op
- /// to have `isRequired` always return false since that is the default.
- virtual bool isRequired() const = 0;
+
+ /// Polymorphic method to to let a pass optionally exempted from skipping by
+ /// PassInstrumentation.
+ /// To opt-in, pass should implement `static bool isRequired()`. It's no-op
+ /// to have `isRequired` always return false since that is the default.
+ virtual bool isRequired() const = 0;
};
/// A template wrapper used to implement the polymorphic API.
@@ -94,22 +94,22 @@ struct PassModel : PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...> {
StringRef name() const override { return PassT::name(); }
- template <typename T>
- using has_required_t = decltype(std::declval<T &>().isRequired());
-
- template <typename T>
- static std::enable_if_t<is_detected<has_required_t, T>::value, bool>
- passIsRequiredImpl() {
- return T::isRequired();
- }
- template <typename T>
- static std::enable_if_t<!is_detected<has_required_t, T>::value, bool>
- passIsRequiredImpl() {
- return false;
- }
-
- bool isRequired() const override { return passIsRequiredImpl<PassT>(); }
-
+ template <typename T>
+ using has_required_t = decltype(std::declval<T &>().isRequired());
+
+ template <typename T>
+ static std::enable_if_t<is_detected<has_required_t, T>::value, bool>
+ passIsRequiredImpl() {
+ return T::isRequired();
+ }
+ template <typename T>
+ static std::enable_if_t<!is_detected<has_required_t, T>::value, bool>
+ passIsRequiredImpl() {
+ return false;
+ }
+
+ bool isRequired() const override { return passIsRequiredImpl<PassT>(); }
+
PassT Pass;
};
diff --git a/contrib/libs/llvm12/include/llvm/IR/PassTimingInfo.h b/contrib/libs/llvm12/include/llvm/IR/PassTimingInfo.h
index 75b937b1e6..a6fb575667 100644
--- a/contrib/libs/llvm12/include/llvm/IR/PassTimingInfo.h
+++ b/contrib/libs/llvm12/include/llvm/IR/PassTimingInfo.h
@@ -24,13 +24,13 @@
#include "llvm/ADT/Any.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Timer.h"
#include <memory>
-#include <utility>
-
+#include <utility>
+
namespace llvm {
class Pass;
@@ -72,11 +72,11 @@ class TimePassesHandler {
raw_ostream *OutStream = nullptr;
bool Enabled;
- bool PerRun;
+ bool PerRun;
public:
- TimePassesHandler();
- TimePassesHandler(bool Enabled, bool PerRun = false);
+ TimePassesHandler();
+ TimePassesHandler(bool Enabled, bool PerRun = false);
/// Destructor handles the print action if it has not been handled before.
~TimePassesHandler() { print(); }
@@ -104,7 +104,7 @@ private:
void stopTimer(StringRef PassID);
// Implementation of pass instrumentation callbacks.
- void runBeforePass(StringRef PassID);
+ void runBeforePass(StringRef PassID);
void runAfterPass(StringRef PassID);
};
diff --git a/contrib/libs/llvm12/include/llvm/IR/PatternMatch.h b/contrib/libs/llvm12/include/llvm/IR/PatternMatch.h
index 2b6566a57b..a4aae7e731 100644
--- a/contrib/libs/llvm12/include/llvm/IR/PatternMatch.h
+++ b/contrib/libs/llvm12/include/llvm/IR/PatternMatch.h
@@ -95,29 +95,29 @@ inline class_match<BinaryOperator> m_BinOp() {
/// Matches any compare instruction and ignore it.
inline class_match<CmpInst> m_Cmp() { return class_match<CmpInst>(); }
-/// Match an arbitrary undef constant.
-inline class_match<UndefValue> m_Undef() { return class_match<UndefValue>(); }
-
-/// Match an arbitrary poison constant.
-inline class_match<PoisonValue> m_Poison() { return class_match<PoisonValue>(); }
-
-/// Match an arbitrary Constant and ignore it.
-inline class_match<Constant> m_Constant() { return class_match<Constant>(); }
-
+/// Match an arbitrary undef constant.
+inline class_match<UndefValue> m_Undef() { return class_match<UndefValue>(); }
+
+/// Match an arbitrary poison constant.
+inline class_match<PoisonValue> m_Poison() { return class_match<PoisonValue>(); }
+
+/// Match an arbitrary Constant and ignore it.
+inline class_match<Constant> m_Constant() { return class_match<Constant>(); }
+
/// Match an arbitrary ConstantInt and ignore it.
inline class_match<ConstantInt> m_ConstantInt() {
return class_match<ConstantInt>();
}
-/// Match an arbitrary ConstantFP and ignore it.
-inline class_match<ConstantFP> m_ConstantFP() {
- return class_match<ConstantFP>();
-}
+/// Match an arbitrary ConstantFP and ignore it.
+inline class_match<ConstantFP> m_ConstantFP() {
+ return class_match<ConstantFP>();
+}
-/// Match an arbitrary ConstantExpr and ignore it.
-inline class_match<ConstantExpr> m_ConstantExpr() {
- return class_match<ConstantExpr>();
-}
+/// Match an arbitrary ConstantExpr and ignore it.
+inline class_match<ConstantExpr> m_ConstantExpr() {
+ return class_match<ConstantExpr>();
+}
/// Match an arbitrary basic block value and ignore it.
inline class_match<BasicBlock> m_BasicBlock() {
@@ -355,33 +355,33 @@ template <typename Predicate> struct api_pred_ty : public Predicate {
}
};
-/// This helper class is used to match scalar and vector constants that
-/// satisfy a specified predicate, and bind them to an APFloat.
-/// Undefs are allowed in splat vector constants.
-template <typename Predicate> struct apf_pred_ty : public Predicate {
- const APFloat *&Res;
-
- apf_pred_ty(const APFloat *&R) : Res(R) {}
-
- template <typename ITy> bool match(ITy *V) {
- if (const auto *CI = dyn_cast<ConstantFP>(V))
- if (this->isValue(CI->getValue())) {
- Res = &CI->getValue();
- return true;
- }
- if (V->getType()->isVectorTy())
- if (const auto *C = dyn_cast<Constant>(V))
- if (auto *CI = dyn_cast_or_null<ConstantFP>(
- C->getSplatValue(/* AllowUndef */ true)))
- if (this->isValue(CI->getValue())) {
- Res = &CI->getValue();
- return true;
- }
-
- return false;
- }
-};
-
+/// This helper class is used to match scalar and vector constants that
+/// satisfy a specified predicate, and bind them to an APFloat.
+/// Undefs are allowed in splat vector constants.
+template <typename Predicate> struct apf_pred_ty : public Predicate {
+ const APFloat *&Res;
+
+ apf_pred_ty(const APFloat *&R) : Res(R) {}
+
+ template <typename ITy> bool match(ITy *V) {
+ if (const auto *CI = dyn_cast<ConstantFP>(V))
+ if (this->isValue(CI->getValue())) {
+ Res = &CI->getValue();
+ return true;
+ }
+ if (V->getType()->isVectorTy())
+ if (const auto *C = dyn_cast<Constant>(V))
+ if (auto *CI = dyn_cast_or_null<ConstantFP>(
+ C->getSplatValue(/* AllowUndef */ true)))
+ if (this->isValue(CI->getValue())) {
+ Res = &CI->getValue();
+ return true;
+ }
+
+ return false;
+ }
+};
+
///////////////////////////////////////////////////////////////////////////////
//
// Encapsulate constant value queries for use in templated predicate matchers.
@@ -602,15 +602,15 @@ inline cstfp_pred_ty<is_nan> m_NaN() {
return cstfp_pred_ty<is_nan>();
}
-struct is_nonnan {
- bool isValue(const APFloat &C) { return !C.isNaN(); }
-};
-/// Match a non-NaN FP constant.
-/// For vectors, this includes constants with undefined elements.
-inline cstfp_pred_ty<is_nonnan> m_NonNaN() {
- return cstfp_pred_ty<is_nonnan>();
-}
-
+struct is_nonnan {
+ bool isValue(const APFloat &C) { return !C.isNaN(); }
+};
+/// Match a non-NaN FP constant.
+/// For vectors, this includes constants with undefined elements.
+inline cstfp_pred_ty<is_nonnan> m_NonNaN() {
+ return cstfp_pred_ty<is_nonnan>();
+}
+
struct is_inf {
bool isValue(const APFloat &C) { return C.isInfinity(); }
};
@@ -620,37 +620,37 @@ inline cstfp_pred_ty<is_inf> m_Inf() {
return cstfp_pred_ty<is_inf>();
}
-struct is_noninf {
- bool isValue(const APFloat &C) { return !C.isInfinity(); }
-};
-/// Match a non-infinity FP constant, i.e. finite or NaN.
-/// For vectors, this includes constants with undefined elements.
-inline cstfp_pred_ty<is_noninf> m_NonInf() {
- return cstfp_pred_ty<is_noninf>();
-}
-
-struct is_finite {
- bool isValue(const APFloat &C) { return C.isFinite(); }
-};
-/// Match a finite FP constant, i.e. not infinity or NaN.
-/// For vectors, this includes constants with undefined elements.
-inline cstfp_pred_ty<is_finite> m_Finite() {
- return cstfp_pred_ty<is_finite>();
-}
-inline apf_pred_ty<is_finite> m_Finite(const APFloat *&V) { return V; }
-
-struct is_finitenonzero {
- bool isValue(const APFloat &C) { return C.isFiniteNonZero(); }
-};
-/// Match a finite non-zero FP constant.
-/// For vectors, this includes constants with undefined elements.
-inline cstfp_pred_ty<is_finitenonzero> m_FiniteNonZero() {
- return cstfp_pred_ty<is_finitenonzero>();
-}
-inline apf_pred_ty<is_finitenonzero> m_FiniteNonZero(const APFloat *&V) {
- return V;
-}
-
+struct is_noninf {
+ bool isValue(const APFloat &C) { return !C.isInfinity(); }
+};
+/// Match a non-infinity FP constant, i.e. finite or NaN.
+/// For vectors, this includes constants with undefined elements.
+inline cstfp_pred_ty<is_noninf> m_NonInf() {
+ return cstfp_pred_ty<is_noninf>();
+}
+
+struct is_finite {
+ bool isValue(const APFloat &C) { return C.isFinite(); }
+};
+/// Match a finite FP constant, i.e. not infinity or NaN.
+/// For vectors, this includes constants with undefined elements.
+inline cstfp_pred_ty<is_finite> m_Finite() {
+ return cstfp_pred_ty<is_finite>();
+}
+inline apf_pred_ty<is_finite> m_Finite(const APFloat *&V) { return V; }
+
+struct is_finitenonzero {
+ bool isValue(const APFloat &C) { return C.isFiniteNonZero(); }
+};
+/// Match a finite non-zero FP constant.
+/// For vectors, this includes constants with undefined elements.
+inline cstfp_pred_ty<is_finitenonzero> m_FiniteNonZero() {
+ return cstfp_pred_ty<is_finitenonzero>();
+}
+inline apf_pred_ty<is_finitenonzero> m_FiniteNonZero(const APFloat *&V) {
+ return V;
+}
+
struct is_any_zero_fp {
bool isValue(const APFloat &C) { return C.isZero(); }
};
@@ -678,15 +678,15 @@ inline cstfp_pred_ty<is_neg_zero_fp> m_NegZeroFP() {
return cstfp_pred_ty<is_neg_zero_fp>();
}
-struct is_non_zero_fp {
- bool isValue(const APFloat &C) { return C.isNonZero(); }
-};
-/// Match a floating-point non-zero.
-/// For vectors, this includes constants with undefined elements.
-inline cstfp_pred_ty<is_non_zero_fp> m_NonZeroFP() {
- return cstfp_pred_ty<is_non_zero_fp>();
-}
-
+struct is_non_zero_fp {
+ bool isValue(const APFloat &C) { return C.isNonZero(); }
+};
+/// Match a floating-point non-zero.
+/// For vectors, this includes constants with undefined elements.
+inline cstfp_pred_ty<is_non_zero_fp> m_NonZeroFP() {
+ return cstfp_pred_ty<is_non_zero_fp>();
+}
+
///////////////////////////////////////////////////////////////////////////////
template <typename Class> struct bind_ty {
@@ -716,38 +716,38 @@ inline bind_ty<BinaryOperator> m_BinOp(BinaryOperator *&I) { return I; }
/// Match a with overflow intrinsic, capturing it if we match.
inline bind_ty<WithOverflowInst> m_WithOverflowInst(WithOverflowInst *&I) { return I; }
-/// Match a Constant, capturing the value if we match.
-inline bind_ty<Constant> m_Constant(Constant *&C) { return C; }
-
+/// Match a Constant, capturing the value if we match.
+inline bind_ty<Constant> m_Constant(Constant *&C) { return C; }
+
/// Match a ConstantInt, capturing the value if we match.
inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; }
/// Match a ConstantFP, capturing the value if we match.
inline bind_ty<ConstantFP> m_ConstantFP(ConstantFP *&C) { return C; }
-/// Match a ConstantExpr, capturing the value if we match.
-inline bind_ty<ConstantExpr> m_ConstantExpr(ConstantExpr *&C) { return C; }
-
+/// Match a ConstantExpr, capturing the value if we match.
+inline bind_ty<ConstantExpr> m_ConstantExpr(ConstantExpr *&C) { return C; }
+
/// Match a basic block value, capturing it if we match.
inline bind_ty<BasicBlock> m_BasicBlock(BasicBlock *&V) { return V; }
inline bind_ty<const BasicBlock> m_BasicBlock(const BasicBlock *&V) {
return V;
}
-/// Match an arbitrary immediate Constant and ignore it.
-inline match_combine_and<class_match<Constant>,
- match_unless<class_match<ConstantExpr>>>
-m_ImmConstant() {
- return m_CombineAnd(m_Constant(), m_Unless(m_ConstantExpr()));
-}
-
-/// Match an immediate Constant, capturing the value if we match.
-inline match_combine_and<bind_ty<Constant>,
- match_unless<class_match<ConstantExpr>>>
-m_ImmConstant(Constant *&C) {
- return m_CombineAnd(m_Constant(C), m_Unless(m_ConstantExpr()));
-}
-
+/// Match an arbitrary immediate Constant and ignore it.
+inline match_combine_and<class_match<Constant>,
+ match_unless<class_match<ConstantExpr>>>
+m_ImmConstant() {
+ return m_CombineAnd(m_Constant(), m_Unless(m_ConstantExpr()));
+}
+
+/// Match an immediate Constant, capturing the value if we match.
+inline match_combine_and<bind_ty<Constant>,
+ match_unless<class_match<ConstantExpr>>>
+m_ImmConstant(Constant *&C) {
+ return m_CombineAnd(m_Constant(C), m_Unless(m_ConstantExpr()));
+}
+
/// Match a specified Value*.
struct specificval_ty {
const Value *Val;
@@ -818,7 +818,7 @@ struct bind_const_intval_ty {
/// Match a specified integer value or vector of all elements of that
/// value.
-template <bool AllowUndefs>
+template <bool AllowUndefs>
struct specific_intval {
APInt Val;
@@ -828,7 +828,7 @@ struct specific_intval {
const auto *CI = dyn_cast<ConstantInt>(V);
if (!CI && V->getType()->isVectorTy())
if (const auto *C = dyn_cast<Constant>(V))
- CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue(AllowUndefs));
+ CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue(AllowUndefs));
return CI && APInt::isSameValue(CI->getValue(), Val);
}
@@ -836,22 +836,22 @@ struct specific_intval {
/// Match a specific integer value or vector with all elements equal to
/// the value.
-inline specific_intval<false> m_SpecificInt(APInt V) {
- return specific_intval<false>(std::move(V));
+inline specific_intval<false> m_SpecificInt(APInt V) {
+ return specific_intval<false>(std::move(V));
}
-inline specific_intval<false> m_SpecificInt(uint64_t V) {
+inline specific_intval<false> m_SpecificInt(uint64_t V) {
return m_SpecificInt(APInt(64, V));
}
-inline specific_intval<true> m_SpecificIntAllowUndef(APInt V) {
- return specific_intval<true>(std::move(V));
-}
-
-inline specific_intval<true> m_SpecificIntAllowUndef(uint64_t V) {
- return m_SpecificIntAllowUndef(APInt(64, V));
-}
-
+inline specific_intval<true> m_SpecificIntAllowUndef(APInt V) {
+ return specific_intval<true>(std::move(V));
+}
+
+inline specific_intval<true> m_SpecificIntAllowUndef(uint64_t V) {
+ return m_SpecificIntAllowUndef(APInt(64, V));
+}
+
/// Match a ConstantInt and bind to its value. This does not match
/// ConstantInts wider than 64-bits.
inline bind_const_intval_ty m_ConstantInt(uint64_t &V) { return V; }
@@ -1564,12 +1564,12 @@ inline CastClass_match<OpTy, Instruction::PtrToInt> m_PtrToInt(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::PtrToInt>(Op);
}
-/// Matches IntToPtr.
-template <typename OpTy>
-inline CastClass_match<OpTy, Instruction::IntToPtr> m_IntToPtr(const OpTy &Op) {
- return CastClass_match<OpTy, Instruction::IntToPtr>(Op);
-}
-
+/// Matches IntToPtr.
+template <typename OpTy>
+inline CastClass_match<OpTy, Instruction::IntToPtr> m_IntToPtr(const OpTy &Op) {
+ return CastClass_match<OpTy, Instruction::IntToPtr>(Op);
+}
+
/// Matches Trunc.
template <typename OpTy>
inline CastClass_match<OpTy, Instruction::Trunc> m_Trunc(const OpTy &Op) {
@@ -1718,17 +1718,17 @@ struct MaxMin_match {
MaxMin_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
template <typename OpTy> bool match(OpTy *V) {
- if (auto *II = dyn_cast<IntrinsicInst>(V)) {
- Intrinsic::ID IID = II->getIntrinsicID();
- if ((IID == Intrinsic::smax && Pred_t::match(ICmpInst::ICMP_SGT)) ||
- (IID == Intrinsic::smin && Pred_t::match(ICmpInst::ICMP_SLT)) ||
- (IID == Intrinsic::umax && Pred_t::match(ICmpInst::ICMP_UGT)) ||
- (IID == Intrinsic::umin && Pred_t::match(ICmpInst::ICMP_ULT))) {
- Value *LHS = II->getOperand(0), *RHS = II->getOperand(1);
- return (L.match(LHS) && R.match(RHS)) ||
- (Commutable && L.match(RHS) && R.match(LHS));
- }
- }
+ if (auto *II = dyn_cast<IntrinsicInst>(V)) {
+ Intrinsic::ID IID = II->getIntrinsicID();
+ if ((IID == Intrinsic::smax && Pred_t::match(ICmpInst::ICMP_SGT)) ||
+ (IID == Intrinsic::smin && Pred_t::match(ICmpInst::ICMP_SLT)) ||
+ (IID == Intrinsic::umax && Pred_t::match(ICmpInst::ICMP_UGT)) ||
+ (IID == Intrinsic::umin && Pred_t::match(ICmpInst::ICMP_ULT))) {
+ Value *LHS = II->getOperand(0), *RHS = II->getOperand(1);
+ return (L.match(LHS) && R.match(RHS)) ||
+ (Commutable && L.match(RHS) && R.match(LHS));
+ }
+ }
// Look for "(x pred y) ? x : y" or "(x pred y) ? y : x".
auto *SI = dyn_cast<SelectInst>(V);
if (!SI)
@@ -1836,17 +1836,17 @@ inline MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty> m_UMin(const LHS &L,
return MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty>(L, R);
}
-template <typename LHS, typename RHS>
-inline match_combine_or<
- match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty>,
- MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty>>,
- match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty>,
- MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty>>>
-m_MaxOrMin(const LHS &L, const RHS &R) {
- return m_CombineOr(m_CombineOr(m_SMax(L, R), m_SMin(L, R)),
- m_CombineOr(m_UMax(L, R), m_UMin(L, R)));
-}
-
+template <typename LHS, typename RHS>
+inline match_combine_or<
+ match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty>,
+ MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty>>,
+ match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty>,
+ MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty>>>
+m_MaxOrMin(const LHS &L, const RHS &R) {
+ return m_CombineOr(m_CombineOr(m_SMax(L, R), m_SMin(L, R)),
+ m_CombineOr(m_UMax(L, R), m_UMin(L, R)));
+}
+
/// Match an 'ordered' floating point maximum function.
/// Floating point has one special value 'NaN'. Therefore, there is no total
/// order. However, if we can ignore the 'NaN' value (for example, because of a
@@ -2137,18 +2137,18 @@ inline typename m_Intrinsic_Ty<Opnd0, Opnd1>::Ty m_FMax(const Opnd0 &Op0,
return m_Intrinsic<Intrinsic::maxnum>(Op0, Op1);
}
-template <typename Opnd0, typename Opnd1, typename Opnd2>
-inline typename m_Intrinsic_Ty<Opnd0, Opnd1, Opnd2>::Ty
-m_FShl(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2) {
- return m_Intrinsic<Intrinsic::fshl>(Op0, Op1, Op2);
-}
-
-template <typename Opnd0, typename Opnd1, typename Opnd2>
-inline typename m_Intrinsic_Ty<Opnd0, Opnd1, Opnd2>::Ty
-m_FShr(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2) {
- return m_Intrinsic<Intrinsic::fshr>(Op0, Op1, Op2);
-}
-
+template <typename Opnd0, typename Opnd1, typename Opnd2>
+inline typename m_Intrinsic_Ty<Opnd0, Opnd1, Opnd2>::Ty
+m_FShl(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2) {
+ return m_Intrinsic<Intrinsic::fshl>(Op0, Op1, Op2);
+}
+
+template <typename Opnd0, typename Opnd1, typename Opnd2>
+inline typename m_Intrinsic_Ty<Opnd0, Opnd1, Opnd2>::Ty
+m_FShr(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2) {
+ return m_Intrinsic<Intrinsic::fshr>(Op0, Op1, Op2);
+}
+
//===----------------------------------------------------------------------===//
// Matchers for two-operands operators with the operators in either order
//
@@ -2210,15 +2210,15 @@ m_Neg(const ValTy &V) {
return m_Sub(m_ZeroInt(), V);
}
-/// Matches a 'Neg' as 'sub nsw 0, V'.
-template <typename ValTy>
-inline OverflowingBinaryOp_match<cst_pred_ty<is_zero_int>, ValTy,
- Instruction::Sub,
- OverflowingBinaryOperator::NoSignedWrap>
-m_NSWNeg(const ValTy &V) {
- return m_NSWSub(m_ZeroInt(), V);
-}
-
+/// Matches a 'Neg' as 'sub nsw 0, V'.
+template <typename ValTy>
+inline OverflowingBinaryOp_match<cst_pred_ty<is_zero_int>, ValTy,
+ Instruction::Sub,
+ OverflowingBinaryOperator::NoSignedWrap>
+m_NSWNeg(const ValTy &V) {
+ return m_NSWSub(m_ZeroInt(), V);
+}
+
/// Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
template <typename ValTy>
inline BinaryOp_match<ValTy, cst_pred_ty<is_all_ones>, Instruction::Xor, true>
@@ -2251,17 +2251,17 @@ m_c_UMax(const LHS &L, const RHS &R) {
return MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty, true>(L, R);
}
-template <typename LHS, typename RHS>
-inline match_combine_or<
- match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty, true>,
- MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty, true>>,
- match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty, true>,
- MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty, true>>>
-m_c_MaxOrMin(const LHS &L, const RHS &R) {
- return m_CombineOr(m_CombineOr(m_c_SMax(L, R), m_c_SMin(L, R)),
- m_CombineOr(m_c_UMax(L, R), m_c_UMin(L, R)));
-}
-
+template <typename LHS, typename RHS>
+inline match_combine_or<
+ match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty, true>,
+ MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty, true>>,
+ match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty, true>,
+ MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty, true>>>
+m_c_MaxOrMin(const LHS &L, const RHS &R) {
+ return m_CombineOr(m_CombineOr(m_c_SMax(L, R), m_c_SMin(L, R)),
+ m_CombineOr(m_c_UMax(L, R), m_c_UMin(L, R)));
+}
+
/// Matches FAdd with LHS and RHS in either order.
template <typename LHS, typename RHS>
inline BinaryOp_match<LHS, RHS, Instruction::FAdd, true>
@@ -2335,29 +2335,29 @@ inline ExtractValue_match<Ind, Val_t> m_ExtractValue(const Val_t &V) {
return ExtractValue_match<Ind, Val_t>(V);
}
-/// Matcher for a single index InsertValue instruction.
-template <int Ind, typename T0, typename T1> struct InsertValue_match {
- T0 Op0;
- T1 Op1;
-
- InsertValue_match(const T0 &Op0, const T1 &Op1) : Op0(Op0), Op1(Op1) {}
-
- template <typename OpTy> bool match(OpTy *V) {
- if (auto *I = dyn_cast<InsertValueInst>(V)) {
- return Op0.match(I->getOperand(0)) && Op1.match(I->getOperand(1)) &&
- I->getNumIndices() == 1 && Ind == I->getIndices()[0];
- }
- return false;
- }
-};
-
-/// Matches a single index InsertValue instruction.
-template <int Ind, typename Val_t, typename Elt_t>
-inline InsertValue_match<Ind, Val_t, Elt_t> m_InsertValue(const Val_t &Val,
- const Elt_t &Elt) {
- return InsertValue_match<Ind, Val_t, Elt_t>(Val, Elt);
-}
-
+/// Matcher for a single index InsertValue instruction.
+template <int Ind, typename T0, typename T1> struct InsertValue_match {
+ T0 Op0;
+ T1 Op1;
+
+ InsertValue_match(const T0 &Op0, const T1 &Op1) : Op0(Op0), Op1(Op1) {}
+
+ template <typename OpTy> bool match(OpTy *V) {
+ if (auto *I = dyn_cast<InsertValueInst>(V)) {
+ return Op0.match(I->getOperand(0)) && Op1.match(I->getOperand(1)) &&
+ I->getNumIndices() == 1 && Ind == I->getIndices()[0];
+ }
+ return false;
+ }
+};
+
+/// Matches a single index InsertValue instruction.
+template <int Ind, typename Val_t, typename Elt_t>
+inline InsertValue_match<Ind, Val_t, Elt_t> m_InsertValue(const Val_t &Val,
+ const Elt_t &Elt) {
+ return InsertValue_match<Ind, Val_t, Elt_t>(Val, Elt);
+}
+
/// Matches patterns for `vscale`. This can either be a call to `llvm.vscale` or
/// the constant expression
/// `ptrtoint(gep <vscale x 1 x i8>, <vscale x 1 x i8>* null, i32 1>`
@@ -2394,58 +2394,58 @@ inline VScaleVal_match m_VScale(const DataLayout &DL) {
return VScaleVal_match(DL);
}
-template <typename LHS, typename RHS, unsigned Opcode>
-struct LogicalOp_match {
- LHS L;
- RHS R;
-
- LogicalOp_match(const LHS &L, const RHS &R) : L(L), R(R) {}
-
- template <typename T> bool match(T *V) {
- if (auto *I = dyn_cast<Instruction>(V)) {
- if (!I->getType()->isIntOrIntVectorTy(1))
- return false;
-
- if (I->getOpcode() == Opcode && L.match(I->getOperand(0)) &&
- R.match(I->getOperand(1)))
- return true;
-
- if (auto *SI = dyn_cast<SelectInst>(I)) {
- if (Opcode == Instruction::And) {
- if (const auto *C = dyn_cast<Constant>(SI->getFalseValue()))
- if (C->isNullValue() && L.match(SI->getCondition()) &&
- R.match(SI->getTrueValue()))
- return true;
- } else {
- assert(Opcode == Instruction::Or);
- if (const auto *C = dyn_cast<Constant>(SI->getTrueValue()))
- if (C->isOneValue() && L.match(SI->getCondition()) &&
- R.match(SI->getFalseValue()))
- return true;
- }
- }
- }
-
- return false;
- }
-};
-
-/// Matches L && R either in the form of L & R or L ? R : false.
-/// Note that the latter form is poison-blocking.
-template <typename LHS, typename RHS>
-inline LogicalOp_match<LHS, RHS, Instruction::And>
-m_LogicalAnd(const LHS &L, const RHS &R) {
- return LogicalOp_match<LHS, RHS, Instruction::And>(L, R);
-}
-
-/// Matches L || R either in the form of L | R or L ? true : R.
-/// Note that the latter form is poison-blocking.
-template <typename LHS, typename RHS>
-inline LogicalOp_match<LHS, RHS, Instruction::Or>
-m_LogicalOr(const LHS &L, const RHS &R) {
- return LogicalOp_match<LHS, RHS, Instruction::Or>(L, R);
-}
-
+template <typename LHS, typename RHS, unsigned Opcode>
+struct LogicalOp_match {
+ LHS L;
+ RHS R;
+
+ LogicalOp_match(const LHS &L, const RHS &R) : L(L), R(R) {}
+
+ template <typename T> bool match(T *V) {
+ if (auto *I = dyn_cast<Instruction>(V)) {
+ if (!I->getType()->isIntOrIntVectorTy(1))
+ return false;
+
+ if (I->getOpcode() == Opcode && L.match(I->getOperand(0)) &&
+ R.match(I->getOperand(1)))
+ return true;
+
+ if (auto *SI = dyn_cast<SelectInst>(I)) {
+ if (Opcode == Instruction::And) {
+ if (const auto *C = dyn_cast<Constant>(SI->getFalseValue()))
+ if (C->isNullValue() && L.match(SI->getCondition()) &&
+ R.match(SI->getTrueValue()))
+ return true;
+ } else {
+ assert(Opcode == Instruction::Or);
+ if (const auto *C = dyn_cast<Constant>(SI->getTrueValue()))
+ if (C->isOneValue() && L.match(SI->getCondition()) &&
+ R.match(SI->getFalseValue()))
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+};
+
+/// Matches L && R either in the form of L & R or L ? R : false.
+/// Note that the latter form is poison-blocking.
+template <typename LHS, typename RHS>
+inline LogicalOp_match<LHS, RHS, Instruction::And>
+m_LogicalAnd(const LHS &L, const RHS &R) {
+ return LogicalOp_match<LHS, RHS, Instruction::And>(L, R);
+}
+
+/// Matches L || R either in the form of L | R or L ? true : R.
+/// Note that the latter form is poison-blocking.
+template <typename LHS, typename RHS>
+inline LogicalOp_match<LHS, RHS, Instruction::Or>
+m_LogicalOr(const LHS &L, const RHS &R) {
+ return LogicalOp_match<LHS, RHS, Instruction::Or>(L, R);
+}
+
} // end namespace PatternMatch
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/IR/PredIteratorCache.h b/contrib/libs/llvm12/include/llvm/IR/PredIteratorCache.h
index 979911ef0c..48cd4c9baf 100644
--- a/contrib/libs/llvm12/include/llvm/IR/PredIteratorCache.h
+++ b/contrib/libs/llvm12/include/llvm/IR/PredIteratorCache.h
@@ -51,7 +51,7 @@ private:
if (Entry)
return Entry;
- SmallVector<BasicBlock *, 32> PredCache(predecessors(BB));
+ SmallVector<BasicBlock *, 32> PredCache(predecessors(BB));
PredCache.push_back(nullptr); // null terminator.
BlockToPredCountMap[BB] = PredCache.size() - 1;
@@ -65,7 +65,7 @@ private:
auto Result = BlockToPredCountMap.find(BB);
if (Result != BlockToPredCountMap.end())
return Result->second;
- return BlockToPredCountMap[BB] = pred_size(BB);
+ return BlockToPredCountMap[BB] = pred_size(BB);
}
public:
diff --git a/contrib/libs/llvm12/include/llvm/IR/PrintPasses.h b/contrib/libs/llvm12/include/llvm/IR/PrintPasses.h
index 5ca9b30e3a..4f6de26f12 100644
--- a/contrib/libs/llvm12/include/llvm/IR/PrintPasses.h
+++ b/contrib/libs/llvm12/include/llvm/IR/PrintPasses.h
@@ -1,55 +1,55 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- PrintPasses.h - Determining whether/when to print IR ---------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_IR_PRINTPASSES_H
-#define LLVM_IR_PRINTPASSES_H
-
-#include "llvm/ADT/StringRef.h"
-#include <vector>
-
-namespace llvm {
-
-// Returns true if printing before/after some pass is enabled, whether all
-// passes or a specific pass.
-bool shouldPrintBeforeSomePass();
-bool shouldPrintAfterSomePass();
-
-// Returns true if we should print before/after a specific pass. The argument
-// should be the pass ID, e.g. "instcombine".
-bool shouldPrintBeforePass(StringRef PassID);
-bool shouldPrintAfterPass(StringRef PassID);
-
-// Returns true if we should print before/after all passes.
-bool shouldPrintBeforeAll();
-bool shouldPrintAfterAll();
-
-// The list of passes to print before/after, if we only want to print
-// before/after specific passes.
-std::vector<std::string> printBeforePasses();
-std::vector<std::string> printAfterPasses();
-
-// Returns true if we should always print the entire module.
-bool forcePrintModuleIR();
-
-// Returns true if we should print the function.
-bool isFunctionInPrintList(StringRef FunctionName);
-
-} // namespace llvm
-
-#endif // LLVM_IR_PRINTPASSES_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- PrintPasses.h - Determining whether/when to print IR ---------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_PRINTPASSES_H
+#define LLVM_IR_PRINTPASSES_H
+
+#include "llvm/ADT/StringRef.h"
+#include <vector>
+
+namespace llvm {
+
+// Returns true if printing before/after some pass is enabled, whether all
+// passes or a specific pass.
+bool shouldPrintBeforeSomePass();
+bool shouldPrintAfterSomePass();
+
+// Returns true if we should print before/after a specific pass. The argument
+// should be the pass ID, e.g. "instcombine".
+bool shouldPrintBeforePass(StringRef PassID);
+bool shouldPrintAfterPass(StringRef PassID);
+
+// Returns true if we should print before/after all passes.
+bool shouldPrintBeforeAll();
+bool shouldPrintAfterAll();
+
+// The list of passes to print before/after, if we only want to print
+// before/after specific passes.
+std::vector<std::string> printBeforePasses();
+std::vector<std::string> printAfterPasses();
+
+// Returns true if we should always print the entire module.
+bool forcePrintModuleIR();
+
+// Returns true if we should print the function.
+bool isFunctionInPrintList(StringRef FunctionName);
+
+} // namespace llvm
+
+#endif // LLVM_IR_PRINTPASSES_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/IR/PseudoProbe.h b/contrib/libs/llvm12/include/llvm/IR/PseudoProbe.h
index 56766cafc3..9126012da1 100644
--- a/contrib/libs/llvm12/include/llvm/IR/PseudoProbe.h
+++ b/contrib/libs/llvm12/include/llvm/IR/PseudoProbe.h
@@ -1,98 +1,98 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- PseudoProbe.h - Pseudo Probe IR Helpers ------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Pseudo probe IR intrinsic and dwarf discriminator manipulation routines.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_IR_PSEUDOPROBE_H
-#define LLVM_IR_PSEUDOPROBE_H
-
-#include "llvm/ADT/Optional.h"
-#include <cassert>
-#include <cstdint>
-#include <limits>
-
-namespace llvm {
-
-class Instruction;
-class BasicBlock;
-
-constexpr const char *PseudoProbeDescMetadataName = "llvm.pseudo_probe_desc";
-
-enum class PseudoProbeType { Block = 0, IndirectCall, DirectCall };
-
-// The saturated distrution factor representing 100% for block probes.
-constexpr static uint64_t PseudoProbeFullDistributionFactor =
- std::numeric_limits<uint64_t>::max();
-
-struct PseudoProbeDwarfDiscriminator {
-public:
- // The following APIs encodes/decodes per-probe information to/from a
- // 32-bit integer which is organized as:
- // [2:0] - 0x7, this is reserved for regular discriminator,
- // see DWARF discriminator encoding rule
- // [18:3] - probe id
- // [25:19] - probe distribution factor
- // [28:26] - probe type, see PseudoProbeType
- // [31:29] - reserved for probe attributes
- static uint32_t packProbeData(uint32_t Index, uint32_t Type, uint32_t Flags,
- uint32_t Factor) {
- assert(Index <= 0xFFFF && "Probe index too big to encode, exceeding 2^16");
- assert(Type <= 0x7 && "Probe type too big to encode, exceeding 7");
- assert(Flags <= 0x7);
- assert(Factor <= 100 &&
- "Probe distribution factor too big to encode, exceeding 100");
- return (Index << 3) | (Factor << 19) | (Type << 26) | 0x7;
- }
-
- static uint32_t extractProbeIndex(uint32_t Value) {
- return (Value >> 3) & 0xFFFF;
- }
-
- static uint32_t extractProbeType(uint32_t Value) {
- return (Value >> 26) & 0x7;
- }
-
- static uint32_t extractProbeAttributes(uint32_t Value) {
- return (Value >> 29) & 0x7;
- }
-
- static uint32_t extractProbeFactor(uint32_t Value) {
- return (Value >> 19) & 0x7F;
- }
-
- // The saturated distrution factor representing 100% for callsites.
- constexpr static uint8_t FullDistributionFactor = 100;
-};
-
-struct PseudoProbe {
- uint32_t Id;
- uint32_t Type;
- uint32_t Attr;
- float Factor;
-};
-
-Optional<PseudoProbe> extractProbe(const Instruction &Inst);
-
-void setProbeDistributionFactor(Instruction &Inst, float Factor);
-
-} // end namespace llvm
-
-#endif // LLVM_IR_PSEUDOPROBE_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- PseudoProbe.h - Pseudo Probe IR Helpers ------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Pseudo probe IR intrinsic and dwarf discriminator manipulation routines.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_PSEUDOPROBE_H
+#define LLVM_IR_PSEUDOPROBE_H
+
+#include "llvm/ADT/Optional.h"
+#include <cassert>
+#include <cstdint>
+#include <limits>
+
+namespace llvm {
+
+class Instruction;
+class BasicBlock;
+
+constexpr const char *PseudoProbeDescMetadataName = "llvm.pseudo_probe_desc";
+
+enum class PseudoProbeType { Block = 0, IndirectCall, DirectCall };
+
+// The saturated distrution factor representing 100% for block probes.
+constexpr static uint64_t PseudoProbeFullDistributionFactor =
+ std::numeric_limits<uint64_t>::max();
+
+struct PseudoProbeDwarfDiscriminator {
+public:
+ // The following APIs encodes/decodes per-probe information to/from a
+ // 32-bit integer which is organized as:
+ // [2:0] - 0x7, this is reserved for regular discriminator,
+ // see DWARF discriminator encoding rule
+ // [18:3] - probe id
+ // [25:19] - probe distribution factor
+ // [28:26] - probe type, see PseudoProbeType
+ // [31:29] - reserved for probe attributes
+ static uint32_t packProbeData(uint32_t Index, uint32_t Type, uint32_t Flags,
+ uint32_t Factor) {
+ assert(Index <= 0xFFFF && "Probe index too big to encode, exceeding 2^16");
+ assert(Type <= 0x7 && "Probe type too big to encode, exceeding 7");
+ assert(Flags <= 0x7);
+ assert(Factor <= 100 &&
+ "Probe distribution factor too big to encode, exceeding 100");
+ return (Index << 3) | (Factor << 19) | (Type << 26) | 0x7;
+ }
+
+ static uint32_t extractProbeIndex(uint32_t Value) {
+ return (Value >> 3) & 0xFFFF;
+ }
+
+ static uint32_t extractProbeType(uint32_t Value) {
+ return (Value >> 26) & 0x7;
+ }
+
+ static uint32_t extractProbeAttributes(uint32_t Value) {
+ return (Value >> 29) & 0x7;
+ }
+
+ static uint32_t extractProbeFactor(uint32_t Value) {
+ return (Value >> 19) & 0x7F;
+ }
+
+ // The saturated distrution factor representing 100% for callsites.
+ constexpr static uint8_t FullDistributionFactor = 100;
+};
+
+struct PseudoProbe {
+ uint32_t Id;
+ uint32_t Type;
+ uint32_t Attr;
+ float Factor;
+};
+
+Optional<PseudoProbe> extractProbe(const Instruction &Inst);
+
+void setProbeDistributionFactor(Instruction &Inst, float Factor);
+
+} // end namespace llvm
+
+#endif // LLVM_IR_PSEUDOPROBE_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/IR/ReplaceConstant.h b/contrib/libs/llvm12/include/llvm/IR/ReplaceConstant.h
index 2506167086..61589d58b0 100644
--- a/contrib/libs/llvm12/include/llvm/IR/ReplaceConstant.h
+++ b/contrib/libs/llvm12/include/llvm/IR/ReplaceConstant.h
@@ -1,39 +1,39 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- ReplaceConstant.h - Replacing LLVM constant expressions --*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the utility function for replacing LLVM constant
-// expressions by instructions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_IR_REPLACECONSTANT_H
-#define LLVM_IR_REPLACECONSTANT_H
-
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/Instruction.h"
-
-namespace llvm {
-
-/// Create a replacement instruction for constant expression \p CE and insert
-/// it before \p Instr.
-Instruction *createReplacementInstr(ConstantExpr *CE, Instruction *Instr);
-
-} // end namespace llvm
-
-#endif // LLVM_IR_REPLACECONSTANT_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- ReplaceConstant.h - Replacing LLVM constant expressions --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the utility function for replacing LLVM constant
+// expressions by instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_REPLACECONSTANT_H
+#define LLVM_IR_REPLACECONSTANT_H
+
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instruction.h"
+
+namespace llvm {
+
+/// Create a replacement instruction for constant expression \p CE and insert
+/// it before \p Instr.
+Instruction *createReplacementInstr(ConstantExpr *CE, Instruction *Instr);
+
+} // end namespace llvm
+
+#endif // LLVM_IR_REPLACECONSTANT_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/IR/RuntimeLibcalls.def b/contrib/libs/llvm12/include/llvm/IR/RuntimeLibcalls.def
index 55d693d7a4..c73172612b 100644
--- a/contrib/libs/llvm12/include/llvm/IR/RuntimeLibcalls.def
+++ b/contrib/libs/llvm12/include/llvm/IR/RuntimeLibcalls.def
@@ -286,9 +286,9 @@ HANDLE_LIBCALL(FPEXT_F64_PPCF128, "__gcc_dtoq")
HANDLE_LIBCALL(FPEXT_F80_F128, "__extendxftf2")
HANDLE_LIBCALL(FPEXT_F64_F128, "__extenddftf2")
HANDLE_LIBCALL(FPEXT_F32_F128, "__extendsftf2")
-HANDLE_LIBCALL(FPEXT_F16_F128, "__extendhftf2")
+HANDLE_LIBCALL(FPEXT_F16_F128, "__extendhftf2")
HANDLE_LIBCALL(FPEXT_F32_F64, "__extendsfdf2")
-HANDLE_LIBCALL(FPEXT_F16_F64, "__extendhfdf2")
+HANDLE_LIBCALL(FPEXT_F16_F64, "__extendhfdf2")
HANDLE_LIBCALL(FPEXT_F16_F32, "__gnu_h2f_ieee")
HANDLE_LIBCALL(FPROUND_F32_F16, "__gnu_f2h_ieee")
HANDLE_LIBCALL(FPROUND_F64_F16, "__truncdfhf2")
@@ -303,9 +303,9 @@ HANDLE_LIBCALL(FPROUND_F80_F64, "__truncxfdf2")
HANDLE_LIBCALL(FPROUND_F128_F64, "__trunctfdf2")
HANDLE_LIBCALL(FPROUND_PPCF128_F64, "__gcc_qtod")
HANDLE_LIBCALL(FPROUND_F128_F80, "__trunctfxf2")
-HANDLE_LIBCALL(FPTOSINT_F16_I32, "__fixhfsi")
-HANDLE_LIBCALL(FPTOSINT_F16_I64, "__fixhfdi")
-HANDLE_LIBCALL(FPTOSINT_F16_I128, "__fixhfti")
+HANDLE_LIBCALL(FPTOSINT_F16_I32, "__fixhfsi")
+HANDLE_LIBCALL(FPTOSINT_F16_I64, "__fixhfdi")
+HANDLE_LIBCALL(FPTOSINT_F16_I128, "__fixhfti")
HANDLE_LIBCALL(FPTOSINT_F32_I32, "__fixsfsi")
HANDLE_LIBCALL(FPTOSINT_F32_I64, "__fixsfdi")
HANDLE_LIBCALL(FPTOSINT_F32_I128, "__fixsfti")
@@ -321,9 +321,9 @@ HANDLE_LIBCALL(FPTOSINT_F128_I128, "__fixtfti")
HANDLE_LIBCALL(FPTOSINT_PPCF128_I32, "__gcc_qtou")
HANDLE_LIBCALL(FPTOSINT_PPCF128_I64, "__fixtfdi")
HANDLE_LIBCALL(FPTOSINT_PPCF128_I128, "__fixtfti")
-HANDLE_LIBCALL(FPTOUINT_F16_I32, "__fixunshfsi")
-HANDLE_LIBCALL(FPTOUINT_F16_I64, "__fixunshfdi")
-HANDLE_LIBCALL(FPTOUINT_F16_I128, "__fixunshfti")
+HANDLE_LIBCALL(FPTOUINT_F16_I32, "__fixunshfsi")
+HANDLE_LIBCALL(FPTOUINT_F16_I64, "__fixunshfdi")
+HANDLE_LIBCALL(FPTOUINT_F16_I128, "__fixunshfti")
HANDLE_LIBCALL(FPTOUINT_F32_I32, "__fixunssfsi")
HANDLE_LIBCALL(FPTOUINT_F32_I64, "__fixunssfdi")
HANDLE_LIBCALL(FPTOUINT_F32_I128, "__fixunssfti")
@@ -339,37 +339,37 @@ HANDLE_LIBCALL(FPTOUINT_F128_I128, "__fixunstfti")
HANDLE_LIBCALL(FPTOUINT_PPCF128_I32, "__fixunstfsi")
HANDLE_LIBCALL(FPTOUINT_PPCF128_I64, "__fixunstfdi")
HANDLE_LIBCALL(FPTOUINT_PPCF128_I128, "__fixunstfti")
-HANDLE_LIBCALL(SINTTOFP_I32_F16, "__floatsihf")
+HANDLE_LIBCALL(SINTTOFP_I32_F16, "__floatsihf")
HANDLE_LIBCALL(SINTTOFP_I32_F32, "__floatsisf")
HANDLE_LIBCALL(SINTTOFP_I32_F64, "__floatsidf")
HANDLE_LIBCALL(SINTTOFP_I32_F80, "__floatsixf")
HANDLE_LIBCALL(SINTTOFP_I32_F128, "__floatsitf")
HANDLE_LIBCALL(SINTTOFP_I32_PPCF128, "__gcc_itoq")
-HANDLE_LIBCALL(SINTTOFP_I64_F16, "__floatdihf")
+HANDLE_LIBCALL(SINTTOFP_I64_F16, "__floatdihf")
HANDLE_LIBCALL(SINTTOFP_I64_F32, "__floatdisf")
HANDLE_LIBCALL(SINTTOFP_I64_F64, "__floatdidf")
HANDLE_LIBCALL(SINTTOFP_I64_F80, "__floatdixf")
HANDLE_LIBCALL(SINTTOFP_I64_F128, "__floatditf")
HANDLE_LIBCALL(SINTTOFP_I64_PPCF128, "__floatditf")
-HANDLE_LIBCALL(SINTTOFP_I128_F16, "__floattihf")
+HANDLE_LIBCALL(SINTTOFP_I128_F16, "__floattihf")
HANDLE_LIBCALL(SINTTOFP_I128_F32, "__floattisf")
HANDLE_LIBCALL(SINTTOFP_I128_F64, "__floattidf")
HANDLE_LIBCALL(SINTTOFP_I128_F80, "__floattixf")
HANDLE_LIBCALL(SINTTOFP_I128_F128, "__floattitf")
HANDLE_LIBCALL(SINTTOFP_I128_PPCF128, "__floattitf")
-HANDLE_LIBCALL(UINTTOFP_I32_F16, "__floatunsihf")
+HANDLE_LIBCALL(UINTTOFP_I32_F16, "__floatunsihf")
HANDLE_LIBCALL(UINTTOFP_I32_F32, "__floatunsisf")
HANDLE_LIBCALL(UINTTOFP_I32_F64, "__floatunsidf")
HANDLE_LIBCALL(UINTTOFP_I32_F80, "__floatunsixf")
HANDLE_LIBCALL(UINTTOFP_I32_F128, "__floatunsitf")
HANDLE_LIBCALL(UINTTOFP_I32_PPCF128, "__gcc_utoq")
-HANDLE_LIBCALL(UINTTOFP_I64_F16, "__floatundihf")
+HANDLE_LIBCALL(UINTTOFP_I64_F16, "__floatundihf")
HANDLE_LIBCALL(UINTTOFP_I64_F32, "__floatundisf")
HANDLE_LIBCALL(UINTTOFP_I64_F64, "__floatundidf")
HANDLE_LIBCALL(UINTTOFP_I64_F80, "__floatundixf")
HANDLE_LIBCALL(UINTTOFP_I64_F128, "__floatunditf")
HANDLE_LIBCALL(UINTTOFP_I64_PPCF128, "__floatunditf")
-HANDLE_LIBCALL(UINTTOFP_I128_F16, "__floatuntihf")
+HANDLE_LIBCALL(UINTTOFP_I128_F16, "__floatuntihf")
HANDLE_LIBCALL(UINTTOFP_I128_F32, "__floatuntisf")
HANDLE_LIBCALL(UINTTOFP_I128_F64, "__floatuntidf")
HANDLE_LIBCALL(UINTTOFP_I128_F80, "__floatuntixf")
@@ -558,23 +558,23 @@ HANDLE_LIBCALL(ATOMIC_FETCH_NAND_4, "__atomic_fetch_nand_4")
HANDLE_LIBCALL(ATOMIC_FETCH_NAND_8, "__atomic_fetch_nand_8")
HANDLE_LIBCALL(ATOMIC_FETCH_NAND_16, "__atomic_fetch_nand_16")
-// Out-of-line atomics libcalls
-#define HLCALLS(A, N) \
- HANDLE_LIBCALL(A##N##_RELAX, nullptr) \
- HANDLE_LIBCALL(A##N##_ACQ, nullptr) \
- HANDLE_LIBCALL(A##N##_REL, nullptr) \
- HANDLE_LIBCALL(A##N##_ACQ_REL, nullptr)
-#define HLCALL5(A) \
- HLCALLS(A, 1) HLCALLS(A, 2) HLCALLS(A, 4) HLCALLS(A, 8) HLCALLS(A, 16)
-HLCALL5(OUTLINE_ATOMIC_CAS)
-HLCALL5(OUTLINE_ATOMIC_SWP)
-HLCALL5(OUTLINE_ATOMIC_LDADD)
-HLCALL5(OUTLINE_ATOMIC_LDSET)
-HLCALL5(OUTLINE_ATOMIC_LDCLR)
-HLCALL5(OUTLINE_ATOMIC_LDEOR)
-#undef HLCALLS
-#undef HLCALL5
-
+// Out-of-line atomics libcalls
+#define HLCALLS(A, N) \
+ HANDLE_LIBCALL(A##N##_RELAX, nullptr) \
+ HANDLE_LIBCALL(A##N##_ACQ, nullptr) \
+ HANDLE_LIBCALL(A##N##_REL, nullptr) \
+ HANDLE_LIBCALL(A##N##_ACQ_REL, nullptr)
+#define HLCALL5(A) \
+ HLCALLS(A, 1) HLCALLS(A, 2) HLCALLS(A, 4) HLCALLS(A, 8) HLCALLS(A, 16)
+HLCALL5(OUTLINE_ATOMIC_CAS)
+HLCALL5(OUTLINE_ATOMIC_SWP)
+HLCALL5(OUTLINE_ATOMIC_LDADD)
+HLCALL5(OUTLINE_ATOMIC_LDSET)
+HLCALL5(OUTLINE_ATOMIC_LDCLR)
+HLCALL5(OUTLINE_ATOMIC_LDEOR)
+#undef HLCALLS
+#undef HLCALL5
+
// Stack Protector Fail
HANDLE_LIBCALL(STACKPROTECTOR_CHECK_FAIL, "__stack_chk_fail")
diff --git a/contrib/libs/llvm12/include/llvm/IR/Statepoint.h b/contrib/libs/llvm12/include/llvm/IR/Statepoint.h
index 8ab9b759da..7678498cbd 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Statepoint.h
+++ b/contrib/libs/llvm12/include/llvm/IR/Statepoint.h
@@ -143,7 +143,7 @@ public:
/// Return an end iterator of the arguments to the underlying call
const_op_iterator actual_arg_end() const {
auto I = actual_arg_begin() + actual_arg_size();
- assert((arg_end() - I) == 2);
+ assert((arg_end() - I) == 2);
return I;
}
/// range adapter for actual call arguments
@@ -154,12 +154,12 @@ public:
const_op_iterator gc_transition_args_begin() const {
if (auto Opt = getOperandBundle(LLVMContext::OB_gc_transition))
return Opt->Inputs.begin();
- return arg_end();
+ return arg_end();
}
const_op_iterator gc_transition_args_end() const {
if (auto Opt = getOperandBundle(LLVMContext::OB_gc_transition))
return Opt->Inputs.end();
- return arg_end();
+ return arg_end();
}
/// range adapter for GC transition arguments
@@ -170,12 +170,12 @@ public:
const_op_iterator deopt_begin() const {
if (auto Opt = getOperandBundle(LLVMContext::OB_deopt))
return Opt->Inputs.begin();
- return arg_end();
+ return arg_end();
}
const_op_iterator deopt_end() const {
if (auto Opt = getOperandBundle(LLVMContext::OB_deopt))
return Opt->Inputs.end();
- return arg_end();
+ return arg_end();
}
/// range adapter for vm state arguments
@@ -188,7 +188,7 @@ public:
const_op_iterator gc_args_begin() const {
if (auto Opt = getOperandBundle(LLVMContext::OB_gc_live))
return Opt->Inputs.begin();
- return arg_end();
+ return arg_end();
}
/// Return an end iterator for the gc argument range
diff --git a/contrib/libs/llvm12/include/llvm/IR/StructuralHash.h b/contrib/libs/llvm12/include/llvm/IR/StructuralHash.h
index 2acde90b6d..0d419d1886 100644
--- a/contrib/libs/llvm12/include/llvm/IR/StructuralHash.h
+++ b/contrib/libs/llvm12/include/llvm/IR/StructuralHash.h
@@ -1,45 +1,45 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- llvm/IR/StructuralHash.h - IR Hash for expensive checks --*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides hashing of the LLVM IR structure to be used to check
-// Passes modification status.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_IR_STRUCTURALHASH_H
-#define LLVM_IR_STRUCTURALHASH_H
-
-#ifdef EXPENSIVE_CHECKS
-
-#include <cstdint>
-
-// This header is only meant to be used when -DEXPENSIVE_CHECKS is set
-namespace llvm {
-
-class Function;
-class Module;
-
-uint64_t StructuralHash(const Function &F);
-uint64_t StructuralHash(const Module &M);
-
-} // end namespace llvm
-
-#endif
-
-#endif // LLVM_IR_STRUCTURALHASH_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- llvm/IR/StructuralHash.h - IR Hash for expensive checks --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides hashing of the LLVM IR structure to be used to check
+// Passes modification status.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_STRUCTURALHASH_H
+#define LLVM_IR_STRUCTURALHASH_H
+
+#ifdef EXPENSIVE_CHECKS
+
+#include <cstdint>
+
+// This header is only meant to be used when -DEXPENSIVE_CHECKS is set
+namespace llvm {
+
+class Function;
+class Module;
+
+uint64_t StructuralHash(const Function &F);
+uint64_t StructuralHash(const Module &M);
+
+} // end namespace llvm
+
+#endif
+
+#endif // LLVM_IR_STRUCTURALHASH_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/IR/SymbolTableListTraits.h b/contrib/libs/llvm12/include/llvm/IR/SymbolTableListTraits.h
index 5101c88a4b..afaa099c55 100644
--- a/contrib/libs/llvm12/include/llvm/IR/SymbolTableListTraits.h
+++ b/contrib/libs/llvm12/include/llvm/IR/SymbolTableListTraits.h
@@ -83,11 +83,11 @@ private:
/// getListOwner - Return the object that owns this list. If this is a list
/// of instructions, it returns the BasicBlock that owns them.
ItemParentClass *getListOwner() {
- size_t Offset = reinterpret_cast<size_t>(
- &((ItemParentClass *)nullptr->*ItemParentClass::getSublistAccess(
- static_cast<ValueSubClass *>(
- nullptr))));
- ListTy *Anchor = static_cast<ListTy *>(this);
+ size_t Offset = reinterpret_cast<size_t>(
+ &((ItemParentClass *)nullptr->*ItemParentClass::getSublistAccess(
+ static_cast<ValueSubClass *>(
+ nullptr))));
+ ListTy *Anchor = static_cast<ListTy *>(this);
return reinterpret_cast<ItemParentClass*>(reinterpret_cast<char*>(Anchor)-
Offset);
}
diff --git a/contrib/libs/llvm12/include/llvm/IR/Type.h b/contrib/libs/llvm12/include/llvm/IR/Type.h
index 58d9faf5a7..ee139e2dc2 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Type.h
+++ b/contrib/libs/llvm12/include/llvm/IR/Type.h
@@ -72,7 +72,7 @@ public:
LabelTyID, ///< Labels
MetadataTyID, ///< Metadata
X86_MMXTyID, ///< MMX vectors (64 bits, X86 specific)
- X86_AMXTyID, ///< AMX vectors (8192 bits, X86 specific)
+ X86_AMXTyID, ///< AMX vectors (8192 bits, X86 specific)
TokenTyID, ///< Tokens
// Derived types... see DerivedTypes.h file.
@@ -190,9 +190,9 @@ public:
/// Return true if this is X86 MMX.
bool isX86_MMXTy() const { return getTypeID() == X86_MMXTyID; }
- /// Return true if this is X86 AMX.
- bool isX86_AMXTy() const { return getTypeID() == X86_AMXTyID; }
-
+ /// Return true if this is X86 AMX.
+ bool isX86_AMXTy() const { return getTypeID() == X86_AMXTyID; }
+
/// Return true if this is a FP type or a vector of FP.
bool isFPOrFPVectorTy() const { return getScalarType()->isFloatingPointTy(); }
@@ -263,7 +263,7 @@ public:
/// includes all first-class types except struct and array types.
bool isSingleValueType() const {
return isFloatingPointTy() || isX86_MMXTy() || isIntegerTy() ||
- isPointerTy() || isVectorTy() || isX86_AMXTy();
+ isPointerTy() || isVectorTy() || isX86_AMXTy();
}
/// Return true if the type is an aggregate type. This means it is valid as
@@ -279,8 +279,8 @@ public:
bool isSized(SmallPtrSetImpl<Type*> *Visited = nullptr) const {
// If it's a primitive, it is always sized.
if (getTypeID() == IntegerTyID || isFloatingPointTy() ||
- getTypeID() == PointerTyID || getTypeID() == X86_MMXTyID ||
- getTypeID() == X86_AMXTyID)
+ getTypeID() == PointerTyID || getTypeID() == X86_MMXTyID ||
+ getTypeID() == X86_AMXTyID)
return true;
// If it is not something that can have a size (e.g. a function or label),
// it doesn't have a size.
@@ -416,7 +416,7 @@ public:
static Type *getFP128Ty(LLVMContext &C);
static Type *getPPC_FP128Ty(LLVMContext &C);
static Type *getX86_MMXTy(LLVMContext &C);
- static Type *getX86_AMXTy(LLVMContext &C);
+ static Type *getX86_AMXTy(LLVMContext &C);
static Type *getTokenTy(LLVMContext &C);
static IntegerType *getIntNTy(LLVMContext &C, unsigned N);
static IntegerType *getInt1Ty(LLVMContext &C);
@@ -439,26 +439,26 @@ public:
}
llvm_unreachable("Unsupported type in Type::getScalarTy");
}
- static Type *getFloatingPointTy(LLVMContext &C, const fltSemantics &S) {
- Type *Ty;
- if (&S == &APFloat::IEEEhalf())
- Ty = Type::getHalfTy(C);
- else if (&S == &APFloat::BFloat())
- Ty = Type::getBFloatTy(C);
- else if (&S == &APFloat::IEEEsingle())
- Ty = Type::getFloatTy(C);
- else if (&S == &APFloat::IEEEdouble())
- Ty = Type::getDoubleTy(C);
- else if (&S == &APFloat::x87DoubleExtended())
- Ty = Type::getX86_FP80Ty(C);
- else if (&S == &APFloat::IEEEquad())
- Ty = Type::getFP128Ty(C);
- else {
- assert(&S == &APFloat::PPCDoubleDouble() && "Unknown FP format");
- Ty = Type::getPPC_FP128Ty(C);
- }
- return Ty;
- }
+ static Type *getFloatingPointTy(LLVMContext &C, const fltSemantics &S) {
+ Type *Ty;
+ if (&S == &APFloat::IEEEhalf())
+ Ty = Type::getHalfTy(C);
+ else if (&S == &APFloat::BFloat())
+ Ty = Type::getBFloatTy(C);
+ else if (&S == &APFloat::IEEEsingle())
+ Ty = Type::getFloatTy(C);
+ else if (&S == &APFloat::IEEEdouble())
+ Ty = Type::getDoubleTy(C);
+ else if (&S == &APFloat::x87DoubleExtended())
+ Ty = Type::getX86_FP80Ty(C);
+ else if (&S == &APFloat::IEEEquad())
+ Ty = Type::getFP128Ty(C);
+ else {
+ assert(&S == &APFloat::PPCDoubleDouble() && "Unknown FP format");
+ Ty = Type::getPPC_FP128Ty(C);
+ }
+ return Ty;
+ }
//===--------------------------------------------------------------------===//
// Convenience methods for getting pointer types with one of the above builtin
@@ -472,7 +472,7 @@ public:
static PointerType *getFP128PtrTy(LLVMContext &C, unsigned AS = 0);
static PointerType *getPPC_FP128PtrTy(LLVMContext &C, unsigned AS = 0);
static PointerType *getX86_MMXPtrTy(LLVMContext &C, unsigned AS = 0);
- static PointerType *getX86_AMXPtrTy(LLVMContext &C, unsigned AS = 0);
+ static PointerType *getX86_AMXPtrTy(LLVMContext &C, unsigned AS = 0);
static PointerType *getIntNPtrTy(LLVMContext &C, unsigned N, unsigned AS = 0);
static PointerType *getInt1PtrTy(LLVMContext &C, unsigned AS = 0);
static PointerType *getInt8PtrTy(LLVMContext &C, unsigned AS = 0);
diff --git a/contrib/libs/llvm12/include/llvm/IR/User.h b/contrib/libs/llvm12/include/llvm/IR/User.h
index d2be19e8a9..3b5eae999e 100644
--- a/contrib/libs/llvm12/include/llvm/IR/User.h
+++ b/contrib/libs/llvm12/include/llvm/IR/User.h
@@ -52,7 +52,7 @@ class User : public Value {
template <unsigned>
friend struct HungoffOperandTraits;
- LLVM_ATTRIBUTE_ALWAYS_INLINE static void *
+ LLVM_ATTRIBUTE_ALWAYS_INLINE static void *
allocateFixedOperandUser(size_t, unsigned, unsigned);
protected:
diff --git a/contrib/libs/llvm12/include/llvm/IR/VPIntrinsics.def b/contrib/libs/llvm12/include/llvm/IR/VPIntrinsics.def
index d269fff4bf..981548c6dd 100644
--- a/contrib/libs/llvm12/include/llvm/IR/VPIntrinsics.def
+++ b/contrib/libs/llvm12/include/llvm/IR/VPIntrinsics.def
@@ -17,140 +17,140 @@
// Provide definitions of macros so that users of this file do not have to
// define everything to use it...
//
-// Register a VP intrinsic and begin its property scope.
-// All VP intrinsic scopes are top level, ie it is illegal to place a
-// BEGIN_REGISTER_VP_INTRINSIC within a VP intrinsic scope.
-// \p VPID The VP intrinsic id.
-// \p MASKPOS The mask operand position.
-// \p EVLPOS The explicit vector length operand position.
-#ifndef BEGIN_REGISTER_VP_INTRINSIC
-#define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, EVLPOS)
+// Register a VP intrinsic and begin its property scope.
+// All VP intrinsic scopes are top level, ie it is illegal to place a
+// BEGIN_REGISTER_VP_INTRINSIC within a VP intrinsic scope.
+// \p VPID The VP intrinsic id.
+// \p MASKPOS The mask operand position.
+// \p EVLPOS The explicit vector length operand position.
+#ifndef BEGIN_REGISTER_VP_INTRINSIC
+#define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, EVLPOS)
#endif
-// End the property scope of a VP intrinsic.
-#ifndef END_REGISTER_VP_INTRINSIC
-#define END_REGISTER_VP_INTRINSIC(VPID)
+// End the property scope of a VP intrinsic.
+#ifndef END_REGISTER_VP_INTRINSIC
+#define END_REGISTER_VP_INTRINSIC(VPID)
#endif
-// Register a new VP SDNode and begin its property scope.
-// When the SDNode scope is nested within a VP intrinsic scope, it is implicitly registered as the canonical SDNode for this VP intrinsic.
-// There is one VP intrinsic that maps directly to one SDNode that goes by the
-// same name. Since the operands are also the same, we open the property
-// scopes for both the VPIntrinsic and the SDNode at once.
-// \p SDOPC The SelectionDAG Node id (eg VP_ADD).
-// \p LEGALPOS The operand position of the SDNode that is used for legalizing
-// this SDNode. This can be `-1`, in which case the return type of
-// the SDNode is used.
-// \p TDNAME The name of the TableGen definition of this SDNode.
-// \p MASKPOS The mask operand position.
-// \p EVLPOS The explicit vector length operand position.
-#ifndef BEGIN_REGISTER_VP_SDNODE
-#define BEGIN_REGISTER_VP_SDNODE(SDOPC, LEGALPOS, TDNAME, MASKPOS, EVLPOS)
-#endif
-
-// End the property scope of a new VP SDNode.
-#ifndef END_REGISTER_VP_SDNODE
-#define END_REGISTER_VP_SDNODE(SDOPC)
-#endif
-
-// Helper macros for the common "1:1 - Intrinsic : SDNode" case.
-//
-// There is one VP intrinsic that maps directly to one SDNode that goes by the
-// same name. Since the operands are also the same, we open the property
-// scopes for both the VPIntrinsic and the SDNode at once.
-//
-// \p INTRIN The canonical name (eg `vp_add`, which at the same time is the
-// name of the intrinsic and the TableGen def of the SDNode).
-// \p MASKPOS The mask operand position.
-// \p EVLPOS The explicit vector length operand position.
-// \p SDOPC The SelectionDAG Node id (eg VP_ADD).
-// \p LEGALPOS The operand position of the SDNode that is used for legalizing
-// this SDNode. This can be `-1`, in which case the return type of
-// the SDNode is used.
-#define BEGIN_REGISTER_VP(INTRIN, MASKPOS, EVLPOS, SDOPC, LEGALPOS) \
-BEGIN_REGISTER_VP_INTRINSIC(INTRIN, MASKPOS, EVLPOS) \
-BEGIN_REGISTER_VP_SDNODE(SDOPC, LEGALPOS, INTRIN, MASKPOS, EVLPOS)
-
-#define END_REGISTER_VP(INTRIN, SDOPC) \
-END_REGISTER_VP_INTRINSIC(INTRIN) \
-END_REGISTER_VP_SDNODE(SDOPC)
-
-
-// The following macros attach properties to the scope they are placed in. This
-// assigns the property to the VP Intrinsic and/or SDNode that belongs to the
-// scope.
-//
-// Property Macros {
-
-// The intrinsic and/or SDNode has the same function as this LLVM IR Opcode.
-// \p OPC The standard IR opcode.
-#ifndef HANDLE_VP_TO_OPC
-#define HANDLE_VP_TO_OPC(OPC)
-#endif
-
-/// } Property Macros
-
-///// Integer Arithmetic {
-
-// Specialized helper macro for integer binary operators (%x, %y, %mask, %evl).
-#ifdef HELPER_REGISTER_BINARY_INT_VP
-#error "The internal helper macro HELPER_REGISTER_BINARY_INT_VP is already defined!"
-#endif
-#define HELPER_REGISTER_BINARY_INT_VP(INTRIN, SDOPC, OPC) \
-BEGIN_REGISTER_VP(INTRIN, 2, 3, SDOPC, -1) \
-HANDLE_VP_TO_OPC(OPC) \
-END_REGISTER_VP(INTRIN, SDOPC)
-
-
-
+// Register a new VP SDNode and begin its property scope.
+// When the SDNode scope is nested within a VP intrinsic scope, it is implicitly registered as the canonical SDNode for this VP intrinsic.
+// There is one VP intrinsic that maps directly to one SDNode that goes by the
+// same name. Since the operands are also the same, we open the property
+// scopes for both the VPIntrinsic and the SDNode at once.
+// \p SDOPC The SelectionDAG Node id (eg VP_ADD).
+// \p LEGALPOS The operand position of the SDNode that is used for legalizing
+// this SDNode. This can be `-1`, in which case the return type of
+// the SDNode is used.
+// \p TDNAME The name of the TableGen definition of this SDNode.
+// \p MASKPOS The mask operand position.
+// \p EVLPOS The explicit vector length operand position.
+#ifndef BEGIN_REGISTER_VP_SDNODE
+#define BEGIN_REGISTER_VP_SDNODE(SDOPC, LEGALPOS, TDNAME, MASKPOS, EVLPOS)
+#endif
+
+// End the property scope of a new VP SDNode.
+#ifndef END_REGISTER_VP_SDNODE
+#define END_REGISTER_VP_SDNODE(SDOPC)
+#endif
+
+// Helper macros for the common "1:1 - Intrinsic : SDNode" case.
+//
+// There is one VP intrinsic that maps directly to one SDNode that goes by the
+// same name. Since the operands are also the same, we open the property
+// scopes for both the VPIntrinsic and the SDNode at once.
+//
+// \p INTRIN The canonical name (eg `vp_add`, which at the same time is the
+// name of the intrinsic and the TableGen def of the SDNode).
+// \p MASKPOS The mask operand position.
+// \p EVLPOS The explicit vector length operand position.
+// \p SDOPC The SelectionDAG Node id (eg VP_ADD).
+// \p LEGALPOS The operand position of the SDNode that is used for legalizing
+// this SDNode. This can be `-1`, in which case the return type of
+// the SDNode is used.
+#define BEGIN_REGISTER_VP(INTRIN, MASKPOS, EVLPOS, SDOPC, LEGALPOS) \
+BEGIN_REGISTER_VP_INTRINSIC(INTRIN, MASKPOS, EVLPOS) \
+BEGIN_REGISTER_VP_SDNODE(SDOPC, LEGALPOS, INTRIN, MASKPOS, EVLPOS)
+
+#define END_REGISTER_VP(INTRIN, SDOPC) \
+END_REGISTER_VP_INTRINSIC(INTRIN) \
+END_REGISTER_VP_SDNODE(SDOPC)
+
+
+// The following macros attach properties to the scope they are placed in. This
+// assigns the property to the VP Intrinsic and/or SDNode that belongs to the
+// scope.
+//
+// Property Macros {
+
+// The intrinsic and/or SDNode has the same function as this LLVM IR Opcode.
+// \p OPC The standard IR opcode.
+#ifndef HANDLE_VP_TO_OPC
+#define HANDLE_VP_TO_OPC(OPC)
+#endif
+
+/// } Property Macros
+
+///// Integer Arithmetic {
+
+// Specialized helper macro for integer binary operators (%x, %y, %mask, %evl).
+#ifdef HELPER_REGISTER_BINARY_INT_VP
+#error "The internal helper macro HELPER_REGISTER_BINARY_INT_VP is already defined!"
+#endif
+#define HELPER_REGISTER_BINARY_INT_VP(INTRIN, SDOPC, OPC) \
+BEGIN_REGISTER_VP(INTRIN, 2, 3, SDOPC, -1) \
+HANDLE_VP_TO_OPC(OPC) \
+END_REGISTER_VP(INTRIN, SDOPC)
+
+
+
// llvm.vp.add(x,y,mask,vlen)
-HELPER_REGISTER_BINARY_INT_VP(vp_add, VP_ADD, Add)
+HELPER_REGISTER_BINARY_INT_VP(vp_add, VP_ADD, Add)
// llvm.vp.and(x,y,mask,vlen)
-HELPER_REGISTER_BINARY_INT_VP(vp_and, VP_AND, And)
+HELPER_REGISTER_BINARY_INT_VP(vp_and, VP_AND, And)
// llvm.vp.ashr(x,y,mask,vlen)
-HELPER_REGISTER_BINARY_INT_VP(vp_ashr, VP_ASHR, AShr)
+HELPER_REGISTER_BINARY_INT_VP(vp_ashr, VP_ASHR, AShr)
// llvm.vp.lshr(x,y,mask,vlen)
-HELPER_REGISTER_BINARY_INT_VP(vp_lshr, VP_LSHR, LShr)
+HELPER_REGISTER_BINARY_INT_VP(vp_lshr, VP_LSHR, LShr)
// llvm.vp.mul(x,y,mask,vlen)
-HELPER_REGISTER_BINARY_INT_VP(vp_mul, VP_MUL, Mul)
+HELPER_REGISTER_BINARY_INT_VP(vp_mul, VP_MUL, Mul)
// llvm.vp.or(x,y,mask,vlen)
-HELPER_REGISTER_BINARY_INT_VP(vp_or, VP_OR, Or)
+HELPER_REGISTER_BINARY_INT_VP(vp_or, VP_OR, Or)
// llvm.vp.sdiv(x,y,mask,vlen)
-HELPER_REGISTER_BINARY_INT_VP(vp_sdiv, VP_SDIV, SDiv)
+HELPER_REGISTER_BINARY_INT_VP(vp_sdiv, VP_SDIV, SDiv)
// llvm.vp.shl(x,y,mask,vlen)
-HELPER_REGISTER_BINARY_INT_VP(vp_shl, VP_SHL, Shl)
+HELPER_REGISTER_BINARY_INT_VP(vp_shl, VP_SHL, Shl)
// llvm.vp.srem(x,y,mask,vlen)
-HELPER_REGISTER_BINARY_INT_VP(vp_srem, VP_SREM, SRem)
+HELPER_REGISTER_BINARY_INT_VP(vp_srem, VP_SREM, SRem)
// llvm.vp.sub(x,y,mask,vlen)
-HELPER_REGISTER_BINARY_INT_VP(vp_sub, VP_SUB, Sub)
+HELPER_REGISTER_BINARY_INT_VP(vp_sub, VP_SUB, Sub)
// llvm.vp.udiv(x,y,mask,vlen)
-HELPER_REGISTER_BINARY_INT_VP(vp_udiv, VP_UDIV, UDiv)
+HELPER_REGISTER_BINARY_INT_VP(vp_udiv, VP_UDIV, UDiv)
// llvm.vp.urem(x,y,mask,vlen)
-HELPER_REGISTER_BINARY_INT_VP(vp_urem, VP_UREM, URem)
+HELPER_REGISTER_BINARY_INT_VP(vp_urem, VP_UREM, URem)
// llvm.vp.xor(x,y,mask,vlen)
-HELPER_REGISTER_BINARY_INT_VP(vp_xor, VP_XOR, Xor)
-
-#undef HELPER_REGISTER_BINARY_INT_VP
-
-///// } Integer Arithmetic
-
-
-#undef BEGIN_REGISTER_VP
-#undef BEGIN_REGISTER_VP_INTRINSIC
-#undef BEGIN_REGISTER_VP_SDNODE
-#undef END_REGISTER_VP
-#undef END_REGISTER_VP_INTRINSIC
-#undef END_REGISTER_VP_SDNODE
-#undef HANDLE_VP_TO_OPC
+HELPER_REGISTER_BINARY_INT_VP(vp_xor, VP_XOR, Xor)
+
+#undef HELPER_REGISTER_BINARY_INT_VP
+
+///// } Integer Arithmetic
+
+
+#undef BEGIN_REGISTER_VP
+#undef BEGIN_REGISTER_VP_INTRINSIC
+#undef BEGIN_REGISTER_VP_SDNODE
+#undef END_REGISTER_VP
+#undef END_REGISTER_VP_INTRINSIC
+#undef END_REGISTER_VP_SDNODE
+#undef HANDLE_VP_TO_OPC
diff --git a/contrib/libs/llvm12/include/llvm/IR/Value.def b/contrib/libs/llvm12/include/llvm/IR/Value.def
index 8e38619b33..0a0125d319 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Value.def
+++ b/contrib/libs/llvm12/include/llvm/IR/Value.def
@@ -23,11 +23,11 @@
#error "Missing macro definition of HANDLE_VALUE*"
#endif
-// If the LLVM_C_API macro is set, then values handled via HANDLE_*_EXCLUDE_LLVM_C_API will not be expanded in areas the HANDLE_* macro is used. If it is not set, then HANDLE_*_EXCLUDE_LLVM_C_API values are handled normally as their HANDLE_* counterparts.
-#ifndef LLVM_C_API
-#define LLVM_C_API 0
-#endif
-
+// If the LLVM_C_API macro is set, then values handled via HANDLE_*_EXCLUDE_LLVM_C_API will not be expanded in areas the HANDLE_* macro is used. If it is not set, then HANDLE_*_EXCLUDE_LLVM_C_API values are handled normally as their HANDLE_* counterparts.
+#ifndef LLVM_C_API
+#define LLVM_C_API 0
+#endif
+
#ifndef HANDLE_MEMORY_VALUE
#define HANDLE_MEMORY_VALUE(ValueName) HANDLE_VALUE(ValueName)
#endif
@@ -60,15 +60,15 @@
#define HANDLE_CONSTANT_MARKER(MarkerName, ValueName)
#endif
-#ifndef HANDLE_CONSTANT_EXCLUDE_LLVM_C_API
-#define HANDLE_CONSTANT_EXCLUDE_LLVM_C_API(ValueName) HANDLE_CONSTANT(ValueName)
-#endif
-
-#if LLVM_C_API
-#undef HANDLE_CONSTANT_EXCLUDE_LLVM_C_API
-#define HANDLE_CONSTANT_EXCLUDE_LLVM_C_API(ValueName)
-#endif
-
+#ifndef HANDLE_CONSTANT_EXCLUDE_LLVM_C_API
+#define HANDLE_CONSTANT_EXCLUDE_LLVM_C_API(ValueName) HANDLE_CONSTANT(ValueName)
+#endif
+
+#if LLVM_C_API
+#undef HANDLE_CONSTANT_EXCLUDE_LLVM_C_API
+#define HANDLE_CONSTANT_EXCLUDE_LLVM_C_API(ValueName)
+#endif
+
// Having constant first makes the range check for isa<Constant> faster
// and smaller by one operation.
@@ -79,7 +79,7 @@ HANDLE_GLOBAL_VALUE(GlobalIFunc)
HANDLE_GLOBAL_VALUE(GlobalVariable)
HANDLE_CONSTANT(BlockAddress)
HANDLE_CONSTANT(ConstantExpr)
-HANDLE_CONSTANT_EXCLUDE_LLVM_C_API(DSOLocalEquivalent)
+HANDLE_CONSTANT_EXCLUDE_LLVM_C_API(DSOLocalEquivalent)
// ConstantAggregate.
HANDLE_CONSTANT(ConstantArray)
@@ -88,7 +88,7 @@ HANDLE_CONSTANT(ConstantVector)
// ConstantData.
HANDLE_CONSTANT(UndefValue)
-HANDLE_CONSTANT(PoisonValue)
+HANDLE_CONSTANT(PoisonValue)
HANDLE_CONSTANT(ConstantAggregateZero)
HANDLE_CONSTANT(ConstantDataArray)
HANDLE_CONSTANT(ConstantDataVector)
@@ -130,5 +130,5 @@ HANDLE_INSTRUCTION(Instruction)
#undef HANDLE_INLINE_ASM_VALUE
#undef HANDLE_VALUE
#undef HANDLE_CONSTANT_MARKER
-#undef HANDLE_CONSTANT_EXCLUDE_LLVM_C_API
-#undef LLVM_C_API
+#undef HANDLE_CONSTANT_EXCLUDE_LLVM_C_API
+#undef LLVM_C_API
diff --git a/contrib/libs/llvm12/include/llvm/IR/Value.h b/contrib/libs/llvm12/include/llvm/IR/Value.h
index 97a8e78840..30c95eafbe 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Value.h
+++ b/contrib/libs/llvm12/include/llvm/IR/Value.h
@@ -22,7 +22,7 @@
#include "llvm-c/Types.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/Use.h"
#include "llvm/Support/Alignment.h"
@@ -51,7 +51,7 @@ class GlobalVariable;
class InlineAsm;
class Instruction;
class LLVMContext;
-class MDNode;
+class MDNode;
class Module;
class ModuleSlotTracker;
class raw_ostream;
@@ -118,13 +118,13 @@ protected:
///
/// Note, this should *NOT* be used directly by any class other than User.
/// User uses this value to find the Use list.
- enum : unsigned { NumUserOperandsBits = 27 };
+ enum : unsigned { NumUserOperandsBits = 27 };
unsigned NumUserOperands : NumUserOperandsBits;
// Use the same type as the bitfield above so that MSVC will pack them.
unsigned IsUsedByMD : 1;
unsigned HasName : 1;
- unsigned HasMetadata : 1; // Has metadata attached to this?
+ unsigned HasMetadata : 1; // Has metadata attached to this?
unsigned HasHungOffUses : 1;
unsigned HasDescriptor : 1;
@@ -288,10 +288,10 @@ public:
/// \note It is an error to call V->takeName(V).
void takeName(Value *V);
-#ifndef NDEBUG
- std::string getNameOrAsOperand() const;
-#endif
-
+#ifndef NDEBUG
+ std::string getNameOrAsOperand() const;
+#endif
+
/// 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
@@ -437,31 +437,31 @@ public:
return materialized_users();
}
- /// Return true if there is exactly one use of this value.
+ /// Return true if there is exactly one use of this value.
///
/// This is specialized because it is a common request and does not require
/// traversing the whole use list.
- bool hasOneUse() const { return hasSingleElement(uses()); }
+ bool hasOneUse() const { return hasSingleElement(uses()); }
- /// Return true if this Value has exactly N uses.
+ /// Return true if this Value has exactly N uses.
bool hasNUses(unsigned N) const;
- /// Return true if this value has N uses or more.
+ /// Return true if this value has N uses or more.
///
/// This is logically equivalent to getNumUses() >= N.
bool hasNUsesOrMore(unsigned N) const;
- /// Return true if there is exactly one user of this value.
- ///
- /// Note that this is not the same as "has one use". If a value has one use,
- /// then there certainly is a single user. But if value has several uses,
- /// it is possible that all uses are in a single user, or not.
- ///
- /// This check is potentially costly, since it requires traversing,
- /// in the worst case, the whole use list of a value.
- bool hasOneUser() const;
-
- /// Return true if there is exactly one use of this value that cannot be
+ /// Return true if there is exactly one user of this value.
+ ///
+ /// Note that this is not the same as "has one use". If a value has one use,
+ /// then there certainly is a single user. But if value has several uses,
+ /// it is possible that all uses are in a single user, or not.
+ ///
+ /// This check is potentially costly, since it requires traversing,
+ /// in the worst case, the whole use list of a value.
+ bool hasOneUser() const;
+
+ /// Return true if there is exactly one use of this value that cannot be
/// dropped.
///
/// This is specialized because it is a common request and does not require
@@ -474,7 +474,7 @@ public:
/// traversing the whole use list.
bool hasNUndroppableUses(unsigned N) const;
- /// Return true if this value has N uses or more.
+ /// Return true if this value has N uses or more.
///
/// This is logically equivalent to getNumUses() >= N.
bool hasNUndroppableUsesOrMore(unsigned N) const;
@@ -489,12 +489,12 @@ public:
void dropDroppableUses(llvm::function_ref<bool(const Use *)> ShouldDrop =
[](const Use *) { return true; });
- /// Remove every use of this value in \p User that can safely be removed.
- void dropDroppableUsesIn(User &Usr);
-
- /// Remove the droppable use \p U.
- static void dropDroppableUse(Use &U);
-
+ /// Remove every use of this value in \p User that can safely be removed.
+ void dropDroppableUsesIn(User &Usr);
+
+ /// Remove the droppable use \p U.
+ static void dropDroppableUse(Use &U);
+
/// Check if this value is used in the specified basic block.
bool isUsedInBasicBlock(const BasicBlock *BB) const;
@@ -559,68 +559,68 @@ public:
/// Return true if there is metadata referencing this value.
bool isUsedByMetadata() const { return IsUsedByMD; }
-protected:
- /// Get the current metadata attachments for the given kind, if any.
- ///
- /// These functions require that the value have at most a single attachment
- /// of the given kind, and return \c nullptr if such an attachment is missing.
- /// @{
- MDNode *getMetadata(unsigned KindID) const;
- MDNode *getMetadata(StringRef Kind) const;
- /// @}
-
- /// Appends all attachments with the given ID to \c MDs in insertion order.
- /// If the Value has no attachments with the given ID, or if ID is invalid,
- /// leaves MDs unchanged.
- /// @{
- void getMetadata(unsigned KindID, SmallVectorImpl<MDNode *> &MDs) const;
- void getMetadata(StringRef Kind, SmallVectorImpl<MDNode *> &MDs) const;
- /// @}
-
- /// Appends all metadata attached to this value to \c MDs, sorting by
- /// KindID. The first element of each pair returned is the KindID, the second
- /// element is the metadata value. Attachments with the same ID appear in
- /// insertion order.
- void
- getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const;
-
- /// Return true if this value has any metadata attached to it.
- bool hasMetadata() const { return (bool)HasMetadata; }
-
- /// Return true if this value has the given type of metadata attached.
- /// @{
- bool hasMetadata(unsigned KindID) const {
- return getMetadata(KindID) != nullptr;
- }
- bool hasMetadata(StringRef Kind) const {
- return getMetadata(Kind) != nullptr;
- }
- /// @}
-
- /// Set a particular kind of metadata attachment.
- ///
- /// Sets the given attachment to \c MD, erasing it if \c MD is \c nullptr or
- /// replacing it if it already exists.
- /// @{
- void setMetadata(unsigned KindID, MDNode *Node);
- void setMetadata(StringRef Kind, MDNode *Node);
- /// @}
-
- /// Add a metadata attachment.
- /// @{
- void addMetadata(unsigned KindID, MDNode &MD);
- void addMetadata(StringRef Kind, MDNode &MD);
- /// @}
-
- /// Erase all metadata attachments with the given kind.
- ///
- /// \returns true if any metadata was removed.
- bool eraseMetadata(unsigned KindID);
-
- /// Erase all metadata attached to this Value.
- void clearMetadata();
-
-public:
+protected:
+ /// Get the current metadata attachments for the given kind, if any.
+ ///
+ /// These functions require that the value have at most a single attachment
+ /// of the given kind, and return \c nullptr if such an attachment is missing.
+ /// @{
+ MDNode *getMetadata(unsigned KindID) const;
+ MDNode *getMetadata(StringRef Kind) const;
+ /// @}
+
+ /// Appends all attachments with the given ID to \c MDs in insertion order.
+ /// If the Value has no attachments with the given ID, or if ID is invalid,
+ /// leaves MDs unchanged.
+ /// @{
+ void getMetadata(unsigned KindID, SmallVectorImpl<MDNode *> &MDs) const;
+ void getMetadata(StringRef Kind, SmallVectorImpl<MDNode *> &MDs) const;
+ /// @}
+
+ /// Appends all metadata attached to this value to \c MDs, sorting by
+ /// KindID. The first element of each pair returned is the KindID, the second
+ /// element is the metadata value. Attachments with the same ID appear in
+ /// insertion order.
+ void
+ getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const;
+
+ /// Return true if this value has any metadata attached to it.
+ bool hasMetadata() const { return (bool)HasMetadata; }
+
+ /// Return true if this value has the given type of metadata attached.
+ /// @{
+ bool hasMetadata(unsigned KindID) const {
+ return getMetadata(KindID) != nullptr;
+ }
+ bool hasMetadata(StringRef Kind) const {
+ return getMetadata(Kind) != nullptr;
+ }
+ /// @}
+
+ /// Set a particular kind of metadata attachment.
+ ///
+ /// Sets the given attachment to \c MD, erasing it if \c MD is \c nullptr or
+ /// replacing it if it already exists.
+ /// @{
+ void setMetadata(unsigned KindID, MDNode *Node);
+ void setMetadata(StringRef Kind, MDNode *Node);
+ /// @}
+
+ /// Add a metadata attachment.
+ /// @{
+ void addMetadata(unsigned KindID, MDNode &MD);
+ void addMetadata(StringRef Kind, MDNode &MD);
+ /// @}
+
+ /// Erase all metadata attachments with the given kind.
+ ///
+ /// \returns true if any metadata was removed.
+ bool eraseMetadata(unsigned KindID);
+
+ /// Erase all metadata attached to this Value.
+ void clearMetadata();
+
+public:
/// Return true if this value is a swifterror value.
///
/// swifterror values can be either a function argument or an alloca with a
diff --git a/contrib/libs/llvm12/include/llvm/IR/ValueHandle.h b/contrib/libs/llvm12/include/llvm/IR/ValueHandle.h
index d8ac351bf6..c0decdba35 100644
--- a/contrib/libs/llvm12/include/llvm/IR/ValueHandle.h
+++ b/contrib/libs/llvm12/include/llvm/IR/ValueHandle.h
@@ -265,13 +265,13 @@ template <> struct simplify_type<const WeakTrackingVH> {
/// class turns into a trivial wrapper around a pointer.
template <typename ValueTy>
class AssertingVH
-#if LLVM_ENABLE_ABI_BREAKING_CHECKS
- : public ValueHandleBase
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+ : public ValueHandleBase
#endif
-{
+{
friend struct DenseMapInfo<AssertingVH<ValueTy>>;
-#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
Value *getRawValPtr() const { return ValueHandleBase::getValPtr(); }
void setRawValPtr(Value *P) { ValueHandleBase::operator=(P); }
#else
@@ -287,14 +287,14 @@ class AssertingVH
void setValPtr(ValueTy *P) { setRawValPtr(GetAsValue(P)); }
public:
-#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
AssertingVH() : ValueHandleBase(Assert) {}
AssertingVH(ValueTy *P) : ValueHandleBase(Assert, GetAsValue(P)) {}
AssertingVH(const AssertingVH &RHS) : ValueHandleBase(Assert, RHS) {}
#else
AssertingVH() : ThePtr(nullptr) {}
AssertingVH(ValueTy *P) : ThePtr(GetAsValue(P)) {}
- AssertingVH(const AssertingVH &) = default;
+ AssertingVH(const AssertingVH &) = default;
#endif
operator ValueTy*() const {
@@ -449,9 +449,9 @@ public:
/// PoisoningVH's as it moves. This is required because in non-assert mode this
/// class turns into a trivial wrapper around a pointer.
template <typename ValueTy>
-class PoisoningVH final
-#if LLVM_ENABLE_ABI_BREAKING_CHECKS
- : public CallbackVH
+class PoisoningVH final
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+ : public CallbackVH
#endif
{
friend struct DenseMapInfo<PoisoningVH<ValueTy>>;
@@ -460,7 +460,7 @@ class PoisoningVH final
static Value *GetAsValue(Value *V) { return V; }
static Value *GetAsValue(const Value *V) { return const_cast<Value *>(V); }
-#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
/// A flag tracking whether this value has been poisoned.
///
/// On delete and RAUW, we leave the value pointer alone so that as a raw
@@ -485,7 +485,7 @@ class PoisoningVH final
Poisoned = true;
RemoveFromUseList();
}
-#else // LLVM_ENABLE_ABI_BREAKING_CHECKS
+#else // LLVM_ENABLE_ABI_BREAKING_CHECKS
Value *ThePtr = nullptr;
Value *getRawValPtr() const { return ThePtr; }
@@ -493,16 +493,16 @@ class PoisoningVH final
#endif
ValueTy *getValPtr() const {
-#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
assert(!Poisoned && "Accessed a poisoned value handle!");
-#endif
+#endif
return static_cast<ValueTy *>(getRawValPtr());
}
void setValPtr(ValueTy *P) { setRawValPtr(GetAsValue(P)); }
public:
PoisoningVH() = default;
-#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
PoisoningVH(ValueTy *P) : CallbackVH(GetAsValue(P)) {}
PoisoningVH(const PoisoningVH &RHS)
: CallbackVH(RHS), Poisoned(RHS.Poisoned) {}
diff --git a/contrib/libs/llvm12/include/llvm/IR/Verifier.h b/contrib/libs/llvm12/include/llvm/IR/Verifier.h
index 9d1f699c68..a679aa970f 100644
--- a/contrib/libs/llvm12/include/llvm/IR/Verifier.h
+++ b/contrib/libs/llvm12/include/llvm/IR/Verifier.h
@@ -123,7 +123,7 @@ public:
Result run(Module &M, ModuleAnalysisManager &);
Result run(Function &F, FunctionAnalysisManager &);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
};
/// Check a module for errors, but report debug info errors separately.
@@ -149,7 +149,7 @@ public:
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/InitializePasses.h b/contrib/libs/llvm12/include/llvm/InitializePasses.h
index 2818827580..62445e815b 100644
--- a/contrib/libs/llvm12/include/llvm/InitializePasses.h
+++ b/contrib/libs/llvm12/include/llvm/InitializePasses.h
@@ -80,19 +80,19 @@ void initializeAlignmentFromAssumptionsPass(PassRegistry&);
void initializeAlwaysInlinerLegacyPassPass(PassRegistry&);
void initializeAssumeSimplifyPassLegacyPassPass(PassRegistry &);
void initializeAssumeBuilderPassLegacyPassPass(PassRegistry &);
-void initializeAnnotation2MetadataLegacyPass(PassRegistry &);
-void initializeAnnotationRemarksLegacyPass(PassRegistry &);
+void initializeAnnotation2MetadataLegacyPass(PassRegistry &);
+void initializeAnnotationRemarksLegacyPass(PassRegistry &);
void initializeOpenMPOptLegacyPassPass(PassRegistry &);
void initializeArgPromotionPass(PassRegistry&);
void initializeAssumptionCacheTrackerPass(PassRegistry&);
void initializeAtomicExpandPass(PassRegistry&);
void initializeAttributorLegacyPassPass(PassRegistry&);
void initializeAttributorCGSCCLegacyPassPass(PassRegistry &);
-void initializeBasicBlockSectionsPass(PassRegistry &);
+void initializeBasicBlockSectionsPass(PassRegistry &);
void initializeBDCELegacyPassPass(PassRegistry&);
void initializeBarrierNoopPass(PassRegistry&);
void initializeBasicAAWrapperPassPass(PassRegistry&);
-void initializeBlockExtractorLegacyPassPass(PassRegistry &);
+void initializeBlockExtractorLegacyPassPass(PassRegistry &);
void initializeBlockFrequencyInfoWrapperPassPass(PassRegistry&);
void initializeBoundsCheckingLegacyPassPass(PassRegistry&);
void initializeBranchFolderPassPass(PassRegistry&);
@@ -119,11 +119,11 @@ void initializeCallGraphViewerPass(PassRegistry&);
void initializeCallGraphWrapperPassPass(PassRegistry&);
void initializeCallSiteSplittingLegacyPassPass(PassRegistry&);
void initializeCalledValuePropagationLegacyPassPass(PassRegistry &);
-void initializeCheckDebugMachineModulePass(PassRegistry &);
+void initializeCheckDebugMachineModulePass(PassRegistry &);
void initializeCodeGenPreparePass(PassRegistry&);
void initializeConstantHoistingLegacyPassPass(PassRegistry&);
void initializeConstantMergeLegacyPassPass(PassRegistry&);
-void initializeConstraintEliminationPass(PassRegistry &);
+void initializeConstraintEliminationPass(PassRegistry &);
void initializeControlHeightReductionLegacyPassPass(PassRegistry&);
void initializeCorrelatedValuePropagationPass(PassRegistry&);
void initializeCostModelAnalysisPass(PassRegistry&);
@@ -132,7 +132,7 @@ void initializeDAEPass(PassRegistry&);
void initializeDAHPass(PassRegistry&);
void initializeDCELegacyPassPass(PassRegistry&);
void initializeDSELegacyPassPass(PassRegistry&);
-void initializeDataFlowSanitizerLegacyPassPass(PassRegistry &);
+void initializeDataFlowSanitizerLegacyPassPass(PassRegistry &);
void initializeDeadMachineInstructionElimPass(PassRegistry&);
void initializeDebugifyMachineModulePass(PassRegistry &);
void initializeDelinearizationPass(PassRegistry&);
@@ -147,7 +147,7 @@ void initializeDomPrinterPass(PassRegistry&);
void initializeDomViewerPass(PassRegistry&);
void initializeDominanceFrontierWrapperPassPass(PassRegistry&);
void initializeDominatorTreeWrapperPassPass(PassRegistry&);
-void initializeDwarfEHPrepareLegacyPassPass(PassRegistry &);
+void initializeDwarfEHPrepareLegacyPassPass(PassRegistry &);
void initializeEarlyCSELegacyPassPass(PassRegistry&);
void initializeEarlyCSEMemSSALegacyPassPass(PassRegistry&);
void initializeEarlyIfConverterPass(PassRegistry&);
@@ -186,13 +186,13 @@ void initializeGlobalSplitPass(PassRegistry&);
void initializeGlobalsAAWrapperPassPass(PassRegistry&);
void initializeGuardWideningLegacyPassPass(PassRegistry&);
void initializeHardwareLoopsPass(PassRegistry&);
-void initializeMemProfilerLegacyPassPass(PassRegistry &);
+void initializeMemProfilerLegacyPassPass(PassRegistry &);
void initializeHotColdSplittingLegacyPassPass(PassRegistry&);
void initializeHWAddressSanitizerLegacyPassPass(PassRegistry &);
void initializeIPSCCPLegacyPassPass(PassRegistry&);
void initializeIRCELegacyPassPass(PassRegistry&);
-void initializeIROutlinerLegacyPassPass(PassRegistry&);
-void initializeIRSimilarityIdentifierWrapperPassPass(PassRegistry&);
+void initializeIROutlinerLegacyPassPass(PassRegistry&);
+void initializeIRSimilarityIdentifierWrapperPassPass(PassRegistry&);
void initializeIRTranslatorPass(PassRegistry&);
void initializeIVUsersWrapperPassPass(PassRegistry&);
void initializeIfConverterPass(PassRegistry&);
@@ -204,7 +204,7 @@ void initializeInferAddressSpacesPass(PassRegistry&);
void initializeInferFunctionAttrsLegacyPassPass(PassRegistry&);
void initializeInjectTLIMappingsLegacyPass(PassRegistry &);
void initializeInlineCostAnalysisPass(PassRegistry&);
-void initializeInstCountLegacyPassPass(PassRegistry &);
+void initializeInstCountLegacyPassPass(PassRegistry &);
void initializeInstNamerPass(PassRegistry&);
void initializeInstSimplifyLegacyPassPass(PassRegistry &);
void initializeInstrProfilingLegacyPassPass(PassRegistry&);
@@ -230,7 +230,7 @@ void initializeLegalizerPass(PassRegistry&);
void initializeGISelCSEAnalysisWrapperPassPass(PassRegistry &);
void initializeGISelKnownBitsAnalysisPass(PassRegistry &);
void initializeLibCallsShrinkWrapLegacyPassPass(PassRegistry&);
-void initializeLintLegacyPassPass(PassRegistry &);
+void initializeLintLegacyPassPass(PassRegistry &);
void initializeLiveDebugValuesPass(PassRegistry&);
void initializeLiveDebugVariablesPass(PassRegistry&);
void initializeLiveIntervalsPass(PassRegistry&);
@@ -246,18 +246,18 @@ void initializeLoopAccessLegacyAnalysisPass(PassRegistry&);
void initializeLoopDataPrefetchLegacyPassPass(PassRegistry&);
void initializeLoopDeletionLegacyPassPass(PassRegistry&);
void initializeLoopDistributeLegacyPass(PassRegistry&);
-void initializeLoopExtractorLegacyPassPass(PassRegistry &);
+void initializeLoopExtractorLegacyPassPass(PassRegistry &);
void initializeLoopGuardWideningLegacyPassPass(PassRegistry&);
void initializeLoopFuseLegacyPass(PassRegistry&);
void initializeLoopIdiomRecognizeLegacyPassPass(PassRegistry&);
void initializeLoopInfoWrapperPassPass(PassRegistry&);
void initializeLoopInstSimplifyLegacyPassPass(PassRegistry&);
-void initializeLoopInterchangeLegacyPassPass(PassRegistry &);
-void initializeLoopFlattenLegacyPassPass(PassRegistry&);
+void initializeLoopInterchangeLegacyPassPass(PassRegistry &);
+void initializeLoopFlattenLegacyPassPass(PassRegistry&);
void initializeLoopLoadEliminationPass(PassRegistry&);
void initializeLoopPassPass(PassRegistry&);
void initializeLoopPredicationLegacyPassPass(PassRegistry&);
-void initializeLoopRerollLegacyPassPass(PassRegistry &);
+void initializeLoopRerollLegacyPassPass(PassRegistry &);
void initializeLoopRotateLegacyPassPass(PassRegistry&);
void initializeLoopSimplifyCFGLegacyPassPass(PassRegistry&);
void initializeLoopSimplifyPass(PassRegistry&);
@@ -266,8 +266,8 @@ void initializeLoopUnrollAndJamPass(PassRegistry&);
void initializeLoopUnrollPass(PassRegistry&);
void initializeLoopUnswitchPass(PassRegistry&);
void initializeLoopVectorizePass(PassRegistry&);
-void initializeLoopVersioningLICMLegacyPassPass(PassRegistry &);
-void initializeLoopVersioningLegacyPassPass(PassRegistry &);
+void initializeLoopVersioningLICMLegacyPassPass(PassRegistry &);
+void initializeLoopVersioningLegacyPassPass(PassRegistry &);
void initializeLowerAtomicLegacyPassPass(PassRegistry&);
void initializeLowerConstantIntrinsicsPass(PassRegistry&);
void initializeLowerEmuTLSPass(PassRegistry&);
@@ -276,10 +276,10 @@ void initializeLowerGuardIntrinsicLegacyPassPass(PassRegistry&);
void initializeLowerWidenableConditionLegacyPassPass(PassRegistry&);
void initializeLowerIntrinsicsPass(PassRegistry&);
void initializeLowerInvokeLegacyPassPass(PassRegistry&);
-void initializeLowerSwitchLegacyPassPass(PassRegistry &);
+void initializeLowerSwitchLegacyPassPass(PassRegistry &);
void initializeLowerTypeTestsPass(PassRegistry&);
void initializeLowerMatrixIntrinsicsLegacyPassPass(PassRegistry &);
-void initializeLowerMatrixIntrinsicsMinimalLegacyPassPass(PassRegistry &);
+void initializeLowerMatrixIntrinsicsMinimalLegacyPassPass(PassRegistry &);
void initializeMIRCanonicalizerPass(PassRegistry &);
void initializeMIRNamerPass(PassRegistry &);
void initializeMIRPrintingPassPass(PassRegistry&);
@@ -293,7 +293,7 @@ void initializeMachineCopyPropagationPass(PassRegistry&);
void initializeMachineDominanceFrontierPass(PassRegistry&);
void initializeMachineDominatorTreePass(PassRegistry&);
void initializeMachineFunctionPrinterPassPass(PassRegistry&);
-void initializeMachineFunctionSplitterPass(PassRegistry &);
+void initializeMachineFunctionSplitterPass(PassRegistry &);
void initializeMachineLICMPass(PassRegistry&);
void initializeMachineLoopInfoPass(PassRegistry&);
void initializeMachineModuleInfoWrapperPassPass(PassRegistry &);
@@ -317,8 +317,8 @@ void initializeMergeFunctionsLegacyPassPass(PassRegistry&);
void initializeMergeICmpsLegacyPassPass(PassRegistry &);
void initializeMergedLoadStoreMotionLegacyPassPass(PassRegistry&);
void initializeMetaRenamerPass(PassRegistry&);
-void initializeModuleDebugInfoLegacyPrinterPass(PassRegistry &);
-void initializeModuleMemProfilerLegacyPassPass(PassRegistry &);
+void initializeModuleDebugInfoLegacyPrinterPass(PassRegistry &);
+void initializeModuleMemProfilerLegacyPassPass(PassRegistry &);
void initializeModuleSummaryIndexWrapperPassPass(PassRegistry&);
void initializeModuloScheduleTestPass(PassRegistry&);
void initializeMustExecutePrinterPass(PassRegistry&);
@@ -329,9 +329,9 @@ void initializeNaryReassociateLegacyPassPass(PassRegistry&);
void initializeNewGVNLegacyPassPass(PassRegistry&);
void initializeObjCARCAAWrapperPassPass(PassRegistry&);
void initializeObjCARCAPElimPass(PassRegistry&);
-void initializeObjCARCContractLegacyPassPass(PassRegistry &);
+void initializeObjCARCContractLegacyPassPass(PassRegistry &);
void initializeObjCARCExpandPass(PassRegistry&);
-void initializeObjCARCOptLegacyPassPass(PassRegistry &);
+void initializeObjCARCOptLegacyPassPass(PassRegistry &);
void initializeOptimizationRemarkEmitterWrapperPassPass(PassRegistry&);
void initializeOptimizePHIsPass(PassRegistry&);
void initializePAEvalPass(PassRegistry&);
@@ -370,14 +370,14 @@ void initializeProfileSummaryInfoWrapperPassPass(PassRegistry&);
void initializePromoteLegacyPassPass(PassRegistry&);
void initializePruneEHPass(PassRegistry&);
void initializeRABasicPass(PassRegistry&);
-void initializePseudoProbeInserterPass(PassRegistry &);
+void initializePseudoProbeInserterPass(PassRegistry &);
void initializeRAGreedyPass(PassRegistry&);
void initializeReachingDefAnalysisPass(PassRegistry&);
void initializeReassociateLegacyPassPass(PassRegistry&);
void initializeRedundantDbgInstEliminationPass(PassRegistry&);
void initializeRegAllocFastPass(PassRegistry&);
void initializeRegBankSelectPass(PassRegistry&);
-void initializeRegToMemLegacyPass(PassRegistry&);
+void initializeRegToMemLegacyPass(PassRegistry&);
void initializeRegUsageInfoCollectorPass(PassRegistry&);
void initializeRegUsageInfoPropagationPass(PassRegistry&);
void initializeRegionInfoPassPass(PassRegistry&);
@@ -400,11 +400,11 @@ void initializeSafepointIRVerifierPass(PassRegistry&);
void initializeSampleProfileLoaderLegacyPassPass(PassRegistry&);
void initializeModuleSanitizerCoverageLegacyPassPass(PassRegistry &);
void initializeScalarEvolutionWrapperPassPass(PassRegistry&);
-void initializeScalarizeMaskedMemIntrinLegacyPassPass(PassRegistry &);
+void initializeScalarizeMaskedMemIntrinLegacyPassPass(PassRegistry &);
void initializeScalarizerLegacyPassPass(PassRegistry&);
void initializeScavengerTestPass(PassRegistry&);
void initializeScopedNoAliasAAWrapperPassPass(PassRegistry&);
-void initializeSeparateConstOffsetFromGEPLegacyPassPass(PassRegistry &);
+void initializeSeparateConstOffsetFromGEPLegacyPassPass(PassRegistry &);
void initializeShadowStackGCLoweringPass(PassRegistry&);
void initializeShrinkWrapPass(PassRegistry&);
void initializeSimpleInlinerPass(PassRegistry&);
@@ -421,16 +421,16 @@ void initializeStackProtectorPass(PassRegistry&);
void initializeStackSafetyGlobalInfoWrapperPassPass(PassRegistry &);
void initializeStackSafetyInfoWrapperPassPass(PassRegistry &);
void initializeStackSlotColoringPass(PassRegistry&);
-void initializeStraightLineStrengthReduceLegacyPassPass(PassRegistry &);
+void initializeStraightLineStrengthReduceLegacyPassPass(PassRegistry &);
void initializeStripDeadDebugInfoPass(PassRegistry&);
void initializeStripDeadPrototypesLegacyPassPass(PassRegistry&);
void initializeStripDebugDeclarePass(PassRegistry&);
void initializeStripDebugMachineModulePass(PassRegistry &);
-void initializeStripGCRelocatesLegacyPass(PassRegistry &);
+void initializeStripGCRelocatesLegacyPass(PassRegistry &);
void initializeStripNonDebugSymbolsPass(PassRegistry&);
-void initializeStripNonLineTableDebugLegacyPassPass(PassRegistry &);
+void initializeStripNonLineTableDebugLegacyPassPass(PassRegistry &);
void initializeStripSymbolsPass(PassRegistry&);
-void initializeStructurizeCFGLegacyPassPass(PassRegistry &);
+void initializeStructurizeCFGLegacyPassPass(PassRegistry &);
void initializeTailCallElimPass(PassRegistry&);
void initializeTailDuplicatePass(PassRegistry&);
void initializeTargetLibraryInfoWrapperPassPass(PassRegistry&);
@@ -440,8 +440,8 @@ void initializeThreadSanitizerLegacyPassPass(PassRegistry&);
void initializeTwoAddressInstructionPassPass(PassRegistry&);
void initializeTypeBasedAAWrapperPassPass(PassRegistry&);
void initializeTypePromotionPass(PassRegistry&);
-void initializeUnifyFunctionExitNodesLegacyPassPass(PassRegistry &);
-void initializeUnifyLoopExitsLegacyPassPass(PassRegistry &);
+void initializeUnifyFunctionExitNodesLegacyPassPass(PassRegistry &);
+void initializeUnifyLoopExitsLegacyPassPass(PassRegistry &);
void initializeUnpackMachineBundlesPass(PassRegistry&);
void initializeUnreachableBlockElimLegacyPassPass(PassRegistry&);
void initializeUnreachableMachineBlockElimPass(PassRegistry&);
diff --git a/contrib/libs/llvm12/include/llvm/InterfaceStub/ELFObjHandler.h b/contrib/libs/llvm12/include/llvm/InterfaceStub/ELFObjHandler.h
index a030f06baa..815bf6da45 100644
--- a/contrib/libs/llvm12/include/llvm/InterfaceStub/ELFObjHandler.h
+++ b/contrib/libs/llvm12/include/llvm/InterfaceStub/ELFObjHandler.h
@@ -1,58 +1,58 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- ELFObjHandler.h ------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===-----------------------------------------------------------------------===/
-///
-/// This supports reading and writing of elf dynamic shared objects.
-///
-//===-----------------------------------------------------------------------===/
-
-#ifndef LLVM_TOOLS_ELFABI_ELFOBJHANDLER_H
-#define LLVM_TOOLS_ELFABI_ELFOBJHANDLER_H
-
-#include "llvm/InterfaceStub/ELFStub.h"
-#include "llvm/Object/ELFObjectFile.h"
-#include "llvm/Object/ELFTypes.h"
-#include "llvm/Support/FileSystem.h"
-
-namespace llvm {
-
-class MemoryBuffer;
-
-namespace elfabi {
-
-enum class ELFTarget { ELF32LE, ELF32BE, ELF64LE, ELF64BE };
-
-/// Attempt to read a binary ELF file from a MemoryBuffer.
-Expected<std::unique_ptr<ELFStub>> readELFFile(MemoryBufferRef Buf);
-
-/// Attempt to write a binary ELF stub.
-/// This function determines appropriate ELFType using the passed ELFTarget and
-/// then writes a binary ELF stub to a specified file path.
-///
-/// @param FilePath File path for writing the ELF binary.
-/// @param Stub Source ELFStub to generate a binary ELF stub from.
-/// @param OutputFormat Target ELFType to write binary as.
-/// @param WriteIfChanged Whether or not to preserve timestamp if
-/// the output stays the same.
-Error writeBinaryStub(StringRef FilePath, const ELFStub &Stub,
- ELFTarget OutputFormat, bool WriteIfChanged = false);
-
-} // end namespace elfabi
-} // end namespace llvm
-
-#endif // LLVM_TOOLS_ELFABI_ELFOBJHANDLER_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- ELFObjHandler.h ------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===-----------------------------------------------------------------------===/
+///
+/// This supports reading and writing of elf dynamic shared objects.
+///
+//===-----------------------------------------------------------------------===/
+
+#ifndef LLVM_TOOLS_ELFABI_ELFOBJHANDLER_H
+#define LLVM_TOOLS_ELFABI_ELFOBJHANDLER_H
+
+#include "llvm/InterfaceStub/ELFStub.h"
+#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/ELFTypes.h"
+#include "llvm/Support/FileSystem.h"
+
+namespace llvm {
+
+class MemoryBuffer;
+
+namespace elfabi {
+
+enum class ELFTarget { ELF32LE, ELF32BE, ELF64LE, ELF64BE };
+
+/// Attempt to read a binary ELF file from a MemoryBuffer.
+Expected<std::unique_ptr<ELFStub>> readELFFile(MemoryBufferRef Buf);
+
+/// Attempt to write a binary ELF stub.
+/// This function determines appropriate ELFType using the passed ELFTarget and
+/// then writes a binary ELF stub to a specified file path.
+///
+/// @param FilePath File path for writing the ELF binary.
+/// @param Stub Source ELFStub to generate a binary ELF stub from.
+/// @param OutputFormat Target ELFType to write binary as.
+/// @param WriteIfChanged Whether or not to preserve timestamp if
+/// the output stays the same.
+Error writeBinaryStub(StringRef FilePath, const ELFStub &Stub,
+ ELFTarget OutputFormat, bool WriteIfChanged = false);
+
+} // end namespace elfabi
+} // end namespace llvm
+
+#endif // LLVM_TOOLS_ELFABI_ELFOBJHANDLER_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/InterfaceStub/ELFStub.h b/contrib/libs/llvm12/include/llvm/InterfaceStub/ELFStub.h
index bcd5b2fcbf..41777d5a48 100644
--- a/contrib/libs/llvm12/include/llvm/InterfaceStub/ELFStub.h
+++ b/contrib/libs/llvm12/include/llvm/InterfaceStub/ELFStub.h
@@ -1,77 +1,77 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- ELFStub.h ------------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===-----------------------------------------------------------------------===/
-///
-/// \file
-/// This file defines an internal representation of an ELF stub.
-///
-//===-----------------------------------------------------------------------===/
-
-#ifndef LLVM_TEXTAPI_ELF_ELFSTUB_H
-#define LLVM_TEXTAPI_ELF_ELFSTUB_H
-
-#include "llvm/BinaryFormat/ELF.h"
-#include "llvm/Support/VersionTuple.h"
-#include <set>
-#include <vector>
-
-namespace llvm {
-namespace elfabi {
-
-typedef uint16_t ELFArch;
-
-enum class ELFSymbolType {
- NoType = ELF::STT_NOTYPE,
- Object = ELF::STT_OBJECT,
- Func = ELF::STT_FUNC,
- TLS = ELF::STT_TLS,
-
- // Type information is 4 bits, so 16 is safely out of range.
- Unknown = 16,
-};
-
-struct ELFSymbol {
- ELFSymbol(std::string SymbolName) : Name(SymbolName) {}
- std::string Name;
- uint64_t Size;
- ELFSymbolType Type;
- bool Undefined;
- bool Weak;
- Optional<std::string> Warning;
- bool operator<(const ELFSymbol &RHS) const { return Name < RHS.Name; }
-};
-
-// A cumulative representation of ELF stubs.
-// Both textual and binary stubs will read into and write from this object.
-class ELFStub {
- // TODO: Add support for symbol versioning.
-public:
- VersionTuple TbeVersion;
- Optional<std::string> SoName;
- ELFArch Arch;
- std::vector<std::string> NeededLibs;
- std::set<ELFSymbol> Symbols;
-
- ELFStub() {}
- ELFStub(const ELFStub &Stub);
- ELFStub(ELFStub &&Stub);
-};
-} // end namespace elfabi
-} // end namespace llvm
-
-#endif // LLVM_TEXTAPI_ELF_ELFSTUB_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- ELFStub.h ------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===-----------------------------------------------------------------------===/
+///
+/// \file
+/// This file defines an internal representation of an ELF stub.
+///
+//===-----------------------------------------------------------------------===/
+
+#ifndef LLVM_TEXTAPI_ELF_ELFSTUB_H
+#define LLVM_TEXTAPI_ELF_ELFSTUB_H
+
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Support/VersionTuple.h"
+#include <set>
+#include <vector>
+
+namespace llvm {
+namespace elfabi {
+
+typedef uint16_t ELFArch;
+
+enum class ELFSymbolType {
+ NoType = ELF::STT_NOTYPE,
+ Object = ELF::STT_OBJECT,
+ Func = ELF::STT_FUNC,
+ TLS = ELF::STT_TLS,
+
+ // Type information is 4 bits, so 16 is safely out of range.
+ Unknown = 16,
+};
+
+struct ELFSymbol {
+ ELFSymbol(std::string SymbolName) : Name(SymbolName) {}
+ std::string Name;
+ uint64_t Size;
+ ELFSymbolType Type;
+ bool Undefined;
+ bool Weak;
+ Optional<std::string> Warning;
+ bool operator<(const ELFSymbol &RHS) const { return Name < RHS.Name; }
+};
+
+// A cumulative representation of ELF stubs.
+// Both textual and binary stubs will read into and write from this object.
+class ELFStub {
+ // TODO: Add support for symbol versioning.
+public:
+ VersionTuple TbeVersion;
+ Optional<std::string> SoName;
+ ELFArch Arch;
+ std::vector<std::string> NeededLibs;
+ std::set<ELFSymbol> Symbols;
+
+ ELFStub() {}
+ ELFStub(const ELFStub &Stub);
+ ELFStub(ELFStub &&Stub);
+};
+} // end namespace elfabi
+} // end namespace llvm
+
+#endif // LLVM_TEXTAPI_ELF_ELFSTUB_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/InterfaceStub/TBEHandler.h b/contrib/libs/llvm12/include/llvm/InterfaceStub/TBEHandler.h
index d86a99610b..f3a4afef30 100644
--- a/contrib/libs/llvm12/include/llvm/InterfaceStub/TBEHandler.h
+++ b/contrib/libs/llvm12/include/llvm/InterfaceStub/TBEHandler.h
@@ -1,54 +1,54 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- TBEHandler.h ---------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===-----------------------------------------------------------------------===/
-///
-/// \file
-/// This file declares an interface for reading and writing .tbe (text-based
-/// ELF) files.
-///
-//===-----------------------------------------------------------------------===/
-
-#ifndef LLVM_TEXTAPI_ELF_TBEHANDLER_H
-#define LLVM_TEXTAPI_ELF_TBEHANDLER_H
-
-#include "llvm/Support/Error.h"
-#include "llvm/Support/VersionTuple.h"
-#include <memory>
-
-namespace llvm {
-
-class raw_ostream;
-class Error;
-class StringRef;
-
-namespace elfabi {
-
-class ELFStub;
-
-const VersionTuple TBEVersionCurrent(1, 0);
-
-/// Attempts to read an ELF interface file from a StringRef buffer.
-Expected<std::unique_ptr<ELFStub>> readTBEFromBuffer(StringRef Buf);
-
-/// Attempts to write an ELF interface file to a raw_ostream.
-Error writeTBEToOutputStream(raw_ostream &OS, const ELFStub &Stub);
-
-} // end namespace elfabi
-} // end namespace llvm
-
-#endif // LLVM_TEXTAPI_ELF_TBEHANDLER_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- TBEHandler.h ---------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===-----------------------------------------------------------------------===/
+///
+/// \file
+/// This file declares an interface for reading and writing .tbe (text-based
+/// ELF) files.
+///
+//===-----------------------------------------------------------------------===/
+
+#ifndef LLVM_TEXTAPI_ELF_TBEHANDLER_H
+#define LLVM_TEXTAPI_ELF_TBEHANDLER_H
+
+#include "llvm/Support/Error.h"
+#include "llvm/Support/VersionTuple.h"
+#include <memory>
+
+namespace llvm {
+
+class raw_ostream;
+class Error;
+class StringRef;
+
+namespace elfabi {
+
+class ELFStub;
+
+const VersionTuple TBEVersionCurrent(1, 0);
+
+/// Attempts to read an ELF interface file from a StringRef buffer.
+Expected<std::unique_ptr<ELFStub>> readTBEFromBuffer(StringRef Buf);
+
+/// Attempts to write an ELF interface file to a raw_ostream.
+Error writeTBEToOutputStream(raw_ostream &OS, const ELFStub &Stub);
+
+} // end namespace elfabi
+} // end namespace llvm
+
+#endif // LLVM_TEXTAPI_ELF_TBEHANDLER_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/LTO/Config.h b/contrib/libs/llvm12/include/llvm/LTO/Config.h
index e13830794c..2c215dd839 100644
--- a/contrib/libs/llvm12/include/llvm/LTO/Config.h
+++ b/contrib/libs/llvm12/include/llvm/LTO/Config.h
@@ -5,7 +5,7 @@
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
-//===-Config.h - LLVM Link Time Optimizer Configuration ---------*- C++ -*-===//
+//===-Config.h - LLVM Link Time Optimizer Configuration ---------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -22,11 +22,11 @@
#define LLVM_LTO_CONFIG_H
#include "llvm/ADT/DenseSet.h"
-#include "llvm/Config/llvm-config.h"
+#include "llvm/Config/llvm-config.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Target/TargetOptions.h"
@@ -51,8 +51,8 @@ struct Config {
TargetOptions Options;
std::vector<std::string> MAttrs;
std::vector<std::string> PassPlugins;
- /// For adding passes that run right before codegen.
- std::function<void(legacy::PassManager &)> PreCodeGenPassesHook;
+ /// For adding passes that run right before codegen.
+ std::function<void(legacy::PassManager &)> PreCodeGenPassesHook;
Optional<Reloc::Model> RelocModel = Reloc::PIC_;
Optional<CodeModel::Model> CodeModel = None;
CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default;
@@ -61,7 +61,7 @@ struct Config {
bool DisableVerify = false;
/// Use the new pass manager
- bool UseNewPM = LLVM_ENABLE_NEW_PASS_MANAGER;
+ bool UseNewPM = LLVM_ENABLE_NEW_PASS_MANAGER;
/// Flag to indicate that the optimizer should not assume builtins are present
/// on the target.
@@ -124,31 +124,31 @@ struct Config {
std::string SplitDwarfOutput;
/// Optimization remarks file path.
- std::string RemarksFilename;
+ std::string RemarksFilename;
/// Optimization remarks pass filter.
- std::string RemarksPasses;
+ std::string RemarksPasses;
/// Whether to emit optimization remarks with hotness informations.
bool RemarksWithHotness = false;
- /// The minimum hotness value a diagnostic needs in order to be included in
- /// optimization diagnostics.
- ///
- /// The threshold is an Optional value, which maps to one of the 3 states:
- /// 1. 0 => threshold disabled. All emarks will be printed.
- /// 2. positive int => manual threshold by user. Remarks with hotness exceed
- /// threshold will be printed.
- /// 3. None => 'auto' threshold by user. The actual value is not
- /// available at command line, but will be synced with
- /// hotness threhold from profile summary during
- /// compilation.
- ///
- /// If threshold option is not specified, it is disabled by default.
- llvm::Optional<uint64_t> RemarksHotnessThreshold = 0;
-
+ /// The minimum hotness value a diagnostic needs in order to be included in
+ /// optimization diagnostics.
+ ///
+ /// The threshold is an Optional value, which maps to one of the 3 states:
+ /// 1. 0 => threshold disabled. All emarks will be printed.
+ /// 2. positive int => manual threshold by user. Remarks with hotness exceed
+ /// threshold will be printed.
+ /// 3. None => 'auto' threshold by user. The actual value is not
+ /// available at command line, but will be synced with
+ /// hotness threhold from profile summary during
+ /// compilation.
+ ///
+ /// If threshold option is not specified, it is disabled by default.
+ llvm::Optional<uint64_t> RemarksHotnessThreshold = 0;
+
/// The format used for serializing remarks (default: YAML).
- std::string RemarksFormat;
+ std::string RemarksFormat;
/// Whether to emit the pass manager debuggging informations.
bool DebugPassManager = false;
diff --git a/contrib/libs/llvm12/include/llvm/LTO/LTO.h b/contrib/libs/llvm12/include/llvm/LTO/LTO.h
index 21d099b9a5..b02400ad3d 100644
--- a/contrib/libs/llvm12/include/llvm/LTO/LTO.h
+++ b/contrib/libs/llvm12/include/llvm/LTO/LTO.h
@@ -89,19 +89,19 @@ std::string getThinLTOOutputFile(const std::string &Path,
const std::string &NewPrefix);
/// Setup optimization remarks.
-Expected<std::unique_ptr<ToolOutputFile>> setupLLVMOptimizationRemarks(
- LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses,
- StringRef RemarksFormat, bool RemarksWithHotness,
- Optional<uint64_t> RemarksHotnessThreshold = 0, int Count = -1);
+Expected<std::unique_ptr<ToolOutputFile>> setupLLVMOptimizationRemarks(
+ LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses,
+ StringRef RemarksFormat, bool RemarksWithHotness,
+ Optional<uint64_t> RemarksHotnessThreshold = 0, int Count = -1);
/// Setups the output file for saving statistics.
Expected<std::unique_ptr<ToolOutputFile>>
setupStatsFile(StringRef StatsFilename);
-/// Produces a container ordering for optimal multi-threaded processing. Returns
-/// ordered indices to elements in the input array.
-std::vector<int> generateModulesOrdering(ArrayRef<BitcodeModule *> R);
-
+/// Produces a container ordering for optimal multi-threaded processing. Returns
+/// ordered indices to elements in the input array.
+std::vector<int> generateModulesOrdering(ArrayRef<BitcodeModule *> R);
+
class LTO;
struct SymbolResolution;
class ThinBackendProc;
diff --git a/contrib/libs/llvm12/include/llvm/LTO/LTOBackend.h b/contrib/libs/llvm12/include/llvm/LTO/LTOBackend.h
index 5d1788aac0..01e2108bc1 100644
--- a/contrib/libs/llvm12/include/llvm/LTO/LTOBackend.h
+++ b/contrib/libs/llvm12/include/llvm/LTO/LTOBackend.h
@@ -40,12 +40,12 @@ class Target;
namespace lto {
-/// Runs middle-end LTO optimizations on \p Mod.
-bool opt(const Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod,
- bool IsThinLTO, ModuleSummaryIndex *ExportSummary,
- const ModuleSummaryIndex *ImportSummary,
- const std::vector<uint8_t> &CmdArgs);
-
+/// Runs middle-end LTO optimizations on \p Mod.
+bool opt(const Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod,
+ bool IsThinLTO, ModuleSummaryIndex *ExportSummary,
+ const ModuleSummaryIndex *ImportSummary,
+ const std::vector<uint8_t> &CmdArgs);
+
/// Runs a regular LTO backend. The regular LTO backend can also act as the
/// regular LTO phase of ThinLTO, which may need to access the combined index.
Error backend(const Config &C, AddStreamFn AddStream,
@@ -57,27 +57,27 @@ Error thinBackend(const Config &C, unsigned Task, AddStreamFn AddStream,
Module &M, const ModuleSummaryIndex &CombinedIndex,
const FunctionImporter::ImportMapTy &ImportList,
const GVSummaryMapTy &DefinedGlobals,
- MapVector<StringRef, BitcodeModule> &ModuleMap,
- const std::vector<uint8_t> &CmdArgs = std::vector<uint8_t>());
+ MapVector<StringRef, BitcodeModule> &ModuleMap,
+ const std::vector<uint8_t> &CmdArgs = std::vector<uint8_t>());
Error finalizeOptimizationRemarks(
std::unique_ptr<ToolOutputFile> DiagOutputFile);
-
-/// Returns the BitcodeModule that is ThinLTO.
-BitcodeModule *findThinLTOModule(MutableArrayRef<BitcodeModule> BMs);
-
-/// Variant of the above.
-Expected<BitcodeModule> findThinLTOModule(MemoryBufferRef MBRef);
-
-/// Distributed ThinLTO: load the referenced modules, keeping their buffers
-/// alive in the provided OwnedImportLifetimeManager. Returns false if the
-/// operation failed.
-bool loadReferencedModules(
- const Module &M, const ModuleSummaryIndex &CombinedIndex,
- FunctionImporter::ImportMapTy &ImportList,
- MapVector<llvm::StringRef, llvm::BitcodeModule> &ModuleMap,
- std::vector<std::unique_ptr<llvm::MemoryBuffer>>
- &OwnedImportsLifetimeManager);
+
+/// Returns the BitcodeModule that is ThinLTO.
+BitcodeModule *findThinLTOModule(MutableArrayRef<BitcodeModule> BMs);
+
+/// Variant of the above.
+Expected<BitcodeModule> findThinLTOModule(MemoryBufferRef MBRef);
+
+/// Distributed ThinLTO: load the referenced modules, keeping their buffers
+/// alive in the provided OwnedImportLifetimeManager. Returns false if the
+/// operation failed.
+bool loadReferencedModules(
+ const Module &M, const ModuleSummaryIndex &CombinedIndex,
+ FunctionImporter::ImportMapTy &ImportList,
+ MapVector<llvm::StringRef, llvm::BitcodeModule> &ModuleMap,
+ std::vector<std::unique_ptr<llvm::MemoryBuffer>>
+ &OwnedImportsLifetimeManager);
}
}
diff --git a/contrib/libs/llvm12/include/llvm/LTO/legacy/LTOCodeGenerator.h b/contrib/libs/llvm12/include/llvm/LTO/legacy/LTOCodeGenerator.h
index 45d974d6b7..d0de7221c2 100644
--- a/contrib/libs/llvm12/include/llvm/LTO/legacy/LTOCodeGenerator.h
+++ b/contrib/libs/llvm12/include/llvm/LTO/legacy/LTOCodeGenerator.h
@@ -100,7 +100,7 @@ struct LTOCodeGenerator {
void setFileType(CodeGenFileType FT) { FileType = FT; }
void setCpu(StringRef MCpu) { this->MCpu = std::string(MCpu); }
- void setAttrs(std::vector<std::string> MAttrs) { this->MAttrs = MAttrs; }
+ void setAttrs(std::vector<std::string> MAttrs) { this->MAttrs = MAttrs; }
void setOptLevel(unsigned OptLevel);
void setShouldInternalize(bool Value) { ShouldInternalize = Value; }
@@ -152,7 +152,7 @@ struct LTOCodeGenerator {
/// \note It is up to the linker to remove the intermediate output file. Do
/// not try to remove the object file in LTOCodeGenerator's destructor as we
/// don't who (LTOCodeGenerator or the output file) will last longer.
- bool compile_to_file(const char **Name);
+ bool compile_to_file(const char **Name);
/// As with compile_to_file(), this function compiles the merged module into
/// single output file. Instead of returning the output file path to the
@@ -160,12 +160,12 @@ struct LTOCodeGenerator {
/// to the caller. This function should delete the intermediate file once
/// its content is brought to memory. Return NULL if the compilation was not
/// successful.
- std::unique_ptr<MemoryBuffer> compile();
+ std::unique_ptr<MemoryBuffer> compile();
/// Optimizes the merged module. Returns true on success.
///
/// Calls \a verifyMergedModuleOnce().
- bool optimize();
+ bool optimize();
/// Compiles the merged optimized module into a single output file. It brings
/// the output to a buffer, and returns the buffer to the caller. Return NULL
@@ -185,8 +185,8 @@ struct LTOCodeGenerator {
/// assume builtins are present on the target.
void setFreestanding(bool Enabled) { Freestanding = Enabled; }
- void setDisableVerify(bool Value) { DisableVerify = Value; }
-
+ void setDisableVerify(bool Value) { DisableVerify = Value; }
+
void setDiagnosticHandler(lto_diagnostic_handler_t, void *);
LLVMContext &getContext() { return Context; }
@@ -232,7 +232,7 @@ private:
std::vector<std::string> CodegenOptions;
std::string FeatureStr;
std::string MCpu;
- std::vector<std::string> MAttrs;
+ std::vector<std::string> MAttrs;
std::string NativeObjectPath;
TargetOptions Options;
CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default;
@@ -248,7 +248,7 @@ private:
std::unique_ptr<ToolOutputFile> DiagnosticOutputFile;
bool Freestanding = false;
std::unique_ptr<ToolOutputFile> StatsFile = nullptr;
- bool DisableVerify = false;
+ bool DisableVerify = false;
};
}
#endif
diff --git a/contrib/libs/llvm12/include/llvm/LinkAllPasses.h b/contrib/libs/llvm12/include/llvm/LinkAllPasses.h
index 28529a1543..dd0346e2bf 100644
--- a/contrib/libs/llvm12/include/llvm/LinkAllPasses.h
+++ b/contrib/libs/llvm12/include/llvm/LinkAllPasses.h
@@ -134,7 +134,7 @@ namespace {
(void) llvm::createLazyValueInfoPass();
(void) llvm::createLoopExtractorPass();
(void) llvm::createLoopInterchangePass();
- (void) llvm::createLoopFlattenPass();
+ (void) llvm::createLoopFlattenPass();
(void) llvm::createLoopPredicationPass();
(void) llvm::createLoopSimplifyPass();
(void) llvm::createLoopSimplifyCFGPass();
@@ -210,7 +210,7 @@ namespace {
(void) llvm::createPrintFunctionPass(os);
(void) llvm::createModuleDebugInfoPrinterPass();
(void) llvm::createPartialInliningPass();
- (void) llvm::createLintLegacyPassPass();
+ (void) llvm::createLintLegacyPassPass();
(void) llvm::createSinkingPass();
(void) llvm::createLowerAtomicPass();
(void) llvm::createCorrelatedValuePropagationPass();
@@ -231,7 +231,7 @@ namespace {
(void) llvm::createMustBeExecutedContextPrinter();
(void) llvm::createFloat2IntPass();
(void) llvm::createEliminateAvailableExternallyPass();
- (void)llvm::createScalarizeMaskedMemIntrinLegacyPass();
+ (void)llvm::createScalarizeMaskedMemIntrinLegacyPass();
(void) llvm::createWarnMissedTransformationsPass();
(void) llvm::createHardwareLoopsPass();
(void) llvm::createInjectTLIMappingsLegacyPass();
@@ -246,7 +246,7 @@ namespace {
llvm::TargetLibraryInfo TLI(TLII);
llvm::AliasAnalysis AA(TLI);
llvm::AliasSetTracker X(AA);
- X.add(nullptr, llvm::LocationSize::beforeOrAfterPointer(),
+ X.add(nullptr, llvm::LocationSize::beforeOrAfterPointer(),
llvm::AAMDNodes()); // for -print-alias-sets
(void) llvm::AreStatisticsEnabled();
(void) llvm::sys::RunningOnValgrind();
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCAsmBackend.h b/contrib/libs/llvm12/include/llvm/MC/MCAsmBackend.h
index 791fb081a5..5b76d925af 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCAsmBackend.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCAsmBackend.h
@@ -151,9 +151,9 @@ public:
/// \param STI - The MCSubtargetInfo in effect when the instruction was
/// encoded.
virtual bool mayNeedRelaxation(const MCInst &Inst,
- const MCSubtargetInfo &STI) const {
- return false;
- }
+ const MCSubtargetInfo &STI) const {
+ return false;
+ }
/// Target specific predicate for whether a given fixup requires the
/// associated instruction to be relaxed.
@@ -184,10 +184,10 @@ public:
///
virtual unsigned getMinimumNopSize() const { return 1; }
- /// Returns the maximum size of a nop in bytes on this target.
- ///
- virtual unsigned getMaximumNopSize() const { return 0; }
-
+ /// Returns the maximum size of a nop in bytes on this target.
+ ///
+ virtual unsigned getMaximumNopSize() const { return 0; }
+
/// Write an (optimal) nop sequence of Count bytes to the given output. If the
/// target cannot generate such a sequence, it should return an error.
///
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCAsmInfo.h b/contrib/libs/llvm12/include/llvm/MC/MCAsmInfo.h
index 638fa04638..e4ee118ed2 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCAsmInfo.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCAsmInfo.h
@@ -61,15 +61,15 @@ enum LCOMMType { NoAlignment, ByteAlignment, Log2Alignment };
/// This class is intended to be used as a base class for asm
/// properties and features specific to the target.
class MCAsmInfo {
-public:
- /// Assembly character literal syntax types.
- enum AsmCharLiteralSyntax {
- ACLS_Unknown, /// Unknown; character literals not used by LLVM for this
- /// target.
- ACLS_SingleQuotePrefix, /// The desired character is prefixed by a single
- /// quote, e.g., `'A`.
- };
-
+public:
+ /// Assembly character literal syntax types.
+ enum AsmCharLiteralSyntax {
+ ACLS_Unknown, /// Unknown; character literals not used by LLVM for this
+ /// target.
+ ACLS_SingleQuotePrefix, /// The desired character is prefixed by a single
+ /// quote, e.g., `'A`.
+ };
+
protected:
//===------------------------------------------------------------------===//
// Properties to be set by the target writer, used to configure asm printer.
@@ -193,9 +193,9 @@ protected:
/// alignment is supported.
bool UseDotAlignForAlignment = false;
- /// True if the target supports LEB128 directives.
- bool HasLEB128Directives = true;
-
+ /// True if the target supports LEB128 directives.
+ bool HasLEB128Directives = true;
+
//===--- Data Emission Directives -------------------------------------===//
/// This should be set to the directive used to get some number of zero (and
@@ -219,16 +219,16 @@ protected:
/// doesn't support this, it can be set to null. Defaults to "\t.asciz\t"
const char *AscizDirective;
- /// This directive accepts a comma-separated list of bytes for emission as a
- /// string of bytes. For targets that do not support this, it shall be set to
- /// null. Defaults to null.
- const char *ByteListDirective = nullptr;
-
- /// Form used for character literals in the assembly syntax. Useful for
- /// producing strings as byte lists. If a target does not use or support
- /// this, it shall be set to ACLS_Unknown. Defaults to ACLS_Unknown.
- AsmCharLiteralSyntax CharacterLiteralSyntax = ACLS_Unknown;
-
+ /// This directive accepts a comma-separated list of bytes for emission as a
+ /// string of bytes. For targets that do not support this, it shall be set to
+ /// null. Defaults to null.
+ const char *ByteListDirective = nullptr;
+
+ /// Form used for character literals in the assembly syntax. Useful for
+ /// producing strings as byte lists. If a target does not use or support
+ /// this, it shall be set to ACLS_Unknown. Defaults to ACLS_Unknown.
+ AsmCharLiteralSyntax CharacterLiteralSyntax = ACLS_Unknown;
+
/// These directives are used to output some unit of integer data to the
/// current section. If a data directive is set to null, smaller data
/// directives will be used to emit the large sizes. Defaults to "\t.byte\t",
@@ -238,9 +238,9 @@ protected:
const char *Data32bitsDirective;
const char *Data64bitsDirective;
- /// True if data directives support signed values
- bool SupportsSignedData = true;
-
+ /// True if data directives support signed values
+ bool SupportsSignedData = true;
+
/// If non-null, a directive that is used to emit a word which should be
/// relocated as a 64-bit GP-relative offset, e.g. .gpdword on Mips. Defaults
/// to nullptr.
@@ -413,12 +413,12 @@ protected:
//===--- Integrated Assembler Information ----------------------------===//
- // Generated object files can use all ELF features supported by GNU ld of
- // this binutils version and later. INT_MAX means all features can be used,
- // regardless of GNU ld support. The default value is referenced by
- // clang/Driver/Options.td.
- std::pair<int, int> BinutilsVersion = {2, 26};
-
+ // Generated object files can use all ELF features supported by GNU ld of
+ // this binutils version and later. INT_MAX means all features can be used,
+ // regardless of GNU ld support. The default value is referenced by
+ // clang/Driver/Options.td.
+ std::pair<int, int> BinutilsVersion = {2, 26};
+
/// Should we use the integrated assembler?
/// The integrated assembler should be enabled by default (by the
/// constructors) when failing to parse a valid piece of assembly (inline
@@ -474,7 +474,7 @@ public:
const char *getData16bitsDirective() const { return Data16bitsDirective; }
const char *getData32bitsDirective() const { return Data32bitsDirective; }
const char *getData64bitsDirective() const { return Data64bitsDirective; }
- bool supportsSignedData() const { return SupportsSignedData; }
+ bool supportsSignedData() const { return SupportsSignedData; }
const char *getGPRel64Directive() const { return GPRel64Directive; }
const char *getGPRel32Directive() const { return GPRel32Directive; }
const char *getDTPRel64Directive() const { return DTPRel64Directive; }
@@ -591,18 +591,18 @@ public:
return UseDotAlignForAlignment;
}
- bool hasLEB128Directives() const { return HasLEB128Directives; }
-
+ bool hasLEB128Directives() const { return HasLEB128Directives; }
+
const char *getZeroDirective() const { return ZeroDirective; }
bool doesZeroDirectiveSupportNonZeroValue() const {
return ZeroDirectiveSupportsNonZeroValue;
}
const char *getAsciiDirective() const { return AsciiDirective; }
const char *getAscizDirective() const { return AscizDirective; }
- const char *getByteListDirective() const { return ByteListDirective; }
- AsmCharLiteralSyntax characterLiteralSyntax() const {
- return CharacterLiteralSyntax;
- }
+ const char *getByteListDirective() const { return ByteListDirective; }
+ AsmCharLiteralSyntax characterLiteralSyntax() const {
+ return CharacterLiteralSyntax;
+ }
bool getAlignmentIsInBytes() const { return AlignmentIsInBytes; }
unsigned getTextAlignFillValue() const { return TextAlignFillValue; }
const char *getGlobalDirective() const { return GlobalDirective; }
@@ -686,17 +686,17 @@ public:
return InitialFrameState;
}
- void setBinutilsVersion(std::pair<int, int> Value) {
- BinutilsVersion = Value;
- }
-
+ void setBinutilsVersion(std::pair<int, int> Value) {
+ BinutilsVersion = Value;
+ }
+
/// Return true if assembly (inline or otherwise) should be parsed.
bool useIntegratedAssembler() const { return UseIntegratedAssembler; }
- bool binutilsIsAtLeast(int Major, int Minor) const {
- return BinutilsVersion >= std::make_pair(Major, Minor);
- }
-
+ bool binutilsIsAtLeast(int Major, int Minor) const {
+ return BinutilsVersion >= std::make_pair(Major, Minor);
+ }
+
/// Set whether assembly (inline or otherwise) should be parsed.
virtual void setUseIntegratedAssembler(bool Value) {
UseIntegratedAssembler = Value;
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCAsmMacro.h b/contrib/libs/llvm12/include/llvm/MC/MCAsmMacro.h
index a92109c677..5e0ed50eba 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCAsmMacro.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCAsmMacro.h
@@ -150,16 +150,16 @@ struct MCAsmMacro {
StringRef Name;
StringRef Body;
MCAsmMacroParameters Parameters;
- std::vector<std::string> Locals;
- bool IsFunction = false;
+ std::vector<std::string> Locals;
+ bool IsFunction = false;
public:
MCAsmMacro(StringRef N, StringRef B, MCAsmMacroParameters P)
: Name(N), Body(B), Parameters(std::move(P)) {}
- MCAsmMacro(StringRef N, StringRef B, MCAsmMacroParameters P,
- std::vector<std::string> L, bool F)
- : Name(N), Body(B), Parameters(std::move(P)), Locals(std::move(L)),
- IsFunction(F) {}
+ MCAsmMacro(StringRef N, StringRef B, MCAsmMacroParameters P,
+ std::vector<std::string> L, bool F)
+ : Name(N), Body(B), Parameters(std::move(P)), Locals(std::move(L)),
+ IsFunction(F) {}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void dump() const { dump(dbgs()); }
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCAssembler.h b/contrib/libs/llvm12/include/llvm/MC/MCAssembler.h
index dd3ae8df6c..7f8dc1409c 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCAssembler.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCAssembler.h
@@ -209,7 +209,7 @@ private:
bool relaxCVInlineLineTable(MCAsmLayout &Layout,
MCCVInlineLineTableFragment &DF);
bool relaxCVDefRange(MCAsmLayout &Layout, MCCVDefRangeFragment &DF);
- bool relaxPseudoProbeAddr(MCAsmLayout &Layout, MCPseudoProbeAddrFragment &DF);
+ bool relaxPseudoProbeAddr(MCAsmLayout &Layout, MCPseudoProbeAddrFragment &DF);
/// finishLayout - Finalize a layout, including fragment lowering.
void finishLayout(MCAsmLayout &Layout);
@@ -218,12 +218,12 @@ private:
handleFixup(const MCAsmLayout &Layout, MCFragment &F, const MCFixup &Fixup);
public:
- struct Symver {
- StringRef Name;
- const MCSymbol *Sym;
- SMLoc Loc;
- };
- std::vector<Symver> Symvers;
+ struct Symver {
+ StringRef Name;
+ const MCSymbol *Sym;
+ SMLoc Loc;
+ };
+ std::vector<Symver> Symvers;
/// Construct a new assembler instance.
//
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCContext.h b/contrib/libs/llvm12/include/llvm/MC/MCContext.h
index 52ceb23ff5..c8297d6088 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCContext.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCContext.h
@@ -29,7 +29,7 @@
#include "llvm/BinaryFormat/XCOFF.h"
#include "llvm/MC/MCAsmMacro.h"
#include "llvm/MC/MCDwarf.h"
-#include "llvm/MC/MCPseudoProbe.h"
+#include "llvm/MC/MCPseudoProbe.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/SectionKind.h"
@@ -105,7 +105,7 @@ namespace llvm {
SpecificBumpPtrAllocator<MCSectionMachO> MachOAllocator;
SpecificBumpPtrAllocator<MCSectionWasm> WasmAllocator;
SpecificBumpPtrAllocator<MCSectionXCOFF> XCOFFAllocator;
- SpecificBumpPtrAllocator<MCInst> MCInstAllocator;
+ SpecificBumpPtrAllocator<MCInst> MCInstAllocator;
/// Bindings of names to symbols.
SymbolTable Symbols;
@@ -207,9 +207,9 @@ namespace llvm {
/// The Compile Unit ID that we are currently processing.
unsigned DwarfCompileUnitID = 0;
- /// A collection of MCPseudoProbe in the current module
- MCPseudoProbeTable PseudoProbeTable;
-
+ /// A collection of MCPseudoProbe in the current module
+ MCPseudoProbeTable PseudoProbeTable;
+
// Sections are differentiated by the quadruple (section_name, group_name,
// unique_id, link_to_symbol_name). Sections sharing the same quadruple are
// combined into one section.
@@ -392,11 +392,11 @@ namespace llvm {
/// @}
- /// \name McInst Management
-
- /// Create and return a new MC instruction.
- MCInst *createMCInst();
-
+ /// \name McInst Management
+
+ /// Create and return a new MC instruction.
+ MCInst *createMCInst();
+
/// \name Symbol Management
/// @{
@@ -404,16 +404,16 @@ namespace llvm {
/// unspecified name.
MCSymbol *createLinkerPrivateTempSymbol();
- /// Create a temporary symbol with a unique name. The name will be omitted
- /// in the symbol table if UseNamesOnTempLabels is false (default except
- /// MCAsmStreamer). The overload without Name uses an unspecified name.
- MCSymbol *createTempSymbol();
- MCSymbol *createTempSymbol(const Twine &Name, bool AlwaysAddSuffix = true);
+ /// Create a temporary symbol with a unique name. The name will be omitted
+ /// in the symbol table if UseNamesOnTempLabels is false (default except
+ /// MCAsmStreamer). The overload without Name uses an unspecified name.
+ MCSymbol *createTempSymbol();
+ MCSymbol *createTempSymbol(const Twine &Name, bool AlwaysAddSuffix = true);
- /// Create a temporary symbol with a unique name whose name cannot be
- /// omitted in the symbol table. This is rarely used.
- MCSymbol *createNamedTempSymbol();
- MCSymbol *createNamedTempSymbol(const Twine &Name);
+ /// Create a temporary symbol with a unique name whose name cannot be
+ /// omitted in the symbol table. This is rarely used.
+ MCSymbol *createNamedTempSymbol();
+ MCSymbol *createNamedTempSymbol(const Twine &Name);
/// Create the definition of a directional local symbol for numbered label
/// (used for "1:" definitions).
@@ -579,8 +579,8 @@ namespace llvm {
MCSectionXCOFF *getXCOFFSection(StringRef Section,
XCOFF::StorageMappingClass MappingClass,
- XCOFF::SymbolType CSectType, SectionKind K,
- bool MultiSymbolsAllowed = false,
+ XCOFF::SymbolType CSectType, SectionKind K,
+ bool MultiSymbolsAllowed = false,
const char *BeginSymName = nullptr);
// Create and save a copy of STI and return a reference to the copy.
@@ -764,8 +764,8 @@ namespace llvm {
}
void undefineMacro(StringRef Name) { MacroMap.erase(Name); }
-
- MCPseudoProbeTable &getMCPseudoProbeTable() { return PseudoProbeTable; }
+
+ MCPseudoProbeTable &getMCPseudoProbeTable() { return PseudoProbeTable; }
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCDwarf.h b/contrib/libs/llvm12/include/llvm/MC/MCDwarf.h
index 37652d9bef..b5e8d14fb8 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCDwarf.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCDwarf.h
@@ -32,7 +32,7 @@
#include <cassert>
#include <cstdint>
#include <string>
-#include <tuple>
+#include <tuple>
#include <utility>
#include <vector>
@@ -395,11 +395,11 @@ public:
int64_t LineDelta, uint64_t AddrDelta, raw_ostream &OS);
/// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas using
- /// fixed length operands. Returns (Offset, Size, SetDelta).
- static std::tuple<uint32_t, uint32_t, bool> fixedEncode(MCContext &Context,
- int64_t LineDelta,
- uint64_t AddrDelta,
- raw_ostream &OS);
+ /// fixed length operands. Returns (Offset, Size, SetDelta).
+ static std::tuple<uint32_t, uint32_t, bool> fixedEncode(MCContext &Context,
+ int64_t LineDelta,
+ uint64_t AddrDelta,
+ raw_ostream &OS);
/// Utility function to emit the encoding to a streamer.
static void Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCExpr.h b/contrib/libs/llvm12/include/llvm/MC/MCExpr.h
index 32bdbefe02..cc395cdee3 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCExpr.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCExpr.h
@@ -231,7 +231,7 @@ public:
VK_WEAKREF, // The link between the symbols in .weakref foo, bar
VK_X86_ABS8,
- VK_X86_PLTOFF,
+ VK_X86_PLTOFF,
VK_ARM_NONE,
VK_ARM_GOT_PREL,
@@ -307,14 +307,14 @@ public:
VK_PPC_GOT_TLSLD_HI, // symbol@got@tlsld@h
VK_PPC_GOT_TLSLD_HA, // symbol@got@tlsld@ha
VK_PPC_GOT_PCREL, // symbol@got@pcrel
- VK_PPC_GOT_TLSGD_PCREL, // symbol@got@tlsgd@pcrel
- VK_PPC_GOT_TLSLD_PCREL, // symbol@got@tlsld@pcrel
- VK_PPC_GOT_TPREL_PCREL, // symbol@got@tprel@pcrel
- VK_PPC_TLS_PCREL, // symbol@tls@pcrel
+ VK_PPC_GOT_TLSGD_PCREL, // symbol@got@tlsgd@pcrel
+ VK_PPC_GOT_TLSLD_PCREL, // symbol@got@tlsld@pcrel
+ VK_PPC_GOT_TPREL_PCREL, // symbol@got@tprel@pcrel
+ VK_PPC_TLS_PCREL, // symbol@tls@pcrel
VK_PPC_TLSLD, // symbol@tlsld
VK_PPC_LOCAL, // symbol@local
VK_PPC_NOTOC, // symbol@notoc
- VK_PPC_PCREL_OPT, // .reloc expr, R_PPC64_PCREL_OPT, expr
+ VK_PPC_PCREL_OPT, // .reloc expr, R_PPC64_PCREL_OPT, expr
VK_COFF_IMGREL32, // symbol@imgrel (image-relative)
@@ -329,9 +329,9 @@ public:
VK_Hexagon_IE_GOT,
VK_WASM_TYPEINDEX, // Reference to a symbol's type (signature)
- VK_WASM_TLSREL, // Memory address relative to __tls_base
- VK_WASM_MBREL, // Memory address relative to __memory_base
- VK_WASM_TBREL, // Table index relative to __table_base
+ VK_WASM_TLSREL, // Memory address relative to __tls_base
+ VK_WASM_MBREL, // Memory address relative to __memory_base
+ VK_WASM_TBREL, // Table index relative to __table_base
VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo
VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi
@@ -364,16 +364,16 @@ private:
/// The symbol being referenced.
const MCSymbol *Symbol;
- // Subclass data stores VariantKind in bits 0..15 and HasSubsectionsViaSymbols
- // in bit 16.
+ // Subclass data stores VariantKind in bits 0..15 and HasSubsectionsViaSymbols
+ // in bit 16.
static const unsigned VariantKindBits = 16;
static const unsigned VariantKindMask = (1 << VariantKindBits) - 1;
// FIXME: Remove this bit.
- static const unsigned HasSubsectionsViaSymbolsBit = 1 << VariantKindBits;
+ static const unsigned HasSubsectionsViaSymbolsBit = 1 << VariantKindBits;
static unsigned encodeSubclassData(VariantKind Kind,
- bool HasSubsectionsViaSymbols) {
+ bool HasSubsectionsViaSymbols) {
return (unsigned)Kind |
(HasSubsectionsViaSymbols ? HasSubsectionsViaSymbolsBit : 0);
}
@@ -501,7 +501,7 @@ public:
Mul, ///< Multiplication.
NE, ///< Inequality comparison.
Or, ///< Bitwise or.
- OrNot, ///< Bitwise or not.
+ OrNot, ///< Bitwise or not.
Shl, ///< Shift left.
AShr, ///< Arithmetic shift right.
LShr, ///< Logical shift right.
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCFragment.h b/contrib/libs/llvm12/include/llvm/MC/MCFragment.h
index a9bc653f87..b6f7f628ff 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCFragment.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCFragment.h
@@ -44,7 +44,7 @@ public:
FT_Data,
FT_CompactEncodedInst,
FT_Fill,
- FT_Nops,
+ FT_Nops,
FT_Relaxable,
FT_Org,
FT_Dwarf,
@@ -54,7 +54,7 @@ public:
FT_SymbolId,
FT_CVInlineLines,
FT_CVDefRange,
- FT_PseudoProbe,
+ FT_PseudoProbe,
FT_Dummy
};
@@ -72,10 +72,10 @@ private:
/// The layout order of this fragment.
unsigned LayoutOrder;
- /// The subsection this fragment belongs to. This is 0 if the fragment is not
- // in any subsection.
- unsigned SubsectionNumber = 0;
-
+ /// The subsection this fragment belongs to. This is 0 if the fragment is not
+ // in any subsection.
+ unsigned SubsectionNumber = 0;
+
FragmentType Kind;
/// Whether fragment is being laid out.
@@ -114,9 +114,9 @@ public:
bool hasInstructions() const { return HasInstructions; }
void dump() const;
-
- void setSubsectionNumber(unsigned Value) { SubsectionNumber = Value; }
- unsigned getSubsectionNumber() const { return SubsectionNumber; }
+
+ void setSubsectionNumber(unsigned Value) { SubsectionNumber = Value; }
+ unsigned getSubsectionNumber() const { return SubsectionNumber; }
};
class MCDummyFragment : public MCFragment {
@@ -155,7 +155,7 @@ public:
case MCFragment::FT_Data:
case MCFragment::FT_Dwarf:
case MCFragment::FT_DwarfFrame:
- case MCFragment::FT_PseudoProbe:
+ case MCFragment::FT_PseudoProbe:
return true;
}
}
@@ -367,31 +367,31 @@ public:
}
};
-class MCNopsFragment : public MCFragment {
- /// The number of bytes to insert.
- int64_t Size;
- /// Maximum number of bytes allowed in each NOP instruction.
- int64_t ControlledNopLength;
-
- /// Source location of the directive that this fragment was created for.
- SMLoc Loc;
-
-public:
- MCNopsFragment(int64_t NumBytes, int64_t ControlledNopLength, SMLoc L,
- MCSection *Sec = nullptr)
- : MCFragment(FT_Nops, false, Sec), Size(NumBytes),
- ControlledNopLength(ControlledNopLength), Loc(L) {}
-
- int64_t getNumBytes() const { return Size; }
- int64_t getControlledNopLength() const { return ControlledNopLength; }
-
- SMLoc getLoc() const { return Loc; }
-
- static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_Nops;
- }
-};
-
+class MCNopsFragment : public MCFragment {
+ /// The number of bytes to insert.
+ int64_t Size;
+ /// Maximum number of bytes allowed in each NOP instruction.
+ int64_t ControlledNopLength;
+
+ /// Source location of the directive that this fragment was created for.
+ SMLoc Loc;
+
+public:
+ MCNopsFragment(int64_t NumBytes, int64_t ControlledNopLength, SMLoc L,
+ MCSection *Sec = nullptr)
+ : MCFragment(FT_Nops, false, Sec), Size(NumBytes),
+ ControlledNopLength(ControlledNopLength), Loc(L) {}
+
+ int64_t getNumBytes() const { return Size; }
+ int64_t getControlledNopLength() const { return ControlledNopLength; }
+
+ SMLoc getLoc() const { return Loc; }
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Nops;
+ }
+};
+
class MCOrgFragment : public MCFragment {
/// Value to use for filling bytes.
int8_t Value;
@@ -600,23 +600,23 @@ public:
return F->getKind() == MCFragment::FT_BoundaryAlign;
}
};
-
-class MCPseudoProbeAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
- /// The expression for the difference of the two symbols that
- /// make up the address delta between two .pseudoprobe directives.
- const MCExpr *AddrDelta;
-
-public:
- MCPseudoProbeAddrFragment(const MCExpr *AddrDelta, MCSection *Sec = nullptr)
- : MCEncodedFragmentWithFixups<8, 1>(FT_PseudoProbe, false, Sec),
- AddrDelta(AddrDelta) {}
-
- const MCExpr &getAddrDelta() const { return *AddrDelta; }
-
- static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_PseudoProbe;
- }
-};
+
+class MCPseudoProbeAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
+ /// The expression for the difference of the two symbols that
+ /// make up the address delta between two .pseudoprobe directives.
+ const MCExpr *AddrDelta;
+
+public:
+ MCPseudoProbeAddrFragment(const MCExpr *AddrDelta, MCSection *Sec = nullptr)
+ : MCEncodedFragmentWithFixups<8, 1>(FT_PseudoProbe, false, Sec),
+ AddrDelta(AddrDelta) {}
+
+ const MCExpr &getAddrDelta() const { return *AddrDelta; }
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_PseudoProbe;
+ }
+};
} // end namespace llvm
#endif // LLVM_MC_MCFRAGMENT_H
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCInst.h b/contrib/libs/llvm12/include/llvm/MC/MCInst.h
index 7ac711071f..14fcd3eaf6 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCInst.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCInst.h
@@ -188,7 +188,7 @@ public:
MCOperand &getOperand(unsigned i) { return Operands[i]; }
unsigned getNumOperands() const { return Operands.size(); }
- void addOperand(const MCOperand Op) { Operands.push_back(Op); }
+ void addOperand(const MCOperand Op) { Operands.push_back(Op); }
using iterator = SmallVectorImpl<MCOperand>::iterator;
using const_iterator = SmallVectorImpl<MCOperand>::const_iterator;
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCInstPrinter.h b/contrib/libs/llvm12/include/llvm/MC/MCInstPrinter.h
index 6d6d24f30f..df6f54b26a 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCInstPrinter.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCInstPrinter.h
@@ -25,7 +25,7 @@ class MCAsmInfo;
class MCInst;
class MCOperand;
class MCInstrInfo;
-class MCInstrAnalysis;
+class MCInstrAnalysis;
class MCRegisterInfo;
class MCSubtargetInfo;
class raw_ostream;
@@ -56,7 +56,7 @@ protected:
const MCAsmInfo &MAI;
const MCInstrInfo &MII;
const MCRegisterInfo &MRI;
- const MCInstrAnalysis *MIA = nullptr;
+ const MCInstrAnalysis *MIA = nullptr;
/// True if we are printing marked up assembly.
bool UseMarkup = false;
@@ -72,9 +72,9 @@ protected:
/// (llvm-objdump -d).
bool PrintBranchImmAsAddress = false;
- /// If true, symbolize branch target and memory reference operands.
- bool SymbolizeOperands = false;
-
+ /// If true, symbolize branch target and memory reference operands.
+ bool SymbolizeOperands = false;
+
/// Utility function for printing annotations.
void printAnnotation(raw_ostream &OS, StringRef Annot);
@@ -95,10 +95,10 @@ public:
/// Specify a stream to emit comments to.
void setCommentStream(raw_ostream &OS) { CommentStream = &OS; }
- /// Returns a pair containing the mnemonic for \p MI and the number of bits
- /// left for further processing by printInstruction (generated by tablegen).
- virtual std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) = 0;
-
+ /// Returns a pair containing the mnemonic for \p MI and the number of bits
+ /// left for further processing by printInstruction (generated by tablegen).
+ virtual std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) = 0;
+
/// Print the specified MCInst to the specified raw_ostream.
///
/// \p Address the address of current instruction on most targets, used to
@@ -131,9 +131,9 @@ public:
PrintBranchImmAsAddress = Value;
}
- void setSymbolizeOperands(bool Value) { SymbolizeOperands = Value; }
- void setMCInstrAnalysis(const MCInstrAnalysis *Value) { MIA = Value; }
-
+ void setSymbolizeOperands(bool Value) { SymbolizeOperands = Value; }
+ void setMCInstrAnalysis(const MCInstrAnalysis *Value) { MIA = Value; }
+
/// Utility function to print immediates in decimal or hex.
format_object<int64_t> formatImm(int64_t Value) const {
return PrintImmHex ? formatHex(Value) : formatDec(Value);
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCInstrDesc.h b/contrib/libs/llvm12/include/llvm/MC/MCInstrDesc.h
index db29717df0..cb90a78f4e 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCInstrDesc.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCInstrDesc.h
@@ -34,22 +34,22 @@ class MCInst;
//===----------------------------------------------------------------------===//
namespace MCOI {
-/// Operand constraints. These are encoded in 16 bits with one of the
-/// low-order 3 bits specifying that a constraint is present and the
-/// corresponding high-order hex digit specifying the constraint value.
-/// This allows for a maximum of 3 constraints.
+/// Operand constraints. These are encoded in 16 bits with one of the
+/// low-order 3 bits specifying that a constraint is present and the
+/// corresponding high-order hex digit specifying the constraint value.
+/// This allows for a maximum of 3 constraints.
enum OperandConstraint {
- TIED_TO = 0, // Must be allocated the same register as specified value.
- EARLY_CLOBBER // If present, operand is an early clobber register.
+ TIED_TO = 0, // Must be allocated the same register as specified value.
+ EARLY_CLOBBER // If present, operand is an early clobber register.
};
-// Define a macro to produce each constraint value.
-#define MCOI_TIED_TO(op) \
- ((1 << MCOI::TIED_TO) | ((op) << (4 + MCOI::TIED_TO * 4)))
-
-#define MCOI_EARLY_CLOBBER \
- (1 << MCOI::EARLY_CLOBBER)
-
+// Define a macro to produce each constraint value.
+#define MCOI_TIED_TO(op) \
+ ((1 << MCOI::TIED_TO) | ((op) << (4 + MCOI::TIED_TO * 4)))
+
+#define MCOI_EARLY_CLOBBER \
+ (1 << MCOI::EARLY_CLOBBER)
+
/// 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.
@@ -102,9 +102,9 @@ public:
/// Information about the type of the operand.
uint8_t OperandType;
- /// Operand constraints (see OperandConstraint enum).
- uint16_t Constraints;
-
+ /// Operand constraints (see OperandConstraint enum).
+ uint16_t Constraints;
+
/// Set if this operand is a pointer value and it requires a callback
/// to look up its register class.
bool isLookupPtrRegClass() const {
@@ -213,14 +213,14 @@ public:
const MCPhysReg *ImplicitDefs; // Registers implicitly defined by this instr
const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands
- /// Returns the value of the specified operand constraint if
- /// it is present. Returns -1 if it is not present.
+ /// Returns the value of the specified operand constraint if
+ /// it is present. Returns -1 if it is not present.
int getOperandConstraint(unsigned OpNum,
MCOI::OperandConstraint Constraint) const {
if (OpNum < NumOperands &&
(OpInfo[OpNum].Constraints & (1 << Constraint))) {
- unsigned ValuePos = 4 + Constraint * 4;
- return (int)(OpInfo[OpNum].Constraints >> ValuePos) & 0x0f;
+ unsigned ValuePos = 4 + Constraint * 4;
+ return (int)(OpInfo[OpNum].Constraints >> ValuePos) & 0x0f;
}
return -1;
}
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCMachObjectWriter.h b/contrib/libs/llvm12/include/llvm/MC/MCMachObjectWriter.h
index aaf5913e7a..8ffd972bb6 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCMachObjectWriter.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCMachObjectWriter.h
@@ -121,7 +121,7 @@ class MachObjectWriter : public MCObjectWriter {
/// \name Symbol Table Data
/// @{
- StringTableBuilder StringTable;
+ StringTableBuilder StringTable;
std::vector<MachSymbolData> LocalSymbolData;
std::vector<MachSymbolData> ExternalSymbolData;
std::vector<MachSymbolData> UndefinedSymbolData;
@@ -136,8 +136,8 @@ public:
MachObjectWriter(std::unique_ptr<MCMachObjectTargetWriter> MOTW,
raw_pwrite_stream &OS, bool IsLittleEndian)
: TargetObjectWriter(std::move(MOTW)),
- StringTable(TargetObjectWriter->is64Bit() ? StringTableBuilder::MachO64
- : StringTableBuilder::MachO),
+ StringTable(TargetObjectWriter->is64Bit() ? StringTableBuilder::MachO64
+ : StringTableBuilder::MachO),
W(OS, IsLittleEndian ? support::little : support::big) {}
support::endian::Writer W;
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCObjectFileInfo.h b/contrib/libs/llvm12/include/llvm/MC/MCObjectFileInfo.h
index 8bebe6adc7..3e020bfd15 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCObjectFileInfo.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCObjectFileInfo.h
@@ -181,10 +181,10 @@ protected:
/// Section containing metadata on function stack sizes.
MCSection *StackSizesSection = nullptr;
- /// Section for pseudo probe information used by AutoFDO
- MCSection *PseudoProbeSection = nullptr;
- MCSection *PseudoProbeDescSection = nullptr;
-
+ /// Section for pseudo probe information used by AutoFDO
+ MCSection *PseudoProbeSection = nullptr;
+ MCSection *PseudoProbeDescSection = nullptr;
+
// ELF specific sections.
MCSection *DataRelROSection = nullptr;
MCSection *MergeableConst4Section = nullptr;
@@ -226,7 +226,7 @@ protected:
MCSection *XDataSection = nullptr;
MCSection *SXDataSection = nullptr;
MCSection *GFIDsSection = nullptr;
- MCSection *GIATsSection = nullptr;
+ MCSection *GIATsSection = nullptr;
MCSection *GLJMPSection = nullptr;
// XCOFF specific sections
@@ -349,12 +349,12 @@ public:
MCSection *getStackSizesSection(const MCSection &TextSec) const;
- MCSection *getBBAddrMapSection(const MCSection &TextSec) const;
-
- MCSection *getPseudoProbeSection(const MCSection *TextSec) const;
-
- MCSection *getPseudoProbeDescSection(StringRef FuncName) const;
-
+ MCSection *getBBAddrMapSection(const MCSection &TextSec) const;
+
+ MCSection *getPseudoProbeSection(const MCSection *TextSec) const;
+
+ MCSection *getPseudoProbeDescSection(StringRef FuncName) const;
+
// ELF specific sections.
MCSection *getDataRelROSection() const { return DataRelROSection; }
const MCSection *getMergeableConst4Section() const {
@@ -413,13 +413,13 @@ public:
MCSection *getXDataSection() const { return XDataSection; }
MCSection *getSXDataSection() const { return SXDataSection; }
MCSection *getGFIDsSection() const { return GFIDsSection; }
- MCSection *getGIATsSection() const { return GIATsSection; }
+ MCSection *getGIATsSection() const { return GIATsSection; }
MCSection *getGLJMPSection() const { return GLJMPSection; }
// XCOFF specific sections
MCSection *getTOCBaseSection() const { return TOCBaseSection; }
- MCSection *getEHFrameSection() const { return EHFrameSection; }
+ MCSection *getEHFrameSection() const { return EHFrameSection; }
enum Environment { IsMachO, IsELF, IsCOFF, IsWasm, IsXCOFF };
Environment getObjectFileType() const { return Env; }
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCObjectStreamer.h b/contrib/libs/llvm12/include/llvm/MC/MCObjectStreamer.h
index 5ec29c3498..f1e47eab00 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCObjectStreamer.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCObjectStreamer.h
@@ -186,8 +186,8 @@ public:
SMLoc Loc = SMLoc()) override;
void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
SMLoc Loc = SMLoc()) override;
- void emitNops(int64_t NumBytes, int64_t ControlledNopLength,
- SMLoc Loc) override;
+ void emitNops(int64_t NumBytes, int64_t ControlledNopLength,
+ SMLoc Loc) override;
void emitFileDirective(StringRef Filename) override;
void emitAddrsig() override;
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCParser/AsmLexer.h b/contrib/libs/llvm12/include/llvm/MC/MCParser/AsmLexer.h
index 9a4bd2fb02..47d4149dd6 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCParser/AsmLexer.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCParser/AsmLexer.h
@@ -63,7 +63,7 @@ private:
bool isAtStartOfComment(const char *Ptr);
bool isAtStatementSeparator(const char *Ptr);
int getNextChar();
- int peekNextChar();
+ int peekNextChar();
AsmToken ReturnError(const char *Loc, const std::string &Msg);
AsmToken LexIdentifier();
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCParser/MCAsmLexer.h b/contrib/libs/llvm12/include/llvm/MC/MCParser/MCAsmLexer.h
index 9bd56e607a..be14fd900d 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCParser/MCAsmLexer.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCParser/MCAsmLexer.h
@@ -56,11 +56,11 @@ protected: // Can only create subclasses.
bool SkipSpace = true;
bool AllowAtInIdentifier;
bool IsAtStartOfStatement = true;
- bool LexMasmHexFloats = false;
+ bool LexMasmHexFloats = false;
bool LexMasmIntegers = false;
- bool LexMasmStrings = false;
- bool UseMasmDefaultRadix = false;
- unsigned DefaultRadix = 10;
+ bool LexMasmStrings = false;
+ bool UseMasmDefaultRadix = false;
+ unsigned DefaultRadix = 10;
AsmCommentConsumer *CommentConsumer = nullptr;
MCAsmLexer();
@@ -158,23 +158,23 @@ public:
this->CommentConsumer = CommentConsumer;
}
- /// Set whether to lex masm-style binary (e.g., 0b1101) and radix-specified
- /// literals (e.g., 0ABCh [hex], 576t [decimal], 77o [octal], 1101y [binary]).
+ /// Set whether to lex masm-style binary (e.g., 0b1101) and radix-specified
+ /// literals (e.g., 0ABCh [hex], 576t [decimal], 77o [octal], 1101y [binary]).
void setLexMasmIntegers(bool V) { LexMasmIntegers = V; }
-
- /// Set whether to use masm-style default-radix integer literals. If disabled,
- /// assume decimal unless prefixed (e.g., 0x2c [hex], 077 [octal]).
- void useMasmDefaultRadix(bool V) { UseMasmDefaultRadix = V; }
-
- unsigned getMasmDefaultRadix() const { return DefaultRadix; }
- void setMasmDefaultRadix(unsigned Radix) { DefaultRadix = Radix; }
-
- /// Set whether to lex masm-style hex float literals, such as 3f800000r.
- void setLexMasmHexFloats(bool V) { LexMasmHexFloats = V; }
-
- /// Set whether to lex masm-style string literals, such as 'Can''t find file'
- /// and "This ""value"" not found".
- void setLexMasmStrings(bool V) { LexMasmStrings = V; }
+
+ /// Set whether to use masm-style default-radix integer literals. If disabled,
+ /// assume decimal unless prefixed (e.g., 0x2c [hex], 077 [octal]).
+ void useMasmDefaultRadix(bool V) { UseMasmDefaultRadix = V; }
+
+ unsigned getMasmDefaultRadix() const { return DefaultRadix; }
+ void setMasmDefaultRadix(unsigned Radix) { DefaultRadix = Radix; }
+
+ /// Set whether to lex masm-style hex float literals, such as 3f800000r.
+ void setLexMasmHexFloats(bool V) { LexMasmHexFloats = V; }
+
+ /// Set whether to lex masm-style string literals, such as 'Can''t find file'
+ /// and "This ""value"" not found".
+ void setLexMasmStrings(bool V) { LexMasmStrings = V; }
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCParser/MCAsmParser.h b/contrib/libs/llvm12/include/llvm/MC/MCParser/MCAsmParser.h
index 2447aa9151..d8e1a5c9fa 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCParser/MCAsmParser.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCParser/MCAsmParser.h
@@ -97,20 +97,20 @@ private:
IdKind Kind;
};
-// Generic type information for an assembly object.
-// All sizes measured in bytes.
-struct AsmTypeInfo {
- StringRef Name;
- unsigned Size = 0;
- unsigned ElementSize = 0;
- unsigned Length = 0;
-};
-
-struct AsmFieldInfo {
- AsmTypeInfo Type;
- unsigned Offset = 0;
-};
-
+// Generic type information for an assembly object.
+// All sizes measured in bytes.
+struct AsmTypeInfo {
+ StringRef Name;
+ unsigned Size = 0;
+ unsigned ElementSize = 0;
+ unsigned Length = 0;
+};
+
+struct AsmFieldInfo {
+ AsmTypeInfo Type;
+ unsigned Offset = 0;
+};
+
/// Generic Sema callback for assembly parser.
class MCAsmParserSemaCallback {
public:
@@ -191,20 +191,20 @@ public:
virtual bool isParsingMasm() const { return false; }
- virtual bool defineMacro(StringRef Name, StringRef Value) { return true; }
-
- virtual bool lookUpField(StringRef Name, AsmFieldInfo &Info) const {
+ virtual bool defineMacro(StringRef Name, StringRef Value) { return true; }
+
+ virtual bool lookUpField(StringRef Name, AsmFieldInfo &Info) const {
+ return true;
+ }
+ virtual bool lookUpField(StringRef Base, StringRef Member,
+ AsmFieldInfo &Info) const {
return true;
}
- virtual bool lookUpField(StringRef Base, StringRef Member,
- AsmFieldInfo &Info) const {
+
+ virtual bool lookUpType(StringRef Name, AsmTypeInfo &Info) const {
return true;
}
- virtual bool lookUpType(StringRef Name, AsmTypeInfo &Info) const {
- return true;
- }
-
/// Parse MS-style inline assembly.
virtual bool parseMSInlineAsm(
void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
@@ -307,8 +307,8 @@ public:
/// \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,
- AsmTypeInfo *TypeInfo) = 0;
+ virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
+ AsmTypeInfo *TypeInfo) = 0;
/// Parse an arbitrary expression, assuming that an initial '(' has
/// already been consumed.
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCParser/MCTargetAsmParser.h b/contrib/libs/llvm12/include/llvm/MC/MCParser/MCTargetAsmParser.h
index fdaddca970..2241332057 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCParser/MCTargetAsmParser.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCParser/MCTargetAsmParser.h
@@ -376,7 +376,7 @@ public:
// Target-specific parsing of expression.
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
- return getParser().parsePrimaryExpr(Res, EndLoc, nullptr);
+ return getParser().parsePrimaryExpr(Res, EndLoc, nullptr);
}
virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCPseudoProbe.h b/contrib/libs/llvm12/include/llvm/MC/MCPseudoProbe.h
index b3d8565696..8cc77d0e97 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCPseudoProbe.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCPseudoProbe.h
@@ -1,189 +1,189 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- MCPseudoProbe.h - Pseudo probe encoding support ---------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the declaration of the MCPseudoProbe to support the pseudo
-// probe encoding for AutoFDO. Pseudo probes together with their inline context
-// are encoded in a DFS recursive way in the .pseudoprobe sections. For each
-// .pseudoprobe section, the encoded binary data consist of a single or mutiple
-// function records each for one outlined function. A function record has the
-// following format :
-//
-// FUNCTION BODY (one for each outlined function present in the text section)
-// GUID (uint64)
-// GUID of the function
-// NPROBES (ULEB128)
-// Number of probes originating from this function.
-// NUM_INLINED_FUNCTIONS (ULEB128)
-// Number of callees inlined into this function, aka number of
-// first-level inlinees
-// PROBE RECORDS
-// A list of NPROBES entries. Each entry contains:
-// INDEX (ULEB128)
-// TYPE (uint4)
-// 0 - block probe, 1 - indirect call, 2 - direct call
-// ATTRIBUTE (uint3)
-// reserved
-// ADDRESS_TYPE (uint1)
-// 0 - code address, 1 - address delta
-// CODE_ADDRESS (uint64 or ULEB128)
-// code address or address delta, depending on ADDRESS_TYPE
-// INLINED FUNCTION RECORDS
-// A list of NUM_INLINED_FUNCTIONS entries describing each of the inlined
-// callees. Each record contains:
-// INLINE SITE
-// GUID of the inlinee (uint64)
-// ID of the callsite probe (ULEB128)
-// FUNCTION BODY
-// A FUNCTION BODY entry describing the inlined function.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_MC_MCPSEUDOPROBE_H
-#define LLVM_MC_MCPSEUDOPROBE_H
-
-#include "llvm/ADT/MapVector.h"
-#include "llvm/MC/MCSection.h"
-#include <functional>
-#include <map>
-#include <vector>
-
-namespace llvm {
-
-class MCStreamer;
-class MCSymbol;
-class MCObjectStreamer;
-
-enum class MCPseudoProbeFlag {
- // If set, indicates that the probe is encoded as an address delta
- // instead of a real code address.
- AddressDelta = 0x1,
-};
-
-/// Instances of this class represent a pseudo probe instance for a pseudo probe
-/// table entry, which is created during a machine instruction is assembled and
-/// uses an address from a temporary label created at the current address in the
-/// current section.
-class MCPseudoProbe {
- MCSymbol *Label;
- uint64_t Guid;
- uint64_t Index;
- uint8_t Type;
- uint8_t Attributes;
-
-public:
- MCPseudoProbe(MCSymbol *Label, uint64_t Guid, uint64_t Index, uint64_t Type,
- uint64_t Attributes)
- : Label(Label), Guid(Guid), Index(Index), Type(Type),
- Attributes(Attributes) {
- assert(Type <= 0xFF && "Probe type too big to encode, exceeding 2^8");
- assert(Attributes <= 0xFF &&
- "Probe attributes too big to encode, exceeding 2^16");
- }
-
- MCSymbol *getLabel() const { return Label; }
-
- uint64_t getGuid() const { return Guid; }
-
- uint64_t getIndex() const { return Index; }
-
- uint8_t getType() const { return Type; }
-
- uint8_t getAttributes() const { return Attributes; }
-
- void emit(MCObjectStreamer *MCOS, const MCPseudoProbe *LastProbe) const;
-};
-
-// An inline frame has the form <Guid, ProbeID>
-using InlineSite = std::tuple<uint64_t, uint32_t>;
-using MCPseudoProbeInlineStack = SmallVector<InlineSite, 8>;
-
-// A Tri-tree based data structure to group probes by inline stack.
-// A tree is allocated for a standalone .text section. A fake
-// instance is created as the root of a tree.
-// A real instance of this class is created for each function, either an
-// unlined function that has code in .text section or an inlined function.
-class MCPseudoProbeInlineTree {
- uint64_t Guid;
- // Set of probes that come with the function.
- std::vector<MCPseudoProbe> Probes;
- // Use std::map for a deterministic output.
- std::map<InlineSite, MCPseudoProbeInlineTree *> Inlinees;
-
- // Root node has a GUID 0.
- bool isRoot() { return Guid == 0; }
- MCPseudoProbeInlineTree *getOrAddNode(InlineSite Site);
-
-public:
- MCPseudoProbeInlineTree() = default;
- MCPseudoProbeInlineTree(uint64_t Guid) : Guid(Guid) {}
- ~MCPseudoProbeInlineTree();
- void addPseudoProbe(const MCPseudoProbe &Probe,
- const MCPseudoProbeInlineStack &InlineStack);
- void emit(MCObjectStreamer *MCOS, const MCPseudoProbe *&LastProbe);
-};
-
-/// Instances of this class represent the pseudo probes inserted into a compile
-/// unit.
-class MCPseudoProbeSection {
-public:
- void addPseudoProbe(MCSection *Sec, const MCPseudoProbe &Probe,
- const MCPseudoProbeInlineStack &InlineStack) {
- MCProbeDivisions[Sec].addPseudoProbe(Probe, InlineStack);
- }
-
- // TODO: Sort by getOrdinal to ensure a determinstic section order
- using MCProbeDivisionMap = std::map<MCSection *, MCPseudoProbeInlineTree>;
-
-private:
- // A collection of MCPseudoProbe for each text section. The MCPseudoProbes
- // are grouped by GUID of the functions where they are from and will be
- // encoded by groups. In the comdat scenario where a text section really only
- // contains the code of a function solely, the probes associated with a comdat
- // function are still grouped by GUIDs due to inlining that can bring probes
- // from different functions into one function.
- MCProbeDivisionMap MCProbeDivisions;
-
-public:
- const MCProbeDivisionMap &getMCProbes() const { return MCProbeDivisions; }
-
- bool empty() const { return MCProbeDivisions.empty(); }
-
- void emit(MCObjectStreamer *MCOS);
-};
-
-class MCPseudoProbeTable {
- // A collection of MCPseudoProbe in the current module grouped by text
- // sections. MCPseudoProbes will be encoded into a corresponding
- // .pseudoprobe section. With functions emitted as separate comdats,
- // a text section really only contains the code of a function solely, and the
- // probes associated with the text section will be emitted into a standalone
- // .pseudoprobe section that shares the same comdat group with the function.
- MCPseudoProbeSection MCProbeSections;
-
-public:
- static void emit(MCObjectStreamer *MCOS);
-
- MCPseudoProbeSection &getProbeSections() { return MCProbeSections; }
-
-#ifndef NDEBUG
- static int DdgPrintIndent;
-#endif
-};
-} // end namespace llvm
-
-#endif // LLVM_MC_MCPSEUDOPROBE_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- MCPseudoProbe.h - Pseudo probe encoding support ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCPseudoProbe to support the pseudo
+// probe encoding for AutoFDO. Pseudo probes together with their inline context
+// are encoded in a DFS recursive way in the .pseudoprobe sections. For each
+// .pseudoprobe section, the encoded binary data consist of a single or mutiple
+// function records each for one outlined function. A function record has the
+// following format :
+//
+// FUNCTION BODY (one for each outlined function present in the text section)
+// GUID (uint64)
+// GUID of the function
+// NPROBES (ULEB128)
+// Number of probes originating from this function.
+// NUM_INLINED_FUNCTIONS (ULEB128)
+// Number of callees inlined into this function, aka number of
+// first-level inlinees
+// PROBE RECORDS
+// A list of NPROBES entries. Each entry contains:
+// INDEX (ULEB128)
+// TYPE (uint4)
+// 0 - block probe, 1 - indirect call, 2 - direct call
+// ATTRIBUTE (uint3)
+// reserved
+// ADDRESS_TYPE (uint1)
+// 0 - code address, 1 - address delta
+// CODE_ADDRESS (uint64 or ULEB128)
+// code address or address delta, depending on ADDRESS_TYPE
+// INLINED FUNCTION RECORDS
+// A list of NUM_INLINED_FUNCTIONS entries describing each of the inlined
+// callees. Each record contains:
+// INLINE SITE
+// GUID of the inlinee (uint64)
+// ID of the callsite probe (ULEB128)
+// FUNCTION BODY
+// A FUNCTION BODY entry describing the inlined function.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCPSEUDOPROBE_H
+#define LLVM_MC_MCPSEUDOPROBE_H
+
+#include "llvm/ADT/MapVector.h"
+#include "llvm/MC/MCSection.h"
+#include <functional>
+#include <map>
+#include <vector>
+
+namespace llvm {
+
+class MCStreamer;
+class MCSymbol;
+class MCObjectStreamer;
+
+enum class MCPseudoProbeFlag {
+ // If set, indicates that the probe is encoded as an address delta
+ // instead of a real code address.
+ AddressDelta = 0x1,
+};
+
+/// Instances of this class represent a pseudo probe instance for a pseudo probe
+/// table entry, which is created during a machine instruction is assembled and
+/// uses an address from a temporary label created at the current address in the
+/// current section.
+class MCPseudoProbe {
+ MCSymbol *Label;
+ uint64_t Guid;
+ uint64_t Index;
+ uint8_t Type;
+ uint8_t Attributes;
+
+public:
+ MCPseudoProbe(MCSymbol *Label, uint64_t Guid, uint64_t Index, uint64_t Type,
+ uint64_t Attributes)
+ : Label(Label), Guid(Guid), Index(Index), Type(Type),
+ Attributes(Attributes) {
+ assert(Type <= 0xFF && "Probe type too big to encode, exceeding 2^8");
+ assert(Attributes <= 0xFF &&
+ "Probe attributes too big to encode, exceeding 2^16");
+ }
+
+ MCSymbol *getLabel() const { return Label; }
+
+ uint64_t getGuid() const { return Guid; }
+
+ uint64_t getIndex() const { return Index; }
+
+ uint8_t getType() const { return Type; }
+
+ uint8_t getAttributes() const { return Attributes; }
+
+ void emit(MCObjectStreamer *MCOS, const MCPseudoProbe *LastProbe) const;
+};
+
+// An inline frame has the form <Guid, ProbeID>
+using InlineSite = std::tuple<uint64_t, uint32_t>;
+using MCPseudoProbeInlineStack = SmallVector<InlineSite, 8>;
+
+// A Tri-tree based data structure to group probes by inline stack.
+// A tree is allocated for a standalone .text section. A fake
+// instance is created as the root of a tree.
+// A real instance of this class is created for each function, either an
+// unlined function that has code in .text section or an inlined function.
+class MCPseudoProbeInlineTree {
+ uint64_t Guid;
+ // Set of probes that come with the function.
+ std::vector<MCPseudoProbe> Probes;
+ // Use std::map for a deterministic output.
+ std::map<InlineSite, MCPseudoProbeInlineTree *> Inlinees;
+
+ // Root node has a GUID 0.
+ bool isRoot() { return Guid == 0; }
+ MCPseudoProbeInlineTree *getOrAddNode(InlineSite Site);
+
+public:
+ MCPseudoProbeInlineTree() = default;
+ MCPseudoProbeInlineTree(uint64_t Guid) : Guid(Guid) {}
+ ~MCPseudoProbeInlineTree();
+ void addPseudoProbe(const MCPseudoProbe &Probe,
+ const MCPseudoProbeInlineStack &InlineStack);
+ void emit(MCObjectStreamer *MCOS, const MCPseudoProbe *&LastProbe);
+};
+
+/// Instances of this class represent the pseudo probes inserted into a compile
+/// unit.
+class MCPseudoProbeSection {
+public:
+ void addPseudoProbe(MCSection *Sec, const MCPseudoProbe &Probe,
+ const MCPseudoProbeInlineStack &InlineStack) {
+ MCProbeDivisions[Sec].addPseudoProbe(Probe, InlineStack);
+ }
+
+ // TODO: Sort by getOrdinal to ensure a determinstic section order
+ using MCProbeDivisionMap = std::map<MCSection *, MCPseudoProbeInlineTree>;
+
+private:
+ // A collection of MCPseudoProbe for each text section. The MCPseudoProbes
+ // are grouped by GUID of the functions where they are from and will be
+ // encoded by groups. In the comdat scenario where a text section really only
+ // contains the code of a function solely, the probes associated with a comdat
+ // function are still grouped by GUIDs due to inlining that can bring probes
+ // from different functions into one function.
+ MCProbeDivisionMap MCProbeDivisions;
+
+public:
+ const MCProbeDivisionMap &getMCProbes() const { return MCProbeDivisions; }
+
+ bool empty() const { return MCProbeDivisions.empty(); }
+
+ void emit(MCObjectStreamer *MCOS);
+};
+
+class MCPseudoProbeTable {
+ // A collection of MCPseudoProbe in the current module grouped by text
+ // sections. MCPseudoProbes will be encoded into a corresponding
+ // .pseudoprobe section. With functions emitted as separate comdats,
+ // a text section really only contains the code of a function solely, and the
+ // probes associated with the text section will be emitted into a standalone
+ // .pseudoprobe section that shares the same comdat group with the function.
+ MCPseudoProbeSection MCProbeSections;
+
+public:
+ static void emit(MCObjectStreamer *MCOS);
+
+ MCPseudoProbeSection &getProbeSections() { return MCProbeSections; }
+
+#ifndef NDEBUG
+ static int DdgPrintIndent;
+#endif
+};
+} // end namespace llvm
+
+#endif // LLVM_MC_MCPSEUDOPROBE_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCRegister.h b/contrib/libs/llvm12/include/llvm/MC/MCRegister.h
index 92d36e2e87..2d9bd6ff08 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCRegister.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCRegister.h
@@ -27,7 +27,7 @@ using MCPhysReg = uint16_t;
/// Wrapper class representing physical registers. Should be passed by value.
class MCRegister {
- friend hash_code hash_value(const MCRegister &);
+ friend hash_code hash_value(const MCRegister &);
unsigned Reg;
public:
@@ -55,25 +55,25 @@ public:
/// Register::isStackSlot() for the more information on them.
///
static bool isStackSlot(unsigned Reg) {
- return FirstStackSlot <= Reg && Reg < VirtualRegFlag;
+ return FirstStackSlot <= Reg && Reg < VirtualRegFlag;
}
/// Return true if the specified register number is in
/// the physical register namespace.
static bool isPhysicalRegister(unsigned Reg) {
- return FirstPhysicalReg <= Reg && Reg < FirstStackSlot;
+ return FirstPhysicalReg <= Reg && Reg < FirstStackSlot;
}
constexpr operator unsigned() const {
return Reg;
}
- /// Check the provided unsigned value is a valid MCRegister.
- static MCRegister from(unsigned Val) {
- assert(Val == NoRegister || isPhysicalRegister(Val));
- return MCRegister(Val);
- }
-
+ /// Check the provided unsigned value is a valid MCRegister.
+ static MCRegister from(unsigned Val) {
+ assert(Val == NoRegister || isPhysicalRegister(Val));
+ return MCRegister(Val);
+ }
+
unsigned id() const {
return Reg;
}
@@ -113,10 +113,10 @@ template<> struct DenseMapInfo<MCRegister> {
}
};
-inline hash_code hash_value(const MCRegister &Reg) {
- return hash_value(Reg.id());
+inline hash_code hash_value(const MCRegister &Reg) {
+ return hash_value(Reg.id());
+}
}
-}
#endif // ifndef LLVM_MC_REGISTER_H
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCRegisterInfo.h b/contrib/libs/llvm12/include/llvm/MC/MCRegisterInfo.h
index 8c53307820..4f6997edd6 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCRegisterInfo.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCRegisterInfo.h
@@ -682,7 +682,7 @@ public:
MCRegUnitIterator(MCRegister Reg, const MCRegisterInfo *MCRI) {
assert(Reg && "Null register has no regunits");
- assert(MCRegister::isPhysicalRegister(Reg.id()));
+ assert(MCRegister::isPhysicalRegister(Reg.id()));
// Decode the RegUnits MCRegisterDesc field.
unsigned RU = MCRI->get(Reg).RegUnits;
unsigned Scale = RU & 15;
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCSchedule.h b/contrib/libs/llvm12/include/llvm/MC/MCSchedule.h
index fe04d31dd2..efe15a2eff 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCSchedule.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCSchedule.h
@@ -212,7 +212,7 @@ struct MCExtraProcessorInfo {
/// 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
-/// scheduling heuristics and aren't sufficiently represented in the abstract.
+/// scheduling 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
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCSectionXCOFF.h b/contrib/libs/llvm12/include/llvm/MC/MCSectionXCOFF.h
index 9ced2fcb26..8382900211 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCSectionXCOFF.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCSectionXCOFF.h
@@ -43,21 +43,21 @@ class MCSectionXCOFF final : public MCSection {
XCOFF::SymbolType Type;
MCSymbolXCOFF *const QualName;
StringRef SymbolTableName;
- bool MultiSymbolsAllowed;
+ bool MultiSymbolsAllowed;
static constexpr unsigned DefaultAlignVal = 4;
MCSectionXCOFF(StringRef Name, XCOFF::StorageMappingClass SMC,
- XCOFF::SymbolType ST, SectionKind K, MCSymbolXCOFF *QualName,
- MCSymbol *Begin, StringRef SymbolTableName,
- bool MultiSymbolsAllowed)
+ XCOFF::SymbolType ST, SectionKind K, MCSymbolXCOFF *QualName,
+ MCSymbol *Begin, StringRef SymbolTableName,
+ bool MultiSymbolsAllowed)
: MCSection(SV_XCOFF, Name, K, Begin), MappingClass(SMC), Type(ST),
- QualName(QualName), SymbolTableName(SymbolTableName),
- MultiSymbolsAllowed(MultiSymbolsAllowed) {
+ QualName(QualName), SymbolTableName(SymbolTableName),
+ MultiSymbolsAllowed(MultiSymbolsAllowed) {
assert((ST == XCOFF::XTY_SD || ST == XCOFF::XTY_CM || ST == XCOFF::XTY_ER) &&
"Invalid or unhandled type for csect.");
assert(QualName != nullptr && "QualName is needed.");
QualName->setRepresentedCsect(this);
- QualName->setStorageClass(XCOFF::C_HIDEXT);
+ QualName->setStorageClass(XCOFF::C_HIDEXT);
// A csect is 4 byte aligned by default, except for undefined symbol csects.
if (Type != XCOFF::XTY_ER)
setAlignment(Align(DefaultAlignVal));
@@ -73,9 +73,9 @@ public:
}
XCOFF::StorageMappingClass getMappingClass() const { return MappingClass; }
- XCOFF::StorageClass getStorageClass() const {
- return QualName->getStorageClass();
- }
+ XCOFF::StorageClass getStorageClass() const {
+ return QualName->getStorageClass();
+ }
XCOFF::SymbolType getCSectType() const { return Type; }
MCSymbolXCOFF *getQualNameSymbol() const { return QualName; }
@@ -85,7 +85,7 @@ public:
bool UseCodeAlign() const override;
bool isVirtualSection() const override;
StringRef getSymbolTableName() const { return SymbolTableName; }
- bool isMultiSymbolsAllowed() const { return MultiSymbolsAllowed; }
+ bool isMultiSymbolsAllowed() const { return MultiSymbolsAllowed; }
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCStreamer.h b/contrib/libs/llvm12/include/llvm/MC/MCStreamer.h
index 4bc2f50c04..4802d6cb35 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCStreamer.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCStreamer.h
@@ -20,7 +20,7 @@
#ifndef LLVM_MC_MCSTREAMER_H
#define LLVM_MC_MCSTREAMER_H
-#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
@@ -28,7 +28,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCLinkerOptimizationHint.h"
-#include "llvm/MC/MCPseudoProbe.h"
+#include "llvm/MC/MCPseudoProbe.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCWinEH.h"
#include "llvm/Support/Error.h"
@@ -214,7 +214,7 @@ class MCStreamer {
std::vector<std::unique_ptr<WinEH::FrameInfo>> WinFrameInfos;
WinEH::FrameInfo *CurrentWinFrameInfo;
- size_t CurrentProcWinFrameInfoStartIndex;
+ size_t CurrentProcWinFrameInfoStartIndex;
/// Tracks an index to represent the order a symbol was emitted in.
/// Zero means we did not emit that symbol.
@@ -224,10 +224,10 @@ class MCStreamer {
/// PushSection.
SmallVector<std::pair<MCSectionSubPair, MCSectionSubPair>, 4> SectionStack;
- /// Pointer to the parser's SMLoc if available. This is used to provide
- /// locations for diagnostics.
- const SMLoc *StartTokLocPtr = nullptr;
-
+ /// Pointer to the parser's SMLoc if available. This is used to provide
+ /// locations for diagnostics.
+ const SMLoc *StartTokLocPtr = nullptr;
+
/// The next unique ID to use when creating a WinCFI-related section (.pdata
/// or .xdata). This ID ensures that we have a one-to-one mapping from
/// code section to unwind info section, which MSVC's incremental linker
@@ -253,8 +253,8 @@ protected:
return CurrentWinFrameInfo;
}
- virtual void EmitWindowsUnwindTables(WinEH::FrameInfo *Frame);
-
+ virtual void EmitWindowsUnwindTables(WinEH::FrameInfo *Frame);
+
virtual void EmitWindowsUnwindTables();
virtual void emitRawTextImpl(StringRef String);
@@ -274,11 +274,11 @@ public:
TargetStreamer.reset(TS);
}
- void setStartTokLocPtr(const SMLoc *Loc) { StartTokLocPtr = Loc; }
- SMLoc getStartTokLoc() const {
- return StartTokLocPtr ? *StartTokLocPtr : SMLoc();
- }
-
+ void setStartTokLocPtr(const SMLoc *Loc) { StartTokLocPtr = Loc; }
+ SMLoc getStartTokLoc() const {
+ return StartTokLocPtr ? *StartTokLocPtr : SMLoc();
+ }
+
/// State management
///
virtual void reset();
@@ -463,10 +463,10 @@ public:
/// so we can sort on them later.
void AssignFragment(MCSymbol *Symbol, MCFragment *Fragment);
- /// Returns the mnemonic for \p MI, if the streamer has access to a
- /// instruction printer and returns an empty string otherwise.
- virtual StringRef getMnemonic(MCInst &MI) { return ""; }
-
+ /// Returns the mnemonic for \p MI, if the streamer has access to a
+ /// instruction printer and returns an empty string otherwise.
+ virtual StringRef getMnemonic(MCInst &MI) { return ""; }
+
/// Emit a label for \p Symbol into the current section.
///
/// This corresponds to an assembler statement such as:
@@ -698,7 +698,7 @@ public:
/// 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);
- virtual void emitIntValue(APInt Value);
+ virtual void emitIntValue(APInt Value);
/// Special case of EmitValue that avoids the client having to pass
/// in a MCExpr for constant integers & prints in Hex format for certain
@@ -803,9 +803,9 @@ public:
virtual void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
SMLoc Loc = SMLoc());
- virtual void emitNops(int64_t NumBytes, int64_t ControlledNopLength,
- SMLoc Loc);
-
+ virtual void emitNops(int64_t NumBytes, int64_t ControlledNopLength,
+ SMLoc Loc);
+
/// Emit NumBytes worth of zeros.
/// This function properly handles data in virtual sections.
void emitZeros(uint64_t NumBytes);
@@ -1057,11 +1057,11 @@ public:
/// Emit the given \p Instruction into the current section.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI);
- /// Emit the a pseudo probe into the current section.
- virtual void emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type,
- uint64_t Attr,
- const MCPseudoProbeInlineStack &InlineStack);
-
+ /// Emit the a pseudo probe into the current section.
+ virtual void emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type,
+ uint64_t Attr,
+ const MCPseudoProbeInlineStack &InlineStack);
+
/// 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.
@@ -1084,7 +1084,7 @@ public:
/// Streamer specific finalization.
virtual void finishImpl();
/// Finish emission of machine code.
- void Finish(SMLoc EndLoc = SMLoc());
+ void Finish(SMLoc EndLoc = SMLoc());
virtual bool mayHaveInstructions(MCSection &Sec) const { return true; }
};
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCSubtargetInfo.h b/contrib/libs/llvm12/include/llvm/MC/MCSubtargetInfo.h
index f6d9137599..b197f603bd 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCSubtargetInfo.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCSubtargetInfo.h
@@ -61,7 +61,7 @@ struct SubtargetFeatureKV {
struct SubtargetSubTypeKV {
const char *Key; ///< K-V key string
FeatureBitArray Implies; ///< K-V bit mask
- FeatureBitArray TuneImplies; ///< K-V bit mask
+ FeatureBitArray TuneImplies; ///< K-V bit mask
const MCSchedModel *SchedModel;
/// Compare routine for std::lower_bound
@@ -82,7 +82,7 @@ struct SubtargetSubTypeKV {
class MCSubtargetInfo {
Triple TargetTriple;
std::string CPU; // CPU being targeted.
- std::string TuneCPU; // CPU being tuned for.
+ std::string TuneCPU; // CPU being tuned for.
ArrayRef<SubtargetFeatureKV> ProcFeatures; // Processor feature list
ArrayRef<SubtargetSubTypeKV> ProcDesc; // Processor descriptions
@@ -99,8 +99,8 @@ class MCSubtargetInfo {
public:
MCSubtargetInfo(const MCSubtargetInfo &) = default;
- MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef TuneCPU,
- StringRef FS, ArrayRef<SubtargetFeatureKV> PF,
+ MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef TuneCPU,
+ StringRef FS, ArrayRef<SubtargetFeatureKV> PF,
ArrayRef<SubtargetSubTypeKV> PD,
const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL,
const MCReadAdvanceEntry *RA, const InstrStage *IS,
@@ -112,7 +112,7 @@ public:
const Triple &getTargetTriple() const { return TargetTriple; }
StringRef getCPU() const { return CPU; }
- StringRef getTuneCPU() const { return TuneCPU; }
+ StringRef getTuneCPU() const { return TuneCPU; }
const FeatureBitset& getFeatureBits() const { return FeatureBits; }
void setFeatureBits(const FeatureBitset &FeatureBits_) {
@@ -128,12 +128,12 @@ protected:
///
/// FIXME: Find a way to stick this in the constructor, since it should only
/// be called during initialization.
- void InitMCProcessorInfo(StringRef CPU, StringRef TuneCPU, StringRef FS);
+ void InitMCProcessorInfo(StringRef CPU, StringRef TuneCPU, StringRef FS);
public:
- /// Set the features to the default for the given CPU and TuneCPU, with ano
- /// appended feature string.
- void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
+ /// Set the features to the default for the given CPU and TuneCPU, with ano
+ /// appended feature string.
+ void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
/// Toggle a feature and return the re-computed feature bits.
/// This version does not change the implied bits.
@@ -220,16 +220,16 @@ public:
void initInstrItins(InstrItineraryData &InstrItins) const;
/// Resolve a variant scheduling class for the given MCInst and CPU.
- virtual unsigned resolveVariantSchedClass(unsigned SchedClass,
- const MCInst *MI,
- const MCInstrInfo *MCII,
- unsigned CPUID) const {
+ virtual unsigned resolveVariantSchedClass(unsigned SchedClass,
+ const MCInst *MI,
+ const MCInstrInfo *MCII,
+ unsigned CPUID) const {
return 0;
}
/// Check whether the CPU string is valid.
bool isCPUStringValid(StringRef CPU) const {
- auto Found = llvm::lower_bound(ProcDesc, CPU);
+ auto Found = llvm::lower_bound(ProcDesc, CPU);
return Found != ProcDesc.end() && StringRef(Found->Key) == CPU;
}
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCSymbol.h b/contrib/libs/llvm12/include/llvm/MC/MCSymbol.h
index 739267eea0..e87e24c0a9 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCSymbol.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCSymbol.h
@@ -23,7 +23,7 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFragment.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
@@ -101,8 +101,8 @@ protected:
mutable unsigned IsRegistered : 1;
- /// True if this symbol is visible outside this translation unit. Note: ELF
- /// uses binding instead of this bit.
+ /// True if this symbol is visible outside this translation unit. Note: ELF
+ /// uses binding instead of this bit.
mutable unsigned IsExternal : 1;
/// This symbol is private extern.
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCSymbolWasm.h b/contrib/libs/llvm12/include/llvm/MC/MCSymbolWasm.h
index 6812b57334..9f84b82191 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCSymbolWasm.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCSymbolWasm.h
@@ -32,7 +32,7 @@ class MCSymbolWasm : public MCSymbol {
Optional<StringRef> ExportName;
wasm::WasmSignature *Signature = nullptr;
Optional<wasm::WasmGlobalType> GlobalType;
- Optional<wasm::ValType> TableType;
+ Optional<wasm::ValType> TableType;
Optional<wasm::WasmEventType> EventType;
/// An expression describing how to calculate the size of a symbol. If a
@@ -50,7 +50,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 isTable() const { return Type == wasm::WASM_SYMBOL_TYPE_TABLE; }
+ bool isTable() const { return Type == wasm::WASM_SYMBOL_TYPE_TABLE; }
bool isSection() const { return Type == wasm::WASM_SYMBOL_TYPE_SECTION; }
bool isEvent() const { return Type == wasm::WASM_SYMBOL_TYPE_EVENT; }
wasm::WasmSymbolType getType() const { return Type; }
@@ -103,15 +103,15 @@ public:
StringRef getExportName() const { return ExportName.getValue(); }
void setExportName(StringRef Name) { ExportName = Name; }
- bool isFunctionTable() const {
- return isTable() && hasTableType() &&
- getTableType() == wasm::ValType::FUNCREF;
- }
- void setFunctionTable() {
- setType(wasm::WASM_SYMBOL_TYPE_TABLE);
- setTableType(wasm::ValType::FUNCREF);
- }
-
+ bool isFunctionTable() const {
+ return isTable() && hasTableType() &&
+ getTableType() == wasm::ValType::FUNCREF;
+ }
+ void setFunctionTable() {
+ setType(wasm::WASM_SYMBOL_TYPE_TABLE);
+ setTableType(wasm::ValType::FUNCREF);
+ }
+
void setUsedInGOT() const { IsUsedInGOT = true; }
bool isUsedInGOT() const { return IsUsedInGOT; }
@@ -127,13 +127,13 @@ public:
}
void setGlobalType(wasm::WasmGlobalType GT) { GlobalType = GT; }
- bool hasTableType() const { return TableType.hasValue(); }
- wasm::ValType getTableType() const {
- assert(hasTableType());
- return TableType.getValue();
- }
- void setTableType(wasm::ValType TT) { TableType = TT; }
-
+ bool hasTableType() const { return TableType.hasValue(); }
+ wasm::ValType getTableType() const {
+ assert(hasTableType());
+ return TableType.getValue();
+ }
+ void setTableType(wasm::ValType TT) { TableType = TT; }
+
const wasm::WasmEventType &getEventType() const {
assert(EventType.hasValue());
return EventType.getValue();
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCTargetOptions.h b/contrib/libs/llvm12/include/llvm/MC/MCTargetOptions.h
index a9999d727f..fb097bf912 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCTargetOptions.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCTargetOptions.h
@@ -29,7 +29,7 @@ enum class ExceptionHandling {
ARM, ///< ARM EHABI
WinEH, ///< Windows Exception Handling
Wasm, ///< WebAssembly Exception Handling
- AIX, ///< AIX Exception Handling
+ AIX, ///< AIX Exception Handling
};
enum class DebugCompressionType {
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCWasmObjectWriter.h b/contrib/libs/llvm12/include/llvm/MC/MCWasmObjectWriter.h
index 9c91c37b59..112bb19b93 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCWasmObjectWriter.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCWasmObjectWriter.h
@@ -59,10 +59,10 @@ std::unique_ptr<MCObjectWriter>
createWasmObjectWriter(std::unique_ptr<MCWasmObjectTargetWriter> MOTW,
raw_pwrite_stream &OS);
-std::unique_ptr<MCObjectWriter>
-createWasmDwoObjectWriter(std::unique_ptr<MCWasmObjectTargetWriter> MOTW,
- raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS);
-
+std::unique_ptr<MCObjectWriter>
+createWasmDwoObjectWriter(std::unique_ptr<MCWasmObjectTargetWriter> MOTW,
+ raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS);
+
} // namespace llvm
#endif
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCWin64EH.h b/contrib/libs/llvm12/include/llvm/MC/MCWin64EH.h
index 8abc939974..a7993d8304 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCWin64EH.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCWin64EH.h
@@ -60,15 +60,15 @@ struct Instruction {
class UnwindEmitter : public WinEH::UnwindEmitter {
public:
void Emit(MCStreamer &Streamer) const override;
- void EmitUnwindInfo(MCStreamer &Streamer, WinEH::FrameInfo *FI,
- bool HandlerData) const override;
+ void EmitUnwindInfo(MCStreamer &Streamer, WinEH::FrameInfo *FI,
+ bool HandlerData) const override;
};
class ARM64UnwindEmitter : public WinEH::UnwindEmitter {
public:
void Emit(MCStreamer &Streamer) const override;
- void EmitUnwindInfo(MCStreamer &Streamer, WinEH::FrameInfo *FI,
- bool HandlerData) const override;
+ void EmitUnwindInfo(MCStreamer &Streamer, WinEH::FrameInfo *FI,
+ bool HandlerData) const override;
};
}
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCWinCOFFStreamer.h b/contrib/libs/llvm12/include/llvm/MC/MCWinCOFFStreamer.h
index a3e4bd74a2..8fb135c08e 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCWinCOFFStreamer.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCWinCOFFStreamer.h
@@ -65,7 +65,7 @@ public:
unsigned ByteAlignment) override;
void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
- void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
+ void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
void emitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment, SMLoc Loc = SMLoc()) override;
void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
diff --git a/contrib/libs/llvm12/include/llvm/MC/MCWinEH.h b/contrib/libs/llvm12/include/llvm/MC/MCWinEH.h
index 9ebb76d3d4..2143a40baa 100644
--- a/contrib/libs/llvm12/include/llvm/MC/MCWinEH.h
+++ b/contrib/libs/llvm12/include/llvm/MC/MCWinEH.h
@@ -33,14 +33,14 @@ struct Instruction {
Instruction(unsigned Op, MCSymbol *L, unsigned Reg, unsigned Off)
: Label(L), Offset(Off), Register(Reg), Operation(Op) {}
-
- bool operator==(const Instruction &I) const {
- // Check whether two instructions refer to the same operation
- // applied at a different spot (i.e. pointing at a different label).
- return Offset == I.Offset && Register == I.Register &&
- Operation == I.Operation;
- }
- bool operator!=(const Instruction &I) const { return !(*this == I); }
+
+ bool operator==(const Instruction &I) const {
+ // Check whether two instructions refer to the same operation
+ // applied at a different spot (i.e. pointing at a different label).
+ return Offset == I.Offset && Register == I.Register &&
+ Operation == I.Operation;
+ }
+ bool operator!=(const Instruction &I) const { return !(*this == I); }
};
struct FrameInfo {
@@ -51,12 +51,12 @@ struct FrameInfo {
const MCSymbol *Function = nullptr;
const MCSymbol *PrologEnd = nullptr;
const MCSymbol *Symbol = nullptr;
- MCSection *TextSection = nullptr;
- uint32_t PackedInfo = 0;
+ MCSection *TextSection = nullptr;
+ uint32_t PackedInfo = 0;
bool HandlesUnwind = false;
bool HandlesExceptions = false;
- bool EmitAttempted = false;
+ bool EmitAttempted = false;
int LastFrameInst = -1;
const FrameInfo *ChainedParent = nullptr;
@@ -70,15 +70,15 @@ struct FrameInfo {
const FrameInfo *ChainedParent)
: Begin(BeginFuncEHLabel), Function(Function),
ChainedParent(ChainedParent) {}
-
- bool empty() const {
- if (!Instructions.empty())
- return false;
- for (const auto &E : EpilogMap)
- if (!E.second.empty())
- return false;
- return true;
- }
+
+ bool empty() const {
+ if (!Instructions.empty())
+ return false;
+ for (const auto &E : EpilogMap)
+ if (!E.second.empty())
+ return false;
+ return true;
+ }
};
class UnwindEmitter {
@@ -87,8 +87,8 @@ public:
/// This emits the unwind info sections (.pdata and .xdata in PE/COFF).
virtual void Emit(MCStreamer &Streamer) const = 0;
- virtual void EmitUnwindInfo(MCStreamer &Streamer, FrameInfo *FI,
- bool HandlerData) const = 0;
+ virtual void EmitUnwindInfo(MCStreamer &Streamer, FrameInfo *FI,
+ bool HandlerData) const = 0;
};
}
}
diff --git a/contrib/libs/llvm12/include/llvm/MC/StringTableBuilder.h b/contrib/libs/llvm12/include/llvm/MC/StringTableBuilder.h
index 6512654052..f731b06153 100644
--- a/contrib/libs/llvm12/include/llvm/MC/StringTableBuilder.h
+++ b/contrib/libs/llvm12/include/llvm/MC/StringTableBuilder.h
@@ -29,17 +29,17 @@ class raw_ostream;
/// Utility for building string tables with deduplicated suffixes.
class StringTableBuilder {
public:
- enum Kind {
- ELF,
- WinCOFF,
- MachO,
- MachO64,
- MachOLinked,
- MachO64Linked,
- RAW,
- DWARF,
- XCOFF
- };
+ enum Kind {
+ ELF,
+ WinCOFF,
+ MachO,
+ MachO64,
+ MachOLinked,
+ MachO64Linked,
+ RAW,
+ DWARF,
+ XCOFF
+ };
private:
DenseMap<CachedHashStringRef, size_t> StringIndexMap;
diff --git a/contrib/libs/llvm12/include/llvm/MC/SubtargetFeature.h b/contrib/libs/llvm12/include/llvm/MC/SubtargetFeature.h
index 2f5202860e..2d534b7bbf 100644
--- a/contrib/libs/llvm12/include/llvm/MC/SubtargetFeature.h
+++ b/contrib/libs/llvm12/include/llvm/MC/SubtargetFeature.h
@@ -37,7 +37,7 @@ namespace llvm {
class raw_ostream;
class Triple;
-const unsigned MAX_SUBTARGET_WORDS = 4;
+const unsigned MAX_SUBTARGET_WORDS = 4;
const unsigned MAX_SUBTARGET_FEATURES = MAX_SUBTARGET_WORDS * 64;
/// Container class for subtarget features.
diff --git a/contrib/libs/llvm12/include/llvm/MCA/HardwareUnits/Scheduler.h b/contrib/libs/llvm12/include/llvm/MCA/HardwareUnits/Scheduler.h
index 437f6c595e..92d34e5f31 100644
--- a/contrib/libs/llvm12/include/llvm/MCA/HardwareUnits/Scheduler.h
+++ b/contrib/libs/llvm12/include/llvm/MCA/HardwareUnits/Scheduler.h
@@ -274,9 +274,9 @@ public:
// This routine performs a sanity check. This routine should only be called
// when we know that 'IR' is not in the scheduler's instruction queues.
void sanityCheck(const InstRef &IR) const {
- assert(!is_contained(WaitSet, IR) && "Already in the wait set!");
- assert(!is_contained(ReadySet, IR) && "Already in the ready set!");
- assert(!is_contained(IssuedSet, IR) && "Already executing!");
+ assert(!is_contained(WaitSet, IR) && "Already in the wait set!");
+ assert(!is_contained(ReadySet, IR) && "Already in the ready set!");
+ assert(!is_contained(IssuedSet, IR) && "Already executing!");
}
#endif // !NDEBUG
};
diff --git a/contrib/libs/llvm12/include/llvm/Object/ArchiveWriter.h b/contrib/libs/llvm12/include/llvm/Object/ArchiveWriter.h
index f07fbede22..a2c582c480 100644
--- a/contrib/libs/llvm12/include/llvm/Object/ArchiveWriter.h
+++ b/contrib/libs/llvm12/include/llvm/Object/ArchiveWriter.h
@@ -46,12 +46,12 @@ Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
bool WriteSymtab, object::Archive::Kind Kind,
bool Deterministic, bool Thin,
std::unique_ptr<MemoryBuffer> OldArchiveBuf = nullptr);
-
-// writeArchiveToBuffer is similar to writeArchive but returns the Archive in a
-// buffer instead of writing it out to a file.
-Expected<std::unique_ptr<MemoryBuffer>>
-writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers, bool WriteSymtab,
- object::Archive::Kind Kind, bool Deterministic, bool Thin);
+
+// writeArchiveToBuffer is similar to writeArchive but returns the Archive in a
+// buffer instead of writing it out to a file.
+Expected<std::unique_ptr<MemoryBuffer>>
+writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers, bool WriteSymtab,
+ object::Archive::Kind Kind, bool Deterministic, bool Thin);
}
#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/Binary.h b/contrib/libs/llvm12/include/llvm/Object/Binary.h
index 70dc19e21b..0b1ee8456b 100644
--- a/contrib/libs/llvm12/include/llvm/Object/Binary.h
+++ b/contrib/libs/llvm12/include/llvm/Object/Binary.h
@@ -98,8 +98,8 @@ public:
Binary(const Binary &other) = delete;
virtual ~Binary();
- virtual Error initContent() { return Error::success(); };
-
+ virtual Error initContent() { return Error::success(); };
+
StringRef getData() const;
StringRef getFileName() const;
MemoryBufferRef getMemoryBufferRef() const;
@@ -172,8 +172,8 @@ public:
static Error checkOffset(MemoryBufferRef M, uintptr_t Addr,
const uint64_t Size) {
if (Addr + Size < Addr || Addr + Size < Size ||
- Addr + Size > reinterpret_cast<uintptr_t>(M.getBufferEnd()) ||
- Addr < reinterpret_cast<uintptr_t>(M.getBufferStart())) {
+ Addr + Size > reinterpret_cast<uintptr_t>(M.getBufferEnd()) ||
+ Addr < reinterpret_cast<uintptr_t>(M.getBufferStart())) {
return errorCodeToError(object_error::unexpected_eof);
}
return Error::success();
@@ -187,8 +187,8 @@ DEFINE_ISA_CONVERSION_FUNCTIONS(Binary, LLVMBinaryRef)
///
/// @param Source The data to create the Binary from.
Expected<std::unique_ptr<Binary>> createBinary(MemoryBufferRef Source,
- LLVMContext *Context = nullptr,
- bool InitContent = true);
+ LLVMContext *Context = nullptr,
+ bool InitContent = true);
template <typename T> class OwningBinary {
std::unique_ptr<T> Bin;
@@ -238,9 +238,9 @@ template <typename T> const T* OwningBinary<T>::getBinary() const {
return Bin.get();
}
-Expected<OwningBinary<Binary>> createBinary(StringRef Path,
- LLVMContext *Context = nullptr,
- bool InitContent = true);
+Expected<OwningBinary<Binary>> createBinary(StringRef Path,
+ LLVMContext *Context = nullptr,
+ bool InitContent = true);
} // end namespace object
diff --git a/contrib/libs/llvm12/include/llvm/Object/COFF.h b/contrib/libs/llvm12/include/llvm/Object/COFF.h
index 4c62889569..816a078cfc 100644
--- a/contrib/libs/llvm12/include/llvm/Object/COFF.h
+++ b/contrib/libs/llvm12/include/llvm/Object/COFF.h
@@ -583,22 +583,22 @@ struct coff_tls_directory {
uint32_t getAlignment() const {
// Bit [20:24] contains section alignment.
- uint32_t Shift = (Characteristics & COFF::IMAGE_SCN_ALIGN_MASK) >> 20;
+ uint32_t Shift = (Characteristics & COFF::IMAGE_SCN_ALIGN_MASK) >> 20;
if (Shift > 0)
return 1U << (Shift - 1);
return 0;
}
-
- void setAlignment(uint32_t Align) {
- uint32_t AlignBits = 0;
- if (Align) {
- assert(llvm::isPowerOf2_32(Align) && "alignment is not a power of 2");
- assert(llvm::Log2_32(Align) <= 13 && "alignment requested is too large");
- AlignBits = (llvm::Log2_32(Align) + 1) << 20;
- }
- Characteristics =
- (Characteristics & ~COFF::IMAGE_SCN_ALIGN_MASK) | AlignBits;
- }
+
+ void setAlignment(uint32_t Align) {
+ uint32_t AlignBits = 0;
+ if (Align) {
+ assert(llvm::isPowerOf2_32(Align) && "alignment is not a power of 2");
+ assert(llvm::Log2_32(Align) <= 13 && "alignment requested is too large");
+ AlignBits = (llvm::Log2_32(Align) + 1) << 20;
+ }
+ Characteristics =
+ (Characteristics & ~COFF::IMAGE_SCN_ALIGN_MASK) | AlignBits;
+ }
};
using coff_tls_directory32 = coff_tls_directory<support::little32_t>;
@@ -804,8 +804,8 @@ private:
const coff_base_reloc_block_header *BaseRelocEnd;
const debug_directory *DebugDirectoryBegin;
const debug_directory *DebugDirectoryEnd;
- const coff_tls_directory32 *TLSDirectory32;
- const coff_tls_directory64 *TLSDirectory64;
+ const coff_tls_directory32 *TLSDirectory32;
+ const coff_tls_directory64 *TLSDirectory64;
// Either coff_load_configuration32 or coff_load_configuration64.
const void *LoadConfig = nullptr;
@@ -825,7 +825,7 @@ private:
Error initExportTablePtr();
Error initBaseRelocPtr();
Error initDebugDirectoryPtr();
- Error initTLSDirectoryPtr();
+ Error initTLSDirectoryPtr();
Error initLoadConfigPtr();
public:
@@ -997,13 +997,13 @@ public:
return make_range(debug_directory_begin(), debug_directory_end());
}
- const coff_tls_directory32 *getTLSDirectory32() const {
- return TLSDirectory32;
- }
- const coff_tls_directory64 *getTLSDirectory64() const {
- return TLSDirectory64;
- }
-
+ const coff_tls_directory32 *getTLSDirectory32() const {
+ return TLSDirectory32;
+ }
+ const coff_tls_directory64 *getTLSDirectory64() const {
+ return TLSDirectory64;
+ }
+
const dos_header *getDOSHeader() const {
if (!PE32Header && !PE32PlusHeader)
return nullptr;
diff --git a/contrib/libs/llvm12/include/llvm/Object/ELF.h b/contrib/libs/llvm12/include/llvm/Object/ELF.h
index e68397b898..20e25a9ee2 100644
--- a/contrib/libs/llvm12/include/llvm/Object/ELF.h
+++ b/contrib/libs/llvm12/include/llvm/Object/ELF.h
@@ -37,43 +37,43 @@
namespace llvm {
namespace object {
-struct VerdAux {
- unsigned Offset;
- std::string Name;
-};
-
-struct VerDef {
- unsigned Offset;
- unsigned Version;
- unsigned Flags;
- unsigned Ndx;
- unsigned Cnt;
- unsigned Hash;
- std::string Name;
- std::vector<VerdAux> AuxV;
-};
-
-struct VernAux {
- unsigned Hash;
- unsigned Flags;
- unsigned Other;
- unsigned Offset;
- std::string Name;
-};
-
-struct VerNeed {
- unsigned Version;
- unsigned Cnt;
- unsigned Offset;
- std::string File;
- std::vector<VernAux> AuxV;
-};
-
-struct VersionEntry {
- std::string Name;
- bool IsVerDef;
-};
-
+struct VerdAux {
+ unsigned Offset;
+ std::string Name;
+};
+
+struct VerDef {
+ unsigned Offset;
+ unsigned Version;
+ unsigned Flags;
+ unsigned Ndx;
+ unsigned Cnt;
+ unsigned Hash;
+ std::string Name;
+ std::vector<VerdAux> AuxV;
+};
+
+struct VernAux {
+ unsigned Hash;
+ unsigned Flags;
+ unsigned Other;
+ unsigned Offset;
+ std::string Name;
+};
+
+struct VerNeed {
+ unsigned Version;
+ unsigned Cnt;
+ unsigned Offset;
+ std::string File;
+ std::vector<VernAux> AuxV;
+};
+
+struct VersionEntry {
+ std::string Name;
+ bool IsVerDef;
+};
+
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type);
uint32_t getELFRelativeRelocationType(uint32_t Machine);
StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type);
@@ -92,51 +92,51 @@ static inline Error createError(const Twine &Err) {
return make_error<StringError>(Err, object_error::parse_failed);
}
-enum PPCInstrMasks : uint64_t {
- PADDI_R12_NO_DISP = 0x0610000039800000,
- PLD_R12_NO_DISP = 0x04100000E5800000,
- MTCTR_R12 = 0x7D8903A6,
- BCTR = 0x4E800420,
-};
-
+enum PPCInstrMasks : uint64_t {
+ PADDI_R12_NO_DISP = 0x0610000039800000,
+ PLD_R12_NO_DISP = 0x04100000E5800000,
+ MTCTR_R12 = 0x7D8903A6,
+ BCTR = 0x4E800420,
+};
+
template <class ELFT> class ELFFile;
-template <class T> struct DataRegion {
- // This constructor is used when we know the start and the size of a data
- // region. We assume that Arr does not go past the end of the file.
- DataRegion(ArrayRef<T> Arr) : First(Arr.data()), Size(Arr.size()) {}
-
- // Sometimes we only know the start of a data region. We still don't want to
- // read past the end of the file, so we provide the end of a buffer.
- DataRegion(const T *Data, const uint8_t *BufferEnd)
- : First(Data), BufEnd(BufferEnd) {}
-
- Expected<T> operator[](uint64_t N) {
- assert(Size || BufEnd);
- if (Size) {
- if (N >= *Size)
- return createError(
- "the index is greater than or equal to the number of entries (" +
- Twine(*Size) + ")");
- } else {
- const uint8_t *EntryStart = (const uint8_t *)First + N * sizeof(T);
- if (EntryStart + sizeof(T) > BufEnd)
- return createError("can't read past the end of the file");
- }
- return *(First + N);
- }
-
- const T *First;
- Optional<uint64_t> Size = None;
- const uint8_t *BufEnd = nullptr;
-};
-
+template <class T> struct DataRegion {
+ // This constructor is used when we know the start and the size of a data
+ // region. We assume that Arr does not go past the end of the file.
+ DataRegion(ArrayRef<T> Arr) : First(Arr.data()), Size(Arr.size()) {}
+
+ // Sometimes we only know the start of a data region. We still don't want to
+ // read past the end of the file, so we provide the end of a buffer.
+ DataRegion(const T *Data, const uint8_t *BufferEnd)
+ : First(Data), BufEnd(BufferEnd) {}
+
+ Expected<T> operator[](uint64_t N) {
+ assert(Size || BufEnd);
+ if (Size) {
+ if (N >= *Size)
+ return createError(
+ "the index is greater than or equal to the number of entries (" +
+ Twine(*Size) + ")");
+ } else {
+ const uint8_t *EntryStart = (const uint8_t *)First + N * sizeof(T);
+ if (EntryStart + sizeof(T) > BufEnd)
+ return createError("can't read past the end of the file");
+ }
+ return *(First + N);
+ }
+
+ const T *First;
+ Optional<uint64_t> Size = None;
+ const uint8_t *BufEnd = nullptr;
+};
+
template <class ELFT>
-std::string getSecIndexForError(const ELFFile<ELFT> &Obj,
- const typename ELFT::Shdr &Sec) {
- auto TableOrErr = Obj.sections();
+std::string getSecIndexForError(const ELFFile<ELFT> &Obj,
+ const typename ELFT::Shdr &Sec) {
+ auto TableOrErr = Obj.sections();
if (TableOrErr)
- return "[index " + std::to_string(&Sec - &TableOrErr->front()) + "]";
+ return "[index " + std::to_string(&Sec - &TableOrErr->front()) + "]";
// To make this helper be more convenient for error reporting purposes we
// drop the error. But really it should never be triggered. Before this point,
// our code should have called 'sections()' and reported a proper error on
@@ -146,21 +146,21 @@ std::string getSecIndexForError(const ELFFile<ELFT> &Obj,
}
template <class ELFT>
-static std::string describe(const ELFFile<ELFT> &Obj,
- const typename ELFT::Shdr &Sec) {
- unsigned SecNdx = &Sec - &cantFail(Obj.sections()).front();
- return (object::getELFSectionTypeName(Obj.getHeader().e_machine,
- Sec.sh_type) +
- " section with index " + Twine(SecNdx))
- .str();
-}
-
-template <class ELFT>
-std::string getPhdrIndexForError(const ELFFile<ELFT> &Obj,
- const typename ELFT::Phdr &Phdr) {
- auto Headers = Obj.program_headers();
+static std::string describe(const ELFFile<ELFT> &Obj,
+ const typename ELFT::Shdr &Sec) {
+ unsigned SecNdx = &Sec - &cantFail(Obj.sections()).front();
+ return (object::getELFSectionTypeName(Obj.getHeader().e_machine,
+ Sec.sh_type) +
+ " section with index " + Twine(SecNdx))
+ .str();
+}
+
+template <class ELFT>
+std::string getPhdrIndexForError(const ELFFile<ELFT> &Obj,
+ const typename ELFT::Phdr &Phdr) {
+ auto Headers = Obj.program_headers();
if (Headers)
- return ("[index " + Twine(&Phdr - &Headers->front()) + "]").str();
+ return ("[index " + Twine(&Phdr - &Headers->front()) + "]").str();
// See comment in the getSecIndexForError() above.
llvm::consumeError(Headers.takeError());
return "[unknown index]";
@@ -183,7 +183,7 @@ public:
using WarningHandler = llvm::function_ref<Error(const Twine &Msg)>;
const uint8_t *base() const { return Buf.bytes_begin(); }
- const uint8_t *end() const { return base() + getBufSize(); }
+ const uint8_t *end() const { return base() + getBufSize(); }
size_t getBufSize() const { return Buf.size(); }
@@ -193,39 +193,39 @@ private:
ELFFile(StringRef Object);
public:
- const Elf_Ehdr &getHeader() const {
- return *reinterpret_cast<const Elf_Ehdr *>(base());
+ const Elf_Ehdr &getHeader() const {
+ return *reinterpret_cast<const Elf_Ehdr *>(base());
}
template <typename T>
Expected<const T *> getEntry(uint32_t Section, uint32_t Entry) const;
template <typename T>
- Expected<const T *> getEntry(const Elf_Shdr &Section, uint32_t Entry) const;
+ Expected<const T *> getEntry(const Elf_Shdr &Section, uint32_t Entry) const;
- Expected<std::vector<VerDef>>
- getVersionDefinitions(const Elf_Shdr &Sec) const;
- Expected<std::vector<VerNeed>> getVersionDependencies(
- const Elf_Shdr &Sec,
- WarningHandler WarnHandler = &defaultWarningHandler) const;
+ Expected<std::vector<VerDef>>
+ getVersionDefinitions(const Elf_Shdr &Sec) const;
+ Expected<std::vector<VerNeed>> getVersionDependencies(
+ const Elf_Shdr &Sec,
+ WarningHandler WarnHandler = &defaultWarningHandler) const;
Expected<StringRef>
- getSymbolVersionByIndex(uint32_t SymbolVersionIndex, bool &IsDefault,
- SmallVector<Optional<VersionEntry>, 0> &VersionMap,
- Optional<bool> IsSymHidden) const;
-
- Expected<StringRef>
- getStringTable(const Elf_Shdr &Section,
+ getSymbolVersionByIndex(uint32_t SymbolVersionIndex, bool &IsDefault,
+ SmallVector<Optional<VersionEntry>, 0> &VersionMap,
+ Optional<bool> IsSymHidden) const;
+
+ Expected<StringRef>
+ getStringTable(const Elf_Shdr &Section,
WarningHandler WarnHandler = &defaultWarningHandler) const;
Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const;
Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section,
Elf_Shdr_Range Sections) const;
- Expected<StringRef> getLinkAsStrtab(const typename ELFT::Shdr &Sec) const;
+ Expected<StringRef> getLinkAsStrtab(const typename ELFT::Shdr &Sec) const;
Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section) const;
Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section,
Elf_Shdr_Range Sections) const;
- Expected<uint64_t> getDynSymtabSize() const;
-
+ Expected<uint64_t> getDynSymtabSize() const;
+
StringRef getRelocationTypeName(uint32_t Type) const;
void getRelocationTypeName(uint32_t Type,
SmallVectorImpl<char> &Result) const;
@@ -235,21 +235,21 @@ public:
std::string getDynamicTagAsString(uint64_t Type) const;
/// Get the symbol for a given relocation.
- Expected<const Elf_Sym *> getRelocationSymbol(const Elf_Rel &Rel,
+ Expected<const Elf_Sym *> getRelocationSymbol(const Elf_Rel &Rel,
const Elf_Shdr *SymTab) const;
- Expected<SmallVector<Optional<VersionEntry>, 0>>
- loadVersionMap(const Elf_Shdr *VerNeedSec, const Elf_Shdr *VerDefSec) const;
-
+ Expected<SmallVector<Optional<VersionEntry>, 0>>
+ loadVersionMap(const Elf_Shdr *VerNeedSec, const Elf_Shdr *VerDefSec) const;
+
static Expected<ELFFile> create(StringRef Object);
bool isLE() const {
- return getHeader().getDataEncoding() == ELF::ELFDATA2LSB;
+ return getHeader().getDataEncoding() == ELF::ELFDATA2LSB;
}
bool isMipsELF64() const {
- return getHeader().e_machine == ELF::EM_MIPS &&
- getHeader().getFileClass() == ELF::ELFCLASS64;
+ return getHeader().e_machine == ELF::EM_MIPS &&
+ getHeader().getFileClass() == ELF::ELFCLASS64;
}
bool isMips64EL() const { return isMipsELF64() && isLE(); }
@@ -258,50 +258,50 @@ public:
Expected<Elf_Dyn_Range> dynamicEntries() const;
- Expected<const uint8_t *>
- toMappedAddr(uint64_t VAddr,
- WarningHandler WarnHandler = &defaultWarningHandler) const;
+ Expected<const uint8_t *>
+ toMappedAddr(uint64_t VAddr,
+ WarningHandler WarnHandler = &defaultWarningHandler) const;
Expected<Elf_Sym_Range> symbols(const Elf_Shdr *Sec) const {
if (!Sec)
return makeArrayRef<Elf_Sym>(nullptr, nullptr);
- return getSectionContentsAsArray<Elf_Sym>(*Sec);
+ return getSectionContentsAsArray<Elf_Sym>(*Sec);
}
- Expected<Elf_Rela_Range> relas(const Elf_Shdr &Sec) const {
+ Expected<Elf_Rela_Range> relas(const Elf_Shdr &Sec) const {
return getSectionContentsAsArray<Elf_Rela>(Sec);
}
- Expected<Elf_Rel_Range> rels(const Elf_Shdr &Sec) const {
+ Expected<Elf_Rel_Range> rels(const Elf_Shdr &Sec) const {
return getSectionContentsAsArray<Elf_Rel>(Sec);
}
- Expected<Elf_Relr_Range> relrs(const Elf_Shdr &Sec) const {
+ Expected<Elf_Relr_Range> relrs(const Elf_Shdr &Sec) const {
return getSectionContentsAsArray<Elf_Relr>(Sec);
}
- std::vector<Elf_Rel> decode_relrs(Elf_Relr_Range relrs) const;
+ std::vector<Elf_Rel> decode_relrs(Elf_Relr_Range relrs) const;
- Expected<std::vector<Elf_Rela>> android_relas(const Elf_Shdr &Sec) const;
+ Expected<std::vector<Elf_Rela>> android_relas(const Elf_Shdr &Sec) const;
/// Iterate over program header table.
Expected<Elf_Phdr_Range> program_headers() const {
- if (getHeader().e_phnum && getHeader().e_phentsize != sizeof(Elf_Phdr))
+ if (getHeader().e_phnum && getHeader().e_phentsize != sizeof(Elf_Phdr))
return createError("invalid e_phentsize: " +
- Twine(getHeader().e_phentsize));
+ Twine(getHeader().e_phentsize));
uint64_t HeadersSize =
- (uint64_t)getHeader().e_phnum * getHeader().e_phentsize;
- uint64_t PhOff = getHeader().e_phoff;
+ (uint64_t)getHeader().e_phnum * getHeader().e_phentsize;
+ uint64_t PhOff = getHeader().e_phoff;
if (PhOff + HeadersSize < PhOff || PhOff + HeadersSize > getBufSize())
return createError("program headers are longer than binary of size " +
Twine(getBufSize()) + ": e_phoff = 0x" +
- Twine::utohexstr(getHeader().e_phoff) +
- ", e_phnum = " + Twine(getHeader().e_phnum) +
- ", e_phentsize = " + Twine(getHeader().e_phentsize));
+ Twine::utohexstr(getHeader().e_phoff) +
+ ", e_phnum = " + Twine(getHeader().e_phnum) +
+ ", e_phentsize = " + Twine(getHeader().e_phentsize));
auto *Begin = reinterpret_cast<const Elf_Phdr *>(base() + PhOff);
- return makeArrayRef(Begin, Begin + getHeader().e_phnum);
+ return makeArrayRef(Begin, Begin + getHeader().e_phnum);
}
/// Get an iterator over notes in a program header.
@@ -315,9 +315,9 @@ public:
assert(Phdr.p_type == ELF::PT_NOTE && "Phdr is not of type PT_NOTE");
ErrorAsOutParameter ErrAsOutParam(&Err);
if (Phdr.p_offset + Phdr.p_filesz > getBufSize()) {
- Err =
- createError("invalid offset (0x" + Twine::utohexstr(Phdr.p_offset) +
- ") or size (0x" + Twine::utohexstr(Phdr.p_filesz) + ")");
+ Err =
+ createError("invalid offset (0x" + Twine::utohexstr(Phdr.p_offset) +
+ ") or size (0x" + Twine::utohexstr(Phdr.p_filesz) + ")");
return Elf_Note_Iterator(Err);
}
return Elf_Note_Iterator(base() + Phdr.p_offset, Phdr.p_filesz, Err);
@@ -334,9 +334,9 @@ public:
assert(Shdr.sh_type == ELF::SHT_NOTE && "Shdr is not of type SHT_NOTE");
ErrorAsOutParameter ErrAsOutParam(&Err);
if (Shdr.sh_offset + Shdr.sh_size > getBufSize()) {
- Err =
- createError("invalid offset (0x" + Twine::utohexstr(Shdr.sh_offset) +
- ") or size (0x" + Twine::utohexstr(Shdr.sh_size) + ")");
+ Err =
+ createError("invalid offset (0x" + Twine::utohexstr(Shdr.sh_offset) +
+ ") or size (0x" + Twine::utohexstr(Shdr.sh_size) + ")");
return Elf_Note_Iterator(Err);
}
return Elf_Note_Iterator(base() + Shdr.sh_offset, Shdr.sh_size, Err);
@@ -374,28 +374,28 @@ public:
Expected<StringRef> getSectionStringTable(
Elf_Shdr_Range Sections,
WarningHandler WarnHandler = &defaultWarningHandler) const;
- Expected<uint32_t> getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms,
- DataRegion<Elf_Word> ShndxTable) const;
- Expected<const Elf_Shdr *> getSection(const Elf_Sym &Sym,
+ Expected<uint32_t> getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms,
+ DataRegion<Elf_Word> ShndxTable) const;
+ Expected<const Elf_Shdr *> getSection(const Elf_Sym &Sym,
const Elf_Shdr *SymTab,
- DataRegion<Elf_Word> ShndxTable) const;
- Expected<const Elf_Shdr *> getSection(const Elf_Sym &Sym,
+ DataRegion<Elf_Word> ShndxTable) const;
+ Expected<const Elf_Shdr *> getSection(const Elf_Sym &Sym,
Elf_Sym_Range Symtab,
- DataRegion<Elf_Word> ShndxTable) const;
+ DataRegion<Elf_Word> ShndxTable) const;
Expected<const Elf_Shdr *> getSection(uint32_t Index) const;
Expected<const Elf_Sym *> getSymbol(const Elf_Shdr *Sec,
uint32_t Index) const;
Expected<StringRef>
- getSectionName(const Elf_Shdr &Section,
+ getSectionName(const Elf_Shdr &Section,
WarningHandler WarnHandler = &defaultWarningHandler) const;
- Expected<StringRef> getSectionName(const Elf_Shdr &Section,
+ Expected<StringRef> getSectionName(const Elf_Shdr &Section,
StringRef DotShstrtab) const;
template <typename T>
- Expected<ArrayRef<T>> getSectionContentsAsArray(const Elf_Shdr &Sec) const;
- Expected<ArrayRef<uint8_t>> getSectionContents(const Elf_Shdr &Sec) const;
- Expected<ArrayRef<uint8_t>> getSegmentContents(const Elf_Phdr &Phdr) const;
+ Expected<ArrayRef<T>> getSectionContentsAsArray(const Elf_Shdr &Sec) const;
+ Expected<ArrayRef<uint8_t>> getSectionContents(const Elf_Shdr &Sec) const;
+ Expected<ArrayRef<uint8_t>> getSegmentContents(const Elf_Phdr &Phdr) const;
};
using ELF32LEFile = ELFFile<ELF32LE>;
@@ -413,30 +413,30 @@ getSection(typename ELFT::ShdrRange Sections, uint32_t Index) {
template <class ELFT>
inline Expected<uint32_t>
-getExtendedSymbolTableIndex(const typename ELFT::Sym &Sym, unsigned SymIndex,
- DataRegion<typename ELFT::Word> ShndxTable) {
- assert(Sym.st_shndx == ELF::SHN_XINDEX);
- if (!ShndxTable.First)
+getExtendedSymbolTableIndex(const typename ELFT::Sym &Sym, unsigned SymIndex,
+ DataRegion<typename ELFT::Word> ShndxTable) {
+ assert(Sym.st_shndx == ELF::SHN_XINDEX);
+ if (!ShndxTable.First)
return createError(
- "found an extended symbol index (" + Twine(SymIndex) +
- "), but unable to locate the extended symbol index table");
-
- Expected<typename ELFT::Word> TableOrErr = ShndxTable[SymIndex];
- if (!TableOrErr)
- return createError("unable to read an extended symbol table at index " +
- Twine(SymIndex) + ": " +
- toString(TableOrErr.takeError()));
- return *TableOrErr;
+ "found an extended symbol index (" + Twine(SymIndex) +
+ "), but unable to locate the extended symbol index table");
+
+ Expected<typename ELFT::Word> TableOrErr = ShndxTable[SymIndex];
+ if (!TableOrErr)
+ return createError("unable to read an extended symbol table at index " +
+ Twine(SymIndex) + ": " +
+ toString(TableOrErr.takeError()));
+ return *TableOrErr;
}
template <class ELFT>
Expected<uint32_t>
-ELFFile<ELFT>::getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms,
- DataRegion<Elf_Word> ShndxTable) const {
- uint32_t Index = Sym.st_shndx;
+ELFFile<ELFT>::getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms,
+ DataRegion<Elf_Word> ShndxTable) const {
+ uint32_t Index = Sym.st_shndx;
if (Index == ELF::SHN_XINDEX) {
- Expected<uint32_t> ErrorOrIndex =
- getExtendedSymbolTableIndex<ELFT>(Sym, &Sym - Syms.begin(), ShndxTable);
+ Expected<uint32_t> ErrorOrIndex =
+ getExtendedSymbolTableIndex<ELFT>(Sym, &Sym - Syms.begin(), ShndxTable);
if (!ErrorOrIndex)
return ErrorOrIndex.takeError();
return *ErrorOrIndex;
@@ -448,8 +448,8 @@ ELFFile<ELFT>::getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms,
template <class ELFT>
Expected<const typename ELFT::Shdr *>
-ELFFile<ELFT>::getSection(const Elf_Sym &Sym, const Elf_Shdr *SymTab,
- DataRegion<Elf_Word> ShndxTable) const {
+ELFFile<ELFT>::getSection(const Elf_Sym &Sym, const Elf_Shdr *SymTab,
+ DataRegion<Elf_Word> ShndxTable) const {
auto SymsOrErr = symbols(SymTab);
if (!SymsOrErr)
return SymsOrErr.takeError();
@@ -458,8 +458,8 @@ ELFFile<ELFT>::getSection(const Elf_Sym &Sym, const Elf_Shdr *SymTab,
template <class ELFT>
Expected<const typename ELFT::Shdr *>
-ELFFile<ELFT>::getSection(const Elf_Sym &Sym, Elf_Sym_Range Symbols,
- DataRegion<Elf_Word> ShndxTable) const {
+ELFFile<ELFT>::getSection(const Elf_Sym &Sym, Elf_Sym_Range Symbols,
+ DataRegion<Elf_Word> ShndxTable) const {
auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable);
if (!IndexOrErr)
return IndexOrErr.takeError();
@@ -479,7 +479,7 @@ ELFFile<ELFT>::getSymbol(const Elf_Shdr *Sec, uint32_t Index) const {
Elf_Sym_Range Symbols = *SymsOrErr;
if (Index >= Symbols.size())
return createError("unable to get symbol from section " +
- getSecIndexForError(*this, *Sec) +
+ getSecIndexForError(*this, *Sec) +
": invalid symbol index (" + Twine(Index) + ")");
return &Symbols[Index];
}
@@ -487,27 +487,27 @@ ELFFile<ELFT>::getSymbol(const Elf_Shdr *Sec, uint32_t Index) const {
template <class ELFT>
template <typename T>
Expected<ArrayRef<T>>
-ELFFile<ELFT>::getSectionContentsAsArray(const Elf_Shdr &Sec) const {
- if (Sec.sh_entsize != sizeof(T) && sizeof(T) != 1)
- return createError("section " + getSecIndexForError(*this, Sec) +
- " has invalid sh_entsize: expected " + Twine(sizeof(T)) +
- ", but got " + Twine(Sec.sh_entsize));
+ELFFile<ELFT>::getSectionContentsAsArray(const Elf_Shdr &Sec) const {
+ if (Sec.sh_entsize != sizeof(T) && sizeof(T) != 1)
+ return createError("section " + getSecIndexForError(*this, Sec) +
+ " has invalid sh_entsize: expected " + Twine(sizeof(T)) +
+ ", but got " + Twine(Sec.sh_entsize));
- uintX_t Offset = Sec.sh_offset;
- uintX_t Size = Sec.sh_size;
+ uintX_t Offset = Sec.sh_offset;
+ uintX_t Size = Sec.sh_size;
if (Size % sizeof(T))
- return createError("section " + getSecIndexForError(*this, Sec) +
+ return createError("section " + getSecIndexForError(*this, Sec) +
" has an invalid sh_size (" + Twine(Size) +
") which is not a multiple of its sh_entsize (" +
- Twine(Sec.sh_entsize) + ")");
+ Twine(Sec.sh_entsize) + ")");
if (std::numeric_limits<uintX_t>::max() - Offset < Size)
- return createError("section " + getSecIndexForError(*this, Sec) +
+ return createError("section " + getSecIndexForError(*this, Sec) +
" has a sh_offset (0x" + Twine::utohexstr(Offset) +
") + sh_size (0x" + Twine::utohexstr(Size) +
") that cannot be represented");
if (Offset + Size > Buf.size())
- return createError("section " + getSecIndexForError(*this, Sec) +
+ return createError("section " + getSecIndexForError(*this, Sec) +
" has a sh_offset (0x" + Twine::utohexstr(Offset) +
") + sh_size (0x" + Twine::utohexstr(Size) +
") that is greater than the file size (0x" +
@@ -523,17 +523,17 @@ ELFFile<ELFT>::getSectionContentsAsArray(const Elf_Shdr &Sec) const {
template <class ELFT>
Expected<ArrayRef<uint8_t>>
-ELFFile<ELFT>::getSegmentContents(const Elf_Phdr &Phdr) const {
- uintX_t Offset = Phdr.p_offset;
- uintX_t Size = Phdr.p_filesz;
+ELFFile<ELFT>::getSegmentContents(const Elf_Phdr &Phdr) const {
+ uintX_t Offset = Phdr.p_offset;
+ uintX_t Size = Phdr.p_filesz;
if (std::numeric_limits<uintX_t>::max() - Offset < Size)
- return createError("program header " + getPhdrIndexForError(*this, Phdr) +
+ return createError("program header " + getPhdrIndexForError(*this, Phdr) +
" has a p_offset (0x" + Twine::utohexstr(Offset) +
") + p_filesz (0x" + Twine::utohexstr(Size) +
") that cannot be represented");
if (Offset + Size > Buf.size())
- return createError("program header " + getPhdrIndexForError(*this, Phdr) +
+ return createError("program header " + getPhdrIndexForError(*this, Phdr) +
" has a p_offset (0x" + Twine::utohexstr(Offset) +
") + p_filesz (0x" + Twine::utohexstr(Size) +
") that is greater than the file size (0x" +
@@ -543,13 +543,13 @@ ELFFile<ELFT>::getSegmentContents(const Elf_Phdr &Phdr) const {
template <class ELFT>
Expected<ArrayRef<uint8_t>>
-ELFFile<ELFT>::getSectionContents(const Elf_Shdr &Sec) const {
+ELFFile<ELFT>::getSectionContents(const Elf_Shdr &Sec) const {
return getSectionContentsAsArray<uint8_t>(Sec);
}
template <class ELFT>
StringRef ELFFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
- return getELFRelocationTypeName(getHeader().e_machine, Type);
+ return getELFRelocationTypeName(getHeader().e_machine, Type);
}
template <class ELFT>
@@ -585,61 +585,61 @@ void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type,
template <class ELFT>
uint32_t ELFFile<ELFT>::getRelativeRelocationType() const {
- return getELFRelativeRelocationType(getHeader().e_machine);
+ return getELFRelativeRelocationType(getHeader().e_machine);
+}
+
+template <class ELFT>
+Expected<SmallVector<Optional<VersionEntry>, 0>>
+ELFFile<ELFT>::loadVersionMap(const Elf_Shdr *VerNeedSec,
+ const Elf_Shdr *VerDefSec) const {
+ SmallVector<Optional<VersionEntry>, 0> VersionMap;
+
+ // The first two version indexes are reserved.
+ // Index 0 is VER_NDX_LOCAL, index 1 is VER_NDX_GLOBAL.
+ VersionMap.push_back(VersionEntry());
+ VersionMap.push_back(VersionEntry());
+
+ auto InsertEntry = [&](unsigned N, StringRef Version, bool IsVerdef) {
+ if (N >= VersionMap.size())
+ VersionMap.resize(N + 1);
+ VersionMap[N] = {std::string(Version), IsVerdef};
+ };
+
+ if (VerDefSec) {
+ Expected<std::vector<VerDef>> Defs = getVersionDefinitions(*VerDefSec);
+ if (!Defs)
+ return Defs.takeError();
+ for (const VerDef &Def : *Defs)
+ InsertEntry(Def.Ndx & ELF::VERSYM_VERSION, Def.Name, true);
+ }
+
+ if (VerNeedSec) {
+ Expected<std::vector<VerNeed>> Deps = getVersionDependencies(*VerNeedSec);
+ if (!Deps)
+ return Deps.takeError();
+ for (const VerNeed &Dep : *Deps)
+ for (const VernAux &Aux : Dep.AuxV)
+ InsertEntry(Aux.Other & ELF::VERSYM_VERSION, Aux.Name, false);
+ }
+
+ return VersionMap;
}
template <class ELFT>
-Expected<SmallVector<Optional<VersionEntry>, 0>>
-ELFFile<ELFT>::loadVersionMap(const Elf_Shdr *VerNeedSec,
- const Elf_Shdr *VerDefSec) const {
- SmallVector<Optional<VersionEntry>, 0> VersionMap;
-
- // The first two version indexes are reserved.
- // Index 0 is VER_NDX_LOCAL, index 1 is VER_NDX_GLOBAL.
- VersionMap.push_back(VersionEntry());
- VersionMap.push_back(VersionEntry());
-
- auto InsertEntry = [&](unsigned N, StringRef Version, bool IsVerdef) {
- if (N >= VersionMap.size())
- VersionMap.resize(N + 1);
- VersionMap[N] = {std::string(Version), IsVerdef};
- };
-
- if (VerDefSec) {
- Expected<std::vector<VerDef>> Defs = getVersionDefinitions(*VerDefSec);
- if (!Defs)
- return Defs.takeError();
- for (const VerDef &Def : *Defs)
- InsertEntry(Def.Ndx & ELF::VERSYM_VERSION, Def.Name, true);
- }
-
- if (VerNeedSec) {
- Expected<std::vector<VerNeed>> Deps = getVersionDependencies(*VerNeedSec);
- if (!Deps)
- return Deps.takeError();
- for (const VerNeed &Dep : *Deps)
- for (const VernAux &Aux : Dep.AuxV)
- InsertEntry(Aux.Other & ELF::VERSYM_VERSION, Aux.Name, false);
- }
-
- return VersionMap;
-}
-
-template <class ELFT>
Expected<const typename ELFT::Sym *>
-ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel &Rel,
+ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel &Rel,
const Elf_Shdr *SymTab) const {
- uint32_t Index = Rel.getSymbol(isMips64EL());
+ uint32_t Index = Rel.getSymbol(isMips64EL());
if (Index == 0)
return nullptr;
- return getEntry<Elf_Sym>(*SymTab, Index);
+ return getEntry<Elf_Sym>(*SymTab, Index);
}
template <class ELFT>
Expected<StringRef>
ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections,
WarningHandler WarnHandler) const {
- uint32_t Index = getHeader().e_shstrndx;
+ uint32_t Index = getHeader().e_shstrndx;
if (Index == ELF::SHN_XINDEX) {
// If the section name string table section index is greater than
// or equal to SHN_LORESERVE, then the actual index of the section name
@@ -657,102 +657,102 @@ ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections,
if (Index >= Sections.size())
return createError("section header string table index " + Twine(Index) +
" does not exist");
- return getStringTable(Sections[Index], WarnHandler);
+ return getStringTable(Sections[Index], WarnHandler);
+}
+
+/// This function finds the number of dynamic symbols using a GNU hash table.
+///
+/// @param Table The GNU hash table for .dynsym.
+template <class ELFT>
+static Expected<uint64_t>
+getDynSymtabSizeFromGnuHash(const typename ELFT::GnuHash &Table,
+ const void *BufEnd) {
+ using Elf_Word = typename ELFT::Word;
+ if (Table.nbuckets == 0)
+ return Table.symndx + 1;
+ uint64_t LastSymIdx = 0;
+ // Find the index of the first symbol in the last chain.
+ for (Elf_Word Val : Table.buckets())
+ LastSymIdx = std::max(LastSymIdx, (uint64_t)Val);
+ const Elf_Word *It =
+ reinterpret_cast<const Elf_Word *>(Table.values(LastSymIdx).end());
+ // Locate the end of the chain to find the last symbol index.
+ while (It < BufEnd && (*It & 1) == 0) {
+ ++LastSymIdx;
+ ++It;
+ }
+ if (It >= BufEnd) {
+ return createStringError(
+ object_error::parse_failed,
+ "no terminator found for GNU hash section before buffer end");
+ }
+ return LastSymIdx + 1;
+}
+
+/// This function determines the number of dynamic symbols. It reads section
+/// headers first. If section headers are not available, the number of
+/// symbols will be inferred by parsing dynamic hash tables.
+template <class ELFT>
+Expected<uint64_t> ELFFile<ELFT>::getDynSymtabSize() const {
+ // Read .dynsym section header first if available.
+ Expected<Elf_Shdr_Range> SectionsOrError = sections();
+ if (!SectionsOrError)
+ return SectionsOrError.takeError();
+ for (const Elf_Shdr &Sec : *SectionsOrError) {
+ if (Sec.sh_type == ELF::SHT_DYNSYM) {
+ if (Sec.sh_size % Sec.sh_entsize != 0) {
+ return createStringError(object_error::parse_failed,
+ "SHT_DYNSYM section has sh_size (" +
+ Twine(Sec.sh_size) + ") % sh_entsize (" +
+ Twine(Sec.sh_entsize) + ") that is not 0");
+ }
+ return Sec.sh_size / Sec.sh_entsize;
+ }
+ }
+
+ if (!SectionsOrError->empty()) {
+ // Section headers are available but .dynsym header is not found.
+ // Return 0 as .dynsym does not exist.
+ return 0;
+ }
+
+ // Section headers do not exist. Falling back to infer
+ // upper bound of .dynsym from .gnu.hash and .hash.
+ Expected<Elf_Dyn_Range> DynTable = dynamicEntries();
+ if (!DynTable)
+ return DynTable.takeError();
+ llvm::Optional<uint64_t> ElfHash;
+ llvm::Optional<uint64_t> ElfGnuHash;
+ for (const Elf_Dyn &Entry : *DynTable) {
+ switch (Entry.d_tag) {
+ case ELF::DT_HASH:
+ ElfHash = Entry.d_un.d_ptr;
+ break;
+ case ELF::DT_GNU_HASH:
+ ElfGnuHash = Entry.d_un.d_ptr;
+ break;
+ }
+ }
+ if (ElfGnuHash) {
+ Expected<const uint8_t *> TablePtr = toMappedAddr(*ElfGnuHash);
+ if (!TablePtr)
+ return TablePtr.takeError();
+ const Elf_GnuHash *Table =
+ reinterpret_cast<const Elf_GnuHash *>(TablePtr.get());
+ return getDynSymtabSizeFromGnuHash<ELFT>(*Table, this->Buf.bytes_end());
+ }
+
+ // Search SYSV hash table to try to find the upper bound of dynsym.
+ if (ElfHash) {
+ Expected<const uint8_t *> TablePtr = toMappedAddr(*ElfHash);
+ if (!TablePtr)
+ return TablePtr.takeError();
+ const Elf_Hash *Table = reinterpret_cast<const Elf_Hash *>(TablePtr.get());
+ return Table->nchain;
+ }
+ return 0;
}
-/// This function finds the number of dynamic symbols using a GNU hash table.
-///
-/// @param Table The GNU hash table for .dynsym.
-template <class ELFT>
-static Expected<uint64_t>
-getDynSymtabSizeFromGnuHash(const typename ELFT::GnuHash &Table,
- const void *BufEnd) {
- using Elf_Word = typename ELFT::Word;
- if (Table.nbuckets == 0)
- return Table.symndx + 1;
- uint64_t LastSymIdx = 0;
- // Find the index of the first symbol in the last chain.
- for (Elf_Word Val : Table.buckets())
- LastSymIdx = std::max(LastSymIdx, (uint64_t)Val);
- const Elf_Word *It =
- reinterpret_cast<const Elf_Word *>(Table.values(LastSymIdx).end());
- // Locate the end of the chain to find the last symbol index.
- while (It < BufEnd && (*It & 1) == 0) {
- ++LastSymIdx;
- ++It;
- }
- if (It >= BufEnd) {
- return createStringError(
- object_error::parse_failed,
- "no terminator found for GNU hash section before buffer end");
- }
- return LastSymIdx + 1;
-}
-
-/// This function determines the number of dynamic symbols. It reads section
-/// headers first. If section headers are not available, the number of
-/// symbols will be inferred by parsing dynamic hash tables.
-template <class ELFT>
-Expected<uint64_t> ELFFile<ELFT>::getDynSymtabSize() const {
- // Read .dynsym section header first if available.
- Expected<Elf_Shdr_Range> SectionsOrError = sections();
- if (!SectionsOrError)
- return SectionsOrError.takeError();
- for (const Elf_Shdr &Sec : *SectionsOrError) {
- if (Sec.sh_type == ELF::SHT_DYNSYM) {
- if (Sec.sh_size % Sec.sh_entsize != 0) {
- return createStringError(object_error::parse_failed,
- "SHT_DYNSYM section has sh_size (" +
- Twine(Sec.sh_size) + ") % sh_entsize (" +
- Twine(Sec.sh_entsize) + ") that is not 0");
- }
- return Sec.sh_size / Sec.sh_entsize;
- }
- }
-
- if (!SectionsOrError->empty()) {
- // Section headers are available but .dynsym header is not found.
- // Return 0 as .dynsym does not exist.
- return 0;
- }
-
- // Section headers do not exist. Falling back to infer
- // upper bound of .dynsym from .gnu.hash and .hash.
- Expected<Elf_Dyn_Range> DynTable = dynamicEntries();
- if (!DynTable)
- return DynTable.takeError();
- llvm::Optional<uint64_t> ElfHash;
- llvm::Optional<uint64_t> ElfGnuHash;
- for (const Elf_Dyn &Entry : *DynTable) {
- switch (Entry.d_tag) {
- case ELF::DT_HASH:
- ElfHash = Entry.d_un.d_ptr;
- break;
- case ELF::DT_GNU_HASH:
- ElfGnuHash = Entry.d_un.d_ptr;
- break;
- }
- }
- if (ElfGnuHash) {
- Expected<const uint8_t *> TablePtr = toMappedAddr(*ElfGnuHash);
- if (!TablePtr)
- return TablePtr.takeError();
- const Elf_GnuHash *Table =
- reinterpret_cast<const Elf_GnuHash *>(TablePtr.get());
- return getDynSymtabSizeFromGnuHash<ELFT>(*Table, this->Buf.bytes_end());
- }
-
- // Search SYSV hash table to try to find the upper bound of dynsym.
- if (ElfHash) {
- Expected<const uint8_t *> TablePtr = toMappedAddr(*ElfHash);
- if (!TablePtr)
- return TablePtr.takeError();
- const Elf_Hash *Table = reinterpret_cast<const Elf_Hash *>(TablePtr.get());
- return Table->nchain;
- }
- return 0;
-}
-
template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {}
template <class ELFT>
@@ -766,13 +766,13 @@ Expected<ELFFile<ELFT>> ELFFile<ELFT>::create(StringRef Object) {
template <class ELFT>
Expected<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
- const uintX_t SectionTableOffset = getHeader().e_shoff;
+ const uintX_t SectionTableOffset = getHeader().e_shoff;
if (SectionTableOffset == 0)
return ArrayRef<Elf_Shdr>();
- if (getHeader().e_shentsize != sizeof(Elf_Shdr))
+ if (getHeader().e_shentsize != sizeof(Elf_Shdr))
return createError("invalid e_shentsize in ELF header: " +
- Twine(getHeader().e_shentsize));
+ Twine(getHeader().e_shentsize));
const uint64_t FileSize = Buf.size();
if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize ||
@@ -789,7 +789,7 @@ Expected<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
const Elf_Shdr *First =
reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
- uintX_t NumSections = getHeader().e_shnum;
+ uintX_t NumSections = getHeader().e_shnum;
if (NumSections == 0)
NumSections = First->sh_size;
@@ -820,231 +820,231 @@ Expected<const T *> ELFFile<ELFT>::getEntry(uint32_t Section,
auto SecOrErr = getSection(Section);
if (!SecOrErr)
return SecOrErr.takeError();
- return getEntry<T>(**SecOrErr, Entry);
+ return getEntry<T>(**SecOrErr, Entry);
}
template <class ELFT>
template <typename T>
-Expected<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr &Section,
+Expected<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr &Section,
uint32_t Entry) const {
- Expected<ArrayRef<T>> EntriesOrErr = getSectionContentsAsArray<T>(Section);
- if (!EntriesOrErr)
- return EntriesOrErr.takeError();
-
- ArrayRef<T> Arr = *EntriesOrErr;
- if (Entry >= Arr.size())
- return createError(
- "can't read an entry at 0x" +
- Twine::utohexstr(Entry * static_cast<uint64_t>(sizeof(T))) +
- ": it goes past the end of the section (0x" +
- Twine::utohexstr(Section.sh_size) + ")");
- return &Arr[Entry];
+ Expected<ArrayRef<T>> EntriesOrErr = getSectionContentsAsArray<T>(Section);
+ if (!EntriesOrErr)
+ return EntriesOrErr.takeError();
+
+ ArrayRef<T> Arr = *EntriesOrErr;
+ if (Entry >= Arr.size())
+ return createError(
+ "can't read an entry at 0x" +
+ Twine::utohexstr(Entry * static_cast<uint64_t>(sizeof(T))) +
+ ": it goes past the end of the section (0x" +
+ Twine::utohexstr(Section.sh_size) + ")");
+ return &Arr[Entry];
+}
+
+template <typename ELFT>
+Expected<StringRef> ELFFile<ELFT>::getSymbolVersionByIndex(
+ uint32_t SymbolVersionIndex, bool &IsDefault,
+ SmallVector<Optional<VersionEntry>, 0> &VersionMap,
+ Optional<bool> IsSymHidden) const {
+ size_t VersionIndex = SymbolVersionIndex & llvm::ELF::VERSYM_VERSION;
+
+ // Special markers for unversioned symbols.
+ if (VersionIndex == llvm::ELF::VER_NDX_LOCAL ||
+ VersionIndex == llvm::ELF::VER_NDX_GLOBAL) {
+ IsDefault = false;
+ return "";
+ }
+
+ // Lookup this symbol in the version table.
+ if (VersionIndex >= VersionMap.size() || !VersionMap[VersionIndex])
+ return createError("SHT_GNU_versym section refers to a version index " +
+ Twine(VersionIndex) + " which is missing");
+
+ const VersionEntry &Entry = *VersionMap[VersionIndex];
+ // A default version (@@) is only available for defined symbols.
+ if (!Entry.IsVerDef || IsSymHidden.getValueOr(false))
+ IsDefault = false;
+ else
+ IsDefault = !(SymbolVersionIndex & llvm::ELF::VERSYM_HIDDEN);
+ return Entry.Name.c_str();
+}
+
+template <class ELFT>
+Expected<std::vector<VerDef>>
+ELFFile<ELFT>::getVersionDefinitions(const Elf_Shdr &Sec) const {
+ Expected<StringRef> StrTabOrErr = getLinkAsStrtab(Sec);
+ if (!StrTabOrErr)
+ return StrTabOrErr.takeError();
+
+ Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
+ if (!ContentsOrErr)
+ return createError("cannot read content of " + describe(*this, Sec) + ": " +
+ toString(ContentsOrErr.takeError()));
+
+ const uint8_t *Start = ContentsOrErr->data();
+ const uint8_t *End = Start + ContentsOrErr->size();
+
+ auto ExtractNextAux = [&](const uint8_t *&VerdauxBuf,
+ unsigned VerDefNdx) -> Expected<VerdAux> {
+ if (VerdauxBuf + sizeof(Elf_Verdaux) > End)
+ return createError("invalid " + describe(*this, Sec) +
+ ": version definition " + Twine(VerDefNdx) +
+ " refers to an auxiliary entry that goes past the end "
+ "of the section");
+
+ auto *Verdaux = reinterpret_cast<const Elf_Verdaux *>(VerdauxBuf);
+ VerdauxBuf += Verdaux->vda_next;
+
+ VerdAux Aux;
+ Aux.Offset = VerdauxBuf - Start;
+ if (Verdaux->vda_name <= StrTabOrErr->size())
+ Aux.Name = std::string(StrTabOrErr->drop_front(Verdaux->vda_name));
+ else
+ Aux.Name = ("<invalid vda_name: " + Twine(Verdaux->vda_name) + ">").str();
+ return Aux;
+ };
+
+ std::vector<VerDef> Ret;
+ const uint8_t *VerdefBuf = Start;
+ for (unsigned I = 1; I <= /*VerDefsNum=*/Sec.sh_info; ++I) {
+ if (VerdefBuf + sizeof(Elf_Verdef) > End)
+ return createError("invalid " + describe(*this, Sec) +
+ ": version definition " + Twine(I) +
+ " goes past the end of the section");
+
+ if (reinterpret_cast<uintptr_t>(VerdefBuf) % sizeof(uint32_t) != 0)
+ return createError(
+ "invalid " + describe(*this, Sec) +
+ ": found a misaligned version definition entry at offset 0x" +
+ Twine::utohexstr(VerdefBuf - Start));
+
+ unsigned Version = *reinterpret_cast<const Elf_Half *>(VerdefBuf);
+ if (Version != 1)
+ return createError("unable to dump " + describe(*this, Sec) +
+ ": version " + Twine(Version) +
+ " is not yet supported");
+
+ const Elf_Verdef *D = reinterpret_cast<const Elf_Verdef *>(VerdefBuf);
+ VerDef &VD = *Ret.emplace(Ret.end());
+ VD.Offset = VerdefBuf - Start;
+ VD.Version = D->vd_version;
+ VD.Flags = D->vd_flags;
+ VD.Ndx = D->vd_ndx;
+ VD.Cnt = D->vd_cnt;
+ VD.Hash = D->vd_hash;
+
+ const uint8_t *VerdauxBuf = VerdefBuf + D->vd_aux;
+ for (unsigned J = 0; J < D->vd_cnt; ++J) {
+ if (reinterpret_cast<uintptr_t>(VerdauxBuf) % sizeof(uint32_t) != 0)
+ return createError("invalid " + describe(*this, Sec) +
+ ": found a misaligned auxiliary entry at offset 0x" +
+ Twine::utohexstr(VerdauxBuf - Start));
+
+ Expected<VerdAux> AuxOrErr = ExtractNextAux(VerdauxBuf, I);
+ if (!AuxOrErr)
+ return AuxOrErr.takeError();
+
+ if (J == 0)
+ VD.Name = AuxOrErr->Name;
+ else
+ VD.AuxV.push_back(*AuxOrErr);
+ }
+
+ VerdefBuf += D->vd_next;
+ }
+
+ return Ret;
+}
+
+template <class ELFT>
+Expected<std::vector<VerNeed>>
+ELFFile<ELFT>::getVersionDependencies(const Elf_Shdr &Sec,
+ WarningHandler WarnHandler) const {
+ StringRef StrTab;
+ Expected<StringRef> StrTabOrErr = getLinkAsStrtab(Sec);
+ if (!StrTabOrErr) {
+ if (Error E = WarnHandler(toString(StrTabOrErr.takeError())))
+ return std::move(E);
+ } else {
+ StrTab = *StrTabOrErr;
+ }
+
+ Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
+ if (!ContentsOrErr)
+ return createError("cannot read content of " + describe(*this, Sec) + ": " +
+ toString(ContentsOrErr.takeError()));
+
+ const uint8_t *Start = ContentsOrErr->data();
+ const uint8_t *End = Start + ContentsOrErr->size();
+ const uint8_t *VerneedBuf = Start;
+
+ std::vector<VerNeed> Ret;
+ for (unsigned I = 1; I <= /*VerneedNum=*/Sec.sh_info; ++I) {
+ if (VerneedBuf + sizeof(Elf_Verdef) > End)
+ return createError("invalid " + describe(*this, Sec) +
+ ": version dependency " + Twine(I) +
+ " goes past the end of the section");
+
+ if (reinterpret_cast<uintptr_t>(VerneedBuf) % sizeof(uint32_t) != 0)
+ return createError(
+ "invalid " + describe(*this, Sec) +
+ ": found a misaligned version dependency entry at offset 0x" +
+ Twine::utohexstr(VerneedBuf - Start));
+
+ unsigned Version = *reinterpret_cast<const Elf_Half *>(VerneedBuf);
+ if (Version != 1)
+ return createError("unable to dump " + describe(*this, Sec) +
+ ": version " + Twine(Version) +
+ " is not yet supported");
+
+ const Elf_Verneed *Verneed =
+ reinterpret_cast<const Elf_Verneed *>(VerneedBuf);
+
+ VerNeed &VN = *Ret.emplace(Ret.end());
+ VN.Version = Verneed->vn_version;
+ VN.Cnt = Verneed->vn_cnt;
+ VN.Offset = VerneedBuf - Start;
+
+ if (Verneed->vn_file < StrTab.size())
+ VN.File = std::string(StrTab.drop_front(Verneed->vn_file));
+ else
+ VN.File = ("<corrupt vn_file: " + Twine(Verneed->vn_file) + ">").str();
+
+ const uint8_t *VernauxBuf = VerneedBuf + Verneed->vn_aux;
+ for (unsigned J = 0; J < Verneed->vn_cnt; ++J) {
+ if (reinterpret_cast<uintptr_t>(VernauxBuf) % sizeof(uint32_t) != 0)
+ return createError("invalid " + describe(*this, Sec) +
+ ": found a misaligned auxiliary entry at offset 0x" +
+ Twine::utohexstr(VernauxBuf - Start));
+
+ if (VernauxBuf + sizeof(Elf_Vernaux) > End)
+ return createError(
+ "invalid " + describe(*this, Sec) + ": version dependency " +
+ Twine(I) +
+ " refers to an auxiliary entry that goes past the end "
+ "of the section");
+
+ const Elf_Vernaux *Vernaux =
+ reinterpret_cast<const Elf_Vernaux *>(VernauxBuf);
+
+ VernAux &Aux = *VN.AuxV.emplace(VN.AuxV.end());
+ Aux.Hash = Vernaux->vna_hash;
+ Aux.Flags = Vernaux->vna_flags;
+ Aux.Other = Vernaux->vna_other;
+ Aux.Offset = VernauxBuf - Start;
+ if (StrTab.size() <= Vernaux->vna_name)
+ Aux.Name = "<corrupt>";
+ else
+ Aux.Name = std::string(StrTab.drop_front(Vernaux->vna_name));
+
+ VernauxBuf += Vernaux->vna_next;
+ }
+ VerneedBuf += Verneed->vn_next;
+ }
+ return Ret;
}
-template <typename ELFT>
-Expected<StringRef> ELFFile<ELFT>::getSymbolVersionByIndex(
- uint32_t SymbolVersionIndex, bool &IsDefault,
- SmallVector<Optional<VersionEntry>, 0> &VersionMap,
- Optional<bool> IsSymHidden) const {
- size_t VersionIndex = SymbolVersionIndex & llvm::ELF::VERSYM_VERSION;
-
- // Special markers for unversioned symbols.
- if (VersionIndex == llvm::ELF::VER_NDX_LOCAL ||
- VersionIndex == llvm::ELF::VER_NDX_GLOBAL) {
- IsDefault = false;
- return "";
- }
-
- // Lookup this symbol in the version table.
- if (VersionIndex >= VersionMap.size() || !VersionMap[VersionIndex])
- return createError("SHT_GNU_versym section refers to a version index " +
- Twine(VersionIndex) + " which is missing");
-
- const VersionEntry &Entry = *VersionMap[VersionIndex];
- // A default version (@@) is only available for defined symbols.
- if (!Entry.IsVerDef || IsSymHidden.getValueOr(false))
- IsDefault = false;
- else
- IsDefault = !(SymbolVersionIndex & llvm::ELF::VERSYM_HIDDEN);
- return Entry.Name.c_str();
-}
-
template <class ELFT>
-Expected<std::vector<VerDef>>
-ELFFile<ELFT>::getVersionDefinitions(const Elf_Shdr &Sec) const {
- Expected<StringRef> StrTabOrErr = getLinkAsStrtab(Sec);
- if (!StrTabOrErr)
- return StrTabOrErr.takeError();
-
- Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
- if (!ContentsOrErr)
- return createError("cannot read content of " + describe(*this, Sec) + ": " +
- toString(ContentsOrErr.takeError()));
-
- const uint8_t *Start = ContentsOrErr->data();
- const uint8_t *End = Start + ContentsOrErr->size();
-
- auto ExtractNextAux = [&](const uint8_t *&VerdauxBuf,
- unsigned VerDefNdx) -> Expected<VerdAux> {
- if (VerdauxBuf + sizeof(Elf_Verdaux) > End)
- return createError("invalid " + describe(*this, Sec) +
- ": version definition " + Twine(VerDefNdx) +
- " refers to an auxiliary entry that goes past the end "
- "of the section");
-
- auto *Verdaux = reinterpret_cast<const Elf_Verdaux *>(VerdauxBuf);
- VerdauxBuf += Verdaux->vda_next;
-
- VerdAux Aux;
- Aux.Offset = VerdauxBuf - Start;
- if (Verdaux->vda_name <= StrTabOrErr->size())
- Aux.Name = std::string(StrTabOrErr->drop_front(Verdaux->vda_name));
- else
- Aux.Name = ("<invalid vda_name: " + Twine(Verdaux->vda_name) + ">").str();
- return Aux;
- };
-
- std::vector<VerDef> Ret;
- const uint8_t *VerdefBuf = Start;
- for (unsigned I = 1; I <= /*VerDefsNum=*/Sec.sh_info; ++I) {
- if (VerdefBuf + sizeof(Elf_Verdef) > End)
- return createError("invalid " + describe(*this, Sec) +
- ": version definition " + Twine(I) +
- " goes past the end of the section");
-
- if (reinterpret_cast<uintptr_t>(VerdefBuf) % sizeof(uint32_t) != 0)
- return createError(
- "invalid " + describe(*this, Sec) +
- ": found a misaligned version definition entry at offset 0x" +
- Twine::utohexstr(VerdefBuf - Start));
-
- unsigned Version = *reinterpret_cast<const Elf_Half *>(VerdefBuf);
- if (Version != 1)
- return createError("unable to dump " + describe(*this, Sec) +
- ": version " + Twine(Version) +
- " is not yet supported");
-
- const Elf_Verdef *D = reinterpret_cast<const Elf_Verdef *>(VerdefBuf);
- VerDef &VD = *Ret.emplace(Ret.end());
- VD.Offset = VerdefBuf - Start;
- VD.Version = D->vd_version;
- VD.Flags = D->vd_flags;
- VD.Ndx = D->vd_ndx;
- VD.Cnt = D->vd_cnt;
- VD.Hash = D->vd_hash;
-
- const uint8_t *VerdauxBuf = VerdefBuf + D->vd_aux;
- for (unsigned J = 0; J < D->vd_cnt; ++J) {
- if (reinterpret_cast<uintptr_t>(VerdauxBuf) % sizeof(uint32_t) != 0)
- return createError("invalid " + describe(*this, Sec) +
- ": found a misaligned auxiliary entry at offset 0x" +
- Twine::utohexstr(VerdauxBuf - Start));
-
- Expected<VerdAux> AuxOrErr = ExtractNextAux(VerdauxBuf, I);
- if (!AuxOrErr)
- return AuxOrErr.takeError();
-
- if (J == 0)
- VD.Name = AuxOrErr->Name;
- else
- VD.AuxV.push_back(*AuxOrErr);
- }
-
- VerdefBuf += D->vd_next;
- }
-
- return Ret;
-}
-
-template <class ELFT>
-Expected<std::vector<VerNeed>>
-ELFFile<ELFT>::getVersionDependencies(const Elf_Shdr &Sec,
- WarningHandler WarnHandler) const {
- StringRef StrTab;
- Expected<StringRef> StrTabOrErr = getLinkAsStrtab(Sec);
- if (!StrTabOrErr) {
- if (Error E = WarnHandler(toString(StrTabOrErr.takeError())))
- return std::move(E);
- } else {
- StrTab = *StrTabOrErr;
- }
-
- Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
- if (!ContentsOrErr)
- return createError("cannot read content of " + describe(*this, Sec) + ": " +
- toString(ContentsOrErr.takeError()));
-
- const uint8_t *Start = ContentsOrErr->data();
- const uint8_t *End = Start + ContentsOrErr->size();
- const uint8_t *VerneedBuf = Start;
-
- std::vector<VerNeed> Ret;
- for (unsigned I = 1; I <= /*VerneedNum=*/Sec.sh_info; ++I) {
- if (VerneedBuf + sizeof(Elf_Verdef) > End)
- return createError("invalid " + describe(*this, Sec) +
- ": version dependency " + Twine(I) +
- " goes past the end of the section");
-
- if (reinterpret_cast<uintptr_t>(VerneedBuf) % sizeof(uint32_t) != 0)
- return createError(
- "invalid " + describe(*this, Sec) +
- ": found a misaligned version dependency entry at offset 0x" +
- Twine::utohexstr(VerneedBuf - Start));
-
- unsigned Version = *reinterpret_cast<const Elf_Half *>(VerneedBuf);
- if (Version != 1)
- return createError("unable to dump " + describe(*this, Sec) +
- ": version " + Twine(Version) +
- " is not yet supported");
-
- const Elf_Verneed *Verneed =
- reinterpret_cast<const Elf_Verneed *>(VerneedBuf);
-
- VerNeed &VN = *Ret.emplace(Ret.end());
- VN.Version = Verneed->vn_version;
- VN.Cnt = Verneed->vn_cnt;
- VN.Offset = VerneedBuf - Start;
-
- if (Verneed->vn_file < StrTab.size())
- VN.File = std::string(StrTab.drop_front(Verneed->vn_file));
- else
- VN.File = ("<corrupt vn_file: " + Twine(Verneed->vn_file) + ">").str();
-
- const uint8_t *VernauxBuf = VerneedBuf + Verneed->vn_aux;
- for (unsigned J = 0; J < Verneed->vn_cnt; ++J) {
- if (reinterpret_cast<uintptr_t>(VernauxBuf) % sizeof(uint32_t) != 0)
- return createError("invalid " + describe(*this, Sec) +
- ": found a misaligned auxiliary entry at offset 0x" +
- Twine::utohexstr(VernauxBuf - Start));
-
- if (VernauxBuf + sizeof(Elf_Vernaux) > End)
- return createError(
- "invalid " + describe(*this, Sec) + ": version dependency " +
- Twine(I) +
- " refers to an auxiliary entry that goes past the end "
- "of the section");
-
- const Elf_Vernaux *Vernaux =
- reinterpret_cast<const Elf_Vernaux *>(VernauxBuf);
-
- VernAux &Aux = *VN.AuxV.emplace(VN.AuxV.end());
- Aux.Hash = Vernaux->vna_hash;
- Aux.Flags = Vernaux->vna_flags;
- Aux.Other = Vernaux->vna_other;
- Aux.Offset = VernauxBuf - Start;
- if (StrTab.size() <= Vernaux->vna_name)
- Aux.Name = "<corrupt>";
- else
- Aux.Name = std::string(StrTab.drop_front(Vernaux->vna_name));
-
- VernauxBuf += Vernaux->vna_next;
- }
- VerneedBuf += Verneed->vn_next;
- }
- return Ret;
-}
-
-template <class ELFT>
Expected<const typename ELFT::Shdr *>
ELFFile<ELFT>::getSection(uint32_t Index) const {
auto TableOrErr = sections();
@@ -1055,14 +1055,14 @@ ELFFile<ELFT>::getSection(uint32_t Index) const {
template <class ELFT>
Expected<StringRef>
-ELFFile<ELFT>::getStringTable(const Elf_Shdr &Section,
+ELFFile<ELFT>::getStringTable(const Elf_Shdr &Section,
WarningHandler WarnHandler) const {
- if (Section.sh_type != ELF::SHT_STRTAB)
+ if (Section.sh_type != ELF::SHT_STRTAB)
if (Error E = WarnHandler("invalid sh_type for string table section " +
- getSecIndexForError(*this, Section) +
+ getSecIndexForError(*this, Section) +
": expected SHT_STRTAB, but got " +
object::getELFSectionTypeName(
- getHeader().e_machine, Section.sh_type)))
+ getHeader().e_machine, Section.sh_type)))
return std::move(E);
auto V = getSectionContentsAsArray<char>(Section);
@@ -1071,10 +1071,10 @@ ELFFile<ELFT>::getStringTable(const Elf_Shdr &Section,
ArrayRef<char> Data = *V;
if (Data.empty())
return createError("SHT_STRTAB string table section " +
- getSecIndexForError(*this, Section) + " is empty");
+ getSecIndexForError(*this, Section) + " is empty");
if (Data.back() != '\0')
return createError("SHT_STRTAB string table section " +
- getSecIndexForError(*this, Section) +
+ getSecIndexForError(*this, Section) +
" is non-null terminated");
return StringRef(Data.begin(), Data.size());
}
@@ -1093,7 +1093,7 @@ Expected<ArrayRef<typename ELFT::Word>>
ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section,
Elf_Shdr_Range Sections) const {
assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX);
- auto VOrErr = getSectionContentsAsArray<Elf_Word>(Section);
+ auto VOrErr = getSectionContentsAsArray<Elf_Word>(Section);
if (!VOrErr)
return VOrErr.takeError();
ArrayRef<Elf_Word> V = *VOrErr;
@@ -1103,10 +1103,10 @@ ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section,
const Elf_Shdr &SymTable = **SymTableOrErr;
if (SymTable.sh_type != ELF::SHT_SYMTAB &&
SymTable.sh_type != ELF::SHT_DYNSYM)
- return createError(
- "SHT_SYMTAB_SHNDX section is linked with " +
- object::getELFSectionTypeName(getHeader().e_machine, SymTable.sh_type) +
- " section (expected SHT_SYMTAB/SHT_DYNSYM)");
+ return createError(
+ "SHT_SYMTAB_SHNDX section is linked with " +
+ object::getELFSectionTypeName(getHeader().e_machine, SymTable.sh_type) +
+ " section (expected SHT_SYMTAB/SHT_DYNSYM)");
uint64_t Syms = SymTable.sh_size / sizeof(Elf_Sym);
if (V.size() != Syms)
@@ -1134,33 +1134,33 @@ ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec,
if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM)
return createError(
"invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
- Expected<const Elf_Shdr *> SectionOrErr =
- object::getSection<ELFT>(Sections, Sec.sh_link);
+ Expected<const Elf_Shdr *> SectionOrErr =
+ object::getSection<ELFT>(Sections, Sec.sh_link);
if (!SectionOrErr)
return SectionOrErr.takeError();
- return getStringTable(**SectionOrErr);
+ return getStringTable(**SectionOrErr);
+}
+
+template <class ELFT>
+Expected<StringRef>
+ELFFile<ELFT>::getLinkAsStrtab(const typename ELFT::Shdr &Sec) const {
+ Expected<const typename ELFT::Shdr *> StrTabSecOrErr =
+ getSection(Sec.sh_link);
+ if (!StrTabSecOrErr)
+ return createError("invalid section linked to " + describe(*this, Sec) +
+ ": " + toString(StrTabSecOrErr.takeError()));
+
+ Expected<StringRef> StrTabOrErr = getStringTable(**StrTabSecOrErr);
+ if (!StrTabOrErr)
+ return createError("invalid string table linked to " +
+ describe(*this, Sec) + ": " +
+ toString(StrTabOrErr.takeError()));
+ return *StrTabOrErr;
}
template <class ELFT>
Expected<StringRef>
-ELFFile<ELFT>::getLinkAsStrtab(const typename ELFT::Shdr &Sec) const {
- Expected<const typename ELFT::Shdr *> StrTabSecOrErr =
- getSection(Sec.sh_link);
- if (!StrTabSecOrErr)
- return createError("invalid section linked to " + describe(*this, Sec) +
- ": " + toString(StrTabSecOrErr.takeError()));
-
- Expected<StringRef> StrTabOrErr = getStringTable(**StrTabSecOrErr);
- if (!StrTabOrErr)
- return createError("invalid string table linked to " +
- describe(*this, Sec) + ": " +
- toString(StrTabOrErr.takeError()));
- return *StrTabOrErr;
-}
-
-template <class ELFT>
-Expected<StringRef>
-ELFFile<ELFT>::getSectionName(const Elf_Shdr &Section,
+ELFFile<ELFT>::getSectionName(const Elf_Shdr &Section,
WarningHandler WarnHandler) const {
auto SectionsOrErr = sections();
if (!SectionsOrErr)
@@ -1172,13 +1172,13 @@ ELFFile<ELFT>::getSectionName(const Elf_Shdr &Section,
}
template <class ELFT>
-Expected<StringRef> ELFFile<ELFT>::getSectionName(const Elf_Shdr &Section,
+Expected<StringRef> ELFFile<ELFT>::getSectionName(const Elf_Shdr &Section,
StringRef DotShstrtab) const {
- uint32_t Offset = Section.sh_name;
+ uint32_t Offset = Section.sh_name;
if (Offset == 0)
return StringRef();
if (Offset >= DotShstrtab.size())
- return createError("a section " + getSecIndexForError(*this, Section) +
+ return createError("a section " + getSecIndexForError(*this, Section) +
" has an invalid sh_name (0x" +
Twine::utohexstr(Offset) +
") offset which goes past the end of the "
diff --git a/contrib/libs/llvm12/include/llvm/Object/ELFObjectFile.h b/contrib/libs/llvm12/include/llvm/Object/ELFObjectFile.h
index 5b782f72d9..28c6ec9bfc 100644
--- a/contrib/libs/llvm12/include/llvm/Object/ELFObjectFile.h
+++ b/contrib/libs/llvm12/include/llvm/Object/ELFObjectFile.h
@@ -58,12 +58,12 @@ class ELFObjectFileBase : public ObjectFile {
friend class ELFSectionRef;
friend class ELFSymbolRef;
- SubtargetFeatures getMIPSFeatures() const;
- SubtargetFeatures getARMFeatures() const;
- SubtargetFeatures getRISCVFeatures() const;
-
- StringRef getAMDGPUCPUName() const;
-
+ SubtargetFeatures getMIPSFeatures() const;
+ SubtargetFeatures getARMFeatures() const;
+ SubtargetFeatures getRISCVFeatures() const;
+
+ StringRef getAMDGPUCPUName() const;
+
protected:
ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
@@ -93,7 +93,7 @@ public:
SubtargetFeatures getFeatures() const override;
- Optional<StringRef> tryGetCPUName() const override;
+ Optional<StringRef> tryGetCPUName() const override;
void setARMSubArch(Triple &TheTriple) const override;
@@ -101,8 +101,8 @@ public:
virtual uint16_t getEMachine() const = 0;
- std::vector<std::pair<Optional<DataRefImpl>, uint64_t>>
- getPltAddresses() const;
+ std::vector<std::pair<Optional<DataRefImpl>, uint64_t>>
+ getPltAddresses() const;
};
class ELFSectionRef : public SectionRef {
@@ -244,28 +244,28 @@ public:
return SectionRef(toDRI(Sec), this);
}
- ELFSymbolRef toSymbolRef(const Elf_Shdr *SymTable, unsigned SymbolNum) const {
- return ELFSymbolRef({toDRI(SymTable, SymbolNum), this});
- }
-
- bool IsContentValid() const { return ContentValid; }
-
+ ELFSymbolRef toSymbolRef(const Elf_Shdr *SymTable, unsigned SymbolNum) const {
+ return ELFSymbolRef({toDRI(SymTable, SymbolNum), this});
+ }
+
+ bool IsContentValid() const { return ContentValid; }
+
private:
ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
const Elf_Shdr *DotDynSymSec, const Elf_Shdr *DotSymtabSec,
- const Elf_Shdr *DotSymtabShndxSec);
+ const Elf_Shdr *DotSymtabShndxSec);
+
+ bool ContentValid = false;
- bool ContentValid = false;
-
protected:
ELFFile<ELFT> EF;
const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section.
const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section.
- const Elf_Shdr *DotSymtabShndxSec = nullptr; // SHT_SYMTAB_SHNDX section.
+ const Elf_Shdr *DotSymtabShndxSec = nullptr; // SHT_SYMTAB_SHNDX section.
+
+ Error initContent() override;
- Error initContent() override;
-
void moveSymbolNext(DataRefImpl &Symb) const override;
Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
@@ -377,7 +377,7 @@ protected:
for (const Elf_Shdr &Sec : *SectionsOrErr) {
if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES ||
Sec.sh_type == ELF::SHT_RISCV_ATTRIBUTES) {
- auto ErrorOrContents = EF.getSectionContents(Sec);
+ auto ErrorOrContents = EF.getSectionContents(Sec);
if (!ErrorOrContents)
return ErrorOrContents.takeError();
@@ -400,24 +400,24 @@ protected:
public:
ELFObjectFile(ELFObjectFile<ELFT> &&Other);
- static Expected<ELFObjectFile<ELFT>> create(MemoryBufferRef Object,
- bool InitContent = true);
+ static Expected<ELFObjectFile<ELFT>> create(MemoryBufferRef Object,
+ bool InitContent = true);
const Elf_Rel *getRel(DataRefImpl Rel) const;
const Elf_Rela *getRela(DataRefImpl Rela) const;
- Expected<const Elf_Sym *> getSymbol(DataRefImpl Sym) const {
- return EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b);
+ Expected<const Elf_Sym *> getSymbol(DataRefImpl Sym) const {
+ return EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b);
+ }
+
+ /// Get the relocation section that contains \a Rel.
+ const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
+ auto RelSecOrErr = EF.getSection(Rel.d.a);
+ if (!RelSecOrErr)
+ report_fatal_error(errorToErrorCode(RelSecOrErr.takeError()).message());
+ return *RelSecOrErr;
}
- /// Get the relocation section that contains \a Rel.
- const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
- auto RelSecOrErr = EF.getSection(Rel.d.a);
- if (!RelSecOrErr)
- report_fatal_error(errorToErrorCode(RelSecOrErr.takeError()).message());
- return *RelSecOrErr;
- }
-
const Elf_Shdr *getSection(DataRefImpl Sec) const {
return reinterpret_cast<const Elf_Shdr *>(Sec.p);
}
@@ -438,9 +438,9 @@ public:
Triple::ArchType getArch() const override;
Expected<uint64_t> getStartAddress() const override;
- unsigned getPlatformFlags() const override { return EF.getHeader().e_flags; }
+ unsigned getPlatformFlags() const override { return EF.getHeader().e_flags; }
- const ELFFile<ELFT> &getELFFile() const { return EF; }
+ const ELFFile<ELFT> &getELFFile() const { return EF; }
bool isDyldType() const { return isDyldELFObject; }
static bool classof(const Binary *v) {
@@ -463,40 +463,40 @@ void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
++Sym.d.b;
}
-template <class ELFT> Error ELFObjectFile<ELFT>::initContent() {
- auto SectionsOrErr = EF.sections();
- if (!SectionsOrErr)
- return SectionsOrErr.takeError();
-
- for (const Elf_Shdr &Sec : *SectionsOrErr) {
- switch (Sec.sh_type) {
- case ELF::SHT_DYNSYM: {
- if (!DotDynSymSec)
- DotDynSymSec = &Sec;
- break;
- }
- case ELF::SHT_SYMTAB: {
- if (!DotSymtabSec)
- DotSymtabSec = &Sec;
- break;
- }
- case ELF::SHT_SYMTAB_SHNDX: {
- if (!DotSymtabShndxSec)
- DotSymtabShndxSec = &Sec;
- break;
- }
- }
- }
-
- ContentValid = true;
- return Error::success();
-}
-
+template <class ELFT> Error ELFObjectFile<ELFT>::initContent() {
+ auto SectionsOrErr = EF.sections();
+ if (!SectionsOrErr)
+ return SectionsOrErr.takeError();
+
+ for (const Elf_Shdr &Sec : *SectionsOrErr) {
+ switch (Sec.sh_type) {
+ case ELF::SHT_DYNSYM: {
+ if (!DotDynSymSec)
+ DotDynSymSec = &Sec;
+ break;
+ }
+ case ELF::SHT_SYMTAB: {
+ if (!DotSymtabSec)
+ DotSymtabSec = &Sec;
+ break;
+ }
+ case ELF::SHT_SYMTAB_SHNDX: {
+ if (!DotSymtabShndxSec)
+ DotSymtabShndxSec = &Sec;
+ break;
+ }
+ }
+ }
+
+ ContentValid = true;
+ return Error::success();
+}
+
template <class ELFT>
Expected<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const {
- Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym);
- if (!SymOrErr)
- return SymOrErr.takeError();
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym);
+ if (!SymOrErr)
+ return SymOrErr.takeError();
auto SymTabOrErr = EF.getSection(Sym.d.a);
if (!SymTabOrErr)
return SymTabOrErr.takeError();
@@ -505,15 +505,15 @@ Expected<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const {
if (!StrTabOrErr)
return StrTabOrErr.takeError();
const Elf_Shdr *StringTableSec = *StrTabOrErr;
- auto SymStrTabOrErr = EF.getStringTable(*StringTableSec);
+ auto SymStrTabOrErr = EF.getStringTable(*StringTableSec);
if (!SymStrTabOrErr)
return SymStrTabOrErr.takeError();
- Expected<StringRef> Name = (*SymOrErr)->getName(*SymStrTabOrErr);
+ Expected<StringRef> Name = (*SymOrErr)->getName(*SymStrTabOrErr);
if (Name && !Name->empty())
return Name;
// If the symbol name is empty use the section name.
- if ((*SymOrErr)->getType() == ELF::STT_SECTION) {
+ if ((*SymOrErr)->getType() == ELF::STT_SECTION) {
if (Expected<section_iterator> SecOrErr = getSymbolSection(Sym)) {
consumeError(Name.takeError());
return (*SecOrErr)->getName();
@@ -539,18 +539,18 @@ uint64_t ELFObjectFile<ELFT>::getSectionOffset(DataRefImpl Sec) const {
template <class ELFT>
uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const {
- Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
- if (!SymOrErr)
- report_fatal_error(SymOrErr.takeError());
-
- uint64_t Ret = (*SymOrErr)->st_value;
- if ((*SymOrErr)->st_shndx == ELF::SHN_ABS)
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
+ if (!SymOrErr)
+ report_fatal_error(SymOrErr.takeError());
+
+ uint64_t Ret = (*SymOrErr)->st_value;
+ if ((*SymOrErr)->st_shndx == ELF::SHN_ABS)
return Ret;
- const Elf_Ehdr &Header = EF.getHeader();
+ const Elf_Ehdr &Header = EF.getHeader();
// Clear the ARM/Thumb or microMIPS indicator flag.
- if ((Header.e_machine == ELF::EM_ARM || Header.e_machine == ELF::EM_MIPS) &&
- (*SymOrErr)->getType() == ELF::STT_FUNC)
+ if ((Header.e_machine == ELF::EM_ARM || Header.e_machine == ELF::EM_MIPS) &&
+ (*SymOrErr)->getType() == ELF::STT_FUNC)
Ret &= ~1;
return Ret;
@@ -565,11 +565,11 @@ ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
return SymbolValueOrErr.takeError();
uint64_t Result = *SymbolValueOrErr;
- Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
- if (!SymOrErr)
- return SymOrErr.takeError();
-
- switch ((*SymOrErr)->st_shndx) {
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
+ if (!SymOrErr)
+ return SymOrErr.takeError();
+
+ switch ((*SymOrErr)->st_shndx) {
case ELF::SHN_COMMON:
case ELF::SHN_UNDEF:
case ELF::SHN_ABS:
@@ -580,19 +580,19 @@ ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
if (!SymTabOrErr)
return SymTabOrErr.takeError();
- if (EF.getHeader().e_type == ELF::ET_REL) {
- ArrayRef<Elf_Word> ShndxTable;
- if (DotSymtabShndxSec) {
- // TODO: Test this error.
- if (Expected<ArrayRef<Elf_Word>> ShndxTableOrErr =
- EF.getSHNDXTable(*DotSymtabShndxSec))
- ShndxTable = *ShndxTableOrErr;
- else
- return ShndxTableOrErr.takeError();
- }
-
- Expected<const Elf_Shdr *> SectionOrErr =
- EF.getSection(**SymOrErr, *SymTabOrErr, ShndxTable);
+ if (EF.getHeader().e_type == ELF::ET_REL) {
+ ArrayRef<Elf_Word> ShndxTable;
+ if (DotSymtabShndxSec) {
+ // TODO: Test this error.
+ if (Expected<ArrayRef<Elf_Word>> ShndxTableOrErr =
+ EF.getSHNDXTable(*DotSymtabShndxSec))
+ ShndxTable = *ShndxTableOrErr;
+ else
+ return ShndxTableOrErr.takeError();
+ }
+
+ Expected<const Elf_Shdr *> SectionOrErr =
+ EF.getSection(**SymOrErr, *SymTabOrErr, ShndxTable);
if (!SectionOrErr)
return SectionOrErr.takeError();
const Elf_Shdr *Section = *SectionOrErr;
@@ -605,68 +605,68 @@ ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
template <class ELFT>
uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const {
- Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
- if (!SymOrErr)
- report_fatal_error(SymOrErr.takeError());
- if ((*SymOrErr)->st_shndx == ELF::SHN_COMMON)
- return (*SymOrErr)->st_value;
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
+ if (!SymOrErr)
+ report_fatal_error(SymOrErr.takeError());
+ if ((*SymOrErr)->st_shndx == ELF::SHN_COMMON)
+ return (*SymOrErr)->st_value;
return 0;
}
template <class ELFT>
uint16_t ELFObjectFile<ELFT>::getEMachine() const {
- return EF.getHeader().e_machine;
+ return EF.getHeader().e_machine;
}
template <class ELFT> uint16_t ELFObjectFile<ELFT>::getEType() const {
- return EF.getHeader().e_type;
+ return EF.getHeader().e_type;
}
template <class ELFT>
uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const {
- Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym);
- if (!SymOrErr)
- report_fatal_error(SymOrErr.takeError());
- return (*SymOrErr)->st_size;
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym);
+ if (!SymOrErr)
+ report_fatal_error(SymOrErr.takeError());
+ return (*SymOrErr)->st_size;
}
template <class ELFT>
uint64_t ELFObjectFile<ELFT>::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
- return getSymbolSize(Symb);
+ return getSymbolSize(Symb);
}
template <class ELFT>
uint8_t ELFObjectFile<ELFT>::getSymbolBinding(DataRefImpl Symb) const {
- Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
- if (!SymOrErr)
- report_fatal_error(SymOrErr.takeError());
- return (*SymOrErr)->getBinding();
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
+ if (!SymOrErr)
+ report_fatal_error(SymOrErr.takeError());
+ return (*SymOrErr)->getBinding();
}
template <class ELFT>
uint8_t ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb) const {
- Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
- if (!SymOrErr)
- report_fatal_error(SymOrErr.takeError());
- return (*SymOrErr)->st_other;
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
+ if (!SymOrErr)
+ report_fatal_error(SymOrErr.takeError());
+ return (*SymOrErr)->st_other;
}
template <class ELFT>
uint8_t ELFObjectFile<ELFT>::getSymbolELFType(DataRefImpl Symb) const {
- Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
- if (!SymOrErr)
- report_fatal_error(SymOrErr.takeError());
- return (*SymOrErr)->getType();
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
+ if (!SymOrErr)
+ report_fatal_error(SymOrErr.takeError());
+ return (*SymOrErr)->getType();
}
template <class ELFT>
Expected<SymbolRef::Type>
ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const {
- Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
- if (!SymOrErr)
- return SymOrErr.takeError();
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
+ if (!SymOrErr)
+ return SymOrErr.takeError();
- switch ((*SymOrErr)->getType()) {
+ switch ((*SymOrErr)->getType()) {
case ELF::STT_NOTYPE:
return SymbolRef::ST_Unknown;
case ELF::STT_SECTION:
@@ -686,11 +686,11 @@ ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const {
template <class ELFT>
Expected<uint32_t> ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
- Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym);
- if (!SymOrErr)
- return SymOrErr.takeError();
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym);
+ if (!SymOrErr)
+ return SymOrErr.takeError();
- const Elf_Sym *ESym = *SymOrErr;
+ const Elf_Sym *ESym = *SymOrErr;
uint32_t Result = SymbolRef::SF_None;
if (ESym->getBinding() != ELF::STB_LOCAL)
@@ -723,7 +723,7 @@ Expected<uint32_t> ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
// TODO: Test this error.
return SymbolsOrErr.takeError();
- if (EF.getHeader().e_machine == ELF::EM_ARM) {
+ if (EF.getHeader().e_machine == ELF::EM_ARM) {
if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) {
StringRef Name = *NameOrErr;
if (Name.startswith("$d") || Name.startswith("$t") ||
@@ -756,17 +756,17 @@ template <class ELFT>
Expected<section_iterator>
ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym,
const Elf_Shdr *SymTab) const {
- ArrayRef<Elf_Word> ShndxTable;
- if (DotSymtabShndxSec) {
- // TODO: Test this error.
- Expected<ArrayRef<Elf_Word>> ShndxTableOrErr =
- EF.getSHNDXTable(*DotSymtabShndxSec);
- if (!ShndxTableOrErr)
- return ShndxTableOrErr.takeError();
- ShndxTable = *ShndxTableOrErr;
- }
-
- auto ESecOrErr = EF.getSection(*ESym, SymTab, ShndxTable);
+ ArrayRef<Elf_Word> ShndxTable;
+ if (DotSymtabShndxSec) {
+ // TODO: Test this error.
+ Expected<ArrayRef<Elf_Word>> ShndxTableOrErr =
+ EF.getSHNDXTable(*DotSymtabShndxSec);
+ if (!ShndxTableOrErr)
+ return ShndxTableOrErr.takeError();
+ ShndxTable = *ShndxTableOrErr;
+ }
+
+ auto ESecOrErr = EF.getSection(*ESym, SymTab, ShndxTable);
if (!ESecOrErr)
return ESecOrErr.takeError();
@@ -782,14 +782,14 @@ ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym,
template <class ELFT>
Expected<section_iterator>
ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb) const {
- Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
- if (!SymOrErr)
- return SymOrErr.takeError();
-
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
+ if (!SymOrErr)
+ return SymOrErr.takeError();
+
auto SymTabOrErr = EF.getSection(Symb.d.a);
if (!SymTabOrErr)
return SymTabOrErr.takeError();
- return getSymbolSection(*SymOrErr, *SymTabOrErr);
+ return getSymbolSection(*SymOrErr, *SymTabOrErr);
}
template <class ELFT>
@@ -800,7 +800,7 @@ void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
template <class ELFT>
Expected<StringRef> ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec) const {
- return EF.getSectionName(*getSection(Sec));
+ return EF.getSectionName(*getSection(Sec));
}
template <class ELFT>
@@ -930,7 +930,7 @@ ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
if (!SectionsOrErr)
return relocation_iterator(RelocationRef());
uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin());
- RelData.d.a = (Sec.p - SHT) / EF.getHeader().e_shentsize;
+ RelData.d.a = (Sec.p - SHT) / EF.getHeader().e_shentsize;
RelData.d.b = 0;
return relocation_iterator(RelocationRef(RelData, this));
}
@@ -957,7 +957,7 @@ ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
template <class ELFT>
Expected<section_iterator>
ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
- if (EF.getHeader().e_type != ELF::ET_REL)
+ if (EF.getHeader().e_type != ELF::ET_REL)
return section_end();
const Elf_Shdr *EShdr = getSection(Sec);
@@ -1016,7 +1016,7 @@ uint64_t ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel) const {
template <class ELFT>
StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
- return getELFRelocationTypeName(EF.getHeader().e_machine, Type);
+ return getELFRelocationTypeName(EF.getHeader().e_machine, Type);
}
template <class ELFT>
@@ -1056,34 +1056,34 @@ ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
template <class ELFT>
Expected<ELFObjectFile<ELFT>>
-ELFObjectFile<ELFT>::create(MemoryBufferRef Object, bool InitContent) {
+ELFObjectFile<ELFT>::create(MemoryBufferRef Object, bool InitContent) {
auto EFOrErr = ELFFile<ELFT>::create(Object.getBuffer());
if (Error E = EFOrErr.takeError())
return std::move(E);
- ELFObjectFile<ELFT> Obj = {Object, std::move(*EFOrErr), nullptr, nullptr,
- nullptr};
- if (InitContent)
- if (Error E = Obj.initContent())
- return std::move(E);
- return std::move(Obj);
+ ELFObjectFile<ELFT> Obj = {Object, std::move(*EFOrErr), nullptr, nullptr,
+ nullptr};
+ if (InitContent)
+ if (Error E = Obj.initContent())
+ return std::move(E);
+ return std::move(Obj);
}
template <class ELFT>
ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
const Elf_Shdr *DotDynSymSec,
const Elf_Shdr *DotSymtabSec,
- const Elf_Shdr *DotSymtabShndx)
+ const Elf_Shdr *DotSymtabShndx)
: ELFObjectFileBase(
getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits),
Object),
EF(EF), DotDynSymSec(DotDynSymSec), DotSymtabSec(DotSymtabSec),
- DotSymtabShndxSec(DotSymtabShndx) {}
+ DotSymtabShndxSec(DotSymtabShndx) {}
template <class ELFT>
ELFObjectFile<ELFT>::ELFObjectFile(ELFObjectFile<ELFT> &&Other)
: ELFObjectFile(Other.Data, Other.EF, Other.DotDynSymSec,
- Other.DotSymtabSec, Other.DotSymtabShndxSec) {}
+ Other.DotSymtabSec, Other.DotSymtabShndxSec) {}
template <class ELFT>
basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin() const {
@@ -1145,9 +1145,9 @@ uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const {
template <class ELFT>
StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
bool IsLittleEndian = ELFT::TargetEndianness == support::little;
- switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
+ switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
case ELF::ELFCLASS32:
- switch (EF.getHeader().e_machine) {
+ switch (EF.getHeader().e_machine) {
case ELF::EM_386:
return "elf32-i386";
case ELF::EM_IAMCU:
@@ -1167,11 +1167,11 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
case ELF::EM_MSP430:
return "elf32-msp430";
case ELF::EM_PPC:
- return (IsLittleEndian ? "elf32-powerpcle" : "elf32-powerpc");
+ return (IsLittleEndian ? "elf32-powerpcle" : "elf32-powerpc");
case ELF::EM_RISCV:
return "elf32-littleriscv";
- case ELF::EM_CSKY:
- return "elf32-csky";
+ case ELF::EM_CSKY:
+ return "elf32-csky";
case ELF::EM_SPARC:
case ELF::EM_SPARC32PLUS:
return "elf32-sparc";
@@ -1181,7 +1181,7 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
return "elf32-unknown";
}
case ELF::ELFCLASS64:
- switch (EF.getHeader().e_machine) {
+ switch (EF.getHeader().e_machine) {
case ELF::EM_386:
return "elf64-i386";
case ELF::EM_X86_64:
@@ -1215,7 +1215,7 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
bool IsLittleEndian = ELFT::TargetEndianness == support::little;
- switch (EF.getHeader().e_machine) {
+ switch (EF.getHeader().e_machine) {
case ELF::EM_386:
case ELF::EM_IAMCU:
return Triple::x86;
@@ -1232,7 +1232,7 @@ template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
case ELF::EM_LANAI:
return Triple::lanai;
case ELF::EM_MIPS:
- switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
+ switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
case ELF::ELFCLASS32:
return IsLittleEndian ? Triple::mipsel : Triple::mips;
case ELF::ELFCLASS64:
@@ -1243,11 +1243,11 @@ template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
case ELF::EM_MSP430:
return Triple::msp430;
case ELF::EM_PPC:
- return IsLittleEndian ? Triple::ppcle : Triple::ppc;
+ return IsLittleEndian ? Triple::ppcle : Triple::ppc;
case ELF::EM_PPC64:
return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
case ELF::EM_RISCV:
- switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
+ switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
case ELF::ELFCLASS32:
return Triple::riscv32;
case ELF::ELFCLASS64:
@@ -1268,7 +1268,7 @@ template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
if (!IsLittleEndian)
return Triple::UnknownArch;
- unsigned MACH = EF.getHeader().e_flags & ELF::EF_AMDGPU_MACH;
+ unsigned MACH = EF.getHeader().e_flags & ELF::EF_AMDGPU_MACH;
if (MACH >= ELF::EF_AMDGPU_MACH_R600_FIRST &&
MACH <= ELF::EF_AMDGPU_MACH_R600_LAST)
return Triple::r600;
@@ -1284,8 +1284,8 @@ template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
case ELF::EM_VE:
return Triple::ve;
- case ELF::EM_CSKY:
- return Triple::csky;
+ case ELF::EM_CSKY:
+ return Triple::csky;
default:
return Triple::UnknownArch;
}
@@ -1293,7 +1293,7 @@ template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
template <class ELFT>
Expected<uint64_t> ELFObjectFile<ELFT>::getStartAddress() const {
- return EF.getHeader().e_entry;
+ return EF.getHeader().e_entry;
}
template <class ELFT>
@@ -1303,7 +1303,7 @@ ELFObjectFile<ELFT>::getDynamicSymbolIterators() const {
}
template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const {
- return EF.getHeader().e_type == ELF::ET_REL;
+ return EF.getHeader().e_type == ELF::ET_REL;
}
} // end namespace object
diff --git a/contrib/libs/llvm12/include/llvm/Object/ELFTypes.h b/contrib/libs/llvm12/include/llvm/Object/ELFTypes.h
index 06f06c9aca..320dfaa573 100644
--- a/contrib/libs/llvm12/include/llvm/Object/ELFTypes.h
+++ b/contrib/libs/llvm12/include/llvm/Object/ELFTypes.h
@@ -114,34 +114,34 @@ using ELF64BE = ELFType<support::big, true>;
using Elf_Word = typename ELFT::Word; \
using Elf_Sword = typename ELFT::Sword; \
using Elf_Xword = typename ELFT::Xword; \
- using Elf_Sxword = typename ELFT::Sxword; \
- using uintX_t = typename ELFT::uint; \
- using Elf_Ehdr = typename ELFT::Ehdr; \
- using Elf_Shdr = typename ELFT::Shdr; \
- using Elf_Sym = typename ELFT::Sym; \
- using Elf_Dyn = typename ELFT::Dyn; \
- using Elf_Phdr = typename ELFT::Phdr; \
- using Elf_Rel = typename ELFT::Rel; \
- using Elf_Rela = typename ELFT::Rela; \
- using Elf_Relr = typename ELFT::Relr; \
- using Elf_Verdef = typename ELFT::Verdef; \
- using Elf_Verdaux = typename ELFT::Verdaux; \
- using Elf_Verneed = typename ELFT::Verneed; \
- using Elf_Vernaux = typename ELFT::Vernaux; \
- using Elf_Versym = typename ELFT::Versym; \
- using Elf_Hash = typename ELFT::Hash; \
- using Elf_GnuHash = typename ELFT::GnuHash; \
- using Elf_Nhdr = typename ELFT::Nhdr; \
- using Elf_Note = typename ELFT::Note; \
- using Elf_Note_Iterator = typename ELFT::NoteIterator; \
- using Elf_CGProfile = typename ELFT::CGProfile; \
- using Elf_Dyn_Range = typename ELFT::DynRange; \
- using Elf_Shdr_Range = typename ELFT::ShdrRange; \
- using Elf_Sym_Range = typename ELFT::SymRange; \
- using Elf_Rel_Range = typename ELFT::RelRange; \
- using Elf_Rela_Range = typename ELFT::RelaRange; \
- using Elf_Relr_Range = typename ELFT::RelrRange; \
- using Elf_Phdr_Range = typename ELFT::PhdrRange; \
+ using Elf_Sxword = typename ELFT::Sxword; \
+ using uintX_t = typename ELFT::uint; \
+ using Elf_Ehdr = typename ELFT::Ehdr; \
+ using Elf_Shdr = typename ELFT::Shdr; \
+ using Elf_Sym = typename ELFT::Sym; \
+ using Elf_Dyn = typename ELFT::Dyn; \
+ using Elf_Phdr = typename ELFT::Phdr; \
+ using Elf_Rel = typename ELFT::Rel; \
+ using Elf_Rela = typename ELFT::Rela; \
+ using Elf_Relr = typename ELFT::Relr; \
+ using Elf_Verdef = typename ELFT::Verdef; \
+ using Elf_Verdaux = typename ELFT::Verdaux; \
+ using Elf_Verneed = typename ELFT::Verneed; \
+ using Elf_Vernaux = typename ELFT::Vernaux; \
+ using Elf_Versym = typename ELFT::Versym; \
+ using Elf_Hash = typename ELFT::Hash; \
+ using Elf_GnuHash = typename ELFT::GnuHash; \
+ using Elf_Nhdr = typename ELFT::Nhdr; \
+ using Elf_Note = typename ELFT::Note; \
+ using Elf_Note_Iterator = typename ELFT::NoteIterator; \
+ using Elf_CGProfile = typename ELFT::CGProfile; \
+ using Elf_Dyn_Range = typename ELFT::DynRange; \
+ using Elf_Shdr_Range = typename ELFT::ShdrRange; \
+ using Elf_Sym_Range = typename ELFT::SymRange; \
+ using Elf_Rel_Range = typename ELFT::RelRange; \
+ using Elf_Rela_Range = typename ELFT::RelaRange; \
+ using Elf_Relr_Range = typename ELFT::RelrRange; \
+ using Elf_Phdr_Range = typename ELFT::PhdrRange; \
#define LLVM_ELF_COMMA ,
#define LLVM_ELF_IMPORT_TYPES(E, W) \
diff --git a/contrib/libs/llvm12/include/llvm/Object/MachO.h b/contrib/libs/llvm12/include/llvm/Object/MachO.h
index 4418f8fb75..bbc0a233ee 100644
--- a/contrib/libs/llvm12/include/llvm/Object/MachO.h
+++ b/contrib/libs/llvm12/include/llvm/Object/MachO.h
@@ -622,7 +622,7 @@ public:
case MachO::PLATFORM_IOSSIMULATOR: return "iossimulator";
case MachO::PLATFORM_TVOSSIMULATOR: return "tvossimulator";
case MachO::PLATFORM_WATCHOSSIMULATOR: return "watchossimulator";
- case MachO::PLATFORM_DRIVERKIT: return "driverkit";
+ case MachO::PLATFORM_DRIVERKIT: return "driverkit";
default:
std::string ret;
raw_string_ostream ss(ret);
diff --git a/contrib/libs/llvm12/include/llvm/Object/MachOUniversal.h b/contrib/libs/llvm12/include/llvm/Object/MachOUniversal.h
index 5ba205404a..2f34b6a71b 100644
--- a/contrib/libs/llvm12/include/llvm/Object/MachOUniversal.h
+++ b/contrib/libs/llvm12/include/llvm/Object/MachOUniversal.h
@@ -29,11 +29,11 @@
namespace llvm {
class StringRef;
-class Module;
-class LLVMContext;
+class Module;
+class LLVMContext;
namespace object {
-class IRObjectFile;
+class IRObjectFile;
class MachOUniversalBinary : public Binary {
virtual void anchor();
@@ -111,8 +111,8 @@ public:
}
Expected<std::unique_ptr<MachOObjectFile>> getAsObjectFile() const;
- Expected<std::unique_ptr<IRObjectFile>>
- getAsIRObject(LLVMContext &Ctx) const;
+ Expected<std::unique_ptr<IRObjectFile>>
+ getAsIRObject(LLVMContext &Ctx) const;
Expected<std::unique_ptr<Archive>> getAsArchive() const;
};
@@ -166,9 +166,9 @@ public:
Expected<std::unique_ptr<MachOObjectFile>>
getMachOObjectForArch(StringRef ArchName) const;
- Expected<std::unique_ptr<IRObjectFile>>
- getIRObjectForArch(StringRef ArchName, LLVMContext &Ctx) const;
-
+ Expected<std::unique_ptr<IRObjectFile>>
+ getIRObjectForArch(StringRef ArchName, LLVMContext &Ctx) const;
+
Expected<std::unique_ptr<Archive>>
getArchiveForArch(StringRef ArchName) const;
};
diff --git a/contrib/libs/llvm12/include/llvm/Object/MachOUniversalWriter.h b/contrib/libs/llvm12/include/llvm/Object/MachOUniversalWriter.h
index 322ace8925..0ff4beabc7 100644
--- a/contrib/libs/llvm12/include/llvm/Object/MachOUniversalWriter.h
+++ b/contrib/libs/llvm12/include/llvm/Object/MachOUniversalWriter.h
@@ -1,113 +1,113 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- MachOUniversalWriter.h - MachO universal binary writer----*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Declares the Slice class and writeUniversalBinary function for writing a
-// MachO universal binary file.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_MACHOUNIVERSALWRITER_H
-#define LLVM_OBJECT_MACHOUNIVERSALWRITER_H
-
-#include "llvm/Object/Archive.h"
-#include "llvm/Object/Binary.h"
-#include "llvm/Object/MachO.h"
-
-namespace llvm {
-class LLVMContext;
-
-namespace object {
-class IRObjectFile;
-
-class Slice {
- const Binary *B;
- uint32_t CPUType;
- uint32_t CPUSubType;
- std::string ArchName;
-
- // P2Alignment field stores slice alignment values from universal
- // binaries. This is also needed to order the slices so the total
- // file size can be calculated before creating the output buffer.
- uint32_t P2Alignment;
-
- Slice(const IRObjectFile &IRO, uint32_t CPUType, uint32_t CPUSubType,
- std::string ArchName, uint32_t Align);
-
-public:
- explicit Slice(const MachOObjectFile &O);
-
- Slice(const MachOObjectFile &O, uint32_t Align);
-
- /// This constructor takes pre-specified \param CPUType , \param CPUSubType ,
- /// \param ArchName , \param Align instead of inferring them from the archive
- /// members.
- Slice(const Archive &A, uint32_t CPUType, uint32_t CPUSubType,
- std::string ArchName, uint32_t Align);
-
- static Expected<Slice> create(const Archive &A,
- LLVMContext *LLVMCtx = nullptr);
-
- static Expected<Slice> create(const IRObjectFile &IRO, uint32_t Align);
-
- void setP2Alignment(uint32_t Align) { P2Alignment = Align; }
-
- const Binary *getBinary() const { return B; }
-
- uint32_t getCPUType() const { return CPUType; }
-
- uint32_t getCPUSubType() const { return CPUSubType; }
-
- uint32_t getP2Alignment() const { return P2Alignment; }
-
- uint64_t getCPUID() const {
- return static_cast<uint64_t>(CPUType) << 32 | CPUSubType;
- }
-
- std::string getArchString() const {
- if (!ArchName.empty())
- return ArchName;
- return ("unknown(" + Twine(CPUType) + "," +
- Twine(CPUSubType & ~MachO::CPU_SUBTYPE_MASK) + ")")
- .str();
- }
-
- friend bool operator<(const Slice &Lhs, const Slice &Rhs) {
- if (Lhs.CPUType == Rhs.CPUType)
- return Lhs.CPUSubType < Rhs.CPUSubType;
- // force arm64-family to follow after all other slices for
- // compatibility with cctools lipo
- if (Lhs.CPUType == MachO::CPU_TYPE_ARM64)
- return false;
- if (Rhs.CPUType == MachO::CPU_TYPE_ARM64)
- return true;
- // Sort by alignment to minimize file size
- return Lhs.P2Alignment < Rhs.P2Alignment;
- }
-};
-
-Error writeUniversalBinary(ArrayRef<Slice> Slices, StringRef OutputFileName);
-
-Expected<std::unique_ptr<MemoryBuffer>>
-writeUniversalBinaryToBuffer(ArrayRef<Slice> Slices);
-
-} // end namespace object
-
-} // end namespace llvm
-
-#endif // LLVM_OBJECT_MACHOUNIVERSALWRITER_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- MachOUniversalWriter.h - MachO universal binary writer----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Declares the Slice class and writeUniversalBinary function for writing a
+// MachO universal binary file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MACHOUNIVERSALWRITER_H
+#define LLVM_OBJECT_MACHOUNIVERSALWRITER_H
+
+#include "llvm/Object/Archive.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/MachO.h"
+
+namespace llvm {
+class LLVMContext;
+
+namespace object {
+class IRObjectFile;
+
+class Slice {
+ const Binary *B;
+ uint32_t CPUType;
+ uint32_t CPUSubType;
+ std::string ArchName;
+
+ // P2Alignment field stores slice alignment values from universal
+ // binaries. This is also needed to order the slices so the total
+ // file size can be calculated before creating the output buffer.
+ uint32_t P2Alignment;
+
+ Slice(const IRObjectFile &IRO, uint32_t CPUType, uint32_t CPUSubType,
+ std::string ArchName, uint32_t Align);
+
+public:
+ explicit Slice(const MachOObjectFile &O);
+
+ Slice(const MachOObjectFile &O, uint32_t Align);
+
+ /// This constructor takes pre-specified \param CPUType , \param CPUSubType ,
+ /// \param ArchName , \param Align instead of inferring them from the archive
+ /// members.
+ Slice(const Archive &A, uint32_t CPUType, uint32_t CPUSubType,
+ std::string ArchName, uint32_t Align);
+
+ static Expected<Slice> create(const Archive &A,
+ LLVMContext *LLVMCtx = nullptr);
+
+ static Expected<Slice> create(const IRObjectFile &IRO, uint32_t Align);
+
+ void setP2Alignment(uint32_t Align) { P2Alignment = Align; }
+
+ const Binary *getBinary() const { return B; }
+
+ uint32_t getCPUType() const { return CPUType; }
+
+ uint32_t getCPUSubType() const { return CPUSubType; }
+
+ uint32_t getP2Alignment() const { return P2Alignment; }
+
+ uint64_t getCPUID() const {
+ return static_cast<uint64_t>(CPUType) << 32 | CPUSubType;
+ }
+
+ std::string getArchString() const {
+ if (!ArchName.empty())
+ return ArchName;
+ return ("unknown(" + Twine(CPUType) + "," +
+ Twine(CPUSubType & ~MachO::CPU_SUBTYPE_MASK) + ")")
+ .str();
+ }
+
+ friend bool operator<(const Slice &Lhs, const Slice &Rhs) {
+ if (Lhs.CPUType == Rhs.CPUType)
+ return Lhs.CPUSubType < Rhs.CPUSubType;
+ // force arm64-family to follow after all other slices for
+ // compatibility with cctools lipo
+ if (Lhs.CPUType == MachO::CPU_TYPE_ARM64)
+ return false;
+ if (Rhs.CPUType == MachO::CPU_TYPE_ARM64)
+ return true;
+ // Sort by alignment to minimize file size
+ return Lhs.P2Alignment < Rhs.P2Alignment;
+ }
+};
+
+Error writeUniversalBinary(ArrayRef<Slice> Slices, StringRef OutputFileName);
+
+Expected<std::unique_ptr<MemoryBuffer>>
+writeUniversalBinaryToBuffer(ArrayRef<Slice> Slices);
+
+} // end namespace object
+
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_MACHOUNIVERSALWRITER_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/ObjectFile.h b/contrib/libs/llvm12/include/llvm/Object/ObjectFile.h
index 1bb4ae876e..7f9ec78c1d 100644
--- a/contrib/libs/llvm12/include/llvm/Object/ObjectFile.h
+++ b/contrib/libs/llvm12/include/llvm/Object/ObjectFile.h
@@ -334,7 +334,7 @@ public:
virtual StringRef getFileFormatName() const = 0;
virtual Triple::ArchType getArch() const = 0;
virtual SubtargetFeatures getFeatures() const = 0;
- virtual Optional<StringRef> tryGetCPUName() const { return None; };
+ virtual Optional<StringRef> tryGetCPUName() const { return None; };
virtual void setARMSubArch(Triple &TheTriple) const { }
virtual Expected<uint64_t> getStartAddress() const {
return errorCodeToError(object_error::parse_failed);
@@ -357,8 +357,8 @@ public:
createObjectFile(StringRef ObjectPath);
static Expected<std::unique_ptr<ObjectFile>>
- createObjectFile(MemoryBufferRef Object, llvm::file_magic Type,
- bool InitContent = true);
+ createObjectFile(MemoryBufferRef Object, llvm::file_magic Type,
+ bool InitContent = true);
static Expected<std::unique_ptr<ObjectFile>>
createObjectFile(MemoryBufferRef Object) {
return createObjectFile(Object, llvm::file_magic::unknown);
@@ -375,7 +375,7 @@ public:
createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
static Expected<std::unique_ptr<ObjectFile>>
- createELFObjectFile(MemoryBufferRef Object, bool InitContent = true);
+ createELFObjectFile(MemoryBufferRef Object, bool InitContent = true);
static Expected<std::unique_ptr<MachOObjectFile>>
createMachOObjectFile(MemoryBufferRef Object,
diff --git a/contrib/libs/llvm12/include/llvm/Object/RelocationResolver.h b/contrib/libs/llvm12/include/llvm/Object/RelocationResolver.h
index 83a5f92c70..d53f50e3e5 100644
--- a/contrib/libs/llvm12/include/llvm/Object/RelocationResolver.h
+++ b/contrib/libs/llvm12/include/llvm/Object/RelocationResolver.h
@@ -38,17 +38,17 @@
namespace llvm {
namespace object {
-using SupportsRelocation = bool (*)(uint64_t);
-using RelocationResolver = uint64_t (*)(uint64_t Type, uint64_t Offset,
- uint64_t S, uint64_t LocData,
- int64_t Addend);
+using SupportsRelocation = bool (*)(uint64_t);
+using RelocationResolver = uint64_t (*)(uint64_t Type, uint64_t Offset,
+ uint64_t S, uint64_t LocData,
+ int64_t Addend);
-std::pair<SupportsRelocation, RelocationResolver>
+std::pair<SupportsRelocation, RelocationResolver>
getRelocationResolver(const ObjectFile &Obj);
-uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,
- uint64_t S, uint64_t LocData);
-
+uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,
+ uint64_t S, uint64_t LocData);
+
} // end namespace object
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Object/StackMapParser.h b/contrib/libs/llvm12/include/llvm/Object/StackMapParser.h
index 52fd959d66..4551e80bb2 100644
--- a/contrib/libs/llvm12/include/llvm/Object/StackMapParser.h
+++ b/contrib/libs/llvm12/include/llvm/Object/StackMapParser.h
@@ -18,7 +18,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/iterator_range.h"
-#include "llvm/Object/ELF.h"
+#include "llvm/Object/ELF.h"
#include "llvm/Support/Endian.h"
#include <cassert>
#include <cstddef>
@@ -328,23 +328,23 @@ public:
}
}
- /// Validates the header of the specified stack map section.
- static Error validateHeader(ArrayRef<uint8_t> StackMapSection) {
- // See the comment for StackMaps::emitStackmapHeader().
- if (StackMapSection.size() < 16)
- return object::createError(
- "the stack map section size (" + Twine(StackMapSection.size()) +
- ") is less than the minimum possible size of its header (16)");
-
- unsigned Version = StackMapSection[0];
- if (Version != 3)
- return object::createError(
- "the version (" + Twine(Version) +
- ") of the stack map section is unsupported, the "
- "supported version is 3");
- return Error::success();
- }
-
+ /// Validates the header of the specified stack map section.
+ static Error validateHeader(ArrayRef<uint8_t> StackMapSection) {
+ // See the comment for StackMaps::emitStackmapHeader().
+ if (StackMapSection.size() < 16)
+ return object::createError(
+ "the stack map section size (" + Twine(StackMapSection.size()) +
+ ") is less than the minimum possible size of its header (16)");
+
+ unsigned Version = StackMapSection[0];
+ if (Version != 3)
+ return object::createError(
+ "the version (" + Twine(Version) +
+ ") of the stack map section is unsupported, the "
+ "supported version is 3");
+ return Error::success();
+ }
+
using function_iterator = AccessorIterator<FunctionAccessor>;
using constant_iterator = AccessorIterator<ConstantAccessor>;
using record_iterator = AccessorIterator<RecordAccessor>;
diff --git a/contrib/libs/llvm12/include/llvm/Object/SymbolicFile.h b/contrib/libs/llvm12/include/llvm/Object/SymbolicFile.h
index b538afa2ab..928c0ad8b3 100644
--- a/contrib/libs/llvm12/include/llvm/Object/SymbolicFile.h
+++ b/contrib/libs/llvm12/include/llvm/Object/SymbolicFile.h
@@ -168,7 +168,7 @@ public:
// construction aux.
static Expected<std::unique_ptr<SymbolicFile>>
createSymbolicFile(MemoryBufferRef Object, llvm::file_magic Type,
- LLVMContext *Context, bool InitContent = true);
+ LLVMContext *Context, bool InitContent = true);
static Expected<std::unique_ptr<SymbolicFile>>
createSymbolicFile(MemoryBufferRef Object) {
@@ -178,8 +178,8 @@ public:
static bool classof(const Binary *v) {
return v->isSymbolic();
}
-
- static bool isSymbolicFile(file_magic Type, const LLVMContext *Context);
+
+ static bool isSymbolicFile(file_magic Type, const LLVMContext *Context);
};
inline BasicSymbolRef::BasicSymbolRef(DataRefImpl SymbolP,
diff --git a/contrib/libs/llvm12/include/llvm/Object/Wasm.h b/contrib/libs/llvm12/include/llvm/Object/Wasm.h
index ab1fbba6be..80e3ddd109 100644
--- a/contrib/libs/llvm12/include/llvm/Object/Wasm.h
+++ b/contrib/libs/llvm12/include/llvm/Object/Wasm.h
@@ -43,15 +43,15 @@ class WasmSymbol {
public:
WasmSymbol(const wasm::WasmSymbolInfo &Info,
const wasm::WasmGlobalType *GlobalType,
- const wasm::WasmTableType *TableType,
+ const wasm::WasmTableType *TableType,
const wasm::WasmEventType *EventType,
const wasm::WasmSignature *Signature)
- : Info(Info), GlobalType(GlobalType), TableType(TableType),
- EventType(EventType), Signature(Signature) {}
+ : Info(Info), GlobalType(GlobalType), TableType(TableType),
+ EventType(EventType), Signature(Signature) {}
const wasm::WasmSymbolInfo &Info;
const wasm::WasmGlobalType *GlobalType;
- const wasm::WasmTableType *TableType;
+ const wasm::WasmTableType *TableType;
const wasm::WasmEventType *EventType;
const wasm::WasmSignature *Signature;
@@ -59,8 +59,8 @@ public:
return Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION;
}
- bool isTypeTable() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_TABLE; }
-
+ bool isTypeTable() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_TABLE; }
+
bool isTypeData() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA; }
bool isTypeGlobal() const {
@@ -116,7 +116,7 @@ struct WasmSection {
uint32_t Type = 0; // Section type (See below)
uint32_t Offset = 0; // Offset with in the file
StringRef Name; // Section name (User-defined sections only)
- uint32_t Comdat = UINT32_MAX; // From the "comdat info" section
+ uint32_t Comdat = UINT32_MAX; // From the "comdat info" section
ArrayRef<uint8_t> Content; // Section content
std::vector<wasm::WasmRelocation> Relocations; // Relocations for this section
};
@@ -158,10 +158,10 @@ public:
ArrayRef<wasm::WasmElemSegment> elements() const { return ElemSegments; }
ArrayRef<WasmSegment> dataSegments() const { return DataSegments; }
ArrayRef<wasm::WasmFunction> functions() const { return Functions; }
- ArrayRef<wasm::WasmDebugName> debugNames() const { return DebugNames; }
+ ArrayRef<wasm::WasmDebugName> debugNames() const { return DebugNames; }
uint32_t startFunction() const { return StartFunction; }
uint32_t getNumImportedGlobals() const { return NumImportedGlobals; }
- uint32_t getNumImportedTables() const { return NumImportedTables; }
+ uint32_t getNumImportedTables() const { return NumImportedTables; }
uint32_t getNumImportedFunctions() const { return NumImportedFunctions; }
uint32_t getNumImportedEvents() const { return NumImportedEvents; }
uint32_t getNumSections() const { return Sections.size(); }
@@ -227,13 +227,13 @@ private:
bool isValidFunctionIndex(uint32_t Index) const;
bool isDefinedFunctionIndex(uint32_t Index) const;
bool isValidGlobalIndex(uint32_t Index) const;
- bool isValidTableIndex(uint32_t Index) const;
+ bool isValidTableIndex(uint32_t Index) const;
bool isDefinedGlobalIndex(uint32_t Index) const;
- bool isDefinedTableIndex(uint32_t Index) const;
+ bool isDefinedTableIndex(uint32_t Index) const;
bool isValidEventIndex(uint32_t Index) const;
bool isDefinedEventIndex(uint32_t Index) const;
bool isValidFunctionSymbol(uint32_t Index) const;
- bool isValidTableSymbol(uint32_t Index) const;
+ bool isValidTableSymbol(uint32_t Index) const;
bool isValidGlobalSymbol(uint32_t Index) const;
bool isValidEventSymbol(uint32_t Index) const;
bool isValidDataSymbol(uint32_t Index) const;
@@ -293,22 +293,22 @@ private:
llvm::Optional<size_t> DataCount;
std::vector<wasm::WasmFunction> Functions;
std::vector<WasmSymbol> Symbols;
- std::vector<wasm::WasmDebugName> DebugNames;
+ std::vector<wasm::WasmDebugName> DebugNames;
uint32_t StartFunction = -1;
bool HasLinkingSection = false;
bool HasDylinkSection = false;
bool SeenCodeSection = false;
- bool HasMemory64 = false;
+ bool HasMemory64 = false;
wasm::WasmLinkingData LinkingData;
uint32_t NumImportedGlobals = 0;
- uint32_t NumImportedTables = 0;
+ uint32_t NumImportedTables = 0;
uint32_t NumImportedFunctions = 0;
uint32_t NumImportedEvents = 0;
uint32_t CodeSection = 0;
uint32_t DataSection = 0;
uint32_t EventSection = 0;
uint32_t GlobalSection = 0;
- uint32_t TableSection = 0;
+ uint32_t TableSection = 0;
};
class WasmSectionOrderChecker {
diff --git a/contrib/libs/llvm12/include/llvm/Object/XCOFFObjectFile.h b/contrib/libs/llvm12/include/llvm/Object/XCOFFObjectFile.h
index 6104dc362c..ba11d43c43 100644
--- a/contrib/libs/llvm12/include/llvm/Object/XCOFFObjectFile.h
+++ b/contrib/libs/llvm12/include/llvm/Object/XCOFFObjectFile.h
@@ -20,8 +20,8 @@
#ifndef LLVM_OBJECT_XCOFFOBJECTFILE_H
#define LLVM_OBJECT_XCOFFOBJECTFILE_H
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/BinaryFormat/XCOFF.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Endian.h"
@@ -379,8 +379,8 @@ public:
Expected<ArrayRef<XCOFFRelocation32>>
relocations(const XCOFFSectionHeader32 &) const;
-
- static bool classof(const Binary *B) { return B->isXCOFF(); }
+
+ static bool classof(const Binary *B) { return B->isXCOFF(); }
}; // XCOFFObjectFile
class XCOFFSymbolRef {
@@ -402,103 +402,103 @@ public:
bool isFunction() const;
};
-class TBVectorExt {
- friend class XCOFFTracebackTable;
-
- uint16_t Data;
- uint32_t VecParmsInfo;
-
- TBVectorExt(StringRef TBvectorStrRef);
-
-public:
- uint8_t getNumberOfVRSaved() const;
- bool isVRSavedOnStack() const;
- bool hasVarArgs() const;
- uint8_t getNumberOfVectorParms() const;
- bool hasVMXInstruction() const;
- SmallString<32> getVectorParmsInfoString() const;
-};
-
-/// This class provides methods to extract traceback table data from a buffer.
-/// The various accessors may reference the buffer provided via the constructor.
-
-class XCOFFTracebackTable {
- const uint8_t *const TBPtr;
- Optional<SmallString<32>> ParmsType;
- Optional<uint32_t> TraceBackTableOffset;
- Optional<uint32_t> HandlerMask;
- Optional<uint32_t> NumOfCtlAnchors;
- Optional<SmallVector<uint32_t, 8>> ControlledStorageInfoDisp;
- Optional<StringRef> FunctionName;
- Optional<uint8_t> AllocaRegister;
- Optional<TBVectorExt> VecExt;
- Optional<uint8_t> ExtensionTable;
-
- XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size, Error &Err);
-public:
- /// Parse an XCOFF Traceback Table from \a Ptr with \a Size bytes.
- /// Returns an XCOFFTracebackTable upon successful parsing, otherwise an
- /// Error is returned.
- ///
- /// \param[in] Ptr
- /// A pointer that points just past the initial 4 bytes of zeros at the
- /// beginning of an XCOFF Traceback Table.
- ///
- /// \param[in, out] Size
- /// A pointer that points to the length of the XCOFF Traceback Table.
- /// If the XCOFF Traceback Table is not parsed successfully or there are
- /// extra bytes that are not recognized, \a Size will be updated to be the
- /// size up to the end of the last successfully parsed field of the table.
- static Expected<XCOFFTracebackTable> create(const uint8_t *Ptr,
- uint64_t &Size);
- uint8_t getVersion() const;
- uint8_t getLanguageID() const;
-
- bool isGlobalLinkage() const;
- bool isOutOfLineEpilogOrPrologue() const;
- bool hasTraceBackTableOffset() const;
- bool isInternalProcedure() const;
- bool hasControlledStorage() const;
- bool isTOCless() const;
- bool isFloatingPointPresent() const;
- bool isFloatingPointOperationLogOrAbortEnabled() const;
-
- bool isInterruptHandler() const;
- bool isFuncNamePresent() const;
- bool isAllocaUsed() const;
- uint8_t getOnConditionDirective() const;
- bool isCRSaved() const;
- bool isLRSaved() const;
-
- bool isBackChainStored() const;
- bool isFixup() const;
- uint8_t getNumOfFPRsSaved() const;
-
- bool hasVectorInfo() const;
- bool hasExtensionTable() const;
- uint8_t getNumOfGPRsSaved() const;
-
- uint8_t getNumberOfFixedParms() const;
-
- uint8_t getNumberOfFPParms() const;
- bool hasParmsOnStack() const;
-
- const Optional<SmallString<32>> &getParmsType() const { return ParmsType; }
- const Optional<uint32_t> &getTraceBackTableOffset() const {
- return TraceBackTableOffset;
- }
- const Optional<uint32_t> &getHandlerMask() const { return HandlerMask; }
- const Optional<uint32_t> &getNumOfCtlAnchors() { return NumOfCtlAnchors; }
- const Optional<SmallVector<uint32_t, 8>> &getControlledStorageInfoDisp() {
- return ControlledStorageInfoDisp;
- }
- const Optional<StringRef> &getFunctionName() const { return FunctionName; }
- const Optional<uint8_t> &getAllocaRegister() const { return AllocaRegister; }
- const Optional<TBVectorExt> &getVectorExt() const { return VecExt; }
- const Optional<uint8_t> &getExtensionTable() const { return ExtensionTable; }
-};
-
-bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes);
+class TBVectorExt {
+ friend class XCOFFTracebackTable;
+
+ uint16_t Data;
+ uint32_t VecParmsInfo;
+
+ TBVectorExt(StringRef TBvectorStrRef);
+
+public:
+ uint8_t getNumberOfVRSaved() const;
+ bool isVRSavedOnStack() const;
+ bool hasVarArgs() const;
+ uint8_t getNumberOfVectorParms() const;
+ bool hasVMXInstruction() const;
+ SmallString<32> getVectorParmsInfoString() const;
+};
+
+/// This class provides methods to extract traceback table data from a buffer.
+/// The various accessors may reference the buffer provided via the constructor.
+
+class XCOFFTracebackTable {
+ const uint8_t *const TBPtr;
+ Optional<SmallString<32>> ParmsType;
+ Optional<uint32_t> TraceBackTableOffset;
+ Optional<uint32_t> HandlerMask;
+ Optional<uint32_t> NumOfCtlAnchors;
+ Optional<SmallVector<uint32_t, 8>> ControlledStorageInfoDisp;
+ Optional<StringRef> FunctionName;
+ Optional<uint8_t> AllocaRegister;
+ Optional<TBVectorExt> VecExt;
+ Optional<uint8_t> ExtensionTable;
+
+ XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size, Error &Err);
+public:
+ /// Parse an XCOFF Traceback Table from \a Ptr with \a Size bytes.
+ /// Returns an XCOFFTracebackTable upon successful parsing, otherwise an
+ /// Error is returned.
+ ///
+ /// \param[in] Ptr
+ /// A pointer that points just past the initial 4 bytes of zeros at the
+ /// beginning of an XCOFF Traceback Table.
+ ///
+ /// \param[in, out] Size
+ /// A pointer that points to the length of the XCOFF Traceback Table.
+ /// If the XCOFF Traceback Table is not parsed successfully or there are
+ /// extra bytes that are not recognized, \a Size will be updated to be the
+ /// size up to the end of the last successfully parsed field of the table.
+ static Expected<XCOFFTracebackTable> create(const uint8_t *Ptr,
+ uint64_t &Size);
+ uint8_t getVersion() const;
+ uint8_t getLanguageID() const;
+
+ bool isGlobalLinkage() const;
+ bool isOutOfLineEpilogOrPrologue() const;
+ bool hasTraceBackTableOffset() const;
+ bool isInternalProcedure() const;
+ bool hasControlledStorage() const;
+ bool isTOCless() const;
+ bool isFloatingPointPresent() const;
+ bool isFloatingPointOperationLogOrAbortEnabled() const;
+
+ bool isInterruptHandler() const;
+ bool isFuncNamePresent() const;
+ bool isAllocaUsed() const;
+ uint8_t getOnConditionDirective() const;
+ bool isCRSaved() const;
+ bool isLRSaved() const;
+
+ bool isBackChainStored() const;
+ bool isFixup() const;
+ uint8_t getNumOfFPRsSaved() const;
+
+ bool hasVectorInfo() const;
+ bool hasExtensionTable() const;
+ uint8_t getNumOfGPRsSaved() const;
+
+ uint8_t getNumberOfFixedParms() const;
+
+ uint8_t getNumberOfFPParms() const;
+ bool hasParmsOnStack() const;
+
+ const Optional<SmallString<32>> &getParmsType() const { return ParmsType; }
+ const Optional<uint32_t> &getTraceBackTableOffset() const {
+ return TraceBackTableOffset;
+ }
+ const Optional<uint32_t> &getHandlerMask() const { return HandlerMask; }
+ const Optional<uint32_t> &getNumOfCtlAnchors() { return NumOfCtlAnchors; }
+ const Optional<SmallVector<uint32_t, 8>> &getControlledStorageInfoDisp() {
+ return ControlledStorageInfoDisp;
+ }
+ const Optional<StringRef> &getFunctionName() const { return FunctionName; }
+ const Optional<uint8_t> &getAllocaRegister() const { return AllocaRegister; }
+ const Optional<TBVectorExt> &getVectorExt() const { return VecExt; }
+ const Optional<uint8_t> &getExtensionTable() const { return ExtensionTable; }
+};
+
+bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes);
} // namespace object
} // namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/ObjectYAML/ArchiveYAML.h b/contrib/libs/llvm12/include/llvm/ObjectYAML/ArchiveYAML.h
index fc933ac89f..a1a0e53f05 100644
--- a/contrib/libs/llvm12/include/llvm/ObjectYAML/ArchiveYAML.h
+++ b/contrib/libs/llvm12/include/llvm/ObjectYAML/ArchiveYAML.h
@@ -1,88 +1,88 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- ArchiveYAML.h - Archive YAMLIO implementation ------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This file declares classes for handling the YAML representation of archives.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECTYAML_ARCHIVEYAML_H
-#define LLVM_OBJECTYAML_ARCHIVEYAML_H
-
-#include "llvm/Support/YAMLTraits.h"
-#include "llvm/ObjectYAML/YAML.h"
-#include "llvm/ADT/MapVector.h"
-
-namespace llvm {
-namespace ArchYAML {
-
-struct Archive {
- struct Child {
- struct Field {
- Field() = default;
- Field(StringRef Default, unsigned Length)
- : DefaultValue(Default), MaxLength(Length) {}
- StringRef Value;
- StringRef DefaultValue;
- unsigned MaxLength;
- };
-
- Child() {
- Fields["Name"] = {"", 16};
- Fields["LastModified"] = {"0", 12};
- Fields["UID"] = {"0", 6};
- Fields["GID"] = {"0", 6};
- Fields["AccessMode"] = {"0", 8};
- Fields["Size"] = {"0", 10};
- Fields["Terminator"] = {"`\n", 2};
- }
-
- MapVector<StringRef, Field> Fields;
-
- Optional<yaml::BinaryRef> Content;
- Optional<llvm::yaml::Hex8> PaddingByte;
- };
-
- StringRef Magic;
- Optional<std::vector<Child>> Members;
- Optional<yaml::BinaryRef> Content;
-};
-
-} // end namespace ArchYAML
-} // end namespace llvm
-
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ArchYAML::Archive::Child)
-
-namespace llvm {
-namespace yaml {
-
-template <> struct MappingTraits<ArchYAML::Archive> {
- static void mapping(IO &IO, ArchYAML::Archive &A);
- static std::string validate(IO &, ArchYAML::Archive &A);
-};
-
-template <> struct MappingTraits<ArchYAML::Archive::Child> {
- static void mapping(IO &IO, ArchYAML::Archive::Child &C);
- static std::string validate(IO &, ArchYAML::Archive::Child &C);
-};
-
-} // end namespace yaml
-} // end namespace llvm
-
-#endif // LLVM_OBJECTYAML_ARCHIVEYAML_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- ArchiveYAML.h - Archive YAMLIO implementation ------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file declares classes for handling the YAML representation of archives.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECTYAML_ARCHIVEYAML_H
+#define LLVM_OBJECTYAML_ARCHIVEYAML_H
+
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/ObjectYAML/YAML.h"
+#include "llvm/ADT/MapVector.h"
+
+namespace llvm {
+namespace ArchYAML {
+
+struct Archive {
+ struct Child {
+ struct Field {
+ Field() = default;
+ Field(StringRef Default, unsigned Length)
+ : DefaultValue(Default), MaxLength(Length) {}
+ StringRef Value;
+ StringRef DefaultValue;
+ unsigned MaxLength;
+ };
+
+ Child() {
+ Fields["Name"] = {"", 16};
+ Fields["LastModified"] = {"0", 12};
+ Fields["UID"] = {"0", 6};
+ Fields["GID"] = {"0", 6};
+ Fields["AccessMode"] = {"0", 8};
+ Fields["Size"] = {"0", 10};
+ Fields["Terminator"] = {"`\n", 2};
+ }
+
+ MapVector<StringRef, Field> Fields;
+
+ Optional<yaml::BinaryRef> Content;
+ Optional<llvm::yaml::Hex8> PaddingByte;
+ };
+
+ StringRef Magic;
+ Optional<std::vector<Child>> Members;
+ Optional<yaml::BinaryRef> Content;
+};
+
+} // end namespace ArchYAML
+} // end namespace llvm
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ArchYAML::Archive::Child)
+
+namespace llvm {
+namespace yaml {
+
+template <> struct MappingTraits<ArchYAML::Archive> {
+ static void mapping(IO &IO, ArchYAML::Archive &A);
+ static std::string validate(IO &, ArchYAML::Archive &A);
+};
+
+template <> struct MappingTraits<ArchYAML::Archive::Child> {
+ static void mapping(IO &IO, ArchYAML::Archive::Child &C);
+ static std::string validate(IO &, ArchYAML::Archive::Child &C);
+};
+
+} // end namespace yaml
+} // end namespace llvm
+
+#endif // LLVM_OBJECTYAML_ARCHIVEYAML_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/ObjectYAML/DWARFEmitter.h b/contrib/libs/llvm12/include/llvm/ObjectYAML/DWARFEmitter.h
index cdbbdf0269..b3641a4c22 100644
--- a/contrib/libs/llvm12/include/llvm/ObjectYAML/DWARFEmitter.h
+++ b/contrib/libs/llvm12/include/llvm/ObjectYAML/DWARFEmitter.h
@@ -40,23 +40,23 @@ Error emitDebugStr(raw_ostream &OS, const Data &DI);
Error emitDebugAranges(raw_ostream &OS, const Data &DI);
Error emitDebugRanges(raw_ostream &OS, const Data &DI);
-Error emitDebugPubnames(raw_ostream &OS, const Data &DI);
-Error emitDebugPubtypes(raw_ostream &OS, const Data &DI);
-Error emitDebugGNUPubnames(raw_ostream &OS, const Data &DI);
-Error emitDebugGNUPubtypes(raw_ostream &OS, const Data &DI);
+Error emitDebugPubnames(raw_ostream &OS, const Data &DI);
+Error emitDebugPubtypes(raw_ostream &OS, const Data &DI);
+Error emitDebugGNUPubnames(raw_ostream &OS, const Data &DI);
+Error emitDebugGNUPubtypes(raw_ostream &OS, const Data &DI);
Error emitDebugInfo(raw_ostream &OS, const Data &DI);
Error emitDebugLine(raw_ostream &OS, const Data &DI);
Error emitDebugAddr(raw_ostream &OS, const Data &DI);
-Error emitDebugStrOffsets(raw_ostream &OS, const Data &DI);
-Error emitDebugRnglists(raw_ostream &OS, const Data &DI);
-Error emitDebugLoclists(raw_ostream &OS, const Data &DI);
+Error emitDebugStrOffsets(raw_ostream &OS, const Data &DI);
+Error emitDebugRnglists(raw_ostream &OS, const Data &DI);
+Error emitDebugLoclists(raw_ostream &OS, const Data &DI);
-std::function<Error(raw_ostream &, const Data &)>
-getDWARFEmitterByName(StringRef SecName);
+std::function<Error(raw_ostream &, const Data &)>
+getDWARFEmitterByName(StringRef SecName);
Expected<StringMap<std::unique_ptr<MemoryBuffer>>>
-emitDebugSections(StringRef YAMLString,
- bool IsLittleEndian = sys::IsLittleEndianHost,
- bool Is64BitAddrSize = true);
+emitDebugSections(StringRef YAMLString,
+ bool IsLittleEndian = sys::IsLittleEndianHost,
+ bool Is64BitAddrSize = true);
} // end namespace DWARFYAML
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/ObjectYAML/DWARFYAML.h b/contrib/libs/llvm12/include/llvm/ObjectYAML/DWARFYAML.h
index a3558906e3..131aaeff88 100644
--- a/contrib/libs/llvm12/include/llvm/ObjectYAML/DWARFYAML.h
+++ b/contrib/libs/llvm12/include/llvm/ObjectYAML/DWARFYAML.h
@@ -25,10 +25,10 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/ObjectYAML/YAML.h"
+#include "llvm/ObjectYAML/YAML.h"
#include "llvm/Support/YAMLTraits.h"
#include <cstdint>
-#include <unordered_map>
+#include <unordered_map>
#include <vector>
namespace llvm {
@@ -47,23 +47,23 @@ struct Abbrev {
std::vector<AttributeAbbrev> Attributes;
};
-struct AbbrevTable {
- Optional<uint64_t> ID;
- std::vector<Abbrev> Table;
-};
-
+struct AbbrevTable {
+ Optional<uint64_t> ID;
+ std::vector<Abbrev> Table;
+};
+
struct ARangeDescriptor {
llvm::yaml::Hex64 Address;
- yaml::Hex64 Length;
+ yaml::Hex64 Length;
};
struct ARange {
dwarf::DwarfFormat Format;
- Optional<yaml::Hex64> Length;
+ Optional<yaml::Hex64> Length;
uint16_t Version;
- yaml::Hex64 CuOffset;
- Optional<yaml::Hex8> AddrSize;
- yaml::Hex8 SegSize;
+ yaml::Hex64 CuOffset;
+ Optional<yaml::Hex8> AddrSize;
+ yaml::Hex8 SegSize;
std::vector<ARangeDescriptor> Descriptors;
};
@@ -88,8 +88,8 @@ struct PubEntry {
};
struct PubSection {
- dwarf::DwarfFormat Format;
- yaml::Hex64 Length;
+ dwarf::DwarfFormat Format;
+ yaml::Hex64 Length;
uint16_t Version;
uint32_t UnitOffset;
uint32_t UnitSize;
@@ -115,12 +115,12 @@ struct DWARFContext {
struct Unit {
dwarf::DwarfFormat Format;
- Optional<yaml::Hex64> Length;
+ Optional<yaml::Hex64> Length;
uint16_t Version;
- Optional<uint8_t> AddrSize;
+ Optional<uint8_t> AddrSize;
llvm::dwarf::UnitType Type; // Added in DWARF 5
- Optional<uint64_t> AbbrevTableID;
- Optional<yaml::Hex64> AbbrOffset;
+ Optional<uint64_t> AbbrevTableID;
+ Optional<yaml::Hex64> AbbrOffset;
std::vector<Entry> Entries;
};
@@ -133,7 +133,7 @@ struct File {
struct LineTableOpcode {
dwarf::LineNumberOps Opcode;
- Optional<uint64_t> ExtLen;
+ Optional<uint64_t> ExtLen;
dwarf::LineNumberExtendedOps SubOpcode;
uint64_t Data;
int64_t SData;
@@ -144,16 +144,16 @@ struct LineTableOpcode {
struct LineTable {
dwarf::DwarfFormat Format;
- Optional<uint64_t> Length;
+ Optional<uint64_t> Length;
uint16_t Version;
- Optional<uint64_t> PrologueLength;
+ Optional<uint64_t> PrologueLength;
uint8_t MinInstLength;
uint8_t MaxOpsPerInst;
uint8_t DefaultIsStmt;
uint8_t LineBase;
uint8_t LineRange;
- Optional<uint8_t> OpcodeBase;
- Optional<std::vector<uint8_t>> StandardOpcodeLengths;
+ Optional<uint8_t> OpcodeBase;
+ Optional<std::vector<uint8_t>> StandardOpcodeLengths;
std::vector<StringRef> IncludeDirs;
std::vector<File> Files;
std::vector<LineTableOpcode> Opcodes;
@@ -173,56 +173,56 @@ struct AddrTableEntry {
std::vector<SegAddrPair> SegAddrPairs;
};
-struct StringOffsetsTable {
- dwarf::DwarfFormat Format;
- Optional<yaml::Hex64> Length;
- yaml::Hex16 Version;
- yaml::Hex16 Padding;
- std::vector<yaml::Hex64> Offsets;
-};
-
-struct DWARFOperation {
- dwarf::LocationAtom Operator;
- std::vector<yaml::Hex64> Values;
-};
-
-struct RnglistEntry {
- dwarf::RnglistEntries Operator;
- std::vector<yaml::Hex64> Values;
-};
-
-struct LoclistEntry {
- dwarf::LoclistEntries Operator;
- std::vector<yaml::Hex64> Values;
- Optional<yaml::Hex64> DescriptionsLength;
- std::vector<DWARFOperation> Descriptions;
-};
-
-template <typename EntryType> struct ListEntries {
- Optional<std::vector<EntryType>> Entries;
- Optional<yaml::BinaryRef> Content;
-};
-
-template <typename EntryType> struct ListTable {
- dwarf::DwarfFormat Format;
- Optional<yaml::Hex64> Length;
- yaml::Hex16 Version;
- Optional<yaml::Hex8> AddrSize;
- yaml::Hex8 SegSelectorSize;
- Optional<uint32_t> OffsetEntryCount;
- Optional<std::vector<yaml::Hex64>> Offsets;
- std::vector<ListEntries<EntryType>> Lists;
-};
-
+struct StringOffsetsTable {
+ dwarf::DwarfFormat Format;
+ Optional<yaml::Hex64> Length;
+ yaml::Hex16 Version;
+ yaml::Hex16 Padding;
+ std::vector<yaml::Hex64> Offsets;
+};
+
+struct DWARFOperation {
+ dwarf::LocationAtom Operator;
+ std::vector<yaml::Hex64> Values;
+};
+
+struct RnglistEntry {
+ dwarf::RnglistEntries Operator;
+ std::vector<yaml::Hex64> Values;
+};
+
+struct LoclistEntry {
+ dwarf::LoclistEntries Operator;
+ std::vector<yaml::Hex64> Values;
+ Optional<yaml::Hex64> DescriptionsLength;
+ std::vector<DWARFOperation> Descriptions;
+};
+
+template <typename EntryType> struct ListEntries {
+ Optional<std::vector<EntryType>> Entries;
+ Optional<yaml::BinaryRef> Content;
+};
+
+template <typename EntryType> struct ListTable {
+ dwarf::DwarfFormat Format;
+ Optional<yaml::Hex64> Length;
+ yaml::Hex16 Version;
+ Optional<yaml::Hex8> AddrSize;
+ yaml::Hex8 SegSelectorSize;
+ Optional<uint32_t> OffsetEntryCount;
+ Optional<std::vector<yaml::Hex64>> Offsets;
+ std::vector<ListEntries<EntryType>> Lists;
+};
+
struct Data {
bool IsLittleEndian;
bool Is64BitAddrSize;
- std::vector<AbbrevTable> DebugAbbrev;
- Optional<std::vector<StringRef>> DebugStrings;
- Optional<std::vector<StringOffsetsTable>> DebugStrOffsets;
- Optional<std::vector<ARange>> DebugAranges;
- Optional<std::vector<Ranges>> DebugRanges;
- Optional<std::vector<AddrTableEntry>> DebugAddr;
+ std::vector<AbbrevTable> DebugAbbrev;
+ Optional<std::vector<StringRef>> DebugStrings;
+ Optional<std::vector<StringOffsetsTable>> DebugStrOffsets;
+ Optional<std::vector<ARange>> DebugAranges;
+ Optional<std::vector<Ranges>> DebugRanges;
+ Optional<std::vector<AddrTableEntry>> DebugAddr;
Optional<PubSection> PubNames;
Optional<PubSection> PubTypes;
@@ -232,23 +232,23 @@ struct Data {
std::vector<Unit> CompileUnits;
std::vector<LineTable> DebugLines;
- Optional<std::vector<ListTable<RnglistEntry>>> DebugRnglists;
- Optional<std::vector<ListTable<LoclistEntry>>> DebugLoclists;
+ Optional<std::vector<ListTable<RnglistEntry>>> DebugRnglists;
+ Optional<std::vector<ListTable<LoclistEntry>>> DebugLoclists;
bool isEmpty() const;
- SetVector<StringRef> getNonEmptySectionNames() const;
-
- struct AbbrevTableInfo {
- uint64_t Index;
- uint64_t Offset;
- };
- Expected<AbbrevTableInfo> getAbbrevTableInfoByID(uint64_t ID) const;
- StringRef getAbbrevTableContentByIndex(uint64_t Index) const;
-
-private:
- mutable std::unordered_map<uint64_t, AbbrevTableInfo> AbbrevTableInfoMap;
- mutable std::unordered_map<uint64_t, std::string> AbbrevTableContents;
+ SetVector<StringRef> getNonEmptySectionNames() const;
+
+ struct AbbrevTableInfo {
+ uint64_t Index;
+ uint64_t Offset;
+ };
+ Expected<AbbrevTableInfo> getAbbrevTableInfoByID(uint64_t ID) const;
+ StringRef getAbbrevTableContentByIndex(uint64_t Index) const;
+
+private:
+ mutable std::unordered_map<uint64_t, AbbrevTableInfo> AbbrevTableInfoMap;
+ mutable std::unordered_map<uint64_t, std::string> AbbrevTableContents;
};
} // end namespace DWARFYAML
@@ -256,7 +256,7 @@ private:
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Abbrev)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AbbrevTable)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AbbrevTable)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARangeDescriptor)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARange)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::RangeEntry)
@@ -270,18 +270,18 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTable)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTableOpcode)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::SegAddrPair)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AddrTableEntry)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::StringOffsetsTable)
-LLVM_YAML_IS_SEQUENCE_VECTOR(
- llvm::DWARFYAML::ListTable<DWARFYAML::RnglistEntry>)
-LLVM_YAML_IS_SEQUENCE_VECTOR(
- llvm::DWARFYAML::ListEntries<DWARFYAML::RnglistEntry>)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::RnglistEntry)
-LLVM_YAML_IS_SEQUENCE_VECTOR(
- llvm::DWARFYAML::ListTable<DWARFYAML::LoclistEntry>)
-LLVM_YAML_IS_SEQUENCE_VECTOR(
- llvm::DWARFYAML::ListEntries<DWARFYAML::LoclistEntry>)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LoclistEntry)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::DWARFOperation)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::StringOffsetsTable)
+LLVM_YAML_IS_SEQUENCE_VECTOR(
+ llvm::DWARFYAML::ListTable<DWARFYAML::RnglistEntry>)
+LLVM_YAML_IS_SEQUENCE_VECTOR(
+ llvm::DWARFYAML::ListEntries<DWARFYAML::RnglistEntry>)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::RnglistEntry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(
+ llvm::DWARFYAML::ListTable<DWARFYAML::LoclistEntry>)
+LLVM_YAML_IS_SEQUENCE_VECTOR(
+ llvm::DWARFYAML::ListEntries<DWARFYAML::LoclistEntry>)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LoclistEntry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::DWARFOperation)
namespace llvm {
namespace yaml {
@@ -290,10 +290,10 @@ template <> struct MappingTraits<DWARFYAML::Data> {
static void mapping(IO &IO, DWARFYAML::Data &DWARF);
};
-template <> struct MappingTraits<DWARFYAML::AbbrevTable> {
- static void mapping(IO &IO, DWARFYAML::AbbrevTable &AbbrevTable);
-};
-
+template <> struct MappingTraits<DWARFYAML::AbbrevTable> {
+ static void mapping(IO &IO, DWARFYAML::AbbrevTable &AbbrevTable);
+};
+
template <> struct MappingTraits<DWARFYAML::Abbrev> {
static void mapping(IO &IO, DWARFYAML::Abbrev &Abbrev);
};
@@ -354,36 +354,36 @@ template <> struct MappingTraits<DWARFYAML::SegAddrPair> {
static void mapping(IO &IO, DWARFYAML::SegAddrPair &SegAddrPair);
};
-template <> struct MappingTraits<DWARFYAML::DWARFOperation> {
- static void mapping(IO &IO, DWARFYAML::DWARFOperation &DWARFOperation);
-};
-
-template <typename EntryType>
-struct MappingTraits<DWARFYAML::ListTable<EntryType>> {
- static void mapping(IO &IO, DWARFYAML::ListTable<EntryType> &ListTable);
-};
-
-template <typename EntryType>
-struct MappingTraits<DWARFYAML::ListEntries<EntryType>> {
- static void mapping(IO &IO, DWARFYAML::ListEntries<EntryType> &ListEntries);
- static std::string validate(IO &IO,
- DWARFYAML::ListEntries<EntryType> &ListEntries);
-};
-
-template <> struct MappingTraits<DWARFYAML::RnglistEntry> {
- static void mapping(IO &IO, DWARFYAML::RnglistEntry &RnglistEntry);
-};
-
-template <> struct MappingTraits<DWARFYAML::LoclistEntry> {
- static void mapping(IO &IO, DWARFYAML::LoclistEntry &LoclistEntry);
-};
-
+template <> struct MappingTraits<DWARFYAML::DWARFOperation> {
+ static void mapping(IO &IO, DWARFYAML::DWARFOperation &DWARFOperation);
+};
+
+template <typename EntryType>
+struct MappingTraits<DWARFYAML::ListTable<EntryType>> {
+ static void mapping(IO &IO, DWARFYAML::ListTable<EntryType> &ListTable);
+};
+
+template <typename EntryType>
+struct MappingTraits<DWARFYAML::ListEntries<EntryType>> {
+ static void mapping(IO &IO, DWARFYAML::ListEntries<EntryType> &ListEntries);
+ static std::string validate(IO &IO,
+ DWARFYAML::ListEntries<EntryType> &ListEntries);
+};
+
+template <> struct MappingTraits<DWARFYAML::RnglistEntry> {
+ static void mapping(IO &IO, DWARFYAML::RnglistEntry &RnglistEntry);
+};
+
+template <> struct MappingTraits<DWARFYAML::LoclistEntry> {
+ static void mapping(IO &IO, DWARFYAML::LoclistEntry &LoclistEntry);
+};
+
template <> struct MappingTraits<DWARFYAML::AddrTableEntry> {
static void mapping(IO &IO, DWARFYAML::AddrTableEntry &AddrTable);
};
-template <> struct MappingTraits<DWARFYAML::StringOffsetsTable> {
- static void mapping(IO &IO, DWARFYAML::StringOffsetsTable &StrOffsetsTable);
+template <> struct MappingTraits<DWARFYAML::StringOffsetsTable> {
+ static void mapping(IO &IO, DWARFYAML::StringOffsetsTable &StrOffsetsTable);
};
template <> struct ScalarEnumerationTraits<dwarf::DwarfFormat> {
@@ -461,34 +461,34 @@ template <> struct ScalarEnumerationTraits<dwarf::Constants> {
}
};
-#define HANDLE_DW_RLE(unused, name) \
- io.enumCase(value, "DW_RLE_" #name, dwarf::DW_RLE_##name);
-
-template <> struct ScalarEnumerationTraits<dwarf::RnglistEntries> {
- static void enumeration(IO &io, dwarf::RnglistEntries &value) {
-#include "llvm/BinaryFormat/Dwarf.def"
- }
-};
-
-#define HANDLE_DW_LLE(unused, name) \
- io.enumCase(value, "DW_LLE_" #name, dwarf::DW_LLE_##name);
-
-template <> struct ScalarEnumerationTraits<dwarf::LoclistEntries> {
- static void enumeration(IO &io, dwarf::LoclistEntries &value) {
-#include "llvm/BinaryFormat/Dwarf.def"
- }
-};
-
-#define HANDLE_DW_OP(id, name, version, vendor) \
- io.enumCase(value, "DW_OP_" #name, dwarf::DW_OP_##name);
-
-template <> struct ScalarEnumerationTraits<dwarf::LocationAtom> {
- static void enumeration(IO &io, dwarf::LocationAtom &value) {
-#include "llvm/BinaryFormat/Dwarf.def"
- io.enumFallback<yaml::Hex8>(value);
- }
-};
-
+#define HANDLE_DW_RLE(unused, name) \
+ io.enumCase(value, "DW_RLE_" #name, dwarf::DW_RLE_##name);
+
+template <> struct ScalarEnumerationTraits<dwarf::RnglistEntries> {
+ static void enumeration(IO &io, dwarf::RnglistEntries &value) {
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+};
+
+#define HANDLE_DW_LLE(unused, name) \
+ io.enumCase(value, "DW_LLE_" #name, dwarf::DW_LLE_##name);
+
+template <> struct ScalarEnumerationTraits<dwarf::LoclistEntries> {
+ static void enumeration(IO &io, dwarf::LoclistEntries &value) {
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+};
+
+#define HANDLE_DW_OP(id, name, version, vendor) \
+ io.enumCase(value, "DW_OP_" #name, dwarf::DW_OP_##name);
+
+template <> struct ScalarEnumerationTraits<dwarf::LocationAtom> {
+ static void enumeration(IO &io, dwarf::LocationAtom &value) {
+#include "llvm/BinaryFormat/Dwarf.def"
+ io.enumFallback<yaml::Hex8>(value);
+ }
+};
+
} // end namespace yaml
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/ObjectYAML/ELFYAML.h b/contrib/libs/llvm12/include/llvm/ObjectYAML/ELFYAML.h
index d0cb9b3f8e..9b5126ae35 100644
--- a/contrib/libs/llvm12/include/llvm/ObjectYAML/ELFYAML.h
+++ b/contrib/libs/llvm12/include/llvm/ObjectYAML/ELFYAML.h
@@ -23,8 +23,8 @@
#define LLVM_OBJECTYAML_ELFYAML_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/BinaryFormat/ELF.h"
-#include "llvm/Object/ELFTypes.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Object/ELFTypes.h"
#include "llvm/ObjectYAML/DWARFYAML.h"
#include "llvm/ObjectYAML/YAML.h"
#include "llvm/Support/YAMLTraits.h"
@@ -78,41 +78,41 @@ LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA)
LLVM_YAML_STRONG_TYPEDEF(StringRef, YAMLFlowString)
LLVM_YAML_STRONG_TYPEDEF(int64_t, YAMLIntUInt)
-template <class ELFT>
-unsigned getDefaultShEntSize(unsigned EMachine, ELF_SHT SecType,
- StringRef SecName) {
- if (EMachine == ELF::EM_MIPS && SecType == ELF::SHT_MIPS_ABIFLAGS)
- return sizeof(object::Elf_Mips_ABIFlags<ELFT>);
-
- switch (SecType) {
- case ELF::SHT_SYMTAB:
- case ELF::SHT_DYNSYM:
- return sizeof(typename ELFT::Sym);
- case ELF::SHT_GROUP:
- return sizeof(typename ELFT::Word);
- case ELF::SHT_REL:
- return sizeof(typename ELFT::Rel);
- case ELF::SHT_RELA:
- return sizeof(typename ELFT::Rela);
- case ELF::SHT_RELR:
- return sizeof(typename ELFT::Relr);
- case ELF::SHT_DYNAMIC:
- return sizeof(typename ELFT::Dyn);
- case ELF::SHT_HASH:
- return sizeof(typename ELFT::Word);
- case ELF::SHT_SYMTAB_SHNDX:
- return sizeof(typename ELFT::Word);
- case ELF::SHT_GNU_versym:
- return sizeof(typename ELFT::Half);
- case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
- return sizeof(object::Elf_CGProfile_Impl<ELFT>);
- default:
- if (SecName == ".debug_str")
- return 1;
- return 0;
- }
-}
-
+template <class ELFT>
+unsigned getDefaultShEntSize(unsigned EMachine, ELF_SHT SecType,
+ StringRef SecName) {
+ if (EMachine == ELF::EM_MIPS && SecType == ELF::SHT_MIPS_ABIFLAGS)
+ return sizeof(object::Elf_Mips_ABIFlags<ELFT>);
+
+ switch (SecType) {
+ case ELF::SHT_SYMTAB:
+ case ELF::SHT_DYNSYM:
+ return sizeof(typename ELFT::Sym);
+ case ELF::SHT_GROUP:
+ return sizeof(typename ELFT::Word);
+ case ELF::SHT_REL:
+ return sizeof(typename ELFT::Rel);
+ case ELF::SHT_RELA:
+ return sizeof(typename ELFT::Rela);
+ case ELF::SHT_RELR:
+ return sizeof(typename ELFT::Relr);
+ case ELF::SHT_DYNAMIC:
+ return sizeof(typename ELFT::Dyn);
+ case ELF::SHT_HASH:
+ return sizeof(typename ELFT::Word);
+ case ELF::SHT_SYMTAB_SHNDX:
+ return sizeof(typename ELFT::Word);
+ case ELF::SHT_GNU_versym:
+ return sizeof(typename ELFT::Half);
+ case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
+ return sizeof(object::Elf_CGProfile_Impl<ELFT>);
+ default:
+ if (SecName == ".debug_str")
+ return 1;
+ return 0;
+ }
+}
+
// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
// since 64-bit can hold 32-bit values too.
struct FileHeader {
@@ -121,7 +121,7 @@ struct FileHeader {
ELF_ELFOSABI OSABI;
llvm::yaml::Hex8 ABIVersion;
ELF_ET Type;
- Optional<ELF_EM> Machine;
+ Optional<ELF_EM> Machine;
ELF_EF Flags;
llvm::yaml::Hex64 Entry;
@@ -141,11 +141,11 @@ struct SectionHeader {
struct Symbol {
StringRef Name;
ELF_STT Type;
- Optional<StringRef> Section;
+ Optional<StringRef> Section;
Optional<ELF_SHN> Index;
ELF_STB Binding;
- Optional<llvm::yaml::Hex64> Value;
- Optional<llvm::yaml::Hex64> Size;
+ Optional<llvm::yaml::Hex64> Value;
+ Optional<llvm::yaml::Hex64> Size;
Optional<uint8_t> Other;
Optional<uint32_t> StName;
@@ -160,16 +160,16 @@ struct DynamicEntry {
llvm::yaml::Hex64 Val;
};
-struct BBAddrMapEntry {
- struct BBEntry {
- llvm::yaml::Hex32 AddressOffset;
- llvm::yaml::Hex32 Size;
- llvm::yaml::Hex32 Metadata;
- };
- llvm::yaml::Hex64 Address;
- Optional<std::vector<BBEntry>> BBEntries;
-};
-
+struct BBAddrMapEntry {
+ struct BBEntry {
+ llvm::yaml::Hex32 AddressOffset;
+ llvm::yaml::Hex32 Size;
+ llvm::yaml::Hex32 Metadata;
+ };
+ llvm::yaml::Hex64 Address;
+ Optional<std::vector<BBEntry>> BBEntries;
+};
+
struct StackSizeEntry {
llvm::yaml::Hex64 Address;
llvm::yaml::Hex64 Size;
@@ -197,29 +197,29 @@ struct Chunk {
StackSizes,
SymtabShndxSection,
Symver,
- ARMIndexTable,
+ ARMIndexTable,
MipsABIFlags,
Addrsig,
LinkerOptions,
DependentLibraries,
- CallGraphProfile,
- BBAddrMap,
-
- // Special chunks.
- SpecialChunksStart,
- Fill = SpecialChunksStart,
- SectionHeaderTable,
+ CallGraphProfile,
+ BBAddrMap,
+
+ // Special chunks.
+ SpecialChunksStart,
+ Fill = SpecialChunksStart,
+ SectionHeaderTable,
};
ChunkKind Kind;
StringRef Name;
Optional<llvm::yaml::Hex64> Offset;
- // Usually chunks are not created implicitly, but rather loaded from YAML.
- // This flag is used to signal whether this is the case or not.
- bool IsImplicit;
-
- Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {}
+ // Usually chunks are not created implicitly, but rather loaded from YAML.
+ // This flag is used to signal whether this is the case or not.
+ bool IsImplicit;
+
+ Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {}
virtual ~Chunk();
};
@@ -227,35 +227,35 @@ struct Section : public Chunk {
ELF_SHT Type;
Optional<ELF_SHF> Flags;
Optional<llvm::yaml::Hex64> Address;
- Optional<StringRef> Link;
+ Optional<StringRef> Link;
llvm::yaml::Hex64 AddressAlign;
Optional<llvm::yaml::Hex64> EntSize;
- Optional<yaml::BinaryRef> Content;
- Optional<llvm::yaml::Hex64> Size;
+ Optional<yaml::BinaryRef> Content;
+ Optional<llvm::yaml::Hex64> Size;
// Holds the original section index.
unsigned OriginalSecNdx;
- Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {}
+ Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {}
+
+ static bool classof(const Chunk *S) {
+ return S->Kind < ChunkKind::SpecialChunksStart;
+ }
- static bool classof(const Chunk *S) {
- return S->Kind < ChunkKind::SpecialChunksStart;
- }
+ // Some derived sections might have their own special entries. This method
+ // returns a vector of <entry name, is used> pairs. It is used for section
+ // validation.
+ virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
+ return {};
+ };
- // Some derived sections might have their own special entries. This method
- // returns a vector of <entry name, is used> pairs. It is used for section
- // validation.
- virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
- return {};
- };
-
// The following members are used to override section fields which is
// useful for creating invalid objects.
- // This can be used to override the sh_addralign field.
- Optional<llvm::yaml::Hex64> ShAddrAlign;
-
+ // This can be used to override the sh_addralign field.
+ Optional<llvm::yaml::Hex64> ShAddrAlign;
+
// This can be used to override the offset stored in the sh_name field.
// It does not affect the name stored in the string table.
Optional<llvm::yaml::Hex64> ShName;
@@ -270,12 +270,12 @@ struct Section : public Chunk {
// This can be used to override the sh_flags field.
Optional<llvm::yaml::Hex64> ShFlags;
-
- // This can be used to override the sh_type field. It is useful when we
- // want to use specific YAML keys for a section of a particular type to
- // describe the content, but still want to have a different final type
- // for the section.
- Optional<ELF_SHT> ShType;
+
+ // This can be used to override the sh_type field. It is useful when we
+ // want to use specific YAML keys for a section of a particular type to
+ // describe the content, but still want to have a different final type
+ // for the section.
+ Optional<ELF_SHT> ShType;
};
// Fill is a block of data which is placed outside of sections. It is
@@ -285,57 +285,57 @@ struct Fill : Chunk {
Optional<yaml::BinaryRef> Pattern;
llvm::yaml::Hex64 Size;
- Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {}
+ Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {}
static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
};
-struct SectionHeaderTable : Chunk {
- SectionHeaderTable(bool IsImplicit)
- : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {}
-
- static bool classof(const Chunk *S) {
- return S->Kind == ChunkKind::SectionHeaderTable;
- }
-
- Optional<std::vector<SectionHeader>> Sections;
- Optional<std::vector<SectionHeader>> Excluded;
- Optional<bool> NoHeaders;
-
- size_t getNumHeaders(size_t SectionsNum) const {
- if (IsImplicit)
- return SectionsNum;
- if (NoHeaders)
- return (*NoHeaders) ? 0 : SectionsNum;
- return (Sections ? Sections->size() : 0) + /*Null section*/ 1;
- }
-
- static constexpr StringRef TypeStr = "SectionHeaderTable";
-};
-
-struct BBAddrMapSection : Section {
- Optional<std::vector<BBAddrMapEntry>> Entries;
-
- BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
-
- std::vector<std::pair<StringRef, bool>> getEntries() const override {
- return {{"Entries", Entries.hasValue()}};
- };
-
- static bool classof(const Chunk *S) {
- return S->Kind == ChunkKind::BBAddrMap;
- }
-};
-
+struct SectionHeaderTable : Chunk {
+ SectionHeaderTable(bool IsImplicit)
+ : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {}
+
+ static bool classof(const Chunk *S) {
+ return S->Kind == ChunkKind::SectionHeaderTable;
+ }
+
+ Optional<std::vector<SectionHeader>> Sections;
+ Optional<std::vector<SectionHeader>> Excluded;
+ Optional<bool> NoHeaders;
+
+ size_t getNumHeaders(size_t SectionsNum) const {
+ if (IsImplicit)
+ return SectionsNum;
+ if (NoHeaders)
+ return (*NoHeaders) ? 0 : SectionsNum;
+ return (Sections ? Sections->size() : 0) + /*Null section*/ 1;
+ }
+
+ static constexpr StringRef TypeStr = "SectionHeaderTable";
+};
+
+struct BBAddrMapSection : Section {
+ Optional<std::vector<BBAddrMapEntry>> Entries;
+
+ BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
+
+ std::vector<std::pair<StringRef, bool>> getEntries() const override {
+ return {{"Entries", Entries.hasValue()}};
+ };
+
+ static bool classof(const Chunk *S) {
+ return S->Kind == ChunkKind::BBAddrMap;
+ }
+};
+
struct StackSizesSection : Section {
Optional<std::vector<StackSizeEntry>> Entries;
StackSizesSection() : Section(ChunkKind::StackSizes) {}
- std::vector<std::pair<StringRef, bool>> getEntries() const override {
- return {{"Entries", Entries.hasValue()}};
- };
-
+ std::vector<std::pair<StringRef, bool>> getEntries() const override {
+ return {{"Entries", Entries.hasValue()}};
+ };
+
static bool classof(const Chunk *S) {
return S->Kind == ChunkKind::StackSizes;
}
@@ -346,14 +346,14 @@ struct StackSizesSection : Section {
};
struct DynamicSection : Section {
- Optional<std::vector<DynamicEntry>> Entries;
+ Optional<std::vector<DynamicEntry>> Entries;
DynamicSection() : Section(ChunkKind::Dynamic) {}
- std::vector<std::pair<StringRef, bool>> getEntries() const override {
- return {{"Entries", Entries.hasValue()}};
- };
-
+ std::vector<std::pair<StringRef, bool>> getEntries() const override {
+ return {{"Entries", Entries.hasValue()}};
+ };
+
static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
};
@@ -381,10 +381,10 @@ struct NoteSection : Section {
NoteSection() : Section(ChunkKind::Note) {}
- std::vector<std::pair<StringRef, bool>> getEntries() const override {
- return {{"Notes", Notes.hasValue()}};
- };
-
+ std::vector<std::pair<StringRef, bool>> getEntries() const override {
+ return {{"Notes", Notes.hasValue()}};
+ };
+
static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
};
@@ -392,10 +392,10 @@ struct HashSection : Section {
Optional<std::vector<uint32_t>> Bucket;
Optional<std::vector<uint32_t>> Chain;
- std::vector<std::pair<StringRef, bool>> getEntries() const override {
- return {{"Bucket", Bucket.hasValue()}, {"Chain", Chain.hasValue()}};
- };
-
+ std::vector<std::pair<StringRef, bool>> getEntries() const override {
+ return {{"Bucket", Bucket.hasValue()}, {"Chain", Chain.hasValue()}};
+ };
+
// The following members are used to override section fields.
// This is useful for creating invalid objects.
Optional<llvm::yaml::Hex64> NBucket;
@@ -434,13 +434,13 @@ struct GnuHashSection : Section {
GnuHashSection() : Section(ChunkKind::GnuHash) {}
- std::vector<std::pair<StringRef, bool>> getEntries() const override {
- return {{"Header", Header.hasValue()},
- {"BloomFilter", BloomFilter.hasValue()},
- {"HashBuckets", HashBuckets.hasValue()},
- {"HashValues", HashValues.hasValue()}};
- };
-
+ std::vector<std::pair<StringRef, bool>> getEntries() const override {
+ return {{"Header", Header.hasValue()},
+ {"BloomFilter", BloomFilter.hasValue()},
+ {"HashBuckets", HashBuckets.hasValue()},
+ {"HashValues", HashValues.hasValue()}};
+ };
+
static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
};
@@ -459,14 +459,14 @@ struct VerneedEntry {
struct VerneedSection : Section {
Optional<std::vector<VerneedEntry>> VerneedV;
- Optional<llvm::yaml::Hex64> Info;
+ Optional<llvm::yaml::Hex64> Info;
VerneedSection() : Section(ChunkKind::Verneed) {}
- std::vector<std::pair<StringRef, bool>> getEntries() const override {
- return {{"Dependencies", VerneedV.hasValue()}};
- };
-
+ std::vector<std::pair<StringRef, bool>> getEntries() const override {
+ return {{"Dependencies", VerneedV.hasValue()}};
+ };
+
static bool classof(const Chunk *S) {
return S->Kind == ChunkKind::Verneed;
}
@@ -477,10 +477,10 @@ struct AddrsigSection : Section {
AddrsigSection() : Section(ChunkKind::Addrsig) {}
- std::vector<std::pair<StringRef, bool>> getEntries() const override {
- return {{"Symbols", Symbols.hasValue()}};
- };
-
+ std::vector<std::pair<StringRef, bool>> getEntries() const override {
+ return {{"Symbols", Symbols.hasValue()}};
+ };
+
static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
};
@@ -494,10 +494,10 @@ struct LinkerOptionsSection : Section {
LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
- std::vector<std::pair<StringRef, bool>> getEntries() const override {
- return {{"Options", Options.hasValue()}};
- };
-
+ std::vector<std::pair<StringRef, bool>> getEntries() const override {
+ return {{"Options", Options.hasValue()}};
+ };
+
static bool classof(const Chunk *S) {
return S->Kind == ChunkKind::LinkerOptions;
}
@@ -508,10 +508,10 @@ struct DependentLibrariesSection : Section {
DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
- std::vector<std::pair<StringRef, bool>> getEntries() const override {
- return {{"Libraries", Libs.hasValue()}};
- };
-
+ std::vector<std::pair<StringRef, bool>> getEntries() const override {
+ return {{"Libraries", Libs.hasValue()}};
+ };
+
static bool classof(const Chunk *S) {
return S->Kind == ChunkKind::DependentLibraries;
}
@@ -532,60 +532,60 @@ struct CallGraphProfileSection : Section {
CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
- std::vector<std::pair<StringRef, bool>> getEntries() const override {
- return {{"Entries", Entries.hasValue()}};
- };
-
+ std::vector<std::pair<StringRef, bool>> getEntries() const override {
+ return {{"Entries", Entries.hasValue()}};
+ };
+
static bool classof(const Chunk *S) {
return S->Kind == ChunkKind::CallGraphProfile;
}
};
struct SymverSection : Section {
- Optional<std::vector<uint16_t>> Entries;
+ Optional<std::vector<uint16_t>> Entries;
SymverSection() : Section(ChunkKind::Symver) {}
- std::vector<std::pair<StringRef, bool>> getEntries() const override {
- return {{"Entries", Entries.hasValue()}};
- };
-
+ std::vector<std::pair<StringRef, bool>> getEntries() const override {
+ return {{"Entries", Entries.hasValue()}};
+ };
+
static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
};
struct VerdefEntry {
- Optional<uint16_t> Version;
- Optional<uint16_t> Flags;
- Optional<uint16_t> VersionNdx;
- Optional<uint32_t> Hash;
+ Optional<uint16_t> Version;
+ Optional<uint16_t> Flags;
+ Optional<uint16_t> VersionNdx;
+ Optional<uint32_t> Hash;
std::vector<StringRef> VerNames;
};
struct VerdefSection : Section {
Optional<std::vector<VerdefEntry>> Entries;
- Optional<llvm::yaml::Hex64> Info;
+ Optional<llvm::yaml::Hex64> Info;
VerdefSection() : Section(ChunkKind::Verdef) {}
- std::vector<std::pair<StringRef, bool>> getEntries() const override {
- return {{"Entries", Entries.hasValue()}};
- };
-
+ std::vector<std::pair<StringRef, bool>> getEntries() const override {
+ return {{"Entries", Entries.hasValue()}};
+ };
+
static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
};
-struct GroupSection : Section {
+struct GroupSection : Section {
// Members of a group contain a flag and a list of section indices
// that are part of the group.
- Optional<std::vector<SectionOrType>> Members;
+ Optional<std::vector<SectionOrType>> Members;
Optional<StringRef> Signature; /* Info */
- GroupSection() : Section(ChunkKind::Group) {}
+ GroupSection() : Section(ChunkKind::Group) {}
+
+ std::vector<std::pair<StringRef, bool>> getEntries() const override {
+ return {{"Members", Members.hasValue()}};
+ };
- std::vector<std::pair<StringRef, bool>> getEntries() const override {
- return {{"Members", Members.hasValue()}};
- };
-
static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
};
@@ -597,15 +597,15 @@ struct Relocation {
};
struct RelocationSection : Section {
- Optional<std::vector<Relocation>> Relocations;
+ Optional<std::vector<Relocation>> Relocations;
StringRef RelocatableSec; /* Info */
RelocationSection() : Section(ChunkKind::Relocation) {}
- std::vector<std::pair<StringRef, bool>> getEntries() const override {
- return {{"Relocations", Relocations.hasValue()}};
- };
-
+ std::vector<std::pair<StringRef, bool>> getEntries() const override {
+ return {{"Relocations", Relocations.hasValue()}};
+ };
+
static bool classof(const Chunk *S) {
return S->Kind == ChunkKind::Relocation;
}
@@ -616,48 +616,48 @@ struct RelrSection : Section {
RelrSection() : Section(ChunkKind::Relr) {}
- std::vector<std::pair<StringRef, bool>> getEntries() const override {
- return {{"Entries", Entries.hasValue()}};
- };
-
+ std::vector<std::pair<StringRef, bool>> getEntries() const override {
+ return {{"Entries", Entries.hasValue()}};
+ };
+
static bool classof(const Chunk *S) {
return S->Kind == ChunkKind::Relr;
}
};
struct SymtabShndxSection : Section {
- Optional<std::vector<uint32_t>> Entries;
+ Optional<std::vector<uint32_t>> Entries;
SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
- std::vector<std::pair<StringRef, bool>> getEntries() const override {
- return {{"Entries", Entries.hasValue()}};
- };
-
+ std::vector<std::pair<StringRef, bool>> getEntries() const override {
+ return {{"Entries", Entries.hasValue()}};
+ };
+
static bool classof(const Chunk *S) {
return S->Kind == ChunkKind::SymtabShndxSection;
}
};
-struct ARMIndexTableEntry {
- llvm::yaml::Hex32 Offset;
- llvm::yaml::Hex32 Value;
-};
-
-struct ARMIndexTableSection : Section {
- Optional<std::vector<ARMIndexTableEntry>> Entries;
-
- ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
-
- std::vector<std::pair<StringRef, bool>> getEntries() const override {
- return {{"Entries", Entries.hasValue()}};
- };
-
- static bool classof(const Chunk *S) {
- return S->Kind == ChunkKind::ARMIndexTable;
- }
-};
-
+struct ARMIndexTableEntry {
+ llvm::yaml::Hex32 Offset;
+ llvm::yaml::Hex32 Value;
+};
+
+struct ARMIndexTableSection : Section {
+ Optional<std::vector<ARMIndexTableEntry>> Entries;
+
+ ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
+
+ std::vector<std::pair<StringRef, bool>> getEntries() const override {
+ return {{"Entries", Entries.hasValue()}};
+ };
+
+ static bool classof(const Chunk *S) {
+ return S->Kind == ChunkKind::ARMIndexTable;
+ }
+};
+
// Represents .MIPS.abiflags section
struct MipsABIFlags : Section {
llvm::yaml::Hex16 Version;
@@ -688,10 +688,10 @@ struct ProgramHeader {
Optional<llvm::yaml::Hex64> FileSize;
Optional<llvm::yaml::Hex64> MemSize;
Optional<llvm::yaml::Hex64> Offset;
- Optional<StringRef> FirstSec;
- Optional<StringRef> LastSec;
+ Optional<StringRef> FirstSec;
+ Optional<StringRef> LastSec;
- // This vector contains all chunks from [FirstSec, LastSec].
+ // This vector contains all chunks from [FirstSec, LastSec].
std::vector<Chunk *> Chunks;
};
@@ -718,26 +718,26 @@ struct Object {
Ret.push_back(S);
return Ret;
}
-
- const SectionHeaderTable &getSectionHeaderTable() const {
- for (const std::unique_ptr<Chunk> &C : Chunks)
- if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get()))
- return *S;
- llvm_unreachable("the section header table chunk must always be present");
- }
-
- unsigned getMachine() const;
-};
-
-bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
- const NoBitsSection &S);
-
+
+ const SectionHeaderTable &getSectionHeaderTable() const {
+ for (const std::unique_ptr<Chunk> &C : Chunks)
+ if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get()))
+ return *S;
+ llvm_unreachable("the section header table chunk must always be present");
+ }
+
+ unsigned getMachine() const;
+};
+
+bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
+ const NoBitsSection &S);
+
} // end namespace ELFYAML
} // end namespace llvm
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntry)
@@ -751,7 +751,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry)
namespace llvm {
namespace yaml {
@@ -881,27 +881,27 @@ template <> struct MappingTraits<ELFYAML::SectionHeader> {
template <> struct MappingTraits<ELFYAML::ProgramHeader> {
static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
- static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr);
+ static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr);
};
template <>
struct MappingTraits<ELFYAML::Symbol> {
static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
- static std::string validate(IO &IO, ELFYAML::Symbol &Symbol);
+ static std::string validate(IO &IO, ELFYAML::Symbol &Symbol);
};
template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
};
-template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> {
- static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &Rel);
-};
-
-template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
- static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &Rel);
-};
-
+template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> {
+ static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &Rel);
+};
+
+template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
+ static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &Rel);
+};
+
template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
};
@@ -938,13 +938,13 @@ template <> struct MappingTraits<ELFYAML::Relocation> {
static void mapping(IO &IO, ELFYAML::Relocation &Rel);
};
-template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> {
- static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E);
-};
-
+template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> {
+ static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E);
+};
+
template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> {
static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C);
- static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
+ static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
};
template <>
diff --git a/contrib/libs/llvm12/include/llvm/ObjectYAML/MachOYAML.h b/contrib/libs/llvm12/include/llvm/ObjectYAML/MachOYAML.h
index c635559122..40d8bc895a 100644
--- a/contrib/libs/llvm12/include/llvm/ObjectYAML/MachOYAML.h
+++ b/contrib/libs/llvm12/include/llvm/ObjectYAML/MachOYAML.h
@@ -227,7 +227,7 @@ template <> struct MappingTraits<MachOYAML::Relocation> {
template <> struct MappingTraits<MachOYAML::Section> {
static void mapping(IO &IO, MachOYAML::Section &Section);
- static std::string validate(IO &io, MachOYAML::Section &Section);
+ static std::string validate(IO &io, MachOYAML::Section &Section);
};
template <> struct MappingTraits<MachOYAML::NListEntry> {
diff --git a/contrib/libs/llvm12/include/llvm/ObjectYAML/MinidumpYAML.h b/contrib/libs/llvm12/include/llvm/ObjectYAML/MinidumpYAML.h
index 910bd84154..098f4c0798 100644
--- a/contrib/libs/llvm12/include/llvm/ObjectYAML/MinidumpYAML.h
+++ b/contrib/libs/llvm12/include/llvm/ObjectYAML/MinidumpYAML.h
@@ -243,7 +243,7 @@ template <> struct BlockScalarTraits<MinidumpYAML::BlockStringRef> {
template <> struct MappingTraits<std::unique_ptr<MinidumpYAML::Stream>> {
static void mapping(IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S);
- static std::string validate(IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S);
+ static std::string validate(IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S);
};
template <> struct MappingContextTraits<minidump::MemoryDescriptor, BinaryRef> {
diff --git a/contrib/libs/llvm12/include/llvm/ObjectYAML/ObjectYAML.h b/contrib/libs/llvm12/include/llvm/ObjectYAML/ObjectYAML.h
index 36da39c9d0..b5d1c41544 100644
--- a/contrib/libs/llvm12/include/llvm/ObjectYAML/ObjectYAML.h
+++ b/contrib/libs/llvm12/include/llvm/ObjectYAML/ObjectYAML.h
@@ -16,7 +16,7 @@
#ifndef LLVM_OBJECTYAML_OBJECTYAML_H
#define LLVM_OBJECTYAML_OBJECTYAML_H
-#include "llvm/ObjectYAML/ArchiveYAML.h"
+#include "llvm/ObjectYAML/ArchiveYAML.h"
#include "llvm/ObjectYAML/COFFYAML.h"
#include "llvm/ObjectYAML/ELFYAML.h"
#include "llvm/ObjectYAML/MachOYAML.h"
@@ -31,7 +31,7 @@ namespace yaml {
class IO;
struct YamlObjectFile {
- std::unique_ptr<ArchYAML::Archive> Arch;
+ std::unique_ptr<ArchYAML::Archive> Arch;
std::unique_ptr<ELFYAML::Object> Elf;
std::unique_ptr<COFFYAML::Object> Coff;
std::unique_ptr<MachOYAML::Object> MachO;
diff --git a/contrib/libs/llvm12/include/llvm/ObjectYAML/WasmYAML.h b/contrib/libs/llvm12/include/llvm/ObjectYAML/WasmYAML.h
index e85b193b06..9db6bde366 100644
--- a/contrib/libs/llvm12/include/llvm/ObjectYAML/WasmYAML.h
+++ b/contrib/libs/llvm12/include/llvm/ObjectYAML/WasmYAML.h
@@ -60,7 +60,7 @@ struct Limits {
struct Table {
TableType ElemType;
Limits TableLimits;
- uint32_t Index;
+ uint32_t Index;
};
struct Export {
@@ -228,8 +228,8 @@ struct NameSection : CustomSection {
}
std::vector<NameEntry> FunctionNames;
- std::vector<NameEntry> GlobalNames;
- std::vector<NameEntry> DataSegmentNames;
+ std::vector<NameEntry> GlobalNames;
+ std::vector<NameEntry> DataSegmentNames;
};
struct LinkingSection : CustomSection {
diff --git a/contrib/libs/llvm12/include/llvm/ObjectYAML/yaml2obj.h b/contrib/libs/llvm12/include/llvm/ObjectYAML/yaml2obj.h
index 92741fa436..174b6dabb0 100644
--- a/contrib/libs/llvm12/include/llvm/ObjectYAML/yaml2obj.h
+++ b/contrib/libs/llvm12/include/llvm/ObjectYAML/yaml2obj.h
@@ -47,17 +47,17 @@ namespace WasmYAML {
struct Object;
}
-namespace ArchYAML {
-struct Archive;
-}
-
+namespace ArchYAML {
+struct Archive;
+}
+
namespace yaml {
class Input;
struct YamlObjectFile;
using ErrorHandler = llvm::function_ref<void(const Twine &Msg)>;
-bool yaml2archive(ArchYAML::Archive &Doc, raw_ostream &Out, ErrorHandler EH);
+bool yaml2archive(ArchYAML::Archive &Doc, raw_ostream &Out, ErrorHandler EH);
bool yaml2coff(COFFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH);
bool yaml2elf(ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH,
uint64_t MaxSize);
diff --git a/contrib/libs/llvm12/include/llvm/Option/ArgList.h b/contrib/libs/llvm12/include/llvm/Option/ArgList.h
index efb1880dde..b6efeb641d 100644
--- a/contrib/libs/llvm12/include/llvm/Option/ArgList.h
+++ b/contrib/libs/llvm12/include/llvm/Option/ArgList.h
@@ -419,10 +419,10 @@ public:
return ArgStrings[Index];
}
- void replaceArgString(unsigned Index, const Twine &S) {
- ArgStrings[Index] = MakeArgString(S);
- }
-
+ void replaceArgString(unsigned Index, const Twine &S) {
+ ArgStrings[Index] = MakeArgString(S);
+ }
+
unsigned getNumInputArgStrings() const override {
return NumInputArgStrings;
}
diff --git a/contrib/libs/llvm12/include/llvm/Option/OptParser.td b/contrib/libs/llvm12/include/llvm/Option/OptParser.td
index ef4ac4e05e..9a179c511b 100644
--- a/contrib/libs/llvm12/include/llvm/Option/OptParser.td
+++ b/contrib/libs/llvm12/include/llvm/Option/OptParser.td
@@ -13,7 +13,7 @@
// Define the kinds of options.
-class OptionKind<string name, int precedence = 0, bit sentinel = false> {
+class OptionKind<string name, int precedence = 0, bit sentinel = false> {
string Name = name;
// The kind precedence, kinds with lower precedence are matched first.
int Precedence = precedence;
@@ -24,9 +24,9 @@ class OptionKind<string name, int precedence = 0, bit sentinel = false> {
// An option group.
def KIND_GROUP : OptionKind<"Group">;
// The input option kind.
-def KIND_INPUT : OptionKind<"Input", 1, true>;
+def KIND_INPUT : OptionKind<"Input", 1, true>;
// The unknown option kind.
-def KIND_UNKNOWN : OptionKind<"Unknown", 2, true>;
+def KIND_UNKNOWN : OptionKind<"Unknown", 2, true>;
// A flag with no values.
def KIND_FLAG : OptionKind<"Flag">;
// An option which prefixes its (single) value.
@@ -97,19 +97,19 @@ class Option<list<string> prefixes, string name, OptionKind kind> {
OptionGroup Group = ?;
Option Alias = ?;
list<string> AliasArgs = [];
- code MacroPrefix = "";
+ code MacroPrefix = "";
code KeyPath = ?;
code DefaultValue = ?;
- code ImpliedValue = ?;
- code ImpliedCheck = "false";
- code ShouldParse = "true";
- bit ShouldAlwaysEmit = false;
+ code ImpliedValue = ?;
+ code ImpliedCheck = "false";
+ code ShouldParse = "true";
+ bit ShouldAlwaysEmit = false;
code NormalizerRetTy = ?;
code NormalizedValuesScope = "";
code Normalizer = "";
code Denormalizer = "";
- code ValueMerger = "mergeForwardValue";
- code ValueExtractor = "extractForwardValue";
+ code ValueMerger = "mergeForwardValue";
+ code ValueExtractor = "extractForwardValue";
list<code> NormalizedValues = ?;
}
@@ -146,75 +146,75 @@ class ValuesCode<code valuecode> { code ValuesCode = valuecode; }
// Helpers for defining marshalling information.
-class KeyPathAndMacro<string key_path_prefix, string key_path_base,
- string macro_prefix = ""> {
- code KeyPath = !strconcat(key_path_prefix, key_path_base);
- code MacroPrefix = macro_prefix;
-}
-
-def EmptyKPM : KeyPathAndMacro<"", "">;
-
-class ImpliedByAnyOf<list<string> key_paths, code value = "true"> {
- code ImpliedCheck = !foldl("false", key_paths, accumulator, key_path,
- !strconcat(accumulator, " || ", key_path));
- code ImpliedValue = value;
-}
-
-class MarshallingInfo<KeyPathAndMacro kpm, code defaultvalue> {
- code KeyPath = kpm.KeyPath;
- code MacroPrefix = kpm.MacroPrefix;
+class KeyPathAndMacro<string key_path_prefix, string key_path_base,
+ string macro_prefix = ""> {
+ code KeyPath = !strconcat(key_path_prefix, key_path_base);
+ code MacroPrefix = macro_prefix;
+}
+
+def EmptyKPM : KeyPathAndMacro<"", "">;
+
+class ImpliedByAnyOf<list<string> key_paths, code value = "true"> {
+ code ImpliedCheck = !foldl("false", key_paths, accumulator, key_path,
+ !strconcat(accumulator, " || ", key_path));
+ code ImpliedValue = value;
+}
+
+class MarshallingInfo<KeyPathAndMacro kpm, code defaultvalue> {
+ code KeyPath = kpm.KeyPath;
+ code MacroPrefix = kpm.MacroPrefix;
code DefaultValue = defaultvalue;
}
-
-class MarshallingInfoString<KeyPathAndMacro kpm, code defaultvalue="std::string()">
- : MarshallingInfo<kpm, defaultvalue> {
- code Normalizer = "normalizeString";
- code Denormalizer = "denormalizeString";
+
+class MarshallingInfoString<KeyPathAndMacro kpm, code defaultvalue="std::string()">
+ : MarshallingInfo<kpm, defaultvalue> {
+ code Normalizer = "normalizeString";
+ code Denormalizer = "denormalizeString";
+}
+
+class MarshallingInfoStringInt<KeyPathAndMacro kpm, code defaultvalue="0", code type="unsigned">
+ : MarshallingInfo<kpm, defaultvalue> {
+ code Normalizer = "normalizeStringIntegral<"#type#">";
+ code Denormalizer = "denormalizeString";
+}
+
+class MarshallingInfoStringVector<KeyPathAndMacro kpm>
+ : MarshallingInfo<kpm, "std::vector<std::string>({})"> {
+ code Normalizer = "normalizeStringVector";
+ code Denormalizer = "denormalizeStringVector";
+}
+
+class MarshallingInfoFlag<KeyPathAndMacro kpm, code defaultvalue = "false">
+ : MarshallingInfo<kpm, defaultvalue> {
+ code Normalizer = "normalizeSimpleFlag";
+ code Denormalizer = "denormalizeSimpleFlag";
+}
+
+class MarshallingInfoNegativeFlag<KeyPathAndMacro kpm, code defaultvalue = "true">
+ : MarshallingInfo<kpm, defaultvalue> {
+ code Normalizer = "normalizeSimpleNegativeFlag";
+ code Denormalizer = "denormalizeSimpleFlag";
+}
+
+class MarshallingInfoBitfieldFlag<KeyPathAndMacro kpm, code value>
+ : MarshallingInfoFlag<kpm, "0u"> {
+ code Normalizer = "makeFlagToValueNormalizer("#value#")";
+ code ValueMerger = "mergeMaskValue";
+ code ValueExtractor = "(extractMaskValue<unsigned, decltype("#value#"), "#value#">)";
}
-class MarshallingInfoStringInt<KeyPathAndMacro kpm, code defaultvalue="0", code type="unsigned">
- : MarshallingInfo<kpm, defaultvalue> {
- code Normalizer = "normalizeStringIntegral<"#type#">";
- code Denormalizer = "denormalizeString";
+// Marshalling info for booleans. Applied to the flag setting keypath to false.
+class MarshallingInfoBooleanFlag<KeyPathAndMacro kpm, code defaultvalue, code value, code name,
+ code other_value, code other_name>
+ : MarshallingInfoFlag<kpm, defaultvalue> {
+ code Normalizer = "makeBooleanOptionNormalizer("#value#", "#other_value#", OPT_"#other_name#")";
+ code Denormalizer = "makeBooleanOptionDenormalizer("#value#")";
}
-class MarshallingInfoStringVector<KeyPathAndMacro kpm>
- : MarshallingInfo<kpm, "std::vector<std::string>({})"> {
- code Normalizer = "normalizeStringVector";
- code Denormalizer = "denormalizeStringVector";
-}
-
-class MarshallingInfoFlag<KeyPathAndMacro kpm, code defaultvalue = "false">
- : MarshallingInfo<kpm, defaultvalue> {
- code Normalizer = "normalizeSimpleFlag";
- code Denormalizer = "denormalizeSimpleFlag";
-}
-
-class MarshallingInfoNegativeFlag<KeyPathAndMacro kpm, code defaultvalue = "true">
- : MarshallingInfo<kpm, defaultvalue> {
- code Normalizer = "normalizeSimpleNegativeFlag";
- code Denormalizer = "denormalizeSimpleFlag";
-}
-
-class MarshallingInfoBitfieldFlag<KeyPathAndMacro kpm, code value>
- : MarshallingInfoFlag<kpm, "0u"> {
- code Normalizer = "makeFlagToValueNormalizer("#value#")";
- code ValueMerger = "mergeMaskValue";
- code ValueExtractor = "(extractMaskValue<unsigned, decltype("#value#"), "#value#">)";
-}
-
-// Marshalling info for booleans. Applied to the flag setting keypath to false.
-class MarshallingInfoBooleanFlag<KeyPathAndMacro kpm, code defaultvalue, code value, code name,
- code other_value, code other_name>
- : MarshallingInfoFlag<kpm, defaultvalue> {
- code Normalizer = "makeBooleanOptionNormalizer("#value#", "#other_value#", OPT_"#other_name#")";
- code Denormalizer = "makeBooleanOptionDenormalizer("#value#")";
-}
-
// Mixins for additional marshalling attributes.
-class ShouldParseIf<code condition> { code ShouldParse = condition; }
-class AlwaysEmit { bit ShouldAlwaysEmit = true; }
+class ShouldParseIf<code condition> { code ShouldParse = condition; }
+class AlwaysEmit { bit ShouldAlwaysEmit = true; }
class Normalizer<code normalizer> { code Normalizer = normalizer; }
class Denormalizer<code denormalizer> { code Denormalizer = denormalizer; }
class NormalizedValuesScope<code scope> { code NormalizedValuesScope = scope; }
@@ -223,8 +223,8 @@ class AutoNormalizeEnum {
code Normalizer = "normalizeSimpleEnum";
code Denormalizer = "denormalizeSimpleEnum";
}
-class ValueMerger<code merger> { code ValueMerger = merger; }
-class ValueExtractor<code extractor> { code ValueExtractor = extractor; }
+class ValueMerger<code merger> { code ValueMerger = merger; }
+class ValueExtractor<code extractor> { code ValueExtractor = extractor; }
// Predefined options.
diff --git a/contrib/libs/llvm12/include/llvm/Option/OptTable.h b/contrib/libs/llvm12/include/llvm/Option/OptTable.h
index 6bc5d4b66f..f7553d2b4b 100644
--- a/contrib/libs/llvm12/include/llvm/Option/OptTable.h
+++ b/contrib/libs/llvm12/include/llvm/Option/OptTable.h
@@ -20,7 +20,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Option/OptSpecifier.h"
-#include "llvm/Support/StringSaver.h"
+#include "llvm/Support/StringSaver.h"
#include <cassert>
#include <string>
#include <vector>
@@ -28,7 +28,7 @@
namespace llvm {
class raw_ostream;
-template <typename Fn> class function_ref;
+template <typename Fn> class function_ref;
namespace opt {
@@ -57,7 +57,7 @@ public:
unsigned ID;
unsigned char Kind;
unsigned char Param;
- unsigned int Flags;
+ unsigned int Flags;
unsigned short GroupID;
unsigned short AliasID;
const char *AliasArgs;
@@ -68,8 +68,8 @@ private:
/// The option information table.
std::vector<Info> OptionInfos;
bool IgnoreCase;
- bool GroupedShortOptions = false;
- const char *EnvVar = nullptr;
+ bool GroupedShortOptions = false;
+ const char *EnvVar = nullptr;
unsigned TheInputOptionID = 0;
unsigned TheUnknownOptionID = 0;
@@ -90,8 +90,8 @@ private:
return OptionInfos[id - 1];
}
- Arg *parseOneArgGrouped(InputArgList &Args, unsigned &Index) const;
-
+ Arg *parseOneArgGrouped(InputArgList &Args, unsigned &Index) const;
+
protected:
OptTable(ArrayRef<Info> OptionInfos, bool IgnoreCase = false);
@@ -133,12 +133,12 @@ public:
return getInfo(id).MetaVar;
}
- /// Specify the environment variable where initial options should be read.
- void setInitialOptionsFromEnvironment(const char *E) { EnvVar = E; }
-
- /// Support grouped short options. e.g. -ab represents -a -b.
- void setGroupedShortOptions(bool Value) { GroupedShortOptions = Value; }
-
+ /// Specify the environment variable where initial options should be read.
+ void setInitialOptionsFromEnvironment(const char *E) { EnvVar = E; }
+
+ /// Support grouped short options. e.g. -ab represents -a -b.
+ void setGroupedShortOptions(bool Value) { GroupedShortOptions = Value; }
+
/// Find possible value for given flags. This is used for shell
/// autocompletion.
///
@@ -159,7 +159,7 @@ public:
///
/// \return The vector of flags which start with Cur.
std::vector<std::string> findByPrefix(StringRef Cur,
- unsigned int DisableFlags) const;
+ unsigned int DisableFlags) const;
/// Find the OptTable option that most closely matches the given string.
///
@@ -232,18 +232,18 @@ public:
unsigned &MissingArgCount, unsigned FlagsToInclude = 0,
unsigned FlagsToExclude = 0) const;
- /// A convenience helper which handles optional initial options populated from
- /// an environment variable, expands response files recursively and parses
- /// options.
- ///
- /// \param ErrorFn - Called on a formatted error message for missing arguments
- /// or unknown options.
- /// \return An InputArgList; on error this will contain all the options which
- /// could be parsed.
- InputArgList parseArgs(int Argc, char *const *Argv, OptSpecifier Unknown,
- StringSaver &Saver,
- function_ref<void(StringRef)> ErrorFn) const;
-
+ /// A convenience helper which handles optional initial options populated from
+ /// an environment variable, expands response files recursively and parses
+ /// options.
+ ///
+ /// \param ErrorFn - Called on a formatted error message for missing arguments
+ /// or unknown options.
+ /// \return An InputArgList; on error this will contain all the options which
+ /// could be parsed.
+ InputArgList parseArgs(int Argc, char *const *Argv, OptSpecifier Unknown,
+ StringSaver &Saver,
+ function_ref<void(StringRef)> ErrorFn) const;
+
/// Render the help text for an option table.
///
/// \param OS - The stream to write the help text to.
diff --git a/contrib/libs/llvm12/include/llvm/Option/Option.h b/contrib/libs/llvm12/include/llvm/Option/Option.h
index 87b0505e8a..6bc4436754 100644
--- a/contrib/libs/llvm12/include/llvm/Option/Option.h
+++ b/contrib/libs/llvm12/include/llvm/Option/Option.h
@@ -220,16 +220,16 @@ public:
/// Index to the position where argument parsing should resume
/// (even if the argument is missing values).
///
- /// \p CurArg The argument to be matched. It may be shorter than the
- /// underlying storage to represent a Joined argument.
- /// \p GroupedShortOption If true, we are handling the fallback case of
- /// parsing a prefix of the current argument as a short option.
- Arg *accept(const ArgList &Args, StringRef CurArg, bool GroupedShortOption,
- unsigned &Index) const;
+ /// \p CurArg The argument to be matched. It may be shorter than the
+ /// underlying storage to represent a Joined argument.
+ /// \p GroupedShortOption If true, we are handling the fallback case of
+ /// parsing a prefix of the current argument as a short option.
+ Arg *accept(const ArgList &Args, StringRef CurArg, bool GroupedShortOption,
+ unsigned &Index) const;
private:
- Arg *acceptInternal(const ArgList &Args, StringRef CurArg,
- unsigned &Index) const;
+ Arg *acceptInternal(const ArgList &Args, StringRef CurArg,
+ unsigned &Index) const;
public:
void print(raw_ostream &O) const;
diff --git a/contrib/libs/llvm12/include/llvm/Pass.h b/contrib/libs/llvm12/include/llvm/Pass.h
index 07f8b96f2c..75addc8ee0 100644
--- a/contrib/libs/llvm12/include/llvm/Pass.h
+++ b/contrib/libs/llvm12/include/llvm/Pass.h
@@ -76,20 +76,20 @@ enum PassKind {
PT_PassManager
};
-/// This enumerates the LLVM full LTO or ThinLTO optimization phases.
-enum class ThinOrFullLTOPhase {
- /// No LTO/ThinLTO behavior needed.
- None,
- /// ThinLTO prelink (summary) phase.
- ThinLTOPreLink,
- /// ThinLTO postlink (backend compile) phase.
- ThinLTOPostLink,
- /// Full LTO prelink phase.
- FullLTOPreLink,
- /// Full LTO postlink (backend compile) phase.
- FullLTOPostLink
-};
-
+/// This enumerates the LLVM full LTO or ThinLTO optimization phases.
+enum class ThinOrFullLTOPhase {
+ /// No LTO/ThinLTO behavior needed.
+ None,
+ /// ThinLTO prelink (summary) phase.
+ ThinLTOPreLink,
+ /// ThinLTO postlink (backend compile) phase.
+ ThinLTOPostLink,
+ /// Full LTO prelink phase.
+ FullLTOPreLink,
+ /// Full LTO postlink (backend compile) phase.
+ FullLTOPostLink
+};
+
//===----------------------------------------------------------------------===//
/// Pass interface - Implemented by all 'passes'. Subclass this if you are an
/// interprocedural optimization or you do not fit into any of the more
@@ -330,12 +330,12 @@ protected:
/// then the value of this boolean will be true, otherwise false.
/// This is the storage for the -time-passes option.
extern bool TimePassesIsEnabled;
-/// If TimePassesPerRun is true, there would be one line of report for
-/// each pass invocation.
-/// If TimePassesPerRun is false, there would be only one line of
-/// report for each pass (even there are more than one pass objects).
-/// (For new pass manager only)
-extern bool TimePassesPerRun;
+/// If TimePassesPerRun is true, there would be one line of report for
+/// each pass invocation.
+/// If TimePassesPerRun is false, there would be only one line of
+/// report for each pass (even there are more than one pass objects).
+/// (For new pass manager only)
+extern bool TimePassesPerRun;
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/PassAnalysisSupport.h b/contrib/libs/llvm12/include/llvm/PassAnalysisSupport.h
index 63e8a90f98..6f0b6dfb26 100644
--- a/contrib/libs/llvm12/include/llvm/PassAnalysisSupport.h
+++ b/contrib/libs/llvm12/include/llvm/PassAnalysisSupport.h
@@ -24,12 +24,12 @@
#if !defined(LLVM_PASS_H) || defined(LLVM_PASSANALYSISSUPPORT_H)
#error "Do not include <PassAnalysisSupport.h>; include <Pass.h> instead"
-#endif
+#endif
#ifndef LLVM_PASSANALYSISSUPPORT_H
#define LLVM_PASSANALYSISSUPPORT_H
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include <cassert>
#include <tuple>
@@ -66,11 +66,11 @@ private:
SmallVector<AnalysisID, 0> Used;
bool PreservesAll = false;
- void pushUnique(VectorType &Set, AnalysisID ID) {
- if (!llvm::is_contained(Set, ID))
- Set.push_back(ID);
- }
-
+ void pushUnique(VectorType &Set, AnalysisID ID) {
+ if (!llvm::is_contained(Set, ID))
+ Set.push_back(ID);
+ }
+
public:
AnalysisUsage() = default;
@@ -93,17 +93,17 @@ public:
///@{
/// Add the specified ID to the set of analyses preserved by this pass.
AnalysisUsage &addPreservedID(const void *ID) {
- pushUnique(Preserved, ID);
+ pushUnique(Preserved, ID);
return *this;
}
AnalysisUsage &addPreservedID(char &ID) {
- pushUnique(Preserved, &ID);
+ pushUnique(Preserved, &ID);
return *this;
}
/// Add the specified Pass class to the set of analyses preserved by this pass.
template<class PassClass>
AnalysisUsage &addPreserved() {
- pushUnique(Preserved, &PassClass::ID);
+ pushUnique(Preserved, &PassClass::ID);
return *this;
}
///@}
@@ -112,17 +112,17 @@ public:
/// Add the specified ID to the set of analyses used by this pass if they are
/// available..
AnalysisUsage &addUsedIfAvailableID(const void *ID) {
- pushUnique(Used, ID);
+ pushUnique(Used, ID);
return *this;
}
AnalysisUsage &addUsedIfAvailableID(char &ID) {
- pushUnique(Used, &ID);
+ pushUnique(Used, &ID);
return *this;
}
/// Add the specified Pass class to the set of analyses used by this pass.
template<class PassClass>
AnalysisUsage &addUsedIfAvailable() {
- pushUnique(Used, &PassClass::ID);
+ pushUnique(Used, &PassClass::ID);
return *this;
}
///@}
@@ -196,7 +196,7 @@ public:
}
/// Return analysis result or null if it doesn't exist.
- Pass *getAnalysisIfAvailable(AnalysisID ID) const;
+ Pass *getAnalysisIfAvailable(AnalysisID ID) const;
private:
/// This keeps track of which passes implements the interfaces that are
@@ -220,7 +220,7 @@ AnalysisType *Pass::getAnalysisIfAvailable() const {
const void *PI = &AnalysisType::ID;
- Pass *ResultPass = Resolver->getAnalysisIfAvailable(PI);
+ Pass *ResultPass = Resolver->getAnalysisIfAvailable(PI);
if (!ResultPass) return nullptr;
// Because the AnalysisType may not be a subclass of pass (for
diff --git a/contrib/libs/llvm12/include/llvm/Passes/PassBuilder.h b/contrib/libs/llvm12/include/llvm/Passes/PassBuilder.h
index 5a72257513..a32a4f7cb9 100644
--- a/contrib/libs/llvm12/include/llvm/Passes/PassBuilder.h
+++ b/contrib/libs/llvm12/include/llvm/Passes/PassBuilder.h
@@ -43,15 +43,15 @@ struct PGOOptions {
enum CSPGOAction { NoCSAction, CSIRInstr, CSIRUse };
PGOOptions(std::string ProfileFile = "", std::string CSProfileGenFile = "",
std::string ProfileRemappingFile = "", PGOAction Action = NoAction,
- CSPGOAction CSAction = NoCSAction,
- bool DebugInfoForProfiling = false,
- bool PseudoProbeForProfiling = false)
+ CSPGOAction CSAction = NoCSAction,
+ bool DebugInfoForProfiling = false,
+ bool PseudoProbeForProfiling = false)
: ProfileFile(ProfileFile), CSProfileGenFile(CSProfileGenFile),
ProfileRemappingFile(ProfileRemappingFile), Action(Action),
- CSAction(CSAction), DebugInfoForProfiling(DebugInfoForProfiling ||
- (Action == SampleUse &&
- !PseudoProbeForProfiling)),
- PseudoProbeForProfiling(PseudoProbeForProfiling) {
+ CSAction(CSAction), DebugInfoForProfiling(DebugInfoForProfiling ||
+ (Action == SampleUse &&
+ !PseudoProbeForProfiling)),
+ PseudoProbeForProfiling(PseudoProbeForProfiling) {
// Note, we do allow ProfileFile.empty() for Action=IRUse LTO can
// callback with IRUse action without ProfileFile.
@@ -66,26 +66,26 @@ struct PGOOptions {
// a profile.
assert(this->CSAction != CSIRUse || this->Action == IRUse);
- // If neither Action nor CSAction, DebugInfoForProfiling or
- // PseudoProbeForProfiling needs to be true.
+ // If neither Action nor CSAction, DebugInfoForProfiling or
+ // PseudoProbeForProfiling needs to be true.
assert(this->Action != NoAction || this->CSAction != NoCSAction ||
- this->DebugInfoForProfiling || this->PseudoProbeForProfiling);
-
- // Pseudo probe emission does not work with -fdebug-info-for-profiling since
- // they both use the discriminator field of debug lines but for different
- // purposes.
- if (this->DebugInfoForProfiling && this->PseudoProbeForProfiling) {
- report_fatal_error(
- "Pseudo probes cannot be used with -debug-info-for-profiling", false);
- }
+ this->DebugInfoForProfiling || this->PseudoProbeForProfiling);
+
+ // Pseudo probe emission does not work with -fdebug-info-for-profiling since
+ // they both use the discriminator field of debug lines but for different
+ // purposes.
+ if (this->DebugInfoForProfiling && this->PseudoProbeForProfiling) {
+ report_fatal_error(
+ "Pseudo probes cannot be used with -debug-info-for-profiling", false);
+ }
}
std::string ProfileFile;
std::string CSProfileGenFile;
std::string ProfileRemappingFile;
PGOAction Action;
CSPGOAction CSAction;
- bool DebugInfoForProfiling;
- bool PseudoProbeForProfiling;
+ bool DebugInfoForProfiling;
+ bool PseudoProbeForProfiling;
};
/// Tunable parameters for passes in the default pipelines.
@@ -130,13 +130,13 @@ public:
/// Tuning option to enable/disable call graph profile. Its default value is
/// that of the flag: `-enable-npm-call-graph-profile`.
bool CallGraphProfile;
-
- /// Tuning option to enable/disable function merging. Its default value is
- /// false.
- bool MergeFunctions;
-
- /// Uniquefy function linkage name. Its default value is false.
- bool UniqueLinkageNames;
+
+ /// Tuning option to enable/disable function merging. Its default value is
+ /// false.
+ bool MergeFunctions;
+
+ /// Uniquefy function linkage name. Its default value is false.
+ bool UniqueLinkageNames;
};
/// This class provides access to building LLVM's passes.
@@ -146,7 +146,7 @@ public:
/// of the built-in passes, and those may reference these members during
/// construction.
class PassBuilder {
- bool DebugLogging;
+ bool DebugLogging;
TargetMachine *TM;
PipelineTuningOptions PTO;
Optional<PGOOptions> PGOOpt;
@@ -276,10 +276,10 @@ public:
unsigned getSizeLevel() const { return SizeLevel; }
};
- explicit PassBuilder(bool DebugLogging = false, TargetMachine *TM = nullptr,
+ explicit PassBuilder(bool DebugLogging = false, TargetMachine *TM = nullptr,
PipelineTuningOptions PTO = PipelineTuningOptions(),
Optional<PGOOptions> PGOOpt = None,
- PassInstrumentationCallbacks *PIC = nullptr);
+ PassInstrumentationCallbacks *PIC = nullptr);
/// Cross register the analysis managers through their proxies.
///
@@ -337,7 +337,7 @@ public:
/// \p Phase indicates the current ThinLTO phase.
FunctionPassManager
buildFunctionSimplificationPipeline(OptimizationLevel Level,
- ThinOrFullLTOPhase Phase);
+ ThinOrFullLTOPhase Phase);
/// Construct the core LLVM module canonicalization and simplification
/// pipeline.
@@ -354,13 +354,13 @@ public:
/// build them.
///
/// \p Phase indicates the current ThinLTO phase.
- ModulePassManager buildModuleSimplificationPipeline(OptimizationLevel Level,
- ThinOrFullLTOPhase Phase);
+ ModulePassManager buildModuleSimplificationPipeline(OptimizationLevel Level,
+ ThinOrFullLTOPhase Phase);
/// Construct the module pipeline that performs inlining as well as
/// the inlining-driven cleanups.
ModuleInlinerWrapperPass buildInlinerPipeline(OptimizationLevel Level,
- ThinOrFullLTOPhase Phase);
+ ThinOrFullLTOPhase Phase);
/// Construct the core LLVM module optimization pipeline.
///
@@ -404,7 +404,7 @@ public:
/// only intended for use when attempting to optimize code. If frontends
/// require some transformations for semantic reasons, they should explicitly
/// build them.
- ModulePassManager buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level);
+ ModulePassManager buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level);
/// Build an ThinLTO default optimization pipeline to a pass manager.
///
@@ -418,7 +418,7 @@ public:
/// require some transformations for semantic reasons, they should explicitly
/// build them.
ModulePassManager
- buildThinLTODefaultPipeline(OptimizationLevel Level,
+ buildThinLTODefaultPipeline(OptimizationLevel Level,
const ModuleSummaryIndex *ImportSummary);
/// Build a pre-link, LTO-targeting default optimization pipeline to a pass
@@ -433,7 +433,7 @@ public:
/// only intended for use when attempting to optimize code. If frontends
/// require some transformations for semantic reasons, they should explicitly
/// build them.
- ModulePassManager buildLTOPreLinkDefaultPipeline(OptimizationLevel Level);
+ ModulePassManager buildLTOPreLinkDefaultPipeline(OptimizationLevel Level);
/// Build an LTO default optimization pipeline to a pass manager.
///
@@ -449,17 +449,17 @@ public:
ModulePassManager buildLTODefaultPipeline(OptimizationLevel Level,
ModuleSummaryIndex *ExportSummary);
- /// Build an O0 pipeline with the minimal semantically required passes.
- ///
- /// This should only be used for non-LTO and LTO pre-link pipelines.
- ModulePassManager buildO0DefaultPipeline(OptimizationLevel Level,
- bool LTOPreLink = false);
-
+ /// Build an O0 pipeline with the minimal semantically required passes.
+ ///
+ /// This should only be used for non-LTO and LTO pre-link pipelines.
+ ModulePassManager buildO0DefaultPipeline(OptimizationLevel Level,
+ bool LTOPreLink = false);
+
/// Build the default `AAManager` with the default alias analysis pipeline
/// registered.
- ///
- /// This also adds target-specific alias analyses registered via
- /// TargetMachine::registerDefaultAliasAnalyses().
+ ///
+ /// This also adds target-specific alias analyses registered via
+ /// TargetMachine::registerDefaultAliasAnalyses().
AAManager buildDefaultAAPipeline();
/// Parse a textual pass pipeline description into a \c
@@ -487,22 +487,22 @@ public:
/// module(function(loop(lpass1,lpass2,lpass3)))
///
/// This shortcut is especially useful for debugging and testing small pass
- /// combinations.
- ///
- /// The sequence of passes aren't necessarily the exact same kind of pass.
- /// You can mix different levels implicitly if adaptor passes are defined to
- /// make them work. For example,
- ///
- /// mpass1,fpass1,fpass2,mpass2,lpass1
- ///
- /// This pipeline uses only one pass manager: the top-level module manager.
- /// fpass1,fpass2 and lpass1 are added into the the top-level module manager
- /// using only adaptor passes. No nested function/loop pass managers are
- /// added. The purpose is to allow easy pass testing when the user
- /// specifically want the pass to run under a adaptor directly. This is
- /// preferred when a pipeline is largely of one type, but one or just a few
- /// passes are of different types(See PassBuilder.cpp for examples).
- Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText);
+ /// combinations.
+ ///
+ /// The sequence of passes aren't necessarily the exact same kind of pass.
+ /// You can mix different levels implicitly if adaptor passes are defined to
+ /// make them work. For example,
+ ///
+ /// mpass1,fpass1,fpass2,mpass2,lpass1
+ ///
+ /// This pipeline uses only one pass manager: the top-level module manager.
+ /// fpass1,fpass2 and lpass1 are added into the the top-level module manager
+ /// using only adaptor passes. No nested function/loop pass managers are
+ /// added. The purpose is to allow easy pass testing when the user
+ /// specifically want the pass to run under a adaptor directly. This is
+ /// preferred when a pipeline is largely of one type, but one or just a few
+ /// passes are of different types(See PassBuilder.cpp for examples).
+ Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText);
/// {{@ Parse a textual pass pipeline description into a specific PassManager
///
@@ -511,9 +511,9 @@ public:
/// this is the valid pipeline text:
///
/// function(lpass)
- Error parsePassPipeline(CGSCCPassManager &CGPM, StringRef PipelineText);
- Error parsePassPipeline(FunctionPassManager &FPM, StringRef PipelineText);
- Error parsePassPipeline(LoopPassManager &LPM, StringRef PipelineText);
+ Error parsePassPipeline(CGSCCPassManager &CGPM, StringRef PipelineText);
+ Error parsePassPipeline(FunctionPassManager &FPM, StringRef PipelineText);
+ Error parsePassPipeline(LoopPassManager &LPM, StringRef PipelineText);
/// @}}
/// Parse a textual alias analysis pipeline into the provided AA manager.
@@ -612,23 +612,23 @@ public:
/// pipeline. This does not apply to 'backend' compiles (LTO and ThinLTO
/// link-time pipelines).
void registerPipelineStartEPCallback(
- const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
+ const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
PipelineStartEPCallbacks.push_back(C);
}
- /// Register a callback for a default optimizer pipeline extension point.
- ///
- /// This extension point allows adding optimization right after passes that do
- /// basic simplification of the input IR.
- void registerPipelineEarlySimplificationEPCallback(
- const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
- PipelineEarlySimplificationEPCallbacks.push_back(C);
- }
-
+ /// Register a callback for a default optimizer pipeline extension point.
+ ///
+ /// This extension point allows adding optimization right after passes that do
+ /// basic simplification of the input IR.
+ void registerPipelineEarlySimplificationEPCallback(
+ const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
+ PipelineEarlySimplificationEPCallbacks.push_back(C);
+ }
+
/// Register a callback for a default optimizer pipeline extension point
///
/// This extension point allows adding optimizations at the very end of the
- /// function optimization pipeline.
+ /// function optimization pipeline.
void registerOptimizerLastEPCallback(
const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
OptimizerLastEPCallbacks.push_back(C);
@@ -695,11 +695,11 @@ public:
/// PassManagers and populate the passed ModulePassManager.
void registerParseTopLevelPipelineCallback(
const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>,
- bool DebugLogging)> &C);
+ bool DebugLogging)> &C);
/// Add PGOInstrumenation passes for O0 only.
- void addPGOInstrPassesForO0(ModulePassManager &MPM, bool RunProfileGen,
- bool IsCS, std::string ProfileFile,
+ void addPGOInstrPassesForO0(ModulePassManager &MPM, bool RunProfileGen,
+ bool IsCS, std::string ProfileFile,
std::string ProfileRemappingFile);
/// Returns PIC. External libraries can use this to register pass
@@ -710,32 +710,32 @@ public:
private:
// O1 pass pipeline
- FunctionPassManager
- buildO1FunctionSimplificationPipeline(OptimizationLevel Level,
- ThinOrFullLTOPhase Phase);
+ FunctionPassManager
+ buildO1FunctionSimplificationPipeline(OptimizationLevel Level,
+ ThinOrFullLTOPhase Phase);
+
+ void addRequiredLTOPreLinkPasses(ModulePassManager &MPM);
- void addRequiredLTOPreLinkPasses(ModulePassManager &MPM);
-
static Optional<std::vector<PipelineElement>>
parsePipelineText(StringRef Text);
- Error parseModulePass(ModulePassManager &MPM, const PipelineElement &E);
- Error parseCGSCCPass(CGSCCPassManager &CGPM, const PipelineElement &E);
- Error parseFunctionPass(FunctionPassManager &FPM, const PipelineElement &E);
- Error parseLoopPass(LoopPassManager &LPM, const PipelineElement &E);
+ Error parseModulePass(ModulePassManager &MPM, const PipelineElement &E);
+ Error parseCGSCCPass(CGSCCPassManager &CGPM, const PipelineElement &E);
+ Error parseFunctionPass(FunctionPassManager &FPM, const PipelineElement &E);
+ Error parseLoopPass(LoopPassManager &LPM, const PipelineElement &E);
bool parseAAPassName(AAManager &AA, StringRef Name);
Error parseLoopPassPipeline(LoopPassManager &LPM,
- ArrayRef<PipelineElement> Pipeline);
+ ArrayRef<PipelineElement> Pipeline);
Error parseFunctionPassPipeline(FunctionPassManager &FPM,
- ArrayRef<PipelineElement> Pipeline);
+ ArrayRef<PipelineElement> Pipeline);
Error parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
- ArrayRef<PipelineElement> Pipeline);
+ ArrayRef<PipelineElement> Pipeline);
Error parseModulePassPipeline(ModulePassManager &MPM,
- ArrayRef<PipelineElement> Pipeline);
+ ArrayRef<PipelineElement> Pipeline);
- void addPGOInstrPasses(ModulePassManager &MPM, OptimizationLevel Level,
- bool RunProfileGen, bool IsCS, std::string ProfileFile,
+ void addPGOInstrPasses(ModulePassManager &MPM, OptimizationLevel Level,
+ bool RunProfileGen, bool IsCS, std::string ProfileFile,
std::string ProfileRemappingFile);
void invokePeepholeEPCallbacks(FunctionPassManager &, OptimizationLevel);
@@ -755,11 +755,11 @@ private:
SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
OptimizerLastEPCallbacks;
// Module callbacks
- SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
+ SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
PipelineStartEPCallbacks;
- SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
- PipelineEarlySimplificationEPCallbacks;
-
+ SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
+ PipelineEarlySimplificationEPCallbacks;
+
SmallVector<std::function<void(ModuleAnalysisManager &)>, 2>
ModuleAnalysisRegistrationCallbacks;
SmallVector<std::function<bool(StringRef, ModulePassManager &,
@@ -767,7 +767,7 @@ private:
2>
ModulePipelineParsingCallbacks;
SmallVector<std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>,
- bool DebugLogging)>,
+ bool DebugLogging)>,
2>
TopLevelPipelineParsingCallbacks;
// CGSCC callbacks
diff --git a/contrib/libs/llvm12/include/llvm/Passes/StandardInstrumentations.h b/contrib/libs/llvm12/include/llvm/Passes/StandardInstrumentations.h
index 93df62b562..d66a0ec466 100644
--- a/contrib/libs/llvm12/include/llvm/Passes/StandardInstrumentations.h
+++ b/contrib/libs/llvm12/include/llvm/Passes/StandardInstrumentations.h
@@ -23,13 +23,13 @@
#define LLVM_PASSES_STANDARDINSTRUMENTATIONS_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/OptBisect.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/OptBisect.h"
#include "llvm/IR/PassTimingInfo.h"
-#include "llvm/IR/ValueHandle.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Transforms/IPO/SampleProfileProbe.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/IPO/SampleProfileProbe.h"
#include <string>
#include <utility>
@@ -37,8 +37,8 @@
namespace llvm {
class Module;
-class Function;
-class PassInstrumentationCallbacks;
+class Function;
+class PassInstrumentationCallbacks;
/// Instrumentation to print IR before/after passes.
///
@@ -51,252 +51,252 @@ public:
void registerCallbacks(PassInstrumentationCallbacks &PIC);
private:
- void printBeforePass(StringRef PassID, Any IR);
+ void printBeforePass(StringRef PassID, Any IR);
void printAfterPass(StringRef PassID, Any IR);
void printAfterPassInvalidated(StringRef PassID);
- bool shouldPrintBeforePass(StringRef PassID);
- bool shouldPrintAfterPass(StringRef PassID);
-
+ bool shouldPrintBeforePass(StringRef PassID);
+ bool shouldPrintAfterPass(StringRef PassID);
+
using PrintModuleDesc = std::tuple<const Module *, std::string, StringRef>;
void pushModuleDesc(StringRef PassID, Any IR);
PrintModuleDesc popModuleDesc(StringRef PassID);
- PassInstrumentationCallbacks *PIC;
+ PassInstrumentationCallbacks *PIC;
/// Stack of Module description, enough to print the module after a given
/// pass.
SmallVector<PrintModuleDesc, 2> ModuleDescStack;
bool StoreModuleDesc = false;
};
-class OptNoneInstrumentation {
-public:
- OptNoneInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {}
- void registerCallbacks(PassInstrumentationCallbacks &PIC);
-
-private:
- bool DebugLogging;
- bool shouldRun(StringRef PassID, Any IR);
-};
-
-class OptBisectInstrumentation {
-public:
- OptBisectInstrumentation() {}
- void registerCallbacks(PassInstrumentationCallbacks &PIC);
-};
-
-// Debug logging for transformation and analysis passes.
-class PrintPassInstrumentation {
-public:
- PrintPassInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {}
- void registerCallbacks(PassInstrumentationCallbacks &PIC);
-
-private:
- bool DebugLogging;
-};
-
-class PreservedCFGCheckerInstrumentation {
-private:
- // CFG is a map BB -> {(Succ, Multiplicity)}, where BB is a non-leaf basic
- // block, {(Succ, Multiplicity)} set of all pairs of the block's successors
- // and the multiplicity of the edge (BB->Succ). As the mapped sets are
- // unordered the order of successors is not tracked by the CFG. In other words
- // this allows basic block successors to be swapped by a pass without
- // reporting a CFG change. CFG can be guarded by basic block tracking pointers
- // in the Graph (BBGuard). That is if any of the block is deleted or RAUWed
- // then the CFG is treated poisoned and no block pointer of the Graph is used.
- struct CFG {
- struct BBGuard final : public CallbackVH {
- BBGuard(const BasicBlock *BB) : CallbackVH(BB) {}
- void deleted() override { CallbackVH::deleted(); }
- void allUsesReplacedWith(Value *) override { CallbackVH::deleted(); }
- bool isPoisoned() const { return !getValPtr(); }
- };
-
- Optional<DenseMap<intptr_t, BBGuard>> BBGuards;
- DenseMap<const BasicBlock *, DenseMap<const BasicBlock *, unsigned>> Graph;
-
- CFG(const Function *F, bool TrackBBLifetime = false);
-
- bool operator==(const CFG &G) const {
- return !isPoisoned() && !G.isPoisoned() && Graph == G.Graph;
- }
-
- bool isPoisoned() const {
- if (BBGuards)
- for (auto &BB : *BBGuards) {
- if (BB.second.isPoisoned())
- return true;
- }
- return false;
- }
-
- static void printDiff(raw_ostream &out, const CFG &Before,
- const CFG &After);
- };
-
- SmallVector<std::pair<StringRef, Optional<CFG>>, 8> GraphStackBefore;
-
-public:
- static cl::opt<bool> VerifyPreservedCFG;
- void registerCallbacks(PassInstrumentationCallbacks &PIC);
-};
-
-// Base class for classes that report changes to the IR.
-// It presents an interface for such classes and provides calls
-// on various events as the new pass manager transforms the IR.
-// It also provides filtering of information based on hidden options
-// specifying which functions are interesting.
-// Calls are made for the following events/queries:
-// 1. The initial IR processed.
-// 2. To get the representation of the IR (of type \p T).
-// 3. When a pass does not change the IR.
-// 4. When a pass changes the IR (given both before and after representations
-// of type \p T).
-// 5. When an IR is invalidated.
-// 6. When a pass is run on an IR that is not interesting (based on options).
-// 7. When a pass is ignored (pass manager or adapter pass).
-// 8. To compare two IR representations (of type \p T).
-template <typename IRUnitT> class ChangeReporter {
-protected:
- ChangeReporter(bool RunInVerboseMode) : VerboseMode(RunInVerboseMode) {}
-
-public:
- virtual ~ChangeReporter();
-
- // Determine if this pass/IR is interesting and if so, save the IR
- // otherwise it is left on the stack without data.
- void saveIRBeforePass(Any IR, StringRef PassID);
- // Compare the IR from before the pass after the pass.
- void handleIRAfterPass(Any IR, StringRef PassID);
- // Handle the situation where a pass is invalidated.
- void handleInvalidatedPass(StringRef PassID);
-
-protected:
- // Register required callbacks.
- void registerRequiredCallbacks(PassInstrumentationCallbacks &PIC);
-
- // Return true when this is a defined function for which printing
- // of changes is desired.
- bool isInterestingFunction(const Function &F);
-
- // Return true when this is a pass for which printing of changes is desired.
- bool isInterestingPass(StringRef PassID);
-
- // Return true when this is a pass on IR for which printing
- // of changes is desired.
- bool isInteresting(Any IR, StringRef PassID);
-
- // Called on the first IR processed.
- virtual void handleInitialIR(Any IR) = 0;
- // Called before and after a pass to get the representation of the IR.
- virtual void generateIRRepresentation(Any IR, StringRef PassID,
- IRUnitT &Output) = 0;
- // Called when the pass is not iteresting.
- virtual void omitAfter(StringRef PassID, std::string &Name) = 0;
- // Called when an interesting IR has changed.
- virtual void handleAfter(StringRef PassID, std::string &Name,
- const IRUnitT &Before, const IRUnitT &After,
- Any) = 0;
- // Called when an interesting pass is invalidated.
- virtual void handleInvalidated(StringRef PassID) = 0;
- // Called when the IR or pass is not interesting.
- virtual void handleFiltered(StringRef PassID, std::string &Name) = 0;
- // Called when an ignored pass is encountered.
- virtual void handleIgnored(StringRef PassID, std::string &Name) = 0;
- // Called to compare the before and after representations of the IR.
- virtual bool same(const IRUnitT &Before, const IRUnitT &After) = 0;
-
- // Stack of IRs before passes.
- std::vector<IRUnitT> BeforeStack;
- // Is this the first IR seen?
- bool InitialIR = true;
-
- // Run in verbose mode, printing everything?
- const bool VerboseMode;
-};
-
-// An abstract template base class that handles printing banners and
-// reporting when things have not changed or are filtered out.
-template <typename IRUnitT>
-class TextChangeReporter : public ChangeReporter<IRUnitT> {
-protected:
- TextChangeReporter(bool Verbose);
-
- // Print a module dump of the first IR that is changed.
- void handleInitialIR(Any IR) override;
- // Report that the IR was omitted because it did not change.
- void omitAfter(StringRef PassID, std::string &Name) override;
- // Report that the pass was invalidated.
- void handleInvalidated(StringRef PassID) override;
- // Report that the IR was filtered out.
- void handleFiltered(StringRef PassID, std::string &Name) override;
- // Report that the pass was ignored.
- void handleIgnored(StringRef PassID, std::string &Name) override;
- // Make substitutions in \p S suitable for reporting changes
- // after the pass and then print it.
-
- raw_ostream &Out;
-};
-
-// A change printer based on the string representation of the IR as created
-// by unwrapAndPrint. The string representation is stored in a std::string
-// to preserve it as the IR changes in each pass. Note that the banner is
-// included in this representation but it is massaged before reporting.
-class IRChangedPrinter : public TextChangeReporter<std::string> {
-public:
- IRChangedPrinter(bool VerboseMode)
- : TextChangeReporter<std::string>(VerboseMode) {}
- ~IRChangedPrinter() override;
- void registerCallbacks(PassInstrumentationCallbacks &PIC);
-
-protected:
- // Called before and after a pass to get the representation of the IR.
- void generateIRRepresentation(Any IR, StringRef PassID,
- std::string &Output) override;
- // Called when an interesting IR has changed.
- void handleAfter(StringRef PassID, std::string &Name,
- const std::string &Before, const std::string &After,
- Any) override;
- // Called to compare the before and after representations of the IR.
- bool same(const std::string &Before, const std::string &After) override;
-};
-
-class VerifyInstrumentation {
- bool DebugLogging;
-
-public:
- VerifyInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {}
- void registerCallbacks(PassInstrumentationCallbacks &PIC);
-};
-
+class OptNoneInstrumentation {
+public:
+ OptNoneInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {}
+ void registerCallbacks(PassInstrumentationCallbacks &PIC);
+
+private:
+ bool DebugLogging;
+ bool shouldRun(StringRef PassID, Any IR);
+};
+
+class OptBisectInstrumentation {
+public:
+ OptBisectInstrumentation() {}
+ void registerCallbacks(PassInstrumentationCallbacks &PIC);
+};
+
+// Debug logging for transformation and analysis passes.
+class PrintPassInstrumentation {
+public:
+ PrintPassInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {}
+ void registerCallbacks(PassInstrumentationCallbacks &PIC);
+
+private:
+ bool DebugLogging;
+};
+
+class PreservedCFGCheckerInstrumentation {
+private:
+ // CFG is a map BB -> {(Succ, Multiplicity)}, where BB is a non-leaf basic
+ // block, {(Succ, Multiplicity)} set of all pairs of the block's successors
+ // and the multiplicity of the edge (BB->Succ). As the mapped sets are
+ // unordered the order of successors is not tracked by the CFG. In other words
+ // this allows basic block successors to be swapped by a pass without
+ // reporting a CFG change. CFG can be guarded by basic block tracking pointers
+ // in the Graph (BBGuard). That is if any of the block is deleted or RAUWed
+ // then the CFG is treated poisoned and no block pointer of the Graph is used.
+ struct CFG {
+ struct BBGuard final : public CallbackVH {
+ BBGuard(const BasicBlock *BB) : CallbackVH(BB) {}
+ void deleted() override { CallbackVH::deleted(); }
+ void allUsesReplacedWith(Value *) override { CallbackVH::deleted(); }
+ bool isPoisoned() const { return !getValPtr(); }
+ };
+
+ Optional<DenseMap<intptr_t, BBGuard>> BBGuards;
+ DenseMap<const BasicBlock *, DenseMap<const BasicBlock *, unsigned>> Graph;
+
+ CFG(const Function *F, bool TrackBBLifetime = false);
+
+ bool operator==(const CFG &G) const {
+ return !isPoisoned() && !G.isPoisoned() && Graph == G.Graph;
+ }
+
+ bool isPoisoned() const {
+ if (BBGuards)
+ for (auto &BB : *BBGuards) {
+ if (BB.second.isPoisoned())
+ return true;
+ }
+ return false;
+ }
+
+ static void printDiff(raw_ostream &out, const CFG &Before,
+ const CFG &After);
+ };
+
+ SmallVector<std::pair<StringRef, Optional<CFG>>, 8> GraphStackBefore;
+
+public:
+ static cl::opt<bool> VerifyPreservedCFG;
+ void registerCallbacks(PassInstrumentationCallbacks &PIC);
+};
+
+// Base class for classes that report changes to the IR.
+// It presents an interface for such classes and provides calls
+// on various events as the new pass manager transforms the IR.
+// It also provides filtering of information based on hidden options
+// specifying which functions are interesting.
+// Calls are made for the following events/queries:
+// 1. The initial IR processed.
+// 2. To get the representation of the IR (of type \p T).
+// 3. When a pass does not change the IR.
+// 4. When a pass changes the IR (given both before and after representations
+// of type \p T).
+// 5. When an IR is invalidated.
+// 6. When a pass is run on an IR that is not interesting (based on options).
+// 7. When a pass is ignored (pass manager or adapter pass).
+// 8. To compare two IR representations (of type \p T).
+template <typename IRUnitT> class ChangeReporter {
+protected:
+ ChangeReporter(bool RunInVerboseMode) : VerboseMode(RunInVerboseMode) {}
+
+public:
+ virtual ~ChangeReporter();
+
+ // Determine if this pass/IR is interesting and if so, save the IR
+ // otherwise it is left on the stack without data.
+ void saveIRBeforePass(Any IR, StringRef PassID);
+ // Compare the IR from before the pass after the pass.
+ void handleIRAfterPass(Any IR, StringRef PassID);
+ // Handle the situation where a pass is invalidated.
+ void handleInvalidatedPass(StringRef PassID);
+
+protected:
+ // Register required callbacks.
+ void registerRequiredCallbacks(PassInstrumentationCallbacks &PIC);
+
+ // Return true when this is a defined function for which printing
+ // of changes is desired.
+ bool isInterestingFunction(const Function &F);
+
+ // Return true when this is a pass for which printing of changes is desired.
+ bool isInterestingPass(StringRef PassID);
+
+ // Return true when this is a pass on IR for which printing
+ // of changes is desired.
+ bool isInteresting(Any IR, StringRef PassID);
+
+ // Called on the first IR processed.
+ virtual void handleInitialIR(Any IR) = 0;
+ // Called before and after a pass to get the representation of the IR.
+ virtual void generateIRRepresentation(Any IR, StringRef PassID,
+ IRUnitT &Output) = 0;
+ // Called when the pass is not iteresting.
+ virtual void omitAfter(StringRef PassID, std::string &Name) = 0;
+ // Called when an interesting IR has changed.
+ virtual void handleAfter(StringRef PassID, std::string &Name,
+ const IRUnitT &Before, const IRUnitT &After,
+ Any) = 0;
+ // Called when an interesting pass is invalidated.
+ virtual void handleInvalidated(StringRef PassID) = 0;
+ // Called when the IR or pass is not interesting.
+ virtual void handleFiltered(StringRef PassID, std::string &Name) = 0;
+ // Called when an ignored pass is encountered.
+ virtual void handleIgnored(StringRef PassID, std::string &Name) = 0;
+ // Called to compare the before and after representations of the IR.
+ virtual bool same(const IRUnitT &Before, const IRUnitT &After) = 0;
+
+ // Stack of IRs before passes.
+ std::vector<IRUnitT> BeforeStack;
+ // Is this the first IR seen?
+ bool InitialIR = true;
+
+ // Run in verbose mode, printing everything?
+ const bool VerboseMode;
+};
+
+// An abstract template base class that handles printing banners and
+// reporting when things have not changed or are filtered out.
+template <typename IRUnitT>
+class TextChangeReporter : public ChangeReporter<IRUnitT> {
+protected:
+ TextChangeReporter(bool Verbose);
+
+ // Print a module dump of the first IR that is changed.
+ void handleInitialIR(Any IR) override;
+ // Report that the IR was omitted because it did not change.
+ void omitAfter(StringRef PassID, std::string &Name) override;
+ // Report that the pass was invalidated.
+ void handleInvalidated(StringRef PassID) override;
+ // Report that the IR was filtered out.
+ void handleFiltered(StringRef PassID, std::string &Name) override;
+ // Report that the pass was ignored.
+ void handleIgnored(StringRef PassID, std::string &Name) override;
+ // Make substitutions in \p S suitable for reporting changes
+ // after the pass and then print it.
+
+ raw_ostream &Out;
+};
+
+// A change printer based on the string representation of the IR as created
+// by unwrapAndPrint. The string representation is stored in a std::string
+// to preserve it as the IR changes in each pass. Note that the banner is
+// included in this representation but it is massaged before reporting.
+class IRChangedPrinter : public TextChangeReporter<std::string> {
+public:
+ IRChangedPrinter(bool VerboseMode)
+ : TextChangeReporter<std::string>(VerboseMode) {}
+ ~IRChangedPrinter() override;
+ void registerCallbacks(PassInstrumentationCallbacks &PIC);
+
+protected:
+ // Called before and after a pass to get the representation of the IR.
+ void generateIRRepresentation(Any IR, StringRef PassID,
+ std::string &Output) override;
+ // Called when an interesting IR has changed.
+ void handleAfter(StringRef PassID, std::string &Name,
+ const std::string &Before, const std::string &After,
+ Any) override;
+ // Called to compare the before and after representations of the IR.
+ bool same(const std::string &Before, const std::string &After) override;
+};
+
+class VerifyInstrumentation {
+ bool DebugLogging;
+
+public:
+ VerifyInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {}
+ void registerCallbacks(PassInstrumentationCallbacks &PIC);
+};
+
/// This class provides an interface to register all the standard pass
/// instrumentations and manages their state (if any).
class StandardInstrumentations {
PrintIRInstrumentation PrintIR;
- PrintPassInstrumentation PrintPass;
+ PrintPassInstrumentation PrintPass;
TimePassesHandler TimePasses;
- OptNoneInstrumentation OptNone;
- OptBisectInstrumentation OptBisect;
- PreservedCFGCheckerInstrumentation PreservedCFGChecker;
- IRChangedPrinter PrintChangedIR;
- PseudoProbeVerifier PseudoProbeVerification;
- VerifyInstrumentation Verify;
-
- bool VerifyEach;
-
+ OptNoneInstrumentation OptNone;
+ OptBisectInstrumentation OptBisect;
+ PreservedCFGCheckerInstrumentation PreservedCFGChecker;
+ IRChangedPrinter PrintChangedIR;
+ PseudoProbeVerifier PseudoProbeVerification;
+ VerifyInstrumentation Verify;
+
+ bool VerifyEach;
+
public:
- StandardInstrumentations(bool DebugLogging, bool VerifyEach = false);
+ StandardInstrumentations(bool DebugLogging, bool VerifyEach = false);
void registerCallbacks(PassInstrumentationCallbacks &PIC);
TimePassesHandler &getTimePasses() { return TimePasses; }
};
-
-extern template class ChangeReporter<std::string>;
-extern template class TextChangeReporter<std::string>;
-
+
+extern template class ChangeReporter<std::string>;
+extern template class TextChangeReporter<std::string>;
+
} // namespace llvm
#endif
diff --git a/contrib/libs/llvm12/include/llvm/ProfileData/Coverage/CoverageMapping.h b/contrib/libs/llvm12/include/llvm/ProfileData/Coverage/CoverageMapping.h
index 4cd3afe58f..99bc8cd9c7 100644
--- a/contrib/libs/llvm12/include/llvm/ProfileData/Coverage/CoverageMapping.h
+++ b/contrib/libs/llvm12/include/llvm/ProfileData/Coverage/CoverageMapping.h
@@ -62,8 +62,8 @@ enum class coveragemap_error {
unsupported_version,
truncated,
malformed,
- decompression_failed,
- invalid_or_missing_arch_specifier
+ decompression_failed,
+ invalid_or_missing_arch_specifier
};
const std::error_category &coveragemap_category();
@@ -97,8 +97,8 @@ private:
/// A Counter is an abstract value that describes how to compute the
/// execution count for a region of code using the collected profile count data.
struct Counter {
- /// The CounterExpression kind (Add or Subtract) is encoded in bit 0 next to
- /// the CounterKind. This means CounterKind has to leave bit 0 free.
+ /// The CounterExpression kind (Add or Subtract) is encoded in bit 0 next to
+ /// the CounterKind. This means CounterKind has to leave bit 0 free.
enum CounterKind { Zero, CounterValueReference, Expression };
static const unsigned EncodingTagBits = 2;
static const unsigned EncodingTagMask = 0x3;
@@ -228,20 +228,20 @@ struct CounterMappingRegion {
/// A GapRegion is like a CodeRegion, but its count is only set as the
/// line execution count when its the only region in the line.
- GapRegion,
-
- /// A BranchRegion represents leaf-level boolean expressions and is
- /// associated with two counters, each representing the number of times the
- /// expression evaluates to true or false.
- BranchRegion
+ GapRegion,
+
+ /// A BranchRegion represents leaf-level boolean expressions and is
+ /// associated with two counters, each representing the number of times the
+ /// expression evaluates to true or false.
+ BranchRegion
};
- /// Primary Counter that is also used for Branch Regions (TrueCount).
+ /// Primary Counter that is also used for Branch Regions (TrueCount).
Counter Count;
-
- /// Secondary Counter used for Branch Regions (FalseCount).
- Counter FalseCount;
-
+
+ /// Secondary Counter used for Branch Regions (FalseCount).
+ Counter FalseCount;
+
unsigned FileID, ExpandedFileID;
unsigned LineStart, ColumnStart, LineEnd, ColumnEnd;
RegionKind Kind;
@@ -253,15 +253,15 @@ struct CounterMappingRegion {
LineStart(LineStart), ColumnStart(ColumnStart), LineEnd(LineEnd),
ColumnEnd(ColumnEnd), Kind(Kind) {}
- CounterMappingRegion(Counter Count, Counter FalseCount, unsigned FileID,
- unsigned ExpandedFileID, unsigned LineStart,
- unsigned ColumnStart, unsigned LineEnd,
- unsigned ColumnEnd, RegionKind Kind)
- : Count(Count), FalseCount(FalseCount), FileID(FileID),
- ExpandedFileID(ExpandedFileID), LineStart(LineStart),
- ColumnStart(ColumnStart), LineEnd(LineEnd), ColumnEnd(ColumnEnd),
- Kind(Kind) {}
-
+ CounterMappingRegion(Counter Count, Counter FalseCount, unsigned FileID,
+ unsigned ExpandedFileID, unsigned LineStart,
+ unsigned ColumnStart, unsigned LineEnd,
+ unsigned ColumnEnd, RegionKind Kind)
+ : Count(Count), FalseCount(FalseCount), FileID(FileID),
+ ExpandedFileID(ExpandedFileID), LineStart(LineStart),
+ ColumnStart(ColumnStart), LineEnd(LineEnd), ColumnEnd(ColumnEnd),
+ Kind(Kind) {}
+
static CounterMappingRegion
makeRegion(Counter Count, unsigned FileID, unsigned LineStart,
unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
@@ -291,14 +291,14 @@ struct CounterMappingRegion {
LineEnd, (1U << 31) | ColumnEnd, GapRegion);
}
- static CounterMappingRegion
- makeBranchRegion(Counter Count, Counter FalseCount, unsigned FileID,
- unsigned LineStart, unsigned ColumnStart, unsigned LineEnd,
- unsigned ColumnEnd) {
- return CounterMappingRegion(Count, FalseCount, FileID, 0, LineStart,
- ColumnStart, LineEnd, ColumnEnd, BranchRegion);
- }
-
+ static CounterMappingRegion
+ makeBranchRegion(Counter Count, Counter FalseCount, unsigned FileID,
+ unsigned LineStart, unsigned ColumnStart, unsigned LineEnd,
+ unsigned ColumnEnd) {
+ return CounterMappingRegion(Count, FalseCount, FileID, 0, LineStart,
+ ColumnStart, LineEnd, ColumnEnd, BranchRegion);
+ }
+
inline LineColPair startLoc() const {
return LineColPair(LineStart, ColumnStart);
}
@@ -309,17 +309,17 @@ struct CounterMappingRegion {
/// Associates a source range with an execution count.
struct CountedRegion : public CounterMappingRegion {
uint64_t ExecutionCount;
- uint64_t FalseExecutionCount;
- bool Folded;
+ uint64_t FalseExecutionCount;
+ bool Folded;
CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount)
- : CounterMappingRegion(R), ExecutionCount(ExecutionCount),
- FalseExecutionCount(0), Folded(false) {}
-
- CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount,
- uint64_t FalseExecutionCount)
- : CounterMappingRegion(R), ExecutionCount(ExecutionCount),
- FalseExecutionCount(FalseExecutionCount), Folded(false) {}
+ : CounterMappingRegion(R), ExecutionCount(ExecutionCount),
+ FalseExecutionCount(0), Folded(false) {}
+
+ CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount,
+ uint64_t FalseExecutionCount)
+ : CounterMappingRegion(R), ExecutionCount(ExecutionCount),
+ FalseExecutionCount(FalseExecutionCount), Folded(false) {}
};
/// A Counter mapping context is used to connect the counters, expressions
@@ -356,8 +356,8 @@ struct FunctionRecord {
std::vector<std::string> Filenames;
/// Regions in the function along with their counts.
std::vector<CountedRegion> CountedRegions;
- /// Branch Regions in the function along with their counts.
- std::vector<CountedRegion> CountedBranchRegions;
+ /// Branch Regions in the function along with their counts.
+ std::vector<CountedRegion> CountedBranchRegions;
/// The number of times this function was executed.
uint64_t ExecutionCount = 0;
@@ -367,19 +367,19 @@ struct FunctionRecord {
FunctionRecord(FunctionRecord &&FR) = default;
FunctionRecord &operator=(FunctionRecord &&) = default;
- void pushRegion(CounterMappingRegion Region, uint64_t Count,
- uint64_t FalseCount) {
- if (Region.Kind == CounterMappingRegion::BranchRegion) {
- CountedBranchRegions.emplace_back(Region, Count, FalseCount);
- // If both counters are hard-coded to zero, then this region represents a
- // constant-folded branch.
- if (Region.Count.isZero() && Region.FalseCount.isZero())
- CountedBranchRegions.back().Folded = true;
- return;
- }
+ void pushRegion(CounterMappingRegion Region, uint64_t Count,
+ uint64_t FalseCount) {
+ if (Region.Kind == CounterMappingRegion::BranchRegion) {
+ CountedBranchRegions.emplace_back(Region, Count, FalseCount);
+ // If both counters are hard-coded to zero, then this region represents a
+ // constant-folded branch.
+ if (Region.Count.isZero() && Region.FalseCount.isZero())
+ CountedBranchRegions.back().Folded = true;
+ return;
+ }
if (CountedRegions.empty())
ExecutionCount = Count;
- CountedRegions.emplace_back(Region, Count, FalseCount);
+ CountedRegions.emplace_back(Region, Count, FalseCount);
}
};
@@ -458,8 +458,8 @@ struct CoverageSegment {
IsRegionEntry(IsRegionEntry), IsGapRegion(false) {}
CoverageSegment(unsigned Line, unsigned Col, uint64_t Count,
- bool IsRegionEntry, bool IsGapRegion = false,
- bool IsBranchRegion = false)
+ bool IsRegionEntry, bool IsGapRegion = false,
+ bool IsBranchRegion = false)
: Line(Line), Col(Col), Count(Count), HasCount(true),
IsRegionEntry(IsRegionEntry), IsGapRegion(IsGapRegion) {}
@@ -539,7 +539,7 @@ class CoverageData {
std::string Filename;
std::vector<CoverageSegment> Segments;
std::vector<ExpansionRecord> Expansions;
- std::vector<CountedRegion> BranchRegions;
+ std::vector<CountedRegion> BranchRegions;
public:
CoverageData() = default;
@@ -563,9 +563,9 @@ public:
/// Expansions that can be further processed.
ArrayRef<ExpansionRecord> getExpansions() const { return Expansions; }
-
- /// Branches that can be further processed.
- ArrayRef<CountedRegion> getBranches() const { return BranchRegions; }
+
+ /// Branches that can be further processed.
+ ArrayRef<CountedRegion> getBranches() const { return BranchRegions; }
};
/// The mapping of profile information to coverage data.
@@ -1001,9 +1001,9 @@ enum CovMapVersion {
Version3 = 2,
// Function records are named, uniqued, and moved to a dedicated section.
Version4 = 3,
- // Branch regions referring to two counters are added
- Version5 = 4,
- // The current version is Version5.
+ // Branch regions referring to two counters are added
+ Version5 = 4,
+ // The current version is Version5.
CurrentVersion = INSTR_PROF_COVMAP_VERSION
};
diff --git a/contrib/libs/llvm12/include/llvm/ProfileData/GCOV.h b/contrib/libs/llvm12/include/llvm/ProfileData/GCOV.h
index d984b3c696..a3c2569f13 100644
--- a/contrib/libs/llvm12/include/llvm/ProfileData/GCOV.h
+++ b/contrib/libs/llvm12/include/llvm/ProfileData/GCOV.h
@@ -22,7 +22,7 @@
#define LLVM_PROFILEDATA_GCOV_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
@@ -54,11 +54,11 @@ enum GCOVVersion { V304, V407, V408, V800, V900 };
/// A struct for passing gcov options between functions.
struct Options {
Options(bool A, bool B, bool C, bool F, bool P, bool U, bool I, bool L,
- bool M, bool N, bool R, bool T, bool X, std::string SourcePrefix)
+ bool M, bool N, bool R, bool T, bool X, std::string SourcePrefix)
: AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F),
PreservePaths(P), UncondBranch(U), Intermediate(I), LongFileNames(L),
- Demangle(M), NoOutput(N), RelativeOnly(R), UseStdout(T),
- HashFilenames(X), SourcePrefix(std::move(SourcePrefix)) {}
+ Demangle(M), NoOutput(N), RelativeOnly(R), UseStdout(T),
+ HashFilenames(X), SourcePrefix(std::move(SourcePrefix)) {}
bool AllBlocks;
bool BranchInfo;
@@ -68,12 +68,12 @@ struct Options {
bool UncondBranch;
bool Intermediate;
bool LongFileNames;
- bool Demangle;
+ bool Demangle;
bool NoOutput;
- bool RelativeOnly;
+ bool RelativeOnly;
bool UseStdout;
bool HashFilenames;
- std::string SourcePrefix;
+ std::string SourcePrefix;
};
} // end namespace GCOV
@@ -204,32 +204,32 @@ public:
std::vector<std::string> filenames;
StringMap<unsigned> filenameToIdx;
-public:
+public:
bool GCNOInitialized = false;
GCOV::GCOVVersion Version;
uint32_t Checksum = 0;
StringRef cwd;
- SmallVector<std::unique_ptr<GCOVFunction>, 16> functions;
+ SmallVector<std::unique_ptr<GCOVFunction>, 16> functions;
std::map<uint32_t, GCOVFunction *> IdentToFunction;
uint32_t RunCount = 0;
uint32_t ProgramCount = 0;
using iterator = pointee_iterator<
SmallVectorImpl<std::unique_ptr<GCOVFunction>>::const_iterator>;
- iterator begin() const { return iterator(functions.begin()); }
- iterator end() const { return iterator(functions.end()); }
+ iterator begin() const { return iterator(functions.begin()); }
+ iterator end() const { return iterator(functions.end()); }
};
struct GCOVArc {
- GCOVArc(GCOVBlock &src, GCOVBlock &dst, uint32_t flags)
- : src(src), dst(dst), flags(flags) {}
- bool onTree() const;
+ GCOVArc(GCOVBlock &src, GCOVBlock &dst, uint32_t flags)
+ : src(src), dst(dst), flags(flags) {}
+ bool onTree() const;
GCOVBlock &src;
GCOVBlock &dst;
- uint32_t flags;
- uint64_t count = 0;
- uint64_t cycleCount = 0;
+ uint32_t flags;
+ uint64_t count = 0;
+ uint64_t cycleCount = 0;
};
/// GCOVFunction - Collects function information.
@@ -240,16 +240,16 @@ public:
GCOVFunction(GCOVFile &file) : file(file) {}
- StringRef getName(bool demangle) const;
+ StringRef getName(bool demangle) const;
StringRef getFilename() const;
uint64_t getEntryCount() const;
- GCOVBlock &getExitBlock() const;
+ GCOVBlock &getExitBlock() const;
- iterator_range<BlockIterator> blocksRange() const {
- return make_range(blocks.begin(), blocks.end());
+ iterator_range<BlockIterator> blocksRange() const {
+ return make_range(blocks.begin(), blocks.end());
}
- uint64_t propagateCounts(const GCOVBlock &v, GCOVArc *pred);
+ uint64_t propagateCounts(const GCOVBlock &v, GCOVArc *pred);
void print(raw_ostream &OS) const;
void dump() const;
@@ -263,26 +263,26 @@ public:
uint32_t endColumn = 0;
uint8_t artificial = 0;
StringRef Name;
- mutable SmallString<0> demangled;
+ mutable SmallString<0> demangled;
unsigned srcIdx;
- SmallVector<std::unique_ptr<GCOVBlock>, 0> blocks;
+ SmallVector<std::unique_ptr<GCOVBlock>, 0> blocks;
SmallVector<std::unique_ptr<GCOVArc>, 0> arcs, treeArcs;
- DenseSet<const GCOVBlock *> visited;
+ DenseSet<const GCOVBlock *> visited;
};
/// GCOVBlock - Collects block information.
class GCOVBlock {
public:
using EdgeIterator = SmallVectorImpl<GCOVArc *>::const_iterator;
- using BlockVector = SmallVector<const GCOVBlock *, 1>;
+ using BlockVector = SmallVector<const GCOVBlock *, 1>;
using BlockVectorLists = SmallVector<BlockVector, 4>;
using Edges = SmallVector<GCOVArc *, 4>;
- GCOVBlock(uint32_t N) : number(N) {}
+ GCOVBlock(uint32_t N) : number(N) {}
- void addLine(uint32_t N) { lines.push_back(N); }
- uint32_t getLastLine() const { return lines.back(); }
- uint64_t getCount() const { return count; }
+ void addLine(uint32_t N) { lines.push_back(N); }
+ uint32_t getLastLine() const { return lines.back(); }
+ uint64_t getCount() const { return count; }
void addSrcEdge(GCOVArc *Edge) { pred.push_back(Edge); }
@@ -299,24 +299,24 @@ public:
void print(raw_ostream &OS) const;
void dump() const;
- static uint64_t
- augmentOneCycle(GCOVBlock *src,
- std::vector<std::pair<GCOVBlock *, size_t>> &stack);
- static uint64_t getCyclesCount(const BlockVector &blocks);
+ static uint64_t
+ augmentOneCycle(GCOVBlock *src,
+ std::vector<std::pair<GCOVBlock *, size_t>> &stack);
+ static uint64_t getCyclesCount(const BlockVector &blocks);
static uint64_t getLineCount(const BlockVector &Blocks);
public:
- uint32_t number;
- uint64_t count = 0;
+ uint32_t number;
+ uint64_t count = 0;
SmallVector<GCOVArc *, 2> pred;
SmallVector<GCOVArc *, 2> succ;
- SmallVector<uint32_t, 4> lines;
- bool traversable = false;
- GCOVArc *incoming = nullptr;
+ SmallVector<uint32_t, 4> lines;
+ bool traversable = false;
+ GCOVArc *incoming = nullptr;
};
-void gcovOneInput(const GCOV::Options &options, StringRef filename,
- StringRef gcno, StringRef gcda, GCOVFile &file);
+void gcovOneInput(const GCOV::Options &options, StringRef filename,
+ StringRef gcno, StringRef gcda, GCOVFile &file);
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/ProfileData/InstrProf.h b/contrib/libs/llvm12/include/llvm/ProfileData/InstrProf.h
index ba9c0570ad..99ac560437 100644
--- a/contrib/libs/llvm12/include/llvm/ProfileData/InstrProf.h
+++ b/contrib/libs/llvm12/include/llvm/ProfileData/InstrProf.h
@@ -81,10 +81,10 @@ inline StringRef getInstrProfValueProfFuncName() {
return INSTR_PROF_VALUE_PROF_FUNC_STR;
}
-/// Return the name profile runtime entry point to do memop size value
-/// profiling.
-inline StringRef getInstrProfValueProfMemOpFuncName() {
- return INSTR_PROF_VALUE_PROF_MEMOP_FUNC_STR;
+/// Return the name profile runtime entry point to do memop size value
+/// profiling.
+inline StringRef getInstrProfValueProfMemOpFuncName() {
+ return INSTR_PROF_VALUE_PROF_MEMOP_FUNC_STR;
}
/// Return the name prefix of variables containing instrumented function names.
@@ -569,9 +569,9 @@ StringRef InstrProfSymtab::getFuncNameOrExternalSymbol(uint64_t FuncMD5Hash) {
StringRef InstrProfSymtab::getFuncName(uint64_t FuncMD5Hash) {
finalizeSymtab();
- auto Result = llvm::lower_bound(MD5NameMap, FuncMD5Hash,
- [](const std::pair<uint64_t, StringRef> &LHS,
- uint64_t RHS) { return LHS.first < RHS; });
+ auto Result = llvm::lower_bound(MD5NameMap, FuncMD5Hash,
+ [](const std::pair<uint64_t, StringRef> &LHS,
+ uint64_t RHS) { return LHS.first < RHS; });
if (Result != MD5NameMap.end() && Result->first == FuncMD5Hash)
return Result->second;
return StringRef();
@@ -579,9 +579,9 @@ StringRef InstrProfSymtab::getFuncName(uint64_t FuncMD5Hash) {
Function* InstrProfSymtab::getFunction(uint64_t FuncMD5Hash) {
finalizeSymtab();
- auto Result = llvm::lower_bound(MD5FuncMap, FuncMD5Hash,
- [](const std::pair<uint64_t, Function *> &LHS,
- uint64_t RHS) { return LHS.first < RHS; });
+ auto Result = llvm::lower_bound(MD5FuncMap, FuncMD5Hash,
+ [](const std::pair<uint64_t, Function *> &LHS,
+ uint64_t RHS) { return LHS.first < RHS; });
if (Result != MD5FuncMap.end() && Result->first == FuncMD5Hash)
return Result->second;
return nullptr;
@@ -684,8 +684,8 @@ struct InstrProfValueSiteRecord {
/// Optionally scale merged counts by \p Weight.
void merge(InstrProfValueSiteRecord &Input, uint64_t Weight,
function_ref<void(instrprof_error)> Warn);
- /// Scale up value profile data counts by N (Numerator) / D (Denominator).
- void scale(uint64_t N, uint64_t D, function_ref<void(instrprof_error)> Warn);
+ /// Scale up value profile data counts by N (Numerator) / D (Denominator).
+ void scale(uint64_t N, uint64_t D, function_ref<void(instrprof_error)> Warn);
/// Compute the overlap b/w this record and Input record.
void overlap(InstrProfValueSiteRecord &Input, uint32_t ValueKind,
@@ -759,8 +759,8 @@ struct InstrProfRecord {
function_ref<void(instrprof_error)> Warn);
/// Scale up profile counts (including value profile data) by
- /// a factor of (N / D).
- void scale(uint64_t N, uint64_t D, function_ref<void(instrprof_error)> Warn);
+ /// a factor of (N / D).
+ void scale(uint64_t N, uint64_t D, function_ref<void(instrprof_error)> Warn);
/// Sort value profile data (per site) by count.
void sortValueData() {
@@ -845,8 +845,8 @@ private:
uint64_t Weight,
function_ref<void(instrprof_error)> Warn);
- // Scale up value profile data count by N (Numerator) / D (Denominator).
- void scaleValueProfData(uint32_t ValueKind, uint64_t N, uint64_t D,
+ // Scale up value profile data count by N (Numerator) / D (Denominator).
+ void scaleValueProfData(uint32_t ValueKind, uint64_t N, uint64_t D,
function_ref<void(instrprof_error)> Warn);
};
@@ -988,9 +988,9 @@ enum ProfVersion {
// In this version, the frontend PGO stable hash algorithm got fixed and
// may produce hashes different from Version5.
Version6 = 6,
- // An additional counter is added around logical operators.
- Version7 = 7,
- // The current version is 7.
+ // An additional counter is added around logical operators.
+ Version7 = 7,
+ // The current version is 7.
CurrentVersion = INSTR_PROF_INDEX_VERSION
};
const uint64_t Version = ProfVersion::CurrentVersion;
@@ -1146,8 +1146,8 @@ void getMemOPSizeRangeFromOption(StringRef Str, int64_t &RangeStart,
// Create a COMDAT variable INSTR_PROF_RAW_VERSION_VAR to make the runtime
// aware this is an ir_level profile so it can set the version flag.
-void createIRLevelProfileFlagVar(Module &M, bool IsCS,
- bool InstrEntryBBEnabled);
+void createIRLevelProfileFlagVar(Module &M, bool IsCS,
+ bool InstrEntryBBEnabled);
// Create the variable for the profile file name.
void createProfileFileNameVar(Module &M, StringRef InstrProfileOutput);
diff --git a/contrib/libs/llvm12/include/llvm/ProfileData/InstrProfData.inc b/contrib/libs/llvm12/include/llvm/ProfileData/InstrProfData.inc
index 727723cfe1..f715505ba5 100644
--- a/contrib/libs/llvm12/include/llvm/ProfileData/InstrProfData.inc
+++ b/contrib/libs/llvm12/include/llvm/ProfileData/InstrProfData.inc
@@ -647,9 +647,9 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
/* Raw profile format version (start from 1). */
#define INSTR_PROF_RAW_VERSION 5
/* Indexed profile format version (start from 1). */
-#define INSTR_PROF_INDEX_VERSION 7
+#define INSTR_PROF_INDEX_VERSION 7
/* Coverage mapping format version (start from 0). */
-#define INSTR_PROF_COVMAP_VERSION 4
+#define INSTR_PROF_COVMAP_VERSION 4
/* Profile version is always of type uint64_t. Reserve the upper 8 bits in the
* version for other variants of profile. We set the lowest bit of the upper 8
@@ -661,7 +661,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
#define GET_VERSION(V) ((V) & ~VARIANT_MASKS_ALL)
#define VARIANT_MASK_IR_PROF (0x1ULL << 56)
#define VARIANT_MASK_CSIR_PROF (0x1ULL << 57)
-#define VARIANT_MASK_INSTR_ENTRY (0x1ULL << 58)
+#define VARIANT_MASK_INSTR_ENTRY (0x1ULL << 58)
#define INSTR_PROF_RAW_VERSION_VAR __llvm_profile_raw_version
#define INSTR_PROF_PROFILE_RUNTIME_VAR __llvm_profile_runtime
@@ -744,9 +744,9 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
#define INSTR_PROF_VALUE_PROF_FUNC __llvm_profile_instrument_target
#define INSTR_PROF_VALUE_PROF_FUNC_STR \
INSTR_PROF_QUOTE(INSTR_PROF_VALUE_PROF_FUNC)
-#define INSTR_PROF_VALUE_PROF_MEMOP_FUNC __llvm_profile_instrument_memop
-#define INSTR_PROF_VALUE_PROF_MEMOP_FUNC_STR \
- INSTR_PROF_QUOTE(INSTR_PROF_VALUE_PROF_MEMOP_FUNC)
+#define INSTR_PROF_VALUE_PROF_MEMOP_FUNC __llvm_profile_instrument_memop
+#define INSTR_PROF_VALUE_PROF_MEMOP_FUNC_STR \
+ INSTR_PROF_QUOTE(INSTR_PROF_VALUE_PROF_MEMOP_FUNC)
/* InstrProfile per-function control data alignment. */
#define INSTR_PROF_DATA_ALIGNMENT 8
@@ -774,121 +774,121 @@ typedef struct InstrProfValueData {
#endif
#undef COVMAP_V2_OR_V3
-
-#ifdef INSTR_PROF_VALUE_PROF_MEMOP_API
-
-#ifdef __cplusplus
-#define INSTR_PROF_INLINE inline
-#else
-#define INSTR_PROF_INLINE
-#endif
-
-/* The value range buckets (22 buckets) for the memop size value profiling looks
- * like:
- *
- * [0, 0]
- * [1, 1]
- * [2, 2]
- * [3, 3]
- * [4, 4]
- * [5, 5]
- * [6, 6]
- * [7, 7]
- * [8, 8]
- * [9, 15]
- * [16, 16]
- * [17, 31]
- * [32, 32]
- * [33, 63]
- * [64, 64]
- * [65, 127]
- * [128, 128]
- * [129, 255]
- * [256, 256]
- * [257, 511]
- * [512, 512]
- * [513, UINT64_MAX]
- *
- * Each range has a 'representative value' which is the lower end value of the
- * range and used to store in the runtime profile data records and the VP
- * metadata. For example, it's 2 for [2, 2] and 64 for [65, 127].
- */
-
-/*
- * Clz and Popcount. This code was copied from
- * compiler-rt/lib/fuzzer/{FuzzerBuiltins.h,FuzzerBuiltinsMsvc.h} and
- * llvm/include/llvm/Support/MathExtras.h.
- */
-#if defined(_MSC_VER) && !defined(__clang__)
-
-#include <intrin.h>
-INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
-int InstProfClzll(unsigned long long X) {
- unsigned long LeadZeroIdx = 0;
-#if !defined(_M_ARM64) && !defined(_M_X64)
- // Scan the high 32 bits.
- if (_BitScanReverse(&LeadZeroIdx, (unsigned long)(X >> 32)))
- return (int)(63 - (LeadZeroIdx + 32)); // Create a bit offset
- // from the MSB.
- // Scan the low 32 bits.
- if (_BitScanReverse(&LeadZeroIdx, (unsigned long)(X)))
- return (int)(63 - LeadZeroIdx);
-#else
- if (_BitScanReverse64(&LeadZeroIdx, X)) return 63 - LeadZeroIdx;
-#endif
- return 64;
-}
-INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
-int InstProfPopcountll(unsigned long long X) {
- // This code originates from https://reviews.llvm.org/rG30626254510f.
- unsigned long long v = X;
- v = v - ((v >> 1) & 0x5555555555555555ULL);
- v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
- v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
- return (int)((unsigned long long)(v * 0x0101010101010101ULL) >> 56);
-}
-
-#else
-
-INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
-int InstProfClzll(unsigned long long X) { return __builtin_clzll(X); }
-INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
-int InstProfPopcountll(unsigned long long X) { return __builtin_popcountll(X); }
-
-#endif /* defined(_MSC_VER) && !defined(__clang__) */
-
-/* Map an (observed) memop size value to the representative value of its range.
- * For example, 5 -> 5, 22 -> 17, 99 -> 65, 256 -> 256, 1001 -> 513. */
-INSTR_PROF_VISIBILITY INSTR_PROF_INLINE uint64_t
-InstrProfGetRangeRepValue(uint64_t Value) {
- if (Value <= 8)
- // The first ranges are individually tracked. Use the value as is.
- return Value;
- else if (Value >= 513)
- // The last range is mapped to its lowest value.
- return 513;
- else if (InstProfPopcountll(Value) == 1)
- // If it's a power of two, use it as is.
- return Value;
- else
- // Otherwise, take to the previous power of two + 1.
- return (1 << (64 - InstProfClzll(Value) - 1)) + 1;
-}
-
-/* Return true if the range that an (observed) memop size value belongs to has
- * only a single value in the range. For example, 0 -> true, 8 -> true, 10 ->
- * false, 64 -> true, 100 -> false, 513 -> false. */
-INSTR_PROF_VISIBILITY INSTR_PROF_INLINE unsigned
-InstrProfIsSingleValRange(uint64_t Value) {
- if (Value <= 8)
- // The first ranges are individually tracked.
- return 1;
- else if (InstProfPopcountll(Value) == 1)
- // If it's a power of two, there's only one value.
- return 1;
- else
- // Otherwise, there's more than one value in the range.
- return 0;
-}
-
-#endif /* INSTR_PROF_VALUE_PROF_MEMOP_API */
+
+#ifdef INSTR_PROF_VALUE_PROF_MEMOP_API
+
+#ifdef __cplusplus
+#define INSTR_PROF_INLINE inline
+#else
+#define INSTR_PROF_INLINE
+#endif
+
+/* The value range buckets (22 buckets) for the memop size value profiling looks
+ * like:
+ *
+ * [0, 0]
+ * [1, 1]
+ * [2, 2]
+ * [3, 3]
+ * [4, 4]
+ * [5, 5]
+ * [6, 6]
+ * [7, 7]
+ * [8, 8]
+ * [9, 15]
+ * [16, 16]
+ * [17, 31]
+ * [32, 32]
+ * [33, 63]
+ * [64, 64]
+ * [65, 127]
+ * [128, 128]
+ * [129, 255]
+ * [256, 256]
+ * [257, 511]
+ * [512, 512]
+ * [513, UINT64_MAX]
+ *
+ * Each range has a 'representative value' which is the lower end value of the
+ * range and used to store in the runtime profile data records and the VP
+ * metadata. For example, it's 2 for [2, 2] and 64 for [65, 127].
+ */
+
+/*
+ * Clz and Popcount. This code was copied from
+ * compiler-rt/lib/fuzzer/{FuzzerBuiltins.h,FuzzerBuiltinsMsvc.h} and
+ * llvm/include/llvm/Support/MathExtras.h.
+ */
+#if defined(_MSC_VER) && !defined(__clang__)
+
+#include <intrin.h>
+INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
+int InstProfClzll(unsigned long long X) {
+ unsigned long LeadZeroIdx = 0;
+#if !defined(_M_ARM64) && !defined(_M_X64)
+ // Scan the high 32 bits.
+ if (_BitScanReverse(&LeadZeroIdx, (unsigned long)(X >> 32)))
+ return (int)(63 - (LeadZeroIdx + 32)); // Create a bit offset
+ // from the MSB.
+ // Scan the low 32 bits.
+ if (_BitScanReverse(&LeadZeroIdx, (unsigned long)(X)))
+ return (int)(63 - LeadZeroIdx);
+#else
+ if (_BitScanReverse64(&LeadZeroIdx, X)) return 63 - LeadZeroIdx;
+#endif
+ return 64;
+}
+INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
+int InstProfPopcountll(unsigned long long X) {
+ // This code originates from https://reviews.llvm.org/rG30626254510f.
+ unsigned long long v = X;
+ v = v - ((v >> 1) & 0x5555555555555555ULL);
+ v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
+ v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
+ return (int)((unsigned long long)(v * 0x0101010101010101ULL) >> 56);
+}
+
+#else
+
+INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
+int InstProfClzll(unsigned long long X) { return __builtin_clzll(X); }
+INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
+int InstProfPopcountll(unsigned long long X) { return __builtin_popcountll(X); }
+
+#endif /* defined(_MSC_VER) && !defined(__clang__) */
+
+/* Map an (observed) memop size value to the representative value of its range.
+ * For example, 5 -> 5, 22 -> 17, 99 -> 65, 256 -> 256, 1001 -> 513. */
+INSTR_PROF_VISIBILITY INSTR_PROF_INLINE uint64_t
+InstrProfGetRangeRepValue(uint64_t Value) {
+ if (Value <= 8)
+ // The first ranges are individually tracked. Use the value as is.
+ return Value;
+ else if (Value >= 513)
+ // The last range is mapped to its lowest value.
+ return 513;
+ else if (InstProfPopcountll(Value) == 1)
+ // If it's a power of two, use it as is.
+ return Value;
+ else
+ // Otherwise, take to the previous power of two + 1.
+ return (1 << (64 - InstProfClzll(Value) - 1)) + 1;
+}
+
+/* Return true if the range that an (observed) memop size value belongs to has
+ * only a single value in the range. For example, 0 -> true, 8 -> true, 10 ->
+ * false, 64 -> true, 100 -> false, 513 -> false. */
+INSTR_PROF_VISIBILITY INSTR_PROF_INLINE unsigned
+InstrProfIsSingleValRange(uint64_t Value) {
+ if (Value <= 8)
+ // The first ranges are individually tracked.
+ return 1;
+ else if (InstProfPopcountll(Value) == 1)
+ // If it's a power of two, there's only one value.
+ return 1;
+ else
+ // Otherwise, there's more than one value in the range.
+ return 0;
+}
+
+#endif /* INSTR_PROF_VALUE_PROF_MEMOP_API */
diff --git a/contrib/libs/llvm12/include/llvm/ProfileData/InstrProfReader.h b/contrib/libs/llvm12/include/llvm/ProfileData/InstrProfReader.h
index a95a7657b0..29555e07d8 100644
--- a/contrib/libs/llvm12/include/llvm/ProfileData/InstrProfReader.h
+++ b/contrib/libs/llvm12/include/llvm/ProfileData/InstrProfReader.h
@@ -90,8 +90,8 @@ public:
virtual bool hasCSIRLevelProfile() const = 0;
- virtual bool instrEntryBBEnabled() const = 0;
-
+ virtual bool instrEntryBBEnabled() const = 0;
+
/// Return the PGO symtab. There are three different readers:
/// Raw, Text, and Indexed profile readers. The first two types
/// of readers are used only by llvm-profdata tool, while the indexed
@@ -161,7 +161,7 @@ private:
line_iterator Line;
bool IsIRLevelProfile = false;
bool HasCSIRLevelProfile = false;
- bool InstrEntryBBEnabled = false;
+ bool InstrEntryBBEnabled = false;
Error readValueProfileData(InstrProfRecord &Record);
@@ -178,8 +178,8 @@ public:
bool hasCSIRLevelProfile() const override { return HasCSIRLevelProfile; }
- bool instrEntryBBEnabled() const override { return InstrEntryBBEnabled; }
-
+ bool instrEntryBBEnabled() const override { return InstrEntryBBEnabled; }
+
/// Read the header.
Error readHeader() override;
@@ -240,10 +240,10 @@ public:
return (Version & VARIANT_MASK_CSIR_PROF) != 0;
}
- bool instrEntryBBEnabled() const override {
- return (Version & VARIANT_MASK_INSTR_ENTRY) != 0;
- }
-
+ bool instrEntryBBEnabled() const override {
+ return (Version & VARIANT_MASK_INSTR_ENTRY) != 0;
+ }
+
InstrProfSymtab &getSymtab() override {
assert(Symtab.get());
return *Symtab.get();
@@ -380,7 +380,7 @@ struct InstrProfReaderIndexBase {
virtual uint64_t getVersion() const = 0;
virtual bool isIRLevelProfile() const = 0;
virtual bool hasCSIRLevelProfile() const = 0;
- virtual bool instrEntryBBEnabled() const = 0;
+ virtual bool instrEntryBBEnabled() const = 0;
virtual Error populateSymtab(InstrProfSymtab &) = 0;
};
@@ -429,10 +429,10 @@ public:
return (FormatVersion & VARIANT_MASK_CSIR_PROF) != 0;
}
- bool instrEntryBBEnabled() const override {
- return (FormatVersion & VARIANT_MASK_INSTR_ENTRY) != 0;
- }
-
+ bool instrEntryBBEnabled() const override {
+ return (FormatVersion & VARIANT_MASK_INSTR_ENTRY) != 0;
+ }
+
Error populateSymtab(InstrProfSymtab &Symtab) override {
return Symtab.create(HashTable->keys());
}
@@ -487,10 +487,10 @@ public:
return Index->hasCSIRLevelProfile();
}
- bool instrEntryBBEnabled() const override {
- return Index->instrEntryBBEnabled();
- }
-
+ bool instrEntryBBEnabled() const override {
+ return Index->instrEntryBBEnabled();
+ }
+
/// Return true if the given buffer is in an indexed instrprof format.
static bool hasFormat(const MemoryBuffer &DataBuffer);
diff --git a/contrib/libs/llvm12/include/llvm/ProfileData/InstrProfWriter.h b/contrib/libs/llvm12/include/llvm/ProfileData/InstrProfWriter.h
index cc4668f7f3..d9824d565b 100644
--- a/contrib/libs/llvm12/include/llvm/ProfileData/InstrProfWriter.h
+++ b/contrib/libs/llvm12/include/llvm/ProfileData/InstrProfWriter.h
@@ -47,16 +47,16 @@ private:
bool Sparse;
StringMap<ProfilingData> FunctionData;
ProfKind ProfileKind = PF_Unknown;
- bool InstrEntryBBEnabled;
+ bool InstrEntryBBEnabled;
// Use raw pointer here for the incomplete type object.
InstrProfRecordWriterTrait *InfoObj;
public:
- InstrProfWriter(bool Sparse = false, bool InstrEntryBBEnabled = false);
+ InstrProfWriter(bool Sparse = false, bool InstrEntryBBEnabled = false);
~InstrProfWriter();
- StringMap<ProfilingData> &getProfileData() { return FunctionData; }
-
+ StringMap<ProfilingData> &getProfileData() { return FunctionData; }
+
/// Add function counts for the given function. If there are already counts
/// for this function and the hash and number of counts match, each counter is
/// summed. Optionally scale counts by \p Weight.
@@ -107,7 +107,7 @@ public:
return Error::success();
}
- void setInstrEntryBBEnabled(bool Enabled) { InstrEntryBBEnabled = Enabled; }
+ void setInstrEntryBBEnabled(bool Enabled) { InstrEntryBBEnabled = Enabled; }
// Internal interface for testing purpose only.
void setValueProfDataEndianness(support::endianness Endianness);
void setOutputSparse(bool Sparse);
diff --git a/contrib/libs/llvm12/include/llvm/ProfileData/ProfileCommon.h b/contrib/libs/llvm12/include/llvm/ProfileData/ProfileCommon.h
index 6c4713add1..649b18830a 100644
--- a/contrib/libs/llvm12/include/llvm/ProfileData/ProfileCommon.h
+++ b/contrib/libs/llvm12/include/llvm/ProfileData/ProfileCommon.h
@@ -24,7 +24,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/IR/ProfileSummary.h"
#include "llvm/ProfileData/InstrProf.h"
-#include "llvm/ProfileData/SampleProf.h"
+#include "llvm/ProfileData/SampleProf.h"
#include "llvm/Support/Error.h"
#include <algorithm>
#include <cstdint>
@@ -41,8 +41,8 @@ class FunctionSamples;
} // end namespace sampleprof
-inline const char *getHotSectionPrefix() { return "hot"; }
-inline const char *getUnlikelySectionPrefix() { return "unlikely"; }
+inline const char *getHotSectionPrefix() { return "hot"; }
+inline const char *getUnlikelySectionPrefix() { return "unlikely"; }
class ProfileSummaryBuilder {
private:
@@ -97,8 +97,8 @@ public:
void addRecord(const sampleprof::FunctionSamples &FS,
bool isCallsiteSample = false);
- std::unique_ptr<ProfileSummary> computeSummaryForProfiles(
- const StringMap<sampleprof::FunctionSamples> &Profiles);
+ std::unique_ptr<ProfileSummary> computeSummaryForProfiles(
+ const StringMap<sampleprof::FunctionSamples> &Profiles);
std::unique_ptr<ProfileSummary> getSummary();
};
diff --git a/contrib/libs/llvm12/include/llvm/ProfileData/SampleProf.h b/contrib/libs/llvm12/include/llvm/ProfileData/SampleProf.h
index 5478b9a474..669bd70d3a 100644
--- a/contrib/libs/llvm12/include/llvm/ProfileData/SampleProf.h
+++ b/contrib/libs/llvm12/include/llvm/ProfileData/SampleProf.h
@@ -61,8 +61,8 @@ enum class sampleprof_error {
ostream_seek_unsupported,
compress_failed,
uncompress_failed,
- zlib_unavailable,
- hash_mismatch
+ zlib_unavailable,
+ hash_mismatch
};
inline std::error_code make_error_code(sampleprof_error E) {
@@ -128,7 +128,7 @@ enum SecType {
SecNameTable = 2,
SecProfileSymbolList = 3,
SecFuncOffsetTable = 4,
- SecFuncMetadata = 5,
+ SecFuncMetadata = 5,
// marker for the first type of profile.
SecFuncProfileFirst = 32,
SecLBRProfile = SecFuncProfileFirst
@@ -146,8 +146,8 @@ static inline std::string getSecName(SecType Type) {
return "ProfileSymbolListSection";
case SecFuncOffsetTable:
return "FuncOffsetTableSection";
- case SecFuncMetadata:
- return "FunctionMetadata";
+ case SecFuncMetadata:
+ return "FunctionMetadata";
case SecLBRProfile:
return "LBRProfileSection";
}
@@ -161,9 +161,9 @@ struct SecHdrTableEntry {
uint64_t Flags;
uint64_t Offset;
uint64_t Size;
- // The index indicating the location of the current entry in
- // SectionHdrLayout table.
- uint32_t LayoutIndex;
+ // The index indicating the location of the current entry in
+ // SectionHdrLayout table.
+ uint32_t LayoutIndex;
};
// Flags common for all sections are defined here. In SecHdrTableEntry::Flags,
@@ -171,9 +171,9 @@ struct SecHdrTableEntry {
// will be saved in the higher 32 bits.
enum class SecCommonFlags : uint32_t {
SecFlagInValid = 0,
- SecFlagCompress = (1 << 0),
- // Indicate the section contains only profile without context.
- SecFlagFlat = (1 << 1)
+ SecFlagCompress = (1 << 0),
+ // Indicate the section contains only profile without context.
+ SecFlagFlat = (1 << 1)
};
// Section specific flags are defined here.
@@ -181,10 +181,10 @@ enum class SecCommonFlags : uint32_t {
// a new check in verifySecFlag.
enum class SecNameTableFlags : uint32_t {
SecFlagInValid = 0,
- SecFlagMD5Name = (1 << 0),
- // Store MD5 in fixed length instead of ULEB128 so NameTable can be
- // accessed like an array.
- SecFlagFixedLengthMD5 = (1 << 1)
+ SecFlagMD5Name = (1 << 0),
+ // Store MD5 in fixed length instead of ULEB128 so NameTable can be
+ // accessed like an array.
+ SecFlagFixedLengthMD5 = (1 << 1)
};
enum class SecProfSummaryFlags : uint32_t {
SecFlagInValid = 0,
@@ -194,11 +194,11 @@ enum class SecProfSummaryFlags : uint32_t {
SecFlagPartial = (1 << 0)
};
-enum class SecFuncMetadataFlags : uint32_t {
- SecFlagInvalid = 0,
- SecFlagIsProbeBased = (1 << 0),
-};
-
+enum class SecFuncMetadataFlags : uint32_t {
+ SecFlagInvalid = 0,
+ SecFlagIsProbeBased = (1 << 0),
+};
+
// Verify section specific flag is used for the correct section.
template <class SecFlagType>
static inline void verifySecFlag(SecType Type, SecFlagType Flag) {
@@ -215,9 +215,9 @@ static inline void verifySecFlag(SecType Type, SecFlagType Flag) {
case SecProfSummary:
IsFlagLegal = std::is_same<SecProfSummaryFlags, SecFlagType>();
break;
- case SecFuncMetadata:
- IsFlagLegal = std::is_same<SecFuncMetadataFlags, SecFlagType>();
- break;
+ case SecFuncMetadata:
+ IsFlagLegal = std::is_same<SecFuncMetadataFlags, SecFlagType>();
+ break;
default:
break;
}
@@ -269,14 +269,14 @@ struct LineLocation {
(LineOffset == O.LineOffset && Discriminator < O.Discriminator);
}
- bool operator==(const LineLocation &O) const {
- return LineOffset == O.LineOffset && Discriminator == O.Discriminator;
- }
-
- bool operator!=(const LineLocation &O) const {
- return LineOffset != O.LineOffset || Discriminator != O.Discriminator;
- }
-
+ bool operator==(const LineLocation &O) const {
+ return LineOffset == O.LineOffset && Discriminator == O.Discriminator;
+ }
+
+ bool operator!=(const LineLocation &O) const {
+ return LineOffset != O.LineOffset || Discriminator != O.Discriminator;
+ }
+
uint32_t LineOffset;
uint32_t Discriminator;
};
@@ -354,16 +354,16 @@ public:
return SortedTargets;
}
- /// Prorate call targets by a distribution factor.
- static const CallTargetMap adjustCallTargets(const CallTargetMap &Targets,
- float DistributionFactor) {
- CallTargetMap AdjustedTargets;
- for (const auto &I : Targets) {
- AdjustedTargets[I.first()] = I.second * DistributionFactor;
- }
- return AdjustedTargets;
- }
-
+ /// Prorate call targets by a distribution factor.
+ static const CallTargetMap adjustCallTargets(const CallTargetMap &Targets,
+ float DistributionFactor) {
+ CallTargetMap AdjustedTargets;
+ for (const auto &I : Targets) {
+ AdjustedTargets[I.first()] = I.second * DistributionFactor;
+ }
+ return AdjustedTargets;
+ }
+
/// Merge the samples in \p Other into this record.
/// Optionally scale sample counts by \p Weight.
sampleprof_error merge(const SampleRecord &Other, uint64_t Weight = 1) {
@@ -384,137 +384,137 @@ private:
raw_ostream &operator<<(raw_ostream &OS, const SampleRecord &Sample);
-// State of context associated with FunctionSamples
-enum ContextStateMask {
- UnknownContext = 0x0, // Profile without context
- RawContext = 0x1, // Full context profile from input profile
- SyntheticContext = 0x2, // Synthetic context created for context promotion
- InlinedContext = 0x4, // Profile for context that is inlined into caller
- MergedContext = 0x8 // Profile for context merged into base profile
-};
-
-// Sample context for FunctionSamples. It consists of the calling context,
-// the function name and context state. Internally sample context is represented
-// using StringRef, which is also the input for constructing a `SampleContext`.
-// It can accept and represent both full context string as well as context-less
-// function name.
-// Example of full context string (note the wrapping `[]`):
-// `[main:3 @ _Z5funcAi:1 @ _Z8funcLeafi]`
-// Example of context-less function name (same as AutoFDO):
-// `_Z8funcLeafi`
-class SampleContext {
-public:
- SampleContext() : State(UnknownContext) {}
- SampleContext(StringRef ContextStr,
- ContextStateMask CState = UnknownContext) {
- setContext(ContextStr, CState);
- }
-
- // Promote context by removing top frames (represented by `ContextStrToRemove`).
- // Note that with string representation of context, the promotion is effectively
- // a substr operation with `ContextStrToRemove` removed from left.
- void promoteOnPath(StringRef ContextStrToRemove) {
- assert(FullContext.startswith(ContextStrToRemove));
-
- // Remove leading context and frame separator " @ ".
- FullContext = FullContext.substr(ContextStrToRemove.size() + 3);
- CallingContext = CallingContext.substr(ContextStrToRemove.size() + 3);
- }
-
- // Split the top context frame (left-most substr) from context.
- static std::pair<StringRef, StringRef>
- splitContextString(StringRef ContextStr) {
- return ContextStr.split(" @ ");
- }
-
- // Decode context string for a frame to get function name and location.
- // `ContextStr` is in the form of `FuncName:StartLine.Discriminator`.
- static void decodeContextString(StringRef ContextStr, StringRef &FName,
- LineLocation &LineLoc) {
- // Get function name
- auto EntrySplit = ContextStr.split(':');
- FName = EntrySplit.first;
-
- LineLoc = {0, 0};
- if (!EntrySplit.second.empty()) {
- // Get line offset, use signed int for getAsInteger so string will
- // be parsed as signed.
- int LineOffset = 0;
- auto LocSplit = EntrySplit.second.split('.');
- LocSplit.first.getAsInteger(10, LineOffset);
- LineLoc.LineOffset = LineOffset;
-
- // Get discriminator
- if (!LocSplit.second.empty())
- LocSplit.second.getAsInteger(10, LineLoc.Discriminator);
- }
- }
-
- operator StringRef() const { return FullContext; }
- bool hasState(ContextStateMask S) { return State & (uint32_t)S; }
- void setState(ContextStateMask S) { State |= (uint32_t)S; }
- void clearState(ContextStateMask S) { State &= (uint32_t)~S; }
- bool hasContext() const { return State != UnknownContext; }
- bool isBaseContext() const { return CallingContext.empty(); }
- StringRef getNameWithoutContext() const { return Name; }
- StringRef getCallingContext() const { return CallingContext; }
- StringRef getNameWithContext(bool WithBracket = false) const {
- return WithBracket ? InputContext : FullContext;
- }
-
-private:
- // Give a context string, decode and populate internal states like
- // Function name, Calling context and context state. Example of input
- // `ContextStr`: `[main:3 @ _Z5funcAi:1 @ _Z8funcLeafi]`
- void setContext(StringRef ContextStr, ContextStateMask CState) {
- assert(!ContextStr.empty());
- InputContext = ContextStr;
- // Note that `[]` wrapped input indicates a full context string, otherwise
- // it's treated as context-less function name only.
- bool HasContext = ContextStr.startswith("[");
- if (!HasContext && CState == UnknownContext) {
- State = UnknownContext;
- Name = FullContext = ContextStr;
- } else {
- // Assume raw context profile if unspecified
- if (CState == UnknownContext)
- State = RawContext;
- else
- State = CState;
-
- // Remove encapsulating '[' and ']' if any
- if (HasContext)
- FullContext = ContextStr.substr(1, ContextStr.size() - 2);
- else
- FullContext = ContextStr;
-
- // Caller is to the left of callee in context string
- auto NameContext = FullContext.rsplit(" @ ");
- if (NameContext.second.empty()) {
- Name = NameContext.first;
- CallingContext = NameContext.second;
- } else {
- Name = NameContext.second;
- CallingContext = NameContext.first;
- }
- }
- }
-
- // Input context string including bracketed calling context and leaf function
- // name
- StringRef InputContext;
- // Full context string including calling context and leaf function name
- StringRef FullContext;
- // Function name for the associated sample profile
- StringRef Name;
- // Calling context (leaf function excluded) for the associated sample profile
- StringRef CallingContext;
- // State of the associated sample profile
- uint32_t State;
-};
-
+// State of context associated with FunctionSamples
+enum ContextStateMask {
+ UnknownContext = 0x0, // Profile without context
+ RawContext = 0x1, // Full context profile from input profile
+ SyntheticContext = 0x2, // Synthetic context created for context promotion
+ InlinedContext = 0x4, // Profile for context that is inlined into caller
+ MergedContext = 0x8 // Profile for context merged into base profile
+};
+
+// Sample context for FunctionSamples. It consists of the calling context,
+// the function name and context state. Internally sample context is represented
+// using StringRef, which is also the input for constructing a `SampleContext`.
+// It can accept and represent both full context string as well as context-less
+// function name.
+// Example of full context string (note the wrapping `[]`):
+// `[main:3 @ _Z5funcAi:1 @ _Z8funcLeafi]`
+// Example of context-less function name (same as AutoFDO):
+// `_Z8funcLeafi`
+class SampleContext {
+public:
+ SampleContext() : State(UnknownContext) {}
+ SampleContext(StringRef ContextStr,
+ ContextStateMask CState = UnknownContext) {
+ setContext(ContextStr, CState);
+ }
+
+ // Promote context by removing top frames (represented by `ContextStrToRemove`).
+ // Note that with string representation of context, the promotion is effectively
+ // a substr operation with `ContextStrToRemove` removed from left.
+ void promoteOnPath(StringRef ContextStrToRemove) {
+ assert(FullContext.startswith(ContextStrToRemove));
+
+ // Remove leading context and frame separator " @ ".
+ FullContext = FullContext.substr(ContextStrToRemove.size() + 3);
+ CallingContext = CallingContext.substr(ContextStrToRemove.size() + 3);
+ }
+
+ // Split the top context frame (left-most substr) from context.
+ static std::pair<StringRef, StringRef>
+ splitContextString(StringRef ContextStr) {
+ return ContextStr.split(" @ ");
+ }
+
+ // Decode context string for a frame to get function name and location.
+ // `ContextStr` is in the form of `FuncName:StartLine.Discriminator`.
+ static void decodeContextString(StringRef ContextStr, StringRef &FName,
+ LineLocation &LineLoc) {
+ // Get function name
+ auto EntrySplit = ContextStr.split(':');
+ FName = EntrySplit.first;
+
+ LineLoc = {0, 0};
+ if (!EntrySplit.second.empty()) {
+ // Get line offset, use signed int for getAsInteger so string will
+ // be parsed as signed.
+ int LineOffset = 0;
+ auto LocSplit = EntrySplit.second.split('.');
+ LocSplit.first.getAsInteger(10, LineOffset);
+ LineLoc.LineOffset = LineOffset;
+
+ // Get discriminator
+ if (!LocSplit.second.empty())
+ LocSplit.second.getAsInteger(10, LineLoc.Discriminator);
+ }
+ }
+
+ operator StringRef() const { return FullContext; }
+ bool hasState(ContextStateMask S) { return State & (uint32_t)S; }
+ void setState(ContextStateMask S) { State |= (uint32_t)S; }
+ void clearState(ContextStateMask S) { State &= (uint32_t)~S; }
+ bool hasContext() const { return State != UnknownContext; }
+ bool isBaseContext() const { return CallingContext.empty(); }
+ StringRef getNameWithoutContext() const { return Name; }
+ StringRef getCallingContext() const { return CallingContext; }
+ StringRef getNameWithContext(bool WithBracket = false) const {
+ return WithBracket ? InputContext : FullContext;
+ }
+
+private:
+ // Give a context string, decode and populate internal states like
+ // Function name, Calling context and context state. Example of input
+ // `ContextStr`: `[main:3 @ _Z5funcAi:1 @ _Z8funcLeafi]`
+ void setContext(StringRef ContextStr, ContextStateMask CState) {
+ assert(!ContextStr.empty());
+ InputContext = ContextStr;
+ // Note that `[]` wrapped input indicates a full context string, otherwise
+ // it's treated as context-less function name only.
+ bool HasContext = ContextStr.startswith("[");
+ if (!HasContext && CState == UnknownContext) {
+ State = UnknownContext;
+ Name = FullContext = ContextStr;
+ } else {
+ // Assume raw context profile if unspecified
+ if (CState == UnknownContext)
+ State = RawContext;
+ else
+ State = CState;
+
+ // Remove encapsulating '[' and ']' if any
+ if (HasContext)
+ FullContext = ContextStr.substr(1, ContextStr.size() - 2);
+ else
+ FullContext = ContextStr;
+
+ // Caller is to the left of callee in context string
+ auto NameContext = FullContext.rsplit(" @ ");
+ if (NameContext.second.empty()) {
+ Name = NameContext.first;
+ CallingContext = NameContext.second;
+ } else {
+ Name = NameContext.second;
+ CallingContext = NameContext.first;
+ }
+ }
+ }
+
+ // Input context string including bracketed calling context and leaf function
+ // name
+ StringRef InputContext;
+ // Full context string including calling context and leaf function name
+ StringRef FullContext;
+ // Function name for the associated sample profile
+ StringRef Name;
+ // Calling context (leaf function excluded) for the associated sample profile
+ StringRef CallingContext;
+ // State of the associated sample profile
+ uint32_t State;
+};
+
class FunctionSamples;
-class SampleProfileReaderItaniumRemapper;
+class SampleProfileReaderItaniumRemapper;
using BodySampleMap = std::map<LineLocation, SampleRecord>;
// NOTE: Using a StringMap here makes parsed profiles consume around 17% more
@@ -542,8 +542,8 @@ public:
: sampleprof_error::success;
}
- void setTotalSamples(uint64_t Num) { TotalSamples = Num; }
-
+ void setTotalSamples(uint64_t Num) { TotalSamples = Num; }
+
sampleprof_error addHeadSamples(uint64_t Num, uint64_t Weight = 1) {
bool Overflowed;
TotalHeadSamples =
@@ -572,22 +572,22 @@ public:
ErrorOr<uint64_t> findSamplesAt(uint32_t LineOffset,
uint32_t Discriminator) const {
const auto &ret = BodySamples.find(LineLocation(LineOffset, Discriminator));
- if (ret == BodySamples.end()) {
- // For CSSPGO, in order to conserve profile size, we no longer write out
- // locations profile for those not hit during training, so we need to
- // treat them as zero instead of error here.
- if (ProfileIsCS)
- return 0;
+ if (ret == BodySamples.end()) {
+ // For CSSPGO, in order to conserve profile size, we no longer write out
+ // locations profile for those not hit during training, so we need to
+ // treat them as zero instead of error here.
+ if (ProfileIsCS)
+ return 0;
+ return std::error_code();
+ // A missing counter for a probe likely means the probe was not executed.
+ // Treat it as a zero count instead of an unknown count to help edge
+ // weight inference.
+ if (FunctionSamples::ProfileIsProbeBased)
+ return 0;
return std::error_code();
- // A missing counter for a probe likely means the probe was not executed.
- // Treat it as a zero count instead of an unknown count to help edge
- // weight inference.
- if (FunctionSamples::ProfileIsProbeBased)
- return 0;
- return std::error_code();
- } else {
+ } else {
return ret->second.getSamples();
- }
+ }
}
/// Returns the call target map collected at a given location.
@@ -601,16 +601,16 @@ public:
return ret->second.getCallTargets();
}
- /// Returns the call target map collected at a given location specified by \p
- /// CallSite. If the location is not found in profile, return error.
- ErrorOr<SampleRecord::CallTargetMap>
- findCallTargetMapAt(const LineLocation &CallSite) const {
- const auto &Ret = BodySamples.find(CallSite);
- if (Ret == BodySamples.end())
- return std::error_code();
- return Ret->second.getCallTargets();
- }
-
+ /// Returns the call target map collected at a given location specified by \p
+ /// CallSite. If the location is not found in profile, return error.
+ ErrorOr<SampleRecord::CallTargetMap>
+ findCallTargetMapAt(const LineLocation &CallSite) const {
+ const auto &Ret = BodySamples.find(CallSite);
+ if (Ret == BodySamples.end())
+ return std::error_code();
+ return Ret->second.getCallTargets();
+ }
+
/// Return the function samples at the given callsite location.
FunctionSamplesMap &functionSamplesAt(const LineLocation &Loc) {
return CallsiteSamples[Loc];
@@ -625,15 +625,15 @@ public:
return &iter->second;
}
- /// Returns a pointer to FunctionSamples at the given callsite location
- /// \p Loc with callee \p CalleeName. If no callsite can be found, relax
- /// the restriction to return the FunctionSamples at callsite location
- /// \p Loc with the maximum total sample count. If \p Remapper is not
- /// nullptr, use \p Remapper to find FunctionSamples with equivalent name
- /// as \p CalleeName.
- const FunctionSamples *
- findFunctionSamplesAt(const LineLocation &Loc, StringRef CalleeName,
- SampleProfileReaderItaniumRemapper *Remapper) const;
+ /// Returns a pointer to FunctionSamples at the given callsite location
+ /// \p Loc with callee \p CalleeName. If no callsite can be found, relax
+ /// the restriction to return the FunctionSamples at callsite location
+ /// \p Loc with the maximum total sample count. If \p Remapper is not
+ /// nullptr, use \p Remapper to find FunctionSamples with equivalent name
+ /// as \p CalleeName.
+ const FunctionSamples *
+ findFunctionSamplesAt(const LineLocation &Loc, StringRef CalleeName,
+ SampleProfileReaderItaniumRemapper *Remapper) const;
bool empty() const { return TotalSamples == 0; }
@@ -650,11 +650,11 @@ public:
/// Return the sample count of the first instruction of the function.
/// The function can be either a standalone symbol or an inlined function.
uint64_t getEntrySamples() const {
- if (FunctionSamples::ProfileIsCS && getHeadSamples()) {
- // For CS profile, if we already have more accurate head samples
- // counted by branch sample from caller, use them as entry samples.
- return getHeadSamples();
- }
+ if (FunctionSamples::ProfileIsCS && getHeadSamples()) {
+ // For CS profile, if we already have more accurate head samples
+ // counted by branch sample from caller, use them as entry samples.
+ return getHeadSamples();
+ }
uint64_t Count = 0;
// Use either BodySamples or CallsiteSamples which ever has the smaller
// lineno.
@@ -697,24 +697,24 @@ public:
sampleprof_error merge(const FunctionSamples &Other, uint64_t Weight = 1) {
sampleprof_error Result = sampleprof_error::success;
Name = Other.getName();
- if (!GUIDToFuncNameMap)
- GUIDToFuncNameMap = Other.GUIDToFuncNameMap;
- if (Context.getNameWithContext(true).empty())
- Context = Other.getContext();
- if (FunctionHash == 0) {
- // Set the function hash code for the target profile.
- FunctionHash = Other.getFunctionHash();
- } else if (FunctionHash != Other.getFunctionHash()) {
- // The two profiles coming with different valid hash codes indicates
- // either:
- // 1. They are same-named static functions from different compilation
- // units (without using -unique-internal-linkage-names), or
- // 2. They are really the same function but from different compilations.
- // Let's bail out in either case for now, which means one profile is
- // dropped.
- return sampleprof_error::hash_mismatch;
- }
-
+ if (!GUIDToFuncNameMap)
+ GUIDToFuncNameMap = Other.GUIDToFuncNameMap;
+ if (Context.getNameWithContext(true).empty())
+ Context = Other.getContext();
+ if (FunctionHash == 0) {
+ // Set the function hash code for the target profile.
+ FunctionHash = Other.getFunctionHash();
+ } else if (FunctionHash != Other.getFunctionHash()) {
+ // The two profiles coming with different valid hash codes indicates
+ // either:
+ // 1. They are same-named static functions from different compilation
+ // units (without using -unique-internal-linkage-names), or
+ // 2. They are really the same function but from different compilations.
+ // Let's bail out in either case for now, which means one profile is
+ // dropped.
+ return sampleprof_error::hash_mismatch;
+ }
+
MergeResult(Result, addTotalSamples(Other.getTotalSamples(), Weight));
MergeResult(Result, addHeadSamples(Other.getHeadSamples(), Weight));
for (const auto &I : Other.getBodySamples()) {
@@ -766,34 +766,34 @@ public:
/// Return the function name.
StringRef getName() const { return Name; }
- /// Return function name with context.
- StringRef getNameWithContext(bool WithBracket = false) const {
- return FunctionSamples::ProfileIsCS
- ? Context.getNameWithContext(WithBracket)
- : Name;
- }
-
+ /// Return function name with context.
+ StringRef getNameWithContext(bool WithBracket = false) const {
+ return FunctionSamples::ProfileIsCS
+ ? Context.getNameWithContext(WithBracket)
+ : Name;
+ }
+
/// Return the original function name.
StringRef getFuncName() const { return getFuncName(Name); }
- void setFunctionHash(uint64_t Hash) { FunctionHash = Hash; }
-
- uint64_t getFunctionHash() const { return FunctionHash; }
-
+ void setFunctionHash(uint64_t Hash) { FunctionHash = Hash; }
+
+ uint64_t getFunctionHash() const { return FunctionHash; }
+
/// Return the canonical name for a function, taking into account
/// suffix elision policy attributes.
static StringRef getCanonicalFnName(const Function &F) {
auto AttrName = "sample-profile-suffix-elision-policy";
auto Attr = F.getFnAttribute(AttrName).getValueAsString();
- return getCanonicalFnName(F.getName(), Attr);
- }
-
- static StringRef getCanonicalFnName(StringRef FnName, StringRef Attr = "") {
- static const char *knownSuffixes[] = { ".llvm.", ".part." };
+ return getCanonicalFnName(F.getName(), Attr);
+ }
+
+ static StringRef getCanonicalFnName(StringRef FnName, StringRef Attr = "") {
+ static const char *knownSuffixes[] = { ".llvm.", ".part." };
if (Attr == "" || Attr == "all") {
- return FnName.split('.').first;
+ return FnName.split('.').first;
} else if (Attr == "selected") {
- StringRef Cand(FnName);
+ StringRef Cand(FnName);
for (const auto &Suf : knownSuffixes) {
StringRef Suffix(Suf);
auto It = Cand.rfind(Suffix);
@@ -805,11 +805,11 @@ public:
}
return Cand;
} else if (Attr == "none") {
- return FnName;
+ return FnName;
} else {
assert(false && "internal error: unknown suffix elision policy");
}
- return FnName;
+ return FnName;
}
/// Translate \p Name into its original name.
@@ -824,19 +824,19 @@ public:
return Name;
assert(GUIDToFuncNameMap && "GUIDToFuncNameMap needs to be popluated first");
- return GUIDToFuncNameMap->lookup(std::stoull(Name.data()));
+ return GUIDToFuncNameMap->lookup(std::stoull(Name.data()));
}
/// Returns the line offset to the start line of the subprogram.
/// We assume that a single function will not exceed 65535 LOC.
static unsigned getOffset(const DILocation *DIL);
- /// Returns a unique call site identifier for a given debug location of a call
- /// instruction. This is wrapper of two scenarios, the probe-based profile and
- /// regular profile, to hide implementation details from the sample loader and
- /// the context tracker.
- static LineLocation getCallSiteIdentifier(const DILocation *DIL);
-
+ /// Returns a unique call site identifier for a given debug location of a call
+ /// instruction. This is wrapper of two scenarios, the probe-based profile and
+ /// regular profile, to hide implementation details from the sample loader and
+ /// the context tracker.
+ static LineLocation getCallSiteIdentifier(const DILocation *DIL);
+
/// Get the FunctionSamples of the inline instance where DIL originates
/// from.
///
@@ -846,20 +846,20 @@ public:
/// tree nodes in the profile.
///
/// \returns the FunctionSamples pointer to the inlined instance.
- /// If \p Remapper is not nullptr, it will be used to find matching
- /// FunctionSamples with not exactly the same but equivalent name.
- const FunctionSamples *findFunctionSamples(
- const DILocation *DIL,
- SampleProfileReaderItaniumRemapper *Remapper = nullptr) const;
-
- static bool ProfileIsProbeBased;
-
- static bool ProfileIsCS;
-
- SampleContext &getContext() const { return Context; }
-
- void setContext(const SampleContext &FContext) { Context = FContext; }
-
+ /// If \p Remapper is not nullptr, it will be used to find matching
+ /// FunctionSamples with not exactly the same but equivalent name.
+ const FunctionSamples *findFunctionSamples(
+ const DILocation *DIL,
+ SampleProfileReaderItaniumRemapper *Remapper = nullptr) const;
+
+ static bool ProfileIsProbeBased;
+
+ static bool ProfileIsCS;
+
+ SampleContext &getContext() const { return Context; }
+
+ void setContext(const SampleContext &FContext) { Context = FContext; }
+
static SampleProfileFormat Format;
/// Whether the profile uses MD5 to represent string.
@@ -876,20 +876,20 @@ public:
return UseMD5 ? std::stoull(Name.data()) : Function::getGUID(Name);
}
- // Find all the names in the current FunctionSamples including names in
- // all the inline instances and names of call targets.
- void findAllNames(DenseSet<StringRef> &NameSet) const;
-
+ // Find all the names in the current FunctionSamples including names in
+ // all the inline instances and names of call targets.
+ void findAllNames(DenseSet<StringRef> &NameSet) const;
+
private:
/// Mangled name of the function.
StringRef Name;
- /// CFG hash value for the function.
- uint64_t FunctionHash = 0;
-
- /// Calling context for function profile
- mutable SampleContext Context;
-
+ /// CFG hash value for the function.
+ uint64_t FunctionHash = 0;
+
+ /// Calling context for function profile
+ mutable SampleContext Context;
+
/// Total number of samples collected inside this function.
///
/// Samples are cumulative, they include all the samples collected
diff --git a/contrib/libs/llvm12/include/llvm/ProfileData/SampleProfReader.h b/contrib/libs/llvm12/include/llvm/ProfileData/SampleProfReader.h
index 62cca31d48..7cece5e376 100644
--- a/contrib/libs/llvm12/include/llvm/ProfileData/SampleProfReader.h
+++ b/contrib/libs/llvm12/include/llvm/ProfileData/SampleProfReader.h
@@ -34,9 +34,9 @@
// offsetA[.discriminator]: fnA:num_of_total_samples
// offsetA1[.discriminator]: number_of_samples [fn7:num fn8:num ... ]
// ...
-// !CFGChecksum: num
+// !CFGChecksum: num
//
-// This is a nested tree in which the indentation represents the nesting level
+// This is a nested tree in which the indentation represents the nesting level
// of the inline stack. There are no blank lines in the file. And the spacing
// within a single line is fixed. Additional spaces will result in an error
// while reading the file.
@@ -55,11 +55,11 @@
// in the prologue of the function (second number). This head sample
// count provides an indicator of how frequently the function is invoked.
//
-// There are three types of lines in the function body.
+// There are three types of lines in the function body.
//
// * Sampled line represents the profile information of a source location.
// * Callsite line represents the profile information of a callsite.
-// * Metadata line represents extra metadata of the function.
+// * Metadata line represents extra metadata of the function.
//
// Each sampled line may contain several items. Some are optional (marked
// below):
@@ -123,19 +123,19 @@
// total number of samples collected for the inlined instance at this
// callsite
//
-// Metadata line can occur in lines with one indent only, containing extra
-// information for the top-level function. Furthermore, metadata can only
-// occur after all the body samples and callsite samples.
-// Each metadata line may contain a particular type of metadata, marked by
-// the starting characters annotated with !. We process each metadata line
-// independently, hence each metadata line has to form an independent piece
-// of information that does not require cross-line reference.
-// We support the following types of metadata:
-//
-// a. CFG Checksum (a.k.a. function hash):
-// !CFGChecksum: 12345
-//
-//
+// Metadata line can occur in lines with one indent only, containing extra
+// information for the top-level function. Furthermore, metadata can only
+// occur after all the body samples and callsite samples.
+// Each metadata line may contain a particular type of metadata, marked by
+// the starting characters annotated with !. We process each metadata line
+// independently, hence each metadata line has to form an independent piece
+// of information that does not require cross-line reference.
+// We support the following types of metadata:
+//
+// a. CFG Checksum (a.k.a. function hash):
+// !CFGChecksum: 12345
+//
+//
// Binary format
// -------------
//
@@ -229,7 +229,7 @@
#ifndef LLVM_PROFILEDATA_SAMPLEPROFREADER_H
#define LLVM_PROFILEDATA_SAMPLEPROFREADER_H
-#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
@@ -253,7 +253,7 @@
namespace llvm {
class raw_ostream;
-class Twine;
+class Twine;
namespace sampleprof {
@@ -297,18 +297,18 @@ public:
return Remappings->lookup(FunctionName);
}
- /// Return the equivalent name in the profile for \p FunctionName if
- /// it exists.
- Optional<StringRef> lookUpNameInProfile(StringRef FunctionName);
+ /// Return the equivalent name in the profile for \p FunctionName if
+ /// it exists.
+ Optional<StringRef> lookUpNameInProfile(StringRef FunctionName);
private:
// The buffer holding the content read from remapping file.
std::unique_ptr<MemoryBuffer> Buffer;
std::unique_ptr<SymbolRemappingReader> Remappings;
- // Map remapping key to the name in the profile. By looking up the
- // key in the remapper, a given new name can be mapped to the
- // cannonical name using the NameMap.
- DenseMap<SymbolRemappingReader::Key, StringRef> NameMap;
+ // Map remapping key to the name in the profile. By looking up the
+ // key in the remapper, a given new name can be mapped to the
+ // cannonical name using the NameMap.
+ DenseMap<SymbolRemappingReader::Key, StringRef> NameMap;
// The Reader the remapper is servicing.
SampleProfileReader &Reader;
// Indicate whether remapping has been applied to the profile read
@@ -400,14 +400,14 @@ public:
auto It = Profiles.find(Fname);
if (It != Profiles.end())
return &It->second;
-
- if (Remapper) {
- if (auto NameInProfile = Remapper->lookUpNameInProfile(Fname)) {
- auto It = Profiles.find(*NameInProfile);
- if (It != Profiles.end())
- return &It->second;
- }
- }
+
+ if (Remapper) {
+ if (auto NameInProfile = Remapper->lookUpNameInProfile(Fname)) {
+ auto It = Profiles.find(*NameInProfile);
+ if (It != Profiles.end())
+ return &It->second;
+ }
+ }
return nullptr;
}
@@ -415,7 +415,7 @@ public:
StringMap<FunctionSamples> &getProfiles() { return Profiles; }
/// Report a parse error message.
- void reportError(int64_t LineNumber, const Twine &Msg) const {
+ void reportError(int64_t LineNumber, const Twine &Msg) const {
Ctx.diagnose(DiagnosticInfoSampleProfile(Buffer->getBufferIdentifier(),
LineNumber, Msg));
}
@@ -440,12 +440,12 @@ public:
/// \brief Return the profile format.
SampleProfileFormat getFormat() const { return Format; }
- /// Whether input profile is based on pseudo probes.
- bool profileIsProbeBased() const { return ProfileIsProbeBased; }
-
- /// Whether input profile is fully context-sensitive
- bool profileIsCS() const { return ProfileIsCS; }
-
+ /// Whether input profile is based on pseudo probes.
+ bool profileIsProbeBased() const { return ProfileIsProbeBased; }
+
+ /// Whether input profile is fully context-sensitive
+ bool profileIsCS() const { return ProfileIsCS; }
+
virtual std::unique_ptr<ProfileSymbolList> getProfileSymbolList() {
return nullptr;
};
@@ -458,12 +458,12 @@ public:
/// Return whether names in the profile are all MD5 numbers.
virtual bool useMD5() { return false; }
- /// Don't read profile without context if the flag is set. This is only meaningful
- /// for ExtBinary format.
- virtual void setSkipFlatProf(bool Skip) {}
-
- SampleProfileReaderItaniumRemapper *getRemapper() { return Remapper.get(); }
-
+ /// Don't read profile without context if the flag is set. This is only meaningful
+ /// for ExtBinary format.
+ virtual void setSkipFlatProf(bool Skip) {}
+
+ SampleProfileReaderItaniumRemapper *getRemapper() { return Remapper.get(); }
+
protected:
/// Map every function to its associated profile.
///
@@ -492,15 +492,15 @@ protected:
std::unique_ptr<SampleProfileReaderItaniumRemapper> Remapper;
- /// \brief Whether samples are collected based on pseudo probes.
- bool ProfileIsProbeBased = false;
-
- /// Whether function profiles are context-sensitive.
- bool ProfileIsCS = false;
-
- /// Number of context-sensitive profiles.
- uint32_t CSProfileCount = 0;
-
+ /// \brief Whether samples are collected based on pseudo probes.
+ bool ProfileIsProbeBased = false;
+
+ /// Whether function profiles are context-sensitive.
+ bool ProfileIsCS = false;
+
+ /// Number of context-sensitive profiles.
+ uint32_t CSProfileCount = 0;
+
/// \brief The format of sample.
SampleProfileFormat Format = SPF_None;
};
@@ -638,26 +638,26 @@ private:
protected:
std::vector<SecHdrTableEntry> SecHdrTable;
- std::error_code readSecHdrTableEntry(uint32_t Idx);
+ std::error_code readSecHdrTableEntry(uint32_t Idx);
std::error_code readSecHdrTable();
- std::error_code readFuncMetadata();
+ std::error_code readFuncMetadata();
std::error_code readFuncOffsetTable();
std::error_code readFuncProfiles();
std::error_code readMD5NameTable();
std::error_code readNameTableSec(bool IsMD5);
- std::error_code readProfileSymbolList();
-
- virtual std::error_code readHeader() override;
- virtual std::error_code verifySPMagic(uint64_t Magic) override = 0;
- virtual std::error_code readOneSection(const uint8_t *Start, uint64_t Size,
- const SecHdrTableEntry &Entry);
- // placeholder for subclasses to dispatch their own section readers.
- virtual std::error_code readCustomSection(const SecHdrTableEntry &Entry) = 0;
- virtual ErrorOr<StringRef> readStringFromTable() override;
-
- std::unique_ptr<ProfileSymbolList> ProfSymList;
-
+ std::error_code readProfileSymbolList();
+
+ virtual std::error_code readHeader() override;
+ virtual std::error_code verifySPMagic(uint64_t Magic) override = 0;
+ virtual std::error_code readOneSection(const uint8_t *Start, uint64_t Size,
+ const SecHdrTableEntry &Entry);
+ // placeholder for subclasses to dispatch their own section readers.
+ virtual std::error_code readCustomSection(const SecHdrTableEntry &Entry) = 0;
+ virtual ErrorOr<StringRef> readStringFromTable() override;
+
+ std::unique_ptr<ProfileSymbolList> ProfSymList;
+
/// The table mapping from function name to the offset of its FunctionSample
/// towards file start.
DenseMap<StringRef, uint64_t> FuncOffsetTable;
@@ -666,12 +666,12 @@ protected:
/// Use all functions from the input profile.
bool UseAllFuncs = true;
- /// Use fixed length MD5 instead of ULEB128 encoding so NameTable doesn't
- /// need to be read in up front and can be directly accessed using index.
- bool FixedLengthMD5 = false;
- /// The starting address of NameTable containing fixed length MD5.
- const uint8_t *MD5NameMemStart = nullptr;
-
+ /// Use fixed length MD5 instead of ULEB128 encoding so NameTable doesn't
+ /// need to be read in up front and can be directly accessed using index.
+ bool FixedLengthMD5 = false;
+ /// The starting address of NameTable containing fixed length MD5.
+ const uint8_t *MD5NameMemStart = nullptr;
+
/// If MD5 is used in NameTable section, the section saves uint64_t data.
/// The uint64_t data has to be converted to a string and then the string
/// will be used to initialize StringRef in NameTable.
@@ -681,54 +681,54 @@ protected:
/// the lifetime of MD5StringBuf is not shorter than that of NameTable.
std::unique_ptr<std::vector<std::string>> MD5StringBuf;
- /// If SkipFlatProf is true, skip the sections with
- /// SecFlagFlat flag.
- bool SkipFlatProf = false;
-
+ /// If SkipFlatProf is true, skip the sections with
+ /// SecFlagFlat flag.
+ bool SkipFlatProf = false;
+
public:
- SampleProfileReaderExtBinaryBase(std::unique_ptr<MemoryBuffer> B,
- LLVMContext &C, SampleProfileFormat Format)
- : SampleProfileReaderBinary(std::move(B), C, Format) {}
+ SampleProfileReaderExtBinaryBase(std::unique_ptr<MemoryBuffer> B,
+ LLVMContext &C, SampleProfileFormat Format)
+ : SampleProfileReaderBinary(std::move(B), C, Format) {}
- /// Read sample profiles in extensible format from the associated file.
- std::error_code readImpl() override;
+ /// Read sample profiles in extensible format from the associated file.
+ std::error_code readImpl() override;
- /// Get the total size of all \p Type sections.
- uint64_t getSectionSize(SecType Type);
- /// Get the total size of header and all sections.
- uint64_t getFileSize();
- virtual bool dumpSectionInfo(raw_ostream &OS = dbgs()) override;
+ /// Get the total size of all \p Type sections.
+ uint64_t getSectionSize(SecType Type);
+ /// Get the total size of header and all sections.
+ uint64_t getFileSize();
+ virtual bool dumpSectionInfo(raw_ostream &OS = dbgs()) override;
/// Collect functions with definitions in Module \p M.
void collectFuncsFrom(const Module &M) override;
/// Return whether names in the profile are all MD5 numbers.
- virtual bool useMD5() override { return MD5StringBuf.get(); }
-
- virtual std::unique_ptr<ProfileSymbolList> getProfileSymbolList() override {
- return std::move(ProfSymList);
- };
-
- virtual void setSkipFlatProf(bool Skip) override { SkipFlatProf = Skip; }
+ virtual bool useMD5() override { return MD5StringBuf.get(); }
+
+ virtual std::unique_ptr<ProfileSymbolList> getProfileSymbolList() override {
+ return std::move(ProfSymList);
+ };
+
+ virtual void setSkipFlatProf(bool Skip) override { SkipFlatProf = Skip; }
+};
+
+class SampleProfileReaderExtBinary : public SampleProfileReaderExtBinaryBase {
+private:
+ virtual std::error_code verifySPMagic(uint64_t Magic) override;
+ virtual std::error_code
+ readCustomSection(const SecHdrTableEntry &Entry) override {
+ return sampleprof_error::success;
+ };
+
+public:
+ SampleProfileReaderExtBinary(std::unique_ptr<MemoryBuffer> B, LLVMContext &C,
+ SampleProfileFormat Format = SPF_Ext_Binary)
+ : SampleProfileReaderExtBinaryBase(std::move(B), C, Format) {}
+
+ /// \brief Return true if \p Buffer is in the format supported by this class.
+ static bool hasFormat(const MemoryBuffer &Buffer);
};
-class SampleProfileReaderExtBinary : public SampleProfileReaderExtBinaryBase {
-private:
- virtual std::error_code verifySPMagic(uint64_t Magic) override;
- virtual std::error_code
- readCustomSection(const SecHdrTableEntry &Entry) override {
- return sampleprof_error::success;
- };
-
-public:
- SampleProfileReaderExtBinary(std::unique_ptr<MemoryBuffer> B, LLVMContext &C,
- SampleProfileFormat Format = SPF_Ext_Binary)
- : SampleProfileReaderExtBinaryBase(std::move(B), C, Format) {}
-
- /// \brief Return true if \p Buffer is in the format supported by this class.
- static bool hasFormat(const MemoryBuffer &Buffer);
-};
-
class SampleProfileReaderCompactBinary : public SampleProfileReaderBinary {
private:
/// Function name table.
diff --git a/contrib/libs/llvm12/include/llvm/ProfileData/SampleProfWriter.h b/contrib/libs/llvm12/include/llvm/ProfileData/SampleProfWriter.h
index e00c52f1d9..ad64621ae7 100644
--- a/contrib/libs/llvm12/include/llvm/ProfileData/SampleProfWriter.h
+++ b/contrib/libs/llvm12/include/llvm/ProfileData/SampleProfWriter.h
@@ -22,7 +22,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/IR/ProfileSummary.h"
#include "llvm/ProfileData/SampleProf.h"
#include "llvm/Support/ErrorOr.h"
@@ -36,15 +36,15 @@
namespace llvm {
namespace sampleprof {
-enum SectionLayout {
- DefaultLayout,
- // The layout splits profile with context information from profile without
- // context information. When Thinlto is enabled, ThinLTO postlink phase only
- // has to load profile with context information and can skip the other part.
- CtxSplitLayout,
- NumOfLayout,
-};
-
+enum SectionLayout {
+ DefaultLayout,
+ // The layout splits profile with context information from profile without
+ // context information. When Thinlto is enabled, ThinLTO postlink phase only
+ // has to load profile with context information and can skip the other part.
+ CtxSplitLayout,
+ NumOfLayout,
+};
+
/// Sample-based profile writer. Base class.
class SampleProfileWriter {
public:
@@ -77,7 +77,7 @@ public:
virtual void setToCompressAllSections() {}
virtual void setUseMD5() {}
virtual void setPartialProfile() {}
- virtual void resetSecLayout(SectionLayout SL) {}
+ virtual void resetSecLayout(SectionLayout SL) {}
protected:
SampleProfileWriter(std::unique_ptr<raw_ostream> &OS)
@@ -162,36 +162,36 @@ class SampleProfileWriterRawBinary : public SampleProfileWriterBinary {
using SampleProfileWriterBinary::SampleProfileWriterBinary;
};
-const std::array<SmallVector<SecHdrTableEntry, 8>, NumOfLayout>
- ExtBinaryHdrLayoutTable = {
- // Note that SecFuncOffsetTable section is written after SecLBRProfile
- // in the profile, but is put before SecLBRProfile in SectionHdrLayout.
- // This is because sample reader follows the order in SectionHdrLayout
- // to read each section. To read function profiles on demand, sample
- // reader need to get the offset of each function profile first.
- //
- // DefaultLayout
- SmallVector<SecHdrTableEntry, 8>({{SecProfSummary, 0, 0, 0, 0},
- {SecNameTable, 0, 0, 0, 0},
- {SecFuncOffsetTable, 0, 0, 0, 0},
- {SecLBRProfile, 0, 0, 0, 0},
- {SecProfileSymbolList, 0, 0, 0, 0},
- {SecFuncMetadata, 0, 0, 0, 0}}),
- // CtxSplitLayout
- SmallVector<SecHdrTableEntry, 8>({{SecProfSummary, 0, 0, 0, 0},
- {SecNameTable, 0, 0, 0, 0},
- // profile with context
- // for next two sections
- {SecFuncOffsetTable, 0, 0, 0, 0},
- {SecLBRProfile, 0, 0, 0, 0},
- // profile without context
- // for next two sections
- {SecFuncOffsetTable, 0, 0, 0, 0},
- {SecLBRProfile, 0, 0, 0, 0},
- {SecProfileSymbolList, 0, 0, 0, 0},
- {SecFuncMetadata, 0, 0, 0, 0}}),
-};
-
+const std::array<SmallVector<SecHdrTableEntry, 8>, NumOfLayout>
+ ExtBinaryHdrLayoutTable = {
+ // Note that SecFuncOffsetTable section is written after SecLBRProfile
+ // in the profile, but is put before SecLBRProfile in SectionHdrLayout.
+ // This is because sample reader follows the order in SectionHdrLayout
+ // to read each section. To read function profiles on demand, sample
+ // reader need to get the offset of each function profile first.
+ //
+ // DefaultLayout
+ SmallVector<SecHdrTableEntry, 8>({{SecProfSummary, 0, 0, 0, 0},
+ {SecNameTable, 0, 0, 0, 0},
+ {SecFuncOffsetTable, 0, 0, 0, 0},
+ {SecLBRProfile, 0, 0, 0, 0},
+ {SecProfileSymbolList, 0, 0, 0, 0},
+ {SecFuncMetadata, 0, 0, 0, 0}}),
+ // CtxSplitLayout
+ SmallVector<SecHdrTableEntry, 8>({{SecProfSummary, 0, 0, 0, 0},
+ {SecNameTable, 0, 0, 0, 0},
+ // profile with context
+ // for next two sections
+ {SecFuncOffsetTable, 0, 0, 0, 0},
+ {SecLBRProfile, 0, 0, 0, 0},
+ // profile without context
+ // for next two sections
+ {SecFuncOffsetTable, 0, 0, 0, 0},
+ {SecLBRProfile, 0, 0, 0, 0},
+ {SecProfileSymbolList, 0, 0, 0, 0},
+ {SecFuncMetadata, 0, 0, 0, 0}}),
+};
+
class SampleProfileWriterExtBinaryBase : public SampleProfileWriterBinary {
using SampleProfileWriterBinary::SampleProfileWriterBinary;
public:
@@ -200,45 +200,45 @@ public:
virtual void setToCompressAllSections() override;
void setToCompressSection(SecType Type);
- virtual std::error_code writeSample(const FunctionSamples &S) override;
-
- // Set to use MD5 to represent string in NameTable.
- virtual void setUseMD5() override {
- UseMD5 = true;
- addSectionFlag(SecNameTable, SecNameTableFlags::SecFlagMD5Name);
- // MD5 will be stored as plain uint64_t instead of variable-length
- // quantity format in NameTable section.
- addSectionFlag(SecNameTable, SecNameTableFlags::SecFlagFixedLengthMD5);
- }
-
- // Set the profile to be partial. It means the profile is for
- // common/shared code. The common profile is usually merged from
- // profiles collected from running other targets.
- virtual void setPartialProfile() override {
- addSectionFlag(SecProfSummary, SecProfSummaryFlags::SecFlagPartial);
- }
-
- virtual void setProfileSymbolList(ProfileSymbolList *PSL) override {
- ProfSymList = PSL;
- };
-
- virtual void resetSecLayout(SectionLayout SL) override {
- verifySecLayout(SL);
-#ifndef NDEBUG
- // Make sure resetSecLayout is called before any flag setting.
- for (auto &Entry : SectionHdrLayout) {
- assert(Entry.Flags == 0 &&
- "resetSecLayout has to be called before any flag setting");
- }
-#endif
- SecLayout = SL;
- SectionHdrLayout = ExtBinaryHdrLayoutTable[SL];
- }
-
+ virtual std::error_code writeSample(const FunctionSamples &S) override;
+
+ // Set to use MD5 to represent string in NameTable.
+ virtual void setUseMD5() override {
+ UseMD5 = true;
+ addSectionFlag(SecNameTable, SecNameTableFlags::SecFlagMD5Name);
+ // MD5 will be stored as plain uint64_t instead of variable-length
+ // quantity format in NameTable section.
+ addSectionFlag(SecNameTable, SecNameTableFlags::SecFlagFixedLengthMD5);
+ }
+
+ // Set the profile to be partial. It means the profile is for
+ // common/shared code. The common profile is usually merged from
+ // profiles collected from running other targets.
+ virtual void setPartialProfile() override {
+ addSectionFlag(SecProfSummary, SecProfSummaryFlags::SecFlagPartial);
+ }
+
+ virtual void setProfileSymbolList(ProfileSymbolList *PSL) override {
+ ProfSymList = PSL;
+ };
+
+ virtual void resetSecLayout(SectionLayout SL) override {
+ verifySecLayout(SL);
+#ifndef NDEBUG
+ // Make sure resetSecLayout is called before any flag setting.
+ for (auto &Entry : SectionHdrLayout) {
+ assert(Entry.Flags == 0 &&
+ "resetSecLayout has to be called before any flag setting");
+ }
+#endif
+ SecLayout = SL;
+ SectionHdrLayout = ExtBinaryHdrLayoutTable[SL];
+ }
+
protected:
- uint64_t markSectionStart(SecType Type, uint32_t LayoutIdx);
- std::error_code addNewSection(SecType Sec, uint32_t LayoutIdx,
- uint64_t SectionStart);
+ uint64_t markSectionStart(SecType Type, uint32_t LayoutIdx);
+ std::error_code addNewSection(SecType Sec, uint32_t LayoutIdx,
+ uint64_t SectionStart);
template <class SecFlagType>
void addSectionFlag(SecType Type, SecFlagType Flag) {
for (auto &Entry : SectionHdrLayout) {
@@ -246,50 +246,50 @@ protected:
addSecFlag(Entry, Flag);
}
}
- template <class SecFlagType>
- void addSectionFlag(uint32_t SectionIdx, SecFlagType Flag) {
- addSecFlag(SectionHdrLayout[SectionIdx], Flag);
- }
-
- // placeholder for subclasses to dispatch their own section writers.
- virtual std::error_code writeCustomSection(SecType Type) = 0;
- // Verify the SecLayout is supported by the format.
- virtual void verifySecLayout(SectionLayout SL) = 0;
-
- // specify the order to write sections.
+ template <class SecFlagType>
+ void addSectionFlag(uint32_t SectionIdx, SecFlagType Flag) {
+ addSecFlag(SectionHdrLayout[SectionIdx], Flag);
+ }
+
+ // placeholder for subclasses to dispatch their own section writers.
+ virtual std::error_code writeCustomSection(SecType Type) = 0;
+ // Verify the SecLayout is supported by the format.
+ virtual void verifySecLayout(SectionLayout SL) = 0;
+
+ // specify the order to write sections.
virtual std::error_code
writeSections(const StringMap<FunctionSamples> &ProfileMap) = 0;
- // Dispatch section writer for each section. \p LayoutIdx is the sequence
- // number indicating where the section is located in SectionHdrLayout.
- virtual std::error_code
- writeOneSection(SecType Type, uint32_t LayoutIdx,
- const StringMap<FunctionSamples> &ProfileMap);
-
- // Helper function to write name table.
- virtual std::error_code writeNameTable() override;
-
- std::error_code writeFuncMetadata(const StringMap<FunctionSamples> &Profiles);
-
- // Functions to write various kinds of sections.
- std::error_code
- writeNameTableSection(const StringMap<FunctionSamples> &ProfileMap);
- std::error_code writeFuncOffsetTable();
- std::error_code writeProfileSymbolListSection();
-
- SectionLayout SecLayout = DefaultLayout;
+ // Dispatch section writer for each section. \p LayoutIdx is the sequence
+ // number indicating where the section is located in SectionHdrLayout.
+ virtual std::error_code
+ writeOneSection(SecType Type, uint32_t LayoutIdx,
+ const StringMap<FunctionSamples> &ProfileMap);
+
+ // Helper function to write name table.
+ virtual std::error_code writeNameTable() override;
+
+ std::error_code writeFuncMetadata(const StringMap<FunctionSamples> &Profiles);
+
+ // Functions to write various kinds of sections.
+ std::error_code
+ writeNameTableSection(const StringMap<FunctionSamples> &ProfileMap);
+ std::error_code writeFuncOffsetTable();
+ std::error_code writeProfileSymbolListSection();
+
+ SectionLayout SecLayout = DefaultLayout;
// Specifiy the order of sections in section header table. Note
- // the order of sections in SecHdrTable may be different that the
+ // the order of sections in SecHdrTable may be different that the
// order in SectionHdrLayout. sample Reader will follow the order
// in SectionHdrLayout to read each section.
- SmallVector<SecHdrTableEntry, 8> SectionHdrLayout =
- ExtBinaryHdrLayoutTable[DefaultLayout];
-
- // Save the start of SecLBRProfile so we can compute the offset to the
- // start of SecLBRProfile for each Function's Profile and will keep it
- // in FuncOffsetTable.
- uint64_t SecLBRProfileStart = 0;
-
+ SmallVector<SecHdrTableEntry, 8> SectionHdrLayout =
+ ExtBinaryHdrLayoutTable[DefaultLayout];
+
+ // Save the start of SecLBRProfile so we can compute the offset to the
+ // start of SecLBRProfile for each Function's Profile and will keep it
+ // in FuncOffsetTable.
+ uint64_t SecLBRProfileStart = 0;
+
private:
void allocSecHdrTable();
std::error_code writeSecHdrTable();
@@ -311,43 +311,43 @@ private:
// The location in the output stream where the SecHdrTable should be
// written to.
uint64_t SecHdrTableOffset;
- // The table contains SecHdrTableEntry entries in order of how they are
- // populated in the writer. It may be different from the order in
- // SectionHdrLayout which specifies the sequence in which sections will
- // be read.
+ // The table contains SecHdrTableEntry entries in order of how they are
+ // populated in the writer. It may be different from the order in
+ // SectionHdrLayout which specifies the sequence in which sections will
+ // be read.
std::vector<SecHdrTableEntry> SecHdrTable;
-
- // FuncOffsetTable maps function name to its profile offset in SecLBRProfile
- // section. It is used to load function profile on demand.
- MapVector<StringRef, uint64_t> FuncOffsetTable;
- // Whether to use MD5 to represent string.
- bool UseMD5 = false;
-
- ProfileSymbolList *ProfSymList = nullptr;
+
+ // FuncOffsetTable maps function name to its profile offset in SecLBRProfile
+ // section. It is used to load function profile on demand.
+ MapVector<StringRef, uint64_t> FuncOffsetTable;
+ // Whether to use MD5 to represent string.
+ bool UseMD5 = false;
+
+ ProfileSymbolList *ProfSymList = nullptr;
};
class SampleProfileWriterExtBinary : public SampleProfileWriterExtBinaryBase {
public:
SampleProfileWriterExtBinary(std::unique_ptr<raw_ostream> &OS)
- : SampleProfileWriterExtBinaryBase(OS) {}
+ : SampleProfileWriterExtBinaryBase(OS) {}
-private:
- std::error_code
- writeDefaultLayout(const StringMap<FunctionSamples> &ProfileMap);
- std::error_code
- writeCtxSplitLayout(const StringMap<FunctionSamples> &ProfileMap);
+private:
+ std::error_code
+ writeDefaultLayout(const StringMap<FunctionSamples> &ProfileMap);
+ std::error_code
+ writeCtxSplitLayout(const StringMap<FunctionSamples> &ProfileMap);
virtual std::error_code
writeSections(const StringMap<FunctionSamples> &ProfileMap) override;
- virtual std::error_code writeCustomSection(SecType Type) override {
- return sampleprof_error::success;
- };
+ virtual std::error_code writeCustomSection(SecType Type) override {
+ return sampleprof_error::success;
+ };
- virtual void verifySecLayout(SectionLayout SL) override {
- assert((SL == DefaultLayout || SL == CtxSplitLayout) &&
- "Unsupported layout");
- }
+ virtual void verifySecLayout(SectionLayout SL) override {
+ assert((SL == DefaultLayout || SL == CtxSplitLayout) &&
+ "Unsupported layout");
+ }
};
// CompactBinary is a compact format of binary profile which both reduces
diff --git a/contrib/libs/llvm12/include/llvm/Remarks/BitstreamRemarkParser.h b/contrib/libs/llvm12/include/llvm/Remarks/BitstreamRemarkParser.h
index 1b5c8ee83b..cd9945a2e2 100644
--- a/contrib/libs/llvm12/include/llvm/Remarks/BitstreamRemarkParser.h
+++ b/contrib/libs/llvm12/include/llvm/Remarks/BitstreamRemarkParser.h
@@ -21,13 +21,13 @@
#ifndef LLVM_REMARKS_BITSTREAM_REMARK_PARSER_H
#define LLVM_REMARKS_BITSTREAM_REMARK_PARSER_H
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Bitstream/BitstreamReader.h"
#include "llvm/Support/Error.h"
#include <array>
-#include <cstdint>
+#include <cstdint>
namespace llvm {
namespace remarks {
diff --git a/contrib/libs/llvm12/include/llvm/Remarks/HotnessThresholdParser.h b/contrib/libs/llvm12/include/llvm/Remarks/HotnessThresholdParser.h
index 40784040b7..1d53f5eea5 100644
--- a/contrib/libs/llvm12/include/llvm/Remarks/HotnessThresholdParser.h
+++ b/contrib/libs/llvm12/include/llvm/Remarks/HotnessThresholdParser.h
@@ -1,74 +1,74 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- HotnessThresholdParser.h - Parser for hotness threshold --*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This file implements a simple parser to decode commandline option for
-/// remarks hotness threshold that supports both int and a special 'auto' value.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_REMARKS_HOTNESSTHRESHOLDPARSER_H
-#define LLVM_REMARKS_HOTNESSTHRESHOLDPARSER_H
-
-#include "llvm/ADT/Optional.h"
-#include "llvm/Support/CommandLine.h"
-
-namespace llvm {
-namespace remarks {
-
-// Parse remarks hotness threshold argument value.
-// Valid option values are
-// 1. integer: manually specified threshold; or
-// 2. string 'auto': automatically get threshold from profile summary.
-//
-// Return None Optional if 'auto' is specified, indicating the value will
-// be filled later during PSI.
-inline Expected<Optional<uint64_t>> parseHotnessThresholdOption(StringRef Arg) {
- if (Arg == "auto")
- return None;
-
- int64_t Val;
- if (Arg.getAsInteger(10, Val))
- return createStringError(llvm::inconvertibleErrorCode(),
- "Not an integer: %s", Arg.data());
-
- // Negative integer effectively means no threshold
- return Val < 0 ? 0 : Val;
-}
-
-// A simple CL parser for '*-remarks-hotness-threshold='
-class HotnessThresholdParser : public cl::parser<Optional<uint64_t>> {
-public:
- HotnessThresholdParser(cl::Option &O) : cl::parser<Optional<uint64_t>>(O) {}
-
- bool parse(cl::Option &O, StringRef ArgName, StringRef Arg,
- Optional<uint64_t> &V) {
- auto ResultOrErr = parseHotnessThresholdOption(Arg);
- if (!ResultOrErr)
- return O.error("Invalid argument '" + Arg +
- "', only integer or 'auto' is supported.");
-
- V = *ResultOrErr;
- return false;
- }
-};
-
-} // namespace remarks
-} // namespace llvm
-#endif // LLVM_REMARKS_HOTNESSTHRESHOLDPARSER_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- HotnessThresholdParser.h - Parser for hotness threshold --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements a simple parser to decode commandline option for
+/// remarks hotness threshold that supports both int and a special 'auto' value.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_REMARKS_HOTNESSTHRESHOLDPARSER_H
+#define LLVM_REMARKS_HOTNESSTHRESHOLDPARSER_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/CommandLine.h"
+
+namespace llvm {
+namespace remarks {
+
+// Parse remarks hotness threshold argument value.
+// Valid option values are
+// 1. integer: manually specified threshold; or
+// 2. string 'auto': automatically get threshold from profile summary.
+//
+// Return None Optional if 'auto' is specified, indicating the value will
+// be filled later during PSI.
+inline Expected<Optional<uint64_t>> parseHotnessThresholdOption(StringRef Arg) {
+ if (Arg == "auto")
+ return None;
+
+ int64_t Val;
+ if (Arg.getAsInteger(10, Val))
+ return createStringError(llvm::inconvertibleErrorCode(),
+ "Not an integer: %s", Arg.data());
+
+ // Negative integer effectively means no threshold
+ return Val < 0 ? 0 : Val;
+}
+
+// A simple CL parser for '*-remarks-hotness-threshold='
+class HotnessThresholdParser : public cl::parser<Optional<uint64_t>> {
+public:
+ HotnessThresholdParser(cl::Option &O) : cl::parser<Optional<uint64_t>>(O) {}
+
+ bool parse(cl::Option &O, StringRef ArgName, StringRef Arg,
+ Optional<uint64_t> &V) {
+ auto ResultOrErr = parseHotnessThresholdOption(Arg);
+ if (!ResultOrErr)
+ return O.error("Invalid argument '" + Arg +
+ "', only integer or 'auto' is supported.");
+
+ V = *ResultOrErr;
+ return false;
+ }
+};
+
+} // namespace remarks
+} // namespace llvm
+#endif // LLVM_REMARKS_HOTNESSTHRESHOLDPARSER_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Support/AArch64TargetParser.def b/contrib/libs/llvm12/include/llvm/Support/AArch64TargetParser.def
index cd4762a6ec..332fb555e8 100644
--- a/contrib/libs/llvm12/include/llvm/Support/AArch64TargetParser.def
+++ b/contrib/libs/llvm12/include/llvm/Support/AArch64TargetParser.def
@@ -51,21 +51,21 @@ AARCH64_ARCH("armv8.6-a", ARMV8_6A, "8.6-A", "v8.6a",
AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
AArch64::AEK_SM4 | AArch64::AEK_SHA3 | AArch64::AEK_BF16 |
AArch64::AEK_SHA2 | AArch64::AEK_AES | AArch64::AEK_I8MM))
-AARCH64_ARCH("armv8.7-a", ARMV8_7A, "8.7-A", "v8.7a",
- ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8,
- (AArch64::AEK_CRC | AArch64::AEK_FP |
- AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
- AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
- AArch64::AEK_SM4 | AArch64::AEK_SHA3 | AArch64::AEK_BF16 |
- AArch64::AEK_SHA2 | AArch64::AEK_AES | AArch64::AEK_I8MM))
-// For v8-R, we do not enable crypto and align with GCC that enables a more
-// minimal set of optional architecture extensions.
-AARCH64_ARCH("armv8-r", ARMV8R, "8-R", "v8r",
- ARMBuildAttrs::CPUArch::v8_R, FK_CRYPTO_NEON_FP_ARMV8,
- (AArch64::AEK_CRC | AArch64::AEK_RDM | AArch64::AEK_SSBS |
- AArch64::AEK_DOTPROD | AArch64::AEK_FP | AArch64::AEK_SIMD |
- AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_RAS |
- AArch64::AEK_RCPC | AArch64::AEK_SB))
+AARCH64_ARCH("armv8.7-a", ARMV8_7A, "8.7-A", "v8.7a",
+ ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8,
+ (AArch64::AEK_CRC | AArch64::AEK_FP |
+ AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
+ AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
+ AArch64::AEK_SM4 | AArch64::AEK_SHA3 | AArch64::AEK_BF16 |
+ AArch64::AEK_SHA2 | AArch64::AEK_AES | AArch64::AEK_I8MM))
+// For v8-R, we do not enable crypto and align with GCC that enables a more
+// minimal set of optional architecture extensions.
+AARCH64_ARCH("armv8-r", ARMV8R, "8-R", "v8r",
+ ARMBuildAttrs::CPUArch::v8_R, FK_CRYPTO_NEON_FP_ARMV8,
+ (AArch64::AEK_CRC | AArch64::AEK_RDM | AArch64::AEK_SSBS |
+ AArch64::AEK_DOTPROD | AArch64::AEK_FP | AArch64::AEK_SIMD |
+ AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_RAS |
+ AArch64::AEK_RCPC | AArch64::AEK_SB))
#undef AARCH64_ARCH
#ifndef AARCH64_ARCH_EXT_NAME
@@ -106,10 +106,10 @@ AARCH64_ARCH_EXT_NAME("i8mm", AArch64::AEK_I8MM, "+i8mm", "-i8mm
AARCH64_ARCH_EXT_NAME("f32mm", AArch64::AEK_F32MM, "+f32mm", "-f32mm")
AARCH64_ARCH_EXT_NAME("f64mm", AArch64::AEK_F64MM, "+f64mm", "-f64mm")
AARCH64_ARCH_EXT_NAME("tme", AArch64::AEK_TME, "+tme", "-tme")
-AARCH64_ARCH_EXT_NAME("ls64", AArch64::AEK_LS64, "+ls64", "-ls64")
-AARCH64_ARCH_EXT_NAME("brbe", AArch64::AEK_BRBE, "+brbe", "-brbe")
-AARCH64_ARCH_EXT_NAME("pauth", AArch64::AEK_PAUTH, "+pauth", "-pauth")
-AARCH64_ARCH_EXT_NAME("flagm", AArch64::AEK_FLAGM, "+flagm", "-flagm")
+AARCH64_ARCH_EXT_NAME("ls64", AArch64::AEK_LS64, "+ls64", "-ls64")
+AARCH64_ARCH_EXT_NAME("brbe", AArch64::AEK_BRBE, "+brbe", "-brbe")
+AARCH64_ARCH_EXT_NAME("pauth", AArch64::AEK_PAUTH, "+pauth", "-pauth")
+AARCH64_ARCH_EXT_NAME("flagm", AArch64::AEK_FLAGM, "+flagm", "-flagm")
#undef AARCH64_ARCH_EXT_NAME
#ifndef AARCH64_CPU_NAME
@@ -149,11 +149,11 @@ AARCH64_CPU_NAME("cortex-a77", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
AARCH64_CPU_NAME("cortex-a78", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC |
AArch64::AEK_SSBS))
-AARCH64_CPU_NAME("cortex-a78c", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
- (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC |
- AArch64::AEK_SSBS))
-AARCH64_CPU_NAME("cortex-r82", ARMV8R, FK_CRYPTO_NEON_FP_ARMV8, false,
- (AArch64::AEK_LSE))
+AARCH64_CPU_NAME("cortex-a78c", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC |
+ AArch64::AEK_SSBS))
+AARCH64_CPU_NAME("cortex-r82", ARMV8R, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_LSE))
AARCH64_CPU_NAME("cortex-x1", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC |
AArch64::AEK_SSBS))
@@ -164,15 +164,15 @@ AARCH64_CPU_NAME("neoverse-n1", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
AArch64::AEK_PROFILE | AArch64::AEK_RAS | AArch64::AEK_RCPC |
AArch64::AEK_SSBS))
-AARCH64_CPU_NAME("neoverse-n2", ARMV8_5A, FK_CRYPTO_NEON_FP_ARMV8, false,
- (AArch64::AEK_BF16 | AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
- AArch64::AEK_I8MM | AArch64::AEK_MTE | AArch64::AEK_RAS |
- AArch64::AEK_RCPC | AArch64::AEK_SB | AArch64::AEK_SSBS |
- AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM))
-AARCH64_CPU_NAME("neoverse-v1", ARMV8_4A, FK_CRYPTO_NEON_FP_ARMV8, false,
- (AArch64::AEK_RAS | AArch64::AEK_SVE | AArch64::AEK_SSBS |
- AArch64::AEK_RCPC | AArch64::AEK_FP16 | AArch64::AEK_BF16 |
- AArch64::AEK_DOTPROD ))
+AARCH64_CPU_NAME("neoverse-n2", ARMV8_5A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_BF16 | AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
+ AArch64::AEK_I8MM | AArch64::AEK_MTE | AArch64::AEK_RAS |
+ AArch64::AEK_RCPC | AArch64::AEK_SB | AArch64::AEK_SSBS |
+ AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM))
+AARCH64_CPU_NAME("neoverse-v1", ARMV8_4A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_RAS | AArch64::AEK_SVE | AArch64::AEK_SSBS |
+ AArch64::AEK_RCPC | AArch64::AEK_FP16 | AArch64::AEK_BF16 |
+ AArch64::AEK_DOTPROD ))
AARCH64_CPU_NAME("cyclone", ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_NONE))
AARCH64_CPU_NAME("apple-a7", ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
@@ -189,8 +189,8 @@ AARCH64_CPU_NAME("apple-a12", ARMV8_3A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_FP16))
AARCH64_CPU_NAME("apple-a13", ARMV8_4A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_FP16 | AArch64::AEK_FP16FML))
-AARCH64_CPU_NAME("apple-a14", ARMV8_5A, FK_CRYPTO_NEON_FP_ARMV8, false,
- (AArch64::AEK_FP16 | AArch64::AEK_FP16FML))
+AARCH64_CPU_NAME("apple-a14", ARMV8_5A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_FP16 | AArch64::AEK_FP16FML))
AARCH64_CPU_NAME("apple-s4", ARMV8_3A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_FP16))
AARCH64_CPU_NAME("apple-s5", ARMV8_3A, FK_CRYPTO_NEON_FP_ARMV8, false,
diff --git a/contrib/libs/llvm12/include/llvm/Support/AArch64TargetParser.h b/contrib/libs/llvm12/include/llvm/Support/AArch64TargetParser.h
index a879cbc60b..3c8ae8b7b8 100644
--- a/contrib/libs/llvm12/include/llvm/Support/AArch64TargetParser.h
+++ b/contrib/libs/llvm12/include/llvm/Support/AArch64TargetParser.h
@@ -69,10 +69,10 @@ enum ArchExtKind : uint64_t {
AEK_I8MM = 1 << 30,
AEK_F32MM = 1ULL << 31,
AEK_F64MM = 1ULL << 32,
- AEK_LS64 = 1ULL << 33,
- AEK_BRBE = 1ULL << 34,
- AEK_PAUTH = 1ULL << 35,
- AEK_FLAGM = 1ULL << 36,
+ AEK_LS64 = 1ULL << 33,
+ AEK_BRBE = 1ULL << 34,
+ AEK_PAUTH = 1ULL << 35,
+ AEK_FLAGM = 1ULL << 36,
};
enum class ArchKind {
@@ -115,7 +115,7 @@ const ArchKind ArchKinds[] = {
};
// FIXME: These should be moved to TargetTuple once it exists
-bool getExtensionFeatures(uint64_t Extensions,
+bool getExtensionFeatures(uint64_t Extensions,
std::vector<StringRef> &Features);
bool getArchFeatures(ArchKind AK, std::vector<StringRef> &Features);
@@ -128,7 +128,7 @@ StringRef getArchExtFeature(StringRef ArchExt);
// Information by Name
unsigned getDefaultFPU(StringRef CPU, ArchKind AK);
-uint64_t getDefaultExtensions(StringRef CPU, ArchKind AK);
+uint64_t getDefaultExtensions(StringRef CPU, ArchKind AK);
StringRef getDefaultCPU(StringRef Arch);
ArchKind getCPUArchKind(StringRef CPU);
diff --git a/contrib/libs/llvm12/include/llvm/Support/AMDGPUMetadata.h b/contrib/libs/llvm12/include/llvm/Support/AMDGPUMetadata.h
index a123dd4a3c..a52236cf0e 100644
--- a/contrib/libs/llvm12/include/llvm/Support/AMDGPUMetadata.h
+++ b/contrib/libs/llvm12/include/llvm/Support/AMDGPUMetadata.h
@@ -22,7 +22,7 @@
#ifndef LLVM_SUPPORT_AMDGPUMETADATA_H
#define LLVM_SUPPORT_AMDGPUMETADATA_H
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringRef.h"
#include <cstdint>
#include <string>
#include <system_error>
@@ -438,7 +438,7 @@ struct Metadata final {
};
/// Converts \p String to \p HSAMetadata.
-std::error_code fromString(StringRef String, Metadata &HSAMetadata);
+std::error_code fromString(StringRef String, Metadata &HSAMetadata);
/// Converts \p HSAMetadata to \p String.
std::error_code toString(Metadata HSAMetadata, std::string &String);
diff --git a/contrib/libs/llvm12/include/llvm/Support/AMDHSAKernelDescriptor.h b/contrib/libs/llvm12/include/llvm/Support/AMDHSAKernelDescriptor.h
index 135b06500f..8e1a6f688b 100644
--- a/contrib/libs/llvm12/include/llvm/Support/AMDHSAKernelDescriptor.h
+++ b/contrib/libs/llvm12/include/llvm/Support/AMDHSAKernelDescriptor.h
@@ -107,7 +107,7 @@ enum : int32_t {
#define COMPUTE_PGM_RSRC2(NAME, SHIFT, WIDTH) \
AMDHSA_BITS_ENUM_ENTRY(COMPUTE_PGM_RSRC2_ ## NAME, SHIFT, WIDTH)
enum : int32_t {
- COMPUTE_PGM_RSRC2(ENABLE_PRIVATE_SEGMENT, 0, 1),
+ COMPUTE_PGM_RSRC2(ENABLE_PRIVATE_SEGMENT, 0, 1),
COMPUTE_PGM_RSRC2(USER_SGPR_COUNT, 1, 5),
COMPUTE_PGM_RSRC2(ENABLE_TRAP_HANDLER, 6, 1),
COMPUTE_PGM_RSRC2(ENABLE_SGPR_WORKGROUP_ID_X, 7, 1),
@@ -169,49 +169,49 @@ struct kernel_descriptor_t {
uint8_t reserved2[6];
};
-enum : uint32_t {
- GROUP_SEGMENT_FIXED_SIZE_OFFSET = 0,
- PRIVATE_SEGMENT_FIXED_SIZE_OFFSET = 4,
- RESERVED0_OFFSET = 8,
- KERNEL_CODE_ENTRY_BYTE_OFFSET_OFFSET = 16,
- RESERVED1_OFFSET = 24,
- COMPUTE_PGM_RSRC3_OFFSET = 44,
- COMPUTE_PGM_RSRC1_OFFSET = 48,
- COMPUTE_PGM_RSRC2_OFFSET = 52,
- KERNEL_CODE_PROPERTIES_OFFSET = 56,
- RESERVED2_OFFSET = 58,
-};
-
+enum : uint32_t {
+ GROUP_SEGMENT_FIXED_SIZE_OFFSET = 0,
+ PRIVATE_SEGMENT_FIXED_SIZE_OFFSET = 4,
+ RESERVED0_OFFSET = 8,
+ KERNEL_CODE_ENTRY_BYTE_OFFSET_OFFSET = 16,
+ RESERVED1_OFFSET = 24,
+ COMPUTE_PGM_RSRC3_OFFSET = 44,
+ COMPUTE_PGM_RSRC1_OFFSET = 48,
+ COMPUTE_PGM_RSRC2_OFFSET = 52,
+ KERNEL_CODE_PROPERTIES_OFFSET = 56,
+ RESERVED2_OFFSET = 58,
+};
+
static_assert(
sizeof(kernel_descriptor_t) == 64,
"invalid size for kernel_descriptor_t");
-static_assert(offsetof(kernel_descriptor_t, group_segment_fixed_size) ==
- GROUP_SEGMENT_FIXED_SIZE_OFFSET,
- "invalid offset for group_segment_fixed_size");
-static_assert(offsetof(kernel_descriptor_t, private_segment_fixed_size) ==
- PRIVATE_SEGMENT_FIXED_SIZE_OFFSET,
- "invalid offset for private_segment_fixed_size");
-static_assert(offsetof(kernel_descriptor_t, reserved0) == RESERVED0_OFFSET,
- "invalid offset for reserved0");
-static_assert(offsetof(kernel_descriptor_t, kernel_code_entry_byte_offset) ==
- KERNEL_CODE_ENTRY_BYTE_OFFSET_OFFSET,
- "invalid offset for kernel_code_entry_byte_offset");
-static_assert(offsetof(kernel_descriptor_t, reserved1) == RESERVED1_OFFSET,
- "invalid offset for reserved1");
-static_assert(offsetof(kernel_descriptor_t, compute_pgm_rsrc3) ==
- COMPUTE_PGM_RSRC3_OFFSET,
- "invalid offset for compute_pgm_rsrc3");
-static_assert(offsetof(kernel_descriptor_t, compute_pgm_rsrc1) ==
- COMPUTE_PGM_RSRC1_OFFSET,
- "invalid offset for compute_pgm_rsrc1");
-static_assert(offsetof(kernel_descriptor_t, compute_pgm_rsrc2) ==
- COMPUTE_PGM_RSRC2_OFFSET,
- "invalid offset for compute_pgm_rsrc2");
-static_assert(offsetof(kernel_descriptor_t, kernel_code_properties) ==
- KERNEL_CODE_PROPERTIES_OFFSET,
- "invalid offset for kernel_code_properties");
-static_assert(offsetof(kernel_descriptor_t, reserved2) == RESERVED2_OFFSET,
- "invalid offset for reserved2");
+static_assert(offsetof(kernel_descriptor_t, group_segment_fixed_size) ==
+ GROUP_SEGMENT_FIXED_SIZE_OFFSET,
+ "invalid offset for group_segment_fixed_size");
+static_assert(offsetof(kernel_descriptor_t, private_segment_fixed_size) ==
+ PRIVATE_SEGMENT_FIXED_SIZE_OFFSET,
+ "invalid offset for private_segment_fixed_size");
+static_assert(offsetof(kernel_descriptor_t, reserved0) == RESERVED0_OFFSET,
+ "invalid offset for reserved0");
+static_assert(offsetof(kernel_descriptor_t, kernel_code_entry_byte_offset) ==
+ KERNEL_CODE_ENTRY_BYTE_OFFSET_OFFSET,
+ "invalid offset for kernel_code_entry_byte_offset");
+static_assert(offsetof(kernel_descriptor_t, reserved1) == RESERVED1_OFFSET,
+ "invalid offset for reserved1");
+static_assert(offsetof(kernel_descriptor_t, compute_pgm_rsrc3) ==
+ COMPUTE_PGM_RSRC3_OFFSET,
+ "invalid offset for compute_pgm_rsrc3");
+static_assert(offsetof(kernel_descriptor_t, compute_pgm_rsrc1) ==
+ COMPUTE_PGM_RSRC1_OFFSET,
+ "invalid offset for compute_pgm_rsrc1");
+static_assert(offsetof(kernel_descriptor_t, compute_pgm_rsrc2) ==
+ COMPUTE_PGM_RSRC2_OFFSET,
+ "invalid offset for compute_pgm_rsrc2");
+static_assert(offsetof(kernel_descriptor_t, kernel_code_properties) ==
+ KERNEL_CODE_PROPERTIES_OFFSET,
+ "invalid offset for kernel_code_properties");
+static_assert(offsetof(kernel_descriptor_t, reserved2) == RESERVED2_OFFSET,
+ "invalid offset for reserved2");
} // end namespace amdhsa
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Support/ARMTargetParser.def b/contrib/libs/llvm12/include/llvm/Support/ARMTargetParser.def
index 5baa4b67d2..37cf0a93bb 100644
--- a/contrib/libs/llvm12/include/llvm/Support/ARMTargetParser.def
+++ b/contrib/libs/llvm12/include/llvm/Support/ARMTargetParser.def
@@ -118,12 +118,12 @@ ARM_ARCH("armv8.6-a", ARMV8_6A, "8.6-A", "v8.6a",
ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS |
ARM::AEK_DOTPROD | ARM::AEK_BF16 | ARM::AEK_SHA2 | ARM::AEK_AES |
ARM::AEK_I8MM))
-ARM_ARCH("armv8.7-a", ARMV8_7A, "8.7-A", "v8.7a",
- ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8,
- (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
- ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS |
- ARM::AEK_DOTPROD | ARM::AEK_BF16 | ARM::AEK_SHA2 | ARM::AEK_AES |
- ARM::AEK_I8MM))
+ARM_ARCH("armv8.7-a", ARMV8_7A, "8.7-A", "v8.7a",
+ ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8,
+ (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+ ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS |
+ ARM::AEK_DOTPROD | ARM::AEK_BF16 | ARM::AEK_SHA2 | ARM::AEK_AES |
+ ARM::AEK_I8MM))
ARM_ARCH("armv8-r", ARMV8R, "8-R", "v8r", ARMBuildAttrs::CPUArch::v8_R,
FK_NEON_FP_ARMV8,
(ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
@@ -300,19 +300,19 @@ ARM_CPU_NAME("cortex-a76ae", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
(ARM::AEK_FP16 | ARM::AEK_DOTPROD))
ARM_CPU_NAME("cortex-a77", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
(ARM::AEK_FP16 | ARM::AEK_DOTPROD))
-ARM_CPU_NAME("cortex-a78", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ARM_CPU_NAME("cortex-a78", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
(ARM::AEK_FP16 | ARM::AEK_DOTPROD))
-ARM_CPU_NAME("cortex-a78c", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
- ARM::AEK_FP16 | ARM::AEK_DOTPROD)
+ARM_CPU_NAME("cortex-a78c", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ ARM::AEK_FP16 | ARM::AEK_DOTPROD)
ARM_CPU_NAME("cortex-x1", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
(ARM::AEK_FP16 | ARM::AEK_DOTPROD))
ARM_CPU_NAME("neoverse-n1", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
(ARM::AEK_FP16 | ARM::AEK_DOTPROD))
-ARM_CPU_NAME("neoverse-n2", ARMV8_5A, FK_CRYPTO_NEON_FP_ARMV8, false,
- (ARM::AEK_BF16 | ARM::AEK_DOTPROD | ARM::AEK_I8MM | ARM::AEK_RAS |
- ARM::AEK_SB))
-ARM_CPU_NAME("neoverse-v1", ARMV8_4A, FK_CRYPTO_NEON_FP_ARMV8, false,
- (ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_BF16 | ARM::AEK_DOTPROD))
+ARM_CPU_NAME("neoverse-n2", ARMV8_5A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (ARM::AEK_BF16 | ARM::AEK_DOTPROD | ARM::AEK_I8MM | ARM::AEK_RAS |
+ ARM::AEK_SB))
+ARM_CPU_NAME("neoverse-v1", ARMV8_4A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_BF16 | ARM::AEK_DOTPROD))
ARM_CPU_NAME("cyclone", ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
ARM_CPU_NAME("exynos-m3", ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
ARM_CPU_NAME("exynos-m4", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
diff --git a/contrib/libs/llvm12/include/llvm/Support/ARMTargetParser.h b/contrib/libs/llvm12/include/llvm/Support/ARMTargetParser.h
index 5dda0d9d1d..901baebefa 100644
--- a/contrib/libs/llvm12/include/llvm/Support/ARMTargetParser.h
+++ b/contrib/libs/llvm12/include/llvm/Support/ARMTargetParser.h
@@ -257,8 +257,8 @@ StringRef getSubArch(ArchKind AK);
StringRef getArchExtName(uint64_t ArchExtKind);
StringRef getArchExtFeature(StringRef ArchExt);
bool appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK, StringRef ArchExt,
- std::vector<StringRef> &Features,
- unsigned &ArgFPUKind);
+ std::vector<StringRef> &Features,
+ unsigned &ArgFPUKind);
StringRef getHWDivName(uint64_t HWDivKind);
// Information by Name
diff --git a/contrib/libs/llvm12/include/llvm/Support/ARMWinEH.h b/contrib/libs/llvm12/include/llvm/Support/ARMWinEH.h
index 4e0aa79565..c35d136f2a 100644
--- a/contrib/libs/llvm12/include/llvm/Support/ARMWinEH.h
+++ b/contrib/libs/llvm12/include/llvm/Support/ARMWinEH.h
@@ -38,9 +38,9 @@ enum class ReturnType {
/// RuntimeFunction - An entry in the table of procedure data (.pdata)
///
-/// This is ARM specific, but the Function Start RVA, Flag and
-/// ExceptionInformationRVA fields work identically for ARM64.
-///
+/// This is ARM specific, but the Function Start RVA, Flag and
+/// ExceptionInformationRVA fields work identically for ARM64.
+///
/// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
/// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
/// +---------------------------------------------------------------+
@@ -214,85 +214,85 @@ inline uint16_t StackAdjustment(const RuntimeFunction &RF) {
/// purpose (r0-r15) and VFP (d0-d31) registers.
std::pair<uint16_t, uint32_t> SavedRegisterMask(const RuntimeFunction &RF);
-/// RuntimeFunctionARM64 - An entry in the table of procedure data (.pdata)
-///
-/// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
-/// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
-/// +---------------------------------------------------------------+
-/// | Function Start RVA |
-/// +-----------------+---+-+-------+-----+---------------------+---+
-/// | Frame Size |CR |H| RegI |RegF | Function Length |Flg|
-/// +-----------------+---+-+-------+-----+---------------------+---+
-///
-/// See https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
-/// for the full reference for this struct.
-
-class RuntimeFunctionARM64 {
-public:
- const support::ulittle32_t BeginAddress;
- const support::ulittle32_t UnwindData;
-
- RuntimeFunctionARM64(const support::ulittle32_t *Data)
- : BeginAddress(Data[0]), UnwindData(Data[1]) {}
-
- RuntimeFunctionARM64(const support::ulittle32_t BeginAddress,
- const support::ulittle32_t UnwindData)
- : BeginAddress(BeginAddress), UnwindData(UnwindData) {}
-
- RuntimeFunctionFlag Flag() const {
- return RuntimeFunctionFlag(UnwindData & 0x3);
- }
-
- uint32_t ExceptionInformationRVA() const {
- assert(Flag() == RuntimeFunctionFlag::RFF_Unpacked &&
- "unpacked form required for this operation");
- return (UnwindData & ~0x3);
- }
-
- uint32_t PackedUnwindData() const {
- assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
- Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
- "packed form required for this operation");
- return (UnwindData & ~0x3);
- }
- uint32_t FunctionLength() const {
- assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
- Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
- "packed form required for this operation");
- return (((UnwindData & 0x00001ffc) >> 2) << 2);
- }
- uint8_t RegF() const {
- assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
- Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
- "packed form required for this operation");
- return ((UnwindData & 0x0000e000) >> 13);
- }
- uint8_t RegI() const {
- assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
- Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
- "packed form required for this operation");
- return ((UnwindData & 0x000f0000) >> 16);
- }
- bool H() const {
- assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
- Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
- "packed form required for this operation");
- return ((UnwindData & 0x00100000) >> 20);
- }
- uint8_t CR() const {
- assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
- Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
- "packed form required for this operation");
- return ((UnwindData & 0x600000) >> 21);
- }
- uint16_t FrameSize() const {
- assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
- Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
- "packed form required for this operation");
- return ((UnwindData & 0xff800000) >> 23);
- }
-};
-
+/// RuntimeFunctionARM64 - An entry in the table of procedure data (.pdata)
+///
+/// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+/// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+/// +---------------------------------------------------------------+
+/// | Function Start RVA |
+/// +-----------------+---+-+-------+-----+---------------------+---+
+/// | Frame Size |CR |H| RegI |RegF | Function Length |Flg|
+/// +-----------------+---+-+-------+-----+---------------------+---+
+///
+/// See https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
+/// for the full reference for this struct.
+
+class RuntimeFunctionARM64 {
+public:
+ const support::ulittle32_t BeginAddress;
+ const support::ulittle32_t UnwindData;
+
+ RuntimeFunctionARM64(const support::ulittle32_t *Data)
+ : BeginAddress(Data[0]), UnwindData(Data[1]) {}
+
+ RuntimeFunctionARM64(const support::ulittle32_t BeginAddress,
+ const support::ulittle32_t UnwindData)
+ : BeginAddress(BeginAddress), UnwindData(UnwindData) {}
+
+ RuntimeFunctionFlag Flag() const {
+ return RuntimeFunctionFlag(UnwindData & 0x3);
+ }
+
+ uint32_t ExceptionInformationRVA() const {
+ assert(Flag() == RuntimeFunctionFlag::RFF_Unpacked &&
+ "unpacked form required for this operation");
+ return (UnwindData & ~0x3);
+ }
+
+ uint32_t PackedUnwindData() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return (UnwindData & ~0x3);
+ }
+ uint32_t FunctionLength() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return (((UnwindData & 0x00001ffc) >> 2) << 2);
+ }
+ uint8_t RegF() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return ((UnwindData & 0x0000e000) >> 13);
+ }
+ uint8_t RegI() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return ((UnwindData & 0x000f0000) >> 16);
+ }
+ bool H() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return ((UnwindData & 0x00100000) >> 20);
+ }
+ uint8_t CR() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return ((UnwindData & 0x600000) >> 21);
+ }
+ uint16_t FrameSize() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return ((UnwindData & 0xff800000) >> 23);
+ }
+};
+
/// ExceptionDataRecord - An entry in the table of exception data (.xdata)
///
/// The format on ARM is:
@@ -505,13 +505,13 @@ struct ExceptionDataRecord {
uint32_t ExceptionHandlerRVA() const {
assert(X() && "Exception Handler RVA is only valid if the X bit is set");
- return Data[HeaderWords(*this) + (E() ? 0 : EpilogueCount()) + CodeWords()];
+ return Data[HeaderWords(*this) + (E() ? 0 : EpilogueCount()) + CodeWords()];
}
uint32_t ExceptionHandlerParameter() const {
assert(X() && "Exception Handler RVA is only valid if the X bit is set");
- return Data[HeaderWords(*this) + (E() ? 0 : EpilogueCount()) + CodeWords() +
- 1];
+ return Data[HeaderWords(*this) + (E() ? 0 : EpilogueCount()) + CodeWords() +
+ 1];
}
};
diff --git a/contrib/libs/llvm12/include/llvm/Support/AlignOf.h b/contrib/libs/llvm12/include/llvm/Support/AlignOf.h
index ce5dc575a3..1521bcebb3 100644
--- a/contrib/libs/llvm12/include/llvm/Support/AlignOf.h
+++ b/contrib/libs/llvm12/include/llvm/Support/AlignOf.h
@@ -20,20 +20,20 @@
#ifndef LLVM_SUPPORT_ALIGNOF_H
#define LLVM_SUPPORT_ALIGNOF_H
-#include <type_traits>
+#include <type_traits>
namespace llvm {
/// A suitably aligned and sized character array member which can hold elements
/// of any type.
///
-/// This template is equivalent to std::aligned_union_t<1, ...>, but we cannot
-/// use it due to a bug in the MSVC x86 compiler:
-/// https://github.com/microsoft/STL/issues/1533
-/// Using `alignas` here works around the bug.
+/// This template is equivalent to std::aligned_union_t<1, ...>, but we cannot
+/// use it due to a bug in the MSVC x86 compiler:
+/// https://github.com/microsoft/STL/issues/1533
+/// Using `alignas` here works around the bug.
template <typename T, typename... Ts> struct AlignedCharArrayUnion {
- using AlignedUnion = std::aligned_union_t<1, T, Ts...>;
- alignas(alignof(AlignedUnion)) char buffer[sizeof(AlignedUnion)];
+ using AlignedUnion = std::aligned_union_t<1, T, Ts...>;
+ alignas(alignof(AlignedUnion)) char buffer[sizeof(AlignedUnion)];
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Support/Allocator.h b/contrib/libs/llvm12/include/llvm/Support/Allocator.h
index 80f338d7f8..639ae5dcaa 100644
--- a/contrib/libs/llvm12/include/llvm/Support/Allocator.h
+++ b/contrib/libs/llvm12/include/llvm/Support/Allocator.h
@@ -73,8 +73,8 @@ template <typename AllocatorT = MallocAllocator, size_t SlabSize = 4096,
size_t SizeThreshold = SlabSize, size_t GrowthDelay = 128>
class BumpPtrAllocatorImpl
: public AllocatorBase<BumpPtrAllocatorImpl<AllocatorT, SlabSize,
- SizeThreshold, GrowthDelay>>,
- private AllocatorT {
+ SizeThreshold, GrowthDelay>>,
+ private AllocatorT {
public:
static_assert(SizeThreshold <= SlabSize,
"The SizeThreshold must be at most the SlabSize to ensure "
@@ -88,15 +88,15 @@ public:
template <typename T>
BumpPtrAllocatorImpl(T &&Allocator)
- : AllocatorT(std::forward<T &&>(Allocator)) {}
+ : AllocatorT(std::forward<T &&>(Allocator)) {}
// Manually implement a move constructor as we must clear the old allocator's
// slabs as a matter of correctness.
BumpPtrAllocatorImpl(BumpPtrAllocatorImpl &&Old)
- : AllocatorT(static_cast<AllocatorT &&>(Old)), CurPtr(Old.CurPtr),
- End(Old.End), Slabs(std::move(Old.Slabs)),
+ : AllocatorT(static_cast<AllocatorT &&>(Old)), CurPtr(Old.CurPtr),
+ End(Old.End), Slabs(std::move(Old.Slabs)),
CustomSizedSlabs(std::move(Old.CustomSizedSlabs)),
- BytesAllocated(Old.BytesAllocated), RedZoneSize(Old.RedZoneSize) {
+ BytesAllocated(Old.BytesAllocated), RedZoneSize(Old.RedZoneSize) {
Old.CurPtr = Old.End = nullptr;
Old.BytesAllocated = 0;
Old.Slabs.clear();
@@ -118,7 +118,7 @@ public:
RedZoneSize = RHS.RedZoneSize;
Slabs = std::move(RHS.Slabs);
CustomSizedSlabs = std::move(RHS.CustomSizedSlabs);
- AllocatorT::operator=(static_cast<AllocatorT &&>(RHS));
+ AllocatorT::operator=(static_cast<AllocatorT &&>(RHS));
RHS.CurPtr = RHS.End = nullptr;
RHS.BytesAllocated = 0;
@@ -178,8 +178,8 @@ public:
// If Size is really big, allocate a separate slab for it.
size_t PaddedSize = SizeToAllocate + Alignment.value() - 1;
if (PaddedSize > SizeThreshold) {
- void *NewSlab =
- AllocatorT::Allocate(PaddedSize, alignof(std::max_align_t));
+ void *NewSlab =
+ AllocatorT::Allocate(PaddedSize, alignof(std::max_align_t));
// We own the new slab and don't want anyone reading anyting other than
// pieces returned from this method. So poison the whole slab.
__asan_poison_memory_region(NewSlab, PaddedSize);
@@ -339,7 +339,7 @@ private:
size_t AllocatedSlabSize = computeSlabSize(Slabs.size());
void *NewSlab =
- AllocatorT::Allocate(AllocatedSlabSize, alignof(std::max_align_t));
+ AllocatorT::Allocate(AllocatedSlabSize, alignof(std::max_align_t));
// We own the new slab and don't want anyone reading anything other than
// pieces returned from this method. So poison the whole slab.
__asan_poison_memory_region(NewSlab, AllocatedSlabSize);
@@ -355,7 +355,7 @@ private:
for (; I != E; ++I) {
size_t AllocatedSlabSize =
computeSlabSize(std::distance(Slabs.begin(), I));
- AllocatorT::Deallocate(*I, AllocatedSlabSize, alignof(std::max_align_t));
+ AllocatorT::Deallocate(*I, AllocatedSlabSize, alignof(std::max_align_t));
}
}
@@ -364,7 +364,7 @@ private:
for (auto &PtrAndSize : CustomSizedSlabs) {
void *Ptr = PtrAndSize.first;
size_t Size = PtrAndSize.second;
- AllocatorT::Deallocate(Ptr, Size, alignof(std::max_align_t));
+ AllocatorT::Deallocate(Ptr, Size, alignof(std::max_align_t));
}
}
diff --git a/contrib/libs/llvm12/include/llvm/Support/AtomicOrdering.h b/contrib/libs/llvm12/include/llvm/Support/AtomicOrdering.h
index a93b7fe8a1..fe381ae274 100644
--- a/contrib/libs/llvm12/include/llvm/Support/AtomicOrdering.h
+++ b/contrib/libs/llvm12/include/llvm/Support/AtomicOrdering.h
@@ -28,7 +28,7 @@
namespace llvm {
-/// Atomic ordering for C11 / C++11's memory models.
+/// Atomic ordering for C11 / C++11's memory models.
///
/// These values cannot change because they are shared with standard library
/// implementations as well as with other compilers.
@@ -94,7 +94,7 @@ inline const char *toIRString(AtomicOrdering ao) {
/// Returns true if ao is stronger than other as defined by the AtomicOrdering
/// lattice, which is based on C++'s definition.
-inline bool isStrongerThan(AtomicOrdering AO, AtomicOrdering Other) {
+inline bool isStrongerThan(AtomicOrdering AO, AtomicOrdering Other) {
static const bool lookup[8][8] = {
// NA UN RX CO AC RE AR SC
/* NotAtomic */ {false, false, false, false, false, false, false, false},
@@ -106,10 +106,10 @@ inline bool isStrongerThan(AtomicOrdering AO, AtomicOrdering Other) {
/* acq_rel */ { true, true, true, true, true, true, false, false},
/* seq_cst */ { true, true, true, true, true, true, true, false},
};
- return lookup[static_cast<size_t>(AO)][static_cast<size_t>(Other)];
+ return lookup[static_cast<size_t>(AO)][static_cast<size_t>(Other)];
}
-inline bool isAtLeastOrStrongerThan(AtomicOrdering AO, AtomicOrdering Other) {
+inline bool isAtLeastOrStrongerThan(AtomicOrdering AO, AtomicOrdering Other) {
static const bool lookup[8][8] = {
// NA UN RX CO AC RE AR SC
/* NotAtomic */ { true, false, false, false, false, false, false, false},
@@ -121,26 +121,26 @@ inline bool isAtLeastOrStrongerThan(AtomicOrdering AO, AtomicOrdering Other) {
/* acq_rel */ { true, true, true, true, true, true, true, false},
/* seq_cst */ { true, true, true, true, true, true, true, true},
};
- return lookup[static_cast<size_t>(AO)][static_cast<size_t>(Other)];
+ return lookup[static_cast<size_t>(AO)][static_cast<size_t>(Other)];
}
-inline bool isStrongerThanUnordered(AtomicOrdering AO) {
- return isStrongerThan(AO, AtomicOrdering::Unordered);
+inline bool isStrongerThanUnordered(AtomicOrdering AO) {
+ return isStrongerThan(AO, AtomicOrdering::Unordered);
}
-inline bool isStrongerThanMonotonic(AtomicOrdering AO) {
- return isStrongerThan(AO, AtomicOrdering::Monotonic);
+inline bool isStrongerThanMonotonic(AtomicOrdering AO) {
+ return isStrongerThan(AO, AtomicOrdering::Monotonic);
}
-inline bool isAcquireOrStronger(AtomicOrdering AO) {
- return isAtLeastOrStrongerThan(AO, AtomicOrdering::Acquire);
+inline bool isAcquireOrStronger(AtomicOrdering AO) {
+ return isAtLeastOrStrongerThan(AO, AtomicOrdering::Acquire);
}
-inline bool isReleaseOrStronger(AtomicOrdering AO) {
- return isAtLeastOrStrongerThan(AO, AtomicOrdering::Release);
+inline bool isReleaseOrStronger(AtomicOrdering AO) {
+ return isAtLeastOrStrongerThan(AO, AtomicOrdering::Release);
}
-inline AtomicOrderingCABI toCABI(AtomicOrdering AO) {
+inline AtomicOrderingCABI toCABI(AtomicOrdering AO) {
static const AtomicOrderingCABI lookup[8] = {
/* NotAtomic */ AtomicOrderingCABI::relaxed,
/* Unordered */ AtomicOrderingCABI::relaxed,
@@ -151,7 +151,7 @@ inline AtomicOrderingCABI toCABI(AtomicOrdering AO) {
/* acq_rel */ AtomicOrderingCABI::acq_rel,
/* seq_cst */ AtomicOrderingCABI::seq_cst,
};
- return lookup[static_cast<size_t>(AO)];
+ return lookup[static_cast<size_t>(AO)];
}
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Support/BinaryItemStream.h b/contrib/libs/llvm12/include/llvm/Support/BinaryItemStream.h
index 836ce5af90..73d853e81a 100644
--- a/contrib/libs/llvm12/include/llvm/Support/BinaryItemStream.h
+++ b/contrib/libs/llvm12/include/llvm/Support/BinaryItemStream.h
@@ -95,7 +95,7 @@ private:
if (Offset >= getLength())
return make_error<BinaryStreamError>(stream_error_code::stream_too_short);
++Offset;
- auto Iter = llvm::lower_bound(ItemEndOffsets, Offset);
+ auto Iter = llvm::lower_bound(ItemEndOffsets, Offset);
size_t Idx = std::distance(ItemEndOffsets.begin(), Iter);
assert(Idx < Items.size() && "binary search for offset failed");
return Idx;
diff --git a/contrib/libs/llvm12/include/llvm/Support/CFGDiff.h b/contrib/libs/llvm12/include/llvm/Support/CFGDiff.h
index f43f377fc2..398314b4fc 100644
--- a/contrib/libs/llvm12/include/llvm/Support/CFGDiff.h
+++ b/contrib/libs/llvm12/include/llvm/Support/CFGDiff.h
@@ -37,38 +37,38 @@
// a non-inversed graph, the children are naturally the successors when
// InverseEdge is false and the predecessors when InverseEdge is true.
-namespace llvm {
-
-namespace detail {
-template <typename Range>
-auto reverse_if_helper(Range &&R, std::integral_constant<bool, false>) {
- return std::forward<Range>(R);
-}
-
-template <typename Range>
-auto reverse_if_helper(Range &&R, std::integral_constant<bool, true>) {
- return llvm::reverse(std::forward<Range>(R));
-}
-
-template <bool B, typename Range> auto reverse_if(Range &&R) {
- return reverse_if_helper(std::forward<Range>(R),
- std::integral_constant<bool, B>{});
-}
-} // namespace detail
-
-// GraphDiff defines a CFG snapshot: given a set of Update<NodePtr>, provides
-// a getChildren method to get a Node's children based on the additional updates
-// in the snapshot. The current diff treats the CFG as a graph rather than a
+namespace llvm {
+
+namespace detail {
+template <typename Range>
+auto reverse_if_helper(Range &&R, std::integral_constant<bool, false>) {
+ return std::forward<Range>(R);
+}
+
+template <typename Range>
+auto reverse_if_helper(Range &&R, std::integral_constant<bool, true>) {
+ return llvm::reverse(std::forward<Range>(R));
+}
+
+template <bool B, typename Range> auto reverse_if(Range &&R) {
+ return reverse_if_helper(std::forward<Range>(R),
+ std::integral_constant<bool, B>{});
+}
+} // namespace detail
+
+// GraphDiff defines a CFG snapshot: given a set of Update<NodePtr>, provides
+// a getChildren method to get a Node's children based on the additional updates
+// in the snapshot. The current diff treats the CFG as a graph rather than a
// multigraph. Added edges are pruned to be unique, and deleted edges will
// remove all existing edges between two blocks.
template <typename NodePtr, bool InverseGraph = false> class GraphDiff {
- struct DeletesInserts {
- SmallVector<NodePtr, 2> DI[2];
+ struct DeletesInserts {
+ SmallVector<NodePtr, 2> DI[2];
};
- using UpdateMapType = SmallDenseMap<NodePtr, DeletesInserts>;
- UpdateMapType Succ;
- UpdateMapType Pred;
-
+ using UpdateMapType = SmallDenseMap<NodePtr, DeletesInserts>;
+ UpdateMapType Succ;
+ UpdateMapType Pred;
+
// By default, it is assumed that, given a CFG and a set of updates, we wish
// to apply these updates as given. If UpdatedAreReverseApplied is set, the
// updates will be applied in reverse: deleted edges are considered re-added
@@ -81,19 +81,19 @@ template <typename NodePtr, bool InverseGraph = false> class GraphDiff {
SmallVector<cfg::Update<NodePtr>, 4> LegalizedUpdates;
void printMap(raw_ostream &OS, const UpdateMapType &M) const {
- StringRef DIText[2] = {"Delete", "Insert"};
- for (auto Pair : M) {
- for (unsigned IsInsert = 0; IsInsert <= 1; ++IsInsert) {
- OS << DIText[IsInsert] << " edges: \n";
- for (auto Child : Pair.second.DI[IsInsert]) {
- OS << "(";
- Pair.first->printAsOperand(OS, false);
- OS << ", ";
- Child->printAsOperand(OS, false);
- OS << ") ";
- }
+ StringRef DIText[2] = {"Delete", "Insert"};
+ for (auto Pair : M) {
+ for (unsigned IsInsert = 0; IsInsert <= 1; ++IsInsert) {
+ OS << DIText[IsInsert] << " edges: \n";
+ for (auto Child : Pair.second.DI[IsInsert]) {
+ OS << "(";
+ Pair.first->printAsOperand(OS, false);
+ OS << ", ";
+ Child->printAsOperand(OS, false);
+ OS << ") ";
+ }
}
- }
+ }
OS << "\n";
}
@@ -101,12 +101,12 @@ public:
GraphDiff() : UpdatedAreReverseApplied(false) {}
GraphDiff(ArrayRef<cfg::Update<NodePtr>> Updates,
bool ReverseApplyUpdates = false) {
- cfg::LegalizeUpdates<NodePtr>(Updates, LegalizedUpdates, InverseGraph);
+ cfg::LegalizeUpdates<NodePtr>(Updates, LegalizedUpdates, InverseGraph);
for (auto U : LegalizedUpdates) {
unsigned IsInsert =
(U.getKind() == cfg::UpdateKind::Insert) == !ReverseApplyUpdates;
- Succ[U.getFrom()].DI[IsInsert].push_back(U.getTo());
- Pred[U.getTo()].DI[IsInsert].push_back(U.getFrom());
+ Succ[U.getFrom()].DI[IsInsert].push_back(U.getTo());
+ Pred[U.getTo()].DI[IsInsert].push_back(U.getFrom());
}
UpdatedAreReverseApplied = ReverseApplyUpdates;
}
@@ -122,56 +122,56 @@ public:
auto U = LegalizedUpdates.pop_back_val();
unsigned IsInsert =
(U.getKind() == cfg::UpdateKind::Insert) == !UpdatedAreReverseApplied;
- auto &SuccDIList = Succ[U.getFrom()];
- auto &SuccList = SuccDIList.DI[IsInsert];
+ auto &SuccDIList = Succ[U.getFrom()];
+ auto &SuccList = SuccDIList.DI[IsInsert];
assert(SuccList.back() == U.getTo());
SuccList.pop_back();
- if (SuccList.empty() && SuccDIList.DI[!IsInsert].empty())
- Succ.erase(U.getFrom());
+ if (SuccList.empty() && SuccDIList.DI[!IsInsert].empty())
+ Succ.erase(U.getFrom());
- auto &PredDIList = Pred[U.getTo()];
- auto &PredList = PredDIList.DI[IsInsert];
+ auto &PredDIList = Pred[U.getTo()];
+ auto &PredList = PredDIList.DI[IsInsert];
assert(PredList.back() == U.getFrom());
PredList.pop_back();
- if (PredList.empty() && PredDIList.DI[!IsInsert].empty())
- Pred.erase(U.getTo());
+ if (PredList.empty() && PredDIList.DI[!IsInsert].empty())
+ Pred.erase(U.getTo());
return U;
}
- using VectRet = SmallVector<NodePtr, 8>;
- template <bool InverseEdge> VectRet getChildren(NodePtr N) const {
- using DirectedNodeT =
- std::conditional_t<InverseEdge, Inverse<NodePtr>, NodePtr>;
- auto R = children<DirectedNodeT>(N);
- VectRet Res = VectRet(detail::reverse_if<!InverseEdge>(R));
-
- // Remove nullptr children for clang.
- llvm::erase_value(Res, nullptr);
-
- auto &Children = (InverseEdge != InverseGraph) ? Pred : Succ;
- auto It = Children.find(N);
- if (It == Children.end())
- return Res;
-
- // Remove children present in the CFG but not in the snapshot.
- for (auto *Child : It->second.DI[0])
- llvm::erase_value(Res, Child);
-
- // Add children present in the snapshot for not in the real CFG.
- auto &AddedChildren = It->second.DI[1];
- llvm::append_range(Res, AddedChildren);
-
- return Res;
+ using VectRet = SmallVector<NodePtr, 8>;
+ template <bool InverseEdge> VectRet getChildren(NodePtr N) const {
+ using DirectedNodeT =
+ std::conditional_t<InverseEdge, Inverse<NodePtr>, NodePtr>;
+ auto R = children<DirectedNodeT>(N);
+ VectRet Res = VectRet(detail::reverse_if<!InverseEdge>(R));
+
+ // Remove nullptr children for clang.
+ llvm::erase_value(Res, nullptr);
+
+ auto &Children = (InverseEdge != InverseGraph) ? Pred : Succ;
+ auto It = Children.find(N);
+ if (It == Children.end())
+ return Res;
+
+ // Remove children present in the CFG but not in the snapshot.
+ for (auto *Child : It->second.DI[0])
+ llvm::erase_value(Res, Child);
+
+ // Add children present in the snapshot for not in the real CFG.
+ auto &AddedChildren = It->second.DI[1];
+ llvm::append_range(Res, AddedChildren);
+
+ return Res;
}
void print(raw_ostream &OS) const {
OS << "===== GraphDiff: CFG edge changes to create a CFG snapshot. \n"
"===== (Note: notion of children/inverse_children depends on "
"the direction of edges and the graph.)\n";
- OS << "Children to delete/insert:\n\t";
- printMap(OS, Succ);
- OS << "Inverse_children to delete/insert:\n\t";
- printMap(OS, Pred);
+ OS << "Children to delete/insert:\n\t";
+ printMap(OS, Succ);
+ OS << "Inverse_children to delete/insert:\n\t";
+ printMap(OS, Pred);
OS << "\n";
}
diff --git a/contrib/libs/llvm12/include/llvm/Support/CheckedArithmetic.h b/contrib/libs/llvm12/include/llvm/Support/CheckedArithmetic.h
index bc2b18bb14..29be66ad59 100644
--- a/contrib/libs/llvm12/include/llvm/Support/CheckedArithmetic.h
+++ b/contrib/libs/llvm12/include/llvm/Support/CheckedArithmetic.h
@@ -35,8 +35,8 @@ template <typename T, typename F>
std::enable_if_t<std::is_integral<T>::value && sizeof(T) * 8 <= 64,
llvm::Optional<T>>
checkedOp(T LHS, T RHS, F Op, bool Signed = true) {
- llvm::APInt ALHS(sizeof(T) * 8, LHS, Signed);
- llvm::APInt ARHS(sizeof(T) * 8, RHS, Signed);
+ llvm::APInt ALHS(sizeof(T) * 8, LHS, Signed);
+ llvm::APInt ARHS(sizeof(T) * 8, RHS, Signed);
bool Overflow;
llvm::APInt Out = (ALHS.*Op)(ARHS, Overflow);
if (Overflow)
diff --git a/contrib/libs/llvm12/include/llvm/Support/CommandLine.h b/contrib/libs/llvm12/include/llvm/Support/CommandLine.h
index b1231bf397..df5b148c14 100644
--- a/contrib/libs/llvm12/include/llvm/Support/CommandLine.h
+++ b/contrib/libs/llvm12/include/llvm/Support/CommandLine.h
@@ -376,22 +376,22 @@ public:
virtual void setDefault() = 0;
- // Prints the help string for an option.
- //
- // This maintains the Indent for multi-line descriptions.
- // FirstLineIndentedBy is the count of chars of the first line
- // i.e. the one containing the --<option name>.
+ // Prints the help string for an option.
+ //
+ // This maintains the Indent for multi-line descriptions.
+ // FirstLineIndentedBy is the count of chars of the first line
+ // i.e. the one containing the --<option name>.
static void printHelpStr(StringRef HelpStr, size_t Indent,
size_t FirstLineIndentedBy);
- // Prints the help string for an enum value.
- //
- // This maintains the Indent for multi-line descriptions.
- // FirstLineIndentedBy is the count of chars of the first line
- // i.e. the one containing the =<value>.
- static void printEnumValHelpStr(StringRef HelpStr, size_t Indent,
- size_t FirstLineIndentedBy);
-
+ // Prints the help string for an enum value.
+ //
+ // This maintains the Indent for multi-line descriptions.
+ // FirstLineIndentedBy is the count of chars of the first line
+ // i.e. the one containing the =<value>.
+ static void printEnumValHelpStr(StringRef HelpStr, size_t Indent,
+ size_t FirstLineIndentedBy);
+
virtual void getExtraOptionNames(SmallVectorImpl<StringRef> &) {}
// addOccurrence - Wrapper around handleOccurrence that enforces Flags.
@@ -692,7 +692,7 @@ public:
: Values(Options) {}
template <class Opt> void apply(Opt &O) const {
- for (const auto &Value : Values)
+ for (const auto &Value : Values)
O.getParser().addLiteralOption(Value.Name, Value.Value,
Value.Description);
}
@@ -1501,7 +1501,7 @@ public:
template <class... Mods>
explicit opt(const Mods &... Ms)
- : Option(llvm::cl::Optional, NotHidden), Parser(*this) {
+ : Option(llvm::cl::Optional, NotHidden), Parser(*this) {
apply(this, Ms...);
done();
}
@@ -2105,14 +2105,14 @@ bool ExpandResponseFiles(
llvm::vfs::FileSystem &FS = *llvm::vfs::getRealFileSystem(),
llvm::Optional<llvm::StringRef> CurrentDir = llvm::None);
-/// A convenience helper which concatenates the options specified by the
-/// environment variable EnvVar and command line options, then expands response
-/// files recursively. The tokenizer is a predefined GNU or Windows one.
-/// \return true if all @files were expanded successfully or there were none.
-bool expandResponseFiles(int Argc, const char *const *Argv, const char *EnvVar,
- StringSaver &Saver,
- SmallVectorImpl<const char *> &NewArgv);
-
+/// A convenience helper which concatenates the options specified by the
+/// environment variable EnvVar and command line options, then expands response
+/// files recursively. The tokenizer is a predefined GNU or Windows one.
+/// \return true if all @files were expanded successfully or there were none.
+bool expandResponseFiles(int Argc, const char *const *Argv, const char *EnvVar,
+ StringSaver &Saver,
+ SmallVectorImpl<const char *> &NewArgv);
+
/// Mark all options not part of this category as cl::ReallyHidden.
///
/// \param Category the category of options to keep displaying
diff --git a/contrib/libs/llvm12/include/llvm/Support/Compiler.h b/contrib/libs/llvm12/include/llvm/Support/Compiler.h
index 18ae5f7f76..07c5bba5ca 100644
--- a/contrib/libs/llvm12/include/llvm/Support/Compiler.h
+++ b/contrib/libs/llvm12/include/llvm/Support/Compiler.h
@@ -153,7 +153,7 @@
/// LLVM_NODISCARD - Warn if a type or return value is discarded.
// Use the 'nodiscard' attribute in C++17 or newer mode.
-#if defined(__cplusplus) && __cplusplus > 201402L && LLVM_HAS_CPP_ATTRIBUTE(nodiscard)
+#if defined(__cplusplus) && __cplusplus > 201402L && LLVM_HAS_CPP_ATTRIBUTE(nodiscard)
#define LLVM_NODISCARD [[nodiscard]]
#elif LLVM_HAS_CPP_ATTRIBUTE(clang::warn_unused_result)
#define LLVM_NODISCARD [[clang::warn_unused_result]]
@@ -241,11 +241,11 @@
/// 3.4 supported this but is buggy in various cases and produces unimplemented
/// errors, just use it in GCC 4.0 and later.
#if __has_attribute(always_inline) || LLVM_GNUC_PREREQ(4, 0, 0)
-#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline))
+#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline))
#elif defined(_MSC_VER)
#define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline
#else
-#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline
+#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline
#endif
#ifdef __GNUC__
@@ -275,7 +275,7 @@
#endif
/// LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
-#if defined(__cplusplus) && __cplusplus > 201402L && LLVM_HAS_CPP_ATTRIBUTE(fallthrough)
+#if defined(__cplusplus) && __cplusplus > 201402L && LLVM_HAS_CPP_ATTRIBUTE(fallthrough)
#define LLVM_FALLTHROUGH [[fallthrough]]
#elif LLVM_HAS_CPP_ATTRIBUTE(gnu::fallthrough)
#define LLVM_FALLTHROUGH [[gnu::fallthrough]]
@@ -321,9 +321,9 @@
#endif
// LLVM_ATTRIBUTE_DEPRECATED(decl, "message")
-// This macro will be removed.
-// Use C++14's attribute instead: [[deprecated("message")]]
-#define LLVM_ATTRIBUTE_DEPRECATED(decl, message) [[deprecated(message)]] decl
+// This macro will be removed.
+// Use C++14's attribute instead: [[deprecated("message")]]
+#define LLVM_ATTRIBUTE_DEPRECATED(decl, message) [[deprecated(message)]] decl
/// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands
/// to an expression which states that it is undefined behavior for the
diff --git a/contrib/libs/llvm12/include/llvm/Support/CrashRecoveryContext.h b/contrib/libs/llvm12/include/llvm/Support/CrashRecoveryContext.h
index 3be1909872..89429f7493 100644
--- a/contrib/libs/llvm12/include/llvm/Support/CrashRecoveryContext.h
+++ b/contrib/libs/llvm12/include/llvm/Support/CrashRecoveryContext.h
@@ -51,11 +51,11 @@ class CrashRecoveryContextCleanup;
/// executed in any case, whether crash occurs or not. These actions may be used
/// to reclaim resources in the case of crash.
class CrashRecoveryContext {
- void *Impl = nullptr;
- CrashRecoveryContextCleanup *head = nullptr;
+ void *Impl = nullptr;
+ CrashRecoveryContextCleanup *head = nullptr;
public:
- CrashRecoveryContext();
+ CrashRecoveryContext();
~CrashRecoveryContext();
/// Register cleanup handler, which is used when the recovery context is
@@ -109,10 +109,10 @@ public:
LLVM_ATTRIBUTE_NORETURN
void HandleExit(int RetCode);
- /// Throw again a signal or an exception, after it was catched once by a
- /// CrashRecoveryContext.
- static bool throwIfCrash(int RetCode);
-
+ /// Throw again a signal or an exception, after it was catched once by a
+ /// CrashRecoveryContext.
+ static bool throwIfCrash(int RetCode);
+
/// In case of a crash, this is the crash identifier.
int RetCode = 0;
@@ -192,7 +192,7 @@ public:
: CrashRecoveryContextCleanupBase<
CrashRecoveryContextDestructorCleanup<T>, T>(context, resource) {}
- void recoverResources() override {
+ void recoverResources() override {
this->resource->~T();
}
};
diff --git a/contrib/libs/llvm12/include/llvm/Support/DOTGraphTraits.h b/contrib/libs/llvm12/include/llvm/Support/DOTGraphTraits.h
index e4cb57d8c9..d79a095eaf 100644
--- a/contrib/libs/llvm12/include/llvm/Support/DOTGraphTraits.h
+++ b/contrib/libs/llvm12/include/llvm/Support/DOTGraphTraits.h
@@ -67,8 +67,8 @@ public:
/// isNodeHidden - If the function returns true, the given node is not
/// displayed in the graph.
- template <typename GraphType>
- static bool isNodeHidden(const void *, const GraphType &) {
+ template <typename GraphType>
+ static bool isNodeHidden(const void *, const GraphType &) {
return false;
}
diff --git a/contrib/libs/llvm12/include/llvm/Support/Error.h b/contrib/libs/llvm12/include/llvm/Support/Error.h
index 6e909257c6..1ac408ff50 100644
--- a/contrib/libs/llvm12/include/llvm/Support/Error.h
+++ b/contrib/libs/llvm12/include/llvm/Support/Error.h
@@ -636,22 +636,22 @@ private:
storage_type *getStorage() {
assert(!HasError && "Cannot get value when an error exists!");
- return reinterpret_cast<storage_type *>(&TStorage);
+ return reinterpret_cast<storage_type *>(&TStorage);
}
const storage_type *getStorage() const {
assert(!HasError && "Cannot get value when an error exists!");
- return reinterpret_cast<const storage_type *>(&TStorage);
+ return reinterpret_cast<const storage_type *>(&TStorage);
}
error_type *getErrorStorage() {
assert(HasError && "Cannot get error when a value exists!");
- return reinterpret_cast<error_type *>(&ErrorStorage);
+ return reinterpret_cast<error_type *>(&ErrorStorage);
}
const error_type *getErrorStorage() const {
assert(HasError && "Cannot get error when a value exists!");
- return reinterpret_cast<const error_type *>(&ErrorStorage);
+ return reinterpret_cast<const error_type *>(&ErrorStorage);
}
// Used by ExpectedAsOutParameter to reset the checked flag.
diff --git a/contrib/libs/llvm12/include/llvm/Support/ErrorHandling.h b/contrib/libs/llvm12/include/llvm/Support/ErrorHandling.h
index 22d300662b..73e97d1179 100644
--- a/contrib/libs/llvm12/include/llvm/Support/ErrorHandling.h
+++ b/contrib/libs/llvm12/include/llvm/Support/ErrorHandling.h
@@ -117,9 +117,9 @@ void install_out_of_memory_new_handler();
/// the following unwind succeeds, e.g. do not trigger additional allocations
/// in the unwind chain.
///
-/// If no error handler is installed (default), throws a bad_alloc exception
-/// if LLVM is compiled with exception support. Otherwise prints the error
-/// to standard error and calls abort().
+/// If no error handler is installed (default), throws a bad_alloc exception
+/// if LLVM is compiled with exception support. Otherwise prints the error
+/// to standard error and calls abort().
LLVM_ATTRIBUTE_NORETURN void report_bad_alloc_error(const char *Reason,
bool GenCrashDiag = true);
diff --git a/contrib/libs/llvm12/include/llvm/Support/ErrorOr.h b/contrib/libs/llvm12/include/llvm/Support/ErrorOr.h
index 0e2e63dff1..67d9a08126 100644
--- a/contrib/libs/llvm12/include/llvm/Support/ErrorOr.h
+++ b/contrib/libs/llvm12/include/llvm/Support/ErrorOr.h
@@ -242,17 +242,17 @@ private:
storage_type *getStorage() {
assert(!HasError && "Cannot get value when an error exists!");
- return reinterpret_cast<storage_type *>(&TStorage);
+ return reinterpret_cast<storage_type *>(&TStorage);
}
const storage_type *getStorage() const {
assert(!HasError && "Cannot get value when an error exists!");
- return reinterpret_cast<const storage_type *>(&TStorage);
+ return reinterpret_cast<const storage_type *>(&TStorage);
}
std::error_code *getErrorStorage() {
assert(HasError && "Cannot get error when a value exists!");
- return reinterpret_cast<std::error_code *>(&ErrorStorage);
+ return reinterpret_cast<std::error_code *>(&ErrorStorage);
}
const std::error_code *getErrorStorage() const {
diff --git a/contrib/libs/llvm12/include/llvm/Support/ExitCodes.h b/contrib/libs/llvm12/include/llvm/Support/ExitCodes.h
index 0b8ffd58ee..3fe064313f 100644
--- a/contrib/libs/llvm12/include/llvm/Support/ExitCodes.h
+++ b/contrib/libs/llvm12/include/llvm/Support/ExitCodes.h
@@ -1,44 +1,44 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===-- llvm/Support/ExitCodes.h - Exit codes for exit() -------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This file contains definitions of exit codes for exit() function. They are
-/// either defined by sysexits.h if it is supported, or defined here if
-/// sysexits.h is not supported.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_EXITCODES_H
-#define LLVM_SUPPORT_EXITCODES_H
-
-#include "llvm/Config/llvm-config.h"
-
-#if HAVE_SYSEXITS_H
-#include <sysexits.h>
-#elif __MVS__
-// <sysexits.h> does not exist on z/OS. The only value used in LLVM is
-// EX_IOERR, which is used to signal a special error condition (broken pipe).
-// Define the macro with its usual value from BSD systems, which is chosen to
-// not clash with more standard exit codes like 1.
-#define EX_IOERR 74
-#elif LLVM_ON_UNIX
-#error Exit code EX_IOERR not available
-#endif
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===-- llvm/Support/ExitCodes.h - Exit codes for exit() -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains definitions of exit codes for exit() function. They are
+/// either defined by sysexits.h if it is supported, or defined here if
+/// sysexits.h is not supported.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_EXITCODES_H
+#define LLVM_SUPPORT_EXITCODES_H
+
+#include "llvm/Config/llvm-config.h"
+
+#if HAVE_SYSEXITS_H
+#include <sysexits.h>
+#elif __MVS__
+// <sysexits.h> does not exist on z/OS. The only value used in LLVM is
+// EX_IOERR, which is used to signal a special error condition (broken pipe).
+// Define the macro with its usual value from BSD systems, which is chosen to
+// not clash with more standard exit codes like 1.
+#define EX_IOERR 74
+#elif LLVM_ON_UNIX
+#error Exit code EX_IOERR not available
+#endif
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Support/FileCollector.h b/contrib/libs/llvm12/include/llvm/Support/FileCollector.h
index 5312484702..828bc973f9 100644
--- a/contrib/libs/llvm12/include/llvm/Support/FileCollector.h
+++ b/contrib/libs/llvm12/include/llvm/Support/FileCollector.h
@@ -27,35 +27,35 @@ namespace llvm {
class FileCollectorFileSystem;
class Twine;
-class FileCollectorBase {
-public:
- FileCollectorBase();
- virtual ~FileCollectorBase();
-
- void addFile(const Twine &file);
- void addDirectory(const Twine &Dir);
-
-protected:
- bool markAsSeen(StringRef Path) {
- if (Path.empty())
- return false;
- return Seen.insert(Path).second;
- }
-
- virtual void addFileImpl(StringRef SrcPath) = 0;
-
- virtual llvm::vfs::directory_iterator
- addDirectoryImpl(const llvm::Twine &Dir,
- IntrusiveRefCntPtr<vfs::FileSystem> FS,
- std::error_code &EC) = 0;
-
- /// Synchronizes access to internal data structures.
- std::mutex Mutex;
-
- /// Tracks already seen files so they can be skipped.
- StringSet<> Seen;
-};
-
+class FileCollectorBase {
+public:
+ FileCollectorBase();
+ virtual ~FileCollectorBase();
+
+ void addFile(const Twine &file);
+ void addDirectory(const Twine &Dir);
+
+protected:
+ bool markAsSeen(StringRef Path) {
+ if (Path.empty())
+ return false;
+ return Seen.insert(Path).second;
+ }
+
+ virtual void addFileImpl(StringRef SrcPath) = 0;
+
+ virtual llvm::vfs::directory_iterator
+ addDirectoryImpl(const llvm::Twine &Dir,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS,
+ std::error_code &EC) = 0;
+
+ /// Synchronizes access to internal data structures.
+ std::mutex Mutex;
+
+ /// Tracks already seen files so they can be skipped.
+ StringSet<> Seen;
+};
+
/// Captures file system interaction and generates data to be later replayed
/// with the RedirectingFileSystem.
///
@@ -74,29 +74,29 @@ protected:
///
/// In order to preserve the relative topology of files we use their real paths
/// as relative paths inside of the Root.
-class FileCollector : public FileCollectorBase {
+class FileCollector : public FileCollectorBase {
public:
- /// Helper utility that encapsulates the logic for canonicalizing a virtual
- /// path and a path to copy from.
- class PathCanonicalizer {
- public:
- struct PathStorage {
- SmallString<256> CopyFrom;
- SmallString<256> VirtualPath;
- };
-
- /// Canonicalize a pair of virtual and real paths.
- PathStorage canonicalize(StringRef SrcPath);
-
- private:
- /// Replace with a (mostly) real path, or don't modify. Resolves symlinks
- /// in the directory, using \a CachedDirs to avoid redundant lookups, but
- /// leaves the filename as a possible symlink.
- void updateWithRealPath(SmallVectorImpl<char> &Path);
-
- StringMap<std::string> CachedDirs;
- };
-
+ /// Helper utility that encapsulates the logic for canonicalizing a virtual
+ /// path and a path to copy from.
+ class PathCanonicalizer {
+ public:
+ struct PathStorage {
+ SmallString<256> CopyFrom;
+ SmallString<256> VirtualPath;
+ };
+
+ /// Canonicalize a pair of virtual and real paths.
+ PathStorage canonicalize(StringRef SrcPath);
+
+ private:
+ /// Replace with a (mostly) real path, or don't modify. Resolves symlinks
+ /// in the directory, using \a CachedDirs to avoid redundant lookups, but
+ /// leaves the filename as a possible symlink.
+ void updateWithRealPath(SmallVectorImpl<char> &Path);
+
+ StringMap<std::string> CachedDirs;
+ };
+
/// \p Root is the directory where collected files are will be stored.
/// \p OverlayRoot is VFS mapping root.
/// \p Root directory gets created in copyFiles unless it already exists.
@@ -129,12 +129,12 @@ private:
}
protected:
- void addFileImpl(StringRef SrcPath) override;
+ void addFileImpl(StringRef SrcPath) override;
llvm::vfs::directory_iterator
addDirectoryImpl(const llvm::Twine &Dir,
- IntrusiveRefCntPtr<vfs::FileSystem> FS,
- std::error_code &EC) override;
+ IntrusiveRefCntPtr<vfs::FileSystem> FS,
+ std::error_code &EC) override;
/// The directory where collected files are copied to in copyFiles().
const std::string Root;
@@ -145,8 +145,8 @@ protected:
/// The yaml mapping writer.
vfs::YAMLVFSWriter VFSWriter;
- /// Helper utility for canonicalizing paths.
- PathCanonicalizer Canonicalizer;
+ /// Helper utility for canonicalizing paths.
+ PathCanonicalizer Canonicalizer;
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Support/FileSystem.h b/contrib/libs/llvm12/include/llvm/Support/FileSystem.h
index bdd39d4e61..4e3ef16c8a 100644
--- a/contrib/libs/llvm12/include/llvm/Support/FileSystem.h
+++ b/contrib/libs/llvm12/include/llvm/Support/FileSystem.h
@@ -41,7 +41,7 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/FileSystem/UniqueID.h"
+#include "llvm/Support/FileSystem/UniqueID.h"
#include "llvm/Support/MD5.h"
#include <cassert>
#include <cstdint>
@@ -1118,43 +1118,43 @@ Expected<file_t>
openNativeFileForRead(const Twine &Name, OpenFlags Flags = OF_None,
SmallVectorImpl<char> *RealPath = nullptr);
-/// Try to locks the file during the specified time.
-///
-/// This function implements advisory locking on entire file. If it returns
-/// <em>errc::success</em>, the file is locked by the calling process. Until the
-/// process unlocks the file by calling \a unlockFile, all attempts to lock the
-/// same file will fail/block. The process that locked the file may assume that
-/// none of other processes read or write this file, provided that all processes
-/// lock the file prior to accessing its content.
-///
-/// @param FD The descriptor representing the file to lock.
-/// @param Timeout Time in milliseconds that the process should wait before
-/// reporting lock failure. Zero value means try to get lock only
-/// once.
-/// @returns errc::success if lock is successfully obtained,
-/// errc::no_lock_available if the file cannot be locked, or platform-specific
-/// error_code otherwise.
-///
-/// @note Care should be taken when using this function in a multithreaded
-/// context, as it may not prevent other threads in the same process from
-/// obtaining a lock on the same file, even if they are using a different file
-/// descriptor.
-std::error_code
-tryLockFile(int FD,
- std::chrono::milliseconds Timeout = std::chrono::milliseconds(0));
-
-/// Lock the file.
-///
-/// This function acts as @ref tryLockFile but it waits infinitely.
-std::error_code lockFile(int FD);
-
-/// Unlock the file.
-///
-/// @param FD The descriptor representing the file to unlock.
-/// @returns errc::success if lock is successfully released or platform-specific
-/// error_code otherwise.
-std::error_code unlockFile(int FD);
-
+/// Try to locks the file during the specified time.
+///
+/// This function implements advisory locking on entire file. If it returns
+/// <em>errc::success</em>, the file is locked by the calling process. Until the
+/// process unlocks the file by calling \a unlockFile, all attempts to lock the
+/// same file will fail/block. The process that locked the file may assume that
+/// none of other processes read or write this file, provided that all processes
+/// lock the file prior to accessing its content.
+///
+/// @param FD The descriptor representing the file to lock.
+/// @param Timeout Time in milliseconds that the process should wait before
+/// reporting lock failure. Zero value means try to get lock only
+/// once.
+/// @returns errc::success if lock is successfully obtained,
+/// errc::no_lock_available if the file cannot be locked, or platform-specific
+/// error_code otherwise.
+///
+/// @note Care should be taken when using this function in a multithreaded
+/// context, as it may not prevent other threads in the same process from
+/// obtaining a lock on the same file, even if they are using a different file
+/// descriptor.
+std::error_code
+tryLockFile(int FD,
+ std::chrono::milliseconds Timeout = std::chrono::milliseconds(0));
+
+/// Lock the file.
+///
+/// This function acts as @ref tryLockFile but it waits infinitely.
+std::error_code lockFile(int FD);
+
+/// Unlock the file.
+///
+/// @param FD The descriptor representing the file to unlock.
+/// @returns errc::success if lock is successfully released or platform-specific
+/// error_code otherwise.
+std::error_code unlockFile(int FD);
+
/// @brief Close the file object. This should be used instead of ::close for
/// portability. On error, the caller should assume the file is closed, as is
/// the case for Process::SafelyCloseFileDescriptor
@@ -1166,35 +1166,35 @@ std::error_code unlockFile(int FD);
/// means that the filesystem may have failed to perform some buffered writes.
std::error_code closeFile(file_t &F);
-/// RAII class that facilitates file locking.
-class FileLocker {
- int FD; ///< Locked file handle.
- FileLocker(int FD) : FD(FD) {}
- friend class llvm::raw_fd_ostream;
-
-public:
- FileLocker(const FileLocker &L) = delete;
- FileLocker(FileLocker &&L) : FD(L.FD) { L.FD = -1; }
- ~FileLocker() {
- if (FD != -1)
- unlockFile(FD);
- }
- FileLocker &operator=(FileLocker &&L) {
- FD = L.FD;
- L.FD = -1;
- return *this;
- }
- FileLocker &operator=(const FileLocker &L) = delete;
- std::error_code unlock() {
- if (FD != -1) {
- std::error_code Result = unlockFile(FD);
- FD = -1;
- return Result;
- }
- return std::error_code();
- }
-};
-
+/// RAII class that facilitates file locking.
+class FileLocker {
+ int FD; ///< Locked file handle.
+ FileLocker(int FD) : FD(FD) {}
+ friend class llvm::raw_fd_ostream;
+
+public:
+ FileLocker(const FileLocker &L) = delete;
+ FileLocker(FileLocker &&L) : FD(L.FD) { L.FD = -1; }
+ ~FileLocker() {
+ if (FD != -1)
+ unlockFile(FD);
+ }
+ FileLocker &operator=(FileLocker &&L) {
+ FD = L.FD;
+ L.FD = -1;
+ return *this;
+ }
+ FileLocker &operator=(const FileLocker &L) = delete;
+ std::error_code unlock() {
+ if (FD != -1) {
+ std::error_code Result = unlockFile(FD);
+ FD = -1;
+ return Result;
+ }
+ return std::error_code();
+ }
+};
+
std::error_code getUniqueID(const Twine Path, UniqueID &Result);
/// Get disk space usage information.
diff --git a/contrib/libs/llvm12/include/llvm/Support/FileSystem/UniqueID.h b/contrib/libs/llvm12/include/llvm/Support/FileSystem/UniqueID.h
index 0703ff4d73..fffe35db83 100644
--- a/contrib/libs/llvm12/include/llvm/Support/FileSystem/UniqueID.h
+++ b/contrib/libs/llvm12/include/llvm/Support/FileSystem/UniqueID.h
@@ -1,63 +1,63 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- llvm/Support/FileSystem/UniqueID.h - UniqueID for files --*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is cut out of llvm/Support/FileSystem.h to allow UniqueID to be
-// reused without bloating the includes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_FILESYSTEM_UNIQUEID_H
-#define LLVM_SUPPORT_FILESYSTEM_UNIQUEID_H
-
-#include <cstdint>
-
-namespace llvm {
-namespace sys {
-namespace fs {
-
-class UniqueID {
- uint64_t Device;
- uint64_t File;
-
-public:
- UniqueID() = default;
- UniqueID(uint64_t Device, uint64_t File) : Device(Device), File(File) {}
-
- bool operator==(const UniqueID &Other) const {
- return Device == Other.Device && File == Other.File;
- }
- bool operator!=(const UniqueID &Other) const { return !(*this == Other); }
- bool operator<(const UniqueID &Other) const {
- /// Don't use std::tie since it bloats the compile time of this header.
- if (Device < Other.Device)
- return true;
- if (Other.Device < Device)
- return false;
- return File < Other.File;
- }
-
- uint64_t getDevice() const { return Device; }
- uint64_t getFile() const { return File; }
-};
-
-} // end namespace fs
-} // end namespace sys
-} // end namespace llvm
-
-#endif // LLVM_SUPPORT_FILESYSTEM_UNIQUEID_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- llvm/Support/FileSystem/UniqueID.h - UniqueID for files --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is cut out of llvm/Support/FileSystem.h to allow UniqueID to be
+// reused without bloating the includes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_FILESYSTEM_UNIQUEID_H
+#define LLVM_SUPPORT_FILESYSTEM_UNIQUEID_H
+
+#include <cstdint>
+
+namespace llvm {
+namespace sys {
+namespace fs {
+
+class UniqueID {
+ uint64_t Device;
+ uint64_t File;
+
+public:
+ UniqueID() = default;
+ UniqueID(uint64_t Device, uint64_t File) : Device(Device), File(File) {}
+
+ bool operator==(const UniqueID &Other) const {
+ return Device == Other.Device && File == Other.File;
+ }
+ bool operator!=(const UniqueID &Other) const { return !(*this == Other); }
+ bool operator<(const UniqueID &Other) const {
+ /// Don't use std::tie since it bloats the compile time of this header.
+ if (Device < Other.Device)
+ return true;
+ if (Other.Device < Device)
+ return false;
+ return File < Other.File;
+ }
+
+ uint64_t getDevice() const { return Device; }
+ uint64_t getFile() const { return File; }
+};
+
+} // end namespace fs
+} // end namespace sys
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_FILESYSTEM_UNIQUEID_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Support/FormatVariadic.h b/contrib/libs/llvm12/include/llvm/Support/FormatVariadic.h
index f9375ed667..3634b0bac6 100644
--- a/contrib/libs/llvm12/include/llvm/Support/FormatVariadic.h
+++ b/contrib/libs/llvm12/include/llvm/Support/FormatVariadic.h
@@ -212,10 +212,10 @@ public:
//
// The characters '{' and '}' are reserved and cannot appear anywhere within a
// replacement sequence. Outside of a replacement sequence, in order to print
-// a literal '{' it must be doubled as "{{".
+// a literal '{' it must be doubled as "{{".
//
// ===Parameter Indexing===
-//
+//
// `index` specifies the index of the parameter in the parameter pack to format
// into the output. Note that it is possible to refer to the same parameter
// index multiple times in a given format string. This makes it possible to
diff --git a/contrib/libs/llvm12/include/llvm/Support/GenericDomTree.h b/contrib/libs/llvm12/include/llvm/Support/GenericDomTree.h
index 291da3802f..3c5b6057c1 100644
--- a/contrib/libs/llvm12/include/llvm/Support/GenericDomTree.h
+++ b/contrib/libs/llvm12/include/llvm/Support/GenericDomTree.h
@@ -35,7 +35,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/CFGDiff.h"
+#include "llvm/Support/CFGDiff.h"
#include "llvm/Support/CFGUpdate.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -67,7 +67,7 @@ template <class NodeT> class DomTreeNodeBase {
NodeT *TheBB;
DomTreeNodeBase *IDom;
unsigned Level;
- SmallVector<DomTreeNodeBase *, 4> Children;
+ SmallVector<DomTreeNodeBase *, 4> Children;
mutable unsigned DFSNumIn = ~0;
mutable unsigned DFSNumOut = ~0;
@@ -75,9 +75,9 @@ template <class NodeT> class DomTreeNodeBase {
DomTreeNodeBase(NodeT *BB, DomTreeNodeBase *iDom)
: TheBB(BB), IDom(iDom), Level(IDom ? IDom->Level + 1 : 0) {}
- using iterator = typename SmallVector<DomTreeNodeBase *, 4>::iterator;
+ using iterator = typename SmallVector<DomTreeNodeBase *, 4>::iterator;
using const_iterator =
- typename SmallVector<DomTreeNodeBase *, 4>::const_iterator;
+ typename SmallVector<DomTreeNodeBase *, 4>::const_iterator;
iterator begin() { return Children.begin(); }
iterator end() { return Children.end(); }
@@ -218,10 +218,10 @@ void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
template <typename DomTreeT>
void ApplyUpdates(DomTreeT &DT,
- GraphDiff<typename DomTreeT::NodePtr,
- DomTreeT::IsPostDominator> &PreViewCFG,
- GraphDiff<typename DomTreeT::NodePtr,
- DomTreeT::IsPostDominator> *PostViewCFG);
+ GraphDiff<typename DomTreeT::NodePtr,
+ DomTreeT::IsPostDominator> &PreViewCFG,
+ GraphDiff<typename DomTreeT::NodePtr,
+ DomTreeT::IsPostDominator> *PostViewCFG);
template <typename DomTreeT>
bool Verify(const DomTreeT &DT, typename DomTreeT::VerificationLevel VL);
@@ -470,8 +470,8 @@ protected:
return this->Roots[0];
}
- /// Find nearest common dominator basic block for basic block A and B. A and B
- /// must have tree nodes.
+ /// Find nearest common dominator basic block for basic block A and B. A and B
+ /// must have tree nodes.
NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) const {
assert(A && B && "Pointers are not valid");
assert(A->getParent() == B->getParent() &&
@@ -487,18 +487,18 @@ protected:
DomTreeNodeBase<NodeT> *NodeA = getNode(A);
DomTreeNodeBase<NodeT> *NodeB = getNode(B);
- assert(NodeA && "A must be in the tree");
- assert(NodeB && "B must be in the tree");
+ assert(NodeA && "A must be in the tree");
+ assert(NodeB && "B must be in the tree");
// Use level information to go up the tree until the levels match. Then
// continue going up til we arrive at the same node.
- while (NodeA != NodeB) {
+ while (NodeA != NodeB) {
if (NodeA->getLevel() < NodeB->getLevel()) std::swap(NodeA, NodeB);
NodeA = NodeA->IDom;
}
- return NodeA->getBlock();
+ return NodeA->getBlock();
}
const NodeT *findNearestCommonDominator(const NodeT *A,
@@ -545,41 +545,41 @@ protected:
/// The type of updates is the same for DomTreeBase<T> and PostDomTreeBase<T>
/// with the same template parameter T.
///
- /// \param Updates An unordered sequence of updates to perform. The current
- /// CFG and the reverse of these updates provides the pre-view of the CFG.
+ /// \param Updates An unordered sequence of updates to perform. The current
+ /// CFG and the reverse of these updates provides the pre-view of the CFG.
///
void applyUpdates(ArrayRef<UpdateType> Updates) {
- GraphDiff<NodePtr, IsPostDominator> PreViewCFG(
- Updates, /*ReverseApplyUpdates=*/true);
- DomTreeBuilder::ApplyUpdates(*this, PreViewCFG, nullptr);
- }
-
- /// \param Updates An unordered sequence of updates to perform. The current
- /// CFG and the reverse of these updates provides the pre-view of the CFG.
- /// \param PostViewUpdates An unordered sequence of update to perform in order
- /// to obtain a post-view of the CFG. The DT will be updated assuming the
- /// obtained PostViewCFG is the desired end state.
- void applyUpdates(ArrayRef<UpdateType> Updates,
- ArrayRef<UpdateType> PostViewUpdates) {
- if (Updates.empty()) {
- GraphDiff<NodePtr, IsPostDom> PostViewCFG(PostViewUpdates);
- DomTreeBuilder::ApplyUpdates(*this, PostViewCFG, &PostViewCFG);
- } else {
- // PreViewCFG needs to merge Updates and PostViewCFG. The updates in
- // Updates need to be reversed, and match the direction in PostViewCFG.
- // The PostViewCFG is created with updates reversed (equivalent to changes
- // made to the CFG), so the PreViewCFG needs all the updates reverse
- // applied.
- SmallVector<UpdateType> AllUpdates(Updates.begin(), Updates.end());
- for (auto &Update : PostViewUpdates)
- AllUpdates.push_back(Update);
- GraphDiff<NodePtr, IsPostDom> PreViewCFG(AllUpdates,
- /*ReverseApplyUpdates=*/true);
- GraphDiff<NodePtr, IsPostDom> PostViewCFG(PostViewUpdates);
- DomTreeBuilder::ApplyUpdates(*this, PreViewCFG, &PostViewCFG);
- }
- }
-
+ GraphDiff<NodePtr, IsPostDominator> PreViewCFG(
+ Updates, /*ReverseApplyUpdates=*/true);
+ DomTreeBuilder::ApplyUpdates(*this, PreViewCFG, nullptr);
+ }
+
+ /// \param Updates An unordered sequence of updates to perform. The current
+ /// CFG and the reverse of these updates provides the pre-view of the CFG.
+ /// \param PostViewUpdates An unordered sequence of update to perform in order
+ /// to obtain a post-view of the CFG. The DT will be updated assuming the
+ /// obtained PostViewCFG is the desired end state.
+ void applyUpdates(ArrayRef<UpdateType> Updates,
+ ArrayRef<UpdateType> PostViewUpdates) {
+ if (Updates.empty()) {
+ GraphDiff<NodePtr, IsPostDom> PostViewCFG(PostViewUpdates);
+ DomTreeBuilder::ApplyUpdates(*this, PostViewCFG, &PostViewCFG);
+ } else {
+ // PreViewCFG needs to merge Updates and PostViewCFG. The updates in
+ // Updates need to be reversed, and match the direction in PostViewCFG.
+ // The PostViewCFG is created with updates reversed (equivalent to changes
+ // made to the CFG), so the PreViewCFG needs all the updates reverse
+ // applied.
+ SmallVector<UpdateType> AllUpdates(Updates.begin(), Updates.end());
+ for (auto &Update : PostViewUpdates)
+ AllUpdates.push_back(Update);
+ GraphDiff<NodePtr, IsPostDom> PreViewCFG(AllUpdates,
+ /*ReverseApplyUpdates=*/true);
+ GraphDiff<NodePtr, IsPostDom> PostViewCFG(PostViewUpdates);
+ DomTreeBuilder::ApplyUpdates(*this, PreViewCFG, &PostViewCFG);
+ }
+ }
+
/// Inform the dominator tree about a CFG edge insertion and update the tree.
///
/// This function has to be called just before or just after making the update
@@ -846,7 +846,7 @@ protected:
"NewBB should have a single successor!");
NodeRef NewBBSucc = *GraphT::child_begin(NewBB);
- SmallVector<NodeRef, 4> PredBlocks(children<Inverse<N>>(NewBB));
+ SmallVector<NodeRef, 4> PredBlocks(children<Inverse<N>>(NewBB));
assert(!PredBlocks.empty() && "No predblocks?");
diff --git a/contrib/libs/llvm12/include/llvm/Support/GenericDomTreeConstruction.h b/contrib/libs/llvm12/include/llvm/Support/GenericDomTreeConstruction.h
index 0298e20795..9d3248b877 100644
--- a/contrib/libs/llvm12/include/llvm/Support/GenericDomTreeConstruction.h
+++ b/contrib/libs/llvm12/include/llvm/Support/GenericDomTreeConstruction.h
@@ -65,7 +65,7 @@ struct SemiNCAInfo {
using TreeNodePtr = DomTreeNodeBase<NodeT> *;
using RootsT = decltype(DomTreeT::Roots);
static constexpr bool IsPostDom = DomTreeT::IsPostDominator;
- using GraphDiffT = GraphDiff<NodePtr, IsPostDom>;
+ using GraphDiffT = GraphDiff<NodePtr, IsPostDom>;
// Information record used by Semi-NCA during tree construction.
struct InfoRec {
@@ -85,17 +85,17 @@ struct SemiNCAInfo {
using UpdateT = typename DomTreeT::UpdateType;
using UpdateKind = typename DomTreeT::UpdateKind;
struct BatchUpdateInfo {
- // Note: Updates inside PreViewCFG are aleady legalized.
- BatchUpdateInfo(GraphDiffT &PreViewCFG, GraphDiffT *PostViewCFG = nullptr)
- : PreViewCFG(PreViewCFG), PostViewCFG(PostViewCFG),
- NumLegalized(PreViewCFG.getNumLegalizedUpdates()) {}
+ // Note: Updates inside PreViewCFG are aleady legalized.
+ BatchUpdateInfo(GraphDiffT &PreViewCFG, GraphDiffT *PostViewCFG = nullptr)
+ : PreViewCFG(PreViewCFG), PostViewCFG(PostViewCFG),
+ NumLegalized(PreViewCFG.getNumLegalizedUpdates()) {}
// Remembers if the whole tree was recalculated at some point during the
// current batch update.
bool IsRecalculated = false;
- GraphDiffT &PreViewCFG;
- GraphDiffT *PostViewCFG;
- const size_t NumLegalized;
+ GraphDiffT &PreViewCFG;
+ GraphDiffT *PostViewCFG;
+ const size_t NumLegalized;
};
BatchUpdateInfo *BatchUpdates;
@@ -111,24 +111,24 @@ struct SemiNCAInfo {
// in progress, we need this information to continue it.
}
- template <bool Inversed>
- static SmallVector<NodePtr, 8> getChildren(NodePtr N, BatchUpdatePtr BUI) {
- if (BUI)
- return BUI->PreViewCFG.template getChildren<Inversed>(N);
- return getChildren<Inversed>(N);
- }
-
- template <bool Inversed>
- static SmallVector<NodePtr, 8> getChildren(NodePtr N) {
- using DirectedNodeT =
- std::conditional_t<Inversed, Inverse<NodePtr>, NodePtr>;
- auto R = children<DirectedNodeT>(N);
- SmallVector<NodePtr, 8> Res(detail::reverse_if<!Inversed>(R));
-
- // Remove nullptr children for clang.
- llvm::erase_value(Res, nullptr);
- return Res;
- }
+ template <bool Inversed>
+ static SmallVector<NodePtr, 8> getChildren(NodePtr N, BatchUpdatePtr BUI) {
+ if (BUI)
+ return BUI->PreViewCFG.template getChildren<Inversed>(N);
+ return getChildren<Inversed>(N);
+ }
+
+ template <bool Inversed>
+ static SmallVector<NodePtr, 8> getChildren(NodePtr N) {
+ using DirectedNodeT =
+ std::conditional_t<Inversed, Inverse<NodePtr>, NodePtr>;
+ auto R = children<DirectedNodeT>(N);
+ SmallVector<NodePtr, 8> Res(detail::reverse_if<!Inversed>(R));
+
+ // Remove nullptr children for clang.
+ llvm::erase_value(Res, nullptr);
+ return Res;
+ }
NodePtr getIDom(NodePtr BB) const {
auto InfoIt = NodeToInfo.find(BB);
@@ -170,8 +170,8 @@ struct SemiNCAInfo {
}
};
- using NodeOrderMap = DenseMap<NodePtr, unsigned>;
-
+ using NodeOrderMap = DenseMap<NodePtr, unsigned>;
+
// Custom DFS implementation which can skip nodes based on a provided
// predicate. It also collects ReverseChildren so that we don't have to spend
// time getting predecessors in SemiNCA.
@@ -179,13 +179,13 @@ struct SemiNCAInfo {
// If IsReverse is set to true, the DFS walk will be performed backwards
// relative to IsPostDom -- using reverse edges for dominators and forward
// edges for postdominators.
- //
- // If SuccOrder is specified then in this order the DFS traverses the children
- // otherwise the order is implied by the results of getChildren().
+ //
+ // If SuccOrder is specified then in this order the DFS traverses the children
+ // otherwise the order is implied by the results of getChildren().
template <bool IsReverse = false, typename DescendCondition>
unsigned runDFS(NodePtr V, unsigned LastNum, DescendCondition Condition,
- unsigned AttachToNum,
- const NodeOrderMap *SuccOrder = nullptr) {
+ unsigned AttachToNum,
+ const NodeOrderMap *SuccOrder = nullptr) {
assert(V);
SmallVector<NodePtr, 64> WorkList = {V};
if (NodeToInfo.count(V) != 0) NodeToInfo[V].Parent = AttachToNum;
@@ -201,14 +201,14 @@ struct SemiNCAInfo {
NumToNode.push_back(BB);
constexpr bool Direction = IsReverse != IsPostDom; // XOR.
- auto Successors = getChildren<Direction>(BB, BatchUpdates);
- if (SuccOrder && Successors.size() > 1)
- llvm::sort(
- Successors.begin(), Successors.end(), [=](NodePtr A, NodePtr B) {
- return SuccOrder->find(A)->second < SuccOrder->find(B)->second;
- });
-
- for (const NodePtr Succ : Successors) {
+ auto Successors = getChildren<Direction>(BB, BatchUpdates);
+ if (SuccOrder && Successors.size() > 1)
+ llvm::sort(
+ Successors.begin(), Successors.end(), [=](NodePtr A, NodePtr B) {
+ return SuccOrder->find(A)->second < SuccOrder->find(B)->second;
+ });
+
+ for (const NodePtr Succ : Successors) {
const auto SIT = NodeToInfo.find(Succ);
// Don't visit nodes more than once but remember to collect
// ReverseChildren.
@@ -343,7 +343,7 @@ struct SemiNCAInfo {
// to CFG nodes within infinite loops.
static bool HasForwardSuccessors(const NodePtr N, BatchUpdatePtr BUI) {
assert(N && "N must be a valid node");
- return !getChildren<false>(N, BUI).empty();
+ return !getChildren<false>(N, BUI).empty();
}
static NodePtr GetEntryNode(const DomTreeT &DT) {
@@ -404,32 +404,32 @@ struct SemiNCAInfo {
// nodes.
if (Total + 1 != Num) {
HasNonTrivialRoots = true;
-
- // SuccOrder is the order of blocks in the function. It is needed to make
- // the calculation of the FurthestAway node and the whole PostDomTree
- // immune to swap successors transformation (e.g. canonicalizing branch
- // predicates). SuccOrder is initialized lazily only for successors of
- // reverse unreachable nodes.
- Optional<NodeOrderMap> SuccOrder;
- auto InitSuccOrderOnce = [&]() {
- SuccOrder = NodeOrderMap();
- for (const auto Node : nodes(DT.Parent))
- if (SNCA.NodeToInfo.count(Node) == 0)
- for (const auto Succ : getChildren<false>(Node, SNCA.BatchUpdates))
- SuccOrder->try_emplace(Succ, 0);
-
- // Add mapping for all entries of SuccOrder.
- unsigned NodeNum = 0;
- for (const auto Node : nodes(DT.Parent)) {
- ++NodeNum;
- auto Order = SuccOrder->find(Node);
- if (Order != SuccOrder->end()) {
- assert(Order->second == 0);
- Order->second = NodeNum;
- }
- }
- };
-
+
+ // SuccOrder is the order of blocks in the function. It is needed to make
+ // the calculation of the FurthestAway node and the whole PostDomTree
+ // immune to swap successors transformation (e.g. canonicalizing branch
+ // predicates). SuccOrder is initialized lazily only for successors of
+ // reverse unreachable nodes.
+ Optional<NodeOrderMap> SuccOrder;
+ auto InitSuccOrderOnce = [&]() {
+ SuccOrder = NodeOrderMap();
+ for (const auto Node : nodes(DT.Parent))
+ if (SNCA.NodeToInfo.count(Node) == 0)
+ for (const auto Succ : getChildren<false>(Node, SNCA.BatchUpdates))
+ SuccOrder->try_emplace(Succ, 0);
+
+ // Add mapping for all entries of SuccOrder.
+ unsigned NodeNum = 0;
+ for (const auto Node : nodes(DT.Parent)) {
+ ++NodeNum;
+ auto Order = SuccOrder->find(Node);
+ if (Order != SuccOrder->end()) {
+ assert(Order->second == 0);
+ Order->second = NodeNum;
+ }
+ }
+ };
+
// Make another DFS pass over all other nodes to find the
// reverse-unreachable blocks, and find the furthest paths we'll be able
// to make.
@@ -454,12 +454,12 @@ struct SemiNCAInfo {
// expensive and does not always lead to a minimal set of roots.
LLVM_DEBUG(dbgs() << "\t\t\tRunning forward DFS\n");
- if (!SuccOrder)
- InitSuccOrderOnce();
- assert(SuccOrder);
-
- const unsigned NewNum =
- SNCA.runDFS<true>(I, Num, AlwaysDescend, Num, &*SuccOrder);
+ if (!SuccOrder)
+ InitSuccOrderOnce();
+ assert(SuccOrder);
+
+ const unsigned NewNum =
+ SNCA.runDFS<true>(I, Num, AlwaysDescend, Num, &*SuccOrder);
const NodePtr FurthestAway = SNCA.NumToNode[NewNum];
LLVM_DEBUG(dbgs() << "\t\t\tFound a new furthest away node "
<< "(non-trivial root): "
@@ -535,7 +535,7 @@ struct SemiNCAInfo {
// If we wound another root in a (forward) DFS walk, remove the current
// root from the set of roots, as it is reverse-reachable from the other
// one.
- if (llvm::is_contained(Roots, N)) {
+ if (llvm::is_contained(Roots, N)) {
LLVM_DEBUG(dbgs() << "\tForward DFS walk found another root "
<< BlockNamePrinter(N) << "\n\tRemoving root "
<< BlockNamePrinter(Root) << "\n");
@@ -568,21 +568,21 @@ struct SemiNCAInfo {
auto *Parent = DT.Parent;
DT.reset();
DT.Parent = Parent;
- // If the update is using the actual CFG, BUI is null. If it's using a view,
- // BUI is non-null and the PreCFGView is used. When calculating from
- // scratch, make the PreViewCFG equal to the PostCFGView, so Post is used.
- BatchUpdatePtr PostViewBUI = nullptr;
- if (BUI && BUI->PostViewCFG) {
- BUI->PreViewCFG = *BUI->PostViewCFG;
- PostViewBUI = BUI;
- }
- // This is rebuilding the whole tree, not incrementally, but PostViewBUI is
- // used in case the caller needs a DT update with a CFGView.
- SemiNCAInfo SNCA(PostViewBUI);
+ // If the update is using the actual CFG, BUI is null. If it's using a view,
+ // BUI is non-null and the PreCFGView is used. When calculating from
+ // scratch, make the PreViewCFG equal to the PostCFGView, so Post is used.
+ BatchUpdatePtr PostViewBUI = nullptr;
+ if (BUI && BUI->PostViewCFG) {
+ BUI->PreViewCFG = *BUI->PostViewCFG;
+ PostViewBUI = BUI;
+ }
+ // This is rebuilding the whole tree, not incrementally, but PostViewBUI is
+ // used in case the caller needs a DT update with a CFGView.
+ SemiNCAInfo SNCA(PostViewBUI);
// Step #0: Number blocks in depth-first order and initialize variables used
// in later stages of the algorithm.
- DT.Roots = FindRoots(DT, PostViewBUI);
+ DT.Roots = FindRoots(DT, PostViewBUI);
SNCA.doFullDFSWalk(DT, AlwaysDescend);
SNCA.runSemiNCA(DT);
@@ -693,7 +693,7 @@ struct SemiNCAInfo {
// root.
if (!DT.isVirtualRoot(To->getIDom())) return false;
- if (!llvm::is_contained(DT.Roots, To->getBlock()))
+ if (!llvm::is_contained(DT.Roots, To->getBlock()))
return false; // To is not a root, nothing to update.
LLVM_DEBUG(dbgs() << "\t\tAfter the insertion, " << BlockNamePrinter(To)
@@ -800,7 +800,7 @@ struct SemiNCAInfo {
//
// Invariant: there is an optimal path from `To` to TN with the minimum
// depth being CurrentLevel.
- for (const NodePtr Succ : getChildren<IsPostDom>(TN->getBlock(), BUI)) {
+ for (const NodePtr Succ : getChildren<IsPostDom>(TN->getBlock(), BUI)) {
const TreeNodePtr SuccTN = DT.getNode(Succ);
assert(SuccTN &&
"Unreachable successor found at reachable insertion");
@@ -930,8 +930,8 @@ struct SemiNCAInfo {
// the DomTree about it.
// The check is O(N), so run it only in debug configuration.
auto IsSuccessor = [BUI](const NodePtr SuccCandidate, const NodePtr Of) {
- auto Successors = getChildren<IsPostDom>(Of, BUI);
- return llvm::is_contained(Successors, SuccCandidate);
+ auto Successors = getChildren<IsPostDom>(Of, BUI);
+ return llvm::is_contained(Successors, SuccCandidate);
};
(void)IsSuccessor;
assert(!IsSuccessor(To, From) && "Deleted edge still exists in the CFG!");
@@ -1017,14 +1017,14 @@ struct SemiNCAInfo {
const TreeNodePtr TN) {
LLVM_DEBUG(dbgs() << "IsReachableFromIDom " << BlockNamePrinter(TN)
<< "\n");
- auto TNB = TN->getBlock();
- for (const NodePtr Pred : getChildren<!IsPostDom>(TNB, BUI)) {
+ auto TNB = TN->getBlock();
+ for (const NodePtr Pred : getChildren<!IsPostDom>(TNB, BUI)) {
LLVM_DEBUG(dbgs() << "\tPred " << BlockNamePrinter(Pred) << "\n");
if (!DT.getNode(Pred)) continue;
- const NodePtr Support = DT.findNearestCommonDominator(TNB, Pred);
+ const NodePtr Support = DT.findNearestCommonDominator(TNB, Pred);
LLVM_DEBUG(dbgs() << "\tSupport " << BlockNamePrinter(Support) << "\n");
- if (Support != TNB) {
+ if (Support != TNB) {
LLVM_DEBUG(dbgs() << "\t" << BlockNamePrinter(TN)
<< " is reachable from support "
<< BlockNamePrinter(Support) << "\n");
@@ -1065,7 +1065,7 @@ struct SemiNCAInfo {
const TreeNodePtr TN = DT.getNode(To);
assert(TN);
if (TN->getLevel() > Level) return true;
- if (!llvm::is_contained(AffectedQueue, To))
+ if (!llvm::is_contained(AffectedQueue, To))
AffectedQueue.push_back(To);
return false;
@@ -1155,34 +1155,34 @@ struct SemiNCAInfo {
//===--------------------- DomTree Batch Updater --------------------------===
//~~
- static void ApplyUpdates(DomTreeT &DT, GraphDiffT &PreViewCFG,
- GraphDiffT *PostViewCFG) {
- // Note: the PostViewCFG is only used when computing from scratch. It's data
- // should already included in the PreViewCFG for incremental updates.
- const size_t NumUpdates = PreViewCFG.getNumLegalizedUpdates();
+ static void ApplyUpdates(DomTreeT &DT, GraphDiffT &PreViewCFG,
+ GraphDiffT *PostViewCFG) {
+ // Note: the PostViewCFG is only used when computing from scratch. It's data
+ // should already included in the PreViewCFG for incremental updates.
+ const size_t NumUpdates = PreViewCFG.getNumLegalizedUpdates();
if (NumUpdates == 0)
return;
// Take the fast path for a single update and avoid running the batch update
// machinery.
if (NumUpdates == 1) {
- UpdateT Update = PreViewCFG.popUpdateForIncrementalUpdates();
- if (!PostViewCFG) {
- if (Update.getKind() == UpdateKind::Insert)
- InsertEdge(DT, /*BUI=*/nullptr, Update.getFrom(), Update.getTo());
- else
- DeleteEdge(DT, /*BUI=*/nullptr, Update.getFrom(), Update.getTo());
- } else {
- BatchUpdateInfo BUI(*PostViewCFG, PostViewCFG);
- if (Update.getKind() == UpdateKind::Insert)
- InsertEdge(DT, &BUI, Update.getFrom(), Update.getTo());
- else
- DeleteEdge(DT, &BUI, Update.getFrom(), Update.getTo());
- }
+ UpdateT Update = PreViewCFG.popUpdateForIncrementalUpdates();
+ if (!PostViewCFG) {
+ if (Update.getKind() == UpdateKind::Insert)
+ InsertEdge(DT, /*BUI=*/nullptr, Update.getFrom(), Update.getTo());
+ else
+ DeleteEdge(DT, /*BUI=*/nullptr, Update.getFrom(), Update.getTo());
+ } else {
+ BatchUpdateInfo BUI(*PostViewCFG, PostViewCFG);
+ if (Update.getKind() == UpdateKind::Insert)
+ InsertEdge(DT, &BUI, Update.getFrom(), Update.getTo());
+ else
+ DeleteEdge(DT, &BUI, Update.getFrom(), Update.getTo());
+ }
return;
}
- BatchUpdateInfo BUI(PreViewCFG, PostViewCFG);
+ BatchUpdateInfo BUI(PreViewCFG, PostViewCFG);
// Recalculate the DominatorTree when the number of updates
// exceeds a threshold, which usually makes direct updating slower than
// recalculation. We select this threshold proportional to the
@@ -1192,21 +1192,21 @@ struct SemiNCAInfo {
// Make unittests of the incremental algorithm work
if (DT.DomTreeNodes.size() <= 100) {
- if (BUI.NumLegalized > DT.DomTreeNodes.size())
+ if (BUI.NumLegalized > DT.DomTreeNodes.size())
CalculateFromScratch(DT, &BUI);
- } else if (BUI.NumLegalized > DT.DomTreeNodes.size() / 40)
+ } else if (BUI.NumLegalized > DT.DomTreeNodes.size() / 40)
CalculateFromScratch(DT, &BUI);
// If the DominatorTree was recalculated at some point, stop the batch
// updates. Full recalculations ignore batch updates and look at the actual
// CFG.
- for (size_t i = 0; i < BUI.NumLegalized && !BUI.IsRecalculated; ++i)
+ for (size_t i = 0; i < BUI.NumLegalized && !BUI.IsRecalculated; ++i)
ApplyNextUpdate(DT, BUI);
}
static void ApplyNextUpdate(DomTreeT &DT, BatchUpdateInfo &BUI) {
- // Popping the next update, will move the PreViewCFG to the next snapshot.
- UpdateT CurrentUpdate = BUI.PreViewCFG.popUpdateForIncrementalUpdates();
+ // Popping the next update, will move the PreViewCFG to the next snapshot.
+ UpdateT CurrentUpdate = BUI.PreViewCFG.popUpdateForIncrementalUpdates();
#if 0
// FIXME: The LLVM_DEBUG macro only plays well with a modular
// build of LLVM when the header is marked as textual, but doing
@@ -1573,11 +1573,11 @@ void Calculate(DomTreeT &DT) {
template <typename DomTreeT>
void CalculateWithUpdates(DomTreeT &DT,
ArrayRef<typename DomTreeT::UpdateType> Updates) {
- // FIXME: Updated to use the PreViewCFG and behave the same as until now.
- // This behavior is however incorrect; this actually needs the PostViewCFG.
- GraphDiff<typename DomTreeT::NodePtr, DomTreeT::IsPostDominator> PreViewCFG(
- Updates, /*ReverseApplyUpdates=*/true);
- typename SemiNCAInfo<DomTreeT>::BatchUpdateInfo BUI(PreViewCFG);
+ // FIXME: Updated to use the PreViewCFG and behave the same as until now.
+ // This behavior is however incorrect; this actually needs the PostViewCFG.
+ GraphDiff<typename DomTreeT::NodePtr, DomTreeT::IsPostDominator> PreViewCFG(
+ Updates, /*ReverseApplyUpdates=*/true);
+ typename SemiNCAInfo<DomTreeT>::BatchUpdateInfo BUI(PreViewCFG);
SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, &BUI);
}
@@ -1597,11 +1597,11 @@ void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
template <class DomTreeT>
void ApplyUpdates(DomTreeT &DT,
- GraphDiff<typename DomTreeT::NodePtr,
- DomTreeT::IsPostDominator> &PreViewCFG,
- GraphDiff<typename DomTreeT::NodePtr,
- DomTreeT::IsPostDominator> *PostViewCFG) {
- SemiNCAInfo<DomTreeT>::ApplyUpdates(DT, PreViewCFG, PostViewCFG);
+ GraphDiff<typename DomTreeT::NodePtr,
+ DomTreeT::IsPostDominator> &PreViewCFG,
+ GraphDiff<typename DomTreeT::NodePtr,
+ DomTreeT::IsPostDominator> *PostViewCFG) {
+ SemiNCAInfo<DomTreeT>::ApplyUpdates(DT, PreViewCFG, PostViewCFG);
}
template <class DomTreeT>
diff --git a/contrib/libs/llvm12/include/llvm/Support/GlobPattern.h b/contrib/libs/llvm12/include/llvm/Support/GlobPattern.h
index 3f474af607..5e31bea143 100644
--- a/contrib/libs/llvm12/include/llvm/Support/GlobPattern.h
+++ b/contrib/libs/llvm12/include/llvm/Support/GlobPattern.h
@@ -38,16 +38,16 @@ public:
static Expected<GlobPattern> create(StringRef Pat);
bool match(StringRef S) const;
- // Returns true for glob pattern "*". Can be used to avoid expensive
- // preparation/acquisition of the input for match().
- bool isTrivialMatchAll() const {
- if (Prefix && Prefix->empty()) {
- assert(!Suffix);
- return true;
- }
- return false;
- }
-
+ // Returns true for glob pattern "*". Can be used to avoid expensive
+ // preparation/acquisition of the input for match().
+ bool isTrivialMatchAll() const {
+ if (Prefix && Prefix->empty()) {
+ assert(!Suffix);
+ return true;
+ }
+ return false;
+ }
+
private:
bool matchOne(ArrayRef<BitVector> Pat, StringRef S) const;
diff --git a/contrib/libs/llvm12/include/llvm/Support/GraphWriter.h b/contrib/libs/llvm12/include/llvm/Support/GraphWriter.h
index a92c8edac7..c4c5b8d521 100644
--- a/contrib/libs/llvm12/include/llvm/Support/GraphWriter.h
+++ b/contrib/libs/llvm12/include/llvm/Support/GraphWriter.h
@@ -165,7 +165,7 @@ public:
writeNode(Node);
}
- bool isNodeHidden(NodeRef Node) { return DTraits.isNodeHidden(Node, G); }
+ bool isNodeHidden(NodeRef Node) { return DTraits.isNodeHidden(Node, G); }
void writeNode(NodeRef Node) {
std::string NodeAttributes = DTraits.getNodeAttributes(Node, G);
@@ -233,10 +233,10 @@ public:
child_iterator EI = GTraits::child_begin(Node);
child_iterator EE = GTraits::child_end(Node);
for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i)
- if (!DTraits.isNodeHidden(*EI, G))
+ if (!DTraits.isNodeHidden(*EI, G))
writeEdge(Node, i, EI);
for (; EI != EE; ++EI)
- if (!DTraits.isNodeHidden(*EI, G))
+ if (!DTraits.isNodeHidden(*EI, G))
writeEdge(Node, 64, EI);
}
diff --git a/contrib/libs/llvm12/include/llvm/Support/Host.h b/contrib/libs/llvm12/include/llvm/Support/Host.h
index 2a1c78ffc9..5ce28816d6 100644
--- a/contrib/libs/llvm12/include/llvm/Support/Host.h
+++ b/contrib/libs/llvm12/include/llvm/Support/Host.h
@@ -72,20 +72,20 @@ namespace sys {
StringRef getHostCPUNameForARM(StringRef ProcCpuinfoContent);
StringRef getHostCPUNameForS390x(StringRef ProcCpuinfoContent);
StringRef getHostCPUNameForBPF();
-
- /// Helper functions to extract CPU details from CPUID on x86.
- namespace x86 {
- enum class VendorSignatures {
- UNKNOWN,
- GENUINE_INTEL,
- AUTHENTIC_AMD,
- };
-
- /// Returns the host CPU's vendor.
- /// MaxLeaf: if a non-nullptr pointer is specified, the EAX value will be
- /// assigned to its pointee.
- VendorSignatures getVendorSignature(unsigned *MaxLeaf = nullptr);
- } // namespace x86
+
+ /// Helper functions to extract CPU details from CPUID on x86.
+ namespace x86 {
+ enum class VendorSignatures {
+ UNKNOWN,
+ GENUINE_INTEL,
+ AUTHENTIC_AMD,
+ };
+
+ /// Returns the host CPU's vendor.
+ /// MaxLeaf: if a non-nullptr pointer is specified, the EAX value will be
+ /// assigned to its pointee.
+ VendorSignatures getVendorSignature(unsigned *MaxLeaf = nullptr);
+ } // namespace x86
}
}
}
diff --git a/contrib/libs/llvm12/include/llvm/Support/InitLLVM.h b/contrib/libs/llvm12/include/llvm/Support/InitLLVM.h
index e48dc0d429..eebbf1dea0 100644
--- a/contrib/libs/llvm12/include/llvm/Support/InitLLVM.h
+++ b/contrib/libs/llvm12/include/llvm/Support/InitLLVM.h
@@ -16,7 +16,7 @@
#ifndef LLVM_SUPPORT_LLVM_H
#define LLVM_SUPPORT_LLVM_H
-#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/PrettyStackTrace.h"
@@ -52,7 +52,7 @@ public:
private:
BumpPtrAllocator Alloc;
SmallVector<const char *, 0> Args;
- Optional<PrettyStackTraceProgram> StackPrinter;
+ Optional<PrettyStackTraceProgram> StackPrinter;
};
} // namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Support/InstructionCost.h b/contrib/libs/llvm12/include/llvm/Support/InstructionCost.h
index d357470468..0f61a6997a 100644
--- a/contrib/libs/llvm12/include/llvm/Support/InstructionCost.h
+++ b/contrib/libs/llvm12/include/llvm/Support/InstructionCost.h
@@ -1,249 +1,249 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- InstructionCost.h ----------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// This file defines an InstructionCost class that is used when calculating
-/// the cost of an instruction, or a group of instructions. In addition to a
-/// numeric value representing the cost the class also contains a state that
-/// can be used to encode particular properties, i.e. a cost being invalid or
-/// unknown.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_INSTRUCTIONCOST_H
-#define LLVM_SUPPORT_INSTRUCTIONCOST_H
-
-#include "llvm/ADT/Optional.h"
-
-namespace llvm {
-
-class raw_ostream;
-
-class InstructionCost {
-public:
- using CostType = int;
-
- /// These states can currently be used to indicate whether a cost is valid or
- /// invalid. Examples of an invalid cost might be where the cost is
- /// prohibitively expensive and the user wants to prevent certain
- /// optimizations being performed. Or perhaps the cost is simply unknown
- /// because the operation makes no sense in certain circumstances. These
- /// states can be expanded in future to support other cases if necessary.
- enum CostState { Valid, Invalid };
-
-private:
- CostType Value;
- CostState State;
-
- void propagateState(const InstructionCost &RHS) {
- if (RHS.State == Invalid)
- State = Invalid;
- }
-
-public:
- InstructionCost() = default;
-
- InstructionCost(CostState) = delete;
- InstructionCost(CostType Val) : Value(Val), State(Valid) {}
-
- static InstructionCost getInvalid(CostType Val = 0) {
- InstructionCost Tmp(Val);
- Tmp.setInvalid();
- return Tmp;
- }
-
- bool isValid() const { return State == Valid; }
- void setValid() { State = Valid; }
- void setInvalid() { State = Invalid; }
- CostState getState() const { return State; }
-
- /// This function is intended to be used as sparingly as possible, since the
- /// class provides the full range of operator support required for arithmetic
- /// and comparisons.
- Optional<CostType> getValue() const {
- if (isValid())
- return Value;
- return None;
- }
-
- /// For all of the arithmetic operators provided here any invalid state is
- /// perpetuated and cannot be removed. Once a cost becomes invalid it stays
- /// invalid, and it also inherits any invalid state from the RHS. Regardless
- /// of the state, arithmetic and comparisons work on the actual values in the
- /// same way as they would on a basic type, such as integer.
-
- InstructionCost &operator+=(const InstructionCost &RHS) {
- propagateState(RHS);
- Value += RHS.Value;
- return *this;
- }
-
- InstructionCost &operator+=(const CostType RHS) {
- InstructionCost RHS2(RHS);
- *this += RHS2;
- return *this;
- }
-
- InstructionCost &operator-=(const InstructionCost &RHS) {
- propagateState(RHS);
- Value -= RHS.Value;
- return *this;
- }
-
- InstructionCost &operator-=(const CostType RHS) {
- InstructionCost RHS2(RHS);
- *this -= RHS2;
- return *this;
- }
-
- InstructionCost &operator*=(const InstructionCost &RHS) {
- propagateState(RHS);
- Value *= RHS.Value;
- return *this;
- }
-
- InstructionCost &operator*=(const CostType RHS) {
- InstructionCost RHS2(RHS);
- *this *= RHS2;
- return *this;
- }
-
- InstructionCost &operator/=(const InstructionCost &RHS) {
- propagateState(RHS);
- Value /= RHS.Value;
- return *this;
- }
-
- InstructionCost &operator/=(const CostType RHS) {
- InstructionCost RHS2(RHS);
- *this /= RHS2;
- return *this;
- }
-
- InstructionCost &operator++() {
- *this += 1;
- return *this;
- }
-
- InstructionCost operator++(int) {
- InstructionCost Copy = *this;
- ++*this;
- return Copy;
- }
-
- InstructionCost &operator--() {
- *this -= 1;
- return *this;
- }
-
- InstructionCost operator--(int) {
- InstructionCost Copy = *this;
- --*this;
- return Copy;
- }
-
- bool operator==(const InstructionCost &RHS) const {
- return State == RHS.State && Value == RHS.Value;
- }
-
- bool operator!=(const InstructionCost &RHS) const { return !(*this == RHS); }
-
- bool operator==(const CostType RHS) const {
- return State == Valid && Value == RHS;
- }
-
- bool operator!=(const CostType RHS) const { return !(*this == RHS); }
-
- /// For the comparison operators we have chosen to use total ordering with
- /// the following rules:
- /// 1. If either of the states != Valid then a lexicographical order is
- /// applied based upon the state.
- /// 2. If both states are valid then order based upon value.
- /// This avoids having to add asserts the comparison operators that the states
- /// are valid and users can test for validity of the cost explicitly.
- bool operator<(const InstructionCost &RHS) const {
- if (State != Valid || RHS.State != Valid)
- return State < RHS.State;
- return Value < RHS.Value;
- }
-
- bool operator>(const InstructionCost &RHS) const { return RHS < *this; }
-
- bool operator<=(const InstructionCost &RHS) const { return !(RHS < *this); }
-
- bool operator>=(const InstructionCost &RHS) const { return !(*this < RHS); }
-
- bool operator<(const CostType RHS) const {
- InstructionCost RHS2(RHS);
- return *this < RHS2;
- }
-
- bool operator>(const CostType RHS) const {
- InstructionCost RHS2(RHS);
- return *this > RHS2;
- }
-
- bool operator<=(const CostType RHS) const {
- InstructionCost RHS2(RHS);
- return *this <= RHS2;
- }
-
- bool operator>=(const CostType RHS) const {
- InstructionCost RHS2(RHS);
- return *this >= RHS2;
- }
-
- void print(raw_ostream &OS) const;
-};
-
-inline InstructionCost operator+(const InstructionCost &LHS,
- const InstructionCost &RHS) {
- InstructionCost LHS2(LHS);
- LHS2 += RHS;
- return LHS2;
-}
-
-inline InstructionCost operator-(const InstructionCost &LHS,
- const InstructionCost &RHS) {
- InstructionCost LHS2(LHS);
- LHS2 -= RHS;
- return LHS2;
-}
-
-inline InstructionCost operator*(const InstructionCost &LHS,
- const InstructionCost &RHS) {
- InstructionCost LHS2(LHS);
- LHS2 *= RHS;
- return LHS2;
-}
-
-inline InstructionCost operator/(const InstructionCost &LHS,
- const InstructionCost &RHS) {
- InstructionCost LHS2(LHS);
- LHS2 /= RHS;
- return LHS2;
-}
-
-inline raw_ostream &operator<<(raw_ostream &OS, const InstructionCost &V) {
- V.print(OS);
- return OS;
-}
-
-} // namespace llvm
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- InstructionCost.h ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file defines an InstructionCost class that is used when calculating
+/// the cost of an instruction, or a group of instructions. In addition to a
+/// numeric value representing the cost the class also contains a state that
+/// can be used to encode particular properties, i.e. a cost being invalid or
+/// unknown.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_INSTRUCTIONCOST_H
+#define LLVM_SUPPORT_INSTRUCTIONCOST_H
+
+#include "llvm/ADT/Optional.h"
+
+namespace llvm {
+
+class raw_ostream;
+
+class InstructionCost {
+public:
+ using CostType = int;
+
+ /// These states can currently be used to indicate whether a cost is valid or
+ /// invalid. Examples of an invalid cost might be where the cost is
+ /// prohibitively expensive and the user wants to prevent certain
+ /// optimizations being performed. Or perhaps the cost is simply unknown
+ /// because the operation makes no sense in certain circumstances. These
+ /// states can be expanded in future to support other cases if necessary.
+ enum CostState { Valid, Invalid };
+
+private:
+ CostType Value;
+ CostState State;
+
+ void propagateState(const InstructionCost &RHS) {
+ if (RHS.State == Invalid)
+ State = Invalid;
+ }
+
+public:
+ InstructionCost() = default;
+
+ InstructionCost(CostState) = delete;
+ InstructionCost(CostType Val) : Value(Val), State(Valid) {}
+
+ static InstructionCost getInvalid(CostType Val = 0) {
+ InstructionCost Tmp(Val);
+ Tmp.setInvalid();
+ return Tmp;
+ }
+
+ bool isValid() const { return State == Valid; }
+ void setValid() { State = Valid; }
+ void setInvalid() { State = Invalid; }
+ CostState getState() const { return State; }
+
+ /// This function is intended to be used as sparingly as possible, since the
+ /// class provides the full range of operator support required for arithmetic
+ /// and comparisons.
+ Optional<CostType> getValue() const {
+ if (isValid())
+ return Value;
+ return None;
+ }
+
+ /// For all of the arithmetic operators provided here any invalid state is
+ /// perpetuated and cannot be removed. Once a cost becomes invalid it stays
+ /// invalid, and it also inherits any invalid state from the RHS. Regardless
+ /// of the state, arithmetic and comparisons work on the actual values in the
+ /// same way as they would on a basic type, such as integer.
+
+ InstructionCost &operator+=(const InstructionCost &RHS) {
+ propagateState(RHS);
+ Value += RHS.Value;
+ return *this;
+ }
+
+ InstructionCost &operator+=(const CostType RHS) {
+ InstructionCost RHS2(RHS);
+ *this += RHS2;
+ return *this;
+ }
+
+ InstructionCost &operator-=(const InstructionCost &RHS) {
+ propagateState(RHS);
+ Value -= RHS.Value;
+ return *this;
+ }
+
+ InstructionCost &operator-=(const CostType RHS) {
+ InstructionCost RHS2(RHS);
+ *this -= RHS2;
+ return *this;
+ }
+
+ InstructionCost &operator*=(const InstructionCost &RHS) {
+ propagateState(RHS);
+ Value *= RHS.Value;
+ return *this;
+ }
+
+ InstructionCost &operator*=(const CostType RHS) {
+ InstructionCost RHS2(RHS);
+ *this *= RHS2;
+ return *this;
+ }
+
+ InstructionCost &operator/=(const InstructionCost &RHS) {
+ propagateState(RHS);
+ Value /= RHS.Value;
+ return *this;
+ }
+
+ InstructionCost &operator/=(const CostType RHS) {
+ InstructionCost RHS2(RHS);
+ *this /= RHS2;
+ return *this;
+ }
+
+ InstructionCost &operator++() {
+ *this += 1;
+ return *this;
+ }
+
+ InstructionCost operator++(int) {
+ InstructionCost Copy = *this;
+ ++*this;
+ return Copy;
+ }
+
+ InstructionCost &operator--() {
+ *this -= 1;
+ return *this;
+ }
+
+ InstructionCost operator--(int) {
+ InstructionCost Copy = *this;
+ --*this;
+ return Copy;
+ }
+
+ bool operator==(const InstructionCost &RHS) const {
+ return State == RHS.State && Value == RHS.Value;
+ }
+
+ bool operator!=(const InstructionCost &RHS) const { return !(*this == RHS); }
+
+ bool operator==(const CostType RHS) const {
+ return State == Valid && Value == RHS;
+ }
+
+ bool operator!=(const CostType RHS) const { return !(*this == RHS); }
+
+ /// For the comparison operators we have chosen to use total ordering with
+ /// the following rules:
+ /// 1. If either of the states != Valid then a lexicographical order is
+ /// applied based upon the state.
+ /// 2. If both states are valid then order based upon value.
+ /// This avoids having to add asserts the comparison operators that the states
+ /// are valid and users can test for validity of the cost explicitly.
+ bool operator<(const InstructionCost &RHS) const {
+ if (State != Valid || RHS.State != Valid)
+ return State < RHS.State;
+ return Value < RHS.Value;
+ }
+
+ bool operator>(const InstructionCost &RHS) const { return RHS < *this; }
+
+ bool operator<=(const InstructionCost &RHS) const { return !(RHS < *this); }
+
+ bool operator>=(const InstructionCost &RHS) const { return !(*this < RHS); }
+
+ bool operator<(const CostType RHS) const {
+ InstructionCost RHS2(RHS);
+ return *this < RHS2;
+ }
+
+ bool operator>(const CostType RHS) const {
+ InstructionCost RHS2(RHS);
+ return *this > RHS2;
+ }
+
+ bool operator<=(const CostType RHS) const {
+ InstructionCost RHS2(RHS);
+ return *this <= RHS2;
+ }
+
+ bool operator>=(const CostType RHS) const {
+ InstructionCost RHS2(RHS);
+ return *this >= RHS2;
+ }
+
+ void print(raw_ostream &OS) const;
+};
+
+inline InstructionCost operator+(const InstructionCost &LHS,
+ const InstructionCost &RHS) {
+ InstructionCost LHS2(LHS);
+ LHS2 += RHS;
+ return LHS2;
+}
+
+inline InstructionCost operator-(const InstructionCost &LHS,
+ const InstructionCost &RHS) {
+ InstructionCost LHS2(LHS);
+ LHS2 -= RHS;
+ return LHS2;
+}
+
+inline InstructionCost operator*(const InstructionCost &LHS,
+ const InstructionCost &RHS) {
+ InstructionCost LHS2(LHS);
+ LHS2 *= RHS;
+ return LHS2;
+}
+
+inline InstructionCost operator/(const InstructionCost &LHS,
+ const InstructionCost &RHS) {
+ InstructionCost LHS2(LHS);
+ LHS2 /= RHS;
+ return LHS2;
+}
+
+inline raw_ostream &operator<<(raw_ostream &OS, const InstructionCost &V) {
+ V.print(OS);
+ return OS;
+}
+
+} // namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Support/JSON.h b/contrib/libs/llvm12/include/llvm/Support/JSON.h
index 8fd3b1b856..2a25583b03 100644
--- a/contrib/libs/llvm12/include/llvm/Support/JSON.h
+++ b/contrib/libs/llvm12/include/llvm/Support/JSON.h
@@ -260,14 +260,14 @@ inline bool operator!=(const Array &L, const Array &R) { return !(L == R); }
/// === Converting JSON values to C++ types ===
///
/// The convention is to have a deserializer function findable via ADL:
-/// fromJSON(const json::Value&, T&, Path) -> bool
-///
-/// The return value indicates overall success, and Path is used for precise
-/// error reporting. (The Path::Root passed in at the top level fromJSON call
-/// captures any nested error and can render it in context).
-/// If conversion fails, fromJSON calls Path::report() and immediately returns.
-/// This ensures that the first fatal error survives.
-///
+/// fromJSON(const json::Value&, T&, Path) -> bool
+///
+/// The return value indicates overall success, and Path is used for precise
+/// error reporting. (The Path::Root passed in at the top level fromJSON call
+/// captures any nested error and can render it in context).
+/// If conversion fails, fromJSON calls Path::report() and immediately returns.
+/// This ensures that the first fatal error survives.
+///
/// Deserializers are provided for:
/// - bool
/// - int and int64_t
@@ -463,12 +463,12 @@ private:
friend class Object;
template <typename T, typename... U> void create(U &&... V) {
- new (reinterpret_cast<T *>(&Union)) T(std::forward<U>(V)...);
+ new (reinterpret_cast<T *>(&Union)) T(std::forward<U>(V)...);
}
template <typename T> T &as() const {
// Using this two-step static_cast via void * instead of reinterpret_cast
// silences a -Wstrict-aliasing false positive from GCC6 and earlier.
- void *Storage = static_cast<void *>(&Union);
+ void *Storage = static_cast<void *>(&Union);
return *static_cast<T *>(Storage);
}
@@ -571,169 +571,169 @@ inline bool Object::erase(StringRef K) {
return M.erase(ObjectKey(K));
}
-/// A "cursor" marking a position within a Value.
-/// The Value is a tree, and this is the path from the root to the current node.
-/// This is used to associate errors with particular subobjects.
-class Path {
-public:
- class Root;
-
- /// Records that the value at the current path is invalid.
- /// Message is e.g. "expected number" and becomes part of the final error.
- /// This overwrites any previously written error message in the root.
- void report(llvm::StringLiteral Message);
-
- /// The root may be treated as a Path.
- Path(Root &R) : Parent(nullptr), Seg(&R) {}
- /// Derives a path for an array element: this[Index]
- Path index(unsigned Index) const { return Path(this, Segment(Index)); }
- /// Derives a path for an object field: this.Field
- Path field(StringRef Field) const { return Path(this, Segment(Field)); }
-
-private:
- /// One element in a JSON path: an object field (.foo) or array index [27].
- /// Exception: the root Path encodes a pointer to the Path::Root.
- class Segment {
- uintptr_t Pointer;
- unsigned Offset;
-
- public:
- Segment() = default;
- Segment(Root *R) : Pointer(reinterpret_cast<uintptr_t>(R)) {}
- Segment(llvm::StringRef Field)
- : Pointer(reinterpret_cast<uintptr_t>(Field.data())),
- Offset(static_cast<unsigned>(Field.size())) {}
- Segment(unsigned Index) : Pointer(0), Offset(Index) {}
-
- bool isField() const { return Pointer != 0; }
- StringRef field() const {
- return StringRef(reinterpret_cast<const char *>(Pointer), Offset);
- }
- unsigned index() const { return Offset; }
- Root *root() const { return reinterpret_cast<Root *>(Pointer); }
- };
-
- const Path *Parent;
- Segment Seg;
-
- Path(const Path *Parent, Segment S) : Parent(Parent), Seg(S) {}
-};
-
-/// The root is the trivial Path to the root value.
-/// It also stores the latest reported error and the path where it occurred.
-class Path::Root {
- llvm::StringRef Name;
- llvm::StringLiteral ErrorMessage;
- std::vector<Path::Segment> ErrorPath; // Only valid in error state. Reversed.
-
- friend void Path::report(llvm::StringLiteral Message);
-
-public:
- Root(llvm::StringRef Name = "") : Name(Name), ErrorMessage("") {}
- // No copy/move allowed as there are incoming pointers.
- Root(Root &&) = delete;
- Root &operator=(Root &&) = delete;
- Root(const Root &) = delete;
- Root &operator=(const Root &) = delete;
-
- /// Returns the last error reported, or else a generic error.
- Error getError() const;
- /// Print the root value with the error shown inline as a comment.
- /// Unrelated parts of the value are elided for brevity, e.g.
- /// {
- /// "id": 42,
- /// "name": /* expected string */ null,
- /// "properties": { ... }
- /// }
- void printErrorContext(const Value &, llvm::raw_ostream &) const;
-};
-
+/// A "cursor" marking a position within a Value.
+/// The Value is a tree, and this is the path from the root to the current node.
+/// This is used to associate errors with particular subobjects.
+class Path {
+public:
+ class Root;
+
+ /// Records that the value at the current path is invalid.
+ /// Message is e.g. "expected number" and becomes part of the final error.
+ /// This overwrites any previously written error message in the root.
+ void report(llvm::StringLiteral Message);
+
+ /// The root may be treated as a Path.
+ Path(Root &R) : Parent(nullptr), Seg(&R) {}
+ /// Derives a path for an array element: this[Index]
+ Path index(unsigned Index) const { return Path(this, Segment(Index)); }
+ /// Derives a path for an object field: this.Field
+ Path field(StringRef Field) const { return Path(this, Segment(Field)); }
+
+private:
+ /// One element in a JSON path: an object field (.foo) or array index [27].
+ /// Exception: the root Path encodes a pointer to the Path::Root.
+ class Segment {
+ uintptr_t Pointer;
+ unsigned Offset;
+
+ public:
+ Segment() = default;
+ Segment(Root *R) : Pointer(reinterpret_cast<uintptr_t>(R)) {}
+ Segment(llvm::StringRef Field)
+ : Pointer(reinterpret_cast<uintptr_t>(Field.data())),
+ Offset(static_cast<unsigned>(Field.size())) {}
+ Segment(unsigned Index) : Pointer(0), Offset(Index) {}
+
+ bool isField() const { return Pointer != 0; }
+ StringRef field() const {
+ return StringRef(reinterpret_cast<const char *>(Pointer), Offset);
+ }
+ unsigned index() const { return Offset; }
+ Root *root() const { return reinterpret_cast<Root *>(Pointer); }
+ };
+
+ const Path *Parent;
+ Segment Seg;
+
+ Path(const Path *Parent, Segment S) : Parent(Parent), Seg(S) {}
+};
+
+/// The root is the trivial Path to the root value.
+/// It also stores the latest reported error and the path where it occurred.
+class Path::Root {
+ llvm::StringRef Name;
+ llvm::StringLiteral ErrorMessage;
+ std::vector<Path::Segment> ErrorPath; // Only valid in error state. Reversed.
+
+ friend void Path::report(llvm::StringLiteral Message);
+
+public:
+ Root(llvm::StringRef Name = "") : Name(Name), ErrorMessage("") {}
+ // No copy/move allowed as there are incoming pointers.
+ Root(Root &&) = delete;
+ Root &operator=(Root &&) = delete;
+ Root(const Root &) = delete;
+ Root &operator=(const Root &) = delete;
+
+ /// Returns the last error reported, or else a generic error.
+ Error getError() const;
+ /// Print the root value with the error shown inline as a comment.
+ /// Unrelated parts of the value are elided for brevity, e.g.
+ /// {
+ /// "id": 42,
+ /// "name": /* expected string */ null,
+ /// "properties": { ... }
+ /// }
+ void printErrorContext(const Value &, llvm::raw_ostream &) const;
+};
+
// Standard deserializers are provided for primitive types.
// See comments on Value.
-inline bool fromJSON(const Value &E, std::string &Out, Path P) {
+inline bool fromJSON(const Value &E, std::string &Out, Path P) {
if (auto S = E.getAsString()) {
Out = std::string(*S);
return true;
}
- P.report("expected string");
+ P.report("expected string");
return false;
}
-inline bool fromJSON(const Value &E, int &Out, Path P) {
+inline bool fromJSON(const Value &E, int &Out, Path P) {
if (auto S = E.getAsInteger()) {
Out = *S;
return true;
}
- P.report("expected integer");
+ P.report("expected integer");
return false;
}
-inline bool fromJSON(const Value &E, int64_t &Out, Path P) {
+inline bool fromJSON(const Value &E, int64_t &Out, Path P) {
if (auto S = E.getAsInteger()) {
Out = *S;
return true;
}
- P.report("expected integer");
+ P.report("expected integer");
return false;
}
-inline bool fromJSON(const Value &E, double &Out, Path P) {
+inline bool fromJSON(const Value &E, double &Out, Path P) {
if (auto S = E.getAsNumber()) {
Out = *S;
return true;
}
- P.report("expected number");
+ P.report("expected number");
return false;
}
-inline bool fromJSON(const Value &E, bool &Out, Path P) {
+inline bool fromJSON(const Value &E, bool &Out, Path P) {
if (auto S = E.getAsBoolean()) {
Out = *S;
return true;
}
- P.report("expected boolean");
+ P.report("expected boolean");
return false;
}
-inline bool fromJSON(const Value &E, std::nullptr_t &Out, Path P) {
+inline bool fromJSON(const Value &E, std::nullptr_t &Out, Path P) {
if (auto S = E.getAsNull()) {
Out = *S;
return true;
}
- P.report("expected null");
+ P.report("expected null");
return false;
}
-template <typename T>
-bool fromJSON(const Value &E, llvm::Optional<T> &Out, Path P) {
+template <typename T>
+bool fromJSON(const Value &E, llvm::Optional<T> &Out, Path P) {
if (E.getAsNull()) {
Out = llvm::None;
return true;
}
T Result;
- if (!fromJSON(E, Result, P))
+ if (!fromJSON(E, Result, P))
return false;
Out = std::move(Result);
return true;
}
-template <typename T>
-bool fromJSON(const Value &E, std::vector<T> &Out, Path P) {
+template <typename T>
+bool fromJSON(const Value &E, std::vector<T> &Out, Path P) {
if (auto *A = E.getAsArray()) {
Out.clear();
Out.resize(A->size());
for (size_t I = 0; I < A->size(); ++I)
- if (!fromJSON((*A)[I], Out[I], P.index(I)))
+ if (!fromJSON((*A)[I], Out[I], P.index(I)))
return false;
return true;
}
- P.report("expected array");
+ P.report("expected array");
return false;
}
template <typename T>
-bool fromJSON(const Value &E, std::map<std::string, T> &Out, Path P) {
+bool fromJSON(const Value &E, std::map<std::string, T> &Out, Path P) {
if (auto *O = E.getAsObject()) {
Out.clear();
for (const auto &KV : *O)
- if (!fromJSON(KV.second, Out[std::string(llvm::StringRef(KV.first))],
- P.field(KV.first)))
+ if (!fromJSON(KV.second, Out[std::string(llvm::StringRef(KV.first))],
+ P.field(KV.first)))
return false;
return true;
}
- P.report("expected object");
+ P.report("expected object");
return false;
}
@@ -746,59 +746,59 @@ template <typename T> Value toJSON(const llvm::Optional<T> &Opt) {
///
/// Example:
/// \code
-/// bool fromJSON(const Value &E, MyStruct &R, Path P) {
-/// ObjectMapper O(E, P);
-/// // When returning false, error details were already reported.
-/// return O && O.map("mandatory_field", R.MandatoryField) &&
-/// O.mapOptional("optional_field", R.OptionalField);
+/// bool fromJSON(const Value &E, MyStruct &R, Path P) {
+/// ObjectMapper O(E, P);
+/// // When returning false, error details were already reported.
+/// return O && O.map("mandatory_field", R.MandatoryField) &&
+/// O.mapOptional("optional_field", R.OptionalField);
/// }
/// \endcode
class ObjectMapper {
public:
- /// If O is not an object, this mapper is invalid and an error is reported.
- ObjectMapper(const Value &E, Path P) : O(E.getAsObject()), P(P) {
- if (!O)
- P.report("expected object");
- }
+ /// If O is not an object, this mapper is invalid and an error is reported.
+ ObjectMapper(const Value &E, Path P) : O(E.getAsObject()), P(P) {
+ if (!O)
+ P.report("expected object");
+ }
/// True if the expression is an object.
/// Must be checked before calling map().
- operator bool() const { return O; }
+ operator bool() const { return O; }
- /// Maps a property to a field.
- /// If the property is missing or invalid, reports an error.
- template <typename T> bool map(StringLiteral Prop, T &Out) {
+ /// Maps a property to a field.
+ /// If the property is missing or invalid, reports an error.
+ template <typename T> bool map(StringLiteral Prop, T &Out) {
assert(*this && "Must check this is an object before calling map()");
if (const Value *E = O->get(Prop))
- return fromJSON(*E, Out, P.field(Prop));
- P.field(Prop).report("missing value");
+ return fromJSON(*E, Out, P.field(Prop));
+ P.field(Prop).report("missing value");
return false;
}
/// Maps a property to a field, if it exists.
- /// If the property exists and is invalid, reports an error.
+ /// If the property exists and is invalid, reports an error.
/// (Optional requires special handling, because missing keys are OK).
- template <typename T> bool map(StringLiteral Prop, llvm::Optional<T> &Out) {
+ template <typename T> bool map(StringLiteral Prop, llvm::Optional<T> &Out) {
assert(*this && "Must check this is an object before calling map()");
if (const Value *E = O->get(Prop))
- return fromJSON(*E, Out, P.field(Prop));
+ return fromJSON(*E, Out, P.field(Prop));
Out = llvm::None;
return true;
}
- /// Maps a property to a field, if it exists.
- /// If the property exists and is invalid, reports an error.
- /// If the property does not exist, Out is unchanged.
- template <typename T> bool mapOptional(StringLiteral Prop, T &Out) {
- assert(*this && "Must check this is an object before calling map()");
- if (const Value *E = O->get(Prop))
- return fromJSON(*E, Out, P.field(Prop));
- return true;
- }
-
+ /// Maps a property to a field, if it exists.
+ /// If the property exists and is invalid, reports an error.
+ /// If the property does not exist, Out is unchanged.
+ template <typename T> bool mapOptional(StringLiteral Prop, T &Out) {
+ assert(*this && "Must check this is an object before calling map()");
+ if (const Value *E = O->get(Prop))
+ return fromJSON(*E, Out, P.field(Prop));
+ return true;
+ }
+
private:
const Object *O;
- Path P;
+ Path P;
};
/// Parses the provided JSON source, or returns a ParseError.
@@ -822,24 +822,24 @@ public:
}
};
-/// Version of parse() that converts the parsed value to the type T.
-/// RootName describes the root object and is used in error messages.
-template <typename T>
-Expected<T> parse(const llvm::StringRef &JSON, const char *RootName = "") {
- auto V = parse(JSON);
- if (!V)
- return V.takeError();
- Path::Root R(RootName);
- T Result;
- if (fromJSON(*V, Result, R))
- return std::move(Result);
- return R.getError();
-}
-
+/// Version of parse() that converts the parsed value to the type T.
+/// RootName describes the root object and is used in error messages.
+template <typename T>
+Expected<T> parse(const llvm::StringRef &JSON, const char *RootName = "") {
+ auto V = parse(JSON);
+ if (!V)
+ return V.takeError();
+ Path::Root R(RootName);
+ T Result;
+ if (fromJSON(*V, Result, R))
+ return std::move(Result);
+ return R.getError();
+}
+
/// json::OStream allows writing well-formed JSON without materializing
/// all structures as json::Value ahead of time.
/// It's faster, lower-level, and less safe than OS << json::Value.
-/// It also allows emitting more constructs, such as comments.
+/// It also allows emitting more constructs, such as comments.
///
/// Only one "top-level" object can be written to a stream.
/// Simplest usage involves passing lambdas (Blocks) to fill in containers:
@@ -925,21 +925,21 @@ class OStream {
Contents();
objectEnd();
}
- /// Emit an externally-serialized value.
- /// The caller must write exactly one valid JSON value to the provided stream.
- /// No validation or formatting of this value occurs.
- void rawValue(llvm::function_ref<void(raw_ostream &)> Contents) {
- rawValueBegin();
- Contents(OS);
- rawValueEnd();
- }
- void rawValue(llvm::StringRef Contents) {
- rawValue([&](raw_ostream &OS) { OS << Contents; });
- }
- /// Emit a JavaScript comment associated with the next printed value.
- /// The string must be valid until the next attribute or value is emitted.
- /// Comments are not part of standard JSON, and many parsers reject them!
- void comment(llvm::StringRef);
+ /// Emit an externally-serialized value.
+ /// The caller must write exactly one valid JSON value to the provided stream.
+ /// No validation or formatting of this value occurs.
+ void rawValue(llvm::function_ref<void(raw_ostream &)> Contents) {
+ rawValueBegin();
+ Contents(OS);
+ rawValueEnd();
+ }
+ void rawValue(llvm::StringRef Contents) {
+ rawValue([&](raw_ostream &OS) { OS << Contents; });
+ }
+ /// Emit a JavaScript comment associated with the next printed value.
+ /// The string must be valid until the next attribute or value is emitted.
+ /// Comments are not part of standard JSON, and many parsers reject them!
+ void comment(llvm::StringRef);
// High level functions to output object attributes.
// Valid only within an object (any number of times).
@@ -966,10 +966,10 @@ class OStream {
void objectEnd();
void attributeBegin(llvm::StringRef Key);
void attributeEnd();
- raw_ostream &rawValueBegin();
- void rawValueEnd();
+ raw_ostream &rawValueBegin();
+ void rawValueEnd();
-private:
+private:
void attributeImpl(llvm::StringRef Key, Block Contents) {
attributeBegin(Key);
Contents();
@@ -977,21 +977,21 @@ private:
}
void valueBegin();
- void flushComment();
+ void flushComment();
void newline();
enum Context {
Singleton, // Top level, or object attribute.
Array,
Object,
- RawValue, // External code writing a value to OS directly.
+ RawValue, // External code writing a value to OS directly.
};
struct State {
Context Ctx = Singleton;
bool HasValue = false;
};
llvm::SmallVector<State, 16> Stack; // Never empty.
- llvm::StringRef PendingComment;
+ llvm::StringRef PendingComment;
llvm::raw_ostream &OS;
unsigned IndentSize;
unsigned Indent = 0;
diff --git a/contrib/libs/llvm12/include/llvm/Support/KnownBits.h b/contrib/libs/llvm12/include/llvm/Support/KnownBits.h
index e7eaf0bbbf..9026e8891e 100644
--- a/contrib/libs/llvm12/include/llvm/Support/KnownBits.h
+++ b/contrib/libs/llvm12/include/llvm/Support/KnownBits.h
@@ -22,7 +22,7 @@
#define LLVM_SUPPORT_KNOWNBITS_H
#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/Optional.h"
namespace llvm {
@@ -105,9 +105,9 @@ public:
/// Returns true if this value is known to be non-negative.
bool isNonNegative() const { return Zero.isSignBitSet(); }
- /// Returns true if this value is known to be non-zero.
- bool isNonZero() const { return !One.isNullValue(); }
-
+ /// Returns true if this value is known to be non-zero.
+ bool isNonZero() const { return !One.isNullValue(); }
+
/// Returns true if this value is known to be positive.
bool isStrictlyPositive() const { return Zero.isSignBitSet() && !One.isNullValue(); }
@@ -121,38 +121,38 @@ public:
Zero.setSignBit();
}
- /// Return the minimal unsigned value possible given these KnownBits.
+ /// Return the minimal unsigned value possible given these KnownBits.
APInt getMinValue() const {
// Assume that all bits that aren't known-ones are zeros.
return One;
}
- /// Return the minimal signed value possible given these KnownBits.
- APInt getSignedMinValue() const {
- // Assume that all bits that aren't known-ones are zeros.
- APInt Min = One;
- // Sign bit is unknown.
- if (Zero.isSignBitClear())
- Min.setSignBit();
- return Min;
- }
-
- /// Return the maximal unsigned value possible given these KnownBits.
+ /// Return the minimal signed value possible given these KnownBits.
+ APInt getSignedMinValue() const {
+ // Assume that all bits that aren't known-ones are zeros.
+ APInt Min = One;
+ // Sign bit is unknown.
+ if (Zero.isSignBitClear())
+ Min.setSignBit();
+ return Min;
+ }
+
+ /// Return the maximal unsigned value possible given these KnownBits.
APInt getMaxValue() const {
// Assume that all bits that aren't known-zeros are ones.
return ~Zero;
}
- /// Return the maximal signed value possible given these KnownBits.
- APInt getSignedMaxValue() const {
- // Assume that all bits that aren't known-zeros are ones.
- APInt Max = ~Zero;
- // Sign bit is unknown.
- if (One.isSignBitClear())
- Max.clearSignBit();
- return Max;
- }
-
+ /// Return the maximal signed value possible given these KnownBits.
+ APInt getSignedMaxValue() const {
+ // Assume that all bits that aren't known-zeros are ones.
+ APInt Max = ~Zero;
+ // Sign bit is unknown.
+ if (One.isSignBitClear())
+ Max.clearSignBit();
+ return Max;
+ }
+
/// Return known bits for a truncation of the value we're tracking.
KnownBits trunc(unsigned BitWidth) const {
return KnownBits(Zero.trunc(BitWidth), One.trunc(BitWidth));
@@ -197,20 +197,20 @@ public:
return *this;
}
- /// Return known bits for a sign extension or truncation of the value we're
- /// tracking.
- KnownBits sextOrTrunc(unsigned BitWidth) const {
- if (BitWidth > getBitWidth())
- return sext(BitWidth);
- if (BitWidth < getBitWidth())
- return trunc(BitWidth);
- return *this;
- }
-
- /// Return known bits for a in-register sign extension of the value we're
- /// tracking.
- KnownBits sextInReg(unsigned SrcBitWidth) const;
-
+ /// Return known bits for a sign extension or truncation of the value we're
+ /// tracking.
+ KnownBits sextOrTrunc(unsigned BitWidth) const {
+ if (BitWidth > getBitWidth())
+ return sext(BitWidth);
+ if (BitWidth < getBitWidth())
+ return trunc(BitWidth);
+ return *this;
+ }
+
+ /// Return known bits for a in-register sign extension of the value we're
+ /// tracking.
+ KnownBits sextInReg(unsigned SrcBitWidth) const;
+
/// Return a KnownBits with the extracted bits
/// [bitPosition,bitPosition+numBits).
KnownBits extractBits(unsigned NumBits, unsigned BitPosition) const {
@@ -218,10 +218,10 @@ public:
One.extractBits(NumBits, BitPosition));
}
- /// Return KnownBits based on this, but updated given that the underlying
- /// value is known to be greater than or equal to Val.
- KnownBits makeGE(const APInt &Val) const;
-
+ /// Return KnownBits based on this, but updated given that the underlying
+ /// value is known to be greater than or equal to Val.
+ KnownBits makeGE(const APInt &Val) const;
+
/// Returns the minimum number of trailing zero bits.
unsigned countMinTrailingZeros() const {
return Zero.countTrailingOnes();
@@ -282,16 +282,16 @@ public:
return getBitWidth() - Zero.countPopulation();
}
- /// Create known bits from a known constant.
- static KnownBits makeConstant(const APInt &C) {
- return KnownBits(~C, C);
- }
-
- /// Compute known bits common to LHS and RHS.
- static KnownBits commonBits(const KnownBits &LHS, const KnownBits &RHS) {
- return KnownBits(LHS.Zero & RHS.Zero, LHS.One & RHS.One);
- }
-
+ /// Create known bits from a known constant.
+ static KnownBits makeConstant(const APInt &C) {
+ return KnownBits(~C, C);
+ }
+
+ /// Compute known bits common to LHS and RHS.
+ static KnownBits commonBits(const KnownBits &LHS, const KnownBits &RHS) {
+ return KnownBits(LHS.Zero & RHS.Zero, LHS.One & RHS.One);
+ }
+
/// Compute known bits resulting from adding LHS, RHS and a 1-bit Carry.
static KnownBits computeForAddCarry(
const KnownBits &LHS, const KnownBits &RHS, const KnownBits &Carry);
@@ -300,84 +300,84 @@ public:
static KnownBits computeForAddSub(bool Add, bool NSW, const KnownBits &LHS,
KnownBits RHS);
- /// Compute known bits resulting from multiplying LHS and RHS.
- static KnownBits computeForMul(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Compute known bits for udiv(LHS, RHS).
- static KnownBits udiv(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Compute known bits for urem(LHS, RHS).
- static KnownBits urem(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Compute known bits for srem(LHS, RHS).
- static KnownBits srem(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Compute known bits for umax(LHS, RHS).
- static KnownBits umax(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Compute known bits for umin(LHS, RHS).
- static KnownBits umin(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Compute known bits for smax(LHS, RHS).
- static KnownBits smax(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Compute known bits for smin(LHS, RHS).
- static KnownBits smin(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Compute known bits for shl(LHS, RHS).
- /// NOTE: RHS (shift amount) bitwidth doesn't need to be the same as LHS.
- static KnownBits shl(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Compute known bits for lshr(LHS, RHS).
- /// NOTE: RHS (shift amount) bitwidth doesn't need to be the same as LHS.
- static KnownBits lshr(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Compute known bits for ashr(LHS, RHS).
- /// NOTE: RHS (shift amount) bitwidth doesn't need to be the same as LHS.
- static KnownBits ashr(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Determine if these known bits always give the same ICMP_EQ result.
- static Optional<bool> eq(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Determine if these known bits always give the same ICMP_NE result.
- static Optional<bool> ne(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Determine if these known bits always give the same ICMP_UGT result.
- static Optional<bool> ugt(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Determine if these known bits always give the same ICMP_UGE result.
- static Optional<bool> uge(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Determine if these known bits always give the same ICMP_ULT result.
- static Optional<bool> ult(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Determine if these known bits always give the same ICMP_ULE result.
- static Optional<bool> ule(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Determine if these known bits always give the same ICMP_SGT result.
- static Optional<bool> sgt(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Determine if these known bits always give the same ICMP_SGE result.
- static Optional<bool> sge(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Determine if these known bits always give the same ICMP_SLT result.
- static Optional<bool> slt(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Determine if these known bits always give the same ICMP_SLE result.
- static Optional<bool> sle(const KnownBits &LHS, const KnownBits &RHS);
-
- /// Insert the bits from a smaller known bits starting at bitPosition.
- void insertBits(const KnownBits &SubBits, unsigned BitPosition) {
- Zero.insertBits(SubBits.Zero, BitPosition);
- One.insertBits(SubBits.One, BitPosition);
- }
-
- /// Return a subset of the known bits from [bitPosition,bitPosition+numBits).
- KnownBits extractBits(unsigned NumBits, unsigned BitPosition) {
- return KnownBits(Zero.extractBits(NumBits, BitPosition),
- One.extractBits(NumBits, BitPosition));
- }
-
+ /// Compute known bits resulting from multiplying LHS and RHS.
+ static KnownBits computeForMul(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Compute known bits for udiv(LHS, RHS).
+ static KnownBits udiv(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Compute known bits for urem(LHS, RHS).
+ static KnownBits urem(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Compute known bits for srem(LHS, RHS).
+ static KnownBits srem(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Compute known bits for umax(LHS, RHS).
+ static KnownBits umax(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Compute known bits for umin(LHS, RHS).
+ static KnownBits umin(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Compute known bits for smax(LHS, RHS).
+ static KnownBits smax(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Compute known bits for smin(LHS, RHS).
+ static KnownBits smin(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Compute known bits for shl(LHS, RHS).
+ /// NOTE: RHS (shift amount) bitwidth doesn't need to be the same as LHS.
+ static KnownBits shl(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Compute known bits for lshr(LHS, RHS).
+ /// NOTE: RHS (shift amount) bitwidth doesn't need to be the same as LHS.
+ static KnownBits lshr(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Compute known bits for ashr(LHS, RHS).
+ /// NOTE: RHS (shift amount) bitwidth doesn't need to be the same as LHS.
+ static KnownBits ashr(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Determine if these known bits always give the same ICMP_EQ result.
+ static Optional<bool> eq(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Determine if these known bits always give the same ICMP_NE result.
+ static Optional<bool> ne(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Determine if these known bits always give the same ICMP_UGT result.
+ static Optional<bool> ugt(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Determine if these known bits always give the same ICMP_UGE result.
+ static Optional<bool> uge(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Determine if these known bits always give the same ICMP_ULT result.
+ static Optional<bool> ult(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Determine if these known bits always give the same ICMP_ULE result.
+ static Optional<bool> ule(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Determine if these known bits always give the same ICMP_SGT result.
+ static Optional<bool> sgt(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Determine if these known bits always give the same ICMP_SGE result.
+ static Optional<bool> sge(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Determine if these known bits always give the same ICMP_SLT result.
+ static Optional<bool> slt(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Determine if these known bits always give the same ICMP_SLE result.
+ static Optional<bool> sle(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Insert the bits from a smaller known bits starting at bitPosition.
+ void insertBits(const KnownBits &SubBits, unsigned BitPosition) {
+ Zero.insertBits(SubBits.Zero, BitPosition);
+ One.insertBits(SubBits.One, BitPosition);
+ }
+
+ /// Return a subset of the known bits from [bitPosition,bitPosition+numBits).
+ KnownBits extractBits(unsigned NumBits, unsigned BitPosition) {
+ return KnownBits(Zero.extractBits(NumBits, BitPosition),
+ One.extractBits(NumBits, BitPosition));
+ }
+
/// Update known bits based on ANDing with RHS.
KnownBits &operator&=(const KnownBits &RHS);
@@ -386,17 +386,17 @@ public:
/// Update known bits based on XORing with RHS.
KnownBits &operator^=(const KnownBits &RHS);
-
- /// Compute known bits for the absolute value.
- KnownBits abs(bool IntMinIsPoison = false) const;
-
- KnownBits byteSwap() {
- return KnownBits(Zero.byteSwap(), One.byteSwap());
- }
-
- KnownBits reverseBits() {
- return KnownBits(Zero.reverseBits(), One.reverseBits());
- }
+
+ /// Compute known bits for the absolute value.
+ KnownBits abs(bool IntMinIsPoison = false) const;
+
+ KnownBits byteSwap() {
+ return KnownBits(Zero.byteSwap(), One.byteSwap());
+ }
+
+ KnownBits reverseBits() {
+ return KnownBits(Zero.reverseBits(), One.reverseBits());
+ }
};
inline KnownBits operator&(KnownBits LHS, const KnownBits &RHS) {
diff --git a/contrib/libs/llvm12/include/llvm/Support/LineIterator.h b/contrib/libs/llvm12/include/llvm/Support/LineIterator.h
index 71cc080931..05b5f93c1b 100644
--- a/contrib/libs/llvm12/include/llvm/Support/LineIterator.h
+++ b/contrib/libs/llvm12/include/llvm/Support/LineIterator.h
@@ -16,10 +16,10 @@
#ifndef LLVM_SUPPORT_LINEITERATOR_H
#define LLVM_SUPPORT_LINEITERATOR_H
-#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/MemoryBufferRef.h"
+#include "llvm/Support/MemoryBufferRef.h"
#include <iterator>
namespace llvm {
@@ -39,7 +39,7 @@ class MemoryBuffer;
/// Note that this iterator requires the buffer to be nul terminated.
class line_iterator
: public std::iterator<std::forward_iterator_tag, StringRef> {
- Optional<MemoryBufferRef> Buffer;
+ Optional<MemoryBufferRef> Buffer;
char CommentMarker = '\0';
bool SkipBlanks = true;
@@ -50,10 +50,10 @@ public:
/// Default construct an "end" iterator.
line_iterator() = default;
- /// Construct a new iterator around an unowned memory buffer.
- explicit line_iterator(const MemoryBufferRef &Buffer, bool SkipBlanks = true,
- char CommentMarker = '\0');
-
+ /// Construct a new iterator around an unowned memory buffer.
+ explicit line_iterator(const MemoryBufferRef &Buffer, bool SkipBlanks = true,
+ char CommentMarker = '\0');
+
/// Construct a new iterator around some memory buffer.
explicit line_iterator(const MemoryBuffer &Buffer, bool SkipBlanks = true,
char CommentMarker = '\0');
diff --git a/contrib/libs/llvm12/include/llvm/Support/MachineValueType.h b/contrib/libs/llvm12/include/llvm/Support/MachineValueType.h
index 1972ff987f..02d3979420 100644
--- a/contrib/libs/llvm12/include/llvm/Support/MachineValueType.h
+++ b/contrib/libs/llvm12/include/llvm/Support/MachineValueType.h
@@ -118,119 +118,119 @@ namespace llvm {
v8i64 = 61, // 8 x i64
v16i64 = 62, // 16 x i64
v32i64 = 63, // 32 x i64
- v64i64 = 64, // 64 x i64
- v128i64 = 65, // 128 x i64
- v256i64 = 66, // 256 x i64
+ v64i64 = 64, // 64 x i64
+ v128i64 = 65, // 128 x i64
+ v256i64 = 66, // 256 x i64
- v1i128 = 67, // 1 x i128
+ v1i128 = 67, // 1 x i128
FIRST_INTEGER_FIXEDLEN_VECTOR_VALUETYPE = v1i1,
LAST_INTEGER_FIXEDLEN_VECTOR_VALUETYPE = v1i128,
- v2f16 = 68, // 2 x f16
- v3f16 = 69, // 3 x f16
- v4f16 = 70, // 4 x f16
- v8f16 = 71, // 8 x f16
- v16f16 = 72, // 16 x f16
- v32f16 = 73, // 32 x f16
- v64f16 = 74, // 64 x f16
- v128f16 = 75, // 128 x f16
- v2bf16 = 76, // 2 x bf16
- v3bf16 = 77, // 3 x bf16
- v4bf16 = 78, // 4 x bf16
- v8bf16 = 79, // 8 x bf16
- v16bf16 = 80, // 16 x bf16
- v32bf16 = 81, // 32 x bf16
- v64bf16 = 82, // 64 x bf16
- v128bf16 = 83, // 128 x bf16
- v1f32 = 84, // 1 x f32
- v2f32 = 85, // 2 x f32
- v3f32 = 86, // 3 x f32
- v4f32 = 87, // 4 x f32
- v5f32 = 88, // 5 x f32
- v8f32 = 89, // 8 x f32
- v16f32 = 90, // 16 x f32
- v32f32 = 91, // 32 x f32
- v64f32 = 92, // 64 x f32
- v128f32 = 93, // 128 x f32
- v256f32 = 94, // 256 x f32
- v512f32 = 95, // 512 x f32
- v1024f32 = 96, // 1024 x f32
- v2048f32 = 97, // 2048 x f32
- v1f64 = 98, // 1 x f64
- v2f64 = 99, // 2 x f64
- v4f64 = 100, // 4 x f64
- v8f64 = 101, // 8 x f64
- v16f64 = 102, // 16 x f64
- v32f64 = 103, // 32 x f64
- v64f64 = 104, // 64 x f64
- v128f64 = 105, // 128 x f64
- v256f64 = 106, // 256 x f64
+ v2f16 = 68, // 2 x f16
+ v3f16 = 69, // 3 x f16
+ v4f16 = 70, // 4 x f16
+ v8f16 = 71, // 8 x f16
+ v16f16 = 72, // 16 x f16
+ v32f16 = 73, // 32 x f16
+ v64f16 = 74, // 64 x f16
+ v128f16 = 75, // 128 x f16
+ v2bf16 = 76, // 2 x bf16
+ v3bf16 = 77, // 3 x bf16
+ v4bf16 = 78, // 4 x bf16
+ v8bf16 = 79, // 8 x bf16
+ v16bf16 = 80, // 16 x bf16
+ v32bf16 = 81, // 32 x bf16
+ v64bf16 = 82, // 64 x bf16
+ v128bf16 = 83, // 128 x bf16
+ v1f32 = 84, // 1 x f32
+ v2f32 = 85, // 2 x f32
+ v3f32 = 86, // 3 x f32
+ v4f32 = 87, // 4 x f32
+ v5f32 = 88, // 5 x f32
+ v8f32 = 89, // 8 x f32
+ v16f32 = 90, // 16 x f32
+ v32f32 = 91, // 32 x f32
+ v64f32 = 92, // 64 x f32
+ v128f32 = 93, // 128 x f32
+ v256f32 = 94, // 256 x f32
+ v512f32 = 95, // 512 x f32
+ v1024f32 = 96, // 1024 x f32
+ v2048f32 = 97, // 2048 x f32
+ v1f64 = 98, // 1 x f64
+ v2f64 = 99, // 2 x f64
+ v4f64 = 100, // 4 x f64
+ v8f64 = 101, // 8 x f64
+ v16f64 = 102, // 16 x f64
+ v32f64 = 103, // 32 x f64
+ v64f64 = 104, // 64 x f64
+ v128f64 = 105, // 128 x f64
+ v256f64 = 106, // 256 x f64
FIRST_FP_FIXEDLEN_VECTOR_VALUETYPE = v2f16,
- LAST_FP_FIXEDLEN_VECTOR_VALUETYPE = v256f64,
+ LAST_FP_FIXEDLEN_VECTOR_VALUETYPE = v256f64,
FIRST_FIXEDLEN_VECTOR_VALUETYPE = v1i1,
- LAST_FIXEDLEN_VECTOR_VALUETYPE = v256f64,
-
- nxv1i1 = 107, // n x 1 x i1
- nxv2i1 = 108, // n x 2 x i1
- nxv4i1 = 109, // n x 4 x i1
- nxv8i1 = 110, // n x 8 x i1
- nxv16i1 = 111, // n x 16 x i1
- nxv32i1 = 112, // n x 32 x i1
- nxv64i1 = 113, // n x 64 x i1
-
- nxv1i8 = 114, // n x 1 x i8
- nxv2i8 = 115, // n x 2 x i8
- nxv4i8 = 116, // n x 4 x i8
- nxv8i8 = 117, // n x 8 x i8
- nxv16i8 = 118, // n x 16 x i8
- nxv32i8 = 119, // n x 32 x i8
- nxv64i8 = 120, // n x 64 x i8
-
- nxv1i16 = 121, // n x 1 x i16
- nxv2i16 = 122, // n x 2 x i16
- nxv4i16 = 123, // n x 4 x i16
- nxv8i16 = 124, // n x 8 x i16
- nxv16i16 = 125, // n x 16 x i16
- nxv32i16 = 126, // n x 32 x i16
-
- nxv1i32 = 127, // n x 1 x i32
- nxv2i32 = 128, // n x 2 x i32
- nxv4i32 = 129, // n x 4 x i32
- nxv8i32 = 130, // n x 8 x i32
- nxv16i32 = 131, // n x 16 x i32
- nxv32i32 = 132, // n x 32 x i32
-
- nxv1i64 = 133, // n x 1 x i64
- nxv2i64 = 134, // n x 2 x i64
- nxv4i64 = 135, // n x 4 x i64
- nxv8i64 = 136, // n x 8 x i64
- nxv16i64 = 137, // n x 16 x i64
- nxv32i64 = 138, // n x 32 x i64
+ LAST_FIXEDLEN_VECTOR_VALUETYPE = v256f64,
+
+ nxv1i1 = 107, // n x 1 x i1
+ nxv2i1 = 108, // n x 2 x i1
+ nxv4i1 = 109, // n x 4 x i1
+ nxv8i1 = 110, // n x 8 x i1
+ nxv16i1 = 111, // n x 16 x i1
+ nxv32i1 = 112, // n x 32 x i1
+ nxv64i1 = 113, // n x 64 x i1
+
+ nxv1i8 = 114, // n x 1 x i8
+ nxv2i8 = 115, // n x 2 x i8
+ nxv4i8 = 116, // n x 4 x i8
+ nxv8i8 = 117, // n x 8 x i8
+ nxv16i8 = 118, // n x 16 x i8
+ nxv32i8 = 119, // n x 32 x i8
+ nxv64i8 = 120, // n x 64 x i8
+
+ nxv1i16 = 121, // n x 1 x i16
+ nxv2i16 = 122, // n x 2 x i16
+ nxv4i16 = 123, // n x 4 x i16
+ nxv8i16 = 124, // n x 8 x i16
+ nxv16i16 = 125, // n x 16 x i16
+ nxv32i16 = 126, // n x 32 x i16
+
+ nxv1i32 = 127, // n x 1 x i32
+ nxv2i32 = 128, // n x 2 x i32
+ nxv4i32 = 129, // n x 4 x i32
+ nxv8i32 = 130, // n x 8 x i32
+ nxv16i32 = 131, // n x 16 x i32
+ nxv32i32 = 132, // n x 32 x i32
+
+ nxv1i64 = 133, // n x 1 x i64
+ nxv2i64 = 134, // n x 2 x i64
+ nxv4i64 = 135, // n x 4 x i64
+ nxv8i64 = 136, // n x 8 x i64
+ nxv16i64 = 137, // n x 16 x i64
+ nxv32i64 = 138, // n x 32 x i64
FIRST_INTEGER_SCALABLE_VECTOR_VALUETYPE = nxv1i1,
LAST_INTEGER_SCALABLE_VECTOR_VALUETYPE = nxv32i64,
- nxv1f16 = 139, // n x 1 x f16
- nxv2f16 = 140, // n x 2 x f16
- nxv4f16 = 141, // n x 4 x f16
- nxv8f16 = 142, // n x 8 x f16
- nxv16f16 = 143, // n x 16 x f16
- nxv32f16 = 144, // n x 32 x f16
- nxv2bf16 = 145, // n x 2 x bf16
- nxv4bf16 = 146, // n x 4 x bf16
- nxv8bf16 = 147, // n x 8 x bf16
- nxv1f32 = 148, // n x 1 x f32
- nxv2f32 = 149, // n x 2 x f32
- nxv4f32 = 150, // n x 4 x f32
- nxv8f32 = 151, // n x 8 x f32
- nxv16f32 = 152, // n x 16 x f32
- nxv1f64 = 153, // n x 1 x f64
- nxv2f64 = 154, // n x 2 x f64
- nxv4f64 = 155, // n x 4 x f64
- nxv8f64 = 156, // n x 8 x f64
+ nxv1f16 = 139, // n x 1 x f16
+ nxv2f16 = 140, // n x 2 x f16
+ nxv4f16 = 141, // n x 4 x f16
+ nxv8f16 = 142, // n x 8 x f16
+ nxv16f16 = 143, // n x 16 x f16
+ nxv32f16 = 144, // n x 32 x f16
+ nxv2bf16 = 145, // n x 2 x bf16
+ nxv4bf16 = 146, // n x 4 x bf16
+ nxv8bf16 = 147, // n x 8 x bf16
+ nxv1f32 = 148, // n x 1 x f32
+ nxv2f32 = 149, // n x 2 x f32
+ nxv4f32 = 150, // n x 4 x f32
+ nxv8f32 = 151, // n x 8 x f32
+ nxv16f32 = 152, // n x 16 x f32
+ nxv1f64 = 153, // n x 1 x f64
+ nxv2f64 = 154, // n x 2 x f64
+ nxv4f64 = 155, // n x 4 x f64
+ nxv8f64 = 156, // n x 8 x f64
FIRST_FP_SCALABLE_VECTOR_VALUETYPE = nxv1f16,
LAST_FP_SCALABLE_VECTOR_VALUETYPE = nxv8f64,
@@ -241,27 +241,27 @@ namespace llvm {
FIRST_VECTOR_VALUETYPE = v1i1,
LAST_VECTOR_VALUETYPE = nxv8f64,
- x86mmx = 157, // This is an X86 MMX value
+ x86mmx = 157, // This is an X86 MMX value
- Glue = 158, // This glues nodes together during pre-RA sched
+ Glue = 158, // This glues nodes together during pre-RA sched
- isVoid = 159, // This has no value
+ isVoid = 159, // This has no value
- Untyped = 160, // This value takes a register, but has
+ Untyped = 160, // This value takes a register, but has
// unspecified type. The register class
// will be determined by the opcode.
- funcref = 161, // WebAssembly's funcref type
- externref = 162, // WebAssembly's externref type
- x86amx = 163, // This is an X86 AMX value
+ funcref = 161, // WebAssembly's funcref type
+ externref = 162, // WebAssembly's externref type
+ x86amx = 163, // This is an X86 AMX value
FIRST_VALUETYPE = 1, // This is always the beginning of the list.
- LAST_VALUETYPE = 164, // This always remains at the end of the list.
+ LAST_VALUETYPE = 164, // This always remains at the end of the list.
// This is the current maximum for LAST_VALUETYPE.
// MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors
// This value must be a multiple of 32.
- MAX_ALLOWED_VALUETYPE = 192,
+ MAX_ALLOWED_VALUETYPE = 192,
// A value of type llvm::TokenTy
token = 248,
@@ -434,43 +434,43 @@ namespace llvm {
SimpleTy == MVT::iPTRAny);
}
- /// Return a vector with the same number of elements as this vector, but
- /// with the element type converted to an integer type with the same
- /// bitwidth.
- MVT changeVectorElementTypeToInteger() const {
- MVT EltTy = getVectorElementType();
- MVT IntTy = MVT::getIntegerVT(EltTy.getSizeInBits());
- MVT VecTy = MVT::getVectorVT(IntTy, getVectorElementCount());
- assert(VecTy.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE &&
- "Simple vector VT not representable by simple integer vector VT!");
- return VecTy;
- }
-
- /// Return a VT for a vector type whose attributes match ourselves
- /// with the exception of the element type that is chosen by the caller.
- MVT changeVectorElementType(MVT EltVT) const {
- MVT VecTy = MVT::getVectorVT(EltVT, getVectorElementCount());
- assert(VecTy.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE &&
- "Simple vector VT not representable by simple integer vector VT!");
- return VecTy;
- }
-
- /// Return the type converted to an equivalently sized integer or vector
- /// with integer element type. Similar to changeVectorElementTypeToInteger,
- /// but also handles scalars.
- MVT changeTypeToInteger() {
- if (isVector())
- return changeVectorElementTypeToInteger();
- return MVT::getIntegerVT(getSizeInBits());
- }
-
+ /// Return a vector with the same number of elements as this vector, but
+ /// with the element type converted to an integer type with the same
+ /// bitwidth.
+ MVT changeVectorElementTypeToInteger() const {
+ MVT EltTy = getVectorElementType();
+ MVT IntTy = MVT::getIntegerVT(EltTy.getSizeInBits());
+ MVT VecTy = MVT::getVectorVT(IntTy, getVectorElementCount());
+ assert(VecTy.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE &&
+ "Simple vector VT not representable by simple integer vector VT!");
+ return VecTy;
+ }
+
+ /// Return a VT for a vector type whose attributes match ourselves
+ /// with the exception of the element type that is chosen by the caller.
+ MVT changeVectorElementType(MVT EltVT) const {
+ MVT VecTy = MVT::getVectorVT(EltVT, getVectorElementCount());
+ assert(VecTy.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE &&
+ "Simple vector VT not representable by simple integer vector VT!");
+ return VecTy;
+ }
+
+ /// Return the type converted to an equivalently sized integer or vector
+ /// with integer element type. Similar to changeVectorElementTypeToInteger,
+ /// but also handles scalars.
+ MVT changeTypeToInteger() {
+ if (isVector())
+ return changeVectorElementTypeToInteger();
+ return MVT::getIntegerVT(getSizeInBits());
+ }
+
/// Return a VT for a vector type with the same element type but
/// half the number of elements.
MVT getHalfNumVectorElementsVT() const {
MVT EltVT = getVectorElementType();
auto EltCnt = getVectorElementCount();
- assert(EltCnt.isKnownEven() && "Splitting vector, but not in half!");
- return getVectorVT(EltVT, EltCnt.divideCoefficientBy(2));
+ assert(EltCnt.isKnownEven() && "Splitting vector, but not in half!");
+ return getVectorVT(EltVT, EltCnt.divideCoefficientBy(2));
}
/// Returns true if the given vector is a power of 2.
@@ -574,9 +574,9 @@ namespace llvm {
case v8i64:
case v16i64:
case v32i64:
- case v64i64:
- case v128i64:
- case v256i64:
+ case v64i64:
+ case v128i64:
+ case v256i64:
case nxv1i64:
case nxv2i64:
case nxv4i64:
@@ -634,9 +634,9 @@ namespace llvm {
case v8f64:
case v16f64:
case v32f64:
- case v64f64:
- case v128f64:
- case v256f64:
+ case v64f64:
+ case v128f64:
+ case v256f64:
case nxv1f64:
case nxv2f64:
case nxv4f64:
@@ -659,27 +659,27 @@ namespace llvm {
case v256i1:
case v256i8:
case v256i32:
- case v256i64:
- case v256f32:
- case v256f64: return 256;
+ case v256i64:
+ case v256f32:
+ case v256f64: return 256;
case v128i1:
case v128i8:
case v128i16:
case v128i32:
- case v128i64:
+ case v128i64:
case v128f16:
case v128bf16:
- case v128f32:
- case v128f64: return 128;
+ case v128f32:
+ case v128f64: return 128;
case v64i1:
case v64i8:
case v64i16:
case v64i32:
- case v64i64:
+ case v64i64:
case v64f16:
case v64bf16:
case v64f32:
- case v64f64:
+ case v64f64:
case nxv64i1:
case nxv64i8: return 64;
case v32i1:
@@ -794,12 +794,12 @@ namespace llvm {
}
ElementCount getVectorElementCount() const {
- return ElementCount::get(getVectorNumElements(), isScalableVector());
+ return ElementCount::get(getVectorNumElements(), isScalableVector());
}
/// Given a vector type, return the minimum number of elements it contains.
unsigned getVectorMinNumElements() const {
- return getVectorElementCount().getKnownMinValue();
+ return getVectorElementCount().getKnownMinValue();
}
/// Returns the size of the specified MVT in bits.
@@ -967,37 +967,37 @@ namespace llvm {
case v32f64: return TypeSize::Fixed(2048);
case nxv32i64: return TypeSize::Scalable(2048);
case v128i32:
- case v64i64:
- case v128f32:
- case v64f64: return TypeSize::Fixed(4096);
+ case v64i64:
+ case v128f32:
+ case v64f64: return TypeSize::Fixed(4096);
case v256i32:
- case v128i64:
- case v256f32:
- case x86amx:
- case v128f64: return TypeSize::Fixed(8192);
+ case v128i64:
+ case v256f32:
+ case x86amx:
+ case v128f64: return TypeSize::Fixed(8192);
case v512i32:
- case v256i64:
- case v512f32:
- case v256f64: return TypeSize::Fixed(16384);
+ case v256i64:
+ case v512f32:
+ case v256f64: return TypeSize::Fixed(16384);
case v1024i32:
case v1024f32: return TypeSize::Fixed(32768);
case v2048i32:
case v2048f32: return TypeSize::Fixed(65536);
- case funcref:
- case externref: return TypeSize::Fixed(0); // opaque type
+ case funcref:
+ case externref: return TypeSize::Fixed(0); // opaque type
}
}
- /// Return the size of the specified fixed width value type in bits. The
- /// function will assert if the type is scalable.
- uint64_t getFixedSizeInBits() const {
- return getSizeInBits().getFixedSize();
+ /// Return the size of the specified fixed width value type in bits. The
+ /// function will assert if the type is scalable.
+ uint64_t getFixedSizeInBits() const {
+ return getSizeInBits().getFixedSize();
+ }
+
+ uint64_t getScalarSizeInBits() const {
+ return getScalarType().getSizeInBits().getFixedSize();
}
- uint64_t getScalarSizeInBits() const {
- return getScalarType().getSizeInBits().getFixedSize();
- }
-
/// Return the number of bytes overwritten by a store of the specified value
/// type.
///
@@ -1021,56 +1021,56 @@ namespace llvm {
/// Returns true if the number of bits for the type is a multiple of an
/// 8-bit byte.
- bool isByteSized() const { return getSizeInBits().isKnownMultipleOf(8); }
-
- /// Return true if we know at compile time this has more bits than VT.
- bool knownBitsGT(MVT VT) const {
- return TypeSize::isKnownGT(getSizeInBits(), VT.getSizeInBits());
+ bool isByteSized() const { return getSizeInBits().isKnownMultipleOf(8); }
+
+ /// Return true if we know at compile time this has more bits than VT.
+ bool knownBitsGT(MVT VT) const {
+ return TypeSize::isKnownGT(getSizeInBits(), VT.getSizeInBits());
+ }
+
+ /// Return true if we know at compile time this has more than or the same
+ /// bits as VT.
+ bool knownBitsGE(MVT VT) const {
+ return TypeSize::isKnownGE(getSizeInBits(), VT.getSizeInBits());
+ }
+
+ /// Return true if we know at compile time this has fewer bits than VT.
+ bool knownBitsLT(MVT VT) const {
+ return TypeSize::isKnownLT(getSizeInBits(), VT.getSizeInBits());
+ }
+
+ /// Return true if we know at compile time this has fewer than or the same
+ /// bits as VT.
+ bool knownBitsLE(MVT VT) const {
+ return TypeSize::isKnownLE(getSizeInBits(), VT.getSizeInBits());
}
- /// Return true if we know at compile time this has more than or the same
- /// bits as VT.
- bool knownBitsGE(MVT VT) const {
- return TypeSize::isKnownGE(getSizeInBits(), VT.getSizeInBits());
- }
-
- /// Return true if we know at compile time this has fewer bits than VT.
- bool knownBitsLT(MVT VT) const {
- return TypeSize::isKnownLT(getSizeInBits(), VT.getSizeInBits());
- }
-
- /// Return true if we know at compile time this has fewer than or the same
- /// bits as VT.
- bool knownBitsLE(MVT VT) const {
- return TypeSize::isKnownLE(getSizeInBits(), VT.getSizeInBits());
- }
-
/// Return true if this has more bits than VT.
bool bitsGT(MVT VT) const {
- assert(isScalableVector() == VT.isScalableVector() &&
- "Comparison between scalable and fixed types");
- return knownBitsGT(VT);
+ assert(isScalableVector() == VT.isScalableVector() &&
+ "Comparison between scalable and fixed types");
+ return knownBitsGT(VT);
}
/// Return true if this has no less bits than VT.
bool bitsGE(MVT VT) const {
- assert(isScalableVector() == VT.isScalableVector() &&
- "Comparison between scalable and fixed types");
- return knownBitsGE(VT);
+ assert(isScalableVector() == VT.isScalableVector() &&
+ "Comparison between scalable and fixed types");
+ return knownBitsGE(VT);
}
/// Return true if this has less bits than VT.
bool bitsLT(MVT VT) const {
- assert(isScalableVector() == VT.isScalableVector() &&
- "Comparison between scalable and fixed types");
- return knownBitsLT(VT);
+ assert(isScalableVector() == VT.isScalableVector() &&
+ "Comparison between scalable and fixed types");
+ return knownBitsLT(VT);
}
/// Return true if this has no more bits than VT.
bool bitsLE(MVT VT) const {
- assert(isScalableVector() == VT.isScalableVector() &&
- "Comparison between scalable and fixed types");
- return knownBitsLE(VT);
+ assert(isScalableVector() == VT.isScalableVector() &&
+ "Comparison between scalable and fixed types");
+ return knownBitsLE(VT);
}
static MVT getFloatingPointVT(unsigned BitWidth) {
@@ -1171,9 +1171,9 @@ namespace llvm {
if (NumElements == 8) return MVT::v8i64;
if (NumElements == 16) return MVT::v16i64;
if (NumElements == 32) return MVT::v32i64;
- if (NumElements == 64) return MVT::v64i64;
- if (NumElements == 128) return MVT::v128i64;
- if (NumElements == 256) return MVT::v256i64;
+ if (NumElements == 64) return MVT::v64i64;
+ if (NumElements == 128) return MVT::v128i64;
+ if (NumElements == 256) return MVT::v256i64;
break;
case MVT::i128:
if (NumElements == 1) return MVT::v1i128;
@@ -1221,9 +1221,9 @@ namespace llvm {
if (NumElements == 8) return MVT::v8f64;
if (NumElements == 16) return MVT::v16f64;
if (NumElements == 32) return MVT::v32f64;
- if (NumElements == 64) return MVT::v64f64;
- if (NumElements == 128) return MVT::v128f64;
- if (NumElements == 256) return MVT::v256f64;
+ if (NumElements == 64) return MVT::v64f64;
+ if (NumElements == 128) return MVT::v128f64;
+ if (NumElements == 256) return MVT::v256f64;
break;
}
return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
@@ -1312,9 +1312,9 @@ namespace llvm {
}
static MVT getVectorVT(MVT VT, ElementCount EC) {
- if (EC.isScalable())
- return getScalableVectorVT(VT, EC.getKnownMinValue());
- return getVectorVT(VT, EC.getKnownMinValue());
+ if (EC.isScalable())
+ return getScalableVectorVT(VT, EC.getKnownMinValue());
+ return getVectorVT(VT, EC.getKnownMinValue());
}
/// Return the value type corresponding to the specified type. This returns
diff --git a/contrib/libs/llvm12/include/llvm/Support/MathExtras.h b/contrib/libs/llvm12/include/llvm/Support/MathExtras.h
index 367b6478a1..9b5304b084 100644
--- a/contrib/libs/llvm12/include/llvm/Support/MathExtras.h
+++ b/contrib/libs/llvm12/include/llvm/Support/MathExtras.h
@@ -447,7 +447,7 @@ inline uint64_t maxUIntN(uint64_t N) {
inline int64_t minIntN(int64_t N) {
assert(N > 0 && N <= 64 && "integer width out of range");
- return UINT64_C(1) + ~(UINT64_C(1) << (N - 1));
+ return UINT64_C(1) + ~(UINT64_C(1) << (N - 1));
}
/// Gets the maximum value for a N-bit signed integer.
diff --git a/contrib/libs/llvm12/include/llvm/Support/MemoryBuffer.h b/contrib/libs/llvm12/include/llvm/Support/MemoryBuffer.h
index cf7eed4703..4359b03ffd 100644
--- a/contrib/libs/llvm12/include/llvm/Support/MemoryBuffer.h
+++ b/contrib/libs/llvm12/include/llvm/Support/MemoryBuffer.h
@@ -26,7 +26,7 @@
#include "llvm/ADT/Twine.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/MemoryBufferRef.h"
+#include "llvm/Support/MemoryBufferRef.h"
#include <cstddef>
#include <cstdint>
#include <memory>
diff --git a/contrib/libs/llvm12/include/llvm/Support/MemoryBufferRef.h b/contrib/libs/llvm12/include/llvm/Support/MemoryBufferRef.h
index 54aa49334e..cc387b7fb7 100644
--- a/contrib/libs/llvm12/include/llvm/Support/MemoryBufferRef.h
+++ b/contrib/libs/llvm12/include/llvm/Support/MemoryBufferRef.h
@@ -1,67 +1,67 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- MemoryBufferRef.h - Memory Buffer Reference --------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the MemoryBuffer interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_MEMORYBUFFERREF_H
-#define LLVM_SUPPORT_MEMORYBUFFERREF_H
-
-#include "llvm/ADT/StringRef.h"
-
-namespace llvm {
-
-class MemoryBuffer;
-
-class MemoryBufferRef {
- StringRef Buffer;
- StringRef Identifier;
-
-public:
- MemoryBufferRef() = default;
- MemoryBufferRef(const MemoryBuffer &Buffer);
- MemoryBufferRef(StringRef Buffer, StringRef Identifier)
- : Buffer(Buffer), Identifier(Identifier) {}
-
- StringRef getBuffer() const { return Buffer; }
- StringRef getBufferIdentifier() const { return Identifier; }
-
- const char *getBufferStart() const { return Buffer.begin(); }
- const char *getBufferEnd() const { return Buffer.end(); }
- size_t getBufferSize() const { return Buffer.size(); }
-
- /// Check pointer identity (not value) of identifier and data.
- friend bool operator==(const MemoryBufferRef &LHS,
- const MemoryBufferRef &RHS) {
- return LHS.Buffer.begin() == RHS.Buffer.begin() &&
- LHS.Buffer.end() == RHS.Buffer.end() &&
- LHS.Identifier.begin() == RHS.Identifier.begin() &&
- LHS.Identifier.end() == RHS.Identifier.end();
- }
-
- friend bool operator!=(const MemoryBufferRef &LHS,
- const MemoryBufferRef &RHS) {
- return !(LHS == RHS);
- }
-};
-
-} // namespace llvm
-
-#endif // LLVM_SUPPORT_MEMORYBUFFERREF_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- MemoryBufferRef.h - Memory Buffer Reference --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MemoryBuffer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MEMORYBUFFERREF_H
+#define LLVM_SUPPORT_MEMORYBUFFERREF_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+class MemoryBuffer;
+
+class MemoryBufferRef {
+ StringRef Buffer;
+ StringRef Identifier;
+
+public:
+ MemoryBufferRef() = default;
+ MemoryBufferRef(const MemoryBuffer &Buffer);
+ MemoryBufferRef(StringRef Buffer, StringRef Identifier)
+ : Buffer(Buffer), Identifier(Identifier) {}
+
+ StringRef getBuffer() const { return Buffer; }
+ StringRef getBufferIdentifier() const { return Identifier; }
+
+ const char *getBufferStart() const { return Buffer.begin(); }
+ const char *getBufferEnd() const { return Buffer.end(); }
+ size_t getBufferSize() const { return Buffer.size(); }
+
+ /// Check pointer identity (not value) of identifier and data.
+ friend bool operator==(const MemoryBufferRef &LHS,
+ const MemoryBufferRef &RHS) {
+ return LHS.Buffer.begin() == RHS.Buffer.begin() &&
+ LHS.Buffer.end() == RHS.Buffer.end() &&
+ LHS.Identifier.begin() == RHS.Identifier.begin() &&
+ LHS.Identifier.end() == RHS.Identifier.end();
+ }
+
+ friend bool operator!=(const MemoryBufferRef &LHS,
+ const MemoryBufferRef &RHS) {
+ return !(LHS == RHS);
+ }
+};
+
+} // namespace llvm
+
+#endif // LLVM_SUPPORT_MEMORYBUFFERREF_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Support/Parallel.h b/contrib/libs/llvm12/include/llvm/Support/Parallel.h
index 4adcf04c2f..ac053bb4cc 100644
--- a/contrib/libs/llvm12/include/llvm/Support/Parallel.h
+++ b/contrib/libs/llvm12/include/llvm/Support/Parallel.h
@@ -18,7 +18,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Config/llvm-config.h"
-#include "llvm/Support/Error.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Threading.h"
@@ -128,17 +128,17 @@ void parallel_sort(RandomAccessIterator Start, RandomAccessIterator End,
llvm::Log2_64(std::distance(Start, End)) + 1);
}
-// TaskGroup has a relatively high overhead, so we want to reduce
-// the number of spawn() calls. We'll create up to 1024 tasks here.
-// (Note that 1024 is an arbitrary number. This code probably needs
-// improving to take the number of available cores into account.)
-enum { MaxTasksPerGroup = 1024 };
-
+// TaskGroup has a relatively high overhead, so we want to reduce
+// the number of spawn() calls. We'll create up to 1024 tasks here.
+// (Note that 1024 is an arbitrary number. This code probably needs
+// improving to take the number of available cores into account.)
+enum { MaxTasksPerGroup = 1024 };
+
template <class IterTy, class FuncTy>
void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) {
- // Limit the number of tasks to MaxTasksPerGroup to limit job scheduling
- // overhead on large inputs.
- ptrdiff_t TaskSize = std::distance(Begin, End) / MaxTasksPerGroup;
+ // Limit the number of tasks to MaxTasksPerGroup to limit job scheduling
+ // overhead on large inputs.
+ ptrdiff_t TaskSize = std::distance(Begin, End) / MaxTasksPerGroup;
if (TaskSize == 0)
TaskSize = 1;
@@ -152,9 +152,9 @@ void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) {
template <class IndexTy, class FuncTy>
void parallel_for_each_n(IndexTy Begin, IndexTy End, FuncTy Fn) {
- // Limit the number of tasks to MaxTasksPerGroup to limit job scheduling
- // overhead on large inputs.
- ptrdiff_t TaskSize = (End - Begin) / MaxTasksPerGroup;
+ // Limit the number of tasks to MaxTasksPerGroup to limit job scheduling
+ // overhead on large inputs.
+ ptrdiff_t TaskSize = (End - Begin) / MaxTasksPerGroup;
if (TaskSize == 0)
TaskSize = 1;
@@ -170,50 +170,50 @@ void parallel_for_each_n(IndexTy Begin, IndexTy End, FuncTy Fn) {
Fn(J);
}
-template <class IterTy, class ResultTy, class ReduceFuncTy,
- class TransformFuncTy>
-ResultTy parallel_transform_reduce(IterTy Begin, IterTy End, ResultTy Init,
- ReduceFuncTy Reduce,
- TransformFuncTy Transform) {
- // Limit the number of tasks to MaxTasksPerGroup to limit job scheduling
- // overhead on large inputs.
- size_t NumInputs = std::distance(Begin, End);
- if (NumInputs == 0)
- return std::move(Init);
- size_t NumTasks = std::min(static_cast<size_t>(MaxTasksPerGroup), NumInputs);
- std::vector<ResultTy> Results(NumTasks, Init);
- {
- // Each task processes either TaskSize or TaskSize+1 inputs. Any inputs
- // remaining after dividing them equally amongst tasks are distributed as
- // one extra input over the first tasks.
- TaskGroup TG;
- size_t TaskSize = NumInputs / NumTasks;
- size_t RemainingInputs = NumInputs % NumTasks;
- IterTy TBegin = Begin;
- for (size_t TaskId = 0; TaskId < NumTasks; ++TaskId) {
- IterTy TEnd = TBegin + TaskSize + (TaskId < RemainingInputs ? 1 : 0);
- TG.spawn([=, &Transform, &Reduce, &Results] {
- // Reduce the result of transformation eagerly within each task.
- ResultTy R = Init;
- for (IterTy It = TBegin; It != TEnd; ++It)
- R = Reduce(R, Transform(*It));
- Results[TaskId] = R;
- });
- TBegin = TEnd;
- }
- assert(TBegin == End);
- }
-
- // Do a final reduction. There are at most 1024 tasks, so this only adds
- // constant single-threaded overhead for large inputs. Hopefully most
- // reductions are cheaper than the transformation.
- ResultTy FinalResult = std::move(Results.front());
- for (ResultTy &PartialResult :
- makeMutableArrayRef(Results.data() + 1, Results.size() - 1))
- FinalResult = Reduce(FinalResult, std::move(PartialResult));
- return std::move(FinalResult);
-}
-
+template <class IterTy, class ResultTy, class ReduceFuncTy,
+ class TransformFuncTy>
+ResultTy parallel_transform_reduce(IterTy Begin, IterTy End, ResultTy Init,
+ ReduceFuncTy Reduce,
+ TransformFuncTy Transform) {
+ // Limit the number of tasks to MaxTasksPerGroup to limit job scheduling
+ // overhead on large inputs.
+ size_t NumInputs = std::distance(Begin, End);
+ if (NumInputs == 0)
+ return std::move(Init);
+ size_t NumTasks = std::min(static_cast<size_t>(MaxTasksPerGroup), NumInputs);
+ std::vector<ResultTy> Results(NumTasks, Init);
+ {
+ // Each task processes either TaskSize or TaskSize+1 inputs. Any inputs
+ // remaining after dividing them equally amongst tasks are distributed as
+ // one extra input over the first tasks.
+ TaskGroup TG;
+ size_t TaskSize = NumInputs / NumTasks;
+ size_t RemainingInputs = NumInputs % NumTasks;
+ IterTy TBegin = Begin;
+ for (size_t TaskId = 0; TaskId < NumTasks; ++TaskId) {
+ IterTy TEnd = TBegin + TaskSize + (TaskId < RemainingInputs ? 1 : 0);
+ TG.spawn([=, &Transform, &Reduce, &Results] {
+ // Reduce the result of transformation eagerly within each task.
+ ResultTy R = Init;
+ for (IterTy It = TBegin; It != TEnd; ++It)
+ R = Reduce(R, Transform(*It));
+ Results[TaskId] = R;
+ });
+ TBegin = TEnd;
+ }
+ assert(TBegin == End);
+ }
+
+ // Do a final reduction. There are at most 1024 tasks, so this only adds
+ // constant single-threaded overhead for large inputs. Hopefully most
+ // reductions are cheaper than the transformation.
+ ResultTy FinalResult = std::move(Results.front());
+ for (ResultTy &PartialResult :
+ makeMutableArrayRef(Results.data() + 1, Results.size() - 1))
+ FinalResult = Reduce(FinalResult, std::move(PartialResult));
+ return std::move(FinalResult);
+}
+
#endif
} // namespace detail
@@ -256,22 +256,22 @@ void parallelForEachN(size_t Begin, size_t End, FuncTy Fn) {
Fn(I);
}
-template <class IterTy, class ResultTy, class ReduceFuncTy,
- class TransformFuncTy>
-ResultTy parallelTransformReduce(IterTy Begin, IterTy End, ResultTy Init,
- ReduceFuncTy Reduce,
- TransformFuncTy Transform) {
-#if LLVM_ENABLE_THREADS
- if (parallel::strategy.ThreadsRequested != 1) {
- return parallel::detail::parallel_transform_reduce(Begin, End, Init, Reduce,
- Transform);
- }
-#endif
- for (IterTy I = Begin; I != End; ++I)
- Init = Reduce(std::move(Init), Transform(*I));
- return std::move(Init);
-}
-
+template <class IterTy, class ResultTy, class ReduceFuncTy,
+ class TransformFuncTy>
+ResultTy parallelTransformReduce(IterTy Begin, IterTy End, ResultTy Init,
+ ReduceFuncTy Reduce,
+ TransformFuncTy Transform) {
+#if LLVM_ENABLE_THREADS
+ if (parallel::strategy.ThreadsRequested != 1) {
+ return parallel::detail::parallel_transform_reduce(Begin, End, Init, Reduce,
+ Transform);
+ }
+#endif
+ for (IterTy I = Begin; I != End; ++I)
+ Init = Reduce(std::move(Init), Transform(*I));
+ return std::move(Init);
+}
+
// Range wrappers.
template <class RangeTy,
class Comparator = std::less<decltype(*std::begin(RangeTy()))>>
@@ -284,31 +284,31 @@ void parallelForEach(RangeTy &&R, FuncTy Fn) {
parallelForEach(std::begin(R), std::end(R), Fn);
}
-template <class RangeTy, class ResultTy, class ReduceFuncTy,
- class TransformFuncTy>
-ResultTy parallelTransformReduce(RangeTy &&R, ResultTy Init,
- ReduceFuncTy Reduce,
- TransformFuncTy Transform) {
- return parallelTransformReduce(std::begin(R), std::end(R), Init, Reduce,
- Transform);
-}
-
-// Parallel for-each, but with error handling.
-template <class RangeTy, class FuncTy>
-Error parallelForEachError(RangeTy &&R, FuncTy Fn) {
- // The transform_reduce algorithm requires that the initial value be copyable.
- // Error objects are uncopyable. We only need to copy initial success values,
- // so work around this mismatch via the C API. The C API represents success
- // values with a null pointer. The joinErrors discards null values and joins
- // multiple errors into an ErrorList.
- return unwrap(parallelTransformReduce(
- std::begin(R), std::end(R), wrap(Error::success()),
- [](LLVMErrorRef Lhs, LLVMErrorRef Rhs) {
- return wrap(joinErrors(unwrap(Lhs), unwrap(Rhs)));
- },
- [&Fn](auto &&V) { return wrap(Fn(V)); }));
-}
-
+template <class RangeTy, class ResultTy, class ReduceFuncTy,
+ class TransformFuncTy>
+ResultTy parallelTransformReduce(RangeTy &&R, ResultTy Init,
+ ReduceFuncTy Reduce,
+ TransformFuncTy Transform) {
+ return parallelTransformReduce(std::begin(R), std::end(R), Init, Reduce,
+ Transform);
+}
+
+// Parallel for-each, but with error handling.
+template <class RangeTy, class FuncTy>
+Error parallelForEachError(RangeTy &&R, FuncTy Fn) {
+ // The transform_reduce algorithm requires that the initial value be copyable.
+ // Error objects are uncopyable. We only need to copy initial success values,
+ // so work around this mismatch via the C API. The C API represents success
+ // values with a null pointer. The joinErrors discards null values and joins
+ // multiple errors into an ErrorList.
+ return unwrap(parallelTransformReduce(
+ std::begin(R), std::end(R), wrap(Error::success()),
+ [](LLVMErrorRef Lhs, LLVMErrorRef Rhs) {
+ return wrap(joinErrors(unwrap(Lhs), unwrap(Rhs)));
+ },
+ [&Fn](auto &&V) { return wrap(Fn(V)); }));
+}
+
} // namespace llvm
#endif // LLVM_SUPPORT_PARALLEL_H
diff --git a/contrib/libs/llvm12/include/llvm/Support/Path.h b/contrib/libs/llvm12/include/llvm/Support/Path.h
index 2c4ecbdcd9..75c8b5e731 100644
--- a/contrib/libs/llvm12/include/llvm/Support/Path.h
+++ b/contrib/libs/llvm12/include/llvm/Support/Path.h
@@ -458,48 +458,48 @@ bool has_extension(const Twine &path, Style style = Style::native);
/// Is path absolute?
///
-/// According to cppreference.com, C++17 states: "An absolute path is a path
-/// that unambiguously identifies the location of a file without reference to
-/// an additional starting location."
-///
-/// In other words, the rules are:
-/// 1) POSIX style paths with nonempty root directory are absolute.
-/// 2) Windows style paths with nonempty root name and root directory are
-/// absolute.
-/// 3) No other paths are absolute.
-///
-/// \see has_root_name
-/// \see has_root_directory
-///
+/// According to cppreference.com, C++17 states: "An absolute path is a path
+/// that unambiguously identifies the location of a file without reference to
+/// an additional starting location."
+///
+/// In other words, the rules are:
+/// 1) POSIX style paths with nonempty root directory are absolute.
+/// 2) Windows style paths with nonempty root name and root directory are
+/// absolute.
+/// 3) No other paths are absolute.
+///
+/// \see has_root_name
+/// \see has_root_directory
+///
/// @param path Input path.
/// @result True if the path is absolute, false if it is not.
bool is_absolute(const Twine &path, Style style = Style::native);
-/// Is path absolute using GNU rules?
-///
-/// GNU rules are:
-/// 1) Paths starting with a path separator are absolute.
-/// 2) Windows style paths are also absolute if they start with a character
-/// followed by ':'.
-/// 3) No other paths are absolute.
-///
-/// On Windows style the path "C:\Users\Default" has "C:" as root name and "\"
-/// as root directory.
-///
-/// Hence "C:" on Windows is absolute under GNU rules and not absolute under
-/// C++17 because it has no root directory. Likewise "/" and "\" on Windows are
-/// absolute under GNU and are not absolute under C++17 due to empty root name.
-///
-/// \see has_root_name
-/// \see has_root_directory
-///
-/// @param path Input path.
-/// @param style The style of \p path (e.g. Windows or POSIX). "native" style
-/// means to derive the style from the host.
-/// @result True if the path is absolute following GNU rules, false if it is
-/// not.
-bool is_absolute_gnu(const Twine &path, Style style = Style::native);
-
+/// Is path absolute using GNU rules?
+///
+/// GNU rules are:
+/// 1) Paths starting with a path separator are absolute.
+/// 2) Windows style paths are also absolute if they start with a character
+/// followed by ':'.
+/// 3) No other paths are absolute.
+///
+/// On Windows style the path "C:\Users\Default" has "C:" as root name and "\"
+/// as root directory.
+///
+/// Hence "C:" on Windows is absolute under GNU rules and not absolute under
+/// C++17 because it has no root directory. Likewise "/" and "\" on Windows are
+/// absolute under GNU and are not absolute under C++17 due to empty root name.
+///
+/// \see has_root_name
+/// \see has_root_directory
+///
+/// @param path Input path.
+/// @param style The style of \p path (e.g. Windows or POSIX). "native" style
+/// means to derive the style from the host.
+/// @result True if the path is absolute following GNU rules, false if it is
+/// not.
+bool is_absolute_gnu(const Twine &path, Style style = Style::native);
+
/// Is path relative?
///
/// @param path Input path.
diff --git a/contrib/libs/llvm12/include/llvm/Support/PluginLoader.h b/contrib/libs/llvm12/include/llvm/Support/PluginLoader.h
index 6bc230d7a5..31598eddae 100644
--- a/contrib/libs/llvm12/include/llvm/Support/PluginLoader.h
+++ b/contrib/libs/llvm12/include/llvm/Support/PluginLoader.h
@@ -23,12 +23,12 @@
#ifndef LLVM_SUPPORT_PLUGINLOADER_H
#define LLVM_SUPPORT_PLUGINLOADER_H
-#ifndef DONT_GET_PLUGIN_LOADER_OPTION
+#ifndef DONT_GET_PLUGIN_LOADER_OPTION
#include "llvm/Support/CommandLine.h"
-#endif
+#endif
+
+#include <string>
-#include <string>
-
namespace llvm {
struct PluginLoader {
void operator=(const std::string &Filename);
diff --git a/contrib/libs/llvm12/include/llvm/Support/Process.h b/contrib/libs/llvm12/include/llvm/Support/Process.h
index 045dcf5cfd..1a605bd085 100644
--- a/contrib/libs/llvm12/include/llvm/Support/Process.h
+++ b/contrib/libs/llvm12/include/llvm/Support/Process.h
@@ -36,7 +36,7 @@
#include "llvm/Support/Chrono.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Error.h"
-#include "llvm/Support/Program.h"
+#include "llvm/Support/Program.h"
#include <system_error>
namespace llvm {
@@ -115,12 +115,12 @@ public:
/// considered.
static Optional<std::string> FindInEnvPath(StringRef EnvName,
StringRef FileName,
- ArrayRef<std::string> IgnoreList,
- char Separator = EnvPathSeparator);
+ ArrayRef<std::string> IgnoreList,
+ char Separator = EnvPathSeparator);
static Optional<std::string> FindInEnvPath(StringRef EnvName,
- StringRef FileName,
- char Separator = EnvPathSeparator);
+ StringRef FileName,
+ char Separator = EnvPathSeparator);
// This functions ensures that the standard file descriptors (input, output,
// and error) are properly mapped to a file descriptor before we use any of
@@ -220,9 +220,9 @@ public:
/// Equivalent to ::exit(), except when running inside a CrashRecoveryContext.
/// In that case, the control flow will resume after RunSafely(), like for a
/// crash, rather than exiting the current process.
- /// Use \arg NoCleanup for calling _exit() instead of exit().
+ /// Use \arg NoCleanup for calling _exit() instead of exit().
LLVM_ATTRIBUTE_NORETURN
- static void Exit(int RetCode, bool NoCleanup = false);
+ static void Exit(int RetCode, bool NoCleanup = false);
};
}
diff --git a/contrib/libs/llvm12/include/llvm/Support/Program.h b/contrib/libs/llvm12/include/llvm/Support/Program.h
index aee27fd301..da32d52f2a 100644
--- a/contrib/libs/llvm12/include/llvm/Support/Program.h
+++ b/contrib/libs/llvm12/include/llvm/Support/Program.h
@@ -21,7 +21,7 @@
#define LLVM_SUPPORT_PROGRAM_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Config/llvm-config.h"
@@ -44,7 +44,7 @@ namespace sys {
typedef unsigned long procid_t; // Must match the type of DWORD on Windows.
typedef void *process_t; // Must match the type of HANDLE on Windows.
#else
- typedef ::pid_t procid_t;
+ typedef ::pid_t procid_t;
typedef procid_t process_t;
#endif
@@ -133,11 +133,11 @@ namespace sys {
///< string is non-empty upon return an error occurred while invoking the
///< program.
bool *ExecutionFailed = nullptr,
- Optional<ProcessStatistics> *ProcStat = nullptr, ///< If non-zero,
- /// provides a pointer to a structure in which process execution
- /// statistics will be stored.
- BitVector *AffinityMask = nullptr ///< CPUs or processors the new
- /// program shall run on.
+ Optional<ProcessStatistics> *ProcStat = nullptr, ///< If non-zero,
+ /// provides a pointer to a structure in which process execution
+ /// statistics will be stored.
+ BitVector *AffinityMask = nullptr ///< CPUs or processors the new
+ /// program shall run on.
);
/// Similar to ExecuteAndWait, but returns immediately.
@@ -150,8 +150,8 @@ namespace sys {
ArrayRef<Optional<StringRef>> Redirects = {},
unsigned MemoryLimit = 0,
std::string *ErrMsg = nullptr,
- bool *ExecutionFailed = nullptr,
- BitVector *AffinityMask = nullptr);
+ bool *ExecutionFailed = nullptr,
+ BitVector *AffinityMask = nullptr);
/// Return true if the given arguments fit within system-specific
/// argument length limits.
@@ -229,7 +229,7 @@ namespace sys {
/// to build a single flat command line appropriate for calling CreateProcess
/// on
/// Windows.
- ErrorOr<std::wstring> flattenWindowsCommandLine(ArrayRef<StringRef> Args);
+ ErrorOr<std::wstring> flattenWindowsCommandLine(ArrayRef<StringRef> Args);
#endif
}
}
diff --git a/contrib/libs/llvm12/include/llvm/Support/RISCVTargetParser.def b/contrib/libs/llvm12/include/llvm/Support/RISCVTargetParser.def
index 262a4f6939..6a06f92581 100644
--- a/contrib/libs/llvm12/include/llvm/Support/RISCVTargetParser.def
+++ b/contrib/libs/llvm12/include/llvm/Support/RISCVTargetParser.def
@@ -1,13 +1,13 @@
-#ifndef PROC_ALIAS
-#define PROC_ALIAS(NAME, RV32, RV64)
-#endif
-
-PROC_ALIAS("generic", "generic-rv32", "generic-rv64")
-PROC_ALIAS("rocket", "rocket-rv32", "rocket-rv64")
-PROC_ALIAS("sifive-7-series", "sifive-7-rv32", "sifive-7-rv64")
-
-#undef PROC_ALIAS
-
+#ifndef PROC_ALIAS
+#define PROC_ALIAS(NAME, RV32, RV64)
+#endif
+
+PROC_ALIAS("generic", "generic-rv32", "generic-rv64")
+PROC_ALIAS("rocket", "rocket-rv32", "rocket-rv64")
+PROC_ALIAS("sifive-7-series", "sifive-7-rv32", "sifive-7-rv64")
+
+#undef PROC_ALIAS
+
#ifndef PROC
#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH)
#endif
@@ -17,11 +17,11 @@ PROC(GENERIC_RV32, {"generic-rv32"}, FK_NONE, {""})
PROC(GENERIC_RV64, {"generic-rv64"}, FK_64BIT, {""})
PROC(ROCKET_RV32, {"rocket-rv32"}, FK_NONE, {""})
PROC(ROCKET_RV64, {"rocket-rv64"}, FK_64BIT, {""})
-PROC(SIFIVE_732, {"sifive-7-rv32"}, FK_NONE, {""})
-PROC(SIFIVE_764, {"sifive-7-rv64"}, FK_64BIT, {""})
+PROC(SIFIVE_732, {"sifive-7-rv32"}, FK_NONE, {""})
+PROC(SIFIVE_764, {"sifive-7-rv64"}, FK_64BIT, {""})
PROC(SIFIVE_E31, {"sifive-e31"}, FK_NONE, {"rv32imac"})
PROC(SIFIVE_U54, {"sifive-u54"}, FK_64BIT, {"rv64gc"})
-PROC(SIFIVE_E76, {"sifive-e76"}, FK_NONE, {"rv32imafc"})
-PROC(SIFIVE_U74, {"sifive-u74"}, FK_64BIT, {"rv64gc"})
+PROC(SIFIVE_E76, {"sifive-e76"}, FK_NONE, {"rv32imafc"})
+PROC(SIFIVE_U74, {"sifive-u74"}, FK_64BIT, {"rv64gc"})
#undef PROC
diff --git a/contrib/libs/llvm12/include/llvm/Support/Signals.h b/contrib/libs/llvm12/include/llvm/Support/Signals.h
index a1da026f1c..4a6e0a2473 100644
--- a/contrib/libs/llvm12/include/llvm/Support/Signals.h
+++ b/contrib/libs/llvm12/include/llvm/Support/Signals.h
@@ -57,9 +57,9 @@ namespace sys {
void DisableSystemDialogsOnCrash();
/// Print the stack trace using the given \c raw_ostream object.
- /// \param Depth refers to the number of stackframes to print. If not
- /// specified, the entire frame is printed.
- void PrintStackTrace(raw_ostream &OS, int Depth = 0);
+ /// \param Depth refers to the number of stackframes to print. If not
+ /// specified, the entire frame is printed.
+ void PrintStackTrace(raw_ostream &OS, int Depth = 0);
// Run all registered signal handlers.
void RunSignalHandlers();
@@ -124,8 +124,8 @@ namespace sys {
/// Context is a system-specific failure context: it is the signal type on
/// Unix; the ExceptionContext on Windows.
void CleanupOnSignal(uintptr_t Context);
-
- void unregisterHandlers();
+
+ void unregisterHandlers();
} // End sys namespace
} // End llvm namespace
diff --git a/contrib/libs/llvm12/include/llvm/Support/Signposts.h b/contrib/libs/llvm12/include/llvm/Support/Signposts.h
index 587b4a72eb..26f907fbe2 100644
--- a/contrib/libs/llvm12/include/llvm/Support/Signposts.h
+++ b/contrib/libs/llvm12/include/llvm/Support/Signposts.h
@@ -24,8 +24,8 @@
#ifndef LLVM_SUPPORT_SIGNPOSTS_H
#define LLVM_SUPPORT_SIGNPOSTS_H
-#include "llvm/ADT/StringRef.h"
-
+#include "llvm/ADT/StringRef.h"
+
namespace llvm {
class SignpostEmitterImpl;
@@ -40,10 +40,10 @@ public:
bool isEnabled() const;
- /// Begin a signposted interval for a given object.
- void startInterval(const void *O, StringRef Name);
- /// End a signposted interval for a given object.
- void endInterval(const void *O, StringRef Name);
+ /// Begin a signposted interval for a given object.
+ void startInterval(const void *O, StringRef Name);
+ /// End a signposted interval for a given object.
+ void endInterval(const void *O, StringRef Name);
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Support/SourceMgr.h b/contrib/libs/llvm12/include/llvm/Support/SourceMgr.h
index e210c96f87..96bc515cde 100644
--- a/contrib/libs/llvm12/include/llvm/Support/SourceMgr.h
+++ b/contrib/libs/llvm12/include/llvm/Support/SourceMgr.h
@@ -179,11 +179,11 @@ public:
std::pair<unsigned, unsigned> getLineAndColumn(SMLoc Loc,
unsigned BufferID = 0) const;
- /// Get a string with the \p SMLoc filename and line number
- /// formatted in the standard style.
- std::string getFormattedLocationNoOffset(SMLoc Loc,
- bool IncludePath = false) const;
-
+ /// Get a string with the \p SMLoc filename and line number
+ /// formatted in the standard style.
+ std::string getFormattedLocationNoOffset(SMLoc Loc,
+ bool IncludePath = false) const;
+
/// Given a line and column number in a mapped buffer, turn it into an SMLoc.
/// This will return a null SMLoc if the line/column location is invalid.
SMLoc FindLocForLineAndColumn(unsigned BufferID, unsigned LineNo,
diff --git a/contrib/libs/llvm12/include/llvm/Support/SwapByteOrder.h b/contrib/libs/llvm12/include/llvm/Support/SwapByteOrder.h
index 16a5f5460a..4e54b0adfb 100644
--- a/contrib/libs/llvm12/include/llvm/Support/SwapByteOrder.h
+++ b/contrib/libs/llvm12/include/llvm/Support/SwapByteOrder.h
@@ -29,7 +29,7 @@
#endif
#if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \
- defined(__Fuchsia__) || defined(__EMSCRIPTEN__)
+ defined(__Fuchsia__) || defined(__EMSCRIPTEN__)
#include <endian.h>
#elif defined(_AIX)
#include <sys/machine.h>
diff --git a/contrib/libs/llvm12/include/llvm/Support/SymbolRemappingReader.h b/contrib/libs/llvm12/include/llvm/Support/SymbolRemappingReader.h
index 0b6c37f18f..453713740a 100644
--- a/contrib/libs/llvm12/include/llvm/Support/SymbolRemappingReader.h
+++ b/contrib/libs/llvm12/include/llvm/Support/SymbolRemappingReader.h
@@ -75,7 +75,7 @@ namespace llvm {
class SymbolRemappingParseError : public ErrorInfo<SymbolRemappingParseError> {
public:
- SymbolRemappingParseError(StringRef File, int64_t Line, const Twine &Message)
+ SymbolRemappingParseError(StringRef File, int64_t Line, const Twine &Message)
: File(File), Line(Line), Message(Message.str()) {}
void log(llvm::raw_ostream &OS) const override {
diff --git a/contrib/libs/llvm12/include/llvm/Support/TargetOpcodes.def b/contrib/libs/llvm12/include/llvm/Support/TargetOpcodes.def
index 2cc5c69728..a63d404840 100644
--- a/contrib/libs/llvm12/include/llvm/Support/TargetOpcodes.def
+++ b/contrib/libs/llvm12/include/llvm/Support/TargetOpcodes.def
@@ -77,10 +77,10 @@ HANDLE_TARGET_OPCODE(SUBREG_TO_REG)
/// DBG_VALUE - a mapping of the llvm.dbg.value intrinsic
HANDLE_TARGET_OPCODE(DBG_VALUE)
-/// DBG_INSTR_REF - A mapping of llvm.dbg.value referring to the instruction
-/// that defines the value, rather than a virtual register.
-HANDLE_TARGET_OPCODE(DBG_INSTR_REF)
-
+/// DBG_INSTR_REF - A mapping of llvm.dbg.value referring to the instruction
+/// that defines the value, rather than a virtual register.
+HANDLE_TARGET_OPCODE(DBG_INSTR_REF)
+
/// DBG_LABEL - a mapping of the llvm.dbg.label intrinsic
HANDLE_TARGET_OPCODE(DBG_LABEL)
@@ -110,9 +110,9 @@ HANDLE_TARGET_OPCODE(BUNDLE)
HANDLE_TARGET_OPCODE(LIFETIME_START)
HANDLE_TARGET_OPCODE(LIFETIME_END)
-/// Pseudo probe
-HANDLE_TARGET_OPCODE(PSEUDO_PROBE)
-
+/// Pseudo probe
+HANDLE_TARGET_OPCODE(PSEUDO_PROBE)
+
/// A Stackmap instruction captures the location of live variables at its
/// position in the instruction stream. It is followed by a shadow of bytes
/// that must lie within the function and not contain another stackmap.
@@ -301,12 +301,12 @@ HANDLE_TARGET_OPCODE(G_INTRINSIC_TRUNC)
/// INTRINSIC round intrinsic.
HANDLE_TARGET_OPCODE(G_INTRINSIC_ROUND)
-/// INTRINSIC round to integer intrinsic.
-HANDLE_TARGET_OPCODE(G_INTRINSIC_LRINT)
-
-/// INTRINSIC roundeven intrinsic.
-HANDLE_TARGET_OPCODE(G_INTRINSIC_ROUNDEVEN)
-
+/// INTRINSIC round to integer intrinsic.
+HANDLE_TARGET_OPCODE(G_INTRINSIC_LRINT)
+
+/// INTRINSIC roundeven intrinsic.
+HANDLE_TARGET_OPCODE(G_INTRINSIC_ROUNDEVEN)
+
/// INTRINSIC readcyclecounter
HANDLE_TARGET_OPCODE(G_READCYCLECOUNTER)
@@ -482,36 +482,36 @@ HANDLE_TARGET_OPCODE(G_USUBSAT)
/// Generic saturating signed subtraction.
HANDLE_TARGET_OPCODE(G_SSUBSAT)
-/// Generic saturating unsigned left shift.
-HANDLE_TARGET_OPCODE(G_USHLSAT)
-
-/// Generic saturating signed left shift.
-HANDLE_TARGET_OPCODE(G_SSHLSAT)
-
-// Perform signed fixed point multiplication
-HANDLE_TARGET_OPCODE(G_SMULFIX)
-
-// Perform unsigned fixed point multiplication
-HANDLE_TARGET_OPCODE(G_UMULFIX)
-
-// Perform signed, saturating fixed point multiplication
-HANDLE_TARGET_OPCODE(G_SMULFIXSAT)
-
-// Perform unsigned, saturating fixed point multiplication
-HANDLE_TARGET_OPCODE(G_UMULFIXSAT)
-
-// Perform signed fixed point division
-HANDLE_TARGET_OPCODE(G_SDIVFIX)
-
-// Perform unsigned fixed point division
-HANDLE_TARGET_OPCODE(G_UDIVFIX)
-
-// Perform signed, saturating fixed point division
-HANDLE_TARGET_OPCODE(G_SDIVFIXSAT)
-
-// Perform unsigned, saturating fixed point division
-HANDLE_TARGET_OPCODE(G_UDIVFIXSAT)
-
+/// Generic saturating unsigned left shift.
+HANDLE_TARGET_OPCODE(G_USHLSAT)
+
+/// Generic saturating signed left shift.
+HANDLE_TARGET_OPCODE(G_SSHLSAT)
+
+// Perform signed fixed point multiplication
+HANDLE_TARGET_OPCODE(G_SMULFIX)
+
+// Perform unsigned fixed point multiplication
+HANDLE_TARGET_OPCODE(G_UMULFIX)
+
+// Perform signed, saturating fixed point multiplication
+HANDLE_TARGET_OPCODE(G_SMULFIXSAT)
+
+// Perform unsigned, saturating fixed point multiplication
+HANDLE_TARGET_OPCODE(G_UMULFIXSAT)
+
+// Perform signed fixed point division
+HANDLE_TARGET_OPCODE(G_SDIVFIX)
+
+// Perform unsigned fixed point division
+HANDLE_TARGET_OPCODE(G_UDIVFIX)
+
+// Perform signed, saturating fixed point division
+HANDLE_TARGET_OPCODE(G_SDIVFIXSAT)
+
+// Perform unsigned, saturating fixed point division
+HANDLE_TARGET_OPCODE(G_UDIVFIXSAT)
+
/// Generic FP addition.
HANDLE_TARGET_OPCODE(G_FADD)
@@ -536,9 +536,9 @@ HANDLE_TARGET_OPCODE(G_FREM)
/// Generic FP exponentiation.
HANDLE_TARGET_OPCODE(G_FPOW)
-/// Generic FP exponentiation, with an integer exponent.
-HANDLE_TARGET_OPCODE(G_FPOWI)
-
+/// Generic FP exponentiation, with an integer exponent.
+HANDLE_TARGET_OPCODE(G_FPOWI)
+
/// Generic base-e exponential of a value.
HANDLE_TARGET_OPCODE(G_FEXP)
@@ -617,9 +617,9 @@ HANDLE_TARGET_OPCODE(G_UMIN)
/// Generic unsigned integer maximum.
HANDLE_TARGET_OPCODE(G_UMAX)
-/// Generic integer absolute value.
-HANDLE_TARGET_OPCODE(G_ABS)
-
+/// Generic integer absolute value.
+HANDLE_TARGET_OPCODE(G_ABS)
+
/// Generic BRANCH instruction. This is an unconditional branch.
HANDLE_TARGET_OPCODE(G_BR)
@@ -704,36 +704,36 @@ HANDLE_TARGET_OPCODE(G_READ_REGISTER)
/// write_register intrinsic
HANDLE_TARGET_OPCODE(G_WRITE_REGISTER)
-/// llvm.memcpy intrinsic
-HANDLE_TARGET_OPCODE(G_MEMCPY)
-
-/// llvm.memmove intrinsic
-HANDLE_TARGET_OPCODE(G_MEMMOVE)
-
-/// llvm.memset intrinsic
-HANDLE_TARGET_OPCODE(G_MEMSET)
-
-/// Vector reductions
-HANDLE_TARGET_OPCODE(G_VECREDUCE_SEQ_FADD)
-HANDLE_TARGET_OPCODE(G_VECREDUCE_SEQ_FMUL)
-HANDLE_TARGET_OPCODE(G_VECREDUCE_FADD)
-HANDLE_TARGET_OPCODE(G_VECREDUCE_FMUL)
-HANDLE_TARGET_OPCODE(G_VECREDUCE_FMAX)
-HANDLE_TARGET_OPCODE(G_VECREDUCE_FMIN)
-HANDLE_TARGET_OPCODE(G_VECREDUCE_ADD)
-HANDLE_TARGET_OPCODE(G_VECREDUCE_MUL)
-HANDLE_TARGET_OPCODE(G_VECREDUCE_AND)
-HANDLE_TARGET_OPCODE(G_VECREDUCE_OR)
-HANDLE_TARGET_OPCODE(G_VECREDUCE_XOR)
-HANDLE_TARGET_OPCODE(G_VECREDUCE_SMAX)
-HANDLE_TARGET_OPCODE(G_VECREDUCE_SMIN)
-HANDLE_TARGET_OPCODE(G_VECREDUCE_UMAX)
-HANDLE_TARGET_OPCODE(G_VECREDUCE_UMIN)
-
+/// llvm.memcpy intrinsic
+HANDLE_TARGET_OPCODE(G_MEMCPY)
+
+/// llvm.memmove intrinsic
+HANDLE_TARGET_OPCODE(G_MEMMOVE)
+
+/// llvm.memset intrinsic
+HANDLE_TARGET_OPCODE(G_MEMSET)
+
+/// Vector reductions
+HANDLE_TARGET_OPCODE(G_VECREDUCE_SEQ_FADD)
+HANDLE_TARGET_OPCODE(G_VECREDUCE_SEQ_FMUL)
+HANDLE_TARGET_OPCODE(G_VECREDUCE_FADD)
+HANDLE_TARGET_OPCODE(G_VECREDUCE_FMUL)
+HANDLE_TARGET_OPCODE(G_VECREDUCE_FMAX)
+HANDLE_TARGET_OPCODE(G_VECREDUCE_FMIN)
+HANDLE_TARGET_OPCODE(G_VECREDUCE_ADD)
+HANDLE_TARGET_OPCODE(G_VECREDUCE_MUL)
+HANDLE_TARGET_OPCODE(G_VECREDUCE_AND)
+HANDLE_TARGET_OPCODE(G_VECREDUCE_OR)
+HANDLE_TARGET_OPCODE(G_VECREDUCE_XOR)
+HANDLE_TARGET_OPCODE(G_VECREDUCE_SMAX)
+HANDLE_TARGET_OPCODE(G_VECREDUCE_SMIN)
+HANDLE_TARGET_OPCODE(G_VECREDUCE_UMAX)
+HANDLE_TARGET_OPCODE(G_VECREDUCE_UMIN)
+
/// Marker for the end of the generic opcode.
/// This is used to check if an opcode is in the range of the
/// generic opcodes.
-HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_VECREDUCE_UMIN)
+HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_VECREDUCE_UMIN)
/// BUILTIN_OP_END - This must be the last enum value in this list.
/// The target-specific post-isel opcode values start here.
diff --git a/contrib/libs/llvm12/include/llvm/Support/TargetParser.h b/contrib/libs/llvm12/include/llvm/Support/TargetParser.h
index c1cb7deff5..08f0298aae 100644
--- a/contrib/libs/llvm12/include/llvm/Support/TargetParser.h
+++ b/contrib/libs/llvm12/include/llvm/Support/TargetParser.h
@@ -69,20 +69,20 @@ enum GPUKind : uint32_t {
// AMDGCN-based processors.
GK_GFX600 = 32,
GK_GFX601 = 33,
- GK_GFX602 = 34,
+ GK_GFX602 = 34,
GK_GFX700 = 40,
GK_GFX701 = 41,
GK_GFX702 = 42,
GK_GFX703 = 43,
GK_GFX704 = 44,
- GK_GFX705 = 45,
+ GK_GFX705 = 45,
GK_GFX801 = 50,
GK_GFX802 = 51,
GK_GFX803 = 52,
- GK_GFX805 = 53,
- GK_GFX810 = 54,
+ GK_GFX805 = 53,
+ GK_GFX810 = 54,
GK_GFX900 = 60,
GK_GFX902 = 61,
@@ -90,18 +90,18 @@ enum GPUKind : uint32_t {
GK_GFX906 = 63,
GK_GFX908 = 64,
GK_GFX909 = 65,
- GK_GFX90C = 66,
+ GK_GFX90C = 66,
GK_GFX1010 = 71,
GK_GFX1011 = 72,
GK_GFX1012 = 73,
GK_GFX1030 = 75,
- GK_GFX1031 = 76,
- GK_GFX1032 = 77,
- GK_GFX1033 = 78,
+ GK_GFX1031 = 76,
+ GK_GFX1032 = 77,
+ GK_GFX1033 = 78,
GK_AMDGCN_FIRST = GK_GFX600,
- GK_AMDGCN_LAST = GK_GFX1033,
+ GK_AMDGCN_LAST = GK_GFX1033,
};
/// Instruction set architecture version.
@@ -126,18 +126,18 @@ enum ArchFeatureKind : uint32_t {
FEATURE_FAST_DENORMAL_F32 = 1 << 5,
// Wavefront 32 is available.
- FEATURE_WAVE32 = 1 << 6,
-
- // Xnack is available.
- FEATURE_XNACK = 1 << 7,
-
- // Sram-ecc is available.
- FEATURE_SRAMECC = 1 << 8,
+ FEATURE_WAVE32 = 1 << 6,
+
+ // Xnack is available.
+ FEATURE_XNACK = 1 << 7,
+
+ // Sram-ecc is available.
+ FEATURE_SRAMECC = 1 << 8,
};
StringRef getArchNameAMDGCN(GPUKind AK);
StringRef getArchNameR600(GPUKind AK);
-StringRef getCanonicalArchName(const Triple &T, StringRef Arch);
+StringRef getCanonicalArchName(const Triple &T, StringRef Arch);
GPUKind parseArchAMDGCN(StringRef CPU);
GPUKind parseArchR600(StringRef CPU);
unsigned getArchAttrAMDGCN(GPUKind AK);
@@ -169,14 +169,14 @@ enum FeatureKind : unsigned {
};
bool checkCPUKind(CPUKind Kind, bool IsRV64);
-bool checkTuneCPUKind(CPUKind Kind, bool IsRV64);
+bool checkTuneCPUKind(CPUKind Kind, bool IsRV64);
CPUKind parseCPUKind(StringRef CPU);
-CPUKind parseTuneCPUKind(StringRef CPU, bool IsRV64);
+CPUKind parseTuneCPUKind(StringRef CPU, bool IsRV64);
StringRef getMArchFromMcpu(StringRef CPU);
void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64);
-void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64);
+void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64);
bool getCPUFeaturesExceptStdExt(CPUKind Kind, std::vector<StringRef> &Features);
-StringRef resolveTuneCPUAlias(StringRef TuneCPU, bool IsRV64);
+StringRef resolveTuneCPUAlias(StringRef TuneCPU, bool IsRV64);
} // namespace RISCV
diff --git a/contrib/libs/llvm12/include/llvm/Support/TargetRegistry.h b/contrib/libs/llvm12/include/llvm/Support/TargetRegistry.h
index 4191d97e7e..f0e5bd9d0a 100644
--- a/contrib/libs/llvm12/include/llvm/Support/TargetRegistry.h
+++ b/contrib/libs/llvm12/include/llvm/Support/TargetRegistry.h
@@ -517,8 +517,8 @@ public:
S = createWasmStreamer(Ctx, std::move(TAB), std::move(OW),
std::move(Emitter), RelaxAll);
break;
- case Triple::GOFF:
- report_fatal_error("GOFF MCObjectStreamer not implemented yet");
+ case Triple::GOFF:
+ report_fatal_error("GOFF MCObjectStreamer not implemented yet");
case Triple::XCOFF:
S = createXCOFFStreamer(Ctx, std::move(TAB), std::move(OW),
std::move(Emitter), RelaxAll);
diff --git a/contrib/libs/llvm12/include/llvm/Support/TaskQueue.h b/contrib/libs/llvm12/include/llvm/Support/TaskQueue.h
index fb0a01779e..a7ecb8f518 100644
--- a/contrib/libs/llvm12/include/llvm/Support/TaskQueue.h
+++ b/contrib/libs/llvm12/include/llvm/Support/TaskQueue.h
@@ -105,7 +105,7 @@ public:
IsTaskInFlight = true;
}
}
- return F;
+ return F;
}
private:
diff --git a/contrib/libs/llvm12/include/llvm/Support/Threading.h b/contrib/libs/llvm12/include/llvm/Support/Threading.h
index 5e34ccd1e9..2a776ce6b9 100644
--- a/contrib/libs/llvm12/include/llvm/Support/Threading.h
+++ b/contrib/libs/llvm12/include/llvm/Support/Threading.h
@@ -217,7 +217,7 @@ void llvm_execute_on_thread_async(
return heavyweight_hardware_concurrency();
}
- /// Returns a default thread strategy where all available hardware resources
+ /// Returns a default thread strategy where all available hardware resources
/// are to be used, except for those initially excluded by an affinity mask.
/// This function takes affinity into consideration. Returns 1 when LLVM is
/// configured with LLVM_ENABLE_THREADS=OFF.
@@ -227,16 +227,16 @@ void llvm_execute_on_thread_async(
return S;
}
- /// Returns an optimal thread strategy to execute specified amount of tasks.
- /// This strategy should prevent us from creating too many threads if we
- /// occasionaly have an unexpectedly small amount of tasks.
- inline ThreadPoolStrategy optimal_concurrency(unsigned TaskCount = 0) {
- ThreadPoolStrategy S;
- S.Limit = true;
- S.ThreadsRequested = TaskCount;
- return S;
- }
-
+ /// Returns an optimal thread strategy to execute specified amount of tasks.
+ /// This strategy should prevent us from creating too many threads if we
+ /// occasionaly have an unexpectedly small amount of tasks.
+ inline ThreadPoolStrategy optimal_concurrency(unsigned TaskCount = 0) {
+ ThreadPoolStrategy S;
+ S.Limit = true;
+ S.ThreadsRequested = TaskCount;
+ return S;
+ }
+
/// Return the current thread id, as used in various OS system calls.
/// Note that not all platforms guarantee that the value returned will be
/// unique across the entire system, so portable code should not assume
diff --git a/contrib/libs/llvm12/include/llvm/Support/ToolOutputFile.h b/contrib/libs/llvm12/include/llvm/Support/ToolOutputFile.h
index bc28c600cf..f02bb455bc 100644
--- a/contrib/libs/llvm12/include/llvm/Support/ToolOutputFile.h
+++ b/contrib/libs/llvm12/include/llvm/Support/ToolOutputFile.h
@@ -42,7 +42,7 @@ class ToolOutputFile {
/// The flag which indicates whether we should not delete the file.
bool Keep;
- StringRef getFilename() { return Filename; }
+ StringRef getFilename() { return Filename; }
explicit CleanupInstaller(StringRef Filename);
~CleanupInstaller();
} Installer;
@@ -65,9 +65,9 @@ public:
/// Return the contained raw_fd_ostream.
raw_fd_ostream &os() { return *OS; }
- /// Return the filename initialized with.
- StringRef getFilename() { return Installer.getFilename(); }
-
+ /// Return the filename initialized with.
+ StringRef getFilename() { return Installer.getFilename(); }
+
/// Indicate that the tool's job wrt this output file has been successful and
/// the file should not be deleted.
void keep() { Installer.Keep = true; }
diff --git a/contrib/libs/llvm12/include/llvm/Support/TrigramIndex.h b/contrib/libs/llvm12/include/llvm/Support/TrigramIndex.h
index 5e4983cf14..d0becee24c 100644
--- a/contrib/libs/llvm12/include/llvm/Support/TrigramIndex.h
+++ b/contrib/libs/llvm12/include/llvm/Support/TrigramIndex.h
@@ -34,7 +34,7 @@
#define LLVM_SUPPORT_TRIGRAMINDEX_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringRef.h"
#include <string>
#include <unordered_map>
#include <vector>
@@ -45,7 +45,7 @@ class StringRef;
class TrigramIndex {
public:
/// Inserts a new Regex into the index.
- void insert(const std::string &Regex);
+ void insert(const std::string &Regex);
/// Returns true, if special case list definitely does not have a line
/// that matches the query. Returns false, if it's not sure.
diff --git a/contrib/libs/llvm12/include/llvm/Support/TypeSize.h b/contrib/libs/llvm12/include/llvm/Support/TypeSize.h
index 04e610ff14..f6b3393098 100644
--- a/contrib/libs/llvm12/include/llvm/Support/TypeSize.h
+++ b/contrib/libs/llvm12/include/llvm/Support/TypeSize.h
@@ -22,418 +22,418 @@
#ifndef LLVM_SUPPORT_TYPESIZE_H
#define LLVM_SUPPORT_TYPESIZE_H
-#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/WithColor.h"
-#include <algorithm>
-#include <array>
-#include <cassert>
+#include <algorithm>
+#include <array>
+#include <cassert>
#include <cstdint>
-#include <type_traits>
+#include <type_traits>
namespace llvm {
-template <typename LeafTy> struct LinearPolyBaseTypeTraits {};
-
-//===----------------------------------------------------------------------===//
-// LinearPolyBase - a base class for linear polynomials with multiple
-// dimensions. This can e.g. be used to describe offsets that are have both a
-// fixed and scalable component.
-//===----------------------------------------------------------------------===//
-
-/// LinearPolyBase describes a linear polynomial:
-/// c0 * scale0 + c1 * scale1 + ... + cK * scaleK
-/// where the scale is implicit, so only the coefficients are encoded.
-template <typename LeafTy>
-class LinearPolyBase {
+template <typename LeafTy> struct LinearPolyBaseTypeTraits {};
+
+//===----------------------------------------------------------------------===//
+// LinearPolyBase - a base class for linear polynomials with multiple
+// dimensions. This can e.g. be used to describe offsets that are have both a
+// fixed and scalable component.
+//===----------------------------------------------------------------------===//
+
+/// LinearPolyBase describes a linear polynomial:
+/// c0 * scale0 + c1 * scale1 + ... + cK * scaleK
+/// where the scale is implicit, so only the coefficients are encoded.
+template <typename LeafTy>
+class LinearPolyBase {
+public:
+ using ScalarTy = typename LinearPolyBaseTypeTraits<LeafTy>::ScalarTy;
+ static constexpr auto Dimensions = LinearPolyBaseTypeTraits<LeafTy>::Dimensions;
+ static_assert(Dimensions != std::numeric_limits<unsigned>::max(),
+ "Dimensions out of range");
+
+private:
+ std::array<ScalarTy, Dimensions> Coefficients;
+
+protected:
+ LinearPolyBase(ArrayRef<ScalarTy> Values) {
+ std::copy(Values.begin(), Values.end(), Coefficients.begin());
+ }
+
+public:
+ friend LeafTy &operator+=(LeafTy &LHS, const LeafTy &RHS) {
+ for (unsigned I=0; I<Dimensions; ++I)
+ LHS.Coefficients[I] += RHS.Coefficients[I];
+ return LHS;
+ }
+
+ friend LeafTy &operator-=(LeafTy &LHS, const LeafTy &RHS) {
+ for (unsigned I=0; I<Dimensions; ++I)
+ LHS.Coefficients[I] -= RHS.Coefficients[I];
+ return LHS;
+ }
+
+ friend LeafTy &operator*=(LeafTy &LHS, ScalarTy RHS) {
+ for (auto &C : LHS.Coefficients)
+ C *= RHS;
+ return LHS;
+ }
+
+ friend LeafTy operator+(const LeafTy &LHS, const LeafTy &RHS) {
+ LeafTy Copy = LHS;
+ return Copy += RHS;
+ }
+
+ friend LeafTy operator-(const LeafTy &LHS, const LeafTy &RHS) {
+ LeafTy Copy = LHS;
+ return Copy -= RHS;
+ }
+
+ friend LeafTy operator*(const LeafTy &LHS, ScalarTy RHS) {
+ LeafTy Copy = LHS;
+ return Copy *= RHS;
+ }
+
+ template <typename U = ScalarTy>
+ friend typename std::enable_if_t<std::is_signed<U>::value, LeafTy>
+ operator-(const LeafTy &LHS) {
+ LeafTy Copy = LHS;
+ return Copy *= -1;
+ }
+
+ bool operator==(const LinearPolyBase &RHS) const {
+ return std::equal(Coefficients.begin(), Coefficients.end(),
+ RHS.Coefficients.begin());
+ }
+
+ bool operator!=(const LinearPolyBase &RHS) const {
+ return !(*this == RHS);
+ }
+
+ bool isZero() const {
+ return all_of(Coefficients, [](const ScalarTy &C) { return C == 0; });
+ }
+ bool isNonZero() const { return !isZero(); }
+ explicit operator bool() const { return isNonZero(); }
+
+ ScalarTy getValue(unsigned Dim) const { return Coefficients[Dim]; }
+};
+
+//===----------------------------------------------------------------------===//
+// StackOffset - Represent an offset with named fixed and scalable components.
+//===----------------------------------------------------------------------===//
+
+class StackOffset;
+template <> struct LinearPolyBaseTypeTraits<StackOffset> {
+ using ScalarTy = int64_t;
+ static constexpr unsigned Dimensions = 2;
+};
+
+/// StackOffset is a class to represent an offset with 2 dimensions,
+/// named fixed and scalable, respectively. This class allows a value for both
+/// dimensions to depict e.g. "8 bytes and 16 scalable bytes", which is needed
+/// to represent stack offsets.
+class StackOffset : public LinearPolyBase<StackOffset> {
+protected:
+ StackOffset(ScalarTy Fixed, ScalarTy Scalable)
+ : LinearPolyBase<StackOffset>({Fixed, Scalable}) {}
+
+public:
+ StackOffset() : StackOffset({0, 0}) {}
+ StackOffset(const LinearPolyBase<StackOffset> &Other)
+ : LinearPolyBase<StackOffset>(Other) {}
+ static StackOffset getFixed(ScalarTy Fixed) { return {Fixed, 0}; }
+ static StackOffset getScalable(ScalarTy Scalable) { return {0, Scalable}; }
+ static StackOffset get(ScalarTy Fixed, ScalarTy Scalable) {
+ return {Fixed, Scalable};
+ }
+
+ ScalarTy getFixed() const { return this->getValue(0); }
+ ScalarTy getScalable() const { return this->getValue(1); }
+};
+
+//===----------------------------------------------------------------------===//
+// UnivariateLinearPolyBase - a base class for linear polynomials with multiple
+// dimensions, but where only one dimension can be set at any time.
+// This can e.g. be used to describe sizes that are either fixed or scalable.
+//===----------------------------------------------------------------------===//
+
+/// UnivariateLinearPolyBase is a base class for ElementCount and TypeSize.
+/// Like LinearPolyBase it tries to represent a linear polynomial
+/// where only one dimension can be set at any time, e.g.
+/// 0 * scale0 + 0 * scale1 + ... + cJ * scaleJ + ... + 0 * scaleK
+/// The dimension that is set is the univariate dimension.
+template <typename LeafTy>
+class UnivariateLinearPolyBase {
+public:
+ using ScalarTy = typename LinearPolyBaseTypeTraits<LeafTy>::ScalarTy;
+ static constexpr auto Dimensions = LinearPolyBaseTypeTraits<LeafTy>::Dimensions;
+ static_assert(Dimensions != std::numeric_limits<unsigned>::max(),
+ "Dimensions out of range");
+
+protected:
+ ScalarTy Value; // The value at the univeriate dimension.
+ unsigned UnivariateDim; // The univeriate dimension.
+
+ UnivariateLinearPolyBase(ScalarTy Val, unsigned UnivariateDim)
+ : Value(Val), UnivariateDim(UnivariateDim) {
+ assert(UnivariateDim < Dimensions && "Dimension out of range");
+ }
+
+ friend LeafTy &operator+=(LeafTy &LHS, const LeafTy &RHS) {
+ assert(LHS.UnivariateDim == RHS.UnivariateDim && "Invalid dimensions");
+ LHS.Value += RHS.Value;
+ return LHS;
+ }
+
+ friend LeafTy &operator-=(LeafTy &LHS, const LeafTy &RHS) {
+ assert(LHS.UnivariateDim == RHS.UnivariateDim && "Invalid dimensions");
+ LHS.Value -= RHS.Value;
+ return LHS;
+ }
+
+ friend LeafTy &operator*=(LeafTy &LHS, ScalarTy RHS) {
+ LHS.Value *= RHS;
+ return LHS;
+ }
+
+ friend LeafTy operator+(const LeafTy &LHS, const LeafTy &RHS) {
+ LeafTy Copy = LHS;
+ return Copy += RHS;
+ }
+
+ friend LeafTy operator-(const LeafTy &LHS, const LeafTy &RHS) {
+ LeafTy Copy = LHS;
+ return Copy -= RHS;
+ }
+
+ friend LeafTy operator*(const LeafTy &LHS, ScalarTy RHS) {
+ LeafTy Copy = LHS;
+ return Copy *= RHS;
+ }
+
+ template <typename U = ScalarTy>
+ friend typename std::enable_if<std::is_signed<U>::value, LeafTy>::type
+ operator-(const LeafTy &LHS) {
+ LeafTy Copy = LHS;
+ return Copy *= -1;
+ }
+
public:
- using ScalarTy = typename LinearPolyBaseTypeTraits<LeafTy>::ScalarTy;
- static constexpr auto Dimensions = LinearPolyBaseTypeTraits<LeafTy>::Dimensions;
- static_assert(Dimensions != std::numeric_limits<unsigned>::max(),
- "Dimensions out of range");
-
-private:
- std::array<ScalarTy, Dimensions> Coefficients;
-
-protected:
- LinearPolyBase(ArrayRef<ScalarTy> Values) {
- std::copy(Values.begin(), Values.end(), Coefficients.begin());
- }
-
-public:
- friend LeafTy &operator+=(LeafTy &LHS, const LeafTy &RHS) {
- for (unsigned I=0; I<Dimensions; ++I)
- LHS.Coefficients[I] += RHS.Coefficients[I];
- return LHS;
- }
-
- friend LeafTy &operator-=(LeafTy &LHS, const LeafTy &RHS) {
- for (unsigned I=0; I<Dimensions; ++I)
- LHS.Coefficients[I] -= RHS.Coefficients[I];
- return LHS;
- }
-
- friend LeafTy &operator*=(LeafTy &LHS, ScalarTy RHS) {
- for (auto &C : LHS.Coefficients)
- C *= RHS;
- return LHS;
- }
-
- friend LeafTy operator+(const LeafTy &LHS, const LeafTy &RHS) {
- LeafTy Copy = LHS;
- return Copy += RHS;
- }
-
- friend LeafTy operator-(const LeafTy &LHS, const LeafTy &RHS) {
- LeafTy Copy = LHS;
- return Copy -= RHS;
- }
-
- friend LeafTy operator*(const LeafTy &LHS, ScalarTy RHS) {
- LeafTy Copy = LHS;
- return Copy *= RHS;
- }
-
- template <typename U = ScalarTy>
- friend typename std::enable_if_t<std::is_signed<U>::value, LeafTy>
- operator-(const LeafTy &LHS) {
- LeafTy Copy = LHS;
- return Copy *= -1;
- }
-
- bool operator==(const LinearPolyBase &RHS) const {
- return std::equal(Coefficients.begin(), Coefficients.end(),
- RHS.Coefficients.begin());
- }
-
- bool operator!=(const LinearPolyBase &RHS) const {
+ bool operator==(const UnivariateLinearPolyBase &RHS) const {
+ return Value == RHS.Value && UnivariateDim == RHS.UnivariateDim;
+ }
+
+ bool operator!=(const UnivariateLinearPolyBase &RHS) const {
return !(*this == RHS);
}
- bool isZero() const {
- return all_of(Coefficients, [](const ScalarTy &C) { return C == 0; });
+ bool isZero() const { return !Value; }
+ bool isNonZero() const { return !isZero(); }
+ explicit operator bool() const { return isNonZero(); }
+ ScalarTy getValue() const { return Value; }
+ ScalarTy getValue(unsigned Dim) const {
+ return Dim == UnivariateDim ? Value : 0;
+ }
+
+ /// Add \p RHS to the value at the univariate dimension.
+ LeafTy getWithIncrement(ScalarTy RHS) {
+ return static_cast<LeafTy>(
+ UnivariateLinearPolyBase(Value + RHS, UnivariateDim));
+ }
+
+ /// Subtract \p RHS from the value at the univariate dimension.
+ LeafTy getWithDecrement(ScalarTy RHS) {
+ return static_cast<LeafTy>(
+ UnivariateLinearPolyBase(Value - RHS, UnivariateDim));
}
- bool isNonZero() const { return !isZero(); }
- explicit operator bool() const { return isNonZero(); }
-
- ScalarTy getValue(unsigned Dim) const { return Coefficients[Dim]; }
};
-//===----------------------------------------------------------------------===//
-// StackOffset - Represent an offset with named fixed and scalable components.
-//===----------------------------------------------------------------------===//
-
-class StackOffset;
-template <> struct LinearPolyBaseTypeTraits<StackOffset> {
- using ScalarTy = int64_t;
- static constexpr unsigned Dimensions = 2;
-};
-
-/// StackOffset is a class to represent an offset with 2 dimensions,
-/// named fixed and scalable, respectively. This class allows a value for both
-/// dimensions to depict e.g. "8 bytes and 16 scalable bytes", which is needed
-/// to represent stack offsets.
-class StackOffset : public LinearPolyBase<StackOffset> {
-protected:
- StackOffset(ScalarTy Fixed, ScalarTy Scalable)
- : LinearPolyBase<StackOffset>({Fixed, Scalable}) {}
-
+
+//===----------------------------------------------------------------------===//
+// LinearPolySize - base class for fixed- or scalable sizes.
+// ^ ^
+// | |
+// | +----- ElementCount - Leaf class to represent an element count
+// | (vscale x unsigned)
+// |
+// +-------- TypeSize - Leaf class to represent a type size
+// (vscale x uint64_t)
+//===----------------------------------------------------------------------===//
+
+/// LinearPolySize is a base class to represent sizes. It is either
+/// fixed-sized or it is scalable-sized, but it cannot be both.
+template <typename LeafTy>
+class LinearPolySize : public UnivariateLinearPolyBase<LeafTy> {
+ // Make the parent class a friend, so that it can access the protected
+ // conversion/copy-constructor for UnivariatePolyBase<LeafTy> ->
+ // LinearPolySize<LeafTy>.
+ friend class UnivariateLinearPolyBase<LeafTy>;
+
+public:
+ using ScalarTy = typename UnivariateLinearPolyBase<LeafTy>::ScalarTy;
+ enum Dims : unsigned { FixedDim = 0, ScalableDim = 1 };
+
+protected:
+ LinearPolySize(ScalarTy MinVal, Dims D)
+ : UnivariateLinearPolyBase<LeafTy>(MinVal, D) {}
+
+ LinearPolySize(const UnivariateLinearPolyBase<LeafTy> &V)
+ : UnivariateLinearPolyBase<LeafTy>(V) {}
+
public:
- StackOffset() : StackOffset({0, 0}) {}
- StackOffset(const LinearPolyBase<StackOffset> &Other)
- : LinearPolyBase<StackOffset>(Other) {}
- static StackOffset getFixed(ScalarTy Fixed) { return {Fixed, 0}; }
- static StackOffset getScalable(ScalarTy Scalable) { return {0, Scalable}; }
- static StackOffset get(ScalarTy Fixed, ScalarTy Scalable) {
- return {Fixed, Scalable};
- }
-
- ScalarTy getFixed() const { return this->getValue(0); }
- ScalarTy getScalable() const { return this->getValue(1); }
-};
-
-//===----------------------------------------------------------------------===//
-// UnivariateLinearPolyBase - a base class for linear polynomials with multiple
-// dimensions, but where only one dimension can be set at any time.
-// This can e.g. be used to describe sizes that are either fixed or scalable.
-//===----------------------------------------------------------------------===//
-
-/// UnivariateLinearPolyBase is a base class for ElementCount and TypeSize.
-/// Like LinearPolyBase it tries to represent a linear polynomial
-/// where only one dimension can be set at any time, e.g.
-/// 0 * scale0 + 0 * scale1 + ... + cJ * scaleJ + ... + 0 * scaleK
-/// The dimension that is set is the univariate dimension.
-template <typename LeafTy>
-class UnivariateLinearPolyBase {
-public:
- using ScalarTy = typename LinearPolyBaseTypeTraits<LeafTy>::ScalarTy;
- static constexpr auto Dimensions = LinearPolyBaseTypeTraits<LeafTy>::Dimensions;
- static_assert(Dimensions != std::numeric_limits<unsigned>::max(),
- "Dimensions out of range");
-
-protected:
- ScalarTy Value; // The value at the univeriate dimension.
- unsigned UnivariateDim; // The univeriate dimension.
-
- UnivariateLinearPolyBase(ScalarTy Val, unsigned UnivariateDim)
- : Value(Val), UnivariateDim(UnivariateDim) {
- assert(UnivariateDim < Dimensions && "Dimension out of range");
- }
-
- friend LeafTy &operator+=(LeafTy &LHS, const LeafTy &RHS) {
- assert(LHS.UnivariateDim == RHS.UnivariateDim && "Invalid dimensions");
- LHS.Value += RHS.Value;
- return LHS;
- }
-
- friend LeafTy &operator-=(LeafTy &LHS, const LeafTy &RHS) {
- assert(LHS.UnivariateDim == RHS.UnivariateDim && "Invalid dimensions");
- LHS.Value -= RHS.Value;
- return LHS;
- }
-
- friend LeafTy &operator*=(LeafTy &LHS, ScalarTy RHS) {
- LHS.Value *= RHS;
- return LHS;
- }
-
- friend LeafTy operator+(const LeafTy &LHS, const LeafTy &RHS) {
- LeafTy Copy = LHS;
- return Copy += RHS;
- }
-
- friend LeafTy operator-(const LeafTy &LHS, const LeafTy &RHS) {
- LeafTy Copy = LHS;
- return Copy -= RHS;
- }
-
- friend LeafTy operator*(const LeafTy &LHS, ScalarTy RHS) {
- LeafTy Copy = LHS;
- return Copy *= RHS;
- }
-
- template <typename U = ScalarTy>
- friend typename std::enable_if<std::is_signed<U>::value, LeafTy>::type
- operator-(const LeafTy &LHS) {
- LeafTy Copy = LHS;
- return Copy *= -1;
- }
-
-public:
- bool operator==(const UnivariateLinearPolyBase &RHS) const {
- return Value == RHS.Value && UnivariateDim == RHS.UnivariateDim;
- }
-
- bool operator!=(const UnivariateLinearPolyBase &RHS) const {
- return !(*this == RHS);
- }
-
- bool isZero() const { return !Value; }
- bool isNonZero() const { return !isZero(); }
- explicit operator bool() const { return isNonZero(); }
- ScalarTy getValue() const { return Value; }
- ScalarTy getValue(unsigned Dim) const {
- return Dim == UnivariateDim ? Value : 0;
- }
-
- /// Add \p RHS to the value at the univariate dimension.
- LeafTy getWithIncrement(ScalarTy RHS) {
- return static_cast<LeafTy>(
- UnivariateLinearPolyBase(Value + RHS, UnivariateDim));
- }
-
- /// Subtract \p RHS from the value at the univariate dimension.
- LeafTy getWithDecrement(ScalarTy RHS) {
- return static_cast<LeafTy>(
- UnivariateLinearPolyBase(Value - RHS, UnivariateDim));
- }
-};
-
-
-//===----------------------------------------------------------------------===//
-// LinearPolySize - base class for fixed- or scalable sizes.
-// ^ ^
-// | |
-// | +----- ElementCount - Leaf class to represent an element count
-// | (vscale x unsigned)
-// |
-// +-------- TypeSize - Leaf class to represent a type size
-// (vscale x uint64_t)
-//===----------------------------------------------------------------------===//
-
-/// LinearPolySize is a base class to represent sizes. It is either
-/// fixed-sized or it is scalable-sized, but it cannot be both.
-template <typename LeafTy>
-class LinearPolySize : public UnivariateLinearPolyBase<LeafTy> {
- // Make the parent class a friend, so that it can access the protected
- // conversion/copy-constructor for UnivariatePolyBase<LeafTy> ->
- // LinearPolySize<LeafTy>.
- friend class UnivariateLinearPolyBase<LeafTy>;
-
-public:
- using ScalarTy = typename UnivariateLinearPolyBase<LeafTy>::ScalarTy;
- enum Dims : unsigned { FixedDim = 0, ScalableDim = 1 };
-
-protected:
- LinearPolySize(ScalarTy MinVal, Dims D)
- : UnivariateLinearPolyBase<LeafTy>(MinVal, D) {}
-
- LinearPolySize(const UnivariateLinearPolyBase<LeafTy> &V)
- : UnivariateLinearPolyBase<LeafTy>(V) {}
-
-public:
-
- static LeafTy getFixed(ScalarTy MinVal) {
- return static_cast<LeafTy>(LinearPolySize(MinVal, FixedDim));
- }
- static LeafTy getScalable(ScalarTy MinVal) {
- return static_cast<LeafTy>(LinearPolySize(MinVal, ScalableDim));
- }
- static LeafTy get(ScalarTy MinVal, bool Scalable) {
- return static_cast<LeafTy>(
- LinearPolySize(MinVal, Scalable ? ScalableDim : FixedDim));
- }
- static LeafTy getNull() { return get(0, false); }
-
- /// Returns the minimum value this size can represent.
- ScalarTy getKnownMinValue() const { return this->getValue(); }
- /// Returns whether the size is scaled by a runtime quantity (vscale).
- bool isScalable() const { return this->UnivariateDim == ScalableDim; }
- /// A return value of true indicates we know at compile time that the number
- /// of elements (vscale * Min) is definitely even. However, returning false
- /// does not guarantee that the total number of elements is odd.
- bool isKnownEven() const { return (getKnownMinValue() & 0x1) == 0; }
- /// This function tells the caller whether the element count is known at
- /// compile time to be a multiple of the scalar value RHS.
- bool isKnownMultipleOf(ScalarTy RHS) const {
- return getKnownMinValue() % RHS == 0;
- }
-
- // Return the minimum value with the assumption that the count is exact.
- // Use in places where a scalable count doesn't make sense (e.g. non-vector
- // types, or vectors in backends which don't support scalable vectors).
- ScalarTy getFixedValue() const {
- assert(!isScalable() &&
- "Request for a fixed element count on a scalable object");
- return getKnownMinValue();
- }
-
- // For some cases, size ordering between scalable and fixed size types cannot
+
+ static LeafTy getFixed(ScalarTy MinVal) {
+ return static_cast<LeafTy>(LinearPolySize(MinVal, FixedDim));
+ }
+ static LeafTy getScalable(ScalarTy MinVal) {
+ return static_cast<LeafTy>(LinearPolySize(MinVal, ScalableDim));
+ }
+ static LeafTy get(ScalarTy MinVal, bool Scalable) {
+ return static_cast<LeafTy>(
+ LinearPolySize(MinVal, Scalable ? ScalableDim : FixedDim));
+ }
+ static LeafTy getNull() { return get(0, false); }
+
+ /// Returns the minimum value this size can represent.
+ ScalarTy getKnownMinValue() const { return this->getValue(); }
+ /// Returns whether the size is scaled by a runtime quantity (vscale).
+ bool isScalable() const { return this->UnivariateDim == ScalableDim; }
+ /// A return value of true indicates we know at compile time that the number
+ /// of elements (vscale * Min) is definitely even. However, returning false
+ /// does not guarantee that the total number of elements is odd.
+ bool isKnownEven() const { return (getKnownMinValue() & 0x1) == 0; }
+ /// This function tells the caller whether the element count is known at
+ /// compile time to be a multiple of the scalar value RHS.
+ bool isKnownMultipleOf(ScalarTy RHS) const {
+ return getKnownMinValue() % RHS == 0;
+ }
+
+ // Return the minimum value with the assumption that the count is exact.
+ // Use in places where a scalable count doesn't make sense (e.g. non-vector
+ // types, or vectors in backends which don't support scalable vectors).
+ ScalarTy getFixedValue() const {
+ assert(!isScalable() &&
+ "Request for a fixed element count on a scalable object");
+ return getKnownMinValue();
+ }
+
+ // For some cases, size ordering between scalable and fixed size types cannot
// be determined at compile time, so such comparisons aren't allowed.
//
// e.g. <vscale x 2 x i16> could be bigger than <4 x i32> with a runtime
// vscale >= 5, equal sized with a vscale of 4, and smaller with
// a vscale <= 3.
//
- // All the functions below make use of the fact vscale is always >= 1, which
- // means that <vscale x 4 x i32> is guaranteed to be >= <4 x i32>, etc.
-
- static bool isKnownLT(const LinearPolySize &LHS, const LinearPolySize &RHS) {
- if (!LHS.isScalable() || RHS.isScalable())
- return LHS.getKnownMinValue() < RHS.getKnownMinValue();
- return false;
- }
-
- static bool isKnownGT(const LinearPolySize &LHS, const LinearPolySize &RHS) {
- if (LHS.isScalable() || !RHS.isScalable())
- return LHS.getKnownMinValue() > RHS.getKnownMinValue();
- return false;
- }
-
- static bool isKnownLE(const LinearPolySize &LHS, const LinearPolySize &RHS) {
- if (!LHS.isScalable() || RHS.isScalable())
- return LHS.getKnownMinValue() <= RHS.getKnownMinValue();
- return false;
- }
-
- static bool isKnownGE(const LinearPolySize &LHS, const LinearPolySize &RHS) {
- if (LHS.isScalable() || !RHS.isScalable())
- return LHS.getKnownMinValue() >= RHS.getKnownMinValue();
- return false;
- }
-
- /// We do not provide the '/' operator here because division for polynomial
- /// types does not work in the same way as for normal integer types. We can
- /// only divide the minimum value (or coefficient) by RHS, which is not the
- /// same as
- /// (Min * Vscale) / RHS
- /// The caller is recommended to use this function in combination with
- /// isKnownMultipleOf(RHS), which lets the caller know if it's possible to
- /// perform a lossless divide by RHS.
- LeafTy divideCoefficientBy(ScalarTy RHS) const {
- return static_cast<LeafTy>(
- LinearPolySize::get(getKnownMinValue() / RHS, isScalable()));
- }
-
- LeafTy coefficientNextPowerOf2() const {
- return static_cast<LeafTy>(LinearPolySize::get(
- static_cast<ScalarTy>(llvm::NextPowerOf2(getKnownMinValue())),
- isScalable()));
- }
-
- /// Printing function.
- void print(raw_ostream &OS) const {
- if (isScalable())
- OS << "vscale x ";
- OS << getKnownMinValue();
- }
-};
-
-class ElementCount;
-template <> struct LinearPolyBaseTypeTraits<ElementCount> {
- using ScalarTy = unsigned;
- static constexpr unsigned Dimensions = 2;
-};
-
-class ElementCount : public LinearPolySize<ElementCount> {
-public:
-
- ElementCount(const LinearPolySize<ElementCount> &V) : LinearPolySize(V) {}
-
- /// Counting predicates.
- ///
- ///@{ Number of elements..
- /// Exactly one element.
- bool isScalar() const { return !isScalable() && getKnownMinValue() == 1; }
- /// One or more elements.
- bool isVector() const {
- return (isScalable() && getKnownMinValue() != 0) || getKnownMinValue() > 1;
- }
- ///@}
-};
-
-// This class is used to represent the size of types. If the type is of fixed
-class TypeSize;
-template <> struct LinearPolyBaseTypeTraits<TypeSize> {
- using ScalarTy = uint64_t;
- static constexpr unsigned Dimensions = 2;
-};
-
-// TODO: Most functionality in this class will gradually be phased out
-// so it will resemble LinearPolySize as much as possible.
-//
-// TypeSize is used to represent the size of types. If the type is of fixed
-// size, it will represent the exact size. If the type is a scalable vector,
-// it will represent the known minimum size.
-class TypeSize : public LinearPolySize<TypeSize> {
-public:
- TypeSize(const LinearPolySize<TypeSize> &V) : LinearPolySize(V) {}
- TypeSize(ScalarTy MinVal, bool IsScalable)
- : LinearPolySize(LinearPolySize::get(MinVal, IsScalable)) {}
-
- static TypeSize Fixed(ScalarTy MinVal) { return TypeSize(MinVal, false); }
- static TypeSize Scalable(ScalarTy MinVal) { return TypeSize(MinVal, true); }
-
- ScalarTy getFixedSize() const { return getFixedValue(); }
- ScalarTy getKnownMinSize() const { return getKnownMinValue(); }
-
- // All code for this class below this point is needed because of the
- // temporary implicit conversion to uint64_t. The operator overloads are
- // needed because otherwise the conversion of the parent class
- // UnivariateLinearPolyBase -> TypeSize is ambiguous.
- // TODO: Remove the implicit conversion.
-
+ // All the functions below make use of the fact vscale is always >= 1, which
+ // means that <vscale x 4 x i32> is guaranteed to be >= <4 x i32>, etc.
+
+ static bool isKnownLT(const LinearPolySize &LHS, const LinearPolySize &RHS) {
+ if (!LHS.isScalable() || RHS.isScalable())
+ return LHS.getKnownMinValue() < RHS.getKnownMinValue();
+ return false;
+ }
+
+ static bool isKnownGT(const LinearPolySize &LHS, const LinearPolySize &RHS) {
+ if (LHS.isScalable() || !RHS.isScalable())
+ return LHS.getKnownMinValue() > RHS.getKnownMinValue();
+ return false;
+ }
+
+ static bool isKnownLE(const LinearPolySize &LHS, const LinearPolySize &RHS) {
+ if (!LHS.isScalable() || RHS.isScalable())
+ return LHS.getKnownMinValue() <= RHS.getKnownMinValue();
+ return false;
+ }
+
+ static bool isKnownGE(const LinearPolySize &LHS, const LinearPolySize &RHS) {
+ if (LHS.isScalable() || !RHS.isScalable())
+ return LHS.getKnownMinValue() >= RHS.getKnownMinValue();
+ return false;
+ }
+
+ /// We do not provide the '/' operator here because division for polynomial
+ /// types does not work in the same way as for normal integer types. We can
+ /// only divide the minimum value (or coefficient) by RHS, which is not the
+ /// same as
+ /// (Min * Vscale) / RHS
+ /// The caller is recommended to use this function in combination with
+ /// isKnownMultipleOf(RHS), which lets the caller know if it's possible to
+ /// perform a lossless divide by RHS.
+ LeafTy divideCoefficientBy(ScalarTy RHS) const {
+ return static_cast<LeafTy>(
+ LinearPolySize::get(getKnownMinValue() / RHS, isScalable()));
+ }
+
+ LeafTy coefficientNextPowerOf2() const {
+ return static_cast<LeafTy>(LinearPolySize::get(
+ static_cast<ScalarTy>(llvm::NextPowerOf2(getKnownMinValue())),
+ isScalable()));
+ }
+
+ /// Printing function.
+ void print(raw_ostream &OS) const {
+ if (isScalable())
+ OS << "vscale x ";
+ OS << getKnownMinValue();
+ }
+};
+
+class ElementCount;
+template <> struct LinearPolyBaseTypeTraits<ElementCount> {
+ using ScalarTy = unsigned;
+ static constexpr unsigned Dimensions = 2;
+};
+
+class ElementCount : public LinearPolySize<ElementCount> {
+public:
+
+ ElementCount(const LinearPolySize<ElementCount> &V) : LinearPolySize(V) {}
+
+ /// Counting predicates.
+ ///
+ ///@{ Number of elements..
+ /// Exactly one element.
+ bool isScalar() const { return !isScalable() && getKnownMinValue() == 1; }
+ /// One or more elements.
+ bool isVector() const {
+ return (isScalable() && getKnownMinValue() != 0) || getKnownMinValue() > 1;
+ }
+ ///@}
+};
+
+// This class is used to represent the size of types. If the type is of fixed
+class TypeSize;
+template <> struct LinearPolyBaseTypeTraits<TypeSize> {
+ using ScalarTy = uint64_t;
+ static constexpr unsigned Dimensions = 2;
+};
+
+// TODO: Most functionality in this class will gradually be phased out
+// so it will resemble LinearPolySize as much as possible.
+//
+// TypeSize is used to represent the size of types. If the type is of fixed
+// size, it will represent the exact size. If the type is a scalable vector,
+// it will represent the known minimum size.
+class TypeSize : public LinearPolySize<TypeSize> {
+public:
+ TypeSize(const LinearPolySize<TypeSize> &V) : LinearPolySize(V) {}
+ TypeSize(ScalarTy MinVal, bool IsScalable)
+ : LinearPolySize(LinearPolySize::get(MinVal, IsScalable)) {}
+
+ static TypeSize Fixed(ScalarTy MinVal) { return TypeSize(MinVal, false); }
+ static TypeSize Scalable(ScalarTy MinVal) { return TypeSize(MinVal, true); }
+
+ ScalarTy getFixedSize() const { return getFixedValue(); }
+ ScalarTy getKnownMinSize() const { return getKnownMinValue(); }
+
+ // All code for this class below this point is needed because of the
+ // temporary implicit conversion to uint64_t. The operator overloads are
+ // needed because otherwise the conversion of the parent class
+ // UnivariateLinearPolyBase -> TypeSize is ambiguous.
+ // TODO: Remove the implicit conversion.
+
// Casts to a uint64_t if this is a fixed-width size.
//
// This interface is deprecated and will be removed in a future version
@@ -445,53 +445,53 @@ public:
// To determine how to upgrade the code:
//
// if (<algorithm works for both scalable and fixed-width vectors>)
- // use getKnownMinValue()
+ // use getKnownMinValue()
// else if (<algorithm works only for fixed-width vectors>) {
// if <algorithm can be adapted for both scalable and fixed-width vectors>
- // update the algorithm and use getKnownMinValue()
+ // update the algorithm and use getKnownMinValue()
// else
- // bail out early for scalable vectors and use getFixedValue()
+ // bail out early for scalable vectors and use getFixedValue()
// }
- operator ScalarTy() const {
+ operator ScalarTy() const {
#ifdef STRICT_FIXED_SIZE_VECTORS
- return getFixedValue();
+ return getFixedValue();
#else
if (isScalable())
WithColor::warning() << "Compiler has made implicit assumption that "
"TypeSize is not scalable. This may or may not "
"lead to broken code.\n";
- return getKnownMinValue();
+ return getKnownMinValue();
#endif
}
- // Additional operators needed to avoid ambiguous parses
- // because of the implicit conversion hack.
- friend TypeSize operator*(const TypeSize &LHS, const int RHS) {
- return LHS * (ScalarTy)RHS;
+ // Additional operators needed to avoid ambiguous parses
+ // because of the implicit conversion hack.
+ friend TypeSize operator*(const TypeSize &LHS, const int RHS) {
+ return LHS * (ScalarTy)RHS;
}
- friend TypeSize operator*(const TypeSize &LHS, const unsigned RHS) {
- return LHS * (ScalarTy)RHS;
+ friend TypeSize operator*(const TypeSize &LHS, const unsigned RHS) {
+ return LHS * (ScalarTy)RHS;
}
- friend TypeSize operator*(const TypeSize &LHS, const int64_t RHS) {
- return LHS * (ScalarTy)RHS;
+ friend TypeSize operator*(const TypeSize &LHS, const int64_t RHS) {
+ return LHS * (ScalarTy)RHS;
}
friend TypeSize operator*(const int LHS, const TypeSize &RHS) {
- return RHS * LHS;
+ return RHS * LHS;
+ }
+ friend TypeSize operator*(const unsigned LHS, const TypeSize &RHS) {
+ return RHS * LHS;
}
- friend TypeSize operator*(const unsigned LHS, const TypeSize &RHS) {
- return RHS * LHS;
- }
friend TypeSize operator*(const int64_t LHS, const TypeSize &RHS) {
- return RHS * LHS;
+ return RHS * LHS;
}
- friend TypeSize operator*(const uint64_t LHS, const TypeSize &RHS) {
- return RHS * LHS;
+ friend TypeSize operator*(const uint64_t LHS, const TypeSize &RHS) {
+ return RHS * LHS;
}
-};
+};
-//===----------------------------------------------------------------------===//
-// Utilities
-//===----------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
+// Utilities
+//===----------------------------------------------------------------------===//
/// Returns a TypeSize with a known minimum size that is the next integer
/// (mod 2**64) that is greater than or equal to \p Value and is a multiple
@@ -500,35 +500,35 @@ public:
/// Similar to the alignTo functions in MathExtras.h
inline TypeSize alignTo(TypeSize Size, uint64_t Align) {
assert(Align != 0u && "Align must be non-zero");
- return {(Size.getKnownMinValue() + Align - 1) / Align * Align,
+ return {(Size.getKnownMinValue() + Align - 1) / Align * Align,
Size.isScalable()};
}
-/// Stream operator function for `LinearPolySize`.
-template <typename LeafTy>
-inline raw_ostream &operator<<(raw_ostream &OS,
- const LinearPolySize<LeafTy> &PS) {
- PS.print(OS);
- return OS;
-}
-
-template <typename T> struct DenseMapInfo;
+/// Stream operator function for `LinearPolySize`.
+template <typename LeafTy>
+inline raw_ostream &operator<<(raw_ostream &OS,
+ const LinearPolySize<LeafTy> &PS) {
+ PS.print(OS);
+ return OS;
+}
+
+template <typename T> struct DenseMapInfo;
template <> struct DenseMapInfo<ElementCount> {
- static inline ElementCount getEmptyKey() {
- return ElementCount::getScalable(~0U);
- }
- static inline ElementCount getTombstoneKey() {
- return ElementCount::getFixed(~0U - 1);
- }
- static unsigned getHashValue(const ElementCount &EltCnt) {
- unsigned HashVal = EltCnt.getKnownMinValue() * 37U;
- if (EltCnt.isScalable())
- return (HashVal - 1U);
+ static inline ElementCount getEmptyKey() {
+ return ElementCount::getScalable(~0U);
+ }
+ static inline ElementCount getTombstoneKey() {
+ return ElementCount::getFixed(~0U - 1);
+ }
+ static unsigned getHashValue(const ElementCount &EltCnt) {
+ unsigned HashVal = EltCnt.getKnownMinValue() * 37U;
+ if (EltCnt.isScalable())
+ return (HashVal - 1U);
- return HashVal;
+ return HashVal;
}
- static bool isEqual(const ElementCount &LHS, const ElementCount &RHS) {
+ static bool isEqual(const ElementCount &LHS, const ElementCount &RHS) {
return LHS == RHS;
}
};
diff --git a/contrib/libs/llvm12/include/llvm/Support/VirtualFileSystem.h b/contrib/libs/llvm12/include/llvm/Support/VirtualFileSystem.h
index dd75b493f0..4729450b67 100644
--- a/contrib/libs/llvm12/include/llvm/Support/VirtualFileSystem.h
+++ b/contrib/libs/llvm12/include/llvm/Support/VirtualFileSystem.h
@@ -45,7 +45,7 @@
namespace llvm {
class MemoryBuffer;
-class MemoryBufferRef;
+class MemoryBufferRef;
class Twine;
namespace vfs {
@@ -503,8 +503,8 @@ public:
/// false if the file or directory already exists in the file system with
/// different contents.
bool addFileNoOwn(const Twine &Path, time_t ModificationTime,
- const llvm::MemoryBufferRef &Buffer,
- Optional<uint32_t> User = None,
+ const llvm::MemoryBufferRef &Buffer,
+ Optional<uint32_t> User = None,
Optional<uint32_t> Group = None,
Optional<llvm::sys::fs::file_type> Type = None,
Optional<llvm::sys::fs::perms> Perms = None);
@@ -539,7 +539,7 @@ llvm::sys::fs::UniqueID getNextVirtualUniqueID();
/// Gets a \p FileSystem for a virtual file system described in YAML
/// format.
-std::unique_ptr<FileSystem>
+std::unique_ptr<FileSystem>
getVFSFromYAML(std::unique_ptr<llvm::MemoryBuffer> Buffer,
llvm::SourceMgr::DiagHandlerTy DiagHandler,
StringRef YAMLFilePath, void *DiagContext = nullptr,
@@ -690,13 +690,13 @@ private:
friend class VFSFromYamlDirIterImpl;
friend class RedirectingFileSystemParser;
- bool shouldUseExternalFS() const { return IsFallthrough; }
+ bool shouldUseExternalFS() const { return IsFallthrough; }
+
+ /// Canonicalize path by removing ".", "..", "./", components. This is
+ /// a VFS request, do not bother about symlinks in the path components
+ /// but canonicalize in order to perform the correct entry search.
+ std::error_code makeCanonical(SmallVectorImpl<char> &Path) const;
- /// Canonicalize path by removing ".", "..", "./", components. This is
- /// a VFS request, do not bother about symlinks in the path components
- /// but canonicalize in order to perform the correct entry search.
- std::error_code makeCanonical(SmallVectorImpl<char> &Path) const;
-
// In a RedirectingFileSystem, keys can be specified in Posix or Windows
// style (or even a mixture of both), so this comparison helper allows
// slashes (representing a root) to match backslashes (and vice versa). Note
@@ -761,20 +761,20 @@ private:
public:
/// Looks up \p Path in \c Roots.
- ErrorOr<Entry *> lookupPath(StringRef Path) const;
+ ErrorOr<Entry *> lookupPath(StringRef Path) const;
/// Parses \p Buffer, which is expected to be in YAML format and
/// returns a virtual file system representing its contents.
- static std::unique_ptr<RedirectingFileSystem>
+ static std::unique_ptr<RedirectingFileSystem>
create(std::unique_ptr<MemoryBuffer> Buffer,
SourceMgr::DiagHandlerTy DiagHandler, StringRef YAMLFilePath,
void *DiagContext, IntrusiveRefCntPtr<FileSystem> ExternalFS);
- /// Redirect each of the remapped files from first to second.
- static std::unique_ptr<RedirectingFileSystem>
- create(ArrayRef<std::pair<std::string, std::string>> RemappedFiles,
- bool UseExternalNames, FileSystem &ExternalFS);
-
+ /// Redirect each of the remapped files from first to second.
+ static std::unique_ptr<RedirectingFileSystem>
+ create(ArrayRef<std::pair<std::string, std::string>> RemappedFiles,
+ bool UseExternalNames, FileSystem &ExternalFS);
+
ErrorOr<Status> status(const Twine &Path) override;
ErrorOr<std::unique_ptr<File>> openFileForRead(const Twine &Path) override;
@@ -795,10 +795,10 @@ public:
StringRef getExternalContentsPrefixDir() const;
- void setFallthrough(bool Fallthrough);
-
- std::vector<llvm::StringRef> getRoots() const;
-
+ void setFallthrough(bool Fallthrough);
+
+ std::vector<llvm::StringRef> getRoots() const;
+
void dump(raw_ostream &OS) const;
void dumpEntry(raw_ostream &OS, Entry *E, int NumSpaces = 0) const;
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
diff --git a/contrib/libs/llvm12/include/llvm/Support/Win64EH.h b/contrib/libs/llvm12/include/llvm/Support/Win64EH.h
index 78057486b4..a2f44c78da 100644
--- a/contrib/libs/llvm12/include/llvm/Support/Win64EH.h
+++ b/contrib/libs/llvm12/include/llvm/Support/Win64EH.h
@@ -45,14 +45,14 @@ enum UnwindOpcodes {
// The following set of unwind opcodes is for ARM64. They are documented at
// https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
UOP_AllocMedium,
- UOP_SaveR19R20X,
+ UOP_SaveR19R20X,
UOP_SaveFPLRX,
UOP_SaveFPLR,
UOP_SaveReg,
UOP_SaveRegX,
UOP_SaveRegP,
UOP_SaveRegPX,
- UOP_SaveLRPair,
+ UOP_SaveLRPair,
UOP_SaveFReg,
UOP_SaveFRegX,
UOP_SaveFRegP,
@@ -60,11 +60,11 @@ enum UnwindOpcodes {
UOP_SetFP,
UOP_AddFP,
UOP_Nop,
- UOP_End,
- UOP_SaveNext,
- UOP_TrapFrame,
- UOP_Context,
- UOP_ClearUnwoundToCall
+ UOP_End,
+ UOP_SaveNext,
+ UOP_TrapFrame,
+ UOP_Context,
+ UOP_ClearUnwoundToCall
};
/// UnwindCode - This union describes a single operation in a function prolog,
diff --git a/contrib/libs/llvm12/include/llvm/Support/X86TargetParser.def b/contrib/libs/llvm12/include/llvm/Support/X86TargetParser.def
index 78831f4f66..ec19ce4e7c 100644
--- a/contrib/libs/llvm12/include/llvm/Support/X86TargetParser.def
+++ b/contrib/libs/llvm12/include/llvm/Support/X86TargetParser.def
@@ -44,7 +44,7 @@ X86_CPU_TYPE(INTEL_KNM, "knm")
X86_CPU_TYPE(INTEL_GOLDMONT, "goldmont")
X86_CPU_TYPE(INTEL_GOLDMONT_PLUS, "goldmont-plus")
X86_CPU_TYPE(INTEL_TREMONT, "tremont")
-X86_CPU_TYPE(AMDFAM19H, "amdfam19h")
+X86_CPU_TYPE(AMDFAM19H, "amdfam19h")
// Alternate names supported by __builtin_cpu_is and target multiversioning.
X86_CPU_TYPE_ALIAS(INTEL_BONNELL, "atom")
@@ -85,9 +85,9 @@ X86_CPU_SUBTYPE(AMDFAM17H_ZNVER2, "znver2")
X86_CPU_SUBTYPE(INTEL_COREI7_CASCADELAKE, "cascadelake")
X86_CPU_SUBTYPE(INTEL_COREI7_TIGERLAKE, "tigerlake")
X86_CPU_SUBTYPE(INTEL_COREI7_COOPERLAKE, "cooperlake")
-X86_CPU_SUBTYPE(INTEL_COREI7_SAPPHIRERAPIDS, "sapphirerapids")
-X86_CPU_SUBTYPE(INTEL_COREI7_ALDERLAKE, "alderlake")
-X86_CPU_SUBTYPE(AMDFAM19H_ZNVER3, "znver3")
+X86_CPU_SUBTYPE(INTEL_COREI7_SAPPHIRERAPIDS, "sapphirerapids")
+X86_CPU_SUBTYPE(INTEL_COREI7_ALDERLAKE, "alderlake")
+X86_CPU_SUBTYPE(AMDFAM19H_ZNVER3, "znver3")
#undef X86_CPU_SUBTYPE
@@ -157,8 +157,8 @@ X86_FEATURE (F16C, "f16c")
X86_FEATURE (FSGSBASE, "fsgsbase")
X86_FEATURE (FXSR, "fxsr")
X86_FEATURE (INVPCID, "invpcid")
-X86_FEATURE (KL, "kl")
-X86_FEATURE (WIDEKL, "widekl")
+X86_FEATURE (KL, "kl")
+X86_FEATURE (WIDEKL, "widekl")
X86_FEATURE (LWP, "lwp")
X86_FEATURE (LZCNT, "lzcnt")
X86_FEATURE (MOVBE, "movbe")
@@ -181,7 +181,7 @@ X86_FEATURE (SHA, "sha")
X86_FEATURE (SHSTK, "shstk")
X86_FEATURE (TBM, "tbm")
X86_FEATURE (TSXLDTRK, "tsxldtrk")
-X86_FEATURE (UINTR, "uintr")
+X86_FEATURE (UINTR, "uintr")
X86_FEATURE (VAES, "vaes")
X86_FEATURE (VZEROUPPER, "vzeroupper")
X86_FEATURE (WAITPKG, "waitpkg")
@@ -191,8 +191,8 @@ X86_FEATURE (XSAVE, "xsave")
X86_FEATURE (XSAVEC, "xsavec")
X86_FEATURE (XSAVEOPT, "xsaveopt")
X86_FEATURE (XSAVES, "xsaves")
-X86_FEATURE (HRESET, "hreset")
-X86_FEATURE (AVXVNNI, "avxvnni")
+X86_FEATURE (HRESET, "hreset")
+X86_FEATURE (AVXVNNI, "avxvnni")
// These features aren't really CPU features, but the frontend can set them.
X86_FEATURE (RETPOLINE_EXTERNAL_THUNK, "retpoline-external-thunk")
X86_FEATURE (RETPOLINE_INDIRECT_BRANCHES, "retpoline-indirect-branches")
diff --git a/contrib/libs/llvm12/include/llvm/Support/X86TargetParser.h b/contrib/libs/llvm12/include/llvm/Support/X86TargetParser.h
index 8f67d20b1b..0113042931 100644
--- a/contrib/libs/llvm12/include/llvm/Support/X86TargetParser.h
+++ b/contrib/libs/llvm12/include/llvm/Support/X86TargetParser.h
@@ -21,7 +21,7 @@
#define LLVM_SUPPORT_X86TARGETPARSERCOMMON_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringMap.h"
namespace llvm {
class StringRef;
@@ -107,8 +107,8 @@ enum CPUKind {
CK_IcelakeClient,
CK_IcelakeServer,
CK_Tigerlake,
- CK_SapphireRapids,
- CK_Alderlake,
+ CK_SapphireRapids,
+ CK_Alderlake,
CK_KNL,
CK_KNM,
CK_Lakemont,
@@ -128,26 +128,26 @@ enum CPUKind {
CK_BDVER4,
CK_ZNVER1,
CK_ZNVER2,
- CK_ZNVER3,
+ CK_ZNVER3,
CK_x86_64,
- CK_x86_64_v2,
- CK_x86_64_v3,
- CK_x86_64_v4,
+ CK_x86_64_v2,
+ CK_x86_64_v3,
+ CK_x86_64_v4,
CK_Geode,
};
/// Parse \p CPU string into a CPUKind. Will only accept 64-bit capable CPUs if
/// \p Only64Bit is true.
CPUKind parseArchX86(StringRef CPU, bool Only64Bit = false);
-CPUKind parseTuneCPU(StringRef CPU, bool Only64Bit = false);
+CPUKind parseTuneCPU(StringRef CPU, bool Only64Bit = false);
/// Provide a list of valid CPU names. If \p Only64Bit is true, the list will
/// only contain 64-bit capable CPUs.
void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values,
- bool Only64Bit = false);
-/// Provide a list of valid -mtune names.
-void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values,
- bool Only64Bit = false);
+ bool Only64Bit = false);
+/// Provide a list of valid -mtune names.
+void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values,
+ bool Only64Bit = false);
/// Get the key feature prioritizing target multiversioning.
ProcessorFeatures getKeyFeature(CPUKind Kind);
@@ -155,10 +155,10 @@ ProcessorFeatures getKeyFeature(CPUKind Kind);
/// Fill in the features that \p CPU supports into \p Features.
void getFeaturesForCPU(StringRef CPU, SmallVectorImpl<StringRef> &Features);
-/// Set or clear entries in \p Features that are implied to be enabled/disabled
+/// Set or clear entries in \p Features that are implied to be enabled/disabled
/// by the provided \p Feature.
-void updateImpliedFeatures(StringRef Feature, bool Enabled,
- StringMap<bool> &Features);
+void updateImpliedFeatures(StringRef Feature, bool Enabled,
+ StringMap<bool> &Features);
} // namespace X86
} // namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Support/YAMLParser.h b/contrib/libs/llvm12/include/llvm/Support/YAMLParser.h
index 00f9761284..f9682b7048 100644
--- a/contrib/libs/llvm12/include/llvm/Support/YAMLParser.h
+++ b/contrib/libs/llvm12/include/llvm/Support/YAMLParser.h
@@ -47,7 +47,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/SMLoc.h"
-#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/SourceMgr.h"
#include <cassert>
#include <cstddef>
#include <iterator>
@@ -85,9 +85,9 @@ bool scanTokens(StringRef Input);
/// escaped, but emitted verbatim.
std::string escape(StringRef Input, bool EscapePrintable = true);
-/// Parse \p S as a bool according to https://yaml.org/type/bool.html.
-llvm::Optional<bool> parseBool(StringRef S);
-
+/// Parse \p S as a bool according to https://yaml.org/type/bool.html.
+llvm::Optional<bool> parseBool(StringRef S);
+
/// This class represents a YAML stream potentially containing multiple
/// documents.
class Stream {
@@ -110,10 +110,10 @@ public:
return !failed();
}
- void printError(Node *N, const Twine &Msg,
- SourceMgr::DiagKind Kind = SourceMgr::DK_Error);
- void printError(const SMRange &Range, const Twine &Msg,
- SourceMgr::DiagKind Kind = SourceMgr::DK_Error);
+ void printError(Node *N, const Twine &Msg,
+ SourceMgr::DiagKind Kind = SourceMgr::DK_Error);
+ void printError(const SMRange &Range, const Twine &Msg,
+ SourceMgr::DiagKind Kind = SourceMgr::DK_Error);
private:
friend class Document;
@@ -235,7 +235,7 @@ public:
/// Gets the value of this node as a StringRef.
///
- /// \param Storage is used to store the content of the returned StringRef if
+ /// \param Storage is used to store the content of the returned StringRef if
/// it requires any modification from how it appeared in the source.
/// This happens with escaped characters and multi-line literals.
StringRef getValue(SmallVectorImpl<char> &Storage) const;
diff --git a/contrib/libs/llvm12/include/llvm/Support/YAMLTraits.h b/contrib/libs/llvm12/include/llvm/Support/YAMLTraits.h
index ab5a8cdbf4..aeb23970e2 100644
--- a/contrib/libs/llvm12/include/llvm/Support/YAMLTraits.h
+++ b/contrib/libs/llvm12/include/llvm/Support/YAMLTraits.h
@@ -26,9 +26,9 @@
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Regex.h"
-#include "llvm/Support/SMLoc.h"
+#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/VersionTuple.h"
+#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/YAMLParser.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
@@ -70,7 +70,7 @@ struct MappingTraits {
// Must provide:
// static void mapping(IO &io, T &fields);
// Optionally may provide:
- // static std::string validate(IO &io, T &fields);
+ // static std::string validate(IO &io, T &fields);
//
// The optional flow flag will cause generated YAML to use a flow mapping
// (e.g. { a: 0, b: 1 }):
@@ -92,7 +92,7 @@ template <class T, class Context> struct MappingContextTraits {
// Must provide:
// static void mapping(IO &io, T &fields, Context &Ctx);
// Optionally may provide:
- // static std::string validate(IO &io, T &fields, Context &Ctx);
+ // static std::string validate(IO &io, T &fields, Context &Ctx);
//
// The optional flow flag will cause generated YAML to use a flow mapping
// (e.g. { a: 0, b: 1 }):
@@ -430,7 +430,7 @@ template <class T> struct has_MappingTraits<T, EmptyContext> {
// Test if MappingContextTraits<T>::validate() is defined on type T.
template <class T, class Context> struct has_MappingValidateTraits {
- using Signature_validate = std::string (*)(class IO &, T &, Context &);
+ using Signature_validate = std::string (*)(class IO &, T &, Context &);
template <typename U>
static char test(SameType<Signature_validate, &U::validate>*);
@@ -444,7 +444,7 @@ template <class T, class Context> struct has_MappingValidateTraits {
// Test if MappingTraits<T>::validate() is defined on type T.
template <class T> struct has_MappingValidateTraits<T, EmptyContext> {
- using Signature_validate = std::string (*)(class IO &, T &);
+ using Signature_validate = std::string (*)(class IO &, T &);
template <typename U>
static char test(SameType<Signature_validate, &U::validate> *);
@@ -646,7 +646,7 @@ inline bool isNull(StringRef S) {
}
inline bool isBool(StringRef S) {
- // FIXME: using parseBool is causing multiple tests to fail.
+ // FIXME: using parseBool is causing multiple tests to fail.
return S.equals("true") || S.equals("True") || S.equals("TRUE") ||
S.equals("false") || S.equals("False") || S.equals("FALSE");
}
@@ -799,7 +799,7 @@ public:
virtual NodeKind getNodeKind() = 0;
virtual void setError(const Twine &) = 0;
- virtual void setAllowUnknownKeys(bool Allow);
+ virtual void setAllowUnknownKeys(bool Allow);
template <typename T>
void enumCase(T &Val, const char* Str, const T ConstVal) {
@@ -913,7 +913,7 @@ private:
template <typename T, typename Context>
void processKeyWithDefault(const char *Key, Optional<T> &Val,
const Optional<T> &DefaultValue, bool Required,
- Context &Ctx);
+ Context &Ctx);
template <typename T, typename Context>
void processKeyWithDefault(const char *Key, T &Val, const T &DefaultValue,
@@ -1051,7 +1051,7 @@ yamlize(IO &io, T &Val, bool, Context &Ctx) {
else
io.beginMapping();
if (io.outputting()) {
- std::string Err = MappingTraits<T>::validate(io, Val);
+ std::string Err = MappingTraits<T>::validate(io, Val);
if (!Err.empty()) {
errs() << Err << "\n";
assert(Err.empty() && "invalid struct trying to be written as yaml");
@@ -1059,7 +1059,7 @@ yamlize(IO &io, T &Val, bool, Context &Ctx) {
}
detail::doMapping(io, Val, Ctx);
if (!io.outputting()) {
- std::string Err = MappingTraits<T>::validate(io, Val);
+ std::string Err = MappingTraits<T>::validate(io, Val);
if (!Err.empty())
io.setError(Err);
}
@@ -1481,10 +1481,10 @@ private:
static bool classof(const MapHNode *) { return true; }
- using NameToNodeAndLoc =
- StringMap<std::pair<std::unique_ptr<HNode>, SMRange>>;
+ using NameToNodeAndLoc =
+ StringMap<std::pair<std::unique_ptr<HNode>, SMRange>>;
- NameToNodeAndLoc Mapping;
+ NameToNodeAndLoc Mapping;
SmallVector<std::string, 6> ValidKeys;
};
@@ -1506,12 +1506,12 @@ private:
std::unique_ptr<Input::HNode> createHNodes(Node *node);
void setError(HNode *hnode, const Twine &message);
void setError(Node *node, const Twine &message);
- void setError(const SMRange &Range, const Twine &message);
+ void setError(const SMRange &Range, const Twine &message);
+
+ void reportWarning(HNode *hnode, const Twine &message);
+ void reportWarning(Node *hnode, const Twine &message);
+ void reportWarning(const SMRange &Range, const Twine &message);
- void reportWarning(HNode *hnode, const Twine &message);
- void reportWarning(Node *hnode, const Twine &message);
- void reportWarning(const SMRange &Range, const Twine &message);
-
public:
// These are only used by operator>>. They could be private
// if those templated things could be made friends.
@@ -1521,8 +1521,8 @@ public:
/// Returns the current node that's being parsed by the YAML Parser.
const Node *getCurrentNode() const;
- void setAllowUnknownKeys(bool Allow) override;
-
+ void setAllowUnknownKeys(bool Allow) override;
+
private:
SourceMgr SrcMgr; // must be before Strm
std::unique_ptr<llvm::yaml::Stream> Strm;
@@ -1533,7 +1533,7 @@ private:
std::vector<bool> BitValuesUsed;
HNode *CurrentNode = nullptr;
bool ScalarMatchFound = false;
- bool AllowUnknownKeys = false;
+ bool AllowUnknownKeys = false;
};
///
@@ -1593,7 +1593,7 @@ public:
private:
void output(StringRef s);
void outputUpToEndOfLine(StringRef s);
- void newLineCheck(bool EmptySequence = false);
+ void newLineCheck(bool EmptySequence = false);
void outputNewLine();
void paddedKey(StringRef key);
void flowKey(StringRef Key);
@@ -1628,42 +1628,42 @@ private:
StringRef PaddingBeforeContainer;
};
-template <typename T, typename Context>
-void IO::processKeyWithDefault(const char *Key, Optional<T> &Val,
- const Optional<T> &DefaultValue, bool Required,
- Context &Ctx) {
- assert(DefaultValue.hasValue() == false &&
- "Optional<T> shouldn't have a value!");
- void *SaveInfo;
- bool UseDefault = true;
- const bool sameAsDefault = outputting() && !Val.hasValue();
- if (!outputting() && !Val.hasValue())
- Val = T();
- if (Val.hasValue() &&
- this->preflightKey(Key, Required, sameAsDefault, UseDefault, SaveInfo)) {
-
- // When reading an Optional<X> key from a YAML description, we allow the
- // special "<none>" value, which can be used to specify that no value was
- // requested, i.e. the DefaultValue will be assigned. The DefaultValue is
- // usually None.
- bool IsNone = false;
- if (!outputting())
- if (auto *Node = dyn_cast<ScalarNode>(((Input *)this)->getCurrentNode()))
- // We use rtrim to ignore possible white spaces that might exist when a
- // comment is present on the same line.
- IsNone = Node->getRawValue().rtrim(' ') == "<none>";
-
- if (IsNone)
- Val = DefaultValue;
- else
- yamlize(*this, Val.getValue(), Required, Ctx);
- this->postflightKey(SaveInfo);
- } else {
- if (UseDefault)
- Val = DefaultValue;
- }
-}
-
+template <typename T, typename Context>
+void IO::processKeyWithDefault(const char *Key, Optional<T> &Val,
+ const Optional<T> &DefaultValue, bool Required,
+ Context &Ctx) {
+ assert(DefaultValue.hasValue() == false &&
+ "Optional<T> shouldn't have a value!");
+ void *SaveInfo;
+ bool UseDefault = true;
+ const bool sameAsDefault = outputting() && !Val.hasValue();
+ if (!outputting() && !Val.hasValue())
+ Val = T();
+ if (Val.hasValue() &&
+ this->preflightKey(Key, Required, sameAsDefault, UseDefault, SaveInfo)) {
+
+ // When reading an Optional<X> key from a YAML description, we allow the
+ // special "<none>" value, which can be used to specify that no value was
+ // requested, i.e. the DefaultValue will be assigned. The DefaultValue is
+ // usually None.
+ bool IsNone = false;
+ if (!outputting())
+ if (auto *Node = dyn_cast<ScalarNode>(((Input *)this)->getCurrentNode()))
+ // We use rtrim to ignore possible white spaces that might exist when a
+ // comment is present on the same line.
+ IsNone = Node->getRawValue().rtrim(' ') == "<none>";
+
+ if (IsNone)
+ Val = DefaultValue;
+ else
+ yamlize(*this, Val.getValue(), Required, Ctx);
+ this->postflightKey(SaveInfo);
+ } else {
+ if (UseDefault)
+ Val = DefaultValue;
+ }
+}
+
/// YAML I/O does conversion based on types. But often native data types
/// are just a typedef of built in intergral types (e.g. int). But the C++
/// type matching system sees through the typedef and all the typedefed types
@@ -1724,12 +1724,12 @@ struct ScalarTraits<Hex64> {
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
-template <> struct ScalarTraits<VersionTuple> {
- static void output(const VersionTuple &Value, void *, llvm::raw_ostream &Out);
- static StringRef input(StringRef, void *, VersionTuple &);
- static QuotingType mustQuote(StringRef) { return QuotingType::None; }
-};
-
+template <> struct ScalarTraits<VersionTuple> {
+ static void output(const VersionTuple &Value, void *, llvm::raw_ostream &Out);
+ static StringRef input(StringRef, void *, VersionTuple &);
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
+};
+
// Define non-member operator>> so that Input can stream in a document list.
template <typename T>
inline std::enable_if_t<has_DocumentListTraits<T>::value, Input &>
diff --git a/contrib/libs/llvm12/include/llvm/Support/raw_ostream.h b/contrib/libs/llvm12/include/llvm/Support/raw_ostream.h
index 37dc103e5f..adacc8bb0a 100644
--- a/contrib/libs/llvm12/include/llvm/Support/raw_ostream.h
+++ b/contrib/libs/llvm12/include/llvm/Support/raw_ostream.h
@@ -22,9 +22,9 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
-#include <chrono>
+#include <chrono>
#include <cstddef>
#include <cstdint>
#include <cstring>
@@ -39,14 +39,14 @@ class format_object_base;
class FormattedString;
class FormattedNumber;
class FormattedBytes;
-template <class T> class LLVM_NODISCARD Expected;
+template <class T> class LLVM_NODISCARD Expected;
namespace sys {
namespace fs {
enum FileAccess : unsigned;
enum OpenFlags : unsigned;
enum CreationDisposition : unsigned;
-class FileLocker;
+class FileLocker;
} // end namespace fs
} // end namespace sys
@@ -55,16 +55,16 @@ class FileLocker;
/// buffered disciplines etc. It is a simple buffer that outputs
/// a chunk at a time.
class raw_ostream {
-public:
- // Class kinds to support LLVM-style RTTI.
- enum class OStreamKind {
- OK_OStream,
- OK_FDStream,
- };
-
+public:
+ // Class kinds to support LLVM-style RTTI.
+ enum class OStreamKind {
+ OK_OStream,
+ OK_FDStream,
+ };
+
private:
- OStreamKind Kind;
-
+ OStreamKind Kind;
+
/// The buffer is handled in such a way that the buffer is
/// uninitialized, unbuffered, or out of space when OutBufCur >=
/// OutBufEnd. Thus a single comparison suffices to determine if we
@@ -122,10 +122,10 @@ public:
static constexpr Colors SAVEDCOLOR = Colors::SAVEDCOLOR;
static constexpr Colors RESET = Colors::RESET;
- explicit raw_ostream(bool unbuffered = false,
- OStreamKind K = OStreamKind::OK_OStream)
- : Kind(K), BufferMode(unbuffered ? BufferKind::Unbuffered
- : BufferKind::InternalBuffer) {
+ explicit raw_ostream(bool unbuffered = false,
+ OStreamKind K = OStreamKind::OK_OStream)
+ : Kind(K), BufferMode(unbuffered ? BufferKind::Unbuffered
+ : BufferKind::InternalBuffer) {
// Start out ready to flush.
OutBufStart = OutBufEnd = OutBufCur = nullptr;
}
@@ -138,8 +138,8 @@ public:
/// tell - Return the current offset with the file.
uint64_t tell() const { return current_pos() + GetNumBytesInBuffer(); }
- OStreamKind get_kind() const { return Kind; }
-
+ OStreamKind get_kind() const { return Kind; }
+
//===--------------------------------------------------------------------===//
// Configuration Interface
//===--------------------------------------------------------------------===//
@@ -408,9 +408,9 @@ class raw_pwrite_stream : public raw_ostream {
void anchor() override;
public:
- explicit raw_pwrite_stream(bool Unbuffered = false,
- OStreamKind K = OStreamKind::OK_OStream)
- : raw_ostream(Unbuffered, K) {}
+ explicit raw_pwrite_stream(bool Unbuffered = false,
+ OStreamKind K = OStreamKind::OK_OStream)
+ : raw_ostream(Unbuffered, K) {}
void pwrite(const char *Ptr, size_t Size, uint64_t Offset) {
#ifndef NDEBUG
uint64_t Pos = tell();
@@ -433,7 +433,7 @@ class raw_fd_ostream : public raw_pwrite_stream {
int FD;
bool ShouldClose;
bool SupportsSeeking = false;
- mutable Optional<bool> HasColors;
+ mutable Optional<bool> HasColors;
#ifdef _WIN32
/// True if this fd refers to a Windows console device. Mintty and other
@@ -457,18 +457,18 @@ class raw_fd_ostream : public raw_pwrite_stream {
/// Determine an efficient buffer size.
size_t preferred_buffer_size() const override;
- void anchor() override;
-
-protected:
+ void anchor() override;
+
+protected:
/// Set the flag indicating that an output error has been encountered.
void error_detected(std::error_code EC) { this->EC = EC; }
- /// Return the file descriptor.
- int get_fd() const { return FD; }
+ /// Return the file descriptor.
+ int get_fd() const { return FD; }
+
+ // Update the file position by increasing \p Delta.
+ void inc_pos(uint64_t Delta) { pos += Delta; }
- // Update the file position by increasing \p Delta.
- void inc_pos(uint64_t Delta) { pos += Delta; }
-
public:
/// Open the specified file for writing. If an error occurs, information
/// about the error is put into EC, and the stream should be immediately
@@ -492,8 +492,8 @@ public:
/// FD is the file descriptor that this writes to. If ShouldClose is true,
/// this closes the file when the stream is destroyed. If FD is for stdout or
/// stderr, it will not be closed.
- raw_fd_ostream(int fd, bool shouldClose, bool unbuffered = false,
- OStreamKind K = OStreamKind::OK_OStream);
+ raw_fd_ostream(int fd, bool shouldClose, bool unbuffered = false,
+ OStreamKind K = OStreamKind::OK_OStream);
~raw_fd_ostream() override;
@@ -501,7 +501,7 @@ public:
/// fsync.
void close();
- bool supportsSeeking() const { return SupportsSeeking; }
+ bool supportsSeeking() const { return SupportsSeeking; }
/// Flushes the stream and repositions the underlying file descriptor position
/// to the offset specified from the beginning of the file.
@@ -529,38 +529,38 @@ public:
/// - from The Zen of Python, by Tim Peters
///
void clear_error() { EC = std::error_code(); }
-
- /// Locks the underlying file.
- ///
- /// @returns RAII object that releases the lock upon leaving the scope, if the
- /// locking was successful. Otherwise returns corresponding
- /// error code.
- ///
- /// The function blocks the current thread until the lock become available or
- /// error occurs.
- ///
- /// Possible use of this function may be as follows:
- ///
- /// @code{.cpp}
- /// if (auto L = stream.lock()) {
- /// // ... do action that require file to be locked.
- /// } else {
- /// handleAllErrors(std::move(L.takeError()), [&](ErrorInfoBase &EIB) {
- /// // ... handle lock error.
- /// });
- /// }
- /// @endcode
- LLVM_NODISCARD Expected<sys::fs::FileLocker> lock();
-
- /// Tries to lock the underlying file within the specified period.
- ///
- /// @returns RAII object that releases the lock upon leaving the scope, if the
- /// locking was successful. Otherwise returns corresponding
- /// error code.
- ///
- /// It is used as @ref lock.
- LLVM_NODISCARD
- Expected<sys::fs::FileLocker> tryLockFor(std::chrono::milliseconds Timeout);
+
+ /// Locks the underlying file.
+ ///
+ /// @returns RAII object that releases the lock upon leaving the scope, if the
+ /// locking was successful. Otherwise returns corresponding
+ /// error code.
+ ///
+ /// The function blocks the current thread until the lock become available or
+ /// error occurs.
+ ///
+ /// Possible use of this function may be as follows:
+ ///
+ /// @code{.cpp}
+ /// if (auto L = stream.lock()) {
+ /// // ... do action that require file to be locked.
+ /// } else {
+ /// handleAllErrors(std::move(L.takeError()), [&](ErrorInfoBase &EIB) {
+ /// // ... handle lock error.
+ /// });
+ /// }
+ /// @endcode
+ LLVM_NODISCARD Expected<sys::fs::FileLocker> lock();
+
+ /// Tries to lock the underlying file within the specified period.
+ ///
+ /// @returns RAII object that releases the lock upon leaving the scope, if the
+ /// locking was successful. Otherwise returns corresponding
+ /// error code.
+ ///
+ /// It is used as @ref lock.
+ LLVM_NODISCARD
+ Expected<sys::fs::FileLocker> tryLockFor(std::chrono::milliseconds Timeout);
};
/// This returns a reference to a raw_fd_ostream for standard output. Use it
@@ -578,34 +578,34 @@ raw_fd_ostream &errs();
raw_ostream &nulls();
//===----------------------------------------------------------------------===//
-// File Streams
-//===----------------------------------------------------------------------===//
-
-/// A raw_ostream of a file for reading/writing/seeking.
-///
-class raw_fd_stream : public raw_fd_ostream {
-public:
- /// Open the specified file for reading/writing/seeking. If an error occurs,
- /// information about the error is put into EC, and the stream should be
- /// immediately destroyed.
- raw_fd_stream(StringRef Filename, std::error_code &EC);
-
- /// This reads the \p Size bytes into a buffer pointed by \p Ptr.
- ///
- /// \param Ptr The start of the buffer to hold data to be read.
- ///
- /// \param Size The number of bytes to be read.
- ///
- /// On success, the number of bytes read is returned, and the file position is
- /// advanced by this number. On error, -1 is returned, use error() to get the
- /// error code.
- ssize_t read(char *Ptr, size_t Size);
-
- /// Check if \p OS is a pointer of type raw_fd_stream*.
- static bool classof(const raw_ostream *OS);
-};
-
-//===----------------------------------------------------------------------===//
+// File Streams
+//===----------------------------------------------------------------------===//
+
+/// A raw_ostream of a file for reading/writing/seeking.
+///
+class raw_fd_stream : public raw_fd_ostream {
+public:
+ /// Open the specified file for reading/writing/seeking. If an error occurs,
+ /// information about the error is put into EC, and the stream should be
+ /// immediately destroyed.
+ raw_fd_stream(StringRef Filename, std::error_code &EC);
+
+ /// This reads the \p Size bytes into a buffer pointed by \p Ptr.
+ ///
+ /// \param Ptr The start of the buffer to hold data to be read.
+ ///
+ /// \param Size The number of bytes to be read.
+ ///
+ /// On success, the number of bytes read is returned, and the file position is
+ /// advanced by this number. On error, -1 is returned, use error() to get the
+ /// error code.
+ ssize_t read(char *Ptr, size_t Size);
+
+ /// Check if \p OS is a pointer of type raw_fd_stream*.
+ static bool classof(const raw_ostream *OS);
+};
+
+//===----------------------------------------------------------------------===//
// Output Stream Adaptors
//===----------------------------------------------------------------------===//
@@ -694,18 +694,18 @@ public:
~buffer_ostream() override { OS << str(); }
};
-class buffer_unique_ostream : public raw_svector_ostream {
- std::unique_ptr<raw_ostream> OS;
- SmallVector<char, 0> Buffer;
-
- virtual void anchor() override;
-
-public:
- buffer_unique_ostream(std::unique_ptr<raw_ostream> OS)
- : raw_svector_ostream(Buffer), OS(std::move(OS)) {}
- ~buffer_unique_ostream() override { *OS << str(); }
-};
-
+class buffer_unique_ostream : public raw_svector_ostream {
+ std::unique_ptr<raw_ostream> OS;
+ SmallVector<char, 0> Buffer;
+
+ virtual void anchor() override;
+
+public:
+ buffer_unique_ostream(std::unique_ptr<raw_ostream> OS)
+ : raw_svector_ostream(Buffer), OS(std::move(OS)) {}
+ ~buffer_unique_ostream() override { *OS << str(); }
+};
+
} // end namespace llvm
#endif // LLVM_SUPPORT_RAW_OSTREAM_H
diff --git a/contrib/libs/llvm12/include/llvm/TableGen/DirectiveEmitter.h b/contrib/libs/llvm12/include/llvm/TableGen/DirectiveEmitter.h
index b73462911e..ce0a7dd0f5 100644
--- a/contrib/libs/llvm12/include/llvm/TableGen/DirectiveEmitter.h
+++ b/contrib/libs/llvm12/include/llvm/TableGen/DirectiveEmitter.h
@@ -1,222 +1,222 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-#ifndef LLVM_TABLEGEN_DIRECTIVEEMITTER_H
-#define LLVM_TABLEGEN_DIRECTIVEEMITTER_H
-
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/TableGen/Record.h"
-
-namespace llvm {
-
-// Wrapper class that contains DirectiveLanguage's information defined in
-// DirectiveBase.td and provides helper methods for accessing it.
-class DirectiveLanguage {
-public:
- explicit DirectiveLanguage(const llvm::RecordKeeper &Records)
- : Records(Records) {
- const auto &DirectiveLanguages = getDirectiveLanguages();
- Def = DirectiveLanguages[0];
- }
-
- StringRef getName() const { return Def->getValueAsString("name"); }
-
- StringRef getCppNamespace() const {
- return Def->getValueAsString("cppNamespace");
- }
-
- StringRef getDirectivePrefix() const {
- return Def->getValueAsString("directivePrefix");
- }
-
- StringRef getClausePrefix() const {
- return Def->getValueAsString("clausePrefix");
- }
-
- StringRef getIncludeHeader() const {
- return Def->getValueAsString("includeHeader");
- }
-
- StringRef getClauseEnumSetClass() const {
- return Def->getValueAsString("clauseEnumSetClass");
- }
-
- StringRef getFlangClauseBaseClass() const {
- return Def->getValueAsString("flangClauseBaseClass");
- }
-
- bool hasMakeEnumAvailableInNamespace() const {
- return Def->getValueAsBit("makeEnumAvailableInNamespace");
- }
-
- bool hasEnableBitmaskEnumInNamespace() const {
- return Def->getValueAsBit("enableBitmaskEnumInNamespace");
- }
-
- const std::vector<Record *> getDirectives() const {
- return Records.getAllDerivedDefinitions("Directive");
- }
-
- const std::vector<Record *> getClauses() const {
- return Records.getAllDerivedDefinitions("Clause");
- }
-
- bool HasValidityErrors() const;
-
-private:
- const llvm::Record *Def;
- const llvm::RecordKeeper &Records;
-
- const std::vector<Record *> getDirectiveLanguages() const {
- return Records.getAllDerivedDefinitions("DirectiveLanguage");
- }
-};
-
-// Base record class used for Directive and Clause class defined in
-// DirectiveBase.td.
-class BaseRecord {
-public:
- explicit BaseRecord(const llvm::Record *Def) : Def(Def) {}
-
- StringRef getName() const { return Def->getValueAsString("name"); }
-
- StringRef getAlternativeName() const {
- return Def->getValueAsString("alternativeName");
- }
-
- // Returns the name of the directive formatted for output. Whitespace are
- // replaced with underscores.
- std::string getFormattedName() {
- StringRef Name = Def->getValueAsString("name");
- std::string N = Name.str();
- std::replace(N.begin(), N.end(), ' ', '_');
- return N;
- }
-
- bool isDefault() const { return Def->getValueAsBit("isDefault"); }
-
- // Returns the record name.
- const StringRef getRecordName() const { return Def->getName(); }
-
-protected:
- const llvm::Record *Def;
-};
-
-// Wrapper class that contains a Directive's information defined in
-// DirectiveBase.td and provides helper methods for accessing it.
-class Directive : public BaseRecord {
-public:
- explicit Directive(const llvm::Record *Def) : BaseRecord(Def) {}
-
- std::vector<Record *> getAllowedClauses() const {
- return Def->getValueAsListOfDefs("allowedClauses");
- }
-
- std::vector<Record *> getAllowedOnceClauses() const {
- return Def->getValueAsListOfDefs("allowedOnceClauses");
- }
-
- std::vector<Record *> getAllowedExclusiveClauses() const {
- return Def->getValueAsListOfDefs("allowedExclusiveClauses");
- }
-
- std::vector<Record *> getRequiredClauses() const {
- return Def->getValueAsListOfDefs("requiredClauses");
- }
-};
-
-// Wrapper class that contains Clause's information defined in DirectiveBase.td
-// and provides helper methods for accessing it.
-class Clause : public BaseRecord {
-public:
- explicit Clause(const llvm::Record *Def) : BaseRecord(Def) {}
-
- // Optional field.
- StringRef getClangClass() const {
- return Def->getValueAsString("clangClass");
- }
-
- // Optional field.
- StringRef getFlangClass() const {
- return Def->getValueAsString("flangClass");
- }
-
- // Get the formatted name for Flang parser class. The generic formatted class
- // name is constructed from the name were the first letter of each word is
- // captitalized and the underscores are removed.
- // ex: async -> Async
- // num_threads -> NumThreads
- std::string getFormattedParserClassName() {
- StringRef Name = Def->getValueAsString("name");
- std::string N = Name.str();
- bool Cap = true;
- std::transform(N.begin(), N.end(), N.begin(), [&Cap](unsigned char C) {
- if (Cap == true) {
- C = llvm::toUpper(C);
- Cap = false;
- } else if (C == '_') {
- Cap = true;
- }
- return C;
- });
- N.erase(std::remove(N.begin(), N.end(), '_'), N.end());
- return N;
- }
-
- // Optional field.
- StringRef getEnumName() const {
- return Def->getValueAsString("enumClauseValue");
- }
-
- std::vector<Record *> getClauseVals() const {
- return Def->getValueAsListOfDefs("allowedClauseValues");
- }
-
- bool isValueOptional() const { return Def->getValueAsBit("isValueOptional"); }
-
- bool isValueList() const { return Def->getValueAsBit("isValueList"); }
-
- StringRef getDefaultValue() const {
- return Def->getValueAsString("defaultValue");
- }
-
- bool isImplicit() const { return Def->getValueAsBit("isImplicit"); }
-};
-
-// Wrapper class that contains VersionedClause's information defined in
-// DirectiveBase.td and provides helper methods for accessing it.
-class VersionedClause {
-public:
- explicit VersionedClause(const llvm::Record *Def) : Def(Def) {}
-
- // Return the specific clause record wrapped in the Clause class.
- Clause getClause() const { return Clause{Def->getValueAsDef("clause")}; }
-
- int64_t getMinVersion() const { return Def->getValueAsInt("minVersion"); }
-
- int64_t getMaxVersion() const { return Def->getValueAsInt("maxVersion"); }
-
-private:
- const llvm::Record *Def;
-};
-
-class ClauseVal : public BaseRecord {
-public:
- explicit ClauseVal(const llvm::Record *Def) : BaseRecord(Def) {}
-
- int getValue() const { return Def->getValueAsInt("value"); }
-
- bool isUserVisible() const { return Def->getValueAsBit("isUserValue"); }
-};
-
-} // namespace llvm
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+#ifndef LLVM_TABLEGEN_DIRECTIVEEMITTER_H
+#define LLVM_TABLEGEN_DIRECTIVEEMITTER_H
+
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/TableGen/Record.h"
+
+namespace llvm {
+
+// Wrapper class that contains DirectiveLanguage's information defined in
+// DirectiveBase.td and provides helper methods for accessing it.
+class DirectiveLanguage {
+public:
+ explicit DirectiveLanguage(const llvm::RecordKeeper &Records)
+ : Records(Records) {
+ const auto &DirectiveLanguages = getDirectiveLanguages();
+ Def = DirectiveLanguages[0];
+ }
+
+ StringRef getName() const { return Def->getValueAsString("name"); }
+
+ StringRef getCppNamespace() const {
+ return Def->getValueAsString("cppNamespace");
+ }
+
+ StringRef getDirectivePrefix() const {
+ return Def->getValueAsString("directivePrefix");
+ }
+
+ StringRef getClausePrefix() const {
+ return Def->getValueAsString("clausePrefix");
+ }
+
+ StringRef getIncludeHeader() const {
+ return Def->getValueAsString("includeHeader");
+ }
+
+ StringRef getClauseEnumSetClass() const {
+ return Def->getValueAsString("clauseEnumSetClass");
+ }
+
+ StringRef getFlangClauseBaseClass() const {
+ return Def->getValueAsString("flangClauseBaseClass");
+ }
+
+ bool hasMakeEnumAvailableInNamespace() const {
+ return Def->getValueAsBit("makeEnumAvailableInNamespace");
+ }
+
+ bool hasEnableBitmaskEnumInNamespace() const {
+ return Def->getValueAsBit("enableBitmaskEnumInNamespace");
+ }
+
+ const std::vector<Record *> getDirectives() const {
+ return Records.getAllDerivedDefinitions("Directive");
+ }
+
+ const std::vector<Record *> getClauses() const {
+ return Records.getAllDerivedDefinitions("Clause");
+ }
+
+ bool HasValidityErrors() const;
+
+private:
+ const llvm::Record *Def;
+ const llvm::RecordKeeper &Records;
+
+ const std::vector<Record *> getDirectiveLanguages() const {
+ return Records.getAllDerivedDefinitions("DirectiveLanguage");
+ }
+};
+
+// Base record class used for Directive and Clause class defined in
+// DirectiveBase.td.
+class BaseRecord {
+public:
+ explicit BaseRecord(const llvm::Record *Def) : Def(Def) {}
+
+ StringRef getName() const { return Def->getValueAsString("name"); }
+
+ StringRef getAlternativeName() const {
+ return Def->getValueAsString("alternativeName");
+ }
+
+ // Returns the name of the directive formatted for output. Whitespace are
+ // replaced with underscores.
+ std::string getFormattedName() {
+ StringRef Name = Def->getValueAsString("name");
+ std::string N = Name.str();
+ std::replace(N.begin(), N.end(), ' ', '_');
+ return N;
+ }
+
+ bool isDefault() const { return Def->getValueAsBit("isDefault"); }
+
+ // Returns the record name.
+ const StringRef getRecordName() const { return Def->getName(); }
+
+protected:
+ const llvm::Record *Def;
+};
+
+// Wrapper class that contains a Directive's information defined in
+// DirectiveBase.td and provides helper methods for accessing it.
+class Directive : public BaseRecord {
+public:
+ explicit Directive(const llvm::Record *Def) : BaseRecord(Def) {}
+
+ std::vector<Record *> getAllowedClauses() const {
+ return Def->getValueAsListOfDefs("allowedClauses");
+ }
+
+ std::vector<Record *> getAllowedOnceClauses() const {
+ return Def->getValueAsListOfDefs("allowedOnceClauses");
+ }
+
+ std::vector<Record *> getAllowedExclusiveClauses() const {
+ return Def->getValueAsListOfDefs("allowedExclusiveClauses");
+ }
+
+ std::vector<Record *> getRequiredClauses() const {
+ return Def->getValueAsListOfDefs("requiredClauses");
+ }
+};
+
+// Wrapper class that contains Clause's information defined in DirectiveBase.td
+// and provides helper methods for accessing it.
+class Clause : public BaseRecord {
+public:
+ explicit Clause(const llvm::Record *Def) : BaseRecord(Def) {}
+
+ // Optional field.
+ StringRef getClangClass() const {
+ return Def->getValueAsString("clangClass");
+ }
+
+ // Optional field.
+ StringRef getFlangClass() const {
+ return Def->getValueAsString("flangClass");
+ }
+
+ // Get the formatted name for Flang parser class. The generic formatted class
+ // name is constructed from the name were the first letter of each word is
+ // captitalized and the underscores are removed.
+ // ex: async -> Async
+ // num_threads -> NumThreads
+ std::string getFormattedParserClassName() {
+ StringRef Name = Def->getValueAsString("name");
+ std::string N = Name.str();
+ bool Cap = true;
+ std::transform(N.begin(), N.end(), N.begin(), [&Cap](unsigned char C) {
+ if (Cap == true) {
+ C = llvm::toUpper(C);
+ Cap = false;
+ } else if (C == '_') {
+ Cap = true;
+ }
+ return C;
+ });
+ N.erase(std::remove(N.begin(), N.end(), '_'), N.end());
+ return N;
+ }
+
+ // Optional field.
+ StringRef getEnumName() const {
+ return Def->getValueAsString("enumClauseValue");
+ }
+
+ std::vector<Record *> getClauseVals() const {
+ return Def->getValueAsListOfDefs("allowedClauseValues");
+ }
+
+ bool isValueOptional() const { return Def->getValueAsBit("isValueOptional"); }
+
+ bool isValueList() const { return Def->getValueAsBit("isValueList"); }
+
+ StringRef getDefaultValue() const {
+ return Def->getValueAsString("defaultValue");
+ }
+
+ bool isImplicit() const { return Def->getValueAsBit("isImplicit"); }
+};
+
+// Wrapper class that contains VersionedClause's information defined in
+// DirectiveBase.td and provides helper methods for accessing it.
+class VersionedClause {
+public:
+ explicit VersionedClause(const llvm::Record *Def) : Def(Def) {}
+
+ // Return the specific clause record wrapped in the Clause class.
+ Clause getClause() const { return Clause{Def->getValueAsDef("clause")}; }
+
+ int64_t getMinVersion() const { return Def->getValueAsInt("minVersion"); }
+
+ int64_t getMaxVersion() const { return Def->getValueAsInt("maxVersion"); }
+
+private:
+ const llvm::Record *Def;
+};
+
+class ClauseVal : public BaseRecord {
+public:
+ explicit ClauseVal(const llvm::Record *Def) : BaseRecord(Def) {}
+
+ int getValue() const { return Def->getValueAsInt("value"); }
+
+ bool isUserVisible() const { return Def->getValueAsBit("isUserValue"); }
+};
+
+} // namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/TableGen/Error.h b/contrib/libs/llvm12/include/llvm/TableGen/Error.h
index 8831879021..9a474a4954 100644
--- a/contrib/libs/llvm12/include/llvm/TableGen/Error.h
+++ b/contrib/libs/llvm12/include/llvm/TableGen/Error.h
@@ -22,38 +22,38 @@
#define LLVM_TABLEGEN_ERROR_H
#include "llvm/Support/SourceMgr.h"
-#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/Record.h"
namespace llvm {
void PrintNote(const Twine &Msg);
void PrintNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg);
-LLVM_ATTRIBUTE_NORETURN void PrintFatalNote(const Twine &Msg);
-LLVM_ATTRIBUTE_NORETURN void PrintFatalNote(ArrayRef<SMLoc> ErrorLoc,
- const Twine &Msg);
-LLVM_ATTRIBUTE_NORETURN void PrintFatalNote(const Record *Rec,
- const Twine &Msg);
-LLVM_ATTRIBUTE_NORETURN void PrintFatalNote(const RecordVal *RecVal,
- const Twine &Msg);
-
-void PrintWarning(const Twine &Msg);
+LLVM_ATTRIBUTE_NORETURN void PrintFatalNote(const Twine &Msg);
+LLVM_ATTRIBUTE_NORETURN void PrintFatalNote(ArrayRef<SMLoc> ErrorLoc,
+ const Twine &Msg);
+LLVM_ATTRIBUTE_NORETURN void PrintFatalNote(const Record *Rec,
+ const Twine &Msg);
+LLVM_ATTRIBUTE_NORETURN void PrintFatalNote(const RecordVal *RecVal,
+ const Twine &Msg);
+
+void PrintWarning(const Twine &Msg);
void PrintWarning(ArrayRef<SMLoc> WarningLoc, const Twine &Msg);
void PrintWarning(const char *Loc, const Twine &Msg);
-void PrintError(const Twine &Msg);
+void PrintError(const Twine &Msg);
void PrintError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg);
void PrintError(const char *Loc, const Twine &Msg);
-void PrintError(const Record *Rec, const Twine &Msg);
-void PrintError(const RecordVal *RecVal, const Twine &Msg);
+void PrintError(const Record *Rec, const Twine &Msg);
+void PrintError(const RecordVal *RecVal, const Twine &Msg);
LLVM_ATTRIBUTE_NORETURN void PrintFatalError(const Twine &Msg);
LLVM_ATTRIBUTE_NORETURN void PrintFatalError(ArrayRef<SMLoc> ErrorLoc,
const Twine &Msg);
-LLVM_ATTRIBUTE_NORETURN void PrintFatalError(const Record *Rec,
- const Twine &Msg);
-LLVM_ATTRIBUTE_NORETURN void PrintFatalError(const RecordVal *RecVal,
- const Twine &Msg);
+LLVM_ATTRIBUTE_NORETURN void PrintFatalError(const Record *Rec,
+ const Twine &Msg);
+LLVM_ATTRIBUTE_NORETURN void PrintFatalError(const RecordVal *RecVal,
+ const Twine &Msg);
extern SourceMgr SrcMgr;
extern unsigned ErrorsPrinted;
diff --git a/contrib/libs/llvm12/include/llvm/TableGen/Record.h b/contrib/libs/llvm12/include/llvm/TableGen/Record.h
index e9c536104f..cf7504c51c 100644
--- a/contrib/libs/llvm12/include/llvm/TableGen/Record.h
+++ b/contrib/libs/llvm12/include/llvm/TableGen/Record.h
@@ -27,12 +27,12 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SMLoc.h"
-#include "llvm/Support/Timer.h"
+#include "llvm/Support/Timer.h"
#include "llvm/Support/TrailingObjects.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -75,7 +75,7 @@ public:
private:
RecTyKind Kind;
- /// ListRecTy of the list that has elements of this type.
+ /// ListRecTy of the list that has elements of this type.
ListRecTy *ListTy = nullptr;
public:
@@ -96,7 +96,7 @@ public:
/// a bit set is not an int, but they are convertible.
virtual bool typeIsA(const RecTy *RHS) const;
- /// Returns the type representing list<thistype>.
+ /// Returns the type representing list<thistype>.
ListRecTy *getListTy();
};
@@ -181,14 +181,14 @@ public:
bool typeIsConvertibleTo(const RecTy *RHS) const override;
};
-/// 'list<Ty>' - Represent a list of element values, all of which must be of
-/// the specified type. The type is stored in ElementTy.
+/// 'list<Ty>' - Represent a list of element values, all of which must be of
+/// the specified type. The type is stored in ElementTy.
class ListRecTy : public RecTy {
friend ListRecTy *RecTy::getListTy();
- RecTy *ElementTy;
+ RecTy *ElementTy;
- explicit ListRecTy(RecTy *T) : RecTy(ListRecTyKind), ElementTy(T) {}
+ explicit ListRecTy(RecTy *T) : RecTy(ListRecTyKind), ElementTy(T) {}
public:
static bool classof(const RecTy *RT) {
@@ -196,7 +196,7 @@ public:
}
static ListRecTy *get(RecTy *T) { return T->getListTy(); }
- RecTy *getElementType() const { return ElementTy; }
+ RecTy *getElementType() const { return ElementTy; }
std::string getAsString() const override;
@@ -327,7 +327,7 @@ private:
virtual void anchor();
public:
- /// Get the kind (type) of the value.
+ /// Get the kind (type) of the value.
InitKind getKind() const { return Kind; }
protected:
@@ -338,61 +338,61 @@ public:
Init &operator=(const Init &) = delete;
virtual ~Init() = default;
- /// Is this a complete value with no unset (uninitialized) subvalues?
+ /// Is this a complete value with no unset (uninitialized) subvalues?
virtual bool isComplete() const { return true; }
/// Is this a concrete and fully resolved value without any references or
/// stuck operations? Unset values are concrete.
virtual bool isConcrete() const { return false; }
- /// Print this value.
+ /// Print this value.
void print(raw_ostream &OS) const { OS << getAsString(); }
- /// Convert this value to a literal form.
+ /// Convert this value to a literal form.
virtual std::string getAsString() const = 0;
-
- /// Convert this value to a literal form,
- /// without adding quotes around a string.
+
+ /// Convert this value to a literal form,
+ /// without adding quotes around a string.
virtual std::string getAsUnquotedString() const { return getAsString(); }
- /// Debugging method that may be called through a debugger; just
+ /// Debugging method that may be called through a debugger; just
/// invokes print on stderr.
void dump() const;
- /// If this value is convertible to type \p Ty, return a value whose
- /// type is \p Ty, generating a !cast operation if required.
- /// Otherwise, return null.
+ /// If this value is convertible to type \p Ty, return a value whose
+ /// type is \p Ty, generating a !cast operation if required.
+ /// Otherwise, return null.
virtual Init *getCastTo(RecTy *Ty) const = 0;
- /// Convert to a value whose type is \p Ty, or return null if this
- /// is not possible. This can happen if the value's type is convertible
- /// to \p Ty, but there are unresolved references.
+ /// Convert to a value whose type is \p Ty, or return null if this
+ /// is not possible. This can happen if the value's type is convertible
+ /// to \p Ty, but there are unresolved references.
virtual Init *convertInitializerTo(RecTy *Ty) const = 0;
- /// This function is used to implement the bit range
- /// selection operator. Given a value, it selects the specified bits,
- /// returning them as a new \p Init of type \p bits. If it is not legal
- /// to use the bit selection operator on this value, null is returned.
+ /// This function is used to implement the bit range
+ /// selection operator. Given a value, it selects the specified bits,
+ /// returning them as a new \p Init of type \p bits. If it is not legal
+ /// to use the bit selection operator on this value, null is returned.
virtual Init *convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
return nullptr;
}
- /// This function is used to implement the list slice
- /// selection operator. Given a value, it selects the specified list
- /// elements, returning them as a new \p Init of type \p list. If it
- /// is not legal to use the slice operator, null is returned.
+ /// This function is used to implement the list slice
+ /// selection operator. Given a value, it selects the specified list
+ /// elements, returning them as a new \p Init of type \p list. If it
+ /// is not legal to use the slice operator, null is returned.
virtual Init *convertInitListSlice(ArrayRef<unsigned> Elements) const {
return nullptr;
}
- /// This function is used to implement the FieldInit class.
- /// Implementors of this method should return the type of the named
- /// field if they are of type record.
+ /// This function is used to implement the FieldInit class.
+ /// Implementors of this method should return the type of the named
+ /// field if they are of type record.
virtual RecTy *getFieldType(StringInit *FieldName) const {
return nullptr;
}
- /// This function is used by classes that refer to other
+ /// This function is used by classes that refer to other
/// variables which may not be defined at the time the expression is formed.
/// If a value is set for the variable later, this method will be called on
/// users of the value to allow the value to propagate out.
@@ -400,7 +400,7 @@ public:
return const_cast<Init *>(this);
}
- /// Get the \p Init value of the specified bit.
+ /// Get the \p Init value of the specified bit.
virtual Init *getBit(unsigned Bit) const = 0;
};
@@ -408,14 +408,14 @@ inline raw_ostream &operator<<(raw_ostream &OS, const Init &I) {
I.print(OS); return OS;
}
-/// This is the common superclass of types that have a specific,
-/// explicit type, stored in ValueTy.
+/// This is the common superclass of types that have a specific,
+/// explicit type, stored in ValueTy.
class TypedInit : public Init {
- RecTy *ValueTy;
+ RecTy *ValueTy;
protected:
explicit TypedInit(InitKind K, RecTy *T, uint8_t Opc = 0)
- : Init(K, Opc), ValueTy(T) {}
+ : Init(K, Opc), ValueTy(T) {}
public:
TypedInit(const TypedInit &) = delete;
@@ -426,8 +426,8 @@ public:
I->getKind() <= IK_LastTypedInit;
}
- /// Get the type of the Init as a RecTy.
- RecTy *getType() const { return ValueTy; }
+ /// Get the type of the Init as a RecTy.
+ RecTy *getType() const { return ValueTy; }
Init *getCastTo(RecTy *Ty) const override;
Init *convertInitializerTo(RecTy *Ty) const override;
@@ -437,11 +437,11 @@ public:
/// This method is used to implement the FieldInit class.
/// Implementors of this method should return the type of the named field if
- /// they are of type record.
+ /// they are of type record.
RecTy *getFieldType(StringInit *FieldName) const override;
};
-/// '?' - Represents an uninitialized value.
+/// '?' - Represents an uninitialized value.
class UnsetInit : public Init {
UnsetInit() : Init(IK_UnsetInit) {}
@@ -453,7 +453,7 @@ public:
return I->getKind() == IK_UnsetInit;
}
- /// Get the singleton unset Init.
+ /// Get the singleton unset Init.
static UnsetInit *get();
Init *getCastTo(RecTy *Ty) const override;
@@ -463,12 +463,12 @@ public:
return const_cast<UnsetInit*>(this);
}
- /// Is this a complete value with no unset (uninitialized) subvalues?
+ /// Is this a complete value with no unset (uninitialized) subvalues?
bool isComplete() const override { return false; }
-
+
bool isConcrete() const override { return true; }
-
- /// Get the string representation of the Init.
+
+ /// Get the string representation of the Init.
std::string getAsString() const override { return "?"; }
};
@@ -585,18 +585,18 @@ public:
/// "foo" - Represent an initialization by a string value.
class StringInit : public TypedInit {
-public:
- enum StringFormat {
- SF_String, // Format as "text"
- SF_Code, // Format as [{text}]
- };
-
-private:
+public:
+ enum StringFormat {
+ SF_String, // Format as "text"
+ SF_Code, // Format as [{text}]
+ };
+
+private:
StringRef Value;
- StringFormat Format;
+ StringFormat Format;
- explicit StringInit(StringRef V, StringFormat Fmt)
- : TypedInit(IK_StringInit, StringRecTy::get()), Value(V), Format(Fmt) {}
+ explicit StringInit(StringRef V, StringFormat Fmt)
+ : TypedInit(IK_StringInit, StringRecTy::get()), Value(V), Format(Fmt) {}
public:
StringInit(const StringInit &) = delete;
@@ -606,25 +606,25 @@ public:
return I->getKind() == IK_StringInit;
}
- static StringInit *get(StringRef, StringFormat Fmt = SF_String);
+ static StringInit *get(StringRef, StringFormat Fmt = SF_String);
- static StringFormat determineFormat(StringFormat Fmt1, StringFormat Fmt2) {
- return (Fmt1 == SF_Code || Fmt2 == SF_Code) ? SF_Code : SF_String;
+ static StringFormat determineFormat(StringFormat Fmt1, StringFormat Fmt2) {
+ return (Fmt1 == SF_Code || Fmt2 == SF_Code) ? SF_Code : SF_String;
}
StringRef getValue() const { return Value; }
- StringFormat getFormat() const { return Format; }
- bool hasCodeFormat() const { return Format == SF_Code; }
+ StringFormat getFormat() const { return Format; }
+ bool hasCodeFormat() const { return Format == SF_Code; }
Init *convertInitializerTo(RecTy *Ty) const override;
bool isConcrete() const override { return true; }
-
+
std::string getAsString() const override {
- if (Format == SF_String)
- return "\"" + Value.str() + "\"";
- else
- return "[{" + Value.str() + "}]";
+ if (Format == SF_String)
+ return "\"" + Value.str() + "\"";
+ else
+ return "[{" + Value.str() + "}]";
}
std::string getAsUnquotedString() const override {
@@ -731,7 +731,7 @@ public:
///
class UnOpInit : public OpInit, public FoldingSetNode {
public:
- enum UnaryOp : uint8_t { CAST, NOT, HEAD, TAIL, SIZE, EMPTY, GETDAGOP };
+ enum UnaryOp : uint8_t { CAST, NOT, HEAD, TAIL, SIZE, EMPTY, GETDAGOP };
private:
Init *LHS;
@@ -780,9 +780,9 @@ public:
/// !op (X, Y) - Combine two inits.
class BinOpInit : public OpInit, public FoldingSetNode {
public:
- enum BinaryOp : uint8_t { ADD, SUB, MUL, AND, OR, XOR, SHL, SRA, SRL, LISTCONCAT,
- LISTSPLAT, STRCONCAT, INTERLEAVE, CONCAT, EQ,
- NE, LE, LT, GE, GT, SETDAGOP };
+ enum BinaryOp : uint8_t { ADD, SUB, MUL, AND, OR, XOR, SHL, SRA, SRL, LISTCONCAT,
+ LISTSPLAT, STRCONCAT, INTERLEAVE, CONCAT, EQ,
+ NE, LE, LT, GE, GT, SETDAGOP };
private:
Init *LHS, *RHS;
@@ -837,7 +837,7 @@ public:
/// !op (X, Y, Z) - Combine two inits.
class TernOpInit : public OpInit, public FoldingSetNode {
public:
- enum TernaryOp : uint8_t { SUBST, FOREACH, FILTER, IF, DAG, SUBSTR };
+ enum TernaryOp : uint8_t { SUBST, FOREACH, FILTER, IF, DAG, SUBSTR };
private:
Init *LHS, *MHS, *RHS;
@@ -1372,70 +1372,70 @@ public:
// High-Level Classes
//===----------------------------------------------------------------------===//
-/// This class represents a field in a record, including its name, type,
-/// value, and source location.
+/// This class represents a field in a record, including its name, type,
+/// value, and source location.
class RecordVal {
friend class Record;
-public:
- enum FieldKind {
- FK_Normal, // A normal record field.
- FK_NonconcreteOK, // A field that can be nonconcrete ('field' keyword).
- FK_TemplateArg, // A template argument.
- };
-
-private:
+public:
+ enum FieldKind {
+ FK_Normal, // A normal record field.
+ FK_NonconcreteOK, // A field that can be nonconcrete ('field' keyword).
+ FK_TemplateArg, // A template argument.
+ };
+
+private:
Init *Name;
- SMLoc Loc; // Source location of definition of name.
- PointerIntPair<RecTy *, 2, FieldKind> TyAndKind;
+ SMLoc Loc; // Source location of definition of name.
+ PointerIntPair<RecTy *, 2, FieldKind> TyAndKind;
Init *Value;
public:
- RecordVal(Init *N, RecTy *T, FieldKind K);
- RecordVal(Init *N, SMLoc Loc, RecTy *T, FieldKind K);
+ RecordVal(Init *N, RecTy *T, FieldKind K);
+ RecordVal(Init *N, SMLoc Loc, RecTy *T, FieldKind K);
- /// Get the name of the field as a StringRef.
+ /// Get the name of the field as a StringRef.
StringRef getName() const;
-
- /// Get the name of the field as an Init.
+
+ /// Get the name of the field as an Init.
Init *getNameInit() const { return Name; }
- /// Get the name of the field as a std::string.
+ /// Get the name of the field as a std::string.
std::string getNameInitAsString() const {
return getNameInit()->getAsUnquotedString();
}
- /// Get the source location of the point where the field was defined.
- const SMLoc &getLoc() const { return Loc; }
-
- /// Is this a field where nonconcrete values are okay?
- bool isNonconcreteOK() const {
- return TyAndKind.getInt() == FK_NonconcreteOK;
- }
-
- /// Is this a template argument?
- bool isTemplateArg() const {
- return TyAndKind.getInt() == FK_TemplateArg;
- }
-
- /// Get the type of the field value as a RecTy.
- RecTy *getType() const { return TyAndKind.getPointer(); }
-
- /// Get the type of the field for printing purposes.
- std::string getPrintType() const;
-
- /// Get the value of the field as an Init.
+ /// Get the source location of the point where the field was defined.
+ const SMLoc &getLoc() const { return Loc; }
+
+ /// Is this a field where nonconcrete values are okay?
+ bool isNonconcreteOK() const {
+ return TyAndKind.getInt() == FK_NonconcreteOK;
+ }
+
+ /// Is this a template argument?
+ bool isTemplateArg() const {
+ return TyAndKind.getInt() == FK_TemplateArg;
+ }
+
+ /// Get the type of the field value as a RecTy.
+ RecTy *getType() const { return TyAndKind.getPointer(); }
+
+ /// Get the type of the field for printing purposes.
+ std::string getPrintType() const;
+
+ /// Get the value of the field as an Init.
Init *getValue() const { return Value; }
- /// Set the value of the field from an Init.
+ /// Set the value of the field from an Init.
bool setValue(Init *V);
- /// Set the value and source location of the field.
- bool setValue(Init *V, SMLoc NewLoc);
-
+ /// Set the value and source location of the field.
+ bool setValue(Init *V, SMLoc NewLoc);
+
void dump() const;
-
- /// Print the value to an output stream, possibly with a semicolon.
+
+ /// Print the value to an output stream, possibly with a semicolon.
void print(raw_ostream &OS, bool PrintSem = true) const;
};
@@ -1453,18 +1453,18 @@ class Record {
SmallVector<SMLoc, 4> Locs;
SmallVector<Init *, 0> TemplateArgs;
SmallVector<RecordVal, 0> Values;
- // Vector of [source location, condition Init, message Init].
- SmallVector<std::tuple<SMLoc, Init *, Init *>, 0> Assertions;
+ // Vector of [source location, condition Init, message Init].
+ SmallVector<std::tuple<SMLoc, Init *, Init *>, 0> Assertions;
- // All superclasses in the inheritance forest in post-order (yes, it
+ // All superclasses in the inheritance forest in post-order (yes, it
// must be a forest; diamond-shaped inheritance is not allowed).
SmallVector<std::pair<Record *, SMRange>, 0> SuperClasses;
// Tracks Record instances. Not owned by Record.
RecordKeeper &TrackedRecords;
- // The DefInit corresponding to this record.
- DefInit *CorrespondingDefInit = nullptr;
+ // The DefInit corresponding to this record.
+ DefInit *CorrespondingDefInit = nullptr;
// Unique record ID.
unsigned ID;
@@ -1488,8 +1488,8 @@ public:
: Record(StringInit::get(N), locs, records, false, Class) {}
// When copy-constructing a Record, we must still guarantee a globally unique
- // ID number. Don't copy CorrespondingDefInit either, since it's owned by the
- // original record. All other fields can be copied normally.
+ // ID number. Don't copy CorrespondingDefInit either, since it's owned by the
+ // original record. All other fields can be copied normally.
Record(const Record &O)
: Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs),
Values(O.Values), SuperClasses(O.SuperClasses),
@@ -1529,18 +1529,18 @@ public:
ArrayRef<RecordVal> getValues() const { return Values; }
- ArrayRef<std::tuple<SMLoc, Init *, Init *>> getAssertions() const {
- return Assertions;
- }
-
+ ArrayRef<std::tuple<SMLoc, Init *, Init *>> getAssertions() const {
+ return Assertions;
+ }
+
ArrayRef<std::pair<Record *, SMRange>> getSuperClasses() const {
return SuperClasses;
}
- /// Determine whether this record has the specified direct superclass.
- bool hasDirectSuperClass(const Record *SuperClass) const;
-
- /// Append the direct superclasses of this record to Classes.
+ /// Determine whether this record has the specified direct superclass.
+ bool hasDirectSuperClass(const Record *SuperClass) const;
+
+ /// Append the direct superclasses of this record to Classes.
void getDirectSuperClasses(SmallVectorImpl<Record *> &Classes) const;
bool isTemplateArg(Init *Name) const {
@@ -1590,10 +1590,10 @@ public:
removeValue(StringInit::get(Name));
}
- void addAssertion(SMLoc Loc, Init *Condition, Init *Message) {
- Assertions.push_back(std::make_tuple(Loc, Condition, Message));
- }
-
+ void addAssertion(SMLoc Loc, Init *Condition, Init *Message) {
+ Assertions.push_back(std::make_tuple(Loc, Condition, Message));
+ }
+
bool isSubClassOf(const Record *R) const {
for (const auto &SCPair : SuperClasses)
if (SCPair.first == R)
@@ -1614,8 +1614,8 @@ public:
}
void addSuperClass(Record *R, SMRange Range) {
- assert(!CorrespondingDefInit &&
- "changing type of record after it has been referenced");
+ assert(!CorrespondingDefInit &&
+ "changing type of record after it has been referenced");
assert(!isSubClassOf(R) && "Already subclassing record!");
SuperClasses.push_back(std::make_pair(R, Range));
}
@@ -1648,9 +1648,9 @@ public:
// High-level methods useful to tablegen back-ends
//
- ///Return the source location for the named field.
- SMLoc getFieldLoc(StringRef FieldName) const;
-
+ ///Return the source location for the named field.
+ SMLoc getFieldLoc(StringRef FieldName) const;
+
/// Return the initializer for a value with the specified name,
/// or throw an exception if the field does not exist.
Init *getValueInit(StringRef FieldName) const;
@@ -1666,11 +1666,11 @@ public:
StringRef getValueAsString(StringRef FieldName) const;
/// This method looks up the specified field and returns
- /// its value as a string, throwing an exception if the field if the value is
- /// not a string and llvm::Optional() if the field does not exist.
- llvm::Optional<StringRef> getValueAsOptionalString(StringRef FieldName) const;
-
- /// This method looks up the specified field and returns
+ /// its value as a string, throwing an exception if the field if the value is
+ /// not a string and llvm::Optional() if the field does not exist.
+ llvm::Optional<StringRef> getValueAsOptionalString(StringRef FieldName) const;
+
+ /// This method looks up the specified field and returns
/// its value as a BitsInit, throwing an exception if the field does not exist
/// or if the value is not the right type.
BitsInit *getValueAsBitsInit(StringRef FieldName) const;
@@ -1731,50 +1731,50 @@ raw_ostream &operator<<(raw_ostream &OS, const Record &R);
class RecordKeeper {
friend class RecordRecTy;
-
+
using RecordMap = std::map<std::string, std::unique_ptr<Record>, std::less<>>;
- using GlobalMap = std::map<std::string, Init *, std::less<>>;
-
- std::string InputFilename;
+ using GlobalMap = std::map<std::string, Init *, std::less<>>;
+
+ std::string InputFilename;
RecordMap Classes, Defs;
- mutable StringMap<std::vector<Record *>> ClassRecordsMap;
+ mutable StringMap<std::vector<Record *>> ClassRecordsMap;
FoldingSet<RecordRecTy> RecordTypePool;
std::map<std::string, Init *, std::less<>> ExtraGlobals;
unsigned AnonCounter = 0;
- // These members are for the phase timing feature. We need a timer group,
- // the last timer started, and a flag to say whether the last timer
- // is the special "backend overall timer."
- TimerGroup *TimingGroup = nullptr;
- Timer *LastTimer = nullptr;
- bool BackendTimer = false;
-
+ // These members are for the phase timing feature. We need a timer group,
+ // the last timer started, and a flag to say whether the last timer
+ // is the special "backend overall timer."
+ TimerGroup *TimingGroup = nullptr;
+ Timer *LastTimer = nullptr;
+ bool BackendTimer = false;
+
public:
- /// Get the main TableGen input file's name.
- const std::string getInputFilename() const { return InputFilename; }
-
- /// Get the map of classes.
+ /// Get the main TableGen input file's name.
+ const std::string getInputFilename() const { return InputFilename; }
+
+ /// Get the map of classes.
const RecordMap &getClasses() const { return Classes; }
-
- /// Get the map of records (defs).
+
+ /// Get the map of records (defs).
const RecordMap &getDefs() const { return Defs; }
- /// Get the map of global variables.
- const GlobalMap &getGlobals() const { return ExtraGlobals; }
-
- /// Get the class with the specified name.
+ /// Get the map of global variables.
+ const GlobalMap &getGlobals() const { return ExtraGlobals; }
+
+ /// Get the class with the specified name.
Record *getClass(StringRef Name) const {
auto I = Classes.find(Name);
return I == Classes.end() ? nullptr : I->second.get();
}
- /// Get the concrete record with the specified name.
+ /// Get the concrete record with the specified name.
Record *getDef(StringRef Name) const {
auto I = Defs.find(Name);
return I == Defs.end() ? nullptr : I->second.get();
}
- /// Get the \p Init value of the specified global variable.
+ /// Get the \p Init value of the specified global variable.
Init *getGlobal(StringRef Name) const {
if (Record *R = getDef(Name))
return R->getDefInit();
@@ -1782,10 +1782,10 @@ public:
return It == ExtraGlobals.end() ? nullptr : It->second;
}
- void saveInputFilename(std::string Filename) {
- InputFilename = Filename;
- }
-
+ void saveInputFilename(std::string Filename) {
+ InputFilename = Filename;
+ }
+
void addClass(std::unique_ptr<Record> R) {
bool Ins = Classes.insert(std::make_pair(std::string(R->getName()),
std::move(R))).second;
@@ -1809,42 +1809,42 @@ public:
Init *getNewAnonymousName();
- /// Start phase timing; called if the --time-phases option is specified.
- void startPhaseTiming() {
- TimingGroup = new TimerGroup("TableGen", "TableGen Phase Timing");
- }
-
- /// Start timing a phase. Automatically stops any previous phase timer.
- void startTimer(StringRef Name);
-
- /// Stop timing a phase.
- void stopTimer();
-
- /// Start timing the overall backend. If the backend itself starts a timer,
- /// then this timer is cleared.
- void startBackendTimer(StringRef Name);
-
- /// Stop timing the overall backend.
- void stopBackendTimer();
-
- /// Stop phase timing and print the report.
- void stopPhaseTiming() {
- if (TimingGroup)
- delete TimingGroup;
- }
-
+ /// Start phase timing; called if the --time-phases option is specified.
+ void startPhaseTiming() {
+ TimingGroup = new TimerGroup("TableGen", "TableGen Phase Timing");
+ }
+
+ /// Start timing a phase. Automatically stops any previous phase timer.
+ void startTimer(StringRef Name);
+
+ /// Stop timing a phase.
+ void stopTimer();
+
+ /// Start timing the overall backend. If the backend itself starts a timer,
+ /// then this timer is cleared.
+ void startBackendTimer(StringRef Name);
+
+ /// Stop timing the overall backend.
+ void stopBackendTimer();
+
+ /// Stop phase timing and print the report.
+ void stopPhaseTiming() {
+ if (TimingGroup)
+ delete TimingGroup;
+ }
+
//===--------------------------------------------------------------------===//
- // High-level helper methods, useful for tablegen backends.
+ // High-level helper methods, useful for tablegen backends.
- /// Get all the concrete records that inherit from the one specified
- /// class. The class must be defined.
+ /// Get all the concrete records that inherit from the one specified
+ /// class. The class must be defined.
std::vector<Record *> getAllDerivedDefinitions(StringRef ClassName) const;
- /// Get all the concrete records that inherit from all the specified
- /// classes. The classes must be defined.
- std::vector<Record *> getAllDerivedDefinitions(
- ArrayRef<StringRef> ClassNames) const;
-
+ /// Get all the concrete records that inherit from all the specified
+ /// classes. The classes must be defined.
+ std::vector<Record *> getAllDerivedDefinitions(
+ ArrayRef<StringRef> ClassNames) const;
+
void dump() const;
};
@@ -1884,18 +1884,18 @@ struct LessRecordRegister {
size_t Len = 0;
const char *Start = Rec.data();
const char *Curr = Start;
- bool IsDigitPart = isDigit(Curr[0]);
+ bool IsDigitPart = isDigit(Curr[0]);
for (size_t I = 0, E = Rec.size(); I != E; ++I, ++Len) {
- bool IsDigit = isDigit(Curr[I]);
- if (IsDigit != IsDigitPart) {
- Parts.push_back(std::make_pair(IsDigitPart, StringRef(Start, Len)));
+ bool IsDigit = isDigit(Curr[I]);
+ if (IsDigit != IsDigitPart) {
+ Parts.push_back(std::make_pair(IsDigitPart, StringRef(Start, Len)));
Len = 0;
Start = &Curr[I];
- IsDigitPart = isDigit(Curr[I]);
+ IsDigitPart = isDigit(Curr[I]);
}
}
// Push the last part.
- Parts.push_back(std::make_pair(IsDigitPart, StringRef(Start, Len)));
+ Parts.push_back(std::make_pair(IsDigitPart, StringRef(Start, Len)));
}
size_t size() { return Parts.size(); }
@@ -2068,7 +2068,7 @@ public:
Init *resolve(Init *VarName) override;
};
-void EmitDetailedRecords(RecordKeeper &RK, raw_ostream &OS);
+void EmitDetailedRecords(RecordKeeper &RK, raw_ostream &OS);
void EmitJSON(RecordKeeper &RK, raw_ostream &OS);
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/TableGen/SearchableTable.td b/contrib/libs/llvm12/include/llvm/TableGen/SearchableTable.td
index 8b912662e8..61dfa5c707 100644
--- a/contrib/libs/llvm12/include/llvm/TableGen/SearchableTable.td
+++ b/contrib/libs/llvm12/include/llvm/TableGen/SearchableTable.td
@@ -67,13 +67,13 @@ class GenericTable {
// List of the names of fields of collected records that contain the data for
// table entries, in the order that is used for initialization in C++.
//
- // TableGen needs to know the type of the fields so that it can format
- // the initializers correctly. It can infer the type of bit, bits, string,
- // Intrinsic, and Instruction values.
- //
- // For each field of the table named xxx, TableGen will look for a field
- // named TypeOf_xxx and use that as a more detailed description of the
- // type of the field. This is required for fields whose type
+ // TableGen needs to know the type of the fields so that it can format
+ // the initializers correctly. It can infer the type of bit, bits, string,
+ // Intrinsic, and Instruction values.
+ //
+ // For each field of the table named xxx, TableGen will look for a field
+ // named TypeOf_xxx and use that as a more detailed description of the
+ // type of the field. This is required for fields whose type
// cannot be deduced automatically, such as enum fields. For example:
//
// def MyEnum : GenericEnum {
@@ -89,15 +89,15 @@ class GenericTable {
// def MyTable : GenericTable {
// let FilterClass = "MyTableEntry";
// let Fields = ["V", ...];
- // string TypeOf_V = "MyEnum";
+ // string TypeOf_V = "MyEnum";
// }
//
- // If a string field was initialized with a code literal, TableGen will
- // emit the code verbatim. However, if a string field was initialized
- // in some other way, but should be interpreted as code, then a TypeOf_xxx
- // field is necessary, with a value of "code":
+ // If a string field was initialized with a code literal, TableGen will
+ // emit the code verbatim. However, if a string field was initialized
+ // in some other way, but should be interpreted as code, then a TypeOf_xxx
+ // field is necessary, with a value of "code":
//
- // string TypeOf_Predicate = "code";
+ // string TypeOf_Predicate = "code";
list<string> Fields;
// (Optional) List of fields that make up the primary key.
@@ -107,7 +107,7 @@ class GenericTable {
string PrimaryKeyName;
// See SearchIndex.EarlyOut
- bit PrimaryKeyEarlyOut = false;
+ bit PrimaryKeyEarlyOut = false;
}
// Define a record derived from this class to generate an additional search
@@ -128,7 +128,7 @@ class SearchIndex {
// instructions.
//
// Can only be used when the first field is an integral (non-string) type.
- bit EarlyOut = false;
+ bit EarlyOut = false;
}
// Legacy table type with integrated enum.
diff --git a/contrib/libs/llvm12/include/llvm/Target/CGPassBuilderOption.h b/contrib/libs/llvm12/include/llvm/Target/CGPassBuilderOption.h
index 6becdb015c..d8e856f066 100644
--- a/contrib/libs/llvm12/include/llvm/Target/CGPassBuilderOption.h
+++ b/contrib/libs/llvm12/include/llvm/Target/CGPassBuilderOption.h
@@ -1,76 +1,76 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- CGPassBuilderOption.h - Options for pass builder ---------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the CCState and CCValAssign classes, used for lowering
-// and implementing calling conventions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_PASSBUILDER_OPTION_H
-#define LLVM_CODEGEN_PASSBUILDER_OPTION_H
-
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Target/TargetOptions.h"
-#include <vector>
-
-namespace llvm {
-class TargetMachine;
-
-enum class RunOutliner { TargetDefault, AlwaysOutline, NeverOutline };
-enum class RegAllocType { Default, Basic, Fast, Greedy, PBQP };
-enum class CFLAAType { None, Steensgaard, Andersen, Both };
-
-// Not one-on-one but mostly corresponding to commandline options in
-// TargetPassConfig.cpp.
-struct CGPassBuilderOption {
- Optional<bool> OptimizeRegAlloc;
- Optional<bool> EnableIPRA;
- bool DebugPM = false;
- bool DisableVerify = false;
- bool EnableImplicitNullChecks = false;
- bool EnableBlockPlacementStats = false;
- bool MISchedPostRA = false;
- bool EarlyLiveIntervals = false;
-
- bool DisableLSR = false;
- bool DisableCGP = false;
- bool PrintLSR = false;
- bool DisableMergeICmps = false;
- bool DisablePartialLibcallInlining = false;
- bool DisableConstantHoisting = false;
- bool PrintISelInput = false;
- bool PrintGCInfo = false;
- bool RequiresCodeGenSCCOrder = false;
-
- RunOutliner EnableMachineOutliner = RunOutliner::TargetDefault;
- RegAllocType RegAlloc = RegAllocType::Default;
- CFLAAType UseCFLAA = CFLAAType::None;
- Optional<GlobalISelAbortMode> EnableGlobalISelAbort;
-
- Optional<bool> VerifyMachineCode;
- Optional<bool> EnableFastISelOption;
- Optional<bool> EnableGlobalISelOption;
-};
-
-CGPassBuilderOption getCGPassBuilderOption();
-
-} // namespace llvm
-
-#endif // LLVM_CODEGEN_PASSBUILDER_OPTION_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- CGPassBuilderOption.h - Options for pass builder ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the CCState and CCValAssign classes, used for lowering
+// and implementing calling conventions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_PASSBUILDER_OPTION_H
+#define LLVM_CODEGEN_PASSBUILDER_OPTION_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Target/TargetOptions.h"
+#include <vector>
+
+namespace llvm {
+class TargetMachine;
+
+enum class RunOutliner { TargetDefault, AlwaysOutline, NeverOutline };
+enum class RegAllocType { Default, Basic, Fast, Greedy, PBQP };
+enum class CFLAAType { None, Steensgaard, Andersen, Both };
+
+// Not one-on-one but mostly corresponding to commandline options in
+// TargetPassConfig.cpp.
+struct CGPassBuilderOption {
+ Optional<bool> OptimizeRegAlloc;
+ Optional<bool> EnableIPRA;
+ bool DebugPM = false;
+ bool DisableVerify = false;
+ bool EnableImplicitNullChecks = false;
+ bool EnableBlockPlacementStats = false;
+ bool MISchedPostRA = false;
+ bool EarlyLiveIntervals = false;
+
+ bool DisableLSR = false;
+ bool DisableCGP = false;
+ bool PrintLSR = false;
+ bool DisableMergeICmps = false;
+ bool DisablePartialLibcallInlining = false;
+ bool DisableConstantHoisting = false;
+ bool PrintISelInput = false;
+ bool PrintGCInfo = false;
+ bool RequiresCodeGenSCCOrder = false;
+
+ RunOutliner EnableMachineOutliner = RunOutliner::TargetDefault;
+ RegAllocType RegAlloc = RegAllocType::Default;
+ CFLAAType UseCFLAA = CFLAAType::None;
+ Optional<GlobalISelAbortMode> EnableGlobalISelAbort;
+
+ Optional<bool> VerifyMachineCode;
+ Optional<bool> EnableFastISelOption;
+ Optional<bool> EnableGlobalISelOption;
+};
+
+CGPassBuilderOption getCGPassBuilderOption();
+
+} // namespace llvm
+
+#endif // LLVM_CODEGEN_PASSBUILDER_OPTION_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Target/GenericOpcodes.td b/contrib/libs/llvm12/include/llvm/Target/GenericOpcodes.td
index fb2e8b1de8..209925969d 100644
--- a/contrib/libs/llvm12/include/llvm/Target/GenericOpcodes.td
+++ b/contrib/libs/llvm12/include/llvm/Target/GenericOpcodes.td
@@ -16,7 +16,7 @@
//------------------------------------------------------------------------------
class GenericInstruction : StandardPseudoInstruction {
- let isPreISelOpcode = true;
+ let isPreISelOpcode = true;
}
// Provide a variant of an instruction with the same operands, but
@@ -31,8 +31,8 @@ class ConstrainedIntruction<GenericInstruction baseInst> :
// TODO: Do we need a better way to mark reads from FP mode than
// hasSideEffects?
- let hasSideEffects = true;
- let mayRaiseFPException = true;
+ let hasSideEffects = true;
+ let mayRaiseFPException = true;
}
// Extend the underlying scalar type of an operation, leaving the high bits
@@ -40,7 +40,7 @@ class ConstrainedIntruction<GenericInstruction baseInst> :
def G_ANYEXT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Sign extend the underlying scalar type of an operation, copying the sign bit
@@ -48,7 +48,7 @@ def G_ANYEXT : GenericInstruction {
def G_SEXT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Sign extend the a value from an arbitrary bit position, copying the sign bit
@@ -62,7 +62,7 @@ def G_SEXT : GenericInstruction {
def G_SEXT_INREG : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src, untyped_imm_0:$sz);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Zero extend the underlying scalar type of an operation, putting zero bits
@@ -70,7 +70,7 @@ def G_SEXT_INREG : GenericInstruction {
def G_ZEXT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
@@ -79,150 +79,150 @@ def G_ZEXT : GenericInstruction {
def G_TRUNC : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_IMPLICIT_DEF : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_PHI : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins variable_ops);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_FRAME_INDEX : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins unknown:$src2);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_GLOBAL_VALUE : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins unknown:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_INTTOPTR : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_PTRTOINT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_BITCAST : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Only supports scalar result types
def G_CONSTANT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins unknown:$imm);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Only supports scalar result types
def G_FCONSTANT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins unknown:$imm);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_VASTART : GenericInstruction {
let OutOperandList = (outs);
let InOperandList = (ins type0:$list);
- let hasSideEffects = false;
- let mayStore = true;
+ let hasSideEffects = false;
+ let mayStore = true;
}
def G_VAARG : GenericInstruction {
let OutOperandList = (outs type0:$val);
let InOperandList = (ins type1:$list, unknown:$align);
- let hasSideEffects = false;
- let mayLoad = true;
- let mayStore = true;
+ let hasSideEffects = false;
+ let mayLoad = true;
+ let mayStore = true;
}
def G_CTLZ : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_CTLZ_ZERO_UNDEF : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_CTTZ : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_CTTZ_ZERO_UNDEF : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_CTPOP : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_BSWAP : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_BITREVERSE : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_ADDRSPACE_CAST : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_BLOCK_ADDR : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins unknown:$ba);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_JUMP_TABLE : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins unknown:$jti);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_DYN_STACKALLOC : GenericInstruction {
let OutOperandList = (outs ptype0:$dst);
let InOperandList = (ins type1:$size, i32imm:$align);
- let hasSideEffects = true;
+ let hasSideEffects = true;
}
def G_FREEZE : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
//------------------------------------------------------------------------------
@@ -233,101 +233,101 @@ def G_FREEZE : GenericInstruction {
def G_ADD : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// Generic subtraction.
def G_SUB : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
+ let hasSideEffects = false;
+ let isCommutable = false;
}
// Generic multiplication.
def G_MUL : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// Generic signed division.
def G_SDIV : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
+ let hasSideEffects = false;
+ let isCommutable = false;
}
// Generic unsigned division.
def G_UDIV : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
+ let hasSideEffects = false;
+ let isCommutable = false;
}
// Generic signed remainder.
def G_SREM : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
+ let hasSideEffects = false;
+ let isCommutable = false;
}
// Generic unsigned remainder.
def G_UREM : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
+ let hasSideEffects = false;
+ let isCommutable = false;
}
// Generic bitwise and.
def G_AND : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// Generic bitwise or.
def G_OR : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// Generic bitwise xor.
def G_XOR : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// Generic left-shift.
def G_SHL : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type1:$src2);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Generic logical right-shift.
def G_LSHR : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type1:$src2);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Generic arithmetic right-shift.
def G_ASHR : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type1:$src2);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
/// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount.
@@ -335,7 +335,7 @@ def G_ASHR : GenericInstruction {
def G_FSHL : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2, type1:$src3);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
/// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount.
@@ -343,35 +343,35 @@ def G_FSHL : GenericInstruction {
def G_FSHR : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2, type1:$src3);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Generic integer comparison.
def G_ICMP : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Generic floating-point comparison.
def G_FCMP : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Generic select
def G_SELECT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Generic pointer offset.
def G_PTR_ADD : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type1:$src2);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Generic pointer mask. type1 should be an integer with the same
@@ -379,48 +379,48 @@ def G_PTR_ADD : GenericInstruction {
def G_PTRMASK : GenericInstruction {
let OutOperandList = (outs ptype0:$dst);
let InOperandList = (ins ptype0:$src, type1:$bits);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Generic signed integer minimum.
def G_SMIN : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// Generic signed integer maximum.
def G_SMAX : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// Generic unsigned integer minimum.
def G_UMIN : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// Generic unsigned integer maximum.
def G_UMAX : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
+}
+
+// Generic integer absolute value.
+def G_ABS : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src);
+ let hasSideEffects = false;
}
-// Generic integer absolute value.
-def G_ABS : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src);
- let hasSideEffects = false;
-}
-
//------------------------------------------------------------------------------
// Overflow ops
//------------------------------------------------------------------------------
@@ -429,73 +429,73 @@ def G_ABS : GenericInstruction {
def G_UADDO : GenericInstruction {
let OutOperandList = (outs type0:$dst, type1:$carry_out);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// Generic unsigned addition consuming and producing a carry flag.
def G_UADDE : GenericInstruction {
let OutOperandList = (outs type0:$dst, type1:$carry_out);
let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Generic signed addition producing a carry flag.
def G_SADDO : GenericInstruction {
let OutOperandList = (outs type0:$dst, type1:$carry_out);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// Generic signed addition consuming and producing a carry flag.
def G_SADDE : GenericInstruction {
let OutOperandList = (outs type0:$dst, type1:$carry_out);
let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Generic unsigned subtraction producing a carry flag.
def G_USUBO : GenericInstruction {
let OutOperandList = (outs type0:$dst, type1:$carry_out);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Generic unsigned subtraction consuming and producing a carry flag.
def G_USUBE : GenericInstruction {
let OutOperandList = (outs type0:$dst, type1:$carry_out);
let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Generic signed subtraction producing a carry flag.
def G_SSUBO : GenericInstruction {
let OutOperandList = (outs type0:$dst, type1:$carry_out);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Generic signed subtraction consuming and producing a carry flag.
def G_SSUBE : GenericInstruction {
let OutOperandList = (outs type0:$dst, type1:$carry_out);
let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Generic unsigned multiplication producing a carry flag.
def G_UMULO : GenericInstruction {
let OutOperandList = (outs type0:$dst, type1:$carry_out);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// Generic signed multiplication producing a carry flag.
def G_SMULO : GenericInstruction {
let OutOperandList = (outs type0:$dst, type1:$carry_out);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// Multiply two numbers at twice the incoming bit width (unsigned) and return
@@ -503,8 +503,8 @@ def G_SMULO : GenericInstruction {
def G_UMULH : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// Multiply two numbers at twice the incoming bit width (signed) and return
@@ -512,8 +512,8 @@ def G_UMULH : GenericInstruction {
def G_SMULH : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
//------------------------------------------------------------------------------
@@ -524,121 +524,121 @@ def G_SMULH : GenericInstruction {
def G_UADDSAT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// Generic saturating signed addition.
def G_SADDSAT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// Generic saturating unsigned subtraction.
def G_USUBSAT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
+ let hasSideEffects = false;
+ let isCommutable = false;
}
// Generic saturating signed subtraction.
def G_SSUBSAT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
-}
-
-// Generic saturating unsigned left shift.
-def G_USHLSAT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type1:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
-}
-
-// Generic saturating signed left shift.
-def G_SSHLSAT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type1:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
-}
-
-/// RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point
-/// multiplication on 2 integers with the same width and scale. SCALE
-/// represents the scale of both operands as fixed point numbers. This
-/// SCALE parameter must be a constant integer. A scale of zero is
-/// effectively performing multiplication on 2 integers.
-def G_SMULFIX : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
- let hasSideEffects = false;
- let isCommutable = true;
-}
-
-def G_UMULFIX : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
- let hasSideEffects = false;
- let isCommutable = true;
-}
-
-/// Same as the corresponding unsaturated fixed point instructions, but the
-/// result is clamped between the min and max values representable by the
-/// bits of the first 2 operands.
-def G_SMULFIXSAT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
- let hasSideEffects = false;
- let isCommutable = true;
-}
-
-def G_UMULFIXSAT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
- let hasSideEffects = false;
- let isCommutable = true;
-}
-
-/// RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on
-/// 2 integers with the same width and scale. SCALE represents the scale
-/// of both operands as fixed point numbers. This SCALE parameter must be a
-/// constant integer.
-def G_SDIVFIX : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
- let hasSideEffects = false;
- let isCommutable = false;
-}
-
-def G_UDIVFIX : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
- let hasSideEffects = false;
- let isCommutable = false;
-}
-
-/// Same as the corresponding unsaturated fixed point instructions,
-/// but the result is clamped between the min and max values
-/// representable by the bits of the first 2 operands.
-def G_SDIVFIXSAT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
- let hasSideEffects = false;
- let isCommutable = false;
-}
-
-def G_UDIVFIXSAT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
- let hasSideEffects = false;
- let isCommutable = false;
-}
-
+ let hasSideEffects = false;
+ let isCommutable = false;
+}
+
+// Generic saturating unsigned left shift.
+def G_USHLSAT : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type1:$src2);
+ let hasSideEffects = false;
+ let isCommutable = false;
+}
+
+// Generic saturating signed left shift.
+def G_SSHLSAT : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type1:$src2);
+ let hasSideEffects = false;
+ let isCommutable = false;
+}
+
+/// RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point
+/// multiplication on 2 integers with the same width and scale. SCALE
+/// represents the scale of both operands as fixed point numbers. This
+/// SCALE parameter must be a constant integer. A scale of zero is
+/// effectively performing multiplication on 2 integers.
+def G_SMULFIX : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
+ let hasSideEffects = false;
+ let isCommutable = true;
+}
+
+def G_UMULFIX : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
+ let hasSideEffects = false;
+ let isCommutable = true;
+}
+
+/// Same as the corresponding unsaturated fixed point instructions, but the
+/// result is clamped between the min and max values representable by the
+/// bits of the first 2 operands.
+def G_SMULFIXSAT : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
+ let hasSideEffects = false;
+ let isCommutable = true;
+}
+
+def G_UMULFIXSAT : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
+ let hasSideEffects = false;
+ let isCommutable = true;
+}
+
+/// RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on
+/// 2 integers with the same width and scale. SCALE represents the scale
+/// of both operands as fixed point numbers. This SCALE parameter must be a
+/// constant integer.
+def G_SDIVFIX : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
+ let hasSideEffects = false;
+ let isCommutable = false;
+}
+
+def G_UDIVFIX : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
+ let hasSideEffects = false;
+ let isCommutable = false;
+}
+
+/// Same as the corresponding unsaturated fixed point instructions,
+/// but the result is clamped between the min and max values
+/// representable by the bits of the first 2 operands.
+def G_SDIVFIXSAT : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
+ let hasSideEffects = false;
+ let isCommutable = false;
+}
+
+def G_UDIVFIXSAT : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
+ let hasSideEffects = false;
+ let isCommutable = false;
+}
+
//------------------------------------------------------------------------------
// Floating Point Unary Ops.
//------------------------------------------------------------------------------
@@ -646,61 +646,61 @@ def G_UDIVFIXSAT : GenericInstruction {
def G_FNEG : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_FPEXT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_FPTRUNC : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_FPTOSI : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_FPTOUI : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_SITOFP : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_UITOFP : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_FABS : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_FCOPYSIGN : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src0, type1:$src1);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_FCANONICALIZE : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two
@@ -713,15 +713,15 @@ def G_FCANONICALIZE : GenericInstruction {
def G_FMINNUM : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
def G_FMAXNUM : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on
@@ -731,15 +731,15 @@ def G_FMAXNUM : GenericInstruction {
def G_FMINNUM_IEEE : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
def G_FMAXNUM_IEEE : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0
@@ -748,15 +748,15 @@ def G_FMAXNUM_IEEE : GenericInstruction {
def G_FMINIMUM : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
def G_FMAXIMUM : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
//------------------------------------------------------------------------------
@@ -767,24 +767,24 @@ def G_FMAXIMUM : GenericInstruction {
def G_FADD : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// Generic FP subtraction.
def G_FSUB : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
+ let hasSideEffects = false;
+ let isCommutable = false;
}
// Generic FP multiplication.
def G_FMUL : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
+ let hasSideEffects = false;
+ let isCommutable = true;
}
// Generic fused multiply-add instruction.
@@ -792,8 +792,8 @@ def G_FMUL : GenericInstruction {
def G_FMA : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
- let hasSideEffects = false;
- let isCommutable = false;
+ let hasSideEffects = false;
+ let isCommutable = false;
}
/// Generic FP multiply and add. Perform a * b + c, while getting the
@@ -801,92 +801,92 @@ def G_FMA : GenericInstruction {
def G_FMAD : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
- let hasSideEffects = false;
- let isCommutable = false;
+ let hasSideEffects = false;
+ let isCommutable = false;
}
// Generic FP division.
def G_FDIV : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Generic FP remainder.
def G_FREM : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Floating point exponentiation.
def G_FPOW : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
+ let hasSideEffects = false;
+}
+
+// Floating point exponentiation, with an integer power.
+def G_FPOWI : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src0, type1:$src1);
+ let hasSideEffects = false;
}
-// Floating point exponentiation, with an integer power.
-def G_FPOWI : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type1:$src1);
- let hasSideEffects = false;
-}
-
// Floating point base-e exponential of a value.
def G_FEXP : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Floating point base-2 exponential of a value.
def G_FEXP2 : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Floating point base-e logarithm of a value.
def G_FLOG : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Floating point base-2 logarithm of a value.
def G_FLOG2 : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Floating point base-10 logarithm of a value.
def G_FLOG10 : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Floating point ceiling of a value.
def G_FCEIL : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Floating point cosine of a value.
def G_FCOS : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Floating point sine of a value.
def G_FSIN : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Floating point square root of a value.
@@ -896,28 +896,28 @@ def G_FSIN : GenericInstruction {
def G_FSQRT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Floating point floor of a value.
def G_FFLOOR : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Floating point round to next integer.
def G_FRINT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Floating point round to the nearest integer.
def G_FNEARBYINT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
//------------------------------------------------------------------------------
@@ -926,31 +926,31 @@ def G_FNEARBYINT : GenericInstruction {
def G_INTRINSIC_TRUNC : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def G_INTRINSIC_ROUND : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
-}
-
-def G_INTRINSIC_LRINT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
-}
-
-def G_INTRINSIC_ROUNDEVEN : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
-}
-
+ let hasSideEffects = false;
+}
+
+def G_INTRINSIC_LRINT : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type1:$src);
+ let hasSideEffects = false;
+}
+
+def G_INTRINSIC_ROUNDEVEN : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1);
+ let hasSideEffects = false;
+}
+
def G_READCYCLECOUNTER : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins);
- let hasSideEffects = true;
+ let hasSideEffects = true;
}
//------------------------------------------------------------------------------
@@ -965,24 +965,24 @@ def G_READCYCLECOUNTER : GenericInstruction {
def G_LOAD : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins ptype1:$addr);
- let hasSideEffects = false;
- let mayLoad = true;
+ let hasSideEffects = false;
+ let mayLoad = true;
}
// Generic sign-extended load. Expects a MachineMemOperand in addition to explicit operands.
def G_SEXTLOAD : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins ptype1:$addr);
- let hasSideEffects = false;
- let mayLoad = true;
+ let hasSideEffects = false;
+ let mayLoad = true;
}
// Generic zero-extended load. Expects a MachineMemOperand in addition to explicit operands.
def G_ZEXTLOAD : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins ptype1:$addr);
- let hasSideEffects = false;
- let mayLoad = true;
+ let hasSideEffects = false;
+ let mayLoad = true;
}
// Generic indexed load. Combines a GEP with a load. $newaddr is set to $base + $offset.
@@ -991,32 +991,32 @@ def G_ZEXTLOAD : GenericInstruction {
def G_INDEXED_LOAD : GenericInstruction {
let OutOperandList = (outs type0:$dst, ptype1:$newaddr);
let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am);
- let hasSideEffects = false;
- let mayLoad = true;
+ let hasSideEffects = false;
+ let mayLoad = true;
}
// Same as G_INDEXED_LOAD except that the load performed is sign-extending, as with G_SEXTLOAD.
def G_INDEXED_SEXTLOAD : GenericInstruction {
let OutOperandList = (outs type0:$dst, ptype1:$newaddr);
let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am);
- let hasSideEffects = false;
- let mayLoad = true;
+ let hasSideEffects = false;
+ let mayLoad = true;
}
// Same as G_INDEXED_LOAD except that the load performed is zero-extending, as with G_ZEXTLOAD.
def G_INDEXED_ZEXTLOAD : GenericInstruction {
let OutOperandList = (outs type0:$dst, ptype1:$newaddr);
let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am);
- let hasSideEffects = false;
- let mayLoad = true;
+ let hasSideEffects = false;
+ let mayLoad = true;
}
// Generic store. Expects a MachineMemOperand in addition to explicit operands.
def G_STORE : GenericInstruction {
let OutOperandList = (outs);
let InOperandList = (ins type0:$src, ptype1:$addr);
- let hasSideEffects = false;
- let mayStore = true;
+ let hasSideEffects = false;
+ let mayStore = true;
}
// Combines a store with a GEP. See description of G_INDEXED_LOAD for indexing behaviour.
@@ -1024,8 +1024,8 @@ def G_INDEXED_STORE : GenericInstruction {
let OutOperandList = (outs ptype0:$newaddr);
let InOperandList = (ins type1:$src, ptype0:$base, ptype2:$offset,
unknown:$am);
- let hasSideEffects = false;
- let mayStore = true;
+ let hasSideEffects = false;
+ let mayStore = true;
}
// Generic atomic cmpxchg with internal success check. Expects a
@@ -1033,9 +1033,9 @@ def G_INDEXED_STORE : GenericInstruction {
def G_ATOMIC_CMPXCHG_WITH_SUCCESS : GenericInstruction {
let OutOperandList = (outs type0:$oldval, type1:$success);
let InOperandList = (ins type2:$addr, type0:$cmpval, type0:$newval);
- let hasSideEffects = false;
- let mayLoad = true;
- let mayStore = true;
+ let hasSideEffects = false;
+ let mayLoad = true;
+ let mayStore = true;
}
// Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
@@ -1043,9 +1043,9 @@ def G_ATOMIC_CMPXCHG_WITH_SUCCESS : GenericInstruction {
def G_ATOMIC_CMPXCHG : GenericInstruction {
let OutOperandList = (outs type0:$oldval);
let InOperandList = (ins ptype1:$addr, type0:$cmpval, type0:$newval);
- let hasSideEffects = false;
- let mayLoad = true;
- let mayStore = true;
+ let hasSideEffects = false;
+ let mayLoad = true;
+ let mayStore = true;
}
// Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
@@ -1053,9 +1053,9 @@ def G_ATOMIC_CMPXCHG : GenericInstruction {
class G_ATOMICRMW_OP : GenericInstruction {
let OutOperandList = (outs type0:$oldval);
let InOperandList = (ins ptype1:$addr, type0:$val);
- let hasSideEffects = false;
- let mayLoad = true;
- let mayStore = true;
+ let hasSideEffects = false;
+ let mayLoad = true;
+ let mayStore = true;
}
def G_ATOMICRMW_XCHG : G_ATOMICRMW_OP;
@@ -1075,7 +1075,7 @@ def G_ATOMICRMW_FSUB : G_ATOMICRMW_OP;
def G_FENCE : GenericInstruction {
let OutOperandList = (outs);
let InOperandList = (ins i32imm:$ordering, i32imm:$scope);
- let hasSideEffects = true;
+ let hasSideEffects = true;
}
//------------------------------------------------------------------------------
@@ -1088,7 +1088,7 @@ def G_FENCE : GenericInstruction {
def G_EXTRACT : GenericInstruction {
let OutOperandList = (outs type0:$res);
let InOperandList = (ins type1:$src, untyped_imm_0:$offset);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Extract multiple registers specified size, starting from blocks given by
@@ -1100,14 +1100,14 @@ def G_EXTRACT : GenericInstruction {
def G_UNMERGE_VALUES : GenericInstruction {
let OutOperandList = (outs type0:$dst0, variable_ops);
let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Insert a smaller register into a larger one at the specified bit-index.
def G_INSERT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src, type1:$op, untyped_imm_0:$offset);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Concatenate multiple registers of the same size into a wider register.
@@ -1117,7 +1117,7 @@ def G_INSERT : GenericInstruction {
def G_MERGE_VALUES : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src0, variable_ops);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
/// Create a vector from multiple scalar registers. No implicit
@@ -1126,7 +1126,7 @@ def G_MERGE_VALUES : GenericInstruction {
def G_BUILD_VECTOR : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src0, variable_ops);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
/// Like G_BUILD_VECTOR, but truncates the larger operand types to fit the
@@ -1134,24 +1134,24 @@ def G_BUILD_VECTOR : GenericInstruction {
def G_BUILD_VECTOR_TRUNC : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src0, variable_ops);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
/// Create a vector by concatenating vectors together.
def G_CONCAT_VECTORS : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src0, variable_ops);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Intrinsic without side effects.
def G_INTRINSIC : GenericInstruction {
let OutOperandList = (outs);
let InOperandList = (ins unknown:$intrin, variable_ops);
- let hasSideEffects = false;
+ let hasSideEffects = false;
// Conservatively assume this is convergent. If there turnes out to
- // be a need, there should be separate convergent intrinsic opcodes.
+ // be a need, there should be separate convergent intrinsic opcodes.
let isConvergent = 1;
}
@@ -1159,13 +1159,13 @@ def G_INTRINSIC : GenericInstruction {
def G_INTRINSIC_W_SIDE_EFFECTS : GenericInstruction {
let OutOperandList = (outs);
let InOperandList = (ins unknown:$intrin, variable_ops);
- let hasSideEffects = true;
- let mayLoad = true;
- let mayStore = true;
+ let hasSideEffects = true;
+ let mayLoad = true;
+ let mayStore = true;
// Conservatively assume this is convergent. If there turnes out to
- // be a need, there should be separate convergent intrinsic opcodes.
- let isConvergent = true;
+ // be a need, there should be separate convergent intrinsic opcodes.
+ let isConvergent = true;
}
//------------------------------------------------------------------------------
@@ -1176,61 +1176,61 @@ def G_INTRINSIC_W_SIDE_EFFECTS : GenericInstruction {
def G_BR : GenericInstruction {
let OutOperandList = (outs);
let InOperandList = (ins unknown:$src1);
- let hasSideEffects = false;
- let isBranch = true;
- let isTerminator = true;
- let isBarrier = true;
+ let hasSideEffects = false;
+ let isBranch = true;
+ let isTerminator = true;
+ let isBarrier = true;
}
// Generic conditional branch.
def G_BRCOND : GenericInstruction {
let OutOperandList = (outs);
let InOperandList = (ins type0:$tst, unknown:$truebb);
- let hasSideEffects = false;
- let isBranch = true;
- let isTerminator = true;
+ let hasSideEffects = false;
+ let isBranch = true;
+ let isTerminator = true;
}
// Generic indirect branch.
def G_BRINDIRECT : GenericInstruction {
let OutOperandList = (outs);
let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
- let isBranch = true;
- let isTerminator = true;
- let isBarrier = true;
- let isIndirectBranch = true;
+ let hasSideEffects = false;
+ let isBranch = true;
+ let isTerminator = true;
+ let isBarrier = true;
+ let isIndirectBranch = true;
}
// Generic branch to jump table entry
def G_BRJT : GenericInstruction {
let OutOperandList = (outs);
let InOperandList = (ins ptype0:$tbl, unknown:$jti, type1:$idx);
- let hasSideEffects = false;
- let isBranch = true;
- let isTerminator = true;
- let isBarrier = true;
- let isIndirectBranch = true;
+ let hasSideEffects = false;
+ let isBranch = true;
+ let isTerminator = true;
+ let isBarrier = true;
+ let isIndirectBranch = true;
}
def G_READ_REGISTER : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins unknown:$register);
- let hasSideEffects = true;
+ let hasSideEffects = true;
// Assume convergent. It's probably not worth the effort of somehow
// modeling convergent and nonconvergent register accesses.
- let isConvergent = true;
+ let isConvergent = true;
}
def G_WRITE_REGISTER : GenericInstruction {
let OutOperandList = (outs);
let InOperandList = (ins unknown:$register, type0:$value);
- let hasSideEffects = true;
+ let hasSideEffects = true;
// Assume convergent. It's probably not worth the effort of somehow
// modeling convergent and nonconvergent register accesses.
- let isConvergent = true;
+ let isConvergent = true;
}
//------------------------------------------------------------------------------
@@ -1241,14 +1241,14 @@ def G_WRITE_REGISTER : GenericInstruction {
def G_INSERT_VECTOR_ELT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Generic extractelement.
def G_EXTRACT_VECTOR_ELT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src, type2:$idx);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
// Generic shufflevector.
@@ -1258,48 +1258,48 @@ def G_EXTRACT_VECTOR_ELT : GenericInstruction {
def G_SHUFFLE_VECTOR: GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$v1, type1:$v2, unknown:$mask);
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
//------------------------------------------------------------------------------
-// Vector reductions
-//------------------------------------------------------------------------------
-
-class VectorReduction : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$v);
- let hasSideEffects = false;
-}
-
-def G_VECREDUCE_SEQ_FADD : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$acc, type2:$v);
- let hasSideEffects = false;
-}
-
-def G_VECREDUCE_SEQ_FMUL : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$acc, type2:$v);
- let hasSideEffects = false;
-}
-
-def G_VECREDUCE_FADD : VectorReduction;
-def G_VECREDUCE_FMUL : VectorReduction;
-
-def G_VECREDUCE_FMAX : VectorReduction;
-def G_VECREDUCE_FMIN : VectorReduction;
-
-def G_VECREDUCE_ADD : VectorReduction;
-def G_VECREDUCE_MUL : VectorReduction;
-def G_VECREDUCE_AND : VectorReduction;
-def G_VECREDUCE_OR : VectorReduction;
-def G_VECREDUCE_XOR : VectorReduction;
-def G_VECREDUCE_SMAX : VectorReduction;
-def G_VECREDUCE_SMIN : VectorReduction;
-def G_VECREDUCE_UMAX : VectorReduction;
-def G_VECREDUCE_UMIN : VectorReduction;
-
-//------------------------------------------------------------------------------
+// Vector reductions
+//------------------------------------------------------------------------------
+
+class VectorReduction : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type1:$v);
+ let hasSideEffects = false;
+}
+
+def G_VECREDUCE_SEQ_FADD : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type1:$acc, type2:$v);
+ let hasSideEffects = false;
+}
+
+def G_VECREDUCE_SEQ_FMUL : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type1:$acc, type2:$v);
+ let hasSideEffects = false;
+}
+
+def G_VECREDUCE_FADD : VectorReduction;
+def G_VECREDUCE_FMUL : VectorReduction;
+
+def G_VECREDUCE_FMAX : VectorReduction;
+def G_VECREDUCE_FMIN : VectorReduction;
+
+def G_VECREDUCE_ADD : VectorReduction;
+def G_VECREDUCE_MUL : VectorReduction;
+def G_VECREDUCE_AND : VectorReduction;
+def G_VECREDUCE_OR : VectorReduction;
+def G_VECREDUCE_XOR : VectorReduction;
+def G_VECREDUCE_SMAX : VectorReduction;
+def G_VECREDUCE_SMIN : VectorReduction;
+def G_VECREDUCE_UMAX : VectorReduction;
+def G_VECREDUCE_UMIN : VectorReduction;
+
+//------------------------------------------------------------------------------
// Constrained floating point ops
//------------------------------------------------------------------------------
@@ -1310,30 +1310,30 @@ def G_STRICT_FDIV : ConstrainedIntruction<G_FDIV>;
def G_STRICT_FREM : ConstrainedIntruction<G_FREM>;
def G_STRICT_FMA : ConstrainedIntruction<G_FMA>;
def G_STRICT_FSQRT : ConstrainedIntruction<G_FSQRT>;
-
-//------------------------------------------------------------------------------
-// Memory intrinsics
-//------------------------------------------------------------------------------
-
-def G_MEMCPY : GenericInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins ptype0:$dst_addr, ptype1:$src_addr, type2:$size, untyped_imm_0:$tailcall);
- let hasSideEffects = false;
- let mayLoad = true;
- let mayStore = true;
-}
-
-def G_MEMMOVE : GenericInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins ptype0:$dst_addr, ptype1:$src_addr, type2:$size, untyped_imm_0:$tailcall);
- let hasSideEffects = false;
- let mayLoad = true;
- let mayStore = true;
-}
-
-def G_MEMSET : GenericInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins ptype0:$dst_addr, type1:$value, type2:$size, untyped_imm_0:$tailcall);
- let hasSideEffects = false;
- let mayStore = true;
-}
+
+//------------------------------------------------------------------------------
+// Memory intrinsics
+//------------------------------------------------------------------------------
+
+def G_MEMCPY : GenericInstruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins ptype0:$dst_addr, ptype1:$src_addr, type2:$size, untyped_imm_0:$tailcall);
+ let hasSideEffects = false;
+ let mayLoad = true;
+ let mayStore = true;
+}
+
+def G_MEMMOVE : GenericInstruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins ptype0:$dst_addr, ptype1:$src_addr, type2:$size, untyped_imm_0:$tailcall);
+ let hasSideEffects = false;
+ let mayLoad = true;
+ let mayStore = true;
+}
+
+def G_MEMSET : GenericInstruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins ptype0:$dst_addr, type1:$value, type2:$size, untyped_imm_0:$tailcall);
+ let hasSideEffects = false;
+ let mayStore = true;
+}
diff --git a/contrib/libs/llvm12/include/llvm/Target/GlobalISel/Combine.td b/contrib/libs/llvm12/include/llvm/Target/GlobalISel/Combine.td
index 2dde4acdc9..e2c7a90a1b 100644
--- a/contrib/libs/llvm12/include/llvm/Target/GlobalISel/Combine.td
+++ b/contrib/libs/llvm12/include/llvm/Target/GlobalISel/Combine.td
@@ -85,7 +85,7 @@ class GIDefMatchData<string type> : GIDefKind {
def extending_load_matchdata : GIDefMatchData<"PreferredTuple">;
def indexed_load_store_matchdata : GIDefMatchData<"IndexedLoadStoreMatchInfo">;
-def instruction_steps_matchdata: GIDefMatchData<"InstructionStepsMatchInfo">;
+def instruction_steps_matchdata: GIDefMatchData<"InstructionStepsMatchInfo">;
/// The operator at the root of a GICombineRule.Match dag.
def match;
@@ -126,30 +126,30 @@ def extending_loads : GICombineRule<
(apply [{ Helper.applyCombineExtendingLoads(*${root}, ${matchinfo}); }])>;
def combines_for_extload: GICombineGroup<[extending_loads]>;
-def sext_trunc_sextload : GICombineRule<
+def sext_trunc_sextload : GICombineRule<
(defs root:$d),
(match (wip_match_opcode G_SEXT_INREG):$d,
- [{ return Helper.matchSextTruncSextLoad(*${d}); }]),
- (apply [{ Helper.applySextTruncSextLoad(*${d}); }])>;
-
-def sext_inreg_of_load_matchdata : GIDefMatchData<"std::tuple<Register, unsigned>">;
-def sext_inreg_of_load : GICombineRule<
- (defs root:$root, sext_inreg_of_load_matchdata:$matchinfo),
- (match (wip_match_opcode G_SEXT_INREG):$root,
- [{ return Helper.matchSextInRegOfLoad(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.applySextInRegOfLoad(*${root}, ${matchinfo}); }])>;
-
+ [{ return Helper.matchSextTruncSextLoad(*${d}); }]),
+ (apply [{ Helper.applySextTruncSextLoad(*${d}); }])>;
+
+def sext_inreg_of_load_matchdata : GIDefMatchData<"std::tuple<Register, unsigned>">;
+def sext_inreg_of_load : GICombineRule<
+ (defs root:$root, sext_inreg_of_load_matchdata:$matchinfo),
+ (match (wip_match_opcode G_SEXT_INREG):$root,
+ [{ return Helper.matchSextInRegOfLoad(*${root}, ${matchinfo}); }]),
+ (apply [{ return Helper.applySextInRegOfLoad(*${root}, ${matchinfo}); }])>;
+
def combine_indexed_load_store : GICombineRule<
(defs root:$root, indexed_load_store_matchdata:$matchinfo),
(match (wip_match_opcode G_LOAD, G_SEXTLOAD, G_ZEXTLOAD, G_STORE):$root,
[{ return Helper.matchCombineIndexedLoadStore(*${root}, ${matchinfo}); }]),
(apply [{ Helper.applyCombineIndexedLoadStore(*${root}, ${matchinfo}); }])>;
-def opt_brcond_by_inverting_cond : GICombineRule<
+def opt_brcond_by_inverting_cond : GICombineRule<
(defs root:$root),
(match (wip_match_opcode G_BR):$root,
- [{ return Helper.matchOptBrCondByInvertingCond(*${root}); }]),
- (apply [{ Helper.applyOptBrCondByInvertingCond(*${root}); }])>;
+ [{ return Helper.matchOptBrCondByInvertingCond(*${root}); }]),
+ (apply [{ Helper.applyOptBrCondByInvertingCond(*${root}); }])>;
def ptr_add_immed_matchdata : GIDefMatchData<"PtrAddChain">;
def ptr_add_immed_chain : GICombineRule<
@@ -158,23 +158,23 @@ def ptr_add_immed_chain : GICombineRule<
[{ return Helper.matchPtrAddImmedChain(*${d}, ${matchinfo}); }]),
(apply [{ Helper.applyPtrAddImmedChain(*${d}, ${matchinfo}); }])>;
-// Fold shift (shift base x), y -> shift base, (x+y), if shifts are same
-def shift_immed_matchdata : GIDefMatchData<"RegisterImmPair">;
-def shift_immed_chain : GICombineRule<
- (defs root:$d, shift_immed_matchdata:$matchinfo),
- (match (wip_match_opcode G_SHL, G_ASHR, G_LSHR, G_SSHLSAT, G_USHLSAT):$d,
- [{ return Helper.matchShiftImmedChain(*${d}, ${matchinfo}); }]),
- (apply [{ Helper.applyShiftImmedChain(*${d}, ${matchinfo}); }])>;
-
-// Transform shift (logic (shift X, C0), Y), C1
-// -> logic (shift X, (C0+C1)), (shift Y, C1), if shifts are same
-def shift_of_shifted_logic_matchdata : GIDefMatchData<"ShiftOfShiftedLogic">;
-def shift_of_shifted_logic_chain : GICombineRule<
- (defs root:$d, shift_of_shifted_logic_matchdata:$matchinfo),
- (match (wip_match_opcode G_SHL, G_ASHR, G_LSHR, G_USHLSAT, G_SSHLSAT):$d,
- [{ return Helper.matchShiftOfShiftedLogic(*${d}, ${matchinfo}); }]),
- (apply [{ Helper.applyShiftOfShiftedLogic(*${d}, ${matchinfo}); }])>;
-
+// Fold shift (shift base x), y -> shift base, (x+y), if shifts are same
+def shift_immed_matchdata : GIDefMatchData<"RegisterImmPair">;
+def shift_immed_chain : GICombineRule<
+ (defs root:$d, shift_immed_matchdata:$matchinfo),
+ (match (wip_match_opcode G_SHL, G_ASHR, G_LSHR, G_SSHLSAT, G_USHLSAT):$d,
+ [{ return Helper.matchShiftImmedChain(*${d}, ${matchinfo}); }]),
+ (apply [{ Helper.applyShiftImmedChain(*${d}, ${matchinfo}); }])>;
+
+// Transform shift (logic (shift X, C0), Y), C1
+// -> logic (shift X, (C0+C1)), (shift Y, C1), if shifts are same
+def shift_of_shifted_logic_matchdata : GIDefMatchData<"ShiftOfShiftedLogic">;
+def shift_of_shifted_logic_chain : GICombineRule<
+ (defs root:$d, shift_of_shifted_logic_matchdata:$matchinfo),
+ (match (wip_match_opcode G_SHL, G_ASHR, G_LSHR, G_USHLSAT, G_SSHLSAT):$d,
+ [{ return Helper.matchShiftOfShiftedLogic(*${d}, ${matchinfo}); }]),
+ (apply [{ Helper.applyShiftOfShiftedLogic(*${d}, ${matchinfo}); }])>;
+
def mul_to_shl_matchdata : GIDefMatchData<"unsigned">;
def mul_to_shl : GICombineRule<
(defs root:$d, mul_to_shl_matchdata:$matchinfo),
@@ -182,14 +182,14 @@ def mul_to_shl : GICombineRule<
[{ return Helper.matchCombineMulToShl(*${mi}, ${matchinfo}); }]),
(apply [{ Helper.applyCombineMulToShl(*${mi}, ${matchinfo}); }])>;
-// shl ([asz]ext x), y => zext (shl x, y), if shift does not overflow int
-def reduce_shl_of_extend_matchdata : GIDefMatchData<"RegisterImmPair">;
-def reduce_shl_of_extend : GICombineRule<
- (defs root:$dst, reduce_shl_of_extend_matchdata:$matchinfo),
- (match (G_SHL $dst, $src0, $src1):$mi,
- [{ return Helper.matchCombineShlOfExtend(*${mi}, ${matchinfo}); }]),
- (apply [{ Helper.applyCombineShlOfExtend(*${mi}, ${matchinfo}); }])>;
-
+// shl ([asz]ext x), y => zext (shl x, y), if shift does not overflow int
+def reduce_shl_of_extend_matchdata : GIDefMatchData<"RegisterImmPair">;
+def reduce_shl_of_extend : GICombineRule<
+ (defs root:$dst, reduce_shl_of_extend_matchdata:$matchinfo),
+ (match (G_SHL $dst, $src0, $src1):$mi,
+ [{ return Helper.matchCombineShlOfExtend(*${mi}, ${matchinfo}); }]),
+ (apply [{ Helper.applyCombineShlOfExtend(*${mi}, ${matchinfo}); }])>;
+
// [us]itofp(undef) = 0, because the result value is bounded.
def undef_to_fp_zero : GICombineRule<
(defs root:$root),
@@ -209,17 +209,17 @@ def undef_to_negative_one: GICombineRule<
[{ return Helper.matchAnyExplicitUseIsUndef(*${root}); }]),
(apply [{ Helper.replaceInstWithConstant(*${root}, -1); }])>;
-def binop_left_undef_to_zero: GICombineRule<
- (defs root:$root),
- (match (wip_match_opcode G_SHL):$root,
- [{ return Helper.matchOperandIsUndef(*${root}, 1); }]),
- (apply [{ Helper.replaceInstWithConstant(*${root}, 0); }])>;
-
+def binop_left_undef_to_zero: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_SHL):$root,
+ [{ return Helper.matchOperandIsUndef(*${root}, 1); }]),
+ (apply [{ Helper.replaceInstWithConstant(*${root}, 0); }])>;
+
// Instructions where if any source operand is undef, the instruction can be
// replaced with undef.
def propagate_undef_any_op: GICombineRule<
(defs root:$root),
- (match (wip_match_opcode G_ADD, G_FPTOSI, G_FPTOUI, G_SUB, G_XOR, G_TRUNC):$root,
+ (match (wip_match_opcode G_ADD, G_FPTOSI, G_FPTOUI, G_SUB, G_XOR, G_TRUNC):$root,
[{ return Helper.matchAnyExplicitUseIsUndef(*${root}); }]),
(apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
@@ -246,24 +246,24 @@ def select_same_val: GICombineRule<
(apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
>;
-// Fold (undef ? x : y) -> y
-def select_undef_cmp: GICombineRule<
- (defs root:$root),
- (match (wip_match_opcode G_SELECT):$root,
- [{ return Helper.matchUndefSelectCmp(*${root}); }]),
- (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
->;
-
-// Fold (true ? x : y) -> x
-// Fold (false ? x : y) -> y
-def select_constant_cmp_matchdata : GIDefMatchData<"unsigned">;
-def select_constant_cmp: GICombineRule<
- (defs root:$root, select_constant_cmp_matchdata:$matchinfo),
- (match (wip_match_opcode G_SELECT):$root,
- [{ return Helper.matchConstantSelectCmp(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, ${matchinfo}); }])
->;
-
+// Fold (undef ? x : y) -> y
+def select_undef_cmp: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_SELECT):$root,
+ [{ return Helper.matchUndefSelectCmp(*${root}); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
+>;
+
+// Fold (true ? x : y) -> x
+// Fold (false ? x : y) -> y
+def select_constant_cmp_matchdata : GIDefMatchData<"unsigned">;
+def select_constant_cmp: GICombineRule<
+ (defs root:$root, select_constant_cmp_matchdata:$matchinfo),
+ (match (wip_match_opcode G_SELECT):$root,
+ [{ return Helper.matchConstantSelectCmp(*${root}, ${matchinfo}); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, ${matchinfo}); }])
+>;
+
// Fold x op 0 -> x
def right_identity_zero: GICombineRule<
(defs root:$root),
@@ -272,14 +272,14 @@ def right_identity_zero: GICombineRule<
(apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
>;
-// Fold x op 1 -> x
-def right_identity_one: GICombineRule<
- (defs root:$root),
- (match (wip_match_opcode G_MUL):$root,
- [{ return Helper.matchConstantOp(${root}->getOperand(2), 1); }]),
- (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
->;
-
+// Fold x op 1 -> x
+def right_identity_one: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_MUL):$root,
+ [{ return Helper.matchConstantOp(${root}->getOperand(2), 1); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
+>;
+
// Fold (x op x) - > x
def binop_same_val: GICombineRule<
(defs root:$root),
@@ -296,13 +296,13 @@ def binop_left_to_zero: GICombineRule<
(apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
>;
-def urem_pow2_to_mask : GICombineRule<
- (defs root:$root),
- (match (wip_match_opcode G_UREM):$root,
- [{ return Helper.matchOperandIsKnownToBeAPowerOfTwo(*${root}, 2); }]),
- (apply [{ return Helper.applySimplifyURemByPow2(*${root}); }])
->;
-
+def urem_pow2_to_mask : GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_UREM):$root,
+ [{ return Helper.matchOperandIsKnownToBeAPowerOfTwo(*${root}, 2); }]),
+ (apply [{ return Helper.applySimplifyURemByPow2(*${root}); }])
+>;
+
// Fold (x op 0) - > 0
def binop_right_to_zero: GICombineRule<
(defs root:$root),
@@ -327,240 +327,240 @@ def simplify_add_to_sub: GICombineRule <
(apply [{ return Helper.applySimplifyAddToSub(*${root}, ${info});}])
>;
-// Fold fp_op(cst) to the constant result of the floating point operation.
-def constant_fp_op_matchinfo: GIDefMatchData<"Optional<APFloat>">;
-def constant_fp_op: GICombineRule <
- (defs root:$root, constant_fp_op_matchinfo:$info),
- (match (wip_match_opcode G_FNEG, G_FABS, G_FPTRUNC, G_FSQRT, G_FLOG2):$root,
- [{ return Helper.matchCombineConstantFoldFpUnary(*${root}, ${info}); }]),
- (apply [{ return Helper.applyCombineConstantFoldFpUnary(*${root}, ${info}); }])
->;
-
-// Fold int2ptr(ptr2int(x)) -> x
-def p2i_to_i2p_matchinfo: GIDefMatchData<"Register">;
-def p2i_to_i2p: GICombineRule<
- (defs root:$root, p2i_to_i2p_matchinfo:$info),
- (match (wip_match_opcode G_INTTOPTR):$root,
- [{ return Helper.matchCombineI2PToP2I(*${root}, ${info}); }]),
- (apply [{ return Helper.applyCombineI2PToP2I(*${root}, ${info}); }])
->;
-
-// Fold ptr2int(int2ptr(x)) -> x
-def i2p_to_p2i_matchinfo: GIDefMatchData<"Register">;
-def i2p_to_p2i: GICombineRule<
- (defs root:$root, i2p_to_p2i_matchinfo:$info),
- (match (wip_match_opcode G_PTRTOINT):$root,
- [{ return Helper.matchCombineP2IToI2P(*${root}, ${info}); }]),
- (apply [{ return Helper.applyCombineP2IToI2P(*${root}, ${info}); }])
->;
-
-// Fold add ptrtoint(x), y -> ptrtoint (ptr_add x), y
-def add_p2i_to_ptradd_matchinfo : GIDefMatchData<"std::pair<Register, bool>">;
-def add_p2i_to_ptradd : GICombineRule<
- (defs root:$root, add_p2i_to_ptradd_matchinfo:$info),
- (match (wip_match_opcode G_ADD):$root,
- [{ return Helper.matchCombineAddP2IToPtrAdd(*${root}, ${info}); }]),
- (apply [{ return Helper.applyCombineAddP2IToPtrAdd(*${root}, ${info}); }])
->;
-
-// Fold (ptr_add (int2ptr C1), C2) -> C1 + C2
-def const_ptradd_to_i2p_matchinfo : GIDefMatchData<"int64_t">;
-def const_ptradd_to_i2p: GICombineRule<
- (defs root:$root, const_ptradd_to_i2p_matchinfo:$info),
- (match (wip_match_opcode G_PTR_ADD):$root,
- [{ return Helper.matchCombineConstPtrAddToI2P(*${root}, ${info}); }]),
- (apply [{ return Helper.applyCombineConstPtrAddToI2P(*${root}, ${info}); }])
->;
-
-// Simplify: (logic_op (op x...), (op y...)) -> (op (logic_op x, y))
-def hoist_logic_op_with_same_opcode_hands: GICombineRule <
- (defs root:$root, instruction_steps_matchdata:$info),
- (match (wip_match_opcode G_AND, G_OR, G_XOR):$root,
- [{ return Helper.matchHoistLogicOpWithSameOpcodeHands(*${root}, ${info}); }]),
- (apply [{ return Helper.applyBuildInstructionSteps(*${root}, ${info});}])
->;
-
-// Fold ashr (shl x, C), C -> sext_inreg (C)
-def shl_ashr_to_sext_inreg_matchinfo : GIDefMatchData<"std::tuple<Register, int64_t>">;
-def shl_ashr_to_sext_inreg : GICombineRule<
- (defs root:$root, shl_ashr_to_sext_inreg_matchinfo:$info),
- (match (wip_match_opcode G_ASHR): $root,
- [{ return Helper.matchAshrShlToSextInreg(*${root}, ${info}); }]),
- (apply [{ return Helper.applyAshShlToSextInreg(*${root}, ${info});}])
->;
-// Fold (x & y) -> x or (x & y) -> y when (x & y) is known to equal x or equal y.
-def redundant_and_matchinfo : GIDefMatchData<"Register">;
-def redundant_and: GICombineRule <
- (defs root:$root, redundant_and_matchinfo:$matchinfo),
- (match (wip_match_opcode G_AND):$root,
- [{ return Helper.matchRedundantAnd(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.replaceSingleDefInstWithReg(*${root}, ${matchinfo}); }])
->;
-
-// Fold (x | y) -> x or (x | y) -> y when (x | y) is known to equal x or equal y.
-def redundant_or_matchinfo : GIDefMatchData<"Register">;
-def redundant_or: GICombineRule <
- (defs root:$root, redundant_or_matchinfo:$matchinfo),
- (match (wip_match_opcode G_OR):$root,
- [{ return Helper.matchRedundantOr(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.replaceSingleDefInstWithReg(*${root}, ${matchinfo}); }])
->;
-
-// If the input is already sign extended, just drop the extension.
-// sext_inreg x, K ->
-// if computeNumSignBits(x) >= (x.getScalarSizeInBits() - K + 1)
-def redundant_sext_inreg: GICombineRule <
- (defs root:$root),
- (match (wip_match_opcode G_SEXT_INREG):$root,
- [{ return Helper.matchRedundantSExtInReg(*${root}); }]),
- (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
->;
-
-// Fold (anyext (trunc x)) -> x if the source type is same as
-// the destination type.
-def anyext_trunc_fold_matchinfo : GIDefMatchData<"Register">;
-def anyext_trunc_fold: GICombineRule <
- (defs root:$root, anyext_trunc_fold_matchinfo:$matchinfo),
- (match (wip_match_opcode G_ANYEXT):$root,
- [{ return Helper.matchCombineAnyExtTrunc(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.applyCombineAnyExtTrunc(*${root}, ${matchinfo}); }])
->;
-
-// Fold ([asz]ext ([asz]ext x)) -> ([asz]ext x).
-def ext_ext_fold_matchinfo : GIDefMatchData<"std::tuple<Register, unsigned>">;
-def ext_ext_fold: GICombineRule <
- (defs root:$root, ext_ext_fold_matchinfo:$matchinfo),
- (match (wip_match_opcode G_ANYEXT, G_SEXT, G_ZEXT):$root,
- [{ return Helper.matchCombineExtOfExt(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.applyCombineExtOfExt(*${root}, ${matchinfo}); }])
->;
-
-def not_cmp_fold_matchinfo : GIDefMatchData<"SmallVector<Register, 4>">;
-def not_cmp_fold : GICombineRule<
- (defs root:$d, not_cmp_fold_matchinfo:$info),
- (match (wip_match_opcode G_XOR): $d,
- [{ return Helper.matchNotCmp(*${d}, ${info}); }]),
- (apply [{ return Helper.applyNotCmp(*${d}, ${info}); }])
->;
-
-// Fold (fneg (fneg x)) -> x.
-def fneg_fneg_fold_matchinfo : GIDefMatchData<"Register">;
-def fneg_fneg_fold: GICombineRule <
- (defs root:$root, fneg_fneg_fold_matchinfo:$matchinfo),
- (match (wip_match_opcode G_FNEG):$root,
- [{ return Helper.matchCombineFNegOfFNeg(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.replaceSingleDefInstWithReg(*${root}, ${matchinfo}); }])
->;
-
-// Fold (unmerge(merge x, y, z)) -> z, y, z.
-def unmerge_merge_matchinfo : GIDefMatchData<"SmallVector<Register, 8>">;
-def unmerge_merge : GICombineRule<
- (defs root:$d, unmerge_merge_matchinfo:$info),
- (match (wip_match_opcode G_UNMERGE_VALUES): $d,
- [{ return Helper.matchCombineUnmergeMergeToPlainValues(*${d}, ${info}); }]),
- (apply [{ return Helper.applyCombineUnmergeMergeToPlainValues(*${d}, ${info}); }])
->;
-
-// Fold (fabs (fabs x)) -> (fabs x).
-def fabs_fabs_fold_matchinfo : GIDefMatchData<"Register">;
-def fabs_fabs_fold: GICombineRule<
- (defs root:$root, fabs_fabs_fold_matchinfo:$matchinfo),
- (match (wip_match_opcode G_FABS):$root,
- [{ return Helper.matchCombineFAbsOfFAbs(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.applyCombineFAbsOfFAbs(*${root}, ${matchinfo}); }])
->;
-
-// Fold (unmerge cst) -> cst1, cst2, ...
-def unmerge_cst_matchinfo : GIDefMatchData<"SmallVector<APInt, 8>">;
-def unmerge_cst : GICombineRule<
- (defs root:$d, unmerge_cst_matchinfo:$info),
- (match (wip_match_opcode G_UNMERGE_VALUES): $d,
- [{ return Helper.matchCombineUnmergeConstant(*${d}, ${info}); }]),
- (apply [{ return Helper.applyCombineUnmergeConstant(*${d}, ${info}); }])
->;
-
-// Transform x,y<dead> = unmerge z -> x = trunc z.
-def unmerge_dead_to_trunc : GICombineRule<
- (defs root:$d),
- (match (wip_match_opcode G_UNMERGE_VALUES): $d,
- [{ return Helper.matchCombineUnmergeWithDeadLanesToTrunc(*${d}); }]),
- (apply [{ return Helper.applyCombineUnmergeWithDeadLanesToTrunc(*${d}); }])
->;
-
-// Transform x,y = unmerge(zext(z)) -> x = zext z; y = 0.
-def unmerge_zext_to_zext : GICombineRule<
- (defs root:$d),
- (match (wip_match_opcode G_UNMERGE_VALUES): $d,
- [{ return Helper.matchCombineUnmergeZExtToZExt(*${d}); }]),
- (apply [{ return Helper.applyCombineUnmergeZExtToZExt(*${d}); }])
->;
-
-// Fold trunc ([asz]ext x) -> x or ([asz]ext x) or (trunc x).
-def trunc_ext_fold_matchinfo : GIDefMatchData<"std::pair<Register, unsigned>">;
-def trunc_ext_fold: GICombineRule <
- (defs root:$root, trunc_ext_fold_matchinfo:$matchinfo),
- (match (wip_match_opcode G_TRUNC):$root,
- [{ return Helper.matchCombineTruncOfExt(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.applyCombineTruncOfExt(*${root}, ${matchinfo}); }])
->;
-
-// Fold trunc (shl x, K) -> shl (trunc x), K => K < VT.getScalarSizeInBits().
-def trunc_shl_matchinfo : GIDefMatchData<"std::pair<Register, Register>">;
-def trunc_shl: GICombineRule <
- (defs root:$root, trunc_shl_matchinfo:$matchinfo),
- (match (wip_match_opcode G_TRUNC):$root,
- [{ return Helper.matchCombineTruncOfShl(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.applyCombineTruncOfShl(*${root}, ${matchinfo}); }])
->;
-
-// Transform (mul x, -1) -> (sub 0, x)
-def mul_by_neg_one: GICombineRule <
- (defs root:$root),
- (match (wip_match_opcode G_MUL):$root,
- [{ return Helper.matchConstantOp(${root}->getOperand(2), -1); }]),
- (apply [{ return Helper.applyCombineMulByNegativeOne(*${root}); }])
->;
-
-// Fold (xor (and x, y), y) -> (and (not x), y)
-def xor_of_and_with_same_reg_matchinfo :
- GIDefMatchData<"std::pair<Register, Register>">;
-def xor_of_and_with_same_reg: GICombineRule <
- (defs root:$root, xor_of_and_with_same_reg_matchinfo:$matchinfo),
- (match (wip_match_opcode G_XOR):$root,
- [{ return Helper.matchXorOfAndWithSameReg(*${root}, ${matchinfo}); }]),
- (apply [{ return Helper.applyXorOfAndWithSameReg(*${root}, ${matchinfo}); }])
->;
-
-// Transform (ptr_add 0, x) -> (int_to_ptr x)
-def ptr_add_with_zero: GICombineRule<
- (defs root:$root),
- (match (wip_match_opcode G_PTR_ADD):$root,
- [{ return Helper.matchPtrAddZero(*${root}); }]),
- (apply [{ return Helper.applyPtrAddZero(*${root}); }])>;
-
-def regs_small_vec : GIDefMatchData<"SmallVector<Register, 4>">;
-def combine_insert_vec_elts_build_vector : GICombineRule<
- (defs root:$root, regs_small_vec:$info),
- (match (wip_match_opcode G_INSERT_VECTOR_ELT):$root,
- [{ return Helper.matchCombineInsertVecElts(*${root}, ${info}); }]),
- (apply [{ return Helper.applyCombineInsertVecElts(*${root}, ${info}); }])>;
-
-def load_or_combine_matchdata :
-GIDefMatchData<"std::function<void(MachineIRBuilder &)>">;
-def load_or_combine : GICombineRule<
- (defs root:$root, load_or_combine_matchdata:$info),
- (match (wip_match_opcode G_OR):$root,
- [{ return Helper.matchLoadOrCombine(*${root}, ${info}); }]),
- (apply [{ return Helper.applyLoadOrCombine(*${root}, ${info}); }])>;
-
-// Currently only the one combine above.
-def insert_vec_elt_combines : GICombineGroup<
- [combine_insert_vec_elts_build_vector]>;
-
+// Fold fp_op(cst) to the constant result of the floating point operation.
+def constant_fp_op_matchinfo: GIDefMatchData<"Optional<APFloat>">;
+def constant_fp_op: GICombineRule <
+ (defs root:$root, constant_fp_op_matchinfo:$info),
+ (match (wip_match_opcode G_FNEG, G_FABS, G_FPTRUNC, G_FSQRT, G_FLOG2):$root,
+ [{ return Helper.matchCombineConstantFoldFpUnary(*${root}, ${info}); }]),
+ (apply [{ return Helper.applyCombineConstantFoldFpUnary(*${root}, ${info}); }])
+>;
+
+// Fold int2ptr(ptr2int(x)) -> x
+def p2i_to_i2p_matchinfo: GIDefMatchData<"Register">;
+def p2i_to_i2p: GICombineRule<
+ (defs root:$root, p2i_to_i2p_matchinfo:$info),
+ (match (wip_match_opcode G_INTTOPTR):$root,
+ [{ return Helper.matchCombineI2PToP2I(*${root}, ${info}); }]),
+ (apply [{ return Helper.applyCombineI2PToP2I(*${root}, ${info}); }])
+>;
+
+// Fold ptr2int(int2ptr(x)) -> x
+def i2p_to_p2i_matchinfo: GIDefMatchData<"Register">;
+def i2p_to_p2i: GICombineRule<
+ (defs root:$root, i2p_to_p2i_matchinfo:$info),
+ (match (wip_match_opcode G_PTRTOINT):$root,
+ [{ return Helper.matchCombineP2IToI2P(*${root}, ${info}); }]),
+ (apply [{ return Helper.applyCombineP2IToI2P(*${root}, ${info}); }])
+>;
+
+// Fold add ptrtoint(x), y -> ptrtoint (ptr_add x), y
+def add_p2i_to_ptradd_matchinfo : GIDefMatchData<"std::pair<Register, bool>">;
+def add_p2i_to_ptradd : GICombineRule<
+ (defs root:$root, add_p2i_to_ptradd_matchinfo:$info),
+ (match (wip_match_opcode G_ADD):$root,
+ [{ return Helper.matchCombineAddP2IToPtrAdd(*${root}, ${info}); }]),
+ (apply [{ return Helper.applyCombineAddP2IToPtrAdd(*${root}, ${info}); }])
+>;
+
+// Fold (ptr_add (int2ptr C1), C2) -> C1 + C2
+def const_ptradd_to_i2p_matchinfo : GIDefMatchData<"int64_t">;
+def const_ptradd_to_i2p: GICombineRule<
+ (defs root:$root, const_ptradd_to_i2p_matchinfo:$info),
+ (match (wip_match_opcode G_PTR_ADD):$root,
+ [{ return Helper.matchCombineConstPtrAddToI2P(*${root}, ${info}); }]),
+ (apply [{ return Helper.applyCombineConstPtrAddToI2P(*${root}, ${info}); }])
+>;
+
+// Simplify: (logic_op (op x...), (op y...)) -> (op (logic_op x, y))
+def hoist_logic_op_with_same_opcode_hands: GICombineRule <
+ (defs root:$root, instruction_steps_matchdata:$info),
+ (match (wip_match_opcode G_AND, G_OR, G_XOR):$root,
+ [{ return Helper.matchHoistLogicOpWithSameOpcodeHands(*${root}, ${info}); }]),
+ (apply [{ return Helper.applyBuildInstructionSteps(*${root}, ${info});}])
+>;
+
+// Fold ashr (shl x, C), C -> sext_inreg (C)
+def shl_ashr_to_sext_inreg_matchinfo : GIDefMatchData<"std::tuple<Register, int64_t>">;
+def shl_ashr_to_sext_inreg : GICombineRule<
+ (defs root:$root, shl_ashr_to_sext_inreg_matchinfo:$info),
+ (match (wip_match_opcode G_ASHR): $root,
+ [{ return Helper.matchAshrShlToSextInreg(*${root}, ${info}); }]),
+ (apply [{ return Helper.applyAshShlToSextInreg(*${root}, ${info});}])
+>;
+// Fold (x & y) -> x or (x & y) -> y when (x & y) is known to equal x or equal y.
+def redundant_and_matchinfo : GIDefMatchData<"Register">;
+def redundant_and: GICombineRule <
+ (defs root:$root, redundant_and_matchinfo:$matchinfo),
+ (match (wip_match_opcode G_AND):$root,
+ [{ return Helper.matchRedundantAnd(*${root}, ${matchinfo}); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithReg(*${root}, ${matchinfo}); }])
+>;
+
+// Fold (x | y) -> x or (x | y) -> y when (x | y) is known to equal x or equal y.
+def redundant_or_matchinfo : GIDefMatchData<"Register">;
+def redundant_or: GICombineRule <
+ (defs root:$root, redundant_or_matchinfo:$matchinfo),
+ (match (wip_match_opcode G_OR):$root,
+ [{ return Helper.matchRedundantOr(*${root}, ${matchinfo}); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithReg(*${root}, ${matchinfo}); }])
+>;
+
+// If the input is already sign extended, just drop the extension.
+// sext_inreg x, K ->
+// if computeNumSignBits(x) >= (x.getScalarSizeInBits() - K + 1)
+def redundant_sext_inreg: GICombineRule <
+ (defs root:$root),
+ (match (wip_match_opcode G_SEXT_INREG):$root,
+ [{ return Helper.matchRedundantSExtInReg(*${root}); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
+>;
+
+// Fold (anyext (trunc x)) -> x if the source type is same as
+// the destination type.
+def anyext_trunc_fold_matchinfo : GIDefMatchData<"Register">;
+def anyext_trunc_fold: GICombineRule <
+ (defs root:$root, anyext_trunc_fold_matchinfo:$matchinfo),
+ (match (wip_match_opcode G_ANYEXT):$root,
+ [{ return Helper.matchCombineAnyExtTrunc(*${root}, ${matchinfo}); }]),
+ (apply [{ return Helper.applyCombineAnyExtTrunc(*${root}, ${matchinfo}); }])
+>;
+
+// Fold ([asz]ext ([asz]ext x)) -> ([asz]ext x).
+def ext_ext_fold_matchinfo : GIDefMatchData<"std::tuple<Register, unsigned>">;
+def ext_ext_fold: GICombineRule <
+ (defs root:$root, ext_ext_fold_matchinfo:$matchinfo),
+ (match (wip_match_opcode G_ANYEXT, G_SEXT, G_ZEXT):$root,
+ [{ return Helper.matchCombineExtOfExt(*${root}, ${matchinfo}); }]),
+ (apply [{ return Helper.applyCombineExtOfExt(*${root}, ${matchinfo}); }])
+>;
+
+def not_cmp_fold_matchinfo : GIDefMatchData<"SmallVector<Register, 4>">;
+def not_cmp_fold : GICombineRule<
+ (defs root:$d, not_cmp_fold_matchinfo:$info),
+ (match (wip_match_opcode G_XOR): $d,
+ [{ return Helper.matchNotCmp(*${d}, ${info}); }]),
+ (apply [{ return Helper.applyNotCmp(*${d}, ${info}); }])
+>;
+
+// Fold (fneg (fneg x)) -> x.
+def fneg_fneg_fold_matchinfo : GIDefMatchData<"Register">;
+def fneg_fneg_fold: GICombineRule <
+ (defs root:$root, fneg_fneg_fold_matchinfo:$matchinfo),
+ (match (wip_match_opcode G_FNEG):$root,
+ [{ return Helper.matchCombineFNegOfFNeg(*${root}, ${matchinfo}); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithReg(*${root}, ${matchinfo}); }])
+>;
+
+// Fold (unmerge(merge x, y, z)) -> z, y, z.
+def unmerge_merge_matchinfo : GIDefMatchData<"SmallVector<Register, 8>">;
+def unmerge_merge : GICombineRule<
+ (defs root:$d, unmerge_merge_matchinfo:$info),
+ (match (wip_match_opcode G_UNMERGE_VALUES): $d,
+ [{ return Helper.matchCombineUnmergeMergeToPlainValues(*${d}, ${info}); }]),
+ (apply [{ return Helper.applyCombineUnmergeMergeToPlainValues(*${d}, ${info}); }])
+>;
+
+// Fold (fabs (fabs x)) -> (fabs x).
+def fabs_fabs_fold_matchinfo : GIDefMatchData<"Register">;
+def fabs_fabs_fold: GICombineRule<
+ (defs root:$root, fabs_fabs_fold_matchinfo:$matchinfo),
+ (match (wip_match_opcode G_FABS):$root,
+ [{ return Helper.matchCombineFAbsOfFAbs(*${root}, ${matchinfo}); }]),
+ (apply [{ return Helper.applyCombineFAbsOfFAbs(*${root}, ${matchinfo}); }])
+>;
+
+// Fold (unmerge cst) -> cst1, cst2, ...
+def unmerge_cst_matchinfo : GIDefMatchData<"SmallVector<APInt, 8>">;
+def unmerge_cst : GICombineRule<
+ (defs root:$d, unmerge_cst_matchinfo:$info),
+ (match (wip_match_opcode G_UNMERGE_VALUES): $d,
+ [{ return Helper.matchCombineUnmergeConstant(*${d}, ${info}); }]),
+ (apply [{ return Helper.applyCombineUnmergeConstant(*${d}, ${info}); }])
+>;
+
+// Transform x,y<dead> = unmerge z -> x = trunc z.
+def unmerge_dead_to_trunc : GICombineRule<
+ (defs root:$d),
+ (match (wip_match_opcode G_UNMERGE_VALUES): $d,
+ [{ return Helper.matchCombineUnmergeWithDeadLanesToTrunc(*${d}); }]),
+ (apply [{ return Helper.applyCombineUnmergeWithDeadLanesToTrunc(*${d}); }])
+>;
+
+// Transform x,y = unmerge(zext(z)) -> x = zext z; y = 0.
+def unmerge_zext_to_zext : GICombineRule<
+ (defs root:$d),
+ (match (wip_match_opcode G_UNMERGE_VALUES): $d,
+ [{ return Helper.matchCombineUnmergeZExtToZExt(*${d}); }]),
+ (apply [{ return Helper.applyCombineUnmergeZExtToZExt(*${d}); }])
+>;
+
+// Fold trunc ([asz]ext x) -> x or ([asz]ext x) or (trunc x).
+def trunc_ext_fold_matchinfo : GIDefMatchData<"std::pair<Register, unsigned>">;
+def trunc_ext_fold: GICombineRule <
+ (defs root:$root, trunc_ext_fold_matchinfo:$matchinfo),
+ (match (wip_match_opcode G_TRUNC):$root,
+ [{ return Helper.matchCombineTruncOfExt(*${root}, ${matchinfo}); }]),
+ (apply [{ return Helper.applyCombineTruncOfExt(*${root}, ${matchinfo}); }])
+>;
+
+// Fold trunc (shl x, K) -> shl (trunc x), K => K < VT.getScalarSizeInBits().
+def trunc_shl_matchinfo : GIDefMatchData<"std::pair<Register, Register>">;
+def trunc_shl: GICombineRule <
+ (defs root:$root, trunc_shl_matchinfo:$matchinfo),
+ (match (wip_match_opcode G_TRUNC):$root,
+ [{ return Helper.matchCombineTruncOfShl(*${root}, ${matchinfo}); }]),
+ (apply [{ return Helper.applyCombineTruncOfShl(*${root}, ${matchinfo}); }])
+>;
+
+// Transform (mul x, -1) -> (sub 0, x)
+def mul_by_neg_one: GICombineRule <
+ (defs root:$root),
+ (match (wip_match_opcode G_MUL):$root,
+ [{ return Helper.matchConstantOp(${root}->getOperand(2), -1); }]),
+ (apply [{ return Helper.applyCombineMulByNegativeOne(*${root}); }])
+>;
+
+// Fold (xor (and x, y), y) -> (and (not x), y)
+def xor_of_and_with_same_reg_matchinfo :
+ GIDefMatchData<"std::pair<Register, Register>">;
+def xor_of_and_with_same_reg: GICombineRule <
+ (defs root:$root, xor_of_and_with_same_reg_matchinfo:$matchinfo),
+ (match (wip_match_opcode G_XOR):$root,
+ [{ return Helper.matchXorOfAndWithSameReg(*${root}, ${matchinfo}); }]),
+ (apply [{ return Helper.applyXorOfAndWithSameReg(*${root}, ${matchinfo}); }])
+>;
+
+// Transform (ptr_add 0, x) -> (int_to_ptr x)
+def ptr_add_with_zero: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_PTR_ADD):$root,
+ [{ return Helper.matchPtrAddZero(*${root}); }]),
+ (apply [{ return Helper.applyPtrAddZero(*${root}); }])>;
+
+def regs_small_vec : GIDefMatchData<"SmallVector<Register, 4>">;
+def combine_insert_vec_elts_build_vector : GICombineRule<
+ (defs root:$root, regs_small_vec:$info),
+ (match (wip_match_opcode G_INSERT_VECTOR_ELT):$root,
+ [{ return Helper.matchCombineInsertVecElts(*${root}, ${info}); }]),
+ (apply [{ return Helper.applyCombineInsertVecElts(*${root}, ${info}); }])>;
+
+def load_or_combine_matchdata :
+GIDefMatchData<"std::function<void(MachineIRBuilder &)>">;
+def load_or_combine : GICombineRule<
+ (defs root:$root, load_or_combine_matchdata:$info),
+ (match (wip_match_opcode G_OR):$root,
+ [{ return Helper.matchLoadOrCombine(*${root}, ${info}); }]),
+ (apply [{ return Helper.applyLoadOrCombine(*${root}, ${info}); }])>;
+
+// Currently only the one combine above.
+def insert_vec_elt_combines : GICombineGroup<
+ [combine_insert_vec_elts_build_vector]>;
+
// FIXME: These should use the custom predicate feature once it lands.
def undef_combines : GICombineGroup<[undef_to_fp_zero, undef_to_int_zero,
undef_to_negative_one,
- binop_left_undef_to_zero,
+ binop_left_undef_to_zero,
propagate_undef_any_op,
propagate_undef_all_ops,
propagate_undef_shuffle_mask,
@@ -568,31 +568,31 @@ def undef_combines : GICombineGroup<[undef_to_fp_zero, undef_to_int_zero,
def identity_combines : GICombineGroup<[select_same_val, right_identity_zero,
binop_same_val, binop_left_to_zero,
- binop_right_to_zero, p2i_to_i2p,
- i2p_to_p2i, anyext_trunc_fold,
- fneg_fneg_fold, right_identity_one]>;
-
-def const_combines : GICombineGroup<[constant_fp_op, const_ptradd_to_i2p]>;
-
-def known_bits_simplifications : GICombineGroup<[
- redundant_and, redundant_sext_inreg, redundant_or, urem_pow2_to_mask]>;
-
-def width_reduction_combines : GICombineGroup<[reduce_shl_of_extend]>;
-
-def select_combines : GICombineGroup<[select_undef_cmp, select_constant_cmp]>;
-
-def trivial_combines : GICombineGroup<[copy_prop, mul_to_shl, add_p2i_to_ptradd,
- mul_by_neg_one]>;
-
-def all_combines : GICombineGroup<[trivial_combines, insert_vec_elt_combines,
- ptr_add_immed_chain, combines_for_extload, combine_indexed_load_store,
- undef_combines, identity_combines, simplify_add_to_sub,
- hoist_logic_op_with_same_opcode_hands,
- shl_ashr_to_sext_inreg, sext_inreg_of_load,
- width_reduction_combines, select_combines,
- known_bits_simplifications, ext_ext_fold,
- not_cmp_fold, opt_brcond_by_inverting_cond,
- unmerge_merge, fabs_fabs_fold, unmerge_cst, unmerge_dead_to_trunc,
- unmerge_zext_to_zext, trunc_ext_fold, trunc_shl,
- const_combines, xor_of_and_with_same_reg, ptr_add_with_zero,
- shift_immed_chain, shift_of_shifted_logic_chain, load_or_combine]>;
+ binop_right_to_zero, p2i_to_i2p,
+ i2p_to_p2i, anyext_trunc_fold,
+ fneg_fneg_fold, right_identity_one]>;
+
+def const_combines : GICombineGroup<[constant_fp_op, const_ptradd_to_i2p]>;
+
+def known_bits_simplifications : GICombineGroup<[
+ redundant_and, redundant_sext_inreg, redundant_or, urem_pow2_to_mask]>;
+
+def width_reduction_combines : GICombineGroup<[reduce_shl_of_extend]>;
+
+def select_combines : GICombineGroup<[select_undef_cmp, select_constant_cmp]>;
+
+def trivial_combines : GICombineGroup<[copy_prop, mul_to_shl, add_p2i_to_ptradd,
+ mul_by_neg_one]>;
+
+def all_combines : GICombineGroup<[trivial_combines, insert_vec_elt_combines,
+ ptr_add_immed_chain, combines_for_extload, combine_indexed_load_store,
+ undef_combines, identity_combines, simplify_add_to_sub,
+ hoist_logic_op_with_same_opcode_hands,
+ shl_ashr_to_sext_inreg, sext_inreg_of_load,
+ width_reduction_combines, select_combines,
+ known_bits_simplifications, ext_ext_fold,
+ not_cmp_fold, opt_brcond_by_inverting_cond,
+ unmerge_merge, fabs_fabs_fold, unmerge_cst, unmerge_dead_to_trunc,
+ unmerge_zext_to_zext, trunc_ext_fold, trunc_shl,
+ const_combines, xor_of_and_with_same_reg, ptr_add_with_zero,
+ shift_immed_chain, shift_of_shifted_logic_chain, load_or_combine]>;
diff --git a/contrib/libs/llvm12/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/contrib/libs/llvm12/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
index 4520354169..6fb8a6b15d 100644
--- a/contrib/libs/llvm12/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
+++ b/contrib/libs/llvm12/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
@@ -26,8 +26,8 @@ class GINodeEquiv<Instruction i, SDNode node> {
// SelectionDAG has separate nodes for atomic and non-atomic memory operations
// (ISD::LOAD, ISD::ATOMIC_LOAD, ISD::STORE, ISD::ATOMIC_STORE) but GlobalISel
// stores this information in the MachineMemoryOperand.
- bit CheckMMOIsNonAtomic = false;
- bit CheckMMOIsAtomic = false;
+ bit CheckMMOIsNonAtomic = false;
+ bit CheckMMOIsAtomic = false;
// SelectionDAG has one node for all loads and uses predicates to
// differentiate them. GlobalISel on the other hand uses separate opcodes.
@@ -52,8 +52,8 @@ def : GINodeEquiv<G_BITCAST, bitconvert>;
def : GINodeEquiv<G_CONSTANT, imm>;
def : GINodeEquiv<G_FCONSTANT, fpimm>;
def : GINodeEquiv<G_IMPLICIT_DEF, undef>;
-def : GINodeEquiv<G_FRAME_INDEX, frameindex>;
-def : GINodeEquiv<G_BLOCK_ADDR, blockaddress>;
+def : GINodeEquiv<G_FRAME_INDEX, frameindex>;
+def : GINodeEquiv<G_BLOCK_ADDR, blockaddress>;
def : GINodeEquiv<G_ADD, add>;
def : GINodeEquiv<G_SUB, sub>;
def : GINodeEquiv<G_MUL, mul>;
@@ -73,16 +73,16 @@ def : GINodeEquiv<G_SADDSAT, saddsat>;
def : GINodeEquiv<G_UADDSAT, uaddsat>;
def : GINodeEquiv<G_SSUBSAT, ssubsat>;
def : GINodeEquiv<G_USUBSAT, usubsat>;
-def : GINodeEquiv<G_SSHLSAT, sshlsat>;
-def : GINodeEquiv<G_USHLSAT, ushlsat>;
-def : GINodeEquiv<G_SMULFIX, smulfix>;
-def : GINodeEquiv<G_UMULFIX, umulfix>;
-def : GINodeEquiv<G_SMULFIXSAT, smulfixsat>;
-def : GINodeEquiv<G_UMULFIXSAT, umulfixsat>;
-def : GINodeEquiv<G_SDIVFIX, sdivfix>;
-def : GINodeEquiv<G_UDIVFIX, udivfix>;
-def : GINodeEquiv<G_SDIVFIXSAT, sdivfixsat>;
-def : GINodeEquiv<G_UDIVFIXSAT, udivfixsat>;
+def : GINodeEquiv<G_SSHLSAT, sshlsat>;
+def : GINodeEquiv<G_USHLSAT, ushlsat>;
+def : GINodeEquiv<G_SMULFIX, smulfix>;
+def : GINodeEquiv<G_UMULFIX, umulfix>;
+def : GINodeEquiv<G_SMULFIXSAT, smulfixsat>;
+def : GINodeEquiv<G_UMULFIXSAT, umulfixsat>;
+def : GINodeEquiv<G_SDIVFIX, sdivfix>;
+def : GINodeEquiv<G_UDIVFIX, udivfix>;
+def : GINodeEquiv<G_SDIVFIXSAT, sdivfixsat>;
+def : GINodeEquiv<G_UDIVFIXSAT, udivfixsat>;
def : GINodeEquiv<G_SELECT, select>;
def : GINodeEquiv<G_FNEG, fneg>;
def : GINodeEquiv<G_FPEXT, fpextend>;
@@ -116,7 +116,7 @@ def : GINodeEquiv<G_CTTZ, cttz>;
def : GINodeEquiv<G_CTLZ_ZERO_UNDEF, ctlz_zero_undef>;
def : GINodeEquiv<G_CTTZ_ZERO_UNDEF, cttz_zero_undef>;
def : GINodeEquiv<G_CTPOP, ctpop>;
-def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, extractelt>;
+def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, extractelt>;
def : GINodeEquiv<G_CONCAT_VECTORS, concat_vectors>;
def : GINodeEquiv<G_BUILD_VECTOR, build_vector>;
def : GINodeEquiv<G_FCEIL, fceil>;
@@ -129,13 +129,13 @@ def : GINodeEquiv<G_FRINT, frint>;
def : GINodeEquiv<G_FNEARBYINT, fnearbyint>;
def : GINodeEquiv<G_INTRINSIC_TRUNC, ftrunc>;
def : GINodeEquiv<G_INTRINSIC_ROUND, fround>;
-def : GINodeEquiv<G_INTRINSIC_LRINT, lrint>;
+def : GINodeEquiv<G_INTRINSIC_LRINT, lrint>;
def : GINodeEquiv<G_FCOPYSIGN, fcopysign>;
def : GINodeEquiv<G_SMIN, smin>;
def : GINodeEquiv<G_SMAX, smax>;
def : GINodeEquiv<G_UMIN, umin>;
def : GINodeEquiv<G_UMAX, umax>;
-def : GINodeEquiv<G_ABS, abs>;
+def : GINodeEquiv<G_ABS, abs>;
def : GINodeEquiv<G_FMINNUM, fminnum>;
def : GINodeEquiv<G_FMAXNUM, fmaxnum>;
def : GINodeEquiv<G_FMINNUM_IEEE, fminnum_ieee>;
@@ -158,7 +158,7 @@ def : GINodeEquiv<G_STRICT_FSQRT, strict_fsqrt>;
// separate nodes for them. This GINodeEquiv maps the non-atomic loads to
// G_LOAD with a non-atomic MachineMemOperand.
def : GINodeEquiv<G_LOAD, ld> {
- let CheckMMOIsNonAtomic = true;
+ let CheckMMOIsNonAtomic = true;
let IfSignExtend = G_SEXTLOAD;
let IfZeroExtend = G_ZEXTLOAD;
}
@@ -174,19 +174,19 @@ def : GINodeEquiv<G_ICMP, setcc> {
// G_STORE handles both atomic and non-atomic stores where as SelectionDAG had
// separate nodes for them. This GINodeEquiv maps the non-atomic stores to
// G_STORE with a non-atomic MachineMemOperand.
-def : GINodeEquiv<G_STORE, st> { let CheckMMOIsNonAtomic = true; }
+def : GINodeEquiv<G_STORE, st> { let CheckMMOIsNonAtomic = true; }
def : GINodeEquiv<G_LOAD, atomic_load> {
- let CheckMMOIsNonAtomic = false;
- let CheckMMOIsAtomic = true;
+ let CheckMMOIsNonAtomic = false;
+ let CheckMMOIsAtomic = true;
+}
+
+// Operands are swapped for atomic_store vs. regular store
+def : GINodeEquiv<G_STORE, atomic_store> {
+ let CheckMMOIsNonAtomic = false;
+ let CheckMMOIsAtomic = true;
}
-// Operands are swapped for atomic_store vs. regular store
-def : GINodeEquiv<G_STORE, atomic_store> {
- let CheckMMOIsNonAtomic = false;
- let CheckMMOIsAtomic = true;
-}
-
def : GINodeEquiv<G_ATOMIC_CMPXCHG, atomic_cmp_swap>;
def : GINodeEquiv<G_ATOMICRMW_XCHG, atomic_swap>;
def : GINodeEquiv<G_ATOMICRMW_ADD, atomic_load_add>;
diff --git a/contrib/libs/llvm12/include/llvm/Target/Target.td b/contrib/libs/llvm12/include/llvm/Target/Target.td
index 0261df6fb2..1c97d70a47 100644
--- a/contrib/libs/llvm12/include/llvm/Target/Target.td
+++ b/contrib/libs/llvm12/include/llvm/Target/Target.td
@@ -110,9 +110,9 @@ class SubRegIndex<int size, int offset = 0> {
// ComposedSubRegIndex - A sub-register that is the result of composing A and B.
// Offset is set to the sum of A and B's Offsets. Size is set to B's Size.
class ComposedSubRegIndex<SubRegIndex A, SubRegIndex B>
- : SubRegIndex<B.Size, !cond(!eq(A.Offset, -1): -1,
- !eq(B.Offset, -1): -1,
- true: !add(A.Offset, B.Offset))> {
+ : SubRegIndex<B.Size, !cond(!eq(A.Offset, -1): -1,
+ !eq(B.Offset, -1): -1,
+ true: !add(A.Offset, B.Offset))> {
// See SubRegIndex.
let ComposedOf = [A, B];
}
@@ -175,12 +175,12 @@ class Register<string n, list<string> altNames = []> {
// completely determined by the value of its sub-registers. For example, the
// x86 register AX is covered by its sub-registers AL and AH, but EAX is not
// covered by its sub-register AX.
- bit CoveredBySubRegs = false;
+ bit CoveredBySubRegs = false;
// HWEncoding - The target specific hardware encoding for this register.
bits<16> HWEncoding = 0;
- bit isArtificial = false;
+ bit isArtificial = false;
}
// RegisterWithSubRegs - This can be used to define instances of Register which
@@ -252,7 +252,7 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
// isAllocatable - Specify that the register class can be used for virtual
// registers and register allocation. Some register classes are only used to
// model instruction operand constraints, and should have isAllocatable = 0.
- bit isAllocatable = true;
+ bit isAllocatable = true;
// AltOrders - List of alternative allocation orders. The default order is
// MemberList itself, and that is good enough for most targets since the
@@ -278,7 +278,7 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
// Generate register pressure set for this register class and any class
// synthesized from it. Set to 0 to inhibit unneeded pressure sets.
- bit GeneratePressureSet = true;
+ bit GeneratePressureSet = true;
// Weight override for register pressure calculation. This is the value
// TargetRegisterClass::getRegClassWeight() will return. The weight is in
@@ -452,7 +452,7 @@ class InstructionEncoding {
// DecodeInstB() is not able to determine if all possible values of ?? are
// valid or not. If DecodeInstB() returns Fail the decoder will attempt to
// decode the bitpattern as InstA too.
- bit hasCompleteDecoder = true;
+ bit hasCompleteDecoder = true;
}
// Allows specifying an InstructionEncoding by HwMode. If an Instruction specifies
@@ -506,59 +506,59 @@ class Instruction : InstructionEncoding {
// Indicates if this is a pre-isel opcode that should be
// legalized/regbankselected/selected.
- bit isPreISelOpcode = false;
+ bit isPreISelOpcode = false;
// These bits capture information about the high-level semantics of the
// instruction.
- bit isReturn = false; // Is this instruction a return instruction?
- bit isBranch = false; // Is this instruction a branch instruction?
- bit isEHScopeReturn = false; // Does this instruction end an EH scope?
- bit isIndirectBranch = false; // Is this instruction an indirect branch?
- bit isCompare = false; // Is this instruction a comparison instruction?
- bit isMoveImm = false; // Is this instruction a move immediate instruction?
- bit isMoveReg = false; // Is this instruction a move register instruction?
- bit isBitcast = false; // Is this instruction a bitcast instruction?
- bit isSelect = false; // Is this instruction a select instruction?
- bit isBarrier = false; // Can control flow fall through this instruction?
- bit isCall = false; // Is this instruction a call instruction?
- bit isAdd = false; // Is this instruction an add instruction?
- bit isTrap = false; // Is this instruction a trap instruction?
- bit canFoldAsLoad = false; // Can this be folded as a simple memory operand?
- bit mayLoad = ?; // Is it possible for this inst to read memory?
- bit mayStore = ?; // Is it possible for this inst to write memory?
- bit mayRaiseFPException = false; // Can this raise a floating-point exception?
- bit isConvertibleToThreeAddress = false; // Can this 2-addr instruction promote?
- bit isCommutable = false; // Is this 3 operand instruction commutable?
- bit isTerminator = false; // Is this part of the terminator for a basic block?
- bit isReMaterializable = false; // Is this instruction re-materializable?
- bit isPredicable = false; // 1 means this instruction is predicable
- // even if it does not have any operand
- // tablegen can identify as a predicate
- bit isUnpredicable = false; // 1 means this instruction is not predicable
- // even if it _does_ have a predicate operand
- bit hasDelaySlot = false; // Does this instruction have an delay slot?
- bit usesCustomInserter = false; // Pseudo instr needing special help.
- bit hasPostISelHook = false; // To be *adjusted* after isel by target hook.
- bit hasCtrlDep = false; // Does this instruction r/w ctrl-flow chains?
- bit isNotDuplicable = false; // Is it unsafe to duplicate this instruction?
- bit isConvergent = false; // Is this instruction convergent?
- bit isAuthenticated = false; // Does this instruction authenticate a pointer?
- bit isAsCheapAsAMove = false; // As cheap (or cheaper) than a move instruction.
- bit hasExtraSrcRegAllocReq = false; // Sources have special regalloc requirement?
- bit hasExtraDefRegAllocReq = false; // Defs have special regalloc requirement?
- bit isRegSequence = false; // Is this instruction a kind of reg sequence?
- // If so, make sure to override
- // TargetInstrInfo::getRegSequenceLikeInputs.
- bit isPseudo = false; // Is this instruction a pseudo-instruction?
- // If so, won't have encoding information for
- // the [MC]CodeEmitter stuff.
- bit isExtractSubreg = false; // Is this instruction a kind of extract subreg?
- // If so, make sure to override
- // TargetInstrInfo::getExtractSubregLikeInputs.
- bit isInsertSubreg = false; // Is this instruction a kind of insert subreg?
- // If so, make sure to override
- // TargetInstrInfo::getInsertSubregLikeInputs.
- bit variadicOpsAreDefs = false; // Are variadic operands definitions?
+ bit isReturn = false; // Is this instruction a return instruction?
+ bit isBranch = false; // Is this instruction a branch instruction?
+ bit isEHScopeReturn = false; // Does this instruction end an EH scope?
+ bit isIndirectBranch = false; // Is this instruction an indirect branch?
+ bit isCompare = false; // Is this instruction a comparison instruction?
+ bit isMoveImm = false; // Is this instruction a move immediate instruction?
+ bit isMoveReg = false; // Is this instruction a move register instruction?
+ bit isBitcast = false; // Is this instruction a bitcast instruction?
+ bit isSelect = false; // Is this instruction a select instruction?
+ bit isBarrier = false; // Can control flow fall through this instruction?
+ bit isCall = false; // Is this instruction a call instruction?
+ bit isAdd = false; // Is this instruction an add instruction?
+ bit isTrap = false; // Is this instruction a trap instruction?
+ bit canFoldAsLoad = false; // Can this be folded as a simple memory operand?
+ bit mayLoad = ?; // Is it possible for this inst to read memory?
+ bit mayStore = ?; // Is it possible for this inst to write memory?
+ bit mayRaiseFPException = false; // Can this raise a floating-point exception?
+ bit isConvertibleToThreeAddress = false; // Can this 2-addr instruction promote?
+ bit isCommutable = false; // Is this 3 operand instruction commutable?
+ bit isTerminator = false; // Is this part of the terminator for a basic block?
+ bit isReMaterializable = false; // Is this instruction re-materializable?
+ bit isPredicable = false; // 1 means this instruction is predicable
+ // even if it does not have any operand
+ // tablegen can identify as a predicate
+ bit isUnpredicable = false; // 1 means this instruction is not predicable
+ // even if it _does_ have a predicate operand
+ bit hasDelaySlot = false; // Does this instruction have an delay slot?
+ bit usesCustomInserter = false; // Pseudo instr needing special help.
+ bit hasPostISelHook = false; // To be *adjusted* after isel by target hook.
+ bit hasCtrlDep = false; // Does this instruction r/w ctrl-flow chains?
+ bit isNotDuplicable = false; // Is it unsafe to duplicate this instruction?
+ bit isConvergent = false; // Is this instruction convergent?
+ bit isAuthenticated = false; // Does this instruction authenticate a pointer?
+ bit isAsCheapAsAMove = false; // As cheap (or cheaper) than a move instruction.
+ bit hasExtraSrcRegAllocReq = false; // Sources have special regalloc requirement?
+ bit hasExtraDefRegAllocReq = false; // Defs have special regalloc requirement?
+ bit isRegSequence = false; // Is this instruction a kind of reg sequence?
+ // If so, make sure to override
+ // TargetInstrInfo::getRegSequenceLikeInputs.
+ bit isPseudo = false; // Is this instruction a pseudo-instruction?
+ // If so, won't have encoding information for
+ // the [MC]CodeEmitter stuff.
+ bit isExtractSubreg = false; // Is this instruction a kind of extract subreg?
+ // If so, make sure to override
+ // TargetInstrInfo::getExtractSubregLikeInputs.
+ bit isInsertSubreg = false; // Is this instruction a kind of insert subreg?
+ // If so, make sure to override
+ // TargetInstrInfo::getInsertSubregLikeInputs.
+ bit variadicOpsAreDefs = false; // Are variadic operands definitions?
// Does the instruction have side effects that are not captured by any
// operands of the instruction or other flags?
@@ -581,15 +581,15 @@ class Instruction : InstructionEncoding {
// CodeEmitter unchanged, but duplicates a canonical instruction
// definition's encoding and should be ignored when constructing the
// assembler match tables.
- bit isCodeGenOnly = false;
+ bit isCodeGenOnly = false;
// Is this instruction a pseudo instruction for use by the assembler parser.
- bit isAsmParserOnly = false;
+ bit isAsmParserOnly = false;
// This instruction is not expected to be queried for scheduling latencies
// and therefore needs no scheduling information even for a complete
// scheduling model.
- bit hasNoSchedulingInfo = false;
+ bit hasNoSchedulingInfo = false;
InstrItinClass Itinerary = NoItinerary;// Execution steps used for scheduling.
@@ -630,13 +630,13 @@ class Instruction : InstructionEncoding {
/// UseNamedOperandTable - If set, the operand indices of this instruction
/// can be queried via the getNamedOperandIdx() function which is generated
/// by TableGen.
- bit UseNamedOperandTable = false;
+ bit UseNamedOperandTable = false;
/// Should FastISel ignore this instruction. For certain ISAs, they have
/// instructions which map to the same ISD Opcode, value type operands and
/// instruction selection predicates. FastISel cannot handle such cases, but
/// SelectionDAG can.
- bit FastISelShouldIgnore = false;
+ bit FastISelShouldIgnore = false;
}
/// Defines an additional encoding that disassembles to the given instruction
@@ -651,7 +651,7 @@ class AdditionalEncoding<Instruction I> : InstructionEncoding {
/// pseudo.
class PseudoInstExpansion<dag Result> {
dag ResultInst = Result; // The instruction to generate.
- bit isPseudo = true;
+ bit isPseudo = true;
}
/// Predicates - These are extra conditionals which are turned into instruction
@@ -662,7 +662,7 @@ class Predicate<string cond> {
/// AssemblerMatcherPredicate - If this feature can be used by the assembler
/// matcher, this is true. Targets should set this by inheriting their
/// feature from the AssemblerPredicate class in addition to Predicate.
- bit AssemblerMatcherPredicate = false;
+ bit AssemblerMatcherPredicate = false;
/// AssemblerCondDag - Set of subtarget features being tested used
/// as alternative condition string used for assembler matcher. Must be used
@@ -688,7 +688,7 @@ class Predicate<string cond> {
/// every function change. Most predicates can leave this at '0'.
///
/// Ignored by SelectionDAG, it always recomputes the predicate on every use.
- bit RecomputePerFunction = false;
+ bit RecomputePerFunction = false;
}
/// NoHonorSignDependentRounding - This predicate is true if support for
@@ -788,7 +788,7 @@ class AsmOperandClass {
/// marked as IsOptional.
///
/// Optional arguments must be at the end of the operand list.
- bit IsOptional = false;
+ bit IsOptional = false;
/// The name of the method on the target specific asm parser that returns the
/// default operand for this optional operand. This method is only used if
@@ -809,7 +809,7 @@ class Operand<ValueType ty> : DAGOperand {
ValueType Type = ty;
string PrintMethod = "printOperand";
string EncoderMethod = "";
- bit hasCompleteDecoder = true;
+ bit hasCompleteDecoder = true;
string OperandType = "OPERAND_UNKNOWN";
dag MIOperandInfo = (ops);
@@ -877,8 +877,8 @@ def f64imm : Operand<f64>;
// have the same LLT).
class TypedOperand<string Ty> : Operand<untyped> {
let OperandType = Ty;
- bit IsPointer = false;
- bit IsImmediate = false;
+ bit IsPointer = false;
+ bit IsImmediate = false;
}
def type0 : TypedOperand<"OPERAND_GENERIC_0">;
@@ -888,7 +888,7 @@ def type3 : TypedOperand<"OPERAND_GENERIC_3">;
def type4 : TypedOperand<"OPERAND_GENERIC_4">;
def type5 : TypedOperand<"OPERAND_GENERIC_5">;
-let IsPointer = true in {
+let IsPointer = true in {
def ptype0 : TypedOperand<"OPERAND_GENERIC_0">;
def ptype1 : TypedOperand<"OPERAND_GENERIC_1">;
def ptype2 : TypedOperand<"OPERAND_GENERIC_2">;
@@ -900,7 +900,7 @@ let IsPointer = true in {
// untyped_imm is for operands where isImm() will be true. It currently has no
// special behaviour and is only used for clarity.
def untyped_imm_0 : TypedOperand<"OPERAND_GENERIC_IMM_0"> {
- let IsImmediate = true;
+ let IsImmediate = true;
}
/// zero_reg definition - Special node to stand for the zero register.
@@ -952,7 +952,7 @@ class InstrInfo {
// For instance, while both Sparc and PowerPC are big-endian platforms, the
// Sparc manual specifies its instructions in the format [31..0] (big), while
// PowerPC specifies them using the format [0..31] (little).
- bit isLittleEndianEncoding = false;
+ bit isLittleEndianEncoding = false;
// The instruction properties mayLoad, mayStore, and hasSideEffects are unset
// by default, and TableGen will infer their value from the instruction
@@ -963,7 +963,7 @@ class InstrInfo {
// is set, it will guess a safe value instead.
//
// This option is a temporary migration help. It will go away.
- bit guessInstructionProperties = true;
+ bit guessInstructionProperties = true;
// TableGen's instruction encoder generator has support for matching operands
// to bit-field variables both by name and by position. While matching by
@@ -975,7 +975,7 @@ class InstrInfo {
// This option is temporary; it will go away once the TableGen decoder
// generator has better support for complex operands and targets have
// migrated away from using positionally encoded operands.
- bit decodePositionallyEncodedOperands = false;
+ bit decodePositionallyEncodedOperands = false;
// When set, this indicates that there will be no overlap between those
// operands that are matched by ordering (positional operands) and those
@@ -984,7 +984,7 @@ class InstrInfo {
// This option is temporary; it will go away once the TableGen decoder
// generator has better support for complex operands and targets have
// migrated away from using positionally encoded operands.
- bit noNamedPositionallyEncodedOperands = false;
+ bit noNamedPositionallyEncodedOperands = false;
}
// Standard Pseudo Instructions.
@@ -994,31 +994,31 @@ class InstrInfo {
// targets that set guessInstructionProperties=0. Any local definition of
// mayLoad/mayStore takes precedence over these default values.
class StandardPseudoInstruction : Instruction {
- let mayLoad = false;
- let mayStore = false;
- let isCodeGenOnly = true;
- let isPseudo = true;
- let hasNoSchedulingInfo = true;
+ let mayLoad = false;
+ let mayStore = false;
+ let isCodeGenOnly = true;
+ let isPseudo = true;
+ let hasNoSchedulingInfo = true;
let Namespace = "TargetOpcode";
}
def PHI : StandardPseudoInstruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins variable_ops);
let AsmString = "PHINODE";
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def INLINEASM : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "";
- let hasSideEffects = false; // Note side effect is encoded in an operand.
+ let hasSideEffects = false; // Note side effect is encoded in an operand.
}
def INLINEASM_BR : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "";
// Unlike INLINEASM, this is always treated as having side-effects.
- let hasSideEffects = true;
+ let hasSideEffects = true;
// Despite potentially branching, this instruction is intentionally _not_
// marked as a terminator or a branch.
}
@@ -1026,177 +1026,177 @@ def CFI_INSTRUCTION : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins i32imm:$id);
let AsmString = "";
- let hasCtrlDep = true;
- let hasSideEffects = false;
- let isNotDuplicable = true;
+ let hasCtrlDep = true;
+ let hasSideEffects = false;
+ let isNotDuplicable = true;
}
def EH_LABEL : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins i32imm:$id);
let AsmString = "";
- let hasCtrlDep = true;
- let hasSideEffects = false;
- let isNotDuplicable = true;
+ let hasCtrlDep = true;
+ let hasSideEffects = false;
+ let isNotDuplicable = true;
}
def GC_LABEL : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins i32imm:$id);
let AsmString = "";
- let hasCtrlDep = true;
- let hasSideEffects = false;
- let isNotDuplicable = true;
+ let hasCtrlDep = true;
+ let hasSideEffects = false;
+ let isNotDuplicable = true;
}
def ANNOTATION_LABEL : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins i32imm:$id);
let AsmString = "";
- let hasCtrlDep = true;
- let hasSideEffects = false;
- let isNotDuplicable = true;
+ let hasCtrlDep = true;
+ let hasSideEffects = false;
+ let isNotDuplicable = true;
}
def KILL : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "";
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def EXTRACT_SUBREG : StandardPseudoInstruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$supersrc, i32imm:$subidx);
let AsmString = "";
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def INSERT_SUBREG : StandardPseudoInstruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$supersrc, unknown:$subsrc, i32imm:$subidx);
let AsmString = "";
- let hasSideEffects = false;
+ let hasSideEffects = false;
let Constraints = "$supersrc = $dst";
}
def IMPLICIT_DEF : StandardPseudoInstruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins);
let AsmString = "";
- let hasSideEffects = false;
- let isReMaterializable = true;
- let isAsCheapAsAMove = true;
+ let hasSideEffects = false;
+ let isReMaterializable = true;
+ let isAsCheapAsAMove = true;
}
def SUBREG_TO_REG : StandardPseudoInstruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$implsrc, unknown:$subsrc, i32imm:$subidx);
let AsmString = "";
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def COPY_TO_REGCLASS : StandardPseudoInstruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$src, i32imm:$regclass);
let AsmString = "";
- let hasSideEffects = false;
- let isAsCheapAsAMove = true;
+ let hasSideEffects = false;
+ let isAsCheapAsAMove = true;
}
def DBG_VALUE : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "DBG_VALUE";
- let hasSideEffects = false;
-}
-def DBG_INSTR_REF : StandardPseudoInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins variable_ops);
- let AsmString = "DBG_INSTR_REF";
- let hasSideEffects = false;
-}
+ let hasSideEffects = false;
+}
+def DBG_INSTR_REF : StandardPseudoInstruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins variable_ops);
+ let AsmString = "DBG_INSTR_REF";
+ let hasSideEffects = false;
+}
def DBG_LABEL : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins unknown:$label);
let AsmString = "DBG_LABEL";
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def REG_SEQUENCE : StandardPseudoInstruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$supersrc, variable_ops);
let AsmString = "";
- let hasSideEffects = false;
- let isAsCheapAsAMove = true;
+ let hasSideEffects = false;
+ let isAsCheapAsAMove = true;
}
def COPY : StandardPseudoInstruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$src);
let AsmString = "";
- let hasSideEffects = false;
- let isAsCheapAsAMove = true;
- let hasNoSchedulingInfo = false;
+ let hasSideEffects = false;
+ let isAsCheapAsAMove = true;
+ let hasNoSchedulingInfo = false;
}
def BUNDLE : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "BUNDLE";
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def LIFETIME_START : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins i32imm:$id);
let AsmString = "LIFETIME_START";
- let hasSideEffects = false;
+ let hasSideEffects = false;
}
def LIFETIME_END : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins i32imm:$id);
let AsmString = "LIFETIME_END";
- let hasSideEffects = false;
-}
-def PSEUDO_PROBE : StandardPseudoInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins i64imm:$guid, i64imm:$index, i8imm:$type, i32imm:$attr);
- let AsmString = "PSEUDO_PROBE";
- let hasSideEffects = 1;
-}
-
+ let hasSideEffects = false;
+}
+def PSEUDO_PROBE : StandardPseudoInstruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins i64imm:$guid, i64imm:$index, i8imm:$type, i32imm:$attr);
+ let AsmString = "PSEUDO_PROBE";
+ let hasSideEffects = 1;
+}
+
def STACKMAP : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins i64imm:$id, i32imm:$nbytes, variable_ops);
- let hasSideEffects = true;
- let isCall = true;
- let mayLoad = true;
- let usesCustomInserter = true;
+ let hasSideEffects = true;
+ let isCall = true;
+ let mayLoad = true;
+ let usesCustomInserter = true;
}
def PATCHPOINT : StandardPseudoInstruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins i64imm:$id, i32imm:$nbytes, unknown:$callee,
i32imm:$nargs, i32imm:$cc, variable_ops);
- let hasSideEffects = true;
- let isCall = true;
- let mayLoad = true;
- let usesCustomInserter = true;
+ let hasSideEffects = true;
+ let isCall = true;
+ let mayLoad = true;
+ let usesCustomInserter = true;
}
def STATEPOINT : StandardPseudoInstruction {
- let OutOperandList = (outs variable_ops);
+ let OutOperandList = (outs variable_ops);
let InOperandList = (ins variable_ops);
- let usesCustomInserter = true;
- let mayLoad = true;
- let mayStore = true;
- let hasSideEffects = true;
- let isCall = true;
+ let usesCustomInserter = true;
+ let mayLoad = true;
+ let mayStore = true;
+ let hasSideEffects = true;
+ let isCall = true;
}
def LOAD_STACK_GUARD : StandardPseudoInstruction {
let OutOperandList = (outs ptr_rc:$dst);
let InOperandList = (ins);
- let mayLoad = true;
- bit isReMaterializable = true;
- let hasSideEffects = false;
- bit isPseudo = true;
+ let mayLoad = true;
+ bit isReMaterializable = true;
+ let hasSideEffects = false;
+ bit isPseudo = true;
}
def PREALLOCATED_SETUP : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins i32imm:$a);
- let usesCustomInserter = true;
- let hasSideEffects = true;
+ let usesCustomInserter = true;
+ let hasSideEffects = true;
}
def PREALLOCATED_ARG : StandardPseudoInstruction {
let OutOperandList = (outs ptr_rc:$loc);
let InOperandList = (ins i32imm:$a, i32imm:$b);
- let usesCustomInserter = true;
- let hasSideEffects = true;
+ let usesCustomInserter = true;
+ let hasSideEffects = true;
}
def LOCAL_ESCAPE : StandardPseudoInstruction {
// This instruction is really just a label. It has to be part of the chain so
@@ -1204,94 +1204,94 @@ def LOCAL_ESCAPE : StandardPseudoInstruction {
// no side effects.
let OutOperandList = (outs);
let InOperandList = (ins ptr_rc:$symbol, i32imm:$id);
- let hasSideEffects = false;
- let hasCtrlDep = true;
+ let hasSideEffects = false;
+ let hasCtrlDep = true;
}
def FAULTING_OP : StandardPseudoInstruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins variable_ops);
- let usesCustomInserter = true;
- let hasSideEffects = true;
- let mayLoad = true;
- let mayStore = true;
- let isTerminator = true;
- let isBranch = true;
+ let usesCustomInserter = true;
+ let hasSideEffects = true;
+ let mayLoad = true;
+ let mayStore = true;
+ let isTerminator = true;
+ let isBranch = true;
}
def PATCHABLE_OP : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
- let usesCustomInserter = true;
- let mayLoad = true;
- let mayStore = true;
- let hasSideEffects = true;
+ let usesCustomInserter = true;
+ let mayLoad = true;
+ let mayStore = true;
+ let hasSideEffects = true;
}
def PATCHABLE_FUNCTION_ENTER : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins);
let AsmString = "# XRay Function Enter.";
- let usesCustomInserter = true;
- let hasSideEffects = true;
+ let usesCustomInserter = true;
+ let hasSideEffects = true;
}
def PATCHABLE_RET : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "# XRay Function Patchable RET.";
- let usesCustomInserter = true;
- let hasSideEffects = true;
- let isTerminator = true;
- let isReturn = true;
+ let usesCustomInserter = true;
+ let hasSideEffects = true;
+ let isTerminator = true;
+ let isReturn = true;
}
def PATCHABLE_FUNCTION_EXIT : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins);
let AsmString = "# XRay Function Exit.";
- let usesCustomInserter = true;
- let hasSideEffects = true;
- let isReturn = false; // Original return instruction will follow
+ let usesCustomInserter = true;
+ let hasSideEffects = true;
+ let isReturn = false; // Original return instruction will follow
}
def PATCHABLE_TAIL_CALL : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "# XRay Tail Call Exit.";
- let usesCustomInserter = true;
- let hasSideEffects = true;
- let isReturn = true;
+ let usesCustomInserter = true;
+ let hasSideEffects = true;
+ let isReturn = true;
}
def PATCHABLE_EVENT_CALL : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins ptr_rc:$event, unknown:$size);
let AsmString = "# XRay Custom Event Log.";
- let usesCustomInserter = true;
- let isCall = true;
- let mayLoad = true;
- let mayStore = true;
- let hasSideEffects = true;
+ let usesCustomInserter = true;
+ let isCall = true;
+ let mayLoad = true;
+ let mayStore = true;
+ let hasSideEffects = true;
}
def PATCHABLE_TYPED_EVENT_CALL : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins unknown:$type, ptr_rc:$event, unknown:$size);
let AsmString = "# XRay Typed Event Log.";
- let usesCustomInserter = true;
- let isCall = true;
- let mayLoad = true;
- let mayStore = true;
- let hasSideEffects = true;
+ let usesCustomInserter = true;
+ let isCall = true;
+ let mayLoad = true;
+ let mayStore = true;
+ let hasSideEffects = true;
}
def FENTRY_CALL : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins);
let AsmString = "# FEntry call";
- let usesCustomInserter = true;
- let isCall = true;
- let mayLoad = true;
- let mayStore = true;
- let hasSideEffects = true;
+ let usesCustomInserter = true;
+ let isCall = true;
+ let mayLoad = true;
+ let mayStore = true;
+ let hasSideEffects = true;
}
def ICALL_BRANCH_FUNNEL : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "";
- let hasSideEffects = true;
+ let hasSideEffects = true;
}
// Generic opcodes used in GlobalISel.
@@ -1317,7 +1317,7 @@ class AsmParser {
// ShouldEmitMatchRegisterName - Set to false if the target needs a hand
// written register name matcher
- bit ShouldEmitMatchRegisterName = true;
+ bit ShouldEmitMatchRegisterName = true;
// Set to true if the target needs a generated 'alternative register name'
// matcher.
@@ -1325,7 +1325,7 @@ class AsmParser {
// This generates a function which can be used to lookup registers from
// their aliases. This function will fail when called on targets where
// several registers share the same alias (i.e. not a 1:1 mapping).
- bit ShouldEmitMatchRegisterAltName = false;
+ bit ShouldEmitMatchRegisterAltName = false;
// Set to true if MatchRegisterName and MatchRegisterAltName functions
// should be generated even if there are duplicate register names. The
@@ -1333,11 +1333,11 @@ class AsmParser {
// (e.g. in validateTargetOperandClass), and there are no guarantees about
// which numeric register identifier will be returned in the case of
// multiple matches.
- bit AllowDuplicateRegisterNames = false;
+ bit AllowDuplicateRegisterNames = false;
// HasMnemonicFirst - Set to false if target instructions don't always
// start with a mnemonic as the first token.
- bit HasMnemonicFirst = true;
+ bit HasMnemonicFirst = true;
// ReportMultipleNearMisses -
// When 0, the assembly matcher reports an error for one encoding or operand
@@ -1345,7 +1345,7 @@ class AsmParser {
// When 1, the assembly matcher returns a list of encodings that were close
// to matching the parsed instruction, so to allow more detailed error
// messages.
- bit ReportMultipleNearMisses = false;
+ bit ReportMultipleNearMisses = false;
}
def DefaultAsmParser : AsmParser;
@@ -1356,7 +1356,7 @@ def DefaultAsmParser : AsmParser;
//
class AsmParserVariant {
// Variant - AsmParsers can be of multiple different variants. Variants are
- // used to support targets that need to parse multiple formats for the
+ // used to support targets that need to parse multiple formats for the
// assembly language.
int Variant = 0;
@@ -1392,7 +1392,7 @@ def all_of;
/// AssemblerPredicate - This is a Predicate that can be used when the assembler
/// matches instructions and aliases.
class AssemblerPredicate<dag cond, string name = ""> {
- bit AssemblerMatcherPredicate = true;
+ bit AssemblerMatcherPredicate = true;
dag AssemblerCondDag = cond;
string PredicateName = name;
}
@@ -1467,7 +1467,7 @@ class InstAlias<string Asm, dag Result, int Emit = 1, string VariantName = ""> {
// Setting this to 0 will cause the alias to ignore the Result instruction's
// defined AsmMatchConverter and instead use the function generated by the
// dag Result.
- bit UseInstAsmMatchConverter = true;
+ bit UseInstAsmMatchConverter = true;
// Assembler variant name to use for this alias. If not specified then
// assembler variants will be determined based on AsmString
@@ -1572,8 +1572,8 @@ class ComplexDeprecationPredicate<string dep> {
// by the scheduler. Each Processor definition requires corresponding
// instruction itineraries.
//
-class Processor<string n, ProcessorItineraries pi, list<SubtargetFeature> f,
- list<SubtargetFeature> tunef = []> {
+class Processor<string n, ProcessorItineraries pi, list<SubtargetFeature> f,
+ list<SubtargetFeature> tunef = []> {
// Name - Chip set name. Used by command line (-mcpu=) to determine the
// appropriate target chip.
//
@@ -1589,12 +1589,12 @@ class Processor<string n, ProcessorItineraries pi, list<SubtargetFeature> f,
// Features - list of
list<SubtargetFeature> Features = f;
-
- // TuneFeatures - list of features for tuning for this CPU. If the target
- // supports -mtune, this should contain the list of features used to make
- // microarchitectural optimization decisions for a given processor. While
- // Features should contain the architectural features for the processor.
- list<SubtargetFeature> TuneFeatures = tunef;
+
+ // TuneFeatures - list of features for tuning for this CPU. If the target
+ // supports -mtune, this should contain the list of features used to make
+ // microarchitectural optimization decisions for a given processor. While
+ // Features should contain the architectural features for the processor.
+ list<SubtargetFeature> TuneFeatures = tunef;
}
// ProcessorModel allows subtargets to specify the more general
@@ -1603,9 +1603,9 @@ class Processor<string n, ProcessorItineraries pi, list<SubtargetFeature> f,
//
// Although this class always passes NoItineraries to the Processor
// class, the SchedMachineModel may still define valid Itineraries.
-class ProcessorModel<string n, SchedMachineModel m, list<SubtargetFeature> f,
- list<SubtargetFeature> tunef = []>
- : Processor<n, NoItineraries, f, tunef> {
+class ProcessorModel<string n, SchedMachineModel m, list<SubtargetFeature> f,
+ list<SubtargetFeature> tunef = []>
+ : Processor<n, NoItineraries, f, tunef> {
let SchedModel = m;
}
diff --git a/contrib/libs/llvm12/include/llvm/Target/TargetCallingConv.td b/contrib/libs/llvm12/include/llvm/Target/TargetCallingConv.td
index 6e7277c165..b3d4fe9d0d 100644
--- a/contrib/libs/llvm12/include/llvm/Target/TargetCallingConv.td
+++ b/contrib/libs/llvm12/include/llvm/Target/TargetCallingConv.td
@@ -187,15 +187,15 @@ class CallingConv<list<CCAction> actions> {
/// If true, this calling convention will be emitted as externally visible in
/// the llvm namespaces instead of as a static function.
- bit Entry = false;
+ bit Entry = false;
- bit Custom = false;
+ bit Custom = false;
}
/// CustomCallingConv - An instance of this is used to declare calling
/// conventions that are implemented using a custom function of the same name.
class CustomCallingConv : CallingConv<[]> {
- let Custom = true;
+ let Custom = true;
}
/// CalleeSavedRegs - A list of callee saved registers for a given calling
diff --git a/contrib/libs/llvm12/include/llvm/Target/TargetInstrPredicate.td b/contrib/libs/llvm12/include/llvm/Target/TargetInstrPredicate.td
index 04022cf45b..9f2cde9d92 100644
--- a/contrib/libs/llvm12/include/llvm/Target/TargetInstrPredicate.td
+++ b/contrib/libs/llvm12/include/llvm/Target/TargetInstrPredicate.td
@@ -11,7 +11,7 @@
// MCInstPredicate definitions are used by target scheduling models to describe
// constraints on instructions.
//
-// Here is an example of an MCInstPredicate definition in TableGen:
+// Here is an example of an MCInstPredicate definition in TableGen:
//
// def MCInstPredicateExample : CheckAll<[
// CheckOpcode<[BLR]>,
@@ -126,11 +126,11 @@ class CheckRegOperand<int Index, Register R> : CheckOperandBase<Index> {
// Check if register operand at index `Index` is the invalid register.
class CheckInvalidRegOperand<int Index> : CheckOperandBase<Index>;
-// Return true if machine operand at position `Index` is a valid
-// register operand.
-class CheckValidRegOperand<int Index> :
- CheckNot<CheckInvalidRegOperand<Index>>;
-
+// Return true if machine operand at position `Index` is a valid
+// register operand.
+class CheckValidRegOperand<int Index> :
+ CheckNot<CheckInvalidRegOperand<Index>>;
+
// Check that the operand at position `Index` is immediate `Imm`.
// If field `FunctionMapper` is a non-empty string, then function
// `FunctionMapper` is applied to the operand value, and the return value is then
@@ -259,20 +259,20 @@ class CheckFunctionPredicate<string MCInstFn, string MachineInstrFn> : MCInstPre
string MachineInstrFnName = MachineInstrFn;
}
-// Similar to CheckFunctionPredicate. However it assumes that MachineInstrFn is
-// a method in TargetInstrInfo, and MCInstrFn takes an extra pointer to
-// MCInstrInfo.
-//
-// It Expands to:
-// - TIIPointer->MachineInstrFn(MI)
-// - MCInstrFn(MI, MCII);
-class CheckFunctionPredicateWithTII<string MCInstFn, string MachineInstrFn, string
-TIIPointer = "TII"> : MCInstPredicate {
- string MCInstFnName = MCInstFn;
- string TIIPtrName = TIIPointer;
- string MachineInstrFnName = MachineInstrFn;
-}
-
+// Similar to CheckFunctionPredicate. However it assumes that MachineInstrFn is
+// a method in TargetInstrInfo, and MCInstrFn takes an extra pointer to
+// MCInstrInfo.
+//
+// It Expands to:
+// - TIIPointer->MachineInstrFn(MI)
+// - MCInstrFn(MI, MCII);
+class CheckFunctionPredicateWithTII<string MCInstFn, string MachineInstrFn, string
+TIIPointer = "TII"> : MCInstPredicate {
+ string MCInstFnName = MCInstFn;
+ string TIIPtrName = TIIPointer;
+ string MachineInstrFnName = MachineInstrFn;
+}
+
// Used to classify machine instructions based on a machine instruction
// predicate.
//
@@ -319,8 +319,8 @@ class DepBreakingClass<list<Instruction> opcodes, MCInstPredicate pred,
// - A list of subtarget hooks (Delegates) that are called from this function.
//
class STIPredicateDecl<string name, MCInstPredicate default = FalsePred,
- bit overrides = true, bit expandForMC = true,
- bit updatesOpcodeMask = false,
+ bit overrides = true, bit expandForMC = true,
+ bit updatesOpcodeMask = false,
list<STIPredicateDecl> delegates = []> {
string Name = name;
@@ -355,7 +355,7 @@ class STIPredicate<STIPredicateDecl declaration,
// Convenience classes and definitions used by processor scheduling models to
// describe dependency breaking instructions and move elimination candidates.
-let UpdatesOpcodeMask = true in {
+let UpdatesOpcodeMask = true in {
def IsZeroIdiomDecl : STIPredicateDecl<"isZeroIdiom">;
diff --git a/contrib/libs/llvm12/include/llvm/Target/TargetItinerary.td b/contrib/libs/llvm12/include/llvm/Target/TargetItinerary.td
index 12e77f1e6d..a432d4e42b 100644
--- a/contrib/libs/llvm12/include/llvm/Target/TargetItinerary.td
+++ b/contrib/libs/llvm12/include/llvm/Target/TargetItinerary.td
@@ -8,7 +8,7 @@
//
// This file defines the target-independent scheduling interfaces
// which should be implemented by each target that uses instruction
-// itineraries for scheduling. Itineraries are detailed reservation
+// itineraries for scheduling. Itineraries are detailed reservation
// tables for each instruction class. They are most appropriate for
// in-order machine with complicated scheduling or bundling constraints.
//
diff --git a/contrib/libs/llvm12/include/llvm/Target/TargetLoweringObjectFile.h b/contrib/libs/llvm12/include/llvm/Target/TargetLoweringObjectFile.h
index 9c40c26448..7befbe1fb2 100644
--- a/contrib/libs/llvm12/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/contrib/libs/llvm12/include/llvm/Target/TargetLoweringObjectFile.h
@@ -45,7 +45,7 @@ class Module;
class SectionKind;
class StringRef;
class TargetMachine;
-class DSOLocalEquivalent;
+class DSOLocalEquivalent;
class TargetLoweringObjectFile : public MCObjectFileInfo {
/// Name-mangler for global names.
@@ -55,7 +55,7 @@ protected:
bool SupportIndirectSymViaGOTPCRel = false;
bool SupportGOTPCRelWithOffset = true;
bool SupportDebugThreadLocalLocation = true;
- bool SupportDSOLocalEquivalentLowering = false;
+ bool SupportDSOLocalEquivalentLowering = false;
/// PersonalityEncoding, LSDAEncoding, TTypeEncoding - Some encoding values
/// for EH.
@@ -70,8 +70,8 @@ protected:
/// This section contains the static destructor pointer list.
MCSection *StaticDtorSection = nullptr;
- const TargetMachine *TM = nullptr;
-
+ const TargetMachine *TM = nullptr;
+
public:
TargetLoweringObjectFile() = default;
TargetLoweringObjectFile(const TargetLoweringObjectFile &) = delete;
@@ -92,9 +92,9 @@ public:
/// Emit the module-level metadata that the platform cares about.
virtual void emitModuleMetadata(MCStreamer &Streamer, Module &M) const {}
- /// Emit Call Graph Profile metadata.
- void emitCGProfileMetadata(MCStreamer &Streamer, Module &M) const;
-
+ /// Emit Call Graph Profile metadata.
+ void emitCGProfileMetadata(MCStreamer &Streamer, Module &M) const;
+
/// Get the module-level metadata that the platform cares about.
virtual void getModuleMetadata(Module &M) {}
@@ -132,10 +132,10 @@ public:
virtual MCSection *getSectionForJumpTable(const Function &F,
const TargetMachine &TM) const;
- virtual MCSection *getSectionForLSDA(const Function &F,
- const TargetMachine &TM) const {
- return LSDASection;
- }
+ virtual MCSection *getSectionForLSDA(const Function &F,
+ const TargetMachine &TM) const {
+ return LSDASection;
+ }
virtual bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,
const Function &F) const;
@@ -169,7 +169,7 @@ public:
unsigned getPersonalityEncoding() const { return PersonalityEncoding; }
unsigned getLSDAEncoding() const { return LSDAEncoding; }
unsigned getTTypeEncoding() const { return TTypeEncoding; }
- unsigned getCallSiteEncoding() const;
+ unsigned getCallSiteEncoding() const;
const MCExpr *getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding,
MCStreamer &Streamer) const;
@@ -194,17 +194,17 @@ public:
return nullptr;
}
- /// Target supports a native lowering of a dso_local_equivalent constant
- /// without needing to replace it with equivalent IR.
- bool supportDSOLocalEquivalentLowering() const {
- return SupportDSOLocalEquivalentLowering;
- }
-
- virtual const MCExpr *lowerDSOLocalEquivalent(const DSOLocalEquivalent *Equiv,
- const TargetMachine &TM) const {
- return nullptr;
- }
-
+ /// Target supports a native lowering of a dso_local_equivalent constant
+ /// without needing to replace it with equivalent IR.
+ bool supportDSOLocalEquivalentLowering() const {
+ return SupportDSOLocalEquivalentLowering;
+ }
+
+ virtual const MCExpr *lowerDSOLocalEquivalent(const DSOLocalEquivalent *Equiv,
+ const TargetMachine &TM) const {
+ return nullptr;
+ }
+
/// Target supports replacing a data "PC"-relative access to a symbol
/// through another symbol, by accessing the later via a GOT entry instead?
bool supportIndirectSymViaGOTPCRel() const {
@@ -249,8 +249,8 @@ public:
/// On targets that support TOC entries, return a section for the entry given
/// the symbol it refers to.
/// TODO: Implement this interface for existing ELF targets.
- virtual MCSection *getSectionForTOCEntry(const MCSymbol *S,
- const TargetMachine &TM) const {
+ virtual MCSection *getSectionForTOCEntry(const MCSymbol *S,
+ const TargetMachine &TM) const {
return nullptr;
}
@@ -271,8 +271,8 @@ public:
/// If supported, return the function entry point symbol.
/// Otherwise, returns nulltpr.
- /// Func must be a function or an alias which has a function as base object.
- virtual MCSymbol *getFunctionEntryPointSymbol(const GlobalValue *Func,
+ /// Func must be a function or an alias which has a function as base object.
+ virtual MCSymbol *getFunctionEntryPointSymbol(const GlobalValue *Func,
const TargetMachine &TM) const {
return nullptr;
}
diff --git a/contrib/libs/llvm12/include/llvm/Target/TargetMachine.h b/contrib/libs/llvm12/include/llvm/Target/TargetMachine.h
index 64a9976d26..4e934b5d4e 100644
--- a/contrib/libs/llvm12/include/llvm/Target/TargetMachine.h
+++ b/contrib/libs/llvm12/include/llvm/Target/TargetMachine.h
@@ -23,36 +23,36 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/Support/CodeGen.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Target/CGPassBuilderOption.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Target/CGPassBuilderOption.h"
#include "llvm/Target/TargetOptions.h"
#include <string>
namespace llvm {
-class AAManager;
-template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs>
-class PassManager;
-using ModulePassManager = PassManager<Module>;
-
+class AAManager;
+template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs>
+class PassManager;
+using ModulePassManager = PassManager<Module>;
+
class Function;
class GlobalValue;
-class MachineFunctionPassManager;
-class MachineFunctionAnalysisManager;
+class MachineFunctionPassManager;
+class MachineFunctionAnalysisManager;
class MachineModuleInfoWrapperPass;
class Mangler;
class MCAsmInfo;
class MCContext;
class MCInstrInfo;
class MCRegisterInfo;
-class MCStreamer;
+class MCStreamer;
class MCSubtargetInfo;
class MCSymbol;
class raw_pwrite_stream;
-class PassBuilder;
+class PassBuilder;
class PassManagerBuilder;
struct PerFunctionMIParsingState;
class SMDiagnostic;
@@ -130,7 +130,7 @@ public:
const Triple &getTargetTriple() const { return TargetTriple; }
StringRef getTargetCPU() const { return TargetCPU; }
StringRef getTargetFeatureString() const { return TargetFS; }
- void setTargetFeatureString(StringRef FS) { TargetFS = std::string(FS); }
+ void setTargetFeatureString(StringRef FS) { TargetFS = std::string(FS); }
/// Virtual method implemented by subclasses that returns a reference to that
/// target's TargetSubtargetInfo-derived member variable.
@@ -261,9 +261,9 @@ public:
Options.SupportsDebugEntryValues = Enable;
}
- bool getAIXExtendedAltivecABI() const {
- return Options.EnableAIXExtendedAltivecABI;
- }
+ bool getAIXExtendedAltivecABI() const {
+ return Options.EnableAIXExtendedAltivecABI;
+ }
bool getUniqueSectionNames() const { return Options.UniqueSectionNames; }
@@ -284,16 +284,16 @@ public:
return Options.FunctionSections;
}
- /// Return true if visibility attribute should not be emitted in XCOFF,
- /// corresponding to -mignore-xcoff-visibility.
- bool getIgnoreXCOFFVisibility() const {
- return Options.IgnoreXCOFFVisibility;
- }
-
- /// Return true if XCOFF traceback table should be emitted,
- /// corresponding to -xcoff-traceback-table.
- bool getXCOFFTracebackTable() const { return Options.XCOFFTracebackTable; }
-
+ /// Return true if visibility attribute should not be emitted in XCOFF,
+ /// corresponding to -mignore-xcoff-visibility.
+ bool getIgnoreXCOFFVisibility() const {
+ return Options.IgnoreXCOFFVisibility;
+ }
+
+ /// Return true if XCOFF traceback table should be emitted,
+ /// corresponding to -xcoff-traceback-table.
+ bool getXCOFFTracebackTable() const { return Options.XCOFFTracebackTable; }
+
/// If basic blocks should be emitted into their own section,
/// corresponding to -fbasic-block-sections.
llvm::BasicBlockSection getBBSectionsType() const {
@@ -305,19 +305,19 @@ public:
return Options.BBSectionsFuncListBuf.get();
}
- /// Returns true if a cast between SrcAS and DestAS is a noop.
- virtual bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const {
- return false;
- }
-
- /// If the specified generic pointer could be assumed as a pointer to a
- /// specific address space, return that address space.
- ///
- /// Under offloading programming, the offloading target may be passed with
- /// values only prepared on the host side and could assume certain
- /// properties.
- virtual unsigned getAssumedAddrSpace(const Value *V) const { return -1; }
-
+ /// Returns true if a cast between SrcAS and DestAS is a noop.
+ virtual bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const {
+ return false;
+ }
+
+ /// If the specified generic pointer could be assumed as a pointer to a
+ /// specific address space, return that address space.
+ ///
+ /// Under offloading programming, the offloading target may be passed with
+ /// values only prepared on the host side and could assume certain
+ /// properties.
+ virtual unsigned getAssumedAddrSpace(const Value *V) const { return -1; }
+
/// Get a \c TargetIRAnalysis appropriate for the target.
///
/// This is used to construct the new pass manager's target IR analysis pass,
@@ -335,15 +335,15 @@ public:
/// PassManagerBuilder::addExtension.
virtual void adjustPassManager(PassManagerBuilder &) {}
- /// Allow the target to modify the pass pipeline with New Pass Manager
- /// (similar to adjustPassManager for Legacy Pass manager).
- virtual void registerPassBuilderCallbacks(PassBuilder &,
- bool DebugPassManager) {}
-
- /// Allow the target to register alias analyses with the AAManager for use
- /// with the new pass manager. Only affects the "default" AAManager.
- virtual void registerDefaultAliasAnalyses(AAManager &) {}
-
+ /// Allow the target to modify the pass pipeline with New Pass Manager
+ /// (similar to adjustPassManager for Legacy Pass manager).
+ virtual void registerPassBuilderCallbacks(PassBuilder &,
+ bool DebugPassManager) {}
+
+ /// Allow the target to register alias analyses with the AAManager for use
+ /// with the new pass manager. Only affects the "default" AAManager.
+ virtual void registerDefaultAliasAnalyses(AAManager &) {}
+
/// Add passes to the specified pass manager to get the specified file
/// emitted. Typically this will involve several steps of code generation.
/// This method should return true if emission of this file type is not
@@ -383,8 +383,8 @@ public:
/// The integer bit size to use for SjLj based exception handling.
static constexpr unsigned DefaultSjLjDataSize = 32;
virtual unsigned getSjLjDataSize() const { return DefaultSjLjDataSize; }
-
- static std::pair<int, int> parseBinutilsVersion(StringRef Version);
+
+ static std::pair<int, int> parseBinutilsVersion(StringRef Version);
};
/// This class describes a target machine that is implemented with the LLVM
@@ -420,21 +420,21 @@ public:
bool DisableVerify = true,
MachineModuleInfoWrapperPass *MMIWP = nullptr) override;
- virtual Error buildCodeGenPipeline(ModulePassManager &,
- MachineFunctionPassManager &,
- MachineFunctionAnalysisManager &,
- raw_pwrite_stream &, raw_pwrite_stream *,
- CodeGenFileType, CGPassBuilderOption,
- PassInstrumentationCallbacks *) {
- return make_error<StringError>("buildCodeGenPipeline is not overriden",
- inconvertibleErrorCode());
- }
-
- virtual std::pair<StringRef, bool> getPassNameFromLegacyName(StringRef) {
- llvm_unreachable(
- "getPassNameFromLegacyName parseMIRPipeline is not overriden");
- }
-
+ virtual Error buildCodeGenPipeline(ModulePassManager &,
+ MachineFunctionPassManager &,
+ MachineFunctionAnalysisManager &,
+ raw_pwrite_stream &, raw_pwrite_stream *,
+ CodeGenFileType, CGPassBuilderOption,
+ PassInstrumentationCallbacks *) {
+ return make_error<StringError>("buildCodeGenPipeline is not overriden",
+ inconvertibleErrorCode());
+ }
+
+ virtual std::pair<StringRef, bool> getPassNameFromLegacyName(StringRef) {
+ llvm_unreachable(
+ "getPassNameFromLegacyName parseMIRPipeline is not overriden");
+ }
+
/// Add passes to the specified pass manager to get machine code emitted with
/// the MCJIT. This method returns true if machine code is not supported. It
/// fills the MCContext Ctx pointer which can be used to build custom
@@ -455,10 +455,10 @@ public:
raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
MCContext &Context);
- Expected<std::unique_ptr<MCStreamer>>
- createMCStreamer(raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
- CodeGenFileType FileType, MCContext &Ctx);
-
+ Expected<std::unique_ptr<MCStreamer>>
+ createMCStreamer(raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
+ CodeGenFileType FileType, MCContext &Ctx);
+
/// True if the target uses physical regs (as nearly all targets do). False
/// for stack machines such as WebAssembly and other virtual-register
/// machines. If true, all vregs must be allocated before PEI. If false, then
diff --git a/contrib/libs/llvm12/include/llvm/Target/TargetOptions.h b/contrib/libs/llvm12/include/llvm/Target/TargetOptions.h
index 2e0571315a..2ae71d2938 100644
--- a/contrib/libs/llvm12/include/llvm/Target/TargetOptions.h
+++ b/contrib/libs/llvm12/include/llvm/Target/TargetOptions.h
@@ -74,18 +74,18 @@ namespace llvm {
Labels, // Do not use Basic Block Sections but label basic blocks. This
// is useful when associating profile counts from virtual addresses
// to basic blocks.
- Preset, // Similar to list but the blocks are identified by passes which
- // seek to use Basic Block Sections, e.g. MachineFunctionSplitter.
- // This option cannot be set via the command line.
+ Preset, // Similar to list but the blocks are identified by passes which
+ // seek to use Basic Block Sections, e.g. MachineFunctionSplitter.
+ // This option cannot be set via the command line.
None // Do not use Basic Block Sections.
};
- enum class StackProtectorGuards {
- None,
- TLS,
- Global
- };
-
+ enum class StackProtectorGuards {
+ None,
+ TLS,
+ Global
+ };
+
enum class EABI {
Unknown,
Default, // Default means not specified
@@ -129,34 +129,34 @@ namespace llvm {
class TargetOptions {
public:
TargetOptions()
- : UnsafeFPMath(false), NoInfsFPMath(false), NoNaNsFPMath(false),
- NoTrappingFPMath(true), NoSignedZerosFPMath(false),
- EnableAIXExtendedAltivecABI(false),
+ : UnsafeFPMath(false), NoInfsFPMath(false), NoNaNsFPMath(false),
+ NoTrappingFPMath(true), NoSignedZerosFPMath(false),
+ EnableAIXExtendedAltivecABI(false),
HonorSignDependentRoundingFPMathOption(false), NoZerosInBSS(false),
GuaranteedTailCallOpt(false), StackSymbolOrdering(true),
EnableFastISel(false), EnableGlobalISel(false), UseInitArray(false),
DisableIntegratedAS(false), RelaxELFRelocations(false),
FunctionSections(false), DataSections(false),
- IgnoreXCOFFVisibility(false), XCOFFTracebackTable(true),
+ IgnoreXCOFFVisibility(false), XCOFFTracebackTable(true),
UniqueSectionNames(true), UniqueBasicBlockSectionNames(false),
TrapUnreachable(false), NoTrapAfterNoreturn(false), TLSSize(0),
EmulatedTLS(false), ExplicitEmulatedTLS(false), EnableIPRA(false),
EmitStackSizeSection(false), EnableMachineOutliner(false),
- EnableMachineFunctionSplitter(false), SupportsDefaultOutlining(false),
- EmitAddrsig(false), EmitCallSiteInfo(false),
- SupportsDebugEntryValues(false), EnableDebugEntryValues(false),
- PseudoProbeForProfiling(false), ValueTrackingVariableLocations(false),
- ForceDwarfFrameSection(false), XRayOmitFunctionIndex(false),
+ EnableMachineFunctionSplitter(false), SupportsDefaultOutlining(false),
+ EmitAddrsig(false), EmitCallSiteInfo(false),
+ SupportsDebugEntryValues(false), EnableDebugEntryValues(false),
+ PseudoProbeForProfiling(false), ValueTrackingVariableLocations(false),
+ ForceDwarfFrameSection(false), XRayOmitFunctionIndex(false),
FPDenormalMode(DenormalMode::IEEE, DenormalMode::IEEE) {}
/// DisableFramePointerElim - This returns true if frame pointer elimination
/// optimization should be disabled for the given machine function.
bool DisableFramePointerElim(const MachineFunction &MF) const;
- /// If greater than 0, override the default value of
- /// MCAsmInfo::BinutilsVersion.
- std::pair<int, int> BinutilsVersion{0, 0};
-
+ /// If greater than 0, override the default value of
+ /// MCAsmInfo::BinutilsVersion.
+ std::pair<int, int> BinutilsVersion{0, 0};
+
/// UnsafeFPMath - This flag is enabled when the
/// -enable-unsafe-fp-math flag is specified on the command line. When
/// this flag is off (the default), the code generator is not allowed to
@@ -187,12 +187,12 @@ namespace llvm {
/// argument or result as insignificant.
unsigned NoSignedZerosFPMath : 1;
- /// EnableAIXExtendedAltivecABI - This flag returns true when -vec-extabi is
- /// specified. The code generator is then able to use both volatile and
- /// nonvolitle vector regisers. When false, the code generator only uses
- /// volatile vector registers which is the default setting on AIX.
- unsigned EnableAIXExtendedAltivecABI : 1;
-
+ /// EnableAIXExtendedAltivecABI - This flag returns true when -vec-extabi is
+ /// specified. The code generator is then able to use both volatile and
+ /// nonvolitle vector regisers. When false, the code generator only uses
+ /// volatile vector registers which is the default setting on AIX.
+ unsigned EnableAIXExtendedAltivecABI : 1;
+
/// HonorSignDependentRoundingFPMath - This returns true when the
/// -enable-sign-dependent-rounding-fp-math is specified. If this returns
/// false (the default), the code generator is allowed to assume that the
@@ -255,12 +255,12 @@ namespace llvm {
/// Emit data into separate sections.
unsigned DataSections : 1;
- /// Do not emit visibility attribute for xcoff.
- unsigned IgnoreXCOFFVisibility : 1;
-
- /// Emit XCOFF traceback table.
- unsigned XCOFFTracebackTable : 1;
-
+ /// Do not emit visibility attribute for xcoff.
+ unsigned IgnoreXCOFFVisibility : 1;
+
+ /// Emit XCOFF traceback table.
+ unsigned XCOFFTracebackTable : 1;
+
unsigned UniqueSectionNames : 1;
/// Use unique names for basic block sections.
@@ -292,9 +292,9 @@ namespace llvm {
/// Enables the MachineOutliner pass.
unsigned EnableMachineOutliner : 1;
- /// Enables the MachineFunctionSplitter pass.
- unsigned EnableMachineFunctionSplitter : 1;
-
+ /// Enables the MachineFunctionSplitter pass.
+ unsigned EnableMachineFunctionSplitter : 1;
+
/// Set if the target supports default outlining behaviour.
unsigned SupportsDefaultOutlining : 1;
@@ -323,30 +323,30 @@ namespace llvm {
/// production.
bool ShouldEmitDebugEntryValues() const;
- /// Emit pseudo probes into the binary for sample profiling
- unsigned PseudoProbeForProfiling : 1;
-
- // When set to true, use experimental new debug variable location tracking,
- // which seeks to follow the values of variables rather than their location,
- // post isel.
- unsigned ValueTrackingVariableLocations : 1;
-
+ /// Emit pseudo probes into the binary for sample profiling
+ unsigned PseudoProbeForProfiling : 1;
+
+ // When set to true, use experimental new debug variable location tracking,
+ // which seeks to follow the values of variables rather than their location,
+ // post isel.
+ unsigned ValueTrackingVariableLocations : 1;
+
/// Emit DWARF debug frame section.
unsigned ForceDwarfFrameSection : 1;
/// Emit XRay Function Index section
unsigned XRayOmitFunctionIndex : 1;
- /// Stack protector guard offset to use.
- unsigned StackProtectorGuardOffset : 32;
-
- /// Stack protector guard mode to use, e.g. tls, global.
- StackProtectorGuards StackProtectorGuard =
- StackProtectorGuards::None;
-
- /// Stack protector guard reg to use, e.g. usually fs or gs in X86.
- std::string StackProtectorGuardReg = "None";
-
+ /// Stack protector guard offset to use.
+ unsigned StackProtectorGuardOffset : 32;
+
+ /// Stack protector guard mode to use, e.g. tls, global.
+ StackProtectorGuards StackProtectorGuard =
+ StackProtectorGuards::None;
+
+ /// Stack protector guard reg to use, e.g. usually fs or gs in X86.
+ std::string StackProtectorGuardReg = "None";
+
/// FloatABIType - This setting is set by -float-abi=xxx option is specfied
/// on the command line. This setting may either be Default, Soft, or Hard.
/// Default selects the target's default behavior. Soft selects the ABI for
diff --git a/contrib/libs/llvm12/include/llvm/Target/TargetPfmCounters.td b/contrib/libs/llvm12/include/llvm/Target/TargetPfmCounters.td
index 93ab042819..b00f3e19c3 100644
--- a/contrib/libs/llvm12/include/llvm/Target/TargetPfmCounters.td
+++ b/contrib/libs/llvm12/include/llvm/Target/TargetPfmCounters.td
@@ -7,8 +7,8 @@
//===----------------------------------------------------------------------===//
//
// This file defines the target-independent interfaces for performance counters.
-//
-//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
// Definition of a hardware counters from libpfm identifiers.
class PfmCounter<string counter> {
diff --git a/contrib/libs/llvm12/include/llvm/Target/TargetSchedule.td b/contrib/libs/llvm12/include/llvm/Target/TargetSchedule.td
index ce6e316dae..a822878ead 100644
--- a/contrib/libs/llvm12/include/llvm/Target/TargetSchedule.td
+++ b/contrib/libs/llvm12/include/llvm/Target/TargetSchedule.td
@@ -87,7 +87,7 @@ class SchedMachineModel {
// Per-cycle resources tables.
ProcessorItineraries Itineraries = NoItineraries;
- bit PostRAScheduler = false; // Enable Post RegAlloc Scheduler pass.
+ bit PostRAScheduler = false; // Enable Post RegAlloc Scheduler pass.
// Subtargets that define a model for only a subset of instructions
// that have a scheduling class (itinerary class or SchedRW list)
@@ -96,13 +96,13 @@ class SchedMachineModel {
// be an error. This should only be set during initial bringup,
// or there will be no way to catch simple errors in the model
// resulting from changes to the instruction definitions.
- bit CompleteModel = true;
+ bit CompleteModel = true;
// Indicates that we should do full overlap checking for multiple InstrRWs
// defining the same instructions within the same SchedMachineModel.
// FIXME: Remove when all in tree targets are clean with the full check
// enabled.
- bit FullInstRWOverlapCheck = true;
+ bit FullInstRWOverlapCheck = true;
// A processor may only implement part of published ISA, due to either new ISA
// extensions, (e.g. Pentium 4 doesn't have AVX) or implementation
@@ -118,12 +118,12 @@ class SchedMachineModel {
// field.
list<Predicate> UnsupportedFeatures = [];
- bit NoModel = false; // Special tag to indicate missing machine model.
+ bit NoModel = false; // Special tag to indicate missing machine model.
}
def NoSchedModel : SchedMachineModel {
- let NoModel = true;
- let CompleteModel = false;
+ let NoModel = true;
+ let CompleteModel = false;
}
// Define a kind of processor resource that may be common across
@@ -254,14 +254,14 @@ class ProcWriteResources<list<ProcResourceKind> resources> {
list<int> ResourceCycles = [];
int Latency = 1;
int NumMicroOps = 1;
- bit BeginGroup = false;
- bit EndGroup = false;
+ bit BeginGroup = false;
+ bit EndGroup = false;
// Allow a processor to mark some scheduling classes as unsupported
// for stronger verification.
- bit Unsupported = false;
+ bit Unsupported = false;
// Allow a processor to mark some scheduling classes as single-issue.
// SingleIssue is an alias for Begin/End Group.
- bit SingleIssue = false;
+ bit SingleIssue = false;
SchedMachineModel SchedModel = ?;
}
@@ -317,7 +317,7 @@ class ProcReadAdvance<int cycles, list<SchedWrite> writes = []> {
list<SchedWrite> ValidWrites = writes;
// Allow a processor to mark some scheduling classes as unsupported
// for stronger verification.
- bit Unsupported = false;
+ bit Unsupported = false;
SchedMachineModel SchedModel = ?;
}
@@ -395,7 +395,7 @@ class SchedVar<SchedPredicateBase pred, list<SchedReadWrite> selected> {
// SchedModel silences warnings but is ignored.
class SchedVariant<list<SchedVar> variants> {
list<SchedVar> Variants = variants;
- bit Variadic = false;
+ bit Variadic = false;
SchedMachineModel SchedModel = ?;
}
@@ -428,7 +428,7 @@ class InstRW<list<SchedReadWrite> rw, dag instrlist> {
dag Instrs = instrlist;
SchedMachineModel SchedModel = ?;
// Allow a subtarget to mark some instructions as unsupported.
- bit Unsupported = false;
+ bit Unsupported = false;
}
// Map a set of itinerary classes to SchedReadWrite resources. This is
@@ -535,7 +535,7 @@ class SchedAlias<SchedReadWrite match, SchedReadWrite alias> {
class RegisterFile<int numPhysRegs, list<RegisterClass> Classes = [],
list<int> Costs = [], list<bit> AllowMoveElim = [],
- int MaxMoveElimPerCy = 0, bit AllowZeroMoveElimOnly = false> {
+ int MaxMoveElimPerCy = 0, bit AllowZeroMoveElimOnly = false> {
list<RegisterClass> RegClasses = Classes;
list<int> RegCosts = Costs;
list<bit> AllowMoveElimination = AllowMoveElim;
diff --git a/contrib/libs/llvm12/include/llvm/Target/TargetSelectionDAG.td b/contrib/libs/llvm12/include/llvm/Target/TargetSelectionDAG.td
index cebce0f6d3..a09feca6ca 100644
--- a/contrib/libs/llvm12/include/llvm/Target/TargetSelectionDAG.td
+++ b/contrib/libs/llvm12/include/llvm/Target/TargetSelectionDAG.td
@@ -164,9 +164,9 @@ def SDTIntToFPOp : SDTypeProfile<1, 1, [ // [su]int_to_fp
def SDTFPToIntOp : SDTypeProfile<1, 1, [ // fp_to_[su]int
SDTCisInt<0>, SDTCisFP<1>, SDTCisSameNumEltsAs<0, 1>
]>;
-def SDTFPToIntSatOp : SDTypeProfile<1, 2, [ // fp_to_[su]int_sat
- SDTCisInt<0>, SDTCisFP<1>, SDTCisInt<2>, SDTCisSameNumEltsAs<0, 1>
-]>;
+def SDTFPToIntSatOp : SDTypeProfile<1, 2, [ // fp_to_[su]int_sat
+ SDTCisInt<0>, SDTCisFP<1>, SDTCisInt<2>, SDTCisSameNumEltsAs<0, 1>
+]>;
def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg
SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>,
SDTCisVTSmallerThanOp<2, 1>
@@ -215,8 +215,8 @@ def SDTCatchret : SDTypeProfile<0, 2, [ // catchret
def SDTNone : SDTypeProfile<0, 0, []>; // ret, trap
-def SDTUBSANTrap : SDTypeProfile<0, 1, []>; // ubsantrap
-
+def SDTUBSANTrap : SDTypeProfile<0, 1, []>; // ubsantrap
+
def SDTLoad : SDTypeProfile<1, 1, [ // load
SDTCisPtrTy<1>
]>;
@@ -250,11 +250,11 @@ def SDTVecInsert : SDTypeProfile<1, 3, [ // vector insert
def SDTVecReduce : SDTypeProfile<1, 1, [ // vector reduction
SDTCisInt<0>, SDTCisVec<1>
]>;
-def SDTFPVecReduce : SDTypeProfile<1, 1, [ // FP vector reduction
- SDTCisFP<0>, SDTCisVec<1>
-]>;
+def SDTFPVecReduce : SDTypeProfile<1, 1, [ // FP vector reduction
+ SDTCisFP<0>, SDTCisVec<1>
+]>;
+
-
def SDTSubVecExtract : SDTypeProfile<1, 2, [// subvector extract
SDTCisSubVecOfVec<0,1>, SDTCisInt<2>
]>;
@@ -405,8 +405,8 @@ def saddsat : SDNode<"ISD::SADDSAT" , SDTIntBinOp, [SDNPCommutative]>;
def uaddsat : SDNode<"ISD::UADDSAT" , SDTIntBinOp, [SDNPCommutative]>;
def ssubsat : SDNode<"ISD::SSUBSAT" , SDTIntBinOp>;
def usubsat : SDNode<"ISD::USUBSAT" , SDTIntBinOp>;
-def sshlsat : SDNode<"ISD::SSHLSAT" , SDTIntBinOp>;
-def ushlsat : SDNode<"ISD::USHLSAT" , SDTIntBinOp>;
+def sshlsat : SDNode<"ISD::SSHLSAT" , SDTIntBinOp>;
+def ushlsat : SDNode<"ISD::USHLSAT" , SDTIntBinOp>;
def smulfix : SDNode<"ISD::SMULFIX" , SDTIntScaledBinOp, [SDNPCommutative]>;
def smulfixsat : SDNode<"ISD::SMULFIXSAT", SDTIntScaledBinOp, [SDNPCommutative]>;
@@ -443,15 +443,15 @@ def vecreduce_smax : SDNode<"ISD::VECREDUCE_SMAX", SDTVecReduce>;
def vecreduce_umax : SDNode<"ISD::VECREDUCE_UMAX", SDTVecReduce>;
def vecreduce_smin : SDNode<"ISD::VECREDUCE_SMIN", SDTVecReduce>;
def vecreduce_umin : SDNode<"ISD::VECREDUCE_UMIN", SDTVecReduce>;
-def vecreduce_fadd : SDNode<"ISD::VECREDUCE_FADD", SDTFPVecReduce>;
+def vecreduce_fadd : SDNode<"ISD::VECREDUCE_FADD", SDTFPVecReduce>;
def fadd : SDNode<"ISD::FADD" , SDTFPBinOp, [SDNPCommutative]>;
def fsub : SDNode<"ISD::FSUB" , SDTFPBinOp>;
def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>;
def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>;
def frem : SDNode<"ISD::FREM" , SDTFPBinOp>;
-def fma : SDNode<"ISD::FMA" , SDTFPTernaryOp, [SDNPCommutative]>;
-def fmad : SDNode<"ISD::FMAD" , SDTFPTernaryOp, [SDNPCommutative]>;
+def fma : SDNode<"ISD::FMA" , SDTFPTernaryOp, [SDNPCommutative]>;
+def fmad : SDNode<"ISD::FMAD" , SDTFPTernaryOp, [SDNPCommutative]>;
def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>;
def fminnum : SDNode<"ISD::FMINNUM" , SDTFPBinOp,
[SDNPCommutative, SDNPAssociative]>;
@@ -494,8 +494,8 @@ def sint_to_fp : SDNode<"ISD::SINT_TO_FP" , SDTIntToFPOp>;
def uint_to_fp : SDNode<"ISD::UINT_TO_FP" , SDTIntToFPOp>;
def fp_to_sint : SDNode<"ISD::FP_TO_SINT" , SDTFPToIntOp>;
def fp_to_uint : SDNode<"ISD::FP_TO_UINT" , SDTFPToIntOp>;
-def fp_to_sint_sat : SDNode<"ISD::FP_TO_SINT_SAT" , SDTFPToIntSatOp>;
-def fp_to_uint_sat : SDNode<"ISD::FP_TO_UINT_SAT" , SDTFPToIntSatOp>;
+def fp_to_sint_sat : SDNode<"ISD::FP_TO_SINT_SAT" , SDTFPToIntSatOp>;
+def fp_to_uint_sat : SDNode<"ISD::FP_TO_UINT_SAT" , SDTFPToIntSatOp>;
def f16_to_fp : SDNode<"ISD::FP16_TO_FP" , SDTIntToFPOp>;
def fp_to_f16 : SDNode<"ISD::FP_TO_FP16" , SDTFPToIntOp>;
@@ -510,7 +510,7 @@ def strict_fdiv : SDNode<"ISD::STRICT_FDIV",
def strict_frem : SDNode<"ISD::STRICT_FREM",
SDTFPBinOp, [SDNPHasChain]>;
def strict_fma : SDNode<"ISD::STRICT_FMA",
- SDTFPTernaryOp, [SDNPHasChain, SDNPCommutative]>;
+ SDTFPTernaryOp, [SDNPHasChain, SDNPCommutative]>;
def strict_fsqrt : SDNode<"ISD::STRICT_FSQRT",
SDTFPUnaryOp, [SDNPHasChain]>;
def strict_fsin : SDNode<"ISD::STRICT_FSIN",
@@ -567,8 +567,8 @@ def strict_sint_to_fp : SDNode<"ISD::STRICT_SINT_TO_FP",
SDTIntToFPOp, [SDNPHasChain]>;
def strict_uint_to_fp : SDNode<"ISD::STRICT_UINT_TO_FP",
SDTIntToFPOp, [SDNPHasChain]>;
-def strict_fsetcc : SDNode<"ISD::STRICT_FSETCC", SDTSetCC, [SDNPHasChain]>;
-def strict_fsetccs : SDNode<"ISD::STRICT_FSETCCS", SDTSetCC, [SDNPHasChain]>;
+def strict_fsetcc : SDNode<"ISD::STRICT_FSETCC", SDTSetCC, [SDNPHasChain]>;
+def strict_fsetccs : SDNode<"ISD::STRICT_FSETCCS", SDTSetCC, [SDNPHasChain]>;
def setcc : SDNode<"ISD::SETCC" , SDTSetCC>;
def select : SDNode<"ISD::SELECT" , SDTSelect>;
@@ -587,8 +587,8 @@ def trap : SDNode<"ISD::TRAP" , SDTNone,
[SDNPHasChain, SDNPSideEffect]>;
def debugtrap : SDNode<"ISD::DEBUGTRAP" , SDTNone,
[SDNPHasChain, SDNPSideEffect]>;
-def ubsantrap : SDNode<"ISD::UBSANTRAP" , SDTUBSANTrap,
- [SDNPHasChain, SDNPSideEffect]>;
+def ubsantrap : SDNode<"ISD::UBSANTRAP" , SDTUBSANTrap,
+ [SDNPHasChain, SDNPSideEffect]>;
def prefetch : SDNode<"ISD::PREFETCH" , SDTPrefetch,
[SDNPHasChain, SDNPMayLoad, SDNPMayStore,
@@ -652,7 +652,7 @@ def ist : SDNode<"ISD::STORE" , SDTIStore,
def vector_shuffle : SDNode<"ISD::VECTOR_SHUFFLE", SDTVecShuffle, []>;
def build_vector : SDNode<"ISD::BUILD_VECTOR", SDTypeProfile<1, -1, []>, []>;
-def splat_vector : SDNode<"ISD::SPLAT_VECTOR", SDTypeProfile<1, 1, []>, []>;
+def splat_vector : SDNode<"ISD::SPLAT_VECTOR", SDTypeProfile<1, 1, []>, []>;
def scalar_to_vector : SDNode<"ISD::SCALAR_TO_VECTOR", SDTypeProfile<1, 1, []>,
[]>;
@@ -768,7 +768,7 @@ class PatFrags<dag ops, list<dag> frags, code pred = [{}],
// This is useful when Fragments involves associative / commutative
// operators: a single piece of code can easily refer to all operands even
// when re-associated / commuted variants of the fragment are matched.
- bit PredicateCodeUsesOperands = false;
+ bit PredicateCodeUsesOperands = false;
// Define a few pre-packaged predicates. This helps GlobalISel import
// existing rules from SelectionDAG for many common cases.
@@ -867,13 +867,13 @@ class ImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm,
SDNode ImmNode = imm>
: PatFrag<(ops), (vt ImmNode), [{}], xform> {
let ImmediateCode = pred;
- bit FastIselShouldIgnore = false;
+ bit FastIselShouldIgnore = false;
// Is the data type of the immediate an APInt?
- bit IsAPInt = false;
+ bit IsAPInt = false;
// Is the data type of the immediate an APFloat?
- bit IsAPFloat = false;
+ bit IsAPFloat = false;
}
// Convenience wrapper for ImmLeaf to use timm/TargetConstant instead
@@ -890,8 +890,8 @@ class TImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm,
// IntImmLeaf will allow GlobalISel to import the rule.
class IntImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm>
: ImmLeaf<vt, pred, xform> {
- let IsAPInt = true;
- let FastIselShouldIgnore = true;
+ let IsAPInt = true;
+ let FastIselShouldIgnore = true;
}
// An ImmLeaf except that Imm is an APFloat.
@@ -900,8 +900,8 @@ class IntImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm>
// generate code for rules that make use of it.
class FPImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm>
: ImmLeaf<vt, pred, xform, fpimm> {
- let IsAPFloat = true;
- let FastIselShouldIgnore = true;
+ let IsAPFloat = true;
+ let FastIselShouldIgnore = true;
}
// Leaf fragments.
@@ -909,23 +909,23 @@ class FPImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm>
def vtInt : PatLeaf<(vt), [{ return N->getVT().isInteger(); }]>;
def vtFP : PatLeaf<(vt), [{ return N->getVT().isFloatingPoint(); }]>;
-// Use ISD::isConstantSplatVectorAllOnes or ISD::isConstantSplatVectorAllZeros
-// to look for the corresponding build_vector or splat_vector. Will look through
-// bitcasts and check for either opcode, except when used as a pattern root.
-// When used as a pattern root, only fixed-length build_vector and scalable
-// splat_vector are supported.
-def immAllOnesV; // ISD::isConstantSplatVectorAllOnes
-def immAllZerosV; // ISD::isConstantSplatVectorAllZeros
+// Use ISD::isConstantSplatVectorAllOnes or ISD::isConstantSplatVectorAllZeros
+// to look for the corresponding build_vector or splat_vector. Will look through
+// bitcasts and check for either opcode, except when used as a pattern root.
+// When used as a pattern root, only fixed-length build_vector and scalable
+// splat_vector are supported.
+def immAllOnesV; // ISD::isConstantSplatVectorAllOnes
+def immAllZerosV; // ISD::isConstantSplatVectorAllZeros
// Other helper fragments.
def not : PatFrag<(ops node:$in), (xor node:$in, -1)>;
def vnot : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV)>;
def ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>;
-def zanyext : PatFrags<(ops node:$op),
- [(zext node:$op),
- (anyext node:$op)]>;
-
+def zanyext : PatFrags<(ops node:$op),
+ [(zext node:$op),
+ (anyext node:$op)]>;
+
// null_frag - The null pattern operator is used in multiclass instantiations
// which accept an SDPatternOperator for use in matching patterns for internal
// definitions. When expanding a pattern, if the null fragment is referenced
@@ -935,222 +935,222 @@ def null_frag : SDPatternOperator;
// load fragments.
def unindexedload : PatFrag<(ops node:$ptr), (ld node:$ptr)> {
- let IsLoad = true;
- let IsUnindexed = true;
+ let IsLoad = true;
+ let IsUnindexed = true;
}
def load : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> {
- let IsLoad = true;
- let IsNonExtLoad = true;
+ let IsLoad = true;
+ let IsNonExtLoad = true;
}
// extending load fragments.
def extload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> {
- let IsLoad = true;
- let IsAnyExtLoad = true;
+ let IsLoad = true;
+ let IsAnyExtLoad = true;
}
def sextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> {
- let IsLoad = true;
- let IsSignExtLoad = true;
+ let IsLoad = true;
+ let IsSignExtLoad = true;
}
def zextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> {
- let IsLoad = true;
- let IsZeroExtLoad = true;
+ let IsLoad = true;
+ let IsZeroExtLoad = true;
}
def extloadi1 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let MemoryVT = i1;
}
def extloadi8 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let MemoryVT = i8;
}
def extloadi16 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let MemoryVT = i16;
}
def extloadi32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let MemoryVT = i32;
}
def extloadf16 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let MemoryVT = f16;
}
def extloadf32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let MemoryVT = f32;
}
def extloadf64 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let MemoryVT = f64;
}
def sextloadi1 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let MemoryVT = i1;
}
def sextloadi8 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let MemoryVT = i8;
}
def sextloadi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let MemoryVT = i16;
}
def sextloadi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let MemoryVT = i32;
}
def zextloadi1 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let MemoryVT = i1;
}
def zextloadi8 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let MemoryVT = i8;
}
def zextloadi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let MemoryVT = i16;
}
def zextloadi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let MemoryVT = i32;
}
def extloadvi1 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let ScalarMemoryVT = i1;
}
def extloadvi8 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let ScalarMemoryVT = i8;
}
def extloadvi16 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let ScalarMemoryVT = i16;
}
def extloadvi32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let ScalarMemoryVT = i32;
}
def extloadvf32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let ScalarMemoryVT = f32;
}
def extloadvf64 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let ScalarMemoryVT = f64;
}
def sextloadvi1 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let ScalarMemoryVT = i1;
}
def sextloadvi8 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let ScalarMemoryVT = i8;
}
def sextloadvi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let ScalarMemoryVT = i16;
}
def sextloadvi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let ScalarMemoryVT = i32;
}
def zextloadvi1 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let ScalarMemoryVT = i1;
}
def zextloadvi8 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let ScalarMemoryVT = i8;
}
def zextloadvi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let ScalarMemoryVT = i16;
}
def zextloadvi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
- let IsLoad = true;
+ let IsLoad = true;
let ScalarMemoryVT = i32;
}
// store fragments.
def unindexedstore : PatFrag<(ops node:$val, node:$ptr),
(st node:$val, node:$ptr)> {
- let IsStore = true;
- let IsUnindexed = true;
+ let IsStore = true;
+ let IsUnindexed = true;
}
def store : PatFrag<(ops node:$val, node:$ptr),
(unindexedstore node:$val, node:$ptr)> {
- let IsStore = true;
- let IsTruncStore = false;
+ let IsStore = true;
+ let IsTruncStore = false;
}
// truncstore fragments.
def truncstore : PatFrag<(ops node:$val, node:$ptr),
(unindexedstore node:$val, node:$ptr)> {
- let IsStore = true;
- let IsTruncStore = true;
+ let IsStore = true;
+ let IsTruncStore = true;
}
def truncstorei8 : PatFrag<(ops node:$val, node:$ptr),
(truncstore node:$val, node:$ptr)> {
- let IsStore = true;
+ let IsStore = true;
let MemoryVT = i8;
}
def truncstorei16 : PatFrag<(ops node:$val, node:$ptr),
(truncstore node:$val, node:$ptr)> {
- let IsStore = true;
+ let IsStore = true;
let MemoryVT = i16;
}
def truncstorei32 : PatFrag<(ops node:$val, node:$ptr),
(truncstore node:$val, node:$ptr)> {
- let IsStore = true;
+ let IsStore = true;
let MemoryVT = i32;
}
def truncstoref16 : PatFrag<(ops node:$val, node:$ptr),
(truncstore node:$val, node:$ptr)> {
- let IsStore = true;
+ let IsStore = true;
let MemoryVT = f16;
}
def truncstoref32 : PatFrag<(ops node:$val, node:$ptr),
(truncstore node:$val, node:$ptr)> {
- let IsStore = true;
+ let IsStore = true;
let MemoryVT = f32;
}
def truncstoref64 : PatFrag<(ops node:$val, node:$ptr),
(truncstore node:$val, node:$ptr)> {
- let IsStore = true;
+ let IsStore = true;
let MemoryVT = f64;
}
def truncstorevi8 : PatFrag<(ops node:$val, node:$ptr),
(truncstore node:$val, node:$ptr)> {
- let IsStore = true;
+ let IsStore = true;
let ScalarMemoryVT = i8;
}
def truncstorevi16 : PatFrag<(ops node:$val, node:$ptr),
(truncstore node:$val, node:$ptr)> {
- let IsStore = true;
+ let IsStore = true;
let ScalarMemoryVT = i16;
}
def truncstorevi32 : PatFrag<(ops node:$val, node:$ptr),
(truncstore node:$val, node:$ptr)> {
- let IsStore = true;
+ let IsStore = true;
let ScalarMemoryVT = i32;
}
// indexed store fragments.
def istore : PatFrag<(ops node:$val, node:$base, node:$offset),
(ist node:$val, node:$base, node:$offset)> {
- let IsStore = true;
- let IsTruncStore = false;
+ let IsStore = true;
+ let IsTruncStore = false;
}
def pre_store : PatFrag<(ops node:$val, node:$base, node:$offset),
@@ -1161,8 +1161,8 @@ def pre_store : PatFrag<(ops node:$val, node:$base, node:$offset),
def itruncstore : PatFrag<(ops node:$val, node:$base, node:$offset),
(ist node:$val, node:$base, node:$offset)> {
- let IsStore = true;
- let IsTruncStore = true;
+ let IsStore = true;
+ let IsTruncStore = true;
}
def pre_truncst : PatFrag<(ops node:$val, node:$base, node:$offset),
(itruncstore node:$val, node:$base, node:$offset), [{
@@ -1171,37 +1171,37 @@ def pre_truncst : PatFrag<(ops node:$val, node:$base, node:$offset),
}]>;
def pre_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset),
(pre_truncst node:$val, node:$base, node:$offset)> {
- let IsStore = true;
+ let IsStore = true;
let MemoryVT = i1;
}
def pre_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset),
(pre_truncst node:$val, node:$base, node:$offset)> {
- let IsStore = true;
+ let IsStore = true;
let MemoryVT = i8;
}
def pre_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset),
(pre_truncst node:$val, node:$base, node:$offset)> {
- let IsStore = true;
+ let IsStore = true;
let MemoryVT = i16;
}
def pre_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset),
(pre_truncst node:$val, node:$base, node:$offset)> {
- let IsStore = true;
+ let IsStore = true;
let MemoryVT = i32;
}
def pre_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset),
(pre_truncst node:$val, node:$base, node:$offset)> {
- let IsStore = true;
+ let IsStore = true;
let MemoryVT = f32;
}
def pre_truncstvi8 : PatFrag<(ops node:$val, node:$base, node:$offset),
(pre_truncst node:$val, node:$base, node:$offset)> {
- let IsStore = true;
+ let IsStore = true;
let ScalarMemoryVT = i8;
}
def pre_truncstvi16 : PatFrag<(ops node:$val, node:$base, node:$offset),
(pre_truncst node:$val, node:$base, node:$offset)> {
- let IsStore = true;
+ let IsStore = true;
let ScalarMemoryVT = i16;
}
@@ -1218,37 +1218,37 @@ def post_truncst : PatFrag<(ops node:$val, node:$base, node:$offset),
}]>;
def post_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset),
(post_truncst node:$val, node:$base, node:$offset)> {
- let IsStore = true;
+ let IsStore = true;
let MemoryVT = i1;
}
def post_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset),
(post_truncst node:$val, node:$base, node:$offset)> {
- let IsStore = true;
+ let IsStore = true;
let MemoryVT = i8;
}
def post_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset),
(post_truncst node:$val, node:$base, node:$offset)> {
- let IsStore = true;
+ let IsStore = true;
let MemoryVT = i16;
}
def post_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset),
(post_truncst node:$val, node:$base, node:$offset)> {
- let IsStore = true;
+ let IsStore = true;
let MemoryVT = i32;
}
def post_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset),
(post_truncst node:$val, node:$base, node:$offset)> {
- let IsStore = true;
+ let IsStore = true;
let MemoryVT = f32;
}
def post_truncstvi8 : PatFrag<(ops node:$val, node:$base, node:$offset),
(post_truncst node:$val, node:$base, node:$offset)> {
- let IsStore = true;
+ let IsStore = true;
let ScalarMemoryVT = i8;
}
def post_truncstvi16 : PatFrag<(ops node:$val, node:$base, node:$offset),
(post_truncst node:$val, node:$base, node:$offset)> {
- let IsStore = true;
+ let IsStore = true;
let ScalarMemoryVT = i16;
}
@@ -1445,88 +1445,88 @@ def any_sint_to_fp : PatFrags<(ops node:$src),
def any_uint_to_fp : PatFrags<(ops node:$src),
[(strict_uint_to_fp node:$src),
(uint_to_fp node:$src)]>;
-def any_fsetcc : PatFrags<(ops node:$lhs, node:$rhs, node:$pred),
- [(strict_fsetcc node:$lhs, node:$rhs, node:$pred),
- (setcc node:$lhs, node:$rhs, node:$pred)]>;
-def any_fsetccs : PatFrags<(ops node:$lhs, node:$rhs, node:$pred),
- [(strict_fsetccs node:$lhs, node:$rhs, node:$pred),
- (setcc node:$lhs, node:$rhs, node:$pred)]>;
+def any_fsetcc : PatFrags<(ops node:$lhs, node:$rhs, node:$pred),
+ [(strict_fsetcc node:$lhs, node:$rhs, node:$pred),
+ (setcc node:$lhs, node:$rhs, node:$pred)]>;
+def any_fsetccs : PatFrags<(ops node:$lhs, node:$rhs, node:$pred),
+ [(strict_fsetccs node:$lhs, node:$rhs, node:$pred),
+ (setcc node:$lhs, node:$rhs, node:$pred)]>;
multiclass binary_atomic_op_ord<SDNode atomic_op> {
def NAME#_monotonic : PatFrag<(ops node:$ptr, node:$val),
(!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> {
- let IsAtomic = true;
- let IsAtomicOrderingMonotonic = true;
+ let IsAtomic = true;
+ let IsAtomicOrderingMonotonic = true;
}
def NAME#_acquire : PatFrag<(ops node:$ptr, node:$val),
(!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> {
- let IsAtomic = true;
- let IsAtomicOrderingAcquire = true;
+ let IsAtomic = true;
+ let IsAtomicOrderingAcquire = true;
}
def NAME#_release : PatFrag<(ops node:$ptr, node:$val),
(!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> {
- let IsAtomic = true;
- let IsAtomicOrderingRelease = true;
+ let IsAtomic = true;
+ let IsAtomicOrderingRelease = true;
}
def NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$val),
(!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> {
- let IsAtomic = true;
- let IsAtomicOrderingAcquireRelease = true;
+ let IsAtomic = true;
+ let IsAtomicOrderingAcquireRelease = true;
}
def NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$val),
(!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> {
- let IsAtomic = true;
- let IsAtomicOrderingSequentiallyConsistent = true;
+ let IsAtomic = true;
+ let IsAtomicOrderingSequentiallyConsistent = true;
}
}
multiclass ternary_atomic_op_ord<SDNode atomic_op> {
def NAME#_monotonic : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
(!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> {
- let IsAtomic = true;
- let IsAtomicOrderingMonotonic = true;
+ let IsAtomic = true;
+ let IsAtomicOrderingMonotonic = true;
}
def NAME#_acquire : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
(!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> {
- let IsAtomic = true;
- let IsAtomicOrderingAcquire = true;
+ let IsAtomic = true;
+ let IsAtomicOrderingAcquire = true;
}
def NAME#_release : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
(!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> {
- let IsAtomic = true;
- let IsAtomicOrderingRelease = true;
+ let IsAtomic = true;
+ let IsAtomicOrderingRelease = true;
}
def NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
(!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> {
- let IsAtomic = true;
- let IsAtomicOrderingAcquireRelease = true;
+ let IsAtomic = true;
+ let IsAtomicOrderingAcquireRelease = true;
}
def NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
(!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> {
- let IsAtomic = true;
- let IsAtomicOrderingSequentiallyConsistent = true;
+ let IsAtomic = true;
+ let IsAtomicOrderingSequentiallyConsistent = true;
}
}
multiclass binary_atomic_op<SDNode atomic_op, bit IsInt = 1> {
def _8 : PatFrag<(ops node:$ptr, node:$val),
(atomic_op node:$ptr, node:$val)> {
- let IsAtomic = true;
+ let IsAtomic = true;
let MemoryVT = !if(IsInt, i8, ?);
}
def _16 : PatFrag<(ops node:$ptr, node:$val),
(atomic_op node:$ptr, node:$val)> {
- let IsAtomic = true;
+ let IsAtomic = true;
let MemoryVT = !if(IsInt, i16, f16);
}
def _32 : PatFrag<(ops node:$ptr, node:$val),
(atomic_op node:$ptr, node:$val)> {
- let IsAtomic = true;
+ let IsAtomic = true;
let MemoryVT = !if(IsInt, i32, f32);
}
def _64 : PatFrag<(ops node:$ptr, node:$val),
(atomic_op node:$ptr, node:$val)> {
- let IsAtomic = true;
+ let IsAtomic = true;
let MemoryVT = !if(IsInt, i64, f64);
}
@@ -1539,22 +1539,22 @@ multiclass binary_atomic_op<SDNode atomic_op, bit IsInt = 1> {
multiclass ternary_atomic_op<SDNode atomic_op> {
def _8 : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
(atomic_op node:$ptr, node:$cmp, node:$val)> {
- let IsAtomic = true;
+ let IsAtomic = true;
let MemoryVT = i8;
}
def _16 : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
(atomic_op node:$ptr, node:$cmp, node:$val)> {
- let IsAtomic = true;
+ let IsAtomic = true;
let MemoryVT = i16;
}
def _32 : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
(atomic_op node:$ptr, node:$cmp, node:$val)> {
- let IsAtomic = true;
+ let IsAtomic = true;
let MemoryVT = i32;
}
def _64 : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
(atomic_op node:$ptr, node:$cmp, node:$val)> {
- let IsAtomic = true;
+ let IsAtomic = true;
let MemoryVT = i64;
}
@@ -1582,25 +1582,25 @@ defm atomic_cmp_swap : ternary_atomic_op<atomic_cmp_swap>;
def atomic_load_8 :
PatFrag<(ops node:$ptr),
(atomic_load node:$ptr)> {
- let IsAtomic = true;
+ let IsAtomic = true;
let MemoryVT = i8;
}
def atomic_load_16 :
PatFrag<(ops node:$ptr),
(atomic_load node:$ptr)> {
- let IsAtomic = true;
+ let IsAtomic = true;
let MemoryVT = i16;
}
def atomic_load_32 :
PatFrag<(ops node:$ptr),
(atomic_load node:$ptr)> {
- let IsAtomic = true;
+ let IsAtomic = true;
let MemoryVT = i32;
}
def atomic_load_64 :
PatFrag<(ops node:$ptr),
(atomic_load node:$ptr)> {
- let IsAtomic = true;
+ let IsAtomic = true;
let MemoryVT = i64;
}
diff --git a/contrib/libs/llvm12/include/llvm/Testing/Support/SupportHelpers.h b/contrib/libs/llvm12/include/llvm/Testing/Support/SupportHelpers.h
index e2f616fac7..fd732dd15f 100644
--- a/contrib/libs/llvm12/include/llvm/Testing/Support/SupportHelpers.h
+++ b/contrib/libs/llvm12/include/llvm/Testing/Support/SupportHelpers.h
@@ -19,8 +19,8 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Error.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/raw_os_ostream.h"
#include "gmock/gmock-matchers.h"
#include "gtest/gtest-printers.h"
@@ -112,143 +112,143 @@ detail::ValueIsMatcher<InnerMatcher> ValueIs(const InnerMatcher &ValueMatcher) {
return detail::ValueIsMatcher<InnerMatcher>(ValueMatcher);
}
namespace unittest {
-
+
SmallString<128> getInputFileDirectory(const char *Argv0);
-
-/// A RAII object that creates a temporary directory upon initialization and
-/// removes it upon destruction.
-class TempDir {
- SmallString<128> Path;
-
-public:
- /// Creates a managed temporary directory.
- ///
- /// @param Name The name of the directory to create.
- /// @param Unique If true, the directory will be created using
- /// llvm::sys::fs::createUniqueDirectory.
- explicit TempDir(StringRef Name, bool Unique = false) {
- std::error_code EC;
- if (Unique) {
- EC = llvm::sys::fs::createUniqueDirectory(Name, Path);
- if (!EC) {
- // Resolve any symlinks in the new directory.
- std::string UnresolvedPath(Path.str());
- EC = llvm::sys::fs::real_path(UnresolvedPath, Path);
- }
- } else {
- Path = Name;
- EC = llvm::sys::fs::create_directory(Path);
- }
- if (EC)
- Path.clear();
- EXPECT_FALSE(EC) << EC.message();
- }
-
- ~TempDir() {
- if (!Path.empty()) {
- EXPECT_FALSE(llvm::sys::fs::remove_directories(Path.str()));
- }
- }
-
- TempDir(const TempDir &) = delete;
- TempDir &operator=(const TempDir &) = delete;
-
- TempDir(TempDir &&) = default;
- TempDir &operator=(TempDir &&) = default;
-
- /// The path to the temporary directory.
- StringRef path() const { return Path; }
-
- /// The null-terminated C string pointing to the path.
- const char *c_str() { return Path.c_str(); }
-
- /// Creates a new path by appending the argument to the path of the managed
- /// directory using the native path separator.
- SmallString<128> path(StringRef component) const {
- SmallString<128> Result(Path);
- SmallString<128> ComponentToAppend(component);
- llvm::sys::path::native(ComponentToAppend);
- llvm::sys::path::append(Result, Twine(ComponentToAppend));
- return Result;
- }
-};
-
-/// A RAII object that creates a link upon initialization and
-/// removes it upon destruction.
-///
-/// The link may be a soft or a hard link, depending on the platform.
-class TempLink {
- SmallString<128> Path;
-
-public:
- /// Creates a managed link at path Link pointing to Target.
- TempLink(StringRef Target, StringRef Link) {
- Path = Link;
- std::error_code EC = sys::fs::create_link(Target, Link);
- if (EC)
- Path.clear();
- EXPECT_FALSE(EC);
- }
- ~TempLink() {
- if (!Path.empty()) {
- EXPECT_FALSE(llvm::sys::fs::remove(Path.str()));
- }
- }
-
- TempLink(const TempLink &) = delete;
- TempLink &operator=(const TempLink &) = delete;
-
- TempLink(TempLink &&) = default;
- TempLink &operator=(TempLink &&) = default;
-
- /// The path to the link.
- StringRef path() const { return Path; }
-};
-
-/// A RAII object that creates a file upon initialization and
-/// removes it upon destruction.
-class TempFile {
- SmallString<128> Path;
-
-public:
- /// Creates a managed file.
- ///
- /// @param Name The name of the file to create.
- /// @param Contents The string to write to the file.
- /// @param Unique If true, the file will be created using
- /// llvm::sys::fs::createTemporaryFile.
- TempFile(StringRef Name, StringRef Suffix = "", StringRef Contents = "",
- bool Unique = false) {
- std::error_code EC;
- int fd;
- if (Unique) {
- EC = llvm::sys::fs::createTemporaryFile(Name, Suffix, fd, Path);
- } else {
- Path = Name;
- if (!Suffix.empty()) {
- Path.append(".");
- Path.append(Suffix);
- }
- EC = llvm::sys::fs::openFileForWrite(Path, fd);
- }
- EXPECT_FALSE(EC);
- raw_fd_ostream OS(fd, /*shouldClose*/ true);
- OS << Contents;
- OS.flush();
- EXPECT_FALSE(OS.error());
- if (EC || OS.error())
- Path.clear();
- }
- ~TempFile() {
- if (!Path.empty()) {
- EXPECT_FALSE(llvm::sys::fs::remove(Path.str()));
- }
- }
-
- /// The path to the file.
- StringRef path() const { return Path; }
-};
-
+
+/// A RAII object that creates a temporary directory upon initialization and
+/// removes it upon destruction.
+class TempDir {
+ SmallString<128> Path;
+
+public:
+ /// Creates a managed temporary directory.
+ ///
+ /// @param Name The name of the directory to create.
+ /// @param Unique If true, the directory will be created using
+ /// llvm::sys::fs::createUniqueDirectory.
+ explicit TempDir(StringRef Name, bool Unique = false) {
+ std::error_code EC;
+ if (Unique) {
+ EC = llvm::sys::fs::createUniqueDirectory(Name, Path);
+ if (!EC) {
+ // Resolve any symlinks in the new directory.
+ std::string UnresolvedPath(Path.str());
+ EC = llvm::sys::fs::real_path(UnresolvedPath, Path);
+ }
+ } else {
+ Path = Name;
+ EC = llvm::sys::fs::create_directory(Path);
+ }
+ if (EC)
+ Path.clear();
+ EXPECT_FALSE(EC) << EC.message();
+ }
+
+ ~TempDir() {
+ if (!Path.empty()) {
+ EXPECT_FALSE(llvm::sys::fs::remove_directories(Path.str()));
+ }
+ }
+
+ TempDir(const TempDir &) = delete;
+ TempDir &operator=(const TempDir &) = delete;
+
+ TempDir(TempDir &&) = default;
+ TempDir &operator=(TempDir &&) = default;
+
+ /// The path to the temporary directory.
+ StringRef path() const { return Path; }
+
+ /// The null-terminated C string pointing to the path.
+ const char *c_str() { return Path.c_str(); }
+
+ /// Creates a new path by appending the argument to the path of the managed
+ /// directory using the native path separator.
+ SmallString<128> path(StringRef component) const {
+ SmallString<128> Result(Path);
+ SmallString<128> ComponentToAppend(component);
+ llvm::sys::path::native(ComponentToAppend);
+ llvm::sys::path::append(Result, Twine(ComponentToAppend));
+ return Result;
+ }
+};
+
+/// A RAII object that creates a link upon initialization and
+/// removes it upon destruction.
+///
+/// The link may be a soft or a hard link, depending on the platform.
+class TempLink {
+ SmallString<128> Path;
+
+public:
+ /// Creates a managed link at path Link pointing to Target.
+ TempLink(StringRef Target, StringRef Link) {
+ Path = Link;
+ std::error_code EC = sys::fs::create_link(Target, Link);
+ if (EC)
+ Path.clear();
+ EXPECT_FALSE(EC);
+ }
+ ~TempLink() {
+ if (!Path.empty()) {
+ EXPECT_FALSE(llvm::sys::fs::remove(Path.str()));
+ }
+ }
+
+ TempLink(const TempLink &) = delete;
+ TempLink &operator=(const TempLink &) = delete;
+
+ TempLink(TempLink &&) = default;
+ TempLink &operator=(TempLink &&) = default;
+
+ /// The path to the link.
+ StringRef path() const { return Path; }
+};
+
+/// A RAII object that creates a file upon initialization and
+/// removes it upon destruction.
+class TempFile {
+ SmallString<128> Path;
+
+public:
+ /// Creates a managed file.
+ ///
+ /// @param Name The name of the file to create.
+ /// @param Contents The string to write to the file.
+ /// @param Unique If true, the file will be created using
+ /// llvm::sys::fs::createTemporaryFile.
+ TempFile(StringRef Name, StringRef Suffix = "", StringRef Contents = "",
+ bool Unique = false) {
+ std::error_code EC;
+ int fd;
+ if (Unique) {
+ EC = llvm::sys::fs::createTemporaryFile(Name, Suffix, fd, Path);
+ } else {
+ Path = Name;
+ if (!Suffix.empty()) {
+ Path.append(".");
+ Path.append(Suffix);
+ }
+ EC = llvm::sys::fs::openFileForWrite(Path, fd);
+ }
+ EXPECT_FALSE(EC);
+ raw_fd_ostream OS(fd, /*shouldClose*/ true);
+ OS << Contents;
+ OS.flush();
+ EXPECT_FALSE(OS.error());
+ if (EC || OS.error())
+ Path.clear();
+ }
+ ~TempFile() {
+ if (!Path.empty()) {
+ EXPECT_FALSE(llvm::sys::fs::remove(Path.str()));
+ }
+ }
+
+ /// The path to the file.
+ StringRef path() const { return Path; }
+};
+
} // namespace unittest
} // namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/TextAPI/MachO/Platform.h b/contrib/libs/llvm12/include/llvm/TextAPI/MachO/Platform.h
index ed1ea07e8b..80708443b1 100644
--- a/contrib/libs/llvm12/include/llvm/TextAPI/MachO/Platform.h
+++ b/contrib/libs/llvm12/include/llvm/TextAPI/MachO/Platform.h
@@ -36,8 +36,8 @@ enum class PlatformKind : unsigned {
macCatalyst = MachO::PLATFORM_MACCATALYST,
iOSSimulator = MachO::PLATFORM_IOSSIMULATOR,
tvOSSimulator = MachO::PLATFORM_TVOSSIMULATOR,
- watchOSSimulator = MachO::PLATFORM_WATCHOSSIMULATOR,
- driverKit = MachO::PLATFORM_DRIVERKIT,
+ watchOSSimulator = MachO::PLATFORM_WATCHOSSIMULATOR,
+ driverKit = MachO::PLATFORM_DRIVERKIT,
};
using PlatformSet = SmallSet<PlatformKind, 3>;
@@ -51,7 +51,7 @@ StringRef getPlatformName(PlatformKind Platform);
} // end namespace llvm.
#endif // LLVM_TEXTAPI_MACHO_PLATFORM_H
-
+
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Coroutines.h b/contrib/libs/llvm12/include/llvm/Transforms/Coroutines.h
index 2dbf762461..e0cc7db8cd 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Coroutines.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Coroutines.h
@@ -30,7 +30,7 @@ void addCoroutinePassesToExtensionPoints(PassManagerBuilder &Builder);
Pass *createCoroEarlyLegacyPass();
/// Split up coroutines into multiple functions driving their state machines.
-Pass *createCoroSplitLegacyPass(bool ReuseFrameSlot = false);
+Pass *createCoroSplitLegacyPass(bool ReuseFrameSlot = false);
/// Analyze coroutines use sites, devirtualize resume/destroy calls and elide
/// heap allocation for coroutine frame where possible.
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroCleanup.h b/contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroCleanup.h
index a7f525fe9d..c7031cf032 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroCleanup.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroCleanup.h
@@ -29,7 +29,7 @@ class Function;
struct CoroCleanupPass : PassInfoMixin<CoroCleanupPass> {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroEarly.h b/contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroEarly.h
index 6d6e4907c8..fe343cd386 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroEarly.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroEarly.h
@@ -32,7 +32,7 @@ class Function;
struct CoroEarlyPass : PassInfoMixin<CoroEarlyPass> {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroElide.h b/contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroElide.h
index af75801fc8..cc469fa2c8 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroElide.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroElide.h
@@ -31,7 +31,7 @@ class Function;
struct CoroElidePass : PassInfoMixin<CoroElidePass> {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroSplit.h b/contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroSplit.h
index ed26d9bb64..c5268f2ef6 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroSplit.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Coroutines/CoroSplit.h
@@ -29,13 +29,13 @@
namespace llvm {
struct CoroSplitPass : PassInfoMixin<CoroSplitPass> {
- CoroSplitPass(bool ReuseFrameSlot = false) : ReuseFrameSlot(ReuseFrameSlot) {}
-
+ CoroSplitPass(bool ReuseFrameSlot = false) : ReuseFrameSlot(ReuseFrameSlot) {}
+
PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
LazyCallGraph &CG, CGSCCUpdateResult &UR);
- static bool isRequired() { return true; }
-
- bool ReuseFrameSlot;
+ static bool isRequired() { return true; }
+
+ bool ReuseFrameSlot;
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/HelloNew/HelloWorld.h b/contrib/libs/llvm12/include/llvm/Transforms/HelloNew/HelloWorld.h
index c25f3ccfb6..7421f01864 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/HelloNew/HelloWorld.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/HelloNew/HelloWorld.h
@@ -1,34 +1,34 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===-- HelloWorld.h - Example Transformations ------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_HELLONEW_HELLOWORLD_H
-#define LLVM_TRANSFORMS_HELLONEW_HELLOWORLD_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-
-class HelloWorldPass : public PassInfoMixin<HelloWorldPass> {
-public:
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-
-} // namespace llvm
-
-#endif // LLVM_TRANSFORMS_HELLONEW_HELLOWORLD_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===-- HelloWorld.h - Example Transformations ------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_HELLONEW_HELLOWORLD_H
+#define LLVM_TRANSFORMS_HELLONEW_HELLOWORLD_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class HelloWorldPass : public PassInfoMixin<HelloWorldPass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_HELLONEW_HELLOWORLD_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/IPO.h b/contrib/libs/llvm12/include/llvm/Transforms/IPO.h
index c270acfe87..79b0313aea 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/IPO.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/IPO.h
@@ -38,13 +38,13 @@ class raw_ostream;
//===----------------------------------------------------------------------===//
//
-// This pass adds !annotation metadata to entries in the
-// @llvm.global.annotations global constant.
-//
-ModulePass *createAnnotation2MetadataLegacyPass();
-
-//===----------------------------------------------------------------------===//
-//
+// This pass adds !annotation metadata to entries in the
+// @llvm.global.annotations global constant.
+//
+ModulePass *createAnnotation2MetadataLegacyPass();
+
+//===----------------------------------------------------------------------===//
+//
// These functions removes symbols from functions and modules. If OnlyDebugInfo
// is true, only debugging information is removed from the module.
//
@@ -223,11 +223,11 @@ ModulePass *createMergeFunctionsPass();
ModulePass *createHotColdSplittingPass();
//===----------------------------------------------------------------------===//
-/// createIROutlinerPass - This pass finds similar code regions and factors
-/// those regions out into functions.
-ModulePass *createIROutlinerPass();
-
-//===----------------------------------------------------------------------===//
+/// createIROutlinerPass - This pass finds similar code regions and factors
+/// those regions out into functions.
+ModulePass *createIROutlinerPass();
+
+//===----------------------------------------------------------------------===//
/// createPartialInliningPass - This pass inlines parts of functions.
///
ModulePass *createPartialInliningPass();
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/IPO/AlwaysInliner.h b/contrib/libs/llvm12/include/llvm/Transforms/IPO/AlwaysInliner.h
index 4a9764b855..06ae0fecb4 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/IPO/AlwaysInliner.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/IPO/AlwaysInliner.h
@@ -41,7 +41,7 @@ public:
: InsertLifetime(InsertLifetime) {}
PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
};
/// Create a legacy pass manager instance of a pass to inline and remove
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/IPO/Annotation2Metadata.h b/contrib/libs/llvm12/include/llvm/Transforms/IPO/Annotation2Metadata.h
index 198d4cfc2c..17740ca383 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/IPO/Annotation2Metadata.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/IPO/Annotation2Metadata.h
@@ -1,41 +1,41 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- Annotation2Metadata.h - Add !annotation metadata. --------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// New pass manager pass to convert @llvm.global.annotations to !annotation
-// metadata.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_IPO_ANNOTATION2METADATA_H
-#define LLVM_TRANSFORMS_IPO_ANNOTATION2METADATA_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-
-class Module;
-
-/// Pass to convert @llvm.global.annotations to !annotation metadata.
-struct Annotation2MetadataPass : public PassInfoMixin<Annotation2MetadataPass> {
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-};
-
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_IPO_SCCP_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- Annotation2Metadata.h - Add !annotation metadata. --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// New pass manager pass to convert @llvm.global.annotations to !annotation
+// metadata.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_ANNOTATION2METADATA_H
+#define LLVM_TRANSFORMS_IPO_ANNOTATION2METADATA_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Module;
+
+/// Pass to convert @llvm.global.annotations to !annotation metadata.
+struct Annotation2MetadataPass : public PassInfoMixin<Annotation2MetadataPass> {
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_SCCP_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/IPO/Attributor.h b/contrib/libs/llvm12/include/llvm/Transforms/IPO/Attributor.h
index fd82945466..96681071db 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/IPO/Attributor.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/IPO/Attributor.h
@@ -104,10 +104,10 @@
#ifndef LLVM_TRANSFORMS_IPO_ATTRIBUTOR_H
#define LLVM_TRANSFORMS_IPO_ATTRIBUTOR_H
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/Analysis/AssumeBundleQueries.h"
#include "llvm/Analysis/CFG.h"
@@ -121,27 +121,27 @@
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/TimeProfiler.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/TimeProfiler.h"
#include "llvm/Transforms/Utils/CallGraphUpdater.h"
namespace llvm {
-struct AADepGraphNode;
-struct AADepGraph;
+struct AADepGraphNode;
+struct AADepGraph;
struct Attributor;
struct AbstractAttribute;
struct InformationCache;
struct AAIsDead;
-class AAManager;
-class AAResults;
+class AAManager;
+class AAResults;
class Function;
-/// The value passed to the line option that defines the maximal initialization
-/// chain length.
-extern unsigned MaxInitializationChainLength;
-
+/// The value passed to the line option that defines the maximal initialization
+/// chain length.
+extern unsigned MaxInitializationChainLength;
+
///{
enum class ChangeStatus {
CHANGED,
@@ -157,74 +157,74 @@ enum class DepClassTy {
};
///}
-/// The data structure for the nodes of a dependency graph
-struct AADepGraphNode {
-public:
- virtual ~AADepGraphNode(){};
- using DepTy = PointerIntPair<AADepGraphNode *, 1>;
-
-protected:
- /// Set of dependency graph nodes which should be updated if this one
- /// is updated. The bit encodes if it is optional.
- TinyPtrVector<DepTy> Deps;
-
- static AADepGraphNode *DepGetVal(DepTy &DT) { return DT.getPointer(); }
- static AbstractAttribute *DepGetValAA(DepTy &DT) {
- return cast<AbstractAttribute>(DT.getPointer());
- }
-
- operator AbstractAttribute *() { return cast<AbstractAttribute>(this); }
-
-public:
- using iterator =
- mapped_iterator<TinyPtrVector<DepTy>::iterator, decltype(&DepGetVal)>;
- using aaiterator =
- mapped_iterator<TinyPtrVector<DepTy>::iterator, decltype(&DepGetValAA)>;
-
- aaiterator begin() { return aaiterator(Deps.begin(), &DepGetValAA); }
- aaiterator end() { return aaiterator(Deps.end(), &DepGetValAA); }
- iterator child_begin() { return iterator(Deps.begin(), &DepGetVal); }
- iterator child_end() { return iterator(Deps.end(), &DepGetVal); }
-
- virtual void print(raw_ostream &OS) const { OS << "AADepNode Impl\n"; }
- TinyPtrVector<DepTy> &getDeps() { return Deps; }
-
- friend struct Attributor;
- friend struct AADepGraph;
-};
-
-/// The data structure for the dependency graph
-///
-/// Note that in this graph if there is an edge from A to B (A -> B),
-/// then it means that B depends on A, and when the state of A is
-/// updated, node B should also be updated
-struct AADepGraph {
- AADepGraph() {}
- ~AADepGraph() {}
-
- using DepTy = AADepGraphNode::DepTy;
- static AADepGraphNode *DepGetVal(DepTy &DT) { return DT.getPointer(); }
- using iterator =
- mapped_iterator<TinyPtrVector<DepTy>::iterator, decltype(&DepGetVal)>;
-
- /// There is no root node for the dependency graph. But the SCCIterator
- /// requires a single entry point, so we maintain a fake("synthetic") root
- /// node that depends on every node.
- AADepGraphNode SyntheticRoot;
- AADepGraphNode *GetEntryNode() { return &SyntheticRoot; }
-
- iterator begin() { return SyntheticRoot.child_begin(); }
- iterator end() { return SyntheticRoot.child_end(); }
-
- void viewGraph();
-
- /// Dump graph to file
- void dumpGraph();
-
- /// Print dependency graph
- void print();
-};
-
+/// The data structure for the nodes of a dependency graph
+struct AADepGraphNode {
+public:
+ virtual ~AADepGraphNode(){};
+ using DepTy = PointerIntPair<AADepGraphNode *, 1>;
+
+protected:
+ /// Set of dependency graph nodes which should be updated if this one
+ /// is updated. The bit encodes if it is optional.
+ TinyPtrVector<DepTy> Deps;
+
+ static AADepGraphNode *DepGetVal(DepTy &DT) { return DT.getPointer(); }
+ static AbstractAttribute *DepGetValAA(DepTy &DT) {
+ return cast<AbstractAttribute>(DT.getPointer());
+ }
+
+ operator AbstractAttribute *() { return cast<AbstractAttribute>(this); }
+
+public:
+ using iterator =
+ mapped_iterator<TinyPtrVector<DepTy>::iterator, decltype(&DepGetVal)>;
+ using aaiterator =
+ mapped_iterator<TinyPtrVector<DepTy>::iterator, decltype(&DepGetValAA)>;
+
+ aaiterator begin() { return aaiterator(Deps.begin(), &DepGetValAA); }
+ aaiterator end() { return aaiterator(Deps.end(), &DepGetValAA); }
+ iterator child_begin() { return iterator(Deps.begin(), &DepGetVal); }
+ iterator child_end() { return iterator(Deps.end(), &DepGetVal); }
+
+ virtual void print(raw_ostream &OS) const { OS << "AADepNode Impl\n"; }
+ TinyPtrVector<DepTy> &getDeps() { return Deps; }
+
+ friend struct Attributor;
+ friend struct AADepGraph;
+};
+
+/// The data structure for the dependency graph
+///
+/// Note that in this graph if there is an edge from A to B (A -> B),
+/// then it means that B depends on A, and when the state of A is
+/// updated, node B should also be updated
+struct AADepGraph {
+ AADepGraph() {}
+ ~AADepGraph() {}
+
+ using DepTy = AADepGraphNode::DepTy;
+ static AADepGraphNode *DepGetVal(DepTy &DT) { return DT.getPointer(); }
+ using iterator =
+ mapped_iterator<TinyPtrVector<DepTy>::iterator, decltype(&DepGetVal)>;
+
+ /// There is no root node for the dependency graph. But the SCCIterator
+ /// requires a single entry point, so we maintain a fake("synthetic") root
+ /// node that depends on every node.
+ AADepGraphNode SyntheticRoot;
+ AADepGraphNode *GetEntryNode() { return &SyntheticRoot; }
+
+ iterator begin() { return SyntheticRoot.child_begin(); }
+ iterator end() { return SyntheticRoot.child_end(); }
+
+ void viewGraph();
+
+ /// Dump graph to file
+ void dumpGraph();
+
+ /// Print dependency graph
+ void print();
+};
+
/// Helper to describe and deal with positions in the LLVM-IR.
///
/// A position in the IR is described by an anchor value and an "offset" that
@@ -344,14 +344,14 @@ struct IRPosition {
/// Return the associated function, if any.
Function *getAssociatedFunction() const {
- if (auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
- // We reuse the logic that associates callback calles to arguments of a
- // call site here to identify the callback callee as the associated
- // function.
- if (Argument *Arg = getAssociatedArgument())
- return Arg->getParent();
+ if (auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
+ // We reuse the logic that associates callback calles to arguments of a
+ // call site here to identify the callback callee as the associated
+ // function.
+ if (Argument *Arg = getAssociatedArgument())
+ return Arg->getParent();
return CB->getCalledFunction();
- }
+ }
return getAnchorScope();
}
@@ -399,11 +399,11 @@ struct IRPosition {
/// Return the value this abstract attribute is associated with.
Value &getAssociatedValue() const {
- if (getCallSiteArgNo() < 0 || isa<Argument>(&getAnchorValue()))
+ if (getCallSiteArgNo() < 0 || isa<Argument>(&getAnchorValue()))
return getAnchorValue();
assert(isa<CallBase>(&getAnchorValue()) && "Expected a call base!");
- return *cast<CallBase>(&getAnchorValue())
- ->getArgOperand(getCallSiteArgNo());
+ return *cast<CallBase>(&getAnchorValue())
+ ->getArgOperand(getCallSiteArgNo());
}
/// Return the type this abstract attribute is associated with.
@@ -413,24 +413,24 @@ struct IRPosition {
return getAssociatedValue().getType();
}
- /// Return the callee argument number of the associated value if it is an
- /// argument or call site argument, otherwise a negative value. In contrast to
- /// `getCallSiteArgNo` this method will always return the "argument number"
- /// from the perspective of the callee. This may not the same as the call site
- /// if this is a callback call.
- int getCalleeArgNo() const {
- return getArgNo(/* CallbackCalleeArgIfApplicable */ true);
- }
-
- /// Return the call site argument number of the associated value if it is an
- /// argument or call site argument, otherwise a negative value. In contrast to
- /// `getCalleArgNo` this method will always return the "operand number" from
- /// the perspective of the call site. This may not the same as the callee
- /// perspective if this is a callback call.
- int getCallSiteArgNo() const {
- return getArgNo(/* CallbackCalleeArgIfApplicable */ false);
- }
-
+ /// Return the callee argument number of the associated value if it is an
+ /// argument or call site argument, otherwise a negative value. In contrast to
+ /// `getCallSiteArgNo` this method will always return the "argument number"
+ /// from the perspective of the callee. This may not the same as the call site
+ /// if this is a callback call.
+ int getCalleeArgNo() const {
+ return getArgNo(/* CallbackCalleeArgIfApplicable */ true);
+ }
+
+ /// Return the call site argument number of the associated value if it is an
+ /// argument or call site argument, otherwise a negative value. In contrast to
+ /// `getCalleArgNo` this method will always return the "operand number" from
+ /// the perspective of the call site. This may not the same as the callee
+ /// perspective if this is a callback call.
+ int getCallSiteArgNo() const {
+ return getArgNo(/* CallbackCalleeArgIfApplicable */ false);
+ }
+
/// Return the index in the attribute list for this position.
unsigned getAttrIdx() const {
switch (getPositionKind()) {
@@ -445,7 +445,7 @@ struct IRPosition {
return AttributeList::ReturnIndex;
case IRPosition::IRP_ARGUMENT:
case IRPosition::IRP_CALL_SITE_ARGUMENT:
- return getCallSiteArgNo() + AttributeList::FirstArgIndex;
+ return getCallSiteArgNo() + AttributeList::FirstArgIndex;
}
llvm_unreachable(
"There is no attribute index for a floating or invalid position!");
@@ -530,17 +530,17 @@ struct IRPosition {
}
}
- /// Return true if the position is an argument or call site argument.
- bool isArgumentPosition() const {
- switch (getPositionKind()) {
- case IRPosition::IRP_ARGUMENT:
- case IRPosition::IRP_CALL_SITE_ARGUMENT:
- return true;
- default:
- return false;
- }
- }
-
+ /// Return true if the position is an argument or call site argument.
+ bool isArgumentPosition() const {
+ switch (getPositionKind()) {
+ case IRPosition::IRP_ARGUMENT:
+ case IRPosition::IRP_CALL_SITE_ARGUMENT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
/// Special DenseMap key values.
///
///{
@@ -587,25 +587,25 @@ private:
verify();
}
- /// Return the callee argument number of the associated value if it is an
- /// argument or call site argument. See also `getCalleeArgNo` and
- /// `getCallSiteArgNo`.
- int getArgNo(bool CallbackCalleeArgIfApplicable) const {
- if (CallbackCalleeArgIfApplicable)
- if (Argument *Arg = getAssociatedArgument())
- return Arg->getArgNo();
- switch (getPositionKind()) {
- case IRPosition::IRP_ARGUMENT:
- return cast<Argument>(getAsValuePtr())->getArgNo();
- case IRPosition::IRP_CALL_SITE_ARGUMENT: {
- Use &U = *getAsUsePtr();
- return cast<CallBase>(U.getUser())->getArgOperandNo(&U);
- }
- default:
- return -1;
- }
- }
-
+ /// Return the callee argument number of the associated value if it is an
+ /// argument or call site argument. See also `getCalleeArgNo` and
+ /// `getCallSiteArgNo`.
+ int getArgNo(bool CallbackCalleeArgIfApplicable) const {
+ if (CallbackCalleeArgIfApplicable)
+ if (Argument *Arg = getAssociatedArgument())
+ return Arg->getArgNo();
+ switch (getPositionKind()) {
+ case IRPosition::IRP_ARGUMENT:
+ return cast<Argument>(getAsValuePtr())->getArgNo();
+ case IRPosition::IRP_CALL_SITE_ARGUMENT: {
+ Use &U = *getAsUsePtr();
+ return cast<CallBase>(U.getUser())->getArgOperandNo(&U);
+ }
+ default:
+ return -1;
+ }
+ }
+
/// IRPosition for the use \p U. The position kind \p PK needs to be
/// IRP_CALL_SITE_ARGUMENT, the anchor value is the user, the associated value
/// the used value.
@@ -769,10 +769,10 @@ struct InformationCache {
[&](const Function &F) {
return AG.getAnalysis<PostDominatorTreeAnalysis>(F);
}),
- AG(AG), CGSCC(CGSCC) {
- if (CGSCC)
- initializeModuleSlice(*CGSCC);
- }
+ AG(AG), CGSCC(CGSCC) {
+ if (CGSCC)
+ initializeModuleSlice(*CGSCC);
+ }
~InformationCache() {
// The FunctionInfo objects are allocated via a BumpPtrAllocator, we call
@@ -781,68 +781,68 @@ struct InformationCache {
It.getSecond()->~FunctionInfo();
}
- /// Apply \p CB to all uses of \p F. If \p LookThroughConstantExprUses is
- /// true, constant expression users are not given to \p CB but their uses are
- /// traversed transitively.
- template <typename CBTy>
- static void foreachUse(Function &F, CBTy CB,
- bool LookThroughConstantExprUses = true) {
- SmallVector<Use *, 8> Worklist(make_pointer_range(F.uses()));
-
- for (unsigned Idx = 0; Idx < Worklist.size(); ++Idx) {
- Use &U = *Worklist[Idx];
-
- // Allow use in constant bitcasts and simply look through them.
- if (LookThroughConstantExprUses && isa<ConstantExpr>(U.getUser())) {
- for (Use &CEU : cast<ConstantExpr>(U.getUser())->uses())
- Worklist.push_back(&CEU);
- continue;
- }
-
- CB(U);
- }
- }
-
- /// Initialize the ModuleSlice member based on \p SCC. ModuleSlices contains
- /// (a subset of) all functions that we can look at during this SCC traversal.
- /// This includes functions (transitively) called from the SCC and the
- /// (transitive) callers of SCC functions. We also can look at a function if
- /// there is a "reference edge", i.a., if the function somehow uses (!=calls)
- /// a function in the SCC or a caller of a function in the SCC.
- void initializeModuleSlice(SetVector<Function *> &SCC) {
- ModuleSlice.insert(SCC.begin(), SCC.end());
-
- SmallPtrSet<Function *, 16> Seen;
- SmallVector<Function *, 16> Worklist(SCC.begin(), SCC.end());
- while (!Worklist.empty()) {
- Function *F = Worklist.pop_back_val();
- ModuleSlice.insert(F);
-
- for (Instruction &I : instructions(*F))
- if (auto *CB = dyn_cast<CallBase>(&I))
- if (Function *Callee = CB->getCalledFunction())
- if (Seen.insert(Callee).second)
- Worklist.push_back(Callee);
- }
-
- Seen.clear();
- Worklist.append(SCC.begin(), SCC.end());
- while (!Worklist.empty()) {
- Function *F = Worklist.pop_back_val();
- ModuleSlice.insert(F);
-
- // Traverse all transitive uses.
- foreachUse(*F, [&](Use &U) {
- if (auto *UsrI = dyn_cast<Instruction>(U.getUser()))
- if (Seen.insert(UsrI->getFunction()).second)
- Worklist.push_back(UsrI->getFunction());
- });
- }
- }
-
- /// The slice of the module we are allowed to look at.
- SmallPtrSet<Function *, 8> ModuleSlice;
-
+ /// Apply \p CB to all uses of \p F. If \p LookThroughConstantExprUses is
+ /// true, constant expression users are not given to \p CB but their uses are
+ /// traversed transitively.
+ template <typename CBTy>
+ static void foreachUse(Function &F, CBTy CB,
+ bool LookThroughConstantExprUses = true) {
+ SmallVector<Use *, 8> Worklist(make_pointer_range(F.uses()));
+
+ for (unsigned Idx = 0; Idx < Worklist.size(); ++Idx) {
+ Use &U = *Worklist[Idx];
+
+ // Allow use in constant bitcasts and simply look through them.
+ if (LookThroughConstantExprUses && isa<ConstantExpr>(U.getUser())) {
+ for (Use &CEU : cast<ConstantExpr>(U.getUser())->uses())
+ Worklist.push_back(&CEU);
+ continue;
+ }
+
+ CB(U);
+ }
+ }
+
+ /// Initialize the ModuleSlice member based on \p SCC. ModuleSlices contains
+ /// (a subset of) all functions that we can look at during this SCC traversal.
+ /// This includes functions (transitively) called from the SCC and the
+ /// (transitive) callers of SCC functions. We also can look at a function if
+ /// there is a "reference edge", i.a., if the function somehow uses (!=calls)
+ /// a function in the SCC or a caller of a function in the SCC.
+ void initializeModuleSlice(SetVector<Function *> &SCC) {
+ ModuleSlice.insert(SCC.begin(), SCC.end());
+
+ SmallPtrSet<Function *, 16> Seen;
+ SmallVector<Function *, 16> Worklist(SCC.begin(), SCC.end());
+ while (!Worklist.empty()) {
+ Function *F = Worklist.pop_back_val();
+ ModuleSlice.insert(F);
+
+ for (Instruction &I : instructions(*F))
+ if (auto *CB = dyn_cast<CallBase>(&I))
+ if (Function *Callee = CB->getCalledFunction())
+ if (Seen.insert(Callee).second)
+ Worklist.push_back(Callee);
+ }
+
+ Seen.clear();
+ Worklist.append(SCC.begin(), SCC.end());
+ while (!Worklist.empty()) {
+ Function *F = Worklist.pop_back_val();
+ ModuleSlice.insert(F);
+
+ // Traverse all transitive uses.
+ foreachUse(*F, [&](Use &U) {
+ if (auto *UsrI = dyn_cast<Instruction>(U.getUser()))
+ if (Seen.insert(UsrI->getFunction()).second)
+ Worklist.push_back(UsrI->getFunction());
+ });
+ }
+ }
+
+ /// The slice of the module we are allowed to look at.
+ SmallPtrSet<Function *, 8> ModuleSlice;
+
/// A vector type to hold instructions.
using InstructionVectorTy = SmallVector<Instruction *, 8>;
@@ -871,7 +871,7 @@ struct InformationCache {
}
/// Return AliasAnalysis Result for function \p F.
- AAResults *getAAResultsForFunction(const Function &F);
+ AAResults *getAAResultsForFunction(const Function &F);
/// Return true if \p Arg is involved in a must-tail call, thus the argument
/// of the caller or callee.
@@ -899,26 +899,26 @@ struct InformationCache {
/// Return the map conaining all the knowledge we have from `llvm.assume`s.
const RetainedKnowledgeMap &getKnowledgeMap() const { return KnowledgeMap; }
- /// Return if \p To is potentially reachable form \p From or not
- /// If the same query was answered, return cached result
- bool getPotentiallyReachable(const Instruction &From, const Instruction &To) {
- auto KeyPair = std::make_pair(&From, &To);
- auto Iter = PotentiallyReachableMap.find(KeyPair);
- if (Iter != PotentiallyReachableMap.end())
- return Iter->second;
- const Function &F = *From.getFunction();
- bool Result = isPotentiallyReachable(
- &From, &To, nullptr, AG.getAnalysis<DominatorTreeAnalysis>(F),
- AG.getAnalysis<LoopAnalysis>(F));
- PotentiallyReachableMap.insert(std::make_pair(KeyPair, Result));
- return Result;
- }
-
- /// Check whether \p F is part of module slice.
- bool isInModuleSlice(const Function &F) {
- return ModuleSlice.count(const_cast<Function *>(&F));
- }
-
+ /// Return if \p To is potentially reachable form \p From or not
+ /// If the same query was answered, return cached result
+ bool getPotentiallyReachable(const Instruction &From, const Instruction &To) {
+ auto KeyPair = std::make_pair(&From, &To);
+ auto Iter = PotentiallyReachableMap.find(KeyPair);
+ if (Iter != PotentiallyReachableMap.end())
+ return Iter->second;
+ const Function &F = *From.getFunction();
+ bool Result = isPotentiallyReachable(
+ &From, &To, nullptr, AG.getAnalysis<DominatorTreeAnalysis>(F),
+ AG.getAnalysis<LoopAnalysis>(F));
+ PotentiallyReachableMap.insert(std::make_pair(KeyPair, Result));
+ return Result;
+ }
+
+ /// Check whether \p F is part of module slice.
+ bool isInModuleSlice(const Function &F) {
+ return ModuleSlice.count(const_cast<Function *>(&F));
+ }
+
private:
struct FunctionInfo {
~FunctionInfo();
@@ -978,10 +978,10 @@ private:
/// Set of inlineable functions
SmallPtrSet<const Function *, 8> InlineableFunctions;
- /// A map for caching results of queries for isPotentiallyReachable
- DenseMap<std::pair<const Instruction *, const Instruction *>, bool>
- PotentiallyReachableMap;
-
+ /// A map for caching results of queries for isPotentiallyReachable
+ DenseMap<std::pair<const Instruction *, const Instruction *>, bool>
+ PotentiallyReachableMap;
+
/// Give the Attributor access to the members so
/// Attributor::identifyDefaultAbstractAttributes(...) can initialize them.
friend struct Attributor;
@@ -1084,7 +1084,7 @@ struct Attributor {
/// attribute. Using this after Attributor started running is restricted to
/// only the Attributor itself. Initial seeding of AAs can be done via this
/// function.
- /// NOTE: ForceUpdate is ignored in any stage other than the update stage.
+ /// NOTE: ForceUpdate is ignored in any stage other than the update stage.
template <typename AAType>
const AAType &getOrCreateAAFor(const IRPosition &IRP,
const AbstractAttribute *QueryingAA = nullptr,
@@ -1092,7 +1092,7 @@ struct Attributor {
DepClassTy DepClass = DepClassTy::OPTIONAL,
bool ForceUpdate = false) {
if (AAType *AAPtr = lookupAAFor<AAType>(IRP, QueryingAA, TrackDependence)) {
- if (ForceUpdate && Phase == AttributorPhase::UPDATE)
+ if (ForceUpdate && Phase == AttributorPhase::UPDATE)
updateAA(*AAPtr);
return *AAPtr;
}
@@ -1102,7 +1102,7 @@ struct Attributor {
auto &AA = AAType::createForPosition(IRP, *this);
// If we are currenty seeding attributes, enforce seeding rules.
- if (Phase == AttributorPhase::SEEDING && !shouldSeedAttribute(AA)) {
+ if (Phase == AttributorPhase::SEEDING && !shouldSeedAttribute(AA)) {
AA.getState().indicatePessimisticFixpoint();
return AA;
}
@@ -1116,9 +1116,9 @@ struct Attributor {
Invalidate |= FnScope->hasFnAttribute(Attribute::Naked) ||
FnScope->hasFnAttribute(Attribute::OptimizeNone);
- // Avoid too many nested initializations to prevent a stack overflow.
- Invalidate |= InitializationChainLength > MaxInitializationChainLength;
-
+ // Avoid too many nested initializations to prevent a stack overflow.
+ Invalidate |= InitializationChainLength > MaxInitializationChainLength;
+
// Bootstrap the new attribute with an initial update to propagate
// information, e.g., function -> call site. If it is not on a given
// Allowed we will not perform updates at all.
@@ -1127,39 +1127,39 @@ struct Attributor {
return AA;
}
- {
- TimeTraceScope TimeScope(AA.getName() + "::initialize");
- ++InitializationChainLength;
- AA.initialize(*this);
- --InitializationChainLength;
- }
-
- // Initialize and update is allowed for code outside of the current function
- // set, but only if it is part of module slice we are allowed to look at.
- // Only exception is AAIsDeadFunction whose initialization is prevented
- // directly, since we don't to compute it twice.
+ {
+ TimeTraceScope TimeScope(AA.getName() + "::initialize");
+ ++InitializationChainLength;
+ AA.initialize(*this);
+ --InitializationChainLength;
+ }
+
+ // Initialize and update is allowed for code outside of the current function
+ // set, but only if it is part of module slice we are allowed to look at.
+ // Only exception is AAIsDeadFunction whose initialization is prevented
+ // directly, since we don't to compute it twice.
if (FnScope && !Functions.count(const_cast<Function *>(FnScope))) {
- if (!getInfoCache().isInModuleSlice(*FnScope)) {
- AA.getState().indicatePessimisticFixpoint();
- return AA;
- }
- }
-
- // If this is queried in the manifest stage, we force the AA to indicate
- // pessimistic fixpoint immediately.
- if (Phase == AttributorPhase::MANIFEST) {
+ if (!getInfoCache().isInModuleSlice(*FnScope)) {
+ AA.getState().indicatePessimisticFixpoint();
+ return AA;
+ }
+ }
+
+ // If this is queried in the manifest stage, we force the AA to indicate
+ // pessimistic fixpoint immediately.
+ if (Phase == AttributorPhase::MANIFEST) {
AA.getState().indicatePessimisticFixpoint();
return AA;
}
// Allow seeded attributes to declare dependencies.
// Remember the seeding state.
- AttributorPhase OldPhase = Phase;
- Phase = AttributorPhase::UPDATE;
+ AttributorPhase OldPhase = Phase;
+ Phase = AttributorPhase::UPDATE;
updateAA(AA);
- Phase = OldPhase;
+ Phase = OldPhase;
if (TrackDependence && AA.getState().isValidState())
recordDependence(AA, const_cast<AbstractAttribute &>(*QueryingAA),
@@ -1228,11 +1228,11 @@ struct Attributor {
assert(!AAPtr && "Attribute already in map!");
AAPtr = &AA;
- // Register AA with the synthetic root only before the manifest stage.
- if (Phase == AttributorPhase::SEEDING || Phase == AttributorPhase::UPDATE)
- DG.SyntheticRoot.Deps.push_back(
- AADepGraphNode::DepTy(&AA, unsigned(DepClassTy::REQUIRED)));
-
+ // Register AA with the synthetic root only before the manifest stage.
+ if (Phase == AttributorPhase::SEEDING || Phase == AttributorPhase::UPDATE)
+ DG.SyntheticRoot.Deps.push_back(
+ AADepGraphNode::DepTy(&AA, unsigned(DepClassTy::REQUIRED)));
+
return AA;
}
@@ -1541,22 +1541,22 @@ struct Attributor {
bool checkForAllReadWriteInstructions(function_ref<bool(Instruction &)> Pred,
AbstractAttribute &QueryingAA);
- /// Create a shallow wrapper for \p F such that \p F has internal linkage
- /// afterwards. It also sets the original \p F 's name to anonymous
- ///
- /// A wrapper is a function with the same type (and attributes) as \p F
- /// that will only call \p F and return the result, if any.
- ///
- /// Assuming the declaration of looks like:
- /// rty F(aty0 arg0, ..., atyN argN);
- ///
- /// The wrapper will then look as follows:
- /// rty wrapper(aty0 arg0, ..., atyN argN) {
- /// return F(arg0, ..., argN);
- /// }
- ///
- static void createShallowWrapper(Function &F);
-
+ /// Create a shallow wrapper for \p F such that \p F has internal linkage
+ /// afterwards. It also sets the original \p F 's name to anonymous
+ ///
+ /// A wrapper is a function with the same type (and attributes) as \p F
+ /// that will only call \p F and return the result, if any.
+ ///
+ /// Assuming the declaration of looks like:
+ /// rty F(aty0 arg0, ..., atyN argN);
+ ///
+ /// The wrapper will then look as follows:
+ /// rty wrapper(aty0 arg0, ..., atyN argN) {
+ /// return F(arg0, ..., argN);
+ /// }
+ ///
+ static void createShallowWrapper(Function &F);
+
/// Return the data layout associated with the anchor scope.
const DataLayout &getDataLayout() const { return InfoCache.DL; }
@@ -1580,10 +1580,10 @@ private:
/// Rewrites function signitures and updates the call graph.
ChangeStatus cleanupIR();
- /// Identify internal functions that are effectively dead, thus not reachable
- /// from a live entry point. The functions are added to ToBeDeletedFunctions.
- void identifyDeadInternalFunctions();
-
+ /// Identify internal functions that are effectively dead, thus not reachable
+ /// from a live entry point. The functions are added to ToBeDeletedFunctions.
+ void identifyDeadInternalFunctions();
+
/// Run `::update` on \p AA and track the dependences queried while doing so.
/// Also adjust the state if we know further updates are not necessary.
ChangeStatus updateAA(AbstractAttribute &AA);
@@ -1635,9 +1635,9 @@ private:
/// Helper to update an underlying call graph.
CallGraphUpdater &CGUpdater;
- /// Abstract Attribute dependency graph
- AADepGraph DG;
-
+ /// Abstract Attribute dependency graph
+ AADepGraph DG;
+
/// Set of functions for which we modified the content such that it might
/// impact the call graph.
SmallPtrSet<Function *, 8> CGModifiedFunctions;
@@ -1676,18 +1676,18 @@ private:
/// Invoke instructions with at least a single dead successor block.
SmallVector<WeakVH, 16> InvokeWithDeadSuccessor;
- /// A flag that indicates which stage of the process we are in. Initially, the
- /// phase is SEEDING. Phase is changed in `Attributor::run()`
- enum class AttributorPhase {
- SEEDING,
- UPDATE,
- MANIFEST,
- CLEANUP,
- } Phase = AttributorPhase::SEEDING;
-
- /// The current initialization chain length. Tracked to avoid stack overflows.
- unsigned InitializationChainLength = 0;
-
+ /// A flag that indicates which stage of the process we are in. Initially, the
+ /// phase is SEEDING. Phase is changed in `Attributor::run()`
+ enum class AttributorPhase {
+ SEEDING,
+ UPDATE,
+ MANIFEST,
+ CLEANUP,
+ } Phase = AttributorPhase::SEEDING;
+
+ /// The current initialization chain length. Tracked to avoid stack overflows.
+ unsigned InitializationChainLength = 0;
+
/// Functions, blocks, and instructions we delete after manifest is done.
///
///{
@@ -1695,8 +1695,8 @@ private:
SmallPtrSet<BasicBlock *, 8> ToBeDeletedBlocks;
SmallDenseSet<WeakVH, 8> ToBeDeletedInsts;
///}
-
- friend AADepGraph;
+
+ friend AADepGraph;
};
/// An interface to query the internal state of an abstract attribute.
@@ -2175,7 +2175,7 @@ struct StateWrapper : public BaseType, public StateTy {
StateType &getState() override { return *this; }
/// See AbstractAttribute::getState(...).
- const StateType &getState() const override { return *this; }
+ const StateType &getState() const override { return *this; }
};
/// Helper class that provides common functionality to manifest IR attributes.
@@ -2269,7 +2269,7 @@ struct IRAttribute : public BaseType {
/// both directions will be added in the future.
/// NOTE: The mechanics of adding a new "concrete" abstract attribute are
/// described in the file comment.
-struct AbstractAttribute : public IRPosition, public AADepGraphNode {
+struct AbstractAttribute : public IRPosition, public AADepGraphNode {
using StateType = AbstractState;
AbstractAttribute(const IRPosition &IRP) : IRPosition(IRP) {}
@@ -2277,14 +2277,14 @@ struct AbstractAttribute : public IRPosition, public AADepGraphNode {
/// Virtual destructor.
virtual ~AbstractAttribute() {}
- /// This function is used to identify if an \p DGN is of type
- /// AbstractAttribute so that the dyn_cast and cast can use such information
- /// to cast an AADepGraphNode to an AbstractAttribute.
- ///
- /// We eagerly return true here because all AADepGraphNodes except for the
- /// Synthethis Node are of type AbstractAttribute
- static bool classof(const AADepGraphNode *DGN) { return true; }
-
+ /// This function is used to identify if an \p DGN is of type
+ /// AbstractAttribute so that the dyn_cast and cast can use such information
+ /// to cast an AADepGraphNode to an AbstractAttribute.
+ ///
+ /// We eagerly return true here because all AADepGraphNodes except for the
+ /// Synthethis Node are of type AbstractAttribute
+ static bool classof(const AADepGraphNode *DGN) { return true; }
+
/// Initialize the state with the information in the Attributor \p A.
///
/// This function is called by the Attributor once all abstract attributes
@@ -2305,8 +2305,8 @@ struct AbstractAttribute : public IRPosition, public AADepGraphNode {
/// Helper functions, for debug purposes only.
///{
- void print(raw_ostream &OS) const override;
- virtual void printWithDeps(raw_ostream &OS) const;
+ void print(raw_ostream &OS) const override;
+ virtual void printWithDeps(raw_ostream &OS) const;
void dump() const { print(dbgs()); }
/// This function should return the "summarized" assumed state as string.
@@ -2635,17 +2635,17 @@ struct AAReachability : public StateWrapper<BooleanState, AbstractAttribute> {
/// Returns true if 'From' instruction is assumed to reach, 'To' instruction.
/// Users should provide two positions they are interested in, and the class
/// determines (and caches) reachability.
- bool isAssumedReachable(Attributor &A, const Instruction &From,
- const Instruction &To) const {
- return A.getInfoCache().getPotentiallyReachable(From, To);
+ bool isAssumedReachable(Attributor &A, const Instruction &From,
+ const Instruction &To) const {
+ return A.getInfoCache().getPotentiallyReachable(From, To);
}
/// Returns true if 'From' instruction is known to reach, 'To' instruction.
/// Users should provide two positions they are interested in, and the class
/// determines (and caches) reachability.
- bool isKnownReachable(Attributor &A, const Instruction &From,
- const Instruction &To) const {
- return A.getInfoCache().getPotentiallyReachable(From, To);
+ bool isKnownReachable(Attributor &A, const Instruction &From,
+ const Instruction &To) const {
+ return A.getInfoCache().getPotentiallyReachable(From, To);
}
/// Create an abstract attribute view for the position \p IRP.
@@ -2808,12 +2808,12 @@ public:
return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
}
- /// Return if the edge from \p From BB to \p To BB is assumed dead.
- /// This is specifically useful in AAReachability.
- virtual bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const {
- return false;
- }
-
+ /// Return if the edge from \p From BB to \p To BB is assumed dead.
+ /// This is specifically useful in AAReachability.
+ virtual bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const {
+ return false;
+ }
+
/// See AbstractAttribute::getName()
const std::string getName() const override { return "AAIsDead"; }
@@ -3470,7 +3470,7 @@ struct AAValueConstantRange
/// See AbstractAttribute::getState(...).
IntegerRangeState &getState() override { return *this; }
- const IntegerRangeState &getState() const override { return *this; }
+ const IntegerRangeState &getState() const override { return *this; }
/// Create an abstract attribute view for the position \p IRP.
static AAValueConstantRange &createForPosition(const IRPosition &IRP,
@@ -3518,279 +3518,279 @@ struct AAValueConstantRange
static const char ID;
};
-/// A class for a set state.
-/// The assumed boolean state indicates whether the corresponding set is full
-/// set or not. If the assumed state is false, this is the worst state. The
-/// worst state (invalid state) of set of potential values is when the set
-/// contains every possible value (i.e. we cannot in any way limit the value
-/// that the target position can take). That never happens naturally, we only
-/// force it. As for the conditions under which we force it, see
-/// AAPotentialValues.
-template <typename MemberTy, typename KeyInfo = DenseMapInfo<MemberTy>>
-struct PotentialValuesState : AbstractState {
- using SetTy = DenseSet<MemberTy, KeyInfo>;
-
- PotentialValuesState() : IsValidState(true), UndefIsContained(false) {}
-
- PotentialValuesState(bool IsValid)
- : IsValidState(IsValid), UndefIsContained(false) {}
-
- /// See AbstractState::isValidState(...)
- bool isValidState() const override { return IsValidState.isValidState(); }
-
- /// See AbstractState::isAtFixpoint(...)
- bool isAtFixpoint() const override { return IsValidState.isAtFixpoint(); }
-
- /// See AbstractState::indicatePessimisticFixpoint(...)
- ChangeStatus indicatePessimisticFixpoint() override {
- return IsValidState.indicatePessimisticFixpoint();
- }
-
- /// See AbstractState::indicateOptimisticFixpoint(...)
- ChangeStatus indicateOptimisticFixpoint() override {
- return IsValidState.indicateOptimisticFixpoint();
- }
-
- /// Return the assumed state
- PotentialValuesState &getAssumed() { return *this; }
- const PotentialValuesState &getAssumed() const { return *this; }
-
- /// Return this set. We should check whether this set is valid or not by
- /// isValidState() before calling this function.
- const SetTy &getAssumedSet() const {
- assert(isValidState() && "This set shoud not be used when it is invalid!");
- return Set;
- }
-
- /// Returns whether this state contains an undef value or not.
- bool undefIsContained() const {
- assert(isValidState() && "This flag shoud not be used when it is invalid!");
- return UndefIsContained;
- }
-
- bool operator==(const PotentialValuesState &RHS) const {
- if (isValidState() != RHS.isValidState())
- return false;
- if (!isValidState() && !RHS.isValidState())
- return true;
- if (undefIsContained() != RHS.undefIsContained())
- return false;
- return Set == RHS.getAssumedSet();
- }
-
- /// Maximum number of potential values to be tracked.
- /// This is set by -attributor-max-potential-values command line option
- static unsigned MaxPotentialValues;
-
- /// Return empty set as the best state of potential values.
- static PotentialValuesState getBestState() {
- return PotentialValuesState(true);
- }
-
- static PotentialValuesState getBestState(PotentialValuesState &PVS) {
- return getBestState();
- }
-
- /// Return full set as the worst state of potential values.
- static PotentialValuesState getWorstState() {
- return PotentialValuesState(false);
- }
-
- /// Union assumed set with the passed value.
- void unionAssumed(const MemberTy &C) { insert(C); }
-
- /// Union assumed set with assumed set of the passed state \p PVS.
- void unionAssumed(const PotentialValuesState &PVS) { unionWith(PVS); }
-
- /// Union assumed set with an undef value.
- void unionAssumedWithUndef() { unionWithUndef(); }
-
- /// "Clamp" this state with \p PVS.
- PotentialValuesState operator^=(const PotentialValuesState &PVS) {
- IsValidState ^= PVS.IsValidState;
- unionAssumed(PVS);
- return *this;
- }
-
- PotentialValuesState operator&=(const PotentialValuesState &PVS) {
- IsValidState &= PVS.IsValidState;
- unionAssumed(PVS);
- return *this;
- }
-
-private:
- /// Check the size of this set, and invalidate when the size is no
- /// less than \p MaxPotentialValues threshold.
- void checkAndInvalidate() {
- if (Set.size() >= MaxPotentialValues)
- indicatePessimisticFixpoint();
- }
-
- /// If this state contains both undef and not undef, we can reduce
- /// undef to the not undef value.
- void reduceUndefValue() { UndefIsContained = UndefIsContained & Set.empty(); }
-
- /// Insert an element into this set.
- void insert(const MemberTy &C) {
- if (!isValidState())
- return;
- Set.insert(C);
- checkAndInvalidate();
- }
-
- /// Take union with R.
- void unionWith(const PotentialValuesState &R) {
- /// If this is a full set, do nothing.;
- if (!isValidState())
- return;
- /// If R is full set, change L to a full set.
- if (!R.isValidState()) {
- indicatePessimisticFixpoint();
- return;
- }
- for (const MemberTy &C : R.Set)
- Set.insert(C);
- UndefIsContained |= R.undefIsContained();
- reduceUndefValue();
- checkAndInvalidate();
- }
-
- /// Take union with an undef value.
- void unionWithUndef() {
- UndefIsContained = true;
- reduceUndefValue();
- }
-
- /// Take intersection with R.
- void intersectWith(const PotentialValuesState &R) {
- /// If R is a full set, do nothing.
- if (!R.isValidState())
- return;
- /// If this is a full set, change this to R.
- if (!isValidState()) {
- *this = R;
- return;
- }
- SetTy IntersectSet;
- for (const MemberTy &C : Set) {
- if (R.Set.count(C))
- IntersectSet.insert(C);
- }
- Set = IntersectSet;
- UndefIsContained &= R.undefIsContained();
- reduceUndefValue();
- }
-
- /// A helper state which indicate whether this state is valid or not.
- BooleanState IsValidState;
-
- /// Container for potential values
- SetTy Set;
-
- /// Flag for undef value
- bool UndefIsContained;
-};
-
-using PotentialConstantIntValuesState = PotentialValuesState<APInt>;
-
-raw_ostream &operator<<(raw_ostream &OS,
- const PotentialConstantIntValuesState &R);
-
-/// An abstract interface for potential values analysis.
-///
-/// This AA collects potential values for each IR position.
-/// An assumed set of potential values is initialized with the empty set (the
-/// best state) and it will grow monotonically as we find more potential values
-/// for this position.
-/// The set might be forced to the worst state, that is, to contain every
-/// possible value for this position in 2 cases.
-/// 1. We surpassed the \p MaxPotentialValues threshold. This includes the
-/// case that this position is affected (e.g. because of an operation) by a
-/// Value that is in the worst state.
-/// 2. We tried to initialize on a Value that we cannot handle (e.g. an
-/// operator we do not currently handle).
-///
-/// TODO: Support values other than constant integers.
-struct AAPotentialValues
- : public StateWrapper<PotentialConstantIntValuesState, AbstractAttribute> {
- using Base = StateWrapper<PotentialConstantIntValuesState, AbstractAttribute>;
- AAPotentialValues(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
-
- /// See AbstractAttribute::getState(...).
- PotentialConstantIntValuesState &getState() override { return *this; }
- const PotentialConstantIntValuesState &getState() const override {
- return *this;
- }
-
- /// Create an abstract attribute view for the position \p IRP.
- static AAPotentialValues &createForPosition(const IRPosition &IRP,
- Attributor &A);
-
- /// Return assumed constant for the associated value
- Optional<ConstantInt *>
- getAssumedConstantInt(Attributor &A,
- const Instruction *CtxI = nullptr) const {
- if (!isValidState())
- return nullptr;
- if (getAssumedSet().size() == 1)
- return cast<ConstantInt>(ConstantInt::get(getAssociatedValue().getType(),
- *(getAssumedSet().begin())));
- if (getAssumedSet().size() == 0) {
- if (undefIsContained())
- return cast<ConstantInt>(
- ConstantInt::get(getAssociatedValue().getType(), 0));
- return llvm::None;
- }
-
- return nullptr;
- }
-
- /// See AbstractAttribute::getName()
- const std::string getName() const override { return "AAPotentialValues"; }
-
- /// See AbstractAttribute::getIdAddr()
- const char *getIdAddr() const override { return &ID; }
-
- /// This function should return true if the type of the \p AA is
- /// AAPotentialValues
- static bool classof(const AbstractAttribute *AA) {
- return (AA->getIdAddr() == &ID);
- }
-
- /// Unique ID (due to the unique address)
- static const char ID;
-};
-
-/// An abstract interface for all noundef attributes.
-struct AANoUndef
- : public IRAttribute<Attribute::NoUndef,
- StateWrapper<BooleanState, AbstractAttribute>> {
- AANoUndef(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}
-
- /// Return true if we assume that the underlying value is noundef.
- bool isAssumedNoUndef() const { return getAssumed(); }
-
- /// Return true if we know that underlying value is noundef.
- bool isKnownNoUndef() const { return getKnown(); }
-
- /// Create an abstract attribute view for the position \p IRP.
- static AANoUndef &createForPosition(const IRPosition &IRP, Attributor &A);
-
- /// See AbstractAttribute::getName()
- const std::string getName() const override { return "AANoUndef"; }
-
- /// See AbstractAttribute::getIdAddr()
- const char *getIdAddr() const override { return &ID; }
-
- /// This function should return true if the type of the \p AA is AANoUndef
- static bool classof(const AbstractAttribute *AA) {
- return (AA->getIdAddr() == &ID);
- }
-
- /// Unique ID (due to the unique address)
- static const char ID;
-};
-
+/// A class for a set state.
+/// The assumed boolean state indicates whether the corresponding set is full
+/// set or not. If the assumed state is false, this is the worst state. The
+/// worst state (invalid state) of set of potential values is when the set
+/// contains every possible value (i.e. we cannot in any way limit the value
+/// that the target position can take). That never happens naturally, we only
+/// force it. As for the conditions under which we force it, see
+/// AAPotentialValues.
+template <typename MemberTy, typename KeyInfo = DenseMapInfo<MemberTy>>
+struct PotentialValuesState : AbstractState {
+ using SetTy = DenseSet<MemberTy, KeyInfo>;
+
+ PotentialValuesState() : IsValidState(true), UndefIsContained(false) {}
+
+ PotentialValuesState(bool IsValid)
+ : IsValidState(IsValid), UndefIsContained(false) {}
+
+ /// See AbstractState::isValidState(...)
+ bool isValidState() const override { return IsValidState.isValidState(); }
+
+ /// See AbstractState::isAtFixpoint(...)
+ bool isAtFixpoint() const override { return IsValidState.isAtFixpoint(); }
+
+ /// See AbstractState::indicatePessimisticFixpoint(...)
+ ChangeStatus indicatePessimisticFixpoint() override {
+ return IsValidState.indicatePessimisticFixpoint();
+ }
+
+ /// See AbstractState::indicateOptimisticFixpoint(...)
+ ChangeStatus indicateOptimisticFixpoint() override {
+ return IsValidState.indicateOptimisticFixpoint();
+ }
+
+ /// Return the assumed state
+ PotentialValuesState &getAssumed() { return *this; }
+ const PotentialValuesState &getAssumed() const { return *this; }
+
+ /// Return this set. We should check whether this set is valid or not by
+ /// isValidState() before calling this function.
+ const SetTy &getAssumedSet() const {
+ assert(isValidState() && "This set shoud not be used when it is invalid!");
+ return Set;
+ }
+
+ /// Returns whether this state contains an undef value or not.
+ bool undefIsContained() const {
+ assert(isValidState() && "This flag shoud not be used when it is invalid!");
+ return UndefIsContained;
+ }
+
+ bool operator==(const PotentialValuesState &RHS) const {
+ if (isValidState() != RHS.isValidState())
+ return false;
+ if (!isValidState() && !RHS.isValidState())
+ return true;
+ if (undefIsContained() != RHS.undefIsContained())
+ return false;
+ return Set == RHS.getAssumedSet();
+ }
+
+ /// Maximum number of potential values to be tracked.
+ /// This is set by -attributor-max-potential-values command line option
+ static unsigned MaxPotentialValues;
+
+ /// Return empty set as the best state of potential values.
+ static PotentialValuesState getBestState() {
+ return PotentialValuesState(true);
+ }
+
+ static PotentialValuesState getBestState(PotentialValuesState &PVS) {
+ return getBestState();
+ }
+
+ /// Return full set as the worst state of potential values.
+ static PotentialValuesState getWorstState() {
+ return PotentialValuesState(false);
+ }
+
+ /// Union assumed set with the passed value.
+ void unionAssumed(const MemberTy &C) { insert(C); }
+
+ /// Union assumed set with assumed set of the passed state \p PVS.
+ void unionAssumed(const PotentialValuesState &PVS) { unionWith(PVS); }
+
+ /// Union assumed set with an undef value.
+ void unionAssumedWithUndef() { unionWithUndef(); }
+
+ /// "Clamp" this state with \p PVS.
+ PotentialValuesState operator^=(const PotentialValuesState &PVS) {
+ IsValidState ^= PVS.IsValidState;
+ unionAssumed(PVS);
+ return *this;
+ }
+
+ PotentialValuesState operator&=(const PotentialValuesState &PVS) {
+ IsValidState &= PVS.IsValidState;
+ unionAssumed(PVS);
+ return *this;
+ }
+
+private:
+ /// Check the size of this set, and invalidate when the size is no
+ /// less than \p MaxPotentialValues threshold.
+ void checkAndInvalidate() {
+ if (Set.size() >= MaxPotentialValues)
+ indicatePessimisticFixpoint();
+ }
+
+ /// If this state contains both undef and not undef, we can reduce
+ /// undef to the not undef value.
+ void reduceUndefValue() { UndefIsContained = UndefIsContained & Set.empty(); }
+
+ /// Insert an element into this set.
+ void insert(const MemberTy &C) {
+ if (!isValidState())
+ return;
+ Set.insert(C);
+ checkAndInvalidate();
+ }
+
+ /// Take union with R.
+ void unionWith(const PotentialValuesState &R) {
+ /// If this is a full set, do nothing.;
+ if (!isValidState())
+ return;
+ /// If R is full set, change L to a full set.
+ if (!R.isValidState()) {
+ indicatePessimisticFixpoint();
+ return;
+ }
+ for (const MemberTy &C : R.Set)
+ Set.insert(C);
+ UndefIsContained |= R.undefIsContained();
+ reduceUndefValue();
+ checkAndInvalidate();
+ }
+
+ /// Take union with an undef value.
+ void unionWithUndef() {
+ UndefIsContained = true;
+ reduceUndefValue();
+ }
+
+ /// Take intersection with R.
+ void intersectWith(const PotentialValuesState &R) {
+ /// If R is a full set, do nothing.
+ if (!R.isValidState())
+ return;
+ /// If this is a full set, change this to R.
+ if (!isValidState()) {
+ *this = R;
+ return;
+ }
+ SetTy IntersectSet;
+ for (const MemberTy &C : Set) {
+ if (R.Set.count(C))
+ IntersectSet.insert(C);
+ }
+ Set = IntersectSet;
+ UndefIsContained &= R.undefIsContained();
+ reduceUndefValue();
+ }
+
+ /// A helper state which indicate whether this state is valid or not.
+ BooleanState IsValidState;
+
+ /// Container for potential values
+ SetTy Set;
+
+ /// Flag for undef value
+ bool UndefIsContained;
+};
+
+using PotentialConstantIntValuesState = PotentialValuesState<APInt>;
+
+raw_ostream &operator<<(raw_ostream &OS,
+ const PotentialConstantIntValuesState &R);
+
+/// An abstract interface for potential values analysis.
+///
+/// This AA collects potential values for each IR position.
+/// An assumed set of potential values is initialized with the empty set (the
+/// best state) and it will grow monotonically as we find more potential values
+/// for this position.
+/// The set might be forced to the worst state, that is, to contain every
+/// possible value for this position in 2 cases.
+/// 1. We surpassed the \p MaxPotentialValues threshold. This includes the
+/// case that this position is affected (e.g. because of an operation) by a
+/// Value that is in the worst state.
+/// 2. We tried to initialize on a Value that we cannot handle (e.g. an
+/// operator we do not currently handle).
+///
+/// TODO: Support values other than constant integers.
+struct AAPotentialValues
+ : public StateWrapper<PotentialConstantIntValuesState, AbstractAttribute> {
+ using Base = StateWrapper<PotentialConstantIntValuesState, AbstractAttribute>;
+ AAPotentialValues(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
+
+ /// See AbstractAttribute::getState(...).
+ PotentialConstantIntValuesState &getState() override { return *this; }
+ const PotentialConstantIntValuesState &getState() const override {
+ return *this;
+ }
+
+ /// Create an abstract attribute view for the position \p IRP.
+ static AAPotentialValues &createForPosition(const IRPosition &IRP,
+ Attributor &A);
+
+ /// Return assumed constant for the associated value
+ Optional<ConstantInt *>
+ getAssumedConstantInt(Attributor &A,
+ const Instruction *CtxI = nullptr) const {
+ if (!isValidState())
+ return nullptr;
+ if (getAssumedSet().size() == 1)
+ return cast<ConstantInt>(ConstantInt::get(getAssociatedValue().getType(),
+ *(getAssumedSet().begin())));
+ if (getAssumedSet().size() == 0) {
+ if (undefIsContained())
+ return cast<ConstantInt>(
+ ConstantInt::get(getAssociatedValue().getType(), 0));
+ return llvm::None;
+ }
+
+ return nullptr;
+ }
+
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AAPotentialValues"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is
+ /// AAPotentialValues
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
+ /// Unique ID (due to the unique address)
+ static const char ID;
+};
+
+/// An abstract interface for all noundef attributes.
+struct AANoUndef
+ : public IRAttribute<Attribute::NoUndef,
+ StateWrapper<BooleanState, AbstractAttribute>> {
+ AANoUndef(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}
+
+ /// Return true if we assume that the underlying value is noundef.
+ bool isAssumedNoUndef() const { return getAssumed(); }
+
+ /// Return true if we know that underlying value is noundef.
+ bool isKnownNoUndef() const { return getKnown(); }
+
+ /// Create an abstract attribute view for the position \p IRP.
+ static AANoUndef &createForPosition(const IRPosition &IRP, Attributor &A);
+
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AANoUndef"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is AANoUndef
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
+ /// Unique ID (due to the unique address)
+ static const char ID;
+};
+
/// Run options, used by the pass manager.
enum AttributorRunOption {
NONE = 0,
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/IPO/BlockExtractor.h b/contrib/libs/llvm12/include/llvm/Transforms/IPO/BlockExtractor.h
index 937c1cbb39..10ac54d79d 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/IPO/BlockExtractor.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/IPO/BlockExtractor.h
@@ -1,36 +1,36 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- BlockExtractor.h - Extracts blocks into their own functions --------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass extracts the specified basic blocks from the module into their
-// own functions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_IPO_BLOCKEXTRACTOR_H
-#define LLVM_TRANSFORMS_IPO_BLOCKEXTRACTOR_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-struct BlockExtractorPass : PassInfoMixin<BlockExtractorPass> {
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-};
-} // namespace llvm
-
-#endif // LLVM_TRANSFORMS_IPO_BLOCKEXTRACTOR_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- BlockExtractor.h - Extracts blocks into their own functions --------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass extracts the specified basic blocks from the module into their
+// own functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_BLOCKEXTRACTOR_H
+#define LLVM_TRANSFORMS_IPO_BLOCKEXTRACTOR_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+struct BlockExtractorPass : PassInfoMixin<BlockExtractorPass> {
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_BLOCKEXTRACTOR_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/IPO/IROutliner.h b/contrib/libs/llvm12/include/llvm/Transforms/IPO/IROutliner.h
index bb1f1beb5a..0b90589079 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/IPO/IROutliner.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/IPO/IROutliner.h
@@ -1,369 +1,369 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- IROutliner.h - Extract similar IR regions into functions ------------==//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// \file
-// The interface file for the IROutliner which is used by the IROutliner Pass.
-//
-// The outliner uses the IRSimilarityIdentifier to identify the similar regions
-// of code. It evaluates each set of IRSimilarityCandidates with an estimate of
-// whether it will provide code size reduction. Each region is extracted using
-// the code extractor. These extracted functions are consolidated into a single
-// function and called from the extracted call site.
-//
-// For example:
-// \code
-// %1 = add i32 %a, %b
-// %2 = add i32 %b, %a
-// %3 = add i32 %b, %a
-// %4 = add i32 %a, %b
-// \endcode
-// would become function
-// \code
-// define internal void outlined_ir_function(i32 %0, i32 %1) {
-// %1 = add i32 %0, %1
-// %2 = add i32 %1, %0
-// ret void
-// }
-// \endcode
-// with calls:
-// \code
-// call void outlined_ir_function(i32 %a, i32 %b)
-// call void outlined_ir_function(i32 %b, i32 %a)
-// \endcode
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_IPO_IROUTLINER_H
-#define LLVM_TRANSFORMS_IPO_IROUTLINER_H
-
-#include "llvm/Analysis/IRSimilarityIdentifier.h"
-#include "llvm/IR/PassManager.h"
-#include "llvm/IR/ValueMap.h"
-#include "llvm/Support/InstructionCost.h"
-#include "llvm/Transforms/Utils/CodeExtractor.h"
-#include <set>
-
-struct OutlinableGroup;
-
-namespace llvm {
-using namespace IRSimilarity;
-
-class Module;
-class TargetTransformInfo;
-class OptimizationRemarkEmitter;
-
-/// The OutlinableRegion holds all the information for a specific region, or
-/// sequence of instructions. This includes what values need to be hoisted to
-/// arguments from the extracted function, inputs and outputs to the region, and
-/// mapping from the extracted function arguments to overall function arguments.
-struct OutlinableRegion {
- /// Describes the region of code.
- IRSimilarityCandidate *Candidate;
-
- /// If this region is outlined, the front and back IRInstructionData could
- /// potentially become invalidated if the only new instruction is a call.
- /// This ensures that we replace in the instruction in the IRInstructionData.
- IRInstructionData *NewFront = nullptr;
- IRInstructionData *NewBack = nullptr;
-
- /// The number of extracted inputs from the CodeExtractor.
- unsigned NumExtractedInputs;
-
- /// The corresponding BasicBlock with the appropriate stores for this
- /// OutlinableRegion in the overall function.
- unsigned OutputBlockNum;
-
- /// Mapping the extracted argument number to the argument number in the
- /// overall function. Since there will be inputs, such as elevated constants
- /// that are not the same in each region in a SimilarityGroup, or values that
- /// cannot be sunk into the extracted section in every region, we must keep
- /// track of which extracted argument maps to which overall argument.
- DenseMap<unsigned, unsigned> ExtractedArgToAgg;
- DenseMap<unsigned, unsigned> AggArgToExtracted;
-
- /// Mapping of the argument number in the deduplicated function
- /// to a given constant, which is used when creating the arguments to the call
- /// to the newly created deduplicated function. This is handled separately
- /// since the CodeExtractor does not recognize constants.
- DenseMap<unsigned, Constant *> AggArgToConstant;
-
- /// The global value numbers that are used as outputs for this section. Once
- /// extracted, each output will be stored to an output register. This
- /// documents the global value numbers that are used in this pattern.
- SmallVector<unsigned, 4> GVNStores;
-
- /// Used to create an outlined function.
- CodeExtractor *CE = nullptr;
-
- /// The call site of the extracted region.
- CallInst *Call = nullptr;
-
- /// The function for the extracted region.
- Function *ExtractedFunction = nullptr;
-
- /// Flag for whether we have split out the IRSimilarityCanidate. That is,
- /// make the region contained the IRSimilarityCandidate its own BasicBlock.
- bool CandidateSplit = false;
-
- /// Flag for whether we should not consider this region for extraction.
- bool IgnoreRegion = false;
-
- /// The BasicBlock that is before the start of the region BasicBlock,
- /// only defined when the region has been split.
- BasicBlock *PrevBB = nullptr;
-
- /// The BasicBlock that contains the starting instruction of the region.
- BasicBlock *StartBB = nullptr;
-
- /// The BasicBlock that contains the ending instruction of the region.
- BasicBlock *EndBB = nullptr;
-
- /// The BasicBlock that is after the start of the region BasicBlock,
- /// only defined when the region has been split.
- BasicBlock *FollowBB = nullptr;
-
- /// The Outlinable Group that contains this region and structurally similar
- /// regions to this region.
- OutlinableGroup *Parent = nullptr;
-
- OutlinableRegion(IRSimilarityCandidate &C, OutlinableGroup &Group)
- : Candidate(&C), Parent(&Group) {
- StartBB = C.getStartBB();
- EndBB = C.getEndBB();
- }
-
- /// For the contained region, split the parent BasicBlock at the starting and
- /// ending instructions of the contained IRSimilarityCandidate.
- void splitCandidate();
-
- /// For the contained region, reattach the BasicBlock at the starting and
- /// ending instructions of the contained IRSimilarityCandidate, or if the
- /// function has been extracted, the start and end of the BasicBlock
- /// containing the called function.
- void reattachCandidate();
-
- /// Get the size of the code removed from the region.
- ///
- /// \param [in] TTI - The TargetTransformInfo for the parent function.
- /// \returns the code size of the region
- InstructionCost getBenefit(TargetTransformInfo &TTI);
-};
-
-/// This class is a pass that identifies similarity in a Module, extracts
-/// instances of the similarity, and then consolidating the similar regions
-/// in an effort to reduce code size. It uses the IRSimilarityIdentifier pass
-/// to identify the similar regions of code, and then extracts the similar
-/// sections into a single function. See the above for an example as to
-/// how code is extracted and consolidated into a single function.
-class IROutliner {
-public:
- IROutliner(function_ref<TargetTransformInfo &(Function &)> GTTI,
- function_ref<IRSimilarityIdentifier &(Module &)> GIRSI,
- function_ref<OptimizationRemarkEmitter &(Function &)> GORE)
- : getTTI(GTTI), getIRSI(GIRSI), getORE(GORE) {}
- bool run(Module &M);
-
-private:
- /// Find repeated similar code sequences in \p M and outline them into new
- /// Functions.
- ///
- /// \param [in] M - The module to outline from.
- /// \returns The number of Functions created.
- unsigned doOutline(Module &M);
-
- /// Remove all the IRSimilarityCandidates from \p CandidateVec that have
- /// instructions contained in a previously outlined region and put the
- /// remaining regions in \p CurrentGroup.
- ///
- /// \param [in] CandidateVec - List of similarity candidates for regions with
- /// the same similarity structure.
- /// \param [in,out] CurrentGroup - Contains the potential sections to
- /// be outlined.
- void
- pruneIncompatibleRegions(std::vector<IRSimilarityCandidate> &CandidateVec,
- OutlinableGroup &CurrentGroup);
-
- /// Create the function based on the overall types found in the current
- /// regions being outlined.
- ///
- /// \param M - The module to outline from.
- /// \param [in,out] CG - The OutlinableGroup for the regions to be outlined.
- /// \param [in] FunctionNameSuffix - How many functions have we previously
- /// created.
- /// \returns the newly created function.
- Function *createFunction(Module &M, OutlinableGroup &CG,
- unsigned FunctionNameSuffix);
-
- /// Identify the needed extracted inputs in a section, and add to the overall
- /// function if needed.
- ///
- /// \param [in] M - The module to outline from.
- /// \param [in,out] Region - The region to be extracted.
- /// \param [in] NotSame - The global value numbers of the Values in the region
- /// that do not have the same Constant in each strucutrally similar region.
- void findAddInputsOutputs(Module &M, OutlinableRegion &Region,
- DenseSet<unsigned> &NotSame);
-
- /// Find the number of instructions that will be removed by extracting the
- /// OutlinableRegions in \p CurrentGroup.
- ///
- /// \param [in] CurrentGroup - The collection of OutlinableRegions to be
- /// analyzed.
- /// \returns the number of outlined instructions across all regions.
- InstructionCost findBenefitFromAllRegions(OutlinableGroup &CurrentGroup);
-
- /// Find the number of instructions that will be added by reloading arguments.
- ///
- /// \param [in] CurrentGroup - The collection of OutlinableRegions to be
- /// analyzed.
- /// \returns the number of added reload instructions across all regions.
- InstructionCost findCostOutputReloads(OutlinableGroup &CurrentGroup);
-
- /// Find the cost and the benefit of \p CurrentGroup and save it back to
- /// \p CurrentGroup.
- ///
- /// \param [in] M - The module being analyzed
- /// \param [in,out] CurrentGroup - The overall outlined section
- void findCostBenefit(Module &M, OutlinableGroup &CurrentGroup);
-
- /// Update the output mapping based on the load instruction, and the outputs
- /// of the extracted function.
- ///
- /// \param Region - The region extracted
- /// \param Outputs - The outputs from the extracted function.
- /// \param LI - The load instruction used to update the mapping.
- void updateOutputMapping(OutlinableRegion &Region,
- ArrayRef<Value *> Outputs, LoadInst *LI);
-
- /// Extract \p Region into its own function.
- ///
- /// \param [in] Region - The region to be extracted into its own function.
- /// \returns True if it was successfully outlined.
- bool extractSection(OutlinableRegion &Region);
-
- /// For the similarities found, and the extracted sections, create a single
- /// outlined function with appropriate output blocks as necessary.
- ///
- /// \param [in] M - The module to outline from
- /// \param [in] CurrentGroup - The set of extracted sections to consolidate.
- /// \param [in,out] FuncsToRemove - List of functions to remove from the
- /// module after outlining is completed.
- /// \param [in,out] OutlinedFunctionNum - the number of new outlined
- /// functions.
- void deduplicateExtractedSections(Module &M, OutlinableGroup &CurrentGroup,
- std::vector<Function *> &FuncsToRemove,
- unsigned &OutlinedFunctionNum);
-
- /// If true, enables us to outline from functions that have LinkOnceFromODR
- /// linkages.
- bool OutlineFromLinkODRs = false;
-
- /// If false, we do not worry if the cost is greater than the benefit. This
- /// is for debugging and testing, so that we can test small cases to ensure
- /// that the outlining is being done correctly.
- bool CostModel = true;
-
- /// The set of outlined Instructions, identified by their location in the
- /// sequential ordering of instructions in a Module.
- DenseSet<unsigned> Outlined;
-
- /// TargetTransformInfo lambda for target specific information.
- function_ref<TargetTransformInfo &(Function &)> getTTI;
-
- /// A mapping from newly created reloaded output values to the original value.
- /// If an value is replace by an output from an outlined region, this maps
- /// that Value, back to its original Value.
- DenseMap<Value *, Value *> OutputMappings;
-
- /// IRSimilarityIdentifier lambda to retrieve IRSimilarityIdentifier.
- function_ref<IRSimilarityIdentifier &(Module &)> getIRSI;
-
- /// The optimization remark emitter for the pass.
- function_ref<OptimizationRemarkEmitter &(Function &)> getORE;
-
- /// The memory allocator used to allocate the CodeExtractors.
- SpecificBumpPtrAllocator<CodeExtractor> ExtractorAllocator;
-
- /// The memory allocator used to allocate the OutlinableRegions.
- SpecificBumpPtrAllocator<OutlinableRegion> RegionAllocator;
-
- /// The memory allocator used to allocate new IRInstructionData.
- SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-
- /// Custom InstVisitor to classify different instructions for whether it can
- /// be analyzed for similarity. This is needed as there may be instruction we
- /// can identify as having similarity, but are more complicated to outline.
- struct InstructionAllowed : public InstVisitor<InstructionAllowed, bool> {
- InstructionAllowed() {}
-
- // TODO: Determine a scheme to resolve when the label is similar enough.
- bool visitBranchInst(BranchInst &BI) { return false; }
- // TODO: Determine a scheme to resolve when the labels are similar enough.
- bool visitPHINode(PHINode &PN) { return false; }
- // TODO: Handle allocas.
- bool visitAllocaInst(AllocaInst &AI) { return false; }
- // VAArg instructions are not allowed since this could cause difficulty when
- // differentiating between different sets of variable instructions in
- // the deduplicated outlined regions.
- bool visitVAArgInst(VAArgInst &VI) { return false; }
- // We exclude all exception handling cases since they are so context
- // dependent.
- bool visitLandingPadInst(LandingPadInst &LPI) { return false; }
- bool visitFuncletPadInst(FuncletPadInst &FPI) { return false; }
- // DebugInfo should be included in the regions, but should not be
- // analyzed for similarity as it has no bearing on the outcome of the
- // program.
- bool visitDbgInfoIntrinsic(DbgInfoIntrinsic &DII) { return true; }
- // TODO: Handle specific intrinsics individually from those that can be
- // handled.
- bool IntrinsicInst(IntrinsicInst &II) { return false; }
- // We only handle CallInsts that are not indirect, since we cannot guarantee
- // that they have a name in these cases.
- bool visitCallInst(CallInst &CI) {
- Function *F = CI.getCalledFunction();
- if (!F || CI.isIndirectCall() || !F->hasName())
- return false;
- return true;
- }
- // TODO: Handle FreezeInsts. Since a frozen value could be frozen inside
- // the outlined region, and then returned as an output, this will have to be
- // handled differently.
- bool visitFreezeInst(FreezeInst &CI) { return false; }
- // TODO: We do not current handle similarity that changes the control flow.
- bool visitInvokeInst(InvokeInst &II) { return false; }
- // TODO: We do not current handle similarity that changes the control flow.
- bool visitCallBrInst(CallBrInst &CBI) { return false; }
- // TODO: Handle interblock similarity.
- bool visitTerminator(Instruction &I) { return false; }
- bool visitInstruction(Instruction &I) { return true; }
- };
-
- /// A InstVisitor used to exclude certain instructions from being outlined.
- InstructionAllowed InstructionClassifier;
-};
-
-/// Pass to outline similar regions.
-class IROutlinerPass : public PassInfoMixin<IROutlinerPass> {
-public:
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-};
-
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_IPO_IROUTLINER_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- IROutliner.h - Extract similar IR regions into functions ------------==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// \file
+// The interface file for the IROutliner which is used by the IROutliner Pass.
+//
+// The outliner uses the IRSimilarityIdentifier to identify the similar regions
+// of code. It evaluates each set of IRSimilarityCandidates with an estimate of
+// whether it will provide code size reduction. Each region is extracted using
+// the code extractor. These extracted functions are consolidated into a single
+// function and called from the extracted call site.
+//
+// For example:
+// \code
+// %1 = add i32 %a, %b
+// %2 = add i32 %b, %a
+// %3 = add i32 %b, %a
+// %4 = add i32 %a, %b
+// \endcode
+// would become function
+// \code
+// define internal void outlined_ir_function(i32 %0, i32 %1) {
+// %1 = add i32 %0, %1
+// %2 = add i32 %1, %0
+// ret void
+// }
+// \endcode
+// with calls:
+// \code
+// call void outlined_ir_function(i32 %a, i32 %b)
+// call void outlined_ir_function(i32 %b, i32 %a)
+// \endcode
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_IROUTLINER_H
+#define LLVM_TRANSFORMS_IPO_IROUTLINER_H
+
+#include "llvm/Analysis/IRSimilarityIdentifier.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/IR/ValueMap.h"
+#include "llvm/Support/InstructionCost.h"
+#include "llvm/Transforms/Utils/CodeExtractor.h"
+#include <set>
+
+struct OutlinableGroup;
+
+namespace llvm {
+using namespace IRSimilarity;
+
+class Module;
+class TargetTransformInfo;
+class OptimizationRemarkEmitter;
+
+/// The OutlinableRegion holds all the information for a specific region, or
+/// sequence of instructions. This includes what values need to be hoisted to
+/// arguments from the extracted function, inputs and outputs to the region, and
+/// mapping from the extracted function arguments to overall function arguments.
+struct OutlinableRegion {
+ /// Describes the region of code.
+ IRSimilarityCandidate *Candidate;
+
+ /// If this region is outlined, the front and back IRInstructionData could
+ /// potentially become invalidated if the only new instruction is a call.
+ /// This ensures that we replace in the instruction in the IRInstructionData.
+ IRInstructionData *NewFront = nullptr;
+ IRInstructionData *NewBack = nullptr;
+
+ /// The number of extracted inputs from the CodeExtractor.
+ unsigned NumExtractedInputs;
+
+ /// The corresponding BasicBlock with the appropriate stores for this
+ /// OutlinableRegion in the overall function.
+ unsigned OutputBlockNum;
+
+ /// Mapping the extracted argument number to the argument number in the
+ /// overall function. Since there will be inputs, such as elevated constants
+ /// that are not the same in each region in a SimilarityGroup, or values that
+ /// cannot be sunk into the extracted section in every region, we must keep
+ /// track of which extracted argument maps to which overall argument.
+ DenseMap<unsigned, unsigned> ExtractedArgToAgg;
+ DenseMap<unsigned, unsigned> AggArgToExtracted;
+
+ /// Mapping of the argument number in the deduplicated function
+ /// to a given constant, which is used when creating the arguments to the call
+ /// to the newly created deduplicated function. This is handled separately
+ /// since the CodeExtractor does not recognize constants.
+ DenseMap<unsigned, Constant *> AggArgToConstant;
+
+ /// The global value numbers that are used as outputs for this section. Once
+ /// extracted, each output will be stored to an output register. This
+ /// documents the global value numbers that are used in this pattern.
+ SmallVector<unsigned, 4> GVNStores;
+
+ /// Used to create an outlined function.
+ CodeExtractor *CE = nullptr;
+
+ /// The call site of the extracted region.
+ CallInst *Call = nullptr;
+
+ /// The function for the extracted region.
+ Function *ExtractedFunction = nullptr;
+
+ /// Flag for whether we have split out the IRSimilarityCanidate. That is,
+ /// make the region contained the IRSimilarityCandidate its own BasicBlock.
+ bool CandidateSplit = false;
+
+ /// Flag for whether we should not consider this region for extraction.
+ bool IgnoreRegion = false;
+
+ /// The BasicBlock that is before the start of the region BasicBlock,
+ /// only defined when the region has been split.
+ BasicBlock *PrevBB = nullptr;
+
+ /// The BasicBlock that contains the starting instruction of the region.
+ BasicBlock *StartBB = nullptr;
+
+ /// The BasicBlock that contains the ending instruction of the region.
+ BasicBlock *EndBB = nullptr;
+
+ /// The BasicBlock that is after the start of the region BasicBlock,
+ /// only defined when the region has been split.
+ BasicBlock *FollowBB = nullptr;
+
+ /// The Outlinable Group that contains this region and structurally similar
+ /// regions to this region.
+ OutlinableGroup *Parent = nullptr;
+
+ OutlinableRegion(IRSimilarityCandidate &C, OutlinableGroup &Group)
+ : Candidate(&C), Parent(&Group) {
+ StartBB = C.getStartBB();
+ EndBB = C.getEndBB();
+ }
+
+ /// For the contained region, split the parent BasicBlock at the starting and
+ /// ending instructions of the contained IRSimilarityCandidate.
+ void splitCandidate();
+
+ /// For the contained region, reattach the BasicBlock at the starting and
+ /// ending instructions of the contained IRSimilarityCandidate, or if the
+ /// function has been extracted, the start and end of the BasicBlock
+ /// containing the called function.
+ void reattachCandidate();
+
+ /// Get the size of the code removed from the region.
+ ///
+ /// \param [in] TTI - The TargetTransformInfo for the parent function.
+ /// \returns the code size of the region
+ InstructionCost getBenefit(TargetTransformInfo &TTI);
+};
+
+/// This class is a pass that identifies similarity in a Module, extracts
+/// instances of the similarity, and then consolidating the similar regions
+/// in an effort to reduce code size. It uses the IRSimilarityIdentifier pass
+/// to identify the similar regions of code, and then extracts the similar
+/// sections into a single function. See the above for an example as to
+/// how code is extracted and consolidated into a single function.
+class IROutliner {
+public:
+ IROutliner(function_ref<TargetTransformInfo &(Function &)> GTTI,
+ function_ref<IRSimilarityIdentifier &(Module &)> GIRSI,
+ function_ref<OptimizationRemarkEmitter &(Function &)> GORE)
+ : getTTI(GTTI), getIRSI(GIRSI), getORE(GORE) {}
+ bool run(Module &M);
+
+private:
+ /// Find repeated similar code sequences in \p M and outline them into new
+ /// Functions.
+ ///
+ /// \param [in] M - The module to outline from.
+ /// \returns The number of Functions created.
+ unsigned doOutline(Module &M);
+
+ /// Remove all the IRSimilarityCandidates from \p CandidateVec that have
+ /// instructions contained in a previously outlined region and put the
+ /// remaining regions in \p CurrentGroup.
+ ///
+ /// \param [in] CandidateVec - List of similarity candidates for regions with
+ /// the same similarity structure.
+ /// \param [in,out] CurrentGroup - Contains the potential sections to
+ /// be outlined.
+ void
+ pruneIncompatibleRegions(std::vector<IRSimilarityCandidate> &CandidateVec,
+ OutlinableGroup &CurrentGroup);
+
+ /// Create the function based on the overall types found in the current
+ /// regions being outlined.
+ ///
+ /// \param M - The module to outline from.
+ /// \param [in,out] CG - The OutlinableGroup for the regions to be outlined.
+ /// \param [in] FunctionNameSuffix - How many functions have we previously
+ /// created.
+ /// \returns the newly created function.
+ Function *createFunction(Module &M, OutlinableGroup &CG,
+ unsigned FunctionNameSuffix);
+
+ /// Identify the needed extracted inputs in a section, and add to the overall
+ /// function if needed.
+ ///
+ /// \param [in] M - The module to outline from.
+ /// \param [in,out] Region - The region to be extracted.
+ /// \param [in] NotSame - The global value numbers of the Values in the region
+ /// that do not have the same Constant in each strucutrally similar region.
+ void findAddInputsOutputs(Module &M, OutlinableRegion &Region,
+ DenseSet<unsigned> &NotSame);
+
+ /// Find the number of instructions that will be removed by extracting the
+ /// OutlinableRegions in \p CurrentGroup.
+ ///
+ /// \param [in] CurrentGroup - The collection of OutlinableRegions to be
+ /// analyzed.
+ /// \returns the number of outlined instructions across all regions.
+ InstructionCost findBenefitFromAllRegions(OutlinableGroup &CurrentGroup);
+
+ /// Find the number of instructions that will be added by reloading arguments.
+ ///
+ /// \param [in] CurrentGroup - The collection of OutlinableRegions to be
+ /// analyzed.
+ /// \returns the number of added reload instructions across all regions.
+ InstructionCost findCostOutputReloads(OutlinableGroup &CurrentGroup);
+
+ /// Find the cost and the benefit of \p CurrentGroup and save it back to
+ /// \p CurrentGroup.
+ ///
+ /// \param [in] M - The module being analyzed
+ /// \param [in,out] CurrentGroup - The overall outlined section
+ void findCostBenefit(Module &M, OutlinableGroup &CurrentGroup);
+
+ /// Update the output mapping based on the load instruction, and the outputs
+ /// of the extracted function.
+ ///
+ /// \param Region - The region extracted
+ /// \param Outputs - The outputs from the extracted function.
+ /// \param LI - The load instruction used to update the mapping.
+ void updateOutputMapping(OutlinableRegion &Region,
+ ArrayRef<Value *> Outputs, LoadInst *LI);
+
+ /// Extract \p Region into its own function.
+ ///
+ /// \param [in] Region - The region to be extracted into its own function.
+ /// \returns True if it was successfully outlined.
+ bool extractSection(OutlinableRegion &Region);
+
+ /// For the similarities found, and the extracted sections, create a single
+ /// outlined function with appropriate output blocks as necessary.
+ ///
+ /// \param [in] M - The module to outline from
+ /// \param [in] CurrentGroup - The set of extracted sections to consolidate.
+ /// \param [in,out] FuncsToRemove - List of functions to remove from the
+ /// module after outlining is completed.
+ /// \param [in,out] OutlinedFunctionNum - the number of new outlined
+ /// functions.
+ void deduplicateExtractedSections(Module &M, OutlinableGroup &CurrentGroup,
+ std::vector<Function *> &FuncsToRemove,
+ unsigned &OutlinedFunctionNum);
+
+ /// If true, enables us to outline from functions that have LinkOnceFromODR
+ /// linkages.
+ bool OutlineFromLinkODRs = false;
+
+ /// If false, we do not worry if the cost is greater than the benefit. This
+ /// is for debugging and testing, so that we can test small cases to ensure
+ /// that the outlining is being done correctly.
+ bool CostModel = true;
+
+ /// The set of outlined Instructions, identified by their location in the
+ /// sequential ordering of instructions in a Module.
+ DenseSet<unsigned> Outlined;
+
+ /// TargetTransformInfo lambda for target specific information.
+ function_ref<TargetTransformInfo &(Function &)> getTTI;
+
+ /// A mapping from newly created reloaded output values to the original value.
+ /// If an value is replace by an output from an outlined region, this maps
+ /// that Value, back to its original Value.
+ DenseMap<Value *, Value *> OutputMappings;
+
+ /// IRSimilarityIdentifier lambda to retrieve IRSimilarityIdentifier.
+ function_ref<IRSimilarityIdentifier &(Module &)> getIRSI;
+
+ /// The optimization remark emitter for the pass.
+ function_ref<OptimizationRemarkEmitter &(Function &)> getORE;
+
+ /// The memory allocator used to allocate the CodeExtractors.
+ SpecificBumpPtrAllocator<CodeExtractor> ExtractorAllocator;
+
+ /// The memory allocator used to allocate the OutlinableRegions.
+ SpecificBumpPtrAllocator<OutlinableRegion> RegionAllocator;
+
+ /// The memory allocator used to allocate new IRInstructionData.
+ SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
+
+ /// Custom InstVisitor to classify different instructions for whether it can
+ /// be analyzed for similarity. This is needed as there may be instruction we
+ /// can identify as having similarity, but are more complicated to outline.
+ struct InstructionAllowed : public InstVisitor<InstructionAllowed, bool> {
+ InstructionAllowed() {}
+
+ // TODO: Determine a scheme to resolve when the label is similar enough.
+ bool visitBranchInst(BranchInst &BI) { return false; }
+ // TODO: Determine a scheme to resolve when the labels are similar enough.
+ bool visitPHINode(PHINode &PN) { return false; }
+ // TODO: Handle allocas.
+ bool visitAllocaInst(AllocaInst &AI) { return false; }
+ // VAArg instructions are not allowed since this could cause difficulty when
+ // differentiating between different sets of variable instructions in
+ // the deduplicated outlined regions.
+ bool visitVAArgInst(VAArgInst &VI) { return false; }
+ // We exclude all exception handling cases since they are so context
+ // dependent.
+ bool visitLandingPadInst(LandingPadInst &LPI) { return false; }
+ bool visitFuncletPadInst(FuncletPadInst &FPI) { return false; }
+ // DebugInfo should be included in the regions, but should not be
+ // analyzed for similarity as it has no bearing on the outcome of the
+ // program.
+ bool visitDbgInfoIntrinsic(DbgInfoIntrinsic &DII) { return true; }
+ // TODO: Handle specific intrinsics individually from those that can be
+ // handled.
+ bool IntrinsicInst(IntrinsicInst &II) { return false; }
+ // We only handle CallInsts that are not indirect, since we cannot guarantee
+ // that they have a name in these cases.
+ bool visitCallInst(CallInst &CI) {
+ Function *F = CI.getCalledFunction();
+ if (!F || CI.isIndirectCall() || !F->hasName())
+ return false;
+ return true;
+ }
+ // TODO: Handle FreezeInsts. Since a frozen value could be frozen inside
+ // the outlined region, and then returned as an output, this will have to be
+ // handled differently.
+ bool visitFreezeInst(FreezeInst &CI) { return false; }
+ // TODO: We do not current handle similarity that changes the control flow.
+ bool visitInvokeInst(InvokeInst &II) { return false; }
+ // TODO: We do not current handle similarity that changes the control flow.
+ bool visitCallBrInst(CallBrInst &CBI) { return false; }
+ // TODO: Handle interblock similarity.
+ bool visitTerminator(Instruction &I) { return false; }
+ bool visitInstruction(Instruction &I) { return true; }
+ };
+
+ /// A InstVisitor used to exclude certain instructions from being outlined.
+ InstructionAllowed InstructionClassifier;
+};
+
+/// Pass to outline similar regions.
+class IROutlinerPass : public PassInfoMixin<IROutlinerPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_IROUTLINER_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/IPO/Inliner.h b/contrib/libs/llvm12/include/llvm/Transforms/IPO/Inliner.h
index a5b5934b73..2430425c60 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/IPO/Inliner.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/IPO/Inliner.h
@@ -21,8 +21,8 @@
#include "llvm/Analysis/InlineAdvisor.h"
#include "llvm/Analysis/InlineCost.h"
#include "llvm/Analysis/LazyCallGraph.h"
-#include "llvm/Analysis/ReplayInlineAdvisor.h"
-#include "llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h"
+#include "llvm/Analysis/ReplayInlineAdvisor.h"
+#include "llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h"
#include "llvm/IR/PassManager.h"
#include <utility>
@@ -104,8 +104,8 @@ protected:
/// passes be composed to achieve the same end result.
class InlinerPass : public PassInfoMixin<InlinerPass> {
public:
- InlinerPass(bool OnlyMandatory = false) : OnlyMandatory(OnlyMandatory) {}
- InlinerPass(InlinerPass &&Arg) = default;
+ InlinerPass(bool OnlyMandatory = false) : OnlyMandatory(OnlyMandatory) {}
+ InlinerPass(InlinerPass &&Arg) = default;
PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
LazyCallGraph &CG, CGSCCUpdateResult &UR);
@@ -113,8 +113,8 @@ public:
private:
InlineAdvisor &getAdvisor(const ModuleAnalysisManagerCGSCCProxy::Result &MAM,
FunctionAnalysisManager &FAM, Module &M);
- std::unique_ptr<InlineAdvisor> OwnedAdvisor;
- const bool OnlyMandatory;
+ std::unique_ptr<InlineAdvisor> OwnedAdvisor;
+ const bool OnlyMandatory;
};
/// Module pass, wrapping the inliner pass. This works in conjunction with the
@@ -127,7 +127,7 @@ class ModuleInlinerWrapperPass
public:
ModuleInlinerWrapperPass(
InlineParams Params = getInlineParams(), bool Debugging = false,
- bool MandatoryFirst = true,
+ bool MandatoryFirst = true,
InliningAdvisorMode Mode = InliningAdvisorMode::Default,
unsigned MaxDevirtIterations = 0);
ModuleInlinerWrapperPass(ModuleInlinerWrapperPass &&Arg) = default;
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/IPO/LoopExtractor.h b/contrib/libs/llvm12/include/llvm/Transforms/IPO/LoopExtractor.h
index 3b721a1279..ede8250980 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/IPO/LoopExtractor.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/IPO/LoopExtractor.h
@@ -1,43 +1,43 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- LoopExtractor.h - Extract each loop into a new function ------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// A pass wrapper around the ExtractLoop() scalar transformation to extract each
-// top-level loop into its own new function. If the loop is the ONLY loop in a
-// given function, it is not touched. This is a pass most useful for debugging
-// via bugpoint.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_IPO_LOOPEXTRACTOR_H
-#define LLVM_TRANSFORMS_IPO_LOOPEXTRACTOR_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-
-struct LoopExtractorPass : public PassInfoMixin<LoopExtractorPass> {
- LoopExtractorPass(unsigned NumLoops = ~0) : NumLoops(NumLoops) {}
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-
-private:
- unsigned NumLoops;
-};
-} // namespace llvm
-
-#endif // LLVM_TRANSFORMS_IPO_LOOPEXTRACTOR_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- LoopExtractor.h - Extract each loop into a new function ------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// A pass wrapper around the ExtractLoop() scalar transformation to extract each
+// top-level loop into its own new function. If the loop is the ONLY loop in a
+// given function, it is not touched. This is a pass most useful for debugging
+// via bugpoint.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_LOOPEXTRACTOR_H
+#define LLVM_TRANSFORMS_IPO_LOOPEXTRACTOR_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+struct LoopExtractorPass : public PassInfoMixin<LoopExtractorPass> {
+ LoopExtractorPass(unsigned NumLoops = ~0) : NumLoops(NumLoops) {}
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+
+private:
+ unsigned NumLoops;
+};
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_LOOPEXTRACTOR_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/IPO/LowerTypeTests.h b/contrib/libs/llvm12/include/llvm/Transforms/IPO/LowerTypeTests.h
index 8ad2193588..40761ef91e 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/IPO/LowerTypeTests.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/IPO/LowerTypeTests.h
@@ -205,14 +205,14 @@ bool isJumpTableCanonical(Function *F);
} // end namespace lowertypetests
class LowerTypeTestsPass : public PassInfoMixin<LowerTypeTestsPass> {
- bool UseCommandLine = false;
-
- ModuleSummaryIndex *ExportSummary = nullptr;
- const ModuleSummaryIndex *ImportSummary = nullptr;
- bool DropTypeTests = true;
-
+ bool UseCommandLine = false;
+
+ ModuleSummaryIndex *ExportSummary = nullptr;
+ const ModuleSummaryIndex *ImportSummary = nullptr;
+ bool DropTypeTests = true;
+
public:
- LowerTypeTestsPass() : UseCommandLine(true) {}
+ LowerTypeTestsPass() : UseCommandLine(true) {}
LowerTypeTestsPass(ModuleSummaryIndex *ExportSummary,
const ModuleSummaryIndex *ImportSummary,
bool DropTypeTests = false)
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/IPO/OpenMPOpt.h b/contrib/libs/llvm12/include/llvm/Transforms/IPO/OpenMPOpt.h
index 76aff7eb6f..4e8071e60c 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/IPO/OpenMPOpt.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/IPO/OpenMPOpt.h
@@ -40,11 +40,11 @@ struct OpenMPInModule {
bool isKnown() { return Value != OpenMP::UNKNOWN; }
operator bool() { return Value != OpenMP::NOT_FOUND; }
- /// Does this function \p F contain any OpenMP runtime calls?
- bool containsOMPRuntimeCalls(Function *F) const {
- return FuncsWithOMPRuntimeCalls.contains(F);
- }
-
+ /// Does this function \p F contain any OpenMP runtime calls?
+ bool containsOMPRuntimeCalls(Function *F) const {
+ return FuncsWithOMPRuntimeCalls.contains(F);
+ }
+
/// Return the known kernels (=GPU entry points) in the module.
SmallPtrSetImpl<Kernel> &getKernels() { return Kernels; }
@@ -54,11 +54,11 @@ struct OpenMPInModule {
private:
enum class OpenMP { FOUND, NOT_FOUND, UNKNOWN } Value = OpenMP::UNKNOWN;
- friend bool containsOpenMP(Module &M, OpenMPInModule &OMPInModule);
-
- /// In which functions are OpenMP runtime calls present?
- SmallPtrSet<Function *, 32> FuncsWithOMPRuntimeCalls;
-
+ friend bool containsOpenMP(Module &M, OpenMPInModule &OMPInModule);
+
+ /// In which functions are OpenMP runtime calls present?
+ SmallPtrSet<Function *, 32> FuncsWithOMPRuntimeCalls;
+
/// Collection of known kernels (=GPU entry points) in the module.
SmallPtrSet<Kernel, 8> Kernels;
};
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/IPO/SampleContextTracker.h b/contrib/libs/llvm12/include/llvm/Transforms/IPO/SampleContextTracker.h
index e5f5e5b737..11328fb5ac 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/IPO/SampleContextTracker.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/IPO/SampleContextTracker.h
@@ -1,163 +1,163 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- Transforms/IPO/SampleContextTracker.h --------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file
-/// This file provides the interface for context-sensitive profile tracker used
-/// by CSSPGO.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_IPO_SAMPLECONTEXTTRACKER_H
-#define LLVM_TRANSFORMS_IPO_SAMPLECONTEXTTRACKER_H
-
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Analysis/CallGraph.h"
-#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/ProfileData/SampleProf.h"
-#include <list>
-#include <map>
-#include <vector>
-
-using namespace llvm;
-using namespace sampleprof;
-
-namespace llvm {
-
-// Internal trie tree representation used for tracking context tree and sample
-// profiles. The path from root node to a given node represents the context of
-// that nodes' profile.
-class ContextTrieNode {
-public:
- ContextTrieNode(ContextTrieNode *Parent = nullptr,
- StringRef FName = StringRef(),
- FunctionSamples *FSamples = nullptr,
- LineLocation CallLoc = {0, 0})
- : ParentContext(Parent), FuncName(FName), FuncSamples(FSamples),
- CallSiteLoc(CallLoc){};
- ContextTrieNode *getChildContext(const LineLocation &CallSite,
- StringRef CalleeName);
- ContextTrieNode *getHottestChildContext(const LineLocation &CallSite);
- ContextTrieNode *getOrCreateChildContext(const LineLocation &CallSite,
- StringRef CalleeName,
- bool AllowCreate = true);
-
- ContextTrieNode &moveToChildContext(const LineLocation &CallSite,
- ContextTrieNode &&NodeToMove,
- StringRef ContextStrToRemove,
- bool DeleteNode = true);
- void removeChildContext(const LineLocation &CallSite, StringRef CalleeName);
- std::map<uint32_t, ContextTrieNode> &getAllChildContext();
- const StringRef getFuncName() const;
- FunctionSamples *getFunctionSamples() const;
- void setFunctionSamples(FunctionSamples *FSamples);
- LineLocation getCallSiteLoc() const;
- ContextTrieNode *getParentContext() const;
- void setParentContext(ContextTrieNode *Parent);
- void dump();
-
-private:
- static uint32_t nodeHash(StringRef ChildName, const LineLocation &Callsite);
-
- // Map line+discriminator location to child context
- std::map<uint32_t, ContextTrieNode> AllChildContext;
-
- // Link to parent context node
- ContextTrieNode *ParentContext;
-
- // Function name for current context
- StringRef FuncName;
-
- // Function Samples for current context
- FunctionSamples *FuncSamples;
-
- // Callsite location in parent context
- LineLocation CallSiteLoc;
-};
-
-// Profile tracker that manages profiles and its associated context. It
-// provides interfaces used by sample profile loader to query context profile or
-// base profile for given function or location; it also manages context tree
-// manipulation that is needed to accommodate inline decisions so we have
-// accurate post-inline profile for functions. Internally context profiles
-// are organized in a trie, with each node representing profile for specific
-// calling context and the context is identified by path from root to the node.
-class SampleContextTracker {
-public:
- using ContextSamplesTy = SmallSet<FunctionSamples *, 16>;
-
- SampleContextTracker(StringMap<FunctionSamples> &Profiles);
- // Query context profile for a specific callee with given name at a given
- // call-site. The full context is identified by location of call instruction.
- FunctionSamples *getCalleeContextSamplesFor(const CallBase &Inst,
- StringRef CalleeName);
- // Get samples for indirect call targets for call site at given location.
- std::vector<const FunctionSamples *>
- getIndirectCalleeContextSamplesFor(const DILocation *DIL);
- // Query context profile for a given location. The full context
- // is identified by input DILocation.
- FunctionSamples *getContextSamplesFor(const DILocation *DIL);
- // Query context profile for a given sample contxt of a function.
- FunctionSamples *getContextSamplesFor(const SampleContext &Context);
- // Get all context profile for given function.
- ContextSamplesTy &getAllContextSamplesFor(const Function &Func);
- ContextSamplesTy &getAllContextSamplesFor(StringRef Name);
- // Query base profile for a given function. A base profile is a merged view
- // of all context profiles for contexts that are not inlined.
- FunctionSamples *getBaseSamplesFor(const Function &Func,
- bool MergeContext = true);
- // Query base profile for a given function by name.
- FunctionSamples *getBaseSamplesFor(StringRef Name, bool MergeContext);
- // Mark a context profile as inlined when function is inlined.
- // This makes sure that inlined context profile will be excluded in
- // function's base profile.
- void markContextSamplesInlined(const FunctionSamples *InlinedSamples);
- void promoteMergeContextSamplesTree(const Instruction &Inst,
- StringRef CalleeName);
- void addCallGraphEdges(CallGraph &CG, StringMap<Function *> &SymbolMap);
- // Dump the internal context profile trie.
- void dump();
-
-private:
- ContextTrieNode *getContextFor(const DILocation *DIL);
- ContextTrieNode *getContextFor(const SampleContext &Context);
- ContextTrieNode *getCalleeContextFor(const DILocation *DIL,
- StringRef CalleeName);
- ContextTrieNode *getOrCreateContextPath(const SampleContext &Context,
- bool AllowCreate);
- ContextTrieNode *getTopLevelContextNode(StringRef FName);
- ContextTrieNode &addTopLevelContextNode(StringRef FName);
- ContextTrieNode &promoteMergeContextSamplesTree(ContextTrieNode &NodeToPromo);
- void mergeContextNode(ContextTrieNode &FromNode, ContextTrieNode &ToNode,
- StringRef ContextStrToRemove);
- ContextTrieNode &promoteMergeContextSamplesTree(ContextTrieNode &FromNode,
- ContextTrieNode &ToNodeParent,
- StringRef ContextStrToRemove);
-
- // Map from function name to context profiles (excluding base profile)
- StringMap<ContextSamplesTy> FuncToCtxtProfileSet;
-
- // Root node for context trie tree
- ContextTrieNode RootContext;
-};
-
-} // end namespace llvm
-#endif // LLVM_TRANSFORMS_IPO_SAMPLECONTEXTTRACKER_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- Transforms/IPO/SampleContextTracker.h --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// This file provides the interface for context-sensitive profile tracker used
+/// by CSSPGO.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_SAMPLECONTEXTTRACKER_H
+#define LLVM_TRANSFORMS_IPO_SAMPLECONTEXTTRACKER_H
+
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/ProfileData/SampleProf.h"
+#include <list>
+#include <map>
+#include <vector>
+
+using namespace llvm;
+using namespace sampleprof;
+
+namespace llvm {
+
+// Internal trie tree representation used for tracking context tree and sample
+// profiles. The path from root node to a given node represents the context of
+// that nodes' profile.
+class ContextTrieNode {
+public:
+ ContextTrieNode(ContextTrieNode *Parent = nullptr,
+ StringRef FName = StringRef(),
+ FunctionSamples *FSamples = nullptr,
+ LineLocation CallLoc = {0, 0})
+ : ParentContext(Parent), FuncName(FName), FuncSamples(FSamples),
+ CallSiteLoc(CallLoc){};
+ ContextTrieNode *getChildContext(const LineLocation &CallSite,
+ StringRef CalleeName);
+ ContextTrieNode *getHottestChildContext(const LineLocation &CallSite);
+ ContextTrieNode *getOrCreateChildContext(const LineLocation &CallSite,
+ StringRef CalleeName,
+ bool AllowCreate = true);
+
+ ContextTrieNode &moveToChildContext(const LineLocation &CallSite,
+ ContextTrieNode &&NodeToMove,
+ StringRef ContextStrToRemove,
+ bool DeleteNode = true);
+ void removeChildContext(const LineLocation &CallSite, StringRef CalleeName);
+ std::map<uint32_t, ContextTrieNode> &getAllChildContext();
+ const StringRef getFuncName() const;
+ FunctionSamples *getFunctionSamples() const;
+ void setFunctionSamples(FunctionSamples *FSamples);
+ LineLocation getCallSiteLoc() const;
+ ContextTrieNode *getParentContext() const;
+ void setParentContext(ContextTrieNode *Parent);
+ void dump();
+
+private:
+ static uint32_t nodeHash(StringRef ChildName, const LineLocation &Callsite);
+
+ // Map line+discriminator location to child context
+ std::map<uint32_t, ContextTrieNode> AllChildContext;
+
+ // Link to parent context node
+ ContextTrieNode *ParentContext;
+
+ // Function name for current context
+ StringRef FuncName;
+
+ // Function Samples for current context
+ FunctionSamples *FuncSamples;
+
+ // Callsite location in parent context
+ LineLocation CallSiteLoc;
+};
+
+// Profile tracker that manages profiles and its associated context. It
+// provides interfaces used by sample profile loader to query context profile or
+// base profile for given function or location; it also manages context tree
+// manipulation that is needed to accommodate inline decisions so we have
+// accurate post-inline profile for functions. Internally context profiles
+// are organized in a trie, with each node representing profile for specific
+// calling context and the context is identified by path from root to the node.
+class SampleContextTracker {
+public:
+ using ContextSamplesTy = SmallSet<FunctionSamples *, 16>;
+
+ SampleContextTracker(StringMap<FunctionSamples> &Profiles);
+ // Query context profile for a specific callee with given name at a given
+ // call-site. The full context is identified by location of call instruction.
+ FunctionSamples *getCalleeContextSamplesFor(const CallBase &Inst,
+ StringRef CalleeName);
+ // Get samples for indirect call targets for call site at given location.
+ std::vector<const FunctionSamples *>
+ getIndirectCalleeContextSamplesFor(const DILocation *DIL);
+ // Query context profile for a given location. The full context
+ // is identified by input DILocation.
+ FunctionSamples *getContextSamplesFor(const DILocation *DIL);
+ // Query context profile for a given sample contxt of a function.
+ FunctionSamples *getContextSamplesFor(const SampleContext &Context);
+ // Get all context profile for given function.
+ ContextSamplesTy &getAllContextSamplesFor(const Function &Func);
+ ContextSamplesTy &getAllContextSamplesFor(StringRef Name);
+ // Query base profile for a given function. A base profile is a merged view
+ // of all context profiles for contexts that are not inlined.
+ FunctionSamples *getBaseSamplesFor(const Function &Func,
+ bool MergeContext = true);
+ // Query base profile for a given function by name.
+ FunctionSamples *getBaseSamplesFor(StringRef Name, bool MergeContext);
+ // Mark a context profile as inlined when function is inlined.
+ // This makes sure that inlined context profile will be excluded in
+ // function's base profile.
+ void markContextSamplesInlined(const FunctionSamples *InlinedSamples);
+ void promoteMergeContextSamplesTree(const Instruction &Inst,
+ StringRef CalleeName);
+ void addCallGraphEdges(CallGraph &CG, StringMap<Function *> &SymbolMap);
+ // Dump the internal context profile trie.
+ void dump();
+
+private:
+ ContextTrieNode *getContextFor(const DILocation *DIL);
+ ContextTrieNode *getContextFor(const SampleContext &Context);
+ ContextTrieNode *getCalleeContextFor(const DILocation *DIL,
+ StringRef CalleeName);
+ ContextTrieNode *getOrCreateContextPath(const SampleContext &Context,
+ bool AllowCreate);
+ ContextTrieNode *getTopLevelContextNode(StringRef FName);
+ ContextTrieNode &addTopLevelContextNode(StringRef FName);
+ ContextTrieNode &promoteMergeContextSamplesTree(ContextTrieNode &NodeToPromo);
+ void mergeContextNode(ContextTrieNode &FromNode, ContextTrieNode &ToNode,
+ StringRef ContextStrToRemove);
+ ContextTrieNode &promoteMergeContextSamplesTree(ContextTrieNode &FromNode,
+ ContextTrieNode &ToNodeParent,
+ StringRef ContextStrToRemove);
+
+ // Map from function name to context profiles (excluding base profile)
+ StringMap<ContextSamplesTy> FuncToCtxtProfileSet;
+
+ // Root node for context trie tree
+ ContextTrieNode RootContext;
+};
+
+} // end namespace llvm
+#endif // LLVM_TRANSFORMS_IPO_SAMPLECONTEXTTRACKER_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/IPO/SampleProfile.h b/contrib/libs/llvm12/include/llvm/Transforms/IPO/SampleProfile.h
index be24fac675..9cc502eba6 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/IPO/SampleProfile.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/IPO/SampleProfile.h
@@ -31,18 +31,18 @@ class Module;
/// The sample profiler data loader pass.
class SampleProfileLoaderPass : public PassInfoMixin<SampleProfileLoaderPass> {
public:
- SampleProfileLoaderPass(
- std::string File = "", std::string RemappingFile = "",
- ThinOrFullLTOPhase LTOPhase = ThinOrFullLTOPhase::None)
+ SampleProfileLoaderPass(
+ std::string File = "", std::string RemappingFile = "",
+ ThinOrFullLTOPhase LTOPhase = ThinOrFullLTOPhase::None)
: ProfileFileName(File), ProfileRemappingFileName(RemappingFile),
- LTOPhase(LTOPhase) {}
+ LTOPhase(LTOPhase) {}
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
private:
std::string ProfileFileName;
std::string ProfileRemappingFileName;
- ThinOrFullLTOPhase LTOPhase;
+ ThinOrFullLTOPhase LTOPhase;
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/IPO/SampleProfileProbe.h b/contrib/libs/llvm12/include/llvm/Transforms/IPO/SampleProfileProbe.h
index 55d7546fe7..7163fe38c0 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/IPO/SampleProfileProbe.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/IPO/SampleProfileProbe.h
@@ -1,158 +1,158 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- Transforms/IPO/SampleProfileProbe.h ----------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file
-/// This file provides the interface for the pseudo probe implementation for
-/// AutoFDO.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_IPO_SAMPLEPROFILEPROBE_H
-#define LLVM_TRANSFORMS_IPO_SAMPLEPROFILEPROBE_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Analysis/CallGraphSCCPass.h"
-#include "llvm/Analysis/LazyCallGraph.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/IR/PassInstrumentation.h"
-#include "llvm/IR/PassManager.h"
-#include "llvm/IR/PseudoProbe.h"
-#include "llvm/ProfileData/SampleProf.h"
-#include "llvm/Target/TargetMachine.h"
-#include <unordered_map>
-
-namespace llvm {
-
-class Module;
-
-using namespace sampleprof;
-using BlockIdMap = std::unordered_map<BasicBlock *, uint32_t>;
-using InstructionIdMap = std::unordered_map<Instruction *, uint32_t>;
-using ProbeFactorMap = std::unordered_map<uint64_t, float>;
-using FuncProbeFactorMap = StringMap<ProbeFactorMap>;
-
-enum class PseudoProbeReservedId { Invalid = 0, Last = Invalid };
-
-class PseudoProbeDescriptor {
- uint64_t FunctionGUID;
- uint64_t FunctionHash;
-
-public:
- PseudoProbeDescriptor(uint64_t GUID, uint64_t Hash)
- : FunctionGUID(GUID), FunctionHash(Hash) {}
- uint64_t getFunctionGUID() const { return FunctionGUID; }
- uint64_t getFunctionHash() const { return FunctionHash; }
-};
-
-// A pseudo probe verifier that can be run after each IR passes to detect the
-// violation of updating probe factors. In principle, the sum of distribution
-// factor for a probe should be identical before and after a pass. For a
-// function pass, the factor sum for a probe would be typically 100%.
-class PseudoProbeVerifier {
-public:
- void registerCallbacks(PassInstrumentationCallbacks &PIC);
-
- // Implementation of pass instrumentation callbacks for new pass manager.
- void runAfterPass(StringRef PassID, Any IR);
-
-private:
- // Allow a little bias due the rounding to integral factors.
- constexpr static float DistributionFactorVariance = 0.02f;
- // Distribution factors from last pass.
- FuncProbeFactorMap FunctionProbeFactors;
-
- void collectProbeFactors(const BasicBlock *BB, ProbeFactorMap &ProbeFactors);
- void runAfterPass(const Module *M);
- void runAfterPass(const LazyCallGraph::SCC *C);
- void runAfterPass(const Function *F);
- void runAfterPass(const Loop *L);
- bool shouldVerifyFunction(const Function *F);
- void verifyProbeFactors(const Function *F,
- const ProbeFactorMap &ProbeFactors);
-};
-
-// This class serves sample counts correlation for SampleProfileLoader by
-// analyzing pseudo probes and their function descriptors injected by
-// SampleProfileProber.
-class PseudoProbeManager {
- DenseMap<uint64_t, PseudoProbeDescriptor> GUIDToProbeDescMap;
-
- const PseudoProbeDescriptor *getDesc(const Function &F) const;
-
-public:
- PseudoProbeManager(const Module &M);
- bool moduleIsProbed(const Module &M) const;
- bool profileIsValid(const Function &F, const FunctionSamples &Samples) const;
-};
-
-/// Sample profile pseudo prober.
-///
-/// Insert pseudo probes for block sampling and value sampling.
-class SampleProfileProber {
-public:
- // Give an empty module id when the prober is not used for instrumentation.
- SampleProfileProber(Function &F, const std::string &CurModuleUniqueId);
- void instrumentOneFunc(Function &F, TargetMachine *TM);
-
-private:
- Function *getFunction() const { return F; }
- uint64_t getFunctionHash() const { return FunctionHash; }
- uint32_t getBlockId(const BasicBlock *BB) const;
- uint32_t getCallsiteId(const Instruction *Call) const;
- void computeCFGHash();
- void computeProbeIdForBlocks();
- void computeProbeIdForCallsites();
-
- Function *F;
-
- /// The current module ID that is used to name a static object as a comdat
- /// group.
- std::string CurModuleUniqueId;
-
- /// A CFG hash code used to identify a function code changes.
- uint64_t FunctionHash;
-
- /// Map basic blocks to the their pseudo probe ids.
- BlockIdMap BlockProbeIds;
-
- /// Map indirect calls to the their pseudo probe ids.
- InstructionIdMap CallProbeIds;
-
- /// The ID of the last probe, Can be used to number a new probe.
- uint32_t LastProbeId;
-};
-
-class SampleProfileProbePass : public PassInfoMixin<SampleProfileProbePass> {
- TargetMachine *TM;
-
-public:
- SampleProfileProbePass(TargetMachine *TM) : TM(TM) {}
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-};
-
-class PseudoProbeUpdatePass : public PassInfoMixin<PseudoProbeUpdatePass> {
- void runOnFunction(Function &F, FunctionAnalysisManager &FAM);
-
-public:
- PseudoProbeUpdatePass() {}
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-};
-
-} // end namespace llvm
-#endif // LLVM_TRANSFORMS_IPO_SAMPLEPROFILEPROBE_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- Transforms/IPO/SampleProfileProbe.h ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// This file provides the interface for the pseudo probe implementation for
+/// AutoFDO.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_SAMPLEPROFILEPROBE_H
+#define LLVM_TRANSFORMS_IPO_SAMPLEPROFILEPROBE_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Analysis/CallGraphSCCPass.h"
+#include "llvm/Analysis/LazyCallGraph.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/PassInstrumentation.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PseudoProbe.h"
+#include "llvm/ProfileData/SampleProf.h"
+#include "llvm/Target/TargetMachine.h"
+#include <unordered_map>
+
+namespace llvm {
+
+class Module;
+
+using namespace sampleprof;
+using BlockIdMap = std::unordered_map<BasicBlock *, uint32_t>;
+using InstructionIdMap = std::unordered_map<Instruction *, uint32_t>;
+using ProbeFactorMap = std::unordered_map<uint64_t, float>;
+using FuncProbeFactorMap = StringMap<ProbeFactorMap>;
+
+enum class PseudoProbeReservedId { Invalid = 0, Last = Invalid };
+
+class PseudoProbeDescriptor {
+ uint64_t FunctionGUID;
+ uint64_t FunctionHash;
+
+public:
+ PseudoProbeDescriptor(uint64_t GUID, uint64_t Hash)
+ : FunctionGUID(GUID), FunctionHash(Hash) {}
+ uint64_t getFunctionGUID() const { return FunctionGUID; }
+ uint64_t getFunctionHash() const { return FunctionHash; }
+};
+
+// A pseudo probe verifier that can be run after each IR passes to detect the
+// violation of updating probe factors. In principle, the sum of distribution
+// factor for a probe should be identical before and after a pass. For a
+// function pass, the factor sum for a probe would be typically 100%.
+class PseudoProbeVerifier {
+public:
+ void registerCallbacks(PassInstrumentationCallbacks &PIC);
+
+ // Implementation of pass instrumentation callbacks for new pass manager.
+ void runAfterPass(StringRef PassID, Any IR);
+
+private:
+ // Allow a little bias due the rounding to integral factors.
+ constexpr static float DistributionFactorVariance = 0.02f;
+ // Distribution factors from last pass.
+ FuncProbeFactorMap FunctionProbeFactors;
+
+ void collectProbeFactors(const BasicBlock *BB, ProbeFactorMap &ProbeFactors);
+ void runAfterPass(const Module *M);
+ void runAfterPass(const LazyCallGraph::SCC *C);
+ void runAfterPass(const Function *F);
+ void runAfterPass(const Loop *L);
+ bool shouldVerifyFunction(const Function *F);
+ void verifyProbeFactors(const Function *F,
+ const ProbeFactorMap &ProbeFactors);
+};
+
+// This class serves sample counts correlation for SampleProfileLoader by
+// analyzing pseudo probes and their function descriptors injected by
+// SampleProfileProber.
+class PseudoProbeManager {
+ DenseMap<uint64_t, PseudoProbeDescriptor> GUIDToProbeDescMap;
+
+ const PseudoProbeDescriptor *getDesc(const Function &F) const;
+
+public:
+ PseudoProbeManager(const Module &M);
+ bool moduleIsProbed(const Module &M) const;
+ bool profileIsValid(const Function &F, const FunctionSamples &Samples) const;
+};
+
+/// Sample profile pseudo prober.
+///
+/// Insert pseudo probes for block sampling and value sampling.
+class SampleProfileProber {
+public:
+ // Give an empty module id when the prober is not used for instrumentation.
+ SampleProfileProber(Function &F, const std::string &CurModuleUniqueId);
+ void instrumentOneFunc(Function &F, TargetMachine *TM);
+
+private:
+ Function *getFunction() const { return F; }
+ uint64_t getFunctionHash() const { return FunctionHash; }
+ uint32_t getBlockId(const BasicBlock *BB) const;
+ uint32_t getCallsiteId(const Instruction *Call) const;
+ void computeCFGHash();
+ void computeProbeIdForBlocks();
+ void computeProbeIdForCallsites();
+
+ Function *F;
+
+ /// The current module ID that is used to name a static object as a comdat
+ /// group.
+ std::string CurModuleUniqueId;
+
+ /// A CFG hash code used to identify a function code changes.
+ uint64_t FunctionHash;
+
+ /// Map basic blocks to the their pseudo probe ids.
+ BlockIdMap BlockProbeIds;
+
+ /// Map indirect calls to the their pseudo probe ids.
+ InstructionIdMap CallProbeIds;
+
+ /// The ID of the last probe, Can be used to number a new probe.
+ uint32_t LastProbeId;
+};
+
+class SampleProfileProbePass : public PassInfoMixin<SampleProfileProbePass> {
+ TargetMachine *TM;
+
+public:
+ SampleProfileProbePass(TargetMachine *TM) : TM(TM) {}
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+class PseudoProbeUpdatePass : public PassInfoMixin<PseudoProbeUpdatePass> {
+ void runOnFunction(Function &F, FunctionAnalysisManager &FAM);
+
+public:
+ PseudoProbeUpdatePass() {}
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // end namespace llvm
+#endif // LLVM_TRANSFORMS_IPO_SAMPLEPROFILEPROBE_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/IPO/StripSymbols.h b/contrib/libs/llvm12/include/llvm/Transforms/IPO/StripSymbols.h
index 21ce7b836f..83829c1fa8 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/IPO/StripSymbols.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/IPO/StripSymbols.h
@@ -1,58 +1,58 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- StripSymbols.h - Strip symbols and debug info from a module --------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// The StripSymbols transformation implements code stripping. Specifically, it
-// can delete:
-//
-// * names for virtual registers
-// * symbols for internal globals and functions
-// * debug information
-//
-// Note that this transformation makes code much less readable, so it should
-// only be used in situations where the 'strip' utility would be used, such as
-// reducing code size or making it harder to reverse engineer code.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_IPO_STRIPSYMBOLS_H
-#define LLVM_TRANSFORMS_IPO_STRIPSYMBOLS_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-
-struct StripSymbolsPass : PassInfoMixin<StripSymbolsPass> {
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-};
-
-struct StripNonDebugSymbolsPass : PassInfoMixin<StripNonDebugSymbolsPass> {
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-};
-
-struct StripDebugDeclarePass : PassInfoMixin<StripDebugDeclarePass> {
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-};
-
-struct StripDeadDebugInfoPass : PassInfoMixin<StripDeadDebugInfoPass> {
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-};
-
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_IPO_STRIPSYMBOLS_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- StripSymbols.h - Strip symbols and debug info from a module --------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// The StripSymbols transformation implements code stripping. Specifically, it
+// can delete:
+//
+// * names for virtual registers
+// * symbols for internal globals and functions
+// * debug information
+//
+// Note that this transformation makes code much less readable, so it should
+// only be used in situations where the 'strip' utility would be used, such as
+// reducing code size or making it harder to reverse engineer code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_STRIPSYMBOLS_H
+#define LLVM_TRANSFORMS_IPO_STRIPSYMBOLS_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+struct StripSymbolsPass : PassInfoMixin<StripSymbolsPass> {
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+struct StripNonDebugSymbolsPass : PassInfoMixin<StripNonDebugSymbolsPass> {
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+struct StripDebugDeclarePass : PassInfoMixin<StripDebugDeclarePass> {
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+struct StripDeadDebugInfoPass : PassInfoMixin<StripDeadDebugInfoPass> {
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_STRIPSYMBOLS_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/IPO/WholeProgramDevirt.h b/contrib/libs/llvm12/include/llvm/Transforms/IPO/WholeProgramDevirt.h
index 0e0cc1fd16..135d78a1d3 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/IPO/WholeProgramDevirt.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/IPO/WholeProgramDevirt.h
@@ -230,9 +230,9 @@ void setAfterReturnValues(MutableArrayRef<VirtualCallTarget> Targets,
struct WholeProgramDevirtPass : public PassInfoMixin<WholeProgramDevirtPass> {
ModuleSummaryIndex *ExportSummary;
const ModuleSummaryIndex *ImportSummary;
- bool UseCommandLine = false;
- WholeProgramDevirtPass()
- : ExportSummary(nullptr), ImportSummary(nullptr), UseCommandLine(true) {}
+ bool UseCommandLine = false;
+ WholeProgramDevirtPass()
+ : ExportSummary(nullptr), ImportSummary(nullptr), UseCommandLine(true) {}
WholeProgramDevirtPass(ModuleSummaryIndex *ExportSummary,
const ModuleSummaryIndex *ImportSummary)
: ExportSummary(ExportSummary), ImportSummary(ImportSummary) {
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/InstCombine/InstCombiner.h b/contrib/libs/llvm12/include/llvm/Transforms/InstCombine/InstCombiner.h
index eff73fb86c..430bc69af6 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/InstCombine/InstCombiner.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/InstCombine/InstCombiner.h
@@ -1,539 +1,539 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- InstCombiner.h - InstCombine implementation --------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-/// \file
-///
-/// This file provides the interface for the instcombine pass implementation.
-/// The interface is used for generic transformations in this folder and
-/// target specific combinations in the targets.
-/// The visitor implementation is in \c InstCombinerImpl in
-/// \c InstCombineInternal.h.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_INSTCOMBINE_INSTCOMBINER_H
-#define LLVM_TRANSFORMS_INSTCOMBINE_INSTCOMBINER_H
-
-#include "llvm/Analysis/InstructionSimplify.h"
-#include "llvm/Analysis/TargetFolder.h"
-#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/PatternMatch.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/KnownBits.h"
-#include "llvm/Transforms/InstCombine/InstCombineWorklist.h"
-#include <cassert>
-
-#define DEBUG_TYPE "instcombine"
-
-namespace llvm {
-
-class AAResults;
-class AssumptionCache;
-class ProfileSummaryInfo;
-class TargetLibraryInfo;
-class TargetTransformInfo;
-
-/// The core instruction combiner logic.
-///
-/// This class provides both the logic to recursively visit instructions and
-/// combine them.
-class LLVM_LIBRARY_VISIBILITY InstCombiner {
- /// Only used to call target specific inst combining.
- TargetTransformInfo &TTI;
-
-public:
- /// Maximum size of array considered when transforming.
- uint64_t MaxArraySizeForCombine = 0;
-
- /// An IRBuilder that automatically inserts new instructions into the
- /// worklist.
- using BuilderTy = IRBuilder<TargetFolder, IRBuilderCallbackInserter>;
- BuilderTy &Builder;
-
-protected:
- /// A worklist of the instructions that need to be simplified.
- InstCombineWorklist &Worklist;
-
- // Mode in which we are running the combiner.
- const bool MinimizeSize;
-
- AAResults *AA;
-
- // Required analyses.
- AssumptionCache &AC;
- TargetLibraryInfo &TLI;
- DominatorTree &DT;
- const DataLayout &DL;
- const SimplifyQuery SQ;
- OptimizationRemarkEmitter &ORE;
- BlockFrequencyInfo *BFI;
- ProfileSummaryInfo *PSI;
-
- // Optional analyses. When non-null, these can both be used to do better
- // combining and will be updated to reflect any changes.
- LoopInfo *LI;
-
- bool MadeIRChange = false;
-
-public:
- InstCombiner(InstCombineWorklist &Worklist, BuilderTy &Builder,
- bool MinimizeSize, AAResults *AA, AssumptionCache &AC,
- TargetLibraryInfo &TLI, TargetTransformInfo &TTI,
- DominatorTree &DT, OptimizationRemarkEmitter &ORE,
- BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI,
- const DataLayout &DL, LoopInfo *LI)
- : TTI(TTI), Builder(Builder), Worklist(Worklist),
- MinimizeSize(MinimizeSize), AA(AA), AC(AC), TLI(TLI), DT(DT), DL(DL),
- SQ(DL, &TLI, &DT, &AC), ORE(ORE), BFI(BFI), PSI(PSI), LI(LI) {}
-
- virtual ~InstCombiner() {}
-
- /// Return the source operand of a potentially bitcasted value while
- /// optionally checking if it has one use. If there is no bitcast or the one
- /// use check is not met, return the input value itself.
- static Value *peekThroughBitcast(Value *V, bool OneUseOnly = false) {
- if (auto *BitCast = dyn_cast<BitCastInst>(V))
- if (!OneUseOnly || BitCast->hasOneUse())
- return BitCast->getOperand(0);
-
- // V is not a bitcast or V has more than one use and OneUseOnly is true.
- return V;
- }
-
- /// Assign a complexity or rank value to LLVM Values. This is used to reduce
- /// the amount of pattern matching needed for compares and commutative
- /// instructions. For example, if we have:
- /// icmp ugt X, Constant
- /// or
- /// xor (add X, Constant), cast Z
- ///
- /// We do not have to consider the commuted variants of these patterns because
- /// canonicalization based on complexity guarantees the above ordering.
- ///
- /// This routine maps IR values to various complexity ranks:
- /// 0 -> undef
- /// 1 -> Constants
- /// 2 -> Other non-instructions
- /// 3 -> Arguments
- /// 4 -> Cast and (f)neg/not instructions
- /// 5 -> Other instructions
- static unsigned getComplexity(Value *V) {
- if (isa<Instruction>(V)) {
- if (isa<CastInst>(V) || match(V, m_Neg(PatternMatch::m_Value())) ||
- match(V, m_Not(PatternMatch::m_Value())) ||
- match(V, m_FNeg(PatternMatch::m_Value())))
- return 4;
- return 5;
- }
- if (isa<Argument>(V))
- return 3;
- return isa<Constant>(V) ? (isa<UndefValue>(V) ? 0 : 1) : 2;
- }
-
- /// Predicate canonicalization reduces the number of patterns that need to be
- /// matched by other transforms. For example, we may swap the operands of a
- /// conditional branch or select to create a compare with a canonical
- /// (inverted) predicate which is then more likely to be matched with other
- /// values.
- static bool isCanonicalPredicate(CmpInst::Predicate Pred) {
- switch (Pred) {
- case CmpInst::ICMP_NE:
- case CmpInst::ICMP_ULE:
- case CmpInst::ICMP_SLE:
- case CmpInst::ICMP_UGE:
- case CmpInst::ICMP_SGE:
- // TODO: There are 16 FCMP predicates. Should others be (not) canonical?
- case CmpInst::FCMP_ONE:
- case CmpInst::FCMP_OLE:
- case CmpInst::FCMP_OGE:
- return false;
- default:
- return true;
- }
- }
-
- /// Given an exploded icmp instruction, return true if the comparison only
- /// checks the sign bit. If it only checks the sign bit, set TrueIfSigned if
- /// the result of the comparison is true when the input value is signed.
- static bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS,
- bool &TrueIfSigned) {
- switch (Pred) {
- case ICmpInst::ICMP_SLT: // True if LHS s< 0
- TrueIfSigned = true;
- return RHS.isNullValue();
- case ICmpInst::ICMP_SLE: // True if LHS s<= -1
- TrueIfSigned = true;
- return RHS.isAllOnesValue();
- case ICmpInst::ICMP_SGT: // True if LHS s> -1
- TrueIfSigned = false;
- return RHS.isAllOnesValue();
- case ICmpInst::ICMP_SGE: // True if LHS s>= 0
- TrueIfSigned = false;
- return RHS.isNullValue();
- case ICmpInst::ICMP_UGT:
- // True if LHS u> RHS and RHS == sign-bit-mask - 1
- TrueIfSigned = true;
- return RHS.isMaxSignedValue();
- case ICmpInst::ICMP_UGE:
- // True if LHS u>= RHS and RHS == sign-bit-mask (2^7, 2^15, 2^31, etc)
- TrueIfSigned = true;
- return RHS.isMinSignedValue();
- case ICmpInst::ICMP_ULT:
- // True if LHS u< RHS and RHS == sign-bit-mask (2^7, 2^15, 2^31, etc)
- TrueIfSigned = false;
- return RHS.isMinSignedValue();
- case ICmpInst::ICMP_ULE:
- // True if LHS u<= RHS and RHS == sign-bit-mask - 1
- TrueIfSigned = false;
- return RHS.isMaxSignedValue();
- default:
- return false;
- }
- }
-
- /// Add one to a Constant
- static Constant *AddOne(Constant *C) {
- return ConstantExpr::getAdd(C, ConstantInt::get(C->getType(), 1));
- }
-
- /// Subtract one from a Constant
- static Constant *SubOne(Constant *C) {
- return ConstantExpr::getSub(C, ConstantInt::get(C->getType(), 1));
- }
-
- llvm::Optional<std::pair<
- CmpInst::Predicate,
- Constant *>> static getFlippedStrictnessPredicateAndConstant(CmpInst::
- Predicate
- Pred,
- Constant *C);
-
- static bool shouldAvoidAbsorbingNotIntoSelect(const SelectInst &SI) {
- // a ? b : false and a ? true : b are the canonical form of logical and/or.
- // This includes !a ? b : false and !a ? true : b. Absorbing the not into
- // the select by swapping operands would break recognition of this pattern
- // in other analyses, so don't do that.
- return match(&SI, PatternMatch::m_LogicalAnd(PatternMatch::m_Value(),
- PatternMatch::m_Value())) ||
- match(&SI, PatternMatch::m_LogicalOr(PatternMatch::m_Value(),
- PatternMatch::m_Value()));
- }
-
- /// Return true if the specified value is free to invert (apply ~ to).
- /// This happens in cases where the ~ can be eliminated. If WillInvertAllUses
- /// is true, work under the assumption that the caller intends to remove all
- /// uses of V and only keep uses of ~V.
- ///
- /// See also: canFreelyInvertAllUsersOf()
- static bool isFreeToInvert(Value *V, bool WillInvertAllUses) {
- // ~(~(X)) -> X.
- if (match(V, m_Not(PatternMatch::m_Value())))
- return true;
-
- // Constants can be considered to be not'ed values.
- if (match(V, PatternMatch::m_AnyIntegralConstant()))
- return true;
-
- // Compares can be inverted if all of their uses are being modified to use
- // the ~V.
- if (isa<CmpInst>(V))
- return WillInvertAllUses;
-
- // If `V` is of the form `A + Constant` then `-1 - V` can be folded into
- // `(-1 - Constant) - A` if we are willing to invert all of the uses.
- if (BinaryOperator *BO = dyn_cast<BinaryOperator>(V))
- if (BO->getOpcode() == Instruction::Add ||
- BO->getOpcode() == Instruction::Sub)
- if (isa<Constant>(BO->getOperand(0)) ||
- isa<Constant>(BO->getOperand(1)))
- return WillInvertAllUses;
-
- // Selects with invertible operands are freely invertible
- if (match(V,
- m_Select(PatternMatch::m_Value(), m_Not(PatternMatch::m_Value()),
- m_Not(PatternMatch::m_Value()))))
- return WillInvertAllUses;
-
- return false;
- }
-
- /// Given i1 V, can every user of V be freely adapted if V is changed to !V ?
- /// InstCombine's freelyInvertAllUsersOf() must be kept in sync with this fn.
- ///
- /// See also: isFreeToInvert()
- static bool canFreelyInvertAllUsersOf(Value *V, Value *IgnoredUser) {
- // Look at every user of V.
- for (Use &U : V->uses()) {
- if (U.getUser() == IgnoredUser)
- continue; // Don't consider this user.
-
- auto *I = cast<Instruction>(U.getUser());
- switch (I->getOpcode()) {
- case Instruction::Select:
- if (U.getOperandNo() != 0) // Only if the value is used as select cond.
- return false;
- if (shouldAvoidAbsorbingNotIntoSelect(*cast<SelectInst>(I)))
- return false;
- break;
- case Instruction::Br:
- assert(U.getOperandNo() == 0 && "Must be branching on that value.");
- break; // Free to invert by swapping true/false values/destinations.
- case Instruction::Xor: // Can invert 'xor' if it's a 'not', by ignoring
- // it.
- if (!match(I, m_Not(PatternMatch::m_Value())))
- return false; // Not a 'not'.
- break;
- default:
- return false; // Don't know, likely not freely invertible.
- }
- // So far all users were free to invert...
- }
- return true; // Can freely invert all users!
- }
-
- /// Some binary operators require special handling to avoid poison and
- /// undefined behavior. If a constant vector has undef elements, replace those
- /// undefs with identity constants if possible because those are always safe
- /// to execute. If no identity constant exists, replace undef with some other
- /// safe constant.
- static Constant *
- getSafeVectorConstantForBinop(BinaryOperator::BinaryOps Opcode, Constant *In,
- bool IsRHSConstant) {
- auto *InVTy = cast<FixedVectorType>(In->getType());
-
- Type *EltTy = InVTy->getElementType();
- auto *SafeC = ConstantExpr::getBinOpIdentity(Opcode, EltTy, IsRHSConstant);
- if (!SafeC) {
- // TODO: Should this be available as a constant utility function? It is
- // similar to getBinOpAbsorber().
- if (IsRHSConstant) {
- switch (Opcode) {
- case Instruction::SRem: // X % 1 = 0
- case Instruction::URem: // X %u 1 = 0
- SafeC = ConstantInt::get(EltTy, 1);
- break;
- case Instruction::FRem: // X % 1.0 (doesn't simplify, but it is safe)
- SafeC = ConstantFP::get(EltTy, 1.0);
- break;
- default:
- llvm_unreachable(
- "Only rem opcodes have no identity constant for RHS");
- }
- } else {
- switch (Opcode) {
- case Instruction::Shl: // 0 << X = 0
- case Instruction::LShr: // 0 >>u X = 0
- case Instruction::AShr: // 0 >> X = 0
- case Instruction::SDiv: // 0 / X = 0
- case Instruction::UDiv: // 0 /u X = 0
- case Instruction::SRem: // 0 % X = 0
- case Instruction::URem: // 0 %u X = 0
- case Instruction::Sub: // 0 - X (doesn't simplify, but it is safe)
- case Instruction::FSub: // 0.0 - X (doesn't simplify, but it is safe)
- case Instruction::FDiv: // 0.0 / X (doesn't simplify, but it is safe)
- case Instruction::FRem: // 0.0 % X = 0
- SafeC = Constant::getNullValue(EltTy);
- break;
- default:
- llvm_unreachable("Expected to find identity constant for opcode");
- }
- }
- }
- assert(SafeC && "Must have safe constant for binop");
- unsigned NumElts = InVTy->getNumElements();
- SmallVector<Constant *, 16> Out(NumElts);
- for (unsigned i = 0; i != NumElts; ++i) {
- Constant *C = In->getAggregateElement(i);
- Out[i] = isa<UndefValue>(C) ? SafeC : C;
- }
- return ConstantVector::get(Out);
- }
-
- /// Create and insert the idiom we use to indicate a block is unreachable
- /// without having to rewrite the CFG from within InstCombine.
- static void CreateNonTerminatorUnreachable(Instruction *InsertAt) {
- auto &Ctx = InsertAt->getContext();
- new StoreInst(ConstantInt::getTrue(Ctx),
- UndefValue::get(Type::getInt1PtrTy(Ctx)), InsertAt);
- }
-
- void addToWorklist(Instruction *I) { Worklist.push(I); }
-
- AssumptionCache &getAssumptionCache() const { return AC; }
- TargetLibraryInfo &getTargetLibraryInfo() const { return TLI; }
- DominatorTree &getDominatorTree() const { return DT; }
- const DataLayout &getDataLayout() const { return DL; }
- const SimplifyQuery &getSimplifyQuery() const { return SQ; }
- OptimizationRemarkEmitter &getOptimizationRemarkEmitter() const {
- return ORE;
- }
- BlockFrequencyInfo *getBlockFrequencyInfo() const { return BFI; }
- ProfileSummaryInfo *getProfileSummaryInfo() const { return PSI; }
- LoopInfo *getLoopInfo() const { return LI; }
-
- // Call target specific combiners
- Optional<Instruction *> targetInstCombineIntrinsic(IntrinsicInst &II);
- Optional<Value *>
- targetSimplifyDemandedUseBitsIntrinsic(IntrinsicInst &II, APInt DemandedMask,
- KnownBits &Known,
- bool &KnownBitsComputed);
- Optional<Value *> targetSimplifyDemandedVectorEltsIntrinsic(
- IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
- APInt &UndefElts2, APInt &UndefElts3,
- std::function<void(Instruction *, unsigned, APInt, APInt &)>
- SimplifyAndSetOp);
-
- /// Inserts an instruction \p New before instruction \p Old
- ///
- /// Also adds the new instruction to the worklist and returns \p New so that
- /// it is suitable for use as the return from the visitation patterns.
- Instruction *InsertNewInstBefore(Instruction *New, Instruction &Old) {
- assert(New && !New->getParent() &&
- "New instruction already inserted into a basic block!");
- BasicBlock *BB = Old.getParent();
- BB->getInstList().insert(Old.getIterator(), New); // Insert inst
- Worklist.push(New);
- return New;
- }
-
- /// Same as InsertNewInstBefore, but also sets the debug loc.
- Instruction *InsertNewInstWith(Instruction *New, Instruction &Old) {
- New->setDebugLoc(Old.getDebugLoc());
- return InsertNewInstBefore(New, Old);
- }
-
- /// A combiner-aware RAUW-like routine.
- ///
- /// This method is to be used when an instruction is found to be dead,
- /// replaceable with another preexisting expression. Here we add all uses of
- /// I to the worklist, replace all uses of I with the new value, then return
- /// I, so that the inst combiner will know that I was modified.
- Instruction *replaceInstUsesWith(Instruction &I, Value *V) {
- // If there are no uses to replace, then we return nullptr to indicate that
- // no changes were made to the program.
- if (I.use_empty())
- return nullptr;
-
- Worklist.pushUsersToWorkList(I); // Add all modified instrs to worklist.
-
- // If we are replacing the instruction with itself, this must be in a
- // segment of unreachable code, so just clobber the instruction.
- if (&I == V)
- V = UndefValue::get(I.getType());
-
- LLVM_DEBUG(dbgs() << "IC: Replacing " << I << "\n"
- << " with " << *V << '\n');
-
- I.replaceAllUsesWith(V);
- return &I;
- }
-
- /// Replace operand of instruction and add old operand to the worklist.
- Instruction *replaceOperand(Instruction &I, unsigned OpNum, Value *V) {
- Worklist.addValue(I.getOperand(OpNum));
- I.setOperand(OpNum, V);
- return &I;
- }
-
- /// Replace use and add the previously used value to the worklist.
- void replaceUse(Use &U, Value *NewValue) {
- Worklist.addValue(U);
- U = NewValue;
- }
-
- /// Combiner aware instruction erasure.
- ///
- /// When dealing with an instruction that has side effects or produces a void
- /// value, we can't rely on DCE to delete the instruction. Instead, visit
- /// methods should return the value returned by this function.
- virtual Instruction *eraseInstFromFunction(Instruction &I) = 0;
-
- void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth,
- const Instruction *CxtI) const {
- llvm::computeKnownBits(V, Known, DL, Depth, &AC, CxtI, &DT);
- }
-
- KnownBits computeKnownBits(const Value *V, unsigned Depth,
- const Instruction *CxtI) const {
- return llvm::computeKnownBits(V, DL, Depth, &AC, CxtI, &DT);
- }
-
- bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero = false,
- unsigned Depth = 0,
- const Instruction *CxtI = nullptr) {
- return llvm::isKnownToBeAPowerOfTwo(V, DL, OrZero, Depth, &AC, CxtI, &DT);
- }
-
- bool MaskedValueIsZero(const Value *V, const APInt &Mask, unsigned Depth = 0,
- const Instruction *CxtI = nullptr) const {
- return llvm::MaskedValueIsZero(V, Mask, DL, Depth, &AC, CxtI, &DT);
- }
-
- unsigned ComputeNumSignBits(const Value *Op, unsigned Depth = 0,
- const Instruction *CxtI = nullptr) const {
- return llvm::ComputeNumSignBits(Op, DL, Depth, &AC, CxtI, &DT);
- }
-
- OverflowResult computeOverflowForUnsignedMul(const Value *LHS,
- const Value *RHS,
- const Instruction *CxtI) const {
- return llvm::computeOverflowForUnsignedMul(LHS, RHS, DL, &AC, CxtI, &DT);
- }
-
- OverflowResult computeOverflowForSignedMul(const Value *LHS, const Value *RHS,
- const Instruction *CxtI) const {
- return llvm::computeOverflowForSignedMul(LHS, RHS, DL, &AC, CxtI, &DT);
- }
-
- OverflowResult computeOverflowForUnsignedAdd(const Value *LHS,
- const Value *RHS,
- const Instruction *CxtI) const {
- return llvm::computeOverflowForUnsignedAdd(LHS, RHS, DL, &AC, CxtI, &DT);
- }
-
- OverflowResult computeOverflowForSignedAdd(const Value *LHS, const Value *RHS,
- const Instruction *CxtI) const {
- return llvm::computeOverflowForSignedAdd(LHS, RHS, DL, &AC, CxtI, &DT);
- }
-
- OverflowResult computeOverflowForUnsignedSub(const Value *LHS,
- const Value *RHS,
- const Instruction *CxtI) const {
- return llvm::computeOverflowForUnsignedSub(LHS, RHS, DL, &AC, CxtI, &DT);
- }
-
- OverflowResult computeOverflowForSignedSub(const Value *LHS, const Value *RHS,
- const Instruction *CxtI) const {
- return llvm::computeOverflowForSignedSub(LHS, RHS, DL, &AC, CxtI, &DT);
- }
-
- virtual bool SimplifyDemandedBits(Instruction *I, unsigned OpNo,
- const APInt &DemandedMask, KnownBits &Known,
- unsigned Depth = 0) = 0;
- virtual Value *
- SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, APInt &UndefElts,
- unsigned Depth = 0,
- bool AllowMultipleUsers = false) = 0;
-};
-
-} // namespace llvm
-
-#undef DEBUG_TYPE
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- InstCombiner.h - InstCombine implementation --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file provides the interface for the instcombine pass implementation.
+/// The interface is used for generic transformations in this folder and
+/// target specific combinations in the targets.
+/// The visitor implementation is in \c InstCombinerImpl in
+/// \c InstCombineInternal.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_INSTCOMBINE_INSTCOMBINER_H
+#define LLVM_TRANSFORMS_INSTCOMBINE_INSTCOMBINER_H
+
+#include "llvm/Analysis/InstructionSimplify.h"
+#include "llvm/Analysis/TargetFolder.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/PatternMatch.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/KnownBits.h"
+#include "llvm/Transforms/InstCombine/InstCombineWorklist.h"
+#include <cassert>
+
+#define DEBUG_TYPE "instcombine"
+
+namespace llvm {
+
+class AAResults;
+class AssumptionCache;
+class ProfileSummaryInfo;
+class TargetLibraryInfo;
+class TargetTransformInfo;
+
+/// The core instruction combiner logic.
+///
+/// This class provides both the logic to recursively visit instructions and
+/// combine them.
+class LLVM_LIBRARY_VISIBILITY InstCombiner {
+ /// Only used to call target specific inst combining.
+ TargetTransformInfo &TTI;
+
+public:
+ /// Maximum size of array considered when transforming.
+ uint64_t MaxArraySizeForCombine = 0;
+
+ /// An IRBuilder that automatically inserts new instructions into the
+ /// worklist.
+ using BuilderTy = IRBuilder<TargetFolder, IRBuilderCallbackInserter>;
+ BuilderTy &Builder;
+
+protected:
+ /// A worklist of the instructions that need to be simplified.
+ InstCombineWorklist &Worklist;
+
+ // Mode in which we are running the combiner.
+ const bool MinimizeSize;
+
+ AAResults *AA;
+
+ // Required analyses.
+ AssumptionCache &AC;
+ TargetLibraryInfo &TLI;
+ DominatorTree &DT;
+ const DataLayout &DL;
+ const SimplifyQuery SQ;
+ OptimizationRemarkEmitter &ORE;
+ BlockFrequencyInfo *BFI;
+ ProfileSummaryInfo *PSI;
+
+ // Optional analyses. When non-null, these can both be used to do better
+ // combining and will be updated to reflect any changes.
+ LoopInfo *LI;
+
+ bool MadeIRChange = false;
+
+public:
+ InstCombiner(InstCombineWorklist &Worklist, BuilderTy &Builder,
+ bool MinimizeSize, AAResults *AA, AssumptionCache &AC,
+ TargetLibraryInfo &TLI, TargetTransformInfo &TTI,
+ DominatorTree &DT, OptimizationRemarkEmitter &ORE,
+ BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI,
+ const DataLayout &DL, LoopInfo *LI)
+ : TTI(TTI), Builder(Builder), Worklist(Worklist),
+ MinimizeSize(MinimizeSize), AA(AA), AC(AC), TLI(TLI), DT(DT), DL(DL),
+ SQ(DL, &TLI, &DT, &AC), ORE(ORE), BFI(BFI), PSI(PSI), LI(LI) {}
+
+ virtual ~InstCombiner() {}
+
+ /// Return the source operand of a potentially bitcasted value while
+ /// optionally checking if it has one use. If there is no bitcast or the one
+ /// use check is not met, return the input value itself.
+ static Value *peekThroughBitcast(Value *V, bool OneUseOnly = false) {
+ if (auto *BitCast = dyn_cast<BitCastInst>(V))
+ if (!OneUseOnly || BitCast->hasOneUse())
+ return BitCast->getOperand(0);
+
+ // V is not a bitcast or V has more than one use and OneUseOnly is true.
+ return V;
+ }
+
+ /// Assign a complexity or rank value to LLVM Values. This is used to reduce
+ /// the amount of pattern matching needed for compares and commutative
+ /// instructions. For example, if we have:
+ /// icmp ugt X, Constant
+ /// or
+ /// xor (add X, Constant), cast Z
+ ///
+ /// We do not have to consider the commuted variants of these patterns because
+ /// canonicalization based on complexity guarantees the above ordering.
+ ///
+ /// This routine maps IR values to various complexity ranks:
+ /// 0 -> undef
+ /// 1 -> Constants
+ /// 2 -> Other non-instructions
+ /// 3 -> Arguments
+ /// 4 -> Cast and (f)neg/not instructions
+ /// 5 -> Other instructions
+ static unsigned getComplexity(Value *V) {
+ if (isa<Instruction>(V)) {
+ if (isa<CastInst>(V) || match(V, m_Neg(PatternMatch::m_Value())) ||
+ match(V, m_Not(PatternMatch::m_Value())) ||
+ match(V, m_FNeg(PatternMatch::m_Value())))
+ return 4;
+ return 5;
+ }
+ if (isa<Argument>(V))
+ return 3;
+ return isa<Constant>(V) ? (isa<UndefValue>(V) ? 0 : 1) : 2;
+ }
+
+ /// Predicate canonicalization reduces the number of patterns that need to be
+ /// matched by other transforms. For example, we may swap the operands of a
+ /// conditional branch or select to create a compare with a canonical
+ /// (inverted) predicate which is then more likely to be matched with other
+ /// values.
+ static bool isCanonicalPredicate(CmpInst::Predicate Pred) {
+ switch (Pred) {
+ case CmpInst::ICMP_NE:
+ case CmpInst::ICMP_ULE:
+ case CmpInst::ICMP_SLE:
+ case CmpInst::ICMP_UGE:
+ case CmpInst::ICMP_SGE:
+ // TODO: There are 16 FCMP predicates. Should others be (not) canonical?
+ case CmpInst::FCMP_ONE:
+ case CmpInst::FCMP_OLE:
+ case CmpInst::FCMP_OGE:
+ return false;
+ default:
+ return true;
+ }
+ }
+
+ /// Given an exploded icmp instruction, return true if the comparison only
+ /// checks the sign bit. If it only checks the sign bit, set TrueIfSigned if
+ /// the result of the comparison is true when the input value is signed.
+ static bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS,
+ bool &TrueIfSigned) {
+ switch (Pred) {
+ case ICmpInst::ICMP_SLT: // True if LHS s< 0
+ TrueIfSigned = true;
+ return RHS.isNullValue();
+ case ICmpInst::ICMP_SLE: // True if LHS s<= -1
+ TrueIfSigned = true;
+ return RHS.isAllOnesValue();
+ case ICmpInst::ICMP_SGT: // True if LHS s> -1
+ TrueIfSigned = false;
+ return RHS.isAllOnesValue();
+ case ICmpInst::ICMP_SGE: // True if LHS s>= 0
+ TrueIfSigned = false;
+ return RHS.isNullValue();
+ case ICmpInst::ICMP_UGT:
+ // True if LHS u> RHS and RHS == sign-bit-mask - 1
+ TrueIfSigned = true;
+ return RHS.isMaxSignedValue();
+ case ICmpInst::ICMP_UGE:
+ // True if LHS u>= RHS and RHS == sign-bit-mask (2^7, 2^15, 2^31, etc)
+ TrueIfSigned = true;
+ return RHS.isMinSignedValue();
+ case ICmpInst::ICMP_ULT:
+ // True if LHS u< RHS and RHS == sign-bit-mask (2^7, 2^15, 2^31, etc)
+ TrueIfSigned = false;
+ return RHS.isMinSignedValue();
+ case ICmpInst::ICMP_ULE:
+ // True if LHS u<= RHS and RHS == sign-bit-mask - 1
+ TrueIfSigned = false;
+ return RHS.isMaxSignedValue();
+ default:
+ return false;
+ }
+ }
+
+ /// Add one to a Constant
+ static Constant *AddOne(Constant *C) {
+ return ConstantExpr::getAdd(C, ConstantInt::get(C->getType(), 1));
+ }
+
+ /// Subtract one from a Constant
+ static Constant *SubOne(Constant *C) {
+ return ConstantExpr::getSub(C, ConstantInt::get(C->getType(), 1));
+ }
+
+ llvm::Optional<std::pair<
+ CmpInst::Predicate,
+ Constant *>> static getFlippedStrictnessPredicateAndConstant(CmpInst::
+ Predicate
+ Pred,
+ Constant *C);
+
+ static bool shouldAvoidAbsorbingNotIntoSelect(const SelectInst &SI) {
+ // a ? b : false and a ? true : b are the canonical form of logical and/or.
+ // This includes !a ? b : false and !a ? true : b. Absorbing the not into
+ // the select by swapping operands would break recognition of this pattern
+ // in other analyses, so don't do that.
+ return match(&SI, PatternMatch::m_LogicalAnd(PatternMatch::m_Value(),
+ PatternMatch::m_Value())) ||
+ match(&SI, PatternMatch::m_LogicalOr(PatternMatch::m_Value(),
+ PatternMatch::m_Value()));
+ }
+
+ /// Return true if the specified value is free to invert (apply ~ to).
+ /// This happens in cases where the ~ can be eliminated. If WillInvertAllUses
+ /// is true, work under the assumption that the caller intends to remove all
+ /// uses of V and only keep uses of ~V.
+ ///
+ /// See also: canFreelyInvertAllUsersOf()
+ static bool isFreeToInvert(Value *V, bool WillInvertAllUses) {
+ // ~(~(X)) -> X.
+ if (match(V, m_Not(PatternMatch::m_Value())))
+ return true;
+
+ // Constants can be considered to be not'ed values.
+ if (match(V, PatternMatch::m_AnyIntegralConstant()))
+ return true;
+
+ // Compares can be inverted if all of their uses are being modified to use
+ // the ~V.
+ if (isa<CmpInst>(V))
+ return WillInvertAllUses;
+
+ // If `V` is of the form `A + Constant` then `-1 - V` can be folded into
+ // `(-1 - Constant) - A` if we are willing to invert all of the uses.
+ if (BinaryOperator *BO = dyn_cast<BinaryOperator>(V))
+ if (BO->getOpcode() == Instruction::Add ||
+ BO->getOpcode() == Instruction::Sub)
+ if (isa<Constant>(BO->getOperand(0)) ||
+ isa<Constant>(BO->getOperand(1)))
+ return WillInvertAllUses;
+
+ // Selects with invertible operands are freely invertible
+ if (match(V,
+ m_Select(PatternMatch::m_Value(), m_Not(PatternMatch::m_Value()),
+ m_Not(PatternMatch::m_Value()))))
+ return WillInvertAllUses;
+
+ return false;
+ }
+
+ /// Given i1 V, can every user of V be freely adapted if V is changed to !V ?
+ /// InstCombine's freelyInvertAllUsersOf() must be kept in sync with this fn.
+ ///
+ /// See also: isFreeToInvert()
+ static bool canFreelyInvertAllUsersOf(Value *V, Value *IgnoredUser) {
+ // Look at every user of V.
+ for (Use &U : V->uses()) {
+ if (U.getUser() == IgnoredUser)
+ continue; // Don't consider this user.
+
+ auto *I = cast<Instruction>(U.getUser());
+ switch (I->getOpcode()) {
+ case Instruction::Select:
+ if (U.getOperandNo() != 0) // Only if the value is used as select cond.
+ return false;
+ if (shouldAvoidAbsorbingNotIntoSelect(*cast<SelectInst>(I)))
+ return false;
+ break;
+ case Instruction::Br:
+ assert(U.getOperandNo() == 0 && "Must be branching on that value.");
+ break; // Free to invert by swapping true/false values/destinations.
+ case Instruction::Xor: // Can invert 'xor' if it's a 'not', by ignoring
+ // it.
+ if (!match(I, m_Not(PatternMatch::m_Value())))
+ return false; // Not a 'not'.
+ break;
+ default:
+ return false; // Don't know, likely not freely invertible.
+ }
+ // So far all users were free to invert...
+ }
+ return true; // Can freely invert all users!
+ }
+
+ /// Some binary operators require special handling to avoid poison and
+ /// undefined behavior. If a constant vector has undef elements, replace those
+ /// undefs with identity constants if possible because those are always safe
+ /// to execute. If no identity constant exists, replace undef with some other
+ /// safe constant.
+ static Constant *
+ getSafeVectorConstantForBinop(BinaryOperator::BinaryOps Opcode, Constant *In,
+ bool IsRHSConstant) {
+ auto *InVTy = cast<FixedVectorType>(In->getType());
+
+ Type *EltTy = InVTy->getElementType();
+ auto *SafeC = ConstantExpr::getBinOpIdentity(Opcode, EltTy, IsRHSConstant);
+ if (!SafeC) {
+ // TODO: Should this be available as a constant utility function? It is
+ // similar to getBinOpAbsorber().
+ if (IsRHSConstant) {
+ switch (Opcode) {
+ case Instruction::SRem: // X % 1 = 0
+ case Instruction::URem: // X %u 1 = 0
+ SafeC = ConstantInt::get(EltTy, 1);
+ break;
+ case Instruction::FRem: // X % 1.0 (doesn't simplify, but it is safe)
+ SafeC = ConstantFP::get(EltTy, 1.0);
+ break;
+ default:
+ llvm_unreachable(
+ "Only rem opcodes have no identity constant for RHS");
+ }
+ } else {
+ switch (Opcode) {
+ case Instruction::Shl: // 0 << X = 0
+ case Instruction::LShr: // 0 >>u X = 0
+ case Instruction::AShr: // 0 >> X = 0
+ case Instruction::SDiv: // 0 / X = 0
+ case Instruction::UDiv: // 0 /u X = 0
+ case Instruction::SRem: // 0 % X = 0
+ case Instruction::URem: // 0 %u X = 0
+ case Instruction::Sub: // 0 - X (doesn't simplify, but it is safe)
+ case Instruction::FSub: // 0.0 - X (doesn't simplify, but it is safe)
+ case Instruction::FDiv: // 0.0 / X (doesn't simplify, but it is safe)
+ case Instruction::FRem: // 0.0 % X = 0
+ SafeC = Constant::getNullValue(EltTy);
+ break;
+ default:
+ llvm_unreachable("Expected to find identity constant for opcode");
+ }
+ }
+ }
+ assert(SafeC && "Must have safe constant for binop");
+ unsigned NumElts = InVTy->getNumElements();
+ SmallVector<Constant *, 16> Out(NumElts);
+ for (unsigned i = 0; i != NumElts; ++i) {
+ Constant *C = In->getAggregateElement(i);
+ Out[i] = isa<UndefValue>(C) ? SafeC : C;
+ }
+ return ConstantVector::get(Out);
+ }
+
+ /// Create and insert the idiom we use to indicate a block is unreachable
+ /// without having to rewrite the CFG from within InstCombine.
+ static void CreateNonTerminatorUnreachable(Instruction *InsertAt) {
+ auto &Ctx = InsertAt->getContext();
+ new StoreInst(ConstantInt::getTrue(Ctx),
+ UndefValue::get(Type::getInt1PtrTy(Ctx)), InsertAt);
+ }
+
+ void addToWorklist(Instruction *I) { Worklist.push(I); }
+
+ AssumptionCache &getAssumptionCache() const { return AC; }
+ TargetLibraryInfo &getTargetLibraryInfo() const { return TLI; }
+ DominatorTree &getDominatorTree() const { return DT; }
+ const DataLayout &getDataLayout() const { return DL; }
+ const SimplifyQuery &getSimplifyQuery() const { return SQ; }
+ OptimizationRemarkEmitter &getOptimizationRemarkEmitter() const {
+ return ORE;
+ }
+ BlockFrequencyInfo *getBlockFrequencyInfo() const { return BFI; }
+ ProfileSummaryInfo *getProfileSummaryInfo() const { return PSI; }
+ LoopInfo *getLoopInfo() const { return LI; }
+
+ // Call target specific combiners
+ Optional<Instruction *> targetInstCombineIntrinsic(IntrinsicInst &II);
+ Optional<Value *>
+ targetSimplifyDemandedUseBitsIntrinsic(IntrinsicInst &II, APInt DemandedMask,
+ KnownBits &Known,
+ bool &KnownBitsComputed);
+ Optional<Value *> targetSimplifyDemandedVectorEltsIntrinsic(
+ IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
+ APInt &UndefElts2, APInt &UndefElts3,
+ std::function<void(Instruction *, unsigned, APInt, APInt &)>
+ SimplifyAndSetOp);
+
+ /// Inserts an instruction \p New before instruction \p Old
+ ///
+ /// Also adds the new instruction to the worklist and returns \p New so that
+ /// it is suitable for use as the return from the visitation patterns.
+ Instruction *InsertNewInstBefore(Instruction *New, Instruction &Old) {
+ assert(New && !New->getParent() &&
+ "New instruction already inserted into a basic block!");
+ BasicBlock *BB = Old.getParent();
+ BB->getInstList().insert(Old.getIterator(), New); // Insert inst
+ Worklist.push(New);
+ return New;
+ }
+
+ /// Same as InsertNewInstBefore, but also sets the debug loc.
+ Instruction *InsertNewInstWith(Instruction *New, Instruction &Old) {
+ New->setDebugLoc(Old.getDebugLoc());
+ return InsertNewInstBefore(New, Old);
+ }
+
+ /// A combiner-aware RAUW-like routine.
+ ///
+ /// This method is to be used when an instruction is found to be dead,
+ /// replaceable with another preexisting expression. Here we add all uses of
+ /// I to the worklist, replace all uses of I with the new value, then return
+ /// I, so that the inst combiner will know that I was modified.
+ Instruction *replaceInstUsesWith(Instruction &I, Value *V) {
+ // If there are no uses to replace, then we return nullptr to indicate that
+ // no changes were made to the program.
+ if (I.use_empty())
+ return nullptr;
+
+ Worklist.pushUsersToWorkList(I); // Add all modified instrs to worklist.
+
+ // If we are replacing the instruction with itself, this must be in a
+ // segment of unreachable code, so just clobber the instruction.
+ if (&I == V)
+ V = UndefValue::get(I.getType());
+
+ LLVM_DEBUG(dbgs() << "IC: Replacing " << I << "\n"
+ << " with " << *V << '\n');
+
+ I.replaceAllUsesWith(V);
+ return &I;
+ }
+
+ /// Replace operand of instruction and add old operand to the worklist.
+ Instruction *replaceOperand(Instruction &I, unsigned OpNum, Value *V) {
+ Worklist.addValue(I.getOperand(OpNum));
+ I.setOperand(OpNum, V);
+ return &I;
+ }
+
+ /// Replace use and add the previously used value to the worklist.
+ void replaceUse(Use &U, Value *NewValue) {
+ Worklist.addValue(U);
+ U = NewValue;
+ }
+
+ /// Combiner aware instruction erasure.
+ ///
+ /// When dealing with an instruction that has side effects or produces a void
+ /// value, we can't rely on DCE to delete the instruction. Instead, visit
+ /// methods should return the value returned by this function.
+ virtual Instruction *eraseInstFromFunction(Instruction &I) = 0;
+
+ void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth,
+ const Instruction *CxtI) const {
+ llvm::computeKnownBits(V, Known, DL, Depth, &AC, CxtI, &DT);
+ }
+
+ KnownBits computeKnownBits(const Value *V, unsigned Depth,
+ const Instruction *CxtI) const {
+ return llvm::computeKnownBits(V, DL, Depth, &AC, CxtI, &DT);
+ }
+
+ bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero = false,
+ unsigned Depth = 0,
+ const Instruction *CxtI = nullptr) {
+ return llvm::isKnownToBeAPowerOfTwo(V, DL, OrZero, Depth, &AC, CxtI, &DT);
+ }
+
+ bool MaskedValueIsZero(const Value *V, const APInt &Mask, unsigned Depth = 0,
+ const Instruction *CxtI = nullptr) const {
+ return llvm::MaskedValueIsZero(V, Mask, DL, Depth, &AC, CxtI, &DT);
+ }
+
+ unsigned ComputeNumSignBits(const Value *Op, unsigned Depth = 0,
+ const Instruction *CxtI = nullptr) const {
+ return llvm::ComputeNumSignBits(Op, DL, Depth, &AC, CxtI, &DT);
+ }
+
+ OverflowResult computeOverflowForUnsignedMul(const Value *LHS,
+ const Value *RHS,
+ const Instruction *CxtI) const {
+ return llvm::computeOverflowForUnsignedMul(LHS, RHS, DL, &AC, CxtI, &DT);
+ }
+
+ OverflowResult computeOverflowForSignedMul(const Value *LHS, const Value *RHS,
+ const Instruction *CxtI) const {
+ return llvm::computeOverflowForSignedMul(LHS, RHS, DL, &AC, CxtI, &DT);
+ }
+
+ OverflowResult computeOverflowForUnsignedAdd(const Value *LHS,
+ const Value *RHS,
+ const Instruction *CxtI) const {
+ return llvm::computeOverflowForUnsignedAdd(LHS, RHS, DL, &AC, CxtI, &DT);
+ }
+
+ OverflowResult computeOverflowForSignedAdd(const Value *LHS, const Value *RHS,
+ const Instruction *CxtI) const {
+ return llvm::computeOverflowForSignedAdd(LHS, RHS, DL, &AC, CxtI, &DT);
+ }
+
+ OverflowResult computeOverflowForUnsignedSub(const Value *LHS,
+ const Value *RHS,
+ const Instruction *CxtI) const {
+ return llvm::computeOverflowForUnsignedSub(LHS, RHS, DL, &AC, CxtI, &DT);
+ }
+
+ OverflowResult computeOverflowForSignedSub(const Value *LHS, const Value *RHS,
+ const Instruction *CxtI) const {
+ return llvm::computeOverflowForSignedSub(LHS, RHS, DL, &AC, CxtI, &DT);
+ }
+
+ virtual bool SimplifyDemandedBits(Instruction *I, unsigned OpNo,
+ const APInt &DemandedMask, KnownBits &Known,
+ unsigned Depth = 0) = 0;
+ virtual Value *
+ SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, APInt &UndefElts,
+ unsigned Depth = 0,
+ bool AllowMultipleUsers = false) = 0;
+};
+
+} // namespace llvm
+
+#undef DEBUG_TYPE
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation.h b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation.h
index 1a0a209ce9..8809cb1ec1 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation.h
@@ -73,9 +73,9 @@ struct GCOVOptions {
// Add the 'noredzone' attribute to added runtime library calls.
bool NoRedZone;
- // Use atomic profile counter increments.
- bool Atomic = false;
-
+ // Use atomic profile counter increments.
+ bool Atomic = false;
+
// Regexes separated by a semi-colon to filter the files to instrument.
std::string Filter;
@@ -153,8 +153,8 @@ ModulePass *createInstrProfilingLegacyPass(
ModulePass *createInstrOrderFilePass();
// Insert DataFlowSanitizer (dynamic data flow analysis) instrumentation
-ModulePass *createDataFlowSanitizerLegacyPassPass(
- const std::vector<std::string> &ABIListFiles = std::vector<std::string>());
+ModulePass *createDataFlowSanitizerLegacyPassPass(
+ const std::vector<std::string> &ABIListFiles = std::vector<std::string>());
// Options for sanitizer coverage instrumentation.
struct SanitizerCoverageOptions {
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/AddressSanitizer.h b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
index cd14ac66f5..46cbf49956 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
@@ -109,7 +109,7 @@ public:
bool Recover = false,
bool UseAfterScope = false);
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
private:
bool CompileKernel;
@@ -130,7 +130,7 @@ public:
bool UseGlobalGC = true,
bool UseOdrIndicator = false);
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
private:
bool CompileKernel;
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/BoundsChecking.h b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/BoundsChecking.h
index bb4d634cde..4661ea7779 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/BoundsChecking.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/BoundsChecking.h
@@ -24,7 +24,7 @@ namespace llvm {
/// stores, and other memory intrinsics.
struct BoundsCheckingPass : PassInfoMixin<BoundsCheckingPass> {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
};
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/DataFlowSanitizer.h b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/DataFlowSanitizer.h
index 38aa2d560b..b732dae51c 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/DataFlowSanitizer.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/DataFlowSanitizer.h
@@ -1,43 +1,43 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- DataFlowSanitizer.h - dynamic data flow analysis -------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_DATAFLOWSANITIZER_H
-#define LLVM_TRANSFORMS_INSTRUMENTATION_DATAFLOWSANITIZER_H
-
-#include "llvm/IR/Module.h"
-#include "llvm/IR/PassManager.h"
-#include <string>
-#include <vector>
-
-namespace llvm {
-
-class DataFlowSanitizerPass : public PassInfoMixin<DataFlowSanitizerPass> {
-private:
- std::vector<std::string> ABIListFiles;
-
-public:
- DataFlowSanitizerPass(
- const std::vector<std::string> &ABIListFiles = std::vector<std::string>())
- : ABIListFiles(ABIListFiles) {}
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
- static bool isRequired() { return true; }
-};
-
-} // namespace llvm
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- DataFlowSanitizer.h - dynamic data flow analysis -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_DATAFLOWSANITIZER_H
+#define LLVM_TRANSFORMS_INSTRUMENTATION_DATAFLOWSANITIZER_H
+
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+class DataFlowSanitizerPass : public PassInfoMixin<DataFlowSanitizerPass> {
+private:
+ std::vector<std::string> ABIListFiles;
+
+public:
+ DataFlowSanitizerPass(
+ const std::vector<std::string> &ABIListFiles = std::vector<std::string>())
+ : ABIListFiles(ABIListFiles) {}
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+ static bool isRequired() { return true; }
+};
+
+} // namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/GCOVProfiler.h b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/GCOVProfiler.h
index 78024a30a3..70b3eea60b 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/GCOVProfiler.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/GCOVProfiler.h
@@ -33,7 +33,7 @@ private:
GCOVOptions GCOVOpts;
};
-} // namespace llvm
+} // namespace llvm
#endif
#ifdef __GNUC__
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/HWAddressSanitizer.h b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/HWAddressSanitizer.h
index 585b6b84f0..a7011f14a5 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/HWAddressSanitizer.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/HWAddressSanitizer.h
@@ -34,7 +34,7 @@ public:
explicit HWAddressSanitizerPass(bool CompileKernel = false,
bool Recover = false);
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
private:
bool CompileKernel;
@@ -44,24 +44,24 @@ private:
FunctionPass *createHWAddressSanitizerLegacyPassPass(bool CompileKernel = false,
bool Recover = false);
-namespace HWASanAccessInfo {
-
-// Bit field positions for the accessinfo parameter to
-// llvm.hwasan.check.memaccess. Shared between the pass and the backend. Bits
-// 0-15 are also used by the runtime.
-enum {
- AccessSizeShift = 0, // 4 bits
- IsWriteShift = 4,
- RecoverShift = 5,
- MatchAllShift = 16, // 8 bits
- HasMatchAllShift = 24,
- CompileKernelShift = 25,
-};
-
-enum { RuntimeMask = 0xffff };
-
-} // namespace HWASanAccessInfo
-
+namespace HWASanAccessInfo {
+
+// Bit field positions for the accessinfo parameter to
+// llvm.hwasan.check.memaccess. Shared between the pass and the backend. Bits
+// 0-15 are also used by the runtime.
+enum {
+ AccessSizeShift = 0, // 4 bits
+ IsWriteShift = 4,
+ RecoverShift = 5,
+ MatchAllShift = 16, // 8 bits
+ HasMatchAllShift = 24,
+ CompileKernelShift = 25,
+};
+
+enum { RuntimeMask = 0xffff };
+
+} // namespace HWASanAccessInfo
+
} // namespace llvm
#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/MemProfiler.h b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/MemProfiler.h
index 4be1152817..86547e02f0 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/MemProfiler.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/MemProfiler.h
@@ -1,62 +1,62 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===--------- Definition of the MemProfiler class --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the MemProfiler class.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_MEMPROFILER_H
-#define LLVM_TRANSFORMS_INSTRUMENTATION_MEMPROFILER_H
-
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-
-/// Public interface to the memory profiler pass for instrumenting code to
-/// profile memory accesses.
-///
-/// The profiler itself is a function pass that works by inserting various
-/// calls to the MemProfiler runtime library functions. The runtime library
-/// essentially replaces malloc() and free() with custom implementations that
-/// record data about the allocations.
-class MemProfilerPass : public PassInfoMixin<MemProfilerPass> {
-public:
- explicit MemProfilerPass();
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
- static bool isRequired() { return true; }
-};
-
-/// Public interface to the memory profiler module pass for instrumenting code
-/// to profile memory allocations and accesses.
-class ModuleMemProfilerPass : public PassInfoMixin<ModuleMemProfilerPass> {
-public:
- explicit ModuleMemProfilerPass();
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
- static bool isRequired() { return true; }
-};
-
-// Insert MemProfiler instrumentation
-FunctionPass *createMemProfilerFunctionPass();
-ModulePass *createModuleMemProfilerLegacyPassPass();
-
-} // namespace llvm
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===--------- Definition of the MemProfiler class --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MemProfiler class.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_MEMPROFILER_H
+#define LLVM_TRANSFORMS_INSTRUMENTATION_MEMPROFILER_H
+
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+/// Public interface to the memory profiler pass for instrumenting code to
+/// profile memory accesses.
+///
+/// The profiler itself is a function pass that works by inserting various
+/// calls to the MemProfiler runtime library functions. The runtime library
+/// essentially replaces malloc() and free() with custom implementations that
+/// record data about the allocations.
+class MemProfilerPass : public PassInfoMixin<MemProfilerPass> {
+public:
+ explicit MemProfilerPass();
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+ static bool isRequired() { return true; }
+};
+
+/// Public interface to the memory profiler module pass for instrumenting code
+/// to profile memory allocations and accesses.
+class ModuleMemProfilerPass : public PassInfoMixin<ModuleMemProfilerPass> {
+public:
+ explicit ModuleMemProfilerPass();
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+ static bool isRequired() { return true; }
+};
+
+// Insert MemProfiler instrumentation
+FunctionPass *createMemProfilerFunctionPass();
+ModulePass *createModuleMemProfilerLegacyPassPass();
+
+} // namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/MemorySanitizer.h b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/MemorySanitizer.h
index 85748cb221..d6d96b89b1 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/MemorySanitizer.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/MemorySanitizer.h
@@ -48,7 +48,7 @@ struct MemorySanitizerPass : public PassInfoMixin<MemorySanitizerPass> {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
private:
MemorySanitizerOptions Options;
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/SanitizerCoverage.h b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/SanitizerCoverage.h
index 69610fc22c..76494514af 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/SanitizerCoverage.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/SanitizerCoverage.h
@@ -53,7 +53,7 @@ public:
*vfs::getRealFileSystem());
}
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
private:
SanitizerCoverageOptions Options;
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h
index 898a08b238..a2e2d99692 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h
@@ -35,7 +35,7 @@ FunctionPass *createThreadSanitizerLegacyPassPass();
struct ThreadSanitizerPass : public PassInfoMixin<ThreadSanitizerPass> {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
};
} // namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/ObjCARC.h b/contrib/libs/llvm12/include/llvm/Transforms/ObjCARC.h
index 456ca448ff..1de1f773f5 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/ObjCARC.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/ObjCARC.h
@@ -21,8 +21,8 @@
#ifndef LLVM_TRANSFORMS_OBJCARC_H
#define LLVM_TRANSFORMS_OBJCARC_H
-#include "llvm/IR/PassManager.h"
-
+#include "llvm/IR/PassManager.h"
+
namespace llvm {
class Pass;
@@ -51,22 +51,22 @@ Pass *createObjCARCContractPass();
//
Pass *createObjCARCOptPass();
-struct ObjCARCOptPass : public PassInfoMixin<ObjCARCOptPass> {
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-
-struct ObjCARCContractPass : public PassInfoMixin<ObjCARCContractPass> {
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-
-struct ObjCARCAPElimPass : public PassInfoMixin<ObjCARCAPElimPass> {
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-};
-
-struct ObjCARCExpandPass : public PassInfoMixin<ObjCARCExpandPass> {
- PreservedAnalyses run(Function &M, FunctionAnalysisManager &AM);
-};
-
+struct ObjCARCOptPass : public PassInfoMixin<ObjCARCOptPass> {
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+struct ObjCARCContractPass : public PassInfoMixin<ObjCARCContractPass> {
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+struct ObjCARCAPElimPass : public PassInfoMixin<ObjCARCAPElimPass> {
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+struct ObjCARCExpandPass : public PassInfoMixin<ObjCARCExpandPass> {
+ PreservedAnalyses run(Function &M, FunctionAnalysisManager &AM);
+};
+
} // End llvm namespace
#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar.h
index dcafc13c49..7cf295b2e8 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar.h
@@ -21,7 +21,7 @@
#ifndef LLVM_TRANSFORMS_SCALAR_H
#define LLVM_TRANSFORMS_SCALAR_H
-#include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
+#include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
#include <functional>
namespace llvm {
@@ -40,15 +40,15 @@ FunctionPass *createAlignmentFromAssumptionsPass();
//===----------------------------------------------------------------------===//
//
-// AnnotationRemarks - Emit remarks for !annotation metadata.
+// AnnotationRemarks - Emit remarks for !annotation metadata.
//
-FunctionPass *createAnnotationRemarksLegacyPass();
+FunctionPass *createAnnotationRemarksLegacyPass();
//===----------------------------------------------------------------------===//
//
-// SCCP - Sparse conditional constant propagation.
+// SCCP - Sparse conditional constant propagation.
//
-FunctionPass *createSCCPPass();
+FunctionPass *createSCCPPass();
//===----------------------------------------------------------------------===//
//
@@ -164,12 +164,12 @@ Pass *createLoopInterchangePass();
//===----------------------------------------------------------------------===//
//
-// LoopFlatten - This pass flattens nested loops into a single loop.
-//
-FunctionPass *createLoopFlattenPass();
-
-//===----------------------------------------------------------------------===//
-//
+// LoopFlatten - This pass flattens nested loops into a single loop.
+//
+FunctionPass *createLoopFlattenPass();
+
+//===----------------------------------------------------------------------===//
+//
// LoopStrengthReduce - This pass is strength reduces GEP instructions that use
// a loop's canonical induction variable as one of their indices.
//
@@ -197,8 +197,8 @@ Pass *createLoopUnrollPass(int OptLevel = 2, bool OnlyWhenForced = false,
int Count = -1, int AllowPartial = -1,
int Runtime = -1, int UpperBound = -1,
int AllowPeeling = -1);
-// Create an unrolling pass for full unrolling that uses exact trip count only
-// and also does peeling.
+// Create an unrolling pass for full unrolling that uses exact trip count only
+// and also does peeling.
Pass *createSimpleLoopUnrollPass(int OptLevel = 2, bool OnlyWhenForced = false,
bool ForgetAllSCEV = false);
@@ -218,7 +218,7 @@ Pass *createLoopRerollPass();
//
// LoopRotate - This pass is a simple loop rotating pass.
//
-Pass *createLoopRotatePass(int MaxHeaderSize = -1, bool PrepareForLTO = false);
+Pass *createLoopRotatePass(int MaxHeaderSize = -1, bool PrepareForLTO = false);
//===----------------------------------------------------------------------===//
//
@@ -253,12 +253,12 @@ FunctionPass *createReassociatePass();
//===----------------------------------------------------------------------===//
//
// JumpThreading - Thread control through mult-pred/multi-succ blocks where some
-// preds always go to some succ. If FreezeSelectCond is true, unfold the
-// condition of a select that unfolds to branch. Thresholds other than minus one
-// override the internal BB duplication default threshold.
+// preds always go to some succ. If FreezeSelectCond is true, unfold the
+// condition of a select that unfolds to branch. Thresholds other than minus one
+// override the internal BB duplication default threshold.
//
-FunctionPass *createJumpThreadingPass(bool FreezeSelectCond = false,
- int Threshold = -1);
+FunctionPass *createJumpThreadingPass(bool FreezeSelectCond = false,
+ int Threshold = -1);
//===----------------------------------------------------------------------===//
//
@@ -266,7 +266,7 @@ FunctionPass *createJumpThreadingPass(bool FreezeSelectCond = false,
// simplify terminator instructions, convert switches to lookup tables, etc.
//
FunctionPass *createCFGSimplificationPass(
- SimplifyCFGOptions Options = SimplifyCFGOptions(),
+ SimplifyCFGOptions Options = SimplifyCFGOptions(),
std::function<bool(const Function &)> Ftor = nullptr);
//===----------------------------------------------------------------------===//
@@ -355,13 +355,13 @@ FunctionPass *createConstantHoistingPass();
//===----------------------------------------------------------------------===//
//
-// ConstraintElimination - This pass eliminates conditions based on found
-// constraints.
-//
-FunctionPass *createConstraintEliminationPass();
-
-//===----------------------------------------------------------------------===//
-//
+// ConstraintElimination - This pass eliminates conditions based on found
+// constraints.
+//
+FunctionPass *createConstraintEliminationPass();
+
+//===----------------------------------------------------------------------===//
+//
// Sink - Code Sinking
//
FunctionPass *createSinkingPass();
@@ -386,13 +386,13 @@ Pass *createLowerMatrixIntrinsicsPass();
//===----------------------------------------------------------------------===//
//
-// LowerMatrixIntrinsicsMinimal - Lower matrix intrinsics to vector operations
-// (lightweight, does not require extra analysis)
-//
-Pass *createLowerMatrixIntrinsicsMinimalPass();
-
-//===----------------------------------------------------------------------===//
-//
+// LowerMatrixIntrinsicsMinimal - Lower matrix intrinsics to vector operations
+// (lightweight, does not require extra analysis)
+//
+Pass *createLowerMatrixIntrinsicsMinimalPass();
+
+//===----------------------------------------------------------------------===//
+//
// LowerWidenableCondition - Lower widenable condition to i1 true.
//
Pass *createLowerWidenableConditionPass();
@@ -546,21 +546,21 @@ Pass *createLoopSimplifyCFGPass();
// transformations.
//
Pass *createWarnMissedTransformationsPass();
-
-//===----------------------------------------------------------------------===//
-//
-// This pass does instruction simplification on each
-// instruction in a function.
-//
-FunctionPass *createInstSimplifyLegacyPass();
-
-
-//===----------------------------------------------------------------------===//
-//
-// createScalarizeMaskedMemIntrinPass - Replace masked load, store, gather
-// and scatter intrinsics with scalar code when target doesn't support them.
-//
-FunctionPass *createScalarizeMaskedMemIntrinLegacyPass();
+
+//===----------------------------------------------------------------------===//
+//
+// This pass does instruction simplification on each
+// instruction in a function.
+//
+FunctionPass *createInstSimplifyLegacyPass();
+
+
+//===----------------------------------------------------------------------===//
+//
+// createScalarizeMaskedMemIntrinPass - Replace masked load, store, gather
+// and scatter intrinsics with scalar code when target doesn't support them.
+//
+FunctionPass *createScalarizeMaskedMemIntrinLegacyPass();
} // End llvm namespace
#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h
index 0a2c890d61..805cabbb03 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h
@@ -44,9 +44,9 @@ struct AlignmentFromAssumptionsPass
ScalarEvolution *SE = nullptr;
DominatorTree *DT = nullptr;
- bool extractAlignmentInfo(CallInst *I, unsigned Idx, Value *&AAPtr,
- const SCEV *&AlignSCEV, const SCEV *&OffSCEV);
- bool processAssumption(CallInst *I, unsigned Idx);
+ bool extractAlignmentInfo(CallInst *I, unsigned Idx, Value *&AAPtr,
+ const SCEV *&AlignSCEV, const SCEV *&OffSCEV);
+ bool processAssumption(CallInst *I, unsigned Idx);
};
}
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/AnnotationRemarks.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/AnnotationRemarks.h
index 408ac969b2..78a4812cb8 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/AnnotationRemarks.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/AnnotationRemarks.h
@@ -1,37 +1,37 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- AnnotationRemarks.cpp - Emit remarks for !annotation MD --*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// \file
-// This file defines AnnotationRemarksPass for the new pass manager.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_SCALAR_ANNOTATION_REMARKS_H
-#define LLVM_TRANSFORMS_SCALAR_ANNOTATION_REMARKS_H
-
-#include "llvm/IR/Function.h"
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-struct AnnotationRemarksPass : public PassInfoMixin<AnnotationRemarksPass> {
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-} // namespace llvm
-
-#endif // LLVM_TRANSFORMS_SCALAR_ANNOTATION_REMARKS_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- AnnotationRemarks.cpp - Emit remarks for !annotation MD --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// \file
+// This file defines AnnotationRemarksPass for the new pass manager.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_ANNOTATION_REMARKS_H
+#define LLVM_TRANSFORMS_SCALAR_ANNOTATION_REMARKS_H
+
+#include "llvm/IR/Function.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+struct AnnotationRemarksPass : public PassInfoMixin<AnnotationRemarksPass> {
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_ANNOTATION_REMARKS_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/ConstraintElimination.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/ConstraintElimination.h
index aabe7a8cda..f353d384e7 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/ConstraintElimination.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/ConstraintElimination.h
@@ -1,35 +1,35 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- ConstraintElimination.h - Constraint elimination pass ----*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_SCALAR_CONSTRAINTELIMINATION_H
-#define LLVM_TRANSFORMS_SCALAR_CONSTRAINTELIMINATION_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-
-class ConstraintEliminationPass
- : public PassInfoMixin<ConstraintEliminationPass> {
-public:
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &);
-};
-
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_SCALAR_CONSTRAINTELIMINATION_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- ConstraintElimination.h - Constraint elimination pass ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_CONSTRAINTELIMINATION_H
+#define LLVM_TRANSFORMS_SCALAR_CONSTRAINTELIMINATION_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class ConstraintEliminationPass
+ : public PassInfoMixin<ConstraintEliminationPass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_CONSTRAINTELIMINATION_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/DCE.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/DCE.h
index d624328b36..344ebe68f9 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/DCE.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/DCE.h
@@ -30,12 +30,12 @@ class DCEPass : public PassInfoMixin<DCEPass> {
public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
-
-class RedundantDbgInstEliminationPass
- : public PassInfoMixin<RedundantDbgInstEliminationPass> {
-public:
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
+
+class RedundantDbgInstEliminationPass
+ : public PassInfoMixin<RedundantDbgInstEliminationPass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
}
#endif // LLVM_TRANSFORMS_SCALAR_DCE_H
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/GVN.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/GVN.h
index 8a41b18799..c2906dc22f 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/GVN.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/GVN.h
@@ -53,8 +53,8 @@ class FunctionPass;
class IntrinsicInst;
class LoadInst;
class LoopInfo;
-class MemorySSA;
-class MemorySSAUpdater;
+class MemorySSA;
+class MemorySSAUpdater;
class OptimizationRemarkEmitter;
class PHINode;
class TargetLibraryInfo;
@@ -80,7 +80,7 @@ struct GVNOptions {
Optional<bool> AllowPRE = None;
Optional<bool> AllowLoadPRE = None;
Optional<bool> AllowLoadInLoopPRE = None;
- Optional<bool> AllowLoadPRESplitBackedge = None;
+ Optional<bool> AllowLoadPRESplitBackedge = None;
Optional<bool> AllowMemDep = None;
GVNOptions() = default;
@@ -102,12 +102,12 @@ struct GVNOptions {
return *this;
}
- /// Enables or disables PRE of loads in GVN.
- GVNOptions &setLoadPRESplitBackedge(bool LoadPRESplitBackedge) {
- AllowLoadPRESplitBackedge = LoadPRESplitBackedge;
- return *this;
- }
-
+ /// Enables or disables PRE of loads in GVN.
+ GVNOptions &setLoadPRESplitBackedge(bool LoadPRESplitBackedge) {
+ AllowLoadPRESplitBackedge = LoadPRESplitBackedge;
+ return *this;
+ }
+
/// Enables or disables use of MemDepAnalysis.
GVNOptions &setMemDep(bool MemDep) {
AllowMemDep = MemDep;
@@ -144,7 +144,7 @@ public:
bool isPREEnabled() const;
bool isLoadPREEnabled() const;
bool isLoadInLoopPREEnabled() const;
- bool isLoadPRESplitBackedgeEnabled() const;
+ bool isLoadPRESplitBackedgeEnabled() const;
bool isMemDepEnabled() const;
/// This class holds the mapping between values and value numbers. It is used
@@ -227,7 +227,7 @@ private:
OptimizationRemarkEmitter *ORE = nullptr;
ImplicitControlFlowTracking *ICF = nullptr;
LoopInfo *LI = nullptr;
- MemorySSAUpdater *MSSAU = nullptr;
+ MemorySSAUpdater *MSSAU = nullptr;
ValueTable VN;
@@ -263,7 +263,7 @@ private:
bool runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
const TargetLibraryInfo &RunTLI, AAResults &RunAA,
MemoryDependenceResults *RunMD, LoopInfo *LI,
- OptimizationRemarkEmitter *ORE, MemorySSA *MSSA = nullptr);
+ OptimizationRemarkEmitter *ORE, MemorySSA *MSSA = nullptr);
/// Push a new Value to the LeaderTable onto the list for its value number.
void addToLeaderTable(uint32_t N, Value *V, const BasicBlock *BB) {
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/IndVarSimplify.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/IndVarSimplify.h
index cd5cb68c0e..885487f548 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/IndVarSimplify.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/IndVarSimplify.h
@@ -30,11 +30,11 @@ class Loop;
class LPMUpdater;
class IndVarSimplifyPass : public PassInfoMixin<IndVarSimplifyPass> {
- /// Perform IV widening during the pass.
- bool WidenIndVars;
-
+ /// Perform IV widening during the pass.
+ bool WidenIndVars;
+
public:
- IndVarSimplifyPass(bool WidenIndVars = true) : WidenIndVars(WidenIndVars) {}
+ IndVarSimplifyPass(bool WidenIndVars = true) : WidenIndVars(WidenIndVars) {}
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
LoopStandardAnalysisResults &AR, LPMUpdater &U);
};
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/InferAddressSpaces.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/InferAddressSpaces.h
index 1132195c13..4d4a62e0c5 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/InferAddressSpaces.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/InferAddressSpaces.h
@@ -1,38 +1,38 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- InferAddressSpace.h - ----------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_SCALAR_INFERADDRESSSPACES_H
-#define LLVM_TRANSFORMS_SCALAR_INFERADDRESSSPACES_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-
-struct InferAddressSpacesPass : PassInfoMixin<InferAddressSpacesPass> {
- InferAddressSpacesPass();
- InferAddressSpacesPass(unsigned AddressSpace);
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-
-private:
- unsigned FlatAddrSpace = 0;
-};
-
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_SCALAR_INFERADDRESSSPACES_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- InferAddressSpace.h - ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_INFERADDRESSSPACES_H
+#define LLVM_TRANSFORMS_SCALAR_INFERADDRESSSPACES_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+struct InferAddressSpacesPass : PassInfoMixin<InferAddressSpacesPass> {
+ InferAddressSpacesPass();
+ InferAddressSpacesPass(unsigned AddressSpace);
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+
+private:
+ unsigned FlatAddrSpace = 0;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_INFERADDRESSSPACES_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/JumpThreading.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/JumpThreading.h
index f24333c390..4d977dcd43 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/JumpThreading.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/JumpThreading.h
@@ -35,7 +35,7 @@
namespace llvm {
-class AAResults;
+class AAResults;
class BasicBlock;
class BinaryOperator;
class BranchInst;
@@ -48,8 +48,8 @@ class IntrinsicInst;
class LazyValueInfo;
class LoadInst;
class PHINode;
-class SelectInst;
-class SwitchInst;
+class SelectInst;
+class SwitchInst;
class TargetLibraryInfo;
class Value;
@@ -86,7 +86,7 @@ enum ConstantPreference { WantInteger, WantBlockAddress };
class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> {
TargetLibraryInfo *TLI;
LazyValueInfo *LVI;
- AAResults *AA;
+ AAResults *AA;
DomTreeUpdater *DTU;
std::unique_ptr<BlockFrequencyInfo> BFI;
std::unique_ptr<BranchProbabilityInfo> BPI;
@@ -100,16 +100,16 @@ class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> {
unsigned BBDupThreshold;
unsigned DefaultBBDupThreshold;
- bool InsertFreezeWhenUnfoldingSelect;
+ bool InsertFreezeWhenUnfoldingSelect;
public:
- JumpThreadingPass(bool InsertFreezeWhenUnfoldingSelect = false, int T = -1);
+ JumpThreadingPass(bool InsertFreezeWhenUnfoldingSelect = false, int T = -1);
// Glue for old PM.
- bool runImpl(Function &F, TargetLibraryInfo *TLI, LazyValueInfo *LVI,
- AAResults *AA, DomTreeUpdater *DTU, bool HasProfileData,
- std::unique_ptr<BlockFrequencyInfo> BFI,
- std::unique_ptr<BranchProbabilityInfo> BPI);
+ bool runImpl(Function &F, TargetLibraryInfo *TLI, LazyValueInfo *LVI,
+ AAResults *AA, DomTreeUpdater *DTU, bool HasProfileData,
+ std::unique_ptr<BlockFrequencyInfo> BFI,
+ std::unique_ptr<BranchProbabilityInfo> BPI);
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
@@ -118,65 +118,65 @@ public:
BPI.reset();
}
- void findLoopHeaders(Function &F);
- bool processBlock(BasicBlock *BB);
- bool maybeMergeBasicBlockIntoOnlyPred(BasicBlock *BB);
- void updateSSA(BasicBlock *BB, BasicBlock *NewBB,
+ void findLoopHeaders(Function &F);
+ bool processBlock(BasicBlock *BB);
+ bool maybeMergeBasicBlockIntoOnlyPred(BasicBlock *BB);
+ void updateSSA(BasicBlock *BB, BasicBlock *NewBB,
DenseMap<Instruction *, Value *> &ValueMapping);
- DenseMap<Instruction *, Value *> cloneInstructions(BasicBlock::iterator BI,
+ DenseMap<Instruction *, Value *> cloneInstructions(BasicBlock::iterator BI,
BasicBlock::iterator BE,
BasicBlock *NewBB,
BasicBlock *PredBB);
- bool tryThreadEdge(BasicBlock *BB,
+ bool tryThreadEdge(BasicBlock *BB,
const SmallVectorImpl<BasicBlock *> &PredBBs,
BasicBlock *SuccBB);
- void threadEdge(BasicBlock *BB, const SmallVectorImpl<BasicBlock *> &PredBBs,
+ void threadEdge(BasicBlock *BB, const SmallVectorImpl<BasicBlock *> &PredBBs,
BasicBlock *SuccBB);
- bool duplicateCondBranchOnPHIIntoPred(
+ bool duplicateCondBranchOnPHIIntoPred(
BasicBlock *BB, const SmallVectorImpl<BasicBlock *> &PredBBs);
- bool computeValueKnownInPredecessorsImpl(
+ bool computeValueKnownInPredecessorsImpl(
Value *V, BasicBlock *BB, jumpthreading::PredValueInfo &Result,
jumpthreading::ConstantPreference Preference,
DenseSet<Value *> &RecursionSet, Instruction *CxtI = nullptr);
bool
- computeValueKnownInPredecessors(Value *V, BasicBlock *BB,
+ computeValueKnownInPredecessors(Value *V, BasicBlock *BB,
jumpthreading::PredValueInfo &Result,
jumpthreading::ConstantPreference Preference,
Instruction *CxtI = nullptr) {
DenseSet<Value *> RecursionSet;
- return computeValueKnownInPredecessorsImpl(V, BB, Result, Preference,
+ return computeValueKnownInPredecessorsImpl(V, BB, Result, Preference,
RecursionSet, CxtI);
}
- Constant *evaluateOnPredecessorEdge(BasicBlock *BB, BasicBlock *PredPredBB,
+ Constant *evaluateOnPredecessorEdge(BasicBlock *BB, BasicBlock *PredPredBB,
Value *cond);
- bool maybethreadThroughTwoBasicBlocks(BasicBlock *BB, Value *Cond);
- void threadThroughTwoBasicBlocks(BasicBlock *PredPredBB, BasicBlock *PredBB,
+ bool maybethreadThroughTwoBasicBlocks(BasicBlock *BB, Value *Cond);
+ void threadThroughTwoBasicBlocks(BasicBlock *PredPredBB, BasicBlock *PredBB,
BasicBlock *BB, BasicBlock *SuccBB);
- bool processThreadableEdges(Value *Cond, BasicBlock *BB,
+ bool processThreadableEdges(Value *Cond, BasicBlock *BB,
jumpthreading::ConstantPreference Preference,
Instruction *CxtI = nullptr);
- bool processBranchOnPHI(PHINode *PN);
- bool processBranchOnXOR(BinaryOperator *BO);
- bool processImpliedCondition(BasicBlock *BB);
+ bool processBranchOnPHI(PHINode *PN);
+ bool processBranchOnXOR(BinaryOperator *BO);
+ bool processImpliedCondition(BasicBlock *BB);
- bool simplifyPartiallyRedundantLoad(LoadInst *LI);
- void unfoldSelectInstr(BasicBlock *Pred, BasicBlock *BB, SelectInst *SI,
+ bool simplifyPartiallyRedundantLoad(LoadInst *LI);
+ void unfoldSelectInstr(BasicBlock *Pred, BasicBlock *BB, SelectInst *SI,
PHINode *SIUse, unsigned Idx);
- bool tryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB);
- bool tryToUnfoldSelect(SwitchInst *SI, BasicBlock *BB);
- bool tryToUnfoldSelectInCurrBB(BasicBlock *BB);
+ bool tryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB);
+ bool tryToUnfoldSelect(SwitchInst *SI, BasicBlock *BB);
+ bool tryToUnfoldSelectInCurrBB(BasicBlock *BB);
- bool processGuards(BasicBlock *BB);
- bool threadGuard(BasicBlock *BB, IntrinsicInst *Guard, BranchInst *BI);
+ bool processGuards(BasicBlock *BB);
+ bool threadGuard(BasicBlock *BB, IntrinsicInst *Guard, BranchInst *BI);
private:
- BasicBlock *splitBlockPreds(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
+ BasicBlock *splitBlockPreds(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
const char *Suffix);
- void updateBlockFreqAndEdgeWeight(BasicBlock *PredBB, BasicBlock *BB,
+ void updateBlockFreqAndEdgeWeight(BasicBlock *PredBB, BasicBlock *BB,
BasicBlock *NewBB, BasicBlock *SuccBB);
/// Check if the block has profile metadata for its outgoing edges.
bool doesBlockHaveProfileData(BasicBlock *BB);
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopFlatten.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopFlatten.h
index 10ab54e1dc..94c153da09 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopFlatten.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopFlatten.h
@@ -1,43 +1,43 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- LoopFlatten.h - Loop Flatten ---------------- -----------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides the interface for the Loop Flatten Pass.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_SCALAR_LOOPFLATTEN_H
-#define LLVM_TRANSFORMS_SCALAR_LOOPFLATTEN_H
-
-#include "llvm/Analysis/LoopAnalysisManager.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/IR/PassManager.h"
-#include "llvm/Transforms/Scalar/LoopPassManager.h"
-
-namespace llvm {
-
-class LoopFlattenPass : public PassInfoMixin<LoopFlattenPass> {
-public:
- LoopFlattenPass() = default;
-
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_SCALAR_LOOPFLATTEN_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- LoopFlatten.h - Loop Flatten ---------------- -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the interface for the Loop Flatten Pass.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_LOOPFLATTEN_H
+#define LLVM_TRANSFORMS_SCALAR_LOOPFLATTEN_H
+
+#include "llvm/Analysis/LoopAnalysisManager.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
+
+namespace llvm {
+
+class LoopFlattenPass : public PassInfoMixin<LoopFlattenPass> {
+public:
+ LoopFlattenPass() = default;
+
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_LOOPFLATTEN_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopIdiomRecognize.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopIdiomRecognize.h
index 3affa35521..33a39a0820 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopIdiomRecognize.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopIdiomRecognize.h
@@ -30,19 +30,19 @@ namespace llvm {
class Loop;
class LPMUpdater;
-/// Options to disable Loop Idiom Recognize, which can be shared with other
-/// passes.
-struct DisableLIRP {
- /// When true, the entire pass is disabled.
- static bool All;
-
- /// When true, Memset is disabled.
- static bool Memset;
-
- /// When true, Memcpy is disabled.
- static bool Memcpy;
-};
-
+/// Options to disable Loop Idiom Recognize, which can be shared with other
+/// passes.
+struct DisableLIRP {
+ /// When true, the entire pass is disabled.
+ static bool All;
+
+ /// When true, Memset is disabled.
+ static bool Memset;
+
+ /// When true, Memcpy is disabled.
+ static bool Memcpy;
+};
+
/// Performs Loop Idiom Recognize Pass.
class LoopIdiomRecognizePass : public PassInfoMixin<LoopIdiomRecognizePass> {
public:
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopInterchange.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopInterchange.h
index 94c3f00d17..61b9808304 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopInterchange.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopInterchange.h
@@ -1,35 +1,35 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- LoopInterchange.h - Loop interchange pass --------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_SCALAR_LOOPINTERCHANGE_H
-#define LLVM_TRANSFORMS_SCALAR_LOOPINTERCHANGE_H
-
-#include "llvm/IR/PassManager.h"
-#include "llvm/Transforms/Scalar/LoopPassManager.h"
-
-namespace llvm {
-
-struct LoopInterchangePass : public PassInfoMixin<LoopInterchangePass> {
- PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
- LoopStandardAnalysisResults &AR, LPMUpdater &U);
-};
-
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_SCALAR_LOOPINTERCHANGE_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- LoopInterchange.h - Loop interchange pass --------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_LOOPINTERCHANGE_H
+#define LLVM_TRANSFORMS_SCALAR_LOOPINTERCHANGE_H
+
+#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
+
+namespace llvm {
+
+struct LoopInterchangePass : public PassInfoMixin<LoopInterchangePass> {
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_LOOPINTERCHANGE_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopPassManager.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopPassManager.h
index c268c9c097..30d26eab5e 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopPassManager.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopPassManager.h
@@ -46,161 +46,161 @@
#include "llvm/ADT/PriorityWorklist.h"
#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/LoopNestAnalysis.h"
+#include "llvm/Analysis/LoopNestAnalysis.h"
#include "llvm/IR/Dominators.h"
-#include "llvm/IR/PassInstrumentation.h"
+#include "llvm/IR/PassInstrumentation.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Transforms/Utils/LCSSA.h"
#include "llvm/Transforms/Utils/LoopSimplify.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
-#include <memory>
+#include <memory>
namespace llvm {
// Forward declarations of an update tracking API used in the pass manager.
class LPMUpdater;
-namespace {
-
-template <typename PassT>
-using HasRunOnLoopT = decltype(std::declval<PassT>().run(
- std::declval<Loop &>(), std::declval<LoopAnalysisManager &>(),
- std::declval<LoopStandardAnalysisResults &>(),
- std::declval<LPMUpdater &>()));
-
-} // namespace
-
+namespace {
+
+template <typename PassT>
+using HasRunOnLoopT = decltype(std::declval<PassT>().run(
+ std::declval<Loop &>(), std::declval<LoopAnalysisManager &>(),
+ std::declval<LoopStandardAnalysisResults &>(),
+ std::declval<LPMUpdater &>()));
+
+} // namespace
+
// Explicit specialization and instantiation declarations for the pass manager.
// See the comments on the definition of the specialization for details on how
// it differs from the primary template.
template <>
-class PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
- LPMUpdater &>
- : public PassInfoMixin<
- PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
- LPMUpdater &>> {
-public:
- /// Construct a pass manager.
- ///
- /// If \p DebugLogging is true, we'll log our progress to llvm::dbgs().
- explicit PassManager(bool DebugLogging = false)
- : DebugLogging(DebugLogging) {}
-
- // FIXME: These are equivalent to the default move constructor/move
- // assignment. However, using = default triggers linker errors due to the
- // explicit instantiations below. Find a way to use the default and remove the
- // duplicated code here.
- PassManager(PassManager &&Arg)
- : IsLoopNestPass(std::move(Arg.IsLoopNestPass)),
- LoopPasses(std::move(Arg.LoopPasses)),
- LoopNestPasses(std::move(Arg.LoopNestPasses)),
- DebugLogging(std::move(Arg.DebugLogging)) {}
-
- PassManager &operator=(PassManager &&RHS) {
- IsLoopNestPass = std::move(RHS.IsLoopNestPass);
- LoopPasses = std::move(RHS.LoopPasses);
- LoopNestPasses = std::move(RHS.LoopNestPasses);
- DebugLogging = std::move(RHS.DebugLogging);
- return *this;
- }
-
- PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
- LoopStandardAnalysisResults &AR, LPMUpdater &U);
-
- /// Add either a loop pass or a loop-nest pass to the pass manager. Append \p
- /// Pass to the list of loop passes if it has a dedicated \fn run() method for
- /// loops and to the list of loop-nest passes if the \fn run() method is for
- /// loop-nests instead. Also append whether \p Pass is loop-nest pass or not
- /// to the end of \var IsLoopNestPass so we can easily identify the types of
- /// passes in the pass manager later.
- template <typename PassT>
- std::enable_if_t<is_detected<HasRunOnLoopT, PassT>::value>
- addPass(PassT Pass) {
- using LoopPassModelT =
- detail::PassModel<Loop, PassT, PreservedAnalyses, LoopAnalysisManager,
- LoopStandardAnalysisResults &, LPMUpdater &>;
- IsLoopNestPass.push_back(false);
- LoopPasses.emplace_back(new LoopPassModelT(std::move(Pass)));
- }
-
- template <typename PassT>
- std::enable_if_t<!is_detected<HasRunOnLoopT, PassT>::value>
- addPass(PassT Pass) {
- using LoopNestPassModelT =
- detail::PassModel<LoopNest, PassT, PreservedAnalyses,
- LoopAnalysisManager, LoopStandardAnalysisResults &,
- LPMUpdater &>;
- IsLoopNestPass.push_back(true);
- LoopNestPasses.emplace_back(new LoopNestPassModelT(std::move(Pass)));
- }
-
- // Specializations of `addPass` for `RepeatedPass`. These are necessary since
- // `RepeatedPass` has a templated `run` method that will result in incorrect
- // detection of `HasRunOnLoopT`.
- template <typename PassT>
- std::enable_if_t<is_detected<HasRunOnLoopT, PassT>::value>
- addPass(RepeatedPass<PassT> Pass) {
- using RepeatedLoopPassModelT =
- detail::PassModel<Loop, RepeatedPass<PassT>, PreservedAnalyses,
- LoopAnalysisManager, LoopStandardAnalysisResults &,
- LPMUpdater &>;
- IsLoopNestPass.push_back(false);
- LoopPasses.emplace_back(new RepeatedLoopPassModelT(std::move(Pass)));
- }
-
- template <typename PassT>
- std::enable_if_t<!is_detected<HasRunOnLoopT, PassT>::value>
- addPass(RepeatedPass<PassT> Pass) {
- using RepeatedLoopNestPassModelT =
- detail::PassModel<LoopNest, RepeatedPass<PassT>, PreservedAnalyses,
- LoopAnalysisManager, LoopStandardAnalysisResults &,
- LPMUpdater &>;
- IsLoopNestPass.push_back(true);
- LoopNestPasses.emplace_back(
- new RepeatedLoopNestPassModelT(std::move(Pass)));
- }
-
- bool isEmpty() const { return LoopPasses.empty() && LoopNestPasses.empty(); }
-
- static bool isRequired() { return true; }
-
- size_t getNumLoopPasses() const { return LoopPasses.size(); }
- size_t getNumLoopNestPasses() const { return LoopNestPasses.size(); }
-
-protected:
- using LoopPassConceptT =
- detail::PassConcept<Loop, LoopAnalysisManager,
- LoopStandardAnalysisResults &, LPMUpdater &>;
- using LoopNestPassConceptT =
- detail::PassConcept<LoopNest, LoopAnalysisManager,
- LoopStandardAnalysisResults &, LPMUpdater &>;
-
- // BitVector that identifies whether the passes are loop passes or loop-nest
- // passes (true for loop-nest passes).
- BitVector IsLoopNestPass;
- std::vector<std::unique_ptr<LoopPassConceptT>> LoopPasses;
- std::vector<std::unique_ptr<LoopNestPassConceptT>> LoopNestPasses;
-
- /// Flag indicating whether we should do debug logging.
- bool DebugLogging;
-
- /// Run either a loop pass or a loop-nest pass. Returns `None` if
- /// PassInstrumentation's BeforePass returns false. Otherwise, returns the
- /// preserved analyses of the pass.
- template <typename IRUnitT, typename PassT>
- Optional<PreservedAnalyses>
- runSinglePass(IRUnitT &IR, PassT &Pass, LoopAnalysisManager &AM,
- LoopStandardAnalysisResults &AR, LPMUpdater &U,
- PassInstrumentation &PI);
-
- PreservedAnalyses runWithLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
- LoopStandardAnalysisResults &AR,
- LPMUpdater &U);
- PreservedAnalyses runWithoutLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
- LoopStandardAnalysisResults &AR,
- LPMUpdater &U);
-};
-
+class PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
+ LPMUpdater &>
+ : public PassInfoMixin<
+ PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
+ LPMUpdater &>> {
+public:
+ /// Construct a pass manager.
+ ///
+ /// If \p DebugLogging is true, we'll log our progress to llvm::dbgs().
+ explicit PassManager(bool DebugLogging = false)
+ : DebugLogging(DebugLogging) {}
+
+ // FIXME: These are equivalent to the default move constructor/move
+ // assignment. However, using = default triggers linker errors due to the
+ // explicit instantiations below. Find a way to use the default and remove the
+ // duplicated code here.
+ PassManager(PassManager &&Arg)
+ : IsLoopNestPass(std::move(Arg.IsLoopNestPass)),
+ LoopPasses(std::move(Arg.LoopPasses)),
+ LoopNestPasses(std::move(Arg.LoopNestPasses)),
+ DebugLogging(std::move(Arg.DebugLogging)) {}
+
+ PassManager &operator=(PassManager &&RHS) {
+ IsLoopNestPass = std::move(RHS.IsLoopNestPass);
+ LoopPasses = std::move(RHS.LoopPasses);
+ LoopNestPasses = std::move(RHS.LoopNestPasses);
+ DebugLogging = std::move(RHS.DebugLogging);
+ return *this;
+ }
+
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
+
+ /// Add either a loop pass or a loop-nest pass to the pass manager. Append \p
+ /// Pass to the list of loop passes if it has a dedicated \fn run() method for
+ /// loops and to the list of loop-nest passes if the \fn run() method is for
+ /// loop-nests instead. Also append whether \p Pass is loop-nest pass or not
+ /// to the end of \var IsLoopNestPass so we can easily identify the types of
+ /// passes in the pass manager later.
+ template <typename PassT>
+ std::enable_if_t<is_detected<HasRunOnLoopT, PassT>::value>
+ addPass(PassT Pass) {
+ using LoopPassModelT =
+ detail::PassModel<Loop, PassT, PreservedAnalyses, LoopAnalysisManager,
+ LoopStandardAnalysisResults &, LPMUpdater &>;
+ IsLoopNestPass.push_back(false);
+ LoopPasses.emplace_back(new LoopPassModelT(std::move(Pass)));
+ }
+
+ template <typename PassT>
+ std::enable_if_t<!is_detected<HasRunOnLoopT, PassT>::value>
+ addPass(PassT Pass) {
+ using LoopNestPassModelT =
+ detail::PassModel<LoopNest, PassT, PreservedAnalyses,
+ LoopAnalysisManager, LoopStandardAnalysisResults &,
+ LPMUpdater &>;
+ IsLoopNestPass.push_back(true);
+ LoopNestPasses.emplace_back(new LoopNestPassModelT(std::move(Pass)));
+ }
+
+ // Specializations of `addPass` for `RepeatedPass`. These are necessary since
+ // `RepeatedPass` has a templated `run` method that will result in incorrect
+ // detection of `HasRunOnLoopT`.
+ template <typename PassT>
+ std::enable_if_t<is_detected<HasRunOnLoopT, PassT>::value>
+ addPass(RepeatedPass<PassT> Pass) {
+ using RepeatedLoopPassModelT =
+ detail::PassModel<Loop, RepeatedPass<PassT>, PreservedAnalyses,
+ LoopAnalysisManager, LoopStandardAnalysisResults &,
+ LPMUpdater &>;
+ IsLoopNestPass.push_back(false);
+ LoopPasses.emplace_back(new RepeatedLoopPassModelT(std::move(Pass)));
+ }
+
+ template <typename PassT>
+ std::enable_if_t<!is_detected<HasRunOnLoopT, PassT>::value>
+ addPass(RepeatedPass<PassT> Pass) {
+ using RepeatedLoopNestPassModelT =
+ detail::PassModel<LoopNest, RepeatedPass<PassT>, PreservedAnalyses,
+ LoopAnalysisManager, LoopStandardAnalysisResults &,
+ LPMUpdater &>;
+ IsLoopNestPass.push_back(true);
+ LoopNestPasses.emplace_back(
+ new RepeatedLoopNestPassModelT(std::move(Pass)));
+ }
+
+ bool isEmpty() const { return LoopPasses.empty() && LoopNestPasses.empty(); }
+
+ static bool isRequired() { return true; }
+
+ size_t getNumLoopPasses() const { return LoopPasses.size(); }
+ size_t getNumLoopNestPasses() const { return LoopNestPasses.size(); }
+
+protected:
+ using LoopPassConceptT =
+ detail::PassConcept<Loop, LoopAnalysisManager,
+ LoopStandardAnalysisResults &, LPMUpdater &>;
+ using LoopNestPassConceptT =
+ detail::PassConcept<LoopNest, LoopAnalysisManager,
+ LoopStandardAnalysisResults &, LPMUpdater &>;
+
+ // BitVector that identifies whether the passes are loop passes or loop-nest
+ // passes (true for loop-nest passes).
+ BitVector IsLoopNestPass;
+ std::vector<std::unique_ptr<LoopPassConceptT>> LoopPasses;
+ std::vector<std::unique_ptr<LoopNestPassConceptT>> LoopNestPasses;
+
+ /// Flag indicating whether we should do debug logging.
+ bool DebugLogging;
+
+ /// Run either a loop pass or a loop-nest pass. Returns `None` if
+ /// PassInstrumentation's BeforePass returns false. Otherwise, returns the
+ /// preserved analyses of the pass.
+ template <typename IRUnitT, typename PassT>
+ Optional<PreservedAnalyses>
+ runSinglePass(IRUnitT &IR, PassT &Pass, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U,
+ PassInstrumentation &PI);
+
+ PreservedAnalyses runWithLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR,
+ LPMUpdater &U);
+ PreservedAnalyses runWithoutLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR,
+ LPMUpdater &U);
+};
+
/// The Loop pass manager.
///
/// See the documentation for the PassManager template for details. It runs
@@ -232,7 +232,7 @@ using RequireAnalysisLoopPass =
RequireAnalysisPass<AnalysisT, Loop, LoopAnalysisManager,
LoopStandardAnalysisResults &, LPMUpdater &>;
-class FunctionToLoopPassAdaptor;
+class FunctionToLoopPassAdaptor;
/// This class provides an interface for updating the loop pass manager based
/// on mutations to the loop nest.
@@ -240,13 +240,13 @@ class FunctionToLoopPassAdaptor;
/// A reference to an instance of this class is passed as an argument to each
/// Loop pass, and Loop passes should use it to update LPM infrastructure if
/// they modify the loop nest structure.
-///
-/// \c LPMUpdater comes with two modes: the loop mode and the loop-nest mode. In
-/// loop mode, all the loops in the function will be pushed into the worklist
-/// and when new loops are added to the pipeline, their subloops are also
-/// inserted recursively. On the other hand, in loop-nest mode, only top-level
-/// loops are contained in the worklist and the addition of new (top-level)
-/// loops will not trigger the addition of their subloops.
+///
+/// \c LPMUpdater comes with two modes: the loop mode and the loop-nest mode. In
+/// loop mode, all the loops in the function will be pushed into the worklist
+/// and when new loops are added to the pipeline, their subloops are also
+/// inserted recursively. On the other hand, in loop-nest mode, only top-level
+/// loops are contained in the worklist and the addition of new (top-level)
+/// loops will not trigger the addition of their subloops.
class LPMUpdater {
public:
/// This can be queried by loop passes which run other loop passes (like pass
@@ -268,8 +268,8 @@ public:
/// state, this routine will mark that the current loop should be skipped by
/// the rest of the pass management infrastructure.
void markLoopAsDeleted(Loop &L, llvm::StringRef Name) {
- assert((!LoopNestMode || L.isOutermost()) &&
- "L should be a top-level loop in loop-nest mode.");
+ assert((!LoopNestMode || L.isOutermost()) &&
+ "L should be a top-level loop in loop-nest mode.");
LAM.clear(L, Name);
assert((&L == CurrentL || CurrentL->contains(&L)) &&
"Cannot delete a loop outside of the "
@@ -285,8 +285,8 @@ public:
/// loops within them will be visited in postorder as usual for the loop pass
/// manager.
void addChildLoops(ArrayRef<Loop *> NewChildLoops) {
- assert(!LoopNestMode &&
- "Child loops should not be pushed in loop-nest mode.");
+ assert(!LoopNestMode &&
+ "Child loops should not be pushed in loop-nest mode.");
// Insert ourselves back into the worklist first, as this loop should be
// revisited after all the children have been processed.
Worklist.insert(CurrentL);
@@ -318,10 +318,10 @@ public:
"All of the new loops must be siblings of the current loop!");
#endif
- if (LoopNestMode)
- Worklist.insert(NewSibLoops);
- else
- appendLoopsToWorklist(NewSibLoops, Worklist);
+ if (LoopNestMode)
+ Worklist.insert(NewSibLoops);
+ else
+ appendLoopsToWorklist(NewSibLoops, Worklist);
// No need to skip the current loop or revisit it, as sibling loops
// shouldn't impact anything.
@@ -341,7 +341,7 @@ public:
}
private:
- friend class llvm::FunctionToLoopPassAdaptor;
+ friend class llvm::FunctionToLoopPassAdaptor;
/// The \c FunctionToLoopPassAdaptor's worklist of loops to process.
SmallPriorityWorklist<Loop *, 4> &Worklist;
@@ -351,7 +351,7 @@ private:
Loop *CurrentL;
bool SkipCurrentLoop;
- const bool LoopNestMode;
+ const bool LoopNestMode;
#ifndef NDEBUG
// In debug builds we also track the parent loop to implement asserts even in
@@ -360,33 +360,33 @@ private:
#endif
LPMUpdater(SmallPriorityWorklist<Loop *, 4> &Worklist,
- LoopAnalysisManager &LAM, bool LoopNestMode = false)
- : Worklist(Worklist), LAM(LAM), LoopNestMode(LoopNestMode) {}
+ LoopAnalysisManager &LAM, bool LoopNestMode = false)
+ : Worklist(Worklist), LAM(LAM), LoopNestMode(LoopNestMode) {}
};
-template <typename IRUnitT, typename PassT>
-Optional<PreservedAnalyses> LoopPassManager::runSinglePass(
- IRUnitT &IR, PassT &Pass, LoopAnalysisManager &AM,
- LoopStandardAnalysisResults &AR, LPMUpdater &U, PassInstrumentation &PI) {
- // Check the PassInstrumentation's BeforePass callbacks before running the
- // pass, skip its execution completely if asked to (callback returns false).
- if (!PI.runBeforePass<IRUnitT>(*Pass, IR))
- return None;
-
- PreservedAnalyses PA;
- {
- TimeTraceScope TimeScope(Pass->name(), IR.getName());
- PA = Pass->run(IR, AM, AR, U);
- }
-
- // do not pass deleted Loop into the instrumentation
- if (U.skipCurrentLoop())
- PI.runAfterPassInvalidated<IRUnitT>(*Pass, PA);
- else
- PI.runAfterPass<IRUnitT>(*Pass, IR, PA);
- return PA;
-}
-
+template <typename IRUnitT, typename PassT>
+Optional<PreservedAnalyses> LoopPassManager::runSinglePass(
+ IRUnitT &IR, PassT &Pass, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U, PassInstrumentation &PI) {
+ // Check the PassInstrumentation's BeforePass callbacks before running the
+ // pass, skip its execution completely if asked to (callback returns false).
+ if (!PI.runBeforePass<IRUnitT>(*Pass, IR))
+ return None;
+
+ PreservedAnalyses PA;
+ {
+ TimeTraceScope TimeScope(Pass->name(), IR.getName());
+ PA = Pass->run(IR, AM, AR, U);
+ }
+
+ // do not pass deleted Loop into the instrumentation
+ if (U.skipCurrentLoop())
+ PI.runAfterPassInvalidated<IRUnitT>(*Pass, PA);
+ else
+ PI.runAfterPass<IRUnitT>(*Pass, IR, PA);
+ return PA;
+}
+
/// Adaptor that maps from a function to its loops.
///
/// Designed to allow composition of a LoopPass(Manager) and a
@@ -394,109 +394,109 @@ Optional<PreservedAnalyses> LoopPassManager::runSinglePass(
/// FunctionAnalysisManager it will run the \c LoopAnalysisManagerFunctionProxy
/// analysis prior to running the loop passes over the function to enable a \c
/// LoopAnalysisManager to be used within this run safely.
-///
-/// The adaptor comes with two modes: the loop mode and the loop-nest mode, and
-/// the worklist updater lived inside will be in the same mode as the adaptor
-/// (refer to the documentation of \c LPMUpdater for more detailed explanation).
-/// Specifically, in loop mode, all loops in the funciton will be pushed into
-/// the worklist and processed by \p Pass, while only top-level loops are
-/// processed in loop-nest mode. Please refer to the various specializations of
-/// \fn createLoopFunctionToLoopPassAdaptor to see when loop mode and loop-nest
-/// mode are used.
+///
+/// The adaptor comes with two modes: the loop mode and the loop-nest mode, and
+/// the worklist updater lived inside will be in the same mode as the adaptor
+/// (refer to the documentation of \c LPMUpdater for more detailed explanation).
+/// Specifically, in loop mode, all loops in the funciton will be pushed into
+/// the worklist and processed by \p Pass, while only top-level loops are
+/// processed in loop-nest mode. Please refer to the various specializations of
+/// \fn createLoopFunctionToLoopPassAdaptor to see when loop mode and loop-nest
+/// mode are used.
class FunctionToLoopPassAdaptor
- : public PassInfoMixin<FunctionToLoopPassAdaptor> {
+ : public PassInfoMixin<FunctionToLoopPassAdaptor> {
public:
- using PassConceptT =
- detail::PassConcept<Loop, LoopAnalysisManager,
- LoopStandardAnalysisResults &, LPMUpdater &>;
-
- explicit FunctionToLoopPassAdaptor(std::unique_ptr<PassConceptT> Pass,
- bool UseMemorySSA = false,
- bool UseBlockFrequencyInfo = false,
- bool DebugLogging = false,
- bool LoopNestMode = false)
+ using PassConceptT =
+ detail::PassConcept<Loop, LoopAnalysisManager,
+ LoopStandardAnalysisResults &, LPMUpdater &>;
+
+ explicit FunctionToLoopPassAdaptor(std::unique_ptr<PassConceptT> Pass,
+ bool UseMemorySSA = false,
+ bool UseBlockFrequencyInfo = false,
+ bool DebugLogging = false,
+ bool LoopNestMode = false)
: Pass(std::move(Pass)), LoopCanonicalizationFPM(DebugLogging),
- UseMemorySSA(UseMemorySSA),
- UseBlockFrequencyInfo(UseBlockFrequencyInfo),
- LoopNestMode(LoopNestMode) {
+ UseMemorySSA(UseMemorySSA),
+ UseBlockFrequencyInfo(UseBlockFrequencyInfo),
+ LoopNestMode(LoopNestMode) {
LoopCanonicalizationFPM.addPass(LoopSimplifyPass());
LoopCanonicalizationFPM.addPass(LCSSAPass());
}
/// Runs the loop passes across every loop in the function.
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
- bool isLoopNestMode() const { return LoopNestMode; }
+ bool isLoopNestMode() const { return LoopNestMode; }
private:
- std::unique_ptr<PassConceptT> Pass;
+ std::unique_ptr<PassConceptT> Pass;
FunctionPassManager LoopCanonicalizationFPM;
bool UseMemorySSA = false;
- bool UseBlockFrequencyInfo = false;
- const bool LoopNestMode;
+ bool UseBlockFrequencyInfo = false;
+ const bool LoopNestMode;
};
/// A function to deduce a loop pass type and wrap it in the templated
/// adaptor.
-///
-/// If \p Pass is a loop pass, the returned adaptor will be in loop mode.
+///
+/// If \p Pass is a loop pass, the returned adaptor will be in loop mode.
template <typename LoopPassT>
-inline std::enable_if_t<is_detected<HasRunOnLoopT, LoopPassT>::value,
- FunctionToLoopPassAdaptor>
+inline std::enable_if_t<is_detected<HasRunOnLoopT, LoopPassT>::value,
+ FunctionToLoopPassAdaptor>
createFunctionToLoopPassAdaptor(LoopPassT Pass, bool UseMemorySSA = false,
- bool UseBlockFrequencyInfo = false,
+ bool UseBlockFrequencyInfo = false,
+ bool DebugLogging = false) {
+ using PassModelT =
+ detail::PassModel<Loop, LoopPassT, PreservedAnalyses, LoopAnalysisManager,
+ LoopStandardAnalysisResults &, LPMUpdater &>;
+ return FunctionToLoopPassAdaptor(
+ std::make_unique<PassModelT>(std::move(Pass)), UseMemorySSA,
+ UseBlockFrequencyInfo, DebugLogging, false);
+}
+
+/// If \p Pass is a loop-nest pass, \p Pass will first be wrapped into a
+/// \c LoopPassManager and the returned adaptor will be in loop-nest mode.
+template <typename LoopNestPassT>
+inline std::enable_if_t<!is_detected<HasRunOnLoopT, LoopNestPassT>::value,
+ FunctionToLoopPassAdaptor>
+createFunctionToLoopPassAdaptor(LoopNestPassT Pass, bool UseMemorySSA = false,
+ bool UseBlockFrequencyInfo = false,
bool DebugLogging = false) {
- using PassModelT =
- detail::PassModel<Loop, LoopPassT, PreservedAnalyses, LoopAnalysisManager,
- LoopStandardAnalysisResults &, LPMUpdater &>;
- return FunctionToLoopPassAdaptor(
- std::make_unique<PassModelT>(std::move(Pass)), UseMemorySSA,
- UseBlockFrequencyInfo, DebugLogging, false);
+ LoopPassManager LPM(DebugLogging);
+ LPM.addPass(std::move(Pass));
+ using PassModelT =
+ detail::PassModel<Loop, LoopPassManager, PreservedAnalyses,
+ LoopAnalysisManager, LoopStandardAnalysisResults &,
+ LPMUpdater &>;
+ return FunctionToLoopPassAdaptor(std::make_unique<PassModelT>(std::move(LPM)),
+ UseMemorySSA, UseBlockFrequencyInfo,
+ DebugLogging, true);
+}
+
+/// If \p Pass is an instance of \c LoopPassManager, the returned adaptor will
+/// be in loop-nest mode if the pass manager contains only loop-nest passes.
+template <>
+inline FunctionToLoopPassAdaptor
+createFunctionToLoopPassAdaptor<LoopPassManager>(LoopPassManager LPM,
+ bool UseMemorySSA,
+ bool UseBlockFrequencyInfo,
+ bool DebugLogging) {
+ // Check if LPM contains any loop pass and if it does not, returns an adaptor
+ // in loop-nest mode.
+ using PassModelT =
+ detail::PassModel<Loop, LoopPassManager, PreservedAnalyses,
+ LoopAnalysisManager, LoopStandardAnalysisResults &,
+ LPMUpdater &>;
+ bool LoopNestMode = (LPM.getNumLoopPasses() == 0);
+ return FunctionToLoopPassAdaptor(std::make_unique<PassModelT>(std::move(LPM)),
+ UseMemorySSA, UseBlockFrequencyInfo,
+ DebugLogging, LoopNestMode);
}
-/// If \p Pass is a loop-nest pass, \p Pass will first be wrapped into a
-/// \c LoopPassManager and the returned adaptor will be in loop-nest mode.
-template <typename LoopNestPassT>
-inline std::enable_if_t<!is_detected<HasRunOnLoopT, LoopNestPassT>::value,
- FunctionToLoopPassAdaptor>
-createFunctionToLoopPassAdaptor(LoopNestPassT Pass, bool UseMemorySSA = false,
- bool UseBlockFrequencyInfo = false,
- bool DebugLogging = false) {
- LoopPassManager LPM(DebugLogging);
- LPM.addPass(std::move(Pass));
- using PassModelT =
- detail::PassModel<Loop, LoopPassManager, PreservedAnalyses,
- LoopAnalysisManager, LoopStandardAnalysisResults &,
- LPMUpdater &>;
- return FunctionToLoopPassAdaptor(std::make_unique<PassModelT>(std::move(LPM)),
- UseMemorySSA, UseBlockFrequencyInfo,
- DebugLogging, true);
-}
-
-/// If \p Pass is an instance of \c LoopPassManager, the returned adaptor will
-/// be in loop-nest mode if the pass manager contains only loop-nest passes.
-template <>
-inline FunctionToLoopPassAdaptor
-createFunctionToLoopPassAdaptor<LoopPassManager>(LoopPassManager LPM,
- bool UseMemorySSA,
- bool UseBlockFrequencyInfo,
- bool DebugLogging) {
- // Check if LPM contains any loop pass and if it does not, returns an adaptor
- // in loop-nest mode.
- using PassModelT =
- detail::PassModel<Loop, LoopPassManager, PreservedAnalyses,
- LoopAnalysisManager, LoopStandardAnalysisResults &,
- LPMUpdater &>;
- bool LoopNestMode = (LPM.getNumLoopPasses() == 0);
- return FunctionToLoopPassAdaptor(std::make_unique<PassModelT>(std::move(LPM)),
- UseMemorySSA, UseBlockFrequencyInfo,
- DebugLogging, LoopNestMode);
-}
-
/// Pass for printing a loop's contents as textual IR.
class PrintLoopPass : public PassInfoMixin<PrintLoopPass> {
raw_ostream &OS;
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopReroll.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopReroll.h
index 53929a90a1..d4674af374 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopReroll.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopReroll.h
@@ -1,38 +1,38 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- LoopReroll.h - Loop rerolling pass ---------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_SCALAR_LOOPREROLL_H
-#define LLVM_TRANSFORMS_SCALAR_LOOPREROLL_H
-
-#include "llvm/IR/PassManager.h"
-#include "llvm/Transforms/Scalar/LoopPassManager.h"
-
-namespace llvm {
-
-class Function;
-
-class LoopRerollPass : public PassInfoMixin<LoopRerollPass> {
-public:
- PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
- LoopStandardAnalysisResults &AR, LPMUpdater &U);
-};
-
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_SCALAR_LOOPREROLL_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- LoopReroll.h - Loop rerolling pass ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_LOOPREROLL_H
+#define LLVM_TRANSFORMS_SCALAR_LOOPREROLL_H
+
+#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
+
+namespace llvm {
+
+class Function;
+
+class LoopRerollPass : public PassInfoMixin<LoopRerollPass> {
+public:
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_LOOPREROLL_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopRotation.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopRotation.h
index 36eb74558a..907bf22274 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopRotation.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopRotation.h
@@ -29,14 +29,14 @@ namespace llvm {
/// A simple loop rotation transformation.
class LoopRotatePass : public PassInfoMixin<LoopRotatePass> {
public:
- LoopRotatePass(bool EnableHeaderDuplication = true,
- bool PrepareForLTO = false);
+ LoopRotatePass(bool EnableHeaderDuplication = true,
+ bool PrepareForLTO = false);
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
LoopStandardAnalysisResults &AR, LPMUpdater &U);
private:
const bool EnableHeaderDuplication;
- const bool PrepareForLTO;
+ const bool PrepareForLTO;
};
}
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopUnrollPass.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopUnrollPass.h
index 9ba3f0ed28..d6c45889ef 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopUnrollPass.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopUnrollPass.h
@@ -29,7 +29,7 @@ class Function;
class Loop;
class LPMUpdater;
-/// Loop unroll pass that only does full loop unrolling and peeling.
+/// Loop unroll pass that only does full loop unrolling and peeling.
class LoopFullUnrollPass : public PassInfoMixin<LoopFullUnrollPass> {
const int OptLevel;
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopVersioningLICM.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopVersioningLICM.h
index c554baddb9..1e16fabbe3 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopVersioningLICM.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LoopVersioningLICM.h
@@ -1,36 +1,36 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- LoopVersioningLICM.h - LICM Loop Versioning ------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_SCALAR_LOOPVERSIONINGLICM_H
-#define LLVM_TRANSFORMS_SCALAR_LOOPVERSIONINGLICM_H
-
-#include "llvm/IR/PassManager.h"
-#include "llvm/Transforms/Scalar/LoopPassManager.h"
-
-namespace llvm {
-
-class LoopVersioningLICMPass : public PassInfoMixin<LoopVersioningLICMPass> {
-public:
- PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
- LoopStandardAnalysisResults &LAR, LPMUpdater &U);
-};
-
-} // namespace llvm
-
-#endif // LLVM_TRANSFORMS_SCALAR_LOOPVERSIONINGLICM_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- LoopVersioningLICM.h - LICM Loop Versioning ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_LOOPVERSIONINGLICM_H
+#define LLVM_TRANSFORMS_SCALAR_LOOPVERSIONINGLICM_H
+
+#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
+
+namespace llvm {
+
+class LoopVersioningLICMPass : public PassInfoMixin<LoopVersioningLICMPass> {
+public:
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &LAR, LPMUpdater &U);
+};
+
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_LOOPVERSIONINGLICM_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LowerAtomic.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LowerAtomic.h
index 6e98c10455..351afc1018 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LowerAtomic.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LowerAtomic.h
@@ -29,7 +29,7 @@ namespace llvm {
class LowerAtomicPass : public PassInfoMixin<LowerAtomicPass> {
public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
};
}
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LowerExpectIntrinsic.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LowerExpectIntrinsic.h
index bf63ebe46e..c862c7fa33 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LowerExpectIntrinsic.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LowerExpectIntrinsic.h
@@ -24,7 +24,7 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
-#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/CommandLine.h"
namespace llvm {
@@ -39,8 +39,8 @@ struct LowerExpectIntrinsicPass : PassInfoMixin<LowerExpectIntrinsicPass> {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &);
};
-extern cl::opt<uint32_t> LikelyBranchWeight;
-extern cl::opt<uint32_t> UnlikelyBranchWeight;
+extern cl::opt<uint32_t> LikelyBranchWeight;
+extern cl::opt<uint32_t> UnlikelyBranchWeight;
}
#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LowerMatrixIntrinsics.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LowerMatrixIntrinsics.h
index d2bbcc508b..58bcd51171 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LowerMatrixIntrinsics.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/LowerMatrixIntrinsics.h
@@ -23,14 +23,14 @@
#include "llvm/IR/PassManager.h"
namespace llvm {
-class LowerMatrixIntrinsicsPass
- : public PassInfoMixin<LowerMatrixIntrinsicsPass> {
- bool Minimal;
-
-public:
- LowerMatrixIntrinsicsPass(bool Minimal = false) : Minimal(Minimal) {}
+class LowerMatrixIntrinsicsPass
+ : public PassInfoMixin<LowerMatrixIntrinsicsPass> {
+ bool Minimal;
+
+public:
+ LowerMatrixIntrinsicsPass(bool Minimal = false) : Minimal(Minimal) {}
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
- static bool isRequired() { return true; }
+ static bool isRequired() { return true; }
};
} // namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/MemCpyOptimizer.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/MemCpyOptimizer.h
index 470e105c41..5615f3375c 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/MemCpyOptimizer.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/MemCpyOptimizer.h
@@ -28,19 +28,19 @@
namespace llvm {
-class AAResults;
+class AAResults;
class AssumptionCache;
-class CallBase;
+class CallBase;
class CallInst;
class DominatorTree;
class Function;
class Instruction;
-class LoadInst;
+class LoadInst;
class MemCpyInst;
class MemMoveInst;
class MemoryDependenceResults;
-class MemorySSA;
-class MemorySSAUpdater;
+class MemorySSA;
+class MemorySSAUpdater;
class MemSetInst;
class StoreInst;
class TargetLibraryInfo;
@@ -49,11 +49,11 @@ class Value;
class MemCpyOptPass : public PassInfoMixin<MemCpyOptPass> {
MemoryDependenceResults *MD = nullptr;
TargetLibraryInfo *TLI = nullptr;
- AAResults *AA = nullptr;
- AssumptionCache *AC = nullptr;
- DominatorTree *DT = nullptr;
- MemorySSA *MSSA = nullptr;
- MemorySSAUpdater *MSSAU = nullptr;
+ AAResults *AA = nullptr;
+ AssumptionCache *AC = nullptr;
+ DominatorTree *DT = nullptr;
+ MemorySSA *MSSA = nullptr;
+ MemorySSAUpdater *MSSAU = nullptr;
public:
MemCpyOptPass() = default;
@@ -61,9 +61,9 @@ public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
// Glue for the old PM.
- bool runImpl(Function &F, MemoryDependenceResults *MD, TargetLibraryInfo *TLI,
- AAResults *AA, AssumptionCache *AC, DominatorTree *DT,
- MemorySSA *MSSA);
+ bool runImpl(Function &F, MemoryDependenceResults *MD, TargetLibraryInfo *TLI,
+ AAResults *AA, AssumptionCache *AC, DominatorTree *DT,
+ MemorySSA *MSSA);
private:
// Helper functions
@@ -71,18 +71,18 @@ private:
bool processMemSet(MemSetInst *SI, BasicBlock::iterator &BBI);
bool processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI);
bool processMemMove(MemMoveInst *M);
- bool performCallSlotOptzn(Instruction *cpyLoad, Instruction *cpyStore,
- Value *cpyDst, Value *cpySrc, uint64_t cpyLen,
- Align cpyAlign, CallInst *C);
+ bool performCallSlotOptzn(Instruction *cpyLoad, Instruction *cpyStore,
+ Value *cpyDst, Value *cpySrc, uint64_t cpyLen,
+ Align cpyAlign, CallInst *C);
bool processMemCpyMemCpyDependence(MemCpyInst *M, MemCpyInst *MDep);
bool processMemSetMemCpyDependence(MemCpyInst *MemCpy, MemSetInst *MemSet);
bool performMemCpyToMemSetOptzn(MemCpyInst *MemCpy, MemSetInst *MemSet);
bool processByValArgument(CallBase &CB, unsigned ArgNo);
Instruction *tryMergingIntoMemset(Instruction *I, Value *StartPtr,
Value *ByteVal);
- bool moveUp(StoreInst *SI, Instruction *P, const LoadInst *LI);
+ bool moveUp(StoreInst *SI, Instruction *P, const LoadInst *LI);
- void eraseInstruction(Instruction *I);
+ void eraseInstruction(Instruction *I);
bool iterateOnFunction(Function &F);
};
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/NaryReassociate.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/NaryReassociate.h
index a91076c0c9..06a9cdc04b 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/NaryReassociate.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/NaryReassociate.h
@@ -121,7 +121,7 @@ private:
bool doOneIteration(Function &F);
// Reassociates I for better CSE.
- Instruction *tryReassociate(Instruction *I, const SCEV *&OrigSCEV);
+ Instruction *tryReassociate(Instruction *I, const SCEV *&OrigSCEV);
// Reassociate GEP for better CSE.
Instruction *tryReassociateGEP(GetElementPtrInst *GEP);
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/Reg2Mem.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/Reg2Mem.h
index 78ee91f0f8..d2a5d8cb85 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/Reg2Mem.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/Reg2Mem.h
@@ -1,38 +1,38 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- Reg2Mem.h - Convert registers to allocas -----------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides the interface for the RegToMem Pass.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_SCALAR_REG2MEM_H
-#define LLVM_TRANSFORMS_SCALAR_REG2MEM_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-
-class RegToMemPass : public PassInfoMixin<RegToMemPass> {
-public:
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_SCALAR_REG2MEM_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- Reg2Mem.h - Convert registers to allocas -----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the interface for the RegToMem Pass.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_REG2MEM_H
+#define LLVM_TRANSFORMS_SCALAR_REG2MEM_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class RegToMemPass : public PassInfoMixin<RegToMemPass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_REG2MEM_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/SROA.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/SROA.h
index 25471d0157..9f369eaf77 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/SROA.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/SROA.h
@@ -25,7 +25,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/PassManager.h"
-#include "llvm/IR/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
#include <vector>
namespace llvm {
@@ -85,8 +85,8 @@ class SROA : public PassInfoMixin<SROA> {
/// A collection of instructions to delete.
/// We try to batch deletions to simplify code and make things a bit more
- /// efficient. We also make sure there is no dangling pointers.
- SmallVector<WeakVH, 8> DeadInsts;
+ /// efficient. We also make sure there is no dangling pointers.
+ SmallVector<WeakVH, 8> DeadInsts;
/// Post-promotion worklist.
///
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h
index dbdfa7502d..89f08f823d 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h
@@ -1,40 +1,40 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- ScalarizeMaskedMemIntrin.h - Scalarize unsupported masked mem ----===//
-// instrinsics
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass replaces masked memory intrinsics - when unsupported by the target
-// - with a chain of basic blocks, that deal with the elements one-by-one if the
-// appropriate mask bit is set.
-//
-//===----------------------------------------------------------------------===//
-//
-#ifndef LLVM_TRANSFORMS_SCALAR_SCALARIZE_MASKED_MEMINTRIN_H
-#define LLVM_TRANSFORMS_SCALAR_SCALARIZE_MASKED_MEMINTRIN_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-
-struct ScalarizeMaskedMemIntrinPass
- : public PassInfoMixin<ScalarizeMaskedMemIntrinPass> {
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-} // end namespace llvm
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- ScalarizeMaskedMemIntrin.h - Scalarize unsupported masked mem ----===//
+// instrinsics
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass replaces masked memory intrinsics - when unsupported by the target
+// - with a chain of basic blocks, that deal with the elements one-by-one if the
+// appropriate mask bit is set.
+//
+//===----------------------------------------------------------------------===//
+//
+#ifndef LLVM_TRANSFORMS_SCALAR_SCALARIZE_MASKED_MEMINTRIN_H
+#define LLVM_TRANSFORMS_SCALAR_SCALARIZE_MASKED_MEMINTRIN_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+struct ScalarizeMaskedMemIntrinPass
+ : public PassInfoMixin<ScalarizeMaskedMemIntrinPass> {
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+} // end namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h
index 219d4f2354..258501eda8 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h
@@ -1,38 +1,38 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- SeparateConstOffsetFromGEP.h ---------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_SCALAR_SEPARATECONSTOFFSETFROMGEP_H
-#define LLVM_TRANSFORMS_SCALAR_SEPARATECONSTOFFSETFROMGEP_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-
-class SeparateConstOffsetFromGEPPass
- : public PassInfoMixin<SeparateConstOffsetFromGEPPass> {
- bool LowerGEP;
-
-public:
- SeparateConstOffsetFromGEPPass(bool LowerGEP = false) : LowerGEP(LowerGEP) {}
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &);
-};
-
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_SCALAR_SEPARATECONSTOFFSETFROMGEP_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- SeparateConstOffsetFromGEP.h ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_SEPARATECONSTOFFSETFROMGEP_H
+#define LLVM_TRANSFORMS_SCALAR_SEPARATECONSTOFFSETFROMGEP_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class SeparateConstOffsetFromGEPPass
+ : public PassInfoMixin<SeparateConstOffsetFromGEPPass> {
+ bool LowerGEP;
+
+public:
+ SeparateConstOffsetFromGEPPass(bool LowerGEP = false) : LowerGEP(LowerGEP) {}
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_SEPARATECONSTOFFSETFROMGEP_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/SimplifyCFG.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/SimplifyCFG.h
index 3e50d4b808..d87a05c3ac 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/SimplifyCFG.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/SimplifyCFG.h
@@ -23,7 +23,7 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
-#include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
+#include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
namespace llvm {
@@ -41,7 +41,7 @@ public:
/// rather than optimal IR. That is, by default we bypass transformations that
/// are likely to improve performance but make analysis for other passes more
/// difficult.
- SimplifyCFGPass();
+ SimplifyCFGPass();
/// Construct a pass with optional optimizations.
SimplifyCFGPass(const SimplifyCFGOptions &PassOptions);
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/StraightLineStrengthReduce.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/StraightLineStrengthReduce.h
index 4418930cce..628f029de0 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/StraightLineStrengthReduce.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/StraightLineStrengthReduce.h
@@ -1,35 +1,35 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- StraightLineStrengthReduce.h - -----------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_SCALAR_STRAIGHTLINESTRENGTHREDUCE_H
-#define LLVM_TRANSFORMS_SCALAR_STRAIGHTLINESTRENGTHREDUCE_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-
-class StraightLineStrengthReducePass
- : public PassInfoMixin<StraightLineStrengthReducePass> {
-public:
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-
-} // namespace llvm
-
-#endif // LLVM_TRANSFORMS_SCALAR_STRAIGHTLINESTRENGTHREDUCE_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- StraightLineStrengthReduce.h - -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_STRAIGHTLINESTRENGTHREDUCE_H
+#define LLVM_TRANSFORMS_SCALAR_STRAIGHTLINESTRENGTHREDUCE_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class StraightLineStrengthReducePass
+ : public PassInfoMixin<StraightLineStrengthReducePass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_STRAIGHTLINESTRENGTHREDUCE_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/StructurizeCFG.h b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/StructurizeCFG.h
index 4435610177..b36082a59c 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Scalar/StructurizeCFG.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Scalar/StructurizeCFG.h
@@ -1,31 +1,31 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- StructurizeCFG.h ---------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_SCALAR_STRUCTURIZECFG_H
-#define LLVM_TRANSFORMS_SCALAR_STRUCTURIZECFG_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-struct StructurizeCFGPass : PassInfoMixin<StructurizeCFGPass> {
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-} // namespace llvm
-
-#endif // LLVM_TRANSFORMS_SCALAR_STRUCTURIZECFG_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- StructurizeCFG.h ---------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_STRUCTURIZECFG_H
+#define LLVM_TRANSFORMS_SCALAR_STRUCTURIZECFG_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+struct StructurizeCFGPass : PassInfoMixin<StructurizeCFGPass> {
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_STRUCTURIZECFG_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils.h
index 4d1704538a..9937638f2f 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils.h
@@ -124,7 +124,7 @@ extern char &LoopSimplifyID;
/// This function returns a new pass that downgrades the debug info in the
/// module to line tables only.
-ModulePass *createStripNonLineTableDebugLegacyPass();
+ModulePass *createStripNonLineTableDebugLegacyPass();
//===----------------------------------------------------------------------===//
//
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/BasicBlockUtils.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/BasicBlockUtils.h
index 2b7016b7e6..17376fd660 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/BasicBlockUtils.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -81,7 +81,7 @@ bool EliminateUnreachableBlocks(Function &F, DomTreeUpdater *DTU = nullptr,
/// in it, fold them away. This handles the case when all entries to the PHI
/// nodes in a block are guaranteed equal, such as when the block has exactly
/// one predecessor.
-bool FoldSingleEntryPHINodes(BasicBlock *BB,
+bool FoldSingleEntryPHINodes(BasicBlock *BB,
MemoryDependenceResults *MemDep = nullptr);
/// Examine each PHI in the given block and delete it if it is dead. Also
@@ -203,8 +203,8 @@ struct CriticalEdgeSplittingOptions {
/// to.
BasicBlock *SplitCriticalEdge(Instruction *TI, unsigned SuccNum,
const CriticalEdgeSplittingOptions &Options =
- CriticalEdgeSplittingOptions(),
- const Twine &BBName = "");
+ CriticalEdgeSplittingOptions(),
+ const Twine &BBName = "");
inline BasicBlock *
SplitCriticalEdge(BasicBlock *BB, succ_iterator SI,
@@ -252,50 +252,72 @@ unsigned SplitAllCriticalEdges(Function &F,
const CriticalEdgeSplittingOptions &Options =
CriticalEdgeSplittingOptions());
-/// Split the edge connecting the specified blocks, and return the newly created
-/// basic block between \p From and \p To.
+/// Split the edge connecting the specified blocks, and return the newly created
+/// basic block between \p From and \p To.
BasicBlock *SplitEdge(BasicBlock *From, BasicBlock *To,
DominatorTree *DT = nullptr, LoopInfo *LI = nullptr,
- MemorySSAUpdater *MSSAU = nullptr,
- const Twine &BBName = "");
-
-/// Split the specified block at the specified instruction.
-///
-/// If \p Before is true, splitBlockBefore handles the block
-/// splitting. Otherwise, execution proceeds as described below.
-///
-/// Everything before \p SplitPt stays in \p Old and everything starting with \p
-/// SplitPt moves to a new block. The two blocks are joined by an unconditional
-/// branch. The new block with name \p BBName is returned.
-///
-/// FIXME: deprecated, switch to the DomTreeUpdater-based one.
-BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt, DominatorTree *DT,
- LoopInfo *LI = nullptr,
- MemorySSAUpdater *MSSAU = nullptr,
- const Twine &BBName = "", bool Before = false);
-
-/// Split the specified block at the specified instruction.
-///
-/// If \p Before is true, splitBlockBefore handles the block
-/// splitting. Otherwise, execution proceeds as described below.
-///
-/// Everything before \p SplitPt stays in \p Old and everything starting with \p
-/// SplitPt moves to a new block. The two blocks are joined by an unconditional
-/// branch. The new block with name \p BBName is returned.
+ MemorySSAUpdater *MSSAU = nullptr,
+ const Twine &BBName = "");
+
+/// Split the specified block at the specified instruction.
+///
+/// If \p Before is true, splitBlockBefore handles the block
+/// splitting. Otherwise, execution proceeds as described below.
+///
+/// Everything before \p SplitPt stays in \p Old and everything starting with \p
+/// SplitPt moves to a new block. The two blocks are joined by an unconditional
+/// branch. The new block with name \p BBName is returned.
+///
+/// FIXME: deprecated, switch to the DomTreeUpdater-based one.
+BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt, DominatorTree *DT,
+ LoopInfo *LI = nullptr,
+ MemorySSAUpdater *MSSAU = nullptr,
+ const Twine &BBName = "", bool Before = false);
+
+/// Split the specified block at the specified instruction.
+///
+/// If \p Before is true, splitBlockBefore handles the block
+/// splitting. Otherwise, execution proceeds as described below.
+///
+/// Everything before \p SplitPt stays in \p Old and everything starting with \p
+/// SplitPt moves to a new block. The two blocks are joined by an unconditional
+/// branch. The new block with name \p BBName is returned.
BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt,
- DomTreeUpdater *DTU = nullptr, LoopInfo *LI = nullptr,
+ DomTreeUpdater *DTU = nullptr, LoopInfo *LI = nullptr,
MemorySSAUpdater *MSSAU = nullptr,
- const Twine &BBName = "", bool Before = false);
-
-/// Split the specified block at the specified instruction \p SplitPt.
-/// All instructions before \p SplitPt are moved to a new block and all
-/// instructions after \p SplitPt stay in the old block. The new block and the
-/// old block are joined by inserting an unconditional branch to the end of the
-/// new block. The new block with name \p BBName is returned.
-BasicBlock *splitBlockBefore(BasicBlock *Old, Instruction *SplitPt,
- DomTreeUpdater *DTU, LoopInfo *LI,
- MemorySSAUpdater *MSSAU, const Twine &BBName = "");
-
+ const Twine &BBName = "", bool Before = false);
+
+/// Split the specified block at the specified instruction \p SplitPt.
+/// All instructions before \p SplitPt are moved to a new block and all
+/// instructions after \p SplitPt stay in the old block. The new block and the
+/// old block are joined by inserting an unconditional branch to the end of the
+/// new block. The new block with name \p BBName is returned.
+BasicBlock *splitBlockBefore(BasicBlock *Old, Instruction *SplitPt,
+ DomTreeUpdater *DTU, LoopInfo *LI,
+ MemorySSAUpdater *MSSAU, const Twine &BBName = "");
+
+/// This method introduces at least one new basic block into the function and
+/// moves some of the predecessors of BB to be predecessors of the new block.
+/// The new predecessors are indicated by the Preds array. The new block is
+/// given a suffix of 'Suffix'. Returns new basic block to which predecessors
+/// from Preds are now pointing.
+///
+/// If BB is a landingpad block then additional basicblock might be introduced.
+/// It will have Suffix+".split_lp". See SplitLandingPadPredecessors for more
+/// details on this case.
+///
+/// This currently updates the LLVM IR, DominatorTree, LoopInfo, and LCCSA but
+/// no other analyses. In particular, it does not preserve LoopSimplify
+/// (because it's complicated to handle the case where one of the edges being
+/// split is an exit of a loop with other exits).
+///
+/// FIXME: deprecated, switch to the DomTreeUpdater-based one.
+BasicBlock *SplitBlockPredecessors(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
+ const char *Suffix, DominatorTree *DT,
+ LoopInfo *LI = nullptr,
+ MemorySSAUpdater *MSSAU = nullptr,
+ bool PreserveLCSSA = false);
+
/// This method introduces at least one new basic block into the function and
/// moves some of the predecessors of BB to be predecessors of the new block.
/// The new predecessors are indicated by the Preds array. The new block is
@@ -310,31 +332,9 @@ BasicBlock *splitBlockBefore(BasicBlock *Old, Instruction *SplitPt,
/// no other analyses. In particular, it does not preserve LoopSimplify
/// (because it's complicated to handle the case where one of the edges being
/// split is an exit of a loop with other exits).
-///
-/// FIXME: deprecated, switch to the DomTreeUpdater-based one.
BasicBlock *SplitBlockPredecessors(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
- const char *Suffix, DominatorTree *DT,
- LoopInfo *LI = nullptr,
- MemorySSAUpdater *MSSAU = nullptr,
- bool PreserveLCSSA = false);
-
-/// This method introduces at least one new basic block into the function and
-/// moves some of the predecessors of BB to be predecessors of the new block.
-/// The new predecessors are indicated by the Preds array. The new block is
-/// given a suffix of 'Suffix'. Returns new basic block to which predecessors
-/// from Preds are now pointing.
-///
-/// If BB is a landingpad block then additional basicblock might be introduced.
-/// It will have Suffix+".split_lp". See SplitLandingPadPredecessors for more
-/// details on this case.
-///
-/// This currently updates the LLVM IR, DominatorTree, LoopInfo, and LCCSA but
-/// no other analyses. In particular, it does not preserve LoopSimplify
-/// (because it's complicated to handle the case where one of the edges being
-/// split is an exit of a loop with other exits).
-BasicBlock *SplitBlockPredecessors(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
const char *Suffix,
- DomTreeUpdater *DTU = nullptr,
+ DomTreeUpdater *DTU = nullptr,
LoopInfo *LI = nullptr,
MemorySSAUpdater *MSSAU = nullptr,
bool PreserveLCSSA = false);
@@ -350,31 +350,31 @@ BasicBlock *SplitBlockPredecessors(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
/// no other analyses. In particular, it does not preserve LoopSimplify
/// (because it's complicated to handle the case where one of the edges being
/// split is an exit of a loop with other exits).
-///
-/// FIXME: deprecated, switch to the DomTreeUpdater-based one.
-void SplitLandingPadPredecessors(BasicBlock *OrigBB,
- ArrayRef<BasicBlock *> Preds,
- const char *Suffix, const char *Suffix2,
- SmallVectorImpl<BasicBlock *> &NewBBs,
- DominatorTree *DT, LoopInfo *LI = nullptr,
- MemorySSAUpdater *MSSAU = nullptr,
- bool PreserveLCSSA = false);
-
-/// This method transforms the landing pad, OrigBB, by introducing two new basic
-/// blocks into the function. One of those new basic blocks gets the
-/// predecessors listed in Preds. The other basic block gets the remaining
-/// predecessors of OrigBB. The landingpad instruction OrigBB is clone into both
-/// of the new basic blocks. The new blocks are given the suffixes 'Suffix1' and
-/// 'Suffix2', and are returned in the NewBBs vector.
-///
-/// This currently updates the LLVM IR, DominatorTree, LoopInfo, and LCCSA but
-/// no other analyses. In particular, it does not preserve LoopSimplify
-/// (because it's complicated to handle the case where one of the edges being
-/// split is an exit of a loop with other exits).
+///
+/// FIXME: deprecated, switch to the DomTreeUpdater-based one.
+void SplitLandingPadPredecessors(BasicBlock *OrigBB,
+ ArrayRef<BasicBlock *> Preds,
+ const char *Suffix, const char *Suffix2,
+ SmallVectorImpl<BasicBlock *> &NewBBs,
+ DominatorTree *DT, LoopInfo *LI = nullptr,
+ MemorySSAUpdater *MSSAU = nullptr,
+ bool PreserveLCSSA = false);
+
+/// This method transforms the landing pad, OrigBB, by introducing two new basic
+/// blocks into the function. One of those new basic blocks gets the
+/// predecessors listed in Preds. The other basic block gets the remaining
+/// predecessors of OrigBB. The landingpad instruction OrigBB is clone into both
+/// of the new basic blocks. The new blocks are given the suffixes 'Suffix1' and
+/// 'Suffix2', and are returned in the NewBBs vector.
+///
+/// This currently updates the LLVM IR, DominatorTree, LoopInfo, and LCCSA but
+/// no other analyses. In particular, it does not preserve LoopSimplify
+/// (because it's complicated to handle the case where one of the edges being
+/// split is an exit of a loop with other exits).
void SplitLandingPadPredecessors(
BasicBlock *OrigBB, ArrayRef<BasicBlock *> Preds, const char *Suffix,
const char *Suffix2, SmallVectorImpl<BasicBlock *> &NewBBs,
- DomTreeUpdater *DTU = nullptr, LoopInfo *LI = nullptr,
+ DomTreeUpdater *DTU = nullptr, LoopInfo *LI = nullptr,
MemorySSAUpdater *MSSAU = nullptr, bool PreserveLCSSA = false);
/// This method duplicates the specified return instruction into a predecessor
@@ -406,39 +406,39 @@ ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
/// Returns the NewBasicBlock's terminator.
///
/// Updates DT and LI if given.
-///
-/// FIXME: deprecated, switch to the DomTreeUpdater-based one.
+///
+/// FIXME: deprecated, switch to the DomTreeUpdater-based one.
+Instruction *SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore,
+ bool Unreachable, MDNode *BranchWeights,
+ DominatorTree *DT,
+ LoopInfo *LI = nullptr,
+ BasicBlock *ThenBlock = nullptr);
+
+/// Split the containing block at the specified instruction - everything before
+/// SplitBefore stays in the old basic block, and the rest of the instructions
+/// in the BB are moved to a new block. The two blocks are connected by a
+/// conditional branch (with value of Cmp being the condition).
+/// Before:
+/// Head
+/// SplitBefore
+/// Tail
+/// After:
+/// Head
+/// if (Cond)
+/// ThenBlock
+/// SplitBefore
+/// Tail
+///
+/// If \p ThenBlock is not specified, a new block will be created for it.
+/// If \p Unreachable is true, the newly created block will end with
+/// UnreachableInst, otherwise it branches to Tail.
+/// Returns the NewBasicBlock's terminator.
+///
+/// Updates DT and LI if given.
Instruction *SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore,
- bool Unreachable, MDNode *BranchWeights,
- DominatorTree *DT,
- LoopInfo *LI = nullptr,
- BasicBlock *ThenBlock = nullptr);
-
-/// Split the containing block at the specified instruction - everything before
-/// SplitBefore stays in the old basic block, and the rest of the instructions
-/// in the BB are moved to a new block. The two blocks are connected by a
-/// conditional branch (with value of Cmp being the condition).
-/// Before:
-/// Head
-/// SplitBefore
-/// Tail
-/// After:
-/// Head
-/// if (Cond)
-/// ThenBlock
-/// SplitBefore
-/// Tail
-///
-/// If \p ThenBlock is not specified, a new block will be created for it.
-/// If \p Unreachable is true, the newly created block will end with
-/// UnreachableInst, otherwise it branches to Tail.
-/// Returns the NewBasicBlock's terminator.
-///
-/// Updates DT and LI if given.
-Instruction *SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore,
bool Unreachable,
MDNode *BranchWeights = nullptr,
- DomTreeUpdater *DTU = nullptr,
+ DomTreeUpdater *DTU = nullptr,
LoopInfo *LI = nullptr,
BasicBlock *ThenBlock = nullptr);
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/BuildLibCalls.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/BuildLibCalls.h
index 173218b15c..edb268a5b1 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/BuildLibCalls.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/BuildLibCalls.h
@@ -103,10 +103,10 @@ namespace llvm {
IRBuilderBase &B, const DataLayout &DL,
const TargetLibraryInfo *TLI);
- /// Emit a call to the mempcpy function.
- Value *emitMemPCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,
- const DataLayout &DL, const TargetLibraryInfo *TLI);
-
+ /// Emit a call to the mempcpy function.
+ Value *emitMemPCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,
+ const DataLayout &DL, const TargetLibraryInfo *TLI);
+
/// Emit a call to the memchr function. This assumes that Ptr is a pointer,
/// Val is an i32 value, and Len is an 'intptr_t' value.
Value *emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B,
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/CallGraphUpdater.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/CallGraphUpdater.h
index 520a4de374..52b14df3ed 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/CallGraphUpdater.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/CallGraphUpdater.h
@@ -94,7 +94,7 @@ public:
/// If a new function was created by outlining, this method can be called
/// to update the call graph for the new function. Note that the old one
/// still needs to be re-analyzed or manually updated.
- void registerOutlinedFunction(Function &OriginalFn, Function &NewFn);
+ void registerOutlinedFunction(Function &OriginalFn, Function &NewFn);
/// Replace \p OldFn in the call graph (and SCC) with \p NewFn. The uses
/// outside the call graph and the function \p OldFn are not modified.
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/Cloning.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/Cloning.h
index d15d6828ce..55e8d5d0b2 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/Cloning.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/Cloning.h
@@ -275,49 +275,49 @@ void updateProfileCallee(
Function *Callee, int64_t entryDelta,
const ValueMap<const Value *, WeakTrackingVH> *VMap = nullptr);
-/// Find the 'llvm.experimental.noalias.scope.decl' intrinsics in the specified
-/// basic blocks and extract their scope. These are candidates for duplication
-/// when cloning.
-void identifyNoAliasScopesToClone(
- ArrayRef<BasicBlock *> BBs, SmallVectorImpl<MDNode *> &NoAliasDeclScopes);
-
-/// Find the 'llvm.experimental.noalias.scope.decl' intrinsics in the specified
-/// instruction range and extract their scope. These are candidates for
-/// duplication when cloning.
-void identifyNoAliasScopesToClone(
- BasicBlock::iterator Start, BasicBlock::iterator End,
- SmallVectorImpl<MDNode *> &NoAliasDeclScopes);
-
-/// Duplicate the specified list of noalias decl scopes.
-/// The 'Ext' string is added as an extension to the name.
-/// Afterwards, the ClonedScopes contains the mapping of the original scope
-/// MDNode onto the cloned scope.
-/// Be aware that the cloned scopes are still part of the original scope domain.
-void cloneNoAliasScopes(
- ArrayRef<MDNode *> NoAliasDeclScopes,
- DenseMap<MDNode *, MDNode *> &ClonedScopes,
- StringRef Ext, LLVMContext &Context);
-
-/// Adapt the metadata for the specified instruction according to the
-/// provided mapping. This is normally used after cloning an instruction, when
-/// some noalias scopes needed to be cloned.
-void adaptNoAliasScopes(
- llvm::Instruction *I, const DenseMap<MDNode *, MDNode *> &ClonedScopes,
- LLVMContext &Context);
-
-/// Clone the specified noalias decl scopes. Then adapt all instructions in the
-/// NewBlocks basicblocks to the cloned versions.
-/// 'Ext' will be added to the duplicate scope names.
-void cloneAndAdaptNoAliasScopes(ArrayRef<MDNode *> NoAliasDeclScopes,
- ArrayRef<BasicBlock *> NewBlocks,
- LLVMContext &Context, StringRef Ext);
-
-/// Clone the specified noalias decl scopes. Then adapt all instructions in the
-/// [IStart, IEnd] (IEnd included !) range to the cloned versions. 'Ext' will be
-/// added to the duplicate scope names.
-void cloneAndAdaptNoAliasScopes(ArrayRef<MDNode *> NoAliasDeclScopes,
- Instruction *IStart, Instruction *IEnd,
- LLVMContext &Context, StringRef Ext);
+/// Find the 'llvm.experimental.noalias.scope.decl' intrinsics in the specified
+/// basic blocks and extract their scope. These are candidates for duplication
+/// when cloning.
+void identifyNoAliasScopesToClone(
+ ArrayRef<BasicBlock *> BBs, SmallVectorImpl<MDNode *> &NoAliasDeclScopes);
+
+/// Find the 'llvm.experimental.noalias.scope.decl' intrinsics in the specified
+/// instruction range and extract their scope. These are candidates for
+/// duplication when cloning.
+void identifyNoAliasScopesToClone(
+ BasicBlock::iterator Start, BasicBlock::iterator End,
+ SmallVectorImpl<MDNode *> &NoAliasDeclScopes);
+
+/// Duplicate the specified list of noalias decl scopes.
+/// The 'Ext' string is added as an extension to the name.
+/// Afterwards, the ClonedScopes contains the mapping of the original scope
+/// MDNode onto the cloned scope.
+/// Be aware that the cloned scopes are still part of the original scope domain.
+void cloneNoAliasScopes(
+ ArrayRef<MDNode *> NoAliasDeclScopes,
+ DenseMap<MDNode *, MDNode *> &ClonedScopes,
+ StringRef Ext, LLVMContext &Context);
+
+/// Adapt the metadata for the specified instruction according to the
+/// provided mapping. This is normally used after cloning an instruction, when
+/// some noalias scopes needed to be cloned.
+void adaptNoAliasScopes(
+ llvm::Instruction *I, const DenseMap<MDNode *, MDNode *> &ClonedScopes,
+ LLVMContext &Context);
+
+/// Clone the specified noalias decl scopes. Then adapt all instructions in the
+/// NewBlocks basicblocks to the cloned versions.
+/// 'Ext' will be added to the duplicate scope names.
+void cloneAndAdaptNoAliasScopes(ArrayRef<MDNode *> NoAliasDeclScopes,
+ ArrayRef<BasicBlock *> NewBlocks,
+ LLVMContext &Context, StringRef Ext);
+
+/// Clone the specified noalias decl scopes. Then adapt all instructions in the
+/// [IStart, IEnd] (IEnd included !) range to the cloned versions. 'Ext' will be
+/// added to the duplicate scope names.
+void cloneAndAdaptNoAliasScopes(ArrayRef<MDNode *> NoAliasDeclScopes,
+ Instruction *IStart, Instruction *IEnd,
+ LLVMContext &Context, StringRef Ext);
} // end namespace llvm
#endif // LLVM_TRANSFORMS_UTILS_CLONING_H
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/Debugify.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/Debugify.h
index c09449953d..7fc4011991 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/Debugify.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/Debugify.h
@@ -20,11 +20,11 @@
#ifndef LLVM_TRANSFORM_UTILS_DEBUGIFY_H
#define LLVM_TRANSFORM_UTILS_DEBUGIFY_H
-#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Bitcode/BitcodeWriterPass.h"
-#include "llvm/IR/IRPrintingPasses.h"
-#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/Bitcode/BitcodeWriterPass.h"
+#include "llvm/IR/IRPrintingPasses.h"
+#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
@@ -82,8 +82,8 @@ struct DebugifyStatistics {
/// Map pass names to a per-pass DebugifyStatistics instance.
using DebugifyStatsMap = llvm::MapVector<llvm::StringRef, DebugifyStatistics>;
-void exportDebugifyStats(StringRef Path, const DebugifyStatsMap &Map);
-
+void exportDebugifyStats(StringRef Path, const DebugifyStatsMap &Map);
+
llvm::ModulePass *
createCheckDebugifyModulePass(bool Strip = false,
llvm::StringRef NameOfWrappedPass = "",
@@ -99,62 +99,62 @@ struct NewPMCheckDebugifyPass
llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM);
};
-struct DebugifyEachInstrumentation {
- DebugifyStatsMap StatsMap;
-
- void registerCallbacks(PassInstrumentationCallbacks &PIC);
-};
-
-/// DebugifyCustomPassManager wraps each pass with the debugify passes if
-/// needed.
-/// NOTE: We support legacy custom pass manager only.
-/// TODO: Add New PM support for custom pass manager.
-class DebugifyCustomPassManager : public legacy::PassManager {
- DebugifyStatsMap DIStatsMap;
- bool EnableDebugifyEach = false;
-
-public:
- using super = legacy::PassManager;
-
- void add(Pass *P) override {
- // Wrap each pass with (-check)-debugify passes if requested, making
- // exceptions for passes which shouldn't see -debugify instrumentation.
- bool WrapWithDebugify = EnableDebugifyEach && !P->getAsImmutablePass() &&
- !isIRPrintingPass(P) && !isBitcodeWriterPass(P);
- if (!WrapWithDebugify) {
- super::add(P);
- return;
- }
-
- // Apply -debugify/-check-debugify before/after each pass and collect
- // debug info loss statistics.
- PassKind Kind = P->getPassKind();
- StringRef Name = P->getPassName();
-
- // TODO: Implement Debugify for LoopPass.
- switch (Kind) {
- case PT_Function:
- super::add(createDebugifyFunctionPass());
- super::add(P);
- super::add(createCheckDebugifyFunctionPass(true, Name, &DIStatsMap));
- break;
- case PT_Module:
- super::add(createDebugifyModulePass());
- super::add(P);
- super::add(createCheckDebugifyModulePass(true, Name, &DIStatsMap));
- break;
- default:
- super::add(P);
- break;
- }
- }
-
- void enableDebugifyEach() { EnableDebugifyEach = true; }
-
- const DebugifyStatsMap &getDebugifyStatsMap() const { return DIStatsMap; }
-};
-} // namespace llvm
-
+struct DebugifyEachInstrumentation {
+ DebugifyStatsMap StatsMap;
+
+ void registerCallbacks(PassInstrumentationCallbacks &PIC);
+};
+
+/// DebugifyCustomPassManager wraps each pass with the debugify passes if
+/// needed.
+/// NOTE: We support legacy custom pass manager only.
+/// TODO: Add New PM support for custom pass manager.
+class DebugifyCustomPassManager : public legacy::PassManager {
+ DebugifyStatsMap DIStatsMap;
+ bool EnableDebugifyEach = false;
+
+public:
+ using super = legacy::PassManager;
+
+ void add(Pass *P) override {
+ // Wrap each pass with (-check)-debugify passes if requested, making
+ // exceptions for passes which shouldn't see -debugify instrumentation.
+ bool WrapWithDebugify = EnableDebugifyEach && !P->getAsImmutablePass() &&
+ !isIRPrintingPass(P) && !isBitcodeWriterPass(P);
+ if (!WrapWithDebugify) {
+ super::add(P);
+ return;
+ }
+
+ // Apply -debugify/-check-debugify before/after each pass and collect
+ // debug info loss statistics.
+ PassKind Kind = P->getPassKind();
+ StringRef Name = P->getPassName();
+
+ // TODO: Implement Debugify for LoopPass.
+ switch (Kind) {
+ case PT_Function:
+ super::add(createDebugifyFunctionPass());
+ super::add(P);
+ super::add(createCheckDebugifyFunctionPass(true, Name, &DIStatsMap));
+ break;
+ case PT_Module:
+ super::add(createDebugifyModulePass());
+ super::add(P);
+ super::add(createCheckDebugifyModulePass(true, Name, &DIStatsMap));
+ break;
+ default:
+ super::add(P);
+ break;
+ }
+ }
+
+ void enableDebugifyEach() { EnableDebugifyEach = true; }
+
+ const DebugifyStatsMap &getDebugifyStatsMap() const { return DIStatsMap; }
+};
+} // namespace llvm
+
#endif // LLVM_TRANSFORM_UTILS_DEBUGIFY_H
#ifdef __GNUC__
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/FixIrreducible.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/FixIrreducible.h
index cdd35469b1..6417ea5882 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/FixIrreducible.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/FixIrreducible.h
@@ -1,31 +1,31 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- FixIrreducible.h - Convert irreducible control-flow into loops -----===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_FIXIRREDUCIBLE_H
-#define LLVM_TRANSFORMS_UTILS_FIXIRREDUCIBLE_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-struct FixIrreduciblePass : PassInfoMixin<FixIrreduciblePass> {
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-} // namespace llvm
-
-#endif // LLVM_TRANSFORMS_UTILS_FIXIRREDUCIBLE_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- FixIrreducible.h - Convert irreducible control-flow into loops -----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_FIXIRREDUCIBLE_H
+#define LLVM_TRANSFORMS_UTILS_FIXIRREDUCIBLE_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+struct FixIrreduciblePass : PassInfoMixin<FixIrreduciblePass> {
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_FIXIRREDUCIBLE_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/InstructionNamer.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/InstructionNamer.h
index e755bf4087..c9ede371d9 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/InstructionNamer.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/InstructionNamer.h
@@ -1,31 +1,31 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- InstructionNamer.h - Give anonymous instructions names -------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_INSTRUCTIONNAMER_H
-#define LLVM_TRANSFORMS_UTILS_INSTRUCTIONNAMER_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-struct InstructionNamerPass : PassInfoMixin<InstructionNamerPass> {
- PreservedAnalyses run(Function &, FunctionAnalysisManager &);
-};
-} // namespace llvm
-
-#endif // LLVM_TRANSFORMS_UTILS_INSTRUCTIONNAMER_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- InstructionNamer.h - Give anonymous instructions names -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_INSTRUCTIONNAMER_H
+#define LLVM_TRANSFORMS_UTILS_INSTRUCTIONNAMER_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+struct InstructionNamerPass : PassInfoMixin<InstructionNamerPass> {
+ PreservedAnalyses run(Function &, FunctionAnalysisManager &);
+};
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_INSTRUCTIONNAMER_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/Local.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/Local.h
index 40cf2cb596..9c76913256 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/Local.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/Local.h
@@ -36,8 +36,8 @@
#include "llvm/IR/Value.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
#include <cstdint>
#include <limits>
@@ -101,9 +101,9 @@ bool wouldInstructionBeTriviallyDead(Instruction *I,
/// recursively. Return true if any instructions were deleted.
bool RecursivelyDeleteTriviallyDeadInstructions(
Value *V, const TargetLibraryInfo *TLI = nullptr,
- MemorySSAUpdater *MSSAU = nullptr,
- std::function<void(Value *)> AboutToDeleteCallback =
- std::function<void(Value *)>());
+ MemorySSAUpdater *MSSAU = nullptr,
+ std::function<void(Value *)> AboutToDeleteCallback =
+ std::function<void(Value *)>());
/// Delete all of the instructions in `DeadInsts`, and all other instructions
/// that deleting these in turn causes to be trivially dead.
@@ -115,9 +115,9 @@ bool RecursivelyDeleteTriviallyDeadInstructions(
/// empty afterward.
void RecursivelyDeleteTriviallyDeadInstructions(
SmallVectorImpl<WeakTrackingVH> &DeadInsts,
- const TargetLibraryInfo *TLI = nullptr, MemorySSAUpdater *MSSAU = nullptr,
- std::function<void(Value *)> AboutToDeleteCallback =
- std::function<void(Value *)>());
+ const TargetLibraryInfo *TLI = nullptr, MemorySSAUpdater *MSSAU = nullptr,
+ std::function<void(Value *)> AboutToDeleteCallback =
+ std::function<void(Value *)>());
/// Same functionality as RecursivelyDeleteTriviallyDeadInstructions, but allow
/// instructions that are not trivially dead. These will be ignored.
@@ -125,9 +125,9 @@ void RecursivelyDeleteTriviallyDeadInstructions(
/// were found and deleted.
bool RecursivelyDeleteTriviallyDeadInstructionsPermissive(
SmallVectorImpl<WeakTrackingVH> &DeadInsts,
- const TargetLibraryInfo *TLI = nullptr, MemorySSAUpdater *MSSAU = nullptr,
- std::function<void(Value *)> AboutToDeleteCallback =
- std::function<void(Value *)>());
+ const TargetLibraryInfo *TLI = nullptr, MemorySSAUpdater *MSSAU = nullptr,
+ std::function<void(Value *)> AboutToDeleteCallback =
+ std::function<void(Value *)>());
/// 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
@@ -179,11 +179,11 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB);
/// It returns true if a modification was made, possibly deleting the basic
/// block that was pointed to. LoopHeaders is an optional input parameter
/// providing the set of loop headers that SimplifyCFG should not eliminate.
-extern cl::opt<bool> RequireAndPreserveDomTree;
+extern cl::opt<bool> RequireAndPreserveDomTree;
bool simplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
- DomTreeUpdater *DTU = nullptr,
+ DomTreeUpdater *DTU = nullptr,
const SimplifyCFGOptions &Options = {},
- ArrayRef<WeakVH> LoopHeaders = {});
+ ArrayRef<WeakVH> LoopHeaders = {});
/// This function is used to flatten a CFG. For example, it uses parallel-and
/// and parallel-or mode to collapse if-conditions and merge if-regions with
@@ -193,9 +193,9 @@ bool FlattenCFG(BasicBlock *BB, AAResults *AA = nullptr);
/// If this basic block is ONLY a setcc and a branch, and if a predecessor
/// branches to us and one of our successors, fold the setcc into the
/// predecessor and use logical operations to pick the right destination.
-bool FoldBranchToCommonDest(BranchInst *BI, llvm::DomTreeUpdater *DTU = nullptr,
- MemorySSAUpdater *MSSAU = nullptr,
- const TargetTransformInfo *TTI = nullptr,
+bool FoldBranchToCommonDest(BranchInst *BI, llvm::DomTreeUpdater *DTU = nullptr,
+ MemorySSAUpdater *MSSAU = nullptr,
+ const TargetTransformInfo *TTI = nullptr,
unsigned BonusInstThreshold = 1);
/// This function takes a virtual register computed by an Instruction and
@@ -339,13 +339,13 @@ DIExpression *salvageDebugInfoImpl(Instruction &I, DIExpression *DIExpr,
bool replaceAllDbgUsesWith(Instruction &From, Value &To, Instruction &DomPoint,
DominatorTree &DT);
-/// Remove all instructions from a basic block other than its terminator
-/// and any present EH pad instructions. Returns a pair where the first element
-/// is the number of instructions (excluding debug info instrinsics) that have
-/// been removed, and the second element is the number of debug info intrinsics
-/// that have been removed.
-std::pair<unsigned, unsigned>
-removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB);
+/// Remove all instructions from a basic block other than its terminator
+/// and any present EH pad instructions. Returns a pair where the first element
+/// is the number of instructions (excluding debug info instrinsics) that have
+/// been removed, and the second element is the number of debug info intrinsics
+/// that have been removed.
+std::pair<unsigned, unsigned>
+removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB);
/// Insert an unreachable instruction before the specified
/// instruction, making it and the rest of the code in the block dead.
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopPeel.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopPeel.h
index 913345fe1e..df15ce4fca 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopPeel.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopPeel.h
@@ -1,51 +1,51 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- llvm/Transforms/Utils/LoopPeel.h ----- Peeling utilities -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines some loop peeling utilities. It does not define any
-// actual pass or policy.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_LOOPPEEL_H
-#define LLVM_TRANSFORMS_UTILS_LOOPPEEL_H
-
-#include "llvm/Analysis/TargetTransformInfo.h"
-
-namespace llvm {
-
-bool canPeel(Loop *L);
-
-bool peelLoop(Loop *L, unsigned PeelCount, LoopInfo *LI, ScalarEvolution *SE,
- DominatorTree *DT, AssumptionCache *AC, bool PreserveLCSSA);
-
-TargetTransformInfo::PeelingPreferences
-gatherPeelingPreferences(Loop *L, ScalarEvolution &SE,
- const TargetTransformInfo &TTI,
- Optional<bool> UserAllowPeeling,
- Optional<bool> UserAllowProfileBasedPeeling,
- bool UnrollingSpecficValues = false);
-
-void computePeelCount(Loop *L, unsigned LoopSize,
- TargetTransformInfo::PeelingPreferences &PP,
- unsigned &TripCount, ScalarEvolution &SE,
- unsigned Threshold = UINT_MAX);
-
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_UTILS_LOOPPEEL_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- llvm/Transforms/Utils/LoopPeel.h ----- Peeling utilities -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines some loop peeling utilities. It does not define any
+// actual pass or policy.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_LOOPPEEL_H
+#define LLVM_TRANSFORMS_UTILS_LOOPPEEL_H
+
+#include "llvm/Analysis/TargetTransformInfo.h"
+
+namespace llvm {
+
+bool canPeel(Loop *L);
+
+bool peelLoop(Loop *L, unsigned PeelCount, LoopInfo *LI, ScalarEvolution *SE,
+ DominatorTree *DT, AssumptionCache *AC, bool PreserveLCSSA);
+
+TargetTransformInfo::PeelingPreferences
+gatherPeelingPreferences(Loop *L, ScalarEvolution &SE,
+ const TargetTransformInfo &TTI,
+ Optional<bool> UserAllowPeeling,
+ Optional<bool> UserAllowProfileBasedPeeling,
+ bool UnrollingSpecficValues = false);
+
+void computePeelCount(Loop *L, unsigned LoopSize,
+ TargetTransformInfo::PeelingPreferences &PP,
+ unsigned &TripCount, ScalarEvolution &SE,
+ unsigned Threshold = UINT_MAX);
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_LOOPPEEL_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopRotationUtils.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopRotationUtils.h
index b13b8c79b0..acfbf03d02 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopRotationUtils.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopRotationUtils.h
@@ -40,8 +40,8 @@ class TargetTransformInfo;
bool LoopRotation(Loop *L, LoopInfo *LI, const TargetTransformInfo *TTI,
AssumptionCache *AC, DominatorTree *DT, ScalarEvolution *SE,
MemorySSAUpdater *MSSAU, const SimplifyQuery &SQ,
- bool RotationOnly, unsigned Threshold, bool IsUtilMode,
- bool PrepareForLTO = false);
+ bool RotationOnly, unsigned Threshold, bool IsUtilMode,
+ bool PrepareForLTO = false);
} // namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopUtils.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopUtils.h
index f3d2d970b9..dc655420b5 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopUtils.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopUtils.h
@@ -33,8 +33,8 @@ class AAResults;
class AliasSet;
class AliasSetTracker;
class BasicBlock;
-class BlockFrequencyInfo;
-class ICFLoopSafetyInfo;
+class BlockFrequencyInfo;
+class ICFLoopSafetyInfo;
class IRBuilderBase;
class Loop;
class LoopInfo;
@@ -82,14 +82,14 @@ bool formDedicatedExitBlocks(Loop *L, DominatorTree *DT, LoopInfo *LI,
/// changes to CFG, preserved.
///
/// Returns true if any modifications are made.
-///
-/// This function may introduce unused PHI nodes. If \p PHIsToRemove is not
-/// nullptr, those are added to it (before removing, the caller has to check if
-/// they still do not have any uses). Otherwise the PHIs are directly removed.
-bool formLCSSAForInstructions(
- SmallVectorImpl<Instruction *> &Worklist, const DominatorTree &DT,
- const LoopInfo &LI, ScalarEvolution *SE, IRBuilderBase &Builder,
- SmallVectorImpl<PHINode *> *PHIsToRemove = nullptr);
+///
+/// This function may introduce unused PHI nodes. If \p PHIsToRemove is not
+/// nullptr, those are added to it (before removing, the caller has to check if
+/// they still do not have any uses). Otherwise the PHIs are directly removed.
+bool formLCSSAForInstructions(
+ SmallVectorImpl<Instruction *> &Worklist, const DominatorTree &DT,
+ const LoopInfo &LI, ScalarEvolution *SE, IRBuilderBase &Builder,
+ SmallVectorImpl<PHINode *> *PHIsToRemove = nullptr);
/// Put loop into LCSSA form.
///
@@ -118,28 +118,28 @@ bool formLCSSA(Loop &L, const DominatorTree &DT, const LoopInfo *LI,
bool formLCSSARecursively(Loop &L, const DominatorTree &DT, const LoopInfo *LI,
ScalarEvolution *SE);
-/// Flags controlling how much is checked when sinking or hoisting
-/// instructions. The number of memory access in the loop (and whether there
-/// are too many) is determined in the constructors when using MemorySSA.
-class SinkAndHoistLICMFlags {
-public:
- // Explicitly set limits.
- SinkAndHoistLICMFlags(unsigned LicmMssaOptCap,
- unsigned LicmMssaNoAccForPromotionCap, bool IsSink,
- Loop *L = nullptr, MemorySSA *MSSA = nullptr);
- // Use default limits.
- SinkAndHoistLICMFlags(bool IsSink, Loop *L = nullptr,
- MemorySSA *MSSA = nullptr);
-
- void setIsSink(bool B) { IsSink = B; }
- bool getIsSink() { return IsSink; }
- bool tooManyMemoryAccesses() { return NoOfMemAccTooLarge; }
- bool tooManyClobberingCalls() { return LicmMssaOptCounter >= LicmMssaOptCap; }
- void incrementClobberingCalls() { ++LicmMssaOptCounter; }
-
-protected:
- bool NoOfMemAccTooLarge = false;
- unsigned LicmMssaOptCounter = 0;
+/// Flags controlling how much is checked when sinking or hoisting
+/// instructions. The number of memory access in the loop (and whether there
+/// are too many) is determined in the constructors when using MemorySSA.
+class SinkAndHoistLICMFlags {
+public:
+ // Explicitly set limits.
+ SinkAndHoistLICMFlags(unsigned LicmMssaOptCap,
+ unsigned LicmMssaNoAccForPromotionCap, bool IsSink,
+ Loop *L = nullptr, MemorySSA *MSSA = nullptr);
+ // Use default limits.
+ SinkAndHoistLICMFlags(bool IsSink, Loop *L = nullptr,
+ MemorySSA *MSSA = nullptr);
+
+ void setIsSink(bool B) { IsSink = B; }
+ bool getIsSink() { return IsSink; }
+ bool tooManyMemoryAccesses() { return NoOfMemAccTooLarge; }
+ bool tooManyClobberingCalls() { return LicmMssaOptCounter >= LicmMssaOptCap; }
+ void incrementClobberingCalls() { ++LicmMssaOptCounter; }
+
+protected:
+ bool NoOfMemAccTooLarge = false;
+ unsigned LicmMssaOptCounter = 0;
unsigned LicmMssaOptCap;
unsigned LicmMssaNoAccForPromotionCap;
bool IsSink;
@@ -150,13 +150,13 @@ protected:
/// reverse depth first order w.r.t the DominatorTree. This allows us to visit
/// uses before definitions, allowing us to sink a loop body in one pass without
/// iteration. Takes DomTreeNode, AAResults, LoopInfo, DominatorTree,
-/// BlockFrequencyInfo, TargetLibraryInfo, Loop, AliasSet information for all
+/// BlockFrequencyInfo, TargetLibraryInfo, Loop, AliasSet information for all
/// instructions of the loop and loop safety information as
/// arguments. Diagnostics is emitted via \p ORE. It returns changed status.
bool sinkRegion(DomTreeNode *, AAResults *, LoopInfo *, DominatorTree *,
- BlockFrequencyInfo *, TargetLibraryInfo *,
- TargetTransformInfo *, Loop *, AliasSetTracker *,
- MemorySSAUpdater *, ICFLoopSafetyInfo *,
+ BlockFrequencyInfo *, TargetLibraryInfo *,
+ TargetTransformInfo *, Loop *, AliasSetTracker *,
+ MemorySSAUpdater *, ICFLoopSafetyInfo *,
SinkAndHoistLICMFlags &, OptimizationRemarkEmitter *);
/// Walk the specified region of the CFG (defined by all blocks
@@ -164,14 +164,14 @@ bool sinkRegion(DomTreeNode *, AAResults *, LoopInfo *, DominatorTree *,
/// first order w.r.t the DominatorTree. This allows us to visit definitions
/// before uses, allowing us to hoist a loop body in one pass without iteration.
/// Takes DomTreeNode, AAResults, LoopInfo, DominatorTree,
-/// BlockFrequencyInfo, TargetLibraryInfo, Loop, AliasSet information for all
-/// instructions of the loop and loop safety information as arguments.
-/// Diagnostics is emitted via \p ORE. It returns changed status.
+/// BlockFrequencyInfo, TargetLibraryInfo, Loop, AliasSet information for all
+/// instructions of the loop and loop safety information as arguments.
+/// Diagnostics is emitted via \p ORE. It returns changed status.
bool hoistRegion(DomTreeNode *, AAResults *, LoopInfo *, DominatorTree *,
- BlockFrequencyInfo *, TargetLibraryInfo *, Loop *,
- AliasSetTracker *, MemorySSAUpdater *, ScalarEvolution *,
- ICFLoopSafetyInfo *, SinkAndHoistLICMFlags &,
- OptimizationRemarkEmitter *);
+ BlockFrequencyInfo *, TargetLibraryInfo *, Loop *,
+ AliasSetTracker *, MemorySSAUpdater *, ScalarEvolution *,
+ ICFLoopSafetyInfo *, SinkAndHoistLICMFlags &,
+ OptimizationRemarkEmitter *);
/// This function deletes dead loops. The caller of this function needs to
/// guarantee that the loop is infact dead.
@@ -187,12 +187,12 @@ bool hoistRegion(DomTreeNode *, AAResults *, LoopInfo *, DominatorTree *,
void deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE,
LoopInfo *LI, MemorySSA *MSSA = nullptr);
-/// Remove the backedge of the specified loop. Handles loop nests and general
-/// loop structures subject to the precondition that the loop has no parent
-/// loop and has a single latch block. Preserves all listed analyses.
-void breakLoopBackedge(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
- LoopInfo &LI, MemorySSA *MSSA);
-
+/// Remove the backedge of the specified loop. Handles loop nests and general
+/// loop structures subject to the precondition that the loop has no parent
+/// loop and has a single latch block. Preserves all listed analyses.
+void breakLoopBackedge(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
+ LoopInfo &LI, MemorySSA *MSSA);
+
/// Try to promote memory values to scalars by sinking stores out of
/// the loop and moving loads to before the loop. We do this by looping over
/// the stores in the loop, looking for stores to Must pointers which are
@@ -227,13 +227,13 @@ Optional<const MDOperand *> findStringMetadataForLoop(const Loop *TheLoop,
/// Find named metadata for a loop with an integer value.
llvm::Optional<int> getOptionalIntLoopAttribute(Loop *TheLoop, StringRef Name);
-/// Find a combination of metadata ("llvm.loop.vectorize.width" and
-/// "llvm.loop.vectorize.scalable.enable") for a loop and use it to construct a
-/// ElementCount. If the metadata "llvm.loop.vectorize.width" cannot be found
-/// then None is returned.
-Optional<ElementCount>
-getOptionalElementCountLoopAttribute(Loop *TheLoop);
-
+/// Find a combination of metadata ("llvm.loop.vectorize.width" and
+/// "llvm.loop.vectorize.scalable.enable") for a loop and use it to construct a
+/// ElementCount. If the metadata "llvm.loop.vectorize.width" cannot be found
+/// then None is returned.
+Optional<ElementCount>
+getOptionalElementCountLoopAttribute(Loop *TheLoop);
+
/// Create a new loop identifier for a loop created from a loop transformation.
///
/// @param OrigLoopID The loop ID of the loop before the transformation.
@@ -269,9 +269,9 @@ bool hasDisableAllTransformsHint(const Loop *L);
/// Look for the loop attribute that disables the LICM transformation heuristics.
bool hasDisableLICMTransformsHint(const Loop *L);
-/// Look for the loop attribute that requires progress within the loop.
-bool hasMustProgress(const Loop *L);
-
+/// Look for the loop attribute that requires progress within the loop.
+bool hasMustProgress(const Loop *L);
+
/// The mode sets how eager a transformation should be applied.
enum TransformationMode {
/// The pass can use heuristics to determine whether a transformation should
@@ -314,9 +314,9 @@ TransformationMode hasLICMVersioningTransformation(Loop *L);
void addStringMetadataToLoop(Loop *TheLoop, const char *MDString,
unsigned V = 0);
-/// Returns true if Name is applied to TheLoop and enabled.
-bool getBooleanLoopAttribute(const Loop *TheLoop, StringRef Name);
-
+/// Returns true if Name is applied to TheLoop and enabled.
+bool getBooleanLoopAttribute(const Loop *TheLoop, StringRef Name);
+
/// Returns a loop's estimated trip count based on branch weight metadata.
/// In addition if \p EstimatedLoopInvocationWeight is not null it is
/// initialized with weight of loop's latch leading to the exit.
@@ -362,29 +362,29 @@ bool canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
OptimizationRemarkEmitter *ORE = nullptr);
/// Returns a Min/Max operation corresponding to MinMaxRecurrenceKind.
-Value *createMinMaxOp(IRBuilderBase &Builder, RecurKind RK, Value *Left,
- Value *Right);
+Value *createMinMaxOp(IRBuilderBase &Builder, RecurKind RK, Value *Left,
+ Value *Right);
/// Generates an ordered vector reduction using extracts to reduce the value.
-Value *getOrderedReduction(IRBuilderBase &Builder, Value *Acc, Value *Src,
- unsigned Op, RecurKind MinMaxKind = RecurKind::None,
- ArrayRef<Value *> RedOps = None);
+Value *getOrderedReduction(IRBuilderBase &Builder, Value *Acc, Value *Src,
+ unsigned Op, RecurKind MinMaxKind = RecurKind::None,
+ ArrayRef<Value *> RedOps = None);
/// Generates a vector reduction using shufflevectors to reduce the value.
/// Fast-math-flags are propagated using the IRBuilder's setting.
Value *getShuffleReduction(IRBuilderBase &Builder, Value *Src, unsigned Op,
- RecurKind MinMaxKind = RecurKind::None,
+ RecurKind MinMaxKind = RecurKind::None,
ArrayRef<Value *> RedOps = None);
/// Create a target reduction of the given vector. The reduction operation
/// is described by the \p Opcode parameter. min/max reductions require
-/// additional information supplied in \p RdxKind.
+/// additional information supplied in \p RdxKind.
/// The target is queried to determine if intrinsics or shuffle sequences are
/// required to implement the reduction.
/// Fast-math-flags are propagated using the IRBuilder's setting.
Value *createSimpleTargetReduction(IRBuilderBase &B,
- const TargetTransformInfo *TTI, Value *Src,
- RecurKind RdxKind,
+ const TargetTransformInfo *TTI, Value *Src,
+ RecurKind RdxKind,
ArrayRef<Value *> RedOps = None);
/// Create a generic target reduction using a recurrence descriptor \p Desc
@@ -392,7 +392,7 @@ Value *createSimpleTargetReduction(IRBuilderBase &B,
/// required to implement the reduction.
/// Fast-math-flags are propagated using the RecurrenceDescriptor.
Value *createTargetReduction(IRBuilderBase &B, const TargetTransformInfo *TTI,
- RecurrenceDescriptor &Desc, Value *Src);
+ RecurrenceDescriptor &Desc, Value *Src);
/// Get the intersection (logical and) of all of the potential IR flags
/// of each scalar operation (VL) that will be converted into a vector (I).
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopVersioning.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopVersioning.h
index fb33ce142b..dd7394a3f0 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopVersioning.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/LoopVersioning.h
@@ -23,7 +23,7 @@
#define LLVM_TRANSFORMS_UTILS_LOOPVERSIONING_H
#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
@@ -50,9 +50,9 @@ public:
/// It uses runtime check provided by the user. If \p UseLAIChecks is true,
/// we will retain the default checks made by LAI. Otherwise, construct an
/// object having no checks and we expect the user to add them.
- LoopVersioning(const LoopAccessInfo &LAI,
- ArrayRef<RuntimePointerCheck> Checks, Loop *L, LoopInfo *LI,
- DominatorTree *DT, ScalarEvolution *SE);
+ LoopVersioning(const LoopAccessInfo &LAI,
+ ArrayRef<RuntimePointerCheck> Checks, Loop *L, LoopInfo *LI,
+ DominatorTree *DT, ScalarEvolution *SE);
/// Performs the CFG manipulation part of versioning the loop including
/// the DominatorTree and LoopInfo updates.
@@ -130,7 +130,7 @@ private:
SmallVector<RuntimePointerCheck, 4> AliasChecks;
/// The set of SCEV checks that we are versioning for.
- const SCEVUnionPredicate &Preds;
+ const SCEVUnionPredicate &Preds;
/// Maps a pointer to the pointer checking group that the pointer
/// belongs to.
@@ -149,14 +149,14 @@ private:
DominatorTree *DT;
ScalarEvolution *SE;
};
-
-/// Expose LoopVersioning as a pass. Currently this is only used for
-/// unit-testing. It adds all memchecks necessary to remove all may-aliasing
-/// array accesses from the loop.
-class LoopVersioningPass : public PassInfoMixin<LoopVersioningPass> {
-public:
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
-};
+
+/// Expose LoopVersioning as a pass. Currently this is only used for
+/// unit-testing. It adds all memchecks necessary to remove all may-aliasing
+/// array accesses from the loop.
+class LoopVersioningPass : public PassInfoMixin<LoopVersioningPass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
+};
}
#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/LowerSwitch.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/LowerSwitch.h
index 5a801fc704..1d177dd618 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/LowerSwitch.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/LowerSwitch.h
@@ -1,37 +1,37 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- LowerSwitch.h - Eliminate Switch instructions ----------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// The LowerSwitch transformation rewrites switch instructions with a sequence
-// of branches, which allows targets to get away with not implementing the
-// switch instruction until it is convenient.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_LOWERSWITCH_H
-#define LLVM_TRANSFORMS_UTILS_LOWERSWITCH_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-struct LowerSwitchPass : public PassInfoMixin<LowerSwitchPass> {
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-} // namespace llvm
-
-#endif // LLVM_TRANSFORMS_UTILS_LOWERSWITCH_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- LowerSwitch.h - Eliminate Switch instructions ----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// The LowerSwitch transformation rewrites switch instructions with a sequence
+// of branches, which allows targets to get away with not implementing the
+// switch instruction until it is convenient.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_LOWERSWITCH_H
+#define LLVM_TRANSFORMS_UTILS_LOWERSWITCH_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+struct LowerSwitchPass : public PassInfoMixin<LowerSwitchPass> {
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_LOWERSWITCH_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/MatrixUtils.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/MatrixUtils.h
index 8606974e57..948e51e22b 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/MatrixUtils.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/MatrixUtils.h
@@ -1,105 +1,105 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- MatrixUtils.h - Utilities to lower matrix intrinsics -----*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Utilities for generating tiled loops for matrix operations.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_MATRIXUTILS_H
-#define LLVM_TRANSFORMS_UTILS_MATRIXUTILS_H
-
-#include "llvm/ADT/StringRef.h"
-
-namespace llvm {
-class DomTreeUpdater;
-class BasicBlock;
-class Value;
-class Loop;
-class LoopInfo;
-class IRBuilderBase;
-
-/// A helper struct to create IR loop nests for tiling in IR of the following
-/// form:
-/// for CurrentColumn = 0..NumColumns
-/// for CurrentRow = 0..NumRows
-/// for CurrentInner = 0..NumInner
-struct TileInfo {
- /// Number of rows of the matrix.
- unsigned NumRows;
-
- /// Number of columns of the matrix.
- unsigned NumColumns;
-
- /// Number of columns of the first matrix of a multiply /
- /// number of rows of the second matrix of a multiply.
- unsigned NumInner;
-
- /// Number of rows/columns in a tile.
- unsigned TileSize = -1;
-
- /// Start row of the current tile to compute.
- Value *CurrentRow;
-
- /// Start column of the current tile to compute.
- Value *CurrentCol;
-
- /// Current tile offset during the tile computation.
- Value *CurrentK;
-
- /// Header of the outermost loop iterating from 0..NumColumns.
- BasicBlock *ColumnLoopHeader = nullptr;
-
- /// Header of the second loop iterating from 0..NumRows.
- BasicBlock *RowLoopHeader = nullptr;
- /// Latch of the second loop iterating from 0..NumRows.
- BasicBlock *RowLoopLatch = nullptr;
- /// Header of the innermost loop iterating from 0..NumInner.
- BasicBlock *InnerLoopHeader = nullptr;
- /// Latch of the innermost loop iterating from 0..NumInner.
- BasicBlock *InnerLoopLatch = nullptr;
-
- TileInfo(unsigned NumRows, unsigned NumColumns, unsigned NumInner,
- unsigned TileSize)
- : NumRows(NumRows), NumColumns(NumColumns), NumInner(NumInner),
- TileSize(TileSize) {}
-
- /// Creates an IR loop nests for tiling of the form below. Returns the block
- /// for the inner loop body and sets {Column,Row,Inner}LoopHeader/Latch
- /// fields.
- ///
- /// for CurrentColumn = 0..NumColumns
- /// for CurrentRow = 0..NumRows
- /// for CurrentInner = 0..NumInner
- BasicBlock *CreateTiledLoops(BasicBlock *Start, BasicBlock *End,
- IRBuilderBase &B, DomTreeUpdater &DTU,
- LoopInfo &LI);
-
-private:
- /// Creates a new loop with header, body and latch blocks that iterates from
- /// [0, Bound). Updates \p Preheader to branch to the new header and uses \p
- /// Exit as exit block. Adds the new loop blocks to \L and applies dominator
- /// tree updates to \p DTU.
- static BasicBlock *CreateLoop(BasicBlock *Preheader, BasicBlock *Exit,
- Value *Bound, Value *Step, StringRef Name,
- IRBuilderBase &B, DomTreeUpdater &DTU, Loop *L,
- LoopInfo &LI);
-};
-} // namespace llvm
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- MatrixUtils.h - Utilities to lower matrix intrinsics -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities for generating tiled loops for matrix operations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_MATRIXUTILS_H
+#define LLVM_TRANSFORMS_UTILS_MATRIXUTILS_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+class DomTreeUpdater;
+class BasicBlock;
+class Value;
+class Loop;
+class LoopInfo;
+class IRBuilderBase;
+
+/// A helper struct to create IR loop nests for tiling in IR of the following
+/// form:
+/// for CurrentColumn = 0..NumColumns
+/// for CurrentRow = 0..NumRows
+/// for CurrentInner = 0..NumInner
+struct TileInfo {
+ /// Number of rows of the matrix.
+ unsigned NumRows;
+
+ /// Number of columns of the matrix.
+ unsigned NumColumns;
+
+ /// Number of columns of the first matrix of a multiply /
+ /// number of rows of the second matrix of a multiply.
+ unsigned NumInner;
+
+ /// Number of rows/columns in a tile.
+ unsigned TileSize = -1;
+
+ /// Start row of the current tile to compute.
+ Value *CurrentRow;
+
+ /// Start column of the current tile to compute.
+ Value *CurrentCol;
+
+ /// Current tile offset during the tile computation.
+ Value *CurrentK;
+
+ /// Header of the outermost loop iterating from 0..NumColumns.
+ BasicBlock *ColumnLoopHeader = nullptr;
+
+ /// Header of the second loop iterating from 0..NumRows.
+ BasicBlock *RowLoopHeader = nullptr;
+ /// Latch of the second loop iterating from 0..NumRows.
+ BasicBlock *RowLoopLatch = nullptr;
+ /// Header of the innermost loop iterating from 0..NumInner.
+ BasicBlock *InnerLoopHeader = nullptr;
+ /// Latch of the innermost loop iterating from 0..NumInner.
+ BasicBlock *InnerLoopLatch = nullptr;
+
+ TileInfo(unsigned NumRows, unsigned NumColumns, unsigned NumInner,
+ unsigned TileSize)
+ : NumRows(NumRows), NumColumns(NumColumns), NumInner(NumInner),
+ TileSize(TileSize) {}
+
+ /// Creates an IR loop nests for tiling of the form below. Returns the block
+ /// for the inner loop body and sets {Column,Row,Inner}LoopHeader/Latch
+ /// fields.
+ ///
+ /// for CurrentColumn = 0..NumColumns
+ /// for CurrentRow = 0..NumRows
+ /// for CurrentInner = 0..NumInner
+ BasicBlock *CreateTiledLoops(BasicBlock *Start, BasicBlock *End,
+ IRBuilderBase &B, DomTreeUpdater &DTU,
+ LoopInfo &LI);
+
+private:
+ /// Creates a new loop with header, body and latch blocks that iterates from
+ /// [0, Bound). Updates \p Preheader to branch to the new header and uses \p
+ /// Exit as exit block. Adds the new loop blocks to \L and applies dominator
+ /// tree updates to \p DTU.
+ static BasicBlock *CreateLoop(BasicBlock *Preheader, BasicBlock *Exit,
+ Value *Bound, Value *Step, StringRef Name,
+ IRBuilderBase &B, DomTreeUpdater &DTU, Loop *L,
+ LoopInfo &LI);
+};
+} // namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/MetaRenamer.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/MetaRenamer.h
index 1e90f7590f..f7aab0a1c5 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/MetaRenamer.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/MetaRenamer.h
@@ -1,37 +1,37 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- MetaRenamer.h - Rename everything with metasyntatic names ----------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass renames everything with metasyntatic names. The intent is to use
-// this pass after bugpoint reduction to conceal the nature of the original
-// program.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_METARENAMER_H
-#define LLVM_TRANSFORMS_UTILS_METARENAMER_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-struct MetaRenamerPass : PassInfoMixin<MetaRenamerPass> {
- PreservedAnalyses run(Module &, ModuleAnalysisManager &);
-};
-} // namespace llvm
-
-#endif // LLVM_TRANSFORMS_UTILS_METARENAMER_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- MetaRenamer.h - Rename everything with metasyntatic names ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass renames everything with metasyntatic names. The intent is to use
+// this pass after bugpoint reduction to conceal the nature of the original
+// program.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_METARENAMER_H
+#define LLVM_TRANSFORMS_UTILS_METARENAMER_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+struct MetaRenamerPass : PassInfoMixin<MetaRenamerPass> {
+ PreservedAnalyses run(Module &, ModuleAnalysisManager &);
+};
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_METARENAMER_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/PredicateInfo.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/PredicateInfo.h
index 628696ecb0..ced45bb3bd 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/PredicateInfo.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/PredicateInfo.h
@@ -77,13 +77,13 @@ class raw_ostream;
enum PredicateType { PT_Branch, PT_Assume, PT_Switch };
-/// Constraint for a predicate of the form "cmp Pred Op, OtherOp", where Op
-/// is the value the constraint applies to (the ssa.copy result).
-struct PredicateConstraint {
- CmpInst::Predicate Predicate;
- Value *OtherOp;
-};
-
+/// Constraint for a predicate of the form "cmp Pred Op, OtherOp", where Op
+/// is the value the constraint applies to (the ssa.copy result).
+struct PredicateConstraint {
+ CmpInst::Predicate Predicate;
+ Value *OtherOp;
+};
+
// Base class for all predicate information we provide.
// All of our predicate information has at least a comparison.
class PredicateBase : public ilist_node<PredicateBase> {
@@ -97,9 +97,9 @@ public:
// predicates, this is different to OriginalOp which refers to the initial
// operand.
Value *RenamedOp;
- // The condition associated with this predicate.
- Value *Condition;
-
+ // The condition associated with this predicate.
+ Value *Condition;
+
PredicateBase(const PredicateBase &) = delete;
PredicateBase &operator=(const PredicateBase &) = delete;
PredicateBase() = delete;
@@ -109,22 +109,22 @@ public:
PB->Type == PT_Switch;
}
- /// Fetch condition in the form of PredicateConstraint, if possible.
- Optional<PredicateConstraint> getConstraint() const;
-
+ /// Fetch condition in the form of PredicateConstraint, if possible.
+ Optional<PredicateConstraint> getConstraint() const;
+
protected:
- PredicateBase(PredicateType PT, Value *Op, Value *Condition)
- : Type(PT), OriginalOp(Op), Condition(Condition) {}
+ PredicateBase(PredicateType PT, Value *Op, Value *Condition)
+ : Type(PT), OriginalOp(Op), Condition(Condition) {}
};
// Provides predicate information for assumes. Since assumes are always true,
// we simply provide the assume instruction, so you can tell your relative
// position to it.
-class PredicateAssume : public PredicateBase {
+class PredicateAssume : public PredicateBase {
public:
IntrinsicInst *AssumeInst;
PredicateAssume(Value *Op, IntrinsicInst *AssumeInst, Value *Condition)
- : PredicateBase(PT_Assume, Op, Condition), AssumeInst(AssumeInst) {}
+ : PredicateBase(PT_Assume, Op, Condition), AssumeInst(AssumeInst) {}
PredicateAssume() = delete;
static bool classof(const PredicateBase *PB) {
return PB->Type == PT_Assume;
@@ -134,7 +134,7 @@ public:
// Mixin class for edge predicates. The FROM block is the block where the
// predicate originates, and the TO block is the block where the predicate is
// valid.
-class PredicateWithEdge : public PredicateBase {
+class PredicateWithEdge : public PredicateBase {
public:
BasicBlock *From;
BasicBlock *To;
@@ -146,7 +146,7 @@ public:
protected:
PredicateWithEdge(PredicateType PType, Value *Op, BasicBlock *From,
BasicBlock *To, Value *Cond)
- : PredicateBase(PType, Op, Cond), From(From), To(To) {}
+ : PredicateBase(PType, Op, Cond), From(From), To(To) {}
};
// Provides predicate information for branches.
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
index d1f41d91a0..02e8cf94ba 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
@@ -33,488 +33,488 @@
#include "llvm/Support/CommandLine.h"
namespace llvm {
-extern cl::opt<unsigned> SCEVCheapExpansionBudget;
-
-/// Return true if the given expression is safe to expand in the sense that
-/// all materialized values are safe to speculate anywhere their operands are
-/// defined.
-bool isSafeToExpand(const SCEV *S, ScalarEvolution &SE);
-
-/// Return true if the given expression is safe to expand in the sense that
-/// all materialized values are defined and safe to speculate at the specified
-/// location and their operands are defined at this location.
-bool isSafeToExpandAt(const SCEV *S, const Instruction *InsertionPoint,
- ScalarEvolution &SE);
-
-/// struct for holding enough information to help calculate the cost of the
-/// given SCEV when expanded into IR.
-struct SCEVOperand {
- explicit SCEVOperand(unsigned Opc, int Idx, const SCEV *S) :
- ParentOpcode(Opc), OperandIdx(Idx), S(S) { }
- /// LLVM instruction opcode that uses the operand.
- unsigned ParentOpcode;
- /// The use index of an expanded instruction.
- int OperandIdx;
- /// The SCEV operand to be costed.
- const SCEV* S;
-};
-
-/// This class uses information about analyze scalars to rewrite expressions
-/// in canonical form.
-///
-/// Clients should create an instance of this class when rewriting is needed,
-/// and destroy it when finished to allow the release of the associated
-/// memory.
-class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> {
- ScalarEvolution &SE;
- const DataLayout &DL;
-
- // New instructions receive a name to identify them with the current pass.
- const char *IVName;
-
- /// Indicates whether LCSSA phis should be created for inserted values.
- bool PreserveLCSSA;
-
- // InsertedExpressions caches Values for reuse, so must track RAUW.
- DenseMap<std::pair<const SCEV *, Instruction *>, TrackingVH<Value>>
- InsertedExpressions;
-
- // InsertedValues only flags inserted instructions so needs no RAUW.
- DenseSet<AssertingVH<Value>> InsertedValues;
- DenseSet<AssertingVH<Value>> InsertedPostIncValues;
-
- /// Keep track of the existing IR values re-used during expansion.
- /// FIXME: Ideally re-used instructions would not be added to
- /// InsertedValues/InsertedPostIncValues.
- SmallPtrSet<Value *, 16> ReusedValues;
-
- /// A memoization of the "relevant" loop for a given SCEV.
- DenseMap<const SCEV *, const Loop *> RelevantLoops;
-
- /// Addrecs referring to any of the given loops are expanded in post-inc
- /// mode. For example, expanding {1,+,1}<L> in post-inc mode returns the add
- /// instruction that adds one to the phi for {0,+,1}<L>, as opposed to a new
- /// phi starting at 1. This is only supported in non-canonical mode.
- PostIncLoopSet PostIncLoops;
-
- /// When this is non-null, addrecs expanded in the loop it indicates should
- /// be inserted with increments at IVIncInsertPos.
- const Loop *IVIncInsertLoop;
-
- /// When expanding addrecs in the IVIncInsertLoop loop, insert the IV
- /// increment at this position.
- Instruction *IVIncInsertPos;
-
- /// Phis that complete an IV chain. Reuse
- DenseSet<AssertingVH<PHINode>> ChainedPhis;
-
- /// When true, SCEVExpander tries to expand expressions in "canonical" form.
- /// When false, expressions are expanded in a more literal form.
- ///
- /// In "canonical" form addrecs are expanded as arithmetic based on a
- /// canonical induction variable. Note that CanonicalMode doesn't guarantee
- /// that all expressions are expanded in "canonical" form. For some
- /// expressions literal mode can be preferred.
- bool CanonicalMode;
-
- /// When invoked from LSR, the expander is in "strength reduction" mode. The
- /// only difference is that phi's are only reused if they are already in
- /// "expanded" form.
- bool LSRMode;
-
- typedef IRBuilder<TargetFolder, IRBuilderCallbackInserter> BuilderType;
- BuilderType Builder;
-
- // RAII object that stores the current insertion point and restores it when
- // the object is destroyed. This includes the debug location. Duplicated
- // from InsertPointGuard to add SetInsertPoint() which is used to updated
- // InsertPointGuards stack when insert points are moved during SCEV
- // expansion.
- class SCEVInsertPointGuard {
- IRBuilderBase &Builder;
- AssertingVH<BasicBlock> Block;
- BasicBlock::iterator Point;
- DebugLoc DbgLoc;
- SCEVExpander *SE;
-
- SCEVInsertPointGuard(const SCEVInsertPointGuard &) = delete;
- SCEVInsertPointGuard &operator=(const SCEVInsertPointGuard &) = delete;
-
- public:
- SCEVInsertPointGuard(IRBuilderBase &B, SCEVExpander *SE)
- : Builder(B), Block(B.GetInsertBlock()), Point(B.GetInsertPoint()),
- DbgLoc(B.getCurrentDebugLocation()), SE(SE) {
- SE->InsertPointGuards.push_back(this);
- }
-
- ~SCEVInsertPointGuard() {
- // These guards should always created/destroyed in FIFO order since they
- // are used to guard lexically scoped blocks of code in
- // ScalarEvolutionExpander.
- assert(SE->InsertPointGuards.back() == this);
- SE->InsertPointGuards.pop_back();
- Builder.restoreIP(IRBuilderBase::InsertPoint(Block, Point));
- Builder.SetCurrentDebugLocation(DbgLoc);
- }
-
- BasicBlock::iterator GetInsertPoint() const { return Point; }
- void SetInsertPoint(BasicBlock::iterator I) { Point = I; }
- };
-
- /// Stack of pointers to saved insert points, used to keep insert points
- /// consistent when instructions are moved.
- SmallVector<SCEVInsertPointGuard *, 8> InsertPointGuards;
-
+extern cl::opt<unsigned> SCEVCheapExpansionBudget;
+
+/// Return true if the given expression is safe to expand in the sense that
+/// all materialized values are safe to speculate anywhere their operands are
+/// defined.
+bool isSafeToExpand(const SCEV *S, ScalarEvolution &SE);
+
+/// Return true if the given expression is safe to expand in the sense that
+/// all materialized values are defined and safe to speculate at the specified
+/// location and their operands are defined at this location.
+bool isSafeToExpandAt(const SCEV *S, const Instruction *InsertionPoint,
+ ScalarEvolution &SE);
+
+/// struct for holding enough information to help calculate the cost of the
+/// given SCEV when expanded into IR.
+struct SCEVOperand {
+ explicit SCEVOperand(unsigned Opc, int Idx, const SCEV *S) :
+ ParentOpcode(Opc), OperandIdx(Idx), S(S) { }
+ /// LLVM instruction opcode that uses the operand.
+ unsigned ParentOpcode;
+ /// The use index of an expanded instruction.
+ int OperandIdx;
+ /// The SCEV operand to be costed.
+ const SCEV* S;
+};
+
+/// This class uses information about analyze scalars to rewrite expressions
+/// in canonical form.
+///
+/// Clients should create an instance of this class when rewriting is needed,
+/// and destroy it when finished to allow the release of the associated
+/// memory.
+class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> {
+ ScalarEvolution &SE;
+ const DataLayout &DL;
+
+ // New instructions receive a name to identify them with the current pass.
+ const char *IVName;
+
+ /// Indicates whether LCSSA phis should be created for inserted values.
+ bool PreserveLCSSA;
+
+ // InsertedExpressions caches Values for reuse, so must track RAUW.
+ DenseMap<std::pair<const SCEV *, Instruction *>, TrackingVH<Value>>
+ InsertedExpressions;
+
+ // InsertedValues only flags inserted instructions so needs no RAUW.
+ DenseSet<AssertingVH<Value>> InsertedValues;
+ DenseSet<AssertingVH<Value>> InsertedPostIncValues;
+
+ /// Keep track of the existing IR values re-used during expansion.
+ /// FIXME: Ideally re-used instructions would not be added to
+ /// InsertedValues/InsertedPostIncValues.
+ SmallPtrSet<Value *, 16> ReusedValues;
+
+ /// A memoization of the "relevant" loop for a given SCEV.
+ DenseMap<const SCEV *, const Loop *> RelevantLoops;
+
+ /// Addrecs referring to any of the given loops are expanded in post-inc
+ /// mode. For example, expanding {1,+,1}<L> in post-inc mode returns the add
+ /// instruction that adds one to the phi for {0,+,1}<L>, as opposed to a new
+ /// phi starting at 1. This is only supported in non-canonical mode.
+ PostIncLoopSet PostIncLoops;
+
+ /// When this is non-null, addrecs expanded in the loop it indicates should
+ /// be inserted with increments at IVIncInsertPos.
+ const Loop *IVIncInsertLoop;
+
+ /// When expanding addrecs in the IVIncInsertLoop loop, insert the IV
+ /// increment at this position.
+ Instruction *IVIncInsertPos;
+
+ /// Phis that complete an IV chain. Reuse
+ DenseSet<AssertingVH<PHINode>> ChainedPhis;
+
+ /// When true, SCEVExpander tries to expand expressions in "canonical" form.
+ /// When false, expressions are expanded in a more literal form.
+ ///
+ /// In "canonical" form addrecs are expanded as arithmetic based on a
+ /// canonical induction variable. Note that CanonicalMode doesn't guarantee
+ /// that all expressions are expanded in "canonical" form. For some
+ /// expressions literal mode can be preferred.
+ bool CanonicalMode;
+
+ /// When invoked from LSR, the expander is in "strength reduction" mode. The
+ /// only difference is that phi's are only reused if they are already in
+ /// "expanded" form.
+ bool LSRMode;
+
+ typedef IRBuilder<TargetFolder, IRBuilderCallbackInserter> BuilderType;
+ BuilderType Builder;
+
+ // RAII object that stores the current insertion point and restores it when
+ // the object is destroyed. This includes the debug location. Duplicated
+ // from InsertPointGuard to add SetInsertPoint() which is used to updated
+ // InsertPointGuards stack when insert points are moved during SCEV
+ // expansion.
+ class SCEVInsertPointGuard {
+ IRBuilderBase &Builder;
+ AssertingVH<BasicBlock> Block;
+ BasicBlock::iterator Point;
+ DebugLoc DbgLoc;
+ SCEVExpander *SE;
+
+ SCEVInsertPointGuard(const SCEVInsertPointGuard &) = delete;
+ SCEVInsertPointGuard &operator=(const SCEVInsertPointGuard &) = delete;
+
+ public:
+ SCEVInsertPointGuard(IRBuilderBase &B, SCEVExpander *SE)
+ : Builder(B), Block(B.GetInsertBlock()), Point(B.GetInsertPoint()),
+ DbgLoc(B.getCurrentDebugLocation()), SE(SE) {
+ SE->InsertPointGuards.push_back(this);
+ }
+
+ ~SCEVInsertPointGuard() {
+ // These guards should always created/destroyed in FIFO order since they
+ // are used to guard lexically scoped blocks of code in
+ // ScalarEvolutionExpander.
+ assert(SE->InsertPointGuards.back() == this);
+ SE->InsertPointGuards.pop_back();
+ Builder.restoreIP(IRBuilderBase::InsertPoint(Block, Point));
+ Builder.SetCurrentDebugLocation(DbgLoc);
+ }
+
+ BasicBlock::iterator GetInsertPoint() const { return Point; }
+ void SetInsertPoint(BasicBlock::iterator I) { Point = I; }
+ };
+
+ /// Stack of pointers to saved insert points, used to keep insert points
+ /// consistent when instructions are moved.
+ SmallVector<SCEVInsertPointGuard *, 8> InsertPointGuards;
+
#ifndef NDEBUG
- const char *DebugType;
+ const char *DebugType;
#endif
- friend struct SCEVVisitor<SCEVExpander, Value *>;
-
-public:
- /// Construct a SCEVExpander in "canonical" mode.
- explicit SCEVExpander(ScalarEvolution &se, const DataLayout &DL,
- const char *name, bool PreserveLCSSA = true)
- : SE(se), DL(DL), IVName(name), PreserveLCSSA(PreserveLCSSA),
- IVIncInsertLoop(nullptr), IVIncInsertPos(nullptr), CanonicalMode(true),
- LSRMode(false),
- Builder(se.getContext(), TargetFolder(DL),
- IRBuilderCallbackInserter(
- [this](Instruction *I) { rememberInstruction(I); })) {
+ friend struct SCEVVisitor<SCEVExpander, Value *>;
+
+public:
+ /// Construct a SCEVExpander in "canonical" mode.
+ explicit SCEVExpander(ScalarEvolution &se, const DataLayout &DL,
+ const char *name, bool PreserveLCSSA = true)
+ : SE(se), DL(DL), IVName(name), PreserveLCSSA(PreserveLCSSA),
+ IVIncInsertLoop(nullptr), IVIncInsertPos(nullptr), CanonicalMode(true),
+ LSRMode(false),
+ Builder(se.getContext(), TargetFolder(DL),
+ IRBuilderCallbackInserter(
+ [this](Instruction *I) { rememberInstruction(I); })) {
#ifndef NDEBUG
- DebugType = "";
+ DebugType = "";
#endif
- }
+ }
- ~SCEVExpander() {
- // Make sure the insert point guard stack is consistent.
- assert(InsertPointGuards.empty());
- }
+ ~SCEVExpander() {
+ // Make sure the insert point guard stack is consistent.
+ assert(InsertPointGuards.empty());
+ }
#ifndef NDEBUG
- void setDebugType(const char *s) { DebugType = s; }
+ void setDebugType(const char *s) { DebugType = s; }
#endif
- /// Erase the contents of the InsertedExpressions map so that users trying
- /// to expand the same expression into multiple BasicBlocks or different
- /// places within the same BasicBlock can do so.
- void clear() {
- InsertedExpressions.clear();
- InsertedValues.clear();
- InsertedPostIncValues.clear();
- ReusedValues.clear();
- ChainedPhis.clear();
- }
-
- /// Return a vector containing all instructions inserted during expansion.
- SmallVector<Instruction *, 32> getAllInsertedInstructions() const {
- SmallVector<Instruction *, 32> Result;
- for (auto &VH : InsertedValues) {
- Value *V = VH;
- if (ReusedValues.contains(V))
- continue;
- if (auto *Inst = dyn_cast<Instruction>(V))
- Result.push_back(Inst);
+ /// Erase the contents of the InsertedExpressions map so that users trying
+ /// to expand the same expression into multiple BasicBlocks or different
+ /// places within the same BasicBlock can do so.
+ void clear() {
+ InsertedExpressions.clear();
+ InsertedValues.clear();
+ InsertedPostIncValues.clear();
+ ReusedValues.clear();
+ ChainedPhis.clear();
+ }
+
+ /// Return a vector containing all instructions inserted during expansion.
+ SmallVector<Instruction *, 32> getAllInsertedInstructions() const {
+ SmallVector<Instruction *, 32> Result;
+ for (auto &VH : InsertedValues) {
+ Value *V = VH;
+ if (ReusedValues.contains(V))
+ continue;
+ if (auto *Inst = dyn_cast<Instruction>(V))
+ Result.push_back(Inst);
}
- for (auto &VH : InsertedPostIncValues) {
- Value *V = VH;
- if (ReusedValues.contains(V))
- continue;
- if (auto *Inst = dyn_cast<Instruction>(V))
- Result.push_back(Inst);
- }
-
- return Result;
- }
-
- /// Return true for expressions that can't be evaluated at runtime
- /// within given \b Budget.
- ///
- /// At is a parameter which specifies point in code where user is going to
- /// expand this expression. Sometimes this knowledge can lead to
- /// a less pessimistic cost estimation.
- bool isHighCostExpansion(const SCEV *Expr, Loop *L, unsigned Budget,
- const TargetTransformInfo *TTI,
- const Instruction *At) {
- assert(TTI && "This function requires TTI to be provided.");
- assert(At && "This function requires At instruction to be provided.");
- if (!TTI) // In assert-less builds, avoid crashing
- return true; // by always claiming to be high-cost.
- SmallVector<SCEVOperand, 8> Worklist;
- SmallPtrSet<const SCEV *, 8> Processed;
- int BudgetRemaining = Budget * TargetTransformInfo::TCC_Basic;
- Worklist.emplace_back(-1, -1, Expr);
- while (!Worklist.empty()) {
- const SCEVOperand WorkItem = Worklist.pop_back_val();
- if (isHighCostExpansionHelper(WorkItem, L, *At, BudgetRemaining,
- *TTI, Processed, Worklist))
- return true;
+ for (auto &VH : InsertedPostIncValues) {
+ Value *V = VH;
+ if (ReusedValues.contains(V))
+ continue;
+ if (auto *Inst = dyn_cast<Instruction>(V))
+ Result.push_back(Inst);
}
- assert(BudgetRemaining >= 0 && "Should have returned from inner loop.");
- return false;
- }
-
- /// Return the induction variable increment's IV operand.
- Instruction *getIVIncOperand(Instruction *IncV, Instruction *InsertPos,
- bool allowScale);
-
- /// Utility for hoisting an IV increment.
- bool hoistIVInc(Instruction *IncV, Instruction *InsertPos);
-
- /// replace congruent phis with their most canonical representative. Return
- /// the number of phis eliminated.
- unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT,
- SmallVectorImpl<WeakTrackingVH> &DeadInsts,
- const TargetTransformInfo *TTI = nullptr);
-
- /// Insert code to directly compute the specified SCEV expression into the
- /// program. The code is inserted into the specified block.
- Value *expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I) {
- return expandCodeForImpl(SH, Ty, I, true);
- }
-
- /// Insert code to directly compute the specified SCEV expression into the
- /// program. The code is inserted into the SCEVExpander's current
- /// insertion point. If a type is specified, the result will be expanded to
- /// have that type, with a cast if necessary.
- Value *expandCodeFor(const SCEV *SH, Type *Ty = nullptr) {
- return expandCodeForImpl(SH, Ty, true);
- }
-
- /// Generates a code sequence that evaluates this predicate. The inserted
- /// instructions will be at position \p Loc. The result will be of type i1
- /// and will have a value of 0 when the predicate is false and 1 otherwise.
- Value *expandCodeForPredicate(const SCEVPredicate *Pred, Instruction *Loc);
-
- /// A specialized variant of expandCodeForPredicate, handling the case when
- /// we are expanding code for a SCEVEqualPredicate.
- Value *expandEqualPredicate(const SCEVEqualPredicate *Pred, Instruction *Loc);
-
- /// Generates code that evaluates if the \p AR expression will overflow.
- Value *generateOverflowCheck(const SCEVAddRecExpr *AR, Instruction *Loc,
- bool Signed);
-
- /// A specialized variant of expandCodeForPredicate, handling the case when
- /// we are expanding code for a SCEVWrapPredicate.
- Value *expandWrapPredicate(const SCEVWrapPredicate *P, Instruction *Loc);
-
- /// A specialized variant of expandCodeForPredicate, handling the case when
- /// we are expanding code for a SCEVUnionPredicate.
- Value *expandUnionPredicate(const SCEVUnionPredicate *Pred, Instruction *Loc);
-
- /// Set the current IV increment loop and position.
- void setIVIncInsertPos(const Loop *L, Instruction *Pos) {
- assert(!CanonicalMode &&
- "IV increment positions are not supported in CanonicalMode");
- IVIncInsertLoop = L;
- IVIncInsertPos = Pos;
- }
-
- /// Enable post-inc expansion for addrecs referring to the given
- /// loops. Post-inc expansion is only supported in non-canonical mode.
- void setPostInc(const PostIncLoopSet &L) {
- assert(!CanonicalMode &&
- "Post-inc expansion is not supported in CanonicalMode");
- PostIncLoops = L;
- }
-
- /// Disable all post-inc expansion.
- void clearPostInc() {
- PostIncLoops.clear();
-
- // When we change the post-inc loop set, cached expansions may no
- // longer be valid.
- InsertedPostIncValues.clear();
- }
-
- /// Disable the behavior of expanding expressions in canonical form rather
- /// than in a more literal form. Non-canonical mode is useful for late
- /// optimization passes.
- void disableCanonicalMode() { CanonicalMode = false; }
-
- void enableLSRMode() { LSRMode = true; }
-
- /// Set the current insertion point. This is useful if multiple calls to
- /// expandCodeFor() are going to be made with the same insert point and the
- /// insert point may be moved during one of the expansions (e.g. if the
- /// insert point is not a block terminator).
- void setInsertPoint(Instruction *IP) {
- assert(IP);
- Builder.SetInsertPoint(IP);
- }
-
- /// Clear the current insertion point. This is useful if the instruction
- /// that had been serving as the insertion point may have been deleted.
- void clearInsertPoint() { Builder.ClearInsertionPoint(); }
-
- /// Set location information used by debugging information.
- void SetCurrentDebugLocation(DebugLoc L) {
- Builder.SetCurrentDebugLocation(std::move(L));
- }
-
- /// Get location information used by debugging information.
- DebugLoc getCurrentDebugLocation() const {
- return Builder.getCurrentDebugLocation();
- }
-
- /// Return true if the specified instruction was inserted by the code
- /// rewriter. If so, the client should not modify the instruction. Note that
- /// this also includes instructions re-used during expansion.
- bool isInsertedInstruction(Instruction *I) const {
- return InsertedValues.count(I) || InsertedPostIncValues.count(I);
- }
-
- void setChainedPhi(PHINode *PN) { ChainedPhis.insert(PN); }
-
- /// Try to find the ValueOffsetPair for S. The function is mainly used to
- /// check whether S can be expanded cheaply. If this returns a non-None
- /// value, we know we can codegen the `ValueOffsetPair` into a suitable
- /// expansion identical with S so that S can be expanded cheaply.
- ///
- /// L is a hint which tells in which loop to look for the suitable value.
- /// On success return value which is equivalent to the expanded S at point
- /// At. Return nullptr if value was not found.
- ///
- /// Note that this function does not perform an exhaustive search. I.e if it
- /// didn't find any value it does not mean that there is no such value.
- ///
- Optional<ScalarEvolution::ValueOffsetPair>
- getRelatedExistingExpansion(const SCEV *S, const Instruction *At, Loop *L);
-
- /// Returns a suitable insert point after \p I, that dominates \p
- /// MustDominate. Skips instructions inserted by the expander.
- BasicBlock::iterator findInsertPointAfter(Instruction *I,
- Instruction *MustDominate);
-
-private:
- LLVMContext &getContext() const { return SE.getContext(); }
-
- /// Insert code to directly compute the specified SCEV expression into the
- /// program. The code is inserted into the SCEVExpander's current
- /// insertion point. If a type is specified, the result will be expanded to
- /// have that type, with a cast if necessary. If \p Root is true, this
- /// indicates that \p SH is the top-level expression to expand passed from
- /// an external client call.
- Value *expandCodeForImpl(const SCEV *SH, Type *Ty, bool Root);
-
- /// Insert code to directly compute the specified SCEV expression into the
- /// program. The code is inserted into the specified block. If \p
- /// Root is true, this indicates that \p SH is the top-level expression to
- /// expand passed from an external client call.
- Value *expandCodeForImpl(const SCEV *SH, Type *Ty, Instruction *I, bool Root);
-
- /// Recursive helper function for isHighCostExpansion.
- bool isHighCostExpansionHelper(
- const SCEVOperand &WorkItem, Loop *L, const Instruction &At,
- int &BudgetRemaining, const TargetTransformInfo &TTI,
- SmallPtrSetImpl<const SCEV *> &Processed,
- SmallVectorImpl<SCEVOperand> &Worklist);
-
- /// Insert the specified binary operator, doing a small amount of work to
- /// avoid inserting an obviously redundant operation, and hoisting to an
- /// outer loop when the opportunity is there and it is safe.
- Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS,
- SCEV::NoWrapFlags Flags, bool IsSafeToHoist);
-
- /// 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 creating a new one.
- Value *ReuseOrCreateCast(Value *V, Type *Ty, Instruction::CastOps Op,
- BasicBlock::iterator IP);
-
- /// Insert a cast of V to the specified type, which must be possible with a
- /// noop cast, doing what we can to share the casts.
- Value *InsertNoopCastOfTo(Value *V, Type *Ty);
-
- /// Expand a SCEVAddExpr with a pointer type into a GEP instead of using
- /// ptrtoint+arithmetic+inttoptr.
- Value *expandAddToGEP(const SCEV *const *op_begin, const SCEV *const *op_end,
- PointerType *PTy, Type *Ty, Value *V);
- Value *expandAddToGEP(const SCEV *Op, PointerType *PTy, Type *Ty, Value *V);
-
- /// Find a previous Value in ExprValueMap for expand.
- ScalarEvolution::ValueOffsetPair
- FindValueInExprValueMap(const SCEV *S, const Instruction *InsertPt);
-
- Value *expand(const SCEV *S);
-
- /// Determine the most "relevant" loop for the given SCEV.
- const Loop *getRelevantLoop(const SCEV *);
-
- Value *visitConstant(const SCEVConstant *S) { return S->getValue(); }
-
- Value *visitPtrToIntExpr(const SCEVPtrToIntExpr *S);
-
- Value *visitTruncateExpr(const SCEVTruncateExpr *S);
-
- Value *visitZeroExtendExpr(const SCEVZeroExtendExpr *S);
-
- Value *visitSignExtendExpr(const SCEVSignExtendExpr *S);
-
- Value *visitAddExpr(const SCEVAddExpr *S);
-
- Value *visitMulExpr(const SCEVMulExpr *S);
-
- Value *visitUDivExpr(const SCEVUDivExpr *S);
-
- Value *visitAddRecExpr(const SCEVAddRecExpr *S);
-
- Value *visitSMaxExpr(const SCEVSMaxExpr *S);
-
- Value *visitUMaxExpr(const SCEVUMaxExpr *S);
-
- Value *visitSMinExpr(const SCEVSMinExpr *S);
-
- Value *visitUMinExpr(const SCEVUMinExpr *S);
-
- Value *visitUnknown(const SCEVUnknown *S) { return S->getValue(); }
-
- void rememberInstruction(Value *I);
-
- bool isNormalAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L);
-
- bool isExpandedAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L);
-
- Value *expandAddRecExprLiterally(const SCEVAddRecExpr *);
- PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
- const Loop *L, Type *ExpandTy, Type *IntTy,
- Type *&TruncTy, bool &InvertStep);
- Value *expandIVInc(PHINode *PN, Value *StepV, const Loop *L, Type *ExpandTy,
- Type *IntTy, bool useSubtract);
-
- void hoistBeforePos(DominatorTree *DT, Instruction *InstToHoist,
- Instruction *Pos, PHINode *LoopPhi);
-
- void fixupInsertPoints(Instruction *I);
-
- /// If required, create LCSSA PHIs for \p Users' operand \p OpIdx. If new
- /// LCSSA PHIs have been created, return the LCSSA PHI available at \p User.
- /// If no PHIs have been created, return the unchanged operand \p OpIdx.
- Value *fixupLCSSAFormFor(Instruction *User, unsigned OpIdx);
-};
-
-/// Helper to remove instructions inserted during SCEV expansion, unless they
-/// are marked as used.
-class SCEVExpanderCleaner {
- SCEVExpander &Expander;
-
- DominatorTree &DT;
-
- /// Indicates whether the result of the expansion is used. If false, the
- /// instructions added during expansion are removed.
- bool ResultUsed;
-
-public:
- SCEVExpanderCleaner(SCEVExpander &Expander, DominatorTree &DT)
- : Expander(Expander), DT(DT), ResultUsed(false) {}
-
- ~SCEVExpanderCleaner();
-
- /// Indicate that the result of the expansion is used.
- void markResultUsed() { ResultUsed = true; }
-};
-} // namespace llvm
-
+
+ return Result;
+ }
+
+ /// Return true for expressions that can't be evaluated at runtime
+ /// within given \b Budget.
+ ///
+ /// At is a parameter which specifies point in code where user is going to
+ /// expand this expression. Sometimes this knowledge can lead to
+ /// a less pessimistic cost estimation.
+ bool isHighCostExpansion(const SCEV *Expr, Loop *L, unsigned Budget,
+ const TargetTransformInfo *TTI,
+ const Instruction *At) {
+ assert(TTI && "This function requires TTI to be provided.");
+ assert(At && "This function requires At instruction to be provided.");
+ if (!TTI) // In assert-less builds, avoid crashing
+ return true; // by always claiming to be high-cost.
+ SmallVector<SCEVOperand, 8> Worklist;
+ SmallPtrSet<const SCEV *, 8> Processed;
+ int BudgetRemaining = Budget * TargetTransformInfo::TCC_Basic;
+ Worklist.emplace_back(-1, -1, Expr);
+ while (!Worklist.empty()) {
+ const SCEVOperand WorkItem = Worklist.pop_back_val();
+ if (isHighCostExpansionHelper(WorkItem, L, *At, BudgetRemaining,
+ *TTI, Processed, Worklist))
+ return true;
+ }
+ assert(BudgetRemaining >= 0 && "Should have returned from inner loop.");
+ return false;
+ }
+
+ /// Return the induction variable increment's IV operand.
+ Instruction *getIVIncOperand(Instruction *IncV, Instruction *InsertPos,
+ bool allowScale);
+
+ /// Utility for hoisting an IV increment.
+ bool hoistIVInc(Instruction *IncV, Instruction *InsertPos);
+
+ /// replace congruent phis with their most canonical representative. Return
+ /// the number of phis eliminated.
+ unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT,
+ SmallVectorImpl<WeakTrackingVH> &DeadInsts,
+ const TargetTransformInfo *TTI = nullptr);
+
+ /// Insert code to directly compute the specified SCEV expression into the
+ /// program. The code is inserted into the specified block.
+ Value *expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I) {
+ return expandCodeForImpl(SH, Ty, I, true);
+ }
+
+ /// Insert code to directly compute the specified SCEV expression into the
+ /// program. The code is inserted into the SCEVExpander's current
+ /// insertion point. If a type is specified, the result will be expanded to
+ /// have that type, with a cast if necessary.
+ Value *expandCodeFor(const SCEV *SH, Type *Ty = nullptr) {
+ return expandCodeForImpl(SH, Ty, true);
+ }
+
+ /// Generates a code sequence that evaluates this predicate. The inserted
+ /// instructions will be at position \p Loc. The result will be of type i1
+ /// and will have a value of 0 when the predicate is false and 1 otherwise.
+ Value *expandCodeForPredicate(const SCEVPredicate *Pred, Instruction *Loc);
+
+ /// A specialized variant of expandCodeForPredicate, handling the case when
+ /// we are expanding code for a SCEVEqualPredicate.
+ Value *expandEqualPredicate(const SCEVEqualPredicate *Pred, Instruction *Loc);
+
+ /// Generates code that evaluates if the \p AR expression will overflow.
+ Value *generateOverflowCheck(const SCEVAddRecExpr *AR, Instruction *Loc,
+ bool Signed);
+
+ /// A specialized variant of expandCodeForPredicate, handling the case when
+ /// we are expanding code for a SCEVWrapPredicate.
+ Value *expandWrapPredicate(const SCEVWrapPredicate *P, Instruction *Loc);
+
+ /// A specialized variant of expandCodeForPredicate, handling the case when
+ /// we are expanding code for a SCEVUnionPredicate.
+ Value *expandUnionPredicate(const SCEVUnionPredicate *Pred, Instruction *Loc);
+
+ /// Set the current IV increment loop and position.
+ void setIVIncInsertPos(const Loop *L, Instruction *Pos) {
+ assert(!CanonicalMode &&
+ "IV increment positions are not supported in CanonicalMode");
+ IVIncInsertLoop = L;
+ IVIncInsertPos = Pos;
+ }
+
+ /// Enable post-inc expansion for addrecs referring to the given
+ /// loops. Post-inc expansion is only supported in non-canonical mode.
+ void setPostInc(const PostIncLoopSet &L) {
+ assert(!CanonicalMode &&
+ "Post-inc expansion is not supported in CanonicalMode");
+ PostIncLoops = L;
+ }
+
+ /// Disable all post-inc expansion.
+ void clearPostInc() {
+ PostIncLoops.clear();
+
+ // When we change the post-inc loop set, cached expansions may no
+ // longer be valid.
+ InsertedPostIncValues.clear();
+ }
+
+ /// Disable the behavior of expanding expressions in canonical form rather
+ /// than in a more literal form. Non-canonical mode is useful for late
+ /// optimization passes.
+ void disableCanonicalMode() { CanonicalMode = false; }
+
+ void enableLSRMode() { LSRMode = true; }
+
+ /// Set the current insertion point. This is useful if multiple calls to
+ /// expandCodeFor() are going to be made with the same insert point and the
+ /// insert point may be moved during one of the expansions (e.g. if the
+ /// insert point is not a block terminator).
+ void setInsertPoint(Instruction *IP) {
+ assert(IP);
+ Builder.SetInsertPoint(IP);
+ }
+
+ /// Clear the current insertion point. This is useful if the instruction
+ /// that had been serving as the insertion point may have been deleted.
+ void clearInsertPoint() { Builder.ClearInsertionPoint(); }
+
+ /// Set location information used by debugging information.
+ void SetCurrentDebugLocation(DebugLoc L) {
+ Builder.SetCurrentDebugLocation(std::move(L));
+ }
+
+ /// Get location information used by debugging information.
+ DebugLoc getCurrentDebugLocation() const {
+ return Builder.getCurrentDebugLocation();
+ }
+
+ /// Return true if the specified instruction was inserted by the code
+ /// rewriter. If so, the client should not modify the instruction. Note that
+ /// this also includes instructions re-used during expansion.
+ bool isInsertedInstruction(Instruction *I) const {
+ return InsertedValues.count(I) || InsertedPostIncValues.count(I);
+ }
+
+ void setChainedPhi(PHINode *PN) { ChainedPhis.insert(PN); }
+
+ /// Try to find the ValueOffsetPair for S. The function is mainly used to
+ /// check whether S can be expanded cheaply. If this returns a non-None
+ /// value, we know we can codegen the `ValueOffsetPair` into a suitable
+ /// expansion identical with S so that S can be expanded cheaply.
+ ///
+ /// L is a hint which tells in which loop to look for the suitable value.
+ /// On success return value which is equivalent to the expanded S at point
+ /// At. Return nullptr if value was not found.
+ ///
+ /// Note that this function does not perform an exhaustive search. I.e if it
+ /// didn't find any value it does not mean that there is no such value.
+ ///
+ Optional<ScalarEvolution::ValueOffsetPair>
+ getRelatedExistingExpansion(const SCEV *S, const Instruction *At, Loop *L);
+
+ /// Returns a suitable insert point after \p I, that dominates \p
+ /// MustDominate. Skips instructions inserted by the expander.
+ BasicBlock::iterator findInsertPointAfter(Instruction *I,
+ Instruction *MustDominate);
+
+private:
+ LLVMContext &getContext() const { return SE.getContext(); }
+
+ /// Insert code to directly compute the specified SCEV expression into the
+ /// program. The code is inserted into the SCEVExpander's current
+ /// insertion point. If a type is specified, the result will be expanded to
+ /// have that type, with a cast if necessary. If \p Root is true, this
+ /// indicates that \p SH is the top-level expression to expand passed from
+ /// an external client call.
+ Value *expandCodeForImpl(const SCEV *SH, Type *Ty, bool Root);
+
+ /// Insert code to directly compute the specified SCEV expression into the
+ /// program. The code is inserted into the specified block. If \p
+ /// Root is true, this indicates that \p SH is the top-level expression to
+ /// expand passed from an external client call.
+ Value *expandCodeForImpl(const SCEV *SH, Type *Ty, Instruction *I, bool Root);
+
+ /// Recursive helper function for isHighCostExpansion.
+ bool isHighCostExpansionHelper(
+ const SCEVOperand &WorkItem, Loop *L, const Instruction &At,
+ int &BudgetRemaining, const TargetTransformInfo &TTI,
+ SmallPtrSetImpl<const SCEV *> &Processed,
+ SmallVectorImpl<SCEVOperand> &Worklist);
+
+ /// Insert the specified binary operator, doing a small amount of work to
+ /// avoid inserting an obviously redundant operation, and hoisting to an
+ /// outer loop when the opportunity is there and it is safe.
+ Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS,
+ SCEV::NoWrapFlags Flags, bool IsSafeToHoist);
+
+ /// 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 creating a new one.
+ Value *ReuseOrCreateCast(Value *V, Type *Ty, Instruction::CastOps Op,
+ BasicBlock::iterator IP);
+
+ /// Insert a cast of V to the specified type, which must be possible with a
+ /// noop cast, doing what we can to share the casts.
+ Value *InsertNoopCastOfTo(Value *V, Type *Ty);
+
+ /// Expand a SCEVAddExpr with a pointer type into a GEP instead of using
+ /// ptrtoint+arithmetic+inttoptr.
+ Value *expandAddToGEP(const SCEV *const *op_begin, const SCEV *const *op_end,
+ PointerType *PTy, Type *Ty, Value *V);
+ Value *expandAddToGEP(const SCEV *Op, PointerType *PTy, Type *Ty, Value *V);
+
+ /// Find a previous Value in ExprValueMap for expand.
+ ScalarEvolution::ValueOffsetPair
+ FindValueInExprValueMap(const SCEV *S, const Instruction *InsertPt);
+
+ Value *expand(const SCEV *S);
+
+ /// Determine the most "relevant" loop for the given SCEV.
+ const Loop *getRelevantLoop(const SCEV *);
+
+ Value *visitConstant(const SCEVConstant *S) { return S->getValue(); }
+
+ Value *visitPtrToIntExpr(const SCEVPtrToIntExpr *S);
+
+ Value *visitTruncateExpr(const SCEVTruncateExpr *S);
+
+ Value *visitZeroExtendExpr(const SCEVZeroExtendExpr *S);
+
+ Value *visitSignExtendExpr(const SCEVSignExtendExpr *S);
+
+ Value *visitAddExpr(const SCEVAddExpr *S);
+
+ Value *visitMulExpr(const SCEVMulExpr *S);
+
+ Value *visitUDivExpr(const SCEVUDivExpr *S);
+
+ Value *visitAddRecExpr(const SCEVAddRecExpr *S);
+
+ Value *visitSMaxExpr(const SCEVSMaxExpr *S);
+
+ Value *visitUMaxExpr(const SCEVUMaxExpr *S);
+
+ Value *visitSMinExpr(const SCEVSMinExpr *S);
+
+ Value *visitUMinExpr(const SCEVUMinExpr *S);
+
+ Value *visitUnknown(const SCEVUnknown *S) { return S->getValue(); }
+
+ void rememberInstruction(Value *I);
+
+ bool isNormalAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L);
+
+ bool isExpandedAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L);
+
+ Value *expandAddRecExprLiterally(const SCEVAddRecExpr *);
+ PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
+ const Loop *L, Type *ExpandTy, Type *IntTy,
+ Type *&TruncTy, bool &InvertStep);
+ Value *expandIVInc(PHINode *PN, Value *StepV, const Loop *L, Type *ExpandTy,
+ Type *IntTy, bool useSubtract);
+
+ void hoistBeforePos(DominatorTree *DT, Instruction *InstToHoist,
+ Instruction *Pos, PHINode *LoopPhi);
+
+ void fixupInsertPoints(Instruction *I);
+
+ /// If required, create LCSSA PHIs for \p Users' operand \p OpIdx. If new
+ /// LCSSA PHIs have been created, return the LCSSA PHI available at \p User.
+ /// If no PHIs have been created, return the unchanged operand \p OpIdx.
+ Value *fixupLCSSAFormFor(Instruction *User, unsigned OpIdx);
+};
+
+/// Helper to remove instructions inserted during SCEV expansion, unless they
+/// are marked as used.
+class SCEVExpanderCleaner {
+ SCEVExpander &Expander;
+
+ DominatorTree &DT;
+
+ /// Indicates whether the result of the expansion is used. If false, the
+ /// instructions added during expansion are removed.
+ bool ResultUsed;
+
+public:
+ SCEVExpanderCleaner(SCEVExpander &Expander, DominatorTree &DT)
+ : Expander(Expander), DT(DT), ResultUsed(false) {}
+
+ ~SCEVExpanderCleaner();
+
+ /// Indicate that the result of the expansion is used.
+ void markResultUsed() { ResultUsed = true; }
+};
+} // namespace llvm
+
#endif
#ifdef __GNUC__
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/SimplifyCFGOptions.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/SimplifyCFGOptions.h
index df04cc9255..37ace5188d 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/SimplifyCFGOptions.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/SimplifyCFGOptions.h
@@ -1,88 +1,88 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- SimplifyCFGOptions.h - Control structure for SimplifyCFG -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// A set of parameters used to control the transforms in the SimplifyCFG pass.
-// Options may change depending on the position in the optimization pipeline.
-// For example, canonical form that includes switches and branches may later be
-// replaced by lookup tables and selects.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYCFGOPTIONS_H
-#define LLVM_TRANSFORMS_UTILS_SIMPLIFYCFGOPTIONS_H
-
-namespace llvm {
-
-class AssumptionCache;
-
-struct SimplifyCFGOptions {
- int BonusInstThreshold = 1;
- bool ForwardSwitchCondToPhi = false;
- bool ConvertSwitchToLookupTable = false;
- bool NeedCanonicalLoop = true;
- bool HoistCommonInsts = false;
- bool SinkCommonInsts = false;
- bool SimplifyCondBranch = true;
- bool FoldTwoEntryPHINode = true;
-
- AssumptionCache *AC = nullptr;
-
- // Support 'builder' pattern to set members by name at construction time.
- SimplifyCFGOptions &bonusInstThreshold(int I) {
- BonusInstThreshold = I;
- return *this;
- }
- SimplifyCFGOptions &forwardSwitchCondToPhi(bool B) {
- ForwardSwitchCondToPhi = B;
- return *this;
- }
- SimplifyCFGOptions &convertSwitchToLookupTable(bool B) {
- ConvertSwitchToLookupTable = B;
- return *this;
- }
- SimplifyCFGOptions &needCanonicalLoops(bool B) {
- NeedCanonicalLoop = B;
- return *this;
- }
- SimplifyCFGOptions &hoistCommonInsts(bool B) {
- HoistCommonInsts = B;
- return *this;
- }
- SimplifyCFGOptions &sinkCommonInsts(bool B) {
- SinkCommonInsts = B;
- return *this;
- }
- SimplifyCFGOptions &setAssumptionCache(AssumptionCache *Cache) {
- AC = Cache;
- return *this;
- }
- SimplifyCFGOptions &setSimplifyCondBranch(bool B) {
- SimplifyCondBranch = B;
- return *this;
- }
-
- SimplifyCFGOptions &setFoldTwoEntryPHINode(bool B) {
- FoldTwoEntryPHINode = B;
- return *this;
- }
-};
-
-} // namespace llvm
-
-#endif // LLVM_TRANSFORMS_UTILS_SIMPLIFYCFGOPTIONS_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- SimplifyCFGOptions.h - Control structure for SimplifyCFG -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// A set of parameters used to control the transforms in the SimplifyCFG pass.
+// Options may change depending on the position in the optimization pipeline.
+// For example, canonical form that includes switches and branches may later be
+// replaced by lookup tables and selects.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYCFGOPTIONS_H
+#define LLVM_TRANSFORMS_UTILS_SIMPLIFYCFGOPTIONS_H
+
+namespace llvm {
+
+class AssumptionCache;
+
+struct SimplifyCFGOptions {
+ int BonusInstThreshold = 1;
+ bool ForwardSwitchCondToPhi = false;
+ bool ConvertSwitchToLookupTable = false;
+ bool NeedCanonicalLoop = true;
+ bool HoistCommonInsts = false;
+ bool SinkCommonInsts = false;
+ bool SimplifyCondBranch = true;
+ bool FoldTwoEntryPHINode = true;
+
+ AssumptionCache *AC = nullptr;
+
+ // Support 'builder' pattern to set members by name at construction time.
+ SimplifyCFGOptions &bonusInstThreshold(int I) {
+ BonusInstThreshold = I;
+ return *this;
+ }
+ SimplifyCFGOptions &forwardSwitchCondToPhi(bool B) {
+ ForwardSwitchCondToPhi = B;
+ return *this;
+ }
+ SimplifyCFGOptions &convertSwitchToLookupTable(bool B) {
+ ConvertSwitchToLookupTable = B;
+ return *this;
+ }
+ SimplifyCFGOptions &needCanonicalLoops(bool B) {
+ NeedCanonicalLoop = B;
+ return *this;
+ }
+ SimplifyCFGOptions &hoistCommonInsts(bool B) {
+ HoistCommonInsts = B;
+ return *this;
+ }
+ SimplifyCFGOptions &sinkCommonInsts(bool B) {
+ SinkCommonInsts = B;
+ return *this;
+ }
+ SimplifyCFGOptions &setAssumptionCache(AssumptionCache *Cache) {
+ AC = Cache;
+ return *this;
+ }
+ SimplifyCFGOptions &setSimplifyCondBranch(bool B) {
+ SimplifyCondBranch = B;
+ return *this;
+ }
+
+ SimplifyCFGOptions &setFoldTwoEntryPHINode(bool B) {
+ FoldTwoEntryPHINode = B;
+ return *this;
+ }
+};
+
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_SIMPLIFYCFGOPTIONS_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/SimplifyIndVar.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/SimplifyIndVar.h
index 4430fcba51..375bf2963a 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/SimplifyIndVar.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/SimplifyIndVar.h
@@ -22,8 +22,8 @@
#ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYINDVAR_H
#define LLVM_TRANSFORMS_UTILS_SIMPLIFYINDVAR_H
-#include "llvm/Analysis/ScalarEvolutionExpressions.h"
-#include "llvm/IR/ConstantRange.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/ValueHandle.h"
namespace llvm {
@@ -66,27 +66,27 @@ bool simplifyLoopIVs(Loop *L, ScalarEvolution *SE, DominatorTree *DT,
LoopInfo *LI, const TargetTransformInfo *TTI,
SmallVectorImpl<WeakTrackingVH> &Dead);
-/// Collect information about induction variables that are used by sign/zero
-/// extend operations. This information is recorded by CollectExtend and provides
-/// the input to WidenIV.
-struct WideIVInfo {
- PHINode *NarrowIV = nullptr;
-
- // Widest integer type created [sz]ext
- Type *WidestNativeType = nullptr;
-
- // Was a sext user seen before a zext?
- bool IsSigned = false;
-};
-
-/// Widen Induction Variables - Extend the width of an IV to cover its
-/// widest uses.
-PHINode *createWideIV(const WideIVInfo &WI,
- LoopInfo *LI, ScalarEvolution *SE, SCEVExpander &Rewriter,
- DominatorTree *DT, SmallVectorImpl<WeakTrackingVH> &DeadInsts,
- unsigned &NumElimExt, unsigned &NumWidened,
- bool HasGuards, bool UsePostIncrementRanges);
-
+/// Collect information about induction variables that are used by sign/zero
+/// extend operations. This information is recorded by CollectExtend and provides
+/// the input to WidenIV.
+struct WideIVInfo {
+ PHINode *NarrowIV = nullptr;
+
+ // Widest integer type created [sz]ext
+ Type *WidestNativeType = nullptr;
+
+ // Was a sext user seen before a zext?
+ bool IsSigned = false;
+};
+
+/// Widen Induction Variables - Extend the width of an IV to cover its
+/// widest uses.
+PHINode *createWideIV(const WideIVInfo &WI,
+ LoopInfo *LI, ScalarEvolution *SE, SCEVExpander &Rewriter,
+ DominatorTree *DT, SmallVectorImpl<WeakTrackingVH> &DeadInsts,
+ unsigned &NumElimExt, unsigned &NumWidened,
+ bool HasGuards, bool UsePostIncrementRanges);
+
} // end namespace llvm
#endif // LLVM_TRANSFORMS_UTILS_SIMPLIFYINDVAR_H
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/SimplifyLibCalls.h
index 3d012f6277..29e2eb9b3d 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/SimplifyLibCalls.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -66,7 +66,7 @@ private:
Value *optimizeStrpCpyChk(CallInst *CI, IRBuilderBase &B, LibFunc Func);
Value *optimizeStrpNCpyChk(CallInst *CI, IRBuilderBase &B, LibFunc Func);
Value *optimizeStrLenChk(CallInst *CI, IRBuilderBase &B);
- Value *optimizeMemPCpyChk(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeMemPCpyChk(CallInst *CI, IRBuilderBase &B);
Value *optimizeMemCCpyChk(CallInst *CI, IRBuilderBase &B);
Value *optimizeSNPrintfChk(CallInst *CI, IRBuilderBase &B);
Value *optimizeSPrintfChk(CallInst *CI,IRBuilderBase &B);
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/StripGCRelocates.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/StripGCRelocates.h
index e977ff1eb4..ab438af771 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/StripGCRelocates.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/StripGCRelocates.h
@@ -1,36 +1,36 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- StripGCRelocates.h - -----------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_STRIPGCRELOCATES_H
-#define LLVM_TRANSFORMS_UTILS_STRIPGCRELOCATES_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-
-class Function;
-
-class StripGCRelocates : public PassInfoMixin<StripGCRelocates> {
-public:
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_UTILS_STRIPGCRELOCATES_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- StripGCRelocates.h - -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_STRIPGCRELOCATES_H
+#define LLVM_TRANSFORMS_UTILS_STRIPGCRELOCATES_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Function;
+
+class StripGCRelocates : public PassInfoMixin<StripGCRelocates> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_STRIPGCRELOCATES_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/StripNonLineTableDebugInfo.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/StripNonLineTableDebugInfo.h
index 91d1d57e53..bd010e3803 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/StripNonLineTableDebugInfo.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/StripNonLineTableDebugInfo.h
@@ -1,37 +1,37 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- StripNonLineTableDebugInfo.h - -------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_STRIPNONLINETABLEDEBUGINFO_H
-#define LLVM_TRANSFORMS_UTILS_STRIPNONLINETABLEDEBUGINFO_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-
-class Module;
-
-class StripNonLineTableDebugInfoPass
- : public PassInfoMixin<StripNonLineTableDebugInfoPass> {
-public:
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-};
-
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_UTILS_STRIPNONLINETABLEDEBUGINFO_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- StripNonLineTableDebugInfo.h - -------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_STRIPNONLINETABLEDEBUGINFO_H
+#define LLVM_TRANSFORMS_UTILS_STRIPNONLINETABLEDEBUGINFO_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Module;
+
+class StripNonLineTableDebugInfoPass
+ : public PassInfoMixin<StripNonLineTableDebugInfoPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_STRIPNONLINETABLEDEBUGINFO_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
index d836f64cc0..dcb046c476 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
@@ -14,24 +14,24 @@
//===----------------------------------------------------------------------===//
//
// This pass is used to ensure that functions have at most one return and one
-// unreachable instruction in them.
+// unreachable instruction in them.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_UTILS_UNIFYFUNCTIONEXITNODES_H
#define LLVM_TRANSFORMS_UTILS_UNIFYFUNCTIONEXITNODES_H
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
namespace llvm {
class BasicBlock;
-class UnifyFunctionExitNodesLegacyPass : public FunctionPass {
+class UnifyFunctionExitNodesLegacyPass : public FunctionPass {
public:
static char ID; // Pass identification, replacement for typeid
- UnifyFunctionExitNodesLegacyPass();
+ UnifyFunctionExitNodesLegacyPass();
// We can preserve non-critical-edgeness when we unify function exit nodes
void getAnalysisUsage(AnalysisUsage &AU) const override;
@@ -41,12 +41,12 @@ public:
Pass *createUnifyFunctionExitNodesPass();
-class UnifyFunctionExitNodesPass
- : public PassInfoMixin<UnifyFunctionExitNodesPass> {
-public:
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-
+class UnifyFunctionExitNodesPass
+ : public PassInfoMixin<UnifyFunctionExitNodesPass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
} // end namespace llvm
#endif // LLVM_TRANSFORMS_UTILS_UNIFYFUNCTIONEXITNODES_H
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Utils/UnifyLoopExits.h b/contrib/libs/llvm12/include/llvm/Transforms/Utils/UnifyLoopExits.h
index 642da24966..ef6ef6f92b 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Utils/UnifyLoopExits.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Utils/UnifyLoopExits.h
@@ -1,33 +1,33 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- UnifyLoopExits.h - Redirect exiting edges to one block -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_UNIFYLOOPEXITS_H
-#define LLVM_TRANSFORMS_UTILS_UNIFYLOOPEXITS_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-
-class UnifyLoopExitsPass : public PassInfoMixin<UnifyLoopExitsPass> {
-public:
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-} // namespace llvm
-
-#endif // LLVM_TRANSFORMS_UTILS_UNIFYLOOPEXITS_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- UnifyLoopExits.h - Redirect exiting edges to one block -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_UNIFYLOOPEXITS_H
+#define LLVM_TRANSFORMS_UTILS_UNIFYLOOPEXITS_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class UnifyLoopExitsPass : public PassInfoMixin<UnifyLoopExitsPass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_UNIFYLOOPEXITS_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h b/contrib/libs/llvm12/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h
index 1b07676bd2..08103ad050 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h
@@ -36,7 +36,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/Analysis/LoopAccessAnalysis.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
-#include "llvm/Support/TypeSize.h"
+#include "llvm/Support/TypeSize.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
namespace llvm {
@@ -51,14 +51,14 @@ namespace llvm {
/// for example 'force', means a decision has been made. So, we need to be
/// careful NOT to add them if the user hasn't specifically asked so.
class LoopVectorizeHints {
- enum HintKind {
- HK_WIDTH,
- HK_UNROLL,
- HK_FORCE,
- HK_ISVECTORIZED,
- HK_PREDICATE,
- HK_SCALABLE
- };
+ enum HintKind {
+ HK_WIDTH,
+ HK_UNROLL,
+ HK_FORCE,
+ HK_ISVECTORIZED,
+ HK_PREDICATE,
+ HK_SCALABLE
+ };
/// Hint - associates name and validation with the hint value.
struct Hint {
@@ -87,9 +87,9 @@ class LoopVectorizeHints {
/// Vector Predicate
Hint Predicate;
- /// Says whether we should use fixed width or scalable vectorization.
- Hint Scalable;
-
+ /// Says whether we should use fixed width or scalable vectorization.
+ Hint Scalable;
+
/// Return the loop metadata prefix.
static StringRef Prefix() { return "llvm.loop."; }
@@ -115,9 +115,9 @@ public:
/// Dumps all the hint information.
void emitRemarkWithHints() const;
- ElementCount getWidth() const {
- return ElementCount::get(Width.Value, isScalable());
- }
+ ElementCount getWidth() const {
+ return ElementCount::get(Width.Value, isScalable());
+ }
unsigned getInterleave() const { return Interleave.Value; }
unsigned getIsVectorized() const { return IsVectorized.Value; }
unsigned getPredicate() const { return Predicate.Value; }
@@ -128,8 +128,8 @@ public:
return (ForceKind)Force.Value;
}
- bool isScalable() const { return Scalable.Value; }
-
+ bool isScalable() const { return Scalable.Value; }
+
/// If hints are provided that force vectorization, use the AlwaysPrint
/// pass name to force the frontend to print the diagnostic.
const char *vectorizeAnalysisPassName() const;
@@ -140,9 +140,9 @@ public:
// enabled by default because can be unsafe or inefficient. For example,
// reordering floating-point operations will change the way round-off
// error accumulates in the loop.
- ElementCount EC = getWidth();
- return getForce() == LoopVectorizeHints::FK_Enabled ||
- EC.getKnownMinValue() > 1;
+ ElementCount EC = getWidth();
+ return getForce() == LoopVectorizeHints::FK_Enabled ||
+ EC.getKnownMinValue() > 1;
}
bool isPotentiallyUnsafe() const {
@@ -225,10 +225,10 @@ public:
Function *F, std::function<const LoopAccessInfo &(Loop &)> *GetLAA,
LoopInfo *LI, OptimizationRemarkEmitter *ORE,
LoopVectorizationRequirements *R, LoopVectorizeHints *H, DemandedBits *DB,
- AssumptionCache *AC, BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI)
+ AssumptionCache *AC, BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI)
: TheLoop(L), LI(LI), PSE(PSE), TTI(TTI), TLI(TLI), DT(DT),
- GetLAA(GetLAA), ORE(ORE), Requirements(R), Hints(H), DB(DB), AC(AC),
- BFI(BFI), PSI(PSI) {}
+ GetLAA(GetLAA), ORE(ORE), Requirements(R), Hints(H), DB(DB), AC(AC),
+ BFI(BFI), PSI(PSI) {}
/// ReductionList contains the reduction descriptors for all
/// of the reductions that were found in the loop.
@@ -253,7 +253,7 @@ public:
/// Return true if we can vectorize this loop while folding its tail by
/// masking, and mark all respective loads/stores for masking.
- /// This object's state is only modified iff this function returns true.
+ /// This object's state is only modified iff this function returns true.
bool prepareToFoldTailByMasking();
/// Returns the primary induction variable.
@@ -312,19 +312,19 @@ public:
/// Returns true if the value V is uniform within the loop.
bool isUniform(Value *V);
- /// A uniform memory op is a load or store which accesses the same memory
- /// location on all lanes.
- bool isUniformMemOp(Instruction &I) {
- Value *Ptr = getLoadStorePointerOperand(&I);
- if (!Ptr)
- return false;
- // Note: There's nothing inherent which prevents predicated loads and
- // stores from being uniform. The current lowering simply doesn't handle
- // it; in particular, the cost model distinguishes scatter/gather from
- // scalar w/predication, and we currently rely on the scalar path.
- return isUniform(Ptr) && !blockNeedsPredication(I.getParent());
- }
-
+ /// A uniform memory op is a load or store which accesses the same memory
+ /// location on all lanes.
+ bool isUniformMemOp(Instruction &I) {
+ Value *Ptr = getLoadStorePointerOperand(&I);
+ if (!Ptr)
+ return false;
+ // Note: There's nothing inherent which prevents predicated loads and
+ // stores from being uniform. The current lowering simply doesn't handle
+ // it; in particular, the cost model distinguishes scatter/gather from
+ // scalar w/predication, and we currently rely on the scalar path.
+ return isUniform(Ptr) && !blockNeedsPredication(I.getParent());
+ }
+
/// Returns the information that we collected about runtime memory check.
const RuntimePointerChecking *getRuntimePointerChecking() const {
return LAI->getRuntimePointerChecking();
@@ -332,21 +332,21 @@ public:
const LoopAccessInfo *getLAI() const { return LAI; }
- bool isSafeForAnyVectorWidth() const {
- return LAI->getDepChecker().isSafeForAnyVectorWidth();
- }
-
+ bool isSafeForAnyVectorWidth() const {
+ return LAI->getDepChecker().isSafeForAnyVectorWidth();
+ }
+
unsigned getMaxSafeDepDistBytes() { return LAI->getMaxSafeDepDistBytes(); }
- uint64_t getMaxSafeVectorWidthInBits() const {
- return LAI->getDepChecker().getMaxSafeVectorWidthInBits();
+ uint64_t getMaxSafeVectorWidthInBits() const {
+ return LAI->getDepChecker().getMaxSafeVectorWidthInBits();
}
bool hasStride(Value *V) { return LAI->hasStride(V); }
/// Returns true if vector representation of the instruction \p I
/// requires mask.
- bool isMaskRequired(const Instruction *I) { return MaskedOp.contains(I); }
+ bool isMaskRequired(const Instruction *I) { return MaskedOp.contains(I); }
unsigned getNumStores() const { return LAI->getNumStores(); }
unsigned getNumLoads() const { return LAI->getNumLoads(); }
@@ -403,17 +403,17 @@ private:
bool canVectorizeOuterLoop();
/// Return true if all of the instructions in the block can be speculatively
- /// executed, and record the loads/stores that require masking.
+ /// executed, and record the loads/stores that require masking.
/// \p SafePtrs is a list of addresses that are known to be legal and we know
/// that we can read from them without segfault.
- /// \p MaskedOp is a list of instructions that have to be transformed into
- /// calls to the appropriate masked intrinsic when the loop is vectorized.
- /// \p ConditionalAssumes is a list of assume instructions in predicated
- /// blocks that must be dropped if the CFG gets flattened.
- bool blockCanBePredicated(
- BasicBlock *BB, SmallPtrSetImpl<Value *> &SafePtrs,
- SmallPtrSetImpl<const Instruction *> &MaskedOp,
- SmallPtrSetImpl<Instruction *> &ConditionalAssumes) const;
+ /// \p MaskedOp is a list of instructions that have to be transformed into
+ /// calls to the appropriate masked intrinsic when the loop is vectorized.
+ /// \p ConditionalAssumes is a list of assume instructions in predicated
+ /// blocks that must be dropped if the CFG gets flattened.
+ bool blockCanBePredicated(
+ BasicBlock *BB, SmallPtrSetImpl<Value *> &SafePtrs,
+ SmallPtrSetImpl<const Instruction *> &MaskedOp,
+ SmallPtrSetImpl<Instruction *> &ConditionalAssumes) const;
/// Updates the vectorization state by adding \p Phi to the inductions list.
/// This can set \p Phi as the main induction of the loop if \p Phi is a
@@ -521,10 +521,10 @@ private:
/// Assume instructions in predicated blocks must be dropped if the CFG gets
/// flattened.
SmallPtrSet<Instruction *, 8> ConditionalAssumes;
-
- /// BFI and PSI are used to check for profile guided size optimizations.
- BlockFrequencyInfo *BFI;
- ProfileSummaryInfo *PSI;
+
+ /// BFI and PSI are used to check for profile guided size optimizations.
+ BlockFrequencyInfo *BFI;
+ ProfileSummaryInfo *PSI;
};
} // namespace llvm
diff --git a/contrib/libs/llvm12/include/llvm/Transforms/Vectorize/SLPVectorizer.h b/contrib/libs/llvm12/include/llvm/Transforms/Vectorize/SLPVectorizer.h
index 7fe02f6714..b63850ce9f 100644
--- a/contrib/libs/llvm12/include/llvm/Transforms/Vectorize/SLPVectorizer.h
+++ b/contrib/libs/llvm12/include/llvm/Transforms/Vectorize/SLPVectorizer.h
@@ -33,7 +33,7 @@
namespace llvm {
-class AAResults;
+class AAResults;
class AssumptionCache;
class BasicBlock;
class CmpInst;
@@ -41,7 +41,7 @@ class DataLayout;
class DemandedBits;
class DominatorTree;
class Function;
-class GetElementPtrInst;
+class GetElementPtrInst;
class InsertElementInst;
class InsertValueInst;
class Instruction;
@@ -71,7 +71,7 @@ struct SLPVectorizerPass : public PassInfoMixin<SLPVectorizerPass> {
ScalarEvolution *SE = nullptr;
TargetTransformInfo *TTI = nullptr;
TargetLibraryInfo *TLI = nullptr;
- AAResults *AA = nullptr;
+ AAResults *AA = nullptr;
LoopInfo *LI = nullptr;
DominatorTree *DT = nullptr;
AssumptionCache *AC = nullptr;
@@ -83,7 +83,7 @@ public:
// Glue for old PM.
bool runImpl(Function &F, ScalarEvolution *SE_, TargetTransformInfo *TTI_,
- TargetLibraryInfo *TLI_, AAResults *AA_, LoopInfo *LI_,
+ TargetLibraryInfo *TLI_, AAResults *AA_, LoopInfo *LI_,
DominatorTree *DT_, AssumptionCache *AC_, DemandedBits *DB_,
OptimizationRemarkEmitter *ORE_);
diff --git a/contrib/libs/llvm12/include/llvm/module.modulemap b/contrib/libs/llvm12/include/llvm/module.modulemap
index 6175954356..a199f7f2d7 100644
--- a/contrib/libs/llvm12/include/llvm/module.modulemap
+++ b/contrib/libs/llvm12/include/llvm/module.modulemap
@@ -30,7 +30,7 @@ module LLVM_Backend {
// These are intended for (repeated) textual inclusion.
textual header "CodeGen/DIEValue.def"
- textual header "CodeGen/MachinePassRegistry.def"
+ textual header "CodeGen/MachinePassRegistry.def"
}
}
@@ -66,7 +66,7 @@ module LLVM_BinaryFormat {
textual header "BinaryFormat/ELFRelocs/ARC.def"
textual header "BinaryFormat/ELFRelocs/AVR.def"
textual header "BinaryFormat/ELFRelocs/BPF.def"
- textual header "BinaryFormat/ELFRelocs/CSKY.def"
+ textual header "BinaryFormat/ELFRelocs/CSKY.def"
textual header "BinaryFormat/ELFRelocs/Hexagon.def"
textual header "BinaryFormat/ELFRelocs/i386.def"
textual header "BinaryFormat/ELFRelocs/Lanai.def"
@@ -190,30 +190,30 @@ module LLVM_ExecutionEngine {
exclude header "ExecutionEngine/Orc/RemoteObjectLayer.h"
// Exclude headers from LLVM_OrcSupport.
- exclude header "ExecutionEngine/Orc/Shared/OrcError.h"
+ exclude header "ExecutionEngine/Orc/Shared/OrcError.h"
exclude header "ExecutionEngine/Orc/RPC/RPCUtils.h"
exclude header "ExecutionEngine/Orc/RPC/RPCSerialization.h"
exclude header "ExecutionEngine/Orc/RPC/RawByteChannel.h"
}
-module LLVM_FileCheck {
- requires cplusplus
-
- umbrella "FileCheck"
- module * { export * }
-}
-
+module LLVM_FileCheck {
+ requires cplusplus
+
+ umbrella "FileCheck"
+ module * { export * }
+}
+
// Orc utilities that don't depend only on Support (not ExecutionEngine or
// IR). This is a workaround for ExecutionEngine's broken layering, and will
// be removed in the future.
module LLVM_OrcSupport {
requires cplusplus
- header "ExecutionEngine/Orc/Shared/OrcError.h"
- header "ExecutionEngine/Orc/Shared/RPCUtils.h"
- header "ExecutionEngine/Orc/Shared/Serialization.h"
- header "ExecutionEngine/Orc/Shared/RawByteChannel.h"
+ header "ExecutionEngine/Orc/Shared/OrcError.h"
+ header "ExecutionEngine/Orc/Shared/RPCUtils.h"
+ header "ExecutionEngine/Orc/Shared/Serialization.h"
+ header "ExecutionEngine/Orc/Shared/RawByteChannel.h"
export *
}
@@ -262,7 +262,7 @@ module LLVM_intrinsic_gen {
module IR_CFG { header "IR/CFG.h" export * }
module IR_ConstantRange { header "IR/ConstantRange.h" export * }
module IR_Dominators { header "IR/Dominators.h" export * }
- module IR_FixedPointBuilder { header "IR/FixedPointBuilder.h" export * }
+ module IR_FixedPointBuilder { header "IR/FixedPointBuilder.h" export * }
module Analysis_PostDominators { header "Analysis/PostDominators.h" export * }
module Analysis_DomTreeUpdater { header "Analysis/DomTreeUpdater.h" export * }
module IR_IRBuilder { header "IR/IRBuilder.h" export * }
diff --git a/contrib/libs/llvm12/include/ya.make b/contrib/libs/llvm12/include/ya.make
index ec3df3d23d..649c0e4a89 100644
--- a/contrib/libs/llvm12/include/ya.make
+++ b/contrib/libs/llvm12/include/ya.make
@@ -20,7 +20,7 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
+ contrib/libs/llvm12
)
NO_UTIL()
@@ -30,7 +30,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/Frontend/OpenACC -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/Frontend/OpenACC/ACC.td --write-if-changed -o
llvm/Frontend/OpenACC/ACC.h.inc -d llvm/Frontend/OpenACC/ACC.h.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/Frontend/Directive/DirectiveBase.td llvm/Frontend/OpenACC/ACC.td
OUTPUT_INCLUDES llvm/ADT/BitmaskEnum.h
OUT_NOAUTO llvm/Frontend/OpenACC/ACC.h.inc llvm/Frontend/OpenACC/ACC.h.inc.d
@@ -41,7 +41,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/Frontend/OpenMP -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/Frontend/OpenMP/OMP.td --write-if-changed -o
llvm/Frontend/OpenMP/OMP.h.inc -d llvm/Frontend/OpenMP/OMP.h.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/Frontend/Directive/DirectiveBase.td llvm/Frontend/OpenMP/OMP.td
OUTPUT_INCLUDES llvm/ADT/BitmaskEnum.h
OUT_NOAUTO llvm/Frontend/OpenMP/OMP.h.inc llvm/Frontend/OpenMP/OMP.h.inc.d
@@ -51,7 +51,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/utils/TableGen -gen-attrs -I ${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/IR
-Iinclude -I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/IR/Attributes.td --write-if-changed -o
llvm/IR/Attributes.inc -d llvm/IR/Attributes.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/IR/Attributes.td
OUT_NOAUTO llvm/IR/Attributes.inc llvm/IR/Attributes.inc.d
)
@@ -61,7 +61,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/IR -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/IR/Intrinsics.td --write-if-changed -o
llvm/IR/IntrinsicEnums.inc -d llvm/IR/IntrinsicEnums.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/CodeGen/SDNodeProperties.td llvm/CodeGen/ValueTypes.td llvm/IR/Intrinsics.td
llvm/IR/IntrinsicsAArch64.td llvm/IR/IntrinsicsAMDGPU.td llvm/IR/IntrinsicsARM.td
llvm/IR/IntrinsicsBPF.td llvm/IR/IntrinsicsHexagon.td llvm/IR/IntrinsicsHexagonDep.td
@@ -77,7 +77,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/IR -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/IR/Intrinsics.td --write-if-changed -o
llvm/IR/IntrinsicImpl.inc -d llvm/IR/IntrinsicImpl.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/CodeGen/SDNodeProperties.td llvm/CodeGen/ValueTypes.td llvm/IR/Intrinsics.td
llvm/IR/IntrinsicsAArch64.td llvm/IR/IntrinsicsAMDGPU.td llvm/IR/IntrinsicsARM.td
llvm/IR/IntrinsicsBPF.td llvm/IR/IntrinsicsHexagon.td llvm/IR/IntrinsicsHexagonDep.td
@@ -93,7 +93,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/IR -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/IR/Intrinsics.td --write-if-changed -o
llvm/IR/IntrinsicsAArch64.h -d llvm/IR/IntrinsicsAArch64.h.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/CodeGen/SDNodeProperties.td llvm/CodeGen/ValueTypes.td llvm/IR/Intrinsics.td
llvm/IR/IntrinsicsAArch64.td llvm/IR/IntrinsicsAMDGPU.td llvm/IR/IntrinsicsARM.td
llvm/IR/IntrinsicsBPF.td llvm/IR/IntrinsicsHexagon.td llvm/IR/IntrinsicsHexagonDep.td
@@ -109,7 +109,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/IR -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/IR/Intrinsics.td --write-if-changed -o
llvm/IR/IntrinsicsAMDGPU.h -d llvm/IR/IntrinsicsAMDGPU.h.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/CodeGen/SDNodeProperties.td llvm/CodeGen/ValueTypes.td llvm/IR/Intrinsics.td
llvm/IR/IntrinsicsAArch64.td llvm/IR/IntrinsicsAMDGPU.td llvm/IR/IntrinsicsARM.td
llvm/IR/IntrinsicsBPF.td llvm/IR/IntrinsicsHexagon.td llvm/IR/IntrinsicsHexagonDep.td
@@ -125,7 +125,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/IR -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/IR/Intrinsics.td --write-if-changed -o
llvm/IR/IntrinsicsARM.h -d llvm/IR/IntrinsicsARM.h.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/CodeGen/SDNodeProperties.td llvm/CodeGen/ValueTypes.td llvm/IR/Intrinsics.td
llvm/IR/IntrinsicsAArch64.td llvm/IR/IntrinsicsAMDGPU.td llvm/IR/IntrinsicsARM.td
llvm/IR/IntrinsicsBPF.td llvm/IR/IntrinsicsHexagon.td llvm/IR/IntrinsicsHexagonDep.td
@@ -141,7 +141,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/IR -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/IR/Intrinsics.td --write-if-changed -o
llvm/IR/IntrinsicsBPF.h -d llvm/IR/IntrinsicsBPF.h.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/CodeGen/SDNodeProperties.td llvm/CodeGen/ValueTypes.td llvm/IR/Intrinsics.td
llvm/IR/IntrinsicsAArch64.td llvm/IR/IntrinsicsAMDGPU.td llvm/IR/IntrinsicsARM.td
llvm/IR/IntrinsicsBPF.td llvm/IR/IntrinsicsHexagon.td llvm/IR/IntrinsicsHexagonDep.td
@@ -157,7 +157,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/IR -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/IR/Intrinsics.td --write-if-changed -o
llvm/IR/IntrinsicsHexagon.h -d llvm/IR/IntrinsicsHexagon.h.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/CodeGen/SDNodeProperties.td llvm/CodeGen/ValueTypes.td llvm/IR/Intrinsics.td
llvm/IR/IntrinsicsAArch64.td llvm/IR/IntrinsicsAMDGPU.td llvm/IR/IntrinsicsARM.td
llvm/IR/IntrinsicsBPF.td llvm/IR/IntrinsicsHexagon.td llvm/IR/IntrinsicsHexagonDep.td
@@ -173,7 +173,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/IR -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/IR/Intrinsics.td --write-if-changed -o
llvm/IR/IntrinsicsMips.h -d llvm/IR/IntrinsicsMips.h.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/CodeGen/SDNodeProperties.td llvm/CodeGen/ValueTypes.td llvm/IR/Intrinsics.td
llvm/IR/IntrinsicsAArch64.td llvm/IR/IntrinsicsAMDGPU.td llvm/IR/IntrinsicsARM.td
llvm/IR/IntrinsicsBPF.td llvm/IR/IntrinsicsHexagon.td llvm/IR/IntrinsicsHexagonDep.td
@@ -189,7 +189,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/IR -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/IR/Intrinsics.td --write-if-changed -o
llvm/IR/IntrinsicsNVPTX.h -d llvm/IR/IntrinsicsNVPTX.h.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/CodeGen/SDNodeProperties.td llvm/CodeGen/ValueTypes.td llvm/IR/Intrinsics.td
llvm/IR/IntrinsicsAArch64.td llvm/IR/IntrinsicsAMDGPU.td llvm/IR/IntrinsicsARM.td
llvm/IR/IntrinsicsBPF.td llvm/IR/IntrinsicsHexagon.td llvm/IR/IntrinsicsHexagonDep.td
@@ -205,7 +205,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/IR -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/IR/Intrinsics.td --write-if-changed -o
llvm/IR/IntrinsicsPowerPC.h -d llvm/IR/IntrinsicsPowerPC.h.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/CodeGen/SDNodeProperties.td llvm/CodeGen/ValueTypes.td llvm/IR/Intrinsics.td
llvm/IR/IntrinsicsAArch64.td llvm/IR/IntrinsicsAMDGPU.td llvm/IR/IntrinsicsARM.td
llvm/IR/IntrinsicsBPF.td llvm/IR/IntrinsicsHexagon.td llvm/IR/IntrinsicsHexagonDep.td
@@ -221,7 +221,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/IR -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/IR/Intrinsics.td --write-if-changed -o
llvm/IR/IntrinsicsR600.h -d llvm/IR/IntrinsicsR600.h.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/CodeGen/SDNodeProperties.td llvm/CodeGen/ValueTypes.td llvm/IR/Intrinsics.td
llvm/IR/IntrinsicsAArch64.td llvm/IR/IntrinsicsAMDGPU.td llvm/IR/IntrinsicsARM.td
llvm/IR/IntrinsicsBPF.td llvm/IR/IntrinsicsHexagon.td llvm/IR/IntrinsicsHexagonDep.td
@@ -237,7 +237,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/IR -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/IR/Intrinsics.td --write-if-changed -o
llvm/IR/IntrinsicsRISCV.h -d llvm/IR/IntrinsicsRISCV.h.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/CodeGen/SDNodeProperties.td llvm/CodeGen/ValueTypes.td llvm/IR/Intrinsics.td
llvm/IR/IntrinsicsAArch64.td llvm/IR/IntrinsicsAMDGPU.td llvm/IR/IntrinsicsARM.td
llvm/IR/IntrinsicsBPF.td llvm/IR/IntrinsicsHexagon.td llvm/IR/IntrinsicsHexagonDep.td
@@ -253,7 +253,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/IR -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/IR/Intrinsics.td --write-if-changed -o
llvm/IR/IntrinsicsS390.h -d llvm/IR/IntrinsicsS390.h.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/CodeGen/SDNodeProperties.td llvm/CodeGen/ValueTypes.td llvm/IR/Intrinsics.td
llvm/IR/IntrinsicsAArch64.td llvm/IR/IntrinsicsAMDGPU.td llvm/IR/IntrinsicsARM.td
llvm/IR/IntrinsicsBPF.td llvm/IR/IntrinsicsHexagon.td llvm/IR/IntrinsicsHexagonDep.td
@@ -269,7 +269,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/IR -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/IR/Intrinsics.td --write-if-changed -o
llvm/IR/IntrinsicsVE.h -d llvm/IR/IntrinsicsVE.h.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/CodeGen/SDNodeProperties.td llvm/CodeGen/ValueTypes.td llvm/IR/Intrinsics.td
llvm/IR/IntrinsicsAArch64.td llvm/IR/IntrinsicsAMDGPU.td llvm/IR/IntrinsicsARM.td
llvm/IR/IntrinsicsBPF.td llvm/IR/IntrinsicsHexagon.td llvm/IR/IntrinsicsHexagonDep.td
@@ -277,15 +277,15 @@ RUN_PROGRAM(
llvm/IR/IntrinsicsRISCV.td llvm/IR/IntrinsicsSystemZ.td llvm/IR/IntrinsicsVE.td
llvm/IR/IntrinsicsVEVL.gen.td llvm/IR/IntrinsicsWebAssembly.td llvm/IR/IntrinsicsX86.td
llvm/IR/IntrinsicsXCore.td
- OUT_NOAUTO llvm/IR/IntrinsicsVE.h llvm/IR/IntrinsicsVE.h.d
-)
-
-RUN_PROGRAM(
+ OUT_NOAUTO llvm/IR/IntrinsicsVE.h llvm/IR/IntrinsicsVE.h.d
+)
+
+RUN_PROGRAM(
contrib/libs/llvm12/utils/TableGen -gen-intrinsic-enums -intrinsic-prefix=wasm -I
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/IR -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/IR/Intrinsics.td --write-if-changed -o
llvm/IR/IntrinsicsWebAssembly.h -d llvm/IR/IntrinsicsWebAssembly.h.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/CodeGen/SDNodeProperties.td llvm/CodeGen/ValueTypes.td llvm/IR/Intrinsics.td
llvm/IR/IntrinsicsAArch64.td llvm/IR/IntrinsicsAMDGPU.td llvm/IR/IntrinsicsARM.td
llvm/IR/IntrinsicsBPF.td llvm/IR/IntrinsicsHexagon.td llvm/IR/IntrinsicsHexagonDep.td
@@ -301,7 +301,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/IR -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/IR/Intrinsics.td --write-if-changed -o
llvm/IR/IntrinsicsX86.h -d llvm/IR/IntrinsicsX86.h.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/CodeGen/SDNodeProperties.td llvm/CodeGen/ValueTypes.td llvm/IR/Intrinsics.td
llvm/IR/IntrinsicsAArch64.td llvm/IR/IntrinsicsAMDGPU.td llvm/IR/IntrinsicsARM.td
llvm/IR/IntrinsicsBPF.td llvm/IR/IntrinsicsHexagon.td llvm/IR/IntrinsicsHexagonDep.td
@@ -317,7 +317,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/include/llvm/IR -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/IR/Intrinsics.td --write-if-changed -o
llvm/IR/IntrinsicsXCore.h -d llvm/IR/IntrinsicsXCore.h.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/CodeGen/SDNodeProperties.td llvm/CodeGen/ValueTypes.td llvm/IR/Intrinsics.td
llvm/IR/IntrinsicsAArch64.td llvm/IR/IntrinsicsAMDGPU.td llvm/IR/IntrinsicsARM.td
llvm/IR/IntrinsicsBPF.td llvm/IR/IntrinsicsHexagon.td llvm/IR/IntrinsicsHexagonDep.td
@@ -334,7 +334,7 @@ RUN_PROGRAM(
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/Frontend/OpenACC/ACC.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Frontend/OpenACC/ACC.cpp -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Frontend/OpenACC/ACC.cpp.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/Frontend/Directive/DirectiveBase.td llvm/Frontend/OpenACC/ACC.td
OUTPUT_INCLUDES llvm/ADT/StringRef.h llvm/ADT/StringSwitch.h llvm/Frontend/OpenACC/ACC.h.inc
llvm/Support/ErrorHandling.h
@@ -348,7 +348,7 @@ RUN_PROGRAM(
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include llvm/Frontend/OpenMP/OMP.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Frontend/OpenMP/OMP.cpp -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Frontend/OpenMP/OMP.cpp.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN llvm/Frontend/Directive/DirectiveBase.td llvm/Frontend/OpenMP/OMP.td
OUTPUT_INCLUDES llvm/ADT/StringRef.h llvm/ADT/StringSwitch.h llvm/Frontend/OpenMP/OMP.h.inc
llvm/Support/ErrorHandling.h
@@ -363,7 +363,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/AArch64/AArch64.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenAsmMatcher.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenAsmMatcher.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -420,7 +420,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/AArch64/AArch64.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenAsmWriter.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenAsmWriter.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -476,7 +476,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/AArch64/AArch64.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenAsmWriter1.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenAsmWriter1.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -532,7 +532,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/AArch64/AArch64.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenCallingConv.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenCallingConv.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -588,7 +588,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/AArch64/AArch64.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenDAGISel.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenDAGISel.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -644,7 +644,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/AArch64/AArch64.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenDisassemblerTables.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenDisassemblerTables.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -702,7 +702,7 @@ RUN_PROGRAM(
--write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenExegesis.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenExegesis.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -758,7 +758,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/AArch64/AArch64.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenFastISel.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenFastISel.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -814,7 +814,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/AArch64/AArch64.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenGlobalISel.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenGlobalISel.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -870,7 +870,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/AArch64/AArch64.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenInstrInfo.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenInstrInfo.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -926,7 +926,7 @@ RUN_PROGRAM(
--write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenMCCodeEmitter.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenMCCodeEmitter.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -983,7 +983,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/AArch64/AArch64.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenMCPseudoLowering.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenMCPseudoLowering.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -1039,7 +1039,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/AArch64/AArch64.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenPostLegalizeGICombiner.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenPostLegalizeGICombiner.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -1097,7 +1097,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/AArch64/AArch64.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenPostLegalizeGILowering.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenPostLegalizeGILowering.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -1155,7 +1155,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/AArch64/AArch64.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenPreLegalizeGICombiner.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenPreLegalizeGICombiner.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -1200,7 +1200,7 @@ RUN_PROGRAM(
llvm/Target/GlobalISel/Target.td llvm/Target/Target.td llvm/Target/TargetCallingConv.td
llvm/Target/TargetInstrPredicate.td llvm/Target/TargetItinerary.td llvm/Target/TargetPfmCounters.td
llvm/Target/TargetSchedule.td llvm/Target/TargetSelectionDAG.td
- OUTPUT_INCLUDES llvm/ADT/SparseBitVector.h
+ OUTPUT_INCLUDES llvm/ADT/SparseBitVector.h
OUT_NOAUTO
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenPreLegalizeGICombiner.inc
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenPreLegalizeGICombiner.inc.d
@@ -1213,7 +1213,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/AArch64/AArch64.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenRegisterBank.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenRegisterBank.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -1260,16 +1260,16 @@ RUN_PROGRAM(
llvm/Target/TargetSchedule.td llvm/Target/TargetSelectionDAG.td
OUT_NOAUTO ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenRegisterBank.inc
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenRegisterBank.inc.d
-)
-
-RUN_PROGRAM(
+)
+
+RUN_PROGRAM(
contrib/libs/llvm12/utils/TableGen -gen-register-info -I
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target/AArch64 -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include -I ${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target
contrib/libs/llvm12/lib/Target/AArch64/AArch64.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenRegisterInfo.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenRegisterInfo.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -1326,7 +1326,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/AArch64/AArch64.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenSubtargetInfo.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenSubtargetInfo.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -1383,7 +1383,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/AArch64/AArch64.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenSystemOperands.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64/AArch64GenSystemOperands.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.td
contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -1438,7 +1438,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/ARM/ARM.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenAsmMatcher.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenAsmMatcher.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/ARM/ARM.td contrib/libs/llvm12/lib/Target/ARM/ARMCallingConv.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrCDE.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td
@@ -1479,7 +1479,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/ARM/ARM.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenAsmWriter.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenAsmWriter.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/ARM/ARM.td contrib/libs/llvm12/lib/Target/ARM/ARMCallingConv.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrCDE.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td
@@ -1519,7 +1519,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/ARM/ARM.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenCallingConv.inc
-d ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenCallingConv.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/ARM/ARM.td contrib/libs/llvm12/lib/Target/ARM/ARMCallingConv.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrCDE.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td
@@ -1560,7 +1560,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/ARM/ARM.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenDAGISel.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenDAGISel.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/ARM/ARM.td contrib/libs/llvm12/lib/Target/ARM/ARMCallingConv.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrCDE.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td
@@ -1601,7 +1601,7 @@ RUN_PROGRAM(
--write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenDisassemblerTables.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenDisassemblerTables.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/ARM/ARM.td contrib/libs/llvm12/lib/Target/ARM/ARMCallingConv.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrCDE.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td
@@ -1643,7 +1643,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/ARM/ARM.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenFastISel.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenFastISel.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/ARM/ARM.td contrib/libs/llvm12/lib/Target/ARM/ARMCallingConv.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrCDE.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td
@@ -1683,7 +1683,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/ARM/ARM.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenGlobalISel.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenGlobalISel.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/ARM/ARM.td contrib/libs/llvm12/lib/Target/ARM/ARMCallingConv.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrCDE.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td
@@ -1723,7 +1723,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/ARM/ARM.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenInstrInfo.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenInstrInfo.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/ARM/ARM.td contrib/libs/llvm12/lib/Target/ARM/ARMCallingConv.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrCDE.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td
@@ -1763,7 +1763,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/ARM/ARM.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenMCCodeEmitter.inc
-d ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenMCCodeEmitter.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/ARM/ARM.td contrib/libs/llvm12/lib/Target/ARM/ARMCallingConv.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrCDE.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td
@@ -1805,7 +1805,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/ARM/ARM.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenMCPseudoLowering.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenMCPseudoLowering.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/ARM/ARM.td contrib/libs/llvm12/lib/Target/ARM/ARMCallingConv.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrCDE.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td
@@ -1846,7 +1846,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/ARM/ARM.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenRegisterBank.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenRegisterBank.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/ARM/ARM.td contrib/libs/llvm12/lib/Target/ARM/ARMCallingConv.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrCDE.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td
@@ -1887,7 +1887,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/ARM/ARM.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenRegisterInfo.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenRegisterInfo.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/ARM/ARM.td contrib/libs/llvm12/lib/Target/ARM/ARMCallingConv.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrCDE.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td
@@ -1928,7 +1928,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/ARM/ARM.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenSubtargetInfo.inc
-d ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenSubtargetInfo.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/ARM/ARM.td contrib/libs/llvm12/lib/Target/ARM/ARMCallingConv.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrCDE.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td
@@ -1970,7 +1970,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/ARM/ARM.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenSystemRegister.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM/ARMGenSystemRegister.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/ARM/ARM.td contrib/libs/llvm12/lib/Target/ARM/ARMCallingConv.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrCDE.td
contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td
@@ -2010,7 +2010,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/BPF/BPF.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF/BPFGenAsmMatcher.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF/BPFGenAsmMatcher.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/BPF/BPF.td contrib/libs/llvm12/lib/Target/BPF/BPFCallingConv.td
contrib/libs/llvm12/lib/Target/BPF/BPFInstrFormats.td
contrib/libs/llvm12/lib/Target/BPF/BPFInstrInfo.td
@@ -2036,7 +2036,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/BPF/BPF.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF/BPFGenAsmWriter.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF/BPFGenAsmWriter.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/BPF/BPF.td contrib/libs/llvm12/lib/Target/BPF/BPFCallingConv.td
contrib/libs/llvm12/lib/Target/BPF/BPFInstrFormats.td
contrib/libs/llvm12/lib/Target/BPF/BPFInstrInfo.td
@@ -2061,7 +2061,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/BPF/BPF.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF/BPFGenCallingConv.inc
-d ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF/BPFGenCallingConv.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/BPF/BPF.td contrib/libs/llvm12/lib/Target/BPF/BPFCallingConv.td
contrib/libs/llvm12/lib/Target/BPF/BPFInstrFormats.td
contrib/libs/llvm12/lib/Target/BPF/BPFInstrInfo.td
@@ -2087,7 +2087,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/BPF/BPF.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF/BPFGenDAGISel.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF/BPFGenDAGISel.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/BPF/BPF.td contrib/libs/llvm12/lib/Target/BPF/BPFCallingConv.td
contrib/libs/llvm12/lib/Target/BPF/BPFInstrFormats.td
contrib/libs/llvm12/lib/Target/BPF/BPFInstrInfo.td
@@ -2113,7 +2113,7 @@ RUN_PROGRAM(
--write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF/BPFGenDisassemblerTables.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF/BPFGenDisassemblerTables.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/BPF/BPF.td contrib/libs/llvm12/lib/Target/BPF/BPFCallingConv.td
contrib/libs/llvm12/lib/Target/BPF/BPFInstrFormats.td
contrib/libs/llvm12/lib/Target/BPF/BPFInstrInfo.td
@@ -2140,7 +2140,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/BPF/BPF.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF/BPFGenInstrInfo.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF/BPFGenInstrInfo.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/BPF/BPF.td contrib/libs/llvm12/lib/Target/BPF/BPFCallingConv.td
contrib/libs/llvm12/lib/Target/BPF/BPFInstrFormats.td
contrib/libs/llvm12/lib/Target/BPF/BPFInstrInfo.td
@@ -2165,7 +2165,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/BPF/BPF.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF/BPFGenMCCodeEmitter.inc
-d ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF/BPFGenMCCodeEmitter.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/BPF/BPF.td contrib/libs/llvm12/lib/Target/BPF/BPFCallingConv.td
contrib/libs/llvm12/lib/Target/BPF/BPFInstrFormats.td
contrib/libs/llvm12/lib/Target/BPF/BPFInstrInfo.td
@@ -2192,7 +2192,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/BPF/BPF.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF/BPFGenRegisterInfo.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF/BPFGenRegisterInfo.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/BPF/BPF.td contrib/libs/llvm12/lib/Target/BPF/BPFCallingConv.td
contrib/libs/llvm12/lib/Target/BPF/BPFInstrFormats.td
contrib/libs/llvm12/lib/Target/BPF/BPFInstrInfo.td
@@ -2218,7 +2218,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/BPF/BPF.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF/BPFGenSubtargetInfo.inc
-d ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF/BPFGenSubtargetInfo.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/BPF/BPF.td contrib/libs/llvm12/lib/Target/BPF/BPFCallingConv.td
contrib/libs/llvm12/lib/Target/BPF/BPFInstrFormats.td
contrib/libs/llvm12/lib/Target/BPF/BPFInstrInfo.td
@@ -2244,7 +2244,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/NVPTX/NVPTX.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXGenAsmWriter.inc
-d ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXGenAsmWriter.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/NVPTX/NVPTX.td contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrFormats.td
contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrInfo.td
contrib/libs/llvm12/lib/Target/NVPTX/NVPTXIntrinsics.td
@@ -2270,7 +2270,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/NVPTX/NVPTX.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXGenDAGISel.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXGenDAGISel.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/NVPTX/NVPTX.td contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrFormats.td
contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrInfo.td
contrib/libs/llvm12/lib/Target/NVPTX/NVPTXIntrinsics.td
@@ -2295,7 +2295,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/NVPTX/NVPTX.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXGenInstrInfo.inc
-d ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXGenInstrInfo.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/NVPTX/NVPTX.td contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrFormats.td
contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrInfo.td
contrib/libs/llvm12/lib/Target/NVPTX/NVPTXIntrinsics.td
@@ -2321,7 +2321,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/NVPTX/NVPTX.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXGenRegisterInfo.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXGenRegisterInfo.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/NVPTX/NVPTX.td contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrFormats.td
contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrInfo.td
contrib/libs/llvm12/lib/Target/NVPTX/NVPTXIntrinsics.td
@@ -2348,7 +2348,7 @@ RUN_PROGRAM(
--write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXGenSubtargetInfo.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXGenSubtargetInfo.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/NVPTX/NVPTX.td contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrFormats.td
contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrInfo.td
contrib/libs/llvm12/lib/Target/NVPTX/NVPTXIntrinsics.td
@@ -2375,7 +2375,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenAsmMatcher.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenAsmMatcher.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
contrib/libs/llvm12/lib/Target/PowerPC/P9InstrResources.td
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td contrib/libs/llvm12/lib/Target/PowerPC/PPCCallingConv.td
@@ -2424,7 +2424,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenAsmWriter.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenAsmWriter.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
contrib/libs/llvm12/lib/Target/PowerPC/P9InstrResources.td
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td contrib/libs/llvm12/lib/Target/PowerPC/PPCCallingConv.td
@@ -2472,7 +2472,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenCallingConv.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenCallingConv.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
contrib/libs/llvm12/lib/Target/PowerPC/P9InstrResources.td
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td contrib/libs/llvm12/lib/Target/PowerPC/PPCCallingConv.td
@@ -2520,7 +2520,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenDAGISel.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenDAGISel.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
contrib/libs/llvm12/lib/Target/PowerPC/P9InstrResources.td
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td contrib/libs/llvm12/lib/Target/PowerPC/PPCCallingConv.td
@@ -2568,7 +2568,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenDisassemblerTables.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenDisassemblerTables.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
contrib/libs/llvm12/lib/Target/PowerPC/P9InstrResources.td
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td contrib/libs/llvm12/lib/Target/PowerPC/PPCCallingConv.td
@@ -2617,7 +2617,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/PowerPC/PPC.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenExegesis.inc
-d ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenExegesis.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
contrib/libs/llvm12/lib/Target/PowerPC/P9InstrResources.td
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td contrib/libs/llvm12/lib/Target/PowerPC/PPCCallingConv.td
@@ -2665,7 +2665,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenFastISel.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenFastISel.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
contrib/libs/llvm12/lib/Target/PowerPC/P9InstrResources.td
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td contrib/libs/llvm12/lib/Target/PowerPC/PPCCallingConv.td
@@ -2713,7 +2713,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenGlobalISel.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenGlobalISel.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
contrib/libs/llvm12/lib/Target/PowerPC/P9InstrResources.td
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td contrib/libs/llvm12/lib/Target/PowerPC/PPCCallingConv.td
@@ -2761,7 +2761,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenInstrInfo.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenInstrInfo.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
contrib/libs/llvm12/lib/Target/PowerPC/P9InstrResources.td
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td contrib/libs/llvm12/lib/Target/PowerPC/PPCCallingConv.td
@@ -2800,16 +2800,16 @@ RUN_PROGRAM(
llvm/Target/TargetPfmCounters.td llvm/Target/TargetSchedule.td llvm/Target/TargetSelectionDAG.td
OUT_NOAUTO ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenInstrInfo.inc
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenInstrInfo.inc.d
-)
-
-RUN_PROGRAM(
+)
+
+RUN_PROGRAM(
contrib/libs/llvm12/utils/TableGen -gen-emitter -I ${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC
-Iinclude -I${ARCADIA_ROOT}/contrib/libs/llvm12/include -I
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/PowerPC/PPC.td
--write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenMCCodeEmitter.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenMCCodeEmitter.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
contrib/libs/llvm12/lib/Target/PowerPC/P9InstrResources.td
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td contrib/libs/llvm12/lib/Target/PowerPC/PPCCallingConv.td
@@ -2858,7 +2858,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenRegisterBank.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenRegisterBank.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
contrib/libs/llvm12/lib/Target/PowerPC/P9InstrResources.td
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td contrib/libs/llvm12/lib/Target/PowerPC/PPCCallingConv.td
@@ -2897,16 +2897,16 @@ RUN_PROGRAM(
llvm/Target/TargetPfmCounters.td llvm/Target/TargetSchedule.td llvm/Target/TargetSelectionDAG.td
OUT_NOAUTO ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenRegisterBank.inc
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenRegisterBank.inc.d
-)
-
-RUN_PROGRAM(
+)
+
+RUN_PROGRAM(
contrib/libs/llvm12/utils/TableGen -gen-register-info -I
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include -I ${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenRegisterInfo.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenRegisterInfo.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
contrib/libs/llvm12/lib/Target/PowerPC/P9InstrResources.td
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td contrib/libs/llvm12/lib/Target/PowerPC/PPCCallingConv.td
@@ -2955,7 +2955,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenSubtargetInfo.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC/PPCGenSubtargetInfo.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
contrib/libs/llvm12/lib/Target/PowerPC/P9InstrResources.td
contrib/libs/llvm12/lib/Target/PowerPC/PPC.td contrib/libs/llvm12/lib/Target/PowerPC/PPCCallingConv.td
@@ -3003,7 +3003,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/X86/X86.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenAsmMatcher.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenAsmMatcher.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/X86/X86.td contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td
contrib/libs/llvm12/lib/Target/X86/X86Instr3DNow.td contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td
contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td
@@ -3061,7 +3061,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/X86/X86.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenAsmWriter.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenAsmWriter.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/X86/X86.td contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td
contrib/libs/llvm12/lib/Target/X86/X86Instr3DNow.td contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td
contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td
@@ -3119,7 +3119,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/X86/X86.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenAsmWriter1.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenAsmWriter1.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/X86/X86.td contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td
contrib/libs/llvm12/lib/Target/X86/X86Instr3DNow.td contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td
contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td
@@ -3176,7 +3176,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/X86/X86.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenCallingConv.inc
-d ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenCallingConv.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/X86/X86.td contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td
contrib/libs/llvm12/lib/Target/X86/X86Instr3DNow.td contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td
contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td
@@ -3234,7 +3234,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/X86/X86.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenDAGISel.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenDAGISel.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/X86/X86.td contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td
contrib/libs/llvm12/lib/Target/X86/X86Instr3DNow.td contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td
contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td
@@ -3292,7 +3292,7 @@ RUN_PROGRAM(
--write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenDisassemblerTables.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenDisassemblerTables.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/X86/X86.td contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td
contrib/libs/llvm12/lib/Target/X86/X86Instr3DNow.td contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td
contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td
@@ -3350,7 +3350,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/X86/X86.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenEVEX2VEXTables.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenEVEX2VEXTables.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/X86/X86.td contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td
contrib/libs/llvm12/lib/Target/X86/X86Instr3DNow.td contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td
contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td
@@ -3407,7 +3407,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/X86/X86.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenExegesis.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenExegesis.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/X86/X86.td contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td
contrib/libs/llvm12/lib/Target/X86/X86Instr3DNow.td contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td
contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td
@@ -3464,7 +3464,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/X86/X86.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenFastISel.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenFastISel.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/X86/X86.td contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td
contrib/libs/llvm12/lib/Target/X86/X86Instr3DNow.td contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td
contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td
@@ -3521,7 +3521,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/X86/X86.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenGlobalISel.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenGlobalISel.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/X86/X86.td contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td
contrib/libs/llvm12/lib/Target/X86/X86Instr3DNow.td contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td
contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td
@@ -3579,7 +3579,7 @@ RUN_PROGRAM(
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenInstrInfo.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenInstrInfo.inc.d
--long-string-literals=0
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/X86/X86.td contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td
contrib/libs/llvm12/lib/Target/X86/X86Instr3DNow.td contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td
contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td
@@ -3637,7 +3637,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/X86/X86.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenRegisterBank.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenRegisterBank.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/X86/X86.td contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td
contrib/libs/llvm12/lib/Target/X86/X86Instr3DNow.td contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td
contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td
@@ -3695,7 +3695,7 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/Target/X86/X86.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenRegisterInfo.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenRegisterInfo.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/X86/X86.td contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td
contrib/libs/llvm12/lib/Target/X86/X86Instr3DNow.td contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td
contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td
@@ -3753,7 +3753,7 @@ RUN_PROGRAM(
${ARCADIA_ROOT}/contrib/libs/llvm12/lib/Target contrib/libs/llvm12/lib/Target/X86/X86.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenSubtargetInfo.inc
-d ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86/X86GenSubtargetInfo.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/lib/Target/X86/X86.td contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td
contrib/libs/llvm12/lib/Target/X86/X86Instr3DNow.td contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td
contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td
@@ -3812,8 +3812,8 @@ RUN_PROGRAM(
contrib/libs/llvm12/lib/ToolDrivers/llvm-dlltool/Options.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/ToolDrivers/llvm-dlltool/Options.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/ToolDrivers/llvm-dlltool/Options.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
- IN contrib/libs/llvm12/lib/ToolDrivers/llvm-dlltool/Options.td llvm/Option/OptParser.td
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ IN contrib/libs/llvm12/lib/ToolDrivers/llvm-dlltool/Options.td llvm/Option/OptParser.td
OUT_NOAUTO ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/ToolDrivers/llvm-dlltool/Options.inc
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/ToolDrivers/llvm-dlltool/Options.inc.d
)
@@ -3824,8 +3824,8 @@ RUN_PROGRAM(
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include contrib/libs/llvm12/lib/ToolDrivers/llvm-lib/Options.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/ToolDrivers/llvm-lib/Options.inc
-d ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/ToolDrivers/llvm-lib/Options.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
- IN contrib/libs/llvm12/lib/ToolDrivers/llvm-lib/Options.td llvm/Option/OptParser.td
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ IN contrib/libs/llvm12/lib/ToolDrivers/llvm-lib/Options.td llvm/Option/OptParser.td
OUT_NOAUTO ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/ToolDrivers/llvm-lib/Options.inc
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/ToolDrivers/llvm-lib/Options.inc.d
)
@@ -3836,8 +3836,8 @@ RUN_PROGRAM(
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include contrib/libs/llvm12/tools/dsymutil/Options.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/dsymutil/Options.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/dsymutil/Options.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
- IN contrib/libs/llvm12/tools/dsymutil/Options.td llvm/Option/OptParser.td
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ IN contrib/libs/llvm12/tools/dsymutil/Options.td llvm/Option/OptParser.td
OUT_NOAUTO ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/dsymutil/Options.inc
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/dsymutil/Options.inc.d
)
@@ -3848,8 +3848,8 @@ RUN_PROGRAM(
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include contrib/libs/llvm12/tools/llvm-cvtres/Opts.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-cvtres/Opts.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-cvtres/Opts.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
- IN contrib/libs/llvm12/tools/llvm-cvtres/Opts.td llvm/Option/OptParser.td
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ IN contrib/libs/llvm12/tools/llvm-cvtres/Opts.td llvm/Option/OptParser.td
OUT_NOAUTO ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-cvtres/Opts.inc
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-cvtres/Opts.inc.d
)
@@ -3860,8 +3860,8 @@ RUN_PROGRAM(
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include contrib/libs/llvm12/tools/llvm-lipo/LipoOpts.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-lipo/LipoOpts.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-lipo/LipoOpts.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
- IN contrib/libs/llvm12/tools/llvm-lipo/LipoOpts.td llvm/Option/OptParser.td
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ IN contrib/libs/llvm12/tools/llvm-lipo/LipoOpts.td llvm/Option/OptParser.td
OUT_NOAUTO ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-lipo/LipoOpts.inc
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-lipo/LipoOpts.inc.d
)
@@ -3872,8 +3872,8 @@ RUN_PROGRAM(
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include contrib/libs/llvm12/tools/llvm-ml/Opts.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-ml/Opts.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-ml/Opts.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
- IN contrib/libs/llvm12/tools/llvm-ml/Opts.td llvm/Option/OptParser.td
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ IN contrib/libs/llvm12/tools/llvm-ml/Opts.td llvm/Option/OptParser.td
OUT_NOAUTO ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-ml/Opts.inc
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-ml/Opts.inc.d
)
@@ -3884,8 +3884,8 @@ RUN_PROGRAM(
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include contrib/libs/llvm12/tools/llvm-mt/Opts.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-mt/Opts.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-mt/Opts.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
- IN contrib/libs/llvm12/tools/llvm-mt/Opts.td llvm/Option/OptParser.td
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ IN contrib/libs/llvm12/tools/llvm-mt/Opts.td llvm/Option/OptParser.td
OUT_NOAUTO ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-mt/Opts.inc
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-mt/Opts.inc.d
)
@@ -3897,8 +3897,8 @@ RUN_PROGRAM(
contrib/libs/llvm12/tools/llvm-objcopy/BitcodeStripOpts.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-objcopy/BitcodeStripOpts.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-objcopy/BitcodeStripOpts.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
- IN contrib/libs/llvm12/tools/llvm-objcopy/BitcodeStripOpts.td llvm/Option/OptParser.td
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ IN contrib/libs/llvm12/tools/llvm-objcopy/BitcodeStripOpts.td llvm/Option/OptParser.td
OUT_NOAUTO ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-objcopy/BitcodeStripOpts.inc
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-objcopy/BitcodeStripOpts.inc.d
)
@@ -3910,8 +3910,8 @@ RUN_PROGRAM(
contrib/libs/llvm12/tools/llvm-objcopy/InstallNameToolOpts.td --write-if-changed -o
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-objcopy/InstallNameToolOpts.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-objcopy/InstallNameToolOpts.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
- IN contrib/libs/llvm12/tools/llvm-objcopy/InstallNameToolOpts.td llvm/Option/OptParser.td
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ IN contrib/libs/llvm12/tools/llvm-objcopy/InstallNameToolOpts.td llvm/Option/OptParser.td
OUT_NOAUTO ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-objcopy/InstallNameToolOpts.inc
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-objcopy/InstallNameToolOpts.inc.d
)
@@ -3922,7 +3922,7 @@ RUN_PROGRAM(
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include contrib/libs/llvm12/tools/llvm-objcopy/ObjcopyOpts.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-objcopy/ObjcopyOpts.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-objcopy/ObjcopyOpts.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/tools/llvm-objcopy/CommonOpts.td
contrib/libs/llvm12/tools/llvm-objcopy/ObjcopyOpts.td llvm/Option/OptParser.td
OUT_NOAUTO ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-objcopy/ObjcopyOpts.inc
@@ -3935,35 +3935,35 @@ RUN_PROGRAM(
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include contrib/libs/llvm12/tools/llvm-objcopy/StripOpts.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-objcopy/StripOpts.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-objcopy/StripOpts.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
IN contrib/libs/llvm12/tools/llvm-objcopy/CommonOpts.td
contrib/libs/llvm12/tools/llvm-objcopy/StripOpts.td llvm/Option/OptParser.td
OUT_NOAUTO ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-objcopy/StripOpts.inc
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-objcopy/StripOpts.inc.d
)
-RUN_PROGRAM(
+RUN_PROGRAM(
contrib/libs/llvm12/utils/TableGen -gen-opt-parser-defs -I
${ARCADIA_ROOT}/contrib/libs/llvm12/tools/llvm-rc -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include contrib/libs/llvm12/tools/llvm-rc/Opts.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-rc/Opts.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-rc/Opts.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
- IN contrib/libs/llvm12/tools/llvm-rc/Opts.td llvm/Option/OptParser.td
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ IN contrib/libs/llvm12/tools/llvm-rc/Opts.td llvm/Option/OptParser.td
OUT_NOAUTO ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-rc/Opts.inc
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-rc/Opts.inc.d
-)
-
-RUN_PROGRAM(
+)
+
+RUN_PROGRAM(
contrib/libs/llvm12/utils/TableGen -gen-opt-parser-defs -I
${ARCADIA_ROOT}/contrib/libs/llvm12/tools/llvm-symbolizer -Iinclude
-I${ARCADIA_ROOT}/contrib/libs/llvm12/include contrib/libs/llvm12/tools/llvm-symbolizer/Opts.td
--write-if-changed -o ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-symbolizer/Opts.inc -d
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-symbolizer/Opts.inc.d
- CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
- IN contrib/libs/llvm12/tools/llvm-symbolizer/Opts.td llvm/Option/OptParser.td
+ CWD ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12
+ IN contrib/libs/llvm12/tools/llvm-symbolizer/Opts.td llvm/Option/OptParser.td
OUT_NOAUTO ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-symbolizer/Opts.inc
${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-symbolizer/Opts.inc.d
-)
-
+)
+
END()
diff --git a/contrib/libs/llvm12/lib/Analysis/AliasAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/AliasAnalysis.cpp
index aa1078a233..fae7a84332 100644
--- a/contrib/libs/llvm12/lib/Analysis/AliasAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/AliasAnalysis.cpp
@@ -24,7 +24,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/CFLAndersAliasAnalysis.h"
#include "llvm/Analysis/CFLSteensAliasAnalysis.h"
@@ -55,17 +55,17 @@
#include <functional>
#include <iterator>
-#define DEBUG_TYPE "aa"
-
+#define DEBUG_TYPE "aa"
+
using namespace llvm;
-STATISTIC(NumNoAlias, "Number of NoAlias results");
-STATISTIC(NumMayAlias, "Number of MayAlias results");
-STATISTIC(NumMustAlias, "Number of MustAlias results");
-
+STATISTIC(NumNoAlias, "Number of NoAlias results");
+STATISTIC(NumMayAlias, "Number of MayAlias results");
+STATISTIC(NumMustAlias, "Number of MustAlias results");
+
/// Allow disabling BasicAA from the AA results. This is particularly useful
/// when testing to isolate a single AA implementation.
-cl::opt<bool> DisableBasicAA("disable-basic-aa", cl::Hidden, cl::init(false));
+cl::opt<bool> DisableBasicAA("disable-basic-aa", cl::Hidden, cl::init(false));
AAResults::AAResults(AAResults &&Arg)
: TLI(Arg.TLI), AAs(std::move(Arg.AAs)), AADeps(std::move(Arg.AADeps)) {
@@ -116,25 +116,25 @@ AliasResult AAResults::alias(const MemoryLocation &LocA,
AliasResult AAResults::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB, AAQueryInfo &AAQI) {
- AliasResult Result = MayAlias;
-
- Depth++;
+ AliasResult Result = MayAlias;
+
+ Depth++;
for (const auto &AA : AAs) {
- Result = AA->alias(LocA, LocB, AAQI);
+ Result = AA->alias(LocA, LocB, AAQI);
if (Result != MayAlias)
- break;
+ break;
+ }
+ Depth--;
+
+ if (Depth == 0) {
+ if (Result == NoAlias)
+ ++NumNoAlias;
+ else if (Result == MustAlias)
+ ++NumMustAlias;
+ else
+ ++NumMayAlias;
}
- Depth--;
-
- if (Depth == 0) {
- if (Result == NoAlias)
- ++NumNoAlias;
- else if (Result == MustAlias)
- ++NumMustAlias;
- else
- ++NumMayAlias;
- }
- return Result;
+ return Result;
}
bool AAResults::pointsToConstantMemory(const MemoryLocation &Loc,
@@ -234,7 +234,7 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call,
unsigned ArgIdx = std::distance(Call->arg_begin(), AI);
MemoryLocation ArgLoc =
MemoryLocation::getForArgument(Call, ArgIdx, TLI);
- AliasResult ArgAlias = alias(ArgLoc, Loc, AAQI);
+ AliasResult ArgAlias = alias(ArgLoc, Loc, AAQI);
if (ArgAlias != NoAlias) {
ModRefInfo ArgMask = getArgModRefInfo(Call, ArgIdx);
AllArgsMask = unionModRef(AllArgsMask, ArgMask);
@@ -254,7 +254,7 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call,
// If Loc is a constant memory location, the call definitely could not
// modify the memory location.
- if (isModSet(Result) && pointsToConstantMemory(Loc, AAQI, /*OrLocal*/ false))
+ if (isModSet(Result) && pointsToConstantMemory(Loc, AAQI, /*OrLocal*/ false))
Result = clearMod(Result);
return Result;
@@ -331,7 +331,7 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call1,
// ModRefC1 indicates what Call1 might do to Call2ArgLoc, and we use
// above ArgMask to update dependence info.
- ModRefInfo ModRefC1 = getModRefInfo(Call1, Call2ArgLoc, AAQI);
+ ModRefInfo ModRefC1 = getModRefInfo(Call1, Call2ArgLoc, AAQI);
ArgMask = intersectModRef(ArgMask, ModRefC1);
// Conservatively clear IsMustAlias unless only MustAlias is found.
@@ -372,7 +372,7 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call1,
// might Mod Call1ArgLoc, then we care about either a Mod or a Ref by
// Call2. If Call1 might Ref, then we care only about a Mod by Call2.
ModRefInfo ArgModRefC1 = getArgModRefInfo(Call1, Call1ArgIdx);
- ModRefInfo ModRefC2 = getModRefInfo(Call2, Call1ArgLoc, AAQI);
+ ModRefInfo ModRefC2 = getModRefInfo(Call2, Call1ArgLoc, AAQI);
if ((isModSet(ArgModRefC1) && isModOrRefSet(ModRefC2)) ||
(isRefSet(ArgModRefC1) && isModSet(ModRefC2)))
R = intersectModRef(unionModRef(R, ArgModRefC1), Result);
@@ -647,43 +647,43 @@ ModRefInfo AAResults::getModRefInfo(const AtomicRMWInst *RMW,
return ModRefInfo::ModRef;
}
-ModRefInfo AAResults::getModRefInfo(const Instruction *I,
- const Optional<MemoryLocation> &OptLoc,
- AAQueryInfo &AAQIP) {
- if (OptLoc == None) {
- if (const auto *Call = dyn_cast<CallBase>(I)) {
- return createModRefInfo(getModRefBehavior(Call));
- }
- }
-
- const MemoryLocation &Loc = OptLoc.getValueOr(MemoryLocation());
-
- switch (I->getOpcode()) {
- case Instruction::VAArg:
- return getModRefInfo((const VAArgInst *)I, Loc, AAQIP);
- case Instruction::Load:
- return getModRefInfo((const LoadInst *)I, Loc, AAQIP);
- case Instruction::Store:
- return getModRefInfo((const StoreInst *)I, Loc, AAQIP);
- case Instruction::Fence:
- return getModRefInfo((const FenceInst *)I, Loc, AAQIP);
- case Instruction::AtomicCmpXchg:
- return getModRefInfo((const AtomicCmpXchgInst *)I, Loc, AAQIP);
- case Instruction::AtomicRMW:
- return getModRefInfo((const AtomicRMWInst *)I, Loc, AAQIP);
- case Instruction::Call:
- return getModRefInfo((const CallInst *)I, Loc, AAQIP);
- case Instruction::Invoke:
- return getModRefInfo((const InvokeInst *)I, Loc, AAQIP);
- case Instruction::CatchPad:
- return getModRefInfo((const CatchPadInst *)I, Loc, AAQIP);
- case Instruction::CatchRet:
- return getModRefInfo((const CatchReturnInst *)I, Loc, AAQIP);
- default:
- return ModRefInfo::NoModRef;
- }
-}
-
+ModRefInfo AAResults::getModRefInfo(const Instruction *I,
+ const Optional<MemoryLocation> &OptLoc,
+ AAQueryInfo &AAQIP) {
+ if (OptLoc == None) {
+ if (const auto *Call = dyn_cast<CallBase>(I)) {
+ return createModRefInfo(getModRefBehavior(Call));
+ }
+ }
+
+ const MemoryLocation &Loc = OptLoc.getValueOr(MemoryLocation());
+
+ switch (I->getOpcode()) {
+ case Instruction::VAArg:
+ return getModRefInfo((const VAArgInst *)I, Loc, AAQIP);
+ case Instruction::Load:
+ return getModRefInfo((const LoadInst *)I, Loc, AAQIP);
+ case Instruction::Store:
+ return getModRefInfo((const StoreInst *)I, Loc, AAQIP);
+ case Instruction::Fence:
+ return getModRefInfo((const FenceInst *)I, Loc, AAQIP);
+ case Instruction::AtomicCmpXchg:
+ return getModRefInfo((const AtomicCmpXchgInst *)I, Loc, AAQIP);
+ case Instruction::AtomicRMW:
+ return getModRefInfo((const AtomicRMWInst *)I, Loc, AAQIP);
+ case Instruction::Call:
+ return getModRefInfo((const CallInst *)I, Loc, AAQIP);
+ case Instruction::Invoke:
+ return getModRefInfo((const InvokeInst *)I, Loc, AAQIP);
+ case Instruction::CatchPad:
+ return getModRefInfo((const CatchPadInst *)I, Loc, AAQIP);
+ case Instruction::CatchRet:
+ return getModRefInfo((const CatchReturnInst *)I, Loc, AAQIP);
+ default:
+ return ModRefInfo::NoModRef;
+ }
+}
+
/// Return information about whether a particular call site modifies
/// or reads the specified memory location \p MemLoc before instruction \p I
/// in a BasicBlock.
@@ -697,7 +697,7 @@ ModRefInfo AAResults::callCapturesBefore(const Instruction *I,
if (!DT)
return ModRefInfo::ModRef;
- const Value *Object = getUnderlyingObject(MemLoc.Ptr);
+ const Value *Object = getUnderlyingObject(MemLoc.Ptr);
if (!isIdentifiedObject(Object) || isa<GlobalValue>(Object) ||
isa<Constant>(Object))
return ModRefInfo::ModRef;
@@ -725,7 +725,7 @@ ModRefInfo AAResults::callCapturesBefore(const Instruction *I,
!Call->isByValArgument(ArgNo)))
continue;
- AliasResult AR = alias(*CI, Object);
+ AliasResult AR = alias(*CI, Object);
// If this is a no-capture pointer argument, see if we can tell that it
// is impossible to alias the pointer we're checking. If not, we have to
// assume that the call could touch the pointer, even though it doesn't
@@ -883,8 +883,8 @@ bool AAResultsWrapperPass::runOnFunction(Function &F) {
void AAResultsWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
- AU.addRequiredTransitive<BasicAAWrapperPass>();
- AU.addRequiredTransitive<TargetLibraryInfoWrapperPass>();
+ AU.addRequiredTransitive<BasicAAWrapperPass>();
+ AU.addRequiredTransitive<TargetLibraryInfoWrapperPass>();
// We also need to mark all the alias analysis passes we will potentially
// probe in runOnFunction as used here to ensure the legacy pass manager
@@ -900,13 +900,13 @@ void AAResultsWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addUsedIfAvailable<ExternalAAWrapperPass>();
}
-AAManager::Result AAManager::run(Function &F, FunctionAnalysisManager &AM) {
- Result R(AM.getResult<TargetLibraryAnalysis>(F));
- for (auto &Getter : ResultGetters)
- (*Getter)(F, AM, R);
- return R;
-}
-
+AAManager::Result AAManager::run(Function &F, FunctionAnalysisManager &AM) {
+ Result R(AM.getResult<TargetLibraryAnalysis>(F));
+ for (auto &Getter : ResultGetters)
+ (*Getter)(F, AM, R);
+ return R;
+}
+
AAResults llvm::createLegacyPMAAResults(Pass &P, Function &F,
BasicAAResult &BAR) {
AAResults AAR(P.getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F));
@@ -943,9 +943,9 @@ bool llvm::isNoAliasCall(const Value *V) {
return false;
}
-static bool isNoAliasOrByValArgument(const Value *V) {
+static bool isNoAliasOrByValArgument(const Value *V) {
if (const Argument *A = dyn_cast<Argument>(V))
- return A->hasNoAliasAttr() || A->hasByValAttr();
+ return A->hasNoAliasAttr() || A->hasByValAttr();
return false;
}
@@ -956,13 +956,13 @@ bool llvm::isIdentifiedObject(const Value *V) {
return true;
if (isNoAliasCall(V))
return true;
- if (isNoAliasOrByValArgument(V))
- return true;
+ if (isNoAliasOrByValArgument(V))
+ return true;
return false;
}
bool llvm::isIdentifiedFunctionLocal(const Value *V) {
- return isa<AllocaInst>(V) || isNoAliasCall(V) || isNoAliasOrByValArgument(V);
+ return isa<AllocaInst>(V) || isNoAliasCall(V) || isNoAliasOrByValArgument(V);
}
void llvm::getAAResultsAnalysisUsage(AnalysisUsage &AU) {
diff --git a/contrib/libs/llvm12/lib/Analysis/AliasAnalysisEvaluator.cpp b/contrib/libs/llvm12/lib/Analysis/AliasAnalysisEvaluator.cpp
index 89d2641d72..bbfa82bcca 100644
--- a/contrib/libs/llvm12/lib/Analysis/AliasAnalysisEvaluator.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/AliasAnalysisEvaluator.cpp
@@ -140,13 +140,13 @@ void AAEvaluator::runInternal(Function &F, AAResults &AA) {
// iterate over the worklist, and run the full (n^2)/2 disambiguations
for (SetVector<Value *>::iterator I1 = Pointers.begin(), E = Pointers.end();
I1 != E; ++I1) {
- auto I1Size = LocationSize::afterPointer();
+ auto I1Size = LocationSize::afterPointer();
Type *I1ElTy = cast<PointerType>((*I1)->getType())->getElementType();
if (I1ElTy->isSized())
I1Size = LocationSize::precise(DL.getTypeStoreSize(I1ElTy));
for (SetVector<Value *>::iterator I2 = Pointers.begin(); I2 != I1; ++I2) {
- auto I2Size = LocationSize::afterPointer();
+ auto I2Size = LocationSize::afterPointer();
Type *I2ElTy = cast<PointerType>((*I2)->getType())->getElementType();
if (I2ElTy->isSized())
I2Size = LocationSize::precise(DL.getTypeStoreSize(I2ElTy));
@@ -231,7 +231,7 @@ void AAEvaluator::runInternal(Function &F, AAResults &AA) {
// Mod/ref alias analysis: compare all pairs of calls and values
for (CallBase *Call : Calls) {
for (auto Pointer : Pointers) {
- auto Size = LocationSize::afterPointer();
+ auto Size = LocationSize::afterPointer();
Type *ElTy = cast<PointerType>(Pointer->getType())->getElementType();
if (ElTy->isSized())
Size = LocationSize::precise(DL.getTypeStoreSize(ElTy));
diff --git a/contrib/libs/llvm12/lib/Analysis/AliasSetTracker.cpp b/contrib/libs/llvm12/lib/Analysis/AliasSetTracker.cpp
index 118928f1d7..486b4d99df 100644
--- a/contrib/libs/llvm12/lib/Analysis/AliasSetTracker.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/AliasSetTracker.cpp
@@ -23,7 +23,7 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Value.h"
#include "llvm/InitializePasses.h"
@@ -83,7 +83,7 @@ void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST) {
addRef();
}
} else if (ASHadUnknownInsts) {
- llvm::append_range(UnknownInsts, AS.UnknownInsts);
+ llvm::append_range(UnknownInsts, AS.UnknownInsts);
AS.UnknownInsts.clear();
}
@@ -438,9 +438,9 @@ void AliasSetTracker::addUnknown(Instruction *Inst) {
break;
// FIXME: Add lifetime/invariant intrinsics (See: PR30807).
case Intrinsic::assume:
- case Intrinsic::experimental_noalias_scope_decl:
+ case Intrinsic::experimental_noalias_scope_decl:
case Intrinsic::sideeffect:
- case Intrinsic::pseudoprobe:
+ case Intrinsic::pseudoprobe:
return;
}
}
@@ -672,10 +672,10 @@ void AliasSet::print(raw_ostream &OS) const {
for (iterator I = begin(), E = end(); I != E; ++I) {
if (I != begin()) OS << ", ";
I.getPointer()->printAsOperand(OS << "(");
- if (I.getSize() == LocationSize::afterPointer())
- OS << ", unknown after)";
- else if (I.getSize() == LocationSize::beforeOrAfterPointer())
- OS << ", unknown before-or-after)";
+ if (I.getSize() == LocationSize::afterPointer())
+ OS << ", unknown after)";
+ else if (I.getSize() == LocationSize::beforeOrAfterPointer())
+ OS << ", unknown before-or-after)";
else
OS << ", " << I.getSize() << ")";
}
@@ -753,11 +753,11 @@ namespace {
bool runOnFunction(Function &F) override {
auto &AAWP = getAnalysis<AAResultsWrapperPass>();
- AliasSetTracker Tracker(AAWP.getAAResults());
+ AliasSetTracker Tracker(AAWP.getAAResults());
errs() << "Alias sets for function '" << F.getName() << "':\n";
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
- Tracker.add(&*I);
- Tracker.print(errs());
+ Tracker.add(&*I);
+ Tracker.print(errs());
return false;
}
};
@@ -771,16 +771,16 @@ INITIALIZE_PASS_BEGIN(AliasSetPrinter, "print-alias-sets",
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_END(AliasSetPrinter, "print-alias-sets",
"Alias Set Printer", false, true)
-
-AliasSetsPrinterPass::AliasSetsPrinterPass(raw_ostream &OS) : OS(OS) {}
-
-PreservedAnalyses AliasSetsPrinterPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- auto &AA = AM.getResult<AAManager>(F);
- AliasSetTracker Tracker(AA);
- OS << "Alias sets for function '" << F.getName() << "':\n";
- for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
- Tracker.add(&*I);
- Tracker.print(OS);
- return PreservedAnalyses::all();
-}
+
+AliasSetsPrinterPass::AliasSetsPrinterPass(raw_ostream &OS) : OS(OS) {}
+
+PreservedAnalyses AliasSetsPrinterPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ auto &AA = AM.getResult<AAManager>(F);
+ AliasSetTracker Tracker(AA);
+ OS << "Alias sets for function '" << F.getName() << "':\n";
+ for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
+ Tracker.add(&*I);
+ Tracker.print(OS);
+ return PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Analysis/Analysis.cpp b/contrib/libs/llvm12/lib/Analysis/Analysis.cpp
index 848e52bd1b..db51670615 100644
--- a/contrib/libs/llvm12/lib/Analysis/Analysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/Analysis.cpp
@@ -50,20 +50,20 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
initializeAAResultsWrapperPassPass(Registry);
initializeGlobalsAAWrapperPassPass(Registry);
initializeIVUsersWrapperPassPass(Registry);
- initializeInstCountLegacyPassPass(Registry);
+ initializeInstCountLegacyPassPass(Registry);
initializeIntervalPartitionPass(Registry);
- initializeIRSimilarityIdentifierWrapperPassPass(Registry);
+ initializeIRSimilarityIdentifierWrapperPassPass(Registry);
initializeLazyBranchProbabilityInfoPassPass(Registry);
initializeLazyBlockFrequencyInfoPassPass(Registry);
initializeLazyValueInfoWrapperPassPass(Registry);
initializeLazyValueInfoPrinterPass(Registry);
initializeLegacyDivergenceAnalysisPass(Registry);
- initializeLintLegacyPassPass(Registry);
+ initializeLintLegacyPassPass(Registry);
initializeLoopInfoWrapperPassPass(Registry);
initializeMemDepPrinterPass(Registry);
initializeMemDerefPrinterPass(Registry);
initializeMemoryDependenceWrapperPassPass(Registry);
- initializeModuleDebugInfoLegacyPrinterPass(Registry);
+ initializeModuleDebugInfoLegacyPrinterPass(Registry);
initializeModuleSummaryIndexWrapperPassPass(Registry);
initializeMustExecutePrinterPass(Registry);
initializeMustBeExecutedContextPrinterPass(Registry);
diff --git a/contrib/libs/llvm12/lib/Analysis/AssumeBundleQueries.cpp b/contrib/libs/llvm12/lib/Analysis/AssumeBundleQueries.cpp
index eab23ee69a..0084e2f13f 100644
--- a/contrib/libs/llvm12/lib/Analysis/AssumeBundleQueries.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/AssumeBundleQueries.cpp
@@ -108,17 +108,17 @@ llvm::getKnowledgeFromBundle(CallInst &Assume,
Result.AttrKind = Attribute::getAttrKindFromName(BOI.Tag->getKey());
if (bundleHasArgument(BOI, ABA_WasOn))
Result.WasOn = getValueFromBundleOpInfo(Assume, BOI, ABA_WasOn);
- auto GetArgOr1 = [&](unsigned Idx) -> unsigned {
- if (auto *ConstInt = dyn_cast<ConstantInt>(
- getValueFromBundleOpInfo(Assume, BOI, ABA_Argument + Idx)))
- return ConstInt->getZExtValue();
- return 1;
- };
+ auto GetArgOr1 = [&](unsigned Idx) -> unsigned {
+ if (auto *ConstInt = dyn_cast<ConstantInt>(
+ getValueFromBundleOpInfo(Assume, BOI, ABA_Argument + Idx)))
+ return ConstInt->getZExtValue();
+ return 1;
+ };
if (BOI.End - BOI.Begin > ABA_Argument)
- Result.ArgValue = GetArgOr1(0);
- if (Result.AttrKind == Attribute::Alignment)
- if (BOI.End - BOI.Begin > ABA_Argument + 1)
- Result.ArgValue = MinAlign(Result.ArgValue, GetArgOr1(1));
+ Result.ArgValue = GetArgOr1(0);
+ if (Result.AttrKind == Attribute::Alignment)
+ if (BOI.End - BOI.Begin > ABA_Argument + 1)
+ Result.ArgValue = MinAlign(Result.ArgValue, GetArgOr1(1));
return Result;
}
@@ -179,15 +179,15 @@ llvm::getKnowledgeForValue(const Value *V,
if (!II || Elem.Index == AssumptionCache::ExprResultIdx)
continue;
if (RetainedKnowledge RK = getKnowledgeFromBundle(
- *II, II->bundle_op_info_begin()[Elem.Index])) {
- if (V != RK.WasOn)
- continue;
+ *II, II->bundle_op_info_begin()[Elem.Index])) {
+ if (V != RK.WasOn)
+ continue;
if (is_contained(AttrKinds, RK.AttrKind) &&
Filter(RK, II, &II->bundle_op_info_begin()[Elem.Index])) {
NumUsefullAssumeQueries++;
return RK;
}
- }
+ }
}
return RetainedKnowledge::none();
}
diff --git a/contrib/libs/llvm12/lib/Analysis/AssumptionCache.cpp b/contrib/libs/llvm12/lib/Analysis/AssumptionCache.cpp
index 9cd9f1df83..70053fdf8d 100644
--- a/contrib/libs/llvm12/lib/Analysis/AssumptionCache.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/AssumptionCache.cpp
@@ -107,7 +107,7 @@ findAffectedValues(CallInst *CI,
AddAffected(A);
AddAffected(B);
// (A << C) or (A >>_s C) or (A >>_u C) where C is some constant.
- } else if (match(V, m_Shift(m_Value(A), m_ConstantInt()))) {
+ } else if (match(V, m_Shift(m_Value(A), m_ConstantInt()))) {
AddAffected(A);
}
};
@@ -115,14 +115,14 @@ findAffectedValues(CallInst *CI,
AddAffectedFromEq(A);
AddAffectedFromEq(B);
}
-
- Value *X;
- // Handle (A + C1) u< C2, which is the canonical form of A > C3 && A < C4,
- // and recognized by LVI at least.
- if (Pred == ICmpInst::ICMP_ULT &&
- match(A, m_Add(m_Value(X), m_ConstantInt())) &&
- match(B, m_ConstantInt()))
- AddAffected(X);
+
+ Value *X;
+ // Handle (A + C1) u< C2, which is the canonical form of A > C3 && A < C4,
+ // and recognized by LVI at least.
+ if (Pred == ICmpInst::ICMP_ULT &&
+ match(A, m_Add(m_Value(X), m_ConstantInt())) &&
+ match(B, m_ConstantInt()))
+ AddAffected(X);
}
}
@@ -163,11 +163,11 @@ void AssumptionCache::unregisterAssumption(CallInst *CI) {
AffectedValues.erase(AVI);
}
- erase_value(AssumeHandles, CI);
+ erase_value(AssumeHandles, CI);
}
void AssumptionCache::AffectedValueCallbackVH::deleted() {
- AC->AffectedValues.erase(getValPtr());
+ AC->AffectedValues.erase(getValPtr());
// 'this' now dangles!
}
@@ -178,7 +178,7 @@ void AssumptionCache::transferAffectedValuesInCache(Value *OV, Value *NV) {
return;
for (auto &A : AVI->second)
- if (!llvm::is_contained(NAVV, A))
+ if (!llvm::is_contained(NAVV, A))
NAVV.push_back(A);
AffectedValues.erase(OV);
}
diff --git a/contrib/libs/llvm12/lib/Analysis/BasicAliasAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/BasicAliasAnalysis.cpp
index 18b0263ff6..97d0cb63ef 100644
--- a/contrib/libs/llvm12/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/BasicAliasAnalysis.cpp
@@ -14,7 +14,7 @@
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
@@ -67,7 +67,7 @@ using namespace llvm;
/// Enable analysis of recursive PHI nodes.
static cl::opt<bool> EnableRecPhiAnalysis("basic-aa-recphi", cl::Hidden,
- cl::init(true));
+ cl::init(true));
/// By default, even on 32-bit architectures we use 64-bit integers for
/// calculations. This will allow us to more-aggressively decompose indexing
@@ -92,7 +92,7 @@ STATISTIC(SearchTimes, "Number of times a GEP is decomposed");
const unsigned MaxNumPhiBBsValueReachabilityCheck = 20;
// The max limit of the search depth in DecomposeGEPExpression() and
-// getUnderlyingObject(), both functions need to use the same search
+// getUnderlyingObject(), both functions need to use the same search
// depth otherwise the algorithm in aliasGEP will assert.
static const unsigned MaxLookupSearchDepth = 6;
@@ -412,22 +412,22 @@ static unsigned getMaxPointerSize(const DataLayout &DL) {
/// specified amount, but which may have other unrepresented high bits. As
/// such, the gep cannot necessarily be reconstructed from its decomposed form.
///
-/// This function is capable of analyzing everything that getUnderlyingObject
-/// can look through. To be able to do that getUnderlyingObject and
-/// DecomposeGEPExpression must use the same search depth
-/// (MaxLookupSearchDepth).
-BasicAAResult::DecomposedGEP
-BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
- AssumptionCache *AC, DominatorTree *DT) {
+/// This function is capable of analyzing everything that getUnderlyingObject
+/// can look through. To be able to do that getUnderlyingObject and
+/// DecomposeGEPExpression must use the same search depth
+/// (MaxLookupSearchDepth).
+BasicAAResult::DecomposedGEP
+BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
+ AssumptionCache *AC, DominatorTree *DT) {
// Limit recursion depth to limit compile time in crazy cases.
unsigned MaxLookup = MaxLookupSearchDepth;
SearchTimes++;
- const Instruction *CxtI = dyn_cast<Instruction>(V);
+ const Instruction *CxtI = dyn_cast<Instruction>(V);
unsigned MaxPointerSize = getMaxPointerSize(DL);
- DecomposedGEP Decomposed;
- Decomposed.Offset = APInt(MaxPointerSize, 0);
- Decomposed.HasCompileTimeConstantScale = true;
+ DecomposedGEP Decomposed;
+ Decomposed.Offset = APInt(MaxPointerSize, 0);
+ Decomposed.HasCompileTimeConstantScale = true;
do {
// See if this is a bitcast or GEP.
const Operator *Op = dyn_cast<Operator>(V);
@@ -440,7 +440,7 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
}
}
Decomposed.Base = V;
- return Decomposed;
+ return Decomposed;
}
if (Op->getOpcode() == Instruction::BitCast ||
@@ -474,13 +474,13 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
}
Decomposed.Base = V;
- return Decomposed;
+ return Decomposed;
}
// Don't attempt to analyze GEPs over unsized objects.
if (!GEPOp->getSourceElementType()->isSized()) {
Decomposed.Base = V;
- return Decomposed;
+ return Decomposed;
}
// Don't attempt to analyze GEPs if index scale is not a compile-time
@@ -488,7 +488,7 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
if (isa<ScalableVectorType>(GEPOp->getSourceElementType())) {
Decomposed.Base = V;
Decomposed.HasCompileTimeConstantScale = false;
- return Decomposed;
+ return Decomposed;
}
unsigned AS = GEPOp->getPointerAddressSpace();
@@ -507,7 +507,7 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
if (FieldNo == 0)
continue;
- Decomposed.Offset += DL.getStructLayout(STy)->getElementOffset(FieldNo);
+ Decomposed.Offset += DL.getStructLayout(STy)->getElementOffset(FieldNo);
continue;
}
@@ -515,9 +515,9 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
if (const ConstantInt *CIdx = dyn_cast<ConstantInt>(Index)) {
if (CIdx->isZero())
continue;
- Decomposed.Offset +=
- DL.getTypeAllocSize(GTI.getIndexedType()).getFixedSize() *
- CIdx->getValue().sextOrTrunc(MaxPointerSize);
+ Decomposed.Offset +=
+ DL.getTypeAllocSize(GTI.getIndexedType()).getFixedSize() *
+ CIdx->getValue().sextOrTrunc(MaxPointerSize);
continue;
}
@@ -550,10 +550,10 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
// FIXME: C1*Scale and the other operations in the decomposed
// (C1*Scale)*V+C2*Scale can also overflow. We should check for this
// possibility.
- bool Overflow;
- APInt ScaledOffset = IndexOffset.sextOrTrunc(MaxPointerSize)
- .smul_ov(Scale, Overflow);
- if (Overflow) {
+ bool Overflow;
+ APInt ScaledOffset = IndexOffset.sextOrTrunc(MaxPointerSize)
+ .smul_ov(Scale, Overflow);
+ if (Overflow) {
Index = OrigIndex;
IndexScale = 1;
IndexOffset = 0;
@@ -562,7 +562,7 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
if (PointerSize > Width)
SExtBits += PointerSize - Width;
} else {
- Decomposed.Offset += ScaledOffset;
+ Decomposed.Offset += ScaledOffset;
Scale *= IndexScale.sextOrTrunc(MaxPointerSize);
}
@@ -585,14 +585,14 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
Scale = adjustToPointerSize(Scale, PointerSize);
if (!!Scale) {
- VariableGEPIndex Entry = {Index, ZExtBits, SExtBits, Scale, CxtI};
+ VariableGEPIndex Entry = {Index, ZExtBits, SExtBits, Scale, CxtI};
Decomposed.VarIndices.push_back(Entry);
}
}
// Take care of wrap-arounds
- if (GepHasConstantOffset)
- Decomposed.Offset = adjustToPointerSize(Decomposed.Offset, PointerSize);
+ if (GepHasConstantOffset)
+ Decomposed.Offset = adjustToPointerSize(Decomposed.Offset, PointerSize);
// Analyze the base pointer next.
V = GEPOp->getOperand(0);
@@ -601,7 +601,7 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
// If the chain of expressions is too deep, just return early.
Decomposed.Base = V;
SearchLimitReached++;
- return Decomposed;
+ return Decomposed;
}
/// Returns whether the given pointer value points to memory that is local to
@@ -615,7 +615,7 @@ bool BasicAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
SmallVector<const Value *, 16> Worklist;
Worklist.push_back(Loc.Ptr);
do {
- const Value *V = getUnderlyingObject(Worklist.pop_back_val());
+ const Value *V = getUnderlyingObject(Worklist.pop_back_val());
if (!Visited.insert(V).second) {
Visited.clear();
return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
@@ -652,7 +652,7 @@ bool BasicAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
Visited.clear();
return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
}
- append_range(Worklist, PN->incoming_values());
+ append_range(Worklist, PN->incoming_values());
continue;
}
@@ -797,8 +797,8 @@ AliasResult BasicAAResult::alias(const MemoryLocation &LocA,
AAQueryInfo &AAQI) {
assert(notDifferentParent(LocA.Ptr, LocB.Ptr) &&
"BasicAliasAnalysis doesn't support interprocedural queries.");
- return aliasCheck(LocA.Ptr, LocA.Size, LocA.AATags, LocB.Ptr, LocB.Size,
- LocB.AATags, AAQI);
+ return aliasCheck(LocA.Ptr, LocA.Size, LocA.AATags, LocB.Ptr, LocB.Size,
+ LocB.AATags, AAQI);
}
/// Checks to see if the specified callsite can clobber the specified memory
@@ -813,7 +813,7 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
assert(notDifferentParent(Call, Loc.Ptr) &&
"AliasAnalysis query involving multiple functions!");
- const Value *Object = getUnderlyingObject(Loc.Ptr);
+ const Value *Object = getUnderlyingObject(Loc.Ptr);
// Calls marked 'tail' cannot read or write allocas from the current frame
// because the current frame might be destroyed by the time they run. However,
@@ -862,9 +862,9 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
// If this is a no-capture pointer argument, see if we can tell that it
// is impossible to alias the pointer we're checking.
- AliasResult AR = getBestAAResults().alias(
- MemoryLocation::getBeforeOrAfter(*CI),
- MemoryLocation::getBeforeOrAfter(Object), AAQI);
+ AliasResult AR = getBestAAResults().alias(
+ MemoryLocation::getBeforeOrAfter(*CI),
+ MemoryLocation::getBeforeOrAfter(Object), AAQI);
if (AR != MustAlias)
IsMustAlias = false;
// Operand doesn't alias 'Object', continue looking for other aliases
@@ -910,19 +910,19 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
if (isMallocOrCallocLikeFn(Call, &TLI)) {
// Be conservative if the accessed pointer may alias the allocation -
// fallback to the generic handling below.
- if (getBestAAResults().alias(MemoryLocation::getBeforeOrAfter(Call),
- Loc, AAQI) == NoAlias)
+ if (getBestAAResults().alias(MemoryLocation::getBeforeOrAfter(Call),
+ Loc, AAQI) == NoAlias)
return ModRefInfo::NoModRef;
}
- // The semantics of memcpy intrinsics either exactly overlap or do not
- // overlap, i.e., source and destination of any given memcpy are either
- // no-alias or must-alias.
+ // The semantics of memcpy intrinsics either exactly overlap or do not
+ // overlap, i.e., source and destination of any given memcpy are either
+ // no-alias or must-alias.
if (auto *Inst = dyn_cast<AnyMemCpyInst>(Call)) {
- AliasResult SrcAA =
- getBestAAResults().alias(MemoryLocation::getForSource(Inst), Loc, AAQI);
- AliasResult DestAA =
- getBestAAResults().alias(MemoryLocation::getForDest(Inst), Loc, AAQI);
+ AliasResult SrcAA =
+ getBestAAResults().alias(MemoryLocation::getForSource(Inst), Loc, AAQI);
+ AliasResult DestAA =
+ getBestAAResults().alias(MemoryLocation::getForDest(Inst), Loc, AAQI);
// It's also possible for Loc to alias both src and dest, or neither.
ModRefInfo rv = ModRefInfo::NoModRef;
if (SrcAA != NoAlias)
@@ -947,9 +947,9 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
// the guard invokes the "deopt" continuation.
if (isIntrinsicCall(Call, Intrinsic::experimental_guard))
return ModRefInfo::Ref;
- // The same applies to deoptimize which is essentially a guard(false).
- if (isIntrinsicCall(Call, Intrinsic::experimental_deoptimize))
- return ModRefInfo::Ref;
+ // The same applies to deoptimize which is essentially a guard(false).
+ if (isIntrinsicCall(Call, Intrinsic::experimental_deoptimize))
+ return ModRefInfo::Ref;
// Like assumes, invariant.start intrinsics were also marked as arbitrarily
// writing so that proper control dependencies are maintained but they never
@@ -1051,7 +1051,7 @@ bool BasicAAResult::isGEPBaseAtNegativeOffset(const GEPOperator *GEPOp,
const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompObject,
LocationSize MaybeObjectAccessSize) {
// If the object access size is unknown, or the GEP isn't inbounds, bail.
- if (!MaybeObjectAccessSize.hasValue() || !GEPOp->isInBounds())
+ if (!MaybeObjectAccessSize.hasValue() || !GEPOp->isInBounds())
return false;
const uint64_t ObjectAccessSize = MaybeObjectAccessSize.getValue();
@@ -1071,21 +1071,21 @@ bool BasicAAResult::isGEPBaseAtNegativeOffset(const GEPOperator *GEPOp,
if (!DecompGEP.VarIndices.empty())
return false;
- return DecompGEP.Offset.sge(DecompObject.Offset + (int64_t)ObjectAccessSize);
+ return DecompGEP.Offset.sge(DecompObject.Offset + (int64_t)ObjectAccessSize);
}
/// Provides a bunch of ad-hoc rules to disambiguate a GEP instruction against
/// another pointer.
///
/// We know that V1 is a GEP, but we don't know anything about V2.
-/// UnderlyingV1 is getUnderlyingObject(GEP1), UnderlyingV2 is the same for
+/// UnderlyingV1 is getUnderlyingObject(GEP1), UnderlyingV2 is the same for
/// V2.
AliasResult BasicAAResult::aliasGEP(
const GEPOperator *GEP1, LocationSize V1Size, const AAMDNodes &V1AAInfo,
const Value *V2, LocationSize V2Size, const AAMDNodes &V2AAInfo,
const Value *UnderlyingV1, const Value *UnderlyingV2, AAQueryInfo &AAQI) {
- DecomposedGEP DecompGEP1 = DecomposeGEPExpression(GEP1, DL, &AC, DT);
- DecomposedGEP DecompGEP2 = DecomposeGEPExpression(V2, DL, &AC, DT);
+ DecomposedGEP DecompGEP1 = DecomposeGEPExpression(GEP1, DL, &AC, DT);
+ DecomposedGEP DecompGEP2 = DecomposeGEPExpression(V2, DL, &AC, DT);
// Don't attempt to analyze the decomposed GEP if index scale is not a
// compile-time constant.
@@ -1095,12 +1095,12 @@ AliasResult BasicAAResult::aliasGEP(
assert(DecompGEP1.Base == UnderlyingV1 && DecompGEP2.Base == UnderlyingV2 &&
"DecomposeGEPExpression returned a result different from "
- "getUnderlyingObject");
+ "getUnderlyingObject");
// If the GEP's offset relative to its base is such that the base would
// fall below the start of the object underlying V2, then the GEP and V2
// cannot alias.
- if (isGEPBaseAtNegativeOffset(GEP1, DecompGEP1, DecompGEP2, V2Size))
+ if (isGEPBaseAtNegativeOffset(GEP1, DecompGEP1, DecompGEP2, V2Size))
return NoAlias;
// If we have two gep instructions with must-alias or not-alias'ing base
// pointers, figure out if the indexes to the GEP tell us anything about the
@@ -1108,22 +1108,22 @@ AliasResult BasicAAResult::aliasGEP(
if (const GEPOperator *GEP2 = dyn_cast<GEPOperator>(V2)) {
// Check for the GEP base being at a negative offset, this time in the other
// direction.
- if (isGEPBaseAtNegativeOffset(GEP2, DecompGEP2, DecompGEP1, V1Size))
+ if (isGEPBaseAtNegativeOffset(GEP2, DecompGEP2, DecompGEP1, V1Size))
return NoAlias;
// Do the base pointers alias?
- AliasResult BaseAlias = getBestAAResults().alias(
- MemoryLocation::getBeforeOrAfter(UnderlyingV1),
- MemoryLocation::getBeforeOrAfter(UnderlyingV2), AAQI);
-
- // For GEPs with identical offsets, we can preserve the size and AAInfo
- // when performing the alias check on the underlying objects.
- if (BaseAlias == MayAlias && DecompGEP1.Offset == DecompGEP2.Offset &&
- DecompGEP1.VarIndices == DecompGEP2.VarIndices) {
- AliasResult PreciseBaseAlias = getBestAAResults().alias(
- MemoryLocation(UnderlyingV1, V1Size, V1AAInfo),
- MemoryLocation(UnderlyingV2, V2Size, V2AAInfo), AAQI);
- if (PreciseBaseAlias == NoAlias)
- return NoAlias;
+ AliasResult BaseAlias = getBestAAResults().alias(
+ MemoryLocation::getBeforeOrAfter(UnderlyingV1),
+ MemoryLocation::getBeforeOrAfter(UnderlyingV2), AAQI);
+
+ // For GEPs with identical offsets, we can preserve the size and AAInfo
+ // when performing the alias check on the underlying objects.
+ if (BaseAlias == MayAlias && DecompGEP1.Offset == DecompGEP2.Offset &&
+ DecompGEP1.VarIndices == DecompGEP2.VarIndices) {
+ AliasResult PreciseBaseAlias = getBestAAResults().alias(
+ MemoryLocation(UnderlyingV1, V1Size, V1AAInfo),
+ MemoryLocation(UnderlyingV2, V2Size, V2AAInfo), AAQI);
+ if (PreciseBaseAlias == NoAlias)
+ return NoAlias;
}
// If we get a No or May, then return it immediately, no amount of analysis
@@ -1135,7 +1135,7 @@ AliasResult BasicAAResult::aliasGEP(
// Subtract the GEP2 pointer from the GEP1 pointer to find out their
// symbolic difference.
- DecompGEP1.Offset -= DecompGEP2.Offset;
+ DecompGEP1.Offset -= DecompGEP2.Offset;
GetIndexDifference(DecompGEP1.VarIndices, DecompGEP2.VarIndices);
} else {
@@ -1144,12 +1144,12 @@ AliasResult BasicAAResult::aliasGEP(
// pointer, we know they cannot alias.
// If both accesses are unknown size, we can't do anything useful here.
- if (!V1Size.hasValue() && !V2Size.hasValue())
+ if (!V1Size.hasValue() && !V2Size.hasValue())
return MayAlias;
- AliasResult R = getBestAAResults().alias(
- MemoryLocation::getBeforeOrAfter(UnderlyingV1),
- MemoryLocation(V2, V2Size, V2AAInfo), AAQI);
+ AliasResult R = getBestAAResults().alias(
+ MemoryLocation::getBeforeOrAfter(UnderlyingV1),
+ MemoryLocation(V2, V2Size, V2AAInfo), AAQI);
if (R != MustAlias) {
// If V2 may alias GEP base pointer, conservatively returns MayAlias.
// If V2 is known not to alias GEP base pointer, then the two values
@@ -1167,17 +1167,17 @@ AliasResult BasicAAResult::aliasGEP(
//
// In the other case, if we have getelementptr <ptr>, 0, 0, 0, 0, ... and V2
// must aliases the GEP, the end result is a must alias also.
- if (DecompGEP1.Offset == 0 && DecompGEP1.VarIndices.empty())
+ if (DecompGEP1.Offset == 0 && DecompGEP1.VarIndices.empty())
return MustAlias;
// If there is a constant difference between the pointers, but the difference
// is less than the size of the associated memory object, then we know
// that the objects are partially overlapping. If the difference is
// greater, we know they do not overlap.
- if (DecompGEP1.Offset != 0 && DecompGEP1.VarIndices.empty()) {
- if (DecompGEP1.Offset.sge(0)) {
- if (V2Size.hasValue()) {
- if (DecompGEP1.Offset.ult(V2Size.getValue()))
+ if (DecompGEP1.Offset != 0 && DecompGEP1.VarIndices.empty()) {
+ if (DecompGEP1.Offset.sge(0)) {
+ if (V2Size.hasValue()) {
+ if (DecompGEP1.Offset.ult(V2Size.getValue()))
return PartialAlias;
return NoAlias;
}
@@ -1188,8 +1188,8 @@ AliasResult BasicAAResult::aliasGEP(
// ---------------->|
// |-->V1Size |-------> V2Size
// GEP1 V2
- if (V1Size.hasValue()) {
- if ((-DecompGEP1.Offset).ult(V1Size.getValue()))
+ if (V1Size.hasValue()) {
+ if ((-DecompGEP1.Offset).ult(V1Size.getValue()))
return PartialAlias;
return NoAlias;
}
@@ -1197,24 +1197,24 @@ AliasResult BasicAAResult::aliasGEP(
}
if (!DecompGEP1.VarIndices.empty()) {
- APInt GCD;
- bool AllNonNegative = DecompGEP1.Offset.isNonNegative();
- bool AllNonPositive = DecompGEP1.Offset.isNonPositive();
+ APInt GCD;
+ bool AllNonNegative = DecompGEP1.Offset.isNonNegative();
+ bool AllNonPositive = DecompGEP1.Offset.isNonPositive();
for (unsigned i = 0, e = DecompGEP1.VarIndices.size(); i != e; ++i) {
- const APInt &Scale = DecompGEP1.VarIndices[i].Scale;
- if (i == 0)
- GCD = Scale.abs();
- else
- GCD = APIntOps::GreatestCommonDivisor(GCD, Scale.abs());
+ const APInt &Scale = DecompGEP1.VarIndices[i].Scale;
+ if (i == 0)
+ GCD = Scale.abs();
+ else
+ GCD = APIntOps::GreatestCommonDivisor(GCD, Scale.abs());
- if (AllNonNegative || AllNonPositive) {
+ if (AllNonNegative || AllNonPositive) {
// If the Value could change between cycles, then any reasoning about
// the Value this cycle may not hold in the next cycle. We'll just
// give up if we can't determine conditions that hold for every cycle:
const Value *V = DecompGEP1.VarIndices[i].V;
- const Instruction *CxtI = DecompGEP1.VarIndices[i].CxtI;
+ const Instruction *CxtI = DecompGEP1.VarIndices[i].CxtI;
- KnownBits Known = computeKnownBits(V, DL, 0, &AC, CxtI, DT);
+ KnownBits Known = computeKnownBits(V, DL, 0, &AC, CxtI, DT);
bool SignKnownZero = Known.isNonNegative();
bool SignKnownOne = Known.isNegative();
@@ -1224,77 +1224,77 @@ AliasResult BasicAAResult::aliasGEP(
SignKnownZero |= IsZExt;
SignKnownOne &= !IsZExt;
- AllNonNegative &= (SignKnownZero && Scale.isNonNegative()) ||
- (SignKnownOne && Scale.isNonPositive());
- AllNonPositive &= (SignKnownZero && Scale.isNonPositive()) ||
- (SignKnownOne && Scale.isNonNegative());
+ AllNonNegative &= (SignKnownZero && Scale.isNonNegative()) ||
+ (SignKnownOne && Scale.isNonPositive());
+ AllNonPositive &= (SignKnownZero && Scale.isNonPositive()) ||
+ (SignKnownOne && Scale.isNonNegative());
}
}
- // We now have accesses at two offsets from the same base:
- // 1. (...)*GCD + DecompGEP1.Offset with size V1Size
- // 2. 0 with size V2Size
- // Using arithmetic modulo GCD, the accesses are at
- // [ModOffset..ModOffset+V1Size) and [0..V2Size). If the first access fits
- // into the range [V2Size..GCD), then we know they cannot overlap.
- APInt ModOffset = DecompGEP1.Offset.srem(GCD);
- if (ModOffset.isNegative())
- ModOffset += GCD; // We want mod, not rem.
- if (V1Size.hasValue() && V2Size.hasValue() &&
- ModOffset.uge(V2Size.getValue()) &&
- (GCD - ModOffset).uge(V1Size.getValue()))
+ // We now have accesses at two offsets from the same base:
+ // 1. (...)*GCD + DecompGEP1.Offset with size V1Size
+ // 2. 0 with size V2Size
+ // Using arithmetic modulo GCD, the accesses are at
+ // [ModOffset..ModOffset+V1Size) and [0..V2Size). If the first access fits
+ // into the range [V2Size..GCD), then we know they cannot overlap.
+ APInt ModOffset = DecompGEP1.Offset.srem(GCD);
+ if (ModOffset.isNegative())
+ ModOffset += GCD; // We want mod, not rem.
+ if (V1Size.hasValue() && V2Size.hasValue() &&
+ ModOffset.uge(V2Size.getValue()) &&
+ (GCD - ModOffset).uge(V1Size.getValue()))
return NoAlias;
- // If we know all the variables are non-negative, then the total offset is
- // also non-negative and >= DecompGEP1.Offset. We have the following layout:
- // [0, V2Size) ... [TotalOffset, TotalOffer+V1Size]
- // If DecompGEP1.Offset >= V2Size, the accesses don't alias.
- if (AllNonNegative && V2Size.hasValue() &&
- DecompGEP1.Offset.uge(V2Size.getValue()))
+ // If we know all the variables are non-negative, then the total offset is
+ // also non-negative and >= DecompGEP1.Offset. We have the following layout:
+ // [0, V2Size) ... [TotalOffset, TotalOffer+V1Size]
+ // If DecompGEP1.Offset >= V2Size, the accesses don't alias.
+ if (AllNonNegative && V2Size.hasValue() &&
+ DecompGEP1.Offset.uge(V2Size.getValue()))
+ return NoAlias;
+ // Similarly, if the variables are non-positive, then the total offset is
+ // also non-positive and <= DecompGEP1.Offset. We have the following layout:
+ // [TotalOffset, TotalOffset+V1Size) ... [0, V2Size)
+ // If -DecompGEP1.Offset >= V1Size, the accesses don't alias.
+ if (AllNonPositive && V1Size.hasValue() &&
+ (-DecompGEP1.Offset).uge(V1Size.getValue()))
return NoAlias;
- // Similarly, if the variables are non-positive, then the total offset is
- // also non-positive and <= DecompGEP1.Offset. We have the following layout:
- // [TotalOffset, TotalOffset+V1Size) ... [0, V2Size)
- // If -DecompGEP1.Offset >= V1Size, the accesses don't alias.
- if (AllNonPositive && V1Size.hasValue() &&
- (-DecompGEP1.Offset).uge(V1Size.getValue()))
- return NoAlias;
-
- if (V1Size.hasValue() && V2Size.hasValue()) {
- // Try to determine whether abs(VarIndex) > 0.
- Optional<APInt> MinAbsVarIndex;
- if (DecompGEP1.VarIndices.size() == 1) {
- // VarIndex = Scale*V. If V != 0 then abs(VarIndex) >= abs(Scale).
- const VariableGEPIndex &Var = DecompGEP1.VarIndices[0];
- if (isKnownNonZero(Var.V, DL, 0, &AC, Var.CxtI, DT))
- MinAbsVarIndex = Var.Scale.abs();
- } else if (DecompGEP1.VarIndices.size() == 2) {
- // VarIndex = Scale*V0 + (-Scale)*V1.
- // If V0 != V1 then abs(VarIndex) >= abs(Scale).
- // Check that VisitedPhiBBs is empty, to avoid reasoning about
- // inequality of values across loop iterations.
- const VariableGEPIndex &Var0 = DecompGEP1.VarIndices[0];
- const VariableGEPIndex &Var1 = DecompGEP1.VarIndices[1];
- if (Var0.Scale == -Var1.Scale && Var0.ZExtBits == Var1.ZExtBits &&
- Var0.SExtBits == Var1.SExtBits && VisitedPhiBBs.empty() &&
- isKnownNonEqual(Var0.V, Var1.V, DL, &AC, /* CxtI */ nullptr, DT))
- MinAbsVarIndex = Var0.Scale.abs();
- }
-
- if (MinAbsVarIndex) {
- // The constant offset will have added at least +/-MinAbsVarIndex to it.
- APInt OffsetLo = DecompGEP1.Offset - *MinAbsVarIndex;
- APInt OffsetHi = DecompGEP1.Offset + *MinAbsVarIndex;
- // Check that an access at OffsetLo or lower, and an access at OffsetHi
- // or higher both do not alias.
- if (OffsetLo.isNegative() && (-OffsetLo).uge(V1Size.getValue()) &&
- OffsetHi.isNonNegative() && OffsetHi.uge(V2Size.getValue()))
- return NoAlias;
- }
- }
-
+
+ if (V1Size.hasValue() && V2Size.hasValue()) {
+ // Try to determine whether abs(VarIndex) > 0.
+ Optional<APInt> MinAbsVarIndex;
+ if (DecompGEP1.VarIndices.size() == 1) {
+ // VarIndex = Scale*V. If V != 0 then abs(VarIndex) >= abs(Scale).
+ const VariableGEPIndex &Var = DecompGEP1.VarIndices[0];
+ if (isKnownNonZero(Var.V, DL, 0, &AC, Var.CxtI, DT))
+ MinAbsVarIndex = Var.Scale.abs();
+ } else if (DecompGEP1.VarIndices.size() == 2) {
+ // VarIndex = Scale*V0 + (-Scale)*V1.
+ // If V0 != V1 then abs(VarIndex) >= abs(Scale).
+ // Check that VisitedPhiBBs is empty, to avoid reasoning about
+ // inequality of values across loop iterations.
+ const VariableGEPIndex &Var0 = DecompGEP1.VarIndices[0];
+ const VariableGEPIndex &Var1 = DecompGEP1.VarIndices[1];
+ if (Var0.Scale == -Var1.Scale && Var0.ZExtBits == Var1.ZExtBits &&
+ Var0.SExtBits == Var1.SExtBits && VisitedPhiBBs.empty() &&
+ isKnownNonEqual(Var0.V, Var1.V, DL, &AC, /* CxtI */ nullptr, DT))
+ MinAbsVarIndex = Var0.Scale.abs();
+ }
+
+ if (MinAbsVarIndex) {
+ // The constant offset will have added at least +/-MinAbsVarIndex to it.
+ APInt OffsetLo = DecompGEP1.Offset - *MinAbsVarIndex;
+ APInt OffsetHi = DecompGEP1.Offset + *MinAbsVarIndex;
+ // Check that an access at OffsetLo or lower, and an access at OffsetHi
+ // or higher both do not alias.
+ if (OffsetLo.isNegative() && (-OffsetLo).uge(V1Size.getValue()) &&
+ OffsetHi.isNonNegative() && OffsetHi.uge(V2Size.getValue()))
+ return NoAlias;
+ }
+ }
+
if (constantOffsetHeuristic(DecompGEP1.VarIndices, V1Size, V2Size,
- DecompGEP1.Offset, &AC, DT))
+ DecompGEP1.Offset, &AC, DT))
return NoAlias;
}
@@ -1322,33 +1322,33 @@ AliasResult
BasicAAResult::aliasSelect(const SelectInst *SI, LocationSize SISize,
const AAMDNodes &SIAAInfo, const Value *V2,
LocationSize V2Size, const AAMDNodes &V2AAInfo,
- AAQueryInfo &AAQI) {
+ AAQueryInfo &AAQI) {
// If the values are Selects with the same condition, we can do a more precise
// check: just check for aliases between the values on corresponding arms.
if (const SelectInst *SI2 = dyn_cast<SelectInst>(V2))
if (SI->getCondition() == SI2->getCondition()) {
- AliasResult Alias = getBestAAResults().alias(
- MemoryLocation(SI->getTrueValue(), SISize, SIAAInfo),
- MemoryLocation(SI2->getTrueValue(), V2Size, V2AAInfo), AAQI);
+ AliasResult Alias = getBestAAResults().alias(
+ MemoryLocation(SI->getTrueValue(), SISize, SIAAInfo),
+ MemoryLocation(SI2->getTrueValue(), V2Size, V2AAInfo), AAQI);
if (Alias == MayAlias)
return MayAlias;
- AliasResult ThisAlias = getBestAAResults().alias(
- MemoryLocation(SI->getFalseValue(), SISize, SIAAInfo),
- MemoryLocation(SI2->getFalseValue(), V2Size, V2AAInfo), AAQI);
+ AliasResult ThisAlias = getBestAAResults().alias(
+ MemoryLocation(SI->getFalseValue(), SISize, SIAAInfo),
+ MemoryLocation(SI2->getFalseValue(), V2Size, V2AAInfo), AAQI);
return MergeAliasResults(ThisAlias, Alias);
}
// If both arms of the Select node NoAlias or MustAlias V2, then returns
// NoAlias / MustAlias. Otherwise, returns MayAlias.
- AliasResult Alias = getBestAAResults().alias(
- MemoryLocation(V2, V2Size, V2AAInfo),
- MemoryLocation(SI->getTrueValue(), SISize, SIAAInfo), AAQI);
+ AliasResult Alias = getBestAAResults().alias(
+ MemoryLocation(V2, V2Size, V2AAInfo),
+ MemoryLocation(SI->getTrueValue(), SISize, SIAAInfo), AAQI);
if (Alias == MayAlias)
return MayAlias;
- AliasResult ThisAlias = getBestAAResults().alias(
- MemoryLocation(V2, V2Size, V2AAInfo),
- MemoryLocation(SI->getFalseValue(), SISize, SIAAInfo), AAQI);
+ AliasResult ThisAlias = getBestAAResults().alias(
+ MemoryLocation(V2, V2Size, V2AAInfo),
+ MemoryLocation(SI->getFalseValue(), SISize, SIAAInfo), AAQI);
return MergeAliasResults(ThisAlias, Alias);
}
@@ -1358,41 +1358,41 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, LocationSize PNSize,
const AAMDNodes &PNAAInfo, const Value *V2,
LocationSize V2Size,
const AAMDNodes &V2AAInfo,
- AAQueryInfo &AAQI) {
+ AAQueryInfo &AAQI) {
// If the values are PHIs in the same block, we can do a more precise
// as well as efficient check: just check for aliases between the values
// on corresponding edges.
if (const PHINode *PN2 = dyn_cast<PHINode>(V2))
if (PN2->getParent() == PN->getParent()) {
- Optional<AliasResult> Alias;
+ Optional<AliasResult> Alias;
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
- AliasResult ThisAlias = getBestAAResults().alias(
- MemoryLocation(PN->getIncomingValue(i), PNSize, PNAAInfo),
- MemoryLocation(
- PN2->getIncomingValueForBlock(PN->getIncomingBlock(i)), V2Size,
- V2AAInfo),
- AAQI);
- if (Alias)
- *Alias = MergeAliasResults(*Alias, ThisAlias);
- else
- Alias = ThisAlias;
- if (*Alias == MayAlias)
+ AliasResult ThisAlias = getBestAAResults().alias(
+ MemoryLocation(PN->getIncomingValue(i), PNSize, PNAAInfo),
+ MemoryLocation(
+ PN2->getIncomingValueForBlock(PN->getIncomingBlock(i)), V2Size,
+ V2AAInfo),
+ AAQI);
+ if (Alias)
+ *Alias = MergeAliasResults(*Alias, ThisAlias);
+ else
+ Alias = ThisAlias;
+ if (*Alias == MayAlias)
break;
}
- return *Alias;
+ return *Alias;
}
SmallVector<Value *, 4> V1Srcs;
- // If a phi operand recurses back to the phi, we can still determine NoAlias
- // if we don't alias the underlying objects of the other phi operands, as we
- // know that the recursive phi needs to be based on them in some way.
+ // If a phi operand recurses back to the phi, we can still determine NoAlias
+ // if we don't alias the underlying objects of the other phi operands, as we
+ // know that the recursive phi needs to be based on them in some way.
bool isRecursive = false;
auto CheckForRecPhi = [&](Value *PV) {
if (!EnableRecPhiAnalysis)
return false;
- if (getUnderlyingObject(PV) == PN) {
- isRecursive = true;
- return true;
+ if (getUnderlyingObject(PV) == PN) {
+ isRecursive = true;
+ return true;
}
return false;
};
@@ -1438,31 +1438,31 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, LocationSize PNSize,
if (V1Srcs.empty())
return MayAlias;
- // If this PHI node is recursive, indicate that the pointer may be moved
- // across iterations. We can only prove NoAlias if different underlying
- // objects are involved.
+ // If this PHI node is recursive, indicate that the pointer may be moved
+ // across iterations. We can only prove NoAlias if different underlying
+ // objects are involved.
if (isRecursive)
- PNSize = LocationSize::beforeOrAfterPointer();
-
- // In the recursive alias queries below, we may compare values from two
- // different loop iterations. Keep track of visited phi blocks, which will
- // be used when determining value equivalence.
- bool BlockInserted = VisitedPhiBBs.insert(PN->getParent()).second;
- auto _ = make_scope_exit([&]() {
- if (BlockInserted)
- VisitedPhiBBs.erase(PN->getParent());
- });
-
- // If we inserted a block into VisitedPhiBBs, alias analysis results that
- // have been cached earlier may no longer be valid. Perform recursive queries
- // with a new AAQueryInfo.
- AAQueryInfo NewAAQI;
- AAQueryInfo *UseAAQI = BlockInserted ? &NewAAQI : &AAQI;
-
- AliasResult Alias = getBestAAResults().alias(
- MemoryLocation(V2, V2Size, V2AAInfo),
- MemoryLocation(V1Srcs[0], PNSize, PNAAInfo), *UseAAQI);
-
+ PNSize = LocationSize::beforeOrAfterPointer();
+
+ // In the recursive alias queries below, we may compare values from two
+ // different loop iterations. Keep track of visited phi blocks, which will
+ // be used when determining value equivalence.
+ bool BlockInserted = VisitedPhiBBs.insert(PN->getParent()).second;
+ auto _ = make_scope_exit([&]() {
+ if (BlockInserted)
+ VisitedPhiBBs.erase(PN->getParent());
+ });
+
+ // If we inserted a block into VisitedPhiBBs, alias analysis results that
+ // have been cached earlier may no longer be valid. Perform recursive queries
+ // with a new AAQueryInfo.
+ AAQueryInfo NewAAQI;
+ AAQueryInfo *UseAAQI = BlockInserted ? &NewAAQI : &AAQI;
+
+ AliasResult Alias = getBestAAResults().alias(
+ MemoryLocation(V2, V2Size, V2AAInfo),
+ MemoryLocation(V1Srcs[0], PNSize, PNAAInfo), *UseAAQI);
+
// Early exit if the check of the first PHI source against V2 is MayAlias.
// Other results are not possible.
if (Alias == MayAlias)
@@ -1477,9 +1477,9 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, LocationSize PNSize,
for (unsigned i = 1, e = V1Srcs.size(); i != e; ++i) {
Value *V = V1Srcs[i];
- AliasResult ThisAlias = getBestAAResults().alias(
- MemoryLocation(V2, V2Size, V2AAInfo),
- MemoryLocation(V, PNSize, PNAAInfo), *UseAAQI);
+ AliasResult ThisAlias = getBestAAResults().alias(
+ MemoryLocation(V2, V2Size, V2AAInfo),
+ MemoryLocation(V, PNSize, PNAAInfo), *UseAAQI);
Alias = MergeAliasResults(ThisAlias, Alias);
if (Alias == MayAlias)
break;
@@ -1491,10 +1491,10 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, LocationSize PNSize,
/// Provides a bunch of ad-hoc rules to disambiguate in common cases, such as
/// array references.
AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
- const AAMDNodes &V1AAInfo,
- const Value *V2, LocationSize V2Size,
- const AAMDNodes &V2AAInfo,
- AAQueryInfo &AAQI) {
+ const AAMDNodes &V1AAInfo,
+ const Value *V2, LocationSize V2Size,
+ const AAMDNodes &V2AAInfo,
+ AAQueryInfo &AAQI) {
// If either of the memory references is empty, it doesn't matter what the
// pointer values are.
if (V1Size.isZero() || V2Size.isZero())
@@ -1522,8 +1522,8 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
return NoAlias; // Scalars cannot alias each other
// Figure out what objects these things are pointing to if we can.
- const Value *O1 = getUnderlyingObject(V1, MaxLookupSearchDepth);
- const Value *O2 = getUnderlyingObject(V2, MaxLookupSearchDepth);
+ const Value *O1 = getUnderlyingObject(V1, MaxLookupSearchDepth);
+ const Value *O2 = getUnderlyingObject(V2, MaxLookupSearchDepth);
// Null values in the default address space don't point to any object, so they
// don't alias any other pointer.
@@ -1578,120 +1578,120 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
TLI, NullIsValidLocation)))
return NoAlias;
- // If one the accesses may be before the accessed pointer, canonicalize this
- // by using unknown after-pointer sizes for both accesses. This is
- // equivalent, because regardless of which pointer is lower, one of them
- // will always came after the other, as long as the underlying objects aren't
- // disjoint. We do this so that the rest of BasicAA does not have to deal
- // with accesses before the base pointer, and to improve cache utilization by
- // merging equivalent states.
- if (V1Size.mayBeBeforePointer() || V2Size.mayBeBeforePointer()) {
- V1Size = LocationSize::afterPointer();
- V2Size = LocationSize::afterPointer();
- }
-
+ // If one the accesses may be before the accessed pointer, canonicalize this
+ // by using unknown after-pointer sizes for both accesses. This is
+ // equivalent, because regardless of which pointer is lower, one of them
+ // will always came after the other, as long as the underlying objects aren't
+ // disjoint. We do this so that the rest of BasicAA does not have to deal
+ // with accesses before the base pointer, and to improve cache utilization by
+ // merging equivalent states.
+ if (V1Size.mayBeBeforePointer() || V2Size.mayBeBeforePointer()) {
+ V1Size = LocationSize::afterPointer();
+ V2Size = LocationSize::afterPointer();
+ }
+
// Check the cache before climbing up use-def chains. This also terminates
// otherwise infinitely recursive queries.
AAQueryInfo::LocPair Locs(MemoryLocation(V1, V1Size, V1AAInfo),
MemoryLocation(V2, V2Size, V2AAInfo));
if (V1 > V2)
std::swap(Locs.first, Locs.second);
- const auto &Pair = AAQI.AliasCache.try_emplace(
- Locs, AAQueryInfo::CacheEntry{NoAlias, 0});
- if (!Pair.second) {
- auto &Entry = Pair.first->second;
- if (!Entry.isDefinitive()) {
- // Remember that we used an assumption.
- ++Entry.NumAssumptionUses;
- ++AAQI.NumAssumptionUses;
- }
- return Entry.Result;
- }
-
- int OrigNumAssumptionUses = AAQI.NumAssumptionUses;
- unsigned OrigNumAssumptionBasedResults = AAQI.AssumptionBasedResults.size();
- AliasResult Result = aliasCheckRecursive(V1, V1Size, V1AAInfo, V2, V2Size,
- V2AAInfo, AAQI, O1, O2);
-
- auto It = AAQI.AliasCache.find(Locs);
- assert(It != AAQI.AliasCache.end() && "Must be in cache");
- auto &Entry = It->second;
-
- // Check whether a NoAlias assumption has been used, but disproven.
- bool AssumptionDisproven = Entry.NumAssumptionUses > 0 && Result != NoAlias;
- if (AssumptionDisproven)
- Result = MayAlias;
-
- // This is a definitive result now, when considered as a root query.
- AAQI.NumAssumptionUses -= Entry.NumAssumptionUses;
- Entry.Result = Result;
- Entry.NumAssumptionUses = -1;
-
- // If the assumption has been disproven, remove any results that may have
- // been based on this assumption. Do this after the Entry updates above to
- // avoid iterator invalidation.
- if (AssumptionDisproven)
- while (AAQI.AssumptionBasedResults.size() > OrigNumAssumptionBasedResults)
- AAQI.AliasCache.erase(AAQI.AssumptionBasedResults.pop_back_val());
-
- // The result may still be based on assumptions higher up in the chain.
- // Remember it, so it can be purged from the cache later.
- if (OrigNumAssumptionUses != AAQI.NumAssumptionUses && Result != MayAlias)
- AAQI.AssumptionBasedResults.push_back(Locs);
- return Result;
-}
-
-AliasResult BasicAAResult::aliasCheckRecursive(
- const Value *V1, LocationSize V1Size, const AAMDNodes &V1AAInfo,
- const Value *V2, LocationSize V2Size, const AAMDNodes &V2AAInfo,
- AAQueryInfo &AAQI, const Value *O1, const Value *O2) {
+ const auto &Pair = AAQI.AliasCache.try_emplace(
+ Locs, AAQueryInfo::CacheEntry{NoAlias, 0});
+ if (!Pair.second) {
+ auto &Entry = Pair.first->second;
+ if (!Entry.isDefinitive()) {
+ // Remember that we used an assumption.
+ ++Entry.NumAssumptionUses;
+ ++AAQI.NumAssumptionUses;
+ }
+ return Entry.Result;
+ }
+
+ int OrigNumAssumptionUses = AAQI.NumAssumptionUses;
+ unsigned OrigNumAssumptionBasedResults = AAQI.AssumptionBasedResults.size();
+ AliasResult Result = aliasCheckRecursive(V1, V1Size, V1AAInfo, V2, V2Size,
+ V2AAInfo, AAQI, O1, O2);
+
+ auto It = AAQI.AliasCache.find(Locs);
+ assert(It != AAQI.AliasCache.end() && "Must be in cache");
+ auto &Entry = It->second;
+
+ // Check whether a NoAlias assumption has been used, but disproven.
+ bool AssumptionDisproven = Entry.NumAssumptionUses > 0 && Result != NoAlias;
+ if (AssumptionDisproven)
+ Result = MayAlias;
+
+ // This is a definitive result now, when considered as a root query.
+ AAQI.NumAssumptionUses -= Entry.NumAssumptionUses;
+ Entry.Result = Result;
+ Entry.NumAssumptionUses = -1;
+
+ // If the assumption has been disproven, remove any results that may have
+ // been based on this assumption. Do this after the Entry updates above to
+ // avoid iterator invalidation.
+ if (AssumptionDisproven)
+ while (AAQI.AssumptionBasedResults.size() > OrigNumAssumptionBasedResults)
+ AAQI.AliasCache.erase(AAQI.AssumptionBasedResults.pop_back_val());
+
+ // The result may still be based on assumptions higher up in the chain.
+ // Remember it, so it can be purged from the cache later.
+ if (OrigNumAssumptionUses != AAQI.NumAssumptionUses && Result != MayAlias)
+ AAQI.AssumptionBasedResults.push_back(Locs);
+ return Result;
+}
+
+AliasResult BasicAAResult::aliasCheckRecursive(
+ const Value *V1, LocationSize V1Size, const AAMDNodes &V1AAInfo,
+ const Value *V2, LocationSize V2Size, const AAMDNodes &V2AAInfo,
+ AAQueryInfo &AAQI, const Value *O1, const Value *O2) {
if (const GEPOperator *GV1 = dyn_cast<GEPOperator>(V1)) {
AliasResult Result =
aliasGEP(GV1, V1Size, V1AAInfo, V2, V2Size, V2AAInfo, O1, O2, AAQI);
- if (Result != MayAlias)
+ if (Result != MayAlias)
+ return Result;
+ } else if (const GEPOperator *GV2 = dyn_cast<GEPOperator>(V2)) {
+ AliasResult Result =
+ aliasGEP(GV2, V2Size, V2AAInfo, V1, V1Size, V1AAInfo, O2, O1, AAQI);
+ if (Result != MayAlias)
return Result;
- } else if (const GEPOperator *GV2 = dyn_cast<GEPOperator>(V2)) {
- AliasResult Result =
- aliasGEP(GV2, V2Size, V2AAInfo, V1, V1Size, V1AAInfo, O2, O1, AAQI);
- if (Result != MayAlias)
- return Result;
}
if (const PHINode *PN = dyn_cast<PHINode>(V1)) {
AliasResult Result =
- aliasPHI(PN, V1Size, V1AAInfo, V2, V2Size, V2AAInfo, AAQI);
- if (Result != MayAlias)
- return Result;
- } else if (const PHINode *PN = dyn_cast<PHINode>(V2)) {
- AliasResult Result =
- aliasPHI(PN, V2Size, V2AAInfo, V1, V1Size, V1AAInfo, AAQI);
- if (Result != MayAlias)
- return Result;
+ aliasPHI(PN, V1Size, V1AAInfo, V2, V2Size, V2AAInfo, AAQI);
+ if (Result != MayAlias)
+ return Result;
+ } else if (const PHINode *PN = dyn_cast<PHINode>(V2)) {
+ AliasResult Result =
+ aliasPHI(PN, V2Size, V2AAInfo, V1, V1Size, V1AAInfo, AAQI);
+ if (Result != MayAlias)
+ return Result;
}
if (const SelectInst *S1 = dyn_cast<SelectInst>(V1)) {
AliasResult Result =
- aliasSelect(S1, V1Size, V1AAInfo, V2, V2Size, V2AAInfo, AAQI);
- if (Result != MayAlias)
- return Result;
- } else if (const SelectInst *S2 = dyn_cast<SelectInst>(V2)) {
- AliasResult Result =
- aliasSelect(S2, V2Size, V2AAInfo, V1, V1Size, V1AAInfo, AAQI);
- if (Result != MayAlias)
- return Result;
+ aliasSelect(S1, V1Size, V1AAInfo, V2, V2Size, V2AAInfo, AAQI);
+ if (Result != MayAlias)
+ return Result;
+ } else if (const SelectInst *S2 = dyn_cast<SelectInst>(V2)) {
+ AliasResult Result =
+ aliasSelect(S2, V2Size, V2AAInfo, V1, V1Size, V1AAInfo, AAQI);
+ if (Result != MayAlias)
+ return Result;
}
// If both pointers are pointing into the same object and one of them
// accesses the entire object, then the accesses must overlap in some way.
- if (O1 == O2) {
- bool NullIsValidLocation = NullPointerIsDefined(&F);
+ if (O1 == O2) {
+ bool NullIsValidLocation = NullPointerIsDefined(&F);
if (V1Size.isPrecise() && V2Size.isPrecise() &&
(isObjectSize(O1, V1Size.getValue(), DL, TLI, NullIsValidLocation) ||
- isObjectSize(O2, V2Size.getValue(), DL, TLI, NullIsValidLocation)))
- return PartialAlias;
- }
+ isObjectSize(O2, V2Size.getValue(), DL, TLI, NullIsValidLocation)))
+ return PartialAlias;
+ }
- return MayAlias;
+ return MayAlias;
}
/// Check whether two Values can be considered equivalent.
@@ -1760,7 +1760,7 @@ void BasicAAResult::GetIndexDifference(
// If we didn't consume this entry, add it to the end of the Dest list.
if (!!Scale) {
- VariableGEPIndex Entry = {V, ZExtBits, SExtBits, -Scale, Src[i].CxtI};
+ VariableGEPIndex Entry = {V, ZExtBits, SExtBits, -Scale, Src[i].CxtI};
Dest.push_back(Entry);
}
}
@@ -1770,8 +1770,8 @@ bool BasicAAResult::constantOffsetHeuristic(
const SmallVectorImpl<VariableGEPIndex> &VarIndices,
LocationSize MaybeV1Size, LocationSize MaybeV2Size, const APInt &BaseOffset,
AssumptionCache *AC, DominatorTree *DT) {
- if (VarIndices.size() != 2 || !MaybeV1Size.hasValue() ||
- !MaybeV2Size.hasValue())
+ if (VarIndices.size() != 2 || !MaybeV1Size.hasValue() ||
+ !MaybeV2Size.hasValue())
return false;
const uint64_t V1Size = MaybeV1Size.getValue();
@@ -1831,12 +1831,12 @@ bool BasicAAResult::constantOffsetHeuristic(
AnalysisKey BasicAA::Key;
BasicAAResult BasicAA::run(Function &F, FunctionAnalysisManager &AM) {
- auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
- auto &AC = AM.getResult<AssumptionAnalysis>(F);
- auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
- auto *LI = AM.getCachedResult<LoopAnalysis>(F);
- auto *PV = AM.getCachedResult<PhiValuesAnalysis>(F);
- return BasicAAResult(F.getParent()->getDataLayout(), F, TLI, AC, DT, LI, PV);
+ auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
+ auto &AC = AM.getResult<AssumptionAnalysis>(F);
+ auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
+ auto *LI = AM.getCachedResult<LoopAnalysis>(F);
+ auto *PV = AM.getCachedResult<PhiValuesAnalysis>(F);
+ return BasicAAResult(F.getParent()->getDataLayout(), F, TLI, AC, DT, LI, PV);
}
BasicAAWrapperPass::BasicAAWrapperPass() : FunctionPass(ID) {
@@ -1878,9 +1878,9 @@ bool BasicAAWrapperPass::runOnFunction(Function &F) {
void BasicAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
- AU.addRequiredTransitive<AssumptionCacheTracker>();
- AU.addRequiredTransitive<DominatorTreeWrapperPass>();
- AU.addRequiredTransitive<TargetLibraryInfoWrapperPass>();
+ AU.addRequiredTransitive<AssumptionCacheTracker>();
+ AU.addRequiredTransitive<DominatorTreeWrapperPass>();
+ AU.addRequiredTransitive<TargetLibraryInfoWrapperPass>();
AU.addUsedIfAvailable<PhiValuesWrapperPass>();
}
diff --git a/contrib/libs/llvm12/lib/Analysis/BranchProbabilityInfo.cpp b/contrib/libs/llvm12/lib/Analysis/BranchProbabilityInfo.cpp
index e8f5791d37..884ba484ae 100644
--- a/contrib/libs/llvm12/lib/Analysis/BranchProbabilityInfo.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/BranchProbabilityInfo.cpp
@@ -61,7 +61,7 @@ INITIALIZE_PASS_BEGIN(BranchProbabilityInfoWrapperPass, "branch-prob",
"Branch Probability Analysis", false, true)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
INITIALIZE_PASS_END(BranchProbabilityInfoWrapperPass, "branch-prob",
"Branch Probability Analysis", false, true)
@@ -120,185 +120,185 @@ static const uint32_t FPH_ORD_WEIGHT = 1024 * 1024 - 1;
/// exceptional case, so the result is unlikely.
static const uint32_t FPH_UNO_WEIGHT = 1;
-/// Set of dedicated "absolute" execution weights for a block. These weights are
-/// meaningful relative to each other and their derivatives only.
-enum class BlockExecWeight : std::uint32_t {
- /// Special weight used for cases with exact zero probability.
- ZERO = 0x0,
- /// Minimal possible non zero weight.
- LOWEST_NON_ZERO = 0x1,
- /// Weight to an 'unreachable' block.
- UNREACHABLE = ZERO,
- /// Weight to a block containing non returning call.
- NORETURN = LOWEST_NON_ZERO,
- /// Weight to 'unwind' block of an invoke instruction.
- UNWIND = LOWEST_NON_ZERO,
- /// Weight to a 'cold' block. Cold blocks are the ones containing calls marked
- /// with attribute 'cold'.
- COLD = 0xffff,
- /// Default weight is used in cases when there is no dedicated execution
- /// weight set. It is not propagated through the domination line either.
- DEFAULT = 0xfffff
-};
-
-BranchProbabilityInfo::SccInfo::SccInfo(const Function &F) {
- // Record SCC numbers of blocks in the CFG to identify irreducible loops.
- // FIXME: We could only calculate this if the CFG is known to be irreducible
- // (perhaps cache this info in LoopInfo if we can easily calculate it there?).
- int SccNum = 0;
- for (scc_iterator<const Function *> It = scc_begin(&F); !It.isAtEnd();
- ++It, ++SccNum) {
- // Ignore single-block SCCs since they either aren't loops or LoopInfo will
- // catch them.
- const std::vector<const BasicBlock *> &Scc = *It;
- if (Scc.size() == 1)
- continue;
-
- LLVM_DEBUG(dbgs() << "BPI: SCC " << SccNum << ":");
- for (const auto *BB : Scc) {
- LLVM_DEBUG(dbgs() << " " << BB->getName());
- SccNums[BB] = SccNum;
- calculateSccBlockType(BB, SccNum);
- }
- LLVM_DEBUG(dbgs() << "\n");
- }
-}
-
-int BranchProbabilityInfo::SccInfo::getSCCNum(const BasicBlock *BB) const {
- auto SccIt = SccNums.find(BB);
- if (SccIt == SccNums.end())
- return -1;
- return SccIt->second;
+/// Set of dedicated "absolute" execution weights for a block. These weights are
+/// meaningful relative to each other and their derivatives only.
+enum class BlockExecWeight : std::uint32_t {
+ /// Special weight used for cases with exact zero probability.
+ ZERO = 0x0,
+ /// Minimal possible non zero weight.
+ LOWEST_NON_ZERO = 0x1,
+ /// Weight to an 'unreachable' block.
+ UNREACHABLE = ZERO,
+ /// Weight to a block containing non returning call.
+ NORETURN = LOWEST_NON_ZERO,
+ /// Weight to 'unwind' block of an invoke instruction.
+ UNWIND = LOWEST_NON_ZERO,
+ /// Weight to a 'cold' block. Cold blocks are the ones containing calls marked
+ /// with attribute 'cold'.
+ COLD = 0xffff,
+ /// Default weight is used in cases when there is no dedicated execution
+ /// weight set. It is not propagated through the domination line either.
+ DEFAULT = 0xfffff
+};
+
+BranchProbabilityInfo::SccInfo::SccInfo(const Function &F) {
+ // Record SCC numbers of blocks in the CFG to identify irreducible loops.
+ // FIXME: We could only calculate this if the CFG is known to be irreducible
+ // (perhaps cache this info in LoopInfo if we can easily calculate it there?).
+ int SccNum = 0;
+ for (scc_iterator<const Function *> It = scc_begin(&F); !It.isAtEnd();
+ ++It, ++SccNum) {
+ // Ignore single-block SCCs since they either aren't loops or LoopInfo will
+ // catch them.
+ const std::vector<const BasicBlock *> &Scc = *It;
+ if (Scc.size() == 1)
+ continue;
+
+ LLVM_DEBUG(dbgs() << "BPI: SCC " << SccNum << ":");
+ for (const auto *BB : Scc) {
+ LLVM_DEBUG(dbgs() << " " << BB->getName());
+ SccNums[BB] = SccNum;
+ calculateSccBlockType(BB, SccNum);
+ }
+ LLVM_DEBUG(dbgs() << "\n");
+ }
+}
+
+int BranchProbabilityInfo::SccInfo::getSCCNum(const BasicBlock *BB) const {
+ auto SccIt = SccNums.find(BB);
+ if (SccIt == SccNums.end())
+ return -1;
+ return SccIt->second;
}
-void BranchProbabilityInfo::SccInfo::getSccEnterBlocks(
- int SccNum, SmallVectorImpl<BasicBlock *> &Enters) const {
-
- for (auto MapIt : SccBlocks[SccNum]) {
- const auto *BB = MapIt.first;
- if (isSCCHeader(BB, SccNum))
- for (const auto *Pred : predecessors(BB))
- if (getSCCNum(Pred) != SccNum)
- Enters.push_back(const_cast<BasicBlock *>(BB));
+void BranchProbabilityInfo::SccInfo::getSccEnterBlocks(
+ int SccNum, SmallVectorImpl<BasicBlock *> &Enters) const {
+
+ for (auto MapIt : SccBlocks[SccNum]) {
+ const auto *BB = MapIt.first;
+ if (isSCCHeader(BB, SccNum))
+ for (const auto *Pred : predecessors(BB))
+ if (getSCCNum(Pred) != SccNum)
+ Enters.push_back(const_cast<BasicBlock *>(BB));
}
-}
-
-void BranchProbabilityInfo::SccInfo::getSccExitBlocks(
- int SccNum, SmallVectorImpl<BasicBlock *> &Exits) const {
- for (auto MapIt : SccBlocks[SccNum]) {
- const auto *BB = MapIt.first;
- if (isSCCExitingBlock(BB, SccNum))
- for (const auto *Succ : successors(BB))
- if (getSCCNum(Succ) != SccNum)
- Exits.push_back(const_cast<BasicBlock *>(BB));
+}
+
+void BranchProbabilityInfo::SccInfo::getSccExitBlocks(
+ int SccNum, SmallVectorImpl<BasicBlock *> &Exits) const {
+ for (auto MapIt : SccBlocks[SccNum]) {
+ const auto *BB = MapIt.first;
+ if (isSCCExitingBlock(BB, SccNum))
+ for (const auto *Succ : successors(BB))
+ if (getSCCNum(Succ) != SccNum)
+ Exits.push_back(const_cast<BasicBlock *>(BB));
}
}
-uint32_t BranchProbabilityInfo::SccInfo::getSccBlockType(const BasicBlock *BB,
- int SccNum) const {
- assert(getSCCNum(BB) == SccNum);
+uint32_t BranchProbabilityInfo::SccInfo::getSccBlockType(const BasicBlock *BB,
+ int SccNum) const {
+ assert(getSCCNum(BB) == SccNum);
- assert(SccBlocks.size() > static_cast<unsigned>(SccNum) && "Unknown SCC");
- const auto &SccBlockTypes = SccBlocks[SccNum];
+ assert(SccBlocks.size() > static_cast<unsigned>(SccNum) && "Unknown SCC");
+ const auto &SccBlockTypes = SccBlocks[SccNum];
+
+ auto It = SccBlockTypes.find(BB);
+ if (It != SccBlockTypes.end()) {
+ return It->second;
+ }
+ return Inner;
+}
- auto It = SccBlockTypes.find(BB);
- if (It != SccBlockTypes.end()) {
- return It->second;
+void BranchProbabilityInfo::SccInfo::calculateSccBlockType(const BasicBlock *BB,
+ int SccNum) {
+ assert(getSCCNum(BB) == SccNum);
+ uint32_t BlockType = Inner;
+
+ if (llvm::any_of(predecessors(BB), [&](const BasicBlock *Pred) {
+ // Consider any block that is an entry point to the SCC as
+ // a header.
+ return getSCCNum(Pred) != SccNum;
+ }))
+ BlockType |= Header;
+
+ if (llvm::any_of(successors(BB), [&](const BasicBlock *Succ) {
+ return getSCCNum(Succ) != SccNum;
+ }))
+ BlockType |= Exiting;
+
+ // Lazily compute the set of headers for a given SCC and cache the results
+ // in the SccHeaderMap.
+ if (SccBlocks.size() <= static_cast<unsigned>(SccNum))
+ SccBlocks.resize(SccNum + 1);
+ auto &SccBlockTypes = SccBlocks[SccNum];
+
+ if (BlockType != Inner) {
+ bool IsInserted;
+ std::tie(std::ignore, IsInserted) =
+ SccBlockTypes.insert(std::make_pair(BB, BlockType));
+ assert(IsInserted && "Duplicated block in SCC");
}
- return Inner;
}
-void BranchProbabilityInfo::SccInfo::calculateSccBlockType(const BasicBlock *BB,
- int SccNum) {
- assert(getSCCNum(BB) == SccNum);
- uint32_t BlockType = Inner;
-
- if (llvm::any_of(predecessors(BB), [&](const BasicBlock *Pred) {
- // Consider any block that is an entry point to the SCC as
- // a header.
- return getSCCNum(Pred) != SccNum;
- }))
- BlockType |= Header;
-
- if (llvm::any_of(successors(BB), [&](const BasicBlock *Succ) {
- return getSCCNum(Succ) != SccNum;
- }))
- BlockType |= Exiting;
-
- // Lazily compute the set of headers for a given SCC and cache the results
- // in the SccHeaderMap.
- if (SccBlocks.size() <= static_cast<unsigned>(SccNum))
- SccBlocks.resize(SccNum + 1);
- auto &SccBlockTypes = SccBlocks[SccNum];
-
- if (BlockType != Inner) {
- bool IsInserted;
- std::tie(std::ignore, IsInserted) =
- SccBlockTypes.insert(std::make_pair(BB, BlockType));
- assert(IsInserted && "Duplicated block in SCC");
+BranchProbabilityInfo::LoopBlock::LoopBlock(const BasicBlock *BB,
+ const LoopInfo &LI,
+ const SccInfo &SccI)
+ : BB(BB) {
+ LD.first = LI.getLoopFor(BB);
+ if (!LD.first) {
+ LD.second = SccI.getSCCNum(BB);
+ }
+}
+
+bool BranchProbabilityInfo::isLoopEnteringEdge(const LoopEdge &Edge) const {
+ const auto &SrcBlock = Edge.first;
+ const auto &DstBlock = Edge.second;
+ return (DstBlock.getLoop() &&
+ !DstBlock.getLoop()->contains(SrcBlock.getLoop())) ||
+ // Assume that SCCs can't be nested.
+ (DstBlock.getSccNum() != -1 &&
+ SrcBlock.getSccNum() != DstBlock.getSccNum());
+}
+
+bool BranchProbabilityInfo::isLoopExitingEdge(const LoopEdge &Edge) const {
+ return isLoopEnteringEdge({Edge.second, Edge.first});
+}
+
+bool BranchProbabilityInfo::isLoopEnteringExitingEdge(
+ const LoopEdge &Edge) const {
+ return isLoopEnteringEdge(Edge) || isLoopExitingEdge(Edge);
+}
+
+bool BranchProbabilityInfo::isLoopBackEdge(const LoopEdge &Edge) const {
+ const auto &SrcBlock = Edge.first;
+ const auto &DstBlock = Edge.second;
+ return SrcBlock.belongsToSameLoop(DstBlock) &&
+ ((DstBlock.getLoop() &&
+ DstBlock.getLoop()->getHeader() == DstBlock.getBlock()) ||
+ (DstBlock.getSccNum() != -1 &&
+ SccI->isSCCHeader(DstBlock.getBlock(), DstBlock.getSccNum())));
+}
+
+void BranchProbabilityInfo::getLoopEnterBlocks(
+ const LoopBlock &LB, SmallVectorImpl<BasicBlock *> &Enters) const {
+ if (LB.getLoop()) {
+ auto *Header = LB.getLoop()->getHeader();
+ Enters.append(pred_begin(Header), pred_end(Header));
+ } else {
+ assert(LB.getSccNum() != -1 && "LB doesn't belong to any loop?");
+ SccI->getSccEnterBlocks(LB.getSccNum(), Enters);
+ }
+}
+
+void BranchProbabilityInfo::getLoopExitBlocks(
+ const LoopBlock &LB, SmallVectorImpl<BasicBlock *> &Exits) const {
+ if (LB.getLoop()) {
+ LB.getLoop()->getExitBlocks(Exits);
+ } else {
+ assert(LB.getSccNum() != -1 && "LB doesn't belong to any loop?");
+ SccI->getSccExitBlocks(LB.getSccNum(), Exits);
}
-}
-
-BranchProbabilityInfo::LoopBlock::LoopBlock(const BasicBlock *BB,
- const LoopInfo &LI,
- const SccInfo &SccI)
- : BB(BB) {
- LD.first = LI.getLoopFor(BB);
- if (!LD.first) {
- LD.second = SccI.getSCCNum(BB);
- }
-}
-
-bool BranchProbabilityInfo::isLoopEnteringEdge(const LoopEdge &Edge) const {
- const auto &SrcBlock = Edge.first;
- const auto &DstBlock = Edge.second;
- return (DstBlock.getLoop() &&
- !DstBlock.getLoop()->contains(SrcBlock.getLoop())) ||
- // Assume that SCCs can't be nested.
- (DstBlock.getSccNum() != -1 &&
- SrcBlock.getSccNum() != DstBlock.getSccNum());
-}
-
-bool BranchProbabilityInfo::isLoopExitingEdge(const LoopEdge &Edge) const {
- return isLoopEnteringEdge({Edge.second, Edge.first});
}
-bool BranchProbabilityInfo::isLoopEnteringExitingEdge(
- const LoopEdge &Edge) const {
- return isLoopEnteringEdge(Edge) || isLoopExitingEdge(Edge);
-}
-
-bool BranchProbabilityInfo::isLoopBackEdge(const LoopEdge &Edge) const {
- const auto &SrcBlock = Edge.first;
- const auto &DstBlock = Edge.second;
- return SrcBlock.belongsToSameLoop(DstBlock) &&
- ((DstBlock.getLoop() &&
- DstBlock.getLoop()->getHeader() == DstBlock.getBlock()) ||
- (DstBlock.getSccNum() != -1 &&
- SccI->isSCCHeader(DstBlock.getBlock(), DstBlock.getSccNum())));
-}
-
-void BranchProbabilityInfo::getLoopEnterBlocks(
- const LoopBlock &LB, SmallVectorImpl<BasicBlock *> &Enters) const {
- if (LB.getLoop()) {
- auto *Header = LB.getLoop()->getHeader();
- Enters.append(pred_begin(Header), pred_end(Header));
- } else {
- assert(LB.getSccNum() != -1 && "LB doesn't belong to any loop?");
- SccI->getSccEnterBlocks(LB.getSccNum(), Enters);
- }
-}
-
-void BranchProbabilityInfo::getLoopExitBlocks(
- const LoopBlock &LB, SmallVectorImpl<BasicBlock *> &Exits) const {
- if (LB.getLoop()) {
- LB.getLoop()->getExitBlocks(Exits);
- } else {
- assert(LB.getSccNum() != -1 && "LB doesn't belong to any loop?");
- SccI->getSccExitBlocks(LB.getSccNum(), Exits);
- }
-}
-
// Propagate existing explicit probabilities from either profile data or
// 'expect' intrinsic processing. Examine metadata against unreachable
// heuristic. The probability of the edge coming to unreachable block is
@@ -339,12 +339,12 @@ bool BranchProbabilityInfo::calcMetadataWeights(const BasicBlock *BB) {
"Too many bits for uint32_t");
Weights.push_back(Weight->getZExtValue());
WeightSum += Weights.back();
- const LoopBlock SrcLoopBB = getLoopBlock(BB);
- const LoopBlock DstLoopBB = getLoopBlock(TI->getSuccessor(I - 1));
- auto EstimatedWeight = getEstimatedEdgeWeight({SrcLoopBB, DstLoopBB});
- if (EstimatedWeight &&
- EstimatedWeight.getValue() <=
- static_cast<uint32_t>(BlockExecWeight::UNREACHABLE))
+ const LoopBlock SrcLoopBB = getLoopBlock(BB);
+ const LoopBlock DstLoopBB = getLoopBlock(TI->getSuccessor(I - 1));
+ auto EstimatedWeight = getEstimatedEdgeWeight({SrcLoopBB, DstLoopBB});
+ if (EstimatedWeight &&
+ EstimatedWeight.getValue() <=
+ static_cast<uint32_t>(BlockExecWeight::UNREACHABLE))
UnreachableIdxs.push_back(I - 1);
else
ReachableIdxs.push_back(I - 1);
@@ -568,7 +568,7 @@ computeUnlikelySuccessors(const BasicBlock *BB, Loop *L,
// we can constant-evaluate the compare to see if it makes the branch be
// taken or not.
Constant *CmpLHSConst = dyn_cast<Constant>(V);
- if (!CmpLHSConst || !llvm::is_contained(successors(BB), B))
+ if (!CmpLHSConst || !llvm::is_contained(successors(BB), B))
continue;
// First collapse InstChain
for (Instruction *I : llvm::reverse(InstChain)) {
@@ -592,323 +592,323 @@ computeUnlikelySuccessors(const BasicBlock *BB, Loop *L,
}
}
-Optional<uint32_t>
-BranchProbabilityInfo::getEstimatedBlockWeight(const BasicBlock *BB) const {
- auto WeightIt = EstimatedBlockWeight.find(BB);
- if (WeightIt == EstimatedBlockWeight.end())
- return None;
- return WeightIt->second;
-}
-
-Optional<uint32_t>
-BranchProbabilityInfo::getEstimatedLoopWeight(const LoopData &L) const {
- auto WeightIt = EstimatedLoopWeight.find(L);
- if (WeightIt == EstimatedLoopWeight.end())
- return None;
- return WeightIt->second;
-}
-
-Optional<uint32_t>
-BranchProbabilityInfo::getEstimatedEdgeWeight(const LoopEdge &Edge) const {
- // For edges entering a loop take weight of a loop rather than an individual
- // block in the loop.
- return isLoopEnteringEdge(Edge)
- ? getEstimatedLoopWeight(Edge.second.getLoopData())
- : getEstimatedBlockWeight(Edge.second.getBlock());
-}
-
-template <class IterT>
-Optional<uint32_t> BranchProbabilityInfo::getMaxEstimatedEdgeWeight(
- const LoopBlock &SrcLoopBB, iterator_range<IterT> Successors) const {
- SmallVector<uint32_t, 4> Weights;
- Optional<uint32_t> MaxWeight;
- for (const BasicBlock *DstBB : Successors) {
- const LoopBlock DstLoopBB = getLoopBlock(DstBB);
- auto Weight = getEstimatedEdgeWeight({SrcLoopBB, DstLoopBB});
-
- if (!Weight)
- return None;
-
- if (!MaxWeight || MaxWeight.getValue() < Weight.getValue())
- MaxWeight = Weight;
+Optional<uint32_t>
+BranchProbabilityInfo::getEstimatedBlockWeight(const BasicBlock *BB) const {
+ auto WeightIt = EstimatedBlockWeight.find(BB);
+ if (WeightIt == EstimatedBlockWeight.end())
+ return None;
+ return WeightIt->second;
+}
+
+Optional<uint32_t>
+BranchProbabilityInfo::getEstimatedLoopWeight(const LoopData &L) const {
+ auto WeightIt = EstimatedLoopWeight.find(L);
+ if (WeightIt == EstimatedLoopWeight.end())
+ return None;
+ return WeightIt->second;
+}
+
+Optional<uint32_t>
+BranchProbabilityInfo::getEstimatedEdgeWeight(const LoopEdge &Edge) const {
+ // For edges entering a loop take weight of a loop rather than an individual
+ // block in the loop.
+ return isLoopEnteringEdge(Edge)
+ ? getEstimatedLoopWeight(Edge.second.getLoopData())
+ : getEstimatedBlockWeight(Edge.second.getBlock());
+}
+
+template <class IterT>
+Optional<uint32_t> BranchProbabilityInfo::getMaxEstimatedEdgeWeight(
+ const LoopBlock &SrcLoopBB, iterator_range<IterT> Successors) const {
+ SmallVector<uint32_t, 4> Weights;
+ Optional<uint32_t> MaxWeight;
+ for (const BasicBlock *DstBB : Successors) {
+ const LoopBlock DstLoopBB = getLoopBlock(DstBB);
+ auto Weight = getEstimatedEdgeWeight({SrcLoopBB, DstLoopBB});
+
+ if (!Weight)
+ return None;
+
+ if (!MaxWeight || MaxWeight.getValue() < Weight.getValue())
+ MaxWeight = Weight;
+ }
+
+ return MaxWeight;
+}
+
+// Updates \p LoopBB's weight and returns true. If \p LoopBB has already
+// an associated weight it is unchanged and false is returned.
+//
+// Please note by the algorithm the weight is not expected to change once set
+// thus 'false' status is used to track visited blocks.
+bool BranchProbabilityInfo::updateEstimatedBlockWeight(
+ LoopBlock &LoopBB, uint32_t BBWeight,
+ SmallVectorImpl<BasicBlock *> &BlockWorkList,
+ SmallVectorImpl<LoopBlock> &LoopWorkList) {
+ BasicBlock *BB = LoopBB.getBlock();
+
+ // In general, weight is assigned to a block when it has final value and
+ // can't/shouldn't be changed. However, there are cases when a block
+ // inherently has several (possibly "contradicting") weights. For example,
+ // "unwind" block may also contain "cold" call. In that case the first
+ // set weight is favored and all consequent weights are ignored.
+ if (!EstimatedBlockWeight.insert({BB, BBWeight}).second)
+ return false;
+
+ for (BasicBlock *PredBlock : predecessors(BB)) {
+ LoopBlock PredLoop = getLoopBlock(PredBlock);
+ // Add affected block/loop to a working list.
+ if (isLoopExitingEdge({PredLoop, LoopBB})) {
+ if (!EstimatedLoopWeight.count(PredLoop.getLoopData()))
+ LoopWorkList.push_back(PredLoop);
+ } else if (!EstimatedBlockWeight.count(PredBlock))
+ BlockWorkList.push_back(PredBlock);
}
+ return true;
+}
+
+// Starting from \p BB traverse through dominator blocks and assign \p BBWeight
+// to all such blocks that are post dominated by \BB. In other words to all
+// blocks that the one is executed if and only if another one is executed.
+// Importantly, we skip loops here for two reasons. First weights of blocks in
+// a loop should be scaled by trip count (yet possibly unknown). Second there is
+// no any value in doing that because that doesn't give any additional
+// information regarding distribution of probabilities inside the loop.
+// Exception is loop 'enter' and 'exit' edges that are handled in a special way
+// at calcEstimatedHeuristics.
+//
+// In addition, \p WorkList is populated with basic blocks if at leas one
+// successor has updated estimated weight.
+void BranchProbabilityInfo::propagateEstimatedBlockWeight(
+ const LoopBlock &LoopBB, DominatorTree *DT, PostDominatorTree *PDT,
+ uint32_t BBWeight, SmallVectorImpl<BasicBlock *> &BlockWorkList,
+ SmallVectorImpl<LoopBlock> &LoopWorkList) {
+ const BasicBlock *BB = LoopBB.getBlock();
+ const auto *DTStartNode = DT->getNode(BB);
+ const auto *PDTStartNode = PDT->getNode(BB);
+
+ // TODO: Consider propagating weight down the domination line as well.
+ for (const auto *DTNode = DTStartNode; DTNode != nullptr;
+ DTNode = DTNode->getIDom()) {
+ auto *DomBB = DTNode->getBlock();
+ // Consider blocks which lie on one 'line'.
+ if (!PDT->dominates(PDTStartNode, PDT->getNode(DomBB)))
+ // If BB doesn't post dominate DomBB it will not post dominate dominators
+ // of DomBB as well.
+ break;
- return MaxWeight;
-}
-
-// Updates \p LoopBB's weight and returns true. If \p LoopBB has already
-// an associated weight it is unchanged and false is returned.
-//
-// Please note by the algorithm the weight is not expected to change once set
-// thus 'false' status is used to track visited blocks.
-bool BranchProbabilityInfo::updateEstimatedBlockWeight(
- LoopBlock &LoopBB, uint32_t BBWeight,
- SmallVectorImpl<BasicBlock *> &BlockWorkList,
- SmallVectorImpl<LoopBlock> &LoopWorkList) {
- BasicBlock *BB = LoopBB.getBlock();
-
- // In general, weight is assigned to a block when it has final value and
- // can't/shouldn't be changed. However, there are cases when a block
- // inherently has several (possibly "contradicting") weights. For example,
- // "unwind" block may also contain "cold" call. In that case the first
- // set weight is favored and all consequent weights are ignored.
- if (!EstimatedBlockWeight.insert({BB, BBWeight}).second)
- return false;
-
- for (BasicBlock *PredBlock : predecessors(BB)) {
- LoopBlock PredLoop = getLoopBlock(PredBlock);
- // Add affected block/loop to a working list.
- if (isLoopExitingEdge({PredLoop, LoopBB})) {
- if (!EstimatedLoopWeight.count(PredLoop.getLoopData()))
- LoopWorkList.push_back(PredLoop);
- } else if (!EstimatedBlockWeight.count(PredBlock))
- BlockWorkList.push_back(PredBlock);
- }
- return true;
-}
-
-// Starting from \p BB traverse through dominator blocks and assign \p BBWeight
-// to all such blocks that are post dominated by \BB. In other words to all
-// blocks that the one is executed if and only if another one is executed.
-// Importantly, we skip loops here for two reasons. First weights of blocks in
-// a loop should be scaled by trip count (yet possibly unknown). Second there is
-// no any value in doing that because that doesn't give any additional
-// information regarding distribution of probabilities inside the loop.
-// Exception is loop 'enter' and 'exit' edges that are handled in a special way
-// at calcEstimatedHeuristics.
-//
-// In addition, \p WorkList is populated with basic blocks if at leas one
-// successor has updated estimated weight.
-void BranchProbabilityInfo::propagateEstimatedBlockWeight(
- const LoopBlock &LoopBB, DominatorTree *DT, PostDominatorTree *PDT,
- uint32_t BBWeight, SmallVectorImpl<BasicBlock *> &BlockWorkList,
- SmallVectorImpl<LoopBlock> &LoopWorkList) {
- const BasicBlock *BB = LoopBB.getBlock();
- const auto *DTStartNode = DT->getNode(BB);
- const auto *PDTStartNode = PDT->getNode(BB);
-
- // TODO: Consider propagating weight down the domination line as well.
- for (const auto *DTNode = DTStartNode; DTNode != nullptr;
- DTNode = DTNode->getIDom()) {
- auto *DomBB = DTNode->getBlock();
- // Consider blocks which lie on one 'line'.
- if (!PDT->dominates(PDTStartNode, PDT->getNode(DomBB)))
- // If BB doesn't post dominate DomBB it will not post dominate dominators
- // of DomBB as well.
- break;
-
- LoopBlock DomLoopBB = getLoopBlock(DomBB);
- const LoopEdge Edge{DomLoopBB, LoopBB};
- // Don't propagate weight to blocks belonging to different loops.
- if (!isLoopEnteringExitingEdge(Edge)) {
- if (!updateEstimatedBlockWeight(DomLoopBB, BBWeight, BlockWorkList,
- LoopWorkList))
- // If DomBB has weight set then all it's predecessors are already
- // processed (since we propagate weight up to the top of IR each time).
- break;
- } else if (isLoopExitingEdge(Edge)) {
- LoopWorkList.push_back(DomLoopBB);
+ LoopBlock DomLoopBB = getLoopBlock(DomBB);
+ const LoopEdge Edge{DomLoopBB, LoopBB};
+ // Don't propagate weight to blocks belonging to different loops.
+ if (!isLoopEnteringExitingEdge(Edge)) {
+ if (!updateEstimatedBlockWeight(DomLoopBB, BBWeight, BlockWorkList,
+ LoopWorkList))
+ // If DomBB has weight set then all it's predecessors are already
+ // processed (since we propagate weight up to the top of IR each time).
+ break;
+ } else if (isLoopExitingEdge(Edge)) {
+ LoopWorkList.push_back(DomLoopBB);
}
}
-}
-
-Optional<uint32_t> BranchProbabilityInfo::getInitialEstimatedBlockWeight(
- const BasicBlock *BB) {
- // Returns true if \p BB has call marked with "NoReturn" attribute.
- auto hasNoReturn = [&](const BasicBlock *BB) {
- for (const auto &I : reverse(*BB))
- if (const CallInst *CI = dyn_cast<CallInst>(&I))
- if (CI->hasFnAttr(Attribute::NoReturn))
- return true;
-
+}
+
+Optional<uint32_t> BranchProbabilityInfo::getInitialEstimatedBlockWeight(
+ const BasicBlock *BB) {
+ // Returns true if \p BB has call marked with "NoReturn" attribute.
+ auto hasNoReturn = [&](const BasicBlock *BB) {
+ for (const auto &I : reverse(*BB))
+ if (const CallInst *CI = dyn_cast<CallInst>(&I))
+ if (CI->hasFnAttr(Attribute::NoReturn))
+ return true;
+
return false;
- };
-
- // Important note regarding the order of checks. They are ordered by weight
- // from lowest to highest. Doing that allows to avoid "unstable" results
- // when several conditions heuristics can be applied simultaneously.
- if (isa<UnreachableInst>(BB->getTerminator()) ||
- // If this block is terminated by a call to
- // @llvm.experimental.deoptimize then treat it like an unreachable
- // since it is expected to practically never execute.
- // TODO: Should we actually treat as never returning call?
- BB->getTerminatingDeoptimizeCall())
- return hasNoReturn(BB)
- ? static_cast<uint32_t>(BlockExecWeight::NORETURN)
- : static_cast<uint32_t>(BlockExecWeight::UNREACHABLE);
-
- // Check if the block is 'unwind' handler of some invoke instruction.
- for (const auto *Pred : predecessors(BB))
- if (Pred)
- if (const auto *II = dyn_cast<InvokeInst>(Pred->getTerminator()))
- if (II->getUnwindDest() == BB)
- return static_cast<uint32_t>(BlockExecWeight::UNWIND);
-
- // Check if the block contains 'cold' call.
- for (const auto &I : *BB)
- if (const CallInst *CI = dyn_cast<CallInst>(&I))
- if (CI->hasFnAttr(Attribute::Cold))
- return static_cast<uint32_t>(BlockExecWeight::COLD);
-
- return None;
-}
-
-// Does RPO traversal over all blocks in \p F and assigns weights to
-// 'unreachable', 'noreturn', 'cold', 'unwind' blocks. In addition it does its
-// best to propagate the weight to up/down the IR.
-void BranchProbabilityInfo::computeEestimateBlockWeight(
- const Function &F, DominatorTree *DT, PostDominatorTree *PDT) {
- SmallVector<BasicBlock *, 8> BlockWorkList;
- SmallVector<LoopBlock, 8> LoopWorkList;
-
- // By doing RPO we make sure that all predecessors already have weights
- // calculated before visiting theirs successors.
- ReversePostOrderTraversal<const Function *> RPOT(&F);
- for (const auto *BB : RPOT)
- if (auto BBWeight = getInitialEstimatedBlockWeight(BB))
- // If we were able to find estimated weight for the block set it to this
- // block and propagate up the IR.
- propagateEstimatedBlockWeight(getLoopBlock(BB), DT, PDT,
- BBWeight.getValue(), BlockWorkList,
- LoopWorkList);
-
- // BlockWorklist/LoopWorkList contains blocks/loops with at least one
- // successor/exit having estimated weight. Try to propagate weight to such
- // blocks/loops from successors/exits.
- // Process loops and blocks. Order is not important.
- do {
- while (!LoopWorkList.empty()) {
- const LoopBlock LoopBB = LoopWorkList.pop_back_val();
-
- if (EstimatedLoopWeight.count(LoopBB.getLoopData()))
- continue;
-
- SmallVector<BasicBlock *, 4> Exits;
- getLoopExitBlocks(LoopBB, Exits);
- auto LoopWeight = getMaxEstimatedEdgeWeight(
- LoopBB, make_range(Exits.begin(), Exits.end()));
-
- if (LoopWeight) {
- // If we never exit the loop then we can enter it once at maximum.
- if (LoopWeight <= static_cast<uint32_t>(BlockExecWeight::UNREACHABLE))
- LoopWeight = static_cast<uint32_t>(BlockExecWeight::LOWEST_NON_ZERO);
-
- EstimatedLoopWeight.insert(
- {LoopBB.getLoopData(), LoopWeight.getValue()});
- // Add all blocks entering the loop into working list.
- getLoopEnterBlocks(LoopBB, BlockWorkList);
- }
- }
-
- while (!BlockWorkList.empty()) {
- // We can reach here only if BlockWorkList is not empty.
- const BasicBlock *BB = BlockWorkList.pop_back_val();
- if (EstimatedBlockWeight.count(BB))
- continue;
-
- // We take maximum over all weights of successors. In other words we take
- // weight of "hot" path. In theory we can probably find a better function
- // which gives higher accuracy results (comparing to "maximum") but I
- // can't
- // think of any right now. And I doubt it will make any difference in
- // practice.
- const LoopBlock LoopBB = getLoopBlock(BB);
- auto MaxWeight = getMaxEstimatedEdgeWeight(LoopBB, successors(BB));
-
- if (MaxWeight)
- propagateEstimatedBlockWeight(LoopBB, DT, PDT, MaxWeight.getValue(),
- BlockWorkList, LoopWorkList);
- }
- } while (!BlockWorkList.empty() || !LoopWorkList.empty());
-}
-
-// Calculate edge probabilities based on block's estimated weight.
-// Note that gathered weights were not scaled for loops. Thus edges entering
-// and exiting loops requires special processing.
-bool BranchProbabilityInfo::calcEstimatedHeuristics(const BasicBlock *BB) {
- assert(BB->getTerminator()->getNumSuccessors() > 1 &&
- "expected more than one successor!");
-
- const LoopBlock LoopBB = getLoopBlock(BB);
-
- SmallPtrSet<const BasicBlock *, 8> UnlikelyBlocks;
- uint32_t TC = LBH_TAKEN_WEIGHT / LBH_NONTAKEN_WEIGHT;
- if (LoopBB.getLoop())
- computeUnlikelySuccessors(BB, LoopBB.getLoop(), UnlikelyBlocks);
-
- // Changed to 'true' if at least one successor has estimated weight.
- bool FoundEstimatedWeight = false;
- SmallVector<uint32_t, 4> SuccWeights;
- uint64_t TotalWeight = 0;
- // Go over all successors of BB and put their weights into SuccWeights.
- for (const_succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) {
- const BasicBlock *SuccBB = *I;
- Optional<uint32_t> Weight;
- const LoopBlock SuccLoopBB = getLoopBlock(SuccBB);
- const LoopEdge Edge{LoopBB, SuccLoopBB};
-
- Weight = getEstimatedEdgeWeight(Edge);
-
- if (isLoopExitingEdge(Edge) &&
- // Avoid adjustment of ZERO weight since it should remain unchanged.
- Weight != static_cast<uint32_t>(BlockExecWeight::ZERO)) {
- // Scale down loop exiting weight by trip count.
- Weight = std::max(
- static_cast<uint32_t>(BlockExecWeight::LOWEST_NON_ZERO),
- Weight.getValueOr(static_cast<uint32_t>(BlockExecWeight::DEFAULT)) /
- TC);
- }
- bool IsUnlikelyEdge = LoopBB.getLoop() && UnlikelyBlocks.contains(SuccBB);
- if (IsUnlikelyEdge &&
- // Avoid adjustment of ZERO weight since it should remain unchanged.
- Weight != static_cast<uint32_t>(BlockExecWeight::ZERO)) {
- // 'Unlikely' blocks have twice lower weight.
- Weight = std::max(
- static_cast<uint32_t>(BlockExecWeight::LOWEST_NON_ZERO),
- Weight.getValueOr(static_cast<uint32_t>(BlockExecWeight::DEFAULT)) /
- 2);
- }
-
- if (Weight)
- FoundEstimatedWeight = true;
-
- auto WeightVal =
- Weight.getValueOr(static_cast<uint32_t>(BlockExecWeight::DEFAULT));
- TotalWeight += WeightVal;
- SuccWeights.push_back(WeightVal);
+ };
+
+ // Important note regarding the order of checks. They are ordered by weight
+ // from lowest to highest. Doing that allows to avoid "unstable" results
+ // when several conditions heuristics can be applied simultaneously.
+ if (isa<UnreachableInst>(BB->getTerminator()) ||
+ // If this block is terminated by a call to
+ // @llvm.experimental.deoptimize then treat it like an unreachable
+ // since it is expected to practically never execute.
+ // TODO: Should we actually treat as never returning call?
+ BB->getTerminatingDeoptimizeCall())
+ return hasNoReturn(BB)
+ ? static_cast<uint32_t>(BlockExecWeight::NORETURN)
+ : static_cast<uint32_t>(BlockExecWeight::UNREACHABLE);
+
+ // Check if the block is 'unwind' handler of some invoke instruction.
+ for (const auto *Pred : predecessors(BB))
+ if (Pred)
+ if (const auto *II = dyn_cast<InvokeInst>(Pred->getTerminator()))
+ if (II->getUnwindDest() == BB)
+ return static_cast<uint32_t>(BlockExecWeight::UNWIND);
+
+ // Check if the block contains 'cold' call.
+ for (const auto &I : *BB)
+ if (const CallInst *CI = dyn_cast<CallInst>(&I))
+ if (CI->hasFnAttr(Attribute::Cold))
+ return static_cast<uint32_t>(BlockExecWeight::COLD);
+
+ return None;
+}
+
+// Does RPO traversal over all blocks in \p F and assigns weights to
+// 'unreachable', 'noreturn', 'cold', 'unwind' blocks. In addition it does its
+// best to propagate the weight to up/down the IR.
+void BranchProbabilityInfo::computeEestimateBlockWeight(
+ const Function &F, DominatorTree *DT, PostDominatorTree *PDT) {
+ SmallVector<BasicBlock *, 8> BlockWorkList;
+ SmallVector<LoopBlock, 8> LoopWorkList;
+
+ // By doing RPO we make sure that all predecessors already have weights
+ // calculated before visiting theirs successors.
+ ReversePostOrderTraversal<const Function *> RPOT(&F);
+ for (const auto *BB : RPOT)
+ if (auto BBWeight = getInitialEstimatedBlockWeight(BB))
+ // If we were able to find estimated weight for the block set it to this
+ // block and propagate up the IR.
+ propagateEstimatedBlockWeight(getLoopBlock(BB), DT, PDT,
+ BBWeight.getValue(), BlockWorkList,
+ LoopWorkList);
+
+ // BlockWorklist/LoopWorkList contains blocks/loops with at least one
+ // successor/exit having estimated weight. Try to propagate weight to such
+ // blocks/loops from successors/exits.
+ // Process loops and blocks. Order is not important.
+ do {
+ while (!LoopWorkList.empty()) {
+ const LoopBlock LoopBB = LoopWorkList.pop_back_val();
+
+ if (EstimatedLoopWeight.count(LoopBB.getLoopData()))
+ continue;
+
+ SmallVector<BasicBlock *, 4> Exits;
+ getLoopExitBlocks(LoopBB, Exits);
+ auto LoopWeight = getMaxEstimatedEdgeWeight(
+ LoopBB, make_range(Exits.begin(), Exits.end()));
+
+ if (LoopWeight) {
+ // If we never exit the loop then we can enter it once at maximum.
+ if (LoopWeight <= static_cast<uint32_t>(BlockExecWeight::UNREACHABLE))
+ LoopWeight = static_cast<uint32_t>(BlockExecWeight::LOWEST_NON_ZERO);
+
+ EstimatedLoopWeight.insert(
+ {LoopBB.getLoopData(), LoopWeight.getValue()});
+ // Add all blocks entering the loop into working list.
+ getLoopEnterBlocks(LoopBB, BlockWorkList);
+ }
+ }
+
+ while (!BlockWorkList.empty()) {
+ // We can reach here only if BlockWorkList is not empty.
+ const BasicBlock *BB = BlockWorkList.pop_back_val();
+ if (EstimatedBlockWeight.count(BB))
+ continue;
+
+ // We take maximum over all weights of successors. In other words we take
+ // weight of "hot" path. In theory we can probably find a better function
+ // which gives higher accuracy results (comparing to "maximum") but I
+ // can't
+ // think of any right now. And I doubt it will make any difference in
+ // practice.
+ const LoopBlock LoopBB = getLoopBlock(BB);
+ auto MaxWeight = getMaxEstimatedEdgeWeight(LoopBB, successors(BB));
+
+ if (MaxWeight)
+ propagateEstimatedBlockWeight(LoopBB, DT, PDT, MaxWeight.getValue(),
+ BlockWorkList, LoopWorkList);
+ }
+ } while (!BlockWorkList.empty() || !LoopWorkList.empty());
+}
+
+// Calculate edge probabilities based on block's estimated weight.
+// Note that gathered weights were not scaled for loops. Thus edges entering
+// and exiting loops requires special processing.
+bool BranchProbabilityInfo::calcEstimatedHeuristics(const BasicBlock *BB) {
+ assert(BB->getTerminator()->getNumSuccessors() > 1 &&
+ "expected more than one successor!");
+
+ const LoopBlock LoopBB = getLoopBlock(BB);
+
+ SmallPtrSet<const BasicBlock *, 8> UnlikelyBlocks;
+ uint32_t TC = LBH_TAKEN_WEIGHT / LBH_NONTAKEN_WEIGHT;
+ if (LoopBB.getLoop())
+ computeUnlikelySuccessors(BB, LoopBB.getLoop(), UnlikelyBlocks);
+
+ // Changed to 'true' if at least one successor has estimated weight.
+ bool FoundEstimatedWeight = false;
+ SmallVector<uint32_t, 4> SuccWeights;
+ uint64_t TotalWeight = 0;
+ // Go over all successors of BB and put their weights into SuccWeights.
+ for (const_succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) {
+ const BasicBlock *SuccBB = *I;
+ Optional<uint32_t> Weight;
+ const LoopBlock SuccLoopBB = getLoopBlock(SuccBB);
+ const LoopEdge Edge{LoopBB, SuccLoopBB};
+
+ Weight = getEstimatedEdgeWeight(Edge);
+
+ if (isLoopExitingEdge(Edge) &&
+ // Avoid adjustment of ZERO weight since it should remain unchanged.
+ Weight != static_cast<uint32_t>(BlockExecWeight::ZERO)) {
+ // Scale down loop exiting weight by trip count.
+ Weight = std::max(
+ static_cast<uint32_t>(BlockExecWeight::LOWEST_NON_ZERO),
+ Weight.getValueOr(static_cast<uint32_t>(BlockExecWeight::DEFAULT)) /
+ TC);
+ }
+ bool IsUnlikelyEdge = LoopBB.getLoop() && UnlikelyBlocks.contains(SuccBB);
+ if (IsUnlikelyEdge &&
+ // Avoid adjustment of ZERO weight since it should remain unchanged.
+ Weight != static_cast<uint32_t>(BlockExecWeight::ZERO)) {
+ // 'Unlikely' blocks have twice lower weight.
+ Weight = std::max(
+ static_cast<uint32_t>(BlockExecWeight::LOWEST_NON_ZERO),
+ Weight.getValueOr(static_cast<uint32_t>(BlockExecWeight::DEFAULT)) /
+ 2);
+ }
+
+ if (Weight)
+ FoundEstimatedWeight = true;
+
+ auto WeightVal =
+ Weight.getValueOr(static_cast<uint32_t>(BlockExecWeight::DEFAULT));
+ TotalWeight += WeightVal;
+ SuccWeights.push_back(WeightVal);
}
- // If non of blocks have estimated weight bail out.
- // If TotalWeight is 0 that means weight of each successor is 0 as well and
- // equally likely. Bail out early to not deal with devision by zero.
- if (!FoundEstimatedWeight || TotalWeight == 0)
- return false;
-
- assert(SuccWeights.size() == succ_size(BB) && "Missed successor?");
- const unsigned SuccCount = SuccWeights.size();
-
- // If the sum of weights does not fit in 32 bits, scale every weight down
- // accordingly.
- if (TotalWeight > UINT32_MAX) {
- uint64_t ScalingFactor = TotalWeight / UINT32_MAX + 1;
- TotalWeight = 0;
- for (unsigned Idx = 0; Idx < SuccCount; ++Idx) {
- SuccWeights[Idx] /= ScalingFactor;
- if (SuccWeights[Idx] == static_cast<uint32_t>(BlockExecWeight::ZERO))
- SuccWeights[Idx] =
- static_cast<uint32_t>(BlockExecWeight::LOWEST_NON_ZERO);
- TotalWeight += SuccWeights[Idx];
- }
- assert(TotalWeight <= UINT32_MAX && "Total weight overflows");
+ // If non of blocks have estimated weight bail out.
+ // If TotalWeight is 0 that means weight of each successor is 0 as well and
+ // equally likely. Bail out early to not deal with devision by zero.
+ if (!FoundEstimatedWeight || TotalWeight == 0)
+ return false;
+
+ assert(SuccWeights.size() == succ_size(BB) && "Missed successor?");
+ const unsigned SuccCount = SuccWeights.size();
+
+ // If the sum of weights does not fit in 32 bits, scale every weight down
+ // accordingly.
+ if (TotalWeight > UINT32_MAX) {
+ uint64_t ScalingFactor = TotalWeight / UINT32_MAX + 1;
+ TotalWeight = 0;
+ for (unsigned Idx = 0; Idx < SuccCount; ++Idx) {
+ SuccWeights[Idx] /= ScalingFactor;
+ if (SuccWeights[Idx] == static_cast<uint32_t>(BlockExecWeight::ZERO))
+ SuccWeights[Idx] =
+ static_cast<uint32_t>(BlockExecWeight::LOWEST_NON_ZERO);
+ TotalWeight += SuccWeights[Idx];
+ }
+ assert(TotalWeight <= UINT32_MAX && "Total weight overflows");
}
- // Finally set probabilities to edges according to estimated block weights.
- SmallVector<BranchProbability, 4> EdgeProbabilities(
- SuccCount, BranchProbability::getUnknown());
-
- for (unsigned Idx = 0; Idx < SuccCount; ++Idx) {
- EdgeProbabilities[Idx] =
- BranchProbability(SuccWeights[Idx], (uint32_t)TotalWeight);
+ // Finally set probabilities to edges according to estimated block weights.
+ SmallVector<BranchProbability, 4> EdgeProbabilities(
+ SuccCount, BranchProbability::getUnknown());
+
+ for (unsigned Idx = 0; Idx < SuccCount; ++Idx) {
+ EdgeProbabilities[Idx] =
+ BranchProbability(SuccWeights[Idx], (uint32_t)TotalWeight);
}
setEdgeProbability(BB, EdgeProbabilities);
return true;
@@ -940,7 +940,7 @@ bool BranchProbabilityInfo::calcZeroHeuristics(const BasicBlock *BB,
// we don't have information about probabilities.
if (Instruction *LHS = dyn_cast<Instruction>(CI->getOperand(0)))
if (LHS->getOpcode() == Instruction::And)
- if (ConstantInt *AndRHS = GetConstantInt(LHS->getOperand(1)))
+ if (ConstantInt *AndRHS = GetConstantInt(LHS->getOperand(1)))
if (AndRHS->getValue().isPowerOf2())
return false;
@@ -956,8 +956,8 @@ bool BranchProbabilityInfo::calcZeroHeuristics(const BasicBlock *BB,
Func == LibFunc_strcmp ||
Func == LibFunc_strncasecmp ||
Func == LibFunc_strncmp ||
- Func == LibFunc_memcmp ||
- Func == LibFunc_bcmp) {
+ Func == LibFunc_memcmp ||
+ Func == LibFunc_bcmp) {
// strcmp and similar functions return zero, negative, or positive, if the
// first string is equal, less, or greater than the second. We consider it
// likely that the strings are not equal, so a comparison with zero is
@@ -1114,7 +1114,7 @@ BranchProbabilityInfo::getHotSucc(const BasicBlock *BB) const {
auto MaxProb = BranchProbability::getZero();
const BasicBlock *MaxSucc = nullptr;
- for (const auto *Succ : successors(BB)) {
+ for (const auto *Succ : successors(BB)) {
auto Prob = getEdgeProbability(BB, Succ);
if (Prob > MaxProb) {
MaxProb = Prob;
@@ -1137,10 +1137,10 @@ BranchProbability
BranchProbabilityInfo::getEdgeProbability(const BasicBlock *Src,
unsigned IndexInSuccessors) const {
auto I = Probs.find(std::make_pair(Src, IndexInSuccessors));
- assert((Probs.end() == Probs.find(std::make_pair(Src, 0))) ==
- (Probs.end() == I) &&
- "Probability for I-th successor must always be defined along with the "
- "probability for the first successor");
+ assert((Probs.end() == Probs.find(std::make_pair(Src, 0))) ==
+ (Probs.end() == I) &&
+ "Probability for I-th successor must always be defined along with the "
+ "probability for the first successor");
if (I != Probs.end())
return I->second;
@@ -1159,32 +1159,32 @@ BranchProbabilityInfo::getEdgeProbability(const BasicBlock *Src,
BranchProbability
BranchProbabilityInfo::getEdgeProbability(const BasicBlock *Src,
const BasicBlock *Dst) const {
- if (!Probs.count(std::make_pair(Src, 0)))
- return BranchProbability(llvm::count(successors(Src), Dst), succ_size(Src));
-
+ if (!Probs.count(std::make_pair(Src, 0)))
+ return BranchProbability(llvm::count(successors(Src), Dst), succ_size(Src));
+
auto Prob = BranchProbability::getZero();
for (const_succ_iterator I = succ_begin(Src), E = succ_end(Src); I != E; ++I)
- if (*I == Dst)
- Prob += Probs.find(std::make_pair(Src, I.getSuccessorIndex()))->second;
+ if (*I == Dst)
+ Prob += Probs.find(std::make_pair(Src, I.getSuccessorIndex()))->second;
- return Prob;
+ return Prob;
}
/// Set the edge probability for all edges at once.
void BranchProbabilityInfo::setEdgeProbability(
const BasicBlock *Src, const SmallVectorImpl<BranchProbability> &Probs) {
assert(Src->getTerminator()->getNumSuccessors() == Probs.size());
- eraseBlock(Src); // Erase stale data if any.
+ eraseBlock(Src); // Erase stale data if any.
if (Probs.size() == 0)
return; // Nothing to set.
- Handles.insert(BasicBlockCallbackVH(Src, this));
+ Handles.insert(BasicBlockCallbackVH(Src, this));
uint64_t TotalNumerator = 0;
for (unsigned SuccIdx = 0; SuccIdx < Probs.size(); ++SuccIdx) {
- this->Probs[std::make_pair(Src, SuccIdx)] = Probs[SuccIdx];
- LLVM_DEBUG(dbgs() << "set edge " << Src->getName() << " -> " << SuccIdx
- << " successor probability to " << Probs[SuccIdx]
- << "\n");
+ this->Probs[std::make_pair(Src, SuccIdx)] = Probs[SuccIdx];
+ LLVM_DEBUG(dbgs() << "set edge " << Src->getName() << " -> " << SuccIdx
+ << " successor probability to " << Probs[SuccIdx]
+ << "\n");
TotalNumerator += Probs[SuccIdx].getNumerator();
}
@@ -1197,25 +1197,25 @@ void BranchProbabilityInfo::setEdgeProbability(
assert(TotalNumerator >= BranchProbability::getDenominator() - Probs.size());
}
-void BranchProbabilityInfo::copyEdgeProbabilities(BasicBlock *Src,
- BasicBlock *Dst) {
- eraseBlock(Dst); // Erase stale data if any.
- unsigned NumSuccessors = Src->getTerminator()->getNumSuccessors();
- assert(NumSuccessors == Dst->getTerminator()->getNumSuccessors());
- if (NumSuccessors == 0)
- return; // Nothing to set.
- if (this->Probs.find(std::make_pair(Src, 0)) == this->Probs.end())
- return; // No probability is set for edges from Src. Keep the same for Dst.
-
- Handles.insert(BasicBlockCallbackVH(Dst, this));
- for (unsigned SuccIdx = 0; SuccIdx < NumSuccessors; ++SuccIdx) {
- auto Prob = this->Probs[std::make_pair(Src, SuccIdx)];
- this->Probs[std::make_pair(Dst, SuccIdx)] = Prob;
- LLVM_DEBUG(dbgs() << "set edge " << Dst->getName() << " -> " << SuccIdx
- << " successor probability to " << Prob << "\n");
- }
-}
-
+void BranchProbabilityInfo::copyEdgeProbabilities(BasicBlock *Src,
+ BasicBlock *Dst) {
+ eraseBlock(Dst); // Erase stale data if any.
+ unsigned NumSuccessors = Src->getTerminator()->getNumSuccessors();
+ assert(NumSuccessors == Dst->getTerminator()->getNumSuccessors());
+ if (NumSuccessors == 0)
+ return; // Nothing to set.
+ if (this->Probs.find(std::make_pair(Src, 0)) == this->Probs.end())
+ return; // No probability is set for edges from Src. Keep the same for Dst.
+
+ Handles.insert(BasicBlockCallbackVH(Dst, this));
+ for (unsigned SuccIdx = 0; SuccIdx < NumSuccessors; ++SuccIdx) {
+ auto Prob = this->Probs[std::make_pair(Src, SuccIdx)];
+ this->Probs[std::make_pair(Dst, SuccIdx)] = Prob;
+ LLVM_DEBUG(dbgs() << "set edge " << Dst->getName() << " -> " << SuccIdx
+ << " successor probability to " << Prob << "\n");
+ }
+}
+
raw_ostream &
BranchProbabilityInfo::printEdgeProbability(raw_ostream &OS,
const BasicBlock *Src,
@@ -1229,55 +1229,55 @@ BranchProbabilityInfo::printEdgeProbability(raw_ostream &OS,
}
void BranchProbabilityInfo::eraseBlock(const BasicBlock *BB) {
- LLVM_DEBUG(dbgs() << "eraseBlock " << BB->getName() << "\n");
-
- // Note that we cannot use successors of BB because the terminator of BB may
- // have changed when eraseBlock is called as a BasicBlockCallbackVH callback.
- // Instead we remove prob data for the block by iterating successors by their
- // indices from 0 till the last which exists. There could not be prob data for
- // a pair (BB, N) if there is no data for (BB, N-1) because the data is always
- // set for all successors from 0 to M at once by the method
- // setEdgeProbability().
- Handles.erase(BasicBlockCallbackVH(BB, this));
- for (unsigned I = 0;; ++I) {
- auto MapI = Probs.find(std::make_pair(BB, I));
- if (MapI == Probs.end()) {
- assert(Probs.count(std::make_pair(BB, I + 1)) == 0 &&
- "Must be no more successors");
- return;
- }
- Probs.erase(MapI);
+ LLVM_DEBUG(dbgs() << "eraseBlock " << BB->getName() << "\n");
+
+ // Note that we cannot use successors of BB because the terminator of BB may
+ // have changed when eraseBlock is called as a BasicBlockCallbackVH callback.
+ // Instead we remove prob data for the block by iterating successors by their
+ // indices from 0 till the last which exists. There could not be prob data for
+ // a pair (BB, N) if there is no data for (BB, N-1) because the data is always
+ // set for all successors from 0 to M at once by the method
+ // setEdgeProbability().
+ Handles.erase(BasicBlockCallbackVH(BB, this));
+ for (unsigned I = 0;; ++I) {
+ auto MapI = Probs.find(std::make_pair(BB, I));
+ if (MapI == Probs.end()) {
+ assert(Probs.count(std::make_pair(BB, I + 1)) == 0 &&
+ "Must be no more successors");
+ return;
+ }
+ Probs.erase(MapI);
}
}
-void BranchProbabilityInfo::calculate(const Function &F, const LoopInfo &LoopI,
+void BranchProbabilityInfo::calculate(const Function &F, const LoopInfo &LoopI,
const TargetLibraryInfo *TLI,
- DominatorTree *DT,
+ DominatorTree *DT,
PostDominatorTree *PDT) {
LLVM_DEBUG(dbgs() << "---- Branch Probability Info : " << F.getName()
<< " ----\n\n");
LastF = &F; // Store the last function we ran on for printing.
- LI = &LoopI;
+ LI = &LoopI;
- SccI = std::make_unique<SccInfo>(F);
+ SccI = std::make_unique<SccInfo>(F);
- assert(EstimatedBlockWeight.empty());
- assert(EstimatedLoopWeight.empty());
+ assert(EstimatedBlockWeight.empty());
+ assert(EstimatedLoopWeight.empty());
- std::unique_ptr<DominatorTree> DTPtr;
+ std::unique_ptr<DominatorTree> DTPtr;
std::unique_ptr<PostDominatorTree> PDTPtr;
- if (!DT) {
- DTPtr = std::make_unique<DominatorTree>(const_cast<Function &>(F));
- DT = DTPtr.get();
- }
-
+ if (!DT) {
+ DTPtr = std::make_unique<DominatorTree>(const_cast<Function &>(F));
+ DT = DTPtr.get();
+ }
+
if (!PDT) {
PDTPtr = std::make_unique<PostDominatorTree>(const_cast<Function &>(F));
PDT = PDTPtr.get();
}
- computeEestimateBlockWeight(F, DT, PDT);
+ computeEestimateBlockWeight(F, DT, PDT);
// Walk the basic blocks in post-order so that we can build up state about
// the successors of a block iteratively.
@@ -1289,7 +1289,7 @@ void BranchProbabilityInfo::calculate(const Function &F, const LoopInfo &LoopI,
continue;
if (calcMetadataWeights(BB))
continue;
- if (calcEstimatedHeuristics(BB))
+ if (calcEstimatedHeuristics(BB))
continue;
if (calcPointerHeuristics(BB))
continue;
@@ -1299,9 +1299,9 @@ void BranchProbabilityInfo::calculate(const Function &F, const LoopInfo &LoopI,
continue;
}
- EstimatedLoopWeight.clear();
- EstimatedBlockWeight.clear();
- SccI.reset();
+ EstimatedLoopWeight.clear();
+ EstimatedBlockWeight.clear();
+ SccI.reset();
if (PrintBranchProb &&
(PrintBranchProbFuncName.empty() ||
@@ -1318,7 +1318,7 @@ void BranchProbabilityInfoWrapperPass::getAnalysisUsage(
AU.addRequired<DominatorTreeWrapperPass>();
AU.addRequired<LoopInfoWrapperPass>();
AU.addRequired<TargetLibraryInfoWrapperPass>();
- AU.addRequired<DominatorTreeWrapperPass>();
+ AU.addRequired<DominatorTreeWrapperPass>();
AU.addRequired<PostDominatorTreeWrapperPass>();
AU.setPreservesAll();
}
@@ -1327,10 +1327,10 @@ bool BranchProbabilityInfoWrapperPass::runOnFunction(Function &F) {
const LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
const TargetLibraryInfo &TLI =
getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
- DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
PostDominatorTree &PDT =
getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
- BPI.calculate(F, LI, &TLI, &DT, &PDT);
+ BPI.calculate(F, LI, &TLI, &DT, &PDT);
return false;
}
@@ -1347,7 +1347,7 @@ BranchProbabilityAnalysis::run(Function &F, FunctionAnalysisManager &AM) {
BranchProbabilityInfo BPI;
BPI.calculate(F, AM.getResult<LoopAnalysis>(F),
&AM.getResult<TargetLibraryAnalysis>(F),
- &AM.getResult<DominatorTreeAnalysis>(F),
+ &AM.getResult<DominatorTreeAnalysis>(F),
&AM.getResult<PostDominatorTreeAnalysis>(F));
return BPI;
}
diff --git a/contrib/libs/llvm12/lib/Analysis/CFG.cpp b/contrib/libs/llvm12/lib/Analysis/CFG.cpp
index 9ddc7e9d3d..33602ed716 100644
--- a/contrib/libs/llvm12/lib/Analysis/CFG.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/CFG.cpp
@@ -14,18 +14,18 @@
#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/Dominators.h"
-#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/CommandLine.h"
using namespace llvm;
-// The max number of basic blocks explored during reachability analysis between
-// two basic blocks. This is kept reasonably small to limit compile time when
-// repeatedly used by clients of this analysis (such as captureTracking).
-static cl::opt<unsigned> DefaultMaxBBsToExplore(
- "dom-tree-reachability-max-bbs-to-explore", cl::Hidden,
- cl::desc("Max number of BBs to explore for reachability analysis"),
- cl::init(32));
-
+// The max number of basic blocks explored during reachability analysis between
+// two basic blocks. This is kept reasonably small to limit compile time when
+// repeatedly used by clients of this analysis (such as captureTracking).
+static cl::opt<unsigned> DefaultMaxBBsToExplore(
+ "dom-tree-reachability-max-bbs-to-explore", cl::Hidden,
+ cl::desc("Max number of BBs to explore for reachability analysis"),
+ cl::init(32));
+
/// FindFunctionBackedges - Analyze the specified function to find all of the
/// loop backedges in the function and return them. This is a relatively cheap
/// (compared to computing dominators and loop info) analysis.
@@ -103,7 +103,7 @@ bool llvm::isCriticalEdge(const Instruction *TI, const BasicBlock *Dest,
assert(TI->isTerminator() && "Must be a terminator to have successors!");
if (TI->getNumSuccessors() == 1) return false;
- assert(is_contained(predecessors(Dest), TI->getParent()) &&
+ assert(is_contained(predecessors(Dest), TI->getParent()) &&
"No edge between TI's block and Dest.");
const_pred_iterator I = pred_begin(Dest), E = pred_end(Dest);
@@ -161,7 +161,7 @@ bool llvm::isPotentiallyReachableFromMany(
const Loop *StopLoop = LI ? getOutermostLoop(LI, StopBB) : nullptr;
- unsigned Limit = DefaultMaxBBsToExplore;
+ unsigned Limit = DefaultMaxBBsToExplore;
SmallPtrSet<const BasicBlock*, 32> Visited;
do {
BasicBlock *BB = Worklist.pop_back_val();
diff --git a/contrib/libs/llvm12/lib/Analysis/CFGPrinter.cpp b/contrib/libs/llvm12/lib/Analysis/CFGPrinter.cpp
index 735a345f98..33b5a46032 100644
--- a/contrib/libs/llvm12/lib/Analysis/CFGPrinter.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/CFGPrinter.cpp
@@ -272,17 +272,17 @@ FunctionPass *llvm::createCFGOnlyPrinterLegacyPassPass() {
void DOTGraphTraits<DOTFuncInfo *>::computeHiddenNodes(const Function *F) {
auto evaluateBB = [&](const BasicBlock *Node) {
- if (succ_empty(Node)) {
+ if (succ_empty(Node)) {
const Instruction *TI = Node->getTerminator();
isHiddenBasicBlock[Node] =
(HideUnreachablePaths && isa<UnreachableInst>(TI)) ||
(HideDeoptimizePaths && Node->getTerminatingDeoptimizeCall());
return;
}
- isHiddenBasicBlock[Node] =
- llvm::all_of(successors(Node), [this](const BasicBlock *BB) {
- return isHiddenBasicBlock[BB];
- });
+ isHiddenBasicBlock[Node] =
+ llvm::all_of(successors(Node), [this](const BasicBlock *BB) {
+ return isHiddenBasicBlock[BB];
+ });
};
/// The post order traversal iteration is done to know the status of
/// isHiddenBasicBlock for all the successors on the current BB.
@@ -290,8 +290,8 @@ void DOTGraphTraits<DOTFuncInfo *>::computeHiddenNodes(const Function *F) {
evaluateBB);
}
-bool DOTGraphTraits<DOTFuncInfo *>::isNodeHidden(const BasicBlock *Node,
- const DOTFuncInfo *CFGInfo) {
+bool DOTGraphTraits<DOTFuncInfo *>::isNodeHidden(const BasicBlock *Node,
+ const DOTFuncInfo *CFGInfo) {
// If both restricting flags are false, all nodes are displayed.
if (!HideUnreachablePaths && !HideDeoptimizePaths)
return false;
diff --git a/contrib/libs/llvm12/lib/Analysis/CFLAndersAliasAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/CFLAndersAliasAnalysis.cpp
index 9cc8c52c30..2be23a56cc 100644
--- a/contrib/libs/llvm12/lib/Analysis/CFLAndersAliasAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/CFLAndersAliasAnalysis.cpp
@@ -559,7 +559,7 @@ bool CFLAndersAAResult::FunctionInfo::mayAlias(
if (RangePair.first != RangePair.second) {
// Be conservative about unknown sizes
- if (!MaybeLHSSize.hasValue() || !MaybeRHSSize.hasValue())
+ if (!MaybeLHSSize.hasValue() || !MaybeRHSSize.hasValue())
return true;
const uint64_t LHSSize = MaybeLHSSize.getValue();
diff --git a/contrib/libs/llvm12/lib/Analysis/CGSCCPassManager.cpp b/contrib/libs/llvm12/lib/Analysis/CGSCCPassManager.cpp
index 6f1c0be4c0..3230e9036b 100644
--- a/contrib/libs/llvm12/lib/Analysis/CGSCCPassManager.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/CGSCCPassManager.cpp
@@ -20,12 +20,12 @@
#include "llvm/IR/Instruction.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/PassManagerImpl.h"
-#include "llvm/IR/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/TimeProfiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
@@ -39,11 +39,11 @@ using namespace llvm;
// template typedefs.
namespace llvm {
-static cl::opt<bool> AbortOnMaxDevirtIterationsReached(
- "abort-on-max-devirt-iterations-reached",
- cl::desc("Abort when the max iterations for devirtualization CGSCC repeat "
- "pass is reached"));
-
+static cl::opt<bool> AbortOnMaxDevirtIterationsReached(
+ "abort-on-max-devirt-iterations-reached",
+ cl::desc("Abort when the max iterations for devirtualization CGSCC repeat "
+ "pass is reached"));
+
// Explicit instantiations for the core proxy templates.
template class AllAnalysesOn<LazyCallGraph::SCC>;
template class AnalysisManager<LazyCallGraph::SCC, LazyCallGraph &>;
@@ -93,9 +93,9 @@ PassManager<LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &,
}
if (UR.InvalidatedSCCs.count(C))
- PI.runAfterPassInvalidated<LazyCallGraph::SCC>(*Pass, PassPA);
+ PI.runAfterPassInvalidated<LazyCallGraph::SCC>(*Pass, PassPA);
else
- PI.runAfterPass<LazyCallGraph::SCC>(*Pass, *C, PassPA);
+ PI.runAfterPass<LazyCallGraph::SCC>(*Pass, *C, PassPA);
// Update the SCC if necessary.
C = UR.UpdatedC ? UR.UpdatedC : C;
@@ -148,452 +148,452 @@ PassManager<LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &,
return PA;
}
-PreservedAnalyses
-ModuleToPostOrderCGSCCPassAdaptor::run(Module &M, ModuleAnalysisManager &AM) {
- // Setup the CGSCC analysis manager from its proxy.
- CGSCCAnalysisManager &CGAM =
- AM.getResult<CGSCCAnalysisManagerModuleProxy>(M).getManager();
-
- // Get the call graph for this module.
- LazyCallGraph &CG = AM.getResult<LazyCallGraphAnalysis>(M);
-
- // Get Function analysis manager from its proxy.
- FunctionAnalysisManager &FAM =
- AM.getCachedResult<FunctionAnalysisManagerModuleProxy>(M)->getManager();
-
- // We keep worklists to allow us to push more work onto the pass manager as
- // the passes are run.
- SmallPriorityWorklist<LazyCallGraph::RefSCC *, 1> RCWorklist;
- SmallPriorityWorklist<LazyCallGraph::SCC *, 1> CWorklist;
-
- // Keep sets for invalidated SCCs and RefSCCs that should be skipped when
- // iterating off the worklists.
- SmallPtrSet<LazyCallGraph::RefSCC *, 4> InvalidRefSCCSet;
- SmallPtrSet<LazyCallGraph::SCC *, 4> InvalidSCCSet;
-
- SmallDenseSet<std::pair<LazyCallGraph::Node *, LazyCallGraph::SCC *>, 4>
- InlinedInternalEdges;
-
- CGSCCUpdateResult UR = {
- RCWorklist, CWorklist, InvalidRefSCCSet, InvalidSCCSet,
- nullptr, nullptr, PreservedAnalyses::all(), InlinedInternalEdges,
- {}};
-
- // Request PassInstrumentation from analysis manager, will use it to run
- // instrumenting callbacks for the passes later.
- PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(M);
-
- PreservedAnalyses PA = PreservedAnalyses::all();
- CG.buildRefSCCs();
- for (auto RCI = CG.postorder_ref_scc_begin(),
- RCE = CG.postorder_ref_scc_end();
- RCI != RCE;) {
- assert(RCWorklist.empty() &&
- "Should always start with an empty RefSCC worklist");
- // The postorder_ref_sccs range we are walking is lazily constructed, so
- // we only push the first one onto the worklist. The worklist allows us
- // to capture *new* RefSCCs created during transformations.
- //
- // We really want to form RefSCCs lazily because that makes them cheaper
- // to update as the program is simplified and allows us to have greater
- // cache locality as forming a RefSCC touches all the parts of all the
- // functions within that RefSCC.
- //
- // We also eagerly increment the iterator to the next position because
- // the CGSCC passes below may delete the current RefSCC.
- RCWorklist.insert(&*RCI++);
-
- do {
- LazyCallGraph::RefSCC *RC = RCWorklist.pop_back_val();
- if (InvalidRefSCCSet.count(RC)) {
- LLVM_DEBUG(dbgs() << "Skipping an invalid RefSCC...\n");
- continue;
- }
-
- assert(CWorklist.empty() &&
- "Should always start with an empty SCC worklist");
-
- LLVM_DEBUG(dbgs() << "Running an SCC pass across the RefSCC: " << *RC
- << "\n");
-
- // The top of the worklist may *also* be the same SCC we just ran over
- // (and invalidated for). Keep track of that last SCC we processed due
- // to SCC update to avoid redundant processing when an SCC is both just
- // updated itself and at the top of the worklist.
- LazyCallGraph::SCC *LastUpdatedC = nullptr;
-
- // Push the initial SCCs in reverse post-order as we'll pop off the
- // back and so see this in post-order.
- for (LazyCallGraph::SCC &C : llvm::reverse(*RC))
- CWorklist.insert(&C);
-
- do {
- LazyCallGraph::SCC *C = CWorklist.pop_back_val();
- // Due to call graph mutations, we may have invalid SCCs or SCCs from
- // other RefSCCs in the worklist. The invalid ones are dead and the
- // other RefSCCs should be queued above, so we just need to skip both
- // scenarios here.
- if (InvalidSCCSet.count(C)) {
- LLVM_DEBUG(dbgs() << "Skipping an invalid SCC...\n");
- continue;
- }
- if (LastUpdatedC == C) {
- LLVM_DEBUG(dbgs() << "Skipping redundant run on SCC: " << *C << "\n");
- continue;
- }
- if (&C->getOuterRefSCC() != RC) {
- LLVM_DEBUG(dbgs() << "Skipping an SCC that is now part of some other "
- "RefSCC...\n");
- continue;
- }
-
- // Ensure we can proxy analysis updates from the CGSCC analysis manager
- // into the the Function analysis manager by getting a proxy here.
- // This also needs to update the FunctionAnalysisManager, as this may be
- // the first time we see this SCC.
- CGAM.getResult<FunctionAnalysisManagerCGSCCProxy>(*C, CG).updateFAM(
- FAM);
-
- // Each time we visit a new SCC pulled off the worklist,
- // a transformation of a child SCC may have also modified this parent
- // and invalidated analyses. So we invalidate using the update record's
- // cross-SCC preserved set. This preserved set is intersected by any
- // CGSCC pass that handles invalidation (primarily pass managers) prior
- // to marking its SCC as preserved. That lets us track everything that
- // might need invalidation across SCCs without excessive invalidations
- // on a single SCC.
- //
- // This essentially allows SCC passes to freely invalidate analyses
- // of any ancestor SCC. If this becomes detrimental to successfully
- // caching analyses, we could force each SCC pass to manually
- // invalidate the analyses for any SCCs other than themselves which
- // are mutated. However, that seems to lose the robustness of the
- // pass-manager driven invalidation scheme.
- CGAM.invalidate(*C, UR.CrossSCCPA);
-
- do {
- // Check that we didn't miss any update scenario.
- assert(!InvalidSCCSet.count(C) && "Processing an invalid SCC!");
- assert(C->begin() != C->end() && "Cannot have an empty SCC!");
- assert(&C->getOuterRefSCC() == RC &&
- "Processing an SCC in a different RefSCC!");
-
- LastUpdatedC = UR.UpdatedC;
- UR.UpdatedRC = nullptr;
- UR.UpdatedC = nullptr;
-
- // Check the PassInstrumentation's BeforePass callbacks before
- // running the pass, skip its execution completely if asked to
- // (callback returns false).
- if (!PI.runBeforePass<LazyCallGraph::SCC>(*Pass, *C))
- continue;
-
- PreservedAnalyses PassPA;
- {
- TimeTraceScope TimeScope(Pass->name());
- PassPA = Pass->run(*C, CGAM, CG, UR);
- }
-
- if (UR.InvalidatedSCCs.count(C))
- PI.runAfterPassInvalidated<LazyCallGraph::SCC>(*Pass, PassPA);
- else
- PI.runAfterPass<LazyCallGraph::SCC>(*Pass, *C, PassPA);
-
- // Update the SCC and RefSCC if necessary.
- C = UR.UpdatedC ? UR.UpdatedC : C;
- RC = UR.UpdatedRC ? UR.UpdatedRC : RC;
-
- if (UR.UpdatedC) {
- // If we're updating the SCC, also update the FAM inside the proxy's
- // result.
- CGAM.getResult<FunctionAnalysisManagerCGSCCProxy>(*C, CG).updateFAM(
- FAM);
- }
-
- // 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)) {
- LLVM_DEBUG(dbgs() << "Skipping invalidated root or island SCC!\n");
- break;
- }
- // Check that we didn't miss any update scenario.
- assert(C->begin() != C->end() && "Cannot have an empty SCC!");
-
- // We handle invalidating the CGSCC analysis manager's information
- // for the (potentially updated) SCC here. Note that any other SCCs
- // whose structure has changed should have been invalidated by
- // whatever was updating the call graph. This SCC gets invalidated
- // late as it contains the nodes that were actively being
- // processed.
- CGAM.invalidate(*C, PassPA);
-
- // Then intersect the preserved set so that invalidation of module
- // analyses will eventually occur when the module pass completes.
- // Also intersect with the cross-SCC preserved set to capture any
- // cross-SCC invalidation.
- UR.CrossSCCPA.intersect(PassPA);
- PA.intersect(std::move(PassPA));
-
- // The pass may have restructured the call graph and refined the
- // current SCC and/or RefSCC. We need to update our current SCC and
- // RefSCC pointers to follow these. Also, when the current SCC is
- // refined, re-run the SCC pass over the newly refined SCC in order
- // to observe the most precise SCC model available. This inherently
- // cannot cycle excessively as it only happens when we split SCCs
- // apart, at most converging on a DAG of single nodes.
- // FIXME: If we ever start having RefSCC passes, we'll want to
- // iterate there too.
- if (UR.UpdatedC)
- 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
- // the processing when we check them in the loop above.
- } while (UR.UpdatedC);
- } while (!CWorklist.empty());
-
- // We only need to keep internal inlined edge information within
- // a RefSCC, clear it to save on space and let the next time we visit
- // any of these functions have a fresh start.
- InlinedInternalEdges.clear();
- } while (!RCWorklist.empty());
- }
-
- // By definition we preserve the call garph, all SCC analyses, and the
- // analysis proxies by handling them above and in any nested pass managers.
- PA.preserveSet<AllAnalysesOn<LazyCallGraph::SCC>>();
- PA.preserve<LazyCallGraphAnalysis>();
- PA.preserve<CGSCCAnalysisManagerModuleProxy>();
- PA.preserve<FunctionAnalysisManagerModuleProxy>();
- return PA;
-}
-
-PreservedAnalyses DevirtSCCRepeatedPass::run(LazyCallGraph::SCC &InitialC,
- CGSCCAnalysisManager &AM,
- LazyCallGraph &CG,
- CGSCCUpdateResult &UR) {
- PreservedAnalyses PA = PreservedAnalyses::all();
- PassInstrumentation PI =
- AM.getResult<PassInstrumentationAnalysis>(InitialC, CG);
-
- // The SCC may be refined while we are running passes over it, so set up
- // a pointer that we can update.
- LazyCallGraph::SCC *C = &InitialC;
-
- // Struct to track the counts of direct and indirect calls in each function
- // of the SCC.
- struct CallCount {
- int Direct;
- int Indirect;
- };
-
- // Put value handles on all of the indirect calls and return the number of
- // direct calls for each function in the SCC.
- auto ScanSCC = [](LazyCallGraph::SCC &C,
- SmallMapVector<Value *, WeakTrackingVH, 16> &CallHandles) {
- assert(CallHandles.empty() && "Must start with a clear set of handles.");
-
- SmallDenseMap<Function *, CallCount> CallCounts;
- CallCount CountLocal = {0, 0};
- for (LazyCallGraph::Node &N : C) {
- CallCount &Count =
- CallCounts.insert(std::make_pair(&N.getFunction(), CountLocal))
- .first->second;
- for (Instruction &I : instructions(N.getFunction()))
- if (auto *CB = dyn_cast<CallBase>(&I)) {
- if (CB->getCalledFunction()) {
- ++Count.Direct;
- } else {
- ++Count.Indirect;
- CallHandles.insert({CB, WeakTrackingVH(CB)});
- }
- }
- }
-
- return CallCounts;
- };
-
- UR.IndirectVHs.clear();
- // Populate the initial call handles and get the initial call counts.
- auto CallCounts = ScanSCC(*C, UR.IndirectVHs);
-
- for (int Iteration = 0;; ++Iteration) {
- if (!PI.runBeforePass<LazyCallGraph::SCC>(*Pass, *C))
- continue;
-
- PreservedAnalyses PassPA = Pass->run(*C, AM, CG, UR);
-
- if (UR.InvalidatedSCCs.count(C))
- PI.runAfterPassInvalidated<LazyCallGraph::SCC>(*Pass, PassPA);
- else
- PI.runAfterPass<LazyCallGraph::SCC>(*Pass, *C, PassPA);
-
- // If the SCC structure has changed, bail immediately and let the outer
- // CGSCC layer handle any iteration to reflect the refined structure.
- if (UR.UpdatedC && UR.UpdatedC != C) {
- PA.intersect(std::move(PassPA));
- break;
- }
-
- // Check that we didn't miss any update scenario.
- assert(!UR.InvalidatedSCCs.count(C) && "Processing an invalid SCC!");
- assert(C->begin() != C->end() && "Cannot have an empty SCC!");
-
- // Check whether any of the handles were devirtualized.
- bool Devirt = llvm::any_of(UR.IndirectVHs, [](auto &P) -> bool {
- if (P.second) {
- if (CallBase *CB = dyn_cast<CallBase>(P.second)) {
- if (CB->getCalledFunction()) {
- LLVM_DEBUG(dbgs() << "Found devirtualized call: " << *CB << "\n");
- return true;
- }
- }
- }
- return false;
- });
-
- // Rescan to build up a new set of handles and count how many direct
- // calls remain. If we decide to iterate, this also sets up the input to
- // the next iteration.
- UR.IndirectVHs.clear();
- auto NewCallCounts = ScanSCC(*C, UR.IndirectVHs);
-
- // If we haven't found an explicit devirtualization already see if we
- // have decreased the number of indirect calls and increased the number
- // of direct calls for any function in the SCC. This can be fooled by all
- // manner of transformations such as DCE and other things, but seems to
- // work well in practice.
- if (!Devirt)
- // Iterate over the keys in NewCallCounts, if Function also exists in
- // CallCounts, make the check below.
- for (auto &Pair : NewCallCounts) {
- auto &CallCountNew = Pair.second;
- auto CountIt = CallCounts.find(Pair.first);
- if (CountIt != CallCounts.end()) {
- const auto &CallCountOld = CountIt->second;
- if (CallCountOld.Indirect > CallCountNew.Indirect &&
- CallCountOld.Direct < CallCountNew.Direct) {
- Devirt = true;
- break;
- }
- }
- }
-
- if (!Devirt) {
- PA.intersect(std::move(PassPA));
- break;
- }
-
- // Otherwise, if we've already hit our max, we're done.
- if (Iteration >= MaxIterations) {
- if (AbortOnMaxDevirtIterationsReached)
- report_fatal_error("Max devirtualization iterations reached");
- LLVM_DEBUG(
- dbgs() << "Found another devirtualization after hitting the max "
- "number of repetitions ("
- << MaxIterations << ") on SCC: " << *C << "\n");
- PA.intersect(std::move(PassPA));
- break;
- }
-
- 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);
-
- // Update the analysis manager with each run and intersect the total set
- // of preserved analyses so we're ready to iterate.
- AM.invalidate(*C, PassPA);
-
- PA.intersect(std::move(PassPA));
- }
-
- // Note that we don't add any preserved entries here unlike a more normal
- // "pass manager" because we only handle invalidation *between* iterations,
- // not after the last iteration.
- return PA;
-}
-
-PreservedAnalyses CGSCCToFunctionPassAdaptor::run(LazyCallGraph::SCC &C,
- CGSCCAnalysisManager &AM,
- LazyCallGraph &CG,
- CGSCCUpdateResult &UR) {
- // Setup the function analysis manager from its proxy.
- FunctionAnalysisManager &FAM =
- AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
-
- SmallVector<LazyCallGraph::Node *, 4> Nodes;
- for (LazyCallGraph::Node &N : C)
- Nodes.push_back(&N);
-
- // The SCC may get split while we are optimizing functions due to deleting
- // edges. If this happens, the current SCC can shift, so keep track of
- // a pointer we can overwrite.
- LazyCallGraph::SCC *CurrentC = &C;
-
- LLVM_DEBUG(dbgs() << "Running function passes across an SCC: " << C << "\n");
-
- PreservedAnalyses PA = PreservedAnalyses::all();
- for (LazyCallGraph::Node *N : Nodes) {
- // Skip nodes from other SCCs. These may have been split out during
- // processing. We'll eventually visit those SCCs and pick up the nodes
- // there.
- if (CG.lookupSCC(*N) != CurrentC)
- continue;
-
- Function &F = N->getFunction();
-
- PassInstrumentation PI = FAM.getResult<PassInstrumentationAnalysis>(F);
- if (!PI.runBeforePass<Function>(*Pass, F))
- continue;
-
- PreservedAnalyses PassPA;
- {
- TimeTraceScope TimeScope(Pass->name());
- PassPA = Pass->run(F, FAM);
- }
-
- PI.runAfterPass<Function>(*Pass, F, PassPA);
-
- // We know that the function pass couldn't have invalidated any other
- // function's analyses (that's the contract of a function pass), so
- // directly handle the function analysis manager's invalidation here.
- FAM.invalidate(F, PassPA);
-
- // Then intersect the preserved set so that invalidation of module
- // analyses will eventually occur when the module pass completes.
- PA.intersect(std::move(PassPA));
-
- // If the call graph hasn't been preserved, update it based on this
- // function pass. This may also update the current SCC to point to
- // a smaller, more refined SCC.
- auto PAC = PA.getChecker<LazyCallGraphAnalysis>();
- if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Module>>()) {
- CurrentC = &updateCGAndAnalysisManagerForFunctionPass(CG, *CurrentC, *N,
- AM, UR, FAM);
- assert(CG.lookupSCC(*N) == CurrentC &&
- "Current SCC not updated to the SCC containing the current node!");
- }
- }
-
- // By definition we preserve the proxy. And we preserve all analyses on
- // Functions. This precludes *any* invalidation of function analyses by the
- // proxy, but that's OK because we've taken care to invalidate analyses in
- // the function analysis manager incrementally above.
- PA.preserveSet<AllAnalysesOn<Function>>();
- PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
-
- // We've also ensured that we updated the call graph along the way.
- PA.preserve<LazyCallGraphAnalysis>();
-
- return PA;
-}
-
+PreservedAnalyses
+ModuleToPostOrderCGSCCPassAdaptor::run(Module &M, ModuleAnalysisManager &AM) {
+ // Setup the CGSCC analysis manager from its proxy.
+ CGSCCAnalysisManager &CGAM =
+ AM.getResult<CGSCCAnalysisManagerModuleProxy>(M).getManager();
+
+ // Get the call graph for this module.
+ LazyCallGraph &CG = AM.getResult<LazyCallGraphAnalysis>(M);
+
+ // Get Function analysis manager from its proxy.
+ FunctionAnalysisManager &FAM =
+ AM.getCachedResult<FunctionAnalysisManagerModuleProxy>(M)->getManager();
+
+ // We keep worklists to allow us to push more work onto the pass manager as
+ // the passes are run.
+ SmallPriorityWorklist<LazyCallGraph::RefSCC *, 1> RCWorklist;
+ SmallPriorityWorklist<LazyCallGraph::SCC *, 1> CWorklist;
+
+ // Keep sets for invalidated SCCs and RefSCCs that should be skipped when
+ // iterating off the worklists.
+ SmallPtrSet<LazyCallGraph::RefSCC *, 4> InvalidRefSCCSet;
+ SmallPtrSet<LazyCallGraph::SCC *, 4> InvalidSCCSet;
+
+ SmallDenseSet<std::pair<LazyCallGraph::Node *, LazyCallGraph::SCC *>, 4>
+ InlinedInternalEdges;
+
+ CGSCCUpdateResult UR = {
+ RCWorklist, CWorklist, InvalidRefSCCSet, InvalidSCCSet,
+ nullptr, nullptr, PreservedAnalyses::all(), InlinedInternalEdges,
+ {}};
+
+ // Request PassInstrumentation from analysis manager, will use it to run
+ // instrumenting callbacks for the passes later.
+ PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(M);
+
+ PreservedAnalyses PA = PreservedAnalyses::all();
+ CG.buildRefSCCs();
+ for (auto RCI = CG.postorder_ref_scc_begin(),
+ RCE = CG.postorder_ref_scc_end();
+ RCI != RCE;) {
+ assert(RCWorklist.empty() &&
+ "Should always start with an empty RefSCC worklist");
+ // The postorder_ref_sccs range we are walking is lazily constructed, so
+ // we only push the first one onto the worklist. The worklist allows us
+ // to capture *new* RefSCCs created during transformations.
+ //
+ // We really want to form RefSCCs lazily because that makes them cheaper
+ // to update as the program is simplified and allows us to have greater
+ // cache locality as forming a RefSCC touches all the parts of all the
+ // functions within that RefSCC.
+ //
+ // We also eagerly increment the iterator to the next position because
+ // the CGSCC passes below may delete the current RefSCC.
+ RCWorklist.insert(&*RCI++);
+
+ do {
+ LazyCallGraph::RefSCC *RC = RCWorklist.pop_back_val();
+ if (InvalidRefSCCSet.count(RC)) {
+ LLVM_DEBUG(dbgs() << "Skipping an invalid RefSCC...\n");
+ continue;
+ }
+
+ assert(CWorklist.empty() &&
+ "Should always start with an empty SCC worklist");
+
+ LLVM_DEBUG(dbgs() << "Running an SCC pass across the RefSCC: " << *RC
+ << "\n");
+
+ // The top of the worklist may *also* be the same SCC we just ran over
+ // (and invalidated for). Keep track of that last SCC we processed due
+ // to SCC update to avoid redundant processing when an SCC is both just
+ // updated itself and at the top of the worklist.
+ LazyCallGraph::SCC *LastUpdatedC = nullptr;
+
+ // Push the initial SCCs in reverse post-order as we'll pop off the
+ // back and so see this in post-order.
+ for (LazyCallGraph::SCC &C : llvm::reverse(*RC))
+ CWorklist.insert(&C);
+
+ do {
+ LazyCallGraph::SCC *C = CWorklist.pop_back_val();
+ // Due to call graph mutations, we may have invalid SCCs or SCCs from
+ // other RefSCCs in the worklist. The invalid ones are dead and the
+ // other RefSCCs should be queued above, so we just need to skip both
+ // scenarios here.
+ if (InvalidSCCSet.count(C)) {
+ LLVM_DEBUG(dbgs() << "Skipping an invalid SCC...\n");
+ continue;
+ }
+ if (LastUpdatedC == C) {
+ LLVM_DEBUG(dbgs() << "Skipping redundant run on SCC: " << *C << "\n");
+ continue;
+ }
+ if (&C->getOuterRefSCC() != RC) {
+ LLVM_DEBUG(dbgs() << "Skipping an SCC that is now part of some other "
+ "RefSCC...\n");
+ continue;
+ }
+
+ // Ensure we can proxy analysis updates from the CGSCC analysis manager
+ // into the the Function analysis manager by getting a proxy here.
+ // This also needs to update the FunctionAnalysisManager, as this may be
+ // the first time we see this SCC.
+ CGAM.getResult<FunctionAnalysisManagerCGSCCProxy>(*C, CG).updateFAM(
+ FAM);
+
+ // Each time we visit a new SCC pulled off the worklist,
+ // a transformation of a child SCC may have also modified this parent
+ // and invalidated analyses. So we invalidate using the update record's
+ // cross-SCC preserved set. This preserved set is intersected by any
+ // CGSCC pass that handles invalidation (primarily pass managers) prior
+ // to marking its SCC as preserved. That lets us track everything that
+ // might need invalidation across SCCs without excessive invalidations
+ // on a single SCC.
+ //
+ // This essentially allows SCC passes to freely invalidate analyses
+ // of any ancestor SCC. If this becomes detrimental to successfully
+ // caching analyses, we could force each SCC pass to manually
+ // invalidate the analyses for any SCCs other than themselves which
+ // are mutated. However, that seems to lose the robustness of the
+ // pass-manager driven invalidation scheme.
+ CGAM.invalidate(*C, UR.CrossSCCPA);
+
+ do {
+ // Check that we didn't miss any update scenario.
+ assert(!InvalidSCCSet.count(C) && "Processing an invalid SCC!");
+ assert(C->begin() != C->end() && "Cannot have an empty SCC!");
+ assert(&C->getOuterRefSCC() == RC &&
+ "Processing an SCC in a different RefSCC!");
+
+ LastUpdatedC = UR.UpdatedC;
+ UR.UpdatedRC = nullptr;
+ UR.UpdatedC = nullptr;
+
+ // Check the PassInstrumentation's BeforePass callbacks before
+ // running the pass, skip its execution completely if asked to
+ // (callback returns false).
+ if (!PI.runBeforePass<LazyCallGraph::SCC>(*Pass, *C))
+ continue;
+
+ PreservedAnalyses PassPA;
+ {
+ TimeTraceScope TimeScope(Pass->name());
+ PassPA = Pass->run(*C, CGAM, CG, UR);
+ }
+
+ if (UR.InvalidatedSCCs.count(C))
+ PI.runAfterPassInvalidated<LazyCallGraph::SCC>(*Pass, PassPA);
+ else
+ PI.runAfterPass<LazyCallGraph::SCC>(*Pass, *C, PassPA);
+
+ // Update the SCC and RefSCC if necessary.
+ C = UR.UpdatedC ? UR.UpdatedC : C;
+ RC = UR.UpdatedRC ? UR.UpdatedRC : RC;
+
+ if (UR.UpdatedC) {
+ // If we're updating the SCC, also update the FAM inside the proxy's
+ // result.
+ CGAM.getResult<FunctionAnalysisManagerCGSCCProxy>(*C, CG).updateFAM(
+ FAM);
+ }
+
+ // 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)) {
+ LLVM_DEBUG(dbgs() << "Skipping invalidated root or island SCC!\n");
+ break;
+ }
+ // Check that we didn't miss any update scenario.
+ assert(C->begin() != C->end() && "Cannot have an empty SCC!");
+
+ // We handle invalidating the CGSCC analysis manager's information
+ // for the (potentially updated) SCC here. Note that any other SCCs
+ // whose structure has changed should have been invalidated by
+ // whatever was updating the call graph. This SCC gets invalidated
+ // late as it contains the nodes that were actively being
+ // processed.
+ CGAM.invalidate(*C, PassPA);
+
+ // Then intersect the preserved set so that invalidation of module
+ // analyses will eventually occur when the module pass completes.
+ // Also intersect with the cross-SCC preserved set to capture any
+ // cross-SCC invalidation.
+ UR.CrossSCCPA.intersect(PassPA);
+ PA.intersect(std::move(PassPA));
+
+ // The pass may have restructured the call graph and refined the
+ // current SCC and/or RefSCC. We need to update our current SCC and
+ // RefSCC pointers to follow these. Also, when the current SCC is
+ // refined, re-run the SCC pass over the newly refined SCC in order
+ // to observe the most precise SCC model available. This inherently
+ // cannot cycle excessively as it only happens when we split SCCs
+ // apart, at most converging on a DAG of single nodes.
+ // FIXME: If we ever start having RefSCC passes, we'll want to
+ // iterate there too.
+ if (UR.UpdatedC)
+ 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
+ // the processing when we check them in the loop above.
+ } while (UR.UpdatedC);
+ } while (!CWorklist.empty());
+
+ // We only need to keep internal inlined edge information within
+ // a RefSCC, clear it to save on space and let the next time we visit
+ // any of these functions have a fresh start.
+ InlinedInternalEdges.clear();
+ } while (!RCWorklist.empty());
+ }
+
+ // By definition we preserve the call garph, all SCC analyses, and the
+ // analysis proxies by handling them above and in any nested pass managers.
+ PA.preserveSet<AllAnalysesOn<LazyCallGraph::SCC>>();
+ PA.preserve<LazyCallGraphAnalysis>();
+ PA.preserve<CGSCCAnalysisManagerModuleProxy>();
+ PA.preserve<FunctionAnalysisManagerModuleProxy>();
+ return PA;
+}
+
+PreservedAnalyses DevirtSCCRepeatedPass::run(LazyCallGraph::SCC &InitialC,
+ CGSCCAnalysisManager &AM,
+ LazyCallGraph &CG,
+ CGSCCUpdateResult &UR) {
+ PreservedAnalyses PA = PreservedAnalyses::all();
+ PassInstrumentation PI =
+ AM.getResult<PassInstrumentationAnalysis>(InitialC, CG);
+
+ // The SCC may be refined while we are running passes over it, so set up
+ // a pointer that we can update.
+ LazyCallGraph::SCC *C = &InitialC;
+
+ // Struct to track the counts of direct and indirect calls in each function
+ // of the SCC.
+ struct CallCount {
+ int Direct;
+ int Indirect;
+ };
+
+ // Put value handles on all of the indirect calls and return the number of
+ // direct calls for each function in the SCC.
+ auto ScanSCC = [](LazyCallGraph::SCC &C,
+ SmallMapVector<Value *, WeakTrackingVH, 16> &CallHandles) {
+ assert(CallHandles.empty() && "Must start with a clear set of handles.");
+
+ SmallDenseMap<Function *, CallCount> CallCounts;
+ CallCount CountLocal = {0, 0};
+ for (LazyCallGraph::Node &N : C) {
+ CallCount &Count =
+ CallCounts.insert(std::make_pair(&N.getFunction(), CountLocal))
+ .first->second;
+ for (Instruction &I : instructions(N.getFunction()))
+ if (auto *CB = dyn_cast<CallBase>(&I)) {
+ if (CB->getCalledFunction()) {
+ ++Count.Direct;
+ } else {
+ ++Count.Indirect;
+ CallHandles.insert({CB, WeakTrackingVH(CB)});
+ }
+ }
+ }
+
+ return CallCounts;
+ };
+
+ UR.IndirectVHs.clear();
+ // Populate the initial call handles and get the initial call counts.
+ auto CallCounts = ScanSCC(*C, UR.IndirectVHs);
+
+ for (int Iteration = 0;; ++Iteration) {
+ if (!PI.runBeforePass<LazyCallGraph::SCC>(*Pass, *C))
+ continue;
+
+ PreservedAnalyses PassPA = Pass->run(*C, AM, CG, UR);
+
+ if (UR.InvalidatedSCCs.count(C))
+ PI.runAfterPassInvalidated<LazyCallGraph::SCC>(*Pass, PassPA);
+ else
+ PI.runAfterPass<LazyCallGraph::SCC>(*Pass, *C, PassPA);
+
+ // If the SCC structure has changed, bail immediately and let the outer
+ // CGSCC layer handle any iteration to reflect the refined structure.
+ if (UR.UpdatedC && UR.UpdatedC != C) {
+ PA.intersect(std::move(PassPA));
+ break;
+ }
+
+ // Check that we didn't miss any update scenario.
+ assert(!UR.InvalidatedSCCs.count(C) && "Processing an invalid SCC!");
+ assert(C->begin() != C->end() && "Cannot have an empty SCC!");
+
+ // Check whether any of the handles were devirtualized.
+ bool Devirt = llvm::any_of(UR.IndirectVHs, [](auto &P) -> bool {
+ if (P.second) {
+ if (CallBase *CB = dyn_cast<CallBase>(P.second)) {
+ if (CB->getCalledFunction()) {
+ LLVM_DEBUG(dbgs() << "Found devirtualized call: " << *CB << "\n");
+ return true;
+ }
+ }
+ }
+ return false;
+ });
+
+ // Rescan to build up a new set of handles and count how many direct
+ // calls remain. If we decide to iterate, this also sets up the input to
+ // the next iteration.
+ UR.IndirectVHs.clear();
+ auto NewCallCounts = ScanSCC(*C, UR.IndirectVHs);
+
+ // If we haven't found an explicit devirtualization already see if we
+ // have decreased the number of indirect calls and increased the number
+ // of direct calls for any function in the SCC. This can be fooled by all
+ // manner of transformations such as DCE and other things, but seems to
+ // work well in practice.
+ if (!Devirt)
+ // Iterate over the keys in NewCallCounts, if Function also exists in
+ // CallCounts, make the check below.
+ for (auto &Pair : NewCallCounts) {
+ auto &CallCountNew = Pair.second;
+ auto CountIt = CallCounts.find(Pair.first);
+ if (CountIt != CallCounts.end()) {
+ const auto &CallCountOld = CountIt->second;
+ if (CallCountOld.Indirect > CallCountNew.Indirect &&
+ CallCountOld.Direct < CallCountNew.Direct) {
+ Devirt = true;
+ break;
+ }
+ }
+ }
+
+ if (!Devirt) {
+ PA.intersect(std::move(PassPA));
+ break;
+ }
+
+ // Otherwise, if we've already hit our max, we're done.
+ if (Iteration >= MaxIterations) {
+ if (AbortOnMaxDevirtIterationsReached)
+ report_fatal_error("Max devirtualization iterations reached");
+ LLVM_DEBUG(
+ dbgs() << "Found another devirtualization after hitting the max "
+ "number of repetitions ("
+ << MaxIterations << ") on SCC: " << *C << "\n");
+ PA.intersect(std::move(PassPA));
+ break;
+ }
+
+ 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);
+
+ // Update the analysis manager with each run and intersect the total set
+ // of preserved analyses so we're ready to iterate.
+ AM.invalidate(*C, PassPA);
+
+ PA.intersect(std::move(PassPA));
+ }
+
+ // Note that we don't add any preserved entries here unlike a more normal
+ // "pass manager" because we only handle invalidation *between* iterations,
+ // not after the last iteration.
+ return PA;
+}
+
+PreservedAnalyses CGSCCToFunctionPassAdaptor::run(LazyCallGraph::SCC &C,
+ CGSCCAnalysisManager &AM,
+ LazyCallGraph &CG,
+ CGSCCUpdateResult &UR) {
+ // Setup the function analysis manager from its proxy.
+ FunctionAnalysisManager &FAM =
+ AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
+
+ SmallVector<LazyCallGraph::Node *, 4> Nodes;
+ for (LazyCallGraph::Node &N : C)
+ Nodes.push_back(&N);
+
+ // The SCC may get split while we are optimizing functions due to deleting
+ // edges. If this happens, the current SCC can shift, so keep track of
+ // a pointer we can overwrite.
+ LazyCallGraph::SCC *CurrentC = &C;
+
+ LLVM_DEBUG(dbgs() << "Running function passes across an SCC: " << C << "\n");
+
+ PreservedAnalyses PA = PreservedAnalyses::all();
+ for (LazyCallGraph::Node *N : Nodes) {
+ // Skip nodes from other SCCs. These may have been split out during
+ // processing. We'll eventually visit those SCCs and pick up the nodes
+ // there.
+ if (CG.lookupSCC(*N) != CurrentC)
+ continue;
+
+ Function &F = N->getFunction();
+
+ PassInstrumentation PI = FAM.getResult<PassInstrumentationAnalysis>(F);
+ if (!PI.runBeforePass<Function>(*Pass, F))
+ continue;
+
+ PreservedAnalyses PassPA;
+ {
+ TimeTraceScope TimeScope(Pass->name());
+ PassPA = Pass->run(F, FAM);
+ }
+
+ PI.runAfterPass<Function>(*Pass, F, PassPA);
+
+ // We know that the function pass couldn't have invalidated any other
+ // function's analyses (that's the contract of a function pass), so
+ // directly handle the function analysis manager's invalidation here.
+ FAM.invalidate(F, PassPA);
+
+ // Then intersect the preserved set so that invalidation of module
+ // analyses will eventually occur when the module pass completes.
+ PA.intersect(std::move(PassPA));
+
+ // If the call graph hasn't been preserved, update it based on this
+ // function pass. This may also update the current SCC to point to
+ // a smaller, more refined SCC.
+ auto PAC = PA.getChecker<LazyCallGraphAnalysis>();
+ if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Module>>()) {
+ CurrentC = &updateCGAndAnalysisManagerForFunctionPass(CG, *CurrentC, *N,
+ AM, UR, FAM);
+ assert(CG.lookupSCC(*N) == CurrentC &&
+ "Current SCC not updated to the SCC containing the current node!");
+ }
+ }
+
+ // By definition we preserve the proxy. And we preserve all analyses on
+ // Functions. This precludes *any* invalidation of function analyses by the
+ // proxy, but that's OK because we've taken care to invalidate analyses in
+ // the function analysis manager incrementally above.
+ PA.preserveSet<AllAnalysesOn<Function>>();
+ PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
+
+ // We've also ensured that we updated the call graph along the way.
+ PA.preserve<LazyCallGraphAnalysis>();
+
+ return PA;
+}
+
bool CGSCCAnalysisManagerModuleProxy::Result::invalidate(
Module &M, const PreservedAnalyses &PA,
ModuleAnalysisManager::Invalidator &Inv) {
@@ -833,7 +833,7 @@ incorporateNewSCCRange(const SCCRangeT &NewSCCRange, LazyCallGraph &G,
CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR) {
using SCC = LazyCallGraph::SCC;
- if (NewSCCRange.empty())
+ if (NewSCCRange.empty())
return C;
// Add the current SCC to the worklist as its shape has changed.
@@ -917,61 +917,61 @@ static LazyCallGraph::SCC &updateCGAndAnalysisManagerForPass(
// First walk the function and handle all called functions. We do this first
// because if there is a single call edge, whether there are ref edges is
// irrelevant.
- for (Instruction &I : instructions(F)) {
- if (auto *CB = dyn_cast<CallBase>(&I)) {
- if (Function *Callee = CB->getCalledFunction()) {
+ for (Instruction &I : instructions(F)) {
+ if (auto *CB = dyn_cast<CallBase>(&I)) {
+ if (Function *Callee = CB->getCalledFunction()) {
if (Visited.insert(Callee).second && !Callee->isDeclaration()) {
- Node *CalleeN = G.lookup(*Callee);
- assert(CalleeN &&
- "Visited function should already have an associated node");
- Edge *E = N->lookup(*CalleeN);
+ Node *CalleeN = G.lookup(*Callee);
+ assert(CalleeN &&
+ "Visited function should already have an associated node");
+ Edge *E = N->lookup(*CalleeN);
assert((E || !FunctionPass) &&
"No function transformations should introduce *new* "
"call edges! Any new calls should be modeled as "
"promoted existing ref edges!");
- bool Inserted = RetainedEdges.insert(CalleeN).second;
+ bool Inserted = RetainedEdges.insert(CalleeN).second;
(void)Inserted;
assert(Inserted && "We should never visit a function twice.");
if (!E)
- NewCallEdges.insert(CalleeN);
+ NewCallEdges.insert(CalleeN);
else if (!E->isCall())
- PromotedRefTargets.insert(CalleeN);
+ PromotedRefTargets.insert(CalleeN);
}
- } else {
- // We can miss devirtualization if an indirect call is created then
- // promoted before updateCGAndAnalysisManagerForPass runs.
- auto *Entry = UR.IndirectVHs.find(CB);
- if (Entry == UR.IndirectVHs.end())
- UR.IndirectVHs.insert({CB, WeakTrackingVH(CB)});
- else if (!Entry->second)
- Entry->second = WeakTrackingVH(CB);
- }
- }
- }
+ } else {
+ // We can miss devirtualization if an indirect call is created then
+ // promoted before updateCGAndAnalysisManagerForPass runs.
+ auto *Entry = UR.IndirectVHs.find(CB);
+ if (Entry == UR.IndirectVHs.end())
+ UR.IndirectVHs.insert({CB, WeakTrackingVH(CB)});
+ else if (!Entry->second)
+ Entry->second = WeakTrackingVH(CB);
+ }
+ }
+ }
// Now walk all references.
for (Instruction &I : instructions(F))
for (Value *Op : I.operand_values())
- if (auto *OpC = dyn_cast<Constant>(Op))
- if (Visited.insert(OpC).second)
- Worklist.push_back(OpC);
+ if (auto *OpC = dyn_cast<Constant>(Op))
+ if (Visited.insert(OpC).second)
+ Worklist.push_back(OpC);
auto VisitRef = [&](Function &Referee) {
- Node *RefereeN = G.lookup(Referee);
- assert(RefereeN &&
- "Visited function should already have an associated node");
- Edge *E = N->lookup(*RefereeN);
+ Node *RefereeN = G.lookup(Referee);
+ assert(RefereeN &&
+ "Visited function should already have an associated node");
+ Edge *E = N->lookup(*RefereeN);
assert((E || !FunctionPass) &&
"No function transformations should introduce *new* ref "
"edges! Any new ref edges would require IPO which "
"function passes aren't allowed to do!");
- bool Inserted = RetainedEdges.insert(RefereeN).second;
+ bool Inserted = RetainedEdges.insert(RefereeN).second;
(void)Inserted;
assert(Inserted && "We should never visit a function twice.");
if (!E)
- NewRefEdges.insert(RefereeN);
+ NewRefEdges.insert(RefereeN);
else if (E->isCall())
- DemotedCallTargets.insert(RefereeN);
+ DemotedCallTargets.insert(RefereeN);
};
LazyCallGraph::visitReferences(Worklist, Visited, VisitRef);
@@ -994,17 +994,17 @@ static LazyCallGraph::SCC &updateCGAndAnalysisManagerForPass(
// TODO: This only allows trivial edges to be added for now.
assert((RC == &TargetRC ||
RC->isAncestorOf(TargetRC)) && "New call edge is not trivial!");
- // Add a trivial ref edge to be promoted later on alongside
- // PromotedRefTargets.
- RC->insertTrivialRefEdge(N, *CallTarget);
+ // Add a trivial ref edge to be promoted later on alongside
+ // PromotedRefTargets.
+ RC->insertTrivialRefEdge(N, *CallTarget);
}
// Include synthetic reference edges to known, defined lib functions.
- for (auto *LibFn : G.getLibFunctions())
+ for (auto *LibFn : G.getLibFunctions())
// While the list of lib functions doesn't have repeats, don't re-visit
// anything handled above.
- if (!Visited.count(LibFn))
- VisitRef(*LibFn);
+ if (!Visited.count(LibFn))
+ VisitRef(*LibFn);
// First remove all of the edges that are no longer present in this function.
// The first step makes these edges uniformly ref edges and accumulates them
@@ -1031,20 +1031,20 @@ static LazyCallGraph::SCC &updateCGAndAnalysisManagerForPass(
DeadTargets.push_back(&E.getNode());
}
// Remove the easy cases quickly and actually pull them out of our list.
- llvm::erase_if(DeadTargets, [&](Node *TargetN) {
- SCC &TargetC = *G.lookupSCC(*TargetN);
- RefSCC &TargetRC = TargetC.getOuterRefSCC();
+ llvm::erase_if(DeadTargets, [&](Node *TargetN) {
+ SCC &TargetC = *G.lookupSCC(*TargetN);
+ RefSCC &TargetRC = TargetC.getOuterRefSCC();
- // We can't trivially remove internal targets, so skip
- // those.
- if (&TargetRC == RC)
- return false;
+ // We can't trivially remove internal targets, so skip
+ // those.
+ if (&TargetRC == RC)
+ return false;
- RC->removeOutgoingEdge(N, *TargetN);
- LLVM_DEBUG(dbgs() << "Deleting outgoing edge from '" << N << "' to '"
- << TargetN << "'\n");
- return true;
- });
+ RC->removeOutgoingEdge(N, *TargetN);
+ LLVM_DEBUG(dbgs() << "Deleting outgoing edge from '" << N << "' to '"
+ << TargetN << "'\n");
+ return true;
+ });
// Now do a batch removal of the internal ref edges left.
auto NewRefSCCs = RC->removeInternalRefEdge(N, DeadTargets);
@@ -1108,11 +1108,11 @@ static LazyCallGraph::SCC &updateCGAndAnalysisManagerForPass(
C, AM, UR);
}
- // We added a ref edge earlier for new call edges, promote those to call edges
- // alongside PromotedRefTargets.
- for (Node *E : NewCallEdges)
- PromotedRefTargets.insert(E);
-
+ // We added a ref edge earlier for new call edges, promote those to call edges
+ // alongside PromotedRefTargets.
+ for (Node *E : NewCallEdges)
+ PromotedRefTargets.insert(E);
+
// Now promote ref edges into call edges.
for (Node *CallTarget : PromotedRefTargets) {
SCC &TargetC = *G.lookupSCC(*CallTarget);
diff --git a/contrib/libs/llvm12/lib/Analysis/CallGraph.cpp b/contrib/libs/llvm12/lib/Analysis/CallGraph.cpp
index 931a3ff3ac..9b212e564a 100644
--- a/contrib/libs/llvm12/lib/Analysis/CallGraph.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/CallGraph.cpp
@@ -267,37 +267,37 @@ void CallGraphNode::replaceCallEdge(CallBase &Call, CallBase &NewCall,
I->second = NewNode;
NewNode->AddRef();
- // Refresh callback references. Do not resize CalledFunctions if the
- // number of callbacks is the same for new and old call sites.
- SmallVector<CallGraphNode *, 4u> OldCBs;
- SmallVector<CallGraphNode *, 4u> NewCBs;
- forEachCallbackFunction(Call, [this, &OldCBs](Function *CB) {
- OldCBs.push_back(CG->getOrInsertFunction(CB));
+ // Refresh callback references. Do not resize CalledFunctions if the
+ // number of callbacks is the same for new and old call sites.
+ SmallVector<CallGraphNode *, 4u> OldCBs;
+ SmallVector<CallGraphNode *, 4u> NewCBs;
+ forEachCallbackFunction(Call, [this, &OldCBs](Function *CB) {
+ OldCBs.push_back(CG->getOrInsertFunction(CB));
});
- forEachCallbackFunction(NewCall, [this, &NewCBs](Function *CB) {
- NewCBs.push_back(CG->getOrInsertFunction(CB));
+ forEachCallbackFunction(NewCall, [this, &NewCBs](Function *CB) {
+ NewCBs.push_back(CG->getOrInsertFunction(CB));
});
- if (OldCBs.size() == NewCBs.size()) {
- for (unsigned N = 0; N < OldCBs.size(); ++N) {
- CallGraphNode *OldNode = OldCBs[N];
- CallGraphNode *NewNode = NewCBs[N];
- for (auto J = CalledFunctions.begin();; ++J) {
- assert(J != CalledFunctions.end() &&
- "Cannot find callsite to update!");
- if (!J->first && J->second == OldNode) {
- J->second = NewNode;
- OldNode->DropRef();
- NewNode->AddRef();
- break;
- }
- }
- }
- } else {
- for (auto *CGN : OldCBs)
- removeOneAbstractEdgeTo(CGN);
- for (auto *CGN : NewCBs)
- addCalledFunction(nullptr, CGN);
- }
+ if (OldCBs.size() == NewCBs.size()) {
+ for (unsigned N = 0; N < OldCBs.size(); ++N) {
+ CallGraphNode *OldNode = OldCBs[N];
+ CallGraphNode *NewNode = NewCBs[N];
+ for (auto J = CalledFunctions.begin();; ++J) {
+ assert(J != CalledFunctions.end() &&
+ "Cannot find callsite to update!");
+ if (!J->first && J->second == OldNode) {
+ J->second = NewNode;
+ OldNode->DropRef();
+ NewNode->AddRef();
+ break;
+ }
+ }
+ }
+ } else {
+ for (auto *CGN : OldCBs)
+ removeOneAbstractEdgeTo(CGN);
+ for (auto *CGN : NewCBs)
+ addCalledFunction(nullptr, CGN);
+ }
return;
}
}
diff --git a/contrib/libs/llvm12/lib/Analysis/CallGraphSCCPass.cpp b/contrib/libs/llvm12/lib/Analysis/CallGraphSCCPass.cpp
index 85339724ed..38057d44e2 100644
--- a/contrib/libs/llvm12/lib/Analysis/CallGraphSCCPass.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/CallGraphSCCPass.cpp
@@ -27,8 +27,8 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/OptBisect.h"
#include "llvm/IR/PassTimingInfo.h"
-#include "llvm/IR/PrintPasses.h"
-#include "llvm/IR/StructuralHash.h"
+#include "llvm/IR/PrintPasses.h"
+#include "llvm/IR/StructuralHash.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -43,8 +43,8 @@ using namespace llvm;
#define DEBUG_TYPE "cgscc-passmgr"
-cl::opt<unsigned> MaxDevirtIterations("max-devirt-iterations", cl::ReallyHidden,
- cl::init(4));
+cl::opt<unsigned> MaxDevirtIterations("max-devirt-iterations", cl::ReallyHidden,
+ cl::init(4));
STATISTIC(MaxSCCIterations, "Maximum CGSCCPassMgr iterations on one SCC");
@@ -467,30 +467,30 @@ bool CGPassManager::RunAllPassesOnSCC(CallGraphSCC &CurSCC, CallGraph &CG,
initializeAnalysisImpl(P);
-#ifdef EXPENSIVE_CHECKS
- uint64_t RefHash = StructuralHash(CG.getModule());
-#endif
-
+#ifdef EXPENSIVE_CHECKS
+ uint64_t RefHash = StructuralHash(CG.getModule());
+#endif
+
// Actually run this pass on the current SCC.
- bool LocalChanged =
- RunPassOnSCC(P, CurSCC, CG, CallGraphUpToDate, DevirtualizedCall);
-
- Changed |= LocalChanged;
-
-#ifdef EXPENSIVE_CHECKS
- if (!LocalChanged && (RefHash != StructuralHash(CG.getModule()))) {
- llvm::errs() << "Pass modifies its input and doesn't report it: "
- << P->getPassName() << "\n";
- llvm_unreachable("Pass modifies its input and doesn't report it");
- }
-#endif
- if (LocalChanged)
+ bool LocalChanged =
+ RunPassOnSCC(P, CurSCC, CG, CallGraphUpToDate, DevirtualizedCall);
+
+ Changed |= LocalChanged;
+
+#ifdef EXPENSIVE_CHECKS
+ if (!LocalChanged && (RefHash != StructuralHash(CG.getModule()))) {
+ llvm::errs() << "Pass modifies its input and doesn't report it: "
+ << P->getPassName() << "\n";
+ llvm_unreachable("Pass modifies its input and doesn't report it");
+ }
+#endif
+ if (LocalChanged)
dumpPassInfo(P, MODIFICATION_MSG, ON_CG_MSG, "");
dumpPreservedSet(P);
verifyPreservedAnalysis(P);
- if (LocalChanged)
- removeNotPreservedAnalysis(P);
+ if (LocalChanged)
+ removeNotPreservedAnalysis(P);
recordAvailableAnalysis(P);
removeDeadPasses(P, "", ON_CG_MSG);
}
@@ -539,12 +539,12 @@ bool CGPassManager::runOnModule(Module &M) {
<< '\n');
DevirtualizedCall = false;
Changed |= RunAllPassesOnSCC(CurSCC, CG, DevirtualizedCall);
- } while (Iteration++ < MaxDevirtIterations && DevirtualizedCall);
+ } while (Iteration++ < MaxDevirtIterations && DevirtualizedCall);
if (DevirtualizedCall)
LLVM_DEBUG(dbgs() << " CGSCCPASSMGR: Stopped iteration after "
<< Iteration
- << " times, due to -max-devirt-iterations\n");
+ << " times, due to -max-devirt-iterations\n");
MaxSCCIterations.updateMax(Iteration);
}
diff --git a/contrib/libs/llvm12/lib/Analysis/CallPrinter.cpp b/contrib/libs/llvm12/lib/Analysis/CallPrinter.cpp
index c1619eb9ea..872a91ad7c 100644
--- a/contrib/libs/llvm12/lib/Analysis/CallPrinter.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/CallPrinter.cpp
@@ -143,8 +143,8 @@ struct DOTGraphTraits<CallGraphDOTInfo *> : public DefaultDOTGraphTraits {
std::string(CGInfo->getModule()->getModuleIdentifier());
}
- static bool isNodeHidden(const CallGraphNode *Node,
- const CallGraphDOTInfo *CGInfo) {
+ static bool isNodeHidden(const CallGraphNode *Node,
+ const CallGraphDOTInfo *CGInfo) {
if (CallMultiGraph || Node->getFunction())
return false;
return true;
@@ -196,7 +196,7 @@ struct DOTGraphTraits<CallGraphDOTInfo *> : public DefaultDOTGraphTraits {
Function *F = Node->getFunction();
if (F == nullptr)
return "";
- std::string attrs;
+ std::string attrs;
if (ShowHeatColors) {
uint64_t freq = CGInfo->getFreq(F);
std::string color = getHeatColor(freq, CGInfo->getMaxFreq());
diff --git a/contrib/libs/llvm12/lib/Analysis/CaptureTracking.cpp b/contrib/libs/llvm12/lib/Analysis/CaptureTracking.cpp
index aff0f8afee..b2fc6e603f 100644
--- a/contrib/libs/llvm12/lib/Analysis/CaptureTracking.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/CaptureTracking.cpp
@@ -18,7 +18,7 @@
#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/ValueTracking.h"
@@ -30,13 +30,13 @@
using namespace llvm;
-#define DEBUG_TYPE "capture-tracking"
-
-STATISTIC(NumCaptured, "Number of pointers maybe captured");
-STATISTIC(NumNotCaptured, "Number of pointers not captured");
-STATISTIC(NumCapturedBefore, "Number of pointers maybe captured before");
-STATISTIC(NumNotCapturedBefore, "Number of pointers not captured before");
-
+#define DEBUG_TYPE "capture-tracking"
+
+STATISTIC(NumCaptured, "Number of pointers maybe captured");
+STATISTIC(NumNotCaptured, "Number of pointers not captured");
+STATISTIC(NumCapturedBefore, "Number of pointers maybe captured before");
+STATISTIC(NumNotCapturedBefore, "Number of pointers not captured before");
+
/// The default value for MaxUsesToExplore argument. It's relatively small to
/// keep the cost of analysis reasonable for clients like BasicAliasAnalysis,
/// where the results can't be cached.
@@ -202,10 +202,10 @@ bool llvm::PointerMayBeCaptured(const Value *V,
SimpleCaptureTracker SCT(ReturnCaptures);
PointerMayBeCaptured(V, &SCT, MaxUsesToExplore);
- if (SCT.Captured)
- ++NumCaptured;
- else
- ++NumNotCaptured;
+ if (SCT.Captured)
+ ++NumCaptured;
+ else
+ ++NumNotCaptured;
return SCT.Captured;
}
@@ -234,10 +234,10 @@ bool llvm::PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures,
CapturesBefore CB(ReturnCaptures, I, DT, IncludeI);
PointerMayBeCaptured(V, &CB, MaxUsesToExplore);
- if (CB.Captured)
- ++NumCapturedBefore;
- else
- ++NumNotCapturedBefore;
+ if (CB.Captured)
+ ++NumCapturedBefore;
+ else
+ ++NumNotCapturedBefore;
return CB.Captured;
}
@@ -256,20 +256,20 @@ void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker,
for (const Use &U : V->uses()) {
// If there are lots of uses, conservatively say that the value
// is captured to avoid taking too much compile time.
- if (Count++ >= MaxUsesToExplore) {
- Tracker->tooManyUses();
- return false;
- }
+ if (Count++ >= MaxUsesToExplore) {
+ Tracker->tooManyUses();
+ return false;
+ }
if (!Visited.insert(&U).second)
continue;
if (!Tracker->shouldExplore(&U))
continue;
Worklist.push_back(&U);
}
- return true;
+ return true;
};
- if (!AddUses(V))
- return;
+ if (!AddUses(V))
+ return;
while (!Worklist.empty()) {
const Use *U = Worklist.pop_back_val();
@@ -289,12 +289,12 @@ void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker,
// The pointer is not captured if returned pointer is not captured.
// NOTE: CaptureTracking users should not assume that only functions
// marked with nocapture do not capture. This means that places like
- // getUnderlyingObject in ValueTracking or DecomposeGEPExpression
+ // getUnderlyingObject in ValueTracking or DecomposeGEPExpression
// in BasicAA also need to know about this property.
if (isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(Call,
true)) {
- if (!AddUses(Call))
- return;
+ if (!AddUses(Call))
+ return;
break;
}
@@ -312,11 +312,11 @@ void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker,
// that loading a value from a pointer does not cause the pointer to be
// captured, even though the loaded value might be the pointer itself
// (think of self-referential objects).
- if (Call->isDataOperand(U) &&
- !Call->doesNotCapture(Call->getDataOperandNo(U))) {
- // The parameter is not marked 'nocapture' - captured.
- if (Tracker->captured(U))
- return;
+ if (Call->isDataOperand(U) &&
+ !Call->doesNotCapture(Call->getDataOperandNo(U))) {
+ // The parameter is not marked 'nocapture' - captured.
+ if (Tracker->captured(U))
+ return;
}
break;
}
@@ -330,9 +330,9 @@ void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker,
// "va-arg" from a pointer does not cause it to be captured.
break;
case Instruction::Store:
- // Stored the pointer - conservatively assume it may be captured.
- // Volatile stores make the address observable.
- if (U->getOperandNo() == 0 || cast<StoreInst>(I)->isVolatile())
+ // Stored the pointer - conservatively assume it may be captured.
+ // Volatile stores make the address observable.
+ if (U->getOperandNo() == 0 || cast<StoreInst>(I)->isVolatile())
if (Tracker->captured(U))
return;
break;
@@ -343,7 +343,7 @@ void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker,
// but the value being stored is.
// Volatile stores make the address observable.
auto *ARMWI = cast<AtomicRMWInst>(I);
- if (U->getOperandNo() == 1 || ARMWI->isVolatile())
+ if (U->getOperandNo() == 1 || ARMWI->isVolatile())
if (Tracker->captured(U))
return;
break;
@@ -355,7 +355,7 @@ void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker,
// but the value being stored is.
// Volatile stores make the address observable.
auto *ACXI = cast<AtomicCmpXchgInst>(I);
- if (U->getOperandNo() == 1 || U->getOperandNo() == 2 ||
+ if (U->getOperandNo() == 1 || U->getOperandNo() == 2 ||
ACXI->isVolatile())
if (Tracker->captured(U))
return;
@@ -367,18 +367,18 @@ void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker,
case Instruction::Select:
case Instruction::AddrSpaceCast:
// The original value is not captured via this if the new value isn't.
- if (!AddUses(I))
- return;
+ if (!AddUses(I))
+ return;
break;
case Instruction::ICmp: {
- unsigned Idx = U->getOperandNo();
+ unsigned Idx = U->getOperandNo();
unsigned OtherIdx = 1 - Idx;
if (auto *CPN = dyn_cast<ConstantPointerNull>(I->getOperand(OtherIdx))) {
// Don't count comparisons of a no-alias return value against null as
// captures. This allows us to ignore comparisons of malloc results
// with null, for example.
if (CPN->getType()->getAddressSpace() == 0)
- if (isNoAliasCall(U->get()->stripPointerCasts()))
+ if (isNoAliasCall(U->get()->stripPointerCasts()))
break;
if (!I->getFunction()->nullPointerIsDefined()) {
auto *O = I->getOperand(Idx)->stripPointerCastsSameRepresentation();
@@ -411,44 +411,44 @@ void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker,
// All uses examined.
}
-
-bool llvm::isNonEscapingLocalObject(
- const Value *V, SmallDenseMap<const Value *, bool, 8> *IsCapturedCache) {
- SmallDenseMap<const Value *, bool, 8>::iterator CacheIt;
- if (IsCapturedCache) {
- bool Inserted;
- std::tie(CacheIt, Inserted) = IsCapturedCache->insert({V, false});
- if (!Inserted)
- // Found cached result, return it!
- return CacheIt->second;
- }
-
- // If this is a local allocation, check to see if it escapes.
- if (isa<AllocaInst>(V) || isNoAliasCall(V)) {
- // Set StoreCaptures to True so that we can assume in our callers that the
- // pointer is not the result of a load instruction. Currently
- // PointerMayBeCaptured doesn't have any special analysis for the
- // StoreCaptures=false case; if it did, our callers could be refined to be
- // more precise.
- auto Ret = !PointerMayBeCaptured(V, false, /*StoreCaptures=*/true);
- if (IsCapturedCache)
- CacheIt->second = Ret;
- return Ret;
- }
-
- // If this is an argument that corresponds to a byval or noalias argument,
- // then it has not escaped before entering the function. Check if it escapes
- // inside the function.
- if (const Argument *A = dyn_cast<Argument>(V))
- if (A->hasByValAttr() || A->hasNoAliasAttr()) {
- // Note even if the argument is marked nocapture, we still need to check
- // for copies made inside the function. The nocapture attribute only
- // specifies that there are no copies made that outlive the function.
- auto Ret = !PointerMayBeCaptured(V, false, /*StoreCaptures=*/true);
- if (IsCapturedCache)
- CacheIt->second = Ret;
- return Ret;
- }
-
- return false;
-}
+
+bool llvm::isNonEscapingLocalObject(
+ const Value *V, SmallDenseMap<const Value *, bool, 8> *IsCapturedCache) {
+ SmallDenseMap<const Value *, bool, 8>::iterator CacheIt;
+ if (IsCapturedCache) {
+ bool Inserted;
+ std::tie(CacheIt, Inserted) = IsCapturedCache->insert({V, false});
+ if (!Inserted)
+ // Found cached result, return it!
+ return CacheIt->second;
+ }
+
+ // If this is a local allocation, check to see if it escapes.
+ if (isa<AllocaInst>(V) || isNoAliasCall(V)) {
+ // Set StoreCaptures to True so that we can assume in our callers that the
+ // pointer is not the result of a load instruction. Currently
+ // PointerMayBeCaptured doesn't have any special analysis for the
+ // StoreCaptures=false case; if it did, our callers could be refined to be
+ // more precise.
+ auto Ret = !PointerMayBeCaptured(V, false, /*StoreCaptures=*/true);
+ if (IsCapturedCache)
+ CacheIt->second = Ret;
+ return Ret;
+ }
+
+ // If this is an argument that corresponds to a byval or noalias argument,
+ // then it has not escaped before entering the function. Check if it escapes
+ // inside the function.
+ if (const Argument *A = dyn_cast<Argument>(V))
+ if (A->hasByValAttr() || A->hasNoAliasAttr()) {
+ // Note even if the argument is marked nocapture, we still need to check
+ // for copies made inside the function. The nocapture attribute only
+ // specifies that there are no copies made that outlive the function.
+ auto Ret = !PointerMayBeCaptured(V, false, /*StoreCaptures=*/true);
+ if (IsCapturedCache)
+ CacheIt->second = Ret;
+ return Ret;
+ }
+
+ return false;
+}
diff --git a/contrib/libs/llvm12/lib/Analysis/CodeMetrics.cpp b/contrib/libs/llvm12/lib/Analysis/CodeMetrics.cpp
index 5ef904e1f1..157811c04e 100644
--- a/contrib/libs/llvm12/lib/Analysis/CodeMetrics.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/CodeMetrics.cpp
@@ -112,9 +112,9 @@ void CodeMetrics::collectEphemeralValues(
/// Fill in the current structure with information gleaned from the specified
/// block.
-void CodeMetrics::analyzeBasicBlock(
- const BasicBlock *BB, const TargetTransformInfo &TTI,
- const SmallPtrSetImpl<const Value *> &EphValues, bool PrepareForLTO) {
+void CodeMetrics::analyzeBasicBlock(
+ const BasicBlock *BB, const TargetTransformInfo &TTI,
+ const SmallPtrSetImpl<const Value *> &EphValues, bool PrepareForLTO) {
++NumBlocks;
unsigned NumInstsBeforeThisBB = NumInsts;
for (const Instruction &I : *BB) {
@@ -125,16 +125,16 @@ void CodeMetrics::analyzeBasicBlock(
// Special handling for calls.
if (const auto *Call = dyn_cast<CallBase>(&I)) {
if (const Function *F = Call->getCalledFunction()) {
- bool IsLoweredToCall = TTI.isLoweredToCall(F);
+ bool IsLoweredToCall = TTI.isLoweredToCall(F);
// If a function is both internal and has a single use, then it is
// extremely likely to get inlined in the future (it was probably
// exposed by an interleaved devirtualization pass).
- // When preparing for LTO, liberally consider calls as inline
- // candidates.
- if (!Call->isNoInline() && IsLoweredToCall &&
- ((F->hasInternalLinkage() && F->hasOneUse()) || PrepareForLTO)) {
+ // When preparing for LTO, liberally consider calls as inline
+ // candidates.
+ if (!Call->isNoInline() && IsLoweredToCall &&
+ ((F->hasInternalLinkage() && F->hasOneUse()) || PrepareForLTO)) {
++NumInlineCandidates;
- }
+ }
// If this call is to function itself, then the function is recursive.
// Inlining it into other functions is a bad idea, because this is
@@ -143,7 +143,7 @@ void CodeMetrics::analyzeBasicBlock(
if (F == BB->getParent())
isRecursive = true;
- if (IsLoweredToCall)
+ if (IsLoweredToCall)
++NumCalls;
} else {
// We don't want inline asm to count as a call - that would prevent loop
diff --git a/contrib/libs/llvm12/lib/Analysis/ConstantFolding.cpp b/contrib/libs/llvm12/lib/Analysis/ConstantFolding.cpp
index b514387d88..cc1ce4c658 100644
--- a/contrib/libs/llvm12/lib/Analysis/ConstantFolding.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/ConstantFolding.cpp
@@ -18,7 +18,7 @@
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
@@ -42,8 +42,8 @@
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
-#include "llvm/IR/IntrinsicsARM.h"
-#include "llvm/IR/IntrinsicsWebAssembly.h"
+#include "llvm/IR/IntrinsicsARM.h"
+#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/IR/IntrinsicsX86.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Type.h"
@@ -105,16 +105,16 @@ Constant *FoldBitCast(Constant *C, Type *DestTy, const DataLayout &DL) {
"Invalid constantexpr bitcast!");
// Catch the obvious splat cases.
- if (C->isNullValue() && !DestTy->isX86_MMXTy() && !DestTy->isX86_AMXTy())
+ if (C->isNullValue() && !DestTy->isX86_MMXTy() && !DestTy->isX86_AMXTy())
return Constant::getNullValue(DestTy);
- if (C->isAllOnesValue() && !DestTy->isX86_MMXTy() && !DestTy->isX86_AMXTy() &&
+ if (C->isAllOnesValue() && !DestTy->isX86_MMXTy() && !DestTy->isX86_AMXTy() &&
!DestTy->isPtrOrPtrVectorTy()) // Don't get ones for ptr types!
return Constant::getAllOnesValue(DestTy);
if (auto *VTy = dyn_cast<VectorType>(C->getType())) {
// Handle a vector->scalar integer/fp cast.
if (isa<IntegerType>(DestTy) || DestTy->isFloatingPointTy()) {
- unsigned NumSrcElts = cast<FixedVectorType>(VTy)->getNumElements();
+ unsigned NumSrcElts = cast<FixedVectorType>(VTy)->getNumElements();
Type *SrcEltTy = VTy->getElementType();
// If the vector is a vector of floating point, convert it to vector of int
@@ -157,8 +157,8 @@ Constant *FoldBitCast(Constant *C, Type *DestTy, const DataLayout &DL) {
return ConstantExpr::getBitCast(C, DestTy);
// If the element types match, IR can fold it.
- unsigned NumDstElt = cast<FixedVectorType>(DestVTy)->getNumElements();
- unsigned NumSrcElt = cast<FixedVectorType>(C->getType())->getNumElements();
+ unsigned NumDstElt = cast<FixedVectorType>(DestVTy)->getNumElements();
+ unsigned NumSrcElt = cast<FixedVectorType>(C->getType())->getNumElements();
if (NumDstElt == NumSrcElt)
return ConstantExpr::getBitCast(C, DestTy);
@@ -295,11 +295,11 @@ Constant *FoldBitCast(Constant *C, Type *DestTy, const DataLayout &DL) {
/// If this constant is a constant offset from a global, return the global and
/// the constant. Because of constantexprs, this function is recursive.
bool llvm::IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV,
- APInt &Offset, const DataLayout &DL,
- DSOLocalEquivalent **DSOEquiv) {
- if (DSOEquiv)
- *DSOEquiv = nullptr;
-
+ APInt &Offset, const DataLayout &DL,
+ DSOLocalEquivalent **DSOEquiv) {
+ if (DSOEquiv)
+ *DSOEquiv = nullptr;
+
// Trivial case, constant is the global.
if ((GV = dyn_cast<GlobalValue>(C))) {
unsigned BitWidth = DL.getIndexTypeSizeInBits(GV->getType());
@@ -307,15 +307,15 @@ bool llvm::IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV,
return true;
}
- if (auto *FoundDSOEquiv = dyn_cast<DSOLocalEquivalent>(C)) {
- if (DSOEquiv)
- *DSOEquiv = FoundDSOEquiv;
- GV = FoundDSOEquiv->getGlobalValue();
- unsigned BitWidth = DL.getIndexTypeSizeInBits(GV->getType());
- Offset = APInt(BitWidth, 0);
- return true;
- }
-
+ if (auto *FoundDSOEquiv = dyn_cast<DSOLocalEquivalent>(C)) {
+ if (DSOEquiv)
+ *DSOEquiv = FoundDSOEquiv;
+ GV = FoundDSOEquiv->getGlobalValue();
+ unsigned BitWidth = DL.getIndexTypeSizeInBits(GV->getType());
+ Offset = APInt(BitWidth, 0);
+ return true;
+ }
+
// Otherwise, if this isn't a constant expr, bail out.
auto *CE = dyn_cast<ConstantExpr>(C);
if (!CE) return false;
@@ -323,8 +323,8 @@ bool llvm::IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV,
// Look through ptr->int and ptr->ptr casts.
if (CE->getOpcode() == Instruction::PtrToInt ||
CE->getOpcode() == Instruction::BitCast)
- return IsConstantOffsetFromGlobal(CE->getOperand(0), GV, Offset, DL,
- DSOEquiv);
+ return IsConstantOffsetFromGlobal(CE->getOperand(0), GV, Offset, DL,
+ DSOEquiv);
// i32* getelementptr ([5 x i32]* @a, i32 0, i32 5)
auto *GEP = dyn_cast<GEPOperator>(CE);
@@ -335,8 +335,8 @@ bool llvm::IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV,
APInt TmpOffset(BitWidth, 0);
// If the base isn't a global+constant, we aren't either.
- if (!IsConstantOffsetFromGlobal(CE->getOperand(0), GV, TmpOffset, DL,
- DSOEquiv))
+ if (!IsConstantOffsetFromGlobal(CE->getOperand(0), GV, TmpOffset, DL,
+ DSOEquiv))
return false;
// Otherwise, add any offset that our operands provide.
@@ -358,13 +358,13 @@ Constant *llvm::ConstantFoldLoadThroughBitcast(Constant *C, Type *DestTy,
// Catch the obvious splat cases (since all-zeros can coerce non-integral
// pointers legally).
- if (C->isNullValue() && !DestTy->isX86_MMXTy() && !DestTy->isX86_AMXTy())
+ if (C->isNullValue() && !DestTy->isX86_MMXTy() && !DestTy->isX86_AMXTy())
return Constant::getNullValue(DestTy);
if (C->isAllOnesValue() &&
(DestTy->isIntegerTy() || DestTy->isFloatingPointTy() ||
DestTy->isVectorTy()) &&
- !DestTy->isX86_AMXTy() && !DestTy->isX86_MMXTy() &&
- !DestTy->isPtrOrPtrVectorTy())
+ !DestTy->isX86_AMXTy() && !DestTy->isX86_MMXTy() &&
+ !DestTy->isPtrOrPtrVectorTy())
// Get ones when the input is trivial, but
// only for supported types inside getAllOnesValue.
return Constant::getAllOnesValue(DestTy);
@@ -508,8 +508,8 @@ bool ReadDataFromGlobal(Constant *C, uint64_t ByteOffset, unsigned char *CurPtr,
NumElts = AT->getNumElements();
EltTy = AT->getElementType();
} else {
- NumElts = cast<FixedVectorType>(C->getType())->getNumElements();
- EltTy = cast<FixedVectorType>(C->getType())->getElementType();
+ NumElts = cast<FixedVectorType>(C->getType())->getNumElements();
+ EltTy = cast<FixedVectorType>(C->getType())->getElementType();
}
uint64_t EltSize = DL.getTypeAllocSize(EltTy);
uint64_t Index = ByteOffset / EltSize;
@@ -576,16 +576,16 @@ Constant *FoldReinterpretLoadFromConstPtr(Constant *C, Type *LoadTy,
C = FoldBitCast(C, MapTy->getPointerTo(AS), DL);
if (Constant *Res = FoldReinterpretLoadFromConstPtr(C, MapTy, DL)) {
- if (Res->isNullValue() && !LoadTy->isX86_MMXTy() &&
- !LoadTy->isX86_AMXTy())
+ if (Res->isNullValue() && !LoadTy->isX86_MMXTy() &&
+ !LoadTy->isX86_AMXTy())
// Materializing a zero can be done trivially without a bitcast
return Constant::getNullValue(LoadTy);
Type *CastTy = LoadTy->isPtrOrPtrVectorTy() ? DL.getIntPtrType(LoadTy) : LoadTy;
Res = FoldBitCast(Res, CastTy, DL);
if (LoadTy->isPtrOrPtrVectorTy()) {
// For vector of pointer, we needed to first convert to a vector of integer, then do vector inttoptr
- if (Res->isNullValue() && !LoadTy->isX86_MMXTy() &&
- !LoadTy->isX86_AMXTy())
+ if (Res->isNullValue() && !LoadTy->isX86_MMXTy() &&
+ !LoadTy->isX86_AMXTy())
return Constant::getNullValue(LoadTy);
if (DL.isNonIntegralPointerType(LoadTy->getScalarType()))
// Be careful not to replace a load of an addrspace value with an inttoptr here
@@ -738,7 +738,7 @@ Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty,
// If this load comes from anywhere in a constant global, and if the global
// is all undef or zero, we know what it loads.
- if (auto *GV = dyn_cast<GlobalVariable>(getUnderlyingObject(CE))) {
+ if (auto *GV = dyn_cast<GlobalVariable>(getUnderlyingObject(CE))) {
if (GV->isConstant() && GV->hasDefinitiveInitializer()) {
if (GV->getInitializer()->isNullValue())
return Constant::getNullValue(Ty);
@@ -1091,8 +1091,8 @@ Constant *ConstantFoldInstOperandsImpl(const Value *InstOrCE, unsigned Opcode,
default: return nullptr;
case Instruction::ICmp:
case Instruction::FCmp: llvm_unreachable("Invalid for compares");
- case Instruction::Freeze:
- return isGuaranteedNotToBeUndefOrPoison(Ops[0]) ? Ops[0] : nullptr;
+ case Instruction::Freeze:
+ return isGuaranteedNotToBeUndefOrPoison(Ops[0]) ? Ops[0] : nullptr;
case Instruction::Call:
if (auto *F = dyn_cast<Function>(Ops.back())) {
const auto *Call = cast<CallBase>(InstOrCE);
@@ -1456,12 +1456,12 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
case Intrinsic::launder_invariant_group:
case Intrinsic::strip_invariant_group:
case Intrinsic::masked_load:
- case Intrinsic::get_active_lane_mask:
- case Intrinsic::abs:
- case Intrinsic::smax:
- case Intrinsic::smin:
- case Intrinsic::umax:
- case Intrinsic::umin:
+ case Intrinsic::get_active_lane_mask:
+ case Intrinsic::abs:
+ case Intrinsic::smax:
+ case Intrinsic::smin:
+ case Intrinsic::umax:
+ case Intrinsic::umin:
case Intrinsic::sadd_with_overflow:
case Intrinsic::uadd_with_overflow:
case Intrinsic::ssub_with_overflow:
@@ -1476,25 +1476,25 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
case Intrinsic::smul_fix_sat:
case Intrinsic::bitreverse:
case Intrinsic::is_constant:
- case Intrinsic::vector_reduce_add:
- case Intrinsic::vector_reduce_mul:
- case Intrinsic::vector_reduce_and:
- case Intrinsic::vector_reduce_or:
- case Intrinsic::vector_reduce_xor:
- case Intrinsic::vector_reduce_smin:
- case Intrinsic::vector_reduce_smax:
- case Intrinsic::vector_reduce_umin:
- case Intrinsic::vector_reduce_umax:
- // Target intrinsics
- case Intrinsic::arm_mve_vctp8:
- case Intrinsic::arm_mve_vctp16:
- case Intrinsic::arm_mve_vctp32:
- case Intrinsic::arm_mve_vctp64:
- // WebAssembly float semantics are always known
- case Intrinsic::wasm_trunc_signed:
- case Intrinsic::wasm_trunc_unsigned:
- case Intrinsic::wasm_trunc_saturate_signed:
- case Intrinsic::wasm_trunc_saturate_unsigned:
+ case Intrinsic::vector_reduce_add:
+ case Intrinsic::vector_reduce_mul:
+ case Intrinsic::vector_reduce_and:
+ case Intrinsic::vector_reduce_or:
+ case Intrinsic::vector_reduce_xor:
+ case Intrinsic::vector_reduce_smin:
+ case Intrinsic::vector_reduce_smax:
+ case Intrinsic::vector_reduce_umin:
+ case Intrinsic::vector_reduce_umax:
+ // Target intrinsics
+ case Intrinsic::arm_mve_vctp8:
+ case Intrinsic::arm_mve_vctp16:
+ case Intrinsic::arm_mve_vctp32:
+ case Intrinsic::arm_mve_vctp64:
+ // WebAssembly float semantics are always known
+ case Intrinsic::wasm_trunc_signed:
+ case Intrinsic::wasm_trunc_unsigned:
+ case Intrinsic::wasm_trunc_saturate_signed:
+ case Intrinsic::wasm_trunc_saturate_unsigned:
return true;
// Floating point operations cannot be folded in strictfp functions in
@@ -1515,8 +1515,8 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
case Intrinsic::powi:
case Intrinsic::fma:
case Intrinsic::fmuladd:
- case Intrinsic::fptoui_sat:
- case Intrinsic::fptosi_sat:
+ case Intrinsic::fptoui_sat:
+ case Intrinsic::fptosi_sat:
case Intrinsic::convert_from_fp16:
case Intrinsic::convert_to_fp16:
case Intrinsic::amdgcn_cos:
@@ -1525,7 +1525,7 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
case Intrinsic::amdgcn_cubesc:
case Intrinsic::amdgcn_cubetc:
case Intrinsic::amdgcn_fmul_legacy:
- case Intrinsic::amdgcn_fma_legacy:
+ case Intrinsic::amdgcn_fma_legacy:
case Intrinsic::amdgcn_fract:
case Intrinsic::amdgcn_ldexp:
case Intrinsic::amdgcn_sin:
@@ -1733,31 +1733,31 @@ Constant *ConstantFoldVectorReduce(Intrinsic::ID IID, Constant *Op) {
return nullptr;
const APInt &X = CI->getValue();
switch (IID) {
- case Intrinsic::vector_reduce_add:
+ case Intrinsic::vector_reduce_add:
Acc = Acc + X;
break;
- case Intrinsic::vector_reduce_mul:
+ case Intrinsic::vector_reduce_mul:
Acc = Acc * X;
break;
- case Intrinsic::vector_reduce_and:
+ case Intrinsic::vector_reduce_and:
Acc = Acc & X;
break;
- case Intrinsic::vector_reduce_or:
+ case Intrinsic::vector_reduce_or:
Acc = Acc | X;
break;
- case Intrinsic::vector_reduce_xor:
+ case Intrinsic::vector_reduce_xor:
Acc = Acc ^ X;
break;
- case Intrinsic::vector_reduce_smin:
+ case Intrinsic::vector_reduce_smin:
Acc = APIntOps::smin(Acc, X);
break;
- case Intrinsic::vector_reduce_smax:
+ case Intrinsic::vector_reduce_smax:
Acc = APIntOps::smax(Acc, X);
break;
- case Intrinsic::vector_reduce_umin:
+ case Intrinsic::vector_reduce_umin:
Acc = APIntOps::umin(Acc, X);
break;
- case Intrinsic::vector_reduce_umax:
+ case Intrinsic::vector_reduce_umax:
Acc = APIntOps::umax(Acc, X);
break;
}
@@ -1832,18 +1832,18 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
// We know we have a "Constant" argument. But we want to only
// return true for manifest constants, not those that depend on
// constants with unknowable values, e.g. GlobalValue or BlockAddress.
- if (Operands[0]->isManifestConstant())
+ if (Operands[0]->isManifestConstant())
return ConstantInt::getTrue(Ty->getContext());
return nullptr;
}
if (isa<UndefValue>(Operands[0])) {
// cosine(arg) is between -1 and 1. cosine(invalid arg) is NaN.
// ctpop() is between 0 and bitwidth, pick 0 for undef.
- // fptoui.sat and fptosi.sat can always fold to zero (for a zero input).
+ // fptoui.sat and fptosi.sat can always fold to zero (for a zero input).
if (IntrinsicID == Intrinsic::cos ||
- IntrinsicID == Intrinsic::ctpop ||
- IntrinsicID == Intrinsic::fptoui_sat ||
- IntrinsicID == Intrinsic::fptosi_sat)
+ IntrinsicID == Intrinsic::ctpop ||
+ IntrinsicID == Intrinsic::fptoui_sat ||
+ IntrinsicID == Intrinsic::fptosi_sat)
return Constant::getNullValue(Ty);
if (IntrinsicID == Intrinsic::bswap ||
IntrinsicID == Intrinsic::bitreverse ||
@@ -1880,51 +1880,51 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
return ConstantInt::get(Ty->getContext(), Val.bitcastToAPInt());
}
- APFloat U = Op->getValueAPF();
-
- if (IntrinsicID == Intrinsic::wasm_trunc_signed ||
- IntrinsicID == Intrinsic::wasm_trunc_unsigned ||
- IntrinsicID == Intrinsic::wasm_trunc_saturate_signed ||
- IntrinsicID == Intrinsic::wasm_trunc_saturate_unsigned) {
-
- bool Saturating = IntrinsicID == Intrinsic::wasm_trunc_saturate_signed ||
- IntrinsicID == Intrinsic::wasm_trunc_saturate_unsigned;
- bool Signed = IntrinsicID == Intrinsic::wasm_trunc_signed ||
- IntrinsicID == Intrinsic::wasm_trunc_saturate_signed;
-
- if (U.isNaN())
- return Saturating ? ConstantInt::get(Ty, 0) : nullptr;
-
- unsigned Width = Ty->getIntegerBitWidth();
- APSInt Int(Width, !Signed);
- bool IsExact = false;
- APFloat::opStatus Status =
- U.convertToInteger(Int, APFloat::rmTowardZero, &IsExact);
-
- if (Status == APFloat::opOK || Status == APFloat::opInexact)
- return ConstantInt::get(Ty, Int);
-
- if (!Saturating)
- return nullptr;
-
- if (U.isNegative())
- return Signed ? ConstantInt::get(Ty, APInt::getSignedMinValue(Width))
- : ConstantInt::get(Ty, APInt::getMinValue(Width));
- else
- return Signed ? ConstantInt::get(Ty, APInt::getSignedMaxValue(Width))
- : ConstantInt::get(Ty, APInt::getMaxValue(Width));
- }
-
- if (IntrinsicID == Intrinsic::fptoui_sat ||
- IntrinsicID == Intrinsic::fptosi_sat) {
- // convertToInteger() already has the desired saturation semantics.
- APSInt Int(Ty->getIntegerBitWidth(),
- IntrinsicID == Intrinsic::fptoui_sat);
- bool IsExact;
- U.convertToInteger(Int, APFloat::rmTowardZero, &IsExact);
- return ConstantInt::get(Ty, Int);
- }
-
+ APFloat U = Op->getValueAPF();
+
+ if (IntrinsicID == Intrinsic::wasm_trunc_signed ||
+ IntrinsicID == Intrinsic::wasm_trunc_unsigned ||
+ IntrinsicID == Intrinsic::wasm_trunc_saturate_signed ||
+ IntrinsicID == Intrinsic::wasm_trunc_saturate_unsigned) {
+
+ bool Saturating = IntrinsicID == Intrinsic::wasm_trunc_saturate_signed ||
+ IntrinsicID == Intrinsic::wasm_trunc_saturate_unsigned;
+ bool Signed = IntrinsicID == Intrinsic::wasm_trunc_signed ||
+ IntrinsicID == Intrinsic::wasm_trunc_saturate_signed;
+
+ if (U.isNaN())
+ return Saturating ? ConstantInt::get(Ty, 0) : nullptr;
+
+ unsigned Width = Ty->getIntegerBitWidth();
+ APSInt Int(Width, !Signed);
+ bool IsExact = false;
+ APFloat::opStatus Status =
+ U.convertToInteger(Int, APFloat::rmTowardZero, &IsExact);
+
+ if (Status == APFloat::opOK || Status == APFloat::opInexact)
+ return ConstantInt::get(Ty, Int);
+
+ if (!Saturating)
+ return nullptr;
+
+ if (U.isNegative())
+ return Signed ? ConstantInt::get(Ty, APInt::getSignedMinValue(Width))
+ : ConstantInt::get(Ty, APInt::getMinValue(Width));
+ else
+ return Signed ? ConstantInt::get(Ty, APInt::getSignedMaxValue(Width))
+ : ConstantInt::get(Ty, APInt::getMaxValue(Width));
+ }
+
+ if (IntrinsicID == Intrinsic::fptoui_sat ||
+ IntrinsicID == Intrinsic::fptosi_sat) {
+ // convertToInteger() already has the desired saturation semantics.
+ APSInt Int(Ty->getIntegerBitWidth(),
+ IntrinsicID == Intrinsic::fptoui_sat);
+ bool IsExact;
+ U.convertToInteger(Int, APFloat::rmTowardZero, &IsExact);
+ return ConstantInt::get(Ty, Int);
+ }
+
if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy())
return nullptr;
@@ -2262,15 +2262,15 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
if (isa<ConstantAggregateZero>(Operands[0])) {
switch (IntrinsicID) {
default: break;
- case Intrinsic::vector_reduce_add:
- case Intrinsic::vector_reduce_mul:
- case Intrinsic::vector_reduce_and:
- case Intrinsic::vector_reduce_or:
- case Intrinsic::vector_reduce_xor:
- case Intrinsic::vector_reduce_smin:
- case Intrinsic::vector_reduce_smax:
- case Intrinsic::vector_reduce_umin:
- case Intrinsic::vector_reduce_umax:
+ case Intrinsic::vector_reduce_add:
+ case Intrinsic::vector_reduce_mul:
+ case Intrinsic::vector_reduce_and:
+ case Intrinsic::vector_reduce_or:
+ case Intrinsic::vector_reduce_xor:
+ case Intrinsic::vector_reduce_smin:
+ case Intrinsic::vector_reduce_smax:
+ case Intrinsic::vector_reduce_umin:
+ case Intrinsic::vector_reduce_umax:
return ConstantInt::get(Ty, 0);
}
}
@@ -2281,15 +2281,15 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
auto *Op = cast<Constant>(Operands[0]);
switch (IntrinsicID) {
default: break;
- case Intrinsic::vector_reduce_add:
- case Intrinsic::vector_reduce_mul:
- case Intrinsic::vector_reduce_and:
- case Intrinsic::vector_reduce_or:
- case Intrinsic::vector_reduce_xor:
- case Intrinsic::vector_reduce_smin:
- case Intrinsic::vector_reduce_smax:
- case Intrinsic::vector_reduce_umin:
- case Intrinsic::vector_reduce_umax:
+ case Intrinsic::vector_reduce_add:
+ case Intrinsic::vector_reduce_mul:
+ case Intrinsic::vector_reduce_and:
+ case Intrinsic::vector_reduce_or:
+ case Intrinsic::vector_reduce_xor:
+ case Intrinsic::vector_reduce_smin:
+ case Intrinsic::vector_reduce_smax:
+ case Intrinsic::vector_reduce_umin:
+ case Intrinsic::vector_reduce_umax:
if (Constant *C = ConstantFoldVectorReduce(IntrinsicID, Op))
return C;
break;
@@ -2327,25 +2327,25 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
const CallBase *Call) {
assert(Operands.size() == 2 && "Wrong number of operands.");
- if (Ty->isFloatingPointTy()) {
- // TODO: We should have undef handling for all of the FP intrinsics that
- // are attempted to be folded in this function.
- bool IsOp0Undef = isa<UndefValue>(Operands[0]);
- bool IsOp1Undef = isa<UndefValue>(Operands[1]);
- switch (IntrinsicID) {
- case Intrinsic::maxnum:
- case Intrinsic::minnum:
- case Intrinsic::maximum:
- case Intrinsic::minimum:
- // If one argument is undef, return the other argument.
- if (IsOp0Undef)
- return Operands[1];
- if (IsOp1Undef)
- return Operands[0];
- break;
- }
- }
-
+ if (Ty->isFloatingPointTy()) {
+ // TODO: We should have undef handling for all of the FP intrinsics that
+ // are attempted to be folded in this function.
+ bool IsOp0Undef = isa<UndefValue>(Operands[0]);
+ bool IsOp1Undef = isa<UndefValue>(Operands[1]);
+ switch (IntrinsicID) {
+ case Intrinsic::maxnum:
+ case Intrinsic::minnum:
+ case Intrinsic::maximum:
+ case Intrinsic::minimum:
+ // If one argument is undef, return the other argument.
+ if (IsOp0Undef)
+ return Operands[1];
+ if (IsOp1Undef)
+ return Operands[0];
+ break;
+ }
+ }
+
if (auto *Op1 = dyn_cast<ConstantFP>(Operands[0])) {
if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy())
return nullptr;
@@ -2393,8 +2393,8 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
if (IntrinsicID == Intrinsic::amdgcn_fmul_legacy) {
const APFloat &C1 = Op1->getValueAPF();
const APFloat &C2 = Op2->getValueAPF();
- // The legacy behaviour is that multiplying +/- 0.0 by anything, even
- // NaN or infinity, gives +0.0.
+ // The legacy behaviour is that multiplying +/- 0.0 by anything, even
+ // NaN or infinity, gives +0.0.
if (C1.isZero() || C2.isZero())
return ConstantFP::getNullValue(Ty);
return ConstantFP::get(Ty->getContext(), C1 * C2);
@@ -2473,37 +2473,37 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
!getConstIntOrUndef(Operands[1], C1))
return nullptr;
- unsigned BitWidth = Ty->getScalarSizeInBits();
+ unsigned BitWidth = Ty->getScalarSizeInBits();
switch (IntrinsicID) {
default: break;
- case Intrinsic::smax:
- if (!C0 && !C1)
- return UndefValue::get(Ty);
- if (!C0 || !C1)
- return ConstantInt::get(Ty, APInt::getSignedMaxValue(BitWidth));
- return ConstantInt::get(Ty, C0->sgt(*C1) ? *C0 : *C1);
-
- case Intrinsic::smin:
- if (!C0 && !C1)
- return UndefValue::get(Ty);
- if (!C0 || !C1)
- return ConstantInt::get(Ty, APInt::getSignedMinValue(BitWidth));
- return ConstantInt::get(Ty, C0->slt(*C1) ? *C0 : *C1);
-
- case Intrinsic::umax:
- if (!C0 && !C1)
- return UndefValue::get(Ty);
- if (!C0 || !C1)
- return ConstantInt::get(Ty, APInt::getMaxValue(BitWidth));
- return ConstantInt::get(Ty, C0->ugt(*C1) ? *C0 : *C1);
-
- case Intrinsic::umin:
- if (!C0 && !C1)
- return UndefValue::get(Ty);
- if (!C0 || !C1)
- return ConstantInt::get(Ty, APInt::getMinValue(BitWidth));
- return ConstantInt::get(Ty, C0->ult(*C1) ? *C0 : *C1);
-
+ case Intrinsic::smax:
+ if (!C0 && !C1)
+ return UndefValue::get(Ty);
+ if (!C0 || !C1)
+ return ConstantInt::get(Ty, APInt::getSignedMaxValue(BitWidth));
+ return ConstantInt::get(Ty, C0->sgt(*C1) ? *C0 : *C1);
+
+ case Intrinsic::smin:
+ if (!C0 && !C1)
+ return UndefValue::get(Ty);
+ if (!C0 || !C1)
+ return ConstantInt::get(Ty, APInt::getSignedMinValue(BitWidth));
+ return ConstantInt::get(Ty, C0->slt(*C1) ? *C0 : *C1);
+
+ case Intrinsic::umax:
+ if (!C0 && !C1)
+ return UndefValue::get(Ty);
+ if (!C0 || !C1)
+ return ConstantInt::get(Ty, APInt::getMaxValue(BitWidth));
+ return ConstantInt::get(Ty, C0->ugt(*C1) ? *C0 : *C1);
+
+ case Intrinsic::umin:
+ if (!C0 && !C1)
+ return UndefValue::get(Ty);
+ if (!C0 || !C1)
+ return ConstantInt::get(Ty, APInt::getMinValue(BitWidth));
+ return ConstantInt::get(Ty, C0->ult(*C1) ? *C0 : *C1);
+
case Intrinsic::usub_with_overflow:
case Intrinsic::ssub_with_overflow:
case Intrinsic::uadd_with_overflow:
@@ -2588,18 +2588,18 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
return ConstantInt::get(Ty, C0->countTrailingZeros());
else
return ConstantInt::get(Ty, C0->countLeadingZeros());
-
- case Intrinsic::abs:
- // Undef or minimum val operand with poison min --> undef
- assert(C1 && "Must be constant int");
- if (C1->isOneValue() && (!C0 || C0->isMinSignedValue()))
- return UndefValue::get(Ty);
-
- // Undef operand with no poison min --> 0 (sign bit must be clear)
- if (C1->isNullValue() && !C0)
- return Constant::getNullValue(Ty);
-
- return ConstantInt::get(Ty, C0->abs());
+
+ case Intrinsic::abs:
+ // Undef or minimum val operand with poison min --> undef
+ assert(C1 && "Must be constant int");
+ if (C1->isOneValue() && (!C0 || C0->isMinSignedValue()))
+ return UndefValue::get(Ty);
+
+ // Undef operand with no poison min --> 0 (sign bit must be clear)
+ if (C1->isNullValue() && !C0)
+ return Constant::getNullValue(Ty);
+
+ return ConstantInt::get(Ty, C0->abs());
}
return nullptr;
@@ -2728,19 +2728,19 @@ static Constant *ConstantFoldScalarCall3(StringRef Name,
if (const auto *Op3 = dyn_cast<ConstantFP>(Operands[2])) {
switch (IntrinsicID) {
default: break;
- case Intrinsic::amdgcn_fma_legacy: {
- const APFloat &C1 = Op1->getValueAPF();
- const APFloat &C2 = Op2->getValueAPF();
- // The legacy behaviour is that multiplying +/- 0.0 by anything, even
- // NaN or infinity, gives +0.0.
- if (C1.isZero() || C2.isZero()) {
- const APFloat &C3 = Op3->getValueAPF();
- // It's tempting to just return C3 here, but that would give the
- // wrong result if C3 was -0.0.
- return ConstantFP::get(Ty->getContext(), APFloat(0.0f) + C3);
- }
- LLVM_FALLTHROUGH;
- }
+ case Intrinsic::amdgcn_fma_legacy: {
+ const APFloat &C1 = Op1->getValueAPF();
+ const APFloat &C2 = Op2->getValueAPF();
+ // The legacy behaviour is that multiplying +/- 0.0 by anything, even
+ // NaN or infinity, gives +0.0.
+ if (C1.isZero() || C2.isZero()) {
+ const APFloat &C3 = Op3->getValueAPF();
+ // It's tempting to just return C3 here, but that would give the
+ // wrong result if C3 was -0.0.
+ return ConstantFP::get(Ty->getContext(), APFloat(0.0f) + C3);
+ }
+ LLVM_FALLTHROUGH;
+ }
case Intrinsic::fma:
case Intrinsic::fmuladd: {
APFloat V = Op1->getValueAPF();
@@ -2868,8 +2868,8 @@ static Constant *ConstantFoldVectorCall(StringRef Name,
SmallVector<Constant *, 4> Lane(Operands.size());
Type *Ty = FVTy->getElementType();
- switch (IntrinsicID) {
- case Intrinsic::masked_load: {
+ switch (IntrinsicID) {
+ case Intrinsic::masked_load: {
auto *SrcPtr = Operands[0];
auto *Mask = Operands[2];
auto *Passthru = Operands[3];
@@ -2907,52 +2907,52 @@ static Constant *ConstantFoldVectorCall(StringRef Name,
return nullptr;
return ConstantVector::get(NewElements);
}
- case Intrinsic::arm_mve_vctp8:
- case Intrinsic::arm_mve_vctp16:
- case Intrinsic::arm_mve_vctp32:
- case Intrinsic::arm_mve_vctp64: {
- if (auto *Op = dyn_cast<ConstantInt>(Operands[0])) {
- unsigned Lanes = FVTy->getNumElements();
- uint64_t Limit = Op->getZExtValue();
- // vctp64 are currently modelled as returning a v4i1, not a v2i1. Make
- // sure we get the limit right in that case and set all relevant lanes.
- if (IntrinsicID == Intrinsic::arm_mve_vctp64)
- Limit *= 2;
-
- SmallVector<Constant *, 16> NCs;
- for (unsigned i = 0; i < Lanes; i++) {
- if (i < Limit)
- NCs.push_back(ConstantInt::getTrue(Ty));
- else
- NCs.push_back(ConstantInt::getFalse(Ty));
- }
- return ConstantVector::get(NCs);
- }
- break;
- }
- case Intrinsic::get_active_lane_mask: {
- auto *Op0 = dyn_cast<ConstantInt>(Operands[0]);
- auto *Op1 = dyn_cast<ConstantInt>(Operands[1]);
- if (Op0 && Op1) {
- unsigned Lanes = FVTy->getNumElements();
- uint64_t Base = Op0->getZExtValue();
- uint64_t Limit = Op1->getZExtValue();
-
- SmallVector<Constant *, 16> NCs;
- for (unsigned i = 0; i < Lanes; i++) {
- if (Base + i < Limit)
- NCs.push_back(ConstantInt::getTrue(Ty));
- else
- NCs.push_back(ConstantInt::getFalse(Ty));
- }
- return ConstantVector::get(NCs);
- }
- break;
- }
- default:
- break;
- }
-
+ case Intrinsic::arm_mve_vctp8:
+ case Intrinsic::arm_mve_vctp16:
+ case Intrinsic::arm_mve_vctp32:
+ case Intrinsic::arm_mve_vctp64: {
+ if (auto *Op = dyn_cast<ConstantInt>(Operands[0])) {
+ unsigned Lanes = FVTy->getNumElements();
+ uint64_t Limit = Op->getZExtValue();
+ // vctp64 are currently modelled as returning a v4i1, not a v2i1. Make
+ // sure we get the limit right in that case and set all relevant lanes.
+ if (IntrinsicID == Intrinsic::arm_mve_vctp64)
+ Limit *= 2;
+
+ SmallVector<Constant *, 16> NCs;
+ for (unsigned i = 0; i < Lanes; i++) {
+ if (i < Limit)
+ NCs.push_back(ConstantInt::getTrue(Ty));
+ else
+ NCs.push_back(ConstantInt::getFalse(Ty));
+ }
+ return ConstantVector::get(NCs);
+ }
+ break;
+ }
+ case Intrinsic::get_active_lane_mask: {
+ auto *Op0 = dyn_cast<ConstantInt>(Operands[0]);
+ auto *Op1 = dyn_cast<ConstantInt>(Operands[1]);
+ if (Op0 && Op1) {
+ unsigned Lanes = FVTy->getNumElements();
+ uint64_t Base = Op0->getZExtValue();
+ uint64_t Limit = Op1->getZExtValue();
+
+ SmallVector<Constant *, 16> NCs;
+ for (unsigned i = 0; i < Lanes; i++) {
+ if (Base + i < Limit)
+ NCs.push_back(ConstantInt::getTrue(Ty));
+ else
+ NCs.push_back(ConstantInt::getFalse(Ty));
+ }
+ return ConstantVector::get(NCs);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
for (unsigned I = 0, E = FVTy->getNumElements(); I != E; ++I) {
// Gather a column of constants.
for (unsigned J = 0, JE = Operands.size(); J != JE; ++J) {
diff --git a/contrib/libs/llvm12/lib/Analysis/ConstraintSystem.cpp b/contrib/libs/llvm12/lib/Analysis/ConstraintSystem.cpp
index 93a9847e26..9739c6af57 100644
--- a/contrib/libs/llvm12/lib/Analysis/ConstraintSystem.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/ConstraintSystem.cpp
@@ -1,158 +1,158 @@
-//===- ConstraintSytem.cpp - A system of linear constraints. ----*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/ConstraintSystem.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/Debug.h"
-
-#include <algorithm>
-#include <string>
-
-using namespace llvm;
-
-#define DEBUG_TYPE "constraint-system"
-
-bool ConstraintSystem::eliminateUsingFM() {
- // Implementation of Fourier–Motzkin elimination, with some tricks from the
- // paper Pugh, William. "The Omega test: a fast and practical integer
- // programming algorithm for dependence
- // analysis."
- // Supercomputing'91: Proceedings of the 1991 ACM/
- // IEEE conference on Supercomputing. IEEE, 1991.
- assert(!Constraints.empty() &&
- "should only be called for non-empty constraint systems");
- unsigned NumVariables = Constraints[0].size();
- SmallVector<SmallVector<int64_t, 8>, 4> NewSystem;
-
- unsigned NumConstraints = Constraints.size();
- uint32_t NewGCD = 1;
- // FIXME do not use copy
- for (unsigned R1 = 0; R1 < NumConstraints; R1++) {
- if (Constraints[R1][1] == 0) {
- SmallVector<int64_t, 8> NR;
- NR.push_back(Constraints[R1][0]);
- for (unsigned i = 2; i < NumVariables; i++) {
- NR.push_back(Constraints[R1][i]);
- }
- NewSystem.push_back(std::move(NR));
- continue;
- }
-
- // FIXME do not use copy
- for (unsigned R2 = R1 + 1; R2 < NumConstraints; R2++) {
- if (R1 == R2)
- continue;
-
- // FIXME: can we do better than just dropping things here?
- if (Constraints[R2][1] == 0)
- continue;
-
- if ((Constraints[R1][1] < 0 && Constraints[R2][1] < 0) ||
- (Constraints[R1][1] > 0 && Constraints[R2][1] > 0))
- continue;
-
- unsigned LowerR = R1;
- unsigned UpperR = R2;
- if (Constraints[UpperR][1] < 0)
- std::swap(LowerR, UpperR);
-
- SmallVector<int64_t, 8> NR;
- for (unsigned I = 0; I < NumVariables; I++) {
- if (I == 1)
- continue;
-
- int64_t M1, M2, N;
- if (MulOverflow(Constraints[UpperR][I],
- ((-1) * Constraints[LowerR][1] / GCD), M1))
- return false;
- if (MulOverflow(Constraints[LowerR][I],
- (Constraints[UpperR][1] / GCD), M2))
- return false;
- if (AddOverflow(M1, M2, N))
- return false;
- NR.push_back(N);
-
- NewGCD = APIntOps::GreatestCommonDivisor({32, (uint32_t)NR.back()},
- {32, NewGCD})
- .getZExtValue();
- }
- NewSystem.push_back(std::move(NR));
- // Give up if the new system gets too big.
- if (NewSystem.size() > 500)
- return false;
- }
- }
- Constraints = std::move(NewSystem);
- GCD = NewGCD;
-
- return true;
-}
-
-bool ConstraintSystem::mayHaveSolutionImpl() {
- while (!Constraints.empty() && Constraints[0].size() > 1) {
- if (!eliminateUsingFM())
- return true;
- }
-
- if (Constraints.empty() || Constraints[0].size() > 1)
- return true;
-
- return all_of(Constraints, [](auto &R) { return R[0] >= 0; });
-}
-
-void ConstraintSystem::dump(ArrayRef<std::string> Names) const {
- if (Constraints.empty())
- return;
-
- for (auto &Row : Constraints) {
- SmallVector<std::string, 16> Parts;
- for (unsigned I = 1, S = Row.size(); I < S; ++I) {
- if (Row[I] == 0)
- continue;
- std::string Coefficient;
- if (Row[I] != 1)
- Coefficient = std::to_string(Row[I]) + " * ";
- Parts.push_back(Coefficient + Names[I - 1]);
- }
- assert(!Parts.empty() && "need to have at least some parts");
- LLVM_DEBUG(dbgs() << join(Parts, std::string(" + "))
- << " <= " << std::to_string(Row[0]) << "\n");
- }
-}
-
-void ConstraintSystem::dump() const {
- SmallVector<std::string, 16> Names;
- for (unsigned i = 1; i < Constraints.back().size(); ++i)
- Names.push_back("x" + std::to_string(i));
- LLVM_DEBUG(dbgs() << "---\n");
- dump(Names);
-}
-
-bool ConstraintSystem::mayHaveSolution() {
- LLVM_DEBUG(dump());
- bool HasSolution = mayHaveSolutionImpl();
- LLVM_DEBUG(dbgs() << (HasSolution ? "sat" : "unsat") << "\n");
- return HasSolution;
-}
-
-bool ConstraintSystem::isConditionImplied(SmallVector<int64_t, 8> R) {
- // If all variable coefficients are 0, we have 'C >= 0'. If the constant is >=
- // 0, R is always true, regardless of the system.
- if (all_of(makeArrayRef(R).drop_front(1), [](int64_t C) { return C == 0; }))
- return R[0] >= 0;
-
- // If there is no solution with the negation of R added to the system, the
- // condition must hold based on the existing constraints.
- R = ConstraintSystem::negate(R);
-
- auto NewSystem = *this;
- NewSystem.addVariableRow(R);
- return !NewSystem.mayHaveSolution();
-}
+//===- ConstraintSytem.cpp - A system of linear constraints. ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/ConstraintSystem.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Debug.h"
+
+#include <algorithm>
+#include <string>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "constraint-system"
+
+bool ConstraintSystem::eliminateUsingFM() {
+ // Implementation of Fourier–Motzkin elimination, with some tricks from the
+ // paper Pugh, William. "The Omega test: a fast and practical integer
+ // programming algorithm for dependence
+ // analysis."
+ // Supercomputing'91: Proceedings of the 1991 ACM/
+ // IEEE conference on Supercomputing. IEEE, 1991.
+ assert(!Constraints.empty() &&
+ "should only be called for non-empty constraint systems");
+ unsigned NumVariables = Constraints[0].size();
+ SmallVector<SmallVector<int64_t, 8>, 4> NewSystem;
+
+ unsigned NumConstraints = Constraints.size();
+ uint32_t NewGCD = 1;
+ // FIXME do not use copy
+ for (unsigned R1 = 0; R1 < NumConstraints; R1++) {
+ if (Constraints[R1][1] == 0) {
+ SmallVector<int64_t, 8> NR;
+ NR.push_back(Constraints[R1][0]);
+ for (unsigned i = 2; i < NumVariables; i++) {
+ NR.push_back(Constraints[R1][i]);
+ }
+ NewSystem.push_back(std::move(NR));
+ continue;
+ }
+
+ // FIXME do not use copy
+ for (unsigned R2 = R1 + 1; R2 < NumConstraints; R2++) {
+ if (R1 == R2)
+ continue;
+
+ // FIXME: can we do better than just dropping things here?
+ if (Constraints[R2][1] == 0)
+ continue;
+
+ if ((Constraints[R1][1] < 0 && Constraints[R2][1] < 0) ||
+ (Constraints[R1][1] > 0 && Constraints[R2][1] > 0))
+ continue;
+
+ unsigned LowerR = R1;
+ unsigned UpperR = R2;
+ if (Constraints[UpperR][1] < 0)
+ std::swap(LowerR, UpperR);
+
+ SmallVector<int64_t, 8> NR;
+ for (unsigned I = 0; I < NumVariables; I++) {
+ if (I == 1)
+ continue;
+
+ int64_t M1, M2, N;
+ if (MulOverflow(Constraints[UpperR][I],
+ ((-1) * Constraints[LowerR][1] / GCD), M1))
+ return false;
+ if (MulOverflow(Constraints[LowerR][I],
+ (Constraints[UpperR][1] / GCD), M2))
+ return false;
+ if (AddOverflow(M1, M2, N))
+ return false;
+ NR.push_back(N);
+
+ NewGCD = APIntOps::GreatestCommonDivisor({32, (uint32_t)NR.back()},
+ {32, NewGCD})
+ .getZExtValue();
+ }
+ NewSystem.push_back(std::move(NR));
+ // Give up if the new system gets too big.
+ if (NewSystem.size() > 500)
+ return false;
+ }
+ }
+ Constraints = std::move(NewSystem);
+ GCD = NewGCD;
+
+ return true;
+}
+
+bool ConstraintSystem::mayHaveSolutionImpl() {
+ while (!Constraints.empty() && Constraints[0].size() > 1) {
+ if (!eliminateUsingFM())
+ return true;
+ }
+
+ if (Constraints.empty() || Constraints[0].size() > 1)
+ return true;
+
+ return all_of(Constraints, [](auto &R) { return R[0] >= 0; });
+}
+
+void ConstraintSystem::dump(ArrayRef<std::string> Names) const {
+ if (Constraints.empty())
+ return;
+
+ for (auto &Row : Constraints) {
+ SmallVector<std::string, 16> Parts;
+ for (unsigned I = 1, S = Row.size(); I < S; ++I) {
+ if (Row[I] == 0)
+ continue;
+ std::string Coefficient;
+ if (Row[I] != 1)
+ Coefficient = std::to_string(Row[I]) + " * ";
+ Parts.push_back(Coefficient + Names[I - 1]);
+ }
+ assert(!Parts.empty() && "need to have at least some parts");
+ LLVM_DEBUG(dbgs() << join(Parts, std::string(" + "))
+ << " <= " << std::to_string(Row[0]) << "\n");
+ }
+}
+
+void ConstraintSystem::dump() const {
+ SmallVector<std::string, 16> Names;
+ for (unsigned i = 1; i < Constraints.back().size(); ++i)
+ Names.push_back("x" + std::to_string(i));
+ LLVM_DEBUG(dbgs() << "---\n");
+ dump(Names);
+}
+
+bool ConstraintSystem::mayHaveSolution() {
+ LLVM_DEBUG(dump());
+ bool HasSolution = mayHaveSolutionImpl();
+ LLVM_DEBUG(dbgs() << (HasSolution ? "sat" : "unsat") << "\n");
+ return HasSolution;
+}
+
+bool ConstraintSystem::isConditionImplied(SmallVector<int64_t, 8> R) {
+ // If all variable coefficients are 0, we have 'C >= 0'. If the constant is >=
+ // 0, R is always true, regardless of the system.
+ if (all_of(makeArrayRef(R).drop_front(1), [](int64_t C) { return C == 0; }))
+ return R[0] >= 0;
+
+ // If there is no solution with the negation of R added to the system, the
+ // condition must hold based on the existing constraints.
+ R = ConstraintSystem::negate(R);
+
+ auto NewSystem = *this;
+ NewSystem.addVariableRow(R);
+ return !NewSystem.mayHaveSolution();
+}
diff --git a/contrib/libs/llvm12/lib/Analysis/CostModel.cpp b/contrib/libs/llvm12/lib/Analysis/CostModel.cpp
index 5e35c450ef..19c307b4ef 100644
--- a/contrib/libs/llvm12/lib/Analysis/CostModel.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/CostModel.cpp
@@ -35,11 +35,11 @@ static cl::opt<TargetTransformInfo::TargetCostKind> CostKind(
clEnumValN(TargetTransformInfo::TCK_Latency,
"latency", "Instruction latency"),
clEnumValN(TargetTransformInfo::TCK_CodeSize,
- "code-size", "Code size"),
- clEnumValN(TargetTransformInfo::TCK_SizeAndLatency,
- "size-latency", "Code size and latency")));
+ "code-size", "Code size"),
+ clEnumValN(TargetTransformInfo::TCK_SizeAndLatency,
+ "size-latency", "Code size and latency")));
+
-
#define CM_NAME "cost-model"
#define DEBUG_TYPE CM_NAME
@@ -57,7 +57,7 @@ namespace {
/// Returns -1 if the cost is unknown.
/// Note, this method does not cache the cost calculation and it
/// can be expensive in some cases.
- InstructionCost getInstructionCost(const Instruction *I) const {
+ InstructionCost getInstructionCost(const Instruction *I) const {
return TTI->getInstructionCost(I, TargetTransformInfo::TCK_RecipThroughput);
}
@@ -103,9 +103,9 @@ void CostModelAnalysis::print(raw_ostream &OS, const Module*) const {
for (BasicBlock &B : *F) {
for (Instruction &Inst : B) {
- InstructionCost Cost = TTI->getInstructionCost(&Inst, CostKind);
- if (auto CostVal = Cost.getValue())
- OS << "Cost Model: Found an estimated cost of " << *CostVal;
+ InstructionCost Cost = TTI->getInstructionCost(&Inst, CostKind);
+ if (auto CostVal = Cost.getValue())
+ OS << "Cost Model: Found an estimated cost of " << *CostVal;
else
OS << "Cost Model: Unknown cost";
diff --git a/contrib/libs/llvm12/lib/Analysis/DDG.cpp b/contrib/libs/llvm12/lib/Analysis/DDG.cpp
index 1d4fe14038..da5de75a03 100644
--- a/contrib/libs/llvm12/lib/Analysis/DDG.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/DDG.cpp
@@ -49,7 +49,7 @@ bool DDGNode::collectInstructions(
assert(!isa<PiBlockDDGNode>(PN) && "Nested PiBlocks are not supported.");
SmallVector<Instruction *, 8> TmpIList;
PN->collectInstructions(Pred, TmpIList);
- llvm::append_range(IList, TmpIList);
+ llvm::append_range(IList, TmpIList);
}
} else
llvm_unreachable("unimplemented type of node");
@@ -190,7 +190,7 @@ DataDependenceGraph::DataDependenceGraph(Function &F, DependenceInfo &D)
// directions.
BasicBlockListType BBList;
for (auto &SCC : make_range(scc_begin(&F), scc_end(&F)))
- append_range(BBList, SCC);
+ append_range(BBList, SCC);
std::reverse(BBList.begin(), BBList.end());
DDGBuilder(*this, D, BBList).populate();
}
@@ -206,7 +206,7 @@ DataDependenceGraph::DataDependenceGraph(Loop &L, LoopInfo &LI,
LoopBlocksDFS DFS(&L);
DFS.perform(&LI);
BasicBlockListType BBList;
- append_range(BBList, make_range(DFS.beginRPO(), DFS.endRPO()));
+ append_range(BBList, make_range(DFS.beginRPO(), DFS.endRPO()));
DDGBuilder(*this, D, BBList).populate();
}
diff --git a/contrib/libs/llvm12/lib/Analysis/DDGPrinter.cpp b/contrib/libs/llvm12/lib/Analysis/DDGPrinter.cpp
index 9c16fcdc8b..51bd548098 100644
--- a/contrib/libs/llvm12/lib/Analysis/DDGPrinter.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/DDGPrinter.cpp
@@ -1,150 +1,150 @@
-//===- DDGPrinter.cpp - DOT printer for the data dependence graph ----------==//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//
-// This file defines the `-dot-ddg` analysis pass, which emits DDG in DOT format
-// in a file named `ddg.<graph-name>.dot` for each loop in a function.
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/DDGPrinter.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/GraphWriter.h"
-
-using namespace llvm;
-
-static cl::opt<bool> DotOnly("dot-ddg-only", cl::init(false), cl::Hidden,
- cl::ZeroOrMore, cl::desc("simple ddg dot graph"));
-static cl::opt<std::string> DDGDotFilenamePrefix(
- "dot-ddg-filename-prefix", cl::init("ddg"), cl::Hidden,
- cl::desc("The prefix used for the DDG dot file names."));
-
-static void writeDDGToDotFile(DataDependenceGraph &G, bool DOnly = false);
-
-//===--------------------------------------------------------------------===//
-// Implementation of DDG DOT Printer for a loop
-//===--------------------------------------------------------------------===//
-PreservedAnalyses DDGDotPrinterPass::run(Loop &L, LoopAnalysisManager &AM,
- LoopStandardAnalysisResults &AR,
- LPMUpdater &U) {
- writeDDGToDotFile(*AM.getResult<DDGAnalysis>(L, AR), DotOnly);
- return PreservedAnalyses::all();
-}
-
-static void writeDDGToDotFile(DataDependenceGraph &G, bool DOnly) {
- std::string Filename =
- Twine(DDGDotFilenamePrefix + "." + G.getName() + ".dot").str();
- errs() << "Writing '" << Filename << "'...";
-
- std::error_code EC;
- raw_fd_ostream File(Filename, EC, sys::fs::F_Text);
-
- if (!EC)
- // We only provide the constant verson of the DOTGraphTrait specialization,
- // hence the conversion to const pointer
- WriteGraph(File, (const DataDependenceGraph *)&G, DOnly);
- else
- errs() << " error opening file for writing!";
- errs() << "\n";
-}
-
-//===--------------------------------------------------------------------===//
-// DDG DOT Printer Implementation
-//===--------------------------------------------------------------------===//
-std::string DDGDotGraphTraits::getNodeLabel(const DDGNode *Node,
- const DataDependenceGraph *Graph) {
- if (isSimple())
- return getSimpleNodeLabel(Node, Graph);
- else
- return getVerboseNodeLabel(Node, Graph);
-}
-
-std::string DDGDotGraphTraits::getEdgeAttributes(
- const DDGNode *Node, GraphTraits<const DDGNode *>::ChildIteratorType I,
- const DataDependenceGraph *G) {
- const DDGEdge *E = static_cast<const DDGEdge *>(*I.getCurrent());
- if (isSimple())
- return getSimpleEdgeAttributes(Node, E, G);
- else
- return getVerboseEdgeAttributes(Node, E, G);
-}
-
-bool DDGDotGraphTraits::isNodeHidden(const DDGNode *Node,
- const DataDependenceGraph *Graph) {
- if (isSimple() && isa<RootDDGNode>(Node))
- return true;
- assert(Graph && "expected a valid graph pointer");
- return Graph->getPiBlock(*Node) != nullptr;
-}
-
-std::string
-DDGDotGraphTraits::getSimpleNodeLabel(const DDGNode *Node,
- const DataDependenceGraph *G) {
- std::string Str;
- raw_string_ostream OS(Str);
- if (isa<SimpleDDGNode>(Node))
- for (auto *II : static_cast<const SimpleDDGNode *>(Node)->getInstructions())
- OS << *II << "\n";
- else if (isa<PiBlockDDGNode>(Node))
- OS << "pi-block\nwith\n"
- << cast<PiBlockDDGNode>(Node)->getNodes().size() << " nodes\n";
- else if (isa<RootDDGNode>(Node))
- OS << "root\n";
- else
- llvm_unreachable("Unimplemented type of node");
- return OS.str();
-}
-
-std::string
-DDGDotGraphTraits::getVerboseNodeLabel(const DDGNode *Node,
- const DataDependenceGraph *G) {
- std::string Str;
- raw_string_ostream OS(Str);
- OS << "<kind:" << Node->getKind() << ">\n";
- if (isa<SimpleDDGNode>(Node))
- for (auto *II : static_cast<const SimpleDDGNode *>(Node)->getInstructions())
- OS << *II << "\n";
- else if (isa<PiBlockDDGNode>(Node)) {
- OS << "--- start of nodes in pi-block ---\n";
- unsigned Count = 0;
- const auto &PNodes = cast<PiBlockDDGNode>(Node)->getNodes();
- for (auto *PN : PNodes) {
- OS << getVerboseNodeLabel(PN, G);
- if (++Count != PNodes.size())
- OS << "\n";
- }
- OS << "--- end of nodes in pi-block ---\n";
- } else if (isa<RootDDGNode>(Node))
- OS << "root\n";
- else
- llvm_unreachable("Unimplemented type of node");
- return OS.str();
-}
-
-std::string DDGDotGraphTraits::getSimpleEdgeAttributes(
- const DDGNode *Src, const DDGEdge *Edge, const DataDependenceGraph *G) {
- std::string Str;
- raw_string_ostream OS(Str);
- DDGEdge::EdgeKind Kind = Edge->getKind();
- OS << "label=\"[" << Kind << "]\"";
- return OS.str();
-}
-
-std::string DDGDotGraphTraits::getVerboseEdgeAttributes(
- const DDGNode *Src, const DDGEdge *Edge, const DataDependenceGraph *G) {
- std::string Str;
- raw_string_ostream OS(Str);
- DDGEdge::EdgeKind Kind = Edge->getKind();
- OS << "label=\"[";
- if (Kind == DDGEdge::EdgeKind::MemoryDependence)
- OS << G->getDependenceString(*Src, Edge->getTargetNode());
- else
- OS << Kind;
- OS << "]\"";
- return OS.str();
-}
+//===- DDGPrinter.cpp - DOT printer for the data dependence graph ----------==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//
+// This file defines the `-dot-ddg` analysis pass, which emits DDG in DOT format
+// in a file named `ddg.<graph-name>.dot` for each loop in a function.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/DDGPrinter.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/GraphWriter.h"
+
+using namespace llvm;
+
+static cl::opt<bool> DotOnly("dot-ddg-only", cl::init(false), cl::Hidden,
+ cl::ZeroOrMore, cl::desc("simple ddg dot graph"));
+static cl::opt<std::string> DDGDotFilenamePrefix(
+ "dot-ddg-filename-prefix", cl::init("ddg"), cl::Hidden,
+ cl::desc("The prefix used for the DDG dot file names."));
+
+static void writeDDGToDotFile(DataDependenceGraph &G, bool DOnly = false);
+
+//===--------------------------------------------------------------------===//
+// Implementation of DDG DOT Printer for a loop
+//===--------------------------------------------------------------------===//
+PreservedAnalyses DDGDotPrinterPass::run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR,
+ LPMUpdater &U) {
+ writeDDGToDotFile(*AM.getResult<DDGAnalysis>(L, AR), DotOnly);
+ return PreservedAnalyses::all();
+}
+
+static void writeDDGToDotFile(DataDependenceGraph &G, bool DOnly) {
+ std::string Filename =
+ Twine(DDGDotFilenamePrefix + "." + G.getName() + ".dot").str();
+ errs() << "Writing '" << Filename << "'...";
+
+ std::error_code EC;
+ raw_fd_ostream File(Filename, EC, sys::fs::F_Text);
+
+ if (!EC)
+ // We only provide the constant verson of the DOTGraphTrait specialization,
+ // hence the conversion to const pointer
+ WriteGraph(File, (const DataDependenceGraph *)&G, DOnly);
+ else
+ errs() << " error opening file for writing!";
+ errs() << "\n";
+}
+
+//===--------------------------------------------------------------------===//
+// DDG DOT Printer Implementation
+//===--------------------------------------------------------------------===//
+std::string DDGDotGraphTraits::getNodeLabel(const DDGNode *Node,
+ const DataDependenceGraph *Graph) {
+ if (isSimple())
+ return getSimpleNodeLabel(Node, Graph);
+ else
+ return getVerboseNodeLabel(Node, Graph);
+}
+
+std::string DDGDotGraphTraits::getEdgeAttributes(
+ const DDGNode *Node, GraphTraits<const DDGNode *>::ChildIteratorType I,
+ const DataDependenceGraph *G) {
+ const DDGEdge *E = static_cast<const DDGEdge *>(*I.getCurrent());
+ if (isSimple())
+ return getSimpleEdgeAttributes(Node, E, G);
+ else
+ return getVerboseEdgeAttributes(Node, E, G);
+}
+
+bool DDGDotGraphTraits::isNodeHidden(const DDGNode *Node,
+ const DataDependenceGraph *Graph) {
+ if (isSimple() && isa<RootDDGNode>(Node))
+ return true;
+ assert(Graph && "expected a valid graph pointer");
+ return Graph->getPiBlock(*Node) != nullptr;
+}
+
+std::string
+DDGDotGraphTraits::getSimpleNodeLabel(const DDGNode *Node,
+ const DataDependenceGraph *G) {
+ std::string Str;
+ raw_string_ostream OS(Str);
+ if (isa<SimpleDDGNode>(Node))
+ for (auto *II : static_cast<const SimpleDDGNode *>(Node)->getInstructions())
+ OS << *II << "\n";
+ else if (isa<PiBlockDDGNode>(Node))
+ OS << "pi-block\nwith\n"
+ << cast<PiBlockDDGNode>(Node)->getNodes().size() << " nodes\n";
+ else if (isa<RootDDGNode>(Node))
+ OS << "root\n";
+ else
+ llvm_unreachable("Unimplemented type of node");
+ return OS.str();
+}
+
+std::string
+DDGDotGraphTraits::getVerboseNodeLabel(const DDGNode *Node,
+ const DataDependenceGraph *G) {
+ std::string Str;
+ raw_string_ostream OS(Str);
+ OS << "<kind:" << Node->getKind() << ">\n";
+ if (isa<SimpleDDGNode>(Node))
+ for (auto *II : static_cast<const SimpleDDGNode *>(Node)->getInstructions())
+ OS << *II << "\n";
+ else if (isa<PiBlockDDGNode>(Node)) {
+ OS << "--- start of nodes in pi-block ---\n";
+ unsigned Count = 0;
+ const auto &PNodes = cast<PiBlockDDGNode>(Node)->getNodes();
+ for (auto *PN : PNodes) {
+ OS << getVerboseNodeLabel(PN, G);
+ if (++Count != PNodes.size())
+ OS << "\n";
+ }
+ OS << "--- end of nodes in pi-block ---\n";
+ } else if (isa<RootDDGNode>(Node))
+ OS << "root\n";
+ else
+ llvm_unreachable("Unimplemented type of node");
+ return OS.str();
+}
+
+std::string DDGDotGraphTraits::getSimpleEdgeAttributes(
+ const DDGNode *Src, const DDGEdge *Edge, const DataDependenceGraph *G) {
+ std::string Str;
+ raw_string_ostream OS(Str);
+ DDGEdge::EdgeKind Kind = Edge->getKind();
+ OS << "label=\"[" << Kind << "]\"";
+ return OS.str();
+}
+
+std::string DDGDotGraphTraits::getVerboseEdgeAttributes(
+ const DDGNode *Src, const DDGEdge *Edge, const DataDependenceGraph *G) {
+ std::string Str;
+ raw_string_ostream OS(Str);
+ DDGEdge::EdgeKind Kind = Edge->getKind();
+ OS << "label=\"[";
+ if (Kind == DDGEdge::EdgeKind::MemoryDependence)
+ OS << G->getDependenceString(*Src, Edge->getTargetNode());
+ else
+ OS << Kind;
+ OS << "]\"";
+ return OS.str();
+}
diff --git a/contrib/libs/llvm12/lib/Analysis/Delinearization.cpp b/contrib/libs/llvm12/lib/Analysis/Delinearization.cpp
index 50adf84cca..87a41bbf16 100644
--- a/contrib/libs/llvm12/lib/Analysis/Delinearization.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/Delinearization.cpp
@@ -13,7 +13,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Analysis/Delinearization.h"
+#include "llvm/Analysis/Delinearization.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/ScalarEvolution.h"
@@ -24,7 +24,7 @@
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/Type.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
@@ -56,8 +56,8 @@ public:
void print(raw_ostream &O, const Module *M = nullptr) const override;
};
-void printDelinearization(raw_ostream &O, Function *F, LoopInfo *LI,
- ScalarEvolution *SE) {
+void printDelinearization(raw_ostream &O, Function *F, LoopInfo *LI,
+ ScalarEvolution *SE) {
O << "Delinearization on function " << F->getName() << ":\n";
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
Instruction *Inst = &(*I);
@@ -108,25 +108,25 @@ void printDelinearization(raw_ostream &O, Function *F, LoopInfo *LI,
}
}
-} // end anonymous namespace
-
-void Delinearization::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AU.addRequired<LoopInfoWrapperPass>();
- AU.addRequired<ScalarEvolutionWrapperPass>();
-}
-
-bool Delinearization::runOnFunction(Function &F) {
- this->F = &F;
- SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
- LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- return false;
-}
-
-void Delinearization::print(raw_ostream &O, const Module *) const {
- printDelinearization(O, F, LI, SE);
-}
-
+} // end anonymous namespace
+
+void Delinearization::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<LoopInfoWrapperPass>();
+ AU.addRequired<ScalarEvolutionWrapperPass>();
+}
+
+bool Delinearization::runOnFunction(Function &F) {
+ this->F = &F;
+ SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
+ LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
+ return false;
+}
+
+void Delinearization::print(raw_ostream &O, const Module *) const {
+ printDelinearization(O, F, LI, SE);
+}
+
char Delinearization::ID = 0;
static const char delinearization_name[] = "Delinearization";
INITIALIZE_PASS_BEGIN(Delinearization, DL_NAME, delinearization_name, true,
@@ -135,12 +135,12 @@ INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_END(Delinearization, DL_NAME, delinearization_name, true, true)
FunctionPass *llvm::createDelinearizationPass() { return new Delinearization; }
-
-DelinearizationPrinterPass::DelinearizationPrinterPass(raw_ostream &OS)
- : OS(OS) {}
-PreservedAnalyses DelinearizationPrinterPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- printDelinearization(OS, &F, &AM.getResult<LoopAnalysis>(F),
- &AM.getResult<ScalarEvolutionAnalysis>(F));
- return PreservedAnalyses::all();
-}
+
+DelinearizationPrinterPass::DelinearizationPrinterPass(raw_ostream &OS)
+ : OS(OS) {}
+PreservedAnalyses DelinearizationPrinterPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ printDelinearization(OS, &F, &AM.getResult<LoopAnalysis>(F),
+ &AM.getResult<ScalarEvolutionAnalysis>(F));
+ return PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Analysis/DemandedBits.cpp b/contrib/libs/llvm12/lib/Analysis/DemandedBits.cpp
index ce17c01829..dd11b0b02b 100644
--- a/contrib/libs/llvm12/lib/Analysis/DemandedBits.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/DemandedBits.cpp
@@ -80,7 +80,7 @@ void DemandedBitsWrapperPass::print(raw_ostream &OS, const Module *M) const {
static bool isAlwaysLive(Instruction *I) {
return I->isTerminator() || isa<DbgInfoIntrinsic>(I) || I->isEHPad() ||
- I->mayHaveSideEffects() || !I->willReturn();
+ I->mayHaveSideEffects() || !I->willReturn();
}
void DemandedBits::determineLiveOperandBits(
@@ -115,7 +115,7 @@ void DemandedBits::determineLiveOperandBits(
default: break;
case Instruction::Call:
case Instruction::Invoke:
- if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(UserI)) {
+ if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(UserI)) {
switch (II->getIntrinsicID()) {
default: break;
case Intrinsic::bswap:
@@ -170,33 +170,33 @@ void DemandedBits::determineLiveOperandBits(
}
break;
}
- case Intrinsic::umax:
- case Intrinsic::umin:
- case Intrinsic::smax:
- case Intrinsic::smin:
- // If low bits of result are not demanded, they are also not demanded
- // for the min/max operands.
- AB = APInt::getBitsSetFrom(BitWidth, AOut.countTrailingZeros());
- break;
+ case Intrinsic::umax:
+ case Intrinsic::umin:
+ case Intrinsic::smax:
+ case Intrinsic::smin:
+ // If low bits of result are not demanded, they are also not demanded
+ // for the min/max operands.
+ AB = APInt::getBitsSetFrom(BitWidth, AOut.countTrailingZeros());
+ break;
}
- }
+ }
break;
case Instruction::Add:
- if (AOut.isMask()) {
- AB = AOut;
- } else {
- ComputeKnownBits(BitWidth, UserI->getOperand(0), UserI->getOperand(1));
- AB = determineLiveOperandBitsAdd(OperandNo, AOut, Known, Known2);
- }
- break;
+ if (AOut.isMask()) {
+ AB = AOut;
+ } else {
+ ComputeKnownBits(BitWidth, UserI->getOperand(0), UserI->getOperand(1));
+ AB = determineLiveOperandBitsAdd(OperandNo, AOut, Known, Known2);
+ }
+ break;
case Instruction::Sub:
- if (AOut.isMask()) {
- AB = AOut;
- } else {
- ComputeKnownBits(BitWidth, UserI->getOperand(0), UserI->getOperand(1));
- AB = determineLiveOperandBitsSub(OperandNo, AOut, Known, Known2);
- }
- break;
+ if (AOut.isMask()) {
+ AB = AOut;
+ } else {
+ ComputeKnownBits(BitWidth, UserI->getOperand(0), UserI->getOperand(1));
+ AB = determineLiveOperandBitsSub(OperandNo, AOut, Known, Known2);
+ }
+ break;
case Instruction::Mul:
// Find the highest live output bit. We don't need any more input
// bits than that (adds, and thus subtracts, ripple only to the
@@ -492,86 +492,86 @@ void DemandedBits::print(raw_ostream &OS) {
}
}
-static APInt determineLiveOperandBitsAddCarry(unsigned OperandNo,
- const APInt &AOut,
- const KnownBits &LHS,
- const KnownBits &RHS,
- bool CarryZero, bool CarryOne) {
- assert(!(CarryZero && CarryOne) &&
- "Carry can't be zero and one at the same time");
-
- // The following check should be done by the caller, as it also indicates
- // that LHS and RHS don't need to be computed.
- //
- // if (AOut.isMask())
- // return AOut;
-
- // Boundary bits' carry out is unaffected by their carry in.
- APInt Bound = (LHS.Zero & RHS.Zero) | (LHS.One & RHS.One);
-
- // First, the alive carry bits are determined from the alive output bits:
- // Let demand ripple to the right but only up to any set bit in Bound.
- // AOut = -1----
- // Bound = ----1-
- // ACarry&~AOut = --111-
- APInt RBound = Bound.reverseBits();
- APInt RAOut = AOut.reverseBits();
- APInt RProp = RAOut + (RAOut | ~RBound);
- APInt RACarry = RProp ^ ~RBound;
- APInt ACarry = RACarry.reverseBits();
-
- // Then, the alive input bits are determined from the alive carry bits:
- APInt NeededToMaintainCarryZero;
- APInt NeededToMaintainCarryOne;
- if (OperandNo == 0) {
- NeededToMaintainCarryZero = LHS.Zero | ~RHS.Zero;
- NeededToMaintainCarryOne = LHS.One | ~RHS.One;
- } else {
- NeededToMaintainCarryZero = RHS.Zero | ~LHS.Zero;
- NeededToMaintainCarryOne = RHS.One | ~LHS.One;
- }
-
- // As in computeForAddCarry
- APInt PossibleSumZero = ~LHS.Zero + ~RHS.Zero + !CarryZero;
- APInt PossibleSumOne = LHS.One + RHS.One + CarryOne;
-
- // The below is simplified from
- //
- // APInt CarryKnownZero = ~(PossibleSumZero ^ LHS.Zero ^ RHS.Zero);
- // APInt CarryKnownOne = PossibleSumOne ^ LHS.One ^ RHS.One;
- // APInt CarryUnknown = ~(CarryKnownZero | CarryKnownOne);
- //
- // APInt NeededToMaintainCarry =
- // (CarryKnownZero & NeededToMaintainCarryZero) |
- // (CarryKnownOne & NeededToMaintainCarryOne) |
- // CarryUnknown;
-
- APInt NeededToMaintainCarry = (~PossibleSumZero | NeededToMaintainCarryZero) &
- (PossibleSumOne | NeededToMaintainCarryOne);
-
- APInt AB = AOut | (ACarry & NeededToMaintainCarry);
- return AB;
-}
-
-APInt DemandedBits::determineLiveOperandBitsAdd(unsigned OperandNo,
- const APInt &AOut,
- const KnownBits &LHS,
- const KnownBits &RHS) {
- return determineLiveOperandBitsAddCarry(OperandNo, AOut, LHS, RHS, true,
- false);
-}
-
-APInt DemandedBits::determineLiveOperandBitsSub(unsigned OperandNo,
- const APInt &AOut,
- const KnownBits &LHS,
- const KnownBits &RHS) {
- KnownBits NRHS;
- NRHS.Zero = RHS.One;
- NRHS.One = RHS.Zero;
- return determineLiveOperandBitsAddCarry(OperandNo, AOut, LHS, NRHS, false,
- true);
-}
-
+static APInt determineLiveOperandBitsAddCarry(unsigned OperandNo,
+ const APInt &AOut,
+ const KnownBits &LHS,
+ const KnownBits &RHS,
+ bool CarryZero, bool CarryOne) {
+ assert(!(CarryZero && CarryOne) &&
+ "Carry can't be zero and one at the same time");
+
+ // The following check should be done by the caller, as it also indicates
+ // that LHS and RHS don't need to be computed.
+ //
+ // if (AOut.isMask())
+ // return AOut;
+
+ // Boundary bits' carry out is unaffected by their carry in.
+ APInt Bound = (LHS.Zero & RHS.Zero) | (LHS.One & RHS.One);
+
+ // First, the alive carry bits are determined from the alive output bits:
+ // Let demand ripple to the right but only up to any set bit in Bound.
+ // AOut = -1----
+ // Bound = ----1-
+ // ACarry&~AOut = --111-
+ APInt RBound = Bound.reverseBits();
+ APInt RAOut = AOut.reverseBits();
+ APInt RProp = RAOut + (RAOut | ~RBound);
+ APInt RACarry = RProp ^ ~RBound;
+ APInt ACarry = RACarry.reverseBits();
+
+ // Then, the alive input bits are determined from the alive carry bits:
+ APInt NeededToMaintainCarryZero;
+ APInt NeededToMaintainCarryOne;
+ if (OperandNo == 0) {
+ NeededToMaintainCarryZero = LHS.Zero | ~RHS.Zero;
+ NeededToMaintainCarryOne = LHS.One | ~RHS.One;
+ } else {
+ NeededToMaintainCarryZero = RHS.Zero | ~LHS.Zero;
+ NeededToMaintainCarryOne = RHS.One | ~LHS.One;
+ }
+
+ // As in computeForAddCarry
+ APInt PossibleSumZero = ~LHS.Zero + ~RHS.Zero + !CarryZero;
+ APInt PossibleSumOne = LHS.One + RHS.One + CarryOne;
+
+ // The below is simplified from
+ //
+ // APInt CarryKnownZero = ~(PossibleSumZero ^ LHS.Zero ^ RHS.Zero);
+ // APInt CarryKnownOne = PossibleSumOne ^ LHS.One ^ RHS.One;
+ // APInt CarryUnknown = ~(CarryKnownZero | CarryKnownOne);
+ //
+ // APInt NeededToMaintainCarry =
+ // (CarryKnownZero & NeededToMaintainCarryZero) |
+ // (CarryKnownOne & NeededToMaintainCarryOne) |
+ // CarryUnknown;
+
+ APInt NeededToMaintainCarry = (~PossibleSumZero | NeededToMaintainCarryZero) &
+ (PossibleSumOne | NeededToMaintainCarryOne);
+
+ APInt AB = AOut | (ACarry & NeededToMaintainCarry);
+ return AB;
+}
+
+APInt DemandedBits::determineLiveOperandBitsAdd(unsigned OperandNo,
+ const APInt &AOut,
+ const KnownBits &LHS,
+ const KnownBits &RHS) {
+ return determineLiveOperandBitsAddCarry(OperandNo, AOut, LHS, RHS, true,
+ false);
+}
+
+APInt DemandedBits::determineLiveOperandBitsSub(unsigned OperandNo,
+ const APInt &AOut,
+ const KnownBits &LHS,
+ const KnownBits &RHS) {
+ KnownBits NRHS;
+ NRHS.Zero = RHS.One;
+ NRHS.One = RHS.Zero;
+ return determineLiveOperandBitsAddCarry(OperandNo, AOut, LHS, NRHS, false,
+ true);
+}
+
FunctionPass *llvm::createDemandedBitsWrapperPass() {
return new DemandedBitsWrapperPass();
}
diff --git a/contrib/libs/llvm12/lib/Analysis/DependenceAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/DependenceAnalysis.cpp
index b637ea7665..c2c61131e4 100644
--- a/contrib/libs/llvm12/lib/Analysis/DependenceAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/DependenceAnalysis.cpp
@@ -653,16 +653,16 @@ static AliasResult underlyingObjectsAlias(AAResults *AA,
const MemoryLocation &LocB) {
// Check the original locations (minus size) for noalias, which can happen for
// tbaa, incompatible underlying object locations, etc.
- MemoryLocation LocAS =
- MemoryLocation::getBeforeOrAfter(LocA.Ptr, LocA.AATags);
- MemoryLocation LocBS =
- MemoryLocation::getBeforeOrAfter(LocB.Ptr, LocB.AATags);
+ MemoryLocation LocAS =
+ MemoryLocation::getBeforeOrAfter(LocA.Ptr, LocA.AATags);
+ MemoryLocation LocBS =
+ MemoryLocation::getBeforeOrAfter(LocB.Ptr, LocB.AATags);
if (AA->alias(LocAS, LocBS) == NoAlias)
return NoAlias;
// Check the underlying objects are the same
- const Value *AObj = getUnderlyingObject(LocA.Ptr);
- const Value *BObj = getUnderlyingObject(LocB.Ptr);
+ const Value *AObj = getUnderlyingObject(LocA.Ptr);
+ const Value *BObj = getUnderlyingObject(LocB.Ptr);
// If the underlying objects are the same, they must alias
if (AObj == BObj)
@@ -873,8 +873,8 @@ void DependenceInfo::removeMatchingExtensions(Subscript *Pair) {
const SCEV *Dst = Pair->Dst;
if ((isa<SCEVZeroExtendExpr>(Src) && isa<SCEVZeroExtendExpr>(Dst)) ||
(isa<SCEVSignExtendExpr>(Src) && isa<SCEVSignExtendExpr>(Dst))) {
- const SCEVIntegralCastExpr *SrcCast = cast<SCEVIntegralCastExpr>(Src);
- const SCEVIntegralCastExpr *DstCast = cast<SCEVIntegralCastExpr>(Dst);
+ const SCEVIntegralCastExpr *SrcCast = cast<SCEVIntegralCastExpr>(Src);
+ const SCEVIntegralCastExpr *DstCast = cast<SCEVIntegralCastExpr>(Dst);
const SCEV *SrcCastOp = SrcCast->getOperand();
const SCEV *DstCastOp = DstCast->getOperand();
if (SrcCastOp->getType() == DstCastOp->getType()) {
@@ -971,8 +971,8 @@ bool DependenceInfo::isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *X,
isa<SCEVSignExtendExpr>(Y)) ||
(isa<SCEVZeroExtendExpr>(X) &&
isa<SCEVZeroExtendExpr>(Y))) {
- const SCEVIntegralCastExpr *CX = cast<SCEVIntegralCastExpr>(X);
- const SCEVIntegralCastExpr *CY = cast<SCEVIntegralCastExpr>(Y);
+ const SCEVIntegralCastExpr *CX = cast<SCEVIntegralCastExpr>(X);
+ const SCEVIntegralCastExpr *CY = cast<SCEVIntegralCastExpr>(Y);
const SCEV *Xop = CX->getOperand();
const SCEV *Yop = CY->getOperand();
if (Xop->getType() == Yop->getType()) {
@@ -1531,18 +1531,18 @@ bool DependenceInfo::exactSIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
// test(BM/G, LM-X) and test(-BM/G, X-UM)
APInt TMUL = BM.sdiv(G);
if (TMUL.sgt(0)) {
- TL = APIntOps::smax(TL, ceilingOfQuotient(-X, TMUL));
+ TL = APIntOps::smax(TL, ceilingOfQuotient(-X, TMUL));
LLVM_DEBUG(dbgs() << "\t TL = " << TL << "\n");
if (UMvalid) {
- TU = APIntOps::smin(TU, floorOfQuotient(UM - X, TMUL));
+ TU = APIntOps::smin(TU, floorOfQuotient(UM - X, TMUL));
LLVM_DEBUG(dbgs() << "\t TU = " << TU << "\n");
}
}
else {
- TU = APIntOps::smin(TU, floorOfQuotient(-X, TMUL));
+ TU = APIntOps::smin(TU, floorOfQuotient(-X, TMUL));
LLVM_DEBUG(dbgs() << "\t TU = " << TU << "\n");
if (UMvalid) {
- TL = APIntOps::smax(TL, ceilingOfQuotient(UM - X, TMUL));
+ TL = APIntOps::smax(TL, ceilingOfQuotient(UM - X, TMUL));
LLVM_DEBUG(dbgs() << "\t TL = " << TL << "\n");
}
}
@@ -1550,18 +1550,18 @@ bool DependenceInfo::exactSIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
// test(AM/G, LM-Y) and test(-AM/G, Y-UM)
TMUL = AM.sdiv(G);
if (TMUL.sgt(0)) {
- TL = APIntOps::smax(TL, ceilingOfQuotient(-Y, TMUL));
+ TL = APIntOps::smax(TL, ceilingOfQuotient(-Y, TMUL));
LLVM_DEBUG(dbgs() << "\t TL = " << TL << "\n");
if (UMvalid) {
- TU = APIntOps::smin(TU, floorOfQuotient(UM - Y, TMUL));
+ TU = APIntOps::smin(TU, floorOfQuotient(UM - Y, TMUL));
LLVM_DEBUG(dbgs() << "\t TU = " << TU << "\n");
}
}
else {
- TU = APIntOps::smin(TU, floorOfQuotient(-Y, TMUL));
+ TU = APIntOps::smin(TU, floorOfQuotient(-Y, TMUL));
LLVM_DEBUG(dbgs() << "\t TU = " << TU << "\n");
if (UMvalid) {
- TL = APIntOps::smax(TL, ceilingOfQuotient(UM - Y, TMUL));
+ TL = APIntOps::smax(TL, ceilingOfQuotient(UM - Y, TMUL));
LLVM_DEBUG(dbgs() << "\t TL = " << TL << "\n");
}
}
@@ -1580,11 +1580,11 @@ bool DependenceInfo::exactSIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
LLVM_DEBUG(dbgs() << "\t exploring LT direction\n");
TMUL = AM - BM;
if (TMUL.sgt(0)) {
- TL = APIntOps::smax(TL, ceilingOfQuotient(X - Y + 1, TMUL));
+ TL = APIntOps::smax(TL, ceilingOfQuotient(X - Y + 1, TMUL));
LLVM_DEBUG(dbgs() << "\t\t TL = " << TL << "\n");
}
else {
- TU = APIntOps::smin(TU, floorOfQuotient(X - Y + 1, TMUL));
+ TU = APIntOps::smin(TU, floorOfQuotient(X - Y + 1, TMUL));
LLVM_DEBUG(dbgs() << "\t\t TU = " << TU << "\n");
}
if (TL.sle(TU)) {
@@ -1597,20 +1597,20 @@ bool DependenceInfo::exactSIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
TL = SaveTL;
LLVM_DEBUG(dbgs() << "\t exploring EQ direction\n");
if (TMUL.sgt(0)) {
- TL = APIntOps::smax(TL, ceilingOfQuotient(X - Y, TMUL));
+ TL = APIntOps::smax(TL, ceilingOfQuotient(X - Y, TMUL));
LLVM_DEBUG(dbgs() << "\t\t TL = " << TL << "\n");
}
else {
- TU = APIntOps::smin(TU, floorOfQuotient(X - Y, TMUL));
+ TU = APIntOps::smin(TU, floorOfQuotient(X - Y, TMUL));
LLVM_DEBUG(dbgs() << "\t\t TU = " << TU << "\n");
}
TMUL = BM - AM;
if (TMUL.sgt(0)) {
- TL = APIntOps::smax(TL, ceilingOfQuotient(Y - X, TMUL));
+ TL = APIntOps::smax(TL, ceilingOfQuotient(Y - X, TMUL));
LLVM_DEBUG(dbgs() << "\t\t TL = " << TL << "\n");
}
else {
- TU = APIntOps::smin(TU, floorOfQuotient(Y - X, TMUL));
+ TU = APIntOps::smin(TU, floorOfQuotient(Y - X, TMUL));
LLVM_DEBUG(dbgs() << "\t\t TU = " << TU << "\n");
}
if (TL.sle(TU)) {
@@ -1623,11 +1623,11 @@ bool DependenceInfo::exactSIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
TL = SaveTL;
LLVM_DEBUG(dbgs() << "\t exploring GT direction\n");
if (TMUL.sgt(0)) {
- TL = APIntOps::smax(TL, ceilingOfQuotient(Y - X + 1, TMUL));
+ TL = APIntOps::smax(TL, ceilingOfQuotient(Y - X + 1, TMUL));
LLVM_DEBUG(dbgs() << "\t\t TL = " << TL << "\n");
}
else {
- TU = APIntOps::smin(TU, floorOfQuotient(Y - X + 1, TMUL));
+ TU = APIntOps::smin(TU, floorOfQuotient(Y - X + 1, TMUL));
LLVM_DEBUG(dbgs() << "\t\t TU = " << TU << "\n");
}
if (TL.sle(TU)) {
@@ -1939,18 +1939,18 @@ bool DependenceInfo::exactRDIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
// test(BM/G, LM-X) and test(-BM/G, X-UM)
APInt TMUL = BM.sdiv(G);
if (TMUL.sgt(0)) {
- TL = APIntOps::smax(TL, ceilingOfQuotient(-X, TMUL));
+ TL = APIntOps::smax(TL, ceilingOfQuotient(-X, TMUL));
LLVM_DEBUG(dbgs() << "\t TL = " << TL << "\n");
if (SrcUMvalid) {
- TU = APIntOps::smin(TU, floorOfQuotient(SrcUM - X, TMUL));
+ TU = APIntOps::smin(TU, floorOfQuotient(SrcUM - X, TMUL));
LLVM_DEBUG(dbgs() << "\t TU = " << TU << "\n");
}
}
else {
- TU = APIntOps::smin(TU, floorOfQuotient(-X, TMUL));
+ TU = APIntOps::smin(TU, floorOfQuotient(-X, TMUL));
LLVM_DEBUG(dbgs() << "\t TU = " << TU << "\n");
if (SrcUMvalid) {
- TL = APIntOps::smax(TL, ceilingOfQuotient(SrcUM - X, TMUL));
+ TL = APIntOps::smax(TL, ceilingOfQuotient(SrcUM - X, TMUL));
LLVM_DEBUG(dbgs() << "\t TL = " << TL << "\n");
}
}
@@ -1958,18 +1958,18 @@ bool DependenceInfo::exactRDIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
// test(AM/G, LM-Y) and test(-AM/G, Y-UM)
TMUL = AM.sdiv(G);
if (TMUL.sgt(0)) {
- TL = APIntOps::smax(TL, ceilingOfQuotient(-Y, TMUL));
+ TL = APIntOps::smax(TL, ceilingOfQuotient(-Y, TMUL));
LLVM_DEBUG(dbgs() << "\t TL = " << TL << "\n");
if (DstUMvalid) {
- TU = APIntOps::smin(TU, floorOfQuotient(DstUM - Y, TMUL));
+ TU = APIntOps::smin(TU, floorOfQuotient(DstUM - Y, TMUL));
LLVM_DEBUG(dbgs() << "\t TU = " << TU << "\n");
}
}
else {
- TU = APIntOps::smin(TU, floorOfQuotient(-Y, TMUL));
+ TU = APIntOps::smin(TU, floorOfQuotient(-Y, TMUL));
LLVM_DEBUG(dbgs() << "\t TU = " << TU << "\n");
if (DstUMvalid) {
- TL = APIntOps::smax(TL, ceilingOfQuotient(DstUM - Y, TMUL));
+ TL = APIntOps::smax(TL, ceilingOfQuotient(DstUM - Y, TMUL));
LLVM_DEBUG(dbgs() << "\t TL = " << TL << "\n");
}
}
diff --git a/contrib/libs/llvm12/lib/Analysis/DependenceGraphBuilder.cpp b/contrib/libs/llvm12/lib/Analysis/DependenceGraphBuilder.cpp
index 0851a5d98c..6b90db4baf 100644
--- a/contrib/libs/llvm12/lib/Analysis/DependenceGraphBuilder.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/DependenceGraphBuilder.cpp
@@ -140,74 +140,74 @@ template <class G> void AbstractDependenceGraphBuilder<G>::createPiBlocks() {
if (*N == PiNode || NodesInSCC.count(N))
continue;
- enum Direction {
- Incoming, // Incoming edges to the SCC
- Outgoing, // Edges going ot of the SCC
- DirectionCount // To make the enum usable as an array index.
- };
-
- // Use these flags to help us avoid creating redundant edges. If there
- // are more than one edges from an outside node to inside nodes, we only
- // keep one edge from that node to the pi-block node. Similarly, if
- // there are more than one edges from inside nodes to an outside node,
- // we only keep one edge from the pi-block node to the outside node.
- // There is a flag defined for each direction (incoming vs outgoing) and
- // for each type of edge supported, using a two-dimensional boolean
- // array.
- using EdgeKind = typename EdgeType::EdgeKind;
- EnumeratedArray<bool, EdgeKind> EdgeAlreadyCreated[DirectionCount]{false,
- false};
-
- auto createEdgeOfKind = [this](NodeType &Src, NodeType &Dst,
- const EdgeKind K) {
- switch (K) {
- case EdgeKind::RegisterDefUse:
- createDefUseEdge(Src, Dst);
- break;
- case EdgeKind::MemoryDependence:
- createMemoryEdge(Src, Dst);
- break;
- case EdgeKind::Rooted:
- createRootedEdge(Src, Dst);
- break;
- default:
- llvm_unreachable("Unsupported type of edge.");
- }
- };
-
- auto reconnectEdges = [&](NodeType *Src, NodeType *Dst, NodeType *New,
- const Direction Dir) {
- if (!Src->hasEdgeTo(*Dst))
- return;
- LLVM_DEBUG(
- dbgs() << "reconnecting("
- << (Dir == Direction::Incoming ? "incoming)" : "outgoing)")
- << ":\nSrc:" << *Src << "\nDst:" << *Dst << "\nNew:" << *New
- << "\n");
- assert((Dir == Direction::Incoming || Dir == Direction::Outgoing) &&
- "Invalid direction.");
-
- SmallVector<EdgeType *, 10> EL;
- Src->findEdgesTo(*Dst, EL);
- for (EdgeType *OldEdge : EL) {
- EdgeKind Kind = OldEdge->getKind();
- if (!EdgeAlreadyCreated[Dir][Kind]) {
- if (Dir == Direction::Incoming) {
- createEdgeOfKind(*Src, *New, Kind);
- LLVM_DEBUG(dbgs() << "created edge from Src to New.\n");
- } else if (Dir == Direction::Outgoing) {
- createEdgeOfKind(*New, *Dst, Kind);
- LLVM_DEBUG(dbgs() << "created edge from New to Dst.\n");
+ enum Direction {
+ Incoming, // Incoming edges to the SCC
+ Outgoing, // Edges going ot of the SCC
+ DirectionCount // To make the enum usable as an array index.
+ };
+
+ // Use these flags to help us avoid creating redundant edges. If there
+ // are more than one edges from an outside node to inside nodes, we only
+ // keep one edge from that node to the pi-block node. Similarly, if
+ // there are more than one edges from inside nodes to an outside node,
+ // we only keep one edge from the pi-block node to the outside node.
+ // There is a flag defined for each direction (incoming vs outgoing) and
+ // for each type of edge supported, using a two-dimensional boolean
+ // array.
+ using EdgeKind = typename EdgeType::EdgeKind;
+ EnumeratedArray<bool, EdgeKind> EdgeAlreadyCreated[DirectionCount]{false,
+ false};
+
+ auto createEdgeOfKind = [this](NodeType &Src, NodeType &Dst,
+ const EdgeKind K) {
+ switch (K) {
+ case EdgeKind::RegisterDefUse:
+ createDefUseEdge(Src, Dst);
+ break;
+ case EdgeKind::MemoryDependence:
+ createMemoryEdge(Src, Dst);
+ break;
+ case EdgeKind::Rooted:
+ createRootedEdge(Src, Dst);
+ break;
+ default:
+ llvm_unreachable("Unsupported type of edge.");
+ }
+ };
+
+ auto reconnectEdges = [&](NodeType *Src, NodeType *Dst, NodeType *New,
+ const Direction Dir) {
+ if (!Src->hasEdgeTo(*Dst))
+ return;
+ LLVM_DEBUG(
+ dbgs() << "reconnecting("
+ << (Dir == Direction::Incoming ? "incoming)" : "outgoing)")
+ << ":\nSrc:" << *Src << "\nDst:" << *Dst << "\nNew:" << *New
+ << "\n");
+ assert((Dir == Direction::Incoming || Dir == Direction::Outgoing) &&
+ "Invalid direction.");
+
+ SmallVector<EdgeType *, 10> EL;
+ Src->findEdgesTo(*Dst, EL);
+ for (EdgeType *OldEdge : EL) {
+ EdgeKind Kind = OldEdge->getKind();
+ if (!EdgeAlreadyCreated[Dir][Kind]) {
+ if (Dir == Direction::Incoming) {
+ createEdgeOfKind(*Src, *New, Kind);
+ LLVM_DEBUG(dbgs() << "created edge from Src to New.\n");
+ } else if (Dir == Direction::Outgoing) {
+ createEdgeOfKind(*New, *Dst, Kind);
+ LLVM_DEBUG(dbgs() << "created edge from New to Dst.\n");
}
- EdgeAlreadyCreated[Dir][Kind] = true;
+ EdgeAlreadyCreated[Dir][Kind] = true;
}
- Src->removeEdge(*OldEdge);
- destroyEdge(*OldEdge);
- LLVM_DEBUG(dbgs() << "removed old edge between Src and Dst.\n\n");
- }
- };
+ Src->removeEdge(*OldEdge);
+ destroyEdge(*OldEdge);
+ LLVM_DEBUG(dbgs() << "removed old edge between Src and Dst.\n\n");
+ }
+ };
- for (NodeType *SCCNode : NL) {
+ for (NodeType *SCCNode : NL) {
// Process incoming edges incident to the pi-block node.
reconnectEdges(N, SCCNode, &PiNode, Direction::Incoming);
@@ -491,14 +491,14 @@ void AbstractDependenceGraphBuilder<G>::sortNodesTopologically() {
// Put members of the pi-block right after the pi-block itself, for
// convenience.
const NodeListType &PiBlockMembers = getNodesInPiBlock(*N);
- llvm::append_range(NodesInPO, PiBlockMembers);
+ llvm::append_range(NodesInPO, PiBlockMembers);
}
NodesInPO.push_back(N);
}
size_t OldSize = Graph.Nodes.size();
Graph.Nodes.clear();
- append_range(Graph.Nodes, reverse(NodesInPO));
+ append_range(Graph.Nodes, reverse(NodesInPO));
if (Graph.Nodes.size() != OldSize)
assert(false &&
"Expected the number of nodes to stay the same after the sort");
diff --git a/contrib/libs/llvm12/lib/Analysis/DevelopmentModeInlineAdvisor.cpp b/contrib/libs/llvm12/lib/Analysis/DevelopmentModeInlineAdvisor.cpp
index 728c83a6d6..e138e82c8b 100644
--- a/contrib/libs/llvm12/lib/Analysis/DevelopmentModeInlineAdvisor.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/DevelopmentModeInlineAdvisor.cpp
@@ -1,531 +1,531 @@
-//===- DevelopmentModeInlineAdvisor.cpp - runtime-loadable model runner --===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements a model runner using Tensorflow C APIs, allowing the
-// loading of a model from a command line option.
-//
-//===----------------------------------------------------------------------===//
-#include "llvm/Config/config.h"
-#if defined(LLVM_HAVE_TF_API)
-
-#include "llvm/Analysis/CallGraph.h"
-#include "llvm/Analysis/InlineSizeEstimatorAnalysis.h"
-#include "llvm/Analysis/MLInlineAdvisor.h"
-#include "llvm/Analysis/Utils/TFUtils.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/ManagedStatic.h"
-
-#include <vector>
-
-using namespace llvm;
-
-static cl::opt<std::string> TrainingLog(
- "training-log", cl::Hidden,
- cl::desc("Path where the development - mode inlining log is saved."));
-
-static cl::opt<std::string> TFModelUnderTrainingPath(
- "ml-inliner-model-under-training", cl::Hidden,
- cl::desc(R"(Path to SavedModel from the previous training iteration.
-The directory is also expected to contain a JSON specification of the
-outputs expected to be logged, where the first entry must be the
-inlining decision. The file containing the specification should be
-called output_spec.json. The expected JSON value is an array of
-dictionaries. Each dictionary should have 2 keys:
-
-- "tensor_spec, followed by the TensorSpec description of the
-output; and
-- "logging_name", a string indicating the name to use when
-logging the output values.
-
-Example:
-[
- {
- "logging_name" : "some_name",
- "tensor_spec" : {
- "name" : "model_name",
- "port" : 0,
- "shape" : [2, 3],
- "type" : "float"
- }
- }
-]
-
-The first value must always correspond to the decision.)"));
-
-static cl::opt<std::string> TFOutputSpecOverride(
- "ml-inliner-output-spec-override", cl::Hidden,
- cl::desc("Override the path to the output spec json file. See "
- "-ml-inliner-model-under-training documentation for the "
- "specification of that file."));
-
-static cl::opt<std::string> TFFeedPrefix("ml-inliner-trained-model-feed-prefix",
- cl::Hidden, cl::init("action_"),
- cl::desc("Prefix for feature names."));
-
-namespace {
-/// An InlineEvent, used by TrainingLogger.
-struct InlineEvent {
- /// What the default policy's decision would have been.
- int64_t DefaultDecision = 0;
-
- /// What we advised. When training off the default policy, this is the same as
- /// DefaultDecision.
- int64_t AdvisedDecision = 0;
-
- /// What actually happened. This would be 'false' in the case of an inline
- /// error, even if AdvisedDecision were true, otherwise it agrees with
- /// AdvisedDecision.
- bool Effect = false;
-
- /// What the change in size was: size_after - size_before
- int64_t Reward = 0;
-};
-
-/// Collect data we may use for training a model, and write it as a textual
-/// Tensorflow SequenceExample
-/// (https://www.tensorflow.org/api_docs/python/tf/train/SequenceExample)
-/// protobuf (https://developers.google.com/protocol-buffers).
-/// Because this is a protobuf, we cannot just stream the events as they come.
-/// Internally, TrainingLogger stores data in column-major format, because that
-/// lines up with how TF SequenceExample represents it.
-class ModelUnderTrainingRunner;
-class TrainingLogger final {
-public:
- TrainingLogger(StringRef LogFileName, const ModelUnderTrainingRunner *MUTR);
-
- /// Log one inlining event.
- void logInlineEvent(const InlineEvent &Event,
- const MLModelRunner &ModelRunner);
-
- /// Print the stored tensors.
- void print();
-
-private:
- StringRef LogFileName;
- const ModelUnderTrainingRunner *const MUTR;
- std::unique_ptr<Logger> L;
- std::vector<bool> Effects;
- /// There's at least one output. We'll set this to a different value if MUTR
- /// is avaliable.
- size_t OutputCount = 1;
- /// Set these 2 clearly OOB, to make sure we set them later.
- size_t DefaultDecisionPos = std::numeric_limits<size_t>::max();
- size_t DecisionPos = std::numeric_limits<size_t>::max();
-};
-
-/// An extension of the MLInlineAdvisor for the 'development' mode, targeting
-/// the offline training scenario. Note that training happens outside of the
-/// compiler, this facility is concerned with producing training data ("logs").
-/// This InlineAdvisor can operate in the following modes:
-///
-/// 1) collect logs for the default policy. This is useful for bootstrapping
-/// training, which will be considerably faster by starting from a reasonable
-/// policy.
-///
-/// 2) collect logs for the ML policy, using a model from a previous
-/// training. Potentially, that model uses internally some small random
-/// perturbation of its weights, to induce exploration (setting this up is the
-/// responsibility of the training algorithm). The logs would then be used to
-/// retrain and improve on this model.
-///
-/// 3) use the provided model, with no logging. This is useful for end to end
-/// validation - the model, in this case, is a release candidate and shouldn't
-/// have random perturbations. It is a convenience feature: rather than needing
-/// to take the release candidate model and compile it in 'release' mode,
-/// validate it, then potentially discard it, it's easier to just pass the model
-/// to the compiler, albeit compilation would be slower, as a one-off. Once the
-/// model behaves satisfactorily, it can be compiled AOT, for efficiency, in
-/// release mode. The expectation is that a well-trained model provides a good
-/// policy over a sufficiently diverse codebase, over many changes (i.e.
-/// training happens seldom).
-class DevelopmentModeMLInlineAdvisor : public MLInlineAdvisor {
-public:
- DevelopmentModeMLInlineAdvisor(
- Module &M, ModuleAnalysisManager &MAM,
- std::unique_ptr<MLModelRunner> ModelRunner,
- std::function<bool(CallBase &)> GetDefaultAdvice, bool IsDoingInference,
- std::unique_ptr<TrainingLogger> Logger);
-
- size_t getTotalSizeEstimate();
-
- virtual ~DevelopmentModeMLInlineAdvisor();
- void updateNativeSizeEstimate(int64_t Change) {
- *CurrentNativeSize += Change;
- }
- void resetNativeSize(Function *F) {
- FAM.invalidate<InlineSizeEstimatorAnalysis>(*F);
- }
-
- std::unique_ptr<MLInlineAdvice>
- getAdviceFromModel(CallBase &CB, OptimizationRemarkEmitter &ORE) override;
-
- Optional<size_t> getNativeSizeEstimate(const Function &F) const;
-
-private:
- bool isLogging() const { return !!Logger; }
- std::unique_ptr<MLInlineAdvice> getMandatoryAdviceImpl(CallBase &CB) override;
-
- std::function<bool(CallBase &)> GetDefaultAdvice;
- const bool IsDoingInference;
- std::unique_ptr<TrainingLogger> Logger;
-
- const Optional<int32_t> InitialNativeSize;
- Optional<int32_t> CurrentNativeSize;
-};
-
-/// A variant of MLInlineAdvice that tracks all non-trivial inlining
-/// decisions, for training/logging.
-class LoggingMLInlineAdvice : public MLInlineAdvice {
-public:
- LoggingMLInlineAdvice(DevelopmentModeMLInlineAdvisor *Advisor, CallBase &CB,
- OptimizationRemarkEmitter &ORE, bool Recommendation,
- TrainingLogger &Logger,
- Optional<size_t> CallerSizeEstimateBefore,
- Optional<size_t> CalleeSizeEstimateBefore,
- bool DefaultDecision, bool Mandatory = false)
- : MLInlineAdvice(Advisor, CB, ORE, Recommendation), Logger(Logger),
- CallerSizeEstimateBefore(CallerSizeEstimateBefore),
- CalleeSizeEstimateBefore(CalleeSizeEstimateBefore),
- DefaultDecision(DefaultDecision), Mandatory(Mandatory) {}
-
- virtual ~LoggingMLInlineAdvice() = default;
-
-private:
- DevelopmentModeMLInlineAdvisor *getAdvisor() const {
- return static_cast<DevelopmentModeMLInlineAdvisor *>(Advisor);
- }
- void recordInliningImpl() override {
- MLInlineAdvice::recordInliningImpl();
- getAdvisor()->resetNativeSize(Caller);
- int Reward = std::numeric_limits<int>::max();
- if (InlineSizeEstimatorAnalysis::isEvaluatorRequested() &&
- !getAdvisor()->isForcedToStop()) {
- int NativeSizeAfter = *getAdvisor()->getNativeSizeEstimate(*Caller) +
- *CalleeSizeEstimateBefore;
- Reward = NativeSizeAfter -
- (*CallerSizeEstimateBefore + *CalleeSizeEstimateBefore);
- getAdvisor()->updateNativeSizeEstimate(Reward);
- }
- log(Reward, /*Success=*/true);
- }
-
- void recordInliningWithCalleeDeletedImpl() override {
- MLInlineAdvice::recordInliningWithCalleeDeletedImpl();
- getAdvisor()->resetNativeSize(Caller);
- if (InlineSizeEstimatorAnalysis::isEvaluatorRequested() &&
- !getAdvisor()->isForcedToStop()) {
- int NativeSizeAfter = *getAdvisor()->getNativeSizeEstimate(*Caller);
- int Reward = NativeSizeAfter -
- (*CallerSizeEstimateBefore + *CalleeSizeEstimateBefore);
- getAdvisor()->updateNativeSizeEstimate(Reward);
- log(Reward, /*Success=*/true);
- }
- }
-
- void recordUnsuccessfulInliningImpl(const InlineResult &Result) override {
- MLInlineAdvice::recordUnsuccessfulInliningImpl(Result);
- log(NoReward, /*Success=*/false);
- }
-
- void recordUnattemptedInliningImpl() override {
- MLInlineAdvice::recordUnattemptedInliningImpl();
- log(NoReward, /*Success=*/false);
- }
-
- void log(int64_t Reward, bool Success) {
- if (Mandatory)
- return;
- InlineEvent Event;
- Event.AdvisedDecision = isInliningRecommended();
- Event.DefaultDecision = DefaultDecision;
- Event.Effect = Success;
- Event.Reward = Reward;
- Logger.logInlineEvent(Event, getAdvisor()->getModelRunner());
- }
-
- static const int64_t NoReward = 0;
- TrainingLogger &Logger;
- const Optional<size_t> CallerSizeEstimateBefore;
- const Optional<size_t> CalleeSizeEstimateBefore;
- const int64_t DefaultDecision;
- const int64_t Mandatory;
-};
-
-/// A pseudo model runner. We use it to store feature values when collecting
-/// logs for the default policy, but never ask it to 'run'.
-class NoInferenceModelRunner : public MLModelRunner {
-public:
- NoInferenceModelRunner(LLVMContext &Ctx)
- : MLModelRunner(Ctx), Features(NumberOfFeatures) {}
- void setFeature(FeatureIndex Index, int64_t Value) override {
- Features[static_cast<int>(Index)] = Value;
- }
-
- int64_t getFeature(int Index) const override { return Features[Index]; }
- bool run() override {
- llvm_unreachable("We shouldn't call run on this model runner.");
- }
-
-private:
- InlineFeatures Features;
-};
-
-/// ModelUnderTrainingRunner - training mode implementation. It uses TF C APIs
-/// to dynamically load and evaluate a TF SavedModel
-/// (https://www.tensorflow.org/guide/saved_model). Runtime performance is
-/// sacrificed for ease of use while training.
-class ModelUnderTrainingRunner final : public MLModelRunner {
-public:
- ModelUnderTrainingRunner(LLVMContext &Ctx, const std::string &ModelPath);
-
- bool run() override;
-
- // Disallows copy and assign.
- ModelUnderTrainingRunner(const ModelUnderTrainingRunner &) = delete;
- ModelUnderTrainingRunner &
- operator=(const ModelUnderTrainingRunner &) = delete;
-
- void setFeature(FeatureIndex Index, int64_t Value) override;
- int64_t getFeature(int Index) const override;
- bool isValid() const { return !!Evaluator; }
-
- const std::vector<LoggedFeatureSpec> &outputLoggedFeatureSpecs() const {
- return OutputSpecs;
- }
-
- const Optional<TFModelEvaluator::EvaluationResult> &
- lastEvaluationResult() const {
- return LastEvaluationResult;
- }
-
-private:
- std::unique_ptr<TFModelEvaluator> Evaluator;
- std::vector<LoggedFeatureSpec> OutputSpecs;
- Optional<TFModelEvaluator::EvaluationResult> LastEvaluationResult;
-
- // The training framework needs some additional features.
- const std::vector<TensorSpec> TrainingOnlyFeatures{
- TensorSpec::createSpec<int64_t>(TFFeedPrefix + "inlining_default", {1}),
- TensorSpec::createSpec<float>(TFFeedPrefix + "discount", {1}),
- TensorSpec::createSpec<float>(TFFeedPrefix + "reward", {1}),
- TensorSpec::createSpec<int32_t>(TFFeedPrefix + "step_type", {1})};
-};
-} // namespace
-
-TrainingLogger::TrainingLogger(StringRef LogFileName,
- const ModelUnderTrainingRunner *MUTR)
- : LogFileName(LogFileName), MUTR(MUTR) {
- // The first output is the inlining decision.
- if (MUTR)
- OutputCount = MUTR->outputLoggedFeatureSpecs().size();
- std::vector<LoggedFeatureSpec> FT;
-
- for (size_t I = 0; I < NumberOfFeatures; ++I)
- FT.push_back(
- {TensorSpec::createSpec<int64_t>(FeatureNameMap.at(I), {1}), None});
- if (MUTR && MUTR->outputLoggedFeatureSpecs().size() > 1)
- append_range(FT, drop_begin(MUTR->outputLoggedFeatureSpecs()));
-
- DefaultDecisionPos = FT.size();
- FT.push_back(
- {TensorSpec::createSpec<int64_t>(DefaultDecisionName, {1}), None});
-
- DecisionPos = FT.size();
- FT.push_back({TensorSpec::createSpec<int64_t>(DecisionName, {1}), None});
-
- L = std::make_unique<Logger>(
- FT, TensorSpec::createSpec<int64_t>(RewardName, {1}),
- InlineSizeEstimatorAnalysis::isEvaluatorRequested());
-}
-
-/// Log one inlining event.
-void TrainingLogger::logInlineEvent(const InlineEvent &Event,
- const MLModelRunner &ModelRunner) {
- size_t CurrentFeature = 0;
- for (; CurrentFeature < NumberOfFeatures; ++CurrentFeature) {
- int64_t F = ModelRunner.getFeature(CurrentFeature);
- L->logTensorValue(CurrentFeature, &F);
- }
-
- for (size_t I = 1; I < OutputCount; ++I) {
- const auto &Result = *MUTR->lastEvaluationResult();
- auto &Spec = MUTR->outputLoggedFeatureSpecs()[I].Spec;
- const char *RawData =
- reinterpret_cast<const char *>(Result.getUntypedTensorValue(I));
- L->logTensorValue(CurrentFeature, RawData,
- Spec.getElementCount() * Spec.getElementByteSize());
- ++CurrentFeature;
- }
-
- assert(CurrentFeature == DefaultDecisionPos);
- L->logTensorValue(DefaultDecisionPos, &Event.DefaultDecision);
- L->logTensorValue(DecisionPos, &Event.AdvisedDecision);
- if (InlineSizeEstimatorAnalysis::isEvaluatorRequested())
- L->logReward(Event.Reward);
-
- // For debugging / later use
- Effects.push_back(Event.Effect);
-}
-
-void TrainingLogger::print() {
- std::error_code EC;
- raw_fd_ostream OutFile(LogFileName, EC);
- L->print(OutFile);
-}
-
-DevelopmentModeMLInlineAdvisor::DevelopmentModeMLInlineAdvisor(
- Module &M, ModuleAnalysisManager &MAM,
- std::unique_ptr<MLModelRunner> ModelRunner,
- std::function<bool(CallBase &)> GetDefaultAdvice, bool IsDoingInference,
- std::unique_ptr<TrainingLogger> Logger)
- : MLInlineAdvisor(M, MAM, std::move(ModelRunner)),
- GetDefaultAdvice(GetDefaultAdvice), IsDoingInference(IsDoingInference),
- Logger(std::move(Logger)),
- InitialNativeSize(isLogging() ? getTotalSizeEstimate() : 0),
- CurrentNativeSize(InitialNativeSize) {
- // We cannot have the case of neither inference nor logging.
- assert(IsDoingInference || isLogging());
-}
-
-DevelopmentModeMLInlineAdvisor::~DevelopmentModeMLInlineAdvisor() {
- if (isLogging())
- Logger->print();
-}
-
-Optional<size_t>
-DevelopmentModeMLInlineAdvisor::getNativeSizeEstimate(const Function &F) const {
- if (!InlineSizeEstimatorAnalysis::isEvaluatorRequested())
- return None;
- auto &R =
- FAM.getResult<InlineSizeEstimatorAnalysis>(const_cast<Function &>(F));
- if (!R) {
- F.getParent()->getContext().emitError(
- "Native size estimator is not present.");
- return 0;
- }
- return *R;
-}
-
-std::unique_ptr<MLInlineAdvice>
-DevelopmentModeMLInlineAdvisor::getMandatoryAdviceImpl(CallBase &CB) {
- return std::make_unique<LoggingMLInlineAdvice>(
- /*Advisor=*/this,
- /*CB=*/CB, /*ORE=*/getCallerORE(CB), /*Recommendation=*/true,
- /*Logger=*/*Logger,
- /*CallerSizeEstimateBefore=*/getNativeSizeEstimate(*CB.getCaller()),
- /*CalleeSizeEstimateBefore=*/
- getNativeSizeEstimate(*CB.getCalledFunction()),
- /*DefaultDecision=*/true, /*Mandatory*/ true);
-}
-
-std::unique_ptr<MLInlineAdvice>
-DevelopmentModeMLInlineAdvisor::getAdviceFromModel(
- CallBase &CB, OptimizationRemarkEmitter &ORE) {
- if (IsDoingInference && !isLogging())
- return MLInlineAdvisor::getAdviceFromModel(CB, ORE);
-
- bool DefaultAdvice = GetDefaultAdvice(CB);
- auto Recommendation = IsDoingInference ? ModelRunner->run() : DefaultAdvice;
- return std::make_unique<LoggingMLInlineAdvice>(
- /*Advisor=*/this,
- /*CB=*/CB, /*ORE=*/ORE, /*Recommendation=*/Recommendation,
- /*Logger=*/*Logger,
- /*CallerSizeEstimateBefore=*/getNativeSizeEstimate(*CB.getCaller()),
- /*CalleeSizeEstimateBefore=*/
- getNativeSizeEstimate(*CB.getCalledFunction()),
- /*DefaultDecision=*/DefaultAdvice);
-}
-
-size_t DevelopmentModeMLInlineAdvisor::getTotalSizeEstimate() {
- if (!InlineSizeEstimatorAnalysis::isEvaluatorRequested())
- return 0;
- size_t Ret = 0;
- for (auto &F : M) {
- if (F.isDeclaration())
- continue;
- if (isFunctionDeleted(&F))
- continue;
- Ret += *getNativeSizeEstimate(F);
- }
- return Ret;
-}
-
-ModelUnderTrainingRunner::ModelUnderTrainingRunner(LLVMContext &Ctx,
- const std::string &ModelPath)
- : MLModelRunner(Ctx) {
- std::vector<TensorSpec> InputSpecs;
- for (size_t I = 0; I < NumberOfFeatures; ++I)
- InputSpecs.push_back(
- TensorSpec::createSpec<int64_t>(TFFeedPrefix + FeatureNameMap[I], {1}));
- append_range(InputSpecs, TrainingOnlyFeatures);
- if (auto MaybeOutSpecs =
- loadOutputSpecs(Ctx, DecisionName, ModelPath, TFOutputSpecOverride))
- OutputSpecs = std::move(*MaybeOutSpecs);
- else
- return;
-
- Evaluator = std::make_unique<TFModelEvaluator>(
- ModelPath, InputSpecs, [&](size_t I) { return OutputSpecs[I].Spec; },
- OutputSpecs.size());
- if (!Evaluator || !Evaluator->isValid()) {
- Ctx.emitError("Failed to create inliner saved model evaluator");
- Evaluator.reset();
- return;
- }
-}
-
-bool ModelUnderTrainingRunner::run() {
- LastEvaluationResult = Evaluator->evaluate();
- if (!LastEvaluationResult.hasValue()) {
- Ctx.emitError("Error evaluating model.");
- return false;
- }
- int64_t Decision = *LastEvaluationResult->getTensorValue<int64_t>(0);
- return static_cast<bool>(Decision);
-}
-
-int64_t ModelUnderTrainingRunner::getFeature(int Index) const {
- return *Evaluator->getInput<int64_t>(Index);
-}
-
-void ModelUnderTrainingRunner::setFeature(FeatureIndex Index, int64_t Value) {
- size_t NumericIndex = static_cast<size_t>(Index);
- *(Evaluator->getInput<int64_t>(NumericIndex)) = Value;
-}
-
-std::unique_ptr<InlineAdvisor> llvm::getDevelopmentModeAdvisor(
- Module &M, ModuleAnalysisManager &MAM,
- std::function<bool(CallBase &)> GetDefaultAdvice) {
- auto &Ctx = M.getContext();
- std::unique_ptr<MLModelRunner> Runner;
- ModelUnderTrainingRunner *MUTRPtr = nullptr;
- bool IsDoingInference = false;
- if (TFModelUnderTrainingPath.empty())
- Runner.reset(new NoInferenceModelRunner(Ctx));
- else {
- auto MUTR = std::make_unique<ModelUnderTrainingRunner>(
- Ctx, TFModelUnderTrainingPath);
- if (!MUTR || !MUTR->isValid()) {
- Ctx.emitError("Could not load the policy model from the provided path");
- return nullptr;
- }
- IsDoingInference = true;
- MUTRPtr = MUTR.get();
- Runner = std::move(MUTR);
- }
- std::unique_ptr<TrainingLogger> Logger;
- if (!TrainingLog.empty())
- Logger = std::make_unique<TrainingLogger>(TrainingLog, MUTRPtr);
-
- return std::make_unique<DevelopmentModeMLInlineAdvisor>(
- M, MAM, std::move(Runner), GetDefaultAdvice, IsDoingInference,
- std::move(Logger));
-}
-#endif // defined(LLVM_HAVE_TF_API)
+//===- DevelopmentModeInlineAdvisor.cpp - runtime-loadable model runner --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a model runner using Tensorflow C APIs, allowing the
+// loading of a model from a command line option.
+//
+//===----------------------------------------------------------------------===//
+#include "llvm/Config/config.h"
+#if defined(LLVM_HAVE_TF_API)
+
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Analysis/InlineSizeEstimatorAnalysis.h"
+#include "llvm/Analysis/MLInlineAdvisor.h"
+#include "llvm/Analysis/Utils/TFUtils.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+
+#include <vector>
+
+using namespace llvm;
+
+static cl::opt<std::string> TrainingLog(
+ "training-log", cl::Hidden,
+ cl::desc("Path where the development - mode inlining log is saved."));
+
+static cl::opt<std::string> TFModelUnderTrainingPath(
+ "ml-inliner-model-under-training", cl::Hidden,
+ cl::desc(R"(Path to SavedModel from the previous training iteration.
+The directory is also expected to contain a JSON specification of the
+outputs expected to be logged, where the first entry must be the
+inlining decision. The file containing the specification should be
+called output_spec.json. The expected JSON value is an array of
+dictionaries. Each dictionary should have 2 keys:
+
+- "tensor_spec, followed by the TensorSpec description of the
+output; and
+- "logging_name", a string indicating the name to use when
+logging the output values.
+
+Example:
+[
+ {
+ "logging_name" : "some_name",
+ "tensor_spec" : {
+ "name" : "model_name",
+ "port" : 0,
+ "shape" : [2, 3],
+ "type" : "float"
+ }
+ }
+]
+
+The first value must always correspond to the decision.)"));
+
+static cl::opt<std::string> TFOutputSpecOverride(
+ "ml-inliner-output-spec-override", cl::Hidden,
+ cl::desc("Override the path to the output spec json file. See "
+ "-ml-inliner-model-under-training documentation for the "
+ "specification of that file."));
+
+static cl::opt<std::string> TFFeedPrefix("ml-inliner-trained-model-feed-prefix",
+ cl::Hidden, cl::init("action_"),
+ cl::desc("Prefix for feature names."));
+
+namespace {
+/// An InlineEvent, used by TrainingLogger.
+struct InlineEvent {
+ /// What the default policy's decision would have been.
+ int64_t DefaultDecision = 0;
+
+ /// What we advised. When training off the default policy, this is the same as
+ /// DefaultDecision.
+ int64_t AdvisedDecision = 0;
+
+ /// What actually happened. This would be 'false' in the case of an inline
+ /// error, even if AdvisedDecision were true, otherwise it agrees with
+ /// AdvisedDecision.
+ bool Effect = false;
+
+ /// What the change in size was: size_after - size_before
+ int64_t Reward = 0;
+};
+
+/// Collect data we may use for training a model, and write it as a textual
+/// Tensorflow SequenceExample
+/// (https://www.tensorflow.org/api_docs/python/tf/train/SequenceExample)
+/// protobuf (https://developers.google.com/protocol-buffers).
+/// Because this is a protobuf, we cannot just stream the events as they come.
+/// Internally, TrainingLogger stores data in column-major format, because that
+/// lines up with how TF SequenceExample represents it.
+class ModelUnderTrainingRunner;
+class TrainingLogger final {
+public:
+ TrainingLogger(StringRef LogFileName, const ModelUnderTrainingRunner *MUTR);
+
+ /// Log one inlining event.
+ void logInlineEvent(const InlineEvent &Event,
+ const MLModelRunner &ModelRunner);
+
+ /// Print the stored tensors.
+ void print();
+
+private:
+ StringRef LogFileName;
+ const ModelUnderTrainingRunner *const MUTR;
+ std::unique_ptr<Logger> L;
+ std::vector<bool> Effects;
+ /// There's at least one output. We'll set this to a different value if MUTR
+ /// is avaliable.
+ size_t OutputCount = 1;
+ /// Set these 2 clearly OOB, to make sure we set them later.
+ size_t DefaultDecisionPos = std::numeric_limits<size_t>::max();
+ size_t DecisionPos = std::numeric_limits<size_t>::max();
+};
+
+/// An extension of the MLInlineAdvisor for the 'development' mode, targeting
+/// the offline training scenario. Note that training happens outside of the
+/// compiler, this facility is concerned with producing training data ("logs").
+/// This InlineAdvisor can operate in the following modes:
+///
+/// 1) collect logs for the default policy. This is useful for bootstrapping
+/// training, which will be considerably faster by starting from a reasonable
+/// policy.
+///
+/// 2) collect logs for the ML policy, using a model from a previous
+/// training. Potentially, that model uses internally some small random
+/// perturbation of its weights, to induce exploration (setting this up is the
+/// responsibility of the training algorithm). The logs would then be used to
+/// retrain and improve on this model.
+///
+/// 3) use the provided model, with no logging. This is useful for end to end
+/// validation - the model, in this case, is a release candidate and shouldn't
+/// have random perturbations. It is a convenience feature: rather than needing
+/// to take the release candidate model and compile it in 'release' mode,
+/// validate it, then potentially discard it, it's easier to just pass the model
+/// to the compiler, albeit compilation would be slower, as a one-off. Once the
+/// model behaves satisfactorily, it can be compiled AOT, for efficiency, in
+/// release mode. The expectation is that a well-trained model provides a good
+/// policy over a sufficiently diverse codebase, over many changes (i.e.
+/// training happens seldom).
+class DevelopmentModeMLInlineAdvisor : public MLInlineAdvisor {
+public:
+ DevelopmentModeMLInlineAdvisor(
+ Module &M, ModuleAnalysisManager &MAM,
+ std::unique_ptr<MLModelRunner> ModelRunner,
+ std::function<bool(CallBase &)> GetDefaultAdvice, bool IsDoingInference,
+ std::unique_ptr<TrainingLogger> Logger);
+
+ size_t getTotalSizeEstimate();
+
+ virtual ~DevelopmentModeMLInlineAdvisor();
+ void updateNativeSizeEstimate(int64_t Change) {
+ *CurrentNativeSize += Change;
+ }
+ void resetNativeSize(Function *F) {
+ FAM.invalidate<InlineSizeEstimatorAnalysis>(*F);
+ }
+
+ std::unique_ptr<MLInlineAdvice>
+ getAdviceFromModel(CallBase &CB, OptimizationRemarkEmitter &ORE) override;
+
+ Optional<size_t> getNativeSizeEstimate(const Function &F) const;
+
+private:
+ bool isLogging() const { return !!Logger; }
+ std::unique_ptr<MLInlineAdvice> getMandatoryAdviceImpl(CallBase &CB) override;
+
+ std::function<bool(CallBase &)> GetDefaultAdvice;
+ const bool IsDoingInference;
+ std::unique_ptr<TrainingLogger> Logger;
+
+ const Optional<int32_t> InitialNativeSize;
+ Optional<int32_t> CurrentNativeSize;
+};
+
+/// A variant of MLInlineAdvice that tracks all non-trivial inlining
+/// decisions, for training/logging.
+class LoggingMLInlineAdvice : public MLInlineAdvice {
+public:
+ LoggingMLInlineAdvice(DevelopmentModeMLInlineAdvisor *Advisor, CallBase &CB,
+ OptimizationRemarkEmitter &ORE, bool Recommendation,
+ TrainingLogger &Logger,
+ Optional<size_t> CallerSizeEstimateBefore,
+ Optional<size_t> CalleeSizeEstimateBefore,
+ bool DefaultDecision, bool Mandatory = false)
+ : MLInlineAdvice(Advisor, CB, ORE, Recommendation), Logger(Logger),
+ CallerSizeEstimateBefore(CallerSizeEstimateBefore),
+ CalleeSizeEstimateBefore(CalleeSizeEstimateBefore),
+ DefaultDecision(DefaultDecision), Mandatory(Mandatory) {}
+
+ virtual ~LoggingMLInlineAdvice() = default;
+
+private:
+ DevelopmentModeMLInlineAdvisor *getAdvisor() const {
+ return static_cast<DevelopmentModeMLInlineAdvisor *>(Advisor);
+ }
+ void recordInliningImpl() override {
+ MLInlineAdvice::recordInliningImpl();
+ getAdvisor()->resetNativeSize(Caller);
+ int Reward = std::numeric_limits<int>::max();
+ if (InlineSizeEstimatorAnalysis::isEvaluatorRequested() &&
+ !getAdvisor()->isForcedToStop()) {
+ int NativeSizeAfter = *getAdvisor()->getNativeSizeEstimate(*Caller) +
+ *CalleeSizeEstimateBefore;
+ Reward = NativeSizeAfter -
+ (*CallerSizeEstimateBefore + *CalleeSizeEstimateBefore);
+ getAdvisor()->updateNativeSizeEstimate(Reward);
+ }
+ log(Reward, /*Success=*/true);
+ }
+
+ void recordInliningWithCalleeDeletedImpl() override {
+ MLInlineAdvice::recordInliningWithCalleeDeletedImpl();
+ getAdvisor()->resetNativeSize(Caller);
+ if (InlineSizeEstimatorAnalysis::isEvaluatorRequested() &&
+ !getAdvisor()->isForcedToStop()) {
+ int NativeSizeAfter = *getAdvisor()->getNativeSizeEstimate(*Caller);
+ int Reward = NativeSizeAfter -
+ (*CallerSizeEstimateBefore + *CalleeSizeEstimateBefore);
+ getAdvisor()->updateNativeSizeEstimate(Reward);
+ log(Reward, /*Success=*/true);
+ }
+ }
+
+ void recordUnsuccessfulInliningImpl(const InlineResult &Result) override {
+ MLInlineAdvice::recordUnsuccessfulInliningImpl(Result);
+ log(NoReward, /*Success=*/false);
+ }
+
+ void recordUnattemptedInliningImpl() override {
+ MLInlineAdvice::recordUnattemptedInliningImpl();
+ log(NoReward, /*Success=*/false);
+ }
+
+ void log(int64_t Reward, bool Success) {
+ if (Mandatory)
+ return;
+ InlineEvent Event;
+ Event.AdvisedDecision = isInliningRecommended();
+ Event.DefaultDecision = DefaultDecision;
+ Event.Effect = Success;
+ Event.Reward = Reward;
+ Logger.logInlineEvent(Event, getAdvisor()->getModelRunner());
+ }
+
+ static const int64_t NoReward = 0;
+ TrainingLogger &Logger;
+ const Optional<size_t> CallerSizeEstimateBefore;
+ const Optional<size_t> CalleeSizeEstimateBefore;
+ const int64_t DefaultDecision;
+ const int64_t Mandatory;
+};
+
+/// A pseudo model runner. We use it to store feature values when collecting
+/// logs for the default policy, but never ask it to 'run'.
+class NoInferenceModelRunner : public MLModelRunner {
+public:
+ NoInferenceModelRunner(LLVMContext &Ctx)
+ : MLModelRunner(Ctx), Features(NumberOfFeatures) {}
+ void setFeature(FeatureIndex Index, int64_t Value) override {
+ Features[static_cast<int>(Index)] = Value;
+ }
+
+ int64_t getFeature(int Index) const override { return Features[Index]; }
+ bool run() override {
+ llvm_unreachable("We shouldn't call run on this model runner.");
+ }
+
+private:
+ InlineFeatures Features;
+};
+
+/// ModelUnderTrainingRunner - training mode implementation. It uses TF C APIs
+/// to dynamically load and evaluate a TF SavedModel
+/// (https://www.tensorflow.org/guide/saved_model). Runtime performance is
+/// sacrificed for ease of use while training.
+class ModelUnderTrainingRunner final : public MLModelRunner {
+public:
+ ModelUnderTrainingRunner(LLVMContext &Ctx, const std::string &ModelPath);
+
+ bool run() override;
+
+ // Disallows copy and assign.
+ ModelUnderTrainingRunner(const ModelUnderTrainingRunner &) = delete;
+ ModelUnderTrainingRunner &
+ operator=(const ModelUnderTrainingRunner &) = delete;
+
+ void setFeature(FeatureIndex Index, int64_t Value) override;
+ int64_t getFeature(int Index) const override;
+ bool isValid() const { return !!Evaluator; }
+
+ const std::vector<LoggedFeatureSpec> &outputLoggedFeatureSpecs() const {
+ return OutputSpecs;
+ }
+
+ const Optional<TFModelEvaluator::EvaluationResult> &
+ lastEvaluationResult() const {
+ return LastEvaluationResult;
+ }
+
+private:
+ std::unique_ptr<TFModelEvaluator> Evaluator;
+ std::vector<LoggedFeatureSpec> OutputSpecs;
+ Optional<TFModelEvaluator::EvaluationResult> LastEvaluationResult;
+
+ // The training framework needs some additional features.
+ const std::vector<TensorSpec> TrainingOnlyFeatures{
+ TensorSpec::createSpec<int64_t>(TFFeedPrefix + "inlining_default", {1}),
+ TensorSpec::createSpec<float>(TFFeedPrefix + "discount", {1}),
+ TensorSpec::createSpec<float>(TFFeedPrefix + "reward", {1}),
+ TensorSpec::createSpec<int32_t>(TFFeedPrefix + "step_type", {1})};
+};
+} // namespace
+
+TrainingLogger::TrainingLogger(StringRef LogFileName,
+ const ModelUnderTrainingRunner *MUTR)
+ : LogFileName(LogFileName), MUTR(MUTR) {
+ // The first output is the inlining decision.
+ if (MUTR)
+ OutputCount = MUTR->outputLoggedFeatureSpecs().size();
+ std::vector<LoggedFeatureSpec> FT;
+
+ for (size_t I = 0; I < NumberOfFeatures; ++I)
+ FT.push_back(
+ {TensorSpec::createSpec<int64_t>(FeatureNameMap.at(I), {1}), None});
+ if (MUTR && MUTR->outputLoggedFeatureSpecs().size() > 1)
+ append_range(FT, drop_begin(MUTR->outputLoggedFeatureSpecs()));
+
+ DefaultDecisionPos = FT.size();
+ FT.push_back(
+ {TensorSpec::createSpec<int64_t>(DefaultDecisionName, {1}), None});
+
+ DecisionPos = FT.size();
+ FT.push_back({TensorSpec::createSpec<int64_t>(DecisionName, {1}), None});
+
+ L = std::make_unique<Logger>(
+ FT, TensorSpec::createSpec<int64_t>(RewardName, {1}),
+ InlineSizeEstimatorAnalysis::isEvaluatorRequested());
+}
+
+/// Log one inlining event.
+void TrainingLogger::logInlineEvent(const InlineEvent &Event,
+ const MLModelRunner &ModelRunner) {
+ size_t CurrentFeature = 0;
+ for (; CurrentFeature < NumberOfFeatures; ++CurrentFeature) {
+ int64_t F = ModelRunner.getFeature(CurrentFeature);
+ L->logTensorValue(CurrentFeature, &F);
+ }
+
+ for (size_t I = 1; I < OutputCount; ++I) {
+ const auto &Result = *MUTR->lastEvaluationResult();
+ auto &Spec = MUTR->outputLoggedFeatureSpecs()[I].Spec;
+ const char *RawData =
+ reinterpret_cast<const char *>(Result.getUntypedTensorValue(I));
+ L->logTensorValue(CurrentFeature, RawData,
+ Spec.getElementCount() * Spec.getElementByteSize());
+ ++CurrentFeature;
+ }
+
+ assert(CurrentFeature == DefaultDecisionPos);
+ L->logTensorValue(DefaultDecisionPos, &Event.DefaultDecision);
+ L->logTensorValue(DecisionPos, &Event.AdvisedDecision);
+ if (InlineSizeEstimatorAnalysis::isEvaluatorRequested())
+ L->logReward(Event.Reward);
+
+ // For debugging / later use
+ Effects.push_back(Event.Effect);
+}
+
+void TrainingLogger::print() {
+ std::error_code EC;
+ raw_fd_ostream OutFile(LogFileName, EC);
+ L->print(OutFile);
+}
+
+DevelopmentModeMLInlineAdvisor::DevelopmentModeMLInlineAdvisor(
+ Module &M, ModuleAnalysisManager &MAM,
+ std::unique_ptr<MLModelRunner> ModelRunner,
+ std::function<bool(CallBase &)> GetDefaultAdvice, bool IsDoingInference,
+ std::unique_ptr<TrainingLogger> Logger)
+ : MLInlineAdvisor(M, MAM, std::move(ModelRunner)),
+ GetDefaultAdvice(GetDefaultAdvice), IsDoingInference(IsDoingInference),
+ Logger(std::move(Logger)),
+ InitialNativeSize(isLogging() ? getTotalSizeEstimate() : 0),
+ CurrentNativeSize(InitialNativeSize) {
+ // We cannot have the case of neither inference nor logging.
+ assert(IsDoingInference || isLogging());
+}
+
+DevelopmentModeMLInlineAdvisor::~DevelopmentModeMLInlineAdvisor() {
+ if (isLogging())
+ Logger->print();
+}
+
+Optional<size_t>
+DevelopmentModeMLInlineAdvisor::getNativeSizeEstimate(const Function &F) const {
+ if (!InlineSizeEstimatorAnalysis::isEvaluatorRequested())
+ return None;
+ auto &R =
+ FAM.getResult<InlineSizeEstimatorAnalysis>(const_cast<Function &>(F));
+ if (!R) {
+ F.getParent()->getContext().emitError(
+ "Native size estimator is not present.");
+ return 0;
+ }
+ return *R;
+}
+
+std::unique_ptr<MLInlineAdvice>
+DevelopmentModeMLInlineAdvisor::getMandatoryAdviceImpl(CallBase &CB) {
+ return std::make_unique<LoggingMLInlineAdvice>(
+ /*Advisor=*/this,
+ /*CB=*/CB, /*ORE=*/getCallerORE(CB), /*Recommendation=*/true,
+ /*Logger=*/*Logger,
+ /*CallerSizeEstimateBefore=*/getNativeSizeEstimate(*CB.getCaller()),
+ /*CalleeSizeEstimateBefore=*/
+ getNativeSizeEstimate(*CB.getCalledFunction()),
+ /*DefaultDecision=*/true, /*Mandatory*/ true);
+}
+
+std::unique_ptr<MLInlineAdvice>
+DevelopmentModeMLInlineAdvisor::getAdviceFromModel(
+ CallBase &CB, OptimizationRemarkEmitter &ORE) {
+ if (IsDoingInference && !isLogging())
+ return MLInlineAdvisor::getAdviceFromModel(CB, ORE);
+
+ bool DefaultAdvice = GetDefaultAdvice(CB);
+ auto Recommendation = IsDoingInference ? ModelRunner->run() : DefaultAdvice;
+ return std::make_unique<LoggingMLInlineAdvice>(
+ /*Advisor=*/this,
+ /*CB=*/CB, /*ORE=*/ORE, /*Recommendation=*/Recommendation,
+ /*Logger=*/*Logger,
+ /*CallerSizeEstimateBefore=*/getNativeSizeEstimate(*CB.getCaller()),
+ /*CalleeSizeEstimateBefore=*/
+ getNativeSizeEstimate(*CB.getCalledFunction()),
+ /*DefaultDecision=*/DefaultAdvice);
+}
+
+size_t DevelopmentModeMLInlineAdvisor::getTotalSizeEstimate() {
+ if (!InlineSizeEstimatorAnalysis::isEvaluatorRequested())
+ return 0;
+ size_t Ret = 0;
+ for (auto &F : M) {
+ if (F.isDeclaration())
+ continue;
+ if (isFunctionDeleted(&F))
+ continue;
+ Ret += *getNativeSizeEstimate(F);
+ }
+ return Ret;
+}
+
+ModelUnderTrainingRunner::ModelUnderTrainingRunner(LLVMContext &Ctx,
+ const std::string &ModelPath)
+ : MLModelRunner(Ctx) {
+ std::vector<TensorSpec> InputSpecs;
+ for (size_t I = 0; I < NumberOfFeatures; ++I)
+ InputSpecs.push_back(
+ TensorSpec::createSpec<int64_t>(TFFeedPrefix + FeatureNameMap[I], {1}));
+ append_range(InputSpecs, TrainingOnlyFeatures);
+ if (auto MaybeOutSpecs =
+ loadOutputSpecs(Ctx, DecisionName, ModelPath, TFOutputSpecOverride))
+ OutputSpecs = std::move(*MaybeOutSpecs);
+ else
+ return;
+
+ Evaluator = std::make_unique<TFModelEvaluator>(
+ ModelPath, InputSpecs, [&](size_t I) { return OutputSpecs[I].Spec; },
+ OutputSpecs.size());
+ if (!Evaluator || !Evaluator->isValid()) {
+ Ctx.emitError("Failed to create inliner saved model evaluator");
+ Evaluator.reset();
+ return;
+ }
+}
+
+bool ModelUnderTrainingRunner::run() {
+ LastEvaluationResult = Evaluator->evaluate();
+ if (!LastEvaluationResult.hasValue()) {
+ Ctx.emitError("Error evaluating model.");
+ return false;
+ }
+ int64_t Decision = *LastEvaluationResult->getTensorValue<int64_t>(0);
+ return static_cast<bool>(Decision);
+}
+
+int64_t ModelUnderTrainingRunner::getFeature(int Index) const {
+ return *Evaluator->getInput<int64_t>(Index);
+}
+
+void ModelUnderTrainingRunner::setFeature(FeatureIndex Index, int64_t Value) {
+ size_t NumericIndex = static_cast<size_t>(Index);
+ *(Evaluator->getInput<int64_t>(NumericIndex)) = Value;
+}
+
+std::unique_ptr<InlineAdvisor> llvm::getDevelopmentModeAdvisor(
+ Module &M, ModuleAnalysisManager &MAM,
+ std::function<bool(CallBase &)> GetDefaultAdvice) {
+ auto &Ctx = M.getContext();
+ std::unique_ptr<MLModelRunner> Runner;
+ ModelUnderTrainingRunner *MUTRPtr = nullptr;
+ bool IsDoingInference = false;
+ if (TFModelUnderTrainingPath.empty())
+ Runner.reset(new NoInferenceModelRunner(Ctx));
+ else {
+ auto MUTR = std::make_unique<ModelUnderTrainingRunner>(
+ Ctx, TFModelUnderTrainingPath);
+ if (!MUTR || !MUTR->isValid()) {
+ Ctx.emitError("Could not load the policy model from the provided path");
+ return nullptr;
+ }
+ IsDoingInference = true;
+ MUTRPtr = MUTR.get();
+ Runner = std::move(MUTR);
+ }
+ std::unique_ptr<TrainingLogger> Logger;
+ if (!TrainingLog.empty())
+ Logger = std::make_unique<TrainingLogger>(TrainingLog, MUTRPtr);
+
+ return std::make_unique<DevelopmentModeMLInlineAdvisor>(
+ M, MAM, std::move(Runner), GetDefaultAdvice, IsDoingInference,
+ std::move(Logger));
+}
+#endif // defined(LLVM_HAVE_TF_API)
diff --git a/contrib/libs/llvm12/lib/Analysis/DivergenceAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/DivergenceAnalysis.cpp
index 422b298bff..287c132780 100644
--- a/contrib/libs/llvm12/lib/Analysis/DivergenceAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/DivergenceAnalysis.cpp
@@ -1,4 +1,4 @@
-//===---- DivergenceAnalysis.cpp --- Divergence Analysis Implementation ----==//
+//===---- DivergenceAnalysis.cpp --- Divergence Analysis Implementation ----==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -96,12 +96,12 @@ DivergenceAnalysis::DivergenceAnalysis(
: F(F), RegionLoop(RegionLoop), DT(DT), LI(LI), SDA(SDA),
IsLCSSAForm(IsLCSSAForm) {}
-bool DivergenceAnalysis::markDivergent(const Value &DivVal) {
- if (isAlwaysUniform(DivVal))
- return false;
+bool DivergenceAnalysis::markDivergent(const Value &DivVal) {
+ if (isAlwaysUniform(DivVal))
+ return false;
assert(isa<Instruction>(DivVal) || isa<Argument>(DivVal));
assert(!isAlwaysUniform(DivVal) && "cannot be a divergent");
- return DivergentValues.insert(&DivVal).second;
+ return DivergentValues.insert(&DivVal).second;
}
void DivergenceAnalysis::addUniformOverride(const Value &UniVal) {
@@ -118,7 +118,7 @@ bool DivergenceAnalysis::isTemporalDivergent(const BasicBlock &ObservingBlock,
for (const auto *Loop = LI.getLoopFor(Inst->getParent());
Loop != RegionLoop && !Loop->contains(&ObservingBlock);
Loop = Loop->getParentLoop()) {
- if (DivergentLoops.contains(Loop))
+ if (DivergentLoops.contains(Loop))
return true;
}
@@ -133,103 +133,103 @@ bool DivergenceAnalysis::inRegion(const BasicBlock &BB) const {
return (!RegionLoop && BB.getParent() == &F) || RegionLoop->contains(&BB);
}
-void DivergenceAnalysis::pushUsers(const Value &V) {
- const auto *I = dyn_cast<const Instruction>(&V);
-
- if (I && I->isTerminator()) {
- analyzeControlDivergence(*I);
- return;
- }
-
- for (const auto *User : V.users()) {
- const auto *UserInst = dyn_cast<const Instruction>(User);
- if (!UserInst)
- continue;
-
- // only compute divergent inside loop
- if (!inRegion(*UserInst))
- continue;
-
- // All users of divergent values are immediate divergent
- if (markDivergent(*UserInst))
- Worklist.push_back(UserInst);
- }
-}
-
-static const Instruction *getIfCarriedInstruction(const Use &U,
- const Loop &DivLoop) {
- const auto *I = dyn_cast<const Instruction>(&U);
- if (!I)
- return nullptr;
- if (!DivLoop.contains(I))
- return nullptr;
- return I;
-}
-
-void DivergenceAnalysis::analyzeTemporalDivergence(const Instruction &I,
- const Loop &OuterDivLoop) {
- if (isAlwaysUniform(I))
- return;
- if (isDivergent(I))
- return;
-
- LLVM_DEBUG(dbgs() << "Analyze temporal divergence: " << I.getName() << "\n");
- assert((isa<PHINode>(I) || !IsLCSSAForm) &&
- "In LCSSA form all users of loop-exiting defs are Phi nodes.");
- for (const Use &Op : I.operands()) {
- const auto *OpInst = getIfCarriedInstruction(Op, OuterDivLoop);
+void DivergenceAnalysis::pushUsers(const Value &V) {
+ const auto *I = dyn_cast<const Instruction>(&V);
+
+ if (I && I->isTerminator()) {
+ analyzeControlDivergence(*I);
+ return;
+ }
+
+ for (const auto *User : V.users()) {
+ const auto *UserInst = dyn_cast<const Instruction>(User);
+ if (!UserInst)
+ continue;
+
+ // only compute divergent inside loop
+ if (!inRegion(*UserInst))
+ continue;
+
+ // All users of divergent values are immediate divergent
+ if (markDivergent(*UserInst))
+ Worklist.push_back(UserInst);
+ }
+}
+
+static const Instruction *getIfCarriedInstruction(const Use &U,
+ const Loop &DivLoop) {
+ const auto *I = dyn_cast<const Instruction>(&U);
+ if (!I)
+ return nullptr;
+ if (!DivLoop.contains(I))
+ return nullptr;
+ return I;
+}
+
+void DivergenceAnalysis::analyzeTemporalDivergence(const Instruction &I,
+ const Loop &OuterDivLoop) {
+ if (isAlwaysUniform(I))
+ return;
+ if (isDivergent(I))
+ return;
+
+ LLVM_DEBUG(dbgs() << "Analyze temporal divergence: " << I.getName() << "\n");
+ assert((isa<PHINode>(I) || !IsLCSSAForm) &&
+ "In LCSSA form all users of loop-exiting defs are Phi nodes.");
+ for (const Use &Op : I.operands()) {
+ const auto *OpInst = getIfCarriedInstruction(Op, OuterDivLoop);
if (!OpInst)
continue;
- if (markDivergent(I))
- pushUsers(I);
- return;
+ if (markDivergent(I))
+ pushUsers(I);
+ return;
}
}
// marks all users of loop-carried values of the loop headed by LoopHeader as
// divergent
-void DivergenceAnalysis::analyzeLoopExitDivergence(const BasicBlock &DivExit,
- const Loop &OuterDivLoop) {
- // All users are in immediate exit blocks
- if (IsLCSSAForm) {
- for (const auto &Phi : DivExit.phis()) {
- analyzeTemporalDivergence(Phi, OuterDivLoop);
- }
- return;
- }
-
- // For non-LCSSA we have to follow all live out edges wherever they may lead.
- const BasicBlock &LoopHeader = *OuterDivLoop.getHeader();
- SmallVector<const BasicBlock *, 8> TaintStack;
- TaintStack.push_back(&DivExit);
+void DivergenceAnalysis::analyzeLoopExitDivergence(const BasicBlock &DivExit,
+ const Loop &OuterDivLoop) {
+ // All users are in immediate exit blocks
+ if (IsLCSSAForm) {
+ for (const auto &Phi : DivExit.phis()) {
+ analyzeTemporalDivergence(Phi, OuterDivLoop);
+ }
+ return;
+ }
+
+ // For non-LCSSA we have to follow all live out edges wherever they may lead.
+ const BasicBlock &LoopHeader = *OuterDivLoop.getHeader();
+ SmallVector<const BasicBlock *, 8> TaintStack;
+ TaintStack.push_back(&DivExit);
// Otherwise potential users of loop-carried values could be anywhere in the
// dominance region of DivLoop (including its fringes for phi nodes)
DenseSet<const BasicBlock *> Visited;
- Visited.insert(&DivExit);
+ Visited.insert(&DivExit);
- do {
- auto *UserBlock = TaintStack.pop_back_val();
+ do {
+ auto *UserBlock = TaintStack.pop_back_val();
// don't spread divergence beyond the region
if (!inRegion(*UserBlock))
continue;
- assert(!OuterDivLoop.contains(UserBlock) &&
+ assert(!OuterDivLoop.contains(UserBlock) &&
"irreducible control flow detected");
// phi nodes at the fringes of the dominance region
if (!DT.dominates(&LoopHeader, UserBlock)) {
// all PHI nodes of UserBlock become divergent
for (auto &Phi : UserBlock->phis()) {
- analyzeTemporalDivergence(Phi, OuterDivLoop);
+ analyzeTemporalDivergence(Phi, OuterDivLoop);
}
continue;
}
- // Taint outside users of values carried by OuterDivLoop.
+ // Taint outside users of values carried by OuterDivLoop.
for (auto &I : *UserBlock) {
- analyzeTemporalDivergence(I, OuterDivLoop);
+ analyzeTemporalDivergence(I, OuterDivLoop);
}
// visit all blocks in the dominance region
@@ -239,57 +239,57 @@ void DivergenceAnalysis::analyzeLoopExitDivergence(const BasicBlock &DivExit,
}
TaintStack.push_back(SuccBlock);
}
- } while (!TaintStack.empty());
+ } while (!TaintStack.empty());
}
-void DivergenceAnalysis::propagateLoopExitDivergence(const BasicBlock &DivExit,
- const Loop &InnerDivLoop) {
- LLVM_DEBUG(dbgs() << "\tpropLoopExitDiv " << DivExit.getName() << "\n");
-
- // Find outer-most loop that does not contain \p DivExit
- const Loop *DivLoop = &InnerDivLoop;
- const Loop *OuterDivLoop = DivLoop;
- const Loop *ExitLevelLoop = LI.getLoopFor(&DivExit);
- const unsigned LoopExitDepth =
- ExitLevelLoop ? ExitLevelLoop->getLoopDepth() : 0;
- while (DivLoop && DivLoop->getLoopDepth() > LoopExitDepth) {
- DivergentLoops.insert(DivLoop); // all crossed loops are divergent
- OuterDivLoop = DivLoop;
- DivLoop = DivLoop->getParentLoop();
+void DivergenceAnalysis::propagateLoopExitDivergence(const BasicBlock &DivExit,
+ const Loop &InnerDivLoop) {
+ LLVM_DEBUG(dbgs() << "\tpropLoopExitDiv " << DivExit.getName() << "\n");
+
+ // Find outer-most loop that does not contain \p DivExit
+ const Loop *DivLoop = &InnerDivLoop;
+ const Loop *OuterDivLoop = DivLoop;
+ const Loop *ExitLevelLoop = LI.getLoopFor(&DivExit);
+ const unsigned LoopExitDepth =
+ ExitLevelLoop ? ExitLevelLoop->getLoopDepth() : 0;
+ while (DivLoop && DivLoop->getLoopDepth() > LoopExitDepth) {
+ DivergentLoops.insert(DivLoop); // all crossed loops are divergent
+ OuterDivLoop = DivLoop;
+ DivLoop = DivLoop->getParentLoop();
}
- LLVM_DEBUG(dbgs() << "\tOuter-most left loop: " << OuterDivLoop->getName()
- << "\n");
+ LLVM_DEBUG(dbgs() << "\tOuter-most left loop: " << OuterDivLoop->getName()
+ << "\n");
- analyzeLoopExitDivergence(DivExit, *OuterDivLoop);
+ analyzeLoopExitDivergence(DivExit, *OuterDivLoop);
}
-// this is a divergent join point - mark all phi nodes as divergent and push
-// them onto the stack.
-void DivergenceAnalysis::taintAndPushPhiNodes(const BasicBlock &JoinBlock) {
- LLVM_DEBUG(dbgs() << "taintAndPushPhiNodes in " << JoinBlock.getName()
- << "\n");
+// this is a divergent join point - mark all phi nodes as divergent and push
+// them onto the stack.
+void DivergenceAnalysis::taintAndPushPhiNodes(const BasicBlock &JoinBlock) {
+ LLVM_DEBUG(dbgs() << "taintAndPushPhiNodes in " << JoinBlock.getName()
+ << "\n");
// ignore divergence outside the region
if (!inRegion(JoinBlock)) {
- return;
+ return;
}
// push non-divergent phi nodes in JoinBlock to the worklist
- for (const auto &Phi : JoinBlock.phis()) {
- if (isDivergent(Phi))
- continue;
- // FIXME Theoretically ,the 'undef' value could be replaced by any other
- // value causing spurious divergence.
- if (Phi.hasConstantOrUndefValue())
- continue;
- if (markDivergent(Phi))
- Worklist.push_back(&Phi);
- }
+ for (const auto &Phi : JoinBlock.phis()) {
+ if (isDivergent(Phi))
+ continue;
+ // FIXME Theoretically ,the 'undef' value could be replaced by any other
+ // value causing spurious divergence.
+ if (Phi.hasConstantOrUndefValue())
+ continue;
+ if (markDivergent(Phi))
+ Worklist.push_back(&Phi);
+ }
}
-void DivergenceAnalysis::analyzeControlDivergence(const Instruction &Term) {
- LLVM_DEBUG(dbgs() << "analyzeControlDiv " << Term.getParent()->getName()
- << "\n");
+void DivergenceAnalysis::analyzeControlDivergence(const Instruction &Term) {
+ LLVM_DEBUG(dbgs() << "analyzeControlDiv " << Term.getParent()->getName()
+ << "\n");
// Don't propagate divergence from unreachable blocks.
if (!DT.isReachableFromEntry(Term.getParent()))
@@ -297,45 +297,45 @@ void DivergenceAnalysis::analyzeControlDivergence(const Instruction &Term) {
const auto *BranchLoop = LI.getLoopFor(Term.getParent());
- const auto &DivDesc = SDA.getJoinBlocks(Term);
+ const auto &DivDesc = SDA.getJoinBlocks(Term);
- // Iterate over all blocks now reachable by a disjoint path join
- for (const auto *JoinBlock : DivDesc.JoinDivBlocks) {
- taintAndPushPhiNodes(*JoinBlock);
+ // Iterate over all blocks now reachable by a disjoint path join
+ for (const auto *JoinBlock : DivDesc.JoinDivBlocks) {
+ taintAndPushPhiNodes(*JoinBlock);
}
- assert(DivDesc.LoopDivBlocks.empty() || BranchLoop);
- for (const auto *DivExitBlock : DivDesc.LoopDivBlocks) {
- propagateLoopExitDivergence(*DivExitBlock, *BranchLoop);
+ assert(DivDesc.LoopDivBlocks.empty() || BranchLoop);
+ for (const auto *DivExitBlock : DivDesc.LoopDivBlocks) {
+ propagateLoopExitDivergence(*DivExitBlock, *BranchLoop);
}
}
void DivergenceAnalysis::compute() {
- // Initialize worklist.
- auto DivValuesCopy = DivergentValues;
- for (const auto *DivVal : DivValuesCopy) {
- assert(isDivergent(*DivVal) && "Worklist invariant violated!");
+ // Initialize worklist.
+ auto DivValuesCopy = DivergentValues;
+ for (const auto *DivVal : DivValuesCopy) {
+ assert(isDivergent(*DivVal) && "Worklist invariant violated!");
pushUsers(*DivVal);
}
- // All values on the Worklist are divergent.
- // Their users may not have been updated yed.
+ // All values on the Worklist are divergent.
+ // Their users may not have been updated yed.
while (!Worklist.empty()) {
const Instruction &I = *Worklist.back();
Worklist.pop_back();
// propagate value divergence to users
- assert(isDivergent(I) && "Worklist invariant violated!");
- pushUsers(I);
+ assert(isDivergent(I) && "Worklist invariant violated!");
+ pushUsers(I);
}
}
bool DivergenceAnalysis::isAlwaysUniform(const Value &V) const {
- return UniformOverrides.contains(&V);
+ return UniformOverrides.contains(&V);
}
bool DivergenceAnalysis::isDivergent(const Value &V) const {
- return DivergentValues.contains(&V);
+ return DivergentValues.contains(&V);
}
bool DivergenceAnalysis::isDivergentUse(const Use &U) const {
@@ -360,7 +360,7 @@ GPUDivergenceAnalysis::GPUDivergenceAnalysis(Function &F,
const PostDominatorTree &PDT,
const LoopInfo &LI,
const TargetTransformInfo &TTI)
- : SDA(DT, PDT, LI), DA(F, nullptr, DT, LI, SDA, /* LCSSA */ false) {
+ : SDA(DT, PDT, LI), DA(F, nullptr, DT, LI, SDA, /* LCSSA */ false) {
for (auto &I : instructions(F)) {
if (TTI.isSourceOfDivergence(&I)) {
DA.markDivergent(I);
diff --git a/contrib/libs/llvm12/lib/Analysis/DomTreeUpdater.cpp b/contrib/libs/llvm12/lib/Analysis/DomTreeUpdater.cpp
index 76b5aff077..8ac7d9d4ef 100644
--- a/contrib/libs/llvm12/lib/Analysis/DomTreeUpdater.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/DomTreeUpdater.cpp
@@ -32,7 +32,7 @@ bool DomTreeUpdater::isUpdateValid(
// Since isUpdateValid() must be called *after* the Terminator of From is
// altered we can determine if the update is unnecessary for batch updates
// or invalid for a single update.
- const bool HasEdge = llvm::is_contained(successors(From), To);
+ const bool HasEdge = llvm::is_contained(successors(From), To);
// If the IR does not match the update,
// 1. In batch updates, this update is unnecessary.
@@ -166,7 +166,7 @@ bool DomTreeUpdater::hasPendingPostDomTreeUpdates() const {
bool DomTreeUpdater::isBBPendingDeletion(llvm::BasicBlock *DelBB) const {
if (Strategy == UpdateStrategy::Eager || DeletedBBs.empty())
return false;
- return DeletedBBs.contains(DelBB);
+ return DeletedBBs.contains(DelBB);
}
// The DT and PDT require the nodes related to updates
diff --git a/contrib/libs/llvm12/lib/Analysis/EHPersonalities.cpp b/contrib/libs/llvm12/lib/Analysis/EHPersonalities.cpp
index e8d0d94d8f..a982f266b2 100644
--- a/contrib/libs/llvm12/lib/Analysis/EHPersonalities.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/EHPersonalities.cpp
@@ -24,23 +24,23 @@ EHPersonality llvm::classifyEHPersonality(const Value *Pers) {
if (!F)
return EHPersonality::Unknown;
return StringSwitch<EHPersonality>(F->getName())
- .Case("__gnat_eh_personality", EHPersonality::GNU_Ada)
- .Case("__gxx_personality_v0", EHPersonality::GNU_CXX)
- .Case("__gxx_personality_seh0", EHPersonality::GNU_CXX)
- .Case("__gxx_personality_sj0", EHPersonality::GNU_CXX_SjLj)
- .Case("__gcc_personality_v0", EHPersonality::GNU_C)
- .Case("__gcc_personality_seh0", EHPersonality::GNU_C)
- .Case("__gcc_personality_sj0", EHPersonality::GNU_C_SjLj)
- .Case("__objc_personality_v0", EHPersonality::GNU_ObjC)
- .Case("_except_handler3", EHPersonality::MSVC_X86SEH)
- .Case("_except_handler4", EHPersonality::MSVC_X86SEH)
- .Case("__C_specific_handler", EHPersonality::MSVC_TableSEH)
- .Case("__CxxFrameHandler3", EHPersonality::MSVC_CXX)
- .Case("ProcessCLRException", EHPersonality::CoreCLR)
- .Case("rust_eh_personality", EHPersonality::Rust)
- .Case("__gxx_wasm_personality_v0", EHPersonality::Wasm_CXX)
- .Case("__xlcxx_personality_v1", EHPersonality::XL_CXX)
- .Default(EHPersonality::Unknown);
+ .Case("__gnat_eh_personality", EHPersonality::GNU_Ada)
+ .Case("__gxx_personality_v0", EHPersonality::GNU_CXX)
+ .Case("__gxx_personality_seh0", EHPersonality::GNU_CXX)
+ .Case("__gxx_personality_sj0", EHPersonality::GNU_CXX_SjLj)
+ .Case("__gcc_personality_v0", EHPersonality::GNU_C)
+ .Case("__gcc_personality_seh0", EHPersonality::GNU_C)
+ .Case("__gcc_personality_sj0", EHPersonality::GNU_C_SjLj)
+ .Case("__objc_personality_v0", EHPersonality::GNU_ObjC)
+ .Case("_except_handler3", EHPersonality::MSVC_X86SEH)
+ .Case("_except_handler4", EHPersonality::MSVC_X86SEH)
+ .Case("__C_specific_handler", EHPersonality::MSVC_TableSEH)
+ .Case("__CxxFrameHandler3", EHPersonality::MSVC_CXX)
+ .Case("ProcessCLRException", EHPersonality::CoreCLR)
+ .Case("rust_eh_personality", EHPersonality::Rust)
+ .Case("__gxx_wasm_personality_v0", EHPersonality::Wasm_CXX)
+ .Case("__xlcxx_personality_v1", EHPersonality::XL_CXX)
+ .Default(EHPersonality::Unknown);
}
StringRef llvm::getEHPersonalityName(EHPersonality Pers) {
@@ -52,14 +52,14 @@ StringRef llvm::getEHPersonalityName(EHPersonality Pers) {
case EHPersonality::GNU_C_SjLj: return "__gcc_personality_sj0";
case EHPersonality::GNU_ObjC: return "__objc_personality_v0";
case EHPersonality::MSVC_X86SEH: return "_except_handler3";
- case EHPersonality::MSVC_TableSEH:
- return "__C_specific_handler";
+ case EHPersonality::MSVC_TableSEH:
+ return "__C_specific_handler";
case EHPersonality::MSVC_CXX: return "__CxxFrameHandler3";
case EHPersonality::CoreCLR: return "ProcessCLRException";
case EHPersonality::Rust: return "rust_eh_personality";
case EHPersonality::Wasm_CXX: return "__gxx_wasm_personality_v0";
- case EHPersonality::XL_CXX:
- return "__xlcxx_personality_v1";
+ case EHPersonality::XL_CXX:
+ return "__xlcxx_personality_v1";
case EHPersonality::Unknown: llvm_unreachable("Unknown EHPersonality!");
}
diff --git a/contrib/libs/llvm12/lib/Analysis/FunctionPropertiesAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/FunctionPropertiesAnalysis.cpp
index 037c18853a..33519038e2 100644
--- a/contrib/libs/llvm12/lib/Analysis/FunctionPropertiesAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/FunctionPropertiesAnalysis.cpp
@@ -1,88 +1,88 @@
-//===- FunctionPropertiesAnalysis.cpp - Function Properties Analysis ------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the FunctionPropertiesInfo and FunctionPropertiesAnalysis
-// classes used to extract function properties.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/FunctionPropertiesAnalysis.h"
-#include "llvm/IR/Instructions.h"
-
-using namespace llvm;
-
-FunctionPropertiesInfo
-FunctionPropertiesInfo::getFunctionPropertiesInfo(const Function &F,
- const LoopInfo &LI) {
-
- FunctionPropertiesInfo FPI;
-
- FPI.Uses = ((!F.hasLocalLinkage()) ? 1 : 0) + F.getNumUses();
-
- for (const auto &BB : F) {
- ++FPI.BasicBlockCount;
-
- if (const auto *BI = dyn_cast<BranchInst>(BB.getTerminator())) {
- if (BI->isConditional())
- FPI.BlocksReachedFromConditionalInstruction += BI->getNumSuccessors();
- } else if (const auto *SI = dyn_cast<SwitchInst>(BB.getTerminator())) {
- FPI.BlocksReachedFromConditionalInstruction +=
- (SI->getNumCases() + (nullptr != SI->getDefaultDest()));
- }
-
- for (const auto &I : BB) {
- if (auto *CS = dyn_cast<CallBase>(&I)) {
- const auto *Callee = CS->getCalledFunction();
- if (Callee && !Callee->isIntrinsic() && !Callee->isDeclaration())
- ++FPI.DirectCallsToDefinedFunctions;
- }
- if (I.getOpcode() == Instruction::Load) {
- ++FPI.LoadInstCount;
- } else if (I.getOpcode() == Instruction::Store) {
- ++FPI.StoreInstCount;
- }
- }
- // Loop Depth of the Basic Block
- int64_t LoopDepth;
- LoopDepth = LI.getLoopDepth(&BB);
- if (FPI.MaxLoopDepth < LoopDepth)
- FPI.MaxLoopDepth = LoopDepth;
- }
- FPI.TopLevelLoopCount += llvm::size(LI);
- return FPI;
-}
-
-void FunctionPropertiesInfo::print(raw_ostream &OS) const {
- OS << "BasicBlockCount: " << BasicBlockCount << "\n"
- << "BlocksReachedFromConditionalInstruction: "
- << BlocksReachedFromConditionalInstruction << "\n"
- << "Uses: " << Uses << "\n"
- << "DirectCallsToDefinedFunctions: " << DirectCallsToDefinedFunctions
- << "\n"
- << "LoadInstCount: " << LoadInstCount << "\n"
- << "StoreInstCount: " << StoreInstCount << "\n"
- << "MaxLoopDepth: " << MaxLoopDepth << "\n"
- << "TopLevelLoopCount: " << TopLevelLoopCount << "\n\n";
-}
-
-AnalysisKey FunctionPropertiesAnalysis::Key;
-
-FunctionPropertiesInfo
-FunctionPropertiesAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
- return FunctionPropertiesInfo::getFunctionPropertiesInfo(
- F, FAM.getResult<LoopAnalysis>(F));
-}
-
-PreservedAnalyses
-FunctionPropertiesPrinterPass::run(Function &F, FunctionAnalysisManager &AM) {
- OS << "Printing analysis results of CFA for function "
- << "'" << F.getName() << "':"
- << "\n";
- AM.getResult<FunctionPropertiesAnalysis>(F).print(OS);
- return PreservedAnalyses::all();
-}
+//===- FunctionPropertiesAnalysis.cpp - Function Properties Analysis ------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the FunctionPropertiesInfo and FunctionPropertiesAnalysis
+// classes used to extract function properties.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/FunctionPropertiesAnalysis.h"
+#include "llvm/IR/Instructions.h"
+
+using namespace llvm;
+
+FunctionPropertiesInfo
+FunctionPropertiesInfo::getFunctionPropertiesInfo(const Function &F,
+ const LoopInfo &LI) {
+
+ FunctionPropertiesInfo FPI;
+
+ FPI.Uses = ((!F.hasLocalLinkage()) ? 1 : 0) + F.getNumUses();
+
+ for (const auto &BB : F) {
+ ++FPI.BasicBlockCount;
+
+ if (const auto *BI = dyn_cast<BranchInst>(BB.getTerminator())) {
+ if (BI->isConditional())
+ FPI.BlocksReachedFromConditionalInstruction += BI->getNumSuccessors();
+ } else if (const auto *SI = dyn_cast<SwitchInst>(BB.getTerminator())) {
+ FPI.BlocksReachedFromConditionalInstruction +=
+ (SI->getNumCases() + (nullptr != SI->getDefaultDest()));
+ }
+
+ for (const auto &I : BB) {
+ if (auto *CS = dyn_cast<CallBase>(&I)) {
+ const auto *Callee = CS->getCalledFunction();
+ if (Callee && !Callee->isIntrinsic() && !Callee->isDeclaration())
+ ++FPI.DirectCallsToDefinedFunctions;
+ }
+ if (I.getOpcode() == Instruction::Load) {
+ ++FPI.LoadInstCount;
+ } else if (I.getOpcode() == Instruction::Store) {
+ ++FPI.StoreInstCount;
+ }
+ }
+ // Loop Depth of the Basic Block
+ int64_t LoopDepth;
+ LoopDepth = LI.getLoopDepth(&BB);
+ if (FPI.MaxLoopDepth < LoopDepth)
+ FPI.MaxLoopDepth = LoopDepth;
+ }
+ FPI.TopLevelLoopCount += llvm::size(LI);
+ return FPI;
+}
+
+void FunctionPropertiesInfo::print(raw_ostream &OS) const {
+ OS << "BasicBlockCount: " << BasicBlockCount << "\n"
+ << "BlocksReachedFromConditionalInstruction: "
+ << BlocksReachedFromConditionalInstruction << "\n"
+ << "Uses: " << Uses << "\n"
+ << "DirectCallsToDefinedFunctions: " << DirectCallsToDefinedFunctions
+ << "\n"
+ << "LoadInstCount: " << LoadInstCount << "\n"
+ << "StoreInstCount: " << StoreInstCount << "\n"
+ << "MaxLoopDepth: " << MaxLoopDepth << "\n"
+ << "TopLevelLoopCount: " << TopLevelLoopCount << "\n\n";
+}
+
+AnalysisKey FunctionPropertiesAnalysis::Key;
+
+FunctionPropertiesInfo
+FunctionPropertiesAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
+ return FunctionPropertiesInfo::getFunctionPropertiesInfo(
+ F, FAM.getResult<LoopAnalysis>(F));
+}
+
+PreservedAnalyses
+FunctionPropertiesPrinterPass::run(Function &F, FunctionAnalysisManager &AM) {
+ OS << "Printing analysis results of CFA for function "
+ << "'" << F.getName() << "':"
+ << "\n";
+ AM.getResult<FunctionPropertiesAnalysis>(F).print(OS);
+ return PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Analysis/GlobalsModRef.cpp b/contrib/libs/llvm12/lib/Analysis/GlobalsModRef.cpp
index d03e35fcfe..145baf82b6 100644
--- a/contrib/libs/llvm12/lib/Analysis/GlobalsModRef.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/GlobalsModRef.cpp
@@ -44,7 +44,7 @@ STATISTIC(NumIndirectGlobalVars, "Number of indirect global objects");
// An option to enable unsafe alias results from the GlobalsModRef analysis.
// When enabled, GlobalsModRef will provide no-alias results which in extremely
// rare cases may not be conservatively correct. In particular, in the face of
-// transforms which cause asymmetry between how effective getUnderlyingObject
+// transforms which cause asymmetry between how effective getUnderlyingObject
// is for two pointers, it may produce incorrect results.
//
// These unsafe results have been returned by GMR for many years without
@@ -367,8 +367,8 @@ bool GlobalsAAResult::AnalyzeUsesOfPointer(Value *V,
} else if (Operator::getOpcode(I) == Instruction::GetElementPtr) {
if (AnalyzeUsesOfPointer(I, Readers, Writers))
return true;
- } else if (Operator::getOpcode(I) == Instruction::BitCast ||
- Operator::getOpcode(I) == Instruction::AddrSpaceCast) {
+ } else if (Operator::getOpcode(I) == Instruction::BitCast ||
+ Operator::getOpcode(I) == Instruction::AddrSpaceCast) {
if (AnalyzeUsesOfPointer(I, Readers, Writers, OkayStoreDest))
return true;
} else if (auto *Call = dyn_cast<CallBase>(I)) {
@@ -436,7 +436,7 @@ bool GlobalsAAResult::AnalyzeIndirectGlobalMemory(GlobalVariable *GV) {
continue;
// Check the value being stored.
- Value *Ptr = getUnderlyingObject(SI->getOperand(0));
+ Value *Ptr = getUnderlyingObject(SI->getOperand(0));
if (!isAllocLikeFn(Ptr, &GetTLI(*SI->getFunction())))
return false; // Too hard to analyze.
@@ -661,12 +661,12 @@ static bool isNonEscapingGlobalNoAliasWithLoad(const GlobalValue *GV,
return false;
if (auto *LI = dyn_cast<LoadInst>(Input)) {
- Inputs.push_back(getUnderlyingObject(LI->getPointerOperand()));
+ Inputs.push_back(getUnderlyingObject(LI->getPointerOperand()));
continue;
}
if (auto *SI = dyn_cast<SelectInst>(Input)) {
- const Value *LHS = getUnderlyingObject(SI->getTrueValue());
- const Value *RHS = getUnderlyingObject(SI->getFalseValue());
+ const Value *LHS = getUnderlyingObject(SI->getTrueValue());
+ const Value *RHS = getUnderlyingObject(SI->getFalseValue());
if (Visited.insert(LHS).second)
Inputs.push_back(LHS);
if (Visited.insert(RHS).second)
@@ -675,7 +675,7 @@ static bool isNonEscapingGlobalNoAliasWithLoad(const GlobalValue *GV,
}
if (auto *PN = dyn_cast<PHINode>(Input)) {
for (const Value *Op : PN->incoming_values()) {
- Op = getUnderlyingObject(Op);
+ Op = getUnderlyingObject(Op);
if (Visited.insert(Op).second)
Inputs.push_back(Op);
}
@@ -774,7 +774,7 @@ bool GlobalsAAResult::isNonEscapingGlobalNoAlias(const GlobalValue *GV,
if (auto *LI = dyn_cast<LoadInst>(Input)) {
// A pointer loaded from a global would have been captured, and we know
// that the global is non-escaping, so no alias.
- const Value *Ptr = getUnderlyingObject(LI->getPointerOperand());
+ const Value *Ptr = getUnderlyingObject(LI->getPointerOperand());
if (isNonEscapingGlobalNoAliasWithLoad(GV, Ptr, Depth, DL))
// The load does not alias with GV.
continue;
@@ -782,8 +782,8 @@ bool GlobalsAAResult::isNonEscapingGlobalNoAlias(const GlobalValue *GV,
return false;
}
if (auto *SI = dyn_cast<SelectInst>(Input)) {
- const Value *LHS = getUnderlyingObject(SI->getTrueValue());
- const Value *RHS = getUnderlyingObject(SI->getFalseValue());
+ const Value *LHS = getUnderlyingObject(SI->getTrueValue());
+ const Value *RHS = getUnderlyingObject(SI->getFalseValue());
if (Visited.insert(LHS).second)
Inputs.push_back(LHS);
if (Visited.insert(RHS).second)
@@ -792,7 +792,7 @@ bool GlobalsAAResult::isNonEscapingGlobalNoAlias(const GlobalValue *GV,
}
if (auto *PN = dyn_cast<PHINode>(Input)) {
for (const Value *Op : PN->incoming_values()) {
- Op = getUnderlyingObject(Op);
+ Op = getUnderlyingObject(Op);
if (Visited.insert(Op).second)
Inputs.push_back(Op);
}
@@ -827,10 +827,10 @@ AliasResult GlobalsAAResult::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB,
AAQueryInfo &AAQI) {
// Get the base object these pointers point to.
- const Value *UV1 =
- getUnderlyingObject(LocA.Ptr->stripPointerCastsAndInvariantGroups());
- const Value *UV2 =
- getUnderlyingObject(LocB.Ptr->stripPointerCastsAndInvariantGroups());
+ const Value *UV1 =
+ getUnderlyingObject(LocA.Ptr->stripPointerCastsAndInvariantGroups());
+ const Value *UV2 =
+ getUnderlyingObject(LocB.Ptr->stripPointerCastsAndInvariantGroups());
// If either of the underlying values is a global, they may be non-addr-taken
// globals, which we can answer queries about.
@@ -917,15 +917,15 @@ ModRefInfo GlobalsAAResult::getModRefInfoForArgument(const CallBase *Call,
// is based on GV, return the conservative result.
for (auto &A : Call->args()) {
SmallVector<const Value*, 4> Objects;
- getUnderlyingObjects(A, Objects);
+ getUnderlyingObjects(A, Objects);
// All objects must be identified.
if (!all_of(Objects, isIdentifiedObject) &&
// Try ::alias to see if all objects are known not to alias GV.
!all_of(Objects, [&](const Value *V) {
- return this->alias(MemoryLocation::getBeforeOrAfter(V),
- MemoryLocation::getBeforeOrAfter(GV),
- AAQI) == NoAlias;
+ return this->alias(MemoryLocation::getBeforeOrAfter(V),
+ MemoryLocation::getBeforeOrAfter(GV),
+ AAQI) == NoAlias;
}))
return ConservativeResult;
@@ -945,7 +945,7 @@ ModRefInfo GlobalsAAResult::getModRefInfo(const CallBase *Call,
// If we are asking for mod/ref info of a direct call with a pointer to a
// global we are tracking, return information if we have it.
if (const GlobalValue *GV =
- dyn_cast<GlobalValue>(getUnderlyingObject(Loc.Ptr)))
+ dyn_cast<GlobalValue>(getUnderlyingObject(Loc.Ptr)))
// If GV is internal to this IR and there is no function with local linkage
// that has had their address taken, keep looking for a tighter ModRefInfo.
if (GV->hasLocalLinkage() && !UnknownFunctionsWithLocalLinkage)
diff --git a/contrib/libs/llvm12/lib/Analysis/IRSimilarityIdentifier.cpp b/contrib/libs/llvm12/lib/Analysis/IRSimilarityIdentifier.cpp
index 751c8ddc9b..25443a6679 100644
--- a/contrib/libs/llvm12/lib/Analysis/IRSimilarityIdentifier.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/IRSimilarityIdentifier.cpp
@@ -1,937 +1,937 @@
-//===- IRSimilarityIdentifier.cpp - Find similarity in a module -----------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// \file
-// Implementation file for the IRSimilarityIdentifier for identifying
-// similarities in IR including the IRInstructionMapper.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/IRSimilarityIdentifier.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/IR/Intrinsics.h"
-#include "llvm/IR/Operator.h"
-#include "llvm/IR/User.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Support/SuffixTree.h"
-
-using namespace llvm;
-using namespace IRSimilarity;
-
-IRInstructionData::IRInstructionData(Instruction &I, bool Legality,
- IRInstructionDataList &IDList)
- : Inst(&I), Legal(Legality), IDL(&IDList) {
- // We check for whether we have a comparison instruction. If it is, we
- // find the "less than" version of the predicate for consistency for
- // comparison instructions throught the program.
- if (CmpInst *C = dyn_cast<CmpInst>(&I)) {
- CmpInst::Predicate Predicate = predicateForConsistency(C);
- if (Predicate != C->getPredicate())
- RevisedPredicate = Predicate;
- }
-
- // Here we collect the operands and their types for determining whether
- // the structure of the operand use matches between two different candidates.
- for (Use &OI : I.operands()) {
- if (isa<CmpInst>(I) && RevisedPredicate.hasValue()) {
- // If we have a CmpInst where the predicate is reversed, it means the
- // operands must be reversed as well.
- OperVals.insert(OperVals.begin(), OI.get());
- continue;
- }
-
- OperVals.push_back(OI.get());
- }
-}
-
-CmpInst::Predicate IRInstructionData::predicateForConsistency(CmpInst *CI) {
- switch (CI->getPredicate()) {
- case CmpInst::FCMP_OGT:
- case CmpInst::FCMP_UGT:
- case CmpInst::FCMP_OGE:
- case CmpInst::FCMP_UGE:
- case CmpInst::ICMP_SGT:
- case CmpInst::ICMP_UGT:
- case CmpInst::ICMP_SGE:
- case CmpInst::ICMP_UGE:
- return CI->getSwappedPredicate();
- default:
- return CI->getPredicate();
- }
-}
-
-CmpInst::Predicate IRInstructionData::getPredicate() const {
- assert(isa<CmpInst>(Inst) &&
- "Can only get a predicate from a compare instruction");
-
- if (RevisedPredicate.hasValue())
- return RevisedPredicate.getValue();
-
- return cast<CmpInst>(Inst)->getPredicate();
-}
-
-static StringRef getCalledFunctionName(CallInst &CI) {
- assert(CI.getCalledFunction() != nullptr && "Called Function is nullptr?");
-
- return CI.getCalledFunction()->getName();
-}
-
-bool IRSimilarity::isClose(const IRInstructionData &A,
- const IRInstructionData &B) {
-
- if (!A.Legal || !B.Legal)
- return false;
-
- // Check if we are performing the same sort of operation on the same types
- // but not on the same values.
- if (!A.Inst->isSameOperationAs(B.Inst)) {
- // If there is a predicate, this means that either there is a swapped
- // predicate, or that the types are different, we want to make sure that
- // the predicates are equivalent via swapping.
- if (isa<CmpInst>(A.Inst) && isa<CmpInst>(B.Inst)) {
-
- if (A.getPredicate() != B.getPredicate())
- return false;
-
- // If the predicates are the same via swap, make sure that the types are
- // still the same.
- auto ZippedTypes = zip(A.OperVals, B.OperVals);
-
- return all_of(
- ZippedTypes, [](std::tuple<llvm::Value *, llvm::Value *> R) {
- return std::get<0>(R)->getType() == std::get<1>(R)->getType();
- });
- }
-
- return false;
- }
-
- // Since any GEP Instruction operands after the first operand cannot be
- // defined by a register, we must make sure that the operands after the first
- // are the same in the two instructions
- if (auto *GEP = dyn_cast<GetElementPtrInst>(A.Inst)) {
- auto *OtherGEP = cast<GetElementPtrInst>(B.Inst);
-
- // If the instructions do not have the same inbounds restrictions, we do
- // not consider them the same.
- if (GEP->isInBounds() != OtherGEP->isInBounds())
- return false;
-
- auto ZippedOperands = zip(GEP->indices(), OtherGEP->indices());
-
- // We increment here since we do not care about the first instruction,
- // we only care about the following operands since they must be the
- // exact same to be considered similar.
- return all_of(drop_begin(ZippedOperands),
- [](std::tuple<llvm::Use &, llvm::Use &> R) {
- return std::get<0>(R) == std::get<1>(R);
- });
- }
-
- // If the instructions are functions, we make sure that the function name is
- // the same. We already know that the types are since is isSameOperationAs is
- // true.
- if (isa<CallInst>(A.Inst) && isa<CallInst>(B.Inst)) {
- CallInst *CIA = cast<CallInst>(A.Inst);
- CallInst *CIB = cast<CallInst>(B.Inst);
- if (getCalledFunctionName(*CIA).compare(getCalledFunctionName(*CIB)) != 0)
- return false;
- }
-
- return true;
-}
-
-// TODO: This is the same as the MachineOutliner, and should be consolidated
-// into the same interface.
-void IRInstructionMapper::convertToUnsignedVec(
- BasicBlock &BB, std::vector<IRInstructionData *> &InstrList,
- std::vector<unsigned> &IntegerMapping) {
- BasicBlock::iterator It = BB.begin();
-
- std::vector<unsigned> IntegerMappingForBB;
- std::vector<IRInstructionData *> InstrListForBB;
-
- HaveLegalRange = false;
- CanCombineWithPrevInstr = false;
- AddedIllegalLastTime = true;
-
- for (BasicBlock::iterator Et = BB.end(); It != Et; ++It) {
- switch (InstClassifier.visit(*It)) {
- case InstrType::Legal:
- mapToLegalUnsigned(It, IntegerMappingForBB, InstrListForBB);
- break;
- case InstrType::Illegal:
- mapToIllegalUnsigned(It, IntegerMappingForBB, InstrListForBB);
- break;
- case InstrType::Invisible:
- AddedIllegalLastTime = false;
- break;
- }
- }
-
- if (HaveLegalRange) {
- mapToIllegalUnsigned(It, IntegerMappingForBB, InstrListForBB, true);
- for_each(InstrListForBB,
- [this](IRInstructionData *ID) { this->IDL->push_back(*ID); });
- llvm::append_range(InstrList, InstrListForBB);
- llvm::append_range(IntegerMapping, IntegerMappingForBB);
- }
-}
-
-// TODO: This is the same as the MachineOutliner, and should be consolidated
-// into the same interface.
-unsigned IRInstructionMapper::mapToLegalUnsigned(
- BasicBlock::iterator &It, std::vector<unsigned> &IntegerMappingForBB,
- std::vector<IRInstructionData *> &InstrListForBB) {
- // We added something legal, so we should unset the AddedLegalLastTime
- // flag.
- AddedIllegalLastTime = false;
-
- // If we have at least two adjacent legal instructions (which may have
- // invisible instructions in between), remember that.
- if (CanCombineWithPrevInstr)
- HaveLegalRange = true;
- CanCombineWithPrevInstr = true;
-
- // Get the integer for this instruction or give it the current
- // LegalInstrNumber.
- IRInstructionData *ID = allocateIRInstructionData(*It, true, *IDL);
- InstrListForBB.push_back(ID);
-
- // Add to the instruction list
- bool WasInserted;
- DenseMap<IRInstructionData *, unsigned, IRInstructionDataTraits>::iterator
- ResultIt;
- std::tie(ResultIt, WasInserted) =
- InstructionIntegerMap.insert(std::make_pair(ID, LegalInstrNumber));
- unsigned INumber = ResultIt->second;
-
- // There was an insertion.
- if (WasInserted)
- LegalInstrNumber++;
-
- IntegerMappingForBB.push_back(INumber);
-
- // Make sure we don't overflow or use any integers reserved by the DenseMap.
- assert(LegalInstrNumber < IllegalInstrNumber &&
- "Instruction mapping overflow!");
-
- assert(LegalInstrNumber != DenseMapInfo<unsigned>::getEmptyKey() &&
- "Tried to assign DenseMap tombstone or empty key to instruction.");
- assert(LegalInstrNumber != DenseMapInfo<unsigned>::getTombstoneKey() &&
- "Tried to assign DenseMap tombstone or empty key to instruction.");
-
- return INumber;
-}
-
-IRInstructionData *
-IRInstructionMapper::allocateIRInstructionData(Instruction &I, bool Legality,
- IRInstructionDataList &IDL) {
- return new (InstDataAllocator->Allocate()) IRInstructionData(I, Legality, IDL);
-}
-
-IRInstructionDataList *
-IRInstructionMapper::allocateIRInstructionDataList() {
- return new (IDLAllocator->Allocate()) IRInstructionDataList();
-}
-
-// TODO: This is the same as the MachineOutliner, and should be consolidated
-// into the same interface.
-unsigned IRInstructionMapper::mapToIllegalUnsigned(
- BasicBlock::iterator &It, std::vector<unsigned> &IntegerMappingForBB,
- std::vector<IRInstructionData *> &InstrListForBB, bool End) {
- // Can't combine an illegal instruction. Set the flag.
- CanCombineWithPrevInstr = false;
-
- // Only add one illegal number per range of legal numbers.
- if (AddedIllegalLastTime)
- return IllegalInstrNumber;
-
- IRInstructionData *ID = nullptr;
- if (!End)
- ID = allocateIRInstructionData(*It, false, *IDL);
- InstrListForBB.push_back(ID);
-
- // Remember that we added an illegal number last time.
- AddedIllegalLastTime = true;
- unsigned INumber = IllegalInstrNumber;
- IntegerMappingForBB.push_back(IllegalInstrNumber--);
-
- assert(LegalInstrNumber < IllegalInstrNumber &&
- "Instruction mapping overflow!");
-
- assert(IllegalInstrNumber != DenseMapInfo<unsigned>::getEmptyKey() &&
- "IllegalInstrNumber cannot be DenseMap tombstone or empty key!");
-
- assert(IllegalInstrNumber != DenseMapInfo<unsigned>::getTombstoneKey() &&
- "IllegalInstrNumber cannot be DenseMap tombstone or empty key!");
-
- return INumber;
-}
-
-IRSimilarityCandidate::IRSimilarityCandidate(unsigned StartIdx, unsigned Len,
- IRInstructionData *FirstInstIt,
- IRInstructionData *LastInstIt)
- : StartIdx(StartIdx), Len(Len) {
-
- assert(FirstInstIt != nullptr && "Instruction is nullptr!");
- assert(LastInstIt != nullptr && "Instruction is nullptr!");
- assert(StartIdx + Len > StartIdx &&
- "Overflow for IRSimilarityCandidate range?");
- assert(Len - 1 == static_cast<unsigned>(std::distance(
- iterator(FirstInstIt), iterator(LastInstIt))) &&
- "Length of the first and last IRInstructionData do not match the "
- "given length");
-
- // We iterate over the given instructions, and map each unique value
- // to a unique number in the IRSimilarityCandidate ValueToNumber and
- // NumberToValue maps. A constant get its own value globally, the individual
- // uses of the constants are not considered to be unique.
- //
- // IR: Mapping Added:
- // %add1 = add i32 %a, c1 %add1 -> 3, %a -> 1, c1 -> 2
- // %add2 = add i32 %a, %1 %add2 -> 4
- // %add3 = add i32 c2, c1 %add3 -> 6, c2 -> 5
- //
- // when replace with global values, starting from 1, would be
- //
- // 3 = add i32 1, 2
- // 4 = add i32 1, 3
- // 6 = add i32 5, 2
- unsigned LocalValNumber = 1;
- IRInstructionDataList::iterator ID = iterator(*FirstInstIt);
- for (unsigned Loc = StartIdx; Loc < StartIdx + Len; Loc++, ID++) {
- // Map the operand values to an unsigned integer if it does not already
- // have an unsigned integer assigned to it.
- for (Value *Arg : ID->OperVals)
- if (ValueToNumber.find(Arg) == ValueToNumber.end()) {
- ValueToNumber.try_emplace(Arg, LocalValNumber);
- NumberToValue.try_emplace(LocalValNumber, Arg);
- LocalValNumber++;
- }
-
- // Mapping the instructions to an unsigned integer if it is not already
- // exist in the mapping.
- if (ValueToNumber.find(ID->Inst) == ValueToNumber.end()) {
- ValueToNumber.try_emplace(ID->Inst, LocalValNumber);
- NumberToValue.try_emplace(LocalValNumber, ID->Inst);
- LocalValNumber++;
- }
- }
-
- // Setting the first and last instruction data pointers for the candidate. If
- // we got through the entire for loop without hitting an assert, we know
- // that both of these instructions are not nullptrs.
- FirstInst = FirstInstIt;
- LastInst = LastInstIt;
-}
-
-bool IRSimilarityCandidate::isSimilar(const IRSimilarityCandidate &A,
- const IRSimilarityCandidate &B) {
- if (A.getLength() != B.getLength())
- return false;
-
- auto InstrDataForBoth =
- zip(make_range(A.begin(), A.end()), make_range(B.begin(), B.end()));
-
- return all_of(InstrDataForBoth,
- [](std::tuple<IRInstructionData &, IRInstructionData &> R) {
- IRInstructionData &A = std::get<0>(R);
- IRInstructionData &B = std::get<1>(R);
- if (!A.Legal || !B.Legal)
- return false;
- return isClose(A, B);
- });
-}
-
-/// Determine if one or more of the assigned global value numbers for the
-/// operands in \p TargetValueNumbers is in the current mapping set for operand
-/// numbers in \p SourceOperands. The set of possible corresponding global
-/// value numbers are replaced with the most recent version of compatible
-/// values.
-///
-/// \param [in] SourceValueToNumberMapping - The mapping of a Value to global
-/// value number for the source IRInstructionCandidate.
-/// \param [in, out] CurrentSrcTgtNumberMapping - The current mapping of source
-/// IRSimilarityCandidate global value numbers to a set of possible numbers in
-/// the target.
-/// \param [in] SourceOperands - The operands in the original
-/// IRSimilarityCandidate in the current instruction.
-/// \param [in] TargetValueNumbers - The global value numbers of the operands in
-/// the corresponding Instruction in the other IRSimilarityCandidate.
-/// \returns true if there exists a possible mapping between the source
-/// Instruction operands and the target Instruction operands, and false if not.
-static bool checkNumberingAndReplaceCommutative(
- const DenseMap<Value *, unsigned> &SourceValueToNumberMapping,
- DenseMap<unsigned, DenseSet<unsigned>> &CurrentSrcTgtNumberMapping,
- ArrayRef<Value *> &SourceOperands,
- DenseSet<unsigned> &TargetValueNumbers){
-
- DenseMap<unsigned, DenseSet<unsigned>>::iterator ValueMappingIt;
-
- unsigned ArgVal;
- bool WasInserted;
-
- // Iterate over the operands in the source IRSimilarityCandidate to determine
- // whether there exists an operand in the other IRSimilarityCandidate that
- // creates a valid mapping of Value to Value between the
- // IRSimilarityCaniddates.
- for (Value *V : SourceOperands) {
- ArgVal = SourceValueToNumberMapping.find(V)->second;
-
- std::tie(ValueMappingIt, WasInserted) = CurrentSrcTgtNumberMapping.insert(
- std::make_pair(ArgVal, TargetValueNumbers));
-
- // Instead of finding a current mapping, we inserted a set. This means a
- // mapping did not exist for the source Instruction operand, it has no
- // current constraints we need to check.
- if (WasInserted)
- continue;
-
- // If a mapping already exists for the source operand to the values in the
- // other IRSimilarityCandidate we need to iterate over the items in other
- // IRSimilarityCandidate's Instruction to determine whether there is a valid
- // mapping of Value to Value.
- DenseSet<unsigned> NewSet;
- for (unsigned &Curr : ValueMappingIt->second)
- // If we can find the value in the mapping, we add it to the new set.
- if (TargetValueNumbers.contains(Curr))
- NewSet.insert(Curr);
-
- // If we could not find a Value, return 0.
- if (NewSet.empty())
- return false;
-
- // Otherwise replace the old mapping with the newly constructed one.
- if (NewSet.size() != ValueMappingIt->second.size())
- ValueMappingIt->second.swap(NewSet);
-
- // We have reached no conclusions about the mapping, and cannot remove
- // any items from the other operands, so we move to check the next operand.
- if (ValueMappingIt->second.size() != 1)
- continue;
-
-
- unsigned ValToRemove = *ValueMappingIt->second.begin();
- // When there is only one item left in the mapping for and operand, remove
- // the value from the other operands. If it results in there being no
- // mapping, return false, it means the mapping is wrong
- for (Value *InnerV : SourceOperands) {
- if (V == InnerV)
- continue;
-
- unsigned InnerVal = SourceValueToNumberMapping.find(InnerV)->second;
- ValueMappingIt = CurrentSrcTgtNumberMapping.find(InnerVal);
- if (ValueMappingIt == CurrentSrcTgtNumberMapping.end())
- continue;
-
- ValueMappingIt->second.erase(ValToRemove);
- if (ValueMappingIt->second.empty())
- return false;
- }
- }
-
- return true;
-}
-
-/// Determine if operand number \p TargetArgVal is in the current mapping set
-/// for operand number \p SourceArgVal.
-///
-/// \param [in, out] CurrentSrcTgtNumberMapping current mapping of global
-/// value numbers from source IRSimilarityCandidate to target
-/// IRSimilarityCandidate.
-/// \param [in] SourceArgVal The global value number for an operand in the
-/// in the original candidate.
-/// \param [in] TargetArgVal The global value number for the corresponding
-/// operand in the other candidate.
-/// \returns True if there exists a mapping and false if not.
-bool checkNumberingAndReplace(
- DenseMap<unsigned, DenseSet<unsigned>> &CurrentSrcTgtNumberMapping,
- unsigned SourceArgVal, unsigned TargetArgVal) {
- // We are given two unsigned integers representing the global values of
- // the operands in different IRSimilarityCandidates and a current mapping
- // between the two.
- //
- // Source Operand GVN: 1
- // Target Operand GVN: 2
- // CurrentMapping: {1: {1, 2}}
- //
- // Since we have mapping, and the target operand is contained in the set, we
- // update it to:
- // CurrentMapping: {1: {2}}
- // and can return true. But, if the mapping was
- // CurrentMapping: {1: {3}}
- // we would return false.
-
- bool WasInserted;
- DenseMap<unsigned, DenseSet<unsigned>>::iterator Val;
-
- std::tie(Val, WasInserted) = CurrentSrcTgtNumberMapping.insert(
- std::make_pair(SourceArgVal, DenseSet<unsigned>({TargetArgVal})));
-
- // If we created a new mapping, then we are done.
- if (WasInserted)
- return true;
-
- // If there is more than one option in the mapping set, and the target value
- // is included in the mapping set replace that set with one that only includes
- // the target value, as it is the only valid mapping via the non commutative
- // instruction.
-
- DenseSet<unsigned> &TargetSet = Val->second;
- if (TargetSet.size() > 1 && TargetSet.contains(TargetArgVal)) {
- TargetSet.clear();
- TargetSet.insert(TargetArgVal);
- return true;
- }
-
- // Return true if we can find the value in the set.
- return TargetSet.contains(TargetArgVal);
-}
-
-bool IRSimilarityCandidate::compareNonCommutativeOperandMapping(
- OperandMapping A, OperandMapping B) {
- // Iterators to keep track of where we are in the operands for each
- // Instruction.
- ArrayRef<Value *>::iterator VItA = A.OperVals.begin();
- ArrayRef<Value *>::iterator VItB = B.OperVals.begin();
- unsigned OperandLength = A.OperVals.size();
-
- // For each operand, get the value numbering and ensure it is consistent.
- for (unsigned Idx = 0; Idx < OperandLength; Idx++, VItA++, VItB++) {
- unsigned OperValA = A.IRSC.ValueToNumber.find(*VItA)->second;
- unsigned OperValB = B.IRSC.ValueToNumber.find(*VItB)->second;
-
- // Attempt to add a set with only the target value. If there is no mapping
- // we can create it here.
- //
- // For an instruction like a subtraction:
- // IRSimilarityCandidateA: IRSimilarityCandidateB:
- // %resultA = sub %a, %b %resultB = sub %d, %e
- //
- // We map %a -> %d and %b -> %e.
- //
- // And check to see whether their mapping is consistent in
- // checkNumberingAndReplace.
-
- if (!checkNumberingAndReplace(A.ValueNumberMapping, OperValA, OperValB))
- return false;
-
- if (!checkNumberingAndReplace(B.ValueNumberMapping, OperValB, OperValA))
- return false;
- }
- return true;
-}
-
-bool IRSimilarityCandidate::compareCommutativeOperandMapping(
- OperandMapping A, OperandMapping B) {
- DenseSet<unsigned> ValueNumbersA;
- DenseSet<unsigned> ValueNumbersB;
-
- ArrayRef<Value *>::iterator VItA = A.OperVals.begin();
- ArrayRef<Value *>::iterator VItB = B.OperVals.begin();
- unsigned OperandLength = A.OperVals.size();
-
- // Find the value number sets for the operands.
- for (unsigned Idx = 0; Idx < OperandLength;
- Idx++, VItA++, VItB++) {
- ValueNumbersA.insert(A.IRSC.ValueToNumber.find(*VItA)->second);
- ValueNumbersB.insert(B.IRSC.ValueToNumber.find(*VItB)->second);
- }
-
- // Iterate over the operands in the first IRSimilarityCandidate and make sure
- // there exists a possible mapping with the operands in the second
- // IRSimilarityCandidate.
- if (!checkNumberingAndReplaceCommutative(A.IRSC.ValueToNumber,
- A.ValueNumberMapping, A.OperVals,
- ValueNumbersB))
- return false;
-
- // Iterate over the operands in the second IRSimilarityCandidate and make sure
- // there exists a possible mapping with the operands in the first
- // IRSimilarityCandidate.
- if (!checkNumberingAndReplaceCommutative(B.IRSC.ValueToNumber,
- B.ValueNumberMapping, B.OperVals,
- ValueNumbersA))
- return false;
-
- return true;
-}
-
-bool IRSimilarityCandidate::compareStructure(const IRSimilarityCandidate &A,
- const IRSimilarityCandidate &B) {
- if (A.getLength() != B.getLength())
- return false;
-
- if (A.ValueToNumber.size() != B.ValueToNumber.size())
- return false;
-
- iterator ItA = A.begin();
- iterator ItB = B.begin();
-
- // These sets create a create a mapping between the values in one candidate
- // to values in the other candidate. If we create a set with one element,
- // and that same element maps to the original element in the candidate
- // we have a good mapping.
- DenseMap<unsigned, DenseSet<unsigned>> ValueNumberMappingA;
- DenseMap<unsigned, DenseSet<unsigned>> ValueNumberMappingB;
- DenseMap<unsigned, DenseSet<unsigned>>::iterator ValueMappingIt;
-
- bool WasInserted;
-
- // Iterate over the instructions contained in each candidate
- unsigned SectionLength = A.getStartIdx() + A.getLength();
- for (unsigned Loc = A.getStartIdx(); Loc < SectionLength;
- ItA++, ItB++, Loc++) {
- // Make sure the instructions are similar to one another.
- if (!isClose(*ItA, *ItB))
- return false;
-
- Instruction *IA = ItA->Inst;
- Instruction *IB = ItB->Inst;
-
- if (!ItA->Legal || !ItB->Legal)
- return false;
-
- // Get the operand sets for the instructions.
- ArrayRef<Value *> OperValsA = ItA->OperVals;
- ArrayRef<Value *> OperValsB = ItB->OperVals;
-
- unsigned InstValA = A.ValueToNumber.find(IA)->second;
- unsigned InstValB = B.ValueToNumber.find(IB)->second;
-
- // Ensure that the mappings for the instructions exists.
- std::tie(ValueMappingIt, WasInserted) = ValueNumberMappingA.insert(
- std::make_pair(InstValA, DenseSet<unsigned>({InstValB})));
- if (!WasInserted && !ValueMappingIt->second.contains(InstValB))
- return false;
-
- std::tie(ValueMappingIt, WasInserted) = ValueNumberMappingB.insert(
- std::make_pair(InstValB, DenseSet<unsigned>({InstValA})));
- if (!WasInserted && !ValueMappingIt->second.contains(InstValA))
- return false;
-
- // We have different paths for commutative instructions and non-commutative
- // instructions since commutative instructions could allow multiple mappings
- // to certain values.
- if (IA->isCommutative() && !isa<FPMathOperator>(IA)) {
- if (!compareCommutativeOperandMapping(
- {A, OperValsA, ValueNumberMappingA},
- {B, OperValsB, ValueNumberMappingB}))
- return false;
- continue;
- }
-
- // Handle the non-commutative cases.
- if (!compareNonCommutativeOperandMapping(
- {A, OperValsA, ValueNumberMappingA},
- {B, OperValsB, ValueNumberMappingB}))
- return false;
- }
- return true;
-}
-
-bool IRSimilarityCandidate::overlap(const IRSimilarityCandidate &A,
- const IRSimilarityCandidate &B) {
- auto DoesOverlap = [](const IRSimilarityCandidate &X,
- const IRSimilarityCandidate &Y) {
- // Check:
- // XXXXXX X starts before Y ends
- // YYYYYYY Y starts after X starts
- return X.StartIdx <= Y.getEndIdx() && Y.StartIdx >= X.StartIdx;
- };
-
- return DoesOverlap(A, B) || DoesOverlap(B, A);
-}
-
-void IRSimilarityIdentifier::populateMapper(
- Module &M, std::vector<IRInstructionData *> &InstrList,
- std::vector<unsigned> &IntegerMapping) {
-
- std::vector<IRInstructionData *> InstrListForModule;
- std::vector<unsigned> IntegerMappingForModule;
- // Iterate over the functions in the module to map each Instruction in each
- // BasicBlock to an unsigned integer.
- for (Function &F : M) {
-
- if (F.empty())
- continue;
-
- for (BasicBlock &BB : F) {
-
- if (BB.sizeWithoutDebug() < 2)
- continue;
-
- // BB has potential to have similarity since it has a size greater than 2
- // and can therefore match other regions greater than 2. Map it to a list
- // of unsigned integers.
- Mapper.convertToUnsignedVec(BB, InstrListForModule,
- IntegerMappingForModule);
- }
- }
-
- // Insert the InstrListForModule at the end of the overall InstrList so that
- // we can have a long InstrList for the entire set of Modules being analyzed.
- llvm::append_range(InstrList, InstrListForModule);
- // Do the same as above, but for IntegerMapping.
- llvm::append_range(IntegerMapping, IntegerMappingForModule);
-}
-
-void IRSimilarityIdentifier::populateMapper(
- ArrayRef<std::unique_ptr<Module>> &Modules,
- std::vector<IRInstructionData *> &InstrList,
- std::vector<unsigned> &IntegerMapping) {
-
- // Iterate over, and map the instructions in each module.
- for (const std::unique_ptr<Module> &M : Modules)
- populateMapper(*M, InstrList, IntegerMapping);
-}
-
-/// From a repeated subsequence, find all the different instances of the
-/// subsequence from the \p InstrList, and create an IRSimilarityCandidate from
-/// the IRInstructionData in subsequence.
-///
-/// \param [in] Mapper - The instruction mapper for sanity checks.
-/// \param [in] InstrList - The vector that holds the instruction data.
-/// \param [in] IntegerMapping - The vector that holds the mapped integers.
-/// \param [out] CandsForRepSubstring - The vector to store the generated
-/// IRSimilarityCandidates.
-static void createCandidatesFromSuffixTree(
- IRInstructionMapper Mapper, std::vector<IRInstructionData *> &InstrList,
- std::vector<unsigned> &IntegerMapping, SuffixTree::RepeatedSubstring &RS,
- std::vector<IRSimilarityCandidate> &CandsForRepSubstring) {
-
- unsigned StringLen = RS.Length;
-
- // Create an IRSimilarityCandidate for instance of this subsequence \p RS.
- for (const unsigned &StartIdx : RS.StartIndices) {
- unsigned EndIdx = StartIdx + StringLen - 1;
-
- // Check that this subsequence does not contain an illegal instruction.
- bool ContainsIllegal = false;
- for (unsigned CurrIdx = StartIdx; CurrIdx <= EndIdx; CurrIdx++) {
- unsigned Key = IntegerMapping[CurrIdx];
- if (Key > Mapper.IllegalInstrNumber) {
- ContainsIllegal = true;
- break;
- }
- }
-
- // If we have an illegal instruction, we should not create an
- // IRSimilarityCandidate for this region.
- if (ContainsIllegal)
- continue;
-
- // We are getting iterators to the instructions in this region of code
- // by advancing the start and end indices from the start of the
- // InstrList.
- std::vector<IRInstructionData *>::iterator StartIt = InstrList.begin();
- std::advance(StartIt, StartIdx);
- std::vector<IRInstructionData *>::iterator EndIt = InstrList.begin();
- std::advance(EndIt, EndIdx);
-
- CandsForRepSubstring.emplace_back(StartIdx, StringLen, *StartIt, *EndIt);
- }
-}
-
-/// From the list of IRSimilarityCandidates, perform a comparison between each
-/// IRSimilarityCandidate to determine if there are overlapping
-/// IRInstructionData, or if they do not have the same structure.
-///
-/// \param [in] CandsForRepSubstring - The vector containing the
-/// IRSimilarityCandidates.
-/// \param [out] StructuralGroups - the mapping of unsigned integers to vector
-/// of IRSimilarityCandidates where each of the IRSimilarityCandidates in the
-/// vector are structurally similar to one another.
-static void findCandidateStructures(
- std::vector<IRSimilarityCandidate> &CandsForRepSubstring,
- DenseMap<unsigned, SimilarityGroup> &StructuralGroups) {
- std::vector<IRSimilarityCandidate>::iterator CandIt, CandEndIt, InnerCandIt,
- InnerCandEndIt;
-
- // IRSimilarityCandidates each have a structure for operand use. It is
- // possible that two instances of the same subsequences have different
- // structure. Each type of structure found is assigned a number. This
- // DenseMap maps an IRSimilarityCandidate to which type of similarity
- // discovered it fits within.
- DenseMap<IRSimilarityCandidate *, unsigned> CandToGroup;
-
- // Find the compatibility from each candidate to the others to determine
- // which candidates overlap and which have the same structure by mapping
- // each structure to a different group.
- bool SameStructure;
- bool Inserted;
- unsigned CurrentGroupNum = 0;
- unsigned OuterGroupNum;
- DenseMap<IRSimilarityCandidate *, unsigned>::iterator CandToGroupIt;
- DenseMap<IRSimilarityCandidate *, unsigned>::iterator CandToGroupItInner;
- DenseMap<unsigned, SimilarityGroup>::iterator CurrentGroupPair;
-
- // Iterate over the candidates to determine its structural and overlapping
- // compatibility with other instructions
- for (CandIt = CandsForRepSubstring.begin(),
- CandEndIt = CandsForRepSubstring.end();
- CandIt != CandEndIt; CandIt++) {
-
- // Determine if it has an assigned structural group already.
- CandToGroupIt = CandToGroup.find(&*CandIt);
- if (CandToGroupIt == CandToGroup.end()) {
- // If not, we assign it one, and add it to our mapping.
- std::tie(CandToGroupIt, Inserted) =
- CandToGroup.insert(std::make_pair(&*CandIt, CurrentGroupNum++));
- }
-
- // Get the structural group number from the iterator.
- OuterGroupNum = CandToGroupIt->second;
-
- // Check if we already have a list of IRSimilarityCandidates for the current
- // structural group. Create one if one does not exist.
- CurrentGroupPair = StructuralGroups.find(OuterGroupNum);
- if (CurrentGroupPair == StructuralGroups.end())
- std::tie(CurrentGroupPair, Inserted) = StructuralGroups.insert(
- std::make_pair(OuterGroupNum, SimilarityGroup({*CandIt})));
-
- // Iterate over the IRSimilarityCandidates following the current
- // IRSimilarityCandidate in the list to determine whether the two
- // IRSimilarityCandidates are compatible. This is so we do not repeat pairs
- // of IRSimilarityCandidates.
- for (InnerCandIt = std::next(CandIt),
- InnerCandEndIt = CandsForRepSubstring.end();
- InnerCandIt != InnerCandEndIt; InnerCandIt++) {
-
- // We check if the inner item has a group already, if it does, we skip it.
- CandToGroupItInner = CandToGroup.find(&*InnerCandIt);
- if (CandToGroupItInner != CandToGroup.end())
- continue;
-
- // Otherwise we determine if they have the same structure and add it to
- // vector if they match.
- SameStructure =
- IRSimilarityCandidate::compareStructure(*CandIt, *InnerCandIt);
- if (!SameStructure)
- continue;
-
- CandToGroup.insert(std::make_pair(&*InnerCandIt, OuterGroupNum));
- CurrentGroupPair->second.push_back(*InnerCandIt);
- }
- }
-}
-
-void IRSimilarityIdentifier::findCandidates(
- std::vector<IRInstructionData *> &InstrList,
- std::vector<unsigned> &IntegerMapping) {
- SuffixTree ST(IntegerMapping);
-
- std::vector<IRSimilarityCandidate> CandsForRepSubstring;
- std::vector<SimilarityGroup> NewCandidateGroups;
-
- DenseMap<unsigned, SimilarityGroup> StructuralGroups;
-
- // Iterate over the subsequences found by the Suffix Tree to create
- // IRSimilarityCandidates for each repeated subsequence and determine which
- // instances are structurally similar to one another.
- for (auto It = ST.begin(), Et = ST.end(); It != Et; ++It) {
- createCandidatesFromSuffixTree(Mapper, InstrList, IntegerMapping, *It,
- CandsForRepSubstring);
-
- if (CandsForRepSubstring.size() < 2)
- continue;
-
- findCandidateStructures(CandsForRepSubstring, StructuralGroups);
- for (std::pair<unsigned, SimilarityGroup> &Group : StructuralGroups)
- // We only add the group if it contains more than one
- // IRSimilarityCandidate. If there is only one, that means there is no
- // other repeated subsequence with the same structure.
- if (Group.second.size() > 1)
- SimilarityCandidates->push_back(Group.second);
-
- CandsForRepSubstring.clear();
- StructuralGroups.clear();
- NewCandidateGroups.clear();
- }
-}
-
-SimilarityGroupList &IRSimilarityIdentifier::findSimilarity(
- ArrayRef<std::unique_ptr<Module>> Modules) {
- resetSimilarityCandidates();
-
- std::vector<IRInstructionData *> InstrList;
- std::vector<unsigned> IntegerMapping;
-
- populateMapper(Modules, InstrList, IntegerMapping);
- findCandidates(InstrList, IntegerMapping);
-
- return SimilarityCandidates.getValue();
-}
-
-SimilarityGroupList &IRSimilarityIdentifier::findSimilarity(Module &M) {
- resetSimilarityCandidates();
-
- std::vector<IRInstructionData *> InstrList;
- std::vector<unsigned> IntegerMapping;
-
- populateMapper(M, InstrList, IntegerMapping);
- findCandidates(InstrList, IntegerMapping);
-
- return SimilarityCandidates.getValue();
-}
-
-INITIALIZE_PASS(IRSimilarityIdentifierWrapperPass, "ir-similarity-identifier",
- "ir-similarity-identifier", false, true)
-
-IRSimilarityIdentifierWrapperPass::IRSimilarityIdentifierWrapperPass()
- : ModulePass(ID) {
- initializeIRSimilarityIdentifierWrapperPassPass(
- *PassRegistry::getPassRegistry());
-}
-
-bool IRSimilarityIdentifierWrapperPass::doInitialization(Module &M) {
- IRSI.reset(new IRSimilarityIdentifier(M));
- return false;
-}
-
-bool IRSimilarityIdentifierWrapperPass::doFinalization(Module &M) {
- IRSI.reset();
- return false;
-}
-
-bool IRSimilarityIdentifierWrapperPass::runOnModule(Module &M) {
- // All the real work is done in the constructor for the pass.
- IRSI.reset(new IRSimilarityIdentifier(M));
- return false;
-}
-
-AnalysisKey IRSimilarityAnalysis::Key;
-IRSimilarityIdentifier IRSimilarityAnalysis::run(Module &M,
- ModuleAnalysisManager &) {
-
- return IRSimilarityIdentifier(M);
-}
-
-PreservedAnalyses
-IRSimilarityAnalysisPrinterPass::run(Module &M, ModuleAnalysisManager &AM) {
- IRSimilarityIdentifier &IRSI = AM.getResult<IRSimilarityAnalysis>(M);
- Optional<SimilarityGroupList> &SimilarityCandidatesOpt = IRSI.getSimilarity();
-
- for (std::vector<IRSimilarityCandidate> &CandVec : *SimilarityCandidatesOpt) {
- OS << CandVec.size() << " candidates of length "
- << CandVec.begin()->getLength() << ". Found in: \n";
- for (IRSimilarityCandidate &Cand : CandVec) {
- OS << " Function: " << Cand.front()->Inst->getFunction()->getName().str()
- << ", Basic Block: ";
- if (Cand.front()->Inst->getParent()->getName().str() == "")
- OS << "(unnamed)\n";
- else
- OS << Cand.front()->Inst->getParent()->getName().str() << "\n";
- }
- }
-
- return PreservedAnalyses::all();
-}
-
-char IRSimilarityIdentifierWrapperPass::ID = 0;
+//===- IRSimilarityIdentifier.cpp - Find similarity in a module -----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// \file
+// Implementation file for the IRSimilarityIdentifier for identifying
+// similarities in IR including the IRInstructionMapper.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/IRSimilarityIdentifier.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Operator.h"
+#include "llvm/IR/User.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Support/SuffixTree.h"
+
+using namespace llvm;
+using namespace IRSimilarity;
+
+IRInstructionData::IRInstructionData(Instruction &I, bool Legality,
+ IRInstructionDataList &IDList)
+ : Inst(&I), Legal(Legality), IDL(&IDList) {
+ // We check for whether we have a comparison instruction. If it is, we
+ // find the "less than" version of the predicate for consistency for
+ // comparison instructions throught the program.
+ if (CmpInst *C = dyn_cast<CmpInst>(&I)) {
+ CmpInst::Predicate Predicate = predicateForConsistency(C);
+ if (Predicate != C->getPredicate())
+ RevisedPredicate = Predicate;
+ }
+
+ // Here we collect the operands and their types for determining whether
+ // the structure of the operand use matches between two different candidates.
+ for (Use &OI : I.operands()) {
+ if (isa<CmpInst>(I) && RevisedPredicate.hasValue()) {
+ // If we have a CmpInst where the predicate is reversed, it means the
+ // operands must be reversed as well.
+ OperVals.insert(OperVals.begin(), OI.get());
+ continue;
+ }
+
+ OperVals.push_back(OI.get());
+ }
+}
+
+CmpInst::Predicate IRInstructionData::predicateForConsistency(CmpInst *CI) {
+ switch (CI->getPredicate()) {
+ case CmpInst::FCMP_OGT:
+ case CmpInst::FCMP_UGT:
+ case CmpInst::FCMP_OGE:
+ case CmpInst::FCMP_UGE:
+ case CmpInst::ICMP_SGT:
+ case CmpInst::ICMP_UGT:
+ case CmpInst::ICMP_SGE:
+ case CmpInst::ICMP_UGE:
+ return CI->getSwappedPredicate();
+ default:
+ return CI->getPredicate();
+ }
+}
+
+CmpInst::Predicate IRInstructionData::getPredicate() const {
+ assert(isa<CmpInst>(Inst) &&
+ "Can only get a predicate from a compare instruction");
+
+ if (RevisedPredicate.hasValue())
+ return RevisedPredicate.getValue();
+
+ return cast<CmpInst>(Inst)->getPredicate();
+}
+
+static StringRef getCalledFunctionName(CallInst &CI) {
+ assert(CI.getCalledFunction() != nullptr && "Called Function is nullptr?");
+
+ return CI.getCalledFunction()->getName();
+}
+
+bool IRSimilarity::isClose(const IRInstructionData &A,
+ const IRInstructionData &B) {
+
+ if (!A.Legal || !B.Legal)
+ return false;
+
+ // Check if we are performing the same sort of operation on the same types
+ // but not on the same values.
+ if (!A.Inst->isSameOperationAs(B.Inst)) {
+ // If there is a predicate, this means that either there is a swapped
+ // predicate, or that the types are different, we want to make sure that
+ // the predicates are equivalent via swapping.
+ if (isa<CmpInst>(A.Inst) && isa<CmpInst>(B.Inst)) {
+
+ if (A.getPredicate() != B.getPredicate())
+ return false;
+
+ // If the predicates are the same via swap, make sure that the types are
+ // still the same.
+ auto ZippedTypes = zip(A.OperVals, B.OperVals);
+
+ return all_of(
+ ZippedTypes, [](std::tuple<llvm::Value *, llvm::Value *> R) {
+ return std::get<0>(R)->getType() == std::get<1>(R)->getType();
+ });
+ }
+
+ return false;
+ }
+
+ // Since any GEP Instruction operands after the first operand cannot be
+ // defined by a register, we must make sure that the operands after the first
+ // are the same in the two instructions
+ if (auto *GEP = dyn_cast<GetElementPtrInst>(A.Inst)) {
+ auto *OtherGEP = cast<GetElementPtrInst>(B.Inst);
+
+ // If the instructions do not have the same inbounds restrictions, we do
+ // not consider them the same.
+ if (GEP->isInBounds() != OtherGEP->isInBounds())
+ return false;
+
+ auto ZippedOperands = zip(GEP->indices(), OtherGEP->indices());
+
+ // We increment here since we do not care about the first instruction,
+ // we only care about the following operands since they must be the
+ // exact same to be considered similar.
+ return all_of(drop_begin(ZippedOperands),
+ [](std::tuple<llvm::Use &, llvm::Use &> R) {
+ return std::get<0>(R) == std::get<1>(R);
+ });
+ }
+
+ // If the instructions are functions, we make sure that the function name is
+ // the same. We already know that the types are since is isSameOperationAs is
+ // true.
+ if (isa<CallInst>(A.Inst) && isa<CallInst>(B.Inst)) {
+ CallInst *CIA = cast<CallInst>(A.Inst);
+ CallInst *CIB = cast<CallInst>(B.Inst);
+ if (getCalledFunctionName(*CIA).compare(getCalledFunctionName(*CIB)) != 0)
+ return false;
+ }
+
+ return true;
+}
+
+// TODO: This is the same as the MachineOutliner, and should be consolidated
+// into the same interface.
+void IRInstructionMapper::convertToUnsignedVec(
+ BasicBlock &BB, std::vector<IRInstructionData *> &InstrList,
+ std::vector<unsigned> &IntegerMapping) {
+ BasicBlock::iterator It = BB.begin();
+
+ std::vector<unsigned> IntegerMappingForBB;
+ std::vector<IRInstructionData *> InstrListForBB;
+
+ HaveLegalRange = false;
+ CanCombineWithPrevInstr = false;
+ AddedIllegalLastTime = true;
+
+ for (BasicBlock::iterator Et = BB.end(); It != Et; ++It) {
+ switch (InstClassifier.visit(*It)) {
+ case InstrType::Legal:
+ mapToLegalUnsigned(It, IntegerMappingForBB, InstrListForBB);
+ break;
+ case InstrType::Illegal:
+ mapToIllegalUnsigned(It, IntegerMappingForBB, InstrListForBB);
+ break;
+ case InstrType::Invisible:
+ AddedIllegalLastTime = false;
+ break;
+ }
+ }
+
+ if (HaveLegalRange) {
+ mapToIllegalUnsigned(It, IntegerMappingForBB, InstrListForBB, true);
+ for_each(InstrListForBB,
+ [this](IRInstructionData *ID) { this->IDL->push_back(*ID); });
+ llvm::append_range(InstrList, InstrListForBB);
+ llvm::append_range(IntegerMapping, IntegerMappingForBB);
+ }
+}
+
+// TODO: This is the same as the MachineOutliner, and should be consolidated
+// into the same interface.
+unsigned IRInstructionMapper::mapToLegalUnsigned(
+ BasicBlock::iterator &It, std::vector<unsigned> &IntegerMappingForBB,
+ std::vector<IRInstructionData *> &InstrListForBB) {
+ // We added something legal, so we should unset the AddedLegalLastTime
+ // flag.
+ AddedIllegalLastTime = false;
+
+ // If we have at least two adjacent legal instructions (which may have
+ // invisible instructions in between), remember that.
+ if (CanCombineWithPrevInstr)
+ HaveLegalRange = true;
+ CanCombineWithPrevInstr = true;
+
+ // Get the integer for this instruction or give it the current
+ // LegalInstrNumber.
+ IRInstructionData *ID = allocateIRInstructionData(*It, true, *IDL);
+ InstrListForBB.push_back(ID);
+
+ // Add to the instruction list
+ bool WasInserted;
+ DenseMap<IRInstructionData *, unsigned, IRInstructionDataTraits>::iterator
+ ResultIt;
+ std::tie(ResultIt, WasInserted) =
+ InstructionIntegerMap.insert(std::make_pair(ID, LegalInstrNumber));
+ unsigned INumber = ResultIt->second;
+
+ // There was an insertion.
+ if (WasInserted)
+ LegalInstrNumber++;
+
+ IntegerMappingForBB.push_back(INumber);
+
+ // Make sure we don't overflow or use any integers reserved by the DenseMap.
+ assert(LegalInstrNumber < IllegalInstrNumber &&
+ "Instruction mapping overflow!");
+
+ assert(LegalInstrNumber != DenseMapInfo<unsigned>::getEmptyKey() &&
+ "Tried to assign DenseMap tombstone or empty key to instruction.");
+ assert(LegalInstrNumber != DenseMapInfo<unsigned>::getTombstoneKey() &&
+ "Tried to assign DenseMap tombstone or empty key to instruction.");
+
+ return INumber;
+}
+
+IRInstructionData *
+IRInstructionMapper::allocateIRInstructionData(Instruction &I, bool Legality,
+ IRInstructionDataList &IDL) {
+ return new (InstDataAllocator->Allocate()) IRInstructionData(I, Legality, IDL);
+}
+
+IRInstructionDataList *
+IRInstructionMapper::allocateIRInstructionDataList() {
+ return new (IDLAllocator->Allocate()) IRInstructionDataList();
+}
+
+// TODO: This is the same as the MachineOutliner, and should be consolidated
+// into the same interface.
+unsigned IRInstructionMapper::mapToIllegalUnsigned(
+ BasicBlock::iterator &It, std::vector<unsigned> &IntegerMappingForBB,
+ std::vector<IRInstructionData *> &InstrListForBB, bool End) {
+ // Can't combine an illegal instruction. Set the flag.
+ CanCombineWithPrevInstr = false;
+
+ // Only add one illegal number per range of legal numbers.
+ if (AddedIllegalLastTime)
+ return IllegalInstrNumber;
+
+ IRInstructionData *ID = nullptr;
+ if (!End)
+ ID = allocateIRInstructionData(*It, false, *IDL);
+ InstrListForBB.push_back(ID);
+
+ // Remember that we added an illegal number last time.
+ AddedIllegalLastTime = true;
+ unsigned INumber = IllegalInstrNumber;
+ IntegerMappingForBB.push_back(IllegalInstrNumber--);
+
+ assert(LegalInstrNumber < IllegalInstrNumber &&
+ "Instruction mapping overflow!");
+
+ assert(IllegalInstrNumber != DenseMapInfo<unsigned>::getEmptyKey() &&
+ "IllegalInstrNumber cannot be DenseMap tombstone or empty key!");
+
+ assert(IllegalInstrNumber != DenseMapInfo<unsigned>::getTombstoneKey() &&
+ "IllegalInstrNumber cannot be DenseMap tombstone or empty key!");
+
+ return INumber;
+}
+
+IRSimilarityCandidate::IRSimilarityCandidate(unsigned StartIdx, unsigned Len,
+ IRInstructionData *FirstInstIt,
+ IRInstructionData *LastInstIt)
+ : StartIdx(StartIdx), Len(Len) {
+
+ assert(FirstInstIt != nullptr && "Instruction is nullptr!");
+ assert(LastInstIt != nullptr && "Instruction is nullptr!");
+ assert(StartIdx + Len > StartIdx &&
+ "Overflow for IRSimilarityCandidate range?");
+ assert(Len - 1 == static_cast<unsigned>(std::distance(
+ iterator(FirstInstIt), iterator(LastInstIt))) &&
+ "Length of the first and last IRInstructionData do not match the "
+ "given length");
+
+ // We iterate over the given instructions, and map each unique value
+ // to a unique number in the IRSimilarityCandidate ValueToNumber and
+ // NumberToValue maps. A constant get its own value globally, the individual
+ // uses of the constants are not considered to be unique.
+ //
+ // IR: Mapping Added:
+ // %add1 = add i32 %a, c1 %add1 -> 3, %a -> 1, c1 -> 2
+ // %add2 = add i32 %a, %1 %add2 -> 4
+ // %add3 = add i32 c2, c1 %add3 -> 6, c2 -> 5
+ //
+ // when replace with global values, starting from 1, would be
+ //
+ // 3 = add i32 1, 2
+ // 4 = add i32 1, 3
+ // 6 = add i32 5, 2
+ unsigned LocalValNumber = 1;
+ IRInstructionDataList::iterator ID = iterator(*FirstInstIt);
+ for (unsigned Loc = StartIdx; Loc < StartIdx + Len; Loc++, ID++) {
+ // Map the operand values to an unsigned integer if it does not already
+ // have an unsigned integer assigned to it.
+ for (Value *Arg : ID->OperVals)
+ if (ValueToNumber.find(Arg) == ValueToNumber.end()) {
+ ValueToNumber.try_emplace(Arg, LocalValNumber);
+ NumberToValue.try_emplace(LocalValNumber, Arg);
+ LocalValNumber++;
+ }
+
+ // Mapping the instructions to an unsigned integer if it is not already
+ // exist in the mapping.
+ if (ValueToNumber.find(ID->Inst) == ValueToNumber.end()) {
+ ValueToNumber.try_emplace(ID->Inst, LocalValNumber);
+ NumberToValue.try_emplace(LocalValNumber, ID->Inst);
+ LocalValNumber++;
+ }
+ }
+
+ // Setting the first and last instruction data pointers for the candidate. If
+ // we got through the entire for loop without hitting an assert, we know
+ // that both of these instructions are not nullptrs.
+ FirstInst = FirstInstIt;
+ LastInst = LastInstIt;
+}
+
+bool IRSimilarityCandidate::isSimilar(const IRSimilarityCandidate &A,
+ const IRSimilarityCandidate &B) {
+ if (A.getLength() != B.getLength())
+ return false;
+
+ auto InstrDataForBoth =
+ zip(make_range(A.begin(), A.end()), make_range(B.begin(), B.end()));
+
+ return all_of(InstrDataForBoth,
+ [](std::tuple<IRInstructionData &, IRInstructionData &> R) {
+ IRInstructionData &A = std::get<0>(R);
+ IRInstructionData &B = std::get<1>(R);
+ if (!A.Legal || !B.Legal)
+ return false;
+ return isClose(A, B);
+ });
+}
+
+/// Determine if one or more of the assigned global value numbers for the
+/// operands in \p TargetValueNumbers is in the current mapping set for operand
+/// numbers in \p SourceOperands. The set of possible corresponding global
+/// value numbers are replaced with the most recent version of compatible
+/// values.
+///
+/// \param [in] SourceValueToNumberMapping - The mapping of a Value to global
+/// value number for the source IRInstructionCandidate.
+/// \param [in, out] CurrentSrcTgtNumberMapping - The current mapping of source
+/// IRSimilarityCandidate global value numbers to a set of possible numbers in
+/// the target.
+/// \param [in] SourceOperands - The operands in the original
+/// IRSimilarityCandidate in the current instruction.
+/// \param [in] TargetValueNumbers - The global value numbers of the operands in
+/// the corresponding Instruction in the other IRSimilarityCandidate.
+/// \returns true if there exists a possible mapping between the source
+/// Instruction operands and the target Instruction operands, and false if not.
+static bool checkNumberingAndReplaceCommutative(
+ const DenseMap<Value *, unsigned> &SourceValueToNumberMapping,
+ DenseMap<unsigned, DenseSet<unsigned>> &CurrentSrcTgtNumberMapping,
+ ArrayRef<Value *> &SourceOperands,
+ DenseSet<unsigned> &TargetValueNumbers){
+
+ DenseMap<unsigned, DenseSet<unsigned>>::iterator ValueMappingIt;
+
+ unsigned ArgVal;
+ bool WasInserted;
+
+ // Iterate over the operands in the source IRSimilarityCandidate to determine
+ // whether there exists an operand in the other IRSimilarityCandidate that
+ // creates a valid mapping of Value to Value between the
+ // IRSimilarityCaniddates.
+ for (Value *V : SourceOperands) {
+ ArgVal = SourceValueToNumberMapping.find(V)->second;
+
+ std::tie(ValueMappingIt, WasInserted) = CurrentSrcTgtNumberMapping.insert(
+ std::make_pair(ArgVal, TargetValueNumbers));
+
+ // Instead of finding a current mapping, we inserted a set. This means a
+ // mapping did not exist for the source Instruction operand, it has no
+ // current constraints we need to check.
+ if (WasInserted)
+ continue;
+
+ // If a mapping already exists for the source operand to the values in the
+ // other IRSimilarityCandidate we need to iterate over the items in other
+ // IRSimilarityCandidate's Instruction to determine whether there is a valid
+ // mapping of Value to Value.
+ DenseSet<unsigned> NewSet;
+ for (unsigned &Curr : ValueMappingIt->second)
+ // If we can find the value in the mapping, we add it to the new set.
+ if (TargetValueNumbers.contains(Curr))
+ NewSet.insert(Curr);
+
+ // If we could not find a Value, return 0.
+ if (NewSet.empty())
+ return false;
+
+ // Otherwise replace the old mapping with the newly constructed one.
+ if (NewSet.size() != ValueMappingIt->second.size())
+ ValueMappingIt->second.swap(NewSet);
+
+ // We have reached no conclusions about the mapping, and cannot remove
+ // any items from the other operands, so we move to check the next operand.
+ if (ValueMappingIt->second.size() != 1)
+ continue;
+
+
+ unsigned ValToRemove = *ValueMappingIt->second.begin();
+ // When there is only one item left in the mapping for and operand, remove
+ // the value from the other operands. If it results in there being no
+ // mapping, return false, it means the mapping is wrong
+ for (Value *InnerV : SourceOperands) {
+ if (V == InnerV)
+ continue;
+
+ unsigned InnerVal = SourceValueToNumberMapping.find(InnerV)->second;
+ ValueMappingIt = CurrentSrcTgtNumberMapping.find(InnerVal);
+ if (ValueMappingIt == CurrentSrcTgtNumberMapping.end())
+ continue;
+
+ ValueMappingIt->second.erase(ValToRemove);
+ if (ValueMappingIt->second.empty())
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/// Determine if operand number \p TargetArgVal is in the current mapping set
+/// for operand number \p SourceArgVal.
+///
+/// \param [in, out] CurrentSrcTgtNumberMapping current mapping of global
+/// value numbers from source IRSimilarityCandidate to target
+/// IRSimilarityCandidate.
+/// \param [in] SourceArgVal The global value number for an operand in the
+/// in the original candidate.
+/// \param [in] TargetArgVal The global value number for the corresponding
+/// operand in the other candidate.
+/// \returns True if there exists a mapping and false if not.
+bool checkNumberingAndReplace(
+ DenseMap<unsigned, DenseSet<unsigned>> &CurrentSrcTgtNumberMapping,
+ unsigned SourceArgVal, unsigned TargetArgVal) {
+ // We are given two unsigned integers representing the global values of
+ // the operands in different IRSimilarityCandidates and a current mapping
+ // between the two.
+ //
+ // Source Operand GVN: 1
+ // Target Operand GVN: 2
+ // CurrentMapping: {1: {1, 2}}
+ //
+ // Since we have mapping, and the target operand is contained in the set, we
+ // update it to:
+ // CurrentMapping: {1: {2}}
+ // and can return true. But, if the mapping was
+ // CurrentMapping: {1: {3}}
+ // we would return false.
+
+ bool WasInserted;
+ DenseMap<unsigned, DenseSet<unsigned>>::iterator Val;
+
+ std::tie(Val, WasInserted) = CurrentSrcTgtNumberMapping.insert(
+ std::make_pair(SourceArgVal, DenseSet<unsigned>({TargetArgVal})));
+
+ // If we created a new mapping, then we are done.
+ if (WasInserted)
+ return true;
+
+ // If there is more than one option in the mapping set, and the target value
+ // is included in the mapping set replace that set with one that only includes
+ // the target value, as it is the only valid mapping via the non commutative
+ // instruction.
+
+ DenseSet<unsigned> &TargetSet = Val->second;
+ if (TargetSet.size() > 1 && TargetSet.contains(TargetArgVal)) {
+ TargetSet.clear();
+ TargetSet.insert(TargetArgVal);
+ return true;
+ }
+
+ // Return true if we can find the value in the set.
+ return TargetSet.contains(TargetArgVal);
+}
+
+bool IRSimilarityCandidate::compareNonCommutativeOperandMapping(
+ OperandMapping A, OperandMapping B) {
+ // Iterators to keep track of where we are in the operands for each
+ // Instruction.
+ ArrayRef<Value *>::iterator VItA = A.OperVals.begin();
+ ArrayRef<Value *>::iterator VItB = B.OperVals.begin();
+ unsigned OperandLength = A.OperVals.size();
+
+ // For each operand, get the value numbering and ensure it is consistent.
+ for (unsigned Idx = 0; Idx < OperandLength; Idx++, VItA++, VItB++) {
+ unsigned OperValA = A.IRSC.ValueToNumber.find(*VItA)->second;
+ unsigned OperValB = B.IRSC.ValueToNumber.find(*VItB)->second;
+
+ // Attempt to add a set with only the target value. If there is no mapping
+ // we can create it here.
+ //
+ // For an instruction like a subtraction:
+ // IRSimilarityCandidateA: IRSimilarityCandidateB:
+ // %resultA = sub %a, %b %resultB = sub %d, %e
+ //
+ // We map %a -> %d and %b -> %e.
+ //
+ // And check to see whether their mapping is consistent in
+ // checkNumberingAndReplace.
+
+ if (!checkNumberingAndReplace(A.ValueNumberMapping, OperValA, OperValB))
+ return false;
+
+ if (!checkNumberingAndReplace(B.ValueNumberMapping, OperValB, OperValA))
+ return false;
+ }
+ return true;
+}
+
+bool IRSimilarityCandidate::compareCommutativeOperandMapping(
+ OperandMapping A, OperandMapping B) {
+ DenseSet<unsigned> ValueNumbersA;
+ DenseSet<unsigned> ValueNumbersB;
+
+ ArrayRef<Value *>::iterator VItA = A.OperVals.begin();
+ ArrayRef<Value *>::iterator VItB = B.OperVals.begin();
+ unsigned OperandLength = A.OperVals.size();
+
+ // Find the value number sets for the operands.
+ for (unsigned Idx = 0; Idx < OperandLength;
+ Idx++, VItA++, VItB++) {
+ ValueNumbersA.insert(A.IRSC.ValueToNumber.find(*VItA)->second);
+ ValueNumbersB.insert(B.IRSC.ValueToNumber.find(*VItB)->second);
+ }
+
+ // Iterate over the operands in the first IRSimilarityCandidate and make sure
+ // there exists a possible mapping with the operands in the second
+ // IRSimilarityCandidate.
+ if (!checkNumberingAndReplaceCommutative(A.IRSC.ValueToNumber,
+ A.ValueNumberMapping, A.OperVals,
+ ValueNumbersB))
+ return false;
+
+ // Iterate over the operands in the second IRSimilarityCandidate and make sure
+ // there exists a possible mapping with the operands in the first
+ // IRSimilarityCandidate.
+ if (!checkNumberingAndReplaceCommutative(B.IRSC.ValueToNumber,
+ B.ValueNumberMapping, B.OperVals,
+ ValueNumbersA))
+ return false;
+
+ return true;
+}
+
+bool IRSimilarityCandidate::compareStructure(const IRSimilarityCandidate &A,
+ const IRSimilarityCandidate &B) {
+ if (A.getLength() != B.getLength())
+ return false;
+
+ if (A.ValueToNumber.size() != B.ValueToNumber.size())
+ return false;
+
+ iterator ItA = A.begin();
+ iterator ItB = B.begin();
+
+ // These sets create a create a mapping between the values in one candidate
+ // to values in the other candidate. If we create a set with one element,
+ // and that same element maps to the original element in the candidate
+ // we have a good mapping.
+ DenseMap<unsigned, DenseSet<unsigned>> ValueNumberMappingA;
+ DenseMap<unsigned, DenseSet<unsigned>> ValueNumberMappingB;
+ DenseMap<unsigned, DenseSet<unsigned>>::iterator ValueMappingIt;
+
+ bool WasInserted;
+
+ // Iterate over the instructions contained in each candidate
+ unsigned SectionLength = A.getStartIdx() + A.getLength();
+ for (unsigned Loc = A.getStartIdx(); Loc < SectionLength;
+ ItA++, ItB++, Loc++) {
+ // Make sure the instructions are similar to one another.
+ if (!isClose(*ItA, *ItB))
+ return false;
+
+ Instruction *IA = ItA->Inst;
+ Instruction *IB = ItB->Inst;
+
+ if (!ItA->Legal || !ItB->Legal)
+ return false;
+
+ // Get the operand sets for the instructions.
+ ArrayRef<Value *> OperValsA = ItA->OperVals;
+ ArrayRef<Value *> OperValsB = ItB->OperVals;
+
+ unsigned InstValA = A.ValueToNumber.find(IA)->second;
+ unsigned InstValB = B.ValueToNumber.find(IB)->second;
+
+ // Ensure that the mappings for the instructions exists.
+ std::tie(ValueMappingIt, WasInserted) = ValueNumberMappingA.insert(
+ std::make_pair(InstValA, DenseSet<unsigned>({InstValB})));
+ if (!WasInserted && !ValueMappingIt->second.contains(InstValB))
+ return false;
+
+ std::tie(ValueMappingIt, WasInserted) = ValueNumberMappingB.insert(
+ std::make_pair(InstValB, DenseSet<unsigned>({InstValA})));
+ if (!WasInserted && !ValueMappingIt->second.contains(InstValA))
+ return false;
+
+ // We have different paths for commutative instructions and non-commutative
+ // instructions since commutative instructions could allow multiple mappings
+ // to certain values.
+ if (IA->isCommutative() && !isa<FPMathOperator>(IA)) {
+ if (!compareCommutativeOperandMapping(
+ {A, OperValsA, ValueNumberMappingA},
+ {B, OperValsB, ValueNumberMappingB}))
+ return false;
+ continue;
+ }
+
+ // Handle the non-commutative cases.
+ if (!compareNonCommutativeOperandMapping(
+ {A, OperValsA, ValueNumberMappingA},
+ {B, OperValsB, ValueNumberMappingB}))
+ return false;
+ }
+ return true;
+}
+
+bool IRSimilarityCandidate::overlap(const IRSimilarityCandidate &A,
+ const IRSimilarityCandidate &B) {
+ auto DoesOverlap = [](const IRSimilarityCandidate &X,
+ const IRSimilarityCandidate &Y) {
+ // Check:
+ // XXXXXX X starts before Y ends
+ // YYYYYYY Y starts after X starts
+ return X.StartIdx <= Y.getEndIdx() && Y.StartIdx >= X.StartIdx;
+ };
+
+ return DoesOverlap(A, B) || DoesOverlap(B, A);
+}
+
+void IRSimilarityIdentifier::populateMapper(
+ Module &M, std::vector<IRInstructionData *> &InstrList,
+ std::vector<unsigned> &IntegerMapping) {
+
+ std::vector<IRInstructionData *> InstrListForModule;
+ std::vector<unsigned> IntegerMappingForModule;
+ // Iterate over the functions in the module to map each Instruction in each
+ // BasicBlock to an unsigned integer.
+ for (Function &F : M) {
+
+ if (F.empty())
+ continue;
+
+ for (BasicBlock &BB : F) {
+
+ if (BB.sizeWithoutDebug() < 2)
+ continue;
+
+ // BB has potential to have similarity since it has a size greater than 2
+ // and can therefore match other regions greater than 2. Map it to a list
+ // of unsigned integers.
+ Mapper.convertToUnsignedVec(BB, InstrListForModule,
+ IntegerMappingForModule);
+ }
+ }
+
+ // Insert the InstrListForModule at the end of the overall InstrList so that
+ // we can have a long InstrList for the entire set of Modules being analyzed.
+ llvm::append_range(InstrList, InstrListForModule);
+ // Do the same as above, but for IntegerMapping.
+ llvm::append_range(IntegerMapping, IntegerMappingForModule);
+}
+
+void IRSimilarityIdentifier::populateMapper(
+ ArrayRef<std::unique_ptr<Module>> &Modules,
+ std::vector<IRInstructionData *> &InstrList,
+ std::vector<unsigned> &IntegerMapping) {
+
+ // Iterate over, and map the instructions in each module.
+ for (const std::unique_ptr<Module> &M : Modules)
+ populateMapper(*M, InstrList, IntegerMapping);
+}
+
+/// From a repeated subsequence, find all the different instances of the
+/// subsequence from the \p InstrList, and create an IRSimilarityCandidate from
+/// the IRInstructionData in subsequence.
+///
+/// \param [in] Mapper - The instruction mapper for sanity checks.
+/// \param [in] InstrList - The vector that holds the instruction data.
+/// \param [in] IntegerMapping - The vector that holds the mapped integers.
+/// \param [out] CandsForRepSubstring - The vector to store the generated
+/// IRSimilarityCandidates.
+static void createCandidatesFromSuffixTree(
+ IRInstructionMapper Mapper, std::vector<IRInstructionData *> &InstrList,
+ std::vector<unsigned> &IntegerMapping, SuffixTree::RepeatedSubstring &RS,
+ std::vector<IRSimilarityCandidate> &CandsForRepSubstring) {
+
+ unsigned StringLen = RS.Length;
+
+ // Create an IRSimilarityCandidate for instance of this subsequence \p RS.
+ for (const unsigned &StartIdx : RS.StartIndices) {
+ unsigned EndIdx = StartIdx + StringLen - 1;
+
+ // Check that this subsequence does not contain an illegal instruction.
+ bool ContainsIllegal = false;
+ for (unsigned CurrIdx = StartIdx; CurrIdx <= EndIdx; CurrIdx++) {
+ unsigned Key = IntegerMapping[CurrIdx];
+ if (Key > Mapper.IllegalInstrNumber) {
+ ContainsIllegal = true;
+ break;
+ }
+ }
+
+ // If we have an illegal instruction, we should not create an
+ // IRSimilarityCandidate for this region.
+ if (ContainsIllegal)
+ continue;
+
+ // We are getting iterators to the instructions in this region of code
+ // by advancing the start and end indices from the start of the
+ // InstrList.
+ std::vector<IRInstructionData *>::iterator StartIt = InstrList.begin();
+ std::advance(StartIt, StartIdx);
+ std::vector<IRInstructionData *>::iterator EndIt = InstrList.begin();
+ std::advance(EndIt, EndIdx);
+
+ CandsForRepSubstring.emplace_back(StartIdx, StringLen, *StartIt, *EndIt);
+ }
+}
+
+/// From the list of IRSimilarityCandidates, perform a comparison between each
+/// IRSimilarityCandidate to determine if there are overlapping
+/// IRInstructionData, or if they do not have the same structure.
+///
+/// \param [in] CandsForRepSubstring - The vector containing the
+/// IRSimilarityCandidates.
+/// \param [out] StructuralGroups - the mapping of unsigned integers to vector
+/// of IRSimilarityCandidates where each of the IRSimilarityCandidates in the
+/// vector are structurally similar to one another.
+static void findCandidateStructures(
+ std::vector<IRSimilarityCandidate> &CandsForRepSubstring,
+ DenseMap<unsigned, SimilarityGroup> &StructuralGroups) {
+ std::vector<IRSimilarityCandidate>::iterator CandIt, CandEndIt, InnerCandIt,
+ InnerCandEndIt;
+
+ // IRSimilarityCandidates each have a structure for operand use. It is
+ // possible that two instances of the same subsequences have different
+ // structure. Each type of structure found is assigned a number. This
+ // DenseMap maps an IRSimilarityCandidate to which type of similarity
+ // discovered it fits within.
+ DenseMap<IRSimilarityCandidate *, unsigned> CandToGroup;
+
+ // Find the compatibility from each candidate to the others to determine
+ // which candidates overlap and which have the same structure by mapping
+ // each structure to a different group.
+ bool SameStructure;
+ bool Inserted;
+ unsigned CurrentGroupNum = 0;
+ unsigned OuterGroupNum;
+ DenseMap<IRSimilarityCandidate *, unsigned>::iterator CandToGroupIt;
+ DenseMap<IRSimilarityCandidate *, unsigned>::iterator CandToGroupItInner;
+ DenseMap<unsigned, SimilarityGroup>::iterator CurrentGroupPair;
+
+ // Iterate over the candidates to determine its structural and overlapping
+ // compatibility with other instructions
+ for (CandIt = CandsForRepSubstring.begin(),
+ CandEndIt = CandsForRepSubstring.end();
+ CandIt != CandEndIt; CandIt++) {
+
+ // Determine if it has an assigned structural group already.
+ CandToGroupIt = CandToGroup.find(&*CandIt);
+ if (CandToGroupIt == CandToGroup.end()) {
+ // If not, we assign it one, and add it to our mapping.
+ std::tie(CandToGroupIt, Inserted) =
+ CandToGroup.insert(std::make_pair(&*CandIt, CurrentGroupNum++));
+ }
+
+ // Get the structural group number from the iterator.
+ OuterGroupNum = CandToGroupIt->second;
+
+ // Check if we already have a list of IRSimilarityCandidates for the current
+ // structural group. Create one if one does not exist.
+ CurrentGroupPair = StructuralGroups.find(OuterGroupNum);
+ if (CurrentGroupPair == StructuralGroups.end())
+ std::tie(CurrentGroupPair, Inserted) = StructuralGroups.insert(
+ std::make_pair(OuterGroupNum, SimilarityGroup({*CandIt})));
+
+ // Iterate over the IRSimilarityCandidates following the current
+ // IRSimilarityCandidate in the list to determine whether the two
+ // IRSimilarityCandidates are compatible. This is so we do not repeat pairs
+ // of IRSimilarityCandidates.
+ for (InnerCandIt = std::next(CandIt),
+ InnerCandEndIt = CandsForRepSubstring.end();
+ InnerCandIt != InnerCandEndIt; InnerCandIt++) {
+
+ // We check if the inner item has a group already, if it does, we skip it.
+ CandToGroupItInner = CandToGroup.find(&*InnerCandIt);
+ if (CandToGroupItInner != CandToGroup.end())
+ continue;
+
+ // Otherwise we determine if they have the same structure and add it to
+ // vector if they match.
+ SameStructure =
+ IRSimilarityCandidate::compareStructure(*CandIt, *InnerCandIt);
+ if (!SameStructure)
+ continue;
+
+ CandToGroup.insert(std::make_pair(&*InnerCandIt, OuterGroupNum));
+ CurrentGroupPair->second.push_back(*InnerCandIt);
+ }
+ }
+}
+
+void IRSimilarityIdentifier::findCandidates(
+ std::vector<IRInstructionData *> &InstrList,
+ std::vector<unsigned> &IntegerMapping) {
+ SuffixTree ST(IntegerMapping);
+
+ std::vector<IRSimilarityCandidate> CandsForRepSubstring;
+ std::vector<SimilarityGroup> NewCandidateGroups;
+
+ DenseMap<unsigned, SimilarityGroup> StructuralGroups;
+
+ // Iterate over the subsequences found by the Suffix Tree to create
+ // IRSimilarityCandidates for each repeated subsequence and determine which
+ // instances are structurally similar to one another.
+ for (auto It = ST.begin(), Et = ST.end(); It != Et; ++It) {
+ createCandidatesFromSuffixTree(Mapper, InstrList, IntegerMapping, *It,
+ CandsForRepSubstring);
+
+ if (CandsForRepSubstring.size() < 2)
+ continue;
+
+ findCandidateStructures(CandsForRepSubstring, StructuralGroups);
+ for (std::pair<unsigned, SimilarityGroup> &Group : StructuralGroups)
+ // We only add the group if it contains more than one
+ // IRSimilarityCandidate. If there is only one, that means there is no
+ // other repeated subsequence with the same structure.
+ if (Group.second.size() > 1)
+ SimilarityCandidates->push_back(Group.second);
+
+ CandsForRepSubstring.clear();
+ StructuralGroups.clear();
+ NewCandidateGroups.clear();
+ }
+}
+
+SimilarityGroupList &IRSimilarityIdentifier::findSimilarity(
+ ArrayRef<std::unique_ptr<Module>> Modules) {
+ resetSimilarityCandidates();
+
+ std::vector<IRInstructionData *> InstrList;
+ std::vector<unsigned> IntegerMapping;
+
+ populateMapper(Modules, InstrList, IntegerMapping);
+ findCandidates(InstrList, IntegerMapping);
+
+ return SimilarityCandidates.getValue();
+}
+
+SimilarityGroupList &IRSimilarityIdentifier::findSimilarity(Module &M) {
+ resetSimilarityCandidates();
+
+ std::vector<IRInstructionData *> InstrList;
+ std::vector<unsigned> IntegerMapping;
+
+ populateMapper(M, InstrList, IntegerMapping);
+ findCandidates(InstrList, IntegerMapping);
+
+ return SimilarityCandidates.getValue();
+}
+
+INITIALIZE_PASS(IRSimilarityIdentifierWrapperPass, "ir-similarity-identifier",
+ "ir-similarity-identifier", false, true)
+
+IRSimilarityIdentifierWrapperPass::IRSimilarityIdentifierWrapperPass()
+ : ModulePass(ID) {
+ initializeIRSimilarityIdentifierWrapperPassPass(
+ *PassRegistry::getPassRegistry());
+}
+
+bool IRSimilarityIdentifierWrapperPass::doInitialization(Module &M) {
+ IRSI.reset(new IRSimilarityIdentifier(M));
+ return false;
+}
+
+bool IRSimilarityIdentifierWrapperPass::doFinalization(Module &M) {
+ IRSI.reset();
+ return false;
+}
+
+bool IRSimilarityIdentifierWrapperPass::runOnModule(Module &M) {
+ // All the real work is done in the constructor for the pass.
+ IRSI.reset(new IRSimilarityIdentifier(M));
+ return false;
+}
+
+AnalysisKey IRSimilarityAnalysis::Key;
+IRSimilarityIdentifier IRSimilarityAnalysis::run(Module &M,
+ ModuleAnalysisManager &) {
+
+ return IRSimilarityIdentifier(M);
+}
+
+PreservedAnalyses
+IRSimilarityAnalysisPrinterPass::run(Module &M, ModuleAnalysisManager &AM) {
+ IRSimilarityIdentifier &IRSI = AM.getResult<IRSimilarityAnalysis>(M);
+ Optional<SimilarityGroupList> &SimilarityCandidatesOpt = IRSI.getSimilarity();
+
+ for (std::vector<IRSimilarityCandidate> &CandVec : *SimilarityCandidatesOpt) {
+ OS << CandVec.size() << " candidates of length "
+ << CandVec.begin()->getLength() << ". Found in: \n";
+ for (IRSimilarityCandidate &Cand : CandVec) {
+ OS << " Function: " << Cand.front()->Inst->getFunction()->getName().str()
+ << ", Basic Block: ";
+ if (Cand.front()->Inst->getParent()->getName().str() == "")
+ OS << "(unnamed)\n";
+ else
+ OS << Cand.front()->Inst->getParent()->getName().str() << "\n";
+ }
+ }
+
+ return PreservedAnalyses::all();
+}
+
+char IRSimilarityIdentifierWrapperPass::ID = 0;
diff --git a/contrib/libs/llvm12/lib/Analysis/IVDescriptors.cpp b/contrib/libs/llvm12/lib/Analysis/IVDescriptors.cpp
index 9902184bb0..94a24ccf21 100644
--- a/contrib/libs/llvm12/lib/Analysis/IVDescriptors.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/IVDescriptors.cpp
@@ -47,36 +47,36 @@ bool RecurrenceDescriptor::areAllUsesIn(Instruction *I,
return true;
}
-bool RecurrenceDescriptor::isIntegerRecurrenceKind(RecurKind Kind) {
+bool RecurrenceDescriptor::isIntegerRecurrenceKind(RecurKind Kind) {
switch (Kind) {
default:
break;
- case RecurKind::Add:
- case RecurKind::Mul:
- case RecurKind::Or:
- case RecurKind::And:
- case RecurKind::Xor:
- case RecurKind::SMax:
- case RecurKind::SMin:
- case RecurKind::UMax:
- case RecurKind::UMin:
+ case RecurKind::Add:
+ case RecurKind::Mul:
+ case RecurKind::Or:
+ case RecurKind::And:
+ case RecurKind::Xor:
+ case RecurKind::SMax:
+ case RecurKind::SMin:
+ case RecurKind::UMax:
+ case RecurKind::UMin:
return true;
}
return false;
}
-bool RecurrenceDescriptor::isFloatingPointRecurrenceKind(RecurKind Kind) {
- return (Kind != RecurKind::None) && !isIntegerRecurrenceKind(Kind);
+bool RecurrenceDescriptor::isFloatingPointRecurrenceKind(RecurKind Kind) {
+ return (Kind != RecurKind::None) && !isIntegerRecurrenceKind(Kind);
}
-bool RecurrenceDescriptor::isArithmeticRecurrenceKind(RecurKind Kind) {
+bool RecurrenceDescriptor::isArithmeticRecurrenceKind(RecurKind Kind) {
switch (Kind) {
default:
break;
- case RecurKind::Add:
- case RecurKind::Mul:
- case RecurKind::FAdd:
- case RecurKind::FMul:
+ case RecurKind::Add:
+ case RecurKind::Mul:
+ case RecurKind::FAdd:
+ case RecurKind::FMul:
return true;
}
return false;
@@ -189,7 +189,7 @@ static void collectCastsToIgnore(Loop *TheLoop, Instruction *Exit,
}
}
-bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurKind Kind,
+bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurKind Kind,
Loop *TheLoop, bool HasFunNoNaNAttr,
RecurrenceDescriptor &RedDes,
DemandedBits *DB,
@@ -243,14 +243,14 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurKind Kind,
if (RecurrenceType->isFloatingPointTy()) {
if (!isFloatingPointRecurrenceKind(Kind))
return false;
- } else if (RecurrenceType->isIntegerTy()) {
+ } else if (RecurrenceType->isIntegerTy()) {
if (!isIntegerRecurrenceKind(Kind))
return false;
if (isArithmeticRecurrenceKind(Kind))
Start = lookThroughAnd(Phi, RecurrenceType, VisitedInsts, CastInsts);
- } else {
- // Pointer min/max may exist, but it is not supported as a reduction op.
- return false;
+ } else {
+ // Pointer min/max may exist, but it is not supported as a reduction op.
+ return false;
}
Worklist.push_back(Start);
@@ -276,7 +276,7 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurKind Kind,
// * An instruction type other than PHI or the reduction operation.
// * A PHI in the header other than the initial PHI.
while (!Worklist.empty()) {
- Instruction *Cur = Worklist.pop_back_val();
+ Instruction *Cur = Worklist.pop_back_val();
// No Users.
// If the instruction has no users then this is a broken chain and can't be
@@ -307,35 +307,35 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurKind Kind,
// FIXME: FMF is allowed on phi, but propagation is not handled correctly.
if (isa<FPMathOperator>(ReduxDesc.getPatternInst()) && !IsAPhi)
FMF &= ReduxDesc.getPatternInst()->getFastMathFlags();
- // Update this reduction kind if we matched a new instruction.
- // TODO: Can we eliminate the need for a 2nd InstDesc by keeping 'Kind'
- // state accurate while processing the worklist?
- if (ReduxDesc.getRecKind() != RecurKind::None)
- Kind = ReduxDesc.getRecKind();
+ // Update this reduction kind if we matched a new instruction.
+ // TODO: Can we eliminate the need for a 2nd InstDesc by keeping 'Kind'
+ // state accurate while processing the worklist?
+ if (ReduxDesc.getRecKind() != RecurKind::None)
+ Kind = ReduxDesc.getRecKind();
}
bool IsASelect = isa<SelectInst>(Cur);
// A conditional reduction operation must only have 2 or less uses in
// VisitedInsts.
- if (IsASelect && (Kind == RecurKind::FAdd || Kind == RecurKind::FMul) &&
+ if (IsASelect && (Kind == RecurKind::FAdd || Kind == RecurKind::FMul) &&
hasMultipleUsesOf(Cur, VisitedInsts, 2))
return false;
// A reduction operation must only have one use of the reduction value.
- if (!IsAPhi && !IsASelect && !isMinMaxRecurrenceKind(Kind) &&
- hasMultipleUsesOf(Cur, VisitedInsts, 1))
+ if (!IsAPhi && !IsASelect && !isMinMaxRecurrenceKind(Kind) &&
+ hasMultipleUsesOf(Cur, VisitedInsts, 1))
return false;
// All inputs to a PHI node must be a reduction value.
if (IsAPhi && Cur != Phi && !areAllUsesIn(Cur, VisitedInsts))
return false;
- if (isIntMinMaxRecurrenceKind(Kind) &&
+ if (isIntMinMaxRecurrenceKind(Kind) &&
(isa<ICmpInst>(Cur) || isa<SelectInst>(Cur)))
++NumCmpSelectPatternInst;
- if (isFPMinMaxRecurrenceKind(Kind) &&
- (isa<FCmpInst>(Cur) || isa<SelectInst>(Cur)))
+ if (isFPMinMaxRecurrenceKind(Kind) &&
+ (isa<FCmpInst>(Cur) || isa<SelectInst>(Cur)))
++NumCmpSelectPatternInst;
// Check whether we found a reduction operator.
@@ -400,7 +400,7 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurKind Kind,
// This means we have seen one but not the other instruction of the
// pattern or more than just a select and cmp.
- if (isMinMaxRecurrenceKind(Kind) && NumCmpSelectPatternInst != 2)
+ if (isMinMaxRecurrenceKind(Kind) && NumCmpSelectPatternInst != 2)
return false;
if (!FoundStartPHI || !FoundReduxOp || !ExitInstruction)
@@ -418,7 +418,7 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurKind Kind,
// can be ignore in the cost model. If we compute a different type than we
// did when evaluating the 'and', the 'and' will not be eliminated, and we
// will end up with different kinds of operations in the recurrence
- // expression (e.g., IntegerAND, IntegerADD). We give up if this is
+ // expression (e.g., IntegerAND, IntegerADD). We give up if this is
// the case.
//
// The vectorizer relies on InstCombine to perform the actual
@@ -446,8 +446,8 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurKind Kind,
// instructions that are a part of the reduction. The vectorizer cost
// model could then apply the recurrence type to these instructions,
// without needing a white list of instructions to ignore.
- // This may also be useful for the inloop reductions, if it can be
- // kept simple enough.
+ // This may also be useful for the inloop reductions, if it can be
+ // kept simple enough.
collectCastsToIgnore(TheLoop, ExitInstruction, RecurrenceType, CastInsts);
}
@@ -458,50 +458,50 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurKind Kind,
// is saved as part of the RecurrenceDescriptor.
// Save the description of this reduction variable.
- RecurrenceDescriptor RD(RdxStart, ExitInstruction, Kind, FMF,
- ReduxDesc.getUnsafeAlgebraInst(), RecurrenceType,
- IsSigned, CastInsts);
+ RecurrenceDescriptor RD(RdxStart, ExitInstruction, Kind, FMF,
+ ReduxDesc.getUnsafeAlgebraInst(), RecurrenceType,
+ IsSigned, CastInsts);
RedDes = RD;
return true;
}
RecurrenceDescriptor::InstDesc
-RecurrenceDescriptor::isMinMaxSelectCmpPattern(Instruction *I,
- const InstDesc &Prev) {
- assert((isa<CmpInst>(I) || isa<SelectInst>(I)) &&
- "Expected a cmp or select instruction");
+RecurrenceDescriptor::isMinMaxSelectCmpPattern(Instruction *I,
+ const InstDesc &Prev) {
+ assert((isa<CmpInst>(I) || isa<SelectInst>(I)) &&
+ "Expected a cmp or select instruction");
// We must handle the select(cmp()) as a single instruction. Advance to the
// select.
- CmpInst::Predicate Pred;
- if (match(I, m_OneUse(m_Cmp(Pred, m_Value(), m_Value())))) {
- if (auto *Select = dyn_cast<SelectInst>(*I->user_begin()))
- return InstDesc(Select, Prev.getRecKind());
+ CmpInst::Predicate Pred;
+ if (match(I, m_OneUse(m_Cmp(Pred, m_Value(), m_Value())))) {
+ if (auto *Select = dyn_cast<SelectInst>(*I->user_begin()))
+ return InstDesc(Select, Prev.getRecKind());
}
- // Only match select with single use cmp condition.
- if (!match(I, m_Select(m_OneUse(m_Cmp(Pred, m_Value(), m_Value())), m_Value(),
- m_Value())))
+ // Only match select with single use cmp condition.
+ if (!match(I, m_Select(m_OneUse(m_Cmp(Pred, m_Value(), m_Value())), m_Value(),
+ m_Value())))
return InstDesc(false, I);
// Look for a min/max pattern.
- if (match(I, m_UMin(m_Value(), m_Value())))
- return InstDesc(I, RecurKind::UMin);
- if (match(I, m_UMax(m_Value(), m_Value())))
- return InstDesc(I, RecurKind::UMax);
- if (match(I, m_SMax(m_Value(), m_Value())))
- return InstDesc(I, RecurKind::SMax);
- if (match(I, m_SMin(m_Value(), m_Value())))
- return InstDesc(I, RecurKind::SMin);
- if (match(I, m_OrdFMin(m_Value(), m_Value())))
- return InstDesc(I, RecurKind::FMin);
- if (match(I, m_OrdFMax(m_Value(), m_Value())))
- return InstDesc(I, RecurKind::FMax);
- if (match(I, m_UnordFMin(m_Value(), m_Value())))
- return InstDesc(I, RecurKind::FMin);
- if (match(I, m_UnordFMax(m_Value(), m_Value())))
- return InstDesc(I, RecurKind::FMax);
+ if (match(I, m_UMin(m_Value(), m_Value())))
+ return InstDesc(I, RecurKind::UMin);
+ if (match(I, m_UMax(m_Value(), m_Value())))
+ return InstDesc(I, RecurKind::UMax);
+ if (match(I, m_SMax(m_Value(), m_Value())))
+ return InstDesc(I, RecurKind::SMax);
+ if (match(I, m_SMin(m_Value(), m_Value())))
+ return InstDesc(I, RecurKind::SMin);
+ if (match(I, m_OrdFMin(m_Value(), m_Value())))
+ return InstDesc(I, RecurKind::FMin);
+ if (match(I, m_OrdFMax(m_Value(), m_Value())))
+ return InstDesc(I, RecurKind::FMax);
+ if (match(I, m_UnordFMin(m_Value(), m_Value())))
+ return InstDesc(I, RecurKind::FMin);
+ if (match(I, m_UnordFMax(m_Value(), m_Value())))
+ return InstDesc(I, RecurKind::FMax);
return InstDesc(false, I);
}
@@ -516,7 +516,7 @@ RecurrenceDescriptor::isMinMaxSelectCmpPattern(Instruction *I,
/// %add = fadd %0, %sum.1
/// %sum.2 = select %cmp, %add, %sum.1
RecurrenceDescriptor::InstDesc
-RecurrenceDescriptor::isConditionalRdxPattern(RecurKind Kind, Instruction *I) {
+RecurrenceDescriptor::isConditionalRdxPattern(RecurKind Kind, Instruction *I) {
SelectInst *SI = dyn_cast<SelectInst>(I);
if (!SI)
return InstDesc(false, I);
@@ -544,16 +544,16 @@ RecurrenceDescriptor::isConditionalRdxPattern(RecurKind Kind, Instruction *I) {
if ((m_FAdd(m_Value(Op1), m_Value(Op2)).match(I1) ||
m_FSub(m_Value(Op1), m_Value(Op2)).match(I1)) &&
I1->isFast())
- return InstDesc(Kind == RecurKind::FAdd, SI);
+ return InstDesc(Kind == RecurKind::FAdd, SI);
if (m_FMul(m_Value(Op1), m_Value(Op2)).match(I1) && (I1->isFast()))
- return InstDesc(Kind == RecurKind::FMul, SI);
+ return InstDesc(Kind == RecurKind::FMul, SI);
return InstDesc(false, I);
}
RecurrenceDescriptor::InstDesc
-RecurrenceDescriptor::isRecurrenceInstr(Instruction *I, RecurKind Kind,
+RecurrenceDescriptor::isRecurrenceInstr(Instruction *I, RecurKind Kind,
InstDesc &Prev, bool HasFunNoNaNAttr) {
Instruction *UAI = Prev.getUnsafeAlgebraInst();
if (!UAI && isa<FPMathOperator>(I) && !I->hasAllowReassoc())
@@ -563,32 +563,32 @@ RecurrenceDescriptor::isRecurrenceInstr(Instruction *I, RecurKind Kind,
default:
return InstDesc(false, I);
case Instruction::PHI:
- return InstDesc(I, Prev.getRecKind(), Prev.getUnsafeAlgebraInst());
+ return InstDesc(I, Prev.getRecKind(), Prev.getUnsafeAlgebraInst());
case Instruction::Sub:
case Instruction::Add:
- return InstDesc(Kind == RecurKind::Add, I);
+ return InstDesc(Kind == RecurKind::Add, I);
case Instruction::Mul:
- return InstDesc(Kind == RecurKind::Mul, I);
+ return InstDesc(Kind == RecurKind::Mul, I);
case Instruction::And:
- return InstDesc(Kind == RecurKind::And, I);
+ return InstDesc(Kind == RecurKind::And, I);
case Instruction::Or:
- return InstDesc(Kind == RecurKind::Or, I);
+ return InstDesc(Kind == RecurKind::Or, I);
case Instruction::Xor:
- return InstDesc(Kind == RecurKind::Xor, I);
- case Instruction::FDiv:
+ return InstDesc(Kind == RecurKind::Xor, I);
+ case Instruction::FDiv:
case Instruction::FMul:
- return InstDesc(Kind == RecurKind::FMul, I, UAI);
+ return InstDesc(Kind == RecurKind::FMul, I, UAI);
case Instruction::FSub:
case Instruction::FAdd:
- return InstDesc(Kind == RecurKind::FAdd, I, UAI);
+ return InstDesc(Kind == RecurKind::FAdd, I, UAI);
case Instruction::Select:
- if (Kind == RecurKind::FAdd || Kind == RecurKind::FMul)
+ if (Kind == RecurKind::FAdd || Kind == RecurKind::FMul)
return isConditionalRdxPattern(Kind, I);
LLVM_FALLTHROUGH;
case Instruction::FCmp:
case Instruction::ICmp:
- if (!isIntMinMaxRecurrenceKind(Kind) &&
- (!HasFunNoNaNAttr || !isFPMinMaxRecurrenceKind(Kind)))
+ if (!isIntMinMaxRecurrenceKind(Kind) &&
+ (!HasFunNoNaNAttr || !isFPMinMaxRecurrenceKind(Kind)))
return InstDesc(false, I);
return isMinMaxSelectCmpPattern(I, Prev);
}
@@ -618,71 +618,71 @@ bool RecurrenceDescriptor::isReductionPHI(PHINode *Phi, Loop *TheLoop,
bool HasFunNoNaNAttr =
F.getFnAttribute("no-nans-fp-math").getValueAsString() == "true";
- if (AddReductionVar(Phi, RecurKind::Add, TheLoop, HasFunNoNaNAttr, RedDes, DB,
+ if (AddReductionVar(Phi, RecurKind::Add, TheLoop, HasFunNoNaNAttr, RedDes, DB,
AC, DT)) {
LLVM_DEBUG(dbgs() << "Found an ADD reduction PHI." << *Phi << "\n");
return true;
}
- if (AddReductionVar(Phi, RecurKind::Mul, TheLoop, HasFunNoNaNAttr, RedDes, DB,
+ if (AddReductionVar(Phi, RecurKind::Mul, TheLoop, HasFunNoNaNAttr, RedDes, DB,
AC, DT)) {
LLVM_DEBUG(dbgs() << "Found a MUL reduction PHI." << *Phi << "\n");
return true;
}
- if (AddReductionVar(Phi, RecurKind::Or, TheLoop, HasFunNoNaNAttr, RedDes, DB,
+ if (AddReductionVar(Phi, RecurKind::Or, TheLoop, HasFunNoNaNAttr, RedDes, DB,
AC, DT)) {
LLVM_DEBUG(dbgs() << "Found an OR reduction PHI." << *Phi << "\n");
return true;
}
- if (AddReductionVar(Phi, RecurKind::And, TheLoop, HasFunNoNaNAttr, RedDes, DB,
+ if (AddReductionVar(Phi, RecurKind::And, TheLoop, HasFunNoNaNAttr, RedDes, DB,
AC, DT)) {
LLVM_DEBUG(dbgs() << "Found an AND reduction PHI." << *Phi << "\n");
return true;
}
- if (AddReductionVar(Phi, RecurKind::Xor, TheLoop, HasFunNoNaNAttr, RedDes, DB,
+ if (AddReductionVar(Phi, RecurKind::Xor, TheLoop, HasFunNoNaNAttr, RedDes, DB,
AC, DT)) {
LLVM_DEBUG(dbgs() << "Found a XOR reduction PHI." << *Phi << "\n");
return true;
}
- if (AddReductionVar(Phi, RecurKind::SMax, TheLoop, HasFunNoNaNAttr, RedDes,
+ if (AddReductionVar(Phi, RecurKind::SMax, TheLoop, HasFunNoNaNAttr, RedDes,
+ DB, AC, DT)) {
+ LLVM_DEBUG(dbgs() << "Found a SMAX reduction PHI." << *Phi << "\n");
+ return true;
+ }
+ if (AddReductionVar(Phi, RecurKind::SMin, TheLoop, HasFunNoNaNAttr, RedDes,
+ DB, AC, DT)) {
+ LLVM_DEBUG(dbgs() << "Found a SMIN reduction PHI." << *Phi << "\n");
+ return true;
+ }
+ if (AddReductionVar(Phi, RecurKind::UMax, TheLoop, HasFunNoNaNAttr, RedDes,
+ DB, AC, DT)) {
+ LLVM_DEBUG(dbgs() << "Found a UMAX reduction PHI." << *Phi << "\n");
+ return true;
+ }
+ if (AddReductionVar(Phi, RecurKind::UMin, TheLoop, HasFunNoNaNAttr, RedDes,
DB, AC, DT)) {
- LLVM_DEBUG(dbgs() << "Found a SMAX reduction PHI." << *Phi << "\n");
+ LLVM_DEBUG(dbgs() << "Found a UMIN reduction PHI." << *Phi << "\n");
return true;
}
- if (AddReductionVar(Phi, RecurKind::SMin, TheLoop, HasFunNoNaNAttr, RedDes,
- DB, AC, DT)) {
- LLVM_DEBUG(dbgs() << "Found a SMIN reduction PHI." << *Phi << "\n");
- return true;
- }
- if (AddReductionVar(Phi, RecurKind::UMax, TheLoop, HasFunNoNaNAttr, RedDes,
- DB, AC, DT)) {
- LLVM_DEBUG(dbgs() << "Found a UMAX reduction PHI." << *Phi << "\n");
- return true;
- }
- if (AddReductionVar(Phi, RecurKind::UMin, TheLoop, HasFunNoNaNAttr, RedDes,
- DB, AC, DT)) {
- LLVM_DEBUG(dbgs() << "Found a UMIN reduction PHI." << *Phi << "\n");
- return true;
- }
- if (AddReductionVar(Phi, RecurKind::FMul, TheLoop, HasFunNoNaNAttr, RedDes,
- DB, AC, DT)) {
+ if (AddReductionVar(Phi, RecurKind::FMul, TheLoop, HasFunNoNaNAttr, RedDes,
+ DB, AC, DT)) {
LLVM_DEBUG(dbgs() << "Found an FMult reduction PHI." << *Phi << "\n");
return true;
}
- if (AddReductionVar(Phi, RecurKind::FAdd, TheLoop, HasFunNoNaNAttr, RedDes,
- DB, AC, DT)) {
+ if (AddReductionVar(Phi, RecurKind::FAdd, TheLoop, HasFunNoNaNAttr, RedDes,
+ DB, AC, DT)) {
LLVM_DEBUG(dbgs() << "Found an FAdd reduction PHI." << *Phi << "\n");
return true;
}
- if (AddReductionVar(Phi, RecurKind::FMax, TheLoop, HasFunNoNaNAttr, RedDes,
- DB, AC, DT)) {
- LLVM_DEBUG(dbgs() << "Found a float MAX reduction PHI." << *Phi << "\n");
+ if (AddReductionVar(Phi, RecurKind::FMax, TheLoop, HasFunNoNaNAttr, RedDes,
+ DB, AC, DT)) {
+ LLVM_DEBUG(dbgs() << "Found a float MAX reduction PHI." << *Phi << "\n");
+ return true;
+ }
+ if (AddReductionVar(Phi, RecurKind::FMin, TheLoop, HasFunNoNaNAttr, RedDes,
+ DB, AC, DT)) {
+ LLVM_DEBUG(dbgs() << "Found a float MIN reduction PHI." << *Phi << "\n");
return true;
}
- if (AddReductionVar(Phi, RecurKind::FMin, TheLoop, HasFunNoNaNAttr, RedDes,
- DB, AC, DT)) {
- LLVM_DEBUG(dbgs() << "Found a float MIN reduction PHI." << *Phi << "\n");
- return true;
- }
// Not a reduction of known type.
return false;
}
@@ -764,143 +764,143 @@ bool RecurrenceDescriptor::isFirstOrderRecurrence(
/// This function returns the identity element (or neutral element) for
/// the operation K.
-Constant *RecurrenceDescriptor::getRecurrenceIdentity(RecurKind K, Type *Tp) {
+Constant *RecurrenceDescriptor::getRecurrenceIdentity(RecurKind K, Type *Tp) {
switch (K) {
- case RecurKind::Xor:
- case RecurKind::Add:
- case RecurKind::Or:
+ case RecurKind::Xor:
+ case RecurKind::Add:
+ case RecurKind::Or:
// Adding, Xoring, Oring zero to a number does not change it.
return ConstantInt::get(Tp, 0);
- case RecurKind::Mul:
+ case RecurKind::Mul:
// Multiplying a number by 1 does not change it.
return ConstantInt::get(Tp, 1);
- case RecurKind::And:
+ case RecurKind::And:
// AND-ing a number with an all-1 value does not change it.
return ConstantInt::get(Tp, -1, true);
- case RecurKind::FMul:
+ case RecurKind::FMul:
// Multiplying a number by 1 does not change it.
return ConstantFP::get(Tp, 1.0L);
- case RecurKind::FAdd:
+ case RecurKind::FAdd:
// Adding zero to a number does not change it.
return ConstantFP::get(Tp, 0.0L);
- case RecurKind::UMin:
- return ConstantInt::get(Tp, -1);
- case RecurKind::UMax:
- return ConstantInt::get(Tp, 0);
- case RecurKind::SMin:
- return ConstantInt::get(Tp,
- APInt::getSignedMaxValue(Tp->getIntegerBitWidth()));
- case RecurKind::SMax:
- return ConstantInt::get(Tp,
- APInt::getSignedMinValue(Tp->getIntegerBitWidth()));
- case RecurKind::FMin:
- return ConstantFP::getInfinity(Tp, true);
- case RecurKind::FMax:
- return ConstantFP::getInfinity(Tp, false);
+ case RecurKind::UMin:
+ return ConstantInt::get(Tp, -1);
+ case RecurKind::UMax:
+ return ConstantInt::get(Tp, 0);
+ case RecurKind::SMin:
+ return ConstantInt::get(Tp,
+ APInt::getSignedMaxValue(Tp->getIntegerBitWidth()));
+ case RecurKind::SMax:
+ return ConstantInt::get(Tp,
+ APInt::getSignedMinValue(Tp->getIntegerBitWidth()));
+ case RecurKind::FMin:
+ return ConstantFP::getInfinity(Tp, true);
+ case RecurKind::FMax:
+ return ConstantFP::getInfinity(Tp, false);
default:
llvm_unreachable("Unknown recurrence kind");
}
}
-unsigned RecurrenceDescriptor::getOpcode(RecurKind Kind) {
+unsigned RecurrenceDescriptor::getOpcode(RecurKind Kind) {
switch (Kind) {
- case RecurKind::Add:
+ case RecurKind::Add:
return Instruction::Add;
- case RecurKind::Mul:
+ case RecurKind::Mul:
return Instruction::Mul;
- case RecurKind::Or:
+ case RecurKind::Or:
return Instruction::Or;
- case RecurKind::And:
+ case RecurKind::And:
return Instruction::And;
- case RecurKind::Xor:
+ case RecurKind::Xor:
return Instruction::Xor;
- case RecurKind::FMul:
+ case RecurKind::FMul:
return Instruction::FMul;
- case RecurKind::FAdd:
+ case RecurKind::FAdd:
return Instruction::FAdd;
- case RecurKind::SMax:
- case RecurKind::SMin:
- case RecurKind::UMax:
- case RecurKind::UMin:
+ case RecurKind::SMax:
+ case RecurKind::SMin:
+ case RecurKind::UMax:
+ case RecurKind::UMin:
return Instruction::ICmp;
- case RecurKind::FMax:
- case RecurKind::FMin:
+ case RecurKind::FMax:
+ case RecurKind::FMin:
return Instruction::FCmp;
default:
llvm_unreachable("Unknown recurrence operation");
}
}
-SmallVector<Instruction *, 4>
-RecurrenceDescriptor::getReductionOpChain(PHINode *Phi, Loop *L) const {
- SmallVector<Instruction *, 4> ReductionOperations;
- unsigned RedOp = getOpcode(Kind);
-
- // Search down from the Phi to the LoopExitInstr, looking for instructions
- // with a single user of the correct type for the reduction.
-
- // Note that we check that the type of the operand is correct for each item in
- // the chain, including the last (the loop exit value). This can come up from
- // sub, which would otherwise be treated as an add reduction. MinMax also need
- // to check for a pair of icmp/select, for which we use getNextInstruction and
- // isCorrectOpcode functions to step the right number of instruction, and
- // check the icmp/select pair.
- // FIXME: We also do not attempt to look through Phi/Select's yet, which might
- // be part of the reduction chain, or attempt to looks through And's to find a
- // smaller bitwidth. Subs are also currently not allowed (which are usually
- // treated as part of a add reduction) as they are expected to generally be
- // more expensive than out-of-loop reductions, and need to be costed more
- // carefully.
- unsigned ExpectedUses = 1;
- if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp)
- ExpectedUses = 2;
-
- auto getNextInstruction = [&](Instruction *Cur) {
- if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp) {
- // We are expecting a icmp/select pair, which we go to the next select
- // instruction if we can. We already know that Cur has 2 uses.
- if (isa<SelectInst>(*Cur->user_begin()))
- return cast<Instruction>(*Cur->user_begin());
- else
- return cast<Instruction>(*std::next(Cur->user_begin()));
- }
- return cast<Instruction>(*Cur->user_begin());
- };
- auto isCorrectOpcode = [&](Instruction *Cur) {
- if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp) {
- Value *LHS, *RHS;
- return SelectPatternResult::isMinOrMax(
- matchSelectPattern(Cur, LHS, RHS).Flavor);
- }
- return Cur->getOpcode() == RedOp;
- };
-
- // The loop exit instruction we check first (as a quick test) but add last. We
- // check the opcode is correct (and dont allow them to be Subs) and that they
- // have expected to have the expected number of uses. They will have one use
- // from the phi and one from a LCSSA value, no matter the type.
- if (!isCorrectOpcode(LoopExitInstr) || !LoopExitInstr->hasNUses(2))
- return {};
-
- // Check that the Phi has one (or two for min/max) uses.
- if (!Phi->hasNUses(ExpectedUses))
- return {};
- Instruction *Cur = getNextInstruction(Phi);
-
- // Each other instruction in the chain should have the expected number of uses
- // and be the correct opcode.
- while (Cur != LoopExitInstr) {
- if (!isCorrectOpcode(Cur) || !Cur->hasNUses(ExpectedUses))
- return {};
-
- ReductionOperations.push_back(Cur);
- Cur = getNextInstruction(Cur);
- }
-
- ReductionOperations.push_back(Cur);
- return ReductionOperations;
-}
-
+SmallVector<Instruction *, 4>
+RecurrenceDescriptor::getReductionOpChain(PHINode *Phi, Loop *L) const {
+ SmallVector<Instruction *, 4> ReductionOperations;
+ unsigned RedOp = getOpcode(Kind);
+
+ // Search down from the Phi to the LoopExitInstr, looking for instructions
+ // with a single user of the correct type for the reduction.
+
+ // Note that we check that the type of the operand is correct for each item in
+ // the chain, including the last (the loop exit value). This can come up from
+ // sub, which would otherwise be treated as an add reduction. MinMax also need
+ // to check for a pair of icmp/select, for which we use getNextInstruction and
+ // isCorrectOpcode functions to step the right number of instruction, and
+ // check the icmp/select pair.
+ // FIXME: We also do not attempt to look through Phi/Select's yet, which might
+ // be part of the reduction chain, or attempt to looks through And's to find a
+ // smaller bitwidth. Subs are also currently not allowed (which are usually
+ // treated as part of a add reduction) as they are expected to generally be
+ // more expensive than out-of-loop reductions, and need to be costed more
+ // carefully.
+ unsigned ExpectedUses = 1;
+ if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp)
+ ExpectedUses = 2;
+
+ auto getNextInstruction = [&](Instruction *Cur) {
+ if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp) {
+ // We are expecting a icmp/select pair, which we go to the next select
+ // instruction if we can. We already know that Cur has 2 uses.
+ if (isa<SelectInst>(*Cur->user_begin()))
+ return cast<Instruction>(*Cur->user_begin());
+ else
+ return cast<Instruction>(*std::next(Cur->user_begin()));
+ }
+ return cast<Instruction>(*Cur->user_begin());
+ };
+ auto isCorrectOpcode = [&](Instruction *Cur) {
+ if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp) {
+ Value *LHS, *RHS;
+ return SelectPatternResult::isMinOrMax(
+ matchSelectPattern(Cur, LHS, RHS).Flavor);
+ }
+ return Cur->getOpcode() == RedOp;
+ };
+
+ // The loop exit instruction we check first (as a quick test) but add last. We
+ // check the opcode is correct (and dont allow them to be Subs) and that they
+ // have expected to have the expected number of uses. They will have one use
+ // from the phi and one from a LCSSA value, no matter the type.
+ if (!isCorrectOpcode(LoopExitInstr) || !LoopExitInstr->hasNUses(2))
+ return {};
+
+ // Check that the Phi has one (or two for min/max) uses.
+ if (!Phi->hasNUses(ExpectedUses))
+ return {};
+ Instruction *Cur = getNextInstruction(Phi);
+
+ // Each other instruction in the chain should have the expected number of uses
+ // and be the correct opcode.
+ while (Cur != LoopExitInstr) {
+ if (!isCorrectOpcode(Cur) || !Cur->hasNUses(ExpectedUses))
+ return {};
+
+ ReductionOperations.push_back(Cur);
+ Cur = getNextInstruction(Cur);
+ }
+
+ ReductionOperations.push_back(Cur);
+ return ReductionOperations;
+}
+
InductionDescriptor::InductionDescriptor(Value *Start, InductionKind K,
const SCEV *Step, BinaryOperator *BOp,
SmallVectorImpl<Instruction *> *Casts)
diff --git a/contrib/libs/llvm12/lib/Analysis/ImportedFunctionsInliningStatistics.cpp b/contrib/libs/llvm12/lib/Analysis/ImportedFunctionsInliningStatistics.cpp
index d057fe4ba9..a7b5fda237 100644
--- a/contrib/libs/llvm12/lib/Analysis/ImportedFunctionsInliningStatistics.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/ImportedFunctionsInliningStatistics.cpp
@@ -1,212 +1,212 @@
-//===-- ImportedFunctionsInliningStats.cpp ----------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-// Generating inliner statistics for imported functions, mostly useful for
-// ThinLTO.
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <iomanip>
-#include <sstream>
-using namespace llvm;
-
-cl::opt<InlinerFunctionImportStatsOpts> InlinerFunctionImportStats(
- "inliner-function-import-stats",
- cl::init(InlinerFunctionImportStatsOpts::No),
- cl::values(clEnumValN(InlinerFunctionImportStatsOpts::Basic, "basic",
- "basic statistics"),
- clEnumValN(InlinerFunctionImportStatsOpts::Verbose, "verbose",
- "printing of statistics for each inlined function")),
- cl::Hidden, cl::desc("Enable inliner stats for imported functions"));
-
-ImportedFunctionsInliningStatistics::InlineGraphNode &
-ImportedFunctionsInliningStatistics::createInlineGraphNode(const Function &F) {
-
- auto &ValueLookup = NodesMap[F.getName()];
- if (!ValueLookup) {
- ValueLookup = std::make_unique<InlineGraphNode>();
- ValueLookup->Imported = F.hasMetadata("thinlto_src_module");
- }
- return *ValueLookup;
-}
-
-void ImportedFunctionsInliningStatistics::recordInline(const Function &Caller,
- const Function &Callee) {
-
- InlineGraphNode &CallerNode = createInlineGraphNode(Caller);
- InlineGraphNode &CalleeNode = createInlineGraphNode(Callee);
- CalleeNode.NumberOfInlines++;
-
- if (!CallerNode.Imported && !CalleeNode.Imported) {
- // Direct inline from not imported callee to not imported caller, so we
- // don't have to add this to graph. It might be very helpful if you wanna
- // get the inliner statistics in compile step where there are no imported
- // functions. In this case the graph would be empty.
- CalleeNode.NumberOfRealInlines++;
- return;
- }
-
- CallerNode.InlinedCallees.push_back(&CalleeNode);
- if (!CallerNode.Imported) {
- // We could avoid second lookup, but it would make the code ultra ugly.
- auto It = NodesMap.find(Caller.getName());
- assert(It != NodesMap.end() && "The node should be already there.");
- // Save Caller as a starting node for traversal. The string has to be one
- // from map because Caller can disappear (and function name with it).
- NonImportedCallers.push_back(It->first());
- }
-}
-
-void ImportedFunctionsInliningStatistics::setModuleInfo(const Module &M) {
- ModuleName = M.getName();
- for (const auto &F : M.functions()) {
- if (F.isDeclaration())
- continue;
- AllFunctions++;
- ImportedFunctions += int(F.hasMetadata("thinlto_src_module"));
- }
-}
-static std::string getStatString(const char *Msg, int32_t Fraction, int32_t All,
- const char *PercentageOfMsg,
- bool LineEnd = true) {
- double Result = 0;
- if (All != 0)
- Result = 100 * static_cast<double>(Fraction) / All;
-
- std::stringstream Str;
- Str << std::setprecision(4) << Msg << ": " << Fraction << " [" << Result
- << "% of " << PercentageOfMsg << "]";
- if (LineEnd)
- Str << "\n";
- return Str.str();
-}
-
-void ImportedFunctionsInliningStatistics::dump(const bool Verbose) {
- calculateRealInlines();
- NonImportedCallers.clear();
-
- int32_t InlinedImportedFunctionsCount = 0;
- int32_t InlinedNotImportedFunctionsCount = 0;
-
- int32_t InlinedImportedFunctionsToImportingModuleCount = 0;
- int32_t InlinedNotImportedFunctionsToImportingModuleCount = 0;
-
- const auto SortedNodes = getSortedNodes();
- std::string Out;
- Out.reserve(5000);
- raw_string_ostream Ostream(Out);
-
- Ostream << "------- Dumping inliner stats for [" << ModuleName
- << "] -------\n";
-
- if (Verbose)
- Ostream << "-- List of inlined functions:\n";
-
- for (const auto &Node : SortedNodes) {
- assert(Node->second->NumberOfInlines >= Node->second->NumberOfRealInlines);
- if (Node->second->NumberOfInlines == 0)
- continue;
-
- if (Node->second->Imported) {
- InlinedImportedFunctionsCount++;
- InlinedImportedFunctionsToImportingModuleCount +=
- int(Node->second->NumberOfRealInlines > 0);
- } else {
- InlinedNotImportedFunctionsCount++;
- InlinedNotImportedFunctionsToImportingModuleCount +=
- int(Node->second->NumberOfRealInlines > 0);
- }
-
- if (Verbose)
- Ostream << "Inlined "
- << (Node->second->Imported ? "imported " : "not imported ")
- << "function [" << Node->first() << "]"
- << ": #inlines = " << Node->second->NumberOfInlines
- << ", #inlines_to_importing_module = "
- << Node->second->NumberOfRealInlines << "\n";
- }
-
- auto InlinedFunctionsCount =
- InlinedImportedFunctionsCount + InlinedNotImportedFunctionsCount;
- auto NotImportedFuncCount = AllFunctions - ImportedFunctions;
- auto ImportedNotInlinedIntoModule =
- ImportedFunctions - InlinedImportedFunctionsToImportingModuleCount;
-
- Ostream << "-- Summary:\n"
- << "All functions: " << AllFunctions
- << ", imported functions: " << ImportedFunctions << "\n"
- << getStatString("inlined functions", InlinedFunctionsCount,
- AllFunctions, "all functions")
- << getStatString("imported functions inlined anywhere",
- InlinedImportedFunctionsCount, ImportedFunctions,
- "imported functions")
- << getStatString("imported functions inlined into importing module",
- InlinedImportedFunctionsToImportingModuleCount,
- ImportedFunctions, "imported functions",
- /*LineEnd=*/false)
- << getStatString(", remaining", ImportedNotInlinedIntoModule,
- ImportedFunctions, "imported functions")
- << getStatString("non-imported functions inlined anywhere",
- InlinedNotImportedFunctionsCount,
- NotImportedFuncCount, "non-imported functions")
- << getStatString(
- "non-imported functions inlined into importing module",
- InlinedNotImportedFunctionsToImportingModuleCount,
- NotImportedFuncCount, "non-imported functions");
- Ostream.flush();
- dbgs() << Out;
-}
-
-void ImportedFunctionsInliningStatistics::calculateRealInlines() {
- // Removing duplicated Callers.
- llvm::sort(NonImportedCallers);
- NonImportedCallers.erase(
- std::unique(NonImportedCallers.begin(), NonImportedCallers.end()),
- NonImportedCallers.end());
-
- for (const auto &Name : NonImportedCallers) {
- auto &Node = *NodesMap[Name];
- if (!Node.Visited)
- dfs(Node);
- }
-}
-
-void ImportedFunctionsInliningStatistics::dfs(InlineGraphNode &GraphNode) {
- assert(!GraphNode.Visited);
- GraphNode.Visited = true;
- for (auto *const InlinedFunctionNode : GraphNode.InlinedCallees) {
- InlinedFunctionNode->NumberOfRealInlines++;
- if (!InlinedFunctionNode->Visited)
- dfs(*InlinedFunctionNode);
- }
-}
-
-ImportedFunctionsInliningStatistics::SortedNodesTy
-ImportedFunctionsInliningStatistics::getSortedNodes() {
- SortedNodesTy SortedNodes;
- SortedNodes.reserve(NodesMap.size());
- for (const NodesMapTy::value_type &Node : NodesMap)
- SortedNodes.push_back(&Node);
-
- llvm::sort(SortedNodes, [&](const SortedNodesTy::value_type &Lhs,
- const SortedNodesTy::value_type &Rhs) {
- if (Lhs->second->NumberOfInlines != Rhs->second->NumberOfInlines)
- return Lhs->second->NumberOfInlines > Rhs->second->NumberOfInlines;
- if (Lhs->second->NumberOfRealInlines != Rhs->second->NumberOfRealInlines)
- return Lhs->second->NumberOfRealInlines >
- Rhs->second->NumberOfRealInlines;
- return Lhs->first() < Rhs->first();
- });
- return SortedNodes;
-}
+//===-- ImportedFunctionsInliningStats.cpp ----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// Generating inliner statistics for imported functions, mostly useful for
+// ThinLTO.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <iomanip>
+#include <sstream>
+using namespace llvm;
+
+cl::opt<InlinerFunctionImportStatsOpts> InlinerFunctionImportStats(
+ "inliner-function-import-stats",
+ cl::init(InlinerFunctionImportStatsOpts::No),
+ cl::values(clEnumValN(InlinerFunctionImportStatsOpts::Basic, "basic",
+ "basic statistics"),
+ clEnumValN(InlinerFunctionImportStatsOpts::Verbose, "verbose",
+ "printing of statistics for each inlined function")),
+ cl::Hidden, cl::desc("Enable inliner stats for imported functions"));
+
+ImportedFunctionsInliningStatistics::InlineGraphNode &
+ImportedFunctionsInliningStatistics::createInlineGraphNode(const Function &F) {
+
+ auto &ValueLookup = NodesMap[F.getName()];
+ if (!ValueLookup) {
+ ValueLookup = std::make_unique<InlineGraphNode>();
+ ValueLookup->Imported = F.hasMetadata("thinlto_src_module");
+ }
+ return *ValueLookup;
+}
+
+void ImportedFunctionsInliningStatistics::recordInline(const Function &Caller,
+ const Function &Callee) {
+
+ InlineGraphNode &CallerNode = createInlineGraphNode(Caller);
+ InlineGraphNode &CalleeNode = createInlineGraphNode(Callee);
+ CalleeNode.NumberOfInlines++;
+
+ if (!CallerNode.Imported && !CalleeNode.Imported) {
+ // Direct inline from not imported callee to not imported caller, so we
+ // don't have to add this to graph. It might be very helpful if you wanna
+ // get the inliner statistics in compile step where there are no imported
+ // functions. In this case the graph would be empty.
+ CalleeNode.NumberOfRealInlines++;
+ return;
+ }
+
+ CallerNode.InlinedCallees.push_back(&CalleeNode);
+ if (!CallerNode.Imported) {
+ // We could avoid second lookup, but it would make the code ultra ugly.
+ auto It = NodesMap.find(Caller.getName());
+ assert(It != NodesMap.end() && "The node should be already there.");
+ // Save Caller as a starting node for traversal. The string has to be one
+ // from map because Caller can disappear (and function name with it).
+ NonImportedCallers.push_back(It->first());
+ }
+}
+
+void ImportedFunctionsInliningStatistics::setModuleInfo(const Module &M) {
+ ModuleName = M.getName();
+ for (const auto &F : M.functions()) {
+ if (F.isDeclaration())
+ continue;
+ AllFunctions++;
+ ImportedFunctions += int(F.hasMetadata("thinlto_src_module"));
+ }
+}
+static std::string getStatString(const char *Msg, int32_t Fraction, int32_t All,
+ const char *PercentageOfMsg,
+ bool LineEnd = true) {
+ double Result = 0;
+ if (All != 0)
+ Result = 100 * static_cast<double>(Fraction) / All;
+
+ std::stringstream Str;
+ Str << std::setprecision(4) << Msg << ": " << Fraction << " [" << Result
+ << "% of " << PercentageOfMsg << "]";
+ if (LineEnd)
+ Str << "\n";
+ return Str.str();
+}
+
+void ImportedFunctionsInliningStatistics::dump(const bool Verbose) {
+ calculateRealInlines();
+ NonImportedCallers.clear();
+
+ int32_t InlinedImportedFunctionsCount = 0;
+ int32_t InlinedNotImportedFunctionsCount = 0;
+
+ int32_t InlinedImportedFunctionsToImportingModuleCount = 0;
+ int32_t InlinedNotImportedFunctionsToImportingModuleCount = 0;
+
+ const auto SortedNodes = getSortedNodes();
+ std::string Out;
+ Out.reserve(5000);
+ raw_string_ostream Ostream(Out);
+
+ Ostream << "------- Dumping inliner stats for [" << ModuleName
+ << "] -------\n";
+
+ if (Verbose)
+ Ostream << "-- List of inlined functions:\n";
+
+ for (const auto &Node : SortedNodes) {
+ assert(Node->second->NumberOfInlines >= Node->second->NumberOfRealInlines);
+ if (Node->second->NumberOfInlines == 0)
+ continue;
+
+ if (Node->second->Imported) {
+ InlinedImportedFunctionsCount++;
+ InlinedImportedFunctionsToImportingModuleCount +=
+ int(Node->second->NumberOfRealInlines > 0);
+ } else {
+ InlinedNotImportedFunctionsCount++;
+ InlinedNotImportedFunctionsToImportingModuleCount +=
+ int(Node->second->NumberOfRealInlines > 0);
+ }
+
+ if (Verbose)
+ Ostream << "Inlined "
+ << (Node->second->Imported ? "imported " : "not imported ")
+ << "function [" << Node->first() << "]"
+ << ": #inlines = " << Node->second->NumberOfInlines
+ << ", #inlines_to_importing_module = "
+ << Node->second->NumberOfRealInlines << "\n";
+ }
+
+ auto InlinedFunctionsCount =
+ InlinedImportedFunctionsCount + InlinedNotImportedFunctionsCount;
+ auto NotImportedFuncCount = AllFunctions - ImportedFunctions;
+ auto ImportedNotInlinedIntoModule =
+ ImportedFunctions - InlinedImportedFunctionsToImportingModuleCount;
+
+ Ostream << "-- Summary:\n"
+ << "All functions: " << AllFunctions
+ << ", imported functions: " << ImportedFunctions << "\n"
+ << getStatString("inlined functions", InlinedFunctionsCount,
+ AllFunctions, "all functions")
+ << getStatString("imported functions inlined anywhere",
+ InlinedImportedFunctionsCount, ImportedFunctions,
+ "imported functions")
+ << getStatString("imported functions inlined into importing module",
+ InlinedImportedFunctionsToImportingModuleCount,
+ ImportedFunctions, "imported functions",
+ /*LineEnd=*/false)
+ << getStatString(", remaining", ImportedNotInlinedIntoModule,
+ ImportedFunctions, "imported functions")
+ << getStatString("non-imported functions inlined anywhere",
+ InlinedNotImportedFunctionsCount,
+ NotImportedFuncCount, "non-imported functions")
+ << getStatString(
+ "non-imported functions inlined into importing module",
+ InlinedNotImportedFunctionsToImportingModuleCount,
+ NotImportedFuncCount, "non-imported functions");
+ Ostream.flush();
+ dbgs() << Out;
+}
+
+void ImportedFunctionsInliningStatistics::calculateRealInlines() {
+ // Removing duplicated Callers.
+ llvm::sort(NonImportedCallers);
+ NonImportedCallers.erase(
+ std::unique(NonImportedCallers.begin(), NonImportedCallers.end()),
+ NonImportedCallers.end());
+
+ for (const auto &Name : NonImportedCallers) {
+ auto &Node = *NodesMap[Name];
+ if (!Node.Visited)
+ dfs(Node);
+ }
+}
+
+void ImportedFunctionsInliningStatistics::dfs(InlineGraphNode &GraphNode) {
+ assert(!GraphNode.Visited);
+ GraphNode.Visited = true;
+ for (auto *const InlinedFunctionNode : GraphNode.InlinedCallees) {
+ InlinedFunctionNode->NumberOfRealInlines++;
+ if (!InlinedFunctionNode->Visited)
+ dfs(*InlinedFunctionNode);
+ }
+}
+
+ImportedFunctionsInliningStatistics::SortedNodesTy
+ImportedFunctionsInliningStatistics::getSortedNodes() {
+ SortedNodesTy SortedNodes;
+ SortedNodes.reserve(NodesMap.size());
+ for (const NodesMapTy::value_type &Node : NodesMap)
+ SortedNodes.push_back(&Node);
+
+ llvm::sort(SortedNodes, [&](const SortedNodesTy::value_type &Lhs,
+ const SortedNodesTy::value_type &Rhs) {
+ if (Lhs->second->NumberOfInlines != Rhs->second->NumberOfInlines)
+ return Lhs->second->NumberOfInlines > Rhs->second->NumberOfInlines;
+ if (Lhs->second->NumberOfRealInlines != Rhs->second->NumberOfRealInlines)
+ return Lhs->second->NumberOfRealInlines >
+ Rhs->second->NumberOfRealInlines;
+ return Lhs->first() < Rhs->first();
+ });
+ return SortedNodes;
+}
diff --git a/contrib/libs/llvm12/lib/Analysis/IndirectCallPromotionAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/IndirectCallPromotionAnalysis.cpp
index db764559c5..b112ed2e44 100644
--- a/contrib/libs/llvm12/lib/Analysis/IndirectCallPromotionAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/IndirectCallPromotionAnalysis.cpp
@@ -22,7 +22,7 @@
#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
-#include <memory>
+#include <memory>
using namespace llvm;
diff --git a/contrib/libs/llvm12/lib/Analysis/InlineAdvisor.cpp b/contrib/libs/llvm12/lib/Analysis/InlineAdvisor.cpp
index e1330d5809..9a2276a161 100644
--- a/contrib/libs/llvm12/lib/Analysis/InlineAdvisor.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/InlineAdvisor.cpp
@@ -16,7 +16,7 @@
#include "llvm/Analysis/InlineCost.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
-#include "llvm/Analysis/ReplayInlineAdvisor.h"
+#include "llvm/Analysis/ReplayInlineAdvisor.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
@@ -49,33 +49,33 @@ static cl::opt<int>
cl::desc("Scale to limit the cost of inline deferral"),
cl::init(2), cl::Hidden);
-extern cl::opt<InlinerFunctionImportStatsOpts> InlinerFunctionImportStats;
-
-void DefaultInlineAdvice::recordUnsuccessfulInliningImpl(
- const InlineResult &Result) {
- using namespace ore;
- llvm::setInlineRemark(*OriginalCB, std::string(Result.getFailureReason()) +
- "; " + inlineCostStr(*OIC));
- ORE.emit([&]() {
- return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block)
- << NV("Callee", Callee) << " will not be inlined into "
- << NV("Caller", Caller) << ": "
- << NV("Reason", Result.getFailureReason());
- });
-}
-
-void DefaultInlineAdvice::recordInliningWithCalleeDeletedImpl() {
- if (EmitRemarks)
+extern cl::opt<InlinerFunctionImportStatsOpts> InlinerFunctionImportStats;
+
+void DefaultInlineAdvice::recordUnsuccessfulInliningImpl(
+ const InlineResult &Result) {
+ using namespace ore;
+ llvm::setInlineRemark(*OriginalCB, std::string(Result.getFailureReason()) +
+ "; " + inlineCostStr(*OIC));
+ ORE.emit([&]() {
+ return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block)
+ << NV("Callee", Callee) << " will not be inlined into "
+ << NV("Caller", Caller) << ": "
+ << NV("Reason", Result.getFailureReason());
+ });
+}
+
+void DefaultInlineAdvice::recordInliningWithCalleeDeletedImpl() {
+ if (EmitRemarks)
emitInlinedInto(ORE, DLoc, Block, *Callee, *Caller, *OIC);
-}
+}
-void DefaultInlineAdvice::recordInliningImpl() {
- if (EmitRemarks)
+void DefaultInlineAdvice::recordInliningImpl() {
+ if (EmitRemarks)
emitInlinedInto(ORE, DLoc, Block, *Callee, *Caller, *OIC);
-}
+}
-llvm::Optional<llvm::InlineCost> static getDefaultInlineAdvice(
- CallBase &CB, FunctionAnalysisManager &FAM, const InlineParams &Params) {
+llvm::Optional<llvm::InlineCost> static getDefaultInlineAdvice(
+ CallBase &CB, FunctionAnalysisManager &FAM, const InlineParams &Params) {
Function &Caller = *CB.getCaller();
ProfileSummaryInfo *PSI =
FAM.getResult<ModuleAnalysisManagerFunctionProxy>(Caller)
@@ -103,11 +103,11 @@ llvm::Optional<llvm::InlineCost> static getDefaultInlineAdvice(
GetBFI, PSI, RemarksEnabled ? &ORE : nullptr);
};
return llvm::shouldInline(CB, GetInlineCost, ORE,
- Params.EnableDeferral.getValueOr(false));
+ Params.EnableDeferral.getValueOr(false));
}
-std::unique_ptr<InlineAdvice>
-DefaultInlineAdvisor::getAdviceImpl(CallBase &CB) {
+std::unique_ptr<InlineAdvice>
+DefaultInlineAdvisor::getAdviceImpl(CallBase &CB) {
auto OIC = getDefaultInlineAdvice(CB, FAM, Params);
return std::make_unique<DefaultInlineAdvice>(
this, CB, OIC,
@@ -133,20 +133,20 @@ void InlineAdvisor::freeDeletedFunctions() {
DeletedFunctions.clear();
}
-void InlineAdvice::recordInlineStatsIfNeeded() {
- if (Advisor->ImportedFunctionsStats)
- Advisor->ImportedFunctionsStats->recordInline(*Caller, *Callee);
-}
-
-void InlineAdvice::recordInlining() {
- markRecorded();
- recordInlineStatsIfNeeded();
- recordInliningImpl();
-}
-
+void InlineAdvice::recordInlineStatsIfNeeded() {
+ if (Advisor->ImportedFunctionsStats)
+ Advisor->ImportedFunctionsStats->recordInline(*Caller, *Callee);
+}
+
+void InlineAdvice::recordInlining() {
+ markRecorded();
+ recordInlineStatsIfNeeded();
+ recordInliningImpl();
+}
+
void InlineAdvice::recordInliningWithCalleeDeleted() {
markRecorded();
- recordInlineStatsIfNeeded();
+ recordInlineStatsIfNeeded();
Advisor->markFunctionAsDeleted(Callee);
recordInliningWithCalleeDeletedImpl();
}
@@ -154,28 +154,28 @@ void InlineAdvice::recordInliningWithCalleeDeleted() {
AnalysisKey InlineAdvisorAnalysis::Key;
bool InlineAdvisorAnalysis::Result::tryCreate(InlineParams Params,
- InliningAdvisorMode Mode,
- StringRef ReplayFile) {
+ InliningAdvisorMode Mode,
+ StringRef ReplayFile) {
auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
switch (Mode) {
case InliningAdvisorMode::Default:
- Advisor.reset(new DefaultInlineAdvisor(M, FAM, Params));
- // Restrict replay to default advisor, ML advisors are stateful so
- // replay will need augmentations to interleave with them correctly.
- if (!ReplayFile.empty()) {
- Advisor = std::make_unique<ReplayInlineAdvisor>(
- M, FAM, M.getContext(), std::move(Advisor), ReplayFile,
- /* EmitRemarks =*/true);
- }
+ Advisor.reset(new DefaultInlineAdvisor(M, FAM, Params));
+ // Restrict replay to default advisor, ML advisors are stateful so
+ // replay will need augmentations to interleave with them correctly.
+ if (!ReplayFile.empty()) {
+ Advisor = std::make_unique<ReplayInlineAdvisor>(
+ M, FAM, M.getContext(), std::move(Advisor), ReplayFile,
+ /* EmitRemarks =*/true);
+ }
break;
case InliningAdvisorMode::Development:
-#ifdef LLVM_HAVE_TF_API
- Advisor =
- llvm::getDevelopmentModeAdvisor(M, MAM, [&FAM, Params](CallBase &CB) {
- auto OIC = getDefaultInlineAdvice(CB, FAM, Params);
- return OIC.hasValue();
- });
-#endif
+#ifdef LLVM_HAVE_TF_API
+ Advisor =
+ llvm::getDevelopmentModeAdvisor(M, MAM, [&FAM, Params](CallBase &CB) {
+ auto OIC = getDefaultInlineAdvice(CB, FAM, Params);
+ return OIC.hasValue();
+ });
+#endif
break;
case InliningAdvisorMode::Release:
#ifdef LLVM_HAVE_TF_AOT
@@ -183,7 +183,7 @@ bool InlineAdvisorAnalysis::Result::tryCreate(InlineParams Params,
#endif
break;
}
-
+
return !!Advisor;
}
@@ -382,35 +382,35 @@ llvm::shouldInline(CallBase &CB,
return IC;
}
-std::string llvm::getCallSiteLocation(DebugLoc DLoc) {
- std::ostringstream CallSiteLoc;
- bool First = true;
- for (DILocation *DIL = DLoc.get(); DIL; DIL = DIL->getInlinedAt()) {
- if (!First)
- CallSiteLoc << " @ ";
- // Note that negative line offset is actually possible, but we use
- // unsigned int to match line offset representation in remarks so
- // it's directly consumable by relay advisor.
- uint32_t Offset =
- DIL->getLine() - DIL->getScope()->getSubprogram()->getLine();
- uint32_t Discriminator = DIL->getBaseDiscriminator();
- StringRef Name = DIL->getScope()->getSubprogram()->getLinkageName();
- if (Name.empty())
- Name = DIL->getScope()->getSubprogram()->getName();
- CallSiteLoc << Name.str() << ":" << llvm::utostr(Offset) << ":"
- << llvm::utostr(DIL->getColumn());
- if (Discriminator)
- CallSiteLoc << "." << llvm::utostr(Discriminator);
- First = false;
- }
-
- return CallSiteLoc.str();
-}
-
+std::string llvm::getCallSiteLocation(DebugLoc DLoc) {
+ std::ostringstream CallSiteLoc;
+ bool First = true;
+ for (DILocation *DIL = DLoc.get(); DIL; DIL = DIL->getInlinedAt()) {
+ if (!First)
+ CallSiteLoc << " @ ";
+ // Note that negative line offset is actually possible, but we use
+ // unsigned int to match line offset representation in remarks so
+ // it's directly consumable by relay advisor.
+ uint32_t Offset =
+ DIL->getLine() - DIL->getScope()->getSubprogram()->getLine();
+ uint32_t Discriminator = DIL->getBaseDiscriminator();
+ StringRef Name = DIL->getScope()->getSubprogram()->getLinkageName();
+ if (Name.empty())
+ Name = DIL->getScope()->getSubprogram()->getName();
+ CallSiteLoc << Name.str() << ":" << llvm::utostr(Offset) << ":"
+ << llvm::utostr(DIL->getColumn());
+ if (Discriminator)
+ CallSiteLoc << "." << llvm::utostr(Discriminator);
+ First = false;
+ }
+
+ return CallSiteLoc.str();
+}
+
void llvm::addLocationToRemarks(OptimizationRemark &Remark, DebugLoc DLoc) {
- if (!DLoc.get()) {
+ if (!DLoc.get()) {
return;
- }
+ }
bool First = true;
Remark << " at callsite ";
@@ -423,14 +423,14 @@ void llvm::addLocationToRemarks(OptimizationRemark &Remark, DebugLoc DLoc) {
StringRef Name = DIL->getScope()->getSubprogram()->getLinkageName();
if (Name.empty())
Name = DIL->getScope()->getSubprogram()->getName();
- Remark << Name << ":" << ore::NV("Line", Offset) << ":"
- << ore::NV("Column", DIL->getColumn());
+ Remark << Name << ":" << ore::NV("Line", Offset) << ":"
+ << ore::NV("Column", DIL->getColumn());
if (Discriminator)
Remark << "." << ore::NV("Disc", Discriminator);
First = false;
}
-
- Remark << ";";
+
+ Remark << ";";
}
void llvm::emitInlinedInto(OptimizationRemarkEmitter &ORE, DebugLoc DLoc,
@@ -451,64 +451,64 @@ void llvm::emitInlinedInto(OptimizationRemarkEmitter &ORE, DebugLoc DLoc,
return Remark;
});
}
-
-InlineAdvisor::InlineAdvisor(Module &M, FunctionAnalysisManager &FAM)
- : M(M), FAM(FAM) {
- if (InlinerFunctionImportStats != InlinerFunctionImportStatsOpts::No) {
- ImportedFunctionsStats =
- std::make_unique<ImportedFunctionsInliningStatistics>();
- ImportedFunctionsStats->setModuleInfo(M);
- }
-}
-
-InlineAdvisor::~InlineAdvisor() {
- if (ImportedFunctionsStats) {
- assert(InlinerFunctionImportStats != InlinerFunctionImportStatsOpts::No);
- ImportedFunctionsStats->dump(InlinerFunctionImportStats ==
- InlinerFunctionImportStatsOpts::Verbose);
- }
-
- freeDeletedFunctions();
-}
-
-std::unique_ptr<InlineAdvice> InlineAdvisor::getMandatoryAdvice(CallBase &CB,
- bool Advice) {
- return std::make_unique<InlineAdvice>(this, CB, getCallerORE(CB), Advice);
-}
-
-InlineAdvisor::MandatoryInliningKind
-InlineAdvisor::getMandatoryKind(CallBase &CB, FunctionAnalysisManager &FAM,
- OptimizationRemarkEmitter &ORE) {
- auto &Callee = *CB.getCalledFunction();
-
- auto GetTLI = [&](Function &F) -> const TargetLibraryInfo & {
- return FAM.getResult<TargetLibraryAnalysis>(F);
- };
-
- auto &TIR = FAM.getResult<TargetIRAnalysis>(Callee);
-
- auto TrivialDecision =
- llvm::getAttributeBasedInliningDecision(CB, &Callee, TIR, GetTLI);
-
- if (TrivialDecision.hasValue()) {
- if (TrivialDecision->isSuccess())
- return MandatoryInliningKind::Always;
- else
- return MandatoryInliningKind::Never;
- }
- return MandatoryInliningKind::NotMandatory;
-}
-
-std::unique_ptr<InlineAdvice> InlineAdvisor::getAdvice(CallBase &CB,
- bool MandatoryOnly) {
- if (!MandatoryOnly)
- return getAdviceImpl(CB);
- bool Advice = CB.getCaller() != CB.getCalledFunction() &&
- MandatoryInliningKind::Always ==
- getMandatoryKind(CB, FAM, getCallerORE(CB));
- return getMandatoryAdvice(CB, Advice);
-}
-
-OptimizationRemarkEmitter &InlineAdvisor::getCallerORE(CallBase &CB) {
- return FAM.getResult<OptimizationRemarkEmitterAnalysis>(*CB.getCaller());
-}
+
+InlineAdvisor::InlineAdvisor(Module &M, FunctionAnalysisManager &FAM)
+ : M(M), FAM(FAM) {
+ if (InlinerFunctionImportStats != InlinerFunctionImportStatsOpts::No) {
+ ImportedFunctionsStats =
+ std::make_unique<ImportedFunctionsInliningStatistics>();
+ ImportedFunctionsStats->setModuleInfo(M);
+ }
+}
+
+InlineAdvisor::~InlineAdvisor() {
+ if (ImportedFunctionsStats) {
+ assert(InlinerFunctionImportStats != InlinerFunctionImportStatsOpts::No);
+ ImportedFunctionsStats->dump(InlinerFunctionImportStats ==
+ InlinerFunctionImportStatsOpts::Verbose);
+ }
+
+ freeDeletedFunctions();
+}
+
+std::unique_ptr<InlineAdvice> InlineAdvisor::getMandatoryAdvice(CallBase &CB,
+ bool Advice) {
+ return std::make_unique<InlineAdvice>(this, CB, getCallerORE(CB), Advice);
+}
+
+InlineAdvisor::MandatoryInliningKind
+InlineAdvisor::getMandatoryKind(CallBase &CB, FunctionAnalysisManager &FAM,
+ OptimizationRemarkEmitter &ORE) {
+ auto &Callee = *CB.getCalledFunction();
+
+ auto GetTLI = [&](Function &F) -> const TargetLibraryInfo & {
+ return FAM.getResult<TargetLibraryAnalysis>(F);
+ };
+
+ auto &TIR = FAM.getResult<TargetIRAnalysis>(Callee);
+
+ auto TrivialDecision =
+ llvm::getAttributeBasedInliningDecision(CB, &Callee, TIR, GetTLI);
+
+ if (TrivialDecision.hasValue()) {
+ if (TrivialDecision->isSuccess())
+ return MandatoryInliningKind::Always;
+ else
+ return MandatoryInliningKind::Never;
+ }
+ return MandatoryInliningKind::NotMandatory;
+}
+
+std::unique_ptr<InlineAdvice> InlineAdvisor::getAdvice(CallBase &CB,
+ bool MandatoryOnly) {
+ if (!MandatoryOnly)
+ return getAdviceImpl(CB);
+ bool Advice = CB.getCaller() != CB.getCalledFunction() &&
+ MandatoryInliningKind::Always ==
+ getMandatoryKind(CB, FAM, getCallerORE(CB));
+ return getMandatoryAdvice(CB, Advice);
+}
+
+OptimizationRemarkEmitter &InlineAdvisor::getCallerORE(CallBase &CB) {
+ return FAM.getResult<OptimizationRemarkEmitterAnalysis>(*CB.getCaller());
+}
diff --git a/contrib/libs/llvm12/lib/Analysis/InlineCost.cpp b/contrib/libs/llvm12/lib/Analysis/InlineCost.cpp
index d937665464..a35f5e11f0 100644
--- a/contrib/libs/llvm12/lib/Analysis/InlineCost.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/InlineCost.cpp
@@ -71,20 +71,20 @@ static cl::opt<int>
cl::init(45), cl::ZeroOrMore,
cl::desc("Threshold for inlining cold callsites"));
-static cl::opt<bool> InlineEnableCostBenefitAnalysis(
- "inline-enable-cost-benefit-analysis", cl::Hidden, cl::init(false),
- cl::desc("Enable the cost-benefit analysis for the inliner"));
-
-static cl::opt<int> InlineSavingsMultiplier(
- "inline-savings-multiplier", cl::Hidden, cl::init(8), cl::ZeroOrMore,
- cl::desc("Multiplier to multiply cycle savings by during inlining"));
-
-static cl::opt<int>
- InlineSizeAllowance("inline-size-allowance", cl::Hidden, cl::init(100),
- cl::ZeroOrMore,
- cl::desc("The maximum size of a callee that get's "
- "inlined without sufficient cycle savings"));
-
+static cl::opt<bool> InlineEnableCostBenefitAnalysis(
+ "inline-enable-cost-benefit-analysis", cl::Hidden, cl::init(false),
+ cl::desc("Enable the cost-benefit analysis for the inliner"));
+
+static cl::opt<int> InlineSavingsMultiplier(
+ "inline-savings-multiplier", cl::Hidden, cl::init(8), cl::ZeroOrMore,
+ cl::desc("Multiplier to multiply cycle savings by during inlining"));
+
+static cl::opt<int>
+ InlineSizeAllowance("inline-size-allowance", cl::Hidden, cl::init(100),
+ cl::ZeroOrMore,
+ cl::desc("The maximum size of a callee that get's "
+ "inlined without sufficient cycle savings"));
+
// We introduce this threshold to help performance of instrumentation based
// PGO before we actually hook up inliner with analysis passes such as BPI and
// BFI.
@@ -197,9 +197,9 @@ protected:
CallBase &CandidateCall;
/// Extension points for handling callsite features.
- // Called before a basic block was analyzed.
- virtual void onBlockStart(const BasicBlock *BB) {}
-
+ // Called before a basic block was analyzed.
+ virtual void onBlockStart(const BasicBlock *BB) {}
+
/// Called after a basic block was analyzed.
virtual void onBlockAnalyzed(const BasicBlock *BB) {}
@@ -471,24 +471,24 @@ class InlineCostCallAnalyzer final : public CallAnalyzer {
/// Ignore the threshold when finalizing analysis.
const bool IgnoreThreshold;
- // True if the cost-benefit-analysis-based inliner is enabled.
- const bool CostBenefitAnalysisEnabled;
-
+ // True if the cost-benefit-analysis-based inliner is enabled.
+ const bool CostBenefitAnalysisEnabled;
+
/// Inlining cost measured in abstract units, accounts for all the
/// instructions expected to be executed for a given function invocation.
/// Instructions that are statically proven to be dead based on call-site
/// arguments are not counted here.
int Cost = 0;
- // The cumulative cost at the beginning of the basic block being analyzed. At
- // the end of analyzing each basic block, "Cost - CostAtBBStart" represents
- // the size of that basic block.
- int CostAtBBStart = 0;
-
- // The static size of live but cold basic blocks. This is "static" in the
- // sense that it's not weighted by profile counts at all.
- int ColdSize = 0;
-
+ // The cumulative cost at the beginning of the basic block being analyzed. At
+ // the end of analyzing each basic block, "Cost - CostAtBBStart" represents
+ // the size of that basic block.
+ int CostAtBBStart = 0;
+
+ // The static size of live but cold basic blocks. This is "static" in the
+ // sense that it's not weighted by profile counts at all.
+ int ColdSize = 0;
+
bool SingleBB = true;
unsigned SROACostSavings = 0;
@@ -626,21 +626,21 @@ class InlineCostCallAnalyzer final : public CallAnalyzer {
SROACostSavings += InlineConstants::InstrCost;
}
- void onBlockStart(const BasicBlock *BB) override { CostAtBBStart = Cost; }
-
+ void onBlockStart(const BasicBlock *BB) override { CostAtBBStart = Cost; }
+
void onBlockAnalyzed(const BasicBlock *BB) override {
- if (CostBenefitAnalysisEnabled) {
- // Keep track of the static size of live but cold basic blocks. For now,
- // we define a cold basic block to be one that's never executed.
- assert(GetBFI && "GetBFI must be available");
- BlockFrequencyInfo *BFI = &(GetBFI(F));
- assert(BFI && "BFI must be available");
- auto ProfileCount = BFI->getBlockProfileCount(BB);
- assert(ProfileCount.hasValue());
- if (ProfileCount.getValue() == 0)
- ColdSize += Cost - CostAtBBStart;
- }
-
+ if (CostBenefitAnalysisEnabled) {
+ // Keep track of the static size of live but cold basic blocks. For now,
+ // we define a cold basic block to be one that's never executed.
+ assert(GetBFI && "GetBFI must be available");
+ BlockFrequencyInfo *BFI = &(GetBFI(F));
+ assert(BFI && "BFI must be available");
+ auto ProfileCount = BFI->getBlockProfileCount(BB);
+ assert(ProfileCount.hasValue());
+ if (ProfileCount.getValue() == 0)
+ ColdSize += Cost - CostAtBBStart;
+ }
+
auto *TI = BB->getTerminator();
// If we had any successors at this point, than post-inlining is likely to
// have them as well. Note that we assume any basic blocks which existed
@@ -671,131 +671,131 @@ class InlineCostCallAnalyzer final : public CallAnalyzer {
InstructionCostDetailMap[I].ThresholdAfter = Threshold;
}
- bool isCostBenefitAnalysisEnabled() {
- if (!InlineEnableCostBenefitAnalysis)
- return false;
-
- if (!PSI || !PSI->hasProfileSummary())
- return false;
-
- if (!GetBFI)
- return false;
-
- auto *Caller = CandidateCall.getParent()->getParent();
- if (!Caller->getEntryCount())
- return false;
-
- BlockFrequencyInfo *CallerBFI = &(GetBFI(*Caller));
- if (!CallerBFI)
- return false;
-
- // For now, limit to hot call site.
- if (!PSI->isHotCallSite(CandidateCall, CallerBFI))
- return false;
-
- if (!F.getEntryCount())
- return false;
-
- BlockFrequencyInfo *CalleeBFI = &(GetBFI(F));
- if (!CalleeBFI)
- return false;
-
- return true;
- }
-
- // Determine whether we should inline the given call site, taking into account
- // both the size cost and the cycle savings. Return None if we don't have
- // suficient profiling information to determine.
- Optional<bool> costBenefitAnalysis() {
- if (!CostBenefitAnalysisEnabled)
- return None;
-
- // buildInlinerPipeline in the pass builder sets HotCallSiteThreshold to 0
- // for the prelink phase of the AutoFDO + ThinLTO build. Honor the logic by
- // falling back to the cost-based metric.
- // TODO: Improve this hacky condition.
- if (Threshold == 0)
- return None;
-
- assert(GetBFI);
- BlockFrequencyInfo *CalleeBFI = &(GetBFI(F));
- assert(CalleeBFI);
-
- // The cycle savings expressed as the sum of InlineConstants::InstrCost
- // multiplied by the estimated dynamic count of each instruction we can
- // avoid. Savings come from the call site cost, such as argument setup and
- // the call instruction, as well as the instructions that are folded.
- //
- // We use 128-bit APInt here to avoid potential overflow. This variable
- // should stay well below 10^^24 (or 2^^80) in practice. This "worst" case
- // assumes that we can avoid or fold a billion instructions, each with a
- // profile count of 10^^15 -- roughly the number of cycles for a 24-hour
- // period on a 4GHz machine.
- APInt CycleSavings(128, 0);
-
- for (auto &BB : F) {
- APInt CurrentSavings(128, 0);
- for (auto &I : BB) {
- if (BranchInst *BI = dyn_cast<BranchInst>(&I)) {
- // Count a conditional branch as savings if it becomes unconditional.
- if (BI->isConditional() &&
- dyn_cast_or_null<ConstantInt>(
- SimplifiedValues.lookup(BI->getCondition()))) {
- CurrentSavings += InlineConstants::InstrCost;
- }
- } else if (Value *V = dyn_cast<Value>(&I)) {
- // Count an instruction as savings if we can fold it.
- if (SimplifiedValues.count(V)) {
- CurrentSavings += InlineConstants::InstrCost;
- }
- }
- // TODO: Consider other forms of savings like switch statements,
- // indirect calls becoming direct, SROACostSavings, LoadEliminationCost,
- // etc.
- }
-
- auto ProfileCount = CalleeBFI->getBlockProfileCount(&BB);
- assert(ProfileCount.hasValue());
- CurrentSavings *= ProfileCount.getValue();
- CycleSavings += CurrentSavings;
- }
-
- // Compute the cycle savings per call.
- auto EntryProfileCount = F.getEntryCount();
- assert(EntryProfileCount.hasValue());
- auto EntryCount = EntryProfileCount.getCount();
- CycleSavings += EntryCount / 2;
- CycleSavings = CycleSavings.udiv(EntryCount);
-
- // Compute the total savings for the call site.
- auto *CallerBB = CandidateCall.getParent();
- BlockFrequencyInfo *CallerBFI = &(GetBFI(*(CallerBB->getParent())));
- CycleSavings += getCallsiteCost(this->CandidateCall, DL);
- CycleSavings *= CallerBFI->getBlockProfileCount(CallerBB).getValue();
-
- // Remove the cost of the cold basic blocks.
- int Size = Cost - ColdSize;
-
- // Allow tiny callees to be inlined regardless of whether they meet the
- // savings threshold.
- Size = Size > InlineSizeAllowance ? Size - InlineSizeAllowance : 1;
-
- // Return true if the savings justify the cost of inlining. Specifically,
- // we evaluate the following inequality:
- //
- // CycleSavings PSI->getOrCompHotCountThreshold()
- // -------------- >= -----------------------------------
- // Size InlineSavingsMultiplier
- //
- // Note that the left hand side is specific to a call site. The right hand
- // side is a constant for the entire executable.
- APInt LHS = CycleSavings;
- LHS *= InlineSavingsMultiplier;
- APInt RHS(128, PSI->getOrCompHotCountThreshold());
- RHS *= Size;
- return LHS.uge(RHS);
- }
-
+ bool isCostBenefitAnalysisEnabled() {
+ if (!InlineEnableCostBenefitAnalysis)
+ return false;
+
+ if (!PSI || !PSI->hasProfileSummary())
+ return false;
+
+ if (!GetBFI)
+ return false;
+
+ auto *Caller = CandidateCall.getParent()->getParent();
+ if (!Caller->getEntryCount())
+ return false;
+
+ BlockFrequencyInfo *CallerBFI = &(GetBFI(*Caller));
+ if (!CallerBFI)
+ return false;
+
+ // For now, limit to hot call site.
+ if (!PSI->isHotCallSite(CandidateCall, CallerBFI))
+ return false;
+
+ if (!F.getEntryCount())
+ return false;
+
+ BlockFrequencyInfo *CalleeBFI = &(GetBFI(F));
+ if (!CalleeBFI)
+ return false;
+
+ return true;
+ }
+
+ // Determine whether we should inline the given call site, taking into account
+ // both the size cost and the cycle savings. Return None if we don't have
+ // suficient profiling information to determine.
+ Optional<bool> costBenefitAnalysis() {
+ if (!CostBenefitAnalysisEnabled)
+ return None;
+
+ // buildInlinerPipeline in the pass builder sets HotCallSiteThreshold to 0
+ // for the prelink phase of the AutoFDO + ThinLTO build. Honor the logic by
+ // falling back to the cost-based metric.
+ // TODO: Improve this hacky condition.
+ if (Threshold == 0)
+ return None;
+
+ assert(GetBFI);
+ BlockFrequencyInfo *CalleeBFI = &(GetBFI(F));
+ assert(CalleeBFI);
+
+ // The cycle savings expressed as the sum of InlineConstants::InstrCost
+ // multiplied by the estimated dynamic count of each instruction we can
+ // avoid. Savings come from the call site cost, such as argument setup and
+ // the call instruction, as well as the instructions that are folded.
+ //
+ // We use 128-bit APInt here to avoid potential overflow. This variable
+ // should stay well below 10^^24 (or 2^^80) in practice. This "worst" case
+ // assumes that we can avoid or fold a billion instructions, each with a
+ // profile count of 10^^15 -- roughly the number of cycles for a 24-hour
+ // period on a 4GHz machine.
+ APInt CycleSavings(128, 0);
+
+ for (auto &BB : F) {
+ APInt CurrentSavings(128, 0);
+ for (auto &I : BB) {
+ if (BranchInst *BI = dyn_cast<BranchInst>(&I)) {
+ // Count a conditional branch as savings if it becomes unconditional.
+ if (BI->isConditional() &&
+ dyn_cast_or_null<ConstantInt>(
+ SimplifiedValues.lookup(BI->getCondition()))) {
+ CurrentSavings += InlineConstants::InstrCost;
+ }
+ } else if (Value *V = dyn_cast<Value>(&I)) {
+ // Count an instruction as savings if we can fold it.
+ if (SimplifiedValues.count(V)) {
+ CurrentSavings += InlineConstants::InstrCost;
+ }
+ }
+ // TODO: Consider other forms of savings like switch statements,
+ // indirect calls becoming direct, SROACostSavings, LoadEliminationCost,
+ // etc.
+ }
+
+ auto ProfileCount = CalleeBFI->getBlockProfileCount(&BB);
+ assert(ProfileCount.hasValue());
+ CurrentSavings *= ProfileCount.getValue();
+ CycleSavings += CurrentSavings;
+ }
+
+ // Compute the cycle savings per call.
+ auto EntryProfileCount = F.getEntryCount();
+ assert(EntryProfileCount.hasValue());
+ auto EntryCount = EntryProfileCount.getCount();
+ CycleSavings += EntryCount / 2;
+ CycleSavings = CycleSavings.udiv(EntryCount);
+
+ // Compute the total savings for the call site.
+ auto *CallerBB = CandidateCall.getParent();
+ BlockFrequencyInfo *CallerBFI = &(GetBFI(*(CallerBB->getParent())));
+ CycleSavings += getCallsiteCost(this->CandidateCall, DL);
+ CycleSavings *= CallerBFI->getBlockProfileCount(CallerBB).getValue();
+
+ // Remove the cost of the cold basic blocks.
+ int Size = Cost - ColdSize;
+
+ // Allow tiny callees to be inlined regardless of whether they meet the
+ // savings threshold.
+ Size = Size > InlineSizeAllowance ? Size - InlineSizeAllowance : 1;
+
+ // Return true if the savings justify the cost of inlining. Specifically,
+ // we evaluate the following inequality:
+ //
+ // CycleSavings PSI->getOrCompHotCountThreshold()
+ // -------------- >= -----------------------------------
+ // Size InlineSavingsMultiplier
+ //
+ // Note that the left hand side is specific to a call site. The right hand
+ // side is a constant for the entire executable.
+ APInt LHS = CycleSavings;
+ LHS *= InlineSavingsMultiplier;
+ APInt RHS(128, PSI->getOrCompHotCountThreshold());
+ RHS *= Size;
+ return LHS.uge(RHS);
+ }
+
InlineResult finalizeAnalysis() override {
// Loops generally act a lot like calls in that they act like barriers to
// movement, require a certain amount of setup, etc. So when optimising for
@@ -824,13 +824,13 @@ class InlineCostCallAnalyzer final : public CallAnalyzer {
else if (NumVectorInstructions <= NumInstructions / 2)
Threshold -= VectorBonus / 2;
- if (auto Result = costBenefitAnalysis()) {
- if (Result.getValue())
- return InlineResult::success();
- else
- return InlineResult::failure("Cost over threshold.");
- }
-
+ if (auto Result = costBenefitAnalysis()) {
+ if (Result.getValue())
+ return InlineResult::success();
+ else
+ return InlineResult::failure("Cost over threshold.");
+ }
+
if (IgnoreThreshold || Cost < std::max(1, Threshold))
return InlineResult::success();
return InlineResult::failure("Cost over threshold.");
@@ -901,11 +901,11 @@ public:
bool IgnoreThreshold = false)
: CallAnalyzer(Callee, Call, TTI, GetAssumptionCache, GetBFI, PSI, ORE),
ComputeFullInlineCost(OptComputeFullInlineCost ||
- Params.ComputeFullInlineCost || ORE ||
- isCostBenefitAnalysisEnabled()),
+ Params.ComputeFullInlineCost || ORE ||
+ isCostBenefitAnalysisEnabled()),
Params(Params), Threshold(Params.DefaultThreshold),
BoostIndirectCalls(BoostIndirect), IgnoreThreshold(IgnoreThreshold),
- CostBenefitAnalysisEnabled(isCostBenefitAnalysisEnabled()),
+ CostBenefitAnalysisEnabled(isCostBenefitAnalysisEnabled()),
Writer(this) {}
/// Annotation Writer for instruction details
@@ -1018,11 +1018,11 @@ bool CallAnalyzer::accumulateGEPOffset(GEPOperator &GEP, APInt &Offset) {
bool CallAnalyzer::isGEPFree(GetElementPtrInst &GEP) {
SmallVector<Value *, 4> Operands;
Operands.push_back(GEP.getOperand(0));
- for (const Use &Op : GEP.indices())
- if (Constant *SimpleOp = SimplifiedValues.lookup(Op))
+ for (const Use &Op : GEP.indices())
+ if (Constant *SimpleOp = SimplifiedValues.lookup(Op))
Operands.push_back(SimpleOp);
else
- Operands.push_back(Op);
+ Operands.push_back(Op);
return TargetTransformInfo::TCC_Free ==
TTI.getUserCost(&GEP, Operands,
TargetTransformInfo::TCK_SizeAndLatency);
@@ -1044,7 +1044,7 @@ bool CallAnalyzer::visitAlloca(AllocaInst &I) {
// is needed to track stack usage during inlining.
Type *Ty = I.getAllocatedType();
AllocatedSize = SaturatingMultiplyAdd(
- AllocSize->getLimitedValue(), DL.getTypeAllocSize(Ty).getKnownMinSize(),
+ AllocSize->getLimitedValue(), DL.getTypeAllocSize(Ty).getKnownMinSize(),
AllocatedSize);
if (AllocatedSize > InlineConstants::MaxSimplifiedDynamicAllocaToInline) {
HasDynamicAlloca = true;
@@ -1058,7 +1058,7 @@ bool CallAnalyzer::visitAlloca(AllocaInst &I) {
if (I.isStaticAlloca()) {
Type *Ty = I.getAllocatedType();
AllocatedSize =
- SaturatingAdd(DL.getTypeAllocSize(Ty).getKnownMinSize(), AllocatedSize);
+ SaturatingAdd(DL.getTypeAllocSize(Ty).getKnownMinSize(), AllocatedSize);
}
// We will happily inline static alloca instructions.
@@ -1194,8 +1194,8 @@ bool CallAnalyzer::visitGetElementPtr(GetElementPtrInst &I) {
// Lambda to check whether a GEP's indices are all constant.
auto IsGEPOffsetConstant = [&](GetElementPtrInst &GEP) {
- for (const Use &Op : GEP.indices())
- if (!isa<Constant>(Op) && !SimplifiedValues.lookup(Op))
+ for (const Use &Op : GEP.indices())
+ if (!isa<Constant>(Op) && !SimplifiedValues.lookup(Op))
return false;
return true;
};
@@ -1278,7 +1278,7 @@ bool CallAnalyzer::visitPtrToInt(PtrToIntInst &I) {
// integer is large enough to represent the pointer.
unsigned IntegerSize = I.getType()->getScalarSizeInBits();
unsigned AS = I.getOperand(0)->getType()->getPointerAddressSpace();
- if (IntegerSize == DL.getPointerSizeInBits(AS)) {
+ if (IntegerSize == DL.getPointerSizeInBits(AS)) {
std::pair<Value *, APInt> BaseAndOffset =
ConstantOffsetPtrs.lookup(I.getOperand(0));
if (BaseAndOffset.first)
@@ -1580,7 +1580,7 @@ void InlineCostCallAnalyzer::updateThreshold(CallBase &Call, Function &Callee) {
// Finally, take the target-specific inlining threshold multiplier into
// account.
Threshold *= TTI.getInliningThresholdMultiplier();
- Threshold += TTI.adjustInliningThreshold(&Call);
+ Threshold += TTI.adjustInliningThreshold(&Call);
SingleBBBonus = Threshold * SingleBBBonusPercent / 100;
VectorBonus = Threshold * VectorBonusPercent / 100;
@@ -2062,8 +2062,8 @@ bool CallAnalyzer::visitInstruction(Instruction &I) {
// We found something we don't understand or can't handle. Mark any SROA-able
// values in the operand list as no longer viable.
- for (const Use &Op : I.operands())
- disableSROA(Op);
+ for (const Use &Op : I.operands())
+ disableSROA(Op);
return false;
}
@@ -2078,7 +2078,7 @@ bool CallAnalyzer::visitInstruction(Instruction &I) {
InlineResult
CallAnalyzer::analyzeBlock(BasicBlock *BB,
SmallPtrSetImpl<const Value *> &EphValues) {
- for (Instruction &I : *BB) {
+ for (Instruction &I : *BB) {
// FIXME: Currently, the number of instructions in a function regardless of
// our ability to simplify them during inline to constants or dead code,
// are actually used by the vector bonus heuristic. As long as that's true,
@@ -2089,16 +2089,16 @@ CallAnalyzer::analyzeBlock(BasicBlock *BB,
if (isa<DbgInfoIntrinsic>(I))
continue;
- // Skip pseudo-probes.
- if (isa<PseudoProbeInst>(I))
- continue;
-
+ // Skip pseudo-probes.
+ if (isa<PseudoProbeInst>(I))
+ continue;
+
// Skip ephemeral values.
- if (EphValues.count(&I))
+ if (EphValues.count(&I))
continue;
++NumInstructions;
- if (isa<ExtractElementInst>(I) || I.getType()->isVectorTy())
+ if (isa<ExtractElementInst>(I) || I.getType()->isVectorTy())
++NumVectorInstructions;
// If the instruction simplified to a constant, there is no cost to this
@@ -2106,14 +2106,14 @@ CallAnalyzer::analyzeBlock(BasicBlock *BB,
// all of the per-instruction logic. The visit tree returns true if we
// consumed the instruction in any way, and false if the instruction's base
// cost should count against inlining.
- onInstructionAnalysisStart(&I);
+ onInstructionAnalysisStart(&I);
- if (Base::visit(&I))
+ if (Base::visit(&I))
++NumInstructionsSimplified;
else
onMissedSimplification();
- onInstructionAnalysisFinish(&I);
+ onInstructionAnalysisFinish(&I);
using namespace ore;
// If the visit this instruction detected an uninlinable pattern, abort.
InlineResult IR = InlineResult::success();
@@ -2274,23 +2274,23 @@ InlineResult CallAnalyzer::analyze() {
// Populate our simplified values by mapping from function arguments to call
// arguments with known important simplifications.
auto CAI = CandidateCall.arg_begin();
- for (Argument &FAI : F.args()) {
+ for (Argument &FAI : F.args()) {
assert(CAI != CandidateCall.arg_end());
if (Constant *C = dyn_cast<Constant>(CAI))
- SimplifiedValues[&FAI] = C;
+ SimplifiedValues[&FAI] = C;
Value *PtrArg = *CAI;
if (ConstantInt *C = stripAndComputeInBoundsConstantOffsets(PtrArg)) {
- ConstantOffsetPtrs[&FAI] = std::make_pair(PtrArg, C->getValue());
+ ConstantOffsetPtrs[&FAI] = std::make_pair(PtrArg, C->getValue());
// We can SROA any pointer arguments derived from alloca instructions.
if (auto *SROAArg = dyn_cast<AllocaInst>(PtrArg)) {
- SROAArgValues[&FAI] = SROAArg;
+ SROAArgValues[&FAI] = SROAArg;
onInitializeSROAArg(SROAArg);
EnabledSROAAllocas.insert(SROAArg);
}
}
- ++CAI;
+ ++CAI;
}
NumConstantArgs = SimplifiedValues.size();
NumConstantOffsetPtrArgs = ConstantOffsetPtrs.size();
@@ -2324,8 +2324,8 @@ InlineResult CallAnalyzer::analyze() {
if (BB->empty())
continue;
- onBlockStart(BB);
-
+ onBlockStart(BB);
+
// Disallow inlining a blockaddress with uses other than strictly callbr.
// A blockaddress only has defined behavior for an indirect branch in the
// same function, and we do not currently support inlining indirect
@@ -2512,13 +2512,13 @@ Optional<InlineResult> llvm::getAttributeBasedInliningDecision(
if (!Callee)
return InlineResult::failure("indirect call");
- // When callee coroutine function is inlined into caller coroutine function
- // before coro-split pass,
- // coro-early pass can not handle this quiet well.
- // So we won't inline the coroutine function if it have not been unsplited
- if (Callee->isPresplitCoroutine())
- return InlineResult::failure("unsplited coroutine call");
-
+ // When callee coroutine function is inlined into caller coroutine function
+ // before coro-split pass,
+ // coro-early pass can not handle this quiet well.
+ // So we won't inline the coroutine function if it have not been unsplited
+ if (Callee->isPresplitCoroutine())
+ return InlineResult::failure("unsplited coroutine call");
+
// Never inline calls with byval arguments that does not have the alloca
// address space. Since byval arguments can be replaced with a copy to an
// alloca, the inlined code would need to be adjusted to handle that the
@@ -2569,15 +2569,15 @@ Optional<InlineResult> llvm::getAttributeBasedInliningDecision(
if (Call.isNoInline())
return InlineResult::failure("noinline call site attribute");
- // Don't inline functions if one does not have any stack protector attribute
- // but the other does.
- if (Caller->hasStackProtectorFnAttr() && !Callee->hasStackProtectorFnAttr())
- return InlineResult::failure(
- "stack protected caller but callee requested no stack protector");
- if (Callee->hasStackProtectorFnAttr() && !Caller->hasStackProtectorFnAttr())
- return InlineResult::failure(
- "stack protected callee but caller requested no stack protector");
-
+ // Don't inline functions if one does not have any stack protector attribute
+ // but the other does.
+ if (Caller->hasStackProtectorFnAttr() && !Callee->hasStackProtectorFnAttr())
+ return InlineResult::failure(
+ "stack protected caller but callee requested no stack protector");
+ if (Callee->hasStackProtectorFnAttr() && !Caller->hasStackProtectorFnAttr())
+ return InlineResult::failure(
+ "stack protected callee but caller requested no stack protector");
+
return None;
}
@@ -2619,26 +2619,26 @@ InlineCost llvm::getInlineCost(
InlineResult llvm::isInlineViable(Function &F) {
bool ReturnsTwice = F.hasFnAttribute(Attribute::ReturnsTwice);
- for (BasicBlock &BB : F) {
+ for (BasicBlock &BB : F) {
// Disallow inlining of functions which contain indirect branches.
- if (isa<IndirectBrInst>(BB.getTerminator()))
+ if (isa<IndirectBrInst>(BB.getTerminator()))
return InlineResult::failure("contains indirect branches");
// Disallow inlining of blockaddresses which are used by non-callbr
// instructions.
- if (BB.hasAddressTaken())
- for (User *U : BlockAddress::get(&BB)->users())
+ if (BB.hasAddressTaken())
+ for (User *U : BlockAddress::get(&BB)->users())
if (!isa<CallBrInst>(*U))
return InlineResult::failure("blockaddress used outside of callbr");
- for (auto &II : BB) {
+ for (auto &II : BB) {
CallBase *Call = dyn_cast<CallBase>(&II);
if (!Call)
continue;
// Disallow recursive calls.
- Function *Callee = Call->getCalledFunction();
- if (&F == Callee)
+ Function *Callee = Call->getCalledFunction();
+ if (&F == Callee)
return InlineResult::failure("recursive call");
// Disallow calls which expose returns-twice to a function not previously
@@ -2647,8 +2647,8 @@ InlineResult llvm::isInlineViable(Function &F) {
cast<CallInst>(Call)->canReturnTwice())
return InlineResult::failure("exposes returns-twice attribute");
- if (Callee)
- switch (Callee->getIntrinsicID()) {
+ if (Callee)
+ switch (Callee->getIntrinsicID()) {
default:
break;
case llvm::Intrinsic::icall_branch_funnel:
@@ -2775,7 +2775,7 @@ InlineCostAnnotationPrinterPass::run(Function &F,
// We can add a flag which determines InlineParams for this run. Right now,
// the default InlineParams are used.
const InlineParams Params = llvm::getInlineParams();
- for (BasicBlock &BB : F) {
+ for (BasicBlock &BB : F) {
for (Instruction &I : BB) {
if (CallInst *CI = dyn_cast<CallInst>(&I)) {
Function *CalledFunction = CI->getCalledFunction();
diff --git a/contrib/libs/llvm12/lib/Analysis/InlineSizeEstimatorAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/InlineSizeEstimatorAnalysis.cpp
index 185252749e..3c90e82fb9 100644
--- a/contrib/libs/llvm12/lib/Analysis/InlineSizeEstimatorAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/InlineSizeEstimatorAnalysis.cpp
@@ -88,32 +88,32 @@ public:
// consecutive instructions (in the IR layout available at inline time) as
// features improves the model performance. We want to move away from manual
// feature selection.
-// The array is given in opcode pairs rather than labels because 1) labels
-// weren't readily available, and 2) the successions were hand - extracted.
-//
-// This array must be sorted.
-static const std::array<std::pair<size_t, size_t>, 137>
- ImportantInstructionSuccessions{
- {{1, 1}, {1, 4}, {1, 5}, {1, 7}, {1, 8}, {1, 9}, {1, 11},
- {1, 12}, {1, 13}, {1, 14}, {1, 18}, {1, 20}, {1, 22}, {1, 24},
- {1, 25}, {1, 26}, {1, 27}, {1, 28}, {1, 29}, {1, 30}, {1, 31},
- {1, 32}, {1, 33}, {1, 34}, {1, 39}, {1, 40}, {1, 42}, {1, 45},
- {2, 1}, {2, 2}, {2, 13}, {2, 28}, {2, 29}, {2, 32}, {2, 33},
- {2, 34}, {2, 38}, {2, 48}, {2, 49}, {2, 53}, {2, 55}, {2, 56},
- {13, 2}, {13, 13}, {13, 26}, {13, 33}, {13, 34}, {13, 56}, {15, 27},
- {28, 2}, {28, 48}, {28, 53}, {29, 2}, {29, 33}, {29, 56}, {31, 31},
- {31, 33}, {31, 34}, {31, 49}, {32, 1}, {32, 2}, {32, 13}, {32, 15},
- {32, 28}, {32, 29}, {32, 32}, {32, 33}, {32, 34}, {32, 39}, {32, 40},
- {32, 48}, {32, 49}, {32, 53}, {32, 56}, {33, 1}, {33, 2}, {33, 32},
- {33, 33}, {33, 34}, {33, 49}, {33, 53}, {33, 56}, {34, 1}, {34, 2},
- {34, 32}, {34, 33}, {34, 34}, {34, 49}, {34, 53}, {34, 56}, {38, 34},
- {39, 57}, {40, 34}, {47, 15}, {47, 49}, {48, 2}, {48, 34}, {48, 56},
- {49, 1}, {49, 2}, {49, 28}, {49, 32}, {49, 33}, {49, 34}, {49, 39},
- {49, 49}, {49, 56}, {53, 1}, {53, 2}, {53, 28}, {53, 34}, {53, 53},
- {53, 57}, {55, 1}, {55, 28}, {55, 34}, {55, 53}, {55, 55}, {55, 56},
- {56, 1}, {56, 2}, {56, 7}, {56, 13}, {56, 32}, {56, 33}, {56, 34},
- {56, 49}, {56, 53}, {56, 56}, {56, 64}, {57, 34}, {57, 56}, {57, 57},
- {64, 1}, {64, 64}, {65, 1}, {65, 65}}};
+// The array is given in opcode pairs rather than labels because 1) labels
+// weren't readily available, and 2) the successions were hand - extracted.
+//
+// This array must be sorted.
+static const std::array<std::pair<size_t, size_t>, 137>
+ ImportantInstructionSuccessions{
+ {{1, 1}, {1, 4}, {1, 5}, {1, 7}, {1, 8}, {1, 9}, {1, 11},
+ {1, 12}, {1, 13}, {1, 14}, {1, 18}, {1, 20}, {1, 22}, {1, 24},
+ {1, 25}, {1, 26}, {1, 27}, {1, 28}, {1, 29}, {1, 30}, {1, 31},
+ {1, 32}, {1, 33}, {1, 34}, {1, 39}, {1, 40}, {1, 42}, {1, 45},
+ {2, 1}, {2, 2}, {2, 13}, {2, 28}, {2, 29}, {2, 32}, {2, 33},
+ {2, 34}, {2, 38}, {2, 48}, {2, 49}, {2, 53}, {2, 55}, {2, 56},
+ {13, 2}, {13, 13}, {13, 26}, {13, 33}, {13, 34}, {13, 56}, {15, 27},
+ {28, 2}, {28, 48}, {28, 53}, {29, 2}, {29, 33}, {29, 56}, {31, 31},
+ {31, 33}, {31, 34}, {31, 49}, {32, 1}, {32, 2}, {32, 13}, {32, 15},
+ {32, 28}, {32, 29}, {32, 32}, {32, 33}, {32, 34}, {32, 39}, {32, 40},
+ {32, 48}, {32, 49}, {32, 53}, {32, 56}, {33, 1}, {33, 2}, {33, 32},
+ {33, 33}, {33, 34}, {33, 49}, {33, 53}, {33, 56}, {34, 1}, {34, 2},
+ {34, 32}, {34, 33}, {34, 34}, {34, 49}, {34, 53}, {34, 56}, {38, 34},
+ {39, 57}, {40, 34}, {47, 15}, {47, 49}, {48, 2}, {48, 34}, {48, 56},
+ {49, 1}, {49, 2}, {49, 28}, {49, 32}, {49, 33}, {49, 34}, {49, 39},
+ {49, 49}, {49, 56}, {53, 1}, {53, 2}, {53, 28}, {53, 34}, {53, 53},
+ {53, 57}, {55, 1}, {55, 28}, {55, 34}, {55, 53}, {55, 55}, {55, 56},
+ {56, 1}, {56, 2}, {56, 7}, {56, 13}, {56, 32}, {56, 33}, {56, 34},
+ {56, 49}, {56, 53}, {56, 56}, {56, 64}, {57, 34}, {57, 56}, {57, 57},
+ {64, 1}, {64, 64}, {65, 1}, {65, 65}}};
// We have: 9 calculated features (the features here); 1 feature for each
// instruction opcode; and 1 feature for each manually-identified sequence.
@@ -123,15 +123,15 @@ static const std::array<std::pair<size_t, size_t>, 137>
// Note that instruction opcodes start from 1. For convenience, we also have an
// always 0 feature for the '0' opcode, hence the extra 1.
const size_t IRToNativeSizeLearning::FunctionFeatures::FeatureCount =
- ImportantInstructionSuccessions.size() + getMaxInstructionID() + 1 +
- IRToNativeSizeLearning::NumNamedFeatures;
+ ImportantInstructionSuccessions.size() + getMaxInstructionID() + 1 +
+ IRToNativeSizeLearning::NumNamedFeatures;
size_t getSize(Function &F, TargetTransformInfo &TTI) {
size_t Ret = 0;
- for (const auto &BB : F)
- for (const auto &I : BB)
- Ret += *(TTI.getInstructionCost(
- &I, TargetTransformInfo::TargetCostKind::TCK_CodeSize).getValue());
+ for (const auto &BB : F)
+ for (const auto &I : BB)
+ Ret += *(TTI.getInstructionCost(
+ &I, TargetTransformInfo::TargetCostKind::TCK_CodeSize).getValue());
return Ret;
}
@@ -143,8 +143,8 @@ size_t getSize(Function &F, FunctionAnalysisManager &FAM) {
unsigned getMaxDominatorTreeDepth(const Function &F,
const DominatorTree &Tree) {
unsigned Ret = 0;
- for (const auto &BB : F)
- if (const auto *TN = Tree.getNode(&BB))
+ for (const auto &BB : F)
+ if (const auto *TN = Tree.getNode(&BB))
Ret = std::max(Ret, TN->getLevel());
return Ret;
}
@@ -153,37 +153,37 @@ unsigned getMaxDominatorTreeDepth(const Function &F,
IRToNativeSizeLearning::FunctionFeatures
IRToNativeSizeLearning::getFunctionFeatures(Function &F,
FunctionAnalysisManager &FAM) {
- assert(llvm::is_sorted(ImportantInstructionSuccessions) &&
- "expected function features are sorted");
+ assert(llvm::is_sorted(ImportantInstructionSuccessions) &&
+ "expected function features are sorted");
auto &DomTree = FAM.getResult<DominatorTreeAnalysis>(F);
FunctionFeatures FF;
size_t InstrCount = getMaxInstructionID() + 1;
FF.InstructionHistogram.resize(InstrCount);
- FF.InstructionPairHistogram.resize(ImportantInstructionSuccessions.size());
+ FF.InstructionPairHistogram.resize(ImportantInstructionSuccessions.size());
- int StartID = 0;
- int LastID = StartID;
+ int StartID = 0;
+ int LastID = StartID;
auto getPairIndex = [](size_t a, size_t b) {
- auto I = llvm::find(ImportantInstructionSuccessions, std::make_pair(a, b));
- if (I == ImportantInstructionSuccessions.end())
+ auto I = llvm::find(ImportantInstructionSuccessions, std::make_pair(a, b));
+ if (I == ImportantInstructionSuccessions.end())
return -1;
- return static_cast<int>(
- std::distance(ImportantInstructionSuccessions.begin(), I));
+ return static_cast<int>(
+ std::distance(ImportantInstructionSuccessions.begin(), I));
};
// We don't want debug calls, because they'd just add noise.
- for (const auto &BB : F) {
- for (const auto &I : BB.instructionsWithoutDebug()) {
- auto ID = I.getOpcode();
+ for (const auto &BB : F) {
+ for (const auto &I : BB.instructionsWithoutDebug()) {
+ auto ID = I.getOpcode();
++FF.InstructionHistogram[ID];
int PairIndex = getPairIndex(LastID, ID);
if (PairIndex >= 0)
++FF.InstructionPairHistogram[PairIndex];
LastID = ID;
- if (isa<CallBase>(I))
+ if (isa<CallBase>(I))
++FF[NamedFeatureIndex::Calls];
}
}
@@ -221,14 +221,14 @@ InlineSizeEstimatorAnalysis::InlineSizeEstimatorAnalysis() {
if (!isEvaluatorRequested()) {
return;
}
- std::vector<TensorSpec> InputSpecs{TensorSpec::createSpec<int32_t>(
- "serving_default_input_1",
- {1, static_cast<int64_t>(
- IRToNativeSizeLearning::FunctionFeatures::FeatureCount)})};
- std::vector<TensorSpec> OutputSpecs{
- TensorSpec::createSpec<float>("StatefulPartitionedCall", {1})};
+ std::vector<TensorSpec> InputSpecs{TensorSpec::createSpec<int32_t>(
+ "serving_default_input_1",
+ {1, static_cast<int64_t>(
+ IRToNativeSizeLearning::FunctionFeatures::FeatureCount)})};
+ std::vector<TensorSpec> OutputSpecs{
+ TensorSpec::createSpec<float>("StatefulPartitionedCall", {1})};
Evaluator = std::make_unique<TFModelEvaluator>(
- TFIR2NativeModelPath.getValue().c_str(), InputSpecs, OutputSpecs);
+ TFIR2NativeModelPath.getValue().c_str(), InputSpecs, OutputSpecs);
if (!Evaluator || !Evaluator->isValid()) {
Evaluator.reset();
return;
@@ -272,12 +272,12 @@ InlineSizeEstimatorAnalysis::run(const Function &F,
return None;
}
bool InlineSizeEstimatorAnalysis::isEvaluatorRequested() { return false; }
-#endif
-
-PreservedAnalyses
-InlineSizeEstimatorAnalysisPrinterPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- OS << "[InlineSizeEstimatorAnalysis] size estimate for " << F.getName()
- << ": " << AM.getResult<InlineSizeEstimatorAnalysis>(F) << "\n";
- return PreservedAnalyses::all();
-}
+#endif
+
+PreservedAnalyses
+InlineSizeEstimatorAnalysisPrinterPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ OS << "[InlineSizeEstimatorAnalysis] size estimate for " << F.getName()
+ << ": " << AM.getResult<InlineSizeEstimatorAnalysis>(F) << "\n";
+ return PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Analysis/InstCount.cpp b/contrib/libs/llvm12/lib/Analysis/InstCount.cpp
index f08bc82c82..8366bee083 100644
--- a/contrib/libs/llvm12/lib/Analysis/InstCount.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/InstCount.cpp
@@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Analysis/InstCount.h"
+#include "llvm/Analysis/InstCount.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/IR/Function.h"
@@ -24,71 +24,71 @@ using namespace llvm;
#define DEBUG_TYPE "instcount"
-STATISTIC(TotalInsts, "Number of instructions (of all types)");
+STATISTIC(TotalInsts, "Number of instructions (of all types)");
STATISTIC(TotalBlocks, "Number of basic blocks");
-STATISTIC(TotalFuncs, "Number of non-external functions");
+STATISTIC(TotalFuncs, "Number of non-external functions");
-#define HANDLE_INST(N, OPCODE, CLASS) \
- STATISTIC(Num##OPCODE##Inst, "Number of " #OPCODE " insts");
+#define HANDLE_INST(N, OPCODE, CLASS) \
+ STATISTIC(Num##OPCODE##Inst, "Number of " #OPCODE " insts");
#include "llvm/IR/Instruction.def"
namespace {
-class InstCount : public InstVisitor<InstCount> {
- friend class InstVisitor<InstCount>;
+class InstCount : public InstVisitor<InstCount> {
+ friend class InstVisitor<InstCount>;
- void visitFunction(Function &F) { ++TotalFuncs; }
- void visitBasicBlock(BasicBlock &BB) { ++TotalBlocks; }
+ void visitFunction(Function &F) { ++TotalFuncs; }
+ void visitBasicBlock(BasicBlock &BB) { ++TotalBlocks; }
-#define HANDLE_INST(N, OPCODE, CLASS) \
- void visit##OPCODE(CLASS &) { \
- ++Num##OPCODE##Inst; \
- ++TotalInsts; \
- }
+#define HANDLE_INST(N, OPCODE, CLASS) \
+ void visit##OPCODE(CLASS &) { \
+ ++Num##OPCODE##Inst; \
+ ++TotalInsts; \
+ }
#include "llvm/IR/Instruction.def"
- void visitInstruction(Instruction &I) {
- errs() << "Instruction Count does not know about " << I;
- llvm_unreachable(nullptr);
- }
-};
-} // namespace
-
-PreservedAnalyses InstCountPass::run(Function &F,
- FunctionAnalysisManager &FAM) {
- LLVM_DEBUG(dbgs() << "INSTCOUNT: running on function " << F.getName()
- << "\n");
- InstCount().visit(F);
-
- return PreservedAnalyses::all();
-}
-
-namespace {
-class InstCountLegacyPass : public FunctionPass {
-public:
- static char ID; // Pass identification, replacement for typeid
- InstCountLegacyPass() : FunctionPass(ID) {
- initializeInstCountLegacyPassPass(*PassRegistry::getPassRegistry());
- }
-
- bool runOnFunction(Function &F) override {
- LLVM_DEBUG(dbgs() << "INSTCOUNT: running on function " << F.getName()
- << "\n");
- InstCount().visit(F);
- return false;
+ void visitInstruction(Instruction &I) {
+ errs() << "Instruction Count does not know about " << I;
+ llvm_unreachable(nullptr);
+ }
+};
+} // namespace
+
+PreservedAnalyses InstCountPass::run(Function &F,
+ FunctionAnalysisManager &FAM) {
+ LLVM_DEBUG(dbgs() << "INSTCOUNT: running on function " << F.getName()
+ << "\n");
+ InstCount().visit(F);
+
+ return PreservedAnalyses::all();
+}
+
+namespace {
+class InstCountLegacyPass : public FunctionPass {
+public:
+ static char ID; // Pass identification, replacement for typeid
+ InstCountLegacyPass() : FunctionPass(ID) {
+ initializeInstCountLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool runOnFunction(Function &F) override {
+ LLVM_DEBUG(dbgs() << "INSTCOUNT: running on function " << F.getName()
+ << "\n");
+ InstCount().visit(F);
+ return false;
};
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- }
-
- void print(raw_ostream &O, const Module *M) const override {}
-};
-} // namespace
-
-char InstCountLegacyPass::ID = 0;
-INITIALIZE_PASS(InstCountLegacyPass, "instcount",
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ }
+
+ void print(raw_ostream &O, const Module *M) const override {}
+};
+} // namespace
+
+char InstCountLegacyPass::ID = 0;
+INITIALIZE_PASS(InstCountLegacyPass, "instcount",
"Counts the various types of Instructions", false, true)
-FunctionPass *llvm::createInstCountPass() { return new InstCountLegacyPass(); }
+FunctionPass *llvm::createInstCountPass() { return new InstCountLegacyPass(); }
diff --git a/contrib/libs/llvm12/lib/Analysis/InstructionSimplify.cpp b/contrib/libs/llvm12/lib/Analysis/InstructionSimplify.cpp
index 730ff6b4e7..a12816885c 100644
--- a/contrib/libs/llvm12/lib/Analysis/InstructionSimplify.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/InstructionSimplify.cpp
@@ -228,56 +228,56 @@ static bool valueDominatesPHI(Value *V, PHINode *P, const DominatorTree *DT) {
return false;
}
-/// Try to simplify a binary operator of form "V op OtherOp" where V is
-/// "(B0 opex B1)" by distributing 'op' across 'opex' as
-/// "(B0 op OtherOp) opex (B1 op OtherOp)".
-static Value *expandBinOp(Instruction::BinaryOps Opcode, Value *V,
- Value *OtherOp, Instruction::BinaryOps OpcodeToExpand,
+/// Try to simplify a binary operator of form "V op OtherOp" where V is
+/// "(B0 opex B1)" by distributing 'op' across 'opex' as
+/// "(B0 op OtherOp) opex (B1 op OtherOp)".
+static Value *expandBinOp(Instruction::BinaryOps Opcode, Value *V,
+ Value *OtherOp, Instruction::BinaryOps OpcodeToExpand,
const SimplifyQuery &Q, unsigned MaxRecurse) {
- auto *B = dyn_cast<BinaryOperator>(V);
- if (!B || B->getOpcode() != OpcodeToExpand)
- return nullptr;
- Value *B0 = B->getOperand(0), *B1 = B->getOperand(1);
- Value *L = SimplifyBinOp(Opcode, B0, OtherOp, Q.getWithoutUndef(),
- MaxRecurse);
- if (!L)
- return nullptr;
- Value *R = SimplifyBinOp(Opcode, B1, OtherOp, Q.getWithoutUndef(),
- MaxRecurse);
- if (!R)
- return nullptr;
-
- // Does the expanded pair of binops simplify to the existing binop?
- if ((L == B0 && R == B1) ||
- (Instruction::isCommutative(OpcodeToExpand) && L == B1 && R == B0)) {
- ++NumExpand;
- return B;
- }
-
- // Otherwise, return "L op' R" if it simplifies.
- Value *S = SimplifyBinOp(OpcodeToExpand, L, R, Q, MaxRecurse);
- if (!S)
- return nullptr;
-
- ++NumExpand;
- return S;
-}
-
-/// Try to simplify binops of form "A op (B op' C)" or the commuted variant by
-/// distributing op over op'.
-static Value *expandCommutativeBinOp(Instruction::BinaryOps Opcode,
- Value *L, Value *R,
- Instruction::BinaryOps OpcodeToExpand,
- const SimplifyQuery &Q,
- unsigned MaxRecurse) {
+ auto *B = dyn_cast<BinaryOperator>(V);
+ if (!B || B->getOpcode() != OpcodeToExpand)
+ return nullptr;
+ Value *B0 = B->getOperand(0), *B1 = B->getOperand(1);
+ Value *L = SimplifyBinOp(Opcode, B0, OtherOp, Q.getWithoutUndef(),
+ MaxRecurse);
+ if (!L)
+ return nullptr;
+ Value *R = SimplifyBinOp(Opcode, B1, OtherOp, Q.getWithoutUndef(),
+ MaxRecurse);
+ if (!R)
+ return nullptr;
+
+ // Does the expanded pair of binops simplify to the existing binop?
+ if ((L == B0 && R == B1) ||
+ (Instruction::isCommutative(OpcodeToExpand) && L == B1 && R == B0)) {
+ ++NumExpand;
+ return B;
+ }
+
+ // Otherwise, return "L op' R" if it simplifies.
+ Value *S = SimplifyBinOp(OpcodeToExpand, L, R, Q, MaxRecurse);
+ if (!S)
+ return nullptr;
+
+ ++NumExpand;
+ return S;
+}
+
+/// Try to simplify binops of form "A op (B op' C)" or the commuted variant by
+/// distributing op over op'.
+static Value *expandCommutativeBinOp(Instruction::BinaryOps Opcode,
+ Value *L, Value *R,
+ Instruction::BinaryOps OpcodeToExpand,
+ const SimplifyQuery &Q,
+ unsigned MaxRecurse) {
// Recursion is always used, so bail out at once if we already hit the limit.
if (!MaxRecurse--)
return nullptr;
- if (Value *V = expandBinOp(Opcode, L, R, OpcodeToExpand, Q, MaxRecurse))
- return V;
- if (Value *V = expandBinOp(Opcode, R, L, OpcodeToExpand, Q, MaxRecurse))
- return V;
+ if (Value *V = expandBinOp(Opcode, L, R, OpcodeToExpand, Q, MaxRecurse))
+ return V;
+ if (Value *V = expandBinOp(Opcode, R, L, OpcodeToExpand, Q, MaxRecurse))
+ return V;
return nullptr;
}
@@ -415,9 +415,9 @@ static Value *ThreadBinOpOverSelect(Instruction::BinaryOps Opcode, Value *LHS,
return TV;
// If one branch simplified to undef, return the other one.
- if (TV && Q.isUndefValue(TV))
+ if (TV && Q.isUndefValue(TV))
return FV;
- if (FV && Q.isUndefValue(FV))
+ if (FV && Q.isUndefValue(FV))
return TV;
// If applying the operation did not change the true and false select values,
@@ -612,7 +612,7 @@ static Value *SimplifyAddInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
return C;
// X + undef -> undef
- if (Q.isUndefValue(Op1))
+ if (Q.isUndefValue(Op1))
return Op1;
// X + 0 -> X
@@ -732,7 +732,7 @@ static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
// X - undef -> undef
// undef - X -> undef
- if (Q.isUndefValue(Op0) || Q.isUndefValue(Op1))
+ if (Q.isUndefValue(Op0) || Q.isUndefValue(Op1))
return UndefValue::get(Op0->getType());
// X - 0 -> X
@@ -867,7 +867,7 @@ static Value *SimplifyMulInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
// X * undef -> 0
// X * 0 -> 0
- if (Q.isUndefValue(Op1) || match(Op1, m_Zero()))
+ if (Q.isUndefValue(Op1) || match(Op1, m_Zero()))
return Constant::getNullValue(Op0->getType());
// X * 1 -> X
@@ -893,8 +893,8 @@ static Value *SimplifyMulInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
return V;
// Mul distributes over Add. Try some generic simplifications based on this.
- if (Value *V = expandCommutativeBinOp(Instruction::Mul, Op0, Op1,
- Instruction::Add, Q, MaxRecurse))
+ if (Value *V = expandCommutativeBinOp(Instruction::Mul, Op0, Op1,
+ Instruction::Add, Q, MaxRecurse))
return V;
// If the operation is with the result of a select instruction, check whether
@@ -920,37 +920,37 @@ Value *llvm::SimplifyMulInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
/// Check for common or similar folds of integer division or integer remainder.
/// This applies to all 4 opcodes (sdiv/udiv/srem/urem).
-static Value *simplifyDivRem(Value *Op0, Value *Op1, bool IsDiv,
- const SimplifyQuery &Q) {
+static Value *simplifyDivRem(Value *Op0, Value *Op1, bool IsDiv,
+ const SimplifyQuery &Q) {
Type *Ty = Op0->getType();
- // X / undef -> poison
- // X % undef -> poison
- if (Q.isUndefValue(Op1))
- return PoisonValue::get(Ty);
+ // X / undef -> poison
+ // X % undef -> poison
+ if (Q.isUndefValue(Op1))
+ return PoisonValue::get(Ty);
- // X / 0 -> poison
- // X % 0 -> poison
+ // X / 0 -> poison
+ // X % 0 -> poison
// We don't need to preserve faults!
if (match(Op1, m_Zero()))
- return PoisonValue::get(Ty);
+ return PoisonValue::get(Ty);
- // If any element of a constant divisor fixed width vector is zero or undef
- // the behavior is undefined and we can fold the whole op to poison.
+ // If any element of a constant divisor fixed width vector is zero or undef
+ // the behavior is undefined and we can fold the whole op to poison.
auto *Op1C = dyn_cast<Constant>(Op1);
auto *VTy = dyn_cast<FixedVectorType>(Ty);
if (Op1C && VTy) {
unsigned NumElts = VTy->getNumElements();
for (unsigned i = 0; i != NumElts; ++i) {
Constant *Elt = Op1C->getAggregateElement(i);
- if (Elt && (Elt->isNullValue() || Q.isUndefValue(Elt)))
- return PoisonValue::get(Ty);
+ if (Elt && (Elt->isNullValue() || Q.isUndefValue(Elt)))
+ return PoisonValue::get(Ty);
}
}
// undef / X -> 0
// undef % X -> 0
- if (Q.isUndefValue(Op0))
+ if (Q.isUndefValue(Op0))
return Constant::getNullValue(Ty);
// 0 / X -> 0
@@ -1044,7 +1044,7 @@ static Value *simplifyDiv(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,
if (Constant *C = foldOrCommuteConstant(Opcode, Op0, Op1, Q))
return C;
- if (Value *V = simplifyDivRem(Op0, Op1, true, Q))
+ if (Value *V = simplifyDivRem(Op0, Op1, true, Q))
return V;
bool IsSigned = Opcode == Instruction::SDiv;
@@ -1102,7 +1102,7 @@ static Value *simplifyRem(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,
if (Constant *C = foldOrCommuteConstant(Opcode, Op0, Op1, Q))
return C;
- if (Value *V = simplifyDivRem(Op0, Op1, false, Q))
+ if (Value *V = simplifyDivRem(Op0, Op1, false, Q))
return V;
// (X % Y) % Y -> X % Y
@@ -1197,14 +1197,14 @@ Value *llvm::SimplifyURemInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
return ::SimplifyURemInst(Op0, Op1, Q, RecursionLimit);
}
-/// Returns true if a shift by \c Amount always yields poison.
-static bool isPoisonShift(Value *Amount, const SimplifyQuery &Q) {
+/// Returns true if a shift by \c Amount always yields poison.
+static bool isPoisonShift(Value *Amount, const SimplifyQuery &Q) {
Constant *C = dyn_cast<Constant>(Amount);
if (!C)
return false;
- // X shift by undef -> poison because it may shift by the bitwidth.
- if (Q.isUndefValue(C))
+ // X shift by undef -> poison because it may shift by the bitwidth.
+ if (Q.isUndefValue(C))
return true;
// Shifting by the bitwidth or more is undefined.
@@ -1215,10 +1215,10 @@ static bool isPoisonShift(Value *Amount, const SimplifyQuery &Q) {
// If all lanes of a vector shift are undefined the whole shift is.
if (isa<ConstantVector>(C) || isa<ConstantDataVector>(C)) {
- for (unsigned I = 0,
- E = cast<FixedVectorType>(C->getType())->getNumElements();
+ for (unsigned I = 0,
+ E = cast<FixedVectorType>(C->getType())->getNumElements();
I != E; ++I)
- if (!isPoisonShift(C->getAggregateElement(I), Q))
+ if (!isPoisonShift(C->getAggregateElement(I), Q))
return false;
return true;
}
@@ -1246,8 +1246,8 @@ static Value *SimplifyShift(Instruction::BinaryOps Opcode, Value *Op0,
return Op0;
// Fold undefined shifts.
- if (isPoisonShift(Op1, Q))
- return PoisonValue::get(Op0->getType());
+ if (isPoisonShift(Op1, Q))
+ return PoisonValue::get(Op0->getType());
// If the operation is with the result of a select instruction, check whether
// operating on either branch of the select always yields the same value.
@@ -1265,7 +1265,7 @@ static Value *SimplifyShift(Instruction::BinaryOps Opcode, Value *Op0,
// the number of bits in the type, the shift is undefined.
KnownBits Known = computeKnownBits(Op1, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
if (Known.One.getLimitedValue() >= Known.getBitWidth())
- return PoisonValue::get(Op0->getType());
+ return PoisonValue::get(Op0->getType());
// If all valid bits in the shift amount are known zero, the first operand is
// unchanged.
@@ -1290,7 +1290,7 @@ static Value *SimplifyRightShift(Instruction::BinaryOps Opcode, Value *Op0,
// undef >> X -> 0
// undef >> X -> undef (if it's exact)
- if (Q.isUndefValue(Op0))
+ if (Q.isUndefValue(Op0))
return isExact ? Op0 : Constant::getNullValue(Op0->getType());
// The low bit cannot be shifted out of an exact shift if it is set.
@@ -1312,7 +1312,7 @@ static Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
// undef << X -> 0
// undef << X -> undef if (if it's NSW/NUW)
- if (Q.isUndefValue(Op0))
+ if (Q.isUndefValue(Op0))
return isNSW || isNUW ? Op0 : Constant::getNullValue(Op0->getType());
// (X >> A) << A -> X
@@ -1698,24 +1698,24 @@ static Value *simplifyAndOrOfICmpsWithLimitConst(ICmpInst *Cmp0, ICmpInst *Cmp1,
if (!Cmp0->isEquality())
return nullptr;
- // The non-equality compare must include a common operand (X). Canonicalize
- // the common operand as operand 0 (the predicate is swapped if the common
- // operand was operand 1).
- ICmpInst::Predicate Pred0 = Cmp0->getPredicate();
- Value *X = Cmp0->getOperand(0);
- ICmpInst::Predicate Pred1;
- bool HasNotOp = match(Cmp1, m_c_ICmp(Pred1, m_Not(m_Specific(X)), m_Value()));
- if (!HasNotOp && !match(Cmp1, m_c_ICmp(Pred1, m_Specific(X), m_Value())))
- return nullptr;
- if (ICmpInst::isEquality(Pred1))
- return nullptr;
-
- // The equality compare must be against a constant. Flip bits if we matched
- // a bitwise not. Convert a null pointer constant to an integer zero value.
+ // The non-equality compare must include a common operand (X). Canonicalize
+ // the common operand as operand 0 (the predicate is swapped if the common
+ // operand was operand 1).
+ ICmpInst::Predicate Pred0 = Cmp0->getPredicate();
+ Value *X = Cmp0->getOperand(0);
+ ICmpInst::Predicate Pred1;
+ bool HasNotOp = match(Cmp1, m_c_ICmp(Pred1, m_Not(m_Specific(X)), m_Value()));
+ if (!HasNotOp && !match(Cmp1, m_c_ICmp(Pred1, m_Specific(X), m_Value())))
+ return nullptr;
+ if (ICmpInst::isEquality(Pred1))
+ return nullptr;
+
+ // The equality compare must be against a constant. Flip bits if we matched
+ // a bitwise not. Convert a null pointer constant to an integer zero value.
APInt MinMaxC;
const APInt *C;
if (match(Cmp0->getOperand(1), m_APInt(C)))
- MinMaxC = HasNotOp ? ~*C : *C;
+ MinMaxC = HasNotOp ? ~*C : *C;
else if (isa<ConstantPointerNull>(Cmp0->getOperand(1)))
MinMaxC = APInt::getNullValue(8);
else
@@ -1999,30 +1999,30 @@ static Value *omitCheckForZeroBeforeInvertedMulWithOverflow(Value *Op0,
return NotOp1;
}
-/// Given a bitwise logic op, check if the operands are add/sub with a common
-/// source value and inverted constant (identity: C - X -> ~(X + ~C)).
-static Value *simplifyLogicOfAddSub(Value *Op0, Value *Op1,
- Instruction::BinaryOps Opcode) {
- assert(Op0->getType() == Op1->getType() && "Mismatched binop types");
- assert(BinaryOperator::isBitwiseLogicOp(Opcode) && "Expected logic op");
- Value *X;
- Constant *C1, *C2;
- if ((match(Op0, m_Add(m_Value(X), m_Constant(C1))) &&
- match(Op1, m_Sub(m_Constant(C2), m_Specific(X)))) ||
- (match(Op1, m_Add(m_Value(X), m_Constant(C1))) &&
- match(Op0, m_Sub(m_Constant(C2), m_Specific(X))))) {
- if (ConstantExpr::getNot(C1) == C2) {
- // (X + C) & (~C - X) --> (X + C) & ~(X + C) --> 0
- // (X + C) | (~C - X) --> (X + C) | ~(X + C) --> -1
- // (X + C) ^ (~C - X) --> (X + C) ^ ~(X + C) --> -1
- Type *Ty = Op0->getType();
- return Opcode == Instruction::And ? ConstantInt::getNullValue(Ty)
- : ConstantInt::getAllOnesValue(Ty);
- }
- }
- return nullptr;
-}
-
+/// Given a bitwise logic op, check if the operands are add/sub with a common
+/// source value and inverted constant (identity: C - X -> ~(X + ~C)).
+static Value *simplifyLogicOfAddSub(Value *Op0, Value *Op1,
+ Instruction::BinaryOps Opcode) {
+ assert(Op0->getType() == Op1->getType() && "Mismatched binop types");
+ assert(BinaryOperator::isBitwiseLogicOp(Opcode) && "Expected logic op");
+ Value *X;
+ Constant *C1, *C2;
+ if ((match(Op0, m_Add(m_Value(X), m_Constant(C1))) &&
+ match(Op1, m_Sub(m_Constant(C2), m_Specific(X)))) ||
+ (match(Op1, m_Add(m_Value(X), m_Constant(C1))) &&
+ match(Op0, m_Sub(m_Constant(C2), m_Specific(X))))) {
+ if (ConstantExpr::getNot(C1) == C2) {
+ // (X + C) & (~C - X) --> (X + C) & ~(X + C) --> 0
+ // (X + C) | (~C - X) --> (X + C) | ~(X + C) --> -1
+ // (X + C) ^ (~C - X) --> (X + C) ^ ~(X + C) --> -1
+ Type *Ty = Op0->getType();
+ return Opcode == Instruction::And ? ConstantInt::getNullValue(Ty)
+ : ConstantInt::getAllOnesValue(Ty);
+ }
+ }
+ return nullptr;
+}
+
/// Given operands for an And, see if we can fold the result.
/// If not, this returns null.
static Value *SimplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
@@ -2031,7 +2031,7 @@ static Value *SimplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
return C;
// X & undef -> 0
- if (Q.isUndefValue(Op1))
+ if (Q.isUndefValue(Op1))
return Constant::getNullValue(Op0->getType());
// X & X = X
@@ -2059,9 +2059,9 @@ static Value *SimplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
if (match(Op1, m_c_Or(m_Specific(Op0), m_Value())))
return Op0;
- if (Value *V = simplifyLogicOfAddSub(Op0, Op1, Instruction::And))
- return V;
-
+ if (Value *V = simplifyLogicOfAddSub(Op0, Op1, Instruction::And))
+ return V;
+
// A mask that only clears known zeros of a shifted value is a no-op.
Value *X;
const APInt *Mask;
@@ -2118,30 +2118,30 @@ static Value *SimplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
return V;
// And distributes over Or. Try some generic simplifications based on this.
- if (Value *V = expandCommutativeBinOp(Instruction::And, Op0, Op1,
- Instruction::Or, Q, MaxRecurse))
+ if (Value *V = expandCommutativeBinOp(Instruction::And, Op0, Op1,
+ Instruction::Or, Q, MaxRecurse))
return V;
// And distributes over Xor. Try some generic simplifications based on this.
- if (Value *V = expandCommutativeBinOp(Instruction::And, Op0, Op1,
- Instruction::Xor, Q, MaxRecurse))
+ if (Value *V = expandCommutativeBinOp(Instruction::And, Op0, Op1,
+ Instruction::Xor, Q, MaxRecurse))
return V;
- if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1)) {
- if (Op0->getType()->isIntOrIntVectorTy(1)) {
- // A & (A && B) -> A && B
- if (match(Op1, m_Select(m_Specific(Op0), m_Value(), m_Zero())))
- return Op1;
- else if (match(Op0, m_Select(m_Specific(Op1), m_Value(), m_Zero())))
- return Op0;
- }
- // If the operation is with the result of a select instruction, check
- // whether operating on either branch of the select always yields the same
- // value.
+ if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1)) {
+ if (Op0->getType()->isIntOrIntVectorTy(1)) {
+ // A & (A && B) -> A && B
+ if (match(Op1, m_Select(m_Specific(Op0), m_Value(), m_Zero())))
+ return Op1;
+ else if (match(Op0, m_Select(m_Specific(Op1), m_Value(), m_Zero())))
+ return Op0;
+ }
+ // If the operation is with the result of a select instruction, check
+ // whether operating on either branch of the select always yields the same
+ // value.
if (Value *V = ThreadBinOpOverSelect(Instruction::And, Op0, Op1, Q,
MaxRecurse))
return V;
- }
+ }
// If the operation is with the result of a phi instruction, check whether
// operating on all incoming values of the phi always yields the same value.
@@ -2201,7 +2201,7 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
// X | undef -> -1
// X | -1 = -1
// Do not return Op1 because it may contain undef elements if it's a vector.
- if (Q.isUndefValue(Op1) || match(Op1, m_AllOnes()))
+ if (Q.isUndefValue(Op1) || match(Op1, m_AllOnes()))
return Constant::getAllOnesValue(Op0->getType());
// X | X = X
@@ -2230,10 +2230,10 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
if (match(Op1, m_Not(m_c_And(m_Specific(Op0), m_Value()))))
return Constant::getAllOnesValue(Op0->getType());
- if (Value *V = simplifyLogicOfAddSub(Op0, Op1, Instruction::Or))
- return V;
-
- Value *A, *B, *NotA;
+ if (Value *V = simplifyLogicOfAddSub(Op0, Op1, Instruction::Or))
+ return V;
+
+ Value *A, *B, *NotA;
// (A & ~B) | (A ^ B) -> (A ^ B)
// (~B & A) | (A ^ B) -> (A ^ B)
// (A & ~B) | (B ^ A) -> (B ^ A)
@@ -2262,7 +2262,7 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
match(Op1, m_c_Xor(m_Not(m_Specific(A)), m_Specific(B)))))
return Op1;
- // Commute the 'or' operands.
+ // Commute the 'or' operands.
// (~A ^ B) | (A & B) -> (~A ^ B)
// (~A ^ B) | (B & A) -> (~A ^ B)
// (B ^ ~A) | (A & B) -> (B ^ ~A)
@@ -2272,25 +2272,25 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
match(Op0, m_c_Xor(m_Not(m_Specific(A)), m_Specific(B)))))
return Op0;
- // (~A & B) | ~(A | B) --> ~A
- // (~A & B) | ~(B | A) --> ~A
- // (B & ~A) | ~(A | B) --> ~A
- // (B & ~A) | ~(B | A) --> ~A
- if (match(Op0, m_c_And(m_CombineAnd(m_Value(NotA), m_Not(m_Value(A))),
- m_Value(B))) &&
- match(Op1, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))))
- return NotA;
-
- // Commute the 'or' operands.
- // ~(A | B) | (~A & B) --> ~A
- // ~(B | A) | (~A & B) --> ~A
- // ~(A | B) | (B & ~A) --> ~A
- // ~(B | A) | (B & ~A) --> ~A
- if (match(Op1, m_c_And(m_CombineAnd(m_Value(NotA), m_Not(m_Value(A))),
- m_Value(B))) &&
- match(Op0, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))))
- return NotA;
-
+ // (~A & B) | ~(A | B) --> ~A
+ // (~A & B) | ~(B | A) --> ~A
+ // (B & ~A) | ~(A | B) --> ~A
+ // (B & ~A) | ~(B | A) --> ~A
+ if (match(Op0, m_c_And(m_CombineAnd(m_Value(NotA), m_Not(m_Value(A))),
+ m_Value(B))) &&
+ match(Op1, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))))
+ return NotA;
+
+ // Commute the 'or' operands.
+ // ~(A | B) | (~A & B) --> ~A
+ // ~(B | A) | (~A & B) --> ~A
+ // ~(A | B) | (B & ~A) --> ~A
+ // ~(B | A) | (B & ~A) --> ~A
+ if (match(Op1, m_c_And(m_CombineAnd(m_Value(NotA), m_Not(m_Value(A))),
+ m_Value(B))) &&
+ match(Op0, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))))
+ return NotA;
+
if (Value *V = simplifyAndOrOfCmps(Q, Op0, Op1, false))
return V;
@@ -2308,25 +2308,25 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
return V;
// Or distributes over And. Try some generic simplifications based on this.
- if (Value *V = expandCommutativeBinOp(Instruction::Or, Op0, Op1,
- Instruction::And, Q, MaxRecurse))
+ if (Value *V = expandCommutativeBinOp(Instruction::Or, Op0, Op1,
+ Instruction::And, Q, MaxRecurse))
return V;
- if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1)) {
- if (Op0->getType()->isIntOrIntVectorTy(1)) {
- // A | (A || B) -> A || B
- if (match(Op1, m_Select(m_Specific(Op0), m_One(), m_Value())))
- return Op1;
- else if (match(Op0, m_Select(m_Specific(Op1), m_One(), m_Value())))
- return Op0;
- }
- // If the operation is with the result of a select instruction, check
- // whether operating on either branch of the select always yields the same
- // value.
+ if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1)) {
+ if (Op0->getType()->isIntOrIntVectorTy(1)) {
+ // A | (A || B) -> A || B
+ if (match(Op1, m_Select(m_Specific(Op0), m_One(), m_Value())))
+ return Op1;
+ else if (match(Op0, m_Select(m_Specific(Op1), m_One(), m_Value())))
+ return Op0;
+ }
+ // If the operation is with the result of a select instruction, check
+ // whether operating on either branch of the select always yields the same
+ // value.
if (Value *V = ThreadBinOpOverSelect(Instruction::Or, Op0, Op1, Q,
MaxRecurse))
return V;
- }
+ }
// (A & C1)|(B & C2)
const APInt *C1, *C2;
@@ -2375,7 +2375,7 @@ static Value *SimplifyXorInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
return C;
// A ^ undef -> undef
- if (Q.isUndefValue(Op1))
+ if (Q.isUndefValue(Op1))
return Op1;
// A ^ 0 = A
@@ -2391,9 +2391,9 @@ static Value *SimplifyXorInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
match(Op1, m_Not(m_Specific(Op0))))
return Constant::getAllOnesValue(Op0->getType());
- if (Value *V = simplifyLogicOfAddSub(Op0, Op1, Instruction::Xor))
- return V;
-
+ if (Value *V = simplifyLogicOfAddSub(Op0, Op1, Instruction::Xor))
+ return V;
+
// Try some generic simplifications for associative operations.
if (Value *V = SimplifyAssociativeBinOp(Instruction::Xor, Op0, Op1, Q,
MaxRecurse))
@@ -2600,8 +2600,8 @@ computePointerICmp(const DataLayout &DL, const TargetLibraryInfo *TLI,
// memory within the lifetime of the current function (allocas, byval
// arguments, globals), then determine the comparison result here.
SmallVector<const Value *, 8> LHSUObjs, RHSUObjs;
- getUnderlyingObjects(LHS, LHSUObjs);
- getUnderlyingObjects(RHS, RHSUObjs);
+ getUnderlyingObjects(LHS, LHSUObjs);
+ getUnderlyingObjects(RHS, RHSUObjs);
// Is the set of underlying objects all noalias calls?
auto IsNAC = [](ArrayRef<const Value *> Objects) {
@@ -2808,7 +2808,7 @@ static Value *simplifyICmpWithConstant(CmpInst::Predicate Pred, Value *LHS,
}
const APInt *C;
- if (!match(RHS, m_APIntAllowUndef(C)))
+ if (!match(RHS, m_APIntAllowUndef(C)))
return nullptr;
// Rule out tautological comparisons (eg., ult 0 or uge 0).
@@ -2826,160 +2826,160 @@ static Value *simplifyICmpWithConstant(CmpInst::Predicate Pred, Value *LHS,
return ConstantInt::getFalse(ITy);
}
- // (mul nuw/nsw X, MulC) != C --> true (if C is not a multiple of MulC)
- // (mul nuw/nsw X, MulC) == C --> false (if C is not a multiple of MulC)
- const APInt *MulC;
- if (ICmpInst::isEquality(Pred) &&
- ((match(LHS, m_NUWMul(m_Value(), m_APIntAllowUndef(MulC))) &&
- *MulC != 0 && C->urem(*MulC) != 0) ||
- (match(LHS, m_NSWMul(m_Value(), m_APIntAllowUndef(MulC))) &&
- *MulC != 0 && C->srem(*MulC) != 0)))
- return ConstantInt::get(ITy, Pred == ICmpInst::ICMP_NE);
-
+ // (mul nuw/nsw X, MulC) != C --> true (if C is not a multiple of MulC)
+ // (mul nuw/nsw X, MulC) == C --> false (if C is not a multiple of MulC)
+ const APInt *MulC;
+ if (ICmpInst::isEquality(Pred) &&
+ ((match(LHS, m_NUWMul(m_Value(), m_APIntAllowUndef(MulC))) &&
+ *MulC != 0 && C->urem(*MulC) != 0) ||
+ (match(LHS, m_NSWMul(m_Value(), m_APIntAllowUndef(MulC))) &&
+ *MulC != 0 && C->srem(*MulC) != 0)))
+ return ConstantInt::get(ITy, Pred == ICmpInst::ICMP_NE);
+
+ return nullptr;
+}
+
+static Value *simplifyICmpWithBinOpOnLHS(
+ CmpInst::Predicate Pred, BinaryOperator *LBO, Value *RHS,
+ const SimplifyQuery &Q, unsigned MaxRecurse) {
+ Type *ITy = GetCompareTy(RHS); // The return type.
+
+ Value *Y = nullptr;
+ // icmp pred (or X, Y), X
+ if (match(LBO, m_c_Or(m_Value(Y), m_Specific(RHS)))) {
+ if (Pred == ICmpInst::ICMP_ULT)
+ return getFalse(ITy);
+ if (Pred == ICmpInst::ICMP_UGE)
+ return getTrue(ITy);
+
+ if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE) {
+ KnownBits RHSKnown = computeKnownBits(RHS, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
+ KnownBits YKnown = computeKnownBits(Y, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
+ if (RHSKnown.isNonNegative() && YKnown.isNegative())
+ return Pred == ICmpInst::ICMP_SLT ? getTrue(ITy) : getFalse(ITy);
+ if (RHSKnown.isNegative() || YKnown.isNonNegative())
+ return Pred == ICmpInst::ICMP_SLT ? getFalse(ITy) : getTrue(ITy);
+ }
+ }
+
+ // icmp pred (and X, Y), X
+ if (match(LBO, m_c_And(m_Value(), m_Specific(RHS)))) {
+ if (Pred == ICmpInst::ICMP_UGT)
+ return getFalse(ITy);
+ if (Pred == ICmpInst::ICMP_ULE)
+ return getTrue(ITy);
+ }
+
+ // icmp pred (urem X, Y), Y
+ if (match(LBO, m_URem(m_Value(), m_Specific(RHS)))) {
+ switch (Pred) {
+ default:
+ break;
+ case ICmpInst::ICMP_SGT:
+ case ICmpInst::ICMP_SGE: {
+ KnownBits Known = computeKnownBits(RHS, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
+ if (!Known.isNonNegative())
+ break;
+ LLVM_FALLTHROUGH;
+ }
+ case ICmpInst::ICMP_EQ:
+ case ICmpInst::ICMP_UGT:
+ case ICmpInst::ICMP_UGE:
+ return getFalse(ITy);
+ case ICmpInst::ICMP_SLT:
+ case ICmpInst::ICMP_SLE: {
+ KnownBits Known = computeKnownBits(RHS, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
+ if (!Known.isNonNegative())
+ break;
+ LLVM_FALLTHROUGH;
+ }
+ case ICmpInst::ICMP_NE:
+ case ICmpInst::ICMP_ULT:
+ case ICmpInst::ICMP_ULE:
+ return getTrue(ITy);
+ }
+ }
+
+ // icmp pred (urem X, Y), X
+ if (match(LBO, m_URem(m_Specific(RHS), m_Value()))) {
+ if (Pred == ICmpInst::ICMP_ULE)
+ return getTrue(ITy);
+ if (Pred == ICmpInst::ICMP_UGT)
+ return getFalse(ITy);
+ }
+
+ // x >> y <=u x
+ // x udiv y <=u x.
+ if (match(LBO, m_LShr(m_Specific(RHS), m_Value())) ||
+ match(LBO, m_UDiv(m_Specific(RHS), m_Value()))) {
+ // icmp pred (X op Y), X
+ if (Pred == ICmpInst::ICMP_UGT)
+ return getFalse(ITy);
+ if (Pred == ICmpInst::ICMP_ULE)
+ return getTrue(ITy);
+ }
+
+ // (x*C1)/C2 <= x for C1 <= C2.
+ // This holds even if the multiplication overflows: Assume that x != 0 and
+ // arithmetic is modulo M. For overflow to occur we must have C1 >= M/x and
+ // thus C2 >= M/x. It follows that (x*C1)/C2 <= (M-1)/C2 <= ((M-1)*x)/M < x.
+ //
+ // Additionally, either the multiplication and division might be represented
+ // as shifts:
+ // (x*C1)>>C2 <= x for C1 < 2**C2.
+ // (x<<C1)/C2 <= x for 2**C1 < C2.
+ const APInt *C1, *C2;
+ if ((match(LBO, m_UDiv(m_Mul(m_Specific(RHS), m_APInt(C1)), m_APInt(C2))) &&
+ C1->ule(*C2)) ||
+ (match(LBO, m_LShr(m_Mul(m_Specific(RHS), m_APInt(C1)), m_APInt(C2))) &&
+ C1->ule(APInt(C2->getBitWidth(), 1) << *C2)) ||
+ (match(LBO, m_UDiv(m_Shl(m_Specific(RHS), m_APInt(C1)), m_APInt(C2))) &&
+ (APInt(C1->getBitWidth(), 1) << *C1).ule(*C2))) {
+ if (Pred == ICmpInst::ICMP_UGT)
+ return getFalse(ITy);
+ if (Pred == ICmpInst::ICMP_ULE)
+ return getTrue(ITy);
+ }
+
return nullptr;
}
-static Value *simplifyICmpWithBinOpOnLHS(
- CmpInst::Predicate Pred, BinaryOperator *LBO, Value *RHS,
- const SimplifyQuery &Q, unsigned MaxRecurse) {
- Type *ITy = GetCompareTy(RHS); // The return type.
-
- Value *Y = nullptr;
- // icmp pred (or X, Y), X
- if (match(LBO, m_c_Or(m_Value(Y), m_Specific(RHS)))) {
- if (Pred == ICmpInst::ICMP_ULT)
- return getFalse(ITy);
- if (Pred == ICmpInst::ICMP_UGE)
- return getTrue(ITy);
-
- if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE) {
- KnownBits RHSKnown = computeKnownBits(RHS, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
- KnownBits YKnown = computeKnownBits(Y, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
- if (RHSKnown.isNonNegative() && YKnown.isNegative())
- return Pred == ICmpInst::ICMP_SLT ? getTrue(ITy) : getFalse(ITy);
- if (RHSKnown.isNegative() || YKnown.isNonNegative())
- return Pred == ICmpInst::ICMP_SLT ? getFalse(ITy) : getTrue(ITy);
- }
- }
-
- // icmp pred (and X, Y), X
- if (match(LBO, m_c_And(m_Value(), m_Specific(RHS)))) {
- if (Pred == ICmpInst::ICMP_UGT)
- return getFalse(ITy);
- if (Pred == ICmpInst::ICMP_ULE)
- return getTrue(ITy);
- }
-
- // icmp pred (urem X, Y), Y
- if (match(LBO, m_URem(m_Value(), m_Specific(RHS)))) {
- switch (Pred) {
- default:
- break;
- case ICmpInst::ICMP_SGT:
- case ICmpInst::ICMP_SGE: {
- KnownBits Known = computeKnownBits(RHS, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
- if (!Known.isNonNegative())
- break;
- LLVM_FALLTHROUGH;
- }
- case ICmpInst::ICMP_EQ:
- case ICmpInst::ICMP_UGT:
- case ICmpInst::ICMP_UGE:
- return getFalse(ITy);
- case ICmpInst::ICMP_SLT:
- case ICmpInst::ICMP_SLE: {
- KnownBits Known = computeKnownBits(RHS, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
- if (!Known.isNonNegative())
- break;
- LLVM_FALLTHROUGH;
- }
- case ICmpInst::ICMP_NE:
- case ICmpInst::ICMP_ULT:
- case ICmpInst::ICMP_ULE:
- return getTrue(ITy);
- }
- }
-
- // icmp pred (urem X, Y), X
- if (match(LBO, m_URem(m_Specific(RHS), m_Value()))) {
- if (Pred == ICmpInst::ICMP_ULE)
- return getTrue(ITy);
- if (Pred == ICmpInst::ICMP_UGT)
- return getFalse(ITy);
- }
-
- // x >> y <=u x
- // x udiv y <=u x.
- if (match(LBO, m_LShr(m_Specific(RHS), m_Value())) ||
- match(LBO, m_UDiv(m_Specific(RHS), m_Value()))) {
- // icmp pred (X op Y), X
- if (Pred == ICmpInst::ICMP_UGT)
- return getFalse(ITy);
- if (Pred == ICmpInst::ICMP_ULE)
- return getTrue(ITy);
- }
-
- // (x*C1)/C2 <= x for C1 <= C2.
- // This holds even if the multiplication overflows: Assume that x != 0 and
- // arithmetic is modulo M. For overflow to occur we must have C1 >= M/x and
- // thus C2 >= M/x. It follows that (x*C1)/C2 <= (M-1)/C2 <= ((M-1)*x)/M < x.
- //
- // Additionally, either the multiplication and division might be represented
- // as shifts:
- // (x*C1)>>C2 <= x for C1 < 2**C2.
- // (x<<C1)/C2 <= x for 2**C1 < C2.
- const APInt *C1, *C2;
- if ((match(LBO, m_UDiv(m_Mul(m_Specific(RHS), m_APInt(C1)), m_APInt(C2))) &&
- C1->ule(*C2)) ||
- (match(LBO, m_LShr(m_Mul(m_Specific(RHS), m_APInt(C1)), m_APInt(C2))) &&
- C1->ule(APInt(C2->getBitWidth(), 1) << *C2)) ||
- (match(LBO, m_UDiv(m_Shl(m_Specific(RHS), m_APInt(C1)), m_APInt(C2))) &&
- (APInt(C1->getBitWidth(), 1) << *C1).ule(*C2))) {
- if (Pred == ICmpInst::ICMP_UGT)
- return getFalse(ITy);
- if (Pred == ICmpInst::ICMP_ULE)
- return getTrue(ITy);
- }
-
- return nullptr;
-}
-
-
-// If only one of the icmp's operands has NSW flags, try to prove that:
-//
-// icmp slt (x + C1), (x +nsw C2)
-//
-// is equivalent to:
-//
-// icmp slt C1, C2
-//
-// which is true if x + C2 has the NSW flags set and:
-// *) C1 < C2 && C1 >= 0, or
-// *) C2 < C1 && C1 <= 0.
-//
-static bool trySimplifyICmpWithAdds(CmpInst::Predicate Pred, Value *LHS,
- Value *RHS) {
- // TODO: only support icmp slt for now.
- if (Pred != CmpInst::ICMP_SLT)
- return false;
-
- // Canonicalize nsw add as RHS.
- if (!match(RHS, m_NSWAdd(m_Value(), m_Value())))
- std::swap(LHS, RHS);
- if (!match(RHS, m_NSWAdd(m_Value(), m_Value())))
- return false;
-
- Value *X;
- const APInt *C1, *C2;
- if (!match(LHS, m_c_Add(m_Value(X), m_APInt(C1))) ||
- !match(RHS, m_c_Add(m_Specific(X), m_APInt(C2))))
- return false;
-
- return (C1->slt(*C2) && C1->isNonNegative()) ||
- (C2->slt(*C1) && C1->isNonPositive());
-}
-
-
+
+// If only one of the icmp's operands has NSW flags, try to prove that:
+//
+// icmp slt (x + C1), (x +nsw C2)
+//
+// is equivalent to:
+//
+// icmp slt C1, C2
+//
+// which is true if x + C2 has the NSW flags set and:
+// *) C1 < C2 && C1 >= 0, or
+// *) C2 < C1 && C1 <= 0.
+//
+static bool trySimplifyICmpWithAdds(CmpInst::Predicate Pred, Value *LHS,
+ Value *RHS) {
+ // TODO: only support icmp slt for now.
+ if (Pred != CmpInst::ICMP_SLT)
+ return false;
+
+ // Canonicalize nsw add as RHS.
+ if (!match(RHS, m_NSWAdd(m_Value(), m_Value())))
+ std::swap(LHS, RHS);
+ if (!match(RHS, m_NSWAdd(m_Value(), m_Value())))
+ return false;
+
+ Value *X;
+ const APInt *C1, *C2;
+ if (!match(LHS, m_c_Add(m_Value(X), m_APInt(C1))) ||
+ !match(RHS, m_c_Add(m_Specific(X), m_APInt(C2))))
+ return false;
+
+ return (C1->slt(*C2) && C1->isNonNegative()) ||
+ (C2->slt(*C1) && C1->isNonPositive());
+}
+
+
/// TODO: A large part of this logic is duplicated in InstCombine's
/// foldICmpBinOp(). We should be able to share that and avoid the code
/// duplication.
@@ -3029,9 +3029,9 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS,
return V;
// icmp (X+Y), (X+Z) -> icmp Y,Z for equalities or if there is no overflow.
- bool CanSimplify = (NoLHSWrapProblem && NoRHSWrapProblem) ||
- trySimplifyICmpWithAdds(Pred, LHS, RHS);
- if (A && C && (A == C || A == D || B == C || B == D) && CanSimplify) {
+ bool CanSimplify = (NoLHSWrapProblem && NoRHSWrapProblem) ||
+ trySimplifyICmpWithAdds(Pred, LHS, RHS);
+ if (A && C && (A == C || A == D || B == C || B == D) && CanSimplify) {
// Determine Y and Z in the form icmp (X+Y), (X+Z).
Value *Y, *Z;
if (A == C) {
@@ -3057,66 +3057,66 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS,
}
}
- if (LBO)
- if (Value *V = simplifyICmpWithBinOpOnLHS(Pred, LBO, RHS, Q, MaxRecurse))
- return V;
+ if (LBO)
+ if (Value *V = simplifyICmpWithBinOpOnLHS(Pred, LBO, RHS, Q, MaxRecurse))
+ return V;
- if (RBO)
- if (Value *V = simplifyICmpWithBinOpOnLHS(
- ICmpInst::getSwappedPredicate(Pred), RBO, LHS, Q, MaxRecurse))
- return V;
+ if (RBO)
+ if (Value *V = simplifyICmpWithBinOpOnLHS(
+ ICmpInst::getSwappedPredicate(Pred), RBO, LHS, Q, MaxRecurse))
+ return V;
// 0 - (zext X) pred C
if (!CmpInst::isUnsigned(Pred) && match(LHS, m_Neg(m_ZExt(m_Value())))) {
- const APInt *C;
- if (match(RHS, m_APInt(C))) {
- if (C->isStrictlyPositive()) {
- if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_NE)
- return ConstantInt::getTrue(GetCompareTy(RHS));
- if (Pred == ICmpInst::ICMP_SGE || Pred == ICmpInst::ICMP_EQ)
- return ConstantInt::getFalse(GetCompareTy(RHS));
+ const APInt *C;
+ if (match(RHS, m_APInt(C))) {
+ if (C->isStrictlyPositive()) {
+ if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_NE)
+ return ConstantInt::getTrue(GetCompareTy(RHS));
+ if (Pred == ICmpInst::ICMP_SGE || Pred == ICmpInst::ICMP_EQ)
+ return ConstantInt::getFalse(GetCompareTy(RHS));
}
- if (C->isNonNegative()) {
+ if (C->isNonNegative()) {
if (Pred == ICmpInst::ICMP_SLE)
- return ConstantInt::getTrue(GetCompareTy(RHS));
+ return ConstantInt::getTrue(GetCompareTy(RHS));
if (Pred == ICmpInst::ICMP_SGT)
- return ConstantInt::getFalse(GetCompareTy(RHS));
+ return ConstantInt::getFalse(GetCompareTy(RHS));
}
}
}
- // If C2 is a power-of-2 and C is not:
- // (C2 << X) == C --> false
- // (C2 << X) != C --> true
- const APInt *C;
- if (match(LHS, m_Shl(m_Power2(), m_Value())) &&
- match(RHS, m_APIntAllowUndef(C)) && !C->isPowerOf2()) {
- // C2 << X can equal zero in some circumstances.
- // This simplification might be unsafe if C is zero.
- //
- // We know it is safe if:
- // - The shift is nsw. We can't shift out the one bit.
- // - The shift is nuw. We can't shift out the one bit.
- // - C2 is one.
- // - C isn't zero.
- if (Q.IIQ.hasNoSignedWrap(cast<OverflowingBinaryOperator>(LBO)) ||
- Q.IIQ.hasNoUnsignedWrap(cast<OverflowingBinaryOperator>(LBO)) ||
- match(LHS, m_Shl(m_One(), m_Value())) || !C->isNullValue()) {
- if (Pred == ICmpInst::ICMP_EQ)
- return ConstantInt::getFalse(GetCompareTy(RHS));
- if (Pred == ICmpInst::ICMP_NE)
- return ConstantInt::getTrue(GetCompareTy(RHS));
+ // If C2 is a power-of-2 and C is not:
+ // (C2 << X) == C --> false
+ // (C2 << X) != C --> true
+ const APInt *C;
+ if (match(LHS, m_Shl(m_Power2(), m_Value())) &&
+ match(RHS, m_APIntAllowUndef(C)) && !C->isPowerOf2()) {
+ // C2 << X can equal zero in some circumstances.
+ // This simplification might be unsafe if C is zero.
+ //
+ // We know it is safe if:
+ // - The shift is nsw. We can't shift out the one bit.
+ // - The shift is nuw. We can't shift out the one bit.
+ // - C2 is one.
+ // - C isn't zero.
+ if (Q.IIQ.hasNoSignedWrap(cast<OverflowingBinaryOperator>(LBO)) ||
+ Q.IIQ.hasNoUnsignedWrap(cast<OverflowingBinaryOperator>(LBO)) ||
+ match(LHS, m_Shl(m_One(), m_Value())) || !C->isNullValue()) {
+ if (Pred == ICmpInst::ICMP_EQ)
+ return ConstantInt::getFalse(GetCompareTy(RHS));
+ if (Pred == ICmpInst::ICMP_NE)
+ return ConstantInt::getTrue(GetCompareTy(RHS));
}
}
- // TODO: This is overly constrained. LHS can be any power-of-2.
- // (1 << X) >u 0x8000 --> false
- // (1 << X) <=u 0x8000 --> true
- if (match(LHS, m_Shl(m_One(), m_Value())) && match(RHS, m_SignMask())) {
+ // TODO: This is overly constrained. LHS can be any power-of-2.
+ // (1 << X) >u 0x8000 --> false
+ // (1 << X) <=u 0x8000 --> true
+ if (match(LHS, m_Shl(m_One(), m_Value())) && match(RHS, m_SignMask())) {
if (Pred == ICmpInst::ICMP_UGT)
- return ConstantInt::getFalse(GetCompareTy(RHS));
+ return ConstantInt::getFalse(GetCompareTy(RHS));
if (Pred == ICmpInst::ICMP_ULE)
- return ConstantInt::getTrue(GetCompareTy(RHS));
+ return ConstantInt::getTrue(GetCompareTy(RHS));
}
if (MaxRecurse && LBO && RBO && LBO->getOpcode() == RBO->getOpcode() &&
@@ -3320,31 +3320,31 @@ static Value *simplifyICmpWithMinMax(CmpInst::Predicate Pred, Value *LHS,
}
}
- // Comparing 1 each of min/max with a common operand?
- // Canonicalize min operand to RHS.
- if (match(LHS, m_UMin(m_Value(), m_Value())) ||
- match(LHS, m_SMin(m_Value(), m_Value()))) {
- std::swap(LHS, RHS);
- Pred = ICmpInst::getSwappedPredicate(Pred);
- }
-
+ // Comparing 1 each of min/max with a common operand?
+ // Canonicalize min operand to RHS.
+ if (match(LHS, m_UMin(m_Value(), m_Value())) ||
+ match(LHS, m_SMin(m_Value(), m_Value()))) {
+ std::swap(LHS, RHS);
+ Pred = ICmpInst::getSwappedPredicate(Pred);
+ }
+
Value *C, *D;
if (match(LHS, m_SMax(m_Value(A), m_Value(B))) &&
match(RHS, m_SMin(m_Value(C), m_Value(D))) &&
(A == C || A == D || B == C || B == D)) {
- // smax(A, B) >=s smin(A, D) --> true
+ // smax(A, B) >=s smin(A, D) --> true
if (Pred == CmpInst::ICMP_SGE)
return getTrue(ITy);
- // smax(A, B) <s smin(A, D) --> false
+ // smax(A, B) <s smin(A, D) --> false
if (Pred == CmpInst::ICMP_SLT)
return getFalse(ITy);
} else if (match(LHS, m_UMax(m_Value(A), m_Value(B))) &&
match(RHS, m_UMin(m_Value(C), m_Value(D))) &&
(A == C || A == D || B == C || B == D)) {
- // umax(A, B) >=u umin(A, D) --> true
+ // umax(A, B) >=u umin(A, D) --> true
if (Pred == CmpInst::ICMP_UGE)
return getTrue(ITy);
- // umax(A, B) <u umin(A, D) --> false
+ // umax(A, B) <u umin(A, D) --> false
if (Pred == CmpInst::ICMP_ULT)
return getFalse(ITy);
}
@@ -3398,12 +3398,12 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
// For EQ and NE, we can always pick a value for the undef to make the
// predicate pass or fail, so we can return undef.
// Matches behavior in llvm::ConstantFoldCompareInstruction.
- if (Q.isUndefValue(RHS) && ICmpInst::isEquality(Pred))
+ if (Q.isUndefValue(RHS) && ICmpInst::isEquality(Pred))
return UndefValue::get(ITy);
// icmp X, X -> true/false
// icmp X, undef -> true/false because undef could be X.
- if (LHS == RHS || Q.isUndefValue(RHS))
+ if (LHS == RHS || Q.isUndefValue(RHS))
return ConstantInt::get(ITy, CmpInst::isTrueWhenEqual(Pred));
if (Value *V = simplifyICmpOfBools(Pred, LHS, RHS, Q))
@@ -3659,7 +3659,7 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
// expression GEP with the same indices and a null base pointer to see
// what constant folding can make out of it.
Constant *Null = Constant::getNullValue(GLHS->getPointerOperandType());
- SmallVector<Value *, 4> IndicesLHS(GLHS->indices());
+ SmallVector<Value *, 4> IndicesLHS(GLHS->indices());
Constant *NewLHS = ConstantExpr::getGetElementPtr(
GLHS->getSourceElementType(), Null, IndicesLHS);
@@ -3730,7 +3730,7 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
// fcmp pred x, undef and fcmp pred undef, x
// fold to true if unordered, false if ordered
- if (Q.isUndefValue(LHS) || Q.isUndefValue(RHS)) {
+ if (Q.isUndefValue(LHS) || Q.isUndefValue(RHS)) {
// Choosing NaN for the undef will always make unordered comparison succeed
// and ordered comparison fail.
return ConstantInt::get(RetTy, CmpInst::isUnordered(Pred));
@@ -3774,21 +3774,21 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
break;
}
}
-
- // LHS == Inf
- if (Pred == FCmpInst::FCMP_OEQ && isKnownNeverInfinity(LHS, Q.TLI))
- return getFalse(RetTy);
- // LHS != Inf
- if (Pred == FCmpInst::FCMP_UNE && isKnownNeverInfinity(LHS, Q.TLI))
- return getTrue(RetTy);
- // LHS == Inf || LHS == NaN
- if (Pred == FCmpInst::FCMP_UEQ && isKnownNeverInfinity(LHS, Q.TLI) &&
- isKnownNeverNaN(LHS, Q.TLI))
- return getFalse(RetTy);
- // LHS != Inf && LHS != NaN
- if (Pred == FCmpInst::FCMP_ONE && isKnownNeverInfinity(LHS, Q.TLI) &&
- isKnownNeverNaN(LHS, Q.TLI))
- return getTrue(RetTy);
+
+ // LHS == Inf
+ if (Pred == FCmpInst::FCMP_OEQ && isKnownNeverInfinity(LHS, Q.TLI))
+ return getFalse(RetTy);
+ // LHS != Inf
+ if (Pred == FCmpInst::FCMP_UNE && isKnownNeverInfinity(LHS, Q.TLI))
+ return getTrue(RetTy);
+ // LHS == Inf || LHS == NaN
+ if (Pred == FCmpInst::FCMP_UEQ && isKnownNeverInfinity(LHS, Q.TLI) &&
+ isKnownNeverNaN(LHS, Q.TLI))
+ return getFalse(RetTy);
+ // LHS != Inf && LHS != NaN
+ if (Pred == FCmpInst::FCMP_ONE && isKnownNeverInfinity(LHS, Q.TLI) &&
+ isKnownNeverNaN(LHS, Q.TLI))
+ return getTrue(RetTy);
}
if (C->isNegative() && !C->isNegZero()) {
assert(!C->isNaN() && "Unexpected NaN constant!");
@@ -3920,33 +3920,33 @@ static Value *SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
// We can't replace %sel with %add unless we strip away the flags (which will
// be done in InstCombine).
// TODO: This is unsound, because it only catches some forms of refinement.
- if (!AllowRefinement && canCreatePoison(cast<Operator>(I)))
+ if (!AllowRefinement && canCreatePoison(cast<Operator>(I)))
return nullptr;
- // The simplification queries below may return the original value. Consider:
- // %div = udiv i32 %arg, %arg2
- // %mul = mul nsw i32 %div, %arg2
- // %cmp = icmp eq i32 %mul, %arg
- // %sel = select i1 %cmp, i32 %div, i32 undef
- // Replacing %arg by %mul, %div becomes "udiv i32 %mul, %arg2", which
- // simplifies back to %arg. This can only happen because %mul does not
- // dominate %div. To ensure a consistent return value contract, we make sure
- // that this case returns nullptr as well.
- auto PreventSelfSimplify = [V](Value *Simplified) {
- return Simplified != V ? Simplified : nullptr;
- };
-
+ // The simplification queries below may return the original value. Consider:
+ // %div = udiv i32 %arg, %arg2
+ // %mul = mul nsw i32 %div, %arg2
+ // %cmp = icmp eq i32 %mul, %arg
+ // %sel = select i1 %cmp, i32 %div, i32 undef
+ // Replacing %arg by %mul, %div becomes "udiv i32 %mul, %arg2", which
+ // simplifies back to %arg. This can only happen because %mul does not
+ // dominate %div. To ensure a consistent return value contract, we make sure
+ // that this case returns nullptr as well.
+ auto PreventSelfSimplify = [V](Value *Simplified) {
+ return Simplified != V ? Simplified : nullptr;
+ };
+
// If this is a binary operator, try to simplify it with the replaced op.
if (auto *B = dyn_cast<BinaryOperator>(I)) {
if (MaxRecurse) {
if (B->getOperand(0) == Op)
- return PreventSelfSimplify(SimplifyBinOp(B->getOpcode(), RepOp,
- B->getOperand(1), Q,
- MaxRecurse - 1));
+ return PreventSelfSimplify(SimplifyBinOp(B->getOpcode(), RepOp,
+ B->getOperand(1), Q,
+ MaxRecurse - 1));
if (B->getOperand(1) == Op)
- return PreventSelfSimplify(SimplifyBinOp(B->getOpcode(),
- B->getOperand(0), RepOp, Q,
- MaxRecurse - 1));
+ return PreventSelfSimplify(SimplifyBinOp(B->getOpcode(),
+ B->getOperand(0), RepOp, Q,
+ MaxRecurse - 1));
}
}
@@ -3954,13 +3954,13 @@ static Value *SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
if (CmpInst *C = dyn_cast<CmpInst>(I)) {
if (MaxRecurse) {
if (C->getOperand(0) == Op)
- return PreventSelfSimplify(SimplifyCmpInst(C->getPredicate(), RepOp,
- C->getOperand(1), Q,
- MaxRecurse - 1));
+ return PreventSelfSimplify(SimplifyCmpInst(C->getPredicate(), RepOp,
+ C->getOperand(1), Q,
+ MaxRecurse - 1));
if (C->getOperand(1) == Op)
- return PreventSelfSimplify(SimplifyCmpInst(C->getPredicate(),
- C->getOperand(0), RepOp, Q,
- MaxRecurse - 1));
+ return PreventSelfSimplify(SimplifyCmpInst(C->getPredicate(),
+ C->getOperand(0), RepOp, Q,
+ MaxRecurse - 1));
}
}
@@ -3970,8 +3970,8 @@ static Value *SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
SmallVector<Value *, 8> NewOps(GEP->getNumOperands());
transform(GEP->operands(), NewOps.begin(),
[&](Value *V) { return V == Op ? RepOp : V; });
- return PreventSelfSimplify(SimplifyGEPInst(GEP->getSourceElementType(),
- NewOps, Q, MaxRecurse - 1));
+ return PreventSelfSimplify(SimplifyGEPInst(GEP->getSourceElementType(),
+ NewOps, Q, MaxRecurse - 1));
}
}
@@ -4090,8 +4090,8 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
// Test for a bogus zero-shift-guard-op around funnel-shift or rotate.
Value *ShAmt;
- auto isFsh = m_CombineOr(m_FShl(m_Value(X), m_Value(), m_Value(ShAmt)),
- m_FShr(m_Value(), m_Value(X), m_Value(ShAmt)));
+ auto isFsh = m_CombineOr(m_FShl(m_Value(X), m_Value(), m_Value(ShAmt)),
+ m_FShr(m_Value(), m_Value(X), m_Value(ShAmt)));
// (ShAmt == 0) ? fshl(X, *, ShAmt) : X --> X
// (ShAmt == 0) ? fshr(*, X, ShAmt) : X --> X
if (match(TrueVal, isFsh) && FalseVal == X && CmpLHS == ShAmt)
@@ -4102,24 +4102,24 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
// intrinsics do not have that problem.
// We do not allow this transform for the general funnel shift case because
// that would not preserve the poison safety of the original code.
- auto isRotate =
- m_CombineOr(m_FShl(m_Value(X), m_Deferred(X), m_Value(ShAmt)),
- m_FShr(m_Value(X), m_Deferred(X), m_Value(ShAmt)));
+ auto isRotate =
+ m_CombineOr(m_FShl(m_Value(X), m_Deferred(X), m_Value(ShAmt)),
+ m_FShr(m_Value(X), m_Deferred(X), m_Value(ShAmt)));
// (ShAmt == 0) ? X : fshl(X, X, ShAmt) --> fshl(X, X, ShAmt)
// (ShAmt == 0) ? X : fshr(X, X, ShAmt) --> fshr(X, X, ShAmt)
if (match(FalseVal, isRotate) && TrueVal == X && CmpLHS == ShAmt &&
Pred == ICmpInst::ICMP_EQ)
return FalseVal;
-
- // X == 0 ? abs(X) : -abs(X) --> -abs(X)
- // X == 0 ? -abs(X) : abs(X) --> abs(X)
- if (match(TrueVal, m_Intrinsic<Intrinsic::abs>(m_Specific(CmpLHS))) &&
- match(FalseVal, m_Neg(m_Intrinsic<Intrinsic::abs>(m_Specific(CmpLHS)))))
- return FalseVal;
- if (match(TrueVal,
- m_Neg(m_Intrinsic<Intrinsic::abs>(m_Specific(CmpLHS)))) &&
- match(FalseVal, m_Intrinsic<Intrinsic::abs>(m_Specific(CmpLHS))))
- return FalseVal;
+
+ // X == 0 ? abs(X) : -abs(X) --> -abs(X)
+ // X == 0 ? -abs(X) : abs(X) --> abs(X)
+ if (match(TrueVal, m_Intrinsic<Intrinsic::abs>(m_Specific(CmpLHS))) &&
+ match(FalseVal, m_Neg(m_Intrinsic<Intrinsic::abs>(m_Specific(CmpLHS)))))
+ return FalseVal;
+ if (match(TrueVal,
+ m_Neg(m_Intrinsic<Intrinsic::abs>(m_Specific(CmpLHS)))) &&
+ match(FalseVal, m_Intrinsic<Intrinsic::abs>(m_Specific(CmpLHS))))
+ return FalseVal;
}
// Check for other compares that behave like bit test.
@@ -4127,12 +4127,12 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
TrueVal, FalseVal))
return V;
- // If we have a scalar equality comparison, then we know the value in one of
- // the arms of the select. See if substituting this value into the arm and
+ // If we have a scalar equality comparison, then we know the value in one of
+ // the arms of the select. See if substituting this value into the arm and
// simplifying the result yields the same value as the other arm.
- // Note that the equivalence/replacement opportunity does not hold for vectors
- // because each element of a vector select is chosen independently.
- if (Pred == ICmpInst::ICMP_EQ && !CondVal->getType()->isVectorTy()) {
+ // Note that the equivalence/replacement opportunity does not hold for vectors
+ // because each element of a vector select is chosen independently.
+ if (Pred == ICmpInst::ICMP_EQ && !CondVal->getType()->isVectorTy()) {
if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, Q,
/* AllowRefinement */ false, MaxRecurse) ==
TrueVal ||
@@ -4193,7 +4193,7 @@ static Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
return ConstantFoldSelectInstruction(CondC, TrueC, FalseC);
// select undef, X, Y -> X or Y
- if (Q.isUndefValue(CondC))
+ if (Q.isUndefValue(CondC))
return isa<Constant>(FalseVal) ? FalseVal : TrueVal;
// TODO: Vector constants with undef elements don't simplify.
@@ -4219,24 +4219,24 @@ static Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
if (TrueVal == FalseVal)
return TrueVal;
- // If the true or false value is undef, we can fold to the other value as
- // long as the other value isn't poison.
- // select ?, undef, X -> X
- if (Q.isUndefValue(TrueVal) &&
- isGuaranteedNotToBeUndefOrPoison(FalseVal, Q.AC, Q.CxtI, Q.DT))
+ // If the true or false value is undef, we can fold to the other value as
+ // long as the other value isn't poison.
+ // select ?, undef, X -> X
+ if (Q.isUndefValue(TrueVal) &&
+ isGuaranteedNotToBeUndefOrPoison(FalseVal, Q.AC, Q.CxtI, Q.DT))
return FalseVal;
- // select ?, X, undef -> X
- if (Q.isUndefValue(FalseVal) &&
- isGuaranteedNotToBeUndefOrPoison(TrueVal, Q.AC, Q.CxtI, Q.DT))
+ // select ?, X, undef -> X
+ if (Q.isUndefValue(FalseVal) &&
+ isGuaranteedNotToBeUndefOrPoison(TrueVal, Q.AC, Q.CxtI, Q.DT))
return TrueVal;
// Deal with partial undef vector constants: select ?, VecC, VecC' --> VecC''
Constant *TrueC, *FalseC;
- if (isa<FixedVectorType>(TrueVal->getType()) &&
- match(TrueVal, m_Constant(TrueC)) &&
+ if (isa<FixedVectorType>(TrueVal->getType()) &&
+ match(TrueVal, m_Constant(TrueC)) &&
match(FalseVal, m_Constant(FalseC))) {
- unsigned NumElts =
- cast<FixedVectorType>(TrueC->getType())->getNumElements();
+ unsigned NumElts =
+ cast<FixedVectorType>(TrueC->getType())->getNumElements();
SmallVector<Constant *, 16> NewC;
for (unsigned i = 0; i != NumElts; ++i) {
// Bail out on incomplete vector constants.
@@ -4249,11 +4249,11 @@ static Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
// one element is undef, choose the defined element as the safe result.
if (TEltC == FEltC)
NewC.push_back(TEltC);
- else if (Q.isUndefValue(TEltC) &&
- isGuaranteedNotToBeUndefOrPoison(FEltC))
+ else if (Q.isUndefValue(TEltC) &&
+ isGuaranteedNotToBeUndefOrPoison(FEltC))
NewC.push_back(FEltC);
- else if (Q.isUndefValue(FEltC) &&
- isGuaranteedNotToBeUndefOrPoison(TEltC))
+ else if (Q.isUndefValue(FEltC) &&
+ isGuaranteedNotToBeUndefOrPoison(TEltC))
NewC.push_back(TEltC);
else
break;
@@ -4304,12 +4304,12 @@ static Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
else if (VectorType *VT = dyn_cast<VectorType>(Ops[1]->getType()))
GEPTy = VectorType::get(GEPTy, VT->getElementCount());
- // getelementptr poison, idx -> poison
- // getelementptr baseptr, poison -> poison
- if (any_of(Ops, [](const auto *V) { return isa<PoisonValue>(V); }))
- return PoisonValue::get(GEPTy);
-
- if (Q.isUndefValue(Ops[0]))
+ // getelementptr poison, idx -> poison
+ // getelementptr baseptr, poison -> poison
+ if (any_of(Ops, [](const auto *V) { return isa<PoisonValue>(V); }))
+ return PoisonValue::get(GEPTy);
+
+ if (Q.isUndefValue(Ops[0]))
return UndefValue::get(GEPTy);
bool IsScalableVec = isa<ScalableVectorType>(SrcTy);
@@ -4332,7 +4332,7 @@ static Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
// doesn't truncate the pointers.
if (Ops[1]->getType()->getScalarSizeInBits() ==
Q.DL.getPointerSizeInBits(AS)) {
- auto PtrToInt = [GEPTy](Value *P) -> Value * {
+ auto PtrToInt = [GEPTy](Value *P) -> Value * {
Value *Temp;
if (match(P, m_PtrToInt(m_Value(Temp))))
if (Temp->getType() == GEPTy)
@@ -4340,14 +4340,14 @@ static Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
return nullptr;
};
- // FIXME: The following transforms are only legal if P and V have the
- // same provenance (PR44403). Check whether getUnderlyingObject() is
- // the same?
-
+ // FIXME: The following transforms are only legal if P and V have the
+ // same provenance (PR44403). Check whether getUnderlyingObject() is
+ // the same?
+
// getelementptr V, (sub P, V) -> P if P points to a type of size 1.
if (TyAllocSize == 1 &&
match(Ops[1], m_Sub(m_Value(P), m_PtrToInt(m_Specific(Ops[0])))))
- if (Value *R = PtrToInt(P))
+ if (Value *R = PtrToInt(P))
return R;
// getelementptr V, (ashr (sub P, V), C) -> Q
@@ -4356,7 +4356,7 @@ static Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
m_AShr(m_Sub(m_Value(P), m_PtrToInt(m_Specific(Ops[0]))),
m_ConstantInt(C))) &&
TyAllocSize == 1ULL << C)
- if (Value *R = PtrToInt(P))
+ if (Value *R = PtrToInt(P))
return R;
// getelementptr V, (sdiv (sub P, V), C) -> Q
@@ -4364,7 +4364,7 @@ static Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
if (match(Ops[1],
m_SDiv(m_Sub(m_Value(P), m_PtrToInt(m_Specific(Ops[0]))),
m_SpecificInt(TyAllocSize))))
- if (Value *R = PtrToInt(P))
+ if (Value *R = PtrToInt(P))
return R;
}
}
@@ -4381,21 +4381,21 @@ static Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
Ops[0]->stripAndAccumulateInBoundsConstantOffsets(Q.DL,
BasePtrOffset);
- // Avoid creating inttoptr of zero here: While LLVMs treatment of
- // inttoptr is generally conservative, this particular case is folded to
- // a null pointer, which will have incorrect provenance.
-
+ // Avoid creating inttoptr of zero here: While LLVMs treatment of
+ // inttoptr is generally conservative, this particular case is folded to
+ // a null pointer, which will have incorrect provenance.
+
// gep (gep V, C), (sub 0, V) -> C
if (match(Ops.back(),
- m_Sub(m_Zero(), m_PtrToInt(m_Specific(StrippedBasePtr)))) &&
- !BasePtrOffset.isNullValue()) {
+ m_Sub(m_Zero(), m_PtrToInt(m_Specific(StrippedBasePtr)))) &&
+ !BasePtrOffset.isNullValue()) {
auto *CI = ConstantInt::get(GEPTy->getContext(), BasePtrOffset);
return ConstantExpr::getIntToPtr(CI, GEPTy);
}
// gep (gep V, C), (xor V, -1) -> C-1
if (match(Ops.back(),
- m_Xor(m_PtrToInt(m_Specific(StrippedBasePtr)), m_AllOnes())) &&
- !BasePtrOffset.isOneValue()) {
+ m_Xor(m_PtrToInt(m_Specific(StrippedBasePtr)), m_AllOnes())) &&
+ !BasePtrOffset.isOneValue()) {
auto *CI = ConstantInt::get(GEPTy->getContext(), BasePtrOffset - 1);
return ConstantExpr::getIntToPtr(CI, GEPTy);
}
@@ -4426,7 +4426,7 @@ static Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
return ConstantFoldInsertValueInstruction(CAgg, CVal, Idxs);
// insertvalue x, undef, n -> x
- if (Q.isUndefValue(Val))
+ if (Q.isUndefValue(Val))
return Agg;
// insertvalue x, (extractvalue y, n), n
@@ -4434,7 +4434,7 @@ static Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
if (EV->getAggregateOperand()->getType() == Agg->getType() &&
EV->getIndices() == Idxs) {
// insertvalue undef, (extractvalue y, n), n -> y
- if (Q.isUndefValue(Agg))
+ if (Q.isUndefValue(Agg))
return EV->getAggregateOperand();
// insertvalue y, (extractvalue y, n), n -> y
@@ -4458,23 +4458,23 @@ Value *llvm::SimplifyInsertElementInst(Value *Vec, Value *Val, Value *Idx,
auto *ValC = dyn_cast<Constant>(Val);
auto *IdxC = dyn_cast<Constant>(Idx);
if (VecC && ValC && IdxC)
- return ConstantExpr::getInsertElement(VecC, ValC, IdxC);
+ return ConstantExpr::getInsertElement(VecC, ValC, IdxC);
- // For fixed-length vector, fold into poison if index is out of bounds.
+ // For fixed-length vector, fold into poison if index is out of bounds.
if (auto *CI = dyn_cast<ConstantInt>(Idx)) {
if (isa<FixedVectorType>(Vec->getType()) &&
CI->uge(cast<FixedVectorType>(Vec->getType())->getNumElements()))
- return PoisonValue::get(Vec->getType());
+ return PoisonValue::get(Vec->getType());
}
// If index is undef, it might be out of bounds (see above case)
- if (Q.isUndefValue(Idx))
- return PoisonValue::get(Vec->getType());
+ if (Q.isUndefValue(Idx))
+ return PoisonValue::get(Vec->getType());
- // If the scalar is poison, or it is undef and there is no risk of
- // propagating poison from the vector value, simplify to the vector value.
- if (isa<PoisonValue>(Val) ||
- (Q.isUndefValue(Val) && isGuaranteedNotToBePoison(Vec)))
+ // If the scalar is poison, or it is undef and there is no risk of
+ // propagating poison from the vector value, simplify to the vector value.
+ if (isa<PoisonValue>(Val) ||
+ (Q.isUndefValue(Val) && isGuaranteedNotToBePoison(Vec)))
return Vec;
// If we are extracting a value from a vector, then inserting it into the same
@@ -4518,18 +4518,18 @@ Value *llvm::SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
/// Given operands for an ExtractElementInst, see if we can fold the result.
/// If not, this returns null.
-static Value *SimplifyExtractElementInst(Value *Vec, Value *Idx,
- const SimplifyQuery &Q, unsigned) {
+static Value *SimplifyExtractElementInst(Value *Vec, Value *Idx,
+ const SimplifyQuery &Q, unsigned) {
auto *VecVTy = cast<VectorType>(Vec->getType());
if (auto *CVec = dyn_cast<Constant>(Vec)) {
if (auto *CIdx = dyn_cast<Constant>(Idx))
- return ConstantExpr::getExtractElement(CVec, CIdx);
+ return ConstantExpr::getExtractElement(CVec, CIdx);
// The index is not relevant if our vector is a splat.
if (auto *Splat = CVec->getSplatValue())
return Splat;
- if (Q.isUndefValue(Vec))
+ if (Q.isUndefValue(Vec))
return UndefValue::get(VecVTy->getElementType());
}
@@ -4538,16 +4538,16 @@ static Value *SimplifyExtractElementInst(Value *Vec, Value *Idx,
if (auto *IdxC = dyn_cast<ConstantInt>(Idx)) {
// For fixed-length vector, fold into undef if index is out of bounds.
if (isa<FixedVectorType>(VecVTy) &&
- IdxC->getValue().uge(cast<FixedVectorType>(VecVTy)->getNumElements()))
- return PoisonValue::get(VecVTy->getElementType());
+ IdxC->getValue().uge(cast<FixedVectorType>(VecVTy)->getNumElements()))
+ return PoisonValue::get(VecVTy->getElementType());
if (Value *Elt = findScalarElement(Vec, IdxC->getZExtValue()))
return Elt;
}
// An undef extract index can be arbitrarily chosen to be an out-of-range
- // index value, which would result in the instruction being poison.
- if (Q.isUndefValue(Idx))
- return PoisonValue::get(VecVTy->getElementType());
+ // index value, which would result in the instruction being poison.
+ if (Q.isUndefValue(Idx))
+ return PoisonValue::get(VecVTy->getElementType());
return nullptr;
}
@@ -4559,10 +4559,10 @@ Value *llvm::SimplifyExtractElementInst(Value *Vec, Value *Idx,
/// See if we can fold the given phi. If not, returns null.
static Value *SimplifyPHINode(PHINode *PN, const SimplifyQuery &Q) {
- // WARNING: no matter how worthwhile it may seem, we can not perform PHI CSE
- // here, because the PHI we may succeed simplifying to was not
- // def-reachable from the original PHI!
-
+ // WARNING: no matter how worthwhile it may seem, we can not perform PHI CSE
+ // here, because the PHI we may succeed simplifying to was not
+ // def-reachable from the original PHI!
+
// If all of the PHI's incoming values are the same then replace the PHI node
// with the common value.
Value *CommonValue = nullptr;
@@ -4570,7 +4570,7 @@ static Value *SimplifyPHINode(PHINode *PN, const SimplifyQuery &Q) {
for (Value *Incoming : PN->incoming_values()) {
// If the incoming value is the phi node itself, it can safely be skipped.
if (Incoming == PN) continue;
- if (Q.isUndefValue(Incoming)) {
+ if (Q.isUndefValue(Incoming)) {
// Remember that we saw an undef value, but otherwise ignore them.
HasUndefInput = true;
continue;
@@ -4648,7 +4648,7 @@ static Value *foldIdentityShuffles(int DestElt, Value *Op0, Value *Op1,
return nullptr;
// The mask value chooses which source operand we need to look at next.
- int InVecNumElts = cast<FixedVectorType>(Op0->getType())->getNumElements();
+ int InVecNumElts = cast<FixedVectorType>(Op0->getType())->getNumElements();
int RootElt = MaskVal;
Value *SourceOp = Op0;
if (MaskVal >= InVecNumElts) {
@@ -4695,16 +4695,16 @@ static Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1,
unsigned MaskNumElts = Mask.size();
ElementCount InVecEltCount = InVecTy->getElementCount();
- bool Scalable = InVecEltCount.isScalable();
+ bool Scalable = InVecEltCount.isScalable();
SmallVector<int, 32> Indices;
Indices.assign(Mask.begin(), Mask.end());
// Canonicalization: If mask does not select elements from an input vector,
- // replace that input vector with poison.
+ // replace that input vector with poison.
if (!Scalable) {
bool MaskSelects0 = false, MaskSelects1 = false;
- unsigned InVecNumElts = InVecEltCount.getKnownMinValue();
+ unsigned InVecNumElts = InVecEltCount.getKnownMinValue();
for (unsigned i = 0; i != MaskNumElts; ++i) {
if (Indices[i] == -1)
continue;
@@ -4714,9 +4714,9 @@ static Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1,
MaskSelects1 = true;
}
if (!MaskSelects0)
- Op0 = PoisonValue::get(InVecTy);
+ Op0 = PoisonValue::get(InVecTy);
if (!MaskSelects1)
- Op1 = PoisonValue::get(InVecTy);
+ Op1 = PoisonValue::get(InVecTy);
}
auto *Op0Const = dyn_cast<Constant>(Op0);
@@ -4725,16 +4725,16 @@ static Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1,
// If all operands are constant, constant fold the shuffle. This
// transformation depends on the value of the mask which is not known at
// compile time for scalable vectors
- if (Op0Const && Op1Const)
- return ConstantExpr::getShuffleVector(Op0Const, Op1Const, Mask);
+ if (Op0Const && Op1Const)
+ return ConstantExpr::getShuffleVector(Op0Const, Op1Const, Mask);
// Canonicalization: if only one input vector is constant, it shall be the
// second one. This transformation depends on the value of the mask which
// is not known at compile time for scalable vectors
if (!Scalable && Op0Const && !Op1Const) {
std::swap(Op0, Op1);
- ShuffleVectorInst::commuteShuffleMask(Indices,
- InVecEltCount.getKnownMinValue());
+ ShuffleVectorInst::commuteShuffleMask(Indices,
+ InVecEltCount.getKnownMinValue());
}
// A splat of an inserted scalar constant becomes a vector constant:
@@ -4766,7 +4766,7 @@ static Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1,
// A shuffle of a splat is always the splat itself. Legal if the shuffle's
// value type is same as the input vectors' type.
if (auto *OpShuf = dyn_cast<ShuffleVectorInst>(Op0))
- if (Q.isUndefValue(Op1) && RetTy == InVecTy &&
+ if (Q.isUndefValue(Op1) && RetTy == InVecTy &&
is_splat(OpShuf->getShuffleMask()))
return Op0;
@@ -4778,7 +4778,7 @@ static Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1,
// Don't fold a shuffle with undef mask elements. This may get folded in a
// better way using demanded bits or other analysis.
// TODO: Should we allow this?
- if (is_contained(Indices, -1))
+ if (is_contained(Indices, -1))
return nullptr;
// Check if every element of this shuffle can be mapped back to the
@@ -4847,20 +4847,20 @@ static Constant *propagateNaN(Constant *In) {
/// transforms based on undef/NaN because the operation itself makes no
/// difference to the result.
static Constant *simplifyFPOp(ArrayRef<Value *> Ops,
- FastMathFlags FMF,
- const SimplifyQuery &Q) {
+ FastMathFlags FMF,
+ const SimplifyQuery &Q) {
for (Value *V : Ops) {
bool IsNan = match(V, m_NaN());
bool IsInf = match(V, m_Inf());
- bool IsUndef = Q.isUndefValue(V);
+ bool IsUndef = Q.isUndefValue(V);
// If this operation has 'nnan' or 'ninf' and at least 1 disallowed operand
// (an undef operand can be chosen to be Nan/Inf), then the result of
- // this operation is poison.
+ // this operation is poison.
if (FMF.noNaNs() && (IsNan || IsUndef))
- return PoisonValue::get(V->getType());
+ return PoisonValue::get(V->getType());
if (FMF.noInfs() && (IsInf || IsUndef))
- return PoisonValue::get(V->getType());
+ return PoisonValue::get(V->getType());
if (IsUndef || IsNan)
return propagateNaN(cast<Constant>(V));
@@ -4875,7 +4875,7 @@ static Value *SimplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF,
if (Constant *C = foldOrCommuteConstant(Instruction::FAdd, Op0, Op1, Q))
return C;
- if (Constant *C = simplifyFPOp({Op0, Op1}, FMF, Q))
+ if (Constant *C = simplifyFPOp({Op0, Op1}, FMF, Q))
return C;
// fadd X, -0 ==> X
@@ -4922,7 +4922,7 @@ static Value *SimplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF,
if (Constant *C = foldOrCommuteConstant(Instruction::FSub, Op0, Op1, Q))
return C;
- if (Constant *C = simplifyFPOp({Op0, Op1}, FMF, Q))
+ if (Constant *C = simplifyFPOp({Op0, Op1}, FMF, Q))
return C;
// fsub X, +0 ==> X
@@ -4964,7 +4964,7 @@ static Value *SimplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF,
static Value *SimplifyFMAFMul(Value *Op0, Value *Op1, FastMathFlags FMF,
const SimplifyQuery &Q, unsigned MaxRecurse) {
- if (Constant *C = simplifyFPOp({Op0, Op1}, FMF, Q))
+ if (Constant *C = simplifyFPOp({Op0, Op1}, FMF, Q))
return C;
// fmul X, 1.0 ==> X
@@ -5031,7 +5031,7 @@ static Value *SimplifyFDivInst(Value *Op0, Value *Op1, FastMathFlags FMF,
if (Constant *C = foldOrCommuteConstant(Instruction::FDiv, Op0, Op1, Q))
return C;
- if (Constant *C = simplifyFPOp({Op0, Op1}, FMF, Q))
+ if (Constant *C = simplifyFPOp({Op0, Op1}, FMF, Q))
return C;
// X / 1.0 -> X
@@ -5076,7 +5076,7 @@ static Value *SimplifyFRemInst(Value *Op0, Value *Op1, FastMathFlags FMF,
if (Constant *C = foldOrCommuteConstant(Instruction::FRem, Op0, Op1, Q))
return C;
- if (Constant *C = simplifyFPOp({Op0, Op1}, FMF, Q))
+ if (Constant *C = simplifyFPOp({Op0, Op1}, FMF, Q))
return C;
// Unlike fdiv, the result of frem always matches the sign of the dividend.
@@ -5321,15 +5321,15 @@ static Value *simplifyUnaryIntrinsic(Function *F, Value *Op0,
// bitreverse(bitreverse(x)) -> x
if (match(Op0, m_BitReverse(m_Value(X)))) return X;
break;
- case Intrinsic::ctpop: {
- // If everything but the lowest bit is zero, that bit is the pop-count. Ex:
- // ctpop(and X, 1) --> and X, 1
- unsigned BitWidth = Op0->getType()->getScalarSizeInBits();
- if (MaskedValueIsZero(Op0, APInt::getHighBitsSet(BitWidth, BitWidth - 1),
- Q.DL, 0, Q.AC, Q.CxtI, Q.DT))
- return Op0;
- break;
- }
+ case Intrinsic::ctpop: {
+ // If everything but the lowest bit is zero, that bit is the pop-count. Ex:
+ // ctpop(and X, 1) --> and X, 1
+ unsigned BitWidth = Op0->getType()->getScalarSizeInBits();
+ if (MaskedValueIsZero(Op0, APInt::getHighBitsSet(BitWidth, BitWidth - 1),
+ Q.DL, 0, Q.AC, Q.CxtI, Q.DT))
+ return Op0;
+ break;
+ }
case Intrinsic::exp:
// exp(log(x)) -> x
if (Q.CxtI->hasAllowReassoc() &&
@@ -5382,156 +5382,156 @@ static Value *simplifyUnaryIntrinsic(Function *F, Value *Op0,
return nullptr;
}
-static Intrinsic::ID getMaxMinOpposite(Intrinsic::ID IID) {
- switch (IID) {
- case Intrinsic::smax: return Intrinsic::smin;
- case Intrinsic::smin: return Intrinsic::smax;
- case Intrinsic::umax: return Intrinsic::umin;
- case Intrinsic::umin: return Intrinsic::umax;
- default: llvm_unreachable("Unexpected intrinsic");
- }
-}
-
-static APInt getMaxMinLimit(Intrinsic::ID IID, unsigned BitWidth) {
- switch (IID) {
- case Intrinsic::smax: return APInt::getSignedMaxValue(BitWidth);
- case Intrinsic::smin: return APInt::getSignedMinValue(BitWidth);
- case Intrinsic::umax: return APInt::getMaxValue(BitWidth);
- case Intrinsic::umin: return APInt::getMinValue(BitWidth);
- default: llvm_unreachable("Unexpected intrinsic");
- }
-}
-
-static ICmpInst::Predicate getMaxMinPredicate(Intrinsic::ID IID) {
- switch (IID) {
- case Intrinsic::smax: return ICmpInst::ICMP_SGE;
- case Intrinsic::smin: return ICmpInst::ICMP_SLE;
- case Intrinsic::umax: return ICmpInst::ICMP_UGE;
- case Intrinsic::umin: return ICmpInst::ICMP_ULE;
- default: llvm_unreachable("Unexpected intrinsic");
- }
-}
-
-/// Given a min/max intrinsic, see if it can be removed based on having an
-/// operand that is another min/max intrinsic with shared operand(s). The caller
-/// is expected to swap the operand arguments to handle commutation.
-static Value *foldMinMaxSharedOp(Intrinsic::ID IID, Value *Op0, Value *Op1) {
- Value *X, *Y;
- if (!match(Op0, m_MaxOrMin(m_Value(X), m_Value(Y))))
- return nullptr;
-
- auto *MM0 = dyn_cast<IntrinsicInst>(Op0);
- if (!MM0)
- return nullptr;
- Intrinsic::ID IID0 = MM0->getIntrinsicID();
-
- if (Op1 == X || Op1 == Y ||
- match(Op1, m_c_MaxOrMin(m_Specific(X), m_Specific(Y)))) {
- // max (max X, Y), X --> max X, Y
- if (IID0 == IID)
- return MM0;
- // max (min X, Y), X --> X
- if (IID0 == getMaxMinOpposite(IID))
- return Op1;
- }
- return nullptr;
-}
-
+static Intrinsic::ID getMaxMinOpposite(Intrinsic::ID IID) {
+ switch (IID) {
+ case Intrinsic::smax: return Intrinsic::smin;
+ case Intrinsic::smin: return Intrinsic::smax;
+ case Intrinsic::umax: return Intrinsic::umin;
+ case Intrinsic::umin: return Intrinsic::umax;
+ default: llvm_unreachable("Unexpected intrinsic");
+ }
+}
+
+static APInt getMaxMinLimit(Intrinsic::ID IID, unsigned BitWidth) {
+ switch (IID) {
+ case Intrinsic::smax: return APInt::getSignedMaxValue(BitWidth);
+ case Intrinsic::smin: return APInt::getSignedMinValue(BitWidth);
+ case Intrinsic::umax: return APInt::getMaxValue(BitWidth);
+ case Intrinsic::umin: return APInt::getMinValue(BitWidth);
+ default: llvm_unreachable("Unexpected intrinsic");
+ }
+}
+
+static ICmpInst::Predicate getMaxMinPredicate(Intrinsic::ID IID) {
+ switch (IID) {
+ case Intrinsic::smax: return ICmpInst::ICMP_SGE;
+ case Intrinsic::smin: return ICmpInst::ICMP_SLE;
+ case Intrinsic::umax: return ICmpInst::ICMP_UGE;
+ case Intrinsic::umin: return ICmpInst::ICMP_ULE;
+ default: llvm_unreachable("Unexpected intrinsic");
+ }
+}
+
+/// Given a min/max intrinsic, see if it can be removed based on having an
+/// operand that is another min/max intrinsic with shared operand(s). The caller
+/// is expected to swap the operand arguments to handle commutation.
+static Value *foldMinMaxSharedOp(Intrinsic::ID IID, Value *Op0, Value *Op1) {
+ Value *X, *Y;
+ if (!match(Op0, m_MaxOrMin(m_Value(X), m_Value(Y))))
+ return nullptr;
+
+ auto *MM0 = dyn_cast<IntrinsicInst>(Op0);
+ if (!MM0)
+ return nullptr;
+ Intrinsic::ID IID0 = MM0->getIntrinsicID();
+
+ if (Op1 == X || Op1 == Y ||
+ match(Op1, m_c_MaxOrMin(m_Specific(X), m_Specific(Y)))) {
+ // max (max X, Y), X --> max X, Y
+ if (IID0 == IID)
+ return MM0;
+ // max (min X, Y), X --> X
+ if (IID0 == getMaxMinOpposite(IID))
+ return Op1;
+ }
+ return nullptr;
+}
+
static Value *simplifyBinaryIntrinsic(Function *F, Value *Op0, Value *Op1,
const SimplifyQuery &Q) {
Intrinsic::ID IID = F->getIntrinsicID();
Type *ReturnType = F->getReturnType();
- unsigned BitWidth = ReturnType->getScalarSizeInBits();
+ unsigned BitWidth = ReturnType->getScalarSizeInBits();
switch (IID) {
- case Intrinsic::abs:
- // abs(abs(x)) -> abs(x). We don't need to worry about the nsw arg here.
- // It is always ok to pick the earlier abs. We'll just lose nsw if its only
- // on the outer abs.
- if (match(Op0, m_Intrinsic<Intrinsic::abs>(m_Value(), m_Value())))
- return Op0;
- break;
-
- case Intrinsic::smax:
- case Intrinsic::smin:
- case Intrinsic::umax:
- case Intrinsic::umin: {
- // If the arguments are the same, this is a no-op.
- if (Op0 == Op1)
- return Op0;
-
- // Canonicalize constant operand as Op1.
- if (isa<Constant>(Op0))
- std::swap(Op0, Op1);
-
- // Assume undef is the limit value.
- if (Q.isUndefValue(Op1))
- return ConstantInt::get(ReturnType, getMaxMinLimit(IID, BitWidth));
-
- const APInt *C;
- if (match(Op1, m_APIntAllowUndef(C))) {
- // Clamp to limit value. For example:
- // umax(i8 %x, i8 255) --> 255
- if (*C == getMaxMinLimit(IID, BitWidth))
- return ConstantInt::get(ReturnType, *C);
-
- // If the constant op is the opposite of the limit value, the other must
- // be larger/smaller or equal. For example:
- // umin(i8 %x, i8 255) --> %x
- if (*C == getMaxMinLimit(getMaxMinOpposite(IID), BitWidth))
- return Op0;
-
- // Remove nested call if constant operands allow it. Example:
- // max (max X, 7), 5 -> max X, 7
- auto *MinMax0 = dyn_cast<IntrinsicInst>(Op0);
- if (MinMax0 && MinMax0->getIntrinsicID() == IID) {
- // TODO: loosen undef/splat restrictions for vector constants.
- Value *M00 = MinMax0->getOperand(0), *M01 = MinMax0->getOperand(1);
- const APInt *InnerC;
- if ((match(M00, m_APInt(InnerC)) || match(M01, m_APInt(InnerC))) &&
- ((IID == Intrinsic::smax && InnerC->sge(*C)) ||
- (IID == Intrinsic::smin && InnerC->sle(*C)) ||
- (IID == Intrinsic::umax && InnerC->uge(*C)) ||
- (IID == Intrinsic::umin && InnerC->ule(*C))))
- return Op0;
- }
- }
-
- if (Value *V = foldMinMaxSharedOp(IID, Op0, Op1))
- return V;
- if (Value *V = foldMinMaxSharedOp(IID, Op1, Op0))
- return V;
-
- ICmpInst::Predicate Pred = getMaxMinPredicate(IID);
- if (isICmpTrue(Pred, Op0, Op1, Q.getWithoutUndef(), RecursionLimit))
- return Op0;
- if (isICmpTrue(Pred, Op1, Op0, Q.getWithoutUndef(), RecursionLimit))
- return Op1;
-
- if (Optional<bool> Imp =
- isImpliedByDomCondition(Pred, Op0, Op1, Q.CxtI, Q.DL))
- return *Imp ? Op0 : Op1;
- if (Optional<bool> Imp =
- isImpliedByDomCondition(Pred, Op1, Op0, Q.CxtI, Q.DL))
- return *Imp ? Op1 : Op0;
-
- break;
- }
+ case Intrinsic::abs:
+ // abs(abs(x)) -> abs(x). We don't need to worry about the nsw arg here.
+ // It is always ok to pick the earlier abs. We'll just lose nsw if its only
+ // on the outer abs.
+ if (match(Op0, m_Intrinsic<Intrinsic::abs>(m_Value(), m_Value())))
+ return Op0;
+ break;
+
+ case Intrinsic::smax:
+ case Intrinsic::smin:
+ case Intrinsic::umax:
+ case Intrinsic::umin: {
+ // If the arguments are the same, this is a no-op.
+ if (Op0 == Op1)
+ return Op0;
+
+ // Canonicalize constant operand as Op1.
+ if (isa<Constant>(Op0))
+ std::swap(Op0, Op1);
+
+ // Assume undef is the limit value.
+ if (Q.isUndefValue(Op1))
+ return ConstantInt::get(ReturnType, getMaxMinLimit(IID, BitWidth));
+
+ const APInt *C;
+ if (match(Op1, m_APIntAllowUndef(C))) {
+ // Clamp to limit value. For example:
+ // umax(i8 %x, i8 255) --> 255
+ if (*C == getMaxMinLimit(IID, BitWidth))
+ return ConstantInt::get(ReturnType, *C);
+
+ // If the constant op is the opposite of the limit value, the other must
+ // be larger/smaller or equal. For example:
+ // umin(i8 %x, i8 255) --> %x
+ if (*C == getMaxMinLimit(getMaxMinOpposite(IID), BitWidth))
+ return Op0;
+
+ // Remove nested call if constant operands allow it. Example:
+ // max (max X, 7), 5 -> max X, 7
+ auto *MinMax0 = dyn_cast<IntrinsicInst>(Op0);
+ if (MinMax0 && MinMax0->getIntrinsicID() == IID) {
+ // TODO: loosen undef/splat restrictions for vector constants.
+ Value *M00 = MinMax0->getOperand(0), *M01 = MinMax0->getOperand(1);
+ const APInt *InnerC;
+ if ((match(M00, m_APInt(InnerC)) || match(M01, m_APInt(InnerC))) &&
+ ((IID == Intrinsic::smax && InnerC->sge(*C)) ||
+ (IID == Intrinsic::smin && InnerC->sle(*C)) ||
+ (IID == Intrinsic::umax && InnerC->uge(*C)) ||
+ (IID == Intrinsic::umin && InnerC->ule(*C))))
+ return Op0;
+ }
+ }
+
+ if (Value *V = foldMinMaxSharedOp(IID, Op0, Op1))
+ return V;
+ if (Value *V = foldMinMaxSharedOp(IID, Op1, Op0))
+ return V;
+
+ ICmpInst::Predicate Pred = getMaxMinPredicate(IID);
+ if (isICmpTrue(Pred, Op0, Op1, Q.getWithoutUndef(), RecursionLimit))
+ return Op0;
+ if (isICmpTrue(Pred, Op1, Op0, Q.getWithoutUndef(), RecursionLimit))
+ return Op1;
+
+ if (Optional<bool> Imp =
+ isImpliedByDomCondition(Pred, Op0, Op1, Q.CxtI, Q.DL))
+ return *Imp ? Op0 : Op1;
+ if (Optional<bool> Imp =
+ isImpliedByDomCondition(Pred, Op1, Op0, Q.CxtI, Q.DL))
+ return *Imp ? Op1 : Op0;
+
+ break;
+ }
case Intrinsic::usub_with_overflow:
case Intrinsic::ssub_with_overflow:
// X - X -> { 0, false }
- // X - undef -> { 0, false }
- // undef - X -> { 0, false }
- if (Op0 == Op1 || Q.isUndefValue(Op0) || Q.isUndefValue(Op1))
+ // X - undef -> { 0, false }
+ // undef - X -> { 0, false }
+ if (Op0 == Op1 || Q.isUndefValue(Op0) || Q.isUndefValue(Op1))
return Constant::getNullValue(ReturnType);
- break;
+ break;
case Intrinsic::uadd_with_overflow:
case Intrinsic::sadd_with_overflow:
- // X + undef -> { -1, false }
- // undef + x -> { -1, false }
- if (Q.isUndefValue(Op0) || Q.isUndefValue(Op1)) {
+ // X + undef -> { -1, false }
+ // undef + x -> { -1, false }
+ if (Q.isUndefValue(Op0) || Q.isUndefValue(Op1)) {
return ConstantStruct::get(
cast<StructType>(ReturnType),
- {Constant::getAllOnesValue(ReturnType->getStructElementType(0)),
+ {Constant::getAllOnesValue(ReturnType->getStructElementType(0)),
Constant::getNullValue(ReturnType->getStructElementType(1))});
}
break;
@@ -5543,7 +5543,7 @@ static Value *simplifyBinaryIntrinsic(Function *F, Value *Op0, Value *Op1,
return Constant::getNullValue(ReturnType);
// undef * X -> { 0, false }
// X * undef -> { 0, false }
- if (Q.isUndefValue(Op0) || Q.isUndefValue(Op1))
+ if (Q.isUndefValue(Op0) || Q.isUndefValue(Op1))
return Constant::getNullValue(ReturnType);
break;
case Intrinsic::uadd_sat:
@@ -5557,7 +5557,7 @@ static Value *simplifyBinaryIntrinsic(Function *F, Value *Op0, Value *Op1,
// sat(undef + X) -> -1
// For unsigned: Assume undef is MAX, thus we saturate to MAX (-1).
// For signed: Assume undef is ~X, in which case X + ~X = -1.
- if (Q.isUndefValue(Op0) || Q.isUndefValue(Op1))
+ if (Q.isUndefValue(Op0) || Q.isUndefValue(Op1))
return Constant::getAllOnesValue(ReturnType);
// X + 0 -> X
@@ -5574,7 +5574,7 @@ static Value *simplifyBinaryIntrinsic(Function *F, Value *Op0, Value *Op1,
LLVM_FALLTHROUGH;
case Intrinsic::ssub_sat:
// X - X -> 0, X - undef -> 0, undef - X -> 0
- if (Op0 == Op1 || Q.isUndefValue(Op0) || Q.isUndefValue(Op1))
+ if (Op0 == Op1 || Q.isUndefValue(Op0) || Q.isUndefValue(Op1))
return Constant::getNullValue(ReturnType);
// X - 0 -> X
if (match(Op1, m_Zero()))
@@ -5612,44 +5612,44 @@ static Value *simplifyBinaryIntrinsic(Function *F, Value *Op0, Value *Op1,
// If the arguments are the same, this is a no-op.
if (Op0 == Op1) return Op0;
- // Canonicalize constant operand as Op1.
- if (isa<Constant>(Op0))
- std::swap(Op0, Op1);
-
- // If an argument is undef, return the other argument.
- if (Q.isUndefValue(Op1))
+ // Canonicalize constant operand as Op1.
+ if (isa<Constant>(Op0))
+ std::swap(Op0, Op1);
+
+ // If an argument is undef, return the other argument.
+ if (Q.isUndefValue(Op1))
return Op0;
bool PropagateNaN = IID == Intrinsic::minimum || IID == Intrinsic::maximum;
- bool IsMin = IID == Intrinsic::minimum || IID == Intrinsic::minnum;
-
- // minnum(X, nan) -> X
- // maxnum(X, nan) -> X
- // minimum(X, nan) -> nan
- // maximum(X, nan) -> nan
+ bool IsMin = IID == Intrinsic::minimum || IID == Intrinsic::minnum;
+
+ // minnum(X, nan) -> X
+ // maxnum(X, nan) -> X
+ // minimum(X, nan) -> nan
+ // maximum(X, nan) -> nan
if (match(Op1, m_NaN()))
- return PropagateNaN ? propagateNaN(cast<Constant>(Op1)) : Op0;
-
- // In the following folds, inf can be replaced with the largest finite
- // float, if the ninf flag is set.
- const APFloat *C;
- if (match(Op1, m_APFloat(C)) &&
- (C->isInfinity() || (Q.CxtI->hasNoInfs() && C->isLargest()))) {
- // minnum(X, -inf) -> -inf
- // maxnum(X, +inf) -> +inf
- // minimum(X, -inf) -> -inf if nnan
- // maximum(X, +inf) -> +inf if nnan
- if (C->isNegative() == IsMin && (!PropagateNaN || Q.CxtI->hasNoNaNs()))
- return ConstantFP::get(ReturnType, *C);
-
- // minnum(X, +inf) -> X if nnan
- // maxnum(X, -inf) -> X if nnan
- // minimum(X, +inf) -> X
- // maximum(X, -inf) -> X
- if (C->isNegative() != IsMin && (PropagateNaN || Q.CxtI->hasNoNaNs()))
- return Op0;
- }
-
+ return PropagateNaN ? propagateNaN(cast<Constant>(Op1)) : Op0;
+
+ // In the following folds, inf can be replaced with the largest finite
+ // float, if the ninf flag is set.
+ const APFloat *C;
+ if (match(Op1, m_APFloat(C)) &&
+ (C->isInfinity() || (Q.CxtI->hasNoInfs() && C->isLargest()))) {
+ // minnum(X, -inf) -> -inf
+ // maxnum(X, +inf) -> +inf
+ // minimum(X, -inf) -> -inf if nnan
+ // maximum(X, +inf) -> +inf if nnan
+ if (C->isNegative() == IsMin && (!PropagateNaN || Q.CxtI->hasNoNaNs()))
+ return ConstantFP::get(ReturnType, *C);
+
+ // minnum(X, +inf) -> X if nnan
+ // maxnum(X, -inf) -> X if nnan
+ // minimum(X, +inf) -> X
+ // maximum(X, -inf) -> X
+ if (C->isNegative() != IsMin && (PropagateNaN || Q.CxtI->hasNoNaNs()))
+ return Op0;
+ }
+
// Min/max of the same operation with common operand:
// m(m(X, Y)), X --> m(X, Y) (4 commuted variants)
if (auto *M0 = dyn_cast<IntrinsicInst>(Op0))
@@ -5703,11 +5703,11 @@ static Value *simplifyIntrinsic(CallBase *Call, const SimplifyQuery &Q) {
*ShAmtArg = Call->getArgOperand(2);
// If both operands are undef, the result is undef.
- if (Q.isUndefValue(Op0) && Q.isUndefValue(Op1))
+ if (Q.isUndefValue(Op0) && Q.isUndefValue(Op1))
return UndefValue::get(F->getReturnType());
// If shift amount is undef, assume it is zero.
- if (Q.isUndefValue(ShAmtArg))
+ if (Q.isUndefValue(ShAmtArg))
return Call->getArgOperand(IID == Intrinsic::fshl ? 0 : 1);
const APInt *ShAmtC;
@@ -5724,7 +5724,7 @@ static Value *simplifyIntrinsic(CallBase *Call, const SimplifyQuery &Q) {
Value *Op0 = Call->getArgOperand(0);
Value *Op1 = Call->getArgOperand(1);
Value *Op2 = Call->getArgOperand(2);
- if (Value *V = simplifyFPOp({ Op0, Op1, Op2 }, {}, Q))
+ if (Value *V = simplifyFPOp({ Op0, Op1, Op2 }, {}, Q))
return V;
return nullptr;
}
@@ -5733,9 +5733,9 @@ static Value *simplifyIntrinsic(CallBase *Call, const SimplifyQuery &Q) {
}
}
-static Value *tryConstantFoldCall(CallBase *Call, const SimplifyQuery &Q) {
- auto *F = dyn_cast<Function>(Call->getCalledOperand());
- if (!F || !canConstantFoldCallTo(Call, F))
+static Value *tryConstantFoldCall(CallBase *Call, const SimplifyQuery &Q) {
+ auto *F = dyn_cast<Function>(Call->getCalledOperand());
+ if (!F || !canConstantFoldCallTo(Call, F))
return nullptr;
SmallVector<Constant *, 4> ConstantArgs;
@@ -5754,33 +5754,33 @@ static Value *tryConstantFoldCall(CallBase *Call, const SimplifyQuery &Q) {
return ConstantFoldCall(Call, F, ConstantArgs, Q.TLI);
}
-Value *llvm::SimplifyCall(CallBase *Call, const SimplifyQuery &Q) {
- // musttail calls can only be simplified if they are also DCEd.
- // As we can't guarantee this here, don't simplify them.
- if (Call->isMustTailCall())
- return nullptr;
-
- // call undef -> poison
- // call null -> poison
- Value *Callee = Call->getCalledOperand();
- if (isa<UndefValue>(Callee) || isa<ConstantPointerNull>(Callee))
- return PoisonValue::get(Call->getType());
-
- if (Value *V = tryConstantFoldCall(Call, Q))
- return V;
-
- auto *F = dyn_cast<Function>(Callee);
- if (F && F->isIntrinsic())
- if (Value *Ret = simplifyIntrinsic(Call, Q))
- return Ret;
-
- return nullptr;
-}
-
+Value *llvm::SimplifyCall(CallBase *Call, const SimplifyQuery &Q) {
+ // musttail calls can only be simplified if they are also DCEd.
+ // As we can't guarantee this here, don't simplify them.
+ if (Call->isMustTailCall())
+ return nullptr;
+
+ // call undef -> poison
+ // call null -> poison
+ Value *Callee = Call->getCalledOperand();
+ if (isa<UndefValue>(Callee) || isa<ConstantPointerNull>(Callee))
+ return PoisonValue::get(Call->getType());
+
+ if (Value *V = tryConstantFoldCall(Call, Q))
+ return V;
+
+ auto *F = dyn_cast<Function>(Callee);
+ if (F && F->isIntrinsic())
+ if (Value *Ret = simplifyIntrinsic(Call, Q))
+ return Ret;
+
+ return nullptr;
+}
+
/// Given operands for a Freeze, see if we can fold the result.
static Value *SimplifyFreezeInst(Value *Op0, const SimplifyQuery &Q) {
// Use a utility function defined in ValueTracking.
- if (llvm::isGuaranteedNotToBeUndefOrPoison(Op0, Q.AC, Q.CxtI, Q.DT))
+ if (llvm::isGuaranteedNotToBeUndefOrPoison(Op0, Q.AC, Q.CxtI, Q.DT))
return Op0;
// We have room for improvement.
return nullptr;
@@ -5889,7 +5889,7 @@ Value *llvm::SimplifyInstruction(Instruction *I, const SimplifyQuery &SQ,
I->getOperand(2), Q);
break;
case Instruction::GetElementPtr: {
- SmallVector<Value *, 8> Ops(I->operands());
+ SmallVector<Value *, 8> Ops(I->operands());
Result = SimplifyGEPInst(cast<GetElementPtrInst>(I)->getSourceElementType(),
Ops, Q);
break;
diff --git a/contrib/libs/llvm12/lib/Analysis/LazyCallGraph.cpp b/contrib/libs/llvm12/lib/Analysis/LazyCallGraph.cpp
index 3d2bc6cb01..f2c85a69f1 100644
--- a/contrib/libs/llvm12/lib/Analysis/LazyCallGraph.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/LazyCallGraph.cpp
@@ -19,7 +19,7 @@
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
-#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
@@ -256,24 +256,24 @@ void LazyCallGraph::SCC::verify() {
"Must set low link to -1 when adding a node to an SCC!");
for (Edge &E : **N)
assert(E.getNode().isPopulated() && "Can't have an unpopulated node!");
-
-#ifdef EXPENSIVE_CHECKS
- // Verify that all nodes in this SCC can reach all other nodes.
- SmallVector<Node *, 4> Worklist;
- SmallPtrSet<Node *, 4> Visited;
- Worklist.push_back(N);
- while (!Worklist.empty()) {
- Node *VisitingNode = Worklist.pop_back_val();
- if (!Visited.insert(VisitingNode).second)
- continue;
- for (Edge &E : (*VisitingNode)->calls())
- Worklist.push_back(&E.getNode());
- }
- for (Node *NodeToVisit : Nodes) {
- assert(Visited.contains(NodeToVisit) &&
- "Cannot reach all nodes within SCC");
- }
-#endif
+
+#ifdef EXPENSIVE_CHECKS
+ // Verify that all nodes in this SCC can reach all other nodes.
+ SmallVector<Node *, 4> Worklist;
+ SmallPtrSet<Node *, 4> Visited;
+ Worklist.push_back(N);
+ while (!Worklist.empty()) {
+ Node *VisitingNode = Worklist.pop_back_val();
+ if (!Visited.insert(VisitingNode).second)
+ continue;
+ for (Edge &E : (*VisitingNode)->calls())
+ Worklist.push_back(&E.getNode());
+ }
+ for (Node *NodeToVisit : Nodes) {
+ assert(Visited.contains(NodeToVisit) &&
+ "Cannot reach all nodes within SCC");
+ }
+#endif
}
}
#endif
@@ -376,31 +376,31 @@ void LazyCallGraph::RefSCC::verify() {
}
}
}
-
-#ifdef EXPENSIVE_CHECKS
- // Verify that all nodes in this RefSCC can reach all other nodes.
- SmallVector<Node *> Nodes;
- for (SCC *C : SCCs) {
- for (Node &N : *C)
- Nodes.push_back(&N);
- }
- for (Node *N : Nodes) {
- SmallVector<Node *, 4> Worklist;
- SmallPtrSet<Node *, 4> Visited;
- Worklist.push_back(N);
- while (!Worklist.empty()) {
- Node *VisitingNode = Worklist.pop_back_val();
- if (!Visited.insert(VisitingNode).second)
- continue;
- for (Edge &E : **VisitingNode)
- Worklist.push_back(&E.getNode());
- }
- for (Node *NodeToVisit : Nodes) {
- assert(Visited.contains(NodeToVisit) &&
- "Cannot reach all nodes within RefSCC");
- }
- }
-#endif
+
+#ifdef EXPENSIVE_CHECKS
+ // Verify that all nodes in this RefSCC can reach all other nodes.
+ SmallVector<Node *> Nodes;
+ for (SCC *C : SCCs) {
+ for (Node &N : *C)
+ Nodes.push_back(&N);
+ }
+ for (Node *N : Nodes) {
+ SmallVector<Node *, 4> Worklist;
+ SmallPtrSet<Node *, 4> Visited;
+ Worklist.push_back(N);
+ while (!Worklist.empty()) {
+ Node *VisitingNode = Worklist.pop_back_val();
+ if (!Visited.insert(VisitingNode).second)
+ continue;
+ for (Edge &E : **VisitingNode)
+ Worklist.push_back(&E.getNode());
+ }
+ for (Node *NodeToVisit : Nodes) {
+ assert(Visited.contains(NodeToVisit) &&
+ "Cannot reach all nodes within RefSCC");
+ }
+ }
+#endif
}
#endif
@@ -866,7 +866,7 @@ LazyCallGraph::RefSCC::switchInternalEdgeToRef(Node &SourceN, Node &TargetN) {
PendingSCCStack.clear();
while (!DFSStack.empty())
OldSCC.Nodes.push_back(DFSStack.pop_back_val().first);
- for (Node &N : drop_begin(OldSCC, OldSize)) {
+ for (Node &N : drop_begin(OldSCC, OldSize)) {
N.DFSNumber = N.LowLink = -1;
G->SCCMap[&N] = &OldSCC;
}
@@ -1586,215 +1586,215 @@ void LazyCallGraph::removeDeadFunction(Function &F) {
// allocators.
}
-// Gets the Edge::Kind from one function to another by looking at the function's
-// instructions. Asserts if there is no edge.
-// Useful for determining what type of edge should exist between functions when
-// the edge hasn't been created yet.
-static LazyCallGraph::Edge::Kind getEdgeKind(Function &OriginalFunction,
- Function &NewFunction) {
- // In release builds, assume that if there are no direct calls to the new
- // function, then there is a ref edge. In debug builds, keep track of
- // references to assert that there is actually a ref edge if there is no call
- // edge.
-#ifndef NDEBUG
- SmallVector<Constant *, 16> Worklist;
- SmallPtrSet<Constant *, 16> Visited;
-#endif
-
- for (Instruction &I : instructions(OriginalFunction)) {
- if (auto *CB = dyn_cast<CallBase>(&I)) {
- if (Function *Callee = CB->getCalledFunction()) {
- if (Callee == &NewFunction)
- return LazyCallGraph::Edge::Kind::Call;
- }
- }
-#ifndef NDEBUG
- for (Value *Op : I.operand_values()) {
- if (Constant *C = dyn_cast<Constant>(Op)) {
- if (Visited.insert(C).second)
- Worklist.push_back(C);
- }
- }
-#endif
- }
-
-#ifndef NDEBUG
- bool FoundNewFunction = false;
- LazyCallGraph::visitReferences(Worklist, Visited, [&](Function &F) {
- if (&F == &NewFunction)
- FoundNewFunction = true;
- });
- assert(FoundNewFunction && "No edge from original function to new function");
-#endif
-
- return LazyCallGraph::Edge::Kind::Ref;
+// Gets the Edge::Kind from one function to another by looking at the function's
+// instructions. Asserts if there is no edge.
+// Useful for determining what type of edge should exist between functions when
+// the edge hasn't been created yet.
+static LazyCallGraph::Edge::Kind getEdgeKind(Function &OriginalFunction,
+ Function &NewFunction) {
+ // In release builds, assume that if there are no direct calls to the new
+ // function, then there is a ref edge. In debug builds, keep track of
+ // references to assert that there is actually a ref edge if there is no call
+ // edge.
+#ifndef NDEBUG
+ SmallVector<Constant *, 16> Worklist;
+ SmallPtrSet<Constant *, 16> Visited;
+#endif
+
+ for (Instruction &I : instructions(OriginalFunction)) {
+ if (auto *CB = dyn_cast<CallBase>(&I)) {
+ if (Function *Callee = CB->getCalledFunction()) {
+ if (Callee == &NewFunction)
+ return LazyCallGraph::Edge::Kind::Call;
+ }
+ }
+#ifndef NDEBUG
+ for (Value *Op : I.operand_values()) {
+ if (Constant *C = dyn_cast<Constant>(Op)) {
+ if (Visited.insert(C).second)
+ Worklist.push_back(C);
+ }
+ }
+#endif
+ }
+
+#ifndef NDEBUG
+ bool FoundNewFunction = false;
+ LazyCallGraph::visitReferences(Worklist, Visited, [&](Function &F) {
+ if (&F == &NewFunction)
+ FoundNewFunction = true;
+ });
+ assert(FoundNewFunction && "No edge from original function to new function");
+#endif
+
+ return LazyCallGraph::Edge::Kind::Ref;
+}
+
+void LazyCallGraph::addSplitFunction(Function &OriginalFunction,
+ Function &NewFunction) {
+ assert(lookup(OriginalFunction) &&
+ "Original function's node should already exist");
+ Node &OriginalN = get(OriginalFunction);
+ SCC *OriginalC = lookupSCC(OriginalN);
+ RefSCC *OriginalRC = lookupRefSCC(OriginalN);
+
+#ifndef NDEBUG
+ OriginalRC->verify();
+ auto VerifyOnExit = make_scope_exit([&]() { OriginalRC->verify(); });
+#endif
+
+ assert(!lookup(NewFunction) &&
+ "New function's node should not already exist");
+ Node &NewN = initNode(NewFunction);
+
+ Edge::Kind EK = getEdgeKind(OriginalFunction, NewFunction);
+
+ SCC *NewC = nullptr;
+ for (Edge &E : *NewN) {
+ Node &EN = E.getNode();
+ if (EK == Edge::Kind::Call && E.isCall() && lookupSCC(EN) == OriginalC) {
+ // If the edge to the new function is a call edge and there is a call edge
+ // from the new function to any function in the original function's SCC,
+ // it is in the same SCC (and RefSCC) as the original function.
+ NewC = OriginalC;
+ NewC->Nodes.push_back(&NewN);
+ break;
+ }
+ }
+
+ if (!NewC) {
+ for (Edge &E : *NewN) {
+ Node &EN = E.getNode();
+ if (lookupRefSCC(EN) == OriginalRC) {
+ // If there is any edge from the new function to any function in the
+ // original function's RefSCC, it is in the same RefSCC as the original
+ // function but a new SCC.
+ RefSCC *NewRC = OriginalRC;
+ NewC = createSCC(*NewRC, SmallVector<Node *, 1>({&NewN}));
+
+ // The new function's SCC is not the same as the original function's
+ // SCC, since that case was handled earlier. If the edge from the
+ // original function to the new function was a call edge, then we need
+ // to insert the newly created function's SCC before the original
+ // function's SCC. Otherwise either the new SCC comes after the original
+ // function's SCC, or it doesn't matter, and in both cases we can add it
+ // to the very end.
+ int InsertIndex = EK == Edge::Kind::Call ? NewRC->SCCIndices[OriginalC]
+ : NewRC->SCCIndices.size();
+ NewRC->SCCs.insert(NewRC->SCCs.begin() + InsertIndex, NewC);
+ for (int I = InsertIndex, Size = NewRC->SCCs.size(); I < Size; ++I)
+ NewRC->SCCIndices[NewRC->SCCs[I]] = I;
+
+ break;
+ }
+ }
+ }
+
+ if (!NewC) {
+ // We didn't find any edges back to the original function's RefSCC, so the
+ // new function belongs in a new RefSCC. The new RefSCC goes before the
+ // original function's RefSCC.
+ RefSCC *NewRC = createRefSCC(*this);
+ NewC = createSCC(*NewRC, SmallVector<Node *, 1>({&NewN}));
+ NewRC->SCCIndices[NewC] = 0;
+ NewRC->SCCs.push_back(NewC);
+ auto OriginalRCIndex = RefSCCIndices.find(OriginalRC)->second;
+ PostOrderRefSCCs.insert(PostOrderRefSCCs.begin() + OriginalRCIndex, NewRC);
+ for (int I = OriginalRCIndex, Size = PostOrderRefSCCs.size(); I < Size; ++I)
+ RefSCCIndices[PostOrderRefSCCs[I]] = I;
+ }
+
+ SCCMap[&NewN] = NewC;
+
+ OriginalN->insertEdgeInternal(NewN, EK);
}
-void LazyCallGraph::addSplitFunction(Function &OriginalFunction,
- Function &NewFunction) {
- assert(lookup(OriginalFunction) &&
- "Original function's node should already exist");
- Node &OriginalN = get(OriginalFunction);
- SCC *OriginalC = lookupSCC(OriginalN);
- RefSCC *OriginalRC = lookupRefSCC(OriginalN);
-
-#ifndef NDEBUG
- OriginalRC->verify();
- auto VerifyOnExit = make_scope_exit([&]() { OriginalRC->verify(); });
-#endif
-
- assert(!lookup(NewFunction) &&
- "New function's node should not already exist");
- Node &NewN = initNode(NewFunction);
-
- Edge::Kind EK = getEdgeKind(OriginalFunction, NewFunction);
-
- SCC *NewC = nullptr;
- for (Edge &E : *NewN) {
- Node &EN = E.getNode();
- if (EK == Edge::Kind::Call && E.isCall() && lookupSCC(EN) == OriginalC) {
- // If the edge to the new function is a call edge and there is a call edge
- // from the new function to any function in the original function's SCC,
- // it is in the same SCC (and RefSCC) as the original function.
- NewC = OriginalC;
- NewC->Nodes.push_back(&NewN);
- break;
- }
- }
-
- if (!NewC) {
- for (Edge &E : *NewN) {
- Node &EN = E.getNode();
- if (lookupRefSCC(EN) == OriginalRC) {
- // If there is any edge from the new function to any function in the
- // original function's RefSCC, it is in the same RefSCC as the original
- // function but a new SCC.
- RefSCC *NewRC = OriginalRC;
- NewC = createSCC(*NewRC, SmallVector<Node *, 1>({&NewN}));
-
- // The new function's SCC is not the same as the original function's
- // SCC, since that case was handled earlier. If the edge from the
- // original function to the new function was a call edge, then we need
- // to insert the newly created function's SCC before the original
- // function's SCC. Otherwise either the new SCC comes after the original
- // function's SCC, or it doesn't matter, and in both cases we can add it
- // to the very end.
- int InsertIndex = EK == Edge::Kind::Call ? NewRC->SCCIndices[OriginalC]
- : NewRC->SCCIndices.size();
- NewRC->SCCs.insert(NewRC->SCCs.begin() + InsertIndex, NewC);
- for (int I = InsertIndex, Size = NewRC->SCCs.size(); I < Size; ++I)
- NewRC->SCCIndices[NewRC->SCCs[I]] = I;
-
- break;
- }
- }
- }
-
- if (!NewC) {
- // We didn't find any edges back to the original function's RefSCC, so the
- // new function belongs in a new RefSCC. The new RefSCC goes before the
- // original function's RefSCC.
- RefSCC *NewRC = createRefSCC(*this);
- NewC = createSCC(*NewRC, SmallVector<Node *, 1>({&NewN}));
- NewRC->SCCIndices[NewC] = 0;
- NewRC->SCCs.push_back(NewC);
- auto OriginalRCIndex = RefSCCIndices.find(OriginalRC)->second;
- PostOrderRefSCCs.insert(PostOrderRefSCCs.begin() + OriginalRCIndex, NewRC);
- for (int I = OriginalRCIndex, Size = PostOrderRefSCCs.size(); I < Size; ++I)
- RefSCCIndices[PostOrderRefSCCs[I]] = I;
- }
-
- SCCMap[&NewN] = NewC;
-
- OriginalN->insertEdgeInternal(NewN, EK);
+void LazyCallGraph::addSplitRefRecursiveFunctions(
+ Function &OriginalFunction, ArrayRef<Function *> NewFunctions) {
+ assert(!NewFunctions.empty() && "Can't add zero functions");
+ assert(lookup(OriginalFunction) &&
+ "Original function's node should already exist");
+ Node &OriginalN = get(OriginalFunction);
+ RefSCC *OriginalRC = lookupRefSCC(OriginalN);
+
+#ifndef NDEBUG
+ OriginalRC->verify();
+ auto VerifyOnExit = make_scope_exit([&]() {
+ OriginalRC->verify();
+#ifdef EXPENSIVE_CHECKS
+ for (Function *NewFunction : NewFunctions)
+ lookupRefSCC(get(*NewFunction))->verify();
+#endif
+ });
+#endif
+
+ bool ExistsRefToOriginalRefSCC = false;
+
+ for (Function *NewFunction : NewFunctions) {
+ Node &NewN = initNode(*NewFunction);
+
+ OriginalN->insertEdgeInternal(NewN, Edge::Kind::Ref);
+
+ // Check if there is any edge from any new function back to any function in
+ // the original function's RefSCC.
+ for (Edge &E : *NewN) {
+ if (lookupRefSCC(E.getNode()) == OriginalRC) {
+ ExistsRefToOriginalRefSCC = true;
+ break;
+ }
+ }
+ }
+
+ RefSCC *NewRC;
+ if (ExistsRefToOriginalRefSCC) {
+ // If there is any edge from any new function to any function in the
+ // original function's RefSCC, all new functions will be in the same RefSCC
+ // as the original function.
+ NewRC = OriginalRC;
+ } else {
+ // Otherwise the new functions are in their own RefSCC.
+ NewRC = createRefSCC(*this);
+ // The new RefSCC goes before the original function's RefSCC in postorder
+ // since there are only edges from the original function's RefSCC to the new
+ // RefSCC.
+ auto OriginalRCIndex = RefSCCIndices.find(OriginalRC)->second;
+ PostOrderRefSCCs.insert(PostOrderRefSCCs.begin() + OriginalRCIndex, NewRC);
+ for (int I = OriginalRCIndex, Size = PostOrderRefSCCs.size(); I < Size; ++I)
+ RefSCCIndices[PostOrderRefSCCs[I]] = I;
+ }
+
+ for (Function *NewFunction : NewFunctions) {
+ Node &NewN = get(*NewFunction);
+ // Each new function is in its own new SCC. The original function can only
+ // have a ref edge to new functions, and no other existing functions can
+ // have references to new functions. Each new function only has a ref edge
+ // to the other new functions.
+ SCC *NewC = createSCC(*NewRC, SmallVector<Node *, 1>({&NewN}));
+ // The new SCCs are either sibling SCCs or parent SCCs to all other existing
+ // SCCs in the RefSCC. Either way, they can go at the back of the postorder
+ // SCC list.
+ auto Index = NewRC->SCCIndices.size();
+ NewRC->SCCIndices[NewC] = Index;
+ NewRC->SCCs.push_back(NewC);
+ SCCMap[&NewN] = NewC;
+ }
+
+#ifndef NDEBUG
+ for (Function *F1 : NewFunctions) {
+ assert(getEdgeKind(OriginalFunction, *F1) == Edge::Kind::Ref &&
+ "Expected ref edges from original function to every new function");
+ Node &N1 = get(*F1);
+ for (Function *F2 : NewFunctions) {
+ if (F1 == F2)
+ continue;
+ Node &N2 = get(*F2);
+ assert(!N1->lookup(N2)->isCall() &&
+ "Edges between new functions must be ref edges");
+ }
+ }
+#endif
}
-void LazyCallGraph::addSplitRefRecursiveFunctions(
- Function &OriginalFunction, ArrayRef<Function *> NewFunctions) {
- assert(!NewFunctions.empty() && "Can't add zero functions");
- assert(lookup(OriginalFunction) &&
- "Original function's node should already exist");
- Node &OriginalN = get(OriginalFunction);
- RefSCC *OriginalRC = lookupRefSCC(OriginalN);
-
-#ifndef NDEBUG
- OriginalRC->verify();
- auto VerifyOnExit = make_scope_exit([&]() {
- OriginalRC->verify();
-#ifdef EXPENSIVE_CHECKS
- for (Function *NewFunction : NewFunctions)
- lookupRefSCC(get(*NewFunction))->verify();
-#endif
- });
-#endif
-
- bool ExistsRefToOriginalRefSCC = false;
-
- for (Function *NewFunction : NewFunctions) {
- Node &NewN = initNode(*NewFunction);
-
- OriginalN->insertEdgeInternal(NewN, Edge::Kind::Ref);
-
- // Check if there is any edge from any new function back to any function in
- // the original function's RefSCC.
- for (Edge &E : *NewN) {
- if (lookupRefSCC(E.getNode()) == OriginalRC) {
- ExistsRefToOriginalRefSCC = true;
- break;
- }
- }
- }
-
- RefSCC *NewRC;
- if (ExistsRefToOriginalRefSCC) {
- // If there is any edge from any new function to any function in the
- // original function's RefSCC, all new functions will be in the same RefSCC
- // as the original function.
- NewRC = OriginalRC;
- } else {
- // Otherwise the new functions are in their own RefSCC.
- NewRC = createRefSCC(*this);
- // The new RefSCC goes before the original function's RefSCC in postorder
- // since there are only edges from the original function's RefSCC to the new
- // RefSCC.
- auto OriginalRCIndex = RefSCCIndices.find(OriginalRC)->second;
- PostOrderRefSCCs.insert(PostOrderRefSCCs.begin() + OriginalRCIndex, NewRC);
- for (int I = OriginalRCIndex, Size = PostOrderRefSCCs.size(); I < Size; ++I)
- RefSCCIndices[PostOrderRefSCCs[I]] = I;
- }
-
- for (Function *NewFunction : NewFunctions) {
- Node &NewN = get(*NewFunction);
- // Each new function is in its own new SCC. The original function can only
- // have a ref edge to new functions, and no other existing functions can
- // have references to new functions. Each new function only has a ref edge
- // to the other new functions.
- SCC *NewC = createSCC(*NewRC, SmallVector<Node *, 1>({&NewN}));
- // The new SCCs are either sibling SCCs or parent SCCs to all other existing
- // SCCs in the RefSCC. Either way, they can go at the back of the postorder
- // SCC list.
- auto Index = NewRC->SCCIndices.size();
- NewRC->SCCIndices[NewC] = Index;
- NewRC->SCCs.push_back(NewC);
- SCCMap[&NewN] = NewC;
- }
-
-#ifndef NDEBUG
- for (Function *F1 : NewFunctions) {
- assert(getEdgeKind(OriginalFunction, *F1) == Edge::Kind::Ref &&
- "Expected ref edges from original function to every new function");
- Node &N1 = get(*F1);
- for (Function *F2 : NewFunctions) {
- if (F1 == F2)
- continue;
- Node &N2 = get(*F2);
- assert(!N1->lookup(N2)->isCall() &&
- "Edges between new functions must be ref edges");
- }
- }
-#endif
-}
-
LazyCallGraph::Node &LazyCallGraph::insertInto(Function &F, Node *&MappedN) {
return *new (MappedN = BPA.Allocate()) Node(*this, F);
}
@@ -1809,11 +1809,11 @@ void LazyCallGraph::updateGraphPtrs() {
RC->G = this;
}
-LazyCallGraph::Node &LazyCallGraph::initNode(Function &F) {
+LazyCallGraph::Node &LazyCallGraph::initNode(Function &F) {
Node &N = get(F);
N.DFSNumber = N.LowLink = -1;
N.populate();
- NodeMap[&F] = &N;
+ NodeMap[&F] = &N;
return N;
}
@@ -1958,7 +1958,7 @@ void LazyCallGraph::buildRefSCCs() {
for (Edge &E : *this)
Roots.push_back(&E.getNode());
- // The roots will be iterated in order.
+ // The roots will be iterated in order.
buildGenericSCCs(
Roots,
[](Node &N) {
diff --git a/contrib/libs/llvm12/lib/Analysis/LazyValueInfo.cpp b/contrib/libs/llvm12/lib/Analysis/LazyValueInfo.cpp
index 03bd788ae6..ba2b6fe94c 100644
--- a/contrib/libs/llvm12/lib/Analysis/LazyValueInfo.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/LazyValueInfo.cpp
@@ -36,7 +36,7 @@
#include "llvm/InitializePasses.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/KnownBits.h"
+#include "llvm/Support/KnownBits.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
using namespace llvm;
@@ -151,21 +151,21 @@ namespace {
} // end anonymous namespace
namespace {
- using NonNullPointerSet = SmallDenseSet<AssertingVH<Value>, 2>;
-
+ using NonNullPointerSet = SmallDenseSet<AssertingVH<Value>, 2>;
+
/// This is the cache kept by LazyValueInfo which
/// maintains information about queries across the clients' queries.
class LazyValueInfoCache {
/// This is all of the cached information for one basic block. It contains
/// the per-value lattice elements, as well as a separate set for
- /// overdefined values to reduce memory usage. Additionally pointers
- /// dereferenced in the block are cached for nullability queries.
+ /// overdefined values to reduce memory usage. Additionally pointers
+ /// dereferenced in the block are cached for nullability queries.
struct BlockCacheEntry {
SmallDenseMap<AssertingVH<Value>, ValueLatticeElement, 4> LatticeElements;
SmallDenseSet<AssertingVH<Value>, 4> OverDefined;
- // None indicates that the nonnull pointers for this basic block
- // block have not been computed yet.
- Optional<NonNullPointerSet> NonNullPointers;
+ // None indicates that the nonnull pointers for this basic block
+ // block have not been computed yet.
+ Optional<NonNullPointerSet> NonNullPointers;
};
/// Cached information per basic block.
@@ -227,19 +227,19 @@ namespace {
return LatticeIt->second;
}
- bool isNonNullAtEndOfBlock(
- Value *V, BasicBlock *BB,
- function_ref<NonNullPointerSet(BasicBlock *)> InitFn) {
- BlockCacheEntry *Entry = getOrCreateBlockEntry(BB);
- if (!Entry->NonNullPointers) {
- Entry->NonNullPointers = InitFn(BB);
- for (Value *V : *Entry->NonNullPointers)
- addValueHandle(V);
- }
-
- return Entry->NonNullPointers->count(V);
- }
-
+ bool isNonNullAtEndOfBlock(
+ Value *V, BasicBlock *BB,
+ function_ref<NonNullPointerSet(BasicBlock *)> InitFn) {
+ BlockCacheEntry *Entry = getOrCreateBlockEntry(BB);
+ if (!Entry->NonNullPointers) {
+ Entry->NonNullPointers = InitFn(BB);
+ for (Value *V : *Entry->NonNullPointers)
+ addValueHandle(V);
+ }
+
+ return Entry->NonNullPointers->count(V);
+ }
+
/// clear - Empty the cache.
void clear() {
BlockCache.clear();
@@ -264,8 +264,8 @@ void LazyValueInfoCache::eraseValue(Value *V) {
for (auto &Pair : BlockCache) {
Pair.second->LatticeElements.erase(V);
Pair.second->OverDefined.erase(V);
- if (Pair.second->NonNullPointers)
- Pair.second->NonNullPointers->erase(V);
+ if (Pair.second->NonNullPointers)
+ Pair.second->NonNullPointers->erase(V);
}
auto HandleIt = ValueHandles.find_as(V);
@@ -333,7 +333,7 @@ void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
if (!changed) continue;
- llvm::append_range(worklist, successors(ToUpdate));
+ llvm::append_range(worklist, successors(ToUpdate));
}
}
@@ -410,8 +410,8 @@ class LazyValueInfoImpl {
BasicBlock *BB);
Optional<ValueLatticeElement> solveBlockValueSelect(SelectInst *S,
BasicBlock *BB);
- Optional<ConstantRange> getRangeFor(Value *V, Instruction *CxtI,
- BasicBlock *BB);
+ Optional<ConstantRange> getRangeFor(Value *V, Instruction *CxtI,
+ BasicBlock *BB);
Optional<ValueLatticeElement> solveBlockValueBinaryOpImpl(
Instruction *I, BasicBlock *BB,
std::function<ConstantRange(const ConstantRange &,
@@ -426,7 +426,7 @@ class LazyValueInfoImpl {
BasicBlock *BB);
Optional<ValueLatticeElement> solveBlockValueExtractValue(
ExtractValueInst *EVI, BasicBlock *BB);
- bool isNonNullAtEndOfBlock(Value *Val, BasicBlock *BB);
+ bool isNonNullAtEndOfBlock(Value *Val, BasicBlock *BB);
void intersectAssumeOrGuardBlockValueConstantRange(Value *Val,
ValueLatticeElement &BBLV,
Instruction *BBI);
@@ -434,16 +434,16 @@ class LazyValueInfoImpl {
void solve();
public:
- /// This is the query interface to determine the lattice value for the
- /// specified Value* at the context instruction (if specified) or at the
- /// start of the block.
+ /// This is the query interface to determine the lattice value for the
+ /// specified Value* at the context instruction (if specified) or at the
+ /// start of the block.
ValueLatticeElement getValueInBlock(Value *V, BasicBlock *BB,
Instruction *CxtI = nullptr);
- /// This is the query interface to determine the lattice value for the
- /// specified Value* at the specified instruction using only information
- /// from assumes/guards and range metadata. Unlike getValueInBlock(), no
- /// recursive query is performed.
+ /// This is the query interface to determine the lattice value for the
+ /// specified Value* at the specified instruction using only information
+ /// from assumes/guards and range metadata. Unlike getValueInBlock(), no
+ /// recursive query is performed.
ValueLatticeElement getValueAt(Value *V, Instruction *CxtI);
/// This is the query interface to determine the lattice
@@ -628,43 +628,43 @@ Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueImpl(
return getFromRangeMetadata(BBI);
}
-static void AddNonNullPointer(Value *Ptr, NonNullPointerSet &PtrSet) {
- // TODO: Use NullPointerIsDefined instead.
- if (Ptr->getType()->getPointerAddressSpace() == 0)
- PtrSet.insert(getUnderlyingObject(Ptr));
-}
-
-static void AddNonNullPointersByInstruction(
- Instruction *I, NonNullPointerSet &PtrSet) {
+static void AddNonNullPointer(Value *Ptr, NonNullPointerSet &PtrSet) {
+ // TODO: Use NullPointerIsDefined instead.
+ if (Ptr->getType()->getPointerAddressSpace() == 0)
+ PtrSet.insert(getUnderlyingObject(Ptr));
+}
+
+static void AddNonNullPointersByInstruction(
+ Instruction *I, NonNullPointerSet &PtrSet) {
if (LoadInst *L = dyn_cast<LoadInst>(I)) {
- AddNonNullPointer(L->getPointerOperand(), PtrSet);
- } else if (StoreInst *S = dyn_cast<StoreInst>(I)) {
- AddNonNullPointer(S->getPointerOperand(), PtrSet);
- } else if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I)) {
- if (MI->isVolatile()) return;
+ AddNonNullPointer(L->getPointerOperand(), PtrSet);
+ } else if (StoreInst *S = dyn_cast<StoreInst>(I)) {
+ AddNonNullPointer(S->getPointerOperand(), PtrSet);
+ } else if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I)) {
+ if (MI->isVolatile()) return;
// FIXME: check whether it has a valuerange that excludes zero?
ConstantInt *Len = dyn_cast<ConstantInt>(MI->getLength());
- if (!Len || Len->isZero()) return;
+ if (!Len || Len->isZero()) return;
- AddNonNullPointer(MI->getRawDest(), PtrSet);
+ AddNonNullPointer(MI->getRawDest(), PtrSet);
if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(MI))
- AddNonNullPointer(MTI->getRawSource(), PtrSet);
+ AddNonNullPointer(MTI->getRawSource(), PtrSet);
}
}
-bool LazyValueInfoImpl::isNonNullAtEndOfBlock(Value *Val, BasicBlock *BB) {
- if (NullPointerIsDefined(BB->getParent(),
- Val->getType()->getPointerAddressSpace()))
- return false;
+bool LazyValueInfoImpl::isNonNullAtEndOfBlock(Value *Val, BasicBlock *BB) {
+ if (NullPointerIsDefined(BB->getParent(),
+ Val->getType()->getPointerAddressSpace()))
+ return false;
- Val = getUnderlyingObject(Val);
- return TheCache.isNonNullAtEndOfBlock(Val, BB, [](BasicBlock *BB) {
- NonNullPointerSet NonNullPointers;
+ Val = getUnderlyingObject(Val);
+ return TheCache.isNonNullAtEndOfBlock(Val, BB, [](BasicBlock *BB) {
+ NonNullPointerSet NonNullPointers;
for (Instruction &I : *BB)
- AddNonNullPointersByInstruction(&I, NonNullPointers);
- return NonNullPointers;
- });
+ AddNonNullPointersByInstruction(&I, NonNullPointers);
+ return NonNullPointers;
+ });
}
Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueNonLocal(
@@ -675,7 +675,7 @@ Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueNonLocal(
// value is overdefined.
if (BB == &BB->getParent()->getEntryBlock()) {
assert(isa<Argument>(Val) && "Unknown live-in to the entry block");
- return ValueLatticeElement::getOverdefined();
+ return ValueLatticeElement::getOverdefined();
}
// Loop over all of our predecessors, merging what we know from them into
@@ -772,23 +772,23 @@ void LazyValueInfoImpl::intersectAssumeOrGuardBlockValueConstantRange(
}
// If guards are not used in the module, don't spend time looking for them
- if (GuardDecl && !GuardDecl->use_empty() &&
- BBI->getIterator() != BB->begin()) {
- for (Instruction &I : make_range(std::next(BBI->getIterator().getReverse()),
- BB->rend())) {
- Value *Cond = nullptr;
- if (match(&I, m_Intrinsic<Intrinsic::experimental_guard>(m_Value(Cond))))
- BBLV = intersect(BBLV, getValueFromCondition(Val, Cond));
- }
- }
-
- if (BBLV.isOverdefined()) {
- // Check whether we're checking at the terminator, and the pointer has
- // been dereferenced in this block.
- PointerType *PTy = dyn_cast<PointerType>(Val->getType());
- if (PTy && BB->getTerminator() == BBI &&
- isNonNullAtEndOfBlock(Val, BB))
- BBLV = ValueLatticeElement::getNot(ConstantPointerNull::get(PTy));
+ if (GuardDecl && !GuardDecl->use_empty() &&
+ BBI->getIterator() != BB->begin()) {
+ for (Instruction &I : make_range(std::next(BBI->getIterator().getReverse()),
+ BB->rend())) {
+ Value *Cond = nullptr;
+ if (match(&I, m_Intrinsic<Intrinsic::experimental_guard>(m_Value(Cond))))
+ BBLV = intersect(BBLV, getValueFromCondition(Val, Cond));
+ }
+ }
+
+ if (BBLV.isOverdefined()) {
+ // Check whether we're checking at the terminator, and the pointer has
+ // been dereferenced in this block.
+ PointerType *PTy = dyn_cast<PointerType>(Val->getType());
+ if (PTy && BB->getTerminator() == BBI &&
+ isNonNullAtEndOfBlock(Val, BB))
+ BBLV = ValueLatticeElement::getNot(ConstantPointerNull::get(PTy));
}
}
@@ -922,19 +922,19 @@ Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueSelect(
return Result;
}
-Optional<ConstantRange> LazyValueInfoImpl::getRangeFor(Value *V,
- Instruction *CxtI,
- BasicBlock *BB) {
- Optional<ValueLatticeElement> OptVal = getBlockValue(V, BB);
+Optional<ConstantRange> LazyValueInfoImpl::getRangeFor(Value *V,
+ Instruction *CxtI,
+ BasicBlock *BB) {
+ Optional<ValueLatticeElement> OptVal = getBlockValue(V, BB);
if (!OptVal)
return None;
ValueLatticeElement &Val = *OptVal;
- intersectAssumeOrGuardBlockValueConstantRange(V, Val, CxtI);
+ intersectAssumeOrGuardBlockValueConstantRange(V, Val, CxtI);
if (Val.isConstantRange())
return Val.getConstantRange();
- const unsigned OperandBitWidth = DL.getTypeSizeInBits(V->getType());
+ const unsigned OperandBitWidth = DL.getTypeSizeInBits(V->getType());
return ConstantRange::getFull(OperandBitWidth);
}
@@ -964,7 +964,7 @@ Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueCast(
// Figure out the range of the LHS. If that fails, we still apply the
// transfer rule on the full set since we may be able to locally infer
// interesting facts.
- Optional<ConstantRange> LHSRes = getRangeFor(CI->getOperand(0), CI, BB);
+ Optional<ConstantRange> LHSRes = getRangeFor(CI->getOperand(0), CI, BB);
if (!LHSRes.hasValue())
// More work to do before applying this transfer rule.
return None;
@@ -987,8 +987,8 @@ Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueBinaryOpImpl(
// conservative range, but apply the transfer rule anyways. This
// lets us pick up facts from expressions like "and i32 (call i32
// @foo()), 32"
- Optional<ConstantRange> LHSRes = getRangeFor(I->getOperand(0), I, BB);
- Optional<ConstantRange> RHSRes = getRangeFor(I->getOperand(1), I, BB);
+ Optional<ConstantRange> LHSRes = getRangeFor(I->getOperand(0), I, BB);
+ Optional<ConstantRange> RHSRes = getRangeFor(I->getOperand(1), I, BB);
if (!LHSRes.hasValue() || !RHSRes.hasValue())
// More work to do before applying this transfer rule.
return None;
@@ -1040,22 +1040,22 @@ LazyValueInfoImpl::solveBlockValueOverflowIntrinsic(WithOverflowInst *WO,
Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueIntrinsic(
IntrinsicInst *II, BasicBlock *BB) {
- if (!ConstantRange::isIntrinsicSupported(II->getIntrinsicID())) {
- LLVM_DEBUG(dbgs() << " compute BB '" << BB->getName()
- << "' - overdefined (unknown intrinsic).\n");
- return ValueLatticeElement::getOverdefined();
- }
-
- SmallVector<ConstantRange, 2> OpRanges;
- for (Value *Op : II->args()) {
- Optional<ConstantRange> Range = getRangeFor(Op, II, BB);
- if (!Range)
- return None;
- OpRanges.push_back(*Range);
- }
-
- return ValueLatticeElement::getRange(
- ConstantRange::intrinsic(II->getIntrinsicID(), OpRanges));
+ if (!ConstantRange::isIntrinsicSupported(II->getIntrinsicID())) {
+ LLVM_DEBUG(dbgs() << " compute BB '" << BB->getName()
+ << "' - overdefined (unknown intrinsic).\n");
+ return ValueLatticeElement::getOverdefined();
+ }
+
+ SmallVector<ConstantRange, 2> OpRanges;
+ for (Value *Op : II->args()) {
+ Optional<ConstantRange> Range = getRangeFor(Op, II, BB);
+ if (!Range)
+ return None;
+ OpRanges.push_back(*Range);
+ }
+
+ return ValueLatticeElement::getRange(
+ ConstantRange::intrinsic(II->getIntrinsicID(), OpRanges));
}
Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueExtractValue(
@@ -1099,26 +1099,26 @@ static bool matchICmpOperand(const APInt *&Offset, Value *LHS, Value *Val,
return false;
}
-/// Get value range for a "(Val + Offset) Pred RHS" condition.
-static ValueLatticeElement getValueFromSimpleICmpCondition(
- CmpInst::Predicate Pred, Value *RHS, const APInt *Offset) {
- ConstantRange RHSRange(RHS->getType()->getIntegerBitWidth(),
- /*isFullSet=*/true);
- if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS))
- RHSRange = ConstantRange(CI->getValue());
- else if (Instruction *I = dyn_cast<Instruction>(RHS))
- if (auto *Ranges = I->getMetadata(LLVMContext::MD_range))
- RHSRange = getConstantRangeFromMetadata(*Ranges);
-
- ConstantRange TrueValues =
- ConstantRange::makeAllowedICmpRegion(Pred, RHSRange);
-
- if (Offset)
- TrueValues = TrueValues.subtract(*Offset);
-
- return ValueLatticeElement::getRange(std::move(TrueValues));
-}
-
+/// Get value range for a "(Val + Offset) Pred RHS" condition.
+static ValueLatticeElement getValueFromSimpleICmpCondition(
+ CmpInst::Predicate Pred, Value *RHS, const APInt *Offset) {
+ ConstantRange RHSRange(RHS->getType()->getIntegerBitWidth(),
+ /*isFullSet=*/true);
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS))
+ RHSRange = ConstantRange(CI->getValue());
+ else if (Instruction *I = dyn_cast<Instruction>(RHS))
+ if (auto *Ranges = I->getMetadata(LLVMContext::MD_range))
+ RHSRange = getConstantRangeFromMetadata(*Ranges);
+
+ ConstantRange TrueValues =
+ ConstantRange::makeAllowedICmpRegion(Pred, RHSRange);
+
+ if (Offset)
+ TrueValues = TrueValues.subtract(*Offset);
+
+ return ValueLatticeElement::getRange(std::move(TrueValues));
+}
+
static ValueLatticeElement getValueFromICmpCondition(Value *Val, ICmpInst *ICI,
bool isTrueDest) {
Value *LHS = ICI->getOperand(0);
@@ -1141,27 +1141,27 @@ static ValueLatticeElement getValueFromICmpCondition(Value *Val, ICmpInst *ICI,
return ValueLatticeElement::getOverdefined();
const APInt *Offset = nullptr;
- if (matchICmpOperand(Offset, LHS, Val, EdgePred))
- return getValueFromSimpleICmpCondition(EdgePred, RHS, Offset);
-
- CmpInst::Predicate SwappedPred = CmpInst::getSwappedPredicate(EdgePred);
- if (matchICmpOperand(Offset, RHS, Val, SwappedPred))
- return getValueFromSimpleICmpCondition(SwappedPred, LHS, Offset);
-
- // If (Val & Mask) == C then all the masked bits are known and we can compute
- // a value range based on that.
- const APInt *Mask, *C;
- if (EdgePred == ICmpInst::ICMP_EQ &&
- match(LHS, m_And(m_Specific(Val), m_APInt(Mask))) &&
- match(RHS, m_APInt(C))) {
- KnownBits Known;
- Known.Zero = ~*C & *Mask;
- Known.One = *C & *Mask;
- return ValueLatticeElement::getRange(
- ConstantRange::fromKnownBits(Known, /*IsSigned*/ false));
- }
+ if (matchICmpOperand(Offset, LHS, Val, EdgePred))
+ return getValueFromSimpleICmpCondition(EdgePred, RHS, Offset);
+
+ CmpInst::Predicate SwappedPred = CmpInst::getSwappedPredicate(EdgePred);
+ if (matchICmpOperand(Offset, RHS, Val, SwappedPred))
+ return getValueFromSimpleICmpCondition(SwappedPred, LHS, Offset);
+
+ // If (Val & Mask) == C then all the masked bits are known and we can compute
+ // a value range based on that.
+ const APInt *Mask, *C;
+ if (EdgePred == ICmpInst::ICMP_EQ &&
+ match(LHS, m_And(m_Specific(Val), m_APInt(Mask))) &&
+ match(RHS, m_APInt(C))) {
+ KnownBits Known;
+ Known.Zero = ~*C & *Mask;
+ Known.One = *C & *Mask;
+ return ValueLatticeElement::getRange(
+ ConstantRange::fromKnownBits(Known, /*IsSigned*/ false));
+ }
- return ValueLatticeElement::getOverdefined();
+ return ValueLatticeElement::getOverdefined();
}
// Handle conditions of the form
@@ -1201,36 +1201,36 @@ getValueFromConditionImpl(Value *Val, Value *Cond, bool isTrueDest,
if (EVI->getNumIndices() == 1 && *EVI->idx_begin() == 1)
return getValueFromOverflowCondition(Val, WO, isTrueDest);
- Value *L, *R;
- bool IsAnd;
- if (match(Cond, m_LogicalAnd(m_Value(L), m_Value(R))))
- IsAnd = true;
- else if (match(Cond, m_LogicalOr(m_Value(L), m_Value(R))))
- IsAnd = false;
- else
+ Value *L, *R;
+ bool IsAnd;
+ if (match(Cond, m_LogicalAnd(m_Value(L), m_Value(R))))
+ IsAnd = true;
+ else if (match(Cond, m_LogicalOr(m_Value(L), m_Value(R))))
+ IsAnd = false;
+ else
return ValueLatticeElement::getOverdefined();
// Prevent infinite recursion if Cond references itself as in this example:
// Cond: "%tmp4 = and i1 %tmp4, undef"
// BL: "%tmp4 = and i1 %tmp4, undef"
// BR: "i1 undef"
- if (L == Cond || R == Cond)
+ if (L == Cond || R == Cond)
return ValueLatticeElement::getOverdefined();
- // if (L && R) -> intersect L and R
- // if (!(L || R)) -> intersect L and R
- // if (L || R) -> union L and R
- // if (!(L && R)) -> union L and R
- if (isTrueDest ^ IsAnd) {
- ValueLatticeElement V = getValueFromCondition(Val, L, isTrueDest, Visited);
- if (V.isOverdefined())
- return V;
- V.mergeIn(getValueFromCondition(Val, R, isTrueDest, Visited));
- return V;
- }
-
- return intersect(getValueFromCondition(Val, L, isTrueDest, Visited),
- getValueFromCondition(Val, R, isTrueDest, Visited));
+ // if (L && R) -> intersect L and R
+ // if (!(L || R)) -> intersect L and R
+ // if (L || R) -> union L and R
+ // if (!(L && R)) -> union L and R
+ if (isTrueDest ^ IsAnd) {
+ ValueLatticeElement V = getValueFromCondition(Val, L, isTrueDest, Visited);
+ if (V.isOverdefined())
+ return V;
+ V.mergeIn(getValueFromCondition(Val, R, isTrueDest, Visited));
+ return V;
+ }
+
+ return intersect(getValueFromCondition(Val, L, isTrueDest, Visited),
+ getValueFromCondition(Val, R, isTrueDest, Visited));
}
static ValueLatticeElement
@@ -1254,15 +1254,15 @@ ValueLatticeElement getValueFromCondition(Value *Val, Value *Cond,
// Return true if Usr has Op as an operand, otherwise false.
static bool usesOperand(User *Usr, Value *Op) {
- return is_contained(Usr->operands(), Op);
+ return is_contained(Usr->operands(), Op);
}
// Return true if the instruction type of Val is supported by
-// constantFoldUser(). Currently CastInst, BinaryOperator and FreezeInst only.
-// Call this before calling constantFoldUser() to find out if it's even worth
-// attempting to call it.
+// constantFoldUser(). Currently CastInst, BinaryOperator and FreezeInst only.
+// Call this before calling constantFoldUser() to find out if it's even worth
+// attempting to call it.
static bool isOperationFoldable(User *Usr) {
- return isa<CastInst>(Usr) || isa<BinaryOperator>(Usr) || isa<FreezeInst>(Usr);
+ return isa<CastInst>(Usr) || isa<BinaryOperator>(Usr) || isa<FreezeInst>(Usr);
}
// Check if Usr can be simplified to an integer constant when the value of one
@@ -1293,9 +1293,9 @@ static ValueLatticeElement constantFoldUser(User *Usr, Value *Op,
SimplifyBinOp(BO->getOpcode(), LHS, RHS, DL))) {
return ValueLatticeElement::getRange(ConstantRange(C->getValue()));
}
- } else if (isa<FreezeInst>(Usr)) {
- assert(cast<FreezeInst>(Usr)->getOperand(0) == Op && "Operand 0 isn't Op");
- return ValueLatticeElement::getRange(ConstantRange(OpConstVal));
+ } else if (isa<FreezeInst>(Usr)) {
+ assert(cast<FreezeInst>(Usr)->getOperand(0) == Op && "Operand 0 isn't Op");
+ return ValueLatticeElement::getRange(ConstantRange(OpConstVal));
}
return ValueLatticeElement::getOverdefined();
}
@@ -1598,12 +1598,12 @@ static bool isKnownNonConstant(Value *V) {
return false;
}
-Constant *LazyValueInfo::getConstant(Value *V, Instruction *CxtI) {
+Constant *LazyValueInfo::getConstant(Value *V, Instruction *CxtI) {
// Bail out early if V is known not to be a Constant.
if (isKnownNonConstant(V))
return nullptr;
- BasicBlock *BB = CxtI->getParent();
+ BasicBlock *BB = CxtI->getParent();
ValueLatticeElement Result =
getImpl(PImpl, AC, BB->getModule()).getValueInBlock(V, BB, CxtI);
@@ -1617,11 +1617,11 @@ Constant *LazyValueInfo::getConstant(Value *V, Instruction *CxtI) {
return nullptr;
}
-ConstantRange LazyValueInfo::getConstantRange(Value *V, Instruction *CxtI,
+ConstantRange LazyValueInfo::getConstantRange(Value *V, Instruction *CxtI,
bool UndefAllowed) {
assert(V->getType()->isIntegerTy());
unsigned Width = V->getType()->getIntegerBitWidth();
- BasicBlock *BB = CxtI->getParent();
+ BasicBlock *BB = CxtI->getParent();
ValueLatticeElement Result =
getImpl(PImpl, AC, BB->getModule()).getValueInBlock(V, BB, CxtI);
if (Result.isUnknown())
@@ -1754,7 +1754,7 @@ LazyValueInfo::getPredicateOnEdge(unsigned Pred, Value *V, Constant *C,
LazyValueInfo::Tristate
LazyValueInfo::getPredicateAt(unsigned Pred, Value *V, Constant *C,
- Instruction *CxtI, bool UseBlockValue) {
+ Instruction *CxtI, bool UseBlockValue) {
// Is or is not NonNull are common predicates being queried. If
// isKnownNonZero can tell us the result of the predicate, we can
// return it quickly. But this is only a fastpath, and falling
@@ -1768,10 +1768,10 @@ LazyValueInfo::getPredicateAt(unsigned Pred, Value *V, Constant *C,
else if (Pred == ICmpInst::ICMP_NE)
return LazyValueInfo::True;
}
-
- ValueLatticeElement Result = UseBlockValue
- ? getImpl(PImpl, AC, M).getValueInBlock(V, CxtI->getParent(), CxtI)
- : getImpl(PImpl, AC, M).getValueAt(V, CxtI);
+
+ ValueLatticeElement Result = UseBlockValue
+ ? getImpl(PImpl, AC, M).getValueInBlock(V, CxtI->getParent(), CxtI)
+ : getImpl(PImpl, AC, M).getValueAt(V, CxtI);
Tristate Ret = getPredicateResult(Pred, C, Result, DL, TLI);
if (Ret != Unknown)
return Ret;
diff --git a/contrib/libs/llvm12/lib/Analysis/LegacyDivergenceAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/LegacyDivergenceAnalysis.cpp
index 76706913f9..30eec5a611 100644
--- a/contrib/libs/llvm12/lib/Analysis/LegacyDivergenceAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/LegacyDivergenceAnalysis.cpp
@@ -299,9 +299,9 @@ FunctionPass *llvm::createLegacyDivergenceAnalysisPass() {
}
void LegacyDivergenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequiredTransitive<DominatorTreeWrapperPass>();
- AU.addRequiredTransitive<PostDominatorTreeWrapperPass>();
- AU.addRequiredTransitive<LoopInfoWrapperPass>();
+ AU.addRequiredTransitive<DominatorTreeWrapperPass>();
+ AU.addRequiredTransitive<PostDominatorTreeWrapperPass>();
+ AU.addRequiredTransitive<LoopInfoWrapperPass>();
AU.setPreservesAll();
}
diff --git a/contrib/libs/llvm12/lib/Analysis/Lint.cpp b/contrib/libs/llvm12/lib/Analysis/Lint.cpp
index 82e95d2276..e188c23cf3 100644
--- a/contrib/libs/llvm12/lib/Analysis/Lint.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/Lint.cpp
@@ -63,7 +63,7 @@
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/InitializePasses.h"
@@ -81,102 +81,102 @@
using namespace llvm;
namespace {
-namespace MemRef {
-static const unsigned Read = 1;
-static const unsigned Write = 2;
-static const unsigned Callee = 4;
-static const unsigned Branchee = 8;
-} // end namespace MemRef
-
-class Lint : public InstVisitor<Lint> {
- friend class InstVisitor<Lint>;
-
- void visitFunction(Function &F);
-
- void visitCallBase(CallBase &CB);
- void visitMemoryReference(Instruction &I, const MemoryLocation &Loc,
- MaybeAlign Alignment, Type *Ty, unsigned Flags);
- void visitEHBeginCatch(IntrinsicInst *II);
- void visitEHEndCatch(IntrinsicInst *II);
-
- void visitReturnInst(ReturnInst &I);
- void visitLoadInst(LoadInst &I);
- void visitStoreInst(StoreInst &I);
- void visitXor(BinaryOperator &I);
- void visitSub(BinaryOperator &I);
- void visitLShr(BinaryOperator &I);
- void visitAShr(BinaryOperator &I);
- void visitShl(BinaryOperator &I);
- void visitSDiv(BinaryOperator &I);
- void visitUDiv(BinaryOperator &I);
- void visitSRem(BinaryOperator &I);
- void visitURem(BinaryOperator &I);
- void visitAllocaInst(AllocaInst &I);
- void visitVAArgInst(VAArgInst &I);
- void visitIndirectBrInst(IndirectBrInst &I);
- void visitExtractElementInst(ExtractElementInst &I);
- void visitInsertElementInst(InsertElementInst &I);
- void visitUnreachableInst(UnreachableInst &I);
-
- Value *findValue(Value *V, bool OffsetOk) const;
- Value *findValueImpl(Value *V, bool OffsetOk,
- SmallPtrSetImpl<Value *> &Visited) const;
-
-public:
- Module *Mod;
- const DataLayout *DL;
- AliasAnalysis *AA;
- AssumptionCache *AC;
- DominatorTree *DT;
- TargetLibraryInfo *TLI;
-
- std::string Messages;
- raw_string_ostream MessagesStr;
-
- Lint(Module *Mod, const DataLayout *DL, AliasAnalysis *AA,
- AssumptionCache *AC, DominatorTree *DT, TargetLibraryInfo *TLI)
- : Mod(Mod), DL(DL), AA(AA), AC(AC), DT(DT), TLI(TLI),
- MessagesStr(Messages) {}
-
- void WriteValues(ArrayRef<const Value *> Vs) {
- for (const Value *V : Vs) {
- if (!V)
- continue;
- if (isa<Instruction>(V)) {
- MessagesStr << *V << '\n';
- } else {
- V->printAsOperand(MessagesStr, true, Mod);
- MessagesStr << '\n';
+namespace MemRef {
+static const unsigned Read = 1;
+static const unsigned Write = 2;
+static const unsigned Callee = 4;
+static const unsigned Branchee = 8;
+} // end namespace MemRef
+
+class Lint : public InstVisitor<Lint> {
+ friend class InstVisitor<Lint>;
+
+ void visitFunction(Function &F);
+
+ void visitCallBase(CallBase &CB);
+ void visitMemoryReference(Instruction &I, const MemoryLocation &Loc,
+ MaybeAlign Alignment, Type *Ty, unsigned Flags);
+ void visitEHBeginCatch(IntrinsicInst *II);
+ void visitEHEndCatch(IntrinsicInst *II);
+
+ void visitReturnInst(ReturnInst &I);
+ void visitLoadInst(LoadInst &I);
+ void visitStoreInst(StoreInst &I);
+ void visitXor(BinaryOperator &I);
+ void visitSub(BinaryOperator &I);
+ void visitLShr(BinaryOperator &I);
+ void visitAShr(BinaryOperator &I);
+ void visitShl(BinaryOperator &I);
+ void visitSDiv(BinaryOperator &I);
+ void visitUDiv(BinaryOperator &I);
+ void visitSRem(BinaryOperator &I);
+ void visitURem(BinaryOperator &I);
+ void visitAllocaInst(AllocaInst &I);
+ void visitVAArgInst(VAArgInst &I);
+ void visitIndirectBrInst(IndirectBrInst &I);
+ void visitExtractElementInst(ExtractElementInst &I);
+ void visitInsertElementInst(InsertElementInst &I);
+ void visitUnreachableInst(UnreachableInst &I);
+
+ Value *findValue(Value *V, bool OffsetOk) const;
+ Value *findValueImpl(Value *V, bool OffsetOk,
+ SmallPtrSetImpl<Value *> &Visited) const;
+
+public:
+ Module *Mod;
+ const DataLayout *DL;
+ AliasAnalysis *AA;
+ AssumptionCache *AC;
+ DominatorTree *DT;
+ TargetLibraryInfo *TLI;
+
+ std::string Messages;
+ raw_string_ostream MessagesStr;
+
+ Lint(Module *Mod, const DataLayout *DL, AliasAnalysis *AA,
+ AssumptionCache *AC, DominatorTree *DT, TargetLibraryInfo *TLI)
+ : Mod(Mod), DL(DL), AA(AA), AC(AC), DT(DT), TLI(TLI),
+ MessagesStr(Messages) {}
+
+ void WriteValues(ArrayRef<const Value *> Vs) {
+ for (const Value *V : Vs) {
+ if (!V)
+ continue;
+ if (isa<Instruction>(V)) {
+ MessagesStr << *V << '\n';
+ } else {
+ V->printAsOperand(MessagesStr, true, Mod);
+ MessagesStr << '\n';
}
}
- }
-
- /// A check failed, so printout out the condition and the message.
- ///
- /// This provides a nice place to put a breakpoint if you want to see why
- /// something is not correct.
- void CheckFailed(const Twine &Message) { MessagesStr << Message << '\n'; }
-
- /// A check failed (with values to print).
- ///
- /// This calls the Message-only version so that the above is easier to set
- /// a breakpoint on.
- template <typename T1, typename... Ts>
- void CheckFailed(const Twine &Message, const T1 &V1, const Ts &... Vs) {
- CheckFailed(Message);
- WriteValues({V1, Vs...});
- }
-};
+ }
+
+ /// A check failed, so printout out the condition and the message.
+ ///
+ /// This provides a nice place to put a breakpoint if you want to see why
+ /// something is not correct.
+ void CheckFailed(const Twine &Message) { MessagesStr << Message << '\n'; }
+
+ /// A check failed (with values to print).
+ ///
+ /// This calls the Message-only version so that the above is easier to set
+ /// a breakpoint on.
+ template <typename T1, typename... Ts>
+ void CheckFailed(const Twine &Message, const T1 &V1, const Ts &... Vs) {
+ CheckFailed(Message);
+ WriteValues({V1, Vs...});
+ }
+};
} // end anonymous namespace
// Assert - We know that cond should be true, if not print an error message.
-#define Assert(C, ...) \
- do { \
- if (!(C)) { \
- CheckFailed(__VA_ARGS__); \
- return; \
- } \
- } while (false)
+#define Assert(C, ...) \
+ do { \
+ if (!(C)) { \
+ CheckFailed(__VA_ARGS__); \
+ return; \
+ } \
+ } while (false)
void Lint::visitFunction(Function &F) {
// This isn't undefined behavior, it's just a little unusual, and it's a
@@ -190,7 +190,7 @@ void Lint::visitFunction(Function &F) {
void Lint::visitCallBase(CallBase &I) {
Value *Callee = I.getCalledOperand();
- visitMemoryReference(I, MemoryLocation::getAfter(Callee), None, nullptr,
+ visitMemoryReference(I, MemoryLocation::getAfter(Callee), None, nullptr,
MemRef::Callee);
if (Function *F = dyn_cast<Function>(findValue(Callee,
@@ -250,10 +250,10 @@ void Lint::visitCallBase(CallBase &I) {
// Check that an sret argument points to valid memory.
if (Formal->hasStructRetAttr() && Actual->getType()->isPointerTy()) {
- Type *Ty = Formal->getParamStructRetType();
- MemoryLocation Loc(
- Actual, LocationSize::precise(DL->getTypeStoreSize(Ty)));
- visitMemoryReference(I, Loc, DL->getABITypeAlign(Ty), Ty,
+ Type *Ty = Formal->getParamStructRetType();
+ MemoryLocation Loc(
+ Actual, LocationSize::precise(DL->getTypeStoreSize(Ty)));
+ visitMemoryReference(I, Loc, DL->getABITypeAlign(Ty), Ty,
MemRef::Read | MemRef::Write);
}
}
@@ -280,22 +280,22 @@ void Lint::visitCallBase(CallBase &I) {
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I))
switch (II->getIntrinsicID()) {
- default:
- break;
+ default:
+ break;
- // TODO: Check more intrinsics
+ // TODO: Check more intrinsics
case Intrinsic::memcpy: {
MemCpyInst *MCI = cast<MemCpyInst>(&I);
- visitMemoryReference(I, MemoryLocation::getForDest(MCI),
+ visitMemoryReference(I, MemoryLocation::getForDest(MCI),
MCI->getDestAlign(), nullptr, MemRef::Write);
- visitMemoryReference(I, MemoryLocation::getForSource(MCI),
+ visitMemoryReference(I, MemoryLocation::getForSource(MCI),
MCI->getSourceAlign(), nullptr, MemRef::Read);
// Check that the memcpy arguments don't overlap. The AliasAnalysis API
// isn't expressive enough for what we really want to do. Known partial
// overlap is not distinguished from the case where nothing is known.
- auto Size = LocationSize::afterPointer();
+ auto Size = LocationSize::afterPointer();
if (const ConstantInt *Len =
dyn_cast<ConstantInt>(findValue(MCI->getLength(),
/*OffsetOk=*/false)))
@@ -309,10 +309,10 @@ void Lint::visitCallBase(CallBase &I) {
case Intrinsic::memcpy_inline: {
MemCpyInlineInst *MCII = cast<MemCpyInlineInst>(&I);
const uint64_t Size = MCII->getLength()->getValue().getLimitedValue();
- visitMemoryReference(I, MemoryLocation::getForDest(MCII),
- MCII->getDestAlign(), nullptr, MemRef::Write);
- visitMemoryReference(I, MemoryLocation::getForSource(MCII),
- MCII->getSourceAlign(), nullptr, MemRef::Read);
+ visitMemoryReference(I, MemoryLocation::getForDest(MCII),
+ MCII->getDestAlign(), nullptr, MemRef::Write);
+ visitMemoryReference(I, MemoryLocation::getForSource(MCII),
+ MCII->getSourceAlign(), nullptr, MemRef::Read);
// Check that the memcpy arguments don't overlap. The AliasAnalysis API
// isn't expressive enough for what we really want to do. Known partial
@@ -324,15 +324,15 @@ void Lint::visitCallBase(CallBase &I) {
}
case Intrinsic::memmove: {
MemMoveInst *MMI = cast<MemMoveInst>(&I);
- visitMemoryReference(I, MemoryLocation::getForDest(MMI),
+ visitMemoryReference(I, MemoryLocation::getForDest(MMI),
MMI->getDestAlign(), nullptr, MemRef::Write);
- visitMemoryReference(I, MemoryLocation::getForSource(MMI),
+ visitMemoryReference(I, MemoryLocation::getForSource(MMI),
MMI->getSourceAlign(), nullptr, MemRef::Read);
break;
}
case Intrinsic::memset: {
MemSetInst *MSI = cast<MemSetInst>(&I);
- visitMemoryReference(I, MemoryLocation::getForDest(MSI),
+ visitMemoryReference(I, MemoryLocation::getForDest(MSI),
MSI->getDestAlign(), nullptr, MemRef::Write);
break;
}
@@ -342,32 +342,32 @@ void Lint::visitCallBase(CallBase &I) {
"Undefined behavior: va_start called in a non-varargs function",
&I);
- visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI), None,
- nullptr, MemRef::Read | MemRef::Write);
+ visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI), None,
+ nullptr, MemRef::Read | MemRef::Write);
break;
case Intrinsic::vacopy:
- visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI), None,
- nullptr, MemRef::Write);
- visitMemoryReference(I, MemoryLocation::getForArgument(&I, 1, TLI), None,
- nullptr, MemRef::Read);
+ visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI), None,
+ nullptr, MemRef::Write);
+ visitMemoryReference(I, MemoryLocation::getForArgument(&I, 1, TLI), None,
+ nullptr, MemRef::Read);
break;
case Intrinsic::vaend:
- visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI), None,
- nullptr, MemRef::Read | MemRef::Write);
+ visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI), None,
+ nullptr, MemRef::Read | MemRef::Write);
break;
case Intrinsic::stackrestore:
// Stackrestore doesn't read or write memory, but it sets the
// stack pointer, which the compiler may read from or write to
// at any time, so check it for both readability and writeability.
- visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI), None,
- nullptr, MemRef::Read | MemRef::Write);
+ visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI), None,
+ nullptr, MemRef::Read | MemRef::Write);
+ break;
+ case Intrinsic::get_active_lane_mask:
+ if (auto *TripCount = dyn_cast<ConstantInt>(I.getArgOperand(1)))
+ Assert(!TripCount->isZero(), "get_active_lane_mask: operand #2 "
+ "must be greater than 0", &I);
break;
- case Intrinsic::get_active_lane_mask:
- if (auto *TripCount = dyn_cast<ConstantInt>(I.getArgOperand(1)))
- Assert(!TripCount->isZero(), "get_active_lane_mask: operand #2 "
- "must be greater than 0", &I);
- break;
}
}
@@ -384,14 +384,14 @@ void Lint::visitReturnInst(ReturnInst &I) {
// TODO: Check that the reference is in bounds.
// TODO: Check readnone/readonly function attributes.
-void Lint::visitMemoryReference(Instruction &I, const MemoryLocation &Loc,
+void Lint::visitMemoryReference(Instruction &I, const MemoryLocation &Loc,
MaybeAlign Align, Type *Ty, unsigned Flags) {
// If no memory is being referenced, it doesn't matter if the pointer
// is valid.
- if (Loc.Size.isZero())
+ if (Loc.Size.isZero())
return;
- Value *Ptr = const_cast<Value *>(Loc.Ptr);
+ Value *Ptr = const_cast<Value *>(Loc.Ptr);
Value *UnderlyingObject = findValue(Ptr, /*OffsetOk=*/true);
Assert(!isa<ConstantPointerNull>(UnderlyingObject),
"Undefined behavior: Null pointer dereference", &I);
@@ -459,8 +459,8 @@ void Lint::visitMemoryReference(Instruction &I, const MemoryLocation &Loc,
// Accesses from before the start or after the end of the object are not
// defined.
- Assert(!Loc.Size.hasValue() || BaseSize == MemoryLocation::UnknownSize ||
- (Offset >= 0 && Offset + Loc.Size.getValue() <= BaseSize),
+ Assert(!Loc.Size.hasValue() || BaseSize == MemoryLocation::UnknownSize ||
+ (Offset >= 0 && Offset + Loc.Size.getValue() <= BaseSize),
"Undefined behavior: Buffer overflow", &I);
// Accesses that say that the memory is more aligned than it is are not
@@ -474,13 +474,13 @@ void Lint::visitMemoryReference(Instruction &I, const MemoryLocation &Loc,
}
void Lint::visitLoadInst(LoadInst &I) {
- visitMemoryReference(I, MemoryLocation::get(&I), I.getAlign(), I.getType(),
- MemRef::Read);
+ visitMemoryReference(I, MemoryLocation::get(&I), I.getAlign(), I.getType(),
+ MemRef::Read);
}
void Lint::visitStoreInst(StoreInst &I) {
- visitMemoryReference(I, MemoryLocation::get(&I), I.getAlign(),
- I.getOperand(0)->getType(), MemRef::Write);
+ visitMemoryReference(I, MemoryLocation::get(&I), I.getAlign(),
+ I.getOperand(0)->getType(), MemRef::Write);
}
void Lint::visitXor(BinaryOperator &I) {
@@ -522,8 +522,8 @@ static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT,
VectorType *VecTy = dyn_cast<VectorType>(V->getType());
if (!VecTy) {
- KnownBits Known =
- computeKnownBits(V, DL, 0, AC, dyn_cast<Instruction>(V), DT);
+ KnownBits Known =
+ computeKnownBits(V, DL, 0, AC, dyn_cast<Instruction>(V), DT);
return Known.isZero();
}
@@ -537,8 +537,8 @@ static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT,
// For a vector, KnownZero will only be true if all values are zero, so check
// this per component
- for (unsigned I = 0, N = cast<FixedVectorType>(VecTy)->getNumElements();
- I != N; ++I) {
+ for (unsigned I = 0, N = cast<FixedVectorType>(VecTy)->getNumElements();
+ I != N; ++I) {
Constant *Elem = C->getAggregateElement(I);
if (isa<UndefValue>(Elem))
return true;
@@ -581,12 +581,12 @@ void Lint::visitAllocaInst(AllocaInst &I) {
}
void Lint::visitVAArgInst(VAArgInst &I) {
- visitMemoryReference(I, MemoryLocation::get(&I), None, nullptr,
- MemRef::Read | MemRef::Write);
+ visitMemoryReference(I, MemoryLocation::get(&I), None, nullptr,
+ MemRef::Read | MemRef::Write);
}
void Lint::visitIndirectBrInst(IndirectBrInst &I) {
- visitMemoryReference(I, MemoryLocation::getAfter(I.getAddress()), None,
+ visitMemoryReference(I, MemoryLocation::getAfter(I.getAddress()), None,
nullptr, MemRef::Branchee);
Assert(I.getNumDestinations() != 0,
@@ -596,17 +596,17 @@ void Lint::visitIndirectBrInst(IndirectBrInst &I) {
void Lint::visitExtractElementInst(ExtractElementInst &I) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(findValue(I.getIndexOperand(),
/*OffsetOk=*/false)))
- Assert(
- CI->getValue().ult(
- cast<FixedVectorType>(I.getVectorOperandType())->getNumElements()),
- "Undefined result: extractelement index out of range", &I);
+ Assert(
+ CI->getValue().ult(
+ cast<FixedVectorType>(I.getVectorOperandType())->getNumElements()),
+ "Undefined result: extractelement index out of range", &I);
}
void Lint::visitInsertElementInst(InsertElementInst &I) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(findValue(I.getOperand(2),
/*OffsetOk=*/false)))
- Assert(CI->getValue().ult(
- cast<FixedVectorType>(I.getType())->getNumElements()),
+ Assert(CI->getValue().ult(
+ cast<FixedVectorType>(I.getType())->getNumElements()),
"Undefined result: insertelement index out of range", &I);
}
@@ -643,7 +643,7 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk,
// TODO: Look through eliminable cast pairs.
// TODO: Look through calls with unique return values.
// TODO: Look through vector insert/extract/shuffle.
- V = OffsetOk ? getUnderlyingObject(V) : V->stripPointerCasts();
+ V = OffsetOk ? getUnderlyingObject(V) : V->stripPointerCasts();
if (LoadInst *L = dyn_cast<LoadInst>(V)) {
BasicBlock::iterator BBI = L->getIterator();
BasicBlock *BB = L->getParent();
@@ -652,13 +652,13 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk,
if (!VisitedBlocks.insert(BB).second)
break;
if (Value *U =
- FindAvailableLoadedValue(L, BB, BBI, DefMaxInstsToScan, AA))
+ FindAvailableLoadedValue(L, BB, BBI, DefMaxInstsToScan, AA))
return findValueImpl(U, OffsetOk, Visited);
- if (BBI != BB->begin())
- break;
+ if (BBI != BB->begin())
+ break;
BB = BB->getUniquePredecessor();
- if (!BB)
- break;
+ if (!BB)
+ break;
BBI = BB->end();
}
} else if (PHINode *PN = dyn_cast<PHINode>(V)) {
@@ -668,8 +668,8 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk,
if (CI->isNoopCast(*DL))
return findValueImpl(CI->getOperand(0), OffsetOk, Visited);
} else if (ExtractValueInst *Ex = dyn_cast<ExtractValueInst>(V)) {
- if (Value *W =
- FindInsertedValue(Ex->getAggregateOperand(), Ex->getIndices()))
+ if (Value *W =
+ FindInsertedValue(Ex->getAggregateOperand(), Ex->getIndices()))
if (W != V)
return findValueImpl(W, OffsetOk, Visited);
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
@@ -700,75 +700,75 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk,
return V;
}
-PreservedAnalyses LintPass::run(Function &F, FunctionAnalysisManager &AM) {
- auto *Mod = F.getParent();
- auto *DL = &F.getParent()->getDataLayout();
- auto *AA = &AM.getResult<AAManager>(F);
- auto *AC = &AM.getResult<AssumptionAnalysis>(F);
- auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
- auto *TLI = &AM.getResult<TargetLibraryAnalysis>(F);
- Lint L(Mod, DL, AA, AC, DT, TLI);
- L.visit(F);
- dbgs() << L.MessagesStr.str();
- return PreservedAnalyses::all();
-}
-
-class LintLegacyPass : public FunctionPass {
-public:
- static char ID; // Pass identification, replacement for typeid
- LintLegacyPass() : FunctionPass(ID) {
- initializeLintLegacyPassPass(*PassRegistry::getPassRegistry());
- }
-
- bool runOnFunction(Function &F) override;
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- AU.addRequired<AAResultsWrapperPass>();
- AU.addRequired<AssumptionCacheTracker>();
- AU.addRequired<TargetLibraryInfoWrapperPass>();
- AU.addRequired<DominatorTreeWrapperPass>();
- }
- void print(raw_ostream &O, const Module *M) const override {}
-};
-
-char LintLegacyPass::ID = 0;
-INITIALIZE_PASS_BEGIN(LintLegacyPass, "lint", "Statically lint-checks LLVM IR",
- false, true)
-INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
-INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
-INITIALIZE_PASS_END(LintLegacyPass, "lint", "Statically lint-checks LLVM IR",
- false, true)
-
-bool LintLegacyPass::runOnFunction(Function &F) {
- auto *Mod = F.getParent();
- auto *DL = &F.getParent()->getDataLayout();
- auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
- auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
- auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
- Lint L(Mod, DL, AA, AC, DT, TLI);
- L.visit(F);
- dbgs() << L.MessagesStr.str();
- return false;
-}
-
+PreservedAnalyses LintPass::run(Function &F, FunctionAnalysisManager &AM) {
+ auto *Mod = F.getParent();
+ auto *DL = &F.getParent()->getDataLayout();
+ auto *AA = &AM.getResult<AAManager>(F);
+ auto *AC = &AM.getResult<AssumptionAnalysis>(F);
+ auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
+ auto *TLI = &AM.getResult<TargetLibraryAnalysis>(F);
+ Lint L(Mod, DL, AA, AC, DT, TLI);
+ L.visit(F);
+ dbgs() << L.MessagesStr.str();
+ return PreservedAnalyses::all();
+}
+
+class LintLegacyPass : public FunctionPass {
+public:
+ static char ID; // Pass identification, replacement for typeid
+ LintLegacyPass() : FunctionPass(ID) {
+ initializeLintLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool runOnFunction(Function &F) override;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ AU.addRequired<AAResultsWrapperPass>();
+ AU.addRequired<AssumptionCacheTracker>();
+ AU.addRequired<TargetLibraryInfoWrapperPass>();
+ AU.addRequired<DominatorTreeWrapperPass>();
+ }
+ void print(raw_ostream &O, const Module *M) const override {}
+};
+
+char LintLegacyPass::ID = 0;
+INITIALIZE_PASS_BEGIN(LintLegacyPass, "lint", "Statically lint-checks LLVM IR",
+ false, true)
+INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
+INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
+INITIALIZE_PASS_END(LintLegacyPass, "lint", "Statically lint-checks LLVM IR",
+ false, true)
+
+bool LintLegacyPass::runOnFunction(Function &F) {
+ auto *Mod = F.getParent();
+ auto *DL = &F.getParent()->getDataLayout();
+ auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
+ auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
+ auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
+ Lint L(Mod, DL, AA, AC, DT, TLI);
+ L.visit(F);
+ dbgs() << L.MessagesStr.str();
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// Implement the public interfaces to this file...
//===----------------------------------------------------------------------===//
-FunctionPass *llvm::createLintLegacyPassPass() { return new LintLegacyPass(); }
+FunctionPass *llvm::createLintLegacyPassPass() { return new LintLegacyPass(); }
/// lintFunction - Check a function for errors, printing messages on stderr.
///
void llvm::lintFunction(const Function &f) {
- Function &F = const_cast<Function &>(f);
+ Function &F = const_cast<Function &>(f);
assert(!F.isDeclaration() && "Cannot lint external functions");
legacy::FunctionPassManager FPM(F.getParent());
- auto *V = new LintLegacyPass();
+ auto *V = new LintLegacyPass();
FPM.add(V);
FPM.run(F);
}
@@ -777,7 +777,7 @@ void llvm::lintFunction(const Function &f) {
///
void llvm::lintModule(const Module &M) {
legacy::PassManager PM;
- auto *V = new LintLegacyPass();
+ auto *V = new LintLegacyPass();
PM.add(V);
- PM.run(const_cast<Module &>(M));
+ PM.run(const_cast<Module &>(M));
}
diff --git a/contrib/libs/llvm12/lib/Analysis/Loads.cpp b/contrib/libs/llvm12/lib/Analysis/Loads.cpp
index 8f1417a552..8f373f70f2 100644
--- a/contrib/libs/llvm12/lib/Analysis/Loads.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/Loads.cpp
@@ -12,9 +12,9 @@
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/MemoryBuiltins.h"
+#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ValueTracking.h"
@@ -109,50 +109,50 @@ static bool isDereferenceableAndAlignedPointer(
return isDereferenceableAndAlignedPointer(ASC->getOperand(0), Alignment,
Size, DL, CtxI, DT, Visited, MaxDepth);
- if (const auto *Call = dyn_cast<CallBase>(V)) {
+ if (const auto *Call = dyn_cast<CallBase>(V)) {
if (auto *RP = getArgumentAliasingToReturnedPointer(Call, true))
return isDereferenceableAndAlignedPointer(RP, Alignment, Size, DL, CtxI,
DT, Visited, MaxDepth);
- // If we have a call we can't recurse through, check to see if this is an
- // allocation function for which we can establish an minimum object size.
- // Such a minimum object size is analogous to a deref_or_null attribute in
- // that we still need to prove the result non-null at point of use.
- // NOTE: We can only use the object size as a base fact as we a) need to
- // prove alignment too, and b) don't want the compile time impact of a
- // separate recursive walk.
- ObjectSizeOpts Opts;
- // TODO: It may be okay to round to align, but that would imply that
- // accessing slightly out of bounds was legal, and we're currently
- // inconsistent about that. For the moment, be conservative.
- Opts.RoundToAlign = false;
- Opts.NullIsUnknownSize = true;
- uint64_t ObjSize;
- // TODO: Plumb through TLI so that malloc routines and such working.
- if (getObjectSize(V, ObjSize, DL, nullptr, Opts)) {
- APInt KnownDerefBytes(Size.getBitWidth(), ObjSize);
- if (KnownDerefBytes.getBoolValue() && KnownDerefBytes.uge(Size) &&
- isKnownNonZero(V, DL, 0, nullptr, CtxI, DT) &&
- // TODO: We're currently inconsistent about whether deref(N) is a
- // global fact or a point in time fact. Once D61652 eventually
- // lands, this check will be restricted to the point in time
- // variant. For that variant, we need to prove that object hasn't
- // been conditionally freed before ontext instruction - if it has, we
- // might be hoisting over the inverse conditional and creating a
- // dynamic use after free.
- !PointerMayBeCapturedBefore(V, true, true, CtxI, DT, true)) {
- // As we recursed through GEPs to get here, we've incrementally
- // checked that each step advanced by a multiple of the alignment. If
- // our base is properly aligned, then the original offset accessed
- // must also be.
- Type *Ty = V->getType();
- assert(Ty->isSized() && "must be sized");
- APInt Offset(DL.getTypeStoreSizeInBits(Ty), 0);
- return isAligned(V, Offset, Alignment, DL);
- }
- }
- }
-
+ // If we have a call we can't recurse through, check to see if this is an
+ // allocation function for which we can establish an minimum object size.
+ // Such a minimum object size is analogous to a deref_or_null attribute in
+ // that we still need to prove the result non-null at point of use.
+ // NOTE: We can only use the object size as a base fact as we a) need to
+ // prove alignment too, and b) don't want the compile time impact of a
+ // separate recursive walk.
+ ObjectSizeOpts Opts;
+ // TODO: It may be okay to round to align, but that would imply that
+ // accessing slightly out of bounds was legal, and we're currently
+ // inconsistent about that. For the moment, be conservative.
+ Opts.RoundToAlign = false;
+ Opts.NullIsUnknownSize = true;
+ uint64_t ObjSize;
+ // TODO: Plumb through TLI so that malloc routines and such working.
+ if (getObjectSize(V, ObjSize, DL, nullptr, Opts)) {
+ APInt KnownDerefBytes(Size.getBitWidth(), ObjSize);
+ if (KnownDerefBytes.getBoolValue() && KnownDerefBytes.uge(Size) &&
+ isKnownNonZero(V, DL, 0, nullptr, CtxI, DT) &&
+ // TODO: We're currently inconsistent about whether deref(N) is a
+ // global fact or a point in time fact. Once D61652 eventually
+ // lands, this check will be restricted to the point in time
+ // variant. For that variant, we need to prove that object hasn't
+ // been conditionally freed before ontext instruction - if it has, we
+ // might be hoisting over the inverse conditional and creating a
+ // dynamic use after free.
+ !PointerMayBeCapturedBefore(V, true, true, CtxI, DT, true)) {
+ // As we recursed through GEPs to get here, we've incrementally
+ // checked that each step advanced by a multiple of the alignment. If
+ // our base is properly aligned, then the original offset accessed
+ // must also be.
+ Type *Ty = V->getType();
+ assert(Ty->isSized() && "must be sized");
+ APInt Offset(DL.getTypeStoreSizeInBits(Ty), 0);
+ return isAligned(V, Offset, Alignment, DL);
+ }
+ }
+ }
+
// If we don't know, assume the worst.
return false;
}
@@ -240,7 +240,7 @@ bool llvm::isDereferenceableAndAlignedInLoop(LoadInst *LI, Loop *L,
Value *Ptr = LI->getPointerOperand();
APInt EltSize(DL.getIndexTypeSizeInBits(Ptr->getType()),
- DL.getTypeStoreSize(LI->getType()).getFixedSize());
+ DL.getTypeStoreSize(LI->getType()).getFixedSize());
const Align Alignment = LI->getAlign();
Instruction *HeaderFirstNonPHI = L->getHeader()->getFirstNonPHI();
@@ -263,7 +263,7 @@ bool llvm::isDereferenceableAndAlignedInLoop(LoadInst *LI, Loop *L,
if (Step->getAPInt() != EltSize)
return false;
- auto TC = SE.getSmallConstantMaxTripCount(L);
+ auto TC = SE.getSmallConstantMaxTripCount(L);
if (!TC)
return false;
@@ -542,23 +542,23 @@ Value *llvm::FindAvailablePtrLoadStore(Value *Ptr, Type *AccessTy,
// block.
return nullptr;
}
-
-bool llvm::canReplacePointersIfEqual(Value *A, Value *B, const DataLayout &DL,
- Instruction *CtxI) {
- Type *Ty = A->getType();
- assert(Ty == B->getType() && Ty->isPointerTy() &&
- "values must have matching pointer types");
-
- // NOTE: The checks in the function are incomplete and currently miss illegal
- // cases! The current implementation is a starting point and the
- // implementation should be made stricter over time.
- if (auto *C = dyn_cast<Constant>(B)) {
- // Do not allow replacing a pointer with a constant pointer, unless it is
- // either null or at least one byte is dereferenceable.
- APInt OneByte(DL.getPointerTypeSizeInBits(Ty), 1);
- return C->isNullValue() ||
- isDereferenceableAndAlignedPointer(B, Align(1), OneByte, DL, CtxI);
- }
-
- return true;
-}
+
+bool llvm::canReplacePointersIfEqual(Value *A, Value *B, const DataLayout &DL,
+ Instruction *CtxI) {
+ Type *Ty = A->getType();
+ assert(Ty == B->getType() && Ty->isPointerTy() &&
+ "values must have matching pointer types");
+
+ // NOTE: The checks in the function are incomplete and currently miss illegal
+ // cases! The current implementation is a starting point and the
+ // implementation should be made stricter over time.
+ if (auto *C = dyn_cast<Constant>(B)) {
+ // Do not allow replacing a pointer with a constant pointer, unless it is
+ // either null or at least one byte is dereferenceable.
+ APInt OneByte(DL.getPointerTypeSizeInBits(Ty), 1);
+ return C->isNullValue() ||
+ isDereferenceableAndAlignedPointer(B, Align(1), OneByte, DL, CtxI);
+ }
+
+ return true;
+}
diff --git a/contrib/libs/llvm12/lib/Analysis/LoopAccessAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/LoopAccessAnalysis.cpp
index 6e59f1fa12..e632fe25c2 100644
--- a/contrib/libs/llvm12/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/LoopAccessAnalysis.cpp
@@ -149,23 +149,23 @@ const SCEV *llvm::replaceSymbolicStrideSCEV(PredicatedScalarEvolution &PSE,
// symbolic stride replaced by one.
ValueToValueMap::const_iterator SI =
PtrToStride.find(OrigPtr ? OrigPtr : Ptr);
- if (SI == PtrToStride.end())
- // For a non-symbolic stride, just return the original expression.
- return OrigSCEV;
+ if (SI == PtrToStride.end())
+ // For a non-symbolic stride, just return the original expression.
+ return OrigSCEV;
- Value *StrideVal = stripIntegerCast(SI->second);
+ Value *StrideVal = stripIntegerCast(SI->second);
- ScalarEvolution *SE = PSE.getSE();
- const auto *U = cast<SCEVUnknown>(SE->getSCEV(StrideVal));
- const auto *CT =
- static_cast<const SCEVConstant *>(SE->getOne(StrideVal->getType()));
+ ScalarEvolution *SE = PSE.getSE();
+ const auto *U = cast<SCEVUnknown>(SE->getSCEV(StrideVal));
+ const auto *CT =
+ static_cast<const SCEVConstant *>(SE->getOne(StrideVal->getType()));
- PSE.addPredicate(*SE->getEqualPredicate(U, CT));
- auto *Expr = PSE.getSCEV(Ptr);
+ PSE.addPredicate(*SE->getEqualPredicate(U, CT));
+ auto *Expr = PSE.getSCEV(Ptr);
- LLVM_DEBUG(dbgs() << "LAA: Replacing SCEV: " << *OrigSCEV
- << " by: " << *Expr << "\n");
- return Expr;
+ LLVM_DEBUG(dbgs() << "LAA: Replacing SCEV: " << *OrigSCEV
+ << " by: " << *Expr << "\n");
+ return Expr;
}
RuntimeCheckingPtrGroup::RuntimeCheckingPtrGroup(
@@ -223,10 +223,10 @@ void RuntimePointerChecking::insert(Loop *Lp, Value *Ptr, bool WritePtr,
ScEnd = SE->getUMaxExpr(AR->getStart(), ScEnd);
}
// Add the size of the pointed element to ScEnd.
- auto &DL = Lp->getHeader()->getModule()->getDataLayout();
- Type *IdxTy = DL.getIndexType(Ptr->getType());
- const SCEV *EltSizeSCEV =
- SE->getStoreSizeOfExpr(IdxTy, Ptr->getType()->getPointerElementType());
+ auto &DL = Lp->getHeader()->getModule()->getDataLayout();
+ Type *IdxTy = DL.getIndexType(Ptr->getType());
+ const SCEV *EltSizeSCEV =
+ SE->getStoreSizeOfExpr(IdxTy, Ptr->getType()->getPointerElementType());
ScEnd = SE->getAddExpr(ScEnd, EltSizeSCEV);
}
@@ -505,16 +505,16 @@ public:
typedef PointerIntPair<Value *, 1, bool> MemAccessInfo;
typedef SmallVector<MemAccessInfo, 8> MemAccessInfoList;
- AccessAnalysis(Loop *TheLoop, AAResults *AA, LoopInfo *LI,
- MemoryDepChecker::DepCandidates &DA,
+ AccessAnalysis(Loop *TheLoop, AAResults *AA, LoopInfo *LI,
+ MemoryDepChecker::DepCandidates &DA,
PredicatedScalarEvolution &PSE)
- : TheLoop(TheLoop), AST(*AA), LI(LI), DepCands(DA),
+ : TheLoop(TheLoop), AST(*AA), LI(LI), DepCands(DA),
IsRTCheckAnalysisNeeded(false), PSE(PSE) {}
/// Register a load and whether it is only read from.
void addLoad(MemoryLocation &Loc, bool IsReadOnly) {
Value *Ptr = const_cast<Value*>(Loc.Ptr);
- AST.add(Ptr, LocationSize::beforeOrAfterPointer(), Loc.AATags);
+ AST.add(Ptr, LocationSize::beforeOrAfterPointer(), Loc.AATags);
Accesses.insert(MemAccessInfo(Ptr, false));
if (IsReadOnly)
ReadOnlyPtr.insert(Ptr);
@@ -523,7 +523,7 @@ public:
/// Register a store.
void addStore(MemoryLocation &Loc) {
Value *Ptr = const_cast<Value*>(Loc.Ptr);
- AST.add(Ptr, LocationSize::beforeOrAfterPointer(), Loc.AATags);
+ AST.add(Ptr, LocationSize::beforeOrAfterPointer(), Loc.AATags);
Accesses.insert(MemAccessInfo(Ptr, true));
}
@@ -727,7 +727,7 @@ bool AccessAnalysis::canCheckPtrAtRT(RuntimePointerChecking &RtCheck,
// First, count how many write and read accesses are in the alias set. Also
// collect MemAccessInfos for later.
SmallVector<MemAccessInfo, 4> AccessInfos;
- for (const auto &A : AS) {
+ for (const auto &A : AS) {
Value *Ptr = A.getValue();
bool IsWrite = Accesses.count(MemAccessInfo(Ptr, true));
@@ -861,7 +861,7 @@ void AccessAnalysis::processMemAccesses() {
// compatibility and potential for underlying-object overlap. As a result, we
// only need to check for potential pointer dependencies within each alias
// set.
- for (const auto &AS : AST) {
+ for (const auto &AS : AST) {
// Note that both the alias-set tracker and the alias sets themselves used
// linked lists internally and so the iteration order here is deterministic
// (matching the original instruction order within each set).
@@ -881,12 +881,12 @@ void AccessAnalysis::processMemAccesses() {
bool UseDeferred = SetIteration > 0;
PtrAccessSet &S = UseDeferred ? DeferredAccesses : Accesses;
- for (const auto &AV : AS) {
+ for (const auto &AV : AS) {
Value *Ptr = AV.getValue();
// For a single memory access in AliasSetTracker, Accesses may contain
// both read and write, and they both need to be handled for CheckDeps.
- for (const auto &AC : S) {
+ for (const auto &AC : S) {
if (AC.getPointer() != Ptr)
continue;
@@ -933,7 +933,7 @@ void AccessAnalysis::processMemAccesses() {
typedef SmallVector<const Value *, 16> ValueVector;
ValueVector TempObjects;
- getUnderlyingObjects(Ptr, TempObjects, LI);
+ getUnderlyingObjects(Ptr, TempObjects, LI);
LLVM_DEBUG(dbgs()
<< "Underlying objects for pointer " << *Ptr << "\n");
for (const Value *UnderlyingObj : TempObjects) {
@@ -987,7 +987,7 @@ static bool isNoWrapAddRec(Value *Ptr, const SCEVAddRecExpr *AR,
// Make sure there is only one non-const index and analyze that.
Value *NonConstIndex = nullptr;
- for (Value *Index : GEP->indices())
+ for (Value *Index : GEP->indices())
if (!isa<ConstantInt>(Index)) {
if (NonConstIndex)
return false;
@@ -1137,7 +1137,7 @@ bool llvm::sortPtrAccesses(ArrayRef<Value *> VL, const DataLayout &DL,
// first pointer in the array.
Value *Ptr0 = VL[0];
const SCEV *Scev0 = SE.getSCEV(Ptr0);
- Value *Obj0 = getUnderlyingObject(Ptr0);
+ Value *Obj0 = getUnderlyingObject(Ptr0);
llvm::SmallSet<int64_t, 4> Offsets;
for (auto *Ptr : VL) {
@@ -1148,7 +1148,7 @@ bool llvm::sortPtrAccesses(ArrayRef<Value *> VL, const DataLayout &DL,
return false;
// If a pointer refers to a different underlying object, bail - the
// pointers are by definition incomparable.
- Value *CurrObj = getUnderlyingObject(Ptr);
+ Value *CurrObj = getUnderlyingObject(Ptr);
if (CurrObj != Obj0)
return false;
@@ -1338,7 +1338,7 @@ bool MemoryDepChecker::couldPreventStoreLoadForward(uint64_t Distance,
// If the number of vector iteration between the store and the load are
// small we could incur conflicts.
if (Distance % VF && Distance / VF < NumItersForStoreLoadThroughMemory) {
- MaxVFWithoutSLForwardIssues = (VF >> 1);
+ MaxVFWithoutSLForwardIssues = (VF >> 1);
break;
}
}
@@ -1654,7 +1654,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
LLVM_DEBUG(dbgs() << "LAA: Positive distance " << Val.getSExtValue()
<< " with max VF = " << MaxVF << '\n');
uint64_t MaxVFInBits = MaxVF * TypeByteSize * 8;
- MaxSafeVectorWidthInBits = std::min(MaxSafeVectorWidthInBits, MaxVFInBits);
+ MaxSafeVectorWidthInBits = std::min(MaxSafeVectorWidthInBits, MaxVFInBits);
return Dependence::BackwardVectorizable;
}
@@ -1766,7 +1766,7 @@ bool LoopAccessInfo::canAnalyzeLoop() {
<< TheLoop->getHeader()->getName() << '\n');
// We can only analyze innermost loops.
- if (!TheLoop->isInnermost()) {
+ if (!TheLoop->isInnermost()) {
LLVM_DEBUG(dbgs() << "LAA: loop is not the innermost loop\n");
recordAnalysis("NotInnerMostLoop") << "loop is not the innermost loop";
return false;
@@ -1783,7 +1783,7 @@ bool LoopAccessInfo::canAnalyzeLoop() {
// ScalarEvolution needs to be able to find the exit count.
const SCEV *ExitCount = PSE->getBackedgeTakenCount();
- if (isa<SCEVCouldNotCompute>(ExitCount)) {
+ if (isa<SCEVCouldNotCompute>(ExitCount)) {
recordAnalysis("CantComputeNumberOfIterations")
<< "could not determine number of loop iterations";
LLVM_DEBUG(dbgs() << "LAA: SCEV could not compute the loop exit count.\n");
@@ -1922,9 +1922,9 @@ void LoopAccessInfo::analyzeLoop(AAResults *AA, LoopInfo *LI,
}
MemoryDepChecker::DepCandidates DependentAccesses;
- AccessAnalysis Accesses(TheLoop, AA, LI, DependentAccesses, *PSE);
+ AccessAnalysis Accesses(TheLoop, AA, LI, DependentAccesses, *PSE);
- // Holds the analyzed pointers. We don't want to call getUnderlyingObjects
+ // Holds the analyzed pointers. We don't want to call getUnderlyingObjects
// multiple times on the same object. If the ptr is accessed twice, once
// for read and once for write, it will only appear once (on the write
// list). This is okay, since we are going to check for conflicts between
@@ -2126,8 +2126,8 @@ bool LoopAccessInfo::isUniform(Value *V) const {
}
void LoopAccessInfo::collectStridedAccess(Value *MemAccess) {
- Value *Ptr = getLoadStorePointerOperand(MemAccess);
- if (!Ptr)
+ Value *Ptr = getLoadStorePointerOperand(MemAccess);
+ if (!Ptr)
return;
Value *Stride = getStrideFromPointer(Ptr, PSE->getSE(), TheLoop);
diff --git a/contrib/libs/llvm12/lib/Analysis/LoopAnalysisManager.cpp b/contrib/libs/llvm12/lib/Analysis/LoopAnalysisManager.cpp
index 69a3c8bba9..4ad5641da1 100644
--- a/contrib/libs/llvm12/lib/Analysis/LoopAnalysisManager.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/LoopAnalysisManager.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/LoopAnalysisManager.h"
-#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/LoopInfo.h"
diff --git a/contrib/libs/llvm12/lib/Analysis/LoopCacheAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/LoopCacheAnalysis.cpp
index a08eb3fbe9..cf68596bfb 100644
--- a/contrib/libs/llvm12/lib/Analysis/LoopCacheAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/LoopCacheAnalysis.cpp
@@ -29,11 +29,11 @@
#include "llvm/ADT/BreadthFirstIterator.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/DependenceAnalysis.h"
-#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/DependenceAnalysis.h"
+#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -149,7 +149,7 @@ IndexedReference::IndexedReference(Instruction &StoreOrLoadInst,
Optional<bool> IndexedReference::hasSpacialReuse(const IndexedReference &Other,
unsigned CLS,
- AAResults &AA) const {
+ AAResults &AA) const {
assert(IsValid && "Expecting a valid reference");
if (BasePointer != Other.getBasePointer() && !isAliased(Other, AA)) {
@@ -206,7 +206,7 @@ Optional<bool> IndexedReference::hasTemporalReuse(const IndexedReference &Other,
unsigned MaxDistance,
const Loop &L,
DependenceInfo &DI,
- AAResults &AA) const {
+ AAResults &AA) const {
assert(IsValid && "Expecting a valid reference");
if (BasePointer != Other.getBasePointer() && !isAliased(Other, AA)) {
@@ -461,7 +461,7 @@ bool IndexedReference::isSimpleAddRecurrence(const SCEV &Subscript,
}
bool IndexedReference::isAliased(const IndexedReference &Other,
- AAResults &AA) const {
+ AAResults &AA) const {
const auto &Loc1 = MemoryLocation::get(&StoreOrLoadInst);
const auto &Loc2 = MemoryLocation::get(&Other.StoreOrLoadInst);
return AA.isMustAlias(Loc1, Loc2);
@@ -480,7 +480,7 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const CacheCost &CC) {
CacheCost::CacheCost(const LoopVectorTy &Loops, const LoopInfo &LI,
ScalarEvolution &SE, TargetTransformInfo &TTI,
- AAResults &AA, DependenceInfo &DI,
+ AAResults &AA, DependenceInfo &DI,
Optional<unsigned> TRT)
: Loops(Loops), TripCounts(), LoopCosts(),
TRT((TRT == None) ? Optional<unsigned>(TemporalReuseThreshold) : TRT),
@@ -499,13 +499,13 @@ CacheCost::CacheCost(const LoopVectorTy &Loops, const LoopInfo &LI,
std::unique_ptr<CacheCost>
CacheCost::getCacheCost(Loop &Root, LoopStandardAnalysisResults &AR,
DependenceInfo &DI, Optional<unsigned> TRT) {
- if (!Root.isOutermost()) {
+ if (!Root.isOutermost()) {
LLVM_DEBUG(dbgs() << "Expecting the outermost loop in a loop nest\n");
return nullptr;
}
LoopVectorTy Loops;
- append_range(Loops, breadth_first(&Root));
+ append_range(Loops, breadth_first(&Root));
if (!getInnerMostLoop(Loops)) {
LLVM_DEBUG(dbgs() << "Cannot compute cache cost of loop nest with more "
diff --git a/contrib/libs/llvm12/lib/Analysis/LoopInfo.cpp b/contrib/libs/llvm12/lib/Analysis/LoopInfo.cpp
index c0b43316d4..a85869b163 100644
--- a/contrib/libs/llvm12/lib/Analysis/LoopInfo.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/LoopInfo.cpp
@@ -34,7 +34,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/PassManager.h"
-#include "llvm/IR/PrintPasses.h"
+#include "llvm/IR/PrintPasses.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -432,10 +432,10 @@ static bool isBlockInLCSSAForm(const Loop &L, const BasicBlock &BB,
for (const Use &U : I.uses()) {
const Instruction *UI = cast<Instruction>(U.getUser());
const BasicBlock *UserBB = UI->getParent();
-
- // For practical purposes, we consider that the use in a PHI
- // occurs in the respective predecessor block. For more info,
- // see the `phi` doc in LangRef and the LCSSA doc.
+
+ // For practical purposes, we consider that the use in a PHI
+ // occurs in the respective predecessor block. For more info,
+ // see the `phi` doc in LangRef and the LCSSA doc.
if (const PHINode *P = dyn_cast<PHINode>(UI))
UserBB = P->getIncomingBlock(U);
@@ -540,22 +540,22 @@ void Loop::setLoopAlreadyUnrolled() {
setLoopID(NewLoopID);
}
-void Loop::setLoopMustProgress() {
- LLVMContext &Context = getHeader()->getContext();
-
- MDNode *MustProgress = findOptionMDForLoop(this, "llvm.loop.mustprogress");
-
- if (MustProgress)
- return;
-
- MDNode *MustProgressMD =
- MDNode::get(Context, MDString::get(Context, "llvm.loop.mustprogress"));
- MDNode *LoopID = getLoopID();
- MDNode *NewLoopID =
- makePostTransformationMetadata(Context, LoopID, {}, {MustProgressMD});
- setLoopID(NewLoopID);
-}
-
+void Loop::setLoopMustProgress() {
+ LLVMContext &Context = getHeader()->getContext();
+
+ MDNode *MustProgress = findOptionMDForLoop(this, "llvm.loop.mustprogress");
+
+ if (MustProgress)
+ return;
+
+ MDNode *MustProgressMD =
+ MDNode::get(Context, MDString::get(Context, "llvm.loop.mustprogress"));
+ MDNode *LoopID = getLoopID();
+ MDNode *NewLoopID =
+ makePostTransformationMetadata(Context, LoopID, {}, {MustProgressMD});
+ setLoopID(NewLoopID);
+}
+
bool Loop::isAnnotatedParallel() const {
MDNode *DesiredLoopIdMetadata = getLoopID();
@@ -567,7 +567,7 @@ bool Loop::isAnnotatedParallel() const {
SmallPtrSet<MDNode *, 4>
ParallelAccessGroups; // For scalable 'contains' check.
if (ParallelAccesses) {
- for (const MDOperand &MD : drop_begin(ParallelAccesses->operands())) {
+ for (const MDOperand &MD : drop_begin(ParallelAccesses->operands())) {
MDNode *AccGroup = cast<MDNode>(MD.get());
assert(isValidAsAccessGroup(AccGroup) &&
"List item must be an access group");
@@ -785,7 +785,7 @@ void UnloopUpdater::removeBlocksFromAncestors() {
/// Update the parent loop for all subloops directly nested within unloop.
void UnloopUpdater::updateSubloopParents() {
- while (!Unloop.isInnermost()) {
+ while (!Unloop.isInnermost()) {
Loop *Subloop = *std::prev(Unloop.end());
Unloop.removeChildLoop(std::prev(Unloop.end()));
@@ -883,7 +883,7 @@ void LoopInfo::erase(Loop *Unloop) {
auto InvalidateOnExit = make_scope_exit([&]() { destroy(Unloop); });
// First handle the special case of no parent loop to simplify the algorithm.
- if (Unloop->isOutermost()) {
+ if (Unloop->isOutermost()) {
// Since BBLoop had no parent, Unloop blocks are no longer in a loop.
for (Loop::block_iterator I = Unloop->block_begin(),
E = Unloop->block_end();
@@ -908,7 +908,7 @@ void LoopInfo::erase(Loop *Unloop) {
}
// Move all of the subloops to the top-level.
- while (!Unloop->isInnermost())
+ while (!Unloop->isInnermost())
addTopLevelLoop(Unloop->removeChildLoop(std::prev(Unloop->end())));
return;
@@ -1038,7 +1038,7 @@ MDNode *llvm::makePostTransformationMetadata(LLVMContext &Context,
SmallVector<Metadata *, 4> MDs;
// Reserve first location for self reference to the LoopID metadata node.
- MDs.push_back(nullptr);
+ MDs.push_back(nullptr);
// Remove metadata for the transformation that has been applied or that became
// outdated.
diff --git a/contrib/libs/llvm12/lib/Analysis/LoopNestAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/LoopNestAnalysis.cpp
index 9746a415bf..7133abcc35 100644
--- a/contrib/libs/llvm12/lib/Analysis/LoopNestAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/LoopNestAnalysis.cpp
@@ -42,7 +42,7 @@ static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop,
LoopNest::LoopNest(Loop &Root, ScalarEvolution &SE)
: MaxPerfectDepth(getMaxPerfectDepth(Root, SE)) {
- append_range(Loops, breadth_first(&Root));
+ append_range(Loops, breadth_first(&Root));
}
std::unique_ptr<LoopNest> LoopNest::getLoopNest(Loop &Root,
@@ -52,8 +52,8 @@ std::unique_ptr<LoopNest> LoopNest::getLoopNest(Loop &Root,
bool LoopNest::arePerfectlyNested(const Loop &OuterLoop, const Loop &InnerLoop,
ScalarEvolution &SE) {
- assert(!OuterLoop.isInnermost() && "Outer loop should have subloops");
- assert(!InnerLoop.isOutermost() && "Inner loop should have a parent");
+ assert(!OuterLoop.isInnermost() && "Outer loop should have subloops");
+ assert(!InnerLoop.isOutermost() && "Inner loop should have a parent");
LLVM_DEBUG(dbgs() << "Checking whether loop '" << OuterLoop.getName()
<< "' and '" << InnerLoop.getName()
<< "' are perfectly nested.\n");
@@ -205,31 +205,31 @@ unsigned LoopNest::getMaxPerfectDepth(const Loop &Root, ScalarEvolution &SE) {
return CurrentDepth;
}
-const BasicBlock &LoopNest::skipEmptyBlockUntil(const BasicBlock *From,
- const BasicBlock *End) {
- assert(From && "Expecting valid From");
- assert(End && "Expecting valid End");
-
- if (From == End || !From->getSingleSuccessor())
- return *From;
-
- auto IsEmpty = [](const BasicBlock *BB) {
- return (BB->getInstList().size() == 1);
- };
-
- // Visited is used to avoid running into an infinite loop.
- SmallPtrSet<const BasicBlock *, 4> Visited;
- const BasicBlock *BB = From->getSingleSuccessor();
- const BasicBlock *PredBB = BB;
- while (BB && BB != End && IsEmpty(BB) && !Visited.count(BB)) {
- Visited.insert(BB);
- PredBB = BB;
- BB = BB->getSingleSuccessor();
- }
-
- return (BB == End) ? *End : *PredBB;
-}
-
+const BasicBlock &LoopNest::skipEmptyBlockUntil(const BasicBlock *From,
+ const BasicBlock *End) {
+ assert(From && "Expecting valid From");
+ assert(End && "Expecting valid End");
+
+ if (From == End || !From->getSingleSuccessor())
+ return *From;
+
+ auto IsEmpty = [](const BasicBlock *BB) {
+ return (BB->getInstList().size() == 1);
+ };
+
+ // Visited is used to avoid running into an infinite loop.
+ SmallPtrSet<const BasicBlock *, 4> Visited;
+ const BasicBlock *BB = From->getSingleSuccessor();
+ const BasicBlock *PredBB = BB;
+ while (BB && BB != End && IsEmpty(BB) && !Visited.count(BB)) {
+ Visited.insert(BB);
+ PredBB = BB;
+ BB = BB->getSingleSuccessor();
+ }
+
+ return (BB == End) ? *End : *PredBB;
+}
+
static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop,
ScalarEvolution &SE) {
// The inner loop must be the only outer loop's child.
@@ -252,92 +252,92 @@ static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop,
InnerLoop.getExitingBlock() != InnerLoopLatch || !InnerLoopExit)
return false;
- // Returns whether the block `ExitBlock` contains at least one LCSSA Phi node.
- auto ContainsLCSSAPhi = [](const BasicBlock &ExitBlock) {
- return any_of(ExitBlock.phis(), [](const PHINode &PN) {
- return PN.getNumIncomingValues() == 1;
- });
- };
-
- // Returns whether the block `BB` qualifies for being an extra Phi block. The
- // extra Phi block is the additional block inserted after the exit block of an
- // "guarded" inner loop which contains "only" Phi nodes corresponding to the
- // LCSSA Phi nodes in the exit block.
- auto IsExtraPhiBlock = [&](const BasicBlock &BB) {
- return BB.getFirstNonPHI() == BB.getTerminator() &&
- all_of(BB.phis(), [&](const PHINode &PN) {
- return all_of(PN.blocks(), [&](const BasicBlock *IncomingBlock) {
- return IncomingBlock == InnerLoopExit ||
- IncomingBlock == OuterLoopHeader;
- });
- });
- };
-
- const BasicBlock *ExtraPhiBlock = nullptr;
+ // Returns whether the block `ExitBlock` contains at least one LCSSA Phi node.
+ auto ContainsLCSSAPhi = [](const BasicBlock &ExitBlock) {
+ return any_of(ExitBlock.phis(), [](const PHINode &PN) {
+ return PN.getNumIncomingValues() == 1;
+ });
+ };
+
+ // Returns whether the block `BB` qualifies for being an extra Phi block. The
+ // extra Phi block is the additional block inserted after the exit block of an
+ // "guarded" inner loop which contains "only" Phi nodes corresponding to the
+ // LCSSA Phi nodes in the exit block.
+ auto IsExtraPhiBlock = [&](const BasicBlock &BB) {
+ return BB.getFirstNonPHI() == BB.getTerminator() &&
+ all_of(BB.phis(), [&](const PHINode &PN) {
+ return all_of(PN.blocks(), [&](const BasicBlock *IncomingBlock) {
+ return IncomingBlock == InnerLoopExit ||
+ IncomingBlock == OuterLoopHeader;
+ });
+ });
+ };
+
+ const BasicBlock *ExtraPhiBlock = nullptr;
// Ensure the only branch that may exist between the loops is the inner loop
// guard.
if (OuterLoopHeader != InnerLoopPreHeader) {
- const BasicBlock &SingleSucc =
- LoopNest::skipEmptyBlockUntil(OuterLoopHeader, InnerLoopPreHeader);
-
- // no conditional branch present
- if (&SingleSucc != InnerLoopPreHeader) {
- const BranchInst *BI = dyn_cast<BranchInst>(SingleSucc.getTerminator());
-
- if (!BI || BI != InnerLoop.getLoopGuardBranch())
- return false;
-
- bool InnerLoopExitContainsLCSSA = ContainsLCSSAPhi(*InnerLoopExit);
-
- // The successors of the inner loop guard should be the inner loop
- // preheader or the outer loop latch possibly through empty blocks.
- for (const BasicBlock *Succ : BI->successors()) {
- const BasicBlock *PotentialInnerPreHeader = Succ;
- const BasicBlock *PotentialOuterLatch = Succ;
-
- // Ensure the inner loop guard successor is empty before skipping
- // blocks.
- if (Succ->getInstList().size() == 1) {
- PotentialInnerPreHeader =
- &LoopNest::skipEmptyBlockUntil(Succ, InnerLoopPreHeader);
- PotentialOuterLatch =
- &LoopNest::skipEmptyBlockUntil(Succ, OuterLoopLatch);
- }
-
- if (PotentialInnerPreHeader == InnerLoopPreHeader)
- continue;
- if (PotentialOuterLatch == OuterLoopLatch)
- continue;
-
- // If `InnerLoopExit` contains LCSSA Phi instructions, additional block
- // may be inserted before the `OuterLoopLatch` to which `BI` jumps. The
- // loops are still considered perfectly nested if the extra block only
- // contains Phi instructions from InnerLoopExit and OuterLoopHeader.
- if (InnerLoopExitContainsLCSSA && IsExtraPhiBlock(*Succ) &&
- Succ->getSingleSuccessor() == OuterLoopLatch) {
- // Points to the extra block so that we can reference it later in the
- // final check. We can also conclude that the inner loop is
- // guarded and there exists LCSSA Phi node in the exit block later if
- // we see a non-null `ExtraPhiBlock`.
- ExtraPhiBlock = Succ;
- continue;
- }
-
- DEBUG_WITH_TYPE(VerboseDebug, {
- dbgs() << "Inner loop guard successor " << Succ->getName()
- << " doesn't lead to inner loop preheader or "
- "outer loop latch.\n";
- });
- return false;
- }
+ const BasicBlock &SingleSucc =
+ LoopNest::skipEmptyBlockUntil(OuterLoopHeader, InnerLoopPreHeader);
+
+ // no conditional branch present
+ if (&SingleSucc != InnerLoopPreHeader) {
+ const BranchInst *BI = dyn_cast<BranchInst>(SingleSucc.getTerminator());
+
+ if (!BI || BI != InnerLoop.getLoopGuardBranch())
+ return false;
+
+ bool InnerLoopExitContainsLCSSA = ContainsLCSSAPhi(*InnerLoopExit);
+
+ // The successors of the inner loop guard should be the inner loop
+ // preheader or the outer loop latch possibly through empty blocks.
+ for (const BasicBlock *Succ : BI->successors()) {
+ const BasicBlock *PotentialInnerPreHeader = Succ;
+ const BasicBlock *PotentialOuterLatch = Succ;
+
+ // Ensure the inner loop guard successor is empty before skipping
+ // blocks.
+ if (Succ->getInstList().size() == 1) {
+ PotentialInnerPreHeader =
+ &LoopNest::skipEmptyBlockUntil(Succ, InnerLoopPreHeader);
+ PotentialOuterLatch =
+ &LoopNest::skipEmptyBlockUntil(Succ, OuterLoopLatch);
+ }
+
+ if (PotentialInnerPreHeader == InnerLoopPreHeader)
+ continue;
+ if (PotentialOuterLatch == OuterLoopLatch)
+ continue;
+
+ // If `InnerLoopExit` contains LCSSA Phi instructions, additional block
+ // may be inserted before the `OuterLoopLatch` to which `BI` jumps. The
+ // loops are still considered perfectly nested if the extra block only
+ // contains Phi instructions from InnerLoopExit and OuterLoopHeader.
+ if (InnerLoopExitContainsLCSSA && IsExtraPhiBlock(*Succ) &&
+ Succ->getSingleSuccessor() == OuterLoopLatch) {
+ // Points to the extra block so that we can reference it later in the
+ // final check. We can also conclude that the inner loop is
+ // guarded and there exists LCSSA Phi node in the exit block later if
+ // we see a non-null `ExtraPhiBlock`.
+ ExtraPhiBlock = Succ;
+ continue;
+ }
+
+ DEBUG_WITH_TYPE(VerboseDebug, {
+ dbgs() << "Inner loop guard successor " << Succ->getName()
+ << " doesn't lead to inner loop preheader or "
+ "outer loop latch.\n";
+ });
+ return false;
+ }
}
}
- // Ensure the inner loop exit block lead to the outer loop latch possibly
- // through empty blocks.
- const BasicBlock &SuccInner =
- LoopNest::skipEmptyBlockUntil(InnerLoop.getExitBlock(), OuterLoopLatch);
- if (&SuccInner != OuterLoopLatch && &SuccInner != ExtraPhiBlock) {
+ // Ensure the inner loop exit block lead to the outer loop latch possibly
+ // through empty blocks.
+ const BasicBlock &SuccInner =
+ LoopNest::skipEmptyBlockUntil(InnerLoop.getExitBlock(), OuterLoopLatch);
+ if (&SuccInner != OuterLoopLatch && &SuccInner != ExtraPhiBlock) {
DEBUG_WITH_TYPE(
VerboseDebug,
dbgs() << "Inner loop exit block " << *InnerLoopExit
@@ -348,8 +348,8 @@ static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop,
return true;
}
-AnalysisKey LoopNestAnalysis::Key;
-
+AnalysisKey LoopNestAnalysis::Key;
+
raw_ostream &llvm::operator<<(raw_ostream &OS, const LoopNest &LN) {
OS << "IsPerfect=";
if (LN.getMaxPerfectDepth() == LN.getNestDepth())
diff --git a/contrib/libs/llvm12/lib/Analysis/LoopPass.cpp b/contrib/libs/llvm12/lib/Analysis/LoopPass.cpp
index e7e7a4dd52..9e470e998e 100644
--- a/contrib/libs/llvm12/lib/Analysis/LoopPass.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/LoopPass.cpp
@@ -19,8 +19,8 @@
#include "llvm/IR/OptBisect.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/PassTimingInfo.h"
-#include "llvm/IR/PrintPasses.h"
-#include "llvm/IR/StructuralHash.h"
+#include "llvm/IR/PrintPasses.h"
+#include "llvm/IR/StructuralHash.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/TimeProfiler.h"
@@ -77,7 +77,7 @@ LPPassManager::LPPassManager()
// Insert loop into loop nest (LoopInfo) and loop queue (LQ).
void LPPassManager::addLoop(Loop &L) {
- if (L.isOutermost()) {
+ if (L.isOutermost()) {
// This is the top level loop.
LQ.push_front(&L);
return;
@@ -117,7 +117,7 @@ void LPPassManager::markLoopAsDeleted(Loop &L) {
// there. However, we have to be careful to not remove the back of the queue
// as that is assumed to match the current loop.
assert(LQ.back() == CurrentLoop && "Loop queue back isn't the current loop!");
- llvm::erase_value(LQ, &L);
+ llvm::erase_value(LQ, &L);
if (&L == CurrentLoop) {
CurrentLoopDeleted = true;
@@ -192,19 +192,19 @@ bool LPPassManager::runOnFunction(Function &F) {
{
PassManagerPrettyStackEntry X(P, *CurrentLoop->getHeader());
TimeRegion PassTimer(getPassTimer(P));
-#ifdef EXPENSIVE_CHECKS
- uint64_t RefHash = StructuralHash(F);
-#endif
+#ifdef EXPENSIVE_CHECKS
+ uint64_t RefHash = StructuralHash(F);
+#endif
LocalChanged = P->runOnLoop(CurrentLoop, *this);
-
-#ifdef EXPENSIVE_CHECKS
- if (!LocalChanged && (RefHash != StructuralHash(F))) {
- llvm::errs() << "Pass modifies its input and doesn't report it: "
- << P->getPassName() << "\n";
- llvm_unreachable("Pass modifies its input and doesn't report it");
- }
-#endif
-
+
+#ifdef EXPENSIVE_CHECKS
+ if (!LocalChanged && (RefHash != StructuralHash(F))) {
+ llvm::errs() << "Pass modifies its input and doesn't report it: "
+ << P->getPassName() << "\n";
+ llvm_unreachable("Pass modifies its input and doesn't report it");
+ }
+#endif
+
Changed |= LocalChanged;
if (EmitICRemark) {
unsigned NewSize = F.getInstructionCount();
@@ -254,8 +254,8 @@ bool LPPassManager::runOnFunction(Function &F) {
F.getContext().yield();
}
- if (LocalChanged)
- removeNotPreservedAnalysis(P);
+ if (LocalChanged)
+ removeNotPreservedAnalysis(P);
recordAvailableAnalysis(P);
removeDeadPasses(P,
CurrentLoopDeleted ? "<deleted>"
diff --git a/contrib/libs/llvm12/lib/Analysis/MLInlineAdvisor.cpp b/contrib/libs/llvm12/lib/Analysis/MLInlineAdvisor.cpp
index d152a42069..89f4ff427d 100644
--- a/contrib/libs/llvm12/lib/Analysis/MLInlineAdvisor.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/MLInlineAdvisor.cpp
@@ -11,16 +11,16 @@
// 'release' mode) or a runtime-loaded model (the 'development' case).
//
//===----------------------------------------------------------------------===//
-#include "llvm/Config/config.h"
-#if defined(LLVM_HAVE_TF_AOT) || defined(LLVM_HAVE_TF_API)
-
+#include "llvm/Config/config.h"
+#if defined(LLVM_HAVE_TF_AOT) || defined(LLVM_HAVE_TF_API)
+
#include <limits>
#include <unordered_map>
#include <unordered_set>
#include "llvm/ADT/SCCIterator.h"
#include "llvm/Analysis/CallGraph.h"
-#include "llvm/Analysis/FunctionPropertiesAnalysis.h"
+#include "llvm/Analysis/FunctionPropertiesAnalysis.h"
#include "llvm/Analysis/InlineCost.h"
#include "llvm/Analysis/MLInlineAdvisor.h"
#include "llvm/Analysis/MLModelRunner.h"
@@ -66,8 +66,8 @@ CallBase *getInlinableCS(Instruction &I) {
MLInlineAdvisor::MLInlineAdvisor(Module &M, ModuleAnalysisManager &MAM,
std::unique_ptr<MLModelRunner> Runner)
: InlineAdvisor(
- M, MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager()),
- ModelRunner(std::move(Runner)), CG(new CallGraph(M)),
+ M, MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager()),
+ ModelRunner(std::move(Runner)), CG(new CallGraph(M)),
InitialIRSize(getModuleIRSize()), CurrentIRSize(InitialIRSize) {
assert(ModelRunner);
@@ -118,8 +118,8 @@ void MLInlineAdvisor::onPassEntry() {
}
int64_t MLInlineAdvisor::getLocalCalls(Function &F) {
- return FAM.getResult<FunctionPropertiesAnalysis>(F)
- .DirectCallsToDefinedFunctions;
+ return FAM.getResult<FunctionPropertiesAnalysis>(F)
+ .DirectCallsToDefinedFunctions;
}
// Update the internal state of the advisor, and force invalidate feature
@@ -134,7 +134,7 @@ void MLInlineAdvisor::onSuccessfulInlining(const MLInlineAdvice &Advice,
Function *Callee = Advice.getCallee();
// The caller features aren't valid anymore.
- FAM.invalidate<FunctionPropertiesAnalysis>(*Caller);
+ FAM.invalidate<FunctionPropertiesAnalysis>(*Caller);
int64_t IRSizeAfter =
getIRSize(*Caller) + (CalleeWasDeleted ? 0 : Advice.CalleeIRSize);
CurrentIRSize += IRSizeAfter - (Advice.CallerIRSize + Advice.CalleeIRSize);
@@ -147,15 +147,15 @@ void MLInlineAdvisor::onSuccessfulInlining(const MLInlineAdvice &Advice,
// For edges, we 'forget' the edges that the caller and callee used to have
// before inlining, and add back what they currently have together.
int64_t NewCallerAndCalleeEdges =
- FAM.getResult<FunctionPropertiesAnalysis>(*Caller)
+ FAM.getResult<FunctionPropertiesAnalysis>(*Caller)
.DirectCallsToDefinedFunctions;
if (CalleeWasDeleted)
--NodeCount;
else
- NewCallerAndCalleeEdges +=
- FAM.getResult<FunctionPropertiesAnalysis>(*Callee)
- .DirectCallsToDefinedFunctions;
+ NewCallerAndCalleeEdges +=
+ FAM.getResult<FunctionPropertiesAnalysis>(*Callee)
+ .DirectCallsToDefinedFunctions;
EdgeCount += (NewCallerAndCalleeEdges - Advice.CallerAndCalleeEdges);
assert(CurrentIRSize >= 0 && EdgeCount >= 0 && NodeCount >= 0);
}
@@ -168,7 +168,7 @@ int64_t MLInlineAdvisor::getModuleIRSize() const {
return Ret;
}
-std::unique_ptr<InlineAdvice> MLInlineAdvisor::getAdviceImpl(CallBase &CB) {
+std::unique_ptr<InlineAdvice> MLInlineAdvisor::getAdviceImpl(CallBase &CB) {
auto &Caller = *CB.getCaller();
auto &Callee = *CB.getCalledFunction();
@@ -178,17 +178,17 @@ std::unique_ptr<InlineAdvice> MLInlineAdvisor::getAdviceImpl(CallBase &CB) {
auto &TIR = FAM.getResult<TargetIRAnalysis>(Callee);
auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(Caller);
- auto MandatoryKind = InlineAdvisor::getMandatoryKind(CB, FAM, ORE);
+ auto MandatoryKind = InlineAdvisor::getMandatoryKind(CB, FAM, ORE);
// If this is a "never inline" case, there won't be any changes to internal
// state we need to track, so we can just return the base InlineAdvice, which
// will do nothing interesting.
// Same thing if this is a recursive case.
- if (MandatoryKind == InlineAdvisor::MandatoryInliningKind::Never ||
+ if (MandatoryKind == InlineAdvisor::MandatoryInliningKind::Never ||
&Caller == &Callee)
- return getMandatoryAdvice(CB, false);
+ return getMandatoryAdvice(CB, false);
- bool Mandatory =
- MandatoryKind == InlineAdvisor::MandatoryInliningKind::Always;
+ bool Mandatory =
+ MandatoryKind == InlineAdvisor::MandatoryInliningKind::Always;
// If we need to stop, we won't want to track anymore any state changes, so
// we just return the base InlineAdvice, which acts as a noop.
@@ -214,15 +214,15 @@ std::unique_ptr<InlineAdvice> MLInlineAdvisor::getAdviceImpl(CallBase &CB) {
}
if (Mandatory)
- return getMandatoryAdvice(CB, true);
+ return getMandatoryAdvice(CB, true);
auto NrCtantParams = 0;
for (auto I = CB.arg_begin(), E = CB.arg_end(); I != E; ++I) {
NrCtantParams += (isa<Constant>(*I));
}
- auto &CallerBefore = FAM.getResult<FunctionPropertiesAnalysis>(Caller);
- auto &CalleeBefore = FAM.getResult<FunctionPropertiesAnalysis>(Callee);
+ auto &CallerBefore = FAM.getResult<FunctionPropertiesAnalysis>(Caller);
+ auto &CalleeBefore = FAM.getResult<FunctionPropertiesAnalysis>(Callee);
ModelRunner->setFeature(FeatureIndex::CalleeBasicBlockCount,
CalleeBefore.BasicBlockCount);
@@ -249,22 +249,22 @@ MLInlineAdvisor::getAdviceFromModel(CallBase &CB,
return std::make_unique<MLInlineAdvice>(this, CB, ORE, ModelRunner->run());
}
-std::unique_ptr<InlineAdvice> MLInlineAdvisor::getMandatoryAdvice(CallBase &CB,
- bool Advice) {
- // Make sure we track inlinings in all cases - mandatory or not.
- if (Advice && !ForceStop)
- return getMandatoryAdviceImpl(CB);
-
- // If this is a "never inline" case, there won't be any changes to internal
- // state we need to track, so we can just return the base InlineAdvice, which
- // will do nothing interesting.
- // Same if we are forced to stop - we don't track anymore.
- return std::make_unique<InlineAdvice>(this, CB, getCallerORE(CB), Advice);
-}
-
+std::unique_ptr<InlineAdvice> MLInlineAdvisor::getMandatoryAdvice(CallBase &CB,
+ bool Advice) {
+ // Make sure we track inlinings in all cases - mandatory or not.
+ if (Advice && !ForceStop)
+ return getMandatoryAdviceImpl(CB);
+
+ // If this is a "never inline" case, there won't be any changes to internal
+ // state we need to track, so we can just return the base InlineAdvice, which
+ // will do nothing interesting.
+ // Same if we are forced to stop - we don't track anymore.
+ return std::make_unique<InlineAdvice>(this, CB, getCallerORE(CB), Advice);
+}
+
std::unique_ptr<MLInlineAdvice>
-MLInlineAdvisor::getMandatoryAdviceImpl(CallBase &CB) {
- return std::make_unique<MLInlineAdvice>(this, CB, getCallerORE(CB), true);
+MLInlineAdvisor::getMandatoryAdviceImpl(CallBase &CB) {
+ return std::make_unique<MLInlineAdvice>(this, CB, getCallerORE(CB), true);
}
void MLInlineAdvice::reportContextForRemark(
@@ -310,5 +310,5 @@ void MLInlineAdvice::recordUnattemptedInliningImpl() {
reportContextForRemark(R);
return R;
});
-}
-#endif // defined(LLVM_HAVE_TF_AOT) || defined(LLVM_HAVE_TF_API)
+}
+#endif // defined(LLVM_HAVE_TF_AOT) || defined(LLVM_HAVE_TF_API)
diff --git a/contrib/libs/llvm12/lib/Analysis/MemDepPrinter.cpp b/contrib/libs/llvm12/lib/Analysis/MemDepPrinter.cpp
index cd0965305d..0064234710 100644
--- a/contrib/libs/llvm12/lib/Analysis/MemDepPrinter.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/MemDepPrinter.cpp
@@ -14,7 +14,7 @@
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/IR/InstIterator.h"
-#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/ErrorHandling.h"
diff --git a/contrib/libs/llvm12/lib/Analysis/MemDerefPrinter.cpp b/contrib/libs/llvm12/lib/Analysis/MemDerefPrinter.cpp
index 0a92e558e2..0078ceacba 100644
--- a/contrib/libs/llvm12/lib/Analysis/MemDerefPrinter.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/MemDerefPrinter.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Analysis/MemDerefPrinter.h"
+#include "llvm/Analysis/MemDerefPrinter.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/IR/DataLayout.h"
@@ -18,7 +18,7 @@
#include "llvm/Pass.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-
+
using namespace llvm;
namespace {
@@ -78,35 +78,35 @@ void MemDerefPrinter::print(raw_ostream &OS, const Module *M) const {
OS << "\n\n";
}
}
-
-PreservedAnalyses MemDerefPrinterPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- OS << "Memory Dereferencibility of pointers in function '" << F.getName()
- << "'\n";
-
- SmallVector<Value *, 4> Deref;
- SmallPtrSet<Value *, 4> DerefAndAligned;
-
- const DataLayout &DL = F.getParent()->getDataLayout();
- for (auto &I : instructions(F)) {
- if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
- Value *PO = LI->getPointerOperand();
- if (isDereferenceablePointer(PO, LI->getType(), DL))
- Deref.push_back(PO);
- if (isDereferenceableAndAlignedPointer(
- PO, LI->getType(), MaybeAlign(LI->getAlignment()), DL))
- DerefAndAligned.insert(PO);
- }
- }
-
- OS << "The following are dereferenceable:\n";
- for (Value *V : Deref) {
- V->print(OS);
- if (DerefAndAligned.count(V))
- OS << "\t(aligned)";
- else
- OS << "\t(unaligned)";
- OS << "\n\n";
- }
- return PreservedAnalyses::all();
-}
+
+PreservedAnalyses MemDerefPrinterPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ OS << "Memory Dereferencibility of pointers in function '" << F.getName()
+ << "'\n";
+
+ SmallVector<Value *, 4> Deref;
+ SmallPtrSet<Value *, 4> DerefAndAligned;
+
+ const DataLayout &DL = F.getParent()->getDataLayout();
+ for (auto &I : instructions(F)) {
+ if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
+ Value *PO = LI->getPointerOperand();
+ if (isDereferenceablePointer(PO, LI->getType(), DL))
+ Deref.push_back(PO);
+ if (isDereferenceableAndAlignedPointer(
+ PO, LI->getType(), MaybeAlign(LI->getAlignment()), DL))
+ DerefAndAligned.insert(PO);
+ }
+ }
+
+ OS << "The following are dereferenceable:\n";
+ for (Value *V : Deref) {
+ V->print(OS);
+ if (DerefAndAligned.count(V))
+ OS << "\t(aligned)";
+ else
+ OS << "\t(unaligned)";
+ OS << "\n\n";
+ }
+ return PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Analysis/MemoryBuiltins.cpp b/contrib/libs/llvm12/lib/Analysis/MemoryBuiltins.cpp
index e07b3c41e6..5dda96a2ca 100644
--- a/contrib/libs/llvm12/lib/Analysis/MemoryBuiltins.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/MemoryBuiltins.cpp
@@ -72,7 +72,7 @@ struct AllocFnsTy {
// know which functions are nounwind, noalias, nocapture parameters, etc.
static const std::pair<LibFunc, AllocFnsTy> AllocationFnData[] = {
{LibFunc_malloc, {MallocLike, 1, 0, -1}},
- {LibFunc_vec_malloc, {MallocLike, 1, 0, -1}},
+ {LibFunc_vec_malloc, {MallocLike, 1, 0, -1}},
{LibFunc_valloc, {MallocLike, 1, 0, -1}},
{LibFunc_Znwj, {OpNewLike, 1, 0, -1}}, // new(unsigned int)
{LibFunc_ZnwjRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new(unsigned int, nothrow)
@@ -104,9 +104,9 @@ static const std::pair<LibFunc, AllocFnsTy> AllocationFnData[] = {
{LibFunc_msvc_new_array_longlong_nothrow, {MallocLike, 2, 0, -1}}, // new[](unsigned long long, nothrow)
{LibFunc_aligned_alloc, {AlignedAllocLike, 2, 1, -1}},
{LibFunc_calloc, {CallocLike, 2, 0, 1}},
- {LibFunc_vec_calloc, {CallocLike, 2, 0, 1}},
+ {LibFunc_vec_calloc, {CallocLike, 2, 0, 1}},
{LibFunc_realloc, {ReallocLike, 2, 1, -1}},
- {LibFunc_vec_realloc, {ReallocLike, 2, 1, -1}},
+ {LibFunc_vec_realloc, {ReallocLike, 2, 1, -1}},
{LibFunc_reallocf, {ReallocLike, 2, 1, -1}},
{LibFunc_strdup, {StrDupLike, 1, -1, -1}},
{LibFunc_strndup, {StrDupLike, 2, 1, -1}}
@@ -381,8 +381,8 @@ PointerType *llvm::getMallocType(const CallInst *CI,
unsigned NumOfBitCastUses = 0;
// Determine if CallInst has a bitcast use.
- for (const User *U : CI->users())
- if (const BitCastInst *BCI = dyn_cast<BitCastInst>(U)) {
+ for (const User *U : CI->users())
+ if (const BitCastInst *BCI = dyn_cast<BitCastInst>(U)) {
MallocType = cast<PointerType>(BCI->getDestTy());
NumOfBitCastUses++;
}
@@ -568,16 +568,16 @@ Value *llvm::lowerObjectSizeCall(IntrinsicInst *ObjectSize,
Value *UseZero =
Builder.CreateICmpULT(SizeOffsetPair.first, SizeOffsetPair.second);
ResultSize = Builder.CreateZExtOrTrunc(ResultSize, ResultType);
- Value *Ret = Builder.CreateSelect(
- UseZero, ConstantInt::get(ResultType, 0), ResultSize);
-
- // The non-constant size expression cannot evaluate to -1.
- if (!isa<Constant>(SizeOffsetPair.first) ||
- !isa<Constant>(SizeOffsetPair.second))
- Builder.CreateAssumption(
- Builder.CreateICmpNE(Ret, ConstantInt::get(ResultType, -1)));
-
- return Ret;
+ Value *Ret = Builder.CreateSelect(
+ UseZero, ConstantInt::get(ResultType, 0), ResultSize);
+
+ // The non-constant size expression cannot evaluate to -1.
+ if (!isa<Constant>(SizeOffsetPair.first) ||
+ !isa<Constant>(SizeOffsetPair.second))
+ Builder.CreateAssumption(
+ Builder.CreateICmpNE(Ret, ConstantInt::get(ResultType, -1)));
+
+ return Ret;
}
}
@@ -686,14 +686,14 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
}
SizeOffsetType ObjectSizeOffsetVisitor::visitArgument(Argument &A) {
- Type *MemoryTy = A.getPointeeInMemoryValueType();
+ Type *MemoryTy = A.getPointeeInMemoryValueType();
// No interprocedural analysis is done at the moment.
- if (!MemoryTy|| !MemoryTy->isSized()) {
+ if (!MemoryTy|| !MemoryTy->isSized()) {
++ObjectVisitorArgument;
return unknown();
}
-
- APInt Size(IntTyBits, DL.getTypeAllocSize(MemoryTy));
+
+ APInt Size(IntTyBits, DL.getTypeAllocSize(MemoryTy));
return std::make_pair(align(Size, A.getParamAlignment()), Zero);
}
diff --git a/contrib/libs/llvm12/lib/Analysis/MemoryDependenceAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/MemoryDependenceAnalysis.cpp
index 3c44207ba7..886b5bf4ac 100644
--- a/contrib/libs/llvm12/lib/Analysis/MemoryDependenceAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -148,7 +148,7 @@ static ModRefInfo GetLocation(const Instruction *Inst, MemoryLocation &Loc,
if (const CallInst *CI = isFreeCall(Inst, &TLI)) {
// calls to free() deallocate the entire structure
- Loc = MemoryLocation::getAfter(CI->getArgOperand(0));
+ Loc = MemoryLocation::getAfter(CI->getArgOperand(0));
return ModRefInfo::Mod;
}
@@ -166,12 +166,12 @@ static ModRefInfo GetLocation(const Instruction *Inst, MemoryLocation &Loc,
// These intrinsics don't really modify the memory, but returning Mod
// will allow them to be handled conservatively.
return ModRefInfo::Mod;
- case Intrinsic::masked_load:
- Loc = MemoryLocation::getForArgument(II, 0, TLI);
- return ModRefInfo::Ref;
- case Intrinsic::masked_store:
- Loc = MemoryLocation::getForArgument(II, 1, TLI);
- return ModRefInfo::Mod;
+ case Intrinsic::masked_load:
+ Loc = MemoryLocation::getForArgument(II, 0, TLI);
+ return ModRefInfo::Ref;
+ case Intrinsic::masked_store:
+ Loc = MemoryLocation::getForArgument(II, 1, TLI);
+ return ModRefInfo::Mod;
default:
break;
}
@@ -344,9 +344,9 @@ MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI,
// If we hit load/store with the same invariant.group metadata (and the
// same pointer operand) we can assume that value pointed by pointer
// operand didn't change.
- if ((isa<LoadInst>(U) ||
- (isa<StoreInst>(U) &&
- cast<StoreInst>(U)->getPointerOperand() == Ptr)) &&
+ if ((isa<LoadInst>(U) ||
+ (isa<StoreInst>(U) &&
+ cast<StoreInst>(U)->getPointerOperand() == Ptr)) &&
U->hasMetadata(LLVMContext::MD_invariant_group))
ClosestDependency = GetClosestDependency(ClosestDependency, U);
}
@@ -370,8 +370,8 @@ MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI,
MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt,
BasicBlock *BB, Instruction *QueryInst, unsigned *Limit) {
- // We can batch AA queries, because IR does not change during a MemDep query.
- BatchAAResults BatchAA(AA);
+ // We can batch AA queries, because IR does not change during a MemDep query.
+ BatchAAResults BatchAA(AA);
bool isInvariantLoad = false;
unsigned DefaultLimit = getDefaultBlockScanLimit();
@@ -450,32 +450,32 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
// If we reach a lifetime begin or end marker, then the query ends here
// because the value is undefined.
- Intrinsic::ID ID = II->getIntrinsicID();
- switch (ID) {
- case Intrinsic::lifetime_start: {
+ Intrinsic::ID ID = II->getIntrinsicID();
+ switch (ID) {
+ case Intrinsic::lifetime_start: {
// FIXME: This only considers queries directly on the invariant-tagged
// pointer, not on query pointers that are indexed off of them. It'd
// be nice to handle that at some point (the right approach is to use
// GetPointerBaseWithConstantOffset).
- MemoryLocation ArgLoc = MemoryLocation::getAfter(II->getArgOperand(1));
- if (BatchAA.isMustAlias(ArgLoc, MemLoc))
+ MemoryLocation ArgLoc = MemoryLocation::getAfter(II->getArgOperand(1));
+ if (BatchAA.isMustAlias(ArgLoc, MemLoc))
return MemDepResult::getDef(II);
continue;
}
- case Intrinsic::masked_load:
- case Intrinsic::masked_store: {
- MemoryLocation Loc;
- /*ModRefInfo MR =*/ GetLocation(II, Loc, TLI);
- AliasResult R = BatchAA.alias(Loc, MemLoc);
- if (R == NoAlias)
- continue;
- if (R == MustAlias)
- return MemDepResult::getDef(II);
- if (ID == Intrinsic::masked_load)
- continue;
- return MemDepResult::getClobber(II);
- }
- }
+ case Intrinsic::masked_load:
+ case Intrinsic::masked_store: {
+ MemoryLocation Loc;
+ /*ModRefInfo MR =*/ GetLocation(II, Loc, TLI);
+ AliasResult R = BatchAA.alias(Loc, MemLoc);
+ if (R == NoAlias)
+ continue;
+ if (R == MustAlias)
+ return MemDepResult::getDef(II);
+ if (ID == Intrinsic::masked_load)
+ continue;
+ return MemDepResult::getClobber(II);
+ }
+ }
}
// Values depend on loads if the pointers are must aliased. This means
@@ -512,7 +512,7 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
MemoryLocation LoadLoc = MemoryLocation::get(LI);
// If we found a pointer, check if it could be the same as our pointer.
- AliasResult R = BatchAA.alias(LoadLoc, MemLoc);
+ AliasResult R = BatchAA.alias(LoadLoc, MemLoc);
if (isLoad) {
if (R == NoAlias)
@@ -543,7 +543,7 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
continue;
// Stores don't alias loads from read-only memory.
- if (BatchAA.pointsToConstantMemory(LoadLoc))
+ if (BatchAA.pointsToConstantMemory(LoadLoc))
continue;
// Stores depend on may/must aliased loads.
@@ -574,7 +574,7 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
// If alias analysis can tell that this store is guaranteed to not modify
// the query pointer, ignore it. Use getModRefInfo to handle cases where
// the query pointer points to constant memory etc.
- if (!isModOrRefSet(BatchAA.getModRefInfo(SI, MemLoc)))
+ if (!isModOrRefSet(BatchAA.getModRefInfo(SI, MemLoc)))
continue;
// Ok, this store might clobber the query pointer. Check to see if it is
@@ -583,7 +583,7 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
MemoryLocation StoreLoc = MemoryLocation::get(SI);
// If we found a pointer, check if it could be the same as our pointer.
- AliasResult R = BatchAA.alias(StoreLoc, MemLoc);
+ AliasResult R = BatchAA.alias(StoreLoc, MemLoc);
if (R == NoAlias)
continue;
@@ -601,8 +601,8 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
// looking for a clobber in many cases; that's an alias property and is
// handled by BasicAA.
if (isa<AllocaInst>(Inst) || isNoAliasFn(Inst, &TLI)) {
- const Value *AccessPtr = getUnderlyingObject(MemLoc.Ptr);
- if (AccessPtr == Inst || BatchAA.isMustAlias(Inst, AccessPtr))
+ const Value *AccessPtr = getUnderlyingObject(MemLoc.Ptr);
+ if (AccessPtr == Inst || BatchAA.isMustAlias(Inst, AccessPtr))
return MemDepResult::getDef(Inst);
}
@@ -619,10 +619,10 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
continue;
// See if this instruction (e.g. a call or vaarg) mod/ref's the pointer.
- ModRefInfo MR = BatchAA.getModRefInfo(Inst, MemLoc);
+ ModRefInfo MR = BatchAA.getModRefInfo(Inst, MemLoc);
// If necessary, perform additional analysis.
if (isModAndRefSet(MR))
- // TODO: Support callCapturesBefore() on BatchAAResults.
+ // TODO: Support callCapturesBefore() on BatchAAResults.
MR = AA.callCapturesBefore(Inst, MemLoc, &DT);
switch (clearMust(MR)) {
case ModRefInfo::NoModRef:
@@ -754,7 +754,7 @@ MemoryDependenceResults::getNonLocalCallDependency(CallBase *QueryCall) {
} else {
// Seed DirtyBlocks with each of the preds of QueryInst's block.
BasicBlock *QueryBB = QueryCall->getParent();
- append_range(DirtyBlocks, PredCache.get(QueryBB));
+ append_range(DirtyBlocks, PredCache.get(QueryBB));
++NumUncacheNonLocal;
}
@@ -768,7 +768,7 @@ MemoryDependenceResults::getNonLocalCallDependency(CallBase *QueryCall) {
// Iterate while we still have blocks to update.
while (!DirtyBlocks.empty()) {
- BasicBlock *DirtyBB = DirtyBlocks.pop_back_val();
+ BasicBlock *DirtyBB = DirtyBlocks.pop_back_val();
// Already processed this block?
if (!Visited.insert(DirtyBB).second)
@@ -838,7 +838,7 @@ MemoryDependenceResults::getNonLocalCallDependency(CallBase *QueryCall) {
// If the block *is* completely transparent to the load, we need to check
// the predecessors of this block. Add them to our worklist.
- append_range(DirtyBlocks, PredCache.get(DirtyBB));
+ append_range(DirtyBlocks, PredCache.get(DirtyBB));
}
}
@@ -1015,7 +1015,7 @@ SortNonLocalDepInfoCache(MemoryDependenceResults::NonLocalDepInfo &Cache,
NonLocalDepEntry Val = Cache.back();
Cache.pop_back();
MemoryDependenceResults::NonLocalDepInfo::iterator Entry =
- llvm::upper_bound(Cache, Val);
+ llvm::upper_bound(Cache, Val);
Cache.insert(Entry, Val);
}
break;
diff --git a/contrib/libs/llvm12/lib/Analysis/MemoryLocation.cpp b/contrib/libs/llvm12/lib/Analysis/MemoryLocation.cpp
index bcd49d3f61..ef9cda37ce 100644
--- a/contrib/libs/llvm12/lib/Analysis/MemoryLocation.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/MemoryLocation.cpp
@@ -20,10 +20,10 @@ using namespace llvm;
void LocationSize::print(raw_ostream &OS) const {
OS << "LocationSize::";
- if (*this == beforeOrAfterPointer())
- OS << "beforeOrAfterPointer";
- else if (*this == afterPointer())
- OS << "afterPointer";
+ if (*this == beforeOrAfterPointer())
+ OS << "beforeOrAfterPointer";
+ else if (*this == afterPointer())
+ OS << "afterPointer";
else if (*this == mapEmpty())
OS << "mapEmpty";
else if (*this == mapTombstone())
@@ -59,8 +59,8 @@ MemoryLocation MemoryLocation::get(const VAArgInst *VI) {
AAMDNodes AATags;
VI->getAAMetadata(AATags);
- return MemoryLocation(VI->getPointerOperand(),
- LocationSize::afterPointer(), AATags);
+ return MemoryLocation(VI->getPointerOperand(),
+ LocationSize::afterPointer(), AATags);
}
MemoryLocation MemoryLocation::get(const AtomicCmpXchgInst *CXI) {
@@ -111,7 +111,7 @@ MemoryLocation MemoryLocation::getForSource(const AtomicMemTransferInst *MTI) {
}
MemoryLocation MemoryLocation::getForSource(const AnyMemTransferInst *MTI) {
- auto Size = LocationSize::afterPointer();
+ auto Size = LocationSize::afterPointer();
if (ConstantInt *C = dyn_cast<ConstantInt>(MTI->getLength()))
Size = LocationSize::precise(C->getValue().getZExtValue());
@@ -132,7 +132,7 @@ MemoryLocation MemoryLocation::getForDest(const AtomicMemIntrinsic *MI) {
}
MemoryLocation MemoryLocation::getForDest(const AnyMemIntrinsic *MI) {
- auto Size = LocationSize::afterPointer();
+ auto Size = LocationSize::afterPointer();
if (ConstantInt *C = dyn_cast<ConstantInt>(MI->getLength()))
Size = LocationSize::precise(C->getValue().getZExtValue());
@@ -160,14 +160,14 @@ MemoryLocation MemoryLocation::getForArgument(const CallBase *Call,
break;
case Intrinsic::memset:
case Intrinsic::memcpy:
- case Intrinsic::memcpy_inline:
+ case Intrinsic::memcpy_inline:
case Intrinsic::memmove:
assert((ArgIdx == 0 || ArgIdx == 1) &&
"Invalid argument index for memory intrinsic");
if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2)))
return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
AATags);
- return MemoryLocation::getAfter(Arg, AATags);
+ return MemoryLocation::getAfter(Arg, AATags);
case Intrinsic::lifetime_start:
case Intrinsic::lifetime_end:
@@ -179,21 +179,21 @@ MemoryLocation MemoryLocation::getForArgument(const CallBase *Call,
cast<ConstantInt>(II->getArgOperand(0))->getZExtValue()),
AATags);
- case Intrinsic::masked_load:
- assert(ArgIdx == 0 && "Invalid argument index");
- return MemoryLocation(
- Arg,
- LocationSize::upperBound(DL.getTypeStoreSize(II->getType())),
- AATags);
-
- case Intrinsic::masked_store:
- assert(ArgIdx == 1 && "Invalid argument index");
- return MemoryLocation(
- Arg,
- LocationSize::upperBound(
- DL.getTypeStoreSize(II->getArgOperand(0)->getType())),
- AATags);
-
+ case Intrinsic::masked_load:
+ assert(ArgIdx == 0 && "Invalid argument index");
+ return MemoryLocation(
+ Arg,
+ LocationSize::upperBound(DL.getTypeStoreSize(II->getType())),
+ AATags);
+
+ case Intrinsic::masked_store:
+ assert(ArgIdx == 1 && "Invalid argument index");
+ return MemoryLocation(
+ Arg,
+ LocationSize::upperBound(
+ DL.getTypeStoreSize(II->getArgOperand(0)->getType())),
+ AATags);
+
case Intrinsic::invariant_end:
// The first argument to an invariant.end is a "descriptor" type (e.g. a
// pointer to a empty struct) which is never actually dereferenced.
@@ -228,48 +228,48 @@ MemoryLocation MemoryLocation::getForArgument(const CallBase *Call,
// LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16
// whenever possible.
LibFunc F;
- if (TLI && TLI->getLibFunc(*Call, F) && TLI->has(F)) {
- switch (F) {
- case LibFunc_memset_pattern16:
- assert((ArgIdx == 0 || ArgIdx == 1) &&
- "Invalid argument index for memset_pattern16");
- if (ArgIdx == 1)
- return MemoryLocation(Arg, LocationSize::precise(16), AATags);
- if (const ConstantInt *LenCI =
- dyn_cast<ConstantInt>(Call->getArgOperand(2)))
- return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
- AATags);
- return MemoryLocation::getAfter(Arg, AATags);
- case LibFunc_bcmp:
- case LibFunc_memcmp:
- assert((ArgIdx == 0 || ArgIdx == 1) &&
- "Invalid argument index for memcmp/bcmp");
- if (const ConstantInt *LenCI =
- dyn_cast<ConstantInt>(Call->getArgOperand(2)))
- return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
- AATags);
- return MemoryLocation::getAfter(Arg, AATags);
- case LibFunc_memchr:
- assert((ArgIdx == 0) && "Invalid argument index for memchr");
- if (const ConstantInt *LenCI =
- dyn_cast<ConstantInt>(Call->getArgOperand(2)))
- return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
- AATags);
- return MemoryLocation::getAfter(Arg, AATags);
- case LibFunc_memccpy:
- assert((ArgIdx == 0 || ArgIdx == 1) &&
- "Invalid argument index for memccpy");
- // We only know an upper bound on the number of bytes read/written.
- if (const ConstantInt *LenCI =
- dyn_cast<ConstantInt>(Call->getArgOperand(3)))
- return MemoryLocation(
- Arg, LocationSize::upperBound(LenCI->getZExtValue()), AATags);
- return MemoryLocation::getAfter(Arg, AATags);
- default:
- break;
- };
+ if (TLI && TLI->getLibFunc(*Call, F) && TLI->has(F)) {
+ switch (F) {
+ case LibFunc_memset_pattern16:
+ assert((ArgIdx == 0 || ArgIdx == 1) &&
+ "Invalid argument index for memset_pattern16");
+ if (ArgIdx == 1)
+ return MemoryLocation(Arg, LocationSize::precise(16), AATags);
+ if (const ConstantInt *LenCI =
+ dyn_cast<ConstantInt>(Call->getArgOperand(2)))
+ return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
+ AATags);
+ return MemoryLocation::getAfter(Arg, AATags);
+ case LibFunc_bcmp:
+ case LibFunc_memcmp:
+ assert((ArgIdx == 0 || ArgIdx == 1) &&
+ "Invalid argument index for memcmp/bcmp");
+ if (const ConstantInt *LenCI =
+ dyn_cast<ConstantInt>(Call->getArgOperand(2)))
+ return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
+ AATags);
+ return MemoryLocation::getAfter(Arg, AATags);
+ case LibFunc_memchr:
+ assert((ArgIdx == 0) && "Invalid argument index for memchr");
+ if (const ConstantInt *LenCI =
+ dyn_cast<ConstantInt>(Call->getArgOperand(2)))
+ return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
+ AATags);
+ return MemoryLocation::getAfter(Arg, AATags);
+ case LibFunc_memccpy:
+ assert((ArgIdx == 0 || ArgIdx == 1) &&
+ "Invalid argument index for memccpy");
+ // We only know an upper bound on the number of bytes read/written.
+ if (const ConstantInt *LenCI =
+ dyn_cast<ConstantInt>(Call->getArgOperand(3)))
+ return MemoryLocation(
+ Arg, LocationSize::upperBound(LenCI->getZExtValue()), AATags);
+ return MemoryLocation::getAfter(Arg, AATags);
+ default:
+ break;
+ };
}
// FIXME: Handle memset_pattern4 and memset_pattern8 also.
- return MemoryLocation::getBeforeOrAfter(Call->getArgOperand(ArgIdx), AATags);
+ return MemoryLocation::getBeforeOrAfter(Call->getArgOperand(ArgIdx), AATags);
}
diff --git a/contrib/libs/llvm12/lib/Analysis/MemorySSA.cpp b/contrib/libs/llvm12/lib/Analysis/MemorySSA.cpp
index a5ce422acf..4722b68e20 100644
--- a/contrib/libs/llvm12/lib/Analysis/MemorySSA.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/MemorySSA.cpp
@@ -24,7 +24,7 @@
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/CFGPrinter.h"
+#include "llvm/Analysis/CFGPrinter.h"
#include "llvm/Analysis/IteratedDominanceFrontier.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Config/llvm-config.h"
@@ -60,11 +60,11 @@ using namespace llvm;
#define DEBUG_TYPE "memoryssa"
-static cl::opt<std::string>
- DotCFGMSSA("dot-cfg-mssa",
- cl::value_desc("file name for generated dot file"),
- cl::desc("file name for generated dot file"), cl::init(""));
-
+static cl::opt<std::string>
+ DotCFGMSSA("dot-cfg-mssa",
+ cl::value_desc("file name for generated dot file"),
+ cl::desc("file name for generated dot file"), cl::init(""));
+
INITIALIZE_PASS_BEGIN(MemorySSAWrapperPass, "memoryssa", "Memory SSA", false,
true)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
@@ -284,7 +284,7 @@ instructionClobbersQuery(const MemoryDef *MD, const MemoryLocation &UseLoc,
case Intrinsic::invariant_start:
case Intrinsic::invariant_end:
case Intrinsic::assume:
- case Intrinsic::experimental_noalias_scope_decl:
+ case Intrinsic::experimental_noalias_scope_decl:
return {false, NoAlias};
case Intrinsic::dbg_addr:
case Intrinsic::dbg_declare:
@@ -296,14 +296,14 @@ instructionClobbersQuery(const MemoryDef *MD, const MemoryLocation &UseLoc,
}
}
- if (auto *CB = dyn_cast_or_null<CallBase>(UseInst)) {
- ModRefInfo I = AA.getModRefInfo(DefInst, CB);
+ if (auto *CB = dyn_cast_or_null<CallBase>(UseInst)) {
+ ModRefInfo I = AA.getModRefInfo(DefInst, CB);
AR = isMustSet(I) ? MustAlias : MayAlias;
return {isModOrRefSet(I), AR};
}
if (auto *DefLoad = dyn_cast<LoadInst>(DefInst))
- if (auto *UseLoad = dyn_cast_or_null<LoadInst>(UseInst))
+ if (auto *UseLoad = dyn_cast_or_null<LoadInst>(UseInst))
return {!areLoadsReorderable(UseLoad, DefLoad), MayAlias};
ModRefInfo I = AA.getModRefInfo(DefInst, UseLoc);
@@ -362,10 +362,10 @@ static bool isUseTriviallyOptimizableToLiveOnEntry(AliasAnalysisType &AA,
const Instruction *I) {
// If the memory can't be changed, then loads of the memory can't be
// clobbered.
- if (auto *LI = dyn_cast<LoadInst>(I))
- return I->hasMetadata(LLVMContext::MD_invariant_load) ||
- AA.pointsToConstantMemory(MemoryLocation::get(LI));
- return false;
+ if (auto *LI = dyn_cast<LoadInst>(I))
+ return I->hasMetadata(LLVMContext::MD_invariant_load) ||
+ AA.pointsToConstantMemory(MemoryLocation::get(LI));
+ return false;
}
/// Verifies that `Start` is clobbered by `ClobberAt`, and that nothing
@@ -452,15 +452,15 @@ checkClobberSanity(const MemoryAccess *Start, MemoryAccess *ClobberAt,
}
assert(isa<MemoryPhi>(MA));
-
- // Add reachable phi predecessors
- for (auto ItB = upward_defs_begin(
- {const_cast<MemoryAccess *>(MA), MAP.second},
- MSSA.getDomTree()),
- ItE = upward_defs_end();
- ItB != ItE; ++ItB)
- if (MSSA.getDomTree().isReachableFromEntry(ItB.getPhiArgBlock()))
- Worklist.emplace_back(*ItB);
+
+ // Add reachable phi predecessors
+ for (auto ItB = upward_defs_begin(
+ {const_cast<MemoryAccess *>(MA), MAP.second},
+ MSSA.getDomTree()),
+ ItE = upward_defs_end();
+ ItB != ItE; ++ItB)
+ if (MSSA.getDomTree().isReachableFromEntry(ItB.getPhiArgBlock()))
+ Worklist.emplace_back(*ItB);
}
}
@@ -511,16 +511,16 @@ template <class AliasAnalysisType> class ClobberWalker {
UpwardsMemoryQuery *Query;
unsigned *UpwardWalkLimit;
- // Phi optimization bookkeeping:
- // List of DefPath to process during the current phi optimization walk.
+ // Phi optimization bookkeeping:
+ // List of DefPath to process during the current phi optimization walk.
SmallVector<DefPath, 32> Paths;
- // List of visited <Access, Location> pairs; we can skip paths already
- // visited with the same memory location.
+ // List of visited <Access, Location> pairs; we can skip paths already
+ // visited with the same memory location.
DenseSet<ConstMemoryAccessPair> VisitedPhis;
- // Record if phi translation has been performed during the current phi
- // optimization walk, as merging alias results after phi translation can
- // yield incorrect results. Context in PR46156.
- bool PerformedPhiTranslation = false;
+ // Record if phi translation has been performed during the current phi
+ // optimization walk, as merging alias results after phi translation can
+ // yield incorrect results. Context in PR46156.
+ bool PerformedPhiTranslation = false;
/// Find the nearest def or phi that `From` can legally be optimized to.
const MemoryAccess *getWalkTarget(const MemoryPhi *From) const {
@@ -595,9 +595,9 @@ template <class AliasAnalysisType> class ClobberWalker {
void addSearches(MemoryPhi *Phi, SmallVectorImpl<ListIndex> &PausedSearches,
ListIndex PriorNode) {
- auto UpwardDefsBegin = upward_defs_begin({Phi, Paths[PriorNode].Loc}, DT,
- &PerformedPhiTranslation);
- auto UpwardDefs = make_range(UpwardDefsBegin, upward_defs_end());
+ auto UpwardDefsBegin = upward_defs_begin({Phi, Paths[PriorNode].Loc}, DT,
+ &PerformedPhiTranslation);
+ auto UpwardDefs = make_range(UpwardDefsBegin, upward_defs_end());
for (const MemoryAccessPair &P : UpwardDefs) {
PausedSearches.push_back(Paths.size());
Paths.emplace_back(P.second, P.first, PriorNode);
@@ -651,16 +651,16 @@ template <class AliasAnalysisType> class ClobberWalker {
// - We still cache things for A, so C only needs to walk up a bit.
// If this behavior becomes problematic, we can fix without a ton of extra
// work.
- if (!VisitedPhis.insert({Node.Last, Node.Loc}).second) {
- if (PerformedPhiTranslation) {
- // If visiting this path performed Phi translation, don't continue,
- // since it may not be correct to merge results from two paths if one
- // relies on the phi translation.
- TerminatedPath Term{Node.Last, PathIndex};
- return Term;
- }
+ if (!VisitedPhis.insert({Node.Last, Node.Loc}).second) {
+ if (PerformedPhiTranslation) {
+ // If visiting this path performed Phi translation, don't continue,
+ // since it may not be correct to merge results from two paths if one
+ // relies on the phi translation.
+ TerminatedPath Term{Node.Last, PathIndex};
+ return Term;
+ }
continue;
- }
+ }
const MemoryAccess *SkipStopWhere = nullptr;
if (Query->SkipSelfAccess && Node.Loc == Query->StartingLoc) {
@@ -773,7 +773,7 @@ template <class AliasAnalysisType> class ClobberWalker {
/// terminates when a MemoryAccess that clobbers said MemoryLocation is found.
OptznResult tryOptimizePhi(MemoryPhi *Phi, MemoryAccess *Start,
const MemoryLocation &Loc) {
- assert(Paths.empty() && VisitedPhis.empty() && !PerformedPhiTranslation &&
+ assert(Paths.empty() && VisitedPhis.empty() && !PerformedPhiTranslation &&
"Reset the optimization state.");
Paths.emplace_back(Loc, Start, Phi, None);
@@ -929,7 +929,7 @@ template <class AliasAnalysisType> class ClobberWalker {
void resetPhiOptznState() {
Paths.clear();
VisitedPhis.clear();
- PerformedPhiTranslation = false;
+ PerformedPhiTranslation = false;
}
public:
@@ -1709,11 +1709,11 @@ MemoryUseOrDef *MemorySSA::createDefinedAccess(Instruction *I,
if (CreationMustSucceed)
assert(NewAccess != nullptr && "Tried to create a memory access for a "
"non-memory touching instruction");
- if (NewAccess) {
- assert((!Definition || !isa<MemoryUse>(Definition)) &&
- "A use cannot be a defining access");
+ if (NewAccess) {
+ assert((!Definition || !isa<MemoryUse>(Definition)) &&
+ "A use cannot be a defining access");
NewAccess->setDefiningAccess(Definition);
- }
+ }
return NewAccess;
}
@@ -1742,15 +1742,15 @@ MemoryUseOrDef *MemorySSA::createNewAccess(Instruction *I,
// dependencies here.
// FIXME: Replace this special casing with a more accurate modelling of
// assume's control dependency.
- if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
- switch (II->getIntrinsicID()) {
- default:
- break;
- case Intrinsic::assume:
- case Intrinsic::experimental_noalias_scope_decl:
+ if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
+ switch (II->getIntrinsicID()) {
+ default:
+ break;
+ case Intrinsic::assume:
+ case Intrinsic::experimental_noalias_scope_decl:
return nullptr;
- }
- }
+ }
+ }
// Using a nonstandard AA pipelines might leave us with unexpected modref
// results for I, so add a check to not model instructions that may not read
@@ -1760,8 +1760,8 @@ MemoryUseOrDef *MemorySSA::createNewAccess(Instruction *I,
bool Def, Use;
if (Template) {
- Def = isa<MemoryDef>(Template);
- Use = isa<MemoryUse>(Template);
+ Def = isa<MemoryDef>(Template);
+ Use = isa<MemoryUse>(Template);
#if !defined(NDEBUG)
ModRefInfo ModRef = AAP->getModRefInfo(I, None);
bool DefCheck, UseCheck;
@@ -1981,7 +1981,7 @@ void MemorySSA::verifyOrderingDominationAndDefUses(Function &F) const {
"Incomplete MemoryPhi Node");
for (unsigned I = 0, E = Phi->getNumIncomingValues(); I != E; ++I) {
verifyUseInDefs(Phi->getIncomingValue(I), Phi);
- assert(is_contained(predecessors(&B), Phi->getIncomingBlock(I)) &&
+ assert(is_contained(predecessors(&B), Phi->getIncomingBlock(I)) &&
"Incoming phi block not a block predecessor");
}
#endif
@@ -2228,98 +2228,98 @@ void MemorySSAPrinterLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<MemorySSAWrapperPass>();
}
-class DOTFuncMSSAInfo {
-private:
- const Function &F;
- MemorySSAAnnotatedWriter MSSAWriter;
-
-public:
- DOTFuncMSSAInfo(const Function &F, MemorySSA &MSSA)
- : F(F), MSSAWriter(&MSSA) {}
-
- const Function *getFunction() { return &F; }
- MemorySSAAnnotatedWriter &getWriter() { return MSSAWriter; }
-};
-
-namespace llvm {
-
-template <>
-struct GraphTraits<DOTFuncMSSAInfo *> : public GraphTraits<const BasicBlock *> {
- static NodeRef getEntryNode(DOTFuncMSSAInfo *CFGInfo) {
- return &(CFGInfo->getFunction()->getEntryBlock());
- }
-
- // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
- using nodes_iterator = pointer_iterator<Function::const_iterator>;
-
- static nodes_iterator nodes_begin(DOTFuncMSSAInfo *CFGInfo) {
- return nodes_iterator(CFGInfo->getFunction()->begin());
- }
-
- static nodes_iterator nodes_end(DOTFuncMSSAInfo *CFGInfo) {
- return nodes_iterator(CFGInfo->getFunction()->end());
- }
-
- static size_t size(DOTFuncMSSAInfo *CFGInfo) {
- return CFGInfo->getFunction()->size();
- }
-};
-
-template <>
-struct DOTGraphTraits<DOTFuncMSSAInfo *> : public DefaultDOTGraphTraits {
-
- DOTGraphTraits(bool IsSimple = false) : DefaultDOTGraphTraits(IsSimple) {}
-
- static std::string getGraphName(DOTFuncMSSAInfo *CFGInfo) {
- return "MSSA CFG for '" + CFGInfo->getFunction()->getName().str() +
- "' function";
- }
-
- std::string getNodeLabel(const BasicBlock *Node, DOTFuncMSSAInfo *CFGInfo) {
- return DOTGraphTraits<DOTFuncInfo *>::getCompleteNodeLabel(
- Node, nullptr,
- [CFGInfo](raw_string_ostream &OS, const BasicBlock &BB) -> void {
- BB.print(OS, &CFGInfo->getWriter(), true, true);
- },
- [](std::string &S, unsigned &I, unsigned Idx) -> void {
- std::string Str = S.substr(I, Idx - I);
- StringRef SR = Str;
- if (SR.count(" = MemoryDef(") || SR.count(" = MemoryPhi(") ||
- SR.count("MemoryUse("))
- return;
- DOTGraphTraits<DOTFuncInfo *>::eraseComment(S, I, Idx);
- });
- }
-
- static std::string getEdgeSourceLabel(const BasicBlock *Node,
- const_succ_iterator I) {
- return DOTGraphTraits<DOTFuncInfo *>::getEdgeSourceLabel(Node, I);
- }
-
- /// Display the raw branch weights from PGO.
- std::string getEdgeAttributes(const BasicBlock *Node, const_succ_iterator I,
- DOTFuncMSSAInfo *CFGInfo) {
- return "";
- }
-
- std::string getNodeAttributes(const BasicBlock *Node,
- DOTFuncMSSAInfo *CFGInfo) {
- return getNodeLabel(Node, CFGInfo).find(';') != std::string::npos
- ? "style=filled, fillcolor=lightpink"
- : "";
- }
-};
-
-} // namespace llvm
-
+class DOTFuncMSSAInfo {
+private:
+ const Function &F;
+ MemorySSAAnnotatedWriter MSSAWriter;
+
+public:
+ DOTFuncMSSAInfo(const Function &F, MemorySSA &MSSA)
+ : F(F), MSSAWriter(&MSSA) {}
+
+ const Function *getFunction() { return &F; }
+ MemorySSAAnnotatedWriter &getWriter() { return MSSAWriter; }
+};
+
+namespace llvm {
+
+template <>
+struct GraphTraits<DOTFuncMSSAInfo *> : public GraphTraits<const BasicBlock *> {
+ static NodeRef getEntryNode(DOTFuncMSSAInfo *CFGInfo) {
+ return &(CFGInfo->getFunction()->getEntryBlock());
+ }
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ using nodes_iterator = pointer_iterator<Function::const_iterator>;
+
+ static nodes_iterator nodes_begin(DOTFuncMSSAInfo *CFGInfo) {
+ return nodes_iterator(CFGInfo->getFunction()->begin());
+ }
+
+ static nodes_iterator nodes_end(DOTFuncMSSAInfo *CFGInfo) {
+ return nodes_iterator(CFGInfo->getFunction()->end());
+ }
+
+ static size_t size(DOTFuncMSSAInfo *CFGInfo) {
+ return CFGInfo->getFunction()->size();
+ }
+};
+
+template <>
+struct DOTGraphTraits<DOTFuncMSSAInfo *> : public DefaultDOTGraphTraits {
+
+ DOTGraphTraits(bool IsSimple = false) : DefaultDOTGraphTraits(IsSimple) {}
+
+ static std::string getGraphName(DOTFuncMSSAInfo *CFGInfo) {
+ return "MSSA CFG for '" + CFGInfo->getFunction()->getName().str() +
+ "' function";
+ }
+
+ std::string getNodeLabel(const BasicBlock *Node, DOTFuncMSSAInfo *CFGInfo) {
+ return DOTGraphTraits<DOTFuncInfo *>::getCompleteNodeLabel(
+ Node, nullptr,
+ [CFGInfo](raw_string_ostream &OS, const BasicBlock &BB) -> void {
+ BB.print(OS, &CFGInfo->getWriter(), true, true);
+ },
+ [](std::string &S, unsigned &I, unsigned Idx) -> void {
+ std::string Str = S.substr(I, Idx - I);
+ StringRef SR = Str;
+ if (SR.count(" = MemoryDef(") || SR.count(" = MemoryPhi(") ||
+ SR.count("MemoryUse("))
+ return;
+ DOTGraphTraits<DOTFuncInfo *>::eraseComment(S, I, Idx);
+ });
+ }
+
+ static std::string getEdgeSourceLabel(const BasicBlock *Node,
+ const_succ_iterator I) {
+ return DOTGraphTraits<DOTFuncInfo *>::getEdgeSourceLabel(Node, I);
+ }
+
+ /// Display the raw branch weights from PGO.
+ std::string getEdgeAttributes(const BasicBlock *Node, const_succ_iterator I,
+ DOTFuncMSSAInfo *CFGInfo) {
+ return "";
+ }
+
+ std::string getNodeAttributes(const BasicBlock *Node,
+ DOTFuncMSSAInfo *CFGInfo) {
+ return getNodeLabel(Node, CFGInfo).find(';') != std::string::npos
+ ? "style=filled, fillcolor=lightpink"
+ : "";
+ }
+};
+
+} // namespace llvm
+
bool MemorySSAPrinterLegacyPass::runOnFunction(Function &F) {
auto &MSSA = getAnalysis<MemorySSAWrapperPass>().getMSSA();
- if (DotCFGMSSA != "") {
- DOTFuncMSSAInfo CFGInfo(F, MSSA);
- WriteGraph(&CFGInfo, "", false, "MSSA", DotCFGMSSA);
- } else
- MSSA.print(dbgs());
-
+ if (DotCFGMSSA != "") {
+ DOTFuncMSSAInfo CFGInfo(F, MSSA);
+ WriteGraph(&CFGInfo, "", false, "MSSA", DotCFGMSSA);
+ } else
+ MSSA.print(dbgs());
+
if (VerifyMemorySSA)
MSSA.verifyMemorySSA();
return false;
@@ -2345,14 +2345,14 @@ bool MemorySSAAnalysis::Result::invalidate(
PreservedAnalyses MemorySSAPrinterPass::run(Function &F,
FunctionAnalysisManager &AM) {
- auto &MSSA = AM.getResult<MemorySSAAnalysis>(F).getMSSA();
- if (DotCFGMSSA != "") {
- DOTFuncMSSAInfo CFGInfo(F, MSSA);
- WriteGraph(&CFGInfo, "", false, "MSSA", DotCFGMSSA);
- } else {
- OS << "MemorySSA for function: " << F.getName() << "\n";
- MSSA.print(OS);
- }
+ auto &MSSA = AM.getResult<MemorySSAAnalysis>(F).getMSSA();
+ if (DotCFGMSSA != "") {
+ DOTFuncMSSAInfo CFGInfo(F, MSSA);
+ WriteGraph(&CFGInfo, "", false, "MSSA", DotCFGMSSA);
+ } else {
+ OS << "MemorySSA for function: " << F.getName() << "\n";
+ MSSA.print(OS);
+ }
return PreservedAnalyses::all();
}
@@ -2422,7 +2422,7 @@ MemorySSA::ClobberWalkerBase<AliasAnalysisType>::getClobberingMemoryAccessBase(
UpwardsMemoryQuery Q;
Q.OriginalAccess = StartingUseOrDef;
Q.StartingLoc = Loc;
- Q.Inst = nullptr;
+ Q.Inst = nullptr;
Q.IsCall = false;
// Unlike the other function, do not walk to the def of a def, because we are
@@ -2544,19 +2544,19 @@ void MemoryDef::deleteMe(DerivedUser *Self) {
void MemoryUse::deleteMe(DerivedUser *Self) {
delete static_cast<MemoryUse *>(Self);
}
-
-bool upward_defs_iterator::IsGuaranteedLoopInvariant(Value *Ptr) const {
- auto IsGuaranteedLoopInvariantBase = [](Value *Ptr) {
- Ptr = Ptr->stripPointerCasts();
- if (!isa<Instruction>(Ptr))
- return true;
- return isa<AllocaInst>(Ptr);
- };
-
- Ptr = Ptr->stripPointerCasts();
- if (auto *GEP = dyn_cast<GEPOperator>(Ptr)) {
- return IsGuaranteedLoopInvariantBase(GEP->getPointerOperand()) &&
- GEP->hasAllConstantIndices();
- }
- return IsGuaranteedLoopInvariantBase(Ptr);
-}
+
+bool upward_defs_iterator::IsGuaranteedLoopInvariant(Value *Ptr) const {
+ auto IsGuaranteedLoopInvariantBase = [](Value *Ptr) {
+ Ptr = Ptr->stripPointerCasts();
+ if (!isa<Instruction>(Ptr))
+ return true;
+ return isa<AllocaInst>(Ptr);
+ };
+
+ Ptr = Ptr->stripPointerCasts();
+ if (auto *GEP = dyn_cast<GEPOperator>(Ptr)) {
+ return IsGuaranteedLoopInvariantBase(GEP->getPointerOperand()) &&
+ GEP->hasAllConstantIndices();
+ }
+ return IsGuaranteedLoopInvariantBase(Ptr);
+}
diff --git a/contrib/libs/llvm12/lib/Analysis/MemorySSAUpdater.cpp b/contrib/libs/llvm12/lib/Analysis/MemorySSAUpdater.cpp
index dfde63f94c..99fa58b887 100644
--- a/contrib/libs/llvm12/lib/Analysis/MemorySSAUpdater.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/MemorySSAUpdater.cpp
@@ -319,7 +319,7 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) {
bool DefBeforeSameBlock = false;
if (DefBefore->getBlock() == MD->getBlock() &&
!(isa<MemoryPhi>(DefBefore) &&
- llvm::is_contained(InsertedPHIs, DefBefore)))
+ llvm::is_contained(InsertedPHIs, DefBefore)))
DefBeforeSameBlock = true;
// There is a def before us, which means we can replace any store/phi uses
@@ -342,8 +342,8 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) {
SmallVector<WeakVH, 8> FixupList(InsertedPHIs.begin(), InsertedPHIs.end());
- SmallSet<WeakVH, 8> ExistingPhis;
-
+ SmallSet<WeakVH, 8> ExistingPhis;
+
// Remember the index where we may insert new phis.
unsigned NewPhiIndex = InsertedPHIs.size();
if (!DefBeforeSameBlock) {
@@ -384,8 +384,8 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) {
if (!MPhi) {
MPhi = MSSA->createMemoryPhi(BBIDF);
NewInsertedPHIs.push_back(MPhi);
- } else {
- ExistingPhis.insert(MPhi);
+ } else {
+ ExistingPhis.insert(MPhi);
}
// Add the phis created into the IDF blocks to NonOptPhis, so they are not
// optimized out as trivial by the call to getPreviousDefFromEnd below.
@@ -431,10 +431,10 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) {
if (NewPhiSize)
tryRemoveTrivialPhis(ArrayRef<WeakVH>(&InsertedPHIs[NewPhiIndex], NewPhiSize));
- // Now that all fixups are done, rename all uses if we are asked. Skip
- // renaming for defs in unreachable blocks.
- BasicBlock *StartBlock = MD->getBlock();
- if (RenameUses && MSSA->getDomTree().getNode(StartBlock)) {
+ // Now that all fixups are done, rename all uses if we are asked. Skip
+ // renaming for defs in unreachable blocks.
+ BasicBlock *StartBlock = MD->getBlock();
+ if (RenameUses && MSSA->getDomTree().getNode(StartBlock)) {
SmallPtrSet<BasicBlock *, 16> Visited;
// We are guaranteed there is a def in the block, because we just got it
// handed to us in this function.
@@ -452,13 +452,13 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) {
if (Phi)
MSSA->renamePass(Phi->getBlock(), nullptr, Visited);
}
- // Existing Phi blocks may need renaming too, if an access was previously
- // optimized and the inserted Defs "covers" the Optimized value.
- for (auto &MP : ExistingPhis) {
- MemoryPhi *Phi = dyn_cast_or_null<MemoryPhi>(MP);
- if (Phi)
- MSSA->renamePass(Phi->getBlock(), nullptr, Visited);
- }
+ // Existing Phi blocks may need renaming too, if an access was previously
+ // optimized and the inserted Defs "covers" the Optimized value.
+ for (auto &MP : ExistingPhis) {
+ MemoryPhi *Phi = dyn_cast_or_null<MemoryPhi>(MP);
+ if (Phi)
+ MSSA->renamePass(Phi->getBlock(), nullptr, Visited);
+ }
}
}
@@ -555,20 +555,20 @@ void MemorySSAUpdater::removeDuplicatePhiEdgesBetween(const BasicBlock *From,
}
}
-/// If all arguments of a MemoryPHI are defined by the same incoming
-/// argument, return that argument.
-static MemoryAccess *onlySingleValue(MemoryPhi *MP) {
- MemoryAccess *MA = nullptr;
-
- for (auto &Arg : MP->operands()) {
- if (!MA)
- MA = cast<MemoryAccess>(Arg);
- else if (MA != Arg)
- return nullptr;
- }
- return MA;
-}
-
+/// If all arguments of a MemoryPHI are defined by the same incoming
+/// argument, return that argument.
+static MemoryAccess *onlySingleValue(MemoryPhi *MP) {
+ MemoryAccess *MA = nullptr;
+
+ for (auto &Arg : MP->operands()) {
+ if (!MA)
+ MA = cast<MemoryAccess>(Arg);
+ else if (MA != Arg)
+ return nullptr;
+ }
+ return MA;
+}
+
static MemoryAccess *getNewDefiningAccessForClone(MemoryAccess *MA,
const ValueToValueMapTy &VMap,
PhiToDefMap &MPhiMap,
@@ -725,10 +725,10 @@ void MemorySSAUpdater::updateForClonedLoop(const LoopBlocksRPO &LoopBlocks,
NewPhi->addIncoming(IncPhi, IncBB);
}
}
- if (auto *SingleAccess = onlySingleValue(NewPhi)) {
- MPhiMap[Phi] = SingleAccess;
- removeMemoryAccess(NewPhi);
- }
+ if (auto *SingleAccess = onlySingleValue(NewPhi)) {
+ MPhiMap[Phi] = SingleAccess;
+ removeMemoryAccess(NewPhi);
+ }
};
auto ProcessBlock = [&](BasicBlock *BB) {
@@ -811,42 +811,42 @@ void MemorySSAUpdater::updateExitBlocksForClonedLoop(
}
void MemorySSAUpdater::applyUpdates(ArrayRef<CFGUpdate> Updates,
- DominatorTree &DT, bool UpdateDT) {
+ DominatorTree &DT, bool UpdateDT) {
SmallVector<CFGUpdate, 4> DeleteUpdates;
- SmallVector<CFGUpdate, 4> RevDeleteUpdates;
+ SmallVector<CFGUpdate, 4> RevDeleteUpdates;
SmallVector<CFGUpdate, 4> InsertUpdates;
for (auto &Update : Updates) {
if (Update.getKind() == DT.Insert)
InsertUpdates.push_back({DT.Insert, Update.getFrom(), Update.getTo()});
- else {
+ else {
DeleteUpdates.push_back({DT.Delete, Update.getFrom(), Update.getTo()});
- RevDeleteUpdates.push_back({DT.Insert, Update.getFrom(), Update.getTo()});
- }
+ RevDeleteUpdates.push_back({DT.Insert, Update.getFrom(), Update.getTo()});
+ }
}
if (!DeleteUpdates.empty()) {
- if (!UpdateDT) {
- SmallVector<CFGUpdate, 0> Empty;
- // Deletes are reversed applied, because this CFGView is pretending the
- // deletes did not happen yet, hence the edges still exist.
- DT.applyUpdates(Empty, RevDeleteUpdates);
- } else {
- // Apply all updates, with the RevDeleteUpdates as PostCFGView.
- DT.applyUpdates(Updates, RevDeleteUpdates);
- }
-
- // Note: the MSSA update below doesn't distinguish between a GD with
- // (RevDelete,false) and (Delete, true), but this matters for the DT
- // updates above; for "children" purposes they are equivalent; but the
- // updates themselves convey the desired update, used inside DT only.
- GraphDiff<BasicBlock *> GD(RevDeleteUpdates);
- applyInsertUpdates(InsertUpdates, DT, &GD);
- // Update DT to redelete edges; this matches the real CFG so we can perform
- // the standard update without a postview of the CFG.
- DT.applyUpdates(DeleteUpdates);
+ if (!UpdateDT) {
+ SmallVector<CFGUpdate, 0> Empty;
+ // Deletes are reversed applied, because this CFGView is pretending the
+ // deletes did not happen yet, hence the edges still exist.
+ DT.applyUpdates(Empty, RevDeleteUpdates);
+ } else {
+ // Apply all updates, with the RevDeleteUpdates as PostCFGView.
+ DT.applyUpdates(Updates, RevDeleteUpdates);
+ }
+
+ // Note: the MSSA update below doesn't distinguish between a GD with
+ // (RevDelete,false) and (Delete, true), but this matters for the DT
+ // updates above; for "children" purposes they are equivalent; but the
+ // updates themselves convey the desired update, used inside DT only.
+ GraphDiff<BasicBlock *> GD(RevDeleteUpdates);
+ applyInsertUpdates(InsertUpdates, DT, &GD);
+ // Update DT to redelete edges; this matches the real CFG so we can perform
+ // the standard update without a postview of the CFG.
+ DT.applyUpdates(DeleteUpdates);
} else {
- if (UpdateDT)
- DT.applyUpdates(Updates);
+ if (UpdateDT)
+ DT.applyUpdates(Updates);
GraphDiff<BasicBlock *> GD;
applyInsertUpdates(InsertUpdates, DT, &GD);
}
@@ -876,8 +876,8 @@ void MemorySSAUpdater::applyInsertUpdates(ArrayRef<CFGUpdate> Updates,
// Check number of predecessors, we only care if there's more than one.
unsigned Count = 0;
BasicBlock *Pred = nullptr;
- for (auto *Pi : GD->template getChildren</*InverseEdge=*/true>(BB)) {
- Pred = Pi;
+ for (auto *Pi : GD->template getChildren</*InverseEdge=*/true>(BB)) {
+ Pred = Pi;
Count++;
if (Count == 2)
break;
@@ -970,7 +970,7 @@ void MemorySSAUpdater::applyInsertUpdates(ArrayRef<CFGUpdate> Updates,
auto *BB = BBPredPair.first;
const auto &AddedBlockSet = BBPredPair.second.Added;
auto &PrevBlockSet = BBPredPair.second.Prev;
- for (auto *Pi : GD->template getChildren</*InverseEdge=*/true>(BB)) {
+ for (auto *Pi : GD->template getChildren</*InverseEdge=*/true>(BB)) {
if (!AddedBlockSet.count(Pi))
PrevBlockSet.insert(Pi);
EdgeCountMap[{Pi, BB}]++;
@@ -1121,7 +1121,7 @@ void MemorySSAUpdater::applyInsertUpdates(ArrayRef<CFGUpdate> Updates,
for (unsigned I = 0, E = IDFPhi->getNumIncomingValues(); I < E; ++I)
IDFPhi->setIncomingValue(I, GetLastDef(IDFPhi->getIncomingBlock(I)));
} else {
- for (auto *Pi : GD->template getChildren</*InverseEdge=*/true>(BBIDF))
+ for (auto *Pi : GD->template getChildren</*InverseEdge=*/true>(BBIDF))
IDFPhi->addIncoming(GetLastDef(Pi), Pi);
}
}
@@ -1341,7 +1341,7 @@ void MemorySSAUpdater::removeMemoryAccess(MemoryAccess *MA, bool OptimizePhis) {
// Note: We assume MemorySSA is not used in metadata since it's not really
// part of the IR.
- assert(NewDefTarget != MA && "Going into an infinite loop");
+ assert(NewDefTarget != MA && "Going into an infinite loop");
while (!MA->use_empty()) {
Use &U = *MA->use_begin();
if (auto *MUD = dyn_cast<MemoryUseOrDef>(U.getUser()))
diff --git a/contrib/libs/llvm12/lib/Analysis/ModuleDebugInfoPrinter.cpp b/contrib/libs/llvm12/lib/Analysis/ModuleDebugInfoPrinter.cpp
index 6cbe391b32..64fd5eb1ac 100644
--- a/contrib/libs/llvm12/lib/Analysis/ModuleDebugInfoPrinter.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/ModuleDebugInfoPrinter.cpp
@@ -14,11 +14,11 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Analysis/ModuleDebugInfoPrinter.h"
+#include "llvm/Analysis/ModuleDebugInfoPrinter.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/IR/DebugInfo.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/ErrorHandling.h"
@@ -26,34 +26,34 @@
using namespace llvm;
namespace {
-class ModuleDebugInfoLegacyPrinter : public ModulePass {
- DebugInfoFinder Finder;
-
-public:
- static char ID; // Pass identification, replacement for typeid
- ModuleDebugInfoLegacyPrinter() : ModulePass(ID) {
- initializeModuleDebugInfoLegacyPrinterPass(
- *PassRegistry::getPassRegistry());
- }
-
- bool runOnModule(Module &M) override;
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- }
- void print(raw_ostream &O, const Module *M) const override;
-};
+class ModuleDebugInfoLegacyPrinter : public ModulePass {
+ DebugInfoFinder Finder;
+
+public:
+ static char ID; // Pass identification, replacement for typeid
+ ModuleDebugInfoLegacyPrinter() : ModulePass(ID) {
+ initializeModuleDebugInfoLegacyPrinterPass(
+ *PassRegistry::getPassRegistry());
+ }
+
+ bool runOnModule(Module &M) override;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ }
+ void print(raw_ostream &O, const Module *M) const override;
+};
}
-char ModuleDebugInfoLegacyPrinter::ID = 0;
-INITIALIZE_PASS(ModuleDebugInfoLegacyPrinter, "module-debuginfo",
+char ModuleDebugInfoLegacyPrinter::ID = 0;
+INITIALIZE_PASS(ModuleDebugInfoLegacyPrinter, "module-debuginfo",
"Decodes module-level debug info", false, true)
ModulePass *llvm::createModuleDebugInfoPrinterPass() {
- return new ModuleDebugInfoLegacyPrinter();
+ return new ModuleDebugInfoLegacyPrinter();
}
-bool ModuleDebugInfoLegacyPrinter::runOnModule(Module &M) {
+bool ModuleDebugInfoLegacyPrinter::runOnModule(Module &M) {
Finder.processModule(M);
return false;
}
@@ -71,8 +71,8 @@ static void printFile(raw_ostream &O, StringRef Filename, StringRef Directory,
O << ":" << Line;
}
-static void printModuleDebugInfo(raw_ostream &O, const Module *M,
- const DebugInfoFinder &Finder) {
+static void printModuleDebugInfo(raw_ostream &O, const Module *M,
+ const DebugInfoFinder &Finder) {
// Printing the nodes directly isn't particularly helpful (since they
// reference other nodes that won't be printed, particularly for the
// filenames), so just print a few useful things.
@@ -131,18 +131,18 @@ static void printModuleDebugInfo(raw_ostream &O, const Module *M,
O << '\n';
}
}
-
-void ModuleDebugInfoLegacyPrinter::print(raw_ostream &O,
- const Module *M) const {
- printModuleDebugInfo(O, M, Finder);
-}
-
-ModuleDebugInfoPrinterPass::ModuleDebugInfoPrinterPass(raw_ostream &OS)
- : OS(OS) {}
-
-PreservedAnalyses ModuleDebugInfoPrinterPass::run(Module &M,
- ModuleAnalysisManager &AM) {
- Finder.processModule(M);
- printModuleDebugInfo(OS, &M, Finder);
- return PreservedAnalyses::all();
-}
+
+void ModuleDebugInfoLegacyPrinter::print(raw_ostream &O,
+ const Module *M) const {
+ printModuleDebugInfo(O, M, Finder);
+}
+
+ModuleDebugInfoPrinterPass::ModuleDebugInfoPrinterPass(raw_ostream &OS)
+ : OS(OS) {}
+
+PreservedAnalyses ModuleDebugInfoPrinterPass::run(Module &M,
+ ModuleAnalysisManager &AM) {
+ Finder.processModule(M);
+ printModuleDebugInfo(OS, &M, Finder);
+ return PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Analysis/ModuleSummaryAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/ModuleSummaryAnalysis.cpp
index aa144883f6..5f7746eeed 100644
--- a/contrib/libs/llvm12/lib/Analysis/ModuleSummaryAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/ModuleSummaryAnalysis.cpp
@@ -145,7 +145,7 @@ static void addVCallToSet(DevirtCallSite Call, GlobalValue::GUID Guid,
SetVector<FunctionSummary::ConstVCall> &ConstVCalls) {
std::vector<uint64_t> Args;
// Start from the second argument to skip the "this" pointer.
- for (auto &Arg : drop_begin(Call.CB.args())) {
+ for (auto &Arg : drop_begin(Call.CB.args())) {
auto *CI = dyn_cast<ConstantInt>(Arg);
if (!CI || CI->getBitWidth() > 64) {
VCalls.insert({Guid, Call.Offset});
@@ -472,7 +472,7 @@ static void computeFunctionSummary(
F.hasFnAttribute(Attribute::AlwaysInline)};
std::vector<FunctionSummary::ParamAccess> ParamAccesses;
if (auto *SSI = GetSSICallback(F))
- ParamAccesses = SSI->getParamAccesses(Index);
+ ParamAccesses = SSI->getParamAccesses(Index);
auto FuncSummary = std::make_unique<FunctionSummary>(
Flags, NumInsts, FunFlags, /*EntryCount=*/0, std::move(Refs),
CallGraphEdges.takeVector(), TypeTests.takeVector(),
diff --git a/contrib/libs/llvm12/lib/Analysis/MustExecute.cpp b/contrib/libs/llvm12/lib/Analysis/MustExecute.cpp
index 2d7343db27..1e7626013e 100644
--- a/contrib/libs/llvm12/lib/Analysis/MustExecute.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/MustExecute.cpp
@@ -16,11 +16,11 @@
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/AssemblyAnnotationWriter.h"
#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Dominators.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
@@ -302,31 +302,31 @@ bool ICFLoopSafetyInfo::doesNotWriteMemoryBefore(const Instruction &I,
}
namespace {
-struct MustExecutePrinter : public FunctionPass {
-
- static char ID; // Pass identification, replacement for typeid
- MustExecutePrinter() : FunctionPass(ID) {
- initializeMustExecutePrinterPass(*PassRegistry::getPassRegistry());
- }
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- AU.addRequired<DominatorTreeWrapperPass>();
- AU.addRequired<LoopInfoWrapperPass>();
- }
- bool runOnFunction(Function &F) override;
-};
-struct MustBeExecutedContextPrinter : public ModulePass {
- static char ID;
-
- MustBeExecutedContextPrinter() : ModulePass(ID) {
- initializeMustBeExecutedContextPrinterPass(
- *PassRegistry::getPassRegistry());
- }
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- }
- bool runOnModule(Module &M) override;
-};
+struct MustExecutePrinter : public FunctionPass {
+
+ static char ID; // Pass identification, replacement for typeid
+ MustExecutePrinter() : FunctionPass(ID) {
+ initializeMustExecutePrinterPass(*PassRegistry::getPassRegistry());
+ }
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ AU.addRequired<DominatorTreeWrapperPass>();
+ AU.addRequired<LoopInfoWrapperPass>();
+ }
+ bool runOnFunction(Function &F) override;
+};
+struct MustBeExecutedContextPrinter : public ModulePass {
+ static char ID;
+
+ MustBeExecutedContextPrinter() : ModulePass(ID) {
+ initializeMustBeExecutedContextPrinterPass(
+ *PassRegistry::getPassRegistry());
+ }
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ }
+ bool runOnModule(Module &M) override;
+};
}
char MustExecutePrinter::ID = 0;
@@ -342,16 +342,16 @@ FunctionPass *llvm::createMustExecutePrinter() {
}
char MustBeExecutedContextPrinter::ID = 0;
-INITIALIZE_PASS_BEGIN(MustBeExecutedContextPrinter,
- "print-must-be-executed-contexts",
- "print the must-be-executed-context for all instructions",
- false, true)
+INITIALIZE_PASS_BEGIN(MustBeExecutedContextPrinter,
+ "print-must-be-executed-contexts",
+ "print the must-be-executed-context for all instructions",
+ false, true)
INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_END(MustBeExecutedContextPrinter,
"print-must-be-executed-contexts",
- "print the must-be-executed-context for all instructions",
+ "print the must-be-executed-context for all instructions",
false, true)
ModulePass *llvm::createMustBeExecutedContextPrinter() {
@@ -631,7 +631,7 @@ MustBeExecutedContextExplorer::findForwardJoinPoint(const BasicBlock *InitBB) {
if (!TransfersExecution)
return nullptr;
- append_range(Worklist, successors(ToBB));
+ append_range(Worklist, successors(ToBB));
}
}
@@ -838,42 +838,42 @@ const Instruction *MustBeExecutedIterator::advance() {
Tail = nullptr;
return nullptr;
}
-
-PreservedAnalyses MustExecutePrinterPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- auto &LI = AM.getResult<LoopAnalysis>(F);
- auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
-
- MustExecuteAnnotatedWriter Writer(F, DT, LI);
- F.print(OS, &Writer);
- return PreservedAnalyses::all();
-}
-
-PreservedAnalyses
-MustBeExecutedContextPrinterPass::run(Module &M, ModuleAnalysisManager &AM) {
- FunctionAnalysisManager &FAM =
- AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
- GetterTy<const LoopInfo> LIGetter = [&](const Function &F) {
- return &FAM.getResult<LoopAnalysis>(const_cast<Function &>(F));
- };
- GetterTy<const DominatorTree> DTGetter = [&](const Function &F) {
- return &FAM.getResult<DominatorTreeAnalysis>(const_cast<Function &>(F));
- };
- GetterTy<const PostDominatorTree> PDTGetter = [&](const Function &F) {
- return &FAM.getResult<PostDominatorTreeAnalysis>(const_cast<Function &>(F));
- };
-
- MustBeExecutedContextExplorer Explorer(
- /* ExploreInterBlock */ true,
- /* ExploreCFGForward */ true,
- /* ExploreCFGBackward */ true, LIGetter, DTGetter, PDTGetter);
-
- for (Function &F : M) {
- for (Instruction &I : instructions(F)) {
- OS << "-- Explore context of: " << I << "\n";
- for (const Instruction *CI : Explorer.range(&I))
- OS << " [F: " << CI->getFunction()->getName() << "] " << *CI << "\n";
- }
- }
- return PreservedAnalyses::all();
-}
+
+PreservedAnalyses MustExecutePrinterPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ auto &LI = AM.getResult<LoopAnalysis>(F);
+ auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
+
+ MustExecuteAnnotatedWriter Writer(F, DT, LI);
+ F.print(OS, &Writer);
+ return PreservedAnalyses::all();
+}
+
+PreservedAnalyses
+MustBeExecutedContextPrinterPass::run(Module &M, ModuleAnalysisManager &AM) {
+ FunctionAnalysisManager &FAM =
+ AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+ GetterTy<const LoopInfo> LIGetter = [&](const Function &F) {
+ return &FAM.getResult<LoopAnalysis>(const_cast<Function &>(F));
+ };
+ GetterTy<const DominatorTree> DTGetter = [&](const Function &F) {
+ return &FAM.getResult<DominatorTreeAnalysis>(const_cast<Function &>(F));
+ };
+ GetterTy<const PostDominatorTree> PDTGetter = [&](const Function &F) {
+ return &FAM.getResult<PostDominatorTreeAnalysis>(const_cast<Function &>(F));
+ };
+
+ MustBeExecutedContextExplorer Explorer(
+ /* ExploreInterBlock */ true,
+ /* ExploreCFGForward */ true,
+ /* ExploreCFGBackward */ true, LIGetter, DTGetter, PDTGetter);
+
+ for (Function &F : M) {
+ for (Instruction &I : instructions(F)) {
+ OS << "-- Explore context of: " << I << "\n";
+ for (const Instruction *CI : Explorer.range(&I))
+ OS << " [F: " << CI->getFunction()->getName() << "] " << *CI << "\n";
+ }
+ }
+ return PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Analysis/ObjCARCAliasAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/ObjCARCAliasAnalysis.cpp
index 2f59520cbe..786d03f694 100644
--- a/contrib/libs/llvm12/lib/Analysis/ObjCARCAliasAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/ObjCARCAliasAnalysis.cpp
@@ -54,11 +54,11 @@ AliasResult ObjCARCAAResult::alias(const MemoryLocation &LocA,
// If that failed, climb to the underlying object, including climbing through
// ObjC-specific no-ops, and try making an imprecise alias query.
- const Value *UA = GetUnderlyingObjCPtr(SA);
- const Value *UB = GetUnderlyingObjCPtr(SB);
+ const Value *UA = GetUnderlyingObjCPtr(SA);
+ const Value *UB = GetUnderlyingObjCPtr(SB);
if (UA != SA || UB != SB) {
- Result = AAResultBase::alias(MemoryLocation::getBeforeOrAfter(UA),
- MemoryLocation::getBeforeOrAfter(UB), AAQI);
+ Result = AAResultBase::alias(MemoryLocation::getBeforeOrAfter(UA),
+ MemoryLocation::getBeforeOrAfter(UB), AAQI);
// We can't use MustAlias or PartialAlias results here because
// GetUnderlyingObjCPtr may return an offsetted pointer value.
if (Result == NoAlias)
@@ -84,10 +84,10 @@ bool ObjCARCAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
// If that failed, climb to the underlying object, including climbing through
// ObjC-specific no-ops, and try making an imprecise alias query.
- const Value *U = GetUnderlyingObjCPtr(S);
+ const Value *U = GetUnderlyingObjCPtr(S);
if (U != S)
- return AAResultBase::pointsToConstantMemory(
- MemoryLocation::getBeforeOrAfter(U), AAQI, OrLocal);
+ return AAResultBase::pointsToConstantMemory(
+ MemoryLocation::getBeforeOrAfter(U), AAQI, OrLocal);
// If that failed, fail. We don't need to chain here, since that's covered
// by the earlier precise query.
@@ -134,8 +134,8 @@ ModRefInfo ObjCARCAAResult::getModRefInfo(const CallBase *Call,
return AAResultBase::getModRefInfo(Call, Loc, AAQI);
}
-AnalysisKey ObjCARCAA::Key;
-
+AnalysisKey ObjCARCAA::Key;
+
ObjCARCAAResult ObjCARCAA::run(Function &F, FunctionAnalysisManager &AM) {
return ObjCARCAAResult(F.getParent()->getDataLayout());
}
diff --git a/contrib/libs/llvm12/lib/Analysis/ObjCARCAnalysisUtils.cpp b/contrib/libs/llvm12/lib/Analysis/ObjCARCAnalysisUtils.cpp
index 4af82760b5..d34a3c6363 100644
--- a/contrib/libs/llvm12/lib/Analysis/ObjCARCAnalysisUtils.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/ObjCARCAnalysisUtils.cpp
@@ -13,7 +13,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/ObjCARCAnalysisUtils.h"
-#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Support/CommandLine.h"
using namespace llvm;
@@ -24,22 +24,22 @@ bool llvm::objcarc::EnableARCOpts;
static cl::opt<bool, true> EnableARCOptimizations(
"enable-objc-arc-opts", cl::desc("enable/disable all ARC Optimizations"),
cl::location(EnableARCOpts), cl::init(true), cl::Hidden);
-
-bool llvm::objcarc::IsPotentialRetainableObjPtr(const Value *Op,
- AAResults &AA) {
- // First make the rudimentary check.
- if (!IsPotentialRetainableObjPtr(Op))
- return false;
-
- // Objects in constant memory are not reference-counted.
- if (AA.pointsToConstantMemory(Op))
- return false;
-
- // Pointers in constant memory are not pointing to reference-counted objects.
- if (const LoadInst *LI = dyn_cast<LoadInst>(Op))
- if (AA.pointsToConstantMemory(LI->getPointerOperand()))
- return false;
-
- // Otherwise assume the worst.
- return true;
-}
+
+bool llvm::objcarc::IsPotentialRetainableObjPtr(const Value *Op,
+ AAResults &AA) {
+ // First make the rudimentary check.
+ if (!IsPotentialRetainableObjPtr(Op))
+ return false;
+
+ // Objects in constant memory are not reference-counted.
+ if (AA.pointsToConstantMemory(Op))
+ return false;
+
+ // Pointers in constant memory are not pointing to reference-counted objects.
+ if (const LoadInst *LI = dyn_cast<LoadInst>(Op))
+ if (AA.pointsToConstantMemory(LI->getPointerOperand()))
+ return false;
+
+ // Otherwise assume the worst.
+ return true;
+}
diff --git a/contrib/libs/llvm12/lib/Analysis/OptimizationRemarkEmitter.cpp b/contrib/libs/llvm12/lib/Analysis/OptimizationRemarkEmitter.cpp
index 47a5a0ef1a..6f3d4d536c 100644
--- a/contrib/libs/llvm12/lib/Analysis/OptimizationRemarkEmitter.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/OptimizationRemarkEmitter.cpp
@@ -15,7 +15,7 @@
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/ProfileSummaryInfo.h"
+#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/LLVMContext.h"
@@ -37,7 +37,7 @@ OptimizationRemarkEmitter::OptimizationRemarkEmitter(const Function *F)
LI.analyze(DT);
// Then compute BranchProbabilityInfo.
- BranchProbabilityInfo BPI(*F, LI, nullptr, &DT, nullptr);
+ BranchProbabilityInfo BPI(*F, LI, nullptr, &DT, nullptr);
// Finally compute BFI.
OwnedBFI = std::make_unique<BlockFrequencyInfo>(*F, BPI, LI);
@@ -97,17 +97,17 @@ OptimizationRemarkEmitterWrapperPass::OptimizationRemarkEmitterWrapperPass()
bool OptimizationRemarkEmitterWrapperPass::runOnFunction(Function &Fn) {
BlockFrequencyInfo *BFI;
- auto &Context = Fn.getContext();
- if (Context.getDiagnosticsHotnessRequested()) {
+ auto &Context = Fn.getContext();
+ if (Context.getDiagnosticsHotnessRequested()) {
BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
- // Get hotness threshold from PSI. This should only happen once.
- if (Context.isDiagnosticsHotnessThresholdSetFromPSI()) {
- if (ProfileSummaryInfo *PSI =
- &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI())
- Context.setDiagnosticsHotnessThreshold(
- PSI->getOrCompHotCountThreshold());
- }
- } else
+ // Get hotness threshold from PSI. This should only happen once.
+ if (Context.isDiagnosticsHotnessThresholdSetFromPSI()) {
+ if (ProfileSummaryInfo *PSI =
+ &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI())
+ Context.setDiagnosticsHotnessThreshold(
+ PSI->getOrCompHotCountThreshold());
+ }
+ } else
BFI = nullptr;
ORE = std::make_unique<OptimizationRemarkEmitter>(&Fn, BFI);
@@ -117,7 +117,7 @@ bool OptimizationRemarkEmitterWrapperPass::runOnFunction(Function &Fn) {
void OptimizationRemarkEmitterWrapperPass::getAnalysisUsage(
AnalysisUsage &AU) const {
LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
- AU.addRequired<ProfileSummaryInfoWrapperPass>();
+ AU.addRequired<ProfileSummaryInfoWrapperPass>();
AU.setPreservesAll();
}
@@ -127,19 +127,19 @@ OptimizationRemarkEmitter
OptimizationRemarkEmitterAnalysis::run(Function &F,
FunctionAnalysisManager &AM) {
BlockFrequencyInfo *BFI;
- auto &Context = F.getContext();
+ auto &Context = F.getContext();
- if (Context.getDiagnosticsHotnessRequested()) {
+ if (Context.getDiagnosticsHotnessRequested()) {
BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
- // Get hotness threshold from PSI. This should only happen once.
- if (Context.isDiagnosticsHotnessThresholdSetFromPSI()) {
- auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
- if (ProfileSummaryInfo *PSI =
- MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent()))
- Context.setDiagnosticsHotnessThreshold(
- PSI->getOrCompHotCountThreshold());
- }
- } else
+ // Get hotness threshold from PSI. This should only happen once.
+ if (Context.isDiagnosticsHotnessThresholdSetFromPSI()) {
+ auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
+ if (ProfileSummaryInfo *PSI =
+ MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent()))
+ Context.setDiagnosticsHotnessThreshold(
+ PSI->getOrCompHotCountThreshold());
+ }
+ } else
BFI = nullptr;
return OptimizationRemarkEmitter(&F, BFI);
@@ -152,6 +152,6 @@ static const char ore_name[] = "Optimization Remark Emitter";
INITIALIZE_PASS_BEGIN(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
false, true)
INITIALIZE_PASS_DEPENDENCY(LazyBFIPass)
-INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
INITIALIZE_PASS_END(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
false, true)
diff --git a/contrib/libs/llvm12/lib/Analysis/RegionPass.cpp b/contrib/libs/llvm12/lib/Analysis/RegionPass.cpp
index 82a9a1d5de..a73607dbef 100644
--- a/contrib/libs/llvm12/lib/Analysis/RegionPass.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/RegionPass.cpp
@@ -15,7 +15,7 @@
#include "llvm/Analysis/RegionPass.h"
#include "llvm/IR/OptBisect.h"
#include "llvm/IR/PassTimingInfo.h"
-#include "llvm/IR/StructuralHash.h"
+#include "llvm/IR/StructuralHash.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
@@ -87,54 +87,54 @@ bool RGPassManager::runOnFunction(Function &F) {
initializeAnalysisImpl(P);
- bool LocalChanged = false;
+ bool LocalChanged = false;
{
PassManagerPrettyStackEntry X(P, *CurrentRegion->getEntry());
TimeRegion PassTimer(getPassTimer(P));
-#ifdef EXPENSIVE_CHECKS
- uint64_t RefHash = StructuralHash(F);
-#endif
- LocalChanged = P->runOnRegion(CurrentRegion, *this);
-
-#ifdef EXPENSIVE_CHECKS
- if (!LocalChanged && (RefHash != StructuralHash(F))) {
- llvm::errs() << "Pass modifies its input and doesn't report it: "
- << P->getPassName() << "\n";
- llvm_unreachable("Pass modifies its input and doesn't report it");
- }
-#endif
-
- Changed |= LocalChanged;
+#ifdef EXPENSIVE_CHECKS
+ uint64_t RefHash = StructuralHash(F);
+#endif
+ LocalChanged = P->runOnRegion(CurrentRegion, *this);
+
+#ifdef EXPENSIVE_CHECKS
+ if (!LocalChanged && (RefHash != StructuralHash(F))) {
+ llvm::errs() << "Pass modifies its input and doesn't report it: "
+ << P->getPassName() << "\n";
+ llvm_unreachable("Pass modifies its input and doesn't report it");
+ }
+#endif
+
+ Changed |= LocalChanged;
}
if (isPassDebuggingExecutionsOrMore()) {
- if (LocalChanged)
+ if (LocalChanged)
dumpPassInfo(P, MODIFICATION_MSG, ON_REGION_MSG,
CurrentRegion->getNameStr());
dumpPreservedSet(P);
}
- // Manually check that this region is still healthy. This is done
- // instead of relying on RegionInfo::verifyRegion since RegionInfo
- // is a function pass and it's really expensive to verify every
- // Region in the function every time. That level of checking can be
- // enabled with the -verify-region-info option.
- {
- TimeRegion PassTimer(getPassTimer(P));
- CurrentRegion->verifyRegion();
+ // Manually check that this region is still healthy. This is done
+ // instead of relying on RegionInfo::verifyRegion since RegionInfo
+ // is a function pass and it's really expensive to verify every
+ // Region in the function every time. That level of checking can be
+ // enabled with the -verify-region-info option.
+ {
+ TimeRegion PassTimer(getPassTimer(P));
+ CurrentRegion->verifyRegion();
}
- // Then call the regular verifyAnalysis functions.
- verifyPreservedAnalysis(P);
-
- if (LocalChanged)
- removeNotPreservedAnalysis(P);
+ // Then call the regular verifyAnalysis functions.
+ verifyPreservedAnalysis(P);
+
+ if (LocalChanged)
+ removeNotPreservedAnalysis(P);
recordAvailableAnalysis(P);
removeDeadPasses(P,
- (!isPassDebuggingExecutionsOrMore())
- ? "<deleted>"
- : CurrentRegion->getNameStr(),
+ (!isPassDebuggingExecutionsOrMore())
+ ? "<deleted>"
+ : CurrentRegion->getNameStr(),
ON_REGION_MSG);
}
diff --git a/contrib/libs/llvm12/lib/Analysis/ReleaseModeModelRunner.cpp b/contrib/libs/llvm12/lib/Analysis/ReleaseModeModelRunner.cpp
index cdf46d2a74..02a4327e54 100644
--- a/contrib/libs/llvm12/lib/Analysis/ReleaseModeModelRunner.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/ReleaseModeModelRunner.cpp
@@ -1,90 +1,90 @@
-//===- ReleaseModeModelRunner.cpp - Fast, precompiled model runner -------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements a model runner wrapping an AOT compiled ML model.
-// Only inference is supported.
-//
-//===----------------------------------------------------------------------===//
-#include "llvm/Config/config.h"
-#if defined(LLVM_HAVE_TF_AOT)
-
-#include "llvm/Analysis/InlineModelFeatureMaps.h"
-#include "llvm/Analysis/MLInlineAdvisor.h"
-
-// codegen-ed file
-#error #include "InlinerSizeModel.h" // NOLINT
-
-#include <memory>
-#include <vector>
-
-using namespace llvm;
-namespace {
-
-const char FeedPrefix[] = "feed_";
-const char FetchPrefix[] = "fetch_";
-
-/// MLModelRunner - production mode implementation. It uses a AOT-compiled
-/// SavedModel for efficient execution.
-class ReleaseModeModelRunner final : public MLModelRunner {
-public:
- ReleaseModeModelRunner(LLVMContext &Ctx);
- virtual ~ReleaseModeModelRunner() = default;
-
- bool run() override;
-
- void setFeature(FeatureIndex Index, int64_t Value) override;
- int64_t getFeature(int Index) const override;
-
-private:
- std::vector<int32_t> FeatureIndices;
- int32_t ResultIndex = -1;
- std::unique_ptr<llvm::InlinerSizeModel> CompiledModel;
-};
-} // namespace
-
-ReleaseModeModelRunner::ReleaseModeModelRunner(LLVMContext &Ctx)
- : MLModelRunner(Ctx),
- CompiledModel(std::make_unique<llvm::InlinerSizeModel>()) {
- assert(CompiledModel && "The CompiledModel should be valid");
-
- FeatureIndices.reserve(NumberOfFeatures);
-
- for (size_t I = 0; I < NumberOfFeatures; ++I) {
- const int Index =
- CompiledModel->LookupArgIndex(FeedPrefix + FeatureNameMap[I]);
- assert(Index >= 0 && "Cannot find Feature in inlining model");
- FeatureIndices[I] = Index;
- }
-
- ResultIndex =
- CompiledModel->LookupResultIndex(std::string(FetchPrefix) + DecisionName);
- assert(ResultIndex >= 0 && "Cannot find DecisionName in inlining model");
-}
-
-int64_t ReleaseModeModelRunner::getFeature(int Index) const {
- return *static_cast<int64_t *>(
- CompiledModel->arg_data(FeatureIndices[Index]));
-}
-
-void ReleaseModeModelRunner::setFeature(FeatureIndex Index, int64_t Value) {
- *static_cast<int64_t *>(CompiledModel->arg_data(
- FeatureIndices[static_cast<size_t>(Index)])) = Value;
-}
-
-bool ReleaseModeModelRunner::run() {
- CompiledModel->Run();
- return static_cast<bool>(
- *static_cast<int64_t *>(CompiledModel->result_data(ResultIndex)));
-}
-
-std::unique_ptr<InlineAdvisor>
-llvm::getReleaseModeAdvisor(Module &M, ModuleAnalysisManager &MAM) {
- auto AOTRunner = std::make_unique<ReleaseModeModelRunner>(M.getContext());
- return std::make_unique<MLInlineAdvisor>(M, MAM, std::move(AOTRunner));
-}
-#endif // defined(LLVM_HAVE_TF_AOT)
+//===- ReleaseModeModelRunner.cpp - Fast, precompiled model runner -------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a model runner wrapping an AOT compiled ML model.
+// Only inference is supported.
+//
+//===----------------------------------------------------------------------===//
+#include "llvm/Config/config.h"
+#if defined(LLVM_HAVE_TF_AOT)
+
+#include "llvm/Analysis/InlineModelFeatureMaps.h"
+#include "llvm/Analysis/MLInlineAdvisor.h"
+
+// codegen-ed file
+#error #include "InlinerSizeModel.h" // NOLINT
+
+#include <memory>
+#include <vector>
+
+using namespace llvm;
+namespace {
+
+const char FeedPrefix[] = "feed_";
+const char FetchPrefix[] = "fetch_";
+
+/// MLModelRunner - production mode implementation. It uses a AOT-compiled
+/// SavedModel for efficient execution.
+class ReleaseModeModelRunner final : public MLModelRunner {
+public:
+ ReleaseModeModelRunner(LLVMContext &Ctx);
+ virtual ~ReleaseModeModelRunner() = default;
+
+ bool run() override;
+
+ void setFeature(FeatureIndex Index, int64_t Value) override;
+ int64_t getFeature(int Index) const override;
+
+private:
+ std::vector<int32_t> FeatureIndices;
+ int32_t ResultIndex = -1;
+ std::unique_ptr<llvm::InlinerSizeModel> CompiledModel;
+};
+} // namespace
+
+ReleaseModeModelRunner::ReleaseModeModelRunner(LLVMContext &Ctx)
+ : MLModelRunner(Ctx),
+ CompiledModel(std::make_unique<llvm::InlinerSizeModel>()) {
+ assert(CompiledModel && "The CompiledModel should be valid");
+
+ FeatureIndices.reserve(NumberOfFeatures);
+
+ for (size_t I = 0; I < NumberOfFeatures; ++I) {
+ const int Index =
+ CompiledModel->LookupArgIndex(FeedPrefix + FeatureNameMap[I]);
+ assert(Index >= 0 && "Cannot find Feature in inlining model");
+ FeatureIndices[I] = Index;
+ }
+
+ ResultIndex =
+ CompiledModel->LookupResultIndex(std::string(FetchPrefix) + DecisionName);
+ assert(ResultIndex >= 0 && "Cannot find DecisionName in inlining model");
+}
+
+int64_t ReleaseModeModelRunner::getFeature(int Index) const {
+ return *static_cast<int64_t *>(
+ CompiledModel->arg_data(FeatureIndices[Index]));
+}
+
+void ReleaseModeModelRunner::setFeature(FeatureIndex Index, int64_t Value) {
+ *static_cast<int64_t *>(CompiledModel->arg_data(
+ FeatureIndices[static_cast<size_t>(Index)])) = Value;
+}
+
+bool ReleaseModeModelRunner::run() {
+ CompiledModel->Run();
+ return static_cast<bool>(
+ *static_cast<int64_t *>(CompiledModel->result_data(ResultIndex)));
+}
+
+std::unique_ptr<InlineAdvisor>
+llvm::getReleaseModeAdvisor(Module &M, ModuleAnalysisManager &MAM) {
+ auto AOTRunner = std::make_unique<ReleaseModeModelRunner>(M.getContext());
+ return std::make_unique<MLInlineAdvisor>(M, MAM, std::move(AOTRunner));
+}
+#endif // defined(LLVM_HAVE_TF_AOT)
diff --git a/contrib/libs/llvm12/lib/Analysis/ReplayInlineAdvisor.cpp b/contrib/libs/llvm12/lib/Analysis/ReplayInlineAdvisor.cpp
index 9833a5635c..b9dac2f3ff 100644
--- a/contrib/libs/llvm12/lib/Analysis/ReplayInlineAdvisor.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/ReplayInlineAdvisor.cpp
@@ -1,82 +1,82 @@
-//===- ReplayInlineAdvisor.cpp - Replay InlineAdvisor ---------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements ReplayInlineAdvisor that replays inline decisions based
-// on previous inline remarks from optimization remark log. This is a best
-// effort approach useful for testing compiler/source changes while holding
-// inlining steady.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/ReplayInlineAdvisor.h"
-#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/Support/LineIterator.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "inline-replay"
-
-ReplayInlineAdvisor::ReplayInlineAdvisor(
- Module &M, FunctionAnalysisManager &FAM, LLVMContext &Context,
- std::unique_ptr<InlineAdvisor> OriginalAdvisor, StringRef RemarksFile,
- bool EmitRemarks)
- : InlineAdvisor(M, FAM), OriginalAdvisor(std::move(OriginalAdvisor)),
- HasReplayRemarks(false), EmitRemarks(EmitRemarks) {
- auto BufferOrErr = MemoryBuffer::getFileOrSTDIN(RemarksFile);
- std::error_code EC = BufferOrErr.getError();
- if (EC) {
- Context.emitError("Could not open remarks file: " + EC.message());
- return;
- }
-
- // Example for inline remarks to parse:
- // main:3:1.1: _Z3subii inlined into main at callsite sum:1 @ main:3:1.1
- // We use the callsite string after `at callsite` to replay inlining.
- line_iterator LineIt(*BufferOrErr.get(), /*SkipBlanks=*/true);
- for (; !LineIt.is_at_eof(); ++LineIt) {
- StringRef Line = *LineIt;
- auto Pair = Line.split(" at callsite ");
-
- auto Callee = Pair.first.split(" inlined into").first.rsplit(": ").second;
-
- auto CallSite = Pair.second.split(";").first;
-
- if (Callee.empty() || CallSite.empty())
- continue;
-
- std::string Combined = (Callee + CallSite).str();
- InlineSitesFromRemarks.insert(Combined);
- }
-
- HasReplayRemarks = true;
-}
-
-std::unique_ptr<InlineAdvice> ReplayInlineAdvisor::getAdviceImpl(CallBase &CB) {
- assert(HasReplayRemarks);
-
- Function &Caller = *CB.getCaller();
- auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(Caller);
-
- if (InlineSitesFromRemarks.empty())
- return std::make_unique<DefaultInlineAdvice>(this, CB, None, ORE,
- EmitRemarks);
-
- std::string CallSiteLoc = getCallSiteLocation(CB.getDebugLoc());
- StringRef Callee = CB.getCalledFunction()->getName();
- std::string Combined = (Callee + CallSiteLoc).str();
- auto Iter = InlineSitesFromRemarks.find(Combined);
-
- Optional<InlineCost> InlineRecommended = None;
- if (Iter != InlineSitesFromRemarks.end()) {
- InlineRecommended = llvm::InlineCost::getAlways("found in replay");
- }
-
- return std::make_unique<DefaultInlineAdvice>(this, CB, InlineRecommended, ORE,
- EmitRemarks);
-}
+//===- ReplayInlineAdvisor.cpp - Replay InlineAdvisor ---------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements ReplayInlineAdvisor that replays inline decisions based
+// on previous inline remarks from optimization remark log. This is a best
+// effort approach useful for testing compiler/source changes while holding
+// inlining steady.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/ReplayInlineAdvisor.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Support/LineIterator.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "inline-replay"
+
+ReplayInlineAdvisor::ReplayInlineAdvisor(
+ Module &M, FunctionAnalysisManager &FAM, LLVMContext &Context,
+ std::unique_ptr<InlineAdvisor> OriginalAdvisor, StringRef RemarksFile,
+ bool EmitRemarks)
+ : InlineAdvisor(M, FAM), OriginalAdvisor(std::move(OriginalAdvisor)),
+ HasReplayRemarks(false), EmitRemarks(EmitRemarks) {
+ auto BufferOrErr = MemoryBuffer::getFileOrSTDIN(RemarksFile);
+ std::error_code EC = BufferOrErr.getError();
+ if (EC) {
+ Context.emitError("Could not open remarks file: " + EC.message());
+ return;
+ }
+
+ // Example for inline remarks to parse:
+ // main:3:1.1: _Z3subii inlined into main at callsite sum:1 @ main:3:1.1
+ // We use the callsite string after `at callsite` to replay inlining.
+ line_iterator LineIt(*BufferOrErr.get(), /*SkipBlanks=*/true);
+ for (; !LineIt.is_at_eof(); ++LineIt) {
+ StringRef Line = *LineIt;
+ auto Pair = Line.split(" at callsite ");
+
+ auto Callee = Pair.first.split(" inlined into").first.rsplit(": ").second;
+
+ auto CallSite = Pair.second.split(";").first;
+
+ if (Callee.empty() || CallSite.empty())
+ continue;
+
+ std::string Combined = (Callee + CallSite).str();
+ InlineSitesFromRemarks.insert(Combined);
+ }
+
+ HasReplayRemarks = true;
+}
+
+std::unique_ptr<InlineAdvice> ReplayInlineAdvisor::getAdviceImpl(CallBase &CB) {
+ assert(HasReplayRemarks);
+
+ Function &Caller = *CB.getCaller();
+ auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(Caller);
+
+ if (InlineSitesFromRemarks.empty())
+ return std::make_unique<DefaultInlineAdvice>(this, CB, None, ORE,
+ EmitRemarks);
+
+ std::string CallSiteLoc = getCallSiteLocation(CB.getDebugLoc());
+ StringRef Callee = CB.getCalledFunction()->getName();
+ std::string Combined = (Callee + CallSiteLoc).str();
+ auto Iter = InlineSitesFromRemarks.find(Combined);
+
+ Optional<InlineCost> InlineRecommended = None;
+ if (Iter != InlineSitesFromRemarks.end()) {
+ InlineRecommended = llvm::InlineCost::getAlways("found in replay");
+ }
+
+ return std::make_unique<DefaultInlineAdvice>(this, CB, InlineRecommended, ORE,
+ EmitRemarks);
+}
diff --git a/contrib/libs/llvm12/lib/Analysis/ScalarEvolution.cpp b/contrib/libs/llvm12/lib/Analysis/ScalarEvolution.cpp
index 5ff63868c9..1a9ae68573 100644
--- a/contrib/libs/llvm12/lib/Analysis/ScalarEvolution.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/ScalarEvolution.cpp
@@ -135,7 +135,7 @@
#include <vector>
using namespace llvm;
-using namespace PatternMatch;
+using namespace PatternMatch;
#define DEBUG_TYPE "scalar-evolution"
@@ -227,11 +227,11 @@ ClassifyExpressions("scalar-evolution-classify-expressions",
cl::Hidden, cl::init(true),
cl::desc("When printing analysis, include information on every instruction"));
-static cl::opt<bool> UseExpensiveRangeSharpening(
- "scalar-evolution-use-expensive-range-sharpening", cl::Hidden,
- cl::init(false),
- cl::desc("Use more powerful methods of sharpening expression ranges. May "
- "be costly in terms of compile time"));
+static cl::opt<bool> UseExpensiveRangeSharpening(
+ "scalar-evolution-use-expensive-range-sharpening", cl::Hidden,
+ cl::init(false),
+ cl::desc("Use more powerful methods of sharpening expression ranges. May "
+ "be costly in terms of compile time"));
//===----------------------------------------------------------------------===//
// SCEV class definitions
@@ -249,17 +249,17 @@ LLVM_DUMP_METHOD void SCEV::dump() const {
#endif
void SCEV::print(raw_ostream &OS) const {
- switch (getSCEVType()) {
+ switch (getSCEVType()) {
case scConstant:
cast<SCEVConstant>(this)->getValue()->printAsOperand(OS, false);
return;
- case scPtrToInt: {
- const SCEVPtrToIntExpr *PtrToInt = cast<SCEVPtrToIntExpr>(this);
- const SCEV *Op = PtrToInt->getOperand();
- OS << "(ptrtoint " << *Op->getType() << " " << *Op << " to "
- << *PtrToInt->getType() << ")";
- return;
- }
+ case scPtrToInt: {
+ const SCEVPtrToIntExpr *PtrToInt = cast<SCEVPtrToIntExpr>(this);
+ const SCEV *Op = PtrToInt->getOperand();
+ OS << "(ptrtoint " << *Op->getType() << " " << *Op << " to "
+ << *PtrToInt->getType() << ")";
+ return;
+ }
case scTruncate: {
const SCEVTruncateExpr *Trunc = cast<SCEVTruncateExpr>(this);
const SCEV *Op = Trunc->getOperand();
@@ -317,8 +317,8 @@ void SCEV::print(raw_ostream &OS) const {
case scSMinExpr:
OpStr = " smin ";
break;
- default:
- llvm_unreachable("There are no other nary expression types.");
+ default:
+ llvm_unreachable("There are no other nary expression types.");
}
OS << "(";
for (SCEVNAryExpr::op_iterator I = NAry->op_begin(), E = NAry->op_end();
@@ -335,10 +335,10 @@ void SCEV::print(raw_ostream &OS) const {
OS << "<nuw>";
if (NAry->hasNoSignedWrap())
OS << "<nsw>";
- break;
- default:
- // Nothing to print for other nary expressions.
- break;
+ break;
+ default:
+ // Nothing to print for other nary expressions.
+ break;
}
return;
}
@@ -380,10 +380,10 @@ void SCEV::print(raw_ostream &OS) const {
}
Type *SCEV::getType() const {
- switch (getSCEVType()) {
+ switch (getSCEVType()) {
case scConstant:
return cast<SCEVConstant>(this)->getType();
- case scPtrToInt:
+ case scPtrToInt:
case scTruncate:
case scZeroExtend:
case scSignExtend:
@@ -465,42 +465,42 @@ ScalarEvolution::getConstant(Type *Ty, uint64_t V, bool isSigned) {
return getConstant(ConstantInt::get(ITy, V, isSigned));
}
-SCEVCastExpr::SCEVCastExpr(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy,
- const SCEV *op, Type *ty)
- : SCEV(ID, SCEVTy, computeExpressionSize(op)), Ty(ty) {
- Operands[0] = op;
-}
-
-SCEVPtrToIntExpr::SCEVPtrToIntExpr(const FoldingSetNodeIDRef ID, const SCEV *Op,
- Type *ITy)
- : SCEVCastExpr(ID, scPtrToInt, Op, ITy) {
- assert(getOperand()->getType()->isPointerTy() && Ty->isIntegerTy() &&
- "Must be a non-bit-width-changing pointer-to-integer cast!");
-}
-
-SCEVIntegralCastExpr::SCEVIntegralCastExpr(const FoldingSetNodeIDRef ID,
- SCEVTypes SCEVTy, const SCEV *op,
- Type *ty)
- : SCEVCastExpr(ID, SCEVTy, op, ty) {}
-
-SCEVTruncateExpr::SCEVTruncateExpr(const FoldingSetNodeIDRef ID, const SCEV *op,
- Type *ty)
- : SCEVIntegralCastExpr(ID, scTruncate, op, ty) {
- assert(getOperand()->getType()->isIntOrPtrTy() && Ty->isIntOrPtrTy() &&
+SCEVCastExpr::SCEVCastExpr(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy,
+ const SCEV *op, Type *ty)
+ : SCEV(ID, SCEVTy, computeExpressionSize(op)), Ty(ty) {
+ Operands[0] = op;
+}
+
+SCEVPtrToIntExpr::SCEVPtrToIntExpr(const FoldingSetNodeIDRef ID, const SCEV *Op,
+ Type *ITy)
+ : SCEVCastExpr(ID, scPtrToInt, Op, ITy) {
+ assert(getOperand()->getType()->isPointerTy() && Ty->isIntegerTy() &&
+ "Must be a non-bit-width-changing pointer-to-integer cast!");
+}
+
+SCEVIntegralCastExpr::SCEVIntegralCastExpr(const FoldingSetNodeIDRef ID,
+ SCEVTypes SCEVTy, const SCEV *op,
+ Type *ty)
+ : SCEVCastExpr(ID, SCEVTy, op, ty) {}
+
+SCEVTruncateExpr::SCEVTruncateExpr(const FoldingSetNodeIDRef ID, const SCEV *op,
+ Type *ty)
+ : SCEVIntegralCastExpr(ID, scTruncate, op, ty) {
+ assert(getOperand()->getType()->isIntOrPtrTy() && Ty->isIntOrPtrTy() &&
"Cannot truncate non-integer value!");
}
SCEVZeroExtendExpr::SCEVZeroExtendExpr(const FoldingSetNodeIDRef ID,
const SCEV *op, Type *ty)
- : SCEVIntegralCastExpr(ID, scZeroExtend, op, ty) {
- assert(getOperand()->getType()->isIntOrPtrTy() && Ty->isIntOrPtrTy() &&
+ : SCEVIntegralCastExpr(ID, scZeroExtend, op, ty) {
+ assert(getOperand()->getType()->isIntOrPtrTy() && Ty->isIntOrPtrTy() &&
"Cannot zero extend non-integer value!");
}
SCEVSignExtendExpr::SCEVSignExtendExpr(const FoldingSetNodeIDRef ID,
const SCEV *op, Type *ty)
- : SCEVIntegralCastExpr(ID, scSignExtend, op, ty) {
- assert(getOperand()->getType()->isIntOrPtrTy() && Ty->isIntOrPtrTy() &&
+ : SCEVIntegralCastExpr(ID, scSignExtend, op, ty) {
+ assert(getOperand()->getType()->isIntOrPtrTy() && Ty->isIntOrPtrTy() &&
"Cannot sign extend non-integer value!");
}
@@ -699,7 +699,7 @@ static int CompareSCEVComplexity(
return 0;
// Primarily, sort the SCEVs by their getSCEVType().
- SCEVTypes LType = LHS->getSCEVType(), RType = RHS->getSCEVType();
+ SCEVTypes LType = LHS->getSCEVType(), RType = RHS->getSCEVType();
if (LType != RType)
return (int)LType - (int)RType;
@@ -708,7 +708,7 @@ static int CompareSCEVComplexity(
// Aside from the getSCEVType() ordering, the particular ordering
// isn't very important except that it's beneficial to be consistent,
// so that (a + b) and (b + a) don't end up as different expressions.
- switch (LType) {
+ switch (LType) {
case scUnknown: {
const SCEVUnknown *LU = cast<SCEVUnknown>(LHS);
const SCEVUnknown *RU = cast<SCEVUnknown>(RHS);
@@ -810,7 +810,7 @@ static int CompareSCEVComplexity(
return X;
}
- case scPtrToInt:
+ case scPtrToInt:
case scTruncate:
case scZeroExtend:
case scSignExtend: {
@@ -1034,115 +1034,115 @@ const SCEV *SCEVAddRecExpr::evaluateAtIteration(const SCEV *It,
// SCEV Expression folder implementations
//===----------------------------------------------------------------------===//
-const SCEV *ScalarEvolution::getPtrToIntExpr(const SCEV *Op, Type *Ty,
- unsigned Depth) {
- assert(Ty->isIntegerTy() && "Target type must be an integer type!");
- assert(Depth <= 1 && "getPtrToIntExpr() should self-recurse at most once.");
-
- // We could be called with an integer-typed operands during SCEV rewrites.
- // Since the operand is an integer already, just perform zext/trunc/self cast.
- if (!Op->getType()->isPointerTy())
- return getTruncateOrZeroExtend(Op, Ty);
-
- // What would be an ID for such a SCEV cast expression?
- FoldingSetNodeID ID;
- ID.AddInteger(scPtrToInt);
- ID.AddPointer(Op);
-
- void *IP = nullptr;
-
- // Is there already an expression for such a cast?
- if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP))
- return getTruncateOrZeroExtend(S, Ty);
-
- // If not, is this expression something we can't reduce any further?
- if (isa<SCEVUnknown>(Op)) {
- // Create an explicit cast node.
- // We can reuse the existing insert position since if we get here,
- // we won't have made any changes which would invalidate it.
- Type *IntPtrTy = getDataLayout().getIntPtrType(Op->getType());
- assert(getDataLayout().getTypeSizeInBits(getEffectiveSCEVType(
- Op->getType())) == getDataLayout().getTypeSizeInBits(IntPtrTy) &&
- "We can only model ptrtoint if SCEV's effective (integer) type is "
- "sufficiently wide to represent all possible pointer values.");
- SCEV *S = new (SCEVAllocator)
- SCEVPtrToIntExpr(ID.Intern(SCEVAllocator), Op, IntPtrTy);
- UniqueSCEVs.InsertNode(S, IP);
- addToLoopUseLists(S);
- return getTruncateOrZeroExtend(S, Ty);
- }
-
- assert(Depth == 0 &&
- "getPtrToIntExpr() should not self-recurse for non-SCEVUnknown's.");
-
- // Otherwise, we've got some expression that is more complex than just a
- // single SCEVUnknown. But we don't want to have a SCEVPtrToIntExpr of an
- // arbitrary expression, we want to have SCEVPtrToIntExpr of an SCEVUnknown
- // only, and the expressions must otherwise be integer-typed.
- // So sink the cast down to the SCEVUnknown's.
-
- /// The SCEVPtrToIntSinkingRewriter takes a scalar evolution expression,
- /// which computes a pointer-typed value, and rewrites the whole expression
- /// tree so that *all* the computations are done on integers, and the only
- /// pointer-typed operands in the expression are SCEVUnknown.
- class SCEVPtrToIntSinkingRewriter
- : public SCEVRewriteVisitor<SCEVPtrToIntSinkingRewriter> {
- using Base = SCEVRewriteVisitor<SCEVPtrToIntSinkingRewriter>;
-
- public:
- SCEVPtrToIntSinkingRewriter(ScalarEvolution &SE) : SCEVRewriteVisitor(SE) {}
-
- static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE) {
- SCEVPtrToIntSinkingRewriter Rewriter(SE);
- return Rewriter.visit(Scev);
- }
-
- const SCEV *visit(const SCEV *S) {
- Type *STy = S->getType();
- // If the expression is not pointer-typed, just keep it as-is.
- if (!STy->isPointerTy())
- return S;
- // Else, recursively sink the cast down into it.
- return Base::visit(S);
- }
-
- const SCEV *visitAddExpr(const SCEVAddExpr *Expr) {
- SmallVector<const SCEV *, 2> Operands;
- bool Changed = false;
- for (auto *Op : Expr->operands()) {
- Operands.push_back(visit(Op));
- Changed |= Op != Operands.back();
- }
- return !Changed ? Expr : SE.getAddExpr(Operands, Expr->getNoWrapFlags());
- }
-
- const SCEV *visitMulExpr(const SCEVMulExpr *Expr) {
- SmallVector<const SCEV *, 2> Operands;
- bool Changed = false;
- for (auto *Op : Expr->operands()) {
- Operands.push_back(visit(Op));
- Changed |= Op != Operands.back();
- }
- return !Changed ? Expr : SE.getMulExpr(Operands, Expr->getNoWrapFlags());
- }
-
- const SCEV *visitUnknown(const SCEVUnknown *Expr) {
- Type *ExprPtrTy = Expr->getType();
- assert(ExprPtrTy->isPointerTy() &&
- "Should only reach pointer-typed SCEVUnknown's.");
- Type *ExprIntPtrTy = SE.getDataLayout().getIntPtrType(ExprPtrTy);
- return SE.getPtrToIntExpr(Expr, ExprIntPtrTy, /*Depth=*/1);
- }
- };
-
- // And actually perform the cast sinking.
- const SCEV *IntOp = SCEVPtrToIntSinkingRewriter::rewrite(Op, *this);
- assert(IntOp->getType()->isIntegerTy() &&
- "We must have succeeded in sinking the cast, "
- "and ending up with an integer-typed expression!");
- return getTruncateOrZeroExtend(IntOp, Ty);
-}
-
+const SCEV *ScalarEvolution::getPtrToIntExpr(const SCEV *Op, Type *Ty,
+ unsigned Depth) {
+ assert(Ty->isIntegerTy() && "Target type must be an integer type!");
+ assert(Depth <= 1 && "getPtrToIntExpr() should self-recurse at most once.");
+
+ // We could be called with an integer-typed operands during SCEV rewrites.
+ // Since the operand is an integer already, just perform zext/trunc/self cast.
+ if (!Op->getType()->isPointerTy())
+ return getTruncateOrZeroExtend(Op, Ty);
+
+ // What would be an ID for such a SCEV cast expression?
+ FoldingSetNodeID ID;
+ ID.AddInteger(scPtrToInt);
+ ID.AddPointer(Op);
+
+ void *IP = nullptr;
+
+ // Is there already an expression for such a cast?
+ if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP))
+ return getTruncateOrZeroExtend(S, Ty);
+
+ // If not, is this expression something we can't reduce any further?
+ if (isa<SCEVUnknown>(Op)) {
+ // Create an explicit cast node.
+ // We can reuse the existing insert position since if we get here,
+ // we won't have made any changes which would invalidate it.
+ Type *IntPtrTy = getDataLayout().getIntPtrType(Op->getType());
+ assert(getDataLayout().getTypeSizeInBits(getEffectiveSCEVType(
+ Op->getType())) == getDataLayout().getTypeSizeInBits(IntPtrTy) &&
+ "We can only model ptrtoint if SCEV's effective (integer) type is "
+ "sufficiently wide to represent all possible pointer values.");
+ SCEV *S = new (SCEVAllocator)
+ SCEVPtrToIntExpr(ID.Intern(SCEVAllocator), Op, IntPtrTy);
+ UniqueSCEVs.InsertNode(S, IP);
+ addToLoopUseLists(S);
+ return getTruncateOrZeroExtend(S, Ty);
+ }
+
+ assert(Depth == 0 &&
+ "getPtrToIntExpr() should not self-recurse for non-SCEVUnknown's.");
+
+ // Otherwise, we've got some expression that is more complex than just a
+ // single SCEVUnknown. But we don't want to have a SCEVPtrToIntExpr of an
+ // arbitrary expression, we want to have SCEVPtrToIntExpr of an SCEVUnknown
+ // only, and the expressions must otherwise be integer-typed.
+ // So sink the cast down to the SCEVUnknown's.
+
+ /// The SCEVPtrToIntSinkingRewriter takes a scalar evolution expression,
+ /// which computes a pointer-typed value, and rewrites the whole expression
+ /// tree so that *all* the computations are done on integers, and the only
+ /// pointer-typed operands in the expression are SCEVUnknown.
+ class SCEVPtrToIntSinkingRewriter
+ : public SCEVRewriteVisitor<SCEVPtrToIntSinkingRewriter> {
+ using Base = SCEVRewriteVisitor<SCEVPtrToIntSinkingRewriter>;
+
+ public:
+ SCEVPtrToIntSinkingRewriter(ScalarEvolution &SE) : SCEVRewriteVisitor(SE) {}
+
+ static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE) {
+ SCEVPtrToIntSinkingRewriter Rewriter(SE);
+ return Rewriter.visit(Scev);
+ }
+
+ const SCEV *visit(const SCEV *S) {
+ Type *STy = S->getType();
+ // If the expression is not pointer-typed, just keep it as-is.
+ if (!STy->isPointerTy())
+ return S;
+ // Else, recursively sink the cast down into it.
+ return Base::visit(S);
+ }
+
+ const SCEV *visitAddExpr(const SCEVAddExpr *Expr) {
+ SmallVector<const SCEV *, 2> Operands;
+ bool Changed = false;
+ for (auto *Op : Expr->operands()) {
+ Operands.push_back(visit(Op));
+ Changed |= Op != Operands.back();
+ }
+ return !Changed ? Expr : SE.getAddExpr(Operands, Expr->getNoWrapFlags());
+ }
+
+ const SCEV *visitMulExpr(const SCEVMulExpr *Expr) {
+ SmallVector<const SCEV *, 2> Operands;
+ bool Changed = false;
+ for (auto *Op : Expr->operands()) {
+ Operands.push_back(visit(Op));
+ Changed |= Op != Operands.back();
+ }
+ return !Changed ? Expr : SE.getMulExpr(Operands, Expr->getNoWrapFlags());
+ }
+
+ const SCEV *visitUnknown(const SCEVUnknown *Expr) {
+ Type *ExprPtrTy = Expr->getType();
+ assert(ExprPtrTy->isPointerTy() &&
+ "Should only reach pointer-typed SCEVUnknown's.");
+ Type *ExprIntPtrTy = SE.getDataLayout().getIntPtrType(ExprPtrTy);
+ return SE.getPtrToIntExpr(Expr, ExprIntPtrTy, /*Depth=*/1);
+ }
+ };
+
+ // And actually perform the cast sinking.
+ const SCEV *IntOp = SCEVPtrToIntSinkingRewriter::rewrite(Op, *this);
+ assert(IntOp->getType()->isIntegerTy() &&
+ "We must have succeeded in sinking the cast, "
+ "and ending up with an integer-typed expression!");
+ return getTruncateOrZeroExtend(IntOp, Ty);
+}
+
const SCEV *ScalarEvolution::getTruncateExpr(const SCEV *Op, Type *Ty,
unsigned Depth) {
assert(getTypeSizeInBits(Op->getType()) > getTypeSizeInBits(Ty) &&
@@ -1194,8 +1194,8 @@ const SCEV *ScalarEvolution::getTruncateExpr(const SCEV *Op, Type *Ty,
for (unsigned i = 0, e = CommOp->getNumOperands(); i != e && numTruncs < 2;
++i) {
const SCEV *S = getTruncateExpr(CommOp->getOperand(i), Ty, Depth + 1);
- if (!isa<SCEVIntegralCastExpr>(CommOp->getOperand(i)) &&
- isa<SCEVTruncateExpr>(S))
+ if (!isa<SCEVIntegralCastExpr>(CommOp->getOperand(i)) &&
+ isa<SCEVTruncateExpr>(S))
numTruncs++;
Operands.push_back(S);
}
@@ -1222,11 +1222,11 @@ const SCEV *ScalarEvolution::getTruncateExpr(const SCEV *Op, Type *Ty,
return getAddRecExpr(Operands, AddRec->getLoop(), SCEV::FlagAnyWrap);
}
- // Return zero if truncating to known zeros.
- uint32_t MinTrailingZeros = GetMinTrailingZeros(Op);
- if (MinTrailingZeros >= getTypeSizeInBits(Ty))
- return getZero(Ty);
-
+ // Return zero if truncating to known zeros.
+ uint32_t MinTrailingZeros = GetMinTrailingZeros(Op);
+ if (MinTrailingZeros >= getTypeSizeInBits(Ty))
+ return getZero(Ty);
+
// The cast wasn't folded; create an explicit cast node. We can reuse
// the existing insert position since if we get here, we won't have
// made any changes which would invalidate it.
@@ -1387,7 +1387,7 @@ static const SCEV *getPreStartForExtend(const SCEVAddRecExpr *AR, Type *Ty,
// If we know `AR` == {`PreStart`+`Step`,+,`Step`} is `WrapType` (FlagNSW
// or FlagNUW) and that `PreStart` + `Step` is `WrapType` too, then
// `PreAR` == {`PreStart`,+,`Step`} is also `WrapType`. Cache this fact.
- SE->setNoWrapFlags(const_cast<SCEVAddRecExpr *>(PreAR), WrapType);
+ SE->setNoWrapFlags(const_cast<SCEVAddRecExpr *>(PreAR), WrapType);
}
return PreStart;
}
@@ -1591,7 +1591,7 @@ ScalarEvolution::getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
if (!AR->hasNoUnsignedWrap()) {
auto NewFlags = proveNoWrapViaConstantRanges(AR);
- setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), NewFlags);
+ setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), NewFlags);
}
// If we have special knowledge that this addrec won't overflow,
@@ -1611,7 +1611,7 @@ ScalarEvolution::getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
// that value once it has finished.
const SCEV *MaxBECount = getConstantMaxBackedgeTakenCount(L);
if (!isa<SCEVCouldNotCompute>(MaxBECount)) {
- // Manually compute the final value for AR, checking for overflow.
+ // Manually compute the final value for AR, checking for overflow.
// Check whether the backedge-taken count can be losslessly casted to
// the addrec's type. The count is always unsigned.
@@ -1639,7 +1639,7 @@ ScalarEvolution::getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
SCEV::FlagAnyWrap, Depth + 1);
if (ZAdd == OperandExtendedAdd) {
// Cache knowledge of AR NUW, which is propagated to this AddRec.
- setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNUW);
+ setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNUW);
// Return the expression with the addrec on the outside.
return getAddRecExpr(
getExtendAddRecStart<SCEVZeroExtendExpr>(AR, Ty, this,
@@ -1658,7 +1658,7 @@ ScalarEvolution::getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
if (ZAdd == OperandExtendedAdd) {
// Cache knowledge of AR NW, which is propagated to this AddRec.
// Negative step causes unsigned wrap, but it still can't self-wrap.
- setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNW);
+ setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNW);
// Return the expression with the addrec on the outside.
return getAddRecExpr(
getExtendAddRecStart<SCEVZeroExtendExpr>(AR, Ty, this,
@@ -1678,24 +1678,24 @@ ScalarEvolution::getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
// doing extra work that may not pay off.
if (!isa<SCEVCouldNotCompute>(MaxBECount) || HasGuards ||
!AC.assumptions().empty()) {
-
- auto NewFlags = proveNoUnsignedWrapViaInduction(AR);
- setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), NewFlags);
- if (AR->hasNoUnsignedWrap()) {
- // Same as nuw case above - duplicated here to avoid a compile time
- // issue. It's not clear that the order of checks does matter, but
- // it's one of two issue possible causes for a change which was
- // reverted. Be conservative for the moment.
- return getAddRecExpr(
+
+ auto NewFlags = proveNoUnsignedWrapViaInduction(AR);
+ setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), NewFlags);
+ if (AR->hasNoUnsignedWrap()) {
+ // Same as nuw case above - duplicated here to avoid a compile time
+ // issue. It's not clear that the order of checks does matter, but
+ // it's one of two issue possible causes for a change which was
+ // reverted. Be conservative for the moment.
+ return getAddRecExpr(
getExtendAddRecStart<SCEVZeroExtendExpr>(AR, Ty, this,
Depth + 1),
getZeroExtendExpr(Step, Ty, Depth + 1), L,
AR->getNoWrapFlags());
- }
-
- // For a negative step, we can extend the operands iff doing so only
- // traverses values in the range zext([0,UINT_MAX]).
- if (isKnownNegative(Step)) {
+ }
+
+ // For a negative step, we can extend the operands iff doing so only
+ // traverses values in the range zext([0,UINT_MAX]).
+ if (isKnownNegative(Step)) {
const SCEV *N = getConstant(APInt::getMaxValue(BitWidth) -
getSignedRangeMin(Step));
if (isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_UGT, AR, N) ||
@@ -1703,7 +1703,7 @@ ScalarEvolution::getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
// Cache knowledge of AR NW, which is propagated to this
// AddRec. Negative step causes unsigned wrap, but it
// still can't self-wrap.
- setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNW);
+ setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNW);
// Return the expression with the addrec on the outside.
return getAddRecExpr(
getExtendAddRecStart<SCEVZeroExtendExpr>(AR, Ty, this,
@@ -1732,7 +1732,7 @@ ScalarEvolution::getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
}
if (proveNoWrapByVaryingStart<SCEVZeroExtendExpr>(Start, Step, L)) {
- setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNUW);
+ setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNUW);
return getAddRecExpr(
getExtendAddRecStart<SCEVZeroExtendExpr>(AR, Ty, this, Depth + 1),
getZeroExtendExpr(Step, Ty, Depth + 1), L, AR->getNoWrapFlags());
@@ -1931,7 +1931,7 @@ ScalarEvolution::getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
if (!AR->hasNoSignedWrap()) {
auto NewFlags = proveNoWrapViaConstantRanges(AR);
- setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), NewFlags);
+ setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), NewFlags);
}
// If we have special knowledge that this addrec won't overflow,
@@ -1980,7 +1980,7 @@ ScalarEvolution::getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
SCEV::FlagAnyWrap, Depth + 1);
if (SAdd == OperandExtendedAdd) {
// Cache knowledge of AR NSW, which is propagated to this AddRec.
- setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNSW);
+ setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNSW);
// Return the expression with the addrec on the outside.
return getAddRecExpr(
getExtendAddRecStart<SCEVSignExtendExpr>(AR, Ty, this,
@@ -2005,7 +2005,7 @@ ScalarEvolution::getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
// Thus (AR is not NW => SAdd != OperandExtendedAdd) <=>
// (SAdd == OperandExtendedAdd => AR is NW)
- setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNW);
+ setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNW);
// Return the expression with the addrec on the outside.
return getAddRecExpr(
@@ -2017,16 +2017,16 @@ ScalarEvolution::getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
}
}
- auto NewFlags = proveNoSignedWrapViaInduction(AR);
- setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), NewFlags);
- if (AR->hasNoSignedWrap()) {
- // Same as nsw case above - duplicated here to avoid a compile time
- // issue. It's not clear that the order of checks does matter, but
- // it's one of two issue possible causes for a change which was
- // reverted. Be conservative for the moment.
- return getAddRecExpr(
- getExtendAddRecStart<SCEVSignExtendExpr>(AR, Ty, this, Depth + 1),
- getSignExtendExpr(Step, Ty, Depth + 1), L, AR->getNoWrapFlags());
+ auto NewFlags = proveNoSignedWrapViaInduction(AR);
+ setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), NewFlags);
+ if (AR->hasNoSignedWrap()) {
+ // Same as nsw case above - duplicated here to avoid a compile time
+ // issue. It's not clear that the order of checks does matter, but
+ // it's one of two issue possible causes for a change which was
+ // reverted. Be conservative for the moment.
+ return getAddRecExpr(
+ getExtendAddRecStart<SCEVSignExtendExpr>(AR, Ty, this, Depth + 1),
+ getSignExtendExpr(Step, Ty, Depth + 1), L, AR->getNoWrapFlags());
}
// sext({C,+,Step}) --> (sext(D) + sext({C-D,+,Step}))<nuw><nsw>
@@ -2047,7 +2047,7 @@ ScalarEvolution::getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
}
if (proveNoWrapByVaryingStart<SCEVSignExtendExpr>(Start, Step, L)) {
- setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNSW);
+ setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNSW);
return getAddRecExpr(
getExtendAddRecStart<SCEVSignExtendExpr>(AR, Ty, this, Depth + 1),
getSignExtendExpr(Step, Ty, Depth + 1), L, AR->getNoWrapFlags());
@@ -2177,7 +2177,7 @@ CollectAddOperandsWithScales(DenseMap<const SCEV *, APInt> &M,
} else {
// A multiplication of a constant with some other value. Update
// the map.
- SmallVector<const SCEV *, 4> MulOps(drop_begin(Mul->operands()));
+ SmallVector<const SCEV *, 4> MulOps(drop_begin(Mul->operands()));
const SCEV *Key = SE.getMulExpr(MulOps);
auto Pair = M.insert({Key, NewScale});
if (Pair.second) {
@@ -2281,9 +2281,9 @@ bool ScalarEvolution::isAvailableAtLoopEntry(const SCEV *S, const Loop *L) {
/// Get a canonical add expression, or something simpler if possible.
const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
- SCEV::NoWrapFlags OrigFlags,
+ SCEV::NoWrapFlags OrigFlags,
unsigned Depth) {
- assert(!(OrigFlags & ~(SCEV::FlagNUW | SCEV::FlagNSW)) &&
+ assert(!(OrigFlags & ~(SCEV::FlagNUW | SCEV::FlagNSW)) &&
"only nuw or nsw allowed");
assert(!Ops.empty() && "Cannot get empty add!");
if (Ops.size() == 1) return Ops[0];
@@ -2319,20 +2319,20 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
if (Ops.size() == 1) return Ops[0];
}
- // Delay expensive flag strengthening until necessary.
- auto ComputeFlags = [this, OrigFlags](const ArrayRef<const SCEV *> Ops) {
- return StrengthenNoWrapFlags(this, scAddExpr, Ops, OrigFlags);
- };
-
+ // Delay expensive flag strengthening until necessary.
+ auto ComputeFlags = [this, OrigFlags](const ArrayRef<const SCEV *> Ops) {
+ return StrengthenNoWrapFlags(this, scAddExpr, Ops, OrigFlags);
+ };
+
// Limit recursion calls depth.
if (Depth > MaxArithDepth || hasHugeExpression(Ops))
- return getOrCreateAddExpr(Ops, ComputeFlags(Ops));
+ return getOrCreateAddExpr(Ops, ComputeFlags(Ops));
if (SCEV *S = std::get<0>(findExistingSCEVInCache(scAddExpr, Ops))) {
- // Don't strengthen flags if we have no new information.
- SCEVAddExpr *Add = static_cast<SCEVAddExpr *>(S);
- if (Add->getNoWrapFlags(OrigFlags) != OrigFlags)
- Add->setNoWrapFlags(ComputeFlags(Ops));
+ // Don't strengthen flags if we have no new information.
+ SCEVAddExpr *Add = static_cast<SCEVAddExpr *>(S);
+ if (Add->getNoWrapFlags(OrigFlags) != OrigFlags)
+ Add->setNoWrapFlags(ComputeFlags(Ops));
return S;
}
@@ -2358,7 +2358,7 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
FoundMatch = true;
}
if (FoundMatch)
- return getAddExpr(Ops, OrigFlags, Depth + 1);
+ return getAddExpr(Ops, OrigFlags, Depth + 1);
// Check for truncates. If all the operands are truncated from the same
// type, see if factoring out the truncate would permit the result to be
@@ -2593,16 +2593,16 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
// If we found some loop invariants, fold them into the recurrence.
if (!LIOps.empty()) {
- // Compute nowrap flags for the addition of the loop-invariant ops and
- // the addrec. Temporarily push it as an operand for that purpose.
- LIOps.push_back(AddRec);
- SCEV::NoWrapFlags Flags = ComputeFlags(LIOps);
- LIOps.pop_back();
-
+ // Compute nowrap flags for the addition of the loop-invariant ops and
+ // the addrec. Temporarily push it as an operand for that purpose.
+ LIOps.push_back(AddRec);
+ SCEV::NoWrapFlags Flags = ComputeFlags(LIOps);
+ LIOps.pop_back();
+
// NLI + LI + {Start,+,Step} --> NLI + {LI+Start,+,Step}
LIOps.push_back(AddRec->getStart());
- SmallVector<const SCEV *, 4> AddRecOps(AddRec->operands());
+ SmallVector<const SCEV *, 4> AddRecOps(AddRec->operands());
// This follows from the fact that the no-wrap flags on the outer add
// expression are applicable on the 0th iteration, when the add recurrence
// will be equal to its start value.
@@ -2640,7 +2640,7 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
"AddRecExprs are not sorted in reverse dominance order?");
if (AddRecLoop == cast<SCEVAddRecExpr>(Ops[OtherIdx])->getLoop()) {
// Other + {A,+,B}<L> + {C,+,D}<L> --> Other + {A+C,+,B+D}<L>
- SmallVector<const SCEV *, 4> AddRecOps(AddRec->operands());
+ SmallVector<const SCEV *, 4> AddRecOps(AddRec->operands());
for (; OtherIdx != Ops.size() && isa<SCEVAddRecExpr>(Ops[OtherIdx]);
++OtherIdx) {
const auto *OtherAddRec = cast<SCEVAddRecExpr>(Ops[OtherIdx]);
@@ -2671,7 +2671,7 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
// Okay, it looks like we really DO need an add expr. Check to see if we
// already have one, otherwise create a new one.
- return getOrCreateAddExpr(Ops, ComputeFlags(Ops));
+ return getOrCreateAddExpr(Ops, ComputeFlags(Ops));
}
const SCEV *
@@ -2715,7 +2715,7 @@ ScalarEvolution::getOrCreateAddRecExpr(ArrayRef<const SCEV *> Ops,
UniqueSCEVs.InsertNode(S, IP);
addToLoopUseLists(S);
}
- setNoWrapFlags(S, Flags);
+ setNoWrapFlags(S, Flags);
return S;
}
@@ -2797,9 +2797,9 @@ static bool containsConstantInAddMulChain(const SCEV *StartExpr) {
/// Get a canonical multiply expression, or something simpler if possible.
const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
- SCEV::NoWrapFlags OrigFlags,
+ SCEV::NoWrapFlags OrigFlags,
unsigned Depth) {
- assert(OrigFlags == maskFlags(OrigFlags, SCEV::FlagNUW | SCEV::FlagNSW) &&
+ assert(OrigFlags == maskFlags(OrigFlags, SCEV::FlagNUW | SCEV::FlagNSW) &&
"only nuw or nsw allowed");
assert(!Ops.empty() && "Cannot get empty mul!");
if (Ops.size() == 1) return Ops[0];
@@ -2813,52 +2813,52 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
// Sort by complexity, this groups all similar expression types together.
GroupByComplexity(Ops, &LI, DT);
- // If there are any constants, fold them together.
- unsigned Idx = 0;
- if (const SCEVConstant *LHSC = dyn_cast<SCEVConstant>(Ops[0])) {
- ++Idx;
- assert(Idx < Ops.size());
- while (const SCEVConstant *RHSC = dyn_cast<SCEVConstant>(Ops[Idx])) {
- // We found two constants, fold them together!
- Ops[0] = getConstant(LHSC->getAPInt() * RHSC->getAPInt());
- if (Ops.size() == 2) return Ops[0];
- Ops.erase(Ops.begin()+1); // Erase the folded element
- LHSC = cast<SCEVConstant>(Ops[0]);
- }
-
- // If we have a multiply of zero, it will always be zero.
- if (LHSC->getValue()->isZero())
- return LHSC;
-
- // If we are left with a constant one being multiplied, strip it off.
- if (LHSC->getValue()->isOne()) {
- Ops.erase(Ops.begin());
- --Idx;
- }
-
- if (Ops.size() == 1)
- return Ops[0];
- }
-
- // Delay expensive flag strengthening until necessary.
- auto ComputeFlags = [this, OrigFlags](const ArrayRef<const SCEV *> Ops) {
- return StrengthenNoWrapFlags(this, scMulExpr, Ops, OrigFlags);
- };
-
- // Limit recursion calls depth.
- if (Depth > MaxArithDepth || hasHugeExpression(Ops))
- return getOrCreateMulExpr(Ops, ComputeFlags(Ops));
-
+ // If there are any constants, fold them together.
+ unsigned Idx = 0;
+ if (const SCEVConstant *LHSC = dyn_cast<SCEVConstant>(Ops[0])) {
+ ++Idx;
+ assert(Idx < Ops.size());
+ while (const SCEVConstant *RHSC = dyn_cast<SCEVConstant>(Ops[Idx])) {
+ // We found two constants, fold them together!
+ Ops[0] = getConstant(LHSC->getAPInt() * RHSC->getAPInt());
+ if (Ops.size() == 2) return Ops[0];
+ Ops.erase(Ops.begin()+1); // Erase the folded element
+ LHSC = cast<SCEVConstant>(Ops[0]);
+ }
+
+ // If we have a multiply of zero, it will always be zero.
+ if (LHSC->getValue()->isZero())
+ return LHSC;
+
+ // If we are left with a constant one being multiplied, strip it off.
+ if (LHSC->getValue()->isOne()) {
+ Ops.erase(Ops.begin());
+ --Idx;
+ }
+
+ if (Ops.size() == 1)
+ return Ops[0];
+ }
+
+ // Delay expensive flag strengthening until necessary.
+ auto ComputeFlags = [this, OrigFlags](const ArrayRef<const SCEV *> Ops) {
+ return StrengthenNoWrapFlags(this, scMulExpr, Ops, OrigFlags);
+ };
+
+ // Limit recursion calls depth.
+ if (Depth > MaxArithDepth || hasHugeExpression(Ops))
+ return getOrCreateMulExpr(Ops, ComputeFlags(Ops));
+
if (SCEV *S = std::get<0>(findExistingSCEVInCache(scMulExpr, Ops))) {
- // Don't strengthen flags if we have no new information.
- SCEVMulExpr *Mul = static_cast<SCEVMulExpr *>(S);
- if (Mul->getNoWrapFlags(OrigFlags) != OrigFlags)
- Mul->setNoWrapFlags(ComputeFlags(Ops));
+ // Don't strengthen flags if we have no new information.
+ SCEVMulExpr *Mul = static_cast<SCEVMulExpr *>(S);
+ if (Mul->getNoWrapFlags(OrigFlags) != OrigFlags)
+ Mul->setNoWrapFlags(ComputeFlags(Ops));
return S;
}
if (const SCEVConstant *LHSC = dyn_cast<SCEVConstant>(Ops[0])) {
- if (Ops.size() == 2) {
+ if (Ops.size() == 2) {
// C1*(C2+V) -> C1*C2 + C1*V
if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(Ops[1]))
// If any of Add's ops are Adds or Muls with a constant, apply this
@@ -2874,9 +2874,9 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
SCEV::FlagAnyWrap, Depth + 1),
SCEV::FlagAnyWrap, Depth + 1);
- if (Ops[0]->isAllOnesValue()) {
- // If we have a mul by -1 of an add, try distributing the -1 among the
- // add operands.
+ if (Ops[0]->isAllOnesValue()) {
+ // If we have a mul by -1 of an add, try distributing the -1 among the
+ // add operands.
if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(Ops[1])) {
SmallVector<const SCEV *, 4> NewOps;
bool AnyFolded = false;
@@ -2961,9 +2961,9 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
//
// No self-wrap cannot be guaranteed after changing the step size, but
// will be inferred if either NUW or NSW is true.
- SCEV::NoWrapFlags Flags = ComputeFlags({Scale, AddRec});
- const SCEV *NewRec = getAddRecExpr(
- NewOps, AddRecLoop, AddRec->getNoWrapFlags(Flags));
+ SCEV::NoWrapFlags Flags = ComputeFlags({Scale, AddRec});
+ const SCEV *NewRec = getAddRecExpr(
+ NewOps, AddRecLoop, AddRec->getNoWrapFlags(Flags));
// If all of the other operands were loop invariant, we are done.
if (Ops.size() == 1) return NewRec;
@@ -3056,7 +3056,7 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
// Okay, it looks like we really DO need an mul expr. Check to see if we
// already have one, otherwise create a new one.
- return getOrCreateMulExpr(Ops, ComputeFlags(Ops));
+ return getOrCreateMulExpr(Ops, ComputeFlags(Ops));
}
/// Represents an unsigned remainder expression based on unsigned division.
@@ -3180,7 +3180,7 @@ const SCEV *ScalarEvolution::getUDivExpr(const SCEV *LHS,
const SCEV *Op = M->getOperand(i);
const SCEV *Div = getUDivExpr(Op, RHSC);
if (!isa<SCEVUDivExpr>(Div) && getMulExpr(Div, RHSC) == Op) {
- Operands = SmallVector<const SCEV *, 4>(M->operands());
+ Operands = SmallVector<const SCEV *, 4>(M->operands());
Operands[i] = Div;
return getMulExpr(Operands);
}
@@ -3274,7 +3274,7 @@ const SCEV *ScalarEvolution::getUDivExactExpr(const SCEV *LHS,
// first element of the mulexpr.
if (const auto *LHSCst = dyn_cast<SCEVConstant>(Mul->getOperand(0))) {
if (LHSCst == RHSCst) {
- SmallVector<const SCEV *, 2> Operands(drop_begin(Mul->operands()));
+ SmallVector<const SCEV *, 2> Operands(drop_begin(Mul->operands()));
return getMulExpr(Operands);
}
@@ -3364,7 +3364,7 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
? (L->getLoopDepth() < NestedLoop->getLoopDepth())
: (!NestedLoop->contains(L) &&
DT.dominates(L->getHeader(), NestedLoop->getHeader()))) {
- SmallVector<const SCEV *, 4> NestedOperands(NestedAR->operands());
+ SmallVector<const SCEV *, 4> NestedOperands(NestedAR->operands());
Operands[0] = NestedAR->getStart();
// AddRecs require their operands be loop-invariant with respect to their
// loops. Don't perform this transformation if it would break this
@@ -3417,12 +3417,12 @@ ScalarEvolution::getGEPExpr(GEPOperator *GEP,
// flow and the no-overflow bits may not be valid for the expression in any
// context. This can be fixed similarly to how these flags are handled for
// adds.
- SCEV::NoWrapFlags OffsetWrap =
- GEP->isInBounds() ? SCEV::FlagNSW : SCEV::FlagAnyWrap;
+ SCEV::NoWrapFlags OffsetWrap =
+ GEP->isInBounds() ? SCEV::FlagNSW : SCEV::FlagAnyWrap;
Type *CurTy = GEP->getType();
bool FirstIter = true;
- SmallVector<const SCEV *, 4> Offsets;
+ SmallVector<const SCEV *, 4> Offsets;
for (const SCEV *IndexExpr : IndexExprs) {
// Compute the (potentially symbolic) offset in bytes for this index.
if (StructType *STy = dyn_cast<StructType>(CurTy)) {
@@ -3430,7 +3430,7 @@ ScalarEvolution::getGEPExpr(GEPOperator *GEP,
ConstantInt *Index = cast<SCEVConstant>(IndexExpr)->getValue();
unsigned FieldNo = Index->getZExtValue();
const SCEV *FieldOffset = getOffsetOfExpr(IntIdxTy, STy, FieldNo);
- Offsets.push_back(FieldOffset);
+ Offsets.push_back(FieldOffset);
// Update CurTy to the type of the field at Index.
CurTy = STy->getTypeAtIndex(Index);
@@ -3450,27 +3450,27 @@ ScalarEvolution::getGEPExpr(GEPOperator *GEP,
IndexExpr = getTruncateOrSignExtend(IndexExpr, IntIdxTy);
// Multiply the index by the element size to compute the element offset.
- const SCEV *LocalOffset = getMulExpr(IndexExpr, ElementSize, OffsetWrap);
- Offsets.push_back(LocalOffset);
+ const SCEV *LocalOffset = getMulExpr(IndexExpr, ElementSize, OffsetWrap);
+ Offsets.push_back(LocalOffset);
}
}
- // Handle degenerate case of GEP without offsets.
- if (Offsets.empty())
- return BaseExpr;
-
- // Add the offsets together, assuming nsw if inbounds.
- const SCEV *Offset = getAddExpr(Offsets, OffsetWrap);
- // Add the base address and the offset. We cannot use the nsw flag, as the
- // base address is unsigned. However, if we know that the offset is
- // non-negative, we can use nuw.
- SCEV::NoWrapFlags BaseWrap = GEP->isInBounds() && isKnownNonNegative(Offset)
- ? SCEV::FlagNUW : SCEV::FlagAnyWrap;
- return getAddExpr(BaseExpr, Offset, BaseWrap);
+ // Handle degenerate case of GEP without offsets.
+ if (Offsets.empty())
+ return BaseExpr;
+
+ // Add the offsets together, assuming nsw if inbounds.
+ const SCEV *Offset = getAddExpr(Offsets, OffsetWrap);
+ // Add the base address and the offset. We cannot use the nsw flag, as the
+ // base address is unsigned. However, if we know that the offset is
+ // non-negative, we can use nuw.
+ SCEV::NoWrapFlags BaseWrap = GEP->isInBounds() && isKnownNonNegative(Offset)
+ ? SCEV::FlagNUW : SCEV::FlagAnyWrap;
+ return getAddExpr(BaseExpr, Offset, BaseWrap);
}
std::tuple<SCEV *, FoldingSetNodeID, void *>
-ScalarEvolution::findExistingSCEVInCache(SCEVTypes SCEVType,
+ScalarEvolution::findExistingSCEVInCache(SCEVTypes SCEVType,
ArrayRef<const SCEV *> Ops) {
FoldingSetNodeID ID;
void *IP = nullptr;
@@ -3481,17 +3481,17 @@ ScalarEvolution::findExistingSCEVInCache(SCEVTypes SCEVType,
UniqueSCEVs.FindNodeOrInsertPos(ID, IP), std::move(ID), IP);
}
-const SCEV *ScalarEvolution::getAbsExpr(const SCEV *Op, bool IsNSW) {
- SCEV::NoWrapFlags Flags = IsNSW ? SCEV::FlagNSW : SCEV::FlagAnyWrap;
- return getSMaxExpr(Op, getNegativeSCEV(Op, Flags));
-}
-
-const SCEV *ScalarEvolution::getSignumExpr(const SCEV *Op) {
- Type *Ty = Op->getType();
- return getSMinExpr(getSMaxExpr(Op, getMinusOne(Ty)), getOne(Ty));
-}
-
-const SCEV *ScalarEvolution::getMinMaxExpr(SCEVTypes Kind,
+const SCEV *ScalarEvolution::getAbsExpr(const SCEV *Op, bool IsNSW) {
+ SCEV::NoWrapFlags Flags = IsNSW ? SCEV::FlagNSW : SCEV::FlagAnyWrap;
+ return getSMaxExpr(Op, getNegativeSCEV(Op, Flags));
+}
+
+const SCEV *ScalarEvolution::getSignumExpr(const SCEV *Op) {
+ Type *Ty = Op->getType();
+ return getSMinExpr(getSMaxExpr(Op, getMinusOne(Ty)), getOne(Ty));
+}
+
+const SCEV *ScalarEvolution::getMinMaxExpr(SCEVTypes Kind,
SmallVectorImpl<const SCEV *> &Ops) {
assert(!Ops.empty() && "Cannot get empty (u|s)(min|max)!");
if (Ops.size() == 1) return Ops[0];
@@ -3615,8 +3615,8 @@ const SCEV *ScalarEvolution::getMinMaxExpr(SCEVTypes Kind,
return ExistingSCEV;
const SCEV **O = SCEVAllocator.Allocate<const SCEV *>(Ops.size());
std::uninitialized_copy(Ops.begin(), Ops.end(), O);
- SCEV *S = new (SCEVAllocator)
- SCEVMinMaxExpr(ID.Intern(SCEVAllocator), Kind, O, Ops.size());
+ SCEV *S = new (SCEVAllocator)
+ SCEVMinMaxExpr(ID.Intern(SCEVAllocator), Kind, O, Ops.size());
UniqueSCEVs.InsertNode(S, IP);
addToLoopUseLists(S);
@@ -3661,42 +3661,42 @@ const SCEV *ScalarEvolution::getUMinExpr(SmallVectorImpl<const SCEV *> &Ops) {
return getMinMaxExpr(scUMinExpr, Ops);
}
-const SCEV *
-ScalarEvolution::getSizeOfScalableVectorExpr(Type *IntTy,
- ScalableVectorType *ScalableTy) {
- Constant *NullPtr = Constant::getNullValue(ScalableTy->getPointerTo());
- Constant *One = ConstantInt::get(IntTy, 1);
- Constant *GEP = ConstantExpr::getGetElementPtr(ScalableTy, NullPtr, One);
- // Note that the expression we created is the final expression, we don't
- // want to simplify it any further Also, if we call a normal getSCEV(),
- // we'll end up in an endless recursion. So just create an SCEVUnknown.
- return getUnknown(ConstantExpr::getPtrToInt(GEP, IntTy));
-}
-
+const SCEV *
+ScalarEvolution::getSizeOfScalableVectorExpr(Type *IntTy,
+ ScalableVectorType *ScalableTy) {
+ Constant *NullPtr = Constant::getNullValue(ScalableTy->getPointerTo());
+ Constant *One = ConstantInt::get(IntTy, 1);
+ Constant *GEP = ConstantExpr::getGetElementPtr(ScalableTy, NullPtr, One);
+ // Note that the expression we created is the final expression, we don't
+ // want to simplify it any further Also, if we call a normal getSCEV(),
+ // we'll end up in an endless recursion. So just create an SCEVUnknown.
+ return getUnknown(ConstantExpr::getPtrToInt(GEP, IntTy));
+}
+
const SCEV *ScalarEvolution::getSizeOfExpr(Type *IntTy, Type *AllocTy) {
- if (auto *ScalableAllocTy = dyn_cast<ScalableVectorType>(AllocTy))
- return getSizeOfScalableVectorExpr(IntTy, ScalableAllocTy);
- // We can bypass creating a target-independent constant expression and then
- // folding it back into a ConstantInt. This is just a compile-time
- // optimization.
+ if (auto *ScalableAllocTy = dyn_cast<ScalableVectorType>(AllocTy))
+ return getSizeOfScalableVectorExpr(IntTy, ScalableAllocTy);
+ // We can bypass creating a target-independent constant expression and then
+ // folding it back into a ConstantInt. This is just a compile-time
+ // optimization.
return getConstant(IntTy, getDataLayout().getTypeAllocSize(AllocTy));
}
-const SCEV *ScalarEvolution::getStoreSizeOfExpr(Type *IntTy, Type *StoreTy) {
- if (auto *ScalableStoreTy = dyn_cast<ScalableVectorType>(StoreTy))
- return getSizeOfScalableVectorExpr(IntTy, ScalableStoreTy);
- // We can bypass creating a target-independent constant expression and then
- // folding it back into a ConstantInt. This is just a compile-time
- // optimization.
- return getConstant(IntTy, getDataLayout().getTypeStoreSize(StoreTy));
-}
-
+const SCEV *ScalarEvolution::getStoreSizeOfExpr(Type *IntTy, Type *StoreTy) {
+ if (auto *ScalableStoreTy = dyn_cast<ScalableVectorType>(StoreTy))
+ return getSizeOfScalableVectorExpr(IntTy, ScalableStoreTy);
+ // We can bypass creating a target-independent constant expression and then
+ // folding it back into a ConstantInt. This is just a compile-time
+ // optimization.
+ return getConstant(IntTy, getDataLayout().getTypeStoreSize(StoreTy));
+}
+
const SCEV *ScalarEvolution::getOffsetOfExpr(Type *IntTy,
StructType *STy,
unsigned FieldNo) {
- // We can bypass creating a target-independent constant expression and then
- // folding it back into a ConstantInt. This is just a compile-time
- // optimization.
+ // We can bypass creating a target-independent constant expression and then
+ // folding it back into a ConstantInt. This is just a compile-time
+ // optimization.
return getConstant(
IntTy, getDataLayout().getStructLayout(STy)->getElementOffset(FieldNo));
}
@@ -3920,7 +3920,7 @@ const SCEV *ScalarEvolution::getNegativeSCEV(const SCEV *V,
Type *Ty = V->getType();
Ty = getEffectiveSCEVType(Ty);
- return getMulExpr(V, getMinusOne(Ty), Flags);
+ return getMulExpr(V, getMinusOne(Ty), Flags);
}
/// If Expr computes ~A, return A else return nullptr
@@ -3954,8 +3954,8 @@ const SCEV *ScalarEvolution::getNotSCEV(const SCEV *V) {
return (const SCEV *)nullptr;
MatchedOperands.push_back(Matched);
}
- return getMinMaxExpr(SCEVMinMaxExpr::negate(MME->getSCEVType()),
- MatchedOperands);
+ return getMinMaxExpr(SCEVMinMaxExpr::negate(MME->getSCEVType()),
+ MatchedOperands);
};
if (const SCEV *Replaced = MatchMinMaxNegation(MME))
return Replaced;
@@ -3963,7 +3963,7 @@ const SCEV *ScalarEvolution::getNotSCEV(const SCEV *V) {
Type *Ty = V->getType();
Ty = getEffectiveSCEVType(Ty);
- return getMinusSCEV(getMinusOne(Ty), V);
+ return getMinusSCEV(getMinusOne(Ty), V);
}
const SCEV *ScalarEvolution::getMinusSCEV(const SCEV *LHS, const SCEV *RHS,
@@ -4110,7 +4110,7 @@ const SCEV *ScalarEvolution::getUMinFromMismatchedTypes(
MaxType = getWiderType(MaxType, S->getType());
else
MaxType = S->getType();
- assert(MaxType && "Failed to find maximum type!");
+ assert(MaxType && "Failed to find maximum type!");
// Extend all ops to max type.
SmallVector<const SCEV *, 2> PromotedOps;
@@ -4127,7 +4127,7 @@ const SCEV *ScalarEvolution::getPointerBase(const SCEV *V) {
return V;
while (true) {
- if (const SCEVIntegralCastExpr *Cast = dyn_cast<SCEVIntegralCastExpr>(V)) {
+ if (const SCEVIntegralCastExpr *Cast = dyn_cast<SCEVIntegralCastExpr>(V)) {
V = Cast->getOperand();
} else if (const SCEVNAryExpr *NAry = dyn_cast<SCEVNAryExpr>(V)) {
const SCEV *PtrOp = nullptr;
@@ -4430,107 +4430,107 @@ ScalarEvolution::proveNoWrapViaConstantRanges(const SCEVAddRecExpr *AR) {
return Result;
}
-SCEV::NoWrapFlags
-ScalarEvolution::proveNoSignedWrapViaInduction(const SCEVAddRecExpr *AR) {
- SCEV::NoWrapFlags Result = AR->getNoWrapFlags();
-
- if (AR->hasNoSignedWrap())
- return Result;
-
- if (!AR->isAffine())
- return Result;
-
- const SCEV *Step = AR->getStepRecurrence(*this);
- const Loop *L = AR->getLoop();
-
- // Check whether the backedge-taken count is SCEVCouldNotCompute.
- // Note that this serves two purposes: It filters out loops that are
- // simply not analyzable, and it covers the case where this code is
- // being called from within backedge-taken count analysis, such that
- // attempting to ask for the backedge-taken count would likely result
- // in infinite recursion. In the later case, the analysis code will
- // cope with a conservative value, and it will take care to purge
- // that value once it has finished.
- const SCEV *MaxBECount = getConstantMaxBackedgeTakenCount(L);
-
- // Normally, in the cases we can prove no-overflow via a
- // backedge guarding condition, we can also compute a backedge
- // taken count for the loop. The exceptions are assumptions and
- // guards present in the loop -- SCEV is not great at exploiting
- // these to compute max backedge taken counts, but can still use
- // these to prove lack of overflow. Use this fact to avoid
- // doing extra work that may not pay off.
-
- if (isa<SCEVCouldNotCompute>(MaxBECount) && !HasGuards &&
- AC.assumptions().empty())
- return Result;
-
- // If the backedge is guarded by a comparison with the pre-inc value the
- // addrec is safe. Also, if the entry is guarded by a comparison with the
- // start value and the backedge is guarded by a comparison with the post-inc
- // value, the addrec is safe.
- ICmpInst::Predicate Pred;
- const SCEV *OverflowLimit =
- getSignedOverflowLimitForStep(Step, &Pred, this);
- if (OverflowLimit &&
- (isLoopBackedgeGuardedByCond(L, Pred, AR, OverflowLimit) ||
- isKnownOnEveryIteration(Pred, AR, OverflowLimit))) {
- Result = setFlags(Result, SCEV::FlagNSW);
- }
- return Result;
-}
-SCEV::NoWrapFlags
-ScalarEvolution::proveNoUnsignedWrapViaInduction(const SCEVAddRecExpr *AR) {
- SCEV::NoWrapFlags Result = AR->getNoWrapFlags();
-
- if (AR->hasNoUnsignedWrap())
- return Result;
-
- if (!AR->isAffine())
- return Result;
-
- const SCEV *Step = AR->getStepRecurrence(*this);
- unsigned BitWidth = getTypeSizeInBits(AR->getType());
- const Loop *L = AR->getLoop();
-
- // Check whether the backedge-taken count is SCEVCouldNotCompute.
- // Note that this serves two purposes: It filters out loops that are
- // simply not analyzable, and it covers the case where this code is
- // being called from within backedge-taken count analysis, such that
- // attempting to ask for the backedge-taken count would likely result
- // in infinite recursion. In the later case, the analysis code will
- // cope with a conservative value, and it will take care to purge
- // that value once it has finished.
- const SCEV *MaxBECount = getConstantMaxBackedgeTakenCount(L);
-
- // Normally, in the cases we can prove no-overflow via a
- // backedge guarding condition, we can also compute a backedge
- // taken count for the loop. The exceptions are assumptions and
- // guards present in the loop -- SCEV is not great at exploiting
- // these to compute max backedge taken counts, but can still use
- // these to prove lack of overflow. Use this fact to avoid
- // doing extra work that may not pay off.
-
- if (isa<SCEVCouldNotCompute>(MaxBECount) && !HasGuards &&
- AC.assumptions().empty())
- return Result;
-
- // If the backedge is guarded by a comparison with the pre-inc value the
- // addrec is safe. Also, if the entry is guarded by a comparison with the
- // start value and the backedge is guarded by a comparison with the post-inc
- // value, the addrec is safe.
- if (isKnownPositive(Step)) {
- const SCEV *N = getConstant(APInt::getMinValue(BitWidth) -
- getUnsignedRangeMax(Step));
- if (isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_ULT, AR, N) ||
- isKnownOnEveryIteration(ICmpInst::ICMP_ULT, AR, N)) {
- Result = setFlags(Result, SCEV::FlagNUW);
- }
- }
-
- return Result;
-}
-
+SCEV::NoWrapFlags
+ScalarEvolution::proveNoSignedWrapViaInduction(const SCEVAddRecExpr *AR) {
+ SCEV::NoWrapFlags Result = AR->getNoWrapFlags();
+
+ if (AR->hasNoSignedWrap())
+ return Result;
+
+ if (!AR->isAffine())
+ return Result;
+
+ const SCEV *Step = AR->getStepRecurrence(*this);
+ const Loop *L = AR->getLoop();
+
+ // Check whether the backedge-taken count is SCEVCouldNotCompute.
+ // Note that this serves two purposes: It filters out loops that are
+ // simply not analyzable, and it covers the case where this code is
+ // being called from within backedge-taken count analysis, such that
+ // attempting to ask for the backedge-taken count would likely result
+ // in infinite recursion. In the later case, the analysis code will
+ // cope with a conservative value, and it will take care to purge
+ // that value once it has finished.
+ const SCEV *MaxBECount = getConstantMaxBackedgeTakenCount(L);
+
+ // Normally, in the cases we can prove no-overflow via a
+ // backedge guarding condition, we can also compute a backedge
+ // taken count for the loop. The exceptions are assumptions and
+ // guards present in the loop -- SCEV is not great at exploiting
+ // these to compute max backedge taken counts, but can still use
+ // these to prove lack of overflow. Use this fact to avoid
+ // doing extra work that may not pay off.
+
+ if (isa<SCEVCouldNotCompute>(MaxBECount) && !HasGuards &&
+ AC.assumptions().empty())
+ return Result;
+
+ // If the backedge is guarded by a comparison with the pre-inc value the
+ // addrec is safe. Also, if the entry is guarded by a comparison with the
+ // start value and the backedge is guarded by a comparison with the post-inc
+ // value, the addrec is safe.
+ ICmpInst::Predicate Pred;
+ const SCEV *OverflowLimit =
+ getSignedOverflowLimitForStep(Step, &Pred, this);
+ if (OverflowLimit &&
+ (isLoopBackedgeGuardedByCond(L, Pred, AR, OverflowLimit) ||
+ isKnownOnEveryIteration(Pred, AR, OverflowLimit))) {
+ Result = setFlags(Result, SCEV::FlagNSW);
+ }
+ return Result;
+}
+SCEV::NoWrapFlags
+ScalarEvolution::proveNoUnsignedWrapViaInduction(const SCEVAddRecExpr *AR) {
+ SCEV::NoWrapFlags Result = AR->getNoWrapFlags();
+
+ if (AR->hasNoUnsignedWrap())
+ return Result;
+
+ if (!AR->isAffine())
+ return Result;
+
+ const SCEV *Step = AR->getStepRecurrence(*this);
+ unsigned BitWidth = getTypeSizeInBits(AR->getType());
+ const Loop *L = AR->getLoop();
+
+ // Check whether the backedge-taken count is SCEVCouldNotCompute.
+ // Note that this serves two purposes: It filters out loops that are
+ // simply not analyzable, and it covers the case where this code is
+ // being called from within backedge-taken count analysis, such that
+ // attempting to ask for the backedge-taken count would likely result
+ // in infinite recursion. In the later case, the analysis code will
+ // cope with a conservative value, and it will take care to purge
+ // that value once it has finished.
+ const SCEV *MaxBECount = getConstantMaxBackedgeTakenCount(L);
+
+ // Normally, in the cases we can prove no-overflow via a
+ // backedge guarding condition, we can also compute a backedge
+ // taken count for the loop. The exceptions are assumptions and
+ // guards present in the loop -- SCEV is not great at exploiting
+ // these to compute max backedge taken counts, but can still use
+ // these to prove lack of overflow. Use this fact to avoid
+ // doing extra work that may not pay off.
+
+ if (isa<SCEVCouldNotCompute>(MaxBECount) && !HasGuards &&
+ AC.assumptions().empty())
+ return Result;
+
+ // If the backedge is guarded by a comparison with the pre-inc value the
+ // addrec is safe. Also, if the entry is guarded by a comparison with the
+ // start value and the backedge is guarded by a comparison with the post-inc
+ // value, the addrec is safe.
+ if (isKnownPositive(Step)) {
+ const SCEV *N = getConstant(APInt::getMinValue(BitWidth) -
+ getUnsignedRangeMax(Step));
+ if (isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_ULT, AR, N) ||
+ isKnownOnEveryIteration(ICmpInst::ICMP_ULT, AR, N)) {
+ Result = setFlags(Result, SCEV::FlagNUW);
+ }
+ }
+
+ return Result;
+}
+
namespace {
/// Represents an abstract binary operation. This may exist as a
@@ -4542,7 +4542,7 @@ struct BinaryOp {
Value *RHS;
bool IsNSW = false;
bool IsNUW = false;
- bool IsExact = false;
+ bool IsExact = false;
/// Op is set if this BinaryOp corresponds to a concrete LLVM instruction or
/// constant expression.
@@ -4555,14 +4555,14 @@ struct BinaryOp {
IsNSW = OBO->hasNoSignedWrap();
IsNUW = OBO->hasNoUnsignedWrap();
}
- if (auto *PEO = dyn_cast<PossiblyExactOperator>(Op))
- IsExact = PEO->isExact();
+ if (auto *PEO = dyn_cast<PossiblyExactOperator>(Op))
+ IsExact = PEO->isExact();
}
explicit BinaryOp(unsigned Opcode, Value *LHS, Value *RHS, bool IsNSW = false,
- bool IsNUW = false, bool IsExact = false)
- : Opcode(Opcode), LHS(LHS), RHS(RHS), IsNSW(IsNSW), IsNUW(IsNUW),
- IsExact(IsExact) {}
+ bool IsNUW = false, bool IsExact = false)
+ : Opcode(Opcode), LHS(LHS), RHS(RHS), IsNSW(IsNSW), IsNUW(IsNUW),
+ IsExact(IsExact) {}
};
} // end anonymous namespace
@@ -5259,15 +5259,15 @@ static bool IsAvailableOnEntry(const Loop *L, DominatorTree &DT, const SCEV *S,
bool follow(const SCEV *S) {
switch (S->getSCEVType()) {
- case scConstant:
- case scPtrToInt:
- case scTruncate:
- case scZeroExtend:
- case scSignExtend:
- case scAddExpr:
- case scMulExpr:
- case scUMaxExpr:
- case scSMaxExpr:
+ case scConstant:
+ case scPtrToInt:
+ case scTruncate:
+ case scZeroExtend:
+ case scSignExtend:
+ case scAddExpr:
+ case scMulExpr:
+ case scUMaxExpr:
+ case scSMaxExpr:
case scUMinExpr:
case scSMinExpr:
// These expressions are available if their operand(s) is/are.
@@ -5305,7 +5305,7 @@ static bool IsAvailableOnEntry(const Loop *L, DominatorTree &DT, const SCEV *S,
// We do not try to smart about these at all.
return setUnavailable();
}
- llvm_unreachable("Unknown SCEV kind!");
+ llvm_unreachable("Unknown SCEV kind!");
}
bool isDone() { return TraversalDone; }
@@ -5525,9 +5525,9 @@ uint32_t ScalarEvolution::GetMinTrailingZerosImpl(const SCEV *S) {
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(S))
return C->getAPInt().countTrailingZeros();
- if (const SCEVPtrToIntExpr *I = dyn_cast<SCEVPtrToIntExpr>(S))
- return GetMinTrailingZeros(I->getOperand());
-
+ if (const SCEVPtrToIntExpr *I = dyn_cast<SCEVPtrToIntExpr>(S))
+ return GetMinTrailingZeros(I->getOperand());
+
if (const SCEVTruncateExpr *T = dyn_cast<SCEVTruncateExpr>(S))
return std::min(GetMinTrailingZeros(T->getOperand()),
(uint32_t)getTypeSizeInBits(T->getType()));
@@ -5619,15 +5619,15 @@ static Optional<ConstantRange> GetRangeFromMetadata(Value *V) {
return None;
}
-void ScalarEvolution::setNoWrapFlags(SCEVAddRecExpr *AddRec,
- SCEV::NoWrapFlags Flags) {
- if (AddRec->getNoWrapFlags(Flags) != Flags) {
- AddRec->setNoWrapFlags(Flags);
- UnsignedRanges.erase(AddRec);
- SignedRanges.erase(AddRec);
- }
-}
-
+void ScalarEvolution::setNoWrapFlags(SCEVAddRecExpr *AddRec,
+ SCEV::NoWrapFlags Flags) {
+ if (AddRec->getNoWrapFlags(Flags) != Flags) {
+ AddRec->setNoWrapFlags(Flags);
+ UnsignedRanges.erase(AddRec);
+ SignedRanges.erase(AddRec);
+ }
+}
+
/// Determine the range for a particular SCEV. If SignHint is
/// HINT_RANGE_UNSIGNED (resp. HINT_RANGE_SIGNED) then getRange prefers ranges
/// with a "cleaner" unsigned (resp. signed) representation.
@@ -5742,11 +5742,11 @@ ScalarEvolution::getRangeRef(const SCEV *S,
RangeType));
}
- if (const SCEVPtrToIntExpr *PtrToInt = dyn_cast<SCEVPtrToIntExpr>(S)) {
- ConstantRange X = getRangeRef(PtrToInt->getOperand(), SignHint);
- return setRange(PtrToInt, SignHint, X);
- }
-
+ if (const SCEVPtrToIntExpr *PtrToInt = dyn_cast<SCEVPtrToIntExpr>(S)) {
+ ConstantRange X = getRangeRef(PtrToInt->getOperand(), SignHint);
+ return setRange(PtrToInt, SignHint, X);
+ }
+
if (const SCEVTruncateExpr *Trunc = dyn_cast<SCEVTruncateExpr>(S)) {
ConstantRange X = getRangeRef(Trunc->getOperand(), SignHint);
return setRange(Trunc, SignHint,
@@ -5799,28 +5799,28 @@ ScalarEvolution::getRangeRef(const SCEV *S,
auto RangeFromAffine = getRangeForAffineAR(
AddRec->getStart(), AddRec->getStepRecurrence(*this), MaxBECount,
BitWidth);
- ConservativeResult =
- ConservativeResult.intersectWith(RangeFromAffine, RangeType);
+ ConservativeResult =
+ ConservativeResult.intersectWith(RangeFromAffine, RangeType);
auto RangeFromFactoring = getRangeViaFactoring(
AddRec->getStart(), AddRec->getStepRecurrence(*this), MaxBECount,
BitWidth);
- ConservativeResult =
- ConservativeResult.intersectWith(RangeFromFactoring, RangeType);
- }
-
- // Now try symbolic BE count and more powerful methods.
- if (UseExpensiveRangeSharpening) {
- const SCEV *SymbolicMaxBECount =
- getSymbolicMaxBackedgeTakenCount(AddRec->getLoop());
- if (!isa<SCEVCouldNotCompute>(SymbolicMaxBECount) &&
- getTypeSizeInBits(MaxBECount->getType()) <= BitWidth &&
- AddRec->hasNoSelfWrap()) {
- auto RangeFromAffineNew = getRangeForAffineNoSelfWrappingAR(
- AddRec, SymbolicMaxBECount, BitWidth, SignHint);
+ ConservativeResult =
+ ConservativeResult.intersectWith(RangeFromFactoring, RangeType);
+ }
+
+ // Now try symbolic BE count and more powerful methods.
+ if (UseExpensiveRangeSharpening) {
+ const SCEV *SymbolicMaxBECount =
+ getSymbolicMaxBackedgeTakenCount(AddRec->getLoop());
+ if (!isa<SCEVCouldNotCompute>(SymbolicMaxBECount) &&
+ getTypeSizeInBits(MaxBECount->getType()) <= BitWidth &&
+ AddRec->hasNoSelfWrap()) {
+ auto RangeFromAffineNew = getRangeForAffineNoSelfWrappingAR(
+ AddRec, SymbolicMaxBECount, BitWidth, SignHint);
ConservativeResult =
- ConservativeResult.intersectWith(RangeFromAffineNew, RangeType);
- }
+ ConservativeResult.intersectWith(RangeFromAffineNew, RangeType);
+ }
}
}
@@ -5991,74 +5991,74 @@ ConstantRange ScalarEvolution::getRangeForAffineAR(const SCEV *Start,
return SR.intersectWith(UR, ConstantRange::Smallest);
}
-ConstantRange ScalarEvolution::getRangeForAffineNoSelfWrappingAR(
- const SCEVAddRecExpr *AddRec, const SCEV *MaxBECount, unsigned BitWidth,
- ScalarEvolution::RangeSignHint SignHint) {
- assert(AddRec->isAffine() && "Non-affine AddRecs are not suppored!\n");
- assert(AddRec->hasNoSelfWrap() &&
- "This only works for non-self-wrapping AddRecs!");
- const bool IsSigned = SignHint == HINT_RANGE_SIGNED;
- const SCEV *Step = AddRec->getStepRecurrence(*this);
- // Only deal with constant step to save compile time.
- if (!isa<SCEVConstant>(Step))
- return ConstantRange::getFull(BitWidth);
- // Let's make sure that we can prove that we do not self-wrap during
- // MaxBECount iterations. We need this because MaxBECount is a maximum
- // iteration count estimate, and we might infer nw from some exit for which we
- // do not know max exit count (or any other side reasoning).
- // TODO: Turn into assert at some point.
- if (getTypeSizeInBits(MaxBECount->getType()) >
- getTypeSizeInBits(AddRec->getType()))
- return ConstantRange::getFull(BitWidth);
- MaxBECount = getNoopOrZeroExtend(MaxBECount, AddRec->getType());
- const SCEV *RangeWidth = getMinusOne(AddRec->getType());
- const SCEV *StepAbs = getUMinExpr(Step, getNegativeSCEV(Step));
- const SCEV *MaxItersWithoutWrap = getUDivExpr(RangeWidth, StepAbs);
- if (!isKnownPredicateViaConstantRanges(ICmpInst::ICMP_ULE, MaxBECount,
- MaxItersWithoutWrap))
- return ConstantRange::getFull(BitWidth);
-
- ICmpInst::Predicate LEPred =
- IsSigned ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE;
- ICmpInst::Predicate GEPred =
- IsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE;
- const SCEV *End = AddRec->evaluateAtIteration(MaxBECount, *this);
-
- // We know that there is no self-wrap. Let's take Start and End values and
- // look at all intermediate values V1, V2, ..., Vn that IndVar takes during
- // the iteration. They either lie inside the range [Min(Start, End),
- // Max(Start, End)] or outside it:
- //
- // Case 1: RangeMin ... Start V1 ... VN End ... RangeMax;
- // Case 2: RangeMin Vk ... V1 Start ... End Vn ... Vk + 1 RangeMax;
- //
- // No self wrap flag guarantees that the intermediate values cannot be BOTH
- // outside and inside the range [Min(Start, End), Max(Start, End)]. Using that
- // knowledge, let's try to prove that we are dealing with Case 1. It is so if
- // Start <= End and step is positive, or Start >= End and step is negative.
- const SCEV *Start = AddRec->getStart();
- ConstantRange StartRange = getRangeRef(Start, SignHint);
- ConstantRange EndRange = getRangeRef(End, SignHint);
- ConstantRange RangeBetween = StartRange.unionWith(EndRange);
- // If they already cover full iteration space, we will know nothing useful
- // even if we prove what we want to prove.
- if (RangeBetween.isFullSet())
- return RangeBetween;
- // Only deal with ranges that do not wrap (i.e. RangeMin < RangeMax).
- bool IsWrappedSet = IsSigned ? RangeBetween.isSignWrappedSet()
- : RangeBetween.isWrappedSet();
- if (IsWrappedSet)
- return ConstantRange::getFull(BitWidth);
-
- if (isKnownPositive(Step) &&
- isKnownPredicateViaConstantRanges(LEPred, Start, End))
- return RangeBetween;
- else if (isKnownNegative(Step) &&
- isKnownPredicateViaConstantRanges(GEPred, Start, End))
- return RangeBetween;
- return ConstantRange::getFull(BitWidth);
-}
-
+ConstantRange ScalarEvolution::getRangeForAffineNoSelfWrappingAR(
+ const SCEVAddRecExpr *AddRec, const SCEV *MaxBECount, unsigned BitWidth,
+ ScalarEvolution::RangeSignHint SignHint) {
+ assert(AddRec->isAffine() && "Non-affine AddRecs are not suppored!\n");
+ assert(AddRec->hasNoSelfWrap() &&
+ "This only works for non-self-wrapping AddRecs!");
+ const bool IsSigned = SignHint == HINT_RANGE_SIGNED;
+ const SCEV *Step = AddRec->getStepRecurrence(*this);
+ // Only deal with constant step to save compile time.
+ if (!isa<SCEVConstant>(Step))
+ return ConstantRange::getFull(BitWidth);
+ // Let's make sure that we can prove that we do not self-wrap during
+ // MaxBECount iterations. We need this because MaxBECount is a maximum
+ // iteration count estimate, and we might infer nw from some exit for which we
+ // do not know max exit count (or any other side reasoning).
+ // TODO: Turn into assert at some point.
+ if (getTypeSizeInBits(MaxBECount->getType()) >
+ getTypeSizeInBits(AddRec->getType()))
+ return ConstantRange::getFull(BitWidth);
+ MaxBECount = getNoopOrZeroExtend(MaxBECount, AddRec->getType());
+ const SCEV *RangeWidth = getMinusOne(AddRec->getType());
+ const SCEV *StepAbs = getUMinExpr(Step, getNegativeSCEV(Step));
+ const SCEV *MaxItersWithoutWrap = getUDivExpr(RangeWidth, StepAbs);
+ if (!isKnownPredicateViaConstantRanges(ICmpInst::ICMP_ULE, MaxBECount,
+ MaxItersWithoutWrap))
+ return ConstantRange::getFull(BitWidth);
+
+ ICmpInst::Predicate LEPred =
+ IsSigned ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE;
+ ICmpInst::Predicate GEPred =
+ IsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE;
+ const SCEV *End = AddRec->evaluateAtIteration(MaxBECount, *this);
+
+ // We know that there is no self-wrap. Let's take Start and End values and
+ // look at all intermediate values V1, V2, ..., Vn that IndVar takes during
+ // the iteration. They either lie inside the range [Min(Start, End),
+ // Max(Start, End)] or outside it:
+ //
+ // Case 1: RangeMin ... Start V1 ... VN End ... RangeMax;
+ // Case 2: RangeMin Vk ... V1 Start ... End Vn ... Vk + 1 RangeMax;
+ //
+ // No self wrap flag guarantees that the intermediate values cannot be BOTH
+ // outside and inside the range [Min(Start, End), Max(Start, End)]. Using that
+ // knowledge, let's try to prove that we are dealing with Case 1. It is so if
+ // Start <= End and step is positive, or Start >= End and step is negative.
+ const SCEV *Start = AddRec->getStart();
+ ConstantRange StartRange = getRangeRef(Start, SignHint);
+ ConstantRange EndRange = getRangeRef(End, SignHint);
+ ConstantRange RangeBetween = StartRange.unionWith(EndRange);
+ // If they already cover full iteration space, we will know nothing useful
+ // even if we prove what we want to prove.
+ if (RangeBetween.isFullSet())
+ return RangeBetween;
+ // Only deal with ranges that do not wrap (i.e. RangeMin < RangeMax).
+ bool IsWrappedSet = IsSigned ? RangeBetween.isSignWrappedSet()
+ : RangeBetween.isWrappedSet();
+ if (IsWrappedSet)
+ return ConstantRange::getFull(BitWidth);
+
+ if (isKnownPositive(Step) &&
+ isKnownPredicateViaConstantRanges(LEPred, Start, End))
+ return RangeBetween;
+ else if (isKnownNegative(Step) &&
+ isKnownPredicateViaConstantRanges(GEPred, Start, End))
+ return RangeBetween;
+ return ConstantRange::getFull(BitWidth);
+}
+
ConstantRange ScalarEvolution::getRangeViaFactoring(const SCEV *Start,
const SCEV *Step,
const SCEV *MaxBECount,
@@ -6091,7 +6091,7 @@ ConstantRange ScalarEvolution::getRangeViaFactoring(const SCEV *Start,
}
// Peel off a cast operation
- if (auto *SCast = dyn_cast<SCEVIntegralCastExpr>(S)) {
+ if (auto *SCast = dyn_cast<SCEVIntegralCastExpr>(S)) {
CastOp = SCast->getSCEVType();
S = SCast->getOperand();
}
@@ -6292,7 +6292,7 @@ bool ScalarEvolution::isAddRecNeverPoison(const Instruction *I, const Loop *L) {
const Instruction *Poison = PoisonStack.pop_back_val();
for (auto *PoisonUser : Poison->users()) {
- if (propagatesPoison(cast<Operator>(PoisonUser))) {
+ if (propagatesPoison(cast<Operator>(PoisonUser))) {
if (Pushed.insert(cast<Instruction>(PoisonUser)).second)
PoisonStack.push_back(cast<Instruction>(PoisonUser));
} else if (auto *BI = dyn_cast<BranchInst>(PoisonUser)) {
@@ -6356,7 +6356,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
} else if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
return getConstant(CI);
else if (isa<ConstantPointerNull>(V))
- // FIXME: we shouldn't special-case null pointer constant.
+ // FIXME: we shouldn't special-case null pointer constant.
return getZero(V->getType());
else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V))
return GA->isInterposable() ? getUnknown(V) : getSCEV(GA->getAliasee());
@@ -6647,15 +6647,15 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
}
}
}
- if (BO->IsExact) {
- // Given exact arithmetic in-bounds right-shift by a constant,
- // we can lower it into: (abs(x) EXACT/u (1<<C)) * signum(x)
- const SCEV *X = getSCEV(BO->LHS);
- const SCEV *AbsX = getAbsExpr(X, /*IsNSW=*/false);
- APInt Mult = APInt::getOneBitSet(BitWidth, AShrAmt);
- const SCEV *Div = getUDivExactExpr(AbsX, getConstant(Mult));
- return getMulExpr(Div, getSignumExpr(X), SCEV::FlagNSW);
- }
+ if (BO->IsExact) {
+ // Given exact arithmetic in-bounds right-shift by a constant,
+ // we can lower it into: (abs(x) EXACT/u (1<<C)) * signum(x)
+ const SCEV *X = getSCEV(BO->LHS);
+ const SCEV *AbsX = getAbsExpr(X, /*IsNSW=*/false);
+ APInt Mult = APInt::getOneBitSet(BitWidth, AShrAmt);
+ const SCEV *Div = getUDivExactExpr(AbsX, getConstant(Mult));
+ return getMulExpr(Div, getSignumExpr(X), SCEV::FlagNSW);
+ }
break;
}
}
@@ -6692,29 +6692,29 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
return getSCEV(U->getOperand(0));
break;
- case Instruction::PtrToInt: {
- // Pointer to integer cast is straight-forward, so do model it.
- Value *Ptr = U->getOperand(0);
- const SCEV *Op = getSCEV(Ptr);
- Type *DstIntTy = U->getType();
- // SCEV doesn't have constant pointer expression type, but it supports
- // nullptr constant (and only that one), which is modelled in SCEV as a
- // zero integer constant. So just skip the ptrtoint cast for constants.
- if (isa<SCEVConstant>(Op))
- return getTruncateOrZeroExtend(Op, DstIntTy);
- Type *PtrTy = Ptr->getType();
- Type *IntPtrTy = getDataLayout().getIntPtrType(PtrTy);
- // But only if effective SCEV (integer) type is wide enough to represent
- // all possible pointer values.
- if (getDataLayout().getTypeSizeInBits(getEffectiveSCEVType(PtrTy)) !=
- getDataLayout().getTypeSizeInBits(IntPtrTy))
- return getUnknown(V);
- return getPtrToIntExpr(Op, DstIntTy);
- }
- case Instruction::IntToPtr:
- // Just don't deal with inttoptr casts.
- return getUnknown(V);
-
+ case Instruction::PtrToInt: {
+ // Pointer to integer cast is straight-forward, so do model it.
+ Value *Ptr = U->getOperand(0);
+ const SCEV *Op = getSCEV(Ptr);
+ Type *DstIntTy = U->getType();
+ // SCEV doesn't have constant pointer expression type, but it supports
+ // nullptr constant (and only that one), which is modelled in SCEV as a
+ // zero integer constant. So just skip the ptrtoint cast for constants.
+ if (isa<SCEVConstant>(Op))
+ return getTruncateOrZeroExtend(Op, DstIntTy);
+ Type *PtrTy = Ptr->getType();
+ Type *IntPtrTy = getDataLayout().getIntPtrType(PtrTy);
+ // But only if effective SCEV (integer) type is wide enough to represent
+ // all possible pointer values.
+ if (getDataLayout().getTypeSizeInBits(getEffectiveSCEVType(PtrTy)) !=
+ getDataLayout().getTypeSizeInBits(IntPtrTy))
+ return getUnknown(V);
+ return getPtrToIntExpr(Op, DstIntTy);
+ }
+ case Instruction::IntToPtr:
+ // Just don't deal with inttoptr casts.
+ return getUnknown(V);
+
case Instruction::SDiv:
// If both operands are non-negative, this is just an udiv.
if (isKnownNonNegative(getSCEV(U->getOperand(0))) &&
@@ -6749,45 +6749,45 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
case Instruction::Invoke:
if (Value *RV = cast<CallBase>(U)->getReturnedArgOperand())
return getSCEV(RV);
-
- if (auto *II = dyn_cast<IntrinsicInst>(U)) {
- switch (II->getIntrinsicID()) {
- case Intrinsic::abs:
- return getAbsExpr(
- getSCEV(II->getArgOperand(0)),
- /*IsNSW=*/cast<ConstantInt>(II->getArgOperand(1))->isOne());
- case Intrinsic::umax:
- return getUMaxExpr(getSCEV(II->getArgOperand(0)),
- getSCEV(II->getArgOperand(1)));
- case Intrinsic::umin:
- return getUMinExpr(getSCEV(II->getArgOperand(0)),
- getSCEV(II->getArgOperand(1)));
- case Intrinsic::smax:
- return getSMaxExpr(getSCEV(II->getArgOperand(0)),
- getSCEV(II->getArgOperand(1)));
- case Intrinsic::smin:
- return getSMinExpr(getSCEV(II->getArgOperand(0)),
- getSCEV(II->getArgOperand(1)));
- case Intrinsic::usub_sat: {
- const SCEV *X = getSCEV(II->getArgOperand(0));
- const SCEV *Y = getSCEV(II->getArgOperand(1));
- const SCEV *ClampedY = getUMinExpr(X, Y);
- return getMinusSCEV(X, ClampedY, SCEV::FlagNUW);
- }
- case Intrinsic::uadd_sat: {
- const SCEV *X = getSCEV(II->getArgOperand(0));
- const SCEV *Y = getSCEV(II->getArgOperand(1));
- const SCEV *ClampedX = getUMinExpr(X, getNotSCEV(Y));
- return getAddExpr(ClampedX, Y, SCEV::FlagNUW);
- }
- case Intrinsic::start_loop_iterations:
- // A start_loop_iterations is just equivalent to the first operand for
- // SCEV purposes.
- return getSCEV(II->getArgOperand(0));
- default:
- break;
- }
- }
+
+ if (auto *II = dyn_cast<IntrinsicInst>(U)) {
+ switch (II->getIntrinsicID()) {
+ case Intrinsic::abs:
+ return getAbsExpr(
+ getSCEV(II->getArgOperand(0)),
+ /*IsNSW=*/cast<ConstantInt>(II->getArgOperand(1))->isOne());
+ case Intrinsic::umax:
+ return getUMaxExpr(getSCEV(II->getArgOperand(0)),
+ getSCEV(II->getArgOperand(1)));
+ case Intrinsic::umin:
+ return getUMinExpr(getSCEV(II->getArgOperand(0)),
+ getSCEV(II->getArgOperand(1)));
+ case Intrinsic::smax:
+ return getSMaxExpr(getSCEV(II->getArgOperand(0)),
+ getSCEV(II->getArgOperand(1)));
+ case Intrinsic::smin:
+ return getSMinExpr(getSCEV(II->getArgOperand(0)),
+ getSCEV(II->getArgOperand(1)));
+ case Intrinsic::usub_sat: {
+ const SCEV *X = getSCEV(II->getArgOperand(0));
+ const SCEV *Y = getSCEV(II->getArgOperand(1));
+ const SCEV *ClampedY = getUMinExpr(X, Y);
+ return getMinusSCEV(X, ClampedY, SCEV::FlagNUW);
+ }
+ case Intrinsic::uadd_sat: {
+ const SCEV *X = getSCEV(II->getArgOperand(0));
+ const SCEV *Y = getSCEV(II->getArgOperand(1));
+ const SCEV *ClampedX = getUMinExpr(X, getNotSCEV(Y));
+ return getAddExpr(ClampedX, Y, SCEV::FlagNUW);
+ }
+ case Intrinsic::start_loop_iterations:
+ // A start_loop_iterations is just equivalent to the first operand for
+ // SCEV purposes.
+ return getSCEV(II->getArgOperand(0));
+ default:
+ break;
+ }
+ }
break;
}
@@ -6820,9 +6820,9 @@ unsigned ScalarEvolution::getSmallConstantTripCount(const Loop *L) {
return 0;
}
-unsigned
-ScalarEvolution::getSmallConstantTripCount(const Loop *L,
- const BasicBlock *ExitingBlock) {
+unsigned
+ScalarEvolution::getSmallConstantTripCount(const Loop *L,
+ const BasicBlock *ExitingBlock) {
assert(ExitingBlock && "Must pass a non-null exiting block!");
assert(L->isLoopExiting(ExitingBlock) &&
"Exiting block must actually branch out of the loop!");
@@ -6859,7 +6859,7 @@ unsigned ScalarEvolution::getSmallConstantTripMultiple(const Loop *L) {
/// that control exits the loop via ExitingBlock.
unsigned
ScalarEvolution::getSmallConstantTripMultiple(const Loop *L,
- const BasicBlock *ExitingBlock) {
+ const BasicBlock *ExitingBlock) {
assert(ExitingBlock && "Must pass a non-null exiting block!");
assert(L->isLoopExiting(ExitingBlock) &&
"Exiting block must actually branch out of the loop!");
@@ -6890,14 +6890,14 @@ ScalarEvolution::getSmallConstantTripMultiple(const Loop *L,
}
const SCEV *ScalarEvolution::getExitCount(const Loop *L,
- const BasicBlock *ExitingBlock,
+ const BasicBlock *ExitingBlock,
ExitCountKind Kind) {
switch (Kind) {
case Exact:
- case SymbolicMaximum:
+ case SymbolicMaximum:
return getBackedgeTakenInfo(L).getExact(ExitingBlock, this);
case ConstantMaximum:
- return getBackedgeTakenInfo(L).getConstantMax(ExitingBlock, this);
+ return getBackedgeTakenInfo(L).getConstantMax(ExitingBlock, this);
};
llvm_unreachable("Invalid ExitCountKind!");
}
@@ -6914,15 +6914,15 @@ const SCEV *ScalarEvolution::getBackedgeTakenCount(const Loop *L,
case Exact:
return getBackedgeTakenInfo(L).getExact(L, this);
case ConstantMaximum:
- return getBackedgeTakenInfo(L).getConstantMax(this);
- case SymbolicMaximum:
- return getBackedgeTakenInfo(L).getSymbolicMax(L, this);
+ return getBackedgeTakenInfo(L).getConstantMax(this);
+ case SymbolicMaximum:
+ return getBackedgeTakenInfo(L).getSymbolicMax(L, this);
};
llvm_unreachable("Invalid ExitCountKind!");
}
bool ScalarEvolution::isBackedgeTakenCountMaxOrZero(const Loop *L) {
- return getBackedgeTakenInfo(L).isConstantMaxOrZero(this);
+ return getBackedgeTakenInfo(L).isConstantMaxOrZero(this);
}
/// Push PHI nodes in the header of the given loop onto the given Worklist.
@@ -6952,7 +6952,7 @@ ScalarEvolution::getPredicatedBackedgeTakenInfo(const Loop *L) {
return PredicatedBackedgeTakenCounts.find(L)->second = std::move(Result);
}
-ScalarEvolution::BackedgeTakenInfo &
+ScalarEvolution::BackedgeTakenInfo &
ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
// Initially insert an invalid entry for this loop. If the insertion
// succeeds, proceed to actually compute a backedge-taken count and
@@ -6976,11 +6976,11 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
const SCEV *BEExact = Result.getExact(L, this);
if (BEExact != getCouldNotCompute()) {
assert(isLoopInvariant(BEExact, L) &&
- isLoopInvariant(Result.getConstantMax(this), L) &&
+ isLoopInvariant(Result.getConstantMax(this), L) &&
"Computed backedge-taken count isn't loop invariant for loop!");
++NumTripCountsComputed;
- } else if (Result.getConstantMax(this) == getCouldNotCompute() &&
- isa<PHINode>(L->getHeader()->begin())) {
+ } else if (Result.getConstantMax(this) == getCouldNotCompute() &&
+ isa<PHINode>(L->getHeader()->begin())) {
// Only count loops that have phi nodes as not being computable.
++NumTripCountsNotComputed;
}
@@ -7221,7 +7221,7 @@ ScalarEvolution::BackedgeTakenInfo::getExact(const Loop *L, ScalarEvolution *SE,
/// Get the exact not taken count for this loop exit.
const SCEV *
-ScalarEvolution::BackedgeTakenInfo::getExact(const BasicBlock *ExitingBlock,
+ScalarEvolution::BackedgeTakenInfo::getExact(const BasicBlock *ExitingBlock,
ScalarEvolution *SE) const {
for (auto &ENT : ExitNotTaken)
if (ENT.ExitingBlock == ExitingBlock && ENT.hasAlwaysTruePredicate())
@@ -7230,8 +7230,8 @@ ScalarEvolution::BackedgeTakenInfo::getExact(const BasicBlock *ExitingBlock,
return SE->getCouldNotCompute();
}
-const SCEV *ScalarEvolution::BackedgeTakenInfo::getConstantMax(
- const BasicBlock *ExitingBlock, ScalarEvolution *SE) const {
+const SCEV *ScalarEvolution::BackedgeTakenInfo::getConstantMax(
+ const BasicBlock *ExitingBlock, ScalarEvolution *SE) const {
for (auto &ENT : ExitNotTaken)
if (ENT.ExitingBlock == ExitingBlock && ENT.hasAlwaysTruePredicate())
return ENT.MaxNotTaken;
@@ -7239,32 +7239,32 @@ const SCEV *ScalarEvolution::BackedgeTakenInfo::getConstantMax(
return SE->getCouldNotCompute();
}
-/// getConstantMax - Get the constant max backedge taken count for the loop.
+/// getConstantMax - Get the constant max backedge taken count for the loop.
const SCEV *
-ScalarEvolution::BackedgeTakenInfo::getConstantMax(ScalarEvolution *SE) const {
+ScalarEvolution::BackedgeTakenInfo::getConstantMax(ScalarEvolution *SE) const {
auto PredicateNotAlwaysTrue = [](const ExitNotTakenInfo &ENT) {
return !ENT.hasAlwaysTruePredicate();
};
- if (any_of(ExitNotTaken, PredicateNotAlwaysTrue) || !getConstantMax())
+ if (any_of(ExitNotTaken, PredicateNotAlwaysTrue) || !getConstantMax())
return SE->getCouldNotCompute();
- assert((isa<SCEVCouldNotCompute>(getConstantMax()) ||
- isa<SCEVConstant>(getConstantMax())) &&
+ assert((isa<SCEVCouldNotCompute>(getConstantMax()) ||
+ isa<SCEVConstant>(getConstantMax())) &&
"No point in having a non-constant max backedge taken count!");
- return getConstantMax();
-}
-
-const SCEV *
-ScalarEvolution::BackedgeTakenInfo::getSymbolicMax(const Loop *L,
- ScalarEvolution *SE) {
- if (!SymbolicMax)
- SymbolicMax = SE->computeSymbolicMaxBackedgeTakenCount(L);
- return SymbolicMax;
-}
-
-bool ScalarEvolution::BackedgeTakenInfo::isConstantMaxOrZero(
- ScalarEvolution *SE) const {
+ return getConstantMax();
+}
+
+const SCEV *
+ScalarEvolution::BackedgeTakenInfo::getSymbolicMax(const Loop *L,
+ ScalarEvolution *SE) {
+ if (!SymbolicMax)
+ SymbolicMax = SE->computeSymbolicMaxBackedgeTakenCount(L);
+ return SymbolicMax;
+}
+
+bool ScalarEvolution::BackedgeTakenInfo::isConstantMaxOrZero(
+ ScalarEvolution *SE) const {
auto PredicateNotAlwaysTrue = [](const ExitNotTakenInfo &ENT) {
return !ENT.hasAlwaysTruePredicate();
};
@@ -7273,8 +7273,8 @@ bool ScalarEvolution::BackedgeTakenInfo::isConstantMaxOrZero(
bool ScalarEvolution::BackedgeTakenInfo::hasOperand(const SCEV *S,
ScalarEvolution *SE) const {
- if (getConstantMax() && getConstantMax() != SE->getCouldNotCompute() &&
- SE->hasOperand(getConstantMax(), S))
+ if (getConstantMax() && getConstantMax() != SE->getCouldNotCompute() &&
+ SE->hasOperand(getConstantMax(), S))
return true;
for (auto &ENT : ExitNotTaken)
@@ -7327,9 +7327,9 @@ ScalarEvolution::ExitLimit::ExitLimit(const SCEV *E, const SCEV *M,
/// Allocate memory for BackedgeTakenInfo and copy the not-taken count of each
/// computable exit into a persistent ExitNotTakenInfo array.
ScalarEvolution::BackedgeTakenInfo::BackedgeTakenInfo(
- ArrayRef<ScalarEvolution::BackedgeTakenInfo::EdgeExitInfo> ExitCounts,
- bool IsComplete, const SCEV *ConstantMax, bool MaxOrZero)
- : ConstantMax(ConstantMax), IsComplete(IsComplete), MaxOrZero(MaxOrZero) {
+ ArrayRef<ScalarEvolution::BackedgeTakenInfo::EdgeExitInfo> ExitCounts,
+ bool IsComplete, const SCEV *ConstantMax, bool MaxOrZero)
+ : ConstantMax(ConstantMax), IsComplete(IsComplete), MaxOrZero(MaxOrZero) {
using EdgeExitInfo = ScalarEvolution::BackedgeTakenInfo::EdgeExitInfo;
ExitNotTaken.reserve(ExitCounts.size());
@@ -7349,8 +7349,8 @@ ScalarEvolution::BackedgeTakenInfo::BackedgeTakenInfo(
return ExitNotTakenInfo(ExitBB, EL.ExactNotTaken, EL.MaxNotTaken,
std::move(Predicate));
});
- assert((isa<SCEVCouldNotCompute>(ConstantMax) ||
- isa<SCEVConstant>(ConstantMax)) &&
+ assert((isa<SCEVCouldNotCompute>(ConstantMax) ||
+ isa<SCEVConstant>(ConstantMax)) &&
"No point in having a non-constant max backedge taken count!");
}
@@ -7539,10 +7539,10 @@ ScalarEvolution::ExitLimit ScalarEvolution::computeExitLimitFromCondCached(
ScalarEvolution::ExitLimit ScalarEvolution::computeExitLimitFromCondImpl(
ExitLimitCacheTy &Cache, const Loop *L, Value *ExitCond, bool ExitIfTrue,
bool ControlsExit, bool AllowPredicates) {
- // Handle BinOp conditions (And, Or).
- if (auto LimitFromBinOp = computeExitLimitFromCondFromBinOp(
- Cache, L, ExitCond, ExitIfTrue, ControlsExit, AllowPredicates))
- return *LimitFromBinOp;
+ // Handle BinOp conditions (And, Or).
+ if (auto LimitFromBinOp = computeExitLimitFromCondFromBinOp(
+ Cache, L, ExitCond, ExitIfTrue, ControlsExit, AllowPredicates))
+ return *LimitFromBinOp;
// With an icmp, it may be feasible to compute an exact backedge-taken count.
// Proceed to the next level to examine the icmp.
@@ -7574,95 +7574,95 @@ ScalarEvolution::ExitLimit ScalarEvolution::computeExitLimitFromCondImpl(
return computeExitCountExhaustively(L, ExitCond, ExitIfTrue);
}
-Optional<ScalarEvolution::ExitLimit>
-ScalarEvolution::computeExitLimitFromCondFromBinOp(
- ExitLimitCacheTy &Cache, const Loop *L, Value *ExitCond, bool ExitIfTrue,
- bool ControlsExit, bool AllowPredicates) {
- // Check if the controlling expression for this loop is an And or Or.
- Value *Op0, *Op1;
- bool IsAnd = false;
- if (match(ExitCond, m_LogicalAnd(m_Value(Op0), m_Value(Op1))))
- IsAnd = true;
- else if (match(ExitCond, m_LogicalOr(m_Value(Op0), m_Value(Op1))))
- IsAnd = false;
- else
- return None;
-
- // EitherMayExit is true in these two cases:
- // br (and Op0 Op1), loop, exit
- // br (or Op0 Op1), exit, loop
- bool EitherMayExit = IsAnd ^ ExitIfTrue;
- ExitLimit EL0 = computeExitLimitFromCondCached(Cache, L, Op0, ExitIfTrue,
- ControlsExit && !EitherMayExit,
- AllowPredicates);
- ExitLimit EL1 = computeExitLimitFromCondCached(Cache, L, Op1, ExitIfTrue,
- ControlsExit && !EitherMayExit,
- AllowPredicates);
-
- // Be robust against unsimplified IR for the form "op i1 X, NeutralElement"
- const Constant *NeutralElement = ConstantInt::get(ExitCond->getType(), IsAnd);
- if (isa<ConstantInt>(Op1))
- return Op1 == NeutralElement ? EL0 : EL1;
- if (isa<ConstantInt>(Op0))
- return Op0 == NeutralElement ? EL1 : EL0;
-
- const SCEV *BECount = getCouldNotCompute();
- const SCEV *MaxBECount = getCouldNotCompute();
- if (EitherMayExit) {
- // Both conditions must be same for the loop to continue executing.
- // Choose the less conservative count.
- // If ExitCond is a short-circuit form (select), using
- // umin(EL0.ExactNotTaken, EL1.ExactNotTaken) is unsafe in general.
- // To see the detailed examples, please see
- // test/Analysis/ScalarEvolution/exit-count-select.ll
- bool PoisonSafe = isa<BinaryOperator>(ExitCond);
- if (!PoisonSafe)
- // Even if ExitCond is select, we can safely derive BECount using both
- // EL0 and EL1 in these cases:
- // (1) EL0.ExactNotTaken is non-zero
- // (2) EL1.ExactNotTaken is non-poison
- // (3) EL0.ExactNotTaken is zero (BECount should be simply zero and
- // it cannot be umin(0, ..))
- // The PoisonSafe assignment below is simplified and the assertion after
- // BECount calculation fully guarantees the condition (3).
- PoisonSafe = isa<SCEVConstant>(EL0.ExactNotTaken) ||
- isa<SCEVConstant>(EL1.ExactNotTaken);
- if (EL0.ExactNotTaken != getCouldNotCompute() &&
- EL1.ExactNotTaken != getCouldNotCompute() && PoisonSafe) {
- BECount =
- getUMinFromMismatchedTypes(EL0.ExactNotTaken, EL1.ExactNotTaken);
-
- // If EL0.ExactNotTaken was zero and ExitCond was a short-circuit form,
- // it should have been simplified to zero (see the condition (3) above)
- assert(!isa<BinaryOperator>(ExitCond) || !EL0.ExactNotTaken->isZero() ||
- BECount->isZero());
- }
- if (EL0.MaxNotTaken == getCouldNotCompute())
- MaxBECount = EL1.MaxNotTaken;
- else if (EL1.MaxNotTaken == getCouldNotCompute())
- MaxBECount = EL0.MaxNotTaken;
- else
- MaxBECount = getUMinFromMismatchedTypes(EL0.MaxNotTaken, EL1.MaxNotTaken);
- } else {
- // Both conditions must be same at the same time for the loop to exit.
- // For now, be conservative.
- if (EL0.ExactNotTaken == EL1.ExactNotTaken)
- BECount = EL0.ExactNotTaken;
- }
-
- // There are cases (e.g. PR26207) where computeExitLimitFromCond is able
- // to be more aggressive when computing BECount than when computing
- // MaxBECount. In these cases it is possible for EL0.ExactNotTaken and
- // EL1.ExactNotTaken to match, but for EL0.MaxNotTaken and EL1.MaxNotTaken
- // to not.
- if (isa<SCEVCouldNotCompute>(MaxBECount) &&
- !isa<SCEVCouldNotCompute>(BECount))
- MaxBECount = getConstant(getUnsignedRangeMax(BECount));
-
- return ExitLimit(BECount, MaxBECount, false,
- { &EL0.Predicates, &EL1.Predicates });
-}
-
+Optional<ScalarEvolution::ExitLimit>
+ScalarEvolution::computeExitLimitFromCondFromBinOp(
+ ExitLimitCacheTy &Cache, const Loop *L, Value *ExitCond, bool ExitIfTrue,
+ bool ControlsExit, bool AllowPredicates) {
+ // Check if the controlling expression for this loop is an And or Or.
+ Value *Op0, *Op1;
+ bool IsAnd = false;
+ if (match(ExitCond, m_LogicalAnd(m_Value(Op0), m_Value(Op1))))
+ IsAnd = true;
+ else if (match(ExitCond, m_LogicalOr(m_Value(Op0), m_Value(Op1))))
+ IsAnd = false;
+ else
+ return None;
+
+ // EitherMayExit is true in these two cases:
+ // br (and Op0 Op1), loop, exit
+ // br (or Op0 Op1), exit, loop
+ bool EitherMayExit = IsAnd ^ ExitIfTrue;
+ ExitLimit EL0 = computeExitLimitFromCondCached(Cache, L, Op0, ExitIfTrue,
+ ControlsExit && !EitherMayExit,
+ AllowPredicates);
+ ExitLimit EL1 = computeExitLimitFromCondCached(Cache, L, Op1, ExitIfTrue,
+ ControlsExit && !EitherMayExit,
+ AllowPredicates);
+
+ // Be robust against unsimplified IR for the form "op i1 X, NeutralElement"
+ const Constant *NeutralElement = ConstantInt::get(ExitCond->getType(), IsAnd);
+ if (isa<ConstantInt>(Op1))
+ return Op1 == NeutralElement ? EL0 : EL1;
+ if (isa<ConstantInt>(Op0))
+ return Op0 == NeutralElement ? EL1 : EL0;
+
+ const SCEV *BECount = getCouldNotCompute();
+ const SCEV *MaxBECount = getCouldNotCompute();
+ if (EitherMayExit) {
+ // Both conditions must be same for the loop to continue executing.
+ // Choose the less conservative count.
+ // If ExitCond is a short-circuit form (select), using
+ // umin(EL0.ExactNotTaken, EL1.ExactNotTaken) is unsafe in general.
+ // To see the detailed examples, please see
+ // test/Analysis/ScalarEvolution/exit-count-select.ll
+ bool PoisonSafe = isa<BinaryOperator>(ExitCond);
+ if (!PoisonSafe)
+ // Even if ExitCond is select, we can safely derive BECount using both
+ // EL0 and EL1 in these cases:
+ // (1) EL0.ExactNotTaken is non-zero
+ // (2) EL1.ExactNotTaken is non-poison
+ // (3) EL0.ExactNotTaken is zero (BECount should be simply zero and
+ // it cannot be umin(0, ..))
+ // The PoisonSafe assignment below is simplified and the assertion after
+ // BECount calculation fully guarantees the condition (3).
+ PoisonSafe = isa<SCEVConstant>(EL0.ExactNotTaken) ||
+ isa<SCEVConstant>(EL1.ExactNotTaken);
+ if (EL0.ExactNotTaken != getCouldNotCompute() &&
+ EL1.ExactNotTaken != getCouldNotCompute() && PoisonSafe) {
+ BECount =
+ getUMinFromMismatchedTypes(EL0.ExactNotTaken, EL1.ExactNotTaken);
+
+ // If EL0.ExactNotTaken was zero and ExitCond was a short-circuit form,
+ // it should have been simplified to zero (see the condition (3) above)
+ assert(!isa<BinaryOperator>(ExitCond) || !EL0.ExactNotTaken->isZero() ||
+ BECount->isZero());
+ }
+ if (EL0.MaxNotTaken == getCouldNotCompute())
+ MaxBECount = EL1.MaxNotTaken;
+ else if (EL1.MaxNotTaken == getCouldNotCompute())
+ MaxBECount = EL0.MaxNotTaken;
+ else
+ MaxBECount = getUMinFromMismatchedTypes(EL0.MaxNotTaken, EL1.MaxNotTaken);
+ } else {
+ // Both conditions must be same at the same time for the loop to exit.
+ // For now, be conservative.
+ if (EL0.ExactNotTaken == EL1.ExactNotTaken)
+ BECount = EL0.ExactNotTaken;
+ }
+
+ // There are cases (e.g. PR26207) where computeExitLimitFromCond is able
+ // to be more aggressive when computing BECount than when computing
+ // MaxBECount. In these cases it is possible for EL0.ExactNotTaken and
+ // EL1.ExactNotTaken to match, but for EL0.MaxNotTaken and EL1.MaxNotTaken
+ // to not.
+ if (isa<SCEVCouldNotCompute>(MaxBECount) &&
+ !isa<SCEVCouldNotCompute>(BECount))
+ MaxBECount = getConstant(getUnsignedRangeMax(BECount));
+
+ return ExitLimit(BECount, MaxBECount, false,
+ { &EL0.Predicates, &EL1.Predicates });
+}
+
ScalarEvolution::ExitLimit
ScalarEvolution::computeExitLimitFromICmp(const Loop *L,
ICmpInst *ExitCond,
@@ -8357,110 +8357,110 @@ const SCEV *ScalarEvolution::getSCEVAtScope(const SCEV *V, const Loop *L) {
/// SCEVConstant, because SCEVConstant is restricted to ConstantInt.
/// Returns NULL if the SCEV isn't representable as a Constant.
static Constant *BuildConstantFromSCEV(const SCEV *V) {
- switch (V->getSCEVType()) {
- case scCouldNotCompute:
- case scAddRecExpr:
- return nullptr;
- case scConstant:
- return cast<SCEVConstant>(V)->getValue();
- case scUnknown:
- return dyn_cast<Constant>(cast<SCEVUnknown>(V)->getValue());
- case scSignExtend: {
- const SCEVSignExtendExpr *SS = cast<SCEVSignExtendExpr>(V);
- if (Constant *CastOp = BuildConstantFromSCEV(SS->getOperand()))
- return ConstantExpr::getSExt(CastOp, SS->getType());
- return nullptr;
- }
- case scZeroExtend: {
- const SCEVZeroExtendExpr *SZ = cast<SCEVZeroExtendExpr>(V);
- if (Constant *CastOp = BuildConstantFromSCEV(SZ->getOperand()))
- return ConstantExpr::getZExt(CastOp, SZ->getType());
- return nullptr;
- }
- case scPtrToInt: {
- const SCEVPtrToIntExpr *P2I = cast<SCEVPtrToIntExpr>(V);
- if (Constant *CastOp = BuildConstantFromSCEV(P2I->getOperand()))
- return ConstantExpr::getPtrToInt(CastOp, P2I->getType());
-
- return nullptr;
- }
- case scTruncate: {
- const SCEVTruncateExpr *ST = cast<SCEVTruncateExpr>(V);
- if (Constant *CastOp = BuildConstantFromSCEV(ST->getOperand()))
- return ConstantExpr::getTrunc(CastOp, ST->getType());
- return nullptr;
- }
- case scAddExpr: {
- const SCEVAddExpr *SA = cast<SCEVAddExpr>(V);
- if (Constant *C = BuildConstantFromSCEV(SA->getOperand(0))) {
- if (PointerType *PTy = dyn_cast<PointerType>(C->getType())) {
- unsigned AS = PTy->getAddressSpace();
- Type *DestPtrTy = Type::getInt8PtrTy(C->getContext(), AS);
- C = ConstantExpr::getBitCast(C, DestPtrTy);
- }
- for (unsigned i = 1, e = SA->getNumOperands(); i != e; ++i) {
- Constant *C2 = BuildConstantFromSCEV(SA->getOperand(i));
- if (!C2)
- return nullptr;
-
- // First pointer!
- if (!C->getType()->isPointerTy() && C2->getType()->isPointerTy()) {
- unsigned AS = C2->getType()->getPointerAddressSpace();
- std::swap(C, C2);
+ switch (V->getSCEVType()) {
+ case scCouldNotCompute:
+ case scAddRecExpr:
+ return nullptr;
+ case scConstant:
+ return cast<SCEVConstant>(V)->getValue();
+ case scUnknown:
+ return dyn_cast<Constant>(cast<SCEVUnknown>(V)->getValue());
+ case scSignExtend: {
+ const SCEVSignExtendExpr *SS = cast<SCEVSignExtendExpr>(V);
+ if (Constant *CastOp = BuildConstantFromSCEV(SS->getOperand()))
+ return ConstantExpr::getSExt(CastOp, SS->getType());
+ return nullptr;
+ }
+ case scZeroExtend: {
+ const SCEVZeroExtendExpr *SZ = cast<SCEVZeroExtendExpr>(V);
+ if (Constant *CastOp = BuildConstantFromSCEV(SZ->getOperand()))
+ return ConstantExpr::getZExt(CastOp, SZ->getType());
+ return nullptr;
+ }
+ case scPtrToInt: {
+ const SCEVPtrToIntExpr *P2I = cast<SCEVPtrToIntExpr>(V);
+ if (Constant *CastOp = BuildConstantFromSCEV(P2I->getOperand()))
+ return ConstantExpr::getPtrToInt(CastOp, P2I->getType());
+
+ return nullptr;
+ }
+ case scTruncate: {
+ const SCEVTruncateExpr *ST = cast<SCEVTruncateExpr>(V);
+ if (Constant *CastOp = BuildConstantFromSCEV(ST->getOperand()))
+ return ConstantExpr::getTrunc(CastOp, ST->getType());
+ return nullptr;
+ }
+ case scAddExpr: {
+ const SCEVAddExpr *SA = cast<SCEVAddExpr>(V);
+ if (Constant *C = BuildConstantFromSCEV(SA->getOperand(0))) {
+ if (PointerType *PTy = dyn_cast<PointerType>(C->getType())) {
+ unsigned AS = PTy->getAddressSpace();
+ Type *DestPtrTy = Type::getInt8PtrTy(C->getContext(), AS);
+ C = ConstantExpr::getBitCast(C, DestPtrTy);
+ }
+ for (unsigned i = 1, e = SA->getNumOperands(); i != e; ++i) {
+ Constant *C2 = BuildConstantFromSCEV(SA->getOperand(i));
+ if (!C2)
+ return nullptr;
+
+ // First pointer!
+ if (!C->getType()->isPointerTy() && C2->getType()->isPointerTy()) {
+ unsigned AS = C2->getType()->getPointerAddressSpace();
+ std::swap(C, C2);
Type *DestPtrTy = Type::getInt8PtrTy(C->getContext(), AS);
- // The offsets have been converted to bytes. We can add bytes to an
- // i8* by GEP with the byte count in the first index.
+ // The offsets have been converted to bytes. We can add bytes to an
+ // i8* by GEP with the byte count in the first index.
C = ConstantExpr::getBitCast(C, DestPtrTy);
}
- // Don't bother trying to sum two pointers. We probably can't
- // statically compute a load that results from it anyway.
- if (C2->getType()->isPointerTy())
- return nullptr;
-
- if (PointerType *PTy = dyn_cast<PointerType>(C->getType())) {
- if (PTy->getElementType()->isStructTy())
- C2 = ConstantExpr::getIntegerCast(
- C2, Type::getInt32Ty(C->getContext()), true);
- C = ConstantExpr::getGetElementPtr(PTy->getElementType(), C, C2);
- } else
- C = ConstantExpr::getAdd(C, C2);
+ // Don't bother trying to sum two pointers. We probably can't
+ // statically compute a load that results from it anyway.
+ if (C2->getType()->isPointerTy())
+ return nullptr;
+
+ if (PointerType *PTy = dyn_cast<PointerType>(C->getType())) {
+ if (PTy->getElementType()->isStructTy())
+ C2 = ConstantExpr::getIntegerCast(
+ C2, Type::getInt32Ty(C->getContext()), true);
+ C = ConstantExpr::getGetElementPtr(PTy->getElementType(), C, C2);
+ } else
+ C = ConstantExpr::getAdd(C, C2);
}
- return C;
- }
- return nullptr;
- }
- case scMulExpr: {
- const SCEVMulExpr *SM = cast<SCEVMulExpr>(V);
- if (Constant *C = BuildConstantFromSCEV(SM->getOperand(0))) {
- // Don't bother with pointers at all.
- if (C->getType()->isPointerTy())
- return nullptr;
- for (unsigned i = 1, e = SM->getNumOperands(); i != e; ++i) {
- Constant *C2 = BuildConstantFromSCEV(SM->getOperand(i));
- if (!C2 || C2->getType()->isPointerTy())
- return nullptr;
- C = ConstantExpr::getMul(C, C2);
+ return C;
+ }
+ return nullptr;
+ }
+ case scMulExpr: {
+ const SCEVMulExpr *SM = cast<SCEVMulExpr>(V);
+ if (Constant *C = BuildConstantFromSCEV(SM->getOperand(0))) {
+ // Don't bother with pointers at all.
+ if (C->getType()->isPointerTy())
+ return nullptr;
+ for (unsigned i = 1, e = SM->getNumOperands(); i != e; ++i) {
+ Constant *C2 = BuildConstantFromSCEV(SM->getOperand(i));
+ if (!C2 || C2->getType()->isPointerTy())
+ return nullptr;
+ C = ConstantExpr::getMul(C, C2);
}
- return C;
- }
- return nullptr;
- }
- case scUDivExpr: {
- const SCEVUDivExpr *SU = cast<SCEVUDivExpr>(V);
- if (Constant *LHS = BuildConstantFromSCEV(SU->getLHS()))
- if (Constant *RHS = BuildConstantFromSCEV(SU->getRHS()))
- if (LHS->getType() == RHS->getType())
- return ConstantExpr::getUDiv(LHS, RHS);
- return nullptr;
- }
- case scSMaxExpr:
- case scUMaxExpr:
- case scSMinExpr:
- case scUMinExpr:
- return nullptr; // TODO: smax, umax, smin, umax.
- }
- llvm_unreachable("Unknown SCEV kind!");
+ return C;
+ }
+ return nullptr;
+ }
+ case scUDivExpr: {
+ const SCEVUDivExpr *SU = cast<SCEVUDivExpr>(V);
+ if (Constant *LHS = BuildConstantFromSCEV(SU->getLHS()))
+ if (Constant *RHS = BuildConstantFromSCEV(SU->getRHS()))
+ if (LHS->getType() == RHS->getType())
+ return ConstantExpr::getUDiv(LHS, RHS);
+ return nullptr;
+ }
+ case scSMaxExpr:
+ case scUMaxExpr:
+ case scSMinExpr:
+ case scUMinExpr:
+ return nullptr; // TODO: smax, umax, smin, umax.
+ }
+ llvm_unreachable("Unknown SCEV kind!");
}
const SCEV *ScalarEvolution::computeSCEVAtScope(const SCEV *V, const Loop *L) {
@@ -8471,22 +8471,22 @@ const SCEV *ScalarEvolution::computeSCEVAtScope(const SCEV *V, const Loop *L) {
if (const SCEVUnknown *SU = dyn_cast<SCEVUnknown>(V)) {
if (Instruction *I = dyn_cast<Instruction>(SU->getValue())) {
if (PHINode *PN = dyn_cast<PHINode>(I)) {
- const Loop *CurrLoop = this->LI[I->getParent()];
+ const Loop *CurrLoop = this->LI[I->getParent()];
// Looking for loop exit value.
- if (CurrLoop && CurrLoop->getParentLoop() == L &&
- PN->getParent() == CurrLoop->getHeader()) {
+ if (CurrLoop && CurrLoop->getParentLoop() == L &&
+ PN->getParent() == CurrLoop->getHeader()) {
// Okay, there is no closed form solution for the PHI node. Check
// to see if the loop that contains it has a known backedge-taken
// count. If so, we may be able to force computation of the exit
// value.
- const SCEV *BackedgeTakenCount = getBackedgeTakenCount(CurrLoop);
+ const SCEV *BackedgeTakenCount = getBackedgeTakenCount(CurrLoop);
// This trivial case can show up in some degenerate cases where
// the incoming IR has not yet been fully simplified.
if (BackedgeTakenCount->isZero()) {
Value *InitValue = nullptr;
bool MultipleInitValues = false;
for (unsigned i = 0; i < PN->getNumIncomingValues(); i++) {
- if (!CurrLoop->contains(PN->getIncomingBlock(i))) {
+ if (!CurrLoop->contains(PN->getIncomingBlock(i))) {
if (!InitValue)
InitValue = PN->getIncomingValue(i);
else if (InitValue != PN->getIncomingValue(i)) {
@@ -8504,18 +8504,18 @@ const SCEV *ScalarEvolution::computeSCEVAtScope(const SCEV *V, const Loop *L) {
isKnownPositive(BackedgeTakenCount) &&
PN->getNumIncomingValues() == 2) {
- unsigned InLoopPred =
- CurrLoop->contains(PN->getIncomingBlock(0)) ? 0 : 1;
+ unsigned InLoopPred =
+ CurrLoop->contains(PN->getIncomingBlock(0)) ? 0 : 1;
Value *BackedgeVal = PN->getIncomingValue(InLoopPred);
- if (CurrLoop->isLoopInvariant(BackedgeVal))
+ if (CurrLoop->isLoopInvariant(BackedgeVal))
return getSCEV(BackedgeVal);
}
if (auto *BTCC = dyn_cast<SCEVConstant>(BackedgeTakenCount)) {
// Okay, we know how many times the containing loop executes. If
// this is a constant evolving PHI node, get the final value at
// the specified iteration number.
- Constant *RV = getConstantEvolutionLoopExitValue(
- PN, BTCC->getAPInt(), CurrLoop);
+ Constant *RV = getConstantEvolutionLoopExitValue(
+ PN, BTCC->getAPInt(), CurrLoop);
if (RV) return getSCEV(RV);
}
}
@@ -8571,10 +8571,10 @@ const SCEV *ScalarEvolution::computeSCEVAtScope(const SCEV *V, const Loop *L) {
if (const CmpInst *CI = dyn_cast<CmpInst>(I))
C = ConstantFoldCompareInstOperands(CI->getPredicate(), Operands[0],
Operands[1], DL, &TLI);
- else if (const LoadInst *Load = dyn_cast<LoadInst>(I)) {
- if (!Load->isVolatile())
- C = ConstantFoldLoadFromConstPtr(Operands[0], Load->getType(),
- DL);
+ else if (const LoadInst *Load = dyn_cast<LoadInst>(I)) {
+ if (!Load->isVolatile())
+ C = ConstantFoldLoadFromConstPtr(Operands[0], Load->getType(),
+ DL);
} else
C = ConstantFoldInstOperands(I, Operands, DL, &TLI);
if (!C) return V;
@@ -8691,13 +8691,13 @@ const SCEV *ScalarEvolution::computeSCEVAtScope(const SCEV *V, const Loop *L) {
return getTruncateExpr(Op, Cast->getType());
}
- if (const SCEVPtrToIntExpr *Cast = dyn_cast<SCEVPtrToIntExpr>(V)) {
- const SCEV *Op = getSCEVAtScope(Cast->getOperand(), L);
- if (Op == Cast->getOperand())
- return Cast; // must be loop invariant
- return getPtrToIntExpr(Op, Cast->getType());
- }
-
+ if (const SCEVPtrToIntExpr *Cast = dyn_cast<SCEVPtrToIntExpr>(V)) {
+ const SCEV *Op = getSCEVAtScope(Cast->getOperand(), L);
+ if (Op == Cast->getOperand())
+ return Cast; // must be loop invariant
+ return getPtrToIntExpr(Op, Cast->getType());
+ }
+
llvm_unreachable("Unknown SCEV type!");
}
@@ -9112,10 +9112,10 @@ ScalarEvolution::howFarToZero(const SCEV *V, const Loop *L, bool ControlsExit,
// 1*N = -Start; -1*N = Start (mod 2^BW), so:
// N = Distance (as unsigned)
if (StepC->getValue()->isOne() || StepC->getValue()->isMinusOne()) {
- APInt MaxBECount = getUnsignedRangeMax(applyLoopGuards(Distance, L));
- APInt MaxBECountBase = getUnsignedRangeMax(Distance);
- if (MaxBECountBase.ult(MaxBECount))
- MaxBECount = MaxBECountBase;
+ APInt MaxBECount = getUnsignedRangeMax(applyLoopGuards(Distance, L));
+ APInt MaxBECountBase = getUnsignedRangeMax(Distance);
+ if (MaxBECountBase.ult(MaxBECount))
+ MaxBECount = MaxBECountBase;
// When a loop like "for (int i = 0; i != n; ++i) { /* body */ }" is rotated,
// we end up with a loop whose backedge-taken count is n - 1. Detect this
@@ -9180,19 +9180,19 @@ ScalarEvolution::howFarToNonZero(const SCEV *V, const Loop *L) {
return getCouldNotCompute();
}
-std::pair<const BasicBlock *, const BasicBlock *>
-ScalarEvolution::getPredecessorWithUniqueSuccessorForBB(const BasicBlock *BB)
- const {
+std::pair<const BasicBlock *, const BasicBlock *>
+ScalarEvolution::getPredecessorWithUniqueSuccessorForBB(const BasicBlock *BB)
+ const {
// If the block has a unique predecessor, then there is no path from the
// predecessor to the block that does not go through the direct edge
// from the predecessor to the block.
- if (const BasicBlock *Pred = BB->getSinglePredecessor())
+ if (const BasicBlock *Pred = BB->getSinglePredecessor())
return {Pred, BB};
// A loop's header is defined to be a block that dominates the loop.
// If the header has a unique predecessor outside the loop, it must be
// a block that has exactly one successor that can reach the loop.
- if (const Loop *L = LI.getLoopFor(BB))
+ if (const Loop *L = LI.getLoopFor(BB))
return {L->getLoopPredecessor(), L->getHeader()};
return {nullptr, nullptr};
@@ -9521,14 +9521,14 @@ bool ScalarEvolution::isKnownPredicate(ICmpInst::Predicate Pred,
return isKnownViaNonRecursiveReasoning(Pred, LHS, RHS);
}
-bool ScalarEvolution::isKnownPredicateAt(ICmpInst::Predicate Pred,
- const SCEV *LHS, const SCEV *RHS,
- const Instruction *Context) {
- // TODO: Analyze guards and assumes from Context's block.
- return isKnownPredicate(Pred, LHS, RHS) ||
- isBasicBlockEntryGuardedByCond(Context->getParent(), Pred, LHS, RHS);
-}
-
+bool ScalarEvolution::isKnownPredicateAt(ICmpInst::Predicate Pred,
+ const SCEV *LHS, const SCEV *RHS,
+ const Instruction *Context) {
+ // TODO: Analyze guards and assumes from Context's block.
+ return isKnownPredicate(Pred, LHS, RHS) ||
+ isBasicBlockEntryGuardedByCond(Context->getParent(), Pred, LHS, RHS);
+}
+
bool ScalarEvolution::isKnownOnEveryIteration(ICmpInst::Predicate Pred,
const SCEVAddRecExpr *LHS,
const SCEV *RHS) {
@@ -9537,30 +9537,30 @@ bool ScalarEvolution::isKnownOnEveryIteration(ICmpInst::Predicate Pred,
isLoopBackedgeGuardedByCond(L, Pred, LHS->getPostIncExpr(*this), RHS);
}
-Optional<ScalarEvolution::MonotonicPredicateType>
-ScalarEvolution::getMonotonicPredicateType(const SCEVAddRecExpr *LHS,
- ICmpInst::Predicate Pred) {
- auto Result = getMonotonicPredicateTypeImpl(LHS, Pred);
+Optional<ScalarEvolution::MonotonicPredicateType>
+ScalarEvolution::getMonotonicPredicateType(const SCEVAddRecExpr *LHS,
+ ICmpInst::Predicate Pred) {
+ auto Result = getMonotonicPredicateTypeImpl(LHS, Pred);
#ifndef NDEBUG
// Verify an invariant: inverting the predicate should turn a monotonically
// increasing change to a monotonically decreasing one, and vice versa.
- if (Result) {
- auto ResultSwapped =
- getMonotonicPredicateTypeImpl(LHS, ICmpInst::getSwappedPredicate(Pred));
+ if (Result) {
+ auto ResultSwapped =
+ getMonotonicPredicateTypeImpl(LHS, ICmpInst::getSwappedPredicate(Pred));
- assert(ResultSwapped.hasValue() && "should be able to analyze both!");
- assert(ResultSwapped.getValue() != Result.getValue() &&
+ assert(ResultSwapped.hasValue() && "should be able to analyze both!");
+ assert(ResultSwapped.getValue() != Result.getValue() &&
"monotonicity should flip as we flip the predicate");
- }
+ }
#endif
return Result;
}
-Optional<ScalarEvolution::MonotonicPredicateType>
-ScalarEvolution::getMonotonicPredicateTypeImpl(const SCEVAddRecExpr *LHS,
- ICmpInst::Predicate Pred) {
+Optional<ScalarEvolution::MonotonicPredicateType>
+ScalarEvolution::getMonotonicPredicateTypeImpl(const SCEVAddRecExpr *LHS,
+ ICmpInst::Predicate Pred) {
// A zero step value for LHS means the induction variable is essentially a
// loop invariant value. We don't really depend on the predicate actually
// flipping from false to true (for increasing predicates, and the other way
@@ -9571,46 +9571,46 @@ ScalarEvolution::getMonotonicPredicateTypeImpl(const SCEVAddRecExpr *LHS,
// where SCEV can prove X >= 0 but not prove X > 0, so it is helpful to be
// as general as possible.
- // Only handle LE/LT/GE/GT predicates.
- if (!ICmpInst::isRelational(Pred))
- return None;
+ // Only handle LE/LT/GE/GT predicates.
+ if (!ICmpInst::isRelational(Pred))
+ return None;
+
+ bool IsGreater = ICmpInst::isGE(Pred) || ICmpInst::isGT(Pred);
+ assert((IsGreater || ICmpInst::isLE(Pred) || ICmpInst::isLT(Pred)) &&
+ "Should be greater or less!");
- bool IsGreater = ICmpInst::isGE(Pred) || ICmpInst::isGT(Pred);
- assert((IsGreater || ICmpInst::isLE(Pred) || ICmpInst::isLT(Pred)) &&
- "Should be greater or less!");
-
- // Check that AR does not wrap.
- if (ICmpInst::isUnsigned(Pred)) {
+ // Check that AR does not wrap.
+ if (ICmpInst::isUnsigned(Pred)) {
if (!LHS->hasNoUnsignedWrap())
- return None;
- return IsGreater ? MonotonicallyIncreasing : MonotonicallyDecreasing;
- } else {
- assert(ICmpInst::isSigned(Pred) &&
- "Relational predicate is either signed or unsigned!");
+ return None;
+ return IsGreater ? MonotonicallyIncreasing : MonotonicallyDecreasing;
+ } else {
+ assert(ICmpInst::isSigned(Pred) &&
+ "Relational predicate is either signed or unsigned!");
if (!LHS->hasNoSignedWrap())
- return None;
+ return None;
const SCEV *Step = LHS->getStepRecurrence(*this);
- if (isKnownNonNegative(Step))
- return IsGreater ? MonotonicallyIncreasing : MonotonicallyDecreasing;
+ if (isKnownNonNegative(Step))
+ return IsGreater ? MonotonicallyIncreasing : MonotonicallyDecreasing;
- if (isKnownNonPositive(Step))
- return !IsGreater ? MonotonicallyIncreasing : MonotonicallyDecreasing;
+ if (isKnownNonPositive(Step))
+ return !IsGreater ? MonotonicallyIncreasing : MonotonicallyDecreasing;
- return None;
+ return None;
}
}
-Optional<ScalarEvolution::LoopInvariantPredicate>
-ScalarEvolution::getLoopInvariantPredicate(ICmpInst::Predicate Pred,
- const SCEV *LHS, const SCEV *RHS,
- const Loop *L) {
+Optional<ScalarEvolution::LoopInvariantPredicate>
+ScalarEvolution::getLoopInvariantPredicate(ICmpInst::Predicate Pred,
+ const SCEV *LHS, const SCEV *RHS,
+ const Loop *L) {
// If there is a loop-invariant, force it into the RHS, otherwise bail out.
if (!isLoopInvariant(RHS, L)) {
if (!isLoopInvariant(LHS, L))
- return None;
+ return None;
std::swap(LHS, RHS);
Pred = ICmpInst::getSwappedPredicate(Pred);
@@ -9618,11 +9618,11 @@ ScalarEvolution::getLoopInvariantPredicate(ICmpInst::Predicate Pred,
const SCEVAddRecExpr *ArLHS = dyn_cast<SCEVAddRecExpr>(LHS);
if (!ArLHS || ArLHS->getLoop() != L)
- return None;
+ return None;
- auto MonotonicType = getMonotonicPredicateType(ArLHS, Pred);
- if (!MonotonicType)
- return None;
+ auto MonotonicType = getMonotonicPredicateType(ArLHS, Pred);
+ if (!MonotonicType)
+ return None;
// If the predicate "ArLHS `Pred` RHS" monotonically increases from false to
// true as the loop iterates, and the backedge is control dependent on
// "ArLHS `Pred` RHS" == true then we can reason as follows:
@@ -9640,79 +9640,79 @@ ScalarEvolution::getLoopInvariantPredicate(ICmpInst::Predicate Pred,
//
// A similar reasoning applies for a monotonically decreasing predicate, by
// replacing true with false and false with true in the above two bullets.
- bool Increasing = *MonotonicType == ScalarEvolution::MonotonicallyIncreasing;
+ bool Increasing = *MonotonicType == ScalarEvolution::MonotonicallyIncreasing;
auto P = Increasing ? Pred : ICmpInst::getInversePredicate(Pred);
if (!isLoopBackedgeGuardedByCond(L, P, LHS, RHS))
- return None;
-
- return ScalarEvolution::LoopInvariantPredicate(Pred, ArLHS->getStart(), RHS);
-}
-
-Optional<ScalarEvolution::LoopInvariantPredicate>
-ScalarEvolution::getLoopInvariantExitCondDuringFirstIterations(
- ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, const Loop *L,
- const Instruction *Context, const SCEV *MaxIter) {
- // Try to prove the following set of facts:
- // - The predicate is monotonic in the iteration space.
- // - If the check does not fail on the 1st iteration:
- // - No overflow will happen during first MaxIter iterations;
- // - It will not fail on the MaxIter'th iteration.
- // If the check does fail on the 1st iteration, we leave the loop and no
- // other checks matter.
-
- // If there is a loop-invariant, force it into the RHS, otherwise bail out.
- if (!isLoopInvariant(RHS, L)) {
- if (!isLoopInvariant(LHS, L))
- return None;
-
- std::swap(LHS, RHS);
- Pred = ICmpInst::getSwappedPredicate(Pred);
- }
-
- auto *AR = dyn_cast<SCEVAddRecExpr>(LHS);
- if (!AR || AR->getLoop() != L)
- return None;
-
- // The predicate must be relational (i.e. <, <=, >=, >).
- if (!ICmpInst::isRelational(Pred))
- return None;
-
- // TODO: Support steps other than +/- 1.
- const SCEV *Step = AR->getStepRecurrence(*this);
- auto *One = getOne(Step->getType());
- auto *MinusOne = getNegativeSCEV(One);
- if (Step != One && Step != MinusOne)
- return None;
-
- // Type mismatch here means that MaxIter is potentially larger than max
- // unsigned value in start type, which mean we cannot prove no wrap for the
- // indvar.
- if (AR->getType() != MaxIter->getType())
- return None;
-
- // Value of IV on suggested last iteration.
- const SCEV *Last = AR->evaluateAtIteration(MaxIter, *this);
- // Does it still meet the requirement?
- if (!isLoopBackedgeGuardedByCond(L, Pred, Last, RHS))
- return None;
- // Because step is +/- 1 and MaxIter has same type as Start (i.e. it does
- // not exceed max unsigned value of this type), this effectively proves
- // that there is no wrap during the iteration. To prove that there is no
- // signed/unsigned wrap, we need to check that
- // Start <= Last for step = 1 or Start >= Last for step = -1.
- ICmpInst::Predicate NoOverflowPred =
- CmpInst::isSigned(Pred) ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE;
- if (Step == MinusOne)
- NoOverflowPred = CmpInst::getSwappedPredicate(NoOverflowPred);
- const SCEV *Start = AR->getStart();
- if (!isKnownPredicateAt(NoOverflowPred, Start, Last, Context))
- return None;
-
- // Everything is fine.
- return ScalarEvolution::LoopInvariantPredicate(Pred, Start, RHS);
-}
-
+ return None;
+
+ return ScalarEvolution::LoopInvariantPredicate(Pred, ArLHS->getStart(), RHS);
+}
+
+Optional<ScalarEvolution::LoopInvariantPredicate>
+ScalarEvolution::getLoopInvariantExitCondDuringFirstIterations(
+ ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, const Loop *L,
+ const Instruction *Context, const SCEV *MaxIter) {
+ // Try to prove the following set of facts:
+ // - The predicate is monotonic in the iteration space.
+ // - If the check does not fail on the 1st iteration:
+ // - No overflow will happen during first MaxIter iterations;
+ // - It will not fail on the MaxIter'th iteration.
+ // If the check does fail on the 1st iteration, we leave the loop and no
+ // other checks matter.
+
+ // If there is a loop-invariant, force it into the RHS, otherwise bail out.
+ if (!isLoopInvariant(RHS, L)) {
+ if (!isLoopInvariant(LHS, L))
+ return None;
+
+ std::swap(LHS, RHS);
+ Pred = ICmpInst::getSwappedPredicate(Pred);
+ }
+
+ auto *AR = dyn_cast<SCEVAddRecExpr>(LHS);
+ if (!AR || AR->getLoop() != L)
+ return None;
+
+ // The predicate must be relational (i.e. <, <=, >=, >).
+ if (!ICmpInst::isRelational(Pred))
+ return None;
+
+ // TODO: Support steps other than +/- 1.
+ const SCEV *Step = AR->getStepRecurrence(*this);
+ auto *One = getOne(Step->getType());
+ auto *MinusOne = getNegativeSCEV(One);
+ if (Step != One && Step != MinusOne)
+ return None;
+
+ // Type mismatch here means that MaxIter is potentially larger than max
+ // unsigned value in start type, which mean we cannot prove no wrap for the
+ // indvar.
+ if (AR->getType() != MaxIter->getType())
+ return None;
+
+ // Value of IV on suggested last iteration.
+ const SCEV *Last = AR->evaluateAtIteration(MaxIter, *this);
+ // Does it still meet the requirement?
+ if (!isLoopBackedgeGuardedByCond(L, Pred, Last, RHS))
+ return None;
+ // Because step is +/- 1 and MaxIter has same type as Start (i.e. it does
+ // not exceed max unsigned value of this type), this effectively proves
+ // that there is no wrap during the iteration. To prove that there is no
+ // signed/unsigned wrap, we need to check that
+ // Start <= Last for step = 1 or Start >= Last for step = -1.
+ ICmpInst::Predicate NoOverflowPred =
+ CmpInst::isSigned(Pred) ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE;
+ if (Step == MinusOne)
+ NoOverflowPred = CmpInst::getSwappedPredicate(NoOverflowPred);
+ const SCEV *Start = AR->getStart();
+ if (!isKnownPredicateAt(NoOverflowPred, Start, Last, Context))
+ return None;
+
+ // Everything is fine.
+ return ScalarEvolution::LoopInvariantPredicate(Pred, Start, RHS);
+}
+
bool ScalarEvolution::isKnownPredicateViaConstantRanges(
ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS) {
if (HasSameValue(LHS, RHS))
@@ -9795,24 +9795,24 @@ bool ScalarEvolution::isKnownPredicateViaNoOverflow(ICmpInst::Predicate Pred,
if (MatchBinaryAddToConst(LHS, RHS, C, SCEV::FlagNSW) && C.isNegative())
return true;
break;
-
- case ICmpInst::ICMP_UGE:
- std::swap(LHS, RHS);
- LLVM_FALLTHROUGH;
- case ICmpInst::ICMP_ULE:
- // X u<= (X + C)<nuw> for any C
- if (MatchBinaryAddToConst(RHS, LHS, C, SCEV::FlagNUW))
- return true;
- break;
-
- case ICmpInst::ICMP_UGT:
- std::swap(LHS, RHS);
- LLVM_FALLTHROUGH;
- case ICmpInst::ICMP_ULT:
- // X u< (X + C)<nuw> if C != 0
- if (MatchBinaryAddToConst(RHS, LHS, C, SCEV::FlagNUW) && !C.isNullValue())
- return true;
- break;
+
+ case ICmpInst::ICMP_UGE:
+ std::swap(LHS, RHS);
+ LLVM_FALLTHROUGH;
+ case ICmpInst::ICMP_ULE:
+ // X u<= (X + C)<nuw> for any C
+ if (MatchBinaryAddToConst(RHS, LHS, C, SCEV::FlagNUW))
+ return true;
+ break;
+
+ case ICmpInst::ICMP_UGT:
+ std::swap(LHS, RHS);
+ LLVM_FALLTHROUGH;
+ case ICmpInst::ICMP_ULT:
+ // X u< (X + C)<nuw> if C != 0
+ if (MatchBinaryAddToConst(RHS, LHS, C, SCEV::FlagNUW) && !C.isNullValue())
+ return true;
+ break;
}
return false;
@@ -9840,14 +9840,14 @@ bool ScalarEvolution::isKnownPredicateViaSplitting(ICmpInst::Predicate Pred,
isKnownPredicate(CmpInst::ICMP_SLT, LHS, RHS);
}
-bool ScalarEvolution::isImpliedViaGuard(const BasicBlock *BB,
+bool ScalarEvolution::isImpliedViaGuard(const BasicBlock *BB,
ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS) {
// No need to even try if we know the module has no guards.
if (!HasGuards)
return false;
- return any_of(*BB, [&](const Instruction &I) {
+ return any_of(*BB, [&](const Instruction &I) {
using namespace llvm::PatternMatch;
Value *Condition;
@@ -9970,12 +9970,12 @@ ScalarEvolution::isLoopBackedgeGuardedByCond(const Loop *L,
return false;
}
-bool ScalarEvolution::isBasicBlockEntryGuardedByCond(const BasicBlock *BB,
- ICmpInst::Predicate Pred,
- const SCEV *LHS,
- const SCEV *RHS) {
+bool ScalarEvolution::isBasicBlockEntryGuardedByCond(const BasicBlock *BB,
+ ICmpInst::Predicate Pred,
+ const SCEV *LHS,
+ const SCEV *RHS) {
if (VerifyIR)
- assert(!verifyFunction(*BB->getParent(), &dbgs()) &&
+ assert(!verifyFunction(*BB->getParent(), &dbgs()) &&
"This cannot be done on broken IR!");
if (isKnownViaNonRecursiveReasoning(Pred, LHS, RHS))
@@ -10001,7 +10001,7 @@ bool ScalarEvolution::isBasicBlockEntryGuardedByCond(const BasicBlock *BB,
}
// Try to prove (Pred, LHS, RHS) using isImpliedViaGuard.
- auto ProveViaGuard = [&](const BasicBlock *Block) {
+ auto ProveViaGuard = [&](const BasicBlock *Block) {
if (isImpliedViaGuard(Block, Pred, LHS, RHS))
return true;
if (ProvingStrictComparison) {
@@ -10018,39 +10018,39 @@ bool ScalarEvolution::isBasicBlockEntryGuardedByCond(const BasicBlock *BB,
};
// Try to prove (Pred, LHS, RHS) using isImpliedCond.
- auto ProveViaCond = [&](const Value *Condition, bool Inverse) {
- const Instruction *Context = &BB->front();
- if (isImpliedCond(Pred, LHS, RHS, Condition, Inverse, Context))
+ auto ProveViaCond = [&](const Value *Condition, bool Inverse) {
+ const Instruction *Context = &BB->front();
+ if (isImpliedCond(Pred, LHS, RHS, Condition, Inverse, Context))
return true;
if (ProvingStrictComparison) {
if (!ProvedNonStrictComparison)
- ProvedNonStrictComparison = isImpliedCond(NonStrictPredicate, LHS, RHS,
- Condition, Inverse, Context);
+ ProvedNonStrictComparison = isImpliedCond(NonStrictPredicate, LHS, RHS,
+ Condition, Inverse, Context);
if (!ProvedNonEquality)
- ProvedNonEquality = isImpliedCond(ICmpInst::ICMP_NE, LHS, RHS,
- Condition, Inverse, Context);
+ ProvedNonEquality = isImpliedCond(ICmpInst::ICMP_NE, LHS, RHS,
+ Condition, Inverse, Context);
if (ProvedNonStrictComparison && ProvedNonEquality)
return true;
}
return false;
};
- // Starting at the block's predecessor, climb up the predecessor chain, as long
+ // Starting at the block's predecessor, climb up the predecessor chain, as long
// as there are predecessors that can be found that have unique successors
- // leading to the original block.
- const Loop *ContainingLoop = LI.getLoopFor(BB);
- const BasicBlock *PredBB;
- if (ContainingLoop && ContainingLoop->getHeader() == BB)
- PredBB = ContainingLoop->getLoopPredecessor();
- else
- PredBB = BB->getSinglePredecessor();
- for (std::pair<const BasicBlock *, const BasicBlock *> Pair(PredBB, BB);
- Pair.first; Pair = getPredecessorWithUniqueSuccessorForBB(Pair.first)) {
+ // leading to the original block.
+ const Loop *ContainingLoop = LI.getLoopFor(BB);
+ const BasicBlock *PredBB;
+ if (ContainingLoop && ContainingLoop->getHeader() == BB)
+ PredBB = ContainingLoop->getLoopPredecessor();
+ else
+ PredBB = BB->getSinglePredecessor();
+ for (std::pair<const BasicBlock *, const BasicBlock *> Pair(PredBB, BB);
+ Pair.first; Pair = getPredecessorWithUniqueSuccessorForBB(Pair.first)) {
if (ProveViaGuard(Pair.first))
return true;
- const BranchInst *LoopEntryPredicate =
- dyn_cast<BranchInst>(Pair.first->getTerminator());
+ const BranchInst *LoopEntryPredicate =
+ dyn_cast<BranchInst>(Pair.first->getTerminator());
if (!LoopEntryPredicate ||
LoopEntryPredicate->isUnconditional())
continue;
@@ -10065,7 +10065,7 @@ bool ScalarEvolution::isBasicBlockEntryGuardedByCond(const BasicBlock *BB,
if (!AssumeVH)
continue;
auto *CI = cast<CallInst>(AssumeVH);
- if (!DT.dominates(CI, BB))
+ if (!DT.dominates(CI, BB))
continue;
if (ProveViaCond(CI->getArgOperand(0), false))
@@ -10075,27 +10075,27 @@ bool ScalarEvolution::isBasicBlockEntryGuardedByCond(const BasicBlock *BB,
return false;
}
-bool ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L,
- ICmpInst::Predicate Pred,
- const SCEV *LHS,
- const SCEV *RHS) {
- // Interpret a null as meaning no loop, where there is obviously no guard
- // (interprocedural conditions notwithstanding).
- if (!L)
- return false;
-
- // Both LHS and RHS must be available at loop entry.
- assert(isAvailableAtLoopEntry(LHS, L) &&
- "LHS is not available at Loop Entry");
- assert(isAvailableAtLoopEntry(RHS, L) &&
- "RHS is not available at Loop Entry");
- return isBasicBlockEntryGuardedByCond(L->getHeader(), Pred, LHS, RHS);
-}
-
-bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS,
- const SCEV *RHS,
- const Value *FoundCondValue, bool Inverse,
- const Instruction *Context) {
+bool ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L,
+ ICmpInst::Predicate Pred,
+ const SCEV *LHS,
+ const SCEV *RHS) {
+ // Interpret a null as meaning no loop, where there is obviously no guard
+ // (interprocedural conditions notwithstanding).
+ if (!L)
+ return false;
+
+ // Both LHS and RHS must be available at loop entry.
+ assert(isAvailableAtLoopEntry(LHS, L) &&
+ "LHS is not available at Loop Entry");
+ assert(isAvailableAtLoopEntry(RHS, L) &&
+ "RHS is not available at Loop Entry");
+ return isBasicBlockEntryGuardedByCond(L->getHeader(), Pred, LHS, RHS);
+}
+
+bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS,
+ const SCEV *RHS,
+ const Value *FoundCondValue, bool Inverse,
+ const Instruction *Context) {
if (!PendingLoopPredicates.insert(FoundCondValue).second)
return false;
@@ -10103,23 +10103,23 @@ bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS,
make_scope_exit([&]() { PendingLoopPredicates.erase(FoundCondValue); });
// Recursively handle And and Or conditions.
- if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(FoundCondValue)) {
+ if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(FoundCondValue)) {
if (BO->getOpcode() == Instruction::And) {
if (!Inverse)
- return isImpliedCond(Pred, LHS, RHS, BO->getOperand(0), Inverse,
- Context) ||
- isImpliedCond(Pred, LHS, RHS, BO->getOperand(1), Inverse,
- Context);
+ return isImpliedCond(Pred, LHS, RHS, BO->getOperand(0), Inverse,
+ Context) ||
+ isImpliedCond(Pred, LHS, RHS, BO->getOperand(1), Inverse,
+ Context);
} else if (BO->getOpcode() == Instruction::Or) {
if (Inverse)
- return isImpliedCond(Pred, LHS, RHS, BO->getOperand(0), Inverse,
- Context) ||
- isImpliedCond(Pred, LHS, RHS, BO->getOperand(1), Inverse,
- Context);
+ return isImpliedCond(Pred, LHS, RHS, BO->getOperand(0), Inverse,
+ Context) ||
+ isImpliedCond(Pred, LHS, RHS, BO->getOperand(1), Inverse,
+ Context);
}
}
- const ICmpInst *ICI = dyn_cast<ICmpInst>(FoundCondValue);
+ const ICmpInst *ICI = dyn_cast<ICmpInst>(FoundCondValue);
if (!ICI) return false;
// Now that we found a conditional branch that dominates the loop or controls
@@ -10133,36 +10133,36 @@ bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS,
const SCEV *FoundLHS = getSCEV(ICI->getOperand(0));
const SCEV *FoundRHS = getSCEV(ICI->getOperand(1));
- return isImpliedCond(Pred, LHS, RHS, FoundPred, FoundLHS, FoundRHS, Context);
+ return isImpliedCond(Pred, LHS, RHS, FoundPred, FoundLHS, FoundRHS, Context);
}
bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS,
const SCEV *RHS,
ICmpInst::Predicate FoundPred,
- const SCEV *FoundLHS, const SCEV *FoundRHS,
- const Instruction *Context) {
+ const SCEV *FoundLHS, const SCEV *FoundRHS,
+ const Instruction *Context) {
// Balance the types.
if (getTypeSizeInBits(LHS->getType()) <
getTypeSizeInBits(FoundLHS->getType())) {
- // For unsigned and equality predicates, try to prove that both found
- // operands fit into narrow unsigned range. If so, try to prove facts in
- // narrow types.
- if (!CmpInst::isSigned(FoundPred)) {
- auto *NarrowType = LHS->getType();
- auto *WideType = FoundLHS->getType();
- auto BitWidth = getTypeSizeInBits(NarrowType);
- const SCEV *MaxValue = getZeroExtendExpr(
- getConstant(APInt::getMaxValue(BitWidth)), WideType);
- if (isKnownPredicate(ICmpInst::ICMP_ULE, FoundLHS, MaxValue) &&
- isKnownPredicate(ICmpInst::ICMP_ULE, FoundRHS, MaxValue)) {
- const SCEV *TruncFoundLHS = getTruncateExpr(FoundLHS, NarrowType);
- const SCEV *TruncFoundRHS = getTruncateExpr(FoundRHS, NarrowType);
- if (isImpliedCondBalancedTypes(Pred, LHS, RHS, FoundPred, TruncFoundLHS,
- TruncFoundRHS, Context))
- return true;
- }
- }
-
+ // For unsigned and equality predicates, try to prove that both found
+ // operands fit into narrow unsigned range. If so, try to prove facts in
+ // narrow types.
+ if (!CmpInst::isSigned(FoundPred)) {
+ auto *NarrowType = LHS->getType();
+ auto *WideType = FoundLHS->getType();
+ auto BitWidth = getTypeSizeInBits(NarrowType);
+ const SCEV *MaxValue = getZeroExtendExpr(
+ getConstant(APInt::getMaxValue(BitWidth)), WideType);
+ if (isKnownPredicate(ICmpInst::ICMP_ULE, FoundLHS, MaxValue) &&
+ isKnownPredicate(ICmpInst::ICMP_ULE, FoundRHS, MaxValue)) {
+ const SCEV *TruncFoundLHS = getTruncateExpr(FoundLHS, NarrowType);
+ const SCEV *TruncFoundRHS = getTruncateExpr(FoundRHS, NarrowType);
+ if (isImpliedCondBalancedTypes(Pred, LHS, RHS, FoundPred, TruncFoundLHS,
+ TruncFoundRHS, Context))
+ return true;
+ }
+ }
+
if (CmpInst::isSigned(Pred)) {
LHS = getSignExtendExpr(LHS, FoundLHS->getType());
RHS = getSignExtendExpr(RHS, FoundLHS->getType());
@@ -10180,17 +10180,17 @@ bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS,
FoundRHS = getZeroExtendExpr(FoundRHS, LHS->getType());
}
}
- return isImpliedCondBalancedTypes(Pred, LHS, RHS, FoundPred, FoundLHS,
- FoundRHS, Context);
-}
+ return isImpliedCondBalancedTypes(Pred, LHS, RHS, FoundPred, FoundLHS,
+ FoundRHS, Context);
+}
-bool ScalarEvolution::isImpliedCondBalancedTypes(
- ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS,
- ICmpInst::Predicate FoundPred, const SCEV *FoundLHS, const SCEV *FoundRHS,
- const Instruction *Context) {
- assert(getTypeSizeInBits(LHS->getType()) ==
- getTypeSizeInBits(FoundLHS->getType()) &&
- "Types should be balanced!");
+bool ScalarEvolution::isImpliedCondBalancedTypes(
+ ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS,
+ ICmpInst::Predicate FoundPred, const SCEV *FoundLHS, const SCEV *FoundRHS,
+ const Instruction *Context) {
+ assert(getTypeSizeInBits(LHS->getType()) ==
+ getTypeSizeInBits(FoundLHS->getType()) &&
+ "Types should be balanced!");
// Canonicalize the query to match the way instcombine will have
// canonicalized the comparison.
if (SimplifyICmpOperands(Pred, LHS, RHS))
@@ -10213,16 +10213,16 @@ bool ScalarEvolution::isImpliedCondBalancedTypes(
// Check whether the found predicate is the same as the desired predicate.
if (FoundPred == Pred)
- return isImpliedCondOperands(Pred, LHS, RHS, FoundLHS, FoundRHS, Context);
+ return isImpliedCondOperands(Pred, LHS, RHS, FoundLHS, FoundRHS, Context);
// Check whether swapping the found predicate makes it the same as the
// desired predicate.
if (ICmpInst::getSwappedPredicate(FoundPred) == Pred) {
if (isa<SCEVConstant>(RHS))
- return isImpliedCondOperands(Pred, LHS, RHS, FoundRHS, FoundLHS, Context);
+ return isImpliedCondOperands(Pred, LHS, RHS, FoundRHS, FoundLHS, Context);
else
- return isImpliedCondOperands(ICmpInst::getSwappedPredicate(Pred), RHS,
- LHS, FoundLHS, FoundRHS, Context);
+ return isImpliedCondOperands(ICmpInst::getSwappedPredicate(Pred), RHS,
+ LHS, FoundLHS, FoundRHS, Context);
}
// Unsigned comparison is the same as signed comparison when both the operands
@@ -10230,7 +10230,7 @@ bool ScalarEvolution::isImpliedCondBalancedTypes(
if (CmpInst::isUnsigned(FoundPred) &&
CmpInst::getSignedPredicate(FoundPred) == Pred &&
isKnownNonNegative(FoundLHS) && isKnownNonNegative(FoundRHS))
- return isImpliedCondOperands(Pred, LHS, RHS, FoundLHS, FoundRHS, Context);
+ return isImpliedCondOperands(Pred, LHS, RHS, FoundLHS, FoundRHS, Context);
// Check if we can make progress by sharpening ranges.
if (FoundPred == ICmpInst::ICMP_NE &&
@@ -10267,8 +10267,8 @@ bool ScalarEvolution::isImpliedCondBalancedTypes(
case ICmpInst::ICMP_UGE:
// We know V `Pred` SharperMin. If this implies LHS `Pred`
// RHS, we're done.
- if (isImpliedCondOperands(Pred, LHS, RHS, V, getConstant(SharperMin),
- Context))
+ if (isImpliedCondOperands(Pred, LHS, RHS, V, getConstant(SharperMin),
+ Context))
return true;
LLVM_FALLTHROUGH;
@@ -10283,26 +10283,26 @@ bool ScalarEvolution::isImpliedCondBalancedTypes(
//
// If V `Pred` Min implies LHS `Pred` RHS, we're done.
- if (isImpliedCondOperands(Pred, LHS, RHS, V, getConstant(Min),
- Context))
+ if (isImpliedCondOperands(Pred, LHS, RHS, V, getConstant(Min),
+ Context))
+ return true;
+ break;
+
+ // `LHS < RHS` and `LHS <= RHS` are handled in the same way as `RHS > LHS` and `RHS >= LHS` respectively.
+ case ICmpInst::ICMP_SLE:
+ case ICmpInst::ICMP_ULE:
+ if (isImpliedCondOperands(CmpInst::getSwappedPredicate(Pred), RHS,
+ LHS, V, getConstant(SharperMin), Context))
return true;
- break;
-
- // `LHS < RHS` and `LHS <= RHS` are handled in the same way as `RHS > LHS` and `RHS >= LHS` respectively.
- case ICmpInst::ICMP_SLE:
- case ICmpInst::ICMP_ULE:
- if (isImpliedCondOperands(CmpInst::getSwappedPredicate(Pred), RHS,
- LHS, V, getConstant(SharperMin), Context))
- return true;
LLVM_FALLTHROUGH;
- case ICmpInst::ICMP_SLT:
- case ICmpInst::ICMP_ULT:
- if (isImpliedCondOperands(CmpInst::getSwappedPredicate(Pred), RHS,
- LHS, V, getConstant(Min), Context))
- return true;
- break;
-
+ case ICmpInst::ICMP_SLT:
+ case ICmpInst::ICMP_ULT:
+ if (isImpliedCondOperands(CmpInst::getSwappedPredicate(Pred), RHS,
+ LHS, V, getConstant(Min), Context))
+ return true;
+ break;
+
default:
// No change
break;
@@ -10313,12 +10313,12 @@ bool ScalarEvolution::isImpliedCondBalancedTypes(
// Check whether the actual condition is beyond sufficient.
if (FoundPred == ICmpInst::ICMP_EQ)
if (ICmpInst::isTrueWhenEqual(Pred))
- if (isImpliedCondOperands(Pred, LHS, RHS, FoundLHS, FoundRHS, Context))
+ if (isImpliedCondOperands(Pred, LHS, RHS, FoundLHS, FoundRHS, Context))
return true;
if (Pred == ICmpInst::ICMP_NE)
if (!ICmpInst::isTrueWhenEqual(FoundPred))
- if (isImpliedCondOperands(FoundPred, LHS, RHS, FoundLHS, FoundRHS,
- Context))
+ if (isImpliedCondOperands(FoundPred, LHS, RHS, FoundLHS, FoundRHS,
+ Context))
return true;
// Otherwise assume the worst.
@@ -10397,51 +10397,51 @@ Optional<APInt> ScalarEvolution::computeConstantDifference(const SCEV *More,
return None;
}
-bool ScalarEvolution::isImpliedCondOperandsViaAddRecStart(
- ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS,
- const SCEV *FoundLHS, const SCEV *FoundRHS, const Instruction *Context) {
- // Try to recognize the following pattern:
- //
- // FoundRHS = ...
- // ...
- // loop:
- // FoundLHS = {Start,+,W}
- // context_bb: // Basic block from the same loop
- // known(Pred, FoundLHS, FoundRHS)
- //
- // If some predicate is known in the context of a loop, it is also known on
- // each iteration of this loop, including the first iteration. Therefore, in
- // this case, `FoundLHS Pred FoundRHS` implies `Start Pred FoundRHS`. Try to
- // prove the original pred using this fact.
- if (!Context)
- return false;
- const BasicBlock *ContextBB = Context->getParent();
- // Make sure AR varies in the context block.
- if (auto *AR = dyn_cast<SCEVAddRecExpr>(FoundLHS)) {
- const Loop *L = AR->getLoop();
- // Make sure that context belongs to the loop and executes on 1st iteration
- // (if it ever executes at all).
- if (!L->contains(ContextBB) || !DT.dominates(ContextBB, L->getLoopLatch()))
- return false;
- if (!isAvailableAtLoopEntry(FoundRHS, AR->getLoop()))
- return false;
- return isImpliedCondOperands(Pred, LHS, RHS, AR->getStart(), FoundRHS);
- }
-
- if (auto *AR = dyn_cast<SCEVAddRecExpr>(FoundRHS)) {
- const Loop *L = AR->getLoop();
- // Make sure that context belongs to the loop and executes on 1st iteration
- // (if it ever executes at all).
- if (!L->contains(ContextBB) || !DT.dominates(ContextBB, L->getLoopLatch()))
- return false;
- if (!isAvailableAtLoopEntry(FoundLHS, AR->getLoop()))
- return false;
- return isImpliedCondOperands(Pred, LHS, RHS, FoundLHS, AR->getStart());
- }
-
- return false;
-}
-
+bool ScalarEvolution::isImpliedCondOperandsViaAddRecStart(
+ ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS,
+ const SCEV *FoundLHS, const SCEV *FoundRHS, const Instruction *Context) {
+ // Try to recognize the following pattern:
+ //
+ // FoundRHS = ...
+ // ...
+ // loop:
+ // FoundLHS = {Start,+,W}
+ // context_bb: // Basic block from the same loop
+ // known(Pred, FoundLHS, FoundRHS)
+ //
+ // If some predicate is known in the context of a loop, it is also known on
+ // each iteration of this loop, including the first iteration. Therefore, in
+ // this case, `FoundLHS Pred FoundRHS` implies `Start Pred FoundRHS`. Try to
+ // prove the original pred using this fact.
+ if (!Context)
+ return false;
+ const BasicBlock *ContextBB = Context->getParent();
+ // Make sure AR varies in the context block.
+ if (auto *AR = dyn_cast<SCEVAddRecExpr>(FoundLHS)) {
+ const Loop *L = AR->getLoop();
+ // Make sure that context belongs to the loop and executes on 1st iteration
+ // (if it ever executes at all).
+ if (!L->contains(ContextBB) || !DT.dominates(ContextBB, L->getLoopLatch()))
+ return false;
+ if (!isAvailableAtLoopEntry(FoundRHS, AR->getLoop()))
+ return false;
+ return isImpliedCondOperands(Pred, LHS, RHS, AR->getStart(), FoundRHS);
+ }
+
+ if (auto *AR = dyn_cast<SCEVAddRecExpr>(FoundRHS)) {
+ const Loop *L = AR->getLoop();
+ // Make sure that context belongs to the loop and executes on 1st iteration
+ // (if it ever executes at all).
+ if (!L->contains(ContextBB) || !DT.dominates(ContextBB, L->getLoopLatch()))
+ return false;
+ if (!isAvailableAtLoopEntry(FoundLHS, AR->getLoop()))
+ return false;
+ return isImpliedCondOperands(Pred, LHS, RHS, FoundLHS, AR->getStart());
+ }
+
+ return false;
+}
+
bool ScalarEvolution::isImpliedCondOperandsViaNoOverflow(
ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS,
const SCEV *FoundLHS, const SCEV *FoundRHS) {
@@ -10622,10 +10622,10 @@ bool ScalarEvolution::isImpliedViaMerge(ICmpInst::Predicate Pred,
if (!dominates(RHS, IncBB))
return false;
const SCEV *L = getSCEV(LPhi->getIncomingValueForBlock(IncBB));
- // Make sure L does not refer to a value from a potentially previous
- // iteration of a loop.
- if (!properlyDominates(L, IncBB))
- return false;
+ // Make sure L does not refer to a value from a potentially previous
+ // iteration of a loop.
+ if (!properlyDominates(L, IncBB))
+ return false;
if (!ProvedEasily(L, RHS))
return false;
}
@@ -10636,18 +10636,18 @@ bool ScalarEvolution::isImpliedViaMerge(ICmpInst::Predicate Pred,
bool ScalarEvolution::isImpliedCondOperands(ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS,
const SCEV *FoundLHS,
- const SCEV *FoundRHS,
- const Instruction *Context) {
+ const SCEV *FoundRHS,
+ const Instruction *Context) {
if (isImpliedCondOperandsViaRanges(Pred, LHS, RHS, FoundLHS, FoundRHS))
return true;
if (isImpliedCondOperandsViaNoOverflow(Pred, LHS, RHS, FoundLHS, FoundRHS))
return true;
- if (isImpliedCondOperandsViaAddRecStart(Pred, LHS, RHS, FoundLHS, FoundRHS,
- Context))
- return true;
-
+ if (isImpliedCondOperandsViaAddRecStart(Pred, LHS, RHS, FoundLHS, FoundRHS,
+ Context))
+ return true;
+
return isImpliedCondOperandsHelper(Pred, LHS, RHS,
FoundLHS, FoundRHS) ||
// ~x < ~y --> x > y
@@ -10664,7 +10664,7 @@ static bool IsMinMaxConsistingOf(const SCEV *MaybeMinMaxExpr,
if (!MinMaxExpr)
return false;
- return is_contained(MinMaxExpr->operands(), Candidate);
+ return is_contained(MinMaxExpr->operands(), Candidate);
}
static bool IsKnownPredicateViaAddRecStart(ScalarEvolution &SE,
@@ -10746,31 +10746,31 @@ bool ScalarEvolution::isImpliedViaOperations(ICmpInst::Predicate Pred,
// We want to avoid hurting the compile time with analysis of too big trees.
if (Depth > MaxSCEVOperationsImplicationDepth)
return false;
-
- // We only want to work with GT comparison so far.
- if (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_SLT) {
- Pred = CmpInst::getSwappedPredicate(Pred);
+
+ // We only want to work with GT comparison so far.
+ if (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_SLT) {
+ Pred = CmpInst::getSwappedPredicate(Pred);
std::swap(LHS, RHS);
std::swap(FoundLHS, FoundRHS);
}
-
- // For unsigned, try to reduce it to corresponding signed comparison.
- if (Pred == ICmpInst::ICMP_UGT)
- // We can replace unsigned predicate with its signed counterpart if all
- // involved values are non-negative.
- // TODO: We could have better support for unsigned.
- if (isKnownNonNegative(FoundLHS) && isKnownNonNegative(FoundRHS)) {
- // Knowing that both FoundLHS and FoundRHS are non-negative, and knowing
- // FoundLHS >u FoundRHS, we also know that FoundLHS >s FoundRHS. Let us
- // use this fact to prove that LHS and RHS are non-negative.
- const SCEV *MinusOne = getMinusOne(LHS->getType());
- if (isImpliedCondOperands(ICmpInst::ICMP_SGT, LHS, MinusOne, FoundLHS,
- FoundRHS) &&
- isImpliedCondOperands(ICmpInst::ICMP_SGT, RHS, MinusOne, FoundLHS,
- FoundRHS))
- Pred = ICmpInst::ICMP_SGT;
- }
-
+
+ // For unsigned, try to reduce it to corresponding signed comparison.
+ if (Pred == ICmpInst::ICMP_UGT)
+ // We can replace unsigned predicate with its signed counterpart if all
+ // involved values are non-negative.
+ // TODO: We could have better support for unsigned.
+ if (isKnownNonNegative(FoundLHS) && isKnownNonNegative(FoundRHS)) {
+ // Knowing that both FoundLHS and FoundRHS are non-negative, and knowing
+ // FoundLHS >u FoundRHS, we also know that FoundLHS >s FoundRHS. Let us
+ // use this fact to prove that LHS and RHS are non-negative.
+ const SCEV *MinusOne = getMinusOne(LHS->getType());
+ if (isImpliedCondOperands(ICmpInst::ICMP_SGT, LHS, MinusOne, FoundLHS,
+ FoundRHS) &&
+ isImpliedCondOperands(ICmpInst::ICMP_SGT, RHS, MinusOne, FoundLHS,
+ FoundRHS))
+ Pred = ICmpInst::ICMP_SGT;
+ }
+
if (Pred != ICmpInst::ICMP_SGT)
return false;
@@ -10810,7 +10810,7 @@ bool ScalarEvolution::isImpliedViaOperations(ICmpInst::Predicate Pred,
auto *LL = LHSAddExpr->getOperand(0);
auto *LR = LHSAddExpr->getOperand(1);
- auto *MinusOne = getMinusOne(RHS->getType());
+ auto *MinusOne = getMinusOne(RHS->getType());
// Checks that S1 >= 0 && S2 > RHS, trivially or using the found context.
auto IsSumGreaterThanRHS = [&](const SCEV *S1, const SCEV *S2) {
@@ -10883,7 +10883,7 @@ bool ScalarEvolution::isImpliedViaOperations(ICmpInst::Predicate Pred,
// 1. If FoundLHS is negative, then the result is 0.
// 2. If FoundLHS is non-negative, then the result is non-negative.
// Anyways, the result is non-negative.
- auto *MinusOne = getMinusOne(WTy);
+ auto *MinusOne = getMinusOne(WTy);
auto *NegDenomMinusOne = getMinusSCEV(MinusOne, DenominatorExt);
if (isKnownNegative(RHS) &&
IsSGTViaContext(FoundRHSExt, NegDenomMinusOne))
@@ -11238,13 +11238,13 @@ ScalarEvolution::howManyLessThans(const SCEV *LHS, const SCEV *RHS,
if (isLoopEntryGuardedByCond(L, Cond, getMinusSCEV(Start, Stride), RHS))
BECount = BECountIfBackedgeTaken;
else {
- // If we know that RHS >= Start in the context of loop, then we know that
- // max(RHS, Start) = RHS at this point.
- if (isLoopEntryGuardedByCond(
- L, IsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE, RHS, Start))
- End = RHS;
- else
- End = IsSigned ? getSMaxExpr(RHS, Start) : getUMaxExpr(RHS, Start);
+ // If we know that RHS >= Start in the context of loop, then we know that
+ // max(RHS, Start) = RHS at this point.
+ if (isLoopEntryGuardedByCond(
+ L, IsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE, RHS, Start))
+ End = RHS;
+ else
+ End = IsSigned ? getSMaxExpr(RHS, Start) : getUMaxExpr(RHS, Start);
BECount = computeBECount(getMinusSCEV(End, Start), Stride, false);
}
@@ -11311,15 +11311,15 @@ ScalarEvolution::howManyGreaterThans(const SCEV *LHS, const SCEV *RHS,
const SCEV *Start = IV->getStart();
const SCEV *End = RHS;
- if (!isLoopEntryGuardedByCond(L, Cond, getAddExpr(Start, Stride), RHS)) {
- // If we know that Start >= RHS in the context of loop, then we know that
- // min(RHS, Start) = RHS at this point.
- if (isLoopEntryGuardedByCond(
- L, IsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE, Start, RHS))
- End = RHS;
- else
- End = IsSigned ? getSMinExpr(RHS, Start) : getUMinExpr(RHS, Start);
- }
+ if (!isLoopEntryGuardedByCond(L, Cond, getAddExpr(Start, Stride), RHS)) {
+ // If we know that Start >= RHS in the context of loop, then we know that
+ // min(RHS, Start) = RHS at this point.
+ if (isLoopEntryGuardedByCond(
+ L, IsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE, Start, RHS))
+ End = RHS;
+ else
+ End = IsSigned ? getSMinExpr(RHS, Start) : getUMinExpr(RHS, Start);
+ }
const SCEV *BECount = computeBECount(getMinusSCEV(Start, End), Stride, false);
@@ -11359,7 +11359,7 @@ const SCEV *SCEVAddRecExpr::getNumIterationsInRange(const ConstantRange &Range,
// If the start is a non-zero constant, shift the range to simplify things.
if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(getStart()))
if (!SC->getValue()->isZero()) {
- SmallVector<const SCEV *, 4> Operands(operands());
+ SmallVector<const SCEV *, 4> Operands(operands());
Operands[0] = SE.getZero(SC->getType());
const SCEV *Shifted = SE.getAddRecExpr(Operands, getLoop(),
getNoWrapFlags(FlagNW));
@@ -11642,7 +11642,7 @@ static bool findArrayDimensionsRec(ScalarEvolution &SE,
}
// Remove all SCEVConstants.
- erase_if(Terms, [](const SCEV *E) { return isa<SCEVConstant>(E); });
+ erase_if(Terms, [](const SCEV *E) { return isa<SCEVConstant>(E); });
if (Terms.size() > 0)
if (!findArrayDimensionsRec(SE, Terms, Sizes))
@@ -11970,7 +11970,7 @@ void ScalarEvolution::SCEVCallbackVH::allUsesReplacedWith(Value *V) {
// so that future queries will recompute the expressions using the new
// value.
Value *Old = getValPtr();
- SmallVector<User *, 16> Worklist(Old->users());
+ SmallVector<User *, 16> Worklist(Old->users());
SmallPtrSet<User *, 8> Visited;
while (!Worklist.empty()) {
User *U = Worklist.pop_back_val();
@@ -11983,7 +11983,7 @@ void ScalarEvolution::SCEVCallbackVH::allUsesReplacedWith(Value *V) {
if (PHINode *PN = dyn_cast<PHINode>(U))
SE->ConstantEvolutionLoopExitValue.erase(PN);
SE->eraseValueFromMap(U);
- llvm::append_range(Worklist, U->users());
+ llvm::append_range(Worklist, U->users());
}
// Delete the Old value.
if (PHINode *PN = dyn_cast<PHINode>(Old))
@@ -12265,10 +12265,10 @@ ScalarEvolution::getLoopDisposition(const SCEV *S, const Loop *L) {
ScalarEvolution::LoopDisposition
ScalarEvolution::computeLoopDisposition(const SCEV *S, const Loop *L) {
- switch (S->getSCEVType()) {
+ switch (S->getSCEVType()) {
case scConstant:
return LoopInvariant;
- case scPtrToInt:
+ case scPtrToInt:
case scTruncate:
case scZeroExtend:
case scSignExtend:
@@ -12373,10 +12373,10 @@ ScalarEvolution::getBlockDisposition(const SCEV *S, const BasicBlock *BB) {
ScalarEvolution::BlockDisposition
ScalarEvolution::computeBlockDisposition(const SCEV *S, const BasicBlock *BB) {
- switch (S->getSCEVType()) {
+ switch (S->getSCEVType()) {
case scConstant:
return ProperlyDominatesBlock;
- case scPtrToInt:
+ case scPtrToInt:
case scTruncate:
case scZeroExtend:
case scSignExtend:
@@ -12548,7 +12548,7 @@ void ScalarEvolution::verify() const {
while (!LoopStack.empty()) {
auto *L = LoopStack.pop_back_val();
- llvm::append_range(LoopStack, *L);
+ llvm::append_range(LoopStack, *L);
auto *CurBECount = SCM.visit(
const_cast<ScalarEvolution *>(this)->getBackedgeTakenCount(L));
@@ -12592,25 +12592,25 @@ void ScalarEvolution::verify() const {
std::abort();
}
}
-
- // Collect all valid loops currently in LoopInfo.
- SmallPtrSet<Loop *, 32> ValidLoops;
- SmallVector<Loop *, 32> Worklist(LI.begin(), LI.end());
- while (!Worklist.empty()) {
- Loop *L = Worklist.pop_back_val();
- if (ValidLoops.contains(L))
- continue;
- ValidLoops.insert(L);
- Worklist.append(L->begin(), L->end());
- }
- // Check for SCEV expressions referencing invalid/deleted loops.
- for (auto &KV : ValueExprMap) {
- auto *AR = dyn_cast<SCEVAddRecExpr>(KV.second);
- if (!AR)
- continue;
- assert(ValidLoops.contains(AR->getLoop()) &&
- "AddRec references invalid loop");
- }
+
+ // Collect all valid loops currently in LoopInfo.
+ SmallPtrSet<Loop *, 32> ValidLoops;
+ SmallVector<Loop *, 32> Worklist(LI.begin(), LI.end());
+ while (!Worklist.empty()) {
+ Loop *L = Worklist.pop_back_val();
+ if (ValidLoops.contains(L))
+ continue;
+ ValidLoops.insert(L);
+ Worklist.append(L->begin(), L->end());
+ }
+ // Check for SCEV expressions referencing invalid/deleted loops.
+ for (auto &KV : ValueExprMap) {
+ auto *AR = dyn_cast<SCEVAddRecExpr>(KV.second);
+ if (!AR)
+ continue;
+ assert(ValidLoops.contains(AR->getLoop()) &&
+ "AddRec references invalid loop");
+ }
}
bool ScalarEvolution::invalidate(
@@ -12643,11 +12643,11 @@ ScalarEvolutionVerifierPass::run(Function &F, FunctionAnalysisManager &AM) {
PreservedAnalyses
ScalarEvolutionPrinterPass::run(Function &F, FunctionAnalysisManager &AM) {
- // For compatibility with opt's -analyze feature under legacy pass manager
- // which was not ported to NPM. This keeps tests using
- // update_analyze_test_checks.py working.
- OS << "Printing analysis 'Scalar Evolution Analysis' for function '"
- << F.getName() << "':\n";
+ // For compatibility with opt's -analyze feature under legacy pass manager
+ // which was not ported to NPM. This keeps tests using
+ // update_analyze_test_checks.py working.
+ OS << "Printing analysis 'Scalar Evolution Analysis' for function '"
+ << F.getName() << "':\n";
AM.getResult<ScalarEvolutionAnalysis>(F).print(OS);
return PreservedAnalyses::all();
}
@@ -13143,24 +13143,24 @@ void PredicatedScalarEvolution::print(raw_ostream &OS, unsigned Depth) const {
}
// Match the mathematical pattern A - (A / B) * B, where A and B can be
-// arbitrary expressions. Also match zext (trunc A to iB) to iY, which is used
-// for URem with constant power-of-2 second operands.
+// arbitrary expressions. Also match zext (trunc A to iB) to iY, which is used
+// for URem with constant power-of-2 second operands.
// It's not always easy, as A and B can be folded (imagine A is X / 2, and B is
// 4, A / B becomes X / 8).
bool ScalarEvolution::matchURem(const SCEV *Expr, const SCEV *&LHS,
const SCEV *&RHS) {
- // Try to match 'zext (trunc A to iB) to iY', which is used
- // for URem with constant power-of-2 second operands. Make sure the size of
- // the operand A matches the size of the whole expressions.
- if (const auto *ZExt = dyn_cast<SCEVZeroExtendExpr>(Expr))
- if (const auto *Trunc = dyn_cast<SCEVTruncateExpr>(ZExt->getOperand(0))) {
- LHS = Trunc->getOperand();
- if (LHS->getType() != Expr->getType())
- LHS = getZeroExtendExpr(LHS, Expr->getType());
- RHS = getConstant(APInt(getTypeSizeInBits(Expr->getType()), 1)
- << getTypeSizeInBits(Trunc->getType()));
- return true;
- }
+ // Try to match 'zext (trunc A to iB) to iY', which is used
+ // for URem with constant power-of-2 second operands. Make sure the size of
+ // the operand A matches the size of the whole expressions.
+ if (const auto *ZExt = dyn_cast<SCEVZeroExtendExpr>(Expr))
+ if (const auto *Trunc = dyn_cast<SCEVTruncateExpr>(ZExt->getOperand(0))) {
+ LHS = Trunc->getOperand();
+ if (LHS->getType() != Expr->getType())
+ LHS = getZeroExtendExpr(LHS, Expr->getType());
+ RHS = getConstant(APInt(getTypeSizeInBits(Expr->getType()), 1)
+ << getTypeSizeInBits(Trunc->getType()));
+ return true;
+ }
const auto *Add = dyn_cast<SCEVAddExpr>(Expr);
if (Add == nullptr || Add->getNumOperands() != 2)
return false;
@@ -13194,146 +13194,146 @@ bool ScalarEvolution::matchURem(const SCEV *Expr, const SCEV *&LHS,
MatchURemWithDivisor(getNegativeSCEV(Mul->getOperand(0)));
return false;
}
-
-const SCEV *
-ScalarEvolution::computeSymbolicMaxBackedgeTakenCount(const Loop *L) {
- SmallVector<BasicBlock*, 16> ExitingBlocks;
- L->getExitingBlocks(ExitingBlocks);
-
- // Form an expression for the maximum exit count possible for this loop. We
- // merge the max and exact information to approximate a version of
- // getConstantMaxBackedgeTakenCount which isn't restricted to just constants.
- SmallVector<const SCEV*, 4> ExitCounts;
- for (BasicBlock *ExitingBB : ExitingBlocks) {
- const SCEV *ExitCount = getExitCount(L, ExitingBB);
- if (isa<SCEVCouldNotCompute>(ExitCount))
- ExitCount = getExitCount(L, ExitingBB,
- ScalarEvolution::ConstantMaximum);
- if (!isa<SCEVCouldNotCompute>(ExitCount)) {
- assert(DT.dominates(ExitingBB, L->getLoopLatch()) &&
- "We should only have known counts for exiting blocks that "
- "dominate latch!");
- ExitCounts.push_back(ExitCount);
- }
- }
- if (ExitCounts.empty())
- return getCouldNotCompute();
- return getUMinFromMismatchedTypes(ExitCounts);
-}
-
-/// This rewriter is similar to SCEVParameterRewriter (it replaces SCEVUnknown
-/// components following the Map (Value -> SCEV)), but skips AddRecExpr because
-/// we cannot guarantee that the replacement is loop invariant in the loop of
-/// the AddRec.
-class SCEVLoopGuardRewriter : public SCEVRewriteVisitor<SCEVLoopGuardRewriter> {
- ValueToSCEVMapTy &Map;
-
-public:
- SCEVLoopGuardRewriter(ScalarEvolution &SE, ValueToSCEVMapTy &M)
- : SCEVRewriteVisitor(SE), Map(M) {}
-
- const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) { return Expr; }
-
- const SCEV *visitUnknown(const SCEVUnknown *Expr) {
- auto I = Map.find(Expr->getValue());
- if (I == Map.end())
- return Expr;
- return I->second;
- }
-};
-
-const SCEV *ScalarEvolution::applyLoopGuards(const SCEV *Expr, const Loop *L) {
- auto CollectCondition = [&](ICmpInst::Predicate Predicate, const SCEV *LHS,
- const SCEV *RHS, ValueToSCEVMapTy &RewriteMap) {
- if (!isa<SCEVUnknown>(LHS)) {
- std::swap(LHS, RHS);
- Predicate = CmpInst::getSwappedPredicate(Predicate);
- }
-
- // For now, limit to conditions that provide information about unknown
- // expressions.
- auto *LHSUnknown = dyn_cast<SCEVUnknown>(LHS);
- if (!LHSUnknown)
- return;
-
- // TODO: use information from more predicates.
- switch (Predicate) {
- case CmpInst::ICMP_ULT: {
- if (!containsAddRecurrence(RHS)) {
- const SCEV *Base = LHS;
- auto I = RewriteMap.find(LHSUnknown->getValue());
- if (I != RewriteMap.end())
- Base = I->second;
-
- RewriteMap[LHSUnknown->getValue()] =
- getUMinExpr(Base, getMinusSCEV(RHS, getOne(RHS->getType())));
- }
- break;
- }
- case CmpInst::ICMP_ULE: {
- if (!containsAddRecurrence(RHS)) {
- const SCEV *Base = LHS;
- auto I = RewriteMap.find(LHSUnknown->getValue());
- if (I != RewriteMap.end())
- Base = I->second;
- RewriteMap[LHSUnknown->getValue()] = getUMinExpr(Base, RHS);
- }
- break;
- }
- case CmpInst::ICMP_EQ:
- if (isa<SCEVConstant>(RHS))
- RewriteMap[LHSUnknown->getValue()] = RHS;
- break;
- case CmpInst::ICMP_NE:
- if (isa<SCEVConstant>(RHS) &&
- cast<SCEVConstant>(RHS)->getValue()->isNullValue())
- RewriteMap[LHSUnknown->getValue()] =
- getUMaxExpr(LHS, getOne(RHS->getType()));
- break;
- default:
- break;
- }
- };
- // Starting at the loop predecessor, climb up the predecessor chain, as long
- // as there are predecessors that can be found that have unique successors
- // leading to the original header.
- // TODO: share this logic with isLoopEntryGuardedByCond.
- ValueToSCEVMapTy RewriteMap;
- for (std::pair<const BasicBlock *, const BasicBlock *> Pair(
- L->getLoopPredecessor(), L->getHeader());
- Pair.first; Pair = getPredecessorWithUniqueSuccessorForBB(Pair.first)) {
-
- const BranchInst *LoopEntryPredicate =
- dyn_cast<BranchInst>(Pair.first->getTerminator());
- if (!LoopEntryPredicate || LoopEntryPredicate->isUnconditional())
- continue;
-
- // TODO: use information from more complex conditions, e.g. AND expressions.
- auto *Cmp = dyn_cast<ICmpInst>(LoopEntryPredicate->getCondition());
- if (!Cmp)
- continue;
-
- auto Predicate = Cmp->getPredicate();
- if (LoopEntryPredicate->getSuccessor(1) == Pair.second)
- Predicate = CmpInst::getInversePredicate(Predicate);
- CollectCondition(Predicate, getSCEV(Cmp->getOperand(0)),
- getSCEV(Cmp->getOperand(1)), RewriteMap);
- }
-
- // Also collect information from assumptions dominating the loop.
- for (auto &AssumeVH : AC.assumptions()) {
- if (!AssumeVH)
- continue;
- auto *AssumeI = cast<CallInst>(AssumeVH);
- auto *Cmp = dyn_cast<ICmpInst>(AssumeI->getOperand(0));
- if (!Cmp || !DT.dominates(AssumeI, L->getHeader()))
- continue;
- CollectCondition(Cmp->getPredicate(), getSCEV(Cmp->getOperand(0)),
- getSCEV(Cmp->getOperand(1)), RewriteMap);
- }
-
- if (RewriteMap.empty())
- return Expr;
- SCEVLoopGuardRewriter Rewriter(*this, RewriteMap);
- return Rewriter.visit(Expr);
-}
+
+const SCEV *
+ScalarEvolution::computeSymbolicMaxBackedgeTakenCount(const Loop *L) {
+ SmallVector<BasicBlock*, 16> ExitingBlocks;
+ L->getExitingBlocks(ExitingBlocks);
+
+ // Form an expression for the maximum exit count possible for this loop. We
+ // merge the max and exact information to approximate a version of
+ // getConstantMaxBackedgeTakenCount which isn't restricted to just constants.
+ SmallVector<const SCEV*, 4> ExitCounts;
+ for (BasicBlock *ExitingBB : ExitingBlocks) {
+ const SCEV *ExitCount = getExitCount(L, ExitingBB);
+ if (isa<SCEVCouldNotCompute>(ExitCount))
+ ExitCount = getExitCount(L, ExitingBB,
+ ScalarEvolution::ConstantMaximum);
+ if (!isa<SCEVCouldNotCompute>(ExitCount)) {
+ assert(DT.dominates(ExitingBB, L->getLoopLatch()) &&
+ "We should only have known counts for exiting blocks that "
+ "dominate latch!");
+ ExitCounts.push_back(ExitCount);
+ }
+ }
+ if (ExitCounts.empty())
+ return getCouldNotCompute();
+ return getUMinFromMismatchedTypes(ExitCounts);
+}
+
+/// This rewriter is similar to SCEVParameterRewriter (it replaces SCEVUnknown
+/// components following the Map (Value -> SCEV)), but skips AddRecExpr because
+/// we cannot guarantee that the replacement is loop invariant in the loop of
+/// the AddRec.
+class SCEVLoopGuardRewriter : public SCEVRewriteVisitor<SCEVLoopGuardRewriter> {
+ ValueToSCEVMapTy &Map;
+
+public:
+ SCEVLoopGuardRewriter(ScalarEvolution &SE, ValueToSCEVMapTy &M)
+ : SCEVRewriteVisitor(SE), Map(M) {}
+
+ const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) { return Expr; }
+
+ const SCEV *visitUnknown(const SCEVUnknown *Expr) {
+ auto I = Map.find(Expr->getValue());
+ if (I == Map.end())
+ return Expr;
+ return I->second;
+ }
+};
+
+const SCEV *ScalarEvolution::applyLoopGuards(const SCEV *Expr, const Loop *L) {
+ auto CollectCondition = [&](ICmpInst::Predicate Predicate, const SCEV *LHS,
+ const SCEV *RHS, ValueToSCEVMapTy &RewriteMap) {
+ if (!isa<SCEVUnknown>(LHS)) {
+ std::swap(LHS, RHS);
+ Predicate = CmpInst::getSwappedPredicate(Predicate);
+ }
+
+ // For now, limit to conditions that provide information about unknown
+ // expressions.
+ auto *LHSUnknown = dyn_cast<SCEVUnknown>(LHS);
+ if (!LHSUnknown)
+ return;
+
+ // TODO: use information from more predicates.
+ switch (Predicate) {
+ case CmpInst::ICMP_ULT: {
+ if (!containsAddRecurrence(RHS)) {
+ const SCEV *Base = LHS;
+ auto I = RewriteMap.find(LHSUnknown->getValue());
+ if (I != RewriteMap.end())
+ Base = I->second;
+
+ RewriteMap[LHSUnknown->getValue()] =
+ getUMinExpr(Base, getMinusSCEV(RHS, getOne(RHS->getType())));
+ }
+ break;
+ }
+ case CmpInst::ICMP_ULE: {
+ if (!containsAddRecurrence(RHS)) {
+ const SCEV *Base = LHS;
+ auto I = RewriteMap.find(LHSUnknown->getValue());
+ if (I != RewriteMap.end())
+ Base = I->second;
+ RewriteMap[LHSUnknown->getValue()] = getUMinExpr(Base, RHS);
+ }
+ break;
+ }
+ case CmpInst::ICMP_EQ:
+ if (isa<SCEVConstant>(RHS))
+ RewriteMap[LHSUnknown->getValue()] = RHS;
+ break;
+ case CmpInst::ICMP_NE:
+ if (isa<SCEVConstant>(RHS) &&
+ cast<SCEVConstant>(RHS)->getValue()->isNullValue())
+ RewriteMap[LHSUnknown->getValue()] =
+ getUMaxExpr(LHS, getOne(RHS->getType()));
+ break;
+ default:
+ break;
+ }
+ };
+ // Starting at the loop predecessor, climb up the predecessor chain, as long
+ // as there are predecessors that can be found that have unique successors
+ // leading to the original header.
+ // TODO: share this logic with isLoopEntryGuardedByCond.
+ ValueToSCEVMapTy RewriteMap;
+ for (std::pair<const BasicBlock *, const BasicBlock *> Pair(
+ L->getLoopPredecessor(), L->getHeader());
+ Pair.first; Pair = getPredecessorWithUniqueSuccessorForBB(Pair.first)) {
+
+ const BranchInst *LoopEntryPredicate =
+ dyn_cast<BranchInst>(Pair.first->getTerminator());
+ if (!LoopEntryPredicate || LoopEntryPredicate->isUnconditional())
+ continue;
+
+ // TODO: use information from more complex conditions, e.g. AND expressions.
+ auto *Cmp = dyn_cast<ICmpInst>(LoopEntryPredicate->getCondition());
+ if (!Cmp)
+ continue;
+
+ auto Predicate = Cmp->getPredicate();
+ if (LoopEntryPredicate->getSuccessor(1) == Pair.second)
+ Predicate = CmpInst::getInversePredicate(Predicate);
+ CollectCondition(Predicate, getSCEV(Cmp->getOperand(0)),
+ getSCEV(Cmp->getOperand(1)), RewriteMap);
+ }
+
+ // Also collect information from assumptions dominating the loop.
+ for (auto &AssumeVH : AC.assumptions()) {
+ if (!AssumeVH)
+ continue;
+ auto *AssumeI = cast<CallInst>(AssumeVH);
+ auto *Cmp = dyn_cast<ICmpInst>(AssumeI->getOperand(0));
+ if (!Cmp || !DT.dominates(AssumeI, L->getHeader()))
+ continue;
+ CollectCondition(Cmp->getPredicate(), getSCEV(Cmp->getOperand(0)),
+ getSCEV(Cmp->getOperand(1)), RewriteMap);
+ }
+
+ if (RewriteMap.empty())
+ return Expr;
+ SCEVLoopGuardRewriter Rewriter(*this, RewriteMap);
+ return Rewriter.visit(Expr);
+}
diff --git a/contrib/libs/llvm12/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp
index 6299247bdf..8f289feb3d 100644
--- a/contrib/libs/llvm12/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp
@@ -82,12 +82,12 @@ AliasResult SCEVAAResult::alias(const MemoryLocation &LocA,
Value *BO = GetBaseValue(BS);
if ((AO && AO != LocA.Ptr) || (BO && BO != LocB.Ptr))
if (alias(MemoryLocation(AO ? AO : LocA.Ptr,
- AO ? LocationSize::beforeOrAfterPointer()
- : LocA.Size,
+ AO ? LocationSize::beforeOrAfterPointer()
+ : LocA.Size,
AO ? AAMDNodes() : LocA.AATags),
MemoryLocation(BO ? BO : LocB.Ptr,
- BO ? LocationSize::beforeOrAfterPointer()
- : LocB.Size,
+ BO ? LocationSize::beforeOrAfterPointer()
+ : LocB.Size,
BO ? AAMDNodes() : LocB.AATags),
AAQI) == NoAlias)
return NoAlias;
diff --git a/contrib/libs/llvm12/lib/Analysis/ScalarEvolutionDivision.cpp b/contrib/libs/llvm12/lib/Analysis/ScalarEvolutionDivision.cpp
index 5ec18d8e9d..64e908bdf3 100644
--- a/contrib/libs/llvm12/lib/Analysis/ScalarEvolutionDivision.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/ScalarEvolutionDivision.cpp
@@ -215,14 +215,14 @@ void SCEVDivision::visitMulExpr(const SCEVMulExpr *Numerator) {
return cannotDivide(Numerator);
// The Remainder is obtained by replacing Denominator by 0 in Numerator.
- ValueToSCEVMapTy RewriteMap;
- RewriteMap[cast<SCEVUnknown>(Denominator)->getValue()] = Zero;
- Remainder = SCEVParameterRewriter::rewrite(Numerator, SE, RewriteMap);
+ ValueToSCEVMapTy RewriteMap;
+ RewriteMap[cast<SCEVUnknown>(Denominator)->getValue()] = Zero;
+ Remainder = SCEVParameterRewriter::rewrite(Numerator, SE, RewriteMap);
if (Remainder->isZero()) {
// The Quotient is obtained by replacing Denominator by 1 in Numerator.
- RewriteMap[cast<SCEVUnknown>(Denominator)->getValue()] = One;
- Quotient = SCEVParameterRewriter::rewrite(Numerator, SE, RewriteMap);
+ RewriteMap[cast<SCEVUnknown>(Denominator)->getValue()] = One;
+ Quotient = SCEVParameterRewriter::rewrite(Numerator, SE, RewriteMap);
return;
}
diff --git a/contrib/libs/llvm12/lib/Analysis/ScopedNoAliasAA.cpp b/contrib/libs/llvm12/lib/Analysis/ScopedNoAliasAA.cpp
index c6c3278e94..6b38d6716b 100644
--- a/contrib/libs/llvm12/lib/Analysis/ScopedNoAliasAA.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/ScopedNoAliasAA.cpp
@@ -34,7 +34,7 @@
#include "llvm/Analysis/ScopedNoAliasAA.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/MemoryLocation.h"
-#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
@@ -161,7 +161,7 @@ ScopedNoAliasAAResult ScopedNoAliasAA::run(Function &F,
char ScopedNoAliasAAWrapperPass::ID = 0;
-INITIALIZE_PASS(ScopedNoAliasAAWrapperPass, "scoped-noalias-aa",
+INITIALIZE_PASS(ScopedNoAliasAAWrapperPass, "scoped-noalias-aa",
"Scoped NoAlias Alias Analysis", false, true)
ImmutablePass *llvm::createScopedNoAliasAAWrapperPass() {
diff --git a/contrib/libs/llvm12/lib/Analysis/StackLifetime.cpp b/contrib/libs/llvm12/lib/Analysis/StackLifetime.cpp
index c4c07bfaed..ab5f2db7d1 100644
--- a/contrib/libs/llvm12/lib/Analysis/StackLifetime.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/StackLifetime.cpp
@@ -11,7 +11,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/AssemblyAnnotationWriter.h"
#include "llvm/IR/BasicBlock.h"
@@ -64,28 +64,28 @@ bool StackLifetime::isAliveAfter(const AllocaInst *AI,
return getLiveRange(AI).test(InstNum);
}
-// Returns unique alloca annotated by lifetime marker only if
-// markers has the same size and points to the alloca start.
-static const AllocaInst *findMatchingAlloca(const IntrinsicInst &II,
- const DataLayout &DL) {
- const AllocaInst *AI = findAllocaForValue(II.getArgOperand(1), true);
- if (!AI)
- return nullptr;
-
- auto AllocaSizeInBits = AI->getAllocationSizeInBits(DL);
- if (!AllocaSizeInBits)
- return nullptr;
- int64_t AllocaSize = AllocaSizeInBits.getValue() / 8;
-
- auto *Size = dyn_cast<ConstantInt>(II.getArgOperand(0));
- if (!Size)
- return nullptr;
- int64_t LifetimeSize = Size->getSExtValue();
-
- if (LifetimeSize != -1 && LifetimeSize != AllocaSize)
- return nullptr;
-
- return AI;
+// Returns unique alloca annotated by lifetime marker only if
+// markers has the same size and points to the alloca start.
+static const AllocaInst *findMatchingAlloca(const IntrinsicInst &II,
+ const DataLayout &DL) {
+ const AllocaInst *AI = findAllocaForValue(II.getArgOperand(1), true);
+ if (!AI)
+ return nullptr;
+
+ auto AllocaSizeInBits = AI->getAllocationSizeInBits(DL);
+ if (!AllocaSizeInBits)
+ return nullptr;
+ int64_t AllocaSize = AllocaSizeInBits.getValue() / 8;
+
+ auto *Size = dyn_cast<ConstantInt>(II.getArgOperand(0));
+ if (!Size)
+ return nullptr;
+ int64_t LifetimeSize = Size->getSExtValue();
+
+ if (LifetimeSize != -1 && LifetimeSize != AllocaSize)
+ return nullptr;
+
+ return AI;
}
void StackLifetime::collectMarkers() {
@@ -93,27 +93,27 @@ void StackLifetime::collectMarkers() {
DenseMap<const BasicBlock *, SmallDenseMap<const IntrinsicInst *, Marker>>
BBMarkerSet;
- const DataLayout &DL = F.getParent()->getDataLayout();
-
+ const DataLayout &DL = F.getParent()->getDataLayout();
+
// Compute the set of start/end markers per basic block.
- for (const BasicBlock *BB : depth_first(&F)) {
- for (const Instruction &I : *BB) {
- const IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I);
- if (!II || !II->isLifetimeStartOrEnd())
- continue;
- const AllocaInst *AI = findMatchingAlloca(*II, DL);
- if (!AI) {
- HasUnknownLifetimeStartOrEnd = true;
- continue;
+ for (const BasicBlock *BB : depth_first(&F)) {
+ for (const Instruction &I : *BB) {
+ const IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I);
+ if (!II || !II->isLifetimeStartOrEnd())
+ continue;
+ const AllocaInst *AI = findMatchingAlloca(*II, DL);
+ if (!AI) {
+ HasUnknownLifetimeStartOrEnd = true;
+ continue;
}
- auto It = AllocaNumbering.find(AI);
- if (It == AllocaNumbering.end())
- continue;
- auto AllocaNo = It->second;
- bool IsStart = II->getIntrinsicID() == Intrinsic::lifetime_start;
- if (IsStart)
- InterestingAllocas.set(AllocaNo);
- BBMarkerSet[BB][II] = {AllocaNo, IsStart};
+ auto It = AllocaNumbering.find(AI);
+ if (It == AllocaNumbering.end())
+ continue;
+ auto AllocaNo = It->second;
+ bool IsStart = II->getIntrinsicID() == Intrinsic::lifetime_start;
+ if (IsStart)
+ InterestingAllocas.set(AllocaNo);
+ BBMarkerSet[BB][II] = {AllocaNo, IsStart};
}
}
@@ -292,7 +292,7 @@ LLVM_DUMP_METHOD void StackLifetime::dumpBlockLiveness() const {
const BasicBlock *BB = IT.getFirst();
const BlockLifetimeInfo &BlockInfo = BlockLiveness.find(BB)->getSecond();
auto BlockRange = BlockInstRange.find(BB)->getSecond();
- dbgs() << " BB (" << BB->getName() << ") [" << BlockRange.first << ", " << BlockRange.second
+ dbgs() << " BB (" << BB->getName() << ") [" << BlockRange.first << ", " << BlockRange.second
<< "): begin " << BlockInfo.Begin << ", end " << BlockInfo.End
<< ", livein " << BlockInfo.LiveIn << ", liveout "
<< BlockInfo.LiveOut << "\n";
@@ -319,20 +319,20 @@ StackLifetime::StackLifetime(const Function &F,
}
void StackLifetime::run() {
- if (HasUnknownLifetimeStartOrEnd) {
- // There is marker which we can't assign to a specific alloca, so we
- // fallback to the most conservative results for the type.
- switch (Type) {
- case LivenessType::May:
- LiveRanges.resize(NumAllocas, getFullLiveRange());
- break;
- case LivenessType::Must:
- LiveRanges.resize(NumAllocas, LiveRange(Instructions.size()));
- break;
- }
- return;
- }
-
+ if (HasUnknownLifetimeStartOrEnd) {
+ // There is marker which we can't assign to a specific alloca, so we
+ // fallback to the most conservative results for the type.
+ switch (Type) {
+ case LivenessType::May:
+ LiveRanges.resize(NumAllocas, getFullLiveRange());
+ break;
+ case LivenessType::Must:
+ LiveRanges.resize(NumAllocas, LiveRange(Instructions.size()));
+ break;
+ }
+ return;
+ }
+
LiveRanges.resize(NumAllocas, LiveRange(Instructions.size()));
for (unsigned I = 0; I < NumAllocas; ++I)
if (!InterestingAllocas.test(I))
diff --git a/contrib/libs/llvm12/lib/Analysis/StackSafetyAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/StackSafetyAnalysis.cpp
index aa7d3fc4bb..73096eb4ba 100644
--- a/contrib/libs/llvm12/lib/Analysis/StackSafetyAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/StackSafetyAnalysis.cpp
@@ -22,7 +22,7 @@
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/ModuleSummaryIndex.h"
+#include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
@@ -38,25 +38,25 @@ using namespace llvm;
STATISTIC(NumAllocaStackSafe, "Number of safe allocas");
STATISTIC(NumAllocaTotal, "Number of total allocas");
-STATISTIC(NumCombinedCalleeLookupTotal,
- "Number of total callee lookups on combined index.");
-STATISTIC(NumCombinedCalleeLookupFailed,
- "Number of failed callee lookups on combined index.");
-STATISTIC(NumModuleCalleeLookupTotal,
- "Number of total callee lookups on module index.");
-STATISTIC(NumModuleCalleeLookupFailed,
- "Number of failed callee lookups on module index.");
-STATISTIC(NumCombinedParamAccessesBefore,
- "Number of total param accesses before generateParamAccessSummary.");
-STATISTIC(NumCombinedParamAccessesAfter,
- "Number of total param accesses after generateParamAccessSummary.");
-STATISTIC(NumCombinedDataFlowNodes,
- "Number of total nodes in combined index for dataflow processing.");
-STATISTIC(NumIndexCalleeUnhandled, "Number of index callee which are unhandled.");
-STATISTIC(NumIndexCalleeMultipleWeak, "Number of index callee non-unique weak.");
-STATISTIC(NumIndexCalleeMultipleExternal, "Number of index callee non-unique external.");
-
-
+STATISTIC(NumCombinedCalleeLookupTotal,
+ "Number of total callee lookups on combined index.");
+STATISTIC(NumCombinedCalleeLookupFailed,
+ "Number of failed callee lookups on combined index.");
+STATISTIC(NumModuleCalleeLookupTotal,
+ "Number of total callee lookups on module index.");
+STATISTIC(NumModuleCalleeLookupFailed,
+ "Number of failed callee lookups on module index.");
+STATISTIC(NumCombinedParamAccessesBefore,
+ "Number of total param accesses before generateParamAccessSummary.");
+STATISTIC(NumCombinedParamAccessesAfter,
+ "Number of total param accesses after generateParamAccessSummary.");
+STATISTIC(NumCombinedDataFlowNodes,
+ "Number of total nodes in combined index for dataflow processing.");
+STATISTIC(NumIndexCalleeUnhandled, "Number of index callee which are unhandled.");
+STATISTIC(NumIndexCalleeMultipleWeak, "Number of index callee non-unique weak.");
+STATISTIC(NumIndexCalleeMultipleExternal, "Number of index callee non-unique external.");
+
+
static cl::opt<int> StackSafetyMaxIterations("stack-safety-max-iterations",
cl::init(20), cl::Hidden);
@@ -68,47 +68,47 @@ static cl::opt<bool> StackSafetyRun("stack-safety-run", cl::init(false),
namespace {
-// Check if we should bailout for such ranges.
-bool isUnsafe(const ConstantRange &R) {
- return R.isEmptySet() || R.isFullSet() || R.isUpperSignWrapped();
-}
-
-ConstantRange addOverflowNever(const ConstantRange &L, const ConstantRange &R) {
- assert(!L.isSignWrappedSet());
- assert(!R.isSignWrappedSet());
- if (L.signedAddMayOverflow(R) !=
- ConstantRange::OverflowResult::NeverOverflows)
- return ConstantRange::getFull(L.getBitWidth());
- ConstantRange Result = L.add(R);
- assert(!Result.isSignWrappedSet());
- return Result;
-}
-
-ConstantRange unionNoWrap(const ConstantRange &L, const ConstantRange &R) {
- assert(!L.isSignWrappedSet());
- assert(!R.isSignWrappedSet());
- auto Result = L.unionWith(R);
- // Two non-wrapped sets can produce wrapped.
- if (Result.isSignWrappedSet())
- Result = ConstantRange::getFull(Result.getBitWidth());
- return Result;
-}
-
+// Check if we should bailout for such ranges.
+bool isUnsafe(const ConstantRange &R) {
+ return R.isEmptySet() || R.isFullSet() || R.isUpperSignWrapped();
+}
+
+ConstantRange addOverflowNever(const ConstantRange &L, const ConstantRange &R) {
+ assert(!L.isSignWrappedSet());
+ assert(!R.isSignWrappedSet());
+ if (L.signedAddMayOverflow(R) !=
+ ConstantRange::OverflowResult::NeverOverflows)
+ return ConstantRange::getFull(L.getBitWidth());
+ ConstantRange Result = L.add(R);
+ assert(!Result.isSignWrappedSet());
+ return Result;
+}
+
+ConstantRange unionNoWrap(const ConstantRange &L, const ConstantRange &R) {
+ assert(!L.isSignWrappedSet());
+ assert(!R.isSignWrappedSet());
+ auto Result = L.unionWith(R);
+ // Two non-wrapped sets can produce wrapped.
+ if (Result.isSignWrappedSet())
+ Result = ConstantRange::getFull(Result.getBitWidth());
+ return Result;
+}
+
/// Describes use of address in as a function call argument.
template <typename CalleeTy> struct CallInfo {
/// Function being called.
const CalleeTy *Callee = nullptr;
/// Index of argument which pass address.
size_t ParamNo = 0;
-
- CallInfo(const CalleeTy *Callee, size_t ParamNo)
- : Callee(Callee), ParamNo(ParamNo) {}
-
- struct Less {
- bool operator()(const CallInfo &L, const CallInfo &R) const {
- return std::tie(L.ParamNo, L.Callee) < std::tie(R.ParamNo, R.Callee);
- }
- };
+
+ CallInfo(const CalleeTy *Callee, size_t ParamNo)
+ : Callee(Callee), ParamNo(ParamNo) {}
+
+ struct Less {
+ bool operator()(const CallInfo &L, const CallInfo &R) const {
+ return std::tie(L.ParamNo, L.Callee) < std::tie(R.ParamNo, R.Callee);
+ }
+ };
};
/// Describe uses of address (alloca or parameter) inside of the function.
@@ -118,26 +118,26 @@ template <typename CalleeTy> struct UseInfo {
ConstantRange Range;
// List of calls which pass address as an argument.
- // Value is offset range of address from base address (alloca or calling
- // function argument). Range should never set to empty-set, that is an invalid
- // access range that can cause empty-set to be propagated with
- // ConstantRange::add
- using CallsTy = std::map<CallInfo<CalleeTy>, ConstantRange,
- typename CallInfo<CalleeTy>::Less>;
- CallsTy Calls;
+ // Value is offset range of address from base address (alloca or calling
+ // function argument). Range should never set to empty-set, that is an invalid
+ // access range that can cause empty-set to be propagated with
+ // ConstantRange::add
+ using CallsTy = std::map<CallInfo<CalleeTy>, ConstantRange,
+ typename CallInfo<CalleeTy>::Less>;
+ CallsTy Calls;
UseInfo(unsigned PointerSize) : Range{PointerSize, false} {}
- void updateRange(const ConstantRange &R) { Range = unionNoWrap(Range, R); }
+ void updateRange(const ConstantRange &R) { Range = unionNoWrap(Range, R); }
};
template <typename CalleeTy>
raw_ostream &operator<<(raw_ostream &OS, const UseInfo<CalleeTy> &U) {
OS << U.Range;
for (auto &Call : U.Calls)
- OS << ", "
- << "@" << Call.first.Callee->getName() << "(arg" << Call.first.ParamNo
- << ", " << Call.second << ")";
+ OS << ", "
+ << "@" << Call.first.Callee->getName() << "(arg" << Call.first.ParamNo
+ << ", " << Call.second << ")";
return OS;
}
@@ -208,7 +208,7 @@ template <typename CalleeTy> struct FunctionInfo {
} else {
assert(Allocas.empty());
}
- O << "\n";
+ O << "\n";
}
};
@@ -419,11 +419,11 @@ bool StackSafetyLocalAnalysis::analyzeAllUses(Value *Ptr,
}
assert(isa<Function>(Callee) || isa<GlobalAlias>(Callee));
- ConstantRange Offsets = offsetFrom(UI, Ptr);
- auto Insert =
- US.Calls.emplace(CallInfo<GlobalValue>(Callee, ArgNo), Offsets);
- if (!Insert.second)
- Insert.first->second = Insert.first->second.unionWith(Offsets);
+ ConstantRange Offsets = offsetFrom(UI, Ptr);
+ auto Insert =
+ US.Calls.emplace(CallInfo<GlobalValue>(Callee, ArgNo), Offsets);
+ if (!Insert.second)
+ Insert.first->second = Insert.first->second.unionWith(Offsets);
break;
}
@@ -456,7 +456,7 @@ FunctionInfo<GlobalValue> StackSafetyLocalAnalysis::run() {
analyzeAllUses(AI, UI, SL);
}
- for (Argument &A : F.args()) {
+ for (Argument &A : F.args()) {
// Non pointers and bypass arguments are not going to be used in any global
// processing.
if (A.getType()->isPointerTy() && !A.hasByValAttr()) {
@@ -529,18 +529,18 @@ template <typename CalleeTy>
bool StackSafetyDataFlowAnalysis<CalleeTy>::updateOneUse(UseInfo<CalleeTy> &US,
bool UpdateToFullSet) {
bool Changed = false;
- for (auto &KV : US.Calls) {
- assert(!KV.second.isEmptySet() &&
+ for (auto &KV : US.Calls) {
+ assert(!KV.second.isEmptySet() &&
"Param range can't be empty-set, invalid offset range");
ConstantRange CalleeRange =
- getArgumentAccessRange(KV.first.Callee, KV.first.ParamNo, KV.second);
+ getArgumentAccessRange(KV.first.Callee, KV.first.ParamNo, KV.second);
if (!US.Range.contains(CalleeRange)) {
Changed = true;
if (UpdateToFullSet)
US.Range = UnknownRange;
else
- US.updateRange(CalleeRange);
+ US.updateRange(CalleeRange);
}
}
return Changed;
@@ -574,7 +574,7 @@ void StackSafetyDataFlowAnalysis<CalleeTy>::runDataFlow() {
auto &FS = F.second;
for (auto &KV : FS.Params)
for (auto &CS : KV.second.Calls)
- Callees.push_back(CS.first.Callee);
+ Callees.push_back(CS.first.Callee);
llvm::sort(Callees);
Callees.erase(std::unique(Callees.begin(), Callees.end()), Callees.end());
@@ -609,52 +609,52 @@ StackSafetyDataFlowAnalysis<CalleeTy>::run() {
return Functions;
}
-FunctionSummary *findCalleeFunctionSummary(ValueInfo VI, StringRef ModuleId) {
- if (!VI)
- return nullptr;
- auto SummaryList = VI.getSummaryList();
- GlobalValueSummary* S = nullptr;
- for (const auto& GVS : SummaryList) {
- if (!GVS->isLive())
- continue;
- if (const AliasSummary *AS = dyn_cast<AliasSummary>(GVS.get()))
- if (!AS->hasAliasee())
- continue;
- if (!isa<FunctionSummary>(GVS->getBaseObject()))
- continue;
- if (GlobalValue::isLocalLinkage(GVS->linkage())) {
- if (GVS->modulePath() == ModuleId) {
- S = GVS.get();
- break;
- }
- } else if (GlobalValue::isExternalLinkage(GVS->linkage())) {
- if (S) {
- ++NumIndexCalleeMultipleExternal;
- return nullptr;
- }
- S = GVS.get();
- } else if (GlobalValue::isWeakLinkage(GVS->linkage())) {
- if (S) {
- ++NumIndexCalleeMultipleWeak;
- return nullptr;
- }
- S = GVS.get();
- } else if (GlobalValue::isAvailableExternallyLinkage(GVS->linkage()) ||
- GlobalValue::isLinkOnceLinkage(GVS->linkage())) {
- if (SummaryList.size() == 1)
- S = GVS.get();
- // According thinLTOResolvePrevailingGUID these are unlikely prevailing.
- } else {
- ++NumIndexCalleeUnhandled;
- }
- };
+FunctionSummary *findCalleeFunctionSummary(ValueInfo VI, StringRef ModuleId) {
+ if (!VI)
+ return nullptr;
+ auto SummaryList = VI.getSummaryList();
+ GlobalValueSummary* S = nullptr;
+ for (const auto& GVS : SummaryList) {
+ if (!GVS->isLive())
+ continue;
+ if (const AliasSummary *AS = dyn_cast<AliasSummary>(GVS.get()))
+ if (!AS->hasAliasee())
+ continue;
+ if (!isa<FunctionSummary>(GVS->getBaseObject()))
+ continue;
+ if (GlobalValue::isLocalLinkage(GVS->linkage())) {
+ if (GVS->modulePath() == ModuleId) {
+ S = GVS.get();
+ break;
+ }
+ } else if (GlobalValue::isExternalLinkage(GVS->linkage())) {
+ if (S) {
+ ++NumIndexCalleeMultipleExternal;
+ return nullptr;
+ }
+ S = GVS.get();
+ } else if (GlobalValue::isWeakLinkage(GVS->linkage())) {
+ if (S) {
+ ++NumIndexCalleeMultipleWeak;
+ return nullptr;
+ }
+ S = GVS.get();
+ } else if (GlobalValue::isAvailableExternallyLinkage(GVS->linkage()) ||
+ GlobalValue::isLinkOnceLinkage(GVS->linkage())) {
+ if (SummaryList.size() == 1)
+ S = GVS.get();
+ // According thinLTOResolvePrevailingGUID these are unlikely prevailing.
+ } else {
+ ++NumIndexCalleeUnhandled;
+ }
+ };
while (S) {
if (!S->isLive() || !S->isDSOLocal())
return nullptr;
if (FunctionSummary *FS = dyn_cast<FunctionSummary>(S))
return FS;
AliasSummary *AS = dyn_cast<AliasSummary>(S);
- if (!AS || !AS->hasAliasee())
+ if (!AS || !AS->hasAliasee())
return nullptr;
S = AS->getBaseObject();
if (S == AS)
@@ -692,33 +692,33 @@ const ConstantRange *findParamAccess(const FunctionSummary &FS,
void resolveAllCalls(UseInfo<GlobalValue> &Use,
const ModuleSummaryIndex *Index) {
ConstantRange FullSet(Use.Range.getBitWidth(), true);
- // Move Use.Calls to a temp storage and repopulate - don't use std::move as it
- // leaves Use.Calls in an undefined state.
- UseInfo<GlobalValue>::CallsTy TmpCalls;
- std::swap(TmpCalls, Use.Calls);
- for (const auto &C : TmpCalls) {
- const Function *F = findCalleeInModule(C.first.Callee);
+ // Move Use.Calls to a temp storage and repopulate - don't use std::move as it
+ // leaves Use.Calls in an undefined state.
+ UseInfo<GlobalValue>::CallsTy TmpCalls;
+ std::swap(TmpCalls, Use.Calls);
+ for (const auto &C : TmpCalls) {
+ const Function *F = findCalleeInModule(C.first.Callee);
if (F) {
- Use.Calls.emplace(CallInfo<GlobalValue>(F, C.first.ParamNo), C.second);
+ Use.Calls.emplace(CallInfo<GlobalValue>(F, C.first.ParamNo), C.second);
continue;
}
if (!Index)
return Use.updateRange(FullSet);
- FunctionSummary *FS =
- findCalleeFunctionSummary(Index->getValueInfo(C.first.Callee->getGUID()),
- C.first.Callee->getParent()->getModuleIdentifier());
- ++NumModuleCalleeLookupTotal;
- if (!FS) {
- ++NumModuleCalleeLookupFailed;
+ FunctionSummary *FS =
+ findCalleeFunctionSummary(Index->getValueInfo(C.first.Callee->getGUID()),
+ C.first.Callee->getParent()->getModuleIdentifier());
+ ++NumModuleCalleeLookupTotal;
+ if (!FS) {
+ ++NumModuleCalleeLookupFailed;
return Use.updateRange(FullSet);
- }
- const ConstantRange *Found = findParamAccess(*FS, C.first.ParamNo);
- if (!Found || Found->isFullSet())
+ }
+ const ConstantRange *Found = findParamAccess(*FS, C.first.ParamNo);
+ if (!Found || Found->isFullSet())
return Use.updateRange(FullSet);
ConstantRange Access = Found->sextOrTrunc(Use.Range.getBitWidth());
- if (!Access.isEmptySet())
- Use.updateRange(addOverflowNever(Access, C.second));
+ if (!Access.isEmptySet())
+ Use.updateRange(addOverflowNever(Access, C.second));
}
}
@@ -733,11 +733,11 @@ GVToSSI createGlobalStackSafetyInfo(
auto Copy = Functions;
for (auto &FnKV : Copy)
- for (auto &KV : FnKV.second.Params) {
+ for (auto &KV : FnKV.second.Params) {
resolveAllCalls(KV.second, Index);
- if (KV.second.Range.isFullSet())
- KV.second.Calls.clear();
- }
+ if (KV.second.Range.isFullSet())
+ KV.second.Calls.clear();
+ }
uint32_t PointerSize = Copy.begin()
->first->getParent()
@@ -752,8 +752,8 @@ GVToSSI createGlobalStackSafetyInfo(
auto &A = KV.second;
resolveAllCalls(A, Index);
for (auto &C : A.Calls) {
- A.updateRange(SSDFA.getArgumentAccessRange(C.first.Callee,
- C.first.ParamNo, C.second));
+ A.updateRange(SSDFA.getArgumentAccessRange(C.first.Callee,
+ C.first.ParamNo, C.second));
}
// FIXME: This is needed only to preserve calls in print() results.
A.Calls = SrcF.Allocas.find(KV.first)->second.Calls;
@@ -822,7 +822,7 @@ const StackSafetyGlobalInfo::InfoTy &StackSafetyGlobalInfo::getInfo() const {
}
std::vector<FunctionSummary::ParamAccess>
-StackSafetyInfo::getParamAccesses(ModuleSummaryIndex &Index) const {
+StackSafetyInfo::getParamAccesses(ModuleSummaryIndex &Index) const {
// Implementation transforms internal representation of parameter information
// into FunctionSummary format.
std::vector<FunctionSummary::ParamAccess> ParamAccesses;
@@ -843,21 +843,21 @@ StackSafetyInfo::getParamAccesses(ModuleSummaryIndex &Index) const {
// will make ParamAccess::Range as FullSet anyway. So we can drop the
// entire parameter like we did above.
// TODO(vitalybuka): Return already filtered parameters from getInfo().
- if (C.second.isFullSet()) {
+ if (C.second.isFullSet()) {
ParamAccesses.pop_back();
break;
}
- Param.Calls.emplace_back(C.first.ParamNo,
- Index.getOrInsertValueInfo(C.first.Callee),
- C.second);
+ Param.Calls.emplace_back(C.first.ParamNo,
+ Index.getOrInsertValueInfo(C.first.Callee),
+ C.second);
}
}
- for (FunctionSummary::ParamAccess &Param : ParamAccesses) {
- sort(Param.Calls, [](const FunctionSummary::ParamAccess::Call &L,
- const FunctionSummary::ParamAccess::Call &R) {
- return std::tie(L.ParamNo, L.Callee) < std::tie(R.ParamNo, R.Callee);
- });
- }
+ for (FunctionSummary::ParamAccess &Param : ParamAccesses) {
+ sort(Param.Calls, [](const FunctionSummary::ParamAccess::Call &L,
+ const FunctionSummary::ParamAccess::Call &R) {
+ return std::tie(L.ParamNo, L.Callee) < std::tie(R.ParamNo, R.Callee);
+ });
+ }
return ParamAccesses;
}
@@ -1002,28 +1002,28 @@ bool llvm::needsParamAccessSummary(const Module &M) {
}
void llvm::generateParamAccessSummary(ModuleSummaryIndex &Index) {
- if (!Index.hasParamAccess())
- return;
+ if (!Index.hasParamAccess())
+ return;
const ConstantRange FullSet(FunctionSummary::ParamAccess::RangeWidth, true);
-
- auto CountParamAccesses = [&](auto &Stat) {
- if (!AreStatisticsEnabled())
- return;
- for (auto &GVS : Index)
- for (auto &GV : GVS.second.SummaryList)
- if (FunctionSummary *FS = dyn_cast<FunctionSummary>(GV.get()))
- Stat += FS->paramAccesses().size();
- };
-
- CountParamAccesses(NumCombinedParamAccessesBefore);
-
+
+ auto CountParamAccesses = [&](auto &Stat) {
+ if (!AreStatisticsEnabled())
+ return;
+ for (auto &GVS : Index)
+ for (auto &GV : GVS.second.SummaryList)
+ if (FunctionSummary *FS = dyn_cast<FunctionSummary>(GV.get()))
+ Stat += FS->paramAccesses().size();
+ };
+
+ CountParamAccesses(NumCombinedParamAccessesBefore);
+
std::map<const FunctionSummary *, FunctionInfo<FunctionSummary>> Functions;
// Convert the ModuleSummaryIndex to a FunctionMap
for (auto &GVS : Index) {
for (auto &GV : GVS.second.SummaryList) {
FunctionSummary *FS = dyn_cast<FunctionSummary>(GV.get());
- if (!FS || FS->paramAccesses().empty())
+ if (!FS || FS->paramAccesses().empty())
continue;
if (FS->isLive() && FS->isDSOLocal()) {
FunctionInfo<FunctionSummary> FI;
@@ -1035,17 +1035,17 @@ void llvm::generateParamAccessSummary(ModuleSummaryIndex &Index) {
US.Range = PS.Use;
for (auto &Call : PS.Calls) {
assert(!Call.Offsets.isFullSet());
- FunctionSummary *S =
- findCalleeFunctionSummary(Call.Callee, FS->modulePath());
- ++NumCombinedCalleeLookupTotal;
+ FunctionSummary *S =
+ findCalleeFunctionSummary(Call.Callee, FS->modulePath());
+ ++NumCombinedCalleeLookupTotal;
if (!S) {
- ++NumCombinedCalleeLookupFailed;
+ ++NumCombinedCalleeLookupFailed;
US.Range = FullSet;
US.Calls.clear();
break;
}
- US.Calls.emplace(CallInfo<FunctionSummary>(S, Call.ParamNo),
- Call.Offsets);
+ US.Calls.emplace(CallInfo<FunctionSummary>(S, Call.ParamNo),
+ Call.Offsets);
}
}
Functions.emplace(FS, std::move(FI));
@@ -1056,16 +1056,16 @@ void llvm::generateParamAccessSummary(ModuleSummaryIndex &Index) {
FS->setParamAccesses({});
}
}
- NumCombinedDataFlowNodes += Functions.size();
+ NumCombinedDataFlowNodes += Functions.size();
StackSafetyDataFlowAnalysis<FunctionSummary> SSDFA(
FunctionSummary::ParamAccess::RangeWidth, std::move(Functions));
for (auto &KV : SSDFA.run()) {
std::vector<FunctionSummary::ParamAccess> NewParams;
NewParams.reserve(KV.second.Params.size());
for (auto &Param : KV.second.Params) {
- // It's not needed as FullSet is processed the same as a missing value.
- if (Param.second.Range.isFullSet())
- continue;
+ // It's not needed as FullSet is processed the same as a missing value.
+ if (Param.second.Range.isFullSet())
+ continue;
NewParams.emplace_back();
FunctionSummary::ParamAccess &New = NewParams.back();
New.ParamNo = Param.first;
@@ -1074,8 +1074,8 @@ void llvm::generateParamAccessSummary(ModuleSummaryIndex &Index) {
const_cast<FunctionSummary *>(KV.first)->setParamAccesses(
std::move(NewParams));
}
-
- CountParamAccesses(NumCombinedParamAccessesAfter);
+
+ CountParamAccesses(NumCombinedParamAccessesAfter);
}
static const char LocalPassArg[] = "stack-safety-local";
diff --git a/contrib/libs/llvm12/lib/Analysis/SyncDependenceAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/SyncDependenceAnalysis.cpp
index f26176a2c5..67a1365b69 100644
--- a/contrib/libs/llvm12/lib/Analysis/SyncDependenceAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/SyncDependenceAnalysis.cpp
@@ -1,4 +1,4 @@
-//===--- SyncDependenceAnalysis.cpp - Compute Control Divergence Effects --===//
+//===--- SyncDependenceAnalysis.cpp - Compute Control Divergence Effects --===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -98,7 +98,7 @@
// loop exit and the loop header (_after_ SSA construction).
//
//===----------------------------------------------------------------------===//
-#include "llvm/Analysis/SyncDependenceAnalysis.h"
+#include "llvm/Analysis/SyncDependenceAnalysis.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/PostDominators.h"
@@ -107,355 +107,355 @@
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
-#include <functional>
+#include <functional>
#include <stack>
#include <unordered_set>
#define DEBUG_TYPE "sync-dependence"
-// The SDA algorithm operates on a modified CFG - we modify the edges leaving
-// loop headers as follows:
-//
-// * We remove all edges leaving all loop headers.
-// * We add additional edges from the loop headers to their exit blocks.
-//
-// The modification is virtual, that is whenever we visit a loop header we
-// pretend it had different successors.
-namespace {
-using namespace llvm;
-
-// Custom Post-Order Traveral
-//
-// We cannot use the vanilla (R)PO computation of LLVM because:
-// * We (virtually) modify the CFG.
-// * We want a loop-compact block enumeration, that is the numbers assigned by
-// the traveral to the blocks of a loop are an interval.
-using POCB = std::function<void(const BasicBlock &)>;
-using VisitedSet = std::set<const BasicBlock *>;
-using BlockStack = std::vector<const BasicBlock *>;
-
-// forward
-static void computeLoopPO(const LoopInfo &LI, Loop &Loop, POCB CallBack,
- VisitedSet &Finalized);
-
-// for a nested region (top-level loop or nested loop)
-static void computeStackPO(BlockStack &Stack, const LoopInfo &LI, Loop *Loop,
- POCB CallBack, VisitedSet &Finalized) {
- const auto *LoopHeader = Loop ? Loop->getHeader() : nullptr;
- while (!Stack.empty()) {
- const auto *NextBB = Stack.back();
-
- auto *NestedLoop = LI.getLoopFor(NextBB);
- bool IsNestedLoop = NestedLoop != Loop;
-
- // Treat the loop as a node
- if (IsNestedLoop) {
- SmallVector<BasicBlock *, 3> NestedExits;
- NestedLoop->getUniqueExitBlocks(NestedExits);
- bool PushedNodes = false;
- for (const auto *NestedExitBB : NestedExits) {
- if (NestedExitBB == LoopHeader)
- continue;
- if (Loop && !Loop->contains(NestedExitBB))
- continue;
- if (Finalized.count(NestedExitBB))
- continue;
- PushedNodes = true;
- Stack.push_back(NestedExitBB);
- }
- if (!PushedNodes) {
- // All loop exits finalized -> finish this node
- Stack.pop_back();
- computeLoopPO(LI, *NestedLoop, CallBack, Finalized);
- }
- continue;
- }
-
- // DAG-style
- bool PushedNodes = false;
- for (const auto *SuccBB : successors(NextBB)) {
- if (SuccBB == LoopHeader)
- continue;
- if (Loop && !Loop->contains(SuccBB))
- continue;
- if (Finalized.count(SuccBB))
- continue;
- PushedNodes = true;
- Stack.push_back(SuccBB);
- }
- if (!PushedNodes) {
- // Never push nodes twice
- Stack.pop_back();
- if (!Finalized.insert(NextBB).second)
- continue;
- CallBack(*NextBB);
- }
- }
-}
-
-static void computeTopLevelPO(Function &F, const LoopInfo &LI, POCB CallBack) {
- VisitedSet Finalized;
- BlockStack Stack;
- Stack.reserve(24); // FIXME made-up number
- Stack.push_back(&F.getEntryBlock());
- computeStackPO(Stack, LI, nullptr, CallBack, Finalized);
-}
-
-static void computeLoopPO(const LoopInfo &LI, Loop &Loop, POCB CallBack,
- VisitedSet &Finalized) {
- /// Call CallBack on all loop blocks.
- std::vector<const BasicBlock *> Stack;
- const auto *LoopHeader = Loop.getHeader();
-
- // Visit the header last
- Finalized.insert(LoopHeader);
- CallBack(*LoopHeader);
-
- // Initialize with immediate successors
- for (const auto *BB : successors(LoopHeader)) {
- if (!Loop.contains(BB))
- continue;
- if (BB == LoopHeader)
- continue;
- Stack.push_back(BB);
- }
-
- // Compute PO inside region
- computeStackPO(Stack, LI, &Loop, CallBack, Finalized);
-}
-
-} // namespace
-
+// The SDA algorithm operates on a modified CFG - we modify the edges leaving
+// loop headers as follows:
+//
+// * We remove all edges leaving all loop headers.
+// * We add additional edges from the loop headers to their exit blocks.
+//
+// The modification is virtual, that is whenever we visit a loop header we
+// pretend it had different successors.
+namespace {
+using namespace llvm;
+
+// Custom Post-Order Traveral
+//
+// We cannot use the vanilla (R)PO computation of LLVM because:
+// * We (virtually) modify the CFG.
+// * We want a loop-compact block enumeration, that is the numbers assigned by
+// the traveral to the blocks of a loop are an interval.
+using POCB = std::function<void(const BasicBlock &)>;
+using VisitedSet = std::set<const BasicBlock *>;
+using BlockStack = std::vector<const BasicBlock *>;
+
+// forward
+static void computeLoopPO(const LoopInfo &LI, Loop &Loop, POCB CallBack,
+ VisitedSet &Finalized);
+
+// for a nested region (top-level loop or nested loop)
+static void computeStackPO(BlockStack &Stack, const LoopInfo &LI, Loop *Loop,
+ POCB CallBack, VisitedSet &Finalized) {
+ const auto *LoopHeader = Loop ? Loop->getHeader() : nullptr;
+ while (!Stack.empty()) {
+ const auto *NextBB = Stack.back();
+
+ auto *NestedLoop = LI.getLoopFor(NextBB);
+ bool IsNestedLoop = NestedLoop != Loop;
+
+ // Treat the loop as a node
+ if (IsNestedLoop) {
+ SmallVector<BasicBlock *, 3> NestedExits;
+ NestedLoop->getUniqueExitBlocks(NestedExits);
+ bool PushedNodes = false;
+ for (const auto *NestedExitBB : NestedExits) {
+ if (NestedExitBB == LoopHeader)
+ continue;
+ if (Loop && !Loop->contains(NestedExitBB))
+ continue;
+ if (Finalized.count(NestedExitBB))
+ continue;
+ PushedNodes = true;
+ Stack.push_back(NestedExitBB);
+ }
+ if (!PushedNodes) {
+ // All loop exits finalized -> finish this node
+ Stack.pop_back();
+ computeLoopPO(LI, *NestedLoop, CallBack, Finalized);
+ }
+ continue;
+ }
+
+ // DAG-style
+ bool PushedNodes = false;
+ for (const auto *SuccBB : successors(NextBB)) {
+ if (SuccBB == LoopHeader)
+ continue;
+ if (Loop && !Loop->contains(SuccBB))
+ continue;
+ if (Finalized.count(SuccBB))
+ continue;
+ PushedNodes = true;
+ Stack.push_back(SuccBB);
+ }
+ if (!PushedNodes) {
+ // Never push nodes twice
+ Stack.pop_back();
+ if (!Finalized.insert(NextBB).second)
+ continue;
+ CallBack(*NextBB);
+ }
+ }
+}
+
+static void computeTopLevelPO(Function &F, const LoopInfo &LI, POCB CallBack) {
+ VisitedSet Finalized;
+ BlockStack Stack;
+ Stack.reserve(24); // FIXME made-up number
+ Stack.push_back(&F.getEntryBlock());
+ computeStackPO(Stack, LI, nullptr, CallBack, Finalized);
+}
+
+static void computeLoopPO(const LoopInfo &LI, Loop &Loop, POCB CallBack,
+ VisitedSet &Finalized) {
+ /// Call CallBack on all loop blocks.
+ std::vector<const BasicBlock *> Stack;
+ const auto *LoopHeader = Loop.getHeader();
+
+ // Visit the header last
+ Finalized.insert(LoopHeader);
+ CallBack(*LoopHeader);
+
+ // Initialize with immediate successors
+ for (const auto *BB : successors(LoopHeader)) {
+ if (!Loop.contains(BB))
+ continue;
+ if (BB == LoopHeader)
+ continue;
+ Stack.push_back(BB);
+ }
+
+ // Compute PO inside region
+ computeStackPO(Stack, LI, &Loop, CallBack, Finalized);
+}
+
+} // namespace
+
namespace llvm {
-ControlDivergenceDesc SyncDependenceAnalysis::EmptyDivergenceDesc;
+ControlDivergenceDesc SyncDependenceAnalysis::EmptyDivergenceDesc;
SyncDependenceAnalysis::SyncDependenceAnalysis(const DominatorTree &DT,
const PostDominatorTree &PDT,
const LoopInfo &LI)
- : DT(DT), PDT(PDT), LI(LI) {
- computeTopLevelPO(*DT.getRoot()->getParent(), LI,
- [&](const BasicBlock &BB) { LoopPO.appendBlock(BB); });
-}
+ : DT(DT), PDT(PDT), LI(LI) {
+ computeTopLevelPO(*DT.getRoot()->getParent(), LI,
+ [&](const BasicBlock &BB) { LoopPO.appendBlock(BB); });
+}
SyncDependenceAnalysis::~SyncDependenceAnalysis() {}
// divergence propagator for reducible CFGs
struct DivergencePropagator {
- const ModifiedPO &LoopPOT;
+ const ModifiedPO &LoopPOT;
const DominatorTree &DT;
const PostDominatorTree &PDT;
const LoopInfo &LI;
- const BasicBlock &DivTermBlock;
-
- // * if BlockLabels[IndexOf(B)] == C then C is the dominating definition at
- // block B
- // * if BlockLabels[IndexOf(B)] ~ undef then we haven't seen B yet
- // * if BlockLabels[IndexOf(B)] == B then B is a join point of disjoint paths
- // from X or B is an immediate successor of X (initial value).
- using BlockLabelVec = std::vector<const BasicBlock *>;
- BlockLabelVec BlockLabels;
- // divergent join and loop exit descriptor.
- std::unique_ptr<ControlDivergenceDesc> DivDesc;
-
- DivergencePropagator(const ModifiedPO &LoopPOT, const DominatorTree &DT,
- const PostDominatorTree &PDT, const LoopInfo &LI,
- const BasicBlock &DivTermBlock)
- : LoopPOT(LoopPOT), DT(DT), PDT(PDT), LI(LI), DivTermBlock(DivTermBlock),
- BlockLabels(LoopPOT.size(), nullptr),
- DivDesc(new ControlDivergenceDesc) {}
+ const BasicBlock &DivTermBlock;
+
+ // * if BlockLabels[IndexOf(B)] == C then C is the dominating definition at
+ // block B
+ // * if BlockLabels[IndexOf(B)] ~ undef then we haven't seen B yet
+ // * if BlockLabels[IndexOf(B)] == B then B is a join point of disjoint paths
+ // from X or B is an immediate successor of X (initial value).
+ using BlockLabelVec = std::vector<const BasicBlock *>;
+ BlockLabelVec BlockLabels;
+ // divergent join and loop exit descriptor.
+ std::unique_ptr<ControlDivergenceDesc> DivDesc;
+
+ DivergencePropagator(const ModifiedPO &LoopPOT, const DominatorTree &DT,
+ const PostDominatorTree &PDT, const LoopInfo &LI,
+ const BasicBlock &DivTermBlock)
+ : LoopPOT(LoopPOT), DT(DT), PDT(PDT), LI(LI), DivTermBlock(DivTermBlock),
+ BlockLabels(LoopPOT.size(), nullptr),
+ DivDesc(new ControlDivergenceDesc) {}
void printDefs(raw_ostream &Out) {
- Out << "Propagator::BlockLabels {\n";
- for (int BlockIdx = (int)BlockLabels.size() - 1; BlockIdx > 0; --BlockIdx) {
- const auto *Label = BlockLabels[BlockIdx];
- Out << LoopPOT.getBlockAt(BlockIdx)->getName().str() << "(" << BlockIdx
- << ") : ";
- if (!Label) {
- Out << "<null>\n";
+ Out << "Propagator::BlockLabels {\n";
+ for (int BlockIdx = (int)BlockLabels.size() - 1; BlockIdx > 0; --BlockIdx) {
+ const auto *Label = BlockLabels[BlockIdx];
+ Out << LoopPOT.getBlockAt(BlockIdx)->getName().str() << "(" << BlockIdx
+ << ") : ";
+ if (!Label) {
+ Out << "<null>\n";
} else {
- Out << Label->getName() << "\n";
+ Out << Label->getName() << "\n";
}
}
Out << "}\n";
}
- // Push a definition (\p PushedLabel) to \p SuccBlock and return whether this
- // causes a divergent join.
- bool computeJoin(const BasicBlock &SuccBlock, const BasicBlock &PushedLabel) {
- auto SuccIdx = LoopPOT.getIndexOf(SuccBlock);
+ // Push a definition (\p PushedLabel) to \p SuccBlock and return whether this
+ // causes a divergent join.
+ bool computeJoin(const BasicBlock &SuccBlock, const BasicBlock &PushedLabel) {
+ auto SuccIdx = LoopPOT.getIndexOf(SuccBlock);
- // unset or same reaching label
- const auto *OldLabel = BlockLabels[SuccIdx];
- if (!OldLabel || (OldLabel == &PushedLabel)) {
- BlockLabels[SuccIdx] = &PushedLabel;
- return false;
+ // unset or same reaching label
+ const auto *OldLabel = BlockLabels[SuccIdx];
+ if (!OldLabel || (OldLabel == &PushedLabel)) {
+ BlockLabels[SuccIdx] = &PushedLabel;
+ return false;
}
- // Update the definition
- BlockLabels[SuccIdx] = &SuccBlock;
- return true;
- }
-
- // visiting a virtual loop exit edge from the loop header --> temporal
- // divergence on join
- bool visitLoopExitEdge(const BasicBlock &ExitBlock,
- const BasicBlock &DefBlock, bool FromParentLoop) {
- // Pushing from a non-parent loop cannot cause temporal divergence.
- if (!FromParentLoop)
- return visitEdge(ExitBlock, DefBlock);
-
- if (!computeJoin(ExitBlock, DefBlock))
- return false;
-
- // Identified a divergent loop exit
- DivDesc->LoopDivBlocks.insert(&ExitBlock);
- LLVM_DEBUG(dbgs() << "\tDivergent loop exit: " << ExitBlock.getName()
- << "\n");
- return true;
+ // Update the definition
+ BlockLabels[SuccIdx] = &SuccBlock;
+ return true;
+ }
+
+ // visiting a virtual loop exit edge from the loop header --> temporal
+ // divergence on join
+ bool visitLoopExitEdge(const BasicBlock &ExitBlock,
+ const BasicBlock &DefBlock, bool FromParentLoop) {
+ // Pushing from a non-parent loop cannot cause temporal divergence.
+ if (!FromParentLoop)
+ return visitEdge(ExitBlock, DefBlock);
+
+ if (!computeJoin(ExitBlock, DefBlock))
+ return false;
+
+ // Identified a divergent loop exit
+ DivDesc->LoopDivBlocks.insert(&ExitBlock);
+ LLVM_DEBUG(dbgs() << "\tDivergent loop exit: " << ExitBlock.getName()
+ << "\n");
+ return true;
}
- // process \p SuccBlock with reaching definition \p DefBlock
- bool visitEdge(const BasicBlock &SuccBlock, const BasicBlock &DefBlock) {
- if (!computeJoin(SuccBlock, DefBlock))
- return false;
-
- // Divergent, disjoint paths join.
- DivDesc->JoinDivBlocks.insert(&SuccBlock);
- LLVM_DEBUG(dbgs() << "\tDivergent join: " << SuccBlock.getName());
- return true;
- }
-
- std::unique_ptr<ControlDivergenceDesc> computeJoinPoints() {
- assert(DivDesc);
-
- LLVM_DEBUG(dbgs() << "SDA:computeJoinPoints: " << DivTermBlock.getName()
- << "\n");
-
- const auto *DivBlockLoop = LI.getLoopFor(&DivTermBlock);
-
- // Early stopping criterion
- int FloorIdx = LoopPOT.size() - 1;
- const BasicBlock *FloorLabel = nullptr;
-
+ // process \p SuccBlock with reaching definition \p DefBlock
+ bool visitEdge(const BasicBlock &SuccBlock, const BasicBlock &DefBlock) {
+ if (!computeJoin(SuccBlock, DefBlock))
+ return false;
+
+ // Divergent, disjoint paths join.
+ DivDesc->JoinDivBlocks.insert(&SuccBlock);
+ LLVM_DEBUG(dbgs() << "\tDivergent join: " << SuccBlock.getName());
+ return true;
+ }
+
+ std::unique_ptr<ControlDivergenceDesc> computeJoinPoints() {
+ assert(DivDesc);
+
+ LLVM_DEBUG(dbgs() << "SDA:computeJoinPoints: " << DivTermBlock.getName()
+ << "\n");
+
+ const auto *DivBlockLoop = LI.getLoopFor(&DivTermBlock);
+
+ // Early stopping criterion
+ int FloorIdx = LoopPOT.size() - 1;
+ const BasicBlock *FloorLabel = nullptr;
+
// bootstrap with branch targets
- int BlockIdx = 0;
-
- for (const auto *SuccBlock : successors(&DivTermBlock)) {
- auto SuccIdx = LoopPOT.getIndexOf(*SuccBlock);
- BlockLabels[SuccIdx] = SuccBlock;
-
- // Find the successor with the highest index to start with
- BlockIdx = std::max<int>(BlockIdx, SuccIdx);
- FloorIdx = std::min<int>(FloorIdx, SuccIdx);
-
- // Identify immediate divergent loop exits
- if (!DivBlockLoop)
- continue;
-
- const auto *BlockLoop = LI.getLoopFor(SuccBlock);
- if (BlockLoop && DivBlockLoop->contains(BlockLoop))
- continue;
- DivDesc->LoopDivBlocks.insert(SuccBlock);
- LLVM_DEBUG(dbgs() << "\tImmediate divergent loop exit: "
- << SuccBlock->getName() << "\n");
+ int BlockIdx = 0;
+
+ for (const auto *SuccBlock : successors(&DivTermBlock)) {
+ auto SuccIdx = LoopPOT.getIndexOf(*SuccBlock);
+ BlockLabels[SuccIdx] = SuccBlock;
+
+ // Find the successor with the highest index to start with
+ BlockIdx = std::max<int>(BlockIdx, SuccIdx);
+ FloorIdx = std::min<int>(FloorIdx, SuccIdx);
+
+ // Identify immediate divergent loop exits
+ if (!DivBlockLoop)
+ continue;
+
+ const auto *BlockLoop = LI.getLoopFor(SuccBlock);
+ if (BlockLoop && DivBlockLoop->contains(BlockLoop))
+ continue;
+ DivDesc->LoopDivBlocks.insert(SuccBlock);
+ LLVM_DEBUG(dbgs() << "\tImmediate divergent loop exit: "
+ << SuccBlock->getName() << "\n");
}
// propagate definitions at the immediate successors of the node in RPO
- for (; BlockIdx >= FloorIdx; --BlockIdx) {
- LLVM_DEBUG(dbgs() << "Before next visit:\n"; printDefs(dbgs()));
+ for (; BlockIdx >= FloorIdx; --BlockIdx) {
+ LLVM_DEBUG(dbgs() << "Before next visit:\n"; printDefs(dbgs()));
- // Any label available here
- const auto *Label = BlockLabels[BlockIdx];
- if (!Label)
+ // Any label available here
+ const auto *Label = BlockLabels[BlockIdx];
+ if (!Label)
continue;
- // Ok. Get the block
- const auto *Block = LoopPOT.getBlockAt(BlockIdx);
- LLVM_DEBUG(dbgs() << "SDA::joins. visiting " << Block->getName() << "\n");
+ // Ok. Get the block
+ const auto *Block = LoopPOT.getBlockAt(BlockIdx);
+ LLVM_DEBUG(dbgs() << "SDA::joins. visiting " << Block->getName() << "\n");
auto *BlockLoop = LI.getLoopFor(Block);
- bool IsLoopHeader = BlockLoop && BlockLoop->getHeader() == Block;
- bool CausedJoin = false;
- int LoweredFloorIdx = FloorIdx;
- if (IsLoopHeader) {
- // Disconnect from immediate successors and propagate directly to loop
- // exits.
+ bool IsLoopHeader = BlockLoop && BlockLoop->getHeader() == Block;
+ bool CausedJoin = false;
+ int LoweredFloorIdx = FloorIdx;
+ if (IsLoopHeader) {
+ // Disconnect from immediate successors and propagate directly to loop
+ // exits.
SmallVector<BasicBlock *, 4> BlockLoopExits;
BlockLoop->getExitBlocks(BlockLoopExits);
-
- bool IsParentLoop = BlockLoop->contains(&DivTermBlock);
+
+ bool IsParentLoop = BlockLoop->contains(&DivTermBlock);
for (const auto *BlockLoopExit : BlockLoopExits) {
- CausedJoin |= visitLoopExitEdge(*BlockLoopExit, *Label, IsParentLoop);
- LoweredFloorIdx = std::min<int>(LoweredFloorIdx,
- LoopPOT.getIndexOf(*BlockLoopExit));
+ CausedJoin |= visitLoopExitEdge(*BlockLoopExit, *Label, IsParentLoop);
+ LoweredFloorIdx = std::min<int>(LoweredFloorIdx,
+ LoopPOT.getIndexOf(*BlockLoopExit));
}
} else {
- // Acyclic successor case
+ // Acyclic successor case
for (const auto *SuccBlock : successors(Block)) {
- CausedJoin |= visitEdge(*SuccBlock, *Label);
- LoweredFloorIdx =
- std::min<int>(LoweredFloorIdx, LoopPOT.getIndexOf(*SuccBlock));
+ CausedJoin |= visitEdge(*SuccBlock, *Label);
+ LoweredFloorIdx =
+ std::min<int>(LoweredFloorIdx, LoopPOT.getIndexOf(*SuccBlock));
}
}
-
- // Floor update
- if (CausedJoin) {
- // 1. Different labels pushed to successors
- FloorIdx = LoweredFloorIdx;
- } else if (FloorLabel != Label) {
- // 2. No join caused BUT we pushed a label that is different than the
- // last pushed label
- FloorIdx = LoweredFloorIdx;
- FloorLabel = Label;
- }
+
+ // Floor update
+ if (CausedJoin) {
+ // 1. Different labels pushed to successors
+ FloorIdx = LoweredFloorIdx;
+ } else if (FloorLabel != Label) {
+ // 2. No join caused BUT we pushed a label that is different than the
+ // last pushed label
+ FloorIdx = LoweredFloorIdx;
+ FloorLabel = Label;
+ }
}
LLVM_DEBUG(dbgs() << "SDA::joins. After propagation:\n"; printDefs(dbgs()));
- return std::move(DivDesc);
+ return std::move(DivDesc);
}
};
-#ifndef NDEBUG
-static void printBlockSet(ConstBlockSet &Blocks, raw_ostream &Out) {
- Out << "[";
- bool First = true;
- for (const auto *BB : Blocks) {
- if (!First)
- Out << ", ";
- First = false;
- Out << BB->getName();
+#ifndef NDEBUG
+static void printBlockSet(ConstBlockSet &Blocks, raw_ostream &Out) {
+ Out << "[";
+ bool First = true;
+ for (const auto *BB : Blocks) {
+ if (!First)
+ Out << ", ";
+ First = false;
+ Out << BB->getName();
}
- Out << "]";
+ Out << "]";
}
-#endif
+#endif
-const ControlDivergenceDesc &
-SyncDependenceAnalysis::getJoinBlocks(const Instruction &Term) {
+const ControlDivergenceDesc &
+SyncDependenceAnalysis::getJoinBlocks(const Instruction &Term) {
// trivial case
- if (Term.getNumSuccessors() <= 1) {
- return EmptyDivergenceDesc;
+ if (Term.getNumSuccessors() <= 1) {
+ return EmptyDivergenceDesc;
}
// already available in cache?
- auto ItCached = CachedControlDivDescs.find(&Term);
- if (ItCached != CachedControlDivDescs.end())
+ auto ItCached = CachedControlDivDescs.find(&Term);
+ if (ItCached != CachedControlDivDescs.end())
return *ItCached->second;
// compute all join points
- // Special handling of divergent loop exits is not needed for LCSSA
+ // Special handling of divergent loop exits is not needed for LCSSA
const auto &TermBlock = *Term.getParent();
- DivergencePropagator Propagator(LoopPO, DT, PDT, LI, TermBlock);
- auto DivDesc = Propagator.computeJoinPoints();
-
- LLVM_DEBUG(dbgs() << "Result (" << Term.getParent()->getName() << "):\n";
- dbgs() << "JoinDivBlocks: ";
- printBlockSet(DivDesc->JoinDivBlocks, dbgs());
- dbgs() << "\nLoopDivBlocks: ";
- printBlockSet(DivDesc->LoopDivBlocks, dbgs()); dbgs() << "\n";);
-
- auto ItInserted = CachedControlDivDescs.emplace(&Term, std::move(DivDesc));
+ DivergencePropagator Propagator(LoopPO, DT, PDT, LI, TermBlock);
+ auto DivDesc = Propagator.computeJoinPoints();
+
+ LLVM_DEBUG(dbgs() << "Result (" << Term.getParent()->getName() << "):\n";
+ dbgs() << "JoinDivBlocks: ";
+ printBlockSet(DivDesc->JoinDivBlocks, dbgs());
+ dbgs() << "\nLoopDivBlocks: ";
+ printBlockSet(DivDesc->LoopDivBlocks, dbgs()); dbgs() << "\n";);
+
+ auto ItInserted = CachedControlDivDescs.emplace(&Term, std::move(DivDesc));
assert(ItInserted.second);
return *ItInserted.first->second;
}
diff --git a/contrib/libs/llvm12/lib/Analysis/TFUtils.cpp b/contrib/libs/llvm12/lib/Analysis/TFUtils.cpp
index 9d4859ab85..3f26bdfdc0 100644
--- a/contrib/libs/llvm12/lib/Analysis/TFUtils.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/TFUtils.cpp
@@ -10,23 +10,23 @@
// This file implements utilities for interfacing with tensorflow C APIs.
//
//===----------------------------------------------------------------------===//
-#include "llvm/Config/config.h"
-#if defined(LLVM_HAVE_TF_API)
+#include "llvm/Config/config.h"
+#if defined(LLVM_HAVE_TF_API)
-#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/Utils/TFUtils.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/JSON.h"
+#include "llvm/Support/JSON.h"
#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
-#error #include "tensorflow/c/c_api.h"
-#error #include "tensorflow/c/c_api_experimental.h"
+#error #include "tensorflow/c/c_api.h"
+#error #include "tensorflow/c/c_api_experimental.h"
#include <cassert>
-#include <numeric>
+#include <numeric>
using namespace llvm;
@@ -64,89 +64,89 @@ TFStatusPtr createTFStatus() {
TFSessionOptionsPtr createTFSessionOptions() {
return TFSessionOptionsPtr(TF_NewSessionOptions(), &TF_DeleteSessionOptions);
}
-
-/// Write the values of one tensor as a list.
-template <typename T>
-void writeTensorValues(raw_ostream &OutFile, const char *TensorData,
- size_t ElemCount) {
- OutFile << "[";
- const T *TypedData = reinterpret_cast<const T *>(TensorData);
- for (size_t I = 0; I < ElemCount; ++I) {
- if (I > 0)
- OutFile << ", ";
- OutFile << TypedData[I];
- }
- OutFile << "]";
-}
-
-/// Write a list of tensors as a sequence of TensorFlow FeatureList protobufs.
-/// The tensors are assumed to be stored contiguously, in row-major format,
-/// in the TensorData buffer. Each tensor has the shape given by Spec. The
-/// feature name in the output is either the provided LoggingName, if
-/// specified, otherwise it's the name of the tensor (as given by Spec).
-void writeRawTensorsAsFeatureLists(raw_ostream &OutFile,
- const LoggedFeatureSpec &LoggedSpec,
- const char *TensorData, size_t TensorCount,
- bool FinalReward = false) {
- const char *FieldName = "<invalid>";
- std::function<void(const char *)> ValueWriter;
- const auto &Spec = LoggedSpec.Spec;
- // The 'Feature' protobuf only has 3 possible fields: float_list,
- // int64_list, or bytes_list, so we capture int32 values as int64. We don't
- // support any other types.
- if (Spec.isElementType<int64_t>()) {
- FieldName = "int64_list";
- ValueWriter = [&](const char *Data) {
- writeTensorValues<int64_t>(OutFile, Data, Spec.getElementCount());
- };
- } else if (Spec.isElementType<int32_t>()) {
- FieldName = "int64_list";
- ValueWriter = [&](const char *Data) {
- writeTensorValues<int32_t>(OutFile, Data, Spec.getElementCount());
- };
-
- } else if (Spec.isElementType<float>()) {
- FieldName = "float_list";
- ValueWriter = [&](const char *Data) {
- writeTensorValues<float>(OutFile, Data, Spec.getElementCount());
- };
-
- } else {
- llvm_unreachable("Unsupported tensor type.");
- }
-
- OutFile << " feature_list: {\n";
- OutFile << " key: "
- << "\""
- << (LoggedSpec.LoggingName ? *LoggedSpec.LoggingName : Spec.name())
- << "\" ";
- OutFile << "value: {\n";
- size_t TensorByteSize = Spec.getElementCount() * Spec.getElementByteSize();
-
- auto WriteFeatureProto = [&](const char *P) {
- OutFile << " feature: { " << FieldName << ": { value: ";
- ValueWriter(P);
- OutFile << " } }\n";
- };
-
- const char *CurrentTensor = TensorData;
- static int64_t Zero = 0;
- // Write all but the last value. If this is the final reward, don't increment
- // the CurrentTensor, and just write 0.
- for (size_t I = 0; I < TensorCount - 1; ++I) {
- if (FinalReward)
- WriteFeatureProto(reinterpret_cast<const char *>(&Zero));
- else {
- WriteFeatureProto(CurrentTensor);
- CurrentTensor += TensorByteSize;
- }
- }
-
- WriteFeatureProto(CurrentTensor);
-
- OutFile << " }\n";
- OutFile << " }\n";
-}
+
+/// Write the values of one tensor as a list.
+template <typename T>
+void writeTensorValues(raw_ostream &OutFile, const char *TensorData,
+ size_t ElemCount) {
+ OutFile << "[";
+ const T *TypedData = reinterpret_cast<const T *>(TensorData);
+ for (size_t I = 0; I < ElemCount; ++I) {
+ if (I > 0)
+ OutFile << ", ";
+ OutFile << TypedData[I];
+ }
+ OutFile << "]";
+}
+
+/// Write a list of tensors as a sequence of TensorFlow FeatureList protobufs.
+/// The tensors are assumed to be stored contiguously, in row-major format,
+/// in the TensorData buffer. Each tensor has the shape given by Spec. The
+/// feature name in the output is either the provided LoggingName, if
+/// specified, otherwise it's the name of the tensor (as given by Spec).
+void writeRawTensorsAsFeatureLists(raw_ostream &OutFile,
+ const LoggedFeatureSpec &LoggedSpec,
+ const char *TensorData, size_t TensorCount,
+ bool FinalReward = false) {
+ const char *FieldName = "<invalid>";
+ std::function<void(const char *)> ValueWriter;
+ const auto &Spec = LoggedSpec.Spec;
+ // The 'Feature' protobuf only has 3 possible fields: float_list,
+ // int64_list, or bytes_list, so we capture int32 values as int64. We don't
+ // support any other types.
+ if (Spec.isElementType<int64_t>()) {
+ FieldName = "int64_list";
+ ValueWriter = [&](const char *Data) {
+ writeTensorValues<int64_t>(OutFile, Data, Spec.getElementCount());
+ };
+ } else if (Spec.isElementType<int32_t>()) {
+ FieldName = "int64_list";
+ ValueWriter = [&](const char *Data) {
+ writeTensorValues<int32_t>(OutFile, Data, Spec.getElementCount());
+ };
+
+ } else if (Spec.isElementType<float>()) {
+ FieldName = "float_list";
+ ValueWriter = [&](const char *Data) {
+ writeTensorValues<float>(OutFile, Data, Spec.getElementCount());
+ };
+
+ } else {
+ llvm_unreachable("Unsupported tensor type.");
+ }
+
+ OutFile << " feature_list: {\n";
+ OutFile << " key: "
+ << "\""
+ << (LoggedSpec.LoggingName ? *LoggedSpec.LoggingName : Spec.name())
+ << "\" ";
+ OutFile << "value: {\n";
+ size_t TensorByteSize = Spec.getElementCount() * Spec.getElementByteSize();
+
+ auto WriteFeatureProto = [&](const char *P) {
+ OutFile << " feature: { " << FieldName << ": { value: ";
+ ValueWriter(P);
+ OutFile << " } }\n";
+ };
+
+ const char *CurrentTensor = TensorData;
+ static int64_t Zero = 0;
+ // Write all but the last value. If this is the final reward, don't increment
+ // the CurrentTensor, and just write 0.
+ for (size_t I = 0; I < TensorCount - 1; ++I) {
+ if (FinalReward)
+ WriteFeatureProto(reinterpret_cast<const char *>(&Zero));
+ else {
+ WriteFeatureProto(CurrentTensor);
+ CurrentTensor += TensorByteSize;
+ }
+ }
+
+ WriteFeatureProto(CurrentTensor);
+
+ OutFile << " }\n";
+ OutFile << " }\n";
+}
} // namespace
namespace llvm {
@@ -170,122 +170,122 @@ private:
std::vector<TF_Tensor *> Output;
};
-size_t TensorSpec::getElementByteSize() const {
- return TF_DataTypeSize(static_cast<TF_DataType>(TypeIndex));
-}
-
-TensorSpec::TensorSpec(const std::string &Name, int Port, int TypeIndex,
- const std::vector<int64_t> &Shape)
- : Name(Name), Port(Port), TypeIndex(TypeIndex), Shape(Shape),
- ElementCount(std::accumulate(Shape.begin(), Shape.end(), 1,
- std::multiplies<int64_t>())) {}
-
-Optional<TensorSpec> getTensorSpecFromJSON(LLVMContext &Ctx,
- const json::Value &Value) {
- auto EmitError = [&](const llvm::Twine &Message) -> Optional<TensorSpec> {
- std::string S;
- llvm::raw_string_ostream OS(S);
- OS << Value;
- Ctx.emitError("Unable to parse JSON Value as spec (" + Message + "): " + S);
- return None;
- };
- // FIXME: accept a Path as a parameter, and use it for error reporting.
- json::Path::Root Root("tensor_spec");
- json::ObjectMapper Mapper(Value, Root);
- if (!Mapper)
- return EmitError("Value is not a dict");
-
- std::string TensorName;
- int TensorPort = -1;
- std::string TensorType;
- std::vector<int64_t> TensorShape;
-
- if (!Mapper.map<std::string>("name", TensorName))
- return EmitError("'name' property not present or not a string");
- if (!Mapper.map<std::string>("type", TensorType))
- return EmitError("'type' property not present or not a string");
- if (!Mapper.map<int>("port", TensorPort))
- return EmitError("'port' property not present or not an int");
- if (!Mapper.map<std::vector<int64_t>>("shape", TensorShape))
- return EmitError("'shape' property not present or not an int array");
-
-#define PARSE_TYPE(T, E) \
- if (TensorType == #T) \
- return TensorSpec::createSpec<T>(TensorName, TensorShape, TensorPort);
- TFUTILS_SUPPORTED_TYPES(PARSE_TYPE)
-#undef PARSE_TYPE
- return None;
-}
-
-Optional<std::vector<LoggedFeatureSpec>>
-loadOutputSpecs(LLVMContext &Ctx, StringRef ExpectedDecisionName,
- StringRef ModelPath, StringRef SpecFileOverride) {
- SmallVector<char, 128> OutputSpecsPath;
- StringRef FileName = SpecFileOverride;
- if (FileName.empty()) {
- llvm::sys::path::append(OutputSpecsPath, ModelPath, "output_spec.json");
- FileName = {OutputSpecsPath.data(), OutputSpecsPath.size()};
- }
-
- auto BufferOrError = MemoryBuffer::getFileOrSTDIN(FileName);
- if (!BufferOrError) {
- Ctx.emitError("Error opening output specs file: " + FileName + " : " +
- BufferOrError.getError().message());
- return None;
- }
- auto ParsedJSONValues = json::parse(BufferOrError.get()->getBuffer());
- if (!ParsedJSONValues) {
- Ctx.emitError("Could not parse specs file: " + FileName);
- return None;
- }
- auto ValuesArray = ParsedJSONValues->getAsArray();
- if (!ValuesArray) {
- Ctx.emitError("Expected an array of {tensor_spec:<TensorSpec>, "
- "logging_name:<name>} dictionaries");
- return None;
- }
- std::vector<LoggedFeatureSpec> Ret;
- for (const auto &Value : *ValuesArray)
- if (const auto *Obj = Value.getAsObject())
- if (const auto *SpecPart = Obj->get("tensor_spec"))
- if (auto TensorSpec = getTensorSpecFromJSON(Ctx, *SpecPart))
- if (auto LoggingName = Obj->getString("logging_name")) {
- if (!TensorSpec->isElementType<int64_t>() &&
- !TensorSpec->isElementType<int32_t>() &&
- !TensorSpec->isElementType<float>()) {
- Ctx.emitError(
- "Only int64, int32, and float tensors are supported. "
- "Found unsupported type for tensor named " +
- TensorSpec->name());
- return None;
- }
- Ret.push_back({*TensorSpec, LoggingName->str()});
- }
-
- if (ValuesArray->size() != Ret.size()) {
- Ctx.emitError(
- "Unable to parse output spec. It should be a json file containing an "
- "array of dictionaries. Each dictionary must have a 'tensor_spec' key, "
- "with a json object describing a TensorSpec; and a 'logging_name' key, "
- "which is a string to use as name when logging this tensor in the "
- "training log.");
- return None;
- }
- if (Ret.empty() || *Ret[0].LoggingName != ExpectedDecisionName) {
- Ctx.emitError("The first output spec must describe the decision tensor, "
- "and must have the logging_name " +
- StringRef(ExpectedDecisionName));
- return None;
- }
- return Ret;
-}
-
+size_t TensorSpec::getElementByteSize() const {
+ return TF_DataTypeSize(static_cast<TF_DataType>(TypeIndex));
+}
+
+TensorSpec::TensorSpec(const std::string &Name, int Port, int TypeIndex,
+ const std::vector<int64_t> &Shape)
+ : Name(Name), Port(Port), TypeIndex(TypeIndex), Shape(Shape),
+ ElementCount(std::accumulate(Shape.begin(), Shape.end(), 1,
+ std::multiplies<int64_t>())) {}
+
+Optional<TensorSpec> getTensorSpecFromJSON(LLVMContext &Ctx,
+ const json::Value &Value) {
+ auto EmitError = [&](const llvm::Twine &Message) -> Optional<TensorSpec> {
+ std::string S;
+ llvm::raw_string_ostream OS(S);
+ OS << Value;
+ Ctx.emitError("Unable to parse JSON Value as spec (" + Message + "): " + S);
+ return None;
+ };
+ // FIXME: accept a Path as a parameter, and use it for error reporting.
+ json::Path::Root Root("tensor_spec");
+ json::ObjectMapper Mapper(Value, Root);
+ if (!Mapper)
+ return EmitError("Value is not a dict");
+
+ std::string TensorName;
+ int TensorPort = -1;
+ std::string TensorType;
+ std::vector<int64_t> TensorShape;
+
+ if (!Mapper.map<std::string>("name", TensorName))
+ return EmitError("'name' property not present or not a string");
+ if (!Mapper.map<std::string>("type", TensorType))
+ return EmitError("'type' property not present or not a string");
+ if (!Mapper.map<int>("port", TensorPort))
+ return EmitError("'port' property not present or not an int");
+ if (!Mapper.map<std::vector<int64_t>>("shape", TensorShape))
+ return EmitError("'shape' property not present or not an int array");
+
+#define PARSE_TYPE(T, E) \
+ if (TensorType == #T) \
+ return TensorSpec::createSpec<T>(TensorName, TensorShape, TensorPort);
+ TFUTILS_SUPPORTED_TYPES(PARSE_TYPE)
+#undef PARSE_TYPE
+ return None;
+}
+
+Optional<std::vector<LoggedFeatureSpec>>
+loadOutputSpecs(LLVMContext &Ctx, StringRef ExpectedDecisionName,
+ StringRef ModelPath, StringRef SpecFileOverride) {
+ SmallVector<char, 128> OutputSpecsPath;
+ StringRef FileName = SpecFileOverride;
+ if (FileName.empty()) {
+ llvm::sys::path::append(OutputSpecsPath, ModelPath, "output_spec.json");
+ FileName = {OutputSpecsPath.data(), OutputSpecsPath.size()};
+ }
+
+ auto BufferOrError = MemoryBuffer::getFileOrSTDIN(FileName);
+ if (!BufferOrError) {
+ Ctx.emitError("Error opening output specs file: " + FileName + " : " +
+ BufferOrError.getError().message());
+ return None;
+ }
+ auto ParsedJSONValues = json::parse(BufferOrError.get()->getBuffer());
+ if (!ParsedJSONValues) {
+ Ctx.emitError("Could not parse specs file: " + FileName);
+ return None;
+ }
+ auto ValuesArray = ParsedJSONValues->getAsArray();
+ if (!ValuesArray) {
+ Ctx.emitError("Expected an array of {tensor_spec:<TensorSpec>, "
+ "logging_name:<name>} dictionaries");
+ return None;
+ }
+ std::vector<LoggedFeatureSpec> Ret;
+ for (const auto &Value : *ValuesArray)
+ if (const auto *Obj = Value.getAsObject())
+ if (const auto *SpecPart = Obj->get("tensor_spec"))
+ if (auto TensorSpec = getTensorSpecFromJSON(Ctx, *SpecPart))
+ if (auto LoggingName = Obj->getString("logging_name")) {
+ if (!TensorSpec->isElementType<int64_t>() &&
+ !TensorSpec->isElementType<int32_t>() &&
+ !TensorSpec->isElementType<float>()) {
+ Ctx.emitError(
+ "Only int64, int32, and float tensors are supported. "
+ "Found unsupported type for tensor named " +
+ TensorSpec->name());
+ return None;
+ }
+ Ret.push_back({*TensorSpec, LoggingName->str()});
+ }
+
+ if (ValuesArray->size() != Ret.size()) {
+ Ctx.emitError(
+ "Unable to parse output spec. It should be a json file containing an "
+ "array of dictionaries. Each dictionary must have a 'tensor_spec' key, "
+ "with a json object describing a TensorSpec; and a 'logging_name' key, "
+ "which is a string to use as name when logging this tensor in the "
+ "training log.");
+ return None;
+ }
+ if (Ret.empty() || *Ret[0].LoggingName != ExpectedDecisionName) {
+ Ctx.emitError("The first output spec must describe the decision tensor, "
+ "and must have the logging_name " +
+ StringRef(ExpectedDecisionName));
+ return None;
+ }
+ return Ret;
+}
+
class TFModelEvaluatorImpl {
public:
TFModelEvaluatorImpl(StringRef SavedModelPath,
- const std::vector<TensorSpec> &InputSpecs,
- function_ref<TensorSpec(size_t)> GetOutputSpecs,
- size_t OutputSpecsSize, const char *Tags);
+ const std::vector<TensorSpec> &InputSpecs,
+ function_ref<TensorSpec(size_t)> GetOutputSpecs,
+ size_t OutputSpecsSize, const char *Tags);
bool isValid() const { return IsValid; }
size_t OutputSize() const { return OutputFeed.size(); }
@@ -329,18 +329,18 @@ private:
/// Reusable utility for ensuring we can bind the requested Name to a node in
/// the SavedModel Graph.
- bool checkReportAndInvalidate(const TF_Output &Output,
- const TensorSpec &OutputSpec);
+ bool checkReportAndInvalidate(const TF_Output &Output,
+ const TensorSpec &OutputSpec);
};
} // namespace llvm
TFModelEvaluatorImpl::TFModelEvaluatorImpl(
- StringRef SavedModelPath, const std::vector<TensorSpec> &InputSpecs,
- function_ref<TensorSpec(size_t)> GetOutputSpecs, size_t OutputSpecsSize,
- const char *Tags = "serve")
+ StringRef SavedModelPath, const std::vector<TensorSpec> &InputSpecs,
+ function_ref<TensorSpec(size_t)> GetOutputSpecs, size_t OutputSpecsSize,
+ const char *Tags = "serve")
: Graph(createTFGraph()), Options(createTFSessionOptions()),
- InputFeed(InputSpecs.size()), Input(InputSpecs.size()),
- OutputFeed(OutputSpecsSize) {
+ InputFeed(InputSpecs.size()), Input(InputSpecs.size()),
+ OutputFeed(OutputSpecsSize) {
if (!ensureInitTF()) {
errs() << "Tensorflow should have been initialized";
return;
@@ -354,44 +354,44 @@ TFModelEvaluatorImpl::TFModelEvaluatorImpl(
errs() << TF_Message(Status.get());
invalidate();
}
- for (size_t I = 0; I < InputSpecs.size(); ++I) {
- auto &InputSpec = InputSpecs[I];
+ for (size_t I = 0; I < InputSpecs.size(); ++I) {
+ auto &InputSpec = InputSpecs[I];
InputFeed[I] = {
- TF_GraphOperationByName(Graph.get(), (InputSpec.name()).c_str()),
- InputSpec.port()};
- if (!checkReportAndInvalidate(InputFeed[I], InputSpec))
+ TF_GraphOperationByName(Graph.get(), (InputSpec.name()).c_str()),
+ InputSpec.port()};
+ if (!checkReportAndInvalidate(InputFeed[I], InputSpec))
return;
- initInput(I, static_cast<TF_DataType>(InputSpec.typeIndex()),
- InputSpec.shape());
+ initInput(I, static_cast<TF_DataType>(InputSpec.typeIndex()),
+ InputSpec.shape());
}
- for (size_t I = 0; I < OutputSpecsSize; ++I) {
- auto OutputSpec = GetOutputSpecs(I);
+ for (size_t I = 0; I < OutputSpecsSize; ++I) {
+ auto OutputSpec = GetOutputSpecs(I);
OutputFeed[I] = {
- TF_GraphOperationByName(Graph.get(), (OutputSpec.name()).c_str()),
- OutputSpec.port()};
- if (!checkReportAndInvalidate(OutputFeed[I], OutputSpec))
+ TF_GraphOperationByName(Graph.get(), (OutputSpec.name()).c_str()),
+ OutputSpec.port()};
+ if (!checkReportAndInvalidate(OutputFeed[I], OutputSpec))
return;
}
}
-TFModelEvaluator::TFModelEvaluator(
- StringRef SavedModelPath, const std::vector<TensorSpec> &InputSpecs,
- function_ref<TensorSpec(size_t)> GetOutputSpecs, size_t OutputSpecsSize,
- const char *Tags)
- : Impl(new TFModelEvaluatorImpl(SavedModelPath, InputSpecs, GetOutputSpecs,
- OutputSpecsSize, Tags)) {
+TFModelEvaluator::TFModelEvaluator(
+ StringRef SavedModelPath, const std::vector<TensorSpec> &InputSpecs,
+ function_ref<TensorSpec(size_t)> GetOutputSpecs, size_t OutputSpecsSize,
+ const char *Tags)
+ : Impl(new TFModelEvaluatorImpl(SavedModelPath, InputSpecs, GetOutputSpecs,
+ OutputSpecsSize, Tags)) {
if (!Impl->isValid())
Impl.reset();
}
-TFModelEvaluator::TFModelEvaluator(StringRef SavedModelPath,
- const std::vector<TensorSpec> &InputSpecs,
- const std::vector<TensorSpec> &OutputSpecs,
- const char *Tags)
- : TFModelEvaluator(
- SavedModelPath, InputSpecs, [&](size_t I) { return OutputSpecs[I]; },
- OutputSpecs.size(), Tags) {}
-
+TFModelEvaluator::TFModelEvaluator(StringRef SavedModelPath,
+ const std::vector<TensorSpec> &InputSpecs,
+ const std::vector<TensorSpec> &OutputSpecs,
+ const char *Tags)
+ : TFModelEvaluator(
+ SavedModelPath, InputSpecs, [&](size_t I) { return OutputSpecs[I]; },
+ OutputSpecs.size(), Tags) {}
+
TFModelEvaluatorImpl::~TFModelEvaluatorImpl() {
for (auto *T : Input) {
TF_DeleteTensor(T);
@@ -405,11 +405,11 @@ TFModelEvaluatorImpl::~TFModelEvaluatorImpl() {
errs() << "Could not delete TF session";
}
-bool TFModelEvaluatorImpl::checkReportAndInvalidate(
- const TF_Output &Output, const TensorSpec &OutputSpec) {
+bool TFModelEvaluatorImpl::checkReportAndInvalidate(
+ const TF_Output &Output, const TensorSpec &OutputSpec) {
if (Output.oper)
return true;
- errs() << "Could not find TF_Output named: " + OutputSpec.name();
+ errs() << "Could not find TF_Output named: " + OutputSpec.name();
IsValid = false;
return IsValid;
}
@@ -451,55 +451,55 @@ TFModelEvaluator::EvaluationResult::EvaluationResult(
TFModelEvaluator::EvaluationResult::EvaluationResult(EvaluationResult &&Other)
: Impl(std::move(Other.Impl)) {}
-TFModelEvaluator::EvaluationResult &
-TFModelEvaluator::EvaluationResult::operator=(EvaluationResult &&Other) {
- Impl = std::move(Other.Impl);
- return *this;
-}
-
+TFModelEvaluator::EvaluationResult &
+TFModelEvaluator::EvaluationResult::operator=(EvaluationResult &&Other) {
+ Impl = std::move(Other.Impl);
+ return *this;
+}
+
void *TFModelEvaluator::EvaluationResult::getUntypedTensorValue(size_t Index) {
return TF_TensorData(Impl->getOutput()[Index]);
}
-const void *
-TFModelEvaluator::EvaluationResult::getUntypedTensorValue(size_t Index) const {
- return TF_TensorData(Impl->getOutput()[Index]);
+const void *
+TFModelEvaluator::EvaluationResult::getUntypedTensorValue(size_t Index) const {
+ return TF_TensorData(Impl->getOutput()[Index]);
}
-#define TFUTILS_GETDATATYPE_IMPL(T, E) \
- template <> int TensorSpec::getDataType<T>() { return E; }
-
-TFUTILS_SUPPORTED_TYPES(TFUTILS_GETDATATYPE_IMPL)
-
-#undef TFUTILS_GETDATATYPE_IMPL
-
-TFModelEvaluator::EvaluationResult::~EvaluationResult() {}
-TFModelEvaluator::~TFModelEvaluator() {}
-
-void Logger::print(raw_ostream &OS) {
- if (RawLogData.empty())
- return;
- if (RawLogData[0].empty())
- return;
- size_t Tensor0Size = FeatureSpecs[0].Spec.getElementCount() *
- FeatureSpecs[0].Spec.getElementByteSize();
- size_t NumberOfRecords = RawLogData[0].size() / Tensor0Size;
- if (NumberOfRecords == 0)
- return;
- size_t RewardSize =
- RewardSpec.getElementCount() * RewardSpec.getElementByteSize();
- size_t NumberOfRewards = RawLogData.back().size() / RewardSize;
-
- OS << "feature_lists: {\n";
- for (size_t I = 0; I < FeatureSpecs.size(); ++I)
- writeRawTensorsAsFeatureLists(OS, FeatureSpecs[I], RawLogData[I].data(),
- NumberOfRecords);
-
- if (IncludeReward)
- writeRawTensorsAsFeatureLists(OS, {RewardSpec, None},
- RawLogData.back().data(), NumberOfRecords,
- NumberOfRewards == 1);
-
- OS << "}\n";
+#define TFUTILS_GETDATATYPE_IMPL(T, E) \
+ template <> int TensorSpec::getDataType<T>() { return E; }
+
+TFUTILS_SUPPORTED_TYPES(TFUTILS_GETDATATYPE_IMPL)
+
+#undef TFUTILS_GETDATATYPE_IMPL
+
+TFModelEvaluator::EvaluationResult::~EvaluationResult() {}
+TFModelEvaluator::~TFModelEvaluator() {}
+
+void Logger::print(raw_ostream &OS) {
+ if (RawLogData.empty())
+ return;
+ if (RawLogData[0].empty())
+ return;
+ size_t Tensor0Size = FeatureSpecs[0].Spec.getElementCount() *
+ FeatureSpecs[0].Spec.getElementByteSize();
+ size_t NumberOfRecords = RawLogData[0].size() / Tensor0Size;
+ if (NumberOfRecords == 0)
+ return;
+ size_t RewardSize =
+ RewardSpec.getElementCount() * RewardSpec.getElementByteSize();
+ size_t NumberOfRewards = RawLogData.back().size() / RewardSize;
+
+ OS << "feature_lists: {\n";
+ for (size_t I = 0; I < FeatureSpecs.size(); ++I)
+ writeRawTensorsAsFeatureLists(OS, FeatureSpecs[I], RawLogData[I].data(),
+ NumberOfRecords);
+
+ if (IncludeReward)
+ writeRawTensorsAsFeatureLists(OS, {RewardSpec, None},
+ RawLogData.back().data(), NumberOfRecords,
+ NumberOfRewards == 1);
+
+ OS << "}\n";
}
-#endif // defined(LLVM_HAVE_TF_API)
+#endif // defined(LLVM_HAVE_TF_API)
diff --git a/contrib/libs/llvm12/lib/Analysis/TargetLibraryInfo.cpp b/contrib/libs/llvm12/lib/Analysis/TargetLibraryInfo.cpp
index 948672e294..a4de21a254 100644
--- a/contrib/libs/llvm12/lib/Analysis/TargetLibraryInfo.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/TargetLibraryInfo.cpp
@@ -24,8 +24,8 @@ static cl::opt<TargetLibraryInfoImpl::VectorLibrary> ClVectorLibrary(
"No vector functions library"),
clEnumValN(TargetLibraryInfoImpl::Accelerate, "Accelerate",
"Accelerate framework"),
- clEnumValN(TargetLibraryInfoImpl::LIBMVEC_X86, "LIBMVEC-X86",
- "GLIBC Vector Math library"),
+ clEnumValN(TargetLibraryInfoImpl::LIBMVEC_X86, "LIBMVEC-X86",
+ "GLIBC Vector Math library"),
clEnumValN(TargetLibraryInfoImpl::MASSV, "MASSV",
"IBM MASS vector library"),
clEnumValN(TargetLibraryInfoImpl::SVML, "SVML",
@@ -551,14 +551,14 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
TLI.setUnavailable(LibFunc_nvvm_reflect);
}
- // These vec_malloc/free routines are only available on AIX.
- if (!T.isOSAIX()) {
- TLI.setUnavailable(LibFunc_vec_calloc);
- TLI.setUnavailable(LibFunc_vec_malloc);
- TLI.setUnavailable(LibFunc_vec_realloc);
- TLI.setUnavailable(LibFunc_vec_free);
- }
-
+ // These vec_malloc/free routines are only available on AIX.
+ if (!T.isOSAIX()) {
+ TLI.setUnavailable(LibFunc_vec_calloc);
+ TLI.setUnavailable(LibFunc_vec_malloc);
+ TLI.setUnavailable(LibFunc_vec_realloc);
+ TLI.setUnavailable(LibFunc_vec_free);
+ }
+
TLI.addVectorizableFunctionsFromVecLib(ClVectorLibrary);
}
@@ -646,7 +646,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
const DataLayout *DL) const {
LLVMContext &Ctx = FTy.getContext();
Type *PCharTy = Type::getInt8PtrTy(Ctx);
- Type *SizeTTy = DL ? DL->getIntPtrType(Ctx, /*AddressSpace=*/0) : nullptr;
+ Type *SizeTTy = DL ? DL->getIntPtrType(Ctx, /*AddressSpace=*/0) : nullptr;
auto IsSizeTTy = [SizeTTy](Type *Ty) {
return SizeTTy ? Ty == SizeTTy : Ty->isIntegerTy();
};
@@ -839,7 +839,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
case LibFunc_system:
return (NumParams == 1 && FTy.getParamType(0)->isPointerTy());
case LibFunc_malloc:
- case LibFunc_vec_malloc:
+ case LibFunc_vec_malloc:
return (NumParams == 1 && FTy.getReturnType()->isPointerTy());
case LibFunc_memcmp:
return (NumParams == 3 && FTy.getReturnType()->isIntegerTy(32) &&
@@ -858,7 +858,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy());
case LibFunc_memcpy_chk:
- case LibFunc_mempcpy_chk:
+ case LibFunc_mempcpy_chk:
case LibFunc_memmove_chk:
--NumParams;
if (!IsSizeTTy(FTy.getParamType(NumParams)))
@@ -894,7 +894,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
return (FTy.getReturnType()->isPointerTy());
case LibFunc_realloc:
case LibFunc_reallocf:
- case LibFunc_vec_realloc:
+ case LibFunc_vec_realloc:
return (NumParams == 2 && FTy.getReturnType() == PCharTy &&
FTy.getParamType(0) == FTy.getReturnType() &&
IsSizeTTy(FTy.getParamType(1)));
@@ -922,7 +922,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
case LibFunc_bzero:
return (NumParams == 2 && FTy.getParamType(0)->isPointerTy());
case LibFunc_calloc:
- case LibFunc_vec_calloc:
+ case LibFunc_vec_calloc:
return (NumParams == 2 && FTy.getReturnType()->isPointerTy());
case LibFunc_atof:
@@ -973,7 +973,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
case LibFunc_mkdir:
case LibFunc_mktime:
case LibFunc_times:
- case LibFunc_vec_free:
+ case LibFunc_vec_free:
return (NumParams != 0 && FTy.getParamType(0)->isPointerTy());
case LibFunc_fopen:
@@ -1243,15 +1243,15 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
case LibFunc_ZdaPvmSt11align_val_t:
return (NumParams == 3 && FTy.getParamType(0)->isPointerTy());
- // void __atomic_load(size_t, void *, void *, int)
- case LibFunc_atomic_load:
- // void __atomic_store(size_t, void *, void *, int)
- case LibFunc_atomic_store:
- return (NumParams == 4 && FTy.getParamType(0)->isIntegerTy() &&
- FTy.getParamType(1)->isPointerTy() &&
- FTy.getParamType(2)->isPointerTy() &&
- FTy.getParamType(3)->isIntegerTy());
-
+ // void __atomic_load(size_t, void *, void *, int)
+ case LibFunc_atomic_load:
+ // void __atomic_store(size_t, void *, void *, int)
+ case LibFunc_atomic_store:
+ return (NumParams == 4 && FTy.getParamType(0)->isIntegerTy() &&
+ FTy.getParamType(1)->isPointerTy() &&
+ FTy.getParamType(2)->isPointerTy() &&
+ FTy.getParamType(3)->isIntegerTy());
+
case LibFunc_memset_pattern16:
return (!FTy.isVarArg() && NumParams == 3 &&
FTy.getParamType(0)->isPointerTy() &&
@@ -1555,10 +1555,10 @@ static bool compareWithVectorFnName(const VecDesc &LHS, StringRef S) {
}
void TargetLibraryInfoImpl::addVectorizableFunctions(ArrayRef<VecDesc> Fns) {
- llvm::append_range(VectorDescs, Fns);
+ llvm::append_range(VectorDescs, Fns);
llvm::sort(VectorDescs, compareByScalarFnName);
- llvm::append_range(ScalarDescs, Fns);
+ llvm::append_range(ScalarDescs, Fns);
llvm::sort(ScalarDescs, compareByVectorFnName);
}
@@ -1573,14 +1573,14 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib(
addVectorizableFunctions(VecFuncs);
break;
}
- case LIBMVEC_X86: {
- const VecDesc VecFuncs[] = {
- #define TLI_DEFINE_LIBMVEC_X86_VECFUNCS
- #include "llvm/Analysis/VecFuncs.def"
- };
- addVectorizableFunctions(VecFuncs);
- break;
- }
+ case LIBMVEC_X86: {
+ const VecDesc VecFuncs[] = {
+ #define TLI_DEFINE_LIBMVEC_X86_VECFUNCS
+ #include "llvm/Analysis/VecFuncs.def"
+ };
+ addVectorizableFunctions(VecFuncs);
+ break;
+ }
case MASSV: {
const VecDesc VecFuncs[] = {
#define TLI_DEFINE_MASSV_VECFUNCS
diff --git a/contrib/libs/llvm12/lib/Analysis/TargetTransformInfo.cpp b/contrib/libs/llvm12/lib/Analysis/TargetTransformInfo.cpp
index 44674433ae..e498401eb8 100644
--- a/contrib/libs/llvm12/lib/Analysis/TargetTransformInfo.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/TargetTransformInfo.cpp
@@ -71,7 +71,7 @@ IntrinsicCostAttributes::IntrinsicCostAttributes(Intrinsic::ID Id,
if (const auto *FPMO = dyn_cast<FPMathOperator>(&CI))
FMF = FPMO->getFastMathFlags();
- Arguments.insert(Arguments.begin(), CI.arg_begin(), CI.arg_end());
+ Arguments.insert(Arguments.begin(), CI.arg_begin(), CI.arg_end());
FunctionType *FTy =
CI.getCalledFunction()->getFunctionType();
ParamTys.insert(ParamTys.begin(), FTy->param_begin(), FTy->param_end());
@@ -79,10 +79,10 @@ IntrinsicCostAttributes::IntrinsicCostAttributes(Intrinsic::ID Id,
IntrinsicCostAttributes::IntrinsicCostAttributes(Intrinsic::ID Id,
const CallBase &CI,
- ElementCount Factor)
- : RetTy(CI.getType()), IID(Id), VF(Factor) {
+ ElementCount Factor)
+ : RetTy(CI.getType()), IID(Id), VF(Factor) {
- assert(!Factor.isScalable() && "Scalable vectors are not yet supported");
+ assert(!Factor.isScalable() && "Scalable vectors are not yet supported");
if (auto *FPMO = dyn_cast<FPMathOperator>(&CI))
FMF = FPMO->getFastMathFlags();
@@ -94,9 +94,9 @@ IntrinsicCostAttributes::IntrinsicCostAttributes(Intrinsic::ID Id,
IntrinsicCostAttributes::IntrinsicCostAttributes(Intrinsic::ID Id,
const CallBase &CI,
- ElementCount Factor,
- unsigned ScalarCost)
- : RetTy(CI.getType()), IID(Id), VF(Factor), ScalarizationCost(ScalarCost) {
+ ElementCount Factor,
+ unsigned ScalarCost)
+ : RetTy(CI.getType()), IID(Id), VF(Factor), ScalarizationCost(ScalarCost) {
if (const auto *FPMO = dyn_cast<FPMathOperator>(&CI))
FMF = FPMO->getFastMathFlags();
@@ -217,11 +217,11 @@ bool HardwareLoopInfo::isHardwareLoopCandidate(ScalarEvolution &SE,
// Note that this block may not be the loop latch block, even if the loop
// has a latch block.
ExitBlock = BB;
- TripCount = SE.getAddExpr(EC, SE.getOne(EC->getType()));
-
- if (!EC->getType()->isPointerTy() && EC->getType() != CountType)
- TripCount = SE.getZeroExtendExpr(TripCount, CountType);
-
+ TripCount = SE.getAddExpr(EC, SE.getOne(EC->getType()));
+
+ if (!EC->getType()->isPointerTy() && EC->getType() != CountType)
+ TripCount = SE.getZeroExtendExpr(TripCount, CountType);
+
break;
}
@@ -247,11 +247,11 @@ unsigned TargetTransformInfo::getInliningThresholdMultiplier() const {
return TTIImpl->getInliningThresholdMultiplier();
}
-unsigned
-TargetTransformInfo::adjustInliningThreshold(const CallBase *CB) const {
- return TTIImpl->adjustInliningThreshold(CB);
-}
-
+unsigned
+TargetTransformInfo::adjustInliningThreshold(const CallBase *CB) const {
+ return TTIImpl->adjustInliningThreshold(CB);
+}
+
int TargetTransformInfo::getInlinerVectorBonusPercent() const {
return TTIImpl->getInlinerVectorBonusPercent();
}
@@ -307,10 +307,10 @@ bool TargetTransformInfo::isNoopAddrSpaceCast(unsigned FromAS,
return TTIImpl->isNoopAddrSpaceCast(FromAS, ToAS);
}
-unsigned TargetTransformInfo::getAssumedAddrSpace(const Value *V) const {
- return TTIImpl->getAssumedAddrSpace(V);
-}
-
+unsigned TargetTransformInfo::getAssumedAddrSpace(const Value *V) const {
+ return TTIImpl->getAssumedAddrSpace(V);
+}
+
Value *TargetTransformInfo::rewriteIntrinsicWithAddressSpace(
IntrinsicInst *II, Value *OldV, Value *NewV) const {
return TTIImpl->rewriteIntrinsicWithAddressSpace(II, OldV, NewV);
@@ -337,29 +337,29 @@ bool TargetTransformInfo::emitGetActiveLaneMask() const {
return TTIImpl->emitGetActiveLaneMask();
}
-Optional<Instruction *>
-TargetTransformInfo::instCombineIntrinsic(InstCombiner &IC,
- IntrinsicInst &II) const {
- return TTIImpl->instCombineIntrinsic(IC, II);
-}
-
-Optional<Value *> TargetTransformInfo::simplifyDemandedUseBitsIntrinsic(
- InstCombiner &IC, IntrinsicInst &II, APInt DemandedMask, KnownBits &Known,
- bool &KnownBitsComputed) const {
- return TTIImpl->simplifyDemandedUseBitsIntrinsic(IC, II, DemandedMask, Known,
- KnownBitsComputed);
-}
-
-Optional<Value *> TargetTransformInfo::simplifyDemandedVectorEltsIntrinsic(
- InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
- APInt &UndefElts2, APInt &UndefElts3,
- std::function<void(Instruction *, unsigned, APInt, APInt &)>
- SimplifyAndSetOp) const {
- return TTIImpl->simplifyDemandedVectorEltsIntrinsic(
- IC, II, DemandedElts, UndefElts, UndefElts2, UndefElts3,
- SimplifyAndSetOp);
-}
-
+Optional<Instruction *>
+TargetTransformInfo::instCombineIntrinsic(InstCombiner &IC,
+ IntrinsicInst &II) const {
+ return TTIImpl->instCombineIntrinsic(IC, II);
+}
+
+Optional<Value *> TargetTransformInfo::simplifyDemandedUseBitsIntrinsic(
+ InstCombiner &IC, IntrinsicInst &II, APInt DemandedMask, KnownBits &Known,
+ bool &KnownBitsComputed) const {
+ return TTIImpl->simplifyDemandedUseBitsIntrinsic(IC, II, DemandedMask, Known,
+ KnownBitsComputed);
+}
+
+Optional<Value *> TargetTransformInfo::simplifyDemandedVectorEltsIntrinsic(
+ InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
+ APInt &UndefElts2, APInt &UndefElts3,
+ std::function<void(Instruction *, unsigned, APInt, APInt &)>
+ SimplifyAndSetOp) const {
+ return TTIImpl->simplifyDemandedVectorEltsIntrinsic(
+ IC, II, DemandedElts, UndefElts, UndefElts2, UndefElts3,
+ SimplifyAndSetOp);
+}
+
void TargetTransformInfo::getUnrollingPreferences(
Loop *L, ScalarEvolution &SE, UnrollingPreferences &UP) const {
return TTIImpl->getUnrollingPreferences(L, SE, UP);
@@ -391,10 +391,10 @@ bool TargetTransformInfo::isLSRCostLess(LSRCost &C1, LSRCost &C2) const {
return TTIImpl->isLSRCostLess(C1, C2);
}
-bool TargetTransformInfo::isNumRegsMajorCostOfLSR() const {
- return TTIImpl->isNumRegsMajorCostOfLSR();
-}
-
+bool TargetTransformInfo::isNumRegsMajorCostOfLSR() const {
+ return TTIImpl->isNumRegsMajorCostOfLSR();
+}
+
bool TargetTransformInfo::isProfitableLSRChainElement(Instruction *I) const {
return TTIImpl->isProfitableLSRChainElement(I);
}
@@ -496,10 +496,10 @@ bool TargetTransformInfo::isTypeLegal(Type *Ty) const {
return TTIImpl->isTypeLegal(Ty);
}
-unsigned TargetTransformInfo::getRegUsageForType(Type *Ty) const {
- return TTIImpl->getRegUsageForType(Ty);
-}
-
+unsigned TargetTransformInfo::getRegUsageForType(Type *Ty) const {
+ return TTIImpl->getRegUsageForType(Ty);
+}
+
bool TargetTransformInfo::shouldBuildLookupTables() const {
return TTIImpl->shouldBuildLookupTables();
}
@@ -593,11 +593,11 @@ int TargetTransformInfo::getIntImmCost(const APInt &Imm, Type *Ty,
return Cost;
}
-int TargetTransformInfo::getIntImmCostInst(unsigned Opcode, unsigned Idx,
- const APInt &Imm, Type *Ty,
- TTI::TargetCostKind CostKind,
- Instruction *Inst) const {
- int Cost = TTIImpl->getIntImmCostInst(Opcode, Idx, Imm, Ty, CostKind, Inst);
+int TargetTransformInfo::getIntImmCostInst(unsigned Opcode, unsigned Idx,
+ const APInt &Imm, Type *Ty,
+ TTI::TargetCostKind CostKind,
+ Instruction *Inst) const {
+ int Cost = TTIImpl->getIntImmCostInst(Opcode, Idx, Imm, Ty, CostKind, Inst);
assert(Cost >= 0 && "TTI should not produce negative costs!");
return Cost;
}
@@ -632,10 +632,10 @@ unsigned TargetTransformInfo::getMinVectorRegisterBitWidth() const {
return TTIImpl->getMinVectorRegisterBitWidth();
}
-Optional<unsigned> TargetTransformInfo::getMaxVScale() const {
- return TTIImpl->getMaxVScale();
-}
-
+Optional<unsigned> TargetTransformInfo::getMaxVScale() const {
+ return TTIImpl->getMaxVScale();
+}
+
bool TargetTransformInfo::shouldMaximizeVectorBandwidth(bool OptSize) const {
return TTIImpl->shouldMaximizeVectorBandwidth(OptSize);
}
@@ -644,11 +644,11 @@ unsigned TargetTransformInfo::getMinimumVF(unsigned ElemWidth) const {
return TTIImpl->getMinimumVF(ElemWidth);
}
-unsigned TargetTransformInfo::getMaximumVF(unsigned ElemWidth,
- unsigned Opcode) const {
- return TTIImpl->getMaximumVF(ElemWidth, Opcode);
-}
-
+unsigned TargetTransformInfo::getMaximumVF(unsigned ElemWidth,
+ unsigned Opcode) const {
+ return TTIImpl->getMaximumVF(ElemWidth, Opcode);
+}
+
bool TargetTransformInfo::shouldConsiderAddressTypePromotion(
const Instruction &I, bool &AllowPromotionWithoutCommonHeader) const {
return TTIImpl->shouldConsiderAddressTypePromotion(
@@ -762,57 +762,57 @@ int TargetTransformInfo::getShuffleCost(ShuffleKind Kind, VectorType *Ty,
return Cost;
}
-TTI::CastContextHint
-TargetTransformInfo::getCastContextHint(const Instruction *I) {
- if (!I)
- return CastContextHint::None;
-
- auto getLoadStoreKind = [](const Value *V, unsigned LdStOp, unsigned MaskedOp,
- unsigned GatScatOp) {
- const Instruction *I = dyn_cast<Instruction>(V);
- if (!I)
- return CastContextHint::None;
-
- if (I->getOpcode() == LdStOp)
- return CastContextHint::Normal;
-
- if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
- if (II->getIntrinsicID() == MaskedOp)
- return TTI::CastContextHint::Masked;
- if (II->getIntrinsicID() == GatScatOp)
- return TTI::CastContextHint::GatherScatter;
- }
-
- return TTI::CastContextHint::None;
- };
-
- switch (I->getOpcode()) {
- case Instruction::ZExt:
- case Instruction::SExt:
- case Instruction::FPExt:
- return getLoadStoreKind(I->getOperand(0), Instruction::Load,
- Intrinsic::masked_load, Intrinsic::masked_gather);
- case Instruction::Trunc:
- case Instruction::FPTrunc:
- if (I->hasOneUse())
- return getLoadStoreKind(*I->user_begin(), Instruction::Store,
- Intrinsic::masked_store,
- Intrinsic::masked_scatter);
- break;
- default:
- return CastContextHint::None;
- }
-
- return TTI::CastContextHint::None;
-}
-
+TTI::CastContextHint
+TargetTransformInfo::getCastContextHint(const Instruction *I) {
+ if (!I)
+ return CastContextHint::None;
+
+ auto getLoadStoreKind = [](const Value *V, unsigned LdStOp, unsigned MaskedOp,
+ unsigned GatScatOp) {
+ const Instruction *I = dyn_cast<Instruction>(V);
+ if (!I)
+ return CastContextHint::None;
+
+ if (I->getOpcode() == LdStOp)
+ return CastContextHint::Normal;
+
+ if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
+ if (II->getIntrinsicID() == MaskedOp)
+ return TTI::CastContextHint::Masked;
+ if (II->getIntrinsicID() == GatScatOp)
+ return TTI::CastContextHint::GatherScatter;
+ }
+
+ return TTI::CastContextHint::None;
+ };
+
+ switch (I->getOpcode()) {
+ case Instruction::ZExt:
+ case Instruction::SExt:
+ case Instruction::FPExt:
+ return getLoadStoreKind(I->getOperand(0), Instruction::Load,
+ Intrinsic::masked_load, Intrinsic::masked_gather);
+ case Instruction::Trunc:
+ case Instruction::FPTrunc:
+ if (I->hasOneUse())
+ return getLoadStoreKind(*I->user_begin(), Instruction::Store,
+ Intrinsic::masked_store,
+ Intrinsic::masked_scatter);
+ break;
+ default:
+ return CastContextHint::None;
+ }
+
+ return TTI::CastContextHint::None;
+}
+
int TargetTransformInfo::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
- CastContextHint CCH,
+ CastContextHint CCH,
TTI::TargetCostKind CostKind,
const Instruction *I) const {
assert((I == nullptr || I->getOpcode() == Opcode) &&
"Opcode should reflect passed instruction.");
- int Cost = TTIImpl->getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
+ int Cost = TTIImpl->getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
assert(Cost >= 0 && "TTI should not produce negative costs!");
return Cost;
}
@@ -834,13 +834,13 @@ int TargetTransformInfo::getCFInstrCost(unsigned Opcode,
int TargetTransformInfo::getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
Type *CondTy,
- CmpInst::Predicate VecPred,
+ CmpInst::Predicate VecPred,
TTI::TargetCostKind CostKind,
const Instruction *I) const {
assert((I == nullptr || I->getOpcode() == Opcode) &&
"Opcode should reflect passed instruction.");
- int Cost =
- TTIImpl->getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind, I);
+ int Cost =
+ TTIImpl->getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind, I);
assert(Cost >= 0 && "TTI should not produce negative costs!");
return Cost;
}
@@ -948,13 +948,13 @@ int TargetTransformInfo::getMinMaxReductionCost(
return Cost;
}
-InstructionCost TargetTransformInfo::getExtendedAddReductionCost(
- bool IsMLA, bool IsUnsigned, Type *ResTy, VectorType *Ty,
- TTI::TargetCostKind CostKind) const {
- return TTIImpl->getExtendedAddReductionCost(IsMLA, IsUnsigned, ResTy, Ty,
- CostKind);
-}
-
+InstructionCost TargetTransformInfo::getExtendedAddReductionCost(
+ bool IsMLA, bool IsUnsigned, Type *ResTy, VectorType *Ty,
+ TTI::TargetCostKind CostKind) const {
+ return TTIImpl->getExtendedAddReductionCost(IsMLA, IsUnsigned, ResTy, Ty,
+ CostKind);
+}
+
unsigned
TargetTransformInfo::getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) const {
return TTIImpl->getCostOfKeepingLiveOverCall(Tys);
@@ -1054,16 +1054,16 @@ bool TargetTransformInfo::useReductionIntrinsic(unsigned Opcode, Type *Ty,
return TTIImpl->useReductionIntrinsic(Opcode, Ty, Flags);
}
-bool TargetTransformInfo::preferInLoopReduction(unsigned Opcode, Type *Ty,
- ReductionFlags Flags) const {
- return TTIImpl->preferInLoopReduction(Opcode, Ty, Flags);
-}
-
-bool TargetTransformInfo::preferPredicatedReductionSelect(
- unsigned Opcode, Type *Ty, ReductionFlags Flags) const {
- return TTIImpl->preferPredicatedReductionSelect(Opcode, Ty, Flags);
-}
-
+bool TargetTransformInfo::preferInLoopReduction(unsigned Opcode, Type *Ty,
+ ReductionFlags Flags) const {
+ return TTIImpl->preferInLoopReduction(Opcode, Ty, Flags);
+}
+
+bool TargetTransformInfo::preferPredicatedReductionSelect(
+ unsigned Opcode, Type *Ty, ReductionFlags Flags) const {
+ return TTIImpl->preferPredicatedReductionSelect(Opcode, Ty, Flags);
+}
+
bool TargetTransformInfo::shouldExpandReduction(const IntrinsicInst *II) const {
return TTIImpl->shouldExpandReduction(II);
}
@@ -1072,10 +1072,10 @@ unsigned TargetTransformInfo::getGISelRematGlobalCost() const {
return TTIImpl->getGISelRematGlobalCost();
}
-bool TargetTransformInfo::supportsScalableVectors() const {
- return TTIImpl->supportsScalableVectors();
-}
-
+bool TargetTransformInfo::supportsScalableVectors() const {
+ return TTIImpl->supportsScalableVectors();
+}
+
int TargetTransformInfo::getInstructionLatency(const Instruction *I) const {
return TTIImpl->getInstructionLatency(I);
}
@@ -1089,8 +1089,8 @@ static bool matchPairwiseShuffleMask(ShuffleVectorInst *SI, bool IsLeft,
else if (!SI)
return false;
- SmallVector<int, 32> Mask(
- cast<FixedVectorType>(SI->getType())->getNumElements(), -1);
+ SmallVector<int, 32> Mask(
+ cast<FixedVectorType>(SI->getType())->getNumElements(), -1);
// Build a mask of 0, 2, ... (left) or 1, 3, ... (right) depending on whether
// we look at the left or right side.
@@ -1229,7 +1229,7 @@ TTI::ReductionKind TTI::matchPairwiseReduction(
if (!RD)
return TTI::RK_None;
- auto *VecTy = cast<FixedVectorType>(RdxStart->getType());
+ auto *VecTy = cast<FixedVectorType>(RdxStart->getType());
unsigned NumVecElems = VecTy->getNumElements();
if (!isPowerOf2_32(NumVecElems))
return TTI::RK_None;
@@ -1294,7 +1294,7 @@ TTI::ReductionKind TTI::matchVectorSplittingReduction(
if (!RD)
return TTI::RK_None;
- auto *VecTy = cast<FixedVectorType>(ReduxRoot->getOperand(0)->getType());
+ auto *VecTy = cast<FixedVectorType>(ReduxRoot->getOperand(0)->getType());
unsigned NumVecElems = VecTy->getNumElements();
if (!isPowerOf2_32(NumVecElems))
return TTI::RK_None;
@@ -1353,18 +1353,18 @@ TTI::ReductionKind TTI::matchVectorSplittingReduction(
return RD->Kind;
}
-TTI::ReductionKind
-TTI::matchVectorReduction(const ExtractElementInst *Root, unsigned &Opcode,
- VectorType *&Ty, bool &IsPairwise) {
- TTI::ReductionKind RdxKind = matchVectorSplittingReduction(Root, Opcode, Ty);
- if (RdxKind != TTI::ReductionKind::RK_None) {
- IsPairwise = false;
- return RdxKind;
- }
- IsPairwise = true;
- return matchPairwiseReduction(Root, Opcode, Ty);
-}
-
+TTI::ReductionKind
+TTI::matchVectorReduction(const ExtractElementInst *Root, unsigned &Opcode,
+ VectorType *&Ty, bool &IsPairwise) {
+ TTI::ReductionKind RdxKind = matchVectorSplittingReduction(Root, Opcode, Ty);
+ if (RdxKind != TTI::ReductionKind::RK_None) {
+ IsPairwise = false;
+ return RdxKind;
+ }
+ IsPairwise = true;
+ return matchPairwiseReduction(Root, Opcode, Ty);
+}
+
int TargetTransformInfo::getInstructionThroughput(const Instruction *I) const {
TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput;
diff --git a/contrib/libs/llvm12/lib/Analysis/TypeBasedAliasAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/TypeBasedAliasAnalysis.cpp
index 2b9a142cb1..268acb682c 100644
--- a/contrib/libs/llvm12/lib/Analysis/TypeBasedAliasAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/TypeBasedAliasAnalysis.cpp
@@ -111,7 +111,7 @@
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
@@ -737,84 +737,84 @@ bool TypeBasedAAWrapperPass::doFinalization(Module &M) {
void TypeBasedAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}
-
-MDNode *AAMDNodes::ShiftTBAA(MDNode *MD, size_t Offset) {
- // Fast path if there's no offset
- if (Offset == 0)
- return MD;
- // Fast path if there's no path tbaa node (and thus scalar)
- if (!isStructPathTBAA(MD))
- return MD;
-
- TBAAStructTagNode Tag(MD);
- SmallVector<Metadata *, 5> Sub;
- Sub.push_back(MD->getOperand(0));
- Sub.push_back(MD->getOperand(1));
- ConstantInt *InnerOffset = mdconst::extract<ConstantInt>(MD->getOperand(2));
-
- if (Tag.isNewFormat()) {
- ConstantInt *InnerSize = mdconst::extract<ConstantInt>(MD->getOperand(3));
-
- if (InnerOffset->getZExtValue() + InnerSize->getZExtValue() <= Offset) {
- return nullptr;
- }
-
- uint64_t NewSize = InnerSize->getZExtValue();
- uint64_t NewOffset = InnerOffset->getZExtValue() - Offset;
- if (InnerOffset->getZExtValue() < Offset) {
- NewOffset = 0;
- NewSize -= Offset - InnerOffset->getZExtValue();
- }
-
- Sub.push_back(ConstantAsMetadata::get(
- ConstantInt::get(InnerOffset->getType(), NewOffset)));
-
- Sub.push_back(ConstantAsMetadata::get(
- ConstantInt::get(InnerSize->getType(), NewSize)));
-
- // immutable type
- if (MD->getNumOperands() >= 5)
- Sub.push_back(MD->getOperand(4));
- } else {
- if (InnerOffset->getZExtValue() < Offset)
- return nullptr;
-
- Sub.push_back(ConstantAsMetadata::get(ConstantInt::get(
- InnerOffset->getType(), InnerOffset->getZExtValue() - Offset)));
-
- // immutable type
- if (MD->getNumOperands() >= 4)
- Sub.push_back(MD->getOperand(3));
- }
- return MDNode::get(MD->getContext(), Sub);
-}
-
-MDNode *AAMDNodes::ShiftTBAAStruct(MDNode *MD, size_t Offset) {
- // Fast path if there's no offset
- if (Offset == 0)
- return MD;
- SmallVector<Metadata *, 3> Sub;
- for (size_t i = 0, size = MD->getNumOperands(); i < size; i += 3) {
- ConstantInt *InnerOffset = mdconst::extract<ConstantInt>(MD->getOperand(i));
- ConstantInt *InnerSize =
- mdconst::extract<ConstantInt>(MD->getOperand(i + 1));
- // Don't include any triples that aren't in bounds
- if (InnerOffset->getZExtValue() + InnerSize->getZExtValue() <= Offset)
- continue;
-
- uint64_t NewSize = InnerSize->getZExtValue();
- uint64_t NewOffset = InnerOffset->getZExtValue() - Offset;
- if (InnerOffset->getZExtValue() < Offset) {
- NewOffset = 0;
- NewSize -= Offset - InnerOffset->getZExtValue();
- }
-
- // Shift the offset of the triple
- Sub.push_back(ConstantAsMetadata::get(
- ConstantInt::get(InnerOffset->getType(), NewOffset)));
- Sub.push_back(ConstantAsMetadata::get(
- ConstantInt::get(InnerSize->getType(), NewSize)));
- Sub.push_back(MD->getOperand(i + 2));
- }
- return MDNode::get(MD->getContext(), Sub);
-} \ No newline at end of file
+
+MDNode *AAMDNodes::ShiftTBAA(MDNode *MD, size_t Offset) {
+ // Fast path if there's no offset
+ if (Offset == 0)
+ return MD;
+ // Fast path if there's no path tbaa node (and thus scalar)
+ if (!isStructPathTBAA(MD))
+ return MD;
+
+ TBAAStructTagNode Tag(MD);
+ SmallVector<Metadata *, 5> Sub;
+ Sub.push_back(MD->getOperand(0));
+ Sub.push_back(MD->getOperand(1));
+ ConstantInt *InnerOffset = mdconst::extract<ConstantInt>(MD->getOperand(2));
+
+ if (Tag.isNewFormat()) {
+ ConstantInt *InnerSize = mdconst::extract<ConstantInt>(MD->getOperand(3));
+
+ if (InnerOffset->getZExtValue() + InnerSize->getZExtValue() <= Offset) {
+ return nullptr;
+ }
+
+ uint64_t NewSize = InnerSize->getZExtValue();
+ uint64_t NewOffset = InnerOffset->getZExtValue() - Offset;
+ if (InnerOffset->getZExtValue() < Offset) {
+ NewOffset = 0;
+ NewSize -= Offset - InnerOffset->getZExtValue();
+ }
+
+ Sub.push_back(ConstantAsMetadata::get(
+ ConstantInt::get(InnerOffset->getType(), NewOffset)));
+
+ Sub.push_back(ConstantAsMetadata::get(
+ ConstantInt::get(InnerSize->getType(), NewSize)));
+
+ // immutable type
+ if (MD->getNumOperands() >= 5)
+ Sub.push_back(MD->getOperand(4));
+ } else {
+ if (InnerOffset->getZExtValue() < Offset)
+ return nullptr;
+
+ Sub.push_back(ConstantAsMetadata::get(ConstantInt::get(
+ InnerOffset->getType(), InnerOffset->getZExtValue() - Offset)));
+
+ // immutable type
+ if (MD->getNumOperands() >= 4)
+ Sub.push_back(MD->getOperand(3));
+ }
+ return MDNode::get(MD->getContext(), Sub);
+}
+
+MDNode *AAMDNodes::ShiftTBAAStruct(MDNode *MD, size_t Offset) {
+ // Fast path if there's no offset
+ if (Offset == 0)
+ return MD;
+ SmallVector<Metadata *, 3> Sub;
+ for (size_t i = 0, size = MD->getNumOperands(); i < size; i += 3) {
+ ConstantInt *InnerOffset = mdconst::extract<ConstantInt>(MD->getOperand(i));
+ ConstantInt *InnerSize =
+ mdconst::extract<ConstantInt>(MD->getOperand(i + 1));
+ // Don't include any triples that aren't in bounds
+ if (InnerOffset->getZExtValue() + InnerSize->getZExtValue() <= Offset)
+ continue;
+
+ uint64_t NewSize = InnerSize->getZExtValue();
+ uint64_t NewOffset = InnerOffset->getZExtValue() - Offset;
+ if (InnerOffset->getZExtValue() < Offset) {
+ NewOffset = 0;
+ NewSize -= Offset - InnerOffset->getZExtValue();
+ }
+
+ // Shift the offset of the triple
+ Sub.push_back(ConstantAsMetadata::get(
+ ConstantInt::get(InnerOffset->getType(), NewOffset)));
+ Sub.push_back(ConstantAsMetadata::get(
+ ConstantInt::get(InnerSize->getType(), NewSize)));
+ Sub.push_back(MD->getOperand(i + 2));
+ }
+ return MDNode::get(MD->getContext(), Sub);
+} \ No newline at end of file
diff --git a/contrib/libs/llvm12/lib/Analysis/VFABIDemangling.cpp b/contrib/libs/llvm12/lib/Analysis/VFABIDemangling.cpp
index 6bda7fe220..faa46537ad 100644
--- a/contrib/libs/llvm12/lib/Analysis/VFABIDemangling.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/VFABIDemangling.cpp
@@ -290,9 +290,9 @@ bool verifyAllVectorsHaveSameWidth(FunctionType *Signature) {
assert(VecTys.size() > 1 && "Invalid number of elements.");
const ElementCount EC = VecTys[0]->getElementCount();
- return llvm::all_of(llvm::drop_begin(VecTys), [&EC](VectorType *VTy) {
- return (EC == VTy->getElementCount());
- });
+ return llvm::all_of(llvm::drop_begin(VecTys), [&EC](VectorType *VTy) {
+ return (EC == VTy->getElementCount());
+ });
}
#endif // NDEBUG
@@ -310,7 +310,7 @@ ElementCount getECFromSignature(FunctionType *Signature) {
if (auto *VTy = dyn_cast<VectorType>(Ty))
return VTy->getElementCount();
- return ElementCount::getFixed(/*Min=*/1);
+ return ElementCount::getFixed(/*Min=*/1);
}
} // namespace
@@ -442,7 +442,7 @@ Optional<VFInfo> VFABI::tryDemangleForVFABI(StringRef MangledName,
if (!F)
return None;
const ElementCount EC = getECFromSignature(F->getFunctionType());
- VF = EC.getKnownMinValue();
+ VF = EC.getKnownMinValue();
}
// Sanity checks.
diff --git a/contrib/libs/llvm12/lib/Analysis/ValueTracking.cpp b/contrib/libs/llvm12/lib/Analysis/ValueTracking.cpp
index edcedc35d3..75486d3c80 100644
--- a/contrib/libs/llvm12/lib/Analysis/ValueTracking.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/ValueTracking.cpp
@@ -115,7 +115,7 @@ struct Query {
/// bits in x, etc. Regarding the mutual recursion, computeKnownBits can call
/// isKnownNonZero, which calls computeKnownBits and isKnownToBeAPowerOfTwo
/// (all of which can call computeKnownBits), and so on.
- std::array<const Value *, MaxAnalysisRecursionDepth> Excluded;
+ std::array<const Value *, MaxAnalysisRecursionDepth> Excluded;
/// If true, it is safe to use metadata during simplification.
InstrInfoQuery IIQ;
@@ -170,8 +170,8 @@ static bool getShuffleDemandedElts(const ShuffleVectorInst *Shuf,
return false;
int NumElts =
- cast<FixedVectorType>(Shuf->getOperand(0)->getType())->getNumElements();
- int NumMaskElts = cast<FixedVectorType>(Shuf->getType())->getNumElements();
+ cast<FixedVectorType>(Shuf->getOperand(0)->getType())->getNumElements();
+ int NumMaskElts = cast<FixedVectorType>(Shuf->getType())->getNumElements();
DemandedLHS = DemandedRHS = APInt::getNullValue(NumElts);
if (DemandedElts.isNullValue())
return true;
@@ -350,14 +350,14 @@ bool llvm::isKnownNegative(const Value *V, const DataLayout &DL, unsigned Depth,
return Known.isNegative();
}
-static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
- const Query &Q);
+static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
+ const Query &Q);
bool llvm::isKnownNonEqual(const Value *V1, const Value *V2,
const DataLayout &DL, AssumptionCache *AC,
const Instruction *CxtI, const DominatorTree *DT,
bool UseInstrInfo) {
- return ::isKnownNonEqual(V1, V2, 0,
+ return ::isKnownNonEqual(V1, V2, 0,
Query(DL, AC, safeCxtI(V1, safeCxtI(V2, CxtI)), DT,
UseInstrInfo, /*ORE=*/nullptr));
}
@@ -433,18 +433,18 @@ static void computeKnownBitsMul(const Value *Op0, const Value *Op1, bool NSW,
bool isKnownNegativeOp0 = Known2.isNegative();
// The product of two numbers with the same sign is non-negative.
isKnownNonNegative = (isKnownNegativeOp1 && isKnownNegativeOp0) ||
- (isKnownNonNegativeOp1 && isKnownNonNegativeOp0);
+ (isKnownNonNegativeOp1 && isKnownNonNegativeOp0);
// The product of a negative number and a non-negative number is either
// negative or zero.
if (!isKnownNonNegative)
- isKnownNegative =
- (isKnownNegativeOp1 && isKnownNonNegativeOp0 &&
- Known2.isNonZero()) ||
- (isKnownNegativeOp0 && isKnownNonNegativeOp1 && Known.isNonZero());
+ isKnownNegative =
+ (isKnownNegativeOp1 && isKnownNonNegativeOp0 &&
+ Known2.isNonZero()) ||
+ (isKnownNegativeOp0 && isKnownNonNegativeOp1 && Known.isNonZero());
}
}
- Known = KnownBits::computeForMul(Known, Known2);
+ Known = KnownBits::computeForMul(Known, Known2);
// Only make use of no-wrap flags if we failed to compute the sign bit
// directly. This matters if the multiplication always overflows, in
@@ -477,9 +477,9 @@ void llvm::computeKnownBitsFromRangeMetadata(const MDNode &Ranges,
unsigned CommonPrefixBits =
(Range.getUnsignedMax() ^ Range.getUnsignedMin()).countLeadingZeros();
APInt Mask = APInt::getHighBitsSet(BitWidth, CommonPrefixBits);
- APInt UnsignedMax = Range.getUnsignedMax().zextOrTrunc(BitWidth);
- Known.One &= UnsignedMax & Mask;
- Known.Zero &= ~UnsignedMax & Mask;
+ APInt UnsignedMax = Range.getUnsignedMax().zextOrTrunc(BitWidth);
+ Known.One &= UnsignedMax & Mask;
+ Known.Zero &= ~UnsignedMax & Mask;
}
}
@@ -509,7 +509,7 @@ static bool isEphemeralValueOf(const Instruction *I, const Value *E) {
if (V == I || isSafeToSpeculativelyExecute(V)) {
EphValues.insert(V);
if (const User *U = dyn_cast<User>(V))
- append_range(WorkSet, U->operands());
+ append_range(WorkSet, U->operands());
}
}
}
@@ -526,7 +526,7 @@ bool llvm::isAssumeLikeIntrinsic(const Instruction *I) {
// FIXME: This list is repeated from NoTTI::getIntrinsicCost.
case Intrinsic::assume:
case Intrinsic::sideeffect:
- case Intrinsic::pseudoprobe:
+ case Intrinsic::pseudoprobe:
case Intrinsic::dbg_declare:
case Intrinsic::dbg_value:
case Intrinsic::dbg_label:
@@ -534,7 +534,7 @@ bool llvm::isAssumeLikeIntrinsic(const Instruction *I) {
case Intrinsic::invariant_end:
case Intrinsic::lifetime_start:
case Intrinsic::lifetime_end:
- case Intrinsic::experimental_noalias_scope_decl:
+ case Intrinsic::experimental_noalias_scope_decl:
case Intrinsic::objectsize:
case Intrinsic::ptr_annotation:
case Intrinsic::var_annotation:
@@ -589,24 +589,24 @@ bool llvm::isValidAssumeForContext(const Instruction *Inv,
return false;
}
-static bool cmpExcludesZero(CmpInst::Predicate Pred, const Value *RHS) {
- // v u> y implies v != 0.
- if (Pred == ICmpInst::ICMP_UGT)
- return true;
-
- // Special-case v != 0 to also handle v != null.
- if (Pred == ICmpInst::ICMP_NE)
- return match(RHS, m_Zero());
-
- // All other predicates - rely on generic ConstantRange handling.
- const APInt *C;
- if (!match(RHS, m_APInt(C)))
- return false;
-
- ConstantRange TrueValues = ConstantRange::makeExactICmpRegion(Pred, *C);
- return !TrueValues.contains(APInt::getNullValue(C->getBitWidth()));
-}
-
+static bool cmpExcludesZero(CmpInst::Predicate Pred, const Value *RHS) {
+ // v u> y implies v != 0.
+ if (Pred == ICmpInst::ICMP_UGT)
+ return true;
+
+ // Special-case v != 0 to also handle v != null.
+ if (Pred == ICmpInst::ICMP_NE)
+ return match(RHS, m_Zero());
+
+ // All other predicates - rely on generic ConstantRange handling.
+ const APInt *C;
+ if (!match(RHS, m_APInt(C)))
+ return false;
+
+ ConstantRange TrueValues = ConstantRange::makeExactICmpRegion(Pred, *C);
+ return !TrueValues.contains(APInt::getNullValue(C->getBitWidth()));
+}
+
static bool isKnownNonZeroFromAssume(const Value *V, const Query &Q) {
// Use of assumptions is context-sensitive. If we don't have a context, we
// cannot use them!
@@ -639,13 +639,13 @@ static bool isKnownNonZeroFromAssume(const Value *V, const Query &Q) {
assert(I->getCalledFunction()->getIntrinsicID() == Intrinsic::assume &&
"must be an assume intrinsic");
- Value *RHS;
- CmpInst::Predicate Pred;
- auto m_V = m_CombineOr(m_Specific(V), m_PtrToInt(m_Specific(V)));
- if (!match(I->getArgOperand(0), m_c_ICmp(Pred, m_V, m_Value(RHS))))
- return false;
+ Value *RHS;
+ CmpInst::Predicate Pred;
+ auto m_V = m_CombineOr(m_Specific(V), m_PtrToInt(m_Specific(V)));
+ if (!match(I->getArgOperand(0), m_c_ICmp(Pred, m_V, m_Value(RHS))))
+ return false;
- if (cmpExcludesZero(Pred, RHS) && isValidAssumeForContext(I, Q.CxtI, Q.DT))
+ if (cmpExcludesZero(Pred, RHS) && isValidAssumeForContext(I, Q.CxtI, Q.DT))
return true;
}
@@ -661,14 +661,14 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known,
unsigned BitWidth = Known.getBitWidth();
- // Refine Known set if the pointer alignment is set by assume bundles.
- if (V->getType()->isPointerTy()) {
- if (RetainedKnowledge RK = getKnowledgeValidInContext(
- V, {Attribute::Alignment}, Q.CxtI, Q.DT, Q.AC)) {
- Known.Zero.setLowBits(Log2_32(RK.ArgValue));
- }
- }
-
+ // Refine Known set if the pointer alignment is set by assume bundles.
+ if (V->getType()->isPointerTy()) {
+ if (RetainedKnowledge RK = getKnowledgeValidInContext(
+ V, {Attribute::Alignment}, Q.CxtI, Q.DT, Q.AC)) {
+ Known.Zero.setLowBits(Log2_32(RK.ArgValue));
+ }
+ }
+
// Note that the patterns below need to be kept in sync with the code
// in AssumptionCache::updateAffectedValues.
@@ -703,7 +703,7 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known,
}
// The remaining tests are all recursive, so bail out if we hit the limit.
- if (Depth == MaxAnalysisRecursionDepth)
+ if (Depth == MaxAnalysisRecursionDepth)
continue;
ICmpInst *Cmp = dyn_cast<ICmpInst>(Arg);
@@ -969,31 +969,31 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known,
/// Compute known bits from a shift operator, including those with a
/// non-constant shift amount. Known is the output of this function. Known2 is a
-/// pre-allocated temporary with the same bit width as Known and on return
-/// contains the known bit of the shift value source. KF is an
-/// operator-specific function that, given the known-bits and a shift amount,
-/// compute the implied known-bits of the shift operator's result respectively
-/// for that shift amount. The results from calling KF are conservatively
-/// combined for all permitted shift amounts.
+/// pre-allocated temporary with the same bit width as Known and on return
+/// contains the known bit of the shift value source. KF is an
+/// operator-specific function that, given the known-bits and a shift amount,
+/// compute the implied known-bits of the shift operator's result respectively
+/// for that shift amount. The results from calling KF are conservatively
+/// combined for all permitted shift amounts.
static void computeKnownBitsFromShiftOperator(
const Operator *I, const APInt &DemandedElts, KnownBits &Known,
KnownBits &Known2, unsigned Depth, const Query &Q,
- function_ref<KnownBits(const KnownBits &, const KnownBits &)> KF) {
+ function_ref<KnownBits(const KnownBits &, const KnownBits &)> KF) {
unsigned BitWidth = Known.getBitWidth();
- computeKnownBits(I->getOperand(0), DemandedElts, Known2, Depth + 1, Q);
+ computeKnownBits(I->getOperand(0), DemandedElts, Known2, Depth + 1, Q);
computeKnownBits(I->getOperand(1), DemandedElts, Known, Depth + 1, Q);
- // Note: We cannot use Known.Zero.getLimitedValue() here, because if
- // BitWidth > 64 and any upper bits are known, we'll end up returning the
- // limit value (which implies all bits are known).
- uint64_t ShiftAmtKZ = Known.Zero.zextOrTrunc(64).getZExtValue();
- uint64_t ShiftAmtKO = Known.One.zextOrTrunc(64).getZExtValue();
- bool ShiftAmtIsConstant = Known.isConstant();
- bool MaxShiftAmtIsOutOfRange = Known.getMaxValue().uge(BitWidth);
-
- if (ShiftAmtIsConstant) {
- Known = KF(Known2, Known);
-
+ // Note: We cannot use Known.Zero.getLimitedValue() here, because if
+ // BitWidth > 64 and any upper bits are known, we'll end up returning the
+ // limit value (which implies all bits are known).
+ uint64_t ShiftAmtKZ = Known.Zero.zextOrTrunc(64).getZExtValue();
+ uint64_t ShiftAmtKO = Known.One.zextOrTrunc(64).getZExtValue();
+ bool ShiftAmtIsConstant = Known.isConstant();
+ bool MaxShiftAmtIsOutOfRange = Known.getMaxValue().uge(BitWidth);
+
+ if (ShiftAmtIsConstant) {
+ Known = KF(Known2, Known);
+
// If the known bits conflict, this must be an overflowing left shift, so
// the shift result is poison. We can return anything we want. Choose 0 for
// the best folding opportunity.
@@ -1007,7 +1007,7 @@ static void computeKnownBitsFromShiftOperator(
// LHS, the value could be poison, but bail out because the check below is
// expensive.
// TODO: Should we just carry on?
- if (MaxShiftAmtIsOutOfRange) {
+ if (MaxShiftAmtIsOutOfRange) {
Known.resetAll();
return;
}
@@ -1050,8 +1050,8 @@ static void computeKnownBitsFromShiftOperator(
continue;
}
- Known = KnownBits::commonBits(
- Known, KF(Known2, KnownBits::makeConstant(APInt(32, ShiftAmt))));
+ Known = KnownBits::commonBits(
+ Known, KF(Known2, KnownBits::makeConstant(APInt(32, ShiftAmt))));
}
// If the known bits conflict, the result is poison. Return a 0 and hope the
@@ -1115,9 +1115,9 @@ static void computeKnownBitsFromOperator(const Operator *I,
break;
}
case Instruction::UDiv: {
- computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
+ computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
- Known = KnownBits::udiv(Known, Known2);
+ Known = KnownBits::udiv(Known, Known2);
break;
}
case Instruction::Select: {
@@ -1126,38 +1126,38 @@ static void computeKnownBitsFromOperator(const Operator *I,
if (SelectPatternResult::isMinOrMax(SPF)) {
computeKnownBits(RHS, Known, Depth + 1, Q);
computeKnownBits(LHS, Known2, Depth + 1, Q);
- switch (SPF) {
- default:
- llvm_unreachable("Unhandled select pattern flavor!");
- case SPF_SMAX:
- Known = KnownBits::smax(Known, Known2);
- break;
- case SPF_SMIN:
- Known = KnownBits::smin(Known, Known2);
- break;
- case SPF_UMAX:
- Known = KnownBits::umax(Known, Known2);
- break;
- case SPF_UMIN:
- Known = KnownBits::umin(Known, Known2);
- break;
- }
- break;
+ switch (SPF) {
+ default:
+ llvm_unreachable("Unhandled select pattern flavor!");
+ case SPF_SMAX:
+ Known = KnownBits::smax(Known, Known2);
+ break;
+ case SPF_SMIN:
+ Known = KnownBits::smin(Known, Known2);
+ break;
+ case SPF_UMAX:
+ Known = KnownBits::umax(Known, Known2);
+ break;
+ case SPF_UMIN:
+ Known = KnownBits::umin(Known, Known2);
+ break;
+ }
+ break;
}
- computeKnownBits(I->getOperand(2), Known, Depth + 1, Q);
- computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
-
- // Only known if known in both the LHS and RHS.
- Known = KnownBits::commonBits(Known, Known2);
-
- if (SPF == SPF_ABS) {
+ computeKnownBits(I->getOperand(2), Known, Depth + 1, Q);
+ computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
+
+ // Only known if known in both the LHS and RHS.
+ Known = KnownBits::commonBits(Known, Known2);
+
+ if (SPF == SPF_ABS) {
// RHS from matchSelectPattern returns the negation part of abs pattern.
// If the negate has an NSW flag we can assume the sign bit of the result
// will be 0 because that makes abs(INT_MIN) undefined.
if (match(RHS, m_Neg(m_Specific(LHS))) &&
Q.IIQ.hasNoSignedWrap(cast<Instruction>(RHS)))
- Known.Zero.setSignBit();
+ Known.Zero.setSignBit();
}
break;
@@ -1215,36 +1215,36 @@ static void computeKnownBitsFromOperator(const Operator *I,
}
case Instruction::Shl: {
bool NSW = Q.IIQ.hasNoSignedWrap(cast<OverflowingBinaryOperator>(I));
- auto KF = [NSW](const KnownBits &KnownVal, const KnownBits &KnownAmt) {
- KnownBits Result = KnownBits::shl(KnownVal, KnownAmt);
+ auto KF = [NSW](const KnownBits &KnownVal, const KnownBits &KnownAmt) {
+ KnownBits Result = KnownBits::shl(KnownVal, KnownAmt);
// If this shift has "nsw" keyword, then the result is either a poison
// value or has the same sign bit as the first operand.
- if (NSW) {
- if (KnownVal.Zero.isSignBitSet())
- Result.Zero.setSignBit();
- if (KnownVal.One.isSignBitSet())
- Result.One.setSignBit();
- }
- return Result;
+ if (NSW) {
+ if (KnownVal.Zero.isSignBitSet())
+ Result.Zero.setSignBit();
+ if (KnownVal.One.isSignBitSet())
+ Result.One.setSignBit();
+ }
+ return Result;
};
computeKnownBitsFromShiftOperator(I, DemandedElts, Known, Known2, Depth, Q,
- KF);
+ KF);
break;
}
case Instruction::LShr: {
- auto KF = [](const KnownBits &KnownVal, const KnownBits &KnownAmt) {
- return KnownBits::lshr(KnownVal, KnownAmt);
+ auto KF = [](const KnownBits &KnownVal, const KnownBits &KnownAmt) {
+ return KnownBits::lshr(KnownVal, KnownAmt);
};
computeKnownBitsFromShiftOperator(I, DemandedElts, Known, Known2, Depth, Q,
- KF);
+ KF);
break;
}
case Instruction::AShr: {
- auto KF = [](const KnownBits &KnownVal, const KnownBits &KnownAmt) {
- return KnownBits::ashr(KnownVal, KnownAmt);
+ auto KF = [](const KnownBits &KnownVal, const KnownBits &KnownAmt) {
+ return KnownBits::ashr(KnownVal, KnownAmt);
};
computeKnownBitsFromShiftOperator(I, DemandedElts, Known, Known2, Depth, Q,
- KF);
+ KF);
break;
}
case Instruction::Sub: {
@@ -1260,15 +1260,15 @@ static void computeKnownBitsFromOperator(const Operator *I,
break;
}
case Instruction::SRem:
- computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
- computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
- Known = KnownBits::srem(Known, Known2);
+ computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
+ computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
+ Known = KnownBits::srem(Known, Known2);
break;
- case Instruction::URem:
+ case Instruction::URem:
computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
- Known = KnownBits::urem(Known, Known2);
+ Known = KnownBits::urem(Known, Known2);
break;
case Instruction::Alloca:
Known.Zero.setLowBits(Log2(cast<AllocaInst>(I)->getAlign()));
@@ -1276,29 +1276,29 @@ static void computeKnownBitsFromOperator(const Operator *I,
case Instruction::GetElementPtr: {
// Analyze all of the subscripts of this getelementptr instruction
// to determine if we can prove known low zero bits.
- computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
- // Accumulate the constant indices in a separate variable
- // to minimize the number of calls to computeForAddSub.
- APInt AccConstIndices(BitWidth, 0, /*IsSigned*/ true);
+ computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
+ // Accumulate the constant indices in a separate variable
+ // to minimize the number of calls to computeForAddSub.
+ APInt AccConstIndices(BitWidth, 0, /*IsSigned*/ true);
gep_type_iterator GTI = gep_type_begin(I);
for (unsigned i = 1, e = I->getNumOperands(); i != e; ++i, ++GTI) {
// TrailZ can only become smaller, short-circuit if we hit zero.
- if (Known.isUnknown())
+ if (Known.isUnknown())
break;
Value *Index = I->getOperand(i);
-
- // Handle case when index is zero.
- Constant *CIndex = dyn_cast<Constant>(Index);
- if (CIndex && CIndex->isZeroValue())
- continue;
-
+
+ // Handle case when index is zero.
+ Constant *CIndex = dyn_cast<Constant>(Index);
+ if (CIndex && CIndex->isZeroValue())
+ continue;
+
if (StructType *STy = GTI.getStructTypeOrNull()) {
// Handle struct member offset arithmetic.
- assert(CIndex &&
- "Access to structure field must be known at compile time");
+ assert(CIndex &&
+ "Access to structure field must be known at compile time");
if (CIndex->getType()->isVectorTy())
Index = CIndex->getSplatValue();
@@ -1306,56 +1306,56 @@ static void computeKnownBitsFromOperator(const Operator *I,
unsigned Idx = cast<ConstantInt>(Index)->getZExtValue();
const StructLayout *SL = Q.DL.getStructLayout(STy);
uint64_t Offset = SL->getElementOffset(Idx);
- AccConstIndices += Offset;
- continue;
- }
-
- // Handle array index arithmetic.
- Type *IndexedTy = GTI.getIndexedType();
- if (!IndexedTy->isSized()) {
- Known.resetAll();
- break;
- }
-
- unsigned IndexBitWidth = Index->getType()->getScalarSizeInBits();
- KnownBits IndexBits(IndexBitWidth);
- computeKnownBits(Index, IndexBits, Depth + 1, Q);
- TypeSize IndexTypeSize = Q.DL.getTypeAllocSize(IndexedTy);
- uint64_t TypeSizeInBytes = IndexTypeSize.getKnownMinSize();
- KnownBits ScalingFactor(IndexBitWidth);
- // Multiply by current sizeof type.
- // &A[i] == A + i * sizeof(*A[i]).
- if (IndexTypeSize.isScalable()) {
- // For scalable types the only thing we know about sizeof is
- // that this is a multiple of the minimum size.
- ScalingFactor.Zero.setLowBits(countTrailingZeros(TypeSizeInBytes));
- } else if (IndexBits.isConstant()) {
- APInt IndexConst = IndexBits.getConstant();
- APInt ScalingFactor(IndexBitWidth, TypeSizeInBytes);
- IndexConst *= ScalingFactor;
- AccConstIndices += IndexConst.sextOrTrunc(BitWidth);
- continue;
+ AccConstIndices += Offset;
+ continue;
+ }
+
+ // Handle array index arithmetic.
+ Type *IndexedTy = GTI.getIndexedType();
+ if (!IndexedTy->isSized()) {
+ Known.resetAll();
+ break;
+ }
+
+ unsigned IndexBitWidth = Index->getType()->getScalarSizeInBits();
+ KnownBits IndexBits(IndexBitWidth);
+ computeKnownBits(Index, IndexBits, Depth + 1, Q);
+ TypeSize IndexTypeSize = Q.DL.getTypeAllocSize(IndexedTy);
+ uint64_t TypeSizeInBytes = IndexTypeSize.getKnownMinSize();
+ KnownBits ScalingFactor(IndexBitWidth);
+ // Multiply by current sizeof type.
+ // &A[i] == A + i * sizeof(*A[i]).
+ if (IndexTypeSize.isScalable()) {
+ // For scalable types the only thing we know about sizeof is
+ // that this is a multiple of the minimum size.
+ ScalingFactor.Zero.setLowBits(countTrailingZeros(TypeSizeInBytes));
+ } else if (IndexBits.isConstant()) {
+ APInt IndexConst = IndexBits.getConstant();
+ APInt ScalingFactor(IndexBitWidth, TypeSizeInBytes);
+ IndexConst *= ScalingFactor;
+ AccConstIndices += IndexConst.sextOrTrunc(BitWidth);
+ continue;
} else {
- ScalingFactor =
- KnownBits::makeConstant(APInt(IndexBitWidth, TypeSizeInBytes));
+ ScalingFactor =
+ KnownBits::makeConstant(APInt(IndexBitWidth, TypeSizeInBytes));
}
- IndexBits = KnownBits::computeForMul(IndexBits, ScalingFactor);
-
- // If the offsets have a different width from the pointer, according
- // to the language reference we need to sign-extend or truncate them
- // to the width of the pointer.
- IndexBits = IndexBits.sextOrTrunc(BitWidth);
-
- // Note that inbounds does *not* guarantee nsw for the addition, as only
- // the offset is signed, while the base address is unsigned.
- Known = KnownBits::computeForAddSub(
- /*Add=*/true, /*NSW=*/false, Known, IndexBits);
+ IndexBits = KnownBits::computeForMul(IndexBits, ScalingFactor);
+
+ // If the offsets have a different width from the pointer, according
+ // to the language reference we need to sign-extend or truncate them
+ // to the width of the pointer.
+ IndexBits = IndexBits.sextOrTrunc(BitWidth);
+
+ // Note that inbounds does *not* guarantee nsw for the addition, as only
+ // the offset is signed, while the base address is unsigned.
+ Known = KnownBits::computeForAddSub(
+ /*Add=*/true, /*NSW=*/false, Known, IndexBits);
+ }
+ if (!Known.isUnknown() && !AccConstIndices.isNullValue()) {
+ KnownBits Index = KnownBits::makeConstant(AccConstIndices);
+ Known = KnownBits::computeForAddSub(
+ /*Add=*/true, /*NSW=*/false, Known, Index);
}
- if (!Known.isUnknown() && !AccConstIndices.isNullValue()) {
- KnownBits Index = KnownBits::makeConstant(AccConstIndices);
- Known = KnownBits::computeForAddSub(
- /*Add=*/true, /*NSW=*/false, Known, Index);
- }
break;
}
case Instruction::PHI: {
@@ -1454,7 +1454,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
// Otherwise take the unions of the known bit sets of the operands,
// taking conservative care to avoid excessive recursion.
- if (Depth < MaxAnalysisRecursionDepth - 1 && !Known.Zero && !Known.One) {
+ if (Depth < MaxAnalysisRecursionDepth - 1 && !Known.Zero && !Known.One) {
// Skip if every incoming value references to ourself.
if (dyn_cast_or_null<UndefValue>(P->hasConstantValue()))
break;
@@ -1476,11 +1476,11 @@ static void computeKnownBitsFromOperator(const Operator *I,
Known2 = KnownBits(BitWidth);
// Recurse, but cap the recursion to one level, because we don't
// want to waste time spinning around in loops.
- computeKnownBits(IncValue, Known2, MaxAnalysisRecursionDepth - 1, RecQ);
- Known = KnownBits::commonBits(Known, Known2);
+ computeKnownBits(IncValue, Known2, MaxAnalysisRecursionDepth - 1, RecQ);
+ Known = KnownBits::commonBits(Known, Known2);
// If all bits have been ruled out, there's no need to check
// more operands.
- if (Known.isUnknown())
+ if (Known.isUnknown())
break;
}
}
@@ -1502,12 +1502,12 @@ static void computeKnownBitsFromOperator(const Operator *I,
if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
switch (II->getIntrinsicID()) {
default: break;
- case Intrinsic::abs: {
- computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q);
- bool IntMinIsPoison = match(II->getArgOperand(1), m_One());
- Known = Known2.abs(IntMinIsPoison);
- break;
- }
+ case Intrinsic::abs: {
+ computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q);
+ bool IntMinIsPoison = match(II->getArgOperand(1), m_One());
+ Known = Known2.abs(IntMinIsPoison);
+ break;
+ }
case Intrinsic::bitreverse:
computeKnownBits(I->getOperand(0), DemandedElts, Known2, Depth + 1, Q);
Known.Zero |= Known2.Zero.reverseBits();
@@ -1521,7 +1521,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
case Intrinsic::ctlz: {
computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q);
// If we have a known 1, its position is our upper bound.
- unsigned PossibleLZ = Known2.countMaxLeadingZeros();
+ unsigned PossibleLZ = Known2.countMaxLeadingZeros();
// If this call is undefined for 0, the result will be less than 2^n.
if (II->getArgOperand(1) == ConstantInt::getTrue(II->getContext()))
PossibleLZ = std::min(PossibleLZ, BitWidth - 1);
@@ -1532,7 +1532,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
case Intrinsic::cttz: {
computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q);
// If we have a known 1, its position is our upper bound.
- unsigned PossibleTZ = Known2.countMaxTrailingZeros();
+ unsigned PossibleTZ = Known2.countMaxTrailingZeros();
// If this call is undefined for 0, the result will be less than 2^n.
if (II->getArgOperand(1) == ConstantInt::getTrue(II->getContext()))
PossibleTZ = std::min(PossibleTZ, BitWidth - 1);
@@ -1603,26 +1603,26 @@ static void computeKnownBitsFromOperator(const Operator *I,
}
break;
}
- case Intrinsic::umin:
- computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
- computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
- Known = KnownBits::umin(Known, Known2);
- break;
- case Intrinsic::umax:
- computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
- computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
- Known = KnownBits::umax(Known, Known2);
- break;
- case Intrinsic::smin:
- computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
- computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
- Known = KnownBits::smin(Known, Known2);
- break;
- case Intrinsic::smax:
- computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
- computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
- Known = KnownBits::smax(Known, Known2);
- break;
+ case Intrinsic::umin:
+ computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
+ computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
+ Known = KnownBits::umin(Known, Known2);
+ break;
+ case Intrinsic::umax:
+ computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
+ computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
+ Known = KnownBits::umax(Known, Known2);
+ break;
+ case Intrinsic::smin:
+ computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
+ computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
+ Known = KnownBits::smin(Known, Known2);
+ break;
+ case Intrinsic::smax:
+ computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
+ computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
+ Known = KnownBits::smax(Known, Known2);
+ break;
case Intrinsic::x86_sse42_crc32_64_64:
Known.Zero.setBitsFrom(32);
break;
@@ -1655,7 +1655,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
if (!!DemandedRHS) {
const Value *RHS = Shuf->getOperand(1);
computeKnownBits(RHS, DemandedRHS, Known2, Depth + 1, Q);
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
}
break;
}
@@ -1684,7 +1684,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
DemandedVecElts.clearBit(EltIdx);
if (!!DemandedVecElts) {
computeKnownBits(Vec, DemandedVecElts, Known2, Depth + 1, Q);
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
}
break;
}
@@ -1734,11 +1734,11 @@ static void computeKnownBitsFromOperator(const Operator *I,
}
}
break;
- case Instruction::Freeze:
- if (isGuaranteedNotToBePoison(I->getOperand(0), Q.AC, Q.CxtI, Q.DT,
- Depth + 1))
- computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
- break;
+ case Instruction::Freeze:
+ if (isGuaranteedNotToBePoison(I->getOperand(0), Q.AC, Q.CxtI, Q.DT,
+ Depth + 1))
+ computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
+ break;
}
}
@@ -1784,7 +1784,7 @@ void computeKnownBits(const Value *V, const APInt &DemandedElts,
}
assert(V && "No Value?");
- assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
+ assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
#ifndef NDEBUG
Type *Ty = V->getType();
@@ -1815,7 +1815,7 @@ void computeKnownBits(const Value *V, const APInt &DemandedElts,
const APInt *C;
if (match(V, m_APInt(C))) {
// We know all of the bits for a scalar constant or a splat vector constant!
- Known = KnownBits::makeConstant(*C);
+ Known = KnownBits::makeConstant(*C);
return;
}
// Null and aggregate-zero are all-zeros.
@@ -1871,7 +1871,7 @@ void computeKnownBits(const Value *V, const APInt &DemandedElts,
assert(!isa<ConstantData>(V) && "Unhandled constant data!");
// All recursive calls that increase depth must come after this.
- if (Depth == MaxAnalysisRecursionDepth)
+ if (Depth == MaxAnalysisRecursionDepth)
return;
// A weak GlobalAlias is totally unknown. A non-weak GlobalAlias has
@@ -1888,7 +1888,7 @@ void computeKnownBits(const Value *V, const APInt &DemandedElts,
// Aligned pointers have trailing zeros - refine Known.Zero set
if (isa<PointerType>(V->getType())) {
Align Alignment = V->getPointerAlignment(Q.DL);
- Known.Zero.setLowBits(Log2(Alignment));
+ Known.Zero.setLowBits(Log2(Alignment));
}
// computeKnownBitsFromAssume strictly refines Known.
@@ -1906,7 +1906,7 @@ void computeKnownBits(const Value *V, const APInt &DemandedElts,
/// types and vectors of integers.
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero, unsigned Depth,
const Query &Q) {
- assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
+ assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
// Attempt to match against constants.
if (OrZero && match(V, m_Power2OrZero()))
@@ -1925,7 +1925,7 @@ bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero, unsigned Depth,
return true;
// The remaining tests are all recursive, so bail out if we hit the limit.
- if (Depth++ == MaxAnalysisRecursionDepth)
+ if (Depth++ == MaxAnalysisRecursionDepth)
return false;
Value *X = nullptr, *Y = nullptr;
@@ -2054,7 +2054,7 @@ static bool isGEPKnownNonNull(const GEPOperator *GEP, unsigned Depth,
// to recurse 10k times just because we have 10k GEP operands. We don't
// bail completely out because we want to handle constant GEPs regardless
// of depth.
- if (Depth++ >= MaxAnalysisRecursionDepth)
+ if (Depth++ >= MaxAnalysisRecursionDepth)
continue;
if (isKnownNonZero(GTI.getOperand(), Depth, Q))
@@ -2086,8 +2086,8 @@ static bool isKnownNonNullFromDominatingCondition(const Value *V,
if (auto *CalledFunc = CB->getCalledFunction())
for (const Argument &Arg : CalledFunc->args())
if (CB->getArgOperand(Arg.getArgNo()) == V &&
- Arg.hasNonNullAttr(/* AllowUndefOrPoison */ false) &&
- DT->dominates(CB, CtxI))
+ Arg.hasNonNullAttr(/* AllowUndefOrPoison */ false) &&
+ DT->dominates(CB, CtxI))
return true;
// If the value is used as a load/store, then the pointer must be non null.
@@ -2100,19 +2100,19 @@ static bool isKnownNonNullFromDominatingCondition(const Value *V,
}
// Consider only compare instructions uniquely controlling a branch
- Value *RHS;
+ Value *RHS;
CmpInst::Predicate Pred;
- if (!match(U, m_c_ICmp(Pred, m_Specific(V), m_Value(RHS))))
+ if (!match(U, m_c_ICmp(Pred, m_Specific(V), m_Value(RHS))))
+ continue;
+
+ bool NonNullIfTrue;
+ if (cmpExcludesZero(Pred, RHS))
+ NonNullIfTrue = true;
+ else if (cmpExcludesZero(CmpInst::getInversePredicate(Pred), RHS))
+ NonNullIfTrue = false;
+ else
continue;
- bool NonNullIfTrue;
- if (cmpExcludesZero(Pred, RHS))
- NonNullIfTrue = true;
- else if (cmpExcludesZero(CmpInst::getInversePredicate(Pred), RHS))
- NonNullIfTrue = false;
- else
- continue;
-
SmallVector<const User *, 4> WorkList;
SmallPtrSet<const User *, 4> Visited;
for (auto *CmpU : U->users()) {
@@ -2127,23 +2127,23 @@ static bool isKnownNonNullFromDominatingCondition(const Value *V,
// propagate "pred != null" condition through AND because it is only
// correct to assume that all conditions of AND are met in true branch.
// TODO: Support similar logic of OR and EQ predicate?
- if (NonNullIfTrue)
- if (match(Curr, m_LogicalAnd(m_Value(), m_Value()))) {
- for (auto *CurrU : Curr->users())
- if (Visited.insert(CurrU).second)
- WorkList.push_back(CurrU);
- continue;
- }
+ if (NonNullIfTrue)
+ if (match(Curr, m_LogicalAnd(m_Value(), m_Value()))) {
+ for (auto *CurrU : Curr->users())
+ if (Visited.insert(CurrU).second)
+ WorkList.push_back(CurrU);
+ continue;
+ }
if (const BranchInst *BI = dyn_cast<BranchInst>(Curr)) {
assert(BI->isConditional() && "uses a comparison!");
BasicBlock *NonNullSuccessor =
- BI->getSuccessor(NonNullIfTrue ? 0 : 1);
+ BI->getSuccessor(NonNullIfTrue ? 0 : 1);
BasicBlockEdge Edge(BI->getParent(), NonNullSuccessor);
if (Edge.isSingleEdge() && DT->dominates(Edge, CtxI->getParent()))
return true;
- } else if (NonNullIfTrue && isGuard(Curr) &&
+ } else if (NonNullIfTrue && isGuard(Curr) &&
DT->dominates(cast<Instruction>(Curr), CtxI)) {
return true;
}
@@ -2196,9 +2196,9 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
// See the comment for IntToPtr/PtrToInt instructions below.
if (CE->getOpcode() == Instruction::IntToPtr ||
CE->getOpcode() == Instruction::PtrToInt)
- if (Q.DL.getTypeSizeInBits(CE->getOperand(0)->getType())
- .getFixedSize() <=
- Q.DL.getTypeSizeInBits(CE->getType()).getFixedSize())
+ if (Q.DL.getTypeSizeInBits(CE->getOperand(0)->getType())
+ .getFixedSize() <=
+ Q.DL.getTypeSizeInBits(CE->getType()).getFixedSize())
return isKnownNonZero(CE->getOperand(0), Depth, Q);
}
@@ -2244,24 +2244,24 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
return true;
// Some of the tests below are recursive, so bail out if we hit the limit.
- if (Depth++ >= MaxAnalysisRecursionDepth)
+ if (Depth++ >= MaxAnalysisRecursionDepth)
return false;
// Check for pointer simplifications.
-
- if (PointerType *PtrTy = dyn_cast<PointerType>(V->getType())) {
+
+ if (PointerType *PtrTy = dyn_cast<PointerType>(V->getType())) {
// Alloca never returns null, malloc might.
if (isa<AllocaInst>(V) && Q.DL.getAllocaAddrSpace() == 0)
return true;
- // A byval, inalloca may not be null in a non-default addres space. A
- // nonnull argument is assumed never 0.
- if (const Argument *A = dyn_cast<Argument>(V)) {
- if (((A->hasPassPointeeByValueCopyAttr() &&
- !NullPointerIsDefined(A->getParent(), PtrTy->getAddressSpace())) ||
- A->hasNonNullAttr()))
+ // A byval, inalloca may not be null in a non-default addres space. A
+ // nonnull argument is assumed never 0.
+ if (const Argument *A = dyn_cast<Argument>(V)) {
+ if (((A->hasPassPointeeByValueCopyAttr() &&
+ !NullPointerIsDefined(A->getParent(), PtrTy->getAddressSpace())) ||
+ A->hasNonNullAttr()))
return true;
- }
+ }
// A Load tagged with nonnull metadata is never null.
if (const LoadInst *LI = dyn_cast<LoadInst>(V))
@@ -2289,22 +2289,22 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
// truncating casts, e.g., int2ptr/ptr2int with appropriate sizes, as well
// as casts that can alter the value, e.g., AddrSpaceCasts.
if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V))
- return isGEPKnownNonNull(GEP, Depth, Q);
+ return isGEPKnownNonNull(GEP, Depth, Q);
if (auto *BCO = dyn_cast<BitCastOperator>(V))
return isKnownNonZero(BCO->getOperand(0), Depth, Q);
if (auto *I2P = dyn_cast<IntToPtrInst>(V))
- if (Q.DL.getTypeSizeInBits(I2P->getSrcTy()).getFixedSize() <=
- Q.DL.getTypeSizeInBits(I2P->getDestTy()).getFixedSize())
+ if (Q.DL.getTypeSizeInBits(I2P->getSrcTy()).getFixedSize() <=
+ Q.DL.getTypeSizeInBits(I2P->getDestTy()).getFixedSize())
return isKnownNonZero(I2P->getOperand(0), Depth, Q);
}
// Similar to int2ptr above, we can look through ptr2int here if the cast
// is a no-op or an extend and not a truncate.
if (auto *P2I = dyn_cast<PtrToIntInst>(V))
- if (Q.DL.getTypeSizeInBits(P2I->getSrcTy()).getFixedSize() <=
- Q.DL.getTypeSizeInBits(P2I->getDestTy()).getFixedSize())
+ if (Q.DL.getTypeSizeInBits(P2I->getSrcTy()).getFixedSize() <=
+ Q.DL.getTypeSizeInBits(P2I->getDestTy()).getFixedSize())
return isKnownNonZero(P2I->getOperand(0), Depth, Q);
unsigned BitWidth = getBitWidth(V->getType()->getScalarType(), Q.DL);
@@ -2431,14 +2431,14 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
}
}
}
- // Check if all incoming values are non-zero using recursion.
- Query RecQ = Q;
- unsigned NewDepth = std::max(Depth, MaxAnalysisRecursionDepth - 1);
- return llvm::all_of(PN->operands(), [&](const Use &U) {
- if (U.get() == PN)
- return true;
- RecQ.CxtI = PN->getIncomingBlock(U)->getTerminator();
- return isKnownNonZero(U.get(), DemandedElts, NewDepth, RecQ);
+ // Check if all incoming values are non-zero using recursion.
+ Query RecQ = Q;
+ unsigned NewDepth = std::max(Depth, MaxAnalysisRecursionDepth - 1);
+ return llvm::all_of(PN->operands(), [&](const Use &U) {
+ if (U.get() == PN)
+ return true;
+ RecQ.CxtI = PN->getIncomingBlock(U)->getTerminator();
+ return isKnownNonZero(U.get(), DemandedElts, NewDepth, RecQ);
});
}
// ExtractElement
@@ -2446,21 +2446,21 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
const Value *Vec = EEI->getVectorOperand();
const Value *Idx = EEI->getIndexOperand();
auto *CIdx = dyn_cast<ConstantInt>(Idx);
- if (auto *VecTy = dyn_cast<FixedVectorType>(Vec->getType())) {
- unsigned NumElts = VecTy->getNumElements();
- APInt DemandedVecElts = APInt::getAllOnesValue(NumElts);
- if (CIdx && CIdx->getValue().ult(NumElts))
- DemandedVecElts = APInt::getOneBitSet(NumElts, CIdx->getZExtValue());
- return isKnownNonZero(Vec, DemandedVecElts, Depth, Q);
- }
- }
- // Freeze
- else if (const FreezeInst *FI = dyn_cast<FreezeInst>(V)) {
- auto *Op = FI->getOperand(0);
- if (isKnownNonZero(Op, Depth, Q) &&
- isGuaranteedNotToBePoison(Op, Q.AC, Q.CxtI, Q.DT, Depth))
- return true;
- }
+ if (auto *VecTy = dyn_cast<FixedVectorType>(Vec->getType())) {
+ unsigned NumElts = VecTy->getNumElements();
+ APInt DemandedVecElts = APInt::getAllOnesValue(NumElts);
+ if (CIdx && CIdx->getValue().ult(NumElts))
+ DemandedVecElts = APInt::getOneBitSet(NumElts, CIdx->getZExtValue());
+ return isKnownNonZero(Vec, DemandedVecElts, Depth, Q);
+ }
+ }
+ // Freeze
+ else if (const FreezeInst *FI = dyn_cast<FreezeInst>(V)) {
+ auto *Op = FI->getOperand(0);
+ if (isKnownNonZero(Op, Depth, Q) &&
+ isGuaranteedNotToBePoison(Op, Q.AC, Q.CxtI, Q.DT, Depth))
+ return true;
+ }
KnownBits Known(BitWidth);
computeKnownBits(V, DemandedElts, Known, Depth, Q);
@@ -2480,8 +2480,8 @@ bool isKnownNonZero(const Value* V, unsigned Depth, const Query& Q) {
}
/// Return true if V2 == V1 + X, where X is known non-zero.
-static bool isAddOfNonZero(const Value *V1, const Value *V2, unsigned Depth,
- const Query &Q) {
+static bool isAddOfNonZero(const Value *V1, const Value *V2, unsigned Depth,
+ const Query &Q) {
const BinaryOperator *BO = dyn_cast<BinaryOperator>(V1);
if (!BO || BO->getOpcode() != Instruction::Add)
return false;
@@ -2492,75 +2492,75 @@ static bool isAddOfNonZero(const Value *V1, const Value *V2, unsigned Depth,
Op = BO->getOperand(0);
else
return false;
- return isKnownNonZero(Op, Depth + 1, Q);
+ return isKnownNonZero(Op, Depth + 1, Q);
}
-
+
/// Return true if it is known that V1 != V2.
-static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
- const Query &Q) {
+static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
+ const Query &Q) {
if (V1 == V2)
return false;
if (V1->getType() != V2->getType())
// We can't look through casts yet.
return false;
-
- if (Depth >= MaxAnalysisRecursionDepth)
- return false;
-
- // See if we can recurse through (exactly one of) our operands. This
- // requires our operation be 1-to-1 and map every input value to exactly
- // one output value. Such an operation is invertible.
- auto *O1 = dyn_cast<Operator>(V1);
- auto *O2 = dyn_cast<Operator>(V2);
- if (O1 && O2 && O1->getOpcode() == O2->getOpcode()) {
- switch (O1->getOpcode()) {
- default: break;
- case Instruction::Add:
- case Instruction::Sub:
- // Assume operand order has been canonicalized
- if (O1->getOperand(0) == O2->getOperand(0))
- return isKnownNonEqual(O1->getOperand(1), O2->getOperand(1),
- Depth + 1, Q);
- if (O1->getOperand(1) == O2->getOperand(1))
- return isKnownNonEqual(O1->getOperand(0), O2->getOperand(0),
- Depth + 1, Q);
- break;
- case Instruction::Mul: {
- // invertible if A * B == (A * B) mod 2^N where A, and B are integers
- // and N is the bitwdith. The nsw case is non-obvious, but proven by
- // alive2: https://alive2.llvm.org/ce/z/Z6D5qK
- auto *OBO1 = cast<OverflowingBinaryOperator>(O1);
- auto *OBO2 = cast<OverflowingBinaryOperator>(O2);
- if ((!OBO1->hasNoUnsignedWrap() || !OBO2->hasNoUnsignedWrap()) &&
- (!OBO1->hasNoSignedWrap() || !OBO2->hasNoSignedWrap()))
- break;
-
- // Assume operand order has been canonicalized
- if (O1->getOperand(1) == O2->getOperand(1) &&
- isa<ConstantInt>(O1->getOperand(1)) &&
- !cast<ConstantInt>(O1->getOperand(1))->isZero())
- return isKnownNonEqual(O1->getOperand(0), O2->getOperand(0),
- Depth + 1, Q);
- break;
- }
- case Instruction::SExt:
- case Instruction::ZExt:
- if (O1->getOperand(0)->getType() == O2->getOperand(0)->getType())
- return isKnownNonEqual(O1->getOperand(0), O2->getOperand(0),
- Depth + 1, Q);
- break;
- };
- }
-
- if (isAddOfNonZero(V1, V2, Depth, Q) || isAddOfNonZero(V2, V1, Depth, Q))
+
+ if (Depth >= MaxAnalysisRecursionDepth)
+ return false;
+
+ // See if we can recurse through (exactly one of) our operands. This
+ // requires our operation be 1-to-1 and map every input value to exactly
+ // one output value. Such an operation is invertible.
+ auto *O1 = dyn_cast<Operator>(V1);
+ auto *O2 = dyn_cast<Operator>(V2);
+ if (O1 && O2 && O1->getOpcode() == O2->getOpcode()) {
+ switch (O1->getOpcode()) {
+ default: break;
+ case Instruction::Add:
+ case Instruction::Sub:
+ // Assume operand order has been canonicalized
+ if (O1->getOperand(0) == O2->getOperand(0))
+ return isKnownNonEqual(O1->getOperand(1), O2->getOperand(1),
+ Depth + 1, Q);
+ if (O1->getOperand(1) == O2->getOperand(1))
+ return isKnownNonEqual(O1->getOperand(0), O2->getOperand(0),
+ Depth + 1, Q);
+ break;
+ case Instruction::Mul: {
+ // invertible if A * B == (A * B) mod 2^N where A, and B are integers
+ // and N is the bitwdith. The nsw case is non-obvious, but proven by
+ // alive2: https://alive2.llvm.org/ce/z/Z6D5qK
+ auto *OBO1 = cast<OverflowingBinaryOperator>(O1);
+ auto *OBO2 = cast<OverflowingBinaryOperator>(O2);
+ if ((!OBO1->hasNoUnsignedWrap() || !OBO2->hasNoUnsignedWrap()) &&
+ (!OBO1->hasNoSignedWrap() || !OBO2->hasNoSignedWrap()))
+ break;
+
+ // Assume operand order has been canonicalized
+ if (O1->getOperand(1) == O2->getOperand(1) &&
+ isa<ConstantInt>(O1->getOperand(1)) &&
+ !cast<ConstantInt>(O1->getOperand(1))->isZero())
+ return isKnownNonEqual(O1->getOperand(0), O2->getOperand(0),
+ Depth + 1, Q);
+ break;
+ }
+ case Instruction::SExt:
+ case Instruction::ZExt:
+ if (O1->getOperand(0)->getType() == O2->getOperand(0)->getType())
+ return isKnownNonEqual(O1->getOperand(0), O2->getOperand(0),
+ Depth + 1, Q);
+ break;
+ };
+ }
+
+ if (isAddOfNonZero(V1, V2, Depth, Q) || isAddOfNonZero(V2, V1, Depth, Q))
return true;
if (V1->getType()->isIntOrIntVectorTy()) {
// Are any known bits in V1 contradictory to known bits in V2? If V1
// has a known zero where V2 has a known one, they must not be equal.
- KnownBits Known1 = computeKnownBits(V1, Depth, Q);
- KnownBits Known2 = computeKnownBits(V2, Depth, Q);
+ KnownBits Known1 = computeKnownBits(V1, Depth, Q);
+ KnownBits Known2 = computeKnownBits(V2, Depth, Q);
if (Known1.Zero.intersects(Known2.One) ||
Known2.Zero.intersects(Known1.One))
@@ -2672,7 +2672,7 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
return 1;
#ifndef NDEBUG
- assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
+ assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
if (auto *FVTy = dyn_cast<FixedVectorType>(Ty)) {
assert(
@@ -2699,8 +2699,8 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
// Note that ConstantInt is handled by the general computeKnownBits case
// below.
- if (Depth == MaxAnalysisRecursionDepth)
- return 1;
+ if (Depth == MaxAnalysisRecursionDepth)
+ return 1;
if (auto *U = dyn_cast<Operator>(V)) {
switch (Operator::getOpcode(V)) {
@@ -2892,13 +2892,13 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
// Take the minimum of all incoming values. This can't infinitely loop
// because of our depth threshold.
- Query RecQ = Q;
- Tmp = TyBits;
- for (unsigned i = 0, e = NumIncomingValues; i != e; ++i) {
+ Query RecQ = Q;
+ Tmp = TyBits;
+ for (unsigned i = 0, e = NumIncomingValues; i != e; ++i) {
if (Tmp == 1) return Tmp;
- RecQ.CxtI = PN->getIncomingBlock(i)->getTerminator();
+ RecQ.CxtI = PN->getIncomingBlock(i)->getTerminator();
Tmp = std::min(
- Tmp, ComputeNumSignBits(PN->getIncomingValue(i), Depth + 1, RecQ));
+ Tmp, ComputeNumSignBits(PN->getIncomingValue(i), Depth + 1, RecQ));
}
return Tmp;
}
@@ -2946,23 +2946,23 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
// fall-back.
if (Tmp == 1)
break;
- assert(Tmp <= TyBits && "Failed to determine minimum sign bits");
+ assert(Tmp <= TyBits && "Failed to determine minimum sign bits");
return Tmp;
}
- case Instruction::Call: {
- if (const auto *II = dyn_cast<IntrinsicInst>(U)) {
- switch (II->getIntrinsicID()) {
- default: break;
- case Intrinsic::abs:
- Tmp = ComputeNumSignBits(U->getOperand(0), Depth + 1, Q);
- if (Tmp == 1) break;
-
- // Absolute value reduces number of sign bits by at most 1.
- return Tmp - 1;
- }
- }
+ case Instruction::Call: {
+ if (const auto *II = dyn_cast<IntrinsicInst>(U)) {
+ switch (II->getIntrinsicID()) {
+ default: break;
+ case Intrinsic::abs:
+ Tmp = ComputeNumSignBits(U->getOperand(0), Depth + 1, Q);
+ if (Tmp == 1) break;
+
+ // Absolute value reduces number of sign bits by at most 1.
+ return Tmp - 1;
+ }
+ }
+ }
}
- }
}
// Finally, if we can prove that the top bits of the result are 0's or 1's,
@@ -2989,7 +2989,7 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
bool llvm::ComputeMultiple(Value *V, unsigned Base, Value *&Multiple,
bool LookThroughSExt, unsigned Depth) {
assert(V && "No Value?");
- assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
+ assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
assert(V->getType()->isIntegerTy() && "Not integer or pointer type!");
Type *T = V->getType();
@@ -3017,7 +3017,7 @@ bool llvm::ComputeMultiple(Value *V, unsigned Base, Value *&Multiple,
return true;
}
- if (Depth == MaxAnalysisRecursionDepth) return false;
+ if (Depth == MaxAnalysisRecursionDepth) return false;
Operator *I = dyn_cast<Operator>(V);
if (!I) return false;
@@ -3051,11 +3051,11 @@ bool llvm::ComputeMultiple(Value *V, unsigned Base, Value *&Multiple,
if (ComputeMultiple(Op0, Base, Mul0, LookThroughSExt, Depth+1)) {
if (Constant *Op1C = dyn_cast<Constant>(Op1))
if (Constant *MulC = dyn_cast<Constant>(Mul0)) {
- if (Op1C->getType()->getPrimitiveSizeInBits().getFixedSize() <
- MulC->getType()->getPrimitiveSizeInBits().getFixedSize())
+ if (Op1C->getType()->getPrimitiveSizeInBits().getFixedSize() <
+ MulC->getType()->getPrimitiveSizeInBits().getFixedSize())
Op1C = ConstantExpr::getZExt(Op1C, MulC->getType());
- if (Op1C->getType()->getPrimitiveSizeInBits().getFixedSize() >
- MulC->getType()->getPrimitiveSizeInBits().getFixedSize())
+ if (Op1C->getType()->getPrimitiveSizeInBits().getFixedSize() >
+ MulC->getType()->getPrimitiveSizeInBits().getFixedSize())
MulC = ConstantExpr::getZExt(MulC, Op1C->getType());
// V == Base * (Mul0 * Op1), so return (Mul0 * Op1)
@@ -3075,11 +3075,11 @@ bool llvm::ComputeMultiple(Value *V, unsigned Base, Value *&Multiple,
if (ComputeMultiple(Op1, Base, Mul1, LookThroughSExt, Depth+1)) {
if (Constant *Op0C = dyn_cast<Constant>(Op0))
if (Constant *MulC = dyn_cast<Constant>(Mul1)) {
- if (Op0C->getType()->getPrimitiveSizeInBits().getFixedSize() <
- MulC->getType()->getPrimitiveSizeInBits().getFixedSize())
+ if (Op0C->getType()->getPrimitiveSizeInBits().getFixedSize() <
+ MulC->getType()->getPrimitiveSizeInBits().getFixedSize())
Op0C = ConstantExpr::getZExt(Op0C, MulC->getType());
- if (Op0C->getType()->getPrimitiveSizeInBits().getFixedSize() >
- MulC->getType()->getPrimitiveSizeInBits().getFixedSize())
+ if (Op0C->getType()->getPrimitiveSizeInBits().getFixedSize() >
+ MulC->getType()->getPrimitiveSizeInBits().getFixedSize())
MulC = ConstantExpr::getZExt(MulC, Op0C->getType());
// V == Base * (Mul1 * Op0), so return (Mul1 * Op0)
@@ -3219,7 +3219,7 @@ bool llvm::CannotBeNegativeZero(const Value *V, const TargetLibraryInfo *TLI,
if (auto *CFP = dyn_cast<ConstantFP>(V))
return !CFP->getValueAPF().isNegZero();
- if (Depth == MaxAnalysisRecursionDepth)
+ if (Depth == MaxAnalysisRecursionDepth)
return false;
auto *Op = dyn_cast<Operator>(V);
@@ -3287,8 +3287,8 @@ static bool cannotBeOrderedLessThanZeroImpl(const Value *V,
}
}
- if (Depth == MaxAnalysisRecursionDepth)
- return false;
+ if (Depth == MaxAnalysisRecursionDepth)
+ return false;
const Operator *I = dyn_cast<Operator>(V);
if (!I)
@@ -3440,7 +3440,7 @@ bool llvm::isKnownNeverInfinity(const Value *V, const TargetLibraryInfo *TLI,
if (auto *CFP = dyn_cast<ConstantFP>(V))
return !CFP->isInfinity();
- if (Depth == MaxAnalysisRecursionDepth)
+ if (Depth == MaxAnalysisRecursionDepth)
return false;
if (auto *Inst = dyn_cast<Instruction>(V)) {
@@ -3449,30 +3449,30 @@ bool llvm::isKnownNeverInfinity(const Value *V, const TargetLibraryInfo *TLI,
return isKnownNeverInfinity(Inst->getOperand(1), TLI, Depth + 1) &&
isKnownNeverInfinity(Inst->getOperand(2), TLI, Depth + 1);
}
- case Instruction::SIToFP:
- case Instruction::UIToFP: {
- // Get width of largest magnitude integer (remove a bit if signed).
- // This still works for a signed minimum value because the largest FP
- // value is scaled by some fraction close to 2.0 (1.0 + 0.xxxx).
- int IntSize = Inst->getOperand(0)->getType()->getScalarSizeInBits();
- if (Inst->getOpcode() == Instruction::SIToFP)
- --IntSize;
-
- // If the exponent of the largest finite FP value can hold the largest
- // integer, the result of the cast must be finite.
- Type *FPTy = Inst->getType()->getScalarType();
- return ilogb(APFloat::getLargest(FPTy->getFltSemantics())) >= IntSize;
- }
+ case Instruction::SIToFP:
+ case Instruction::UIToFP: {
+ // Get width of largest magnitude integer (remove a bit if signed).
+ // This still works for a signed minimum value because the largest FP
+ // value is scaled by some fraction close to 2.0 (1.0 + 0.xxxx).
+ int IntSize = Inst->getOperand(0)->getType()->getScalarSizeInBits();
+ if (Inst->getOpcode() == Instruction::SIToFP)
+ --IntSize;
+
+ // If the exponent of the largest finite FP value can hold the largest
+ // integer, the result of the cast must be finite.
+ Type *FPTy = Inst->getType()->getScalarType();
+ return ilogb(APFloat::getLargest(FPTy->getFltSemantics())) >= IntSize;
+ }
default:
break;
}
}
// try to handle fixed width vector constants
- auto *VFVTy = dyn_cast<FixedVectorType>(V->getType());
- if (VFVTy && isa<Constant>(V)) {
+ auto *VFVTy = dyn_cast<FixedVectorType>(V->getType());
+ if (VFVTy && isa<Constant>(V)) {
// For vectors, verify that each element is not infinity.
- unsigned NumElts = VFVTy->getNumElements();
+ unsigned NumElts = VFVTy->getNumElements();
for (unsigned i = 0; i != NumElts; ++i) {
Constant *Elt = cast<Constant>(V)->getAggregateElement(i);
if (!Elt)
@@ -3504,7 +3504,7 @@ bool llvm::isKnownNeverNaN(const Value *V, const TargetLibraryInfo *TLI,
if (auto *CFP = dyn_cast<ConstantFP>(V))
return !CFP->isNaN();
- if (Depth == MaxAnalysisRecursionDepth)
+ if (Depth == MaxAnalysisRecursionDepth)
return false;
if (auto *Inst = dyn_cast<Instruction>(V)) {
@@ -3574,10 +3574,10 @@ bool llvm::isKnownNeverNaN(const Value *V, const TargetLibraryInfo *TLI,
}
// Try to handle fixed width vector constants
- auto *VFVTy = dyn_cast<FixedVectorType>(V->getType());
- if (VFVTy && isa<Constant>(V)) {
+ auto *VFVTy = dyn_cast<FixedVectorType>(V->getType());
+ if (VFVTy && isa<Constant>(V)) {
// For vectors, verify that each element is not NaN.
- unsigned NumElts = VFVTy->getNumElements();
+ unsigned NumElts = VFVTy->getNumElements();
for (unsigned i = 0; i != NumElts; ++i) {
Constant *Elt = cast<Constant>(V)->getAggregateElement(i);
if (!Elt)
@@ -3655,13 +3655,13 @@ Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) {
if (auto *CE = dyn_cast<ConstantExpr>(C)) {
if (CE->getOpcode() == Instruction::IntToPtr) {
- if (auto *PtrTy = dyn_cast<PointerType>(CE->getType())) {
- unsigned BitWidth = DL.getPointerSizeInBits(PtrTy->getAddressSpace());
- return isBytewiseValue(
- ConstantExpr::getIntegerCast(CE->getOperand(0),
- Type::getIntNTy(Ctx, BitWidth), false),
- DL);
- }
+ if (auto *PtrTy = dyn_cast<PointerType>(CE->getType())) {
+ unsigned BitWidth = DL.getPointerSizeInBits(PtrTy->getAddressSpace());
+ return isBytewiseValue(
+ ConstantExpr::getIntegerCast(CE->getOperand(0),
+ Type::getIntNTy(Ctx, BitWidth), false),
+ DL);
+ }
}
}
@@ -4130,7 +4130,7 @@ static bool isSameUnderlyingObjectInLoop(const PHINode *PN,
return true;
}
-Value *llvm::getUnderlyingObject(Value *V, unsigned MaxLookup) {
+Value *llvm::getUnderlyingObject(Value *V, unsigned MaxLookup) {
if (!V->getType()->isPointerTy())
return V;
for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) {
@@ -4175,15 +4175,15 @@ Value *llvm::getUnderlyingObject(Value *V, unsigned MaxLookup) {
return V;
}
-void llvm::getUnderlyingObjects(const Value *V,
+void llvm::getUnderlyingObjects(const Value *V,
SmallVectorImpl<const Value *> &Objects,
- LoopInfo *LI, unsigned MaxLookup) {
+ LoopInfo *LI, unsigned MaxLookup) {
SmallPtrSet<const Value *, 4> Visited;
SmallVector<const Value *, 4> Worklist;
Worklist.push_back(V);
do {
const Value *P = Worklist.pop_back_val();
- P = getUnderlyingObject(P, MaxLookup);
+ P = getUnderlyingObject(P, MaxLookup);
if (!Visited.insert(P).second)
continue;
@@ -4207,7 +4207,7 @@ void llvm::getUnderlyingObjects(const Value *V,
// underlying objects.
if (!LI || !LI->isLoopHeader(PN->getParent()) ||
isSameUnderlyingObjectInLoop(PN, LI))
- append_range(Worklist, PN->incoming_values());
+ append_range(Worklist, PN->incoming_values());
continue;
}
@@ -4243,18 +4243,18 @@ static const Value *getUnderlyingObjectFromInt(const Value *V) {
} while (true);
}
-/// This is a wrapper around getUnderlyingObjects and adds support for basic
+/// This is a wrapper around getUnderlyingObjects and adds support for basic
/// ptrtoint+arithmetic+inttoptr sequences.
-/// It returns false if unidentified object is found in getUnderlyingObjects.
+/// It returns false if unidentified object is found in getUnderlyingObjects.
bool llvm::getUnderlyingObjectsForCodeGen(const Value *V,
- SmallVectorImpl<Value *> &Objects) {
+ SmallVectorImpl<Value *> &Objects) {
SmallPtrSet<const Value *, 16> Visited;
SmallVector<const Value *, 4> Working(1, V);
do {
V = Working.pop_back_val();
SmallVector<const Value *, 4> Objs;
- getUnderlyingObjects(V, Objs);
+ getUnderlyingObjects(V, Objs);
for (const Value *V : Objs) {
if (!Visited.insert(V).second)
@@ -4267,7 +4267,7 @@ bool llvm::getUnderlyingObjectsForCodeGen(const Value *V,
continue;
}
}
- // If getUnderlyingObjects fails to find an identifiable object,
+ // If getUnderlyingObjects fails to find an identifiable object,
// getUnderlyingObjectsForCodeGen also fails for safety.
if (!isIdentifiedObject(V)) {
Objects.clear();
@@ -4279,72 +4279,72 @@ bool llvm::getUnderlyingObjectsForCodeGen(const Value *V,
return true;
}
-AllocaInst *llvm::findAllocaForValue(Value *V, bool OffsetZero) {
- AllocaInst *Result = nullptr;
- SmallPtrSet<Value *, 4> Visited;
- SmallVector<Value *, 4> Worklist;
-
- auto AddWork = [&](Value *V) {
- if (Visited.insert(V).second)
- Worklist.push_back(V);
- };
-
- AddWork(V);
- do {
- V = Worklist.pop_back_val();
- assert(Visited.count(V));
-
- if (AllocaInst *AI = dyn_cast<AllocaInst>(V)) {
- if (Result && Result != AI)
- return nullptr;
- Result = AI;
- } else if (CastInst *CI = dyn_cast<CastInst>(V)) {
- AddWork(CI->getOperand(0));
- } else if (PHINode *PN = dyn_cast<PHINode>(V)) {
- for (Value *IncValue : PN->incoming_values())
- AddWork(IncValue);
- } else if (auto *SI = dyn_cast<SelectInst>(V)) {
- AddWork(SI->getTrueValue());
- AddWork(SI->getFalseValue());
- } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V)) {
- if (OffsetZero && !GEP->hasAllZeroIndices())
- return nullptr;
- AddWork(GEP->getPointerOperand());
- } else {
- return nullptr;
- }
- } while (!Worklist.empty());
-
- return Result;
-}
-
-static bool onlyUsedByLifetimeMarkersOrDroppableInstsHelper(
- const Value *V, bool AllowLifetime, bool AllowDroppable) {
+AllocaInst *llvm::findAllocaForValue(Value *V, bool OffsetZero) {
+ AllocaInst *Result = nullptr;
+ SmallPtrSet<Value *, 4> Visited;
+ SmallVector<Value *, 4> Worklist;
+
+ auto AddWork = [&](Value *V) {
+ if (Visited.insert(V).second)
+ Worklist.push_back(V);
+ };
+
+ AddWork(V);
+ do {
+ V = Worklist.pop_back_val();
+ assert(Visited.count(V));
+
+ if (AllocaInst *AI = dyn_cast<AllocaInst>(V)) {
+ if (Result && Result != AI)
+ return nullptr;
+ Result = AI;
+ } else if (CastInst *CI = dyn_cast<CastInst>(V)) {
+ AddWork(CI->getOperand(0));
+ } else if (PHINode *PN = dyn_cast<PHINode>(V)) {
+ for (Value *IncValue : PN->incoming_values())
+ AddWork(IncValue);
+ } else if (auto *SI = dyn_cast<SelectInst>(V)) {
+ AddWork(SI->getTrueValue());
+ AddWork(SI->getFalseValue());
+ } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V)) {
+ if (OffsetZero && !GEP->hasAllZeroIndices())
+ return nullptr;
+ AddWork(GEP->getPointerOperand());
+ } else {
+ return nullptr;
+ }
+ } while (!Worklist.empty());
+
+ return Result;
+}
+
+static bool onlyUsedByLifetimeMarkersOrDroppableInstsHelper(
+ const Value *V, bool AllowLifetime, bool AllowDroppable) {
for (const User *U : V->users()) {
const IntrinsicInst *II = dyn_cast<IntrinsicInst>(U);
- if (!II)
- return false;
+ if (!II)
+ return false;
+
+ if (AllowLifetime && II->isLifetimeStartOrEnd())
+ continue;
- if (AllowLifetime && II->isLifetimeStartOrEnd())
- continue;
-
- if (AllowDroppable && II->isDroppable())
- continue;
-
- return false;
+ if (AllowDroppable && II->isDroppable())
+ continue;
+
+ return false;
}
return true;
}
-bool llvm::onlyUsedByLifetimeMarkers(const Value *V) {
- return onlyUsedByLifetimeMarkersOrDroppableInstsHelper(
- V, /* AllowLifetime */ true, /* AllowDroppable */ false);
-}
-bool llvm::onlyUsedByLifetimeMarkersOrDroppableInsts(const Value *V) {
- return onlyUsedByLifetimeMarkersOrDroppableInstsHelper(
- V, /* AllowLifetime */ true, /* AllowDroppable */ true);
-}
-
+bool llvm::onlyUsedByLifetimeMarkers(const Value *V) {
+ return onlyUsedByLifetimeMarkersOrDroppableInstsHelper(
+ V, /* AllowLifetime */ true, /* AllowDroppable */ false);
+}
+bool llvm::onlyUsedByLifetimeMarkersOrDroppableInsts(const Value *V) {
+ return onlyUsedByLifetimeMarkersOrDroppableInstsHelper(
+ V, /* AllowLifetime */ true, /* AllowDroppable */ true);
+}
+
bool llvm::mustSuppressSpeculation(const LoadInst &LI) {
if (!LI.isUnordered())
return true;
@@ -4390,7 +4390,7 @@ bool llvm::isSafeToSpeculativelyExecute(const Value *V,
if (*Denominator == 0)
return false;
// It's safe to hoist if the denominator is not 0 or -1.
- if (!Denominator->isAllOnesValue())
+ if (!Denominator->isAllOnesValue())
return true;
// At this point we know that the denominator is -1. It is safe to hoist as
// long we know that the numerator is not INT_MIN.
@@ -4698,30 +4698,30 @@ bool llvm::isOverflowIntrinsicNoWrap(const WithOverflowInst *WO,
return llvm::any_of(GuardingBranches, AllUsesGuardedByBranch);
}
-static bool canCreateUndefOrPoison(const Operator *Op, bool PoisonOnly) {
+static bool canCreateUndefOrPoison(const Operator *Op, bool PoisonOnly) {
// See whether I has flags that may create poison
- if (const auto *OvOp = dyn_cast<OverflowingBinaryOperator>(Op)) {
- if (OvOp->hasNoSignedWrap() || OvOp->hasNoUnsignedWrap())
- return true;
- }
- if (const auto *ExactOp = dyn_cast<PossiblyExactOperator>(Op))
- if (ExactOp->isExact())
- return true;
- if (const auto *FP = dyn_cast<FPMathOperator>(Op)) {
+ if (const auto *OvOp = dyn_cast<OverflowingBinaryOperator>(Op)) {
+ if (OvOp->hasNoSignedWrap() || OvOp->hasNoUnsignedWrap())
+ return true;
+ }
+ if (const auto *ExactOp = dyn_cast<PossiblyExactOperator>(Op))
+ if (ExactOp->isExact())
+ return true;
+ if (const auto *FP = dyn_cast<FPMathOperator>(Op)) {
auto FMF = FP->getFastMathFlags();
if (FMF.noNaNs() || FMF.noInfs())
return true;
}
- unsigned Opcode = Op->getOpcode();
+ unsigned Opcode = Op->getOpcode();
- // Check whether opcode is a poison/undef-generating operation
+ // Check whether opcode is a poison/undef-generating operation
switch (Opcode) {
case Instruction::Shl:
case Instruction::AShr:
case Instruction::LShr: {
// Shifts return poison if shiftwidth is larger than the bitwidth.
- if (auto *C = dyn_cast<Constant>(Op->getOperand(1))) {
+ if (auto *C = dyn_cast<Constant>(Op->getOperand(1))) {
SmallVector<Constant *, 4> ShiftAmounts;
if (auto *FVTy = dyn_cast<FixedVectorType>(C->getType())) {
unsigned NumElts = FVTy->getNumElements();
@@ -4733,8 +4733,8 @@ static bool canCreateUndefOrPoison(const Operator *Op, bool PoisonOnly) {
ShiftAmounts.push_back(C);
bool Safe = llvm::all_of(ShiftAmounts, [](Constant *C) {
- auto *CI = dyn_cast_or_null<ConstantInt>(C);
- return CI && CI->getValue().ult(C->getType()->getIntegerBitWidth());
+ auto *CI = dyn_cast_or_null<ConstantInt>(C);
+ return CI && CI->getValue().ult(C->getType()->getIntegerBitWidth());
});
return !Safe;
}
@@ -4747,29 +4747,29 @@ static bool canCreateUndefOrPoison(const Operator *Op, bool PoisonOnly) {
return true;
case Instruction::Call:
case Instruction::CallBr:
- case Instruction::Invoke: {
- const auto *CB = cast<CallBase>(Op);
- return !CB->hasRetAttr(Attribute::NoUndef);
- }
+ case Instruction::Invoke: {
+ const auto *CB = cast<CallBase>(Op);
+ return !CB->hasRetAttr(Attribute::NoUndef);
+ }
case Instruction::InsertElement:
case Instruction::ExtractElement: {
// If index exceeds the length of the vector, it returns poison
- auto *VTy = cast<VectorType>(Op->getOperand(0)->getType());
- unsigned IdxOp = Op->getOpcode() == Instruction::InsertElement ? 2 : 1;
- auto *Idx = dyn_cast<ConstantInt>(Op->getOperand(IdxOp));
- if (!Idx || Idx->getValue().uge(VTy->getElementCount().getKnownMinValue()))
+ auto *VTy = cast<VectorType>(Op->getOperand(0)->getType());
+ unsigned IdxOp = Op->getOpcode() == Instruction::InsertElement ? 2 : 1;
+ auto *Idx = dyn_cast<ConstantInt>(Op->getOperand(IdxOp));
+ if (!Idx || Idx->getValue().uge(VTy->getElementCount().getKnownMinValue()))
return true;
return false;
}
- case Instruction::ShuffleVector: {
- // shufflevector may return undef.
- if (PoisonOnly)
- return false;
- ArrayRef<int> Mask = isa<ConstantExpr>(Op)
- ? cast<ConstantExpr>(Op)->getShuffleMask()
- : cast<ShuffleVectorInst>(Op)->getShuffleMask();
- return is_contained(Mask, UndefMaskElem);
- }
+ case Instruction::ShuffleVector: {
+ // shufflevector may return undef.
+ if (PoisonOnly)
+ return false;
+ ArrayRef<int> Mask = isa<ConstantExpr>(Op)
+ ? cast<ConstantExpr>(Op)->getShuffleMask()
+ : cast<ShuffleVectorInst>(Op)->getShuffleMask();
+ return is_contained(Mask, UndefMaskElem);
+ }
case Instruction::FNeg:
case Instruction::PHI:
case Instruction::Select:
@@ -4781,104 +4781,104 @@ static bool canCreateUndefOrPoison(const Operator *Op, bool PoisonOnly) {
case Instruction::ICmp:
case Instruction::FCmp:
return false;
- case Instruction::GetElementPtr: {
- const auto *GEP = cast<GEPOperator>(Op);
- return GEP->isInBounds();
- }
- default: {
- const auto *CE = dyn_cast<ConstantExpr>(Op);
- if (isa<CastInst>(Op) || (CE && CE->isCast()))
+ case Instruction::GetElementPtr: {
+ const auto *GEP = cast<GEPOperator>(Op);
+ return GEP->isInBounds();
+ }
+ default: {
+ const auto *CE = dyn_cast<ConstantExpr>(Op);
+ if (isa<CastInst>(Op) || (CE && CE->isCast()))
return false;
- else if (Instruction::isBinaryOp(Opcode))
+ else if (Instruction::isBinaryOp(Opcode))
return false;
// Be conservative and return true.
return true;
}
- }
-}
-
-bool llvm::canCreateUndefOrPoison(const Operator *Op) {
- return ::canCreateUndefOrPoison(Op, /*PoisonOnly=*/false);
-}
-
-bool llvm::canCreatePoison(const Operator *Op) {
- return ::canCreateUndefOrPoison(Op, /*PoisonOnly=*/true);
-}
-
-static bool directlyImpliesPoison(const Value *ValAssumedPoison,
- const Value *V, unsigned Depth) {
- if (ValAssumedPoison == V)
- return true;
-
- const unsigned MaxDepth = 2;
+ }
+}
+
+bool llvm::canCreateUndefOrPoison(const Operator *Op) {
+ return ::canCreateUndefOrPoison(Op, /*PoisonOnly=*/false);
+}
+
+bool llvm::canCreatePoison(const Operator *Op) {
+ return ::canCreateUndefOrPoison(Op, /*PoisonOnly=*/true);
+}
+
+static bool directlyImpliesPoison(const Value *ValAssumedPoison,
+ const Value *V, unsigned Depth) {
+ if (ValAssumedPoison == V)
+ return true;
+
+ const unsigned MaxDepth = 2;
if (Depth >= MaxDepth)
return false;
- const auto *I = dyn_cast<Instruction>(V);
- if (I && propagatesPoison(cast<Operator>(I))) {
- return any_of(I->operands(), [=](const Value *Op) {
- return directlyImpliesPoison(ValAssumedPoison, Op, Depth + 1);
- });
- }
- return false;
-}
-
-static bool impliesPoison(const Value *ValAssumedPoison, const Value *V,
- unsigned Depth) {
- if (isGuaranteedNotToBeUndefOrPoison(ValAssumedPoison))
+ const auto *I = dyn_cast<Instruction>(V);
+ if (I && propagatesPoison(cast<Operator>(I))) {
+ return any_of(I->operands(), [=](const Value *Op) {
+ return directlyImpliesPoison(ValAssumedPoison, Op, Depth + 1);
+ });
+ }
+ return false;
+}
+
+static bool impliesPoison(const Value *ValAssumedPoison, const Value *V,
+ unsigned Depth) {
+ if (isGuaranteedNotToBeUndefOrPoison(ValAssumedPoison))
return true;
- if (directlyImpliesPoison(ValAssumedPoison, V, /* Depth */ 0))
- return true;
-
- const unsigned MaxDepth = 2;
- if (Depth >= MaxDepth)
- return false;
-
- const auto *I = dyn_cast<Instruction>(ValAssumedPoison);
- if (I && !canCreatePoison(cast<Operator>(I))) {
- return all_of(I->operands(), [=](const Value *Op) {
- return impliesPoison(Op, V, Depth + 1);
- });
- }
- return false;
-}
-
-bool llvm::impliesPoison(const Value *ValAssumedPoison, const Value *V) {
- return ::impliesPoison(ValAssumedPoison, V, /* Depth */ 0);
-}
-
-static bool programUndefinedIfUndefOrPoison(const Value *V,
- bool PoisonOnly);
-
-static bool isGuaranteedNotToBeUndefOrPoison(const Value *V,
- AssumptionCache *AC,
- const Instruction *CtxI,
- const DominatorTree *DT,
- unsigned Depth, bool PoisonOnly) {
- if (Depth >= MaxAnalysisRecursionDepth)
- return false;
-
- if (isa<MetadataAsValue>(V))
- return false;
-
- if (const auto *A = dyn_cast<Argument>(V)) {
- if (A->hasAttribute(Attribute::NoUndef))
- return true;
- }
-
+ if (directlyImpliesPoison(ValAssumedPoison, V, /* Depth */ 0))
+ return true;
+
+ const unsigned MaxDepth = 2;
+ if (Depth >= MaxDepth)
+ return false;
+
+ const auto *I = dyn_cast<Instruction>(ValAssumedPoison);
+ if (I && !canCreatePoison(cast<Operator>(I))) {
+ return all_of(I->operands(), [=](const Value *Op) {
+ return impliesPoison(Op, V, Depth + 1);
+ });
+ }
+ return false;
+}
+
+bool llvm::impliesPoison(const Value *ValAssumedPoison, const Value *V) {
+ return ::impliesPoison(ValAssumedPoison, V, /* Depth */ 0);
+}
+
+static bool programUndefinedIfUndefOrPoison(const Value *V,
+ bool PoisonOnly);
+
+static bool isGuaranteedNotToBeUndefOrPoison(const Value *V,
+ AssumptionCache *AC,
+ const Instruction *CtxI,
+ const DominatorTree *DT,
+ unsigned Depth, bool PoisonOnly) {
+ if (Depth >= MaxAnalysisRecursionDepth)
+ return false;
+
+ if (isa<MetadataAsValue>(V))
+ return false;
+
+ if (const auto *A = dyn_cast<Argument>(V)) {
+ if (A->hasAttribute(Attribute::NoUndef))
+ return true;
+ }
+
if (auto *C = dyn_cast<Constant>(V)) {
- if (isa<UndefValue>(C))
- return PoisonOnly && !isa<PoisonValue>(C);
+ if (isa<UndefValue>(C))
+ return PoisonOnly && !isa<PoisonValue>(C);
if (isa<ConstantInt>(C) || isa<GlobalVariable>(C) || isa<ConstantFP>(V) ||
isa<ConstantPointerNull>(C) || isa<Function>(C))
return true;
- if (C->getType()->isVectorTy() && !isa<ConstantExpr>(C))
- return (PoisonOnly ? !C->containsPoisonElement()
- : !C->containsUndefOrPoisonElement()) &&
- !C->containsConstantExpression();
+ if (C->getType()->isVectorTy() && !isa<ConstantExpr>(C))
+ return (PoisonOnly ? !C->containsPoisonElement()
+ : !C->containsUndefOrPoisonElement()) &&
+ !C->containsConstantExpression();
}
// Strip cast operations from a pointer value.
@@ -4895,45 +4895,45 @@ static bool isGuaranteedNotToBeUndefOrPoison(const Value *V,
return true;
auto OpCheck = [&](const Value *V) {
- return isGuaranteedNotToBeUndefOrPoison(V, AC, CtxI, DT, Depth + 1,
- PoisonOnly);
+ return isGuaranteedNotToBeUndefOrPoison(V, AC, CtxI, DT, Depth + 1,
+ PoisonOnly);
};
- if (auto *Opr = dyn_cast<Operator>(V)) {
- // If the value is a freeze instruction, then it can never
- // be undef or poison.
- if (isa<FreezeInst>(V))
- return true;
-
- if (const auto *CB = dyn_cast<CallBase>(V)) {
- if (CB->hasRetAttr(Attribute::NoUndef))
+ if (auto *Opr = dyn_cast<Operator>(V)) {
+ // If the value is a freeze instruction, then it can never
+ // be undef or poison.
+ if (isa<FreezeInst>(V))
+ return true;
+
+ if (const auto *CB = dyn_cast<CallBase>(V)) {
+ if (CB->hasRetAttr(Attribute::NoUndef))
return true;
}
-
- if (const auto *PN = dyn_cast<PHINode>(V)) {
- unsigned Num = PN->getNumIncomingValues();
- bool IsWellDefined = true;
- for (unsigned i = 0; i < Num; ++i) {
- auto *TI = PN->getIncomingBlock(i)->getTerminator();
- if (!isGuaranteedNotToBeUndefOrPoison(PN->getIncomingValue(i), AC, TI,
- DT, Depth + 1, PoisonOnly)) {
- IsWellDefined = false;
- break;
- }
- }
- if (IsWellDefined)
+
+ if (const auto *PN = dyn_cast<PHINode>(V)) {
+ unsigned Num = PN->getNumIncomingValues();
+ bool IsWellDefined = true;
+ for (unsigned i = 0; i < Num; ++i) {
+ auto *TI = PN->getIncomingBlock(i)->getTerminator();
+ if (!isGuaranteedNotToBeUndefOrPoison(PN->getIncomingValue(i), AC, TI,
+ DT, Depth + 1, PoisonOnly)) {
+ IsWellDefined = false;
+ break;
+ }
+ }
+ if (IsWellDefined)
return true;
- } else if (!canCreateUndefOrPoison(Opr) && all_of(Opr->operands(), OpCheck))
+ } else if (!canCreateUndefOrPoison(Opr) && all_of(Opr->operands(), OpCheck))
return true;
}
- if (auto *I = dyn_cast<LoadInst>(V))
- if (I->getMetadata(LLVMContext::MD_noundef))
- return true;
-
- if (programUndefinedIfUndefOrPoison(V, PoisonOnly))
- return true;
-
+ if (auto *I = dyn_cast<LoadInst>(V))
+ if (I->getMetadata(LLVMContext::MD_noundef))
+ return true;
+
+ if (programUndefinedIfUndefOrPoison(V, PoisonOnly))
+ return true;
+
// CxtI may be null or a cloned instruction.
if (!CtxI || !CtxI->getParent() || !DT)
return false;
@@ -4952,48 +4952,48 @@ static bool isGuaranteedNotToBeUndefOrPoison(const Value *V,
while (Dominator) {
auto *TI = Dominator->getBlock()->getTerminator();
- Value *Cond = nullptr;
+ Value *Cond = nullptr;
if (auto BI = dyn_cast<BranchInst>(TI)) {
- if (BI->isConditional())
- Cond = BI->getCondition();
+ if (BI->isConditional())
+ Cond = BI->getCondition();
} else if (auto SI = dyn_cast<SwitchInst>(TI)) {
- Cond = SI->getCondition();
- }
-
- if (Cond) {
- if (Cond == V)
+ Cond = SI->getCondition();
+ }
+
+ if (Cond) {
+ if (Cond == V)
return true;
- else if (PoisonOnly && isa<Operator>(Cond)) {
- // For poison, we can analyze further
- auto *Opr = cast<Operator>(Cond);
- if (propagatesPoison(Opr) && is_contained(Opr->operand_values(), V))
- return true;
- }
+ else if (PoisonOnly && isa<Operator>(Cond)) {
+ // For poison, we can analyze further
+ auto *Opr = cast<Operator>(Cond);
+ if (propagatesPoison(Opr) && is_contained(Opr->operand_values(), V))
+ return true;
+ }
}
Dominator = Dominator->getIDom();
}
- SmallVector<Attribute::AttrKind, 2> AttrKinds{Attribute::NoUndef};
- if (getKnowledgeValidInContext(V, AttrKinds, CtxI, DT, AC))
- return true;
-
+ SmallVector<Attribute::AttrKind, 2> AttrKinds{Attribute::NoUndef};
+ if (getKnowledgeValidInContext(V, AttrKinds, CtxI, DT, AC))
+ return true;
+
return false;
}
-bool llvm::isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC,
- const Instruction *CtxI,
- const DominatorTree *DT,
- unsigned Depth) {
- return ::isGuaranteedNotToBeUndefOrPoison(V, AC, CtxI, DT, Depth, false);
-}
-
-bool llvm::isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC,
- const Instruction *CtxI,
- const DominatorTree *DT, unsigned Depth) {
- return ::isGuaranteedNotToBeUndefOrPoison(V, AC, CtxI, DT, Depth, true);
-}
-
+bool llvm::isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC,
+ const Instruction *CtxI,
+ const DominatorTree *DT,
+ unsigned Depth) {
+ return ::isGuaranteedNotToBeUndefOrPoison(V, AC, CtxI, DT, Depth, false);
+}
+
+bool llvm::isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC,
+ const Instruction *CtxI,
+ const DominatorTree *DT, unsigned Depth) {
+ return ::isGuaranteedNotToBeUndefOrPoison(V, AC, CtxI, DT, Depth, true);
+}
+
OverflowResult llvm::computeOverflowForSignedAdd(const AddOperator *Add,
const DataLayout &DL,
AssumptionCache *AC,
@@ -5023,9 +5023,9 @@ bool llvm::isGuaranteedToTransferExecutionToSuccessor(const Instruction *I) {
if (isa<UnreachableInst>(I))
return false;
- // An instruction that returns without throwing must transfer control flow
- // to a successor.
- return !I->mayThrow() && I->willReturn();
+ // An instruction that returns without throwing must transfer control flow
+ // to a successor.
+ return !I->mayThrow() && I->willReturn();
}
bool llvm::isGuaranteedToTransferExecutionToSuccessor(const BasicBlock *BB) {
@@ -5052,7 +5052,7 @@ bool llvm::isGuaranteedToExecuteForEveryIteration(const Instruction *I,
llvm_unreachable("Instruction not contained in its own parent basic block.");
}
-bool llvm::propagatesPoison(const Operator *I) {
+bool llvm::propagatesPoison(const Operator *I) {
switch (I->getOpcode()) {
case Instruction::Freeze:
case Instruction::Select:
@@ -5073,141 +5073,141 @@ bool llvm::propagatesPoison(const Operator *I) {
}
}
-void llvm::getGuaranteedNonPoisonOps(const Instruction *I,
- SmallPtrSetImpl<const Value *> &Operands) {
+void llvm::getGuaranteedNonPoisonOps(const Instruction *I,
+ SmallPtrSetImpl<const Value *> &Operands) {
switch (I->getOpcode()) {
case Instruction::Store:
- Operands.insert(cast<StoreInst>(I)->getPointerOperand());
- break;
+ Operands.insert(cast<StoreInst>(I)->getPointerOperand());
+ break;
case Instruction::Load:
- Operands.insert(cast<LoadInst>(I)->getPointerOperand());
- break;
+ Operands.insert(cast<LoadInst>(I)->getPointerOperand());
+ break;
case Instruction::AtomicCmpXchg:
- Operands.insert(cast<AtomicCmpXchgInst>(I)->getPointerOperand());
- break;
+ Operands.insert(cast<AtomicCmpXchgInst>(I)->getPointerOperand());
+ break;
case Instruction::AtomicRMW:
- Operands.insert(cast<AtomicRMWInst>(I)->getPointerOperand());
- break;
+ Operands.insert(cast<AtomicRMWInst>(I)->getPointerOperand());
+ break;
case Instruction::UDiv:
case Instruction::SDiv:
case Instruction::URem:
case Instruction::SRem:
- Operands.insert(I->getOperand(1));
- break;
+ Operands.insert(I->getOperand(1));
+ break;
case Instruction::Call:
- case Instruction::Invoke: {
- const CallBase *CB = cast<CallBase>(I);
- if (CB->isIndirectCall())
- Operands.insert(CB->getCalledOperand());
- for (unsigned i = 0; i < CB->arg_size(); ++i) {
- if (CB->paramHasAttr(i, Attribute::NoUndef))
- Operands.insert(CB->getArgOperand(i));
+ case Instruction::Invoke: {
+ const CallBase *CB = cast<CallBase>(I);
+ if (CB->isIndirectCall())
+ Operands.insert(CB->getCalledOperand());
+ for (unsigned i = 0; i < CB->arg_size(); ++i) {
+ if (CB->paramHasAttr(i, Attribute::NoUndef))
+ Operands.insert(CB->getArgOperand(i));
}
- break;
- }
+ break;
+ }
default:
- break;
+ break;
}
}
bool llvm::mustTriggerUB(const Instruction *I,
const SmallSet<const Value *, 16>& KnownPoison) {
- SmallPtrSet<const Value *, 4> NonPoisonOps;
- getGuaranteedNonPoisonOps(I, NonPoisonOps);
-
- for (const auto *V : NonPoisonOps)
- if (KnownPoison.count(V))
- return true;
-
- return false;
-}
-
-static bool programUndefinedIfUndefOrPoison(const Value *V,
- bool PoisonOnly) {
- // We currently only look for uses of values within the same basic
+ SmallPtrSet<const Value *, 4> NonPoisonOps;
+ getGuaranteedNonPoisonOps(I, NonPoisonOps);
+
+ for (const auto *V : NonPoisonOps)
+ if (KnownPoison.count(V))
+ return true;
+
+ return false;
+}
+
+static bool programUndefinedIfUndefOrPoison(const Value *V,
+ bool PoisonOnly) {
+ // We currently only look for uses of values within the same basic
// block, as that makes it easier to guarantee that the uses will be
- // executed given that Inst is executed.
+ // executed given that Inst is executed.
//
// FIXME: Expand this to consider uses beyond the same basic block. To do
// this, look out for the distinction between post-dominance and strong
// post-dominance.
- const BasicBlock *BB = nullptr;
- BasicBlock::const_iterator Begin;
- if (const auto *Inst = dyn_cast<Instruction>(V)) {
- BB = Inst->getParent();
- Begin = Inst->getIterator();
- Begin++;
- } else if (const auto *Arg = dyn_cast<Argument>(V)) {
- BB = &Arg->getParent()->getEntryBlock();
- Begin = BB->begin();
- } else {
- return false;
- }
-
- // Limit number of instructions we look at, to avoid scanning through large
- // blocks. The current limit is chosen arbitrarily.
- unsigned ScanLimit = 32;
- BasicBlock::const_iterator End = BB->end();
-
- if (!PoisonOnly) {
- // Be conservative & just check whether a value is passed to a noundef
- // argument.
- // Instructions that raise UB with a poison operand are well-defined
- // or have unclear semantics when the input is partially undef.
- // For example, 'udiv x, (undef | 1)' isn't UB.
-
- for (auto &I : make_range(Begin, End)) {
- if (isa<DbgInfoIntrinsic>(I))
- continue;
- if (--ScanLimit == 0)
- break;
-
- if (const auto *CB = dyn_cast<CallBase>(&I)) {
- for (unsigned i = 0; i < CB->arg_size(); ++i) {
- if (CB->paramHasAttr(i, Attribute::NoUndef) &&
- CB->getArgOperand(i) == V)
- return true;
- }
- }
- if (!isGuaranteedToTransferExecutionToSuccessor(&I))
- break;
- }
- return false;
- }
-
- // Set of instructions that we have proved will yield poison if Inst
+ const BasicBlock *BB = nullptr;
+ BasicBlock::const_iterator Begin;
+ if (const auto *Inst = dyn_cast<Instruction>(V)) {
+ BB = Inst->getParent();
+ Begin = Inst->getIterator();
+ Begin++;
+ } else if (const auto *Arg = dyn_cast<Argument>(V)) {
+ BB = &Arg->getParent()->getEntryBlock();
+ Begin = BB->begin();
+ } else {
+ return false;
+ }
+
+ // Limit number of instructions we look at, to avoid scanning through large
+ // blocks. The current limit is chosen arbitrarily.
+ unsigned ScanLimit = 32;
+ BasicBlock::const_iterator End = BB->end();
+
+ if (!PoisonOnly) {
+ // Be conservative & just check whether a value is passed to a noundef
+ // argument.
+ // Instructions that raise UB with a poison operand are well-defined
+ // or have unclear semantics when the input is partially undef.
+ // For example, 'udiv x, (undef | 1)' isn't UB.
+
+ for (auto &I : make_range(Begin, End)) {
+ if (isa<DbgInfoIntrinsic>(I))
+ continue;
+ if (--ScanLimit == 0)
+ break;
+
+ if (const auto *CB = dyn_cast<CallBase>(&I)) {
+ for (unsigned i = 0; i < CB->arg_size(); ++i) {
+ if (CB->paramHasAttr(i, Attribute::NoUndef) &&
+ CB->getArgOperand(i) == V)
+ return true;
+ }
+ }
+ if (!isGuaranteedToTransferExecutionToSuccessor(&I))
+ break;
+ }
+ return false;
+ }
+
+ // Set of instructions that we have proved will yield poison if Inst
// does.
SmallSet<const Value *, 16> YieldsPoison;
SmallSet<const BasicBlock *, 4> Visited;
- YieldsPoison.insert(V);
- auto Propagate = [&](const User *User) {
- if (propagatesPoison(cast<Operator>(User)))
- YieldsPoison.insert(User);
- };
- for_each(V->users(), Propagate);
- Visited.insert(BB);
+ YieldsPoison.insert(V);
+ auto Propagate = [&](const User *User) {
+ if (propagatesPoison(cast<Operator>(User)))
+ YieldsPoison.insert(User);
+ };
+ for_each(V->users(), Propagate);
+ Visited.insert(BB);
- while (true) {
+ while (true) {
for (auto &I : make_range(Begin, End)) {
- if (isa<DbgInfoIntrinsic>(I))
- continue;
- if (--ScanLimit == 0)
- return false;
- if (mustTriggerUB(&I, YieldsPoison))
- return true;
- if (!isGuaranteedToTransferExecutionToSuccessor(&I))
- return false;
+ if (isa<DbgInfoIntrinsic>(I))
+ continue;
+ if (--ScanLimit == 0)
+ return false;
+ if (mustTriggerUB(&I, YieldsPoison))
+ return true;
+ if (!isGuaranteedToTransferExecutionToSuccessor(&I))
+ return false;
// Mark poison that propagates from I through uses of I.
- if (YieldsPoison.count(&I))
- for_each(I.users(), Propagate);
+ if (YieldsPoison.count(&I))
+ for_each(I.users(), Propagate);
}
if (auto *NextBB = BB->getSingleSuccessor()) {
@@ -5224,14 +5224,14 @@ static bool programUndefinedIfUndefOrPoison(const Value *V,
return false;
}
-bool llvm::programUndefinedIfUndefOrPoison(const Instruction *Inst) {
- return ::programUndefinedIfUndefOrPoison(Inst, false);
-}
-
-bool llvm::programUndefinedIfPoison(const Instruction *Inst) {
- return ::programUndefinedIfUndefOrPoison(Inst, true);
-}
-
+bool llvm::programUndefinedIfUndefOrPoison(const Instruction *Inst) {
+ return ::programUndefinedIfUndefOrPoison(Inst, false);
+}
+
+bool llvm::programUndefinedIfPoison(const Instruction *Inst) {
+ return ::programUndefinedIfUndefOrPoison(Inst, true);
+}
+
static bool isKnownNonNaN(const Value *V, FastMathFlags FMF) {
if (FMF.noNaNs())
return true;
@@ -5594,10 +5594,10 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred,
// elements because those can not be back-propagated for analysis.
Value *OutputZeroVal = nullptr;
if (match(TrueVal, m_AnyZeroFP()) && !match(FalseVal, m_AnyZeroFP()) &&
- !cast<Constant>(TrueVal)->containsUndefOrPoisonElement())
+ !cast<Constant>(TrueVal)->containsUndefOrPoisonElement())
OutputZeroVal = TrueVal;
else if (match(FalseVal, m_AnyZeroFP()) && !match(TrueVal, m_AnyZeroFP()) &&
- !cast<Constant>(FalseVal)->containsUndefOrPoisonElement())
+ !cast<Constant>(FalseVal)->containsUndefOrPoisonElement())
OutputZeroVal = FalseVal;
if (OutputZeroVal) {
@@ -5874,7 +5874,7 @@ static Value *lookThroughCast(CmpInst *CmpI, Value *V1, Value *V2,
SelectPatternResult llvm::matchSelectPattern(Value *V, Value *&LHS, Value *&RHS,
Instruction::CastOps *CastOp,
unsigned Depth) {
- if (Depth >= MaxAnalysisRecursionDepth)
+ if (Depth >= MaxAnalysisRecursionDepth)
return {SPF_UNKNOWN, SPNB_NA, false};
SelectInst *SI = dyn_cast<SelectInst>(V);
@@ -5953,46 +5953,46 @@ CmpInst::Predicate llvm::getInverseMinMaxPred(SelectPatternFlavor SPF) {
return getMinMaxPred(getInverseMinMaxFlavor(SPF));
}
-std::pair<Intrinsic::ID, bool>
-llvm::canConvertToMinOrMaxIntrinsic(ArrayRef<Value *> VL) {
- // Check if VL contains select instructions that can be folded into a min/max
- // vector intrinsic and return the intrinsic if it is possible.
- // TODO: Support floating point min/max.
- bool AllCmpSingleUse = true;
- SelectPatternResult SelectPattern;
- SelectPattern.Flavor = SPF_UNKNOWN;
- if (all_of(VL, [&SelectPattern, &AllCmpSingleUse](Value *I) {
- Value *LHS, *RHS;
- auto CurrentPattern = matchSelectPattern(I, LHS, RHS);
- if (!SelectPatternResult::isMinOrMax(CurrentPattern.Flavor) ||
- CurrentPattern.Flavor == SPF_FMINNUM ||
- CurrentPattern.Flavor == SPF_FMAXNUM ||
- !I->getType()->isIntOrIntVectorTy())
- return false;
- if (SelectPattern.Flavor != SPF_UNKNOWN &&
- SelectPattern.Flavor != CurrentPattern.Flavor)
- return false;
- SelectPattern = CurrentPattern;
- AllCmpSingleUse &=
- match(I, m_Select(m_OneUse(m_Value()), m_Value(), m_Value()));
- return true;
- })) {
- switch (SelectPattern.Flavor) {
- case SPF_SMIN:
- return {Intrinsic::smin, AllCmpSingleUse};
- case SPF_UMIN:
- return {Intrinsic::umin, AllCmpSingleUse};
- case SPF_SMAX:
- return {Intrinsic::smax, AllCmpSingleUse};
- case SPF_UMAX:
- return {Intrinsic::umax, AllCmpSingleUse};
- default:
- llvm_unreachable("unexpected select pattern flavor");
- }
- }
- return {Intrinsic::not_intrinsic, false};
-}
-
+std::pair<Intrinsic::ID, bool>
+llvm::canConvertToMinOrMaxIntrinsic(ArrayRef<Value *> VL) {
+ // Check if VL contains select instructions that can be folded into a min/max
+ // vector intrinsic and return the intrinsic if it is possible.
+ // TODO: Support floating point min/max.
+ bool AllCmpSingleUse = true;
+ SelectPatternResult SelectPattern;
+ SelectPattern.Flavor = SPF_UNKNOWN;
+ if (all_of(VL, [&SelectPattern, &AllCmpSingleUse](Value *I) {
+ Value *LHS, *RHS;
+ auto CurrentPattern = matchSelectPattern(I, LHS, RHS);
+ if (!SelectPatternResult::isMinOrMax(CurrentPattern.Flavor) ||
+ CurrentPattern.Flavor == SPF_FMINNUM ||
+ CurrentPattern.Flavor == SPF_FMAXNUM ||
+ !I->getType()->isIntOrIntVectorTy())
+ return false;
+ if (SelectPattern.Flavor != SPF_UNKNOWN &&
+ SelectPattern.Flavor != CurrentPattern.Flavor)
+ return false;
+ SelectPattern = CurrentPattern;
+ AllCmpSingleUse &=
+ match(I, m_Select(m_OneUse(m_Value()), m_Value(), m_Value()));
+ return true;
+ })) {
+ switch (SelectPattern.Flavor) {
+ case SPF_SMIN:
+ return {Intrinsic::smin, AllCmpSingleUse};
+ case SPF_UMIN:
+ return {Intrinsic::umin, AllCmpSingleUse};
+ case SPF_SMAX:
+ return {Intrinsic::smax, AllCmpSingleUse};
+ case SPF_UMAX:
+ return {Intrinsic::umax, AllCmpSingleUse};
+ default:
+ llvm_unreachable("unexpected select pattern flavor");
+ }
+ }
+ return {Intrinsic::not_intrinsic, false};
+}
+
/// Return true if "icmp Pred LHS RHS" is always true.
static bool isTruePredicate(CmpInst::Predicate Pred, const Value *LHS,
const Value *RHS, const DataLayout &DL,
@@ -6172,25 +6172,25 @@ static Optional<bool> isImpliedCondICmps(const ICmpInst *LHS,
/// Return true if LHS implies RHS is true. Return false if LHS implies RHS is
/// false. Otherwise, return None if we can't infer anything. We expect the
-/// RHS to be an icmp and the LHS to be an 'and', 'or', or a 'select' instruction.
+/// RHS to be an icmp and the LHS to be an 'and', 'or', or a 'select' instruction.
static Optional<bool>
-isImpliedCondAndOr(const Instruction *LHS, CmpInst::Predicate RHSPred,
+isImpliedCondAndOr(const Instruction *LHS, CmpInst::Predicate RHSPred,
const Value *RHSOp0, const Value *RHSOp1,
const DataLayout &DL, bool LHSIsTrue, unsigned Depth) {
- // The LHS must be an 'or', 'and', or a 'select' instruction.
+ // The LHS must be an 'or', 'and', or a 'select' instruction.
assert((LHS->getOpcode() == Instruction::And ||
- LHS->getOpcode() == Instruction::Or ||
- LHS->getOpcode() == Instruction::Select) &&
- "Expected LHS to be 'and', 'or', or 'select'.");
+ LHS->getOpcode() == Instruction::Or ||
+ LHS->getOpcode() == Instruction::Select) &&
+ "Expected LHS to be 'and', 'or', or 'select'.");
- assert(Depth <= MaxAnalysisRecursionDepth && "Hit recursion limit");
+ assert(Depth <= MaxAnalysisRecursionDepth && "Hit recursion limit");
// If the result of an 'or' is false, then we know both legs of the 'or' are
// false. Similarly, if the result of an 'and' is true, then we know both
// legs of the 'and' are true.
- const Value *ALHS, *ARHS;
- if ((!LHSIsTrue && match(LHS, m_LogicalOr(m_Value(ALHS), m_Value(ARHS)))) ||
- (LHSIsTrue && match(LHS, m_LogicalAnd(m_Value(ALHS), m_Value(ARHS))))) {
+ const Value *ALHS, *ARHS;
+ if ((!LHSIsTrue && match(LHS, m_LogicalOr(m_Value(ALHS), m_Value(ARHS)))) ||
+ (LHSIsTrue && match(LHS, m_LogicalAnd(m_Value(ALHS), m_Value(ARHS))))) {
// FIXME: Make this non-recursion.
if (Optional<bool> Implication = isImpliedCondition(
ALHS, RHSPred, RHSOp0, RHSOp1, DL, LHSIsTrue, Depth + 1))
@@ -6208,7 +6208,7 @@ llvm::isImpliedCondition(const Value *LHS, CmpInst::Predicate RHSPred,
const Value *RHSOp0, const Value *RHSOp1,
const DataLayout &DL, bool LHSIsTrue, unsigned Depth) {
// Bail out when we hit the limit.
- if (Depth == MaxAnalysisRecursionDepth)
+ if (Depth == MaxAnalysisRecursionDepth)
return None;
// A mismatch occurs when we compare a scalar cmp to a vector cmp, for
@@ -6231,14 +6231,14 @@ llvm::isImpliedCondition(const Value *LHS, CmpInst::Predicate RHSPred,
return isImpliedCondICmps(LHSCmp, RHSPred, RHSOp0, RHSOp1, DL, LHSIsTrue,
Depth);
- /// The LHS should be an 'or', 'and', or a 'select' instruction. We expect
- /// the RHS to be an icmp.
- /// FIXME: Add support for and/or/select on the RHS.
- if (const Instruction *LHSI = dyn_cast<Instruction>(LHS)) {
- if ((LHSI->getOpcode() == Instruction::And ||
- LHSI->getOpcode() == Instruction::Or ||
- LHSI->getOpcode() == Instruction::Select))
- return isImpliedCondAndOr(LHSI, RHSPred, RHSOp0, RHSOp1, DL, LHSIsTrue,
+ /// The LHS should be an 'or', 'and', or a 'select' instruction. We expect
+ /// the RHS to be an icmp.
+ /// FIXME: Add support for and/or/select on the RHS.
+ if (const Instruction *LHSI = dyn_cast<Instruction>(LHS)) {
+ if ((LHSI->getOpcode() == Instruction::And ||
+ LHSI->getOpcode() == Instruction::Or ||
+ LHSI->getOpcode() == Instruction::Select))
+ return isImpliedCondAndOr(LHSI, RHSPred, RHSOp0, RHSOp1, DL, LHSIsTrue,
Depth);
}
return None;
@@ -6471,13 +6471,13 @@ static void setLimitsForIntrinsic(const IntrinsicInst &II, APInt &Lower,
unsigned Width = Lower.getBitWidth();
const APInt *C;
switch (II.getIntrinsicID()) {
- case Intrinsic::ctpop:
- case Intrinsic::ctlz:
- case Intrinsic::cttz:
- // Maximum of set/clear bits is the bit width.
- assert(Lower == 0 && "Expected lower bound to be zero");
- Upper = Width + 1;
- break;
+ case Intrinsic::ctpop:
+ case Intrinsic::ctlz:
+ case Intrinsic::cttz:
+ // Maximum of set/clear bits is the bit width.
+ assert(Lower == 0 && "Expected lower bound to be zero");
+ Upper = Width + 1;
+ break;
case Intrinsic::uadd_sat:
// uadd.sat(x, C) produces [C, UINT_MAX].
if (match(II.getOperand(0), m_APInt(C)) ||
@@ -6529,41 +6529,41 @@ static void setLimitsForIntrinsic(const IntrinsicInst &II, APInt &Lower,
}
}
break;
- case Intrinsic::umin:
- case Intrinsic::umax:
- case Intrinsic::smin:
- case Intrinsic::smax:
- if (!match(II.getOperand(0), m_APInt(C)) &&
- !match(II.getOperand(1), m_APInt(C)))
- break;
-
- switch (II.getIntrinsicID()) {
- case Intrinsic::umin:
- Upper = *C + 1;
- break;
- case Intrinsic::umax:
- Lower = *C;
- break;
- case Intrinsic::smin:
- Lower = APInt::getSignedMinValue(Width);
- Upper = *C + 1;
- break;
- case Intrinsic::smax:
- Lower = *C;
- Upper = APInt::getSignedMaxValue(Width) + 1;
- break;
- default:
- llvm_unreachable("Must be min/max intrinsic");
- }
- break;
- case Intrinsic::abs:
- // If abs of SIGNED_MIN is poison, then the result is [0..SIGNED_MAX],
- // otherwise it is [0..SIGNED_MIN], as -SIGNED_MIN == SIGNED_MIN.
- if (match(II.getOperand(1), m_One()))
- Upper = APInt::getSignedMaxValue(Width) + 1;
- else
- Upper = APInt::getSignedMinValue(Width) + 1;
- break;
+ case Intrinsic::umin:
+ case Intrinsic::umax:
+ case Intrinsic::smin:
+ case Intrinsic::smax:
+ if (!match(II.getOperand(0), m_APInt(C)) &&
+ !match(II.getOperand(1), m_APInt(C)))
+ break;
+
+ switch (II.getIntrinsicID()) {
+ case Intrinsic::umin:
+ Upper = *C + 1;
+ break;
+ case Intrinsic::umax:
+ Lower = *C;
+ break;
+ case Intrinsic::smin:
+ Lower = APInt::getSignedMinValue(Width);
+ Upper = *C + 1;
+ break;
+ case Intrinsic::smax:
+ Lower = *C;
+ Upper = APInt::getSignedMaxValue(Width) + 1;
+ break;
+ default:
+ llvm_unreachable("Must be min/max intrinsic");
+ }
+ break;
+ case Intrinsic::abs:
+ // If abs of SIGNED_MIN is poison, then the result is [0..SIGNED_MAX],
+ // otherwise it is [0..SIGNED_MIN], as -SIGNED_MIN == SIGNED_MIN.
+ if (match(II.getOperand(1), m_One()))
+ Upper = APInt::getSignedMaxValue(Width) + 1;
+ else
+ Upper = APInt::getSignedMinValue(Width) + 1;
+ break;
default:
break;
}
@@ -6628,7 +6628,7 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool UseInstrInfo,
unsigned Depth) {
assert(V->getType()->isIntOrIntVectorTy() && "Expected integer instruction");
- if (Depth == MaxAnalysisRecursionDepth)
+ if (Depth == MaxAnalysisRecursionDepth)
return ConstantRange::getFull(V->getType()->getScalarSizeInBits());
const APInt *C;
diff --git a/contrib/libs/llvm12/lib/Analysis/VectorUtils.cpp b/contrib/libs/llvm12/lib/Analysis/VectorUtils.cpp
index 1c7a473bcf..9a4c96b6f7 100644
--- a/contrib/libs/llvm12/lib/Analysis/VectorUtils.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/VectorUtils.cpp
@@ -43,18 +43,18 @@ static cl::opt<unsigned> MaxInterleaveGroupFactor(
/// hasVectorInstrinsicScalarOpd).
bool llvm::isTriviallyVectorizable(Intrinsic::ID ID) {
switch (ID) {
- case Intrinsic::abs: // Begin integer bit-manipulation.
- case Intrinsic::bswap:
+ case Intrinsic::abs: // Begin integer bit-manipulation.
+ case Intrinsic::bswap:
case Intrinsic::bitreverse:
case Intrinsic::ctpop:
case Intrinsic::ctlz:
case Intrinsic::cttz:
case Intrinsic::fshl:
case Intrinsic::fshr:
- case Intrinsic::smax:
- case Intrinsic::smin:
- case Intrinsic::umax:
- case Intrinsic::umin:
+ case Intrinsic::smax:
+ case Intrinsic::smin:
+ case Intrinsic::umax:
+ case Intrinsic::umin:
case Intrinsic::sadd_sat:
case Intrinsic::ssub_sat:
case Intrinsic::uadd_sat:
@@ -99,7 +99,7 @@ bool llvm::isTriviallyVectorizable(Intrinsic::ID ID) {
bool llvm::hasVectorInstrinsicScalarOpd(Intrinsic::ID ID,
unsigned ScalarOpdIdx) {
switch (ID) {
- case Intrinsic::abs:
+ case Intrinsic::abs:
case Intrinsic::ctlz:
case Intrinsic::cttz:
case Intrinsic::powi:
@@ -125,8 +125,8 @@ Intrinsic::ID llvm::getVectorIntrinsicIDForCall(const CallInst *CI,
if (isTriviallyVectorizable(ID) || ID == Intrinsic::lifetime_start ||
ID == Intrinsic::lifetime_end || ID == Intrinsic::assume ||
- ID == Intrinsic::experimental_noalias_scope_decl ||
- ID == Intrinsic::sideeffect || ID == Intrinsic::pseudoprobe)
+ ID == Intrinsic::experimental_noalias_scope_decl ||
+ ID == Intrinsic::sideeffect || ID == Intrinsic::pseudoprobe)
return ID;
return Intrinsic::not_intrinsic;
}
@@ -137,7 +137,7 @@ Intrinsic::ID llvm::getVectorIntrinsicIDForCall(const CallInst *CI,
unsigned llvm::getGEPInductionOperand(const GetElementPtrInst *Gep) {
const DataLayout &DL = Gep->getModule()->getDataLayout();
unsigned LastOperand = Gep->getNumOperands() - 1;
- TypeSize GEPAllocSize = DL.getTypeAllocSize(Gep->getResultElementType());
+ TypeSize GEPAllocSize = DL.getTypeAllocSize(Gep->getResultElementType());
// Walk backwards and try to peel off zeros.
while (LastOperand > 1 && match(Gep->getOperand(LastOperand), m_Zero())) {
@@ -209,7 +209,7 @@ Value *llvm::getStrideFromPointer(Value *Ptr, ScalarEvolution *SE, Loop *Lp) {
if (Ptr != OrigPtr)
// Strip off casts.
- while (const SCEVIntegralCastExpr *C = dyn_cast<SCEVIntegralCastExpr>(V))
+ while (const SCEVIntegralCastExpr *C = dyn_cast<SCEVIntegralCastExpr>(V))
V = C->getOperand();
const SCEVAddRecExpr *S = dyn_cast<SCEVAddRecExpr>(V);
@@ -242,7 +242,7 @@ Value *llvm::getStrideFromPointer(Value *Ptr, ScalarEvolution *SE, Loop *Lp) {
// Strip off casts.
Type *StripedOffRecurrenceCast = nullptr;
- if (const SCEVIntegralCastExpr *C = dyn_cast<SCEVIntegralCastExpr>(V)) {
+ if (const SCEVIntegralCastExpr *C = dyn_cast<SCEVIntegralCastExpr>(V)) {
StripedOffRecurrenceCast = C->getType();
V = C->getOperand();
}
@@ -291,10 +291,10 @@ Value *llvm::findScalarElement(Value *V, unsigned EltNo) {
if (EltNo == IIElt)
return III->getOperand(1);
- // Guard against infinite loop on malformed, unreachable IR.
- if (III == III->getOperand(0))
- return nullptr;
-
+ // Guard against infinite loop on malformed, unreachable IR.
+ if (III == III->getOperand(0))
+ return nullptr;
+
// Otherwise, the insertelement doesn't modify the value, recurse on its
// vector input.
return findScalarElement(III->getOperand(0), EltNo);
@@ -347,7 +347,7 @@ int llvm::getSplatIndex(ArrayRef<int> Mask) {
/// This function is not fully general. It checks only 2 cases:
/// the input value is (1) a splat constant vector or (2) a sequence
/// of instructions that broadcasts a scalar at element 0.
-Value *llvm::getSplatValue(const Value *V) {
+Value *llvm::getSplatValue(const Value *V) {
if (isa<VectorType>(V->getType()))
if (auto *C = dyn_cast<Constant>(V))
return C->getSplatValue();
@@ -363,7 +363,7 @@ Value *llvm::getSplatValue(const Value *V) {
}
bool llvm::isSplatValue(const Value *V, int Index, unsigned Depth) {
- assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
+ assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
if (isa<VectorType>(V->getType())) {
if (isa<UndefValue>(V))
@@ -390,7 +390,7 @@ bool llvm::isSplatValue(const Value *V, int Index, unsigned Depth) {
}
// The remaining tests are all recursive, so bail out if we hit the limit.
- if (Depth++ == MaxAnalysisRecursionDepth)
+ if (Depth++ == MaxAnalysisRecursionDepth)
return false;
// If both operands of a binop are splats, the result is a splat.
@@ -421,7 +421,7 @@ void llvm::narrowShuffleMaskElts(int Scale, ArrayRef<int> Mask,
ScaledMask.clear();
for (int MaskElt : Mask) {
if (MaskElt >= 0) {
- assert(((uint64_t)Scale * MaskElt + (Scale - 1)) <= INT32_MAX &&
+ assert(((uint64_t)Scale * MaskElt + (Scale - 1)) <= INT32_MAX &&
"Overflowed 32-bits");
}
for (int SliceElt = 0; SliceElt != Scale; ++SliceElt)
@@ -823,14 +823,14 @@ static Value *concatenateTwoVectors(IRBuilderBase &Builder, Value *V1,
VecTy1->getScalarType() == VecTy2->getScalarType() &&
"Expect two vectors with the same element type");
- unsigned NumElts1 = cast<FixedVectorType>(VecTy1)->getNumElements();
- unsigned NumElts2 = cast<FixedVectorType>(VecTy2)->getNumElements();
+ unsigned NumElts1 = cast<FixedVectorType>(VecTy1)->getNumElements();
+ unsigned NumElts2 = cast<FixedVectorType>(VecTy2)->getNumElements();
assert(NumElts1 >= NumElts2 && "Unexpect the first vector has less elements");
if (NumElts1 > NumElts2) {
// Extend with UNDEFs.
V2 = Builder.CreateShuffleVector(
- V2, createSequentialMask(0, NumElts2, NumElts1 - NumElts2));
+ V2, createSequentialMask(0, NumElts2, NumElts1 - NumElts2));
}
return Builder.CreateShuffleVector(
@@ -866,22 +866,22 @@ Value *llvm::concatenateVectors(IRBuilderBase &Builder,
}
bool llvm::maskIsAllZeroOrUndef(Value *Mask) {
- assert(isa<VectorType>(Mask->getType()) &&
- isa<IntegerType>(Mask->getType()->getScalarType()) &&
- cast<IntegerType>(Mask->getType()->getScalarType())->getBitWidth() ==
- 1 &&
- "Mask must be a vector of i1");
-
+ assert(isa<VectorType>(Mask->getType()) &&
+ isa<IntegerType>(Mask->getType()->getScalarType()) &&
+ cast<IntegerType>(Mask->getType()->getScalarType())->getBitWidth() ==
+ 1 &&
+ "Mask must be a vector of i1");
+
auto *ConstMask = dyn_cast<Constant>(Mask);
if (!ConstMask)
return false;
if (ConstMask->isNullValue() || isa<UndefValue>(ConstMask))
return true;
- if (isa<ScalableVectorType>(ConstMask->getType()))
- return false;
- for (unsigned
- I = 0,
- E = cast<FixedVectorType>(ConstMask->getType())->getNumElements();
+ if (isa<ScalableVectorType>(ConstMask->getType()))
+ return false;
+ for (unsigned
+ I = 0,
+ E = cast<FixedVectorType>(ConstMask->getType())->getNumElements();
I != E; ++I) {
if (auto *MaskElt = ConstMask->getAggregateElement(I))
if (MaskElt->isNullValue() || isa<UndefValue>(MaskElt))
@@ -893,22 +893,22 @@ bool llvm::maskIsAllZeroOrUndef(Value *Mask) {
bool llvm::maskIsAllOneOrUndef(Value *Mask) {
- assert(isa<VectorType>(Mask->getType()) &&
- isa<IntegerType>(Mask->getType()->getScalarType()) &&
- cast<IntegerType>(Mask->getType()->getScalarType())->getBitWidth() ==
- 1 &&
- "Mask must be a vector of i1");
-
+ assert(isa<VectorType>(Mask->getType()) &&
+ isa<IntegerType>(Mask->getType()->getScalarType()) &&
+ cast<IntegerType>(Mask->getType()->getScalarType())->getBitWidth() ==
+ 1 &&
+ "Mask must be a vector of i1");
+
auto *ConstMask = dyn_cast<Constant>(Mask);
if (!ConstMask)
return false;
if (ConstMask->isAllOnesValue() || isa<UndefValue>(ConstMask))
return true;
- if (isa<ScalableVectorType>(ConstMask->getType()))
- return false;
- for (unsigned
- I = 0,
- E = cast<FixedVectorType>(ConstMask->getType())->getNumElements();
+ if (isa<ScalableVectorType>(ConstMask->getType()))
+ return false;
+ for (unsigned
+ I = 0,
+ E = cast<FixedVectorType>(ConstMask->getType())->getNumElements();
I != E; ++I) {
if (auto *MaskElt = ConstMask->getAggregateElement(I))
if (MaskElt->isAllOnesValue() || isa<UndefValue>(MaskElt))
@@ -921,14 +921,14 @@ bool llvm::maskIsAllOneOrUndef(Value *Mask) {
/// TODO: This is a lot like known bits, but for
/// vectors. Is there something we can common this with?
APInt llvm::possiblyDemandedEltsInMask(Value *Mask) {
- assert(isa<FixedVectorType>(Mask->getType()) &&
- isa<IntegerType>(Mask->getType()->getScalarType()) &&
- cast<IntegerType>(Mask->getType()->getScalarType())->getBitWidth() ==
- 1 &&
- "Mask must be a fixed width vector of i1");
-
- const unsigned VWidth =
- cast<FixedVectorType>(Mask->getType())->getNumElements();
+ assert(isa<FixedVectorType>(Mask->getType()) &&
+ isa<IntegerType>(Mask->getType()->getScalarType()) &&
+ cast<IntegerType>(Mask->getType()->getScalarType())->getBitWidth() ==
+ 1 &&
+ "Mask must be a fixed width vector of i1");
+
+ const unsigned VWidth =
+ cast<FixedVectorType>(Mask->getType())->getNumElements();
APInt DemandedElts = APInt::getAllOnesValue(VWidth);
if (auto *CV = dyn_cast<ConstantVector>(Mask))
for (unsigned i = 0; i < VWidth; i++)
diff --git a/contrib/libs/llvm12/lib/Analysis/ya.make b/contrib/libs/llvm12/lib/Analysis/ya.make
index 4a6521c1fd..6e09c89fe4 100644
--- a/contrib/libs/llvm12/lib/Analysis/ya.make
+++ b/contrib/libs/llvm12/lib/Analysis/ya.make
@@ -15,13 +15,13 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/ProfileData
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/ProfileData
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
@@ -56,28 +56,28 @@ SRCS(
CmpInstAnalysis.cpp
CodeMetrics.cpp
ConstantFolding.cpp
- ConstraintSystem.cpp
+ ConstraintSystem.cpp
CostModel.cpp
DDG.cpp
- DDGPrinter.cpp
+ DDGPrinter.cpp
Delinearization.cpp
DemandedBits.cpp
DependenceAnalysis.cpp
DependenceGraphBuilder.cpp
- DevelopmentModeInlineAdvisor.cpp
+ DevelopmentModeInlineAdvisor.cpp
DivergenceAnalysis.cpp
DomPrinter.cpp
DomTreeUpdater.cpp
DominanceFrontier.cpp
EHPersonalities.cpp
- FunctionPropertiesAnalysis.cpp
+ FunctionPropertiesAnalysis.cpp
GlobalsModRef.cpp
GuardUtils.cpp
HeatUtils.cpp
- IRSimilarityIdentifier.cpp
+ IRSimilarityIdentifier.cpp
IVDescriptors.cpp
IVUsers.cpp
- ImportedFunctionsInliningStatistics.cpp
+ ImportedFunctionsInliningStatistics.cpp
IndirectCallPromotionAnalysis.cpp
InlineAdvisor.cpp
InlineCost.cpp
@@ -101,7 +101,7 @@ SRCS(
LoopNestAnalysis.cpp
LoopPass.cpp
LoopUnrollAnalyzer.cpp
- MLInlineAdvisor.cpp
+ MLInlineAdvisor.cpp
MemDepPrinter.cpp
MemDerefPrinter.cpp
MemoryBuiltins.cpp
@@ -124,8 +124,8 @@ SRCS(
RegionInfo.cpp
RegionPass.cpp
RegionPrinter.cpp
- ReleaseModeModelRunner.cpp
- ReplayInlineAdvisor.cpp
+ ReleaseModeModelRunner.cpp
+ ReplayInlineAdvisor.cpp
ScalarEvolution.cpp
ScalarEvolutionAliasAnalysis.cpp
ScalarEvolutionDivision.cpp
@@ -135,7 +135,7 @@ SRCS(
StackSafetyAnalysis.cpp
SyncDependenceAnalysis.cpp
SyntheticCountsUtils.cpp
- TFUtils.cpp
+ TFUtils.cpp
TargetLibraryInfo.cpp
TargetTransformInfo.cpp
Trace.cpp
diff --git a/contrib/libs/llvm12/lib/AsmParser/LLLexer.cpp b/contrib/libs/llvm12/lib/AsmParser/LLLexer.cpp
index 7e452a2157..427de74f91 100644
--- a/contrib/libs/llvm12/lib/AsmParser/LLLexer.cpp
+++ b/contrib/libs/llvm12/lib/AsmParser/LLLexer.cpp
@@ -531,7 +531,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(undef);
KEYWORD(null);
KEYWORD(none);
- KEYWORD(poison);
+ KEYWORD(poison);
KEYWORD(to);
KEYWORD(caller);
KEYWORD(within);
@@ -625,7 +625,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(amdgpu_ps);
KEYWORD(amdgpu_cs);
KEYWORD(amdgpu_kernel);
- KEYWORD(amdgpu_gfx);
+ KEYWORD(amdgpu_gfx);
KEYWORD(tailcc);
KEYWORD(cc);
@@ -653,7 +653,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(nest);
KEYWORD(noalias);
KEYWORD(nobuiltin);
- KEYWORD(nocallback);
+ KEYWORD(nocallback);
KEYWORD(nocapture);
KEYWORD(noduplicate);
KEYWORD(nofree);
@@ -663,7 +663,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(nonlazybind);
KEYWORD(nomerge);
KEYWORD(nonnull);
- KEYWORD(noprofile);
+ KEYWORD(noprofile);
KEYWORD(noredzone);
KEYWORD(noreturn);
KEYWORD(nosync);
@@ -701,8 +701,8 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(writeonly);
KEYWORD(zeroext);
KEYWORD(immarg);
- KEYWORD(byref);
- KEYWORD(mustprogress);
+ KEYWORD(byref);
+ KEYWORD(mustprogress);
KEYWORD(type);
KEYWORD(opaque);
@@ -727,7 +727,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(vscale);
KEYWORD(x);
KEYWORD(blockaddress);
- KEYWORD(dso_local_equivalent);
+ KEYWORD(dso_local_equivalent);
// Metadata types.
KEYWORD(distinct);
@@ -841,7 +841,7 @@ lltok::Kind LLLexer::LexIdentifier() {
TYPEKEYWORD("label", Type::getLabelTy(Context));
TYPEKEYWORD("metadata", Type::getMetadataTy(Context));
TYPEKEYWORD("x86_mmx", Type::getX86_MMXTy(Context));
- TYPEKEYWORD("x86_amx", Type::getX86_AMXTy(Context));
+ TYPEKEYWORD("x86_amx", Type::getX86_AMXTy(Context));
TYPEKEYWORD("token", Type::getTokenTy(Context));
#undef TYPEKEYWORD
diff --git a/contrib/libs/llvm12/lib/AsmParser/LLParser.cpp b/contrib/libs/llvm12/lib/AsmParser/LLParser.cpp
index eec0f69d97..2a3fb8fb66 100644
--- a/contrib/libs/llvm12/lib/AsmParser/LLParser.cpp
+++ b/contrib/libs/llvm12/lib/AsmParser/LLParser.cpp
@@ -65,20 +65,20 @@ bool LLParser::Run(bool UpgradeDebugInfo,
Lex.Lex();
if (Context.shouldDiscardValueNames())
- return error(
+ return error(
Lex.getLoc(),
"Can't read textual IR with a Context that discards named Values");
if (M) {
- if (parseTargetDefinitions())
+ if (parseTargetDefinitions())
return true;
if (auto LayoutOverride = DataLayoutCallback(M->getTargetTriple()))
M->setDataLayout(*LayoutOverride);
}
- return parseTopLevelEntities() || validateEndOfModule(UpgradeDebugInfo) ||
- validateEndOfIndex();
+ return parseTopLevelEntities() || validateEndOfModule(UpgradeDebugInfo) ||
+ validateEndOfIndex();
}
bool LLParser::parseStandaloneConstantValue(Constant *&C,
@@ -87,10 +87,10 @@ bool LLParser::parseStandaloneConstantValue(Constant *&C,
Lex.Lex();
Type *Ty = nullptr;
- if (parseType(Ty) || parseConstantValue(Ty, C))
+ if (parseType(Ty) || parseConstantValue(Ty, C))
return true;
if (Lex.getKind() != lltok::Eof)
- return error(Lex.getLoc(), "expected end of string");
+ return error(Lex.getLoc(), "expected end of string");
return false;
}
@@ -102,7 +102,7 @@ bool LLParser::parseTypeAtBeginning(Type *&Ty, unsigned &Read,
Read = 0;
SMLoc Start = Lex.getLoc();
Ty = nullptr;
- if (parseType(Ty))
+ if (parseType(Ty))
return true;
SMLoc End = Lex.getLoc();
Read = End.getPointer() - Start.getPointer();
@@ -123,9 +123,9 @@ void LLParser::restoreParsingState(const SlotMapping *Slots) {
std::make_pair(I.first, std::make_pair(I.second, LocTy())));
}
-/// validateEndOfModule - Do final validity and sanity checks at the end of the
+/// validateEndOfModule - Do final validity and sanity checks at the end of the
/// module.
-bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
+bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
if (!M)
return false;
// Handle any function attribute group forward references.
@@ -190,39 +190,39 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
// If there are entries in ForwardRefBlockAddresses at this point, the
// function was never defined.
if (!ForwardRefBlockAddresses.empty())
- return error(ForwardRefBlockAddresses.begin()->first.Loc,
+ return error(ForwardRefBlockAddresses.begin()->first.Loc,
"expected function name in blockaddress");
for (const auto &NT : NumberedTypes)
if (NT.second.second.isValid())
- return error(NT.second.second,
+ return error(NT.second.second,
"use of undefined type '%" + Twine(NT.first) + "'");
for (StringMap<std::pair<Type*, LocTy> >::iterator I =
NamedTypes.begin(), E = NamedTypes.end(); I != E; ++I)
if (I->second.second.isValid())
- return error(I->second.second,
+ return error(I->second.second,
"use of undefined type named '" + I->getKey() + "'");
if (!ForwardRefComdats.empty())
- return error(ForwardRefComdats.begin()->second,
+ return error(ForwardRefComdats.begin()->second,
"use of undefined comdat '$" +
ForwardRefComdats.begin()->first + "'");
if (!ForwardRefVals.empty())
- return error(ForwardRefVals.begin()->second.second,
+ return error(ForwardRefVals.begin()->second.second,
"use of undefined value '@" + ForwardRefVals.begin()->first +
- "'");
+ "'");
if (!ForwardRefValIDs.empty())
- return error(ForwardRefValIDs.begin()->second.second,
+ return error(ForwardRefValIDs.begin()->second.second,
"use of undefined value '@" +
- Twine(ForwardRefValIDs.begin()->first) + "'");
+ Twine(ForwardRefValIDs.begin()->first) + "'");
if (!ForwardRefMDNodes.empty())
- return error(ForwardRefMDNodes.begin()->second.second,
+ return error(ForwardRefMDNodes.begin()->second.second,
"use of undefined metadata '!" +
- Twine(ForwardRefMDNodes.begin()->first) + "'");
+ Twine(ForwardRefMDNodes.begin()->first) + "'");
// Resolve metadata cycles.
for (auto &N : NumberedMetadata) {
@@ -275,22 +275,22 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
}
/// Do final validity and sanity checks at the end of the index.
-bool LLParser::validateEndOfIndex() {
+bool LLParser::validateEndOfIndex() {
if (!Index)
return false;
if (!ForwardRefValueInfos.empty())
- return error(ForwardRefValueInfos.begin()->second.front().second,
+ return error(ForwardRefValueInfos.begin()->second.front().second,
"use of undefined summary '^" +
Twine(ForwardRefValueInfos.begin()->first) + "'");
if (!ForwardRefAliasees.empty())
- return error(ForwardRefAliasees.begin()->second.front().second,
+ return error(ForwardRefAliasees.begin()->second.front().second,
"use of undefined summary '^" +
Twine(ForwardRefAliasees.begin()->first) + "'");
if (!ForwardRefTypeIds.empty())
- return error(ForwardRefTypeIds.begin()->second.front().second,
+ return error(ForwardRefTypeIds.begin()->second.front().second,
"use of undefined type id summary '^" +
Twine(ForwardRefTypeIds.begin()->first) + "'");
@@ -301,15 +301,15 @@ bool LLParser::validateEndOfIndex() {
// Top-Level Entities
//===----------------------------------------------------------------------===//
-bool LLParser::parseTargetDefinitions() {
+bool LLParser::parseTargetDefinitions() {
while (true) {
switch (Lex.getKind()) {
case lltok::kw_target:
- if (parseTargetDefinition())
+ if (parseTargetDefinition())
return true;
break;
case lltok::kw_source_filename:
- if (parseSourceFileName())
+ if (parseSourceFileName())
return true;
break;
default:
@@ -318,7 +318,7 @@ bool LLParser::parseTargetDefinitions() {
}
}
-bool LLParser::parseTopLevelEntities() {
+bool LLParser::parseTopLevelEntities() {
// If there is no Module, then parse just the summary index entries.
if (!M) {
while (true) {
@@ -326,11 +326,11 @@ bool LLParser::parseTopLevelEntities() {
case lltok::Eof:
return false;
case lltok::SummaryID:
- if (parseSummaryEntry())
+ if (parseSummaryEntry())
return true;
break;
case lltok::kw_source_filename:
- if (parseSourceFileName())
+ if (parseSourceFileName())
return true;
break;
default:
@@ -341,64 +341,64 @@ bool LLParser::parseTopLevelEntities() {
}
while (true) {
switch (Lex.getKind()) {
- default:
- return tokError("expected top-level entity");
+ default:
+ return tokError("expected top-level entity");
case lltok::Eof: return false;
- case lltok::kw_declare:
- if (parseDeclare())
- return true;
- break;
- case lltok::kw_define:
- if (parseDefine())
- return true;
- break;
- case lltok::kw_module:
- if (parseModuleAsm())
- return true;
- break;
- case lltok::kw_deplibs:
- if (parseDepLibs())
- return true;
- break;
- case lltok::LocalVarID:
- if (parseUnnamedType())
- return true;
- break;
- case lltok::LocalVar:
- if (parseNamedType())
- return true;
- break;
- case lltok::GlobalID:
- if (parseUnnamedGlobal())
- return true;
- break;
- case lltok::GlobalVar:
- if (parseNamedGlobal())
- return true;
- break;
+ case lltok::kw_declare:
+ if (parseDeclare())
+ return true;
+ break;
+ case lltok::kw_define:
+ if (parseDefine())
+ return true;
+ break;
+ case lltok::kw_module:
+ if (parseModuleAsm())
+ return true;
+ break;
+ case lltok::kw_deplibs:
+ if (parseDepLibs())
+ return true;
+ break;
+ case lltok::LocalVarID:
+ if (parseUnnamedType())
+ return true;
+ break;
+ case lltok::LocalVar:
+ if (parseNamedType())
+ return true;
+ break;
+ case lltok::GlobalID:
+ if (parseUnnamedGlobal())
+ return true;
+ break;
+ case lltok::GlobalVar:
+ if (parseNamedGlobal())
+ return true;
+ break;
case lltok::ComdatVar: if (parseComdat()) return true; break;
- case lltok::exclaim:
- if (parseStandaloneMetadata())
- return true;
- break;
+ case lltok::exclaim:
+ if (parseStandaloneMetadata())
+ return true;
+ break;
case lltok::SummaryID:
- if (parseSummaryEntry())
+ if (parseSummaryEntry())
+ return true;
+ break;
+ case lltok::MetadataVar:
+ if (parseNamedMetadata())
+ return true;
+ break;
+ case lltok::kw_attributes:
+ if (parseUnnamedAttrGrp())
+ return true;
+ break;
+ case lltok::kw_uselistorder:
+ if (parseUseListOrder())
return true;
break;
- case lltok::MetadataVar:
- if (parseNamedMetadata())
- return true;
- break;
- case lltok::kw_attributes:
- if (parseUnnamedAttrGrp())
- return true;
- break;
- case lltok::kw_uselistorder:
- if (parseUseListOrder())
- return true;
- break;
case lltok::kw_uselistorder_bb:
- if (parseUseListOrderBB())
+ if (parseUseListOrderBB())
return true;
break;
}
@@ -407,14 +407,14 @@ bool LLParser::parseTopLevelEntities() {
/// toplevelentity
/// ::= 'module' 'asm' STRINGCONSTANT
-bool LLParser::parseModuleAsm() {
+bool LLParser::parseModuleAsm() {
assert(Lex.getKind() == lltok::kw_module);
Lex.Lex();
std::string AsmStr;
- if (parseToken(lltok::kw_asm, "expected 'module asm'") ||
- parseStringConstant(AsmStr))
- return true;
+ if (parseToken(lltok::kw_asm, "expected 'module asm'") ||
+ parseStringConstant(AsmStr))
+ return true;
M->appendModuleInlineAsm(AsmStr);
return false;
@@ -423,23 +423,23 @@ bool LLParser::parseModuleAsm() {
/// toplevelentity
/// ::= 'target' 'triple' '=' STRINGCONSTANT
/// ::= 'target' 'datalayout' '=' STRINGCONSTANT
-bool LLParser::parseTargetDefinition() {
+bool LLParser::parseTargetDefinition() {
assert(Lex.getKind() == lltok::kw_target);
std::string Str;
switch (Lex.Lex()) {
- default:
- return tokError("unknown target property");
+ default:
+ return tokError("unknown target property");
case lltok::kw_triple:
Lex.Lex();
- if (parseToken(lltok::equal, "expected '=' after target triple") ||
- parseStringConstant(Str))
+ if (parseToken(lltok::equal, "expected '=' after target triple") ||
+ parseStringConstant(Str))
return true;
M->setTargetTriple(Str);
return false;
case lltok::kw_datalayout:
Lex.Lex();
- if (parseToken(lltok::equal, "expected '=' after target datalayout") ||
- parseStringConstant(Str))
+ if (parseToken(lltok::equal, "expected '=' after target datalayout") ||
+ parseStringConstant(Str))
return true;
M->setDataLayout(Str);
return false;
@@ -448,11 +448,11 @@ bool LLParser::parseTargetDefinition() {
/// toplevelentity
/// ::= 'source_filename' '=' STRINGCONSTANT
-bool LLParser::parseSourceFileName() {
+bool LLParser::parseSourceFileName() {
assert(Lex.getKind() == lltok::kw_source_filename);
Lex.Lex();
- if (parseToken(lltok::equal, "expected '=' after source_filename") ||
- parseStringConstant(SourceFileName))
+ if (parseToken(lltok::equal, "expected '=' after source_filename") ||
+ parseStringConstant(SourceFileName))
return true;
if (M)
M->setSourceFileName(SourceFileName);
@@ -463,11 +463,11 @@ bool LLParser::parseSourceFileName() {
/// ::= 'deplibs' '=' '[' ']'
/// ::= 'deplibs' '=' '[' STRINGCONSTANT (',' STRINGCONSTANT)* ']'
/// FIXME: Remove in 4.0. Currently parse, but ignore.
-bool LLParser::parseDepLibs() {
+bool LLParser::parseDepLibs() {
assert(Lex.getKind() == lltok::kw_deplibs);
Lex.Lex();
- if (parseToken(lltok::equal, "expected '=' after deplibs") ||
- parseToken(lltok::lsquare, "expected '=' after deplibs"))
+ if (parseToken(lltok::equal, "expected '=' after deplibs") ||
+ parseToken(lltok::lsquare, "expected '=' after deplibs"))
return true;
if (EatIfPresent(lltok::rsquare))
@@ -475,32 +475,32 @@ bool LLParser::parseDepLibs() {
do {
std::string Str;
- if (parseStringConstant(Str))
- return true;
+ if (parseStringConstant(Str))
+ return true;
} while (EatIfPresent(lltok::comma));
- return parseToken(lltok::rsquare, "expected ']' at end of list");
+ return parseToken(lltok::rsquare, "expected ']' at end of list");
}
-/// parseUnnamedType:
+/// parseUnnamedType:
/// ::= LocalVarID '=' 'type' type
-bool LLParser::parseUnnamedType() {
+bool LLParser::parseUnnamedType() {
LocTy TypeLoc = Lex.getLoc();
unsigned TypeID = Lex.getUIntVal();
Lex.Lex(); // eat LocalVarID;
- if (parseToken(lltok::equal, "expected '=' after name") ||
- parseToken(lltok::kw_type, "expected 'type' after '='"))
+ if (parseToken(lltok::equal, "expected '=' after name") ||
+ parseToken(lltok::kw_type, "expected 'type' after '='"))
return true;
Type *Result = nullptr;
- if (parseStructDefinition(TypeLoc, "", NumberedTypes[TypeID], Result))
- return true;
+ if (parseStructDefinition(TypeLoc, "", NumberedTypes[TypeID], Result))
+ return true;
if (!isa<StructType>(Result)) {
std::pair<Type*, LocTy> &Entry = NumberedTypes[TypeID];
if (Entry.first)
- return error(TypeLoc, "non-struct types may not be recursive");
+ return error(TypeLoc, "non-struct types may not be recursive");
Entry.first = Result;
Entry.second = SMLoc();
}
@@ -510,23 +510,23 @@ bool LLParser::parseUnnamedType() {
/// toplevelentity
/// ::= LocalVar '=' 'type' type
-bool LLParser::parseNamedType() {
+bool LLParser::parseNamedType() {
std::string Name = Lex.getStrVal();
LocTy NameLoc = Lex.getLoc();
Lex.Lex(); // eat LocalVar.
- if (parseToken(lltok::equal, "expected '=' after name") ||
- parseToken(lltok::kw_type, "expected 'type' after name"))
+ if (parseToken(lltok::equal, "expected '=' after name") ||
+ parseToken(lltok::kw_type, "expected 'type' after name"))
return true;
Type *Result = nullptr;
- if (parseStructDefinition(NameLoc, Name, NamedTypes[Name], Result))
- return true;
+ if (parseStructDefinition(NameLoc, Name, NamedTypes[Name], Result))
+ return true;
if (!isa<StructType>(Result)) {
std::pair<Type*, LocTy> &Entry = NamedTypes[Name];
if (Entry.first)
- return error(NameLoc, "non-struct types may not be recursive");
+ return error(NameLoc, "non-struct types may not be recursive");
Entry.first = Result;
Entry.second = SMLoc();
}
@@ -536,7 +536,7 @@ bool LLParser::parseNamedType() {
/// toplevelentity
/// ::= 'declare' FunctionHeader
-bool LLParser::parseDeclare() {
+bool LLParser::parseDeclare() {
assert(Lex.getKind() == lltok::kw_declare);
Lex.Lex();
@@ -544,13 +544,13 @@ bool LLParser::parseDeclare() {
while (Lex.getKind() == lltok::MetadataVar) {
unsigned MDK;
MDNode *N;
- if (parseMetadataAttachment(MDK, N))
+ if (parseMetadataAttachment(MDK, N))
return true;
MDs.push_back({MDK, N});
}
Function *F;
- if (parseFunctionHeader(F, false))
+ if (parseFunctionHeader(F, false))
return true;
for (auto &MD : MDs)
F->addMetadata(MD.first, *MD.second);
@@ -559,32 +559,32 @@ bool LLParser::parseDeclare() {
/// toplevelentity
/// ::= 'define' FunctionHeader (!dbg !56)* '{' ...
-bool LLParser::parseDefine() {
+bool LLParser::parseDefine() {
assert(Lex.getKind() == lltok::kw_define);
Lex.Lex();
Function *F;
- return parseFunctionHeader(F, true) || parseOptionalFunctionMetadata(*F) ||
- parseFunctionBody(*F);
+ return parseFunctionHeader(F, true) || parseOptionalFunctionMetadata(*F) ||
+ parseFunctionBody(*F);
}
-/// parseGlobalType
+/// parseGlobalType
/// ::= 'constant'
/// ::= 'global'
-bool LLParser::parseGlobalType(bool &IsConstant) {
+bool LLParser::parseGlobalType(bool &IsConstant) {
if (Lex.getKind() == lltok::kw_constant)
IsConstant = true;
else if (Lex.getKind() == lltok::kw_global)
IsConstant = false;
else {
IsConstant = false;
- return tokError("expected 'global' or 'constant'");
+ return tokError("expected 'global' or 'constant'");
}
Lex.Lex();
return false;
}
-bool LLParser::parseOptionalUnnamedAddr(
+bool LLParser::parseOptionalUnnamedAddr(
GlobalVariable::UnnamedAddr &UnnamedAddr) {
if (EatIfPresent(lltok::kw_unnamed_addr))
UnnamedAddr = GlobalValue::UnnamedAddr::Global;
@@ -595,17 +595,17 @@ bool LLParser::parseOptionalUnnamedAddr(
return false;
}
-/// parseUnnamedGlobal:
+/// parseUnnamedGlobal:
/// OptionalVisibility (ALIAS | IFUNC) ...
/// OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility
/// OptionalDLLStorageClass
/// ... -> global variable
/// GlobalID '=' OptionalVisibility (ALIAS | IFUNC) ...
-/// GlobalID '=' OptionalLinkage OptionalPreemptionSpecifier
-/// OptionalVisibility
+/// GlobalID '=' OptionalLinkage OptionalPreemptionSpecifier
+/// OptionalVisibility
/// OptionalDLLStorageClass
/// ... -> global variable
-bool LLParser::parseUnnamedGlobal() {
+bool LLParser::parseUnnamedGlobal() {
unsigned VarID = NumberedVals.size();
std::string Name;
LocTy NameLoc = Lex.getLoc();
@@ -613,11 +613,11 @@ bool LLParser::parseUnnamedGlobal() {
// Handle the GlobalID form.
if (Lex.getKind() == lltok::GlobalID) {
if (Lex.getUIntVal() != VarID)
- return error(Lex.getLoc(),
- "variable expected to be numbered '%" + Twine(VarID) + "'");
+ return error(Lex.getLoc(),
+ "variable expected to be numbered '%" + Twine(VarID) + "'");
Lex.Lex(); // eat GlobalID;
- if (parseToken(lltok::equal, "expected '=' after name"))
+ if (parseToken(lltok::equal, "expected '=' after name"))
return true;
}
@@ -626,25 +626,25 @@ bool LLParser::parseUnnamedGlobal() {
bool DSOLocal;
GlobalVariable::ThreadLocalMode TLM;
GlobalVariable::UnnamedAddr UnnamedAddr;
- if (parseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass,
+ if (parseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass,
DSOLocal) ||
- parseOptionalThreadLocal(TLM) || parseOptionalUnnamedAddr(UnnamedAddr))
+ parseOptionalThreadLocal(TLM) || parseOptionalUnnamedAddr(UnnamedAddr))
return true;
if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc)
- return parseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
+ return parseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
DLLStorageClass, DSOLocal, TLM, UnnamedAddr);
return parseIndirectSymbol(Name, NameLoc, Linkage, Visibility,
DLLStorageClass, DSOLocal, TLM, UnnamedAddr);
}
-/// parseNamedGlobal:
+/// parseNamedGlobal:
/// GlobalVar '=' OptionalVisibility (ALIAS | IFUNC) ...
/// GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier
/// OptionalVisibility OptionalDLLStorageClass
/// ... -> global variable
-bool LLParser::parseNamedGlobal() {
+bool LLParser::parseNamedGlobal() {
assert(Lex.getKind() == lltok::GlobalVar);
LocTy NameLoc = Lex.getLoc();
std::string Name = Lex.getStrVal();
@@ -655,14 +655,14 @@ bool LLParser::parseNamedGlobal() {
bool DSOLocal;
GlobalVariable::ThreadLocalMode TLM;
GlobalVariable::UnnamedAddr UnnamedAddr;
- if (parseToken(lltok::equal, "expected '=' in global variable") ||
- parseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass,
+ if (parseToken(lltok::equal, "expected '=' in global variable") ||
+ parseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass,
DSOLocal) ||
- parseOptionalThreadLocal(TLM) || parseOptionalUnnamedAddr(UnnamedAddr))
+ parseOptionalThreadLocal(TLM) || parseOptionalUnnamedAddr(UnnamedAddr))
return true;
if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc)
- return parseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
+ return parseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
DLLStorageClass, DSOLocal, TLM, UnnamedAddr);
return parseIndirectSymbol(Name, NameLoc, Linkage, Visibility,
@@ -675,16 +675,16 @@ bool LLParser::parseComdat() {
LocTy NameLoc = Lex.getLoc();
Lex.Lex();
- if (parseToken(lltok::equal, "expected '=' here"))
+ if (parseToken(lltok::equal, "expected '=' here"))
return true;
- if (parseToken(lltok::kw_comdat, "expected comdat keyword"))
- return tokError("expected comdat type");
+ if (parseToken(lltok::kw_comdat, "expected comdat keyword"))
+ return tokError("expected comdat type");
Comdat::SelectionKind SK;
switch (Lex.getKind()) {
default:
- return tokError("unknown selection kind");
+ return tokError("unknown selection kind");
case lltok::kw_any:
SK = Comdat::Any;
break;
@@ -707,7 +707,7 @@ bool LLParser::parseComdat() {
Module::ComdatSymTabType &ComdatSymTab = M->getComdatSymbolTable();
Module::ComdatSymTabType::iterator I = ComdatSymTab.find(Name);
if (I != ComdatSymTab.end() && !ForwardRefComdats.erase(Name))
- return error(NameLoc, "redefinition of comdat '$" + Name + "'");
+ return error(NameLoc, "redefinition of comdat '$" + Name + "'");
Comdat *C;
if (I != ComdatSymTab.end())
@@ -721,21 +721,21 @@ bool LLParser::parseComdat() {
// MDString:
// ::= '!' STRINGCONSTANT
-bool LLParser::parseMDString(MDString *&Result) {
+bool LLParser::parseMDString(MDString *&Result) {
std::string Str;
- if (parseStringConstant(Str))
- return true;
+ if (parseStringConstant(Str))
+ return true;
Result = MDString::get(Context, Str);
return false;
}
// MDNode:
// ::= '!' MDNodeNumber
-bool LLParser::parseMDNodeID(MDNode *&Result) {
+bool LLParser::parseMDNodeID(MDNode *&Result) {
// !{ ..., !42, ... }
LocTy IDLoc = Lex.getLoc();
unsigned MID = 0;
- if (parseUInt32(MID))
+ if (parseUInt32(MID))
return true;
// If not a forward reference, just return it now.
@@ -753,60 +753,60 @@ bool LLParser::parseMDNodeID(MDNode *&Result) {
return false;
}
-/// parseNamedMetadata:
+/// parseNamedMetadata:
/// !foo = !{ !1, !2 }
-bool LLParser::parseNamedMetadata() {
+bool LLParser::parseNamedMetadata() {
assert(Lex.getKind() == lltok::MetadataVar);
std::string Name = Lex.getStrVal();
Lex.Lex();
- if (parseToken(lltok::equal, "expected '=' here") ||
- parseToken(lltok::exclaim, "Expected '!' here") ||
- parseToken(lltok::lbrace, "Expected '{' here"))
+ if (parseToken(lltok::equal, "expected '=' here") ||
+ parseToken(lltok::exclaim, "Expected '!' here") ||
+ parseToken(lltok::lbrace, "Expected '{' here"))
return true;
NamedMDNode *NMD = M->getOrInsertNamedMetadata(Name);
if (Lex.getKind() != lltok::rbrace)
do {
MDNode *N = nullptr;
- // parse DIExpressions inline as a special case. They are still MDNodes,
+ // parse DIExpressions inline as a special case. They are still MDNodes,
// so they can still appear in named metadata. Remove this logic if they
// become plain Metadata.
if (Lex.getKind() == lltok::MetadataVar &&
Lex.getStrVal() == "DIExpression") {
- if (parseDIExpression(N, /*IsDistinct=*/false))
+ if (parseDIExpression(N, /*IsDistinct=*/false))
return true;
- } else if (parseToken(lltok::exclaim, "Expected '!' here") ||
- parseMDNodeID(N)) {
+ } else if (parseToken(lltok::exclaim, "Expected '!' here") ||
+ parseMDNodeID(N)) {
return true;
}
NMD->addOperand(N);
} while (EatIfPresent(lltok::comma));
- return parseToken(lltok::rbrace, "expected end of metadata node");
+ return parseToken(lltok::rbrace, "expected end of metadata node");
}
-/// parseStandaloneMetadata:
+/// parseStandaloneMetadata:
/// !42 = !{...}
-bool LLParser::parseStandaloneMetadata() {
+bool LLParser::parseStandaloneMetadata() {
assert(Lex.getKind() == lltok::exclaim);
Lex.Lex();
unsigned MetadataID = 0;
MDNode *Init;
- if (parseUInt32(MetadataID) || parseToken(lltok::equal, "expected '=' here"))
+ if (parseUInt32(MetadataID) || parseToken(lltok::equal, "expected '=' here"))
return true;
// Detect common error, from old metadata syntax.
if (Lex.getKind() == lltok::Type)
- return tokError("unexpected type in metadata definition");
+ return tokError("unexpected type in metadata definition");
bool IsDistinct = EatIfPresent(lltok::kw_distinct);
if (Lex.getKind() == lltok::MetadataVar) {
- if (parseSpecializedMDNode(Init, IsDistinct))
+ if (parseSpecializedMDNode(Init, IsDistinct))
return true;
- } else if (parseToken(lltok::exclaim, "Expected '!' here") ||
- parseMDTuple(Init, IsDistinct))
+ } else if (parseToken(lltok::exclaim, "Expected '!' here") ||
+ parseMDTuple(Init, IsDistinct))
return true;
// See if this was forward referenced, if so, handle it.
@@ -818,7 +818,7 @@ bool LLParser::parseStandaloneMetadata() {
assert(NumberedMetadata[MetadataID] == Init && "Tracking VH didn't work");
} else {
if (NumberedMetadata.count(MetadataID))
- return tokError("Metadata id is already used");
+ return tokError("Metadata id is already used");
NumberedMetadata[MetadataID].reset(Init);
}
@@ -826,25 +826,25 @@ bool LLParser::parseStandaloneMetadata() {
}
// Skips a single module summary entry.
-bool LLParser::skipModuleSummaryEntry() {
+bool LLParser::skipModuleSummaryEntry() {
// Each module summary entry consists of a tag for the entry
- // type, followed by a colon, then the fields which may be surrounded by
- // nested sets of parentheses. The "tag:" looks like a Label. Once parsing
- // support is in place we will look for the tokens corresponding to the
- // expected tags.
+ // type, followed by a colon, then the fields which may be surrounded by
+ // nested sets of parentheses. The "tag:" looks like a Label. Once parsing
+ // support is in place we will look for the tokens corresponding to the
+ // expected tags.
if (Lex.getKind() != lltok::kw_gv && Lex.getKind() != lltok::kw_module &&
- Lex.getKind() != lltok::kw_typeid && Lex.getKind() != lltok::kw_flags &&
- Lex.getKind() != lltok::kw_blockcount)
- return tokError(
- "Expected 'gv', 'module', 'typeid', 'flags' or 'blockcount' at the "
- "start of summary entry");
- if (Lex.getKind() == lltok::kw_flags)
- return parseSummaryIndexFlags();
- if (Lex.getKind() == lltok::kw_blockcount)
- return parseBlockCount();
+ Lex.getKind() != lltok::kw_typeid && Lex.getKind() != lltok::kw_flags &&
+ Lex.getKind() != lltok::kw_blockcount)
+ return tokError(
+ "Expected 'gv', 'module', 'typeid', 'flags' or 'blockcount' at the "
+ "start of summary entry");
+ if (Lex.getKind() == lltok::kw_flags)
+ return parseSummaryIndexFlags();
+ if (Lex.getKind() == lltok::kw_blockcount)
+ return parseBlockCount();
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' at start of summary entry") ||
- parseToken(lltok::lparen, "expected '(' at start of summary entry"))
+ if (parseToken(lltok::colon, "expected ':' at start of summary entry") ||
+ parseToken(lltok::lparen, "expected '(' at start of summary entry"))
return true;
// Now walk through the parenthesized entry, until the number of open
// parentheses goes back down to 0 (the first '(' was parsed above).
@@ -858,7 +858,7 @@ bool LLParser::skipModuleSummaryEntry() {
NumOpenParen--;
break;
case lltok::Eof:
- return tokError("found end of file while parsing summary entry");
+ return tokError("found end of file while parsing summary entry");
default:
// Skip everything in between parentheses.
break;
@@ -870,7 +870,7 @@ bool LLParser::skipModuleSummaryEntry() {
/// SummaryEntry
/// ::= SummaryID '=' GVEntry | ModuleEntry | TypeIdEntry
-bool LLParser::parseSummaryEntry() {
+bool LLParser::parseSummaryEntry() {
assert(Lex.getKind() == lltok::SummaryID);
unsigned SummaryID = Lex.getUIntVal();
@@ -879,35 +879,35 @@ bool LLParser::parseSummaryEntry() {
Lex.setIgnoreColonInIdentifiers(true);
Lex.Lex();
- if (parseToken(lltok::equal, "expected '=' here"))
+ if (parseToken(lltok::equal, "expected '=' here"))
return true;
// If we don't have an index object, skip the summary entry.
if (!Index)
- return skipModuleSummaryEntry();
+ return skipModuleSummaryEntry();
bool result = false;
switch (Lex.getKind()) {
case lltok::kw_gv:
- result = parseGVEntry(SummaryID);
+ result = parseGVEntry(SummaryID);
break;
case lltok::kw_module:
- result = parseModuleEntry(SummaryID);
+ result = parseModuleEntry(SummaryID);
break;
case lltok::kw_typeid:
- result = parseTypeIdEntry(SummaryID);
+ result = parseTypeIdEntry(SummaryID);
break;
case lltok::kw_typeidCompatibleVTable:
- result = parseTypeIdCompatibleVtableEntry(SummaryID);
+ result = parseTypeIdCompatibleVtableEntry(SummaryID);
break;
case lltok::kw_flags:
- result = parseSummaryIndexFlags();
+ result = parseSummaryIndexFlags();
break;
case lltok::kw_blockcount:
- result = parseBlockCount();
+ result = parseBlockCount();
break;
default:
- result = error(Lex.getLoc(), "unexpected summary kind");
+ result = error(Lex.getLoc(), "unexpected summary kind");
break;
}
Lex.setIgnoreColonInIdentifiers(false);
@@ -957,16 +957,16 @@ bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
GlobalValue::LinkageTypes Linkage = (GlobalValue::LinkageTypes) L;
if(IsAlias && !GlobalAlias::isValidLinkage(Linkage))
- return error(NameLoc, "invalid linkage type for alias");
+ return error(NameLoc, "invalid linkage type for alias");
if (!isValidVisibilityForLinkage(Visibility, L))
- return error(NameLoc,
+ return error(NameLoc,
"symbol with local linkage must have default visibility");
Type *Ty;
LocTy ExplicitTypeLoc = Lex.getLoc();
- if (parseType(Ty) ||
- parseToken(lltok::comma, "expected comma after alias or ifunc's type"))
+ if (parseType(Ty) ||
+ parseToken(lltok::comma, "expected comma after alias or ifunc's type"))
return true;
Constant *Aliasee;
@@ -975,31 +975,31 @@ bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
Lex.getKind() != lltok::kw_getelementptr &&
Lex.getKind() != lltok::kw_addrspacecast &&
Lex.getKind() != lltok::kw_inttoptr) {
- if (parseGlobalTypeAndValue(Aliasee))
+ if (parseGlobalTypeAndValue(Aliasee))
return true;
} else {
// The bitcast dest type is not present, it is implied by the dest type.
ValID ID;
- if (parseValID(ID))
+ if (parseValID(ID))
return true;
if (ID.Kind != ValID::t_Constant)
- return error(AliaseeLoc, "invalid aliasee");
+ return error(AliaseeLoc, "invalid aliasee");
Aliasee = ID.ConstantVal;
}
Type *AliaseeType = Aliasee->getType();
auto *PTy = dyn_cast<PointerType>(AliaseeType);
if (!PTy)
- return error(AliaseeLoc, "An alias or ifunc must have pointer type");
+ return error(AliaseeLoc, "An alias or ifunc must have pointer type");
unsigned AddrSpace = PTy->getAddressSpace();
if (IsAlias && Ty != PTy->getElementType())
- return error(ExplicitTypeLoc,
- "explicit pointee type doesn't match operand's pointee type");
+ return error(ExplicitTypeLoc,
+ "explicit pointee type doesn't match operand's pointee type");
if (!IsAlias && !PTy->getElementType()->isFunctionTy())
- return error(ExplicitTypeLoc,
- "explicit pointee type should be a function type");
+ return error(ExplicitTypeLoc,
+ "explicit pointee type should be a function type");
GlobalValue *GVal = nullptr;
@@ -1009,7 +1009,7 @@ bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
GVal = M->getNamedValue(Name);
if (GVal) {
if (!ForwardRefVals.erase(Name))
- return error(NameLoc, "redefinition of global '@" + Name + "'");
+ return error(NameLoc, "redefinition of global '@" + Name + "'");
}
} else {
auto I = ForwardRefValIDs.find(NumberedVals.size());
@@ -1043,10 +1043,10 @@ bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
if (Lex.getKind() == lltok::kw_partition) {
Lex.Lex();
GA->setPartition(Lex.getStrVal());
- if (parseToken(lltok::StringConstant, "expected partition string"))
+ if (parseToken(lltok::StringConstant, "expected partition string"))
return true;
} else {
- return tokError("unknown alias or ifunc property!");
+ return tokError("unknown alias or ifunc property!");
}
}
@@ -1056,7 +1056,7 @@ bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
if (GVal) {
// Verify that types agree.
if (GVal->getType() != GA->getType())
- return error(
+ return error(
ExplicitTypeLoc,
"forward reference and definition of alias have different types");
@@ -1079,7 +1079,7 @@ bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
return false;
}
-/// parseGlobal
+/// parseGlobal
/// ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier
/// OptionalVisibility OptionalDLLStorageClass
/// OptionalThreadLocal OptionalUnnamedAddr OptionalAddrSpace
@@ -1092,13 +1092,13 @@ bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
/// Everything up to and including OptionalUnnamedAddr has been parsed
/// already.
///
-bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc,
+bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc,
unsigned Linkage, bool HasLinkage,
unsigned Visibility, unsigned DLLStorageClass,
bool DSOLocal, GlobalVariable::ThreadLocalMode TLM,
GlobalVariable::UnnamedAddr UnnamedAddr) {
if (!isValidVisibilityForLinkage(Visibility, Linkage))
- return error(NameLoc,
+ return error(NameLoc,
"symbol with local linkage must have default visibility");
unsigned AddrSpace;
@@ -1107,11 +1107,11 @@ bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc,
LocTy TyLoc;
Type *Ty = nullptr;
- if (parseOptionalAddrSpace(AddrSpace) ||
- parseOptionalToken(lltok::kw_externally_initialized,
+ if (parseOptionalAddrSpace(AddrSpace) ||
+ parseOptionalToken(lltok::kw_externally_initialized,
IsExternallyInitialized,
&IsExternallyInitializedLoc) ||
- parseGlobalType(IsConstant) || parseType(Ty, TyLoc))
+ parseGlobalType(IsConstant) || parseType(Ty, TyLoc))
return true;
// If the linkage is specified and is external, then no initializer is
@@ -1120,12 +1120,12 @@ bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc,
if (!HasLinkage ||
!GlobalValue::isValidDeclarationLinkage(
(GlobalValue::LinkageTypes)Linkage)) {
- if (parseGlobalValue(Ty, Init))
+ if (parseGlobalValue(Ty, Init))
return true;
}
if (Ty->isFunctionTy() || !PointerType::isValidElementType(Ty))
- return error(TyLoc, "invalid type for global variable");
+ return error(TyLoc, "invalid type for global variable");
GlobalValue *GVal = nullptr;
@@ -1134,7 +1134,7 @@ bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc,
GVal = M->getNamedValue(Name);
if (GVal) {
if (!ForwardRefVals.erase(Name))
- return error(NameLoc, "redefinition of global '@" + Name + "'");
+ return error(NameLoc, "redefinition of global '@" + Name + "'");
}
} else {
auto I = ForwardRefValIDs.find(NumberedVals.size());
@@ -1151,9 +1151,9 @@ bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc,
AddrSpace);
} else {
if (GVal->getValueType() != Ty)
- return error(
- TyLoc,
- "forward reference and definition of global have different types");
+ return error(
+ TyLoc,
+ "forward reference and definition of global have different types");
GV = cast<GlobalVariable>(GVal);
@@ -1176,27 +1176,27 @@ bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc,
GV->setThreadLocalMode(TLM);
GV->setUnnamedAddr(UnnamedAddr);
- // parse attributes on the global.
+ // parse attributes on the global.
while (Lex.getKind() == lltok::comma) {
Lex.Lex();
if (Lex.getKind() == lltok::kw_section) {
Lex.Lex();
GV->setSection(Lex.getStrVal());
- if (parseToken(lltok::StringConstant, "expected global section string"))
+ if (parseToken(lltok::StringConstant, "expected global section string"))
return true;
} else if (Lex.getKind() == lltok::kw_partition) {
Lex.Lex();
GV->setPartition(Lex.getStrVal());
- if (parseToken(lltok::StringConstant, "expected partition string"))
+ if (parseToken(lltok::StringConstant, "expected partition string"))
return true;
} else if (Lex.getKind() == lltok::kw_align) {
MaybeAlign Alignment;
- if (parseOptionalAlignment(Alignment))
- return true;
+ if (parseOptionalAlignment(Alignment))
+ return true;
GV->setAlignment(Alignment);
} else if (Lex.getKind() == lltok::MetadataVar) {
- if (parseGlobalObjectMetadataAttachment(*GV))
+ if (parseGlobalObjectMetadataAttachment(*GV))
return true;
} else {
Comdat *C;
@@ -1205,14 +1205,14 @@ bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc,
if (C)
GV->setComdat(C);
else
- return tokError("unknown global variable property!");
+ return tokError("unknown global variable property!");
}
}
AttrBuilder Attrs;
LocTy BuiltinLoc;
std::vector<unsigned> FwdRefAttrGrps;
- if (parseFnAttributeValuePairs(Attrs, FwdRefAttrGrps, false, BuiltinLoc))
+ if (parseFnAttributeValuePairs(Attrs, FwdRefAttrGrps, false, BuiltinLoc))
return true;
if (Attrs.hasAttributes() || !FwdRefAttrGrps.empty()) {
GV->setAttributes(AttributeSet::get(Context, Attrs));
@@ -1222,37 +1222,37 @@ bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc,
return false;
}
-/// parseUnnamedAttrGrp
+/// parseUnnamedAttrGrp
/// ::= 'attributes' AttrGrpID '=' '{' AttrValPair+ '}'
-bool LLParser::parseUnnamedAttrGrp() {
+bool LLParser::parseUnnamedAttrGrp() {
assert(Lex.getKind() == lltok::kw_attributes);
LocTy AttrGrpLoc = Lex.getLoc();
Lex.Lex();
if (Lex.getKind() != lltok::AttrGrpID)
- return tokError("expected attribute group id");
+ return tokError("expected attribute group id");
unsigned VarID = Lex.getUIntVal();
std::vector<unsigned> unused;
LocTy BuiltinLoc;
Lex.Lex();
- if (parseToken(lltok::equal, "expected '=' here") ||
- parseToken(lltok::lbrace, "expected '{' here") ||
- parseFnAttributeValuePairs(NumberedAttrBuilders[VarID], unused, true,
+ if (parseToken(lltok::equal, "expected '=' here") ||
+ parseToken(lltok::lbrace, "expected '{' here") ||
+ parseFnAttributeValuePairs(NumberedAttrBuilders[VarID], unused, true,
BuiltinLoc) ||
- parseToken(lltok::rbrace, "expected end of attribute group"))
+ parseToken(lltok::rbrace, "expected end of attribute group"))
return true;
if (!NumberedAttrBuilders[VarID].hasAttributes())
- return error(AttrGrpLoc, "attribute group has no attributes");
+ return error(AttrGrpLoc, "attribute group has no attributes");
return false;
}
-/// parseFnAttributeValuePairs
+/// parseFnAttributeValuePairs
/// ::= <attr> | <attr> '=' <value>
-bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
+bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
std::vector<unsigned> &FwdRefAttrGrps,
bool inAttrGrp, LocTy &BuiltinLoc) {
bool HaveError = false;
@@ -1266,7 +1266,7 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
switch (Token) {
default:
if (!inAttrGrp) return HaveError;
- return error(Lex.getLoc(), "unterminated attribute group");
+ return error(Lex.getLoc(), "unterminated attribute group");
case lltok::rbrace:
// Finished.
return false;
@@ -1276,9 +1276,9 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
//
// define void @foo() #1 { ... }
if (inAttrGrp)
- HaveError |= error(
- Lex.getLoc(),
- "cannot have an attribute group reference in an attribute group");
+ HaveError |= error(
+ Lex.getLoc(),
+ "cannot have an attribute group reference in an attribute group");
unsigned AttrGrpNum = Lex.getUIntVal();
if (inAttrGrp) break;
@@ -1289,7 +1289,7 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
}
// Target-dependent attributes:
case lltok::StringConstant: {
- if (parseStringAttribute(B))
+ if (parseStringAttribute(B))
return true;
continue;
}
@@ -1303,11 +1303,11 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
if (inAttrGrp) {
Lex.Lex();
uint32_t Value = 0;
- if (parseToken(lltok::equal, "expected '=' here") || parseUInt32(Value))
+ if (parseToken(lltok::equal, "expected '=' here") || parseUInt32(Value))
return true;
Alignment = Align(Value);
} else {
- if (parseOptionalAlignment(Alignment))
+ if (parseOptionalAlignment(Alignment))
return true;
}
B.addAlignmentAttr(Alignment);
@@ -1317,11 +1317,11 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
unsigned Alignment;
if (inAttrGrp) {
Lex.Lex();
- if (parseToken(lltok::equal, "expected '=' here") ||
- parseUInt32(Alignment))
+ if (parseToken(lltok::equal, "expected '=' here") ||
+ parseUInt32(Alignment))
return true;
} else {
- if (parseOptionalStackAlignment(Alignment))
+ if (parseOptionalStackAlignment(Alignment))
return true;
}
B.addStackAlignmentAttr(Alignment);
@@ -1340,7 +1340,7 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
case lltok::kw_argmemonly: B.addAttribute(Attribute::ArgMemOnly); break;
case lltok::kw_builtin: B.addAttribute(Attribute::Builtin); break;
case lltok::kw_cold: B.addAttribute(Attribute::Cold); break;
- case lltok::kw_hot: B.addAttribute(Attribute::Hot); break;
+ case lltok::kw_hot: B.addAttribute(Attribute::Hot); break;
case lltok::kw_convergent: B.addAttribute(Attribute::Convergent); break;
case lltok::kw_inaccessiblememonly:
B.addAttribute(Attribute::InaccessibleMemOnly); break;
@@ -1349,14 +1349,14 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break;
case lltok::kw_jumptable: B.addAttribute(Attribute::JumpTable); break;
case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break;
- case lltok::kw_mustprogress:
- B.addAttribute(Attribute::MustProgress);
- break;
+ case lltok::kw_mustprogress:
+ B.addAttribute(Attribute::MustProgress);
+ break;
case lltok::kw_naked: B.addAttribute(Attribute::Naked); break;
case lltok::kw_nobuiltin: B.addAttribute(Attribute::NoBuiltin); break;
- case lltok::kw_nocallback:
- B.addAttribute(Attribute::NoCallback);
- break;
+ case lltok::kw_nocallback:
+ B.addAttribute(Attribute::NoCallback);
+ break;
case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break;
case lltok::kw_nofree: B.addAttribute(Attribute::NoFree); break;
case lltok::kw_noimplicitfloat:
@@ -1368,7 +1368,7 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break;
case lltok::kw_nosync: B.addAttribute(Attribute::NoSync); break;
case lltok::kw_nocf_check: B.addAttribute(Attribute::NoCfCheck); break;
- case lltok::kw_noprofile: B.addAttribute(Attribute::NoProfile); break;
+ case lltok::kw_noprofile: B.addAttribute(Attribute::NoProfile); break;
case lltok::kw_norecurse: B.addAttribute(Attribute::NoRecurse); break;
case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break;
case lltok::kw_null_pointer_is_valid:
@@ -1408,18 +1408,18 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
case lltok::kw_writeonly: B.addAttribute(Attribute::WriteOnly); break;
case lltok::kw_preallocated: {
Type *Ty;
- if (parsePreallocated(Ty))
+ if (parsePreallocated(Ty))
return true;
B.addPreallocatedAttr(Ty);
break;
}
- // error handling.
+ // error handling.
case lltok::kw_inreg:
case lltok::kw_signext:
case lltok::kw_zeroext:
HaveError |=
- error(Lex.getLoc(), "invalid use of attribute on a function");
+ error(Lex.getLoc(), "invalid use of attribute on a function");
break;
case lltok::kw_byval:
case lltok::kw_dereferenceable:
@@ -1435,14 +1435,14 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
case lltok::kw_swifterror:
case lltok::kw_swiftself:
case lltok::kw_immarg:
- case lltok::kw_byref:
+ case lltok::kw_byref:
HaveError |=
- error(Lex.getLoc(),
- "invalid use of parameter-only attribute on a function");
+ error(Lex.getLoc(),
+ "invalid use of parameter-only attribute on a function");
break;
}
- // parsePreallocated() consumes token
+ // parsePreallocated() consumes token
if (Token != lltok::kw_preallocated)
Lex.Lex();
}
@@ -1478,22 +1478,22 @@ Value *LLParser::checkValidVariableType(LocTy Loc, const Twine &Name, Type *Ty,
return Val;
}
if (Ty->isLabelTy())
- error(Loc, "'" + Name + "' is not a basic block");
+ error(Loc, "'" + Name + "' is not a basic block");
else
- error(Loc, "'" + Name + "' defined with type '" +
+ error(Loc, "'" + Name + "' defined with type '" +
getTypeString(Val->getType()) + "' but expected '" +
getTypeString(SuggestedTy) + "'");
return nullptr;
}
-/// getGlobalVal - Get a value with the specified name or ID, creating a
+/// getGlobalVal - Get a value with the specified name or ID, creating a
/// forward reference record if needed. This can return null if the value
/// exists but does not have the right type.
-GlobalValue *LLParser::getGlobalVal(const std::string &Name, Type *Ty,
+GlobalValue *LLParser::getGlobalVal(const std::string &Name, Type *Ty,
LocTy Loc, bool IsCall) {
PointerType *PTy = dyn_cast<PointerType>(Ty);
if (!PTy) {
- error(Loc, "global variable reference must have pointer type");
+ error(Loc, "global variable reference must have pointer type");
return nullptr;
}
@@ -1520,11 +1520,11 @@ GlobalValue *LLParser::getGlobalVal(const std::string &Name, Type *Ty,
return FwdVal;
}
-GlobalValue *LLParser::getGlobalVal(unsigned ID, Type *Ty, LocTy Loc,
+GlobalValue *LLParser::getGlobalVal(unsigned ID, Type *Ty, LocTy Loc,
bool IsCall) {
PointerType *PTy = dyn_cast<PointerType>(Ty);
if (!PTy) {
- error(Loc, "global variable reference must have pointer type");
+ error(Loc, "global variable reference must have pointer type");
return nullptr;
}
@@ -1570,56 +1570,56 @@ Comdat *LLParser::getComdat(const std::string &Name, LocTy Loc) {
// Helper Routines.
//===----------------------------------------------------------------------===//
-/// parseToken - If the current token has the specified kind, eat it and return
+/// parseToken - If the current token has the specified kind, eat it and return
/// success. Otherwise, emit the specified error and return failure.
-bool LLParser::parseToken(lltok::Kind T, const char *ErrMsg) {
+bool LLParser::parseToken(lltok::Kind T, const char *ErrMsg) {
if (Lex.getKind() != T)
- return tokError(ErrMsg);
+ return tokError(ErrMsg);
Lex.Lex();
return false;
}
-/// parseStringConstant
+/// parseStringConstant
/// ::= StringConstant
-bool LLParser::parseStringConstant(std::string &Result) {
+bool LLParser::parseStringConstant(std::string &Result) {
if (Lex.getKind() != lltok::StringConstant)
- return tokError("expected string constant");
+ return tokError("expected string constant");
Result = Lex.getStrVal();
Lex.Lex();
return false;
}
-/// parseUInt32
+/// parseUInt32
/// ::= uint32
-bool LLParser::parseUInt32(uint32_t &Val) {
+bool LLParser::parseUInt32(uint32_t &Val) {
if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
- return tokError("expected integer");
+ return tokError("expected integer");
uint64_t Val64 = Lex.getAPSIntVal().getLimitedValue(0xFFFFFFFFULL+1);
if (Val64 != unsigned(Val64))
- return tokError("expected 32-bit integer (too large)");
+ return tokError("expected 32-bit integer (too large)");
Val = Val64;
Lex.Lex();
return false;
}
-/// parseUInt64
+/// parseUInt64
/// ::= uint64
-bool LLParser::parseUInt64(uint64_t &Val) {
+bool LLParser::parseUInt64(uint64_t &Val) {
if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
- return tokError("expected integer");
+ return tokError("expected integer");
Val = Lex.getAPSIntVal().getLimitedValue();
Lex.Lex();
return false;
}
-/// parseTLSModel
+/// parseTLSModel
/// := 'localdynamic'
/// := 'initialexec'
/// := 'localexec'
-bool LLParser::parseTLSModel(GlobalVariable::ThreadLocalMode &TLM) {
+bool LLParser::parseTLSModel(GlobalVariable::ThreadLocalMode &TLM) {
switch (Lex.getKind()) {
default:
- return tokError("expected localdynamic, initialexec or localexec");
+ return tokError("expected localdynamic, initialexec or localexec");
case lltok::kw_localdynamic:
TLM = GlobalVariable::LocalDynamicTLSModel;
break;
@@ -1635,11 +1635,11 @@ bool LLParser::parseTLSModel(GlobalVariable::ThreadLocalMode &TLM) {
return false;
}
-/// parseOptionalThreadLocal
+/// parseOptionalThreadLocal
/// := /*empty*/
/// := 'thread_local'
/// := 'thread_local' '(' tlsmodel ')'
-bool LLParser::parseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM) {
+bool LLParser::parseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM) {
TLM = GlobalVariable::NotThreadLocal;
if (!EatIfPresent(lltok::kw_thread_local))
return false;
@@ -1647,40 +1647,40 @@ bool LLParser::parseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM) {
TLM = GlobalVariable::GeneralDynamicTLSModel;
if (Lex.getKind() == lltok::lparen) {
Lex.Lex();
- return parseTLSModel(TLM) ||
- parseToken(lltok::rparen, "expected ')' after thread local model");
+ return parseTLSModel(TLM) ||
+ parseToken(lltok::rparen, "expected ')' after thread local model");
}
return false;
}
-/// parseOptionalAddrSpace
+/// parseOptionalAddrSpace
/// := /*empty*/
/// := 'addrspace' '(' uint32 ')'
-bool LLParser::parseOptionalAddrSpace(unsigned &AddrSpace, unsigned DefaultAS) {
+bool LLParser::parseOptionalAddrSpace(unsigned &AddrSpace, unsigned DefaultAS) {
AddrSpace = DefaultAS;
if (!EatIfPresent(lltok::kw_addrspace))
return false;
- return parseToken(lltok::lparen, "expected '(' in address space") ||
- parseUInt32(AddrSpace) ||
- parseToken(lltok::rparen, "expected ')' in address space");
+ return parseToken(lltok::lparen, "expected '(' in address space") ||
+ parseUInt32(AddrSpace) ||
+ parseToken(lltok::rparen, "expected ')' in address space");
}
-/// parseStringAttribute
+/// parseStringAttribute
/// := StringConstant
/// := StringConstant '=' StringConstant
-bool LLParser::parseStringAttribute(AttrBuilder &B) {
+bool LLParser::parseStringAttribute(AttrBuilder &B) {
std::string Attr = Lex.getStrVal();
Lex.Lex();
std::string Val;
- if (EatIfPresent(lltok::equal) && parseStringConstant(Val))
+ if (EatIfPresent(lltok::equal) && parseStringConstant(Val))
return true;
B.addAttribute(Attr, Val);
return false;
}
-/// parseOptionalParamAttrs - parse a potentially empty list of parameter
-/// attributes.
-bool LLParser::parseOptionalParamAttrs(AttrBuilder &B) {
+/// parseOptionalParamAttrs - parse a potentially empty list of parameter
+/// attributes.
+bool LLParser::parseOptionalParamAttrs(AttrBuilder &B) {
bool HaveError = false;
B.clear();
@@ -1691,59 +1691,59 @@ bool LLParser::parseOptionalParamAttrs(AttrBuilder &B) {
default: // End of attributes.
return HaveError;
case lltok::StringConstant: {
- if (parseStringAttribute(B))
+ if (parseStringAttribute(B))
return true;
continue;
}
case lltok::kw_align: {
MaybeAlign Alignment;
- if (parseOptionalAlignment(Alignment, true))
+ if (parseOptionalAlignment(Alignment, true))
return true;
B.addAlignmentAttr(Alignment);
continue;
}
case lltok::kw_byval: {
Type *Ty;
- if (parseRequiredTypeAttr(Ty, lltok::kw_byval))
+ if (parseRequiredTypeAttr(Ty, lltok::kw_byval))
return true;
B.addByValAttr(Ty);
continue;
}
- case lltok::kw_sret: {
- Type *Ty;
- if (parseRequiredTypeAttr(Ty, lltok::kw_sret))
- return true;
- B.addStructRetAttr(Ty);
- continue;
- }
+ case lltok::kw_sret: {
+ Type *Ty;
+ if (parseRequiredTypeAttr(Ty, lltok::kw_sret))
+ return true;
+ B.addStructRetAttr(Ty);
+ continue;
+ }
case lltok::kw_preallocated: {
Type *Ty;
- if (parsePreallocated(Ty))
+ if (parsePreallocated(Ty))
return true;
B.addPreallocatedAttr(Ty);
continue;
}
case lltok::kw_dereferenceable: {
uint64_t Bytes;
- if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes))
+ if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes))
return true;
B.addDereferenceableAttr(Bytes);
continue;
}
case lltok::kw_dereferenceable_or_null: {
uint64_t Bytes;
- if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable_or_null, Bytes))
+ if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable_or_null, Bytes))
return true;
B.addDereferenceableOrNullAttr(Bytes);
continue;
}
- case lltok::kw_byref: {
- Type *Ty;
- if (parseByRef(Ty))
- return true;
- B.addByRefAttr(Ty);
- continue;
- }
+ case lltok::kw_byref: {
+ Type *Ty;
+ if (parseByRef(Ty))
+ return true;
+ B.addByRefAttr(Ty);
+ continue;
+ }
case lltok::kw_inalloca: B.addAttribute(Attribute::InAlloca); break;
case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break;
case lltok::kw_nest: B.addAttribute(Attribute::Nest); break;
@@ -1771,7 +1771,7 @@ bool LLParser::parseOptionalParamAttrs(AttrBuilder &B) {
case lltok::kw_inlinehint:
case lltok::kw_jumptable:
case lltok::kw_minsize:
- case lltok::kw_mustprogress:
+ case lltok::kw_mustprogress:
case lltok::kw_naked:
case lltok::kw_nobuiltin:
case lltok::kw_noduplicate:
@@ -1779,7 +1779,7 @@ bool LLParser::parseOptionalParamAttrs(AttrBuilder &B) {
case lltok::kw_noinline:
case lltok::kw_nonlazybind:
case lltok::kw_nomerge:
- case lltok::kw_noprofile:
+ case lltok::kw_noprofile:
case lltok::kw_noredzone:
case lltok::kw_noreturn:
case lltok::kw_nocf_check:
@@ -1801,8 +1801,8 @@ bool LLParser::parseOptionalParamAttrs(AttrBuilder &B) {
case lltok::kw_shadowcallstack:
case lltok::kw_strictfp:
case lltok::kw_uwtable:
- HaveError |=
- error(Lex.getLoc(), "invalid use of function-only attribute");
+ HaveError |=
+ error(Lex.getLoc(), "invalid use of function-only attribute");
break;
}
@@ -1810,9 +1810,9 @@ bool LLParser::parseOptionalParamAttrs(AttrBuilder &B) {
}
}
-/// parseOptionalReturnAttrs - parse a potentially empty list of return
-/// attributes.
-bool LLParser::parseOptionalReturnAttrs(AttrBuilder &B) {
+/// parseOptionalReturnAttrs - parse a potentially empty list of return
+/// attributes.
+bool LLParser::parseOptionalReturnAttrs(AttrBuilder &B) {
bool HaveError = false;
B.clear();
@@ -1823,27 +1823,27 @@ bool LLParser::parseOptionalReturnAttrs(AttrBuilder &B) {
default: // End of attributes.
return HaveError;
case lltok::StringConstant: {
- if (parseStringAttribute(B))
+ if (parseStringAttribute(B))
return true;
continue;
}
case lltok::kw_dereferenceable: {
uint64_t Bytes;
- if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes))
+ if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes))
return true;
B.addDereferenceableAttr(Bytes);
continue;
}
case lltok::kw_dereferenceable_or_null: {
uint64_t Bytes;
- if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable_or_null, Bytes))
+ if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable_or_null, Bytes))
return true;
B.addDereferenceableOrNullAttr(Bytes);
continue;
}
case lltok::kw_align: {
MaybeAlign Alignment;
- if (parseOptionalAlignment(Alignment))
+ if (parseOptionalAlignment(Alignment))
return true;
B.addAlignmentAttr(Alignment);
continue;
@@ -1857,7 +1857,7 @@ bool LLParser::parseOptionalReturnAttrs(AttrBuilder &B) {
case lltok::kw_signext: B.addAttribute(Attribute::SExt); break;
case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break;
- // error handling.
+ // error handling.
case lltok::kw_byval:
case lltok::kw_inalloca:
case lltok::kw_nest:
@@ -1867,9 +1867,9 @@ bool LLParser::parseOptionalReturnAttrs(AttrBuilder &B) {
case lltok::kw_swifterror:
case lltok::kw_swiftself:
case lltok::kw_immarg:
- case lltok::kw_byref:
- HaveError |=
- error(Lex.getLoc(), "invalid use of parameter-only attribute");
+ case lltok::kw_byref:
+ HaveError |=
+ error(Lex.getLoc(), "invalid use of parameter-only attribute");
break;
case lltok::kw_alignstack:
@@ -1880,7 +1880,7 @@ bool LLParser::parseOptionalReturnAttrs(AttrBuilder &B) {
case lltok::kw_inlinehint:
case lltok::kw_jumptable:
case lltok::kw_minsize:
- case lltok::kw_mustprogress:
+ case lltok::kw_mustprogress:
case lltok::kw_naked:
case lltok::kw_nobuiltin:
case lltok::kw_noduplicate:
@@ -1888,7 +1888,7 @@ bool LLParser::parseOptionalReturnAttrs(AttrBuilder &B) {
case lltok::kw_noinline:
case lltok::kw_nonlazybind:
case lltok::kw_nomerge:
- case lltok::kw_noprofile:
+ case lltok::kw_noprofile:
case lltok::kw_noredzone:
case lltok::kw_noreturn:
case lltok::kw_nocf_check:
@@ -1910,17 +1910,17 @@ bool LLParser::parseOptionalReturnAttrs(AttrBuilder &B) {
case lltok::kw_shadowcallstack:
case lltok::kw_strictfp:
case lltok::kw_uwtable:
- HaveError |=
- error(Lex.getLoc(), "invalid use of function-only attribute");
+ HaveError |=
+ error(Lex.getLoc(), "invalid use of function-only attribute");
break;
case lltok::kw_readnone:
case lltok::kw_readonly:
- HaveError |=
- error(Lex.getLoc(), "invalid use of attribute on return type");
+ HaveError |=
+ error(Lex.getLoc(), "invalid use of attribute on return type");
break;
case lltok::kw_preallocated:
HaveError |=
- error(Lex.getLoc(),
+ error(Lex.getLoc(),
"invalid use of parameter-only/call site-only attribute");
break;
}
@@ -1960,7 +1960,7 @@ static unsigned parseOptionalLinkageAux(lltok::Kind Kind, bool &HasLinkage) {
}
}
-/// parseOptionalLinkage
+/// parseOptionalLinkage
/// ::= /*empty*/
/// ::= 'private'
/// ::= 'internal'
@@ -1973,24 +1973,24 @@ static unsigned parseOptionalLinkageAux(lltok::Kind Kind, bool &HasLinkage) {
/// ::= 'common'
/// ::= 'extern_weak'
/// ::= 'external'
-bool LLParser::parseOptionalLinkage(unsigned &Res, bool &HasLinkage,
+bool LLParser::parseOptionalLinkage(unsigned &Res, bool &HasLinkage,
unsigned &Visibility,
- unsigned &DLLStorageClass, bool &DSOLocal) {
+ unsigned &DLLStorageClass, bool &DSOLocal) {
Res = parseOptionalLinkageAux(Lex.getKind(), HasLinkage);
if (HasLinkage)
Lex.Lex();
- parseOptionalDSOLocal(DSOLocal);
- parseOptionalVisibility(Visibility);
- parseOptionalDLLStorageClass(DLLStorageClass);
+ parseOptionalDSOLocal(DSOLocal);
+ parseOptionalVisibility(Visibility);
+ parseOptionalDLLStorageClass(DLLStorageClass);
if (DSOLocal && DLLStorageClass == GlobalValue::DLLImportStorageClass) {
- return error(Lex.getLoc(), "dso_location and DLL-StorageClass mismatch");
+ return error(Lex.getLoc(), "dso_location and DLL-StorageClass mismatch");
}
return false;
}
-void LLParser::parseOptionalDSOLocal(bool &DSOLocal) {
+void LLParser::parseOptionalDSOLocal(bool &DSOLocal) {
switch (Lex.getKind()) {
default:
DSOLocal = false;
@@ -2006,13 +2006,13 @@ void LLParser::parseOptionalDSOLocal(bool &DSOLocal) {
}
}
-/// parseOptionalVisibility
+/// parseOptionalVisibility
/// ::= /*empty*/
/// ::= 'default'
/// ::= 'hidden'
/// ::= 'protected'
///
-void LLParser::parseOptionalVisibility(unsigned &Res) {
+void LLParser::parseOptionalVisibility(unsigned &Res) {
switch (Lex.getKind()) {
default:
Res = GlobalValue::DefaultVisibility;
@@ -2030,12 +2030,12 @@ void LLParser::parseOptionalVisibility(unsigned &Res) {
Lex.Lex();
}
-/// parseOptionalDLLStorageClass
+/// parseOptionalDLLStorageClass
/// ::= /*empty*/
/// ::= 'dllimport'
/// ::= 'dllexport'
///
-void LLParser::parseOptionalDLLStorageClass(unsigned &Res) {
+void LLParser::parseOptionalDLLStorageClass(unsigned &Res) {
switch (Lex.getKind()) {
default:
Res = GlobalValue::DefaultStorageClass;
@@ -2050,7 +2050,7 @@ void LLParser::parseOptionalDLLStorageClass(unsigned &Res) {
Lex.Lex();
}
-/// parseOptionalCallingConv
+/// parseOptionalCallingConv
/// ::= /*empty*/
/// ::= 'ccc'
/// ::= 'fastcc'
@@ -2096,7 +2096,7 @@ void LLParser::parseOptionalDLLStorageClass(unsigned &Res) {
/// ::= 'tailcc'
/// ::= 'cc' UINT
///
-bool LLParser::parseOptionalCallingConv(unsigned &CC) {
+bool LLParser::parseOptionalCallingConv(unsigned &CC) {
switch (Lex.getKind()) {
default: CC = CallingConv::C; return false;
case lltok::kw_ccc: CC = CallingConv::C; break;
@@ -2136,7 +2136,7 @@ bool LLParser::parseOptionalCallingConv(unsigned &CC) {
case lltok::kw_hhvm_ccc: CC = CallingConv::HHVM_C; break;
case lltok::kw_cxx_fast_tlscc: CC = CallingConv::CXX_FAST_TLS; break;
case lltok::kw_amdgpu_vs: CC = CallingConv::AMDGPU_VS; break;
- case lltok::kw_amdgpu_gfx: CC = CallingConv::AMDGPU_Gfx; break;
+ case lltok::kw_amdgpu_gfx: CC = CallingConv::AMDGPU_Gfx; break;
case lltok::kw_amdgpu_ls: CC = CallingConv::AMDGPU_LS; break;
case lltok::kw_amdgpu_hs: CC = CallingConv::AMDGPU_HS; break;
case lltok::kw_amdgpu_es: CC = CallingConv::AMDGPU_ES; break;
@@ -2147,7 +2147,7 @@ bool LLParser::parseOptionalCallingConv(unsigned &CC) {
case lltok::kw_tailcc: CC = CallingConv::Tail; break;
case lltok::kw_cc: {
Lex.Lex();
- return parseUInt32(CC);
+ return parseUInt32(CC);
}
}
@@ -2155,28 +2155,28 @@ bool LLParser::parseOptionalCallingConv(unsigned &CC) {
return false;
}
-/// parseMetadataAttachment
+/// parseMetadataAttachment
/// ::= !dbg !42
-bool LLParser::parseMetadataAttachment(unsigned &Kind, MDNode *&MD) {
+bool LLParser::parseMetadataAttachment(unsigned &Kind, MDNode *&MD) {
assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata attachment");
std::string Name = Lex.getStrVal();
Kind = M->getMDKindID(Name);
Lex.Lex();
- return parseMDNode(MD);
+ return parseMDNode(MD);
}
-/// parseInstructionMetadata
+/// parseInstructionMetadata
/// ::= !dbg !42 (',' !dbg !57)*
-bool LLParser::parseInstructionMetadata(Instruction &Inst) {
+bool LLParser::parseInstructionMetadata(Instruction &Inst) {
do {
if (Lex.getKind() != lltok::MetadataVar)
- return tokError("expected metadata after comma");
+ return tokError("expected metadata after comma");
unsigned MDK;
MDNode *N;
- if (parseMetadataAttachment(MDK, N))
+ if (parseMetadataAttachment(MDK, N))
return true;
Inst.setMetadata(MDK, N);
@@ -2188,31 +2188,31 @@ bool LLParser::parseInstructionMetadata(Instruction &Inst) {
return false;
}
-/// parseGlobalObjectMetadataAttachment
+/// parseGlobalObjectMetadataAttachment
/// ::= !dbg !57
-bool LLParser::parseGlobalObjectMetadataAttachment(GlobalObject &GO) {
+bool LLParser::parseGlobalObjectMetadataAttachment(GlobalObject &GO) {
unsigned MDK;
MDNode *N;
- if (parseMetadataAttachment(MDK, N))
+ if (parseMetadataAttachment(MDK, N))
return true;
GO.addMetadata(MDK, *N);
return false;
}
-/// parseOptionalFunctionMetadata
+/// parseOptionalFunctionMetadata
/// ::= (!dbg !57)*
-bool LLParser::parseOptionalFunctionMetadata(Function &F) {
+bool LLParser::parseOptionalFunctionMetadata(Function &F) {
while (Lex.getKind() == lltok::MetadataVar)
- if (parseGlobalObjectMetadataAttachment(F))
+ if (parseGlobalObjectMetadataAttachment(F))
return true;
return false;
}
-/// parseOptionalAlignment
+/// parseOptionalAlignment
/// ::= /* empty */
/// ::= 'align' 4
-bool LLParser::parseOptionalAlignment(MaybeAlign &Alignment, bool AllowParens) {
+bool LLParser::parseOptionalAlignment(MaybeAlign &Alignment, bool AllowParens) {
Alignment = None;
if (!EatIfPresent(lltok::kw_align))
return false;
@@ -2226,26 +2226,26 @@ bool LLParser::parseOptionalAlignment(MaybeAlign &Alignment, bool AllowParens) {
HaveParens = true;
}
- if (parseUInt32(Value))
+ if (parseUInt32(Value))
return true;
if (HaveParens && !EatIfPresent(lltok::rparen))
- return error(ParenLoc, "expected ')'");
+ return error(ParenLoc, "expected ')'");
if (!isPowerOf2_32(Value))
- return error(AlignLoc, "alignment is not a power of two");
+ return error(AlignLoc, "alignment is not a power of two");
if (Value > Value::MaximumAlignment)
- return error(AlignLoc, "huge alignments are not supported yet");
+ return error(AlignLoc, "huge alignments are not supported yet");
Alignment = Align(Value);
return false;
}
-/// parseOptionalDerefAttrBytes
+/// parseOptionalDerefAttrBytes
/// ::= /* empty */
/// ::= AttrKind '(' 4 ')'
///
/// where AttrKind is either 'dereferenceable' or 'dereferenceable_or_null'.
-bool LLParser::parseOptionalDerefAttrBytes(lltok::Kind AttrKind,
+bool LLParser::parseOptionalDerefAttrBytes(lltok::Kind AttrKind,
uint64_t &Bytes) {
assert((AttrKind == lltok::kw_dereferenceable ||
AttrKind == lltok::kw_dereferenceable_or_null) &&
@@ -2256,25 +2256,25 @@ bool LLParser::parseOptionalDerefAttrBytes(lltok::Kind AttrKind,
return false;
LocTy ParenLoc = Lex.getLoc();
if (!EatIfPresent(lltok::lparen))
- return error(ParenLoc, "expected '('");
+ return error(ParenLoc, "expected '('");
LocTy DerefLoc = Lex.getLoc();
- if (parseUInt64(Bytes))
- return true;
+ if (parseUInt64(Bytes))
+ return true;
ParenLoc = Lex.getLoc();
if (!EatIfPresent(lltok::rparen))
- return error(ParenLoc, "expected ')'");
+ return error(ParenLoc, "expected ')'");
if (!Bytes)
- return error(DerefLoc, "dereferenceable bytes must be non-zero");
+ return error(DerefLoc, "dereferenceable bytes must be non-zero");
return false;
}
-/// parseOptionalCommaAlign
+/// parseOptionalCommaAlign
/// ::=
/// ::= ',' align 4
///
/// This returns with AteExtraComma set to true if it ate an excess comma at the
/// end.
-bool LLParser::parseOptionalCommaAlign(MaybeAlign &Alignment,
+bool LLParser::parseOptionalCommaAlign(MaybeAlign &Alignment,
bool &AteExtraComma) {
AteExtraComma = false;
while (EatIfPresent(lltok::comma)) {
@@ -2285,22 +2285,22 @@ bool LLParser::parseOptionalCommaAlign(MaybeAlign &Alignment,
}
if (Lex.getKind() != lltok::kw_align)
- return error(Lex.getLoc(), "expected metadata or 'align'");
+ return error(Lex.getLoc(), "expected metadata or 'align'");
- if (parseOptionalAlignment(Alignment))
- return true;
+ if (parseOptionalAlignment(Alignment))
+ return true;
}
return false;
}
-/// parseOptionalCommaAddrSpace
+/// parseOptionalCommaAddrSpace
/// ::=
/// ::= ',' addrspace(1)
///
/// This returns with AteExtraComma set to true if it ate an excess comma at the
/// end.
-bool LLParser::parseOptionalCommaAddrSpace(unsigned &AddrSpace, LocTy &Loc,
+bool LLParser::parseOptionalCommaAddrSpace(unsigned &AddrSpace, LocTy &Loc,
bool &AteExtraComma) {
AteExtraComma = false;
while (EatIfPresent(lltok::comma)) {
@@ -2312,9 +2312,9 @@ bool LLParser::parseOptionalCommaAddrSpace(unsigned &AddrSpace, LocTy &Loc,
Loc = Lex.getLoc();
if (Lex.getKind() != lltok::kw_addrspace)
- return error(Lex.getLoc(), "expected metadata or 'addrspace'");
+ return error(Lex.getLoc(), "expected metadata or 'addrspace'");
- if (parseOptionalAddrSpace(AddrSpace))
+ if (parseOptionalAddrSpace(AddrSpace))
return true;
}
@@ -2327,18 +2327,18 @@ bool LLParser::parseAllocSizeArguments(unsigned &BaseSizeArg,
auto StartParen = Lex.getLoc();
if (!EatIfPresent(lltok::lparen))
- return error(StartParen, "expected '('");
+ return error(StartParen, "expected '('");
- if (parseUInt32(BaseSizeArg))
+ if (parseUInt32(BaseSizeArg))
return true;
if (EatIfPresent(lltok::comma)) {
auto HowManyAt = Lex.getLoc();
unsigned HowMany;
- if (parseUInt32(HowMany))
+ if (parseUInt32(HowMany))
return true;
if (HowMany == BaseSizeArg)
- return error(HowManyAt,
+ return error(HowManyAt,
"'allocsize' indices can't refer to the same parameter");
HowManyArg = HowMany;
} else
@@ -2346,42 +2346,42 @@ bool LLParser::parseAllocSizeArguments(unsigned &BaseSizeArg,
auto EndParen = Lex.getLoc();
if (!EatIfPresent(lltok::rparen))
- return error(EndParen, "expected ')'");
+ return error(EndParen, "expected ')'");
return false;
}
-/// parseScopeAndOrdering
+/// parseScopeAndOrdering
/// if isAtomic: ::= SyncScope? AtomicOrdering
/// else: ::=
///
/// This sets Scope and Ordering to the parsed values.
-bool LLParser::parseScopeAndOrdering(bool IsAtomic, SyncScope::ID &SSID,
+bool LLParser::parseScopeAndOrdering(bool IsAtomic, SyncScope::ID &SSID,
AtomicOrdering &Ordering) {
- if (!IsAtomic)
+ if (!IsAtomic)
return false;
- return parseScope(SSID) || parseOrdering(Ordering);
+ return parseScope(SSID) || parseOrdering(Ordering);
}
-/// parseScope
+/// parseScope
/// ::= syncscope("singlethread" | "<target scope>")?
///
/// This sets synchronization scope ID to the ID of the parsed value.
-bool LLParser::parseScope(SyncScope::ID &SSID) {
+bool LLParser::parseScope(SyncScope::ID &SSID) {
SSID = SyncScope::System;
if (EatIfPresent(lltok::kw_syncscope)) {
auto StartParenAt = Lex.getLoc();
if (!EatIfPresent(lltok::lparen))
- return error(StartParenAt, "Expected '(' in syncscope");
+ return error(StartParenAt, "Expected '(' in syncscope");
std::string SSN;
auto SSNAt = Lex.getLoc();
- if (parseStringConstant(SSN))
- return error(SSNAt, "Expected synchronization scope name");
+ if (parseStringConstant(SSN))
+ return error(SSNAt, "Expected synchronization scope name");
auto EndParenAt = Lex.getLoc();
if (!EatIfPresent(lltok::rparen))
- return error(EndParenAt, "Expected ')' in syncscope");
+ return error(EndParenAt, "Expected ')' in syncscope");
SSID = Context.getOrInsertSyncScopeID(SSN);
}
@@ -2389,14 +2389,14 @@ bool LLParser::parseScope(SyncScope::ID &SSID) {
return false;
}
-/// parseOrdering
+/// parseOrdering
/// ::= AtomicOrdering
///
/// This sets Ordering to the parsed value.
-bool LLParser::parseOrdering(AtomicOrdering &Ordering) {
+bool LLParser::parseOrdering(AtomicOrdering &Ordering) {
switch (Lex.getKind()) {
- default:
- return tokError("Expected ordering on atomic instruction");
+ default:
+ return tokError("Expected ordering on atomic instruction");
case lltok::kw_unordered: Ordering = AtomicOrdering::Unordered; break;
case lltok::kw_monotonic: Ordering = AtomicOrdering::Monotonic; break;
// Not specified yet:
@@ -2412,53 +2412,53 @@ bool LLParser::parseOrdering(AtomicOrdering &Ordering) {
return false;
}
-/// parseOptionalStackAlignment
+/// parseOptionalStackAlignment
/// ::= /* empty */
/// ::= 'alignstack' '(' 4 ')'
-bool LLParser::parseOptionalStackAlignment(unsigned &Alignment) {
+bool LLParser::parseOptionalStackAlignment(unsigned &Alignment) {
Alignment = 0;
if (!EatIfPresent(lltok::kw_alignstack))
return false;
LocTy ParenLoc = Lex.getLoc();
if (!EatIfPresent(lltok::lparen))
- return error(ParenLoc, "expected '('");
+ return error(ParenLoc, "expected '('");
LocTy AlignLoc = Lex.getLoc();
- if (parseUInt32(Alignment))
- return true;
+ if (parseUInt32(Alignment))
+ return true;
ParenLoc = Lex.getLoc();
if (!EatIfPresent(lltok::rparen))
- return error(ParenLoc, "expected ')'");
+ return error(ParenLoc, "expected ')'");
if (!isPowerOf2_32(Alignment))
- return error(AlignLoc, "stack alignment is not a power of two");
+ return error(AlignLoc, "stack alignment is not a power of two");
return false;
}
-/// parseIndexList - This parses the index list for an insert/extractvalue
+/// parseIndexList - This parses the index list for an insert/extractvalue
/// instruction. This sets AteExtraComma in the case where we eat an extra
/// comma at the end of the line and find that it is followed by metadata.
/// Clients that don't allow metadata can call the version of this function that
/// only takes one argument.
///
-/// parseIndexList
+/// parseIndexList
/// ::= (',' uint32)+
///
-bool LLParser::parseIndexList(SmallVectorImpl<unsigned> &Indices,
+bool LLParser::parseIndexList(SmallVectorImpl<unsigned> &Indices,
bool &AteExtraComma) {
AteExtraComma = false;
if (Lex.getKind() != lltok::comma)
- return tokError("expected ',' as start of index list");
+ return tokError("expected ',' as start of index list");
while (EatIfPresent(lltok::comma)) {
if (Lex.getKind() == lltok::MetadataVar) {
- if (Indices.empty())
- return tokError("expected index");
+ if (Indices.empty())
+ return tokError("expected index");
AteExtraComma = true;
return false;
}
unsigned Idx = 0;
- if (parseUInt32(Idx))
- return true;
+ if (parseUInt32(Idx))
+ return true;
Indices.push_back(Idx);
}
@@ -2469,12 +2469,12 @@ bool LLParser::parseIndexList(SmallVectorImpl<unsigned> &Indices,
// Type Parsing.
//===----------------------------------------------------------------------===//
-/// parseType - parse a type.
-bool LLParser::parseType(Type *&Result, const Twine &Msg, bool AllowVoid) {
+/// parseType - parse a type.
+bool LLParser::parseType(Type *&Result, const Twine &Msg, bool AllowVoid) {
SMLoc TypeLoc = Lex.getLoc();
switch (Lex.getKind()) {
default:
- return tokError(Msg);
+ return tokError(Msg);
case lltok::Type:
// Type ::= 'float' | 'void' (etc)
Result = Lex.getTyVal();
@@ -2482,23 +2482,23 @@ bool LLParser::parseType(Type *&Result, const Twine &Msg, bool AllowVoid) {
break;
case lltok::lbrace:
// Type ::= StructType
- if (parseAnonStructType(Result, false))
+ if (parseAnonStructType(Result, false))
return true;
break;
case lltok::lsquare:
// Type ::= '[' ... ']'
Lex.Lex(); // eat the lsquare.
- if (parseArrayVectorType(Result, false))
+ if (parseArrayVectorType(Result, false))
return true;
break;
case lltok::less: // Either vector or packed struct.
// Type ::= '<' ... '>'
Lex.Lex();
if (Lex.getKind() == lltok::lbrace) {
- if (parseAnonStructType(Result, true) ||
- parseToken(lltok::greater, "expected '>' at end of packed struct"))
+ if (parseAnonStructType(Result, true) ||
+ parseToken(lltok::greater, "expected '>' at end of packed struct"))
return true;
- } else if (parseArrayVectorType(Result, true))
+ } else if (parseArrayVectorType(Result, true))
return true;
break;
case lltok::LocalVar: {
@@ -2532,23 +2532,23 @@ bool LLParser::parseType(Type *&Result, const Twine &Msg, bool AllowVoid) {
}
}
- // parse the type suffixes.
+ // parse the type suffixes.
while (true) {
switch (Lex.getKind()) {
// End of type.
default:
if (!AllowVoid && Result->isVoidTy())
- return error(TypeLoc, "void type only allowed for function results");
+ return error(TypeLoc, "void type only allowed for function results");
return false;
// Type ::= Type '*'
case lltok::star:
if (Result->isLabelTy())
- return tokError("basic block pointers are invalid");
+ return tokError("basic block pointers are invalid");
if (Result->isVoidTy())
- return tokError("pointers to void are invalid - use i8* instead");
+ return tokError("pointers to void are invalid - use i8* instead");
if (!PointerType::isValidElementType(Result))
- return tokError("pointer to this type is invalid");
+ return tokError("pointer to this type is invalid");
Result = PointerType::getUnqual(Result);
Lex.Lex();
break;
@@ -2556,14 +2556,14 @@ bool LLParser::parseType(Type *&Result, const Twine &Msg, bool AllowVoid) {
// Type ::= Type 'addrspace' '(' uint32 ')' '*'
case lltok::kw_addrspace: {
if (Result->isLabelTy())
- return tokError("basic block pointers are invalid");
+ return tokError("basic block pointers are invalid");
if (Result->isVoidTy())
- return tokError("pointers to void are invalid; use i8* instead");
+ return tokError("pointers to void are invalid; use i8* instead");
if (!PointerType::isValidElementType(Result))
- return tokError("pointer to this type is invalid");
+ return tokError("pointer to this type is invalid");
unsigned AddrSpace;
- if (parseOptionalAddrSpace(AddrSpace) ||
- parseToken(lltok::star, "expected '*' in address space"))
+ if (parseOptionalAddrSpace(AddrSpace) ||
+ parseToken(lltok::star, "expected '*' in address space"))
return true;
Result = PointerType::get(Result, AddrSpace);
@@ -2572,55 +2572,55 @@ bool LLParser::parseType(Type *&Result, const Twine &Msg, bool AllowVoid) {
/// Types '(' ArgTypeListI ')' OptFuncAttrs
case lltok::lparen:
- if (parseFunctionType(Result))
+ if (parseFunctionType(Result))
return true;
break;
}
}
}
-/// parseParameterList
+/// parseParameterList
/// ::= '(' ')'
/// ::= '(' Arg (',' Arg)* ')'
/// Arg
/// ::= Type OptionalAttributes Value OptionalAttributes
-bool LLParser::parseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
+bool LLParser::parseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
PerFunctionState &PFS, bool IsMustTailCall,
bool InVarArgsFunc) {
- if (parseToken(lltok::lparen, "expected '(' in call"))
+ if (parseToken(lltok::lparen, "expected '(' in call"))
return true;
while (Lex.getKind() != lltok::rparen) {
// If this isn't the first argument, we need a comma.
if (!ArgList.empty() &&
- parseToken(lltok::comma, "expected ',' in argument list"))
+ parseToken(lltok::comma, "expected ',' in argument list"))
return true;
- // parse an ellipsis if this is a musttail call in a variadic function.
+ // parse an ellipsis if this is a musttail call in a variadic function.
if (Lex.getKind() == lltok::dotdotdot) {
const char *Msg = "unexpected ellipsis in argument list for ";
if (!IsMustTailCall)
- return tokError(Twine(Msg) + "non-musttail call");
+ return tokError(Twine(Msg) + "non-musttail call");
if (!InVarArgsFunc)
- return tokError(Twine(Msg) + "musttail call in non-varargs function");
+ return tokError(Twine(Msg) + "musttail call in non-varargs function");
Lex.Lex(); // Lex the '...', it is purely for readability.
- return parseToken(lltok::rparen, "expected ')' at end of argument list");
+ return parseToken(lltok::rparen, "expected ')' at end of argument list");
}
- // parse the argument.
+ // parse the argument.
LocTy ArgLoc;
Type *ArgTy = nullptr;
AttrBuilder ArgAttrs;
Value *V;
- if (parseType(ArgTy, ArgLoc))
+ if (parseType(ArgTy, ArgLoc))
return true;
if (ArgTy->isMetadataTy()) {
- if (parseMetadataAsValue(V, PFS))
+ if (parseMetadataAsValue(V, PFS))
return true;
} else {
// Otherwise, handle normal operands.
- if (parseOptionalParamAttrs(ArgAttrs) || parseValue(ArgTy, V, PFS))
+ if (parseOptionalParamAttrs(ArgAttrs) || parseValue(ArgTy, V, PFS))
return true;
}
ArgList.push_back(ParamInfo(
@@ -2628,41 +2628,41 @@ bool LLParser::parseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
}
if (IsMustTailCall && InVarArgsFunc)
- return tokError("expected '...' at end of argument list for musttail call "
+ return tokError("expected '...' at end of argument list for musttail call "
"in varargs function");
Lex.Lex(); // Lex the ')'.
return false;
}
-/// parseRequiredTypeAttr
-/// ::= attrname(<ty>)
-bool LLParser::parseRequiredTypeAttr(Type *&Result, lltok::Kind AttrName) {
+/// parseRequiredTypeAttr
+/// ::= attrname(<ty>)
+bool LLParser::parseRequiredTypeAttr(Type *&Result, lltok::Kind AttrName) {
Result = nullptr;
- if (!EatIfPresent(AttrName))
+ if (!EatIfPresent(AttrName))
return true;
if (!EatIfPresent(lltok::lparen))
- return error(Lex.getLoc(), "expected '('");
- if (parseType(Result))
+ return error(Lex.getLoc(), "expected '('");
+ if (parseType(Result))
return true;
if (!EatIfPresent(lltok::rparen))
- return error(Lex.getLoc(), "expected ')'");
+ return error(Lex.getLoc(), "expected ')'");
return false;
}
-/// parsePreallocated
+/// parsePreallocated
/// ::= preallocated(<ty>)
-bool LLParser::parsePreallocated(Type *&Result) {
- return parseRequiredTypeAttr(Result, lltok::kw_preallocated);
+bool LLParser::parsePreallocated(Type *&Result) {
+ return parseRequiredTypeAttr(Result, lltok::kw_preallocated);
+}
+
+/// parseByRef
+/// ::= byref(<type>)
+bool LLParser::parseByRef(Type *&Result) {
+ return parseRequiredTypeAttr(Result, lltok::kw_byref);
}
-/// parseByRef
-/// ::= byref(<type>)
-bool LLParser::parseByRef(Type *&Result) {
- return parseRequiredTypeAttr(Result, lltok::kw_byref);
-}
-
-/// parseOptionalOperandBundles
+/// parseOptionalOperandBundles
/// ::= /*empty*/
/// ::= '[' OperandBundle [, OperandBundle ]* ']'
///
@@ -2671,7 +2671,7 @@ bool LLParser::parseByRef(Type *&Result) {
/// ::= bundle-tag '(' Type Value [, Type Value ]* ')'
///
/// bundle-tag ::= String Constant
-bool LLParser::parseOptionalOperandBundles(
+bool LLParser::parseOptionalOperandBundles(
SmallVectorImpl<OperandBundleDef> &BundleList, PerFunctionState &PFS) {
LocTy BeginLoc = Lex.getLoc();
if (!EatIfPresent(lltok::lsquare))
@@ -2680,26 +2680,26 @@ bool LLParser::parseOptionalOperandBundles(
while (Lex.getKind() != lltok::rsquare) {
// If this isn't the first operand bundle, we need a comma.
if (!BundleList.empty() &&
- parseToken(lltok::comma, "expected ',' in input list"))
+ parseToken(lltok::comma, "expected ',' in input list"))
return true;
std::string Tag;
- if (parseStringConstant(Tag))
+ if (parseStringConstant(Tag))
return true;
- if (parseToken(lltok::lparen, "expected '(' in operand bundle"))
+ if (parseToken(lltok::lparen, "expected '(' in operand bundle"))
return true;
std::vector<Value *> Inputs;
while (Lex.getKind() != lltok::rparen) {
// If this isn't the first input, we need a comma.
if (!Inputs.empty() &&
- parseToken(lltok::comma, "expected ',' in input list"))
+ parseToken(lltok::comma, "expected ',' in input list"))
return true;
Type *Ty = nullptr;
Value *Input = nullptr;
- if (parseType(Ty) || parseValue(Ty, Input, PFS))
+ if (parseType(Ty) || parseValue(Ty, Input, PFS))
return true;
Inputs.push_back(Input);
}
@@ -2710,13 +2710,13 @@ bool LLParser::parseOptionalOperandBundles(
}
if (BundleList.empty())
- return error(BeginLoc, "operand bundle set must not be empty");
+ return error(BeginLoc, "operand bundle set must not be empty");
Lex.Lex(); // Lex the ']'.
return false;
}
-/// parseArgumentList - parse the argument list for a function type or function
+/// parseArgumentList - parse the argument list for a function type or function
/// prototype.
/// ::= '(' ArgTypeListI ')'
/// ArgTypeListI
@@ -2725,17 +2725,17 @@ bool LLParser::parseOptionalOperandBundles(
/// ::= ArgTypeList ',' '...'
/// ::= ArgType (',' ArgType)*
///
-bool LLParser::parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
- bool &IsVarArg) {
+bool LLParser::parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
+ bool &IsVarArg) {
unsigned CurValID = 0;
- IsVarArg = false;
+ IsVarArg = false;
assert(Lex.getKind() == lltok::lparen);
Lex.Lex(); // eat the (.
if (Lex.getKind() == lltok::rparen) {
// empty
} else if (Lex.getKind() == lltok::dotdotdot) {
- IsVarArg = true;
+ IsVarArg = true;
Lex.Lex();
} else {
LocTy TypeLoc = Lex.getLoc();
@@ -2743,25 +2743,25 @@ bool LLParser::parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
AttrBuilder Attrs;
std::string Name;
- if (parseType(ArgTy) || parseOptionalParamAttrs(Attrs))
- return true;
+ if (parseType(ArgTy) || parseOptionalParamAttrs(Attrs))
+ return true;
if (ArgTy->isVoidTy())
- return error(TypeLoc, "argument can not have void type");
+ return error(TypeLoc, "argument can not have void type");
if (Lex.getKind() == lltok::LocalVar) {
Name = Lex.getStrVal();
Lex.Lex();
} else if (Lex.getKind() == lltok::LocalVarID) {
if (Lex.getUIntVal() != CurValID)
- return error(TypeLoc, "argument expected to be numbered '%" +
+ return error(TypeLoc, "argument expected to be numbered '%" +
Twine(CurValID) + "'");
++CurValID;
Lex.Lex();
}
if (!FunctionType::isValidArgumentType(ArgTy))
- return error(TypeLoc, "invalid type for function argument");
+ return error(TypeLoc, "invalid type for function argument");
ArgList.emplace_back(TypeLoc, ArgTy,
AttributeSet::get(ArgTy->getContext(), Attrs),
@@ -2770,17 +2770,17 @@ bool LLParser::parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
while (EatIfPresent(lltok::comma)) {
// Handle ... at end of arg list.
if (EatIfPresent(lltok::dotdotdot)) {
- IsVarArg = true;
+ IsVarArg = true;
break;
}
// Otherwise must be an argument type.
TypeLoc = Lex.getLoc();
- if (parseType(ArgTy) || parseOptionalParamAttrs(Attrs))
- return true;
+ if (parseType(ArgTy) || parseOptionalParamAttrs(Attrs))
+ return true;
if (ArgTy->isVoidTy())
- return error(TypeLoc, "argument can not have void type");
+ return error(TypeLoc, "argument can not have void type");
if (Lex.getKind() == lltok::LocalVar) {
Name = Lex.getStrVal();
@@ -2788,7 +2788,7 @@ bool LLParser::parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
} else {
if (Lex.getKind() == lltok::LocalVarID) {
if (Lex.getUIntVal() != CurValID)
- return error(TypeLoc, "argument expected to be numbered '%" +
+ return error(TypeLoc, "argument expected to be numbered '%" +
Twine(CurValID) + "'");
Lex.Lex();
}
@@ -2797,7 +2797,7 @@ bool LLParser::parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
}
if (!ArgTy->isFirstClassType())
- return error(TypeLoc, "invalid type for function argument");
+ return error(TypeLoc, "invalid type for function argument");
ArgList.emplace_back(TypeLoc, ArgTy,
AttributeSet::get(ArgTy->getContext(), Attrs),
@@ -2805,28 +2805,28 @@ bool LLParser::parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
}
}
- return parseToken(lltok::rparen, "expected ')' at end of argument list");
+ return parseToken(lltok::rparen, "expected ')' at end of argument list");
}
-/// parseFunctionType
+/// parseFunctionType
/// ::= Type ArgumentList OptionalAttrs
-bool LLParser::parseFunctionType(Type *&Result) {
+bool LLParser::parseFunctionType(Type *&Result) {
assert(Lex.getKind() == lltok::lparen);
if (!FunctionType::isValidReturnType(Result))
- return tokError("invalid function return type");
+ return tokError("invalid function return type");
SmallVector<ArgInfo, 8> ArgList;
- bool IsVarArg;
- if (parseArgumentList(ArgList, IsVarArg))
+ bool IsVarArg;
+ if (parseArgumentList(ArgList, IsVarArg))
return true;
// Reject names on the arguments lists.
for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
if (!ArgList[i].Name.empty())
- return error(ArgList[i].Loc, "argument name invalid in function type");
+ return error(ArgList[i].Loc, "argument name invalid in function type");
if (ArgList[i].Attrs.hasAttributes())
- return error(ArgList[i].Loc,
+ return error(ArgList[i].Loc,
"argument attributes invalid in function type");
}
@@ -2834,28 +2834,28 @@ bool LLParser::parseFunctionType(Type *&Result) {
for (unsigned i = 0, e = ArgList.size(); i != e; ++i)
ArgListTy.push_back(ArgList[i].Ty);
- Result = FunctionType::get(Result, ArgListTy, IsVarArg);
+ Result = FunctionType::get(Result, ArgListTy, IsVarArg);
return false;
}
-/// parseAnonStructType - parse an anonymous struct type, which is inlined into
+/// parseAnonStructType - parse an anonymous struct type, which is inlined into
/// other structs.
-bool LLParser::parseAnonStructType(Type *&Result, bool Packed) {
+bool LLParser::parseAnonStructType(Type *&Result, bool Packed) {
SmallVector<Type*, 8> Elts;
- if (parseStructBody(Elts))
- return true;
+ if (parseStructBody(Elts))
+ return true;
Result = StructType::get(Context, Elts, Packed);
return false;
}
-/// parseStructDefinition - parse a struct in a 'type' definition.
-bool LLParser::parseStructDefinition(SMLoc TypeLoc, StringRef Name,
- std::pair<Type *, LocTy> &Entry,
+/// parseStructDefinition - parse a struct in a 'type' definition.
+bool LLParser::parseStructDefinition(SMLoc TypeLoc, StringRef Name,
+ std::pair<Type *, LocTy> &Entry,
Type *&ResultTy) {
// If the type was already defined, diagnose the redefinition.
if (Entry.first && !Entry.second.isValid())
- return error(TypeLoc, "redefinition of type");
+ return error(TypeLoc, "redefinition of type");
// If we have opaque, just return without filling in the definition for the
// struct. This counts as a definition as far as the .ll file goes.
@@ -2878,12 +2878,12 @@ bool LLParser::parseStructDefinition(SMLoc TypeLoc, StringRef Name,
// forward referenced and not allowed to be recursive.
if (Lex.getKind() != lltok::lbrace) {
if (Entry.first)
- return error(TypeLoc, "forward references to non-struct type");
+ return error(TypeLoc, "forward references to non-struct type");
ResultTy = nullptr;
if (isPacked)
- return parseArrayVectorType(ResultTy, true);
- return parseType(ResultTy);
+ return parseArrayVectorType(ResultTy, true);
+ return parseType(ResultTy);
}
// This type is being defined, so clear the location to indicate this.
@@ -2896,8 +2896,8 @@ bool LLParser::parseStructDefinition(SMLoc TypeLoc, StringRef Name,
StructType *STy = cast<StructType>(Entry.first);
SmallVector<Type*, 8> Body;
- if (parseStructBody(Body) ||
- (isPacked && parseToken(lltok::greater, "expected '>' in packed struct")))
+ if (parseStructBody(Body) ||
+ (isPacked && parseToken(lltok::greater, "expected '>' in packed struct")))
return true;
STy->setBody(Body, isPacked);
@@ -2905,13 +2905,13 @@ bool LLParser::parseStructDefinition(SMLoc TypeLoc, StringRef Name,
return false;
}
-/// parseStructType: Handles packed and unpacked types. </> parsed elsewhere.
+/// parseStructType: Handles packed and unpacked types. </> parsed elsewhere.
/// StructType
/// ::= '{' '}'
/// ::= '{' Type (',' Type)* '}'
/// ::= '<' '{' '}' '>'
/// ::= '<' '{' Type (',' Type)* '}' '>'
-bool LLParser::parseStructBody(SmallVectorImpl<Type *> &Body) {
+bool LLParser::parseStructBody(SmallVectorImpl<Type *> &Body) {
assert(Lex.getKind() == lltok::lbrace);
Lex.Lex(); // Consume the '{'
@@ -2921,39 +2921,39 @@ bool LLParser::parseStructBody(SmallVectorImpl<Type *> &Body) {
LocTy EltTyLoc = Lex.getLoc();
Type *Ty = nullptr;
- if (parseType(Ty))
- return true;
+ if (parseType(Ty))
+ return true;
Body.push_back(Ty);
if (!StructType::isValidElementType(Ty))
- return error(EltTyLoc, "invalid element type for struct");
+ return error(EltTyLoc, "invalid element type for struct");
while (EatIfPresent(lltok::comma)) {
EltTyLoc = Lex.getLoc();
- if (parseType(Ty))
- return true;
+ if (parseType(Ty))
+ return true;
if (!StructType::isValidElementType(Ty))
- return error(EltTyLoc, "invalid element type for struct");
+ return error(EltTyLoc, "invalid element type for struct");
Body.push_back(Ty);
}
- return parseToken(lltok::rbrace, "expected '}' at end of struct");
+ return parseToken(lltok::rbrace, "expected '}' at end of struct");
}
-/// parseArrayVectorType - parse an array or vector type, assuming the first
+/// parseArrayVectorType - parse an array or vector type, assuming the first
/// token has already been consumed.
/// Type
/// ::= '[' APSINTVAL 'x' Types ']'
/// ::= '<' APSINTVAL 'x' Types '>'
/// ::= '<' 'vscale' 'x' APSINTVAL 'x' Types '>'
-bool LLParser::parseArrayVectorType(Type *&Result, bool IsVector) {
+bool LLParser::parseArrayVectorType(Type *&Result, bool IsVector) {
bool Scalable = false;
- if (IsVector && Lex.getKind() == lltok::kw_vscale) {
+ if (IsVector && Lex.getKind() == lltok::kw_vscale) {
Lex.Lex(); // consume the 'vscale'
- if (parseToken(lltok::kw_x, "expected 'x' after vscale"))
+ if (parseToken(lltok::kw_x, "expected 'x' after vscale"))
return true;
Scalable = true;
@@ -2961,35 +2961,35 @@ bool LLParser::parseArrayVectorType(Type *&Result, bool IsVector) {
if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned() ||
Lex.getAPSIntVal().getBitWidth() > 64)
- return tokError("expected number in address space");
+ return tokError("expected number in address space");
LocTy SizeLoc = Lex.getLoc();
uint64_t Size = Lex.getAPSIntVal().getZExtValue();
Lex.Lex();
- if (parseToken(lltok::kw_x, "expected 'x' after element count"))
- return true;
+ if (parseToken(lltok::kw_x, "expected 'x' after element count"))
+ return true;
LocTy TypeLoc = Lex.getLoc();
Type *EltTy = nullptr;
- if (parseType(EltTy))
- return true;
+ if (parseType(EltTy))
+ return true;
- if (parseToken(IsVector ? lltok::greater : lltok::rsquare,
+ if (parseToken(IsVector ? lltok::greater : lltok::rsquare,
"expected end of sequential type"))
return true;
- if (IsVector) {
+ if (IsVector) {
if (Size == 0)
- return error(SizeLoc, "zero element vector is illegal");
+ return error(SizeLoc, "zero element vector is illegal");
if ((unsigned)Size != Size)
- return error(SizeLoc, "size too large for vector");
+ return error(SizeLoc, "size too large for vector");
if (!VectorType::isValidElementType(EltTy))
- return error(TypeLoc, "invalid vector element type");
+ return error(TypeLoc, "invalid vector element type");
Result = VectorType::get(EltTy, unsigned(Size), Scalable);
} else {
if (!ArrayType::isValidElementType(EltTy))
- return error(TypeLoc, "invalid array element type");
+ return error(TypeLoc, "invalid array element type");
Result = ArrayType::get(EltTy, Size);
}
return false;
@@ -3029,22 +3029,22 @@ LLParser::PerFunctionState::~PerFunctionState() {
}
}
-bool LLParser::PerFunctionState::finishFunction() {
+bool LLParser::PerFunctionState::finishFunction() {
if (!ForwardRefVals.empty())
- return P.error(ForwardRefVals.begin()->second.second,
+ return P.error(ForwardRefVals.begin()->second.second,
"use of undefined value '%" + ForwardRefVals.begin()->first +
- "'");
+ "'");
if (!ForwardRefValIDs.empty())
- return P.error(ForwardRefValIDs.begin()->second.second,
+ return P.error(ForwardRefValIDs.begin()->second.second,
"use of undefined value '%" +
- Twine(ForwardRefValIDs.begin()->first) + "'");
+ Twine(ForwardRefValIDs.begin()->first) + "'");
return false;
}
-/// getVal - Get a value with the specified name or ID, creating a
+/// getVal - Get a value with the specified name or ID, creating a
/// forward reference record if needed. This can return null if the value
/// exists but does not have the right type.
-Value *LLParser::PerFunctionState::getVal(const std::string &Name, Type *Ty,
+Value *LLParser::PerFunctionState::getVal(const std::string &Name, Type *Ty,
LocTy Loc, bool IsCall) {
// Look this name up in the normal function symbol table.
Value *Val = F.getValueSymbolTable()->lookup(Name);
@@ -3063,7 +3063,7 @@ Value *LLParser::PerFunctionState::getVal(const std::string &Name, Type *Ty,
// Don't make placeholders with invalid type.
if (!Ty->isFirstClassType()) {
- P.error(Loc, "invalid use of a non-first-class type");
+ P.error(Loc, "invalid use of a non-first-class type");
return nullptr;
}
@@ -3079,7 +3079,7 @@ Value *LLParser::PerFunctionState::getVal(const std::string &Name, Type *Ty,
return FwdVal;
}
-Value *LLParser::PerFunctionState::getVal(unsigned ID, Type *Ty, LocTy Loc,
+Value *LLParser::PerFunctionState::getVal(unsigned ID, Type *Ty, LocTy Loc,
bool IsCall) {
// Look this name up in the normal function symbol table.
Value *Val = ID < NumberedVals.size() ? NumberedVals[ID] : nullptr;
@@ -3097,7 +3097,7 @@ Value *LLParser::PerFunctionState::getVal(unsigned ID, Type *Ty, LocTy Loc,
return P.checkValidVariableType(Loc, "%" + Twine(ID), Ty, Val, IsCall);
if (!Ty->isFirstClassType()) {
- P.error(Loc, "invalid use of a non-first-class type");
+ P.error(Loc, "invalid use of a non-first-class type");
return nullptr;
}
@@ -3113,15 +3113,15 @@ Value *LLParser::PerFunctionState::getVal(unsigned ID, Type *Ty, LocTy Loc,
return FwdVal;
}
-/// setInstName - After an instruction is parsed and inserted into its
+/// setInstName - After an instruction is parsed and inserted into its
/// basic block, this installs its name.
-bool LLParser::PerFunctionState::setInstName(int NameID,
+bool LLParser::PerFunctionState::setInstName(int NameID,
const std::string &NameStr,
LocTy NameLoc, Instruction *Inst) {
// If this instruction has void type, it cannot have a name or ID specified.
if (Inst->getType()->isVoidTy()) {
if (NameID != -1 || !NameStr.empty())
- return P.error(NameLoc, "instructions returning void cannot have a name");
+ return P.error(NameLoc, "instructions returning void cannot have a name");
return false;
}
@@ -3133,16 +3133,16 @@ bool LLParser::PerFunctionState::setInstName(int NameID,
NameID = NumberedVals.size();
if (unsigned(NameID) != NumberedVals.size())
- return P.error(NameLoc, "instruction expected to be numbered '%" +
- Twine(NumberedVals.size()) + "'");
+ return P.error(NameLoc, "instruction expected to be numbered '%" +
+ Twine(NumberedVals.size()) + "'");
auto FI = ForwardRefValIDs.find(NameID);
if (FI != ForwardRefValIDs.end()) {
Value *Sentinel = FI->second.first;
if (Sentinel->getType() != Inst->getType())
- return P.error(NameLoc, "instruction forward referenced with type '" +
- getTypeString(FI->second.first->getType()) +
- "'");
+ return P.error(NameLoc, "instruction forward referenced with type '" +
+ getTypeString(FI->second.first->getType()) +
+ "'");
Sentinel->replaceAllUsesWith(Inst);
Sentinel->deleteValue();
@@ -3158,9 +3158,9 @@ bool LLParser::PerFunctionState::setInstName(int NameID,
if (FI != ForwardRefVals.end()) {
Value *Sentinel = FI->second.first;
if (Sentinel->getType() != Inst->getType())
- return P.error(NameLoc, "instruction forward referenced with type '" +
- getTypeString(FI->second.first->getType()) +
- "'");
+ return P.error(NameLoc, "instruction forward referenced with type '" +
+ getTypeString(FI->second.first->getType()) +
+ "'");
Sentinel->replaceAllUsesWith(Inst);
Sentinel->deleteValue();
@@ -3171,46 +3171,46 @@ bool LLParser::PerFunctionState::setInstName(int NameID,
Inst->setName(NameStr);
if (Inst->getName() != NameStr)
- return P.error(NameLoc, "multiple definition of local value named '" +
- NameStr + "'");
+ return P.error(NameLoc, "multiple definition of local value named '" +
+ NameStr + "'");
return false;
}
-/// getBB - Get a basic block with the specified name or ID, creating a
+/// getBB - Get a basic block with the specified name or ID, creating a
/// forward reference record if needed.
-BasicBlock *LLParser::PerFunctionState::getBB(const std::string &Name,
+BasicBlock *LLParser::PerFunctionState::getBB(const std::string &Name,
LocTy Loc) {
return dyn_cast_or_null<BasicBlock>(
- getVal(Name, Type::getLabelTy(F.getContext()), Loc, /*IsCall=*/false));
+ getVal(Name, Type::getLabelTy(F.getContext()), Loc, /*IsCall=*/false));
}
-BasicBlock *LLParser::PerFunctionState::getBB(unsigned ID, LocTy Loc) {
+BasicBlock *LLParser::PerFunctionState::getBB(unsigned ID, LocTy Loc) {
return dyn_cast_or_null<BasicBlock>(
- getVal(ID, Type::getLabelTy(F.getContext()), Loc, /*IsCall=*/false));
+ getVal(ID, Type::getLabelTy(F.getContext()), Loc, /*IsCall=*/false));
}
-/// defineBB - Define the specified basic block, which is either named or
+/// defineBB - Define the specified basic block, which is either named or
/// unnamed. If there is an error, this returns null otherwise it returns
/// the block being defined.
-BasicBlock *LLParser::PerFunctionState::defineBB(const std::string &Name,
+BasicBlock *LLParser::PerFunctionState::defineBB(const std::string &Name,
int NameID, LocTy Loc) {
BasicBlock *BB;
if (Name.empty()) {
if (NameID != -1 && unsigned(NameID) != NumberedVals.size()) {
- P.error(Loc, "label expected to be numbered '" +
+ P.error(Loc, "label expected to be numbered '" +
Twine(NumberedVals.size()) + "'");
return nullptr;
}
- BB = getBB(NumberedVals.size(), Loc);
+ BB = getBB(NumberedVals.size(), Loc);
if (!BB) {
- P.error(Loc, "unable to create block numbered '" +
+ P.error(Loc, "unable to create block numbered '" +
Twine(NumberedVals.size()) + "'");
return nullptr;
}
} else {
- BB = getBB(Name, Loc);
+ BB = getBB(Name, Loc);
if (!BB) {
- P.error(Loc, "unable to create block named '" + Name + "'");
+ P.error(Loc, "unable to create block named '" + Name + "'");
return nullptr;
}
}
@@ -3235,17 +3235,17 @@ BasicBlock *LLParser::PerFunctionState::defineBB(const std::string &Name,
// Constants.
//===----------------------------------------------------------------------===//
-/// parseValID - parse an abstract value that doesn't necessarily have a
+/// parseValID - parse an abstract value that doesn't necessarily have a
/// type implied. For example, if we parse "4" we don't know what integer type
/// it has. The value will later be combined with its type and checked for
/// sanity. PFS is used to convert function-local operands of metadata (since
/// metadata operands are not just parsed here but also converted to values).
/// PFS can be null when we are not parsing metadata values inside a function.
-bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
+bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
ID.Loc = Lex.getLoc();
switch (Lex.getKind()) {
- default:
- return tokError("expected value token");
+ default:
+ return tokError("expected value token");
case lltok::GlobalID: // @42
ID.UIntVal = Lex.getUIntVal();
ID.Kind = ValID::t_GlobalID;
@@ -3280,7 +3280,7 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
break;
case lltok::kw_null: ID.Kind = ValID::t_Null; break;
case lltok::kw_undef: ID.Kind = ValID::t_Undef; break;
- case lltok::kw_poison: ID.Kind = ValID::t_Poison; break;
+ case lltok::kw_poison: ID.Kind = ValID::t_Poison; break;
case lltok::kw_zeroinitializer: ID.Kind = ValID::t_Zero; break;
case lltok::kw_none: ID.Kind = ValID::t_None; break;
@@ -3288,8 +3288,8 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
// ValID ::= '{' ConstVector '}'
Lex.Lex();
SmallVector<Constant*, 16> Elts;
- if (parseGlobalValueVector(Elts) ||
- parseToken(lltok::rbrace, "expected end of struct constant"))
+ if (parseGlobalValueVector(Elts) ||
+ parseToken(lltok::rbrace, "expected end of struct constant"))
return true;
ID.ConstantStructElts = std::make_unique<Constant *[]>(Elts.size());
@@ -3307,10 +3307,10 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
SmallVector<Constant*, 16> Elts;
LocTy FirstEltLoc = Lex.getLoc();
- if (parseGlobalValueVector(Elts) ||
+ if (parseGlobalValueVector(Elts) ||
(isPackedStruct &&
- parseToken(lltok::rbrace, "expected end of packed struct")) ||
- parseToken(lltok::greater, "expected end of constant"))
+ parseToken(lltok::rbrace, "expected end of packed struct")) ||
+ parseToken(lltok::greater, "expected end of constant"))
return true;
if (isPackedStruct) {
@@ -3323,21 +3323,21 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
}
if (Elts.empty())
- return error(ID.Loc, "constant vector must not be empty");
+ return error(ID.Loc, "constant vector must not be empty");
if (!Elts[0]->getType()->isIntegerTy() &&
!Elts[0]->getType()->isFloatingPointTy() &&
!Elts[0]->getType()->isPointerTy())
- return error(
- FirstEltLoc,
- "vector elements must have integer, pointer or floating point type");
+ return error(
+ FirstEltLoc,
+ "vector elements must have integer, pointer or floating point type");
// Verify that all the vector elements have the same type.
for (unsigned i = 1, e = Elts.size(); i != e; ++i)
if (Elts[i]->getType() != Elts[0]->getType())
- return error(FirstEltLoc, "vector element #" + Twine(i) +
- " is not of type '" +
- getTypeString(Elts[0]->getType()));
+ return error(FirstEltLoc, "vector element #" + Twine(i) +
+ " is not of type '" +
+ getTypeString(Elts[0]->getType()));
ID.ConstantVal = ConstantVector::get(Elts);
ID.Kind = ValID::t_Constant;
@@ -3347,8 +3347,8 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
Lex.Lex();
SmallVector<Constant*, 16> Elts;
LocTy FirstEltLoc = Lex.getLoc();
- if (parseGlobalValueVector(Elts) ||
- parseToken(lltok::rsquare, "expected end of array constant"))
+ if (parseGlobalValueVector(Elts) ||
+ parseToken(lltok::rsquare, "expected end of array constant"))
return true;
// Handle empty element.
@@ -3360,17 +3360,17 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
}
if (!Elts[0]->getType()->isFirstClassType())
- return error(FirstEltLoc, "invalid array element type: " +
- getTypeString(Elts[0]->getType()));
+ return error(FirstEltLoc, "invalid array element type: " +
+ getTypeString(Elts[0]->getType()));
ArrayType *ATy = ArrayType::get(Elts[0]->getType(), Elts.size());
// Verify all elements are correct type!
for (unsigned i = 0, e = Elts.size(); i != e; ++i) {
if (Elts[i]->getType() != Elts[0]->getType())
- return error(FirstEltLoc, "array element #" + Twine(i) +
- " is not of type '" +
- getTypeString(Elts[0]->getType()));
+ return error(FirstEltLoc, "array element #" + Twine(i) +
+ " is not of type '" +
+ getTypeString(Elts[0]->getType()));
}
ID.ConstantVal = ConstantArray::get(ATy, Elts);
@@ -3381,8 +3381,8 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
Lex.Lex();
ID.ConstantVal = ConstantDataArray::getString(Context, Lex.getStrVal(),
false);
- if (parseToken(lltok::StringConstant, "expected string"))
- return true;
+ if (parseToken(lltok::StringConstant, "expected string"))
+ return true;
ID.Kind = ValID::t_Constant;
return false;
@@ -3391,12 +3391,12 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
// STRINGCONSTANT
bool HasSideEffect, AlignStack, AsmDialect;
Lex.Lex();
- if (parseOptionalToken(lltok::kw_sideeffect, HasSideEffect) ||
- parseOptionalToken(lltok::kw_alignstack, AlignStack) ||
- parseOptionalToken(lltok::kw_inteldialect, AsmDialect) ||
- parseStringConstant(ID.StrVal) ||
- parseToken(lltok::comma, "expected comma in inline asm expression") ||
- parseToken(lltok::StringConstant, "expected constraint string"))
+ if (parseOptionalToken(lltok::kw_sideeffect, HasSideEffect) ||
+ parseOptionalToken(lltok::kw_alignstack, AlignStack) ||
+ parseOptionalToken(lltok::kw_inteldialect, AsmDialect) ||
+ parseStringConstant(ID.StrVal) ||
+ parseToken(lltok::comma, "expected comma in inline asm expression") ||
+ parseToken(lltok::StringConstant, "expected constraint string"))
return true;
ID.StrVal2 = Lex.getStrVal();
ID.UIntVal = unsigned(HasSideEffect) | (unsigned(AlignStack)<<1) |
@@ -3411,18 +3411,18 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
ValID Fn, Label;
- if (parseToken(lltok::lparen, "expected '(' in block address expression") ||
- parseValID(Fn) ||
- parseToken(lltok::comma,
- "expected comma in block address expression") ||
- parseValID(Label) ||
- parseToken(lltok::rparen, "expected ')' in block address expression"))
+ if (parseToken(lltok::lparen, "expected '(' in block address expression") ||
+ parseValID(Fn) ||
+ parseToken(lltok::comma,
+ "expected comma in block address expression") ||
+ parseValID(Label) ||
+ parseToken(lltok::rparen, "expected ')' in block address expression"))
return true;
if (Fn.Kind != ValID::t_GlobalID && Fn.Kind != ValID::t_GlobalName)
- return error(Fn.Loc, "expected function name in blockaddress");
+ return error(Fn.Loc, "expected function name in blockaddress");
if (Label.Kind != ValID::t_LocalID && Label.Kind != ValID::t_LocalName)
- return error(Label.Loc, "expected basic block name in blockaddress");
+ return error(Label.Loc, "expected basic block name in blockaddress");
// Try to find the function (but skip it if it's forward-referenced).
GlobalValue *GV = nullptr;
@@ -3436,10 +3436,10 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
if (GV) {
// Confirm that it's actually a function with a definition.
if (!isa<Function>(GV))
- return error(Fn.Loc, "expected function name in blockaddress");
+ return error(Fn.Loc, "expected function name in blockaddress");
F = cast<Function>(GV);
if (F->isDeclaration())
- return error(Fn.Loc, "cannot take blockaddress inside a declaration");
+ return error(Fn.Loc, "cannot take blockaddress inside a declaration");
}
if (!F) {
@@ -3463,19 +3463,19 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
BasicBlock *BB;
if (BlockAddressPFS && F == &BlockAddressPFS->getFunction()) {
if (Label.Kind == ValID::t_LocalID)
- BB = BlockAddressPFS->getBB(Label.UIntVal, Label.Loc);
+ BB = BlockAddressPFS->getBB(Label.UIntVal, Label.Loc);
else
- BB = BlockAddressPFS->getBB(Label.StrVal, Label.Loc);
+ BB = BlockAddressPFS->getBB(Label.StrVal, Label.Loc);
if (!BB)
- return error(Label.Loc, "referenced value is not a basic block");
+ return error(Label.Loc, "referenced value is not a basic block");
} else {
if (Label.Kind == ValID::t_LocalID)
- return error(Label.Loc, "cannot take address of numeric label after "
+ return error(Label.Loc, "cannot take address of numeric label after "
"the function is defined");
BB = dyn_cast_or_null<BasicBlock>(
F->getValueSymbolTable()->lookup(Label.StrVal));
if (!BB)
- return error(Label.Loc, "referenced value is not a basic block");
+ return error(Label.Loc, "referenced value is not a basic block");
}
ID.ConstantVal = BlockAddress::get(F, BB);
@@ -3483,39 +3483,39 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
return false;
}
- case lltok::kw_dso_local_equivalent: {
- // ValID ::= 'dso_local_equivalent' @foo
- Lex.Lex();
-
- ValID Fn;
-
- if (parseValID(Fn))
- return true;
-
- if (Fn.Kind != ValID::t_GlobalID && Fn.Kind != ValID::t_GlobalName)
- return error(Fn.Loc,
- "expected global value name in dso_local_equivalent");
-
- // Try to find the function (but skip it if it's forward-referenced).
- GlobalValue *GV = nullptr;
- if (Fn.Kind == ValID::t_GlobalID) {
- if (Fn.UIntVal < NumberedVals.size())
- GV = NumberedVals[Fn.UIntVal];
- } else if (!ForwardRefVals.count(Fn.StrVal)) {
- GV = M->getNamedValue(Fn.StrVal);
- }
-
- assert(GV && "Could not find a corresponding global variable");
-
- if (!GV->getValueType()->isFunctionTy())
- return error(Fn.Loc, "expected a function, alias to function, or ifunc "
- "in dso_local_equivalent");
-
- ID.ConstantVal = DSOLocalEquivalent::get(GV);
- ID.Kind = ValID::t_Constant;
- return false;
- }
-
+ case lltok::kw_dso_local_equivalent: {
+ // ValID ::= 'dso_local_equivalent' @foo
+ Lex.Lex();
+
+ ValID Fn;
+
+ if (parseValID(Fn))
+ return true;
+
+ if (Fn.Kind != ValID::t_GlobalID && Fn.Kind != ValID::t_GlobalName)
+ return error(Fn.Loc,
+ "expected global value name in dso_local_equivalent");
+
+ // Try to find the function (but skip it if it's forward-referenced).
+ GlobalValue *GV = nullptr;
+ if (Fn.Kind == ValID::t_GlobalID) {
+ if (Fn.UIntVal < NumberedVals.size())
+ GV = NumberedVals[Fn.UIntVal];
+ } else if (!ForwardRefVals.count(Fn.StrVal)) {
+ GV = M->getNamedValue(Fn.StrVal);
+ }
+
+ assert(GV && "Could not find a corresponding global variable");
+
+ if (!GV->getValueType()->isFunctionTy())
+ return error(Fn.Loc, "expected a function, alias to function, or ifunc "
+ "in dso_local_equivalent");
+
+ ID.ConstantVal = DSOLocalEquivalent::get(GV);
+ ID.Kind = ValID::t_Constant;
+ return false;
+ }
+
case lltok::kw_trunc:
case lltok::kw_zext:
case lltok::kw_sext:
@@ -3533,16 +3533,16 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
Type *DestTy = nullptr;
Constant *SrcVal;
Lex.Lex();
- if (parseToken(lltok::lparen, "expected '(' after constantexpr cast") ||
- parseGlobalTypeAndValue(SrcVal) ||
- parseToken(lltok::kw_to, "expected 'to' in constantexpr cast") ||
- parseType(DestTy) ||
- parseToken(lltok::rparen, "expected ')' at end of constantexpr cast"))
+ if (parseToken(lltok::lparen, "expected '(' after constantexpr cast") ||
+ parseGlobalTypeAndValue(SrcVal) ||
+ parseToken(lltok::kw_to, "expected 'to' in constantexpr cast") ||
+ parseType(DestTy) ||
+ parseToken(lltok::rparen, "expected ')' at end of constantexpr cast"))
return true;
if (!CastInst::castIsValid((Instruction::CastOps)Opc, SrcVal, DestTy))
- return error(ID.Loc, "invalid cast opcode for cast from '" +
- getTypeString(SrcVal->getType()) + "' to '" +
- getTypeString(DestTy) + "'");
+ return error(ID.Loc, "invalid cast opcode for cast from '" +
+ getTypeString(SrcVal->getType()) + "' to '" +
+ getTypeString(DestTy) + "'");
ID.ConstantVal = ConstantExpr::getCast((Instruction::CastOps)Opc,
SrcVal, DestTy);
ID.Kind = ValID::t_Constant;
@@ -3552,16 +3552,16 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
Lex.Lex();
Constant *Val;
SmallVector<unsigned, 4> Indices;
- if (parseToken(lltok::lparen,
- "expected '(' in extractvalue constantexpr") ||
- parseGlobalTypeAndValue(Val) || parseIndexList(Indices) ||
- parseToken(lltok::rparen, "expected ')' in extractvalue constantexpr"))
+ if (parseToken(lltok::lparen,
+ "expected '(' in extractvalue constantexpr") ||
+ parseGlobalTypeAndValue(Val) || parseIndexList(Indices) ||
+ parseToken(lltok::rparen, "expected ')' in extractvalue constantexpr"))
return true;
if (!Val->getType()->isAggregateType())
- return error(ID.Loc, "extractvalue operand must be aggregate type");
+ return error(ID.Loc, "extractvalue operand must be aggregate type");
if (!ExtractValueInst::getIndexedType(Val->getType(), Indices))
- return error(ID.Loc, "invalid indices for extractvalue");
+ return error(ID.Loc, "invalid indices for extractvalue");
ID.ConstantVal = ConstantExpr::getExtractValue(Val, Indices);
ID.Kind = ValID::t_Constant;
return false;
@@ -3570,21 +3570,21 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
Lex.Lex();
Constant *Val0, *Val1;
SmallVector<unsigned, 4> Indices;
- if (parseToken(lltok::lparen, "expected '(' in insertvalue constantexpr") ||
- parseGlobalTypeAndValue(Val0) ||
- parseToken(lltok::comma,
- "expected comma in insertvalue constantexpr") ||
- parseGlobalTypeAndValue(Val1) || parseIndexList(Indices) ||
- parseToken(lltok::rparen, "expected ')' in insertvalue constantexpr"))
+ if (parseToken(lltok::lparen, "expected '(' in insertvalue constantexpr") ||
+ parseGlobalTypeAndValue(Val0) ||
+ parseToken(lltok::comma,
+ "expected comma in insertvalue constantexpr") ||
+ parseGlobalTypeAndValue(Val1) || parseIndexList(Indices) ||
+ parseToken(lltok::rparen, "expected ')' in insertvalue constantexpr"))
return true;
if (!Val0->getType()->isAggregateType())
- return error(ID.Loc, "insertvalue operand must be aggregate type");
+ return error(ID.Loc, "insertvalue operand must be aggregate type");
Type *IndexedType =
ExtractValueInst::getIndexedType(Val0->getType(), Indices);
if (!IndexedType)
- return error(ID.Loc, "invalid indices for insertvalue");
+ return error(ID.Loc, "invalid indices for insertvalue");
if (IndexedType != Val1->getType())
- return error(ID.Loc, "insertvalue operand and field disagree in type: '" +
+ return error(ID.Loc, "insertvalue operand and field disagree in type: '" +
getTypeString(Val1->getType()) +
"' instead of '" + getTypeString(IndexedType) +
"'");
@@ -3597,28 +3597,28 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
unsigned PredVal, Opc = Lex.getUIntVal();
Constant *Val0, *Val1;
Lex.Lex();
- if (parseCmpPredicate(PredVal, Opc) ||
- parseToken(lltok::lparen, "expected '(' in compare constantexpr") ||
- parseGlobalTypeAndValue(Val0) ||
- parseToken(lltok::comma, "expected comma in compare constantexpr") ||
- parseGlobalTypeAndValue(Val1) ||
- parseToken(lltok::rparen, "expected ')' in compare constantexpr"))
+ if (parseCmpPredicate(PredVal, Opc) ||
+ parseToken(lltok::lparen, "expected '(' in compare constantexpr") ||
+ parseGlobalTypeAndValue(Val0) ||
+ parseToken(lltok::comma, "expected comma in compare constantexpr") ||
+ parseGlobalTypeAndValue(Val1) ||
+ parseToken(lltok::rparen, "expected ')' in compare constantexpr"))
return true;
if (Val0->getType() != Val1->getType())
- return error(ID.Loc, "compare operands must have the same type");
+ return error(ID.Loc, "compare operands must have the same type");
CmpInst::Predicate Pred = (CmpInst::Predicate)PredVal;
if (Opc == Instruction::FCmp) {
if (!Val0->getType()->isFPOrFPVectorTy())
- return error(ID.Loc, "fcmp requires floating point operands");
+ return error(ID.Loc, "fcmp requires floating point operands");
ID.ConstantVal = ConstantExpr::getFCmp(Pred, Val0, Val1);
} else {
assert(Opc == Instruction::ICmp && "Unexpected opcode for CmpInst!");
if (!Val0->getType()->isIntOrIntVectorTy() &&
!Val0->getType()->isPtrOrPtrVectorTy())
- return error(ID.Loc, "icmp requires pointer or integer operands");
+ return error(ID.Loc, "icmp requires pointer or integer operands");
ID.ConstantVal = ConstantExpr::getICmp(Pred, Val0, Val1);
}
ID.Kind = ValID::t_Constant;
@@ -3630,16 +3630,16 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
unsigned Opc = Lex.getUIntVal();
Constant *Val;
Lex.Lex();
- if (parseToken(lltok::lparen, "expected '(' in unary constantexpr") ||
- parseGlobalTypeAndValue(Val) ||
- parseToken(lltok::rparen, "expected ')' in unary constantexpr"))
+ if (parseToken(lltok::lparen, "expected '(' in unary constantexpr") ||
+ parseGlobalTypeAndValue(Val) ||
+ parseToken(lltok::rparen, "expected ')' in unary constantexpr"))
return true;
// Check that the type is valid for the operator.
switch (Opc) {
case Instruction::FNeg:
if (!Val->getType()->isFPOrFPVectorTy())
- return error(ID.Loc, "constexpr requires fp operands");
+ return error(ID.Loc, "constexpr requires fp operands");
break;
default: llvm_unreachable("Unknown unary operator!");
}
@@ -3685,14 +3685,14 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
if (EatIfPresent(lltok::kw_exact))
Exact = true;
}
- if (parseToken(lltok::lparen, "expected '(' in binary constantexpr") ||
- parseGlobalTypeAndValue(Val0) ||
- parseToken(lltok::comma, "expected comma in binary constantexpr") ||
- parseGlobalTypeAndValue(Val1) ||
- parseToken(lltok::rparen, "expected ')' in binary constantexpr"))
+ if (parseToken(lltok::lparen, "expected '(' in binary constantexpr") ||
+ parseGlobalTypeAndValue(Val0) ||
+ parseToken(lltok::comma, "expected comma in binary constantexpr") ||
+ parseGlobalTypeAndValue(Val1) ||
+ parseToken(lltok::rparen, "expected ')' in binary constantexpr"))
return true;
if (Val0->getType() != Val1->getType())
- return error(ID.Loc, "operands of constexpr must have same type");
+ return error(ID.Loc, "operands of constexpr must have same type");
// Check that the type is valid for the operator.
switch (Opc) {
case Instruction::Add:
@@ -3706,7 +3706,7 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
case Instruction::AShr:
case Instruction::LShr:
if (!Val0->getType()->isIntOrIntVectorTy())
- return error(ID.Loc, "constexpr requires integer operands");
+ return error(ID.Loc, "constexpr requires integer operands");
break;
case Instruction::FAdd:
case Instruction::FSub:
@@ -3714,7 +3714,7 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
case Instruction::FDiv:
case Instruction::FRem:
if (!Val0->getType()->isFPOrFPVectorTy())
- return error(ID.Loc, "constexpr requires fp operands");
+ return error(ID.Loc, "constexpr requires fp operands");
break;
default: llvm_unreachable("Unknown binary operator!");
}
@@ -3735,16 +3735,16 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
unsigned Opc = Lex.getUIntVal();
Constant *Val0, *Val1;
Lex.Lex();
- if (parseToken(lltok::lparen, "expected '(' in logical constantexpr") ||
- parseGlobalTypeAndValue(Val0) ||
- parseToken(lltok::comma, "expected comma in logical constantexpr") ||
- parseGlobalTypeAndValue(Val1) ||
- parseToken(lltok::rparen, "expected ')' in logical constantexpr"))
+ if (parseToken(lltok::lparen, "expected '(' in logical constantexpr") ||
+ parseGlobalTypeAndValue(Val0) ||
+ parseToken(lltok::comma, "expected comma in logical constantexpr") ||
+ parseGlobalTypeAndValue(Val1) ||
+ parseToken(lltok::rparen, "expected ')' in logical constantexpr"))
return true;
if (Val0->getType() != Val1->getType())
- return error(ID.Loc, "operands of constexpr must have same type");
+ return error(ID.Loc, "operands of constexpr must have same type");
if (!Val0->getType()->isIntOrIntVectorTy())
- return error(ID.Loc,
+ return error(ID.Loc,
"constexpr requires integer or integer vector operands");
ID.ConstantVal = ConstantExpr::get(Opc, Val0, Val1);
ID.Kind = ValID::t_Constant;
@@ -3765,31 +3765,31 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
if (Opc == Instruction::GetElementPtr)
InBounds = EatIfPresent(lltok::kw_inbounds);
- if (parseToken(lltok::lparen, "expected '(' in constantexpr"))
+ if (parseToken(lltok::lparen, "expected '(' in constantexpr"))
return true;
LocTy ExplicitTypeLoc = Lex.getLoc();
if (Opc == Instruction::GetElementPtr) {
- if (parseType(Ty) ||
- parseToken(lltok::comma, "expected comma after getelementptr's type"))
+ if (parseType(Ty) ||
+ parseToken(lltok::comma, "expected comma after getelementptr's type"))
return true;
}
Optional<unsigned> InRangeOp;
- if (parseGlobalValueVector(
+ if (parseGlobalValueVector(
Elts, Opc == Instruction::GetElementPtr ? &InRangeOp : nullptr) ||
- parseToken(lltok::rparen, "expected ')' in constantexpr"))
+ parseToken(lltok::rparen, "expected ')' in constantexpr"))
return true;
if (Opc == Instruction::GetElementPtr) {
if (Elts.size() == 0 ||
!Elts[0]->getType()->isPtrOrPtrVectorTy())
- return error(ID.Loc, "base of getelementptr must be a pointer");
+ return error(ID.Loc, "base of getelementptr must be a pointer");
Type *BaseType = Elts[0]->getType();
auto *BasePointerType = cast<PointerType>(BaseType->getScalarType());
if (Ty != BasePointerType->getElementType())
- return error(
+ return error(
ExplicitTypeLoc,
"explicit pointee type doesn't match operand's pointee type");
@@ -3802,11 +3802,11 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
for (Constant *Val : Indices) {
Type *ValTy = Val->getType();
if (!ValTy->isIntOrIntVectorTy())
- return error(ID.Loc, "getelementptr index must be an integer");
+ return error(ID.Loc, "getelementptr index must be an integer");
if (auto *ValVTy = dyn_cast<VectorType>(ValTy)) {
unsigned ValNumEl = cast<FixedVectorType>(ValVTy)->getNumElements();
if (GEPWidth && (ValNumEl != GEPWidth))
- return error(
+ return error(
ID.Loc,
"getelementptr vector index has a wrong number of elements");
// GEPWidth may have been unknown because the base is a scalar,
@@ -3817,14 +3817,14 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
SmallPtrSet<Type*, 4> Visited;
if (!Indices.empty() && !Ty->isSized(&Visited))
- return error(ID.Loc, "base element of getelementptr must be sized");
+ return error(ID.Loc, "base element of getelementptr must be sized");
if (!GetElementPtrInst::getIndexedType(Ty, Indices))
- return error(ID.Loc, "invalid getelementptr indices");
+ return error(ID.Loc, "invalid getelementptr indices");
if (InRangeOp) {
if (*InRangeOp == 0)
- return error(ID.Loc,
+ return error(ID.Loc,
"inrange keyword may not appear on pointer operand");
--*InRangeOp;
}
@@ -3833,31 +3833,31 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
InBounds, InRangeOp);
} else if (Opc == Instruction::Select) {
if (Elts.size() != 3)
- return error(ID.Loc, "expected three operands to select");
+ return error(ID.Loc, "expected three operands to select");
if (const char *Reason = SelectInst::areInvalidOperands(Elts[0], Elts[1],
Elts[2]))
- return error(ID.Loc, Reason);
+ return error(ID.Loc, Reason);
ID.ConstantVal = ConstantExpr::getSelect(Elts[0], Elts[1], Elts[2]);
} else if (Opc == Instruction::ShuffleVector) {
if (Elts.size() != 3)
- return error(ID.Loc, "expected three operands to shufflevector");
+ return error(ID.Loc, "expected three operands to shufflevector");
if (!ShuffleVectorInst::isValidOperands(Elts[0], Elts[1], Elts[2]))
- return error(ID.Loc, "invalid operands to shufflevector");
+ return error(ID.Loc, "invalid operands to shufflevector");
SmallVector<int, 16> Mask;
ShuffleVectorInst::getShuffleMask(cast<Constant>(Elts[2]), Mask);
ID.ConstantVal = ConstantExpr::getShuffleVector(Elts[0], Elts[1], Mask);
} else if (Opc == Instruction::ExtractElement) {
if (Elts.size() != 2)
- return error(ID.Loc, "expected two operands to extractelement");
+ return error(ID.Loc, "expected two operands to extractelement");
if (!ExtractElementInst::isValidOperands(Elts[0], Elts[1]))
- return error(ID.Loc, "invalid extractelement operands");
+ return error(ID.Loc, "invalid extractelement operands");
ID.ConstantVal = ConstantExpr::getExtractElement(Elts[0], Elts[1]);
} else {
assert(Opc == Instruction::InsertElement && "Unknown opcode");
if (Elts.size() != 3)
- return error(ID.Loc, "expected three operands to insertelement");
+ return error(ID.Loc, "expected three operands to insertelement");
if (!InsertElementInst::isValidOperands(Elts[0], Elts[1], Elts[2]))
- return error(ID.Loc, "invalid insertelement operands");
+ return error(ID.Loc, "invalid insertelement operands");
ID.ConstantVal =
ConstantExpr::getInsertElement(Elts[0], Elts[1],Elts[2]);
}
@@ -3871,21 +3871,21 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
return false;
}
-/// parseGlobalValue - parse a global value with the specified type.
-bool LLParser::parseGlobalValue(Type *Ty, Constant *&C) {
+/// parseGlobalValue - parse a global value with the specified type.
+bool LLParser::parseGlobalValue(Type *Ty, Constant *&C) {
C = nullptr;
ValID ID;
Value *V = nullptr;
- bool Parsed = parseValID(ID) ||
- convertValIDToValue(Ty, ID, V, nullptr, /*IsCall=*/false);
+ bool Parsed = parseValID(ID) ||
+ convertValIDToValue(Ty, ID, V, nullptr, /*IsCall=*/false);
if (V && !(C = dyn_cast<Constant>(V)))
- return error(ID.Loc, "global values must be constants");
+ return error(ID.Loc, "global values must be constants");
return Parsed;
}
-bool LLParser::parseGlobalTypeAndValue(Constant *&V) {
+bool LLParser::parseGlobalTypeAndValue(Constant *&V) {
Type *Ty = nullptr;
- return parseType(Ty) || parseGlobalValue(Ty, V);
+ return parseType(Ty) || parseGlobalValue(Ty, V);
}
bool LLParser::parseOptionalComdat(StringRef GlobalName, Comdat *&C) {
@@ -3897,24 +3897,24 @@ bool LLParser::parseOptionalComdat(StringRef GlobalName, Comdat *&C) {
if (EatIfPresent(lltok::lparen)) {
if (Lex.getKind() != lltok::ComdatVar)
- return tokError("expected comdat variable");
+ return tokError("expected comdat variable");
C = getComdat(Lex.getStrVal(), Lex.getLoc());
Lex.Lex();
- if (parseToken(lltok::rparen, "expected ')' after comdat var"))
+ if (parseToken(lltok::rparen, "expected ')' after comdat var"))
return true;
} else {
if (GlobalName.empty())
- return tokError("comdat cannot be unnamed");
+ return tokError("comdat cannot be unnamed");
C = getComdat(std::string(GlobalName), KwLoc);
}
return false;
}
-/// parseGlobalValueVector
+/// parseGlobalValueVector
/// ::= /*empty*/
/// ::= [inrange] TypeAndValue (',' [inrange] TypeAndValue)*
-bool LLParser::parseGlobalValueVector(SmallVectorImpl<Constant *> &Elts,
+bool LLParser::parseGlobalValueVector(SmallVectorImpl<Constant *> &Elts,
Optional<unsigned> *InRangeOp) {
// Empty list.
if (Lex.getKind() == lltok::rbrace ||
@@ -3928,17 +3928,17 @@ bool LLParser::parseGlobalValueVector(SmallVectorImpl<Constant *> &Elts,
*InRangeOp = Elts.size();
Constant *C;
- if (parseGlobalTypeAndValue(C))
- return true;
+ if (parseGlobalTypeAndValue(C))
+ return true;
Elts.push_back(C);
} while (EatIfPresent(lltok::comma));
return false;
}
-bool LLParser::parseMDTuple(MDNode *&MD, bool IsDistinct) {
+bool LLParser::parseMDTuple(MDNode *&MD, bool IsDistinct) {
SmallVector<Metadata *, 16> Elts;
- if (parseMDNodeVector(Elts))
+ if (parseMDNodeVector(Elts))
return true;
MD = (IsDistinct ? MDTuple::getDistinct : MDTuple::get)(Context, Elts);
@@ -3949,20 +3949,20 @@ bool LLParser::parseMDTuple(MDNode *&MD, bool IsDistinct) {
/// ::= !{ ... }
/// ::= !7
/// ::= !DILocation(...)
-bool LLParser::parseMDNode(MDNode *&N) {
+bool LLParser::parseMDNode(MDNode *&N) {
if (Lex.getKind() == lltok::MetadataVar)
- return parseSpecializedMDNode(N);
+ return parseSpecializedMDNode(N);
- return parseToken(lltok::exclaim, "expected '!' here") || parseMDNodeTail(N);
+ return parseToken(lltok::exclaim, "expected '!' here") || parseMDNodeTail(N);
}
-bool LLParser::parseMDNodeTail(MDNode *&N) {
+bool LLParser::parseMDNodeTail(MDNode *&N) {
// !{ ... }
if (Lex.getKind() == lltok::lbrace)
- return parseMDTuple(N);
+ return parseMDTuple(N);
// !42
- return parseMDNodeID(N);
+ return parseMDNodeID(N);
}
namespace {
@@ -4160,9 +4160,9 @@ struct MDSignedOrUnsignedField
namespace llvm {
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDAPSIntField &Result) {
+bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDAPSIntField &Result) {
if (Lex.getKind() != lltok::APSInt)
- return tokError("expected integer");
+ return tokError("expected integer");
Result.assign(Lex.getAPSIntVal());
Lex.Lex();
@@ -4170,14 +4170,14 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDAPSIntField &Result) {
}
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name,
+bool LLParser::parseMDField(LocTy Loc, StringRef Name,
MDUnsignedField &Result) {
if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
- return tokError("expected unsigned integer");
+ return tokError("expected unsigned integer");
auto &U = Lex.getAPSIntVal();
if (U.ugt(Result.Max))
- return tokError("value for '" + Name + "' too large, limit is " +
+ return tokError("value for '" + Name + "' too large, limit is " +
Twine(Result.Max));
Result.assign(U.getZExtValue());
assert(Result.Val <= Result.Max && "Expected value in range");
@@ -4186,25 +4186,25 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name,
}
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name, LineField &Result) {
- return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
+bool LLParser::parseMDField(LocTy Loc, StringRef Name, LineField &Result) {
+ return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
}
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name, ColumnField &Result) {
- return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
+bool LLParser::parseMDField(LocTy Loc, StringRef Name, ColumnField &Result) {
+ return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
}
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfTagField &Result) {
+bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfTagField &Result) {
if (Lex.getKind() == lltok::APSInt)
- return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
+ return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
if (Lex.getKind() != lltok::DwarfTag)
- return tokError("expected DWARF tag");
+ return tokError("expected DWARF tag");
unsigned Tag = dwarf::getTag(Lex.getStrVal());
if (Tag == dwarf::DW_TAG_invalid)
- return tokError("invalid DWARF tag" + Twine(" '") + Lex.getStrVal() + "'");
+ return tokError("invalid DWARF tag" + Twine(" '") + Lex.getStrVal() + "'");
assert(Tag <= Result.Max && "Expected valid DWARF tag");
Result.assign(Tag);
@@ -4213,18 +4213,18 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfTagField &Result) {
}
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name,
+bool LLParser::parseMDField(LocTy Loc, StringRef Name,
DwarfMacinfoTypeField &Result) {
if (Lex.getKind() == lltok::APSInt)
- return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
+ return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
if (Lex.getKind() != lltok::DwarfMacinfo)
- return tokError("expected DWARF macinfo type");
+ return tokError("expected DWARF macinfo type");
unsigned Macinfo = dwarf::getMacinfo(Lex.getStrVal());
if (Macinfo == dwarf::DW_MACINFO_invalid)
- return tokError("invalid DWARF macinfo type" + Twine(" '") +
- Lex.getStrVal() + "'");
+ return tokError("invalid DWARF macinfo type" + Twine(" '") +
+ Lex.getStrVal() + "'");
assert(Macinfo <= Result.Max && "Expected valid DWARF macinfo type");
Result.assign(Macinfo);
@@ -4233,17 +4233,17 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name,
}
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name,
+bool LLParser::parseMDField(LocTy Loc, StringRef Name,
DwarfVirtualityField &Result) {
if (Lex.getKind() == lltok::APSInt)
- return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
+ return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
if (Lex.getKind() != lltok::DwarfVirtuality)
- return tokError("expected DWARF virtuality code");
+ return tokError("expected DWARF virtuality code");
unsigned Virtuality = dwarf::getVirtuality(Lex.getStrVal());
if (Virtuality == dwarf::DW_VIRTUALITY_invalid)
- return tokError("invalid DWARF virtuality code" + Twine(" '") +
+ return tokError("invalid DWARF virtuality code" + Twine(" '") +
Lex.getStrVal() + "'");
assert(Virtuality <= Result.Max && "Expected valid DWARF virtuality code");
Result.assign(Virtuality);
@@ -4252,16 +4252,16 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name,
}
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfLangField &Result) {
+bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfLangField &Result) {
if (Lex.getKind() == lltok::APSInt)
- return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
+ return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
if (Lex.getKind() != lltok::DwarfLang)
- return tokError("expected DWARF language");
+ return tokError("expected DWARF language");
unsigned Lang = dwarf::getLanguage(Lex.getStrVal());
if (!Lang)
- return tokError("invalid DWARF language" + Twine(" '") + Lex.getStrVal() +
+ return tokError("invalid DWARF language" + Twine(" '") + Lex.getStrVal() +
"'");
assert(Lang <= Result.Max && "Expected valid DWARF language");
Result.assign(Lang);
@@ -4270,17 +4270,17 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfLangField &Result) {
}
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfCCField &Result) {
+bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfCCField &Result) {
if (Lex.getKind() == lltok::APSInt)
- return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
+ return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
if (Lex.getKind() != lltok::DwarfCC)
- return tokError("expected DWARF calling convention");
+ return tokError("expected DWARF calling convention");
unsigned CC = dwarf::getCallingConvention(Lex.getStrVal());
if (!CC)
- return tokError("invalid DWARF calling convention" + Twine(" '") +
- Lex.getStrVal() + "'");
+ return tokError("invalid DWARF calling convention" + Twine(" '") +
+ Lex.getStrVal() + "'");
assert(CC <= Result.Max && "Expected valid DWARF calling convention");
Result.assign(CC);
Lex.Lex();
@@ -4288,17 +4288,17 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfCCField &Result) {
}
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name,
- EmissionKindField &Result) {
+bool LLParser::parseMDField(LocTy Loc, StringRef Name,
+ EmissionKindField &Result) {
if (Lex.getKind() == lltok::APSInt)
- return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
+ return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
if (Lex.getKind() != lltok::EmissionKind)
- return tokError("expected emission kind");
+ return tokError("expected emission kind");
auto Kind = DICompileUnit::getEmissionKind(Lex.getStrVal());
if (!Kind)
- return tokError("invalid emission kind" + Twine(" '") + Lex.getStrVal() +
+ return tokError("invalid emission kind" + Twine(" '") + Lex.getStrVal() +
"'");
assert(*Kind <= Result.Max && "Expected valid emission kind");
Result.assign(*Kind);
@@ -4307,17 +4307,17 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name,
}
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name,
+bool LLParser::parseMDField(LocTy Loc, StringRef Name,
NameTableKindField &Result) {
if (Lex.getKind() == lltok::APSInt)
- return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
+ return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
if (Lex.getKind() != lltok::NameTableKind)
- return tokError("expected nameTable kind");
+ return tokError("expected nameTable kind");
auto Kind = DICompileUnit::getNameTableKind(Lex.getStrVal());
if (!Kind)
- return tokError("invalid nameTable kind" + Twine(" '") + Lex.getStrVal() +
+ return tokError("invalid nameTable kind" + Twine(" '") + Lex.getStrVal() +
"'");
assert(((unsigned)*Kind) <= Result.Max && "Expected valid nameTable kind");
Result.assign((unsigned)*Kind);
@@ -4326,17 +4326,17 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name,
}
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name,
+bool LLParser::parseMDField(LocTy Loc, StringRef Name,
DwarfAttEncodingField &Result) {
if (Lex.getKind() == lltok::APSInt)
- return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
+ return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
if (Lex.getKind() != lltok::DwarfAttEncoding)
- return tokError("expected DWARF type attribute encoding");
+ return tokError("expected DWARF type attribute encoding");
unsigned Encoding = dwarf::getAttributeEncoding(Lex.getStrVal());
if (!Encoding)
- return tokError("invalid DWARF type attribute encoding" + Twine(" '") +
+ return tokError("invalid DWARF type attribute encoding" + Twine(" '") +
Lex.getStrVal() + "'");
assert(Encoding <= Result.Max && "Expected valid DWARF language");
Result.assign(Encoding);
@@ -4349,29 +4349,29 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name,
/// ::= DIFlagVector
/// ::= DIFlagVector '|' DIFlagFwdDecl '|' uint32 '|' DIFlagPublic
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name, DIFlagField &Result) {
+bool LLParser::parseMDField(LocTy Loc, StringRef Name, DIFlagField &Result) {
- // parser for a single flag.
+ // parser for a single flag.
auto parseFlag = [&](DINode::DIFlags &Val) {
if (Lex.getKind() == lltok::APSInt && !Lex.getAPSIntVal().isSigned()) {
uint32_t TempVal = static_cast<uint32_t>(Val);
- bool Res = parseUInt32(TempVal);
+ bool Res = parseUInt32(TempVal);
Val = static_cast<DINode::DIFlags>(TempVal);
return Res;
}
if (Lex.getKind() != lltok::DIFlag)
- return tokError("expected debug info flag");
+ return tokError("expected debug info flag");
Val = DINode::getFlag(Lex.getStrVal());
if (!Val)
- return tokError(Twine("invalid debug info flag flag '") +
+ return tokError(Twine("invalid debug info flag flag '") +
Lex.getStrVal() + "'");
Lex.Lex();
return false;
};
- // parse the flags and combine them together.
+ // parse the flags and combine them together.
DINode::DIFlags Combined = DINode::FlagZero;
do {
DINode::DIFlags Val;
@@ -4389,29 +4389,29 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name, DIFlagField &Result) {
/// ::= DISPFlagVector
/// ::= DISPFlagVector '|' DISPFlag* '|' uint32
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name, DISPFlagField &Result) {
+bool LLParser::parseMDField(LocTy Loc, StringRef Name, DISPFlagField &Result) {
- // parser for a single flag.
+ // parser for a single flag.
auto parseFlag = [&](DISubprogram::DISPFlags &Val) {
if (Lex.getKind() == lltok::APSInt && !Lex.getAPSIntVal().isSigned()) {
uint32_t TempVal = static_cast<uint32_t>(Val);
- bool Res = parseUInt32(TempVal);
+ bool Res = parseUInt32(TempVal);
Val = static_cast<DISubprogram::DISPFlags>(TempVal);
return Res;
}
if (Lex.getKind() != lltok::DISPFlag)
- return tokError("expected debug info flag");
+ return tokError("expected debug info flag");
Val = DISubprogram::getFlag(Lex.getStrVal());
if (!Val)
- return tokError(Twine("invalid subprogram debug info flag '") +
+ return tokError(Twine("invalid subprogram debug info flag '") +
Lex.getStrVal() + "'");
Lex.Lex();
return false;
};
- // parse the flags and combine them together.
+ // parse the flags and combine them together.
DISubprogram::DISPFlags Combined = DISubprogram::SPFlagZero;
do {
DISubprogram::DISPFlags Val;
@@ -4425,16 +4425,16 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name, DISPFlagField &Result) {
}
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDSignedField &Result) {
+bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDSignedField &Result) {
if (Lex.getKind() != lltok::APSInt)
- return tokError("expected signed integer");
+ return tokError("expected signed integer");
auto &S = Lex.getAPSIntVal();
if (S < Result.Min)
- return tokError("value for '" + Name + "' too small, limit is " +
+ return tokError("value for '" + Name + "' too small, limit is " +
Twine(Result.Min));
if (S > Result.Max)
- return tokError("value for '" + Name + "' too large, limit is " +
+ return tokError("value for '" + Name + "' too large, limit is " +
Twine(Result.Max));
Result.assign(S.getExtValue());
assert(Result.Val >= Result.Min && "Expected value in range");
@@ -4444,10 +4444,10 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDSignedField &Result) {
}
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDBoolField &Result) {
+bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDBoolField &Result) {
switch (Lex.getKind()) {
default:
- return tokError("expected 'true' or 'false'");
+ return tokError("expected 'true' or 'false'");
case lltok::kw_true:
Result.assign(true);
break;
@@ -4460,17 +4460,17 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDBoolField &Result) {
}
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDField &Result) {
+bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDField &Result) {
if (Lex.getKind() == lltok::kw_null) {
if (!Result.AllowNull)
- return tokError("'" + Name + "' cannot be null");
+ return tokError("'" + Name + "' cannot be null");
Lex.Lex();
Result.assign(nullptr);
return false;
}
Metadata *MD;
- if (parseMetadata(MD, nullptr))
+ if (parseMetadata(MD, nullptr))
return true;
Result.assign(MD);
@@ -4478,12 +4478,12 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDField &Result) {
}
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name,
+bool LLParser::parseMDField(LocTy Loc, StringRef Name,
MDSignedOrMDField &Result) {
// Try to parse a signed int.
if (Lex.getKind() == lltok::APSInt) {
MDSignedField Res = Result.A;
- if (!parseMDField(Loc, Name, Res)) {
+ if (!parseMDField(Loc, Name, Res)) {
Result.assign(Res);
return false;
}
@@ -4492,7 +4492,7 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name,
// Otherwise, try to parse as an MDField.
MDField Res = Result.B;
- if (!parseMDField(Loc, Name, Res)) {
+ if (!parseMDField(Loc, Name, Res)) {
Result.assign(Res);
return false;
}
@@ -4501,23 +4501,23 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name,
}
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDStringField &Result) {
+bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDStringField &Result) {
LocTy ValueLoc = Lex.getLoc();
std::string S;
- if (parseStringConstant(S))
+ if (parseStringConstant(S))
return true;
if (!Result.AllowEmpty && S.empty())
- return error(ValueLoc, "'" + Name + "' cannot be empty");
+ return error(ValueLoc, "'" + Name + "' cannot be empty");
Result.assign(S.empty() ? nullptr : MDString::get(Context, S));
return false;
}
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDFieldList &Result) {
+bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDFieldList &Result) {
SmallVector<Metadata *, 4> MDs;
- if (parseMDNodeVector(MDs))
+ if (parseMDNodeVector(MDs))
return true;
Result.assign(std::move(MDs));
@@ -4525,14 +4525,14 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDFieldList &Result) {
}
template <>
-bool LLParser::parseMDField(LocTy Loc, StringRef Name,
+bool LLParser::parseMDField(LocTy Loc, StringRef Name,
ChecksumKindField &Result) {
Optional<DIFile::ChecksumKind> CSKind =
DIFile::getChecksumKind(Lex.getStrVal());
if (Lex.getKind() != lltok::ChecksumKind || !CSKind)
- return tokError("invalid checksum kind" + Twine(" '") + Lex.getStrVal() +
- "'");
+ return tokError("invalid checksum kind" + Twine(" '") + Lex.getStrVal() +
+ "'");
Result.assign(*CSKind);
Lex.Lex();
@@ -4542,12 +4542,12 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name,
} // end namespace llvm
template <class ParserTy>
-bool LLParser::parseMDFieldsImplBody(ParserTy ParseField) {
+bool LLParser::parseMDFieldsImplBody(ParserTy ParseField) {
do {
if (Lex.getKind() != lltok::LabelStr)
- return tokError("expected field label here");
+ return tokError("expected field label here");
- if (ParseField())
+ if (ParseField())
return true;
} while (EatIfPresent(lltok::comma));
@@ -4555,70 +4555,70 @@ bool LLParser::parseMDFieldsImplBody(ParserTy ParseField) {
}
template <class ParserTy>
-bool LLParser::parseMDFieldsImpl(ParserTy ParseField, LocTy &ClosingLoc) {
+bool LLParser::parseMDFieldsImpl(ParserTy ParseField, LocTy &ClosingLoc) {
assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
Lex.Lex();
- if (parseToken(lltok::lparen, "expected '(' here"))
+ if (parseToken(lltok::lparen, "expected '(' here"))
return true;
if (Lex.getKind() != lltok::rparen)
- if (parseMDFieldsImplBody(ParseField))
+ if (parseMDFieldsImplBody(ParseField))
return true;
ClosingLoc = Lex.getLoc();
- return parseToken(lltok::rparen, "expected ')' here");
+ return parseToken(lltok::rparen, "expected ')' here");
}
template <class FieldTy>
-bool LLParser::parseMDField(StringRef Name, FieldTy &Result) {
+bool LLParser::parseMDField(StringRef Name, FieldTy &Result) {
if (Result.Seen)
- return tokError("field '" + Name + "' cannot be specified more than once");
+ return tokError("field '" + Name + "' cannot be specified more than once");
LocTy Loc = Lex.getLoc();
Lex.Lex();
- return parseMDField(Loc, Name, Result);
+ return parseMDField(Loc, Name, Result);
}
-bool LLParser::parseSpecializedMDNode(MDNode *&N, bool IsDistinct) {
+bool LLParser::parseSpecializedMDNode(MDNode *&N, bool IsDistinct) {
assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) \
if (Lex.getStrVal() == #CLASS) \
- return parse##CLASS(N, IsDistinct);
+ return parse##CLASS(N, IsDistinct);
#include "llvm/IR/Metadata.def"
- return tokError("expected metadata type");
+ return tokError("expected metadata type");
}
#define DECLARE_FIELD(NAME, TYPE, INIT) TYPE NAME INIT
#define NOP_FIELD(NAME, TYPE, INIT)
#define REQUIRE_FIELD(NAME, TYPE, INIT) \
if (!NAME.Seen) \
- return error(ClosingLoc, "missing required field '" #NAME "'");
+ return error(ClosingLoc, "missing required field '" #NAME "'");
#define PARSE_MD_FIELD(NAME, TYPE, DEFAULT) \
if (Lex.getStrVal() == #NAME) \
- return parseMDField(#NAME, NAME);
+ return parseMDField(#NAME, NAME);
#define PARSE_MD_FIELDS() \
VISIT_MD_FIELDS(DECLARE_FIELD, DECLARE_FIELD) \
do { \
LocTy ClosingLoc; \
- if (parseMDFieldsImpl( \
- [&]() -> bool { \
- VISIT_MD_FIELDS(PARSE_MD_FIELD, PARSE_MD_FIELD) \
- return tokError(Twine("invalid field '") + Lex.getStrVal() + \
- "'"); \
- }, \
- ClosingLoc)) \
+ if (parseMDFieldsImpl( \
+ [&]() -> bool { \
+ VISIT_MD_FIELDS(PARSE_MD_FIELD, PARSE_MD_FIELD) \
+ return tokError(Twine("invalid field '") + Lex.getStrVal() + \
+ "'"); \
+ }, \
+ ClosingLoc)) \
return true; \
VISIT_MD_FIELDS(NOP_FIELD, REQUIRE_FIELD) \
} while (false)
#define GET_OR_DISTINCT(CLASS, ARGS) \
(IsDistinct ? CLASS::getDistinct ARGS : CLASS::get ARGS)
-/// parseDILocationFields:
+/// parseDILocationFields:
/// ::= !DILocation(line: 43, column: 8, scope: !5, inlinedAt: !6,
/// isImplicitCode: true)
-bool LLParser::parseDILocation(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDILocation(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
OPTIONAL(line, LineField, ); \
OPTIONAL(column, ColumnField, ); \
@@ -4634,9 +4634,9 @@ bool LLParser::parseDILocation(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseGenericDINode:
+/// parseGenericDINode:
/// ::= !GenericDINode(tag: 15, header: "...", operands: {...})
-bool LLParser::parseGenericDINode(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseGenericDINode(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(tag, DwarfTagField, ); \
OPTIONAL(header, MDStringField, ); \
@@ -4649,11 +4649,11 @@ bool LLParser::parseGenericDINode(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDISubrange:
+/// parseDISubrange:
/// ::= !DISubrange(count: 30, lowerBound: 2)
/// ::= !DISubrange(count: !node, lowerBound: 2)
/// ::= !DISubrange(lowerBound: !node1, upperBound: !node2, stride: !node3)
-bool LLParser::parseDISubrange(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDISubrange(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
OPTIONAL(count, MDSignedOrMDField, (-1, -1, INT64_MAX, false)); \
OPTIONAL(lowerBound, MDSignedOrMDField, ); \
@@ -4691,42 +4691,42 @@ bool LLParser::parseDISubrange(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDIGenericSubrange:
-/// ::= !DIGenericSubrange(lowerBound: !node1, upperBound: !node2, stride:
-/// !node3)
-bool LLParser::parseDIGenericSubrange(MDNode *&Result, bool IsDistinct) {
-#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
- OPTIONAL(count, MDSignedOrMDField, ); \
- OPTIONAL(lowerBound, MDSignedOrMDField, ); \
- OPTIONAL(upperBound, MDSignedOrMDField, ); \
- OPTIONAL(stride, MDSignedOrMDField, );
- PARSE_MD_FIELDS();
-#undef VISIT_MD_FIELDS
-
- auto ConvToMetadata = [&](MDSignedOrMDField Bound) -> Metadata * {
- if (Bound.isMDSignedField())
- return DIExpression::get(
- Context, {dwarf::DW_OP_consts,
- static_cast<uint64_t>(Bound.getMDSignedValue())});
- if (Bound.isMDField())
- return Bound.getMDFieldValue();
- return nullptr;
- };
-
- Metadata *Count = ConvToMetadata(count);
- Metadata *LowerBound = ConvToMetadata(lowerBound);
- Metadata *UpperBound = ConvToMetadata(upperBound);
- Metadata *Stride = ConvToMetadata(stride);
-
- Result = GET_OR_DISTINCT(DIGenericSubrange,
- (Context, Count, LowerBound, UpperBound, Stride));
-
- return false;
-}
-
-/// parseDIEnumerator:
+/// parseDIGenericSubrange:
+/// ::= !DIGenericSubrange(lowerBound: !node1, upperBound: !node2, stride:
+/// !node3)
+bool LLParser::parseDIGenericSubrange(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ OPTIONAL(count, MDSignedOrMDField, ); \
+ OPTIONAL(lowerBound, MDSignedOrMDField, ); \
+ OPTIONAL(upperBound, MDSignedOrMDField, ); \
+ OPTIONAL(stride, MDSignedOrMDField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ auto ConvToMetadata = [&](MDSignedOrMDField Bound) -> Metadata * {
+ if (Bound.isMDSignedField())
+ return DIExpression::get(
+ Context, {dwarf::DW_OP_consts,
+ static_cast<uint64_t>(Bound.getMDSignedValue())});
+ if (Bound.isMDField())
+ return Bound.getMDFieldValue();
+ return nullptr;
+ };
+
+ Metadata *Count = ConvToMetadata(count);
+ Metadata *LowerBound = ConvToMetadata(lowerBound);
+ Metadata *UpperBound = ConvToMetadata(upperBound);
+ Metadata *Stride = ConvToMetadata(stride);
+
+ Result = GET_OR_DISTINCT(DIGenericSubrange,
+ (Context, Count, LowerBound, UpperBound, Stride));
+
+ return false;
+}
+
+/// parseDIEnumerator:
/// ::= !DIEnumerator(value: 30, isUnsigned: true, name: "SomeKind")
-bool LLParser::parseDIEnumerator(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDIEnumerator(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(name, MDStringField, ); \
REQUIRED(value, MDAPSIntField, ); \
@@ -4735,7 +4735,7 @@ bool LLParser::parseDIEnumerator(MDNode *&Result, bool IsDistinct) {
#undef VISIT_MD_FIELDS
if (isUnsigned.Val && value.Val.isNegative())
- return tokError("unsigned enumerator with negative value");
+ return tokError("unsigned enumerator with negative value");
APSInt Value(value.Val);
// Add a leading zero so that unsigned values with the msb set are not
@@ -4749,10 +4749,10 @@ bool LLParser::parseDIEnumerator(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDIBasicType:
+/// parseDIBasicType:
/// ::= !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32,
/// encoding: DW_ATE_encoding, flags: 0)
-bool LLParser::parseDIBasicType(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDIBasicType(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_base_type)); \
OPTIONAL(name, MDStringField, ); \
@@ -4768,33 +4768,33 @@ bool LLParser::parseDIBasicType(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDIStringType:
-/// ::= !DIStringType(name: "character(4)", size: 32, align: 32)
-bool LLParser::parseDIStringType(MDNode *&Result, bool IsDistinct) {
-#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
- OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_string_type)); \
- OPTIONAL(name, MDStringField, ); \
- OPTIONAL(stringLength, MDField, ); \
- OPTIONAL(stringLengthExpression, MDField, ); \
- OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
- OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \
- OPTIONAL(encoding, DwarfAttEncodingField, );
- PARSE_MD_FIELDS();
-#undef VISIT_MD_FIELDS
-
- Result = GET_OR_DISTINCT(DIStringType,
- (Context, tag.Val, name.Val, stringLength.Val,
- stringLengthExpression.Val, size.Val, align.Val,
- encoding.Val));
- return false;
-}
-
-/// parseDIDerivedType:
+/// parseDIStringType:
+/// ::= !DIStringType(name: "character(4)", size: 32, align: 32)
+bool LLParser::parseDIStringType(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_string_type)); \
+ OPTIONAL(name, MDStringField, ); \
+ OPTIONAL(stringLength, MDField, ); \
+ OPTIONAL(stringLengthExpression, MDField, ); \
+ OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(encoding, DwarfAttEncodingField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DIStringType,
+ (Context, tag.Val, name.Val, stringLength.Val,
+ stringLengthExpression.Val, size.Val, align.Val,
+ encoding.Val));
+ return false;
+}
+
+/// parseDIDerivedType:
/// ::= !DIDerivedType(tag: DW_TAG_pointer_type, name: "int", file: !0,
/// line: 7, scope: !1, baseType: !2, size: 32,
/// align: 32, offset: 0, flags: 0, extraData: !3,
/// dwarfAddressSpace: 3)
-bool LLParser::parseDIDerivedType(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDIDerivedType(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(tag, DwarfTagField, ); \
OPTIONAL(name, MDStringField, ); \
@@ -4823,7 +4823,7 @@ bool LLParser::parseDIDerivedType(MDNode *&Result, bool IsDistinct) {
return false;
}
-bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(tag, DwarfTagField, ); \
OPTIONAL(name, MDStringField, ); \
@@ -4841,28 +4841,28 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
OPTIONAL(templateParams, MDField, ); \
OPTIONAL(identifier, MDStringField, ); \
OPTIONAL(discriminator, MDField, ); \
- OPTIONAL(dataLocation, MDField, ); \
- OPTIONAL(associated, MDField, ); \
- OPTIONAL(allocated, MDField, ); \
- OPTIONAL(rank, MDSignedOrMDField, );
+ OPTIONAL(dataLocation, MDField, ); \
+ OPTIONAL(associated, MDField, ); \
+ OPTIONAL(allocated, MDField, ); \
+ OPTIONAL(rank, MDSignedOrMDField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
- Metadata *Rank = nullptr;
- if (rank.isMDSignedField())
- Rank = ConstantAsMetadata::get(ConstantInt::getSigned(
- Type::getInt64Ty(Context), rank.getMDSignedValue()));
- else if (rank.isMDField())
- Rank = rank.getMDFieldValue();
-
+ Metadata *Rank = nullptr;
+ if (rank.isMDSignedField())
+ Rank = ConstantAsMetadata::get(ConstantInt::getSigned(
+ Type::getInt64Ty(Context), rank.getMDSignedValue()));
+ else if (rank.isMDField())
+ Rank = rank.getMDFieldValue();
+
// If this has an identifier try to build an ODR type.
if (identifier.Val)
if (auto *CT = DICompositeType::buildODRType(
Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val,
scope.Val, baseType.Val, size.Val, align.Val, offset.Val, flags.Val,
elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val,
- discriminator.Val, dataLocation.Val, associated.Val, allocated.Val,
- Rank)) {
+ discriminator.Val, dataLocation.Val, associated.Val, allocated.Val,
+ Rank)) {
Result = CT;
return false;
}
@@ -4874,12 +4874,12 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
(Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val,
size.Val, align.Val, offset.Val, flags.Val, elements.Val,
runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val,
- discriminator.Val, dataLocation.Val, associated.Val, allocated.Val,
- Rank));
+ discriminator.Val, dataLocation.Val, associated.Val, allocated.Val,
+ Rank));
return false;
}
-bool LLParser::parseDISubroutineType(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDISubroutineType(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
OPTIONAL(flags, DIFlagField, ); \
OPTIONAL(cc, DwarfCCField, ); \
@@ -4892,12 +4892,12 @@ bool LLParser::parseDISubroutineType(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDIFileType:
+/// parseDIFileType:
/// ::= !DIFileType(filename: "path/to/file", directory: "/path/to/dir",
/// checksumkind: CSK_MD5,
/// checksum: "000102030405060708090a0b0c0d0e0f",
/// source: "source file contents")
-bool LLParser::parseDIFile(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDIFile(MDNode *&Result, bool IsDistinct) {
// The default constructed value for checksumkind is required, but will never
// be used, as the parser checks if the field was actually Seen before using
// the Val.
@@ -4924,14 +4924,14 @@ bool LLParser::parseDIFile(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDICompileUnit:
+/// parseDICompileUnit:
/// ::= !DICompileUnit(language: DW_LANG_C99, file: !0, producer: "clang",
/// isOptimized: true, flags: "-O2", runtimeVersion: 1,
/// splitDebugFilename: "abc.debug",
/// emissionKind: FullDebug, enums: !1, retainedTypes: !2,
/// globals: !4, imports: !5, macros: !6, dwoId: 0x0abcd,
/// sysroot: "/", sdk: "MacOSX.sdk")
-bool LLParser::parseDICompileUnit(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDICompileUnit(MDNode *&Result, bool IsDistinct) {
if (!IsDistinct)
return Lex.Error("missing 'distinct', required for !DICompileUnit");
@@ -4968,7 +4968,7 @@ bool LLParser::parseDICompileUnit(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDISubprogram:
+/// parseDISubprogram:
/// ::= !DISubprogram(scope: !0, name: "foo", linkageName: "_Zfoo",
/// file: !1, line: 7, type: !2, isLocal: false,
/// isDefinition: true, scopeLine: 8, containingType: !3,
@@ -4976,7 +4976,7 @@ bool LLParser::parseDICompileUnit(MDNode *&Result, bool IsDistinct) {
/// virtualIndex: 10, thisAdjustment: 4, flags: 11,
/// spFlags: 10, isOptimized: false, templateParams: !4,
/// declaration: !5, retainedNodes: !6, thrownTypes: !7)
-bool LLParser::parseDISubprogram(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDISubprogram(MDNode *&Result, bool IsDistinct) {
auto Loc = Lex.getLoc();
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
OPTIONAL(scope, MDField, ); \
@@ -5022,9 +5022,9 @@ bool LLParser::parseDISubprogram(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDILexicalBlock:
+/// parseDILexicalBlock:
/// ::= !DILexicalBlock(scope: !0, file: !2, line: 7, column: 9)
-bool LLParser::parseDILexicalBlock(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDILexicalBlock(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(scope, MDField, (/* AllowNull */ false)); \
OPTIONAL(file, MDField, ); \
@@ -5038,9 +5038,9 @@ bool LLParser::parseDILexicalBlock(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDILexicalBlockFile:
+/// parseDILexicalBlockFile:
/// ::= !DILexicalBlockFile(scope: !0, file: !2, discriminator: 9)
-bool LLParser::parseDILexicalBlockFile(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDILexicalBlockFile(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(scope, MDField, (/* AllowNull */ false)); \
OPTIONAL(file, MDField, ); \
@@ -5053,9 +5053,9 @@ bool LLParser::parseDILexicalBlockFile(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDICommonBlock:
+/// parseDICommonBlock:
/// ::= !DICommonBlock(scope: !0, file: !2, name: "COMMON name", line: 9)
-bool LLParser::parseDICommonBlock(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDICommonBlock(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(scope, MDField, ); \
OPTIONAL(declaration, MDField, ); \
@@ -5071,9 +5071,9 @@ bool LLParser::parseDICommonBlock(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDINamespace:
+/// parseDINamespace:
/// ::= !DINamespace(scope: !0, file: !2, name: "SomeNamespace", line: 9)
-bool LLParser::parseDINamespace(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDINamespace(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(scope, MDField, ); \
OPTIONAL(name, MDStringField, ); \
@@ -5086,10 +5086,10 @@ bool LLParser::parseDINamespace(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDIMacro:
-/// ::= !DIMacro(macinfo: type, line: 9, name: "SomeMacro", value:
-/// "SomeValue")
-bool LLParser::parseDIMacro(MDNode *&Result, bool IsDistinct) {
+/// parseDIMacro:
+/// ::= !DIMacro(macinfo: type, line: 9, name: "SomeMacro", value:
+/// "SomeValue")
+bool LLParser::parseDIMacro(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(type, DwarfMacinfoTypeField, ); \
OPTIONAL(line, LineField, ); \
@@ -5103,9 +5103,9 @@ bool LLParser::parseDIMacro(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDIMacroFile:
+/// parseDIMacroFile:
/// ::= !DIMacroFile(line: 9, file: !2, nodes: !3)
-bool LLParser::parseDIMacroFile(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDIMacroFile(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
OPTIONAL(type, DwarfMacinfoTypeField, (dwarf::DW_MACINFO_start_file)); \
OPTIONAL(line, LineField, ); \
@@ -5119,11 +5119,11 @@ bool LLParser::parseDIMacroFile(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDIModule:
+/// parseDIModule:
/// ::= !DIModule(scope: !0, name: "SomeModule", configMacros:
/// "-DNDEBUG", includePath: "/usr/include", apinotes: "module.apinotes",
-/// file: !1, line: 4, isDecl: false)
-bool LLParser::parseDIModule(MDNode *&Result, bool IsDistinct) {
+/// file: !1, line: 4, isDecl: false)
+bool LLParser::parseDIModule(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(scope, MDField, ); \
REQUIRED(name, MDStringField, ); \
@@ -5131,20 +5131,20 @@ bool LLParser::parseDIModule(MDNode *&Result, bool IsDistinct) {
OPTIONAL(includePath, MDStringField, ); \
OPTIONAL(apinotes, MDStringField, ); \
OPTIONAL(file, MDField, ); \
- OPTIONAL(line, LineField, ); \
- OPTIONAL(isDecl, MDBoolField, );
+ OPTIONAL(line, LineField, ); \
+ OPTIONAL(isDecl, MDBoolField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
Result = GET_OR_DISTINCT(DIModule, (Context, file.Val, scope.Val, name.Val,
configMacros.Val, includePath.Val,
- apinotes.Val, line.Val, isDecl.Val));
+ apinotes.Val, line.Val, isDecl.Val));
return false;
}
-/// parseDITemplateTypeParameter:
+/// parseDITemplateTypeParameter:
/// ::= !DITemplateTypeParameter(name: "Ty", type: !1, defaulted: false)
-bool LLParser::parseDITemplateTypeParameter(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDITemplateTypeParameter(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
OPTIONAL(name, MDStringField, ); \
REQUIRED(type, MDField, ); \
@@ -5157,11 +5157,11 @@ bool LLParser::parseDITemplateTypeParameter(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDITemplateValueParameter:
+/// parseDITemplateValueParameter:
/// ::= !DITemplateValueParameter(tag: DW_TAG_template_value_parameter,
/// name: "V", type: !1, defaulted: false,
/// value: i32 7)
-bool LLParser::parseDITemplateValueParameter(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDITemplateValueParameter(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_template_value_parameter)); \
OPTIONAL(name, MDStringField, ); \
@@ -5178,12 +5178,12 @@ bool LLParser::parseDITemplateValueParameter(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDIGlobalVariable:
+/// parseDIGlobalVariable:
/// ::= !DIGlobalVariable(scope: !0, name: "foo", linkageName: "foo",
/// file: !1, line: 7, type: !2, isLocal: false,
/// isDefinition: true, templateParams: !3,
/// declaration: !4, align: 8)
-bool LLParser::parseDIGlobalVariable(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDIGlobalVariable(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(name, MDStringField, (/* AllowEmpty */ false)); \
OPTIONAL(scope, MDField, ); \
@@ -5207,14 +5207,14 @@ bool LLParser::parseDIGlobalVariable(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDILocalVariable:
+/// parseDILocalVariable:
/// ::= !DILocalVariable(arg: 7, scope: !0, name: "foo",
/// file: !1, line: 7, type: !2, arg: 2, flags: 7,
/// align: 8)
/// ::= !DILocalVariable(scope: !0, name: "foo",
/// file: !1, line: 7, type: !2, arg: 2, flags: 7,
/// align: 8)
-bool LLParser::parseDILocalVariable(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDILocalVariable(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(scope, MDField, (/* AllowNull */ false)); \
OPTIONAL(name, MDStringField, ); \
@@ -5233,9 +5233,9 @@ bool LLParser::parseDILocalVariable(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDILabel:
+/// parseDILabel:
/// ::= !DILabel(scope: !0, name: "foo", file: !1, line: 7)
-bool LLParser::parseDILabel(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDILabel(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(scope, MDField, (/* AllowNull */ false)); \
REQUIRED(name, MDStringField, ); \
@@ -5249,13 +5249,13 @@ bool LLParser::parseDILabel(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDIExpression:
+/// parseDIExpression:
/// ::= !DIExpression(0, 7, -1)
-bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) {
assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
Lex.Lex();
- if (parseToken(lltok::lparen, "expected '(' here"))
+ if (parseToken(lltok::lparen, "expected '(' here"))
return true;
SmallVector<uint64_t, 8> Elements;
@@ -5267,7 +5267,7 @@ bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) {
Elements.push_back(Op);
continue;
}
- return tokError(Twine("invalid DWARF op '") + Lex.getStrVal() + "'");
+ return tokError(Twine("invalid DWARF op '") + Lex.getStrVal() + "'");
}
if (Lex.getKind() == lltok::DwarfAttEncoding) {
@@ -5276,30 +5276,30 @@ bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) {
Elements.push_back(Op);
continue;
}
- return tokError(Twine("invalid DWARF attribute encoding '") +
- Lex.getStrVal() + "'");
+ return tokError(Twine("invalid DWARF attribute encoding '") +
+ Lex.getStrVal() + "'");
}
if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
- return tokError("expected unsigned integer");
+ return tokError("expected unsigned integer");
auto &U = Lex.getAPSIntVal();
if (U.ugt(UINT64_MAX))
- return tokError("element too large, limit is " + Twine(UINT64_MAX));
+ return tokError("element too large, limit is " + Twine(UINT64_MAX));
Elements.push_back(U.getZExtValue());
Lex.Lex();
} while (EatIfPresent(lltok::comma));
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
Result = GET_OR_DISTINCT(DIExpression, (Context, Elements));
return false;
}
-/// parseDIGlobalVariableExpression:
+/// parseDIGlobalVariableExpression:
/// ::= !DIGlobalVariableExpression(var: !0, expr: !1)
-bool LLParser::parseDIGlobalVariableExpression(MDNode *&Result,
+bool LLParser::parseDIGlobalVariableExpression(MDNode *&Result,
bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(var, MDField, ); \
@@ -5312,10 +5312,10 @@ bool LLParser::parseDIGlobalVariableExpression(MDNode *&Result,
return false;
}
-/// parseDIObjCProperty:
+/// parseDIObjCProperty:
/// ::= !DIObjCProperty(name: "foo", file: !1, line: 7, setter: "setFoo",
/// getter: "getFoo", attributes: 7, type: !2)
-bool LLParser::parseDIObjCProperty(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDIObjCProperty(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
OPTIONAL(name, MDStringField, ); \
OPTIONAL(file, MDField, ); \
@@ -5333,10 +5333,10 @@ bool LLParser::parseDIObjCProperty(MDNode *&Result, bool IsDistinct) {
return false;
}
-/// parseDIImportedEntity:
+/// parseDIImportedEntity:
/// ::= !DIImportedEntity(tag: DW_TAG_imported_module, scope: !0, entity: !1,
/// line: 7, name: "foo")
-bool LLParser::parseDIImportedEntity(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDIImportedEntity(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(tag, DwarfTagField, ); \
REQUIRED(scope, MDField, ); \
@@ -5358,45 +5358,45 @@ bool LLParser::parseDIImportedEntity(MDNode *&Result, bool IsDistinct) {
#undef REQUIRE_FIELD
#undef DECLARE_FIELD
-/// parseMetadataAsValue
+/// parseMetadataAsValue
/// ::= metadata i32 %local
/// ::= metadata i32 @global
/// ::= metadata i32 7
/// ::= metadata !0
/// ::= metadata !{...}
/// ::= metadata !"string"
-bool LLParser::parseMetadataAsValue(Value *&V, PerFunctionState &PFS) {
+bool LLParser::parseMetadataAsValue(Value *&V, PerFunctionState &PFS) {
// Note: the type 'metadata' has already been parsed.
Metadata *MD;
- if (parseMetadata(MD, &PFS))
+ if (parseMetadata(MD, &PFS))
return true;
V = MetadataAsValue::get(Context, MD);
return false;
}
-/// parseValueAsMetadata
+/// parseValueAsMetadata
/// ::= i32 %local
/// ::= i32 @global
/// ::= i32 7
-bool LLParser::parseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg,
+bool LLParser::parseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg,
PerFunctionState *PFS) {
Type *Ty;
LocTy Loc;
- if (parseType(Ty, TypeMsg, Loc))
+ if (parseType(Ty, TypeMsg, Loc))
return true;
if (Ty->isMetadataTy())
- return error(Loc, "invalid metadata-value-metadata roundtrip");
+ return error(Loc, "invalid metadata-value-metadata roundtrip");
Value *V;
- if (parseValue(Ty, V, PFS))
+ if (parseValue(Ty, V, PFS))
return true;
MD = ValueAsMetadata::get(V);
return false;
}
-/// parseMetadata
+/// parseMetadata
/// ::= i32 %local
/// ::= i32 @global
/// ::= i32 7
@@ -5404,10 +5404,10 @@ bool LLParser::parseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg,
/// ::= !{...}
/// ::= !"string"
/// ::= !DILocation(...)
-bool LLParser::parseMetadata(Metadata *&MD, PerFunctionState *PFS) {
+bool LLParser::parseMetadata(Metadata *&MD, PerFunctionState *PFS) {
if (Lex.getKind() == lltok::MetadataVar) {
MDNode *N;
- if (parseSpecializedMDNode(N))
+ if (parseSpecializedMDNode(N))
return true;
MD = N;
return false;
@@ -5416,7 +5416,7 @@ bool LLParser::parseMetadata(Metadata *&MD, PerFunctionState *PFS) {
// ValueAsMetadata:
// <type> <value>
if (Lex.getKind() != lltok::exclaim)
- return parseValueAsMetadata(MD, "expected metadata operand", PFS);
+ return parseValueAsMetadata(MD, "expected metadata operand", PFS);
// '!'.
assert(Lex.getKind() == lltok::exclaim && "Expected '!' here");
@@ -5426,7 +5426,7 @@ bool LLParser::parseMetadata(Metadata *&MD, PerFunctionState *PFS) {
// ::= '!' STRINGCONSTANT
if (Lex.getKind() == lltok::StringConstant) {
MDString *S;
- if (parseMDString(S))
+ if (parseMDString(S))
return true;
MD = S;
return false;
@@ -5436,7 +5436,7 @@ bool LLParser::parseMetadata(Metadata *&MD, PerFunctionState *PFS) {
// !{ ... }
// !7
MDNode *N;
- if (parseMDNodeTail(N))
+ if (parseMDNodeTail(N))
return true;
MD = N;
return false;
@@ -5446,52 +5446,52 @@ bool LLParser::parseMetadata(Metadata *&MD, PerFunctionState *PFS) {
// Function Parsing.
//===----------------------------------------------------------------------===//
-bool LLParser::convertValIDToValue(Type *Ty, ValID &ID, Value *&V,
+bool LLParser::convertValIDToValue(Type *Ty, ValID &ID, Value *&V,
PerFunctionState *PFS, bool IsCall) {
if (Ty->isFunctionTy())
- return error(ID.Loc, "functions are not values, refer to them as pointers");
+ return error(ID.Loc, "functions are not values, refer to them as pointers");
switch (ID.Kind) {
case ValID::t_LocalID:
- if (!PFS)
- return error(ID.Loc, "invalid use of function-local name");
- V = PFS->getVal(ID.UIntVal, Ty, ID.Loc, IsCall);
+ if (!PFS)
+ return error(ID.Loc, "invalid use of function-local name");
+ V = PFS->getVal(ID.UIntVal, Ty, ID.Loc, IsCall);
return V == nullptr;
case ValID::t_LocalName:
- if (!PFS)
- return error(ID.Loc, "invalid use of function-local name");
- V = PFS->getVal(ID.StrVal, Ty, ID.Loc, IsCall);
+ if (!PFS)
+ return error(ID.Loc, "invalid use of function-local name");
+ V = PFS->getVal(ID.StrVal, Ty, ID.Loc, IsCall);
return V == nullptr;
case ValID::t_InlineAsm: {
if (!ID.FTy || !InlineAsm::Verify(ID.FTy, ID.StrVal2))
- return error(ID.Loc, "invalid type for inline asm constraint string");
+ return error(ID.Loc, "invalid type for inline asm constraint string");
V = InlineAsm::get(ID.FTy, ID.StrVal, ID.StrVal2, ID.UIntVal & 1,
(ID.UIntVal >> 1) & 1,
(InlineAsm::AsmDialect(ID.UIntVal >> 2)));
return false;
}
case ValID::t_GlobalName:
- V = getGlobalVal(ID.StrVal, Ty, ID.Loc, IsCall);
+ V = getGlobalVal(ID.StrVal, Ty, ID.Loc, IsCall);
return V == nullptr;
case ValID::t_GlobalID:
- V = getGlobalVal(ID.UIntVal, Ty, ID.Loc, IsCall);
+ V = getGlobalVal(ID.UIntVal, Ty, ID.Loc, IsCall);
return V == nullptr;
case ValID::t_APSInt:
if (!Ty->isIntegerTy())
- return error(ID.Loc, "integer constant must have integer type");
+ return error(ID.Loc, "integer constant must have integer type");
ID.APSIntVal = ID.APSIntVal.extOrTrunc(Ty->getPrimitiveSizeInBits());
V = ConstantInt::get(Context, ID.APSIntVal);
return false;
case ValID::t_APFloat:
if (!Ty->isFloatingPointTy() ||
!ConstantFP::isValueValidForType(Ty, ID.APFloatVal))
- return error(ID.Loc, "floating point constant invalid for type");
+ return error(ID.Loc, "floating point constant invalid for type");
// The lexer has no type info, so builds all half, bfloat, float, and double
// FP constants as double. Fix this here. Long double does not need this.
if (&ID.APFloatVal.getSemantics() == &APFloat::IEEEdouble()) {
- // Check for signaling before potentially converting and losing that info.
- bool IsSNAN = ID.APFloatVal.isSignaling();
+ // Check for signaling before potentially converting and losing that info.
+ bool IsSNAN = ID.APFloatVal.isSignaling();
bool Ignored;
if (Ty->isHalfTy())
ID.APFloatVal.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven,
@@ -5502,81 +5502,81 @@ bool LLParser::convertValIDToValue(Type *Ty, ValID &ID, Value *&V,
else if (Ty->isFloatTy())
ID.APFloatVal.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven,
&Ignored);
- if (IsSNAN) {
- // The convert call above may quiet an SNaN, so manufacture another
- // SNaN. The bitcast works because the payload (significand) parameter
- // is truncated to fit.
- APInt Payload = ID.APFloatVal.bitcastToAPInt();
- ID.APFloatVal = APFloat::getSNaN(ID.APFloatVal.getSemantics(),
- ID.APFloatVal.isNegative(), &Payload);
- }
+ if (IsSNAN) {
+ // The convert call above may quiet an SNaN, so manufacture another
+ // SNaN. The bitcast works because the payload (significand) parameter
+ // is truncated to fit.
+ APInt Payload = ID.APFloatVal.bitcastToAPInt();
+ ID.APFloatVal = APFloat::getSNaN(ID.APFloatVal.getSemantics(),
+ ID.APFloatVal.isNegative(), &Payload);
+ }
}
V = ConstantFP::get(Context, ID.APFloatVal);
if (V->getType() != Ty)
- return error(ID.Loc, "floating point constant does not have type '" +
- getTypeString(Ty) + "'");
+ return error(ID.Loc, "floating point constant does not have type '" +
+ getTypeString(Ty) + "'");
return false;
case ValID::t_Null:
if (!Ty->isPointerTy())
- return error(ID.Loc, "null must be a pointer type");
+ return error(ID.Loc, "null must be a pointer type");
V = ConstantPointerNull::get(cast<PointerType>(Ty));
return false;
case ValID::t_Undef:
// FIXME: LabelTy should not be a first-class type.
if (!Ty->isFirstClassType() || Ty->isLabelTy())
- return error(ID.Loc, "invalid type for undef constant");
+ return error(ID.Loc, "invalid type for undef constant");
V = UndefValue::get(Ty);
return false;
case ValID::t_EmptyArray:
if (!Ty->isArrayTy() || cast<ArrayType>(Ty)->getNumElements() != 0)
- return error(ID.Loc, "invalid empty array initializer");
+ return error(ID.Loc, "invalid empty array initializer");
V = UndefValue::get(Ty);
return false;
case ValID::t_Zero:
// FIXME: LabelTy should not be a first-class type.
if (!Ty->isFirstClassType() || Ty->isLabelTy())
- return error(ID.Loc, "invalid type for null constant");
+ return error(ID.Loc, "invalid type for null constant");
V = Constant::getNullValue(Ty);
return false;
case ValID::t_None:
if (!Ty->isTokenTy())
- return error(ID.Loc, "invalid type for none constant");
+ return error(ID.Loc, "invalid type for none constant");
V = Constant::getNullValue(Ty);
return false;
- case ValID::t_Poison:
- // FIXME: LabelTy should not be a first-class type.
- if (!Ty->isFirstClassType() || Ty->isLabelTy())
- return error(ID.Loc, "invalid type for poison constant");
- V = PoisonValue::get(Ty);
- return false;
+ case ValID::t_Poison:
+ // FIXME: LabelTy should not be a first-class type.
+ if (!Ty->isFirstClassType() || Ty->isLabelTy())
+ return error(ID.Loc, "invalid type for poison constant");
+ V = PoisonValue::get(Ty);
+ return false;
case ValID::t_Constant:
if (ID.ConstantVal->getType() != Ty)
- return error(ID.Loc, "constant expression type mismatch");
+ return error(ID.Loc, "constant expression type mismatch");
V = ID.ConstantVal;
return false;
case ValID::t_ConstantStruct:
case ValID::t_PackedConstantStruct:
if (StructType *ST = dyn_cast<StructType>(Ty)) {
if (ST->getNumElements() != ID.UIntVal)
- return error(ID.Loc,
+ return error(ID.Loc,
"initializer with struct type has wrong # elements");
if (ST->isPacked() != (ID.Kind == ValID::t_PackedConstantStruct))
- return error(ID.Loc, "packed'ness of initializer and type don't match");
+ return error(ID.Loc, "packed'ness of initializer and type don't match");
// Verify that the elements are compatible with the structtype.
for (unsigned i = 0, e = ID.UIntVal; i != e; ++i)
if (ID.ConstantStructElts[i]->getType() != ST->getElementType(i))
- return error(
- ID.Loc,
- "element " + Twine(i) +
- " of struct initializer doesn't match struct element type");
+ return error(
+ ID.Loc,
+ "element " + Twine(i) +
+ " of struct initializer doesn't match struct element type");
V = ConstantStruct::get(
ST, makeArrayRef(ID.ConstantStructElts.get(), ID.UIntVal));
} else
- return error(ID.Loc, "constant expression type mismatch");
+ return error(ID.Loc, "constant expression type mismatch");
return false;
}
llvm_unreachable("Invalid ValID");
@@ -5586,7 +5586,7 @@ bool LLParser::parseConstantValue(Type *Ty, Constant *&C) {
C = nullptr;
ValID ID;
auto Loc = Lex.getLoc();
- if (parseValID(ID, /*PFS=*/nullptr))
+ if (parseValID(ID, /*PFS=*/nullptr))
return true;
switch (ID.Kind) {
case ValID::t_APSInt:
@@ -5596,7 +5596,7 @@ bool LLParser::parseConstantValue(Type *Ty, Constant *&C) {
case ValID::t_ConstantStruct:
case ValID::t_PackedConstantStruct: {
Value *V;
- if (convertValIDToValue(Ty, ID, V, /*PFS=*/nullptr, /*IsCall=*/false))
+ if (convertValIDToValue(Ty, ID, V, /*PFS=*/nullptr, /*IsCall=*/false))
return true;
assert(isa<Constant>(V) && "Expected a constant value");
C = cast<Constant>(V);
@@ -5606,30 +5606,30 @@ bool LLParser::parseConstantValue(Type *Ty, Constant *&C) {
C = Constant::getNullValue(Ty);
return false;
default:
- return error(Loc, "expected a constant value");
+ return error(Loc, "expected a constant value");
}
}
-bool LLParser::parseValue(Type *Ty, Value *&V, PerFunctionState *PFS) {
+bool LLParser::parseValue(Type *Ty, Value *&V, PerFunctionState *PFS) {
V = nullptr;
ValID ID;
- return parseValID(ID, PFS) ||
- convertValIDToValue(Ty, ID, V, PFS, /*IsCall=*/false);
+ return parseValID(ID, PFS) ||
+ convertValIDToValue(Ty, ID, V, PFS, /*IsCall=*/false);
}
-bool LLParser::parseTypeAndValue(Value *&V, PerFunctionState *PFS) {
+bool LLParser::parseTypeAndValue(Value *&V, PerFunctionState *PFS) {
Type *Ty = nullptr;
- return parseType(Ty) || parseValue(Ty, V, PFS);
+ return parseType(Ty) || parseValue(Ty, V, PFS);
}
-bool LLParser::parseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc,
+bool LLParser::parseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc,
PerFunctionState &PFS) {
Value *V;
Loc = Lex.getLoc();
- if (parseTypeAndValue(V, PFS))
- return true;
+ if (parseTypeAndValue(V, PFS))
+ return true;
if (!isa<BasicBlock>(V))
- return error(Loc, "expected a basic block");
+ return error(Loc, "expected a basic block");
BB = cast<BasicBlock>(V);
return false;
}
@@ -5639,8 +5639,8 @@ bool LLParser::parseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc,
/// OptionalCallingConv OptRetAttrs OptUnnamedAddr Type GlobalName
/// '(' ArgList ')' OptAddrSpace OptFuncAttrs OptSection OptionalAlign
/// OptGC OptionalPrefix OptionalPrologue OptPersonalityFn
-bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
- // parse the linkage.
+bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
+ // parse the linkage.
LocTy LinkageLoc = Lex.getLoc();
unsigned Linkage;
unsigned Visibility;
@@ -5651,10 +5651,10 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
bool HasLinkage;
Type *RetType = nullptr;
LocTy RetTypeLoc = Lex.getLoc();
- if (parseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass,
+ if (parseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass,
DSOLocal) ||
- parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(RetAttrs) ||
- parseType(RetType, RetTypeLoc, true /*void allowed*/))
+ parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(RetAttrs) ||
+ parseType(RetType, RetTypeLoc, true /*void allowed*/))
return true;
// Verify that the linkage is ok.
@@ -5662,8 +5662,8 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
case GlobalValue::ExternalLinkage:
break; // always ok.
case GlobalValue::ExternalWeakLinkage:
- if (IsDefine)
- return error(LinkageLoc, "invalid linkage for function definition");
+ if (IsDefine)
+ return error(LinkageLoc, "invalid linkage for function definition");
break;
case GlobalValue::PrivateLinkage:
case GlobalValue::InternalLinkage:
@@ -5672,20 +5672,20 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
case GlobalValue::LinkOnceODRLinkage:
case GlobalValue::WeakAnyLinkage:
case GlobalValue::WeakODRLinkage:
- if (!IsDefine)
- return error(LinkageLoc, "invalid linkage for function declaration");
+ if (!IsDefine)
+ return error(LinkageLoc, "invalid linkage for function declaration");
break;
case GlobalValue::AppendingLinkage:
case GlobalValue::CommonLinkage:
- return error(LinkageLoc, "invalid function linkage type");
+ return error(LinkageLoc, "invalid function linkage type");
}
if (!isValidVisibilityForLinkage(Visibility, Linkage))
- return error(LinkageLoc,
+ return error(LinkageLoc,
"symbol with local linkage must have default visibility");
if (!FunctionType::isValidReturnType(RetType))
- return error(RetTypeLoc, "invalid function return type");
+ return error(RetTypeLoc, "invalid function return type");
LocTy NameLoc = Lex.getLoc();
@@ -5696,19 +5696,19 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
unsigned NameID = Lex.getUIntVal();
if (NameID != NumberedVals.size())
- return tokError("function expected to be numbered '%" +
+ return tokError("function expected to be numbered '%" +
Twine(NumberedVals.size()) + "'");
} else {
- return tokError("expected function name");
+ return tokError("expected function name");
}
Lex.Lex();
if (Lex.getKind() != lltok::lparen)
- return tokError("expected '(' in function argument list");
+ return tokError("expected '(' in function argument list");
SmallVector<ArgInfo, 8> ArgList;
- bool IsVarArg;
+ bool IsVarArg;
AttrBuilder FuncAttrs;
std::vector<unsigned> FwdRefAttrGrps;
LocTy BuiltinLoc;
@@ -5723,24 +5723,24 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
Constant *PersonalityFn = nullptr;
Comdat *C;
- if (parseArgumentList(ArgList, IsVarArg) ||
- parseOptionalUnnamedAddr(UnnamedAddr) ||
- parseOptionalProgramAddrSpace(AddrSpace) ||
- parseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false,
+ if (parseArgumentList(ArgList, IsVarArg) ||
+ parseOptionalUnnamedAddr(UnnamedAddr) ||
+ parseOptionalProgramAddrSpace(AddrSpace) ||
+ parseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false,
BuiltinLoc) ||
- (EatIfPresent(lltok::kw_section) && parseStringConstant(Section)) ||
- (EatIfPresent(lltok::kw_partition) && parseStringConstant(Partition)) ||
+ (EatIfPresent(lltok::kw_section) && parseStringConstant(Section)) ||
+ (EatIfPresent(lltok::kw_partition) && parseStringConstant(Partition)) ||
parseOptionalComdat(FunctionName, C) ||
- parseOptionalAlignment(Alignment) ||
- (EatIfPresent(lltok::kw_gc) && parseStringConstant(GC)) ||
- (EatIfPresent(lltok::kw_prefix) && parseGlobalTypeAndValue(Prefix)) ||
- (EatIfPresent(lltok::kw_prologue) && parseGlobalTypeAndValue(Prologue)) ||
+ parseOptionalAlignment(Alignment) ||
+ (EatIfPresent(lltok::kw_gc) && parseStringConstant(GC)) ||
+ (EatIfPresent(lltok::kw_prefix) && parseGlobalTypeAndValue(Prefix)) ||
+ (EatIfPresent(lltok::kw_prologue) && parseGlobalTypeAndValue(Prologue)) ||
(EatIfPresent(lltok::kw_personality) &&
- parseGlobalTypeAndValue(PersonalityFn)))
+ parseGlobalTypeAndValue(PersonalityFn)))
return true;
if (FuncAttrs.contains(Attribute::Builtin))
- return error(BuiltinLoc, "'builtin' attribute not valid on function");
+ return error(BuiltinLoc, "'builtin' attribute not valid on function");
// If the alignment was parsed as an attribute, move to the alignment field.
if (FuncAttrs.hasAlignmentAttr()) {
@@ -5763,9 +5763,9 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
AttributeSet::get(Context, RetAttrs), Attrs);
if (PAL.hasAttribute(1, Attribute::StructRet) && !RetType->isVoidTy())
- return error(RetTypeLoc, "functions with 'sret' argument must return void");
+ return error(RetTypeLoc, "functions with 'sret' argument must return void");
- FunctionType *FT = FunctionType::get(RetType, ParamTypeList, IsVarArg);
+ FunctionType *FT = FunctionType::get(RetType, ParamTypeList, IsVarArg);
PointerType *PFT = PointerType::get(FT, AddrSpace);
Fn = nullptr;
@@ -5776,24 +5776,24 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
if (FRVI != ForwardRefVals.end()) {
Fn = M->getFunction(FunctionName);
if (!Fn)
- return error(FRVI->second.second, "invalid forward reference to "
- "function as global value!");
+ return error(FRVI->second.second, "invalid forward reference to "
+ "function as global value!");
if (Fn->getType() != PFT)
- return error(FRVI->second.second,
- "invalid forward reference to "
- "function '" +
- FunctionName +
- "' with wrong type: "
- "expected '" +
- getTypeString(PFT) + "' but was '" +
- getTypeString(Fn->getType()) + "'");
+ return error(FRVI->second.second,
+ "invalid forward reference to "
+ "function '" +
+ FunctionName +
+ "' with wrong type: "
+ "expected '" +
+ getTypeString(PFT) + "' but was '" +
+ getTypeString(Fn->getType()) + "'");
ForwardRefVals.erase(FRVI);
} else if ((Fn = M->getFunction(FunctionName))) {
// Reject redefinitions.
- return error(NameLoc,
- "invalid redefinition of function '" + FunctionName + "'");
+ return error(NameLoc,
+ "invalid redefinition of function '" + FunctionName + "'");
} else if (M->getNamedValue(FunctionName)) {
- return error(NameLoc, "redefinition of function '@" + FunctionName + "'");
+ return error(NameLoc, "redefinition of function '@" + FunctionName + "'");
}
} else {
@@ -5803,12 +5803,12 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
if (I != ForwardRefValIDs.end()) {
Fn = cast<Function>(I->second.first);
if (Fn->getType() != PFT)
- return error(NameLoc, "type of definition and forward reference of '@" +
- Twine(NumberedVals.size()) +
- "' disagree: "
- "expected '" +
- getTypeString(PFT) + "' but was '" +
- getTypeString(Fn->getType()) + "'");
+ return error(NameLoc, "type of definition and forward reference of '@" +
+ Twine(NumberedVals.size()) +
+ "' disagree: "
+ "expected '" +
+ getTypeString(PFT) + "' but was '" +
+ getTypeString(Fn->getType()) + "'");
ForwardRefValIDs.erase(I);
}
}
@@ -5851,11 +5851,11 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
ArgIt->setName(ArgList[i].Name);
if (ArgIt->getName() != ArgList[i].Name)
- return error(ArgList[i].Loc,
- "redefinition of argument '%" + ArgList[i].Name + "'");
+ return error(ArgList[i].Loc,
+ "redefinition of argument '%" + ArgList[i].Name + "'");
}
- if (IsDefine)
+ if (IsDefine)
return false;
// Check the declaration has no block address forward references.
@@ -5869,7 +5869,7 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
}
auto Blocks = ForwardRefBlockAddresses.find(ID);
if (Blocks != ForwardRefBlockAddresses.end())
- return error(Blocks->first.Loc,
+ return error(Blocks->first.Loc,
"cannot take blockaddress inside a declaration");
return false;
}
@@ -5896,11 +5896,11 @@ bool LLParser::PerFunctionState::resolveForwardRefBlockAddresses() {
"Expected local id or name");
BasicBlock *BB;
if (BBID.Kind == ValID::t_LocalName)
- BB = getBB(BBID.StrVal, BBID.Loc);
+ BB = getBB(BBID.StrVal, BBID.Loc);
else
- BB = getBB(BBID.UIntVal, BBID.Loc);
+ BB = getBB(BBID.UIntVal, BBID.Loc);
if (!BB)
- return P.error(BBID.Loc, "referenced value is not a basic block");
+ return P.error(BBID.Loc, "referenced value is not a basic block");
GV->replaceAllUsesWith(BlockAddress::get(&F, BB));
GV->eraseFromParent();
@@ -5910,11 +5910,11 @@ bool LLParser::PerFunctionState::resolveForwardRefBlockAddresses() {
return false;
}
-/// parseFunctionBody
+/// parseFunctionBody
/// ::= '{' BasicBlock+ UseListOrderDirective* '}'
-bool LLParser::parseFunctionBody(Function &Fn) {
+bool LLParser::parseFunctionBody(Function &Fn) {
if (Lex.getKind() != lltok::lbrace)
- return tokError("expected '{' in function body");
+ return tokError("expected '{' in function body");
Lex.Lex(); // eat the {.
int FunctionNumber = -1;
@@ -5930,27 +5930,27 @@ bool LLParser::parseFunctionBody(Function &Fn) {
// We need at least one basic block.
if (Lex.getKind() == lltok::rbrace || Lex.getKind() == lltok::kw_uselistorder)
- return tokError("function body requires at least one basic block");
+ return tokError("function body requires at least one basic block");
while (Lex.getKind() != lltok::rbrace &&
Lex.getKind() != lltok::kw_uselistorder)
- if (parseBasicBlock(PFS))
- return true;
+ if (parseBasicBlock(PFS))
+ return true;
while (Lex.getKind() != lltok::rbrace)
- if (parseUseListOrder(&PFS))
+ if (parseUseListOrder(&PFS))
return true;
// Eat the }.
Lex.Lex();
// Verify function is ok.
- return PFS.finishFunction();
+ return PFS.finishFunction();
}
-/// parseBasicBlock
+/// parseBasicBlock
/// ::= (LabelStr|LabelID)? Instruction*
-bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
+bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
// If this basic block starts out with a name, remember it.
std::string Name;
int NameID = -1;
@@ -5963,13 +5963,13 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
Lex.Lex();
}
- BasicBlock *BB = PFS.defineBB(Name, NameID, NameLoc);
+ BasicBlock *BB = PFS.defineBB(Name, NameID, NameLoc);
if (!BB)
return true;
std::string NameStr;
- // parse the instructions in this block until we get a terminator.
+ // parse the instructions in this block until we get a terminator.
Instruction *Inst;
do {
// This instruction may have three possibilities for a name: a) none
@@ -5981,18 +5981,18 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
if (Lex.getKind() == lltok::LocalVarID) {
NameID = Lex.getUIntVal();
Lex.Lex();
- if (parseToken(lltok::equal, "expected '=' after instruction id"))
+ if (parseToken(lltok::equal, "expected '=' after instruction id"))
return true;
} else if (Lex.getKind() == lltok::LocalVar) {
NameStr = Lex.getStrVal();
Lex.Lex();
- if (parseToken(lltok::equal, "expected '=' after instruction name"))
+ if (parseToken(lltok::equal, "expected '=' after instruction name"))
return true;
}
- switch (parseInstruction(Inst, BB, PFS)) {
- default:
- llvm_unreachable("Unknown parseInstruction result!");
+ switch (parseInstruction(Inst, BB, PFS)) {
+ default:
+ llvm_unreachable("Unknown parseInstruction result!");
case InstError: return true;
case InstNormal:
BB->getInstList().push_back(Inst);
@@ -6000,7 +6000,7 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
// With a normal result, we check to see if the instruction is followed by
// a comma and metadata.
if (EatIfPresent(lltok::comma))
- if (parseInstructionMetadata(*Inst))
+ if (parseInstructionMetadata(*Inst))
return true;
break;
case InstExtraComma:
@@ -6008,14 +6008,14 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
// If the instruction parser ate an extra comma at the end of it, it
// *must* be followed by metadata.
- if (parseInstructionMetadata(*Inst))
+ if (parseInstructionMetadata(*Inst))
return true;
break;
}
// Set the name on the instruction.
- if (PFS.setInstName(NameID, NameStr, NameLoc, Inst))
- return true;
+ if (PFS.setInstName(NameID, NameStr, NameLoc, Inst))
+ return true;
} while (!Inst->isTerminator());
return false;
@@ -6025,50 +6025,50 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
// Instruction Parsing.
//===----------------------------------------------------------------------===//
-/// parseInstruction - parse one of the many different instructions.
+/// parseInstruction - parse one of the many different instructions.
///
-int LLParser::parseInstruction(Instruction *&Inst, BasicBlock *BB,
+int LLParser::parseInstruction(Instruction *&Inst, BasicBlock *BB,
PerFunctionState &PFS) {
lltok::Kind Token = Lex.getKind();
if (Token == lltok::Eof)
- return tokError("found end of file when expecting more instructions");
+ return tokError("found end of file when expecting more instructions");
LocTy Loc = Lex.getLoc();
unsigned KeywordVal = Lex.getUIntVal();
Lex.Lex(); // Eat the keyword.
switch (Token) {
- default:
- return error(Loc, "expected instruction opcode");
+ default:
+ return error(Loc, "expected instruction opcode");
// Terminator Instructions.
case lltok::kw_unreachable: Inst = new UnreachableInst(Context); return false;
- case lltok::kw_ret:
- return parseRet(Inst, BB, PFS);
- case lltok::kw_br:
- return parseBr(Inst, PFS);
- case lltok::kw_switch:
- return parseSwitch(Inst, PFS);
- case lltok::kw_indirectbr:
- return parseIndirectBr(Inst, PFS);
- case lltok::kw_invoke:
- return parseInvoke(Inst, PFS);
- case lltok::kw_resume:
- return parseResume(Inst, PFS);
- case lltok::kw_cleanupret:
- return parseCleanupRet(Inst, PFS);
- case lltok::kw_catchret:
- return parseCatchRet(Inst, PFS);
- case lltok::kw_catchswitch:
- return parseCatchSwitch(Inst, PFS);
- case lltok::kw_catchpad:
- return parseCatchPad(Inst, PFS);
- case lltok::kw_cleanuppad:
- return parseCleanupPad(Inst, PFS);
- case lltok::kw_callbr:
- return parseCallBr(Inst, PFS);
+ case lltok::kw_ret:
+ return parseRet(Inst, BB, PFS);
+ case lltok::kw_br:
+ return parseBr(Inst, PFS);
+ case lltok::kw_switch:
+ return parseSwitch(Inst, PFS);
+ case lltok::kw_indirectbr:
+ return parseIndirectBr(Inst, PFS);
+ case lltok::kw_invoke:
+ return parseInvoke(Inst, PFS);
+ case lltok::kw_resume:
+ return parseResume(Inst, PFS);
+ case lltok::kw_cleanupret:
+ return parseCleanupRet(Inst, PFS);
+ case lltok::kw_catchret:
+ return parseCatchRet(Inst, PFS);
+ case lltok::kw_catchswitch:
+ return parseCatchSwitch(Inst, PFS);
+ case lltok::kw_catchpad:
+ return parseCatchPad(Inst, PFS);
+ case lltok::kw_cleanuppad:
+ return parseCleanupPad(Inst, PFS);
+ case lltok::kw_callbr:
+ return parseCallBr(Inst, PFS);
// Unary Operators.
case lltok::kw_fneg: {
FastMathFlags FMF = EatFastMathFlagsIfPresent();
- int Res = parseUnaryOp(Inst, PFS, KeywordVal, /*IsFP*/ true);
+ int Res = parseUnaryOp(Inst, PFS, KeywordVal, /*IsFP*/ true);
if (Res != 0)
return Res;
if (FMF.any())
@@ -6084,8 +6084,8 @@ int LLParser::parseInstruction(Instruction *&Inst, BasicBlock *BB,
bool NSW = EatIfPresent(lltok::kw_nsw);
if (!NUW) NUW = EatIfPresent(lltok::kw_nuw);
- if (parseArithmetic(Inst, PFS, KeywordVal, /*IsFP*/ false))
- return true;
+ if (parseArithmetic(Inst, PFS, KeywordVal, /*IsFP*/ false))
+ return true;
if (NUW) cast<BinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
if (NSW) cast<BinaryOperator>(Inst)->setHasNoSignedWrap(true);
@@ -6097,7 +6097,7 @@ int LLParser::parseInstruction(Instruction *&Inst, BasicBlock *BB,
case lltok::kw_fdiv:
case lltok::kw_frem: {
FastMathFlags FMF = EatFastMathFlagsIfPresent();
- int Res = parseArithmetic(Inst, PFS, KeywordVal, /*IsFP*/ true);
+ int Res = parseArithmetic(Inst, PFS, KeywordVal, /*IsFP*/ true);
if (Res != 0)
return Res;
if (FMF.any())
@@ -6111,25 +6111,25 @@ int LLParser::parseInstruction(Instruction *&Inst, BasicBlock *BB,
case lltok::kw_ashr: {
bool Exact = EatIfPresent(lltok::kw_exact);
- if (parseArithmetic(Inst, PFS, KeywordVal, /*IsFP*/ false))
- return true;
+ if (parseArithmetic(Inst, PFS, KeywordVal, /*IsFP*/ false))
+ return true;
if (Exact) cast<BinaryOperator>(Inst)->setIsExact(true);
return false;
}
case lltok::kw_urem:
- case lltok::kw_srem:
- return parseArithmetic(Inst, PFS, KeywordVal,
- /*IsFP*/ false);
+ case lltok::kw_srem:
+ return parseArithmetic(Inst, PFS, KeywordVal,
+ /*IsFP*/ false);
case lltok::kw_and:
case lltok::kw_or:
- case lltok::kw_xor:
- return parseLogical(Inst, PFS, KeywordVal);
- case lltok::kw_icmp:
- return parseCompare(Inst, PFS, KeywordVal);
+ case lltok::kw_xor:
+ return parseLogical(Inst, PFS, KeywordVal);
+ case lltok::kw_icmp:
+ return parseCompare(Inst, PFS, KeywordVal);
case lltok::kw_fcmp: {
FastMathFlags FMF = EatFastMathFlagsIfPresent();
- int Res = parseCompare(Inst, PFS, KeywordVal);
+ int Res = parseCompare(Inst, PFS, KeywordVal);
if (Res != 0)
return Res;
if (FMF.any())
@@ -6150,84 +6150,84 @@ int LLParser::parseInstruction(Instruction *&Inst, BasicBlock *BB,
case lltok::kw_fptoui:
case lltok::kw_fptosi:
case lltok::kw_inttoptr:
- case lltok::kw_ptrtoint:
- return parseCast(Inst, PFS, KeywordVal);
+ case lltok::kw_ptrtoint:
+ return parseCast(Inst, PFS, KeywordVal);
// Other.
case lltok::kw_select: {
FastMathFlags FMF = EatFastMathFlagsIfPresent();
- int Res = parseSelect(Inst, PFS);
+ int Res = parseSelect(Inst, PFS);
if (Res != 0)
return Res;
if (FMF.any()) {
if (!isa<FPMathOperator>(Inst))
- return error(Loc, "fast-math-flags specified for select without "
+ return error(Loc, "fast-math-flags specified for select without "
"floating-point scalar or vector return type");
Inst->setFastMathFlags(FMF);
}
return 0;
}
- case lltok::kw_va_arg:
- return parseVAArg(Inst, PFS);
- case lltok::kw_extractelement:
- return parseExtractElement(Inst, PFS);
- case lltok::kw_insertelement:
- return parseInsertElement(Inst, PFS);
- case lltok::kw_shufflevector:
- return parseShuffleVector(Inst, PFS);
+ case lltok::kw_va_arg:
+ return parseVAArg(Inst, PFS);
+ case lltok::kw_extractelement:
+ return parseExtractElement(Inst, PFS);
+ case lltok::kw_insertelement:
+ return parseInsertElement(Inst, PFS);
+ case lltok::kw_shufflevector:
+ return parseShuffleVector(Inst, PFS);
case lltok::kw_phi: {
FastMathFlags FMF = EatFastMathFlagsIfPresent();
- int Res = parsePHI(Inst, PFS);
+ int Res = parsePHI(Inst, PFS);
if (Res != 0)
return Res;
if (FMF.any()) {
if (!isa<FPMathOperator>(Inst))
- return error(Loc, "fast-math-flags specified for phi without "
+ return error(Loc, "fast-math-flags specified for phi without "
"floating-point scalar or vector return type");
Inst->setFastMathFlags(FMF);
}
return 0;
}
- case lltok::kw_landingpad:
- return parseLandingPad(Inst, PFS);
- case lltok::kw_freeze:
- return parseFreeze(Inst, PFS);
+ case lltok::kw_landingpad:
+ return parseLandingPad(Inst, PFS);
+ case lltok::kw_freeze:
+ return parseFreeze(Inst, PFS);
// Call.
- case lltok::kw_call:
- return parseCall(Inst, PFS, CallInst::TCK_None);
- case lltok::kw_tail:
- return parseCall(Inst, PFS, CallInst::TCK_Tail);
- case lltok::kw_musttail:
- return parseCall(Inst, PFS, CallInst::TCK_MustTail);
- case lltok::kw_notail:
- return parseCall(Inst, PFS, CallInst::TCK_NoTail);
+ case lltok::kw_call:
+ return parseCall(Inst, PFS, CallInst::TCK_None);
+ case lltok::kw_tail:
+ return parseCall(Inst, PFS, CallInst::TCK_Tail);
+ case lltok::kw_musttail:
+ return parseCall(Inst, PFS, CallInst::TCK_MustTail);
+ case lltok::kw_notail:
+ return parseCall(Inst, PFS, CallInst::TCK_NoTail);
// Memory.
- case lltok::kw_alloca:
- return parseAlloc(Inst, PFS);
- case lltok::kw_load:
- return parseLoad(Inst, PFS);
- case lltok::kw_store:
- return parseStore(Inst, PFS);
- case lltok::kw_cmpxchg:
- return parseCmpXchg(Inst, PFS);
- case lltok::kw_atomicrmw:
- return parseAtomicRMW(Inst, PFS);
- case lltok::kw_fence:
- return parseFence(Inst, PFS);
- case lltok::kw_getelementptr:
- return parseGetElementPtr(Inst, PFS);
- case lltok::kw_extractvalue:
- return parseExtractValue(Inst, PFS);
- case lltok::kw_insertvalue:
- return parseInsertValue(Inst, PFS);
- }
-}
-
-/// parseCmpPredicate - parse an integer or fp predicate, based on Kind.
-bool LLParser::parseCmpPredicate(unsigned &P, unsigned Opc) {
+ case lltok::kw_alloca:
+ return parseAlloc(Inst, PFS);
+ case lltok::kw_load:
+ return parseLoad(Inst, PFS);
+ case lltok::kw_store:
+ return parseStore(Inst, PFS);
+ case lltok::kw_cmpxchg:
+ return parseCmpXchg(Inst, PFS);
+ case lltok::kw_atomicrmw:
+ return parseAtomicRMW(Inst, PFS);
+ case lltok::kw_fence:
+ return parseFence(Inst, PFS);
+ case lltok::kw_getelementptr:
+ return parseGetElementPtr(Inst, PFS);
+ case lltok::kw_extractvalue:
+ return parseExtractValue(Inst, PFS);
+ case lltok::kw_insertvalue:
+ return parseInsertValue(Inst, PFS);
+ }
+}
+
+/// parseCmpPredicate - parse an integer or fp predicate, based on Kind.
+bool LLParser::parseCmpPredicate(unsigned &P, unsigned Opc) {
if (Opc == Instruction::FCmp) {
switch (Lex.getKind()) {
- default:
- return tokError("expected fcmp predicate (e.g. 'oeq')");
+ default:
+ return tokError("expected fcmp predicate (e.g. 'oeq')");
case lltok::kw_oeq: P = CmpInst::FCMP_OEQ; break;
case lltok::kw_one: P = CmpInst::FCMP_ONE; break;
case lltok::kw_olt: P = CmpInst::FCMP_OLT; break;
@@ -6247,8 +6247,8 @@ bool LLParser::parseCmpPredicate(unsigned &P, unsigned Opc) {
}
} else {
switch (Lex.getKind()) {
- default:
- return tokError("expected icmp predicate (e.g. 'eq')");
+ default:
+ return tokError("expected icmp predicate (e.g. 'eq')");
case lltok::kw_eq: P = CmpInst::ICMP_EQ; break;
case lltok::kw_ne: P = CmpInst::ICMP_NE; break;
case lltok::kw_slt: P = CmpInst::ICMP_SLT; break;
@@ -6269,48 +6269,48 @@ bool LLParser::parseCmpPredicate(unsigned &P, unsigned Opc) {
// Terminator Instructions.
//===----------------------------------------------------------------------===//
-/// parseRet - parse a return instruction.
+/// parseRet - parse a return instruction.
/// ::= 'ret' void (',' !dbg, !1)*
/// ::= 'ret' TypeAndValue (',' !dbg, !1)*
-bool LLParser::parseRet(Instruction *&Inst, BasicBlock *BB,
+bool LLParser::parseRet(Instruction *&Inst, BasicBlock *BB,
PerFunctionState &PFS) {
SMLoc TypeLoc = Lex.getLoc();
Type *Ty = nullptr;
- if (parseType(Ty, true /*void allowed*/))
- return true;
+ if (parseType(Ty, true /*void allowed*/))
+ return true;
Type *ResType = PFS.getFunction().getReturnType();
if (Ty->isVoidTy()) {
if (!ResType->isVoidTy())
- return error(TypeLoc, "value doesn't match function result type '" +
- getTypeString(ResType) + "'");
+ return error(TypeLoc, "value doesn't match function result type '" +
+ getTypeString(ResType) + "'");
Inst = ReturnInst::Create(Context);
return false;
}
Value *RV;
- if (parseValue(Ty, RV, PFS))
- return true;
+ if (parseValue(Ty, RV, PFS))
+ return true;
if (ResType != RV->getType())
- return error(TypeLoc, "value doesn't match function result type '" +
- getTypeString(ResType) + "'");
+ return error(TypeLoc, "value doesn't match function result type '" +
+ getTypeString(ResType) + "'");
Inst = ReturnInst::Create(Context, RV);
return false;
}
-/// parseBr
+/// parseBr
/// ::= 'br' TypeAndValue
/// ::= 'br' TypeAndValue ',' TypeAndValue ',' TypeAndValue
-bool LLParser::parseBr(Instruction *&Inst, PerFunctionState &PFS) {
+bool LLParser::parseBr(Instruction *&Inst, PerFunctionState &PFS) {
LocTy Loc, Loc2;
Value *Op0;
BasicBlock *Op1, *Op2;
- if (parseTypeAndValue(Op0, Loc, PFS))
- return true;
+ if (parseTypeAndValue(Op0, Loc, PFS))
+ return true;
if (BasicBlock *BB = dyn_cast<BasicBlock>(Op0)) {
Inst = BranchInst::Create(BB);
@@ -6318,52 +6318,52 @@ bool LLParser::parseBr(Instruction *&Inst, PerFunctionState &PFS) {
}
if (Op0->getType() != Type::getInt1Ty(Context))
- return error(Loc, "branch condition must have 'i1' type");
+ return error(Loc, "branch condition must have 'i1' type");
- if (parseToken(lltok::comma, "expected ',' after branch condition") ||
- parseTypeAndBasicBlock(Op1, Loc, PFS) ||
- parseToken(lltok::comma, "expected ',' after true destination") ||
- parseTypeAndBasicBlock(Op2, Loc2, PFS))
+ if (parseToken(lltok::comma, "expected ',' after branch condition") ||
+ parseTypeAndBasicBlock(Op1, Loc, PFS) ||
+ parseToken(lltok::comma, "expected ',' after true destination") ||
+ parseTypeAndBasicBlock(Op2, Loc2, PFS))
return true;
Inst = BranchInst::Create(Op1, Op2, Op0);
return false;
}
-/// parseSwitch
+/// parseSwitch
/// Instruction
/// ::= 'switch' TypeAndValue ',' TypeAndValue '[' JumpTable ']'
/// JumpTable
/// ::= (TypeAndValue ',' TypeAndValue)*
-bool LLParser::parseSwitch(Instruction *&Inst, PerFunctionState &PFS) {
+bool LLParser::parseSwitch(Instruction *&Inst, PerFunctionState &PFS) {
LocTy CondLoc, BBLoc;
Value *Cond;
BasicBlock *DefaultBB;
- if (parseTypeAndValue(Cond, CondLoc, PFS) ||
- parseToken(lltok::comma, "expected ',' after switch condition") ||
- parseTypeAndBasicBlock(DefaultBB, BBLoc, PFS) ||
- parseToken(lltok::lsquare, "expected '[' with switch table"))
+ if (parseTypeAndValue(Cond, CondLoc, PFS) ||
+ parseToken(lltok::comma, "expected ',' after switch condition") ||
+ parseTypeAndBasicBlock(DefaultBB, BBLoc, PFS) ||
+ parseToken(lltok::lsquare, "expected '[' with switch table"))
return true;
if (!Cond->getType()->isIntegerTy())
- return error(CondLoc, "switch condition must have integer type");
+ return error(CondLoc, "switch condition must have integer type");
- // parse the jump table pairs.
+ // parse the jump table pairs.
SmallPtrSet<Value*, 32> SeenCases;
SmallVector<std::pair<ConstantInt*, BasicBlock*>, 32> Table;
while (Lex.getKind() != lltok::rsquare) {
Value *Constant;
BasicBlock *DestBB;
- if (parseTypeAndValue(Constant, CondLoc, PFS) ||
- parseToken(lltok::comma, "expected ',' after case value") ||
- parseTypeAndBasicBlock(DestBB, PFS))
+ if (parseTypeAndValue(Constant, CondLoc, PFS) ||
+ parseToken(lltok::comma, "expected ',' after case value") ||
+ parseTypeAndBasicBlock(DestBB, PFS))
return true;
if (!SeenCases.insert(Constant).second)
- return error(CondLoc, "duplicate case value in switch");
+ return error(CondLoc, "duplicate case value in switch");
if (!isa<ConstantInt>(Constant))
- return error(CondLoc, "case value is not a constant integer");
+ return error(CondLoc, "case value is not a constant integer");
Table.push_back(std::make_pair(cast<ConstantInt>(Constant), DestBB));
}
@@ -6377,37 +6377,37 @@ bool LLParser::parseSwitch(Instruction *&Inst, PerFunctionState &PFS) {
return false;
}
-/// parseIndirectBr
+/// parseIndirectBr
/// Instruction
/// ::= 'indirectbr' TypeAndValue ',' '[' LabelList ']'
-bool LLParser::parseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) {
+bool LLParser::parseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) {
LocTy AddrLoc;
Value *Address;
- if (parseTypeAndValue(Address, AddrLoc, PFS) ||
- parseToken(lltok::comma, "expected ',' after indirectbr address") ||
- parseToken(lltok::lsquare, "expected '[' with indirectbr"))
+ if (parseTypeAndValue(Address, AddrLoc, PFS) ||
+ parseToken(lltok::comma, "expected ',' after indirectbr address") ||
+ parseToken(lltok::lsquare, "expected '[' with indirectbr"))
return true;
if (!Address->getType()->isPointerTy())
- return error(AddrLoc, "indirectbr address must have pointer type");
+ return error(AddrLoc, "indirectbr address must have pointer type");
- // parse the destination list.
+ // parse the destination list.
SmallVector<BasicBlock*, 16> DestList;
if (Lex.getKind() != lltok::rsquare) {
BasicBlock *DestBB;
- if (parseTypeAndBasicBlock(DestBB, PFS))
+ if (parseTypeAndBasicBlock(DestBB, PFS))
return true;
DestList.push_back(DestBB);
while (EatIfPresent(lltok::comma)) {
- if (parseTypeAndBasicBlock(DestBB, PFS))
+ if (parseTypeAndBasicBlock(DestBB, PFS))
return true;
DestList.push_back(DestBB);
}
}
- if (parseToken(lltok::rsquare, "expected ']' at end of block list"))
+ if (parseToken(lltok::rsquare, "expected ']' at end of block list"))
return true;
IndirectBrInst *IBI = IndirectBrInst::Create(Address, DestList.size());
@@ -6417,10 +6417,10 @@ bool LLParser::parseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) {
return false;
}
-/// parseInvoke
+/// parseInvoke
/// ::= 'invoke' OptionalCallingConv OptionalAttrs Type Value ParamList
/// OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue
-bool LLParser::parseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
+bool LLParser::parseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
LocTy CallLoc = Lex.getLoc();
AttrBuilder RetAttrs, FnAttrs;
std::vector<unsigned> FwdRefAttrGrps;
@@ -6434,17 +6434,17 @@ bool LLParser::parseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
SmallVector<OperandBundleDef, 2> BundleList;
BasicBlock *NormalBB, *UnwindBB;
- if (parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(RetAttrs) ||
- parseOptionalProgramAddrSpace(InvokeAddrSpace) ||
- parseType(RetType, RetTypeLoc, true /*void allowed*/) ||
- parseValID(CalleeID) || parseParameterList(ArgList, PFS) ||
- parseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false,
+ if (parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(RetAttrs) ||
+ parseOptionalProgramAddrSpace(InvokeAddrSpace) ||
+ parseType(RetType, RetTypeLoc, true /*void allowed*/) ||
+ parseValID(CalleeID) || parseParameterList(ArgList, PFS) ||
+ parseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false,
NoBuiltinLoc) ||
- parseOptionalOperandBundles(BundleList, PFS) ||
- parseToken(lltok::kw_to, "expected 'to' in invoke") ||
- parseTypeAndBasicBlock(NormalBB, PFS) ||
- parseToken(lltok::kw_unwind, "expected 'unwind' in invoke") ||
- parseTypeAndBasicBlock(UnwindBB, PFS))
+ parseOptionalOperandBundles(BundleList, PFS) ||
+ parseToken(lltok::kw_to, "expected 'to' in invoke") ||
+ parseTypeAndBasicBlock(NormalBB, PFS) ||
+ parseToken(lltok::kw_unwind, "expected 'unwind' in invoke") ||
+ parseTypeAndBasicBlock(UnwindBB, PFS))
return true;
// If RetType is a non-function pointer type, then this is the short syntax
@@ -6458,7 +6458,7 @@ bool LLParser::parseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
ParamTypes.push_back(ArgList[i].V->getType());
if (!FunctionType::isValidReturnType(RetType))
- return error(RetTypeLoc, "Invalid result type for LLVM function");
+ return error(RetTypeLoc, "Invalid result type for LLVM function");
Ty = FunctionType::get(RetType, ParamTypes, false);
}
@@ -6467,7 +6467,7 @@ bool LLParser::parseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
// Look up the callee.
Value *Callee;
- if (convertValIDToValue(PointerType::get(Ty, InvokeAddrSpace), CalleeID,
+ if (convertValIDToValue(PointerType::get(Ty, InvokeAddrSpace), CalleeID,
Callee, &PFS, /*IsCall=*/true))
return true;
@@ -6484,21 +6484,21 @@ bool LLParser::parseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
if (I != E) {
ExpectedTy = *I++;
} else if (!Ty->isVarArg()) {
- return error(ArgList[i].Loc, "too many arguments specified");
+ return error(ArgList[i].Loc, "too many arguments specified");
}
if (ExpectedTy && ExpectedTy != ArgList[i].V->getType())
- return error(ArgList[i].Loc, "argument is not of expected type '" +
- getTypeString(ExpectedTy) + "'");
+ return error(ArgList[i].Loc, "argument is not of expected type '" +
+ getTypeString(ExpectedTy) + "'");
Args.push_back(ArgList[i].V);
ArgAttrs.push_back(ArgList[i].Attrs);
}
if (I != E)
- return error(CallLoc, "not enough parameters specified for call");
+ return error(CallLoc, "not enough parameters specified for call");
if (FnAttrs.hasAlignmentAttr())
- return error(CallLoc, "invoke instructions may not have an alignment");
+ return error(CallLoc, "invoke instructions may not have an alignment");
// Finish off the Attribute and check them
AttributeList PAL =
@@ -6514,11 +6514,11 @@ bool LLParser::parseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
return false;
}
-/// parseResume
+/// parseResume
/// ::= 'resume' TypeAndValue
-bool LLParser::parseResume(Instruction *&Inst, PerFunctionState &PFS) {
+bool LLParser::parseResume(Instruction *&Inst, PerFunctionState &PFS) {
Value *Exn; LocTy ExnLoc;
- if (parseTypeAndValue(Exn, ExnLoc, PFS))
+ if (parseTypeAndValue(Exn, ExnLoc, PFS))
return true;
ResumeInst *RI = ResumeInst::Create(Exn);
@@ -6526,29 +6526,29 @@ bool LLParser::parseResume(Instruction *&Inst, PerFunctionState &PFS) {
return false;
}
-bool LLParser::parseExceptionArgs(SmallVectorImpl<Value *> &Args,
+bool LLParser::parseExceptionArgs(SmallVectorImpl<Value *> &Args,
PerFunctionState &PFS) {
- if (parseToken(lltok::lsquare, "expected '[' in catchpad/cleanuppad"))
+ if (parseToken(lltok::lsquare, "expected '[' in catchpad/cleanuppad"))
return true;
while (Lex.getKind() != lltok::rsquare) {
// If this isn't the first argument, we need a comma.
if (!Args.empty() &&
- parseToken(lltok::comma, "expected ',' in argument list"))
+ parseToken(lltok::comma, "expected ',' in argument list"))
return true;
- // parse the argument.
+ // parse the argument.
LocTy ArgLoc;
Type *ArgTy = nullptr;
- if (parseType(ArgTy, ArgLoc))
+ if (parseType(ArgTy, ArgLoc))
return true;
Value *V;
if (ArgTy->isMetadataTy()) {
- if (parseMetadataAsValue(V, PFS))
+ if (parseMetadataAsValue(V, PFS))
return true;
} else {
- if (parseValue(ArgTy, V, PFS))
+ if (parseValue(ArgTy, V, PFS))
return true;
}
Args.push_back(V);
@@ -6558,27 +6558,27 @@ bool LLParser::parseExceptionArgs(SmallVectorImpl<Value *> &Args,
return false;
}
-/// parseCleanupRet
+/// parseCleanupRet
/// ::= 'cleanupret' from Value unwind ('to' 'caller' | TypeAndValue)
-bool LLParser::parseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) {
+bool LLParser::parseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) {
Value *CleanupPad = nullptr;
- if (parseToken(lltok::kw_from, "expected 'from' after cleanupret"))
+ if (parseToken(lltok::kw_from, "expected 'from' after cleanupret"))
return true;
- if (parseValue(Type::getTokenTy(Context), CleanupPad, PFS))
+ if (parseValue(Type::getTokenTy(Context), CleanupPad, PFS))
return true;
- if (parseToken(lltok::kw_unwind, "expected 'unwind' in cleanupret"))
+ if (parseToken(lltok::kw_unwind, "expected 'unwind' in cleanupret"))
return true;
BasicBlock *UnwindBB = nullptr;
if (Lex.getKind() == lltok::kw_to) {
Lex.Lex();
- if (parseToken(lltok::kw_caller, "expected 'caller' in cleanupret"))
+ if (parseToken(lltok::kw_caller, "expected 'caller' in cleanupret"))
return true;
} else {
- if (parseTypeAndBasicBlock(UnwindBB, PFS)) {
+ if (parseTypeAndBasicBlock(UnwindBB, PFS)) {
return true;
}
}
@@ -6587,64 +6587,64 @@ bool LLParser::parseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) {
return false;
}
-/// parseCatchRet
+/// parseCatchRet
/// ::= 'catchret' from Parent Value 'to' TypeAndValue
-bool LLParser::parseCatchRet(Instruction *&Inst, PerFunctionState &PFS) {
+bool LLParser::parseCatchRet(Instruction *&Inst, PerFunctionState &PFS) {
Value *CatchPad = nullptr;
- if (parseToken(lltok::kw_from, "expected 'from' after catchret"))
+ if (parseToken(lltok::kw_from, "expected 'from' after catchret"))
return true;
- if (parseValue(Type::getTokenTy(Context), CatchPad, PFS))
+ if (parseValue(Type::getTokenTy(Context), CatchPad, PFS))
return true;
BasicBlock *BB;
- if (parseToken(lltok::kw_to, "expected 'to' in catchret") ||
- parseTypeAndBasicBlock(BB, PFS))
- return true;
+ if (parseToken(lltok::kw_to, "expected 'to' in catchret") ||
+ parseTypeAndBasicBlock(BB, PFS))
+ return true;
Inst = CatchReturnInst::Create(CatchPad, BB);
return false;
}
-/// parseCatchSwitch
+/// parseCatchSwitch
/// ::= 'catchswitch' within Parent
-bool LLParser::parseCatchSwitch(Instruction *&Inst, PerFunctionState &PFS) {
+bool LLParser::parseCatchSwitch(Instruction *&Inst, PerFunctionState &PFS) {
Value *ParentPad;
- if (parseToken(lltok::kw_within, "expected 'within' after catchswitch"))
+ if (parseToken(lltok::kw_within, "expected 'within' after catchswitch"))
return true;
if (Lex.getKind() != lltok::kw_none && Lex.getKind() != lltok::LocalVar &&
Lex.getKind() != lltok::LocalVarID)
- return tokError("expected scope value for catchswitch");
+ return tokError("expected scope value for catchswitch");
- if (parseValue(Type::getTokenTy(Context), ParentPad, PFS))
+ if (parseValue(Type::getTokenTy(Context), ParentPad, PFS))
return true;
- if (parseToken(lltok::lsquare, "expected '[' with catchswitch labels"))
+ if (parseToken(lltok::lsquare, "expected '[' with catchswitch labels"))
return true;
SmallVector<BasicBlock *, 32> Table;
do {
BasicBlock *DestBB;
- if (parseTypeAndBasicBlock(DestBB, PFS))
+ if (parseTypeAndBasicBlock(DestBB, PFS))
return true;
Table.push_back(DestBB);
} while (EatIfPresent(lltok::comma));
- if (parseToken(lltok::rsquare, "expected ']' after catchswitch labels"))
+ if (parseToken(lltok::rsquare, "expected ']' after catchswitch labels"))
return true;
- if (parseToken(lltok::kw_unwind, "expected 'unwind' after catchswitch scope"))
+ if (parseToken(lltok::kw_unwind, "expected 'unwind' after catchswitch scope"))
return true;
BasicBlock *UnwindBB = nullptr;
if (EatIfPresent(lltok::kw_to)) {
- if (parseToken(lltok::kw_caller, "expected 'caller' in catchswitch"))
+ if (parseToken(lltok::kw_caller, "expected 'caller' in catchswitch"))
return true;
} else {
- if (parseTypeAndBasicBlock(UnwindBB, PFS))
+ if (parseTypeAndBasicBlock(UnwindBB, PFS))
return true;
}
@@ -6656,45 +6656,45 @@ bool LLParser::parseCatchSwitch(Instruction *&Inst, PerFunctionState &PFS) {
return false;
}
-/// parseCatchPad
+/// parseCatchPad
/// ::= 'catchpad' ParamList 'to' TypeAndValue 'unwind' TypeAndValue
-bool LLParser::parseCatchPad(Instruction *&Inst, PerFunctionState &PFS) {
+bool LLParser::parseCatchPad(Instruction *&Inst, PerFunctionState &PFS) {
Value *CatchSwitch = nullptr;
- if (parseToken(lltok::kw_within, "expected 'within' after catchpad"))
+ if (parseToken(lltok::kw_within, "expected 'within' after catchpad"))
return true;
if (Lex.getKind() != lltok::LocalVar && Lex.getKind() != lltok::LocalVarID)
- return tokError("expected scope value for catchpad");
+ return tokError("expected scope value for catchpad");
- if (parseValue(Type::getTokenTy(Context), CatchSwitch, PFS))
+ if (parseValue(Type::getTokenTy(Context), CatchSwitch, PFS))
return true;
SmallVector<Value *, 8> Args;
- if (parseExceptionArgs(Args, PFS))
+ if (parseExceptionArgs(Args, PFS))
return true;
Inst = CatchPadInst::Create(CatchSwitch, Args);
return false;
}
-/// parseCleanupPad
+/// parseCleanupPad
/// ::= 'cleanuppad' within Parent ParamList
-bool LLParser::parseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) {
+bool LLParser::parseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) {
Value *ParentPad = nullptr;
- if (parseToken(lltok::kw_within, "expected 'within' after cleanuppad"))
+ if (parseToken(lltok::kw_within, "expected 'within' after cleanuppad"))
return true;
if (Lex.getKind() != lltok::kw_none && Lex.getKind() != lltok::LocalVar &&
Lex.getKind() != lltok::LocalVarID)
- return tokError("expected scope value for cleanuppad");
+ return tokError("expected scope value for cleanuppad");
- if (parseValue(Type::getTokenTy(Context), ParentPad, PFS))
+ if (parseValue(Type::getTokenTy(Context), ParentPad, PFS))
return true;
SmallVector<Value *, 8> Args;
- if (parseExceptionArgs(Args, PFS))
+ if (parseExceptionArgs(Args, PFS))
return true;
Inst = CleanupPadInst::Create(ParentPad, Args);
@@ -6705,32 +6705,32 @@ bool LLParser::parseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) {
// Unary Operators.
//===----------------------------------------------------------------------===//
-/// parseUnaryOp
+/// parseUnaryOp
/// ::= UnaryOp TypeAndValue ',' Value
///
/// If IsFP is false, then any integer operand is allowed, if it is true, any fp
/// operand is allowed.
-bool LLParser::parseUnaryOp(Instruction *&Inst, PerFunctionState &PFS,
+bool LLParser::parseUnaryOp(Instruction *&Inst, PerFunctionState &PFS,
unsigned Opc, bool IsFP) {
LocTy Loc; Value *LHS;
- if (parseTypeAndValue(LHS, Loc, PFS))
+ if (parseTypeAndValue(LHS, Loc, PFS))
return true;
bool Valid = IsFP ? LHS->getType()->isFPOrFPVectorTy()
: LHS->getType()->isIntOrIntVectorTy();
if (!Valid)
- return error(Loc, "invalid operand type for instruction");
+ return error(Loc, "invalid operand type for instruction");
Inst = UnaryOperator::Create((Instruction::UnaryOps)Opc, LHS);
return false;
}
-/// parseCallBr
+/// parseCallBr
/// ::= 'callbr' OptionalCallingConv OptionalAttrs Type Value ParamList
/// OptionalAttrs OptionalOperandBundles 'to' TypeAndValue
/// '[' LabelList ']'
-bool LLParser::parseCallBr(Instruction *&Inst, PerFunctionState &PFS) {
+bool LLParser::parseCallBr(Instruction *&Inst, PerFunctionState &PFS) {
LocTy CallLoc = Lex.getLoc();
AttrBuilder RetAttrs, FnAttrs;
std::vector<unsigned> FwdRefAttrGrps;
@@ -6743,34 +6743,34 @@ bool LLParser::parseCallBr(Instruction *&Inst, PerFunctionState &PFS) {
SmallVector<OperandBundleDef, 2> BundleList;
BasicBlock *DefaultDest;
- if (parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(RetAttrs) ||
- parseType(RetType, RetTypeLoc, true /*void allowed*/) ||
- parseValID(CalleeID) || parseParameterList(ArgList, PFS) ||
- parseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false,
+ if (parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(RetAttrs) ||
+ parseType(RetType, RetTypeLoc, true /*void allowed*/) ||
+ parseValID(CalleeID) || parseParameterList(ArgList, PFS) ||
+ parseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false,
NoBuiltinLoc) ||
- parseOptionalOperandBundles(BundleList, PFS) ||
- parseToken(lltok::kw_to, "expected 'to' in callbr") ||
- parseTypeAndBasicBlock(DefaultDest, PFS) ||
- parseToken(lltok::lsquare, "expected '[' in callbr"))
+ parseOptionalOperandBundles(BundleList, PFS) ||
+ parseToken(lltok::kw_to, "expected 'to' in callbr") ||
+ parseTypeAndBasicBlock(DefaultDest, PFS) ||
+ parseToken(lltok::lsquare, "expected '[' in callbr"))
return true;
- // parse the destination list.
+ // parse the destination list.
SmallVector<BasicBlock *, 16> IndirectDests;
if (Lex.getKind() != lltok::rsquare) {
BasicBlock *DestBB;
- if (parseTypeAndBasicBlock(DestBB, PFS))
+ if (parseTypeAndBasicBlock(DestBB, PFS))
return true;
IndirectDests.push_back(DestBB);
while (EatIfPresent(lltok::comma)) {
- if (parseTypeAndBasicBlock(DestBB, PFS))
+ if (parseTypeAndBasicBlock(DestBB, PFS))
return true;
IndirectDests.push_back(DestBB);
}
}
- if (parseToken(lltok::rsquare, "expected ']' at end of block list"))
+ if (parseToken(lltok::rsquare, "expected ']' at end of block list"))
return true;
// If RetType is a non-function pointer type, then this is the short syntax
@@ -6784,7 +6784,7 @@ bool LLParser::parseCallBr(Instruction *&Inst, PerFunctionState &PFS) {
ParamTypes.push_back(ArgList[i].V->getType());
if (!FunctionType::isValidReturnType(RetType))
- return error(RetTypeLoc, "Invalid result type for LLVM function");
+ return error(RetTypeLoc, "Invalid result type for LLVM function");
Ty = FunctionType::get(RetType, ParamTypes, false);
}
@@ -6793,7 +6793,7 @@ bool LLParser::parseCallBr(Instruction *&Inst, PerFunctionState &PFS) {
// Look up the callee.
Value *Callee;
- if (convertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS,
+ if (convertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS,
/*IsCall=*/true))
return true;
@@ -6810,21 +6810,21 @@ bool LLParser::parseCallBr(Instruction *&Inst, PerFunctionState &PFS) {
if (I != E) {
ExpectedTy = *I++;
} else if (!Ty->isVarArg()) {
- return error(ArgList[i].Loc, "too many arguments specified");
+ return error(ArgList[i].Loc, "too many arguments specified");
}
if (ExpectedTy && ExpectedTy != ArgList[i].V->getType())
- return error(ArgList[i].Loc, "argument is not of expected type '" +
+ return error(ArgList[i].Loc, "argument is not of expected type '" +
getTypeString(ExpectedTy) + "'");
Args.push_back(ArgList[i].V);
ArgAttrs.push_back(ArgList[i].Attrs);
}
if (I != E)
- return error(CallLoc, "not enough parameters specified for call");
+ return error(CallLoc, "not enough parameters specified for call");
if (FnAttrs.hasAlignmentAttr())
- return error(CallLoc, "callbr instructions may not have an alignment");
+ return error(CallLoc, "callbr instructions may not have an alignment");
// Finish off the Attribute and check them
AttributeList PAL =
@@ -6845,70 +6845,70 @@ bool LLParser::parseCallBr(Instruction *&Inst, PerFunctionState &PFS) {
// Binary Operators.
//===----------------------------------------------------------------------===//
-/// parseArithmetic
+/// parseArithmetic
/// ::= ArithmeticOps TypeAndValue ',' Value
///
/// If IsFP is false, then any integer operand is allowed, if it is true, any fp
/// operand is allowed.
-bool LLParser::parseArithmetic(Instruction *&Inst, PerFunctionState &PFS,
+bool LLParser::parseArithmetic(Instruction *&Inst, PerFunctionState &PFS,
unsigned Opc, bool IsFP) {
LocTy Loc; Value *LHS, *RHS;
- if (parseTypeAndValue(LHS, Loc, PFS) ||
- parseToken(lltok::comma, "expected ',' in arithmetic operation") ||
- parseValue(LHS->getType(), RHS, PFS))
+ if (parseTypeAndValue(LHS, Loc, PFS) ||
+ parseToken(lltok::comma, "expected ',' in arithmetic operation") ||
+ parseValue(LHS->getType(), RHS, PFS))
return true;
bool Valid = IsFP ? LHS->getType()->isFPOrFPVectorTy()
: LHS->getType()->isIntOrIntVectorTy();
if (!Valid)
- return error(Loc, "invalid operand type for instruction");
+ return error(Loc, "invalid operand type for instruction");
Inst = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
return false;
}
-/// parseLogical
+/// parseLogical
/// ::= ArithmeticOps TypeAndValue ',' Value {
-bool LLParser::parseLogical(Instruction *&Inst, PerFunctionState &PFS,
+bool LLParser::parseLogical(Instruction *&Inst, PerFunctionState &PFS,
unsigned Opc) {
LocTy Loc; Value *LHS, *RHS;
- if (parseTypeAndValue(LHS, Loc, PFS) ||
- parseToken(lltok::comma, "expected ',' in logical operation") ||
- parseValue(LHS->getType(), RHS, PFS))
+ if (parseTypeAndValue(LHS, Loc, PFS) ||
+ parseToken(lltok::comma, "expected ',' in logical operation") ||
+ parseValue(LHS->getType(), RHS, PFS))
return true;
if (!LHS->getType()->isIntOrIntVectorTy())
- return error(Loc,
- "instruction requires integer or integer vector operands");
+ return error(Loc,
+ "instruction requires integer or integer vector operands");
Inst = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
return false;
}
-/// parseCompare
+/// parseCompare
/// ::= 'icmp' IPredicates TypeAndValue ',' Value
/// ::= 'fcmp' FPredicates TypeAndValue ',' Value
-bool LLParser::parseCompare(Instruction *&Inst, PerFunctionState &PFS,
+bool LLParser::parseCompare(Instruction *&Inst, PerFunctionState &PFS,
unsigned Opc) {
- // parse the integer/fp comparison predicate.
+ // parse the integer/fp comparison predicate.
LocTy Loc;
unsigned Pred;
Value *LHS, *RHS;
- if (parseCmpPredicate(Pred, Opc) || parseTypeAndValue(LHS, Loc, PFS) ||
- parseToken(lltok::comma, "expected ',' after compare value") ||
- parseValue(LHS->getType(), RHS, PFS))
+ if (parseCmpPredicate(Pred, Opc) || parseTypeAndValue(LHS, Loc, PFS) ||
+ parseToken(lltok::comma, "expected ',' after compare value") ||
+ parseValue(LHS->getType(), RHS, PFS))
return true;
if (Opc == Instruction::FCmp) {
if (!LHS->getType()->isFPOrFPVectorTy())
- return error(Loc, "fcmp requires floating point operands");
+ return error(Loc, "fcmp requires floating point operands");
Inst = new FCmpInst(CmpInst::Predicate(Pred), LHS, RHS);
} else {
assert(Opc == Instruction::ICmp && "Unknown opcode for CmpInst!");
if (!LHS->getType()->isIntOrIntVectorTy() &&
!LHS->getType()->isPtrOrPtrVectorTy())
- return error(Loc, "icmp requires integer operands");
+ return error(Loc, "icmp requires integer operands");
Inst = new ICmpInst(CmpInst::Predicate(Pred), LHS, RHS);
}
return false;
@@ -6918,132 +6918,132 @@ bool LLParser::parseCompare(Instruction *&Inst, PerFunctionState &PFS,
// Other Instructions.
//===----------------------------------------------------------------------===//
-/// parseCast
+/// parseCast
/// ::= CastOpc TypeAndValue 'to' Type
-bool LLParser::parseCast(Instruction *&Inst, PerFunctionState &PFS,
+bool LLParser::parseCast(Instruction *&Inst, PerFunctionState &PFS,
unsigned Opc) {
LocTy Loc;
Value *Op;
Type *DestTy = nullptr;
- if (parseTypeAndValue(Op, Loc, PFS) ||
- parseToken(lltok::kw_to, "expected 'to' after cast value") ||
- parseType(DestTy))
+ if (parseTypeAndValue(Op, Loc, PFS) ||
+ parseToken(lltok::kw_to, "expected 'to' after cast value") ||
+ parseType(DestTy))
return true;
if (!CastInst::castIsValid((Instruction::CastOps)Opc, Op, DestTy)) {
CastInst::castIsValid((Instruction::CastOps)Opc, Op, DestTy);
- return error(Loc, "invalid cast opcode for cast from '" +
- getTypeString(Op->getType()) + "' to '" +
- getTypeString(DestTy) + "'");
+ return error(Loc, "invalid cast opcode for cast from '" +
+ getTypeString(Op->getType()) + "' to '" +
+ getTypeString(DestTy) + "'");
}
Inst = CastInst::Create((Instruction::CastOps)Opc, Op, DestTy);
return false;
}
-/// parseSelect
+/// parseSelect
/// ::= 'select' TypeAndValue ',' TypeAndValue ',' TypeAndValue
-bool LLParser::parseSelect(Instruction *&Inst, PerFunctionState &PFS) {
+bool LLParser::parseSelect(Instruction *&Inst, PerFunctionState &PFS) {
LocTy Loc;
Value *Op0, *Op1, *Op2;
- if (parseTypeAndValue(Op0, Loc, PFS) ||
- parseToken(lltok::comma, "expected ',' after select condition") ||
- parseTypeAndValue(Op1, PFS) ||
- parseToken(lltok::comma, "expected ',' after select value") ||
- parseTypeAndValue(Op2, PFS))
+ if (parseTypeAndValue(Op0, Loc, PFS) ||
+ parseToken(lltok::comma, "expected ',' after select condition") ||
+ parseTypeAndValue(Op1, PFS) ||
+ parseToken(lltok::comma, "expected ',' after select value") ||
+ parseTypeAndValue(Op2, PFS))
return true;
if (const char *Reason = SelectInst::areInvalidOperands(Op0, Op1, Op2))
- return error(Loc, Reason);
+ return error(Loc, Reason);
Inst = SelectInst::Create(Op0, Op1, Op2);
return false;
}
-/// parseVAArg
+/// parseVAArg
/// ::= 'va_arg' TypeAndValue ',' Type
-bool LLParser::parseVAArg(Instruction *&Inst, PerFunctionState &PFS) {
+bool LLParser::parseVAArg(Instruction *&Inst, PerFunctionState &PFS) {
Value *Op;
Type *EltTy = nullptr;
LocTy TypeLoc;
- if (parseTypeAndValue(Op, PFS) ||
- parseToken(lltok::comma, "expected ',' after vaarg operand") ||
- parseType(EltTy, TypeLoc))
+ if (parseTypeAndValue(Op, PFS) ||
+ parseToken(lltok::comma, "expected ',' after vaarg operand") ||
+ parseType(EltTy, TypeLoc))
return true;
if (!EltTy->isFirstClassType())
- return error(TypeLoc, "va_arg requires operand with first class type");
+ return error(TypeLoc, "va_arg requires operand with first class type");
Inst = new VAArgInst(Op, EltTy);
return false;
}
-/// parseExtractElement
+/// parseExtractElement
/// ::= 'extractelement' TypeAndValue ',' TypeAndValue
-bool LLParser::parseExtractElement(Instruction *&Inst, PerFunctionState &PFS) {
+bool LLParser::parseExtractElement(Instruction *&Inst, PerFunctionState &PFS) {
LocTy Loc;
Value *Op0, *Op1;
- if (parseTypeAndValue(Op0, Loc, PFS) ||
- parseToken(lltok::comma, "expected ',' after extract value") ||
- parseTypeAndValue(Op1, PFS))
+ if (parseTypeAndValue(Op0, Loc, PFS) ||
+ parseToken(lltok::comma, "expected ',' after extract value") ||
+ parseTypeAndValue(Op1, PFS))
return true;
if (!ExtractElementInst::isValidOperands(Op0, Op1))
- return error(Loc, "invalid extractelement operands");
+ return error(Loc, "invalid extractelement operands");
Inst = ExtractElementInst::Create(Op0, Op1);
return false;
}
-/// parseInsertElement
+/// parseInsertElement
/// ::= 'insertelement' TypeAndValue ',' TypeAndValue ',' TypeAndValue
-bool LLParser::parseInsertElement(Instruction *&Inst, PerFunctionState &PFS) {
+bool LLParser::parseInsertElement(Instruction *&Inst, PerFunctionState &PFS) {
LocTy Loc;
Value *Op0, *Op1, *Op2;
- if (parseTypeAndValue(Op0, Loc, PFS) ||
- parseToken(lltok::comma, "expected ',' after insertelement value") ||
- parseTypeAndValue(Op1, PFS) ||
- parseToken(lltok::comma, "expected ',' after insertelement value") ||
- parseTypeAndValue(Op2, PFS))
+ if (parseTypeAndValue(Op0, Loc, PFS) ||
+ parseToken(lltok::comma, "expected ',' after insertelement value") ||
+ parseTypeAndValue(Op1, PFS) ||
+ parseToken(lltok::comma, "expected ',' after insertelement value") ||
+ parseTypeAndValue(Op2, PFS))
return true;
if (!InsertElementInst::isValidOperands(Op0, Op1, Op2))
- return error(Loc, "invalid insertelement operands");
+ return error(Loc, "invalid insertelement operands");
Inst = InsertElementInst::Create(Op0, Op1, Op2);
return false;
}
-/// parseShuffleVector
+/// parseShuffleVector
/// ::= 'shufflevector' TypeAndValue ',' TypeAndValue ',' TypeAndValue
-bool LLParser::parseShuffleVector(Instruction *&Inst, PerFunctionState &PFS) {
+bool LLParser::parseShuffleVector(Instruction *&Inst, PerFunctionState &PFS) {
LocTy Loc;
Value *Op0, *Op1, *Op2;
- if (parseTypeAndValue(Op0, Loc, PFS) ||
- parseToken(lltok::comma, "expected ',' after shuffle mask") ||
- parseTypeAndValue(Op1, PFS) ||
- parseToken(lltok::comma, "expected ',' after shuffle value") ||
- parseTypeAndValue(Op2, PFS))
+ if (parseTypeAndValue(Op0, Loc, PFS) ||
+ parseToken(lltok::comma, "expected ',' after shuffle mask") ||
+ parseTypeAndValue(Op1, PFS) ||
+ parseToken(lltok::comma, "expected ',' after shuffle value") ||
+ parseTypeAndValue(Op2, PFS))
return true;
if (!ShuffleVectorInst::isValidOperands(Op0, Op1, Op2))
- return error(Loc, "invalid shufflevector operands");
+ return error(Loc, "invalid shufflevector operands");
Inst = new ShuffleVectorInst(Op0, Op1, Op2);
return false;
}
-/// parsePHI
+/// parsePHI
/// ::= 'phi' Type '[' Value ',' Value ']' (',' '[' Value ',' Value ']')*
-int LLParser::parsePHI(Instruction *&Inst, PerFunctionState &PFS) {
+int LLParser::parsePHI(Instruction *&Inst, PerFunctionState &PFS) {
Type *Ty = nullptr; LocTy TypeLoc;
Value *Op0, *Op1;
- if (parseType(Ty, TypeLoc) ||
- parseToken(lltok::lsquare, "expected '[' in phi value list") ||
- parseValue(Ty, Op0, PFS) ||
- parseToken(lltok::comma, "expected ',' after insertelement value") ||
- parseValue(Type::getLabelTy(Context), Op1, PFS) ||
- parseToken(lltok::rsquare, "expected ']' in phi value list"))
+ if (parseType(Ty, TypeLoc) ||
+ parseToken(lltok::lsquare, "expected '[' in phi value list") ||
+ parseValue(Ty, Op0, PFS) ||
+ parseToken(lltok::comma, "expected ',' after insertelement value") ||
+ parseValue(Type::getLabelTy(Context), Op1, PFS) ||
+ parseToken(lltok::rsquare, "expected ']' in phi value list"))
return true;
bool AteExtraComma = false;
@@ -7060,16 +7060,16 @@ int LLParser::parsePHI(Instruction *&Inst, PerFunctionState &PFS) {
break;
}
- if (parseToken(lltok::lsquare, "expected '[' in phi value list") ||
- parseValue(Ty, Op0, PFS) ||
- parseToken(lltok::comma, "expected ',' after insertelement value") ||
- parseValue(Type::getLabelTy(Context), Op1, PFS) ||
- parseToken(lltok::rsquare, "expected ']' in phi value list"))
+ if (parseToken(lltok::lsquare, "expected '[' in phi value list") ||
+ parseValue(Ty, Op0, PFS) ||
+ parseToken(lltok::comma, "expected ',' after insertelement value") ||
+ parseValue(Type::getLabelTy(Context), Op1, PFS) ||
+ parseToken(lltok::rsquare, "expected ']' in phi value list"))
return true;
}
if (!Ty->isFirstClassType())
- return error(TypeLoc, "phi node must have first class type");
+ return error(TypeLoc, "phi node must have first class type");
PHINode *PN = PHINode::Create(Ty, PHIVals.size());
for (unsigned i = 0, e = PHIVals.size(); i != e; ++i)
@@ -7078,16 +7078,16 @@ int LLParser::parsePHI(Instruction *&Inst, PerFunctionState &PFS) {
return AteExtraComma ? InstExtraComma : InstNormal;
}
-/// parseLandingPad
+/// parseLandingPad
/// ::= 'landingpad' Type 'personality' TypeAndValue 'cleanup'? Clause+
/// Clause
/// ::= 'catch' TypeAndValue
/// ::= 'filter'
/// ::= 'filter' TypeAndValue ( ',' TypeAndValue )*
-bool LLParser::parseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
+bool LLParser::parseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
Type *Ty = nullptr; LocTy TyLoc;
- if (parseType(Ty, TyLoc))
+ if (parseType(Ty, TyLoc))
return true;
std::unique_ptr<LandingPadInst> LP(LandingPadInst::Create(Ty, 0));
@@ -7100,26 +7100,26 @@ bool LLParser::parseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
else if (EatIfPresent(lltok::kw_filter))
CT = LandingPadInst::Filter;
else
- return tokError("expected 'catch' or 'filter' clause type");
+ return tokError("expected 'catch' or 'filter' clause type");
Value *V;
LocTy VLoc;
- if (parseTypeAndValue(V, VLoc, PFS))
+ if (parseTypeAndValue(V, VLoc, PFS))
return true;
// A 'catch' type expects a non-array constant. A filter clause expects an
// array constant.
if (CT == LandingPadInst::Catch) {
if (isa<ArrayType>(V->getType()))
- error(VLoc, "'catch' clause has an invalid type");
+ error(VLoc, "'catch' clause has an invalid type");
} else {
if (!isa<ArrayType>(V->getType()))
- error(VLoc, "'filter' clause has an invalid type");
+ error(VLoc, "'filter' clause has an invalid type");
}
Constant *CV = dyn_cast<Constant>(V);
if (!CV)
- return error(VLoc, "clause argument must be a constant");
+ return error(VLoc, "clause argument must be a constant");
LP->addClause(CV);
}
@@ -7127,19 +7127,19 @@ bool LLParser::parseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
return false;
}
-/// parseFreeze
+/// parseFreeze
/// ::= 'freeze' Type Value
-bool LLParser::parseFreeze(Instruction *&Inst, PerFunctionState &PFS) {
+bool LLParser::parseFreeze(Instruction *&Inst, PerFunctionState &PFS) {
LocTy Loc;
Value *Op;
- if (parseTypeAndValue(Op, Loc, PFS))
+ if (parseTypeAndValue(Op, Loc, PFS))
return true;
Inst = new FreezeInst(Op);
return false;
}
-/// parseCall
+/// parseCall
/// ::= 'call' OptionalFastMathFlags OptionalCallingConv
/// OptionalAttrs Type Value ParameterList OptionalAttrs
/// ::= 'tail' 'call' OptionalFastMathFlags OptionalCallingConv
@@ -7148,7 +7148,7 @@ bool LLParser::parseFreeze(Instruction *&Inst, PerFunctionState &PFS) {
/// OptionalAttrs Type Value ParameterList OptionalAttrs
/// ::= 'notail' 'call' OptionalFastMathFlags OptionalCallingConv
/// OptionalAttrs Type Value ParameterList OptionalAttrs
-bool LLParser::parseCall(Instruction *&Inst, PerFunctionState &PFS,
+bool LLParser::parseCall(Instruction *&Inst, PerFunctionState &PFS,
CallInst::TailCallKind TCK) {
AttrBuilder RetAttrs, FnAttrs;
std::vector<unsigned> FwdRefAttrGrps;
@@ -7163,20 +7163,20 @@ bool LLParser::parseCall(Instruction *&Inst, PerFunctionState &PFS,
LocTy CallLoc = Lex.getLoc();
if (TCK != CallInst::TCK_None &&
- parseToken(lltok::kw_call,
+ parseToken(lltok::kw_call,
"expected 'tail call', 'musttail call', or 'notail call'"))
return true;
FastMathFlags FMF = EatFastMathFlagsIfPresent();
- if (parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(RetAttrs) ||
- parseOptionalProgramAddrSpace(CallAddrSpace) ||
- parseType(RetType, RetTypeLoc, true /*void allowed*/) ||
- parseValID(CalleeID) ||
- parseParameterList(ArgList, PFS, TCK == CallInst::TCK_MustTail,
+ if (parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(RetAttrs) ||
+ parseOptionalProgramAddrSpace(CallAddrSpace) ||
+ parseType(RetType, RetTypeLoc, true /*void allowed*/) ||
+ parseValID(CalleeID) ||
+ parseParameterList(ArgList, PFS, TCK == CallInst::TCK_MustTail,
PFS.getFunction().isVarArg()) ||
- parseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false, BuiltinLoc) ||
- parseOptionalOperandBundles(BundleList, PFS))
+ parseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false, BuiltinLoc) ||
+ parseOptionalOperandBundles(BundleList, PFS))
return true;
// If RetType is a non-function pointer type, then this is the short syntax
@@ -7190,7 +7190,7 @@ bool LLParser::parseCall(Instruction *&Inst, PerFunctionState &PFS,
ParamTypes.push_back(ArgList[i].V->getType());
if (!FunctionType::isValidReturnType(RetType))
- return error(RetTypeLoc, "Invalid result type for LLVM function");
+ return error(RetTypeLoc, "Invalid result type for LLVM function");
Ty = FunctionType::get(RetType, ParamTypes, false);
}
@@ -7199,7 +7199,7 @@ bool LLParser::parseCall(Instruction *&Inst, PerFunctionState &PFS,
// Look up the callee.
Value *Callee;
- if (convertValIDToValue(PointerType::get(Ty, CallAddrSpace), CalleeID, Callee,
+ if (convertValIDToValue(PointerType::get(Ty, CallAddrSpace), CalleeID, Callee,
&PFS, /*IsCall=*/true))
return true;
@@ -7217,21 +7217,21 @@ bool LLParser::parseCall(Instruction *&Inst, PerFunctionState &PFS,
if (I != E) {
ExpectedTy = *I++;
} else if (!Ty->isVarArg()) {
- return error(ArgList[i].Loc, "too many arguments specified");
+ return error(ArgList[i].Loc, "too many arguments specified");
}
if (ExpectedTy && ExpectedTy != ArgList[i].V->getType())
- return error(ArgList[i].Loc, "argument is not of expected type '" +
- getTypeString(ExpectedTy) + "'");
+ return error(ArgList[i].Loc, "argument is not of expected type '" +
+ getTypeString(ExpectedTy) + "'");
Args.push_back(ArgList[i].V);
Attrs.push_back(ArgList[i].Attrs);
}
if (I != E)
- return error(CallLoc, "not enough parameters specified for call");
+ return error(CallLoc, "not enough parameters specified for call");
if (FnAttrs.hasAlignmentAttr())
- return error(CallLoc, "call instructions may not have an alignment");
+ return error(CallLoc, "call instructions may not have an alignment");
// Finish off the Attribute and check them
AttributeList PAL =
@@ -7244,8 +7244,8 @@ bool LLParser::parseCall(Instruction *&Inst, PerFunctionState &PFS,
if (FMF.any()) {
if (!isa<FPMathOperator>(CI)) {
CI->deleteValue();
- return error(CallLoc, "fast-math-flags specified for call without "
- "floating-point scalar or vector return type");
+ return error(CallLoc, "fast-math-flags specified for call without "
+ "floating-point scalar or vector return type");
}
CI->setFastMathFlags(FMF);
}
@@ -7259,10 +7259,10 @@ bool LLParser::parseCall(Instruction *&Inst, PerFunctionState &PFS,
// Memory Instructions.
//===----------------------------------------------------------------------===//
-/// parseAlloc
+/// parseAlloc
/// ::= 'alloca' 'inalloca'? 'swifterror'? Type (',' TypeAndValue)?
/// (',' 'align' i32)? (',', 'addrspace(n))?
-int LLParser::parseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
+int LLParser::parseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
Value *Size = nullptr;
LocTy SizeLoc, TyLoc, ASLoc;
MaybeAlign Alignment;
@@ -7272,37 +7272,37 @@ int LLParser::parseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
bool IsInAlloca = EatIfPresent(lltok::kw_inalloca);
bool IsSwiftError = EatIfPresent(lltok::kw_swifterror);
- if (parseType(Ty, TyLoc))
- return true;
+ if (parseType(Ty, TyLoc))
+ return true;
if (Ty->isFunctionTy() || !PointerType::isValidElementType(Ty))
- return error(TyLoc, "invalid type for alloca");
+ return error(TyLoc, "invalid type for alloca");
bool AteExtraComma = false;
if (EatIfPresent(lltok::comma)) {
if (Lex.getKind() == lltok::kw_align) {
- if (parseOptionalAlignment(Alignment))
+ if (parseOptionalAlignment(Alignment))
return true;
- if (parseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma))
+ if (parseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma))
return true;
} else if (Lex.getKind() == lltok::kw_addrspace) {
ASLoc = Lex.getLoc();
- if (parseOptionalAddrSpace(AddrSpace))
+ if (parseOptionalAddrSpace(AddrSpace))
return true;
} else if (Lex.getKind() == lltok::MetadataVar) {
AteExtraComma = true;
} else {
- if (parseTypeAndValue(Size, SizeLoc, PFS))
+ if (parseTypeAndValue(Size, SizeLoc, PFS))
return true;
if (EatIfPresent(lltok::comma)) {
if (Lex.getKind() == lltok::kw_align) {
- if (parseOptionalAlignment(Alignment))
+ if (parseOptionalAlignment(Alignment))
return true;
- if (parseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma))
+ if (parseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma))
return true;
} else if (Lex.getKind() == lltok::kw_addrspace) {
ASLoc = Lex.getLoc();
- if (parseOptionalAddrSpace(AddrSpace))
+ if (parseOptionalAddrSpace(AddrSpace))
return true;
} else if (Lex.getKind() == lltok::MetadataVar) {
AteExtraComma = true;
@@ -7312,11 +7312,11 @@ int LLParser::parseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
}
if (Size && !Size->getType()->isIntegerTy())
- return error(SizeLoc, "element count must have integer type");
+ return error(SizeLoc, "element count must have integer type");
SmallPtrSet<Type *, 4> Visited;
if (!Alignment && !Ty->isSized(&Visited))
- return error(TyLoc, "Cannot allocate unsized type");
+ return error(TyLoc, "Cannot allocate unsized type");
if (!Alignment)
Alignment = M->getDataLayout().getPrefTypeAlign(Ty);
AllocaInst *AI = new AllocaInst(Ty, AddrSpace, Size, *Alignment);
@@ -7326,11 +7326,11 @@ int LLParser::parseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
return AteExtraComma ? InstExtraComma : InstNormal;
}
-/// parseLoad
+/// parseLoad
/// ::= 'load' 'volatile'? TypeAndValue (',' 'align' i32)?
/// ::= 'load' 'atomic' 'volatile'? TypeAndValue
/// 'singlethread'? AtomicOrdering (',' 'align' i32)?
-int LLParser::parseLoad(Instruction *&Inst, PerFunctionState &PFS) {
+int LLParser::parseLoad(Instruction *&Inst, PerFunctionState &PFS) {
Value *Val; LocTy Loc;
MaybeAlign Alignment;
bool AteExtraComma = false;
@@ -7351,39 +7351,39 @@ int LLParser::parseLoad(Instruction *&Inst, PerFunctionState &PFS) {
Type *Ty;
LocTy ExplicitTypeLoc = Lex.getLoc();
- if (parseType(Ty) ||
- parseToken(lltok::comma, "expected comma after load's type") ||
- parseTypeAndValue(Val, Loc, PFS) ||
- parseScopeAndOrdering(isAtomic, SSID, Ordering) ||
- parseOptionalCommaAlign(Alignment, AteExtraComma))
+ if (parseType(Ty) ||
+ parseToken(lltok::comma, "expected comma after load's type") ||
+ parseTypeAndValue(Val, Loc, PFS) ||
+ parseScopeAndOrdering(isAtomic, SSID, Ordering) ||
+ parseOptionalCommaAlign(Alignment, AteExtraComma))
return true;
if (!Val->getType()->isPointerTy() || !Ty->isFirstClassType())
- return error(Loc, "load operand must be a pointer to a first class type");
+ return error(Loc, "load operand must be a pointer to a first class type");
if (isAtomic && !Alignment)
- return error(Loc, "atomic load must have explicit non-zero alignment");
+ return error(Loc, "atomic load must have explicit non-zero alignment");
if (Ordering == AtomicOrdering::Release ||
Ordering == AtomicOrdering::AcquireRelease)
- return error(Loc, "atomic load cannot use Release ordering");
+ return error(Loc, "atomic load cannot use Release ordering");
if (Ty != cast<PointerType>(Val->getType())->getElementType())
- return error(ExplicitTypeLoc,
+ return error(ExplicitTypeLoc,
"explicit pointee type doesn't match operand's pointee type");
SmallPtrSet<Type *, 4> Visited;
if (!Alignment && !Ty->isSized(&Visited))
- return error(ExplicitTypeLoc, "loading unsized types is not allowed");
+ return error(ExplicitTypeLoc, "loading unsized types is not allowed");
if (!Alignment)
Alignment = M->getDataLayout().getABITypeAlign(Ty);
Inst = new LoadInst(Ty, Val, "", isVolatile, *Alignment, Ordering, SSID);
return AteExtraComma ? InstExtraComma : InstNormal;
}
-/// parseStore
+/// parseStore
/// ::= 'store' 'volatile'? TypeAndValue ',' TypeAndValue (',' 'align' i32)?
/// ::= 'store' 'atomic' 'volatile'? TypeAndValue ',' TypeAndValue
/// 'singlethread'? AtomicOrdering (',' 'align' i32)?
-int LLParser::parseStore(Instruction *&Inst, PerFunctionState &PFS) {
+int LLParser::parseStore(Instruction *&Inst, PerFunctionState &PFS) {
Value *Val, *Ptr; LocTy Loc, PtrLoc;
MaybeAlign Alignment;
bool AteExtraComma = false;
@@ -7402,27 +7402,27 @@ int LLParser::parseStore(Instruction *&Inst, PerFunctionState &PFS) {
Lex.Lex();
}
- if (parseTypeAndValue(Val, Loc, PFS) ||
- parseToken(lltok::comma, "expected ',' after store operand") ||
- parseTypeAndValue(Ptr, PtrLoc, PFS) ||
- parseScopeAndOrdering(isAtomic, SSID, Ordering) ||
- parseOptionalCommaAlign(Alignment, AteExtraComma))
+ if (parseTypeAndValue(Val, Loc, PFS) ||
+ parseToken(lltok::comma, "expected ',' after store operand") ||
+ parseTypeAndValue(Ptr, PtrLoc, PFS) ||
+ parseScopeAndOrdering(isAtomic, SSID, Ordering) ||
+ parseOptionalCommaAlign(Alignment, AteExtraComma))
return true;
if (!Ptr->getType()->isPointerTy())
- return error(PtrLoc, "store operand must be a pointer");
+ return error(PtrLoc, "store operand must be a pointer");
if (!Val->getType()->isFirstClassType())
- return error(Loc, "store operand must be a first class value");
+ return error(Loc, "store operand must be a first class value");
if (cast<PointerType>(Ptr->getType())->getElementType() != Val->getType())
- return error(Loc, "stored value and pointer type do not match");
+ return error(Loc, "stored value and pointer type do not match");
if (isAtomic && !Alignment)
- return error(Loc, "atomic store must have explicit non-zero alignment");
+ return error(Loc, "atomic store must have explicit non-zero alignment");
if (Ordering == AtomicOrdering::Acquire ||
Ordering == AtomicOrdering::AcquireRelease)
- return error(Loc, "atomic store cannot use Acquire ordering");
+ return error(Loc, "atomic store cannot use Acquire ordering");
SmallPtrSet<Type *, 4> Visited;
if (!Alignment && !Val->getType()->isSized(&Visited))
- return error(Loc, "storing unsized types is not allowed");
+ return error(Loc, "storing unsized types is not allowed");
if (!Alignment)
Alignment = M->getDataLayout().getABITypeAlign(Val->getType());
@@ -7430,10 +7430,10 @@ int LLParser::parseStore(Instruction *&Inst, PerFunctionState &PFS) {
return AteExtraComma ? InstExtraComma : InstNormal;
}
-/// parseCmpXchg
+/// parseCmpXchg
/// ::= 'cmpxchg' 'weak'? 'volatile'? TypeAndValue ',' TypeAndValue ','
/// TypeAndValue 'singlethread'? AtomicOrdering AtomicOrdering
-int LLParser::parseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) {
+int LLParser::parseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) {
Value *Ptr, *Cmp, *New; LocTy PtrLoc, CmpLoc, NewLoc;
bool AteExtraComma = false;
AtomicOrdering SuccessOrdering = AtomicOrdering::NotAtomic;
@@ -7448,33 +7448,33 @@ int LLParser::parseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) {
if (EatIfPresent(lltok::kw_volatile))
isVolatile = true;
- if (parseTypeAndValue(Ptr, PtrLoc, PFS) ||
- parseToken(lltok::comma, "expected ',' after cmpxchg address") ||
- parseTypeAndValue(Cmp, CmpLoc, PFS) ||
- parseToken(lltok::comma, "expected ',' after cmpxchg cmp operand") ||
- parseTypeAndValue(New, NewLoc, PFS) ||
- parseScopeAndOrdering(true /*Always atomic*/, SSID, SuccessOrdering) ||
- parseOrdering(FailureOrdering))
+ if (parseTypeAndValue(Ptr, PtrLoc, PFS) ||
+ parseToken(lltok::comma, "expected ',' after cmpxchg address") ||
+ parseTypeAndValue(Cmp, CmpLoc, PFS) ||
+ parseToken(lltok::comma, "expected ',' after cmpxchg cmp operand") ||
+ parseTypeAndValue(New, NewLoc, PFS) ||
+ parseScopeAndOrdering(true /*Always atomic*/, SSID, SuccessOrdering) ||
+ parseOrdering(FailureOrdering))
return true;
if (SuccessOrdering == AtomicOrdering::Unordered ||
FailureOrdering == AtomicOrdering::Unordered)
- return tokError("cmpxchg cannot be unordered");
+ return tokError("cmpxchg cannot be unordered");
if (isStrongerThan(FailureOrdering, SuccessOrdering))
- return tokError("cmpxchg failure argument shall be no stronger than the "
+ return tokError("cmpxchg failure argument shall be no stronger than the "
"success argument");
if (FailureOrdering == AtomicOrdering::Release ||
FailureOrdering == AtomicOrdering::AcquireRelease)
- return tokError(
+ return tokError(
"cmpxchg failure ordering cannot include release semantics");
if (!Ptr->getType()->isPointerTy())
- return error(PtrLoc, "cmpxchg operand must be a pointer");
+ return error(PtrLoc, "cmpxchg operand must be a pointer");
if (cast<PointerType>(Ptr->getType())->getElementType() != Cmp->getType())
- return error(CmpLoc, "compare value and pointer type do not match");
+ return error(CmpLoc, "compare value and pointer type do not match");
if (cast<PointerType>(Ptr->getType())->getElementType() != New->getType())
- return error(NewLoc, "new value and pointer type do not match");
+ return error(NewLoc, "new value and pointer type do not match");
if (!New->getType()->isFirstClassType())
- return error(NewLoc, "cmpxchg operand must be a first class value");
+ return error(NewLoc, "cmpxchg operand must be a first class value");
Align Alignment(
PFS.getFunction().getParent()->getDataLayout().getTypeStoreSize(
@@ -7488,10 +7488,10 @@ int LLParser::parseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) {
return AteExtraComma ? InstExtraComma : InstNormal;
}
-/// parseAtomicRMW
+/// parseAtomicRMW
/// ::= 'atomicrmw' 'volatile'? BinOp TypeAndValue ',' TypeAndValue
/// 'singlethread'? AtomicOrdering
-int LLParser::parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) {
+int LLParser::parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) {
Value *Ptr, *Val; LocTy PtrLoc, ValLoc;
bool AteExtraComma = false;
AtomicOrdering Ordering = AtomicOrdering::NotAtomic;
@@ -7504,8 +7504,8 @@ int LLParser::parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) {
isVolatile = true;
switch (Lex.getKind()) {
- default:
- return tokError("expected binary operation in atomicrmw");
+ default:
+ return tokError("expected binary operation in atomicrmw");
case lltok::kw_xchg: Operation = AtomicRMWInst::Xchg; break;
case lltok::kw_add: Operation = AtomicRMWInst::Add; break;
case lltok::kw_sub: Operation = AtomicRMWInst::Sub; break;
@@ -7528,43 +7528,43 @@ int LLParser::parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) {
}
Lex.Lex(); // Eat the operation.
- if (parseTypeAndValue(Ptr, PtrLoc, PFS) ||
- parseToken(lltok::comma, "expected ',' after atomicrmw address") ||
- parseTypeAndValue(Val, ValLoc, PFS) ||
- parseScopeAndOrdering(true /*Always atomic*/, SSID, Ordering))
+ if (parseTypeAndValue(Ptr, PtrLoc, PFS) ||
+ parseToken(lltok::comma, "expected ',' after atomicrmw address") ||
+ parseTypeAndValue(Val, ValLoc, PFS) ||
+ parseScopeAndOrdering(true /*Always atomic*/, SSID, Ordering))
return true;
if (Ordering == AtomicOrdering::Unordered)
- return tokError("atomicrmw cannot be unordered");
+ return tokError("atomicrmw cannot be unordered");
if (!Ptr->getType()->isPointerTy())
- return error(PtrLoc, "atomicrmw operand must be a pointer");
+ return error(PtrLoc, "atomicrmw operand must be a pointer");
if (cast<PointerType>(Ptr->getType())->getElementType() != Val->getType())
- return error(ValLoc, "atomicrmw value and pointer type do not match");
+ return error(ValLoc, "atomicrmw value and pointer type do not match");
if (Operation == AtomicRMWInst::Xchg) {
if (!Val->getType()->isIntegerTy() &&
!Val->getType()->isFloatingPointTy()) {
- return error(ValLoc,
- "atomicrmw " + AtomicRMWInst::getOperationName(Operation) +
- " operand must be an integer or floating point type");
+ return error(ValLoc,
+ "atomicrmw " + AtomicRMWInst::getOperationName(Operation) +
+ " operand must be an integer or floating point type");
}
} else if (IsFP) {
if (!Val->getType()->isFloatingPointTy()) {
- return error(ValLoc, "atomicrmw " +
- AtomicRMWInst::getOperationName(Operation) +
- " operand must be a floating point type");
+ return error(ValLoc, "atomicrmw " +
+ AtomicRMWInst::getOperationName(Operation) +
+ " operand must be a floating point type");
}
} else {
if (!Val->getType()->isIntegerTy()) {
- return error(ValLoc, "atomicrmw " +
- AtomicRMWInst::getOperationName(Operation) +
- " operand must be an integer");
+ return error(ValLoc, "atomicrmw " +
+ AtomicRMWInst::getOperationName(Operation) +
+ " operand must be an integer");
}
}
unsigned Size = Val->getType()->getPrimitiveSizeInBits();
if (Size < 8 || (Size & (Size - 1)))
- return error(ValLoc, "atomicrmw operand must be power-of-two byte-sized"
+ return error(ValLoc, "atomicrmw operand must be power-of-two byte-sized"
" integer");
Align Alignment(
PFS.getFunction().getParent()->getDataLayout().getTypeStoreSize(
@@ -7576,26 +7576,26 @@ int LLParser::parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) {
return AteExtraComma ? InstExtraComma : InstNormal;
}
-/// parseFence
+/// parseFence
/// ::= 'fence' 'singlethread'? AtomicOrdering
-int LLParser::parseFence(Instruction *&Inst, PerFunctionState &PFS) {
+int LLParser::parseFence(Instruction *&Inst, PerFunctionState &PFS) {
AtomicOrdering Ordering = AtomicOrdering::NotAtomic;
SyncScope::ID SSID = SyncScope::System;
- if (parseScopeAndOrdering(true /*Always atomic*/, SSID, Ordering))
+ if (parseScopeAndOrdering(true /*Always atomic*/, SSID, Ordering))
return true;
if (Ordering == AtomicOrdering::Unordered)
- return tokError("fence cannot be unordered");
+ return tokError("fence cannot be unordered");
if (Ordering == AtomicOrdering::Monotonic)
- return tokError("fence cannot be monotonic");
+ return tokError("fence cannot be monotonic");
Inst = new FenceInst(Context, Ordering, SSID);
return InstNormal;
}
-/// parseGetElementPtr
+/// parseGetElementPtr
/// ::= 'getelementptr' 'inbounds'? TypeAndValue (',' TypeAndValue)*
-int LLParser::parseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
+int LLParser::parseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
Value *Ptr = nullptr;
Value *Val = nullptr;
LocTy Loc, EltLoc;
@@ -7604,18 +7604,18 @@ int LLParser::parseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
Type *Ty = nullptr;
LocTy ExplicitTypeLoc = Lex.getLoc();
- if (parseType(Ty) ||
- parseToken(lltok::comma, "expected comma after getelementptr's type") ||
- parseTypeAndValue(Ptr, Loc, PFS))
+ if (parseType(Ty) ||
+ parseToken(lltok::comma, "expected comma after getelementptr's type") ||
+ parseTypeAndValue(Ptr, Loc, PFS))
return true;
Type *BaseType = Ptr->getType();
PointerType *BasePointerType = dyn_cast<PointerType>(BaseType->getScalarType());
if (!BasePointerType)
- return error(Loc, "base of getelementptr must be a pointer");
+ return error(Loc, "base of getelementptr must be a pointer");
if (Ty != BasePointerType->getElementType())
- return error(ExplicitTypeLoc,
+ return error(ExplicitTypeLoc,
"explicit pointee type doesn't match operand's pointee type");
SmallVector<Value*, 16> Indices;
@@ -7624,24 +7624,24 @@ int LLParser::parseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
// All vector parameters should have the same vector width.
ElementCount GEPWidth = BaseType->isVectorTy()
? cast<VectorType>(BaseType)->getElementCount()
- : ElementCount::getFixed(0);
+ : ElementCount::getFixed(0);
while (EatIfPresent(lltok::comma)) {
if (Lex.getKind() == lltok::MetadataVar) {
AteExtraComma = true;
break;
}
- if (parseTypeAndValue(Val, EltLoc, PFS))
- return true;
+ if (parseTypeAndValue(Val, EltLoc, PFS))
+ return true;
if (!Val->getType()->isIntOrIntVectorTy())
- return error(EltLoc, "getelementptr index must be an integer");
+ return error(EltLoc, "getelementptr index must be an integer");
if (auto *ValVTy = dyn_cast<VectorType>(Val->getType())) {
ElementCount ValNumEl = ValVTy->getElementCount();
- if (GEPWidth != ElementCount::getFixed(0) && GEPWidth != ValNumEl)
- return error(
- EltLoc,
- "getelementptr vector index has a wrong number of elements");
+ if (GEPWidth != ElementCount::getFixed(0) && GEPWidth != ValNumEl)
+ return error(
+ EltLoc,
+ "getelementptr vector index has a wrong number of elements");
GEPWidth = ValNumEl;
}
Indices.push_back(Val);
@@ -7649,55 +7649,55 @@ int LLParser::parseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
SmallPtrSet<Type*, 4> Visited;
if (!Indices.empty() && !Ty->isSized(&Visited))
- return error(Loc, "base element of getelementptr must be sized");
+ return error(Loc, "base element of getelementptr must be sized");
if (!GetElementPtrInst::getIndexedType(Ty, Indices))
- return error(Loc, "invalid getelementptr indices");
+ return error(Loc, "invalid getelementptr indices");
Inst = GetElementPtrInst::Create(Ty, Ptr, Indices);
if (InBounds)
cast<GetElementPtrInst>(Inst)->setIsInBounds(true);
return AteExtraComma ? InstExtraComma : InstNormal;
}
-/// parseExtractValue
+/// parseExtractValue
/// ::= 'extractvalue' TypeAndValue (',' uint32)+
-int LLParser::parseExtractValue(Instruction *&Inst, PerFunctionState &PFS) {
+int LLParser::parseExtractValue(Instruction *&Inst, PerFunctionState &PFS) {
Value *Val; LocTy Loc;
SmallVector<unsigned, 4> Indices;
bool AteExtraComma;
- if (parseTypeAndValue(Val, Loc, PFS) ||
- parseIndexList(Indices, AteExtraComma))
+ if (parseTypeAndValue(Val, Loc, PFS) ||
+ parseIndexList(Indices, AteExtraComma))
return true;
if (!Val->getType()->isAggregateType())
- return error(Loc, "extractvalue operand must be aggregate type");
+ return error(Loc, "extractvalue operand must be aggregate type");
if (!ExtractValueInst::getIndexedType(Val->getType(), Indices))
- return error(Loc, "invalid indices for extractvalue");
+ return error(Loc, "invalid indices for extractvalue");
Inst = ExtractValueInst::Create(Val, Indices);
return AteExtraComma ? InstExtraComma : InstNormal;
}
-/// parseInsertValue
+/// parseInsertValue
/// ::= 'insertvalue' TypeAndValue ',' TypeAndValue (',' uint32)+
-int LLParser::parseInsertValue(Instruction *&Inst, PerFunctionState &PFS) {
+int LLParser::parseInsertValue(Instruction *&Inst, PerFunctionState &PFS) {
Value *Val0, *Val1; LocTy Loc0, Loc1;
SmallVector<unsigned, 4> Indices;
bool AteExtraComma;
- if (parseTypeAndValue(Val0, Loc0, PFS) ||
- parseToken(lltok::comma, "expected comma after insertvalue operand") ||
- parseTypeAndValue(Val1, Loc1, PFS) ||
- parseIndexList(Indices, AteExtraComma))
+ if (parseTypeAndValue(Val0, Loc0, PFS) ||
+ parseToken(lltok::comma, "expected comma after insertvalue operand") ||
+ parseTypeAndValue(Val1, Loc1, PFS) ||
+ parseIndexList(Indices, AteExtraComma))
return true;
if (!Val0->getType()->isAggregateType())
- return error(Loc0, "insertvalue operand must be aggregate type");
+ return error(Loc0, "insertvalue operand must be aggregate type");
Type *IndexedType = ExtractValueInst::getIndexedType(Val0->getType(), Indices);
if (!IndexedType)
- return error(Loc0, "invalid indices for insertvalue");
+ return error(Loc0, "invalid indices for insertvalue");
if (IndexedType != Val1->getType())
- return error(Loc1, "insertvalue operand and field disagree in type: '" +
+ return error(Loc1, "insertvalue operand and field disagree in type: '" +
getTypeString(Val1->getType()) + "' instead of '" +
getTypeString(IndexedType) + "'");
Inst = InsertValueInst::Create(Val0, Val1, Indices);
@@ -7708,12 +7708,12 @@ int LLParser::parseInsertValue(Instruction *&Inst, PerFunctionState &PFS) {
// Embedded metadata.
//===----------------------------------------------------------------------===//
-/// parseMDNodeVector
+/// parseMDNodeVector
/// ::= { Element (',' Element)* }
/// Element
/// ::= 'null' | TypeAndValue
-bool LLParser::parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) {
- if (parseToken(lltok::lbrace, "expected '{' here"))
+bool LLParser::parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) {
+ if (parseToken(lltok::lbrace, "expected '{' here"))
return true;
// Check for an empty list.
@@ -7728,12 +7728,12 @@ bool LLParser::parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) {
}
Metadata *MD;
- if (parseMetadata(MD, nullptr))
+ if (parseMetadata(MD, nullptr))
return true;
Elts.push_back(MD);
} while (EatIfPresent(lltok::comma));
- return parseToken(lltok::rbrace, "expected end of metadata node");
+ return parseToken(lltok::rbrace, "expected end of metadata node");
}
//===----------------------------------------------------------------------===//
@@ -7742,7 +7742,7 @@ bool LLParser::parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) {
bool LLParser::sortUseListOrder(Value *V, ArrayRef<unsigned> Indexes,
SMLoc Loc) {
if (V->use_empty())
- return error(Loc, "value has no uses");
+ return error(Loc, "value has no uses");
unsigned NumUses = 0;
SmallDenseMap<const Use *, unsigned, 16> Order;
@@ -7752,9 +7752,9 @@ bool LLParser::sortUseListOrder(Value *V, ArrayRef<unsigned> Indexes,
Order[&U] = Indexes[NumUses - 1];
}
if (NumUses < 2)
- return error(Loc, "value only has one use");
+ return error(Loc, "value only has one use");
if (Order.size() != Indexes.size() || NumUses > Indexes.size())
- return error(Loc,
+ return error(Loc,
"wrong number of indexes, expected " + Twine(V->getNumUses()));
V->sortUseList([&](const Use &L, const Use &R) {
@@ -7763,11 +7763,11 @@ bool LLParser::sortUseListOrder(Value *V, ArrayRef<unsigned> Indexes,
return false;
}
-/// parseUseListOrderIndexes
+/// parseUseListOrderIndexes
/// ::= '{' uint32 (',' uint32)+ '}'
-bool LLParser::parseUseListOrderIndexes(SmallVectorImpl<unsigned> &Indexes) {
+bool LLParser::parseUseListOrderIndexes(SmallVectorImpl<unsigned> &Indexes) {
SMLoc Loc = Lex.getLoc();
- if (parseToken(lltok::lbrace, "expected '{' here"))
+ if (parseToken(lltok::lbrace, "expected '{' here"))
return true;
if (Lex.getKind() == lltok::rbrace)
return Lex.Error("expected non-empty list of uselistorder indexes");
@@ -7781,7 +7781,7 @@ bool LLParser::parseUseListOrderIndexes(SmallVectorImpl<unsigned> &Indexes) {
assert(Indexes.empty() && "Expected empty order vector");
do {
unsigned Index;
- if (parseUInt32(Index))
+ if (parseUInt32(Index))
return true;
// Update consistency checks.
@@ -7792,51 +7792,51 @@ bool LLParser::parseUseListOrderIndexes(SmallVectorImpl<unsigned> &Indexes) {
Indexes.push_back(Index);
} while (EatIfPresent(lltok::comma));
- if (parseToken(lltok::rbrace, "expected '}' here"))
+ if (parseToken(lltok::rbrace, "expected '}' here"))
return true;
if (Indexes.size() < 2)
- return error(Loc, "expected >= 2 uselistorder indexes");
+ return error(Loc, "expected >= 2 uselistorder indexes");
if (Offset != 0 || Max >= Indexes.size())
- return error(Loc,
- "expected distinct uselistorder indexes in range [0, size)");
+ return error(Loc,
+ "expected distinct uselistorder indexes in range [0, size)");
if (IsOrdered)
- return error(Loc, "expected uselistorder indexes to change the order");
+ return error(Loc, "expected uselistorder indexes to change the order");
return false;
}
-/// parseUseListOrder
+/// parseUseListOrder
/// ::= 'uselistorder' Type Value ',' UseListOrderIndexes
-bool LLParser::parseUseListOrder(PerFunctionState *PFS) {
+bool LLParser::parseUseListOrder(PerFunctionState *PFS) {
SMLoc Loc = Lex.getLoc();
- if (parseToken(lltok::kw_uselistorder, "expected uselistorder directive"))
+ if (parseToken(lltok::kw_uselistorder, "expected uselistorder directive"))
return true;
Value *V;
SmallVector<unsigned, 16> Indexes;
- if (parseTypeAndValue(V, PFS) ||
- parseToken(lltok::comma, "expected comma in uselistorder directive") ||
- parseUseListOrderIndexes(Indexes))
+ if (parseTypeAndValue(V, PFS) ||
+ parseToken(lltok::comma, "expected comma in uselistorder directive") ||
+ parseUseListOrderIndexes(Indexes))
return true;
return sortUseListOrder(V, Indexes, Loc);
}
-/// parseUseListOrderBB
+/// parseUseListOrderBB
/// ::= 'uselistorder_bb' @foo ',' %bar ',' UseListOrderIndexes
-bool LLParser::parseUseListOrderBB() {
+bool LLParser::parseUseListOrderBB() {
assert(Lex.getKind() == lltok::kw_uselistorder_bb);
SMLoc Loc = Lex.getLoc();
Lex.Lex();
ValID Fn, Label;
SmallVector<unsigned, 16> Indexes;
- if (parseValID(Fn) ||
- parseToken(lltok::comma, "expected comma in uselistorder_bb directive") ||
- parseValID(Label) ||
- parseToken(lltok::comma, "expected comma in uselistorder_bb directive") ||
- parseUseListOrderIndexes(Indexes))
+ if (parseValID(Fn) ||
+ parseToken(lltok::comma, "expected comma in uselistorder_bb directive") ||
+ parseValID(Label) ||
+ parseToken(lltok::comma, "expected comma in uselistorder_bb directive") ||
+ parseUseListOrderIndexes(Indexes))
return true;
// Check the function.
@@ -7846,26 +7846,26 @@ bool LLParser::parseUseListOrderBB() {
else if (Fn.Kind == ValID::t_GlobalID)
GV = Fn.UIntVal < NumberedVals.size() ? NumberedVals[Fn.UIntVal] : nullptr;
else
- return error(Fn.Loc, "expected function name in uselistorder_bb");
+ return error(Fn.Loc, "expected function name in uselistorder_bb");
if (!GV)
- return error(Fn.Loc,
- "invalid function forward reference in uselistorder_bb");
+ return error(Fn.Loc,
+ "invalid function forward reference in uselistorder_bb");
auto *F = dyn_cast<Function>(GV);
if (!F)
- return error(Fn.Loc, "expected function name in uselistorder_bb");
+ return error(Fn.Loc, "expected function name in uselistorder_bb");
if (F->isDeclaration())
- return error(Fn.Loc, "invalid declaration in uselistorder_bb");
+ return error(Fn.Loc, "invalid declaration in uselistorder_bb");
// Check the basic block.
if (Label.Kind == ValID::t_LocalID)
- return error(Label.Loc, "invalid numeric label in uselistorder_bb");
+ return error(Label.Loc, "invalid numeric label in uselistorder_bb");
if (Label.Kind != ValID::t_LocalName)
- return error(Label.Loc, "expected basic block name in uselistorder_bb");
+ return error(Label.Loc, "expected basic block name in uselistorder_bb");
Value *V = F->getValueSymbolTable()->lookup(Label.StrVal);
if (!V)
- return error(Label.Loc, "invalid basic block in uselistorder_bb");
+ return error(Label.Loc, "invalid basic block in uselistorder_bb");
if (!isa<BasicBlock>(V))
- return error(Label.Loc, "expected basic block in uselistorder_bb");
+ return error(Label.Loc, "expected basic block in uselistorder_bb");
return sortUseListOrder(V, Indexes, Loc);
}
@@ -7873,32 +7873,32 @@ bool LLParser::parseUseListOrderBB() {
/// ModuleEntry
/// ::= 'module' ':' '(' 'path' ':' STRINGCONSTANT ',' 'hash' ':' Hash ')'
/// Hash ::= '(' UInt32 ',' UInt32 ',' UInt32 ',' UInt32 ',' UInt32 ')'
-bool LLParser::parseModuleEntry(unsigned ID) {
+bool LLParser::parseModuleEntry(unsigned ID) {
assert(Lex.getKind() == lltok::kw_module);
Lex.Lex();
std::string Path;
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here") ||
- parseToken(lltok::kw_path, "expected 'path' here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseStringConstant(Path) ||
- parseToken(lltok::comma, "expected ',' here") ||
- parseToken(lltok::kw_hash, "expected 'hash' here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here"))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here") ||
+ parseToken(lltok::kw_path, "expected 'path' here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseStringConstant(Path) ||
+ parseToken(lltok::comma, "expected ',' here") ||
+ parseToken(lltok::kw_hash, "expected 'hash' here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here"))
return true;
ModuleHash Hash;
- if (parseUInt32(Hash[0]) || parseToken(lltok::comma, "expected ',' here") ||
- parseUInt32(Hash[1]) || parseToken(lltok::comma, "expected ',' here") ||
- parseUInt32(Hash[2]) || parseToken(lltok::comma, "expected ',' here") ||
- parseUInt32(Hash[3]) || parseToken(lltok::comma, "expected ',' here") ||
- parseUInt32(Hash[4]))
+ if (parseUInt32(Hash[0]) || parseToken(lltok::comma, "expected ',' here") ||
+ parseUInt32(Hash[1]) || parseToken(lltok::comma, "expected ',' here") ||
+ parseUInt32(Hash[2]) || parseToken(lltok::comma, "expected ',' here") ||
+ parseUInt32(Hash[3]) || parseToken(lltok::comma, "expected ',' here") ||
+ parseUInt32(Hash[4]))
return true;
- if (parseToken(lltok::rparen, "expected ')' here") ||
- parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here") ||
+ parseToken(lltok::rparen, "expected ')' here"))
return true;
auto ModuleEntry = Index->addModule(Path, ID, Hash);
@@ -7909,21 +7909,21 @@ bool LLParser::parseModuleEntry(unsigned ID) {
/// TypeIdEntry
/// ::= 'typeid' ':' '(' 'name' ':' STRINGCONSTANT ',' TypeIdSummary ')'
-bool LLParser::parseTypeIdEntry(unsigned ID) {
+bool LLParser::parseTypeIdEntry(unsigned ID) {
assert(Lex.getKind() == lltok::kw_typeid);
Lex.Lex();
std::string Name;
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here") ||
- parseToken(lltok::kw_name, "expected 'name' here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseStringConstant(Name))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here") ||
+ parseToken(lltok::kw_name, "expected 'name' here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseStringConstant(Name))
return true;
TypeIdSummary &TIS = Index->getOrInsertTypeIdSummary(Name);
- if (parseToken(lltok::comma, "expected ',' here") ||
- parseTypeIdSummary(TIS) || parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::comma, "expected ',' here") ||
+ parseTypeIdSummary(TIS) || parseToken(lltok::rparen, "expected ')' here"))
return true;
// Check if this ID was forward referenced, and if so, update the
@@ -7943,20 +7943,20 @@ bool LLParser::parseTypeIdEntry(unsigned ID) {
/// TypeIdSummary
/// ::= 'summary' ':' '(' TypeTestResolution [',' OptionalWpdResolutions]? ')'
-bool LLParser::parseTypeIdSummary(TypeIdSummary &TIS) {
- if (parseToken(lltok::kw_summary, "expected 'summary' here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here") ||
- parseTypeTestResolution(TIS.TTRes))
+bool LLParser::parseTypeIdSummary(TypeIdSummary &TIS) {
+ if (parseToken(lltok::kw_summary, "expected 'summary' here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here") ||
+ parseTypeTestResolution(TIS.TTRes))
return true;
if (EatIfPresent(lltok::comma)) {
// Expect optional wpdResolutions field
- if (parseOptionalWpdResolutions(TIS.WPDRes))
+ if (parseOptionalWpdResolutions(TIS.WPDRes))
return true;
}
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
return false;
@@ -7969,40 +7969,40 @@ static ValueInfo EmptyVI =
/// ::= 'typeidCompatibleVTable' ':' '(' 'name' ':' STRINGCONSTANT ','
/// TypeIdCompatibleVtableInfo
/// ')'
-bool LLParser::parseTypeIdCompatibleVtableEntry(unsigned ID) {
+bool LLParser::parseTypeIdCompatibleVtableEntry(unsigned ID) {
assert(Lex.getKind() == lltok::kw_typeidCompatibleVTable);
Lex.Lex();
std::string Name;
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here") ||
- parseToken(lltok::kw_name, "expected 'name' here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseStringConstant(Name))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here") ||
+ parseToken(lltok::kw_name, "expected 'name' here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseStringConstant(Name))
return true;
TypeIdCompatibleVtableInfo &TI =
Index->getOrInsertTypeIdCompatibleVtableSummary(Name);
- if (parseToken(lltok::comma, "expected ',' here") ||
- parseToken(lltok::kw_summary, "expected 'summary' here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here"))
+ if (parseToken(lltok::comma, "expected ',' here") ||
+ parseToken(lltok::kw_summary, "expected 'summary' here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here"))
return true;
IdToIndexMapType IdToIndexMap;
- // parse each call edge
+ // parse each call edge
do {
uint64_t Offset;
- if (parseToken(lltok::lparen, "expected '(' here") ||
- parseToken(lltok::kw_offset, "expected 'offset' here") ||
- parseToken(lltok::colon, "expected ':' here") || parseUInt64(Offset) ||
- parseToken(lltok::comma, "expected ',' here"))
+ if (parseToken(lltok::lparen, "expected '(' here") ||
+ parseToken(lltok::kw_offset, "expected 'offset' here") ||
+ parseToken(lltok::colon, "expected ':' here") || parseUInt64(Offset) ||
+ parseToken(lltok::comma, "expected ',' here"))
return true;
LocTy Loc = Lex.getLoc();
unsigned GVId;
ValueInfo VI;
- if (parseGVReference(VI, GVId))
+ if (parseGVReference(VI, GVId))
return true;
// Keep track of the TypeIdCompatibleVtableInfo array index needing a
@@ -8012,23 +8012,23 @@ bool LLParser::parseTypeIdCompatibleVtableEntry(unsigned ID) {
IdToIndexMap[GVId].push_back(std::make_pair(TI.size(), Loc));
TI.push_back({Offset, VI});
- if (parseToken(lltok::rparen, "expected ')' in call"))
+ if (parseToken(lltok::rparen, "expected ')' in call"))
return true;
} while (EatIfPresent(lltok::comma));
// Now that the TI vector is finalized, it is safe to save the locations
// of any forward GV references that need updating later.
for (auto I : IdToIndexMap) {
- auto &Infos = ForwardRefValueInfos[I.first];
+ auto &Infos = ForwardRefValueInfos[I.first];
for (auto P : I.second) {
assert(TI[P.first].VTableVI == EmptyVI &&
"Forward referenced ValueInfo expected to be empty");
- Infos.emplace_back(&TI[P.first].VTableVI, P.second);
+ Infos.emplace_back(&TI[P.first].VTableVI, P.second);
}
}
- if (parseToken(lltok::rparen, "expected ')' here") ||
- parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here") ||
+ parseToken(lltok::rparen, "expected ')' here"))
return true;
// Check if this ID was forward referenced, and if so, update the
@@ -8052,12 +8052,12 @@ bool LLParser::parseTypeIdCompatibleVtableEntry(unsigned ID) {
/// 'sizeM1BitWidth' ':' SizeM1BitWidth [',' 'alignLog2' ':' UInt64]?
/// [',' 'sizeM1' ':' UInt64]? [',' 'bitMask' ':' UInt8]?
/// [',' 'inlinesBits' ':' UInt64]? ')'
-bool LLParser::parseTypeTestResolution(TypeTestResolution &TTRes) {
- if (parseToken(lltok::kw_typeTestRes, "expected 'typeTestRes' here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here") ||
- parseToken(lltok::kw_kind, "expected 'kind' here") ||
- parseToken(lltok::colon, "expected ':' here"))
+bool LLParser::parseTypeTestResolution(TypeTestResolution &TTRes) {
+ if (parseToken(lltok::kw_typeTestRes, "expected 'typeTestRes' here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here") ||
+ parseToken(lltok::kw_kind, "expected 'kind' here") ||
+ parseToken(lltok::colon, "expected ':' here"))
return true;
switch (Lex.getKind()) {
@@ -8080,34 +8080,34 @@ bool LLParser::parseTypeTestResolution(TypeTestResolution &TTRes) {
TTRes.TheKind = TypeTestResolution::AllOnes;
break;
default:
- return error(Lex.getLoc(), "unexpected TypeTestResolution kind");
+ return error(Lex.getLoc(), "unexpected TypeTestResolution kind");
}
Lex.Lex();
- if (parseToken(lltok::comma, "expected ',' here") ||
- parseToken(lltok::kw_sizeM1BitWidth, "expected 'sizeM1BitWidth' here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseUInt32(TTRes.SizeM1BitWidth))
+ if (parseToken(lltok::comma, "expected ',' here") ||
+ parseToken(lltok::kw_sizeM1BitWidth, "expected 'sizeM1BitWidth' here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseUInt32(TTRes.SizeM1BitWidth))
return true;
- // parse optional fields
+ // parse optional fields
while (EatIfPresent(lltok::comma)) {
switch (Lex.getKind()) {
case lltok::kw_alignLog2:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':'") ||
- parseUInt64(TTRes.AlignLog2))
+ if (parseToken(lltok::colon, "expected ':'") ||
+ parseUInt64(TTRes.AlignLog2))
return true;
break;
case lltok::kw_sizeM1:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':'") || parseUInt64(TTRes.SizeM1))
+ if (parseToken(lltok::colon, "expected ':'") || parseUInt64(TTRes.SizeM1))
return true;
break;
case lltok::kw_bitMask: {
unsigned Val;
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':'") || parseUInt32(Val))
+ if (parseToken(lltok::colon, "expected ':'") || parseUInt32(Val))
return true;
assert(Val <= 0xff);
TTRes.BitMask = (uint8_t)Val;
@@ -8115,16 +8115,16 @@ bool LLParser::parseTypeTestResolution(TypeTestResolution &TTRes) {
}
case lltok::kw_inlineBits:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':'") ||
- parseUInt64(TTRes.InlineBits))
+ if (parseToken(lltok::colon, "expected ':'") ||
+ parseUInt64(TTRes.InlineBits))
return true;
break;
default:
- return error(Lex.getLoc(), "expected optional TypeTestResolution field");
+ return error(Lex.getLoc(), "expected optional TypeTestResolution field");
}
}
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
return false;
@@ -8133,26 +8133,26 @@ bool LLParser::parseTypeTestResolution(TypeTestResolution &TTRes) {
/// OptionalWpdResolutions
/// ::= 'wpsResolutions' ':' '(' WpdResolution [',' WpdResolution]* ')'
/// WpdResolution ::= '(' 'offset' ':' UInt64 ',' WpdRes ')'
-bool LLParser::parseOptionalWpdResolutions(
+bool LLParser::parseOptionalWpdResolutions(
std::map<uint64_t, WholeProgramDevirtResolution> &WPDResMap) {
- if (parseToken(lltok::kw_wpdResolutions, "expected 'wpdResolutions' here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here"))
+ if (parseToken(lltok::kw_wpdResolutions, "expected 'wpdResolutions' here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here"))
return true;
do {
uint64_t Offset;
WholeProgramDevirtResolution WPDRes;
- if (parseToken(lltok::lparen, "expected '(' here") ||
- parseToken(lltok::kw_offset, "expected 'offset' here") ||
- parseToken(lltok::colon, "expected ':' here") || parseUInt64(Offset) ||
- parseToken(lltok::comma, "expected ',' here") || parseWpdRes(WPDRes) ||
- parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::lparen, "expected '(' here") ||
+ parseToken(lltok::kw_offset, "expected 'offset' here") ||
+ parseToken(lltok::colon, "expected ':' here") || parseUInt64(Offset) ||
+ parseToken(lltok::comma, "expected ',' here") || parseWpdRes(WPDRes) ||
+ parseToken(lltok::rparen, "expected ')' here"))
return true;
WPDResMap[Offset] = WPDRes;
} while (EatIfPresent(lltok::comma));
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
return false;
@@ -8166,12 +8166,12 @@ bool LLParser::parseOptionalWpdResolutions(
/// [',' OptionalResByArg]? ')'
/// ::= 'wpdRes' ':' '(' 'kind' ':' 'branchFunnel'
/// [',' OptionalResByArg]? ')'
-bool LLParser::parseWpdRes(WholeProgramDevirtResolution &WPDRes) {
- if (parseToken(lltok::kw_wpdRes, "expected 'wpdRes' here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here") ||
- parseToken(lltok::kw_kind, "expected 'kind' here") ||
- parseToken(lltok::colon, "expected ':' here"))
+bool LLParser::parseWpdRes(WholeProgramDevirtResolution &WPDRes) {
+ if (parseToken(lltok::kw_wpdRes, "expected 'wpdRes' here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here") ||
+ parseToken(lltok::kw_kind, "expected 'kind' here") ||
+ parseToken(lltok::colon, "expected ':' here"))
return true;
switch (Lex.getKind()) {
@@ -8185,30 +8185,30 @@ bool LLParser::parseWpdRes(WholeProgramDevirtResolution &WPDRes) {
WPDRes.TheKind = WholeProgramDevirtResolution::BranchFunnel;
break;
default:
- return error(Lex.getLoc(), "unexpected WholeProgramDevirtResolution kind");
+ return error(Lex.getLoc(), "unexpected WholeProgramDevirtResolution kind");
}
Lex.Lex();
- // parse optional fields
+ // parse optional fields
while (EatIfPresent(lltok::comma)) {
switch (Lex.getKind()) {
case lltok::kw_singleImplName:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseStringConstant(WPDRes.SingleImplName))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseStringConstant(WPDRes.SingleImplName))
return true;
break;
case lltok::kw_resByArg:
- if (parseOptionalResByArg(WPDRes.ResByArg))
+ if (parseOptionalResByArg(WPDRes.ResByArg))
return true;
break;
default:
- return error(Lex.getLoc(),
+ return error(Lex.getLoc(),
"expected optional WholeProgramDevirtResolution field");
}
}
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
return false;
@@ -8221,22 +8221,22 @@ bool LLParser::parseWpdRes(WholeProgramDevirtResolution &WPDRes) {
/// 'virtualConstProp' )
/// [',' 'info' ':' UInt64]? [',' 'byte' ':' UInt32]?
/// [',' 'bit' ':' UInt32]? ')'
-bool LLParser::parseOptionalResByArg(
+bool LLParser::parseOptionalResByArg(
std::map<std::vector<uint64_t>, WholeProgramDevirtResolution::ByArg>
&ResByArg) {
- if (parseToken(lltok::kw_resByArg, "expected 'resByArg' here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here"))
+ if (parseToken(lltok::kw_resByArg, "expected 'resByArg' here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here"))
return true;
do {
std::vector<uint64_t> Args;
- if (parseArgs(Args) || parseToken(lltok::comma, "expected ',' here") ||
- parseToken(lltok::kw_byArg, "expected 'byArg here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here") ||
- parseToken(lltok::kw_kind, "expected 'kind' here") ||
- parseToken(lltok::colon, "expected ':' here"))
+ if (parseArgs(Args) || parseToken(lltok::comma, "expected ',' here") ||
+ parseToken(lltok::kw_byArg, "expected 'byArg here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here") ||
+ parseToken(lltok::kw_kind, "expected 'kind' here") ||
+ parseToken(lltok::colon, "expected ':' here"))
return true;
WholeProgramDevirtResolution::ByArg ByArg;
@@ -8254,45 +8254,45 @@ bool LLParser::parseOptionalResByArg(
ByArg.TheKind = WholeProgramDevirtResolution::ByArg::VirtualConstProp;
break;
default:
- return error(Lex.getLoc(),
+ return error(Lex.getLoc(),
"unexpected WholeProgramDevirtResolution::ByArg kind");
}
Lex.Lex();
- // parse optional fields
+ // parse optional fields
while (EatIfPresent(lltok::comma)) {
switch (Lex.getKind()) {
case lltok::kw_info:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseUInt64(ByArg.Info))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseUInt64(ByArg.Info))
return true;
break;
case lltok::kw_byte:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseUInt32(ByArg.Byte))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseUInt32(ByArg.Byte))
return true;
break;
case lltok::kw_bit:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseUInt32(ByArg.Bit))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseUInt32(ByArg.Bit))
return true;
break;
default:
- return error(Lex.getLoc(),
+ return error(Lex.getLoc(),
"expected optional whole program devirt field");
}
}
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
ResByArg[Args] = ByArg;
} while (EatIfPresent(lltok::comma));
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
return false;
@@ -8300,20 +8300,20 @@ bool LLParser::parseOptionalResByArg(
/// OptionalResByArg
/// ::= 'args' ':' '(' UInt64[, UInt64]* ')'
-bool LLParser::parseArgs(std::vector<uint64_t> &Args) {
- if (parseToken(lltok::kw_args, "expected 'args' here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here"))
+bool LLParser::parseArgs(std::vector<uint64_t> &Args) {
+ if (parseToken(lltok::kw_args, "expected 'args' here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here"))
return true;
do {
uint64_t Val;
- if (parseUInt64(Val))
+ if (parseUInt64(Val))
return true;
Args.push_back(Val);
} while (EatIfPresent(lltok::comma));
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
return false;
@@ -8334,7 +8334,7 @@ static void resolveFwdRef(ValueInfo *Fwd, ValueInfo &Resolved) {
/// Stores the given Name/GUID and associated summary into the Index.
/// Also updates any forward references to the associated entry ID.
-void LLParser::addGlobalValueToIndex(
+void LLParser::addGlobalValueToIndex(
std::string Name, GlobalValue::GUID GUID, GlobalValue::LinkageTypes Linkage,
unsigned ID, std::unique_ptr<GlobalValueSummary> Summary) {
// First create the ValueInfo utilizing the Name or GUID.
@@ -8396,48 +8396,48 @@ void LLParser::addGlobalValueToIndex(
}
}
-/// parseSummaryIndexFlags
+/// parseSummaryIndexFlags
/// ::= 'flags' ':' UInt64
-bool LLParser::parseSummaryIndexFlags() {
+bool LLParser::parseSummaryIndexFlags() {
assert(Lex.getKind() == lltok::kw_flags);
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' here"))
+ if (parseToken(lltok::colon, "expected ':' here"))
return true;
uint64_t Flags;
- if (parseUInt64(Flags))
+ if (parseUInt64(Flags))
return true;
- if (Index)
- Index->setFlags(Flags);
+ if (Index)
+ Index->setFlags(Flags);
return false;
}
-/// parseBlockCount
+/// parseBlockCount
/// ::= 'blockcount' ':' UInt64
-bool LLParser::parseBlockCount() {
+bool LLParser::parseBlockCount() {
assert(Lex.getKind() == lltok::kw_blockcount);
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' here"))
+ if (parseToken(lltok::colon, "expected ':' here"))
return true;
uint64_t BlockCount;
- if (parseUInt64(BlockCount))
+ if (parseUInt64(BlockCount))
return true;
- if (Index)
- Index->setBlockCount(BlockCount);
+ if (Index)
+ Index->setBlockCount(BlockCount);
return false;
}
-/// parseGVEntry
+/// parseGVEntry
/// ::= 'gv' ':' '(' ('name' ':' STRINGCONSTANT | 'guid' ':' UInt64)
/// [',' 'summaries' ':' Summary[',' Summary]* ]? ')'
/// Summary ::= '(' (FunctionSummary | VariableSummary | AliasSummary) ')'
-bool LLParser::parseGVEntry(unsigned ID) {
+bool LLParser::parseGVEntry(unsigned ID) {
assert(Lex.getKind() == lltok::kw_gv);
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here"))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here"))
return true;
std::string Name;
@@ -8445,23 +8445,23 @@ bool LLParser::parseGVEntry(unsigned ID) {
switch (Lex.getKind()) {
case lltok::kw_name:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseStringConstant(Name))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseStringConstant(Name))
return true;
// Can't create GUID/ValueInfo until we have the linkage.
break;
case lltok::kw_guid:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' here") || parseUInt64(GUID))
+ if (parseToken(lltok::colon, "expected ':' here") || parseUInt64(GUID))
return true;
break;
default:
- return error(Lex.getLoc(), "expected name or guid tag");
+ return error(Lex.getLoc(), "expected name or guid tag");
}
if (!EatIfPresent(lltok::comma)) {
// No summaries. Wrap up.
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
// This was created for a call to an external or indirect target.
// A GUID with no summary came from a VALUE_GUID record, dummy GUID
@@ -8469,37 +8469,37 @@ bool LLParser::parseGVEntry(unsigned ID) {
// an external definition. We pass ExternalLinkage since that is only
// used when the GUID must be computed from Name, and in that case
// the symbol must have external linkage.
- addGlobalValueToIndex(Name, GUID, GlobalValue::ExternalLinkage, ID,
+ addGlobalValueToIndex(Name, GUID, GlobalValue::ExternalLinkage, ID,
nullptr);
return false;
}
// Have a list of summaries
- if (parseToken(lltok::kw_summaries, "expected 'summaries' here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here"))
+ if (parseToken(lltok::kw_summaries, "expected 'summaries' here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here"))
return true;
do {
switch (Lex.getKind()) {
case lltok::kw_function:
- if (parseFunctionSummary(Name, GUID, ID))
+ if (parseFunctionSummary(Name, GUID, ID))
return true;
break;
case lltok::kw_variable:
- if (parseVariableSummary(Name, GUID, ID))
+ if (parseVariableSummary(Name, GUID, ID))
return true;
break;
case lltok::kw_alias:
- if (parseAliasSummary(Name, GUID, ID))
+ if (parseAliasSummary(Name, GUID, ID))
return true;
break;
default:
- return error(Lex.getLoc(), "expected summary type");
+ return error(Lex.getLoc(), "expected summary type");
}
} while (EatIfPresent(lltok::comma));
- if (parseToken(lltok::rparen, "expected ')' here") ||
- parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here") ||
+ parseToken(lltok::rparen, "expected ')' here"))
return true;
return false;
@@ -8510,7 +8510,7 @@ bool LLParser::parseGVEntry(unsigned ID) {
/// ',' 'insts' ':' UInt32 [',' OptionalFFlags]? [',' OptionalCalls]?
/// [',' OptionalTypeIdInfo]? [',' OptionalParamAccesses]?
/// [',' OptionalRefs]? ')'
-bool LLParser::parseFunctionSummary(std::string Name, GlobalValue::GUID GUID,
+bool LLParser::parseFunctionSummary(std::string Name, GlobalValue::GUID GUID,
unsigned ID) {
assert(Lex.getKind() == lltok::kw_function);
Lex.Lex();
@@ -8526,44 +8526,44 @@ bool LLParser::parseFunctionSummary(std::string Name, GlobalValue::GUID GUID,
std::vector<ValueInfo> Refs;
// Default is all-zeros (conservative values).
FunctionSummary::FFlags FFlags = {};
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here") ||
- parseModuleReference(ModulePath) ||
- parseToken(lltok::comma, "expected ',' here") || parseGVFlags(GVFlags) ||
- parseToken(lltok::comma, "expected ',' here") ||
- parseToken(lltok::kw_insts, "expected 'insts' here") ||
- parseToken(lltok::colon, "expected ':' here") || parseUInt32(InstCount))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here") ||
+ parseModuleReference(ModulePath) ||
+ parseToken(lltok::comma, "expected ',' here") || parseGVFlags(GVFlags) ||
+ parseToken(lltok::comma, "expected ',' here") ||
+ parseToken(lltok::kw_insts, "expected 'insts' here") ||
+ parseToken(lltok::colon, "expected ':' here") || parseUInt32(InstCount))
return true;
- // parse optional fields
+ // parse optional fields
while (EatIfPresent(lltok::comma)) {
switch (Lex.getKind()) {
case lltok::kw_funcFlags:
- if (parseOptionalFFlags(FFlags))
+ if (parseOptionalFFlags(FFlags))
return true;
break;
case lltok::kw_calls:
- if (parseOptionalCalls(Calls))
+ if (parseOptionalCalls(Calls))
return true;
break;
case lltok::kw_typeIdInfo:
- if (parseOptionalTypeIdInfo(TypeIdInfo))
+ if (parseOptionalTypeIdInfo(TypeIdInfo))
return true;
break;
case lltok::kw_refs:
- if (parseOptionalRefs(Refs))
+ if (parseOptionalRefs(Refs))
return true;
break;
case lltok::kw_params:
- if (parseOptionalParamAccesses(ParamAccesses))
+ if (parseOptionalParamAccesses(ParamAccesses))
return true;
break;
default:
- return error(Lex.getLoc(), "expected optional function summary field");
+ return error(Lex.getLoc(), "expected optional function summary field");
}
}
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
auto FS = std::make_unique<FunctionSummary>(
@@ -8577,7 +8577,7 @@ bool LLParser::parseFunctionSummary(std::string Name, GlobalValue::GUID GUID,
FS->setModulePath(ModulePath);
- addGlobalValueToIndex(Name, GUID, (GlobalValue::LinkageTypes)GVFlags.Linkage,
+ addGlobalValueToIndex(Name, GUID, (GlobalValue::LinkageTypes)GVFlags.Linkage,
ID, std::move(FS));
return false;
@@ -8586,7 +8586,7 @@ bool LLParser::parseFunctionSummary(std::string Name, GlobalValue::GUID GUID,
/// VariableSummary
/// ::= 'variable' ':' '(' 'module' ':' ModuleReference ',' GVFlags
/// [',' OptionalRefs]? ')'
-bool LLParser::parseVariableSummary(std::string Name, GlobalValue::GUID GUID,
+bool LLParser::parseVariableSummary(std::string Name, GlobalValue::GUID GUID,
unsigned ID) {
assert(Lex.getKind() == lltok::kw_variable);
Lex.Lex();
@@ -8601,31 +8601,31 @@ bool LLParser::parseVariableSummary(std::string Name, GlobalValue::GUID GUID,
GlobalObject::VCallVisibilityPublic);
std::vector<ValueInfo> Refs;
VTableFuncList VTableFuncs;
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here") ||
- parseModuleReference(ModulePath) ||
- parseToken(lltok::comma, "expected ',' here") || parseGVFlags(GVFlags) ||
- parseToken(lltok::comma, "expected ',' here") ||
- parseGVarFlags(GVarFlags))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here") ||
+ parseModuleReference(ModulePath) ||
+ parseToken(lltok::comma, "expected ',' here") || parseGVFlags(GVFlags) ||
+ parseToken(lltok::comma, "expected ',' here") ||
+ parseGVarFlags(GVarFlags))
return true;
- // parse optional fields
+ // parse optional fields
while (EatIfPresent(lltok::comma)) {
switch (Lex.getKind()) {
case lltok::kw_vTableFuncs:
- if (parseOptionalVTableFuncs(VTableFuncs))
+ if (parseOptionalVTableFuncs(VTableFuncs))
return true;
break;
case lltok::kw_refs:
- if (parseOptionalRefs(Refs))
+ if (parseOptionalRefs(Refs))
return true;
break;
default:
- return error(Lex.getLoc(), "expected optional variable summary field");
+ return error(Lex.getLoc(), "expected optional variable summary field");
}
}
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
auto GS =
@@ -8634,7 +8634,7 @@ bool LLParser::parseVariableSummary(std::string Name, GlobalValue::GUID GUID,
GS->setModulePath(ModulePath);
GS->setVTableFuncs(std::move(VTableFuncs));
- addGlobalValueToIndex(Name, GUID, (GlobalValue::LinkageTypes)GVFlags.Linkage,
+ addGlobalValueToIndex(Name, GUID, (GlobalValue::LinkageTypes)GVFlags.Linkage,
ID, std::move(GS));
return false;
@@ -8643,7 +8643,7 @@ bool LLParser::parseVariableSummary(std::string Name, GlobalValue::GUID GUID,
/// AliasSummary
/// ::= 'alias' ':' '(' 'module' ':' ModuleReference ',' GVFlags ','
/// 'aliasee' ':' GVReference ')'
-bool LLParser::parseAliasSummary(std::string Name, GlobalValue::GUID GUID,
+bool LLParser::parseAliasSummary(std::string Name, GlobalValue::GUID GUID,
unsigned ID) {
assert(Lex.getKind() == lltok::kw_alias);
LocTy Loc = Lex.getLoc();
@@ -8653,21 +8653,21 @@ bool LLParser::parseAliasSummary(std::string Name, GlobalValue::GUID GUID,
GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags(
/*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false,
/*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false);
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here") ||
- parseModuleReference(ModulePath) ||
- parseToken(lltok::comma, "expected ',' here") || parseGVFlags(GVFlags) ||
- parseToken(lltok::comma, "expected ',' here") ||
- parseToken(lltok::kw_aliasee, "expected 'aliasee' here") ||
- parseToken(lltok::colon, "expected ':' here"))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here") ||
+ parseModuleReference(ModulePath) ||
+ parseToken(lltok::comma, "expected ',' here") || parseGVFlags(GVFlags) ||
+ parseToken(lltok::comma, "expected ',' here") ||
+ parseToken(lltok::kw_aliasee, "expected 'aliasee' here") ||
+ parseToken(lltok::colon, "expected ':' here"))
return true;
ValueInfo AliaseeVI;
unsigned GVId;
- if (parseGVReference(AliaseeVI, GVId))
+ if (parseGVReference(AliaseeVI, GVId))
return true;
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
auto AS = std::make_unique<AliasSummary>(GVFlags);
@@ -8676,14 +8676,14 @@ bool LLParser::parseAliasSummary(std::string Name, GlobalValue::GUID GUID,
// Record forward reference if the aliasee is not parsed yet.
if (AliaseeVI.getRef() == FwdVIRef) {
- ForwardRefAliasees[GVId].emplace_back(AS.get(), Loc);
+ ForwardRefAliasees[GVId].emplace_back(AS.get(), Loc);
} else {
auto Summary = Index->findSummaryInModule(AliaseeVI, ModulePath);
assert(Summary && "Aliasee must be a definition");
AS->setAliasee(AliaseeVI, Summary);
}
- addGlobalValueToIndex(Name, GUID, (GlobalValue::LinkageTypes)GVFlags.Linkage,
+ addGlobalValueToIndex(Name, GUID, (GlobalValue::LinkageTypes)GVFlags.Linkage,
ID, std::move(AS));
return false;
@@ -8691,9 +8691,9 @@ bool LLParser::parseAliasSummary(std::string Name, GlobalValue::GUID GUID,
/// Flag
/// ::= [0|1]
-bool LLParser::parseFlag(unsigned &Val) {
+bool LLParser::parseFlag(unsigned &Val) {
if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
- return tokError("expected integer");
+ return tokError("expected integer");
Val = (unsigned)Lex.getAPSIntVal().getBoolValue();
Lex.Lex();
return false;
@@ -8706,12 +8706,12 @@ bool LLParser::parseFlag(unsigned &Val) {
/// [',' 'noInline' ':' Flag]? ')'
/// [',' 'alwaysInline' ':' Flag]? ')'
-bool LLParser::parseOptionalFFlags(FunctionSummary::FFlags &FFlags) {
+bool LLParser::parseOptionalFFlags(FunctionSummary::FFlags &FFlags) {
assert(Lex.getKind() == lltok::kw_funcFlags);
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' in funcFlags") |
- parseToken(lltok::lparen, "expected '(' in funcFlags"))
+ if (parseToken(lltok::colon, "expected ':' in funcFlags") |
+ parseToken(lltok::lparen, "expected '(' in funcFlags"))
return true;
do {
@@ -8719,46 +8719,46 @@ bool LLParser::parseOptionalFFlags(FunctionSummary::FFlags &FFlags) {
switch (Lex.getKind()) {
case lltok::kw_readNone:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
+ if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
return true;
FFlags.ReadNone = Val;
break;
case lltok::kw_readOnly:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
+ if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
return true;
FFlags.ReadOnly = Val;
break;
case lltok::kw_noRecurse:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
+ if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
return true;
FFlags.NoRecurse = Val;
break;
case lltok::kw_returnDoesNotAlias:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
+ if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
return true;
FFlags.ReturnDoesNotAlias = Val;
break;
case lltok::kw_noInline:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
+ if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
return true;
FFlags.NoInline = Val;
break;
case lltok::kw_alwaysInline:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
+ if (parseToken(lltok::colon, "expected ':'") || parseFlag(Val))
return true;
FFlags.AlwaysInline = Val;
break;
default:
- return error(Lex.getLoc(), "expected function flag type");
+ return error(Lex.getLoc(), "expected function flag type");
}
} while (EatIfPresent(lltok::comma));
- if (parseToken(lltok::rparen, "expected ')' in funcFlags"))
+ if (parseToken(lltok::rparen, "expected ')' in funcFlags"))
return true;
return false;
@@ -8768,26 +8768,26 @@ bool LLParser::parseOptionalFFlags(FunctionSummary::FFlags &FFlags) {
/// := 'calls' ':' '(' Call [',' Call]* ')'
/// Call ::= '(' 'callee' ':' GVReference
/// [( ',' 'hotness' ':' Hotness | ',' 'relbf' ':' UInt32 )]? ')'
-bool LLParser::parseOptionalCalls(std::vector<FunctionSummary::EdgeTy> &Calls) {
+bool LLParser::parseOptionalCalls(std::vector<FunctionSummary::EdgeTy> &Calls) {
assert(Lex.getKind() == lltok::kw_calls);
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' in calls") |
- parseToken(lltok::lparen, "expected '(' in calls"))
+ if (parseToken(lltok::colon, "expected ':' in calls") |
+ parseToken(lltok::lparen, "expected '(' in calls"))
return true;
IdToIndexMapType IdToIndexMap;
- // parse each call edge
+ // parse each call edge
do {
ValueInfo VI;
- if (parseToken(lltok::lparen, "expected '(' in call") ||
- parseToken(lltok::kw_callee, "expected 'callee' in call") ||
- parseToken(lltok::colon, "expected ':'"))
+ if (parseToken(lltok::lparen, "expected '(' in call") ||
+ parseToken(lltok::kw_callee, "expected 'callee' in call") ||
+ parseToken(lltok::colon, "expected ':'"))
return true;
LocTy Loc = Lex.getLoc();
unsigned GVId;
- if (parseGVReference(VI, GVId))
+ if (parseGVReference(VI, GVId))
return true;
CalleeInfo::HotnessType Hotness = CalleeInfo::HotnessType::Unknown;
@@ -8795,11 +8795,11 @@ bool LLParser::parseOptionalCalls(std::vector<FunctionSummary::EdgeTy> &Calls) {
if (EatIfPresent(lltok::comma)) {
// Expect either hotness or relbf
if (EatIfPresent(lltok::kw_hotness)) {
- if (parseToken(lltok::colon, "expected ':'") || parseHotness(Hotness))
+ if (parseToken(lltok::colon, "expected ':'") || parseHotness(Hotness))
return true;
} else {
- if (parseToken(lltok::kw_relbf, "expected relbf") ||
- parseToken(lltok::colon, "expected ':'") || parseUInt32(RelBF))
+ if (parseToken(lltok::kw_relbf, "expected relbf") ||
+ parseToken(lltok::colon, "expected ':'") || parseUInt32(RelBF))
return true;
}
}
@@ -8810,22 +8810,22 @@ bool LLParser::parseOptionalCalls(std::vector<FunctionSummary::EdgeTy> &Calls) {
IdToIndexMap[GVId].push_back(std::make_pair(Calls.size(), Loc));
Calls.push_back(FunctionSummary::EdgeTy{VI, CalleeInfo(Hotness, RelBF)});
- if (parseToken(lltok::rparen, "expected ')' in call"))
+ if (parseToken(lltok::rparen, "expected ')' in call"))
return true;
} while (EatIfPresent(lltok::comma));
// Now that the Calls vector is finalized, it is safe to save the locations
// of any forward GV references that need updating later.
for (auto I : IdToIndexMap) {
- auto &Infos = ForwardRefValueInfos[I.first];
+ auto &Infos = ForwardRefValueInfos[I.first];
for (auto P : I.second) {
assert(Calls[P.first].first.getRef() == FwdVIRef &&
"Forward referenced ValueInfo expected to be empty");
- Infos.emplace_back(&Calls[P.first].first, P.second);
+ Infos.emplace_back(&Calls[P.first].first, P.second);
}
}
- if (parseToken(lltok::rparen, "expected ')' in calls"))
+ if (parseToken(lltok::rparen, "expected ')' in calls"))
return true;
return false;
@@ -8833,7 +8833,7 @@ bool LLParser::parseOptionalCalls(std::vector<FunctionSummary::EdgeTy> &Calls) {
/// Hotness
/// := ('unknown'|'cold'|'none'|'hot'|'critical')
-bool LLParser::parseHotness(CalleeInfo::HotnessType &Hotness) {
+bool LLParser::parseHotness(CalleeInfo::HotnessType &Hotness) {
switch (Lex.getKind()) {
case lltok::kw_unknown:
Hotness = CalleeInfo::HotnessType::Unknown;
@@ -8851,7 +8851,7 @@ bool LLParser::parseHotness(CalleeInfo::HotnessType &Hotness) {
Hotness = CalleeInfo::HotnessType::Critical;
break;
default:
- return error(Lex.getLoc(), "invalid call edge hotness");
+ return error(Lex.getLoc(), "invalid call edge hotness");
}
Lex.Lex();
return false;
@@ -8860,32 +8860,32 @@ bool LLParser::parseHotness(CalleeInfo::HotnessType &Hotness) {
/// OptionalVTableFuncs
/// := 'vTableFuncs' ':' '(' VTableFunc [',' VTableFunc]* ')'
/// VTableFunc ::= '(' 'virtFunc' ':' GVReference ',' 'offset' ':' UInt64 ')'
-bool LLParser::parseOptionalVTableFuncs(VTableFuncList &VTableFuncs) {
+bool LLParser::parseOptionalVTableFuncs(VTableFuncList &VTableFuncs) {
assert(Lex.getKind() == lltok::kw_vTableFuncs);
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' in vTableFuncs") |
- parseToken(lltok::lparen, "expected '(' in vTableFuncs"))
+ if (parseToken(lltok::colon, "expected ':' in vTableFuncs") |
+ parseToken(lltok::lparen, "expected '(' in vTableFuncs"))
return true;
IdToIndexMapType IdToIndexMap;
- // parse each virtual function pair
+ // parse each virtual function pair
do {
ValueInfo VI;
- if (parseToken(lltok::lparen, "expected '(' in vTableFunc") ||
- parseToken(lltok::kw_virtFunc, "expected 'callee' in vTableFunc") ||
- parseToken(lltok::colon, "expected ':'"))
+ if (parseToken(lltok::lparen, "expected '(' in vTableFunc") ||
+ parseToken(lltok::kw_virtFunc, "expected 'callee' in vTableFunc") ||
+ parseToken(lltok::colon, "expected ':'"))
return true;
LocTy Loc = Lex.getLoc();
unsigned GVId;
- if (parseGVReference(VI, GVId))
+ if (parseGVReference(VI, GVId))
return true;
uint64_t Offset;
- if (parseToken(lltok::comma, "expected comma") ||
- parseToken(lltok::kw_offset, "expected offset") ||
- parseToken(lltok::colon, "expected ':'") || parseUInt64(Offset))
+ if (parseToken(lltok::comma, "expected comma") ||
+ parseToken(lltok::kw_offset, "expected offset") ||
+ parseToken(lltok::colon, "expected ':'") || parseUInt64(Offset))
return true;
// Keep track of the VTableFuncs array index needing a forward reference.
@@ -8895,53 +8895,53 @@ bool LLParser::parseOptionalVTableFuncs(VTableFuncList &VTableFuncs) {
IdToIndexMap[GVId].push_back(std::make_pair(VTableFuncs.size(), Loc));
VTableFuncs.push_back({VI, Offset});
- if (parseToken(lltok::rparen, "expected ')' in vTableFunc"))
+ if (parseToken(lltok::rparen, "expected ')' in vTableFunc"))
return true;
} while (EatIfPresent(lltok::comma));
// Now that the VTableFuncs vector is finalized, it is safe to save the
// locations of any forward GV references that need updating later.
for (auto I : IdToIndexMap) {
- auto &Infos = ForwardRefValueInfos[I.first];
+ auto &Infos = ForwardRefValueInfos[I.first];
for (auto P : I.second) {
assert(VTableFuncs[P.first].FuncVI == EmptyVI &&
"Forward referenced ValueInfo expected to be empty");
- Infos.emplace_back(&VTableFuncs[P.first].FuncVI, P.second);
+ Infos.emplace_back(&VTableFuncs[P.first].FuncVI, P.second);
}
}
- if (parseToken(lltok::rparen, "expected ')' in vTableFuncs"))
+ if (parseToken(lltok::rparen, "expected ')' in vTableFuncs"))
return true;
return false;
}
/// ParamNo := 'param' ':' UInt64
-bool LLParser::parseParamNo(uint64_t &ParamNo) {
- if (parseToken(lltok::kw_param, "expected 'param' here") ||
- parseToken(lltok::colon, "expected ':' here") || parseUInt64(ParamNo))
+bool LLParser::parseParamNo(uint64_t &ParamNo) {
+ if (parseToken(lltok::kw_param, "expected 'param' here") ||
+ parseToken(lltok::colon, "expected ':' here") || parseUInt64(ParamNo))
return true;
return false;
}
/// ParamAccessOffset := 'offset' ':' '[' APSINTVAL ',' APSINTVAL ']'
-bool LLParser::parseParamAccessOffset(ConstantRange &Range) {
+bool LLParser::parseParamAccessOffset(ConstantRange &Range) {
APSInt Lower;
APSInt Upper;
auto ParseAPSInt = [&](APSInt &Val) {
if (Lex.getKind() != lltok::APSInt)
- return tokError("expected integer");
+ return tokError("expected integer");
Val = Lex.getAPSIntVal();
Val = Val.extOrTrunc(FunctionSummary::ParamAccess::RangeWidth);
Val.setIsSigned(true);
Lex.Lex();
return false;
};
- if (parseToken(lltok::kw_offset, "expected 'offset' here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lsquare, "expected '[' here") || ParseAPSInt(Lower) ||
- parseToken(lltok::comma, "expected ',' here") || ParseAPSInt(Upper) ||
- parseToken(lltok::rsquare, "expected ']' here"))
+ if (parseToken(lltok::kw_offset, "expected 'offset' here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lsquare, "expected '[' here") || ParseAPSInt(Lower) ||
+ parseToken(lltok::comma, "expected ',' here") || ParseAPSInt(Upper) ||
+ parseToken(lltok::rsquare, "expected ']' here"))
return true;
++Upper;
@@ -8955,29 +8955,29 @@ bool LLParser::parseParamAccessOffset(ConstantRange &Range) {
/// ParamAccessCall
/// := '(' 'callee' ':' GVReference ',' ParamNo ',' ParamAccessOffset ')'
-bool LLParser::parseParamAccessCall(FunctionSummary::ParamAccess::Call &Call,
- IdLocListType &IdLocList) {
- if (parseToken(lltok::lparen, "expected '(' here") ||
- parseToken(lltok::kw_callee, "expected 'callee' here") ||
- parseToken(lltok::colon, "expected ':' here"))
+bool LLParser::parseParamAccessCall(FunctionSummary::ParamAccess::Call &Call,
+ IdLocListType &IdLocList) {
+ if (parseToken(lltok::lparen, "expected '(' here") ||
+ parseToken(lltok::kw_callee, "expected 'callee' here") ||
+ parseToken(lltok::colon, "expected ':' here"))
return true;
unsigned GVId;
ValueInfo VI;
- LocTy Loc = Lex.getLoc();
- if (parseGVReference(VI, GVId))
+ LocTy Loc = Lex.getLoc();
+ if (parseGVReference(VI, GVId))
return true;
- Call.Callee = VI;
- IdLocList.emplace_back(GVId, Loc);
+ Call.Callee = VI;
+ IdLocList.emplace_back(GVId, Loc);
- if (parseToken(lltok::comma, "expected ',' here") ||
- parseParamNo(Call.ParamNo) ||
- parseToken(lltok::comma, "expected ',' here") ||
- parseParamAccessOffset(Call.Offsets))
+ if (parseToken(lltok::comma, "expected ',' here") ||
+ parseParamNo(Call.ParamNo) ||
+ parseToken(lltok::comma, "expected ',' here") ||
+ parseParamAccessOffset(Call.Offsets))
return true;
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
return false;
@@ -8986,31 +8986,31 @@ bool LLParser::parseParamAccessCall(FunctionSummary::ParamAccess::Call &Call,
/// ParamAccess
/// := '(' ParamNo ',' ParamAccessOffset [',' OptionalParamAccessCalls]? ')'
/// OptionalParamAccessCalls := '(' Call [',' Call]* ')'
-bool LLParser::parseParamAccess(FunctionSummary::ParamAccess &Param,
- IdLocListType &IdLocList) {
- if (parseToken(lltok::lparen, "expected '(' here") ||
- parseParamNo(Param.ParamNo) ||
- parseToken(lltok::comma, "expected ',' here") ||
- parseParamAccessOffset(Param.Use))
+bool LLParser::parseParamAccess(FunctionSummary::ParamAccess &Param,
+ IdLocListType &IdLocList) {
+ if (parseToken(lltok::lparen, "expected '(' here") ||
+ parseParamNo(Param.ParamNo) ||
+ parseToken(lltok::comma, "expected ',' here") ||
+ parseParamAccessOffset(Param.Use))
return true;
if (EatIfPresent(lltok::comma)) {
- if (parseToken(lltok::kw_calls, "expected 'calls' here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here"))
+ if (parseToken(lltok::kw_calls, "expected 'calls' here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here"))
return true;
do {
FunctionSummary::ParamAccess::Call Call;
- if (parseParamAccessCall(Call, IdLocList))
+ if (parseParamAccessCall(Call, IdLocList))
return true;
Param.Calls.push_back(Call);
} while (EatIfPresent(lltok::comma));
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
}
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
return false;
@@ -9018,53 +9018,53 @@ bool LLParser::parseParamAccess(FunctionSummary::ParamAccess &Param,
/// OptionalParamAccesses
/// := 'params' ':' '(' ParamAccess [',' ParamAccess]* ')'
-bool LLParser::parseOptionalParamAccesses(
+bool LLParser::parseOptionalParamAccesses(
std::vector<FunctionSummary::ParamAccess> &Params) {
assert(Lex.getKind() == lltok::kw_params);
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here"))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here"))
return true;
- IdLocListType VContexts;
- size_t CallsNum = 0;
+ IdLocListType VContexts;
+ size_t CallsNum = 0;
do {
FunctionSummary::ParamAccess ParamAccess;
- if (parseParamAccess(ParamAccess, VContexts))
+ if (parseParamAccess(ParamAccess, VContexts))
return true;
- CallsNum += ParamAccess.Calls.size();
- assert(VContexts.size() == CallsNum);
- Params.emplace_back(std::move(ParamAccess));
+ CallsNum += ParamAccess.Calls.size();
+ assert(VContexts.size() == CallsNum);
+ Params.emplace_back(std::move(ParamAccess));
} while (EatIfPresent(lltok::comma));
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
- // Now that the Params is finalized, it is safe to save the locations
- // of any forward GV references that need updating later.
- IdLocListType::const_iterator ItContext = VContexts.begin();
- for (auto &PA : Params) {
- for (auto &C : PA.Calls) {
- if (C.Callee.getRef() == FwdVIRef)
- ForwardRefValueInfos[ItContext->first].emplace_back(&C.Callee,
- ItContext->second);
- ++ItContext;
- }
- }
- assert(ItContext == VContexts.end());
-
+ // Now that the Params is finalized, it is safe to save the locations
+ // of any forward GV references that need updating later.
+ IdLocListType::const_iterator ItContext = VContexts.begin();
+ for (auto &PA : Params) {
+ for (auto &C : PA.Calls) {
+ if (C.Callee.getRef() == FwdVIRef)
+ ForwardRefValueInfos[ItContext->first].emplace_back(&C.Callee,
+ ItContext->second);
+ ++ItContext;
+ }
+ }
+ assert(ItContext == VContexts.end());
+
return false;
}
/// OptionalRefs
/// := 'refs' ':' '(' GVReference [',' GVReference]* ')'
-bool LLParser::parseOptionalRefs(std::vector<ValueInfo> &Refs) {
+bool LLParser::parseOptionalRefs(std::vector<ValueInfo> &Refs) {
assert(Lex.getKind() == lltok::kw_refs);
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' in refs") ||
- parseToken(lltok::lparen, "expected '(' in refs"))
+ if (parseToken(lltok::colon, "expected ':' in refs") ||
+ parseToken(lltok::lparen, "expected '(' in refs"))
return true;
struct ValueContext {
@@ -9073,11 +9073,11 @@ bool LLParser::parseOptionalRefs(std::vector<ValueInfo> &Refs) {
LocTy Loc;
};
std::vector<ValueContext> VContexts;
- // parse each ref edge
+ // parse each ref edge
do {
ValueContext VC;
VC.Loc = Lex.getLoc();
- if (parseGVReference(VC.VI, VC.GVId))
+ if (parseGVReference(VC.VI, VC.GVId))
return true;
VContexts.push_back(VC);
} while (EatIfPresent(lltok::comma));
@@ -9102,15 +9102,15 @@ bool LLParser::parseOptionalRefs(std::vector<ValueInfo> &Refs) {
// Now that the Refs vector is finalized, it is safe to save the locations
// of any forward GV references that need updating later.
for (auto I : IdToIndexMap) {
- auto &Infos = ForwardRefValueInfos[I.first];
+ auto &Infos = ForwardRefValueInfos[I.first];
for (auto P : I.second) {
assert(Refs[P.first].getRef() == FwdVIRef &&
"Forward referenced ValueInfo expected to be empty");
- Infos.emplace_back(&Refs[P.first], P.second);
+ Infos.emplace_back(&Refs[P.first], P.second);
}
}
- if (parseToken(lltok::rparen, "expected ')' in refs"))
+ if (parseToken(lltok::rparen, "expected ')' in refs"))
return true;
return false;
@@ -9120,47 +9120,47 @@ bool LLParser::parseOptionalRefs(std::vector<ValueInfo> &Refs) {
/// := 'typeidinfo' ':' '(' [',' TypeTests]? [',' TypeTestAssumeVCalls]?
/// [',' TypeCheckedLoadVCalls]? [',' TypeTestAssumeConstVCalls]?
/// [',' TypeCheckedLoadConstVCalls]? ')'
-bool LLParser::parseOptionalTypeIdInfo(
+bool LLParser::parseOptionalTypeIdInfo(
FunctionSummary::TypeIdInfo &TypeIdInfo) {
assert(Lex.getKind() == lltok::kw_typeIdInfo);
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' in typeIdInfo"))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' in typeIdInfo"))
return true;
do {
switch (Lex.getKind()) {
case lltok::kw_typeTests:
- if (parseTypeTests(TypeIdInfo.TypeTests))
+ if (parseTypeTests(TypeIdInfo.TypeTests))
return true;
break;
case lltok::kw_typeTestAssumeVCalls:
- if (parseVFuncIdList(lltok::kw_typeTestAssumeVCalls,
+ if (parseVFuncIdList(lltok::kw_typeTestAssumeVCalls,
TypeIdInfo.TypeTestAssumeVCalls))
return true;
break;
case lltok::kw_typeCheckedLoadVCalls:
- if (parseVFuncIdList(lltok::kw_typeCheckedLoadVCalls,
+ if (parseVFuncIdList(lltok::kw_typeCheckedLoadVCalls,
TypeIdInfo.TypeCheckedLoadVCalls))
return true;
break;
case lltok::kw_typeTestAssumeConstVCalls:
- if (parseConstVCallList(lltok::kw_typeTestAssumeConstVCalls,
+ if (parseConstVCallList(lltok::kw_typeTestAssumeConstVCalls,
TypeIdInfo.TypeTestAssumeConstVCalls))
return true;
break;
case lltok::kw_typeCheckedLoadConstVCalls:
- if (parseConstVCallList(lltok::kw_typeCheckedLoadConstVCalls,
+ if (parseConstVCallList(lltok::kw_typeCheckedLoadConstVCalls,
TypeIdInfo.TypeCheckedLoadConstVCalls))
return true;
break;
default:
- return error(Lex.getLoc(), "invalid typeIdInfo list type");
+ return error(Lex.getLoc(), "invalid typeIdInfo list type");
}
} while (EatIfPresent(lltok::comma));
- if (parseToken(lltok::rparen, "expected ')' in typeIdInfo"))
+ if (parseToken(lltok::rparen, "expected ')' in typeIdInfo"))
return true;
return false;
@@ -9169,12 +9169,12 @@ bool LLParser::parseOptionalTypeIdInfo(
/// TypeTests
/// ::= 'typeTests' ':' '(' (SummaryID | UInt64)
/// [',' (SummaryID | UInt64)]* ')'
-bool LLParser::parseTypeTests(std::vector<GlobalValue::GUID> &TypeTests) {
+bool LLParser::parseTypeTests(std::vector<GlobalValue::GUID> &TypeTests) {
assert(Lex.getKind() == lltok::kw_typeTests);
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' in typeIdInfo"))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' in typeIdInfo"))
return true;
IdToIndexMapType IdToIndexMap;
@@ -9188,7 +9188,7 @@ bool LLParser::parseTypeTests(std::vector<GlobalValue::GUID> &TypeTests) {
// can only do so once the std::vector is finalized.
IdToIndexMap[ID].push_back(std::make_pair(TypeTests.size(), Loc));
Lex.Lex();
- } else if (parseUInt64(GUID))
+ } else if (parseUInt64(GUID))
return true;
TypeTests.push_back(GUID);
} while (EatIfPresent(lltok::comma));
@@ -9196,15 +9196,15 @@ bool LLParser::parseTypeTests(std::vector<GlobalValue::GUID> &TypeTests) {
// Now that the TypeTests vector is finalized, it is safe to save the
// locations of any forward GV references that need updating later.
for (auto I : IdToIndexMap) {
- auto &Ids = ForwardRefTypeIds[I.first];
+ auto &Ids = ForwardRefTypeIds[I.first];
for (auto P : I.second) {
assert(TypeTests[P.first] == 0 &&
"Forward referenced type id GUID expected to be 0");
- Ids.emplace_back(&TypeTests[P.first], P.second);
+ Ids.emplace_back(&TypeTests[P.first], P.second);
}
}
- if (parseToken(lltok::rparen, "expected ')' in typeIdInfo"))
+ if (parseToken(lltok::rparen, "expected ')' in typeIdInfo"))
return true;
return false;
@@ -9212,34 +9212,34 @@ bool LLParser::parseTypeTests(std::vector<GlobalValue::GUID> &TypeTests) {
/// VFuncIdList
/// ::= Kind ':' '(' VFuncId [',' VFuncId]* ')'
-bool LLParser::parseVFuncIdList(
+bool LLParser::parseVFuncIdList(
lltok::Kind Kind, std::vector<FunctionSummary::VFuncId> &VFuncIdList) {
assert(Lex.getKind() == Kind);
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here"))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here"))
return true;
IdToIndexMapType IdToIndexMap;
do {
FunctionSummary::VFuncId VFuncId;
- if (parseVFuncId(VFuncId, IdToIndexMap, VFuncIdList.size()))
+ if (parseVFuncId(VFuncId, IdToIndexMap, VFuncIdList.size()))
return true;
VFuncIdList.push_back(VFuncId);
} while (EatIfPresent(lltok::comma));
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
// Now that the VFuncIdList vector is finalized, it is safe to save the
// locations of any forward GV references that need updating later.
for (auto I : IdToIndexMap) {
- auto &Ids = ForwardRefTypeIds[I.first];
+ auto &Ids = ForwardRefTypeIds[I.first];
for (auto P : I.second) {
assert(VFuncIdList[P.first].GUID == 0 &&
"Forward referenced type id GUID expected to be 0");
- Ids.emplace_back(&VFuncIdList[P.first].GUID, P.second);
+ Ids.emplace_back(&VFuncIdList[P.first].GUID, P.second);
}
}
@@ -9248,35 +9248,35 @@ bool LLParser::parseVFuncIdList(
/// ConstVCallList
/// ::= Kind ':' '(' ConstVCall [',' ConstVCall]* ')'
-bool LLParser::parseConstVCallList(
+bool LLParser::parseConstVCallList(
lltok::Kind Kind,
std::vector<FunctionSummary::ConstVCall> &ConstVCallList) {
assert(Lex.getKind() == Kind);
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here"))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here"))
return true;
IdToIndexMapType IdToIndexMap;
do {
FunctionSummary::ConstVCall ConstVCall;
- if (parseConstVCall(ConstVCall, IdToIndexMap, ConstVCallList.size()))
+ if (parseConstVCall(ConstVCall, IdToIndexMap, ConstVCallList.size()))
return true;
ConstVCallList.push_back(ConstVCall);
} while (EatIfPresent(lltok::comma));
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
// Now that the ConstVCallList vector is finalized, it is safe to save the
// locations of any forward GV references that need updating later.
for (auto I : IdToIndexMap) {
- auto &Ids = ForwardRefTypeIds[I.first];
+ auto &Ids = ForwardRefTypeIds[I.first];
for (auto P : I.second) {
assert(ConstVCallList[P.first].VFunc.GUID == 0 &&
"Forward referenced type id GUID expected to be 0");
- Ids.emplace_back(&ConstVCallList[P.first].VFunc.GUID, P.second);
+ Ids.emplace_back(&ConstVCallList[P.first].VFunc.GUID, P.second);
}
}
@@ -9285,17 +9285,17 @@ bool LLParser::parseConstVCallList(
/// ConstVCall
/// ::= '(' VFuncId ',' Args ')'
-bool LLParser::parseConstVCall(FunctionSummary::ConstVCall &ConstVCall,
+bool LLParser::parseConstVCall(FunctionSummary::ConstVCall &ConstVCall,
IdToIndexMapType &IdToIndexMap, unsigned Index) {
- if (parseToken(lltok::lparen, "expected '(' here") ||
- parseVFuncId(ConstVCall.VFunc, IdToIndexMap, Index))
+ if (parseToken(lltok::lparen, "expected '(' here") ||
+ parseVFuncId(ConstVCall.VFunc, IdToIndexMap, Index))
return true;
if (EatIfPresent(lltok::comma))
- if (parseArgs(ConstVCall.Args))
+ if (parseArgs(ConstVCall.Args))
return true;
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
return false;
@@ -9304,13 +9304,13 @@ bool LLParser::parseConstVCall(FunctionSummary::ConstVCall &ConstVCall,
/// VFuncId
/// ::= 'vFuncId' ':' '(' (SummaryID | 'guid' ':' UInt64) ','
/// 'offset' ':' UInt64 ')'
-bool LLParser::parseVFuncId(FunctionSummary::VFuncId &VFuncId,
+bool LLParser::parseVFuncId(FunctionSummary::VFuncId &VFuncId,
IdToIndexMapType &IdToIndexMap, unsigned Index) {
assert(Lex.getKind() == lltok::kw_vFuncId);
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here"))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here"))
return true;
if (Lex.getKind() == lltok::SummaryID) {
@@ -9322,16 +9322,16 @@ bool LLParser::parseVFuncId(FunctionSummary::VFuncId &VFuncId,
// can only do so once the caller's std::vector is finalized.
IdToIndexMap[ID].push_back(std::make_pair(Index, Loc));
Lex.Lex();
- } else if (parseToken(lltok::kw_guid, "expected 'guid' here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseUInt64(VFuncId.GUID))
+ } else if (parseToken(lltok::kw_guid, "expected 'guid' here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseUInt64(VFuncId.GUID))
return true;
- if (parseToken(lltok::comma, "expected ',' here") ||
- parseToken(lltok::kw_offset, "expected 'offset' here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseUInt64(VFuncId.Offset) ||
- parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::comma, "expected ',' here") ||
+ parseToken(lltok::kw_offset, "expected 'offset' here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseUInt64(VFuncId.Offset) ||
+ parseToken(lltok::rparen, "expected ')' here"))
return true;
return false;
@@ -9341,12 +9341,12 @@ bool LLParser::parseVFuncId(FunctionSummary::VFuncId &VFuncId,
/// ::= 'flags' ':' '(' 'linkage' ':' OptionalLinkageAux ','
/// 'notEligibleToImport' ':' Flag ',' 'live' ':' Flag ','
/// 'dsoLocal' ':' Flag ',' 'canAutoHide' ':' Flag ')'
-bool LLParser::parseGVFlags(GlobalValueSummary::GVFlags &GVFlags) {
+bool LLParser::parseGVFlags(GlobalValueSummary::GVFlags &GVFlags) {
assert(Lex.getKind() == lltok::kw_flags);
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here"))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here"))
return true;
do {
@@ -9354,7 +9354,7 @@ bool LLParser::parseGVFlags(GlobalValueSummary::GVFlags &GVFlags) {
switch (Lex.getKind()) {
case lltok::kw_linkage:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':'"))
+ if (parseToken(lltok::colon, "expected ':'"))
return true;
bool HasLinkage;
GVFlags.Linkage = parseOptionalLinkageAux(Lex.getKind(), HasLinkage);
@@ -9363,34 +9363,34 @@ bool LLParser::parseGVFlags(GlobalValueSummary::GVFlags &GVFlags) {
break;
case lltok::kw_notEligibleToImport:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':'") || parseFlag(Flag))
+ if (parseToken(lltok::colon, "expected ':'") || parseFlag(Flag))
return true;
GVFlags.NotEligibleToImport = Flag;
break;
case lltok::kw_live:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':'") || parseFlag(Flag))
+ if (parseToken(lltok::colon, "expected ':'") || parseFlag(Flag))
return true;
GVFlags.Live = Flag;
break;
case lltok::kw_dsoLocal:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':'") || parseFlag(Flag))
+ if (parseToken(lltok::colon, "expected ':'") || parseFlag(Flag))
return true;
GVFlags.DSOLocal = Flag;
break;
case lltok::kw_canAutoHide:
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':'") || parseFlag(Flag))
+ if (parseToken(lltok::colon, "expected ':'") || parseFlag(Flag))
return true;
GVFlags.CanAutoHide = Flag;
break;
default:
- return error(Lex.getLoc(), "expected gv flag type");
+ return error(Lex.getLoc(), "expected gv flag type");
}
} while (EatIfPresent(lltok::comma));
- if (parseToken(lltok::rparen, "expected ')' here"))
+ if (parseToken(lltok::rparen, "expected ')' here"))
return true;
return false;
@@ -9400,19 +9400,19 @@ bool LLParser::parseGVFlags(GlobalValueSummary::GVFlags &GVFlags) {
/// ::= 'varFlags' ':' '(' 'readonly' ':' Flag
/// ',' 'writeonly' ':' Flag
/// ',' 'constant' ':' Flag ')'
-bool LLParser::parseGVarFlags(GlobalVarSummary::GVarFlags &GVarFlags) {
+bool LLParser::parseGVarFlags(GlobalVarSummary::GVarFlags &GVarFlags) {
assert(Lex.getKind() == lltok::kw_varFlags);
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::lparen, "expected '(' here"))
+ if (parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::lparen, "expected '(' here"))
return true;
auto ParseRest = [this](unsigned int &Val) {
Lex.Lex();
- if (parseToken(lltok::colon, "expected ':'"))
+ if (parseToken(lltok::colon, "expected ':'"))
return true;
- return parseFlag(Val);
+ return parseFlag(Val);
};
do {
@@ -9439,19 +9439,19 @@ bool LLParser::parseGVarFlags(GlobalVarSummary::GVarFlags &GVarFlags) {
GVarFlags.VCallVisibility = Flag;
break;
default:
- return error(Lex.getLoc(), "expected gvar flag type");
+ return error(Lex.getLoc(), "expected gvar flag type");
}
} while (EatIfPresent(lltok::comma));
- return parseToken(lltok::rparen, "expected ')' here");
+ return parseToken(lltok::rparen, "expected ')' here");
}
/// ModuleReference
/// ::= 'module' ':' UInt
-bool LLParser::parseModuleReference(StringRef &ModulePath) {
- // parse module id.
- if (parseToken(lltok::kw_module, "expected 'module' here") ||
- parseToken(lltok::colon, "expected ':' here") ||
- parseToken(lltok::SummaryID, "expected module ID"))
+bool LLParser::parseModuleReference(StringRef &ModulePath) {
+ // parse module id.
+ if (parseToken(lltok::kw_module, "expected 'module' here") ||
+ parseToken(lltok::colon, "expected ':' here") ||
+ parseToken(lltok::SummaryID, "expected module ID"))
return true;
unsigned ModuleID = Lex.getUIntVal();
@@ -9464,11 +9464,11 @@ bool LLParser::parseModuleReference(StringRef &ModulePath) {
/// GVReference
/// ::= SummaryID
-bool LLParser::parseGVReference(ValueInfo &VI, unsigned &GVId) {
+bool LLParser::parseGVReference(ValueInfo &VI, unsigned &GVId) {
bool WriteOnly = false, ReadOnly = EatIfPresent(lltok::kw_readonly);
if (!ReadOnly)
WriteOnly = EatIfPresent(lltok::kw_writeonly);
- if (parseToken(lltok::SummaryID, "expected GV ID"))
+ if (parseToken(lltok::SummaryID, "expected GV ID"))
return true;
GVId = Lex.getUIntVal();
diff --git a/contrib/libs/llvm12/lib/AsmParser/LLParser.h b/contrib/libs/llvm12/lib/AsmParser/LLParser.h
index 7d35eae53c..aa79823ce9 100644
--- a/contrib/libs/llvm12/lib/AsmParser/LLParser.h
+++ b/contrib/libs/llvm12/lib/AsmParser/LLParser.h
@@ -46,7 +46,7 @@ namespace llvm {
t_LocalID, t_GlobalID, // ID in UIntVal.
t_LocalName, t_GlobalName, // Name in StrVal.
t_APSInt, t_APFloat, // Value in APSIntVal/APFloatVal.
- t_Null, t_Undef, t_Zero, t_None, t_Poison, // No value.
+ t_Null, t_Undef, t_Zero, t_None, t_Poison, // No value.
t_EmptyArray, // No value: []
t_Constant, // Value in ConstantVal.
t_InlineAsm, // Value in FTy/StrVal/StrVal2/UIntVal.
@@ -166,8 +166,8 @@ namespace llvm {
: Context(Context), Lex(F, SM, Err, Context), M(M), Index(Index),
Slots(Slots), BlockAddressPFS(nullptr) {}
bool Run(
- bool UpgradeDebugInfo, DataLayoutCallbackTy DataLayoutCallback =
- [](StringRef) { return None; });
+ bool UpgradeDebugInfo, DataLayoutCallbackTy DataLayoutCallback =
+ [](StringRef) { return None; });
bool parseStandaloneConstantValue(Constant *&C, const SlotMapping *Slots);
@@ -177,26 +177,26 @@ namespace llvm {
LLVMContext &getContext() { return Context; }
private:
- bool error(LocTy L, const Twine &Msg) const { return Lex.Error(L, Msg); }
- bool tokError(const Twine &Msg) const { return error(Lex.getLoc(), Msg); }
+ bool error(LocTy L, const Twine &Msg) const { return Lex.Error(L, Msg); }
+ bool tokError(const Twine &Msg) const { return error(Lex.getLoc(), Msg); }
/// Restore the internal name and slot mappings using the mappings that
/// were created at an earlier parsing stage.
void restoreParsingState(const SlotMapping *Slots);
- /// getGlobalVal - Get a value with the specified name or ID, creating a
+ /// getGlobalVal - Get a value with the specified name or ID, creating a
/// forward reference record if needed. This can return null if the value
/// exists but does not have the right type.
- GlobalValue *getGlobalVal(const std::string &N, Type *Ty, LocTy Loc,
+ GlobalValue *getGlobalVal(const std::string &N, Type *Ty, LocTy Loc,
bool IsCall);
- GlobalValue *getGlobalVal(unsigned ID, Type *Ty, LocTy Loc, bool IsCall);
+ GlobalValue *getGlobalVal(unsigned ID, Type *Ty, LocTy Loc, bool IsCall);
/// Get a Comdat with the specified name, creating a forward reference
/// record if needed.
Comdat *getComdat(const std::string &Name, LocTy Loc);
// Helper Routines.
- bool parseToken(lltok::Kind T, const char *ErrMsg);
+ bool parseToken(lltok::Kind T, const char *ErrMsg);
bool EatIfPresent(lltok::Kind T) {
if (Lex.getKind() != T) return false;
Lex.Lex();
@@ -223,7 +223,7 @@ namespace llvm {
return FMF;
}
- bool parseOptionalToken(lltok::Kind T, bool &Present,
+ bool parseOptionalToken(lltok::Kind T, bool &Present,
LocTy *Loc = nullptr) {
if (Lex.getKind() != T) {
Present = false;
@@ -235,81 +235,81 @@ namespace llvm {
}
return false;
}
- bool parseStringConstant(std::string &Result);
- bool parseUInt32(unsigned &Val);
- bool parseUInt32(unsigned &Val, LocTy &Loc) {
+ bool parseStringConstant(std::string &Result);
+ bool parseUInt32(unsigned &Val);
+ bool parseUInt32(unsigned &Val, LocTy &Loc) {
Loc = Lex.getLoc();
- return parseUInt32(Val);
+ return parseUInt32(Val);
}
- bool parseUInt64(uint64_t &Val);
- bool parseUInt64(uint64_t &Val, LocTy &Loc) {
+ bool parseUInt64(uint64_t &Val);
+ bool parseUInt64(uint64_t &Val, LocTy &Loc) {
Loc = Lex.getLoc();
- return parseUInt64(Val);
+ return parseUInt64(Val);
}
- bool parseFlag(unsigned &Val);
+ bool parseFlag(unsigned &Val);
- bool parseStringAttribute(AttrBuilder &B);
+ bool parseStringAttribute(AttrBuilder &B);
- bool parseTLSModel(GlobalVariable::ThreadLocalMode &TLM);
- bool parseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM);
- bool parseOptionalUnnamedAddr(GlobalVariable::UnnamedAddr &UnnamedAddr);
- bool parseOptionalAddrSpace(unsigned &AddrSpace, unsigned DefaultAS = 0);
- bool parseOptionalProgramAddrSpace(unsigned &AddrSpace) {
- return parseOptionalAddrSpace(
+ bool parseTLSModel(GlobalVariable::ThreadLocalMode &TLM);
+ bool parseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM);
+ bool parseOptionalUnnamedAddr(GlobalVariable::UnnamedAddr &UnnamedAddr);
+ bool parseOptionalAddrSpace(unsigned &AddrSpace, unsigned DefaultAS = 0);
+ bool parseOptionalProgramAddrSpace(unsigned &AddrSpace) {
+ return parseOptionalAddrSpace(
AddrSpace, M->getDataLayout().getProgramAddressSpace());
};
- bool parseOptionalParamAttrs(AttrBuilder &B);
- bool parseOptionalReturnAttrs(AttrBuilder &B);
- bool parseOptionalLinkage(unsigned &Res, bool &HasLinkage,
+ bool parseOptionalParamAttrs(AttrBuilder &B);
+ bool parseOptionalReturnAttrs(AttrBuilder &B);
+ bool parseOptionalLinkage(unsigned &Res, bool &HasLinkage,
unsigned &Visibility, unsigned &DLLStorageClass,
bool &DSOLocal);
- void parseOptionalDSOLocal(bool &DSOLocal);
- void parseOptionalVisibility(unsigned &Res);
- void parseOptionalDLLStorageClass(unsigned &Res);
- bool parseOptionalCallingConv(unsigned &CC);
- bool parseOptionalAlignment(MaybeAlign &Alignment,
+ void parseOptionalDSOLocal(bool &DSOLocal);
+ void parseOptionalVisibility(unsigned &Res);
+ void parseOptionalDLLStorageClass(unsigned &Res);
+ bool parseOptionalCallingConv(unsigned &CC);
+ bool parseOptionalAlignment(MaybeAlign &Alignment,
bool AllowParens = false);
- bool parseOptionalDerefAttrBytes(lltok::Kind AttrKind, uint64_t &Bytes);
- bool parseScopeAndOrdering(bool IsAtomic, SyncScope::ID &SSID,
+ bool parseOptionalDerefAttrBytes(lltok::Kind AttrKind, uint64_t &Bytes);
+ bool parseScopeAndOrdering(bool IsAtomic, SyncScope::ID &SSID,
AtomicOrdering &Ordering);
- bool parseScope(SyncScope::ID &SSID);
- bool parseOrdering(AtomicOrdering &Ordering);
- bool parseOptionalStackAlignment(unsigned &Alignment);
- bool parseOptionalCommaAlign(MaybeAlign &Alignment, bool &AteExtraComma);
- bool parseOptionalCommaAddrSpace(unsigned &AddrSpace, LocTy &Loc,
+ bool parseScope(SyncScope::ID &SSID);
+ bool parseOrdering(AtomicOrdering &Ordering);
+ bool parseOptionalStackAlignment(unsigned &Alignment);
+ bool parseOptionalCommaAlign(MaybeAlign &Alignment, bool &AteExtraComma);
+ bool parseOptionalCommaAddrSpace(unsigned &AddrSpace, LocTy &Loc,
bool &AteExtraComma);
- bool parseOptionalCommaInAlloca(bool &IsInAlloca);
+ bool parseOptionalCommaInAlloca(bool &IsInAlloca);
bool parseAllocSizeArguments(unsigned &BaseSizeArg,
Optional<unsigned> &HowManyArg);
- bool parseIndexList(SmallVectorImpl<unsigned> &Indices,
+ bool parseIndexList(SmallVectorImpl<unsigned> &Indices,
bool &AteExtraComma);
- bool parseIndexList(SmallVectorImpl<unsigned> &Indices) {
+ bool parseIndexList(SmallVectorImpl<unsigned> &Indices) {
bool AteExtraComma;
- if (parseIndexList(Indices, AteExtraComma))
- return true;
+ if (parseIndexList(Indices, AteExtraComma))
+ return true;
if (AteExtraComma)
- return tokError("expected index");
+ return tokError("expected index");
return false;
}
// Top-Level Entities
- bool parseTopLevelEntities();
- bool validateEndOfModule(bool UpgradeDebugInfo);
- bool validateEndOfIndex();
- bool parseTargetDefinitions();
- bool parseTargetDefinition();
- bool parseModuleAsm();
- bool parseSourceFileName();
- bool parseDepLibs(); // FIXME: Remove in 4.0.
- bool parseUnnamedType();
- bool parseNamedType();
- bool parseDeclare();
- bool parseDefine();
-
- bool parseGlobalType(bool &IsConstant);
- bool parseUnnamedGlobal();
- bool parseNamedGlobal();
- bool parseGlobal(const std::string &Name, LocTy NameLoc, unsigned Linkage,
+ bool parseTopLevelEntities();
+ bool validateEndOfModule(bool UpgradeDebugInfo);
+ bool validateEndOfIndex();
+ bool parseTargetDefinitions();
+ bool parseTargetDefinition();
+ bool parseModuleAsm();
+ bool parseSourceFileName();
+ bool parseDepLibs(); // FIXME: Remove in 4.0.
+ bool parseUnnamedType();
+ bool parseNamedType();
+ bool parseDeclare();
+ bool parseDefine();
+
+ bool parseGlobalType(bool &IsConstant);
+ bool parseUnnamedGlobal();
+ bool parseNamedGlobal();
+ bool parseGlobal(const std::string &Name, LocTy NameLoc, unsigned Linkage,
bool HasLinkage, unsigned Visibility,
unsigned DLLStorageClass, bool DSOLocal,
GlobalVariable::ThreadLocalMode TLM,
@@ -320,96 +320,96 @@ namespace llvm {
GlobalVariable::ThreadLocalMode TLM,
GlobalVariable::UnnamedAddr UnnamedAddr);
bool parseComdat();
- bool parseStandaloneMetadata();
- bool parseNamedMetadata();
- bool parseMDString(MDString *&Result);
- bool parseMDNodeID(MDNode *&Result);
- bool parseUnnamedAttrGrp();
- bool parseFnAttributeValuePairs(AttrBuilder &B,
+ bool parseStandaloneMetadata();
+ bool parseNamedMetadata();
+ bool parseMDString(MDString *&Result);
+ bool parseMDNodeID(MDNode *&Result);
+ bool parseUnnamedAttrGrp();
+ bool parseFnAttributeValuePairs(AttrBuilder &B,
std::vector<unsigned> &FwdRefAttrGrps,
bool inAttrGrp, LocTy &BuiltinLoc);
- bool parseRequiredTypeAttr(Type *&Result, lltok::Kind AttrName);
- bool parsePreallocated(Type *&Result);
- bool parseByRef(Type *&Result);
+ bool parseRequiredTypeAttr(Type *&Result, lltok::Kind AttrName);
+ bool parsePreallocated(Type *&Result);
+ bool parseByRef(Type *&Result);
// Module Summary Index Parsing.
- bool skipModuleSummaryEntry();
- bool parseSummaryEntry();
- bool parseModuleEntry(unsigned ID);
- bool parseModuleReference(StringRef &ModulePath);
- bool parseGVReference(ValueInfo &VI, unsigned &GVId);
- bool parseSummaryIndexFlags();
- bool parseBlockCount();
- bool parseGVEntry(unsigned ID);
- bool parseFunctionSummary(std::string Name, GlobalValue::GUID, unsigned ID);
- bool parseVariableSummary(std::string Name, GlobalValue::GUID, unsigned ID);
- bool parseAliasSummary(std::string Name, GlobalValue::GUID, unsigned ID);
- bool parseGVFlags(GlobalValueSummary::GVFlags &GVFlags);
- bool parseGVarFlags(GlobalVarSummary::GVarFlags &GVarFlags);
- bool parseOptionalFFlags(FunctionSummary::FFlags &FFlags);
- bool parseOptionalCalls(std::vector<FunctionSummary::EdgeTy> &Calls);
- bool parseHotness(CalleeInfo::HotnessType &Hotness);
- bool parseOptionalTypeIdInfo(FunctionSummary::TypeIdInfo &TypeIdInfo);
- bool parseTypeTests(std::vector<GlobalValue::GUID> &TypeTests);
- bool parseVFuncIdList(lltok::Kind Kind,
+ bool skipModuleSummaryEntry();
+ bool parseSummaryEntry();
+ bool parseModuleEntry(unsigned ID);
+ bool parseModuleReference(StringRef &ModulePath);
+ bool parseGVReference(ValueInfo &VI, unsigned &GVId);
+ bool parseSummaryIndexFlags();
+ bool parseBlockCount();
+ bool parseGVEntry(unsigned ID);
+ bool parseFunctionSummary(std::string Name, GlobalValue::GUID, unsigned ID);
+ bool parseVariableSummary(std::string Name, GlobalValue::GUID, unsigned ID);
+ bool parseAliasSummary(std::string Name, GlobalValue::GUID, unsigned ID);
+ bool parseGVFlags(GlobalValueSummary::GVFlags &GVFlags);
+ bool parseGVarFlags(GlobalVarSummary::GVarFlags &GVarFlags);
+ bool parseOptionalFFlags(FunctionSummary::FFlags &FFlags);
+ bool parseOptionalCalls(std::vector<FunctionSummary::EdgeTy> &Calls);
+ bool parseHotness(CalleeInfo::HotnessType &Hotness);
+ bool parseOptionalTypeIdInfo(FunctionSummary::TypeIdInfo &TypeIdInfo);
+ bool parseTypeTests(std::vector<GlobalValue::GUID> &TypeTests);
+ bool parseVFuncIdList(lltok::Kind Kind,
std::vector<FunctionSummary::VFuncId> &VFuncIdList);
- bool parseConstVCallList(
+ bool parseConstVCallList(
lltok::Kind Kind,
std::vector<FunctionSummary::ConstVCall> &ConstVCallList);
using IdToIndexMapType =
std::map<unsigned, std::vector<std::pair<unsigned, LocTy>>>;
- bool parseConstVCall(FunctionSummary::ConstVCall &ConstVCall,
+ bool parseConstVCall(FunctionSummary::ConstVCall &ConstVCall,
IdToIndexMapType &IdToIndexMap, unsigned Index);
- bool parseVFuncId(FunctionSummary::VFuncId &VFuncId,
+ bool parseVFuncId(FunctionSummary::VFuncId &VFuncId,
IdToIndexMapType &IdToIndexMap, unsigned Index);
- bool parseOptionalVTableFuncs(VTableFuncList &VTableFuncs);
- bool parseOptionalParamAccesses(
+ bool parseOptionalVTableFuncs(VTableFuncList &VTableFuncs);
+ bool parseOptionalParamAccesses(
std::vector<FunctionSummary::ParamAccess> &Params);
- bool parseParamNo(uint64_t &ParamNo);
- using IdLocListType = std::vector<std::pair<unsigned, LocTy>>;
- bool parseParamAccess(FunctionSummary::ParamAccess &Param,
- IdLocListType &IdLocList);
- bool parseParamAccessCall(FunctionSummary::ParamAccess::Call &Call,
- IdLocListType &IdLocList);
- bool parseParamAccessOffset(ConstantRange &Range);
- bool parseOptionalRefs(std::vector<ValueInfo> &Refs);
- bool parseTypeIdEntry(unsigned ID);
- bool parseTypeIdSummary(TypeIdSummary &TIS);
- bool parseTypeIdCompatibleVtableEntry(unsigned ID);
- bool parseTypeTestResolution(TypeTestResolution &TTRes);
- bool parseOptionalWpdResolutions(
+ bool parseParamNo(uint64_t &ParamNo);
+ using IdLocListType = std::vector<std::pair<unsigned, LocTy>>;
+ bool parseParamAccess(FunctionSummary::ParamAccess &Param,
+ IdLocListType &IdLocList);
+ bool parseParamAccessCall(FunctionSummary::ParamAccess::Call &Call,
+ IdLocListType &IdLocList);
+ bool parseParamAccessOffset(ConstantRange &Range);
+ bool parseOptionalRefs(std::vector<ValueInfo> &Refs);
+ bool parseTypeIdEntry(unsigned ID);
+ bool parseTypeIdSummary(TypeIdSummary &TIS);
+ bool parseTypeIdCompatibleVtableEntry(unsigned ID);
+ bool parseTypeTestResolution(TypeTestResolution &TTRes);
+ bool parseOptionalWpdResolutions(
std::map<uint64_t, WholeProgramDevirtResolution> &WPDResMap);
- bool parseWpdRes(WholeProgramDevirtResolution &WPDRes);
- bool parseOptionalResByArg(
+ bool parseWpdRes(WholeProgramDevirtResolution &WPDRes);
+ bool parseOptionalResByArg(
std::map<std::vector<uint64_t>, WholeProgramDevirtResolution::ByArg>
&ResByArg);
- bool parseArgs(std::vector<uint64_t> &Args);
- void addGlobalValueToIndex(std::string Name, GlobalValue::GUID,
+ bool parseArgs(std::vector<uint64_t> &Args);
+ void addGlobalValueToIndex(std::string Name, GlobalValue::GUID,
GlobalValue::LinkageTypes Linkage, unsigned ID,
std::unique_ptr<GlobalValueSummary> Summary);
// Type Parsing.
- bool parseType(Type *&Result, const Twine &Msg, bool AllowVoid = false);
- bool parseType(Type *&Result, bool AllowVoid = false) {
- return parseType(Result, "expected type", AllowVoid);
+ bool parseType(Type *&Result, const Twine &Msg, bool AllowVoid = false);
+ bool parseType(Type *&Result, bool AllowVoid = false) {
+ return parseType(Result, "expected type", AllowVoid);
}
- bool parseType(Type *&Result, const Twine &Msg, LocTy &Loc,
+ bool parseType(Type *&Result, const Twine &Msg, LocTy &Loc,
bool AllowVoid = false) {
Loc = Lex.getLoc();
- return parseType(Result, Msg, AllowVoid);
+ return parseType(Result, Msg, AllowVoid);
}
- bool parseType(Type *&Result, LocTy &Loc, bool AllowVoid = false) {
+ bool parseType(Type *&Result, LocTy &Loc, bool AllowVoid = false) {
Loc = Lex.getLoc();
- return parseType(Result, AllowVoid);
+ return parseType(Result, AllowVoid);
}
- bool parseAnonStructType(Type *&Result, bool Packed);
- bool parseStructBody(SmallVectorImpl<Type *> &Body);
- bool parseStructDefinition(SMLoc TypeLoc, StringRef Name,
- std::pair<Type *, LocTy> &Entry,
+ bool parseAnonStructType(Type *&Result, bool Packed);
+ bool parseStructBody(SmallVectorImpl<Type *> &Body);
+ bool parseStructDefinition(SMLoc TypeLoc, StringRef Name,
+ std::pair<Type *, LocTy> &Entry,
Type *&ResultTy);
- bool parseArrayVectorType(Type *&Result, bool IsVector);
- bool parseFunctionType(Type *&Result);
+ bool parseArrayVectorType(Type *&Result, bool IsVector);
+ bool parseFunctionType(Type *&Result);
// Function Semantic Analysis.
class PerFunctionState {
@@ -428,63 +428,63 @@ namespace llvm {
Function &getFunction() const { return F; }
- bool finishFunction();
+ bool finishFunction();
/// GetVal - Get a value with the specified name or ID, creating a
/// forward reference record if needed. This can return null if the value
/// exists but does not have the right type.
- Value *getVal(const std::string &Name, Type *Ty, LocTy Loc, bool IsCall);
- Value *getVal(unsigned ID, Type *Ty, LocTy Loc, bool IsCall);
+ Value *getVal(const std::string &Name, Type *Ty, LocTy Loc, bool IsCall);
+ Value *getVal(unsigned ID, Type *Ty, LocTy Loc, bool IsCall);
- /// setInstName - After an instruction is parsed and inserted into its
+ /// setInstName - After an instruction is parsed and inserted into its
/// basic block, this installs its name.
- bool setInstName(int NameID, const std::string &NameStr, LocTy NameLoc,
+ bool setInstName(int NameID, const std::string &NameStr, LocTy NameLoc,
Instruction *Inst);
/// GetBB - Get a basic block with the specified name or ID, creating a
/// forward reference record if needed. This can return null if the value
/// is not a BasicBlock.
- BasicBlock *getBB(const std::string &Name, LocTy Loc);
- BasicBlock *getBB(unsigned ID, LocTy Loc);
+ BasicBlock *getBB(const std::string &Name, LocTy Loc);
+ BasicBlock *getBB(unsigned ID, LocTy Loc);
/// DefineBB - Define the specified basic block, which is either named or
/// unnamed. If there is an error, this returns null otherwise it returns
/// the block being defined.
- BasicBlock *defineBB(const std::string &Name, int NameID, LocTy Loc);
+ BasicBlock *defineBB(const std::string &Name, int NameID, LocTy Loc);
bool resolveForwardRefBlockAddresses();
};
- bool convertValIDToValue(Type *Ty, ValID &ID, Value *&V,
+ bool convertValIDToValue(Type *Ty, ValID &ID, Value *&V,
PerFunctionState *PFS, bool IsCall);
Value *checkValidVariableType(LocTy Loc, const Twine &Name, Type *Ty,
Value *Val, bool IsCall);
bool parseConstantValue(Type *Ty, Constant *&C);
- bool parseValue(Type *Ty, Value *&V, PerFunctionState *PFS);
- bool parseValue(Type *Ty, Value *&V, PerFunctionState &PFS) {
- return parseValue(Ty, V, &PFS);
+ bool parseValue(Type *Ty, Value *&V, PerFunctionState *PFS);
+ bool parseValue(Type *Ty, Value *&V, PerFunctionState &PFS) {
+ return parseValue(Ty, V, &PFS);
}
- bool parseValue(Type *Ty, Value *&V, LocTy &Loc, PerFunctionState &PFS) {
+ bool parseValue(Type *Ty, Value *&V, LocTy &Loc, PerFunctionState &PFS) {
Loc = Lex.getLoc();
- return parseValue(Ty, V, &PFS);
+ return parseValue(Ty, V, &PFS);
}
- bool parseTypeAndValue(Value *&V, PerFunctionState *PFS);
- bool parseTypeAndValue(Value *&V, PerFunctionState &PFS) {
- return parseTypeAndValue(V, &PFS);
+ bool parseTypeAndValue(Value *&V, PerFunctionState *PFS);
+ bool parseTypeAndValue(Value *&V, PerFunctionState &PFS) {
+ return parseTypeAndValue(V, &PFS);
}
- bool parseTypeAndValue(Value *&V, LocTy &Loc, PerFunctionState &PFS) {
+ bool parseTypeAndValue(Value *&V, LocTy &Loc, PerFunctionState &PFS) {
Loc = Lex.getLoc();
- return parseTypeAndValue(V, PFS);
+ return parseTypeAndValue(V, PFS);
}
- bool parseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc,
+ bool parseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc,
PerFunctionState &PFS);
- bool parseTypeAndBasicBlock(BasicBlock *&BB, PerFunctionState &PFS) {
+ bool parseTypeAndBasicBlock(BasicBlock *&BB, PerFunctionState &PFS) {
LocTy Loc;
- return parseTypeAndBasicBlock(BB, Loc, PFS);
+ return parseTypeAndBasicBlock(BB, Loc, PFS);
}
struct ParamInfo {
@@ -494,47 +494,47 @@ namespace llvm {
ParamInfo(LocTy loc, Value *v, AttributeSet attrs)
: Loc(loc), V(v), Attrs(attrs) {}
};
- bool parseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
- PerFunctionState &PFS, bool IsMustTailCall = false,
+ bool parseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
+ PerFunctionState &PFS, bool IsMustTailCall = false,
bool InVarArgsFunc = false);
bool
- parseOptionalOperandBundles(SmallVectorImpl<OperandBundleDef> &BundleList,
+ parseOptionalOperandBundles(SmallVectorImpl<OperandBundleDef> &BundleList,
PerFunctionState &PFS);
- bool parseExceptionArgs(SmallVectorImpl<Value *> &Args,
+ bool parseExceptionArgs(SmallVectorImpl<Value *> &Args,
PerFunctionState &PFS);
// Constant Parsing.
- bool parseValID(ValID &ID, PerFunctionState *PFS = nullptr);
- bool parseGlobalValue(Type *Ty, Constant *&C);
- bool parseGlobalTypeAndValue(Constant *&V);
- bool parseGlobalValueVector(SmallVectorImpl<Constant *> &Elts,
+ bool parseValID(ValID &ID, PerFunctionState *PFS = nullptr);
+ bool parseGlobalValue(Type *Ty, Constant *&C);
+ bool parseGlobalTypeAndValue(Constant *&V);
+ bool parseGlobalValueVector(SmallVectorImpl<Constant *> &Elts,
Optional<unsigned> *InRangeOp = nullptr);
bool parseOptionalComdat(StringRef GlobalName, Comdat *&C);
- bool parseMetadataAsValue(Value *&V, PerFunctionState &PFS);
- bool parseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg,
+ bool parseMetadataAsValue(Value *&V, PerFunctionState &PFS);
+ bool parseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg,
PerFunctionState *PFS);
- bool parseMetadata(Metadata *&MD, PerFunctionState *PFS);
- bool parseMDTuple(MDNode *&MD, bool IsDistinct = false);
- bool parseMDNode(MDNode *&N);
- bool parseMDNodeTail(MDNode *&N);
- bool parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts);
- bool parseMetadataAttachment(unsigned &Kind, MDNode *&MD);
- bool parseInstructionMetadata(Instruction &Inst);
- bool parseGlobalObjectMetadataAttachment(GlobalObject &GO);
- bool parseOptionalFunctionMetadata(Function &F);
+ bool parseMetadata(Metadata *&MD, PerFunctionState *PFS);
+ bool parseMDTuple(MDNode *&MD, bool IsDistinct = false);
+ bool parseMDNode(MDNode *&N);
+ bool parseMDNodeTail(MDNode *&N);
+ bool parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts);
+ bool parseMetadataAttachment(unsigned &Kind, MDNode *&MD);
+ bool parseInstructionMetadata(Instruction &Inst);
+ bool parseGlobalObjectMetadataAttachment(GlobalObject &GO);
+ bool parseOptionalFunctionMetadata(Function &F);
template <class FieldTy>
- bool parseMDField(LocTy Loc, StringRef Name, FieldTy &Result);
- template <class FieldTy> bool parseMDField(StringRef Name, FieldTy &Result);
- template <class ParserTy> bool parseMDFieldsImplBody(ParserTy ParseField);
+ bool parseMDField(LocTy Loc, StringRef Name, FieldTy &Result);
+ template <class FieldTy> bool parseMDField(StringRef Name, FieldTy &Result);
+ template <class ParserTy> bool parseMDFieldsImplBody(ParserTy ParseField);
template <class ParserTy>
- bool parseMDFieldsImpl(ParserTy ParseField, LocTy &ClosingLoc);
- bool parseSpecializedMDNode(MDNode *&N, bool IsDistinct = false);
+ bool parseMDFieldsImpl(ParserTy ParseField, LocTy &ClosingLoc);
+ bool parseSpecializedMDNode(MDNode *&N, bool IsDistinct = false);
#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) \
- bool parse##CLASS(MDNode *&Result, bool IsDistinct);
+ bool parse##CLASS(MDNode *&Result, bool IsDistinct);
#include "llvm/IR/Metadata.def"
// Function Parsing.
@@ -546,64 +546,64 @@ namespace llvm {
ArgInfo(LocTy L, Type *ty, AttributeSet Attr, const std::string &N)
: Loc(L), Ty(ty), Attrs(Attr), Name(N) {}
};
- bool parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, bool &IsVarArg);
- bool parseFunctionHeader(Function *&Fn, bool IsDefine);
- bool parseFunctionBody(Function &Fn);
- bool parseBasicBlock(PerFunctionState &PFS);
+ bool parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, bool &IsVarArg);
+ bool parseFunctionHeader(Function *&Fn, bool IsDefine);
+ bool parseFunctionBody(Function &Fn);
+ bool parseBasicBlock(PerFunctionState &PFS);
enum TailCallType { TCT_None, TCT_Tail, TCT_MustTail };
// Instruction Parsing. Each instruction parsing routine can return with a
// normal result, an error result, or return having eaten an extra comma.
enum InstResult { InstNormal = 0, InstError = 1, InstExtraComma = 2 };
- int parseInstruction(Instruction *&Inst, BasicBlock *BB,
+ int parseInstruction(Instruction *&Inst, BasicBlock *BB,
PerFunctionState &PFS);
- bool parseCmpPredicate(unsigned &P, unsigned Opc);
-
- bool parseRet(Instruction *&Inst, BasicBlock *BB, PerFunctionState &PFS);
- bool parseBr(Instruction *&Inst, PerFunctionState &PFS);
- bool parseSwitch(Instruction *&Inst, PerFunctionState &PFS);
- bool parseIndirectBr(Instruction *&Inst, PerFunctionState &PFS);
- bool parseInvoke(Instruction *&Inst, PerFunctionState &PFS);
- bool parseResume(Instruction *&Inst, PerFunctionState &PFS);
- bool parseCleanupRet(Instruction *&Inst, PerFunctionState &PFS);
- bool parseCatchRet(Instruction *&Inst, PerFunctionState &PFS);
- bool parseCatchSwitch(Instruction *&Inst, PerFunctionState &PFS);
- bool parseCatchPad(Instruction *&Inst, PerFunctionState &PFS);
- bool parseCleanupPad(Instruction *&Inst, PerFunctionState &PFS);
- bool parseCallBr(Instruction *&Inst, PerFunctionState &PFS);
-
- bool parseUnaryOp(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc,
+ bool parseCmpPredicate(unsigned &P, unsigned Opc);
+
+ bool parseRet(Instruction *&Inst, BasicBlock *BB, PerFunctionState &PFS);
+ bool parseBr(Instruction *&Inst, PerFunctionState &PFS);
+ bool parseSwitch(Instruction *&Inst, PerFunctionState &PFS);
+ bool parseIndirectBr(Instruction *&Inst, PerFunctionState &PFS);
+ bool parseInvoke(Instruction *&Inst, PerFunctionState &PFS);
+ bool parseResume(Instruction *&Inst, PerFunctionState &PFS);
+ bool parseCleanupRet(Instruction *&Inst, PerFunctionState &PFS);
+ bool parseCatchRet(Instruction *&Inst, PerFunctionState &PFS);
+ bool parseCatchSwitch(Instruction *&Inst, PerFunctionState &PFS);
+ bool parseCatchPad(Instruction *&Inst, PerFunctionState &PFS);
+ bool parseCleanupPad(Instruction *&Inst, PerFunctionState &PFS);
+ bool parseCallBr(Instruction *&Inst, PerFunctionState &PFS);
+
+ bool parseUnaryOp(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc,
bool IsFP);
- bool parseArithmetic(Instruction *&Inst, PerFunctionState &PFS,
- unsigned Opc, bool IsFP);
- bool parseLogical(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc);
- bool parseCompare(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc);
- bool parseCast(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc);
- bool parseSelect(Instruction *&Inst, PerFunctionState &PFS);
- bool parseVAArg(Instruction *&Inst, PerFunctionState &PFS);
- bool parseExtractElement(Instruction *&Inst, PerFunctionState &PFS);
- bool parseInsertElement(Instruction *&Inst, PerFunctionState &PFS);
- bool parseShuffleVector(Instruction *&Inst, PerFunctionState &PFS);
- int parsePHI(Instruction *&Inst, PerFunctionState &PFS);
- bool parseLandingPad(Instruction *&Inst, PerFunctionState &PFS);
- bool parseCall(Instruction *&Inst, PerFunctionState &PFS,
+ bool parseArithmetic(Instruction *&Inst, PerFunctionState &PFS,
+ unsigned Opc, bool IsFP);
+ bool parseLogical(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc);
+ bool parseCompare(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc);
+ bool parseCast(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc);
+ bool parseSelect(Instruction *&Inst, PerFunctionState &PFS);
+ bool parseVAArg(Instruction *&Inst, PerFunctionState &PFS);
+ bool parseExtractElement(Instruction *&Inst, PerFunctionState &PFS);
+ bool parseInsertElement(Instruction *&Inst, PerFunctionState &PFS);
+ bool parseShuffleVector(Instruction *&Inst, PerFunctionState &PFS);
+ int parsePHI(Instruction *&Inst, PerFunctionState &PFS);
+ bool parseLandingPad(Instruction *&Inst, PerFunctionState &PFS);
+ bool parseCall(Instruction *&Inst, PerFunctionState &PFS,
CallInst::TailCallKind TCK);
- int parseAlloc(Instruction *&Inst, PerFunctionState &PFS);
- int parseLoad(Instruction *&Inst, PerFunctionState &PFS);
- int parseStore(Instruction *&Inst, PerFunctionState &PFS);
- int parseCmpXchg(Instruction *&Inst, PerFunctionState &PFS);
- int parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS);
- int parseFence(Instruction *&Inst, PerFunctionState &PFS);
- int parseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS);
- int parseExtractValue(Instruction *&Inst, PerFunctionState &PFS);
- int parseInsertValue(Instruction *&Inst, PerFunctionState &PFS);
- bool parseFreeze(Instruction *&I, PerFunctionState &PFS);
+ int parseAlloc(Instruction *&Inst, PerFunctionState &PFS);
+ int parseLoad(Instruction *&Inst, PerFunctionState &PFS);
+ int parseStore(Instruction *&Inst, PerFunctionState &PFS);
+ int parseCmpXchg(Instruction *&Inst, PerFunctionState &PFS);
+ int parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS);
+ int parseFence(Instruction *&Inst, PerFunctionState &PFS);
+ int parseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS);
+ int parseExtractValue(Instruction *&Inst, PerFunctionState &PFS);
+ int parseInsertValue(Instruction *&Inst, PerFunctionState &PFS);
+ bool parseFreeze(Instruction *&I, PerFunctionState &PFS);
// Use-list order directives.
- bool parseUseListOrder(PerFunctionState *PFS = nullptr);
- bool parseUseListOrderBB();
- bool parseUseListOrderIndexes(SmallVectorImpl<unsigned> &Indexes);
+ bool parseUseListOrder(PerFunctionState *PFS = nullptr);
+ bool parseUseListOrderBB();
+ bool parseUseListOrderIndexes(SmallVectorImpl<unsigned> &Indexes);
bool sortUseListOrder(Value *V, ArrayRef<unsigned> Indexes, SMLoc Loc);
};
} // End llvm namespace
diff --git a/contrib/libs/llvm12/lib/AsmParser/LLToken.h b/contrib/libs/llvm12/lib/AsmParser/LLToken.h
index 7d600e85ef..5149f86183 100644
--- a/contrib/libs/llvm12/lib/AsmParser/LLToken.h
+++ b/contrib/libs/llvm12/lib/AsmParser/LLToken.h
@@ -74,7 +74,7 @@ enum Kind {
kw_localexec,
kw_zeroinitializer,
kw_undef,
- kw_poison,
+ kw_poison,
kw_null,
kw_none,
kw_to,
@@ -171,7 +171,7 @@ enum Kind {
kw_amdgpu_ps,
kw_amdgpu_cs,
kw_amdgpu_kernel,
- kw_amdgpu_gfx,
+ kw_amdgpu_gfx,
kw_tailcc,
// Attributes:
@@ -200,7 +200,7 @@ enum Kind {
kw_noalias,
kw_noundef,
kw_nobuiltin,
- kw_nocallback,
+ kw_nocallback,
kw_nocapture,
kw_noduplicate,
kw_nofree,
@@ -210,7 +210,7 @@ enum Kind {
kw_nonlazybind,
kw_nomerge,
kw_nonnull,
- kw_noprofile,
+ kw_noprofile,
kw_noredzone,
kw_noreturn,
kw_nosync,
@@ -244,8 +244,8 @@ enum Kind {
kw_writeonly,
kw_zeroext,
kw_immarg,
- kw_byref,
- kw_mustprogress,
+ kw_byref,
+ kw_mustprogress,
kw_type,
kw_opaque,
@@ -363,7 +363,7 @@ enum Kind {
kw_extractvalue,
kw_insertvalue,
kw_blockaddress,
- kw_dso_local_equivalent,
+ kw_dso_local_equivalent,
kw_freeze,
diff --git a/contrib/libs/llvm12/lib/AsmParser/ya.make b/contrib/libs/llvm12/lib/AsmParser/ya.make
index e05e9e83a8..a84b5563eb 100644
--- a/contrib/libs/llvm12/lib/AsmParser/ya.make
+++ b/contrib/libs/llvm12/lib/AsmParser/ya.make
@@ -12,11 +12,11 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/BinaryFormat/Dwarf.cpp b/contrib/libs/llvm12/lib/BinaryFormat/Dwarf.cpp
index f439982d91..e4747369f3 100644
--- a/contrib/libs/llvm12/lib/BinaryFormat/Dwarf.cpp
+++ b/contrib/libs/llvm12/lib/BinaryFormat/Dwarf.cpp
@@ -151,8 +151,8 @@ StringRef llvm::dwarf::OperationEncodingString(unsigned Encoding) {
return "DW_OP_LLVM_tag_offset";
case DW_OP_LLVM_entry_value:
return "DW_OP_LLVM_entry_value";
- case DW_OP_LLVM_implicit_pointer:
- return "DW_OP_LLVM_implicit_pointer";
+ case DW_OP_LLVM_implicit_pointer:
+ return "DW_OP_LLVM_implicit_pointer";
}
}
@@ -165,7 +165,7 @@ unsigned llvm::dwarf::getOperationEncoding(StringRef OperationEncodingString) {
.Case("DW_OP_LLVM_fragment", DW_OP_LLVM_fragment)
.Case("DW_OP_LLVM_tag_offset", DW_OP_LLVM_tag_offset)
.Case("DW_OP_LLVM_entry_value", DW_OP_LLVM_entry_value)
- .Case("DW_OP_LLVM_implicit_pointer", DW_OP_LLVM_implicit_pointer)
+ .Case("DW_OP_LLVM_implicit_pointer", DW_OP_LLVM_implicit_pointer)
.Default(0);
}
@@ -491,17 +491,17 @@ StringRef llvm::dwarf::MacroString(unsigned Encoding) {
}
}
-StringRef llvm::dwarf::GnuMacroString(unsigned Encoding) {
- switch (Encoding) {
- default:
- return StringRef();
-#define HANDLE_DW_MACRO_GNU(ID, NAME) \
- case DW_MACRO_GNU_##NAME: \
- return "DW_MACRO_GNU_" #NAME;
-#include "llvm/BinaryFormat/Dwarf.def"
- }
-}
-
+StringRef llvm::dwarf::GnuMacroString(unsigned Encoding) {
+ switch (Encoding) {
+ default:
+ return StringRef();
+#define HANDLE_DW_MACRO_GNU(ID, NAME) \
+ case DW_MACRO_GNU_##NAME: \
+ return "DW_MACRO_GNU_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
unsigned llvm::dwarf::getMacro(StringRef MacroString) {
return StringSwitch<unsigned>(MacroString)
#define HANDLE_DW_MACRO(ID, NAME) .Case("DW_MACRO_" #NAME, ID)
@@ -798,17 +798,17 @@ StringRef llvm::dwarf::FormatString(bool IsDWARF64) {
return FormatString(IsDWARF64 ? DWARF64 : DWARF32);
}
-StringRef llvm::dwarf::RLEString(unsigned RLE) {
- switch (RLE) {
- default:
- return StringRef();
-#define HANDLE_DW_RLE(ID, NAME) \
- case DW_RLE_##NAME: \
- return "DW_RLE_" #NAME;
-#include "llvm/BinaryFormat/Dwarf.def"
- }
-}
-
+StringRef llvm::dwarf::RLEString(unsigned RLE) {
+ switch (RLE) {
+ default:
+ return StringRef();
+#define HANDLE_DW_RLE(ID, NAME) \
+ case DW_RLE_##NAME: \
+ return "DW_RLE_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
constexpr char llvm::dwarf::EnumTraits<Attribute>::Type[];
constexpr char llvm::dwarf::EnumTraits<Form>::Type[];
constexpr char llvm::dwarf::EnumTraits<Index>::Type[];
diff --git a/contrib/libs/llvm12/lib/BinaryFormat/MachO.cpp b/contrib/libs/llvm12/lib/BinaryFormat/MachO.cpp
index 396939ea93..02a515c943 100644
--- a/contrib/libs/llvm12/lib/BinaryFormat/MachO.cpp
+++ b/contrib/libs/llvm12/lib/BinaryFormat/MachO.cpp
@@ -55,10 +55,10 @@ static MachO::CPUSubTypeARM getARMSubType(const Triple &T) {
}
static MachO::CPUSubTypeARM64 getARM64SubType(const Triple &T) {
- assert(T.isAArch64());
+ assert(T.isAArch64());
if (T.isArch32Bit())
return (MachO::CPUSubTypeARM64)MachO::CPU_SUBTYPE_ARM64_32_V8;
- if (T.isArm64e())
+ if (T.isArm64e())
return MachO::CPU_SUBTYPE_ARM64E;
return MachO::CPU_SUBTYPE_ARM64_ALL;
@@ -84,7 +84,7 @@ Expected<uint32_t> MachO::getCPUType(const Triple &T) {
if (T.isARM() || T.isThumb())
return MachO::CPU_TYPE_ARM;
if (T.isAArch64())
- return T.isArch32Bit() ? MachO::CPU_TYPE_ARM64_32 : MachO::CPU_TYPE_ARM64;
+ return T.isArch32Bit() ? MachO::CPU_TYPE_ARM64_32 : MachO::CPU_TYPE_ARM64;
if (T.getArch() == Triple::ppc)
return MachO::CPU_TYPE_POWERPC;
if (T.getArch() == Triple::ppc64)
diff --git a/contrib/libs/llvm12/lib/BinaryFormat/MsgPackDocument.cpp b/contrib/libs/llvm12/lib/BinaryFormat/MsgPackDocument.cpp
index 79996147d1..81ea4cee1a 100644
--- a/contrib/libs/llvm12/lib/BinaryFormat/MsgPackDocument.cpp
+++ b/contrib/libs/llvm12/lib/BinaryFormat/MsgPackDocument.cpp
@@ -277,8 +277,8 @@ void Document::writeToBlob(std::string &Blob) {
case Type::String:
MPWriter.write(Node.getString());
break;
- case Type::Empty:
- llvm_unreachable("unhandled empty msgpack node");
+ case Type::Empty:
+ llvm_unreachable("unhandled empty msgpack node");
default:
llvm_unreachable("unhandled msgpack object kind");
}
diff --git a/contrib/libs/llvm12/lib/BinaryFormat/Wasm.cpp b/contrib/libs/llvm12/lib/BinaryFormat/Wasm.cpp
index 9eff65f05a..126680ac41 100644
--- a/contrib/libs/llvm12/lib/BinaryFormat/Wasm.cpp
+++ b/contrib/libs/llvm12/lib/BinaryFormat/Wasm.cpp
@@ -14,8 +14,8 @@ std::string llvm::wasm::toString(wasm::WasmSymbolType Type) {
return "WASM_SYMBOL_TYPE_FUNCTION";
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
return "WASM_SYMBOL_TYPE_GLOBAL";
- case wasm::WASM_SYMBOL_TYPE_TABLE:
- return "WASM_SYMBOL_TYPE_TABLE";
+ case wasm::WASM_SYMBOL_TYPE_TABLE:
+ return "WASM_SYMBOL_TYPE_TABLE";
case wasm::WASM_SYMBOL_TYPE_DATA:
return "WASM_SYMBOL_TYPE_DATA";
case wasm::WASM_SYMBOL_TYPE_SECTION:
@@ -48,9 +48,9 @@ bool llvm::wasm::relocTypeHasAddend(uint32_t Type) {
case R_WASM_MEMORY_ADDR_REL_SLEB64:
case R_WASM_MEMORY_ADDR_I32:
case R_WASM_MEMORY_ADDR_I64:
- case R_WASM_MEMORY_ADDR_TLS_SLEB:
+ case R_WASM_MEMORY_ADDR_TLS_SLEB:
case R_WASM_FUNCTION_OFFSET_I32:
- case R_WASM_FUNCTION_OFFSET_I64:
+ case R_WASM_FUNCTION_OFFSET_I64:
case R_WASM_SECTION_OFFSET_I32:
return true;
default:
diff --git a/contrib/libs/llvm12/lib/BinaryFormat/XCOFF.cpp b/contrib/libs/llvm12/lib/BinaryFormat/XCOFF.cpp
index 253decd197..0f270a5cea 100644
--- a/contrib/libs/llvm12/lib/BinaryFormat/XCOFF.cpp
+++ b/contrib/libs/llvm12/lib/BinaryFormat/XCOFF.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/BinaryFormat/XCOFF.h"
-#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
using namespace llvm;
@@ -76,81 +76,81 @@ StringRef XCOFF::getRelocationTypeString(XCOFF::RelocationType Type) {
}
return "Unknown";
}
-
-#define LANG_CASE(A) \
- case XCOFF::TracebackTable::A: \
- return #A;
-
-StringRef XCOFF::getNameForTracebackTableLanguageId(
- XCOFF::TracebackTable::LanguageID LangId) {
- switch (LangId) {
- LANG_CASE(C)
- LANG_CASE(Fortran)
- LANG_CASE(Pascal)
- LANG_CASE(Ada)
- LANG_CASE(PL1)
- LANG_CASE(Basic)
- LANG_CASE(Lisp)
- LANG_CASE(Cobol)
- LANG_CASE(Modula2)
- LANG_CASE(Rpg)
- LANG_CASE(PL8)
- LANG_CASE(Assembly)
- LANG_CASE(Java)
- LANG_CASE(ObjectiveC)
- LANG_CASE(CPlusPlus)
- }
- return "Unknown";
-}
-#undef LANG_CASE
-
-SmallString<32> XCOFF::parseParmsType(uint32_t Value, unsigned ParmsNum) {
- SmallString<32> ParmsType;
- for (unsigned I = 0; I < ParmsNum; ++I) {
- if (I != 0)
- ParmsType += ", ";
- if ((Value & TracebackTable::ParmTypeIsFloatingBit) == 0) {
- // Fixed parameter type.
- ParmsType += "i";
- Value <<= 1;
- } else {
- if ((Value & TracebackTable::ParmTypeFloatingIsDoubleBit) == 0)
- // Float parameter type.
- ParmsType += "f";
- else
- // Double parameter type.
- ParmsType += "d";
-
- Value <<= 2;
- }
- }
- assert(Value == 0u && "ParmsType encodes more than ParmsNum parameters.");
- return ParmsType;
-}
-
-SmallString<32> XCOFF::getExtendedTBTableFlagString(uint8_t Flag) {
- SmallString<32> Res;
-
- if (Flag & ExtendedTBTableFlag::TB_OS1)
- Res += "TB_OS1 ";
- if (Flag & ExtendedTBTableFlag::TB_RESERVED)
- Res += "TB_RESERVED ";
- if (Flag & ExtendedTBTableFlag::TB_SSP_CANARY)
- Res += "TB_SSP_CANARY ";
- if (Flag & ExtendedTBTableFlag::TB_OS2)
- Res += "TB_OS2 ";
- if (Flag & ExtendedTBTableFlag::TB_EH_INFO)
- Res += "TB_EH_INFO ";
- if (Flag & ExtendedTBTableFlag::TB_LONGTBTABLE2)
- Res += "TB_LONGTBTABLE2 ";
-
- // Two of the bits that haven't got used in the mask.
- if (Flag & 0x06)
- Res += "Unknown ";
-
- // Pop the last space.
- Res.pop_back();
- return Res;
-}
-
+
+#define LANG_CASE(A) \
+ case XCOFF::TracebackTable::A: \
+ return #A;
+
+StringRef XCOFF::getNameForTracebackTableLanguageId(
+ XCOFF::TracebackTable::LanguageID LangId) {
+ switch (LangId) {
+ LANG_CASE(C)
+ LANG_CASE(Fortran)
+ LANG_CASE(Pascal)
+ LANG_CASE(Ada)
+ LANG_CASE(PL1)
+ LANG_CASE(Basic)
+ LANG_CASE(Lisp)
+ LANG_CASE(Cobol)
+ LANG_CASE(Modula2)
+ LANG_CASE(Rpg)
+ LANG_CASE(PL8)
+ LANG_CASE(Assembly)
+ LANG_CASE(Java)
+ LANG_CASE(ObjectiveC)
+ LANG_CASE(CPlusPlus)
+ }
+ return "Unknown";
+}
+#undef LANG_CASE
+
+SmallString<32> XCOFF::parseParmsType(uint32_t Value, unsigned ParmsNum) {
+ SmallString<32> ParmsType;
+ for (unsigned I = 0; I < ParmsNum; ++I) {
+ if (I != 0)
+ ParmsType += ", ";
+ if ((Value & TracebackTable::ParmTypeIsFloatingBit) == 0) {
+ // Fixed parameter type.
+ ParmsType += "i";
+ Value <<= 1;
+ } else {
+ if ((Value & TracebackTable::ParmTypeFloatingIsDoubleBit) == 0)
+ // Float parameter type.
+ ParmsType += "f";
+ else
+ // Double parameter type.
+ ParmsType += "d";
+
+ Value <<= 2;
+ }
+ }
+ assert(Value == 0u && "ParmsType encodes more than ParmsNum parameters.");
+ return ParmsType;
+}
+
+SmallString<32> XCOFF::getExtendedTBTableFlagString(uint8_t Flag) {
+ SmallString<32> Res;
+
+ if (Flag & ExtendedTBTableFlag::TB_OS1)
+ Res += "TB_OS1 ";
+ if (Flag & ExtendedTBTableFlag::TB_RESERVED)
+ Res += "TB_RESERVED ";
+ if (Flag & ExtendedTBTableFlag::TB_SSP_CANARY)
+ Res += "TB_SSP_CANARY ";
+ if (Flag & ExtendedTBTableFlag::TB_OS2)
+ Res += "TB_OS2 ";
+ if (Flag & ExtendedTBTableFlag::TB_EH_INFO)
+ Res += "TB_EH_INFO ";
+ if (Flag & ExtendedTBTableFlag::TB_LONGTBTABLE2)
+ Res += "TB_LONGTBTABLE2 ";
+
+ // Two of the bits that haven't got used in the mask.
+ if (Flag & 0x06)
+ Res += "Unknown ";
+
+ // Pop the last space.
+ Res.pop_back();
+ return Res;
+}
+
#undef RELOC_CASE
diff --git a/contrib/libs/llvm12/lib/BinaryFormat/ya.make b/contrib/libs/llvm12/lib/BinaryFormat/ya.make
index 459f5a0c89..c1d64fa5a6 100644
--- a/contrib/libs/llvm12/lib/BinaryFormat/ya.make
+++ b/contrib/libs/llvm12/lib/BinaryFormat/ya.make
@@ -15,8 +15,8 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/Bitcode/Reader/BitcodeAnalyzer.cpp b/contrib/libs/llvm12/lib/Bitcode/Reader/BitcodeAnalyzer.cpp
index bb69e625ea..e91af121ea 100644
--- a/contrib/libs/llvm12/lib/Bitcode/Reader/BitcodeAnalyzer.cpp
+++ b/contrib/libs/llvm12/lib/Bitcode/Reader/BitcodeAnalyzer.cpp
@@ -135,7 +135,7 @@ static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID,
STRINGIFY_CODE(MODULE_CODE, FUNCTION)
STRINGIFY_CODE(MODULE_CODE, ALIAS)
STRINGIFY_CODE(MODULE_CODE, GCNAME)
- STRINGIFY_CODE(MODULE_CODE, COMDAT)
+ STRINGIFY_CODE(MODULE_CODE, COMDAT)
STRINGIFY_CODE(MODULE_CODE, VSTOFFSET)
STRINGIFY_CODE(MODULE_CODE, METADATA_VALUES_UNUSED)
STRINGIFY_CODE(MODULE_CODE, SOURCE_FILENAME)
@@ -177,20 +177,20 @@ static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID,
STRINGIFY_CODE(TYPE_CODE, OPAQUE)
STRINGIFY_CODE(TYPE_CODE, INTEGER)
STRINGIFY_CODE(TYPE_CODE, POINTER)
- STRINGIFY_CODE(TYPE_CODE, HALF)
+ STRINGIFY_CODE(TYPE_CODE, HALF)
STRINGIFY_CODE(TYPE_CODE, ARRAY)
STRINGIFY_CODE(TYPE_CODE, VECTOR)
STRINGIFY_CODE(TYPE_CODE, X86_FP80)
STRINGIFY_CODE(TYPE_CODE, FP128)
STRINGIFY_CODE(TYPE_CODE, PPC_FP128)
STRINGIFY_CODE(TYPE_CODE, METADATA)
- STRINGIFY_CODE(TYPE_CODE, X86_MMX)
+ STRINGIFY_CODE(TYPE_CODE, X86_MMX)
STRINGIFY_CODE(TYPE_CODE, STRUCT_ANON)
STRINGIFY_CODE(TYPE_CODE, STRUCT_NAME)
STRINGIFY_CODE(TYPE_CODE, STRUCT_NAMED)
STRINGIFY_CODE(TYPE_CODE, FUNCTION)
- STRINGIFY_CODE(TYPE_CODE, TOKEN)
- STRINGIFY_CODE(TYPE_CODE, BFLOAT)
+ STRINGIFY_CODE(TYPE_CODE, TOKEN)
+ STRINGIFY_CODE(TYPE_CODE, BFLOAT)
}
case bitc::CONSTANTS_BLOCK_ID:
diff --git a/contrib/libs/llvm12/lib/Bitcode/Reader/BitcodeReader.cpp b/contrib/libs/llvm12/lib/Bitcode/Reader/BitcodeReader.cpp
index 38befd1cde..f2800201e8 100644
--- a/contrib/libs/llvm12/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/contrib/libs/llvm12/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -20,8 +20,8 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/Bitcode/BitcodeCommon.h"
-#include "llvm/Bitcode/LLVMBitCodes.h"
+#include "llvm/Bitcode/BitcodeCommon.h"
+#include "llvm/Bitcode/LLVMBitCodes.h"
#include "llvm/Bitstream/BitstreamReader.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Argument.h"
@@ -579,7 +579,7 @@ public:
/// \returns true if an error occurred.
Error parseBitcodeInto(
Module *M, bool ShouldLazyLoadMetadata = false, bool IsImporting = false,
- DataLayoutCallbackTy DataLayoutCallback = [](StringRef) { return None; });
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef) { return None; });
static uint64_t decodeSignRotatedValue(uint64_t V);
@@ -649,7 +649,7 @@ private:
/// Read a value/type pair out of the specified record from slot 'Slot'.
/// Increment Slot past the number of slots used in the record. Return true on
/// failure.
- bool getValueTypePair(const SmallVectorImpl<uint64_t> &Record, unsigned &Slot,
+ bool getValueTypePair(const SmallVectorImpl<uint64_t> &Record, unsigned &Slot,
unsigned InstNum, Value *&ResVal,
Type **FullTy = nullptr) {
if (Slot == Record.size()) return true;
@@ -676,7 +676,7 @@ private:
/// Read a value out of the specified record from slot 'Slot'. Increment Slot
/// past the number of slots used by the value in the record. Return true if
/// there is an error.
- bool popValue(const SmallVectorImpl<uint64_t> &Record, unsigned &Slot,
+ bool popValue(const SmallVectorImpl<uint64_t> &Record, unsigned &Slot,
unsigned InstNum, Type *Ty, Value *&ResVal) {
if (getValue(Record, Slot, InstNum, Ty, ResVal))
return true;
@@ -686,7 +686,7 @@ private:
}
/// Like popValue, but does not increment the Slot number.
- bool getValue(const SmallVectorImpl<uint64_t> &Record, unsigned Slot,
+ bool getValue(const SmallVectorImpl<uint64_t> &Record, unsigned Slot,
unsigned InstNum, Type *Ty, Value *&ResVal) {
ResVal = getValue(Record, Slot, InstNum, Ty);
return ResVal == nullptr;
@@ -694,7 +694,7 @@ private:
/// Version of getValue that returns ResVal directly, or 0 if there is an
/// error.
- Value *getValue(const SmallVectorImpl<uint64_t> &Record, unsigned Slot,
+ Value *getValue(const SmallVectorImpl<uint64_t> &Record, unsigned Slot,
unsigned InstNum, Type *Ty) {
if (Slot == Record.size()) return nullptr;
unsigned ValNo = (unsigned)Record[Slot];
@@ -705,7 +705,7 @@ private:
}
/// Like getValue, but decodes signed VBRs.
- Value *getValueSigned(const SmallVectorImpl<uint64_t> &Record, unsigned Slot,
+ Value *getValueSigned(const SmallVectorImpl<uint64_t> &Record, unsigned Slot,
unsigned InstNum, Type *Ty) {
if (Slot == Record.size()) return nullptr;
unsigned ValNo = (unsigned)decodeSignRotatedValue(Record[Slot]);
@@ -715,9 +715,9 @@ private:
return getFnValueByID(ValNo, Ty);
}
- /// Upgrades old-style typeless byval or sret attributes by adding the
- /// corresponding argument's pointee type.
- void propagateByValSRetTypes(CallBase *CB, ArrayRef<Type *> ArgsFullTys);
+ /// Upgrades old-style typeless byval or sret attributes by adding the
+ /// corresponding argument's pointee type.
+ void propagateByValSRetTypes(CallBase *CB, ArrayRef<Type *> ArgsFullTys);
/// Converts alignment exponent (i.e. power of two (or zero)) to the
/// corresponding alignment to use. If alignment is too large, returns
@@ -833,8 +833,8 @@ private:
void parseTypeIdCompatibleVtableSummaryRecord(ArrayRef<uint64_t> Record);
void parseTypeIdCompatibleVtableInfo(ArrayRef<uint64_t> Record, size_t &Slot,
TypeIdCompatibleVtableInfo &TypeId);
- std::vector<FunctionSummary::ParamAccess>
- parseParamAccesses(ArrayRef<uint64_t> Record);
+ std::vector<FunctionSummary::ParamAccess>
+ parseParamAccesses(ArrayRef<uint64_t> Record);
std::pair<ValueInfo, GlobalValue::GUID>
getValueInfoFromValueId(unsigned ValueId);
@@ -1433,8 +1433,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
return Attribute::NoAlias;
case bitc::ATTR_KIND_NO_BUILTIN:
return Attribute::NoBuiltin;
- case bitc::ATTR_KIND_NO_CALLBACK:
- return Attribute::NoCallback;
+ case bitc::ATTR_KIND_NO_CALLBACK:
+ return Attribute::NoCallback;
case bitc::ATTR_KIND_NO_CAPTURE:
return Attribute::NoCapture;
case bitc::ATTR_KIND_NO_DUPLICATE:
@@ -1535,12 +1535,12 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
return Attribute::Preallocated;
case bitc::ATTR_KIND_NOUNDEF:
return Attribute::NoUndef;
- case bitc::ATTR_KIND_BYREF:
- return Attribute::ByRef;
- case bitc::ATTR_KIND_MUSTPROGRESS:
- return Attribute::MustProgress;
- case bitc::ATTR_KIND_HOT:
- return Attribute::Hot;
+ case bitc::ATTR_KIND_BYREF:
+ return Attribute::ByRef;
+ case bitc::ATTR_KIND_MUSTPROGRESS:
+ return Attribute::MustProgress;
+ case bitc::ATTR_KIND_HOT:
+ return Attribute::Hot;
}
}
@@ -1615,8 +1615,8 @@ Error BitcodeReader::parseAttributeGroupBlock() {
// this AttributeList with a function.
if (Kind == Attribute::ByVal)
B.addByValAttr(nullptr);
- else if (Kind == Attribute::StructRet)
- B.addStructRetAttr(nullptr);
+ else if (Kind == Attribute::StructRet)
+ B.addStructRetAttr(nullptr);
B.addAttribute(Kind);
} else if (Record[i] == 1) { // Integer attribute
@@ -1660,10 +1660,10 @@ Error BitcodeReader::parseAttributeGroupBlock() {
return Err;
if (Kind == Attribute::ByVal) {
B.addByValAttr(HasType ? getTypeByID(Record[++i]) : nullptr);
- } else if (Kind == Attribute::StructRet) {
- B.addStructRetAttr(HasType ? getTypeByID(Record[++i]) : nullptr);
- } else if (Kind == Attribute::ByRef) {
- B.addByRefAttr(getTypeByID(Record[++i]));
+ } else if (Kind == Attribute::StructRet) {
+ B.addStructRetAttr(HasType ? getTypeByID(Record[++i]) : nullptr);
+ } else if (Kind == Attribute::ByRef) {
+ B.addByRefAttr(getTypeByID(Record[++i]));
} else if (Kind == Attribute::Preallocated) {
B.addPreallocatedAttr(getTypeByID(Record[++i]));
}
@@ -1726,7 +1726,7 @@ Error BitcodeReader::parseTypeTableBody() {
case bitc::TYPE_CODE_NUMENTRY: // TYPE_CODE_NUMENTRY: [numentries]
// TYPE_CODE_NUMENTRY contains a count of the number of types in the
// type list. This allows us to reserve space.
- if (Record.empty())
+ if (Record.empty())
return error("Invalid record");
TypeList.resize(Record[0]);
continue;
@@ -1763,14 +1763,14 @@ Error BitcodeReader::parseTypeTableBody() {
case bitc::TYPE_CODE_X86_MMX: // X86_MMX
ResultTy = Type::getX86_MMXTy(Context);
break;
- case bitc::TYPE_CODE_X86_AMX: // X86_AMX
- ResultTy = Type::getX86_AMXTy(Context);
- break;
+ case bitc::TYPE_CODE_X86_AMX: // X86_AMX
+ ResultTy = Type::getX86_AMXTy(Context);
+ break;
case bitc::TYPE_CODE_TOKEN: // TOKEN
ResultTy = Type::getTokenTy(Context);
break;
case bitc::TYPE_CODE_INTEGER: { // INTEGER: [width]
- if (Record.empty())
+ if (Record.empty())
return error("Invalid record");
uint64_t NumBits = Record[0];
@@ -1782,7 +1782,7 @@ Error BitcodeReader::parseTypeTableBody() {
}
case bitc::TYPE_CODE_POINTER: { // POINTER: [pointee type] or
// [pointee type, address space]
- if (Record.empty())
+ if (Record.empty())
return error("Invalid record");
unsigned AddressSpace = 0;
if (Record.size() == 2)
@@ -1837,7 +1837,7 @@ Error BitcodeReader::parseTypeTableBody() {
break;
}
case bitc::TYPE_CODE_STRUCT_ANON: { // STRUCT: [ispacked, eltty x N]
- if (Record.empty())
+ if (Record.empty())
return error("Invalid record");
SmallVector<Type*, 8> EltTys;
for (unsigned i = 1, e = Record.size(); i != e; ++i) {
@@ -1857,7 +1857,7 @@ Error BitcodeReader::parseTypeTableBody() {
continue;
case bitc::TYPE_CODE_STRUCT_NAMED: { // STRUCT: [ispacked, eltty x N]
- if (Record.empty())
+ if (Record.empty())
return error("Invalid record");
if (NumRecords >= TypeList.size())
@@ -2417,9 +2417,9 @@ Error BitcodeReader::parseConstants() {
case bitc::CST_CODE_UNDEF: // UNDEF
V = UndefValue::get(CurTy);
break;
- case bitc::CST_CODE_POISON: // POISON
- V = PoisonValue::get(CurTy);
- break;
+ case bitc::CST_CODE_POISON: // POISON
+ V = PoisonValue::get(CurTy);
+ break;
case bitc::CST_CODE_SETTYPE: // SETTYPE: [typeid]
if (Record.empty())
return error("Invalid record");
@@ -2933,7 +2933,7 @@ Error BitcodeReader::parseUseLists() {
if (RecordLength < 3)
// Records should have at least an ID and two indexes.
return error("Invalid record");
- unsigned ID = Record.pop_back_val();
+ unsigned ID = Record.pop_back_val();
Value *V;
if (IsBB) {
@@ -2985,15 +2985,15 @@ Error BitcodeReader::materializeMetadata() {
}
// Upgrade "Linker Options" module flag to "llvm.linker.options" module-level
- // metadata. Only upgrade if the new option doesn't exist to avoid upgrade
- // multiple times.
- if (!TheModule->getNamedMetadata("llvm.linker.options")) {
- if (Metadata *Val = TheModule->getModuleFlag("Linker Options")) {
- NamedMDNode *LinkerOpts =
- TheModule->getOrInsertNamedMetadata("llvm.linker.options");
- for (const MDOperand &MDOptions : cast<MDNode>(Val)->operands())
- LinkerOpts->addOperand(cast<MDNode>(MDOptions));
- }
+ // metadata. Only upgrade if the new option doesn't exist to avoid upgrade
+ // multiple times.
+ if (!TheModule->getNamedMetadata("llvm.linker.options")) {
+ if (Metadata *Val = TheModule->getModuleFlag("Linker Options")) {
+ NamedMDNode *LinkerOpts =
+ TheModule->getOrInsertNamedMetadata("llvm.linker.options");
+ for (const MDOperand &MDOptions : cast<MDNode>(Val)->operands())
+ LinkerOpts->addOperand(cast<MDNode>(MDOptions));
+ }
}
DeferredMetadataInfo.clear();
@@ -3301,24 +3301,24 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
Func->setLinkage(getDecodedLinkage(RawLinkage));
Func->setAttributes(getAttributes(Record[4]));
- // Upgrade any old-style byval or sret without a type by propagating the
- // argument's pointee type. There should be no opaque pointers where the byval
- // type is implicit.
+ // Upgrade any old-style byval or sret without a type by propagating the
+ // argument's pointee type. There should be no opaque pointers where the byval
+ // type is implicit.
for (unsigned i = 0; i != Func->arg_size(); ++i) {
- for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet}) {
- if (!Func->hasParamAttribute(i, Kind))
- continue;
-
- Func->removeParamAttr(i, Kind);
-
- Type *PTy = cast<FunctionType>(FullFTy)->getParamType(i);
- Type *PtrEltTy = getPointerElementFlatType(PTy);
- Attribute NewAttr =
- Kind == Attribute::ByVal
- ? Attribute::getWithByValType(Context, PtrEltTy)
- : Attribute::getWithStructRetType(Context, PtrEltTy);
- Func->addParamAttr(i, NewAttr);
- }
+ for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet}) {
+ if (!Func->hasParamAttribute(i, Kind))
+ continue;
+
+ Func->removeParamAttr(i, Kind);
+
+ Type *PTy = cast<FunctionType>(FullFTy)->getParamType(i);
+ Type *PtrEltTy = getPointerElementFlatType(PTy);
+ Attribute NewAttr =
+ Kind == Attribute::ByVal
+ ? Attribute::getWithByValType(Context, PtrEltTy)
+ : Attribute::getWithStructRetType(Context, PtrEltTy);
+ Func->addParamAttr(i, NewAttr);
+ }
}
MaybeAlign Alignment;
@@ -3738,7 +3738,7 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
break;
/// MODULE_CODE_VSTOFFSET: [offset]
case bitc::MODULE_CODE_VSTOFFSET:
- if (Record.empty())
+ if (Record.empty())
return error("Invalid record");
// Note that we subtract 1 here because the offset is relative to one word
// before the start of the identification or module block, which was
@@ -3779,22 +3779,22 @@ Error BitcodeReader::typeCheckLoadStoreInst(Type *ValType, Type *PtrType) {
return Error::success();
}
-void BitcodeReader::propagateByValSRetTypes(CallBase *CB,
- ArrayRef<Type *> ArgsFullTys) {
+void BitcodeReader::propagateByValSRetTypes(CallBase *CB,
+ ArrayRef<Type *> ArgsFullTys) {
for (unsigned i = 0; i != CB->arg_size(); ++i) {
- for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet}) {
- if (!CB->paramHasAttr(i, Kind))
- continue;
-
- CB->removeParamAttr(i, Kind);
-
- Type *PtrEltTy = getPointerElementFlatType(ArgsFullTys[i]);
- Attribute NewAttr =
- Kind == Attribute::ByVal
- ? Attribute::getWithByValType(Context, PtrEltTy)
- : Attribute::getWithStructRetType(Context, PtrEltTy);
- CB->addParamAttr(i, NewAttr);
- }
+ for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet}) {
+ if (!CB->paramHasAttr(i, Kind))
+ continue;
+
+ CB->removeParamAttr(i, Kind);
+
+ Type *PtrEltTy = getPointerElementFlatType(ArgsFullTys[i]);
+ Attribute NewAttr =
+ Kind == Attribute::ByVal
+ ? Attribute::getWithByValType(Context, PtrEltTy)
+ : Attribute::getWithStructRetType(Context, PtrEltTy);
+ CB->addParamAttr(i, NewAttr);
+ }
}
}
@@ -3898,7 +3898,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
default: // Default behavior: reject
return error("Invalid value");
case bitc::FUNC_CODE_DECLAREBLOCKS: { // DECLAREBLOCKS: [nblocks]
- if (Record.empty() || Record[0] == 0)
+ if (Record.empty() || Record[0] == 0)
return error("Invalid record");
// Create all the basic blocks for the function.
FunctionBBs.resize(Record[0]);
@@ -3965,8 +3965,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
if (!IA)
return error("Invalid record");
}
- LastLoc = DILocation::get(Scope->getContext(), Line, Col, Scope, IA,
- isImplicitCode);
+ LastLoc = DILocation::get(Scope->getContext(), Line, Col, Scope, IA,
+ isImplicitCode);
I->setDebugLoc(LastLoc);
I = nullptr;
continue;
@@ -4647,7 +4647,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
cast<InvokeInst>(I)->setCallingConv(
static_cast<CallingConv::ID>(CallingConv::MaxID & CCInfo));
cast<InvokeInst>(I)->setAttributes(PAL);
- propagateByValSRetTypes(cast<CallBase>(I), ArgsFullTys);
+ propagateByValSRetTypes(cast<CallBase>(I), ArgsFullTys);
break;
}
@@ -4741,7 +4741,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
InstructionList.push_back(I);
break;
case bitc::FUNC_CODE_INST_PHI: { // PHI: [ty, val0,bb0, ...]
- if (Record.empty())
+ if (Record.empty())
return error("Invalid record");
// The first record specifies the type.
FullTy = getFullyStructuredTypeByID(Record[0]);
@@ -4843,13 +4843,13 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, opty, op, align]
if (Record.size() != 4)
return error("Invalid record");
- using APV = AllocaPackedValues;
- const uint64_t Rec = Record[3];
- const bool InAlloca = Bitfield::get<APV::UsedWithInAlloca>(Rec);
- const bool SwiftError = Bitfield::get<APV::SwiftError>(Rec);
+ using APV = AllocaPackedValues;
+ const uint64_t Rec = Record[3];
+ const bool InAlloca = Bitfield::get<APV::UsedWithInAlloca>(Rec);
+ const bool SwiftError = Bitfield::get<APV::SwiftError>(Rec);
FullTy = getFullyStructuredTypeByID(Record[0]);
Type *Ty = flattenPointerTypes(FullTy);
- if (!Bitfield::get<APV::ExplicitType>(Rec)) {
+ if (!Bitfield::get<APV::ExplicitType>(Rec)) {
auto *PTy = dyn_cast_or_null<PointerType>(Ty);
if (!PTy)
return error("Old-style alloca with a non-pointer type");
@@ -4858,8 +4858,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Type *OpTy = getTypeByID(Record[1]);
Value *Size = getFnValueByID(Record[2], OpTy);
MaybeAlign Align;
- if (Error Err =
- parseAlignmentValue(Bitfield::get<APV::Align>(Rec), Align)) {
+ if (Error Err =
+ parseAlignmentValue(Bitfield::get<APV::Align>(Rec), Align)) {
return Err;
}
if (!Ty || !Size)
@@ -5016,55 +5016,55 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
InstructionList.push_back(I);
break;
}
- case bitc::FUNC_CODE_INST_CMPXCHG_OLD: {
- // CMPXCHG_OLD: [ptrty, ptr, cmp, val, vol, ordering, synchscope,
- // failure_ordering?, weak?]
- const size_t NumRecords = Record.size();
+ case bitc::FUNC_CODE_INST_CMPXCHG_OLD: {
+ // CMPXCHG_OLD: [ptrty, ptr, cmp, val, vol, ordering, synchscope,
+ // failure_ordering?, weak?]
+ const size_t NumRecords = Record.size();
unsigned OpNum = 0;
- Value *Ptr = nullptr;
+ Value *Ptr = nullptr;
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, &FullTy))
return error("Invalid record");
if (!isa<PointerType>(Ptr->getType()))
return error("Cmpxchg operand is not a pointer type");
- Value *Cmp = nullptr;
- if (popValue(Record, OpNum, NextValueNo,
- getPointerElementFlatType(FullTy), Cmp))
+ Value *Cmp = nullptr;
+ if (popValue(Record, OpNum, NextValueNo,
+ getPointerElementFlatType(FullTy), Cmp))
return error("Invalid record");
- FullTy = cast<PointerType>(FullTy)->getElementType();
-
- Value *New = nullptr;
+ FullTy = cast<PointerType>(FullTy)->getElementType();
+
+ Value *New = nullptr;
if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), New) ||
- NumRecords < OpNum + 3 || NumRecords > OpNum + 5)
+ NumRecords < OpNum + 3 || NumRecords > OpNum + 5)
return error("Invalid record");
- const AtomicOrdering SuccessOrdering =
- getDecodedOrdering(Record[OpNum + 1]);
+ const AtomicOrdering SuccessOrdering =
+ getDecodedOrdering(Record[OpNum + 1]);
if (SuccessOrdering == AtomicOrdering::NotAtomic ||
SuccessOrdering == AtomicOrdering::Unordered)
return error("Invalid record");
- const SyncScope::ID SSID = getDecodedSyncScopeID(Record[OpNum + 2]);
-
+ const SyncScope::ID SSID = getDecodedSyncScopeID(Record[OpNum + 2]);
+
if (Error Err = typeCheckLoadStoreInst(Cmp->getType(), Ptr->getType()))
return Err;
- const AtomicOrdering FailureOrdering =
- NumRecords < 7
- ? AtomicCmpXchgInst::getStrongestFailureOrdering(SuccessOrdering)
- : getDecodedOrdering(Record[OpNum + 3]);
-
- const Align Alignment(
+ const AtomicOrdering FailureOrdering =
+ NumRecords < 7
+ ? AtomicCmpXchgInst::getStrongestFailureOrdering(SuccessOrdering)
+ : getDecodedOrdering(Record[OpNum + 3]);
+
+ const Align Alignment(
TheModule->getDataLayout().getTypeStoreSize(Cmp->getType()));
-
+
I = new AtomicCmpXchgInst(Ptr, Cmp, New, Alignment, SuccessOrdering,
FailureOrdering, SSID);
- cast<AtomicCmpXchgInst>(I)->setVolatile(Record[OpNum]);
+ cast<AtomicCmpXchgInst>(I)->setVolatile(Record[OpNum]);
FullTy = StructType::get(Context, {FullTy, Type::getInt1Ty(Context)});
- if (NumRecords < 8) {
+ if (NumRecords < 8) {
// Before weak cmpxchgs existed, the instruction simply returned the
// value loaded from memory, so bitcode files from that era will be
// expecting the first component of a modern cmpxchg.
@@ -5072,59 +5072,59 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
I = ExtractValueInst::Create(I, 0);
FullTy = cast<StructType>(FullTy)->getElementType(0);
} else {
- cast<AtomicCmpXchgInst>(I)->setWeak(Record[OpNum + 4]);
+ cast<AtomicCmpXchgInst>(I)->setWeak(Record[OpNum + 4]);
}
InstructionList.push_back(I);
break;
}
- case bitc::FUNC_CODE_INST_CMPXCHG: {
- // CMPXCHG: [ptrty, ptr, cmp, val, vol, success_ordering, synchscope,
- // failure_ordering, weak]
- const size_t NumRecords = Record.size();
- unsigned OpNum = 0;
- Value *Ptr = nullptr;
- if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, &FullTy))
- return error("Invalid record");
-
- if (!isa<PointerType>(Ptr->getType()))
- return error("Cmpxchg operand is not a pointer type");
-
- Value *Cmp = nullptr;
- if (getValueTypePair(Record, OpNum, NextValueNo, Cmp, &FullTy))
- return error("Invalid record");
-
- Value *Val = nullptr;
- if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), Val) ||
- NumRecords < OpNum + 3 || NumRecords > OpNum + 5)
- return error("Invalid record");
-
- const AtomicOrdering SuccessOrdering =
- getDecodedOrdering(Record[OpNum + 1]);
- if (SuccessOrdering == AtomicOrdering::NotAtomic ||
- SuccessOrdering == AtomicOrdering::Unordered)
- return error("Invalid record");
-
- const SyncScope::ID SSID = getDecodedSyncScopeID(Record[OpNum + 2]);
-
- if (Error Err = typeCheckLoadStoreInst(Cmp->getType(), Ptr->getType()))
- return Err;
-
- const AtomicOrdering FailureOrdering =
- getDecodedOrdering(Record[OpNum + 3]);
-
- const Align Alignment(
- TheModule->getDataLayout().getTypeStoreSize(Cmp->getType()));
-
- I = new AtomicCmpXchgInst(Ptr, Cmp, Val, Alignment, SuccessOrdering,
- FailureOrdering, SSID);
- FullTy = StructType::get(Context, {FullTy, Type::getInt1Ty(Context)});
- cast<AtomicCmpXchgInst>(I)->setVolatile(Record[OpNum]);
- cast<AtomicCmpXchgInst>(I)->setWeak(Record[OpNum + 4]);
-
- InstructionList.push_back(I);
- break;
- }
+ case bitc::FUNC_CODE_INST_CMPXCHG: {
+ // CMPXCHG: [ptrty, ptr, cmp, val, vol, success_ordering, synchscope,
+ // failure_ordering, weak]
+ const size_t NumRecords = Record.size();
+ unsigned OpNum = 0;
+ Value *Ptr = nullptr;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, &FullTy))
+ return error("Invalid record");
+
+ if (!isa<PointerType>(Ptr->getType()))
+ return error("Cmpxchg operand is not a pointer type");
+
+ Value *Cmp = nullptr;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Cmp, &FullTy))
+ return error("Invalid record");
+
+ Value *Val = nullptr;
+ if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), Val) ||
+ NumRecords < OpNum + 3 || NumRecords > OpNum + 5)
+ return error("Invalid record");
+
+ const AtomicOrdering SuccessOrdering =
+ getDecodedOrdering(Record[OpNum + 1]);
+ if (SuccessOrdering == AtomicOrdering::NotAtomic ||
+ SuccessOrdering == AtomicOrdering::Unordered)
+ return error("Invalid record");
+
+ const SyncScope::ID SSID = getDecodedSyncScopeID(Record[OpNum + 2]);
+
+ if (Error Err = typeCheckLoadStoreInst(Cmp->getType(), Ptr->getType()))
+ return Err;
+
+ const AtomicOrdering FailureOrdering =
+ getDecodedOrdering(Record[OpNum + 3]);
+
+ const Align Alignment(
+ TheModule->getDataLayout().getTypeStoreSize(Cmp->getType()));
+
+ I = new AtomicCmpXchgInst(Ptr, Cmp, Val, Alignment, SuccessOrdering,
+ FailureOrdering, SSID);
+ FullTy = StructType::get(Context, {FullTy, Type::getInt1Ty(Context)});
+ cast<AtomicCmpXchgInst>(I)->setVolatile(Record[OpNum]);
+ cast<AtomicCmpXchgInst>(I)->setWeak(Record[OpNum + 4]);
+
+ InstructionList.push_back(I);
+ break;
+ }
case bitc::FUNC_CODE_INST_ATOMICRMW: {
// ATOMICRMW:[ptrty, ptr, val, op, vol, ordering, ssid]
unsigned OpNum = 0;
@@ -5254,7 +5254,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
TCK = CallInst::TCK_NoTail;
cast<CallInst>(I)->setTailCallKind(TCK);
cast<CallInst>(I)->setAttributes(PAL);
- propagateByValSRetTypes(cast<CallBase>(I), ArgsFullTys);
+ propagateByValSRetTypes(cast<CallBase>(I), ArgsFullTys);
if (FMF.any()) {
if (!isa<FPMathOperator>(I))
return error("Fast-math-flags specified for call without "
@@ -5282,7 +5282,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
// number of operand bundle blocks. These blocks are read into
// OperandBundles and consumed at the next call or invoke instruction.
- if (Record.empty() || Record[0] >= BundleTags.size())
+ if (Record.empty() || Record[0] >= BundleTags.size())
return error("Invalid record");
std::vector<Value *> Inputs;
@@ -5472,36 +5472,36 @@ Error BitcodeReader::materialize(GlobalValue *GV) {
}
}
- // "Upgrade" older incorrect branch weights by dropping them.
- for (auto &I : instructions(F)) {
- if (auto *MD = I.getMetadata(LLVMContext::MD_prof)) {
- if (MD->getOperand(0) != nullptr && isa<MDString>(MD->getOperand(0))) {
- MDString *MDS = cast<MDString>(MD->getOperand(0));
- StringRef ProfName = MDS->getString();
- // Check consistency of !prof branch_weights metadata.
- if (!ProfName.equals("branch_weights"))
- continue;
- unsigned ExpectedNumOperands = 0;
- if (BranchInst *BI = dyn_cast<BranchInst>(&I))
- ExpectedNumOperands = BI->getNumSuccessors();
- else if (SwitchInst *SI = dyn_cast<SwitchInst>(&I))
- ExpectedNumOperands = SI->getNumSuccessors();
- else if (isa<CallInst>(&I))
- ExpectedNumOperands = 1;
- else if (IndirectBrInst *IBI = dyn_cast<IndirectBrInst>(&I))
- ExpectedNumOperands = IBI->getNumDestinations();
- else if (isa<SelectInst>(&I))
- ExpectedNumOperands = 2;
- else
- continue; // ignore and continue.
-
- // If branch weight doesn't match, just strip branch weight.
- if (MD->getNumOperands() != 1 + ExpectedNumOperands)
- I.setMetadata(LLVMContext::MD_prof, nullptr);
- }
- }
- }
-
+ // "Upgrade" older incorrect branch weights by dropping them.
+ for (auto &I : instructions(F)) {
+ if (auto *MD = I.getMetadata(LLVMContext::MD_prof)) {
+ if (MD->getOperand(0) != nullptr && isa<MDString>(MD->getOperand(0))) {
+ MDString *MDS = cast<MDString>(MD->getOperand(0));
+ StringRef ProfName = MDS->getString();
+ // Check consistency of !prof branch_weights metadata.
+ if (!ProfName.equals("branch_weights"))
+ continue;
+ unsigned ExpectedNumOperands = 0;
+ if (BranchInst *BI = dyn_cast<BranchInst>(&I))
+ ExpectedNumOperands = BI->getNumSuccessors();
+ else if (SwitchInst *SI = dyn_cast<SwitchInst>(&I))
+ ExpectedNumOperands = SI->getNumSuccessors();
+ else if (isa<CallInst>(&I))
+ ExpectedNumOperands = 1;
+ else if (IndirectBrInst *IBI = dyn_cast<IndirectBrInst>(&I))
+ ExpectedNumOperands = IBI->getNumDestinations();
+ else if (isa<SelectInst>(&I))
+ ExpectedNumOperands = 2;
+ else
+ continue; // ignore and continue.
+
+ // If branch weight doesn't match, just strip branch weight.
+ if (MD->getNumOperands() != 1 + ExpectedNumOperands)
+ I.setMetadata(LLVMContext::MD_prof, nullptr);
+ }
+ }
+ }
+
// Look for functions that rely on old function attribute behavior.
UpgradeFunctionAttributes(*F);
@@ -5815,7 +5815,7 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() {
}
/// MODULE_CODE_VSTOFFSET: [offset]
case bitc::MODULE_CODE_VSTOFFSET:
- if (Record.empty())
+ if (Record.empty())
return error("Invalid record");
// Note that we subtract 1 here because the offset is relative to one
// word before the start of the identification or module block, which
@@ -5933,8 +5933,8 @@ static void parseTypeIdSummaryRecord(ArrayRef<uint64_t> Record,
parseWholeProgramDevirtResolution(Record, Strtab, Slot, TypeId);
}
-std::vector<FunctionSummary::ParamAccess>
-ModuleSummaryIndexBitcodeReader::parseParamAccesses(ArrayRef<uint64_t> Record) {
+std::vector<FunctionSummary::ParamAccess>
+ModuleSummaryIndexBitcodeReader::parseParamAccesses(ArrayRef<uint64_t> Record) {
auto ReadRange = [&]() {
APInt Lower(FunctionSummary::ParamAccess::RangeWidth,
BitcodeReader::decodeSignRotatedValue(Record.front()));
@@ -5960,7 +5960,7 @@ ModuleSummaryIndexBitcodeReader::parseParamAccesses(ArrayRef<uint64_t> Record) {
for (auto &Call : ParamAccess.Calls) {
Call.ParamNo = Record.front();
Record = Record.drop_front();
- Call.Callee = getValueInfoFromValueId(Record.front()).first;
+ Call.Callee = getValueInfoFromValueId(Record.front()).first;
Record = Record.drop_front();
Call.Offsets = ReadRange();
}
@@ -6357,7 +6357,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
}
case bitc::FS_TYPE_TESTS:
assert(PendingTypeTests.empty());
- llvm::append_range(PendingTypeTests, Record);
+ llvm::append_range(PendingTypeTests, Record);
break;
case bitc::FS_TYPE_TEST_ASSUME_VCALLS:
diff --git a/contrib/libs/llvm12/lib/Bitcode/Reader/MetadataLoader.cpp b/contrib/libs/llvm12/lib/Bitcode/Reader/MetadataLoader.cpp
index 4f517ef277..8cdda62870 100644
--- a/contrib/libs/llvm12/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/contrib/libs/llvm12/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -365,7 +365,7 @@ public:
~PlaceholderQueue() {
assert(empty() && "PlaceholderQueue hasn't been flushed before being destroyed");
}
- bool empty() const { return PHs.empty(); }
+ bool empty() const { return PHs.empty(); }
DistinctMDOperandPlaceholder &getPlaceholderOp(unsigned ID);
void flush(BitcodeReaderMetadataList &MetadataList);
@@ -438,20 +438,20 @@ class MetadataLoader::MetadataLoaderImpl {
/// Index that keeps track of where to find a metadata record in the stream.
std::vector<uint64_t> GlobalMetadataBitPosIndex;
- /// Cursor position of the start of the global decl attachments, to enable
- /// loading using the index built for lazy loading, instead of forward
- /// references.
- uint64_t GlobalDeclAttachmentPos = 0;
-
-#ifndef NDEBUG
- /// Sanity check that we end up parsing all of the global decl attachments.
- unsigned NumGlobalDeclAttachSkipped = 0;
- unsigned NumGlobalDeclAttachParsed = 0;
-#endif
-
- /// Load the global decl attachments, using the index built for lazy loading.
- Expected<bool> loadGlobalDeclAttachments();
-
+ /// Cursor position of the start of the global decl attachments, to enable
+ /// loading using the index built for lazy loading, instead of forward
+ /// references.
+ uint64_t GlobalDeclAttachmentPos = 0;
+
+#ifndef NDEBUG
+ /// Sanity check that we end up parsing all of the global decl attachments.
+ unsigned NumGlobalDeclAttachSkipped = 0;
+ unsigned NumGlobalDeclAttachParsed = 0;
+#endif
+
+ /// Load the global decl attachments, using the index built for lazy loading.
+ Expected<bool> loadGlobalDeclAttachments();
+
/// Populate the index above to enable lazily loading of metadata, and load
/// the named metadata as well as the transitively referenced global
/// Metadata.
@@ -676,7 +676,7 @@ public:
return FunctionsWithSPs.lookup(F);
}
- bool hasSeenOldLoopTags() const { return HasSeenOldLoopTags; }
+ bool hasSeenOldLoopTags() const { return HasSeenOldLoopTags; }
Error parseMetadataAttachment(
Function &F, const SmallVectorImpl<Instruction *> &InstructionList);
@@ -684,7 +684,7 @@ public:
Error parseMetadataKinds();
void setStripTBAA(bool Value) { StripTBAA = Value; }
- bool isStrippingTBAA() const { return StripTBAA; }
+ bool isStrippingTBAA() const { return StripTBAA; }
unsigned size() const { return MetadataList.size(); }
void shrinkTo(unsigned N) { MetadataList.shrinkTo(N); }
@@ -695,10 +695,10 @@ Expected<bool>
MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() {
IndexCursor = Stream;
SmallVector<uint64_t, 64> Record;
- GlobalDeclAttachmentPos = 0;
+ GlobalDeclAttachmentPos = 0;
// Get the abbrevs, and preload record positions to make them lazy-loadable.
while (true) {
- uint64_t SavedPos = IndexCursor.GetCurrentBitNo();
+ uint64_t SavedPos = IndexCursor.GetCurrentBitNo();
Expected<BitstreamEntry> MaybeEntry = IndexCursor.advanceSkippingSubblocks(
BitstreamCursor::AF_DontPopBlockAtEnd);
if (!MaybeEntry)
@@ -833,11 +833,11 @@ MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() {
break;
}
case bitc::METADATA_GLOBAL_DECL_ATTACHMENT: {
- if (!GlobalDeclAttachmentPos)
- GlobalDeclAttachmentPos = SavedPos;
-#ifndef NDEBUG
- NumGlobalDeclAttachSkipped++;
-#endif
+ if (!GlobalDeclAttachmentPos)
+ GlobalDeclAttachmentPos = SavedPos;
+#ifndef NDEBUG
+ NumGlobalDeclAttachSkipped++;
+#endif
break;
}
case bitc::METADATA_KIND:
@@ -852,7 +852,7 @@ MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() {
case bitc::METADATA_SUBRANGE:
case bitc::METADATA_ENUMERATOR:
case bitc::METADATA_BASIC_TYPE:
- case bitc::METADATA_STRING_TYPE:
+ case bitc::METADATA_STRING_TYPE:
case bitc::METADATA_DERIVED_TYPE:
case bitc::METADATA_COMPOSITE_TYPE:
case bitc::METADATA_SUBROUTINE_TYPE:
@@ -875,7 +875,7 @@ MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() {
case bitc::METADATA_OBJC_PROPERTY:
case bitc::METADATA_IMPORTED_ENTITY:
case bitc::METADATA_GLOBAL_VAR_EXPR:
- case bitc::METADATA_GENERIC_SUBRANGE:
+ case bitc::METADATA_GENERIC_SUBRANGE:
// We don't expect to see any of these, if we see one, give up on
// lazy-loading and fallback.
MDStringRef.clear();
@@ -888,83 +888,83 @@ MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() {
}
}
-// Load the global decl attachments after building the lazy loading index.
-// We don't load them "lazily" - all global decl attachments must be
-// parsed since they aren't materialized on demand. However, by delaying
-// their parsing until after the index is created, we can use the index
-// instead of creating temporaries.
-Expected<bool> MetadataLoader::MetadataLoaderImpl::loadGlobalDeclAttachments() {
- // Nothing to do if we didn't find any of these metadata records.
- if (!GlobalDeclAttachmentPos)
- return true;
- // Use a temporary cursor so that we don't mess up the main Stream cursor or
- // the lazy loading IndexCursor (which holds the necessary abbrev ids).
- BitstreamCursor TempCursor = Stream;
- SmallVector<uint64_t, 64> Record;
- // Jump to the position before the first global decl attachment, so we can
- // scan for the first BitstreamEntry record.
- if (Error Err = TempCursor.JumpToBit(GlobalDeclAttachmentPos))
- return std::move(Err);
- while (true) {
- Expected<BitstreamEntry> MaybeEntry = TempCursor.advanceSkippingSubblocks(
- BitstreamCursor::AF_DontPopBlockAtEnd);
- if (!MaybeEntry)
- return MaybeEntry.takeError();
- BitstreamEntry Entry = MaybeEntry.get();
-
- switch (Entry.Kind) {
- case BitstreamEntry::SubBlock: // Handled for us already.
- case BitstreamEntry::Error:
- return error("Malformed block");
- case BitstreamEntry::EndBlock:
- // Sanity check that we parsed them all.
- assert(NumGlobalDeclAttachSkipped == NumGlobalDeclAttachParsed);
- return true;
- case BitstreamEntry::Record:
- break;
- }
- uint64_t CurrentPos = TempCursor.GetCurrentBitNo();
- Expected<unsigned> MaybeCode = TempCursor.skipRecord(Entry.ID);
- if (!MaybeCode)
- return MaybeCode.takeError();
- if (MaybeCode.get() != bitc::METADATA_GLOBAL_DECL_ATTACHMENT) {
- // Anything other than a global decl attachment signals the end of
- // these records. sanity check that we parsed them all.
- assert(NumGlobalDeclAttachSkipped == NumGlobalDeclAttachParsed);
- return true;
- }
-#ifndef NDEBUG
- NumGlobalDeclAttachParsed++;
-#endif
- // FIXME: we need to do this early because we don't materialize global
- // value explicitly.
- if (Error Err = TempCursor.JumpToBit(CurrentPos))
- return std::move(Err);
- Record.clear();
- if (Expected<unsigned> MaybeRecord =
- TempCursor.readRecord(Entry.ID, Record))
- ;
- else
- return MaybeRecord.takeError();
- if (Record.size() % 2 == 0)
- return error("Invalid record");
- unsigned ValueID = Record[0];
- if (ValueID >= ValueList.size())
- return error("Invalid record");
- if (auto *GO = dyn_cast<GlobalObject>(ValueList[ValueID])) {
- // Need to save and restore the current position since
- // parseGlobalObjectAttachment will resolve all forward references which
- // would require parsing from locations stored in the index.
- CurrentPos = TempCursor.GetCurrentBitNo();
- if (Error Err = parseGlobalObjectAttachment(
- *GO, ArrayRef<uint64_t>(Record).slice(1)))
- return std::move(Err);
- if (Error Err = TempCursor.JumpToBit(CurrentPos))
- return std::move(Err);
- }
- }
-}
-
+// Load the global decl attachments after building the lazy loading index.
+// We don't load them "lazily" - all global decl attachments must be
+// parsed since they aren't materialized on demand. However, by delaying
+// their parsing until after the index is created, we can use the index
+// instead of creating temporaries.
+Expected<bool> MetadataLoader::MetadataLoaderImpl::loadGlobalDeclAttachments() {
+ // Nothing to do if we didn't find any of these metadata records.
+ if (!GlobalDeclAttachmentPos)
+ return true;
+ // Use a temporary cursor so that we don't mess up the main Stream cursor or
+ // the lazy loading IndexCursor (which holds the necessary abbrev ids).
+ BitstreamCursor TempCursor = Stream;
+ SmallVector<uint64_t, 64> Record;
+ // Jump to the position before the first global decl attachment, so we can
+ // scan for the first BitstreamEntry record.
+ if (Error Err = TempCursor.JumpToBit(GlobalDeclAttachmentPos))
+ return std::move(Err);
+ while (true) {
+ Expected<BitstreamEntry> MaybeEntry = TempCursor.advanceSkippingSubblocks(
+ BitstreamCursor::AF_DontPopBlockAtEnd);
+ if (!MaybeEntry)
+ return MaybeEntry.takeError();
+ BitstreamEntry Entry = MaybeEntry.get();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::SubBlock: // Handled for us already.
+ case BitstreamEntry::Error:
+ return error("Malformed block");
+ case BitstreamEntry::EndBlock:
+ // Sanity check that we parsed them all.
+ assert(NumGlobalDeclAttachSkipped == NumGlobalDeclAttachParsed);
+ return true;
+ case BitstreamEntry::Record:
+ break;
+ }
+ uint64_t CurrentPos = TempCursor.GetCurrentBitNo();
+ Expected<unsigned> MaybeCode = TempCursor.skipRecord(Entry.ID);
+ if (!MaybeCode)
+ return MaybeCode.takeError();
+ if (MaybeCode.get() != bitc::METADATA_GLOBAL_DECL_ATTACHMENT) {
+ // Anything other than a global decl attachment signals the end of
+ // these records. sanity check that we parsed them all.
+ assert(NumGlobalDeclAttachSkipped == NumGlobalDeclAttachParsed);
+ return true;
+ }
+#ifndef NDEBUG
+ NumGlobalDeclAttachParsed++;
+#endif
+ // FIXME: we need to do this early because we don't materialize global
+ // value explicitly.
+ if (Error Err = TempCursor.JumpToBit(CurrentPos))
+ return std::move(Err);
+ Record.clear();
+ if (Expected<unsigned> MaybeRecord =
+ TempCursor.readRecord(Entry.ID, Record))
+ ;
+ else
+ return MaybeRecord.takeError();
+ if (Record.size() % 2 == 0)
+ return error("Invalid record");
+ unsigned ValueID = Record[0];
+ if (ValueID >= ValueList.size())
+ return error("Invalid record");
+ if (auto *GO = dyn_cast<GlobalObject>(ValueList[ValueID])) {
+ // Need to save and restore the current position since
+ // parseGlobalObjectAttachment will resolve all forward references which
+ // would require parsing from locations stored in the index.
+ CurrentPos = TempCursor.GetCurrentBitNo();
+ if (Error Err = parseGlobalObjectAttachment(
+ *GO, ArrayRef<uint64_t>(Record).slice(1)))
+ return std::move(Err);
+ if (Error Err = TempCursor.JumpToBit(CurrentPos))
+ return std::move(Err);
+ }
+ }
+}
+
/// Parse a METADATA_BLOCK. If ModuleLevel is true then we are parsing
/// module level metadata.
Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) {
@@ -994,14 +994,14 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) {
MetadataList.resize(MDStringRef.size() +
GlobalMetadataBitPosIndex.size());
- // Now that we have built the index, load the global decl attachments
- // that were deferred during that process. This avoids creating
- // temporaries.
- SuccessOrErr = loadGlobalDeclAttachments();
- if (!SuccessOrErr)
- return SuccessOrErr.takeError();
- assert(SuccessOrErr.get());
-
+ // Now that we have built the index, load the global decl attachments
+ // that were deferred during that process. This avoids creating
+ // temporaries.
+ SuccessOrErr = loadGlobalDeclAttachments();
+ if (!SuccessOrErr)
+ return SuccessOrErr.takeError();
+ assert(SuccessOrErr.get());
+
// Reading the named metadata created forward references and/or
// placeholders, that we flush here.
resolveForwardRefsAndPlaceholders(Placeholders);
@@ -1372,18 +1372,18 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
NextMetadataNo++;
break;
}
- case bitc::METADATA_GENERIC_SUBRANGE: {
- Metadata *Val = nullptr;
- Val = GET_OR_DISTINCT(DIGenericSubrange,
- (Context, getMDOrNull(Record[1]),
- getMDOrNull(Record[2]), getMDOrNull(Record[3]),
- getMDOrNull(Record[4])));
-
- MetadataList.assignValue(Val, NextMetadataNo);
- IsDistinct = Record[0] & 1;
- NextMetadataNo++;
- break;
- }
+ case bitc::METADATA_GENERIC_SUBRANGE: {
+ Metadata *Val = nullptr;
+ Val = GET_OR_DISTINCT(DIGenericSubrange,
+ (Context, getMDOrNull(Record[1]),
+ getMDOrNull(Record[2]), getMDOrNull(Record[3]),
+ getMDOrNull(Record[4])));
+
+ MetadataList.assignValue(Val, NextMetadataNo);
+ IsDistinct = Record[0] & 1;
+ NextMetadataNo++;
+ break;
+ }
case bitc::METADATA_ENUMERATOR: {
if (Record.size() < 3)
return error("Invalid record");
@@ -1423,20 +1423,20 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
NextMetadataNo++;
break;
}
- case bitc::METADATA_STRING_TYPE: {
- if (Record.size() != 8)
- return error("Invalid record");
-
- IsDistinct = Record[0];
- MetadataList.assignValue(
- GET_OR_DISTINCT(DIStringType,
- (Context, Record[1], getMDString(Record[2]),
- getMDOrNull(Record[3]), getMDOrNull(Record[4]),
- Record[5], Record[6], Record[7])),
- NextMetadataNo);
- NextMetadataNo++;
- break;
- }
+ case bitc::METADATA_STRING_TYPE: {
+ if (Record.size() != 8)
+ return error("Invalid record");
+
+ IsDistinct = Record[0];
+ MetadataList.assignValue(
+ GET_OR_DISTINCT(DIStringType,
+ (Context, Record[1], getMDString(Record[2]),
+ getMDOrNull(Record[3]), getMDOrNull(Record[4]),
+ Record[5], Record[6], Record[7])),
+ NextMetadataNo);
+ NextMetadataNo++;
+ break;
+ }
case bitc::METADATA_DERIVED_TYPE: {
if (Record.size() < 12 || Record.size() > 13)
return error("Invalid record");
@@ -1462,7 +1462,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
break;
}
case bitc::METADATA_COMPOSITE_TYPE: {
- if (Record.size() < 16 || Record.size() > 21)
+ if (Record.size() < 16 || Record.size() > 21)
return error("Invalid record");
// If we have a UUID and this is not a forward declaration, lookup the
@@ -1487,9 +1487,9 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
Metadata *TemplateParams = nullptr;
Metadata *Discriminator = nullptr;
Metadata *DataLocation = nullptr;
- Metadata *Associated = nullptr;
- Metadata *Allocated = nullptr;
- Metadata *Rank = nullptr;
+ Metadata *Associated = nullptr;
+ Metadata *Allocated = nullptr;
+ Metadata *Rank = nullptr;
auto *Identifier = getMDString(Record[15]);
// If this module is being parsed so that it can be ThinLTO imported
// into another module, composite types only need to be imported
@@ -1514,21 +1514,21 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
Discriminator = getMDOrNull(Record[16]);
if (Record.size() > 17)
DataLocation = getMDOrNull(Record[17]);
- if (Record.size() > 19) {
- Associated = getMDOrNull(Record[18]);
- Allocated = getMDOrNull(Record[19]);
- }
- if (Record.size() > 20) {
- Rank = getMDOrNull(Record[20]);
- }
+ if (Record.size() > 19) {
+ Associated = getMDOrNull(Record[18]);
+ Allocated = getMDOrNull(Record[19]);
+ }
+ if (Record.size() > 20) {
+ Rank = getMDOrNull(Record[20]);
+ }
}
DICompositeType *CT = nullptr;
if (Identifier)
CT = DICompositeType::buildODRType(
Context, *Identifier, Tag, Name, File, Line, Scope, BaseType,
SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
- VTableHolder, TemplateParams, Discriminator, DataLocation, Associated,
- Allocated, Rank);
+ VTableHolder, TemplateParams, Discriminator, DataLocation, Associated,
+ Allocated, Rank);
// Create a node if we didn't get a lazy ODR type.
if (!CT)
@@ -1536,8 +1536,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
(Context, Tag, Name, File, Line, Scope, BaseType,
SizeInBits, AlignInBits, OffsetInBits, Flags,
Elements, RuntimeLang, VTableHolder, TemplateParams,
- Identifier, Discriminator, DataLocation, Associated,
- Allocated, Rank));
+ Identifier, Discriminator, DataLocation, Associated,
+ Allocated, Rank));
if (!IsNotUsedInTypeRef && Identifier)
MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT));
@@ -1565,20 +1565,20 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
}
case bitc::METADATA_MODULE: {
- if (Record.size() < 5 || Record.size() > 9)
+ if (Record.size() < 5 || Record.size() > 9)
return error("Invalid record");
- unsigned Offset = Record.size() >= 8 ? 2 : 1;
+ unsigned Offset = Record.size() >= 8 ? 2 : 1;
IsDistinct = Record[0];
MetadataList.assignValue(
GET_OR_DISTINCT(
DIModule,
- (Context, Record.size() >= 8 ? getMDOrNull(Record[1]) : nullptr,
+ (Context, Record.size() >= 8 ? getMDOrNull(Record[1]) : nullptr,
getMDOrNull(Record[0 + Offset]), getMDString(Record[1 + Offset]),
getMDString(Record[2 + Offset]), getMDString(Record[3 + Offset]),
getMDString(Record[4 + Offset]),
- Record.size() <= 7 ? 0 : Record[7],
- Record.size() <= 8 ? false : Record[8])),
+ Record.size() <= 7 ? 0 : Record[7],
+ Record.size() <= 8 ? false : Record[8])),
NextMetadataNo);
NextMetadataNo++;
break;
@@ -2126,8 +2126,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseGlobalObjectAttachment(
auto K = MDKindMap.find(Record[I]);
if (K == MDKindMap.end())
return error("Invalid ID");
- MDNode *MD =
- dyn_cast_or_null<MDNode>(getMetadataFwdRefOrLoad(Record[I + 1]));
+ MDNode *MD =
+ dyn_cast_or_null<MDNode>(getMetadataFwdRefOrLoad(Record[I + 1]));
if (!MD)
return error("Invalid metadata attachment: expect fwd ref to MDNode");
GO.addMetadata(K->second, *MD);
diff --git a/contrib/libs/llvm12/lib/Bitcode/Reader/ya.make b/contrib/libs/llvm12/lib/Bitcode/Reader/ya.make
index 12ecee8a38..c648d2fc66 100644
--- a/contrib/libs/llvm12/lib/Bitcode/Reader/ya.make
+++ b/contrib/libs/llvm12/lib/Bitcode/Reader/ya.make
@@ -12,11 +12,11 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Bitstream/Reader
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Bitstream/Reader
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/Bitcode/Writer/BitcodeWriter.cpp b/contrib/libs/llvm12/lib/Bitcode/Writer/BitcodeWriter.cpp
index d653669bf6..37ecb9992e 100644
--- a/contrib/libs/llvm12/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/contrib/libs/llvm12/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -24,7 +24,7 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
-#include "llvm/Bitcode/BitcodeCommon.h"
+#include "llvm/Bitcode/BitcodeCommon.h"
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/Bitcode/LLVMBitCodes.h"
#include "llvm/Bitstream/BitCodes.h"
@@ -86,9 +86,9 @@ static cl::opt<unsigned>
IndexThreshold("bitcode-mdindex-threshold", cl::Hidden, cl::init(25),
cl::desc("Number of metadatas above which we emit an index "
"to enable lazy-loading"));
-static cl::opt<uint32_t> FlushThreshold(
- "bitcode-flush-threshold", cl::Hidden, cl::init(512),
- cl::desc("The threshold (unit M) for flushing LLVM bitcode."));
+static cl::opt<uint32_t> FlushThreshold(
+ "bitcode-flush-threshold", cl::Hidden, cl::init(512),
+ cl::desc("The threshold (unit M) for flushing LLVM bitcode."));
static cl::opt<bool> WriteRelBFToSummary(
"write-relbf-to-summary", cl::Hidden, cl::init(false),
@@ -300,15 +300,15 @@ private:
SmallVectorImpl<uint64_t> &Record, unsigned &Abbrev);
void writeDISubrange(const DISubrange *N, SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev);
- void writeDIGenericSubrange(const DIGenericSubrange *N,
- SmallVectorImpl<uint64_t> &Record,
- unsigned Abbrev);
+ void writeDIGenericSubrange(const DIGenericSubrange *N,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev);
void writeDIEnumerator(const DIEnumerator *N,
SmallVectorImpl<uint64_t> &Record, unsigned Abbrev);
void writeDIBasicType(const DIBasicType *N, SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev);
- void writeDIStringType(const DIStringType *N,
- SmallVectorImpl<uint64_t> &Record, unsigned Abbrev);
+ void writeDIStringType(const DIStringType *N,
+ SmallVectorImpl<uint64_t> &Record, unsigned Abbrev);
void writeDIDerivedType(const DIDerivedType *N,
SmallVectorImpl<uint64_t> &Record, unsigned Abbrev);
void writeDICompositeType(const DICompositeType *N,
@@ -403,8 +403,8 @@ private:
unsigned getEncodedSyncScopeID(SyncScope::ID SSID) {
return unsigned(SSID);
}
-
- unsigned getEncodedAlign(MaybeAlign Alignment) { return encode(Alignment); }
+
+ unsigned getEncodedAlign(MaybeAlign Alignment) { return encode(Alignment); }
};
/// Class to manage the bitcode writing for a combined index.
@@ -626,8 +626,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_IN_ALLOCA;
case Attribute::Cold:
return bitc::ATTR_KIND_COLD;
- case Attribute::Hot:
- return bitc::ATTR_KIND_HOT;
+ case Attribute::Hot:
+ return bitc::ATTR_KIND_HOT;
case Attribute::InaccessibleMemOnly:
return bitc::ATTR_KIND_INACCESSIBLEMEM_ONLY;
case Attribute::InaccessibleMemOrArgMemOnly:
@@ -648,8 +648,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_NO_ALIAS;
case Attribute::NoBuiltin:
return bitc::ATTR_KIND_NO_BUILTIN;
- case Attribute::NoCallback:
- return bitc::ATTR_KIND_NO_CALLBACK;
+ case Attribute::NoCallback:
+ return bitc::ATTR_KIND_NO_CALLBACK;
case Attribute::NoCapture:
return bitc::ATTR_KIND_NO_CAPTURE;
case Attribute::NoDuplicate:
@@ -680,8 +680,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_NOSYNC;
case Attribute::NoCfCheck:
return bitc::ATTR_KIND_NOCF_CHECK;
- case Attribute::NoProfile:
- return bitc::ATTR_KIND_NO_PROFILE;
+ case Attribute::NoProfile:
+ return bitc::ATTR_KIND_NO_PROFILE;
case Attribute::NoUnwind:
return bitc::ATTR_KIND_NO_UNWIND;
case Attribute::NullPointerIsValid:
@@ -750,10 +750,10 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_PREALLOCATED;
case Attribute::NoUndef:
return bitc::ATTR_KIND_NOUNDEF;
- case Attribute::ByRef:
- return bitc::ATTR_KIND_BYREF;
- case Attribute::MustProgress:
- return bitc::ATTR_KIND_MUSTPROGRESS;
+ case Attribute::ByRef:
+ return bitc::ATTR_KIND_BYREF;
+ case Attribute::MustProgress:
+ return bitc::ATTR_KIND_MUSTPROGRESS;
case Attribute::EndAttrKinds:
llvm_unreachable("Can not encode end-attribute kinds marker.");
case Attribute::None:
@@ -915,7 +915,7 @@ void ModuleBitcodeWriter::writeTypeTable() {
case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break;
case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break;
case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break;
- case Type::X86_AMXTyID: Code = bitc::TYPE_CODE_X86_AMX; break;
+ case Type::X86_AMXTyID: Code = bitc::TYPE_CODE_X86_AMX; break;
case Type::TokenTyID: Code = bitc::TYPE_CODE_TOKEN; break;
case Type::IntegerTyID:
// INTEGER: [width]
@@ -985,7 +985,7 @@ void ModuleBitcodeWriter::writeTypeTable() {
// VECTOR [numelts, eltty] or
// [numelts, eltty, scalable]
Code = bitc::TYPE_CODE_VECTOR;
- TypeVals.push_back(VT->getElementCount().getKnownMinValue());
+ TypeVals.push_back(VT->getElementCount().getKnownMinValue());
TypeVals.push_back(VE.getTypeID(VT->getElementType()));
if (isa<ScalableVectorType>(VT))
TypeVals.push_back(true);
@@ -1201,14 +1201,14 @@ void ModuleBitcodeWriter::writeModuleInfo() {
// compute the maximum alignment value.
std::map<std::string, unsigned> SectionMap;
std::map<std::string, unsigned> GCMap;
- MaybeAlign MaxAlignment;
+ MaybeAlign MaxAlignment;
unsigned MaxGlobalType = 0;
- const auto UpdateMaxAlignment = [&MaxAlignment](const MaybeAlign A) {
- if (A)
- MaxAlignment = !MaxAlignment ? *A : std::max(*MaxAlignment, *A);
- };
+ const auto UpdateMaxAlignment = [&MaxAlignment](const MaybeAlign A) {
+ if (A)
+ MaxAlignment = !MaxAlignment ? *A : std::max(*MaxAlignment, *A);
+ };
for (const GlobalVariable &GV : M.globals()) {
- UpdateMaxAlignment(GV.getAlign());
+ UpdateMaxAlignment(GV.getAlign());
MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV.getValueType()));
if (GV.hasSection()) {
// Give section names unique ID's.
@@ -1221,7 +1221,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
}
}
for (const Function &F : M) {
- UpdateMaxAlignment(F.getAlign());
+ UpdateMaxAlignment(F.getAlign());
if (F.hasSection()) {
// Give section names unique ID's.
unsigned &Entry = SectionMap[std::string(F.getSection())];
@@ -1257,10 +1257,10 @@ void ModuleBitcodeWriter::writeModuleInfo() {
//| constant
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Initializer.
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // Linkage.
- if (!MaxAlignment) // Alignment.
+ if (!MaxAlignment) // Alignment.
Abbv->Add(BitCodeAbbrevOp(0));
else {
- unsigned MaxEncAlignment = getEncodedAlign(MaxAlignment);
+ unsigned MaxEncAlignment = getEncodedAlign(MaxAlignment);
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
Log2_32_Ceil(MaxEncAlignment+1)));
}
@@ -1313,7 +1313,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
Vals.push_back(GV.isDeclaration() ? 0 :
(VE.getValueID(GV.getInitializer()) + 1));
Vals.push_back(getEncodedLinkage(GV));
- Vals.push_back(getEncodedAlign(GV.getAlign()));
+ Vals.push_back(getEncodedAlign(GV.getAlign()));
Vals.push_back(GV.hasSection() ? SectionMap[std::string(GV.getSection())]
: 0);
if (GV.isThreadLocal() ||
@@ -1359,7 +1359,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
Vals.push_back(F.isDeclaration());
Vals.push_back(getEncodedLinkage(F));
Vals.push_back(VE.getAttributeListID(F.getAttributes()));
- Vals.push_back(getEncodedAlign(F.getAlign()));
+ Vals.push_back(getEncodedAlign(F.getAlign()));
Vals.push_back(F.hasSection() ? SectionMap[std::string(F.getSection())]
: 0);
Vals.push_back(getEncodedVisibility(F));
@@ -1561,19 +1561,19 @@ void ModuleBitcodeWriter::writeDISubrange(const DISubrange *N,
Record.clear();
}
-void ModuleBitcodeWriter::writeDIGenericSubrange(
- const DIGenericSubrange *N, SmallVectorImpl<uint64_t> &Record,
- unsigned Abbrev) {
- Record.push_back((uint64_t)N->isDistinct());
- Record.push_back(VE.getMetadataOrNullID(N->getRawCountNode()));
- Record.push_back(VE.getMetadataOrNullID(N->getRawLowerBound()));
- Record.push_back(VE.getMetadataOrNullID(N->getRawUpperBound()));
- Record.push_back(VE.getMetadataOrNullID(N->getRawStride()));
-
- Stream.EmitRecord(bitc::METADATA_GENERIC_SUBRANGE, Record, Abbrev);
- Record.clear();
-}
-
+void ModuleBitcodeWriter::writeDIGenericSubrange(
+ const DIGenericSubrange *N, SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back((uint64_t)N->isDistinct());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawCountNode()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawLowerBound()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawUpperBound()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawStride()));
+
+ Stream.EmitRecord(bitc::METADATA_GENERIC_SUBRANGE, Record, Abbrev);
+ Record.clear();
+}
+
static void emitSignedInt64(SmallVectorImpl<uint64_t> &Vals, uint64_t V) {
if ((int64_t)V >= 0)
Vals.push_back(V << 1);
@@ -1620,22 +1620,22 @@ void ModuleBitcodeWriter::writeDIBasicType(const DIBasicType *N,
Record.clear();
}
-void ModuleBitcodeWriter::writeDIStringType(const DIStringType *N,
- SmallVectorImpl<uint64_t> &Record,
- unsigned Abbrev) {
- Record.push_back(N->isDistinct());
- Record.push_back(N->getTag());
- Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
- Record.push_back(VE.getMetadataOrNullID(N->getStringLength()));
- Record.push_back(VE.getMetadataOrNullID(N->getStringLengthExp()));
- Record.push_back(N->getSizeInBits());
- Record.push_back(N->getAlignInBits());
- Record.push_back(N->getEncoding());
-
- Stream.EmitRecord(bitc::METADATA_STRING_TYPE, Record, Abbrev);
- Record.clear();
-}
-
+void ModuleBitcodeWriter::writeDIStringType(const DIStringType *N,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(N->getTag());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
+ Record.push_back(VE.getMetadataOrNullID(N->getStringLength()));
+ Record.push_back(VE.getMetadataOrNullID(N->getStringLengthExp()));
+ Record.push_back(N->getSizeInBits());
+ Record.push_back(N->getAlignInBits());
+ Record.push_back(N->getEncoding());
+
+ Stream.EmitRecord(bitc::METADATA_STRING_TYPE, Record, Abbrev);
+ Record.clear();
+}
+
void ModuleBitcodeWriter::writeDIDerivedType(const DIDerivedType *N,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
@@ -1685,9 +1685,9 @@ void ModuleBitcodeWriter::writeDICompositeType(
Record.push_back(VE.getMetadataOrNullID(N->getRawIdentifier()));
Record.push_back(VE.getMetadataOrNullID(N->getDiscriminator()));
Record.push_back(VE.getMetadataOrNullID(N->getRawDataLocation()));
- Record.push_back(VE.getMetadataOrNullID(N->getRawAssociated()));
- Record.push_back(VE.getMetadataOrNullID(N->getRawAllocated()));
- Record.push_back(VE.getMetadataOrNullID(N->getRawRank()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawAssociated()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawAllocated()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawRank()));
Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev);
Record.clear();
@@ -1871,7 +1871,7 @@ void ModuleBitcodeWriter::writeDIModule(const DIModule *N,
for (auto &I : N->operands())
Record.push_back(VE.getMetadataOrNullID(I));
Record.push_back(N->getLineNo());
- Record.push_back(N->getIsDecl());
+ Record.push_back(N->getIsDecl());
Stream.EmitRecord(bitc::METADATA_MODULE, Record, Abbrev);
Record.clear();
@@ -2433,8 +2433,8 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
unsigned AbbrevToUse = 0;
if (C->isNullValue()) {
Code = bitc::CST_CODE_NULL;
- } else if (isa<PoisonValue>(C)) {
- Code = bitc::CST_CODE_POISON;
+ } else if (isa<PoisonValue>(C)) {
+ Code = bitc::CST_CODE_POISON;
} else if (isa<UndefValue>(C)) {
Code = bitc::CST_CODE_UNDEF;
} else if (const ConstantInt *IV = dyn_cast<ConstantInt>(C)) {
@@ -3002,13 +3002,13 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I,
Vals.push_back(VE.getTypeID(AI.getAllocatedType()));
Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
Vals.push_back(VE.getValueID(I.getOperand(0))); // size.
- using APV = AllocaPackedValues;
- unsigned Record = 0;
- Bitfield::set<APV::Align>(Record, getEncodedAlign(AI.getAlign()));
- Bitfield::set<APV::UsedWithInAlloca>(Record, AI.isUsedWithInAlloca());
- Bitfield::set<APV::ExplicitType>(Record, true);
- Bitfield::set<APV::SwiftError>(Record, AI.isSwiftError());
- Vals.push_back(Record);
+ using APV = AllocaPackedValues;
+ unsigned Record = 0;
+ Bitfield::set<APV::Align>(Record, getEncodedAlign(AI.getAlign()));
+ Bitfield::set<APV::UsedWithInAlloca>(Record, AI.isUsedWithInAlloca());
+ Bitfield::set<APV::ExplicitType>(Record, true);
+ Bitfield::set<APV::SwiftError>(Record, AI.isSwiftError());
+ Vals.push_back(Record);
break;
}
@@ -3022,7 +3022,7 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I,
AbbrevToUse = FUNCTION_INST_LOAD_ABBREV;
}
Vals.push_back(VE.getTypeID(I.getType()));
- Vals.push_back(getEncodedAlign(cast<LoadInst>(I).getAlign()));
+ Vals.push_back(getEncodedAlign(cast<LoadInst>(I).getAlign()));
Vals.push_back(cast<LoadInst>(I).isVolatile());
if (cast<LoadInst>(I).isAtomic()) {
Vals.push_back(getEncodedOrdering(cast<LoadInst>(I).getOrdering()));
@@ -3036,7 +3036,7 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I,
Code = bitc::FUNC_CODE_INST_STORE;
pushValueAndType(I.getOperand(1), InstID, Vals); // ptrty + ptr
pushValueAndType(I.getOperand(0), InstID, Vals); // valty + val
- Vals.push_back(getEncodedAlign(cast<StoreInst>(I).getAlign()));
+ Vals.push_back(getEncodedAlign(cast<StoreInst>(I).getAlign()));
Vals.push_back(cast<StoreInst>(I).isVolatile());
if (cast<StoreInst>(I).isAtomic()) {
Vals.push_back(getEncodedOrdering(cast<StoreInst>(I).getOrdering()));
@@ -3599,10 +3599,10 @@ void IndexBitcodeWriter::writeModStrings() {
/// Write the function type metadata related records that need to appear before
/// a function summary entry (whether per-module or combined).
-template <typename Fn>
+template <typename Fn>
static void writeFunctionTypeMetadataRecords(BitstreamWriter &Stream,
- FunctionSummary *FS,
- Fn GetValueID) {
+ FunctionSummary *FS,
+ Fn GetValueID) {
if (!FS->type_tests().empty())
Stream.EmitRecord(bitc::FS_TYPE_TESTS, FS->type_tests());
@@ -3631,7 +3631,7 @@ static void writeFunctionTypeMetadataRecords(BitstreamWriter &Stream,
Record.clear();
Record.push_back(VC.VFunc.GUID);
Record.push_back(VC.VFunc.Offset);
- llvm::append_range(Record, VC.Args);
+ llvm::append_range(Record, VC.Args);
Stream.EmitRecord(Ty, Record);
}
};
@@ -3652,25 +3652,25 @@ static void writeFunctionTypeMetadataRecords(BitstreamWriter &Stream,
if (!FS->paramAccesses().empty()) {
Record.clear();
for (auto &Arg : FS->paramAccesses()) {
- size_t UndoSize = Record.size();
+ size_t UndoSize = Record.size();
Record.push_back(Arg.ParamNo);
WriteRange(Arg.Use);
Record.push_back(Arg.Calls.size());
for (auto &Call : Arg.Calls) {
Record.push_back(Call.ParamNo);
- Optional<unsigned> ValueID = GetValueID(Call.Callee);
- if (!ValueID) {
- // If ValueID is unknown we can't drop just this call, we must drop
- // entire parameter.
- Record.resize(UndoSize);
- break;
- }
- Record.push_back(*ValueID);
+ Optional<unsigned> ValueID = GetValueID(Call.Callee);
+ if (!ValueID) {
+ // If ValueID is unknown we can't drop just this call, we must drop
+ // entire parameter.
+ Record.resize(UndoSize);
+ break;
+ }
+ Record.push_back(*ValueID);
WriteRange(Call.Offsets);
}
}
- if (!Record.empty())
- Stream.EmitRecord(bitc::FS_PARAM_ACCESS, Record);
+ if (!Record.empty())
+ Stream.EmitRecord(bitc::FS_PARAM_ACCESS, Record);
}
}
@@ -3705,7 +3705,7 @@ static void writeWholeProgramDevirtResolutionByArg(
SmallVector<uint64_t, 64> &NameVals, const std::vector<uint64_t> &args,
const WholeProgramDevirtResolution::ByArg &ByArg) {
NameVals.push_back(args.size());
- llvm::append_range(NameVals, args);
+ llvm::append_range(NameVals, args);
NameVals.push_back(ByArg.TheKind);
NameVals.push_back(ByArg.Info);
@@ -3768,11 +3768,11 @@ void ModuleBitcodeWriterBase::writePerModuleFunctionSummaryRecord(
FunctionSummary *FS = cast<FunctionSummary>(Summary);
- writeFunctionTypeMetadataRecords(
- Stream, FS, [&](const ValueInfo &VI) -> Optional<unsigned> {
- return {VE.getValueID(VI.getValue())};
- });
-
+ writeFunctionTypeMetadataRecords(
+ Stream, FS, [&](const ValueInfo &VI) -> Optional<unsigned> {
+ return {VE.getValueID(VI.getValue())};
+ });
+
auto SpecialRefCnts = FS->specialRefCounts();
NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));
NameVals.push_back(FS->instCount());
@@ -3832,7 +3832,7 @@ void ModuleBitcodeWriterBase::writeModuleLevelReferences(
NameVals.push_back(VE.getValueID(RI.getValue()));
// Sort the refs for determinism output, the vector returned by FS->refs() has
// been initialized from a DenseSet.
- llvm::sort(drop_begin(NameVals, SizeBeforeRefs));
+ llvm::sort(drop_begin(NameVals, SizeBeforeRefs));
if (VTableFuncs.empty())
Stream.EmitRecord(bitc::FS_PERMODULE_GLOBALVAR_INIT_REFS, NameVals,
@@ -4148,38 +4148,38 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
return;
}
- auto GetValueId = [&](const ValueInfo &VI) -> Optional<unsigned> {
- GlobalValue::GUID GUID = VI.getGUID();
- Optional<unsigned> CallValueId = getValueId(GUID);
- if (CallValueId)
- return CallValueId;
- // For SamplePGO, the indirect call targets for local functions will
- // have its original name annotated in profile. We try to find the
- // corresponding PGOFuncName as the GUID.
- GUID = Index.getGUIDFromOriginalID(GUID);
- if (!GUID)
- return None;
- CallValueId = getValueId(GUID);
- if (!CallValueId)
- return None;
- // The mapping from OriginalId to GUID may return a GUID
- // that corresponds to a static variable. Filter it out here.
- // This can happen when
- // 1) There is a call to a library function which does not have
- // a CallValidId;
- // 2) There is a static variable with the OriginalGUID identical
- // to the GUID of the library function in 1);
- // When this happens, the logic for SamplePGO kicks in and
- // the static variable in 2) will be found, which needs to be
- // filtered out.
- auto *GVSum = Index.getGlobalValueSummary(GUID, false);
- if (GVSum && GVSum->getSummaryKind() == GlobalValueSummary::GlobalVarKind)
- return None;
- return CallValueId;
- };
-
+ auto GetValueId = [&](const ValueInfo &VI) -> Optional<unsigned> {
+ GlobalValue::GUID GUID = VI.getGUID();
+ Optional<unsigned> CallValueId = getValueId(GUID);
+ if (CallValueId)
+ return CallValueId;
+ // For SamplePGO, the indirect call targets for local functions will
+ // have its original name annotated in profile. We try to find the
+ // corresponding PGOFuncName as the GUID.
+ GUID = Index.getGUIDFromOriginalID(GUID);
+ if (!GUID)
+ return None;
+ CallValueId = getValueId(GUID);
+ if (!CallValueId)
+ return None;
+ // The mapping from OriginalId to GUID may return a GUID
+ // that corresponds to a static variable. Filter it out here.
+ // This can happen when
+ // 1) There is a call to a library function which does not have
+ // a CallValidId;
+ // 2) There is a static variable with the OriginalGUID identical
+ // to the GUID of the library function in 1);
+ // When this happens, the logic for SamplePGO kicks in and
+ // the static variable in 2) will be found, which needs to be
+ // filtered out.
+ auto *GVSum = Index.getGlobalValueSummary(GUID, false);
+ if (GVSum && GVSum->getSummaryKind() == GlobalValueSummary::GlobalVarKind)
+ return None;
+ return CallValueId;
+ };
+
auto *FS = cast<FunctionSummary>(S);
- writeFunctionTypeMetadataRecords(Stream, FS, GetValueId);
+ writeFunctionTypeMetadataRecords(Stream, FS, GetValueId);
getReferencedTypeIds(FS, ReferencedTypeIds);
NameVals.push_back(*ValueId);
@@ -4221,9 +4221,9 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
for (auto &EI : FS->calls()) {
// If this GUID doesn't have a value id, it doesn't have a function
// summary and we don't need to record any calls to it.
- Optional<unsigned> CallValueId = GetValueId(EI.first);
- if (!CallValueId)
- continue;
+ Optional<unsigned> CallValueId = GetValueId(EI.first);
+ if (!CallValueId)
+ continue;
NameVals.push_back(*CallValueId);
if (HasProfileData)
NameVals.push_back(static_cast<uint8_t>(EI.second.Hotness));
@@ -4485,8 +4485,8 @@ static void writeBitcodeHeader(BitstreamWriter &Stream) {
Stream.Emit(0xD, 4);
}
-BitcodeWriter::BitcodeWriter(SmallVectorImpl<char> &Buffer, raw_fd_stream *FS)
- : Buffer(Buffer), Stream(new BitstreamWriter(Buffer, FS, FlushThreshold)) {
+BitcodeWriter::BitcodeWriter(SmallVectorImpl<char> &Buffer, raw_fd_stream *FS)
+ : Buffer(Buffer), Stream(new BitstreamWriter(Buffer, FS, FlushThreshold)) {
writeBitcodeHeader(*Stream);
}
@@ -4597,7 +4597,7 @@ void llvm::WriteBitcodeToFile(const Module &M, raw_ostream &Out,
if (TT.isOSDarwin() || TT.isOSBinFormatMachO())
Buffer.insert(Buffer.begin(), BWH_HeaderSize, 0);
- BitcodeWriter Writer(Buffer, dyn_cast<raw_fd_stream>(&Out));
+ BitcodeWriter Writer(Buffer, dyn_cast<raw_fd_stream>(&Out));
Writer.writeModule(M, ShouldPreserveUseListOrder, Index, GenerateHash,
ModHash);
Writer.writeSymtab();
@@ -4607,8 +4607,8 @@ void llvm::WriteBitcodeToFile(const Module &M, raw_ostream &Out,
emitDarwinBCHeaderAndTrailer(Buffer, TT);
// Write the generated bitstream to "Out".
- if (!Buffer.empty())
- Out.write((char *)&Buffer.front(), Buffer.size());
+ if (!Buffer.empty())
+ Out.write((char *)&Buffer.front(), Buffer.size());
}
void IndexBitcodeWriter::write() {
@@ -4812,9 +4812,9 @@ static const char *getSectionNameForBitcode(const Triple &T) {
case Triple::Wasm:
case Triple::UnknownObjectFormat:
return ".llvmbc";
- case Triple::GOFF:
- llvm_unreachable("GOFF is not yet implemented");
- break;
+ case Triple::GOFF:
+ llvm_unreachable("GOFF is not yet implemented");
+ break;
case Triple::XCOFF:
llvm_unreachable("XCOFF is not yet implemented");
break;
@@ -4831,9 +4831,9 @@ static const char *getSectionNameForCommandline(const Triple &T) {
case Triple::Wasm:
case Triple::UnknownObjectFormat:
return ".llvmcmd";
- case Triple::GOFF:
- llvm_unreachable("GOFF is not yet implemented");
- break;
+ case Triple::GOFF:
+ llvm_unreachable("GOFF is not yet implemented");
+ break;
case Triple::XCOFF:
llvm_unreachable("XCOFF is not yet implemented");
break;
@@ -4842,8 +4842,8 @@ static const char *getSectionNameForCommandline(const Triple &T) {
}
void llvm::EmbedBitcodeInModule(llvm::Module &M, llvm::MemoryBufferRef Buf,
- bool EmbedBitcode, bool EmbedCmdline,
- const std::vector<uint8_t> &CmdArgs) {
+ bool EmbedBitcode, bool EmbedCmdline,
+ const std::vector<uint8_t> &CmdArgs) {
// Save llvm.compiler.used and remove it.
SmallVector<Constant *, 2> UsedArray;
SmallPtrSet<GlobalValue *, 4> UsedGlobals;
@@ -4862,10 +4862,10 @@ void llvm::EmbedBitcodeInModule(llvm::Module &M, llvm::MemoryBufferRef Buf,
std::string Data;
ArrayRef<uint8_t> ModuleData;
Triple T(M.getTargetTriple());
-
+
if (EmbedBitcode) {
- if (Buf.getBufferSize() == 0 ||
- !isBitcode((const unsigned char *)Buf.getBufferStart(),
+ if (Buf.getBufferSize() == 0 ||
+ !isBitcode((const unsigned char *)Buf.getBufferStart(),
(const unsigned char *)Buf.getBufferEnd())) {
// If the input is LLVM Assembly, bitcode is produced by serializing
// the module. Use-lists order need to be preserved in this case.
@@ -4884,9 +4884,9 @@ void llvm::EmbedBitcodeInModule(llvm::Module &M, llvm::MemoryBufferRef Buf,
M, ModuleConstant->getType(), true, llvm::GlobalValue::PrivateLinkage,
ModuleConstant);
GV->setSection(getSectionNameForBitcode(T));
- // Set alignment to 1 to prevent padding between two contributions from input
- // sections after linking.
- GV->setAlignment(Align(1));
+ // Set alignment to 1 to prevent padding between two contributions from input
+ // sections after linking.
+ GV->setAlignment(Align(1));
UsedArray.push_back(
ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType));
if (llvm::GlobalVariable *Old =
@@ -4900,17 +4900,17 @@ void llvm::EmbedBitcodeInModule(llvm::Module &M, llvm::MemoryBufferRef Buf,
}
// Skip if only bitcode needs to be embedded.
- if (EmbedCmdline) {
+ if (EmbedCmdline) {
// Embed command-line options.
- ArrayRef<uint8_t> CmdData(const_cast<uint8_t *>(CmdArgs.data()),
- CmdArgs.size());
+ ArrayRef<uint8_t> CmdData(const_cast<uint8_t *>(CmdArgs.data()),
+ CmdArgs.size());
llvm::Constant *CmdConstant =
llvm::ConstantDataArray::get(M.getContext(), CmdData);
GV = new llvm::GlobalVariable(M, CmdConstant->getType(), true,
llvm::GlobalValue::PrivateLinkage,
CmdConstant);
GV->setSection(getSectionNameForCommandline(T));
- GV->setAlignment(Align(1));
+ GV->setAlignment(Align(1));
UsedArray.push_back(
ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType));
if (llvm::GlobalVariable *Old = M.getGlobalVariable("llvm.cmdline", true)) {
diff --git a/contrib/libs/llvm12/lib/Bitcode/Writer/ValueEnumerator.cpp b/contrib/libs/llvm12/lib/Bitcode/Writer/ValueEnumerator.cpp
index d7b3b19844..bbee8b3249 100644
--- a/contrib/libs/llvm12/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/contrib/libs/llvm12/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -78,16 +78,16 @@ struct OrderMap {
} // end anonymous namespace
-/// Look for a value that might be wrapped as metadata, e.g. a value in a
-/// metadata operand. Returns nullptr for a non-wrapped input value if
-/// OnlyWrapped is true, or it returns the input value as-is if false.
-static const Value *skipMetadataWrapper(const Value *V, bool OnlyWrapped) {
- if (const auto *MAV = dyn_cast<MetadataAsValue>(V))
- if (const auto *VAM = dyn_cast<ValueAsMetadata>(MAV->getMetadata()))
- return VAM->getValue();
- return OnlyWrapped ? nullptr : V;
-}
-
+/// Look for a value that might be wrapped as metadata, e.g. a value in a
+/// metadata operand. Returns nullptr for a non-wrapped input value if
+/// OnlyWrapped is true, or it returns the input value as-is if false.
+static const Value *skipMetadataWrapper(const Value *V, bool OnlyWrapped) {
+ if (const auto *MAV = dyn_cast<MetadataAsValue>(V))
+ if (const auto *VAM = dyn_cast<ValueAsMetadata>(MAV->getMetadata()))
+ return VAM->getValue();
+ return OnlyWrapped ? nullptr : V;
+}
+
static void orderValue(const Value *V, OrderMap &OM) {
if (OM.lookup(V).first)
return;
@@ -133,25 +133,25 @@ static OrderMap orderModule(const Module &M) {
if (!isa<GlobalValue>(U.get()))
orderValue(U.get(), OM);
}
-
- // As constants used in metadata operands are emitted as module-level
- // constants, we must order them before other operands. Also, we must order
- // these before global values, as these will be read before setting the
- // global values' initializers. The latter matters for constants which have
- // uses towards other constants that are used as initializers.
- for (const Function &F : M) {
- if (F.isDeclaration())
- continue;
- for (const BasicBlock &BB : F)
- for (const Instruction &I : BB)
- for (const Value *V : I.operands()) {
- if (const Value *Op = skipMetadataWrapper(V, true)) {
- if ((isa<Constant>(*Op) && !isa<GlobalValue>(*Op)) ||
- isa<InlineAsm>(*Op))
- orderValue(Op, OM);
- }
- }
- }
+
+ // As constants used in metadata operands are emitted as module-level
+ // constants, we must order them before other operands. Also, we must order
+ // these before global values, as these will be read before setting the
+ // global values' initializers. The latter matters for constants which have
+ // uses towards other constants that are used as initializers.
+ for (const Function &F : M) {
+ if (F.isDeclaration())
+ continue;
+ for (const BasicBlock &BB : F)
+ for (const Instruction &I : BB)
+ for (const Value *V : I.operands()) {
+ if (const Value *Op = skipMetadataWrapper(V, true)) {
+ if ((isa<Constant>(*Op) && !isa<GlobalValue>(*Op)) ||
+ isa<InlineAsm>(*Op))
+ orderValue(Op, OM);
+ }
+ }
+ }
OM.LastGlobalConstantID = OM.size();
// Initializers of GlobalValues are processed in
@@ -1002,8 +1002,8 @@ void ValueEnumerator::incorporateFunction(const Function &F) {
EnumerateValue(&I);
if (I.hasAttribute(Attribute::ByVal))
EnumerateType(I.getParamByValType());
- else if (I.hasAttribute(Attribute::StructRet))
- EnumerateType(I.getParamStructRetType());
+ else if (I.hasAttribute(Attribute::StructRet))
+ EnumerateType(I.getParamStructRetType());
}
FirstFuncConstantID = Values.size();
diff --git a/contrib/libs/llvm12/lib/Bitcode/Writer/ya.make b/contrib/libs/llvm12/lib/Bitcode/Writer/ya.make
index 7eec1a75c1..624b4f8e7e 100644
--- a/contrib/libs/llvm12/lib/Bitcode/Writer/ya.make
+++ b/contrib/libs/llvm12/lib/Bitcode/Writer/ya.make
@@ -12,13 +12,13 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/Bitstream/Reader/BitstreamReader.cpp b/contrib/libs/llvm12/lib/Bitstream/Reader/BitstreamReader.cpp
index bbeb36c6de..28adfe6268 100644
--- a/contrib/libs/llvm12/lib/Bitstream/Reader/BitstreamReader.cpp
+++ b/contrib/libs/llvm12/lib/Bitstream/Reader/BitstreamReader.cpp
@@ -27,7 +27,7 @@ Error BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) {
if (BlockInfo) {
if (const BitstreamBlockInfo::BlockInfo *Info =
BlockInfo->getBlockInfo(BlockID)) {
- llvm::append_range(CurAbbrevs, Info->Abbrevs);
+ llvm::append_range(CurAbbrevs, Info->Abbrevs);
}
}
@@ -155,9 +155,9 @@ Expected<unsigned> BitstreamCursor::skipRecord(unsigned AbbrevID) {
report_fatal_error("Array element type can't be an Array or a Blob");
case BitCodeAbbrevOp::Fixed:
assert((unsigned)EltEnc.getEncodingData() <= MaxChunkSize);
- if (Error Err =
- JumpToBit(GetCurrentBitNo() + static_cast<uint64_t>(NumElts) *
- EltEnc.getEncodingData()))
+ if (Error Err =
+ JumpToBit(GetCurrentBitNo() + static_cast<uint64_t>(NumElts) *
+ EltEnc.getEncodingData()))
return std::move(Err);
break;
case BitCodeAbbrevOp::VBR:
@@ -186,7 +186,7 @@ Expected<unsigned> BitstreamCursor::skipRecord(unsigned AbbrevID) {
SkipToFourByteBoundary(); // 32-bit alignment
// Figure out where the end of this blob will be including tail padding.
- const size_t NewEnd = GetCurrentBitNo() + alignTo(NumElts, 4) * 8;
+ const size_t NewEnd = GetCurrentBitNo() + alignTo(NumElts, 4) * 8;
// If this would read off the end of the bitcode file, just set the
// record to empty and return.
@@ -314,7 +314,7 @@ Expected<unsigned> BitstreamCursor::readRecord(unsigned AbbrevID,
// Figure out where the end of this blob will be including tail padding.
size_t CurBitPos = GetCurrentBitNo();
- const size_t NewEnd = CurBitPos + alignTo(NumElts, 4) * 8;
+ const size_t NewEnd = CurBitPos + alignTo(NumElts, 4) * 8;
// If this would read off the end of the bitcode file, just set the
// record to empty and return.
diff --git a/contrib/libs/llvm12/lib/Bitstream/Reader/ya.make b/contrib/libs/llvm12/lib/Bitstream/Reader/ya.make
index fff7a30920..09acec1b47 100644
--- a/contrib/libs/llvm12/lib/Bitstream/Reader/ya.make
+++ b/contrib/libs/llvm12/lib/Bitstream/Reader/ya.make
@@ -12,8 +12,8 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/CodeGen/AllocationOrder.cpp b/contrib/libs/llvm12/lib/CodeGen/AllocationOrder.cpp
index 137c8f4f0e..2aef1234ac 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AllocationOrder.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AllocationOrder.cpp
@@ -26,15 +26,15 @@ using namespace llvm;
#define DEBUG_TYPE "regalloc"
// Compare VirtRegMap::getRegAllocPref().
-AllocationOrder AllocationOrder::create(unsigned VirtReg, const VirtRegMap &VRM,
- const RegisterClassInfo &RegClassInfo,
- const LiveRegMatrix *Matrix) {
+AllocationOrder AllocationOrder::create(unsigned VirtReg, const VirtRegMap &VRM,
+ const RegisterClassInfo &RegClassInfo,
+ const LiveRegMatrix *Matrix) {
const MachineFunction &MF = VRM.getMachineFunction();
const TargetRegisterInfo *TRI = &VRM.getTargetRegInfo();
- auto Order = RegClassInfo.getOrder(MF.getRegInfo().getRegClass(VirtReg));
- SmallVector<MCPhysReg, 16> Hints;
- bool HardHints =
- TRI->getRegAllocationHints(VirtReg, Order, Hints, MF, &VRM, Matrix);
+ auto Order = RegClassInfo.getOrder(MF.getRegInfo().getRegClass(VirtReg));
+ SmallVector<MCPhysReg, 16> Hints;
+ bool HardHints =
+ TRI->getRegAllocationHints(VirtReg, Order, Hints, MF, &VRM, Matrix);
LLVM_DEBUG({
if (!Hints.empty()) {
@@ -49,5 +49,5 @@ AllocationOrder AllocationOrder::create(unsigned VirtReg, const VirtRegMap &VRM,
assert(is_contained(Order, Hints[I]) &&
"Target hint is outside allocation order.");
#endif
- return AllocationOrder(std::move(Hints), Order, HardHints);
+ return AllocationOrder(std::move(Hints), Order, HardHints);
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/AllocationOrder.h b/contrib/libs/llvm12/lib/CodeGen/AllocationOrder.h
index 3414dae03a..0701e68101 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AllocationOrder.h
+++ b/contrib/libs/llvm12/lib/CodeGen/AllocationOrder.h
@@ -17,9 +17,9 @@
#define LLVM_LIB_CODEGEN_ALLOCATIONORDER_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/Register.h"
+#include "llvm/CodeGen/Register.h"
namespace llvm {
@@ -28,95 +28,95 @@ class VirtRegMap;
class LiveRegMatrix;
class LLVM_LIBRARY_VISIBILITY AllocationOrder {
- const SmallVector<MCPhysReg, 16> Hints;
+ const SmallVector<MCPhysReg, 16> Hints;
ArrayRef<MCPhysReg> Order;
- // How far into the Order we can iterate. This is 0 if the AllocationOrder is
- // constructed with HardHints = true, Order.size() otherwise. While
- // technically a size_t, it will participate in comparisons with the
- // Iterator's Pos, which must be signed, so it's typed here as signed, too, to
- // avoid warnings and under the assumption that the size of Order is
- // relatively small.
- // IterationLimit defines an invalid iterator position.
- const int IterationLimit;
+ // How far into the Order we can iterate. This is 0 if the AllocationOrder is
+ // constructed with HardHints = true, Order.size() otherwise. While
+ // technically a size_t, it will participate in comparisons with the
+ // Iterator's Pos, which must be signed, so it's typed here as signed, too, to
+ // avoid warnings and under the assumption that the size of Order is
+ // relatively small.
+ // IterationLimit defines an invalid iterator position.
+ const int IterationLimit;
public:
- /// Forward iterator for an AllocationOrder.
- class Iterator final {
- const AllocationOrder &AO;
- int Pos = 0;
-
- public:
- Iterator(const AllocationOrder &AO, int Pos) : AO(AO), Pos(Pos) {}
-
- /// Return true if the curent position is that of a preferred register.
- bool isHint() const { return Pos < 0; }
-
- /// Return the next physical register in the allocation order.
- MCRegister operator*() const {
- if (Pos < 0)
- return AO.Hints.end()[Pos];
- assert(Pos < AO.IterationLimit);
- return AO.Order[Pos];
- }
-
- /// Advance the iterator to the next position. If that's past the Hints
- /// list, advance to the first value that's not also in the Hints list.
- Iterator &operator++() {
- if (Pos < AO.IterationLimit)
- ++Pos;
- while (Pos >= 0 && Pos < AO.IterationLimit && AO.isHint(AO.Order[Pos]))
- ++Pos;
- return *this;
- }
-
- bool operator==(const Iterator &Other) const {
- assert(&AO == &Other.AO);
- return Pos == Other.Pos;
- }
-
- bool operator!=(const Iterator &Other) const { return !(*this == Other); }
- };
-
+ /// Forward iterator for an AllocationOrder.
+ class Iterator final {
+ const AllocationOrder &AO;
+ int Pos = 0;
+
+ public:
+ Iterator(const AllocationOrder &AO, int Pos) : AO(AO), Pos(Pos) {}
+
+ /// Return true if the curent position is that of a preferred register.
+ bool isHint() const { return Pos < 0; }
+
+ /// Return the next physical register in the allocation order.
+ MCRegister operator*() const {
+ if (Pos < 0)
+ return AO.Hints.end()[Pos];
+ assert(Pos < AO.IterationLimit);
+ return AO.Order[Pos];
+ }
+
+ /// Advance the iterator to the next position. If that's past the Hints
+ /// list, advance to the first value that's not also in the Hints list.
+ Iterator &operator++() {
+ if (Pos < AO.IterationLimit)
+ ++Pos;
+ while (Pos >= 0 && Pos < AO.IterationLimit && AO.isHint(AO.Order[Pos]))
+ ++Pos;
+ return *this;
+ }
+
+ bool operator==(const Iterator &Other) const {
+ assert(&AO == &Other.AO);
+ return Pos == Other.Pos;
+ }
+
+ bool operator!=(const Iterator &Other) const { return !(*this == Other); }
+ };
+
/// Create a new AllocationOrder for VirtReg.
/// @param VirtReg Virtual register to allocate for.
/// @param VRM Virtual register map for function.
/// @param RegClassInfo Information about reserved and allocatable registers.
- static AllocationOrder create(unsigned VirtReg, const VirtRegMap &VRM,
- const RegisterClassInfo &RegClassInfo,
- const LiveRegMatrix *Matrix);
-
- /// Create an AllocationOrder given the Hits, Order, and HardHits values.
- /// Use the create method above - the ctor is for unittests.
- AllocationOrder(SmallVector<MCPhysReg, 16> &&Hints, ArrayRef<MCPhysReg> Order,
- bool HardHints)
- : Hints(std::move(Hints)), Order(Order),
- IterationLimit(HardHints ? 0 : static_cast<int>(Order.size())) {}
-
- Iterator begin() const {
- return Iterator(*this, -(static_cast<int>(Hints.size())));
+ static AllocationOrder create(unsigned VirtReg, const VirtRegMap &VRM,
+ const RegisterClassInfo &RegClassInfo,
+ const LiveRegMatrix *Matrix);
+
+ /// Create an AllocationOrder given the Hits, Order, and HardHits values.
+ /// Use the create method above - the ctor is for unittests.
+ AllocationOrder(SmallVector<MCPhysReg, 16> &&Hints, ArrayRef<MCPhysReg> Order,
+ bool HardHints)
+ : Hints(std::move(Hints)), Order(Order),
+ IterationLimit(HardHints ? 0 : static_cast<int>(Order.size())) {}
+
+ Iterator begin() const {
+ return Iterator(*this, -(static_cast<int>(Hints.size())));
}
- Iterator end() const { return Iterator(*this, IterationLimit); }
-
- Iterator getOrderLimitEnd(unsigned OrderLimit) const {
- assert(OrderLimit <= Order.size());
- if (OrderLimit == 0)
- return end();
- Iterator Ret(*this,
- std::min(static_cast<int>(OrderLimit) - 1, IterationLimit));
- return ++Ret;
+ Iterator end() const { return Iterator(*this, IterationLimit); }
+
+ Iterator getOrderLimitEnd(unsigned OrderLimit) const {
+ assert(OrderLimit <= Order.size());
+ if (OrderLimit == 0)
+ return end();
+ Iterator Ret(*this,
+ std::min(static_cast<int>(OrderLimit) - 1, IterationLimit));
+ return ++Ret;
}
- /// Get the allocation order without reordered hints.
- ArrayRef<MCPhysReg> getOrder() const { return Order; }
+ /// Get the allocation order without reordered hints.
+ ArrayRef<MCPhysReg> getOrder() const { return Order; }
- /// Return true if Reg is a preferred physical register.
- bool isHint(Register Reg) const {
- assert(!Reg.isPhysical() ||
- Reg.id() <
- static_cast<uint32_t>(std::numeric_limits<MCPhysReg>::max()));
- return Reg.isPhysical() && is_contained(Hints, Reg.id());
- }
+ /// Return true if Reg is a preferred physical register.
+ bool isHint(Register Reg) const {
+ assert(!Reg.isPhysical() ||
+ Reg.id() <
+ static_cast<uint32_t>(std::numeric_limits<MCPhysReg>::max()));
+ return Reg.isPhysical() && is_contained(Hints, Reg.id());
+ }
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/CodeGen/Analysis.cpp b/contrib/libs/llvm12/lib/CodeGen/Analysis.cpp
index 08f8fa04fb..ebeff1fec3 100644
--- a/contrib/libs/llvm12/lib/CodeGen/Analysis.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/Analysis.cpp
@@ -88,25 +88,25 @@ void llvm::ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL,
uint64_t StartingOffset) {
// Given a struct type, recursively traverse the elements.
if (StructType *STy = dyn_cast<StructType>(Ty)) {
- // If the Offsets aren't needed, don't query the struct layout. This allows
- // us to support structs with scalable vectors for operations that don't
- // need offsets.
- const StructLayout *SL = Offsets ? DL.getStructLayout(STy) : nullptr;
+ // If the Offsets aren't needed, don't query the struct layout. This allows
+ // us to support structs with scalable vectors for operations that don't
+ // need offsets.
+ const StructLayout *SL = Offsets ? DL.getStructLayout(STy) : nullptr;
for (StructType::element_iterator EB = STy->element_begin(),
EI = EB,
EE = STy->element_end();
- EI != EE; ++EI) {
- // Don't compute the element offset if we didn't get a StructLayout above.
- uint64_t EltOffset = SL ? SL->getElementOffset(EI - EB) : 0;
+ EI != EE; ++EI) {
+ // Don't compute the element offset if we didn't get a StructLayout above.
+ uint64_t EltOffset = SL ? SL->getElementOffset(EI - EB) : 0;
ComputeValueVTs(TLI, DL, *EI, ValueVTs, MemVTs, Offsets,
- StartingOffset + EltOffset);
- }
+ StartingOffset + EltOffset);
+ }
return;
}
// Given an array type, recursively traverse the elements.
if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
Type *EltTy = ATy->getElementType();
- uint64_t EltSize = DL.getTypeAllocSize(EltTy).getFixedValue();
+ uint64_t EltSize = DL.getTypeAllocSize(EltTy).getFixedValue();
for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i)
ComputeValueVTs(TLI, DL, EltTy, ValueVTs, MemVTs, Offsets,
StartingOffset + i * EltSize);
@@ -137,21 +137,21 @@ void llvm::computeValueLLTs(const DataLayout &DL, Type &Ty,
uint64_t StartingOffset) {
// Given a struct type, recursively traverse the elements.
if (StructType *STy = dyn_cast<StructType>(&Ty)) {
- // If the Offsets aren't needed, don't query the struct layout. This allows
- // us to support structs with scalable vectors for operations that don't
- // need offsets.
- const StructLayout *SL = Offsets ? DL.getStructLayout(STy) : nullptr;
- for (unsigned I = 0, E = STy->getNumElements(); I != E; ++I) {
- uint64_t EltOffset = SL ? SL->getElementOffset(I) : 0;
+ // If the Offsets aren't needed, don't query the struct layout. This allows
+ // us to support structs with scalable vectors for operations that don't
+ // need offsets.
+ const StructLayout *SL = Offsets ? DL.getStructLayout(STy) : nullptr;
+ for (unsigned I = 0, E = STy->getNumElements(); I != E; ++I) {
+ uint64_t EltOffset = SL ? SL->getElementOffset(I) : 0;
computeValueLLTs(DL, *STy->getElementType(I), ValueTys, Offsets,
- StartingOffset + EltOffset);
- }
+ StartingOffset + EltOffset);
+ }
return;
}
// Given an array type, recursively traverse the elements.
if (ArrayType *ATy = dyn_cast<ArrayType>(&Ty)) {
Type *EltTy = ATy->getElementType();
- uint64_t EltSize = DL.getTypeAllocSize(EltTy).getFixedValue();
+ uint64_t EltSize = DL.getTypeAllocSize(EltTy).getFixedValue();
for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i)
computeValueLLTs(DL, *EltTy, ValueTys, Offsets,
StartingOffset + i * EltSize);
@@ -527,15 +527,15 @@ bool llvm::isInTailCallPosition(const CallBase &Call, const TargetMachine &TM) {
// Debug info intrinsics do not get in the way of tail call optimization.
if (isa<DbgInfoIntrinsic>(BBI))
continue;
- // Pseudo probe intrinsics do not block tail call optimization either.
- if (isa<PseudoProbeInst>(BBI))
- continue;
- // A lifetime end, assume or noalias.decl intrinsic should not stop tail
- // call optimization.
+ // Pseudo probe intrinsics do not block tail call optimization either.
+ if (isa<PseudoProbeInst>(BBI))
+ continue;
+ // A lifetime end, assume or noalias.decl intrinsic should not stop tail
+ // call optimization.
if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(BBI))
if (II->getIntrinsicID() == Intrinsic::lifetime_end ||
- II->getIntrinsicID() == Intrinsic::assume ||
- II->getIntrinsicID() == Intrinsic::experimental_noalias_scope_decl)
+ II->getIntrinsicID() == Intrinsic::assume ||
+ II->getIntrinsicID() == Intrinsic::experimental_noalias_scope_decl)
continue;
if (BBI->mayHaveSideEffects() || BBI->mayReadFromMemory() ||
!isSafeToSpeculativelyExecute(&*BBI))
@@ -733,7 +733,7 @@ static void collectEHScopeMembers(
if (Visiting->isEHScopeReturnBlock())
continue;
- append_range(Worklist, Visiting->successors());
+ append_range(Worklist, Visiting->successors());
}
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AIXException.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AIXException.cpp
index e91d2e6a88..95d878e65b 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AIXException.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AIXException.cpp
@@ -1,79 +1,79 @@
-//===-- CodeGen/AsmPrinter/AIXException.cpp - AIX Exception Impl ----------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains support for writing AIX exception info into asm files.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DwarfException.h"
-#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
-#include "llvm/MC/MCSectionXCOFF.h"
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
-#include "llvm/Target/TargetMachine.h"
-
-namespace llvm {
-
-AIXException::AIXException(AsmPrinter *A) : DwarfCFIExceptionBase(A) {}
-
-void AIXException::emitExceptionInfoTable(const MCSymbol *LSDA,
- const MCSymbol *PerSym) {
- // Generate EH Info Table.
- // The EH Info Table, aka, 'compat unwind section' on AIX, have the following
- // format: struct eh_info_t {
- // unsigned version; /* EH info verion 0 */
- // #if defined(__64BIT__)
- // char _pad[4]; /* padding */
- // #endif
- // unsigned long lsda; /* Pointer to LSDA */
- // unsigned long personality; /* Pointer to the personality routine */
- // }
-
- Asm->OutStreamer->SwitchSection(
- Asm->getObjFileLowering().getCompactUnwindSection());
- MCSymbol *EHInfoLabel =
- TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(Asm->MF);
- Asm->OutStreamer->emitLabel(EHInfoLabel);
-
- // Version number.
- Asm->emitInt32(0);
-
- const DataLayout &DL = MMI->getModule()->getDataLayout();
- const unsigned PointerSize = DL.getPointerSize();
-
- // Add necessary paddings in 64 bit mode.
- Asm->OutStreamer->emitValueToAlignment(PointerSize);
-
- // LSDA location.
- Asm->OutStreamer->emitValue(MCSymbolRefExpr::create(LSDA, Asm->OutContext),
- PointerSize);
-
- // Personality routine.
- Asm->OutStreamer->emitValue(MCSymbolRefExpr::create(PerSym, Asm->OutContext),
- PointerSize);
-}
-
-void AIXException::endFunction(const MachineFunction *MF) {
- if (!TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF))
- return;
-
- const MCSymbol *LSDALabel = emitExceptionTable();
-
- const Function &F = MF->getFunction();
- assert(F.hasPersonalityFn() &&
- "Landingpads are presented, but no personality routine is found.");
- const Function *Per =
- dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
- const MCSymbol *PerSym = Asm->TM.getSymbol(Per);
-
- emitExceptionInfoTable(LSDALabel, PerSym);
-}
-
-} // End of namespace llvm
+//===-- CodeGen/AsmPrinter/AIXException.cpp - AIX Exception Impl ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains support for writing AIX exception info into asm files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DwarfException.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
+#include "llvm/MC/MCSectionXCOFF.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetMachine.h"
+
+namespace llvm {
+
+AIXException::AIXException(AsmPrinter *A) : DwarfCFIExceptionBase(A) {}
+
+void AIXException::emitExceptionInfoTable(const MCSymbol *LSDA,
+ const MCSymbol *PerSym) {
+ // Generate EH Info Table.
+ // The EH Info Table, aka, 'compat unwind section' on AIX, have the following
+ // format: struct eh_info_t {
+ // unsigned version; /* EH info verion 0 */
+ // #if defined(__64BIT__)
+ // char _pad[4]; /* padding */
+ // #endif
+ // unsigned long lsda; /* Pointer to LSDA */
+ // unsigned long personality; /* Pointer to the personality routine */
+ // }
+
+ Asm->OutStreamer->SwitchSection(
+ Asm->getObjFileLowering().getCompactUnwindSection());
+ MCSymbol *EHInfoLabel =
+ TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(Asm->MF);
+ Asm->OutStreamer->emitLabel(EHInfoLabel);
+
+ // Version number.
+ Asm->emitInt32(0);
+
+ const DataLayout &DL = MMI->getModule()->getDataLayout();
+ const unsigned PointerSize = DL.getPointerSize();
+
+ // Add necessary paddings in 64 bit mode.
+ Asm->OutStreamer->emitValueToAlignment(PointerSize);
+
+ // LSDA location.
+ Asm->OutStreamer->emitValue(MCSymbolRefExpr::create(LSDA, Asm->OutContext),
+ PointerSize);
+
+ // Personality routine.
+ Asm->OutStreamer->emitValue(MCSymbolRefExpr::create(PerSym, Asm->OutContext),
+ PointerSize);
+}
+
+void AIXException::endFunction(const MachineFunction *MF) {
+ if (!TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF))
+ return;
+
+ const MCSymbol *LSDALabel = emitExceptionTable();
+
+ const Function &F = MF->getFunction();
+ assert(F.hasPersonalityFn() &&
+ "Landingpads are presented, but no personality routine is found.");
+ const Function *Per =
+ dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
+ const MCSymbol *PerSym = Asm->TM.getSymbol(Per);
+
+ emitExceptionInfoTable(LSDALabel, PerSym);
+}
+
+} // End of namespace llvm
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AccelTable.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AccelTable.cpp
index ae8cd3b886..4e45a0ffc6 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AccelTable.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AccelTable.cpp
@@ -270,7 +270,7 @@ void AccelTableWriter::emitOffsets(const MCSymbol *Base) const {
continue;
PrevHash = HashValue;
Asm->OutStreamer->AddComment("Offset in Bucket " + Twine(i));
- Asm->emitLabelDifference(Hash->Sym, Base, Asm->getDwarfOffsetByteSize());
+ Asm->emitLabelDifference(Hash->Sym, Base, Asm->getDwarfOffsetByteSize());
}
}
}
@@ -366,8 +366,8 @@ void Dwarf5AccelTableWriter<DataT>::Header::emit(
assert(CompUnitCount > 0 && "Index must have at least one CU.");
AsmPrinter *Asm = Ctx.Asm;
- Asm->emitDwarfUnitLength(Ctx.ContributionEnd, Ctx.ContributionStart,
- "Header: unit length");
+ Asm->emitDwarfUnitLength(Ctx.ContributionEnd, Ctx.ContributionStart,
+ "Header: unit length");
Asm->OutStreamer->emitLabel(Ctx.ContributionStart);
Asm->OutStreamer->AddComment("Header: version");
Asm->emitInt16(Version);
@@ -504,7 +504,7 @@ template <typename DataT> void Dwarf5AccelTableWriter<DataT>::emitData() const {
for (const auto *Value : Hash->Values)
emitEntry(*static_cast<const DataT *>(Value));
Asm->OutStreamer->AddComment("End of list: " + Hash->Name.getString());
- Asm->emitInt8(0);
+ Asm->emitInt8(0);
}
}
}
@@ -591,14 +591,14 @@ void llvm::emitDWARF5AccelTable(
}
void AppleAccelTableOffsetData::emit(AsmPrinter *Asm) const {
- assert(Die.getDebugSectionOffset() <= UINT32_MAX &&
- "The section offset exceeds the limit.");
+ assert(Die.getDebugSectionOffset() <= UINT32_MAX &&
+ "The section offset exceeds the limit.");
Asm->emitInt32(Die.getDebugSectionOffset());
}
void AppleAccelTableTypeData::emit(AsmPrinter *Asm) const {
- assert(Die.getDebugSectionOffset() <= UINT32_MAX &&
- "The section offset exceeds the limit.");
+ assert(Die.getDebugSectionOffset() <= UINT32_MAX &&
+ "The section offset exceeds the limit.");
Asm->emitInt32(Die.getDebugSectionOffset());
Asm->emitInt16(Die.getTag());
Asm->emitInt8(0);
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AddressPool.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AddressPool.cpp
index 3ff0dd1487..3df8e35acc 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AddressPool.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AddressPool.cpp
@@ -29,7 +29,7 @@ MCSymbol *AddressPool::emitHeader(AsmPrinter &Asm, MCSection *Section) {
MCSymbol *BeginLabel = Asm.createTempSymbol(Prefix + "start");
MCSymbol *EndLabel = Asm.createTempSymbol(Prefix + "end");
- Asm.emitDwarfUnitLength(EndLabel, BeginLabel, "Length of contribution");
+ Asm.emitDwarfUnitLength(EndLabel, BeginLabel, "Length of contribution");
Asm.OutStreamer->emitLabel(BeginLabel);
Asm.OutStreamer->AddComment("DWARF version number");
Asm.emitInt16(Asm.getDwarfVersion());
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AddressPool.h b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AddressPool.h
index 4c444998af..f1edc6c330 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AddressPool.h
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AddressPool.h
@@ -48,7 +48,7 @@ public:
bool hasBeenUsed() const { return HasBeenUsed; }
- void resetUsedFlag(bool HasBeenUsed = false) { this->HasBeenUsed = HasBeenUsed; }
+ void resetUsedFlag(bool HasBeenUsed = false) { this->HasBeenUsed = HasBeenUsed; }
MCSymbol *getLabel() { return AddressTableBaseSym; }
void setLabel(MCSymbol *Sym) { AddressTableBaseSym = Sym; }
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index a21f2c8ca8..85754bf29d 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -14,7 +14,7 @@
#include "CodeViewDebug.h"
#include "DwarfDebug.h"
#include "DwarfException.h"
-#include "PseudoProbePrinter.h"
+#include "PseudoProbePrinter.h"
#include "WasmException.h"
#include "WinCFGuard.h"
#include "WinException.h"
@@ -31,7 +31,7 @@
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/EHPersonalities.h"
-#include "llvm/Analysis/MemoryLocation.h"
+#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/BinaryFormat/Dwarf.h"
@@ -79,7 +79,7 @@
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
-#include "llvm/IR/PseudoProbe.h"
+#include "llvm/IR/PseudoProbe.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -134,26 +134,26 @@ using namespace llvm;
#define DEBUG_TYPE "asm-printer"
-// FIXME: this option currently only applies to DWARF, and not CodeView, tables
-static cl::opt<bool>
- DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden,
- cl::desc("Disable debug info printing"));
-
-const char DWARFGroupName[] = "dwarf";
-const char DWARFGroupDescription[] = "DWARF Emission";
-const char DbgTimerName[] = "emit";
-const char DbgTimerDescription[] = "Debug Info Emission";
-const char EHTimerName[] = "write_exception";
-const char EHTimerDescription[] = "DWARF Exception Writer";
-const char CFGuardName[] = "Control Flow Guard";
-const char CFGuardDescription[] = "Control Flow Guard";
-const char CodeViewLineTablesGroupName[] = "linetables";
-const char CodeViewLineTablesGroupDescription[] = "CodeView Line Tables";
-const char PPTimerName[] = "emit";
-const char PPTimerDescription[] = "Pseudo Probe Emission";
-const char PPGroupName[] = "pseudo probe";
-const char PPGroupDescription[] = "Pseudo Probe Emission";
-
+// FIXME: this option currently only applies to DWARF, and not CodeView, tables
+static cl::opt<bool>
+ DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden,
+ cl::desc("Disable debug info printing"));
+
+const char DWARFGroupName[] = "dwarf";
+const char DWARFGroupDescription[] = "DWARF Emission";
+const char DbgTimerName[] = "emit";
+const char DbgTimerDescription[] = "Debug Info Emission";
+const char EHTimerName[] = "write_exception";
+const char EHTimerDescription[] = "DWARF Exception Writer";
+const char CFGuardName[] = "Control Flow Guard";
+const char CFGuardDescription[] = "Control Flow Guard";
+const char CodeViewLineTablesGroupName[] = "linetables";
+const char CodeViewLineTablesGroupDescription[] = "CodeView Line Tables";
+const char PPTimerName[] = "emit";
+const char PPTimerDescription[] = "Pseudo Probe Emission";
+const char PPGroupName[] = "pseudo probe";
+const char PPGroupDescription[] = "Pseudo Probe Emission";
+
STATISTIC(EmittedInsts, "Number of machine instrs printed");
char AsmPrinter::ID = 0;
@@ -199,8 +199,8 @@ AsmPrinter::AsmPrinter(TargetMachine &tm, std::unique_ptr<MCStreamer> Streamer)
}
AsmPrinter::~AsmPrinter() {
- assert(!DD && Handlers.size() == NumUserHandlers &&
- "Debug/EH info didn't get finalized");
+ assert(!DD && Handlers.size() == NumUserHandlers &&
+ "Debug/EH info didn't get finalized");
if (GCMetadataPrinters) {
gcp_map_type &GCMap = getGCMap(GCMetadataPrinters);
@@ -243,11 +243,11 @@ void AsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) {
}
void AsmPrinter::emitInitialRawDwarfLocDirective(const MachineFunction &MF) {
- if (DD) {
- assert(OutStreamer->hasRawTextSupport() &&
- "Expected assembly output mode.");
- (void)DD->emitInitialLocDirective(MF, /*CUID=*/0);
- }
+ if (DD) {
+ assert(OutStreamer->hasRawTextSupport() &&
+ "Expected assembly output mode.");
+ (void)DD->emitInitialLocDirective(MF, /*CUID=*/0);
+ }
}
/// getCurrentSection() - Return the current section we are emitting to.
@@ -275,9 +275,9 @@ bool AsmPrinter::doInitialization(Module &M) {
OutStreamer->InitSections(false);
- if (DisableDebugInfoPrinting)
- MMI->setDebugInfoAvailability(false);
-
+ if (DisableDebugInfoPrinting)
+ MMI->setDebugInfoAvailability(false);
+
// Emit the version-min deployment target directive if needed.
//
// FIXME: If we end up with a collection of these sorts of Darwin-specific
@@ -313,7 +313,7 @@ bool AsmPrinter::doInitialization(Module &M) {
std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo(
TM.getTargetTriple().str(), TM.getTargetCPU(),
TM.getTargetFeatureString()));
- assert(STI && "Unable to create subtarget info");
+ assert(STI && "Unable to create subtarget info");
OutStreamer->AddComment("Start of file scope inline assembly");
OutStreamer->AddBlankLine();
emitInlineAsm(M.getModuleInlineAsm() + "\n",
@@ -331,21 +331,21 @@ bool AsmPrinter::doInitialization(Module &M) {
CodeViewLineTablesGroupDescription);
}
if (!EmitCodeView || M.getDwarfVersion()) {
- if (!DisableDebugInfoPrinting) {
- DD = new DwarfDebug(this);
- Handlers.emplace_back(std::unique_ptr<DwarfDebug>(DD), DbgTimerName,
- DbgTimerDescription, DWARFGroupName,
- DWARFGroupDescription);
- }
+ if (!DisableDebugInfoPrinting) {
+ DD = new DwarfDebug(this);
+ Handlers.emplace_back(std::unique_ptr<DwarfDebug>(DD), DbgTimerName,
+ DbgTimerDescription, DWARFGroupName,
+ DWARFGroupDescription);
+ }
}
}
- if (M.getNamedMetadata(PseudoProbeDescMetadataName)) {
- PP = new PseudoProbeHandler(this, &M);
- Handlers.emplace_back(std::unique_ptr<PseudoProbeHandler>(PP), PPTimerName,
- PPTimerDescription, PPGroupName, PPGroupDescription);
- }
-
+ if (M.getNamedMetadata(PseudoProbeDescMetadataName)) {
+ PP = new PseudoProbeHandler(this, &M);
+ Handlers.emplace_back(std::unique_ptr<PseudoProbeHandler>(PP), PPTimerName,
+ PPTimerDescription, PPGroupName, PPGroupDescription);
+ }
+
switch (MAI->getExceptionHandlingType()) {
case ExceptionHandling::SjLj:
case ExceptionHandling::DwarfCFI:
@@ -393,9 +393,9 @@ bool AsmPrinter::doInitialization(Module &M) {
case ExceptionHandling::Wasm:
ES = new WasmException(this);
break;
- case ExceptionHandling::AIX:
- ES = new AIXException(this);
- break;
+ case ExceptionHandling::AIX:
+ ES = new AIXException(this);
+ break;
}
if (ES)
Handlers.emplace_back(std::unique_ptr<EHStreamer>(ES), EHTimerName,
@@ -407,13 +407,13 @@ bool AsmPrinter::doInitialization(Module &M) {
Handlers.emplace_back(std::make_unique<WinCFGuard>(this), CFGuardName,
CFGuardDescription, DWARFGroupName,
DWARFGroupDescription);
-
- for (const HandlerInfo &HI : Handlers) {
- NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
- HI.TimerGroupDescription, TimePassesIsEnabled);
- HI.Handler->beginModule(&M);
- }
-
+
+ for (const HandlerInfo &HI : Handlers) {
+ NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
+ HI.TimerGroupDescription, TimePassesIsEnabled);
+ HI.Handler->beginModule(&M);
+ }
+
return false;
}
@@ -484,8 +484,8 @@ MCSymbol *AsmPrinter::getSymbolPreferLocal(const GlobalValue &GV) const {
if (TM.getTargetTriple().isOSBinFormatELF() && GV.canBenefitFromLocalAlias()) {
const Module &M = *GV.getParent();
if (TM.getRelocationModel() != Reloc::Static &&
- M.getPIELevel() == PIELevel::Default && GV.isDSOLocal())
- return getSymbolWithGlobalValueBase(&GV, "$local");
+ M.getPIELevel() == PIELevel::Default && GV.isDSOLocal())
+ return getSymbolWithGlobalValueBase(&GV, "$local");
}
return TM.getSymbol(&GV);
}
@@ -533,8 +533,8 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
GVSym->redefineIfPossible();
if (GVSym->isDefined() || GVSym->isVariable())
- OutContext.reportError(SMLoc(), "symbol '" + Twine(GVSym->getName()) +
- "' is already defined");
+ OutContext.reportError(SMLoc(), "symbol '" + Twine(GVSym->getName()) +
+ "' is already defined");
if (MAI->hasDotTypeDotSizeDirective())
OutStreamer->emitSymbolAttribute(EmittedSym, MCSA_ELF_TypeObject);
@@ -845,21 +845,21 @@ static void emitComments(const MachineInstr &MI, raw_ostream &CommentOS) {
if ((Size = MI.getRestoreSize(TII))) {
CommentOS << *Size << "-byte Reload\n";
} else if ((Size = MI.getFoldedRestoreSize(TII))) {
- if (*Size) {
- if (*Size == unsigned(MemoryLocation::UnknownSize))
- CommentOS << "Unknown-size Folded Reload\n";
- else
- CommentOS << *Size << "-byte Folded Reload\n";
- }
+ if (*Size) {
+ if (*Size == unsigned(MemoryLocation::UnknownSize))
+ CommentOS << "Unknown-size Folded Reload\n";
+ else
+ CommentOS << *Size << "-byte Folded Reload\n";
+ }
} else if ((Size = MI.getSpillSize(TII))) {
CommentOS << *Size << "-byte Spill\n";
} else if ((Size = MI.getFoldedSpillSize(TII))) {
- if (*Size) {
- if (*Size == unsigned(MemoryLocation::UnknownSize))
- CommentOS << "Unknown-size Folded Spill\n";
- else
- CommentOS << *Size << "-byte Folded Spill\n";
- }
+ if (*Size) {
+ if (*Size == unsigned(MemoryLocation::UnknownSize))
+ CommentOS << "Unknown-size Folded Spill\n";
+ else
+ CommentOS << *Size << "-byte Folded Spill\n";
+ }
}
// Check for spill-induced copies
@@ -918,7 +918,7 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
// The second operand is only an offset if it's an immediate.
bool MemLoc = MI->isIndirectDebugValue();
- auto Offset = StackOffset::getFixed(MemLoc ? MI->getOperand(1).getImm() : 0);
+ auto Offset = StackOffset::getFixed(MemLoc ? MI->getOperand(1).getImm() : 0);
const DIExpression *Expr = MI->getDebugExpression();
if (Expr->getNumElements()) {
OS << '[';
@@ -957,8 +957,8 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
} else if (MI->getDebugOperand(0).isTargetIndex()) {
auto Op = MI->getDebugOperand(0);
OS << "!target-index(" << Op.getIndex() << "," << Op.getOffset() << ")";
- // NOTE: Want this comment at start of line, don't emit with AddComment.
- AP.OutStreamer->emitRawComment(OS.str());
+ // NOTE: Want this comment at start of line, don't emit with AddComment.
+ AP.OutStreamer->emitRawComment(OS.str());
return true;
} else {
Register Reg;
@@ -984,7 +984,7 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
}
if (MemLoc)
- OS << '+' << Offset.getFixed() << ']';
+ OS << '+' << Offset.getFixed() << ']';
// NOTE: Want this comment at start of line, don't emit with AddComment.
AP.OutStreamer->emitRawComment(OS.str());
@@ -1066,56 +1066,56 @@ void AsmPrinter::emitFrameAlloc(const MachineInstr &MI) {
MCConstantExpr::create(FrameOffset, OutContext));
}
-/// Returns the BB metadata to be emitted in the .llvm_bb_addr_map section for a
-/// given basic block. This can be used to capture more precise profile
-/// information. We use the last 3 bits (LSBs) to ecnode the following
-/// information:
-/// * (1): set if return block (ret or tail call).
-/// * (2): set if ends with a tail call.
-/// * (3): set if exception handling (EH) landing pad.
-/// The remaining bits are zero.
-static unsigned getBBAddrMapMetadata(const MachineBasicBlock &MBB) {
- const TargetInstrInfo *TII = MBB.getParent()->getSubtarget().getInstrInfo();
- return ((unsigned)MBB.isReturnBlock()) |
- ((!MBB.empty() && TII->isTailCall(MBB.back())) << 1) |
- (MBB.isEHPad() << 2);
-}
-
-void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
- MCSection *BBAddrMapSection =
- getObjFileLowering().getBBAddrMapSection(*MF.getSection());
- assert(BBAddrMapSection && ".llvm_bb_addr_map section is not initialized.");
-
- const MCSymbol *FunctionSymbol = getFunctionBegin();
-
- OutStreamer->PushSection();
- OutStreamer->SwitchSection(BBAddrMapSection);
- OutStreamer->emitSymbolValue(FunctionSymbol, getPointerSize());
- // Emit the total number of basic blocks in this function.
- OutStreamer->emitULEB128IntValue(MF.size());
- // Emit BB Information for each basic block in the funciton.
- for (const MachineBasicBlock &MBB : MF) {
- const MCSymbol *MBBSymbol =
- MBB.isEntryBlock() ? FunctionSymbol : MBB.getSymbol();
- // Emit the basic block offset.
- emitLabelDifferenceAsULEB128(MBBSymbol, FunctionSymbol);
- // Emit the basic block size. When BBs have alignments, their size cannot
- // always be computed from their offsets.
- emitLabelDifferenceAsULEB128(MBB.getEndSymbol(), MBBSymbol);
- OutStreamer->emitULEB128IntValue(getBBAddrMapMetadata(MBB));
- }
- OutStreamer->PopSection();
-}
-
-void AsmPrinter::emitPseudoProbe(const MachineInstr &MI) {
- auto GUID = MI.getOperand(0).getImm();
- auto Index = MI.getOperand(1).getImm();
- auto Type = MI.getOperand(2).getImm();
- auto Attr = MI.getOperand(3).getImm();
- DILocation *DebugLoc = MI.getDebugLoc();
- PP->emitPseudoProbe(GUID, Index, Type, Attr, DebugLoc);
-}
-
+/// Returns the BB metadata to be emitted in the .llvm_bb_addr_map section for a
+/// given basic block. This can be used to capture more precise profile
+/// information. We use the last 3 bits (LSBs) to ecnode the following
+/// information:
+/// * (1): set if return block (ret or tail call).
+/// * (2): set if ends with a tail call.
+/// * (3): set if exception handling (EH) landing pad.
+/// The remaining bits are zero.
+static unsigned getBBAddrMapMetadata(const MachineBasicBlock &MBB) {
+ const TargetInstrInfo *TII = MBB.getParent()->getSubtarget().getInstrInfo();
+ return ((unsigned)MBB.isReturnBlock()) |
+ ((!MBB.empty() && TII->isTailCall(MBB.back())) << 1) |
+ (MBB.isEHPad() << 2);
+}
+
+void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
+ MCSection *BBAddrMapSection =
+ getObjFileLowering().getBBAddrMapSection(*MF.getSection());
+ assert(BBAddrMapSection && ".llvm_bb_addr_map section is not initialized.");
+
+ const MCSymbol *FunctionSymbol = getFunctionBegin();
+
+ OutStreamer->PushSection();
+ OutStreamer->SwitchSection(BBAddrMapSection);
+ OutStreamer->emitSymbolValue(FunctionSymbol, getPointerSize());
+ // Emit the total number of basic blocks in this function.
+ OutStreamer->emitULEB128IntValue(MF.size());
+ // Emit BB Information for each basic block in the funciton.
+ for (const MachineBasicBlock &MBB : MF) {
+ const MCSymbol *MBBSymbol =
+ MBB.isEntryBlock() ? FunctionSymbol : MBB.getSymbol();
+ // Emit the basic block offset.
+ emitLabelDifferenceAsULEB128(MBBSymbol, FunctionSymbol);
+ // Emit the basic block size. When BBs have alignments, their size cannot
+ // always be computed from their offsets.
+ emitLabelDifferenceAsULEB128(MBB.getEndSymbol(), MBBSymbol);
+ OutStreamer->emitULEB128IntValue(getBBAddrMapMetadata(MBB));
+ }
+ OutStreamer->PopSection();
+}
+
+void AsmPrinter::emitPseudoProbe(const MachineInstr &MI) {
+ auto GUID = MI.getOperand(0).getImm();
+ auto Index = MI.getOperand(1).getImm();
+ auto Type = MI.getOperand(2).getImm();
+ auto Attr = MI.getOperand(3).getImm();
+ DILocation *DebugLoc = MI.getDebugLoc();
+ PP->emitPseudoProbe(GUID, Index, Type, Attr, DebugLoc);
+}
+
void AsmPrinter::emitStackSizeSection(const MachineFunction &MF) {
if (!MF.getTarget().Options.EmitStackSizeSection)
return;
@@ -1184,11 +1184,11 @@ void AsmPrinter::emitFunctionBody() {
bool HasAnyRealCode = false;
int NumInstsInFunction = 0;
- bool CanDoExtraAnalysis = ORE->allowExtraAnalysis(DEBUG_TYPE);
+ bool CanDoExtraAnalysis = ORE->allowExtraAnalysis(DEBUG_TYPE);
for (auto &MBB : *MF) {
// Print a label for the basic block.
emitBasicBlockStart(MBB);
- DenseMap<StringRef, unsigned> MnemonicCounts;
+ DenseMap<StringRef, unsigned> MnemonicCounts;
for (auto &MI : MBB) {
// Print the assembly for the instruction.
if (!MI.isPosition() && !MI.isImplicitDef() && !MI.isKill() &&
@@ -1201,10 +1201,10 @@ void AsmPrinter::emitFunctionBody() {
if (MCSymbol *S = MI.getPreInstrSymbol())
OutStreamer->emitLabel(S);
- for (const HandlerInfo &HI : Handlers) {
- NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
- HI.TimerGroupDescription, TimePassesIsEnabled);
- HI.Handler->beginInstruction(&MI);
+ for (const HandlerInfo &HI : Handlers) {
+ NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
+ HI.TimerGroupDescription, TimePassesIsEnabled);
+ HI.Handler->beginInstruction(&MI);
}
if (isVerbose())
@@ -1232,11 +1232,11 @@ void AsmPrinter::emitFunctionBody() {
emitInstruction(&MI);
}
break;
- case TargetOpcode::DBG_INSTR_REF:
- // This instruction reference will have been resolved to a machine
- // location, and a nearby DBG_VALUE created. We can safely ignore
- // the instruction reference.
- break;
+ case TargetOpcode::DBG_INSTR_REF:
+ // This instruction reference will have been resolved to a machine
+ // location, and a nearby DBG_VALUE created. We can safely ignore
+ // the instruction reference.
+ break;
case TargetOpcode::DBG_LABEL:
if (isVerbose()) {
if (!emitDebugLabelComment(&MI, *this))
@@ -1249,18 +1249,18 @@ void AsmPrinter::emitFunctionBody() {
case TargetOpcode::KILL:
if (isVerbose()) emitKill(&MI, *this);
break;
- case TargetOpcode::PSEUDO_PROBE:
- emitPseudoProbe(MI);
- break;
+ case TargetOpcode::PSEUDO_PROBE:
+ emitPseudoProbe(MI);
+ break;
default:
emitInstruction(&MI);
- if (CanDoExtraAnalysis) {
- MCInst MCI;
- MCI.setOpcode(MI.getOpcode());
- auto Name = OutStreamer->getMnemonic(MCI);
- auto I = MnemonicCounts.insert({Name, 0u});
- I.first->second++;
- }
+ if (CanDoExtraAnalysis) {
+ MCInst MCI;
+ MCI.setOpcode(MI.getOpcode());
+ auto Name = OutStreamer->getMnemonic(MCI);
+ auto I = MnemonicCounts.insert({Name, 0u});
+ I.first->second++;
+ }
break;
}
@@ -1268,69 +1268,69 @@ void AsmPrinter::emitFunctionBody() {
if (MCSymbol *S = MI.getPostInstrSymbol())
OutStreamer->emitLabel(S);
- for (const HandlerInfo &HI : Handlers) {
- NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
- HI.TimerGroupDescription, TimePassesIsEnabled);
- HI.Handler->endInstruction();
+ for (const HandlerInfo &HI : Handlers) {
+ NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
+ HI.TimerGroupDescription, TimePassesIsEnabled);
+ HI.Handler->endInstruction();
}
}
- // We must emit temporary symbol for the end of this basic block, if either
- // we have BBLabels enabled or if this basic blocks marks the end of a
- // section (except the section containing the entry basic block as the end
- // symbol for that section is CurrentFnEnd).
- if (MF->hasBBLabels() ||
- (MAI->hasDotTypeDotSizeDirective() && MBB.isEndSection() &&
- !MBB.sameSection(&MF->front())))
- OutStreamer->emitLabel(MBB.getEndSymbol());
+ // We must emit temporary symbol for the end of this basic block, if either
+ // we have BBLabels enabled or if this basic blocks marks the end of a
+ // section (except the section containing the entry basic block as the end
+ // symbol for that section is CurrentFnEnd).
+ if (MF->hasBBLabels() ||
+ (MAI->hasDotTypeDotSizeDirective() && MBB.isEndSection() &&
+ !MBB.sameSection(&MF->front())))
+ OutStreamer->emitLabel(MBB.getEndSymbol());
if (MBB.isEndSection()) {
- // The size directive for the section containing the entry block is
- // handled separately by the function section.
+ // The size directive for the section containing the entry block is
+ // handled separately by the function section.
if (!MBB.sameSection(&MF->front())) {
- if (MAI->hasDotTypeDotSizeDirective()) {
- // Emit the size directive for the basic block section.
- const MCExpr *SizeExp = MCBinaryExpr::createSub(
- MCSymbolRefExpr::create(MBB.getEndSymbol(), OutContext),
- MCSymbolRefExpr::create(CurrentSectionBeginSym, OutContext),
- OutContext);
- OutStreamer->emitELFSize(CurrentSectionBeginSym, SizeExp);
- }
+ if (MAI->hasDotTypeDotSizeDirective()) {
+ // Emit the size directive for the basic block section.
+ const MCExpr *SizeExp = MCBinaryExpr::createSub(
+ MCSymbolRefExpr::create(MBB.getEndSymbol(), OutContext),
+ MCSymbolRefExpr::create(CurrentSectionBeginSym, OutContext),
+ OutContext);
+ OutStreamer->emitELFSize(CurrentSectionBeginSym, SizeExp);
+ }
MBBSectionRanges[MBB.getSectionIDNum()] =
- MBBSectionRange{CurrentSectionBeginSym, MBB.getEndSymbol()};
+ MBBSectionRange{CurrentSectionBeginSym, MBB.getEndSymbol()};
}
}
emitBasicBlockEnd(MBB);
-
- if (CanDoExtraAnalysis) {
- // Skip empty blocks.
- if (MBB.empty())
- continue;
-
- MachineOptimizationRemarkAnalysis R(DEBUG_TYPE, "InstructionMix",
- MBB.begin()->getDebugLoc(), &MBB);
-
- // Generate instruction mix remark. First, sort counts in descending order
- // by count and name.
- SmallVector<std::pair<StringRef, unsigned>, 128> MnemonicVec;
- for (auto &KV : MnemonicCounts)
- MnemonicVec.emplace_back(KV.first, KV.second);
-
- sort(MnemonicVec, [](const std::pair<StringRef, unsigned> &A,
- const std::pair<StringRef, unsigned> &B) {
- if (A.second > B.second)
- return true;
- if (A.second == B.second)
- return StringRef(A.first) < StringRef(B.first);
- return false;
- });
- R << "BasicBlock: " << ore::NV("BasicBlock", MBB.getName()) << "\n";
- for (auto &KV : MnemonicVec) {
- auto Name = (Twine("INST_") + KV.first.trim()).str();
- R << KV.first << ": " << ore::NV(Name, KV.second) << "\n";
- }
- ORE->emit(R);
- }
+
+ if (CanDoExtraAnalysis) {
+ // Skip empty blocks.
+ if (MBB.empty())
+ continue;
+
+ MachineOptimizationRemarkAnalysis R(DEBUG_TYPE, "InstructionMix",
+ MBB.begin()->getDebugLoc(), &MBB);
+
+ // Generate instruction mix remark. First, sort counts in descending order
+ // by count and name.
+ SmallVector<std::pair<StringRef, unsigned>, 128> MnemonicVec;
+ for (auto &KV : MnemonicCounts)
+ MnemonicVec.emplace_back(KV.first, KV.second);
+
+ sort(MnemonicVec, [](const std::pair<StringRef, unsigned> &A,
+ const std::pair<StringRef, unsigned> &B) {
+ if (A.second > B.second)
+ return true;
+ if (A.second == B.second)
+ return StringRef(A.first) < StringRef(B.first);
+ return false;
+ });
+ R << "BasicBlock: " << ore::NV("BasicBlock", MBB.getName()) << "\n";
+ for (auto &KV : MnemonicVec) {
+ auto Name = (Twine("INST_") + KV.first.trim()).str();
+ R << KV.first << ": " << ore::NV(Name, KV.second) << "\n";
+ }
+ ORE->emit(R);
+ }
}
EmittedInsts += NumInstsInFunction;
@@ -1417,11 +1417,11 @@ void AsmPrinter::emitFunctionBody() {
HI.Handler->endFunction(MF);
}
- // Emit section containing BB address offsets and their metadata, when
- // BB labels are requested for this function.
- if (MF->hasBBLabels())
- emitBBAddrMapSection(*MF);
-
+ // Emit section containing BB address offsets and their metadata, when
+ // BB labels are requested for this function.
+ if (MF->hasBBLabels())
+ emitBBAddrMapSection(*MF);
+
// Emit section containing stack size metadata.
emitStackSizeSection(*MF);
@@ -1524,30 +1524,30 @@ void AsmPrinter::emitGlobalIndirectSymbol(Module &M,
IsFunction =
CE->getOperand(0)->getType()->getPointerElementType()->isFunctionTy();
- // AIX's assembly directive `.set` is not usable for aliasing purpose,
- // so AIX has to use the extra-label-at-definition strategy. At this
- // point, all the extra label is emitted, we just have to emit linkage for
- // those labels.
- if (TM.getTargetTriple().isOSBinFormatXCOFF()) {
- assert(!isa<GlobalIFunc>(GIS) && "IFunc is not supported on AIX.");
- assert(MAI->hasVisibilityOnlyWithLinkage() &&
- "Visibility should be handled with emitLinkage() on AIX.");
- emitLinkage(&GIS, Name);
- // If it's a function, also emit linkage for aliases of function entry
- // point.
- if (IsFunction)
- emitLinkage(&GIS,
- getObjFileLowering().getFunctionEntryPointSymbol(&GIS, TM));
- return;
- }
-
- if (GIS.hasExternalLinkage() || !MAI->getWeakRefDirective())
- OutStreamer->emitSymbolAttribute(Name, MCSA_Global);
- else if (GIS.hasWeakLinkage() || GIS.hasLinkOnceLinkage())
- OutStreamer->emitSymbolAttribute(Name, MCSA_WeakReference);
- else
- assert(GIS.hasLocalLinkage() && "Invalid alias or ifunc linkage");
-
+ // AIX's assembly directive `.set` is not usable for aliasing purpose,
+ // so AIX has to use the extra-label-at-definition strategy. At this
+ // point, all the extra label is emitted, we just have to emit linkage for
+ // those labels.
+ if (TM.getTargetTriple().isOSBinFormatXCOFF()) {
+ assert(!isa<GlobalIFunc>(GIS) && "IFunc is not supported on AIX.");
+ assert(MAI->hasVisibilityOnlyWithLinkage() &&
+ "Visibility should be handled with emitLinkage() on AIX.");
+ emitLinkage(&GIS, Name);
+ // If it's a function, also emit linkage for aliases of function entry
+ // point.
+ if (IsFunction)
+ emitLinkage(&GIS,
+ getObjFileLowering().getFunctionEntryPointSymbol(&GIS, TM));
+ return;
+ }
+
+ if (GIS.hasExternalLinkage() || !MAI->getWeakRefDirective())
+ OutStreamer->emitSymbolAttribute(Name, MCSA_Global);
+ else if (GIS.hasWeakLinkage() || GIS.hasLinkOnceLinkage())
+ OutStreamer->emitSymbolAttribute(Name, MCSA_WeakReference);
+ else
+ assert(GIS.hasLocalLinkage() && "Invalid alias or ifunc linkage");
+
// Set the symbol type to function if the alias has a function type.
// This affects codegen when the aliasee is not a function.
if (IsFunction)
@@ -1657,8 +1657,8 @@ bool AsmPrinter::doFinalization(Module &M) {
// Variable `Name` is the function descriptor symbol (see above). Get the
// function entry point symbol.
MCSymbol *FnEntryPointSym = TLOF.getFunctionEntryPointSymbol(&F, TM);
- // Emit linkage for the function entry point.
- emitLinkage(&F, FnEntryPointSym);
+ // Emit linkage for the function entry point.
+ emitLinkage(&F, FnEntryPointSym);
// Emit linkage for the function descriptor.
emitLinkage(&F, Name);
@@ -1723,11 +1723,11 @@ bool AsmPrinter::doFinalization(Module &M) {
HI.TimerGroupDescription, TimePassesIsEnabled);
HI.Handler->endModule();
}
-
- // This deletes all the ephemeral handlers that AsmPrinter added, while
- // keeping all the user-added handlers alive until the AsmPrinter is
- // destroyed.
- Handlers.erase(Handlers.begin() + NumUserHandlers, Handlers.end());
+
+ // This deletes all the ephemeral handlers that AsmPrinter added, while
+ // keeping all the user-added handlers alive until the AsmPrinter is
+ // destroyed.
+ Handlers.erase(Handlers.begin() + NumUserHandlers, Handlers.end());
DD = nullptr;
// If the target wants to know about weak references, print them all.
@@ -1854,11 +1854,11 @@ bool AsmPrinter::doFinalization(Module &M) {
return false;
}
-MCSymbol *AsmPrinter::getMBBExceptionSym(const MachineBasicBlock &MBB) {
- auto Res = MBBSectionExceptionSyms.try_emplace(MBB.getSectionIDNum());
- if (Res.second)
- Res.first->second = createTempSymbol("exception");
- return Res.first->second;
+MCSymbol *AsmPrinter::getMBBExceptionSym(const MachineBasicBlock &MBB) {
+ auto Res = MBBSectionExceptionSyms.try_emplace(MBB.getSectionIDNum());
+ if (Res.second)
+ Res.first->second = createTempSymbol("exception");
+ return Res.first->second;
}
void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
@@ -1885,13 +1885,13 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
CurrentFnBegin = nullptr;
CurrentSectionBeginSym = nullptr;
MBBSectionRanges.clear();
- MBBSectionExceptionSyms.clear();
+ MBBSectionExceptionSyms.clear();
bool NeedsLocalForSize = MAI->needsLocalForSize();
if (F.hasFnAttribute("patchable-function-entry") ||
F.hasFnAttribute("function-instrument") ||
F.hasFnAttribute("xray-instruction-threshold") ||
needFuncLabelsForEHOrDebugInfo(MF) || NeedsLocalForSize ||
- MF.getTarget().Options.EmitStackSizeSection || MF.hasBBLabels()) {
+ MF.getTarget().Options.EmitStackSizeSection || MF.hasBBLabels()) {
CurrentFnBegin = createTempSymbol("func_begin");
if (NeedsLocalForSize)
CurrentFnSymForSize = CurrentFnBegin;
@@ -1981,7 +1981,7 @@ void AsmPrinter::emitConstantPool() {
unsigned NewOffset = alignTo(Offset, CPE.getAlign());
OutStreamer->emitZeros(NewOffset - Offset);
- Offset = NewOffset + CPE.getSizeInBytes(getDataLayout());
+ Offset = NewOffset + CPE.getSizeInBytes(getDataLayout());
OutStreamer->emitLabel(Sym);
if (CPE.isMachineConstantPoolEntry())
@@ -2181,50 +2181,50 @@ void AsmPrinter::emitLLVMUsedList(const ConstantArray *InitList) {
}
}
-void AsmPrinter::preprocessXXStructorList(const DataLayout &DL,
- const Constant *List,
- SmallVector<Structor, 8> &Structors) {
- // Should be an array of '{ i32, void ()*, i8* }' structs. The first value is
- // the init priority.
- if (!isa<ConstantArray>(List))
- return;
+void AsmPrinter::preprocessXXStructorList(const DataLayout &DL,
+ const Constant *List,
+ SmallVector<Structor, 8> &Structors) {
+ // Should be an array of '{ i32, void ()*, i8* }' structs. The first value is
+ // the init priority.
+ if (!isa<ConstantArray>(List))
+ return;
// Gather the structors in a form that's convenient for sorting by priority.
for (Value *O : cast<ConstantArray>(List)->operands()) {
auto *CS = cast<ConstantStruct>(O);
if (CS->getOperand(1)->isNullValue())
- break; // Found a null terminator, skip the rest.
+ break; // Found a null terminator, skip the rest.
ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0));
- if (!Priority)
- continue; // Malformed.
+ if (!Priority)
+ continue; // Malformed.
Structors.push_back(Structor());
Structor &S = Structors.back();
S.Priority = Priority->getLimitedValue(65535);
S.Func = CS->getOperand(1);
- if (!CS->getOperand(2)->isNullValue()) {
- if (TM.getTargetTriple().isOSAIX())
- llvm::report_fatal_error(
- "associated data of XXStructor list is not yet supported on AIX");
+ if (!CS->getOperand(2)->isNullValue()) {
+ if (TM.getTargetTriple().isOSAIX())
+ llvm::report_fatal_error(
+ "associated data of XXStructor list is not yet supported on AIX");
S.ComdatKey =
dyn_cast<GlobalValue>(CS->getOperand(2)->stripPointerCasts());
- }
+ }
}
// Emit the function pointers in the target-specific order
llvm::stable_sort(Structors, [](const Structor &L, const Structor &R) {
return L.Priority < R.Priority;
});
-}
-
-/// EmitXXStructorList - Emit the ctor or dtor list taking into account the init
-/// priority.
-void AsmPrinter::emitXXStructorList(const DataLayout &DL, const Constant *List,
- bool IsCtor) {
- SmallVector<Structor, 8> Structors;
- preprocessXXStructorList(DL, List, Structors);
- if (Structors.empty())
- return;
-
+}
+
+/// EmitXXStructorList - Emit the ctor or dtor list taking into account the init
+/// priority.
+void AsmPrinter::emitXXStructorList(const DataLayout &DL, const Constant *List,
+ bool IsCtor) {
+ SmallVector<Structor, 8> Structors;
+ preprocessXXStructorList(DL, List, Structors);
+ if (Structors.empty())
+ return;
+
const Align Align = DL.getPointerPrefAlignment();
for (Structor &S : Structors) {
const TargetLoweringObjectFile &Obj = getObjFileLowering();
@@ -2240,9 +2240,9 @@ void AsmPrinter::emitXXStructorList(const DataLayout &DL, const Constant *List,
KeySym = getSymbol(GV);
}
-
+
MCSection *OutputSection =
- (IsCtor ? Obj.getStaticCtorSection(S.Priority, KeySym)
+ (IsCtor ? Obj.getStaticCtorSection(S.Priority, KeySym)
: Obj.getStaticDtorSection(S.Priority, KeySym));
OutStreamer->SwitchSection(OutputSection);
if (OutStreamer->getCurrentSection() != OutStreamer->getPreviousSection())
@@ -2376,25 +2376,25 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) {
if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV))
return MCSymbolRefExpr::create(GetBlockAddressSymbol(BA), Ctx);
- if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(CV))
- return getObjFileLowering().lowerDSOLocalEquivalent(Equiv, TM);
-
+ if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(CV))
+ return getObjFileLowering().lowerDSOLocalEquivalent(Equiv, TM);
+
const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV);
if (!CE) {
llvm_unreachable("Unknown constant value to lower!");
}
switch (CE->getOpcode()) {
- case Instruction::AddrSpaceCast: {
- const Constant *Op = CE->getOperand(0);
- unsigned DstAS = CE->getType()->getPointerAddressSpace();
- unsigned SrcAS = Op->getType()->getPointerAddressSpace();
- if (TM.isNoopAddrSpaceCast(SrcAS, DstAS))
- return lowerConstant(Op);
-
- // Fallthrough to error.
- LLVM_FALLTHROUGH;
- }
+ case Instruction::AddrSpaceCast: {
+ const Constant *Op = CE->getOperand(0);
+ unsigned DstAS = CE->getType()->getPointerAddressSpace();
+ unsigned SrcAS = Op->getType()->getPointerAddressSpace();
+ if (TM.isNoopAddrSpaceCast(SrcAS, DstAS))
+ return lowerConstant(Op);
+
+ // Fallthrough to error.
+ LLVM_FALLTHROUGH;
+ }
default: {
// If the code isn't optimized, there may be outstanding folding
// opportunities. Attempt to fold the expression using DataLayout as a
@@ -2460,8 +2460,8 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) {
//
// If the pointer is larger than the resultant integer, then
// as with Trunc just depend on the assembler to truncate it.
- if (DL.getTypeAllocSize(Ty).getFixedSize() <=
- DL.getTypeAllocSize(Op->getType()).getFixedSize())
+ if (DL.getTypeAllocSize(Ty).getFixedSize() <=
+ DL.getTypeAllocSize(Op->getType()).getFixedSize())
return OpExpr;
// Otherwise the pointer is smaller than the resultant integer, mask off
@@ -2475,25 +2475,25 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) {
case Instruction::Sub: {
GlobalValue *LHSGV;
APInt LHSOffset;
- DSOLocalEquivalent *DSOEquiv;
+ DSOLocalEquivalent *DSOEquiv;
if (IsConstantOffsetFromGlobal(CE->getOperand(0), LHSGV, LHSOffset,
- getDataLayout(), &DSOEquiv)) {
+ getDataLayout(), &DSOEquiv)) {
GlobalValue *RHSGV;
APInt RHSOffset;
if (IsConstantOffsetFromGlobal(CE->getOperand(1), RHSGV, RHSOffset,
getDataLayout())) {
const MCExpr *RelocExpr =
getObjFileLowering().lowerRelativeReference(LHSGV, RHSGV, TM);
- if (!RelocExpr) {
- const MCExpr *LHSExpr =
- MCSymbolRefExpr::create(getSymbol(LHSGV), Ctx);
- if (DSOEquiv &&
- getObjFileLowering().supportDSOLocalEquivalentLowering())
- LHSExpr =
- getObjFileLowering().lowerDSOLocalEquivalent(DSOEquiv, TM);
+ if (!RelocExpr) {
+ const MCExpr *LHSExpr =
+ MCSymbolRefExpr::create(getSymbol(LHSGV), Ctx);
+ if (DSOEquiv &&
+ getObjFileLowering().supportDSOLocalEquivalentLowering())
+ LHSExpr =
+ getObjFileLowering().lowerDSOLocalEquivalent(DSOEquiv, TM);
RelocExpr = MCBinaryExpr::createSub(
- LHSExpr, MCSymbolRefExpr::create(getSymbol(RHSGV), Ctx), Ctx);
- }
+ LHSExpr, MCSymbolRefExpr::create(getSymbol(RHSGV), Ctx), Ctx);
+ }
int64_t Addend = (LHSOffset - RHSOffset).getSExtValue();
if (Addend != 0)
RelocExpr = MCBinaryExpr::createAdd(
@@ -3124,7 +3124,7 @@ static void emitBasicBlockLoopComments(const MachineBasicBlock &MBB,
OS.indent(Loop->getLoopDepth()*2-2);
OS << "This ";
- if (Loop->isInnermost())
+ if (Loop->isInnermost())
OS << "Inner ";
OS << "Loop Header: Depth=" + Twine(Loop->getLoopDepth()) << '\n';
@@ -3148,16 +3148,16 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
if (Alignment != Align(1))
emitAlignment(Alignment);
- // Switch to a new section if this basic block must begin a section. The
- // entry block is always placed in the function section and is handled
- // separately.
- if (MBB.isBeginSection() && !MBB.isEntryBlock()) {
- OutStreamer->SwitchSection(
- getObjFileLowering().getSectionForMachineBasicBlock(MF->getFunction(),
- MBB, TM));
- CurrentSectionBeginSym = MBB.getSymbol();
- }
-
+ // Switch to a new section if this basic block must begin a section. The
+ // entry block is always placed in the function section and is handled
+ // separately.
+ if (MBB.isBeginSection() && !MBB.isEntryBlock()) {
+ OutStreamer->SwitchSection(
+ getObjFileLowering().getSectionForMachineBasicBlock(MF->getFunction(),
+ MBB, TM));
+ CurrentSectionBeginSym = MBB.getSymbol();
+ }
+
// If the block has its address taken, emit any labels that were used to
// reference the block. It is possible that there is more than one label
// here, because multiple LLVM BB's may have been RAUW'd to this block after
@@ -3188,25 +3188,25 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
emitBasicBlockLoopComments(MBB, MLI, *this);
}
- // Print the main label for the block.
- if (shouldEmitLabelForBasicBlock(MBB)) {
- if (isVerbose() && MBB.hasLabelMustBeEmitted())
- OutStreamer->AddComment("Label of block must be emitted");
- OutStreamer->emitLabel(MBB.getSymbol());
- } else {
+ // Print the main label for the block.
+ if (shouldEmitLabelForBasicBlock(MBB)) {
+ if (isVerbose() && MBB.hasLabelMustBeEmitted())
+ OutStreamer->AddComment("Label of block must be emitted");
+ OutStreamer->emitLabel(MBB.getSymbol());
+ } else {
if (isVerbose()) {
// NOTE: Want this comment at start of line, don't emit with AddComment.
OutStreamer->emitRawComment(" %bb." + Twine(MBB.getNumber()) + ":",
false);
}
}
-
- // With BB sections, each basic block must handle CFI information on its own
- // if it begins a section (Entry block is handled separately by
- // AsmPrinterHandler::beginFunction).
- if (MBB.isBeginSection() && !MBB.isEntryBlock())
- for (const HandlerInfo &HI : Handlers)
- HI.Handler->beginBasicBlock(MBB);
+
+ // With BB sections, each basic block must handle CFI information on its own
+ // if it begins a section (Entry block is handled separately by
+ // AsmPrinterHandler::beginFunction).
+ if (MBB.isBeginSection() && !MBB.isEntryBlock())
+ for (const HandlerInfo &HI : Handlers)
+ HI.Handler->beginBasicBlock(MBB);
}
void AsmPrinter::emitBasicBlockEnd(const MachineBasicBlock &MBB) {
@@ -3238,21 +3238,21 @@ void AsmPrinter::emitVisibility(MCSymbol *Sym, unsigned Visibility,
OutStreamer->emitSymbolAttribute(Sym, Attr);
}
-bool AsmPrinter::shouldEmitLabelForBasicBlock(
- const MachineBasicBlock &MBB) const {
- // With `-fbasic-block-sections=`, a label is needed for every non-entry block
- // in the labels mode (option `=labels`) and every section beginning in the
- // sections mode (`=all` and `=list=`).
- if ((MF->hasBBLabels() || MBB.isBeginSection()) && !MBB.isEntryBlock())
- return true;
- // A label is needed for any block with at least one predecessor (when that
- // predecessor is not the fallthrough predecessor, or if it is an EH funclet
- // entry, or if a label is forced).
- return !MBB.pred_empty() &&
- (!isBlockOnlyReachableByFallthrough(&MBB) || MBB.isEHFuncletEntry() ||
- MBB.hasLabelMustBeEmitted());
-}
-
+bool AsmPrinter::shouldEmitLabelForBasicBlock(
+ const MachineBasicBlock &MBB) const {
+ // With `-fbasic-block-sections=`, a label is needed for every non-entry block
+ // in the labels mode (option `=labels`) and every section beginning in the
+ // sections mode (`=all` and `=list=`).
+ if ((MF->hasBBLabels() || MBB.isBeginSection()) && !MBB.isEntryBlock())
+ return true;
+ // A label is needed for any block with at least one predecessor (when that
+ // predecessor is not the fallthrough predecessor, or if it is an EH funclet
+ // entry, or if a label is forced).
+ return !MBB.pred_empty() &&
+ (!isBlockOnlyReachableByFallthrough(&MBB) || MBB.isEHFuncletEntry() ||
+ MBB.hasLabelMustBeEmitted());
+}
+
/// isBlockOnlyReachableByFallthough - Return true if the basic block has
/// exactly one predecessor and the control transfer mechanism between
/// the predecessor and this block is a fall-through.
@@ -3368,7 +3368,7 @@ void AsmPrinter::emitXRayTable() {
MCSection *InstMap = nullptr;
MCSection *FnSledIndex = nullptr;
const Triple &TT = TM.getTargetTriple();
- // Use PC-relative addresses on all targets.
+ // Use PC-relative addresses on all targets.
if (TT.isOSBinFormatELF()) {
auto LinkedToSym = cast<MCSymbolELF>(CurrentFnSym);
auto Flags = ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER;
@@ -3405,20 +3405,20 @@ void AsmPrinter::emitXRayTable() {
OutStreamer->SwitchSection(InstMap);
OutStreamer->emitLabel(SledsStart);
for (const auto &Sled : Sleds) {
- MCSymbol *Dot = Ctx.createTempSymbol();
- OutStreamer->emitLabel(Dot);
- OutStreamer->emitValueImpl(
- MCBinaryExpr::createSub(MCSymbolRefExpr::create(Sled.Sled, Ctx),
- MCSymbolRefExpr::create(Dot, Ctx), Ctx),
- WordSizeBytes);
- OutStreamer->emitValueImpl(
- MCBinaryExpr::createSub(
- MCSymbolRefExpr::create(CurrentFnBegin, Ctx),
- MCBinaryExpr::createAdd(MCSymbolRefExpr::create(Dot, Ctx),
- MCConstantExpr::create(WordSizeBytes, Ctx),
- Ctx),
- Ctx),
- WordSizeBytes);
+ MCSymbol *Dot = Ctx.createTempSymbol();
+ OutStreamer->emitLabel(Dot);
+ OutStreamer->emitValueImpl(
+ MCBinaryExpr::createSub(MCSymbolRefExpr::create(Sled.Sled, Ctx),
+ MCSymbolRefExpr::create(Dot, Ctx), Ctx),
+ WordSizeBytes);
+ OutStreamer->emitValueImpl(
+ MCBinaryExpr::createSub(
+ MCSymbolRefExpr::create(CurrentFnBegin, Ctx),
+ MCBinaryExpr::createAdd(MCSymbolRefExpr::create(Dot, Ctx),
+ MCConstantExpr::create(WordSizeBytes, Ctx),
+ Ctx),
+ Ctx),
+ WordSizeBytes);
Sled.emit(WordSizeBytes, OutStreamer.get());
}
MCSymbol *SledsEnd = OutContext.createTempSymbol("xray_sleds_end", true);
@@ -3493,17 +3493,17 @@ uint16_t AsmPrinter::getDwarfVersion() const {
void AsmPrinter::setDwarfVersion(uint16_t Version) {
OutStreamer->getContext().setDwarfVersion(Version);
}
-
-bool AsmPrinter::isDwarf64() const {
- return OutStreamer->getContext().getDwarfFormat() == dwarf::DWARF64;
-}
-
-unsigned int AsmPrinter::getDwarfOffsetByteSize() const {
- return dwarf::getDwarfOffsetByteSize(
- OutStreamer->getContext().getDwarfFormat());
-}
-
-unsigned int AsmPrinter::getUnitLengthFieldByteSize() const {
- return dwarf::getUnitLengthFieldByteSize(
- OutStreamer->getContext().getDwarfFormat());
-}
+
+bool AsmPrinter::isDwarf64() const {
+ return OutStreamer->getContext().getDwarfFormat() == dwarf::DWARF64;
+}
+
+unsigned int AsmPrinter::getDwarfOffsetByteSize() const {
+ return dwarf::getDwarfOffsetByteSize(
+ OutStreamer->getContext().getDwarfFormat());
+}
+
+unsigned int AsmPrinter::getUnitLengthFieldByteSize() const {
+ return dwarf::getUnitLengthFieldByteSize(
+ OutStreamer->getContext().getDwarfFormat());
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
index 3ab8869c2c..c6e43445e7 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
@@ -27,7 +27,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
-#include <cstdint>
+#include <cstdint>
using namespace llvm;
#define DEBUG_TYPE "asm-printer"
@@ -98,12 +98,12 @@ static const char *DecodeDWARFEncoding(unsigned Encoding) {
case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8
:
return "indirect pcrel sdata8";
- case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_datarel |
- dwarf::DW_EH_PE_sdata4:
- return "indirect datarel sdata4";
- case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_datarel |
- dwarf::DW_EH_PE_sdata8:
- return "indirect datarel sdata8";
+ case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_datarel |
+ dwarf::DW_EH_PE_sdata4:
+ return "indirect datarel sdata4";
+ case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_datarel |
+ dwarf::DW_EH_PE_sdata8:
+ return "indirect datarel sdata8";
}
return "<unknown encoding>";
@@ -144,7 +144,7 @@ unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
}
}
-void AsmPrinter::emitTTypeReference(const GlobalValue *GV, unsigned Encoding) {
+void AsmPrinter::emitTTypeReference(const GlobalValue *GV, unsigned Encoding) {
if (GV) {
const TargetLoweringObjectFile &TLOF = getObjFileLowering();
@@ -160,22 +160,22 @@ void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label,
if (!ForceOffset) {
// On COFF targets, we have to emit the special .secrel32 directive.
if (MAI->needsDwarfSectionOffsetDirective()) {
- assert(!isDwarf64() &&
- "emitting DWARF64 is not implemented for COFF targets");
+ assert(!isDwarf64() &&
+ "emitting DWARF64 is not implemented for COFF targets");
OutStreamer->EmitCOFFSecRel32(Label, /*Offset=*/0);
return;
}
// If the format uses relocations with dwarf, refer to the symbol directly.
if (MAI->doesDwarfUseRelocationsAcrossSections()) {
- OutStreamer->emitSymbolValue(Label, getDwarfOffsetByteSize());
+ OutStreamer->emitSymbolValue(Label, getDwarfOffsetByteSize());
return;
}
}
// Otherwise, emit it as a label difference from the start of the section.
- emitLabelDifference(Label, Label->getSection().getBeginSymbol(),
- getDwarfOffsetByteSize());
+ emitLabelDifference(Label, Label->getSection().getBeginSymbol(),
+ getDwarfOffsetByteSize());
}
void AsmPrinter::emitDwarfStringOffset(DwarfStringPoolEntry S) const {
@@ -186,40 +186,40 @@ void AsmPrinter::emitDwarfStringOffset(DwarfStringPoolEntry S) const {
}
// Just emit the offset directly; no need for symbol math.
- OutStreamer->emitIntValue(S.Offset, getDwarfOffsetByteSize());
+ OutStreamer->emitIntValue(S.Offset, getDwarfOffsetByteSize());
}
void AsmPrinter::emitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const {
- emitLabelPlusOffset(Label, Offset, getDwarfOffsetByteSize());
+ emitLabelPlusOffset(Label, Offset, getDwarfOffsetByteSize());
+}
+
+void AsmPrinter::emitDwarfLengthOrOffset(uint64_t Value) const {
+ assert(isDwarf64() || Value <= UINT32_MAX);
+ OutStreamer->emitIntValue(Value, getDwarfOffsetByteSize());
+}
+
+void AsmPrinter::maybeEmitDwarf64Mark() const {
+ if (!isDwarf64())
+ return;
+ OutStreamer->AddComment("DWARF64 Mark");
+ OutStreamer->emitInt32(dwarf::DW_LENGTH_DWARF64);
+}
+
+void AsmPrinter::emitDwarfUnitLength(uint64_t Length,
+ const Twine &Comment) const {
+ assert(isDwarf64() || Length <= dwarf::DW_LENGTH_lo_reserved);
+ maybeEmitDwarf64Mark();
+ OutStreamer->AddComment(Comment);
+ OutStreamer->emitIntValue(Length, getDwarfOffsetByteSize());
+}
+
+void AsmPrinter::emitDwarfUnitLength(const MCSymbol *Hi, const MCSymbol *Lo,
+ const Twine &Comment) const {
+ maybeEmitDwarf64Mark();
+ OutStreamer->AddComment(Comment);
+ OutStreamer->emitAbsoluteSymbolDiff(Hi, Lo, getDwarfOffsetByteSize());
}
-void AsmPrinter::emitDwarfLengthOrOffset(uint64_t Value) const {
- assert(isDwarf64() || Value <= UINT32_MAX);
- OutStreamer->emitIntValue(Value, getDwarfOffsetByteSize());
-}
-
-void AsmPrinter::maybeEmitDwarf64Mark() const {
- if (!isDwarf64())
- return;
- OutStreamer->AddComment("DWARF64 Mark");
- OutStreamer->emitInt32(dwarf::DW_LENGTH_DWARF64);
-}
-
-void AsmPrinter::emitDwarfUnitLength(uint64_t Length,
- const Twine &Comment) const {
- assert(isDwarf64() || Length <= dwarf::DW_LENGTH_lo_reserved);
- maybeEmitDwarf64Mark();
- OutStreamer->AddComment(Comment);
- OutStreamer->emitIntValue(Length, getDwarfOffsetByteSize());
-}
-
-void AsmPrinter::emitDwarfUnitLength(const MCSymbol *Hi, const MCSymbol *Lo,
- const Twine &Comment) const {
- maybeEmitDwarf64Mark();
- OutStreamer->AddComment(Comment);
- OutStreamer->emitAbsoluteSymbolDiff(Hi, Lo, getDwarfOffsetByteSize());
-}
-
void AsmPrinter::emitCallSiteOffset(const MCSymbol *Hi, const MCSymbol *Lo,
unsigned Encoding) const {
// The least significant 3 bits specify the width of the encoding
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index c30e7651ba..4a67b0bc2c 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -11,7 +11,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -147,7 +147,7 @@ void AsmPrinter::emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
// we only need MCInstrInfo for asm parsing. We create one unconditionally
// because it's not subtarget dependent.
std::unique_ptr<MCInstrInfo> MII(TM.getTarget().createMCInstrInfo());
- assert(MII && "Failed to create instruction info");
+ assert(MII && "Failed to create instruction info");
std::unique_ptr<MCTargetAsmParser> TAP(TM.getTarget().createMCAsmParser(
STI, *Parser, *MII, MCOptions));
if (!TAP)
@@ -234,8 +234,8 @@ static void EmitMSInlineAsmStr(const char *AsmStr, const MachineInstr *MI,
const char *IDStart = LastEmitted;
const char *IDEnd = IDStart;
- while (isDigit(*IDEnd))
- ++IDEnd;
+ while (isDigit(*IDEnd))
+ ++IDEnd;
unsigned Val;
if (StringRef(IDStart, IDEnd-IDStart).getAsInteger(10, Val))
@@ -400,8 +400,8 @@ static void EmitGCCInlineAsmStr(const char *AsmStr, const MachineInstr *MI,
const char *IDStart = LastEmitted;
const char *IDEnd = IDStart;
- while (isDigit(*IDEnd))
- ++IDEnd;
+ while (isDigit(*IDEnd))
+ ++IDEnd;
unsigned Val;
if (StringRef(IDStart, IDEnd-IDStart).getAsInteger(10, Val))
@@ -551,23 +551,23 @@ void AsmPrinter::emitInlineAsm(const MachineInstr *MI) const {
EmitMSInlineAsmStr(AsmStr, MI, MMI, AP, LocCookie, OS);
// Emit warnings if we use reserved registers on the clobber list, as
- // that might lead to undefined behaviour.
- SmallVector<Register, 8> RestrRegs;
- const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
+ // that might lead to undefined behaviour.
+ SmallVector<Register, 8> RestrRegs;
+ const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
// Start with the first operand descriptor, and iterate over them.
for (unsigned I = InlineAsm::MIOp_FirstOperand, NumOps = MI->getNumOperands();
I < NumOps; ++I) {
const MachineOperand &MO = MI->getOperand(I);
- if (!MO.isImm())
- continue;
- unsigned Flags = MO.getImm();
- if (InlineAsm::getKind(Flags) == InlineAsm::Kind_Clobber) {
- Register Reg = MI->getOperand(I + 1).getReg();
- if (!TRI->isAsmClobberable(*MF, Reg))
- RestrRegs.push_back(Reg);
+ if (!MO.isImm())
+ continue;
+ unsigned Flags = MO.getImm();
+ if (InlineAsm::getKind(Flags) == InlineAsm::Kind_Clobber) {
+ Register Reg = MI->getOperand(I + 1).getReg();
+ if (!TRI->isAsmClobberable(*MF, Reg))
+ RestrRegs.push_back(Reg);
}
- // Skip to one before the next operand descriptor, if it exists.
- I += InlineAsm::getNumOperandRegisters(Flags);
+ // Skip to one before the next operand descriptor, if it exists.
+ I += InlineAsm::getNumOperandRegisters(Flags);
}
if (!RestrRegs.empty()) {
@@ -577,15 +577,15 @@ void AsmPrinter::emitInlineAsm(const MachineInstr *MI) const {
SrcMgr.getMemoryBuffer(BufNum)->getBuffer().begin());
std::string Msg = "inline asm clobber list contains reserved registers: ";
- for (auto I = RestrRegs.begin(), E = RestrRegs.end(); I != E; ++I) {
+ for (auto I = RestrRegs.begin(), E = RestrRegs.end(); I != E; ++I) {
if(I != RestrRegs.begin())
Msg += ", ";
- Msg += TRI->getName(*I);
+ Msg += TRI->getName(*I);
}
- const char *Note =
- "Reserved registers on the clobber list may not be "
- "preserved across the asm statement, and clobbering them may "
- "lead to undefined behaviour.";
+ const char *Note =
+ "Reserved registers on the clobber list may not be "
+ "preserved across the asm statement, and clobbering them may "
+ "lead to undefined behaviour.";
SrcMgr.PrintMessage(Loc, SourceMgr::DK_Warning, Msg);
SrcMgr.PrintMessage(Loc, SourceMgr::DK_Note, Note);
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/ByteStreamer.h b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/ByteStreamer.h
index 6aa6045307..5e7db1f2f7 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/ByteStreamer.h
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/ByteStreamer.h
@@ -29,7 +29,7 @@ class ByteStreamer {
public:
// For now we're just handling the calls we need for dwarf emission/hashing.
- virtual void emitInt8(uint8_t Byte, const Twine &Comment = "") = 0;
+ virtual void emitInt8(uint8_t Byte, const Twine &Comment = "") = 0;
virtual void emitSLEB128(uint64_t DWord, const Twine &Comment = "") = 0;
virtual void emitULEB128(uint64_t DWord, const Twine &Comment = "",
unsigned PadTo = 0) = 0;
@@ -41,7 +41,7 @@ private:
public:
APByteStreamer(AsmPrinter &Asm) : AP(Asm) {}
- void emitInt8(uint8_t Byte, const Twine &Comment) override {
+ void emitInt8(uint8_t Byte, const Twine &Comment) override {
AP.OutStreamer->AddComment(Comment);
AP.emitInt8(Byte);
}
@@ -61,7 +61,7 @@ class HashingByteStreamer final : public ByteStreamer {
DIEHash &Hash;
public:
HashingByteStreamer(DIEHash &H) : Hash(H) {}
- void emitInt8(uint8_t Byte, const Twine &Comment) override {
+ void emitInt8(uint8_t Byte, const Twine &Comment) override {
Hash.update(Byte);
}
void emitSLEB128(uint64_t DWord, const Twine &Comment) override {
@@ -88,7 +88,7 @@ public:
std::vector<std::string> &Comments, bool GenerateComments)
: Buffer(Buffer), Comments(Comments), GenerateComments(GenerateComments) {
}
- void emitInt8(uint8_t Byte, const Twine &Comment) override {
+ void emitInt8(uint8_t Byte, const Twine &Comment) override {
Buffer.push_back(Byte);
if (GenerateComments)
Comments.push_back(Comment.str());
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 639dc6740c..b15e750aaf 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -126,9 +126,9 @@ static CPUType mapArchToCVCPUType(Triple::ArchType Type) {
case Triple::ArchType::x86_64:
return CPUType::X64;
case Triple::ArchType::thumb:
- // LLVM currently doesn't support Windows CE and so thumb
- // here is indiscriminately mapped to ARMNT specifically.
- return CPUType::ARMNT;
+ // LLVM currently doesn't support Windows CE and so thumb
+ // here is indiscriminately mapped to ARMNT specifically.
+ return CPUType::ARMNT;
case Triple::ArchType::aarch64:
return CPUType::ARM64;
default:
@@ -137,7 +137,7 @@ static CPUType mapArchToCVCPUType(Triple::ArchType Type) {
}
CodeViewDebug::CodeViewDebug(AsmPrinter *AP)
- : DebugHandlerBase(AP), OS(*Asm->OutStreamer), TypeTable(Allocator) {}
+ : DebugHandlerBase(AP), OS(*Asm->OutStreamer), TypeTable(Allocator) {}
StringRef CodeViewDebug::getFullFilepath(const DIFile *File) {
std::string &Filepath = FileToFilepathMap[File];
@@ -475,7 +475,7 @@ void CodeViewDebug::recordLocalVariable(LocalVariable &&Var,
static void addLocIfNotPresent(SmallVectorImpl<const DILocation *> &Locs,
const DILocation *Loc) {
- if (!llvm::is_contained(Locs, Loc))
+ if (!llvm::is_contained(Locs, Loc))
Locs.push_back(Loc);
}
@@ -541,27 +541,27 @@ void CodeViewDebug::emitCodeViewMagicVersion() {
OS.emitInt32(COFF::DEBUG_SECTION_MAGIC);
}
-void CodeViewDebug::beginModule(Module *M) {
- // If module doesn't have named metadata anchors or COFF debug section
- // is not available, skip any debug info related stuff.
- if (!M->getNamedMetadata("llvm.dbg.cu") ||
- !Asm->getObjFileLowering().getCOFFDebugSymbolsSection()) {
- Asm = nullptr;
- return;
- }
- // Tell MMI that we have and need debug info.
- MMI->setDebugInfoAvailability(true);
-
- TheCPU = mapArchToCVCPUType(Triple(M->getTargetTriple()).getArch());
-
- collectGlobalVariableInfo();
-
- // Check if we should emit type record hashes.
- ConstantInt *GH =
- mdconst::extract_or_null<ConstantInt>(M->getModuleFlag("CodeViewGHash"));
- EmitDebugGlobalHashes = GH && !GH->isZero();
-}
-
+void CodeViewDebug::beginModule(Module *M) {
+ // If module doesn't have named metadata anchors or COFF debug section
+ // is not available, skip any debug info related stuff.
+ if (!M->getNamedMetadata("llvm.dbg.cu") ||
+ !Asm->getObjFileLowering().getCOFFDebugSymbolsSection()) {
+ Asm = nullptr;
+ return;
+ }
+ // Tell MMI that we have and need debug info.
+ MMI->setDebugInfoAvailability(true);
+
+ TheCPU = mapArchToCVCPUType(Triple(M->getTargetTriple()).getArch());
+
+ collectGlobalVariableInfo();
+
+ // Check if we should emit type record hashes.
+ ConstantInt *GH =
+ mdconst::extract_or_null<ConstantInt>(M->getModuleFlag("CodeViewGHash"));
+ EmitDebugGlobalHashes = GH && !GH->isZero();
+}
+
void CodeViewDebug::endModule() {
if (!Asm || !MMI->hasDebugInfo())
return;
@@ -586,14 +586,14 @@ void CodeViewDebug::endModule() {
if (!P.first->isDeclarationForLinker())
emitDebugInfoForFunction(P.first, *P.second);
- // Get types used by globals without emitting anything.
- // This is meant to collect all static const data members so they can be
- // emitted as globals.
- collectDebugInfoForGlobals();
-
- // Emit retained types.
- emitDebugInfoForRetainedTypes();
-
+ // Get types used by globals without emitting anything.
+ // This is meant to collect all static const data members so they can be
+ // emitted as globals.
+ collectDebugInfoForGlobals();
+
+ // Emit retained types.
+ emitDebugInfoForRetainedTypes();
+
// Emit global variable debug information.
setCurrentSubprogram(nullptr);
emitDebugInfoForGlobals();
@@ -1186,15 +1186,15 @@ void CodeViewDebug::collectVariableInfoFromMFTable(
// Get the frame register used and the offset.
Register FrameReg;
- StackOffset FrameOffset = TFI->getFrameIndexReference(*Asm->MF, VI.Slot, FrameReg);
+ StackOffset FrameOffset = TFI->getFrameIndexReference(*Asm->MF, VI.Slot, FrameReg);
uint16_t CVReg = TRI->getCodeViewRegNum(FrameReg);
- assert(!FrameOffset.getScalable() &&
- "Frame offsets with a scalable component are not supported");
-
+ assert(!FrameOffset.getScalable() &&
+ "Frame offsets with a scalable component are not supported");
+
// Calculate the label ranges.
LocalVarDefRange DefRange =
- createDefRangeMem(CVReg, FrameOffset.getFixed() + ExprOffset);
+ createDefRangeMem(CVReg, FrameOffset.getFixed() + ExprOffset);
for (const InsnRange &Range : Scope->getRanges()) {
const MCSymbol *Begin = getLabelBeforeInsn(Range.first);
@@ -2149,15 +2149,15 @@ void CodeViewDebug::collectMemberInfo(ClassInfo &Info,
const DIDerivedType *DDTy) {
if (!DDTy->getName().empty()) {
Info.Members.push_back({DDTy, 0});
-
- // Collect static const data members with values.
- if ((DDTy->getFlags() & DINode::FlagStaticMember) ==
- DINode::FlagStaticMember) {
- if (DDTy->getConstant() && (isa<ConstantInt>(DDTy->getConstant()) ||
- isa<ConstantFP>(DDTy->getConstant())))
- StaticConstMembers.push_back(DDTy);
- }
-
+
+ // Collect static const data members with values.
+ if ((DDTy->getFlags() & DINode::FlagStaticMember) ==
+ DINode::FlagStaticMember) {
+ if (DDTy->getConstant() && (isa<ConstantInt>(DDTy->getConstant()) ||
+ isa<ConstantFP>(DDTy->getConstant())))
+ StaticConstMembers.push_back(DDTy);
+ }
+
return;
}
@@ -3060,32 +3060,32 @@ void CodeViewDebug::collectGlobalVariableInfo() {
}
}
-void CodeViewDebug::collectDebugInfoForGlobals() {
- for (const CVGlobalVariable &CVGV : GlobalVariables) {
- const DIGlobalVariable *DIGV = CVGV.DIGV;
- const DIScope *Scope = DIGV->getScope();
- getCompleteTypeIndex(DIGV->getType());
- getFullyQualifiedName(Scope, DIGV->getName());
- }
-
- for (const CVGlobalVariable &CVGV : ComdatVariables) {
- const DIGlobalVariable *DIGV = CVGV.DIGV;
- const DIScope *Scope = DIGV->getScope();
- getCompleteTypeIndex(DIGV->getType());
- getFullyQualifiedName(Scope, DIGV->getName());
- }
-}
-
+void CodeViewDebug::collectDebugInfoForGlobals() {
+ for (const CVGlobalVariable &CVGV : GlobalVariables) {
+ const DIGlobalVariable *DIGV = CVGV.DIGV;
+ const DIScope *Scope = DIGV->getScope();
+ getCompleteTypeIndex(DIGV->getType());
+ getFullyQualifiedName(Scope, DIGV->getName());
+ }
+
+ for (const CVGlobalVariable &CVGV : ComdatVariables) {
+ const DIGlobalVariable *DIGV = CVGV.DIGV;
+ const DIScope *Scope = DIGV->getScope();
+ getCompleteTypeIndex(DIGV->getType());
+ getFullyQualifiedName(Scope, DIGV->getName());
+ }
+}
+
void CodeViewDebug::emitDebugInfoForGlobals() {
// First, emit all globals that are not in a comdat in a single symbol
// substream. MSVC doesn't like it if the substream is empty, so only open
// it if we have at least one global to emit.
switchToDebugSectionForSymbol(nullptr);
- if (!GlobalVariables.empty() || !StaticConstMembers.empty()) {
+ if (!GlobalVariables.empty() || !StaticConstMembers.empty()) {
OS.AddComment("Symbol subsection for globals");
MCSymbol *EndLabel = beginCVSubsection(DebugSubsectionKind::Symbols);
emitGlobalVariableList(GlobalVariables);
- emitStaticConstMemberList();
+ emitStaticConstMemberList();
endCVSubsection(EndLabel);
}
@@ -3124,61 +3124,61 @@ void CodeViewDebug::emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals) {
}
}
-void CodeViewDebug::emitStaticConstMemberList() {
- for (const DIDerivedType *DTy : StaticConstMembers) {
- const DIScope *Scope = DTy->getScope();
-
- APSInt Value;
- if (const ConstantInt *CI =
- dyn_cast_or_null<ConstantInt>(DTy->getConstant()))
- Value = APSInt(CI->getValue(),
- DebugHandlerBase::isUnsignedDIType(DTy->getBaseType()));
- else if (const ConstantFP *CFP =
- dyn_cast_or_null<ConstantFP>(DTy->getConstant()))
- Value = APSInt(CFP->getValueAPF().bitcastToAPInt(), true);
- else
- llvm_unreachable("cannot emit a constant without a value");
-
- std::string QualifiedName = getFullyQualifiedName(Scope, DTy->getName());
-
- MCSymbol *SConstantEnd = beginSymbolRecord(SymbolKind::S_CONSTANT);
- OS.AddComment("Type");
- OS.emitInt32(getTypeIndex(DTy->getBaseType()).getIndex());
- OS.AddComment("Value");
-
- // Encoded integers shouldn't need more than 10 bytes.
- uint8_t Data[10];
- BinaryStreamWriter Writer(Data, llvm::support::endianness::little);
- CodeViewRecordIO IO(Writer);
- cantFail(IO.mapEncodedInteger(Value));
- StringRef SRef((char *)Data, Writer.getOffset());
- OS.emitBinaryData(SRef);
-
- OS.AddComment("Name");
- emitNullTerminatedSymbolName(OS, QualifiedName);
- endSymbolRecord(SConstantEnd);
- }
-}
-
-static bool isFloatDIType(const DIType *Ty) {
- if (isa<DICompositeType>(Ty))
- return false;
-
- if (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
- dwarf::Tag T = (dwarf::Tag)Ty->getTag();
- if (T == dwarf::DW_TAG_pointer_type ||
- T == dwarf::DW_TAG_ptr_to_member_type ||
- T == dwarf::DW_TAG_reference_type ||
- T == dwarf::DW_TAG_rvalue_reference_type)
- return false;
- assert(DTy->getBaseType() && "Expected valid base type");
- return isFloatDIType(DTy->getBaseType());
- }
-
- auto *BTy = cast<DIBasicType>(Ty);
- return (BTy->getEncoding() == dwarf::DW_ATE_float);
-}
-
+void CodeViewDebug::emitStaticConstMemberList() {
+ for (const DIDerivedType *DTy : StaticConstMembers) {
+ const DIScope *Scope = DTy->getScope();
+
+ APSInt Value;
+ if (const ConstantInt *CI =
+ dyn_cast_or_null<ConstantInt>(DTy->getConstant()))
+ Value = APSInt(CI->getValue(),
+ DebugHandlerBase::isUnsignedDIType(DTy->getBaseType()));
+ else if (const ConstantFP *CFP =
+ dyn_cast_or_null<ConstantFP>(DTy->getConstant()))
+ Value = APSInt(CFP->getValueAPF().bitcastToAPInt(), true);
+ else
+ llvm_unreachable("cannot emit a constant without a value");
+
+ std::string QualifiedName = getFullyQualifiedName(Scope, DTy->getName());
+
+ MCSymbol *SConstantEnd = beginSymbolRecord(SymbolKind::S_CONSTANT);
+ OS.AddComment("Type");
+ OS.emitInt32(getTypeIndex(DTy->getBaseType()).getIndex());
+ OS.AddComment("Value");
+
+ // Encoded integers shouldn't need more than 10 bytes.
+ uint8_t Data[10];
+ BinaryStreamWriter Writer(Data, llvm::support::endianness::little);
+ CodeViewRecordIO IO(Writer);
+ cantFail(IO.mapEncodedInteger(Value));
+ StringRef SRef((char *)Data, Writer.getOffset());
+ OS.emitBinaryData(SRef);
+
+ OS.AddComment("Name");
+ emitNullTerminatedSymbolName(OS, QualifiedName);
+ endSymbolRecord(SConstantEnd);
+ }
+}
+
+static bool isFloatDIType(const DIType *Ty) {
+ if (isa<DICompositeType>(Ty))
+ return false;
+
+ if (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
+ dwarf::Tag T = (dwarf::Tag)Ty->getTag();
+ if (T == dwarf::DW_TAG_pointer_type ||
+ T == dwarf::DW_TAG_ptr_to_member_type ||
+ T == dwarf::DW_TAG_reference_type ||
+ T == dwarf::DW_TAG_rvalue_reference_type)
+ return false;
+ assert(DTy->getBaseType() && "Expected valid base type");
+ return isFloatDIType(DTy->getBaseType());
+ }
+
+ auto *BTy = cast<DIBasicType>(Ty);
+ return (BTy->getEncoding() == dwarf::DW_ATE_float);
+}
+
void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) {
const DIGlobalVariable *DIGV = CVGV.DIGV;
@@ -3215,12 +3215,12 @@ void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) {
assert(DIE->isConstant() &&
"Global constant variables must contain a constant expression.");
- // Use unsigned for floats.
- bool isUnsigned = isFloatDIType(DIGV->getType())
- ? true
- : DebugHandlerBase::isUnsignedDIType(DIGV->getType());
- APSInt Value(APInt(/*BitWidth=*/64, DIE->getElement(1)), isUnsigned);
-
+ // Use unsigned for floats.
+ bool isUnsigned = isFloatDIType(DIGV->getType())
+ ? true
+ : DebugHandlerBase::isUnsignedDIType(DIGV->getType());
+ APSInt Value(APInt(/*BitWidth=*/64, DIE->getElement(1)), isUnsigned);
+
MCSymbol *SConstantEnd = beginSymbolRecord(SymbolKind::S_CONSTANT);
OS.AddComment("Type");
OS.emitInt32(getTypeIndex(DIGV->getType()).getIndex());
@@ -3230,7 +3230,7 @@ void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) {
uint8_t data[10];
BinaryStreamWriter Writer(data, llvm::support::endianness::little);
CodeViewRecordIO IO(Writer);
- cantFail(IO.mapEncodedInteger(Value));
+ cantFail(IO.mapEncodedInteger(Value));
StringRef SRef((char *)data, Writer.getOffset());
OS.emitBinaryData(SRef);
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/CodeViewDebug.h
index 4dd58dbb42..9eee5492bc 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -203,9 +203,9 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
// Array of non-COMDAT global variables.
SmallVector<CVGlobalVariable, 1> GlobalVariables;
- /// List of static const data members to be emitted as S_CONSTANTs.
- SmallVector<const DIDerivedType *, 4> StaticConstMembers;
-
+ /// List of static const data members to be emitted as S_CONSTANTs.
+ SmallVector<const DIDerivedType *, 4> StaticConstMembers;
+
/// The set of comdat .debug$S sections that we've seen so far. Each section
/// must start with a magic version number that must only be emitted once.
/// This set tracks which sections we've already opened.
@@ -312,11 +312,11 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
void emitDebugInfoForUDTs(
const std::vector<std::pair<std::string, const DIType *>> &UDTs);
- void collectDebugInfoForGlobals();
+ void collectDebugInfoForGlobals();
void emitDebugInfoForGlobals();
void emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals);
void emitDebugInfoForGlobal(const CVGlobalVariable &CVGV);
- void emitStaticConstMemberList();
+ void emitStaticConstMemberList();
/// Opens a subsection of the given kind in a .debug$S codeview section.
/// Returns an end label for use with endCVSubsection when the subsection is
@@ -465,8 +465,8 @@ protected:
public:
CodeViewDebug(AsmPrinter *AP);
- void beginModule(Module *M) override;
-
+ void beginModule(Module *M) override;
+
void setSymbolSize(const MCSymbol *, uint64_t) override {}
/// Emit the COFF section that holds the line table information.
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DIE.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DIE.cpp
index 651797b728..39b0b027c7 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -194,7 +194,7 @@ DIEAbbrev DIE::generateAbbrev() const {
return Abbrev;
}
-uint64_t DIE::getDebugSectionOffset() const {
+uint64_t DIE::getDebugSectionOffset() const {
const DIEUnit *Unit = getUnit();
assert(Unit && "DIE must be owned by a DIEUnit to get its absolute offset");
return Unit->getDebugSectionOffset() + getOffset();
@@ -313,8 +313,8 @@ unsigned DIE::computeOffsetsAndAbbrevs(const AsmPrinter *AP,
//===----------------------------------------------------------------------===//
// DIEUnit Implementation
//===----------------------------------------------------------------------===//
-DIEUnit::DIEUnit(dwarf::Tag UnitTag)
- : Die(UnitTag), Section(nullptr), Offset(0) {
+DIEUnit::DIEUnit(dwarf::Tag UnitTag)
+ : Die(UnitTag), Section(nullptr), Offset(0) {
Die.Owner = this;
assert((UnitTag == dwarf::DW_TAG_compile_unit ||
UnitTag == dwarf::DW_TAG_skeleton_unit ||
@@ -428,10 +428,10 @@ void DIEInteger::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
/// SizeOf - Determine size of integer value in bytes.
///
unsigned DIEInteger::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
- assert(AP && "AsmPrinter is required to set FormParams");
- dwarf::FormParams Params = {AP->getDwarfVersion(),
- uint8_t(AP->getPointerSize()),
- AP->OutStreamer->getContext().getDwarfFormat()};
+ assert(AP && "AsmPrinter is required to set FormParams");
+ dwarf::FormParams Params = {AP->getDwarfVersion(),
+ uint8_t(AP->getPointerSize()),
+ AP->OutStreamer->getContext().getDwarfFormat()};
if (Optional<uint8_t> FixedSize = dwarf::getFixedFormByteSize(Form, Params))
return *FixedSize;
@@ -470,16 +470,16 @@ void DIEExpr::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
/// SizeOf - Determine size of expression value in bytes.
///
unsigned DIEExpr::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
- switch (Form) {
- case dwarf::DW_FORM_data4:
- return 4;
- case dwarf::DW_FORM_data8:
- return 8;
- case dwarf::DW_FORM_sec_offset:
- return AP->getDwarfOffsetByteSize();
- default:
- llvm_unreachable("DIE Value form not supported yet");
- }
+ switch (Form) {
+ case dwarf::DW_FORM_data4:
+ return 4;
+ case dwarf::DW_FORM_data8:
+ return 8;
+ case dwarf::DW_FORM_sec_offset:
+ return AP->getDwarfOffsetByteSize();
+ default:
+ llvm_unreachable("DIE Value form not supported yet");
+ }
}
LLVM_DUMP_METHOD
@@ -492,26 +492,26 @@ void DIEExpr::print(raw_ostream &O) const { O << "Expr: " << *Expr; }
/// EmitValue - Emit label value.
///
void DIELabel::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
- bool IsSectionRelative = Form != dwarf::DW_FORM_addr;
- AP->emitLabelReference(Label, SizeOf(AP, Form), IsSectionRelative);
+ bool IsSectionRelative = Form != dwarf::DW_FORM_addr;
+ AP->emitLabelReference(Label, SizeOf(AP, Form), IsSectionRelative);
}
/// SizeOf - Determine size of label value in bytes.
///
unsigned DIELabel::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
- switch (Form) {
- case dwarf::DW_FORM_data4:
- return 4;
- case dwarf::DW_FORM_data8:
- return 8;
- case dwarf::DW_FORM_sec_offset:
- case dwarf::DW_FORM_strp:
- return AP->getDwarfOffsetByteSize();
- case dwarf::DW_FORM_addr:
- return AP->MAI->getCodePointerSize();
- default:
- llvm_unreachable("DIE Value form not supported yet");
- }
+ switch (Form) {
+ case dwarf::DW_FORM_data4:
+ return 4;
+ case dwarf::DW_FORM_data8:
+ return 8;
+ case dwarf::DW_FORM_sec_offset:
+ case dwarf::DW_FORM_strp:
+ return AP->getDwarfOffsetByteSize();
+ case dwarf::DW_FORM_addr:
+ return AP->MAI->getCodePointerSize();
+ default:
+ llvm_unreachable("DIE Value form not supported yet");
+ }
}
LLVM_DUMP_METHOD
@@ -547,16 +547,16 @@ void DIEDelta::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
/// SizeOf - Determine size of delta value in bytes.
///
unsigned DIEDelta::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
- switch (Form) {
- case dwarf::DW_FORM_data4:
- return 4;
- case dwarf::DW_FORM_data8:
- return 8;
- case dwarf::DW_FORM_sec_offset:
- return AP->getDwarfOffsetByteSize();
- default:
- llvm_unreachable("DIE Value form not supported yet");
- }
+ switch (Form) {
+ case dwarf::DW_FORM_data4:
+ return 4;
+ case dwarf::DW_FORM_data8:
+ return 8;
+ case dwarf::DW_FORM_sec_offset:
+ return AP->getDwarfOffsetByteSize();
+ default:
+ llvm_unreachable("DIE Value form not supported yet");
+ }
}
LLVM_DUMP_METHOD
@@ -662,7 +662,7 @@ void DIEEntry::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
case dwarf::DW_FORM_ref_addr: {
// Get the absolute offset for this DIE within the debug info/types section.
- uint64_t Addr = Entry->getDebugSectionOffset();
+ uint64_t Addr = Entry->getDebugSectionOffset();
if (const MCSymbol *SectionSym =
Entry->getUnit()->getCrossSectionRelativeBaseAddress()) {
AP->emitLabelPlusOffset(SectionSym, Addr, SizeOf(AP, Form), true);
@@ -819,24 +819,24 @@ void DIEBlock::print(raw_ostream &O) const {
//===----------------------------------------------------------------------===//
unsigned DIELocList::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
- switch (Form) {
- case dwarf::DW_FORM_loclistx:
+ switch (Form) {
+ case dwarf::DW_FORM_loclistx:
return getULEB128Size(Index);
- case dwarf::DW_FORM_data4:
- assert(!AP->isDwarf64() &&
- "DW_FORM_data4 is not suitable to emit a pointer to a location list "
- "in the 64-bit DWARF format");
+ case dwarf::DW_FORM_data4:
+ assert(!AP->isDwarf64() &&
+ "DW_FORM_data4 is not suitable to emit a pointer to a location list "
+ "in the 64-bit DWARF format");
return 4;
- case dwarf::DW_FORM_data8:
- assert(AP->isDwarf64() &&
- "DW_FORM_data8 is not suitable to emit a pointer to a location list "
- "in the 32-bit DWARF format");
- return 8;
- case dwarf::DW_FORM_sec_offset:
- return AP->getDwarfOffsetByteSize();
- default:
- llvm_unreachable("DIE Value form not supported yet");
- }
+ case dwarf::DW_FORM_data8:
+ assert(AP->isDwarf64() &&
+ "DW_FORM_data8 is not suitable to emit a pointer to a location list "
+ "in the 32-bit DWARF format");
+ return 8;
+ case dwarf::DW_FORM_sec_offset:
+ return AP->getDwarfOffsetByteSize();
+ default:
+ llvm_unreachable("DIE Value form not supported yet");
+ }
}
/// EmitValue - Emit label value.
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DIEHash.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DIEHash.cpp
index 01c5c4a01d..da9997efc0 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DIEHash.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DIEHash.cpp
@@ -12,7 +12,7 @@
#include "DIEHash.h"
#include "ByteStreamer.h"
-#include "DwarfCompileUnit.h"
+#include "DwarfCompileUnit.h"
#include "DwarfDebug.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
@@ -215,15 +215,15 @@ void DIEHash::hashDIEEntry(dwarf::Attribute Attribute, dwarf::Tag Tag,
// all of the data is going to be added as integers.
void DIEHash::hashBlockData(const DIE::const_value_range &Values) {
for (const auto &V : Values)
- if (V.getType() == DIEValue::isBaseTypeRef) {
- const DIE &C =
- *CU->ExprRefedBaseTypes[V.getDIEBaseTypeRef().getIndex()].Die;
- StringRef Name = getDIEStringAttr(C, dwarf::DW_AT_name);
- assert(!Name.empty() &&
- "Base types referenced from DW_OP_convert should have a name");
- hashNestedType(C, Name);
- } else
- Hash.update((uint64_t)V.getDIEInteger().getValue());
+ if (V.getType() == DIEValue::isBaseTypeRef) {
+ const DIE &C =
+ *CU->ExprRefedBaseTypes[V.getDIEBaseTypeRef().getIndex()].Die;
+ StringRef Name = getDIEStringAttr(C, dwarf::DW_AT_name);
+ assert(!Name.empty() &&
+ "Base types referenced from DW_OP_convert should have a name");
+ hashNestedType(C, Name);
+ } else
+ Hash.update((uint64_t)V.getDIEInteger().getValue());
}
// Hash the contents of a loclistptr class.
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DIEHash.h b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DIEHash.h
index 0a1ab02ee7..29e1da4c5d 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DIEHash.h
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DIEHash.h
@@ -31,8 +31,8 @@ class DIEHash {
};
public:
- DIEHash(AsmPrinter *A = nullptr, DwarfCompileUnit *CU = nullptr)
- : AP(A), CU(CU) {}
+ DIEHash(AsmPrinter *A = nullptr, DwarfCompileUnit *CU = nullptr)
+ : AP(A), CU(CU) {}
/// Computes the CU signature.
uint64_t computeCUSignature(StringRef DWOName, const DIE &Die);
@@ -102,7 +102,7 @@ private:
private:
MD5 Hash;
AsmPrinter *AP;
- DwarfCompileUnit *CU;
+ DwarfCompileUnit *CU;
DenseMap<const DIE *, unsigned> Numbering;
};
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
index 6139139e36..1c9131edab 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
@@ -8,11 +8,11 @@
#include "llvm/CodeGen/DbgEntityHistoryCalculator.h"
#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/LexicalScopes.h"
+#include "llvm/CodeGen/LexicalScopes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
@@ -53,37 +53,37 @@ static Register isDescribedByReg(const MachineInstr &MI) {
: Register();
}
-void InstructionOrdering::initialize(const MachineFunction &MF) {
- // We give meta instructions the same ordinal as the preceding instruction
- // because this class is written for the task of comparing positions of
- // variable location ranges against scope ranges. To reflect what we'll see
- // in the binary, when we look at location ranges we must consider all
- // DBG_VALUEs between two real instructions at the same position. And a
- // scope range which ends on a meta instruction should be considered to end
- // at the last seen real instruction. E.g.
- //
- // 1 instruction p Both the variable location for x and for y start
- // 1 DBG_VALUE for "x" after instruction p so we give them all the same
- // 1 DBG_VALUE for "y" number. If a scope range ends at DBG_VALUE for "y",
- // 2 instruction q we should treat it as ending after instruction p
- // because it will be the last real instruction in the
- // range. DBG_VALUEs at or after this position for
- // variables declared in the scope will have no effect.
- clear();
- unsigned Position = 0;
- for (const MachineBasicBlock &MBB : MF)
- for (const MachineInstr &MI : MBB)
- InstNumberMap[&MI] = MI.isMetaInstruction() ? Position : ++Position;
-}
-
-bool InstructionOrdering::isBefore(const MachineInstr *A,
- const MachineInstr *B) const {
- assert(A->getParent() && B->getParent() && "Operands must have a parent");
- assert(A->getMF() == B->getMF() &&
- "Operands must be in the same MachineFunction");
- return InstNumberMap.lookup(A) < InstNumberMap.lookup(B);
-}
-
+void InstructionOrdering::initialize(const MachineFunction &MF) {
+ // We give meta instructions the same ordinal as the preceding instruction
+ // because this class is written for the task of comparing positions of
+ // variable location ranges against scope ranges. To reflect what we'll see
+ // in the binary, when we look at location ranges we must consider all
+ // DBG_VALUEs between two real instructions at the same position. And a
+ // scope range which ends on a meta instruction should be considered to end
+ // at the last seen real instruction. E.g.
+ //
+ // 1 instruction p Both the variable location for x and for y start
+ // 1 DBG_VALUE for "x" after instruction p so we give them all the same
+ // 1 DBG_VALUE for "y" number. If a scope range ends at DBG_VALUE for "y",
+ // 2 instruction q we should treat it as ending after instruction p
+ // because it will be the last real instruction in the
+ // range. DBG_VALUEs at or after this position for
+ // variables declared in the scope will have no effect.
+ clear();
+ unsigned Position = 0;
+ for (const MachineBasicBlock &MBB : MF)
+ for (const MachineInstr &MI : MBB)
+ InstNumberMap[&MI] = MI.isMetaInstruction() ? Position : ++Position;
+}
+
+bool InstructionOrdering::isBefore(const MachineInstr *A,
+ const MachineInstr *B) const {
+ assert(A->getParent() && B->getParent() && "Operands must have a parent");
+ assert(A->getMF() == B->getMF() &&
+ "Operands must be in the same MachineFunction");
+ return InstNumberMap.lookup(A) < InstNumberMap.lookup(B);
+}
+
bool DbgValueHistoryMap::startDbgValue(InlinedEntity Var,
const MachineInstr &MI,
EntryIndex &NewIndex) {
@@ -123,156 +123,156 @@ void DbgValueHistoryMap::Entry::endEntry(EntryIndex Index) {
EndIndex = Index;
}
-/// Check if the instruction range [StartMI, EndMI] intersects any instruction
-/// range in Ranges. EndMI can be nullptr to indicate that the range is
-/// unbounded. Assumes Ranges is ordered and disjoint. Returns true and points
-/// to the first intersecting scope range if one exists.
-static Optional<ArrayRef<InsnRange>::iterator>
-intersects(const MachineInstr *StartMI, const MachineInstr *EndMI,
- const ArrayRef<InsnRange> &Ranges,
- const InstructionOrdering &Ordering) {
- for (auto RangesI = Ranges.begin(), RangesE = Ranges.end();
- RangesI != RangesE; ++RangesI) {
- if (EndMI && Ordering.isBefore(EndMI, RangesI->first))
- return None;
- if (EndMI && !Ordering.isBefore(RangesI->second, EndMI))
- return RangesI;
- if (Ordering.isBefore(StartMI, RangesI->second))
- return RangesI;
- }
- return None;
-}
-
-void DbgValueHistoryMap::trimLocationRanges(
- const MachineFunction &MF, LexicalScopes &LScopes,
- const InstructionOrdering &Ordering) {
- // The indices of the entries we're going to remove for each variable.
- SmallVector<EntryIndex, 4> ToRemove;
- // Entry reference count for each variable. Clobbers left with no references
- // will be removed.
- SmallVector<int, 4> ReferenceCount;
- // Entries reference other entries by index. Offsets is used to remap these
- // references if any entries are removed.
- SmallVector<size_t, 4> Offsets;
-
- for (auto &Record : VarEntries) {
- auto &HistoryMapEntries = Record.second;
- if (HistoryMapEntries.empty())
- continue;
-
- InlinedEntity Entity = Record.first;
- const DILocalVariable *LocalVar = cast<DILocalVariable>(Entity.first);
-
- LexicalScope *Scope = nullptr;
- if (const DILocation *InlinedAt = Entity.second) {
- Scope = LScopes.findInlinedScope(LocalVar->getScope(), InlinedAt);
- } else {
- Scope = LScopes.findLexicalScope(LocalVar->getScope());
- // Ignore variables for non-inlined function level scopes. The scope
- // ranges (from scope->getRanges()) will not include any instructions
- // before the first one with a debug-location, which could cause us to
- // incorrectly drop a location. We could introduce special casing for
- // these variables, but it doesn't seem worth it because no out-of-scope
- // locations have been observed for variables declared in function level
- // scopes.
- if (Scope &&
- (Scope->getScopeNode() == Scope->getScopeNode()->getSubprogram()) &&
- (Scope->getScopeNode() == LocalVar->getScope()))
- continue;
- }
-
- // If there is no scope for the variable then something has probably gone
- // wrong.
- if (!Scope)
- continue;
-
- ToRemove.clear();
- // Zero the reference counts.
- ReferenceCount.assign(HistoryMapEntries.size(), 0);
- // Index of the DBG_VALUE which marks the start of the current location
- // range.
- EntryIndex StartIndex = 0;
- ArrayRef<InsnRange> ScopeRanges(Scope->getRanges());
- for (auto EI = HistoryMapEntries.begin(), EE = HistoryMapEntries.end();
- EI != EE; ++EI, ++StartIndex) {
- // Only DBG_VALUEs can open location ranges so skip anything else.
- if (!EI->isDbgValue())
- continue;
-
- // Index of the entry which closes this range.
- EntryIndex EndIndex = EI->getEndIndex();
- // If this range is closed bump the reference count of the closing entry.
- if (EndIndex != NoEntry)
- ReferenceCount[EndIndex] += 1;
- // Skip this location range if the opening entry is still referenced. It
- // may close a location range which intersects a scope range.
- // TODO: We could be 'smarter' and trim these kinds of ranges such that
- // they do not leak out of the scope ranges if they partially overlap.
- if (ReferenceCount[StartIndex] > 0)
- continue;
-
- const MachineInstr *StartMI = EI->getInstr();
- const MachineInstr *EndMI = EndIndex != NoEntry
- ? HistoryMapEntries[EndIndex].getInstr()
- : nullptr;
- // Check if the location range [StartMI, EndMI] intersects with any scope
- // range for the variable.
- if (auto R = intersects(StartMI, EndMI, ScopeRanges, Ordering)) {
- // Adjust ScopeRanges to exclude ranges which subsequent location ranges
- // cannot possibly intersect.
- ScopeRanges = ArrayRef<InsnRange>(R.getValue(), ScopeRanges.end());
- } else {
- // If the location range does not intersect any scope range then the
- // DBG_VALUE which opened this location range is usless, mark it for
- // removal.
- ToRemove.push_back(StartIndex);
- // Because we'll be removing this entry we need to update the reference
- // count of the closing entry, if one exists.
- if (EndIndex != NoEntry)
- ReferenceCount[EndIndex] -= 1;
- }
- }
-
- // If there is nothing to remove then jump to next variable.
- if (ToRemove.empty())
- continue;
-
- // Mark clobbers that will no longer close any location ranges for removal.
- for (size_t i = 0; i < HistoryMapEntries.size(); ++i)
- if (ReferenceCount[i] <= 0 && HistoryMapEntries[i].isClobber())
- ToRemove.push_back(i);
-
- llvm::sort(ToRemove);
-
- // Build an offset map so we can update the EndIndex of the remaining
- // entries.
- // Zero the offsets.
- Offsets.assign(HistoryMapEntries.size(), 0);
- size_t CurOffset = 0;
- auto ToRemoveItr = ToRemove.begin();
- for (size_t EntryIdx = *ToRemoveItr; EntryIdx < HistoryMapEntries.size();
- ++EntryIdx) {
- // Check if this is an entry which will be removed.
- if (ToRemoveItr != ToRemove.end() && *ToRemoveItr == EntryIdx) {
- ++ToRemoveItr;
- ++CurOffset;
- }
- Offsets[EntryIdx] = CurOffset;
- }
-
- // Update the EndIndex of the entries to account for those which will be
- // removed.
- for (auto &Entry : HistoryMapEntries)
- if (Entry.isClosed())
- Entry.EndIndex -= Offsets[Entry.EndIndex];
-
- // Now actually remove the entries. Iterate backwards so that our remaining
- // ToRemove indices are valid after each erase.
- for (auto Itr = ToRemove.rbegin(), End = ToRemove.rend(); Itr != End; ++Itr)
- HistoryMapEntries.erase(HistoryMapEntries.begin() + *Itr);
- }
-}
-
+/// Check if the instruction range [StartMI, EndMI] intersects any instruction
+/// range in Ranges. EndMI can be nullptr to indicate that the range is
+/// unbounded. Assumes Ranges is ordered and disjoint. Returns true and points
+/// to the first intersecting scope range if one exists.
+static Optional<ArrayRef<InsnRange>::iterator>
+intersects(const MachineInstr *StartMI, const MachineInstr *EndMI,
+ const ArrayRef<InsnRange> &Ranges,
+ const InstructionOrdering &Ordering) {
+ for (auto RangesI = Ranges.begin(), RangesE = Ranges.end();
+ RangesI != RangesE; ++RangesI) {
+ if (EndMI && Ordering.isBefore(EndMI, RangesI->first))
+ return None;
+ if (EndMI && !Ordering.isBefore(RangesI->second, EndMI))
+ return RangesI;
+ if (Ordering.isBefore(StartMI, RangesI->second))
+ return RangesI;
+ }
+ return None;
+}
+
+void DbgValueHistoryMap::trimLocationRanges(
+ const MachineFunction &MF, LexicalScopes &LScopes,
+ const InstructionOrdering &Ordering) {
+ // The indices of the entries we're going to remove for each variable.
+ SmallVector<EntryIndex, 4> ToRemove;
+ // Entry reference count for each variable. Clobbers left with no references
+ // will be removed.
+ SmallVector<int, 4> ReferenceCount;
+ // Entries reference other entries by index. Offsets is used to remap these
+ // references if any entries are removed.
+ SmallVector<size_t, 4> Offsets;
+
+ for (auto &Record : VarEntries) {
+ auto &HistoryMapEntries = Record.second;
+ if (HistoryMapEntries.empty())
+ continue;
+
+ InlinedEntity Entity = Record.first;
+ const DILocalVariable *LocalVar = cast<DILocalVariable>(Entity.first);
+
+ LexicalScope *Scope = nullptr;
+ if (const DILocation *InlinedAt = Entity.second) {
+ Scope = LScopes.findInlinedScope(LocalVar->getScope(), InlinedAt);
+ } else {
+ Scope = LScopes.findLexicalScope(LocalVar->getScope());
+ // Ignore variables for non-inlined function level scopes. The scope
+ // ranges (from scope->getRanges()) will not include any instructions
+ // before the first one with a debug-location, which could cause us to
+ // incorrectly drop a location. We could introduce special casing for
+ // these variables, but it doesn't seem worth it because no out-of-scope
+ // locations have been observed for variables declared in function level
+ // scopes.
+ if (Scope &&
+ (Scope->getScopeNode() == Scope->getScopeNode()->getSubprogram()) &&
+ (Scope->getScopeNode() == LocalVar->getScope()))
+ continue;
+ }
+
+ // If there is no scope for the variable then something has probably gone
+ // wrong.
+ if (!Scope)
+ continue;
+
+ ToRemove.clear();
+ // Zero the reference counts.
+ ReferenceCount.assign(HistoryMapEntries.size(), 0);
+ // Index of the DBG_VALUE which marks the start of the current location
+ // range.
+ EntryIndex StartIndex = 0;
+ ArrayRef<InsnRange> ScopeRanges(Scope->getRanges());
+ for (auto EI = HistoryMapEntries.begin(), EE = HistoryMapEntries.end();
+ EI != EE; ++EI, ++StartIndex) {
+ // Only DBG_VALUEs can open location ranges so skip anything else.
+ if (!EI->isDbgValue())
+ continue;
+
+ // Index of the entry which closes this range.
+ EntryIndex EndIndex = EI->getEndIndex();
+ // If this range is closed bump the reference count of the closing entry.
+ if (EndIndex != NoEntry)
+ ReferenceCount[EndIndex] += 1;
+ // Skip this location range if the opening entry is still referenced. It
+ // may close a location range which intersects a scope range.
+ // TODO: We could be 'smarter' and trim these kinds of ranges such that
+ // they do not leak out of the scope ranges if they partially overlap.
+ if (ReferenceCount[StartIndex] > 0)
+ continue;
+
+ const MachineInstr *StartMI = EI->getInstr();
+ const MachineInstr *EndMI = EndIndex != NoEntry
+ ? HistoryMapEntries[EndIndex].getInstr()
+ : nullptr;
+ // Check if the location range [StartMI, EndMI] intersects with any scope
+ // range for the variable.
+ if (auto R = intersects(StartMI, EndMI, ScopeRanges, Ordering)) {
+ // Adjust ScopeRanges to exclude ranges which subsequent location ranges
+ // cannot possibly intersect.
+ ScopeRanges = ArrayRef<InsnRange>(R.getValue(), ScopeRanges.end());
+ } else {
+ // If the location range does not intersect any scope range then the
+ // DBG_VALUE which opened this location range is usless, mark it for
+ // removal.
+ ToRemove.push_back(StartIndex);
+ // Because we'll be removing this entry we need to update the reference
+ // count of the closing entry, if one exists.
+ if (EndIndex != NoEntry)
+ ReferenceCount[EndIndex] -= 1;
+ }
+ }
+
+ // If there is nothing to remove then jump to next variable.
+ if (ToRemove.empty())
+ continue;
+
+ // Mark clobbers that will no longer close any location ranges for removal.
+ for (size_t i = 0; i < HistoryMapEntries.size(); ++i)
+ if (ReferenceCount[i] <= 0 && HistoryMapEntries[i].isClobber())
+ ToRemove.push_back(i);
+
+ llvm::sort(ToRemove);
+
+ // Build an offset map so we can update the EndIndex of the remaining
+ // entries.
+ // Zero the offsets.
+ Offsets.assign(HistoryMapEntries.size(), 0);
+ size_t CurOffset = 0;
+ auto ToRemoveItr = ToRemove.begin();
+ for (size_t EntryIdx = *ToRemoveItr; EntryIdx < HistoryMapEntries.size();
+ ++EntryIdx) {
+ // Check if this is an entry which will be removed.
+ if (ToRemoveItr != ToRemove.end() && *ToRemoveItr == EntryIdx) {
+ ++ToRemoveItr;
+ ++CurOffset;
+ }
+ Offsets[EntryIdx] = CurOffset;
+ }
+
+ // Update the EndIndex of the entries to account for those which will be
+ // removed.
+ for (auto &Entry : HistoryMapEntries)
+ if (Entry.isClosed())
+ Entry.EndIndex -= Offsets[Entry.EndIndex];
+
+ // Now actually remove the entries. Iterate backwards so that our remaining
+ // ToRemove indices are valid after each erase.
+ for (auto Itr = ToRemove.rbegin(), End = ToRemove.rend(); Itr != End; ++Itr)
+ HistoryMapEntries.erase(HistoryMapEntries.begin() + *Itr);
+ }
+}
+
void DbgLabelInstrMap::addInstr(InlinedEntity Label, const MachineInstr &MI) {
assert(MI.isDebugLabel() && "not a DBG_LABEL");
LabelInstr[Label] = &MI;
@@ -417,7 +417,7 @@ void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
DbgValueHistoryMap &DbgValues,
DbgLabelInstrMap &DbgLabels) {
const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();
- Register SP = TLI->getStackPointerRegisterToSaveRestore();
+ Register SP = TLI->getStackPointerRegisterToSaveRestore();
Register FrameReg = TRI->getFrameRegister(*MF);
RegDescribedVarsMap RegVars;
DbgValueEntriesMap LiveEntries;
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
index 01bcdd9be2..68a4bfba42 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
@@ -21,16 +21,16 @@
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/MC/MCStreamer.h"
-#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/CommandLine.h"
using namespace llvm;
#define DEBUG_TYPE "dwarfdebug"
-/// If true, we drop variable location ranges which exist entirely outside the
-/// variable's lexical scope instruction ranges.
-static cl::opt<bool> TrimVarLocs("trim-var-locs", cl::Hidden, cl::init(true));
-
+/// If true, we drop variable location ranges which exist entirely outside the
+/// variable's lexical scope instruction ranges.
+static cl::opt<bool> TrimVarLocs("trim-var-locs", cl::Hidden, cl::init(true));
+
Optional<DbgVariableLocation>
DbgVariableLocation::extractFromMachineInstruction(
const MachineInstr &Instruction) {
@@ -91,11 +91,11 @@ DbgVariableLocation::extractFromMachineInstruction(
DebugHandlerBase::DebugHandlerBase(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {}
-void DebugHandlerBase::beginModule(Module *M) {
- if (M->debug_compile_units().empty())
- Asm = nullptr;
-}
-
+void DebugHandlerBase::beginModule(Module *M) {
+ if (M->debug_compile_units().empty())
+ Asm = nullptr;
+}
+
// Each LexicalScope has first instruction and last instruction to mark
// beginning and end of a scope respectively. Create an inverse map that list
// scopes starts (and ends) with an instruction. One instruction may start (or
@@ -163,54 +163,54 @@ uint64_t DebugHandlerBase::getBaseTypeSize(const DIType *Ty) {
return getBaseTypeSize(BaseType);
}
-bool DebugHandlerBase::isUnsignedDIType(const DIType *Ty) {
- if (auto *CTy = dyn_cast<DICompositeType>(Ty)) {
- // FIXME: Enums without a fixed underlying type have unknown signedness
- // here, leading to incorrectly emitted constants.
- if (CTy->getTag() == dwarf::DW_TAG_enumeration_type)
- return false;
-
- // (Pieces of) aggregate types that get hacked apart by SROA may be
- // represented by a constant. Encode them as unsigned bytes.
- return true;
- }
-
- if (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
- dwarf::Tag T = (dwarf::Tag)Ty->getTag();
- // Encode pointer constants as unsigned bytes. This is used at least for
- // null pointer constant emission.
- // FIXME: reference and rvalue_reference /probably/ shouldn't be allowed
- // here, but accept them for now due to a bug in SROA producing bogus
- // dbg.values.
- if (T == dwarf::DW_TAG_pointer_type ||
- T == dwarf::DW_TAG_ptr_to_member_type ||
- T == dwarf::DW_TAG_reference_type ||
- T == dwarf::DW_TAG_rvalue_reference_type)
- return true;
- assert(T == dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type ||
- T == dwarf::DW_TAG_volatile_type ||
- T == dwarf::DW_TAG_restrict_type || T == dwarf::DW_TAG_atomic_type);
- assert(DTy->getBaseType() && "Expected valid base type");
- return isUnsignedDIType(DTy->getBaseType());
- }
-
- auto *BTy = cast<DIBasicType>(Ty);
- unsigned Encoding = BTy->getEncoding();
- assert((Encoding == dwarf::DW_ATE_unsigned ||
- Encoding == dwarf::DW_ATE_unsigned_char ||
- Encoding == dwarf::DW_ATE_signed ||
- Encoding == dwarf::DW_ATE_signed_char ||
- Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF ||
- Encoding == dwarf::DW_ATE_boolean ||
- (Ty->getTag() == dwarf::DW_TAG_unspecified_type &&
- Ty->getName() == "decltype(nullptr)")) &&
- "Unsupported encoding");
- return Encoding == dwarf::DW_ATE_unsigned ||
- Encoding == dwarf::DW_ATE_unsigned_char ||
- Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean ||
- Ty->getTag() == dwarf::DW_TAG_unspecified_type;
-}
-
+bool DebugHandlerBase::isUnsignedDIType(const DIType *Ty) {
+ if (auto *CTy = dyn_cast<DICompositeType>(Ty)) {
+ // FIXME: Enums without a fixed underlying type have unknown signedness
+ // here, leading to incorrectly emitted constants.
+ if (CTy->getTag() == dwarf::DW_TAG_enumeration_type)
+ return false;
+
+ // (Pieces of) aggregate types that get hacked apart by SROA may be
+ // represented by a constant. Encode them as unsigned bytes.
+ return true;
+ }
+
+ if (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
+ dwarf::Tag T = (dwarf::Tag)Ty->getTag();
+ // Encode pointer constants as unsigned bytes. This is used at least for
+ // null pointer constant emission.
+ // FIXME: reference and rvalue_reference /probably/ shouldn't be allowed
+ // here, but accept them for now due to a bug in SROA producing bogus
+ // dbg.values.
+ if (T == dwarf::DW_TAG_pointer_type ||
+ T == dwarf::DW_TAG_ptr_to_member_type ||
+ T == dwarf::DW_TAG_reference_type ||
+ T == dwarf::DW_TAG_rvalue_reference_type)
+ return true;
+ assert(T == dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type ||
+ T == dwarf::DW_TAG_volatile_type ||
+ T == dwarf::DW_TAG_restrict_type || T == dwarf::DW_TAG_atomic_type);
+ assert(DTy->getBaseType() && "Expected valid base type");
+ return isUnsignedDIType(DTy->getBaseType());
+ }
+
+ auto *BTy = cast<DIBasicType>(Ty);
+ unsigned Encoding = BTy->getEncoding();
+ assert((Encoding == dwarf::DW_ATE_unsigned ||
+ Encoding == dwarf::DW_ATE_unsigned_char ||
+ Encoding == dwarf::DW_ATE_signed ||
+ Encoding == dwarf::DW_ATE_signed_char ||
+ Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF ||
+ Encoding == dwarf::DW_ATE_boolean ||
+ (Ty->getTag() == dwarf::DW_TAG_unspecified_type &&
+ Ty->getName() == "decltype(nullptr)")) &&
+ "Unsupported encoding");
+ return Encoding == dwarf::DW_ATE_unsigned ||
+ Encoding == dwarf::DW_ATE_unsigned_char ||
+ Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean ||
+ Ty->getTag() == dwarf::DW_TAG_unspecified_type;
+}
+
static bool hasDebugInfo(const MachineModuleInfo *MMI,
const MachineFunction *MF) {
if (!MMI->hasDebugInfo())
@@ -249,9 +249,9 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
assert(DbgLabels.empty() && "DbgLabels map wasn't cleaned!");
calculateDbgEntityHistory(MF, Asm->MF->getSubtarget().getRegisterInfo(),
DbgValues, DbgLabels);
- InstOrdering.initialize(*MF);
- if (TrimVarLocs)
- DbgValues.trimLocationRanges(*MF, LScopes, InstOrdering);
+ InstOrdering.initialize(*MF);
+ if (TrimVarLocs)
+ DbgValues.trimLocationRanges(*MF, LScopes, InstOrdering);
LLVM_DEBUG(DbgValues.dump());
// Request labels for the full history.
@@ -273,16 +273,16 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
// doing that violates the ranges that are calculated in the history map.
// However, we currently do not emit debug values for constant arguments
// directly at the start of the function, so this code is still useful.
- // FIXME: If the first mention of an argument is in a unique section basic
- // block, we cannot always assign the CurrentFnBeginLabel as it lies in a
- // different section. Temporarily, we disable generating loc list
- // information or DW_AT_const_value when the block is in a different
- // section.
+ // FIXME: If the first mention of an argument is in a unique section basic
+ // block, we cannot always assign the CurrentFnBeginLabel as it lies in a
+ // different section. Temporarily, we disable generating loc list
+ // information or DW_AT_const_value when the block is in a different
+ // section.
const DILocalVariable *DIVar =
Entries.front().getInstr()->getDebugVariable();
if (DIVar->isParameter() &&
- getDISubprogram(DIVar->getScope())->describes(&MF->getFunction()) &&
- Entries.front().getInstr()->getParent()->sameSection(&MF->front())) {
+ getDISubprogram(DIVar->getScope())->describes(&MF->getFunction()) &&
+ Entries.front().getInstr()->getParent()->sameSection(&MF->front())) {
if (!IsDescribedByReg(Entries.front().getInstr()))
LabelsBeforeInsn[Entries.front().getInstr()] = Asm->getFunctionBegin();
if (Entries.front().getInstr()->getDebugExpression()->isFragment()) {
@@ -329,7 +329,7 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
}
void DebugHandlerBase::beginInstruction(const MachineInstr *MI) {
- if (!Asm || !MMI->hasDebugInfo())
+ if (!Asm || !MMI->hasDebugInfo())
return;
assert(CurMI == nullptr);
@@ -355,7 +355,7 @@ void DebugHandlerBase::beginInstruction(const MachineInstr *MI) {
}
void DebugHandlerBase::endInstruction() {
- if (!Asm || !MMI->hasDebugInfo())
+ if (!Asm || !MMI->hasDebugInfo())
return;
assert(CurMI != nullptr);
@@ -387,13 +387,13 @@ void DebugHandlerBase::endInstruction() {
}
void DebugHandlerBase::endFunction(const MachineFunction *MF) {
- if (Asm && hasDebugInfo(MMI, MF))
+ if (Asm && hasDebugInfo(MMI, MF))
endFunctionImpl(MF);
DbgValues.clear();
DbgLabels.clear();
LabelsBeforeInsn.clear();
LabelsAfterInsn.clear();
- InstOrdering.clear();
+ InstOrdering.clear();
}
void DebugHandlerBase::beginBasicBlock(const MachineBasicBlock &MBB) {
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
index 747ccf79eb..c20ac6040a 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
@@ -81,9 +81,9 @@ void DwarfCFIException::endModule() {
}
}
-static MCSymbol *getExceptionSym(AsmPrinter *Asm,
- const MachineBasicBlock *MBB) {
- return Asm->getMBBExceptionSym(*MBB);
+static MCSymbol *getExceptionSym(AsmPrinter *Asm,
+ const MachineBasicBlock *MBB) {
+ return Asm->getMBBExceptionSym(*MBB);
}
void DwarfCFIException::beginFunction(const MachineFunction *MF) {
@@ -162,7 +162,7 @@ void DwarfCFIException::beginFragment(const MachineBasicBlock *MBB,
// Provide LSDA information.
if (shouldEmitLSDA)
- Asm->OutStreamer->emitCFILsda(ESP(Asm, MBB), TLOF.getLSDAEncoding());
+ Asm->OutStreamer->emitCFILsda(ESP(Asm, MBB), TLOF.getLSDAEncoding());
}
/// endFunction - Gather and emit post-function exception information.
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index c07f0569ec..befc4bba19 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -105,7 +105,7 @@ unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) {
return Asm->OutStreamer->emitDwarfFileDirective(0, "", "", None, None,
CUID);
return Asm->OutStreamer->emitDwarfFileDirective(
- 0, File->getDirectory(), File->getFilename(), DD->getMD5AsBytes(File),
+ 0, File->getDirectory(), File->getFilename(), DD->getMD5AsBytes(File),
File->getSource(), CUID);
}
@@ -248,9 +248,9 @@ void DwarfCompileUnit::addLocationAttribute(
: dwarf::DW_OP_const8u);
// 2) containing the (relocated) offset of the TLS variable
// within the module's TLS block.
- addExpr(*Loc,
- PointerSize == 4 ? dwarf::DW_FORM_data4
- : dwarf::DW_FORM_data8,
+ addExpr(*Loc,
+ PointerSize == 4 ? dwarf::DW_FORM_data4
+ : dwarf::DW_FORM_data8,
Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym));
} else {
addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);
@@ -422,10 +422,10 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {
// FIXME: duplicated from Target/WebAssembly/WebAssembly.h
// don't want to depend on target specific headers in this code?
const unsigned TI_GLOBAL_RELOC = 3;
- // FIXME: when writing dwo, we need to avoid relocations. Probably
- // the "right" solution is to treat globals the way func and data symbols
- // are (with entries in .debug_addr).
- if (FrameBase.Location.WasmLoc.Kind == TI_GLOBAL_RELOC && !isDwoUnit()) {
+ // FIXME: when writing dwo, we need to avoid relocations. Probably
+ // the "right" solution is to treat globals the way func and data symbols
+ // are (with entries in .debug_addr).
+ if (FrameBase.Location.WasmLoc.Kind == TI_GLOBAL_RELOC && !isDwoUnit()) {
// These need to be relocatable.
assert(FrameBase.Location.WasmLoc.Index == 0); // Only SP so far.
auto SPSym = cast<MCSymbolWasm>(
@@ -442,8 +442,8 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {
true});
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location);
- addSInt(*Loc, dwarf::DW_FORM_sdata, TI_GLOBAL_RELOC);
- addLabel(*Loc, dwarf::DW_FORM_data4, SPSym);
+ addSInt(*Loc, dwarf::DW_FORM_sdata, TI_GLOBAL_RELOC);
+ addLabel(*Loc, dwarf::DW_FORM_data4, SPSym);
DD->addArangeLabel(SymbolCU(this, SPSym));
addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
@@ -558,12 +558,12 @@ void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE,
void DwarfCompileUnit::attachRangesOrLowHighPC(
DIE &Die, SmallVector<RangeSpan, 2> Ranges) {
- assert(!Ranges.empty());
- if (!DD->useRangesSection() ||
- (Ranges.size() == 1 &&
- (!DD->alwaysUseRanges() ||
- DD->getSectionLabel(&Ranges.front().Begin->getSection()) ==
- Ranges.front().Begin))) {
+ assert(!Ranges.empty());
+ if (!DD->useRangesSection() ||
+ (Ranges.size() == 1 &&
+ (!DD->alwaysUseRanges() ||
+ DD->getSectionLabel(&Ranges.front().Begin->getSection()) ==
+ Ranges.front().Begin))) {
const RangeSpan &Front = Ranges.front();
const RangeSpan &Back = Ranges.back();
attachLowHighPC(Die, Front.Begin, Back.End);
@@ -686,9 +686,9 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
// Add variable address.
- unsigned Index = DV.getDebugLocListIndex();
- if (Index != ~0U) {
- addLocationList(*VariableDie, dwarf::DW_AT_location, Index);
+ unsigned Index = DV.getDebugLocListIndex();
+ if (Index != ~0U) {
+ addLocationList(*VariableDie, dwarf::DW_AT_location, Index);
auto TagOffset = DV.getDebugLocListTagOffset();
if (TagOffset)
addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
@@ -720,13 +720,13 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
addConstantFPValue(*VariableDie, DVal->getConstantFP());
} else if (DVal->isConstantInt()) {
addConstantValue(*VariableDie, DVal->getConstantInt(), DV.getType());
- } else if (DVal->isTargetIndexLocation()) {
- DIELoc *Loc = new (DIEValueAllocator) DIELoc;
- DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
- const DIBasicType *BT = dyn_cast<DIBasicType>(
- static_cast<const Metadata *>(DV.getVariable()->getType()));
- DwarfDebug::emitDebugLocValue(*Asm, BT, *DVal, DwarfExpr);
- addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
+ } else if (DVal->isTargetIndexLocation()) {
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+ DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
+ const DIBasicType *BT = dyn_cast<DIBasicType>(
+ static_cast<const Metadata *>(DV.getVariable()->getType()));
+ DwarfDebug::emitDebugLocValue(*Asm, BT, *DVal, DwarfExpr);
+ addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
}
return VariableDie;
}
@@ -742,14 +742,14 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
Register FrameReg;
const DIExpression *Expr = Fragment.Expr;
const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
- StackOffset Offset =
- TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg);
+ StackOffset Offset =
+ TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg);
DwarfExpr.addFragmentOffset(Expr);
-
- auto *TRI = Asm->MF->getSubtarget().getRegisterInfo();
+
+ auto *TRI = Asm->MF->getSubtarget().getRegisterInfo();
SmallVector<uint64_t, 8> Ops;
- TRI->getOffsetOpcodes(Offset, Ops);
-
+ TRI->getOffsetOpcodes(Offset, Ops);
+
// According to
// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
// cuda-gdb requires DW_AT_address_class for all variables to be able to
@@ -810,10 +810,10 @@ static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) {
return Result;
if (auto *DLVar = Array->getDataLocation())
Result.push_back(DLVar);
- if (auto *AsVar = Array->getAssociated())
- Result.push_back(AsVar);
- if (auto *AlVar = Array->getAllocated())
- Result.push_back(AlVar);
+ if (auto *AsVar = Array->getAssociated())
+ Result.push_back(AsVar);
+ if (auto *AlVar = Array->getAllocated())
+ Result.push_back(AlVar);
for (auto *El : Array->getElements()) {
if (auto *Subrange = dyn_cast<DISubrange>(El)) {
if (auto Count = Subrange->getCount())
@@ -828,19 +828,19 @@ static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) {
if (auto ST = Subrange->getStride())
if (auto *Dependency = ST.dyn_cast<DIVariable *>())
Result.push_back(Dependency);
- } else if (auto *GenericSubrange = dyn_cast<DIGenericSubrange>(El)) {
- if (auto Count = GenericSubrange->getCount())
- if (auto *Dependency = Count.dyn_cast<DIVariable *>())
- Result.push_back(Dependency);
- if (auto LB = GenericSubrange->getLowerBound())
- if (auto *Dependency = LB.dyn_cast<DIVariable *>())
- Result.push_back(Dependency);
- if (auto UB = GenericSubrange->getUpperBound())
- if (auto *Dependency = UB.dyn_cast<DIVariable *>())
- Result.push_back(Dependency);
- if (auto ST = GenericSubrange->getStride())
- if (auto *Dependency = ST.dyn_cast<DIVariable *>())
- Result.push_back(Dependency);
+ } else if (auto *GenericSubrange = dyn_cast<DIGenericSubrange>(El)) {
+ if (auto Count = GenericSubrange->getCount())
+ if (auto *Dependency = Count.dyn_cast<DIVariable *>())
+ Result.push_back(Dependency);
+ if (auto LB = GenericSubrange->getLowerBound())
+ if (auto *Dependency = LB.dyn_cast<DIVariable *>())
+ Result.push_back(Dependency);
+ if (auto UB = GenericSubrange->getUpperBound())
+ if (auto *Dependency = UB.dyn_cast<DIVariable *>())
+ Result.push_back(Dependency);
+ if (auto ST = GenericSubrange->getStride())
+ if (auto *Dependency = ST.dyn_cast<DIVariable *>())
+ Result.push_back(Dependency);
}
}
return Result;
@@ -1022,7 +1022,7 @@ void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
}
bool DwarfCompileUnit::useGNUAnalogForDwarf5Feature() const {
- return DD->getDwarfVersion() == 4 && !DD->tuneForLLDB();
+ return DD->getDwarfVersion() == 4 && !DD->tuneForLLDB();
}
dwarf::Tag DwarfCompileUnit::getDwarf5OrGNUTag(dwarf::Tag Tag) const {
@@ -1378,9 +1378,9 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
/// Add a Dwarf loclistptr attribute data and value.
void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute,
unsigned Index) {
- dwarf::Form Form = (DD->getDwarfVersion() >= 5)
- ? dwarf::DW_FORM_loclistx
- : DD->getDwarfSectionOffsetForm();
+ dwarf::Form Form = (DD->getDwarfVersion() >= 5)
+ ? dwarf::DW_FORM_loclistx
+ : DD->getDwarfSectionOffsetForm();
Die.addValue(DIEValueAllocator, Attribute, Form, DIELocList(Index));
}
@@ -1441,8 +1441,8 @@ void DwarfCompileUnit::addAddrTableBase() {
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
MCSymbol *Label = DD->getAddressPool().getLabel();
addSectionLabel(getUnitDie(),
- DD->getDwarfVersion() >= 5 ? dwarf::DW_AT_addr_base
- : dwarf::DW_AT_GNU_addr_base,
+ DD->getDwarfVersion() >= 5 ? dwarf::DW_AT_addr_base
+ : dwarf::DW_AT_GNU_addr_base,
Label, TLOF.getDwarfAddrSection()->getBeginSymbol());
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
index c9f33672ca..6d8186a5ee 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
@@ -33,9 +33,9 @@
namespace llvm {
class AsmPrinter;
-class DIE;
-class DIELoc;
-class DIEValueList;
+class DIE;
+class DIELoc;
+class DIEValueList;
class DwarfFile;
class GlobalVariable;
class MCExpr;
@@ -57,7 +57,7 @@ class DwarfCompileUnit final : public DwarfUnit {
DwarfCompileUnit *Skeleton = nullptr;
/// The start of the unit within its section.
- MCSymbol *LabelBegin = nullptr;
+ MCSymbol *LabelBegin = nullptr;
/// The start of the unit macro info within macro section.
MCSymbol *MacroLabelBegin;
@@ -289,8 +289,8 @@ public:
return DwarfUnit::getHeaderSize() + DWOIdSize;
}
unsigned getLength() {
- return Asm->getUnitLengthFieldByteSize() + // Length field
- getHeaderSize() + getUnitDie().getSize();
+ return Asm->getUnitLengthFieldByteSize() + // Length field
+ getHeaderSize() + getUnitDie().getSize();
}
void emitHeader(bool UseOffsets) override;
@@ -299,7 +299,7 @@ public:
void addAddrTableBase();
MCSymbol *getLabelBegin() const {
- assert(LabelBegin && "LabelBegin is not initialized");
+ assert(LabelBegin && "LabelBegin is not initialized");
return LabelBegin;
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index b48ea8547b..462682743c 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -123,18 +123,18 @@ static cl::opt<DefaultOnOff> DwarfSectionsAsReferences(
clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")),
cl::init(Default));
-static cl::opt<bool>
- UseGNUDebugMacro("use-gnu-debug-macro", cl::Hidden,
- cl::desc("Emit the GNU .debug_macro format with DWARF <5"),
- cl::init(false));
-
-static cl::opt<DefaultOnOff> DwarfOpConvert(
- "dwarf-op-convert", cl::Hidden,
- cl::desc("Enable use of the DWARFv5 DW_OP_convert operator"),
- cl::values(clEnumVal(Default, "Default for platform"),
- clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")),
- cl::init(Default));
-
+static cl::opt<bool>
+ UseGNUDebugMacro("use-gnu-debug-macro", cl::Hidden,
+ cl::desc("Emit the GNU .debug_macro format with DWARF <5"),
+ cl::init(false));
+
+static cl::opt<DefaultOnOff> DwarfOpConvert(
+ "dwarf-op-convert", cl::Hidden,
+ cl::desc("Enable use of the DWARFv5 DW_OP_convert operator"),
+ cl::values(clEnumVal(Default, "Default for platform"),
+ clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")),
+ cl::init(Default));
+
enum LinkageNameOption {
DefaultLinkageNames,
AllLinkageNames,
@@ -151,23 +151,23 @@ static cl::opt<LinkageNameOption>
"Abstract subprograms")),
cl::init(DefaultLinkageNames));
-static cl::opt<DwarfDebug::MinimizeAddrInV5> MinimizeAddrInV5Option(
- "minimize-addr-in-v5", cl::Hidden,
- cl::desc("Always use DW_AT_ranges in DWARFv5 whenever it could allow more "
- "address pool entry sharing to reduce relocations/object size"),
- cl::values(clEnumValN(DwarfDebug::MinimizeAddrInV5::Default, "Default",
- "Default address minimization strategy"),
- clEnumValN(DwarfDebug::MinimizeAddrInV5::Ranges, "Ranges",
- "Use rnglists for contiguous ranges if that allows "
- "using a pre-existing base address"),
- clEnumValN(DwarfDebug::MinimizeAddrInV5::Disabled, "Disabled",
- "Stuff")),
- cl::init(DwarfDebug::MinimizeAddrInV5::Default));
+static cl::opt<DwarfDebug::MinimizeAddrInV5> MinimizeAddrInV5Option(
+ "minimize-addr-in-v5", cl::Hidden,
+ cl::desc("Always use DW_AT_ranges in DWARFv5 whenever it could allow more "
+ "address pool entry sharing to reduce relocations/object size"),
+ cl::values(clEnumValN(DwarfDebug::MinimizeAddrInV5::Default, "Default",
+ "Default address minimization strategy"),
+ clEnumValN(DwarfDebug::MinimizeAddrInV5::Ranges, "Ranges",
+ "Use rnglists for contiguous ranges if that allows "
+ "using a pre-existing base address"),
+ clEnumValN(DwarfDebug::MinimizeAddrInV5::Disabled, "Disabled",
+ "Stuff")),
+ cl::init(DwarfDebug::MinimizeAddrInV5::Default));
static constexpr unsigned ULEB128PadSize = 4;
void DebugLocDwarfExpression::emitOp(uint8_t Op, const char *Comment) {
- getActiveStreamer().emitInt8(
+ getActiveStreamer().emitInt8(
Op, Comment ? Twine(Comment) + " " + dwarf::OperationEncodingString(Op)
: dwarf::OperationEncodingString(Op));
}
@@ -181,7 +181,7 @@ void DebugLocDwarfExpression::emitUnsigned(uint64_t Value) {
}
void DebugLocDwarfExpression::emitData1(uint8_t Value) {
- getActiveStreamer().emitInt8(Value, Twine(Value));
+ getActiveStreamer().emitInt8(Value, Twine(Value));
}
void DebugLocDwarfExpression::emitBaseTypeRef(uint64_t Idx) {
@@ -190,7 +190,7 @@ void DebugLocDwarfExpression::emitBaseTypeRef(uint64_t Idx) {
}
bool DebugLocDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI,
- llvm::Register MachineReg) {
+ llvm::Register MachineReg) {
// This information is not available while emitting .debug_loc entries.
return false;
}
@@ -215,7 +215,7 @@ void DebugLocDwarfExpression::commitTemporaryBuffer() {
const char *Comment = (Byte.index() < TmpBuf->Comments.size())
? TmpBuf->Comments[Byte.index()].c_str()
: "";
- OutBS.emitInt8(Byte.value(), Comment);
+ OutBS.emitInt8(Byte.value(), Comment);
}
TmpBuf->Bytes.clear();
TmpBuf->Comments.clear();
@@ -230,8 +230,8 @@ static DbgValueLoc getDebugLocValue(const MachineInstr *MI) {
const DIExpression *Expr = MI->getDebugExpression();
assert(MI->getNumOperands() == 4);
if (MI->getDebugOperand(0).isReg()) {
- const auto &RegOp = MI->getDebugOperand(0);
- const auto &Op1 = MI->getDebugOffset();
+ const auto &RegOp = MI->getDebugOperand(0);
+ const auto &Op1 = MI->getDebugOffset();
// If the second operand is an immediate, this is a
// register-indirect address.
assert((!Op1.isImm() || (Op1.getImm() == 0)) && "unexpected offset");
@@ -239,7 +239,7 @@ static DbgValueLoc getDebugLocValue(const MachineInstr *MI) {
return DbgValueLoc(Expr, MLoc);
}
if (MI->getDebugOperand(0).isTargetIndex()) {
- const auto &Op = MI->getDebugOperand(0);
+ const auto &Op = MI->getDebugOperand(0);
return DbgValueLoc(Expr,
TargetIndexLocation(Op.getIndex(), Op.getOffset()));
}
@@ -342,7 +342,7 @@ static AccelTableKind computeAccelTableKind(unsigned DwarfVersion,
return AccelTableKind::None;
}
-DwarfDebug::DwarfDebug(AsmPrinter *A)
+DwarfDebug::DwarfDebug(AsmPrinter *A)
: DebugHandlerBase(A), DebugLocs(A->OutStreamer->isVerboseAsm()),
InfoHolder(A, "info_string", DIEValueAllocator),
SkeletonHolder(A, "skel_string", DIEValueAllocator),
@@ -385,11 +385,11 @@ DwarfDebug::DwarfDebug(AsmPrinter *A)
DwarfVersion =
TT.isNVPTX() ? 2 : (DwarfVersion ? DwarfVersion : dwarf::DWARF_VERSION);
- bool Dwarf64 = Asm->TM.Options.MCOptions.Dwarf64 &&
- DwarfVersion >= 3 && // DWARF64 was introduced in DWARFv3.
- TT.isArch64Bit() && // DWARF64 requires 64-bit relocations.
- TT.isOSBinFormatELF(); // Support only ELF for now.
-
+ bool Dwarf64 = Asm->TM.Options.MCOptions.Dwarf64 &&
+ DwarfVersion >= 3 && // DWARF64 was introduced in DWARFv3.
+ TT.isArch64Bit() && // DWARF64 requires 64-bit relocations.
+ TT.isOSBinFormatELF(); // Support only ELF for now.
+
UseRangesSection = !NoDwarfRangesSection && !TT.isNVPTX();
// Use sections as references. Force for NVPTX.
@@ -399,9 +399,9 @@ DwarfDebug::DwarfDebug(AsmPrinter *A)
UseSectionsAsReferences = DwarfSectionsAsReferences == Enable;
// Don't generate type units for unsupported object file formats.
- GenerateTypeUnits = (A->TM.getTargetTriple().isOSBinFormatELF() ||
- A->TM.getTargetTriple().isOSBinFormatWasm()) &&
- GenerateDwarfTypeUnits;
+ GenerateTypeUnits = (A->TM.getTargetTriple().isOSBinFormatELF() ||
+ A->TM.getTargetTriple().isOSBinFormatWasm()) &&
+ GenerateDwarfTypeUnits;
TheAccelTableKind = computeAccelTableKind(
DwarfVersion, GenerateTypeUnits, DebuggerTuning, A->TM.getTargetTriple());
@@ -424,31 +424,31 @@ DwarfDebug::DwarfDebug(AsmPrinter *A)
// Emit call-site-param debug info for GDB and LLDB, if the target supports
// the debug entry values feature. It can also be enabled explicitly.
- EmitDebugEntryValues = Asm->TM.Options.ShouldEmitDebugEntryValues();
-
- // It is unclear if the GCC .debug_macro extension is well-specified
- // for split DWARF. For now, do not allow LLVM to emit it.
- UseDebugMacroSection =
- DwarfVersion >= 5 || (UseGNUDebugMacro && !useSplitDwarf());
- if (DwarfOpConvert == Default)
- EnableOpConvert = !((tuneForGDB() && useSplitDwarf()) || (tuneForLLDB() && !TT.isOSBinFormatMachO()));
- else
- EnableOpConvert = (DwarfOpConvert == Enable);
-
- // Split DWARF would benefit object size significantly by trading reductions
- // in address pool usage for slightly increased range list encodings.
- if (DwarfVersion >= 5) {
- MinimizeAddr = MinimizeAddrInV5Option;
- // FIXME: In the future, enable this by default for Split DWARF where the
- // tradeoff is more pronounced due to being able to offload the range
- // lists to the dwo file and shrink object files/reduce relocations there.
- if (MinimizeAddr == MinimizeAddrInV5::Default)
- MinimizeAddr = MinimizeAddrInV5::Disabled;
- }
-
+ EmitDebugEntryValues = Asm->TM.Options.ShouldEmitDebugEntryValues();
+
+ // It is unclear if the GCC .debug_macro extension is well-specified
+ // for split DWARF. For now, do not allow LLVM to emit it.
+ UseDebugMacroSection =
+ DwarfVersion >= 5 || (UseGNUDebugMacro && !useSplitDwarf());
+ if (DwarfOpConvert == Default)
+ EnableOpConvert = !((tuneForGDB() && useSplitDwarf()) || (tuneForLLDB() && !TT.isOSBinFormatMachO()));
+ else
+ EnableOpConvert = (DwarfOpConvert == Enable);
+
+ // Split DWARF would benefit object size significantly by trading reductions
+ // in address pool usage for slightly increased range list encodings.
+ if (DwarfVersion >= 5) {
+ MinimizeAddr = MinimizeAddrInV5Option;
+ // FIXME: In the future, enable this by default for Split DWARF where the
+ // tradeoff is more pronounced due to being able to offload the range
+ // lists to the dwo file and shrink object files/reduce relocations there.
+ if (MinimizeAddr == MinimizeAddrInV5::Default)
+ MinimizeAddr = MinimizeAddrInV5::Disabled;
+ }
+
Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);
- Asm->OutStreamer->getContext().setDwarfFormat(Dwarf64 ? dwarf::DWARF64
- : dwarf::DWARF32);
+ Asm->OutStreamer->getContext().setDwarfFormat(Dwarf64 ? dwarf::DWARF64
+ : dwarf::DWARF32);
}
// Define out of line so we don't have to include DwarfUnit.h in DwarfDebug.h.
@@ -597,7 +597,7 @@ static const DIExpression *combineDIExpressions(const DIExpression *Original,
std::vector<uint64_t> Elts = Addition->getElements().vec();
// Avoid multiple DW_OP_stack_values.
if (Original->isImplicit() && Addition->isImplicit())
- erase_value(Elts, dwarf::DW_OP_stack_value);
+ erase_value(Elts, dwarf::DW_OP_stack_value);
const DIExpression *CombinedExpr =
(Elts.size() > 0) ? DIExpression::append(Original, Elts) : Original;
return CombinedExpr;
@@ -723,11 +723,11 @@ static void interpretValues(const MachineInstr *CurMI,
ForwardedRegWorklist[ParamFwdReg], Params);
} else if (ParamValue->first.isReg()) {
Register RegLoc = ParamValue->first.getReg();
- Register SP = TLI.getStackPointerRegisterToSaveRestore();
+ Register SP = TLI.getStackPointerRegisterToSaveRestore();
Register FP = TRI.getFrameRegister(*MF);
bool IsSPorFP = (RegLoc == SP) || (RegLoc == FP);
if (TRI.isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP) {
- MachineLocation MLoc(RegLoc, /*Indirect=*/IsSPorFP);
+ MachineLocation MLoc(RegLoc, /*Indirect=*/IsSPorFP);
finishCallSiteParams(MLoc, ParamValue->second,
ForwardedRegWorklist[ParamFwdReg], Params);
} else {
@@ -811,11 +811,11 @@ static void collectCallSiteParameters(const MachineInstr *CallMI,
(void)InsertedReg;
}
- // Do not emit CSInfo for undef forwarding registers.
- for (auto &MO : CallMI->uses())
- if (MO.isReg() && MO.isUndef())
- ForwardedRegWorklist.erase(MO.getReg());
-
+ // Do not emit CSInfo for undef forwarding registers.
+ for (auto &MO : CallMI->uses())
+ if (MO.isReg() && MO.isUndef())
+ ForwardedRegWorklist.erase(MO.getReg());
+
// We erase, from the ForwardedRegWorklist, those forwarding registers for
// which we successfully describe a loaded value (by using
// the describeLoadedValue()). For those remaining arguments in the working
@@ -1090,8 +1090,8 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) {
// compilation directory.
if (!Asm->OutStreamer->hasRawTextSupport() || SingleCU)
Asm->OutStreamer->emitDwarfFile0Directive(
- CompilationDir, DIUnit->getFilename(), getMD5AsBytes(DIUnit->getFile()),
- DIUnit->getSource(), NewCU.getUniqueID());
+ CompilationDir, DIUnit->getFilename(), getMD5AsBytes(DIUnit->getFile()),
+ DIUnit->getSource(), NewCU.getUniqueID());
if (useSplitDwarf()) {
NewCU.setSkeleton(constructSkeletonCU(NewCU));
@@ -1144,17 +1144,17 @@ sortGlobalExprs(SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &GVEs) {
// Emit all Dwarf sections that should come prior to the content. Create
// global DIEs and emit initial debug info sections. This is invoked by
// the target AsmPrinter.
-void DwarfDebug::beginModule(Module *M) {
- DebugHandlerBase::beginModule(M);
-
- if (!Asm || !MMI->hasDebugInfo())
+void DwarfDebug::beginModule(Module *M) {
+ DebugHandlerBase::beginModule(M);
+
+ if (!Asm || !MMI->hasDebugInfo())
return;
unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
M->debug_compile_units_end());
- assert(NumDebugCUs > 0 && "Asm unexpectedly initialized");
- assert(MMI->hasDebugInfo() &&
- "DebugInfoAvailabilty unexpectedly not initialized");
+ assert(NumDebugCUs > 0 && "Asm unexpectedly initialized");
+ assert(MMI->hasDebugInfo() &&
+ "DebugInfoAvailabilty unexpectedly not initialized");
SingleCU = NumDebugCUs == 1;
DenseMap<DIGlobalVariable *, SmallVector<DwarfCompileUnit::GlobalExpr, 1>>
GVMap;
@@ -1306,7 +1306,7 @@ void DwarfDebug::finalizeModuleInfo() {
Asm->TM.Options.MCOptions.SplitDwarfFile);
// Emit a unique identifier for this CU.
uint64_t ID =
- DIEHash(Asm, &TheCU).computeCUSignature(DWOName, TheCU.getUnitDie());
+ DIEHash(Asm, &TheCU).computeCUSignature(DWOName, TheCU.getUnitDie());
if (getDwarfVersion() >= 5) {
TheCU.setDWOId(ID);
SkCU->setDWOId(ID);
@@ -1367,18 +1367,18 @@ void DwarfDebug::finalizeModuleInfo() {
// If compile Unit has macros, emit "DW_AT_macro_info/DW_AT_macros"
// attribute.
if (CUNode->getMacros()) {
- if (UseDebugMacroSection) {
+ if (UseDebugMacroSection) {
if (useSplitDwarf())
TheCU.addSectionDelta(
TheCU.getUnitDie(), dwarf::DW_AT_macros, U.getMacroLabelBegin(),
TLOF.getDwarfMacroDWOSection()->getBeginSymbol());
- else {
- dwarf::Attribute MacrosAttr = getDwarfVersion() >= 5
- ? dwarf::DW_AT_macros
- : dwarf::DW_AT_GNU_macros;
- U.addSectionLabel(U.getUnitDie(), MacrosAttr, U.getMacroLabelBegin(),
+ else {
+ dwarf::Attribute MacrosAttr = getDwarfVersion() >= 5
+ ? dwarf::DW_AT_macros
+ : dwarf::DW_AT_GNU_macros;
+ U.addSectionLabel(U.getUnitDie(), MacrosAttr, U.getMacroLabelBegin(),
TLOF.getDwarfMacroSection()->getBeginSymbol());
- }
+ }
} else {
if (useSplitDwarf())
TheCU.addSectionDelta(
@@ -1415,8 +1415,8 @@ void DwarfDebug::endModule() {
}
// If we aren't actually generating debug info (check beginModule -
- // conditionalized on the presence of the llvm.dbg.cu metadata node)
- if (!Asm || !MMI->hasDebugInfo())
+ // conditionalized on the presence of the llvm.dbg.cu metadata node)
+ if (!Asm || !MMI->hasDebugInfo())
return;
// Finalize the debug info for the module.
@@ -1548,8 +1548,8 @@ void DwarfDebug::collectVariableInfoFromMFTable(
/// either open or otherwise rolls off the end of the scope.
static bool validThroughout(LexicalScopes &LScopes,
const MachineInstr *DbgValue,
- const MachineInstr *RangeEnd,
- const InstructionOrdering &Ordering) {
+ const MachineInstr *RangeEnd,
+ const InstructionOrdering &Ordering) {
assert(DbgValue->getDebugLoc() && "DBG_VALUE without a debug location");
auto MBB = DbgValue->getParent();
auto DL = DbgValue->getDebugLoc();
@@ -1562,29 +1562,29 @@ static bool validThroughout(LexicalScopes &LScopes,
return false;
const MachineInstr *LScopeBegin = LSRange.front().first;
- // If the scope starts before the DBG_VALUE then we may have a negative
- // result. Otherwise the location is live coming into the scope and we
- // can skip the following checks.
- if (!Ordering.isBefore(DbgValue, LScopeBegin)) {
- // Exit if the lexical scope begins outside of the current block.
- if (LScopeBegin->getParent() != MBB)
- return false;
-
- MachineBasicBlock::const_reverse_iterator Pred(DbgValue);
- for (++Pred; Pred != MBB->rend(); ++Pred) {
- if (Pred->getFlag(MachineInstr::FrameSetup))
- break;
- auto PredDL = Pred->getDebugLoc();
- if (!PredDL || Pred->isMetaInstruction())
- continue;
- // Check whether the instruction preceding the DBG_VALUE is in the same
- // (sub)scope as the DBG_VALUE.
- if (DL->getScope() == PredDL->getScope())
- return false;
- auto *PredScope = LScopes.findLexicalScope(PredDL);
- if (!PredScope || LScope->dominates(PredScope))
- return false;
- }
+ // If the scope starts before the DBG_VALUE then we may have a negative
+ // result. Otherwise the location is live coming into the scope and we
+ // can skip the following checks.
+ if (!Ordering.isBefore(DbgValue, LScopeBegin)) {
+ // Exit if the lexical scope begins outside of the current block.
+ if (LScopeBegin->getParent() != MBB)
+ return false;
+
+ MachineBasicBlock::const_reverse_iterator Pred(DbgValue);
+ for (++Pred; Pred != MBB->rend(); ++Pred) {
+ if (Pred->getFlag(MachineInstr::FrameSetup))
+ break;
+ auto PredDL = Pred->getDebugLoc();
+ if (!PredDL || Pred->isMetaInstruction())
+ continue;
+ // Check whether the instruction preceding the DBG_VALUE is in the same
+ // (sub)scope as the DBG_VALUE.
+ if (DL->getScope() == PredDL->getScope())
+ return false;
+ auto *PredScope = LScopes.findLexicalScope(PredDL);
+ if (!PredScope || LScope->dominates(PredScope))
+ return false;
+ }
}
// If the range of the DBG_VALUE is open-ended, report success.
@@ -1598,10 +1598,10 @@ static bool validThroughout(LexicalScopes &LScopes,
if (DbgValue->getDebugOperand(0).isImm() && MBB->pred_empty())
return true;
- // Test if the location terminates before the end of the scope.
- const MachineInstr *LScopeEnd = LSRange.back().second;
- if (Ordering.isBefore(RangeEnd, LScopeEnd))
- return false;
+ // Test if the location terminates before the end of the scope.
+ const MachineInstr *LScopeEnd = LSRange.back().second;
+ if (Ordering.isBefore(RangeEnd, LScopeEnd))
+ return false;
// There's a single location which starts at the scope start, and ends at or
// after the scope end.
@@ -1641,8 +1641,8 @@ static bool validThroughout(LexicalScopes &LScopes,
// [1-3) [(reg0, fragment 0, 32), (reg1, fragment 32, 32)]
// [3-4) [(reg1, fragment 32, 32), (123, fragment 64, 32)]
// [4-) [(@g, fragment 0, 96)]
-bool DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
- const DbgValueHistoryMap::Entries &Entries) {
+bool DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
+ const DbgValueHistoryMap::Entries &Entries) {
using OpenRange =
std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
SmallVector<OpenRange, 4> OpenRanges;
@@ -1655,7 +1655,7 @@ bool DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
// Remove all values that are no longer live.
size_t Index = std::distance(EB, EI);
- erase_if(OpenRanges, [&](OpenRange &R) { return R.first <= Index; });
+ erase_if(OpenRanges, [&](OpenRange &R) { return R.first <= Index; });
// If we are dealing with a clobbering entry, this iteration will result in
// a location list entry starting after the clobbering instruction.
@@ -1736,8 +1736,8 @@ bool DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
DebugLoc.pop_back();
}
- return DebugLoc.size() == 1 && isSafeForSingleLocation &&
- validThroughout(LScopes, StartDebugMI, EndMI, getInstOrdering());
+ return DebugLoc.size() == 1 && isSafeForSingleLocation &&
+ validThroughout(LScopes, StartDebugMI, EndMI, getInstOrdering());
}
DbgEntity *DwarfDebug::createConcreteEntity(DwarfCompileUnit &TheCU,
@@ -1805,7 +1805,7 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
if (HistSize == 1 || SingleValueWithClobber) {
const auto *End =
SingleValueWithClobber ? HistoryMapEntries[1].getInstr() : nullptr;
- if (validThroughout(LScopes, MInsn, End, getInstOrdering())) {
+ if (validThroughout(LScopes, MInsn, End, getInstOrdering())) {
RegVar->initializeDbgValue(MInsn);
continue;
}
@@ -1820,7 +1820,7 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
// Build the location list for this variable.
SmallVector<DebugLocEntry, 8> Entries;
- bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
+ bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
// Check whether buildLocationList managed to merge all locations to one
// that is valid throughout the variable's scope. If so, produce single
@@ -1925,8 +1925,8 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
}
DebugHandlerBase::beginInstruction(MI);
- if (!CurMI)
- return;
+ if (!CurMI)
+ return;
if (NoDebug)
return;
@@ -2365,8 +2365,8 @@ void DwarfDebug::emitDebugPubSection(bool GnuStyle, StringRef Name,
// Emit the header.
MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + Name + "_begin");
MCSymbol *EndLabel = Asm->createTempSymbol("pub" + Name + "_end");
- Asm->emitDwarfUnitLength(EndLabel, BeginLabel,
- "Length of Public " + Name + " Info");
+ Asm->emitDwarfUnitLength(EndLabel, BeginLabel,
+ "Length of Public " + Name + " Info");
Asm->OutStreamer->emitLabel(BeginLabel);
@@ -2377,7 +2377,7 @@ void DwarfDebug::emitDebugPubSection(bool GnuStyle, StringRef Name,
emitSectionReference(*TheU);
Asm->OutStreamer->AddComment("Compilation Unit Length");
- Asm->emitDwarfLengthOrOffset(TheU->getLength());
+ Asm->emitDwarfLengthOrOffset(TheU->getLength());
// Emit the pubnames for this compilation unit.
for (const auto &GI : Globals) {
@@ -2385,7 +2385,7 @@ void DwarfDebug::emitDebugPubSection(bool GnuStyle, StringRef Name,
const DIE *Entity = GI.second;
Asm->OutStreamer->AddComment("DIE offset");
- Asm->emitDwarfLengthOrOffset(Entity->getOffset());
+ Asm->emitDwarfLengthOrOffset(Entity->getOffset());
if (GnuStyle) {
dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheU, Entity);
@@ -2400,7 +2400,7 @@ void DwarfDebug::emitDebugPubSection(bool GnuStyle, StringRef Name,
}
Asm->OutStreamer->AddComment("End Mark");
- Asm->emitDwarfLengthOrOffset(0);
+ Asm->emitDwarfLengthOrOffset(0);
Asm->OutStreamer->emitLabel(EndLabel);
}
@@ -2439,7 +2439,7 @@ void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer,
for (auto &Op : Expr) {
assert(Op.getCode() != dwarf::DW_OP_const_type &&
"3 operand ops not yet supported");
- Streamer.emitInt8(Op.getCode(), Comment != End ? *(Comment++) : "");
+ Streamer.emitInt8(Op.getCode(), Comment != End ? *(Comment++) : "");
Offset++;
for (unsigned I = 0; I < 2; ++I) {
if (Op.getDescription().Op[I] == Encoding::SizeNA)
@@ -2455,7 +2455,7 @@ void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer,
Comment++;
} else {
for (uint64_t J = Offset; J < Op.getOperandEndOffset(I); ++J)
- Streamer.emitInt8(Data.getData()[J], Comment != End ? *(Comment++) : "");
+ Streamer.emitInt8(Data.getData()[J], Comment != End ? *(Comment++) : "");
}
Offset = Op.getOperandEndOffset(I);
}
@@ -2492,26 +2492,26 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
TargetIndexLocation Loc = Value.getTargetIndexLocation();
// TODO TargetIndexLocation is a target-independent. Currently only the WebAssembly-specific
// encoding is supported.
- assert(AP.TM.getTargetTriple().isWasm());
+ assert(AP.TM.getTargetTriple().isWasm());
DwarfExpr.addWasmLocation(Loc.Index, static_cast<uint64_t>(Loc.Offset));
- DwarfExpr.addExpression(std::move(ExprCursor));
- return;
+ DwarfExpr.addExpression(std::move(ExprCursor));
+ return;
} else if (Value.isConstantFP()) {
- if (AP.getDwarfVersion() >= 4 && !AP.getDwarfDebug()->tuneForSCE() &&
- !ExprCursor) {
- DwarfExpr.addConstantFP(Value.getConstantFP()->getValueAPF(), AP);
- return;
- }
- if (Value.getConstantFP()->getValueAPF().bitcastToAPInt().getBitWidth() <=
- 64 /*bits*/)
- DwarfExpr.addUnsignedConstant(
- Value.getConstantFP()->getValueAPF().bitcastToAPInt());
- else
- LLVM_DEBUG(
- dbgs()
- << "Skipped DwarfExpression creation for ConstantFP of size"
- << Value.getConstantFP()->getValueAPF().bitcastToAPInt().getBitWidth()
- << " bits\n");
+ if (AP.getDwarfVersion() >= 4 && !AP.getDwarfDebug()->tuneForSCE() &&
+ !ExprCursor) {
+ DwarfExpr.addConstantFP(Value.getConstantFP()->getValueAPF(), AP);
+ return;
+ }
+ if (Value.getConstantFP()->getValueAPF().bitcastToAPInt().getBitWidth() <=
+ 64 /*bits*/)
+ DwarfExpr.addUnsignedConstant(
+ Value.getConstantFP()->getValueAPF().bitcastToAPInt());
+ else
+ LLVM_DEBUG(
+ dbgs()
+ << "Skipped DwarfExpression creation for ConstantFP of size"
+ << Value.getConstantFP()->getValueAPF().bitcastToAPInt().getBitWidth()
+ << " bits\n");
}
DwarfExpr.addExpression(std::move(ExprCursor));
}
@@ -2534,7 +2534,7 @@ void DebugLocEntry::finalize(const AsmPrinter &AP,
}) && "all values are expected to be fragments");
assert(llvm::is_sorted(Values) && "fragments are expected to be sorted");
- for (const auto &Fragment : Values)
+ for (const auto &Fragment : Values)
DwarfDebug::emitDebugLocValue(AP, BT, Fragment, DwarfExpr);
} else {
@@ -2577,8 +2577,8 @@ static MCSymbol *emitRnglistsTableHeader(AsmPrinter *Asm,
Asm->OutStreamer->emitLabel(Holder.getRnglistsTableBaseSym());
for (const RangeSpanList &List : Holder.getRangeLists())
- Asm->emitLabelDifference(List.Label, Holder.getRnglistsTableBaseSym(),
- Asm->getDwarfOffsetByteSize());
+ Asm->emitLabelDifference(List.Label, Holder.getRnglistsTableBaseSym(),
+ Asm->getDwarfOffsetByteSize());
return TableEnd;
}
@@ -2597,8 +2597,8 @@ static MCSymbol *emitLoclistsTableHeader(AsmPrinter *Asm,
Asm->OutStreamer->emitLabel(DebugLocs.getSym());
for (const auto &List : DebugLocs.getLists())
- Asm->emitLabelDifference(List.Label, DebugLocs.getSym(),
- Asm->getDwarfOffsetByteSize());
+ Asm->emitLabelDifference(List.Label, DebugLocs.getSym(),
+ Asm->getDwarfOffsetByteSize());
return TableEnd;
}
@@ -2880,23 +2880,23 @@ void DwarfDebug::emitDebugARanges() {
// Emit size of content not including length itself.
unsigned ContentSize =
- sizeof(int16_t) + // DWARF ARange version number
- Asm->getDwarfOffsetByteSize() + // Offset of CU in the .debug_info
- // section
- sizeof(int8_t) + // Pointer Size (in bytes)
- sizeof(int8_t); // Segment Size (in bytes)
+ sizeof(int16_t) + // DWARF ARange version number
+ Asm->getDwarfOffsetByteSize() + // Offset of CU in the .debug_info
+ // section
+ sizeof(int8_t) + // Pointer Size (in bytes)
+ sizeof(int8_t); // Segment Size (in bytes)
unsigned TupleSize = PtrSize * 2;
// 7.20 in the Dwarf specs requires the table to be aligned to a tuple.
- unsigned Padding = offsetToAlignment(
- Asm->getUnitLengthFieldByteSize() + ContentSize, Align(TupleSize));
+ unsigned Padding = offsetToAlignment(
+ Asm->getUnitLengthFieldByteSize() + ContentSize, Align(TupleSize));
ContentSize += Padding;
ContentSize += (List.size() + 1) * TupleSize;
// For each compile unit, write the list of spans it covers.
- Asm->emitDwarfUnitLength(ContentSize, "Length of ARange Set");
+ Asm->emitDwarfUnitLength(ContentSize, "Length of ARange Set");
Asm->OutStreamer->AddComment("DWARF Arange version number");
Asm->emitInt16(dwarf::DW_ARANGES_VERSION);
Asm->OutStreamer->AddComment("Offset Into Debug Info Section");
@@ -2982,30 +2982,30 @@ void DwarfDebug::emitDebugRangesDWO() {
Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
}
-/// Emit the header of a DWARF 5 macro section, or the GNU extension for
-/// DWARF 4.
+/// Emit the header of a DWARF 5 macro section, or the GNU extension for
+/// DWARF 4.
static void emitMacroHeader(AsmPrinter *Asm, const DwarfDebug &DD,
- const DwarfCompileUnit &CU, uint16_t DwarfVersion) {
+ const DwarfCompileUnit &CU, uint16_t DwarfVersion) {
enum HeaderFlagMask {
#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
#include "llvm/BinaryFormat/Dwarf.def"
};
Asm->OutStreamer->AddComment("Macro information version");
- Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
- // We emit the line offset flag unconditionally here, since line offset should
- // be mostly present.
- if (Asm->isDwarf64()) {
- Asm->OutStreamer->AddComment("Flags: 64 bit, debug_line_offset present");
- Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
- } else {
- Asm->OutStreamer->AddComment("Flags: 32 bit, debug_line_offset present");
- Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
- }
+ Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
+ // We emit the line offset flag unconditionally here, since line offset should
+ // be mostly present.
+ if (Asm->isDwarf64()) {
+ Asm->OutStreamer->AddComment("Flags: 64 bit, debug_line_offset present");
+ Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
+ } else {
+ Asm->OutStreamer->AddComment("Flags: 32 bit, debug_line_offset present");
+ Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
+ }
Asm->OutStreamer->AddComment("debug_line_offset");
- if (DD.useSplitDwarf())
- Asm->emitDwarfLengthOrOffset(0);
- else
- Asm->emitDwarfSymbolReference(CU.getLineTableStartSym());
+ if (DD.useSplitDwarf())
+ Asm->emitDwarfLengthOrOffset(0);
+ else
+ Asm->emitDwarfSymbolReference(CU.getLineTableStartSym());
}
void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U) {
@@ -3023,62 +3023,62 @@ void DwarfDebug::emitMacro(DIMacro &M) {
StringRef Name = M.getName();
StringRef Value = M.getValue();
- // There should be one space between the macro name and the macro value in
- // define entries. In undef entries, only the macro name is emitted.
- std::string Str = Value.empty() ? Name.str() : (Name + " " + Value).str();
-
- if (UseDebugMacroSection) {
- if (getDwarfVersion() >= 5) {
- unsigned Type = M.getMacinfoType() == dwarf::DW_MACINFO_define
- ? dwarf::DW_MACRO_define_strx
- : dwarf::DW_MACRO_undef_strx;
- Asm->OutStreamer->AddComment(dwarf::MacroString(Type));
- Asm->emitULEB128(Type);
- Asm->OutStreamer->AddComment("Line Number");
- Asm->emitULEB128(M.getLine());
- Asm->OutStreamer->AddComment("Macro String");
- Asm->emitULEB128(
- InfoHolder.getStringPool().getIndexedEntry(*Asm, Str).getIndex());
- } else {
- unsigned Type = M.getMacinfoType() == dwarf::DW_MACINFO_define
- ? dwarf::DW_MACRO_GNU_define_indirect
- : dwarf::DW_MACRO_GNU_undef_indirect;
- Asm->OutStreamer->AddComment(dwarf::GnuMacroString(Type));
- Asm->emitULEB128(Type);
- Asm->OutStreamer->AddComment("Line Number");
- Asm->emitULEB128(M.getLine());
- Asm->OutStreamer->AddComment("Macro String");
- Asm->emitDwarfSymbolReference(
- InfoHolder.getStringPool().getEntry(*Asm, Str).getSymbol());
- }
+ // There should be one space between the macro name and the macro value in
+ // define entries. In undef entries, only the macro name is emitted.
+ std::string Str = Value.empty() ? Name.str() : (Name + " " + Value).str();
+
+ if (UseDebugMacroSection) {
+ if (getDwarfVersion() >= 5) {
+ unsigned Type = M.getMacinfoType() == dwarf::DW_MACINFO_define
+ ? dwarf::DW_MACRO_define_strx
+ : dwarf::DW_MACRO_undef_strx;
+ Asm->OutStreamer->AddComment(dwarf::MacroString(Type));
+ Asm->emitULEB128(Type);
+ Asm->OutStreamer->AddComment("Line Number");
+ Asm->emitULEB128(M.getLine());
+ Asm->OutStreamer->AddComment("Macro String");
+ Asm->emitULEB128(
+ InfoHolder.getStringPool().getIndexedEntry(*Asm, Str).getIndex());
+ } else {
+ unsigned Type = M.getMacinfoType() == dwarf::DW_MACINFO_define
+ ? dwarf::DW_MACRO_GNU_define_indirect
+ : dwarf::DW_MACRO_GNU_undef_indirect;
+ Asm->OutStreamer->AddComment(dwarf::GnuMacroString(Type));
+ Asm->emitULEB128(Type);
+ Asm->OutStreamer->AddComment("Line Number");
+ Asm->emitULEB128(M.getLine());
+ Asm->OutStreamer->AddComment("Macro String");
+ Asm->emitDwarfSymbolReference(
+ InfoHolder.getStringPool().getEntry(*Asm, Str).getSymbol());
+ }
} else {
Asm->OutStreamer->AddComment(dwarf::MacinfoString(M.getMacinfoType()));
Asm->emitULEB128(M.getMacinfoType());
Asm->OutStreamer->AddComment("Line Number");
Asm->emitULEB128(M.getLine());
Asm->OutStreamer->AddComment("Macro String");
- Asm->OutStreamer->emitBytes(Str);
+ Asm->OutStreamer->emitBytes(Str);
Asm->emitInt8('\0');
}
}
void DwarfDebug::emitMacroFileImpl(
- DIMacroFile &MF, DwarfCompileUnit &U, unsigned StartFile, unsigned EndFile,
+ DIMacroFile &MF, DwarfCompileUnit &U, unsigned StartFile, unsigned EndFile,
StringRef (*MacroFormToString)(unsigned Form)) {
Asm->OutStreamer->AddComment(MacroFormToString(StartFile));
Asm->emitULEB128(StartFile);
Asm->OutStreamer->AddComment("Line Number");
- Asm->emitULEB128(MF.getLine());
+ Asm->emitULEB128(MF.getLine());
Asm->OutStreamer->AddComment("File Number");
- DIFile &F = *MF.getFile();
- if (useSplitDwarf())
- Asm->emitULEB128(getDwoLineTable(U)->getFile(
- F.getDirectory(), F.getFilename(), getMD5AsBytes(&F),
- Asm->OutContext.getDwarfVersion(), F.getSource()));
- else
- Asm->emitULEB128(U.getOrCreateSourceID(&F));
- handleMacroNodes(MF.getElements(), U);
+ DIFile &F = *MF.getFile();
+ if (useSplitDwarf())
+ Asm->emitULEB128(getDwoLineTable(U)->getFile(
+ F.getDirectory(), F.getFilename(), getMD5AsBytes(&F),
+ Asm->OutContext.getDwarfVersion(), F.getSource()));
+ else
+ Asm->emitULEB128(U.getOrCreateSourceID(&F));
+ handleMacroNodes(MF.getElements(), U);
Asm->OutStreamer->AddComment(MacroFormToString(EndFile));
Asm->emitULEB128(EndFile);
}
@@ -3087,10 +3087,10 @@ void DwarfDebug::emitMacroFile(DIMacroFile &F, DwarfCompileUnit &U) {
// DWARFv5 macro and DWARFv4 macinfo share some common encodings,
// so for readibility/uniformity, We are explicitly emitting those.
assert(F.getMacinfoType() == dwarf::DW_MACINFO_start_file);
- if (UseDebugMacroSection)
- emitMacroFileImpl(
- F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
- (getDwarfVersion() >= 5) ? dwarf::MacroString : dwarf::GnuMacroString);
+ if (UseDebugMacroSection)
+ emitMacroFileImpl(
+ F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
+ (getDwarfVersion() >= 5) ? dwarf::MacroString : dwarf::GnuMacroString);
else
emitMacroFileImpl(F, U, dwarf::DW_MACINFO_start_file,
dwarf::DW_MACINFO_end_file, dwarf::MacinfoString);
@@ -3107,8 +3107,8 @@ void DwarfDebug::emitDebugMacinfoImpl(MCSection *Section) {
continue;
Asm->OutStreamer->SwitchSection(Section);
Asm->OutStreamer->emitLabel(U.getMacroLabelBegin());
- if (UseDebugMacroSection)
- emitMacroHeader(Asm, *this, U, getDwarfVersion());
+ if (UseDebugMacroSection)
+ emitMacroHeader(Asm, *this, U, getDwarfVersion());
handleMacroNodes(Macros, U);
Asm->OutStreamer->AddComment("End Of Macro List Mark");
Asm->emitInt8(0);
@@ -3118,14 +3118,14 @@ void DwarfDebug::emitDebugMacinfoImpl(MCSection *Section) {
/// Emit macros into a debug macinfo/macro section.
void DwarfDebug::emitDebugMacinfo() {
auto &ObjLower = Asm->getObjFileLowering();
- emitDebugMacinfoImpl(UseDebugMacroSection
+ emitDebugMacinfoImpl(UseDebugMacroSection
? ObjLower.getDwarfMacroSection()
: ObjLower.getDwarfMacinfoSection());
}
void DwarfDebug::emitDebugMacinfoDWO() {
auto &ObjLower = Asm->getObjFileLowering();
- emitDebugMacinfoImpl(UseDebugMacroSection
+ emitDebugMacinfoImpl(UseDebugMacroSection
? ObjLower.getDwarfMacroDWOSection()
: ObjLower.getDwarfMacinfoDWOSection());
}
@@ -3212,7 +3212,7 @@ MCDwarfDwoLineTable *DwarfDebug::getDwoLineTable(const DwarfCompileUnit &CU) {
const DICompileUnit *DIUnit = CU.getCUNode();
SplitTypeUnitFileTable.maybeSetRootFile(
DIUnit->getDirectory(), DIUnit->getFilename(),
- getMD5AsBytes(DIUnit->getFile()), DIUnit->getSource());
+ getMD5AsBytes(DIUnit->getFile()), DIUnit->getSource());
return &SplitTypeUnitFileTable;
}
@@ -3315,14 +3315,14 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU,
DwarfDebug::NonTypeUnitContext::NonTypeUnitContext(DwarfDebug *DD)
: DD(DD),
- TypeUnitsUnderConstruction(std::move(DD->TypeUnitsUnderConstruction)), AddrPoolUsed(DD->AddrPool.hasBeenUsed()) {
+ TypeUnitsUnderConstruction(std::move(DD->TypeUnitsUnderConstruction)), AddrPoolUsed(DD->AddrPool.hasBeenUsed()) {
DD->TypeUnitsUnderConstruction.clear();
- DD->AddrPool.resetUsedFlag();
+ DD->AddrPool.resetUsedFlag();
}
DwarfDebug::NonTypeUnitContext::~NonTypeUnitContext() {
DD->TypeUnitsUnderConstruction = std::move(TypeUnitsUnderConstruction);
- DD->AddrPool.resetUsedFlag(AddrPoolUsed);
+ DD->AddrPool.resetUsedFlag(AddrPoolUsed);
}
DwarfDebug::NonTypeUnitContext DwarfDebug::enterNonTypeUnitContext() {
@@ -3387,15 +3387,15 @@ uint16_t DwarfDebug::getDwarfVersion() const {
return Asm->OutStreamer->getContext().getDwarfVersion();
}
-dwarf::Form DwarfDebug::getDwarfSectionOffsetForm() const {
- if (Asm->getDwarfVersion() >= 4)
- return dwarf::Form::DW_FORM_sec_offset;
- assert((!Asm->isDwarf64() || (Asm->getDwarfVersion() == 3)) &&
- "DWARF64 is not defined prior DWARFv3");
- return Asm->isDwarf64() ? dwarf::Form::DW_FORM_data8
- : dwarf::Form::DW_FORM_data4;
-}
-
+dwarf::Form DwarfDebug::getDwarfSectionOffsetForm() const {
+ if (Asm->getDwarfVersion() >= 4)
+ return dwarf::Form::DW_FORM_sec_offset;
+ assert((!Asm->isDwarf64() || (Asm->getDwarfVersion() == 3)) &&
+ "DWARF64 is not defined prior DWARFv3");
+ return Asm->isDwarf64() ? dwarf::Form::DW_FORM_data8
+ : dwarf::Form::DW_FORM_data4;
+}
+
const MCSymbol *DwarfDebug::getSectionLabel(const MCSection *S) {
return SectionLabels.find(S)->second;
}
@@ -3404,20 +3404,20 @@ void DwarfDebug::insertSectionLabel(const MCSymbol *S) {
if (useSplitDwarf() || getDwarfVersion() >= 5)
AddrPool.getIndex(S);
}
-
-Optional<MD5::MD5Result> DwarfDebug::getMD5AsBytes(const DIFile *File) const {
- assert(File);
- if (getDwarfVersion() < 5)
- return None;
- Optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
- if (!Checksum || Checksum->Kind != DIFile::CSK_MD5)
- return None;
-
- // Convert the string checksum to an MD5Result for the streamer.
- // The verifier validates the checksum so we assume it's okay.
- // An MD5 checksum is 16 bytes.
- std::string ChecksumString = fromHex(Checksum->Value);
- MD5::MD5Result CKMem;
- std::copy(ChecksumString.begin(), ChecksumString.end(), CKMem.Bytes.data());
- return CKMem;
-}
+
+Optional<MD5::MD5Result> DwarfDebug::getMD5AsBytes(const DIFile *File) const {
+ assert(File);
+ if (getDwarfVersion() < 5)
+ return None;
+ Optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
+ if (!Checksum || Checksum->Kind != DIFile::CSK_MD5)
+ return None;
+
+ // Convert the string checksum to an MD5Result for the streamer.
+ // The verifier validates the checksum so we assume it's okay.
+ // An MD5 checksum is 16 bytes.
+ std::string ChecksumString = fromHex(Checksum->Value);
+ MD5::MD5Result CKMem;
+ std::copy(ChecksumString.begin(), ChecksumString.end(), CKMem.Bytes.data());
+ return CKMem;
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfDebug.h b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfDebug.h
index a5380addbb..df19ef4588 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -114,7 +114,7 @@ public:
///
/// Variables that have been optimized out use none of these fields.
class DbgVariable : public DbgEntity {
- /// Index of the entry list in DebugLocs.
+ /// Index of the entry list in DebugLocs.
unsigned DebugLocListIndex = ~0u;
/// DW_OP_LLVM_tag_offset value from DebugLocs.
Optional<uint8_t> DebugLocListTagOffset;
@@ -372,23 +372,23 @@ class DwarfDebug : public DebugHandlerBase {
/// Generate DWARF v4 type units.
bool GenerateTypeUnits;
- /// Emit a .debug_macro section instead of .debug_macinfo.
- bool UseDebugMacroSection;
-
- /// Avoid using DW_OP_convert due to consumer incompatibilities.
- bool EnableOpConvert;
-
-public:
- enum class MinimizeAddrInV5 {
- Default,
- Disabled,
- Ranges,
- };
-
-private:
- /// Force the use of DW_AT_ranges even for single-entry range lists.
- MinimizeAddrInV5 MinimizeAddr = MinimizeAddrInV5::Disabled;
-
+ /// Emit a .debug_macro section instead of .debug_macinfo.
+ bool UseDebugMacroSection;
+
+ /// Avoid using DW_OP_convert due to consumer incompatibilities.
+ bool EnableOpConvert;
+
+public:
+ enum class MinimizeAddrInV5 {
+ Default,
+ Disabled,
+ Ranges,
+ };
+
+private:
+ /// Force the use of DW_AT_ranges even for single-entry range lists.
+ MinimizeAddrInV5 MinimizeAddr = MinimizeAddrInV5::Disabled;
+
/// DWARF5 Experimental Options
/// @{
AccelTableKind TheAccelTableKind;
@@ -426,9 +426,9 @@ private:
bool SingleCU;
bool IsDarwin;
- /// Map for tracking Fortran deferred CHARACTER lengths.
- DenseMap<const DIStringType *, unsigned> StringTypeLocMap;
-
+ /// Map for tracking Fortran deferred CHARACTER lengths.
+ DenseMap<const DIStringType *, unsigned> StringTypeLocMap;
+
AddressPool AddrPool;
/// Accelerator tables.
@@ -612,8 +612,8 @@ private:
/// function that describe the same variable. If the resulting
/// list has only one entry that is valid for entire variable's
/// scope return true.
- bool buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
- const DbgValueHistoryMap::Entries &Entries);
+ bool buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
+ const DbgValueHistoryMap::Entries &Entries);
/// Collect variable information from the side table maintained by MF.
void collectVariableInfoFromMFTable(DwarfCompileUnit &TheCU,
@@ -635,13 +635,13 @@ public:
//===--------------------------------------------------------------------===//
// Main entry points.
//
- DwarfDebug(AsmPrinter *A);
+ DwarfDebug(AsmPrinter *A);
~DwarfDebug() override;
/// Emit all Dwarf sections that should come prior to the
/// content.
- void beginModule(Module *M) override;
+ void beginModule(Module *M) override;
/// Emit all Dwarf sections that should come after the content.
void endModule() override;
@@ -663,7 +663,7 @@ public:
class NonTypeUnitContext {
DwarfDebug *DD;
decltype(DwarfDebug::TypeUnitsUnderConstruction) TypeUnitsUnderConstruction;
- bool AddrPoolUsed;
+ bool AddrPoolUsed;
friend class DwarfDebug;
NonTypeUnitContext(DwarfDebug *DD);
public:
@@ -700,12 +700,12 @@ public:
/// Returns whether ranges section should be emitted.
bool useRangesSection() const { return UseRangesSection; }
- /// Returns whether range encodings should be used for single entry range
- /// lists.
- bool alwaysUseRanges() const {
- return MinimizeAddr == MinimizeAddrInV5::Ranges;
- }
-
+ /// Returns whether range encodings should be used for single entry range
+ /// lists.
+ bool alwaysUseRanges() const {
+ return MinimizeAddr == MinimizeAddrInV5::Ranges;
+ }
+
/// Returns whether to use sections as labels rather than temp symbols.
bool useSectionsAsReferences() const {
return UseSectionsAsReferences;
@@ -744,21 +744,21 @@ public:
return EmitDebugEntryValues;
}
- bool useOpConvert() const {
- return EnableOpConvert;
- }
-
+ bool useOpConvert() const {
+ return EnableOpConvert;
+ }
+
bool shareAcrossDWOCUs() const;
/// Returns the Dwarf Version.
uint16_t getDwarfVersion() const;
- /// Returns a suitable DWARF form to represent a section offset, i.e.
- /// * DW_FORM_sec_offset for DWARF version >= 4;
- /// * DW_FORM_data8 for 64-bit DWARFv3;
- /// * DW_FORM_data4 for 32-bit DWARFv3 and DWARFv2.
- dwarf::Form getDwarfSectionOffsetForm() const;
-
+ /// Returns a suitable DWARF form to represent a section offset, i.e.
+ /// * DW_FORM_sec_offset for DWARF version >= 4;
+ /// * DW_FORM_data8 for 64-bit DWARFv3;
+ /// * DW_FORM_data4 for 32-bit DWARFv3 and DWARFv2.
+ dwarf::Form getDwarfSectionOffsetForm() const;
+
/// Returns the previous CU that was being updated
const DwarfCompileUnit *getPrevCU() const { return PrevCU; }
void setPrevCU(const DwarfCompileUnit *PrevCU) { this->PrevCU = PrevCU; }
@@ -803,16 +803,16 @@ public:
return CUDieMap.lookup(Die);
}
- unsigned getStringTypeLoc(const DIStringType *ST) const {
- return StringTypeLocMap.lookup(ST);
- }
-
- void addStringTypeLoc(const DIStringType *ST, unsigned Loc) {
- assert(ST);
- if (Loc)
- StringTypeLocMap[ST] = Loc;
- }
-
+ unsigned getStringTypeLoc(const DIStringType *ST) const {
+ return StringTypeLocMap.lookup(ST);
+ }
+
+ void addStringTypeLoc(const DIStringType *ST, unsigned Loc) {
+ assert(ST);
+ if (Loc)
+ StringTypeLocMap[ST] = Loc;
+ }
+
/// \defgroup DebuggerTuning Predicates to tune DWARF for a given debugger.
///
/// Returns whether we are "tuning" for a given debugger.
@@ -828,10 +828,10 @@ public:
static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
const DbgValueLoc &Value,
DwarfExpression &DwarfExpr);
-
- /// If the \p File has an MD5 checksum, return it as an MD5Result
- /// allocated in the MCContext.
- Optional<MD5::MD5Result> getMD5AsBytes(const DIFile *File) const;
+
+ /// If the \p File has an MD5 checksum, return it as an MD5Result
+ /// allocated in the MCContext.
+ Optional<MD5::MD5Result> getMD5AsBytes(const DIFile *File) const;
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfException.h b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfException.h
index 4ff07151ab..b19b436538 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfException.h
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfException.h
@@ -92,20 +92,20 @@ public:
/// Gather and emit post-function exception information.
void endFunction(const MachineFunction *) override;
};
-
-class LLVM_LIBRARY_VISIBILITY AIXException : public DwarfCFIExceptionBase {
- /// This is AIX's compat unwind section, which unwinder would use
- /// to find the location of LSDA area and personality rountine.
- void emitExceptionInfoTable(const MCSymbol *LSDA, const MCSymbol *PerSym);
-
-public:
- AIXException(AsmPrinter *A);
-
- void endModule() override {}
- void beginFunction(const MachineFunction *MF) override {}
-
- void endFunction(const MachineFunction *MF) override;
-};
+
+class LLVM_LIBRARY_VISIBILITY AIXException : public DwarfCFIExceptionBase {
+ /// This is AIX's compat unwind section, which unwinder would use
+ /// to find the location of LSDA area and personality rountine.
+ void emitExceptionInfoTable(const MCSymbol *LSDA, const MCSymbol *PerSym);
+
+public:
+ AIXException(AsmPrinter *A);
+
+ void endModule() override {}
+ void beginFunction(const MachineFunction *MF) override {}
+
+ void endFunction(const MachineFunction *MF) override;
+};
} // End of namespace llvm
#endif
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index 83d4169397..59ad7646ce 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -17,14 +17,14 @@
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/Register.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
-#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DataLayout.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
using namespace llvm;
-#define DEBUG_TYPE "dwarfdebug"
-
+#define DEBUG_TYPE "dwarfdebug"
+
void DwarfExpression::emitConstu(uint64_t Value) {
if (Value < 32)
emitOp(dwarf::DW_OP_lit0 + Value);
@@ -97,8 +97,8 @@ void DwarfExpression::addAnd(unsigned Mask) {
}
bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
- llvm::Register MachineReg,
- unsigned MaxSize) {
+ llvm::Register MachineReg,
+ unsigned MaxSize) {
if (!llvm::Register::isPhysicalRegister(MachineReg)) {
if (isFrameRegister(TRI, MachineReg)) {
DwarfRegs.push_back(Register::createRegister(-1, nullptr));
@@ -220,36 +220,36 @@ void DwarfExpression::addUnsignedConstant(const APInt &Value) {
}
}
-void DwarfExpression::addConstantFP(const APFloat &APF, const AsmPrinter &AP) {
- assert(isImplicitLocation() || isUnknownLocation());
- APInt API = APF.bitcastToAPInt();
- int NumBytes = API.getBitWidth() / 8;
- if (NumBytes == 4 /*float*/ || NumBytes == 8 /*double*/) {
- // FIXME: Add support for `long double`.
- emitOp(dwarf::DW_OP_implicit_value);
- emitUnsigned(NumBytes /*Size of the block in bytes*/);
-
- // The loop below is emitting the value starting at least significant byte,
- // so we need to perform a byte-swap to get the byte order correct in case
- // of a big-endian target.
- if (AP.getDataLayout().isBigEndian())
- API = API.byteSwap();
-
- for (int i = 0; i < NumBytes; ++i) {
- emitData1(API.getZExtValue() & 0xFF);
- API = API.lshr(8);
- }
-
- return;
- }
- LLVM_DEBUG(
- dbgs() << "Skipped DW_OP_implicit_value creation for ConstantFP of size: "
- << API.getBitWidth() << " bits\n");
-}
-
+void DwarfExpression::addConstantFP(const APFloat &APF, const AsmPrinter &AP) {
+ assert(isImplicitLocation() || isUnknownLocation());
+ APInt API = APF.bitcastToAPInt();
+ int NumBytes = API.getBitWidth() / 8;
+ if (NumBytes == 4 /*float*/ || NumBytes == 8 /*double*/) {
+ // FIXME: Add support for `long double`.
+ emitOp(dwarf::DW_OP_implicit_value);
+ emitUnsigned(NumBytes /*Size of the block in bytes*/);
+
+ // The loop below is emitting the value starting at least significant byte,
+ // so we need to perform a byte-swap to get the byte order correct in case
+ // of a big-endian target.
+ if (AP.getDataLayout().isBigEndian())
+ API = API.byteSwap();
+
+ for (int i = 0; i < NumBytes; ++i) {
+ emitData1(API.getZExtValue() & 0xFF);
+ API = API.lshr(8);
+ }
+
+ return;
+ }
+ LLVM_DEBUG(
+ dbgs() << "Skipped DW_OP_implicit_value creation for ConstantFP of size: "
+ << API.getBitWidth() << " bits\n");
+}
+
bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
DIExpressionCursor &ExprCursor,
- llvm::Register MachineReg,
+ llvm::Register MachineReg,
unsigned FragmentOffsetInBits) {
auto Fragment = ExprCursor.getFragmentInfo();
if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) {
@@ -526,7 +526,7 @@ void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
case dwarf::DW_OP_not:
case dwarf::DW_OP_dup:
case dwarf::DW_OP_push_object_address:
- case dwarf::DW_OP_over:
+ case dwarf::DW_OP_over:
emitOp(OpNum);
break;
case dwarf::DW_OP_deref:
@@ -542,15 +542,15 @@ void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
assert(!isRegisterLocation());
emitConstu(Op->getArg(0));
break;
- case dwarf::DW_OP_consts:
- assert(!isRegisterLocation());
- emitOp(dwarf::DW_OP_consts);
- emitSigned(Op->getArg(0));
- break;
+ case dwarf::DW_OP_consts:
+ assert(!isRegisterLocation());
+ emitOp(dwarf::DW_OP_consts);
+ emitSigned(Op->getArg(0));
+ break;
case dwarf::DW_OP_LLVM_convert: {
unsigned BitSize = Op->getArg(0);
dwarf::TypeKind Encoding = static_cast<dwarf::TypeKind>(Op->getArg(1));
- if (DwarfVersion >= 5 && CU.getDwarfDebug().useOpConvert()) {
+ if (DwarfVersion >= 5 && CU.getDwarfDebug().useOpConvert()) {
emitOp(dwarf::DW_OP_convert);
// If targeting a location-list; simply emit the index into the raw
// byte stream as ULEB128, DwarfDebug::emitDebugLocEntry has been
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfExpression.h b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 6d73207168..8fca9f5a63 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -218,7 +218,7 @@ protected:
/// Return whether the given machine register is the frame register in the
/// current function.
virtual bool isFrameRegister(const TargetRegisterInfo &TRI,
- llvm::Register MachineReg) = 0;
+ llvm::Register MachineReg) = 0;
/// Emit a DW_OP_reg operation. Note that this is only legal inside a DWARF
/// register location description.
@@ -245,7 +245,7 @@ protected:
/// multiple subregisters that alias the register.
///
/// \return false if no DWARF register exists for MachineReg.
- bool addMachineReg(const TargetRegisterInfo &TRI, llvm::Register MachineReg,
+ bool addMachineReg(const TargetRegisterInfo &TRI, llvm::Register MachineReg,
unsigned MaxSize = ~1U);
/// Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
@@ -299,9 +299,9 @@ public:
/// Emit an unsigned constant.
void addUnsignedConstant(const APInt &Value);
- /// Emit an floating point constant.
- void addConstantFP(const APFloat &Value, const AsmPrinter &AP);
-
+ /// Emit an floating point constant.
+ void addConstantFP(const APFloat &Value, const AsmPrinter &AP);
+
/// Lock this down to become a memory location description.
void setMemoryLocationKind() {
assert(isUnknownLocation());
@@ -325,8 +325,8 @@ public:
/// \return false if no DWARF register exists
/// for MachineReg.
bool addMachineRegExpression(const TargetRegisterInfo &TRI,
- DIExpressionCursor &Expr,
- llvm::Register MachineReg,
+ DIExpressionCursor &Expr,
+ llvm::Register MachineReg,
unsigned FragmentOffsetInBits = 0);
/// Begin emission of an entry value dwarf operation. The entry value's
@@ -389,7 +389,7 @@ class DebugLocDwarfExpression final : public DwarfExpression {
void commitTemporaryBuffer() override;
bool isFrameRegister(const TargetRegisterInfo &TRI,
- llvm::Register MachineReg) override;
+ llvm::Register MachineReg) override;
public:
DebugLocDwarfExpression(unsigned DwarfVersion, BufferByteStreamer &BS,
@@ -419,7 +419,7 @@ class DIEDwarfExpression final : public DwarfExpression {
void commitTemporaryBuffer() override;
bool isFrameRegister(const TargetRegisterInfo &TRI,
- llvm::Register MachineReg) override;
+ llvm::Register MachineReg) override;
public:
DIEDwarfExpression(const AsmPrinter &AP, DwarfCompileUnit &CU, DIELoc &DIE);
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfFile.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfFile.cpp
index b21ac54386..838e1c9a10 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfFile.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfFile.cpp
@@ -12,7 +12,7 @@
#include "DwarfUnit.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Metadata.h"
#include "llvm/MC/MCStreamer.h"
#include <algorithm>
#include <cstdint>
@@ -58,7 +58,7 @@ void DwarfFile::emitUnit(DwarfUnit *TheU, bool UseOffsets) {
// Compute the size and offset for each DIE.
void DwarfFile::computeSizeAndOffsets() {
// Offset from the first CU in the debug info section is 0 initially.
- uint64_t SecOffset = 0;
+ uint64_t SecOffset = 0;
// Iterate over each compile unit and set the size and offsets for each
// DIE within each compile unit. All offsets are CU relative.
@@ -74,15 +74,15 @@ void DwarfFile::computeSizeAndOffsets() {
TheU->setDebugSectionOffset(SecOffset);
SecOffset += computeSizeAndOffsetsForUnit(TheU.get());
}
- if (SecOffset > UINT32_MAX && !Asm->isDwarf64())
- report_fatal_error("The generated debug information is too large "
- "for the 32-bit DWARF format.");
+ if (SecOffset > UINT32_MAX && !Asm->isDwarf64())
+ report_fatal_error("The generated debug information is too large "
+ "for the 32-bit DWARF format.");
}
unsigned DwarfFile::computeSizeAndOffsetsForUnit(DwarfUnit *TheU) {
// CU-relative offset is reset to 0 here.
- unsigned Offset = Asm->getUnitLengthFieldByteSize() + // Length of Unit Info
- TheU->getHeaderSize(); // Unit-specific headers
+ unsigned Offset = Asm->getUnitLengthFieldByteSize() + // Length of Unit Info
+ TheU->getHeaderSize(); // Unit-specific headers
// The return value here is CU-relative, after laying out
// all of the CU DIE.
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfFile.h b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfFile.h
index 4120e4d668..79a6ce7801 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfFile.h
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfFile.h
@@ -25,12 +25,12 @@ class AsmPrinter;
class DbgEntity;
class DbgVariable;
class DbgLabel;
-class DINode;
+class DINode;
class DwarfCompileUnit;
class DwarfUnit;
class LexicalScope;
class MCSection;
-class MDNode;
+class MDNode;
// Data structure to hold a range for range lists.
struct RangeSpan {
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp
index 899fdade48..a876f8ccac 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp
@@ -56,13 +56,13 @@ void DwarfStringPool::emitStringOffsetsTableHeader(AsmPrinter &Asm,
if (getNumIndexedStrings() == 0)
return;
Asm.OutStreamer->SwitchSection(Section);
- unsigned EntrySize = Asm.getDwarfOffsetByteSize();
+ unsigned EntrySize = Asm.getDwarfOffsetByteSize();
// We are emitting the header for a contribution to the string offsets
// table. The header consists of an entry with the contribution's
// size (not including the size of the length field), the DWARF version and
// 2 bytes of padding.
- Asm.emitDwarfUnitLength(getNumIndexedStrings() * EntrySize + 4,
- "Length of String Offsets Set");
+ Asm.emitDwarfUnitLength(getNumIndexedStrings() * EntrySize + 4,
+ "Length of String Offsets Set");
Asm.emitInt16(Asm.getDwarfVersion());
Asm.emitInt16(0);
// Define the symbol that marks the start of the contribution. It is
@@ -118,7 +118,7 @@ void DwarfStringPool::emit(AsmPrinter &Asm, MCSection *StrSection,
}
Asm.OutStreamer->SwitchSection(OffsetSection);
- unsigned size = Asm.getDwarfOffsetByteSize();
+ unsigned size = Asm.getDwarfOffsetByteSize();
for (const auto &Entry : Entries)
if (UseRelativeOffsets)
Asm.emitDwarfStringOffset(Entry->getValue());
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfStringPool.h b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfStringPool.h
index 0759123d0d..79b5df89e3 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfStringPool.h
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfStringPool.h
@@ -28,7 +28,7 @@ class DwarfStringPool {
StringMap<EntryTy, BumpPtrAllocator &> Pool;
StringRef Prefix;
- uint64_t NumBytes = 0;
+ uint64_t NumBytes = 0;
unsigned NumIndexedStrings = 0;
bool ShouldCreateSymbols;
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index 61f2eafa87..118b5fcc3b 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -83,14 +83,14 @@ unsigned DIEDwarfExpression::getTemporaryBufferSize() {
void DIEDwarfExpression::commitTemporaryBuffer() { OutDIE.takeValues(TmpDIE); }
bool DIEDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI,
- llvm::Register MachineReg) {
+ llvm::Register MachineReg) {
return MachineReg == TRI.getFrameRegister(*AP.MF);
}
DwarfUnit::DwarfUnit(dwarf::Tag UnitTag, const DICompileUnit *Node,
AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU)
- : DIEUnit(UnitTag), CUNode(Node), Asm(A), DD(DW), DU(DWU),
- IndexTyDie(nullptr) {}
+ : DIEUnit(UnitTag), CUNode(Node), Asm(A), DD(DW), DU(DWU),
+ IndexTyDie(nullptr) {}
DwarfTypeUnit::DwarfTypeUnit(DwarfCompileUnit &CU, AsmPrinter *A,
DwarfDebug *DW, DwarfFile *DWU,
@@ -299,7 +299,7 @@ void DwarfUnit::addLabel(DIELoc &Die, dwarf::Form Form, const MCSymbol *Label) {
void DwarfUnit::addSectionOffset(DIE &Die, dwarf::Attribute Attribute,
uint64_t Integer) {
- addUInt(Die, Attribute, DD->getDwarfSectionOffsetForm(), Integer);
+ addUInt(Die, Attribute, DD->getDwarfSectionOffsetForm(), Integer);
}
unsigned DwarfTypeUnit::getOrCreateSourceID(const DIFile *File) {
@@ -310,9 +310,9 @@ unsigned DwarfTypeUnit::getOrCreateSourceID(const DIFile *File) {
// This is a split type unit that needs a line table.
addSectionOffset(getUnitDie(), dwarf::DW_AT_stmt_list, 0);
}
- return SplitLineTable->getFile(
- File->getDirectory(), File->getFilename(), DD->getMD5AsBytes(File),
- Asm->OutContext.getDwarfVersion(), File->getSource());
+ return SplitLineTable->getFile(
+ File->getDirectory(), File->getFilename(), DD->getMD5AsBytes(File),
+ Asm->OutContext.getDwarfVersion(), File->getSource());
}
void DwarfUnit::addOpAddress(DIELoc &Die, const MCSymbol *Sym) {
@@ -330,7 +330,7 @@ void DwarfUnit::addOpAddress(DIELoc &Die, const MCSymbol *Sym) {
}
addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
- addLabel(Die, dwarf::DW_FORM_addr, Sym);
+ addLabel(Die, dwarf::DW_FORM_addr, Sym);
}
void DwarfUnit::addLabelDelta(DIE &Die, dwarf::Attribute Attribute,
@@ -445,7 +445,7 @@ void DwarfUnit::addConstantValue(DIE &Die, const ConstantInt *CI,
}
void DwarfUnit::addConstantValue(DIE &Die, uint64_t Val, const DIType *Ty) {
- addConstantValue(Die, DD->isUnsignedDIType(Ty), Val);
+ addConstantValue(Die, DD->isUnsignedDIType(Ty), Val);
}
void DwarfUnit::addConstantValue(DIE &Die, bool Unsigned, uint64_t Val) {
@@ -456,7 +456,7 @@ void DwarfUnit::addConstantValue(DIE &Die, bool Unsigned, uint64_t Val) {
}
void DwarfUnit::addConstantValue(DIE &Die, const APInt &Val, const DIType *Ty) {
- addConstantValue(Die, Val, DD->isUnsignedDIType(Ty));
+ addConstantValue(Die, Val, DD->isUnsignedDIType(Ty));
}
void DwarfUnit::addConstantValue(DIE &Die, const APInt &Val, bool Unsigned) {
@@ -553,8 +553,8 @@ DIE *DwarfUnit::createTypeDIE(const DIScope *Context, DIE &ContextDIE,
if (auto *BT = dyn_cast<DIBasicType>(Ty))
constructTypeDIE(TyDIE, BT);
- else if (auto *ST = dyn_cast<DIStringType>(Ty))
- constructTypeDIE(TyDIE, ST);
+ else if (auto *ST = dyn_cast<DIStringType>(Ty))
+ constructTypeDIE(TyDIE, ST);
else if (auto *STy = dyn_cast<DISubroutineType>(Ty))
constructTypeDIE(TyDIE, STy);
else if (auto *CTy = dyn_cast<DICompositeType>(Ty)) {
@@ -673,9 +673,9 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIBasicType *BTy) {
if (BTy->getTag() == dwarf::DW_TAG_unspecified_type)
return;
- if (BTy->getTag() != dwarf::DW_TAG_string_type)
- addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
- BTy->getEncoding());
+ if (BTy->getTag() != dwarf::DW_TAG_string_type)
+ addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
+ BTy->getEncoding());
uint64_t Size = BTy->getSizeInBits() >> 3;
addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size);
@@ -686,37 +686,37 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIBasicType *BTy) {
addUInt(Buffer, dwarf::DW_AT_endianity, None, dwarf::DW_END_little);
}
-void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIStringType *STy) {
- // Get core information.
- StringRef Name = STy->getName();
- // Add name if not anonymous or intermediate type.
- if (!Name.empty())
- addString(Buffer, dwarf::DW_AT_name, Name);
-
- if (DIVariable *Var = STy->getStringLength()) {
- if (auto *VarDIE = getDIE(Var))
- addDIEEntry(Buffer, dwarf::DW_AT_string_length, *VarDIE);
- } else if (DIExpression *Expr = STy->getStringLengthExp()) {
- DIELoc *Loc = new (DIEValueAllocator) DIELoc;
- DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
- // This is to describe the memory location of the
- // length of a Fortran deferred length string, so
- // lock it down as such.
- DwarfExpr.setMemoryLocationKind();
- DwarfExpr.addExpression(Expr);
- addBlock(Buffer, dwarf::DW_AT_string_length, DwarfExpr.finalize());
- } else {
- uint64_t Size = STy->getSizeInBits() >> 3;
- addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size);
- }
-
- if (STy->getEncoding()) {
- // For eventual Unicode support.
- addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
- STy->getEncoding());
- }
-}
-
+void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIStringType *STy) {
+ // Get core information.
+ StringRef Name = STy->getName();
+ // Add name if not anonymous or intermediate type.
+ if (!Name.empty())
+ addString(Buffer, dwarf::DW_AT_name, Name);
+
+ if (DIVariable *Var = STy->getStringLength()) {
+ if (auto *VarDIE = getDIE(Var))
+ addDIEEntry(Buffer, dwarf::DW_AT_string_length, *VarDIE);
+ } else if (DIExpression *Expr = STy->getStringLengthExp()) {
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+ DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
+ // This is to describe the memory location of the
+ // length of a Fortran deferred length string, so
+ // lock it down as such.
+ DwarfExpr.setMemoryLocationKind();
+ DwarfExpr.addExpression(Expr);
+ addBlock(Buffer, dwarf::DW_AT_string_length, DwarfExpr.finalize());
+ } else {
+ uint64_t Size = STy->getSizeInBits() >> 3;
+ addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size);
+ }
+
+ if (STy->getEncoding()) {
+ // For eventual Unicode support.
+ addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
+ STy->getEncoding());
+ }
+}
+
void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy) {
// Get core information.
StringRef Name = DTy->getName();
@@ -843,11 +843,11 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
}
}
- // Add template parameters to a class, structure or union types.
- if (Tag == dwarf::DW_TAG_class_type ||
- Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type)
- addTemplateParams(Buffer, CTy->getTemplateParams());
-
+ // Add template parameters to a class, structure or union types.
+ if (Tag == dwarf::DW_TAG_class_type ||
+ Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type)
+ addTemplateParams(Buffer, CTy->getTemplateParams());
+
// Add elements to structure type.
DINodeArray Elements = CTy->getElements();
for (const auto *Element : Elements) {
@@ -867,7 +867,7 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
DIE &Variant = createAndAddDIE(dwarf::DW_TAG_variant, Buffer);
if (const ConstantInt *CI =
dyn_cast_or_null<ConstantInt>(DDTy->getDiscriminantValue())) {
- if (DD->isUnsignedDIType(Discriminator->getBaseType()))
+ if (DD->isUnsignedDIType(Discriminator->getBaseType()))
addUInt(Variant, dwarf::DW_AT_discr_value, None, CI->getZExtValue());
else
addSInt(Variant, dwarf::DW_AT_discr_value, None, CI->getSExtValue());
@@ -940,10 +940,10 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
Tag == dwarf::DW_TAG_class_type || Tag == dwarf::DW_TAG_structure_type ||
Tag == dwarf::DW_TAG_union_type) {
// Add size if non-zero (derived types might be zero-sized.)
- // Ignore the size if it's a non-enum forward decl.
+ // Ignore the size if it's a non-enum forward decl.
// TODO: Do we care about size for enum forward declarations?
- if (Size &&
- (!CTy->isForwardDecl() || Tag == dwarf::DW_TAG_enumeration_type))
+ if (Size &&
+ (!CTy->isForwardDecl() || Tag == dwarf::DW_TAG_enumeration_type))
addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size);
else if (!CTy->isForwardDecl())
// Add zero size if it is not a forward declaration.
@@ -1067,8 +1067,8 @@ DIE *DwarfUnit::getOrCreateModule(const DIModule *M) {
getOrCreateSourceID(M->getFile()));
if (M->getLineNo())
addUInt(MDie, dwarf::DW_AT_decl_line, None, M->getLineNo());
- if (M->getIsDecl())
- addFlag(MDie, dwarf::DW_AT_declaration);
+ if (M->getIsDecl())
+ addFlag(MDie, dwarf::DW_AT_declaration);
return &MDie;
}
@@ -1290,7 +1290,7 @@ void DwarfUnit::constructSubrangeDIE(DIE &Buffer, const DISubrange *SR,
if (auto *CI = SR->getCount().dyn_cast<ConstantInt*>())
Count = CI->getSExtValue();
- auto AddBoundTypeEntry = [&](dwarf::Attribute Attr,
+ auto AddBoundTypeEntry = [&](dwarf::Attribute Attr,
DISubrange::BoundType Bound) -> void {
if (auto *BV = Bound.dyn_cast<DIVariable *>()) {
if (auto *VarDIE = getDIE(BV))
@@ -1308,7 +1308,7 @@ void DwarfUnit::constructSubrangeDIE(DIE &Buffer, const DISubrange *SR,
}
};
- AddBoundTypeEntry(dwarf::DW_AT_lower_bound, SR->getLowerBound());
+ AddBoundTypeEntry(dwarf::DW_AT_lower_bound, SR->getLowerBound());
if (auto *CV = SR->getCount().dyn_cast<DIVariable*>()) {
if (auto *CountVarDIE = getDIE(CV))
@@ -1316,47 +1316,47 @@ void DwarfUnit::constructSubrangeDIE(DIE &Buffer, const DISubrange *SR,
} else if (Count != -1)
addUInt(DW_Subrange, dwarf::DW_AT_count, None, Count);
- AddBoundTypeEntry(dwarf::DW_AT_upper_bound, SR->getUpperBound());
-
- AddBoundTypeEntry(dwarf::DW_AT_byte_stride, SR->getStride());
-}
-
-void DwarfUnit::constructGenericSubrangeDIE(DIE &Buffer,
- const DIGenericSubrange *GSR,
- DIE *IndexTy) {
- DIE &DwGenericSubrange =
- createAndAddDIE(dwarf::DW_TAG_generic_subrange, Buffer);
- addDIEEntry(DwGenericSubrange, dwarf::DW_AT_type, *IndexTy);
-
- int64_t DefaultLowerBound = getDefaultLowerBound();
-
- auto AddBoundTypeEntry = [&](dwarf::Attribute Attr,
- DIGenericSubrange::BoundType Bound) -> void {
- if (auto *BV = Bound.dyn_cast<DIVariable *>()) {
- if (auto *VarDIE = getDIE(BV))
- addDIEEntry(DwGenericSubrange, Attr, *VarDIE);
- } else if (auto *BE = Bound.dyn_cast<DIExpression *>()) {
- if (BE->isSignedConstant()) {
- if (Attr != dwarf::DW_AT_lower_bound || DefaultLowerBound == -1 ||
- static_cast<int64_t>(BE->getElement(1)) != DefaultLowerBound)
- addSInt(DwGenericSubrange, Attr, dwarf::DW_FORM_sdata,
- BE->getElement(1));
- } else {
- DIELoc *Loc = new (DIEValueAllocator) DIELoc;
- DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
- DwarfExpr.setMemoryLocationKind();
- DwarfExpr.addExpression(BE);
- addBlock(DwGenericSubrange, Attr, DwarfExpr.finalize());
- }
- }
- };
-
- AddBoundTypeEntry(dwarf::DW_AT_lower_bound, GSR->getLowerBound());
- AddBoundTypeEntry(dwarf::DW_AT_count, GSR->getCount());
- AddBoundTypeEntry(dwarf::DW_AT_upper_bound, GSR->getUpperBound());
- AddBoundTypeEntry(dwarf::DW_AT_byte_stride, GSR->getStride());
-}
-
+ AddBoundTypeEntry(dwarf::DW_AT_upper_bound, SR->getUpperBound());
+
+ AddBoundTypeEntry(dwarf::DW_AT_byte_stride, SR->getStride());
+}
+
+void DwarfUnit::constructGenericSubrangeDIE(DIE &Buffer,
+ const DIGenericSubrange *GSR,
+ DIE *IndexTy) {
+ DIE &DwGenericSubrange =
+ createAndAddDIE(dwarf::DW_TAG_generic_subrange, Buffer);
+ addDIEEntry(DwGenericSubrange, dwarf::DW_AT_type, *IndexTy);
+
+ int64_t DefaultLowerBound = getDefaultLowerBound();
+
+ auto AddBoundTypeEntry = [&](dwarf::Attribute Attr,
+ DIGenericSubrange::BoundType Bound) -> void {
+ if (auto *BV = Bound.dyn_cast<DIVariable *>()) {
+ if (auto *VarDIE = getDIE(BV))
+ addDIEEntry(DwGenericSubrange, Attr, *VarDIE);
+ } else if (auto *BE = Bound.dyn_cast<DIExpression *>()) {
+ if (BE->isSignedConstant()) {
+ if (Attr != dwarf::DW_AT_lower_bound || DefaultLowerBound == -1 ||
+ static_cast<int64_t>(BE->getElement(1)) != DefaultLowerBound)
+ addSInt(DwGenericSubrange, Attr, dwarf::DW_FORM_sdata,
+ BE->getElement(1));
+ } else {
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+ DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
+ DwarfExpr.setMemoryLocationKind();
+ DwarfExpr.addExpression(BE);
+ addBlock(DwGenericSubrange, Attr, DwarfExpr.finalize());
+ }
+ }
+ };
+
+ AddBoundTypeEntry(dwarf::DW_AT_lower_bound, GSR->getLowerBound());
+ AddBoundTypeEntry(dwarf::DW_AT_count, GSR->getCount());
+ AddBoundTypeEntry(dwarf::DW_AT_upper_bound, GSR->getUpperBound());
+ AddBoundTypeEntry(dwarf::DW_AT_byte_stride, GSR->getStride());
+}
+
DIE *DwarfUnit::getIndexTyDie() {
if (IndexTyDie)
return IndexTyDie;
@@ -1419,39 +1419,39 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
addBlock(Buffer, dwarf::DW_AT_data_location, DwarfExpr.finalize());
}
- if (DIVariable *Var = CTy->getAssociated()) {
- if (auto *VarDIE = getDIE(Var))
- addDIEEntry(Buffer, dwarf::DW_AT_associated, *VarDIE);
- } else if (DIExpression *Expr = CTy->getAssociatedExp()) {
- DIELoc *Loc = new (DIEValueAllocator) DIELoc;
- DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
- DwarfExpr.setMemoryLocationKind();
- DwarfExpr.addExpression(Expr);
- addBlock(Buffer, dwarf::DW_AT_associated, DwarfExpr.finalize());
- }
-
- if (DIVariable *Var = CTy->getAllocated()) {
- if (auto *VarDIE = getDIE(Var))
- addDIEEntry(Buffer, dwarf::DW_AT_allocated, *VarDIE);
- } else if (DIExpression *Expr = CTy->getAllocatedExp()) {
- DIELoc *Loc = new (DIEValueAllocator) DIELoc;
- DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
- DwarfExpr.setMemoryLocationKind();
- DwarfExpr.addExpression(Expr);
- addBlock(Buffer, dwarf::DW_AT_allocated, DwarfExpr.finalize());
- }
-
- if (auto *RankConst = CTy->getRankConst()) {
- addSInt(Buffer, dwarf::DW_AT_rank, dwarf::DW_FORM_sdata,
- RankConst->getSExtValue());
- } else if (auto *RankExpr = CTy->getRankExp()) {
- DIELoc *Loc = new (DIEValueAllocator) DIELoc;
- DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
- DwarfExpr.setMemoryLocationKind();
- DwarfExpr.addExpression(RankExpr);
- addBlock(Buffer, dwarf::DW_AT_rank, DwarfExpr.finalize());
- }
-
+ if (DIVariable *Var = CTy->getAssociated()) {
+ if (auto *VarDIE = getDIE(Var))
+ addDIEEntry(Buffer, dwarf::DW_AT_associated, *VarDIE);
+ } else if (DIExpression *Expr = CTy->getAssociatedExp()) {
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+ DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
+ DwarfExpr.setMemoryLocationKind();
+ DwarfExpr.addExpression(Expr);
+ addBlock(Buffer, dwarf::DW_AT_associated, DwarfExpr.finalize());
+ }
+
+ if (DIVariable *Var = CTy->getAllocated()) {
+ if (auto *VarDIE = getDIE(Var))
+ addDIEEntry(Buffer, dwarf::DW_AT_allocated, *VarDIE);
+ } else if (DIExpression *Expr = CTy->getAllocatedExp()) {
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+ DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
+ DwarfExpr.setMemoryLocationKind();
+ DwarfExpr.addExpression(Expr);
+ addBlock(Buffer, dwarf::DW_AT_allocated, DwarfExpr.finalize());
+ }
+
+ if (auto *RankConst = CTy->getRankConst()) {
+ addSInt(Buffer, dwarf::DW_AT_rank, dwarf::DW_FORM_sdata,
+ RankConst->getSExtValue());
+ } else if (auto *RankExpr = CTy->getRankExp()) {
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+ DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
+ DwarfExpr.setMemoryLocationKind();
+ DwarfExpr.addExpression(RankExpr);
+ addBlock(Buffer, dwarf::DW_AT_rank, DwarfExpr.finalize());
+ }
+
// Emit the element type.
addType(Buffer, CTy->getBaseType());
@@ -1464,19 +1464,19 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
DINodeArray Elements = CTy->getElements();
for (unsigned i = 0, N = Elements.size(); i < N; ++i) {
// FIXME: Should this really be such a loose cast?
- if (auto *Element = dyn_cast_or_null<DINode>(Elements[i])) {
+ if (auto *Element = dyn_cast_or_null<DINode>(Elements[i])) {
if (Element->getTag() == dwarf::DW_TAG_subrange_type)
constructSubrangeDIE(Buffer, cast<DISubrange>(Element), IdxTy);
- else if (Element->getTag() == dwarf::DW_TAG_generic_subrange)
- constructGenericSubrangeDIE(Buffer, cast<DIGenericSubrange>(Element),
- IdxTy);
- }
+ else if (Element->getTag() == dwarf::DW_TAG_generic_subrange)
+ constructGenericSubrangeDIE(Buffer, cast<DIGenericSubrange>(Element),
+ IdxTy);
+ }
}
}
void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
const DIType *DTy = CTy->getBaseType();
- bool IsUnsigned = DTy && DD->isUnsignedDIType(DTy);
+ bool IsUnsigned = DTy && DD->isUnsignedDIType(DTy);
if (DTy) {
if (DD->getDwarfVersion() >= 3)
addType(Buffer, DTy);
@@ -1679,11 +1679,11 @@ void DwarfUnit::emitCommonHeader(bool UseOffsets, dwarf::UnitType UT) {
StringRef Prefix = isDwoUnit() ? "debug_info_dwo_" : "debug_info_";
MCSymbol *BeginLabel = Asm->createTempSymbol(Prefix + "start");
EndLabel = Asm->createTempSymbol(Prefix + "end");
- Asm->emitDwarfUnitLength(EndLabel, BeginLabel, "Length of Unit");
+ Asm->emitDwarfUnitLength(EndLabel, BeginLabel, "Length of Unit");
Asm->OutStreamer->emitLabel(BeginLabel);
} else
- Asm->emitDwarfUnitLength(getHeaderSize() + getUnitDie().getSize(),
- "Length of Unit");
+ Asm->emitDwarfUnitLength(getHeaderSize() + getUnitDie().getSize(),
+ "Length of Unit");
Asm->OutStreamer->AddComment("DWARF version number");
unsigned Version = DD->getDwarfVersion();
@@ -1703,7 +1703,7 @@ void DwarfUnit::emitCommonHeader(bool UseOffsets, dwarf::UnitType UT) {
Asm->OutStreamer->AddComment("Offset Into Abbrev. Section");
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
if (UseOffsets)
- Asm->emitDwarfLengthOrOffset(0);
+ Asm->emitDwarfLengthOrOffset(0);
else
Asm->emitDwarfSymbolReference(
TLOF.getDwarfAbbrevSection()->getBeginSymbol(), false);
@@ -1722,14 +1722,14 @@ void DwarfTypeUnit::emitHeader(bool UseOffsets) {
Asm->OutStreamer->emitIntValue(TypeSignature, sizeof(TypeSignature));
Asm->OutStreamer->AddComment("Type DIE Offset");
// In a skeleton type unit there is no type DIE so emit a zero offset.
- Asm->emitDwarfLengthOrOffset(Ty ? Ty->getOffset() : 0);
+ Asm->emitDwarfLengthOrOffset(Ty ? Ty->getOffset() : 0);
}
DIE::value_iterator
DwarfUnit::addSectionDelta(DIE &Die, dwarf::Attribute Attribute,
const MCSymbol *Hi, const MCSymbol *Lo) {
return Die.addValue(DIEValueAllocator, Attribute,
- DD->getDwarfSectionOffsetForm(),
+ DD->getDwarfSectionOffsetForm(),
new (DIEValueAllocator) DIEDelta(Hi, Lo));
}
@@ -1737,7 +1737,7 @@ DIE::value_iterator
DwarfUnit::addSectionLabel(DIE &Die, dwarf::Attribute Attribute,
const MCSymbol *Label, const MCSymbol *Sec) {
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
- return addLabel(Die, Attribute, DD->getDwarfSectionOffsetForm(), Label);
+ return addLabel(Die, Attribute, DD->getDwarfSectionOffsetForm(), Label);
return addSectionDelta(Die, Attribute, Label, Sec);
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfUnit.h b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfUnit.h
index 13c60ed220..5c643760fd 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfUnit.h
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/DwarfUnit.h
@@ -18,17 +18,17 @@
#include "llvm/ADT/Optional.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/DIE.h"
-#include <string>
+#include <string>
namespace llvm {
-class ConstantFP;
+class ConstantFP;
class ConstantInt;
class DbgVariable;
class DwarfCompileUnit;
-class MachineOperand;
-class MCDwarfDwoLineTable;
-class MCSymbol;
+class MachineOperand;
+class MCDwarfDwoLineTable;
+class MCSymbol;
//===----------------------------------------------------------------------===//
/// This dwarf writer support class manages information associated with a
@@ -82,7 +82,7 @@ public:
MCSymbol *getEndLabel() const { return EndLabel; }
uint16_t getLanguage() const { return CUNode->getSourceLanguage(); }
const DICompileUnit *getCUNode() const { return CUNode; }
- DwarfDebug &getDwarfDebug() const { return *DD; }
+ DwarfDebug &getDwarfDebug() const { return *DD; }
/// Return true if this compile unit has something to write out.
bool hasContent() const { return getUnitDie().hasChildren(); }
@@ -248,9 +248,9 @@ public:
/// Compute the size of a header for this unit, not including the initial
/// length field.
virtual unsigned getHeaderSize() const {
- return sizeof(int16_t) + // DWARF version number
- Asm->getDwarfOffsetByteSize() + // Offset Into Abbrev. Section
- sizeof(int8_t) + // Pointer Size (in bytes)
+ return sizeof(int16_t) + // DWARF version number
+ Asm->getDwarfOffsetByteSize() + // Offset Into Abbrev. Section
+ sizeof(int8_t) + // Pointer Size (in bytes)
(DD->getDwarfVersion() >= 5 ? sizeof(int8_t)
: 0); // DWARF v5 unit type
}
@@ -295,12 +295,12 @@ protected:
private:
void constructTypeDIE(DIE &Buffer, const DIBasicType *BTy);
- void constructTypeDIE(DIE &Buffer, const DIStringType *BTy);
+ void constructTypeDIE(DIE &Buffer, const DIStringType *BTy);
void constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy);
void constructTypeDIE(DIE &Buffer, const DISubroutineType *CTy);
void constructSubrangeDIE(DIE &Buffer, const DISubrange *SR, DIE *IndexTy);
- void constructGenericSubrangeDIE(DIE &Buffer, const DIGenericSubrange *SR,
- DIE *IndexTy);
+ void constructGenericSubrangeDIE(DIE &Buffer, const DIGenericSubrange *SR,
+ DIE *IndexTy);
void constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy);
void constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy);
DIE &constructMemberDIE(DIE &Buffer, const DIDerivedType *DT);
@@ -353,7 +353,7 @@ public:
void emitHeader(bool UseOffsets) override;
unsigned getHeaderSize() const override {
return DwarfUnit::getHeaderSize() + sizeof(uint64_t) + // Type Signature
- Asm->getDwarfOffsetByteSize(); // Type DIE Offset
+ Asm->getDwarfOffsetByteSize(); // Type DIE Offset
}
void addGlobalName(StringRef Name, const DIE &Die,
const DIScope *Context) override;
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/EHStreamer.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/EHStreamer.cpp
index 76b737c3d4..2ffe8a7b04 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/EHStreamer.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/EHStreamer.cpp
@@ -44,9 +44,9 @@ EHStreamer::~EHStreamer() = default;
unsigned EHStreamer::sharedTypeIDs(const LandingPadInfo *L,
const LandingPadInfo *R) {
const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
- return std::mismatch(LIds.begin(), LIds.end(), RIds.begin(), RIds.end())
- .first -
- LIds.begin();
+ return std::mismatch(LIds.begin(), LIds.end(), RIds.begin(), RIds.end())
+ .first -
+ LIds.begin();
}
/// Compute the actions table and gather the first action index for each landing
@@ -214,30 +214,30 @@ void EHStreamer::computePadMap(
/// the landing pad and the action. Calls marked 'nounwind' have no entry and
/// must not be contained in the try-range of any entry - they form gaps in the
/// table. Entries must be ordered by try-range address.
-///
-/// Call-sites are split into one or more call-site ranges associated with
-/// different sections of the function.
-///
-/// - Without -basic-block-sections, all call-sites are grouped into one
-/// call-site-range corresponding to the function section.
-///
-/// - With -basic-block-sections, one call-site range is created for each
-/// section, with its FragmentBeginLabel and FragmentEndLabel respectively
-// set to the beginning and ending of the corresponding section and its
-// ExceptionLabel set to the exception symbol dedicated for this section.
-// Later, one LSDA header will be emitted for each call-site range with its
-// call-sites following. The action table and type info table will be
-// shared across all ranges.
-void EHStreamer::computeCallSiteTable(
- SmallVectorImpl<CallSiteEntry> &CallSites,
- SmallVectorImpl<CallSiteRange> &CallSiteRanges,
- const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
- const SmallVectorImpl<unsigned> &FirstActions) {
+///
+/// Call-sites are split into one or more call-site ranges associated with
+/// different sections of the function.
+///
+/// - Without -basic-block-sections, all call-sites are grouped into one
+/// call-site-range corresponding to the function section.
+///
+/// - With -basic-block-sections, one call-site range is created for each
+/// section, with its FragmentBeginLabel and FragmentEndLabel respectively
+// set to the beginning and ending of the corresponding section and its
+// ExceptionLabel set to the exception symbol dedicated for this section.
+// Later, one LSDA header will be emitted for each call-site range with its
+// call-sites following. The action table and type info table will be
+// shared across all ranges.
+void EHStreamer::computeCallSiteTable(
+ SmallVectorImpl<CallSiteEntry> &CallSites,
+ SmallVectorImpl<CallSiteRange> &CallSiteRanges,
+ const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
+ const SmallVectorImpl<unsigned> &FirstActions) {
RangeMapType PadMap;
computePadMap(LandingPads, PadMap);
// The end label of the previous invoke or nounwind try-range.
- MCSymbol *LastLabel = Asm->getFunctionBegin();
+ MCSymbol *LastLabel = Asm->getFunctionBegin();
// Whether there is a potentially throwing instruction (currently this means
// an ordinary call) between the end of the previous try-range and now.
@@ -250,21 +250,21 @@ void EHStreamer::computeCallSiteTable(
// Visit all instructions in order of address.
for (const auto &MBB : *Asm->MF) {
- if (&MBB == &Asm->MF->front() || MBB.isBeginSection()) {
- // We start a call-site range upon function entry and at the beginning of
- // every basic block section.
- CallSiteRanges.push_back(
- {Asm->MBBSectionRanges[MBB.getSectionIDNum()].BeginLabel,
- Asm->MBBSectionRanges[MBB.getSectionIDNum()].EndLabel,
- Asm->getMBBExceptionSym(MBB), CallSites.size()});
- PreviousIsInvoke = false;
- SawPotentiallyThrowing = false;
- LastLabel = nullptr;
- }
-
- if (MBB.isEHPad())
- CallSiteRanges.back().IsLPRange = true;
-
+ if (&MBB == &Asm->MF->front() || MBB.isBeginSection()) {
+ // We start a call-site range upon function entry and at the beginning of
+ // every basic block section.
+ CallSiteRanges.push_back(
+ {Asm->MBBSectionRanges[MBB.getSectionIDNum()].BeginLabel,
+ Asm->MBBSectionRanges[MBB.getSectionIDNum()].EndLabel,
+ Asm->getMBBExceptionSym(MBB), CallSites.size()});
+ PreviousIsInvoke = false;
+ SawPotentiallyThrowing = false;
+ LastLabel = nullptr;
+ }
+
+ if (MBB.isEHPad())
+ CallSiteRanges.back().IsLPRange = true;
+
for (const auto &MI : MBB) {
if (!MI.isEHLabel()) {
if (MI.isCall())
@@ -288,14 +288,14 @@ void EHStreamer::computeCallSiteTable(
assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
"Inconsistent landing pad map!");
- // For Dwarf and AIX exception handling (SjLj handling doesn't use this).
- // If some instruction between the previous try-range and this one may
- // throw, create a call-site entry with no landing pad for the region
- // between the try-ranges.
- if (SawPotentiallyThrowing &&
- (Asm->MAI->usesCFIForEH() ||
- Asm->MAI->getExceptionHandlingType() == ExceptionHandling::AIX)) {
- CallSites.push_back({LastLabel, BeginLabel, nullptr, 0});
+ // For Dwarf and AIX exception handling (SjLj handling doesn't use this).
+ // If some instruction between the previous try-range and this one may
+ // throw, create a call-site entry with no landing pad for the region
+ // between the try-ranges.
+ if (SawPotentiallyThrowing &&
+ (Asm->MAI->usesCFIForEH() ||
+ Asm->MAI->getExceptionHandlingType() == ExceptionHandling::AIX)) {
+ CallSites.push_back({LastLabel, BeginLabel, nullptr, 0});
PreviousIsInvoke = false;
}
@@ -339,20 +339,20 @@ void EHStreamer::computeCallSiteTable(
}
}
- // We end the call-site range upon function exit and at the end of every
- // basic block section.
- if (&MBB == &Asm->MF->back() || MBB.isEndSection()) {
- // If some instruction between the previous try-range and the end of the
- // function may throw, create a call-site entry with no landing pad for
- // the region following the try-range.
- if (SawPotentiallyThrowing && !IsSJLJ) {
- CallSiteEntry Site = {LastLabel, CallSiteRanges.back().FragmentEndLabel,
- nullptr, 0};
- CallSites.push_back(Site);
- SawPotentiallyThrowing = false;
- }
- CallSiteRanges.back().CallSiteEndIdx = CallSites.size();
- }
+ // We end the call-site range upon function exit and at the end of every
+ // basic block section.
+ if (&MBB == &Asm->MF->back() || MBB.isEndSection()) {
+ // If some instruction between the previous try-range and the end of the
+ // function may throw, create a call-site entry with no landing pad for
+ // the region following the try-range.
+ if (SawPotentiallyThrowing && !IsSJLJ) {
+ CallSiteEntry Site = {LastLabel, CallSiteRanges.back().FragmentEndLabel,
+ nullptr, 0};
+ CallSites.push_back(Site);
+ SawPotentiallyThrowing = false;
+ }
+ CallSiteRanges.back().CallSiteEndIdx = CallSites.size();
+ }
}
}
@@ -403,25 +403,25 @@ MCSymbol *EHStreamer::emitExceptionTable() {
SmallVector<unsigned, 64> FirstActions;
computeActionsTable(LandingPads, Actions, FirstActions);
- // Compute the call-site table and call-site ranges. Normally, there is only
- // one call-site-range which covers the whole funciton. With
- // -basic-block-sections, there is one call-site-range per basic block
- // section.
+ // Compute the call-site table and call-site ranges. Normally, there is only
+ // one call-site-range which covers the whole funciton. With
+ // -basic-block-sections, there is one call-site-range per basic block
+ // section.
SmallVector<CallSiteEntry, 64> CallSites;
- SmallVector<CallSiteRange, 4> CallSiteRanges;
- computeCallSiteTable(CallSites, CallSiteRanges, LandingPads, FirstActions);
+ SmallVector<CallSiteRange, 4> CallSiteRanges;
+ computeCallSiteTable(CallSites, CallSiteRanges, LandingPads, FirstActions);
bool IsSJLJ = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::SjLj;
bool IsWasm = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::Wasm;
- bool HasLEB128Directives = Asm->MAI->hasLEB128Directives();
+ bool HasLEB128Directives = Asm->MAI->hasLEB128Directives();
unsigned CallSiteEncoding =
IsSJLJ ? static_cast<unsigned>(dwarf::DW_EH_PE_udata4) :
Asm->getObjFileLowering().getCallSiteEncoding();
bool HaveTTData = !TypeInfos.empty() || !FilterIds.empty();
// Type infos.
- MCSection *LSDASection =
- Asm->getObjFileLowering().getSectionForLSDA(MF->getFunction(), Asm->TM);
+ MCSection *LSDASection =
+ Asm->getObjFileLowering().getSectionForLSDA(MF->getFunction(), Asm->TM);
unsigned TTypeEncoding;
if (!HaveTTData) {
@@ -471,122 +471,122 @@ MCSymbol *EHStreamer::emitExceptionTable() {
Asm->OutContext.getOrCreateSymbol(Twine("GCC_except_table")+
Twine(Asm->getFunctionNumber()));
Asm->OutStreamer->emitLabel(GCCETSym);
- MCSymbol *CstEndLabel = Asm->createTempSymbol(
- CallSiteRanges.size() > 1 ? "action_table_base" : "cst_end");
+ MCSymbol *CstEndLabel = Asm->createTempSymbol(
+ CallSiteRanges.size() > 1 ? "action_table_base" : "cst_end");
MCSymbol *TTBaseLabel = nullptr;
- if (HaveTTData)
+ if (HaveTTData)
TTBaseLabel = Asm->createTempSymbol("ttbase");
- const bool VerboseAsm = Asm->OutStreamer->isVerboseAsm();
-
- // Helper for emitting references (offsets) for type table and the end of the
- // call-site table (which marks the beginning of the action table).
- // * For Itanium, these references will be emitted for every callsite range.
- // * For SJLJ and Wasm, they will be emitted only once in the LSDA header.
- auto EmitTypeTableRefAndCallSiteTableEndRef = [&]() {
- Asm->emitEncodingByte(TTypeEncoding, "@TType");
- if (HaveTTData) {
- // N.B.: There is a dependency loop between the size of the TTBase uleb128
- // here and the amount of padding before the aligned type table. The
- // assembler must sometimes pad this uleb128 or insert extra padding
- // before the type table. See PR35809 or GNU as bug 4029.
- MCSymbol *TTBaseRefLabel = Asm->createTempSymbol("ttbaseref");
- Asm->emitLabelDifferenceAsULEB128(TTBaseLabel, TTBaseRefLabel);
- Asm->OutStreamer->emitLabel(TTBaseRefLabel);
- }
-
- // The Action table follows the call-site table. So we emit the
- // label difference from here (start of the call-site table for SJLJ and
- // Wasm, and start of a call-site range for Itanium) to the end of the
- // whole call-site table (end of the last call-site range for Itanium).
- MCSymbol *CstBeginLabel = Asm->createTempSymbol("cst_begin");
- Asm->emitEncodingByte(CallSiteEncoding, "Call site");
- Asm->emitLabelDifferenceAsULEB128(CstEndLabel, CstBeginLabel);
- Asm->OutStreamer->emitLabel(CstBeginLabel);
- };
-
- // An alternative path to EmitTypeTableRefAndCallSiteTableEndRef.
- // For some platforms, the system assembler does not accept the form of
- // `.uleb128 label2 - label1`. In those situations, we would need to calculate
- // the size between label1 and label2 manually.
- // In this case, we would need to calculate the LSDA size and the call
- // site table size.
- auto EmitTypeTableOffsetAndCallSiteTableOffset = [&]() {
- assert(CallSiteEncoding == dwarf::DW_EH_PE_udata4 && !HasLEB128Directives &&
- "Targets supporting .uleb128 do not need to take this path.");
- if (CallSiteRanges.size() > 1)
- report_fatal_error(
- "-fbasic-block-sections is not yet supported on "
- "platforms that do not have general LEB128 directive support.");
-
- uint64_t CallSiteTableSize = 0;
- const CallSiteRange &CSRange = CallSiteRanges.back();
- for (size_t CallSiteIdx = CSRange.CallSiteBeginIdx;
- CallSiteIdx < CSRange.CallSiteEndIdx; ++CallSiteIdx) {
- const CallSiteEntry &S = CallSites[CallSiteIdx];
- // Each call site entry consists of 3 udata4 fields (12 bytes) and
- // 1 ULEB128 field.
- CallSiteTableSize += 12 + getULEB128Size(S.Action);
- assert(isUInt<32>(CallSiteTableSize) && "CallSiteTableSize overflows.");
- }
-
- Asm->emitEncodingByte(TTypeEncoding, "@TType");
- if (HaveTTData) {
- const unsigned ByteSizeOfCallSiteOffset =
- getULEB128Size(CallSiteTableSize);
- uint64_t ActionTableSize = 0;
- for (const ActionEntry &Action : Actions) {
- // Each action entry consists of two SLEB128 fields.
- ActionTableSize += getSLEB128Size(Action.ValueForTypeID) +
- getSLEB128Size(Action.NextAction);
- assert(isUInt<32>(ActionTableSize) && "ActionTableSize overflows.");
- }
-
- const unsigned TypeInfoSize =
- Asm->GetSizeOfEncodedValue(TTypeEncoding) * MF->getTypeInfos().size();
-
- const uint64_t LSDASizeBeforeAlign =
- 1 // Call site encoding byte.
- + ByteSizeOfCallSiteOffset // ULEB128 encoding of CallSiteTableSize.
- + CallSiteTableSize // Call site table content.
- + ActionTableSize; // Action table content.
-
- const uint64_t LSDASizeWithoutAlign = LSDASizeBeforeAlign + TypeInfoSize;
- const unsigned ByteSizeOfLSDAWithoutAlign =
- getULEB128Size(LSDASizeWithoutAlign);
- const uint64_t DisplacementBeforeAlign =
- 2 // LPStartEncoding and TypeTableEncoding.
- + ByteSizeOfLSDAWithoutAlign + LSDASizeBeforeAlign;
-
- // The type info area starts with 4 byte alignment.
- const unsigned NeedAlignVal = (4 - DisplacementBeforeAlign % 4) % 4;
- uint64_t LSDASizeWithAlign = LSDASizeWithoutAlign + NeedAlignVal;
- const unsigned ByteSizeOfLSDAWithAlign =
- getULEB128Size(LSDASizeWithAlign);
-
- // The LSDASizeWithAlign could use 1 byte less padding for alignment
- // when the data we use to represent the LSDA Size "needs" to be 1 byte
- // larger than the one previously calculated without alignment.
- if (ByteSizeOfLSDAWithAlign > ByteSizeOfLSDAWithoutAlign)
- LSDASizeWithAlign -= 1;
-
- Asm->OutStreamer->emitULEB128IntValue(LSDASizeWithAlign,
- ByteSizeOfLSDAWithAlign);
- }
-
- Asm->emitEncodingByte(CallSiteEncoding, "Call site");
- Asm->OutStreamer->emitULEB128IntValue(CallSiteTableSize);
- };
-
+ const bool VerboseAsm = Asm->OutStreamer->isVerboseAsm();
+
+ // Helper for emitting references (offsets) for type table and the end of the
+ // call-site table (which marks the beginning of the action table).
+ // * For Itanium, these references will be emitted for every callsite range.
+ // * For SJLJ and Wasm, they will be emitted only once in the LSDA header.
+ auto EmitTypeTableRefAndCallSiteTableEndRef = [&]() {
+ Asm->emitEncodingByte(TTypeEncoding, "@TType");
+ if (HaveTTData) {
+ // N.B.: There is a dependency loop between the size of the TTBase uleb128
+ // here and the amount of padding before the aligned type table. The
+ // assembler must sometimes pad this uleb128 or insert extra padding
+ // before the type table. See PR35809 or GNU as bug 4029.
+ MCSymbol *TTBaseRefLabel = Asm->createTempSymbol("ttbaseref");
+ Asm->emitLabelDifferenceAsULEB128(TTBaseLabel, TTBaseRefLabel);
+ Asm->OutStreamer->emitLabel(TTBaseRefLabel);
+ }
+
+ // The Action table follows the call-site table. So we emit the
+ // label difference from here (start of the call-site table for SJLJ and
+ // Wasm, and start of a call-site range for Itanium) to the end of the
+ // whole call-site table (end of the last call-site range for Itanium).
+ MCSymbol *CstBeginLabel = Asm->createTempSymbol("cst_begin");
+ Asm->emitEncodingByte(CallSiteEncoding, "Call site");
+ Asm->emitLabelDifferenceAsULEB128(CstEndLabel, CstBeginLabel);
+ Asm->OutStreamer->emitLabel(CstBeginLabel);
+ };
+
+ // An alternative path to EmitTypeTableRefAndCallSiteTableEndRef.
+ // For some platforms, the system assembler does not accept the form of
+ // `.uleb128 label2 - label1`. In those situations, we would need to calculate
+ // the size between label1 and label2 manually.
+ // In this case, we would need to calculate the LSDA size and the call
+ // site table size.
+ auto EmitTypeTableOffsetAndCallSiteTableOffset = [&]() {
+ assert(CallSiteEncoding == dwarf::DW_EH_PE_udata4 && !HasLEB128Directives &&
+ "Targets supporting .uleb128 do not need to take this path.");
+ if (CallSiteRanges.size() > 1)
+ report_fatal_error(
+ "-fbasic-block-sections is not yet supported on "
+ "platforms that do not have general LEB128 directive support.");
+
+ uint64_t CallSiteTableSize = 0;
+ const CallSiteRange &CSRange = CallSiteRanges.back();
+ for (size_t CallSiteIdx = CSRange.CallSiteBeginIdx;
+ CallSiteIdx < CSRange.CallSiteEndIdx; ++CallSiteIdx) {
+ const CallSiteEntry &S = CallSites[CallSiteIdx];
+ // Each call site entry consists of 3 udata4 fields (12 bytes) and
+ // 1 ULEB128 field.
+ CallSiteTableSize += 12 + getULEB128Size(S.Action);
+ assert(isUInt<32>(CallSiteTableSize) && "CallSiteTableSize overflows.");
+ }
+
+ Asm->emitEncodingByte(TTypeEncoding, "@TType");
+ if (HaveTTData) {
+ const unsigned ByteSizeOfCallSiteOffset =
+ getULEB128Size(CallSiteTableSize);
+ uint64_t ActionTableSize = 0;
+ for (const ActionEntry &Action : Actions) {
+ // Each action entry consists of two SLEB128 fields.
+ ActionTableSize += getSLEB128Size(Action.ValueForTypeID) +
+ getSLEB128Size(Action.NextAction);
+ assert(isUInt<32>(ActionTableSize) && "ActionTableSize overflows.");
+ }
+
+ const unsigned TypeInfoSize =
+ Asm->GetSizeOfEncodedValue(TTypeEncoding) * MF->getTypeInfos().size();
+
+ const uint64_t LSDASizeBeforeAlign =
+ 1 // Call site encoding byte.
+ + ByteSizeOfCallSiteOffset // ULEB128 encoding of CallSiteTableSize.
+ + CallSiteTableSize // Call site table content.
+ + ActionTableSize; // Action table content.
+
+ const uint64_t LSDASizeWithoutAlign = LSDASizeBeforeAlign + TypeInfoSize;
+ const unsigned ByteSizeOfLSDAWithoutAlign =
+ getULEB128Size(LSDASizeWithoutAlign);
+ const uint64_t DisplacementBeforeAlign =
+ 2 // LPStartEncoding and TypeTableEncoding.
+ + ByteSizeOfLSDAWithoutAlign + LSDASizeBeforeAlign;
+
+ // The type info area starts with 4 byte alignment.
+ const unsigned NeedAlignVal = (4 - DisplacementBeforeAlign % 4) % 4;
+ uint64_t LSDASizeWithAlign = LSDASizeWithoutAlign + NeedAlignVal;
+ const unsigned ByteSizeOfLSDAWithAlign =
+ getULEB128Size(LSDASizeWithAlign);
+
+ // The LSDASizeWithAlign could use 1 byte less padding for alignment
+ // when the data we use to represent the LSDA Size "needs" to be 1 byte
+ // larger than the one previously calculated without alignment.
+ if (ByteSizeOfLSDAWithAlign > ByteSizeOfLSDAWithoutAlign)
+ LSDASizeWithAlign -= 1;
+
+ Asm->OutStreamer->emitULEB128IntValue(LSDASizeWithAlign,
+ ByteSizeOfLSDAWithAlign);
+ }
+
+ Asm->emitEncodingByte(CallSiteEncoding, "Call site");
+ Asm->OutStreamer->emitULEB128IntValue(CallSiteTableSize);
+ };
+
// SjLj / Wasm Exception handling
if (IsSJLJ || IsWasm) {
- Asm->OutStreamer->emitLabel(Asm->getMBBExceptionSym(Asm->MF->front()));
-
- // emit the LSDA header.
- Asm->emitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
- EmitTypeTableRefAndCallSiteTableEndRef();
-
+ Asm->OutStreamer->emitLabel(Asm->getMBBExceptionSym(Asm->MF->front()));
+
+ // emit the LSDA header.
+ Asm->emitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
+ EmitTypeTableRefAndCallSiteTableEndRef();
+
unsigned idx = 0;
for (SmallVectorImpl<CallSiteEntry>::const_iterator
I = CallSites.begin(), E = CallSites.end(); I != E; ++I, ++idx) {
@@ -611,7 +611,7 @@ MCSymbol *EHStreamer::emitExceptionTable() {
}
Asm->emitULEB128(S.Action);
}
- Asm->OutStreamer->emitLabel(CstEndLabel);
+ Asm->OutStreamer->emitLabel(CstEndLabel);
} else {
// Itanium LSDA exception handling
@@ -633,126 +633,126 @@ MCSymbol *EHStreamer::emitExceptionTable() {
// A missing entry in the call-site table indicates that a call is not
// supposed to throw.
- assert(CallSiteRanges.size() != 0 && "No call-site ranges!");
-
- // There should be only one call-site range which includes all the landing
- // pads. Find that call-site range here.
- const CallSiteRange *LandingPadRange = nullptr;
- for (const CallSiteRange &CSRange : CallSiteRanges) {
- if (CSRange.IsLPRange) {
- assert(LandingPadRange == nullptr &&
- "All landing pads must be in a single callsite range.");
- LandingPadRange = &CSRange;
- }
- }
-
- // The call-site table is split into its call-site ranges, each being
- // emitted as:
- // [ LPStartEncoding | LPStart ]
- // [ TypeTableEncoding | TypeTableOffset ]
- // [ CallSiteEncoding | CallSiteTableEndOffset ]
- // cst_begin -> { call-site entries contained in this range }
- //
- // and is followed by the next call-site range.
- //
- // For each call-site range, CallSiteTableEndOffset is computed as the
- // difference between cst_begin of that range and the last call-site-table's
- // end label. This offset is used to find the action table.
-
+ assert(CallSiteRanges.size() != 0 && "No call-site ranges!");
+
+ // There should be only one call-site range which includes all the landing
+ // pads. Find that call-site range here.
+ const CallSiteRange *LandingPadRange = nullptr;
+ for (const CallSiteRange &CSRange : CallSiteRanges) {
+ if (CSRange.IsLPRange) {
+ assert(LandingPadRange == nullptr &&
+ "All landing pads must be in a single callsite range.");
+ LandingPadRange = &CSRange;
+ }
+ }
+
+ // The call-site table is split into its call-site ranges, each being
+ // emitted as:
+ // [ LPStartEncoding | LPStart ]
+ // [ TypeTableEncoding | TypeTableOffset ]
+ // [ CallSiteEncoding | CallSiteTableEndOffset ]
+ // cst_begin -> { call-site entries contained in this range }
+ //
+ // and is followed by the next call-site range.
+ //
+ // For each call-site range, CallSiteTableEndOffset is computed as the
+ // difference between cst_begin of that range and the last call-site-table's
+ // end label. This offset is used to find the action table.
+
unsigned Entry = 0;
- for (const CallSiteRange &CSRange : CallSiteRanges) {
- if (CSRange.CallSiteBeginIdx != 0) {
- // Align the call-site range for all ranges except the first. The
- // first range is already aligned due to the exception table alignment.
- Asm->emitAlignment(Align(4));
- }
- Asm->OutStreamer->emitLabel(CSRange.ExceptionLabel);
-
- // Emit the LSDA header.
- // If only one call-site range exists, LPStart is omitted as it is the
- // same as the function entry.
- if (CallSiteRanges.size() == 1) {
- Asm->emitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
- } else if (!Asm->isPositionIndependent()) {
- // For more than one call-site ranges, LPStart must be explicitly
- // specified.
- // For non-PIC we can simply use the absolute value.
- Asm->emitEncodingByte(dwarf::DW_EH_PE_absptr, "@LPStart");
- Asm->OutStreamer->emitSymbolValue(LandingPadRange->FragmentBeginLabel,
- Asm->MAI->getCodePointerSize());
- } else {
- // For PIC mode, we Emit a PC-relative address for LPStart.
- Asm->emitEncodingByte(dwarf::DW_EH_PE_pcrel, "@LPStart");
- MCContext &Context = Asm->OutStreamer->getContext();
- MCSymbol *Dot = Context.createTempSymbol();
- Asm->OutStreamer->emitLabel(Dot);
- Asm->OutStreamer->emitValue(
- MCBinaryExpr::createSub(
- MCSymbolRefExpr::create(LandingPadRange->FragmentBeginLabel,
- Context),
- MCSymbolRefExpr::create(Dot, Context), Context),
- Asm->MAI->getCodePointerSize());
- }
-
- if (HasLEB128Directives)
- EmitTypeTableRefAndCallSiteTableEndRef();
- else
- EmitTypeTableOffsetAndCallSiteTableOffset();
-
- for (size_t CallSiteIdx = CSRange.CallSiteBeginIdx;
- CallSiteIdx != CSRange.CallSiteEndIdx; ++CallSiteIdx) {
- const CallSiteEntry &S = CallSites[CallSiteIdx];
-
- MCSymbol *EHFuncBeginSym = CSRange.FragmentBeginLabel;
- MCSymbol *EHFuncEndSym = CSRange.FragmentEndLabel;
-
- MCSymbol *BeginLabel = S.BeginLabel;
- if (!BeginLabel)
- BeginLabel = EHFuncBeginSym;
- MCSymbol *EndLabel = S.EndLabel;
- if (!EndLabel)
- EndLabel = EHFuncEndSym;
-
- // Offset of the call site relative to the start of the procedure.
+ for (const CallSiteRange &CSRange : CallSiteRanges) {
+ if (CSRange.CallSiteBeginIdx != 0) {
+ // Align the call-site range for all ranges except the first. The
+ // first range is already aligned due to the exception table alignment.
+ Asm->emitAlignment(Align(4));
+ }
+ Asm->OutStreamer->emitLabel(CSRange.ExceptionLabel);
+
+ // Emit the LSDA header.
+ // If only one call-site range exists, LPStart is omitted as it is the
+ // same as the function entry.
+ if (CallSiteRanges.size() == 1) {
+ Asm->emitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
+ } else if (!Asm->isPositionIndependent()) {
+ // For more than one call-site ranges, LPStart must be explicitly
+ // specified.
+ // For non-PIC we can simply use the absolute value.
+ Asm->emitEncodingByte(dwarf::DW_EH_PE_absptr, "@LPStart");
+ Asm->OutStreamer->emitSymbolValue(LandingPadRange->FragmentBeginLabel,
+ Asm->MAI->getCodePointerSize());
+ } else {
+ // For PIC mode, we Emit a PC-relative address for LPStart.
+ Asm->emitEncodingByte(dwarf::DW_EH_PE_pcrel, "@LPStart");
+ MCContext &Context = Asm->OutStreamer->getContext();
+ MCSymbol *Dot = Context.createTempSymbol();
+ Asm->OutStreamer->emitLabel(Dot);
+ Asm->OutStreamer->emitValue(
+ MCBinaryExpr::createSub(
+ MCSymbolRefExpr::create(LandingPadRange->FragmentBeginLabel,
+ Context),
+ MCSymbolRefExpr::create(Dot, Context), Context),
+ Asm->MAI->getCodePointerSize());
+ }
+
+ if (HasLEB128Directives)
+ EmitTypeTableRefAndCallSiteTableEndRef();
+ else
+ EmitTypeTableOffsetAndCallSiteTableOffset();
+
+ for (size_t CallSiteIdx = CSRange.CallSiteBeginIdx;
+ CallSiteIdx != CSRange.CallSiteEndIdx; ++CallSiteIdx) {
+ const CallSiteEntry &S = CallSites[CallSiteIdx];
+
+ MCSymbol *EHFuncBeginSym = CSRange.FragmentBeginLabel;
+ MCSymbol *EHFuncEndSym = CSRange.FragmentEndLabel;
+
+ MCSymbol *BeginLabel = S.BeginLabel;
+ if (!BeginLabel)
+ BeginLabel = EHFuncBeginSym;
+ MCSymbol *EndLabel = S.EndLabel;
+ if (!EndLabel)
+ EndLabel = EHFuncEndSym;
+
+ // Offset of the call site relative to the start of the procedure.
if (VerboseAsm)
- Asm->OutStreamer->AddComment(">> Call Site " + Twine(++Entry) +
- " <<");
- Asm->emitCallSiteOffset(BeginLabel, EHFuncBeginSym, CallSiteEncoding);
+ Asm->OutStreamer->AddComment(">> Call Site " + Twine(++Entry) +
+ " <<");
+ Asm->emitCallSiteOffset(BeginLabel, EHFuncBeginSym, CallSiteEncoding);
if (VerboseAsm)
- Asm->OutStreamer->AddComment(Twine(" Call between ") +
- BeginLabel->getName() + " and " +
- EndLabel->getName());
- Asm->emitCallSiteOffset(EndLabel, BeginLabel, CallSiteEncoding);
-
- // Offset of the landing pad relative to the start of the landing pad
- // fragment.
- if (!S.LPad) {
- if (VerboseAsm)
- Asm->OutStreamer->AddComment(" has no landing pad");
- Asm->emitCallSiteValue(0, CallSiteEncoding);
- } else {
- if (VerboseAsm)
- Asm->OutStreamer->AddComment(Twine(" jumps to ") +
- S.LPad->LandingPadLabel->getName());
- Asm->emitCallSiteOffset(S.LPad->LandingPadLabel,
- LandingPadRange->FragmentBeginLabel,
- CallSiteEncoding);
- }
-
- // Offset of the first associated action record, relative to the start
- // of the action table. This value is biased by 1 (1 indicates the start
- // of the action table), and 0 indicates that there are no actions.
- if (VerboseAsm) {
- if (S.Action == 0)
- Asm->OutStreamer->AddComment(" On action: cleanup");
- else
- Asm->OutStreamer->AddComment(" On action: " +
- Twine((S.Action - 1) / 2 + 1));
- }
- Asm->emitULEB128(S.Action);
+ Asm->OutStreamer->AddComment(Twine(" Call between ") +
+ BeginLabel->getName() + " and " +
+ EndLabel->getName());
+ Asm->emitCallSiteOffset(EndLabel, BeginLabel, CallSiteEncoding);
+
+ // Offset of the landing pad relative to the start of the landing pad
+ // fragment.
+ if (!S.LPad) {
+ if (VerboseAsm)
+ Asm->OutStreamer->AddComment(" has no landing pad");
+ Asm->emitCallSiteValue(0, CallSiteEncoding);
+ } else {
+ if (VerboseAsm)
+ Asm->OutStreamer->AddComment(Twine(" jumps to ") +
+ S.LPad->LandingPadLabel->getName());
+ Asm->emitCallSiteOffset(S.LPad->LandingPadLabel,
+ LandingPadRange->FragmentBeginLabel,
+ CallSiteEncoding);
+ }
+
+ // Offset of the first associated action record, relative to the start
+ // of the action table. This value is biased by 1 (1 indicates the start
+ // of the action table), and 0 indicates that there are no actions.
+ if (VerboseAsm) {
+ if (S.Action == 0)
+ Asm->OutStreamer->AddComment(" On action: cleanup");
+ else
+ Asm->OutStreamer->AddComment(" On action: " +
+ Twine((S.Action - 1) / 2 + 1));
+ }
+ Asm->emitULEB128(S.Action);
}
}
- Asm->OutStreamer->emitLabel(CstEndLabel);
+ Asm->OutStreamer->emitLabel(CstEndLabel);
}
// Emit the Action Table.
@@ -784,11 +784,11 @@ MCSymbol *EHStreamer::emitExceptionTable() {
// Action Record
if (VerboseAsm) {
- if (Action.Previous == unsigned(-1)) {
+ if (Action.Previous == unsigned(-1)) {
Asm->OutStreamer->AddComment(" No further actions");
} else {
- Asm->OutStreamer->AddComment(" Continue to action " +
- Twine(Action.Previous + 1));
+ Asm->OutStreamer->AddComment(" Continue to action " +
+ Twine(Action.Previous + 1));
}
}
Asm->emitSLEB128(Action.NextAction);
@@ -808,7 +808,7 @@ void EHStreamer::emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel) {
const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos();
const std::vector<unsigned> &FilterIds = MF->getFilterIds();
- const bool VerboseAsm = Asm->OutStreamer->isVerboseAsm();
+ const bool VerboseAsm = Asm->OutStreamer->isVerboseAsm();
int Entry = 0;
// Emit the Catch TypeInfos.
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/EHStreamer.h b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/EHStreamer.h
index 5f9f6d3381..234e62506a 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/EHStreamer.h
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/EHStreamer.h
@@ -69,48 +69,48 @@ protected:
unsigned Action;
};
- /// Structure describing a contiguous range of call-sites which reside
- /// in the same procedure fragment. With -fbasic-block-sections, there will
- /// be one call site range per basic block section. Otherwise, we will have
- /// one call site range containing all the call sites in the function.
- struct CallSiteRange {
- // Symbol marking the beginning of the precedure fragment.
- MCSymbol *FragmentBeginLabel = nullptr;
- // Symbol marking the end of the procedure fragment.
- MCSymbol *FragmentEndLabel = nullptr;
- // LSDA symbol for this call-site range.
- MCSymbol *ExceptionLabel = nullptr;
- // Index of the first call-site entry in the call-site table which
- // belongs to this range.
- size_t CallSiteBeginIdx = 0;
- // Index just after the last call-site entry in the call-site table which
- // belongs to this range.
- size_t CallSiteEndIdx = 0;
- // Whether this is the call-site range containing all the landing pads.
- bool IsLPRange = false;
- };
-
+ /// Structure describing a contiguous range of call-sites which reside
+ /// in the same procedure fragment. With -fbasic-block-sections, there will
+ /// be one call site range per basic block section. Otherwise, we will have
+ /// one call site range containing all the call sites in the function.
+ struct CallSiteRange {
+ // Symbol marking the beginning of the precedure fragment.
+ MCSymbol *FragmentBeginLabel = nullptr;
+ // Symbol marking the end of the procedure fragment.
+ MCSymbol *FragmentEndLabel = nullptr;
+ // LSDA symbol for this call-site range.
+ MCSymbol *ExceptionLabel = nullptr;
+ // Index of the first call-site entry in the call-site table which
+ // belongs to this range.
+ size_t CallSiteBeginIdx = 0;
+ // Index just after the last call-site entry in the call-site table which
+ // belongs to this range.
+ size_t CallSiteEndIdx = 0;
+ // Whether this is the call-site range containing all the landing pads.
+ bool IsLPRange = false;
+ };
+
/// Compute the actions table and gather the first action index for each
/// landing pad site.
- void computeActionsTable(
- const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
- SmallVectorImpl<ActionEntry> &Actions,
- SmallVectorImpl<unsigned> &FirstActions);
+ void computeActionsTable(
+ const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
+ SmallVectorImpl<ActionEntry> &Actions,
+ SmallVectorImpl<unsigned> &FirstActions);
void computePadMap(const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
RangeMapType &PadMap);
- /// Compute the call-site table and the call-site ranges. The entry for an
- /// invoke has a try-range containing the call, a non-zero landing pad and an
- /// appropriate action. The entry for an ordinary call has a try-range
- /// containing the call and zero for the landing pad and the action. Calls
- /// marked 'nounwind' have no entry and must not be contained in the try-range
- /// of any entry - they form gaps in the table. Entries must be ordered by
- /// try-range address. CallSiteRanges vector is only populated for Itanium
- /// exception handling.
+ /// Compute the call-site table and the call-site ranges. The entry for an
+ /// invoke has a try-range containing the call, a non-zero landing pad and an
+ /// appropriate action. The entry for an ordinary call has a try-range
+ /// containing the call and zero for the landing pad and the action. Calls
+ /// marked 'nounwind' have no entry and must not be contained in the try-range
+ /// of any entry - they form gaps in the table. Entries must be ordered by
+ /// try-range address. CallSiteRanges vector is only populated for Itanium
+ /// exception handling.
virtual void computeCallSiteTable(
SmallVectorImpl<CallSiteEntry> &CallSites,
- SmallVectorImpl<CallSiteRange> &CallSiteRanges,
+ SmallVectorImpl<CallSiteRange> &CallSiteRanges,
const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
const SmallVectorImpl<unsigned> &FirstActions);
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
index b31268b896..354b638b47 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
@@ -145,10 +145,10 @@ void OcamlGCMetadataPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
report_fatal_error("Function '" + FI.getFunction().getName() +
"' is too large for the ocaml GC! "
"Frame size " +
- Twine(FrameSize) +
- ">= 65536.\n"
- "(" +
- Twine(reinterpret_cast<uintptr_t>(&FI)) + ")");
+ Twine(FrameSize) +
+ ">= 65536.\n"
+ "(" +
+ Twine(reinterpret_cast<uintptr_t>(&FI)) + ")");
}
AP.OutStreamer->AddComment("live roots for " +
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp
index 1dc107041e..e8636052c5 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp
@@ -1,84 +1,84 @@
-//===- llvm/CodeGen/PseudoProbePrinter.cpp - Pseudo Probe Emission -------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains support for writing pseudo probe info into asm files.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PseudoProbePrinter.h"
-#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/PseudoProbe.h"
-#include "llvm/MC/MCPseudoProbe.h"
-#include "llvm/MC/MCStreamer.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "pseudoprobe"
-
-PseudoProbeHandler::~PseudoProbeHandler() = default;
-
-PseudoProbeHandler::PseudoProbeHandler(AsmPrinter *A, Module *M) : Asm(A) {
- NamedMDNode *FuncInfo = M->getNamedMetadata(PseudoProbeDescMetadataName);
- assert(FuncInfo && "Pseudo probe descriptors are missing");
- for (const auto *Operand : FuncInfo->operands()) {
- const auto *MD = cast<MDNode>(Operand);
- auto GUID =
- mdconst::dyn_extract<ConstantInt>(MD->getOperand(0))->getZExtValue();
- auto Name = cast<MDString>(MD->getOperand(2))->getString();
- // We may see pairs with same name but different GUIDs here in LTO mode, due
- // to static same-named functions inlined from other modules into this
- // module. Function profiles with the same name will be merged no matter
- // whether they are collected on the same function. Therefore we just pick
- // up the last <Name, GUID> pair here to represent the same-named function
- // collection and all probes from the collection will be merged into a
- // single profile eventually.
- Names[Name] = GUID;
- }
-
- LLVM_DEBUG(dump());
-}
-
-void PseudoProbeHandler::emitPseudoProbe(uint64_t Guid, uint64_t Index,
- uint64_t Type, uint64_t Attr,
- const DILocation *DebugLoc) {
- // Gather all the inlined-at nodes.
- // When it's done ReversedInlineStack looks like ([66, B], [88, A])
- // which means, Function A inlines function B at calliste with a probe id 88,
- // and B inlines C at probe 66 where C is represented by Guid.
- SmallVector<InlineSite, 8> ReversedInlineStack;
- auto *InlinedAt = DebugLoc ? DebugLoc->getInlinedAt() : nullptr;
- while (InlinedAt) {
- const DISubprogram *SP = InlinedAt->getScope()->getSubprogram();
- // Use linkage name for C++ if possible.
- auto Name = SP->getLinkageName();
- if (Name.empty())
- Name = SP->getName();
- assert(Names.count(Name) && "Pseudo probe descriptor missing for function");
- uint64_t CallerGuid = Names[Name];
- uint64_t CallerProbeId = PseudoProbeDwarfDiscriminator::extractProbeIndex(
- InlinedAt->getDiscriminator());
- ReversedInlineStack.emplace_back(CallerGuid, CallerProbeId);
- InlinedAt = InlinedAt->getInlinedAt();
- }
-
- SmallVector<InlineSite, 8> InlineStack(ReversedInlineStack.rbegin(),
- ReversedInlineStack.rend());
- Asm->OutStreamer->emitPseudoProbe(Guid, Index, Type, Attr, InlineStack);
-}
-
-#ifndef NDEBUG
-void PseudoProbeHandler::dump() const {
- dbgs() << "\n=============================\n";
- dbgs() << "\nFunction Name to GUID map:\n";
- dbgs() << "\n=============================\n";
- for (const auto &Item : Names)
- dbgs() << "Func: " << Item.first << " GUID: " << Item.second << "\n";
-}
-#endif
+//===- llvm/CodeGen/PseudoProbePrinter.cpp - Pseudo Probe Emission -------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains support for writing pseudo probe info into asm files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PseudoProbePrinter.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PseudoProbe.h"
+#include "llvm/MC/MCPseudoProbe.h"
+#include "llvm/MC/MCStreamer.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "pseudoprobe"
+
+PseudoProbeHandler::~PseudoProbeHandler() = default;
+
+PseudoProbeHandler::PseudoProbeHandler(AsmPrinter *A, Module *M) : Asm(A) {
+ NamedMDNode *FuncInfo = M->getNamedMetadata(PseudoProbeDescMetadataName);
+ assert(FuncInfo && "Pseudo probe descriptors are missing");
+ for (const auto *Operand : FuncInfo->operands()) {
+ const auto *MD = cast<MDNode>(Operand);
+ auto GUID =
+ mdconst::dyn_extract<ConstantInt>(MD->getOperand(0))->getZExtValue();
+ auto Name = cast<MDString>(MD->getOperand(2))->getString();
+ // We may see pairs with same name but different GUIDs here in LTO mode, due
+ // to static same-named functions inlined from other modules into this
+ // module. Function profiles with the same name will be merged no matter
+ // whether they are collected on the same function. Therefore we just pick
+ // up the last <Name, GUID> pair here to represent the same-named function
+ // collection and all probes from the collection will be merged into a
+ // single profile eventually.
+ Names[Name] = GUID;
+ }
+
+ LLVM_DEBUG(dump());
+}
+
+void PseudoProbeHandler::emitPseudoProbe(uint64_t Guid, uint64_t Index,
+ uint64_t Type, uint64_t Attr,
+ const DILocation *DebugLoc) {
+ // Gather all the inlined-at nodes.
+ // When it's done ReversedInlineStack looks like ([66, B], [88, A])
+ // which means, Function A inlines function B at calliste with a probe id 88,
+ // and B inlines C at probe 66 where C is represented by Guid.
+ SmallVector<InlineSite, 8> ReversedInlineStack;
+ auto *InlinedAt = DebugLoc ? DebugLoc->getInlinedAt() : nullptr;
+ while (InlinedAt) {
+ const DISubprogram *SP = InlinedAt->getScope()->getSubprogram();
+ // Use linkage name for C++ if possible.
+ auto Name = SP->getLinkageName();
+ if (Name.empty())
+ Name = SP->getName();
+ assert(Names.count(Name) && "Pseudo probe descriptor missing for function");
+ uint64_t CallerGuid = Names[Name];
+ uint64_t CallerProbeId = PseudoProbeDwarfDiscriminator::extractProbeIndex(
+ InlinedAt->getDiscriminator());
+ ReversedInlineStack.emplace_back(CallerGuid, CallerProbeId);
+ InlinedAt = InlinedAt->getInlinedAt();
+ }
+
+ SmallVector<InlineSite, 8> InlineStack(ReversedInlineStack.rbegin(),
+ ReversedInlineStack.rend());
+ Asm->OutStreamer->emitPseudoProbe(Guid, Index, Type, Attr, InlineStack);
+}
+
+#ifndef NDEBUG
+void PseudoProbeHandler::dump() const {
+ dbgs() << "\n=============================\n";
+ dbgs() << "\nFunction Name to GUID map:\n";
+ dbgs() << "\n=============================\n";
+ for (const auto &Item : Names)
+ dbgs() << "Func: " << Item.first << " GUID: " << Item.second << "\n";
+}
+#endif
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/PseudoProbePrinter.h b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/PseudoProbePrinter.h
index 627b497936..bea07ceae9 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/PseudoProbePrinter.h
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/PseudoProbePrinter.h
@@ -1,53 +1,53 @@
-//===- PseudoProbePrinter.h - Pseudo probe encoding support -----*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains support for writing pseudo probe info into asm files.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_PSEUDOPROBEPRINTER_H
-#define LLVM_LIB_CODEGEN_ASMPRINTER_PSEUDOPROBEPRINTER_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/CodeGen/AsmPrinterHandler.h"
-
-namespace llvm {
-
-class AsmPrinter;
-class MCStreamer;
-class Module;
-class DILocation;
-
-class PseudoProbeHandler : public AsmPrinterHandler {
- // Target of pseudo probe emission.
- AsmPrinter *Asm;
- // Name to GUID map
- DenseMap<StringRef, uint64_t> Names;
-
-public:
- PseudoProbeHandler(AsmPrinter *A, Module *M);
- ~PseudoProbeHandler() override;
-
- void emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type,
- uint64_t Attr, const DILocation *DebugLoc);
-
- // Unused.
- void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {}
- void endModule() override {}
- void beginFunction(const MachineFunction *MF) override {}
- void endFunction(const MachineFunction *MF) override {}
- void beginInstruction(const MachineInstr *MI) override {}
- void endInstruction() override {}
-
-#ifndef NDEBUG
- void dump() const;
-#endif
-};
-
-} // namespace llvm
-#endif // LLVM_LIB_CODEGEN_ASMPRINTER_PSEUDOPROBEPRINTER_H
+//===- PseudoProbePrinter.h - Pseudo probe encoding support -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains support for writing pseudo probe info into asm files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_PSEUDOPROBEPRINTER_H
+#define LLVM_LIB_CODEGEN_ASMPRINTER_PSEUDOPROBEPRINTER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/AsmPrinterHandler.h"
+
+namespace llvm {
+
+class AsmPrinter;
+class MCStreamer;
+class Module;
+class DILocation;
+
+class PseudoProbeHandler : public AsmPrinterHandler {
+ // Target of pseudo probe emission.
+ AsmPrinter *Asm;
+ // Name to GUID map
+ DenseMap<StringRef, uint64_t> Names;
+
+public:
+ PseudoProbeHandler(AsmPrinter *A, Module *M);
+ ~PseudoProbeHandler() override;
+
+ void emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type,
+ uint64_t Attr, const DILocation *DebugLoc);
+
+ // Unused.
+ void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {}
+ void endModule() override {}
+ void beginFunction(const MachineFunction *MF) override {}
+ void endFunction(const MachineFunction *MF) override {}
+ void beginInstruction(const MachineInstr *MI) override {}
+ void endInstruction() override {}
+
+#ifndef NDEBUG
+ void dump() const;
+#endif
+};
+
+} // namespace llvm
+#endif // LLVM_LIB_CODEGEN_ASMPRINTER_PSEUDOPROBEPRINTER_H
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WasmException.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WasmException.cpp
index c40a8b3c85..352a33e863 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WasmException.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WasmException.cpp
@@ -18,11 +18,11 @@
using namespace llvm;
void WasmException::endModule() {
- // This is the symbol used in 'throw' and 'catch' instruction to denote this
- // is a C++ exception. This symbol has to be emitted somewhere once in the
- // module. Check if the symbol has already been created, i.e., we have at
- // least one 'throw' or 'catch' instruction in the module, and emit the symbol
- // only if so.
+ // This is the symbol used in 'throw' and 'catch' instruction to denote this
+ // is a C++ exception. This symbol has to be emitted somewhere once in the
+ // module. Check if the symbol has already been created, i.e., we have at
+ // least one 'throw' or 'catch' instruction in the module, and emit the symbol
+ // only if so.
SmallString<60> NameStr;
Mangler::getNameWithPrefix(NameStr, "__cpp_exception", Asm->getDataLayout());
if (Asm->OutContext.lookupSymbol(NameStr)) {
@@ -76,7 +76,7 @@ void WasmException::endFunction(const MachineFunction *MF) {
// information.
void WasmException::computeCallSiteTable(
SmallVectorImpl<CallSiteEntry> &CallSites,
- SmallVectorImpl<CallSiteRange> &CallSiteRanges,
+ SmallVectorImpl<CallSiteRange> &CallSiteRanges,
const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
const SmallVectorImpl<unsigned> &FirstActions) {
MachineFunction &MF = *Asm->MF;
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WasmException.h b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WasmException.h
index 40c5013539..f06de786bd 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WasmException.h
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WasmException.h
@@ -32,7 +32,7 @@ protected:
// Compute the call site table for wasm EH.
void computeCallSiteTable(
SmallVectorImpl<CallSiteEntry> &CallSites,
- SmallVectorImpl<CallSiteRange> &CallSiteRanges,
+ SmallVectorImpl<CallSiteRange> &CallSiteRanges,
const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
const SmallVectorImpl<unsigned> &FirstActions) override;
};
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WinCFGuard.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WinCFGuard.cpp
index 1486c9e868..1e3f33e707 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WinCFGuard.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WinCFGuard.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
//
// This file contains support for writing the metadata for Windows Control Flow
-// Guard, including address-taken functions and valid longjmp targets.
+// Guard, including address-taken functions and valid longjmp targets.
//
//===----------------------------------------------------------------------===//
@@ -17,7 +17,7 @@
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/IR/Constants.h"
-#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/IR/Metadata.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
@@ -38,7 +38,7 @@ void WinCFGuard::endFunction(const MachineFunction *MF) {
return;
// Copy the function's longjmp targets to a module-level list.
- llvm::append_range(LongjmpTargets, MF->getLongjmpTargets());
+ llvm::append_range(LongjmpTargets, MF->getLongjmpTargets());
}
/// Returns true if this function's address is escaped in a way that might make
@@ -77,50 +77,50 @@ static bool isPossibleIndirectCallTarget(const Function *F) {
return false;
}
-MCSymbol *WinCFGuard::lookupImpSymbol(const MCSymbol *Sym) {
- if (Sym->getName().startswith("__imp_"))
- return nullptr;
- return Asm->OutContext.lookupSymbol(Twine("__imp_") + Sym->getName());
-}
-
+MCSymbol *WinCFGuard::lookupImpSymbol(const MCSymbol *Sym) {
+ if (Sym->getName().startswith("__imp_"))
+ return nullptr;
+ return Asm->OutContext.lookupSymbol(Twine("__imp_") + Sym->getName());
+}
+
void WinCFGuard::endModule() {
const Module *M = Asm->MMI->getModule();
- std::vector<const MCSymbol *> GFIDsEntries;
- std::vector<const MCSymbol *> GIATsEntries;
- for (const Function &F : *M) {
- if (isPossibleIndirectCallTarget(&F)) {
- // If F is a dllimport and has an "__imp_" symbol already defined, add the
- // "__imp_" symbol to the .giats section.
- if (F.hasDLLImportStorageClass()) {
- if (MCSymbol *impSym = lookupImpSymbol(Asm->getSymbol(&F))) {
- GIATsEntries.push_back(impSym);
- }
- }
- // Add the function's symbol to the .gfids section.
- // Note: For dllimport functions, MSVC sometimes does not add this symbol
- // to the .gfids section, but only adds the corresponding "__imp_" symbol
- // to the .giats section. Here we always add the symbol to the .gfids
- // section, since this does not introduce security risks.
- GFIDsEntries.push_back(Asm->getSymbol(&F));
- }
- }
-
- if (GFIDsEntries.empty() && GIATsEntries.empty() && LongjmpTargets.empty())
+ std::vector<const MCSymbol *> GFIDsEntries;
+ std::vector<const MCSymbol *> GIATsEntries;
+ for (const Function &F : *M) {
+ if (isPossibleIndirectCallTarget(&F)) {
+ // If F is a dllimport and has an "__imp_" symbol already defined, add the
+ // "__imp_" symbol to the .giats section.
+ if (F.hasDLLImportStorageClass()) {
+ if (MCSymbol *impSym = lookupImpSymbol(Asm->getSymbol(&F))) {
+ GIATsEntries.push_back(impSym);
+ }
+ }
+ // Add the function's symbol to the .gfids section.
+ // Note: For dllimport functions, MSVC sometimes does not add this symbol
+ // to the .gfids section, but only adds the corresponding "__imp_" symbol
+ // to the .giats section. Here we always add the symbol to the .gfids
+ // section, since this does not introduce security risks.
+ GFIDsEntries.push_back(Asm->getSymbol(&F));
+ }
+ }
+
+ if (GFIDsEntries.empty() && GIATsEntries.empty() && LongjmpTargets.empty())
return;
-
- // Emit the symbol index of each GFIDs entry to form the .gfids section.
+
+ // Emit the symbol index of each GFIDs entry to form the .gfids section.
auto &OS = *Asm->OutStreamer;
OS.SwitchSection(Asm->OutContext.getObjectFileInfo()->getGFIDsSection());
- for (const MCSymbol *S : GFIDsEntries)
- OS.EmitCOFFSymbolIndex(S);
+ for (const MCSymbol *S : GFIDsEntries)
+ OS.EmitCOFFSymbolIndex(S);
+
+ // Emit the symbol index of each GIATs entry to form the .giats section.
+ OS.SwitchSection(Asm->OutContext.getObjectFileInfo()->getGIATsSection());
+ for (const MCSymbol *S : GIATsEntries) {
+ OS.EmitCOFFSymbolIndex(S);
+ }
- // Emit the symbol index of each GIATs entry to form the .giats section.
- OS.SwitchSection(Asm->OutContext.getObjectFileInfo()->getGIATsSection());
- for (const MCSymbol *S : GIATsEntries) {
- OS.EmitCOFFSymbolIndex(S);
- }
-
- // Emit the symbol index of each longjmp target to form the .gljmp section.
+ // Emit the symbol index of each longjmp target to form the .gljmp section.
OS.SwitchSection(Asm->OutContext.getObjectFileInfo()->getGLJMPSection());
for (const MCSymbol *S : LongjmpTargets) {
OS.EmitCOFFSymbolIndex(S);
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WinCFGuard.h b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WinCFGuard.h
index 870345f1eb..0e472af52c 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WinCFGuard.h
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WinCFGuard.h
@@ -24,7 +24,7 @@ class LLVM_LIBRARY_VISIBILITY WinCFGuard : public AsmPrinterHandler {
/// Target of directive emission.
AsmPrinter *Asm;
std::vector<const MCSymbol *> LongjmpTargets;
- MCSymbol *lookupImpSymbol(const MCSymbol *Sym);
+ MCSymbol *lookupImpSymbol(const MCSymbol *Sym);
public:
WinCFGuard(AsmPrinter *A);
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WinException.cpp b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WinException.cpp
index e981bd0d96..3a9c9df797 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WinException.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/WinException.cpp
@@ -137,8 +137,8 @@ void WinException::endFunction(const MachineFunction *MF) {
endFuncletImpl();
- // endFunclet will emit the necessary .xdata tables for table-based SEH.
- if (Per == EHPersonality::MSVC_TableSEH && MF->hasEHFunclets())
+ // endFunclet will emit the necessary .xdata tables for table-based SEH.
+ if (Per == EHPersonality::MSVC_TableSEH && MF->hasEHFunclets())
return;
if (shouldEmitPersonality || shouldEmitLSDA) {
@@ -151,7 +151,7 @@ void WinException::endFunction(const MachineFunction *MF) {
// Emit the tables appropriate to the personality function in use. If we
// don't recognize the personality, assume it uses an Itanium-style LSDA.
- if (Per == EHPersonality::MSVC_TableSEH)
+ if (Per == EHPersonality::MSVC_TableSEH)
emitCSpecificHandlerTable(MF);
else if (Per == EHPersonality::MSVC_X86SEH)
emitExceptHandlerTable(MF);
@@ -260,33 +260,33 @@ void WinException::endFuncletImpl() {
if (Per == EHPersonality::MSVC_CXX && shouldEmitPersonality &&
!CurrentFuncletEntry->isCleanupFuncletEntry()) {
- // Emit an UNWIND_INFO struct describing the prologue.
- Asm->OutStreamer->EmitWinEHHandlerData();
-
+ // Emit an UNWIND_INFO struct describing the prologue.
+ Asm->OutStreamer->EmitWinEHHandlerData();
+
// If this is a C++ catch funclet (or the parent function),
// emit a reference to the LSDA for the parent function.
StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName());
MCSymbol *FuncInfoXData = Asm->OutContext.getOrCreateSymbol(
Twine("$cppxdata$", FuncLinkageName));
Asm->OutStreamer->emitValue(create32bitRef(FuncInfoXData), 4);
- } else if (Per == EHPersonality::MSVC_TableSEH && MF->hasEHFunclets() &&
+ } else if (Per == EHPersonality::MSVC_TableSEH && MF->hasEHFunclets() &&
!CurrentFuncletEntry->isEHFuncletEntry()) {
- // Emit an UNWIND_INFO struct describing the prologue.
- Asm->OutStreamer->EmitWinEHHandlerData();
-
+ // Emit an UNWIND_INFO struct describing the prologue.
+ Asm->OutStreamer->EmitWinEHHandlerData();
+
// If this is the parent function in Win64 SEH, emit the LSDA immediately
// following .seh_handlerdata.
emitCSpecificHandlerTable(MF);
- } else if (shouldEmitPersonality || shouldEmitLSDA) {
- // Emit an UNWIND_INFO struct describing the prologue.
- Asm->OutStreamer->EmitWinEHHandlerData();
- // In these cases, no further info is written to the .xdata section
- // right here, but is written by e.g. emitExceptionTable in endFunction()
- // above.
- } else {
- // No need to emit the EH handler data right here if nothing needs
- // writing to the .xdata section; it will be emitted for all
- // functions that need it in the end anyway.
+ } else if (shouldEmitPersonality || shouldEmitLSDA) {
+ // Emit an UNWIND_INFO struct describing the prologue.
+ Asm->OutStreamer->EmitWinEHHandlerData();
+ // In these cases, no further info is written to the .xdata section
+ // right here, but is written by e.g. emitExceptionTable in endFunction()
+ // above.
+ } else {
+ // No need to emit the EH handler data right here if nothing needs
+ // writing to the .xdata section; it will be emitted for all
+ // functions that need it in the end anyway.
}
// Switch back to the funclet start .text section now that we are done
@@ -343,24 +343,24 @@ int WinException::getFrameIndexOffset(int FrameIndex,
const TargetFrameLowering &TFI = *Asm->MF->getSubtarget().getFrameLowering();
Register UnusedReg;
if (Asm->MAI->usesWindowsCFI()) {
- StackOffset Offset =
+ StackOffset Offset =
TFI.getFrameIndexReferencePreferSP(*Asm->MF, FrameIndex, UnusedReg,
/*IgnoreSPUpdates*/ true);
assert(UnusedReg ==
Asm->MF->getSubtarget()
.getTargetLowering()
->getStackPointerRegisterToSaveRestore());
- return Offset.getFixed();
+ return Offset.getFixed();
}
// For 32-bit, offsets should be relative to the end of the EH registration
// node. For 64-bit, it's relative to SP at the end of the prologue.
assert(FuncInfo.EHRegNodeEndOffset != INT_MAX);
- StackOffset Offset = TFI.getFrameIndexReference(*Asm->MF, FrameIndex, UnusedReg);
- Offset += StackOffset::getFixed(FuncInfo.EHRegNodeEndOffset);
- assert(!Offset.getScalable() &&
- "Frame offsets with a scalable component are not supported");
- return Offset.getFixed();
+ StackOffset Offset = TFI.getFrameIndexReference(*Asm->MF, FrameIndex, UnusedReg);
+ Offset += StackOffset::getFixed(FuncInfo.EHRegNodeEndOffset);
+ assert(!Offset.getScalable() &&
+ "Frame offsets with a scalable component are not supported");
+ return Offset.getFixed();
}
namespace {
@@ -957,7 +957,7 @@ void WinException::emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo,
int FI = FuncInfo.EHRegNodeFrameIndex;
if (FI != INT_MAX) {
const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
- Offset = TFI->getNonLocalFrameIndexReference(*Asm->MF, FI).getFixed();
+ Offset = TFI->getNonLocalFrameIndexReference(*Asm->MF, FI).getFixed();
}
MCContext &Ctx = Asm->OutContext;
@@ -1021,8 +1021,8 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
Register UnusedReg;
const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering();
int SSPIdx = MFI.getStackProtectorIndex();
- GSCookieOffset =
- TFI->getFrameIndexReference(*MF, SSPIdx, UnusedReg).getFixed();
+ GSCookieOffset =
+ TFI->getFrameIndexReference(*MF, SSPIdx, UnusedReg).getFixed();
}
// Retrieve the EH Guard slot.
@@ -1032,8 +1032,8 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
Register UnusedReg;
const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering();
int EHGuardIdx = FuncInfo.EHGuardFrameIndex;
- EHCookieOffset =
- TFI->getFrameIndexReference(*MF, EHGuardIdx, UnusedReg).getFixed();
+ EHCookieOffset =
+ TFI->getFrameIndexReference(*MF, EHGuardIdx, UnusedReg).getFixed();
}
AddComment("GSCookieOffset");
diff --git a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/ya.make b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/ya.make
index 47a05ac91e..47d6139b3d 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/ya.make
+++ b/contrib/libs/llvm12/lib/CodeGen/AsmPrinter/ya.make
@@ -12,25 +12,25 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/CodeGen
- contrib/libs/llvm12/lib/DebugInfo/CodeView
- contrib/libs/llvm12/lib/DebugInfo/DWARF
- contrib/libs/llvm12/lib/DebugInfo/MSF
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/MC/MCParser
- contrib/libs/llvm12/lib/Remarks
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/CodeGen
+ contrib/libs/llvm12/lib/DebugInfo/CodeView
+ contrib/libs/llvm12/lib/DebugInfo/DWARF
+ contrib/libs/llvm12/lib/DebugInfo/MSF
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/MC/MCParser
+ contrib/libs/llvm12/lib/Remarks
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target
)
IF (SANITIZER_TYPE == "undefined")
PEERDIR(
- contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc
)
ENDIF()
@@ -43,7 +43,7 @@ NO_COMPILER_WARNINGS()
NO_UTIL()
SRCS(
- AIXException.cpp
+ AIXException.cpp
ARMException.cpp
AccelTable.cpp
AddressPool.cpp
@@ -66,7 +66,7 @@ SRCS(
EHStreamer.cpp
ErlangGCPrinter.cpp
OcamlGCPrinter.cpp
- PseudoProbePrinter.cpp
+ PseudoProbePrinter.cpp
WasmException.cpp
WinCFGuard.cpp
WinException.cpp
diff --git a/contrib/libs/llvm12/lib/CodeGen/AtomicExpandPass.cpp b/contrib/libs/llvm12/lib/CodeGen/AtomicExpandPass.cpp
index 3a9bde744e..4026022caa 100644
--- a/contrib/libs/llvm12/lib/CodeGen/AtomicExpandPass.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/AtomicExpandPass.cpp
@@ -1507,8 +1507,8 @@ void AtomicExpand::expandAtomicLoadToLibcall(LoadInst *I) {
bool expanded = expandAtomicOpToLibcall(
I, Size, I->getAlign(), I->getPointerOperand(), nullptr, nullptr,
I->getOrdering(), AtomicOrdering::NotAtomic, Libcalls);
- if (!expanded)
- report_fatal_error("expandAtomicOpToLibcall shouldn't fail for Load");
+ if (!expanded)
+ report_fatal_error("expandAtomicOpToLibcall shouldn't fail for Load");
}
void AtomicExpand::expandAtomicStoreToLibcall(StoreInst *I) {
@@ -1520,8 +1520,8 @@ void AtomicExpand::expandAtomicStoreToLibcall(StoreInst *I) {
bool expanded = expandAtomicOpToLibcall(
I, Size, I->getAlign(), I->getPointerOperand(), I->getValueOperand(),
nullptr, I->getOrdering(), AtomicOrdering::NotAtomic, Libcalls);
- if (!expanded)
- report_fatal_error("expandAtomicOpToLibcall shouldn't fail for Store");
+ if (!expanded)
+ report_fatal_error("expandAtomicOpToLibcall shouldn't fail for Store");
}
void AtomicExpand::expandAtomicCASToLibcall(AtomicCmpXchgInst *I) {
@@ -1535,8 +1535,8 @@ void AtomicExpand::expandAtomicCASToLibcall(AtomicCmpXchgInst *I) {
I, Size, I->getAlign(), I->getPointerOperand(), I->getNewValOperand(),
I->getCompareOperand(), I->getSuccessOrdering(), I->getFailureOrdering(),
Libcalls);
- if (!expanded)
- report_fatal_error("expandAtomicOpToLibcall shouldn't fail for CAS");
+ if (!expanded)
+ report_fatal_error("expandAtomicOpToLibcall shouldn't fail for CAS");
}
static ArrayRef<RTLIB::Libcall> GetRMWLibcall(AtomicRMWInst::BinOp Op) {
@@ -1685,11 +1685,11 @@ bool AtomicExpand::expandAtomicOpToLibcall(
return false;
}
- if (!TLI->getLibcallName(RTLibType)) {
- // This target does not implement the requested atomic libcall so give up.
- return false;
- }
-
+ if (!TLI->getLibcallName(RTLibType)) {
+ // This target does not implement the requested atomic libcall so give up.
+ return false;
+ }
+
// Build up the function call. There's two kinds. First, the sized
// variants. These calls are going to be one of the following (with
// N=1,2,4,8,16):
diff --git a/contrib/libs/llvm12/lib/CodeGen/BasicBlockSections.cpp b/contrib/libs/llvm12/lib/CodeGen/BasicBlockSections.cpp
index ba1b0a91ca..7499ea8b42 100644
--- a/contrib/libs/llvm12/lib/CodeGen/BasicBlockSections.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/BasicBlockSections.cpp
@@ -1,484 +1,484 @@
-//===-- BasicBlockSections.cpp ---=========--------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// BasicBlockSections implementation.
-//
-// The purpose of this pass is to assign sections to basic blocks when
-// -fbasic-block-sections= option is used. Further, with profile information
-// only the subset of basic blocks with profiles are placed in separate sections
-// and the rest are grouped in a cold section. The exception handling blocks are
-// treated specially to ensure they are all in one seciton.
-//
-// Basic Block Sections
-// ====================
-//
-// With option, -fbasic-block-sections=list, every function may be split into
-// clusters of basic blocks. Every cluster will be emitted into a separate
-// section with its basic blocks sequenced in the given order. To get the
-// optimized performance, the clusters must form an optimal BB layout for the
-// function. Every cluster's section is labeled with a symbol to allow the
-// linker to reorder the sections in any arbitrary sequence. A global order of
-// these sections would encapsulate the function layout.
-//
-// There are a couple of challenges to be addressed:
-//
-// 1. The last basic block of every cluster should not have any implicit
-// fallthrough to its next basic block, as it can be reordered by the linker.
-// The compiler should make these fallthroughs explicit by adding
-// unconditional jumps..
-//
-// 2. All inter-cluster branch targets would now need to be resolved by the
-// linker as they cannot be calculated during compile time. This is done
-// using static relocations. Further, the compiler tries to use short branch
-// instructions on some ISAs for small branch offsets. This is not possible
-// for inter-cluster branches as the offset is not determined at compile
-// time, and therefore, long branch instructions have to be used for those.
-//
-// 3. Debug Information (DebugInfo) and Call Frame Information (CFI) emission
-// needs special handling with basic block sections. DebugInfo needs to be
-// emitted with more relocations as basic block sections can break a
-// function into potentially several disjoint pieces, and CFI needs to be
-// emitted per cluster. This also bloats the object file and binary sizes.
-//
-// Basic Block Labels
-// ==================
-//
-// With -fbasic-block-sections=labels, we emit the offsets of BB addresses of
-// every function into the .llvm_bb_addr_map section. Along with the function
-// symbols, this allows for mapping of virtual addresses in PMU profiles back to
-// the corresponding basic blocks. This logic is implemented in AsmPrinter. This
-// pass only assigns the BBSectionType of every function to ``labels``.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/CodeGen/BasicBlockSectionUtils.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/TargetInstrInfo.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/LineIterator.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Target/TargetMachine.h"
-
-using llvm::SmallSet;
-using llvm::SmallVector;
-using llvm::StringMap;
-using llvm::StringRef;
-using namespace llvm;
-
-// Placing the cold clusters in a separate section mitigates against poor
-// profiles and allows optimizations such as hugepage mapping to be applied at a
-// section granularity. Defaults to ".text.split." which is recognized by lld
-// via the `-z keep-text-section-prefix` flag.
-cl::opt<std::string> llvm::BBSectionsColdTextPrefix(
- "bbsections-cold-text-prefix",
- cl::desc("The text prefix to use for cold basic block clusters"),
- cl::init(".text.split."), cl::Hidden);
-
-namespace {
-
-// This struct represents the cluster information for a machine basic block.
-struct BBClusterInfo {
- // MachineBasicBlock ID.
- unsigned MBBNumber;
- // Cluster ID this basic block belongs to.
- unsigned ClusterID;
- // Position of basic block within the cluster.
- unsigned PositionInCluster;
-};
-
-using ProgramBBClusterInfoMapTy = StringMap<SmallVector<BBClusterInfo, 4>>;
-
-class BasicBlockSections : public MachineFunctionPass {
-public:
- static char ID;
-
- // This contains the basic-block-sections profile.
- const MemoryBuffer *MBuf = nullptr;
-
- // This encapsulates the BB cluster information for the whole program.
- //
- // For every function name, it contains the cluster information for (all or
- // some of) its basic blocks. The cluster information for every basic block
- // includes its cluster ID along with the position of the basic block in that
- // cluster.
- ProgramBBClusterInfoMapTy ProgramBBClusterInfo;
-
- // Some functions have alias names. We use this map to find the main alias
- // name for which we have mapping in ProgramBBClusterInfo.
- StringMap<StringRef> FuncAliasMap;
-
- BasicBlockSections(const MemoryBuffer *Buf)
- : MachineFunctionPass(ID), MBuf(Buf) {
- initializeBasicBlockSectionsPass(*PassRegistry::getPassRegistry());
- };
-
- BasicBlockSections() : MachineFunctionPass(ID) {
- initializeBasicBlockSectionsPass(*PassRegistry::getPassRegistry());
- }
-
- StringRef getPassName() const override {
- return "Basic Block Sections Analysis";
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override;
-
- /// Read profiles of basic blocks if available here.
- bool doInitialization(Module &M) override;
-
- /// Identify basic blocks that need separate sections and prepare to emit them
- /// accordingly.
- bool runOnMachineFunction(MachineFunction &MF) override;
-};
-
-} // end anonymous namespace
-
-char BasicBlockSections::ID = 0;
-INITIALIZE_PASS(BasicBlockSections, "bbsections-prepare",
- "Prepares for basic block sections, by splitting functions "
- "into clusters of basic blocks.",
- false, false)
-
-// This function updates and optimizes the branching instructions of every basic
-// block in a given function to account for changes in the layout.
-static void updateBranches(
- MachineFunction &MF,
- const SmallVector<MachineBasicBlock *, 4> &PreLayoutFallThroughs) {
- const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
- SmallVector<MachineOperand, 4> Cond;
- for (auto &MBB : MF) {
- auto NextMBBI = std::next(MBB.getIterator());
- auto *FTMBB = PreLayoutFallThroughs[MBB.getNumber()];
- // If this block had a fallthrough before we need an explicit unconditional
- // branch to that block if either
- // 1- the block ends a section, which means its next block may be
- // reorderd by the linker, or
- // 2- the fallthrough block is not adjacent to the block in the new
- // order.
- if (FTMBB && (MBB.isEndSection() || &*NextMBBI != FTMBB))
- TII->insertUnconditionalBranch(MBB, FTMBB, MBB.findBranchDebugLoc());
-
- // We do not optimize branches for machine basic blocks ending sections, as
- // their adjacent block might be reordered by the linker.
- if (MBB.isEndSection())
- continue;
-
- // It might be possible to optimize branches by flipping the branch
- // condition.
- Cond.clear();
- MachineBasicBlock *TBB = nullptr, *FBB = nullptr; // For analyzeBranch.
- if (TII->analyzeBranch(MBB, TBB, FBB, Cond))
- continue;
- MBB.updateTerminator(FTMBB);
- }
-}
-
-// This function provides the BBCluster information associated with a function.
-// Returns true if a valid association exists and false otherwise.
-static bool getBBClusterInfoForFunction(
- const MachineFunction &MF, const StringMap<StringRef> FuncAliasMap,
- const ProgramBBClusterInfoMapTy &ProgramBBClusterInfo,
- std::vector<Optional<BBClusterInfo>> &V) {
- // Get the main alias name for the function.
- auto FuncName = MF.getName();
- auto R = FuncAliasMap.find(FuncName);
- StringRef AliasName = R == FuncAliasMap.end() ? FuncName : R->second;
-
- // Find the assoicated cluster information.
- auto P = ProgramBBClusterInfo.find(AliasName);
- if (P == ProgramBBClusterInfo.end())
- return false;
-
- if (P->second.empty()) {
- // This indicates that sections are desired for all basic blocks of this
- // function. We clear the BBClusterInfo vector to denote this.
- V.clear();
- return true;
- }
-
- V.resize(MF.getNumBlockIDs());
- for (auto bbClusterInfo : P->second) {
- // Bail out if the cluster information contains invalid MBB numbers.
- if (bbClusterInfo.MBBNumber >= MF.getNumBlockIDs())
- return false;
- V[bbClusterInfo.MBBNumber] = bbClusterInfo;
- }
- return true;
-}
-
-// This function sorts basic blocks according to the cluster's information.
-// All explicitly specified clusters of basic blocks will be ordered
-// accordingly. All non-specified BBs go into a separate "Cold" section.
-// Additionally, if exception handling landing pads end up in more than one
-// clusters, they are moved into a single "Exception" section. Eventually,
-// clusters are ordered in increasing order of their IDs, with the "Exception"
-// and "Cold" succeeding all other clusters.
-// FuncBBClusterInfo represent the cluster information for basic blocks. If this
-// is empty, it means unique sections for all basic blocks in the function.
-static void
-assignSections(MachineFunction &MF,
- const std::vector<Optional<BBClusterInfo>> &FuncBBClusterInfo) {
- assert(MF.hasBBSections() && "BB Sections is not set for function.");
- // This variable stores the section ID of the cluster containing eh_pads (if
- // all eh_pads are one cluster). If more than one cluster contain eh_pads, we
- // set it equal to ExceptionSectionID.
- Optional<MBBSectionID> EHPadsSectionID;
-
- for (auto &MBB : MF) {
- // With the 'all' option, every basic block is placed in a unique section.
- // With the 'list' option, every basic block is placed in a section
- // associated with its cluster, unless we want individual unique sections
- // for every basic block in this function (if FuncBBClusterInfo is empty).
- if (MF.getTarget().getBBSectionsType() == llvm::BasicBlockSection::All ||
- FuncBBClusterInfo.empty()) {
- // If unique sections are desired for all basic blocks of the function, we
- // set every basic block's section ID equal to its number (basic block
- // id). This further ensures that basic blocks are ordered canonically.
- MBB.setSectionID({static_cast<unsigned int>(MBB.getNumber())});
- } else if (FuncBBClusterInfo[MBB.getNumber()].hasValue())
- MBB.setSectionID(FuncBBClusterInfo[MBB.getNumber()]->ClusterID);
- else {
- // BB goes into the special cold section if it is not specified in the
- // cluster info map.
- MBB.setSectionID(MBBSectionID::ColdSectionID);
- }
-
- if (MBB.isEHPad() && EHPadsSectionID != MBB.getSectionID() &&
- EHPadsSectionID != MBBSectionID::ExceptionSectionID) {
- // If we already have one cluster containing eh_pads, this must be updated
- // to ExceptionSectionID. Otherwise, we set it equal to the current
- // section ID.
- EHPadsSectionID = EHPadsSectionID.hasValue()
- ? MBBSectionID::ExceptionSectionID
- : MBB.getSectionID();
- }
- }
-
- // If EHPads are in more than one section, this places all of them in the
- // special exception section.
- if (EHPadsSectionID == MBBSectionID::ExceptionSectionID)
- for (auto &MBB : MF)
- if (MBB.isEHPad())
- MBB.setSectionID(EHPadsSectionID.getValue());
-}
-
-void llvm::sortBasicBlocksAndUpdateBranches(
- MachineFunction &MF, MachineBasicBlockComparator MBBCmp) {
- SmallVector<MachineBasicBlock *, 4> PreLayoutFallThroughs(
- MF.getNumBlockIDs());
- for (auto &MBB : MF)
- PreLayoutFallThroughs[MBB.getNumber()] = MBB.getFallThrough();
-
- MF.sort(MBBCmp);
-
- // Set IsBeginSection and IsEndSection according to the assigned section IDs.
- MF.assignBeginEndSections();
-
- // After reordering basic blocks, we must update basic block branches to
- // insert explicit fallthrough branches when required and optimize branches
- // when possible.
- updateBranches(MF, PreLayoutFallThroughs);
-}
-
-// If the exception section begins with a landing pad, that landing pad will
-// assume a zero offset (relative to @LPStart) in the LSDA. However, a value of
-// zero implies "no landing pad." This function inserts a NOP just before the EH
-// pad label to ensure a nonzero offset. Returns true if padding is not needed.
-static bool avoidZeroOffsetLandingPad(MachineFunction &MF) {
- for (auto &MBB : MF) {
- if (MBB.isBeginSection() && MBB.isEHPad()) {
- MachineBasicBlock::iterator MI = MBB.begin();
- while (!MI->isEHLabel())
- ++MI;
- MCInst Noop;
- MF.getSubtarget().getInstrInfo()->getNoop(Noop);
- BuildMI(MBB, MI, DebugLoc(),
- MF.getSubtarget().getInstrInfo()->get(Noop.getOpcode()));
- return false;
- }
- }
- return true;
-}
-
-bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) {
- auto BBSectionsType = MF.getTarget().getBBSectionsType();
- assert(BBSectionsType != BasicBlockSection::None &&
- "BB Sections not enabled!");
- // Renumber blocks before sorting them for basic block sections. This is
- // useful during sorting, basic blocks in the same section will retain the
- // default order. This renumbering should also be done for basic block
- // labels to match the profiles with the correct blocks.
- MF.RenumberBlocks();
-
- if (BBSectionsType == BasicBlockSection::Labels) {
- MF.setBBSectionsType(BBSectionsType);
- return true;
- }
-
- std::vector<Optional<BBClusterInfo>> FuncBBClusterInfo;
- if (BBSectionsType == BasicBlockSection::List &&
- !getBBClusterInfoForFunction(MF, FuncAliasMap, ProgramBBClusterInfo,
- FuncBBClusterInfo))
- return true;
- MF.setBBSectionsType(BBSectionsType);
- assignSections(MF, FuncBBClusterInfo);
-
- // We make sure that the cluster including the entry basic block precedes all
- // other clusters.
- auto EntryBBSectionID = MF.front().getSectionID();
-
- // Helper function for ordering BB sections as follows:
- // * Entry section (section including the entry block).
- // * Regular sections (in increasing order of their Number).
- // ...
- // * Exception section
- // * Cold section
- auto MBBSectionOrder = [EntryBBSectionID](const MBBSectionID &LHS,
- const MBBSectionID &RHS) {
- // We make sure that the section containing the entry block precedes all the
- // other sections.
- if (LHS == EntryBBSectionID || RHS == EntryBBSectionID)
- return LHS == EntryBBSectionID;
- return LHS.Type == RHS.Type ? LHS.Number < RHS.Number : LHS.Type < RHS.Type;
- };
-
- // We sort all basic blocks to make sure the basic blocks of every cluster are
- // contiguous and ordered accordingly. Furthermore, clusters are ordered in
- // increasing order of their section IDs, with the exception and the
- // cold section placed at the end of the function.
- auto Comparator = [&](const MachineBasicBlock &X,
- const MachineBasicBlock &Y) {
- auto XSectionID = X.getSectionID();
- auto YSectionID = Y.getSectionID();
- if (XSectionID != YSectionID)
- return MBBSectionOrder(XSectionID, YSectionID);
- // If the two basic block are in the same section, the order is decided by
- // their position within the section.
- if (XSectionID.Type == MBBSectionID::SectionType::Default)
- return FuncBBClusterInfo[X.getNumber()]->PositionInCluster <
- FuncBBClusterInfo[Y.getNumber()]->PositionInCluster;
- return X.getNumber() < Y.getNumber();
- };
-
- sortBasicBlocksAndUpdateBranches(MF, Comparator);
- avoidZeroOffsetLandingPad(MF);
- return true;
-}
-
-// Basic Block Sections can be enabled for a subset of machine basic blocks.
-// This is done by passing a file containing names of functions for which basic
-// block sections are desired. Additionally, machine basic block ids of the
-// functions can also be specified for a finer granularity. Moreover, a cluster
-// of basic blocks could be assigned to the same section.
-// A file with basic block sections for all of function main and three blocks
-// for function foo (of which 1 and 2 are placed in a cluster) looks like this:
-// ----------------------------
-// list.txt:
-// !main
-// !foo
-// !!1 2
-// !!4
-static Error getBBClusterInfo(const MemoryBuffer *MBuf,
- ProgramBBClusterInfoMapTy &ProgramBBClusterInfo,
- StringMap<StringRef> &FuncAliasMap) {
- assert(MBuf);
- line_iterator LineIt(*MBuf, /*SkipBlanks=*/true, /*CommentMarker=*/'#');
-
- auto invalidProfileError = [&](auto Message) {
- return make_error<StringError>(
- Twine("Invalid profile " + MBuf->getBufferIdentifier() + " at line " +
- Twine(LineIt.line_number()) + ": " + Message),
- inconvertibleErrorCode());
- };
-
- auto FI = ProgramBBClusterInfo.end();
-
- // Current cluster ID corresponding to this function.
- unsigned CurrentCluster = 0;
- // Current position in the current cluster.
- unsigned CurrentPosition = 0;
-
- // Temporary set to ensure every basic block ID appears once in the clusters
- // of a function.
- SmallSet<unsigned, 4> FuncBBIDs;
-
- for (; !LineIt.is_at_eof(); ++LineIt) {
- StringRef S(*LineIt);
- if (S[0] == '@')
- continue;
- // Check for the leading "!"
- if (!S.consume_front("!") || S.empty())
- break;
- // Check for second "!" which indicates a cluster of basic blocks.
- if (S.consume_front("!")) {
- if (FI == ProgramBBClusterInfo.end())
- return invalidProfileError(
- "Cluster list does not follow a function name specifier.");
- SmallVector<StringRef, 4> BBIndexes;
- S.split(BBIndexes, ' ');
- // Reset current cluster position.
- CurrentPosition = 0;
- for (auto BBIndexStr : BBIndexes) {
- unsigned long long BBIndex;
- if (getAsUnsignedInteger(BBIndexStr, 10, BBIndex))
- return invalidProfileError(Twine("Unsigned integer expected: '") +
- BBIndexStr + "'.");
- if (!FuncBBIDs.insert(BBIndex).second)
- return invalidProfileError(Twine("Duplicate basic block id found '") +
- BBIndexStr + "'.");
- if (!BBIndex && CurrentPosition)
- return invalidProfileError("Entry BB (0) does not begin a cluster.");
-
- FI->second.emplace_back(BBClusterInfo{
- ((unsigned)BBIndex), CurrentCluster, CurrentPosition++});
- }
- CurrentCluster++;
- } else { // This is a function name specifier.
- // Function aliases are separated using '/'. We use the first function
- // name for the cluster info mapping and delegate all other aliases to
- // this one.
- SmallVector<StringRef, 4> Aliases;
- S.split(Aliases, '/');
- for (size_t i = 1; i < Aliases.size(); ++i)
- FuncAliasMap.try_emplace(Aliases[i], Aliases.front());
-
- // Prepare for parsing clusters of this function name.
- // Start a new cluster map for this function name.
- FI = ProgramBBClusterInfo.try_emplace(Aliases.front()).first;
- CurrentCluster = 0;
- FuncBBIDs.clear();
- }
- }
- return Error::success();
-}
-
-bool BasicBlockSections::doInitialization(Module &M) {
- if (!MBuf)
- return false;
- if (auto Err = getBBClusterInfo(MBuf, ProgramBBClusterInfo, FuncAliasMap))
- report_fatal_error(std::move(Err));
- return false;
-}
-
-void BasicBlockSections::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- MachineFunctionPass::getAnalysisUsage(AU);
-}
-
-MachineFunctionPass *
-llvm::createBasicBlockSectionsPass(const MemoryBuffer *Buf) {
- return new BasicBlockSections(Buf);
-}
+//===-- BasicBlockSections.cpp ---=========--------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// BasicBlockSections implementation.
+//
+// The purpose of this pass is to assign sections to basic blocks when
+// -fbasic-block-sections= option is used. Further, with profile information
+// only the subset of basic blocks with profiles are placed in separate sections
+// and the rest are grouped in a cold section. The exception handling blocks are
+// treated specially to ensure they are all in one seciton.
+//
+// Basic Block Sections
+// ====================
+//
+// With option, -fbasic-block-sections=list, every function may be split into
+// clusters of basic blocks. Every cluster will be emitted into a separate
+// section with its basic blocks sequenced in the given order. To get the
+// optimized performance, the clusters must form an optimal BB layout for the
+// function. Every cluster's section is labeled with a symbol to allow the
+// linker to reorder the sections in any arbitrary sequence. A global order of
+// these sections would encapsulate the function layout.
+//
+// There are a couple of challenges to be addressed:
+//
+// 1. The last basic block of every cluster should not have any implicit
+// fallthrough to its next basic block, as it can be reordered by the linker.
+// The compiler should make these fallthroughs explicit by adding
+// unconditional jumps..
+//
+// 2. All inter-cluster branch targets would now need to be resolved by the
+// linker as they cannot be calculated during compile time. This is done
+// using static relocations. Further, the compiler tries to use short branch
+// instructions on some ISAs for small branch offsets. This is not possible
+// for inter-cluster branches as the offset is not determined at compile
+// time, and therefore, long branch instructions have to be used for those.
+//
+// 3. Debug Information (DebugInfo) and Call Frame Information (CFI) emission
+// needs special handling with basic block sections. DebugInfo needs to be
+// emitted with more relocations as basic block sections can break a
+// function into potentially several disjoint pieces, and CFI needs to be
+// emitted per cluster. This also bloats the object file and binary sizes.
+//
+// Basic Block Labels
+// ==================
+//
+// With -fbasic-block-sections=labels, we emit the offsets of BB addresses of
+// every function into the .llvm_bb_addr_map section. Along with the function
+// symbols, this allows for mapping of virtual addresses in PMU profiles back to
+// the corresponding basic blocks. This logic is implemented in AsmPrinter. This
+// pass only assigns the BBSectionType of every function to ``labels``.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/CodeGen/BasicBlockSectionUtils.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/LineIterator.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Target/TargetMachine.h"
+
+using llvm::SmallSet;
+using llvm::SmallVector;
+using llvm::StringMap;
+using llvm::StringRef;
+using namespace llvm;
+
+// Placing the cold clusters in a separate section mitigates against poor
+// profiles and allows optimizations such as hugepage mapping to be applied at a
+// section granularity. Defaults to ".text.split." which is recognized by lld
+// via the `-z keep-text-section-prefix` flag.
+cl::opt<std::string> llvm::BBSectionsColdTextPrefix(
+ "bbsections-cold-text-prefix",
+ cl::desc("The text prefix to use for cold basic block clusters"),
+ cl::init(".text.split."), cl::Hidden);
+
+namespace {
+
+// This struct represents the cluster information for a machine basic block.
+struct BBClusterInfo {
+ // MachineBasicBlock ID.
+ unsigned MBBNumber;
+ // Cluster ID this basic block belongs to.
+ unsigned ClusterID;
+ // Position of basic block within the cluster.
+ unsigned PositionInCluster;
+};
+
+using ProgramBBClusterInfoMapTy = StringMap<SmallVector<BBClusterInfo, 4>>;
+
+class BasicBlockSections : public MachineFunctionPass {
+public:
+ static char ID;
+
+ // This contains the basic-block-sections profile.
+ const MemoryBuffer *MBuf = nullptr;
+
+ // This encapsulates the BB cluster information for the whole program.
+ //
+ // For every function name, it contains the cluster information for (all or
+ // some of) its basic blocks. The cluster information for every basic block
+ // includes its cluster ID along with the position of the basic block in that
+ // cluster.
+ ProgramBBClusterInfoMapTy ProgramBBClusterInfo;
+
+ // Some functions have alias names. We use this map to find the main alias
+ // name for which we have mapping in ProgramBBClusterInfo.
+ StringMap<StringRef> FuncAliasMap;
+
+ BasicBlockSections(const MemoryBuffer *Buf)
+ : MachineFunctionPass(ID), MBuf(Buf) {
+ initializeBasicBlockSectionsPass(*PassRegistry::getPassRegistry());
+ };
+
+ BasicBlockSections() : MachineFunctionPass(ID) {
+ initializeBasicBlockSectionsPass(*PassRegistry::getPassRegistry());
+ }
+
+ StringRef getPassName() const override {
+ return "Basic Block Sections Analysis";
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+ /// Read profiles of basic blocks if available here.
+ bool doInitialization(Module &M) override;
+
+ /// Identify basic blocks that need separate sections and prepare to emit them
+ /// accordingly.
+ bool runOnMachineFunction(MachineFunction &MF) override;
+};
+
+} // end anonymous namespace
+
+char BasicBlockSections::ID = 0;
+INITIALIZE_PASS(BasicBlockSections, "bbsections-prepare",
+ "Prepares for basic block sections, by splitting functions "
+ "into clusters of basic blocks.",
+ false, false)
+
+// This function updates and optimizes the branching instructions of every basic
+// block in a given function to account for changes in the layout.
+static void updateBranches(
+ MachineFunction &MF,
+ const SmallVector<MachineBasicBlock *, 4> &PreLayoutFallThroughs) {
+ const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
+ SmallVector<MachineOperand, 4> Cond;
+ for (auto &MBB : MF) {
+ auto NextMBBI = std::next(MBB.getIterator());
+ auto *FTMBB = PreLayoutFallThroughs[MBB.getNumber()];
+ // If this block had a fallthrough before we need an explicit unconditional
+ // branch to that block if either
+ // 1- the block ends a section, which means its next block may be
+ // reorderd by the linker, or
+ // 2- the fallthrough block is not adjacent to the block in the new
+ // order.
+ if (FTMBB && (MBB.isEndSection() || &*NextMBBI != FTMBB))
+ TII->insertUnconditionalBranch(MBB, FTMBB, MBB.findBranchDebugLoc());
+
+ // We do not optimize branches for machine basic blocks ending sections, as
+ // their adjacent block might be reordered by the linker.
+ if (MBB.isEndSection())
+ continue;
+
+ // It might be possible to optimize branches by flipping the branch
+ // condition.
+ Cond.clear();
+ MachineBasicBlock *TBB = nullptr, *FBB = nullptr; // For analyzeBranch.
+ if (TII->analyzeBranch(MBB, TBB, FBB, Cond))
+ continue;
+ MBB.updateTerminator(FTMBB);
+ }
+}
+
+// This function provides the BBCluster information associated with a function.
+// Returns true if a valid association exists and false otherwise.
+static bool getBBClusterInfoForFunction(
+ const MachineFunction &MF, const StringMap<StringRef> FuncAliasMap,
+ const ProgramBBClusterInfoMapTy &ProgramBBClusterInfo,
+ std::vector<Optional<BBClusterInfo>> &V) {
+ // Get the main alias name for the function.
+ auto FuncName = MF.getName();
+ auto R = FuncAliasMap.find(FuncName);
+ StringRef AliasName = R == FuncAliasMap.end() ? FuncName : R->second;
+
+ // Find the assoicated cluster information.
+ auto P = ProgramBBClusterInfo.find(AliasName);
+ if (P == ProgramBBClusterInfo.end())
+ return false;
+
+ if (P->second.empty()) {
+ // This indicates that sections are desired for all basic blocks of this
+ // function. We clear the BBClusterInfo vector to denote this.
+ V.clear();
+ return true;
+ }
+
+ V.resize(MF.getNumBlockIDs());
+ for (auto bbClusterInfo : P->second) {
+ // Bail out if the cluster information contains invalid MBB numbers.
+ if (bbClusterInfo.MBBNumber >= MF.getNumBlockIDs())
+ return false;
+ V[bbClusterInfo.MBBNumber] = bbClusterInfo;
+ }
+ return true;
+}
+
+// This function sorts basic blocks according to the cluster's information.
+// All explicitly specified clusters of basic blocks will be ordered
+// accordingly. All non-specified BBs go into a separate "Cold" section.
+// Additionally, if exception handling landing pads end up in more than one
+// clusters, they are moved into a single "Exception" section. Eventually,
+// clusters are ordered in increasing order of their IDs, with the "Exception"
+// and "Cold" succeeding all other clusters.
+// FuncBBClusterInfo represent the cluster information for basic blocks. If this
+// is empty, it means unique sections for all basic blocks in the function.
+static void
+assignSections(MachineFunction &MF,
+ const std::vector<Optional<BBClusterInfo>> &FuncBBClusterInfo) {
+ assert(MF.hasBBSections() && "BB Sections is not set for function.");
+ // This variable stores the section ID of the cluster containing eh_pads (if
+ // all eh_pads are one cluster). If more than one cluster contain eh_pads, we
+ // set it equal to ExceptionSectionID.
+ Optional<MBBSectionID> EHPadsSectionID;
+
+ for (auto &MBB : MF) {
+ // With the 'all' option, every basic block is placed in a unique section.
+ // With the 'list' option, every basic block is placed in a section
+ // associated with its cluster, unless we want individual unique sections
+ // for every basic block in this function (if FuncBBClusterInfo is empty).
+ if (MF.getTarget().getBBSectionsType() == llvm::BasicBlockSection::All ||
+ FuncBBClusterInfo.empty()) {
+ // If unique sections are desired for all basic blocks of the function, we
+ // set every basic block's section ID equal to its number (basic block
+ // id). This further ensures that basic blocks are ordered canonically.
+ MBB.setSectionID({static_cast<unsigned int>(MBB.getNumber())});
+ } else if (FuncBBClusterInfo[MBB.getNumber()].hasValue())
+ MBB.setSectionID(FuncBBClusterInfo[MBB.getNumber()]->ClusterID);
+ else {
+ // BB goes into the special cold section if it is not specified in the
+ // cluster info map.
+ MBB.setSectionID(MBBSectionID::ColdSectionID);
+ }
+
+ if (MBB.isEHPad() && EHPadsSectionID != MBB.getSectionID() &&
+ EHPadsSectionID != MBBSectionID::ExceptionSectionID) {
+ // If we already have one cluster containing eh_pads, this must be updated
+ // to ExceptionSectionID. Otherwise, we set it equal to the current
+ // section ID.
+ EHPadsSectionID = EHPadsSectionID.hasValue()
+ ? MBBSectionID::ExceptionSectionID
+ : MBB.getSectionID();
+ }
+ }
+
+ // If EHPads are in more than one section, this places all of them in the
+ // special exception section.
+ if (EHPadsSectionID == MBBSectionID::ExceptionSectionID)
+ for (auto &MBB : MF)
+ if (MBB.isEHPad())
+ MBB.setSectionID(EHPadsSectionID.getValue());
+}
+
+void llvm::sortBasicBlocksAndUpdateBranches(
+ MachineFunction &MF, MachineBasicBlockComparator MBBCmp) {
+ SmallVector<MachineBasicBlock *, 4> PreLayoutFallThroughs(
+ MF.getNumBlockIDs());
+ for (auto &MBB : MF)
+ PreLayoutFallThroughs[MBB.getNumber()] = MBB.getFallThrough();
+
+ MF.sort(MBBCmp);
+
+ // Set IsBeginSection and IsEndSection according to the assigned section IDs.
+ MF.assignBeginEndSections();
+
+ // After reordering basic blocks, we must update basic block branches to
+ // insert explicit fallthrough branches when required and optimize branches
+ // when possible.
+ updateBranches(MF, PreLayoutFallThroughs);
+}
+
+// If the exception section begins with a landing pad, that landing pad will
+// assume a zero offset (relative to @LPStart) in the LSDA. However, a value of
+// zero implies "no landing pad." This function inserts a NOP just before the EH
+// pad label to ensure a nonzero offset. Returns true if padding is not needed.
+static bool avoidZeroOffsetLandingPad(MachineFunction &MF) {
+ for (auto &MBB : MF) {
+ if (MBB.isBeginSection() && MBB.isEHPad()) {
+ MachineBasicBlock::iterator MI = MBB.begin();
+ while (!MI->isEHLabel())
+ ++MI;
+ MCInst Noop;
+ MF.getSubtarget().getInstrInfo()->getNoop(Noop);
+ BuildMI(MBB, MI, DebugLoc(),
+ MF.getSubtarget().getInstrInfo()->get(Noop.getOpcode()));
+ return false;
+ }
+ }
+ return true;
+}
+
+bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) {
+ auto BBSectionsType = MF.getTarget().getBBSectionsType();
+ assert(BBSectionsType != BasicBlockSection::None &&
+ "BB Sections not enabled!");
+ // Renumber blocks before sorting them for basic block sections. This is
+ // useful during sorting, basic blocks in the same section will retain the
+ // default order. This renumbering should also be done for basic block
+ // labels to match the profiles with the correct blocks.
+ MF.RenumberBlocks();
+
+ if (BBSectionsType == BasicBlockSection::Labels) {
+ MF.setBBSectionsType(BBSectionsType);
+ return true;
+ }
+
+ std::vector<Optional<BBClusterInfo>> FuncBBClusterInfo;
+ if (BBSectionsType == BasicBlockSection::List &&
+ !getBBClusterInfoForFunction(MF, FuncAliasMap, ProgramBBClusterInfo,
+ FuncBBClusterInfo))
+ return true;
+ MF.setBBSectionsType(BBSectionsType);
+ assignSections(MF, FuncBBClusterInfo);
+
+ // We make sure that the cluster including the entry basic block precedes all
+ // other clusters.
+ auto EntryBBSectionID = MF.front().getSectionID();
+
+ // Helper function for ordering BB sections as follows:
+ // * Entry section (section including the entry block).
+ // * Regular sections (in increasing order of their Number).
+ // ...
+ // * Exception section
+ // * Cold section
+ auto MBBSectionOrder = [EntryBBSectionID](const MBBSectionID &LHS,
+ const MBBSectionID &RHS) {
+ // We make sure that the section containing the entry block precedes all the
+ // other sections.
+ if (LHS == EntryBBSectionID || RHS == EntryBBSectionID)
+ return LHS == EntryBBSectionID;
+ return LHS.Type == RHS.Type ? LHS.Number < RHS.Number : LHS.Type < RHS.Type;
+ };
+
+ // We sort all basic blocks to make sure the basic blocks of every cluster are
+ // contiguous and ordered accordingly. Furthermore, clusters are ordered in
+ // increasing order of their section IDs, with the exception and the
+ // cold section placed at the end of the function.
+ auto Comparator = [&](const MachineBasicBlock &X,
+ const MachineBasicBlock &Y) {
+ auto XSectionID = X.getSectionID();
+ auto YSectionID = Y.getSectionID();
+ if (XSectionID != YSectionID)
+ return MBBSectionOrder(XSectionID, YSectionID);
+ // If the two basic block are in the same section, the order is decided by
+ // their position within the section.
+ if (XSectionID.Type == MBBSectionID::SectionType::Default)
+ return FuncBBClusterInfo[X.getNumber()]->PositionInCluster <
+ FuncBBClusterInfo[Y.getNumber()]->PositionInCluster;
+ return X.getNumber() < Y.getNumber();
+ };
+
+ sortBasicBlocksAndUpdateBranches(MF, Comparator);
+ avoidZeroOffsetLandingPad(MF);
+ return true;
+}
+
+// Basic Block Sections can be enabled for a subset of machine basic blocks.
+// This is done by passing a file containing names of functions for which basic
+// block sections are desired. Additionally, machine basic block ids of the
+// functions can also be specified for a finer granularity. Moreover, a cluster
+// of basic blocks could be assigned to the same section.
+// A file with basic block sections for all of function main and three blocks
+// for function foo (of which 1 and 2 are placed in a cluster) looks like this:
+// ----------------------------
+// list.txt:
+// !main
+// !foo
+// !!1 2
+// !!4
+static Error getBBClusterInfo(const MemoryBuffer *MBuf,
+ ProgramBBClusterInfoMapTy &ProgramBBClusterInfo,
+ StringMap<StringRef> &FuncAliasMap) {
+ assert(MBuf);
+ line_iterator LineIt(*MBuf, /*SkipBlanks=*/true, /*CommentMarker=*/'#');
+
+ auto invalidProfileError = [&](auto Message) {
+ return make_error<StringError>(
+ Twine("Invalid profile " + MBuf->getBufferIdentifier() + " at line " +
+ Twine(LineIt.line_number()) + ": " + Message),
+ inconvertibleErrorCode());
+ };
+
+ auto FI = ProgramBBClusterInfo.end();
+
+ // Current cluster ID corresponding to this function.
+ unsigned CurrentCluster = 0;
+ // Current position in the current cluster.
+ unsigned CurrentPosition = 0;
+
+ // Temporary set to ensure every basic block ID appears once in the clusters
+ // of a function.
+ SmallSet<unsigned, 4> FuncBBIDs;
+
+ for (; !LineIt.is_at_eof(); ++LineIt) {
+ StringRef S(*LineIt);
+ if (S[0] == '@')
+ continue;
+ // Check for the leading "!"
+ if (!S.consume_front("!") || S.empty())
+ break;
+ // Check for second "!" which indicates a cluster of basic blocks.
+ if (S.consume_front("!")) {
+ if (FI == ProgramBBClusterInfo.end())
+ return invalidProfileError(
+ "Cluster list does not follow a function name specifier.");
+ SmallVector<StringRef, 4> BBIndexes;
+ S.split(BBIndexes, ' ');
+ // Reset current cluster position.
+ CurrentPosition = 0;
+ for (auto BBIndexStr : BBIndexes) {
+ unsigned long long BBIndex;
+ if (getAsUnsignedInteger(BBIndexStr, 10, BBIndex))
+ return invalidProfileError(Twine("Unsigned integer expected: '") +
+ BBIndexStr + "'.");
+ if (!FuncBBIDs.insert(BBIndex).second)
+ return invalidProfileError(Twine("Duplicate basic block id found '") +
+ BBIndexStr + "'.");
+ if (!BBIndex && CurrentPosition)
+ return invalidProfileError("Entry BB (0) does not begin a cluster.");
+
+ FI->second.emplace_back(BBClusterInfo{
+ ((unsigned)BBIndex), CurrentCluster, CurrentPosition++});
+ }
+ CurrentCluster++;
+ } else { // This is a function name specifier.
+ // Function aliases are separated using '/'. We use the first function
+ // name for the cluster info mapping and delegate all other aliases to
+ // this one.
+ SmallVector<StringRef, 4> Aliases;
+ S.split(Aliases, '/');
+ for (size_t i = 1; i < Aliases.size(); ++i)
+ FuncAliasMap.try_emplace(Aliases[i], Aliases.front());
+
+ // Prepare for parsing clusters of this function name.
+ // Start a new cluster map for this function name.
+ FI = ProgramBBClusterInfo.try_emplace(Aliases.front()).first;
+ CurrentCluster = 0;
+ FuncBBIDs.clear();
+ }
+ }
+ return Error::success();
+}
+
+bool BasicBlockSections::doInitialization(Module &M) {
+ if (!MBuf)
+ return false;
+ if (auto Err = getBBClusterInfo(MBuf, ProgramBBClusterInfo, FuncAliasMap))
+ report_fatal_error(std::move(Err));
+ return false;
+}
+
+void BasicBlockSections::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ MachineFunctionPass::getAnalysisUsage(AU);
+}
+
+MachineFunctionPass *
+llvm::createBasicBlockSectionsPass(const MemoryBuffer *Buf) {
+ return new BasicBlockSections(Buf);
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/BranchFolding.cpp b/contrib/libs/llvm12/lib/CodeGen/BranchFolding.cpp
index 7a3fadae37..fd3f465fb3 100644
--- a/contrib/libs/llvm12/lib/CodeGen/BranchFolding.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/BranchFolding.cpp
@@ -134,18 +134,18 @@ bool BranchFolderPass::runOnMachineFunction(MachineFunction &MF) {
MF.getSubtarget().getRegisterInfo());
}
-BranchFolder::BranchFolder(bool DefaultEnableTailMerge, bool CommonHoist,
+BranchFolder::BranchFolder(bool DefaultEnableTailMerge, bool CommonHoist,
MBFIWrapper &FreqInfo,
const MachineBranchProbabilityInfo &ProbInfo,
- ProfileSummaryInfo *PSI, unsigned MinTailLength)
+ ProfileSummaryInfo *PSI, unsigned MinTailLength)
: EnableHoistCommonCode(CommonHoist), MinCommonTailLength(MinTailLength),
MBBFreqInfo(FreqInfo), MBPI(ProbInfo), PSI(PSI) {
if (MinCommonTailLength == 0)
MinCommonTailLength = TailMergeSize;
switch (FlagEnableTailMerge) {
- case cl::BOU_UNSET:
- EnableTailMerge = DefaultEnableTailMerge;
- break;
+ case cl::BOU_UNSET:
+ EnableTailMerge = DefaultEnableTailMerge;
+ break;
case cl::BOU_TRUE: EnableTailMerge = true; break;
case cl::BOU_FALSE: EnableTailMerge = false; break;
}
@@ -1403,7 +1403,7 @@ ReoptimizeBlock:
LLVM_DEBUG(dbgs() << "\nMerging into block: " << PrevBB
<< "From MBB: " << *MBB);
// Remove redundant DBG_VALUEs first.
- if (!PrevBB.empty()) {
+ if (!PrevBB.empty()) {
MachineBasicBlock::iterator PrevBBIter = PrevBB.end();
--PrevBBIter;
MachineBasicBlock::iterator MBBIter = MBB->begin();
diff --git a/contrib/libs/llvm12/lib/CodeGen/BranchFolding.h b/contrib/libs/llvm12/lib/CodeGen/BranchFolding.h
index 0e026da3b8..2a4ea92a92 100644
--- a/contrib/libs/llvm12/lib/CodeGen/BranchFolding.h
+++ b/contrib/libs/llvm12/lib/CodeGen/BranchFolding.h
@@ -32,7 +32,7 @@ class TargetRegisterInfo;
class LLVM_LIBRARY_VISIBILITY BranchFolder {
public:
- explicit BranchFolder(bool DefaultEnableTailMerge, bool CommonHoist,
+ explicit BranchFolder(bool DefaultEnableTailMerge, bool CommonHoist,
MBFIWrapper &FreqInfo,
const MachineBranchProbabilityInfo &ProbInfo,
ProfileSummaryInfo *PSI,
diff --git a/contrib/libs/llvm12/lib/CodeGen/BranchRelaxation.cpp b/contrib/libs/llvm12/lib/CodeGen/BranchRelaxation.cpp
index 80a70c2176..366c303614 100644
--- a/contrib/libs/llvm12/lib/CodeGen/BranchRelaxation.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/BranchRelaxation.cpp
@@ -507,31 +507,31 @@ bool BranchRelaxation::relaxBranchInstructions() {
Next = std::next(J);
MachineInstr &MI = *J;
- if (!MI.isConditionalBranch())
- continue;
-
- if (MI.getOpcode() == TargetOpcode::FAULTING_OP)
- // FAULTING_OP's destination is not encoded in the instruction stream
- // and thus never needs relaxed.
- continue;
-
- MachineBasicBlock *DestBB = TII->getBranchDestBlock(MI);
- if (!isBlockInRange(MI, *DestBB)) {
- if (Next != MBB.end() && Next->isConditionalBranch()) {
- // If there are multiple conditional branches, this isn't an
- // analyzable block. Split later terminators into a new block so
- // each one will be analyzable.
-
- splitBlockBeforeInstr(*Next, DestBB);
- } else {
- fixupConditionalBranch(MI);
- ++NumConditionalRelaxed;
+ if (!MI.isConditionalBranch())
+ continue;
+
+ if (MI.getOpcode() == TargetOpcode::FAULTING_OP)
+ // FAULTING_OP's destination is not encoded in the instruction stream
+ // and thus never needs relaxed.
+ continue;
+
+ MachineBasicBlock *DestBB = TII->getBranchDestBlock(MI);
+ if (!isBlockInRange(MI, *DestBB)) {
+ if (Next != MBB.end() && Next->isConditionalBranch()) {
+ // If there are multiple conditional branches, this isn't an
+ // analyzable block. Split later terminators into a new block so
+ // each one will be analyzable.
+
+ splitBlockBeforeInstr(*Next, DestBB);
+ } else {
+ fixupConditionalBranch(MI);
+ ++NumConditionalRelaxed;
}
-
- Changed = true;
-
- // This may have modified all of the terminators, so start over.
- Next = MBB.getFirstTerminator();
+
+ Changed = true;
+
+ // This may have modified all of the terminators, so start over.
+ Next = MBB.getFirstTerminator();
}
}
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/BreakFalseDeps.cpp b/contrib/libs/llvm12/lib/CodeGen/BreakFalseDeps.cpp
index 7454888e40..b11db3e657 100644
--- a/contrib/libs/llvm12/lib/CodeGen/BreakFalseDeps.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/BreakFalseDeps.cpp
@@ -118,7 +118,7 @@ bool BreakFalseDeps::pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx,
if (!MO.isRenamable())
return false;
- MCRegister OriginalReg = MO.getReg().asMCReg();
+ MCRegister OriginalReg = MO.getReg().asMCReg();
// Update only undef operands that have reg units that are mapped to one root.
for (MCRegUnitIterator Unit(OriginalReg, TRI); Unit.isValid(); ++Unit) {
@@ -171,8 +171,8 @@ bool BreakFalseDeps::pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx,
bool BreakFalseDeps::shouldBreakDependence(MachineInstr *MI, unsigned OpIdx,
unsigned Pref) {
- MCRegister Reg = MI->getOperand(OpIdx).getReg().asMCReg();
- unsigned Clearance = RDA->getClearance(MI, Reg);
+ MCRegister Reg = MI->getOperand(OpIdx).getReg().asMCReg();
+ unsigned Clearance = RDA->getClearance(MI, Reg);
LLVM_DEBUG(dbgs() << "Clearance: " << Clearance << ", want " << Pref);
if (Pref > Clearance) {
@@ -186,24 +186,24 @@ bool BreakFalseDeps::shouldBreakDependence(MachineInstr *MI, unsigned OpIdx,
void BreakFalseDeps::processDefs(MachineInstr *MI) {
assert(!MI->isDebugInstr() && "Won't process debug values");
- const MCInstrDesc &MCID = MI->getDesc();
-
+ const MCInstrDesc &MCID = MI->getDesc();
+
// Break dependence on undef uses. Do this before updating LiveRegs below.
// This can remove a false dependence with no additional instructions.
- for (unsigned i = MCID.getNumDefs(), e = MCID.getNumOperands(); i != e; ++i) {
- MachineOperand &MO = MI->getOperand(i);
- if (!MO.isReg() || !MO.getReg() || !MO.isUse() || !MO.isUndef())
- continue;
-
- unsigned Pref = TII->getUndefRegClearance(*MI, i, TRI);
- if (Pref) {
- bool HadTrueDependency = pickBestRegisterForUndef(MI, i, Pref);
- // We don't need to bother trying to break a dependency if this
- // instruction has a true dependency on that register through another
- // operand - we'll have to wait for it to be available regardless.
- if (!HadTrueDependency && shouldBreakDependence(MI, i, Pref))
- UndefReads.push_back(std::make_pair(MI, i));
- }
+ for (unsigned i = MCID.getNumDefs(), e = MCID.getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (!MO.isReg() || !MO.getReg() || !MO.isUse() || !MO.isUndef())
+ continue;
+
+ unsigned Pref = TII->getUndefRegClearance(*MI, i, TRI);
+ if (Pref) {
+ bool HadTrueDependency = pickBestRegisterForUndef(MI, i, Pref);
+ // We don't need to bother trying to break a dependency if this
+ // instruction has a true dependency on that register through another
+ // operand - we'll have to wait for it to be available regardless.
+ if (!HadTrueDependency && shouldBreakDependence(MI, i, Pref))
+ UndefReads.push_back(std::make_pair(MI, i));
+ }
}
// The code below allows the target to create a new instruction to break the
diff --git a/contrib/libs/llvm12/lib/CodeGen/CalcSpillWeights.cpp b/contrib/libs/llvm12/lib/CodeGen/CalcSpillWeights.cpp
index 95f94cea85..16f380c1eb 100644
--- a/contrib/libs/llvm12/lib/CodeGen/CalcSpillWeights.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/CalcSpillWeights.cpp
@@ -28,59 +28,59 @@ using namespace llvm;
#define DEBUG_TYPE "calcspillweights"
-void VirtRegAuxInfo::calculateSpillWeightsAndHints() {
+void VirtRegAuxInfo::calculateSpillWeightsAndHints() {
LLVM_DEBUG(dbgs() << "********** Compute Spill Weights **********\n"
<< "********** Function: " << MF.getName() << '\n');
MachineRegisterInfo &MRI = MF.getRegInfo();
- for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
- unsigned Reg = Register::index2VirtReg(I);
+ for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
+ unsigned Reg = Register::index2VirtReg(I);
if (MRI.reg_nodbg_empty(Reg))
continue;
- calculateSpillWeightAndHint(LIS.getInterval(Reg));
+ calculateSpillWeightAndHint(LIS.getInterval(Reg));
}
}
// Return the preferred allocation register for reg, given a COPY instruction.
-static Register copyHint(const MachineInstr *MI, unsigned Reg,
- const TargetRegisterInfo &TRI,
- const MachineRegisterInfo &MRI) {
- unsigned Sub, HSub;
- Register HReg;
- if (MI->getOperand(0).getReg() == Reg) {
- Sub = MI->getOperand(0).getSubReg();
- HReg = MI->getOperand(1).getReg();
- HSub = MI->getOperand(1).getSubReg();
+static Register copyHint(const MachineInstr *MI, unsigned Reg,
+ const TargetRegisterInfo &TRI,
+ const MachineRegisterInfo &MRI) {
+ unsigned Sub, HSub;
+ Register HReg;
+ if (MI->getOperand(0).getReg() == Reg) {
+ Sub = MI->getOperand(0).getSubReg();
+ HReg = MI->getOperand(1).getReg();
+ HSub = MI->getOperand(1).getSubReg();
} else {
- Sub = MI->getOperand(1).getSubReg();
- HReg = MI->getOperand(0).getReg();
- HSub = MI->getOperand(0).getSubReg();
+ Sub = MI->getOperand(1).getSubReg();
+ HReg = MI->getOperand(0).getReg();
+ HSub = MI->getOperand(0).getSubReg();
}
- if (!HReg)
+ if (!HReg)
return 0;
- if (Register::isVirtualRegister(HReg))
- return Sub == HSub ? HReg : Register();
+ if (Register::isVirtualRegister(HReg))
+ return Sub == HSub ? HReg : Register();
- const TargetRegisterClass *rc = MRI.getRegClass(Reg);
- MCRegister CopiedPReg = HSub ? TRI.getSubReg(HReg, HSub) : HReg.asMCReg();
+ const TargetRegisterClass *rc = MRI.getRegClass(Reg);
+ MCRegister CopiedPReg = HSub ? TRI.getSubReg(HReg, HSub) : HReg.asMCReg();
if (rc->contains(CopiedPReg))
return CopiedPReg;
// Check if reg:sub matches so that a super register could be hinted.
- if (Sub)
- return TRI.getMatchingSuperReg(CopiedPReg, Sub, rc);
+ if (Sub)
+ return TRI.getMatchingSuperReg(CopiedPReg, Sub, rc);
return 0;
}
// Check if all values in LI are rematerializable
-static bool isRematerializable(const LiveInterval &LI, const LiveIntervals &LIS,
- const VirtRegMap &VRM,
+static bool isRematerializable(const LiveInterval &LI, const LiveIntervals &LIS,
+ const VirtRegMap &VRM,
const TargetInstrInfo &TII) {
- unsigned Reg = LI.reg();
- unsigned Original = VRM.getOriginal(Reg);
+ unsigned Reg = LI.reg();
+ unsigned Original = VRM.getOriginal(Reg);
for (LiveInterval::const_vni_iterator I = LI.vni_begin(), E = LI.vni_end();
I != E; ++I) {
const VNInfo *VNI = *I;
@@ -95,28 +95,28 @@ static bool isRematerializable(const LiveInterval &LI, const LiveIntervals &LIS,
// Trace copies introduced by live range splitting. The inline
// spiller can rematerialize through these copies, so the spill
// weight must reflect this.
- while (MI->isFullCopy()) {
- // The copy destination must match the interval register.
- if (MI->getOperand(0).getReg() != Reg)
- return false;
-
- // Get the source register.
- Reg = MI->getOperand(1).getReg();
-
- // If the original (pre-splitting) registers match this
- // copy came from a split.
- if (!Register::isVirtualRegister(Reg) || VRM.getOriginal(Reg) != Original)
- return false;
-
- // Follow the copy live-in value.
- const LiveInterval &SrcLI = LIS.getInterval(Reg);
- LiveQueryResult SrcQ = SrcLI.Query(VNI->def);
- VNI = SrcQ.valueIn();
- assert(VNI && "Copy from non-existing value");
- if (VNI->isPHIDef())
- return false;
- MI = LIS.getInstructionFromIndex(VNI->def);
- assert(MI && "Dead valno in interval");
+ while (MI->isFullCopy()) {
+ // The copy destination must match the interval register.
+ if (MI->getOperand(0).getReg() != Reg)
+ return false;
+
+ // Get the source register.
+ Reg = MI->getOperand(1).getReg();
+
+ // If the original (pre-splitting) registers match this
+ // copy came from a split.
+ if (!Register::isVirtualRegister(Reg) || VRM.getOriginal(Reg) != Original)
+ return false;
+
+ // Follow the copy live-in value.
+ const LiveInterval &SrcLI = LIS.getInterval(Reg);
+ LiveQueryResult SrcQ = SrcLI.Query(VNI->def);
+ VNI = SrcQ.valueIn();
+ assert(VNI && "Copy from non-existing value");
+ if (VNI->isPHIDef())
+ return false;
+ MI = LIS.getInstructionFromIndex(VNI->def);
+ assert(MI && "Dead valno in interval");
}
if (!TII.isTriviallyReMaterializable(*MI, LIS.getAliasAnalysis()))
@@ -125,55 +125,55 @@ static bool isRematerializable(const LiveInterval &LI, const LiveIntervals &LIS,
return true;
}
-void VirtRegAuxInfo::calculateSpillWeightAndHint(LiveInterval &LI) {
- float Weight = weightCalcHelper(LI);
+void VirtRegAuxInfo::calculateSpillWeightAndHint(LiveInterval &LI) {
+ float Weight = weightCalcHelper(LI);
// Check if unspillable.
- if (Weight < 0)
+ if (Weight < 0)
return;
- LI.setWeight(Weight);
+ LI.setWeight(Weight);
}
-float VirtRegAuxInfo::futureWeight(LiveInterval &LI, SlotIndex Start,
- SlotIndex End) {
- return weightCalcHelper(LI, &Start, &End);
+float VirtRegAuxInfo::futureWeight(LiveInterval &LI, SlotIndex Start,
+ SlotIndex End) {
+ return weightCalcHelper(LI, &Start, &End);
}
-float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
- SlotIndex *End) {
- MachineRegisterInfo &MRI = MF.getRegInfo();
- const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
- const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
- MachineBasicBlock *MBB = nullptr;
- MachineLoop *Loop = nullptr;
- bool IsExiting = false;
- float TotalWeight = 0;
- unsigned NumInstr = 0; // Number of instructions using LI
- SmallPtrSet<MachineInstr *, 8> Visited;
-
- std::pair<Register, Register> TargetHint = MRI.getRegAllocationHint(LI.reg());
-
- if (LI.isSpillable()) {
- Register Reg = LI.reg();
- Register Original = VRM.getOriginal(Reg);
- const LiveInterval &OrigInt = LIS.getInterval(Original);
- // li comes from a split of OrigInt. If OrigInt was marked
- // as not spillable, make sure the new interval is marked
- // as not spillable as well.
- if (!OrigInt.isSpillable())
- LI.markNotSpillable();
- }
-
+float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
+ SlotIndex *End) {
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
+ const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
+ MachineBasicBlock *MBB = nullptr;
+ MachineLoop *Loop = nullptr;
+ bool IsExiting = false;
+ float TotalWeight = 0;
+ unsigned NumInstr = 0; // Number of instructions using LI
+ SmallPtrSet<MachineInstr *, 8> Visited;
+
+ std::pair<Register, Register> TargetHint = MRI.getRegAllocationHint(LI.reg());
+
+ if (LI.isSpillable()) {
+ Register Reg = LI.reg();
+ Register Original = VRM.getOriginal(Reg);
+ const LiveInterval &OrigInt = LIS.getInterval(Original);
+ // li comes from a split of OrigInt. If OrigInt was marked
+ // as not spillable, make sure the new interval is marked
+ // as not spillable as well.
+ if (!OrigInt.isSpillable())
+ LI.markNotSpillable();
+ }
+
// Don't recompute spill weight for an unspillable register.
- bool IsSpillable = LI.isSpillable();
+ bool IsSpillable = LI.isSpillable();
- bool IsLocalSplitArtifact = Start && End;
+ bool IsLocalSplitArtifact = Start && End;
// Do not update future local split artifacts.
- bool ShouldUpdateLI = !IsLocalSplitArtifact;
+ bool ShouldUpdateLI = !IsLocalSplitArtifact;
- if (IsLocalSplitArtifact) {
- MachineBasicBlock *localMBB = LIS.getMBBFromIndex(*End);
- assert(localMBB == LIS.getMBBFromIndex(*Start) &&
+ if (IsLocalSplitArtifact) {
+ MachineBasicBlock *localMBB = LIS.getMBBFromIndex(*End);
+ assert(localMBB == LIS.getMBBFromIndex(*Start) &&
"start and end are expected to be in the same basic block");
// Local split artifact will have 2 additional copy instructions and they
@@ -181,119 +181,119 @@ float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
// localLI = COPY other
// ...
// other = COPY localLI
- TotalWeight += LiveIntervals::getSpillWeight(true, false, &MBFI, localMBB);
- TotalWeight += LiveIntervals::getSpillWeight(false, true, &MBFI, localMBB);
+ TotalWeight += LiveIntervals::getSpillWeight(true, false, &MBFI, localMBB);
+ TotalWeight += LiveIntervals::getSpillWeight(false, true, &MBFI, localMBB);
- NumInstr += 2;
+ NumInstr += 2;
}
// CopyHint is a sortable hint derived from a COPY instruction.
struct CopyHint {
- const Register Reg;
- const float Weight;
- CopyHint(Register R, float W) : Reg(R), Weight(W) {}
- bool operator<(const CopyHint &Rhs) const {
+ const Register Reg;
+ const float Weight;
+ CopyHint(Register R, float W) : Reg(R), Weight(W) {}
+ bool operator<(const CopyHint &Rhs) const {
// Always prefer any physreg hint.
- if (Reg.isPhysical() != Rhs.Reg.isPhysical())
- return Reg.isPhysical();
- if (Weight != Rhs.Weight)
- return (Weight > Rhs.Weight);
- return Reg.id() < Rhs.Reg.id(); // Tie-breaker.
+ if (Reg.isPhysical() != Rhs.Reg.isPhysical())
+ return Reg.isPhysical();
+ if (Weight != Rhs.Weight)
+ return (Weight > Rhs.Weight);
+ return Reg.id() < Rhs.Reg.id(); // Tie-breaker.
}
};
-
+
std::set<CopyHint> CopyHints;
- DenseMap<unsigned, float> Hint;
+ DenseMap<unsigned, float> Hint;
for (MachineRegisterInfo::reg_instr_nodbg_iterator
- I = MRI.reg_instr_nodbg_begin(LI.reg()),
- E = MRI.reg_instr_nodbg_end();
+ I = MRI.reg_instr_nodbg_begin(LI.reg()),
+ E = MRI.reg_instr_nodbg_end();
I != E;) {
- MachineInstr *MI = &*(I++);
+ MachineInstr *MI = &*(I++);
// For local split artifacts, we are interested only in instructions between
// the expected start and end of the range.
- SlotIndex SI = LIS.getInstructionIndex(*MI);
- if (IsLocalSplitArtifact && ((SI < *Start) || (SI > *End)))
+ SlotIndex SI = LIS.getInstructionIndex(*MI);
+ if (IsLocalSplitArtifact && ((SI < *Start) || (SI > *End)))
continue;
- NumInstr++;
- if (MI->isIdentityCopy() || MI->isImplicitDef())
+ NumInstr++;
+ if (MI->isIdentityCopy() || MI->isImplicitDef())
continue;
- if (!Visited.insert(MI).second)
+ if (!Visited.insert(MI).second)
continue;
- // For terminators that produce values, ask the backend if the register is
- // not spillable.
- if (TII.isUnspillableTerminator(MI) && MI->definesRegister(LI.reg())) {
- LI.markNotSpillable();
- return -1.0f;
- }
-
- float Weight = 1.0f;
- if (IsSpillable) {
+ // For terminators that produce values, ask the backend if the register is
+ // not spillable.
+ if (TII.isUnspillableTerminator(MI) && MI->definesRegister(LI.reg())) {
+ LI.markNotSpillable();
+ return -1.0f;
+ }
+
+ float Weight = 1.0f;
+ if (IsSpillable) {
// Get loop info for mi.
- if (MI->getParent() != MBB) {
- MBB = MI->getParent();
- Loop = Loops.getLoopFor(MBB);
- IsExiting = Loop ? Loop->isLoopExiting(MBB) : false;
+ if (MI->getParent() != MBB) {
+ MBB = MI->getParent();
+ Loop = Loops.getLoopFor(MBB);
+ IsExiting = Loop ? Loop->isLoopExiting(MBB) : false;
}
// Calculate instr weight.
- bool Reads, Writes;
- std::tie(Reads, Writes) = MI->readsWritesVirtualRegister(LI.reg());
- Weight = LiveIntervals::getSpillWeight(Writes, Reads, &MBFI, *MI);
+ bool Reads, Writes;
+ std::tie(Reads, Writes) = MI->readsWritesVirtualRegister(LI.reg());
+ Weight = LiveIntervals::getSpillWeight(Writes, Reads, &MBFI, *MI);
// Give extra weight to what looks like a loop induction variable update.
- if (Writes && IsExiting && LIS.isLiveOutOfMBB(LI, MBB))
- Weight *= 3;
+ if (Writes && IsExiting && LIS.isLiveOutOfMBB(LI, MBB))
+ Weight *= 3;
- TotalWeight += Weight;
+ TotalWeight += Weight;
}
// Get allocation hints from copies.
- if (!MI->isCopy())
+ if (!MI->isCopy())
continue;
- Register HintReg = copyHint(MI, LI.reg(), TRI, MRI);
- if (!HintReg)
+ Register HintReg = copyHint(MI, LI.reg(), TRI, MRI);
+ if (!HintReg)
continue;
// Force hweight onto the stack so that x86 doesn't add hidden precision,
// making the comparison incorrectly pass (i.e., 1 > 1 == true??).
//
// FIXME: we probably shouldn't use floats at all.
- volatile float HWeight = Hint[HintReg] += Weight;
- if (HintReg.isVirtual() || MRI.isAllocatable(HintReg))
- CopyHints.insert(CopyHint(HintReg, HWeight));
+ volatile float HWeight = Hint[HintReg] += Weight;
+ if (HintReg.isVirtual() || MRI.isAllocatable(HintReg))
+ CopyHints.insert(CopyHint(HintReg, HWeight));
}
// Pass all the sorted copy hints to mri.
- if (ShouldUpdateLI && CopyHints.size()) {
+ if (ShouldUpdateLI && CopyHints.size()) {
// Remove a generic hint if previously added by target.
if (TargetHint.first == 0 && TargetHint.second)
- MRI.clearSimpleHint(LI.reg());
+ MRI.clearSimpleHint(LI.reg());
- std::set<Register> HintedRegs;
+ std::set<Register> HintedRegs;
for (auto &Hint : CopyHints) {
if (!HintedRegs.insert(Hint.Reg).second ||
(TargetHint.first != 0 && Hint.Reg == TargetHint.second))
// Don't add the same reg twice or the target-type hint again.
continue;
- MRI.addRegAllocationHint(LI.reg(), Hint.Reg);
+ MRI.addRegAllocationHint(LI.reg(), Hint.Reg);
}
// Weakly boost the spill weight of hinted registers.
- TotalWeight *= 1.01F;
+ TotalWeight *= 1.01F;
}
// If the live interval was already unspillable, leave it that way.
- if (!IsSpillable)
+ if (!IsSpillable)
return -1.0;
// Mark li as unspillable if all live ranges are tiny and the interval
// is not live at any reg mask. If the interval is live at a reg mask
// spilling may be required.
- if (ShouldUpdateLI && LI.isZeroLength(LIS.getSlotIndexes()) &&
- !LI.isLiveAtIndexes(LIS.getRegMaskSlots())) {
- LI.markNotSpillable();
+ if (ShouldUpdateLI && LI.isZeroLength(LIS.getSlotIndexes()) &&
+ !LI.isLiveAtIndexes(LIS.getRegMaskSlots())) {
+ LI.markNotSpillable();
return -1.0;
}
@@ -301,10 +301,10 @@ float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
// it is a preferred candidate for spilling.
// FIXME: this gets much more complicated once we support non-trivial
// re-materialization.
- if (isRematerializable(LI, LIS, VRM, *MF.getSubtarget().getInstrInfo()))
- TotalWeight *= 0.5F;
+ if (isRematerializable(LI, LIS, VRM, *MF.getSubtarget().getInstrInfo()))
+ TotalWeight *= 0.5F;
- if (IsLocalSplitArtifact)
- return normalize(TotalWeight, Start->distance(*End), NumInstr);
- return normalize(TotalWeight, LI.getSize(), NumInstr);
+ if (IsLocalSplitArtifact)
+ return normalize(TotalWeight, Start->distance(*End), NumInstr);
+ return normalize(TotalWeight, LI.getSize(), NumInstr);
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/CallingConvLower.cpp b/contrib/libs/llvm12/lib/CodeGen/CallingConvLower.cpp
index a7ca19f840..c9246f6e87 100644
--- a/contrib/libs/llvm12/lib/CodeGen/CallingConvLower.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/CallingConvLower.cpp
@@ -13,7 +13,7 @@
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
@@ -63,11 +63,11 @@ void CCState::MarkAllocated(MCPhysReg Reg) {
UsedRegs[*AI / 32] |= 1 << (*AI & 31);
}
-void CCState::MarkUnallocated(MCPhysReg Reg) {
- for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI)
- UsedRegs[*AI / 32] &= ~(1 << (*AI & 31));
-}
-
+void CCState::MarkUnallocated(MCPhysReg Reg) {
+ for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI)
+ UsedRegs[*AI / 32] &= ~(1 << (*AI & 31));
+}
+
bool CCState::IsShadowAllocatedReg(MCRegister Reg) const {
if (!isAllocated(Reg))
return false;
@@ -190,17 +190,17 @@ void CCState::AnalyzeCallResult(MVT VT, CCAssignFn Fn) {
}
}
-void CCState::ensureMaxAlignment(Align Alignment) {
- if (!AnalyzingMustTailForwardedRegs)
- MF.getFrameInfo().ensureMaxAlignment(Alignment);
-}
-
+void CCState::ensureMaxAlignment(Align Alignment) {
+ if (!AnalyzingMustTailForwardedRegs)
+ MF.getFrameInfo().ensureMaxAlignment(Alignment);
+}
+
static bool isValueTypeInRegForCC(CallingConv::ID CC, MVT VT) {
if (VT.isVector())
return true; // Assume -msse-regparm might be in effect.
if (!VT.isInteger())
return false;
- return (CC == CallingConv::X86_VectorCall || CC == CallingConv::X86_FastCall);
+ return (CC == CallingConv::X86_VectorCall || CC == CallingConv::X86_FastCall);
}
void CCState::getRemainingRegParmsForType(SmallVectorImpl<MCPhysReg> &Regs,
@@ -216,8 +216,8 @@ void CCState::getRemainingRegParmsForType(SmallVectorImpl<MCPhysReg> &Regs,
// Allocate something of this value type repeatedly until we get assigned a
// location in memory.
- bool HaveRegParm;
- do {
+ bool HaveRegParm;
+ do {
if (Fn(0, VT, VT, CCValAssign::Full, Flags, *this)) {
#ifndef NDEBUG
dbgs() << "Call has unhandled type " << EVT(VT).getEVTString()
@@ -226,7 +226,7 @@ void CCState::getRemainingRegParmsForType(SmallVectorImpl<MCPhysReg> &Regs,
llvm_unreachable(nullptr);
}
HaveRegParm = Locs.back().isRegLoc();
- } while (HaveRegParm);
+ } while (HaveRegParm);
// Copy all the registers from the value locations we added.
assert(NumLocs < Locs.size() && "CC assignment failed to add location");
@@ -257,7 +257,7 @@ void CCState::analyzeMustTailForwardedRegisters(
const TargetLowering *TL = MF.getSubtarget().getTargetLowering();
const TargetRegisterClass *RC = TL->getRegClassFor(RegVT);
for (MCPhysReg PReg : RemainingRegs) {
- Register VReg = MF.addLiveIn(PReg, RC);
+ Register VReg = MF.addLiveIn(PReg, RC);
Forwards.push_back(ForwardedRegister(VReg, PReg, RegVT));
}
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/CodeGen.cpp b/contrib/libs/llvm12/lib/CodeGen/CodeGen.cpp
index c9424b17e5..d2400d0371 100644
--- a/contrib/libs/llvm12/lib/CodeGen/CodeGen.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/CodeGen.cpp
@@ -20,17 +20,17 @@ using namespace llvm;
/// initializeCodeGen - Initialize all passes linked into the CodeGen library.
void llvm::initializeCodeGen(PassRegistry &Registry) {
initializeAtomicExpandPass(Registry);
- initializeBasicBlockSectionsPass(Registry);
+ initializeBasicBlockSectionsPass(Registry);
initializeBranchFolderPassPass(Registry);
initializeBranchRelaxationPass(Registry);
initializeCFGuardLongjmpPass(Registry);
initializeCFIInstrInserterPass(Registry);
- initializeCheckDebugMachineModulePass(Registry);
+ initializeCheckDebugMachineModulePass(Registry);
initializeCodeGenPreparePass(Registry);
initializeDeadMachineInstructionElimPass(Registry);
initializeDebugifyMachineModulePass(Registry);
initializeDetectDeadLanesPass(Registry);
- initializeDwarfEHPrepareLegacyPassPass(Registry);
+ initializeDwarfEHPrepareLegacyPassPass(Registry);
initializeEarlyIfConverterPass(Registry);
initializeEarlyIfPredicatorPass(Registry);
initializeEarlyMachineLICMPass(Registry);
diff --git a/contrib/libs/llvm12/lib/CodeGen/CodeGenPassBuilder.cpp b/contrib/libs/llvm12/lib/CodeGen/CodeGenPassBuilder.cpp
index bda0db093a..7f37f2069a 100644
--- a/contrib/libs/llvm12/lib/CodeGen/CodeGenPassBuilder.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/CodeGenPassBuilder.cpp
@@ -1,25 +1,25 @@
-//===--- CodeGenPassBuilder.cpp --------------------------------------- ---===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines interfaces to access the target independent code
-// generation passes provided by the LLVM backend.
-//
-//===---------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/CodeGenPassBuilder.h"
-
-using namespace llvm;
-
-namespace llvm {
-#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
- AnalysisKey PASS_NAME::Key;
-#include "llvm/CodeGen/MachinePassRegistry.def"
-#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
- AnalysisKey PASS_NAME::Key;
-#include "llvm/CodeGen/MachinePassRegistry.def"
-} // namespace llvm
+//===--- CodeGenPassBuilder.cpp --------------------------------------- ---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines interfaces to access the target independent code
+// generation passes provided by the LLVM backend.
+//
+//===---------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/CodeGenPassBuilder.h"
+
+using namespace llvm;
+
+namespace llvm {
+#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
+ AnalysisKey PASS_NAME::Key;
+#include "llvm/CodeGen/MachinePassRegistry.def"
+#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
+ AnalysisKey PASS_NAME::Key;
+#include "llvm/CodeGen/MachinePassRegistry.def"
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/CodeGen/CodeGenPrepare.cpp b/contrib/libs/llvm12/lib/CodeGen/CodeGenPrepare.cpp
index ac72238d21..b2bc75c197 100644
--- a/contrib/libs/llvm12/lib/CodeGen/CodeGenPrepare.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/CodeGenPrepare.cpp
@@ -376,7 +376,7 @@ class TypePromotionTransaction;
return *DT;
}
- void removeAllAssertingVHReferences(Value *V);
+ void removeAllAssertingVHReferences(Value *V);
bool eliminateFallThrough(Function &F);
bool eliminateMostlyEmptyBlocks(Function &F);
BasicBlock *findDestBlockOfMergeableEmptyBlock(BasicBlock *BB);
@@ -384,7 +384,7 @@ class TypePromotionTransaction;
void eliminateMostlyEmptyBlock(BasicBlock *BB);
bool isMergingEmptyBlockProfitable(BasicBlock *BB, BasicBlock *DestBB,
bool isPreheader);
- bool makeBitReverse(Instruction &I);
+ bool makeBitReverse(Instruction &I);
bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT);
bool optimizeInst(Instruction *I, bool &ModifiedDT);
bool optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
@@ -439,11 +439,11 @@ char CodeGenPrepare::ID = 0;
INITIALIZE_PASS_BEGIN(CodeGenPrepare, DEBUG_TYPE,
"Optimize for code generation", false, false)
-INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
-INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
+INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_END(CodeGenPrepare, DEBUG_TYPE,
"Optimize for code generation", false, false)
@@ -472,21 +472,21 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
OptSize = F.hasOptSize();
if (ProfileGuidedSectionPrefix) {
- // The hot attribute overwrites profile count based hotness while profile
- // counts based hotness overwrite the cold attribute.
- // This is a conservative behabvior.
- if (F.hasFnAttribute(Attribute::Hot) ||
- PSI->isFunctionHotInCallGraph(&F, *BFI))
- F.setSectionPrefix("hot");
- // If PSI shows this function is not hot, we will placed the function
- // into unlikely section if (1) PSI shows this is a cold function, or
- // (2) the function has a attribute of cold.
- else if (PSI->isFunctionColdInCallGraph(&F, *BFI) ||
- F.hasFnAttribute(Attribute::Cold))
- F.setSectionPrefix("unlikely");
+ // The hot attribute overwrites profile count based hotness while profile
+ // counts based hotness overwrite the cold attribute.
+ // This is a conservative behabvior.
+ if (F.hasFnAttribute(Attribute::Hot) ||
+ PSI->isFunctionHotInCallGraph(&F, *BFI))
+ F.setSectionPrefix("hot");
+ // If PSI shows this function is not hot, we will placed the function
+ // into unlikely section if (1) PSI shows this is a cold function, or
+ // (2) the function has a attribute of cold.
+ else if (PSI->isFunctionColdInCallGraph(&F, *BFI) ||
+ F.hasFnAttribute(Attribute::Cold))
+ F.setSectionPrefix("unlikely");
else if (ProfileUnknownInSpecialSection && PSI->hasPartialSampleProfile() &&
PSI->isFunctionHotnessUnknown(F))
- F.setSectionPrefix("unknown");
+ F.setSectionPrefix("unknown");
}
/// This optimization identifies DIV instructions that can be
@@ -552,7 +552,7 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
LargeOffsetGEPID.clear();
}
- NewGEPBases.clear();
+ NewGEPBases.clear();
SunkAddrs.clear();
if (!DisableBranchOpts) {
@@ -562,13 +562,13 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
// are removed.
SmallSetVector<BasicBlock*, 8> WorkList;
for (BasicBlock &BB : F) {
- SmallVector<BasicBlock *, 2> Successors(successors(&BB));
+ SmallVector<BasicBlock *, 2> Successors(successors(&BB));
MadeChange |= ConstantFoldTerminator(&BB, true);
if (!MadeChange) continue;
for (SmallVectorImpl<BasicBlock*>::iterator
II = Successors.begin(), IE = Successors.end(); II != IE; ++II)
- if (pred_empty(*II))
+ if (pred_empty(*II))
WorkList.insert(*II);
}
@@ -576,13 +576,13 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
MadeChange |= !WorkList.empty();
while (!WorkList.empty()) {
BasicBlock *BB = WorkList.pop_back_val();
- SmallVector<BasicBlock*, 2> Successors(successors(BB));
+ SmallVector<BasicBlock*, 2> Successors(successors(BB));
DeleteDeadBlock(BB);
for (SmallVectorImpl<BasicBlock*>::iterator
II = Successors.begin(), IE = Successors.end(); II != IE; ++II)
- if (pred_empty(*II))
+ if (pred_empty(*II))
WorkList.insert(*II);
}
@@ -616,33 +616,33 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
return EverMadeChange;
}
-/// An instruction is about to be deleted, so remove all references to it in our
-/// GEP-tracking data strcutures.
-void CodeGenPrepare::removeAllAssertingVHReferences(Value *V) {
- LargeOffsetGEPMap.erase(V);
- NewGEPBases.erase(V);
-
- auto GEP = dyn_cast<GetElementPtrInst>(V);
- if (!GEP)
- return;
-
- LargeOffsetGEPID.erase(GEP);
-
- auto VecI = LargeOffsetGEPMap.find(GEP->getPointerOperand());
- if (VecI == LargeOffsetGEPMap.end())
- return;
-
- auto &GEPVector = VecI->second;
- const auto &I =
- llvm::find_if(GEPVector, [=](auto &Elt) { return Elt.first == GEP; });
- if (I == GEPVector.end())
- return;
-
- GEPVector.erase(I);
- if (GEPVector.empty())
- LargeOffsetGEPMap.erase(VecI);
-}
-
+/// An instruction is about to be deleted, so remove all references to it in our
+/// GEP-tracking data strcutures.
+void CodeGenPrepare::removeAllAssertingVHReferences(Value *V) {
+ LargeOffsetGEPMap.erase(V);
+ NewGEPBases.erase(V);
+
+ auto GEP = dyn_cast<GetElementPtrInst>(V);
+ if (!GEP)
+ return;
+
+ LargeOffsetGEPID.erase(GEP);
+
+ auto VecI = LargeOffsetGEPMap.find(GEP->getPointerOperand());
+ if (VecI == LargeOffsetGEPMap.end())
+ return;
+
+ auto &GEPVector = VecI->second;
+ const auto &I =
+ llvm::find_if(GEPVector, [=](auto &Elt) { return Elt.first == GEP; });
+ if (I == GEPVector.end())
+ return;
+
+ GEPVector.erase(I);
+ if (GEPVector.empty())
+ LargeOffsetGEPMap.erase(VecI);
+}
+
// Verify BFI has been updated correctly by recomputing BFI and comparing them.
void LLVM_ATTRIBUTE_UNUSED CodeGenPrepare::verifyBFIUpdates(Function &F) {
DominatorTree NewDT(F);
@@ -661,10 +661,10 @@ bool CodeGenPrepare::eliminateFallThrough(Function &F) {
// Use a temporary array to avoid iterator being invalidated when
// deleting blocks.
SmallVector<WeakTrackingVH, 16> Blocks;
- for (auto &Block : llvm::drop_begin(F))
+ for (auto &Block : llvm::drop_begin(F))
Blocks.push_back(&Block);
- SmallSet<WeakTrackingVH, 16> Preds;
+ SmallSet<WeakTrackingVH, 16> Preds;
for (auto &Block : Blocks) {
auto *BB = cast_or_null<BasicBlock>(Block);
if (!BB)
@@ -683,16 +683,16 @@ bool CodeGenPrepare::eliminateFallThrough(Function &F) {
// Merge BB into SinglePred and delete it.
MergeBlockIntoPredecessor(BB);
- Preds.insert(SinglePred);
+ Preds.insert(SinglePred);
}
}
-
- // (Repeatedly) merging blocks into their predecessors can create redundant
- // debug intrinsics.
- for (auto &Pred : Preds)
- if (auto *BB = cast_or_null<BasicBlock>(Pred))
- RemoveRedundantDbgInstrs(BB);
-
+
+ // (Repeatedly) merging blocks into their predecessors can create redundant
+ // debug intrinsics.
+ for (auto &Pred : Preds)
+ if (auto *BB = cast_or_null<BasicBlock>(Pred))
+ RemoveRedundantDbgInstrs(BB);
+
return Changed;
}
@@ -737,7 +737,7 @@ bool CodeGenPrepare::eliminateMostlyEmptyBlocks(Function &F) {
SmallVector<Loop *, 16> LoopList(LI->begin(), LI->end());
while (!LoopList.empty()) {
Loop *L = LoopList.pop_back_val();
- llvm::append_range(LoopList, *L);
+ llvm::append_range(LoopList, *L);
if (BasicBlock *Preheader = L->getLoopPreheader())
Preheaders.insert(Preheader);
}
@@ -747,7 +747,7 @@ bool CodeGenPrepare::eliminateMostlyEmptyBlocks(Function &F) {
// as we remove them.
// Note that this intentionally skips the entry block.
SmallVector<WeakTrackingVH, 16> Blocks;
- for (auto &Block : llvm::drop_begin(F))
+ for (auto &Block : llvm::drop_begin(F))
Blocks.push_back(&Block);
for (auto &Block : Blocks) {
@@ -2062,14 +2062,14 @@ bool CodeGenPrepare::optimizeCallInst(CallInst *CI, bool &ModifiedDT) {
switch (II->getIntrinsicID()) {
default: break;
case Intrinsic::assume: {
- Value *Operand = II->getOperand(0);
+ Value *Operand = II->getOperand(0);
II->eraseFromParent();
- // Prune the operand, it's most likely dead.
- resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
- RecursivelyDeleteTriviallyDeadInstructions(
- Operand, TLInfo, nullptr,
- [&](Value *V) { removeAllAssertingVHReferences(V); });
- });
+ // Prune the operand, it's most likely dead.
+ resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
+ RecursivelyDeleteTriviallyDeadInstructions(
+ Operand, TLInfo, nullptr,
+ [&](Value *V) { removeAllAssertingVHReferences(V); });
+ });
return true;
}
@@ -2230,7 +2230,7 @@ bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB, bool &ModifiedDT
EVI = dyn_cast<ExtractValueInst>(V);
if (EVI) {
V = EVI->getOperand(0);
- if (!llvm::all_of(EVI->indices(), [](unsigned idx) { return idx == 0; }))
+ if (!llvm::all_of(EVI->indices(), [](unsigned idx) { return idx == 0; }))
return false;
}
@@ -2249,12 +2249,12 @@ bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB, bool &ModifiedDT
// Skip over debug and the bitcast.
do {
++BI;
- } while (isa<DbgInfoIntrinsic>(BI) || &*BI == BCI || &*BI == EVI ||
- isa<PseudoProbeInst>(BI));
+ } while (isa<DbgInfoIntrinsic>(BI) || &*BI == BCI || &*BI == EVI ||
+ isa<PseudoProbeInst>(BI));
if (&*BI != RetI)
return false;
} else {
- if (BB->getFirstNonPHIOrDbg(true) != RetI)
+ if (BB->getFirstNonPHIOrDbg(true) != RetI)
return false;
}
@@ -2279,12 +2279,12 @@ bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB, bool &ModifiedDT
for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) {
if (!VisitedBBs.insert(*PI).second)
continue;
- if (Instruction *I = (*PI)->rbegin()->getPrevNonDebugInstruction(true)) {
- CallInst *CI = dyn_cast<CallInst>(I);
- if (CI && CI->use_empty() && TLI->mayBeEmittedAsTailCall(CI) &&
- attributesPermitTailCall(F, CI, RetI, *TLI))
- TailCallBBs.push_back(*PI);
- }
+ if (Instruction *I = (*PI)->rbegin()->getPrevNonDebugInstruction(true)) {
+ CallInst *CI = dyn_cast<CallInst>(I);
+ if (CI && CI->use_empty() && TLI->mayBeEmittedAsTailCall(CI) &&
+ attributesPermitTailCall(F, CI, RetI, *TLI))
+ TailCallBBs.push_back(*PI);
+ }
}
}
@@ -2308,7 +2308,7 @@ bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB, bool &ModifiedDT
}
// If we eliminated all predecessors of the block, delete the block now.
- if (Changed && !BB->hasAddressTaken() && pred_empty(BB))
+ if (Changed && !BB->hasAddressTaken() && pred_empty(BB))
BB->eraseFromParent();
return Changed;
@@ -3159,7 +3159,7 @@ public:
/// \returns whether the element is actually removed, i.e. was in the
/// collection before the operation.
bool erase(PHINode *Ptr) {
- if (NodeMap.erase(Ptr)) {
+ if (NodeMap.erase(Ptr)) {
SkipRemovedElements(FirstValidElement);
return true;
}
@@ -3714,7 +3714,7 @@ private:
PHINode::Create(CommonType, PredCount, "sunk_phi", CurrentPhi);
Map[Current] = PHI;
ST.insertNewPhi(PHI);
- append_range(Worklist, CurrentPhi->incoming_values());
+ append_range(Worklist, CurrentPhi->incoming_values());
}
}
}
@@ -4336,7 +4336,7 @@ bool AddressingModeMatcher::matchOperationAddr(User *AddrInst, unsigned Opcode,
unsigned SrcAS
= AddrInst->getOperand(0)->getType()->getPointerAddressSpace();
unsigned DestAS = AddrInst->getType()->getPointerAddressSpace();
- if (TLI.getTargetMachine().isNoopAddrSpaceCast(SrcAS, DestAS))
+ if (TLI.getTargetMachine().isNoopAddrSpaceCast(SrcAS, DestAS))
return matchAddr(AddrInst->getOperand(0), Depth);
return false;
}
@@ -4968,7 +4968,7 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
// For a PHI node, push all of its incoming values.
if (PHINode *P = dyn_cast<PHINode>(V)) {
- append_range(worklist, P->incoming_values());
+ append_range(worklist, P->incoming_values());
PhiOrSelectSeen = true;
continue;
}
@@ -5282,11 +5282,11 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
// If we have no uses, recursively delete the value and all dead instructions
// using it.
if (Repl->use_empty()) {
- resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
- RecursivelyDeleteTriviallyDeadInstructions(
- Repl, TLInfo, nullptr,
- [&](Value *V) { removeAllAssertingVHReferences(V); });
- });
+ resetIteratorIfInvalidatedWhileCalling(CurInstIterator->getParent(), [&]() {
+ RecursivelyDeleteTriviallyDeadInstructions(
+ Repl, TLInfo, nullptr,
+ [&](Value *V) { removeAllAssertingVHReferences(V); });
+ });
}
++NumMemoryInsts;
return true;
@@ -5307,112 +5307,112 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
///
/// If the final index isn't a vector or is a splat, we can emit a scalar GEP
/// followed by a GEP with an all zeroes vector index. This will enable
-/// SelectionDAGBuilder to use the scalar GEP as the uniform base and have a
+/// SelectionDAGBuilder to use the scalar GEP as the uniform base and have a
/// zero index.
bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
Value *Ptr) {
- Value *NewAddr;
-
- if (const auto *GEP = dyn_cast<GetElementPtrInst>(Ptr)) {
- // Don't optimize GEPs that don't have indices.
- if (!GEP->hasIndices())
- return false;
-
- // If the GEP and the gather/scatter aren't in the same BB, don't optimize.
- // FIXME: We should support this by sinking the GEP.
- if (MemoryInst->getParent() != GEP->getParent())
- return false;
-
- SmallVector<Value *, 2> Ops(GEP->operands());
-
- bool RewriteGEP = false;
-
- if (Ops[0]->getType()->isVectorTy()) {
- Ops[0] = getSplatValue(Ops[0]);
- if (!Ops[0])
- return false;
- RewriteGEP = true;
- }
-
- unsigned FinalIndex = Ops.size() - 1;
-
- // Ensure all but the last index is 0.
- // FIXME: This isn't strictly required. All that's required is that they are
- // all scalars or splats.
- for (unsigned i = 1; i < FinalIndex; ++i) {
- auto *C = dyn_cast<Constant>(Ops[i]);
- if (!C)
- return false;
- if (isa<VectorType>(C->getType()))
- C = C->getSplatValue();
- auto *CI = dyn_cast_or_null<ConstantInt>(C);
- if (!CI || !CI->isZero())
- return false;
- // Scalarize the index if needed.
- Ops[i] = CI;
- }
-
- // Try to scalarize the final index.
- if (Ops[FinalIndex]->getType()->isVectorTy()) {
- if (Value *V = getSplatValue(Ops[FinalIndex])) {
- auto *C = dyn_cast<ConstantInt>(V);
- // Don't scalarize all zeros vector.
- if (!C || !C->isZero()) {
- Ops[FinalIndex] = V;
- RewriteGEP = true;
- }
+ Value *NewAddr;
+
+ if (const auto *GEP = dyn_cast<GetElementPtrInst>(Ptr)) {
+ // Don't optimize GEPs that don't have indices.
+ if (!GEP->hasIndices())
+ return false;
+
+ // If the GEP and the gather/scatter aren't in the same BB, don't optimize.
+ // FIXME: We should support this by sinking the GEP.
+ if (MemoryInst->getParent() != GEP->getParent())
+ return false;
+
+ SmallVector<Value *, 2> Ops(GEP->operands());
+
+ bool RewriteGEP = false;
+
+ if (Ops[0]->getType()->isVectorTy()) {
+ Ops[0] = getSplatValue(Ops[0]);
+ if (!Ops[0])
+ return false;
+ RewriteGEP = true;
+ }
+
+ unsigned FinalIndex = Ops.size() - 1;
+
+ // Ensure all but the last index is 0.
+ // FIXME: This isn't strictly required. All that's required is that they are
+ // all scalars or splats.
+ for (unsigned i = 1; i < FinalIndex; ++i) {
+ auto *C = dyn_cast<Constant>(Ops[i]);
+ if (!C)
+ return false;
+ if (isa<VectorType>(C->getType()))
+ C = C->getSplatValue();
+ auto *CI = dyn_cast_or_null<ConstantInt>(C);
+ if (!CI || !CI->isZero())
+ return false;
+ // Scalarize the index if needed.
+ Ops[i] = CI;
+ }
+
+ // Try to scalarize the final index.
+ if (Ops[FinalIndex]->getType()->isVectorTy()) {
+ if (Value *V = getSplatValue(Ops[FinalIndex])) {
+ auto *C = dyn_cast<ConstantInt>(V);
+ // Don't scalarize all zeros vector.
+ if (!C || !C->isZero()) {
+ Ops[FinalIndex] = V;
+ RewriteGEP = true;
+ }
}
}
- // If we made any changes or the we have extra operands, we need to generate
- // new instructions.
- if (!RewriteGEP && Ops.size() == 2)
- return false;
-
- auto NumElts = cast<VectorType>(Ptr->getType())->getElementCount();
-
- IRBuilder<> Builder(MemoryInst);
-
- Type *ScalarIndexTy = DL->getIndexType(Ops[0]->getType()->getScalarType());
-
- // If the final index isn't a vector, emit a scalar GEP containing all ops
- // and a vector GEP with all zeroes final index.
- if (!Ops[FinalIndex]->getType()->isVectorTy()) {
- NewAddr = Builder.CreateGEP(Ops[0], makeArrayRef(Ops).drop_front());
- auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
- NewAddr = Builder.CreateGEP(NewAddr, Constant::getNullValue(IndexTy));
- } else {
- Value *Base = Ops[0];
- Value *Index = Ops[FinalIndex];
-
- // Create a scalar GEP if there are more than 2 operands.
- if (Ops.size() != 2) {
- // Replace the last index with 0.
- Ops[FinalIndex] = Constant::getNullValue(ScalarIndexTy);
- Base = Builder.CreateGEP(Base, makeArrayRef(Ops).drop_front());
- }
-
- // Now create the GEP with scalar pointer and vector index.
- NewAddr = Builder.CreateGEP(Base, Index);
- }
- } else if (!isa<Constant>(Ptr)) {
- // Not a GEP, maybe its a splat and we can create a GEP to enable
- // SelectionDAGBuilder to use it as a uniform base.
- Value *V = getSplatValue(Ptr);
- if (!V)
- return false;
-
- auto NumElts = cast<VectorType>(Ptr->getType())->getElementCount();
-
- IRBuilder<> Builder(MemoryInst);
-
- // Emit a vector GEP with a scalar pointer and all 0s vector index.
- Type *ScalarIndexTy = DL->getIndexType(V->getType()->getScalarType());
- auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
- NewAddr = Builder.CreateGEP(V, Constant::getNullValue(IndexTy));
- } else {
- // Constant, SelectionDAGBuilder knows to check if its a splat.
- return false;
+ // If we made any changes or the we have extra operands, we need to generate
+ // new instructions.
+ if (!RewriteGEP && Ops.size() == 2)
+ return false;
+
+ auto NumElts = cast<VectorType>(Ptr->getType())->getElementCount();
+
+ IRBuilder<> Builder(MemoryInst);
+
+ Type *ScalarIndexTy = DL->getIndexType(Ops[0]->getType()->getScalarType());
+
+ // If the final index isn't a vector, emit a scalar GEP containing all ops
+ // and a vector GEP with all zeroes final index.
+ if (!Ops[FinalIndex]->getType()->isVectorTy()) {
+ NewAddr = Builder.CreateGEP(Ops[0], makeArrayRef(Ops).drop_front());
+ auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
+ NewAddr = Builder.CreateGEP(NewAddr, Constant::getNullValue(IndexTy));
+ } else {
+ Value *Base = Ops[0];
+ Value *Index = Ops[FinalIndex];
+
+ // Create a scalar GEP if there are more than 2 operands.
+ if (Ops.size() != 2) {
+ // Replace the last index with 0.
+ Ops[FinalIndex] = Constant::getNullValue(ScalarIndexTy);
+ Base = Builder.CreateGEP(Base, makeArrayRef(Ops).drop_front());
+ }
+
+ // Now create the GEP with scalar pointer and vector index.
+ NewAddr = Builder.CreateGEP(Base, Index);
+ }
+ } else if (!isa<Constant>(Ptr)) {
+ // Not a GEP, maybe its a splat and we can create a GEP to enable
+ // SelectionDAGBuilder to use it as a uniform base.
+ Value *V = getSplatValue(Ptr);
+ if (!V)
+ return false;
+
+ auto NumElts = cast<VectorType>(Ptr->getType())->getElementCount();
+
+ IRBuilder<> Builder(MemoryInst);
+
+ // Emit a vector GEP with a scalar pointer and all 0s vector index.
+ Type *ScalarIndexTy = DL->getIndexType(V->getType()->getScalarType());
+ auto *IndexTy = VectorType::get(ScalarIndexTy, NumElts);
+ NewAddr = Builder.CreateGEP(V, Constant::getNullValue(IndexTy));
+ } else {
+ // Constant, SelectionDAGBuilder knows to check if its a splat.
+ return false;
}
MemoryInst->replaceUsesOfWith(Ptr, NewAddr);
@@ -5420,9 +5420,9 @@ bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
// If we have no uses, recursively delete the value and all dead instructions
// using it.
if (Ptr->use_empty())
- RecursivelyDeleteTriviallyDeadInstructions(
- Ptr, TLInfo, nullptr,
- [&](Value *V) { removeAllAssertingVHReferences(V); });
+ RecursivelyDeleteTriviallyDeadInstructions(
+ Ptr, TLInfo, nullptr,
+ [&](Value *V) { removeAllAssertingVHReferences(V); });
return true;
}
@@ -5811,12 +5811,12 @@ bool CodeGenPrepare::optimizePhiType(
Visited.insert(I);
SmallPtrSet<Instruction *, 4> Defs;
SmallPtrSet<Instruction *, 4> Uses;
- // This works by adding extra bitcasts between load/stores and removing
- // existing bicasts. If we have a phi(bitcast(load)) or a store(bitcast(phi))
- // we can get in the situation where we remove a bitcast in one iteration
- // just to add it again in the next. We need to ensure that at least one
- // bitcast we remove are anchored to something that will not change back.
- bool AnyAnchored = false;
+ // This works by adding extra bitcasts between load/stores and removing
+ // existing bicasts. If we have a phi(bitcast(load)) or a store(bitcast(phi))
+ // we can get in the situation where we remove a bitcast in one iteration
+ // just to add it again in the next. We need to ensure that at least one
+ // bitcast we remove are anchored to something that will not change back.
+ bool AnyAnchored = false;
while (!Worklist.empty()) {
Instruction *II = Worklist.pop_back_val();
@@ -5833,8 +5833,8 @@ bool CodeGenPrepare::optimizePhiType(
Worklist.push_back(OpPhi);
}
} else if (auto *OpLoad = dyn_cast<LoadInst>(V)) {
- if (!OpLoad->isSimple())
- return false;
+ if (!OpLoad->isSimple())
+ return false;
if (!Defs.count(OpLoad)) {
Defs.insert(OpLoad);
Worklist.push_back(OpLoad);
@@ -5852,12 +5852,12 @@ bool CodeGenPrepare::optimizePhiType(
if (!Defs.count(OpBC)) {
Defs.insert(OpBC);
Worklist.push_back(OpBC);
- AnyAnchored |= !isa<LoadInst>(OpBC->getOperand(0)) &&
- !isa<ExtractElementInst>(OpBC->getOperand(0));
+ AnyAnchored |= !isa<LoadInst>(OpBC->getOperand(0)) &&
+ !isa<ExtractElementInst>(OpBC->getOperand(0));
}
- } else if (!isa<UndefValue>(V)) {
+ } else if (!isa<UndefValue>(V)) {
return false;
- }
+ }
}
}
@@ -5872,7 +5872,7 @@ bool CodeGenPrepare::optimizePhiType(
Worklist.push_back(OpPhi);
}
} else if (auto *OpStore = dyn_cast<StoreInst>(V)) {
- if (!OpStore->isSimple() || OpStore->getOperand(0) != II)
+ if (!OpStore->isSimple() || OpStore->getOperand(0) != II)
return false;
Uses.insert(OpStore);
} else if (auto *OpBC = dyn_cast<BitCastInst>(V)) {
@@ -5881,15 +5881,15 @@ bool CodeGenPrepare::optimizePhiType(
if (OpBC->getType() != ConvertTy)
return false;
Uses.insert(OpBC);
- AnyAnchored |=
- any_of(OpBC->users(), [](User *U) { return !isa<StoreInst>(U); });
- } else {
+ AnyAnchored |=
+ any_of(OpBC->users(), [](User *U) { return !isa<StoreInst>(U); });
+ } else {
return false;
- }
+ }
}
}
- if (!ConvertTy || !AnyAnchored || !TLI->shouldConvertPhiType(PhiTy, ConvertTy))
+ if (!ConvertTy || !AnyAnchored || !TLI->shouldConvertPhiType(PhiTy, ConvertTy))
return false;
LLVM_DEBUG(dbgs() << "Converting " << *I << "\n and connected nodes to "
@@ -5900,13 +5900,13 @@ bool CodeGenPrepare::optimizePhiType(
ValueToValueMap ValMap;
ValMap[UndefValue::get(PhiTy)] = UndefValue::get(ConvertTy);
for (Instruction *D : Defs) {
- if (isa<BitCastInst>(D)) {
+ if (isa<BitCastInst>(D)) {
ValMap[D] = D->getOperand(0);
- DeletedInstrs.insert(D);
- } else {
+ DeletedInstrs.insert(D);
+ } else {
ValMap[D] =
new BitCastInst(D, ConvertTy, D->getName() + ".bc", D->getNextNode());
- }
+ }
}
for (PHINode *Phi : PhiNodes)
ValMap[Phi] = PHINode::Create(ConvertTy, Phi->getNumIncomingValues(),
@@ -5917,17 +5917,17 @@ bool CodeGenPrepare::optimizePhiType(
for (int i = 0, e = Phi->getNumIncomingValues(); i < e; i++)
NewPhi->addIncoming(ValMap[Phi->getIncomingValue(i)],
Phi->getIncomingBlock(i));
- Visited.insert(NewPhi);
+ Visited.insert(NewPhi);
}
// And finally pipe up the stores and bitcasts
for (Instruction *U : Uses) {
if (isa<BitCastInst>(U)) {
DeletedInstrs.insert(U);
U->replaceAllUsesWith(ValMap[U->getOperand(0)]);
- } else {
+ } else {
U->setOperand(0,
new BitCastInst(ValMap[U->getOperand(0)], PhiTy, "bc", U));
- }
+ }
}
// Save the removed phis to be deleted later.
@@ -6522,7 +6522,7 @@ bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
/// If we have a SelectInst that will likely profit from branch prediction,
/// turn it into a branch.
bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
- if (DisableSelectToBranch)
+ if (DisableSelectToBranch)
return false;
// Find all consecutive select instructions that share the same condition.
@@ -6558,8 +6558,8 @@ bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
SelectKind = TargetLowering::ScalarValSelect;
if (TLI->isSelectSupported(SelectKind) &&
- (!isFormingBranchFromSelectProfitable(TTI, TLI, SI) || OptSize ||
- llvm::shouldOptimizeForSize(SI->getParent(), PSI, BFI.get())))
+ (!isFormingBranchFromSelectProfitable(TTI, TLI, SI) || OptSize ||
+ llvm::shouldOptimizeForSize(SI->getParent(), PSI, BFI.get())))
return false;
// The DominatorTree needs to be rebuilt by any consumers after this
@@ -6697,7 +6697,7 @@ bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
/// in MVE takes a GPR (integer) register, and the instruction that incorporate
/// a VDUP (such as a VADD qd, qm, rm) also require a gpr register.
bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
- // Accept shuf(insertelem(undef/poison, val, 0), undef/poison, <0,0,..>) only
+ // Accept shuf(insertelem(undef/poison, val, 0), undef/poison, <0,0,..>) only
if (!match(SVI, m_Shuffle(m_InsertElt(m_Undef(), m_Value(), m_ZeroInt()),
m_Undef(), m_ZeroMask())))
return false;
@@ -6717,12 +6717,12 @@ bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
Builder.SetInsertPoint(SVI);
Value *BC1 = Builder.CreateBitCast(
cast<Instruction>(SVI->getOperand(0))->getOperand(1), NewType);
- Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
+ Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1);
Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
SVI->replaceAllUsesWith(BC2);
- RecursivelyDeleteTriviallyDeadInstructions(
- SVI, TLInfo, nullptr, [&](Value *V) { removeAllAssertingVHReferences(V); });
+ RecursivelyDeleteTriviallyDeadInstructions(
+ SVI, TLInfo, nullptr, [&](Value *V) { removeAllAssertingVHReferences(V); });
// Also hoist the bitcast up to its operand if it they are not in the same
// block.
@@ -6995,10 +6995,10 @@ class VectorPromoteHelper {
if (UseSplat)
return ConstantVector::getSplat(EC, Val);
- if (!EC.isScalable()) {
+ if (!EC.isScalable()) {
SmallVector<Constant *, 4> ConstVec;
UndefValue *UndefVal = UndefValue::get(Val->getType());
- for (unsigned Idx = 0; Idx != EC.getKnownMinValue(); ++Idx) {
+ for (unsigned Idx = 0; Idx != EC.getKnownMinValue(); ++Idx) {
if (Idx == ExtractIdx)
ConstVec.push_back(Val);
else
@@ -7679,10 +7679,10 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, bool &ModifiedDT) {
/// Given an OR instruction, check to see if this is a bitreverse
/// idiom. If so, insert the new intrinsic and return true.
-bool CodeGenPrepare::makeBitReverse(Instruction &I) {
+bool CodeGenPrepare::makeBitReverse(Instruction &I) {
if (!I.getType()->isIntegerTy() ||
- !TLI->isOperationLegalOrCustom(ISD::BITREVERSE,
- TLI->getValueType(*DL, I.getType(), true)))
+ !TLI->isOperationLegalOrCustom(ISD::BITREVERSE,
+ TLI->getValueType(*DL, I.getType(), true)))
return false;
SmallVector<Instruction*, 4> Insts;
@@ -7690,8 +7690,8 @@ bool CodeGenPrepare::makeBitReverse(Instruction &I) {
return false;
Instruction *LastInst = Insts.back();
I.replaceAllUsesWith(LastInst);
- RecursivelyDeleteTriviallyDeadInstructions(
- &I, TLInfo, nullptr, [&](Value *V) { removeAllAssertingVHReferences(V); });
+ RecursivelyDeleteTriviallyDeadInstructions(
+ &I, TLInfo, nullptr, [&](Value *V) { removeAllAssertingVHReferences(V); });
return true;
}
@@ -7713,7 +7713,7 @@ bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, bool &ModifiedDT) {
while (MadeBitReverse) {
MadeBitReverse = false;
for (auto &I : reverse(BB)) {
- if (makeBitReverse(I)) {
+ if (makeBitReverse(I)) {
MadeBitReverse = MadeChange = true;
break;
}
@@ -7832,10 +7832,10 @@ bool CodeGenPrepare::splitBranchCondition(Function &F, bool &ModifiedDT) {
// %cond2 = icmp|fcmp|binary instruction ...
// %cond.or = or|and i1 %cond1, cond2
// br i1 %cond.or label %dest1, label %dest2"
- Instruction *LogicOp;
+ Instruction *LogicOp;
BasicBlock *TBB, *FBB;
- if (!match(BB.getTerminator(),
- m_Br(m_OneUse(m_Instruction(LogicOp)), TBB, FBB)))
+ if (!match(BB.getTerminator(),
+ m_Br(m_OneUse(m_Instruction(LogicOp)), TBB, FBB)))
continue;
auto *Br1 = cast<BranchInst>(BB.getTerminator());
@@ -7848,22 +7848,22 @@ bool CodeGenPrepare::splitBranchCondition(Function &F, bool &ModifiedDT) {
unsigned Opc;
Value *Cond1, *Cond2;
- if (match(LogicOp,
- m_LogicalAnd(m_OneUse(m_Value(Cond1)), m_OneUse(m_Value(Cond2)))))
+ if (match(LogicOp,
+ m_LogicalAnd(m_OneUse(m_Value(Cond1)), m_OneUse(m_Value(Cond2)))))
Opc = Instruction::And;
- else if (match(LogicOp, m_LogicalOr(m_OneUse(m_Value(Cond1)),
- m_OneUse(m_Value(Cond2)))))
+ else if (match(LogicOp, m_LogicalOr(m_OneUse(m_Value(Cond1)),
+ m_OneUse(m_Value(Cond2)))))
Opc = Instruction::Or;
else
continue;
- auto IsGoodCond = [](Value *Cond) {
- return match(
- Cond,
- m_CombineOr(m_Cmp(), m_CombineOr(m_LogicalAnd(m_Value(), m_Value()),
- m_LogicalOr(m_Value(), m_Value()))));
- };
- if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
+ auto IsGoodCond = [](Value *Cond) {
+ return match(
+ Cond,
+ m_CombineOr(m_Cmp(), m_CombineOr(m_LogicalAnd(m_Value(), m_Value()),
+ m_LogicalOr(m_Value(), m_Value()))));
+ };
+ if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2))
continue;
LLVM_DEBUG(dbgs() << "Before branch condition splitting\n"; BB.dump());
diff --git a/contrib/libs/llvm12/lib/CodeGen/CommandFlags.cpp b/contrib/libs/llvm12/lib/CodeGen/CommandFlags.cpp
index a96d12cd3e..97c110afdd 100644
--- a/contrib/libs/llvm12/lib/CodeGen/CommandFlags.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/CommandFlags.cpp
@@ -58,7 +58,7 @@ CGOPT(bool, EnableNoInfsFPMath)
CGOPT(bool, EnableNoNaNsFPMath)
CGOPT(bool, EnableNoSignedZerosFPMath)
CGOPT(bool, EnableNoTrappingFPMath)
-CGOPT(bool, EnableAIXExtendedAltivecABI)
+CGOPT(bool, EnableAIXExtendedAltivecABI)
CGOPT(DenormalMode::DenormalModeKind, DenormalFPMath)
CGOPT(DenormalMode::DenormalModeKind, DenormalFP32Math)
CGOPT(bool, EnableHonorSignDependentRoundingFPMath)
@@ -75,12 +75,12 @@ CGOPT(bool, UseCtors)
CGOPT(bool, RelaxELFRelocations)
CGOPT_EXP(bool, DataSections)
CGOPT_EXP(bool, FunctionSections)
-CGOPT(bool, IgnoreXCOFFVisibility)
-CGOPT(bool, XCOFFTracebackTable)
+CGOPT(bool, IgnoreXCOFFVisibility)
+CGOPT(bool, XCOFFTracebackTable)
CGOPT(std::string, BBSections)
-CGOPT(std::string, StackProtectorGuard)
-CGOPT(unsigned, StackProtectorGuardOffset)
-CGOPT(std::string, StackProtectorGuardReg)
+CGOPT(std::string, StackProtectorGuard)
+CGOPT(unsigned, StackProtectorGuardOffset)
+CGOPT(std::string, StackProtectorGuardReg)
CGOPT(unsigned, TLSSize)
CGOPT(bool, EmulatedTLS)
CGOPT(bool, UniqueSectionNames)
@@ -90,10 +90,10 @@ CGOPT(DebuggerKind, DebuggerTuningOpt)
CGOPT(bool, EnableStackSizeSection)
CGOPT(bool, EnableAddrsig)
CGOPT(bool, EmitCallSiteInfo)
-CGOPT(bool, EnableMachineFunctionSplitter)
+CGOPT(bool, EnableMachineFunctionSplitter)
CGOPT(bool, EnableDebugEntryValues)
-CGOPT(bool, PseudoProbeForProfiling)
-CGOPT(bool, ValueTrackingVariableLocations)
+CGOPT(bool, PseudoProbeForProfiling)
+CGOPT(bool, ValueTrackingVariableLocations)
CGOPT(bool, ForceDwarfFrameSection)
CGOPT(bool, XRayOmitFunctionIndex)
@@ -285,11 +285,11 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
cl::init(false));
CGBINDOPT(DontPlaceZerosInBSS);
- static cl::opt<bool> EnableAIXExtendedAltivecABI(
- "vec-extabi", cl::desc("Enable the AIX Extended Altivec ABI."),
- cl::init(false));
- CGBINDOPT(EnableAIXExtendedAltivecABI);
-
+ static cl::opt<bool> EnableAIXExtendedAltivecABI(
+ "vec-extabi", cl::desc("Enable the AIX Extended Altivec ABI."),
+ cl::init(false));
+ CGBINDOPT(EnableAIXExtendedAltivecABI);
+
static cl::opt<bool> EnableGuaranteedTailCallOpt(
"tailcallopt",
cl::desc(
@@ -345,40 +345,40 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
cl::init(false));
CGBINDOPT(FunctionSections);
- static cl::opt<bool> IgnoreXCOFFVisibility(
- "ignore-xcoff-visibility",
- cl::desc("Not emit the visibility attribute for asm in AIX OS or give "
- "all symbols 'unspecified' visibility in XCOFF object file"),
- cl::init(false));
- CGBINDOPT(IgnoreXCOFFVisibility);
-
- static cl::opt<bool> XCOFFTracebackTable(
- "xcoff-traceback-table", cl::desc("Emit the XCOFF traceback table"),
- cl::init(true));
- CGBINDOPT(XCOFFTracebackTable);
-
+ static cl::opt<bool> IgnoreXCOFFVisibility(
+ "ignore-xcoff-visibility",
+ cl::desc("Not emit the visibility attribute for asm in AIX OS or give "
+ "all symbols 'unspecified' visibility in XCOFF object file"),
+ cl::init(false));
+ CGBINDOPT(IgnoreXCOFFVisibility);
+
+ static cl::opt<bool> XCOFFTracebackTable(
+ "xcoff-traceback-table", cl::desc("Emit the XCOFF traceback table"),
+ cl::init(true));
+ CGBINDOPT(XCOFFTracebackTable);
+
static cl::opt<std::string> BBSections(
- "basic-block-sections",
+ "basic-block-sections",
cl::desc("Emit basic blocks into separate sections"),
cl::value_desc("all | <function list (file)> | labels | none"),
cl::init("none"));
CGBINDOPT(BBSections);
- static cl::opt<std::string> StackProtectorGuard(
- "stack-protector-guard", cl::desc("Stack protector guard mode"),
- cl::init("none"));
- CGBINDOPT(StackProtectorGuard);
-
- static cl::opt<std::string> StackProtectorGuardReg(
- "stack-protector-guard-reg", cl::desc("Stack protector guard register"),
- cl::init("none"));
- CGBINDOPT(StackProtectorGuardReg);
-
- static cl::opt<unsigned> StackProtectorGuardOffset(
- "stack-protector-guard-offset", cl::desc("Stack protector guard offset"),
- cl::init((unsigned)-1));
- CGBINDOPT(StackProtectorGuardOffset);
-
+ static cl::opt<std::string> StackProtectorGuard(
+ "stack-protector-guard", cl::desc("Stack protector guard mode"),
+ cl::init("none"));
+ CGBINDOPT(StackProtectorGuard);
+
+ static cl::opt<std::string> StackProtectorGuardReg(
+ "stack-protector-guard-reg", cl::desc("Stack protector guard register"),
+ cl::init("none"));
+ CGBINDOPT(StackProtectorGuardReg);
+
+ static cl::opt<unsigned> StackProtectorGuardOffset(
+ "stack-protector-guard-offset", cl::desc("Stack protector guard offset"),
+ cl::init((unsigned)-1));
+ CGBINDOPT(StackProtectorGuardOffset);
+
static cl::opt<unsigned> TLSSize(
"tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(0));
CGBINDOPT(TLSSize);
@@ -393,7 +393,7 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
CGBINDOPT(UniqueSectionNames);
static cl::opt<bool> UniqueBasicBlockSectionNames(
- "unique-basic-block-section-names",
+ "unique-basic-block-section-names",
cl::desc("Give unique names to every basic block section"),
cl::init(false));
CGBINDOPT(UniqueBasicBlockSectionNames);
@@ -441,24 +441,24 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
cl::init(false));
CGBINDOPT(EnableDebugEntryValues);
- static cl::opt<bool> PseudoProbeForProfiling(
- "pseudo-probe-for-profiling", cl::desc("Emit pseudo probes for AutoFDO"),
- cl::init(false));
- CGBINDOPT(PseudoProbeForProfiling);
-
- static cl::opt<bool> ValueTrackingVariableLocations(
- "experimental-debug-variable-locations",
- cl::desc("Use experimental new value-tracking variable locations"),
- cl::init(false));
- CGBINDOPT(ValueTrackingVariableLocations);
-
- static cl::opt<bool> EnableMachineFunctionSplitter(
- "split-machine-functions",
- cl::desc("Split out cold basic blocks from machine functions based on "
- "profile information"),
- cl::init(false));
- CGBINDOPT(EnableMachineFunctionSplitter);
-
+ static cl::opt<bool> PseudoProbeForProfiling(
+ "pseudo-probe-for-profiling", cl::desc("Emit pseudo probes for AutoFDO"),
+ cl::init(false));
+ CGBINDOPT(PseudoProbeForProfiling);
+
+ static cl::opt<bool> ValueTrackingVariableLocations(
+ "experimental-debug-variable-locations",
+ cl::desc("Use experimental new value-tracking variable locations"),
+ cl::init(false));
+ CGBINDOPT(ValueTrackingVariableLocations);
+
+ static cl::opt<bool> EnableMachineFunctionSplitter(
+ "split-machine-functions",
+ cl::desc("Split out cold basic blocks from machine functions based on "
+ "profile information"),
+ cl::init(false));
+ CGBINDOPT(EnableMachineFunctionSplitter);
+
static cl::opt<bool> ForceDwarfFrameSection(
"force-dwarf-frame-section",
cl::desc("Always emit a debug frame section."), cl::init(false));
@@ -495,28 +495,28 @@ codegen::getBBSectionsMode(llvm::TargetOptions &Options) {
}
}
-llvm::StackProtectorGuards
-codegen::getStackProtectorGuardMode(llvm::TargetOptions &Options) {
- if (getStackProtectorGuard() == "tls")
- return StackProtectorGuards::TLS;
- if (getStackProtectorGuard() == "global")
- return StackProtectorGuards::Global;
- if (getStackProtectorGuard() != "none") {
- ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
- MemoryBuffer::getFile(getStackProtectorGuard());
- if (!MBOrErr)
- errs() << "error illegal stack protector guard mode: "
- << MBOrErr.getError().message() << "\n";
- else
- Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
- }
- return StackProtectorGuards::None;
-}
-
+llvm::StackProtectorGuards
+codegen::getStackProtectorGuardMode(llvm::TargetOptions &Options) {
+ if (getStackProtectorGuard() == "tls")
+ return StackProtectorGuards::TLS;
+ if (getStackProtectorGuard() == "global")
+ return StackProtectorGuards::Global;
+ if (getStackProtectorGuard() != "none") {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
+ MemoryBuffer::getFile(getStackProtectorGuard());
+ if (!MBOrErr)
+ errs() << "error illegal stack protector guard mode: "
+ << MBOrErr.getError().message() << "\n";
+ else
+ Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
+ }
+ return StackProtectorGuards::None;
+}
+
// Common utility function tightly tied to the options listed here. Initializes
// a TargetOptions object with CodeGen flags and returns it.
-TargetOptions
-codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
+TargetOptions
+codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
TargetOptions Options;
Options.AllowFPOpFusion = getFuseFPOps();
Options.UnsafeFPMath = getEnableUnsafeFPMath();
@@ -534,35 +534,35 @@ codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
getEnableHonorSignDependentRoundingFPMath();
if (getFloatABIForCalls() != FloatABI::Default)
Options.FloatABIType = getFloatABIForCalls();
- Options.EnableAIXExtendedAltivecABI = getEnableAIXExtendedAltivecABI();
+ Options.EnableAIXExtendedAltivecABI = getEnableAIXExtendedAltivecABI();
Options.NoZerosInBSS = getDontPlaceZerosInBSS();
Options.GuaranteedTailCallOpt = getEnableGuaranteedTailCallOpt();
Options.StackAlignmentOverride = getOverrideStackAlignment();
Options.StackSymbolOrdering = getStackSymbolOrdering();
Options.UseInitArray = !getUseCtors();
Options.RelaxELFRelocations = getRelaxELFRelocations();
- Options.DataSections =
- getExplicitDataSections().getValueOr(TheTriple.hasDefaultDataSections());
+ Options.DataSections =
+ getExplicitDataSections().getValueOr(TheTriple.hasDefaultDataSections());
Options.FunctionSections = getFunctionSections();
- Options.IgnoreXCOFFVisibility = getIgnoreXCOFFVisibility();
- Options.XCOFFTracebackTable = getXCOFFTracebackTable();
+ Options.IgnoreXCOFFVisibility = getIgnoreXCOFFVisibility();
+ Options.XCOFFTracebackTable = getXCOFFTracebackTable();
Options.BBSections = getBBSectionsMode(Options);
Options.UniqueSectionNames = getUniqueSectionNames();
Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames();
- Options.StackProtectorGuard = getStackProtectorGuardMode(Options);
- Options.StackProtectorGuardOffset = getStackProtectorGuardOffset();
- Options.StackProtectorGuardReg = getStackProtectorGuardReg();
+ Options.StackProtectorGuard = getStackProtectorGuardMode(Options);
+ Options.StackProtectorGuardOffset = getStackProtectorGuardOffset();
+ Options.StackProtectorGuardReg = getStackProtectorGuardReg();
Options.TLSSize = getTLSSize();
Options.EmulatedTLS = getEmulatedTLS();
Options.ExplicitEmulatedTLS = EmulatedTLSView->getNumOccurrences() > 0;
Options.ExceptionModel = getExceptionModel();
Options.EmitStackSizeSection = getEnableStackSizeSection();
- Options.EnableMachineFunctionSplitter = getEnableMachineFunctionSplitter();
+ Options.EnableMachineFunctionSplitter = getEnableMachineFunctionSplitter();
Options.EmitAddrsig = getEnableAddrsig();
Options.EmitCallSiteInfo = getEmitCallSiteInfo();
Options.EnableDebugEntryValues = getEnableDebugEntryValues();
- Options.PseudoProbeForProfiling = getPseudoProbeForProfiling();
- Options.ValueTrackingVariableLocations = getValueTrackingVariableLocations();
+ Options.PseudoProbeForProfiling = getPseudoProbeForProfiling();
+ Options.ValueTrackingVariableLocations = getValueTrackingVariableLocations();
Options.ForceDwarfFrameSection = getForceDwarfFrameSection();
Options.XRayOmitFunctionIndex = getXRayOmitFunctionIndex();
diff --git a/contrib/libs/llvm12/lib/CodeGen/DeadMachineInstructionElim.cpp b/contrib/libs/llvm12/lib/CodeGen/DeadMachineInstructionElim.cpp
index 95df2a1c66..93467e9d09 100644
--- a/contrib/libs/llvm12/lib/CodeGen/DeadMachineInstructionElim.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/DeadMachineInstructionElim.cpp
@@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
@@ -49,8 +49,8 @@ namespace {
private:
bool isDead(const MachineInstr *MI) const;
-
- bool eliminateDeadMI(MachineFunction &MF);
+
+ bool eliminateDeadMI(MachineFunction &MF);
};
}
char DeadMachineInstructionElim::ID = 0;
@@ -110,13 +110,13 @@ bool DeadMachineInstructionElim::isDead(const MachineInstr *MI) const {
bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) {
if (skipFunction(MF.getFunction()))
return false;
- bool AnyChanges = eliminateDeadMI(MF);
- while (AnyChanges && eliminateDeadMI(MF))
- ;
- return AnyChanges;
-}
+ bool AnyChanges = eliminateDeadMI(MF);
+ while (AnyChanges && eliminateDeadMI(MF))
+ ;
+ return AnyChanges;
+}
-bool DeadMachineInstructionElim::eliminateDeadMI(MachineFunction &MF) {
+bool DeadMachineInstructionElim::eliminateDeadMI(MachineFunction &MF) {
bool AnyChanges = false;
MRI = &MF.getRegInfo();
TRI = MF.getSubtarget().getRegisterInfo();
@@ -125,24 +125,24 @@ bool DeadMachineInstructionElim::eliminateDeadMI(MachineFunction &MF) {
// Loop over all instructions in all blocks, from bottom to top, so that it's
// more likely that chains of dependent but ultimately dead instructions will
// be cleaned up.
- for (MachineBasicBlock *MBB : post_order(&MF)) {
+ for (MachineBasicBlock *MBB : post_order(&MF)) {
// Start out assuming that reserved registers are live out of this block.
LivePhysRegs = MRI->getReservedRegs();
// Add live-ins from successors to LivePhysRegs. Normally, physregs are not
// live across blocks, but some targets (x86) can have flags live out of a
// block.
- for (MachineBasicBlock::succ_iterator S = MBB->succ_begin(),
- E = MBB->succ_end();
- S != E; S++)
+ for (MachineBasicBlock::succ_iterator S = MBB->succ_begin(),
+ E = MBB->succ_end();
+ S != E; S++)
for (const auto &LI : (*S)->liveins())
LivePhysRegs.set(LI.PhysReg);
// Now scan the instructions and delete dead ones, tracking physreg
// liveness as we go.
- for (MachineBasicBlock::reverse_iterator MII = MBB->rbegin(),
- MIE = MBB->rend();
- MII != MIE;) {
+ for (MachineBasicBlock::reverse_iterator MII = MBB->rbegin(),
+ MIE = MBB->rend();
+ MII != MIE;) {
MachineInstr *MI = &*MII++;
// If the instruction is dead, delete it!
diff --git a/contrib/libs/llvm12/lib/CodeGen/DetectDeadLanes.cpp b/contrib/libs/llvm12/lib/CodeGen/DetectDeadLanes.cpp
index 920ffa9535..03fe5f1552 100644
--- a/contrib/libs/llvm12/lib/CodeGen/DetectDeadLanes.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/DetectDeadLanes.cpp
@@ -36,7 +36,7 @@
#include "llvm/PassRegistry.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include <deque>
+#include <deque>
using namespace llvm;
diff --git a/contrib/libs/llvm12/lib/CodeGen/DwarfEHPrepare.cpp b/contrib/libs/llvm12/lib/CodeGen/DwarfEHPrepare.cpp
index 05a94b3fda..97e0162f35 100644
--- a/contrib/libs/llvm12/lib/CodeGen/DwarfEHPrepare.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/DwarfEHPrepare.cpp
@@ -15,7 +15,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/CFG.h"
-#include "llvm/Analysis/DomTreeUpdater.h"
+#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/CodeGen/RuntimeLibcalls.h"
@@ -45,43 +45,43 @@ STATISTIC(NumResumesLowered, "Number of resume calls lowered");
namespace {
-class DwarfEHPrepare {
- CodeGenOpt::Level OptLevel;
+class DwarfEHPrepare {
+ CodeGenOpt::Level OptLevel;
- // RewindFunction - _Unwind_Resume or the target equivalent.
- FunctionCallee &RewindFunction;
+ // RewindFunction - _Unwind_Resume or the target equivalent.
+ FunctionCallee &RewindFunction;
- Function &F;
- const TargetLowering &TLI;
- DomTreeUpdater *DTU;
- const TargetTransformInfo *TTI;
+ Function &F;
+ const TargetLowering &TLI;
+ DomTreeUpdater *DTU;
+ const TargetTransformInfo *TTI;
- /// Return the exception object from the value passed into
- /// the 'resume' instruction (typically an aggregate). Clean up any dead
- /// instructions, including the 'resume' instruction.
- Value *GetExceptionObject(ResumeInst *RI);
+ /// Return the exception object from the value passed into
+ /// the 'resume' instruction (typically an aggregate). Clean up any dead
+ /// instructions, including the 'resume' instruction.
+ Value *GetExceptionObject(ResumeInst *RI);
- /// Replace resumes that are not reachable from a cleanup landing pad with
- /// unreachable and then simplify those blocks.
- size_t
- pruneUnreachableResumes(SmallVectorImpl<ResumeInst *> &Resumes,
- SmallVectorImpl<LandingPadInst *> &CleanupLPads);
+ /// Replace resumes that are not reachable from a cleanup landing pad with
+ /// unreachable and then simplify those blocks.
+ size_t
+ pruneUnreachableResumes(SmallVectorImpl<ResumeInst *> &Resumes,
+ SmallVectorImpl<LandingPadInst *> &CleanupLPads);
- /// Convert the ResumeInsts that are still present
- /// into calls to the appropriate _Unwind_Resume function.
- bool InsertUnwindResumeCalls();
+ /// Convert the ResumeInsts that are still present
+ /// into calls to the appropriate _Unwind_Resume function.
+ bool InsertUnwindResumeCalls();
-public:
- DwarfEHPrepare(CodeGenOpt::Level OptLevel_, FunctionCallee &RewindFunction_,
- Function &F_, const TargetLowering &TLI_, DomTreeUpdater *DTU_,
- const TargetTransformInfo *TTI_)
- : OptLevel(OptLevel_), RewindFunction(RewindFunction_), F(F_), TLI(TLI_),
- DTU(DTU_), TTI(TTI_) {}
+public:
+ DwarfEHPrepare(CodeGenOpt::Level OptLevel_, FunctionCallee &RewindFunction_,
+ Function &F_, const TargetLowering &TLI_, DomTreeUpdater *DTU_,
+ const TargetTransformInfo *TTI_)
+ : OptLevel(OptLevel_), RewindFunction(RewindFunction_), F(F_), TLI(TLI_),
+ DTU(DTU_), TTI(TTI_) {}
- bool run();
-};
+ bool run();
+};
-} // namespace
+} // namespace
Value *DwarfEHPrepare::GetExceptionObject(ResumeInst *RI) {
Value *V = RI->getOperand(0);
@@ -121,15 +121,15 @@ Value *DwarfEHPrepare::GetExceptionObject(ResumeInst *RI) {
}
size_t DwarfEHPrepare::pruneUnreachableResumes(
- SmallVectorImpl<ResumeInst *> &Resumes,
+ SmallVectorImpl<ResumeInst *> &Resumes,
SmallVectorImpl<LandingPadInst *> &CleanupLPads) {
- assert(DTU && "Should have DomTreeUpdater here.");
-
+ assert(DTU && "Should have DomTreeUpdater here.");
+
BitVector ResumeReachable(Resumes.size());
size_t ResumeIndex = 0;
for (auto *RI : Resumes) {
for (auto *LP : CleanupLPads) {
- if (isPotentiallyReachable(LP, RI, nullptr, &DTU->getDomTree())) {
+ if (isPotentiallyReachable(LP, RI, nullptr, &DTU->getDomTree())) {
ResumeReachable.set(ResumeIndex);
break;
}
@@ -141,7 +141,7 @@ size_t DwarfEHPrepare::pruneUnreachableResumes(
if (ResumeReachable.all())
return Resumes.size();
- LLVMContext &Ctx = F.getContext();
+ LLVMContext &Ctx = F.getContext();
// Otherwise, insert unreachable instructions and call simplifycfg.
size_t ResumesLeft = 0;
@@ -153,17 +153,17 @@ size_t DwarfEHPrepare::pruneUnreachableResumes(
BasicBlock *BB = RI->getParent();
new UnreachableInst(Ctx, RI);
RI->eraseFromParent();
- simplifyCFG(BB, *TTI, RequireAndPreserveDomTree ? DTU : nullptr);
+ simplifyCFG(BB, *TTI, RequireAndPreserveDomTree ? DTU : nullptr);
}
}
Resumes.resize(ResumesLeft);
return ResumesLeft;
}
-bool DwarfEHPrepare::InsertUnwindResumeCalls() {
- SmallVector<ResumeInst *, 16> Resumes;
- SmallVector<LandingPadInst *, 16> CleanupLPads;
- for (BasicBlock &BB : F) {
+bool DwarfEHPrepare::InsertUnwindResumeCalls() {
+ SmallVector<ResumeInst *, 16> Resumes;
+ SmallVector<LandingPadInst *, 16> CleanupLPads;
+ for (BasicBlock &BB : F) {
if (auto *RI = dyn_cast<ResumeInst>(BB.getTerminator()))
Resumes.push_back(RI);
if (auto *LP = BB.getLandingPadInst())
@@ -175,25 +175,25 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls() {
return false;
// Check the personality, don't do anything if it's scope-based.
- EHPersonality Pers = classifyEHPersonality(F.getPersonalityFn());
+ EHPersonality Pers = classifyEHPersonality(F.getPersonalityFn());
if (isScopedEHPersonality(Pers))
return false;
- LLVMContext &Ctx = F.getContext();
+ LLVMContext &Ctx = F.getContext();
size_t ResumesLeft = Resumes.size();
if (OptLevel != CodeGenOpt::None)
- ResumesLeft = pruneUnreachableResumes(Resumes, CleanupLPads);
+ ResumesLeft = pruneUnreachableResumes(Resumes, CleanupLPads);
if (ResumesLeft == 0)
return true; // We pruned them all.
// Find the rewind function if we didn't already.
if (!RewindFunction) {
- FunctionType *FTy =
- FunctionType::get(Type::getVoidTy(Ctx), Type::getInt8PtrTy(Ctx), false);
- const char *RewindName = TLI.getLibcallName(RTLIB::UNWIND_RESUME);
- RewindFunction = F.getParent()->getOrInsertFunction(RewindName, FTy);
+ FunctionType *FTy =
+ FunctionType::get(Type::getVoidTy(Ctx), Type::getInt8PtrTy(Ctx), false);
+ const char *RewindName = TLI.getLibcallName(RTLIB::UNWIND_RESUME);
+ RewindFunction = F.getParent()->getOrInsertFunction(RewindName, FTy);
}
// Create the basic block where the _Unwind_Resume call will live.
@@ -206,27 +206,27 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls() {
// Call the _Unwind_Resume function.
CallInst *CI = CallInst::Create(RewindFunction, ExnObj, "", UnwindBB);
- CI->setCallingConv(TLI.getLibcallCallingConv(RTLIB::UNWIND_RESUME));
+ CI->setCallingConv(TLI.getLibcallCallingConv(RTLIB::UNWIND_RESUME));
// We never expect _Unwind_Resume to return.
- CI->setDoesNotReturn();
+ CI->setDoesNotReturn();
new UnreachableInst(Ctx, UnwindBB);
return true;
}
- std::vector<DominatorTree::UpdateType> Updates;
- Updates.reserve(Resumes.size());
+ std::vector<DominatorTree::UpdateType> Updates;
+ Updates.reserve(Resumes.size());
+
+ BasicBlock *UnwindBB = BasicBlock::Create(Ctx, "unwind_resume", &F);
+ PHINode *PN = PHINode::Create(Type::getInt8PtrTy(Ctx), ResumesLeft, "exn.obj",
+ UnwindBB);
- BasicBlock *UnwindBB = BasicBlock::Create(Ctx, "unwind_resume", &F);
- PHINode *PN = PHINode::Create(Type::getInt8PtrTy(Ctx), ResumesLeft, "exn.obj",
- UnwindBB);
-
// Extract the exception object from the ResumeInst and add it to the PHI node
// that feeds the _Unwind_Resume call.
for (ResumeInst *RI : Resumes) {
BasicBlock *Parent = RI->getParent();
BranchInst::Create(UnwindBB, Parent);
- Updates.push_back({DominatorTree::Insert, Parent, UnwindBB});
+ Updates.push_back({DominatorTree::Insert, Parent, UnwindBB});
Value *ExnObj = GetExceptionObject(RI);
PN->addIncoming(ExnObj, Parent);
@@ -236,100 +236,100 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls() {
// Call the function.
CallInst *CI = CallInst::Create(RewindFunction, PN, "", UnwindBB);
- CI->setCallingConv(TLI.getLibcallCallingConv(RTLIB::UNWIND_RESUME));
+ CI->setCallingConv(TLI.getLibcallCallingConv(RTLIB::UNWIND_RESUME));
// We never expect _Unwind_Resume to return.
- CI->setDoesNotReturn();
+ CI->setDoesNotReturn();
new UnreachableInst(Ctx, UnwindBB);
-
- if (DTU && RequireAndPreserveDomTree)
- DTU->applyUpdates(Updates);
-
+
+ if (DTU && RequireAndPreserveDomTree)
+ DTU->applyUpdates(Updates);
+
return true;
}
-bool DwarfEHPrepare::run() {
- assert(((OptLevel == CodeGenOpt::None || !RequireAndPreserveDomTree) ||
- (DTU &&
- DTU->getDomTree().verify(DominatorTree::VerificationLevel::Full))) &&
- "Original domtree is invalid?");
-
- bool Changed = InsertUnwindResumeCalls();
-
- assert(((OptLevel == CodeGenOpt::None || !RequireAndPreserveDomTree) ||
- (DTU &&
- DTU->getDomTree().verify(DominatorTree::VerificationLevel::Full))) &&
- "Original domtree is invalid?");
-
+bool DwarfEHPrepare::run() {
+ assert(((OptLevel == CodeGenOpt::None || !RequireAndPreserveDomTree) ||
+ (DTU &&
+ DTU->getDomTree().verify(DominatorTree::VerificationLevel::Full))) &&
+ "Original domtree is invalid?");
+
+ bool Changed = InsertUnwindResumeCalls();
+
+ assert(((OptLevel == CodeGenOpt::None || !RequireAndPreserveDomTree) ||
+ (DTU &&
+ DTU->getDomTree().verify(DominatorTree::VerificationLevel::Full))) &&
+ "Original domtree is invalid?");
+
return Changed;
}
-
-static bool prepareDwarfEH(CodeGenOpt::Level OptLevel,
- FunctionCallee &RewindFunction, Function &F,
- const TargetLowering &TLI, DominatorTree *DT,
- const TargetTransformInfo *TTI) {
- DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
-
- return DwarfEHPrepare(OptLevel, RewindFunction, F, TLI, DT ? &DTU : nullptr,
- TTI)
- .run();
-}
-
-namespace {
-
-class DwarfEHPrepareLegacyPass : public FunctionPass {
- // RewindFunction - _Unwind_Resume or the target equivalent.
- FunctionCallee RewindFunction = nullptr;
-
- CodeGenOpt::Level OptLevel;
-
-public:
- static char ID; // Pass identification, replacement for typeid.
-
- DwarfEHPrepareLegacyPass(CodeGenOpt::Level OptLevel = CodeGenOpt::Default)
- : FunctionPass(ID), OptLevel(OptLevel) {}
-
- bool runOnFunction(Function &F) override {
- const TargetMachine &TM =
- getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
- const TargetLowering &TLI = *TM.getSubtargetImpl(F)->getTargetLowering();
- DominatorTree *DT = nullptr;
- const TargetTransformInfo *TTI = nullptr;
- if (OptLevel != CodeGenOpt::None) {
- DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
- }
- return prepareDwarfEH(OptLevel, RewindFunction, F, TLI, DT, TTI);
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<TargetPassConfig>();
- AU.addRequired<TargetTransformInfoWrapperPass>();
- if (OptLevel != CodeGenOpt::None) {
- AU.addRequired<DominatorTreeWrapperPass>();
- AU.addRequired<TargetTransformInfoWrapperPass>();
- if (RequireAndPreserveDomTree)
- AU.addPreserved<DominatorTreeWrapperPass>();
- }
- }
-
- StringRef getPassName() const override {
- return "Exception handling preparation";
- }
-};
-
-} // end anonymous namespace
-
-char DwarfEHPrepareLegacyPass::ID = 0;
-
-INITIALIZE_PASS_BEGIN(DwarfEHPrepareLegacyPass, DEBUG_TYPE,
- "Prepare DWARF exceptions", false, false)
-INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
-INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
-INITIALIZE_PASS_END(DwarfEHPrepareLegacyPass, DEBUG_TYPE,
- "Prepare DWARF exceptions", false, false)
-
-FunctionPass *llvm::createDwarfEHPass(CodeGenOpt::Level OptLevel) {
- return new DwarfEHPrepareLegacyPass(OptLevel);
-}
+
+static bool prepareDwarfEH(CodeGenOpt::Level OptLevel,
+ FunctionCallee &RewindFunction, Function &F,
+ const TargetLowering &TLI, DominatorTree *DT,
+ const TargetTransformInfo *TTI) {
+ DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
+
+ return DwarfEHPrepare(OptLevel, RewindFunction, F, TLI, DT ? &DTU : nullptr,
+ TTI)
+ .run();
+}
+
+namespace {
+
+class DwarfEHPrepareLegacyPass : public FunctionPass {
+ // RewindFunction - _Unwind_Resume or the target equivalent.
+ FunctionCallee RewindFunction = nullptr;
+
+ CodeGenOpt::Level OptLevel;
+
+public:
+ static char ID; // Pass identification, replacement for typeid.
+
+ DwarfEHPrepareLegacyPass(CodeGenOpt::Level OptLevel = CodeGenOpt::Default)
+ : FunctionPass(ID), OptLevel(OptLevel) {}
+
+ bool runOnFunction(Function &F) override {
+ const TargetMachine &TM =
+ getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
+ const TargetLowering &TLI = *TM.getSubtargetImpl(F)->getTargetLowering();
+ DominatorTree *DT = nullptr;
+ const TargetTransformInfo *TTI = nullptr;
+ if (OptLevel != CodeGenOpt::None) {
+ DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
+ }
+ return prepareDwarfEH(OptLevel, RewindFunction, F, TLI, DT, TTI);
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<TargetPassConfig>();
+ AU.addRequired<TargetTransformInfoWrapperPass>();
+ if (OptLevel != CodeGenOpt::None) {
+ AU.addRequired<DominatorTreeWrapperPass>();
+ AU.addRequired<TargetTransformInfoWrapperPass>();
+ if (RequireAndPreserveDomTree)
+ AU.addPreserved<DominatorTreeWrapperPass>();
+ }
+ }
+
+ StringRef getPassName() const override {
+ return "Exception handling preparation";
+ }
+};
+
+} // end anonymous namespace
+
+char DwarfEHPrepareLegacyPass::ID = 0;
+
+INITIALIZE_PASS_BEGIN(DwarfEHPrepareLegacyPass, DEBUG_TYPE,
+ "Prepare DWARF exceptions", false, false)
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
+INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
+INITIALIZE_PASS_END(DwarfEHPrepareLegacyPass, DEBUG_TYPE,
+ "Prepare DWARF exceptions", false, false)
+
+FunctionPass *llvm::createDwarfEHPass(CodeGenOpt::Level OptLevel) {
+ return new DwarfEHPrepareLegacyPass(OptLevel);
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/EarlyIfConversion.cpp b/contrib/libs/llvm12/lib/CodeGen/EarlyIfConversion.cpp
index 1a8b890c5d..cf7d93d6a3 100644
--- a/contrib/libs/llvm12/lib/CodeGen/EarlyIfConversion.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/EarlyIfConversion.cpp
@@ -27,7 +27,7 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
-#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
+#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MachineTraceMetrics.h"
#include "llvm/CodeGen/Passes.h"
@@ -265,8 +265,8 @@ bool SSAIfConv::InstrDependenciesAllowIfConv(MachineInstr *I) {
// Remember clobbered regunits.
if (MO.isDef() && Register::isPhysicalRegister(Reg))
- for (MCRegUnitIterator Units(Reg.asMCReg(), TRI); Units.isValid();
- ++Units)
+ for (MCRegUnitIterator Units(Reg.asMCReg(), TRI); Units.isValid();
+ ++Units)
ClobberedRegUnits.set(*Units);
if (!MO.readsReg() || !Register::isVirtualRegister(Reg))
@@ -365,7 +365,7 @@ bool SSAIfConv::findInsertionPoint() {
// Keep track of live regunits before the current position.
// Only track RegUnits that are also in ClobberedRegUnits.
LiveRegUnits.clear();
- SmallVector<MCRegister, 8> Reads;
+ SmallVector<MCRegister, 8> Reads;
MachineBasicBlock::iterator FirstTerm = Head->getFirstTerminator();
MachineBasicBlock::iterator I = Head->end();
MachineBasicBlock::iterator B = Head->begin();
@@ -387,12 +387,12 @@ bool SSAIfConv::findInsertionPoint() {
continue;
// I clobbers Reg, so it isn't live before I.
if (MO.isDef())
- for (MCRegUnitIterator Units(Reg.asMCReg(), TRI); Units.isValid();
- ++Units)
+ for (MCRegUnitIterator Units(Reg.asMCReg(), TRI); Units.isValid();
+ ++Units)
LiveRegUnits.erase(*Units);
// Unless I reads Reg.
if (MO.readsReg())
- Reads.push_back(Reg.asMCReg());
+ Reads.push_back(Reg.asMCReg());
}
// Anything read by I is live before I.
while (!Reads.empty())
@@ -797,17 +797,17 @@ static unsigned adjCycles(unsigned Cyc, int Delta) {
return Cyc + Delta;
}
-namespace {
-/// Helper class to simplify emission of cycle counts into optimization remarks.
-struct Cycles {
- const char *Key;
- unsigned Value;
-};
-template <typename Remark> Remark &operator<<(Remark &R, Cycles C) {
- return R << ore::NV(C.Key, C.Value) << (C.Value == 1 ? " cycle" : " cycles");
-}
-} // anonymous namespace
-
+namespace {
+/// Helper class to simplify emission of cycle counts into optimization remarks.
+struct Cycles {
+ const char *Key;
+ unsigned Value;
+};
+template <typename Remark> Remark &operator<<(Remark &R, Cycles C) {
+ return R << ore::NV(C.Key, C.Value) << (C.Value == 1 ? " cycle" : " cycles");
+}
+} // anonymous namespace
+
/// Apply cost model and heuristics to the if-conversion in IfConv.
/// Return true if the conversion is a good idea.
///
@@ -828,9 +828,9 @@ bool EarlyIfConverter::shouldConvertIf() {
// Set a somewhat arbitrary limit on the critical path extension we accept.
unsigned CritLimit = SchedModel.MispredictPenalty/2;
- MachineBasicBlock &MBB = *IfConv.Head;
- MachineOptimizationRemarkEmitter MORE(*MBB.getParent(), nullptr);
-
+ MachineBasicBlock &MBB = *IfConv.Head;
+ MachineOptimizationRemarkEmitter MORE(*MBB.getParent(), nullptr);
+
// If-conversion only makes sense when there is unexploited ILP. Compute the
// maximum-ILP resource length of the trace after if-conversion. Compare it
// to the shortest critical path.
@@ -842,17 +842,17 @@ bool EarlyIfConverter::shouldConvertIf() {
<< ", minimal critical path " << MinCrit << '\n');
if (ResLength > MinCrit + CritLimit) {
LLVM_DEBUG(dbgs() << "Not enough available ILP.\n");
- MORE.emit([&]() {
- MachineOptimizationRemarkMissed R(DEBUG_TYPE, "IfConversion",
- MBB.findDebugLoc(MBB.back()), &MBB);
- R << "did not if-convert branch: the resulting critical path ("
- << Cycles{"ResLength", ResLength}
- << ") would extend the shorter leg's critical path ("
- << Cycles{"MinCrit", MinCrit} << ") by more than the threshold of "
- << Cycles{"CritLimit", CritLimit}
- << ", which cannot be hidden by available ILP.";
- return R;
- });
+ MORE.emit([&]() {
+ MachineOptimizationRemarkMissed R(DEBUG_TYPE, "IfConversion",
+ MBB.findDebugLoc(MBB.back()), &MBB);
+ R << "did not if-convert branch: the resulting critical path ("
+ << Cycles{"ResLength", ResLength}
+ << ") would extend the shorter leg's critical path ("
+ << Cycles{"MinCrit", MinCrit} << ") by more than the threshold of "
+ << Cycles{"CritLimit", CritLimit}
+ << ", which cannot be hidden by available ILP.";
+ return R;
+ });
return false;
}
@@ -867,14 +867,14 @@ bool EarlyIfConverter::shouldConvertIf() {
// Look at all the tail phis, and compute the critical path extension caused
// by inserting select instructions.
MachineTraceMetrics::Trace TailTrace = MinInstr->getTrace(IfConv.Tail);
- struct CriticalPathInfo {
- unsigned Extra; // Count of extra cycles that the component adds.
- unsigned Depth; // Absolute depth of the component in cycles.
- };
- CriticalPathInfo Cond{};
- CriticalPathInfo TBlock{};
- CriticalPathInfo FBlock{};
- bool ShouldConvert = true;
+ struct CriticalPathInfo {
+ unsigned Extra; // Count of extra cycles that the component adds.
+ unsigned Depth; // Absolute depth of the component in cycles.
+ };
+ CriticalPathInfo Cond{};
+ CriticalPathInfo TBlock{};
+ CriticalPathInfo FBlock{};
+ bool ShouldConvert = true;
for (unsigned i = 0, e = IfConv.PHIs.size(); i != e; ++i) {
SSAIfConv::PHIInfo &PI = IfConv.PHIs[i];
unsigned Slack = TailTrace.getInstrSlack(*PI.PHI);
@@ -886,11 +886,11 @@ bool EarlyIfConverter::shouldConvertIf() {
if (CondDepth > MaxDepth) {
unsigned Extra = CondDepth - MaxDepth;
LLVM_DEBUG(dbgs() << "Condition adds " << Extra << " cycles.\n");
- if (Extra > Cond.Extra)
- Cond = {Extra, CondDepth};
+ if (Extra > Cond.Extra)
+ Cond = {Extra, CondDepth};
if (Extra > CritLimit) {
LLVM_DEBUG(dbgs() << "Exceeds limit of " << CritLimit << '\n');
- ShouldConvert = false;
+ ShouldConvert = false;
}
}
@@ -899,11 +899,11 @@ bool EarlyIfConverter::shouldConvertIf() {
if (TDepth > MaxDepth) {
unsigned Extra = TDepth - MaxDepth;
LLVM_DEBUG(dbgs() << "TBB data adds " << Extra << " cycles.\n");
- if (Extra > TBlock.Extra)
- TBlock = {Extra, TDepth};
+ if (Extra > TBlock.Extra)
+ TBlock = {Extra, TDepth};
if (Extra > CritLimit) {
LLVM_DEBUG(dbgs() << "Exceeds limit of " << CritLimit << '\n');
- ShouldConvert = false;
+ ShouldConvert = false;
}
}
@@ -912,63 +912,63 @@ bool EarlyIfConverter::shouldConvertIf() {
if (FDepth > MaxDepth) {
unsigned Extra = FDepth - MaxDepth;
LLVM_DEBUG(dbgs() << "FBB data adds " << Extra << " cycles.\n");
- if (Extra > FBlock.Extra)
- FBlock = {Extra, FDepth};
+ if (Extra > FBlock.Extra)
+ FBlock = {Extra, FDepth};
if (Extra > CritLimit) {
LLVM_DEBUG(dbgs() << "Exceeds limit of " << CritLimit << '\n');
- ShouldConvert = false;
+ ShouldConvert = false;
}
}
}
-
- // Organize by "short" and "long" legs, since the diagnostics get confusing
- // when referring to the "true" and "false" sides of the branch, given that
- // those don't always correlate with what the user wrote in source-terms.
- const CriticalPathInfo Short = TBlock.Extra > FBlock.Extra ? FBlock : TBlock;
- const CriticalPathInfo Long = TBlock.Extra > FBlock.Extra ? TBlock : FBlock;
-
- if (ShouldConvert) {
- MORE.emit([&]() {
- MachineOptimizationRemark R(DEBUG_TYPE, "IfConversion",
- MBB.back().getDebugLoc(), &MBB);
- R << "performing if-conversion on branch: the condition adds "
- << Cycles{"CondCycles", Cond.Extra} << " to the critical path";
- if (Short.Extra > 0)
- R << ", and the short leg adds another "
- << Cycles{"ShortCycles", Short.Extra};
- if (Long.Extra > 0)
- R << ", and the long leg adds another "
- << Cycles{"LongCycles", Long.Extra};
- R << ", each staying under the threshold of "
- << Cycles{"CritLimit", CritLimit} << ".";
- return R;
- });
- } else {
- MORE.emit([&]() {
- MachineOptimizationRemarkMissed R(DEBUG_TYPE, "IfConversion",
- MBB.back().getDebugLoc(), &MBB);
- R << "did not if-convert branch: the condition would add "
- << Cycles{"CondCycles", Cond.Extra} << " to the critical path";
- if (Cond.Extra > CritLimit)
- R << " exceeding the limit of " << Cycles{"CritLimit", CritLimit};
- if (Short.Extra > 0) {
- R << ", and the short leg would add another "
- << Cycles{"ShortCycles", Short.Extra};
- if (Short.Extra > CritLimit)
- R << " exceeding the limit of " << Cycles{"CritLimit", CritLimit};
- }
- if (Long.Extra > 0) {
- R << ", and the long leg would add another "
- << Cycles{"LongCycles", Long.Extra};
- if (Long.Extra > CritLimit)
- R << " exceeding the limit of " << Cycles{"CritLimit", CritLimit};
- }
- R << ".";
- return R;
- });
- }
-
- return ShouldConvert;
+
+ // Organize by "short" and "long" legs, since the diagnostics get confusing
+ // when referring to the "true" and "false" sides of the branch, given that
+ // those don't always correlate with what the user wrote in source-terms.
+ const CriticalPathInfo Short = TBlock.Extra > FBlock.Extra ? FBlock : TBlock;
+ const CriticalPathInfo Long = TBlock.Extra > FBlock.Extra ? TBlock : FBlock;
+
+ if (ShouldConvert) {
+ MORE.emit([&]() {
+ MachineOptimizationRemark R(DEBUG_TYPE, "IfConversion",
+ MBB.back().getDebugLoc(), &MBB);
+ R << "performing if-conversion on branch: the condition adds "
+ << Cycles{"CondCycles", Cond.Extra} << " to the critical path";
+ if (Short.Extra > 0)
+ R << ", and the short leg adds another "
+ << Cycles{"ShortCycles", Short.Extra};
+ if (Long.Extra > 0)
+ R << ", and the long leg adds another "
+ << Cycles{"LongCycles", Long.Extra};
+ R << ", each staying under the threshold of "
+ << Cycles{"CritLimit", CritLimit} << ".";
+ return R;
+ });
+ } else {
+ MORE.emit([&]() {
+ MachineOptimizationRemarkMissed R(DEBUG_TYPE, "IfConversion",
+ MBB.back().getDebugLoc(), &MBB);
+ R << "did not if-convert branch: the condition would add "
+ << Cycles{"CondCycles", Cond.Extra} << " to the critical path";
+ if (Cond.Extra > CritLimit)
+ R << " exceeding the limit of " << Cycles{"CritLimit", CritLimit};
+ if (Short.Extra > 0) {
+ R << ", and the short leg would add another "
+ << Cycles{"ShortCycles", Short.Extra};
+ if (Short.Extra > CritLimit)
+ R << " exceeding the limit of " << Cycles{"CritLimit", CritLimit};
+ }
+ if (Long.Extra > 0) {
+ R << ", and the long leg would add another "
+ << Cycles{"LongCycles", Long.Extra};
+ if (Long.Extra > CritLimit)
+ R << " exceeding the limit of " << Cycles{"CritLimit", CritLimit};
+ }
+ R << ".";
+ return R;
+ });
+ }
+
+ return ShouldConvert;
}
/// Attempt repeated if-conversion on MBB, return true if successful.
diff --git a/contrib/libs/llvm12/lib/CodeGen/ExpandReductions.cpp b/contrib/libs/llvm12/lib/CodeGen/ExpandReductions.cpp
index d28eb1a9f3..a4c9f02dc6 100644
--- a/contrib/libs/llvm12/lib/CodeGen/ExpandReductions.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/ExpandReductions.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
//
// This pass implements IR expansion for reduction intrinsics, allowing targets
-// to enable the intrinsics until just before codegen.
+// to enable the intrinsics until just before codegen.
//
//===----------------------------------------------------------------------===//
@@ -30,49 +30,49 @@ namespace {
unsigned getOpcode(Intrinsic::ID ID) {
switch (ID) {
- case Intrinsic::vector_reduce_fadd:
+ case Intrinsic::vector_reduce_fadd:
return Instruction::FAdd;
- case Intrinsic::vector_reduce_fmul:
+ case Intrinsic::vector_reduce_fmul:
return Instruction::FMul;
- case Intrinsic::vector_reduce_add:
+ case Intrinsic::vector_reduce_add:
return Instruction::Add;
- case Intrinsic::vector_reduce_mul:
+ case Intrinsic::vector_reduce_mul:
return Instruction::Mul;
- case Intrinsic::vector_reduce_and:
+ case Intrinsic::vector_reduce_and:
return Instruction::And;
- case Intrinsic::vector_reduce_or:
+ case Intrinsic::vector_reduce_or:
return Instruction::Or;
- case Intrinsic::vector_reduce_xor:
+ case Intrinsic::vector_reduce_xor:
return Instruction::Xor;
- case Intrinsic::vector_reduce_smax:
- case Intrinsic::vector_reduce_smin:
- case Intrinsic::vector_reduce_umax:
- case Intrinsic::vector_reduce_umin:
+ case Intrinsic::vector_reduce_smax:
+ case Intrinsic::vector_reduce_smin:
+ case Intrinsic::vector_reduce_umax:
+ case Intrinsic::vector_reduce_umin:
return Instruction::ICmp;
- case Intrinsic::vector_reduce_fmax:
- case Intrinsic::vector_reduce_fmin:
+ case Intrinsic::vector_reduce_fmax:
+ case Intrinsic::vector_reduce_fmin:
return Instruction::FCmp;
default:
llvm_unreachable("Unexpected ID");
}
}
-RecurKind getRK(Intrinsic::ID ID) {
+RecurKind getRK(Intrinsic::ID ID) {
switch (ID) {
- case Intrinsic::vector_reduce_smax:
- return RecurKind::SMax;
- case Intrinsic::vector_reduce_smin:
- return RecurKind::SMin;
- case Intrinsic::vector_reduce_umax:
- return RecurKind::UMax;
- case Intrinsic::vector_reduce_umin:
- return RecurKind::UMin;
- case Intrinsic::vector_reduce_fmax:
- return RecurKind::FMax;
- case Intrinsic::vector_reduce_fmin:
- return RecurKind::FMin;
+ case Intrinsic::vector_reduce_smax:
+ return RecurKind::SMax;
+ case Intrinsic::vector_reduce_smin:
+ return RecurKind::SMin;
+ case Intrinsic::vector_reduce_umax:
+ return RecurKind::UMax;
+ case Intrinsic::vector_reduce_umin:
+ return RecurKind::UMin;
+ case Intrinsic::vector_reduce_fmax:
+ return RecurKind::FMax;
+ case Intrinsic::vector_reduce_fmin:
+ return RecurKind::FMin;
default:
- return RecurKind::None;
+ return RecurKind::None;
}
}
@@ -83,19 +83,19 @@ bool expandReductions(Function &F, const TargetTransformInfo *TTI) {
if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
switch (II->getIntrinsicID()) {
default: break;
- case Intrinsic::vector_reduce_fadd:
- case Intrinsic::vector_reduce_fmul:
- case Intrinsic::vector_reduce_add:
- case Intrinsic::vector_reduce_mul:
- case Intrinsic::vector_reduce_and:
- case Intrinsic::vector_reduce_or:
- case Intrinsic::vector_reduce_xor:
- case Intrinsic::vector_reduce_smax:
- case Intrinsic::vector_reduce_smin:
- case Intrinsic::vector_reduce_umax:
- case Intrinsic::vector_reduce_umin:
- case Intrinsic::vector_reduce_fmax:
- case Intrinsic::vector_reduce_fmin:
+ case Intrinsic::vector_reduce_fadd:
+ case Intrinsic::vector_reduce_fmul:
+ case Intrinsic::vector_reduce_add:
+ case Intrinsic::vector_reduce_mul:
+ case Intrinsic::vector_reduce_and:
+ case Intrinsic::vector_reduce_or:
+ case Intrinsic::vector_reduce_xor:
+ case Intrinsic::vector_reduce_smax:
+ case Intrinsic::vector_reduce_smin:
+ case Intrinsic::vector_reduce_umax:
+ case Intrinsic::vector_reduce_umin:
+ case Intrinsic::vector_reduce_fmax:
+ case Intrinsic::vector_reduce_fmin:
if (TTI->shouldExpandReduction(II))
Worklist.push_back(II);
@@ -108,7 +108,7 @@ bool expandReductions(Function &F, const TargetTransformInfo *TTI) {
FastMathFlags FMF =
isa<FPMathOperator>(II) ? II->getFastMathFlags() : FastMathFlags{};
Intrinsic::ID ID = II->getIntrinsicID();
- RecurKind RK = getRK(ID);
+ RecurKind RK = getRK(ID);
Value *Rdx = nullptr;
IRBuilder<> Builder(II);
@@ -116,57 +116,57 @@ bool expandReductions(Function &F, const TargetTransformInfo *TTI) {
Builder.setFastMathFlags(FMF);
switch (ID) {
default: llvm_unreachable("Unexpected intrinsic!");
- case Intrinsic::vector_reduce_fadd:
- case Intrinsic::vector_reduce_fmul: {
+ case Intrinsic::vector_reduce_fadd:
+ case Intrinsic::vector_reduce_fmul: {
// FMFs must be attached to the call, otherwise it's an ordered reduction
// and it can't be handled by generating a shuffle sequence.
Value *Acc = II->getArgOperand(0);
Value *Vec = II->getArgOperand(1);
if (!FMF.allowReassoc())
- Rdx = getOrderedReduction(Builder, Acc, Vec, getOpcode(ID), RK);
+ Rdx = getOrderedReduction(Builder, Acc, Vec, getOpcode(ID), RK);
else {
if (!isPowerOf2_32(
cast<FixedVectorType>(Vec->getType())->getNumElements()))
continue;
- Rdx = getShuffleReduction(Builder, Vec, getOpcode(ID), RK);
+ Rdx = getShuffleReduction(Builder, Vec, getOpcode(ID), RK);
Rdx = Builder.CreateBinOp((Instruction::BinaryOps)getOpcode(ID),
Acc, Rdx, "bin.rdx");
}
break;
}
- case Intrinsic::vector_reduce_add:
- case Intrinsic::vector_reduce_mul:
- case Intrinsic::vector_reduce_and:
- case Intrinsic::vector_reduce_or:
- case Intrinsic::vector_reduce_xor:
- case Intrinsic::vector_reduce_smax:
- case Intrinsic::vector_reduce_smin:
- case Intrinsic::vector_reduce_umax:
- case Intrinsic::vector_reduce_umin: {
+ case Intrinsic::vector_reduce_add:
+ case Intrinsic::vector_reduce_mul:
+ case Intrinsic::vector_reduce_and:
+ case Intrinsic::vector_reduce_or:
+ case Intrinsic::vector_reduce_xor:
+ case Intrinsic::vector_reduce_smax:
+ case Intrinsic::vector_reduce_smin:
+ case Intrinsic::vector_reduce_umax:
+ case Intrinsic::vector_reduce_umin: {
Value *Vec = II->getArgOperand(0);
if (!isPowerOf2_32(
cast<FixedVectorType>(Vec->getType())->getNumElements()))
continue;
- Rdx = getShuffleReduction(Builder, Vec, getOpcode(ID), RK);
+ Rdx = getShuffleReduction(Builder, Vec, getOpcode(ID), RK);
+ break;
+ }
+ case Intrinsic::vector_reduce_fmax:
+ case Intrinsic::vector_reduce_fmin: {
+ // FIXME: We only expand 'fast' reductions here because the underlying
+ // code in createMinMaxOp() assumes that comparisons use 'fast'
+ // semantics.
+ Value *Vec = II->getArgOperand(0);
+ if (!isPowerOf2_32(
+ cast<FixedVectorType>(Vec->getType())->getNumElements()) ||
+ !FMF.isFast())
+ continue;
+
+ Rdx = getShuffleReduction(Builder, Vec, getOpcode(ID), RK);
break;
}
- case Intrinsic::vector_reduce_fmax:
- case Intrinsic::vector_reduce_fmin: {
- // FIXME: We only expand 'fast' reductions here because the underlying
- // code in createMinMaxOp() assumes that comparisons use 'fast'
- // semantics.
- Value *Vec = II->getArgOperand(0);
- if (!isPowerOf2_32(
- cast<FixedVectorType>(Vec->getType())->getNumElements()) ||
- !FMF.isFast())
- continue;
-
- Rdx = getShuffleReduction(Builder, Vec, getOpcode(ID), RK);
- break;
}
- }
II->replaceAllUsesWith(Rdx);
II->eraseFromParent();
Changed = true;
diff --git a/contrib/libs/llvm12/lib/CodeGen/FixupStatepointCallerSaved.cpp b/contrib/libs/llvm12/lib/CodeGen/FixupStatepointCallerSaved.cpp
index b7c0a46aa6..f8f99b7e87 100644
--- a/contrib/libs/llvm12/lib/CodeGen/FixupStatepointCallerSaved.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/FixupStatepointCallerSaved.cpp
@@ -46,20 +46,20 @@ static cl::opt<bool> FixupSCSExtendSlotSize(
cl::desc("Allow spill in spill slot of greater size than register size"),
cl::Hidden);
-static cl::opt<bool> PassGCPtrInCSR(
- "fixup-allow-gcptr-in-csr", cl::Hidden, cl::init(false),
- cl::desc("Allow passing GC Pointer arguments in callee saved registers"));
-
-static cl::opt<bool> EnableCopyProp(
- "fixup-scs-enable-copy-propagation", cl::Hidden, cl::init(true),
- cl::desc("Enable simple copy propagation during register reloading"));
-
-// This is purely debugging option.
-// It may be handy for investigating statepoint spilling issues.
-static cl::opt<unsigned> MaxStatepointsWithRegs(
- "fixup-max-csr-statepoints", cl::Hidden,
- cl::desc("Max number of statepoints allowed to pass GC Ptrs in registers"));
-
+static cl::opt<bool> PassGCPtrInCSR(
+ "fixup-allow-gcptr-in-csr", cl::Hidden, cl::init(false),
+ cl::desc("Allow passing GC Pointer arguments in callee saved registers"));
+
+static cl::opt<bool> EnableCopyProp(
+ "fixup-scs-enable-copy-propagation", cl::Hidden, cl::init(true),
+ cl::desc("Enable simple copy propagation during register reloading"));
+
+// This is purely debugging option.
+// It may be handy for investigating statepoint spilling issues.
+static cl::opt<unsigned> MaxStatepointsWithRegs(
+ "fixup-max-csr-statepoints", cl::Hidden,
+ cl::desc("Max number of statepoints allowed to pass GC Ptrs in registers"));
+
namespace {
class FixupStatepointCallerSaved : public MachineFunctionPass {
@@ -81,7 +81,7 @@ public:
bool runOnMachineFunction(MachineFunction &MF) override;
};
-
+
} // End anonymous namespace.
char FixupStatepointCallerSaved::ID = 0;
@@ -98,101 +98,101 @@ static unsigned getRegisterSize(const TargetRegisterInfo &TRI, Register Reg) {
return TRI.getSpillSize(*RC);
}
-// Try to eliminate redundant copy to register which we're going to
-// spill, i.e. try to change:
-// X = COPY Y
-// SPILL X
-// to
-// SPILL Y
-// If there are no uses of X between copy and STATEPOINT, that COPY
-// may be eliminated.
-// Reg - register we're about to spill
-// RI - On entry points to statepoint.
-// On successful copy propagation set to new spill point.
-// IsKill - set to true if COPY is Kill (there are no uses of Y)
-// Returns either found source copy register or original one.
-static Register performCopyPropagation(Register Reg,
- MachineBasicBlock::iterator &RI,
- bool &IsKill, const TargetInstrInfo &TII,
- const TargetRegisterInfo &TRI) {
- // First check if statepoint itself uses Reg in non-meta operands.
- int Idx = RI->findRegisterUseOperandIdx(Reg, false, &TRI);
- if (Idx >= 0 && (unsigned)Idx < StatepointOpers(&*RI).getNumDeoptArgsIdx()) {
- IsKill = false;
- return Reg;
- }
-
- if (!EnableCopyProp)
- return Reg;
-
- MachineBasicBlock *MBB = RI->getParent();
- MachineBasicBlock::reverse_iterator E = MBB->rend();
- MachineInstr *Def = nullptr, *Use = nullptr;
- for (auto It = ++(RI.getReverse()); It != E; ++It) {
- if (It->readsRegister(Reg, &TRI) && !Use)
- Use = &*It;
- if (It->modifiesRegister(Reg, &TRI)) {
- Def = &*It;
- break;
- }
- }
-
- if (!Def)
- return Reg;
-
- auto DestSrc = TII.isCopyInstr(*Def);
- if (!DestSrc || DestSrc->Destination->getReg() != Reg)
- return Reg;
-
- Register SrcReg = DestSrc->Source->getReg();
-
- if (getRegisterSize(TRI, Reg) != getRegisterSize(TRI, SrcReg))
- return Reg;
-
- LLVM_DEBUG(dbgs() << "spillRegisters: perform copy propagation "
- << printReg(Reg, &TRI) << " -> " << printReg(SrcReg, &TRI)
- << "\n");
-
- // Insert spill immediately after Def
- RI = ++MachineBasicBlock::iterator(Def);
- IsKill = DestSrc->Source->isKill();
-
- // There are no uses of original register between COPY and STATEPOINT.
- // There can't be any after STATEPOINT, so we can eliminate Def.
- if (!Use) {
- LLVM_DEBUG(dbgs() << "spillRegisters: removing dead copy " << *Def);
- Def->eraseFromParent();
- }
- return SrcReg;
-}
-
+// Try to eliminate redundant copy to register which we're going to
+// spill, i.e. try to change:
+// X = COPY Y
+// SPILL X
+// to
+// SPILL Y
+// If there are no uses of X between copy and STATEPOINT, that COPY
+// may be eliminated.
+// Reg - register we're about to spill
+// RI - On entry points to statepoint.
+// On successful copy propagation set to new spill point.
+// IsKill - set to true if COPY is Kill (there are no uses of Y)
+// Returns either found source copy register or original one.
+static Register performCopyPropagation(Register Reg,
+ MachineBasicBlock::iterator &RI,
+ bool &IsKill, const TargetInstrInfo &TII,
+ const TargetRegisterInfo &TRI) {
+ // First check if statepoint itself uses Reg in non-meta operands.
+ int Idx = RI->findRegisterUseOperandIdx(Reg, false, &TRI);
+ if (Idx >= 0 && (unsigned)Idx < StatepointOpers(&*RI).getNumDeoptArgsIdx()) {
+ IsKill = false;
+ return Reg;
+ }
+
+ if (!EnableCopyProp)
+ return Reg;
+
+ MachineBasicBlock *MBB = RI->getParent();
+ MachineBasicBlock::reverse_iterator E = MBB->rend();
+ MachineInstr *Def = nullptr, *Use = nullptr;
+ for (auto It = ++(RI.getReverse()); It != E; ++It) {
+ if (It->readsRegister(Reg, &TRI) && !Use)
+ Use = &*It;
+ if (It->modifiesRegister(Reg, &TRI)) {
+ Def = &*It;
+ break;
+ }
+ }
+
+ if (!Def)
+ return Reg;
+
+ auto DestSrc = TII.isCopyInstr(*Def);
+ if (!DestSrc || DestSrc->Destination->getReg() != Reg)
+ return Reg;
+
+ Register SrcReg = DestSrc->Source->getReg();
+
+ if (getRegisterSize(TRI, Reg) != getRegisterSize(TRI, SrcReg))
+ return Reg;
+
+ LLVM_DEBUG(dbgs() << "spillRegisters: perform copy propagation "
+ << printReg(Reg, &TRI) << " -> " << printReg(SrcReg, &TRI)
+ << "\n");
+
+ // Insert spill immediately after Def
+ RI = ++MachineBasicBlock::iterator(Def);
+ IsKill = DestSrc->Source->isKill();
+
+ // There are no uses of original register between COPY and STATEPOINT.
+ // There can't be any after STATEPOINT, so we can eliminate Def.
+ if (!Use) {
+ LLVM_DEBUG(dbgs() << "spillRegisters: removing dead copy " << *Def);
+ Def->eraseFromParent();
+ }
+ return SrcReg;
+}
+
namespace {
-// Pair {Register, FrameIndex}
-using RegSlotPair = std::pair<Register, int>;
-
-// Keeps track of what reloads were inserted in MBB.
-class RegReloadCache {
- using ReloadSet = SmallSet<RegSlotPair, 8>;
- DenseMap<const MachineBasicBlock *, ReloadSet> Reloads;
-
-public:
- RegReloadCache() = default;
-
- // Record reload of Reg from FI in block MBB
- void recordReload(Register Reg, int FI, const MachineBasicBlock *MBB) {
- RegSlotPair RSP(Reg, FI);
- auto Res = Reloads[MBB].insert(RSP);
- (void)Res;
- assert(Res.second && "reload already exists");
- }
-
- // Does basic block MBB contains reload of Reg from FI?
- bool hasReload(Register Reg, int FI, const MachineBasicBlock *MBB) {
- RegSlotPair RSP(Reg, FI);
- return Reloads.count(MBB) && Reloads[MBB].count(RSP);
- }
-};
-
+// Pair {Register, FrameIndex}
+using RegSlotPair = std::pair<Register, int>;
+
+// Keeps track of what reloads were inserted in MBB.
+class RegReloadCache {
+ using ReloadSet = SmallSet<RegSlotPair, 8>;
+ DenseMap<const MachineBasicBlock *, ReloadSet> Reloads;
+
+public:
+ RegReloadCache() = default;
+
+ // Record reload of Reg from FI in block MBB
+ void recordReload(Register Reg, int FI, const MachineBasicBlock *MBB) {
+ RegSlotPair RSP(Reg, FI);
+ auto Res = Reloads[MBB].insert(RSP);
+ (void)Res;
+ assert(Res.second && "reload already exists");
+ }
+
+ // Does basic block MBB contains reload of Reg from FI?
+ bool hasReload(Register Reg, int FI, const MachineBasicBlock *MBB) {
+ RegSlotPair RSP(Reg, FI);
+ return Reloads.count(MBB) && Reloads[MBB].count(RSP);
+ }
+};
+
// Cache used frame indexes during statepoint re-write to re-use them in
// processing next statepoint instruction.
// Two strategies. One is to preserve the size of spill slot while another one
@@ -214,62 +214,62 @@ private:
// size will be increased.
DenseMap<unsigned, FrameIndexesPerSize> Cache;
- // Keeps track of slots reserved for the shared landing pad processing.
- // Initialized from GlobalIndices for the current EHPad.
- SmallSet<int, 8> ReservedSlots;
-
- // Landing pad can be destination of several statepoints. Every register
- // defined by such statepoints must be spilled to the same stack slot.
- // This map keeps that information.
- DenseMap<const MachineBasicBlock *, SmallVector<RegSlotPair, 8>>
- GlobalIndices;
-
- FrameIndexesPerSize &getCacheBucket(unsigned Size) {
- // In FixupSCSExtendSlotSize mode the bucket with 0 index is used
- // for all sizes.
- return Cache[FixupSCSExtendSlotSize ? 0 : Size];
- }
-
+ // Keeps track of slots reserved for the shared landing pad processing.
+ // Initialized from GlobalIndices for the current EHPad.
+ SmallSet<int, 8> ReservedSlots;
+
+ // Landing pad can be destination of several statepoints. Every register
+ // defined by such statepoints must be spilled to the same stack slot.
+ // This map keeps that information.
+ DenseMap<const MachineBasicBlock *, SmallVector<RegSlotPair, 8>>
+ GlobalIndices;
+
+ FrameIndexesPerSize &getCacheBucket(unsigned Size) {
+ // In FixupSCSExtendSlotSize mode the bucket with 0 index is used
+ // for all sizes.
+ return Cache[FixupSCSExtendSlotSize ? 0 : Size];
+ }
+
public:
FrameIndexesCache(MachineFrameInfo &MFI, const TargetRegisterInfo &TRI)
: MFI(MFI), TRI(TRI) {}
// Reset the current state of used frame indexes. After invocation of
- // this function all frame indexes are available for allocation with
- // the exception of slots reserved for landing pad processing (if any).
- void reset(const MachineBasicBlock *EHPad) {
+ // this function all frame indexes are available for allocation with
+ // the exception of slots reserved for landing pad processing (if any).
+ void reset(const MachineBasicBlock *EHPad) {
for (auto &It : Cache)
It.second.Index = 0;
-
- ReservedSlots.clear();
- if (EHPad && GlobalIndices.count(EHPad))
- for (auto &RSP : GlobalIndices[EHPad])
- ReservedSlots.insert(RSP.second);
+
+ ReservedSlots.clear();
+ if (EHPad && GlobalIndices.count(EHPad))
+ for (auto &RSP : GlobalIndices[EHPad])
+ ReservedSlots.insert(RSP.second);
}
-
+
// Get frame index to spill the register.
- int getFrameIndex(Register Reg, MachineBasicBlock *EHPad) {
- // Check if slot for Reg is already reserved at EHPad.
- auto It = GlobalIndices.find(EHPad);
- if (It != GlobalIndices.end()) {
- auto &Vec = It->second;
- auto Idx = llvm::find_if(
- Vec, [Reg](RegSlotPair &RSP) { return Reg == RSP.first; });
- if (Idx != Vec.end()) {
- int FI = Idx->second;
- LLVM_DEBUG(dbgs() << "Found global FI " << FI << " for register "
- << printReg(Reg, &TRI) << " at "
- << printMBBReference(*EHPad) << "\n");
- assert(ReservedSlots.count(FI) && "using unreserved slot");
- return FI;
- }
- }
-
+ int getFrameIndex(Register Reg, MachineBasicBlock *EHPad) {
+ // Check if slot for Reg is already reserved at EHPad.
+ auto It = GlobalIndices.find(EHPad);
+ if (It != GlobalIndices.end()) {
+ auto &Vec = It->second;
+ auto Idx = llvm::find_if(
+ Vec, [Reg](RegSlotPair &RSP) { return Reg == RSP.first; });
+ if (Idx != Vec.end()) {
+ int FI = Idx->second;
+ LLVM_DEBUG(dbgs() << "Found global FI " << FI << " for register "
+ << printReg(Reg, &TRI) << " at "
+ << printMBBReference(*EHPad) << "\n");
+ assert(ReservedSlots.count(FI) && "using unreserved slot");
+ return FI;
+ }
+ }
+
unsigned Size = getRegisterSize(TRI, Reg);
- FrameIndexesPerSize &Line = getCacheBucket(Size);
- while (Line.Index < Line.Slots.size()) {
+ FrameIndexesPerSize &Line = getCacheBucket(Size);
+ while (Line.Index < Line.Slots.size()) {
int FI = Line.Slots[Line.Index++];
- if (ReservedSlots.count(FI))
- continue;
+ if (ReservedSlots.count(FI))
+ continue;
// If all sizes are kept together we probably need to extend the
// spill slot size.
if (MFI.getObjectSize(FI) < Size) {
@@ -283,25 +283,25 @@ public:
NumSpillSlotsAllocated++;
Line.Slots.push_back(FI);
++Line.Index;
-
- // Remember assignment {Reg, FI} for EHPad
- if (EHPad) {
- GlobalIndices[EHPad].push_back(std::make_pair(Reg, FI));
- LLVM_DEBUG(dbgs() << "Reserved FI " << FI << " for spilling reg "
- << printReg(Reg, &TRI) << " at landing pad "
- << printMBBReference(*EHPad) << "\n");
- }
-
+
+ // Remember assignment {Reg, FI} for EHPad
+ if (EHPad) {
+ GlobalIndices[EHPad].push_back(std::make_pair(Reg, FI));
+ LLVM_DEBUG(dbgs() << "Reserved FI " << FI << " for spilling reg "
+ << printReg(Reg, &TRI) << " at landing pad "
+ << printMBBReference(*EHPad) << "\n");
+ }
+
return FI;
}
-
+
// Sort all registers to spill in descendent order. In the
// FixupSCSExtendSlotSize mode it will minimize the total frame size.
// In non FixupSCSExtendSlotSize mode we can skip this step.
void sortRegisters(SmallVectorImpl<Register> &Regs) {
if (!FixupSCSExtendSlotSize)
return;
- llvm::sort(Regs, [&](Register &A, Register &B) {
+ llvm::sort(Regs, [&](Register &A, Register &B) {
return getRegisterSize(TRI, A) > getRegisterSize(TRI, B);
});
}
@@ -313,8 +313,8 @@ private:
// statepoint instruction.
MachineInstr &MI;
MachineFunction &MF;
- // If non-null then statepoint is invoke, and this points to the landing pad.
- MachineBasicBlock *EHPad;
+ // If non-null then statepoint is invoke, and this points to the landing pad.
+ MachineBasicBlock *EHPad;
const TargetRegisterInfo &TRI;
const TargetInstrInfo &TII;
MachineFrameInfo &MFI;
@@ -322,77 +322,77 @@ private:
const uint32_t *Mask;
// Cache of frame indexes used on previous instruction processing.
FrameIndexesCache &CacheFI;
- bool AllowGCPtrInCSR;
+ bool AllowGCPtrInCSR;
// Operands with physical registers requiring spilling.
SmallVector<unsigned, 8> OpsToSpill;
// Set of register to spill.
SmallVector<Register, 8> RegsToSpill;
- // Set of registers to reload after statepoint.
- SmallVector<Register, 8> RegsToReload;
+ // Set of registers to reload after statepoint.
+ SmallVector<Register, 8> RegsToReload;
// Map Register to Frame Slot index.
DenseMap<Register, int> RegToSlotIdx;
public:
StatepointState(MachineInstr &MI, const uint32_t *Mask,
- FrameIndexesCache &CacheFI, bool AllowGCPtrInCSR)
+ FrameIndexesCache &CacheFI, bool AllowGCPtrInCSR)
: MI(MI), MF(*MI.getMF()), TRI(*MF.getSubtarget().getRegisterInfo()),
TII(*MF.getSubtarget().getInstrInfo()), MFI(MF.getFrameInfo()),
- Mask(Mask), CacheFI(CacheFI), AllowGCPtrInCSR(AllowGCPtrInCSR) {
-
- // Find statepoint's landing pad, if any.
- EHPad = nullptr;
- MachineBasicBlock *MBB = MI.getParent();
- // Invoke statepoint must be last one in block.
- bool Last = std::none_of(++MI.getIterator(), MBB->end().getInstrIterator(),
- [](MachineInstr &I) {
- return I.getOpcode() == TargetOpcode::STATEPOINT;
- });
-
- if (!Last)
- return;
-
- auto IsEHPad = [](MachineBasicBlock *B) { return B->isEHPad(); };
-
- assert(llvm::count_if(MBB->successors(), IsEHPad) < 2 && "multiple EHPads");
-
- auto It = llvm::find_if(MBB->successors(), IsEHPad);
- if (It != MBB->succ_end())
- EHPad = *It;
- }
-
- MachineBasicBlock *getEHPad() const { return EHPad; }
-
+ Mask(Mask), CacheFI(CacheFI), AllowGCPtrInCSR(AllowGCPtrInCSR) {
+
+ // Find statepoint's landing pad, if any.
+ EHPad = nullptr;
+ MachineBasicBlock *MBB = MI.getParent();
+ // Invoke statepoint must be last one in block.
+ bool Last = std::none_of(++MI.getIterator(), MBB->end().getInstrIterator(),
+ [](MachineInstr &I) {
+ return I.getOpcode() == TargetOpcode::STATEPOINT;
+ });
+
+ if (!Last)
+ return;
+
+ auto IsEHPad = [](MachineBasicBlock *B) { return B->isEHPad(); };
+
+ assert(llvm::count_if(MBB->successors(), IsEHPad) < 2 && "multiple EHPads");
+
+ auto It = llvm::find_if(MBB->successors(), IsEHPad);
+ if (It != MBB->succ_end())
+ EHPad = *It;
+ }
+
+ MachineBasicBlock *getEHPad() const { return EHPad; }
+
// Return true if register is callee saved.
bool isCalleeSaved(Register Reg) { return (Mask[Reg / 32] >> Reg % 32) & 1; }
-
+
// Iterates over statepoint meta args to find caller saver registers.
// Also cache the size of found registers.
// Returns true if caller save registers found.
bool findRegistersToSpill() {
- SmallSet<Register, 8> GCRegs;
- // All GC pointer operands assigned to registers produce new value.
- // Since they're tied to their defs, it is enough to collect def registers.
- for (const auto &Def : MI.defs())
- GCRegs.insert(Def.getReg());
-
+ SmallSet<Register, 8> GCRegs;
+ // All GC pointer operands assigned to registers produce new value.
+ // Since they're tied to their defs, it is enough to collect def registers.
+ for (const auto &Def : MI.defs())
+ GCRegs.insert(Def.getReg());
+
SmallSet<Register, 8> VisitedRegs;
for (unsigned Idx = StatepointOpers(&MI).getVarIdx(),
EndIdx = MI.getNumOperands();
Idx < EndIdx; ++Idx) {
MachineOperand &MO = MI.getOperand(Idx);
- // Leave `undef` operands as is, StackMaps will rewrite them
- // into a constant.
- if (!MO.isReg() || MO.isImplicit() || MO.isUndef())
+ // Leave `undef` operands as is, StackMaps will rewrite them
+ // into a constant.
+ if (!MO.isReg() || MO.isImplicit() || MO.isUndef())
continue;
Register Reg = MO.getReg();
assert(Reg.isPhysical() && "Only physical regs are expected");
-
- if (isCalleeSaved(Reg) && (AllowGCPtrInCSR || !is_contained(GCRegs, Reg)))
+
+ if (isCalleeSaved(Reg) && (AllowGCPtrInCSR || !is_contained(GCRegs, Reg)))
continue;
-
- LLVM_DEBUG(dbgs() << "Will spill " << printReg(Reg, &TRI) << " at index "
- << Idx << "\n");
-
+
+ LLVM_DEBUG(dbgs() << "Will spill " << printReg(Reg, &TRI) << " at index "
+ << Idx << "\n");
+
if (VisitedRegs.insert(Reg).second)
RegsToSpill.push_back(Reg);
OpsToSpill.push_back(Idx);
@@ -400,109 +400,109 @@ public:
CacheFI.sortRegisters(RegsToSpill);
return !RegsToSpill.empty();
}
-
+
// Spill all caller saved registers right before statepoint instruction.
// Remember frame index where register is spilled.
void spillRegisters() {
for (Register Reg : RegsToSpill) {
- int FI = CacheFI.getFrameIndex(Reg, EHPad);
+ int FI = CacheFI.getFrameIndex(Reg, EHPad);
const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg);
-
+
NumSpilledRegisters++;
RegToSlotIdx[Reg] = FI;
-
- LLVM_DEBUG(dbgs() << "Spilling " << printReg(Reg, &TRI) << " to FI " << FI
- << "\n");
-
- // Perform trivial copy propagation
- bool IsKill = true;
- MachineBasicBlock::iterator InsertBefore(MI);
- Reg = performCopyPropagation(Reg, InsertBefore, IsKill, TII, TRI);
-
- LLVM_DEBUG(dbgs() << "Insert spill before " << *InsertBefore);
- TII.storeRegToStackSlot(*MI.getParent(), InsertBefore, Reg, IsKill, FI,
- RC, &TRI);
+
+ LLVM_DEBUG(dbgs() << "Spilling " << printReg(Reg, &TRI) << " to FI " << FI
+ << "\n");
+
+ // Perform trivial copy propagation
+ bool IsKill = true;
+ MachineBasicBlock::iterator InsertBefore(MI);
+ Reg = performCopyPropagation(Reg, InsertBefore, IsKill, TII, TRI);
+
+ LLVM_DEBUG(dbgs() << "Insert spill before " << *InsertBefore);
+ TII.storeRegToStackSlot(*MI.getParent(), InsertBefore, Reg, IsKill, FI,
+ RC, &TRI);
}
}
-
- void insertReloadBefore(unsigned Reg, MachineBasicBlock::iterator It,
- MachineBasicBlock *MBB) {
- const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg);
- int FI = RegToSlotIdx[Reg];
- if (It != MBB->end()) {
- TII.loadRegFromStackSlot(*MBB, It, Reg, FI, RC, &TRI);
- return;
- }
-
- // To insert reload at the end of MBB, insert it before last instruction
- // and then swap them.
- assert(!MBB->empty() && "Empty block");
- --It;
- TII.loadRegFromStackSlot(*MBB, It, Reg, FI, RC, &TRI);
- MachineInstr *Reload = It->getPrevNode();
- int Dummy = 0;
- (void)Dummy;
- assert(TII.isLoadFromStackSlot(*Reload, Dummy) == Reg);
- assert(Dummy == FI);
- MBB->remove(Reload);
- MBB->insertAfter(It, Reload);
- }
-
- // Insert reloads of (relocated) registers spilled in statepoint.
- void insertReloads(MachineInstr *NewStatepoint, RegReloadCache &RC) {
- MachineBasicBlock *MBB = NewStatepoint->getParent();
- auto InsertPoint = std::next(NewStatepoint->getIterator());
-
- for (auto Reg : RegsToReload) {
- insertReloadBefore(Reg, InsertPoint, MBB);
- LLVM_DEBUG(dbgs() << "Reloading " << printReg(Reg, &TRI) << " from FI "
- << RegToSlotIdx[Reg] << " after statepoint\n");
-
- if (EHPad && !RC.hasReload(Reg, RegToSlotIdx[Reg], EHPad)) {
- RC.recordReload(Reg, RegToSlotIdx[Reg], EHPad);
- auto EHPadInsertPoint = EHPad->SkipPHIsLabelsAndDebug(EHPad->begin());
- insertReloadBefore(Reg, EHPadInsertPoint, EHPad);
- LLVM_DEBUG(dbgs() << "...also reload at EHPad "
- << printMBBReference(*EHPad) << "\n");
- }
- }
- }
-
+
+ void insertReloadBefore(unsigned Reg, MachineBasicBlock::iterator It,
+ MachineBasicBlock *MBB) {
+ const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg);
+ int FI = RegToSlotIdx[Reg];
+ if (It != MBB->end()) {
+ TII.loadRegFromStackSlot(*MBB, It, Reg, FI, RC, &TRI);
+ return;
+ }
+
+ // To insert reload at the end of MBB, insert it before last instruction
+ // and then swap them.
+ assert(!MBB->empty() && "Empty block");
+ --It;
+ TII.loadRegFromStackSlot(*MBB, It, Reg, FI, RC, &TRI);
+ MachineInstr *Reload = It->getPrevNode();
+ int Dummy = 0;
+ (void)Dummy;
+ assert(TII.isLoadFromStackSlot(*Reload, Dummy) == Reg);
+ assert(Dummy == FI);
+ MBB->remove(Reload);
+ MBB->insertAfter(It, Reload);
+ }
+
+ // Insert reloads of (relocated) registers spilled in statepoint.
+ void insertReloads(MachineInstr *NewStatepoint, RegReloadCache &RC) {
+ MachineBasicBlock *MBB = NewStatepoint->getParent();
+ auto InsertPoint = std::next(NewStatepoint->getIterator());
+
+ for (auto Reg : RegsToReload) {
+ insertReloadBefore(Reg, InsertPoint, MBB);
+ LLVM_DEBUG(dbgs() << "Reloading " << printReg(Reg, &TRI) << " from FI "
+ << RegToSlotIdx[Reg] << " after statepoint\n");
+
+ if (EHPad && !RC.hasReload(Reg, RegToSlotIdx[Reg], EHPad)) {
+ RC.recordReload(Reg, RegToSlotIdx[Reg], EHPad);
+ auto EHPadInsertPoint = EHPad->SkipPHIsLabelsAndDebug(EHPad->begin());
+ insertReloadBefore(Reg, EHPadInsertPoint, EHPad);
+ LLVM_DEBUG(dbgs() << "...also reload at EHPad "
+ << printMBBReference(*EHPad) << "\n");
+ }
+ }
+ }
+
// Re-write statepoint machine instruction to replace caller saved operands
// with indirect memory location (frame index).
- MachineInstr *rewriteStatepoint() {
+ MachineInstr *rewriteStatepoint() {
MachineInstr *NewMI =
MF.CreateMachineInstr(TII.get(MI.getOpcode()), MI.getDebugLoc(), true);
MachineInstrBuilder MIB(MF, NewMI);
- unsigned NumOps = MI.getNumOperands();
-
- // New indices for the remaining defs.
- SmallVector<unsigned, 8> NewIndices;
- unsigned NumDefs = MI.getNumDefs();
- for (unsigned I = 0; I < NumDefs; ++I) {
- MachineOperand &DefMO = MI.getOperand(I);
- assert(DefMO.isReg() && DefMO.isDef() && "Expected Reg Def operand");
- Register Reg = DefMO.getReg();
- if (!AllowGCPtrInCSR) {
- assert(is_contained(RegsToSpill, Reg));
- RegsToReload.push_back(Reg);
- } else {
- if (isCalleeSaved(Reg)) {
- NewIndices.push_back(NewMI->getNumOperands());
- MIB.addReg(Reg, RegState::Define);
- } else {
- NewIndices.push_back(NumOps);
- RegsToReload.push_back(Reg);
- }
- }
- }
-
+ unsigned NumOps = MI.getNumOperands();
+
+ // New indices for the remaining defs.
+ SmallVector<unsigned, 8> NewIndices;
+ unsigned NumDefs = MI.getNumDefs();
+ for (unsigned I = 0; I < NumDefs; ++I) {
+ MachineOperand &DefMO = MI.getOperand(I);
+ assert(DefMO.isReg() && DefMO.isDef() && "Expected Reg Def operand");
+ Register Reg = DefMO.getReg();
+ if (!AllowGCPtrInCSR) {
+ assert(is_contained(RegsToSpill, Reg));
+ RegsToReload.push_back(Reg);
+ } else {
+ if (isCalleeSaved(Reg)) {
+ NewIndices.push_back(NewMI->getNumOperands());
+ MIB.addReg(Reg, RegState::Define);
+ } else {
+ NewIndices.push_back(NumOps);
+ RegsToReload.push_back(Reg);
+ }
+ }
+ }
+
// Add End marker.
OpsToSpill.push_back(MI.getNumOperands());
unsigned CurOpIdx = 0;
- for (unsigned I = NumDefs; I < MI.getNumOperands(); ++I) {
+ for (unsigned I = NumDefs; I < MI.getNumOperands(); ++I) {
MachineOperand &MO = MI.getOperand(I);
if (I == OpsToSpill[CurOpIdx]) {
int FI = RegToSlotIdx[MO.getReg()];
@@ -513,38 +513,38 @@ public:
MIB.addFrameIndex(FI);
MIB.addImm(0);
++CurOpIdx;
- } else {
+ } else {
MIB.add(MO);
- unsigned OldDef;
- if (AllowGCPtrInCSR && MI.isRegTiedToDefOperand(I, &OldDef)) {
- assert(OldDef < NumDefs);
- assert(NewIndices[OldDef] < NumOps);
- MIB->tieOperands(NewIndices[OldDef], MIB->getNumOperands() - 1);
- }
- }
+ unsigned OldDef;
+ if (AllowGCPtrInCSR && MI.isRegTiedToDefOperand(I, &OldDef)) {
+ assert(OldDef < NumDefs);
+ assert(NewIndices[OldDef] < NumOps);
+ MIB->tieOperands(NewIndices[OldDef], MIB->getNumOperands() - 1);
+ }
+ }
}
assert(CurOpIdx == (OpsToSpill.size() - 1) && "Not all operands processed");
// Add mem operands.
NewMI->setMemRefs(MF, MI.memoperands());
for (auto It : RegToSlotIdx) {
- Register R = It.first;
+ Register R = It.first;
int FrameIndex = It.second;
auto PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex);
- MachineMemOperand::Flags Flags = MachineMemOperand::MOLoad;
- if (is_contained(RegsToReload, R))
- Flags |= MachineMemOperand::MOStore;
- auto *MMO =
- MF.getMachineMemOperand(PtrInfo, Flags, getRegisterSize(TRI, R),
- MFI.getObjectAlign(FrameIndex));
+ MachineMemOperand::Flags Flags = MachineMemOperand::MOLoad;
+ if (is_contained(RegsToReload, R))
+ Flags |= MachineMemOperand::MOStore;
+ auto *MMO =
+ MF.getMachineMemOperand(PtrInfo, Flags, getRegisterSize(TRI, R),
+ MFI.getObjectAlign(FrameIndex));
NewMI->addMemOperand(MF, MMO);
}
-
+
// Insert new statepoint and erase old one.
MI.getParent()->insert(MI, NewMI);
-
- LLVM_DEBUG(dbgs() << "rewritten statepoint to : " << *NewMI << "\n");
+
+ LLVM_DEBUG(dbgs() << "rewritten statepoint to : " << *NewMI << "\n");
MI.eraseFromParent();
- return NewMI;
+ return NewMI;
}
};
@@ -553,33 +553,33 @@ private:
MachineFunction &MF;
const TargetRegisterInfo &TRI;
FrameIndexesCache CacheFI;
- RegReloadCache ReloadCache;
+ RegReloadCache ReloadCache;
public:
StatepointProcessor(MachineFunction &MF)
: MF(MF), TRI(*MF.getSubtarget().getRegisterInfo()),
CacheFI(MF.getFrameInfo(), TRI) {}
- bool process(MachineInstr &MI, bool AllowGCPtrInCSR) {
+ bool process(MachineInstr &MI, bool AllowGCPtrInCSR) {
StatepointOpers SO(&MI);
uint64_t Flags = SO.getFlags();
// Do nothing for LiveIn, it supports all registers.
if (Flags & (uint64_t)StatepointFlags::DeoptLiveIn)
return false;
- LLVM_DEBUG(dbgs() << "\nMBB " << MI.getParent()->getNumber() << " "
- << MI.getParent()->getName() << " : process statepoint "
- << MI);
+ LLVM_DEBUG(dbgs() << "\nMBB " << MI.getParent()->getNumber() << " "
+ << MI.getParent()->getName() << " : process statepoint "
+ << MI);
CallingConv::ID CC = SO.getCallingConv();
const uint32_t *Mask = TRI.getCallPreservedMask(MF, CC);
- StatepointState SS(MI, Mask, CacheFI, AllowGCPtrInCSR);
- CacheFI.reset(SS.getEHPad());
+ StatepointState SS(MI, Mask, CacheFI, AllowGCPtrInCSR);
+ CacheFI.reset(SS.getEHPad());
if (!SS.findRegistersToSpill())
return false;
SS.spillRegisters();
- auto *NewStatepoint = SS.rewriteStatepoint();
- SS.insertReloads(NewStatepoint, ReloadCache);
+ auto *NewStatepoint = SS.rewriteStatepoint();
+ SS.insertReloads(NewStatepoint, ReloadCache);
return true;
}
};
@@ -604,14 +604,14 @@ bool FixupStatepointCallerSaved::runOnMachineFunction(MachineFunction &MF) {
bool Changed = false;
StatepointProcessor SPP(MF);
- unsigned NumStatepoints = 0;
- bool AllowGCPtrInCSR = PassGCPtrInCSR;
- for (MachineInstr *I : Statepoints) {
- ++NumStatepoints;
- if (MaxStatepointsWithRegs.getNumOccurrences() &&
- NumStatepoints >= MaxStatepointsWithRegs)
- AllowGCPtrInCSR = false;
- Changed |= SPP.process(*I, AllowGCPtrInCSR);
- }
+ unsigned NumStatepoints = 0;
+ bool AllowGCPtrInCSR = PassGCPtrInCSR;
+ for (MachineInstr *I : Statepoints) {
+ ++NumStatepoints;
+ if (MaxStatepointsWithRegs.getNumOccurrences() &&
+ NumStatepoints >= MaxStatepointsWithRegs)
+ AllowGCPtrInCSR = false;
+ Changed |= SPP.process(*I, AllowGCPtrInCSR);
+ }
return Changed;
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/GCRootLowering.cpp b/contrib/libs/llvm12/lib/CodeGen/GCRootLowering.cpp
index af0e70fcf6..e2ee0c97f9 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GCRootLowering.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GCRootLowering.cpp
@@ -296,10 +296,10 @@ void GCMachineCodeAnalysis::FindStackOffsets(MachineFunction &MF) {
} else {
Register FrameReg; // FIXME: surely GCRoot ought to store the
// register that the offset is from?
- auto FrameOffset = TFI->getFrameIndexReference(MF, RI->Num, FrameReg);
- assert(!FrameOffset.getScalable() &&
- "Frame offsets with a scalable component are not supported");
- RI->StackOffset = FrameOffset.getFixed();
+ auto FrameOffset = TFI->getFrameIndexReference(MF, RI->Num, FrameReg);
+ assert(!FrameOffset.getScalable() &&
+ "Frame offsets with a scalable component are not supported");
+ RI->StackOffset = FrameOffset.getFixed();
++RI;
}
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/CSEInfo.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/CSEInfo.cpp
index 24391970d6..2fa208fbfa 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/CSEInfo.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/CSEInfo.cpp
@@ -59,7 +59,7 @@ bool CSEConfigFull::shouldCSEOpc(unsigned Opc) {
case TargetOpcode::G_UNMERGE_VALUES:
case TargetOpcode::G_TRUNC:
case TargetOpcode::G_PTR_ADD:
- case TargetOpcode::G_EXTRACT:
+ case TargetOpcode::G_EXTRACT:
return true;
}
return false;
@@ -367,21 +367,21 @@ GISelInstProfileBuilder::addNodeIDFlag(unsigned Flag) const {
return *this;
}
-const GISelInstProfileBuilder &
-GISelInstProfileBuilder::addNodeIDReg(Register Reg) const {
- LLT Ty = MRI.getType(Reg);
- if (Ty.isValid())
- addNodeIDRegType(Ty);
-
- if (const RegClassOrRegBank &RCOrRB = MRI.getRegClassOrRegBank(Reg)) {
- if (const auto *RB = RCOrRB.dyn_cast<const RegisterBank *>())
- addNodeIDRegType(RB);
- else if (const auto *RC = RCOrRB.dyn_cast<const TargetRegisterClass *>())
- addNodeIDRegType(RC);
- }
- return *this;
-}
-
+const GISelInstProfileBuilder &
+GISelInstProfileBuilder::addNodeIDReg(Register Reg) const {
+ LLT Ty = MRI.getType(Reg);
+ if (Ty.isValid())
+ addNodeIDRegType(Ty);
+
+ if (const RegClassOrRegBank &RCOrRB = MRI.getRegClassOrRegBank(Reg)) {
+ if (const auto *RB = RCOrRB.dyn_cast<const RegisterBank *>())
+ addNodeIDRegType(RB);
+ else if (const auto *RC = RCOrRB.dyn_cast<const TargetRegisterClass *>())
+ addNodeIDRegType(RC);
+ }
+ return *this;
+}
+
const GISelInstProfileBuilder &GISelInstProfileBuilder::addNodeIDMachineOperand(
const MachineOperand &MO) const {
if (MO.isReg()) {
@@ -389,8 +389,8 @@ const GISelInstProfileBuilder &GISelInstProfileBuilder::addNodeIDMachineOperand(
if (!MO.isDef())
addNodeIDRegNum(Reg);
- // Profile the register properties.
- addNodeIDReg(Reg);
+ // Profile the register properties.
+ addNodeIDReg(Reg);
assert(!MO.isImplicit() && "Unhandled case");
} else if (MO.isImm())
ID.AddInteger(MO.getImm());
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/CSEMIRBuilder.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/CSEMIRBuilder.cpp
index b0f8a6610d..2c86f06a60 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/CSEMIRBuilder.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/CSEMIRBuilder.cpp
@@ -13,7 +13,7 @@
#include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
-#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DebugInfoMetadata.h"
using namespace llvm;
@@ -42,14 +42,14 @@ CSEMIRBuilder::getDominatingInstrForID(FoldingSetNodeID &ID,
if (MI) {
CSEInfo->countOpcodeHit(MI->getOpcode());
auto CurrPos = getInsertPt();
- auto MII = MachineBasicBlock::iterator(MI);
- if (MII == CurrPos) {
- // Move the insert point ahead of the instruction so any future uses of
- // this builder will have the def ready.
- setInsertPt(*CurMBB, std::next(MII));
- } else if (!dominates(MI, CurrPos)) {
+ auto MII = MachineBasicBlock::iterator(MI);
+ if (MII == CurrPos) {
+ // Move the insert point ahead of the instruction so any future uses of
+ // this builder will have the def ready.
+ setInsertPt(*CurMBB, std::next(MII));
+ } else if (!dominates(MI, CurrPos)) {
CurMBB->splice(CurrPos, CurMBB, MI);
- }
+ }
return MachineInstrBuilder(getMF(), MI);
}
return MachineInstrBuilder();
@@ -68,11 +68,11 @@ void CSEMIRBuilder::profileDstOp(const DstOp &Op,
case DstOp::DstType::Ty_RC:
B.addNodeIDRegType(Op.getRegClass());
break;
- case DstOp::DstType::Ty_Reg: {
- // Regs can have LLT&(RB|RC). If those exist, profile them as well.
- B.addNodeIDReg(Op.getReg());
- break;
- }
+ case DstOp::DstType::Ty_Reg: {
+ // Regs can have LLT&(RB|RC). If those exist, profile them as well.
+ B.addNodeIDReg(Op.getReg());
+ break;
+ }
default:
B.addNodeIDRegType(Op.getLLTTy(*getMRI()));
break;
@@ -82,9 +82,9 @@ void CSEMIRBuilder::profileDstOp(const DstOp &Op,
void CSEMIRBuilder::profileSrcOp(const SrcOp &Op,
GISelInstProfileBuilder &B) const {
switch (Op.getSrcOpKind()) {
- case SrcOp::SrcType::Ty_Imm:
- B.addNodeIDImmediate(static_cast<int64_t>(Op.getImm()));
- break;
+ case SrcOp::SrcType::Ty_Imm:
+ B.addNodeIDImmediate(static_cast<int64_t>(Op.getImm()));
+ break;
case SrcOp::SrcType::Ty_Predicate:
B.addNodeIDImmediate(static_cast<int64_t>(Op.getPredicate()));
break;
@@ -130,7 +130,7 @@ bool CSEMIRBuilder::checkCopyToDefsPossible(ArrayRef<DstOp> DstOps) {
if (DstOps.size() == 1)
return true; // always possible to emit copy to just 1 vreg.
- return llvm::all_of(DstOps, [](const DstOp &Op) {
+ return llvm::all_of(DstOps, [](const DstOp &Op) {
DstOp::DstType DT = Op.getDstOpKind();
return DT == DstOp::DstType::Ty_LLT || DT == DstOp::DstType::Ty_RC;
});
@@ -146,21 +146,21 @@ CSEMIRBuilder::generateCopiesIfRequired(ArrayRef<DstOp> DstOps,
if (Op.getDstOpKind() == DstOp::DstType::Ty_Reg)
return buildCopy(Op.getReg(), MIB.getReg(0));
}
-
- // If we didn't generate a copy then we're re-using an existing node directly
- // instead of emitting any code. Merge the debug location we wanted to emit
- // into the instruction we're CSE'ing with. Debug locations arent part of the
- // profile so we don't need to recompute it.
- if (getDebugLoc()) {
- GISelChangeObserver *Observer = getState().Observer;
- if (Observer)
- Observer->changingInstr(*MIB);
- MIB->setDebugLoc(
- DILocation::getMergedLocation(MIB->getDebugLoc(), getDebugLoc()));
- if (Observer)
- Observer->changedInstr(*MIB);
- }
-
+
+ // If we didn't generate a copy then we're re-using an existing node directly
+ // instead of emitting any code. Merge the debug location we wanted to emit
+ // into the instruction we're CSE'ing with. Debug locations arent part of the
+ // profile so we don't need to recompute it.
+ if (getDebugLoc()) {
+ GISelChangeObserver *Observer = getState().Observer;
+ if (Observer)
+ Observer->changingInstr(*MIB);
+ MIB->setDebugLoc(
+ DILocation::getMergedLocation(MIB->getDebugLoc(), getDebugLoc()));
+ if (Observer)
+ Observer->changedInstr(*MIB);
+ }
+
return MIB;
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/CallLowering.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/CallLowering.cpp
index ad7c789b2e..803e1527a4 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/CallLowering.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/CallLowering.cpp
@@ -30,51 +30,51 @@ using namespace llvm;
void CallLowering::anchor() {}
-/// Helper function which updates \p Flags when \p AttrFn returns true.
-static void
-addFlagsUsingAttrFn(ISD::ArgFlagsTy &Flags,
- const std::function<bool(Attribute::AttrKind)> &AttrFn) {
- if (AttrFn(Attribute::SExt))
- Flags.setSExt();
- if (AttrFn(Attribute::ZExt))
- Flags.setZExt();
- if (AttrFn(Attribute::InReg))
- Flags.setInReg();
- if (AttrFn(Attribute::StructRet))
- Flags.setSRet();
- if (AttrFn(Attribute::Nest))
- Flags.setNest();
- if (AttrFn(Attribute::ByVal))
- Flags.setByVal();
- if (AttrFn(Attribute::Preallocated))
- Flags.setPreallocated();
- if (AttrFn(Attribute::InAlloca))
- Flags.setInAlloca();
- if (AttrFn(Attribute::Returned))
- Flags.setReturned();
- if (AttrFn(Attribute::SwiftSelf))
- Flags.setSwiftSelf();
- if (AttrFn(Attribute::SwiftError))
- Flags.setSwiftError();
-}
-
-ISD::ArgFlagsTy CallLowering::getAttributesForArgIdx(const CallBase &Call,
- unsigned ArgIdx) const {
- ISD::ArgFlagsTy Flags;
- addFlagsUsingAttrFn(Flags, [&Call, &ArgIdx](Attribute::AttrKind Attr) {
- return Call.paramHasAttr(ArgIdx, Attr);
- });
- return Flags;
-}
-
-void CallLowering::addArgFlagsFromAttributes(ISD::ArgFlagsTy &Flags,
- const AttributeList &Attrs,
- unsigned OpIdx) const {
- addFlagsUsingAttrFn(Flags, [&Attrs, &OpIdx](Attribute::AttrKind Attr) {
- return Attrs.hasAttribute(OpIdx, Attr);
- });
-}
-
+/// Helper function which updates \p Flags when \p AttrFn returns true.
+static void
+addFlagsUsingAttrFn(ISD::ArgFlagsTy &Flags,
+ const std::function<bool(Attribute::AttrKind)> &AttrFn) {
+ if (AttrFn(Attribute::SExt))
+ Flags.setSExt();
+ if (AttrFn(Attribute::ZExt))
+ Flags.setZExt();
+ if (AttrFn(Attribute::InReg))
+ Flags.setInReg();
+ if (AttrFn(Attribute::StructRet))
+ Flags.setSRet();
+ if (AttrFn(Attribute::Nest))
+ Flags.setNest();
+ if (AttrFn(Attribute::ByVal))
+ Flags.setByVal();
+ if (AttrFn(Attribute::Preallocated))
+ Flags.setPreallocated();
+ if (AttrFn(Attribute::InAlloca))
+ Flags.setInAlloca();
+ if (AttrFn(Attribute::Returned))
+ Flags.setReturned();
+ if (AttrFn(Attribute::SwiftSelf))
+ Flags.setSwiftSelf();
+ if (AttrFn(Attribute::SwiftError))
+ Flags.setSwiftError();
+}
+
+ISD::ArgFlagsTy CallLowering::getAttributesForArgIdx(const CallBase &Call,
+ unsigned ArgIdx) const {
+ ISD::ArgFlagsTy Flags;
+ addFlagsUsingAttrFn(Flags, [&Call, &ArgIdx](Attribute::AttrKind Attr) {
+ return Call.paramHasAttr(ArgIdx, Attr);
+ });
+ return Flags;
+}
+
+void CallLowering::addArgFlagsFromAttributes(ISD::ArgFlagsTy &Flags,
+ const AttributeList &Attrs,
+ unsigned OpIdx) const {
+ addFlagsUsingAttrFn(Flags, [&Attrs, &OpIdx](Attribute::AttrKind Attr) {
+ return Attrs.hasAttribute(OpIdx, Attr);
+ });
+}
+
bool CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, const CallBase &CB,
ArrayRef<Register> ResRegs,
ArrayRef<ArrayRef<Register>> ArgRegs,
@@ -82,45 +82,45 @@ bool CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, const CallBase &CB,
std::function<unsigned()> GetCalleeReg) const {
CallLoweringInfo Info;
const DataLayout &DL = MIRBuilder.getDataLayout();
- MachineFunction &MF = MIRBuilder.getMF();
- bool CanBeTailCalled = CB.isTailCall() &&
- isInTailCallPosition(CB, MF.getTarget()) &&
- (MF.getFunction()
- .getFnAttribute("disable-tail-calls")
- .getValueAsString() != "true");
-
- CallingConv::ID CallConv = CB.getCallingConv();
- Type *RetTy = CB.getType();
- bool IsVarArg = CB.getFunctionType()->isVarArg();
-
- SmallVector<BaseArgInfo, 4> SplitArgs;
- getReturnInfo(CallConv, RetTy, CB.getAttributes(), SplitArgs, DL);
- Info.CanLowerReturn = canLowerReturn(MF, CallConv, SplitArgs, IsVarArg);
-
- if (!Info.CanLowerReturn) {
- // Callee requires sret demotion.
- insertSRetOutgoingArgument(MIRBuilder, CB, Info);
-
- // The sret demotion isn't compatible with tail-calls, since the sret
- // argument points into the caller's stack frame.
- CanBeTailCalled = false;
- }
-
+ MachineFunction &MF = MIRBuilder.getMF();
+ bool CanBeTailCalled = CB.isTailCall() &&
+ isInTailCallPosition(CB, MF.getTarget()) &&
+ (MF.getFunction()
+ .getFnAttribute("disable-tail-calls")
+ .getValueAsString() != "true");
+
+ CallingConv::ID CallConv = CB.getCallingConv();
+ Type *RetTy = CB.getType();
+ bool IsVarArg = CB.getFunctionType()->isVarArg();
+
+ SmallVector<BaseArgInfo, 4> SplitArgs;
+ getReturnInfo(CallConv, RetTy, CB.getAttributes(), SplitArgs, DL);
+ Info.CanLowerReturn = canLowerReturn(MF, CallConv, SplitArgs, IsVarArg);
+
+ if (!Info.CanLowerReturn) {
+ // Callee requires sret demotion.
+ insertSRetOutgoingArgument(MIRBuilder, CB, Info);
+
+ // The sret demotion isn't compatible with tail-calls, since the sret
+ // argument points into the caller's stack frame.
+ CanBeTailCalled = false;
+ }
+
// First step is to marshall all the function's parameters into the correct
// physregs and memory locations. Gather the sequence of argument types that
// we'll pass to the assigner function.
unsigned i = 0;
unsigned NumFixedArgs = CB.getFunctionType()->getNumParams();
for (auto &Arg : CB.args()) {
- ArgInfo OrigArg{ArgRegs[i], Arg->getType(), getAttributesForArgIdx(CB, i),
+ ArgInfo OrigArg{ArgRegs[i], Arg->getType(), getAttributesForArgIdx(CB, i),
i < NumFixedArgs};
setArgFlags(OrigArg, i + AttributeList::FirstArgIndex, DL, CB);
-
- // If we have an explicit sret argument that is an Instruction, (i.e., it
- // might point to function-local memory), we can't meaningfully tail-call.
- if (OrigArg.Flags[0].isSRet() && isa<Instruction>(&Arg))
- CanBeTailCalled = false;
-
+
+ // If we have an explicit sret argument that is an Instruction, (i.e., it
+ // might point to function-local memory), we can't meaningfully tail-call.
+ if (OrigArg.Flags[0].isSRet() && isa<Instruction>(&Arg))
+ CanBeTailCalled = false;
+
Info.OrigArgs.push_back(OrigArg);
++i;
}
@@ -133,16 +133,16 @@ bool CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, const CallBase &CB,
else
Info.Callee = MachineOperand::CreateReg(GetCalleeReg(), false);
- Info.OrigRet = ArgInfo{ResRegs, RetTy, ISD::ArgFlagsTy{}};
+ Info.OrigRet = ArgInfo{ResRegs, RetTy, ISD::ArgFlagsTy{}};
if (!Info.OrigRet.Ty->isVoidTy())
setArgFlags(Info.OrigRet, AttributeList::ReturnIndex, DL, CB);
Info.KnownCallees = CB.getMetadata(LLVMContext::MD_callees);
- Info.CallConv = CallConv;
+ Info.CallConv = CallConv;
Info.SwiftErrorVReg = SwiftErrorVReg;
Info.IsMustTailCall = CB.isMustTailCall();
- Info.IsTailCall = CanBeTailCalled;
- Info.IsVarArg = IsVarArg;
+ Info.IsTailCall = CanBeTailCalled;
+ Info.IsVarArg = IsVarArg;
return lowerCall(MIRBuilder, Info);
}
@@ -152,7 +152,7 @@ void CallLowering::setArgFlags(CallLowering::ArgInfo &Arg, unsigned OpIdx,
const FuncInfoTy &FuncInfo) const {
auto &Flags = Arg.Flags[0];
const AttributeList &Attrs = FuncInfo.getAttributes();
- addArgFlagsFromAttributes(Flags, Attrs, OpIdx);
+ addArgFlagsFromAttributes(Flags, Attrs, OpIdx);
if (Flags.isByVal() || Flags.isInAlloca() || Flags.isPreallocated()) {
Type *ElementTy = cast<PointerType>(Arg.Ty)->getElementType();
@@ -245,97 +245,97 @@ bool CallLowering::handleAssignments(CCState &CCInfo,
unsigned NumArgs = Args.size();
for (unsigned i = 0; i != NumArgs; ++i) {
EVT CurVT = EVT::getEVT(Args[i].Ty);
- if (CurVT.isSimple() &&
- !Handler.assignArg(i, CurVT.getSimpleVT(), CurVT.getSimpleVT(),
- CCValAssign::Full, Args[i], Args[i].Flags[0],
- CCInfo))
- continue;
-
- MVT NewVT = TLI->getRegisterTypeForCallingConv(
- F.getContext(), F.getCallingConv(), EVT(CurVT));
-
- // If we need to split the type over multiple regs, check it's a scenario
- // we currently support.
- unsigned NumParts = TLI->getNumRegistersForCallingConv(
- F.getContext(), F.getCallingConv(), CurVT);
-
- if (NumParts == 1) {
- // Try to use the register type if we couldn't assign the VT.
- if (Handler.assignArg(i, NewVT, NewVT, CCValAssign::Full, Args[i],
- Args[i].Flags[0], CCInfo))
- return false;
- continue;
- }
-
- assert(NumParts > 1);
- // For now only handle exact splits.
- if (NewVT.getSizeInBits() * NumParts != CurVT.getSizeInBits())
- return false;
-
- // For incoming arguments (physregs to vregs), we could have values in
- // physregs (or memlocs) which we want to extract and copy to vregs.
- // During this, we might have to deal with the LLT being split across
- // multiple regs, so we have to record this information for later.
- //
- // If we have outgoing args, then we have the opposite case. We have a
- // vreg with an LLT which we want to assign to a physical location, and
- // we might have to record that the value has to be split later.
- if (Handler.isIncomingArgumentHandler()) {
- // We're handling an incoming arg which is split over multiple regs.
- // E.g. passing an s128 on AArch64.
- ISD::ArgFlagsTy OrigFlags = Args[i].Flags[0];
- Args[i].OrigRegs.push_back(Args[i].Regs[0]);
- Args[i].Regs.clear();
- Args[i].Flags.clear();
- LLT NewLLT = getLLTForMVT(NewVT);
- // For each split register, create and assign a vreg that will store
- // the incoming component of the larger value. These will later be
- // merged to form the final vreg.
- for (unsigned Part = 0; Part < NumParts; ++Part) {
- Register Reg =
- MIRBuilder.getMRI()->createGenericVirtualRegister(NewLLT);
- ISD::ArgFlagsTy Flags = OrigFlags;
- if (Part == 0) {
- Flags.setSplit();
+ if (CurVT.isSimple() &&
+ !Handler.assignArg(i, CurVT.getSimpleVT(), CurVT.getSimpleVT(),
+ CCValAssign::Full, Args[i], Args[i].Flags[0],
+ CCInfo))
+ continue;
+
+ MVT NewVT = TLI->getRegisterTypeForCallingConv(
+ F.getContext(), F.getCallingConv(), EVT(CurVT));
+
+ // If we need to split the type over multiple regs, check it's a scenario
+ // we currently support.
+ unsigned NumParts = TLI->getNumRegistersForCallingConv(
+ F.getContext(), F.getCallingConv(), CurVT);
+
+ if (NumParts == 1) {
+ // Try to use the register type if we couldn't assign the VT.
+ if (Handler.assignArg(i, NewVT, NewVT, CCValAssign::Full, Args[i],
+ Args[i].Flags[0], CCInfo))
+ return false;
+ continue;
+ }
+
+ assert(NumParts > 1);
+ // For now only handle exact splits.
+ if (NewVT.getSizeInBits() * NumParts != CurVT.getSizeInBits())
+ return false;
+
+ // For incoming arguments (physregs to vregs), we could have values in
+ // physregs (or memlocs) which we want to extract and copy to vregs.
+ // During this, we might have to deal with the LLT being split across
+ // multiple regs, so we have to record this information for later.
+ //
+ // If we have outgoing args, then we have the opposite case. We have a
+ // vreg with an LLT which we want to assign to a physical location, and
+ // we might have to record that the value has to be split later.
+ if (Handler.isIncomingArgumentHandler()) {
+ // We're handling an incoming arg which is split over multiple regs.
+ // E.g. passing an s128 on AArch64.
+ ISD::ArgFlagsTy OrigFlags = Args[i].Flags[0];
+ Args[i].OrigRegs.push_back(Args[i].Regs[0]);
+ Args[i].Regs.clear();
+ Args[i].Flags.clear();
+ LLT NewLLT = getLLTForMVT(NewVT);
+ // For each split register, create and assign a vreg that will store
+ // the incoming component of the larger value. These will later be
+ // merged to form the final vreg.
+ for (unsigned Part = 0; Part < NumParts; ++Part) {
+ Register Reg =
+ MIRBuilder.getMRI()->createGenericVirtualRegister(NewLLT);
+ ISD::ArgFlagsTy Flags = OrigFlags;
+ if (Part == 0) {
+ Flags.setSplit();
} else {
- Flags.setOrigAlign(Align(1));
- if (Part == NumParts - 1)
- Flags.setSplitEnd();
+ Flags.setOrigAlign(Align(1));
+ if (Part == NumParts - 1)
+ Flags.setSplitEnd();
}
- Args[i].Regs.push_back(Reg);
- Args[i].Flags.push_back(Flags);
- if (Handler.assignArg(i, NewVT, NewVT, CCValAssign::Full, Args[i],
- Args[i].Flags[Part], CCInfo)) {
- // Still couldn't assign this smaller part type for some reason.
- return false;
+ Args[i].Regs.push_back(Reg);
+ Args[i].Flags.push_back(Flags);
+ if (Handler.assignArg(i, NewVT, NewVT, CCValAssign::Full, Args[i],
+ Args[i].Flags[Part], CCInfo)) {
+ // Still couldn't assign this smaller part type for some reason.
+ return false;
+ }
+ }
+ } else {
+ // This type is passed via multiple registers in the calling convention.
+ // We need to extract the individual parts.
+ Register LargeReg = Args[i].Regs[0];
+ LLT SmallTy = LLT::scalar(NewVT.getSizeInBits());
+ auto Unmerge = MIRBuilder.buildUnmerge(SmallTy, LargeReg);
+ assert(Unmerge->getNumOperands() == NumParts + 1);
+ ISD::ArgFlagsTy OrigFlags = Args[i].Flags[0];
+ // We're going to replace the regs and flags with the split ones.
+ Args[i].Regs.clear();
+ Args[i].Flags.clear();
+ for (unsigned PartIdx = 0; PartIdx < NumParts; ++PartIdx) {
+ ISD::ArgFlagsTy Flags = OrigFlags;
+ if (PartIdx == 0) {
+ Flags.setSplit();
+ } else {
+ Flags.setOrigAlign(Align(1));
+ if (PartIdx == NumParts - 1)
+ Flags.setSplitEnd();
}
+ Args[i].Regs.push_back(Unmerge.getReg(PartIdx));
+ Args[i].Flags.push_back(Flags);
+ if (Handler.assignArg(i, NewVT, NewVT, CCValAssign::Full,
+ Args[i], Args[i].Flags[PartIdx], CCInfo))
+ return false;
}
- } else {
- // This type is passed via multiple registers in the calling convention.
- // We need to extract the individual parts.
- Register LargeReg = Args[i].Regs[0];
- LLT SmallTy = LLT::scalar(NewVT.getSizeInBits());
- auto Unmerge = MIRBuilder.buildUnmerge(SmallTy, LargeReg);
- assert(Unmerge->getNumOperands() == NumParts + 1);
- ISD::ArgFlagsTy OrigFlags = Args[i].Flags[0];
- // We're going to replace the regs and flags with the split ones.
- Args[i].Regs.clear();
- Args[i].Flags.clear();
- for (unsigned PartIdx = 0; PartIdx < NumParts; ++PartIdx) {
- ISD::ArgFlagsTy Flags = OrigFlags;
- if (PartIdx == 0) {
- Flags.setSplit();
- } else {
- Flags.setOrigAlign(Align(1));
- if (PartIdx == NumParts - 1)
- Flags.setSplitEnd();
- }
- Args[i].Regs.push_back(Unmerge.getReg(PartIdx));
- Args[i].Flags.push_back(Flags);
- if (Handler.assignArg(i, NewVT, NewVT, CCValAssign::Full,
- Args[i], Args[i].Flags[PartIdx], CCInfo))
- return false;
- }
}
}
@@ -361,239 +361,239 @@ bool CallLowering::handleAssignments(CCState &CCInfo,
EVT VAVT = VA.getValVT();
const LLT OrigTy = getLLTForType(*Args[i].Ty, DL);
- // Expected to be multiple regs for a single incoming arg.
- // There should be Regs.size() ArgLocs per argument.
- unsigned NumArgRegs = Args[i].Regs.size();
-
- assert((j + (NumArgRegs - 1)) < ArgLocs.size() &&
- "Too many regs for number of args");
- for (unsigned Part = 0; Part < NumArgRegs; ++Part) {
- // There should be Regs.size() ArgLocs per argument.
- VA = ArgLocs[j + Part];
- if (VA.isMemLoc()) {
- // Don't currently support loading/storing a type that needs to be split
- // to the stack. Should be easy, just not implemented yet.
- if (NumArgRegs > 1) {
- LLVM_DEBUG(
- dbgs()
- << "Load/store a split arg to/from the stack not implemented yet\n");
- return false;
+ // Expected to be multiple regs for a single incoming arg.
+ // There should be Regs.size() ArgLocs per argument.
+ unsigned NumArgRegs = Args[i].Regs.size();
+
+ assert((j + (NumArgRegs - 1)) < ArgLocs.size() &&
+ "Too many regs for number of args");
+ for (unsigned Part = 0; Part < NumArgRegs; ++Part) {
+ // There should be Regs.size() ArgLocs per argument.
+ VA = ArgLocs[j + Part];
+ if (VA.isMemLoc()) {
+ // Don't currently support loading/storing a type that needs to be split
+ // to the stack. Should be easy, just not implemented yet.
+ if (NumArgRegs > 1) {
+ LLVM_DEBUG(
+ dbgs()
+ << "Load/store a split arg to/from the stack not implemented yet\n");
+ return false;
}
-
- // FIXME: Use correct address space for pointer size
- EVT LocVT = VA.getValVT();
- unsigned MemSize = LocVT == MVT::iPTR ? DL.getPointerSize()
- : LocVT.getStoreSize();
- unsigned Offset = VA.getLocMemOffset();
- MachinePointerInfo MPO;
- Register StackAddr = Handler.getStackAddress(MemSize, Offset, MPO);
- Handler.assignValueToAddress(Args[i], StackAddr,
- MemSize, MPO, VA);
- continue;
- }
-
- assert(VA.isRegLoc() && "custom loc should have been handled already");
-
- // GlobalISel does not currently work for scalable vectors.
- if (OrigVT.getFixedSizeInBits() >= VAVT.getFixedSizeInBits() ||
- !Handler.isIncomingArgumentHandler()) {
- // This is an argument that might have been split. There should be
- // Regs.size() ArgLocs per argument.
-
- // Insert the argument copies. If VAVT < OrigVT, we'll insert the merge
- // to the original register after handling all of the parts.
- Handler.assignValueToReg(Args[i].Regs[Part], VA.getLocReg(), VA);
- continue;
- }
-
- // This ArgLoc covers multiple pieces, so we need to split it.
- const LLT VATy(VAVT.getSimpleVT());
- Register NewReg =
- MIRBuilder.getMRI()->createGenericVirtualRegister(VATy);
- Handler.assignValueToReg(NewReg, VA.getLocReg(), VA);
- // If it's a vector type, we either need to truncate the elements
- // or do an unmerge to get the lower block of elements.
- if (VATy.isVector() &&
- VATy.getNumElements() > OrigVT.getVectorNumElements()) {
- // Just handle the case where the VA type is 2 * original type.
- if (VATy.getNumElements() != OrigVT.getVectorNumElements() * 2) {
- LLVM_DEBUG(dbgs()
- << "Incoming promoted vector arg has too many elts");
- return false;
+
+ // FIXME: Use correct address space for pointer size
+ EVT LocVT = VA.getValVT();
+ unsigned MemSize = LocVT == MVT::iPTR ? DL.getPointerSize()
+ : LocVT.getStoreSize();
+ unsigned Offset = VA.getLocMemOffset();
+ MachinePointerInfo MPO;
+ Register StackAddr = Handler.getStackAddress(MemSize, Offset, MPO);
+ Handler.assignValueToAddress(Args[i], StackAddr,
+ MemSize, MPO, VA);
+ continue;
+ }
+
+ assert(VA.isRegLoc() && "custom loc should have been handled already");
+
+ // GlobalISel does not currently work for scalable vectors.
+ if (OrigVT.getFixedSizeInBits() >= VAVT.getFixedSizeInBits() ||
+ !Handler.isIncomingArgumentHandler()) {
+ // This is an argument that might have been split. There should be
+ // Regs.size() ArgLocs per argument.
+
+ // Insert the argument copies. If VAVT < OrigVT, we'll insert the merge
+ // to the original register after handling all of the parts.
+ Handler.assignValueToReg(Args[i].Regs[Part], VA.getLocReg(), VA);
+ continue;
+ }
+
+ // This ArgLoc covers multiple pieces, so we need to split it.
+ const LLT VATy(VAVT.getSimpleVT());
+ Register NewReg =
+ MIRBuilder.getMRI()->createGenericVirtualRegister(VATy);
+ Handler.assignValueToReg(NewReg, VA.getLocReg(), VA);
+ // If it's a vector type, we either need to truncate the elements
+ // or do an unmerge to get the lower block of elements.
+ if (VATy.isVector() &&
+ VATy.getNumElements() > OrigVT.getVectorNumElements()) {
+ // Just handle the case where the VA type is 2 * original type.
+ if (VATy.getNumElements() != OrigVT.getVectorNumElements() * 2) {
+ LLVM_DEBUG(dbgs()
+ << "Incoming promoted vector arg has too many elts");
+ return false;
}
- auto Unmerge = MIRBuilder.buildUnmerge({OrigTy, OrigTy}, {NewReg});
- MIRBuilder.buildCopy(ArgReg, Unmerge.getReg(0));
+ auto Unmerge = MIRBuilder.buildUnmerge({OrigTy, OrigTy}, {NewReg});
+ MIRBuilder.buildCopy(ArgReg, Unmerge.getReg(0));
} else {
- MIRBuilder.buildTrunc(ArgReg, {NewReg}).getReg(0);
+ MIRBuilder.buildTrunc(ArgReg, {NewReg}).getReg(0);
}
- }
-
- // Now that all pieces have been handled, re-pack any arguments into any
- // wider, original registers.
- if (Handler.isIncomingArgumentHandler()) {
- if (VAVT.getFixedSizeInBits() < OrigVT.getFixedSizeInBits()) {
- assert(NumArgRegs >= 2);
-
- // Merge the split registers into the expected larger result vreg
- // of the original call.
- MIRBuilder.buildMerge(Args[i].OrigRegs[0], Args[i].Regs);
+ }
+
+ // Now that all pieces have been handled, re-pack any arguments into any
+ // wider, original registers.
+ if (Handler.isIncomingArgumentHandler()) {
+ if (VAVT.getFixedSizeInBits() < OrigVT.getFixedSizeInBits()) {
+ assert(NumArgRegs >= 2);
+
+ // Merge the split registers into the expected larger result vreg
+ // of the original call.
+ MIRBuilder.buildMerge(Args[i].OrigRegs[0], Args[i].Regs);
}
- }
-
- j += NumArgRegs - 1;
- }
-
- return true;
-}
-
-void CallLowering::insertSRetLoads(MachineIRBuilder &MIRBuilder, Type *RetTy,
- ArrayRef<Register> VRegs, Register DemoteReg,
- int FI) const {
- MachineFunction &MF = MIRBuilder.getMF();
- MachineRegisterInfo &MRI = MF.getRegInfo();
- const DataLayout &DL = MF.getDataLayout();
-
- SmallVector<EVT, 4> SplitVTs;
- SmallVector<uint64_t, 4> Offsets;
- ComputeValueVTs(*TLI, DL, RetTy, SplitVTs, &Offsets, 0);
-
- assert(VRegs.size() == SplitVTs.size());
-
- unsigned NumValues = SplitVTs.size();
- Align BaseAlign = DL.getPrefTypeAlign(RetTy);
- Type *RetPtrTy = RetTy->getPointerTo(DL.getAllocaAddrSpace());
- LLT OffsetLLTy = getLLTForType(*DL.getIntPtrType(RetPtrTy), DL);
-
- MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF, FI);
-
- for (unsigned I = 0; I < NumValues; ++I) {
- Register Addr;
- MIRBuilder.materializePtrAdd(Addr, DemoteReg, OffsetLLTy, Offsets[I]);
- auto *MMO = MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad,
- MRI.getType(VRegs[I]).getSizeInBytes(),
- commonAlignment(BaseAlign, Offsets[I]));
- MIRBuilder.buildLoad(VRegs[I], Addr, *MMO);
- }
-}
-
-void CallLowering::insertSRetStores(MachineIRBuilder &MIRBuilder, Type *RetTy,
- ArrayRef<Register> VRegs,
- Register DemoteReg) const {
- MachineFunction &MF = MIRBuilder.getMF();
- MachineRegisterInfo &MRI = MF.getRegInfo();
- const DataLayout &DL = MF.getDataLayout();
-
- SmallVector<EVT, 4> SplitVTs;
- SmallVector<uint64_t, 4> Offsets;
- ComputeValueVTs(*TLI, DL, RetTy, SplitVTs, &Offsets, 0);
-
- assert(VRegs.size() == SplitVTs.size());
-
- unsigned NumValues = SplitVTs.size();
- Align BaseAlign = DL.getPrefTypeAlign(RetTy);
- unsigned AS = DL.getAllocaAddrSpace();
- LLT OffsetLLTy =
- getLLTForType(*DL.getIntPtrType(RetTy->getPointerTo(AS)), DL);
-
- MachinePointerInfo PtrInfo(AS);
-
- for (unsigned I = 0; I < NumValues; ++I) {
- Register Addr;
- MIRBuilder.materializePtrAdd(Addr, DemoteReg, OffsetLLTy, Offsets[I]);
- auto *MMO = MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOStore,
- MRI.getType(VRegs[I]).getSizeInBytes(),
- commonAlignment(BaseAlign, Offsets[I]));
- MIRBuilder.buildStore(VRegs[I], Addr, *MMO);
- }
-}
-
-void CallLowering::insertSRetIncomingArgument(
- const Function &F, SmallVectorImpl<ArgInfo> &SplitArgs, Register &DemoteReg,
- MachineRegisterInfo &MRI, const DataLayout &DL) const {
- unsigned AS = DL.getAllocaAddrSpace();
- DemoteReg = MRI.createGenericVirtualRegister(
- LLT::pointer(AS, DL.getPointerSizeInBits(AS)));
-
- Type *PtrTy = PointerType::get(F.getReturnType(), AS);
-
- SmallVector<EVT, 1> ValueVTs;
- ComputeValueVTs(*TLI, DL, PtrTy, ValueVTs);
-
- // NOTE: Assume that a pointer won't get split into more than one VT.
- assert(ValueVTs.size() == 1);
-
- ArgInfo DemoteArg(DemoteReg, ValueVTs[0].getTypeForEVT(PtrTy->getContext()));
- setArgFlags(DemoteArg, AttributeList::ReturnIndex, DL, F);
- DemoteArg.Flags[0].setSRet();
- SplitArgs.insert(SplitArgs.begin(), DemoteArg);
-}
-
-void CallLowering::insertSRetOutgoingArgument(MachineIRBuilder &MIRBuilder,
- const CallBase &CB,
- CallLoweringInfo &Info) const {
- const DataLayout &DL = MIRBuilder.getDataLayout();
- Type *RetTy = CB.getType();
- unsigned AS = DL.getAllocaAddrSpace();
- LLT FramePtrTy = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
-
- int FI = MIRBuilder.getMF().getFrameInfo().CreateStackObject(
- DL.getTypeAllocSize(RetTy), DL.getPrefTypeAlign(RetTy), false);
-
- Register DemoteReg = MIRBuilder.buildFrameIndex(FramePtrTy, FI).getReg(0);
- ArgInfo DemoteArg(DemoteReg, PointerType::get(RetTy, AS));
- setArgFlags(DemoteArg, AttributeList::ReturnIndex, DL, CB);
- DemoteArg.Flags[0].setSRet();
-
- Info.OrigArgs.insert(Info.OrigArgs.begin(), DemoteArg);
- Info.DemoteStackIndex = FI;
- Info.DemoteRegister = DemoteReg;
-}
-
-bool CallLowering::checkReturn(CCState &CCInfo,
- SmallVectorImpl<BaseArgInfo> &Outs,
- CCAssignFn *Fn) const {
- for (unsigned I = 0, E = Outs.size(); I < E; ++I) {
- MVT VT = MVT::getVT(Outs[I].Ty);
- if (Fn(I, VT, VT, CCValAssign::Full, Outs[I].Flags[0], CCInfo))
+ }
+
+ j += NumArgRegs - 1;
+ }
+
+ return true;
+}
+
+void CallLowering::insertSRetLoads(MachineIRBuilder &MIRBuilder, Type *RetTy,
+ ArrayRef<Register> VRegs, Register DemoteReg,
+ int FI) const {
+ MachineFunction &MF = MIRBuilder.getMF();
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ const DataLayout &DL = MF.getDataLayout();
+
+ SmallVector<EVT, 4> SplitVTs;
+ SmallVector<uint64_t, 4> Offsets;
+ ComputeValueVTs(*TLI, DL, RetTy, SplitVTs, &Offsets, 0);
+
+ assert(VRegs.size() == SplitVTs.size());
+
+ unsigned NumValues = SplitVTs.size();
+ Align BaseAlign = DL.getPrefTypeAlign(RetTy);
+ Type *RetPtrTy = RetTy->getPointerTo(DL.getAllocaAddrSpace());
+ LLT OffsetLLTy = getLLTForType(*DL.getIntPtrType(RetPtrTy), DL);
+
+ MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF, FI);
+
+ for (unsigned I = 0; I < NumValues; ++I) {
+ Register Addr;
+ MIRBuilder.materializePtrAdd(Addr, DemoteReg, OffsetLLTy, Offsets[I]);
+ auto *MMO = MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad,
+ MRI.getType(VRegs[I]).getSizeInBytes(),
+ commonAlignment(BaseAlign, Offsets[I]));
+ MIRBuilder.buildLoad(VRegs[I], Addr, *MMO);
+ }
+}
+
+void CallLowering::insertSRetStores(MachineIRBuilder &MIRBuilder, Type *RetTy,
+ ArrayRef<Register> VRegs,
+ Register DemoteReg) const {
+ MachineFunction &MF = MIRBuilder.getMF();
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ const DataLayout &DL = MF.getDataLayout();
+
+ SmallVector<EVT, 4> SplitVTs;
+ SmallVector<uint64_t, 4> Offsets;
+ ComputeValueVTs(*TLI, DL, RetTy, SplitVTs, &Offsets, 0);
+
+ assert(VRegs.size() == SplitVTs.size());
+
+ unsigned NumValues = SplitVTs.size();
+ Align BaseAlign = DL.getPrefTypeAlign(RetTy);
+ unsigned AS = DL.getAllocaAddrSpace();
+ LLT OffsetLLTy =
+ getLLTForType(*DL.getIntPtrType(RetTy->getPointerTo(AS)), DL);
+
+ MachinePointerInfo PtrInfo(AS);
+
+ for (unsigned I = 0; I < NumValues; ++I) {
+ Register Addr;
+ MIRBuilder.materializePtrAdd(Addr, DemoteReg, OffsetLLTy, Offsets[I]);
+ auto *MMO = MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOStore,
+ MRI.getType(VRegs[I]).getSizeInBytes(),
+ commonAlignment(BaseAlign, Offsets[I]));
+ MIRBuilder.buildStore(VRegs[I], Addr, *MMO);
+ }
+}
+
+void CallLowering::insertSRetIncomingArgument(
+ const Function &F, SmallVectorImpl<ArgInfo> &SplitArgs, Register &DemoteReg,
+ MachineRegisterInfo &MRI, const DataLayout &DL) const {
+ unsigned AS = DL.getAllocaAddrSpace();
+ DemoteReg = MRI.createGenericVirtualRegister(
+ LLT::pointer(AS, DL.getPointerSizeInBits(AS)));
+
+ Type *PtrTy = PointerType::get(F.getReturnType(), AS);
+
+ SmallVector<EVT, 1> ValueVTs;
+ ComputeValueVTs(*TLI, DL, PtrTy, ValueVTs);
+
+ // NOTE: Assume that a pointer won't get split into more than one VT.
+ assert(ValueVTs.size() == 1);
+
+ ArgInfo DemoteArg(DemoteReg, ValueVTs[0].getTypeForEVT(PtrTy->getContext()));
+ setArgFlags(DemoteArg, AttributeList::ReturnIndex, DL, F);
+ DemoteArg.Flags[0].setSRet();
+ SplitArgs.insert(SplitArgs.begin(), DemoteArg);
+}
+
+void CallLowering::insertSRetOutgoingArgument(MachineIRBuilder &MIRBuilder,
+ const CallBase &CB,
+ CallLoweringInfo &Info) const {
+ const DataLayout &DL = MIRBuilder.getDataLayout();
+ Type *RetTy = CB.getType();
+ unsigned AS = DL.getAllocaAddrSpace();
+ LLT FramePtrTy = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
+
+ int FI = MIRBuilder.getMF().getFrameInfo().CreateStackObject(
+ DL.getTypeAllocSize(RetTy), DL.getPrefTypeAlign(RetTy), false);
+
+ Register DemoteReg = MIRBuilder.buildFrameIndex(FramePtrTy, FI).getReg(0);
+ ArgInfo DemoteArg(DemoteReg, PointerType::get(RetTy, AS));
+ setArgFlags(DemoteArg, AttributeList::ReturnIndex, DL, CB);
+ DemoteArg.Flags[0].setSRet();
+
+ Info.OrigArgs.insert(Info.OrigArgs.begin(), DemoteArg);
+ Info.DemoteStackIndex = FI;
+ Info.DemoteRegister = DemoteReg;
+}
+
+bool CallLowering::checkReturn(CCState &CCInfo,
+ SmallVectorImpl<BaseArgInfo> &Outs,
+ CCAssignFn *Fn) const {
+ for (unsigned I = 0, E = Outs.size(); I < E; ++I) {
+ MVT VT = MVT::getVT(Outs[I].Ty);
+ if (Fn(I, VT, VT, CCValAssign::Full, Outs[I].Flags[0], CCInfo))
return false;
}
return true;
}
-void CallLowering::getReturnInfo(CallingConv::ID CallConv, Type *RetTy,
- AttributeList Attrs,
- SmallVectorImpl<BaseArgInfo> &Outs,
- const DataLayout &DL) const {
- LLVMContext &Context = RetTy->getContext();
- ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy();
-
- SmallVector<EVT, 4> SplitVTs;
- ComputeValueVTs(*TLI, DL, RetTy, SplitVTs);
- addArgFlagsFromAttributes(Flags, Attrs, AttributeList::ReturnIndex);
-
- for (EVT VT : SplitVTs) {
- unsigned NumParts =
- TLI->getNumRegistersForCallingConv(Context, CallConv, VT);
- MVT RegVT = TLI->getRegisterTypeForCallingConv(Context, CallConv, VT);
- Type *PartTy = EVT(RegVT).getTypeForEVT(Context);
-
- for (unsigned I = 0; I < NumParts; ++I) {
- Outs.emplace_back(PartTy, Flags);
- }
- }
-}
-
-bool CallLowering::checkReturnTypeForCallConv(MachineFunction &MF) const {
- const auto &F = MF.getFunction();
- Type *ReturnType = F.getReturnType();
- CallingConv::ID CallConv = F.getCallingConv();
-
- SmallVector<BaseArgInfo, 4> SplitArgs;
- getReturnInfo(CallConv, ReturnType, F.getAttributes(), SplitArgs,
- MF.getDataLayout());
- return canLowerReturn(MF, CallConv, SplitArgs, F.isVarArg());
-}
-
+void CallLowering::getReturnInfo(CallingConv::ID CallConv, Type *RetTy,
+ AttributeList Attrs,
+ SmallVectorImpl<BaseArgInfo> &Outs,
+ const DataLayout &DL) const {
+ LLVMContext &Context = RetTy->getContext();
+ ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy();
+
+ SmallVector<EVT, 4> SplitVTs;
+ ComputeValueVTs(*TLI, DL, RetTy, SplitVTs);
+ addArgFlagsFromAttributes(Flags, Attrs, AttributeList::ReturnIndex);
+
+ for (EVT VT : SplitVTs) {
+ unsigned NumParts =
+ TLI->getNumRegistersForCallingConv(Context, CallConv, VT);
+ MVT RegVT = TLI->getRegisterTypeForCallingConv(Context, CallConv, VT);
+ Type *PartTy = EVT(RegVT).getTypeForEVT(Context);
+
+ for (unsigned I = 0; I < NumParts; ++I) {
+ Outs.emplace_back(PartTy, Flags);
+ }
+ }
+}
+
+bool CallLowering::checkReturnTypeForCallConv(MachineFunction &MF) const {
+ const auto &F = MF.getFunction();
+ Type *ReturnType = F.getReturnType();
+ CallingConv::ID CallConv = F.getCallingConv();
+
+ SmallVector<BaseArgInfo, 4> SplitArgs;
+ getReturnInfo(CallConv, ReturnType, F.getAttributes(), SplitArgs,
+ MF.getDataLayout());
+ return canLowerReturn(MF, CallConv, SplitArgs, F.isVarArg());
+}
+
bool CallLowering::analyzeArgInfo(CCState &CCState,
SmallVectorImpl<ArgInfo> &Args,
CCAssignFn &AssignFnFixed,
@@ -611,58 +611,58 @@ bool CallLowering::analyzeArgInfo(CCState &CCState,
return true;
}
-bool CallLowering::parametersInCSRMatch(
- const MachineRegisterInfo &MRI, const uint32_t *CallerPreservedMask,
- const SmallVectorImpl<CCValAssign> &OutLocs,
- const SmallVectorImpl<ArgInfo> &OutArgs) const {
- for (unsigned i = 0; i < OutLocs.size(); ++i) {
- auto &ArgLoc = OutLocs[i];
- // If it's not a register, it's fine.
- if (!ArgLoc.isRegLoc())
- continue;
-
- MCRegister PhysReg = ArgLoc.getLocReg();
-
- // Only look at callee-saved registers.
- if (MachineOperand::clobbersPhysReg(CallerPreservedMask, PhysReg))
- continue;
-
- LLVM_DEBUG(
- dbgs()
- << "... Call has an argument passed in a callee-saved register.\n");
-
- // Check if it was copied from.
- const ArgInfo &OutInfo = OutArgs[i];
-
- if (OutInfo.Regs.size() > 1) {
- LLVM_DEBUG(
- dbgs() << "... Cannot handle arguments in multiple registers.\n");
- return false;
- }
-
- // Check if we copy the register, walking through copies from virtual
- // registers. Note that getDefIgnoringCopies does not ignore copies from
- // physical registers.
- MachineInstr *RegDef = getDefIgnoringCopies(OutInfo.Regs[0], MRI);
- if (!RegDef || RegDef->getOpcode() != TargetOpcode::COPY) {
- LLVM_DEBUG(
- dbgs()
- << "... Parameter was not copied into a VReg, cannot tail call.\n");
- return false;
- }
-
- // Got a copy. Verify that it's the same as the register we want.
- Register CopyRHS = RegDef->getOperand(1).getReg();
- if (CopyRHS != PhysReg) {
- LLVM_DEBUG(dbgs() << "... Callee-saved register was not copied into "
- "VReg, cannot tail call.\n");
- return false;
- }
- }
-
- return true;
-}
-
+bool CallLowering::parametersInCSRMatch(
+ const MachineRegisterInfo &MRI, const uint32_t *CallerPreservedMask,
+ const SmallVectorImpl<CCValAssign> &OutLocs,
+ const SmallVectorImpl<ArgInfo> &OutArgs) const {
+ for (unsigned i = 0; i < OutLocs.size(); ++i) {
+ auto &ArgLoc = OutLocs[i];
+ // If it's not a register, it's fine.
+ if (!ArgLoc.isRegLoc())
+ continue;
+
+ MCRegister PhysReg = ArgLoc.getLocReg();
+
+ // Only look at callee-saved registers.
+ if (MachineOperand::clobbersPhysReg(CallerPreservedMask, PhysReg))
+ continue;
+
+ LLVM_DEBUG(
+ dbgs()
+ << "... Call has an argument passed in a callee-saved register.\n");
+
+ // Check if it was copied from.
+ const ArgInfo &OutInfo = OutArgs[i];
+
+ if (OutInfo.Regs.size() > 1) {
+ LLVM_DEBUG(
+ dbgs() << "... Cannot handle arguments in multiple registers.\n");
+ return false;
+ }
+
+ // Check if we copy the register, walking through copies from virtual
+ // registers. Note that getDefIgnoringCopies does not ignore copies from
+ // physical registers.
+ MachineInstr *RegDef = getDefIgnoringCopies(OutInfo.Regs[0], MRI);
+ if (!RegDef || RegDef->getOpcode() != TargetOpcode::COPY) {
+ LLVM_DEBUG(
+ dbgs()
+ << "... Parameter was not copied into a VReg, cannot tail call.\n");
+ return false;
+ }
+
+ // Got a copy. Verify that it's the same as the register we want.
+ Register CopyRHS = RegDef->getOperand(1).getReg();
+ if (CopyRHS != PhysReg) {
+ LLVM_DEBUG(dbgs() << "... Callee-saved register was not copied into "
+ "VReg, cannot tail call.\n");
+ return false;
+ }
+ }
+
+ return true;
+}
+
bool CallLowering::resultsCompatible(CallLoweringInfo &Info,
MachineFunction &MF,
SmallVectorImpl<ArgInfo> &InArgs,
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Combiner.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Combiner.cpp
index 86480b47e9..f1071d96e5 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Combiner.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Combiner.cpp
@@ -153,8 +153,8 @@ bool Combiner::combineMachineInstrs(MachineFunction &MF,
MFChanged |= Changed;
} while (Changed);
- assert(!CSEInfo || (!errorToBool(CSEInfo->verify()) &&
- "CSEInfo is not consistent. Likely missing calls to "
- "observer on mutations"));
+ assert(!CSEInfo || (!errorToBool(CSEInfo->verify()) &&
+ "CSEInfo is not consistent. Likely missing calls to "
+ "observer on mutations"));
return MFChanged;
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 8ea55b6abd..a9353bdfb7 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -16,7 +16,7 @@
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
@@ -44,75 +44,75 @@ CombinerHelper::CombinerHelper(GISelChangeObserver &Observer,
(void)this->KB;
}
-const TargetLowering &CombinerHelper::getTargetLowering() const {
- return *Builder.getMF().getSubtarget().getTargetLowering();
-}
-
-/// \returns The little endian in-memory byte position of byte \p I in a
-/// \p ByteWidth bytes wide type.
-///
-/// E.g. Given a 4-byte type x, x[0] -> byte 0
-static unsigned littleEndianByteAt(const unsigned ByteWidth, const unsigned I) {
- assert(I < ByteWidth && "I must be in [0, ByteWidth)");
- return I;
-}
-
-/// \returns The big endian in-memory byte position of byte \p I in a
-/// \p ByteWidth bytes wide type.
-///
-/// E.g. Given a 4-byte type x, x[0] -> byte 3
-static unsigned bigEndianByteAt(const unsigned ByteWidth, const unsigned I) {
- assert(I < ByteWidth && "I must be in [0, ByteWidth)");
- return ByteWidth - I - 1;
-}
-
-/// Given a map from byte offsets in memory to indices in a load/store,
-/// determine if that map corresponds to a little or big endian byte pattern.
-///
-/// \param MemOffset2Idx maps memory offsets to address offsets.
-/// \param LowestIdx is the lowest index in \p MemOffset2Idx.
-///
-/// \returns true if the map corresponds to a big endian byte pattern, false
-/// if it corresponds to a little endian byte pattern, and None otherwise.
-///
-/// E.g. given a 32-bit type x, and x[AddrOffset], the in-memory byte patterns
-/// are as follows:
-///
-/// AddrOffset Little endian Big endian
-/// 0 0 3
-/// 1 1 2
-/// 2 2 1
-/// 3 3 0
-static Optional<bool>
-isBigEndian(const SmallDenseMap<int64_t, int64_t, 8> &MemOffset2Idx,
- int64_t LowestIdx) {
- // Need at least two byte positions to decide on endianness.
- unsigned Width = MemOffset2Idx.size();
- if (Width < 2)
- return None;
- bool BigEndian = true, LittleEndian = true;
- for (unsigned MemOffset = 0; MemOffset < Width; ++ MemOffset) {
- auto MemOffsetAndIdx = MemOffset2Idx.find(MemOffset);
- if (MemOffsetAndIdx == MemOffset2Idx.end())
- return None;
- const int64_t Idx = MemOffsetAndIdx->second - LowestIdx;
- assert(Idx >= 0 && "Expected non-negative byte offset?");
- LittleEndian &= Idx == littleEndianByteAt(Width, MemOffset);
- BigEndian &= Idx == bigEndianByteAt(Width, MemOffset);
- if (!BigEndian && !LittleEndian)
- return None;
- }
-
- assert((BigEndian != LittleEndian) &&
- "Pattern cannot be both big and little endian!");
- return BigEndian;
-}
-
-bool CombinerHelper::isLegalOrBeforeLegalizer(
- const LegalityQuery &Query) const {
- return !LI || LI->getAction(Query).Action == LegalizeActions::Legal;
-}
-
+const TargetLowering &CombinerHelper::getTargetLowering() const {
+ return *Builder.getMF().getSubtarget().getTargetLowering();
+}
+
+/// \returns The little endian in-memory byte position of byte \p I in a
+/// \p ByteWidth bytes wide type.
+///
+/// E.g. Given a 4-byte type x, x[0] -> byte 0
+static unsigned littleEndianByteAt(const unsigned ByteWidth, const unsigned I) {
+ assert(I < ByteWidth && "I must be in [0, ByteWidth)");
+ return I;
+}
+
+/// \returns The big endian in-memory byte position of byte \p I in a
+/// \p ByteWidth bytes wide type.
+///
+/// E.g. Given a 4-byte type x, x[0] -> byte 3
+static unsigned bigEndianByteAt(const unsigned ByteWidth, const unsigned I) {
+ assert(I < ByteWidth && "I must be in [0, ByteWidth)");
+ return ByteWidth - I - 1;
+}
+
+/// Given a map from byte offsets in memory to indices in a load/store,
+/// determine if that map corresponds to a little or big endian byte pattern.
+///
+/// \param MemOffset2Idx maps memory offsets to address offsets.
+/// \param LowestIdx is the lowest index in \p MemOffset2Idx.
+///
+/// \returns true if the map corresponds to a big endian byte pattern, false
+/// if it corresponds to a little endian byte pattern, and None otherwise.
+///
+/// E.g. given a 32-bit type x, and x[AddrOffset], the in-memory byte patterns
+/// are as follows:
+///
+/// AddrOffset Little endian Big endian
+/// 0 0 3
+/// 1 1 2
+/// 2 2 1
+/// 3 3 0
+static Optional<bool>
+isBigEndian(const SmallDenseMap<int64_t, int64_t, 8> &MemOffset2Idx,
+ int64_t LowestIdx) {
+ // Need at least two byte positions to decide on endianness.
+ unsigned Width = MemOffset2Idx.size();
+ if (Width < 2)
+ return None;
+ bool BigEndian = true, LittleEndian = true;
+ for (unsigned MemOffset = 0; MemOffset < Width; ++ MemOffset) {
+ auto MemOffsetAndIdx = MemOffset2Idx.find(MemOffset);
+ if (MemOffsetAndIdx == MemOffset2Idx.end())
+ return None;
+ const int64_t Idx = MemOffsetAndIdx->second - LowestIdx;
+ assert(Idx >= 0 && "Expected non-negative byte offset?");
+ LittleEndian &= Idx == littleEndianByteAt(Width, MemOffset);
+ BigEndian &= Idx == bigEndianByteAt(Width, MemOffset);
+ if (!BigEndian && !LittleEndian)
+ return None;
+ }
+
+ assert((BigEndian != LittleEndian) &&
+ "Pattern cannot be both big and little endian!");
+ return BigEndian;
+}
+
+bool CombinerHelper::isLegalOrBeforeLegalizer(
+ const LegalityQuery &Query) const {
+ return !LI || LI->getAction(Query).Action == LegalizeActions::Legal;
+}
+
void CombinerHelper::replaceRegWith(MachineRegisterInfo &MRI, Register FromReg,
Register ToReg) const {
Observer.changingAllUsesOfReg(MRI, FromReg);
@@ -624,13 +624,13 @@ bool CombinerHelper::isPredecessor(const MachineInstr &DefMI,
assert(DefMI.getParent() == UseMI.getParent());
if (&DefMI == &UseMI)
return false;
- const MachineBasicBlock &MBB = *DefMI.getParent();
- auto DefOrUse = find_if(MBB, [&DefMI, &UseMI](const MachineInstr &MI) {
- return &MI == &DefMI || &MI == &UseMI;
- });
- if (DefOrUse == MBB.end())
- llvm_unreachable("Block must contain both DefMI and UseMI!");
- return &*DefOrUse == &DefMI;
+ const MachineBasicBlock &MBB = *DefMI.getParent();
+ auto DefOrUse = find_if(MBB, [&DefMI, &UseMI](const MachineInstr &MI) {
+ return &MI == &DefMI || &MI == &UseMI;
+ });
+ if (DefOrUse == MBB.end())
+ llvm_unreachable("Block must contain both DefMI and UseMI!");
+ return &*DefOrUse == &DefMI;
}
bool CombinerHelper::dominates(const MachineInstr &DefMI,
@@ -645,101 +645,101 @@ bool CombinerHelper::dominates(const MachineInstr &DefMI,
return isPredecessor(DefMI, UseMI);
}
-bool CombinerHelper::matchSextTruncSextLoad(MachineInstr &MI) {
+bool CombinerHelper::matchSextTruncSextLoad(MachineInstr &MI) {
+ assert(MI.getOpcode() == TargetOpcode::G_SEXT_INREG);
+ Register SrcReg = MI.getOperand(1).getReg();
+ Register LoadUser = SrcReg;
+
+ if (MRI.getType(SrcReg).isVector())
+ return false;
+
+ Register TruncSrc;
+ if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc))))
+ LoadUser = TruncSrc;
+
+ uint64_t SizeInBits = MI.getOperand(2).getImm();
+ // If the source is a G_SEXTLOAD from the same bit width, then we don't
+ // need any extend at all, just a truncate.
+ if (auto *LoadMI = getOpcodeDef(TargetOpcode::G_SEXTLOAD, LoadUser, MRI)) {
+ const auto &MMO = **LoadMI->memoperands_begin();
+ // If truncating more than the original extended value, abort.
+ if (TruncSrc && MRI.getType(TruncSrc).getSizeInBits() < MMO.getSizeInBits())
+ return false;
+ if (MMO.getSizeInBits() == SizeInBits)
+ return true;
+ }
+ return false;
+}
+
+bool CombinerHelper::applySextTruncSextLoad(MachineInstr &MI) {
+ assert(MI.getOpcode() == TargetOpcode::G_SEXT_INREG);
+ Builder.setInstrAndDebugLoc(MI);
+ Builder.buildCopy(MI.getOperand(0).getReg(), MI.getOperand(1).getReg());
+ MI.eraseFromParent();
+ return true;
+}
+
+bool CombinerHelper::matchSextInRegOfLoad(
+ MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo) {
assert(MI.getOpcode() == TargetOpcode::G_SEXT_INREG);
+
+ // Only supports scalars for now.
+ if (MRI.getType(MI.getOperand(0).getReg()).isVector())
+ return false;
+
Register SrcReg = MI.getOperand(1).getReg();
- Register LoadUser = SrcReg;
-
- if (MRI.getType(SrcReg).isVector())
- return false;
-
- Register TruncSrc;
- if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc))))
- LoadUser = TruncSrc;
-
- uint64_t SizeInBits = MI.getOperand(2).getImm();
- // If the source is a G_SEXTLOAD from the same bit width, then we don't
- // need any extend at all, just a truncate.
- if (auto *LoadMI = getOpcodeDef(TargetOpcode::G_SEXTLOAD, LoadUser, MRI)) {
- const auto &MMO = **LoadMI->memoperands_begin();
- // If truncating more than the original extended value, abort.
- if (TruncSrc && MRI.getType(TruncSrc).getSizeInBits() < MMO.getSizeInBits())
- return false;
- if (MMO.getSizeInBits() == SizeInBits)
- return true;
- }
- return false;
-}
-
-bool CombinerHelper::applySextTruncSextLoad(MachineInstr &MI) {
+ MachineInstr *LoadDef = getOpcodeDef(TargetOpcode::G_LOAD, SrcReg, MRI);
+ if (!LoadDef || !MRI.hasOneNonDBGUse(LoadDef->getOperand(0).getReg()))
+ return false;
+
+ // If the sign extend extends from a narrower width than the load's width,
+ // then we can narrow the load width when we combine to a G_SEXTLOAD.
+ auto &MMO = **LoadDef->memoperands_begin();
+ // Don't do this for non-simple loads.
+ if (MMO.isAtomic() || MMO.isVolatile())
+ return false;
+
+ // Avoid widening the load at all.
+ unsigned NewSizeBits =
+ std::min((uint64_t)MI.getOperand(2).getImm(), MMO.getSizeInBits());
+
+ // Don't generate G_SEXTLOADs with a < 1 byte width.
+ if (NewSizeBits < 8)
+ return false;
+ // Don't bother creating a non-power-2 sextload, it will likely be broken up
+ // anyway for most targets.
+ if (!isPowerOf2_32(NewSizeBits))
+ return false;
+ MatchInfo = std::make_tuple(LoadDef->getOperand(0).getReg(), NewSizeBits);
+ return true;
+}
+
+bool CombinerHelper::applySextInRegOfLoad(
+ MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo) {
assert(MI.getOpcode() == TargetOpcode::G_SEXT_INREG);
- Builder.setInstrAndDebugLoc(MI);
- Builder.buildCopy(MI.getOperand(0).getReg(), MI.getOperand(1).getReg());
+ Register LoadReg;
+ unsigned ScalarSizeBits;
+ std::tie(LoadReg, ScalarSizeBits) = MatchInfo;
+ auto *LoadDef = MRI.getVRegDef(LoadReg);
+ assert(LoadDef && "Expected a load reg");
+
+ // If we have the following:
+ // %ld = G_LOAD %ptr, (load 2)
+ // %ext = G_SEXT_INREG %ld, 8
+ // ==>
+ // %ld = G_SEXTLOAD %ptr (load 1)
+
+ auto &MMO = **LoadDef->memoperands_begin();
+ Builder.setInstrAndDebugLoc(MI);
+ auto &MF = Builder.getMF();
+ auto PtrInfo = MMO.getPointerInfo();
+ auto *NewMMO = MF.getMachineMemOperand(&MMO, PtrInfo, ScalarSizeBits / 8);
+ Builder.buildLoadInstr(TargetOpcode::G_SEXTLOAD, MI.getOperand(0).getReg(),
+ LoadDef->getOperand(1).getReg(), *NewMMO);
MI.eraseFromParent();
return true;
}
-bool CombinerHelper::matchSextInRegOfLoad(
- MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_SEXT_INREG);
-
- // Only supports scalars for now.
- if (MRI.getType(MI.getOperand(0).getReg()).isVector())
- return false;
-
- Register SrcReg = MI.getOperand(1).getReg();
- MachineInstr *LoadDef = getOpcodeDef(TargetOpcode::G_LOAD, SrcReg, MRI);
- if (!LoadDef || !MRI.hasOneNonDBGUse(LoadDef->getOperand(0).getReg()))
- return false;
-
- // If the sign extend extends from a narrower width than the load's width,
- // then we can narrow the load width when we combine to a G_SEXTLOAD.
- auto &MMO = **LoadDef->memoperands_begin();
- // Don't do this for non-simple loads.
- if (MMO.isAtomic() || MMO.isVolatile())
- return false;
-
- // Avoid widening the load at all.
- unsigned NewSizeBits =
- std::min((uint64_t)MI.getOperand(2).getImm(), MMO.getSizeInBits());
-
- // Don't generate G_SEXTLOADs with a < 1 byte width.
- if (NewSizeBits < 8)
- return false;
- // Don't bother creating a non-power-2 sextload, it will likely be broken up
- // anyway for most targets.
- if (!isPowerOf2_32(NewSizeBits))
- return false;
- MatchInfo = std::make_tuple(LoadDef->getOperand(0).getReg(), NewSizeBits);
- return true;
-}
-
-bool CombinerHelper::applySextInRegOfLoad(
- MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_SEXT_INREG);
- Register LoadReg;
- unsigned ScalarSizeBits;
- std::tie(LoadReg, ScalarSizeBits) = MatchInfo;
- auto *LoadDef = MRI.getVRegDef(LoadReg);
- assert(LoadDef && "Expected a load reg");
-
- // If we have the following:
- // %ld = G_LOAD %ptr, (load 2)
- // %ext = G_SEXT_INREG %ld, 8
- // ==>
- // %ld = G_SEXTLOAD %ptr (load 1)
-
- auto &MMO = **LoadDef->memoperands_begin();
- Builder.setInstrAndDebugLoc(MI);
- auto &MF = Builder.getMF();
- auto PtrInfo = MMO.getPointerInfo();
- auto *NewMMO = MF.getMachineMemOperand(&MMO, PtrInfo, ScalarSizeBits / 8);
- Builder.buildLoadInstr(TargetOpcode::G_SEXTLOAD, MI.getOperand(0).getReg(),
- LoadDef->getOperand(1).getReg(), *NewMMO);
- MI.eraseFromParent();
- return true;
-}
-
bool CombinerHelper::findPostIndexCandidate(MachineInstr &MI, Register &Addr,
Register &Base, Register &Offset) {
auto &MF = *MI.getParent()->getParent();
@@ -757,7 +757,7 @@ bool CombinerHelper::findPostIndexCandidate(MachineInstr &MI, Register &Addr,
return false;
LLVM_DEBUG(dbgs() << "Searching for post-indexing opportunity for: " << MI);
- // FIXME: The following use traversal needs a bail out for patholigical cases.
+ // FIXME: The following use traversal needs a bail out for patholigical cases.
for (auto &Use : MRI.use_nodbg_instructions(Base)) {
if (Use.getOpcode() != TargetOpcode::G_PTR_ADD)
continue;
@@ -884,11 +884,11 @@ bool CombinerHelper::matchCombineIndexedLoadStore(MachineInstr &MI, IndexedLoadS
Opcode != TargetOpcode::G_ZEXTLOAD && Opcode != TargetOpcode::G_STORE)
return false;
- // For now, no targets actually support these opcodes so don't waste time
- // running these unless we're forced to for testing.
- if (!ForceLegalIndexing)
- return false;
-
+ // For now, no targets actually support these opcodes so don't waste time
+ // running these unless we're forced to for testing.
+ if (!ForceLegalIndexing)
+ return false;
+
MatchInfo.IsPre = findPreIndexCandidate(MI, MatchInfo.Addr, MatchInfo.Base,
MatchInfo.Offset);
if (!MatchInfo.IsPre &&
@@ -941,7 +941,7 @@ void CombinerHelper::applyCombineIndexedLoadStore(
LLVM_DEBUG(dbgs() << " Combinined to indexed operation");
}
-bool CombinerHelper::matchOptBrCondByInvertingCond(MachineInstr &MI) {
+bool CombinerHelper::matchOptBrCondByInvertingCond(MachineInstr &MI) {
if (MI.getOpcode() != TargetOpcode::G_BR)
return false;
@@ -956,7 +956,7 @@ bool CombinerHelper::matchOptBrCondByInvertingCond(MachineInstr &MI) {
// The above pattern does not have a fall through to the successor bb2, always
// resulting in a branch no matter which path is taken. Here we try to find
// and replace that pattern with conditional branch to bb3 and otherwise
- // fallthrough to bb2. This is generally better for branch predictors.
+ // fallthrough to bb2. This is generally better for branch predictors.
MachineBasicBlock *MBB = MI.getParent();
MachineBasicBlock::iterator BrIt(MI);
@@ -968,36 +968,36 @@ bool CombinerHelper::matchOptBrCondByInvertingCond(MachineInstr &MI) {
if (BrCond->getOpcode() != TargetOpcode::G_BRCOND)
return false;
- // Check that the next block is the conditional branch target. Also make sure
- // that it isn't the same as the G_BR's target (otherwise, this will loop.)
- MachineBasicBlock *BrCondTarget = BrCond->getOperand(1).getMBB();
- return BrCondTarget != MI.getOperand(0).getMBB() &&
- MBB->isLayoutSuccessor(BrCondTarget);
+ // Check that the next block is the conditional branch target. Also make sure
+ // that it isn't the same as the G_BR's target (otherwise, this will loop.)
+ MachineBasicBlock *BrCondTarget = BrCond->getOperand(1).getMBB();
+ return BrCondTarget != MI.getOperand(0).getMBB() &&
+ MBB->isLayoutSuccessor(BrCondTarget);
}
-void CombinerHelper::applyOptBrCondByInvertingCond(MachineInstr &MI) {
+void CombinerHelper::applyOptBrCondByInvertingCond(MachineInstr &MI) {
MachineBasicBlock *BrTarget = MI.getOperand(0).getMBB();
MachineBasicBlock::iterator BrIt(MI);
MachineInstr *BrCond = &*std::prev(BrIt);
- Builder.setInstrAndDebugLoc(*BrCond);
- LLT Ty = MRI.getType(BrCond->getOperand(0).getReg());
- // FIXME: Does int/fp matter for this? If so, we might need to restrict
- // this to i1 only since we might not know for sure what kind of
- // compare generated the condition value.
- auto True = Builder.buildConstant(
- Ty, getICmpTrueVal(getTargetLowering(), false, false));
- auto Xor = Builder.buildXor(Ty, BrCond->getOperand(0), True);
-
- auto *FallthroughBB = BrCond->getOperand(1).getMBB();
- Observer.changingInstr(MI);
- MI.getOperand(0).setMBB(FallthroughBB);
- Observer.changedInstr(MI);
-
- // Change the conditional branch to use the inverted condition and
- // new target block.
+ Builder.setInstrAndDebugLoc(*BrCond);
+ LLT Ty = MRI.getType(BrCond->getOperand(0).getReg());
+ // FIXME: Does int/fp matter for this? If so, we might need to restrict
+ // this to i1 only since we might not know for sure what kind of
+ // compare generated the condition value.
+ auto True = Builder.buildConstant(
+ Ty, getICmpTrueVal(getTargetLowering(), false, false));
+ auto Xor = Builder.buildXor(Ty, BrCond->getOperand(0), True);
+
+ auto *FallthroughBB = BrCond->getOperand(1).getMBB();
+ Observer.changingInstr(MI);
+ MI.getOperand(0).setMBB(FallthroughBB);
+ Observer.changedInstr(MI);
+
+ // Change the conditional branch to use the inverted condition and
+ // new target block.
Observer.changingInstr(*BrCond);
- BrCond->getOperand(0).setReg(Xor.getReg(0));
+ BrCond->getOperand(0).setReg(Xor.getReg(0));
BrCond->getOperand(1).setMBB(BrTarget);
Observer.changedInstr(*BrCond);
}
@@ -1090,7 +1090,7 @@ static Register getMemsetValue(Register Val, LLT Ty, MachineIRBuilder &MIB) {
unsigned NumBits = Ty.getScalarSizeInBits();
auto ValVRegAndVal = getConstantVRegValWithLookThrough(Val, MRI);
if (!Ty.isVector() && ValVRegAndVal) {
- APInt Scalar = ValVRegAndVal->Value.truncOrSelf(8);
+ APInt Scalar = ValVRegAndVal->Value.truncOrSelf(8);
APInt SplatVal = APInt::getSplat(NumBits, Scalar);
return MIB.buildConstant(Ty, SplatVal).getReg(0);
}
@@ -1442,11 +1442,11 @@ bool CombinerHelper::optimizeMemmove(MachineInstr &MI, Register Dst,
}
bool CombinerHelper::tryCombineMemCpyFamily(MachineInstr &MI, unsigned MaxLen) {
- const unsigned Opc = MI.getOpcode();
+ const unsigned Opc = MI.getOpcode();
// This combine is fairly complex so it's not written with a separate
// matcher function.
- assert((Opc == TargetOpcode::G_MEMCPY || Opc == TargetOpcode::G_MEMMOVE ||
- Opc == TargetOpcode::G_MEMSET) && "Expected memcpy like instruction");
+ assert((Opc == TargetOpcode::G_MEMCPY || Opc == TargetOpcode::G_MEMMOVE ||
+ Opc == TargetOpcode::G_MEMSET) && "Expected memcpy like instruction");
auto MMOIt = MI.memoperands_begin();
const MachineMemOperand *MemOp = *MMOIt;
@@ -1457,11 +1457,11 @@ bool CombinerHelper::tryCombineMemCpyFamily(MachineInstr &MI, unsigned MaxLen) {
Align DstAlign = MemOp->getBaseAlign();
Align SrcAlign;
- Register Dst = MI.getOperand(0).getReg();
- Register Src = MI.getOperand(1).getReg();
- Register Len = MI.getOperand(2).getReg();
+ Register Dst = MI.getOperand(0).getReg();
+ Register Src = MI.getOperand(1).getReg();
+ Register Len = MI.getOperand(2).getReg();
- if (Opc != TargetOpcode::G_MEMSET) {
+ if (Opc != TargetOpcode::G_MEMSET) {
assert(MMOIt != MI.memoperands_end() && "Expected a second MMO on MI");
MemOp = *(++MMOIt);
SrcAlign = MemOp->getBaseAlign();
@@ -1471,7 +1471,7 @@ bool CombinerHelper::tryCombineMemCpyFamily(MachineInstr &MI, unsigned MaxLen) {
auto LenVRegAndVal = getConstantVRegValWithLookThrough(Len, MRI);
if (!LenVRegAndVal)
return false; // Leave it to the legalizer to lower it to a libcall.
- unsigned KnownLen = LenVRegAndVal->Value.getZExtValue();
+ unsigned KnownLen = LenVRegAndVal->Value.getZExtValue();
if (KnownLen == 0) {
MI.eraseFromParent();
@@ -1481,78 +1481,78 @@ bool CombinerHelper::tryCombineMemCpyFamily(MachineInstr &MI, unsigned MaxLen) {
if (MaxLen && KnownLen > MaxLen)
return false;
- if (Opc == TargetOpcode::G_MEMCPY)
+ if (Opc == TargetOpcode::G_MEMCPY)
return optimizeMemcpy(MI, Dst, Src, KnownLen, DstAlign, SrcAlign, IsVolatile);
- if (Opc == TargetOpcode::G_MEMMOVE)
+ if (Opc == TargetOpcode::G_MEMMOVE)
return optimizeMemmove(MI, Dst, Src, KnownLen, DstAlign, SrcAlign, IsVolatile);
- if (Opc == TargetOpcode::G_MEMSET)
+ if (Opc == TargetOpcode::G_MEMSET)
return optimizeMemset(MI, Dst, Src, KnownLen, DstAlign, IsVolatile);
return false;
}
-static Optional<APFloat> constantFoldFpUnary(unsigned Opcode, LLT DstTy,
- const Register Op,
- const MachineRegisterInfo &MRI) {
- const ConstantFP *MaybeCst = getConstantFPVRegVal(Op, MRI);
- if (!MaybeCst)
- return None;
-
- APFloat V = MaybeCst->getValueAPF();
- switch (Opcode) {
- default:
- llvm_unreachable("Unexpected opcode!");
- case TargetOpcode::G_FNEG: {
- V.changeSign();
- return V;
- }
- case TargetOpcode::G_FABS: {
- V.clearSign();
- return V;
- }
- case TargetOpcode::G_FPTRUNC:
- break;
- case TargetOpcode::G_FSQRT: {
- bool Unused;
- V.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &Unused);
- V = APFloat(sqrt(V.convertToDouble()));
- break;
- }
- case TargetOpcode::G_FLOG2: {
- bool Unused;
- V.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &Unused);
- V = APFloat(log2(V.convertToDouble()));
- break;
- }
- }
- // Convert `APFloat` to appropriate IEEE type depending on `DstTy`. Otherwise,
- // `buildFConstant` will assert on size mismatch. Only `G_FPTRUNC`, `G_FSQRT`,
- // and `G_FLOG2` reach here.
- bool Unused;
- V.convert(getFltSemanticForLLT(DstTy), APFloat::rmNearestTiesToEven, &Unused);
- return V;
-}
-
-bool CombinerHelper::matchCombineConstantFoldFpUnary(MachineInstr &MI,
- Optional<APFloat> &Cst) {
- Register DstReg = MI.getOperand(0).getReg();
- Register SrcReg = MI.getOperand(1).getReg();
- LLT DstTy = MRI.getType(DstReg);
- Cst = constantFoldFpUnary(MI.getOpcode(), DstTy, SrcReg, MRI);
- return Cst.hasValue();
-}
-
-bool CombinerHelper::applyCombineConstantFoldFpUnary(MachineInstr &MI,
- Optional<APFloat> &Cst) {
- assert(Cst.hasValue() && "Optional is unexpectedly empty!");
- Builder.setInstrAndDebugLoc(MI);
- MachineFunction &MF = Builder.getMF();
- auto *FPVal = ConstantFP::get(MF.getFunction().getContext(), *Cst);
- Register DstReg = MI.getOperand(0).getReg();
- Builder.buildFConstant(DstReg, *FPVal);
- MI.eraseFromParent();
- return true;
-}
-
+static Optional<APFloat> constantFoldFpUnary(unsigned Opcode, LLT DstTy,
+ const Register Op,
+ const MachineRegisterInfo &MRI) {
+ const ConstantFP *MaybeCst = getConstantFPVRegVal(Op, MRI);
+ if (!MaybeCst)
+ return None;
+
+ APFloat V = MaybeCst->getValueAPF();
+ switch (Opcode) {
+ default:
+ llvm_unreachable("Unexpected opcode!");
+ case TargetOpcode::G_FNEG: {
+ V.changeSign();
+ return V;
+ }
+ case TargetOpcode::G_FABS: {
+ V.clearSign();
+ return V;
+ }
+ case TargetOpcode::G_FPTRUNC:
+ break;
+ case TargetOpcode::G_FSQRT: {
+ bool Unused;
+ V.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &Unused);
+ V = APFloat(sqrt(V.convertToDouble()));
+ break;
+ }
+ case TargetOpcode::G_FLOG2: {
+ bool Unused;
+ V.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &Unused);
+ V = APFloat(log2(V.convertToDouble()));
+ break;
+ }
+ }
+ // Convert `APFloat` to appropriate IEEE type depending on `DstTy`. Otherwise,
+ // `buildFConstant` will assert on size mismatch. Only `G_FPTRUNC`, `G_FSQRT`,
+ // and `G_FLOG2` reach here.
+ bool Unused;
+ V.convert(getFltSemanticForLLT(DstTy), APFloat::rmNearestTiesToEven, &Unused);
+ return V;
+}
+
+bool CombinerHelper::matchCombineConstantFoldFpUnary(MachineInstr &MI,
+ Optional<APFloat> &Cst) {
+ Register DstReg = MI.getOperand(0).getReg();
+ Register SrcReg = MI.getOperand(1).getReg();
+ LLT DstTy = MRI.getType(DstReg);
+ Cst = constantFoldFpUnary(MI.getOpcode(), DstTy, SrcReg, MRI);
+ return Cst.hasValue();
+}
+
+bool CombinerHelper::applyCombineConstantFoldFpUnary(MachineInstr &MI,
+ Optional<APFloat> &Cst) {
+ assert(Cst.hasValue() && "Optional is unexpectedly empty!");
+ Builder.setInstrAndDebugLoc(MI);
+ MachineFunction &MF = Builder.getMF();
+ auto *FPVal = ConstantFP::get(MF.getFunction().getContext(), *Cst);
+ Register DstReg = MI.getOperand(0).getReg();
+ Builder.buildFConstant(DstReg, *FPVal);
+ MI.eraseFromParent();
+ return true;
+}
+
bool CombinerHelper::matchPtrAddImmedChain(MachineInstr &MI,
PtrAddChain &MatchInfo) {
// We're trying to match the following pattern:
@@ -1581,7 +1581,7 @@ bool CombinerHelper::matchPtrAddImmedChain(MachineInstr &MI,
return false;
// Pass the combined immediate to the apply function.
- MatchInfo.Imm = (MaybeImmVal->Value + MaybeImm2Val->Value).getSExtValue();
+ MatchInfo.Imm = (MaybeImmVal->Value + MaybeImm2Val->Value).getSExtValue();
MatchInfo.Base = Base;
return true;
}
@@ -1599,211 +1599,211 @@ bool CombinerHelper::applyPtrAddImmedChain(MachineInstr &MI,
return true;
}
-bool CombinerHelper::matchShiftImmedChain(MachineInstr &MI,
- RegisterImmPair &MatchInfo) {
- // We're trying to match the following pattern with any of
- // G_SHL/G_ASHR/G_LSHR/G_SSHLSAT/G_USHLSAT shift instructions:
- // %t1 = SHIFT %base, G_CONSTANT imm1
- // %root = SHIFT %t1, G_CONSTANT imm2
- // -->
- // %root = SHIFT %base, G_CONSTANT (imm1 + imm2)
-
- unsigned Opcode = MI.getOpcode();
- assert((Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR ||
- Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_SSHLSAT ||
- Opcode == TargetOpcode::G_USHLSAT) &&
- "Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT");
-
- Register Shl2 = MI.getOperand(1).getReg();
- Register Imm1 = MI.getOperand(2).getReg();
- auto MaybeImmVal = getConstantVRegValWithLookThrough(Imm1, MRI);
- if (!MaybeImmVal)
- return false;
-
- MachineInstr *Shl2Def = MRI.getUniqueVRegDef(Shl2);
- if (Shl2Def->getOpcode() != Opcode)
- return false;
-
- Register Base = Shl2Def->getOperand(1).getReg();
- Register Imm2 = Shl2Def->getOperand(2).getReg();
- auto MaybeImm2Val = getConstantVRegValWithLookThrough(Imm2, MRI);
- if (!MaybeImm2Val)
- return false;
-
- // Pass the combined immediate to the apply function.
- MatchInfo.Imm =
- (MaybeImmVal->Value.getSExtValue() + MaybeImm2Val->Value).getSExtValue();
- MatchInfo.Reg = Base;
-
- // There is no simple replacement for a saturating unsigned left shift that
- // exceeds the scalar size.
- if (Opcode == TargetOpcode::G_USHLSAT &&
- MatchInfo.Imm >= MRI.getType(Shl2).getScalarSizeInBits())
- return false;
-
- return true;
-}
-
-bool CombinerHelper::applyShiftImmedChain(MachineInstr &MI,
- RegisterImmPair &MatchInfo) {
- unsigned Opcode = MI.getOpcode();
- assert((Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR ||
- Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_SSHLSAT ||
- Opcode == TargetOpcode::G_USHLSAT) &&
- "Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT");
-
- Builder.setInstrAndDebugLoc(MI);
- LLT Ty = MRI.getType(MI.getOperand(1).getReg());
- unsigned const ScalarSizeInBits = Ty.getScalarSizeInBits();
- auto Imm = MatchInfo.Imm;
-
- if (Imm >= ScalarSizeInBits) {
- // Any logical shift that exceeds scalar size will produce zero.
- if (Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_LSHR) {
- Builder.buildConstant(MI.getOperand(0), 0);
- MI.eraseFromParent();
- return true;
- }
- // Arithmetic shift and saturating signed left shift have no effect beyond
- // scalar size.
- Imm = ScalarSizeInBits - 1;
- }
-
- LLT ImmTy = MRI.getType(MI.getOperand(2).getReg());
- Register NewImm = Builder.buildConstant(ImmTy, Imm).getReg(0);
- Observer.changingInstr(MI);
- MI.getOperand(1).setReg(MatchInfo.Reg);
- MI.getOperand(2).setReg(NewImm);
- Observer.changedInstr(MI);
- return true;
-}
-
-bool CombinerHelper::matchShiftOfShiftedLogic(MachineInstr &MI,
- ShiftOfShiftedLogic &MatchInfo) {
- // We're trying to match the following pattern with any of
- // G_SHL/G_ASHR/G_LSHR/G_USHLSAT/G_SSHLSAT shift instructions in combination
- // with any of G_AND/G_OR/G_XOR logic instructions.
- // %t1 = SHIFT %X, G_CONSTANT C0
- // %t2 = LOGIC %t1, %Y
- // %root = SHIFT %t2, G_CONSTANT C1
- // -->
- // %t3 = SHIFT %X, G_CONSTANT (C0+C1)
- // %t4 = SHIFT %Y, G_CONSTANT C1
- // %root = LOGIC %t3, %t4
- unsigned ShiftOpcode = MI.getOpcode();
- assert((ShiftOpcode == TargetOpcode::G_SHL ||
- ShiftOpcode == TargetOpcode::G_ASHR ||
- ShiftOpcode == TargetOpcode::G_LSHR ||
- ShiftOpcode == TargetOpcode::G_USHLSAT ||
- ShiftOpcode == TargetOpcode::G_SSHLSAT) &&
- "Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT");
-
- // Match a one-use bitwise logic op.
- Register LogicDest = MI.getOperand(1).getReg();
- if (!MRI.hasOneNonDBGUse(LogicDest))
- return false;
-
- MachineInstr *LogicMI = MRI.getUniqueVRegDef(LogicDest);
- unsigned LogicOpcode = LogicMI->getOpcode();
- if (LogicOpcode != TargetOpcode::G_AND && LogicOpcode != TargetOpcode::G_OR &&
- LogicOpcode != TargetOpcode::G_XOR)
- return false;
-
- // Find a matching one-use shift by constant.
- const Register C1 = MI.getOperand(2).getReg();
- auto MaybeImmVal = getConstantVRegValWithLookThrough(C1, MRI);
- if (!MaybeImmVal)
- return false;
-
- const uint64_t C1Val = MaybeImmVal->Value.getZExtValue();
-
- auto matchFirstShift = [&](const MachineInstr *MI, uint64_t &ShiftVal) {
- // Shift should match previous one and should be a one-use.
- if (MI->getOpcode() != ShiftOpcode ||
- !MRI.hasOneNonDBGUse(MI->getOperand(0).getReg()))
- return false;
-
- // Must be a constant.
- auto MaybeImmVal =
- getConstantVRegValWithLookThrough(MI->getOperand(2).getReg(), MRI);
- if (!MaybeImmVal)
- return false;
-
- ShiftVal = MaybeImmVal->Value.getSExtValue();
- return true;
- };
-
- // Logic ops are commutative, so check each operand for a match.
- Register LogicMIReg1 = LogicMI->getOperand(1).getReg();
- MachineInstr *LogicMIOp1 = MRI.getUniqueVRegDef(LogicMIReg1);
- Register LogicMIReg2 = LogicMI->getOperand(2).getReg();
- MachineInstr *LogicMIOp2 = MRI.getUniqueVRegDef(LogicMIReg2);
- uint64_t C0Val;
-
- if (matchFirstShift(LogicMIOp1, C0Val)) {
- MatchInfo.LogicNonShiftReg = LogicMIReg2;
- MatchInfo.Shift2 = LogicMIOp1;
- } else if (matchFirstShift(LogicMIOp2, C0Val)) {
- MatchInfo.LogicNonShiftReg = LogicMIReg1;
- MatchInfo.Shift2 = LogicMIOp2;
- } else
- return false;
-
- MatchInfo.ValSum = C0Val + C1Val;
-
- // The fold is not valid if the sum of the shift values exceeds bitwidth.
- if (MatchInfo.ValSum >= MRI.getType(LogicDest).getScalarSizeInBits())
- return false;
-
- MatchInfo.Logic = LogicMI;
- return true;
-}
-
-bool CombinerHelper::applyShiftOfShiftedLogic(MachineInstr &MI,
- ShiftOfShiftedLogic &MatchInfo) {
- unsigned Opcode = MI.getOpcode();
- assert((Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR ||
- Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_USHLSAT ||
- Opcode == TargetOpcode::G_SSHLSAT) &&
- "Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT");
-
- LLT ShlType = MRI.getType(MI.getOperand(2).getReg());
- LLT DestType = MRI.getType(MI.getOperand(0).getReg());
- Builder.setInstrAndDebugLoc(MI);
-
- Register Const = Builder.buildConstant(ShlType, MatchInfo.ValSum).getReg(0);
-
- Register Shift1Base = MatchInfo.Shift2->getOperand(1).getReg();
- Register Shift1 =
- Builder.buildInstr(Opcode, {DestType}, {Shift1Base, Const}).getReg(0);
-
- Register Shift2Const = MI.getOperand(2).getReg();
- Register Shift2 = Builder
- .buildInstr(Opcode, {DestType},
- {MatchInfo.LogicNonShiftReg, Shift2Const})
- .getReg(0);
-
- Register Dest = MI.getOperand(0).getReg();
- Builder.buildInstr(MatchInfo.Logic->getOpcode(), {Dest}, {Shift1, Shift2});
-
- // These were one use so it's safe to remove them.
- MatchInfo.Shift2->eraseFromParent();
- MatchInfo.Logic->eraseFromParent();
-
- MI.eraseFromParent();
- return true;
-}
-
+bool CombinerHelper::matchShiftImmedChain(MachineInstr &MI,
+ RegisterImmPair &MatchInfo) {
+ // We're trying to match the following pattern with any of
+ // G_SHL/G_ASHR/G_LSHR/G_SSHLSAT/G_USHLSAT shift instructions:
+ // %t1 = SHIFT %base, G_CONSTANT imm1
+ // %root = SHIFT %t1, G_CONSTANT imm2
+ // -->
+ // %root = SHIFT %base, G_CONSTANT (imm1 + imm2)
+
+ unsigned Opcode = MI.getOpcode();
+ assert((Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR ||
+ Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_SSHLSAT ||
+ Opcode == TargetOpcode::G_USHLSAT) &&
+ "Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT");
+
+ Register Shl2 = MI.getOperand(1).getReg();
+ Register Imm1 = MI.getOperand(2).getReg();
+ auto MaybeImmVal = getConstantVRegValWithLookThrough(Imm1, MRI);
+ if (!MaybeImmVal)
+ return false;
+
+ MachineInstr *Shl2Def = MRI.getUniqueVRegDef(Shl2);
+ if (Shl2Def->getOpcode() != Opcode)
+ return false;
+
+ Register Base = Shl2Def->getOperand(1).getReg();
+ Register Imm2 = Shl2Def->getOperand(2).getReg();
+ auto MaybeImm2Val = getConstantVRegValWithLookThrough(Imm2, MRI);
+ if (!MaybeImm2Val)
+ return false;
+
+ // Pass the combined immediate to the apply function.
+ MatchInfo.Imm =
+ (MaybeImmVal->Value.getSExtValue() + MaybeImm2Val->Value).getSExtValue();
+ MatchInfo.Reg = Base;
+
+ // There is no simple replacement for a saturating unsigned left shift that
+ // exceeds the scalar size.
+ if (Opcode == TargetOpcode::G_USHLSAT &&
+ MatchInfo.Imm >= MRI.getType(Shl2).getScalarSizeInBits())
+ return false;
+
+ return true;
+}
+
+bool CombinerHelper::applyShiftImmedChain(MachineInstr &MI,
+ RegisterImmPair &MatchInfo) {
+ unsigned Opcode = MI.getOpcode();
+ assert((Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR ||
+ Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_SSHLSAT ||
+ Opcode == TargetOpcode::G_USHLSAT) &&
+ "Expected G_SHL, G_ASHR, G_LSHR, G_SSHLSAT or G_USHLSAT");
+
+ Builder.setInstrAndDebugLoc(MI);
+ LLT Ty = MRI.getType(MI.getOperand(1).getReg());
+ unsigned const ScalarSizeInBits = Ty.getScalarSizeInBits();
+ auto Imm = MatchInfo.Imm;
+
+ if (Imm >= ScalarSizeInBits) {
+ // Any logical shift that exceeds scalar size will produce zero.
+ if (Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_LSHR) {
+ Builder.buildConstant(MI.getOperand(0), 0);
+ MI.eraseFromParent();
+ return true;
+ }
+ // Arithmetic shift and saturating signed left shift have no effect beyond
+ // scalar size.
+ Imm = ScalarSizeInBits - 1;
+ }
+
+ LLT ImmTy = MRI.getType(MI.getOperand(2).getReg());
+ Register NewImm = Builder.buildConstant(ImmTy, Imm).getReg(0);
+ Observer.changingInstr(MI);
+ MI.getOperand(1).setReg(MatchInfo.Reg);
+ MI.getOperand(2).setReg(NewImm);
+ Observer.changedInstr(MI);
+ return true;
+}
+
+bool CombinerHelper::matchShiftOfShiftedLogic(MachineInstr &MI,
+ ShiftOfShiftedLogic &MatchInfo) {
+ // We're trying to match the following pattern with any of
+ // G_SHL/G_ASHR/G_LSHR/G_USHLSAT/G_SSHLSAT shift instructions in combination
+ // with any of G_AND/G_OR/G_XOR logic instructions.
+ // %t1 = SHIFT %X, G_CONSTANT C0
+ // %t2 = LOGIC %t1, %Y
+ // %root = SHIFT %t2, G_CONSTANT C1
+ // -->
+ // %t3 = SHIFT %X, G_CONSTANT (C0+C1)
+ // %t4 = SHIFT %Y, G_CONSTANT C1
+ // %root = LOGIC %t3, %t4
+ unsigned ShiftOpcode = MI.getOpcode();
+ assert((ShiftOpcode == TargetOpcode::G_SHL ||
+ ShiftOpcode == TargetOpcode::G_ASHR ||
+ ShiftOpcode == TargetOpcode::G_LSHR ||
+ ShiftOpcode == TargetOpcode::G_USHLSAT ||
+ ShiftOpcode == TargetOpcode::G_SSHLSAT) &&
+ "Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT");
+
+ // Match a one-use bitwise logic op.
+ Register LogicDest = MI.getOperand(1).getReg();
+ if (!MRI.hasOneNonDBGUse(LogicDest))
+ return false;
+
+ MachineInstr *LogicMI = MRI.getUniqueVRegDef(LogicDest);
+ unsigned LogicOpcode = LogicMI->getOpcode();
+ if (LogicOpcode != TargetOpcode::G_AND && LogicOpcode != TargetOpcode::G_OR &&
+ LogicOpcode != TargetOpcode::G_XOR)
+ return false;
+
+ // Find a matching one-use shift by constant.
+ const Register C1 = MI.getOperand(2).getReg();
+ auto MaybeImmVal = getConstantVRegValWithLookThrough(C1, MRI);
+ if (!MaybeImmVal)
+ return false;
+
+ const uint64_t C1Val = MaybeImmVal->Value.getZExtValue();
+
+ auto matchFirstShift = [&](const MachineInstr *MI, uint64_t &ShiftVal) {
+ // Shift should match previous one and should be a one-use.
+ if (MI->getOpcode() != ShiftOpcode ||
+ !MRI.hasOneNonDBGUse(MI->getOperand(0).getReg()))
+ return false;
+
+ // Must be a constant.
+ auto MaybeImmVal =
+ getConstantVRegValWithLookThrough(MI->getOperand(2).getReg(), MRI);
+ if (!MaybeImmVal)
+ return false;
+
+ ShiftVal = MaybeImmVal->Value.getSExtValue();
+ return true;
+ };
+
+ // Logic ops are commutative, so check each operand for a match.
+ Register LogicMIReg1 = LogicMI->getOperand(1).getReg();
+ MachineInstr *LogicMIOp1 = MRI.getUniqueVRegDef(LogicMIReg1);
+ Register LogicMIReg2 = LogicMI->getOperand(2).getReg();
+ MachineInstr *LogicMIOp2 = MRI.getUniqueVRegDef(LogicMIReg2);
+ uint64_t C0Val;
+
+ if (matchFirstShift(LogicMIOp1, C0Val)) {
+ MatchInfo.LogicNonShiftReg = LogicMIReg2;
+ MatchInfo.Shift2 = LogicMIOp1;
+ } else if (matchFirstShift(LogicMIOp2, C0Val)) {
+ MatchInfo.LogicNonShiftReg = LogicMIReg1;
+ MatchInfo.Shift2 = LogicMIOp2;
+ } else
+ return false;
+
+ MatchInfo.ValSum = C0Val + C1Val;
+
+ // The fold is not valid if the sum of the shift values exceeds bitwidth.
+ if (MatchInfo.ValSum >= MRI.getType(LogicDest).getScalarSizeInBits())
+ return false;
+
+ MatchInfo.Logic = LogicMI;
+ return true;
+}
+
+bool CombinerHelper::applyShiftOfShiftedLogic(MachineInstr &MI,
+ ShiftOfShiftedLogic &MatchInfo) {
+ unsigned Opcode = MI.getOpcode();
+ assert((Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_ASHR ||
+ Opcode == TargetOpcode::G_LSHR || Opcode == TargetOpcode::G_USHLSAT ||
+ Opcode == TargetOpcode::G_SSHLSAT) &&
+ "Expected G_SHL, G_ASHR, G_LSHR, G_USHLSAT and G_SSHLSAT");
+
+ LLT ShlType = MRI.getType(MI.getOperand(2).getReg());
+ LLT DestType = MRI.getType(MI.getOperand(0).getReg());
+ Builder.setInstrAndDebugLoc(MI);
+
+ Register Const = Builder.buildConstant(ShlType, MatchInfo.ValSum).getReg(0);
+
+ Register Shift1Base = MatchInfo.Shift2->getOperand(1).getReg();
+ Register Shift1 =
+ Builder.buildInstr(Opcode, {DestType}, {Shift1Base, Const}).getReg(0);
+
+ Register Shift2Const = MI.getOperand(2).getReg();
+ Register Shift2 = Builder
+ .buildInstr(Opcode, {DestType},
+ {MatchInfo.LogicNonShiftReg, Shift2Const})
+ .getReg(0);
+
+ Register Dest = MI.getOperand(0).getReg();
+ Builder.buildInstr(MatchInfo.Logic->getOpcode(), {Dest}, {Shift1, Shift2});
+
+ // These were one use so it's safe to remove them.
+ MatchInfo.Shift2->eraseFromParent();
+ MatchInfo.Logic->eraseFromParent();
+
+ MI.eraseFromParent();
+ return true;
+}
+
bool CombinerHelper::matchCombineMulToShl(MachineInstr &MI,
unsigned &ShiftVal) {
assert(MI.getOpcode() == TargetOpcode::G_MUL && "Expected a G_MUL");
auto MaybeImmVal =
getConstantVRegValWithLookThrough(MI.getOperand(2).getReg(), MRI);
- if (!MaybeImmVal)
+ if (!MaybeImmVal)
return false;
-
- ShiftVal = MaybeImmVal->Value.exactLogBase2();
- return (static_cast<int32_t>(ShiftVal) != -1);
+
+ ShiftVal = MaybeImmVal->Value.exactLogBase2();
+ return (static_cast<int32_t>(ShiftVal) != -1);
}
bool CombinerHelper::applyCombineMulToShl(MachineInstr &MI,
@@ -1819,254 +1819,254 @@ bool CombinerHelper::applyCombineMulToShl(MachineInstr &MI,
return true;
}
-// shl ([sza]ext x), y => zext (shl x, y), if shift does not overflow source
-bool CombinerHelper::matchCombineShlOfExtend(MachineInstr &MI,
- RegisterImmPair &MatchData) {
- assert(MI.getOpcode() == TargetOpcode::G_SHL && KB);
-
- Register LHS = MI.getOperand(1).getReg();
-
- Register ExtSrc;
- if (!mi_match(LHS, MRI, m_GAnyExt(m_Reg(ExtSrc))) &&
- !mi_match(LHS, MRI, m_GZExt(m_Reg(ExtSrc))) &&
- !mi_match(LHS, MRI, m_GSExt(m_Reg(ExtSrc))))
- return false;
-
- // TODO: Should handle vector splat.
- Register RHS = MI.getOperand(2).getReg();
- auto MaybeShiftAmtVal = getConstantVRegValWithLookThrough(RHS, MRI);
- if (!MaybeShiftAmtVal)
- return false;
-
- if (LI) {
- LLT SrcTy = MRI.getType(ExtSrc);
-
- // We only really care about the legality with the shifted value. We can
- // pick any type the constant shift amount, so ask the target what to
- // use. Otherwise we would have to guess and hope it is reported as legal.
- LLT ShiftAmtTy = getTargetLowering().getPreferredShiftAmountTy(SrcTy);
- if (!isLegalOrBeforeLegalizer({TargetOpcode::G_SHL, {SrcTy, ShiftAmtTy}}))
- return false;
- }
-
- int64_t ShiftAmt = MaybeShiftAmtVal->Value.getSExtValue();
- MatchData.Reg = ExtSrc;
- MatchData.Imm = ShiftAmt;
-
- unsigned MinLeadingZeros = KB->getKnownZeroes(ExtSrc).countLeadingOnes();
- return MinLeadingZeros >= ShiftAmt;
-}
-
-bool CombinerHelper::applyCombineShlOfExtend(MachineInstr &MI,
- const RegisterImmPair &MatchData) {
- Register ExtSrcReg = MatchData.Reg;
- int64_t ShiftAmtVal = MatchData.Imm;
-
- LLT ExtSrcTy = MRI.getType(ExtSrcReg);
- Builder.setInstrAndDebugLoc(MI);
- auto ShiftAmt = Builder.buildConstant(ExtSrcTy, ShiftAmtVal);
- auto NarrowShift =
- Builder.buildShl(ExtSrcTy, ExtSrcReg, ShiftAmt, MI.getFlags());
- Builder.buildZExt(MI.getOperand(0), NarrowShift);
- MI.eraseFromParent();
- return true;
-}
-
-static Register peekThroughBitcast(Register Reg,
- const MachineRegisterInfo &MRI) {
- while (mi_match(Reg, MRI, m_GBitcast(m_Reg(Reg))))
- ;
-
- return Reg;
-}
-
-bool CombinerHelper::matchCombineUnmergeMergeToPlainValues(
- MachineInstr &MI, SmallVectorImpl<Register> &Operands) {
- assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&
- "Expected an unmerge");
- Register SrcReg =
- peekThroughBitcast(MI.getOperand(MI.getNumOperands() - 1).getReg(), MRI);
-
- MachineInstr *SrcInstr = MRI.getVRegDef(SrcReg);
- if (SrcInstr->getOpcode() != TargetOpcode::G_MERGE_VALUES &&
- SrcInstr->getOpcode() != TargetOpcode::G_BUILD_VECTOR &&
- SrcInstr->getOpcode() != TargetOpcode::G_CONCAT_VECTORS)
- return false;
-
- // Check the source type of the merge.
- LLT SrcMergeTy = MRI.getType(SrcInstr->getOperand(1).getReg());
- LLT Dst0Ty = MRI.getType(MI.getOperand(0).getReg());
- bool SameSize = Dst0Ty.getSizeInBits() == SrcMergeTy.getSizeInBits();
- if (SrcMergeTy != Dst0Ty && !SameSize)
- return false;
- // They are the same now (modulo a bitcast).
- // We can collect all the src registers.
- for (unsigned Idx = 1, EndIdx = SrcInstr->getNumOperands(); Idx != EndIdx;
- ++Idx)
- Operands.push_back(SrcInstr->getOperand(Idx).getReg());
- return true;
-}
-
-bool CombinerHelper::applyCombineUnmergeMergeToPlainValues(
- MachineInstr &MI, SmallVectorImpl<Register> &Operands) {
- assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&
- "Expected an unmerge");
- assert((MI.getNumOperands() - 1 == Operands.size()) &&
- "Not enough operands to replace all defs");
- unsigned NumElems = MI.getNumOperands() - 1;
-
- LLT SrcTy = MRI.getType(Operands[0]);
- LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
- bool CanReuseInputDirectly = DstTy == SrcTy;
- Builder.setInstrAndDebugLoc(MI);
- for (unsigned Idx = 0; Idx < NumElems; ++Idx) {
- Register DstReg = MI.getOperand(Idx).getReg();
- Register SrcReg = Operands[Idx];
- if (CanReuseInputDirectly)
- replaceRegWith(MRI, DstReg, SrcReg);
- else
- Builder.buildCast(DstReg, SrcReg);
- }
- MI.eraseFromParent();
- return true;
-}
-
-bool CombinerHelper::matchCombineUnmergeConstant(MachineInstr &MI,
- SmallVectorImpl<APInt> &Csts) {
- unsigned SrcIdx = MI.getNumOperands() - 1;
- Register SrcReg = MI.getOperand(SrcIdx).getReg();
- MachineInstr *SrcInstr = MRI.getVRegDef(SrcReg);
- if (SrcInstr->getOpcode() != TargetOpcode::G_CONSTANT &&
- SrcInstr->getOpcode() != TargetOpcode::G_FCONSTANT)
- return false;
- // Break down the big constant in smaller ones.
- const MachineOperand &CstVal = SrcInstr->getOperand(1);
- APInt Val = SrcInstr->getOpcode() == TargetOpcode::G_CONSTANT
- ? CstVal.getCImm()->getValue()
- : CstVal.getFPImm()->getValueAPF().bitcastToAPInt();
-
- LLT Dst0Ty = MRI.getType(MI.getOperand(0).getReg());
- unsigned ShiftAmt = Dst0Ty.getSizeInBits();
- // Unmerge a constant.
- for (unsigned Idx = 0; Idx != SrcIdx; ++Idx) {
- Csts.emplace_back(Val.trunc(ShiftAmt));
- Val = Val.lshr(ShiftAmt);
- }
-
- return true;
-}
-
-bool CombinerHelper::applyCombineUnmergeConstant(MachineInstr &MI,
- SmallVectorImpl<APInt> &Csts) {
- assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&
- "Expected an unmerge");
- assert((MI.getNumOperands() - 1 == Csts.size()) &&
- "Not enough operands to replace all defs");
- unsigned NumElems = MI.getNumOperands() - 1;
- Builder.setInstrAndDebugLoc(MI);
- for (unsigned Idx = 0; Idx < NumElems; ++Idx) {
- Register DstReg = MI.getOperand(Idx).getReg();
- Builder.buildConstant(DstReg, Csts[Idx]);
- }
-
- MI.eraseFromParent();
- return true;
-}
-
-bool CombinerHelper::matchCombineUnmergeWithDeadLanesToTrunc(MachineInstr &MI) {
- assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&
- "Expected an unmerge");
- // Check that all the lanes are dead except the first one.
- for (unsigned Idx = 1, EndIdx = MI.getNumDefs(); Idx != EndIdx; ++Idx) {
- if (!MRI.use_nodbg_empty(MI.getOperand(Idx).getReg()))
- return false;
- }
- return true;
-}
-
-bool CombinerHelper::applyCombineUnmergeWithDeadLanesToTrunc(MachineInstr &MI) {
- Builder.setInstrAndDebugLoc(MI);
- Register SrcReg = MI.getOperand(MI.getNumDefs()).getReg();
- // Truncating a vector is going to truncate every single lane,
- // whereas we want the full lowbits.
- // Do the operation on a scalar instead.
- LLT SrcTy = MRI.getType(SrcReg);
- if (SrcTy.isVector())
- SrcReg =
- Builder.buildCast(LLT::scalar(SrcTy.getSizeInBits()), SrcReg).getReg(0);
-
- Register Dst0Reg = MI.getOperand(0).getReg();
- LLT Dst0Ty = MRI.getType(Dst0Reg);
- if (Dst0Ty.isVector()) {
- auto MIB = Builder.buildTrunc(LLT::scalar(Dst0Ty.getSizeInBits()), SrcReg);
- Builder.buildCast(Dst0Reg, MIB);
- } else
- Builder.buildTrunc(Dst0Reg, SrcReg);
- MI.eraseFromParent();
- return true;
-}
-
-bool CombinerHelper::matchCombineUnmergeZExtToZExt(MachineInstr &MI) {
- assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&
- "Expected an unmerge");
- Register Dst0Reg = MI.getOperand(0).getReg();
- LLT Dst0Ty = MRI.getType(Dst0Reg);
- // G_ZEXT on vector applies to each lane, so it will
- // affect all destinations. Therefore we won't be able
- // to simplify the unmerge to just the first definition.
- if (Dst0Ty.isVector())
- return false;
- Register SrcReg = MI.getOperand(MI.getNumDefs()).getReg();
- LLT SrcTy = MRI.getType(SrcReg);
- if (SrcTy.isVector())
- return false;
-
- Register ZExtSrcReg;
- if (!mi_match(SrcReg, MRI, m_GZExt(m_Reg(ZExtSrcReg))))
- return false;
-
- // Finally we can replace the first definition with
- // a zext of the source if the definition is big enough to hold
- // all of ZExtSrc bits.
- LLT ZExtSrcTy = MRI.getType(ZExtSrcReg);
- return ZExtSrcTy.getSizeInBits() <= Dst0Ty.getSizeInBits();
-}
-
-bool CombinerHelper::applyCombineUnmergeZExtToZExt(MachineInstr &MI) {
- assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&
- "Expected an unmerge");
-
- Register Dst0Reg = MI.getOperand(0).getReg();
-
- MachineInstr *ZExtInstr =
- MRI.getVRegDef(MI.getOperand(MI.getNumDefs()).getReg());
- assert(ZExtInstr && ZExtInstr->getOpcode() == TargetOpcode::G_ZEXT &&
- "Expecting a G_ZEXT");
-
- Register ZExtSrcReg = ZExtInstr->getOperand(1).getReg();
- LLT Dst0Ty = MRI.getType(Dst0Reg);
- LLT ZExtSrcTy = MRI.getType(ZExtSrcReg);
-
- Builder.setInstrAndDebugLoc(MI);
-
- if (Dst0Ty.getSizeInBits() > ZExtSrcTy.getSizeInBits()) {
- Builder.buildZExt(Dst0Reg, ZExtSrcReg);
- } else {
- assert(Dst0Ty.getSizeInBits() == ZExtSrcTy.getSizeInBits() &&
- "ZExt src doesn't fit in destination");
- replaceRegWith(MRI, Dst0Reg, ZExtSrcReg);
- }
-
- Register ZeroReg;
- for (unsigned Idx = 1, EndIdx = MI.getNumDefs(); Idx != EndIdx; ++Idx) {
- if (!ZeroReg)
- ZeroReg = Builder.buildConstant(Dst0Ty, 0).getReg(0);
- replaceRegWith(MRI, MI.getOperand(Idx).getReg(), ZeroReg);
- }
- MI.eraseFromParent();
- return true;
-}
-
+// shl ([sza]ext x), y => zext (shl x, y), if shift does not overflow source
+bool CombinerHelper::matchCombineShlOfExtend(MachineInstr &MI,
+ RegisterImmPair &MatchData) {
+ assert(MI.getOpcode() == TargetOpcode::G_SHL && KB);
+
+ Register LHS = MI.getOperand(1).getReg();
+
+ Register ExtSrc;
+ if (!mi_match(LHS, MRI, m_GAnyExt(m_Reg(ExtSrc))) &&
+ !mi_match(LHS, MRI, m_GZExt(m_Reg(ExtSrc))) &&
+ !mi_match(LHS, MRI, m_GSExt(m_Reg(ExtSrc))))
+ return false;
+
+ // TODO: Should handle vector splat.
+ Register RHS = MI.getOperand(2).getReg();
+ auto MaybeShiftAmtVal = getConstantVRegValWithLookThrough(RHS, MRI);
+ if (!MaybeShiftAmtVal)
+ return false;
+
+ if (LI) {
+ LLT SrcTy = MRI.getType(ExtSrc);
+
+ // We only really care about the legality with the shifted value. We can
+ // pick any type the constant shift amount, so ask the target what to
+ // use. Otherwise we would have to guess and hope it is reported as legal.
+ LLT ShiftAmtTy = getTargetLowering().getPreferredShiftAmountTy(SrcTy);
+ if (!isLegalOrBeforeLegalizer({TargetOpcode::G_SHL, {SrcTy, ShiftAmtTy}}))
+ return false;
+ }
+
+ int64_t ShiftAmt = MaybeShiftAmtVal->Value.getSExtValue();
+ MatchData.Reg = ExtSrc;
+ MatchData.Imm = ShiftAmt;
+
+ unsigned MinLeadingZeros = KB->getKnownZeroes(ExtSrc).countLeadingOnes();
+ return MinLeadingZeros >= ShiftAmt;
+}
+
+bool CombinerHelper::applyCombineShlOfExtend(MachineInstr &MI,
+ const RegisterImmPair &MatchData) {
+ Register ExtSrcReg = MatchData.Reg;
+ int64_t ShiftAmtVal = MatchData.Imm;
+
+ LLT ExtSrcTy = MRI.getType(ExtSrcReg);
+ Builder.setInstrAndDebugLoc(MI);
+ auto ShiftAmt = Builder.buildConstant(ExtSrcTy, ShiftAmtVal);
+ auto NarrowShift =
+ Builder.buildShl(ExtSrcTy, ExtSrcReg, ShiftAmt, MI.getFlags());
+ Builder.buildZExt(MI.getOperand(0), NarrowShift);
+ MI.eraseFromParent();
+ return true;
+}
+
+static Register peekThroughBitcast(Register Reg,
+ const MachineRegisterInfo &MRI) {
+ while (mi_match(Reg, MRI, m_GBitcast(m_Reg(Reg))))
+ ;
+
+ return Reg;
+}
+
+bool CombinerHelper::matchCombineUnmergeMergeToPlainValues(
+ MachineInstr &MI, SmallVectorImpl<Register> &Operands) {
+ assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&
+ "Expected an unmerge");
+ Register SrcReg =
+ peekThroughBitcast(MI.getOperand(MI.getNumOperands() - 1).getReg(), MRI);
+
+ MachineInstr *SrcInstr = MRI.getVRegDef(SrcReg);
+ if (SrcInstr->getOpcode() != TargetOpcode::G_MERGE_VALUES &&
+ SrcInstr->getOpcode() != TargetOpcode::G_BUILD_VECTOR &&
+ SrcInstr->getOpcode() != TargetOpcode::G_CONCAT_VECTORS)
+ return false;
+
+ // Check the source type of the merge.
+ LLT SrcMergeTy = MRI.getType(SrcInstr->getOperand(1).getReg());
+ LLT Dst0Ty = MRI.getType(MI.getOperand(0).getReg());
+ bool SameSize = Dst0Ty.getSizeInBits() == SrcMergeTy.getSizeInBits();
+ if (SrcMergeTy != Dst0Ty && !SameSize)
+ return false;
+ // They are the same now (modulo a bitcast).
+ // We can collect all the src registers.
+ for (unsigned Idx = 1, EndIdx = SrcInstr->getNumOperands(); Idx != EndIdx;
+ ++Idx)
+ Operands.push_back(SrcInstr->getOperand(Idx).getReg());
+ return true;
+}
+
+bool CombinerHelper::applyCombineUnmergeMergeToPlainValues(
+ MachineInstr &MI, SmallVectorImpl<Register> &Operands) {
+ assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&
+ "Expected an unmerge");
+ assert((MI.getNumOperands() - 1 == Operands.size()) &&
+ "Not enough operands to replace all defs");
+ unsigned NumElems = MI.getNumOperands() - 1;
+
+ LLT SrcTy = MRI.getType(Operands[0]);
+ LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
+ bool CanReuseInputDirectly = DstTy == SrcTy;
+ Builder.setInstrAndDebugLoc(MI);
+ for (unsigned Idx = 0; Idx < NumElems; ++Idx) {
+ Register DstReg = MI.getOperand(Idx).getReg();
+ Register SrcReg = Operands[Idx];
+ if (CanReuseInputDirectly)
+ replaceRegWith(MRI, DstReg, SrcReg);
+ else
+ Builder.buildCast(DstReg, SrcReg);
+ }
+ MI.eraseFromParent();
+ return true;
+}
+
+bool CombinerHelper::matchCombineUnmergeConstant(MachineInstr &MI,
+ SmallVectorImpl<APInt> &Csts) {
+ unsigned SrcIdx = MI.getNumOperands() - 1;
+ Register SrcReg = MI.getOperand(SrcIdx).getReg();
+ MachineInstr *SrcInstr = MRI.getVRegDef(SrcReg);
+ if (SrcInstr->getOpcode() != TargetOpcode::G_CONSTANT &&
+ SrcInstr->getOpcode() != TargetOpcode::G_FCONSTANT)
+ return false;
+ // Break down the big constant in smaller ones.
+ const MachineOperand &CstVal = SrcInstr->getOperand(1);
+ APInt Val = SrcInstr->getOpcode() == TargetOpcode::G_CONSTANT
+ ? CstVal.getCImm()->getValue()
+ : CstVal.getFPImm()->getValueAPF().bitcastToAPInt();
+
+ LLT Dst0Ty = MRI.getType(MI.getOperand(0).getReg());
+ unsigned ShiftAmt = Dst0Ty.getSizeInBits();
+ // Unmerge a constant.
+ for (unsigned Idx = 0; Idx != SrcIdx; ++Idx) {
+ Csts.emplace_back(Val.trunc(ShiftAmt));
+ Val = Val.lshr(ShiftAmt);
+ }
+
+ return true;
+}
+
+bool CombinerHelper::applyCombineUnmergeConstant(MachineInstr &MI,
+ SmallVectorImpl<APInt> &Csts) {
+ assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&
+ "Expected an unmerge");
+ assert((MI.getNumOperands() - 1 == Csts.size()) &&
+ "Not enough operands to replace all defs");
+ unsigned NumElems = MI.getNumOperands() - 1;
+ Builder.setInstrAndDebugLoc(MI);
+ for (unsigned Idx = 0; Idx < NumElems; ++Idx) {
+ Register DstReg = MI.getOperand(Idx).getReg();
+ Builder.buildConstant(DstReg, Csts[Idx]);
+ }
+
+ MI.eraseFromParent();
+ return true;
+}
+
+bool CombinerHelper::matchCombineUnmergeWithDeadLanesToTrunc(MachineInstr &MI) {
+ assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&
+ "Expected an unmerge");
+ // Check that all the lanes are dead except the first one.
+ for (unsigned Idx = 1, EndIdx = MI.getNumDefs(); Idx != EndIdx; ++Idx) {
+ if (!MRI.use_nodbg_empty(MI.getOperand(Idx).getReg()))
+ return false;
+ }
+ return true;
+}
+
+bool CombinerHelper::applyCombineUnmergeWithDeadLanesToTrunc(MachineInstr &MI) {
+ Builder.setInstrAndDebugLoc(MI);
+ Register SrcReg = MI.getOperand(MI.getNumDefs()).getReg();
+ // Truncating a vector is going to truncate every single lane,
+ // whereas we want the full lowbits.
+ // Do the operation on a scalar instead.
+ LLT SrcTy = MRI.getType(SrcReg);
+ if (SrcTy.isVector())
+ SrcReg =
+ Builder.buildCast(LLT::scalar(SrcTy.getSizeInBits()), SrcReg).getReg(0);
+
+ Register Dst0Reg = MI.getOperand(0).getReg();
+ LLT Dst0Ty = MRI.getType(Dst0Reg);
+ if (Dst0Ty.isVector()) {
+ auto MIB = Builder.buildTrunc(LLT::scalar(Dst0Ty.getSizeInBits()), SrcReg);
+ Builder.buildCast(Dst0Reg, MIB);
+ } else
+ Builder.buildTrunc(Dst0Reg, SrcReg);
+ MI.eraseFromParent();
+ return true;
+}
+
+bool CombinerHelper::matchCombineUnmergeZExtToZExt(MachineInstr &MI) {
+ assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&
+ "Expected an unmerge");
+ Register Dst0Reg = MI.getOperand(0).getReg();
+ LLT Dst0Ty = MRI.getType(Dst0Reg);
+ // G_ZEXT on vector applies to each lane, so it will
+ // affect all destinations. Therefore we won't be able
+ // to simplify the unmerge to just the first definition.
+ if (Dst0Ty.isVector())
+ return false;
+ Register SrcReg = MI.getOperand(MI.getNumDefs()).getReg();
+ LLT SrcTy = MRI.getType(SrcReg);
+ if (SrcTy.isVector())
+ return false;
+
+ Register ZExtSrcReg;
+ if (!mi_match(SrcReg, MRI, m_GZExt(m_Reg(ZExtSrcReg))))
+ return false;
+
+ // Finally we can replace the first definition with
+ // a zext of the source if the definition is big enough to hold
+ // all of ZExtSrc bits.
+ LLT ZExtSrcTy = MRI.getType(ZExtSrcReg);
+ return ZExtSrcTy.getSizeInBits() <= Dst0Ty.getSizeInBits();
+}
+
+bool CombinerHelper::applyCombineUnmergeZExtToZExt(MachineInstr &MI) {
+ assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&
+ "Expected an unmerge");
+
+ Register Dst0Reg = MI.getOperand(0).getReg();
+
+ MachineInstr *ZExtInstr =
+ MRI.getVRegDef(MI.getOperand(MI.getNumDefs()).getReg());
+ assert(ZExtInstr && ZExtInstr->getOpcode() == TargetOpcode::G_ZEXT &&
+ "Expecting a G_ZEXT");
+
+ Register ZExtSrcReg = ZExtInstr->getOperand(1).getReg();
+ LLT Dst0Ty = MRI.getType(Dst0Reg);
+ LLT ZExtSrcTy = MRI.getType(ZExtSrcReg);
+
+ Builder.setInstrAndDebugLoc(MI);
+
+ if (Dst0Ty.getSizeInBits() > ZExtSrcTy.getSizeInBits()) {
+ Builder.buildZExt(Dst0Reg, ZExtSrcReg);
+ } else {
+ assert(Dst0Ty.getSizeInBits() == ZExtSrcTy.getSizeInBits() &&
+ "ZExt src doesn't fit in destination");
+ replaceRegWith(MRI, Dst0Reg, ZExtSrcReg);
+ }
+
+ Register ZeroReg;
+ for (unsigned Idx = 1, EndIdx = MI.getNumDefs(); Idx != EndIdx; ++Idx) {
+ if (!ZeroReg)
+ ZeroReg = Builder.buildConstant(Dst0Ty, 0).getReg(0);
+ replaceRegWith(MRI, MI.getOperand(Idx).getReg(), ZeroReg);
+ }
+ MI.eraseFromParent();
+ return true;
+}
+
bool CombinerHelper::matchCombineShiftToUnmerge(MachineInstr &MI,
unsigned TargetShiftSize,
unsigned &ShiftVal) {
@@ -2088,7 +2088,7 @@ bool CombinerHelper::matchCombineShiftToUnmerge(MachineInstr &MI,
if (!MaybeImmVal)
return false;
- ShiftVal = MaybeImmVal->Value.getSExtValue();
+ ShiftVal = MaybeImmVal->Value.getSExtValue();
return ShiftVal >= Size / 2 && ShiftVal < Size;
}
@@ -2177,296 +2177,296 @@ bool CombinerHelper::tryCombineShiftToUnmerge(MachineInstr &MI,
return false;
}
-bool CombinerHelper::matchCombineI2PToP2I(MachineInstr &MI, Register &Reg) {
- assert(MI.getOpcode() == TargetOpcode::G_INTTOPTR && "Expected a G_INTTOPTR");
- Register DstReg = MI.getOperand(0).getReg();
- LLT DstTy = MRI.getType(DstReg);
- Register SrcReg = MI.getOperand(1).getReg();
- return mi_match(SrcReg, MRI,
- m_GPtrToInt(m_all_of(m_SpecificType(DstTy), m_Reg(Reg))));
-}
-
-bool CombinerHelper::applyCombineI2PToP2I(MachineInstr &MI, Register &Reg) {
- assert(MI.getOpcode() == TargetOpcode::G_INTTOPTR && "Expected a G_INTTOPTR");
- Register DstReg = MI.getOperand(0).getReg();
- Builder.setInstr(MI);
- Builder.buildCopy(DstReg, Reg);
- MI.eraseFromParent();
- return true;
-}
-
-bool CombinerHelper::matchCombineP2IToI2P(MachineInstr &MI, Register &Reg) {
- assert(MI.getOpcode() == TargetOpcode::G_PTRTOINT && "Expected a G_PTRTOINT");
- Register SrcReg = MI.getOperand(1).getReg();
- return mi_match(SrcReg, MRI, m_GIntToPtr(m_Reg(Reg)));
-}
-
-bool CombinerHelper::applyCombineP2IToI2P(MachineInstr &MI, Register &Reg) {
- assert(MI.getOpcode() == TargetOpcode::G_PTRTOINT && "Expected a G_PTRTOINT");
- Register DstReg = MI.getOperand(0).getReg();
- Builder.setInstr(MI);
- Builder.buildZExtOrTrunc(DstReg, Reg);
- MI.eraseFromParent();
- return true;
-}
-
-bool CombinerHelper::matchCombineAddP2IToPtrAdd(
- MachineInstr &MI, std::pair<Register, bool> &PtrReg) {
- assert(MI.getOpcode() == TargetOpcode::G_ADD);
- Register LHS = MI.getOperand(1).getReg();
- Register RHS = MI.getOperand(2).getReg();
- LLT IntTy = MRI.getType(LHS);
-
- // G_PTR_ADD always has the pointer in the LHS, so we may need to commute the
- // instruction.
- PtrReg.second = false;
- for (Register SrcReg : {LHS, RHS}) {
- if (mi_match(SrcReg, MRI, m_GPtrToInt(m_Reg(PtrReg.first)))) {
- // Don't handle cases where the integer is implicitly converted to the
- // pointer width.
- LLT PtrTy = MRI.getType(PtrReg.first);
- if (PtrTy.getScalarSizeInBits() == IntTy.getScalarSizeInBits())
- return true;
- }
-
- PtrReg.second = true;
- }
-
- return false;
-}
-
-bool CombinerHelper::applyCombineAddP2IToPtrAdd(
- MachineInstr &MI, std::pair<Register, bool> &PtrReg) {
- Register Dst = MI.getOperand(0).getReg();
- Register LHS = MI.getOperand(1).getReg();
- Register RHS = MI.getOperand(2).getReg();
-
- const bool DoCommute = PtrReg.second;
- if (DoCommute)
- std::swap(LHS, RHS);
- LHS = PtrReg.first;
-
- LLT PtrTy = MRI.getType(LHS);
-
- Builder.setInstrAndDebugLoc(MI);
- auto PtrAdd = Builder.buildPtrAdd(PtrTy, LHS, RHS);
- Builder.buildPtrToInt(Dst, PtrAdd);
- MI.eraseFromParent();
- return true;
-}
-
-bool CombinerHelper::matchCombineConstPtrAddToI2P(MachineInstr &MI,
- int64_t &NewCst) {
- assert(MI.getOpcode() == TargetOpcode::G_PTR_ADD && "Expected a G_PTR_ADD");
- Register LHS = MI.getOperand(1).getReg();
- Register RHS = MI.getOperand(2).getReg();
- MachineRegisterInfo &MRI = Builder.getMF().getRegInfo();
-
- if (auto RHSCst = getConstantVRegSExtVal(RHS, MRI)) {
- int64_t Cst;
- if (mi_match(LHS, MRI, m_GIntToPtr(m_ICst(Cst)))) {
- NewCst = Cst + *RHSCst;
- return true;
- }
- }
-
- return false;
-}
-
-bool CombinerHelper::applyCombineConstPtrAddToI2P(MachineInstr &MI,
- int64_t &NewCst) {
- assert(MI.getOpcode() == TargetOpcode::G_PTR_ADD && "Expected a G_PTR_ADD");
- Register Dst = MI.getOperand(0).getReg();
-
- Builder.setInstrAndDebugLoc(MI);
- Builder.buildConstant(Dst, NewCst);
- MI.eraseFromParent();
- return true;
-}
-
-bool CombinerHelper::matchCombineAnyExtTrunc(MachineInstr &MI, Register &Reg) {
- assert(MI.getOpcode() == TargetOpcode::G_ANYEXT && "Expected a G_ANYEXT");
- Register DstReg = MI.getOperand(0).getReg();
- Register SrcReg = MI.getOperand(1).getReg();
- LLT DstTy = MRI.getType(DstReg);
- return mi_match(SrcReg, MRI,
- m_GTrunc(m_all_of(m_Reg(Reg), m_SpecificType(DstTy))));
-}
-
-bool CombinerHelper::applyCombineAnyExtTrunc(MachineInstr &MI, Register &Reg) {
- assert(MI.getOpcode() == TargetOpcode::G_ANYEXT && "Expected a G_ANYEXT");
- Register DstReg = MI.getOperand(0).getReg();
- MI.eraseFromParent();
- replaceRegWith(MRI, DstReg, Reg);
- return true;
-}
-
-bool CombinerHelper::matchCombineExtOfExt(
- MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo) {
- assert((MI.getOpcode() == TargetOpcode::G_ANYEXT ||
- MI.getOpcode() == TargetOpcode::G_SEXT ||
- MI.getOpcode() == TargetOpcode::G_ZEXT) &&
- "Expected a G_[ASZ]EXT");
- Register SrcReg = MI.getOperand(1).getReg();
- MachineInstr *SrcMI = MRI.getVRegDef(SrcReg);
- // Match exts with the same opcode, anyext([sz]ext) and sext(zext).
- unsigned Opc = MI.getOpcode();
- unsigned SrcOpc = SrcMI->getOpcode();
- if (Opc == SrcOpc ||
- (Opc == TargetOpcode::G_ANYEXT &&
- (SrcOpc == TargetOpcode::G_SEXT || SrcOpc == TargetOpcode::G_ZEXT)) ||
- (Opc == TargetOpcode::G_SEXT && SrcOpc == TargetOpcode::G_ZEXT)) {
- MatchInfo = std::make_tuple(SrcMI->getOperand(1).getReg(), SrcOpc);
- return true;
- }
- return false;
-}
-
-bool CombinerHelper::applyCombineExtOfExt(
- MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo) {
- assert((MI.getOpcode() == TargetOpcode::G_ANYEXT ||
- MI.getOpcode() == TargetOpcode::G_SEXT ||
- MI.getOpcode() == TargetOpcode::G_ZEXT) &&
- "Expected a G_[ASZ]EXT");
-
- Register Reg = std::get<0>(MatchInfo);
- unsigned SrcExtOp = std::get<1>(MatchInfo);
-
- // Combine exts with the same opcode.
- if (MI.getOpcode() == SrcExtOp) {
- Observer.changingInstr(MI);
- MI.getOperand(1).setReg(Reg);
- Observer.changedInstr(MI);
- return true;
- }
-
- // Combine:
- // - anyext([sz]ext x) to [sz]ext x
- // - sext(zext x) to zext x
- if (MI.getOpcode() == TargetOpcode::G_ANYEXT ||
- (MI.getOpcode() == TargetOpcode::G_SEXT &&
- SrcExtOp == TargetOpcode::G_ZEXT)) {
- Register DstReg = MI.getOperand(0).getReg();
- Builder.setInstrAndDebugLoc(MI);
- Builder.buildInstr(SrcExtOp, {DstReg}, {Reg});
- MI.eraseFromParent();
- return true;
- }
-
- return false;
-}
-
-bool CombinerHelper::applyCombineMulByNegativeOne(MachineInstr &MI) {
- assert(MI.getOpcode() == TargetOpcode::G_MUL && "Expected a G_MUL");
- Register DstReg = MI.getOperand(0).getReg();
- Register SrcReg = MI.getOperand(1).getReg();
- LLT DstTy = MRI.getType(DstReg);
-
- Builder.setInstrAndDebugLoc(MI);
- Builder.buildSub(DstReg, Builder.buildConstant(DstTy, 0), SrcReg,
- MI.getFlags());
- MI.eraseFromParent();
- return true;
-}
-
-bool CombinerHelper::matchCombineFNegOfFNeg(MachineInstr &MI, Register &Reg) {
- assert(MI.getOpcode() == TargetOpcode::G_FNEG && "Expected a G_FNEG");
- Register SrcReg = MI.getOperand(1).getReg();
- return mi_match(SrcReg, MRI, m_GFNeg(m_Reg(Reg)));
-}
-
-bool CombinerHelper::matchCombineFAbsOfFAbs(MachineInstr &MI, Register &Src) {
- assert(MI.getOpcode() == TargetOpcode::G_FABS && "Expected a G_FABS");
- Src = MI.getOperand(1).getReg();
- Register AbsSrc;
- return mi_match(Src, MRI, m_GFabs(m_Reg(AbsSrc)));
-}
-
-bool CombinerHelper::applyCombineFAbsOfFAbs(MachineInstr &MI, Register &Src) {
- assert(MI.getOpcode() == TargetOpcode::G_FABS && "Expected a G_FABS");
- Register Dst = MI.getOperand(0).getReg();
- MI.eraseFromParent();
- replaceRegWith(MRI, Dst, Src);
- return true;
-}
-
-bool CombinerHelper::matchCombineTruncOfExt(
- MachineInstr &MI, std::pair<Register, unsigned> &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_TRUNC && "Expected a G_TRUNC");
- Register SrcReg = MI.getOperand(1).getReg();
- MachineInstr *SrcMI = MRI.getVRegDef(SrcReg);
- unsigned SrcOpc = SrcMI->getOpcode();
- if (SrcOpc == TargetOpcode::G_ANYEXT || SrcOpc == TargetOpcode::G_SEXT ||
- SrcOpc == TargetOpcode::G_ZEXT) {
- MatchInfo = std::make_pair(SrcMI->getOperand(1).getReg(), SrcOpc);
- return true;
- }
- return false;
-}
-
-bool CombinerHelper::applyCombineTruncOfExt(
- MachineInstr &MI, std::pair<Register, unsigned> &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_TRUNC && "Expected a G_TRUNC");
- Register SrcReg = MatchInfo.first;
- unsigned SrcExtOp = MatchInfo.second;
- Register DstReg = MI.getOperand(0).getReg();
- LLT SrcTy = MRI.getType(SrcReg);
- LLT DstTy = MRI.getType(DstReg);
- if (SrcTy == DstTy) {
- MI.eraseFromParent();
- replaceRegWith(MRI, DstReg, SrcReg);
- return true;
- }
- Builder.setInstrAndDebugLoc(MI);
- if (SrcTy.getSizeInBits() < DstTy.getSizeInBits())
- Builder.buildInstr(SrcExtOp, {DstReg}, {SrcReg});
- else
- Builder.buildTrunc(DstReg, SrcReg);
- MI.eraseFromParent();
- return true;
-}
-
-bool CombinerHelper::matchCombineTruncOfShl(
- MachineInstr &MI, std::pair<Register, Register> &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_TRUNC && "Expected a G_TRUNC");
- Register DstReg = MI.getOperand(0).getReg();
- Register SrcReg = MI.getOperand(1).getReg();
- LLT DstTy = MRI.getType(DstReg);
- Register ShiftSrc;
- Register ShiftAmt;
-
- if (MRI.hasOneNonDBGUse(SrcReg) &&
- mi_match(SrcReg, MRI, m_GShl(m_Reg(ShiftSrc), m_Reg(ShiftAmt))) &&
- isLegalOrBeforeLegalizer(
- {TargetOpcode::G_SHL,
- {DstTy, getTargetLowering().getPreferredShiftAmountTy(DstTy)}})) {
- KnownBits Known = KB->getKnownBits(ShiftAmt);
- unsigned Size = DstTy.getSizeInBits();
- if (Known.getBitWidth() - Known.countMinLeadingZeros() <= Log2_32(Size)) {
- MatchInfo = std::make_pair(ShiftSrc, ShiftAmt);
- return true;
- }
- }
- return false;
-}
-
-bool CombinerHelper::applyCombineTruncOfShl(
- MachineInstr &MI, std::pair<Register, Register> &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_TRUNC && "Expected a G_TRUNC");
- Register DstReg = MI.getOperand(0).getReg();
- Register SrcReg = MI.getOperand(1).getReg();
- LLT DstTy = MRI.getType(DstReg);
- MachineInstr *SrcMI = MRI.getVRegDef(SrcReg);
-
- Register ShiftSrc = MatchInfo.first;
- Register ShiftAmt = MatchInfo.second;
- Builder.setInstrAndDebugLoc(MI);
- auto TruncShiftSrc = Builder.buildTrunc(DstTy, ShiftSrc);
- Builder.buildShl(DstReg, TruncShiftSrc, ShiftAmt, SrcMI->getFlags());
- MI.eraseFromParent();
- return true;
-}
-
+bool CombinerHelper::matchCombineI2PToP2I(MachineInstr &MI, Register &Reg) {
+ assert(MI.getOpcode() == TargetOpcode::G_INTTOPTR && "Expected a G_INTTOPTR");
+ Register DstReg = MI.getOperand(0).getReg();
+ LLT DstTy = MRI.getType(DstReg);
+ Register SrcReg = MI.getOperand(1).getReg();
+ return mi_match(SrcReg, MRI,
+ m_GPtrToInt(m_all_of(m_SpecificType(DstTy), m_Reg(Reg))));
+}
+
+bool CombinerHelper::applyCombineI2PToP2I(MachineInstr &MI, Register &Reg) {
+ assert(MI.getOpcode() == TargetOpcode::G_INTTOPTR && "Expected a G_INTTOPTR");
+ Register DstReg = MI.getOperand(0).getReg();
+ Builder.setInstr(MI);
+ Builder.buildCopy(DstReg, Reg);
+ MI.eraseFromParent();
+ return true;
+}
+
+bool CombinerHelper::matchCombineP2IToI2P(MachineInstr &MI, Register &Reg) {
+ assert(MI.getOpcode() == TargetOpcode::G_PTRTOINT && "Expected a G_PTRTOINT");
+ Register SrcReg = MI.getOperand(1).getReg();
+ return mi_match(SrcReg, MRI, m_GIntToPtr(m_Reg(Reg)));
+}
+
+bool CombinerHelper::applyCombineP2IToI2P(MachineInstr &MI, Register &Reg) {
+ assert(MI.getOpcode() == TargetOpcode::G_PTRTOINT && "Expected a G_PTRTOINT");
+ Register DstReg = MI.getOperand(0).getReg();
+ Builder.setInstr(MI);
+ Builder.buildZExtOrTrunc(DstReg, Reg);
+ MI.eraseFromParent();
+ return true;
+}
+
+bool CombinerHelper::matchCombineAddP2IToPtrAdd(
+ MachineInstr &MI, std::pair<Register, bool> &PtrReg) {
+ assert(MI.getOpcode() == TargetOpcode::G_ADD);
+ Register LHS = MI.getOperand(1).getReg();
+ Register RHS = MI.getOperand(2).getReg();
+ LLT IntTy = MRI.getType(LHS);
+
+ // G_PTR_ADD always has the pointer in the LHS, so we may need to commute the
+ // instruction.
+ PtrReg.second = false;
+ for (Register SrcReg : {LHS, RHS}) {
+ if (mi_match(SrcReg, MRI, m_GPtrToInt(m_Reg(PtrReg.first)))) {
+ // Don't handle cases where the integer is implicitly converted to the
+ // pointer width.
+ LLT PtrTy = MRI.getType(PtrReg.first);
+ if (PtrTy.getScalarSizeInBits() == IntTy.getScalarSizeInBits())
+ return true;
+ }
+
+ PtrReg.second = true;
+ }
+
+ return false;
+}
+
+bool CombinerHelper::applyCombineAddP2IToPtrAdd(
+ MachineInstr &MI, std::pair<Register, bool> &PtrReg) {
+ Register Dst = MI.getOperand(0).getReg();
+ Register LHS = MI.getOperand(1).getReg();
+ Register RHS = MI.getOperand(2).getReg();
+
+ const bool DoCommute = PtrReg.second;
+ if (DoCommute)
+ std::swap(LHS, RHS);
+ LHS = PtrReg.first;
+
+ LLT PtrTy = MRI.getType(LHS);
+
+ Builder.setInstrAndDebugLoc(MI);
+ auto PtrAdd = Builder.buildPtrAdd(PtrTy, LHS, RHS);
+ Builder.buildPtrToInt(Dst, PtrAdd);
+ MI.eraseFromParent();
+ return true;
+}
+
+bool CombinerHelper::matchCombineConstPtrAddToI2P(MachineInstr &MI,
+ int64_t &NewCst) {
+ assert(MI.getOpcode() == TargetOpcode::G_PTR_ADD && "Expected a G_PTR_ADD");
+ Register LHS = MI.getOperand(1).getReg();
+ Register RHS = MI.getOperand(2).getReg();
+ MachineRegisterInfo &MRI = Builder.getMF().getRegInfo();
+
+ if (auto RHSCst = getConstantVRegSExtVal(RHS, MRI)) {
+ int64_t Cst;
+ if (mi_match(LHS, MRI, m_GIntToPtr(m_ICst(Cst)))) {
+ NewCst = Cst + *RHSCst;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool CombinerHelper::applyCombineConstPtrAddToI2P(MachineInstr &MI,
+ int64_t &NewCst) {
+ assert(MI.getOpcode() == TargetOpcode::G_PTR_ADD && "Expected a G_PTR_ADD");
+ Register Dst = MI.getOperand(0).getReg();
+
+ Builder.setInstrAndDebugLoc(MI);
+ Builder.buildConstant(Dst, NewCst);
+ MI.eraseFromParent();
+ return true;
+}
+
+bool CombinerHelper::matchCombineAnyExtTrunc(MachineInstr &MI, Register &Reg) {
+ assert(MI.getOpcode() == TargetOpcode::G_ANYEXT && "Expected a G_ANYEXT");
+ Register DstReg = MI.getOperand(0).getReg();
+ Register SrcReg = MI.getOperand(1).getReg();
+ LLT DstTy = MRI.getType(DstReg);
+ return mi_match(SrcReg, MRI,
+ m_GTrunc(m_all_of(m_Reg(Reg), m_SpecificType(DstTy))));
+}
+
+bool CombinerHelper::applyCombineAnyExtTrunc(MachineInstr &MI, Register &Reg) {
+ assert(MI.getOpcode() == TargetOpcode::G_ANYEXT && "Expected a G_ANYEXT");
+ Register DstReg = MI.getOperand(0).getReg();
+ MI.eraseFromParent();
+ replaceRegWith(MRI, DstReg, Reg);
+ return true;
+}
+
+bool CombinerHelper::matchCombineExtOfExt(
+ MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo) {
+ assert((MI.getOpcode() == TargetOpcode::G_ANYEXT ||
+ MI.getOpcode() == TargetOpcode::G_SEXT ||
+ MI.getOpcode() == TargetOpcode::G_ZEXT) &&
+ "Expected a G_[ASZ]EXT");
+ Register SrcReg = MI.getOperand(1).getReg();
+ MachineInstr *SrcMI = MRI.getVRegDef(SrcReg);
+ // Match exts with the same opcode, anyext([sz]ext) and sext(zext).
+ unsigned Opc = MI.getOpcode();
+ unsigned SrcOpc = SrcMI->getOpcode();
+ if (Opc == SrcOpc ||
+ (Opc == TargetOpcode::G_ANYEXT &&
+ (SrcOpc == TargetOpcode::G_SEXT || SrcOpc == TargetOpcode::G_ZEXT)) ||
+ (Opc == TargetOpcode::G_SEXT && SrcOpc == TargetOpcode::G_ZEXT)) {
+ MatchInfo = std::make_tuple(SrcMI->getOperand(1).getReg(), SrcOpc);
+ return true;
+ }
+ return false;
+}
+
+bool CombinerHelper::applyCombineExtOfExt(
+ MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo) {
+ assert((MI.getOpcode() == TargetOpcode::G_ANYEXT ||
+ MI.getOpcode() == TargetOpcode::G_SEXT ||
+ MI.getOpcode() == TargetOpcode::G_ZEXT) &&
+ "Expected a G_[ASZ]EXT");
+
+ Register Reg = std::get<0>(MatchInfo);
+ unsigned SrcExtOp = std::get<1>(MatchInfo);
+
+ // Combine exts with the same opcode.
+ if (MI.getOpcode() == SrcExtOp) {
+ Observer.changingInstr(MI);
+ MI.getOperand(1).setReg(Reg);
+ Observer.changedInstr(MI);
+ return true;
+ }
+
+ // Combine:
+ // - anyext([sz]ext x) to [sz]ext x
+ // - sext(zext x) to zext x
+ if (MI.getOpcode() == TargetOpcode::G_ANYEXT ||
+ (MI.getOpcode() == TargetOpcode::G_SEXT &&
+ SrcExtOp == TargetOpcode::G_ZEXT)) {
+ Register DstReg = MI.getOperand(0).getReg();
+ Builder.setInstrAndDebugLoc(MI);
+ Builder.buildInstr(SrcExtOp, {DstReg}, {Reg});
+ MI.eraseFromParent();
+ return true;
+ }
+
+ return false;
+}
+
+bool CombinerHelper::applyCombineMulByNegativeOne(MachineInstr &MI) {
+ assert(MI.getOpcode() == TargetOpcode::G_MUL && "Expected a G_MUL");
+ Register DstReg = MI.getOperand(0).getReg();
+ Register SrcReg = MI.getOperand(1).getReg();
+ LLT DstTy = MRI.getType(DstReg);
+
+ Builder.setInstrAndDebugLoc(MI);
+ Builder.buildSub(DstReg, Builder.buildConstant(DstTy, 0), SrcReg,
+ MI.getFlags());
+ MI.eraseFromParent();
+ return true;
+}
+
+bool CombinerHelper::matchCombineFNegOfFNeg(MachineInstr &MI, Register &Reg) {
+ assert(MI.getOpcode() == TargetOpcode::G_FNEG && "Expected a G_FNEG");
+ Register SrcReg = MI.getOperand(1).getReg();
+ return mi_match(SrcReg, MRI, m_GFNeg(m_Reg(Reg)));
+}
+
+bool CombinerHelper::matchCombineFAbsOfFAbs(MachineInstr &MI, Register &Src) {
+ assert(MI.getOpcode() == TargetOpcode::G_FABS && "Expected a G_FABS");
+ Src = MI.getOperand(1).getReg();
+ Register AbsSrc;
+ return mi_match(Src, MRI, m_GFabs(m_Reg(AbsSrc)));
+}
+
+bool CombinerHelper::applyCombineFAbsOfFAbs(MachineInstr &MI, Register &Src) {
+ assert(MI.getOpcode() == TargetOpcode::G_FABS && "Expected a G_FABS");
+ Register Dst = MI.getOperand(0).getReg();
+ MI.eraseFromParent();
+ replaceRegWith(MRI, Dst, Src);
+ return true;
+}
+
+bool CombinerHelper::matchCombineTruncOfExt(
+ MachineInstr &MI, std::pair<Register, unsigned> &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_TRUNC && "Expected a G_TRUNC");
+ Register SrcReg = MI.getOperand(1).getReg();
+ MachineInstr *SrcMI = MRI.getVRegDef(SrcReg);
+ unsigned SrcOpc = SrcMI->getOpcode();
+ if (SrcOpc == TargetOpcode::G_ANYEXT || SrcOpc == TargetOpcode::G_SEXT ||
+ SrcOpc == TargetOpcode::G_ZEXT) {
+ MatchInfo = std::make_pair(SrcMI->getOperand(1).getReg(), SrcOpc);
+ return true;
+ }
+ return false;
+}
+
+bool CombinerHelper::applyCombineTruncOfExt(
+ MachineInstr &MI, std::pair<Register, unsigned> &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_TRUNC && "Expected a G_TRUNC");
+ Register SrcReg = MatchInfo.first;
+ unsigned SrcExtOp = MatchInfo.second;
+ Register DstReg = MI.getOperand(0).getReg();
+ LLT SrcTy = MRI.getType(SrcReg);
+ LLT DstTy = MRI.getType(DstReg);
+ if (SrcTy == DstTy) {
+ MI.eraseFromParent();
+ replaceRegWith(MRI, DstReg, SrcReg);
+ return true;
+ }
+ Builder.setInstrAndDebugLoc(MI);
+ if (SrcTy.getSizeInBits() < DstTy.getSizeInBits())
+ Builder.buildInstr(SrcExtOp, {DstReg}, {SrcReg});
+ else
+ Builder.buildTrunc(DstReg, SrcReg);
+ MI.eraseFromParent();
+ return true;
+}
+
+bool CombinerHelper::matchCombineTruncOfShl(
+ MachineInstr &MI, std::pair<Register, Register> &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_TRUNC && "Expected a G_TRUNC");
+ Register DstReg = MI.getOperand(0).getReg();
+ Register SrcReg = MI.getOperand(1).getReg();
+ LLT DstTy = MRI.getType(DstReg);
+ Register ShiftSrc;
+ Register ShiftAmt;
+
+ if (MRI.hasOneNonDBGUse(SrcReg) &&
+ mi_match(SrcReg, MRI, m_GShl(m_Reg(ShiftSrc), m_Reg(ShiftAmt))) &&
+ isLegalOrBeforeLegalizer(
+ {TargetOpcode::G_SHL,
+ {DstTy, getTargetLowering().getPreferredShiftAmountTy(DstTy)}})) {
+ KnownBits Known = KB->getKnownBits(ShiftAmt);
+ unsigned Size = DstTy.getSizeInBits();
+ if (Known.getBitWidth() - Known.countMinLeadingZeros() <= Log2_32(Size)) {
+ MatchInfo = std::make_pair(ShiftSrc, ShiftAmt);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool CombinerHelper::applyCombineTruncOfShl(
+ MachineInstr &MI, std::pair<Register, Register> &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_TRUNC && "Expected a G_TRUNC");
+ Register DstReg = MI.getOperand(0).getReg();
+ Register SrcReg = MI.getOperand(1).getReg();
+ LLT DstTy = MRI.getType(DstReg);
+ MachineInstr *SrcMI = MRI.getVRegDef(SrcReg);
+
+ Register ShiftSrc = MatchInfo.first;
+ Register ShiftAmt = MatchInfo.second;
+ Builder.setInstrAndDebugLoc(MI);
+ auto TruncShiftSrc = Builder.buildTrunc(DstTy, ShiftSrc);
+ Builder.buildShl(DstReg, TruncShiftSrc, ShiftAmt, SrcMI->getFlags());
+ MI.eraseFromParent();
+ return true;
+}
+
bool CombinerHelper::matchAnyExplicitUseIsUndef(MachineInstr &MI) {
return any_of(MI.explicit_uses(), [this](const MachineOperand &MO) {
return MO.isReg() &&
@@ -2493,22 +2493,22 @@ bool CombinerHelper::matchUndefStore(MachineInstr &MI) {
MRI);
}
-bool CombinerHelper::matchUndefSelectCmp(MachineInstr &MI) {
- assert(MI.getOpcode() == TargetOpcode::G_SELECT);
- return getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, MI.getOperand(1).getReg(),
- MRI);
-}
-
-bool CombinerHelper::matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx) {
- assert(MI.getOpcode() == TargetOpcode::G_SELECT);
- if (auto MaybeCstCmp =
- getConstantVRegValWithLookThrough(MI.getOperand(1).getReg(), MRI)) {
- OpIdx = MaybeCstCmp->Value.isNullValue() ? 3 : 2;
- return true;
- }
- return false;
-}
-
+bool CombinerHelper::matchUndefSelectCmp(MachineInstr &MI) {
+ assert(MI.getOpcode() == TargetOpcode::G_SELECT);
+ return getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, MI.getOperand(1).getReg(),
+ MRI);
+}
+
+bool CombinerHelper::matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx) {
+ assert(MI.getOpcode() == TargetOpcode::G_SELECT);
+ if (auto MaybeCstCmp =
+ getConstantVRegValWithLookThrough(MI.getOperand(1).getReg(), MRI)) {
+ OpIdx = MaybeCstCmp->Value.isNullValue() ? 3 : 2;
+ return true;
+ }
+ return false;
+}
+
bool CombinerHelper::eraseInst(MachineInstr &MI) {
MI.eraseFromParent();
return true;
@@ -2605,16 +2605,16 @@ bool CombinerHelper::replaceSingleDefInstWithOperand(MachineInstr &MI,
return true;
}
-bool CombinerHelper::replaceSingleDefInstWithReg(MachineInstr &MI,
- Register Replacement) {
- assert(MI.getNumExplicitDefs() == 1 && "Expected one explicit def?");
- Register OldReg = MI.getOperand(0).getReg();
- assert(canReplaceReg(OldReg, Replacement, MRI) && "Cannot replace register?");
- MI.eraseFromParent();
- replaceRegWith(MRI, OldReg, Replacement);
- return true;
-}
-
+bool CombinerHelper::replaceSingleDefInstWithReg(MachineInstr &MI,
+ Register Replacement) {
+ assert(MI.getNumExplicitDefs() == 1 && "Expected one explicit def?");
+ Register OldReg = MI.getOperand(0).getReg();
+ assert(canReplaceReg(OldReg, Replacement, MRI) && "Cannot replace register?");
+ MI.eraseFromParent();
+ replaceRegWith(MRI, OldReg, Replacement);
+ return true;
+}
+
bool CombinerHelper::matchSelectSameVal(MachineInstr &MI) {
assert(MI.getOpcode() == TargetOpcode::G_SELECT);
// Match (cond ? x : x)
@@ -2635,18 +2635,18 @@ bool CombinerHelper::matchOperandIsZero(MachineInstr &MI, unsigned OpIdx) {
MRI);
}
-bool CombinerHelper::matchOperandIsUndef(MachineInstr &MI, unsigned OpIdx) {
- MachineOperand &MO = MI.getOperand(OpIdx);
- return MO.isReg() &&
- getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, MO.getReg(), MRI);
-}
-
-bool CombinerHelper::matchOperandIsKnownToBeAPowerOfTwo(MachineInstr &MI,
- unsigned OpIdx) {
- MachineOperand &MO = MI.getOperand(OpIdx);
- return isKnownToBeAPowerOfTwo(MO.getReg(), MRI, KB);
-}
-
+bool CombinerHelper::matchOperandIsUndef(MachineInstr &MI, unsigned OpIdx) {
+ MachineOperand &MO = MI.getOperand(OpIdx);
+ return MO.isReg() &&
+ getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, MO.getReg(), MRI);
+}
+
+bool CombinerHelper::matchOperandIsKnownToBeAPowerOfTwo(MachineInstr &MI,
+ unsigned OpIdx) {
+ MachineOperand &MO = MI.getOperand(OpIdx);
+ return isKnownToBeAPowerOfTwo(MO.getReg(), MRI, KB);
+}
+
bool CombinerHelper::replaceInstWithFConstant(MachineInstr &MI, double C) {
assert(MI.getNumDefs() == 1 && "Expected only one def?");
Builder.setInstr(MI);
@@ -2682,7 +2682,7 @@ bool CombinerHelper::matchSimplifyAddToSub(
// ((0-A) + B) -> B - A
// (A + (0-B)) -> A - B
auto CheckFold = [&](Register &MaybeSub, Register &MaybeNewLHS) {
- if (!mi_match(MaybeSub, MRI, m_Neg(m_Reg(NewRHS))))
+ if (!mi_match(MaybeSub, MRI, m_Neg(m_Reg(NewRHS))))
return false;
NewLHS = MaybeNewLHS;
return true;
@@ -2691,67 +2691,67 @@ bool CombinerHelper::matchSimplifyAddToSub(
return CheckFold(LHS, RHS) || CheckFold(RHS, LHS);
}
-bool CombinerHelper::matchCombineInsertVecElts(
- MachineInstr &MI, SmallVectorImpl<Register> &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT &&
- "Invalid opcode");
- Register DstReg = MI.getOperand(0).getReg();
- LLT DstTy = MRI.getType(DstReg);
- assert(DstTy.isVector() && "Invalid G_INSERT_VECTOR_ELT?");
- unsigned NumElts = DstTy.getNumElements();
- // If this MI is part of a sequence of insert_vec_elts, then
- // don't do the combine in the middle of the sequence.
- if (MRI.hasOneUse(DstReg) && MRI.use_instr_begin(DstReg)->getOpcode() ==
- TargetOpcode::G_INSERT_VECTOR_ELT)
- return false;
- MachineInstr *CurrInst = &MI;
- MachineInstr *TmpInst;
- int64_t IntImm;
- Register TmpReg;
- MatchInfo.resize(NumElts);
- while (mi_match(
- CurrInst->getOperand(0).getReg(), MRI,
- m_GInsertVecElt(m_MInstr(TmpInst), m_Reg(TmpReg), m_ICst(IntImm)))) {
- if (IntImm >= NumElts)
- return false;
- if (!MatchInfo[IntImm])
- MatchInfo[IntImm] = TmpReg;
- CurrInst = TmpInst;
- }
- // Variable index.
- if (CurrInst->getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT)
- return false;
- if (TmpInst->getOpcode() == TargetOpcode::G_BUILD_VECTOR) {
- for (unsigned I = 1; I < TmpInst->getNumOperands(); ++I) {
- if (!MatchInfo[I - 1].isValid())
- MatchInfo[I - 1] = TmpInst->getOperand(I).getReg();
- }
- return true;
- }
- // If we didn't end in a G_IMPLICIT_DEF, bail out.
- return TmpInst->getOpcode() == TargetOpcode::G_IMPLICIT_DEF;
-}
-
-bool CombinerHelper::applyCombineInsertVecElts(
- MachineInstr &MI, SmallVectorImpl<Register> &MatchInfo) {
- Builder.setInstr(MI);
- Register UndefReg;
- auto GetUndef = [&]() {
- if (UndefReg)
- return UndefReg;
- LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
- UndefReg = Builder.buildUndef(DstTy.getScalarType()).getReg(0);
- return UndefReg;
- };
- for (unsigned I = 0; I < MatchInfo.size(); ++I) {
- if (!MatchInfo[I])
- MatchInfo[I] = GetUndef();
- }
- Builder.buildBuildVector(MI.getOperand(0).getReg(), MatchInfo);
- MI.eraseFromParent();
- return true;
-}
-
+bool CombinerHelper::matchCombineInsertVecElts(
+ MachineInstr &MI, SmallVectorImpl<Register> &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT &&
+ "Invalid opcode");
+ Register DstReg = MI.getOperand(0).getReg();
+ LLT DstTy = MRI.getType(DstReg);
+ assert(DstTy.isVector() && "Invalid G_INSERT_VECTOR_ELT?");
+ unsigned NumElts = DstTy.getNumElements();
+ // If this MI is part of a sequence of insert_vec_elts, then
+ // don't do the combine in the middle of the sequence.
+ if (MRI.hasOneUse(DstReg) && MRI.use_instr_begin(DstReg)->getOpcode() ==
+ TargetOpcode::G_INSERT_VECTOR_ELT)
+ return false;
+ MachineInstr *CurrInst = &MI;
+ MachineInstr *TmpInst;
+ int64_t IntImm;
+ Register TmpReg;
+ MatchInfo.resize(NumElts);
+ while (mi_match(
+ CurrInst->getOperand(0).getReg(), MRI,
+ m_GInsertVecElt(m_MInstr(TmpInst), m_Reg(TmpReg), m_ICst(IntImm)))) {
+ if (IntImm >= NumElts)
+ return false;
+ if (!MatchInfo[IntImm])
+ MatchInfo[IntImm] = TmpReg;
+ CurrInst = TmpInst;
+ }
+ // Variable index.
+ if (CurrInst->getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT)
+ return false;
+ if (TmpInst->getOpcode() == TargetOpcode::G_BUILD_VECTOR) {
+ for (unsigned I = 1; I < TmpInst->getNumOperands(); ++I) {
+ if (!MatchInfo[I - 1].isValid())
+ MatchInfo[I - 1] = TmpInst->getOperand(I).getReg();
+ }
+ return true;
+ }
+ // If we didn't end in a G_IMPLICIT_DEF, bail out.
+ return TmpInst->getOpcode() == TargetOpcode::G_IMPLICIT_DEF;
+}
+
+bool CombinerHelper::applyCombineInsertVecElts(
+ MachineInstr &MI, SmallVectorImpl<Register> &MatchInfo) {
+ Builder.setInstr(MI);
+ Register UndefReg;
+ auto GetUndef = [&]() {
+ if (UndefReg)
+ return UndefReg;
+ LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
+ UndefReg = Builder.buildUndef(DstTy.getScalarType()).getReg(0);
+ return UndefReg;
+ };
+ for (unsigned I = 0; I < MatchInfo.size(); ++I) {
+ if (!MatchInfo[I])
+ MatchInfo[I] = GetUndef();
+ }
+ Builder.buildBuildVector(MI.getOperand(0).getReg(), MatchInfo);
+ MI.eraseFromParent();
+ return true;
+}
+
bool CombinerHelper::applySimplifyAddToSub(
MachineInstr &MI, std::tuple<Register, Register> &MatchInfo) {
Builder.setInstr(MI);
@@ -2762,812 +2762,812 @@ bool CombinerHelper::applySimplifyAddToSub(
return true;
}
-bool CombinerHelper::matchHoistLogicOpWithSameOpcodeHands(
- MachineInstr &MI, InstructionStepsMatchInfo &MatchInfo) {
- // Matches: logic (hand x, ...), (hand y, ...) -> hand (logic x, y), ...
- //
- // Creates the new hand + logic instruction (but does not insert them.)
- //
- // On success, MatchInfo is populated with the new instructions. These are
- // inserted in applyHoistLogicOpWithSameOpcodeHands.
- unsigned LogicOpcode = MI.getOpcode();
- assert(LogicOpcode == TargetOpcode::G_AND ||
- LogicOpcode == TargetOpcode::G_OR ||
- LogicOpcode == TargetOpcode::G_XOR);
- MachineIRBuilder MIB(MI);
- Register Dst = MI.getOperand(0).getReg();
- Register LHSReg = MI.getOperand(1).getReg();
- Register RHSReg = MI.getOperand(2).getReg();
-
- // Don't recompute anything.
- if (!MRI.hasOneNonDBGUse(LHSReg) || !MRI.hasOneNonDBGUse(RHSReg))
- return false;
-
- // Make sure we have (hand x, ...), (hand y, ...)
- MachineInstr *LeftHandInst = getDefIgnoringCopies(LHSReg, MRI);
- MachineInstr *RightHandInst = getDefIgnoringCopies(RHSReg, MRI);
- if (!LeftHandInst || !RightHandInst)
- return false;
- unsigned HandOpcode = LeftHandInst->getOpcode();
- if (HandOpcode != RightHandInst->getOpcode())
- return false;
- if (!LeftHandInst->getOperand(1).isReg() ||
- !RightHandInst->getOperand(1).isReg())
- return false;
-
- // Make sure the types match up, and if we're doing this post-legalization,
- // we end up with legal types.
- Register X = LeftHandInst->getOperand(1).getReg();
- Register Y = RightHandInst->getOperand(1).getReg();
- LLT XTy = MRI.getType(X);
- LLT YTy = MRI.getType(Y);
- if (XTy != YTy)
- return false;
- if (!isLegalOrBeforeLegalizer({LogicOpcode, {XTy, YTy}}))
- return false;
-
- // Optional extra source register.
- Register ExtraHandOpSrcReg;
- switch (HandOpcode) {
- default:
- return false;
- case TargetOpcode::G_ANYEXT:
- case TargetOpcode::G_SEXT:
- case TargetOpcode::G_ZEXT: {
- // Match: logic (ext X), (ext Y) --> ext (logic X, Y)
- break;
- }
- case TargetOpcode::G_AND:
- case TargetOpcode::G_ASHR:
- case TargetOpcode::G_LSHR:
- case TargetOpcode::G_SHL: {
- // Match: logic (binop x, z), (binop y, z) -> binop (logic x, y), z
- MachineOperand &ZOp = LeftHandInst->getOperand(2);
- if (!matchEqualDefs(ZOp, RightHandInst->getOperand(2)))
- return false;
- ExtraHandOpSrcReg = ZOp.getReg();
- break;
- }
- }
-
- // Record the steps to build the new instructions.
- //
- // Steps to build (logic x, y)
- auto NewLogicDst = MRI.createGenericVirtualRegister(XTy);
- OperandBuildSteps LogicBuildSteps = {
- [=](MachineInstrBuilder &MIB) { MIB.addDef(NewLogicDst); },
- [=](MachineInstrBuilder &MIB) { MIB.addReg(X); },
- [=](MachineInstrBuilder &MIB) { MIB.addReg(Y); }};
- InstructionBuildSteps LogicSteps(LogicOpcode, LogicBuildSteps);
-
- // Steps to build hand (logic x, y), ...z
- OperandBuildSteps HandBuildSteps = {
- [=](MachineInstrBuilder &MIB) { MIB.addDef(Dst); },
- [=](MachineInstrBuilder &MIB) { MIB.addReg(NewLogicDst); }};
- if (ExtraHandOpSrcReg.isValid())
- HandBuildSteps.push_back(
- [=](MachineInstrBuilder &MIB) { MIB.addReg(ExtraHandOpSrcReg); });
- InstructionBuildSteps HandSteps(HandOpcode, HandBuildSteps);
-
- MatchInfo = InstructionStepsMatchInfo({LogicSteps, HandSteps});
- return true;
-}
-
-bool CombinerHelper::applyBuildInstructionSteps(
- MachineInstr &MI, InstructionStepsMatchInfo &MatchInfo) {
- assert(MatchInfo.InstrsToBuild.size() &&
- "Expected at least one instr to build?");
- Builder.setInstr(MI);
- for (auto &InstrToBuild : MatchInfo.InstrsToBuild) {
- assert(InstrToBuild.Opcode && "Expected a valid opcode?");
- assert(InstrToBuild.OperandFns.size() && "Expected at least one operand?");
- MachineInstrBuilder Instr = Builder.buildInstr(InstrToBuild.Opcode);
- for (auto &OperandFn : InstrToBuild.OperandFns)
- OperandFn(Instr);
- }
- MI.eraseFromParent();
- return true;
-}
-
-bool CombinerHelper::matchAshrShlToSextInreg(
- MachineInstr &MI, std::tuple<Register, int64_t> &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_ASHR);
- int64_t ShlCst, AshrCst;
- Register Src;
- // FIXME: detect splat constant vectors.
- if (!mi_match(MI.getOperand(0).getReg(), MRI,
- m_GAShr(m_GShl(m_Reg(Src), m_ICst(ShlCst)), m_ICst(AshrCst))))
- return false;
- if (ShlCst != AshrCst)
- return false;
- if (!isLegalOrBeforeLegalizer(
- {TargetOpcode::G_SEXT_INREG, {MRI.getType(Src)}}))
- return false;
- MatchInfo = std::make_tuple(Src, ShlCst);
- return true;
-}
-bool CombinerHelper::applyAshShlToSextInreg(
- MachineInstr &MI, std::tuple<Register, int64_t> &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_ASHR);
- Register Src;
- int64_t ShiftAmt;
- std::tie(Src, ShiftAmt) = MatchInfo;
- unsigned Size = MRI.getType(Src).getScalarSizeInBits();
- Builder.setInstrAndDebugLoc(MI);
- Builder.buildSExtInReg(MI.getOperand(0).getReg(), Src, Size - ShiftAmt);
- MI.eraseFromParent();
- return true;
-}
-
-bool CombinerHelper::matchRedundantAnd(MachineInstr &MI,
- Register &Replacement) {
- // Given
- //
- // %y:_(sN) = G_SOMETHING
- // %x:_(sN) = G_SOMETHING
- // %res:_(sN) = G_AND %x, %y
- //
- // Eliminate the G_AND when it is known that x & y == x or x & y == y.
- //
- // Patterns like this can appear as a result of legalization. E.g.
- //
- // %cmp:_(s32) = G_ICMP intpred(pred), %x(s32), %y
- // %one:_(s32) = G_CONSTANT i32 1
- // %and:_(s32) = G_AND %cmp, %one
- //
- // In this case, G_ICMP only produces a single bit, so x & 1 == x.
- assert(MI.getOpcode() == TargetOpcode::G_AND);
- if (!KB)
- return false;
-
- Register AndDst = MI.getOperand(0).getReg();
- LLT DstTy = MRI.getType(AndDst);
-
- // FIXME: This should be removed once GISelKnownBits supports vectors.
- if (DstTy.isVector())
- return false;
-
- Register LHS = MI.getOperand(1).getReg();
- Register RHS = MI.getOperand(2).getReg();
- KnownBits LHSBits = KB->getKnownBits(LHS);
- KnownBits RHSBits = KB->getKnownBits(RHS);
-
- // Check that x & Mask == x.
- // x & 1 == x, always
- // x & 0 == x, only if x is also 0
- // Meaning Mask has no effect if every bit is either one in Mask or zero in x.
- //
- // Check if we can replace AndDst with the LHS of the G_AND
- if (canReplaceReg(AndDst, LHS, MRI) &&
- (LHSBits.Zero | RHSBits.One).isAllOnesValue()) {
- Replacement = LHS;
- return true;
- }
-
- // Check if we can replace AndDst with the RHS of the G_AND
- if (canReplaceReg(AndDst, RHS, MRI) &&
- (LHSBits.One | RHSBits.Zero).isAllOnesValue()) {
- Replacement = RHS;
- return true;
- }
-
- return false;
-}
-
-bool CombinerHelper::matchRedundantOr(MachineInstr &MI, Register &Replacement) {
- // Given
- //
- // %y:_(sN) = G_SOMETHING
- // %x:_(sN) = G_SOMETHING
- // %res:_(sN) = G_OR %x, %y
- //
- // Eliminate the G_OR when it is known that x | y == x or x | y == y.
- assert(MI.getOpcode() == TargetOpcode::G_OR);
- if (!KB)
- return false;
-
- Register OrDst = MI.getOperand(0).getReg();
- LLT DstTy = MRI.getType(OrDst);
-
- // FIXME: This should be removed once GISelKnownBits supports vectors.
- if (DstTy.isVector())
- return false;
-
- Register LHS = MI.getOperand(1).getReg();
- Register RHS = MI.getOperand(2).getReg();
- KnownBits LHSBits = KB->getKnownBits(LHS);
- KnownBits RHSBits = KB->getKnownBits(RHS);
-
- // Check that x | Mask == x.
- // x | 0 == x, always
- // x | 1 == x, only if x is also 1
- // Meaning Mask has no effect if every bit is either zero in Mask or one in x.
- //
- // Check if we can replace OrDst with the LHS of the G_OR
- if (canReplaceReg(OrDst, LHS, MRI) &&
- (LHSBits.One | RHSBits.Zero).isAllOnesValue()) {
- Replacement = LHS;
- return true;
- }
-
- // Check if we can replace OrDst with the RHS of the G_OR
- if (canReplaceReg(OrDst, RHS, MRI) &&
- (LHSBits.Zero | RHSBits.One).isAllOnesValue()) {
- Replacement = RHS;
- return true;
- }
-
- return false;
-}
-
-bool CombinerHelper::matchRedundantSExtInReg(MachineInstr &MI) {
- // If the input is already sign extended, just drop the extension.
- Register Src = MI.getOperand(1).getReg();
- unsigned ExtBits = MI.getOperand(2).getImm();
- unsigned TypeSize = MRI.getType(Src).getScalarSizeInBits();
- return KB->computeNumSignBits(Src) >= (TypeSize - ExtBits + 1);
-}
-
-static bool isConstValidTrue(const TargetLowering &TLI, unsigned ScalarSizeBits,
- int64_t Cst, bool IsVector, bool IsFP) {
- // For i1, Cst will always be -1 regardless of boolean contents.
- return (ScalarSizeBits == 1 && Cst == -1) ||
- isConstTrueVal(TLI, Cst, IsVector, IsFP);
-}
-
-bool CombinerHelper::matchNotCmp(MachineInstr &MI,
- SmallVectorImpl<Register> &RegsToNegate) {
- assert(MI.getOpcode() == TargetOpcode::G_XOR);
- LLT Ty = MRI.getType(MI.getOperand(0).getReg());
- const auto &TLI = *Builder.getMF().getSubtarget().getTargetLowering();
- Register XorSrc;
- Register CstReg;
- // We match xor(src, true) here.
- if (!mi_match(MI.getOperand(0).getReg(), MRI,
- m_GXor(m_Reg(XorSrc), m_Reg(CstReg))))
- return false;
-
- if (!MRI.hasOneNonDBGUse(XorSrc))
- return false;
-
- // Check that XorSrc is the root of a tree of comparisons combined with ANDs
- // and ORs. The suffix of RegsToNegate starting from index I is used a work
- // list of tree nodes to visit.
- RegsToNegate.push_back(XorSrc);
- // Remember whether the comparisons are all integer or all floating point.
- bool IsInt = false;
- bool IsFP = false;
- for (unsigned I = 0; I < RegsToNegate.size(); ++I) {
- Register Reg = RegsToNegate[I];
- if (!MRI.hasOneNonDBGUse(Reg))
- return false;
- MachineInstr *Def = MRI.getVRegDef(Reg);
- switch (Def->getOpcode()) {
- default:
- // Don't match if the tree contains anything other than ANDs, ORs and
- // comparisons.
- return false;
- case TargetOpcode::G_ICMP:
- if (IsFP)
- return false;
- IsInt = true;
- // When we apply the combine we will invert the predicate.
- break;
- case TargetOpcode::G_FCMP:
- if (IsInt)
- return false;
- IsFP = true;
- // When we apply the combine we will invert the predicate.
- break;
- case TargetOpcode::G_AND:
- case TargetOpcode::G_OR:
- // Implement De Morgan's laws:
- // ~(x & y) -> ~x | ~y
- // ~(x | y) -> ~x & ~y
- // When we apply the combine we will change the opcode and recursively
- // negate the operands.
- RegsToNegate.push_back(Def->getOperand(1).getReg());
- RegsToNegate.push_back(Def->getOperand(2).getReg());
- break;
- }
- }
-
- // Now we know whether the comparisons are integer or floating point, check
- // the constant in the xor.
- int64_t Cst;
- if (Ty.isVector()) {
- MachineInstr *CstDef = MRI.getVRegDef(CstReg);
- auto MaybeCst = getBuildVectorConstantSplat(*CstDef, MRI);
- if (!MaybeCst)
- return false;
- if (!isConstValidTrue(TLI, Ty.getScalarSizeInBits(), *MaybeCst, true, IsFP))
- return false;
- } else {
- if (!mi_match(CstReg, MRI, m_ICst(Cst)))
- return false;
- if (!isConstValidTrue(TLI, Ty.getSizeInBits(), Cst, false, IsFP))
- return false;
- }
-
- return true;
-}
-
-bool CombinerHelper::applyNotCmp(MachineInstr &MI,
- SmallVectorImpl<Register> &RegsToNegate) {
- for (Register Reg : RegsToNegate) {
- MachineInstr *Def = MRI.getVRegDef(Reg);
- Observer.changingInstr(*Def);
- // For each comparison, invert the opcode. For each AND and OR, change the
- // opcode.
- switch (Def->getOpcode()) {
- default:
- llvm_unreachable("Unexpected opcode");
- case TargetOpcode::G_ICMP:
- case TargetOpcode::G_FCMP: {
- MachineOperand &PredOp = Def->getOperand(1);
- CmpInst::Predicate NewP = CmpInst::getInversePredicate(
- (CmpInst::Predicate)PredOp.getPredicate());
- PredOp.setPredicate(NewP);
- break;
- }
- case TargetOpcode::G_AND:
- Def->setDesc(Builder.getTII().get(TargetOpcode::G_OR));
- break;
- case TargetOpcode::G_OR:
- Def->setDesc(Builder.getTII().get(TargetOpcode::G_AND));
- break;
- }
- Observer.changedInstr(*Def);
- }
-
- replaceRegWith(MRI, MI.getOperand(0).getReg(), MI.getOperand(1).getReg());
- MI.eraseFromParent();
- return true;
-}
-
-bool CombinerHelper::matchXorOfAndWithSameReg(
- MachineInstr &MI, std::pair<Register, Register> &MatchInfo) {
- // Match (xor (and x, y), y) (or any of its commuted cases)
- assert(MI.getOpcode() == TargetOpcode::G_XOR);
- Register &X = MatchInfo.first;
- Register &Y = MatchInfo.second;
- Register AndReg = MI.getOperand(1).getReg();
- Register SharedReg = MI.getOperand(2).getReg();
-
- // Find a G_AND on either side of the G_XOR.
- // Look for one of
- //
- // (xor (and x, y), SharedReg)
- // (xor SharedReg, (and x, y))
- if (!mi_match(AndReg, MRI, m_GAnd(m_Reg(X), m_Reg(Y)))) {
- std::swap(AndReg, SharedReg);
- if (!mi_match(AndReg, MRI, m_GAnd(m_Reg(X), m_Reg(Y))))
- return false;
- }
-
- // Only do this if we'll eliminate the G_AND.
- if (!MRI.hasOneNonDBGUse(AndReg))
- return false;
-
- // We can combine if SharedReg is the same as either the LHS or RHS of the
- // G_AND.
- if (Y != SharedReg)
- std::swap(X, Y);
- return Y == SharedReg;
-}
-
-bool CombinerHelper::applyXorOfAndWithSameReg(
- MachineInstr &MI, std::pair<Register, Register> &MatchInfo) {
- // Fold (xor (and x, y), y) -> (and (not x), y)
- Builder.setInstrAndDebugLoc(MI);
- Register X, Y;
- std::tie(X, Y) = MatchInfo;
- auto Not = Builder.buildNot(MRI.getType(X), X);
- Observer.changingInstr(MI);
- MI.setDesc(Builder.getTII().get(TargetOpcode::G_AND));
- MI.getOperand(1).setReg(Not->getOperand(0).getReg());
- MI.getOperand(2).setReg(Y);
- Observer.changedInstr(MI);
- return true;
-}
-
-bool CombinerHelper::matchPtrAddZero(MachineInstr &MI) {
- Register DstReg = MI.getOperand(0).getReg();
- LLT Ty = MRI.getType(DstReg);
- const DataLayout &DL = Builder.getMF().getDataLayout();
-
- if (DL.isNonIntegralAddressSpace(Ty.getScalarType().getAddressSpace()))
- return false;
-
- if (Ty.isPointer()) {
- auto ConstVal = getConstantVRegVal(MI.getOperand(1).getReg(), MRI);
- return ConstVal && *ConstVal == 0;
- }
-
- assert(Ty.isVector() && "Expecting a vector type");
- const MachineInstr *VecMI = MRI.getVRegDef(MI.getOperand(1).getReg());
- return isBuildVectorAllZeros(*VecMI, MRI);
-}
-
-bool CombinerHelper::applyPtrAddZero(MachineInstr &MI) {
- assert(MI.getOpcode() == TargetOpcode::G_PTR_ADD);
- Builder.setInstrAndDebugLoc(MI);
- Builder.buildIntToPtr(MI.getOperand(0), MI.getOperand(2));
- MI.eraseFromParent();
- return true;
-}
-
-/// The second source operand is known to be a power of 2.
-bool CombinerHelper::applySimplifyURemByPow2(MachineInstr &MI) {
- Register DstReg = MI.getOperand(0).getReg();
- Register Src0 = MI.getOperand(1).getReg();
- Register Pow2Src1 = MI.getOperand(2).getReg();
- LLT Ty = MRI.getType(DstReg);
- Builder.setInstrAndDebugLoc(MI);
-
- // Fold (urem x, pow2) -> (and x, pow2-1)
- auto NegOne = Builder.buildConstant(Ty, -1);
- auto Add = Builder.buildAdd(Ty, Pow2Src1, NegOne);
- Builder.buildAnd(DstReg, Src0, Add);
- MI.eraseFromParent();
- return true;
-}
-
-Optional<SmallVector<Register, 8>>
-CombinerHelper::findCandidatesForLoadOrCombine(const MachineInstr *Root) const {
- assert(Root->getOpcode() == TargetOpcode::G_OR && "Expected G_OR only!");
- // We want to detect if Root is part of a tree which represents a bunch
- // of loads being merged into a larger load. We'll try to recognize patterns
- // like, for example:
- //
- // Reg Reg
- // \ /
- // OR_1 Reg
- // \ /
- // OR_2
- // \ Reg
- // .. /
- // Root
- //
- // Reg Reg Reg Reg
- // \ / \ /
- // OR_1 OR_2
- // \ /
- // \ /
- // ...
- // Root
- //
- // Each "Reg" may have been produced by a load + some arithmetic. This
- // function will save each of them.
- SmallVector<Register, 8> RegsToVisit;
- SmallVector<const MachineInstr *, 7> Ors = {Root};
-
- // In the "worst" case, we're dealing with a load for each byte. So, there
- // are at most #bytes - 1 ORs.
- const unsigned MaxIter =
- MRI.getType(Root->getOperand(0).getReg()).getSizeInBytes() - 1;
- for (unsigned Iter = 0; Iter < MaxIter; ++Iter) {
- if (Ors.empty())
- break;
- const MachineInstr *Curr = Ors.pop_back_val();
- Register OrLHS = Curr->getOperand(1).getReg();
- Register OrRHS = Curr->getOperand(2).getReg();
-
- // In the combine, we want to elimate the entire tree.
- if (!MRI.hasOneNonDBGUse(OrLHS) || !MRI.hasOneNonDBGUse(OrRHS))
- return None;
-
- // If it's a G_OR, save it and continue to walk. If it's not, then it's
- // something that may be a load + arithmetic.
- if (const MachineInstr *Or = getOpcodeDef(TargetOpcode::G_OR, OrLHS, MRI))
- Ors.push_back(Or);
- else
- RegsToVisit.push_back(OrLHS);
- if (const MachineInstr *Or = getOpcodeDef(TargetOpcode::G_OR, OrRHS, MRI))
- Ors.push_back(Or);
- else
- RegsToVisit.push_back(OrRHS);
- }
-
- // We're going to try and merge each register into a wider power-of-2 type,
- // so we ought to have an even number of registers.
- if (RegsToVisit.empty() || RegsToVisit.size() % 2 != 0)
- return None;
- return RegsToVisit;
-}
-
-/// Helper function for findLoadOffsetsForLoadOrCombine.
-///
-/// Check if \p Reg is the result of loading a \p MemSizeInBits wide value,
-/// and then moving that value into a specific byte offset.
-///
-/// e.g. x[i] << 24
-///
-/// \returns The load instruction and the byte offset it is moved into.
-static Optional<std::pair<MachineInstr *, int64_t>>
-matchLoadAndBytePosition(Register Reg, unsigned MemSizeInBits,
- const MachineRegisterInfo &MRI) {
- assert(MRI.hasOneNonDBGUse(Reg) &&
- "Expected Reg to only have one non-debug use?");
- Register MaybeLoad;
- int64_t Shift;
- if (!mi_match(Reg, MRI,
- m_OneNonDBGUse(m_GShl(m_Reg(MaybeLoad), m_ICst(Shift))))) {
- Shift = 0;
- MaybeLoad = Reg;
- }
-
- if (Shift % MemSizeInBits != 0)
- return None;
-
- // TODO: Handle other types of loads.
- auto *Load = getOpcodeDef(TargetOpcode::G_ZEXTLOAD, MaybeLoad, MRI);
- if (!Load)
- return None;
-
- const auto &MMO = **Load->memoperands_begin();
- if (!MMO.isUnordered() || MMO.getSizeInBits() != MemSizeInBits)
- return None;
-
- return std::make_pair(Load, Shift / MemSizeInBits);
-}
-
-Optional<std::pair<MachineInstr *, int64_t>>
-CombinerHelper::findLoadOffsetsForLoadOrCombine(
- SmallDenseMap<int64_t, int64_t, 8> &MemOffset2Idx,
- const SmallVector<Register, 8> &RegsToVisit, const unsigned MemSizeInBits) {
-
- // Each load found for the pattern. There should be one for each RegsToVisit.
- SmallSetVector<const MachineInstr *, 8> Loads;
-
- // The lowest index used in any load. (The lowest "i" for each x[i].)
- int64_t LowestIdx = INT64_MAX;
-
- // The load which uses the lowest index.
- MachineInstr *LowestIdxLoad = nullptr;
-
- // Keeps track of the load indices we see. We shouldn't see any indices twice.
- SmallSet<int64_t, 8> SeenIdx;
-
- // Ensure each load is in the same MBB.
- // TODO: Support multiple MachineBasicBlocks.
- MachineBasicBlock *MBB = nullptr;
- const MachineMemOperand *MMO = nullptr;
-
- // Earliest instruction-order load in the pattern.
- MachineInstr *EarliestLoad = nullptr;
-
- // Latest instruction-order load in the pattern.
- MachineInstr *LatestLoad = nullptr;
-
- // Base pointer which every load should share.
- Register BasePtr;
-
- // We want to find a load for each register. Each load should have some
- // appropriate bit twiddling arithmetic. During this loop, we will also keep
- // track of the load which uses the lowest index. Later, we will check if we
- // can use its pointer in the final, combined load.
- for (auto Reg : RegsToVisit) {
- // Find the load, and find the position that it will end up in (e.g. a
- // shifted) value.
- auto LoadAndPos = matchLoadAndBytePosition(Reg, MemSizeInBits, MRI);
- if (!LoadAndPos)
- return None;
- MachineInstr *Load;
- int64_t DstPos;
- std::tie(Load, DstPos) = *LoadAndPos;
-
- // TODO: Handle multiple MachineBasicBlocks. Currently not handled because
- // it is difficult to check for stores/calls/etc between loads.
- MachineBasicBlock *LoadMBB = Load->getParent();
- if (!MBB)
- MBB = LoadMBB;
- if (LoadMBB != MBB)
- return None;
-
- // Make sure that the MachineMemOperands of every seen load are compatible.
- const MachineMemOperand *LoadMMO = *Load->memoperands_begin();
- if (!MMO)
- MMO = LoadMMO;
- if (MMO->getAddrSpace() != LoadMMO->getAddrSpace())
- return None;
-
- // Find out what the base pointer and index for the load is.
- Register LoadPtr;
- int64_t Idx;
- if (!mi_match(Load->getOperand(1).getReg(), MRI,
- m_GPtrAdd(m_Reg(LoadPtr), m_ICst(Idx)))) {
- LoadPtr = Load->getOperand(1).getReg();
- Idx = 0;
- }
-
- // Don't combine things like a[i], a[i] -> a bigger load.
- if (!SeenIdx.insert(Idx).second)
- return None;
-
- // Every load must share the same base pointer; don't combine things like:
- //
- // a[i], b[i + 1] -> a bigger load.
- if (!BasePtr.isValid())
- BasePtr = LoadPtr;
- if (BasePtr != LoadPtr)
- return None;
-
- if (Idx < LowestIdx) {
- LowestIdx = Idx;
- LowestIdxLoad = Load;
- }
-
- // Keep track of the byte offset that this load ends up at. If we have seen
- // the byte offset, then stop here. We do not want to combine:
- //
- // a[i] << 16, a[i + k] << 16 -> a bigger load.
- if (!MemOffset2Idx.try_emplace(DstPos, Idx).second)
- return None;
- Loads.insert(Load);
-
- // Keep track of the position of the earliest/latest loads in the pattern.
- // We will check that there are no load fold barriers between them later
- // on.
- //
- // FIXME: Is there a better way to check for load fold barriers?
- if (!EarliestLoad || dominates(*Load, *EarliestLoad))
- EarliestLoad = Load;
- if (!LatestLoad || dominates(*LatestLoad, *Load))
- LatestLoad = Load;
- }
-
- // We found a load for each register. Let's check if each load satisfies the
- // pattern.
- assert(Loads.size() == RegsToVisit.size() &&
- "Expected to find a load for each register?");
- assert(EarliestLoad != LatestLoad && EarliestLoad &&
- LatestLoad && "Expected at least two loads?");
-
- // Check if there are any stores, calls, etc. between any of the loads. If
- // there are, then we can't safely perform the combine.
- //
- // MaxIter is chosen based off the (worst case) number of iterations it
- // typically takes to succeed in the LLVM test suite plus some padding.
- //
- // FIXME: Is there a better way to check for load fold barriers?
- const unsigned MaxIter = 20;
- unsigned Iter = 0;
- for (const auto &MI : instructionsWithoutDebug(EarliestLoad->getIterator(),
- LatestLoad->getIterator())) {
- if (Loads.count(&MI))
- continue;
- if (MI.isLoadFoldBarrier())
- return None;
- if (Iter++ == MaxIter)
- return None;
- }
-
- return std::make_pair(LowestIdxLoad, LowestIdx);
-}
-
-bool CombinerHelper::matchLoadOrCombine(
- MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_OR);
- MachineFunction &MF = *MI.getMF();
- // Assuming a little-endian target, transform:
- // s8 *a = ...
- // s32 val = a[0] | (a[1] << 8) | (a[2] << 16) | (a[3] << 24)
- // =>
- // s32 val = *((i32)a)
- //
- // s8 *a = ...
- // s32 val = (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]
- // =>
- // s32 val = BSWAP(*((s32)a))
- Register Dst = MI.getOperand(0).getReg();
- LLT Ty = MRI.getType(Dst);
- if (Ty.isVector())
- return false;
-
- // We need to combine at least two loads into this type. Since the smallest
- // possible load is into a byte, we need at least a 16-bit wide type.
- const unsigned WideMemSizeInBits = Ty.getSizeInBits();
- if (WideMemSizeInBits < 16 || WideMemSizeInBits % 8 != 0)
- return false;
-
- // Match a collection of non-OR instructions in the pattern.
- auto RegsToVisit = findCandidatesForLoadOrCombine(&MI);
- if (!RegsToVisit)
- return false;
-
- // We have a collection of non-OR instructions. Figure out how wide each of
- // the small loads should be based off of the number of potential loads we
- // found.
- const unsigned NarrowMemSizeInBits = WideMemSizeInBits / RegsToVisit->size();
- if (NarrowMemSizeInBits % 8 != 0)
- return false;
-
- // Check if each register feeding into each OR is a load from the same
- // base pointer + some arithmetic.
- //
- // e.g. a[0], a[1] << 8, a[2] << 16, etc.
- //
- // Also verify that each of these ends up putting a[i] into the same memory
- // offset as a load into a wide type would.
- SmallDenseMap<int64_t, int64_t, 8> MemOffset2Idx;
- MachineInstr *LowestIdxLoad;
- int64_t LowestIdx;
- auto MaybeLoadInfo = findLoadOffsetsForLoadOrCombine(
- MemOffset2Idx, *RegsToVisit, NarrowMemSizeInBits);
- if (!MaybeLoadInfo)
- return false;
- std::tie(LowestIdxLoad, LowestIdx) = *MaybeLoadInfo;
-
- // We have a bunch of loads being OR'd together. Using the addresses + offsets
- // we found before, check if this corresponds to a big or little endian byte
- // pattern. If it does, then we can represent it using a load + possibly a
- // BSWAP.
- bool IsBigEndianTarget = MF.getDataLayout().isBigEndian();
- Optional<bool> IsBigEndian = isBigEndian(MemOffset2Idx, LowestIdx);
- if (!IsBigEndian.hasValue())
- return false;
- bool NeedsBSwap = IsBigEndianTarget != *IsBigEndian;
- if (NeedsBSwap && !isLegalOrBeforeLegalizer({TargetOpcode::G_BSWAP, {Ty}}))
- return false;
-
- // Make sure that the load from the lowest index produces offset 0 in the
- // final value.
- //
- // This ensures that we won't combine something like this:
- //
- // load x[i] -> byte 2
- // load x[i+1] -> byte 0 ---> wide_load x[i]
- // load x[i+2] -> byte 1
- const unsigned NumLoadsInTy = WideMemSizeInBits / NarrowMemSizeInBits;
- const unsigned ZeroByteOffset =
- *IsBigEndian
- ? bigEndianByteAt(NumLoadsInTy, 0)
- : littleEndianByteAt(NumLoadsInTy, 0);
- auto ZeroOffsetIdx = MemOffset2Idx.find(ZeroByteOffset);
- if (ZeroOffsetIdx == MemOffset2Idx.end() ||
- ZeroOffsetIdx->second != LowestIdx)
- return false;
-
- // We wil reuse the pointer from the load which ends up at byte offset 0. It
- // may not use index 0.
- Register Ptr = LowestIdxLoad->getOperand(1).getReg();
- const MachineMemOperand &MMO = **LowestIdxLoad->memoperands_begin();
- LegalityQuery::MemDesc MMDesc;
- MMDesc.SizeInBits = WideMemSizeInBits;
- MMDesc.AlignInBits = MMO.getAlign().value() * 8;
- MMDesc.Ordering = MMO.getOrdering();
- if (!isLegalOrBeforeLegalizer(
- {TargetOpcode::G_LOAD, {Ty, MRI.getType(Ptr)}, {MMDesc}}))
- return false;
- auto PtrInfo = MMO.getPointerInfo();
- auto *NewMMO = MF.getMachineMemOperand(&MMO, PtrInfo, WideMemSizeInBits / 8);
-
- // Load must be allowed and fast on the target.
- LLVMContext &C = MF.getFunction().getContext();
- auto &DL = MF.getDataLayout();
- bool Fast = false;
- if (!getTargetLowering().allowsMemoryAccess(C, DL, Ty, *NewMMO, &Fast) ||
- !Fast)
- return false;
-
- MatchInfo = [=](MachineIRBuilder &MIB) {
- Register LoadDst = NeedsBSwap ? MRI.cloneVirtualRegister(Dst) : Dst;
- MIB.buildLoad(LoadDst, Ptr, *NewMMO);
- if (NeedsBSwap)
- MIB.buildBSwap(Dst, LoadDst);
- };
- return true;
-}
-
-bool CombinerHelper::applyLoadOrCombine(
- MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
- Builder.setInstrAndDebugLoc(MI);
- MatchInfo(Builder);
- MI.eraseFromParent();
- return true;
-}
-
+bool CombinerHelper::matchHoistLogicOpWithSameOpcodeHands(
+ MachineInstr &MI, InstructionStepsMatchInfo &MatchInfo) {
+ // Matches: logic (hand x, ...), (hand y, ...) -> hand (logic x, y), ...
+ //
+ // Creates the new hand + logic instruction (but does not insert them.)
+ //
+ // On success, MatchInfo is populated with the new instructions. These are
+ // inserted in applyHoistLogicOpWithSameOpcodeHands.
+ unsigned LogicOpcode = MI.getOpcode();
+ assert(LogicOpcode == TargetOpcode::G_AND ||
+ LogicOpcode == TargetOpcode::G_OR ||
+ LogicOpcode == TargetOpcode::G_XOR);
+ MachineIRBuilder MIB(MI);
+ Register Dst = MI.getOperand(0).getReg();
+ Register LHSReg = MI.getOperand(1).getReg();
+ Register RHSReg = MI.getOperand(2).getReg();
+
+ // Don't recompute anything.
+ if (!MRI.hasOneNonDBGUse(LHSReg) || !MRI.hasOneNonDBGUse(RHSReg))
+ return false;
+
+ // Make sure we have (hand x, ...), (hand y, ...)
+ MachineInstr *LeftHandInst = getDefIgnoringCopies(LHSReg, MRI);
+ MachineInstr *RightHandInst = getDefIgnoringCopies(RHSReg, MRI);
+ if (!LeftHandInst || !RightHandInst)
+ return false;
+ unsigned HandOpcode = LeftHandInst->getOpcode();
+ if (HandOpcode != RightHandInst->getOpcode())
+ return false;
+ if (!LeftHandInst->getOperand(1).isReg() ||
+ !RightHandInst->getOperand(1).isReg())
+ return false;
+
+ // Make sure the types match up, and if we're doing this post-legalization,
+ // we end up with legal types.
+ Register X = LeftHandInst->getOperand(1).getReg();
+ Register Y = RightHandInst->getOperand(1).getReg();
+ LLT XTy = MRI.getType(X);
+ LLT YTy = MRI.getType(Y);
+ if (XTy != YTy)
+ return false;
+ if (!isLegalOrBeforeLegalizer({LogicOpcode, {XTy, YTy}}))
+ return false;
+
+ // Optional extra source register.
+ Register ExtraHandOpSrcReg;
+ switch (HandOpcode) {
+ default:
+ return false;
+ case TargetOpcode::G_ANYEXT:
+ case TargetOpcode::G_SEXT:
+ case TargetOpcode::G_ZEXT: {
+ // Match: logic (ext X), (ext Y) --> ext (logic X, Y)
+ break;
+ }
+ case TargetOpcode::G_AND:
+ case TargetOpcode::G_ASHR:
+ case TargetOpcode::G_LSHR:
+ case TargetOpcode::G_SHL: {
+ // Match: logic (binop x, z), (binop y, z) -> binop (logic x, y), z
+ MachineOperand &ZOp = LeftHandInst->getOperand(2);
+ if (!matchEqualDefs(ZOp, RightHandInst->getOperand(2)))
+ return false;
+ ExtraHandOpSrcReg = ZOp.getReg();
+ break;
+ }
+ }
+
+ // Record the steps to build the new instructions.
+ //
+ // Steps to build (logic x, y)
+ auto NewLogicDst = MRI.createGenericVirtualRegister(XTy);
+ OperandBuildSteps LogicBuildSteps = {
+ [=](MachineInstrBuilder &MIB) { MIB.addDef(NewLogicDst); },
+ [=](MachineInstrBuilder &MIB) { MIB.addReg(X); },
+ [=](MachineInstrBuilder &MIB) { MIB.addReg(Y); }};
+ InstructionBuildSteps LogicSteps(LogicOpcode, LogicBuildSteps);
+
+ // Steps to build hand (logic x, y), ...z
+ OperandBuildSteps HandBuildSteps = {
+ [=](MachineInstrBuilder &MIB) { MIB.addDef(Dst); },
+ [=](MachineInstrBuilder &MIB) { MIB.addReg(NewLogicDst); }};
+ if (ExtraHandOpSrcReg.isValid())
+ HandBuildSteps.push_back(
+ [=](MachineInstrBuilder &MIB) { MIB.addReg(ExtraHandOpSrcReg); });
+ InstructionBuildSteps HandSteps(HandOpcode, HandBuildSteps);
+
+ MatchInfo = InstructionStepsMatchInfo({LogicSteps, HandSteps});
+ return true;
+}
+
+bool CombinerHelper::applyBuildInstructionSteps(
+ MachineInstr &MI, InstructionStepsMatchInfo &MatchInfo) {
+ assert(MatchInfo.InstrsToBuild.size() &&
+ "Expected at least one instr to build?");
+ Builder.setInstr(MI);
+ for (auto &InstrToBuild : MatchInfo.InstrsToBuild) {
+ assert(InstrToBuild.Opcode && "Expected a valid opcode?");
+ assert(InstrToBuild.OperandFns.size() && "Expected at least one operand?");
+ MachineInstrBuilder Instr = Builder.buildInstr(InstrToBuild.Opcode);
+ for (auto &OperandFn : InstrToBuild.OperandFns)
+ OperandFn(Instr);
+ }
+ MI.eraseFromParent();
+ return true;
+}
+
+bool CombinerHelper::matchAshrShlToSextInreg(
+ MachineInstr &MI, std::tuple<Register, int64_t> &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_ASHR);
+ int64_t ShlCst, AshrCst;
+ Register Src;
+ // FIXME: detect splat constant vectors.
+ if (!mi_match(MI.getOperand(0).getReg(), MRI,
+ m_GAShr(m_GShl(m_Reg(Src), m_ICst(ShlCst)), m_ICst(AshrCst))))
+ return false;
+ if (ShlCst != AshrCst)
+ return false;
+ if (!isLegalOrBeforeLegalizer(
+ {TargetOpcode::G_SEXT_INREG, {MRI.getType(Src)}}))
+ return false;
+ MatchInfo = std::make_tuple(Src, ShlCst);
+ return true;
+}
+bool CombinerHelper::applyAshShlToSextInreg(
+ MachineInstr &MI, std::tuple<Register, int64_t> &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_ASHR);
+ Register Src;
+ int64_t ShiftAmt;
+ std::tie(Src, ShiftAmt) = MatchInfo;
+ unsigned Size = MRI.getType(Src).getScalarSizeInBits();
+ Builder.setInstrAndDebugLoc(MI);
+ Builder.buildSExtInReg(MI.getOperand(0).getReg(), Src, Size - ShiftAmt);
+ MI.eraseFromParent();
+ return true;
+}
+
+bool CombinerHelper::matchRedundantAnd(MachineInstr &MI,
+ Register &Replacement) {
+ // Given
+ //
+ // %y:_(sN) = G_SOMETHING
+ // %x:_(sN) = G_SOMETHING
+ // %res:_(sN) = G_AND %x, %y
+ //
+ // Eliminate the G_AND when it is known that x & y == x or x & y == y.
+ //
+ // Patterns like this can appear as a result of legalization. E.g.
+ //
+ // %cmp:_(s32) = G_ICMP intpred(pred), %x(s32), %y
+ // %one:_(s32) = G_CONSTANT i32 1
+ // %and:_(s32) = G_AND %cmp, %one
+ //
+ // In this case, G_ICMP only produces a single bit, so x & 1 == x.
+ assert(MI.getOpcode() == TargetOpcode::G_AND);
+ if (!KB)
+ return false;
+
+ Register AndDst = MI.getOperand(0).getReg();
+ LLT DstTy = MRI.getType(AndDst);
+
+ // FIXME: This should be removed once GISelKnownBits supports vectors.
+ if (DstTy.isVector())
+ return false;
+
+ Register LHS = MI.getOperand(1).getReg();
+ Register RHS = MI.getOperand(2).getReg();
+ KnownBits LHSBits = KB->getKnownBits(LHS);
+ KnownBits RHSBits = KB->getKnownBits(RHS);
+
+ // Check that x & Mask == x.
+ // x & 1 == x, always
+ // x & 0 == x, only if x is also 0
+ // Meaning Mask has no effect if every bit is either one in Mask or zero in x.
+ //
+ // Check if we can replace AndDst with the LHS of the G_AND
+ if (canReplaceReg(AndDst, LHS, MRI) &&
+ (LHSBits.Zero | RHSBits.One).isAllOnesValue()) {
+ Replacement = LHS;
+ return true;
+ }
+
+ // Check if we can replace AndDst with the RHS of the G_AND
+ if (canReplaceReg(AndDst, RHS, MRI) &&
+ (LHSBits.One | RHSBits.Zero).isAllOnesValue()) {
+ Replacement = RHS;
+ return true;
+ }
+
+ return false;
+}
+
+bool CombinerHelper::matchRedundantOr(MachineInstr &MI, Register &Replacement) {
+ // Given
+ //
+ // %y:_(sN) = G_SOMETHING
+ // %x:_(sN) = G_SOMETHING
+ // %res:_(sN) = G_OR %x, %y
+ //
+ // Eliminate the G_OR when it is known that x | y == x or x | y == y.
+ assert(MI.getOpcode() == TargetOpcode::G_OR);
+ if (!KB)
+ return false;
+
+ Register OrDst = MI.getOperand(0).getReg();
+ LLT DstTy = MRI.getType(OrDst);
+
+ // FIXME: This should be removed once GISelKnownBits supports vectors.
+ if (DstTy.isVector())
+ return false;
+
+ Register LHS = MI.getOperand(1).getReg();
+ Register RHS = MI.getOperand(2).getReg();
+ KnownBits LHSBits = KB->getKnownBits(LHS);
+ KnownBits RHSBits = KB->getKnownBits(RHS);
+
+ // Check that x | Mask == x.
+ // x | 0 == x, always
+ // x | 1 == x, only if x is also 1
+ // Meaning Mask has no effect if every bit is either zero in Mask or one in x.
+ //
+ // Check if we can replace OrDst with the LHS of the G_OR
+ if (canReplaceReg(OrDst, LHS, MRI) &&
+ (LHSBits.One | RHSBits.Zero).isAllOnesValue()) {
+ Replacement = LHS;
+ return true;
+ }
+
+ // Check if we can replace OrDst with the RHS of the G_OR
+ if (canReplaceReg(OrDst, RHS, MRI) &&
+ (LHSBits.Zero | RHSBits.One).isAllOnesValue()) {
+ Replacement = RHS;
+ return true;
+ }
+
+ return false;
+}
+
+bool CombinerHelper::matchRedundantSExtInReg(MachineInstr &MI) {
+ // If the input is already sign extended, just drop the extension.
+ Register Src = MI.getOperand(1).getReg();
+ unsigned ExtBits = MI.getOperand(2).getImm();
+ unsigned TypeSize = MRI.getType(Src).getScalarSizeInBits();
+ return KB->computeNumSignBits(Src) >= (TypeSize - ExtBits + 1);
+}
+
+static bool isConstValidTrue(const TargetLowering &TLI, unsigned ScalarSizeBits,
+ int64_t Cst, bool IsVector, bool IsFP) {
+ // For i1, Cst will always be -1 regardless of boolean contents.
+ return (ScalarSizeBits == 1 && Cst == -1) ||
+ isConstTrueVal(TLI, Cst, IsVector, IsFP);
+}
+
+bool CombinerHelper::matchNotCmp(MachineInstr &MI,
+ SmallVectorImpl<Register> &RegsToNegate) {
+ assert(MI.getOpcode() == TargetOpcode::G_XOR);
+ LLT Ty = MRI.getType(MI.getOperand(0).getReg());
+ const auto &TLI = *Builder.getMF().getSubtarget().getTargetLowering();
+ Register XorSrc;
+ Register CstReg;
+ // We match xor(src, true) here.
+ if (!mi_match(MI.getOperand(0).getReg(), MRI,
+ m_GXor(m_Reg(XorSrc), m_Reg(CstReg))))
+ return false;
+
+ if (!MRI.hasOneNonDBGUse(XorSrc))
+ return false;
+
+ // Check that XorSrc is the root of a tree of comparisons combined with ANDs
+ // and ORs. The suffix of RegsToNegate starting from index I is used a work
+ // list of tree nodes to visit.
+ RegsToNegate.push_back(XorSrc);
+ // Remember whether the comparisons are all integer or all floating point.
+ bool IsInt = false;
+ bool IsFP = false;
+ for (unsigned I = 0; I < RegsToNegate.size(); ++I) {
+ Register Reg = RegsToNegate[I];
+ if (!MRI.hasOneNonDBGUse(Reg))
+ return false;
+ MachineInstr *Def = MRI.getVRegDef(Reg);
+ switch (Def->getOpcode()) {
+ default:
+ // Don't match if the tree contains anything other than ANDs, ORs and
+ // comparisons.
+ return false;
+ case TargetOpcode::G_ICMP:
+ if (IsFP)
+ return false;
+ IsInt = true;
+ // When we apply the combine we will invert the predicate.
+ break;
+ case TargetOpcode::G_FCMP:
+ if (IsInt)
+ return false;
+ IsFP = true;
+ // When we apply the combine we will invert the predicate.
+ break;
+ case TargetOpcode::G_AND:
+ case TargetOpcode::G_OR:
+ // Implement De Morgan's laws:
+ // ~(x & y) -> ~x | ~y
+ // ~(x | y) -> ~x & ~y
+ // When we apply the combine we will change the opcode and recursively
+ // negate the operands.
+ RegsToNegate.push_back(Def->getOperand(1).getReg());
+ RegsToNegate.push_back(Def->getOperand(2).getReg());
+ break;
+ }
+ }
+
+ // Now we know whether the comparisons are integer or floating point, check
+ // the constant in the xor.
+ int64_t Cst;
+ if (Ty.isVector()) {
+ MachineInstr *CstDef = MRI.getVRegDef(CstReg);
+ auto MaybeCst = getBuildVectorConstantSplat(*CstDef, MRI);
+ if (!MaybeCst)
+ return false;
+ if (!isConstValidTrue(TLI, Ty.getScalarSizeInBits(), *MaybeCst, true, IsFP))
+ return false;
+ } else {
+ if (!mi_match(CstReg, MRI, m_ICst(Cst)))
+ return false;
+ if (!isConstValidTrue(TLI, Ty.getSizeInBits(), Cst, false, IsFP))
+ return false;
+ }
+
+ return true;
+}
+
+bool CombinerHelper::applyNotCmp(MachineInstr &MI,
+ SmallVectorImpl<Register> &RegsToNegate) {
+ for (Register Reg : RegsToNegate) {
+ MachineInstr *Def = MRI.getVRegDef(Reg);
+ Observer.changingInstr(*Def);
+ // For each comparison, invert the opcode. For each AND and OR, change the
+ // opcode.
+ switch (Def->getOpcode()) {
+ default:
+ llvm_unreachable("Unexpected opcode");
+ case TargetOpcode::G_ICMP:
+ case TargetOpcode::G_FCMP: {
+ MachineOperand &PredOp = Def->getOperand(1);
+ CmpInst::Predicate NewP = CmpInst::getInversePredicate(
+ (CmpInst::Predicate)PredOp.getPredicate());
+ PredOp.setPredicate(NewP);
+ break;
+ }
+ case TargetOpcode::G_AND:
+ Def->setDesc(Builder.getTII().get(TargetOpcode::G_OR));
+ break;
+ case TargetOpcode::G_OR:
+ Def->setDesc(Builder.getTII().get(TargetOpcode::G_AND));
+ break;
+ }
+ Observer.changedInstr(*Def);
+ }
+
+ replaceRegWith(MRI, MI.getOperand(0).getReg(), MI.getOperand(1).getReg());
+ MI.eraseFromParent();
+ return true;
+}
+
+bool CombinerHelper::matchXorOfAndWithSameReg(
+ MachineInstr &MI, std::pair<Register, Register> &MatchInfo) {
+ // Match (xor (and x, y), y) (or any of its commuted cases)
+ assert(MI.getOpcode() == TargetOpcode::G_XOR);
+ Register &X = MatchInfo.first;
+ Register &Y = MatchInfo.second;
+ Register AndReg = MI.getOperand(1).getReg();
+ Register SharedReg = MI.getOperand(2).getReg();
+
+ // Find a G_AND on either side of the G_XOR.
+ // Look for one of
+ //
+ // (xor (and x, y), SharedReg)
+ // (xor SharedReg, (and x, y))
+ if (!mi_match(AndReg, MRI, m_GAnd(m_Reg(X), m_Reg(Y)))) {
+ std::swap(AndReg, SharedReg);
+ if (!mi_match(AndReg, MRI, m_GAnd(m_Reg(X), m_Reg(Y))))
+ return false;
+ }
+
+ // Only do this if we'll eliminate the G_AND.
+ if (!MRI.hasOneNonDBGUse(AndReg))
+ return false;
+
+ // We can combine if SharedReg is the same as either the LHS or RHS of the
+ // G_AND.
+ if (Y != SharedReg)
+ std::swap(X, Y);
+ return Y == SharedReg;
+}
+
+bool CombinerHelper::applyXorOfAndWithSameReg(
+ MachineInstr &MI, std::pair<Register, Register> &MatchInfo) {
+ // Fold (xor (and x, y), y) -> (and (not x), y)
+ Builder.setInstrAndDebugLoc(MI);
+ Register X, Y;
+ std::tie(X, Y) = MatchInfo;
+ auto Not = Builder.buildNot(MRI.getType(X), X);
+ Observer.changingInstr(MI);
+ MI.setDesc(Builder.getTII().get(TargetOpcode::G_AND));
+ MI.getOperand(1).setReg(Not->getOperand(0).getReg());
+ MI.getOperand(2).setReg(Y);
+ Observer.changedInstr(MI);
+ return true;
+}
+
+bool CombinerHelper::matchPtrAddZero(MachineInstr &MI) {
+ Register DstReg = MI.getOperand(0).getReg();
+ LLT Ty = MRI.getType(DstReg);
+ const DataLayout &DL = Builder.getMF().getDataLayout();
+
+ if (DL.isNonIntegralAddressSpace(Ty.getScalarType().getAddressSpace()))
+ return false;
+
+ if (Ty.isPointer()) {
+ auto ConstVal = getConstantVRegVal(MI.getOperand(1).getReg(), MRI);
+ return ConstVal && *ConstVal == 0;
+ }
+
+ assert(Ty.isVector() && "Expecting a vector type");
+ const MachineInstr *VecMI = MRI.getVRegDef(MI.getOperand(1).getReg());
+ return isBuildVectorAllZeros(*VecMI, MRI);
+}
+
+bool CombinerHelper::applyPtrAddZero(MachineInstr &MI) {
+ assert(MI.getOpcode() == TargetOpcode::G_PTR_ADD);
+ Builder.setInstrAndDebugLoc(MI);
+ Builder.buildIntToPtr(MI.getOperand(0), MI.getOperand(2));
+ MI.eraseFromParent();
+ return true;
+}
+
+/// The second source operand is known to be a power of 2.
+bool CombinerHelper::applySimplifyURemByPow2(MachineInstr &MI) {
+ Register DstReg = MI.getOperand(0).getReg();
+ Register Src0 = MI.getOperand(1).getReg();
+ Register Pow2Src1 = MI.getOperand(2).getReg();
+ LLT Ty = MRI.getType(DstReg);
+ Builder.setInstrAndDebugLoc(MI);
+
+ // Fold (urem x, pow2) -> (and x, pow2-1)
+ auto NegOne = Builder.buildConstant(Ty, -1);
+ auto Add = Builder.buildAdd(Ty, Pow2Src1, NegOne);
+ Builder.buildAnd(DstReg, Src0, Add);
+ MI.eraseFromParent();
+ return true;
+}
+
+Optional<SmallVector<Register, 8>>
+CombinerHelper::findCandidatesForLoadOrCombine(const MachineInstr *Root) const {
+ assert(Root->getOpcode() == TargetOpcode::G_OR && "Expected G_OR only!");
+ // We want to detect if Root is part of a tree which represents a bunch
+ // of loads being merged into a larger load. We'll try to recognize patterns
+ // like, for example:
+ //
+ // Reg Reg
+ // \ /
+ // OR_1 Reg
+ // \ /
+ // OR_2
+ // \ Reg
+ // .. /
+ // Root
+ //
+ // Reg Reg Reg Reg
+ // \ / \ /
+ // OR_1 OR_2
+ // \ /
+ // \ /
+ // ...
+ // Root
+ //
+ // Each "Reg" may have been produced by a load + some arithmetic. This
+ // function will save each of them.
+ SmallVector<Register, 8> RegsToVisit;
+ SmallVector<const MachineInstr *, 7> Ors = {Root};
+
+ // In the "worst" case, we're dealing with a load for each byte. So, there
+ // are at most #bytes - 1 ORs.
+ const unsigned MaxIter =
+ MRI.getType(Root->getOperand(0).getReg()).getSizeInBytes() - 1;
+ for (unsigned Iter = 0; Iter < MaxIter; ++Iter) {
+ if (Ors.empty())
+ break;
+ const MachineInstr *Curr = Ors.pop_back_val();
+ Register OrLHS = Curr->getOperand(1).getReg();
+ Register OrRHS = Curr->getOperand(2).getReg();
+
+ // In the combine, we want to elimate the entire tree.
+ if (!MRI.hasOneNonDBGUse(OrLHS) || !MRI.hasOneNonDBGUse(OrRHS))
+ return None;
+
+ // If it's a G_OR, save it and continue to walk. If it's not, then it's
+ // something that may be a load + arithmetic.
+ if (const MachineInstr *Or = getOpcodeDef(TargetOpcode::G_OR, OrLHS, MRI))
+ Ors.push_back(Or);
+ else
+ RegsToVisit.push_back(OrLHS);
+ if (const MachineInstr *Or = getOpcodeDef(TargetOpcode::G_OR, OrRHS, MRI))
+ Ors.push_back(Or);
+ else
+ RegsToVisit.push_back(OrRHS);
+ }
+
+ // We're going to try and merge each register into a wider power-of-2 type,
+ // so we ought to have an even number of registers.
+ if (RegsToVisit.empty() || RegsToVisit.size() % 2 != 0)
+ return None;
+ return RegsToVisit;
+}
+
+/// Helper function for findLoadOffsetsForLoadOrCombine.
+///
+/// Check if \p Reg is the result of loading a \p MemSizeInBits wide value,
+/// and then moving that value into a specific byte offset.
+///
+/// e.g. x[i] << 24
+///
+/// \returns The load instruction and the byte offset it is moved into.
+static Optional<std::pair<MachineInstr *, int64_t>>
+matchLoadAndBytePosition(Register Reg, unsigned MemSizeInBits,
+ const MachineRegisterInfo &MRI) {
+ assert(MRI.hasOneNonDBGUse(Reg) &&
+ "Expected Reg to only have one non-debug use?");
+ Register MaybeLoad;
+ int64_t Shift;
+ if (!mi_match(Reg, MRI,
+ m_OneNonDBGUse(m_GShl(m_Reg(MaybeLoad), m_ICst(Shift))))) {
+ Shift = 0;
+ MaybeLoad = Reg;
+ }
+
+ if (Shift % MemSizeInBits != 0)
+ return None;
+
+ // TODO: Handle other types of loads.
+ auto *Load = getOpcodeDef(TargetOpcode::G_ZEXTLOAD, MaybeLoad, MRI);
+ if (!Load)
+ return None;
+
+ const auto &MMO = **Load->memoperands_begin();
+ if (!MMO.isUnordered() || MMO.getSizeInBits() != MemSizeInBits)
+ return None;
+
+ return std::make_pair(Load, Shift / MemSizeInBits);
+}
+
+Optional<std::pair<MachineInstr *, int64_t>>
+CombinerHelper::findLoadOffsetsForLoadOrCombine(
+ SmallDenseMap<int64_t, int64_t, 8> &MemOffset2Idx,
+ const SmallVector<Register, 8> &RegsToVisit, const unsigned MemSizeInBits) {
+
+ // Each load found for the pattern. There should be one for each RegsToVisit.
+ SmallSetVector<const MachineInstr *, 8> Loads;
+
+ // The lowest index used in any load. (The lowest "i" for each x[i].)
+ int64_t LowestIdx = INT64_MAX;
+
+ // The load which uses the lowest index.
+ MachineInstr *LowestIdxLoad = nullptr;
+
+ // Keeps track of the load indices we see. We shouldn't see any indices twice.
+ SmallSet<int64_t, 8> SeenIdx;
+
+ // Ensure each load is in the same MBB.
+ // TODO: Support multiple MachineBasicBlocks.
+ MachineBasicBlock *MBB = nullptr;
+ const MachineMemOperand *MMO = nullptr;
+
+ // Earliest instruction-order load in the pattern.
+ MachineInstr *EarliestLoad = nullptr;
+
+ // Latest instruction-order load in the pattern.
+ MachineInstr *LatestLoad = nullptr;
+
+ // Base pointer which every load should share.
+ Register BasePtr;
+
+ // We want to find a load for each register. Each load should have some
+ // appropriate bit twiddling arithmetic. During this loop, we will also keep
+ // track of the load which uses the lowest index. Later, we will check if we
+ // can use its pointer in the final, combined load.
+ for (auto Reg : RegsToVisit) {
+ // Find the load, and find the position that it will end up in (e.g. a
+ // shifted) value.
+ auto LoadAndPos = matchLoadAndBytePosition(Reg, MemSizeInBits, MRI);
+ if (!LoadAndPos)
+ return None;
+ MachineInstr *Load;
+ int64_t DstPos;
+ std::tie(Load, DstPos) = *LoadAndPos;
+
+ // TODO: Handle multiple MachineBasicBlocks. Currently not handled because
+ // it is difficult to check for stores/calls/etc between loads.
+ MachineBasicBlock *LoadMBB = Load->getParent();
+ if (!MBB)
+ MBB = LoadMBB;
+ if (LoadMBB != MBB)
+ return None;
+
+ // Make sure that the MachineMemOperands of every seen load are compatible.
+ const MachineMemOperand *LoadMMO = *Load->memoperands_begin();
+ if (!MMO)
+ MMO = LoadMMO;
+ if (MMO->getAddrSpace() != LoadMMO->getAddrSpace())
+ return None;
+
+ // Find out what the base pointer and index for the load is.
+ Register LoadPtr;
+ int64_t Idx;
+ if (!mi_match(Load->getOperand(1).getReg(), MRI,
+ m_GPtrAdd(m_Reg(LoadPtr), m_ICst(Idx)))) {
+ LoadPtr = Load->getOperand(1).getReg();
+ Idx = 0;
+ }
+
+ // Don't combine things like a[i], a[i] -> a bigger load.
+ if (!SeenIdx.insert(Idx).second)
+ return None;
+
+ // Every load must share the same base pointer; don't combine things like:
+ //
+ // a[i], b[i + 1] -> a bigger load.
+ if (!BasePtr.isValid())
+ BasePtr = LoadPtr;
+ if (BasePtr != LoadPtr)
+ return None;
+
+ if (Idx < LowestIdx) {
+ LowestIdx = Idx;
+ LowestIdxLoad = Load;
+ }
+
+ // Keep track of the byte offset that this load ends up at. If we have seen
+ // the byte offset, then stop here. We do not want to combine:
+ //
+ // a[i] << 16, a[i + k] << 16 -> a bigger load.
+ if (!MemOffset2Idx.try_emplace(DstPos, Idx).second)
+ return None;
+ Loads.insert(Load);
+
+ // Keep track of the position of the earliest/latest loads in the pattern.
+ // We will check that there are no load fold barriers between them later
+ // on.
+ //
+ // FIXME: Is there a better way to check for load fold barriers?
+ if (!EarliestLoad || dominates(*Load, *EarliestLoad))
+ EarliestLoad = Load;
+ if (!LatestLoad || dominates(*LatestLoad, *Load))
+ LatestLoad = Load;
+ }
+
+ // We found a load for each register. Let's check if each load satisfies the
+ // pattern.
+ assert(Loads.size() == RegsToVisit.size() &&
+ "Expected to find a load for each register?");
+ assert(EarliestLoad != LatestLoad && EarliestLoad &&
+ LatestLoad && "Expected at least two loads?");
+
+ // Check if there are any stores, calls, etc. between any of the loads. If
+ // there are, then we can't safely perform the combine.
+ //
+ // MaxIter is chosen based off the (worst case) number of iterations it
+ // typically takes to succeed in the LLVM test suite plus some padding.
+ //
+ // FIXME: Is there a better way to check for load fold barriers?
+ const unsigned MaxIter = 20;
+ unsigned Iter = 0;
+ for (const auto &MI : instructionsWithoutDebug(EarliestLoad->getIterator(),
+ LatestLoad->getIterator())) {
+ if (Loads.count(&MI))
+ continue;
+ if (MI.isLoadFoldBarrier())
+ return None;
+ if (Iter++ == MaxIter)
+ return None;
+ }
+
+ return std::make_pair(LowestIdxLoad, LowestIdx);
+}
+
+bool CombinerHelper::matchLoadOrCombine(
+ MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_OR);
+ MachineFunction &MF = *MI.getMF();
+ // Assuming a little-endian target, transform:
+ // s8 *a = ...
+ // s32 val = a[0] | (a[1] << 8) | (a[2] << 16) | (a[3] << 24)
+ // =>
+ // s32 val = *((i32)a)
+ //
+ // s8 *a = ...
+ // s32 val = (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]
+ // =>
+ // s32 val = BSWAP(*((s32)a))
+ Register Dst = MI.getOperand(0).getReg();
+ LLT Ty = MRI.getType(Dst);
+ if (Ty.isVector())
+ return false;
+
+ // We need to combine at least two loads into this type. Since the smallest
+ // possible load is into a byte, we need at least a 16-bit wide type.
+ const unsigned WideMemSizeInBits = Ty.getSizeInBits();
+ if (WideMemSizeInBits < 16 || WideMemSizeInBits % 8 != 0)
+ return false;
+
+ // Match a collection of non-OR instructions in the pattern.
+ auto RegsToVisit = findCandidatesForLoadOrCombine(&MI);
+ if (!RegsToVisit)
+ return false;
+
+ // We have a collection of non-OR instructions. Figure out how wide each of
+ // the small loads should be based off of the number of potential loads we
+ // found.
+ const unsigned NarrowMemSizeInBits = WideMemSizeInBits / RegsToVisit->size();
+ if (NarrowMemSizeInBits % 8 != 0)
+ return false;
+
+ // Check if each register feeding into each OR is a load from the same
+ // base pointer + some arithmetic.
+ //
+ // e.g. a[0], a[1] << 8, a[2] << 16, etc.
+ //
+ // Also verify that each of these ends up putting a[i] into the same memory
+ // offset as a load into a wide type would.
+ SmallDenseMap<int64_t, int64_t, 8> MemOffset2Idx;
+ MachineInstr *LowestIdxLoad;
+ int64_t LowestIdx;
+ auto MaybeLoadInfo = findLoadOffsetsForLoadOrCombine(
+ MemOffset2Idx, *RegsToVisit, NarrowMemSizeInBits);
+ if (!MaybeLoadInfo)
+ return false;
+ std::tie(LowestIdxLoad, LowestIdx) = *MaybeLoadInfo;
+
+ // We have a bunch of loads being OR'd together. Using the addresses + offsets
+ // we found before, check if this corresponds to a big or little endian byte
+ // pattern. If it does, then we can represent it using a load + possibly a
+ // BSWAP.
+ bool IsBigEndianTarget = MF.getDataLayout().isBigEndian();
+ Optional<bool> IsBigEndian = isBigEndian(MemOffset2Idx, LowestIdx);
+ if (!IsBigEndian.hasValue())
+ return false;
+ bool NeedsBSwap = IsBigEndianTarget != *IsBigEndian;
+ if (NeedsBSwap && !isLegalOrBeforeLegalizer({TargetOpcode::G_BSWAP, {Ty}}))
+ return false;
+
+ // Make sure that the load from the lowest index produces offset 0 in the
+ // final value.
+ //
+ // This ensures that we won't combine something like this:
+ //
+ // load x[i] -> byte 2
+ // load x[i+1] -> byte 0 ---> wide_load x[i]
+ // load x[i+2] -> byte 1
+ const unsigned NumLoadsInTy = WideMemSizeInBits / NarrowMemSizeInBits;
+ const unsigned ZeroByteOffset =
+ *IsBigEndian
+ ? bigEndianByteAt(NumLoadsInTy, 0)
+ : littleEndianByteAt(NumLoadsInTy, 0);
+ auto ZeroOffsetIdx = MemOffset2Idx.find(ZeroByteOffset);
+ if (ZeroOffsetIdx == MemOffset2Idx.end() ||
+ ZeroOffsetIdx->second != LowestIdx)
+ return false;
+
+ // We wil reuse the pointer from the load which ends up at byte offset 0. It
+ // may not use index 0.
+ Register Ptr = LowestIdxLoad->getOperand(1).getReg();
+ const MachineMemOperand &MMO = **LowestIdxLoad->memoperands_begin();
+ LegalityQuery::MemDesc MMDesc;
+ MMDesc.SizeInBits = WideMemSizeInBits;
+ MMDesc.AlignInBits = MMO.getAlign().value() * 8;
+ MMDesc.Ordering = MMO.getOrdering();
+ if (!isLegalOrBeforeLegalizer(
+ {TargetOpcode::G_LOAD, {Ty, MRI.getType(Ptr)}, {MMDesc}}))
+ return false;
+ auto PtrInfo = MMO.getPointerInfo();
+ auto *NewMMO = MF.getMachineMemOperand(&MMO, PtrInfo, WideMemSizeInBits / 8);
+
+ // Load must be allowed and fast on the target.
+ LLVMContext &C = MF.getFunction().getContext();
+ auto &DL = MF.getDataLayout();
+ bool Fast = false;
+ if (!getTargetLowering().allowsMemoryAccess(C, DL, Ty, *NewMMO, &Fast) ||
+ !Fast)
+ return false;
+
+ MatchInfo = [=](MachineIRBuilder &MIB) {
+ Register LoadDst = NeedsBSwap ? MRI.cloneVirtualRegister(Dst) : Dst;
+ MIB.buildLoad(LoadDst, Ptr, *NewMMO);
+ if (NeedsBSwap)
+ MIB.buildBSwap(Dst, LoadDst);
+ };
+ return true;
+}
+
+bool CombinerHelper::applyLoadOrCombine(
+ MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
+ Builder.setInstrAndDebugLoc(MI);
+ MatchInfo(Builder);
+ MI.eraseFromParent();
+ return true;
+}
+
bool CombinerHelper::tryCombine(MachineInstr &MI) {
if (tryCombineCopy(MI))
return true;
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/GISelChangeObserver.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/GISelChangeObserver.cpp
index 6bc72e4aa9..59f4d60a41 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/GISelChangeObserver.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/GISelChangeObserver.cpp
@@ -16,7 +16,7 @@
using namespace llvm;
void GISelChangeObserver::changingAllUsesOfReg(
- const MachineRegisterInfo &MRI, Register Reg) {
+ const MachineRegisterInfo &MRI, Register Reg) {
for (auto &ChangingMI : MRI.use_instructions(Reg)) {
changingInstr(ChangingMI);
ChangingAllUsesOfReg.insert(&ChangingMI);
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/GISelKnownBits.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/GISelKnownBits.cpp
index e38ede1b67..2de20489e1 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/GISelKnownBits.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/GISelKnownBits.cpp
@@ -94,25 +94,25 @@ dumpResult(const MachineInstr &MI, const KnownBits &Known, unsigned Depth) {
<< "\n";
}
-/// Compute known bits for the intersection of \p Src0 and \p Src1
-void GISelKnownBits::computeKnownBitsMin(Register Src0, Register Src1,
- KnownBits &Known,
- const APInt &DemandedElts,
- unsigned Depth) {
- // Test src1 first, since we canonicalize simpler expressions to the RHS.
- computeKnownBitsImpl(Src1, Known, DemandedElts, Depth);
-
- // If we don't know any bits, early out.
- if (Known.isUnknown())
- return;
-
- KnownBits Known2;
- computeKnownBitsImpl(Src0, Known2, DemandedElts, Depth);
-
- // Only known if known in both the LHS and RHS.
- Known = KnownBits::commonBits(Known, Known2);
-}
-
+/// Compute known bits for the intersection of \p Src0 and \p Src1
+void GISelKnownBits::computeKnownBitsMin(Register Src0, Register Src1,
+ KnownBits &Known,
+ const APInt &DemandedElts,
+ unsigned Depth) {
+ // Test src1 first, since we canonicalize simpler expressions to the RHS.
+ computeKnownBitsImpl(Src1, Known, DemandedElts, Depth);
+
+ // If we don't know any bits, early out.
+ if (Known.isUnknown())
+ return;
+
+ KnownBits Known2;
+ computeKnownBitsImpl(Src0, Known2, DemandedElts, Depth);
+
+ // Only known if known in both the LHS and RHS.
+ Known = KnownBits::commonBits(Known, Known2);
+}
+
void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known,
const APInt &DemandedElts,
unsigned Depth) {
@@ -200,7 +200,7 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known,
// For COPYs we don't do anything, don't increase the depth.
computeKnownBitsImpl(SrcReg, Known2, DemandedElts,
Depth + (Opcode != TargetOpcode::COPY));
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
// If we reach a point where we don't know anything
// just stop looking through the operands.
if (Known.One == 0 && Known.Zero == 0)
@@ -217,7 +217,7 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known,
auto CstVal = getConstantVRegVal(R, MRI);
if (!CstVal)
break;
- Known = KnownBits::makeConstant(*CstVal);
+ Known = KnownBits::makeConstant(*CstVal);
break;
}
case TargetOpcode::G_FRAME_INDEX: {
@@ -284,52 +284,52 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known,
Depth + 1);
computeKnownBitsImpl(MI.getOperand(1).getReg(), Known2, DemandedElts,
Depth + 1);
- Known = KnownBits::computeForMul(Known, Known2);
+ Known = KnownBits::computeForMul(Known, Known2);
break;
}
case TargetOpcode::G_SELECT: {
- computeKnownBitsMin(MI.getOperand(2).getReg(), MI.getOperand(3).getReg(),
- Known, DemandedElts, Depth + 1);
- break;
- }
- case TargetOpcode::G_SMIN: {
- // TODO: Handle clamp pattern with number of sign bits
- KnownBits KnownRHS;
- computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts,
+ computeKnownBitsMin(MI.getOperand(2).getReg(), MI.getOperand(3).getReg(),
+ Known, DemandedElts, Depth + 1);
+ break;
+ }
+ case TargetOpcode::G_SMIN: {
+ // TODO: Handle clamp pattern with number of sign bits
+ KnownBits KnownRHS;
+ computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts,
Depth + 1);
- computeKnownBitsImpl(MI.getOperand(2).getReg(), KnownRHS, DemandedElts,
+ computeKnownBitsImpl(MI.getOperand(2).getReg(), KnownRHS, DemandedElts,
Depth + 1);
- Known = KnownBits::smin(Known, KnownRHS);
+ Known = KnownBits::smin(Known, KnownRHS);
+ break;
+ }
+ case TargetOpcode::G_SMAX: {
+ // TODO: Handle clamp pattern with number of sign bits
+ KnownBits KnownRHS;
+ computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts,
+ Depth + 1);
+ computeKnownBitsImpl(MI.getOperand(2).getReg(), KnownRHS, DemandedElts,
+ Depth + 1);
+ Known = KnownBits::smax(Known, KnownRHS);
+ break;
+ }
+ case TargetOpcode::G_UMIN: {
+ KnownBits KnownRHS;
+ computeKnownBitsImpl(MI.getOperand(1).getReg(), Known,
+ DemandedElts, Depth + 1);
+ computeKnownBitsImpl(MI.getOperand(2).getReg(), KnownRHS,
+ DemandedElts, Depth + 1);
+ Known = KnownBits::umin(Known, KnownRHS);
+ break;
+ }
+ case TargetOpcode::G_UMAX: {
+ KnownBits KnownRHS;
+ computeKnownBitsImpl(MI.getOperand(1).getReg(), Known,
+ DemandedElts, Depth + 1);
+ computeKnownBitsImpl(MI.getOperand(2).getReg(), KnownRHS,
+ DemandedElts, Depth + 1);
+ Known = KnownBits::umax(Known, KnownRHS);
break;
}
- case TargetOpcode::G_SMAX: {
- // TODO: Handle clamp pattern with number of sign bits
- KnownBits KnownRHS;
- computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts,
- Depth + 1);
- computeKnownBitsImpl(MI.getOperand(2).getReg(), KnownRHS, DemandedElts,
- Depth + 1);
- Known = KnownBits::smax(Known, KnownRHS);
- break;
- }
- case TargetOpcode::G_UMIN: {
- KnownBits KnownRHS;
- computeKnownBitsImpl(MI.getOperand(1).getReg(), Known,
- DemandedElts, Depth + 1);
- computeKnownBitsImpl(MI.getOperand(2).getReg(), KnownRHS,
- DemandedElts, Depth + 1);
- Known = KnownBits::umin(Known, KnownRHS);
- break;
- }
- case TargetOpcode::G_UMAX: {
- KnownBits KnownRHS;
- computeKnownBitsImpl(MI.getOperand(1).getReg(), Known,
- DemandedElts, Depth + 1);
- computeKnownBitsImpl(MI.getOperand(2).getReg(), KnownRHS,
- DemandedElts, Depth + 1);
- Known = KnownBits::umax(Known, KnownRHS);
- break;
- }
case TargetOpcode::G_FCMP:
case TargetOpcode::G_ICMP: {
if (TL.getBooleanContents(DstTy.isVector(),
@@ -347,58 +347,58 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known,
Known = Known.sext(BitWidth);
break;
}
- case TargetOpcode::G_SEXT_INREG: {
- computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts,
- Depth + 1);
- Known = Known.sextInReg(MI.getOperand(2).getImm());
- break;
- }
+ case TargetOpcode::G_SEXT_INREG: {
+ computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts,
+ Depth + 1);
+ Known = Known.sextInReg(MI.getOperand(2).getImm());
+ break;
+ }
case TargetOpcode::G_ANYEXT: {
computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts,
Depth + 1);
- Known = Known.anyext(BitWidth);
+ Known = Known.anyext(BitWidth);
break;
}
case TargetOpcode::G_LOAD: {
- const MachineMemOperand *MMO = *MI.memoperands_begin();
- if (const MDNode *Ranges = MMO->getRanges()) {
- computeKnownBitsFromRangeMetadata(*Ranges, Known);
+ const MachineMemOperand *MMO = *MI.memoperands_begin();
+ if (const MDNode *Ranges = MMO->getRanges()) {
+ computeKnownBitsFromRangeMetadata(*Ranges, Known);
}
-
+
break;
}
case TargetOpcode::G_ZEXTLOAD: {
// Everything above the retrieved bits is zero
- Known.Zero.setBitsFrom((*MI.memoperands_begin())->getSizeInBits());
+ Known.Zero.setBitsFrom((*MI.memoperands_begin())->getSizeInBits());
break;
}
- case TargetOpcode::G_ASHR: {
- KnownBits LHSKnown, RHSKnown;
- computeKnownBitsImpl(MI.getOperand(1).getReg(), LHSKnown, DemandedElts,
- Depth + 1);
+ case TargetOpcode::G_ASHR: {
+ KnownBits LHSKnown, RHSKnown;
+ computeKnownBitsImpl(MI.getOperand(1).getReg(), LHSKnown, DemandedElts,
+ Depth + 1);
computeKnownBitsImpl(MI.getOperand(2).getReg(), RHSKnown, DemandedElts,
Depth + 1);
- Known = KnownBits::ashr(LHSKnown, RHSKnown);
- break;
- }
- case TargetOpcode::G_LSHR: {
- KnownBits LHSKnown, RHSKnown;
- computeKnownBitsImpl(MI.getOperand(1).getReg(), LHSKnown, DemandedElts,
+ Known = KnownBits::ashr(LHSKnown, RHSKnown);
+ break;
+ }
+ case TargetOpcode::G_LSHR: {
+ KnownBits LHSKnown, RHSKnown;
+ computeKnownBitsImpl(MI.getOperand(1).getReg(), LHSKnown, DemandedElts,
+ Depth + 1);
+ computeKnownBitsImpl(MI.getOperand(2).getReg(), RHSKnown, DemandedElts,
+ Depth + 1);
+ Known = KnownBits::lshr(LHSKnown, RHSKnown);
+ break;
+ }
+ case TargetOpcode::G_SHL: {
+ KnownBits LHSKnown, RHSKnown;
+ computeKnownBitsImpl(MI.getOperand(1).getReg(), LHSKnown, DemandedElts,
+ Depth + 1);
+ computeKnownBitsImpl(MI.getOperand(2).getReg(), RHSKnown, DemandedElts,
Depth + 1);
- computeKnownBitsImpl(MI.getOperand(2).getReg(), RHSKnown, DemandedElts,
- Depth + 1);
- Known = KnownBits::lshr(LHSKnown, RHSKnown);
+ Known = KnownBits::shl(LHSKnown, RHSKnown);
break;
}
- case TargetOpcode::G_SHL: {
- KnownBits LHSKnown, RHSKnown;
- computeKnownBitsImpl(MI.getOperand(1).getReg(), LHSKnown, DemandedElts,
- Depth + 1);
- computeKnownBitsImpl(MI.getOperand(2).getReg(), RHSKnown, DemandedElts,
- Depth + 1);
- Known = KnownBits::shl(LHSKnown, RHSKnown);
- break;
- }
case TargetOpcode::G_INTTOPTR:
case TargetOpcode::G_PTRTOINT:
// Fall through and handle them the same as zext/trunc.
@@ -418,50 +418,50 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known,
Known.Zero.setBitsFrom(SrcBitWidth);
break;
}
- case TargetOpcode::G_MERGE_VALUES: {
- unsigned NumOps = MI.getNumOperands();
- unsigned OpSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
-
- for (unsigned I = 0; I != NumOps - 1; ++I) {
- KnownBits SrcOpKnown;
- computeKnownBitsImpl(MI.getOperand(I + 1).getReg(), SrcOpKnown,
- DemandedElts, Depth + 1);
- Known.insertBits(SrcOpKnown, I * OpSize);
- }
- break;
- }
- case TargetOpcode::G_UNMERGE_VALUES: {
- unsigned NumOps = MI.getNumOperands();
- Register SrcReg = MI.getOperand(NumOps - 1).getReg();
- if (MRI.getType(SrcReg).isVector())
- return; // TODO: Handle vectors.
-
- KnownBits SrcOpKnown;
- computeKnownBitsImpl(SrcReg, SrcOpKnown, DemandedElts, Depth + 1);
-
- // Figure out the result operand index
- unsigned DstIdx = 0;
- for (; DstIdx != NumOps - 1 && MI.getOperand(DstIdx).getReg() != R;
- ++DstIdx)
- ;
-
- Known = SrcOpKnown.extractBits(BitWidth, BitWidth * DstIdx);
- break;
- }
- case TargetOpcode::G_BSWAP: {
- Register SrcReg = MI.getOperand(1).getReg();
- computeKnownBitsImpl(SrcReg, Known, DemandedElts, Depth + 1);
- Known.byteSwap();
- break;
- }
- case TargetOpcode::G_BITREVERSE: {
- Register SrcReg = MI.getOperand(1).getReg();
- computeKnownBitsImpl(SrcReg, Known, DemandedElts, Depth + 1);
- Known.reverseBits();
- break;
- }
- }
-
+ case TargetOpcode::G_MERGE_VALUES: {
+ unsigned NumOps = MI.getNumOperands();
+ unsigned OpSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
+
+ for (unsigned I = 0; I != NumOps - 1; ++I) {
+ KnownBits SrcOpKnown;
+ computeKnownBitsImpl(MI.getOperand(I + 1).getReg(), SrcOpKnown,
+ DemandedElts, Depth + 1);
+ Known.insertBits(SrcOpKnown, I * OpSize);
+ }
+ break;
+ }
+ case TargetOpcode::G_UNMERGE_VALUES: {
+ unsigned NumOps = MI.getNumOperands();
+ Register SrcReg = MI.getOperand(NumOps - 1).getReg();
+ if (MRI.getType(SrcReg).isVector())
+ return; // TODO: Handle vectors.
+
+ KnownBits SrcOpKnown;
+ computeKnownBitsImpl(SrcReg, SrcOpKnown, DemandedElts, Depth + 1);
+
+ // Figure out the result operand index
+ unsigned DstIdx = 0;
+ for (; DstIdx != NumOps - 1 && MI.getOperand(DstIdx).getReg() != R;
+ ++DstIdx)
+ ;
+
+ Known = SrcOpKnown.extractBits(BitWidth, BitWidth * DstIdx);
+ break;
+ }
+ case TargetOpcode::G_BSWAP: {
+ Register SrcReg = MI.getOperand(1).getReg();
+ computeKnownBitsImpl(SrcReg, Known, DemandedElts, Depth + 1);
+ Known.byteSwap();
+ break;
+ }
+ case TargetOpcode::G_BITREVERSE: {
+ Register SrcReg = MI.getOperand(1).getReg();
+ computeKnownBitsImpl(SrcReg, Known, DemandedElts, Depth + 1);
+ Known.reverseBits();
+ break;
+ }
+ }
+
assert(!Known.hasConflict() && "Bits known to be one AND zero?");
LLVM_DEBUG(dumpResult(MI, Known, Depth));
@@ -469,17 +469,17 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known,
ComputeKnownBitsCache[R] = Known;
}
-/// Compute number of sign bits for the intersection of \p Src0 and \p Src1
-unsigned GISelKnownBits::computeNumSignBitsMin(Register Src0, Register Src1,
- const APInt &DemandedElts,
- unsigned Depth) {
- // Test src1 first, since we canonicalize simpler expressions to the RHS.
- unsigned Src1SignBits = computeNumSignBits(Src1, DemandedElts, Depth);
- if (Src1SignBits == 1)
- return 1;
- return std::min(computeNumSignBits(Src0, DemandedElts, Depth), Src1SignBits);
-}
-
+/// Compute number of sign bits for the intersection of \p Src0 and \p Src1
+unsigned GISelKnownBits::computeNumSignBitsMin(Register Src0, Register Src1,
+ const APInt &DemandedElts,
+ unsigned Depth) {
+ // Test src1 first, since we canonicalize simpler expressions to the RHS.
+ unsigned Src1SignBits = computeNumSignBits(Src1, DemandedElts, Depth);
+ if (Src1SignBits == 1)
+ return 1;
+ return std::min(computeNumSignBits(Src0, DemandedElts, Depth), Src1SignBits);
+}
+
unsigned GISelKnownBits::computeNumSignBits(Register R,
const APInt &DemandedElts,
unsigned Depth) {
@@ -523,31 +523,31 @@ unsigned GISelKnownBits::computeNumSignBits(Register R,
unsigned Tmp = DstTy.getScalarSizeInBits() - SrcTy.getScalarSizeInBits();
return computeNumSignBits(Src, DemandedElts, Depth + 1) + Tmp;
}
- case TargetOpcode::G_SEXT_INREG: {
- // Max of the input and what this extends.
- Register Src = MI.getOperand(1).getReg();
- unsigned SrcBits = MI.getOperand(2).getImm();
- unsigned InRegBits = TyBits - SrcBits + 1;
- return std::max(computeNumSignBits(Src, DemandedElts, Depth + 1), InRegBits);
- }
+ case TargetOpcode::G_SEXT_INREG: {
+ // Max of the input and what this extends.
+ Register Src = MI.getOperand(1).getReg();
+ unsigned SrcBits = MI.getOperand(2).getImm();
+ unsigned InRegBits = TyBits - SrcBits + 1;
+ return std::max(computeNumSignBits(Src, DemandedElts, Depth + 1), InRegBits);
+ }
case TargetOpcode::G_SEXTLOAD: {
- // FIXME: We need an in-memory type representation.
- if (DstTy.isVector())
- return 1;
-
- // e.g. i16->i32 = '17' bits known.
- const MachineMemOperand *MMO = *MI.memoperands_begin();
- return TyBits - MMO->getSizeInBits() + 1;
- }
- case TargetOpcode::G_ZEXTLOAD: {
- // FIXME: We need an in-memory type representation.
- if (DstTy.isVector())
- return 1;
-
- // e.g. i16->i32 = '16' bits known.
- const MachineMemOperand *MMO = *MI.memoperands_begin();
- return TyBits - MMO->getSizeInBits();
- }
+ // FIXME: We need an in-memory type representation.
+ if (DstTy.isVector())
+ return 1;
+
+ // e.g. i16->i32 = '17' bits known.
+ const MachineMemOperand *MMO = *MI.memoperands_begin();
+ return TyBits - MMO->getSizeInBits() + 1;
+ }
+ case TargetOpcode::G_ZEXTLOAD: {
+ // FIXME: We need an in-memory type representation.
+ if (DstTy.isVector())
+ return 1;
+
+ // e.g. i16->i32 = '16' bits known.
+ const MachineMemOperand *MMO = *MI.memoperands_begin();
+ return TyBits - MMO->getSizeInBits();
+ }
case TargetOpcode::G_TRUNC: {
Register Src = MI.getOperand(1).getReg();
LLT SrcTy = MRI.getType(Src);
@@ -560,11 +560,11 @@ unsigned GISelKnownBits::computeNumSignBits(Register R,
return NumSrcSignBits - (NumSrcBits - DstTyBits);
break;
}
- case TargetOpcode::G_SELECT: {
- return computeNumSignBitsMin(MI.getOperand(2).getReg(),
- MI.getOperand(3).getReg(), DemandedElts,
- Depth + 1);
- }
+ case TargetOpcode::G_SELECT: {
+ return computeNumSignBitsMin(MI.getOperand(2).getReg(),
+ MI.getOperand(3).getReg(), DemandedElts,
+ Depth + 1);
+ }
case TargetOpcode::G_INTRINSIC:
case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
default: {
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/IRTranslator.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/IRTranslator.cpp
index c81add2e6b..b7883cbc31 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -29,11 +29,11 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/StackProtector.h"
-#include "llvm/CodeGen/SwitchLoweringUtils.h"
+#include "llvm/CodeGen/SwitchLoweringUtils.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
@@ -50,13 +50,13 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/InlineAsm.h"
-#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
-#include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
@@ -74,7 +74,7 @@
#include "llvm/Target/TargetMachine.h"
#include <algorithm>
#include <cassert>
-#include <cstddef>
+#include <cstddef>
#include <cstdint>
#include <iterator>
#include <string>
@@ -95,8 +95,8 @@ INITIALIZE_PASS_BEGIN(IRTranslator, DEBUG_TYPE, "IRTranslator LLVM IR -> MI",
false, false)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(StackProtector)
+INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(StackProtector)
INITIALIZE_PASS_END(IRTranslator, DEBUG_TYPE, "IRTranslator LLVM IR -> MI",
false, false)
@@ -117,8 +117,8 @@ static void reportTranslationError(MachineFunction &MF,
ORE.emit(R);
}
-IRTranslator::IRTranslator(CodeGenOpt::Level optlevel)
- : MachineFunctionPass(ID), OptLevel(optlevel) {}
+IRTranslator::IRTranslator(CodeGenOpt::Level optlevel)
+ : MachineFunctionPass(ID), OptLevel(optlevel) {}
#ifndef NDEBUG
namespace {
@@ -162,17 +162,17 @@ void IRTranslator::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<StackProtector>();
AU.addRequired<TargetPassConfig>();
AU.addRequired<GISelCSEAnalysisWrapperPass>();
- if (OptLevel != CodeGenOpt::None)
- AU.addRequired<BranchProbabilityInfoWrapperPass>();
+ if (OptLevel != CodeGenOpt::None)
+ AU.addRequired<BranchProbabilityInfoWrapperPass>();
getSelectionDAGFallbackAnalysisUsage(AU);
MachineFunctionPass::getAnalysisUsage(AU);
}
IRTranslator::ValueToVRegInfo::VRegListT &
IRTranslator::allocateVRegs(const Value &Val) {
- auto VRegsIt = VMap.findVRegs(Val);
- if (VRegsIt != VMap.vregs_end())
- return *VRegsIt->second;
+ auto VRegsIt = VMap.findVRegs(Val);
+ if (VRegsIt != VMap.vregs_end())
+ return *VRegsIt->second;
auto *Regs = VMap.getVRegs(Val);
auto *Offsets = VMap.getOffsets(Val);
SmallVector<LLT, 4> SplitTys;
@@ -234,9 +234,9 @@ ArrayRef<Register> IRTranslator::getOrCreateVRegs(const Value &Val) {
}
int IRTranslator::getOrCreateFrameIndex(const AllocaInst &AI) {
- auto MapEntry = FrameIndices.find(&AI);
- if (MapEntry != FrameIndices.end())
- return MapEntry->second;
+ auto MapEntry = FrameIndices.find(&AI);
+ if (MapEntry != FrameIndices.end())
+ return MapEntry->second;
uint64_t ElementSize = DL->getTypeAllocSize(AI.getAllocatedType());
uint64_t Size =
@@ -306,8 +306,8 @@ bool IRTranslator::translateBinaryOp(unsigned Opcode, const User &U,
return true;
}
-bool IRTranslator::translateUnaryOp(unsigned Opcode, const User &U,
- MachineIRBuilder &MIRBuilder) {
+bool IRTranslator::translateUnaryOp(unsigned Opcode, const User &U,
+ MachineIRBuilder &MIRBuilder) {
Register Op0 = getOrCreateVReg(*U.getOperand(0));
Register Res = getOrCreateVReg(U);
uint16_t Flags = 0;
@@ -315,14 +315,14 @@ bool IRTranslator::translateUnaryOp(unsigned Opcode, const User &U,
const Instruction &I = cast<Instruction>(U);
Flags = MachineInstr::copyFlagsFromInstruction(I);
}
- MIRBuilder.buildInstr(Opcode, {Res}, {Op0}, Flags);
+ MIRBuilder.buildInstr(Opcode, {Res}, {Op0}, Flags);
return true;
}
-bool IRTranslator::translateFNeg(const User &U, MachineIRBuilder &MIRBuilder) {
- return translateUnaryOp(TargetOpcode::G_FNEG, U, MIRBuilder);
-}
-
+bool IRTranslator::translateFNeg(const User &U, MachineIRBuilder &MIRBuilder) {
+ return translateUnaryOp(TargetOpcode::G_FNEG, U, MIRBuilder);
+}
+
bool IRTranslator::translateCompare(const User &U,
MachineIRBuilder &MIRBuilder) {
auto *CI = dyn_cast<CmpInst>(&U);
@@ -368,289 +368,289 @@ bool IRTranslator::translateRet(const User &U, MachineIRBuilder &MIRBuilder) {
// The target may mess up with the insertion point, but
// this is not important as a return is the last instruction
// of the block anyway.
- return CLI->lowerReturn(MIRBuilder, Ret, VRegs, FuncInfo, SwiftErrorVReg);
-}
-
-void IRTranslator::emitBranchForMergedCondition(
- const Value *Cond, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
- MachineBasicBlock *CurBB, MachineBasicBlock *SwitchBB,
- BranchProbability TProb, BranchProbability FProb, bool InvertCond) {
- // If the leaf of the tree is a comparison, merge the condition into
- // the caseblock.
- if (const CmpInst *BOp = dyn_cast<CmpInst>(Cond)) {
- CmpInst::Predicate Condition;
- if (const ICmpInst *IC = dyn_cast<ICmpInst>(Cond)) {
- Condition = InvertCond ? IC->getInversePredicate() : IC->getPredicate();
- } else {
- const FCmpInst *FC = cast<FCmpInst>(Cond);
- Condition = InvertCond ? FC->getInversePredicate() : FC->getPredicate();
- }
-
- SwitchCG::CaseBlock CB(Condition, false, BOp->getOperand(0),
- BOp->getOperand(1), nullptr, TBB, FBB, CurBB,
- CurBuilder->getDebugLoc(), TProb, FProb);
- SL->SwitchCases.push_back(CB);
- return;
- }
-
- // Create a CaseBlock record representing this branch.
- CmpInst::Predicate Pred = InvertCond ? CmpInst::ICMP_NE : CmpInst::ICMP_EQ;
- SwitchCG::CaseBlock CB(
- Pred, false, Cond, ConstantInt::getTrue(MF->getFunction().getContext()),
- nullptr, TBB, FBB, CurBB, CurBuilder->getDebugLoc(), TProb, FProb);
- SL->SwitchCases.push_back(CB);
-}
-
-static bool isValInBlock(const Value *V, const BasicBlock *BB) {
- if (const Instruction *I = dyn_cast<Instruction>(V))
- return I->getParent() == BB;
- return true;
-}
-
-void IRTranslator::findMergedConditions(
- const Value *Cond, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
- MachineBasicBlock *CurBB, MachineBasicBlock *SwitchBB,
- Instruction::BinaryOps Opc, BranchProbability TProb,
- BranchProbability FProb, bool InvertCond) {
- using namespace PatternMatch;
- assert((Opc == Instruction::And || Opc == Instruction::Or) &&
- "Expected Opc to be AND/OR");
- // Skip over not part of the tree and remember to invert op and operands at
- // next level.
- Value *NotCond;
- if (match(Cond, m_OneUse(m_Not(m_Value(NotCond)))) &&
- isValInBlock(NotCond, CurBB->getBasicBlock())) {
- findMergedConditions(NotCond, TBB, FBB, CurBB, SwitchBB, Opc, TProb, FProb,
- !InvertCond);
- return;
- }
-
- const Instruction *BOp = dyn_cast<Instruction>(Cond);
- const Value *BOpOp0, *BOpOp1;
- // Compute the effective opcode for Cond, taking into account whether it needs
- // to be inverted, e.g.
- // and (not (or A, B)), C
- // gets lowered as
- // and (and (not A, not B), C)
- Instruction::BinaryOps BOpc = (Instruction::BinaryOps)0;
- if (BOp) {
- BOpc = match(BOp, m_LogicalAnd(m_Value(BOpOp0), m_Value(BOpOp1)))
- ? Instruction::And
- : (match(BOp, m_LogicalOr(m_Value(BOpOp0), m_Value(BOpOp1)))
- ? Instruction::Or
- : (Instruction::BinaryOps)0);
- if (InvertCond) {
- if (BOpc == Instruction::And)
- BOpc = Instruction::Or;
- else if (BOpc == Instruction::Or)
- BOpc = Instruction::And;
- }
- }
-
- // If this node is not part of the or/and tree, emit it as a branch.
- // Note that all nodes in the tree should have same opcode.
- bool BOpIsInOrAndTree = BOpc && BOpc == Opc && BOp->hasOneUse();
- if (!BOpIsInOrAndTree || BOp->getParent() != CurBB->getBasicBlock() ||
- !isValInBlock(BOpOp0, CurBB->getBasicBlock()) ||
- !isValInBlock(BOpOp1, CurBB->getBasicBlock())) {
- emitBranchForMergedCondition(Cond, TBB, FBB, CurBB, SwitchBB, TProb, FProb,
- InvertCond);
- return;
- }
-
- // Create TmpBB after CurBB.
- MachineFunction::iterator BBI(CurBB);
- MachineBasicBlock *TmpBB =
- MF->CreateMachineBasicBlock(CurBB->getBasicBlock());
- CurBB->getParent()->insert(++BBI, TmpBB);
-
- if (Opc == Instruction::Or) {
- // Codegen X | Y as:
- // BB1:
- // jmp_if_X TBB
- // jmp TmpBB
- // TmpBB:
- // jmp_if_Y TBB
- // jmp FBB
- //
-
- // We have flexibility in setting Prob for BB1 and Prob for TmpBB.
- // The requirement is that
- // TrueProb for BB1 + (FalseProb for BB1 * TrueProb for TmpBB)
- // = TrueProb for original BB.
- // Assuming the original probabilities are A and B, one choice is to set
- // BB1's probabilities to A/2 and A/2+B, and set TmpBB's probabilities to
- // A/(1+B) and 2B/(1+B). This choice assumes that
- // TrueProb for BB1 == FalseProb for BB1 * TrueProb for TmpBB.
- // Another choice is to assume TrueProb for BB1 equals to TrueProb for
- // TmpBB, but the math is more complicated.
-
- auto NewTrueProb = TProb / 2;
- auto NewFalseProb = TProb / 2 + FProb;
- // Emit the LHS condition.
- findMergedConditions(BOpOp0, TBB, TmpBB, CurBB, SwitchBB, Opc, NewTrueProb,
- NewFalseProb, InvertCond);
-
- // Normalize A/2 and B to get A/(1+B) and 2B/(1+B).
- SmallVector<BranchProbability, 2> Probs{TProb / 2, FProb};
- BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
- // Emit the RHS condition into TmpBB.
- findMergedConditions(BOpOp1, TBB, FBB, TmpBB, SwitchBB, Opc, Probs[0],
- Probs[1], InvertCond);
- } else {
- assert(Opc == Instruction::And && "Unknown merge op!");
- // Codegen X & Y as:
- // BB1:
- // jmp_if_X TmpBB
- // jmp FBB
- // TmpBB:
- // jmp_if_Y TBB
- // jmp FBB
- //
- // This requires creation of TmpBB after CurBB.
-
- // We have flexibility in setting Prob for BB1 and Prob for TmpBB.
- // The requirement is that
- // FalseProb for BB1 + (TrueProb for BB1 * FalseProb for TmpBB)
- // = FalseProb for original BB.
- // Assuming the original probabilities are A and B, one choice is to set
- // BB1's probabilities to A+B/2 and B/2, and set TmpBB's probabilities to
- // 2A/(1+A) and B/(1+A). This choice assumes that FalseProb for BB1 ==
- // TrueProb for BB1 * FalseProb for TmpBB.
-
- auto NewTrueProb = TProb + FProb / 2;
- auto NewFalseProb = FProb / 2;
- // Emit the LHS condition.
- findMergedConditions(BOpOp0, TmpBB, FBB, CurBB, SwitchBB, Opc, NewTrueProb,
- NewFalseProb, InvertCond);
-
- // Normalize A and B/2 to get 2A/(1+A) and B/(1+A).
- SmallVector<BranchProbability, 2> Probs{TProb, FProb / 2};
- BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
- // Emit the RHS condition into TmpBB.
- findMergedConditions(BOpOp1, TBB, FBB, TmpBB, SwitchBB, Opc, Probs[0],
- Probs[1], InvertCond);
- }
-}
-
-bool IRTranslator::shouldEmitAsBranches(
- const std::vector<SwitchCG::CaseBlock> &Cases) {
- // For multiple cases, it's better to emit as branches.
- if (Cases.size() != 2)
- return true;
-
- // If this is two comparisons of the same values or'd or and'd together, they
- // will get folded into a single comparison, so don't emit two blocks.
- if ((Cases[0].CmpLHS == Cases[1].CmpLHS &&
- Cases[0].CmpRHS == Cases[1].CmpRHS) ||
- (Cases[0].CmpRHS == Cases[1].CmpLHS &&
- Cases[0].CmpLHS == Cases[1].CmpRHS)) {
- return false;
- }
-
- // Handle: (X != null) | (Y != null) --> (X|Y) != 0
- // Handle: (X == null) & (Y == null) --> (X|Y) == 0
- if (Cases[0].CmpRHS == Cases[1].CmpRHS &&
- Cases[0].PredInfo.Pred == Cases[1].PredInfo.Pred &&
- isa<Constant>(Cases[0].CmpRHS) &&
- cast<Constant>(Cases[0].CmpRHS)->isNullValue()) {
- if (Cases[0].PredInfo.Pred == CmpInst::ICMP_EQ &&
- Cases[0].TrueBB == Cases[1].ThisBB)
- return false;
- if (Cases[0].PredInfo.Pred == CmpInst::ICMP_NE &&
- Cases[0].FalseBB == Cases[1].ThisBB)
- return false;
- }
-
- return true;
-}
-
+ return CLI->lowerReturn(MIRBuilder, Ret, VRegs, FuncInfo, SwiftErrorVReg);
+}
+
+void IRTranslator::emitBranchForMergedCondition(
+ const Value *Cond, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
+ MachineBasicBlock *CurBB, MachineBasicBlock *SwitchBB,
+ BranchProbability TProb, BranchProbability FProb, bool InvertCond) {
+ // If the leaf of the tree is a comparison, merge the condition into
+ // the caseblock.
+ if (const CmpInst *BOp = dyn_cast<CmpInst>(Cond)) {
+ CmpInst::Predicate Condition;
+ if (const ICmpInst *IC = dyn_cast<ICmpInst>(Cond)) {
+ Condition = InvertCond ? IC->getInversePredicate() : IC->getPredicate();
+ } else {
+ const FCmpInst *FC = cast<FCmpInst>(Cond);
+ Condition = InvertCond ? FC->getInversePredicate() : FC->getPredicate();
+ }
+
+ SwitchCG::CaseBlock CB(Condition, false, BOp->getOperand(0),
+ BOp->getOperand(1), nullptr, TBB, FBB, CurBB,
+ CurBuilder->getDebugLoc(), TProb, FProb);
+ SL->SwitchCases.push_back(CB);
+ return;
+ }
+
+ // Create a CaseBlock record representing this branch.
+ CmpInst::Predicate Pred = InvertCond ? CmpInst::ICMP_NE : CmpInst::ICMP_EQ;
+ SwitchCG::CaseBlock CB(
+ Pred, false, Cond, ConstantInt::getTrue(MF->getFunction().getContext()),
+ nullptr, TBB, FBB, CurBB, CurBuilder->getDebugLoc(), TProb, FProb);
+ SL->SwitchCases.push_back(CB);
+}
+
+static bool isValInBlock(const Value *V, const BasicBlock *BB) {
+ if (const Instruction *I = dyn_cast<Instruction>(V))
+ return I->getParent() == BB;
+ return true;
+}
+
+void IRTranslator::findMergedConditions(
+ const Value *Cond, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
+ MachineBasicBlock *CurBB, MachineBasicBlock *SwitchBB,
+ Instruction::BinaryOps Opc, BranchProbability TProb,
+ BranchProbability FProb, bool InvertCond) {
+ using namespace PatternMatch;
+ assert((Opc == Instruction::And || Opc == Instruction::Or) &&
+ "Expected Opc to be AND/OR");
+ // Skip over not part of the tree and remember to invert op and operands at
+ // next level.
+ Value *NotCond;
+ if (match(Cond, m_OneUse(m_Not(m_Value(NotCond)))) &&
+ isValInBlock(NotCond, CurBB->getBasicBlock())) {
+ findMergedConditions(NotCond, TBB, FBB, CurBB, SwitchBB, Opc, TProb, FProb,
+ !InvertCond);
+ return;
+ }
+
+ const Instruction *BOp = dyn_cast<Instruction>(Cond);
+ const Value *BOpOp0, *BOpOp1;
+ // Compute the effective opcode for Cond, taking into account whether it needs
+ // to be inverted, e.g.
+ // and (not (or A, B)), C
+ // gets lowered as
+ // and (and (not A, not B), C)
+ Instruction::BinaryOps BOpc = (Instruction::BinaryOps)0;
+ if (BOp) {
+ BOpc = match(BOp, m_LogicalAnd(m_Value(BOpOp0), m_Value(BOpOp1)))
+ ? Instruction::And
+ : (match(BOp, m_LogicalOr(m_Value(BOpOp0), m_Value(BOpOp1)))
+ ? Instruction::Or
+ : (Instruction::BinaryOps)0);
+ if (InvertCond) {
+ if (BOpc == Instruction::And)
+ BOpc = Instruction::Or;
+ else if (BOpc == Instruction::Or)
+ BOpc = Instruction::And;
+ }
+ }
+
+ // If this node is not part of the or/and tree, emit it as a branch.
+ // Note that all nodes in the tree should have same opcode.
+ bool BOpIsInOrAndTree = BOpc && BOpc == Opc && BOp->hasOneUse();
+ if (!BOpIsInOrAndTree || BOp->getParent() != CurBB->getBasicBlock() ||
+ !isValInBlock(BOpOp0, CurBB->getBasicBlock()) ||
+ !isValInBlock(BOpOp1, CurBB->getBasicBlock())) {
+ emitBranchForMergedCondition(Cond, TBB, FBB, CurBB, SwitchBB, TProb, FProb,
+ InvertCond);
+ return;
+ }
+
+ // Create TmpBB after CurBB.
+ MachineFunction::iterator BBI(CurBB);
+ MachineBasicBlock *TmpBB =
+ MF->CreateMachineBasicBlock(CurBB->getBasicBlock());
+ CurBB->getParent()->insert(++BBI, TmpBB);
+
+ if (Opc == Instruction::Or) {
+ // Codegen X | Y as:
+ // BB1:
+ // jmp_if_X TBB
+ // jmp TmpBB
+ // TmpBB:
+ // jmp_if_Y TBB
+ // jmp FBB
+ //
+
+ // We have flexibility in setting Prob for BB1 and Prob for TmpBB.
+ // The requirement is that
+ // TrueProb for BB1 + (FalseProb for BB1 * TrueProb for TmpBB)
+ // = TrueProb for original BB.
+ // Assuming the original probabilities are A and B, one choice is to set
+ // BB1's probabilities to A/2 and A/2+B, and set TmpBB's probabilities to
+ // A/(1+B) and 2B/(1+B). This choice assumes that
+ // TrueProb for BB1 == FalseProb for BB1 * TrueProb for TmpBB.
+ // Another choice is to assume TrueProb for BB1 equals to TrueProb for
+ // TmpBB, but the math is more complicated.
+
+ auto NewTrueProb = TProb / 2;
+ auto NewFalseProb = TProb / 2 + FProb;
+ // Emit the LHS condition.
+ findMergedConditions(BOpOp0, TBB, TmpBB, CurBB, SwitchBB, Opc, NewTrueProb,
+ NewFalseProb, InvertCond);
+
+ // Normalize A/2 and B to get A/(1+B) and 2B/(1+B).
+ SmallVector<BranchProbability, 2> Probs{TProb / 2, FProb};
+ BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
+ // Emit the RHS condition into TmpBB.
+ findMergedConditions(BOpOp1, TBB, FBB, TmpBB, SwitchBB, Opc, Probs[0],
+ Probs[1], InvertCond);
+ } else {
+ assert(Opc == Instruction::And && "Unknown merge op!");
+ // Codegen X & Y as:
+ // BB1:
+ // jmp_if_X TmpBB
+ // jmp FBB
+ // TmpBB:
+ // jmp_if_Y TBB
+ // jmp FBB
+ //
+ // This requires creation of TmpBB after CurBB.
+
+ // We have flexibility in setting Prob for BB1 and Prob for TmpBB.
+ // The requirement is that
+ // FalseProb for BB1 + (TrueProb for BB1 * FalseProb for TmpBB)
+ // = FalseProb for original BB.
+ // Assuming the original probabilities are A and B, one choice is to set
+ // BB1's probabilities to A+B/2 and B/2, and set TmpBB's probabilities to
+ // 2A/(1+A) and B/(1+A). This choice assumes that FalseProb for BB1 ==
+ // TrueProb for BB1 * FalseProb for TmpBB.
+
+ auto NewTrueProb = TProb + FProb / 2;
+ auto NewFalseProb = FProb / 2;
+ // Emit the LHS condition.
+ findMergedConditions(BOpOp0, TmpBB, FBB, CurBB, SwitchBB, Opc, NewTrueProb,
+ NewFalseProb, InvertCond);
+
+ // Normalize A and B/2 to get 2A/(1+A) and B/(1+A).
+ SmallVector<BranchProbability, 2> Probs{TProb, FProb / 2};
+ BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
+ // Emit the RHS condition into TmpBB.
+ findMergedConditions(BOpOp1, TBB, FBB, TmpBB, SwitchBB, Opc, Probs[0],
+ Probs[1], InvertCond);
+ }
+}
+
+bool IRTranslator::shouldEmitAsBranches(
+ const std::vector<SwitchCG::CaseBlock> &Cases) {
+ // For multiple cases, it's better to emit as branches.
+ if (Cases.size() != 2)
+ return true;
+
+ // If this is two comparisons of the same values or'd or and'd together, they
+ // will get folded into a single comparison, so don't emit two blocks.
+ if ((Cases[0].CmpLHS == Cases[1].CmpLHS &&
+ Cases[0].CmpRHS == Cases[1].CmpRHS) ||
+ (Cases[0].CmpRHS == Cases[1].CmpLHS &&
+ Cases[0].CmpLHS == Cases[1].CmpRHS)) {
+ return false;
+ }
+
+ // Handle: (X != null) | (Y != null) --> (X|Y) != 0
+ // Handle: (X == null) & (Y == null) --> (X|Y) == 0
+ if (Cases[0].CmpRHS == Cases[1].CmpRHS &&
+ Cases[0].PredInfo.Pred == Cases[1].PredInfo.Pred &&
+ isa<Constant>(Cases[0].CmpRHS) &&
+ cast<Constant>(Cases[0].CmpRHS)->isNullValue()) {
+ if (Cases[0].PredInfo.Pred == CmpInst::ICMP_EQ &&
+ Cases[0].TrueBB == Cases[1].ThisBB)
+ return false;
+ if (Cases[0].PredInfo.Pred == CmpInst::ICMP_NE &&
+ Cases[0].FalseBB == Cases[1].ThisBB)
+ return false;
+ }
+
+ return true;
+}
+
bool IRTranslator::translateBr(const User &U, MachineIRBuilder &MIRBuilder) {
const BranchInst &BrInst = cast<BranchInst>(U);
- auto &CurMBB = MIRBuilder.getMBB();
- auto *Succ0MBB = &getMBB(*BrInst.getSuccessor(0));
-
- if (BrInst.isUnconditional()) {
- // If the unconditional target is the layout successor, fallthrough.
- if (!CurMBB.isLayoutSuccessor(Succ0MBB))
- MIRBuilder.buildBr(*Succ0MBB);
-
- // Link successors.
- for (const BasicBlock *Succ : successors(&BrInst))
- CurMBB.addSuccessor(&getMBB(*Succ));
- return true;
- }
-
- // If this condition is one of the special cases we handle, do special stuff
- // now.
- const Value *CondVal = BrInst.getCondition();
- MachineBasicBlock *Succ1MBB = &getMBB(*BrInst.getSuccessor(1));
-
- const auto &TLI = *MF->getSubtarget().getTargetLowering();
-
- // If this is a series of conditions that are or'd or and'd together, emit
- // this as a sequence of branches instead of setcc's with and/or operations.
- // As long as jumps are not expensive (exceptions for multi-use logic ops,
- // unpredictable branches, and vector extracts because those jumps are likely
- // expensive for any target), this should improve performance.
- // For example, instead of something like:
- // cmp A, B
- // C = seteq
- // cmp D, E
- // F = setle
- // or C, F
- // jnz foo
- // Emit:
- // cmp A, B
- // je foo
- // cmp D, E
- // jle foo
- using namespace PatternMatch;
- const Instruction *CondI = dyn_cast<Instruction>(CondVal);
- if (!TLI.isJumpExpensive() && CondI && CondI->hasOneUse() &&
- !BrInst.hasMetadata(LLVMContext::MD_unpredictable)) {
- Instruction::BinaryOps Opcode = (Instruction::BinaryOps)0;
- Value *Vec;
- const Value *BOp0, *BOp1;
- if (match(CondI, m_LogicalAnd(m_Value(BOp0), m_Value(BOp1))))
- Opcode = Instruction::And;
- else if (match(CondI, m_LogicalOr(m_Value(BOp0), m_Value(BOp1))))
- Opcode = Instruction::Or;
-
- if (Opcode && !(match(BOp0, m_ExtractElt(m_Value(Vec), m_Value())) &&
- match(BOp1, m_ExtractElt(m_Specific(Vec), m_Value())))) {
- findMergedConditions(CondI, Succ0MBB, Succ1MBB, &CurMBB, &CurMBB, Opcode,
- getEdgeProbability(&CurMBB, Succ0MBB),
- getEdgeProbability(&CurMBB, Succ1MBB),
- /*InvertCond=*/false);
- assert(SL->SwitchCases[0].ThisBB == &CurMBB && "Unexpected lowering!");
-
- // Allow some cases to be rejected.
- if (shouldEmitAsBranches(SL->SwitchCases)) {
- // Emit the branch for this block.
- emitSwitchCase(SL->SwitchCases[0], &CurMBB, *CurBuilder);
- SL->SwitchCases.erase(SL->SwitchCases.begin());
- return true;
- }
-
- // Okay, we decided not to do this, remove any inserted MBB's and clear
- // SwitchCases.
- for (unsigned I = 1, E = SL->SwitchCases.size(); I != E; ++I)
- MF->erase(SL->SwitchCases[I].ThisBB);
-
- SL->SwitchCases.clear();
- }
- }
-
- // Create a CaseBlock record representing this branch.
- SwitchCG::CaseBlock CB(CmpInst::ICMP_EQ, false, CondVal,
- ConstantInt::getTrue(MF->getFunction().getContext()),
- nullptr, Succ0MBB, Succ1MBB, &CurMBB,
- CurBuilder->getDebugLoc());
-
- // Use emitSwitchCase to actually insert the fast branch sequence for this
- // cond branch.
- emitSwitchCase(CB, &CurMBB, *CurBuilder);
+ auto &CurMBB = MIRBuilder.getMBB();
+ auto *Succ0MBB = &getMBB(*BrInst.getSuccessor(0));
+
+ if (BrInst.isUnconditional()) {
+ // If the unconditional target is the layout successor, fallthrough.
+ if (!CurMBB.isLayoutSuccessor(Succ0MBB))
+ MIRBuilder.buildBr(*Succ0MBB);
+
+ // Link successors.
+ for (const BasicBlock *Succ : successors(&BrInst))
+ CurMBB.addSuccessor(&getMBB(*Succ));
+ return true;
+ }
+
+ // If this condition is one of the special cases we handle, do special stuff
+ // now.
+ const Value *CondVal = BrInst.getCondition();
+ MachineBasicBlock *Succ1MBB = &getMBB(*BrInst.getSuccessor(1));
+
+ const auto &TLI = *MF->getSubtarget().getTargetLowering();
+
+ // If this is a series of conditions that are or'd or and'd together, emit
+ // this as a sequence of branches instead of setcc's with and/or operations.
+ // As long as jumps are not expensive (exceptions for multi-use logic ops,
+ // unpredictable branches, and vector extracts because those jumps are likely
+ // expensive for any target), this should improve performance.
+ // For example, instead of something like:
+ // cmp A, B
+ // C = seteq
+ // cmp D, E
+ // F = setle
+ // or C, F
+ // jnz foo
+ // Emit:
+ // cmp A, B
+ // je foo
+ // cmp D, E
+ // jle foo
+ using namespace PatternMatch;
+ const Instruction *CondI = dyn_cast<Instruction>(CondVal);
+ if (!TLI.isJumpExpensive() && CondI && CondI->hasOneUse() &&
+ !BrInst.hasMetadata(LLVMContext::MD_unpredictable)) {
+ Instruction::BinaryOps Opcode = (Instruction::BinaryOps)0;
+ Value *Vec;
+ const Value *BOp0, *BOp1;
+ if (match(CondI, m_LogicalAnd(m_Value(BOp0), m_Value(BOp1))))
+ Opcode = Instruction::And;
+ else if (match(CondI, m_LogicalOr(m_Value(BOp0), m_Value(BOp1))))
+ Opcode = Instruction::Or;
+
+ if (Opcode && !(match(BOp0, m_ExtractElt(m_Value(Vec), m_Value())) &&
+ match(BOp1, m_ExtractElt(m_Specific(Vec), m_Value())))) {
+ findMergedConditions(CondI, Succ0MBB, Succ1MBB, &CurMBB, &CurMBB, Opcode,
+ getEdgeProbability(&CurMBB, Succ0MBB),
+ getEdgeProbability(&CurMBB, Succ1MBB),
+ /*InvertCond=*/false);
+ assert(SL->SwitchCases[0].ThisBB == &CurMBB && "Unexpected lowering!");
+
+ // Allow some cases to be rejected.
+ if (shouldEmitAsBranches(SL->SwitchCases)) {
+ // Emit the branch for this block.
+ emitSwitchCase(SL->SwitchCases[0], &CurMBB, *CurBuilder);
+ SL->SwitchCases.erase(SL->SwitchCases.begin());
+ return true;
+ }
+
+ // Okay, we decided not to do this, remove any inserted MBB's and clear
+ // SwitchCases.
+ for (unsigned I = 1, E = SL->SwitchCases.size(); I != E; ++I)
+ MF->erase(SL->SwitchCases[I].ThisBB);
+
+ SL->SwitchCases.clear();
+ }
+ }
+
+ // Create a CaseBlock record representing this branch.
+ SwitchCG::CaseBlock CB(CmpInst::ICMP_EQ, false, CondVal,
+ ConstantInt::getTrue(MF->getFunction().getContext()),
+ nullptr, Succ0MBB, Succ1MBB, &CurMBB,
+ CurBuilder->getDebugLoc());
+
+ // Use emitSwitchCase to actually insert the fast branch sequence for this
+ // cond branch.
+ emitSwitchCase(CB, &CurMBB, *CurBuilder);
return true;
}
@@ -715,7 +715,7 @@ bool IRTranslator::translateSwitch(const User &U, MachineIRBuilder &MIB) {
}
SL->findJumpTables(Clusters, &SI, DefaultMBB, nullptr, nullptr);
- SL->findBitTestClusters(Clusters, &SI);
+ SL->findBitTestClusters(Clusters, &SI);
LLVM_DEBUG({
dbgs() << "Case clusters: ";
@@ -836,22 +836,22 @@ void IRTranslator::emitSwitchCase(SwitchCG::CaseBlock &CB,
const LLT i1Ty = LLT::scalar(1);
// Build the compare.
if (!CB.CmpMHS) {
- const auto *CI = dyn_cast<ConstantInt>(CB.CmpRHS);
- // For conditional branch lowering, we might try to do something silly like
- // emit an G_ICMP to compare an existing G_ICMP i1 result with true. If so,
- // just re-use the existing condition vreg.
- if (MRI->getType(CondLHS).getSizeInBits() == 1 && CI &&
- CI->getZExtValue() == 1 && CB.PredInfo.Pred == CmpInst::ICMP_EQ) {
- Cond = CondLHS;
- } else {
- Register CondRHS = getOrCreateVReg(*CB.CmpRHS);
- if (CmpInst::isFPPredicate(CB.PredInfo.Pred))
- Cond =
- MIB.buildFCmp(CB.PredInfo.Pred, i1Ty, CondLHS, CondRHS).getReg(0);
- else
- Cond =
- MIB.buildICmp(CB.PredInfo.Pred, i1Ty, CondLHS, CondRHS).getReg(0);
- }
+ const auto *CI = dyn_cast<ConstantInt>(CB.CmpRHS);
+ // For conditional branch lowering, we might try to do something silly like
+ // emit an G_ICMP to compare an existing G_ICMP i1 result with true. If so,
+ // just re-use the existing condition vreg.
+ if (MRI->getType(CondLHS).getSizeInBits() == 1 && CI &&
+ CI->getZExtValue() == 1 && CB.PredInfo.Pred == CmpInst::ICMP_EQ) {
+ Cond = CondLHS;
+ } else {
+ Register CondRHS = getOrCreateVReg(*CB.CmpRHS);
+ if (CmpInst::isFPPredicate(CB.PredInfo.Pred))
+ Cond =
+ MIB.buildFCmp(CB.PredInfo.Pred, i1Ty, CondLHS, CondRHS).getReg(0);
+ else
+ Cond =
+ MIB.buildICmp(CB.PredInfo.Pred, i1Ty, CondLHS, CondRHS).getReg(0);
+ }
} else {
assert(CB.PredInfo.Pred == CmpInst::ICMP_SLE &&
"Can only handle SLE ranges");
@@ -884,8 +884,8 @@ void IRTranslator::emitSwitchCase(SwitchCG::CaseBlock &CB,
addSuccessorWithProb(CB.ThisBB, CB.FalseBB, CB.FalseProb);
CB.ThisBB->normalizeSuccProbs();
- addMachineCFGPred({SwitchBB->getBasicBlock(), CB.FalseBB->getBasicBlock()},
- CB.ThisBB);
+ addMachineCFGPred({SwitchBB->getBasicBlock(), CB.FalseBB->getBasicBlock()},
+ CB.ThisBB);
MIB.buildBrCond(Cond, *CB.TrueBB);
MIB.buildBr(*CB.FalseBB);
@@ -998,156 +998,156 @@ bool IRTranslator::lowerSwitchRangeWorkItem(SwitchCG::CaseClusterIt I,
return true;
}
-void IRTranslator::emitBitTestHeader(SwitchCG::BitTestBlock &B,
- MachineBasicBlock *SwitchBB) {
- MachineIRBuilder &MIB = *CurBuilder;
- MIB.setMBB(*SwitchBB);
-
- // Subtract the minimum value.
- Register SwitchOpReg = getOrCreateVReg(*B.SValue);
-
- LLT SwitchOpTy = MRI->getType(SwitchOpReg);
- Register MinValReg = MIB.buildConstant(SwitchOpTy, B.First).getReg(0);
- auto RangeSub = MIB.buildSub(SwitchOpTy, SwitchOpReg, MinValReg);
-
- // Ensure that the type will fit the mask value.
- LLT MaskTy = SwitchOpTy;
- for (unsigned I = 0, E = B.Cases.size(); I != E; ++I) {
- if (!isUIntN(SwitchOpTy.getSizeInBits(), B.Cases[I].Mask)) {
- // Switch table case range are encoded into series of masks.
- // Just use pointer type, it's guaranteed to fit.
- MaskTy = LLT::scalar(64);
- break;
- }
- }
- Register SubReg = RangeSub.getReg(0);
- if (SwitchOpTy != MaskTy)
- SubReg = MIB.buildZExtOrTrunc(MaskTy, SubReg).getReg(0);
-
- B.RegVT = getMVTForLLT(MaskTy);
- B.Reg = SubReg;
-
- MachineBasicBlock *MBB = B.Cases[0].ThisBB;
-
- if (!B.OmitRangeCheck)
- addSuccessorWithProb(SwitchBB, B.Default, B.DefaultProb);
- addSuccessorWithProb(SwitchBB, MBB, B.Prob);
-
- SwitchBB->normalizeSuccProbs();
-
- if (!B.OmitRangeCheck) {
- // Conditional branch to the default block.
- auto RangeCst = MIB.buildConstant(SwitchOpTy, B.Range);
- auto RangeCmp = MIB.buildICmp(CmpInst::Predicate::ICMP_UGT, LLT::scalar(1),
- RangeSub, RangeCst);
- MIB.buildBrCond(RangeCmp, *B.Default);
- }
-
- // Avoid emitting unnecessary branches to the next block.
- if (MBB != SwitchBB->getNextNode())
- MIB.buildBr(*MBB);
-}
-
-void IRTranslator::emitBitTestCase(SwitchCG::BitTestBlock &BB,
- MachineBasicBlock *NextMBB,
- BranchProbability BranchProbToNext,
- Register Reg, SwitchCG::BitTestCase &B,
- MachineBasicBlock *SwitchBB) {
- MachineIRBuilder &MIB = *CurBuilder;
- MIB.setMBB(*SwitchBB);
-
- LLT SwitchTy = getLLTForMVT(BB.RegVT);
- Register Cmp;
- unsigned PopCount = countPopulation(B.Mask);
- if (PopCount == 1) {
- // Testing for a single bit; just compare the shift count with what it
- // would need to be to shift a 1 bit in that position.
- auto MaskTrailingZeros =
- MIB.buildConstant(SwitchTy, countTrailingZeros(B.Mask));
- Cmp =
- MIB.buildICmp(ICmpInst::ICMP_EQ, LLT::scalar(1), Reg, MaskTrailingZeros)
- .getReg(0);
- } else if (PopCount == BB.Range) {
- // There is only one zero bit in the range, test for it directly.
- auto MaskTrailingOnes =
- MIB.buildConstant(SwitchTy, countTrailingOnes(B.Mask));
- Cmp = MIB.buildICmp(CmpInst::ICMP_NE, LLT::scalar(1), Reg, MaskTrailingOnes)
- .getReg(0);
- } else {
- // Make desired shift.
- auto CstOne = MIB.buildConstant(SwitchTy, 1);
- auto SwitchVal = MIB.buildShl(SwitchTy, CstOne, Reg);
-
- // Emit bit tests and jumps.
- auto CstMask = MIB.buildConstant(SwitchTy, B.Mask);
- auto AndOp = MIB.buildAnd(SwitchTy, SwitchVal, CstMask);
- auto CstZero = MIB.buildConstant(SwitchTy, 0);
- Cmp = MIB.buildICmp(CmpInst::ICMP_NE, LLT::scalar(1), AndOp, CstZero)
- .getReg(0);
- }
-
- // The branch probability from SwitchBB to B.TargetBB is B.ExtraProb.
- addSuccessorWithProb(SwitchBB, B.TargetBB, B.ExtraProb);
- // The branch probability from SwitchBB to NextMBB is BranchProbToNext.
- addSuccessorWithProb(SwitchBB, NextMBB, BranchProbToNext);
- // It is not guaranteed that the sum of B.ExtraProb and BranchProbToNext is
- // one as they are relative probabilities (and thus work more like weights),
- // and hence we need to normalize them to let the sum of them become one.
- SwitchBB->normalizeSuccProbs();
-
- // Record the fact that the IR edge from the header to the bit test target
- // will go through our new block. Neeeded for PHIs to have nodes added.
- addMachineCFGPred({BB.Parent->getBasicBlock(), B.TargetBB->getBasicBlock()},
- SwitchBB);
-
- MIB.buildBrCond(Cmp, *B.TargetBB);
-
- // Avoid emitting unnecessary branches to the next block.
- if (NextMBB != SwitchBB->getNextNode())
- MIB.buildBr(*NextMBB);
-}
-
-bool IRTranslator::lowerBitTestWorkItem(
- SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
- MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
- MachineIRBuilder &MIB, MachineFunction::iterator BBI,
- BranchProbability DefaultProb, BranchProbability UnhandledProbs,
- SwitchCG::CaseClusterIt I, MachineBasicBlock *Fallthrough,
- bool FallthroughUnreachable) {
- using namespace SwitchCG;
- MachineFunction *CurMF = SwitchMBB->getParent();
- // FIXME: Optimize away range check based on pivot comparisons.
- BitTestBlock *BTB = &SL->BitTestCases[I->BTCasesIndex];
- // The bit test blocks haven't been inserted yet; insert them here.
- for (BitTestCase &BTC : BTB->Cases)
- CurMF->insert(BBI, BTC.ThisBB);
-
- // Fill in fields of the BitTestBlock.
- BTB->Parent = CurMBB;
- BTB->Default = Fallthrough;
-
- BTB->DefaultProb = UnhandledProbs;
- // If the cases in bit test don't form a contiguous range, we evenly
- // distribute the probability on the edge to Fallthrough to two
- // successors of CurMBB.
- if (!BTB->ContiguousRange) {
- BTB->Prob += DefaultProb / 2;
- BTB->DefaultProb -= DefaultProb / 2;
- }
-
- if (FallthroughUnreachable) {
- // Skip the range check if the fallthrough block is unreachable.
- BTB->OmitRangeCheck = true;
- }
-
- // If we're in the right place, emit the bit test header right now.
- if (CurMBB == SwitchMBB) {
- emitBitTestHeader(*BTB, SwitchMBB);
- BTB->Emitted = true;
- }
- return true;
-}
-
+void IRTranslator::emitBitTestHeader(SwitchCG::BitTestBlock &B,
+ MachineBasicBlock *SwitchBB) {
+ MachineIRBuilder &MIB = *CurBuilder;
+ MIB.setMBB(*SwitchBB);
+
+ // Subtract the minimum value.
+ Register SwitchOpReg = getOrCreateVReg(*B.SValue);
+
+ LLT SwitchOpTy = MRI->getType(SwitchOpReg);
+ Register MinValReg = MIB.buildConstant(SwitchOpTy, B.First).getReg(0);
+ auto RangeSub = MIB.buildSub(SwitchOpTy, SwitchOpReg, MinValReg);
+
+ // Ensure that the type will fit the mask value.
+ LLT MaskTy = SwitchOpTy;
+ for (unsigned I = 0, E = B.Cases.size(); I != E; ++I) {
+ if (!isUIntN(SwitchOpTy.getSizeInBits(), B.Cases[I].Mask)) {
+ // Switch table case range are encoded into series of masks.
+ // Just use pointer type, it's guaranteed to fit.
+ MaskTy = LLT::scalar(64);
+ break;
+ }
+ }
+ Register SubReg = RangeSub.getReg(0);
+ if (SwitchOpTy != MaskTy)
+ SubReg = MIB.buildZExtOrTrunc(MaskTy, SubReg).getReg(0);
+
+ B.RegVT = getMVTForLLT(MaskTy);
+ B.Reg = SubReg;
+
+ MachineBasicBlock *MBB = B.Cases[0].ThisBB;
+
+ if (!B.OmitRangeCheck)
+ addSuccessorWithProb(SwitchBB, B.Default, B.DefaultProb);
+ addSuccessorWithProb(SwitchBB, MBB, B.Prob);
+
+ SwitchBB->normalizeSuccProbs();
+
+ if (!B.OmitRangeCheck) {
+ // Conditional branch to the default block.
+ auto RangeCst = MIB.buildConstant(SwitchOpTy, B.Range);
+ auto RangeCmp = MIB.buildICmp(CmpInst::Predicate::ICMP_UGT, LLT::scalar(1),
+ RangeSub, RangeCst);
+ MIB.buildBrCond(RangeCmp, *B.Default);
+ }
+
+ // Avoid emitting unnecessary branches to the next block.
+ if (MBB != SwitchBB->getNextNode())
+ MIB.buildBr(*MBB);
+}
+
+void IRTranslator::emitBitTestCase(SwitchCG::BitTestBlock &BB,
+ MachineBasicBlock *NextMBB,
+ BranchProbability BranchProbToNext,
+ Register Reg, SwitchCG::BitTestCase &B,
+ MachineBasicBlock *SwitchBB) {
+ MachineIRBuilder &MIB = *CurBuilder;
+ MIB.setMBB(*SwitchBB);
+
+ LLT SwitchTy = getLLTForMVT(BB.RegVT);
+ Register Cmp;
+ unsigned PopCount = countPopulation(B.Mask);
+ if (PopCount == 1) {
+ // Testing for a single bit; just compare the shift count with what it
+ // would need to be to shift a 1 bit in that position.
+ auto MaskTrailingZeros =
+ MIB.buildConstant(SwitchTy, countTrailingZeros(B.Mask));
+ Cmp =
+ MIB.buildICmp(ICmpInst::ICMP_EQ, LLT::scalar(1), Reg, MaskTrailingZeros)
+ .getReg(0);
+ } else if (PopCount == BB.Range) {
+ // There is only one zero bit in the range, test for it directly.
+ auto MaskTrailingOnes =
+ MIB.buildConstant(SwitchTy, countTrailingOnes(B.Mask));
+ Cmp = MIB.buildICmp(CmpInst::ICMP_NE, LLT::scalar(1), Reg, MaskTrailingOnes)
+ .getReg(0);
+ } else {
+ // Make desired shift.
+ auto CstOne = MIB.buildConstant(SwitchTy, 1);
+ auto SwitchVal = MIB.buildShl(SwitchTy, CstOne, Reg);
+
+ // Emit bit tests and jumps.
+ auto CstMask = MIB.buildConstant(SwitchTy, B.Mask);
+ auto AndOp = MIB.buildAnd(SwitchTy, SwitchVal, CstMask);
+ auto CstZero = MIB.buildConstant(SwitchTy, 0);
+ Cmp = MIB.buildICmp(CmpInst::ICMP_NE, LLT::scalar(1), AndOp, CstZero)
+ .getReg(0);
+ }
+
+ // The branch probability from SwitchBB to B.TargetBB is B.ExtraProb.
+ addSuccessorWithProb(SwitchBB, B.TargetBB, B.ExtraProb);
+ // The branch probability from SwitchBB to NextMBB is BranchProbToNext.
+ addSuccessorWithProb(SwitchBB, NextMBB, BranchProbToNext);
+ // It is not guaranteed that the sum of B.ExtraProb and BranchProbToNext is
+ // one as they are relative probabilities (and thus work more like weights),
+ // and hence we need to normalize them to let the sum of them become one.
+ SwitchBB->normalizeSuccProbs();
+
+ // Record the fact that the IR edge from the header to the bit test target
+ // will go through our new block. Neeeded for PHIs to have nodes added.
+ addMachineCFGPred({BB.Parent->getBasicBlock(), B.TargetBB->getBasicBlock()},
+ SwitchBB);
+
+ MIB.buildBrCond(Cmp, *B.TargetBB);
+
+ // Avoid emitting unnecessary branches to the next block.
+ if (NextMBB != SwitchBB->getNextNode())
+ MIB.buildBr(*NextMBB);
+}
+
+bool IRTranslator::lowerBitTestWorkItem(
+ SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
+ MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
+ MachineIRBuilder &MIB, MachineFunction::iterator BBI,
+ BranchProbability DefaultProb, BranchProbability UnhandledProbs,
+ SwitchCG::CaseClusterIt I, MachineBasicBlock *Fallthrough,
+ bool FallthroughUnreachable) {
+ using namespace SwitchCG;
+ MachineFunction *CurMF = SwitchMBB->getParent();
+ // FIXME: Optimize away range check based on pivot comparisons.
+ BitTestBlock *BTB = &SL->BitTestCases[I->BTCasesIndex];
+ // The bit test blocks haven't been inserted yet; insert them here.
+ for (BitTestCase &BTC : BTB->Cases)
+ CurMF->insert(BBI, BTC.ThisBB);
+
+ // Fill in fields of the BitTestBlock.
+ BTB->Parent = CurMBB;
+ BTB->Default = Fallthrough;
+
+ BTB->DefaultProb = UnhandledProbs;
+ // If the cases in bit test don't form a contiguous range, we evenly
+ // distribute the probability on the edge to Fallthrough to two
+ // successors of CurMBB.
+ if (!BTB->ContiguousRange) {
+ BTB->Prob += DefaultProb / 2;
+ BTB->DefaultProb -= DefaultProb / 2;
+ }
+
+ if (FallthroughUnreachable) {
+ // Skip the range check if the fallthrough block is unreachable.
+ BTB->OmitRangeCheck = true;
+ }
+
+ // If we're in the right place, emit the bit test header right now.
+ if (CurMBB == SwitchMBB) {
+ emitBitTestHeader(*BTB, SwitchMBB);
+ BTB->Emitted = true;
+ }
+ return true;
+}
+
bool IRTranslator::lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W,
Value *Cond,
MachineBasicBlock *SwitchMBB,
@@ -1208,15 +1208,15 @@ bool IRTranslator::lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W,
switch (I->Kind) {
case CC_BitTests: {
- if (!lowerBitTestWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
- DefaultProb, UnhandledProbs, I, Fallthrough,
- FallthroughUnreachable)) {
- LLVM_DEBUG(dbgs() << "Failed to lower bit test for switch");
- return false;
- }
- break;
+ if (!lowerBitTestWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
+ DefaultProb, UnhandledProbs, I, Fallthrough,
+ FallthroughUnreachable)) {
+ LLVM_DEBUG(dbgs() << "Failed to lower bit test for switch");
+ return false;
+ }
+ break;
}
-
+
case CC_JumpTable: {
if (!lowerJumpTableWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
UnhandledProbs, I, Fallthrough,
@@ -1557,34 +1557,34 @@ bool IRTranslator::translateGetElementPtr(const User &U,
bool IRTranslator::translateMemFunc(const CallInst &CI,
MachineIRBuilder &MIRBuilder,
- unsigned Opcode) {
+ unsigned Opcode) {
// If the source is undef, then just emit a nop.
if (isa<UndefValue>(CI.getArgOperand(1)))
return true;
- SmallVector<Register, 3> SrcRegs;
-
- unsigned MinPtrSize = UINT_MAX;
- for (auto AI = CI.arg_begin(), AE = CI.arg_end(); std::next(AI) != AE; ++AI) {
- Register SrcReg = getOrCreateVReg(**AI);
- LLT SrcTy = MRI->getType(SrcReg);
- if (SrcTy.isPointer())
- MinPtrSize = std::min(SrcTy.getSizeInBits(), MinPtrSize);
- SrcRegs.push_back(SrcReg);
- }
-
- LLT SizeTy = LLT::scalar(MinPtrSize);
-
- // The size operand should be the minimum of the pointer sizes.
- Register &SizeOpReg = SrcRegs[SrcRegs.size() - 1];
- if (MRI->getType(SizeOpReg) != SizeTy)
- SizeOpReg = MIRBuilder.buildZExtOrTrunc(SizeTy, SizeOpReg).getReg(0);
-
- auto ICall = MIRBuilder.buildInstr(Opcode);
- for (Register SrcReg : SrcRegs)
- ICall.addUse(SrcReg);
-
+ SmallVector<Register, 3> SrcRegs;
+
+ unsigned MinPtrSize = UINT_MAX;
+ for (auto AI = CI.arg_begin(), AE = CI.arg_end(); std::next(AI) != AE; ++AI) {
+ Register SrcReg = getOrCreateVReg(**AI);
+ LLT SrcTy = MRI->getType(SrcReg);
+ if (SrcTy.isPointer())
+ MinPtrSize = std::min(SrcTy.getSizeInBits(), MinPtrSize);
+ SrcRegs.push_back(SrcReg);
+ }
+
+ LLT SizeTy = LLT::scalar(MinPtrSize);
+
+ // The size operand should be the minimum of the pointer sizes.
+ Register &SizeOpReg = SrcRegs[SrcRegs.size() - 1];
+ if (MRI->getType(SizeOpReg) != SizeTy)
+ SizeOpReg = MIRBuilder.buildZExtOrTrunc(SizeTy, SizeOpReg).getReg(0);
+
+ auto ICall = MIRBuilder.buildInstr(Opcode);
+ for (Register SrcReg : SrcRegs)
+ ICall.addUse(SrcReg);
+
Align DstAlign;
Align SrcAlign;
unsigned IsVol =
@@ -1612,7 +1612,7 @@ bool IRTranslator::translateMemFunc(const CallInst &CI,
ICall.addMemOperand(MF->getMachineMemOperand(
MachinePointerInfo(CI.getArgOperand(0)),
MachineMemOperand::MOStore | VolFlag, 1, DstAlign));
- if (Opcode != TargetOpcode::G_MEMSET)
+ if (Opcode != TargetOpcode::G_MEMSET)
ICall.addMemOperand(MF->getMachineMemOperand(
MachinePointerInfo(CI.getArgOperand(1)),
MachineMemOperand::MOLoad | VolFlag, 1, SrcAlign));
@@ -1651,16 +1651,16 @@ bool IRTranslator::translateOverflowIntrinsic(const CallInst &CI, unsigned Op,
return true;
}
-bool IRTranslator::translateFixedPointIntrinsic(unsigned Op, const CallInst &CI,
- MachineIRBuilder &MIRBuilder) {
- Register Dst = getOrCreateVReg(CI);
- Register Src0 = getOrCreateVReg(*CI.getOperand(0));
- Register Src1 = getOrCreateVReg(*CI.getOperand(1));
- uint64_t Scale = cast<ConstantInt>(CI.getOperand(2))->getZExtValue();
- MIRBuilder.buildInstr(Op, {Dst}, { Src0, Src1, Scale });
- return true;
-}
-
+bool IRTranslator::translateFixedPointIntrinsic(unsigned Op, const CallInst &CI,
+ MachineIRBuilder &MIRBuilder) {
+ Register Dst = getOrCreateVReg(CI);
+ Register Src0 = getOrCreateVReg(*CI.getOperand(0));
+ Register Src1 = getOrCreateVReg(*CI.getOperand(1));
+ uint64_t Scale = cast<ConstantInt>(CI.getOperand(2))->getZExtValue();
+ MIRBuilder.buildInstr(Op, {Dst}, { Src0, Src1, Scale });
+ return true;
+}
+
unsigned IRTranslator::getSimpleIntrinsicOpcode(Intrinsic::ID ID) {
switch (ID) {
default:
@@ -1711,14 +1711,14 @@ unsigned IRTranslator::getSimpleIntrinsicOpcode(Intrinsic::ID ID) {
return TargetOpcode::G_FNEARBYINT;
case Intrinsic::pow:
return TargetOpcode::G_FPOW;
- case Intrinsic::powi:
- return TargetOpcode::G_FPOWI;
+ case Intrinsic::powi:
+ return TargetOpcode::G_FPOWI;
case Intrinsic::rint:
return TargetOpcode::G_FRINT;
case Intrinsic::round:
return TargetOpcode::G_INTRINSIC_ROUND;
- case Intrinsic::roundeven:
- return TargetOpcode::G_INTRINSIC_ROUNDEVEN;
+ case Intrinsic::roundeven:
+ return TargetOpcode::G_INTRINSIC_ROUNDEVEN;
case Intrinsic::sin:
return TargetOpcode::G_FSIN;
case Intrinsic::sqrt:
@@ -1729,31 +1729,31 @@ unsigned IRTranslator::getSimpleIntrinsicOpcode(Intrinsic::ID ID) {
return TargetOpcode::G_READCYCLECOUNTER;
case Intrinsic::ptrmask:
return TargetOpcode::G_PTRMASK;
- case Intrinsic::lrint:
- return TargetOpcode::G_INTRINSIC_LRINT;
- // FADD/FMUL require checking the FMF, so are handled elsewhere.
- case Intrinsic::vector_reduce_fmin:
- return TargetOpcode::G_VECREDUCE_FMIN;
- case Intrinsic::vector_reduce_fmax:
- return TargetOpcode::G_VECREDUCE_FMAX;
- case Intrinsic::vector_reduce_add:
- return TargetOpcode::G_VECREDUCE_ADD;
- case Intrinsic::vector_reduce_mul:
- return TargetOpcode::G_VECREDUCE_MUL;
- case Intrinsic::vector_reduce_and:
- return TargetOpcode::G_VECREDUCE_AND;
- case Intrinsic::vector_reduce_or:
- return TargetOpcode::G_VECREDUCE_OR;
- case Intrinsic::vector_reduce_xor:
- return TargetOpcode::G_VECREDUCE_XOR;
- case Intrinsic::vector_reduce_smax:
- return TargetOpcode::G_VECREDUCE_SMAX;
- case Intrinsic::vector_reduce_smin:
- return TargetOpcode::G_VECREDUCE_SMIN;
- case Intrinsic::vector_reduce_umax:
- return TargetOpcode::G_VECREDUCE_UMAX;
- case Intrinsic::vector_reduce_umin:
- return TargetOpcode::G_VECREDUCE_UMIN;
+ case Intrinsic::lrint:
+ return TargetOpcode::G_INTRINSIC_LRINT;
+ // FADD/FMUL require checking the FMF, so are handled elsewhere.
+ case Intrinsic::vector_reduce_fmin:
+ return TargetOpcode::G_VECREDUCE_FMIN;
+ case Intrinsic::vector_reduce_fmax:
+ return TargetOpcode::G_VECREDUCE_FMAX;
+ case Intrinsic::vector_reduce_add:
+ return TargetOpcode::G_VECREDUCE_ADD;
+ case Intrinsic::vector_reduce_mul:
+ return TargetOpcode::G_VECREDUCE_MUL;
+ case Intrinsic::vector_reduce_and:
+ return TargetOpcode::G_VECREDUCE_AND;
+ case Intrinsic::vector_reduce_or:
+ return TargetOpcode::G_VECREDUCE_OR;
+ case Intrinsic::vector_reduce_xor:
+ return TargetOpcode::G_VECREDUCE_XOR;
+ case Intrinsic::vector_reduce_smax:
+ return TargetOpcode::G_VECREDUCE_SMAX;
+ case Intrinsic::vector_reduce_smin:
+ return TargetOpcode::G_VECREDUCE_SMIN;
+ case Intrinsic::vector_reduce_umax:
+ return TargetOpcode::G_VECREDUCE_UMAX;
+ case Intrinsic::vector_reduce_umin:
+ return TargetOpcode::G_VECREDUCE_UMIN;
}
return Intrinsic::not_intrinsic;
}
@@ -1846,7 +1846,7 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
// Get the underlying objects for the location passed on the lifetime
// marker.
SmallVector<const Value *, 4> Allocas;
- getUnderlyingObjects(CI.getArgOperand(1), Allocas);
+ getUnderlyingObjects(CI.getArgOperand(1), Allocas);
// Iterate over each underlying object, creating lifetime markers for each
// static alloca. Quit if we find a non-static alloca.
@@ -1960,37 +1960,37 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
return translateBinaryOp(TargetOpcode::G_USUBSAT, CI, MIRBuilder);
case Intrinsic::ssub_sat:
return translateBinaryOp(TargetOpcode::G_SSUBSAT, CI, MIRBuilder);
- case Intrinsic::ushl_sat:
- return translateBinaryOp(TargetOpcode::G_USHLSAT, CI, MIRBuilder);
- case Intrinsic::sshl_sat:
- return translateBinaryOp(TargetOpcode::G_SSHLSAT, CI, MIRBuilder);
- case Intrinsic::umin:
- return translateBinaryOp(TargetOpcode::G_UMIN, CI, MIRBuilder);
- case Intrinsic::umax:
- return translateBinaryOp(TargetOpcode::G_UMAX, CI, MIRBuilder);
- case Intrinsic::smin:
- return translateBinaryOp(TargetOpcode::G_SMIN, CI, MIRBuilder);
- case Intrinsic::smax:
- return translateBinaryOp(TargetOpcode::G_SMAX, CI, MIRBuilder);
- case Intrinsic::abs:
- // TODO: Preserve "int min is poison" arg in GMIR?
- return translateUnaryOp(TargetOpcode::G_ABS, CI, MIRBuilder);
- case Intrinsic::smul_fix:
- return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIX, CI, MIRBuilder);
- case Intrinsic::umul_fix:
- return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIX, CI, MIRBuilder);
- case Intrinsic::smul_fix_sat:
- return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIXSAT, CI, MIRBuilder);
- case Intrinsic::umul_fix_sat:
- return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIXSAT, CI, MIRBuilder);
- case Intrinsic::sdiv_fix:
- return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIX, CI, MIRBuilder);
- case Intrinsic::udiv_fix:
- return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIX, CI, MIRBuilder);
- case Intrinsic::sdiv_fix_sat:
- return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIXSAT, CI, MIRBuilder);
- case Intrinsic::udiv_fix_sat:
- return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIXSAT, CI, MIRBuilder);
+ case Intrinsic::ushl_sat:
+ return translateBinaryOp(TargetOpcode::G_USHLSAT, CI, MIRBuilder);
+ case Intrinsic::sshl_sat:
+ return translateBinaryOp(TargetOpcode::G_SSHLSAT, CI, MIRBuilder);
+ case Intrinsic::umin:
+ return translateBinaryOp(TargetOpcode::G_UMIN, CI, MIRBuilder);
+ case Intrinsic::umax:
+ return translateBinaryOp(TargetOpcode::G_UMAX, CI, MIRBuilder);
+ case Intrinsic::smin:
+ return translateBinaryOp(TargetOpcode::G_SMIN, CI, MIRBuilder);
+ case Intrinsic::smax:
+ return translateBinaryOp(TargetOpcode::G_SMAX, CI, MIRBuilder);
+ case Intrinsic::abs:
+ // TODO: Preserve "int min is poison" arg in GMIR?
+ return translateUnaryOp(TargetOpcode::G_ABS, CI, MIRBuilder);
+ case Intrinsic::smul_fix:
+ return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIX, CI, MIRBuilder);
+ case Intrinsic::umul_fix:
+ return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIX, CI, MIRBuilder);
+ case Intrinsic::smul_fix_sat:
+ return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIXSAT, CI, MIRBuilder);
+ case Intrinsic::umul_fix_sat:
+ return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIXSAT, CI, MIRBuilder);
+ case Intrinsic::sdiv_fix:
+ return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIX, CI, MIRBuilder);
+ case Intrinsic::udiv_fix:
+ return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIX, CI, MIRBuilder);
+ case Intrinsic::sdiv_fix_sat:
+ return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIXSAT, CI, MIRBuilder);
+ case Intrinsic::udiv_fix_sat:
+ return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIXSAT, CI, MIRBuilder);
case Intrinsic::fmuladd: {
const TargetMachine &TM = MF->getTarget();
const TargetLowering &TLI = *MF->getSubtarget().getTargetLowering();
@@ -2014,24 +2014,24 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
}
return true;
}
- case Intrinsic::convert_from_fp16:
- // FIXME: This intrinsic should probably be removed from the IR.
- MIRBuilder.buildFPExt(getOrCreateVReg(CI),
- getOrCreateVReg(*CI.getArgOperand(0)),
- MachineInstr::copyFlagsFromInstruction(CI));
- return true;
- case Intrinsic::convert_to_fp16:
- // FIXME: This intrinsic should probably be removed from the IR.
- MIRBuilder.buildFPTrunc(getOrCreateVReg(CI),
- getOrCreateVReg(*CI.getArgOperand(0)),
- MachineInstr::copyFlagsFromInstruction(CI));
- return true;
+ case Intrinsic::convert_from_fp16:
+ // FIXME: This intrinsic should probably be removed from the IR.
+ MIRBuilder.buildFPExt(getOrCreateVReg(CI),
+ getOrCreateVReg(*CI.getArgOperand(0)),
+ MachineInstr::copyFlagsFromInstruction(CI));
+ return true;
+ case Intrinsic::convert_to_fp16:
+ // FIXME: This intrinsic should probably be removed from the IR.
+ MIRBuilder.buildFPTrunc(getOrCreateVReg(CI),
+ getOrCreateVReg(*CI.getArgOperand(0)),
+ MachineInstr::copyFlagsFromInstruction(CI));
+ return true;
case Intrinsic::memcpy:
- return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY);
+ return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY);
case Intrinsic::memmove:
- return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMMOVE);
+ return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMMOVE);
case Intrinsic::memset:
- return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET);
+ return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET);
case Intrinsic::eh_typeid_for: {
GlobalValue *GV = ExtractTypeInfo(CI.getArgOperand(0));
Register Reg = getOrCreateVReg(CI);
@@ -2114,18 +2114,18 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
}
case Intrinsic::invariant_end:
return true;
- case Intrinsic::expect:
- case Intrinsic::annotation:
- case Intrinsic::ptr_annotation:
- case Intrinsic::launder_invariant_group:
- case Intrinsic::strip_invariant_group: {
- // Drop the intrinsic, but forward the value.
- MIRBuilder.buildCopy(getOrCreateVReg(CI),
- getOrCreateVReg(*CI.getArgOperand(0)));
- return true;
- }
+ case Intrinsic::expect:
+ case Intrinsic::annotation:
+ case Intrinsic::ptr_annotation:
+ case Intrinsic::launder_invariant_group:
+ case Intrinsic::strip_invariant_group: {
+ // Drop the intrinsic, but forward the value.
+ MIRBuilder.buildCopy(getOrCreateVReg(CI),
+ getOrCreateVReg(*CI.getArgOperand(0)));
+ return true;
+ }
case Intrinsic::assume:
- case Intrinsic::experimental_noalias_scope_decl:
+ case Intrinsic::experimental_noalias_scope_decl:
case Intrinsic::var_annotation:
case Intrinsic::sideeffect:
// Discard annotate attributes, assumptions, and artificial side-effects.
@@ -2145,68 +2145,68 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
.addUse(getOrCreateVReg(*CI.getArgOperand(1)));
return true;
}
- case Intrinsic::localescape: {
- MachineBasicBlock &EntryMBB = MF->front();
- StringRef EscapedName = GlobalValue::dropLLVMManglingEscape(MF->getName());
-
- // Directly emit some LOCAL_ESCAPE machine instrs. Label assignment emission
- // is the same on all targets.
- for (unsigned Idx = 0, E = CI.getNumArgOperands(); Idx < E; ++Idx) {
- Value *Arg = CI.getArgOperand(Idx)->stripPointerCasts();
- if (isa<ConstantPointerNull>(Arg))
- continue; // Skip null pointers. They represent a hole in index space.
-
- int FI = getOrCreateFrameIndex(*cast<AllocaInst>(Arg));
- MCSymbol *FrameAllocSym =
- MF->getMMI().getContext().getOrCreateFrameAllocSymbol(EscapedName,
- Idx);
-
- // This should be inserted at the start of the entry block.
- auto LocalEscape =
- MIRBuilder.buildInstrNoInsert(TargetOpcode::LOCAL_ESCAPE)
- .addSym(FrameAllocSym)
- .addFrameIndex(FI);
-
- EntryMBB.insert(EntryMBB.begin(), LocalEscape);
- }
-
- return true;
- }
- case Intrinsic::vector_reduce_fadd:
- case Intrinsic::vector_reduce_fmul: {
- // Need to check for the reassoc flag to decide whether we want a
- // sequential reduction opcode or not.
- Register Dst = getOrCreateVReg(CI);
- Register ScalarSrc = getOrCreateVReg(*CI.getArgOperand(0));
- Register VecSrc = getOrCreateVReg(*CI.getArgOperand(1));
- unsigned Opc = 0;
- if (!CI.hasAllowReassoc()) {
- // The sequential ordering case.
- Opc = ID == Intrinsic::vector_reduce_fadd
- ? TargetOpcode::G_VECREDUCE_SEQ_FADD
- : TargetOpcode::G_VECREDUCE_SEQ_FMUL;
- MIRBuilder.buildInstr(Opc, {Dst}, {ScalarSrc, VecSrc},
- MachineInstr::copyFlagsFromInstruction(CI));
- return true;
- }
- // We split the operation into a separate G_FADD/G_FMUL + the reduce,
- // since the associativity doesn't matter.
- unsigned ScalarOpc;
- if (ID == Intrinsic::vector_reduce_fadd) {
- Opc = TargetOpcode::G_VECREDUCE_FADD;
- ScalarOpc = TargetOpcode::G_FADD;
- } else {
- Opc = TargetOpcode::G_VECREDUCE_FMUL;
- ScalarOpc = TargetOpcode::G_FMUL;
- }
- LLT DstTy = MRI->getType(Dst);
- auto Rdx = MIRBuilder.buildInstr(
- Opc, {DstTy}, {VecSrc}, MachineInstr::copyFlagsFromInstruction(CI));
- MIRBuilder.buildInstr(ScalarOpc, {Dst}, {ScalarSrc, Rdx},
- MachineInstr::copyFlagsFromInstruction(CI));
-
- return true;
- }
+ case Intrinsic::localescape: {
+ MachineBasicBlock &EntryMBB = MF->front();
+ StringRef EscapedName = GlobalValue::dropLLVMManglingEscape(MF->getName());
+
+ // Directly emit some LOCAL_ESCAPE machine instrs. Label assignment emission
+ // is the same on all targets.
+ for (unsigned Idx = 0, E = CI.getNumArgOperands(); Idx < E; ++Idx) {
+ Value *Arg = CI.getArgOperand(Idx)->stripPointerCasts();
+ if (isa<ConstantPointerNull>(Arg))
+ continue; // Skip null pointers. They represent a hole in index space.
+
+ int FI = getOrCreateFrameIndex(*cast<AllocaInst>(Arg));
+ MCSymbol *FrameAllocSym =
+ MF->getMMI().getContext().getOrCreateFrameAllocSymbol(EscapedName,
+ Idx);
+
+ // This should be inserted at the start of the entry block.
+ auto LocalEscape =
+ MIRBuilder.buildInstrNoInsert(TargetOpcode::LOCAL_ESCAPE)
+ .addSym(FrameAllocSym)
+ .addFrameIndex(FI);
+
+ EntryMBB.insert(EntryMBB.begin(), LocalEscape);
+ }
+
+ return true;
+ }
+ case Intrinsic::vector_reduce_fadd:
+ case Intrinsic::vector_reduce_fmul: {
+ // Need to check for the reassoc flag to decide whether we want a
+ // sequential reduction opcode or not.
+ Register Dst = getOrCreateVReg(CI);
+ Register ScalarSrc = getOrCreateVReg(*CI.getArgOperand(0));
+ Register VecSrc = getOrCreateVReg(*CI.getArgOperand(1));
+ unsigned Opc = 0;
+ if (!CI.hasAllowReassoc()) {
+ // The sequential ordering case.
+ Opc = ID == Intrinsic::vector_reduce_fadd
+ ? TargetOpcode::G_VECREDUCE_SEQ_FADD
+ : TargetOpcode::G_VECREDUCE_SEQ_FMUL;
+ MIRBuilder.buildInstr(Opc, {Dst}, {ScalarSrc, VecSrc},
+ MachineInstr::copyFlagsFromInstruction(CI));
+ return true;
+ }
+ // We split the operation into a separate G_FADD/G_FMUL + the reduce,
+ // since the associativity doesn't matter.
+ unsigned ScalarOpc;
+ if (ID == Intrinsic::vector_reduce_fadd) {
+ Opc = TargetOpcode::G_VECREDUCE_FADD;
+ ScalarOpc = TargetOpcode::G_FADD;
+ } else {
+ Opc = TargetOpcode::G_VECREDUCE_FMUL;
+ ScalarOpc = TargetOpcode::G_FMUL;
+ }
+ LLT DstTy = MRI->getType(Dst);
+ auto Rdx = MIRBuilder.buildInstr(
+ Opc, {DstTy}, {VecSrc}, MachineInstr::copyFlagsFromInstruction(CI));
+ MIRBuilder.buildInstr(ScalarOpc, {Dst}, {ScalarSrc, Rdx},
+ MachineInstr::copyFlagsFromInstruction(CI));
+
+ return true;
+ }
#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
case Intrinsic::INTRINSIC:
#include "llvm/IR/ConstrainedOps.def"
@@ -2328,11 +2328,11 @@ bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) {
} else {
MIB.addFPImm(cast<ConstantFP>(Arg.value()));
}
- } else if (auto MD = dyn_cast<MetadataAsValue>(Arg.value())) {
- auto *MDN = dyn_cast<MDNode>(MD->getMetadata());
- if (!MDN) // This was probably an MDString.
- return false;
- MIB.addMetadata(MDN);
+ } else if (auto MD = dyn_cast<MetadataAsValue>(Arg.value())) {
+ auto *MDN = dyn_cast<MDNode>(MD->getMetadata());
+ if (!MDN) // This was probably an MDString.
+ return false;
+ MIB.addMetadata(MDN);
} else {
ArrayRef<Register> VRegs = getOrCreateVRegs(*Arg.value());
if (VRegs.size() > 1)
@@ -2357,62 +2357,62 @@ bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) {
return true;
}
-bool IRTranslator::findUnwindDestinations(
- const BasicBlock *EHPadBB,
- BranchProbability Prob,
- SmallVectorImpl<std::pair<MachineBasicBlock *, BranchProbability>>
- &UnwindDests) {
- EHPersonality Personality = classifyEHPersonality(
- EHPadBB->getParent()->getFunction().getPersonalityFn());
- bool IsMSVCCXX = Personality == EHPersonality::MSVC_CXX;
- bool IsCoreCLR = Personality == EHPersonality::CoreCLR;
- bool IsWasmCXX = Personality == EHPersonality::Wasm_CXX;
- bool IsSEH = isAsynchronousEHPersonality(Personality);
-
- if (IsWasmCXX) {
- // Ignore this for now.
- return false;
- }
-
- while (EHPadBB) {
- const Instruction *Pad = EHPadBB->getFirstNonPHI();
- BasicBlock *NewEHPadBB = nullptr;
- if (isa<LandingPadInst>(Pad)) {
- // Stop on landingpads. They are not funclets.
- UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
- break;
- }
- if (isa<CleanupPadInst>(Pad)) {
- // Stop on cleanup pads. Cleanups are always funclet entries for all known
- // personalities.
- UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
- UnwindDests.back().first->setIsEHScopeEntry();
- UnwindDests.back().first->setIsEHFuncletEntry();
- break;
- }
- if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(Pad)) {
- // Add the catchpad handlers to the possible destinations.
- for (const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
- UnwindDests.emplace_back(&getMBB(*CatchPadBB), Prob);
- // For MSVC++ and the CLR, catchblocks are funclets and need prologues.
- if (IsMSVCCXX || IsCoreCLR)
- UnwindDests.back().first->setIsEHFuncletEntry();
- if (!IsSEH)
- UnwindDests.back().first->setIsEHScopeEntry();
- }
- NewEHPadBB = CatchSwitch->getUnwindDest();
- } else {
- continue;
- }
-
- BranchProbabilityInfo *BPI = FuncInfo.BPI;
- if (BPI && NewEHPadBB)
- Prob *= BPI->getEdgeProbability(EHPadBB, NewEHPadBB);
- EHPadBB = NewEHPadBB;
- }
- return true;
-}
-
+bool IRTranslator::findUnwindDestinations(
+ const BasicBlock *EHPadBB,
+ BranchProbability Prob,
+ SmallVectorImpl<std::pair<MachineBasicBlock *, BranchProbability>>
+ &UnwindDests) {
+ EHPersonality Personality = classifyEHPersonality(
+ EHPadBB->getParent()->getFunction().getPersonalityFn());
+ bool IsMSVCCXX = Personality == EHPersonality::MSVC_CXX;
+ bool IsCoreCLR = Personality == EHPersonality::CoreCLR;
+ bool IsWasmCXX = Personality == EHPersonality::Wasm_CXX;
+ bool IsSEH = isAsynchronousEHPersonality(Personality);
+
+ if (IsWasmCXX) {
+ // Ignore this for now.
+ return false;
+ }
+
+ while (EHPadBB) {
+ const Instruction *Pad = EHPadBB->getFirstNonPHI();
+ BasicBlock *NewEHPadBB = nullptr;
+ if (isa<LandingPadInst>(Pad)) {
+ // Stop on landingpads. They are not funclets.
+ UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
+ break;
+ }
+ if (isa<CleanupPadInst>(Pad)) {
+ // Stop on cleanup pads. Cleanups are always funclet entries for all known
+ // personalities.
+ UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
+ UnwindDests.back().first->setIsEHScopeEntry();
+ UnwindDests.back().first->setIsEHFuncletEntry();
+ break;
+ }
+ if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(Pad)) {
+ // Add the catchpad handlers to the possible destinations.
+ for (const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
+ UnwindDests.emplace_back(&getMBB(*CatchPadBB), Prob);
+ // For MSVC++ and the CLR, catchblocks are funclets and need prologues.
+ if (IsMSVCCXX || IsCoreCLR)
+ UnwindDests.back().first->setIsEHFuncletEntry();
+ if (!IsSEH)
+ UnwindDests.back().first->setIsEHScopeEntry();
+ }
+ NewEHPadBB = CatchSwitch->getUnwindDest();
+ } else {
+ continue;
+ }
+
+ BranchProbabilityInfo *BPI = FuncInfo.BPI;
+ if (BPI && NewEHPadBB)
+ Prob *= BPI->getEdgeProbability(EHPadBB, NewEHPadBB);
+ EHPadBB = NewEHPadBB;
+ }
+ return true;
+}
+
bool IRTranslator::translateInvoke(const User &U,
MachineIRBuilder &MIRBuilder) {
const InvokeInst &I = cast<InvokeInst>(U);
@@ -2438,7 +2438,7 @@ bool IRTranslator::translateInvoke(const User &U,
return false;
// FIXME: support Windows exception handling.
- if (!isa<LandingPadInst>(EHPadBB->getFirstNonPHI()))
+ if (!isa<LandingPadInst>(EHPadBB->getFirstNonPHI()))
return false;
// Emit the actual call, bracketed by EH_LABELs so that the MF knows about
@@ -2452,26 +2452,26 @@ bool IRTranslator::translateInvoke(const User &U,
MCSymbol *EndSymbol = Context.createTempSymbol();
MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(EndSymbol);
- SmallVector<std::pair<MachineBasicBlock *, BranchProbability>, 1> UnwindDests;
- BranchProbabilityInfo *BPI = FuncInfo.BPI;
- MachineBasicBlock *InvokeMBB = &MIRBuilder.getMBB();
- BranchProbability EHPadBBProb =
- BPI ? BPI->getEdgeProbability(InvokeMBB->getBasicBlock(), EHPadBB)
- : BranchProbability::getZero();
-
- if (!findUnwindDestinations(EHPadBB, EHPadBBProb, UnwindDests))
- return false;
-
+ SmallVector<std::pair<MachineBasicBlock *, BranchProbability>, 1> UnwindDests;
+ BranchProbabilityInfo *BPI = FuncInfo.BPI;
+ MachineBasicBlock *InvokeMBB = &MIRBuilder.getMBB();
+ BranchProbability EHPadBBProb =
+ BPI ? BPI->getEdgeProbability(InvokeMBB->getBasicBlock(), EHPadBB)
+ : BranchProbability::getZero();
+
+ if (!findUnwindDestinations(EHPadBB, EHPadBBProb, UnwindDests))
+ return false;
+
MachineBasicBlock &EHPadMBB = getMBB(*EHPadBB),
&ReturnMBB = getMBB(*ReturnBB);
- // Update successor info.
- addSuccessorWithProb(InvokeMBB, &ReturnMBB);
- for (auto &UnwindDest : UnwindDests) {
- UnwindDest.first->setIsEHPad();
- addSuccessorWithProb(InvokeMBB, UnwindDest.first, UnwindDest.second);
- }
- InvokeMBB->normalizeSuccProbs();
-
+ // Update successor info.
+ addSuccessorWithProb(InvokeMBB, &ReturnMBB);
+ for (auto &UnwindDest : UnwindDests) {
+ UnwindDest.first->setIsEHPad();
+ addSuccessorWithProb(InvokeMBB, UnwindDest.first, UnwindDest.second);
+ }
+ InvokeMBB->normalizeSuccProbs();
+
MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
MIRBuilder.buildBr(ReturnMBB);
return true;
@@ -2511,12 +2511,12 @@ bool IRTranslator::translateLandingPad(const User &U,
MIRBuilder.buildInstr(TargetOpcode::EH_LABEL)
.addSym(MF->addLandingPad(&MBB));
- // If the unwinder does not preserve all registers, ensure that the
- // function marks the clobbered registers as used.
- const TargetRegisterInfo &TRI = *MF->getSubtarget().getRegisterInfo();
- if (auto *RegMask = TRI.getCustomEHPadPreservedMask(*MF))
- MF->getRegInfo().addPhysRegsUsedFromRegMask(RegMask);
-
+ // If the unwinder does not preserve all registers, ensure that the
+ // function marks the clobbered registers as used.
+ const TargetRegisterInfo &TRI = *MF->getSubtarget().getRegisterInfo();
+ if (auto *RegMask = TRI.getCustomEHPadPreservedMask(*MF))
+ MF->getRegInfo().addPhysRegsUsedFromRegMask(RegMask);
+
LLT Ty = getLLTForType(*LP.getType(), *DL);
Register Undef = MRI->createGenericVirtualRegister(Ty);
MIRBuilder.buildUndef(Undef);
@@ -2855,8 +2855,8 @@ bool IRTranslator::translate(const Instruction &Inst) {
// We only emit constants into the entry block from here. To prevent jumpy
// debug behaviour set the line to 0.
if (const DebugLoc &DL = Inst.getDebugLoc())
- EntryBuilder->setDebugLoc(DILocation::get(
- Inst.getContext(), 0, 0, DL.getScope(), DL.getInlinedAt()));
+ EntryBuilder->setDebugLoc(DILocation::get(
+ Inst.getContext(), 0, 0, DL.getScope(), DL.getInlinedAt()));
else
EntryBuilder->setDebugLoc(DebugLoc());
@@ -2934,57 +2934,57 @@ bool IRTranslator::translate(const Constant &C, Register Reg) {
}
void IRTranslator::finalizeBasicBlock() {
- for (auto &BTB : SL->BitTestCases) {
- // Emit header first, if it wasn't already emitted.
- if (!BTB.Emitted)
- emitBitTestHeader(BTB, BTB.Parent);
-
- BranchProbability UnhandledProb = BTB.Prob;
- for (unsigned j = 0, ej = BTB.Cases.size(); j != ej; ++j) {
- UnhandledProb -= BTB.Cases[j].ExtraProb;
- // Set the current basic block to the mbb we wish to insert the code into
- MachineBasicBlock *MBB = BTB.Cases[j].ThisBB;
- // If all cases cover a contiguous range, it is not necessary to jump to
- // the default block after the last bit test fails. This is because the
- // range check during bit test header creation has guaranteed that every
- // case here doesn't go outside the range. In this case, there is no need
- // to perform the last bit test, as it will always be true. Instead, make
- // the second-to-last bit-test fall through to the target of the last bit
- // test, and delete the last bit test.
-
- MachineBasicBlock *NextMBB;
- if (BTB.ContiguousRange && j + 2 == ej) {
- // Second-to-last bit-test with contiguous range: fall through to the
- // target of the final bit test.
- NextMBB = BTB.Cases[j + 1].TargetBB;
- } else if (j + 1 == ej) {
- // For the last bit test, fall through to Default.
- NextMBB = BTB.Default;
- } else {
- // Otherwise, fall through to the next bit test.
- NextMBB = BTB.Cases[j + 1].ThisBB;
- }
-
- emitBitTestCase(BTB, NextMBB, UnhandledProb, BTB.Reg, BTB.Cases[j], MBB);
-
- // FIXME delete this block below?
- if (BTB.ContiguousRange && j + 2 == ej) {
- // Since we're not going to use the final bit test, remove it.
- BTB.Cases.pop_back();
- break;
- }
- }
- // This is "default" BB. We have two jumps to it. From "header" BB and from
- // last "case" BB, unless the latter was skipped.
- CFGEdge HeaderToDefaultEdge = {BTB.Parent->getBasicBlock(),
- BTB.Default->getBasicBlock()};
- addMachineCFGPred(HeaderToDefaultEdge, BTB.Parent);
- if (!BTB.ContiguousRange) {
- addMachineCFGPred(HeaderToDefaultEdge, BTB.Cases.back().ThisBB);
- }
- }
- SL->BitTestCases.clear();
-
+ for (auto &BTB : SL->BitTestCases) {
+ // Emit header first, if it wasn't already emitted.
+ if (!BTB.Emitted)
+ emitBitTestHeader(BTB, BTB.Parent);
+
+ BranchProbability UnhandledProb = BTB.Prob;
+ for (unsigned j = 0, ej = BTB.Cases.size(); j != ej; ++j) {
+ UnhandledProb -= BTB.Cases[j].ExtraProb;
+ // Set the current basic block to the mbb we wish to insert the code into
+ MachineBasicBlock *MBB = BTB.Cases[j].ThisBB;
+ // If all cases cover a contiguous range, it is not necessary to jump to
+ // the default block after the last bit test fails. This is because the
+ // range check during bit test header creation has guaranteed that every
+ // case here doesn't go outside the range. In this case, there is no need
+ // to perform the last bit test, as it will always be true. Instead, make
+ // the second-to-last bit-test fall through to the target of the last bit
+ // test, and delete the last bit test.
+
+ MachineBasicBlock *NextMBB;
+ if (BTB.ContiguousRange && j + 2 == ej) {
+ // Second-to-last bit-test with contiguous range: fall through to the
+ // target of the final bit test.
+ NextMBB = BTB.Cases[j + 1].TargetBB;
+ } else if (j + 1 == ej) {
+ // For the last bit test, fall through to Default.
+ NextMBB = BTB.Default;
+ } else {
+ // Otherwise, fall through to the next bit test.
+ NextMBB = BTB.Cases[j + 1].ThisBB;
+ }
+
+ emitBitTestCase(BTB, NextMBB, UnhandledProb, BTB.Reg, BTB.Cases[j], MBB);
+
+ // FIXME delete this block below?
+ if (BTB.ContiguousRange && j + 2 == ej) {
+ // Since we're not going to use the final bit test, remove it.
+ BTB.Cases.pop_back();
+ break;
+ }
+ }
+ // This is "default" BB. We have two jumps to it. From "header" BB and from
+ // last "case" BB, unless the latter was skipped.
+ CFGEdge HeaderToDefaultEdge = {BTB.Parent->getBasicBlock(),
+ BTB.Default->getBasicBlock()};
+ addMachineCFGPred(HeaderToDefaultEdge, BTB.Parent);
+ if (!BTB.ContiguousRange) {
+ addMachineCFGPred(HeaderToDefaultEdge, BTB.Cases.back().ThisBB);
+ }
+ }
+ SL->BitTestCases.clear();
+
for (auto &JTCase : SL->JTCases) {
// Emit header first, if it wasn't already emitted.
if (!JTCase.first.Emitted)
@@ -2993,10 +2993,10 @@ void IRTranslator::finalizeBasicBlock() {
emitJumpTable(JTCase.second, JTCase.second.MBB);
}
SL->JTCases.clear();
-
- for (auto &SwCase : SL->SwitchCases)
- emitSwitchCase(SwCase, &CurBuilder->getMBB(), *CurBuilder);
- SL->SwitchCases.clear();
+
+ for (auto &SwCase : SL->SwitchCases)
+ emitSwitchCase(SwCase, &CurBuilder->getMBB(), *CurBuilder);
+ SL->SwitchCases.clear();
}
void IRTranslator::finalizeFunction() {
@@ -3058,24 +3058,24 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
MRI = &MF->getRegInfo();
DL = &F.getParent()->getDataLayout();
ORE = std::make_unique<OptimizationRemarkEmitter>(&F);
- const TargetMachine &TM = MF->getTarget();
- TM.resetTargetOptions(F);
- EnableOpts = OptLevel != CodeGenOpt::None && !skipFunction(F);
+ const TargetMachine &TM = MF->getTarget();
+ TM.resetTargetOptions(F);
+ EnableOpts = OptLevel != CodeGenOpt::None && !skipFunction(F);
FuncInfo.MF = MF;
- if (EnableOpts)
- FuncInfo.BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
- else
- FuncInfo.BPI = nullptr;
-
- FuncInfo.CanLowerReturn = CLI->checkReturnTypeForCallConv(*MF);
-
+ if (EnableOpts)
+ FuncInfo.BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
+ else
+ FuncInfo.BPI = nullptr;
+
+ FuncInfo.CanLowerReturn = CLI->checkReturnTypeForCallConv(*MF);
+
const auto &TLI = *MF->getSubtarget().getTargetLowering();
-
+
SL = std::make_unique<GISelSwitchLowering>(this, FuncInfo);
SL->init(TLI, TM, *DL);
-
+
assert(PendingPHIs.empty() && "stale PHIs");
if (!DL->isLittleEndian()) {
@@ -3142,7 +3142,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
}
}
- if (!CLI->lowerFormalArguments(*EntryBuilder.get(), F, VRegArgs, FuncInfo)) {
+ if (!CLI->lowerFormalArguments(*EntryBuilder.get(), F, VRegArgs, FuncInfo)) {
OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure",
F.getSubprogram(), &F.getEntryBlock());
R << "unable to lower arguments: " << ore::NV("Prototype", F.getType());
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
index 8bdf9f8862..bb4d41cfd6 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
@@ -562,11 +562,11 @@ bool InlineAsmLowering::lowerInlineAsm(
}
unsigned Flag = InlineAsm::getFlagWord(InlineAsm::Kind_RegUse, NumRegs);
- if (OpInfo.Regs.front().isVirtual()) {
- // Put the register class of the virtual registers in the flag word.
- const TargetRegisterClass *RC = MRI->getRegClass(OpInfo.Regs.front());
- Flag = InlineAsm::getFlagWordForRegClass(Flag, RC->getID());
- }
+ if (OpInfo.Regs.front().isVirtual()) {
+ // Put the register class of the virtual registers in the flag word.
+ const TargetRegisterClass *RC = MRI->getRegClass(OpInfo.Regs.front());
+ Flag = InlineAsm::getFlagWordForRegClass(Flag, RC->getID());
+ }
Inst.addImm(Flag);
if (!buildAnyextOrCopy(OpInfo.Regs[0], SourceRegs[0], MIRBuilder))
return false;
@@ -662,7 +662,7 @@ bool InlineAsmLowering::lowerAsmOperandForConstraint(
default:
return false;
case 'i': // Simple Integer or Relocatable Constant
- case 'n': // immediate integer with a known value.
+ case 'n': // immediate integer with a known value.
if (ConstantInt *CI = dyn_cast<ConstantInt>(Val)) {
assert(CI->getBitWidth() <= 64 &&
"expected immediate to fit into 64-bits");
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/InstructionSelect.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/InstructionSelect.cpp
index bbd09edaf1..25fae54871 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/InstructionSelect.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/InstructionSelect.cpp
@@ -41,7 +41,7 @@ static cl::opt<std::string>
cl::desc("Record GlobalISel rule coverage files of this "
"prefix if instrumentation was generated"));
#else
-static const std::string CoveragePrefix;
+static const std::string CoveragePrefix;
#endif
char InstructionSelect::ID = 0;
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/InstructionSelector.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/InstructionSelector.cpp
index 1f39b5bf2c..4fec9e628d 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/InstructionSelector.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/InstructionSelector.cpp
@@ -38,7 +38,7 @@ bool InstructionSelector::isOperandImmEqual(
const MachineRegisterInfo &MRI) const {
if (MO.isReg() && MO.getReg())
if (auto VRegVal = getConstantVRegValWithLookThrough(MO.getReg(), MRI))
- return VRegVal->Value.getSExtValue() == Value;
+ return VRegVal->Value.getSExtValue() == Value;
return false;
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalityPredicates.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalityPredicates.cpp
index 5d2979e053..1993f60332 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalityPredicates.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalityPredicates.cpp
@@ -10,17 +10,17 @@
//
//===----------------------------------------------------------------------===//
-// Enable optimizations to work around MSVC debug mode bug in 32-bit:
-// https://developercommunity.visualstudio.com/content/problem/1179643/msvc-copies-overaligned-non-trivially-copyable-par.html
-// FIXME: Remove this when the issue is closed.
-#if defined(_MSC_VER) && !defined(__clang__) && defined(_M_IX86)
-// We have to disable runtime checks in order to enable optimizations. This is
-// done for the entire file because the problem is actually observed in STL
-// template functions.
-#pragma runtime_checks("", off)
-#pragma optimize("gs", on)
-#endif
-
+// Enable optimizations to work around MSVC debug mode bug in 32-bit:
+// https://developercommunity.visualstudio.com/content/problem/1179643/msvc-copies-overaligned-non-trivially-copyable-par.html
+// FIXME: Remove this when the issue is closed.
+#if defined(_MSC_VER) && !defined(__clang__) && defined(_M_IX86)
+// We have to disable runtime checks in order to enable optimizations. This is
+// done for the entire file because the problem is actually observed in STL
+// template functions.
+#pragma runtime_checks("", off)
+#pragma optimize("gs", on)
+#endif
+
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
using namespace llvm;
@@ -35,7 +35,7 @@ LegalityPredicates::typeInSet(unsigned TypeIdx,
std::initializer_list<LLT> TypesInit) {
SmallVector<LLT, 4> Types = TypesInit;
return [=](const LegalityQuery &Query) {
- return llvm::is_contained(Types, Query.Types[TypeIdx]);
+ return llvm::is_contained(Types, Query.Types[TypeIdx]);
};
}
@@ -45,7 +45,7 @@ LegalityPredicate LegalityPredicates::typePairInSet(
SmallVector<std::pair<LLT, LLT>, 4> Types = TypesInit;
return [=](const LegalityQuery &Query) {
std::pair<LLT, LLT> Match = {Query.Types[TypeIdx0], Query.Types[TypeIdx1]};
- return llvm::is_contained(Types, Match);
+ return llvm::is_contained(Types, Match);
};
}
@@ -57,10 +57,10 @@ LegalityPredicate LegalityPredicates::typePairAndMemDescInSet(
TypePairAndMemDesc Match = {Query.Types[TypeIdx0], Query.Types[TypeIdx1],
Query.MMODescrs[MMOIdx].SizeInBits,
Query.MMODescrs[MMOIdx].AlignInBits};
- return llvm::any_of(TypesAndMemDesc,
- [=](const TypePairAndMemDesc &Entry) -> bool {
- return Match.isCompatible(Entry);
- });
+ return llvm::any_of(TypesAndMemDesc,
+ [=](const TypePairAndMemDesc &Entry) -> bool {
+ return Match.isCompatible(Entry);
+ });
};
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalizeMutations.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalizeMutations.cpp
index a5169a9239..f3ba3f0801 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalizeMutations.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalizeMutations.cpp
@@ -43,16 +43,16 @@ LegalizeMutation LegalizeMutations::changeElementTo(unsigned TypeIdx,
};
}
-LegalizeMutation LegalizeMutations::changeElementSizeTo(unsigned TypeIdx,
- unsigned FromTypeIdx) {
- return [=](const LegalityQuery &Query) {
- const LLT OldTy = Query.Types[TypeIdx];
- const LLT NewTy = Query.Types[FromTypeIdx];
- const LLT NewEltTy = LLT::scalar(NewTy.getScalarSizeInBits());
- return std::make_pair(TypeIdx, OldTy.changeElementType(NewEltTy));
- };
-}
-
+LegalizeMutation LegalizeMutations::changeElementSizeTo(unsigned TypeIdx,
+ unsigned FromTypeIdx) {
+ return [=](const LegalityQuery &Query) {
+ const LLT OldTy = Query.Types[TypeIdx];
+ const LLT NewTy = Query.Types[FromTypeIdx];
+ const LLT NewEltTy = LLT::scalar(NewTy.getScalarSizeInBits());
+ return std::make_pair(TypeIdx, OldTy.changeElementType(NewEltTy));
+ };
+}
+
LegalizeMutation LegalizeMutations::widenScalarOrEltToNextPow2(unsigned TypeIdx,
unsigned Min) {
return [=](const LegalityQuery &Query) {
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Legalizer.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Legalizer.cpp
index c0629d955d..5ba9367cac 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Legalizer.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Legalizer.cpp
@@ -284,7 +284,7 @@ Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
WrapperObserver)) {
WorkListObserver.printNewInstrs();
for (auto *DeadMI : DeadInstructions) {
- LLVM_DEBUG(dbgs() << "Is dead: " << *DeadMI);
+ LLVM_DEBUG(dbgs() << "Is dead: " << *DeadMI);
RemoveDeadInstFromLists(DeadMI);
DeadMI->eraseFromParentAndMarkDBGValuesForRemoval();
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 995abb85d0..66871ca3b9 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -16,7 +16,7 @@
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
-#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
+#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
@@ -30,7 +30,7 @@
using namespace llvm;
using namespace LegalizeActions;
-using namespace MIPatternMatch;
+using namespace MIPatternMatch;
/// Try to break down \p OrigTy into \p NarrowTy sized pieces.
///
@@ -77,8 +77,8 @@ static Type *getFloatTypeForLLT(LLVMContext &Ctx, LLT Ty) {
return Type::getFloatTy(Ctx);
case 64:
return Type::getDoubleTy(Ctx);
- case 80:
- return Type::getX86_FP80Ty(Ctx);
+ case 80:
+ return Type::getX86_FP80Ty(Ctx);
case 128:
return Type::getFP128Ty(Ctx);
default:
@@ -90,15 +90,15 @@ LegalizerHelper::LegalizerHelper(MachineFunction &MF,
GISelChangeObserver &Observer,
MachineIRBuilder &Builder)
: MIRBuilder(Builder), Observer(Observer), MRI(MF.getRegInfo()),
- LI(*MF.getSubtarget().getLegalizerInfo()),
- TLI(*MF.getSubtarget().getTargetLowering()) { }
+ LI(*MF.getSubtarget().getLegalizerInfo()),
+ TLI(*MF.getSubtarget().getTargetLowering()) { }
LegalizerHelper::LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
GISelChangeObserver &Observer,
MachineIRBuilder &B)
- : MIRBuilder(B), Observer(Observer), MRI(MF.getRegInfo()), LI(LI),
- TLI(*MF.getSubtarget().getTargetLowering()) { }
-
+ : MIRBuilder(B), Observer(Observer), MRI(MF.getRegInfo()), LI(LI),
+ TLI(*MF.getSubtarget().getTargetLowering()) { }
+
LegalizerHelper::LegalizeResult
LegalizerHelper::legalizeInstrStep(MachineInstr &MI) {
LLVM_DEBUG(dbgs() << "Legalizing: " << MI);
@@ -240,20 +240,20 @@ void LegalizerHelper::insertParts(Register DstReg,
}
}
-/// Append the result registers of G_UNMERGE_VALUES \p MI to \p Regs.
+/// Append the result registers of G_UNMERGE_VALUES \p MI to \p Regs.
static void getUnmergeResults(SmallVectorImpl<Register> &Regs,
const MachineInstr &MI) {
assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
- const int StartIdx = Regs.size();
+ const int StartIdx = Regs.size();
const int NumResults = MI.getNumOperands() - 1;
- Regs.resize(Regs.size() + NumResults);
+ Regs.resize(Regs.size() + NumResults);
for (int I = 0; I != NumResults; ++I)
- Regs[StartIdx + I] = MI.getOperand(I).getReg();
+ Regs[StartIdx + I] = MI.getOperand(I).getReg();
}
-void LegalizerHelper::extractGCDType(SmallVectorImpl<Register> &Parts,
- LLT GCDTy, Register SrcReg) {
+void LegalizerHelper::extractGCDType(SmallVectorImpl<Register> &Parts,
+ LLT GCDTy, Register SrcReg) {
LLT SrcTy = MRI.getType(SrcReg);
if (SrcTy == GCDTy) {
// If the source already evenly divides the result type, we don't need to do
@@ -264,13 +264,13 @@ void LegalizerHelper::extractGCDType(SmallVectorImpl<Register> &Parts,
auto Unmerge = MIRBuilder.buildUnmerge(GCDTy, SrcReg);
getUnmergeResults(Parts, *Unmerge);
}
-}
+}
-LLT LegalizerHelper::extractGCDType(SmallVectorImpl<Register> &Parts, LLT DstTy,
- LLT NarrowTy, Register SrcReg) {
- LLT SrcTy = MRI.getType(SrcReg);
- LLT GCDTy = getGCDType(getGCDType(SrcTy, NarrowTy), DstTy);
- extractGCDType(Parts, GCDTy, SrcReg);
+LLT LegalizerHelper::extractGCDType(SmallVectorImpl<Register> &Parts, LLT DstTy,
+ LLT NarrowTy, Register SrcReg) {
+ LLT SrcTy = MRI.getType(SrcReg);
+ LLT GCDTy = getGCDType(getGCDType(SrcTy, NarrowTy), DstTy);
+ extractGCDType(Parts, GCDTy, SrcReg);
return GCDTy;
}
@@ -384,14 +384,14 @@ void LegalizerHelper::buildWidenedRemergeToDst(Register DstReg, LLT LCMTy,
}
if (LCMTy.isVector()) {
- unsigned NumDefs = LCMTy.getSizeInBits() / DstTy.getSizeInBits();
- SmallVector<Register, 8> UnmergeDefs(NumDefs);
- UnmergeDefs[0] = DstReg;
- for (unsigned I = 1; I != NumDefs; ++I)
- UnmergeDefs[I] = MRI.createGenericVirtualRegister(DstTy);
-
- MIRBuilder.buildUnmerge(UnmergeDefs,
- MIRBuilder.buildMerge(LCMTy, RemergeRegs));
+ unsigned NumDefs = LCMTy.getSizeInBits() / DstTy.getSizeInBits();
+ SmallVector<Register, 8> UnmergeDefs(NumDefs);
+ UnmergeDefs[0] = DstReg;
+ for (unsigned I = 1; I != NumDefs; ++I)
+ UnmergeDefs[I] = MRI.createGenericVirtualRegister(DstTy);
+
+ MIRBuilder.buildUnmerge(UnmergeDefs,
+ MIRBuilder.buildMerge(LCMTy, RemergeRegs));
return;
}
@@ -399,20 +399,20 @@ void LegalizerHelper::buildWidenedRemergeToDst(Register DstReg, LLT LCMTy,
}
static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size) {
-#define RTLIBCASE_INT(LibcallPrefix) \
- do { \
- switch (Size) { \
- case 32: \
- return RTLIB::LibcallPrefix##32; \
- case 64: \
- return RTLIB::LibcallPrefix##64; \
- case 128: \
- return RTLIB::LibcallPrefix##128; \
- default: \
- llvm_unreachable("unexpected size"); \
- } \
- } while (0)
-
+#define RTLIBCASE_INT(LibcallPrefix) \
+ do { \
+ switch (Size) { \
+ case 32: \
+ return RTLIB::LibcallPrefix##32; \
+ case 64: \
+ return RTLIB::LibcallPrefix##64; \
+ case 128: \
+ return RTLIB::LibcallPrefix##128; \
+ default: \
+ llvm_unreachable("unexpected size"); \
+ } \
+ } while (0)
+
#define RTLIBCASE(LibcallPrefix) \
do { \
switch (Size) { \
@@ -420,8 +420,8 @@ static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size) {
return RTLIB::LibcallPrefix##32; \
case 64: \
return RTLIB::LibcallPrefix##64; \
- case 80: \
- return RTLIB::LibcallPrefix##80; \
+ case 80: \
+ return RTLIB::LibcallPrefix##80; \
case 128: \
return RTLIB::LibcallPrefix##128; \
default: \
@@ -431,15 +431,15 @@ static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size) {
switch (Opcode) {
case TargetOpcode::G_SDIV:
- RTLIBCASE_INT(SDIV_I);
+ RTLIBCASE_INT(SDIV_I);
case TargetOpcode::G_UDIV:
- RTLIBCASE_INT(UDIV_I);
+ RTLIBCASE_INT(UDIV_I);
case TargetOpcode::G_SREM:
- RTLIBCASE_INT(SREM_I);
+ RTLIBCASE_INT(SREM_I);
case TargetOpcode::G_UREM:
- RTLIBCASE_INT(UREM_I);
+ RTLIBCASE_INT(UREM_I);
case TargetOpcode::G_CTLZ_ZERO_UNDEF:
- RTLIBCASE_INT(CTLZ_I);
+ RTLIBCASE_INT(CTLZ_I);
case TargetOpcode::G_FADD:
RTLIBCASE(ADD_F);
case TargetOpcode::G_FSUB:
@@ -482,16 +482,16 @@ static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size) {
RTLIBCASE(RINT_F);
case TargetOpcode::G_FNEARBYINT:
RTLIBCASE(NEARBYINT_F);
- case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
- RTLIBCASE(ROUNDEVEN_F);
+ case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
+ RTLIBCASE(ROUNDEVEN_F);
}
llvm_unreachable("Unknown libcall function");
}
/// True if an instruction is in tail position in its caller. Intended for
/// legalizing libcalls as tail calls when possible.
-static bool isLibCallInTailPosition(const TargetInstrInfo &TII,
- MachineInstr &MI) {
+static bool isLibCallInTailPosition(const TargetInstrInfo &TII,
+ MachineInstr &MI) {
MachineBasicBlock &MBB = *MI.getParent();
const Function &F = MBB.getParent()->getFunction();
@@ -566,7 +566,7 @@ llvm::createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
SmallVector<CallLowering::ArgInfo, 3> Args;
// Add all the args, except for the last which is an imm denoting 'tail'.
- for (unsigned i = 0; i < MI.getNumOperands() - 1; ++i) {
+ for (unsigned i = 0; i < MI.getNumOperands() - 1; ++i) {
Register Reg = MI.getOperand(i).getReg();
// Need derive an IR type for call lowering.
@@ -582,14 +582,14 @@ llvm::createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering();
auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
RTLIB::Libcall RTLibcall;
- switch (MI.getOpcode()) {
- case TargetOpcode::G_MEMCPY:
+ switch (MI.getOpcode()) {
+ case TargetOpcode::G_MEMCPY:
RTLibcall = RTLIB::MEMCPY;
break;
- case TargetOpcode::G_MEMMOVE:
- RTLibcall = RTLIB::MEMMOVE;
- break;
- case TargetOpcode::G_MEMSET:
+ case TargetOpcode::G_MEMMOVE:
+ RTLibcall = RTLIB::MEMMOVE;
+ break;
+ case TargetOpcode::G_MEMSET:
RTLibcall = RTLIB::MEMSET;
break;
default:
@@ -601,8 +601,8 @@ llvm::createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
Info.CallConv = TLI.getLibcallCallingConv(RTLibcall);
Info.Callee = MachineOperand::CreateES(Name);
Info.OrigRet = CallLowering::ArgInfo({0}, Type::getVoidTy(Ctx));
- Info.IsTailCall = MI.getOperand(MI.getNumOperands() - 1).getImm() &&
- isLibCallInTailPosition(MIRBuilder.getTII(), MI);
+ Info.IsTailCall = MI.getOperand(MI.getNumOperands() - 1).getImm() &&
+ isLibCallInTailPosition(MIRBuilder.getTII(), MI);
std::copy(Args.begin(), Args.end(), std::back_inserter(Info.OrigArgs));
if (!CLI.lowerCall(MIRBuilder, Info))
@@ -695,11 +695,11 @@ LegalizerHelper::libcall(MachineInstr &MI) {
case TargetOpcode::G_FMAXNUM:
case TargetOpcode::G_FSQRT:
case TargetOpcode::G_FRINT:
- case TargetOpcode::G_FNEARBYINT:
- case TargetOpcode::G_INTRINSIC_ROUNDEVEN: {
+ case TargetOpcode::G_FNEARBYINT:
+ case TargetOpcode::G_INTRINSIC_ROUNDEVEN: {
Type *HLTy = getFloatTypeForLLT(Ctx, LLTy);
- if (!HLTy || (Size != 32 && Size != 64 && Size != 80 && Size != 128)) {
- LLVM_DEBUG(dbgs() << "No libcall available for type " << LLTy << ".\n");
+ if (!HLTy || (Size != 32 && Size != 64 && Size != 80 && Size != 128)) {
+ LLVM_DEBUG(dbgs() << "No libcall available for type " << LLTy << ".\n");
return UnableToLegalize;
}
auto Status = simpleLibcall(MI, MIRBuilder, Size, HLTy);
@@ -748,14 +748,14 @@ LegalizerHelper::libcall(MachineInstr &MI) {
return Status;
break;
}
- case TargetOpcode::G_MEMCPY:
- case TargetOpcode::G_MEMMOVE:
- case TargetOpcode::G_MEMSET: {
- LegalizeResult Result = createMemLibcall(MIRBuilder, *MIRBuilder.getMRI(), MI);
- MI.eraseFromParent();
- return Result;
+ case TargetOpcode::G_MEMCPY:
+ case TargetOpcode::G_MEMMOVE:
+ case TargetOpcode::G_MEMSET: {
+ LegalizeResult Result = createMemLibcall(MIRBuilder, *MIRBuilder.getMRI(), MI);
+ MI.eraseFromParent();
+ return Result;
+ }
}
- }
MI.eraseFromParent();
return Legalized;
@@ -935,7 +935,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
case TargetOpcode::G_INSERT:
return narrowScalarInsert(MI, TypeIdx, NarrowTy);
case TargetOpcode::G_LOAD: {
- auto &MMO = **MI.memoperands_begin();
+ auto &MMO = **MI.memoperands_begin();
Register DstReg = MI.getOperand(0).getReg();
LLT DstTy = MRI.getType(DstReg);
if (DstTy.isVector())
@@ -959,15 +959,15 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
Register TmpReg = MRI.createGenericVirtualRegister(NarrowTy);
auto &MMO = **MI.memoperands_begin();
- unsigned MemSize = MMO.getSizeInBits();
-
- if (MemSize == NarrowSize) {
+ unsigned MemSize = MMO.getSizeInBits();
+
+ if (MemSize == NarrowSize) {
MIRBuilder.buildLoad(TmpReg, PtrReg, MMO);
- } else if (MemSize < NarrowSize) {
+ } else if (MemSize < NarrowSize) {
MIRBuilder.buildLoadInstr(MI.getOpcode(), TmpReg, PtrReg, MMO);
- } else if (MemSize > NarrowSize) {
- // FIXME: Need to split the load.
- return UnableToLegalize;
+ } else if (MemSize > NarrowSize) {
+ // FIXME: Need to split the load.
+ return UnableToLegalize;
}
if (ZExt)
@@ -1063,11 +1063,11 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
Observer.changedInstr(MI);
return Legalized;
case TargetOpcode::G_PHI: {
- // FIXME: add support for when SizeOp0 isn't an exact multiple of
- // NarrowSize.
- if (SizeOp0 % NarrowSize != 0)
- return UnableToLegalize;
-
+ // FIXME: add support for when SizeOp0 isn't an exact multiple of
+ // NarrowSize.
+ if (SizeOp0 % NarrowSize != 0)
+ return UnableToLegalize;
+
unsigned NumParts = SizeOp0 / NarrowSize;
SmallVector<Register, 2> DstRegs(NumParts);
SmallVector<SmallVector<Register, 2>, 2> SrcRegs(MI.getNumOperands() / 2);
@@ -1248,7 +1248,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
MI.eraseFromParent();
return Legalized;
}
- case TargetOpcode::G_PTR_ADD:
+ case TargetOpcode::G_PTR_ADD:
case TargetOpcode::G_PTRMASK: {
if (TypeIdx != 1)
return UnableToLegalize;
@@ -1257,17 +1257,17 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
Observer.changedInstr(MI);
return Legalized;
}
- case TargetOpcode::G_FPTOUI:
- case TargetOpcode::G_FPTOSI:
- return narrowScalarFPTOI(MI, TypeIdx, NarrowTy);
- case TargetOpcode::G_FPEXT:
- if (TypeIdx != 0)
- return UnableToLegalize;
- Observer.changingInstr(MI);
- narrowScalarDst(MI, NarrowTy, 0, TargetOpcode::G_FPEXT);
- Observer.changedInstr(MI);
- return Legalized;
- }
+ case TargetOpcode::G_FPTOUI:
+ case TargetOpcode::G_FPTOSI:
+ return narrowScalarFPTOI(MI, TypeIdx, NarrowTy);
+ case TargetOpcode::G_FPEXT:
+ if (TypeIdx != 0)
+ return UnableToLegalize;
+ Observer.changingInstr(MI);
+ narrowScalarDst(MI, NarrowTy, 0, TargetOpcode::G_FPEXT);
+ Observer.changedInstr(MI);
+ return Legalized;
+ }
}
Register LegalizerHelper::coerceToScalar(Register Val) {
@@ -1328,7 +1328,7 @@ void LegalizerHelper::moreElementsVectorDst(MachineInstr &MI, LLT WideTy,
unsigned OpIdx) {
MachineOperand &MO = MI.getOperand(OpIdx);
MIRBuilder.setInsertPt(MIRBuilder.getMBB(), ++MIRBuilder.getInsertPt());
- MO.setReg(widenWithUnmerge(WideTy, MO.getReg()));
+ MO.setReg(widenWithUnmerge(WideTy, MO.getReg()));
}
void LegalizerHelper::moreElementsVectorSrc(MachineInstr &MI, LLT MoreTy,
@@ -1496,40 +1496,40 @@ LegalizerHelper::widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx,
return Legalized;
}
-Register LegalizerHelper::widenWithUnmerge(LLT WideTy, Register OrigReg) {
- Register WideReg = MRI.createGenericVirtualRegister(WideTy);
- LLT OrigTy = MRI.getType(OrigReg);
- LLT LCMTy = getLCMType(WideTy, OrigTy);
-
- const int NumMergeParts = LCMTy.getSizeInBits() / WideTy.getSizeInBits();
- const int NumUnmergeParts = LCMTy.getSizeInBits() / OrigTy.getSizeInBits();
-
- Register UnmergeSrc = WideReg;
-
- // Create a merge to the LCM type, padding with undef
- // %0:_(<3 x s32>) = G_FOO => <4 x s32>
- // =>
- // %1:_(<4 x s32>) = G_FOO
- // %2:_(<4 x s32>) = G_IMPLICIT_DEF
- // %3:_(<12 x s32>) = G_CONCAT_VECTORS %1, %2, %2
- // %0:_(<3 x s32>), %4:_, %5:_, %6:_ = G_UNMERGE_VALUES %3
- if (NumMergeParts > 1) {
- Register Undef = MIRBuilder.buildUndef(WideTy).getReg(0);
- SmallVector<Register, 8> MergeParts(NumMergeParts, Undef);
- MergeParts[0] = WideReg;
- UnmergeSrc = MIRBuilder.buildMerge(LCMTy, MergeParts).getReg(0);
- }
-
- // Unmerge to the original register and pad with dead defs.
- SmallVector<Register, 8> UnmergeResults(NumUnmergeParts);
- UnmergeResults[0] = OrigReg;
- for (int I = 1; I != NumUnmergeParts; ++I)
- UnmergeResults[I] = MRI.createGenericVirtualRegister(OrigTy);
-
- MIRBuilder.buildUnmerge(UnmergeResults, UnmergeSrc);
- return WideReg;
-}
-
+Register LegalizerHelper::widenWithUnmerge(LLT WideTy, Register OrigReg) {
+ Register WideReg = MRI.createGenericVirtualRegister(WideTy);
+ LLT OrigTy = MRI.getType(OrigReg);
+ LLT LCMTy = getLCMType(WideTy, OrigTy);
+
+ const int NumMergeParts = LCMTy.getSizeInBits() / WideTy.getSizeInBits();
+ const int NumUnmergeParts = LCMTy.getSizeInBits() / OrigTy.getSizeInBits();
+
+ Register UnmergeSrc = WideReg;
+
+ // Create a merge to the LCM type, padding with undef
+ // %0:_(<3 x s32>) = G_FOO => <4 x s32>
+ // =>
+ // %1:_(<4 x s32>) = G_FOO
+ // %2:_(<4 x s32>) = G_IMPLICIT_DEF
+ // %3:_(<12 x s32>) = G_CONCAT_VECTORS %1, %2, %2
+ // %0:_(<3 x s32>), %4:_, %5:_, %6:_ = G_UNMERGE_VALUES %3
+ if (NumMergeParts > 1) {
+ Register Undef = MIRBuilder.buildUndef(WideTy).getReg(0);
+ SmallVector<Register, 8> MergeParts(NumMergeParts, Undef);
+ MergeParts[0] = WideReg;
+ UnmergeSrc = MIRBuilder.buildMerge(LCMTy, MergeParts).getReg(0);
+ }
+
+ // Unmerge to the original register and pad with dead defs.
+ SmallVector<Register, 8> UnmergeResults(NumUnmergeParts);
+ UnmergeResults[0] = OrigReg;
+ for (int I = 1; I != NumUnmergeParts; ++I)
+ UnmergeResults[I] = MRI.createGenericVirtualRegister(OrigTy);
+
+ MIRBuilder.buildUnmerge(UnmergeResults, UnmergeSrc);
+ return WideReg;
+}
+
LegalizerHelper::LegalizeResult
LegalizerHelper::widenScalarUnmergeValues(MachineInstr &MI, unsigned TypeIdx,
LLT WideTy) {
@@ -1599,60 +1599,60 @@ LegalizerHelper::widenScalarUnmergeValues(MachineInstr &MI, unsigned TypeIdx,
auto Unmerge = MIRBuilder.buildUnmerge(WideTy, WideSrc);
- // Create a sequence of unmerges and merges to the original results. Since we
- // may have widened the source, we will need to pad the results with dead defs
- // to cover the source register.
- // e.g. widen s48 to s64:
- // %1:_(s48), %2:_(s48) = G_UNMERGE_VALUES %0:_(s96)
+ // Create a sequence of unmerges and merges to the original results. Since we
+ // may have widened the source, we will need to pad the results with dead defs
+ // to cover the source register.
+ // e.g. widen s48 to s64:
+ // %1:_(s48), %2:_(s48) = G_UNMERGE_VALUES %0:_(s96)
//
// =>
- // %4:_(s192) = G_ANYEXT %0:_(s96)
- // %5:_(s64), %6, %7 = G_UNMERGE_VALUES %4 ; Requested unmerge
- // ; unpack to GCD type, with extra dead defs
- // %8:_(s16), %9, %10, %11 = G_UNMERGE_VALUES %5:_(s64)
- // %12:_(s16), %13, dead %14, dead %15 = G_UNMERGE_VALUES %6:_(s64)
- // dead %16:_(s16), dead %17, dead %18, dead %18 = G_UNMERGE_VALUES %7:_(s64)
- // %1:_(s48) = G_MERGE_VALUES %8:_(s16), %9, %10 ; Remerge to destination
- // %2:_(s48) = G_MERGE_VALUES %11:_(s16), %12, %13 ; Remerge to destination
- const LLT GCDTy = getGCDType(WideTy, DstTy);
+ // %4:_(s192) = G_ANYEXT %0:_(s96)
+ // %5:_(s64), %6, %7 = G_UNMERGE_VALUES %4 ; Requested unmerge
+ // ; unpack to GCD type, with extra dead defs
+ // %8:_(s16), %9, %10, %11 = G_UNMERGE_VALUES %5:_(s64)
+ // %12:_(s16), %13, dead %14, dead %15 = G_UNMERGE_VALUES %6:_(s64)
+ // dead %16:_(s16), dead %17, dead %18, dead %18 = G_UNMERGE_VALUES %7:_(s64)
+ // %1:_(s48) = G_MERGE_VALUES %8:_(s16), %9, %10 ; Remerge to destination
+ // %2:_(s48) = G_MERGE_VALUES %11:_(s16), %12, %13 ; Remerge to destination
+ const LLT GCDTy = getGCDType(WideTy, DstTy);
const int NumUnmerge = Unmerge->getNumOperands() - 1;
- const int PartsPerRemerge = DstTy.getSizeInBits() / GCDTy.getSizeInBits();
-
- // Directly unmerge to the destination without going through a GCD type
- // if possible
- if (PartsPerRemerge == 1) {
- const int PartsPerUnmerge = WideTy.getSizeInBits() / DstTy.getSizeInBits();
-
- for (int I = 0; I != NumUnmerge; ++I) {
- auto MIB = MIRBuilder.buildInstr(TargetOpcode::G_UNMERGE_VALUES);
-
- for (int J = 0; J != PartsPerUnmerge; ++J) {
- int Idx = I * PartsPerUnmerge + J;
- if (Idx < NumDst)
- MIB.addDef(MI.getOperand(Idx).getReg());
- else {
- // Create dead def for excess components.
- MIB.addDef(MRI.createGenericVirtualRegister(DstTy));
- }
+ const int PartsPerRemerge = DstTy.getSizeInBits() / GCDTy.getSizeInBits();
+
+ // Directly unmerge to the destination without going through a GCD type
+ // if possible
+ if (PartsPerRemerge == 1) {
+ const int PartsPerUnmerge = WideTy.getSizeInBits() / DstTy.getSizeInBits();
+
+ for (int I = 0; I != NumUnmerge; ++I) {
+ auto MIB = MIRBuilder.buildInstr(TargetOpcode::G_UNMERGE_VALUES);
+
+ for (int J = 0; J != PartsPerUnmerge; ++J) {
+ int Idx = I * PartsPerUnmerge + J;
+ if (Idx < NumDst)
+ MIB.addDef(MI.getOperand(Idx).getReg());
+ else {
+ // Create dead def for excess components.
+ MIB.addDef(MRI.createGenericVirtualRegister(DstTy));
+ }
}
-
- MIB.addUse(Unmerge.getReg(I));
+
+ MIB.addUse(Unmerge.getReg(I));
+ }
+ } else {
+ SmallVector<Register, 16> Parts;
+ for (int J = 0; J != NumUnmerge; ++J)
+ extractGCDType(Parts, GCDTy, Unmerge.getReg(J));
+
+ SmallVector<Register, 8> RemergeParts;
+ for (int I = 0; I != NumDst; ++I) {
+ for (int J = 0; J < PartsPerRemerge; ++J) {
+ const int Idx = I * PartsPerRemerge + J;
+ RemergeParts.emplace_back(Parts[Idx]);
+ }
+
+ MIRBuilder.buildMerge(MI.getOperand(I).getReg(), RemergeParts);
+ RemergeParts.clear();
}
- } else {
- SmallVector<Register, 16> Parts;
- for (int J = 0; J != NumUnmerge; ++J)
- extractGCDType(Parts, GCDTy, Unmerge.getReg(J));
-
- SmallVector<Register, 8> RemergeParts;
- for (int I = 0; I != NumDst; ++I) {
- for (int J = 0; J < PartsPerRemerge; ++J) {
- const int Idx = I * PartsPerRemerge + J;
- RemergeParts.emplace_back(Parts[Idx]);
- }
-
- MIRBuilder.buildMerge(MI.getOperand(I).getReg(), RemergeParts);
- RemergeParts.clear();
- }
}
MI.eraseFromParent();
@@ -1702,7 +1702,7 @@ LegalizerHelper::widenScalarExtract(MachineInstr &MI, unsigned TypeIdx,
if (WideTy.getSizeInBits() > SrcTy.getSizeInBits()) {
Src = MIRBuilder.buildAnyExt(WideTy, Src);
ShiftTy = WideTy;
- }
+ }
auto LShr = MIRBuilder.buildLShr(
ShiftTy, Src, MIRBuilder.buildConstant(ShiftTy, Offset));
@@ -1740,7 +1740,7 @@ LegalizerHelper::widenScalarExtract(MachineInstr &MI, unsigned TypeIdx,
LegalizerHelper::LegalizeResult
LegalizerHelper::widenScalarInsert(MachineInstr &MI, unsigned TypeIdx,
LLT WideTy) {
- if (TypeIdx != 0 || WideTy.isVector())
+ if (TypeIdx != 0 || WideTy.isVector())
return UnableToLegalize;
Observer.changingInstr(MI);
widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
@@ -1750,45 +1750,45 @@ LegalizerHelper::widenScalarInsert(MachineInstr &MI, unsigned TypeIdx,
}
LegalizerHelper::LegalizeResult
-LegalizerHelper::widenScalarAddoSubo(MachineInstr &MI, unsigned TypeIdx,
- LLT WideTy) {
- if (TypeIdx == 1)
- return UnableToLegalize; // TODO
- unsigned Op = MI.getOpcode();
- unsigned Opcode = Op == TargetOpcode::G_UADDO || Op == TargetOpcode::G_SADDO
- ? TargetOpcode::G_ADD
- : TargetOpcode::G_SUB;
- unsigned ExtOpcode =
- Op == TargetOpcode::G_UADDO || Op == TargetOpcode::G_USUBO
- ? TargetOpcode::G_ZEXT
- : TargetOpcode::G_SEXT;
- auto LHSExt = MIRBuilder.buildInstr(ExtOpcode, {WideTy}, {MI.getOperand(2)});
- auto RHSExt = MIRBuilder.buildInstr(ExtOpcode, {WideTy}, {MI.getOperand(3)});
- // Do the arithmetic in the larger type.
- auto NewOp = MIRBuilder.buildInstr(Opcode, {WideTy}, {LHSExt, RHSExt});
- LLT OrigTy = MRI.getType(MI.getOperand(0).getReg());
- auto TruncOp = MIRBuilder.buildTrunc(OrigTy, NewOp);
- auto ExtOp = MIRBuilder.buildInstr(ExtOpcode, {WideTy}, {TruncOp});
- // There is no overflow if the ExtOp is the same as NewOp.
- MIRBuilder.buildICmp(CmpInst::ICMP_NE, MI.getOperand(1), NewOp, ExtOp);
- // Now trunc the NewOp to the original result.
- MIRBuilder.buildTrunc(MI.getOperand(0), NewOp);
- MI.eraseFromParent();
- return Legalized;
-}
-
-LegalizerHelper::LegalizeResult
-LegalizerHelper::widenScalarAddSubShlSat(MachineInstr &MI, unsigned TypeIdx,
- LLT WideTy) {
+LegalizerHelper::widenScalarAddoSubo(MachineInstr &MI, unsigned TypeIdx,
+ LLT WideTy) {
+ if (TypeIdx == 1)
+ return UnableToLegalize; // TODO
+ unsigned Op = MI.getOpcode();
+ unsigned Opcode = Op == TargetOpcode::G_UADDO || Op == TargetOpcode::G_SADDO
+ ? TargetOpcode::G_ADD
+ : TargetOpcode::G_SUB;
+ unsigned ExtOpcode =
+ Op == TargetOpcode::G_UADDO || Op == TargetOpcode::G_USUBO
+ ? TargetOpcode::G_ZEXT
+ : TargetOpcode::G_SEXT;
+ auto LHSExt = MIRBuilder.buildInstr(ExtOpcode, {WideTy}, {MI.getOperand(2)});
+ auto RHSExt = MIRBuilder.buildInstr(ExtOpcode, {WideTy}, {MI.getOperand(3)});
+ // Do the arithmetic in the larger type.
+ auto NewOp = MIRBuilder.buildInstr(Opcode, {WideTy}, {LHSExt, RHSExt});
+ LLT OrigTy = MRI.getType(MI.getOperand(0).getReg());
+ auto TruncOp = MIRBuilder.buildTrunc(OrigTy, NewOp);
+ auto ExtOp = MIRBuilder.buildInstr(ExtOpcode, {WideTy}, {TruncOp});
+ // There is no overflow if the ExtOp is the same as NewOp.
+ MIRBuilder.buildICmp(CmpInst::ICMP_NE, MI.getOperand(1), NewOp, ExtOp);
+ // Now trunc the NewOp to the original result.
+ MIRBuilder.buildTrunc(MI.getOperand(0), NewOp);
+ MI.eraseFromParent();
+ return Legalized;
+}
+
+LegalizerHelper::LegalizeResult
+LegalizerHelper::widenScalarAddSubShlSat(MachineInstr &MI, unsigned TypeIdx,
+ LLT WideTy) {
bool IsSigned = MI.getOpcode() == TargetOpcode::G_SADDSAT ||
- MI.getOpcode() == TargetOpcode::G_SSUBSAT ||
- MI.getOpcode() == TargetOpcode::G_SSHLSAT;
- bool IsShift = MI.getOpcode() == TargetOpcode::G_SSHLSAT ||
- MI.getOpcode() == TargetOpcode::G_USHLSAT;
+ MI.getOpcode() == TargetOpcode::G_SSUBSAT ||
+ MI.getOpcode() == TargetOpcode::G_SSHLSAT;
+ bool IsShift = MI.getOpcode() == TargetOpcode::G_SSHLSAT ||
+ MI.getOpcode() == TargetOpcode::G_USHLSAT;
// We can convert this to:
// 1. Any extend iN to iM
// 2. SHL by M-N
- // 3. [US][ADD|SUB|SHL]SAT
+ // 3. [US][ADD|SUB|SHL]SAT
// 4. L/ASHR by M-N
//
// It may be more efficient to lower this to a min and a max operation in
@@ -1799,14 +1799,14 @@ LegalizerHelper::widenScalarAddSubShlSat(MachineInstr &MI, unsigned TypeIdx,
unsigned NewBits = WideTy.getScalarSizeInBits();
unsigned SHLAmount = NewBits - MRI.getType(DstReg).getScalarSizeInBits();
- // Shifts must zero-extend the RHS to preserve the unsigned quantity, and
- // must not left shift the RHS to preserve the shift amount.
+ // Shifts must zero-extend the RHS to preserve the unsigned quantity, and
+ // must not left shift the RHS to preserve the shift amount.
auto LHS = MIRBuilder.buildAnyExt(WideTy, MI.getOperand(1));
- auto RHS = IsShift ? MIRBuilder.buildZExt(WideTy, MI.getOperand(2))
- : MIRBuilder.buildAnyExt(WideTy, MI.getOperand(2));
+ auto RHS = IsShift ? MIRBuilder.buildZExt(WideTy, MI.getOperand(2))
+ : MIRBuilder.buildAnyExt(WideTy, MI.getOperand(2));
auto ShiftK = MIRBuilder.buildConstant(WideTy, SHLAmount);
auto ShiftL = MIRBuilder.buildShl(WideTy, LHS, ShiftK);
- auto ShiftR = IsShift ? RHS : MIRBuilder.buildShl(WideTy, RHS, ShiftK);
+ auto ShiftR = IsShift ? RHS : MIRBuilder.buildShl(WideTy, RHS, ShiftK);
auto WideInst = MIRBuilder.buildInstr(MI.getOpcode(), {WideTy},
{ShiftL, ShiftR}, MI.getFlags());
@@ -1834,18 +1834,18 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
return widenScalarMergeValues(MI, TypeIdx, WideTy);
case TargetOpcode::G_UNMERGE_VALUES:
return widenScalarUnmergeValues(MI, TypeIdx, WideTy);
- case TargetOpcode::G_SADDO:
- case TargetOpcode::G_SSUBO:
+ case TargetOpcode::G_SADDO:
+ case TargetOpcode::G_SSUBO:
case TargetOpcode::G_UADDO:
- case TargetOpcode::G_USUBO:
- return widenScalarAddoSubo(MI, TypeIdx, WideTy);
+ case TargetOpcode::G_USUBO:
+ return widenScalarAddoSubo(MI, TypeIdx, WideTy);
case TargetOpcode::G_SADDSAT:
case TargetOpcode::G_SSUBSAT:
- case TargetOpcode::G_SSHLSAT:
+ case TargetOpcode::G_SSHLSAT:
case TargetOpcode::G_UADDSAT:
case TargetOpcode::G_USUBSAT:
- case TargetOpcode::G_USHLSAT:
- return widenScalarAddSubShlSat(MI, TypeIdx, WideTy);
+ case TargetOpcode::G_USHLSAT:
+ return widenScalarAddSubShlSat(MI, TypeIdx, WideTy);
case TargetOpcode::G_CTTZ:
case TargetOpcode::G_CTTZ_ZERO_UNDEF:
case TargetOpcode::G_CTLZ:
@@ -2038,22 +2038,22 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
return Legalized;
case TargetOpcode::G_SITOFP:
Observer.changingInstr(MI);
-
- if (TypeIdx == 0)
- widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
- else
- widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_SEXT);
-
+
+ if (TypeIdx == 0)
+ widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
+ else
+ widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_SEXT);
+
Observer.changedInstr(MI);
return Legalized;
case TargetOpcode::G_UITOFP:
Observer.changingInstr(MI);
-
- if (TypeIdx == 0)
- widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
- else
- widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT);
-
+
+ if (TypeIdx == 0)
+ widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
+ else
+ widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT);
+
Observer.changedInstr(MI);
return Legalized;
case TargetOpcode::G_LOAD:
@@ -2069,7 +2069,7 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
return UnableToLegalize;
LLT Ty = MRI.getType(MI.getOperand(0).getReg());
- if (!Ty.isScalar())
+ if (!Ty.isScalar())
return UnableToLegalize;
Observer.changingInstr(MI);
@@ -2267,7 +2267,7 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
case TargetOpcode::G_FPOW:
case TargetOpcode::G_INTRINSIC_TRUNC:
case TargetOpcode::G_INTRINSIC_ROUND:
- case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
+ case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
assert(TypeIdx == 0);
Observer.changingInstr(MI);
@@ -2277,15 +2277,15 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
Observer.changedInstr(MI);
return Legalized;
- case TargetOpcode::G_FPOWI: {
- if (TypeIdx != 0)
- return UnableToLegalize;
- Observer.changingInstr(MI);
- widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_FPEXT);
- widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
- Observer.changedInstr(MI);
- return Legalized;
- }
+ case TargetOpcode::G_FPOWI: {
+ if (TypeIdx != 0)
+ return UnableToLegalize;
+ Observer.changingInstr(MI);
+ widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_FPEXT);
+ widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
+ Observer.changedInstr(MI);
+ return Legalized;
+ }
case TargetOpcode::G_INTTOPTR:
if (TypeIdx != 1)
return UnableToLegalize;
@@ -2312,7 +2312,7 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
// Avoid changing the result vector type if the source element type was
// requested.
if (TypeIdx == 1) {
- MI.setDesc(MIRBuilder.getTII().get(TargetOpcode::G_BUILD_VECTOR_TRUNC));
+ MI.setDesc(MIRBuilder.getTII().get(TargetOpcode::G_BUILD_VECTOR_TRUNC));
} else {
widenScalarDst(MI, WideTy, 0);
}
@@ -2415,377 +2415,377 @@ LegalizerHelper::lowerBitcast(MachineInstr &MI) {
return UnableToLegalize;
}
-/// Figure out the bit offset into a register when coercing a vector index for
-/// the wide element type. This is only for the case when promoting vector to
-/// one with larger elements.
-//
-///
-/// %offset_idx = G_AND %idx, ~(-1 << Log2(DstEltSize / SrcEltSize))
-/// %offset_bits = G_SHL %offset_idx, Log2(SrcEltSize)
-static Register getBitcastWiderVectorElementOffset(MachineIRBuilder &B,
- Register Idx,
- unsigned NewEltSize,
- unsigned OldEltSize) {
- const unsigned Log2EltRatio = Log2_32(NewEltSize / OldEltSize);
- LLT IdxTy = B.getMRI()->getType(Idx);
-
- // Now figure out the amount we need to shift to get the target bits.
- auto OffsetMask = B.buildConstant(
- IdxTy, ~(APInt::getAllOnesValue(IdxTy.getSizeInBits()) << Log2EltRatio));
- auto OffsetIdx = B.buildAnd(IdxTy, Idx, OffsetMask);
- return B.buildShl(IdxTy, OffsetIdx,
- B.buildConstant(IdxTy, Log2_32(OldEltSize))).getReg(0);
-}
-
-/// Perform a G_EXTRACT_VECTOR_ELT in a different sized vector element. If this
-/// is casting to a vector with a smaller element size, perform multiple element
-/// extracts and merge the results. If this is coercing to a vector with larger
-/// elements, index the bitcasted vector and extract the target element with bit
-/// operations. This is intended to force the indexing in the native register
-/// size for architectures that can dynamically index the register file.
+/// Figure out the bit offset into a register when coercing a vector index for
+/// the wide element type. This is only for the case when promoting vector to
+/// one with larger elements.
+//
+///
+/// %offset_idx = G_AND %idx, ~(-1 << Log2(DstEltSize / SrcEltSize))
+/// %offset_bits = G_SHL %offset_idx, Log2(SrcEltSize)
+static Register getBitcastWiderVectorElementOffset(MachineIRBuilder &B,
+ Register Idx,
+ unsigned NewEltSize,
+ unsigned OldEltSize) {
+ const unsigned Log2EltRatio = Log2_32(NewEltSize / OldEltSize);
+ LLT IdxTy = B.getMRI()->getType(Idx);
+
+ // Now figure out the amount we need to shift to get the target bits.
+ auto OffsetMask = B.buildConstant(
+ IdxTy, ~(APInt::getAllOnesValue(IdxTy.getSizeInBits()) << Log2EltRatio));
+ auto OffsetIdx = B.buildAnd(IdxTy, Idx, OffsetMask);
+ return B.buildShl(IdxTy, OffsetIdx,
+ B.buildConstant(IdxTy, Log2_32(OldEltSize))).getReg(0);
+}
+
+/// Perform a G_EXTRACT_VECTOR_ELT in a different sized vector element. If this
+/// is casting to a vector with a smaller element size, perform multiple element
+/// extracts and merge the results. If this is coercing to a vector with larger
+/// elements, index the bitcasted vector and extract the target element with bit
+/// operations. This is intended to force the indexing in the native register
+/// size for architectures that can dynamically index the register file.
+LegalizerHelper::LegalizeResult
+LegalizerHelper::bitcastExtractVectorElt(MachineInstr &MI, unsigned TypeIdx,
+ LLT CastTy) {
+ if (TypeIdx != 1)
+ return UnableToLegalize;
+
+ Register Dst = MI.getOperand(0).getReg();
+ Register SrcVec = MI.getOperand(1).getReg();
+ Register Idx = MI.getOperand(2).getReg();
+ LLT SrcVecTy = MRI.getType(SrcVec);
+ LLT IdxTy = MRI.getType(Idx);
+
+ LLT SrcEltTy = SrcVecTy.getElementType();
+ unsigned NewNumElts = CastTy.isVector() ? CastTy.getNumElements() : 1;
+ unsigned OldNumElts = SrcVecTy.getNumElements();
+
+ LLT NewEltTy = CastTy.isVector() ? CastTy.getElementType() : CastTy;
+ Register CastVec = MIRBuilder.buildBitcast(CastTy, SrcVec).getReg(0);
+
+ const unsigned NewEltSize = NewEltTy.getSizeInBits();
+ const unsigned OldEltSize = SrcEltTy.getSizeInBits();
+ if (NewNumElts > OldNumElts) {
+ // Decreasing the vector element size
+ //
+ // e.g. i64 = extract_vector_elt x:v2i64, y:i32
+ // =>
+ // v4i32:castx = bitcast x:v2i64
+ //
+ // i64 = bitcast
+ // (v2i32 build_vector (i32 (extract_vector_elt castx, (2 * y))),
+ // (i32 (extract_vector_elt castx, (2 * y + 1)))
+ //
+ if (NewNumElts % OldNumElts != 0)
+ return UnableToLegalize;
+
+ // Type of the intermediate result vector.
+ const unsigned NewEltsPerOldElt = NewNumElts / OldNumElts;
+ LLT MidTy = LLT::scalarOrVector(NewEltsPerOldElt, NewEltTy);
+
+ auto NewEltsPerOldEltK = MIRBuilder.buildConstant(IdxTy, NewEltsPerOldElt);
+
+ SmallVector<Register, 8> NewOps(NewEltsPerOldElt);
+ auto NewBaseIdx = MIRBuilder.buildMul(IdxTy, Idx, NewEltsPerOldEltK);
+
+ for (unsigned I = 0; I < NewEltsPerOldElt; ++I) {
+ auto IdxOffset = MIRBuilder.buildConstant(IdxTy, I);
+ auto TmpIdx = MIRBuilder.buildAdd(IdxTy, NewBaseIdx, IdxOffset);
+ auto Elt = MIRBuilder.buildExtractVectorElement(NewEltTy, CastVec, TmpIdx);
+ NewOps[I] = Elt.getReg(0);
+ }
+
+ auto NewVec = MIRBuilder.buildBuildVector(MidTy, NewOps);
+ MIRBuilder.buildBitcast(Dst, NewVec);
+ MI.eraseFromParent();
+ return Legalized;
+ }
+
+ if (NewNumElts < OldNumElts) {
+ if (NewEltSize % OldEltSize != 0)
+ return UnableToLegalize;
+
+ // This only depends on powers of 2 because we use bit tricks to figure out
+ // the bit offset we need to shift to get the target element. A general
+ // expansion could emit division/multiply.
+ if (!isPowerOf2_32(NewEltSize / OldEltSize))
+ return UnableToLegalize;
+
+ // Increasing the vector element size.
+ // %elt:_(small_elt) = G_EXTRACT_VECTOR_ELT %vec:_(<N x small_elt>), %idx
+ //
+ // =>
+ //
+ // %cast = G_BITCAST %vec
+ // %scaled_idx = G_LSHR %idx, Log2(DstEltSize / SrcEltSize)
+ // %wide_elt = G_EXTRACT_VECTOR_ELT %cast, %scaled_idx
+ // %offset_idx = G_AND %idx, ~(-1 << Log2(DstEltSize / SrcEltSize))
+ // %offset_bits = G_SHL %offset_idx, Log2(SrcEltSize)
+ // %elt_bits = G_LSHR %wide_elt, %offset_bits
+ // %elt = G_TRUNC %elt_bits
+
+ const unsigned Log2EltRatio = Log2_32(NewEltSize / OldEltSize);
+ auto Log2Ratio = MIRBuilder.buildConstant(IdxTy, Log2EltRatio);
+
+ // Divide to get the index in the wider element type.
+ auto ScaledIdx = MIRBuilder.buildLShr(IdxTy, Idx, Log2Ratio);
+
+ Register WideElt = CastVec;
+ if (CastTy.isVector()) {
+ WideElt = MIRBuilder.buildExtractVectorElement(NewEltTy, CastVec,
+ ScaledIdx).getReg(0);
+ }
+
+ // Compute the bit offset into the register of the target element.
+ Register OffsetBits = getBitcastWiderVectorElementOffset(
+ MIRBuilder, Idx, NewEltSize, OldEltSize);
+
+ // Shift the wide element to get the target element.
+ auto ExtractedBits = MIRBuilder.buildLShr(NewEltTy, WideElt, OffsetBits);
+ MIRBuilder.buildTrunc(Dst, ExtractedBits);
+ MI.eraseFromParent();
+ return Legalized;
+ }
+
+ return UnableToLegalize;
+}
+
+/// Emit code to insert \p InsertReg into \p TargetRet at \p OffsetBits in \p
+/// TargetReg, while preserving other bits in \p TargetReg.
+///
+/// (InsertReg << Offset) | (TargetReg & ~(-1 >> InsertReg.size()) << Offset)
+static Register buildBitFieldInsert(MachineIRBuilder &B,
+ Register TargetReg, Register InsertReg,
+ Register OffsetBits) {
+ LLT TargetTy = B.getMRI()->getType(TargetReg);
+ LLT InsertTy = B.getMRI()->getType(InsertReg);
+ auto ZextVal = B.buildZExt(TargetTy, InsertReg);
+ auto ShiftedInsertVal = B.buildShl(TargetTy, ZextVal, OffsetBits);
+
+ // Produce a bitmask of the value to insert
+ auto EltMask = B.buildConstant(
+ TargetTy, APInt::getLowBitsSet(TargetTy.getSizeInBits(),
+ InsertTy.getSizeInBits()));
+ // Shift it into position
+ auto ShiftedMask = B.buildShl(TargetTy, EltMask, OffsetBits);
+ auto InvShiftedMask = B.buildNot(TargetTy, ShiftedMask);
+
+ // Clear out the bits in the wide element
+ auto MaskedOldElt = B.buildAnd(TargetTy, TargetReg, InvShiftedMask);
+
+ // The value to insert has all zeros already, so stick it into the masked
+ // wide element.
+ return B.buildOr(TargetTy, MaskedOldElt, ShiftedInsertVal).getReg(0);
+}
+
+/// Perform a G_INSERT_VECTOR_ELT in a different sized vector element. If this
+/// is increasing the element size, perform the indexing in the target element
+/// type, and use bit operations to insert at the element position. This is
+/// intended for architectures that can dynamically index the register file and
+/// want to force indexing in the native register size.
+LegalizerHelper::LegalizeResult
+LegalizerHelper::bitcastInsertVectorElt(MachineInstr &MI, unsigned TypeIdx,
+ LLT CastTy) {
+ if (TypeIdx != 0)
+ return UnableToLegalize;
+
+ Register Dst = MI.getOperand(0).getReg();
+ Register SrcVec = MI.getOperand(1).getReg();
+ Register Val = MI.getOperand(2).getReg();
+ Register Idx = MI.getOperand(3).getReg();
+
+ LLT VecTy = MRI.getType(Dst);
+ LLT IdxTy = MRI.getType(Idx);
+
+ LLT VecEltTy = VecTy.getElementType();
+ LLT NewEltTy = CastTy.isVector() ? CastTy.getElementType() : CastTy;
+ const unsigned NewEltSize = NewEltTy.getSizeInBits();
+ const unsigned OldEltSize = VecEltTy.getSizeInBits();
+
+ unsigned NewNumElts = CastTy.isVector() ? CastTy.getNumElements() : 1;
+ unsigned OldNumElts = VecTy.getNumElements();
+
+ Register CastVec = MIRBuilder.buildBitcast(CastTy, SrcVec).getReg(0);
+ if (NewNumElts < OldNumElts) {
+ if (NewEltSize % OldEltSize != 0)
+ return UnableToLegalize;
+
+ // This only depends on powers of 2 because we use bit tricks to figure out
+ // the bit offset we need to shift to get the target element. A general
+ // expansion could emit division/multiply.
+ if (!isPowerOf2_32(NewEltSize / OldEltSize))
+ return UnableToLegalize;
+
+ const unsigned Log2EltRatio = Log2_32(NewEltSize / OldEltSize);
+ auto Log2Ratio = MIRBuilder.buildConstant(IdxTy, Log2EltRatio);
+
+ // Divide to get the index in the wider element type.
+ auto ScaledIdx = MIRBuilder.buildLShr(IdxTy, Idx, Log2Ratio);
+
+ Register ExtractedElt = CastVec;
+ if (CastTy.isVector()) {
+ ExtractedElt = MIRBuilder.buildExtractVectorElement(NewEltTy, CastVec,
+ ScaledIdx).getReg(0);
+ }
+
+ // Compute the bit offset into the register of the target element.
+ Register OffsetBits = getBitcastWiderVectorElementOffset(
+ MIRBuilder, Idx, NewEltSize, OldEltSize);
+
+ Register InsertedElt = buildBitFieldInsert(MIRBuilder, ExtractedElt,
+ Val, OffsetBits);
+ if (CastTy.isVector()) {
+ InsertedElt = MIRBuilder.buildInsertVectorElement(
+ CastTy, CastVec, InsertedElt, ScaledIdx).getReg(0);
+ }
+
+ MIRBuilder.buildBitcast(Dst, InsertedElt);
+ MI.eraseFromParent();
+ return Legalized;
+ }
+
+ return UnableToLegalize;
+}
+
+LegalizerHelper::LegalizeResult
+LegalizerHelper::lowerLoad(MachineInstr &MI) {
+ // Lower to a memory-width G_LOAD and a G_SEXT/G_ZEXT/G_ANYEXT
+ Register DstReg = MI.getOperand(0).getReg();
+ Register PtrReg = MI.getOperand(1).getReg();
+ LLT DstTy = MRI.getType(DstReg);
+ auto &MMO = **MI.memoperands_begin();
+
+ if (DstTy.getSizeInBits() == MMO.getSizeInBits()) {
+ if (MI.getOpcode() == TargetOpcode::G_LOAD) {
+ // This load needs splitting into power of 2 sized loads.
+ if (DstTy.isVector())
+ return UnableToLegalize;
+ if (isPowerOf2_32(DstTy.getSizeInBits()))
+ return UnableToLegalize; // Don't know what we're being asked to do.
+
+ // Our strategy here is to generate anyextending loads for the smaller
+ // types up to next power-2 result type, and then combine the two larger
+ // result values together, before truncating back down to the non-pow-2
+ // type.
+ // E.g. v1 = i24 load =>
+ // v2 = i32 zextload (2 byte)
+ // v3 = i32 load (1 byte)
+ // v4 = i32 shl v3, 16
+ // v5 = i32 or v4, v2
+ // v1 = i24 trunc v5
+ // By doing this we generate the correct truncate which should get
+ // combined away as an artifact with a matching extend.
+ uint64_t LargeSplitSize = PowerOf2Floor(DstTy.getSizeInBits());
+ uint64_t SmallSplitSize = DstTy.getSizeInBits() - LargeSplitSize;
+
+ MachineFunction &MF = MIRBuilder.getMF();
+ MachineMemOperand *LargeMMO =
+ MF.getMachineMemOperand(&MMO, 0, LargeSplitSize / 8);
+ MachineMemOperand *SmallMMO = MF.getMachineMemOperand(
+ &MMO, LargeSplitSize / 8, SmallSplitSize / 8);
+
+ LLT PtrTy = MRI.getType(PtrReg);
+ unsigned AnyExtSize = NextPowerOf2(DstTy.getSizeInBits());
+ LLT AnyExtTy = LLT::scalar(AnyExtSize);
+ Register LargeLdReg = MRI.createGenericVirtualRegister(AnyExtTy);
+ Register SmallLdReg = MRI.createGenericVirtualRegister(AnyExtTy);
+ auto LargeLoad = MIRBuilder.buildLoadInstr(
+ TargetOpcode::G_ZEXTLOAD, LargeLdReg, PtrReg, *LargeMMO);
+
+ auto OffsetCst = MIRBuilder.buildConstant(
+ LLT::scalar(PtrTy.getSizeInBits()), LargeSplitSize / 8);
+ Register PtrAddReg = MRI.createGenericVirtualRegister(PtrTy);
+ auto SmallPtr =
+ MIRBuilder.buildPtrAdd(PtrAddReg, PtrReg, OffsetCst.getReg(0));
+ auto SmallLoad = MIRBuilder.buildLoad(SmallLdReg, SmallPtr.getReg(0),
+ *SmallMMO);
+
+ auto ShiftAmt = MIRBuilder.buildConstant(AnyExtTy, LargeSplitSize);
+ auto Shift = MIRBuilder.buildShl(AnyExtTy, SmallLoad, ShiftAmt);
+ auto Or = MIRBuilder.buildOr(AnyExtTy, Shift, LargeLoad);
+ MIRBuilder.buildTrunc(DstReg, {Or.getReg(0)});
+ MI.eraseFromParent();
+ return Legalized;
+ }
+
+ MIRBuilder.buildLoad(DstReg, PtrReg, MMO);
+ MI.eraseFromParent();
+ return Legalized;
+ }
+
+ if (DstTy.isScalar()) {
+ Register TmpReg =
+ MRI.createGenericVirtualRegister(LLT::scalar(MMO.getSizeInBits()));
+ MIRBuilder.buildLoad(TmpReg, PtrReg, MMO);
+ switch (MI.getOpcode()) {
+ default:
+ llvm_unreachable("Unexpected opcode");
+ case TargetOpcode::G_LOAD:
+ MIRBuilder.buildAnyExtOrTrunc(DstReg, TmpReg);
+ break;
+ case TargetOpcode::G_SEXTLOAD:
+ MIRBuilder.buildSExt(DstReg, TmpReg);
+ break;
+ case TargetOpcode::G_ZEXTLOAD:
+ MIRBuilder.buildZExt(DstReg, TmpReg);
+ break;
+ }
+
+ MI.eraseFromParent();
+ return Legalized;
+ }
+
+ return UnableToLegalize;
+}
+
+LegalizerHelper::LegalizeResult
+LegalizerHelper::lowerStore(MachineInstr &MI) {
+ // Lower a non-power of 2 store into multiple pow-2 stores.
+ // E.g. split an i24 store into an i16 store + i8 store.
+ // We do this by first extending the stored value to the next largest power
+ // of 2 type, and then using truncating stores to store the components.
+ // By doing this, likewise with G_LOAD, generate an extend that can be
+ // artifact-combined away instead of leaving behind extracts.
+ Register SrcReg = MI.getOperand(0).getReg();
+ Register PtrReg = MI.getOperand(1).getReg();
+ LLT SrcTy = MRI.getType(SrcReg);
+ MachineMemOperand &MMO = **MI.memoperands_begin();
+ if (SrcTy.getSizeInBits() != MMO.getSizeInBits())
+ return UnableToLegalize;
+ if (SrcTy.isVector())
+ return UnableToLegalize;
+ if (isPowerOf2_32(SrcTy.getSizeInBits()))
+ return UnableToLegalize; // Don't know what we're being asked to do.
+
+ // Extend to the next pow-2.
+ const LLT ExtendTy = LLT::scalar(NextPowerOf2(SrcTy.getSizeInBits()));
+ auto ExtVal = MIRBuilder.buildAnyExt(ExtendTy, SrcReg);
+
+ // Obtain the smaller value by shifting away the larger value.
+ uint64_t LargeSplitSize = PowerOf2Floor(SrcTy.getSizeInBits());
+ uint64_t SmallSplitSize = SrcTy.getSizeInBits() - LargeSplitSize;
+ auto ShiftAmt = MIRBuilder.buildConstant(ExtendTy, LargeSplitSize);
+ auto SmallVal = MIRBuilder.buildLShr(ExtendTy, ExtVal, ShiftAmt);
+
+ // Generate the PtrAdd and truncating stores.
+ LLT PtrTy = MRI.getType(PtrReg);
+ auto OffsetCst = MIRBuilder.buildConstant(
+ LLT::scalar(PtrTy.getSizeInBits()), LargeSplitSize / 8);
+ Register PtrAddReg = MRI.createGenericVirtualRegister(PtrTy);
+ auto SmallPtr =
+ MIRBuilder.buildPtrAdd(PtrAddReg, PtrReg, OffsetCst.getReg(0));
+
+ MachineFunction &MF = MIRBuilder.getMF();
+ MachineMemOperand *LargeMMO =
+ MF.getMachineMemOperand(&MMO, 0, LargeSplitSize / 8);
+ MachineMemOperand *SmallMMO =
+ MF.getMachineMemOperand(&MMO, LargeSplitSize / 8, SmallSplitSize / 8);
+ MIRBuilder.buildStore(ExtVal.getReg(0), PtrReg, *LargeMMO);
+ MIRBuilder.buildStore(SmallVal.getReg(0), SmallPtr.getReg(0), *SmallMMO);
+ MI.eraseFromParent();
+ return Legalized;
+}
+
LegalizerHelper::LegalizeResult
-LegalizerHelper::bitcastExtractVectorElt(MachineInstr &MI, unsigned TypeIdx,
- LLT CastTy) {
- if (TypeIdx != 1)
- return UnableToLegalize;
-
- Register Dst = MI.getOperand(0).getReg();
- Register SrcVec = MI.getOperand(1).getReg();
- Register Idx = MI.getOperand(2).getReg();
- LLT SrcVecTy = MRI.getType(SrcVec);
- LLT IdxTy = MRI.getType(Idx);
-
- LLT SrcEltTy = SrcVecTy.getElementType();
- unsigned NewNumElts = CastTy.isVector() ? CastTy.getNumElements() : 1;
- unsigned OldNumElts = SrcVecTy.getNumElements();
-
- LLT NewEltTy = CastTy.isVector() ? CastTy.getElementType() : CastTy;
- Register CastVec = MIRBuilder.buildBitcast(CastTy, SrcVec).getReg(0);
-
- const unsigned NewEltSize = NewEltTy.getSizeInBits();
- const unsigned OldEltSize = SrcEltTy.getSizeInBits();
- if (NewNumElts > OldNumElts) {
- // Decreasing the vector element size
- //
- // e.g. i64 = extract_vector_elt x:v2i64, y:i32
- // =>
- // v4i32:castx = bitcast x:v2i64
- //
- // i64 = bitcast
- // (v2i32 build_vector (i32 (extract_vector_elt castx, (2 * y))),
- // (i32 (extract_vector_elt castx, (2 * y + 1)))
- //
- if (NewNumElts % OldNumElts != 0)
- return UnableToLegalize;
-
- // Type of the intermediate result vector.
- const unsigned NewEltsPerOldElt = NewNumElts / OldNumElts;
- LLT MidTy = LLT::scalarOrVector(NewEltsPerOldElt, NewEltTy);
-
- auto NewEltsPerOldEltK = MIRBuilder.buildConstant(IdxTy, NewEltsPerOldElt);
-
- SmallVector<Register, 8> NewOps(NewEltsPerOldElt);
- auto NewBaseIdx = MIRBuilder.buildMul(IdxTy, Idx, NewEltsPerOldEltK);
-
- for (unsigned I = 0; I < NewEltsPerOldElt; ++I) {
- auto IdxOffset = MIRBuilder.buildConstant(IdxTy, I);
- auto TmpIdx = MIRBuilder.buildAdd(IdxTy, NewBaseIdx, IdxOffset);
- auto Elt = MIRBuilder.buildExtractVectorElement(NewEltTy, CastVec, TmpIdx);
- NewOps[I] = Elt.getReg(0);
- }
-
- auto NewVec = MIRBuilder.buildBuildVector(MidTy, NewOps);
- MIRBuilder.buildBitcast(Dst, NewVec);
- MI.eraseFromParent();
- return Legalized;
- }
-
- if (NewNumElts < OldNumElts) {
- if (NewEltSize % OldEltSize != 0)
- return UnableToLegalize;
-
- // This only depends on powers of 2 because we use bit tricks to figure out
- // the bit offset we need to shift to get the target element. A general
- // expansion could emit division/multiply.
- if (!isPowerOf2_32(NewEltSize / OldEltSize))
- return UnableToLegalize;
-
- // Increasing the vector element size.
- // %elt:_(small_elt) = G_EXTRACT_VECTOR_ELT %vec:_(<N x small_elt>), %idx
- //
- // =>
- //
- // %cast = G_BITCAST %vec
- // %scaled_idx = G_LSHR %idx, Log2(DstEltSize / SrcEltSize)
- // %wide_elt = G_EXTRACT_VECTOR_ELT %cast, %scaled_idx
- // %offset_idx = G_AND %idx, ~(-1 << Log2(DstEltSize / SrcEltSize))
- // %offset_bits = G_SHL %offset_idx, Log2(SrcEltSize)
- // %elt_bits = G_LSHR %wide_elt, %offset_bits
- // %elt = G_TRUNC %elt_bits
-
- const unsigned Log2EltRatio = Log2_32(NewEltSize / OldEltSize);
- auto Log2Ratio = MIRBuilder.buildConstant(IdxTy, Log2EltRatio);
-
- // Divide to get the index in the wider element type.
- auto ScaledIdx = MIRBuilder.buildLShr(IdxTy, Idx, Log2Ratio);
-
- Register WideElt = CastVec;
- if (CastTy.isVector()) {
- WideElt = MIRBuilder.buildExtractVectorElement(NewEltTy, CastVec,
- ScaledIdx).getReg(0);
- }
-
- // Compute the bit offset into the register of the target element.
- Register OffsetBits = getBitcastWiderVectorElementOffset(
- MIRBuilder, Idx, NewEltSize, OldEltSize);
-
- // Shift the wide element to get the target element.
- auto ExtractedBits = MIRBuilder.buildLShr(NewEltTy, WideElt, OffsetBits);
- MIRBuilder.buildTrunc(Dst, ExtractedBits);
- MI.eraseFromParent();
- return Legalized;
- }
-
- return UnableToLegalize;
-}
-
-/// Emit code to insert \p InsertReg into \p TargetRet at \p OffsetBits in \p
-/// TargetReg, while preserving other bits in \p TargetReg.
-///
-/// (InsertReg << Offset) | (TargetReg & ~(-1 >> InsertReg.size()) << Offset)
-static Register buildBitFieldInsert(MachineIRBuilder &B,
- Register TargetReg, Register InsertReg,
- Register OffsetBits) {
- LLT TargetTy = B.getMRI()->getType(TargetReg);
- LLT InsertTy = B.getMRI()->getType(InsertReg);
- auto ZextVal = B.buildZExt(TargetTy, InsertReg);
- auto ShiftedInsertVal = B.buildShl(TargetTy, ZextVal, OffsetBits);
-
- // Produce a bitmask of the value to insert
- auto EltMask = B.buildConstant(
- TargetTy, APInt::getLowBitsSet(TargetTy.getSizeInBits(),
- InsertTy.getSizeInBits()));
- // Shift it into position
- auto ShiftedMask = B.buildShl(TargetTy, EltMask, OffsetBits);
- auto InvShiftedMask = B.buildNot(TargetTy, ShiftedMask);
-
- // Clear out the bits in the wide element
- auto MaskedOldElt = B.buildAnd(TargetTy, TargetReg, InvShiftedMask);
-
- // The value to insert has all zeros already, so stick it into the masked
- // wide element.
- return B.buildOr(TargetTy, MaskedOldElt, ShiftedInsertVal).getReg(0);
-}
-
-/// Perform a G_INSERT_VECTOR_ELT in a different sized vector element. If this
-/// is increasing the element size, perform the indexing in the target element
-/// type, and use bit operations to insert at the element position. This is
-/// intended for architectures that can dynamically index the register file and
-/// want to force indexing in the native register size.
-LegalizerHelper::LegalizeResult
-LegalizerHelper::bitcastInsertVectorElt(MachineInstr &MI, unsigned TypeIdx,
- LLT CastTy) {
- if (TypeIdx != 0)
- return UnableToLegalize;
-
- Register Dst = MI.getOperand(0).getReg();
- Register SrcVec = MI.getOperand(1).getReg();
- Register Val = MI.getOperand(2).getReg();
- Register Idx = MI.getOperand(3).getReg();
-
- LLT VecTy = MRI.getType(Dst);
- LLT IdxTy = MRI.getType(Idx);
-
- LLT VecEltTy = VecTy.getElementType();
- LLT NewEltTy = CastTy.isVector() ? CastTy.getElementType() : CastTy;
- const unsigned NewEltSize = NewEltTy.getSizeInBits();
- const unsigned OldEltSize = VecEltTy.getSizeInBits();
-
- unsigned NewNumElts = CastTy.isVector() ? CastTy.getNumElements() : 1;
- unsigned OldNumElts = VecTy.getNumElements();
-
- Register CastVec = MIRBuilder.buildBitcast(CastTy, SrcVec).getReg(0);
- if (NewNumElts < OldNumElts) {
- if (NewEltSize % OldEltSize != 0)
- return UnableToLegalize;
-
- // This only depends on powers of 2 because we use bit tricks to figure out
- // the bit offset we need to shift to get the target element. A general
- // expansion could emit division/multiply.
- if (!isPowerOf2_32(NewEltSize / OldEltSize))
- return UnableToLegalize;
-
- const unsigned Log2EltRatio = Log2_32(NewEltSize / OldEltSize);
- auto Log2Ratio = MIRBuilder.buildConstant(IdxTy, Log2EltRatio);
-
- // Divide to get the index in the wider element type.
- auto ScaledIdx = MIRBuilder.buildLShr(IdxTy, Idx, Log2Ratio);
-
- Register ExtractedElt = CastVec;
- if (CastTy.isVector()) {
- ExtractedElt = MIRBuilder.buildExtractVectorElement(NewEltTy, CastVec,
- ScaledIdx).getReg(0);
- }
-
- // Compute the bit offset into the register of the target element.
- Register OffsetBits = getBitcastWiderVectorElementOffset(
- MIRBuilder, Idx, NewEltSize, OldEltSize);
-
- Register InsertedElt = buildBitFieldInsert(MIRBuilder, ExtractedElt,
- Val, OffsetBits);
- if (CastTy.isVector()) {
- InsertedElt = MIRBuilder.buildInsertVectorElement(
- CastTy, CastVec, InsertedElt, ScaledIdx).getReg(0);
- }
-
- MIRBuilder.buildBitcast(Dst, InsertedElt);
- MI.eraseFromParent();
- return Legalized;
- }
-
- return UnableToLegalize;
-}
-
-LegalizerHelper::LegalizeResult
-LegalizerHelper::lowerLoad(MachineInstr &MI) {
- // Lower to a memory-width G_LOAD and a G_SEXT/G_ZEXT/G_ANYEXT
- Register DstReg = MI.getOperand(0).getReg();
- Register PtrReg = MI.getOperand(1).getReg();
- LLT DstTy = MRI.getType(DstReg);
- auto &MMO = **MI.memoperands_begin();
-
- if (DstTy.getSizeInBits() == MMO.getSizeInBits()) {
- if (MI.getOpcode() == TargetOpcode::G_LOAD) {
- // This load needs splitting into power of 2 sized loads.
- if (DstTy.isVector())
- return UnableToLegalize;
- if (isPowerOf2_32(DstTy.getSizeInBits()))
- return UnableToLegalize; // Don't know what we're being asked to do.
-
- // Our strategy here is to generate anyextending loads for the smaller
- // types up to next power-2 result type, and then combine the two larger
- // result values together, before truncating back down to the non-pow-2
- // type.
- // E.g. v1 = i24 load =>
- // v2 = i32 zextload (2 byte)
- // v3 = i32 load (1 byte)
- // v4 = i32 shl v3, 16
- // v5 = i32 or v4, v2
- // v1 = i24 trunc v5
- // By doing this we generate the correct truncate which should get
- // combined away as an artifact with a matching extend.
- uint64_t LargeSplitSize = PowerOf2Floor(DstTy.getSizeInBits());
- uint64_t SmallSplitSize = DstTy.getSizeInBits() - LargeSplitSize;
-
- MachineFunction &MF = MIRBuilder.getMF();
- MachineMemOperand *LargeMMO =
- MF.getMachineMemOperand(&MMO, 0, LargeSplitSize / 8);
- MachineMemOperand *SmallMMO = MF.getMachineMemOperand(
- &MMO, LargeSplitSize / 8, SmallSplitSize / 8);
-
- LLT PtrTy = MRI.getType(PtrReg);
- unsigned AnyExtSize = NextPowerOf2(DstTy.getSizeInBits());
- LLT AnyExtTy = LLT::scalar(AnyExtSize);
- Register LargeLdReg = MRI.createGenericVirtualRegister(AnyExtTy);
- Register SmallLdReg = MRI.createGenericVirtualRegister(AnyExtTy);
- auto LargeLoad = MIRBuilder.buildLoadInstr(
- TargetOpcode::G_ZEXTLOAD, LargeLdReg, PtrReg, *LargeMMO);
-
- auto OffsetCst = MIRBuilder.buildConstant(
- LLT::scalar(PtrTy.getSizeInBits()), LargeSplitSize / 8);
- Register PtrAddReg = MRI.createGenericVirtualRegister(PtrTy);
- auto SmallPtr =
- MIRBuilder.buildPtrAdd(PtrAddReg, PtrReg, OffsetCst.getReg(0));
- auto SmallLoad = MIRBuilder.buildLoad(SmallLdReg, SmallPtr.getReg(0),
- *SmallMMO);
-
- auto ShiftAmt = MIRBuilder.buildConstant(AnyExtTy, LargeSplitSize);
- auto Shift = MIRBuilder.buildShl(AnyExtTy, SmallLoad, ShiftAmt);
- auto Or = MIRBuilder.buildOr(AnyExtTy, Shift, LargeLoad);
- MIRBuilder.buildTrunc(DstReg, {Or.getReg(0)});
- MI.eraseFromParent();
- return Legalized;
- }
-
- MIRBuilder.buildLoad(DstReg, PtrReg, MMO);
- MI.eraseFromParent();
- return Legalized;
- }
-
- if (DstTy.isScalar()) {
- Register TmpReg =
- MRI.createGenericVirtualRegister(LLT::scalar(MMO.getSizeInBits()));
- MIRBuilder.buildLoad(TmpReg, PtrReg, MMO);
- switch (MI.getOpcode()) {
- default:
- llvm_unreachable("Unexpected opcode");
- case TargetOpcode::G_LOAD:
- MIRBuilder.buildAnyExtOrTrunc(DstReg, TmpReg);
- break;
- case TargetOpcode::G_SEXTLOAD:
- MIRBuilder.buildSExt(DstReg, TmpReg);
- break;
- case TargetOpcode::G_ZEXTLOAD:
- MIRBuilder.buildZExt(DstReg, TmpReg);
- break;
- }
-
- MI.eraseFromParent();
- return Legalized;
- }
-
- return UnableToLegalize;
-}
-
-LegalizerHelper::LegalizeResult
-LegalizerHelper::lowerStore(MachineInstr &MI) {
- // Lower a non-power of 2 store into multiple pow-2 stores.
- // E.g. split an i24 store into an i16 store + i8 store.
- // We do this by first extending the stored value to the next largest power
- // of 2 type, and then using truncating stores to store the components.
- // By doing this, likewise with G_LOAD, generate an extend that can be
- // artifact-combined away instead of leaving behind extracts.
- Register SrcReg = MI.getOperand(0).getReg();
- Register PtrReg = MI.getOperand(1).getReg();
- LLT SrcTy = MRI.getType(SrcReg);
- MachineMemOperand &MMO = **MI.memoperands_begin();
- if (SrcTy.getSizeInBits() != MMO.getSizeInBits())
- return UnableToLegalize;
- if (SrcTy.isVector())
- return UnableToLegalize;
- if (isPowerOf2_32(SrcTy.getSizeInBits()))
- return UnableToLegalize; // Don't know what we're being asked to do.
-
- // Extend to the next pow-2.
- const LLT ExtendTy = LLT::scalar(NextPowerOf2(SrcTy.getSizeInBits()));
- auto ExtVal = MIRBuilder.buildAnyExt(ExtendTy, SrcReg);
-
- // Obtain the smaller value by shifting away the larger value.
- uint64_t LargeSplitSize = PowerOf2Floor(SrcTy.getSizeInBits());
- uint64_t SmallSplitSize = SrcTy.getSizeInBits() - LargeSplitSize;
- auto ShiftAmt = MIRBuilder.buildConstant(ExtendTy, LargeSplitSize);
- auto SmallVal = MIRBuilder.buildLShr(ExtendTy, ExtVal, ShiftAmt);
-
- // Generate the PtrAdd and truncating stores.
- LLT PtrTy = MRI.getType(PtrReg);
- auto OffsetCst = MIRBuilder.buildConstant(
- LLT::scalar(PtrTy.getSizeInBits()), LargeSplitSize / 8);
- Register PtrAddReg = MRI.createGenericVirtualRegister(PtrTy);
- auto SmallPtr =
- MIRBuilder.buildPtrAdd(PtrAddReg, PtrReg, OffsetCst.getReg(0));
-
- MachineFunction &MF = MIRBuilder.getMF();
- MachineMemOperand *LargeMMO =
- MF.getMachineMemOperand(&MMO, 0, LargeSplitSize / 8);
- MachineMemOperand *SmallMMO =
- MF.getMachineMemOperand(&MMO, LargeSplitSize / 8, SmallSplitSize / 8);
- MIRBuilder.buildStore(ExtVal.getReg(0), PtrReg, *LargeMMO);
- MIRBuilder.buildStore(SmallVal.getReg(0), SmallPtr.getReg(0), *SmallMMO);
- MI.eraseFromParent();
- return Legalized;
-}
-
-LegalizerHelper::LegalizeResult
LegalizerHelper::bitcast(MachineInstr &MI, unsigned TypeIdx, LLT CastTy) {
switch (MI.getOpcode()) {
case TargetOpcode::G_LOAD: {
@@ -2833,24 +2833,24 @@ LegalizerHelper::bitcast(MachineInstr &MI, unsigned TypeIdx, LLT CastTy) {
Observer.changedInstr(MI);
return Legalized;
}
- case TargetOpcode::G_EXTRACT_VECTOR_ELT:
- return bitcastExtractVectorElt(MI, TypeIdx, CastTy);
- case TargetOpcode::G_INSERT_VECTOR_ELT:
- return bitcastInsertVectorElt(MI, TypeIdx, CastTy);
+ case TargetOpcode::G_EXTRACT_VECTOR_ELT:
+ return bitcastExtractVectorElt(MI, TypeIdx, CastTy);
+ case TargetOpcode::G_INSERT_VECTOR_ELT:
+ return bitcastInsertVectorElt(MI, TypeIdx, CastTy);
default:
return UnableToLegalize;
}
}
-// Legalize an instruction by changing the opcode in place.
-void LegalizerHelper::changeOpcode(MachineInstr &MI, unsigned NewOpcode) {
- Observer.changingInstr(MI);
- MI.setDesc(MIRBuilder.getTII().get(NewOpcode));
- Observer.changedInstr(MI);
-}
-
+// Legalize an instruction by changing the opcode in place.
+void LegalizerHelper::changeOpcode(MachineInstr &MI, unsigned NewOpcode) {
+ Observer.changingInstr(MI);
+ MI.setDesc(MIRBuilder.getTII().get(NewOpcode));
+ Observer.changedInstr(MI);
+}
+
LegalizerHelper::LegalizeResult
-LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
+LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
using namespace TargetOpcode;
switch(MI.getOpcode()) {
@@ -2860,7 +2860,7 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
return lowerBitcast(MI);
case TargetOpcode::G_SREM:
case TargetOpcode::G_UREM: {
- LLT Ty = MRI.getType(MI.getOperand(0).getReg());
+ LLT Ty = MRI.getType(MI.getOperand(0).getReg());
auto Quot =
MIRBuilder.buildInstr(MI.getOpcode() == G_SREM ? G_SDIV : G_UDIV, {Ty},
{MI.getOperand(1), MI.getOperand(2)});
@@ -2873,9 +2873,9 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
case TargetOpcode::G_SADDO:
case TargetOpcode::G_SSUBO:
return lowerSADDO_SSUBO(MI);
- case TargetOpcode::G_UMULH:
- case TargetOpcode::G_SMULH:
- return lowerSMULH_UMULH(MI);
+ case TargetOpcode::G_UMULH:
+ case TargetOpcode::G_SMULH:
+ return lowerSMULH_UMULH(MI);
case TargetOpcode::G_SMULO:
case TargetOpcode::G_UMULO: {
// Generate G_UMULH/G_SMULH to check for overflow and a normal G_MUL for the
@@ -2884,7 +2884,7 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
Register Overflow = MI.getOperand(1).getReg();
Register LHS = MI.getOperand(2).getReg();
Register RHS = MI.getOperand(3).getReg();
- LLT Ty = MRI.getType(Res);
+ LLT Ty = MRI.getType(Res);
unsigned Opcode = MI.getOpcode() == TargetOpcode::G_SMULO
? TargetOpcode::G_SMULH
@@ -2914,24 +2914,24 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
return Legalized;
}
case TargetOpcode::G_FNEG: {
- Register Res = MI.getOperand(0).getReg();
- LLT Ty = MRI.getType(Res);
-
+ Register Res = MI.getOperand(0).getReg();
+ LLT Ty = MRI.getType(Res);
+
// TODO: Handle vector types once we are able to
// represent them.
if (Ty.isVector())
return UnableToLegalize;
- auto SignMask =
- MIRBuilder.buildConstant(Ty, APInt::getSignMask(Ty.getSizeInBits()));
+ auto SignMask =
+ MIRBuilder.buildConstant(Ty, APInt::getSignMask(Ty.getSizeInBits()));
Register SubByReg = MI.getOperand(1).getReg();
- MIRBuilder.buildXor(Res, SubByReg, SignMask);
+ MIRBuilder.buildXor(Res, SubByReg, SignMask);
MI.eraseFromParent();
return Legalized;
}
case TargetOpcode::G_FSUB: {
- Register Res = MI.getOperand(0).getReg();
- LLT Ty = MRI.getType(Res);
-
+ Register Res = MI.getOperand(0).getReg();
+ LLT Ty = MRI.getType(Res);
+
// Lower (G_FSUB LHS, RHS) to (G_FADD LHS, (G_FNEG RHS)).
// First, check if G_FNEG is marked as Lower. If so, we may
// end up with an infinite loop as G_FSUB is used to legalize G_FNEG.
@@ -2951,12 +2951,12 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
return lowerFFloor(MI);
case TargetOpcode::G_INTRINSIC_ROUND:
return lowerIntrinsicRound(MI);
- case TargetOpcode::G_INTRINSIC_ROUNDEVEN: {
- // Since round even is the assumed rounding mode for unconstrained FP
- // operations, rint and roundeven are the same operation.
- changeOpcode(MI, TargetOpcode::G_FRINT);
- return Legalized;
- }
+ case TargetOpcode::G_INTRINSIC_ROUNDEVEN: {
+ // Since round even is the assumed rounding mode for unconstrained FP
+ // operations, rint and roundeven are the same operation.
+ changeOpcode(MI, TargetOpcode::G_FRINT);
+ return Legalized;
+ }
case TargetOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS: {
Register OldValRes = MI.getOperand(0).getReg();
Register SuccessRes = MI.getOperand(1).getReg();
@@ -2971,16 +2971,16 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
}
case TargetOpcode::G_LOAD:
case TargetOpcode::G_SEXTLOAD:
- case TargetOpcode::G_ZEXTLOAD:
- return lowerLoad(MI);
- case TargetOpcode::G_STORE:
- return lowerStore(MI);
+ case TargetOpcode::G_ZEXTLOAD:
+ return lowerLoad(MI);
+ case TargetOpcode::G_STORE:
+ return lowerStore(MI);
case TargetOpcode::G_CTLZ_ZERO_UNDEF:
case TargetOpcode::G_CTTZ_ZERO_UNDEF:
case TargetOpcode::G_CTLZ:
case TargetOpcode::G_CTTZ:
case TargetOpcode::G_CTPOP:
- return lowerBitCount(MI);
+ return lowerBitCount(MI);
case G_UADDO: {
Register Res = MI.getOperand(0).getReg();
Register CarryOut = MI.getOperand(1).getReg();
@@ -3042,24 +3042,24 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
return Legalized;
}
case G_UITOFP:
- return lowerUITOFP(MI);
+ return lowerUITOFP(MI);
case G_SITOFP:
- return lowerSITOFP(MI);
+ return lowerSITOFP(MI);
case G_FPTOUI:
- return lowerFPTOUI(MI);
+ return lowerFPTOUI(MI);
case G_FPTOSI:
return lowerFPTOSI(MI);
case G_FPTRUNC:
- return lowerFPTRUNC(MI);
- case G_FPOWI:
- return lowerFPOWI(MI);
+ return lowerFPTRUNC(MI);
+ case G_FPOWI:
+ return lowerFPOWI(MI);
case G_SMIN:
case G_SMAX:
case G_UMIN:
case G_UMAX:
- return lowerMinMax(MI);
+ return lowerMinMax(MI);
case G_FCOPYSIGN:
- return lowerFCopySign(MI);
+ return lowerFCopySign(MI);
case G_FMINNUM:
case G_FMAXNUM:
return lowerFMinNumMaxNum(MI);
@@ -3082,9 +3082,9 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
MI.eraseFromParent();
return Legalized;
}
- case G_EXTRACT_VECTOR_ELT:
- case G_INSERT_VECTOR_ELT:
- return lowerExtractInsertVectorElt(MI);
+ case G_EXTRACT_VECTOR_ELT:
+ case G_INSERT_VECTOR_ELT:
+ return lowerExtractInsertVectorElt(MI);
case G_SHUFFLE_VECTOR:
return lowerShuffleVector(MI);
case G_DYN_STACKALLOC:
@@ -3100,123 +3100,123 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
case G_READ_REGISTER:
case G_WRITE_REGISTER:
return lowerReadWriteRegister(MI);
- case G_UADDSAT:
- case G_USUBSAT: {
- // Try to make a reasonable guess about which lowering strategy to use. The
- // target can override this with custom lowering and calling the
- // implementation functions.
- LLT Ty = MRI.getType(MI.getOperand(0).getReg());
- if (LI.isLegalOrCustom({G_UMIN, Ty}))
- return lowerAddSubSatToMinMax(MI);
- return lowerAddSubSatToAddoSubo(MI);
- }
- case G_SADDSAT:
- case G_SSUBSAT: {
- LLT Ty = MRI.getType(MI.getOperand(0).getReg());
-
- // FIXME: It would probably make more sense to see if G_SADDO is preferred,
- // since it's a shorter expansion. However, we would need to figure out the
- // preferred boolean type for the carry out for the query.
- if (LI.isLegalOrCustom({G_SMIN, Ty}) && LI.isLegalOrCustom({G_SMAX, Ty}))
- return lowerAddSubSatToMinMax(MI);
- return lowerAddSubSatToAddoSubo(MI);
- }
- case G_SSHLSAT:
- case G_USHLSAT:
- return lowerShlSat(MI);
- case G_ABS: {
- // Expand %res = G_ABS %a into:
- // %v1 = G_ASHR %a, scalar_size-1
- // %v2 = G_ADD %a, %v1
- // %res = G_XOR %v2, %v1
- LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
- Register OpReg = MI.getOperand(1).getReg();
- auto ShiftAmt =
- MIRBuilder.buildConstant(DstTy, DstTy.getScalarSizeInBits() - 1);
- auto Shift =
- MIRBuilder.buildAShr(DstTy, OpReg, ShiftAmt);
- auto Add = MIRBuilder.buildAdd(DstTy, OpReg, Shift);
- MIRBuilder.buildXor(MI.getOperand(0).getReg(), Add, Shift);
- MI.eraseFromParent();
- return Legalized;
- }
- case G_SELECT:
- return lowerSelect(MI);
- }
+ case G_UADDSAT:
+ case G_USUBSAT: {
+ // Try to make a reasonable guess about which lowering strategy to use. The
+ // target can override this with custom lowering and calling the
+ // implementation functions.
+ LLT Ty = MRI.getType(MI.getOperand(0).getReg());
+ if (LI.isLegalOrCustom({G_UMIN, Ty}))
+ return lowerAddSubSatToMinMax(MI);
+ return lowerAddSubSatToAddoSubo(MI);
+ }
+ case G_SADDSAT:
+ case G_SSUBSAT: {
+ LLT Ty = MRI.getType(MI.getOperand(0).getReg());
+
+ // FIXME: It would probably make more sense to see if G_SADDO is preferred,
+ // since it's a shorter expansion. However, we would need to figure out the
+ // preferred boolean type for the carry out for the query.
+ if (LI.isLegalOrCustom({G_SMIN, Ty}) && LI.isLegalOrCustom({G_SMAX, Ty}))
+ return lowerAddSubSatToMinMax(MI);
+ return lowerAddSubSatToAddoSubo(MI);
+ }
+ case G_SSHLSAT:
+ case G_USHLSAT:
+ return lowerShlSat(MI);
+ case G_ABS: {
+ // Expand %res = G_ABS %a into:
+ // %v1 = G_ASHR %a, scalar_size-1
+ // %v2 = G_ADD %a, %v1
+ // %res = G_XOR %v2, %v1
+ LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
+ Register OpReg = MI.getOperand(1).getReg();
+ auto ShiftAmt =
+ MIRBuilder.buildConstant(DstTy, DstTy.getScalarSizeInBits() - 1);
+ auto Shift =
+ MIRBuilder.buildAShr(DstTy, OpReg, ShiftAmt);
+ auto Add = MIRBuilder.buildAdd(DstTy, OpReg, Shift);
+ MIRBuilder.buildXor(MI.getOperand(0).getReg(), Add, Shift);
+ MI.eraseFromParent();
+ return Legalized;
+ }
+ case G_SELECT:
+ return lowerSelect(MI);
+ }
+}
+
+Align LegalizerHelper::getStackTemporaryAlignment(LLT Ty,
+ Align MinAlign) const {
+ // FIXME: We're missing a way to go back from LLT to llvm::Type to query the
+ // datalayout for the preferred alignment. Also there should be a target hook
+ // for this to allow targets to reduce the alignment and ignore the
+ // datalayout. e.g. AMDGPU should always use a 4-byte alignment, regardless of
+ // the type.
+ return std::max(Align(PowerOf2Ceil(Ty.getSizeInBytes())), MinAlign);
+}
+
+MachineInstrBuilder
+LegalizerHelper::createStackTemporary(TypeSize Bytes, Align Alignment,
+ MachinePointerInfo &PtrInfo) {
+ MachineFunction &MF = MIRBuilder.getMF();
+ const DataLayout &DL = MIRBuilder.getDataLayout();
+ int FrameIdx = MF.getFrameInfo().CreateStackObject(Bytes, Alignment, false);
+
+ unsigned AddrSpace = DL.getAllocaAddrSpace();
+ LLT FramePtrTy = LLT::pointer(AddrSpace, DL.getPointerSizeInBits(AddrSpace));
+
+ PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIdx);
+ return MIRBuilder.buildFrameIndex(FramePtrTy, FrameIdx);
+}
+
+static Register clampDynamicVectorIndex(MachineIRBuilder &B, Register IdxReg,
+ LLT VecTy) {
+ int64_t IdxVal;
+ if (mi_match(IdxReg, *B.getMRI(), m_ICst(IdxVal)))
+ return IdxReg;
+
+ LLT IdxTy = B.getMRI()->getType(IdxReg);
+ unsigned NElts = VecTy.getNumElements();
+ if (isPowerOf2_32(NElts)) {
+ APInt Imm = APInt::getLowBitsSet(IdxTy.getSizeInBits(), Log2_32(NElts));
+ return B.buildAnd(IdxTy, IdxReg, B.buildConstant(IdxTy, Imm)).getReg(0);
+ }
+
+ return B.buildUMin(IdxTy, IdxReg, B.buildConstant(IdxTy, NElts - 1))
+ .getReg(0);
+}
+
+Register LegalizerHelper::getVectorElementPointer(Register VecPtr, LLT VecTy,
+ Register Index) {
+ LLT EltTy = VecTy.getElementType();
+
+ // Calculate the element offset and add it to the pointer.
+ unsigned EltSize = EltTy.getSizeInBits() / 8; // FIXME: should be ABI size.
+ assert(EltSize * 8 == EltTy.getSizeInBits() &&
+ "Converting bits to bytes lost precision");
+
+ Index = clampDynamicVectorIndex(MIRBuilder, Index, VecTy);
+
+ LLT IdxTy = MRI.getType(Index);
+ auto Mul = MIRBuilder.buildMul(IdxTy, Index,
+ MIRBuilder.buildConstant(IdxTy, EltSize));
+
+ LLT PtrTy = MRI.getType(VecPtr);
+ return MIRBuilder.buildPtrAdd(PtrTy, VecPtr, Mul).getReg(0);
}
-Align LegalizerHelper::getStackTemporaryAlignment(LLT Ty,
- Align MinAlign) const {
- // FIXME: We're missing a way to go back from LLT to llvm::Type to query the
- // datalayout for the preferred alignment. Also there should be a target hook
- // for this to allow targets to reduce the alignment and ignore the
- // datalayout. e.g. AMDGPU should always use a 4-byte alignment, regardless of
- // the type.
- return std::max(Align(PowerOf2Ceil(Ty.getSizeInBytes())), MinAlign);
-}
-
-MachineInstrBuilder
-LegalizerHelper::createStackTemporary(TypeSize Bytes, Align Alignment,
- MachinePointerInfo &PtrInfo) {
- MachineFunction &MF = MIRBuilder.getMF();
- const DataLayout &DL = MIRBuilder.getDataLayout();
- int FrameIdx = MF.getFrameInfo().CreateStackObject(Bytes, Alignment, false);
-
- unsigned AddrSpace = DL.getAllocaAddrSpace();
- LLT FramePtrTy = LLT::pointer(AddrSpace, DL.getPointerSizeInBits(AddrSpace));
-
- PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIdx);
- return MIRBuilder.buildFrameIndex(FramePtrTy, FrameIdx);
-}
-
-static Register clampDynamicVectorIndex(MachineIRBuilder &B, Register IdxReg,
- LLT VecTy) {
- int64_t IdxVal;
- if (mi_match(IdxReg, *B.getMRI(), m_ICst(IdxVal)))
- return IdxReg;
-
- LLT IdxTy = B.getMRI()->getType(IdxReg);
- unsigned NElts = VecTy.getNumElements();
- if (isPowerOf2_32(NElts)) {
- APInt Imm = APInt::getLowBitsSet(IdxTy.getSizeInBits(), Log2_32(NElts));
- return B.buildAnd(IdxTy, IdxReg, B.buildConstant(IdxTy, Imm)).getReg(0);
- }
-
- return B.buildUMin(IdxTy, IdxReg, B.buildConstant(IdxTy, NElts - 1))
- .getReg(0);
-}
-
-Register LegalizerHelper::getVectorElementPointer(Register VecPtr, LLT VecTy,
- Register Index) {
- LLT EltTy = VecTy.getElementType();
-
- // Calculate the element offset and add it to the pointer.
- unsigned EltSize = EltTy.getSizeInBits() / 8; // FIXME: should be ABI size.
- assert(EltSize * 8 == EltTy.getSizeInBits() &&
- "Converting bits to bytes lost precision");
-
- Index = clampDynamicVectorIndex(MIRBuilder, Index, VecTy);
-
- LLT IdxTy = MRI.getType(Index);
- auto Mul = MIRBuilder.buildMul(IdxTy, Index,
- MIRBuilder.buildConstant(IdxTy, EltSize));
-
- LLT PtrTy = MRI.getType(VecPtr);
- return MIRBuilder.buildPtrAdd(PtrTy, VecPtr, Mul).getReg(0);
-}
-
LegalizerHelper::LegalizeResult LegalizerHelper::fewerElementsVectorImplicitDef(
MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy) {
Register DstReg = MI.getOperand(0).getReg();
- LLT DstTy = MRI.getType(DstReg);
- LLT LCMTy = getLCMType(DstTy, NarrowTy);
+ LLT DstTy = MRI.getType(DstReg);
+ LLT LCMTy = getLCMType(DstTy, NarrowTy);
- unsigned NumParts = LCMTy.getSizeInBits() / NarrowTy.getSizeInBits();
+ unsigned NumParts = LCMTy.getSizeInBits() / NarrowTy.getSizeInBits();
- auto NewUndef = MIRBuilder.buildUndef(NarrowTy);
- SmallVector<Register, 8> Parts(NumParts, NewUndef.getReg(0));
+ auto NewUndef = MIRBuilder.buildUndef(NarrowTy);
+ SmallVector<Register, 8> Parts(NumParts, NewUndef.getReg(0));
- buildWidenedRemergeToDst(DstReg, LCMTy, Parts);
+ buildWidenedRemergeToDst(DstReg, LCMTy, Parts);
MI.eraseFromParent();
return Legalized;
}
@@ -3337,7 +3337,7 @@ LegalizerHelper::fewerElementsVectorCasts(MachineInstr &MI, unsigned TypeIdx,
if (NumParts * NarrowTy.getNumElements() != DstTy.getNumElements())
return UnableToLegalize;
- NarrowTy1 = LLT::vector(NarrowTy.getNumElements(), SrcTy.getElementType());
+ NarrowTy1 = LLT::vector(NarrowTy.getNumElements(), SrcTy.getElementType());
} else {
NumParts = DstTy.getNumElements();
NarrowTy1 = SrcTy.getElementType();
@@ -3610,116 +3610,116 @@ LegalizerHelper::fewerElementsVectorUnmergeValues(MachineInstr &MI,
return Legalized;
}
-// Handle FewerElementsVector a G_BUILD_VECTOR or G_CONCAT_VECTORS that produces
-// a vector
-//
-// Create a G_BUILD_VECTOR or G_CONCAT_VECTORS of NarrowTy pieces, padding with
-// undef as necessary.
-//
-// %3:_(<3 x s16>) = G_BUILD_VECTOR %0, %1, %2
-// -> <2 x s16>
-//
-// %4:_(s16) = G_IMPLICIT_DEF
-// %5:_(<2 x s16>) = G_BUILD_VECTOR %0, %1
-// %6:_(<2 x s16>) = G_BUILD_VECTOR %2, %4
-// %7:_(<2 x s16>) = G_IMPLICIT_DEF
-// %8:_(<6 x s16>) = G_CONCAT_VECTORS %5, %6, %7
-// %3:_(<3 x s16>), %8:_(<3 x s16>) = G_UNMERGE_VALUES %8
+// Handle FewerElementsVector a G_BUILD_VECTOR or G_CONCAT_VECTORS that produces
+// a vector
+//
+// Create a G_BUILD_VECTOR or G_CONCAT_VECTORS of NarrowTy pieces, padding with
+// undef as necessary.
+//
+// %3:_(<3 x s16>) = G_BUILD_VECTOR %0, %1, %2
+// -> <2 x s16>
+//
+// %4:_(s16) = G_IMPLICIT_DEF
+// %5:_(<2 x s16>) = G_BUILD_VECTOR %0, %1
+// %6:_(<2 x s16>) = G_BUILD_VECTOR %2, %4
+// %7:_(<2 x s16>) = G_IMPLICIT_DEF
+// %8:_(<6 x s16>) = G_CONCAT_VECTORS %5, %6, %7
+// %3:_(<3 x s16>), %8:_(<3 x s16>) = G_UNMERGE_VALUES %8
LegalizerHelper::LegalizeResult
-LegalizerHelper::fewerElementsVectorMerge(MachineInstr &MI, unsigned TypeIdx,
- LLT NarrowTy) {
+LegalizerHelper::fewerElementsVectorMerge(MachineInstr &MI, unsigned TypeIdx,
+ LLT NarrowTy) {
Register DstReg = MI.getOperand(0).getReg();
LLT DstTy = MRI.getType(DstReg);
- LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
- LLT GCDTy = getGCDType(getGCDType(SrcTy, NarrowTy), DstTy);
-
- // Break into a common type
- SmallVector<Register, 16> Parts;
- for (unsigned I = 1, E = MI.getNumOperands(); I != E; ++I)
- extractGCDType(Parts, GCDTy, MI.getOperand(I).getReg());
-
- // Build the requested new merge, padding with undef.
- LLT LCMTy = buildLCMMergePieces(DstTy, NarrowTy, GCDTy, Parts,
- TargetOpcode::G_ANYEXT);
-
- // Pack into the original result register.
- buildWidenedRemergeToDst(DstReg, LCMTy, Parts);
-
- MI.eraseFromParent();
- return Legalized;
-}
-
-LegalizerHelper::LegalizeResult
-LegalizerHelper::fewerElementsVectorExtractInsertVectorElt(MachineInstr &MI,
- unsigned TypeIdx,
- LLT NarrowVecTy) {
- Register DstReg = MI.getOperand(0).getReg();
- Register SrcVec = MI.getOperand(1).getReg();
- Register InsertVal;
- bool IsInsert = MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT;
-
- assert((IsInsert ? TypeIdx == 0 : TypeIdx == 1) && "not a vector type index");
- if (IsInsert)
- InsertVal = MI.getOperand(2).getReg();
-
- Register Idx = MI.getOperand(MI.getNumOperands() - 1).getReg();
-
- // TODO: Handle total scalarization case.
- if (!NarrowVecTy.isVector())
- return UnableToLegalize;
-
- LLT VecTy = MRI.getType(SrcVec);
-
- // If the index is a constant, we can really break this down as you would
- // expect, and index into the target size pieces.
- int64_t IdxVal;
- if (mi_match(Idx, MRI, m_ICst(IdxVal))) {
- // Avoid out of bounds indexing the pieces.
- if (IdxVal >= VecTy.getNumElements()) {
- MIRBuilder.buildUndef(DstReg);
- MI.eraseFromParent();
- return Legalized;
+ LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
+ LLT GCDTy = getGCDType(getGCDType(SrcTy, NarrowTy), DstTy);
+
+ // Break into a common type
+ SmallVector<Register, 16> Parts;
+ for (unsigned I = 1, E = MI.getNumOperands(); I != E; ++I)
+ extractGCDType(Parts, GCDTy, MI.getOperand(I).getReg());
+
+ // Build the requested new merge, padding with undef.
+ LLT LCMTy = buildLCMMergePieces(DstTy, NarrowTy, GCDTy, Parts,
+ TargetOpcode::G_ANYEXT);
+
+ // Pack into the original result register.
+ buildWidenedRemergeToDst(DstReg, LCMTy, Parts);
+
+ MI.eraseFromParent();
+ return Legalized;
+}
+
+LegalizerHelper::LegalizeResult
+LegalizerHelper::fewerElementsVectorExtractInsertVectorElt(MachineInstr &MI,
+ unsigned TypeIdx,
+ LLT NarrowVecTy) {
+ Register DstReg = MI.getOperand(0).getReg();
+ Register SrcVec = MI.getOperand(1).getReg();
+ Register InsertVal;
+ bool IsInsert = MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT;
+
+ assert((IsInsert ? TypeIdx == 0 : TypeIdx == 1) && "not a vector type index");
+ if (IsInsert)
+ InsertVal = MI.getOperand(2).getReg();
+
+ Register Idx = MI.getOperand(MI.getNumOperands() - 1).getReg();
+
+ // TODO: Handle total scalarization case.
+ if (!NarrowVecTy.isVector())
+ return UnableToLegalize;
+
+ LLT VecTy = MRI.getType(SrcVec);
+
+ // If the index is a constant, we can really break this down as you would
+ // expect, and index into the target size pieces.
+ int64_t IdxVal;
+ if (mi_match(Idx, MRI, m_ICst(IdxVal))) {
+ // Avoid out of bounds indexing the pieces.
+ if (IdxVal >= VecTy.getNumElements()) {
+ MIRBuilder.buildUndef(DstReg);
+ MI.eraseFromParent();
+ return Legalized;
}
- SmallVector<Register, 8> VecParts;
- LLT GCDTy = extractGCDType(VecParts, VecTy, NarrowVecTy, SrcVec);
-
- // Build a sequence of NarrowTy pieces in VecParts for this operand.
- LLT LCMTy = buildLCMMergePieces(VecTy, NarrowVecTy, GCDTy, VecParts,
- TargetOpcode::G_ANYEXT);
-
- unsigned NewNumElts = NarrowVecTy.getNumElements();
-
- LLT IdxTy = MRI.getType(Idx);
- int64_t PartIdx = IdxVal / NewNumElts;
- auto NewIdx =
- MIRBuilder.buildConstant(IdxTy, IdxVal - NewNumElts * PartIdx);
-
- if (IsInsert) {
- LLT PartTy = MRI.getType(VecParts[PartIdx]);
-
- // Use the adjusted index to insert into one of the subvectors.
- auto InsertPart = MIRBuilder.buildInsertVectorElement(
- PartTy, VecParts[PartIdx], InsertVal, NewIdx);
- VecParts[PartIdx] = InsertPart.getReg(0);
-
- // Recombine the inserted subvector with the others to reform the result
- // vector.
- buildWidenedRemergeToDst(DstReg, LCMTy, VecParts);
- } else {
- MIRBuilder.buildExtractVectorElement(DstReg, VecParts[PartIdx], NewIdx);
- }
-
- MI.eraseFromParent();
- return Legalized;
- }
-
- // With a variable index, we can't perform the operation in a smaller type, so
- // we're forced to expand this.
- //
- // TODO: We could emit a chain of compare/select to figure out which piece to
- // index.
- return lowerExtractInsertVectorElt(MI);
+ SmallVector<Register, 8> VecParts;
+ LLT GCDTy = extractGCDType(VecParts, VecTy, NarrowVecTy, SrcVec);
+
+ // Build a sequence of NarrowTy pieces in VecParts for this operand.
+ LLT LCMTy = buildLCMMergePieces(VecTy, NarrowVecTy, GCDTy, VecParts,
+ TargetOpcode::G_ANYEXT);
+
+ unsigned NewNumElts = NarrowVecTy.getNumElements();
+
+ LLT IdxTy = MRI.getType(Idx);
+ int64_t PartIdx = IdxVal / NewNumElts;
+ auto NewIdx =
+ MIRBuilder.buildConstant(IdxTy, IdxVal - NewNumElts * PartIdx);
+
+ if (IsInsert) {
+ LLT PartTy = MRI.getType(VecParts[PartIdx]);
+
+ // Use the adjusted index to insert into one of the subvectors.
+ auto InsertPart = MIRBuilder.buildInsertVectorElement(
+ PartTy, VecParts[PartIdx], InsertVal, NewIdx);
+ VecParts[PartIdx] = InsertPart.getReg(0);
+
+ // Recombine the inserted subvector with the others to reform the result
+ // vector.
+ buildWidenedRemergeToDst(DstReg, LCMTy, VecParts);
+ } else {
+ MIRBuilder.buildExtractVectorElement(DstReg, VecParts[PartIdx], NewIdx);
+ }
+
+ MI.eraseFromParent();
+ return Legalized;
+ }
+
+ // With a variable index, we can't perform the operation in a smaller type, so
+ // we're forced to expand this.
+ //
+ // TODO: We could emit a chain of compare/select to figure out which piece to
+ // index.
+ return lowerExtractInsertVectorElt(MI);
}
LegalizerHelper::LegalizeResult
@@ -3765,8 +3765,8 @@ LegalizerHelper::reduceLoadStoreWidth(MachineInstr &MI, unsigned TypeIdx,
if (NumParts == -1)
return UnableToLegalize;
- LLT PtrTy = MRI.getType(AddrReg);
- const LLT OffsetTy = LLT::scalar(PtrTy.getSizeInBits());
+ LLT PtrTy = MRI.getType(AddrReg);
+ const LLT OffsetTy = LLT::scalar(PtrTy.getSizeInBits());
unsigned TotalSize = ValTy.getSizeInBits();
@@ -3964,7 +3964,7 @@ LegalizerHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
case G_ADD:
case G_SUB:
case G_MUL:
- case G_PTR_ADD:
+ case G_PTR_ADD:
case G_SMULH:
case G_UMULH:
case G_FADD:
@@ -3988,7 +3988,7 @@ LegalizerHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
case G_FFLOOR:
case G_FRINT:
case G_INTRINSIC_ROUND:
- case G_INTRINSIC_ROUNDEVEN:
+ case G_INTRINSIC_ROUNDEVEN:
case G_INTRINSIC_TRUNC:
case G_FCOS:
case G_FSIN:
@@ -4020,8 +4020,8 @@ LegalizerHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
case G_SHL:
case G_LSHR:
case G_ASHR:
- case G_SSHLSAT:
- case G_USHLSAT:
+ case G_SSHLSAT:
+ case G_USHLSAT:
case G_CTLZ:
case G_CTLZ_ZERO_UNDEF:
case G_CTTZ:
@@ -4052,15 +4052,15 @@ LegalizerHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
case G_UNMERGE_VALUES:
return fewerElementsVectorUnmergeValues(MI, TypeIdx, NarrowTy);
case G_BUILD_VECTOR:
- assert(TypeIdx == 0 && "not a vector type index");
- return fewerElementsVectorMerge(MI, TypeIdx, NarrowTy);
- case G_CONCAT_VECTORS:
- if (TypeIdx != 1) // TODO: This probably does work as expected already.
- return UnableToLegalize;
- return fewerElementsVectorMerge(MI, TypeIdx, NarrowTy);
- case G_EXTRACT_VECTOR_ELT:
- case G_INSERT_VECTOR_ELT:
- return fewerElementsVectorExtractInsertVectorElt(MI, TypeIdx, NarrowTy);
+ assert(TypeIdx == 0 && "not a vector type index");
+ return fewerElementsVectorMerge(MI, TypeIdx, NarrowTy);
+ case G_CONCAT_VECTORS:
+ if (TypeIdx != 1) // TODO: This probably does work as expected already.
+ return UnableToLegalize;
+ return fewerElementsVectorMerge(MI, TypeIdx, NarrowTy);
+ case G_EXTRACT_VECTOR_ELT:
+ case G_INSERT_VECTOR_ELT:
+ return fewerElementsVectorExtractInsertVectorElt(MI, TypeIdx, NarrowTy);
case G_LOAD:
case G_STORE:
return reduceLoadStoreWidth(MI, TypeIdx, NarrowTy);
@@ -4484,31 +4484,31 @@ LegalizerHelper::narrowScalarMul(MachineInstr &MI, LLT NarrowTy) {
}
LegalizerHelper::LegalizeResult
-LegalizerHelper::narrowScalarFPTOI(MachineInstr &MI, unsigned TypeIdx,
- LLT NarrowTy) {
- if (TypeIdx != 0)
- return UnableToLegalize;
-
- bool IsSigned = MI.getOpcode() == TargetOpcode::G_FPTOSI;
-
- Register Src = MI.getOperand(1).getReg();
- LLT SrcTy = MRI.getType(Src);
-
- // If all finite floats fit into the narrowed integer type, we can just swap
- // out the result type. This is practically only useful for conversions from
- // half to at least 16-bits, so just handle the one case.
- if (SrcTy.getScalarType() != LLT::scalar(16) ||
- NarrowTy.getScalarSizeInBits() < (IsSigned ? 17 : 16))
- return UnableToLegalize;
-
- Observer.changingInstr(MI);
- narrowScalarDst(MI, NarrowTy, 0,
- IsSigned ? TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT);
- Observer.changedInstr(MI);
- return Legalized;
-}
-
-LegalizerHelper::LegalizeResult
+LegalizerHelper::narrowScalarFPTOI(MachineInstr &MI, unsigned TypeIdx,
+ LLT NarrowTy) {
+ if (TypeIdx != 0)
+ return UnableToLegalize;
+
+ bool IsSigned = MI.getOpcode() == TargetOpcode::G_FPTOSI;
+
+ Register Src = MI.getOperand(1).getReg();
+ LLT SrcTy = MRI.getType(Src);
+
+ // If all finite floats fit into the narrowed integer type, we can just swap
+ // out the result type. This is practically only useful for conversions from
+ // half to at least 16-bits, so just handle the one case.
+ if (SrcTy.getScalarType() != LLT::scalar(16) ||
+ NarrowTy.getScalarSizeInBits() < (IsSigned ? 17 : 16))
+ return UnableToLegalize;
+
+ Observer.changingInstr(MI);
+ narrowScalarDst(MI, NarrowTy, 0,
+ IsSigned ? TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT);
+ Observer.changedInstr(MI);
+ return Legalized;
+}
+
+LegalizerHelper::LegalizeResult
LegalizerHelper::narrowScalarExtract(MachineInstr &MI, unsigned TypeIdx,
LLT NarrowTy) {
if (TypeIdx != 1)
@@ -4857,9 +4857,9 @@ LegalizerHelper::narrowScalarCTPOP(MachineInstr &MI, unsigned TypeIdx,
}
LegalizerHelper::LegalizeResult
-LegalizerHelper::lowerBitCount(MachineInstr &MI) {
+LegalizerHelper::lowerBitCount(MachineInstr &MI) {
unsigned Opc = MI.getOpcode();
- const auto &TII = MIRBuilder.getTII();
+ const auto &TII = MIRBuilder.getTII();
auto isSupported = [this](const LegalityQuery &Q) {
auto QAction = LI.getAction(Q).Action;
return QAction == Legal || QAction == Libcall || QAction == Custom;
@@ -4947,15 +4947,15 @@ LegalizerHelper::lowerBitCount(MachineInstr &MI) {
// unless the target has ctlz but not ctpop, in which case we use:
// { return 32 - nlz(~x & (x-1)); }
// Ref: "Hacker's Delight" by Henry Warren
- auto MIBCstNeg1 = MIRBuilder.buildConstant(SrcTy, -1);
- auto MIBNot = MIRBuilder.buildXor(SrcTy, SrcReg, MIBCstNeg1);
+ auto MIBCstNeg1 = MIRBuilder.buildConstant(SrcTy, -1);
+ auto MIBNot = MIRBuilder.buildXor(SrcTy, SrcReg, MIBCstNeg1);
auto MIBTmp = MIRBuilder.buildAnd(
- SrcTy, MIBNot, MIRBuilder.buildAdd(SrcTy, SrcReg, MIBCstNeg1));
- if (!isSupported({TargetOpcode::G_CTPOP, {SrcTy, SrcTy}}) &&
- isSupported({TargetOpcode::G_CTLZ, {SrcTy, SrcTy}})) {
- auto MIBCstLen = MIRBuilder.buildConstant(SrcTy, Len);
+ SrcTy, MIBNot, MIRBuilder.buildAdd(SrcTy, SrcReg, MIBCstNeg1));
+ if (!isSupported({TargetOpcode::G_CTPOP, {SrcTy, SrcTy}}) &&
+ isSupported({TargetOpcode::G_CTLZ, {SrcTy, SrcTy}})) {
+ auto MIBCstLen = MIRBuilder.buildConstant(SrcTy, Len);
MIRBuilder.buildSub(MI.getOperand(0), MIBCstLen,
- MIRBuilder.buildCTLZ(SrcTy, MIBTmp));
+ MIRBuilder.buildCTLZ(SrcTy, MIBTmp));
MI.eraseFromParent();
return Legalized;
}
@@ -4964,8 +4964,8 @@ LegalizerHelper::lowerBitCount(MachineInstr &MI) {
return Legalized;
}
case TargetOpcode::G_CTPOP: {
- Register SrcReg = MI.getOperand(1).getReg();
- LLT Ty = MRI.getType(SrcReg);
+ Register SrcReg = MI.getOperand(1).getReg();
+ LLT Ty = MRI.getType(SrcReg);
unsigned Size = Ty.getSizeInBits();
MachineIRBuilder &B = MIRBuilder;
@@ -4975,11 +4975,11 @@ LegalizerHelper::lowerBitCount(MachineInstr &MI) {
// B2Count = val - { (val >> 1) & 0x55555555 }
// since it gives same result in blocks of 2 with one instruction less.
auto C_1 = B.buildConstant(Ty, 1);
- auto B2Set1LoTo1Hi = B.buildLShr(Ty, SrcReg, C_1);
+ auto B2Set1LoTo1Hi = B.buildLShr(Ty, SrcReg, C_1);
APInt B2Mask1HiTo0 = APInt::getSplat(Size, APInt(8, 0x55));
auto C_B2Mask1HiTo0 = B.buildConstant(Ty, B2Mask1HiTo0);
auto B2Count1Hi = B.buildAnd(Ty, B2Set1LoTo1Hi, C_B2Mask1HiTo0);
- auto B2Count = B.buildSub(Ty, SrcReg, B2Count1Hi);
+ auto B2Count = B.buildSub(Ty, SrcReg, B2Count1Hi);
// In order to get count in blocks of 4 add values from adjacent block of 2.
// B4Count = { B2Count & 0x33333333 } + { (B2Count >> 2) & 0x33333333 }
@@ -5078,7 +5078,7 @@ LegalizerHelper::lowerU64ToF32BitOps(MachineInstr &MI) {
return Legalized;
}
-LegalizerHelper::LegalizeResult LegalizerHelper::lowerUITOFP(MachineInstr &MI) {
+LegalizerHelper::LegalizeResult LegalizerHelper::lowerUITOFP(MachineInstr &MI) {
Register Dst = MI.getOperand(0).getReg();
Register Src = MI.getOperand(1).getReg();
LLT DstTy = MRI.getType(Dst);
@@ -5106,7 +5106,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerUITOFP(MachineInstr &MI) {
return UnableToLegalize;
}
-LegalizerHelper::LegalizeResult LegalizerHelper::lowerSITOFP(MachineInstr &MI) {
+LegalizerHelper::LegalizeResult LegalizerHelper::lowerSITOFP(MachineInstr &MI) {
Register Dst = MI.getOperand(0).getReg();
Register Src = MI.getOperand(1).getReg();
LLT DstTy = MRI.getType(Dst);
@@ -5152,7 +5152,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerSITOFP(MachineInstr &MI) {
return UnableToLegalize;
}
-LegalizerHelper::LegalizeResult LegalizerHelper::lowerFPTOUI(MachineInstr &MI) {
+LegalizerHelper::LegalizeResult LegalizerHelper::lowerFPTOUI(MachineInstr &MI) {
Register Dst = MI.getOperand(0).getReg();
Register Src = MI.getOperand(1).getReg();
LLT DstTy = MRI.getType(Dst);
@@ -5369,7 +5369,7 @@ LegalizerHelper::lowerFPTRUNC_F64_TO_F16(MachineInstr &MI) {
}
LegalizerHelper::LegalizeResult
-LegalizerHelper::lowerFPTRUNC(MachineInstr &MI) {
+LegalizerHelper::lowerFPTRUNC(MachineInstr &MI) {
Register Dst = MI.getOperand(0).getReg();
Register Src = MI.getOperand(1).getReg();
@@ -5384,20 +5384,20 @@ LegalizerHelper::lowerFPTRUNC(MachineInstr &MI) {
return UnableToLegalize;
}
-// TODO: If RHS is a constant SelectionDAGBuilder expands this into a
-// multiplication tree.
-LegalizerHelper::LegalizeResult LegalizerHelper::lowerFPOWI(MachineInstr &MI) {
- Register Dst = MI.getOperand(0).getReg();
- Register Src0 = MI.getOperand(1).getReg();
- Register Src1 = MI.getOperand(2).getReg();
- LLT Ty = MRI.getType(Dst);
-
- auto CvtSrc1 = MIRBuilder.buildSITOFP(Ty, Src1);
- MIRBuilder.buildFPow(Dst, Src0, CvtSrc1, MI.getFlags());
- MI.eraseFromParent();
- return Legalized;
-}
-
+// TODO: If RHS is a constant SelectionDAGBuilder expands this into a
+// multiplication tree.
+LegalizerHelper::LegalizeResult LegalizerHelper::lowerFPOWI(MachineInstr &MI) {
+ Register Dst = MI.getOperand(0).getReg();
+ Register Src0 = MI.getOperand(1).getReg();
+ Register Src1 = MI.getOperand(2).getReg();
+ LLT Ty = MRI.getType(Dst);
+
+ auto CvtSrc1 = MIRBuilder.buildSITOFP(Ty, Src1);
+ MIRBuilder.buildFPow(Dst, Src0, CvtSrc1, MI.getFlags());
+ MI.eraseFromParent();
+ return Legalized;
+}
+
static CmpInst::Predicate minMaxToCompare(unsigned Opc) {
switch (Opc) {
case TargetOpcode::G_SMIN:
@@ -5413,7 +5413,7 @@ static CmpInst::Predicate minMaxToCompare(unsigned Opc) {
}
}
-LegalizerHelper::LegalizeResult LegalizerHelper::lowerMinMax(MachineInstr &MI) {
+LegalizerHelper::LegalizeResult LegalizerHelper::lowerMinMax(MachineInstr &MI) {
Register Dst = MI.getOperand(0).getReg();
Register Src0 = MI.getOperand(1).getReg();
Register Src1 = MI.getOperand(2).getReg();
@@ -5429,7 +5429,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerMinMax(MachineInstr &MI) {
}
LegalizerHelper::LegalizeResult
-LegalizerHelper::lowerFCopySign(MachineInstr &MI) {
+LegalizerHelper::lowerFCopySign(MachineInstr &MI) {
Register Dst = MI.getOperand(0).getReg();
Register Src0 = MI.getOperand(1).getReg();
Register Src1 = MI.getOperand(2).getReg();
@@ -5651,72 +5651,72 @@ LegalizerHelper::lowerUnmergeValues(MachineInstr &MI) {
return Legalized;
}
-/// Lower a vector extract or insert by writing the vector to a stack temporary
-/// and reloading the element or vector.
-///
-/// %dst = G_EXTRACT_VECTOR_ELT %vec, %idx
-/// =>
-/// %stack_temp = G_FRAME_INDEX
-/// G_STORE %vec, %stack_temp
-/// %idx = clamp(%idx, %vec.getNumElements())
-/// %element_ptr = G_PTR_ADD %stack_temp, %idx
-/// %dst = G_LOAD %element_ptr
+/// Lower a vector extract or insert by writing the vector to a stack temporary
+/// and reloading the element or vector.
+///
+/// %dst = G_EXTRACT_VECTOR_ELT %vec, %idx
+/// =>
+/// %stack_temp = G_FRAME_INDEX
+/// G_STORE %vec, %stack_temp
+/// %idx = clamp(%idx, %vec.getNumElements())
+/// %element_ptr = G_PTR_ADD %stack_temp, %idx
+/// %dst = G_LOAD %element_ptr
+LegalizerHelper::LegalizeResult
+LegalizerHelper::lowerExtractInsertVectorElt(MachineInstr &MI) {
+ Register DstReg = MI.getOperand(0).getReg();
+ Register SrcVec = MI.getOperand(1).getReg();
+ Register InsertVal;
+ if (MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT)
+ InsertVal = MI.getOperand(2).getReg();
+
+ Register Idx = MI.getOperand(MI.getNumOperands() - 1).getReg();
+
+ LLT VecTy = MRI.getType(SrcVec);
+ LLT EltTy = VecTy.getElementType();
+ if (!EltTy.isByteSized()) { // Not implemented.
+ LLVM_DEBUG(dbgs() << "Can't handle non-byte element vectors yet\n");
+ return UnableToLegalize;
+ }
+
+ unsigned EltBytes = EltTy.getSizeInBytes();
+ Align VecAlign = getStackTemporaryAlignment(VecTy);
+ Align EltAlign;
+
+ MachinePointerInfo PtrInfo;
+ auto StackTemp = createStackTemporary(TypeSize::Fixed(VecTy.getSizeInBytes()),
+ VecAlign, PtrInfo);
+ MIRBuilder.buildStore(SrcVec, StackTemp, PtrInfo, VecAlign);
+
+ // Get the pointer to the element, and be sure not to hit undefined behavior
+ // if the index is out of bounds.
+ Register EltPtr = getVectorElementPointer(StackTemp.getReg(0), VecTy, Idx);
+
+ int64_t IdxVal;
+ if (mi_match(Idx, MRI, m_ICst(IdxVal))) {
+ int64_t Offset = IdxVal * EltBytes;
+ PtrInfo = PtrInfo.getWithOffset(Offset);
+ EltAlign = commonAlignment(VecAlign, Offset);
+ } else {
+ // We lose information with a variable offset.
+ EltAlign = getStackTemporaryAlignment(EltTy);
+ PtrInfo = MachinePointerInfo(MRI.getType(EltPtr).getAddressSpace());
+ }
+
+ if (InsertVal) {
+ // Write the inserted element
+ MIRBuilder.buildStore(InsertVal, EltPtr, PtrInfo, EltAlign);
+
+ // Reload the whole vector.
+ MIRBuilder.buildLoad(DstReg, StackTemp, PtrInfo, VecAlign);
+ } else {
+ MIRBuilder.buildLoad(DstReg, EltPtr, PtrInfo, EltAlign);
+ }
+
+ MI.eraseFromParent();
+ return Legalized;
+}
+
LegalizerHelper::LegalizeResult
-LegalizerHelper::lowerExtractInsertVectorElt(MachineInstr &MI) {
- Register DstReg = MI.getOperand(0).getReg();
- Register SrcVec = MI.getOperand(1).getReg();
- Register InsertVal;
- if (MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT)
- InsertVal = MI.getOperand(2).getReg();
-
- Register Idx = MI.getOperand(MI.getNumOperands() - 1).getReg();
-
- LLT VecTy = MRI.getType(SrcVec);
- LLT EltTy = VecTy.getElementType();
- if (!EltTy.isByteSized()) { // Not implemented.
- LLVM_DEBUG(dbgs() << "Can't handle non-byte element vectors yet\n");
- return UnableToLegalize;
- }
-
- unsigned EltBytes = EltTy.getSizeInBytes();
- Align VecAlign = getStackTemporaryAlignment(VecTy);
- Align EltAlign;
-
- MachinePointerInfo PtrInfo;
- auto StackTemp = createStackTemporary(TypeSize::Fixed(VecTy.getSizeInBytes()),
- VecAlign, PtrInfo);
- MIRBuilder.buildStore(SrcVec, StackTemp, PtrInfo, VecAlign);
-
- // Get the pointer to the element, and be sure not to hit undefined behavior
- // if the index is out of bounds.
- Register EltPtr = getVectorElementPointer(StackTemp.getReg(0), VecTy, Idx);
-
- int64_t IdxVal;
- if (mi_match(Idx, MRI, m_ICst(IdxVal))) {
- int64_t Offset = IdxVal * EltBytes;
- PtrInfo = PtrInfo.getWithOffset(Offset);
- EltAlign = commonAlignment(VecAlign, Offset);
- } else {
- // We lose information with a variable offset.
- EltAlign = getStackTemporaryAlignment(EltTy);
- PtrInfo = MachinePointerInfo(MRI.getType(EltPtr).getAddressSpace());
- }
-
- if (InsertVal) {
- // Write the inserted element
- MIRBuilder.buildStore(InsertVal, EltPtr, PtrInfo, EltAlign);
-
- // Reload the whole vector.
- MIRBuilder.buildLoad(DstReg, StackTemp, PtrInfo, VecAlign);
- } else {
- MIRBuilder.buildLoad(DstReg, EltPtr, PtrInfo, EltAlign);
- }
-
- MI.eraseFromParent();
- return Legalized;
-}
-
-LegalizerHelper::LegalizeResult
LegalizerHelper::lowerShuffleVector(MachineInstr &MI) {
Register DstReg = MI.getOperand(0).getReg();
Register Src0Reg = MI.getOperand(1).getReg();
@@ -5931,185 +5931,185 @@ LegalizerHelper::lowerSADDO_SSUBO(MachineInstr &MI) {
}
LegalizerHelper::LegalizeResult
-LegalizerHelper::lowerAddSubSatToMinMax(MachineInstr &MI) {
- Register Res = MI.getOperand(0).getReg();
- Register LHS = MI.getOperand(1).getReg();
- Register RHS = MI.getOperand(2).getReg();
- LLT Ty = MRI.getType(Res);
- bool IsSigned;
- bool IsAdd;
- unsigned BaseOp;
- switch (MI.getOpcode()) {
- default:
- llvm_unreachable("unexpected addsat/subsat opcode");
- case TargetOpcode::G_UADDSAT:
- IsSigned = false;
- IsAdd = true;
- BaseOp = TargetOpcode::G_ADD;
- break;
- case TargetOpcode::G_SADDSAT:
- IsSigned = true;
- IsAdd = true;
- BaseOp = TargetOpcode::G_ADD;
- break;
- case TargetOpcode::G_USUBSAT:
- IsSigned = false;
- IsAdd = false;
- BaseOp = TargetOpcode::G_SUB;
- break;
- case TargetOpcode::G_SSUBSAT:
- IsSigned = true;
- IsAdd = false;
- BaseOp = TargetOpcode::G_SUB;
- break;
- }
-
- if (IsSigned) {
- // sadd.sat(a, b) ->
- // hi = 0x7fffffff - smax(a, 0)
- // lo = 0x80000000 - smin(a, 0)
- // a + smin(smax(lo, b), hi)
- // ssub.sat(a, b) ->
- // lo = smax(a, -1) - 0x7fffffff
- // hi = smin(a, -1) - 0x80000000
- // a - smin(smax(lo, b), hi)
- // TODO: AMDGPU can use a "median of 3" instruction here:
- // a +/- med3(lo, b, hi)
- uint64_t NumBits = Ty.getScalarSizeInBits();
- auto MaxVal =
- MIRBuilder.buildConstant(Ty, APInt::getSignedMaxValue(NumBits));
- auto MinVal =
- MIRBuilder.buildConstant(Ty, APInt::getSignedMinValue(NumBits));
- MachineInstrBuilder Hi, Lo;
- if (IsAdd) {
- auto Zero = MIRBuilder.buildConstant(Ty, 0);
- Hi = MIRBuilder.buildSub(Ty, MaxVal, MIRBuilder.buildSMax(Ty, LHS, Zero));
- Lo = MIRBuilder.buildSub(Ty, MinVal, MIRBuilder.buildSMin(Ty, LHS, Zero));
- } else {
- auto NegOne = MIRBuilder.buildConstant(Ty, -1);
- Lo = MIRBuilder.buildSub(Ty, MIRBuilder.buildSMax(Ty, LHS, NegOne),
- MaxVal);
- Hi = MIRBuilder.buildSub(Ty, MIRBuilder.buildSMin(Ty, LHS, NegOne),
- MinVal);
- }
- auto RHSClamped =
- MIRBuilder.buildSMin(Ty, MIRBuilder.buildSMax(Ty, Lo, RHS), Hi);
- MIRBuilder.buildInstr(BaseOp, {Res}, {LHS, RHSClamped});
- } else {
- // uadd.sat(a, b) -> a + umin(~a, b)
- // usub.sat(a, b) -> a - umin(a, b)
- Register Not = IsAdd ? MIRBuilder.buildNot(Ty, LHS).getReg(0) : LHS;
- auto Min = MIRBuilder.buildUMin(Ty, Not, RHS);
- MIRBuilder.buildInstr(BaseOp, {Res}, {LHS, Min});
- }
-
- MI.eraseFromParent();
- return Legalized;
-}
-
-LegalizerHelper::LegalizeResult
-LegalizerHelper::lowerAddSubSatToAddoSubo(MachineInstr &MI) {
- Register Res = MI.getOperand(0).getReg();
- Register LHS = MI.getOperand(1).getReg();
- Register RHS = MI.getOperand(2).getReg();
- LLT Ty = MRI.getType(Res);
- LLT BoolTy = Ty.changeElementSize(1);
- bool IsSigned;
- bool IsAdd;
- unsigned OverflowOp;
- switch (MI.getOpcode()) {
- default:
- llvm_unreachable("unexpected addsat/subsat opcode");
- case TargetOpcode::G_UADDSAT:
- IsSigned = false;
- IsAdd = true;
- OverflowOp = TargetOpcode::G_UADDO;
- break;
- case TargetOpcode::G_SADDSAT:
- IsSigned = true;
- IsAdd = true;
- OverflowOp = TargetOpcode::G_SADDO;
- break;
- case TargetOpcode::G_USUBSAT:
- IsSigned = false;
- IsAdd = false;
- OverflowOp = TargetOpcode::G_USUBO;
- break;
- case TargetOpcode::G_SSUBSAT:
- IsSigned = true;
- IsAdd = false;
- OverflowOp = TargetOpcode::G_SSUBO;
- break;
- }
-
- auto OverflowRes =
- MIRBuilder.buildInstr(OverflowOp, {Ty, BoolTy}, {LHS, RHS});
- Register Tmp = OverflowRes.getReg(0);
- Register Ov = OverflowRes.getReg(1);
- MachineInstrBuilder Clamp;
- if (IsSigned) {
- // sadd.sat(a, b) ->
- // {tmp, ov} = saddo(a, b)
- // ov ? (tmp >>s 31) + 0x80000000 : r
- // ssub.sat(a, b) ->
- // {tmp, ov} = ssubo(a, b)
- // ov ? (tmp >>s 31) + 0x80000000 : r
- uint64_t NumBits = Ty.getScalarSizeInBits();
- auto ShiftAmount = MIRBuilder.buildConstant(Ty, NumBits - 1);
- auto Sign = MIRBuilder.buildAShr(Ty, Tmp, ShiftAmount);
- auto MinVal =
- MIRBuilder.buildConstant(Ty, APInt::getSignedMinValue(NumBits));
- Clamp = MIRBuilder.buildAdd(Ty, Sign, MinVal);
- } else {
- // uadd.sat(a, b) ->
- // {tmp, ov} = uaddo(a, b)
- // ov ? 0xffffffff : tmp
- // usub.sat(a, b) ->
- // {tmp, ov} = usubo(a, b)
- // ov ? 0 : tmp
- Clamp = MIRBuilder.buildConstant(Ty, IsAdd ? -1 : 0);
- }
- MIRBuilder.buildSelect(Res, Ov, Clamp, Tmp);
-
- MI.eraseFromParent();
- return Legalized;
-}
-
-LegalizerHelper::LegalizeResult
-LegalizerHelper::lowerShlSat(MachineInstr &MI) {
- assert((MI.getOpcode() == TargetOpcode::G_SSHLSAT ||
- MI.getOpcode() == TargetOpcode::G_USHLSAT) &&
- "Expected shlsat opcode!");
- bool IsSigned = MI.getOpcode() == TargetOpcode::G_SSHLSAT;
- Register Res = MI.getOperand(0).getReg();
- Register LHS = MI.getOperand(1).getReg();
- Register RHS = MI.getOperand(2).getReg();
- LLT Ty = MRI.getType(Res);
- LLT BoolTy = Ty.changeElementSize(1);
-
- unsigned BW = Ty.getScalarSizeInBits();
- auto Result = MIRBuilder.buildShl(Ty, LHS, RHS);
- auto Orig = IsSigned ? MIRBuilder.buildAShr(Ty, Result, RHS)
- : MIRBuilder.buildLShr(Ty, Result, RHS);
-
- MachineInstrBuilder SatVal;
- if (IsSigned) {
- auto SatMin = MIRBuilder.buildConstant(Ty, APInt::getSignedMinValue(BW));
- auto SatMax = MIRBuilder.buildConstant(Ty, APInt::getSignedMaxValue(BW));
- auto Cmp = MIRBuilder.buildICmp(CmpInst::ICMP_SLT, BoolTy, LHS,
- MIRBuilder.buildConstant(Ty, 0));
- SatVal = MIRBuilder.buildSelect(Ty, Cmp, SatMin, SatMax);
- } else {
- SatVal = MIRBuilder.buildConstant(Ty, APInt::getMaxValue(BW));
- }
- auto Ov = MIRBuilder.buildICmp(CmpInst::ICMP_NE, BoolTy, LHS, Orig);
- MIRBuilder.buildSelect(Res, Ov, SatVal, Result);
-
- MI.eraseFromParent();
- return Legalized;
-}
-
-LegalizerHelper::LegalizeResult
+LegalizerHelper::lowerAddSubSatToMinMax(MachineInstr &MI) {
+ Register Res = MI.getOperand(0).getReg();
+ Register LHS = MI.getOperand(1).getReg();
+ Register RHS = MI.getOperand(2).getReg();
+ LLT Ty = MRI.getType(Res);
+ bool IsSigned;
+ bool IsAdd;
+ unsigned BaseOp;
+ switch (MI.getOpcode()) {
+ default:
+ llvm_unreachable("unexpected addsat/subsat opcode");
+ case TargetOpcode::G_UADDSAT:
+ IsSigned = false;
+ IsAdd = true;
+ BaseOp = TargetOpcode::G_ADD;
+ break;
+ case TargetOpcode::G_SADDSAT:
+ IsSigned = true;
+ IsAdd = true;
+ BaseOp = TargetOpcode::G_ADD;
+ break;
+ case TargetOpcode::G_USUBSAT:
+ IsSigned = false;
+ IsAdd = false;
+ BaseOp = TargetOpcode::G_SUB;
+ break;
+ case TargetOpcode::G_SSUBSAT:
+ IsSigned = true;
+ IsAdd = false;
+ BaseOp = TargetOpcode::G_SUB;
+ break;
+ }
+
+ if (IsSigned) {
+ // sadd.sat(a, b) ->
+ // hi = 0x7fffffff - smax(a, 0)
+ // lo = 0x80000000 - smin(a, 0)
+ // a + smin(smax(lo, b), hi)
+ // ssub.sat(a, b) ->
+ // lo = smax(a, -1) - 0x7fffffff
+ // hi = smin(a, -1) - 0x80000000
+ // a - smin(smax(lo, b), hi)
+ // TODO: AMDGPU can use a "median of 3" instruction here:
+ // a +/- med3(lo, b, hi)
+ uint64_t NumBits = Ty.getScalarSizeInBits();
+ auto MaxVal =
+ MIRBuilder.buildConstant(Ty, APInt::getSignedMaxValue(NumBits));
+ auto MinVal =
+ MIRBuilder.buildConstant(Ty, APInt::getSignedMinValue(NumBits));
+ MachineInstrBuilder Hi, Lo;
+ if (IsAdd) {
+ auto Zero = MIRBuilder.buildConstant(Ty, 0);
+ Hi = MIRBuilder.buildSub(Ty, MaxVal, MIRBuilder.buildSMax(Ty, LHS, Zero));
+ Lo = MIRBuilder.buildSub(Ty, MinVal, MIRBuilder.buildSMin(Ty, LHS, Zero));
+ } else {
+ auto NegOne = MIRBuilder.buildConstant(Ty, -1);
+ Lo = MIRBuilder.buildSub(Ty, MIRBuilder.buildSMax(Ty, LHS, NegOne),
+ MaxVal);
+ Hi = MIRBuilder.buildSub(Ty, MIRBuilder.buildSMin(Ty, LHS, NegOne),
+ MinVal);
+ }
+ auto RHSClamped =
+ MIRBuilder.buildSMin(Ty, MIRBuilder.buildSMax(Ty, Lo, RHS), Hi);
+ MIRBuilder.buildInstr(BaseOp, {Res}, {LHS, RHSClamped});
+ } else {
+ // uadd.sat(a, b) -> a + umin(~a, b)
+ // usub.sat(a, b) -> a - umin(a, b)
+ Register Not = IsAdd ? MIRBuilder.buildNot(Ty, LHS).getReg(0) : LHS;
+ auto Min = MIRBuilder.buildUMin(Ty, Not, RHS);
+ MIRBuilder.buildInstr(BaseOp, {Res}, {LHS, Min});
+ }
+
+ MI.eraseFromParent();
+ return Legalized;
+}
+
+LegalizerHelper::LegalizeResult
+LegalizerHelper::lowerAddSubSatToAddoSubo(MachineInstr &MI) {
+ Register Res = MI.getOperand(0).getReg();
+ Register LHS = MI.getOperand(1).getReg();
+ Register RHS = MI.getOperand(2).getReg();
+ LLT Ty = MRI.getType(Res);
+ LLT BoolTy = Ty.changeElementSize(1);
+ bool IsSigned;
+ bool IsAdd;
+ unsigned OverflowOp;
+ switch (MI.getOpcode()) {
+ default:
+ llvm_unreachable("unexpected addsat/subsat opcode");
+ case TargetOpcode::G_UADDSAT:
+ IsSigned = false;
+ IsAdd = true;
+ OverflowOp = TargetOpcode::G_UADDO;
+ break;
+ case TargetOpcode::G_SADDSAT:
+ IsSigned = true;
+ IsAdd = true;
+ OverflowOp = TargetOpcode::G_SADDO;
+ break;
+ case TargetOpcode::G_USUBSAT:
+ IsSigned = false;
+ IsAdd = false;
+ OverflowOp = TargetOpcode::G_USUBO;
+ break;
+ case TargetOpcode::G_SSUBSAT:
+ IsSigned = true;
+ IsAdd = false;
+ OverflowOp = TargetOpcode::G_SSUBO;
+ break;
+ }
+
+ auto OverflowRes =
+ MIRBuilder.buildInstr(OverflowOp, {Ty, BoolTy}, {LHS, RHS});
+ Register Tmp = OverflowRes.getReg(0);
+ Register Ov = OverflowRes.getReg(1);
+ MachineInstrBuilder Clamp;
+ if (IsSigned) {
+ // sadd.sat(a, b) ->
+ // {tmp, ov} = saddo(a, b)
+ // ov ? (tmp >>s 31) + 0x80000000 : r
+ // ssub.sat(a, b) ->
+ // {tmp, ov} = ssubo(a, b)
+ // ov ? (tmp >>s 31) + 0x80000000 : r
+ uint64_t NumBits = Ty.getScalarSizeInBits();
+ auto ShiftAmount = MIRBuilder.buildConstant(Ty, NumBits - 1);
+ auto Sign = MIRBuilder.buildAShr(Ty, Tmp, ShiftAmount);
+ auto MinVal =
+ MIRBuilder.buildConstant(Ty, APInt::getSignedMinValue(NumBits));
+ Clamp = MIRBuilder.buildAdd(Ty, Sign, MinVal);
+ } else {
+ // uadd.sat(a, b) ->
+ // {tmp, ov} = uaddo(a, b)
+ // ov ? 0xffffffff : tmp
+ // usub.sat(a, b) ->
+ // {tmp, ov} = usubo(a, b)
+ // ov ? 0 : tmp
+ Clamp = MIRBuilder.buildConstant(Ty, IsAdd ? -1 : 0);
+ }
+ MIRBuilder.buildSelect(Res, Ov, Clamp, Tmp);
+
+ MI.eraseFromParent();
+ return Legalized;
+}
+
+LegalizerHelper::LegalizeResult
+LegalizerHelper::lowerShlSat(MachineInstr &MI) {
+ assert((MI.getOpcode() == TargetOpcode::G_SSHLSAT ||
+ MI.getOpcode() == TargetOpcode::G_USHLSAT) &&
+ "Expected shlsat opcode!");
+ bool IsSigned = MI.getOpcode() == TargetOpcode::G_SSHLSAT;
+ Register Res = MI.getOperand(0).getReg();
+ Register LHS = MI.getOperand(1).getReg();
+ Register RHS = MI.getOperand(2).getReg();
+ LLT Ty = MRI.getType(Res);
+ LLT BoolTy = Ty.changeElementSize(1);
+
+ unsigned BW = Ty.getScalarSizeInBits();
+ auto Result = MIRBuilder.buildShl(Ty, LHS, RHS);
+ auto Orig = IsSigned ? MIRBuilder.buildAShr(Ty, Result, RHS)
+ : MIRBuilder.buildLShr(Ty, Result, RHS);
+
+ MachineInstrBuilder SatVal;
+ if (IsSigned) {
+ auto SatMin = MIRBuilder.buildConstant(Ty, APInt::getSignedMinValue(BW));
+ auto SatMax = MIRBuilder.buildConstant(Ty, APInt::getSignedMaxValue(BW));
+ auto Cmp = MIRBuilder.buildICmp(CmpInst::ICMP_SLT, BoolTy, LHS,
+ MIRBuilder.buildConstant(Ty, 0));
+ SatVal = MIRBuilder.buildSelect(Ty, Cmp, SatMin, SatMax);
+ } else {
+ SatVal = MIRBuilder.buildConstant(Ty, APInt::getMaxValue(BW));
+ }
+ auto Ov = MIRBuilder.buildICmp(CmpInst::ICMP_NE, BoolTy, LHS, Orig);
+ MIRBuilder.buildSelect(Res, Ov, SatVal, Result);
+
+ MI.eraseFromParent();
+ return Legalized;
+}
+
+LegalizerHelper::LegalizeResult
LegalizerHelper::lowerBswap(MachineInstr &MI) {
Register Dst = MI.getOperand(0).getReg();
Register Src = MI.getOperand(1).getReg();
@@ -6199,7 +6199,7 @@ LegalizerHelper::lowerReadWriteRegister(MachineInstr &MI) {
const MDString *RegStr = cast<MDString>(
cast<MDNode>(MI.getOperand(NameOpIdx).getMetadata())->getOperand(0));
- Register PhysReg = TLI.getRegisterByName(RegStr->getString().data(), Ty, MF);
+ Register PhysReg = TLI.getRegisterByName(RegStr->getString().data(), Ty, MF);
if (!PhysReg.isValid())
return UnableToLegalize;
@@ -6211,63 +6211,63 @@ LegalizerHelper::lowerReadWriteRegister(MachineInstr &MI) {
MI.eraseFromParent();
return Legalized;
}
-
-LegalizerHelper::LegalizeResult
-LegalizerHelper::lowerSMULH_UMULH(MachineInstr &MI) {
- bool IsSigned = MI.getOpcode() == TargetOpcode::G_SMULH;
- unsigned ExtOp = IsSigned ? TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT;
- Register Result = MI.getOperand(0).getReg();
- LLT OrigTy = MRI.getType(Result);
- auto SizeInBits = OrigTy.getScalarSizeInBits();
- LLT WideTy = OrigTy.changeElementSize(SizeInBits * 2);
-
- auto LHS = MIRBuilder.buildInstr(ExtOp, {WideTy}, {MI.getOperand(1)});
- auto RHS = MIRBuilder.buildInstr(ExtOp, {WideTy}, {MI.getOperand(2)});
- auto Mul = MIRBuilder.buildMul(WideTy, LHS, RHS);
- unsigned ShiftOp = IsSigned ? TargetOpcode::G_ASHR : TargetOpcode::G_LSHR;
-
- auto ShiftAmt = MIRBuilder.buildConstant(WideTy, SizeInBits);
- auto Shifted = MIRBuilder.buildInstr(ShiftOp, {WideTy}, {Mul, ShiftAmt});
- MIRBuilder.buildTrunc(Result, Shifted);
-
- MI.eraseFromParent();
- return Legalized;
-}
-
-LegalizerHelper::LegalizeResult LegalizerHelper::lowerSelect(MachineInstr &MI) {
- // Implement vector G_SELECT in terms of XOR, AND, OR.
- Register DstReg = MI.getOperand(0).getReg();
- Register MaskReg = MI.getOperand(1).getReg();
- Register Op1Reg = MI.getOperand(2).getReg();
- Register Op2Reg = MI.getOperand(3).getReg();
- LLT DstTy = MRI.getType(DstReg);
- LLT MaskTy = MRI.getType(MaskReg);
- LLT Op1Ty = MRI.getType(Op1Reg);
- if (!DstTy.isVector())
- return UnableToLegalize;
-
- // Vector selects can have a scalar predicate. If so, splat into a vector and
- // finish for later legalization attempts to try again.
- if (MaskTy.isScalar()) {
- Register MaskElt = MaskReg;
- if (MaskTy.getSizeInBits() < DstTy.getScalarSizeInBits())
- MaskElt = MIRBuilder.buildSExt(DstTy.getElementType(), MaskElt).getReg(0);
- // Generate a vector splat idiom to be pattern matched later.
- auto ShufSplat = MIRBuilder.buildShuffleSplat(DstTy, MaskElt);
- Observer.changingInstr(MI);
- MI.getOperand(1).setReg(ShufSplat.getReg(0));
- Observer.changedInstr(MI);
- return Legalized;
- }
-
- if (MaskTy.getSizeInBits() != Op1Ty.getSizeInBits()) {
- return UnableToLegalize;
- }
-
- auto NotMask = MIRBuilder.buildNot(MaskTy, MaskReg);
- auto NewOp1 = MIRBuilder.buildAnd(MaskTy, Op1Reg, MaskReg);
- auto NewOp2 = MIRBuilder.buildAnd(MaskTy, Op2Reg, NotMask);
- MIRBuilder.buildOr(DstReg, NewOp1, NewOp2);
- MI.eraseFromParent();
- return Legalized;
-}
+
+LegalizerHelper::LegalizeResult
+LegalizerHelper::lowerSMULH_UMULH(MachineInstr &MI) {
+ bool IsSigned = MI.getOpcode() == TargetOpcode::G_SMULH;
+ unsigned ExtOp = IsSigned ? TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT;
+ Register Result = MI.getOperand(0).getReg();
+ LLT OrigTy = MRI.getType(Result);
+ auto SizeInBits = OrigTy.getScalarSizeInBits();
+ LLT WideTy = OrigTy.changeElementSize(SizeInBits * 2);
+
+ auto LHS = MIRBuilder.buildInstr(ExtOp, {WideTy}, {MI.getOperand(1)});
+ auto RHS = MIRBuilder.buildInstr(ExtOp, {WideTy}, {MI.getOperand(2)});
+ auto Mul = MIRBuilder.buildMul(WideTy, LHS, RHS);
+ unsigned ShiftOp = IsSigned ? TargetOpcode::G_ASHR : TargetOpcode::G_LSHR;
+
+ auto ShiftAmt = MIRBuilder.buildConstant(WideTy, SizeInBits);
+ auto Shifted = MIRBuilder.buildInstr(ShiftOp, {WideTy}, {Mul, ShiftAmt});
+ MIRBuilder.buildTrunc(Result, Shifted);
+
+ MI.eraseFromParent();
+ return Legalized;
+}
+
+LegalizerHelper::LegalizeResult LegalizerHelper::lowerSelect(MachineInstr &MI) {
+ // Implement vector G_SELECT in terms of XOR, AND, OR.
+ Register DstReg = MI.getOperand(0).getReg();
+ Register MaskReg = MI.getOperand(1).getReg();
+ Register Op1Reg = MI.getOperand(2).getReg();
+ Register Op2Reg = MI.getOperand(3).getReg();
+ LLT DstTy = MRI.getType(DstReg);
+ LLT MaskTy = MRI.getType(MaskReg);
+ LLT Op1Ty = MRI.getType(Op1Reg);
+ if (!DstTy.isVector())
+ return UnableToLegalize;
+
+ // Vector selects can have a scalar predicate. If so, splat into a vector and
+ // finish for later legalization attempts to try again.
+ if (MaskTy.isScalar()) {
+ Register MaskElt = MaskReg;
+ if (MaskTy.getSizeInBits() < DstTy.getScalarSizeInBits())
+ MaskElt = MIRBuilder.buildSExt(DstTy.getElementType(), MaskElt).getReg(0);
+ // Generate a vector splat idiom to be pattern matched later.
+ auto ShufSplat = MIRBuilder.buildShuffleSplat(DstTy, MaskElt);
+ Observer.changingInstr(MI);
+ MI.getOperand(1).setReg(ShufSplat.getReg(0));
+ Observer.changedInstr(MI);
+ return Legalized;
+ }
+
+ if (MaskTy.getSizeInBits() != Op1Ty.getSizeInBits()) {
+ return UnableToLegalize;
+ }
+
+ auto NotMask = MIRBuilder.buildNot(MaskTy, MaskReg);
+ auto NewOp1 = MIRBuilder.buildAnd(MaskTy, Op1Reg, MaskReg);
+ auto NewOp2 = MIRBuilder.buildAnd(MaskTy, Op2Reg, NotMask);
+ MIRBuilder.buildOr(DstReg, NewOp1, NewOp2);
+ MI.eraseFromParent();
+ return Legalized;
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalizerInfo.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
index 0a5cb26325..30acac14bc 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
@@ -105,7 +105,7 @@ raw_ostream &LegalityQuery::print(raw_ostream &OS) const {
static bool hasNoSimpleLoops(const LegalizeRule &Rule, const LegalityQuery &Q,
const std::pair<unsigned, LLT> &Mutation) {
switch (Rule.getAction()) {
- case Legal:
+ case Legal:
case Custom:
case Lower:
case MoreElements:
@@ -123,7 +123,7 @@ static bool mutationIsSane(const LegalizeRule &Rule,
std::pair<unsigned, LLT> Mutation) {
// If the user wants a custom mutation, then we can't really say much about
// it. Return true, and trust that they're doing the right thing.
- if (Rule.getAction() == Custom || Rule.getAction() == Legal)
+ if (Rule.getAction() == Custom || Rule.getAction() == Legal)
return true;
const unsigned TypeIdx = Mutation.first;
@@ -148,8 +148,8 @@ static bool mutationIsSane(const LegalizeRule &Rule,
if (NewTy.getNumElements() <= OldElts)
return false;
}
- } else if (Rule.getAction() == MoreElements)
- return false;
+ } else if (Rule.getAction() == MoreElements)
+ return false;
// Make sure the element type didn't change.
return NewTy.getScalarType() == OldTy.getScalarType();
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Localizer.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Localizer.cpp
index 66cff18e91..30c00c63f6 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Localizer.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Localizer.cpp
@@ -11,7 +11,7 @@
#include "llvm/CodeGen/GlobalISel/Localizer.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
@@ -57,20 +57,20 @@ bool Localizer::isLocalUse(MachineOperand &MOUse, const MachineInstr &Def,
return InsertMBB == Def.getParent();
}
-bool Localizer::isNonUniquePhiValue(MachineOperand &Op) const {
- MachineInstr *MI = Op.getParent();
- if (!MI->isPHI())
- return false;
-
- Register SrcReg = Op.getReg();
- for (unsigned Idx = 1; Idx < MI->getNumOperands(); Idx += 2) {
- auto &MO = MI->getOperand(Idx);
- if (&MO != &Op && MO.isReg() && MO.getReg() == SrcReg)
- return true;
- }
- return false;
-}
-
+bool Localizer::isNonUniquePhiValue(MachineOperand &Op) const {
+ MachineInstr *MI = Op.getParent();
+ if (!MI->isPHI())
+ return false;
+
+ Register SrcReg = Op.getReg();
+ for (unsigned Idx = 1; Idx < MI->getNumOperands(); Idx += 2) {
+ auto &MO = MI->getOperand(Idx);
+ if (&MO != &Op && MO.isReg() && MO.getReg() == SrcReg)
+ return true;
+ }
+ return false;
+}
+
bool Localizer::localizeInterBlock(MachineFunction &MF,
LocalizedSetVecT &LocalizedInstrs) {
bool Changed = false;
@@ -108,14 +108,14 @@ bool Localizer::localizeInterBlock(MachineFunction &MF,
LocalizedInstrs.insert(&MI);
continue;
}
-
- // If the use is a phi operand that's not unique, don't try to localize.
- // If we do, we can cause unnecessary instruction bloat by duplicating
- // into each predecessor block, when the existing one is sufficient and
- // allows for easier optimization later.
- if (isNonUniquePhiValue(MOUse))
- continue;
-
+
+ // If the use is a phi operand that's not unique, don't try to localize.
+ // If we do, we can cause unnecessary instruction bloat by duplicating
+ // into each predecessor block, when the existing one is sufficient and
+ // allows for easier optimization later.
+ if (isNonUniquePhiValue(MOUse))
+ continue;
+
LLVM_DEBUG(dbgs() << "Fixing non-local use\n");
Changed = true;
auto MBBAndReg = std::make_pair(InsertMBB, Reg);
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 549bb1a13c..67ef02a4e7 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -9,7 +9,7 @@
/// This file implements the MachineIRBuidler class.
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
-#include "llvm/Analysis/MemoryLocation.h"
+#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
@@ -106,8 +106,8 @@ MachineInstrBuilder MachineIRBuilder::buildConstDbgValue(const Constant &C,
} else if (auto *CFP = dyn_cast<ConstantFP>(&C)) {
MIB.addFPImm(CFP);
} else {
- // Insert $noreg if we didn't find a usable constant and had to drop it.
- MIB.addReg(Register());
+ // Insert $noreg if we didn't find a usable constant and had to drop it.
+ MIB.addReg(Register());
}
MIB.addImm(0).addMetadata(Variable).addMetadata(Expr);
@@ -162,11 +162,11 @@ MachineInstrBuilder MachineIRBuilder::buildJumpTable(const LLT PtrTy,
.addJumpTableIndex(JTI);
}
-void MachineIRBuilder::validateUnaryOp(const LLT Res, const LLT Op0) {
- assert((Res.isScalar() || Res.isVector()) && "invalid operand type");
- assert((Res == Op0) && "type mismatch");
-}
-
+void MachineIRBuilder::validateUnaryOp(const LLT Res, const LLT Op0) {
+ assert((Res.isScalar() || Res.isVector()) && "invalid operand type");
+ assert((Res == Op0) && "type mismatch");
+}
+
void MachineIRBuilder::validateBinaryOp(const LLT Res, const LLT Op0,
const LLT Op1) {
assert((Res.isScalar() || Res.isVector()) && "invalid operand type");
@@ -317,29 +317,29 @@ MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res,
return buildFConstant(Res, *CFP);
}
-MachineInstrBuilder MachineIRBuilder::buildBrCond(const SrcOp &Tst,
+MachineInstrBuilder MachineIRBuilder::buildBrCond(const SrcOp &Tst,
MachineBasicBlock &Dest) {
- assert(Tst.getLLTTy(*getMRI()).isScalar() && "invalid operand type");
+ assert(Tst.getLLTTy(*getMRI()).isScalar() && "invalid operand type");
- auto MIB = buildInstr(TargetOpcode::G_BRCOND);
- Tst.addSrcToMIB(MIB);
- MIB.addMBB(&Dest);
- return MIB;
+ auto MIB = buildInstr(TargetOpcode::G_BRCOND);
+ Tst.addSrcToMIB(MIB);
+ MIB.addMBB(&Dest);
+ return MIB;
}
-MachineInstrBuilder
-MachineIRBuilder::buildLoad(const DstOp &Dst, const SrcOp &Addr,
- MachinePointerInfo PtrInfo, Align Alignment,
- MachineMemOperand::Flags MMOFlags,
- const AAMDNodes &AAInfo) {
- MMOFlags |= MachineMemOperand::MOLoad;
- assert((MMOFlags & MachineMemOperand::MOStore) == 0);
-
- uint64_t Size = MemoryLocation::getSizeOrUnknown(
- TypeSize::Fixed(Dst.getLLTTy(*getMRI()).getSizeInBytes()));
- MachineMemOperand *MMO =
- getMF().getMachineMemOperand(PtrInfo, MMOFlags, Size, Alignment, AAInfo);
- return buildLoad(Dst, Addr, *MMO);
+MachineInstrBuilder
+MachineIRBuilder::buildLoad(const DstOp &Dst, const SrcOp &Addr,
+ MachinePointerInfo PtrInfo, Align Alignment,
+ MachineMemOperand::Flags MMOFlags,
+ const AAMDNodes &AAInfo) {
+ MMOFlags |= MachineMemOperand::MOLoad;
+ assert((MMOFlags & MachineMemOperand::MOStore) == 0);
+
+ uint64_t Size = MemoryLocation::getSizeOrUnknown(
+ TypeSize::Fixed(Dst.getLLTTy(*getMRI()).getSizeInBytes()));
+ MachineMemOperand *MMO =
+ getMF().getMachineMemOperand(PtrInfo, MMOFlags, Size, Alignment, AAInfo);
+ return buildLoad(Dst, Addr, *MMO);
}
MachineInstrBuilder MachineIRBuilder::buildLoadInstr(unsigned Opcode,
@@ -386,21 +386,21 @@ MachineInstrBuilder MachineIRBuilder::buildStore(const SrcOp &Val,
return MIB;
}
-MachineInstrBuilder
-MachineIRBuilder::buildStore(const SrcOp &Val, const SrcOp &Addr,
- MachinePointerInfo PtrInfo, Align Alignment,
- MachineMemOperand::Flags MMOFlags,
- const AAMDNodes &AAInfo) {
- MMOFlags |= MachineMemOperand::MOStore;
- assert((MMOFlags & MachineMemOperand::MOLoad) == 0);
-
- uint64_t Size = MemoryLocation::getSizeOrUnknown(
- TypeSize::Fixed(Val.getLLTTy(*getMRI()).getSizeInBytes()));
- MachineMemOperand *MMO =
- getMF().getMachineMemOperand(PtrInfo, MMOFlags, Size, Alignment, AAInfo);
- return buildStore(Val, Addr, *MMO);
-}
-
+MachineInstrBuilder
+MachineIRBuilder::buildStore(const SrcOp &Val, const SrcOp &Addr,
+ MachinePointerInfo PtrInfo, Align Alignment,
+ MachineMemOperand::Flags MMOFlags,
+ const AAMDNodes &AAInfo) {
+ MMOFlags |= MachineMemOperand::MOStore;
+ assert((MMOFlags & MachineMemOperand::MOLoad) == 0);
+
+ uint64_t Size = MemoryLocation::getSizeOrUnknown(
+ TypeSize::Fixed(Val.getLLTTy(*getMRI()).getSizeInBytes()));
+ MachineMemOperand *MMO =
+ getMF().getMachineMemOperand(PtrInfo, MMOFlags, Size, Alignment, AAInfo);
+ return buildStore(Val, Addr, *MMO);
+}
+
MachineInstrBuilder MachineIRBuilder::buildAnyExt(const DstOp &Res,
const SrcOp &Op) {
return buildInstr(TargetOpcode::G_ANYEXT, Res, Op);
@@ -635,35 +635,35 @@ MachineIRBuilder::buildBuildVectorTrunc(const DstOp &Res,
return buildInstr(TargetOpcode::G_BUILD_VECTOR_TRUNC, Res, TmpVec);
}
-MachineInstrBuilder MachineIRBuilder::buildShuffleSplat(const DstOp &Res,
- const SrcOp &Src) {
- LLT DstTy = Res.getLLTTy(*getMRI());
- assert(Src.getLLTTy(*getMRI()) == DstTy.getElementType() &&
- "Expected Src to match Dst elt ty");
- auto UndefVec = buildUndef(DstTy);
- auto Zero = buildConstant(LLT::scalar(64), 0);
- auto InsElt = buildInsertVectorElement(DstTy, UndefVec, Src, Zero);
- SmallVector<int, 16> ZeroMask(DstTy.getNumElements());
- return buildShuffleVector(DstTy, InsElt, UndefVec, ZeroMask);
-}
-
-MachineInstrBuilder MachineIRBuilder::buildShuffleVector(const DstOp &Res,
- const SrcOp &Src1,
- const SrcOp &Src2,
- ArrayRef<int> Mask) {
- LLT DstTy = Res.getLLTTy(*getMRI());
- LLT Src1Ty = Src1.getLLTTy(*getMRI());
- LLT Src2Ty = Src2.getLLTTy(*getMRI());
- assert(Src1Ty.getNumElements() + Src2Ty.getNumElements() >= Mask.size());
- assert(DstTy.getElementType() == Src1Ty.getElementType() &&
- DstTy.getElementType() == Src2Ty.getElementType());
- (void)Src1Ty;
- (void)Src2Ty;
- ArrayRef<int> MaskAlloc = getMF().allocateShuffleMask(Mask);
- return buildInstr(TargetOpcode::G_SHUFFLE_VECTOR, {DstTy}, {Src1, Src2})
- .addShuffleMask(MaskAlloc);
-}
-
+MachineInstrBuilder MachineIRBuilder::buildShuffleSplat(const DstOp &Res,
+ const SrcOp &Src) {
+ LLT DstTy = Res.getLLTTy(*getMRI());
+ assert(Src.getLLTTy(*getMRI()) == DstTy.getElementType() &&
+ "Expected Src to match Dst elt ty");
+ auto UndefVec = buildUndef(DstTy);
+ auto Zero = buildConstant(LLT::scalar(64), 0);
+ auto InsElt = buildInsertVectorElement(DstTy, UndefVec, Src, Zero);
+ SmallVector<int, 16> ZeroMask(DstTy.getNumElements());
+ return buildShuffleVector(DstTy, InsElt, UndefVec, ZeroMask);
+}
+
+MachineInstrBuilder MachineIRBuilder::buildShuffleVector(const DstOp &Res,
+ const SrcOp &Src1,
+ const SrcOp &Src2,
+ ArrayRef<int> Mask) {
+ LLT DstTy = Res.getLLTTy(*getMRI());
+ LLT Src1Ty = Src1.getLLTTy(*getMRI());
+ LLT Src2Ty = Src2.getLLTTy(*getMRI());
+ assert(Src1Ty.getNumElements() + Src2Ty.getNumElements() >= Mask.size());
+ assert(DstTy.getElementType() == Src1Ty.getElementType() &&
+ DstTy.getElementType() == Src2Ty.getElementType());
+ (void)Src1Ty;
+ (void)Src2Ty;
+ ArrayRef<int> MaskAlloc = getMF().allocateShuffleMask(Mask);
+ return buildInstr(TargetOpcode::G_SHUFFLE_VECTOR, {DstTy}, {Src1, Src2})
+ .addShuffleMask(MaskAlloc);
+}
+
MachineInstrBuilder
MachineIRBuilder::buildConcatVectors(const DstOp &Res, ArrayRef<Register> Ops) {
// Unfortunately to convert from ArrayRef<Register> to ArrayRef<SrcOp>,
@@ -986,14 +986,14 @@ MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opc,
SrcOps[1].getLLTTy(*getMRI()), SrcOps[2].getLLTTy(*getMRI()));
break;
}
- case TargetOpcode::G_FNEG:
- case TargetOpcode::G_ABS:
- // All these are unary ops.
- assert(DstOps.size() == 1 && "Invalid Dst");
- assert(SrcOps.size() == 1 && "Invalid Srcs");
- validateUnaryOp(DstOps[0].getLLTTy(*getMRI()),
- SrcOps[0].getLLTTy(*getMRI()));
- break;
+ case TargetOpcode::G_FNEG:
+ case TargetOpcode::G_ABS:
+ // All these are unary ops.
+ assert(DstOps.size() == 1 && "Invalid Dst");
+ assert(SrcOps.size() == 1 && "Invalid Srcs");
+ validateUnaryOp(DstOps[0].getLLTTy(*getMRI()),
+ SrcOps[0].getLLTTy(*getMRI()));
+ break;
case TargetOpcode::G_ADD:
case TargetOpcode::G_AND:
case TargetOpcode::G_MUL:
@@ -1022,9 +1022,9 @@ MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opc,
}
case TargetOpcode::G_SHL:
case TargetOpcode::G_ASHR:
- case TargetOpcode::G_LSHR:
- case TargetOpcode::G_USHLSAT:
- case TargetOpcode::G_SSHLSAT: {
+ case TargetOpcode::G_LSHR:
+ case TargetOpcode::G_USHLSAT:
+ case TargetOpcode::G_SSHLSAT: {
assert(DstOps.size() == 1 && "Invalid Dst");
assert(SrcOps.size() == 2 && "Invalid Srcs");
validateShiftOp(DstOps[0].getLLTTy(*getMRI()),
@@ -1089,11 +1089,11 @@ MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opc,
case TargetOpcode::G_UNMERGE_VALUES: {
assert(!DstOps.empty() && "Invalid trivial sequence");
assert(SrcOps.size() == 1 && "Invalid src for Unmerge");
- assert(llvm::all_of(DstOps,
- [&, this](const DstOp &Op) {
- return Op.getLLTTy(*getMRI()) ==
- DstOps[0].getLLTTy(*getMRI());
- }) &&
+ assert(llvm::all_of(DstOps,
+ [&, this](const DstOp &Op) {
+ return Op.getLLTTy(*getMRI()) ==
+ DstOps[0].getLLTTy(*getMRI());
+ }) &&
"type mismatch in output list");
assert(DstOps.size() * DstOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() &&
@@ -1103,11 +1103,11 @@ MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opc,
case TargetOpcode::G_MERGE_VALUES: {
assert(!SrcOps.empty() && "invalid trivial sequence");
assert(DstOps.size() == 1 && "Invalid Dst");
- assert(llvm::all_of(SrcOps,
- [&, this](const SrcOp &Op) {
- return Op.getLLTTy(*getMRI()) ==
- SrcOps[0].getLLTTy(*getMRI());
- }) &&
+ assert(llvm::all_of(SrcOps,
+ [&, this](const SrcOp &Op) {
+ return Op.getLLTTy(*getMRI()) ==
+ SrcOps[0].getLLTTy(*getMRI());
+ }) &&
"type mismatch in input list");
assert(SrcOps.size() * SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
DstOps[0].getLLTTy(*getMRI()).getSizeInBits() &&
@@ -1154,11 +1154,11 @@ MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opc,
assert(DstOps.size() == 1 && "Invalid DstOps");
assert(DstOps[0].getLLTTy(*getMRI()).isVector() &&
"Res type must be a vector");
- assert(llvm::all_of(SrcOps,
- [&, this](const SrcOp &Op) {
- return Op.getLLTTy(*getMRI()) ==
- SrcOps[0].getLLTTy(*getMRI());
- }) &&
+ assert(llvm::all_of(SrcOps,
+ [&, this](const SrcOp &Op) {
+ return Op.getLLTTy(*getMRI()) ==
+ SrcOps[0].getLLTTy(*getMRI());
+ }) &&
"type mismatch in input list");
assert(SrcOps.size() * SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
DstOps[0].getLLTTy(*getMRI()).getSizeInBits() &&
@@ -1171,11 +1171,11 @@ MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opc,
assert(DstOps.size() == 1 && "Invalid DstOps");
assert(DstOps[0].getLLTTy(*getMRI()).isVector() &&
"Res type must be a vector");
- assert(llvm::all_of(SrcOps,
- [&, this](const SrcOp &Op) {
- return Op.getLLTTy(*getMRI()) ==
- SrcOps[0].getLLTTy(*getMRI());
- }) &&
+ assert(llvm::all_of(SrcOps,
+ [&, this](const SrcOp &Op) {
+ return Op.getLLTTy(*getMRI()) ==
+ SrcOps[0].getLLTTy(*getMRI());
+ }) &&
"type mismatch in input list");
if (SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
DstOps[0].getLLTTy(*getMRI()).getElementType().getSizeInBits())
@@ -1186,12 +1186,12 @@ MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opc,
assert(DstOps.size() == 1 && "Invalid DstOps");
assert((!SrcOps.empty() || SrcOps.size() < 2) &&
"Must have at least 2 operands");
- assert(llvm::all_of(SrcOps,
- [&, this](const SrcOp &Op) {
- return (Op.getLLTTy(*getMRI()).isVector() &&
- Op.getLLTTy(*getMRI()) ==
- SrcOps[0].getLLTTy(*getMRI()));
- }) &&
+ assert(llvm::all_of(SrcOps,
+ [&, this](const SrcOp &Op) {
+ return (Op.getLLTTy(*getMRI()).isVector() &&
+ Op.getLLTTy(*getMRI()) ==
+ SrcOps[0].getLLTTy(*getMRI()));
+ }) &&
"type mismatch in input list");
assert(SrcOps.size() * SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
DstOps[0].getLLTTy(*getMRI()).getSizeInBits() &&
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
index 05f47915b3..e2a9637471 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
@@ -421,7 +421,7 @@ RegisterBankInfo::getInstrPossibleMappings(const MachineInstr &MI) const {
// Then the alternative mapping, if any.
InstructionMappings AltMappings = getInstrAlternativeMappings(MI);
- append_range(PossibleMappings, AltMappings);
+ append_range(PossibleMappings, AltMappings);
#ifndef NDEBUG
for (const InstructionMapping *Mapping : PossibleMappings)
assert(Mapping->verify(MI) && "Mapping is invalid");
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Utils.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Utils.cpp
index 2adc30eacc..cd24832244 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/Utils.cpp
@@ -11,11 +11,11 @@
#include "llvm/CodeGen/GlobalISel/Utils.h"
#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
-#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
-#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
+#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
+#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -23,16 +23,16 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/StackProtector.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
-#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/IR/Constants.h"
-#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetMachine.h"
#define DEBUG_TYPE "globalisel-utils"
using namespace llvm;
-using namespace MIPatternMatch;
+using namespace MIPatternMatch;
Register llvm::constrainRegToClass(MachineRegisterInfo &MRI,
const TargetInstrInfo &TII,
@@ -48,7 +48,7 @@ Register llvm::constrainOperandRegClass(
const MachineFunction &MF, const TargetRegisterInfo &TRI,
MachineRegisterInfo &MRI, const TargetInstrInfo &TII,
const RegisterBankInfo &RBI, MachineInstr &InsertPt,
- const TargetRegisterClass &RegClass, MachineOperand &RegMO) {
+ const TargetRegisterClass &RegClass, MachineOperand &RegMO) {
Register Reg = RegMO.getReg();
// Assume physical registers are properly constrained.
assert(Register::isVirtualRegister(Reg) && "PhysReg not implemented");
@@ -69,13 +69,13 @@ Register llvm::constrainOperandRegClass(
TII.get(TargetOpcode::COPY), Reg)
.addReg(ConstrainedReg);
}
- if (GISelChangeObserver *Observer = MF.getObserver()) {
- Observer->changingInstr(*RegMO.getParent());
- }
- RegMO.setReg(ConstrainedReg);
- if (GISelChangeObserver *Observer = MF.getObserver()) {
- Observer->changedInstr(*RegMO.getParent());
- }
+ if (GISelChangeObserver *Observer = MF.getObserver()) {
+ Observer->changingInstr(*RegMO.getParent());
+ }
+ RegMO.setReg(ConstrainedReg);
+ if (GISelChangeObserver *Observer = MF.getObserver()) {
+ Observer->changedInstr(*RegMO.getParent());
+ }
} else {
if (GISelChangeObserver *Observer = MF.getObserver()) {
if (!RegMO.isDef()) {
@@ -93,7 +93,7 @@ Register llvm::constrainOperandRegClass(
const MachineFunction &MF, const TargetRegisterInfo &TRI,
MachineRegisterInfo &MRI, const TargetInstrInfo &TII,
const RegisterBankInfo &RBI, MachineInstr &InsertPt, const MCInstrDesc &II,
- MachineOperand &RegMO, unsigned OpIdx) {
+ MachineOperand &RegMO, unsigned OpIdx) {
Register Reg = RegMO.getReg();
// Assume physical registers are properly constrained.
assert(Register::isVirtualRegister(Reg) && "PhysReg not implemented");
@@ -163,7 +163,7 @@ bool llvm::constrainSelectedInstRegOperands(MachineInstr &I,
// If the operand is a vreg, we should constrain its regclass, and only
// insert COPYs if that's impossible.
// constrainOperandRegClass does that for us.
- constrainOperandRegClass(MF, TRI, MRI, TII, RBI, I, I.getDesc(), MO, OpI);
+ constrainOperandRegClass(MF, TRI, MRI, TII, RBI, I, I.getDesc(), MO, OpI);
// Tie uses to defs as indicated in MCInstrDesc if this hasn't already been
// done.
@@ -192,14 +192,14 @@ bool llvm::canReplaceReg(Register DstReg, Register SrcReg,
bool llvm::isTriviallyDead(const MachineInstr &MI,
const MachineRegisterInfo &MRI) {
- // FIXME: This logical is mostly duplicated with
- // DeadMachineInstructionElim::isDead. Why is LOCAL_ESCAPE not considered in
- // MachineInstr::isLabel?
-
- // Don't delete frame allocation labels.
- if (MI.getOpcode() == TargetOpcode::LOCAL_ESCAPE)
- return false;
-
+ // FIXME: This logical is mostly duplicated with
+ // DeadMachineInstructionElim::isDead. Why is LOCAL_ESCAPE not considered in
+ // MachineInstr::isLabel?
+
+ // Don't delete frame allocation labels.
+ if (MI.getOpcode() == TargetOpcode::LOCAL_ESCAPE)
+ return false;
+
// If we can move an instruction, we can remove it. Otherwise, it has
// a side-effect of some sort.
bool SawStore = false;
@@ -262,8 +262,8 @@ void llvm::reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC,
reportGISelFailure(MF, TPC, MORE, R);
}
-Optional<APInt> llvm::getConstantVRegVal(Register VReg,
- const MachineRegisterInfo &MRI) {
+Optional<APInt> llvm::getConstantVRegVal(Register VReg,
+ const MachineRegisterInfo &MRI) {
Optional<ValueAndVReg> ValAndVReg =
getConstantVRegValWithLookThrough(VReg, MRI, /*LookThroughInstrs*/ false);
assert((!ValAndVReg || ValAndVReg->VReg == VReg) &&
@@ -273,17 +273,17 @@ Optional<APInt> llvm::getConstantVRegVal(Register VReg,
return ValAndVReg->Value;
}
-Optional<int64_t> llvm::getConstantVRegSExtVal(Register VReg,
- const MachineRegisterInfo &MRI) {
- Optional<APInt> Val = getConstantVRegVal(VReg, MRI);
- if (Val && Val->getBitWidth() <= 64)
- return Val->getSExtValue();
- return None;
-}
-
+Optional<int64_t> llvm::getConstantVRegSExtVal(Register VReg,
+ const MachineRegisterInfo &MRI) {
+ Optional<APInt> Val = getConstantVRegVal(VReg, MRI);
+ if (Val && Val->getBitWidth() <= 64)
+ return Val->getSExtValue();
+ return None;
+}
+
Optional<ValueAndVReg> llvm::getConstantVRegValWithLookThrough(
Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs,
- bool HandleFConstant, bool LookThroughAnyExt) {
+ bool HandleFConstant, bool LookThroughAnyExt) {
SmallVector<std::pair<unsigned, unsigned>, 4> SeenOpcodes;
MachineInstr *MI;
auto IsConstantOpcode = [HandleFConstant](unsigned Opcode) {
@@ -310,10 +310,10 @@ Optional<ValueAndVReg> llvm::getConstantVRegValWithLookThrough(
while ((MI = MRI.getVRegDef(VReg)) && !IsConstantOpcode(MI->getOpcode()) &&
LookThroughInstrs) {
switch (MI->getOpcode()) {
- case TargetOpcode::G_ANYEXT:
- if (!LookThroughAnyExt)
- return None;
- LLVM_FALLTHROUGH;
+ case TargetOpcode::G_ANYEXT:
+ if (!LookThroughAnyExt)
+ return None;
+ LLVM_FALLTHROUGH;
case TargetOpcode::G_TRUNC:
case TargetOpcode::G_SEXT:
case TargetOpcode::G_ZEXT:
@@ -347,7 +347,7 @@ Optional<ValueAndVReg> llvm::getConstantVRegValWithLookThrough(
case TargetOpcode::G_TRUNC:
Val = Val.trunc(OpcodeAndSize.second);
break;
- case TargetOpcode::G_ANYEXT:
+ case TargetOpcode::G_ANYEXT:
case TargetOpcode::G_SEXT:
Val = Val.sext(OpcodeAndSize.second);
break;
@@ -357,10 +357,10 @@ Optional<ValueAndVReg> llvm::getConstantVRegValWithLookThrough(
}
}
- return ValueAndVReg{Val, VReg};
+ return ValueAndVReg{Val, VReg};
}
-const ConstantFP *
+const ConstantFP *
llvm::getConstantFPVRegVal(Register VReg, const MachineRegisterInfo &MRI) {
MachineInstr *MI = MRI.getVRegDef(VReg);
if (TargetOpcode::G_FCONSTANT != MI->getOpcode())
@@ -368,8 +368,8 @@ llvm::getConstantFPVRegVal(Register VReg, const MachineRegisterInfo &MRI) {
return MI->getOperand(1).getFPImm();
}
-Optional<DefinitionAndSourceRegister>
-llvm::getDefSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI) {
+Optional<DefinitionAndSourceRegister>
+llvm::getDefSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI) {
Register DefSrcReg = Reg;
auto *DefMI = MRI.getVRegDef(Reg);
auto DstTy = MRI.getType(DefMI->getOperand(0).getReg());
@@ -378,7 +378,7 @@ llvm::getDefSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI) {
while (DefMI->getOpcode() == TargetOpcode::COPY) {
Register SrcReg = DefMI->getOperand(1).getReg();
auto SrcTy = MRI.getType(SrcReg);
- if (!SrcTy.isValid())
+ if (!SrcTy.isValid())
break;
DefMI = MRI.getVRegDef(SrcReg);
DefSrcReg = SrcReg;
@@ -386,8 +386,8 @@ llvm::getDefSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI) {
return DefinitionAndSourceRegister{DefMI, DefSrcReg};
}
-MachineInstr *llvm::getDefIgnoringCopies(Register Reg,
- const MachineRegisterInfo &MRI) {
+MachineInstr *llvm::getDefIgnoringCopies(Register Reg,
+ const MachineRegisterInfo &MRI) {
Optional<DefinitionAndSourceRegister> DefSrcReg =
getDefSrcRegIgnoringCopies(Reg, MRI);
return DefSrcReg ? DefSrcReg->MI : nullptr;
@@ -400,8 +400,8 @@ Register llvm::getSrcRegIgnoringCopies(Register Reg,
return DefSrcReg ? DefSrcReg->Reg : Register();
}
-MachineInstr *llvm::getOpcodeDef(unsigned Opcode, Register Reg,
- const MachineRegisterInfo &MRI) {
+MachineInstr *llvm::getOpcodeDef(unsigned Opcode, Register Reg,
+ const MachineRegisterInfo &MRI) {
MachineInstr *DefMI = getDefIgnoringCopies(Reg, MRI);
return DefMI && DefMI->getOpcode() == Opcode ? DefMI : nullptr;
}
@@ -430,8 +430,8 @@ Optional<APInt> llvm::ConstantFoldBinOp(unsigned Opcode, const Register Op1,
if (!MaybeOp1Cst)
return None;
- const APInt &C1 = *MaybeOp1Cst;
- const APInt &C2 = *MaybeOp2Cst;
+ const APInt &C1 = *MaybeOp1Cst;
+ const APInt &C2 = *MaybeOp2Cst;
switch (Opcode) {
default:
break;
@@ -480,8 +480,8 @@ bool llvm::isKnownNeverNaN(Register Val, const MachineRegisterInfo &MRI,
if (!DefMI)
return false;
- const TargetMachine& TM = DefMI->getMF()->getTarget();
- if (DefMI->getFlag(MachineInstr::FmNoNans) || TM.Options.NoNaNsFPMath)
+ const TargetMachine& TM = DefMI->getMF()->getTarget();
+ if (DefMI->getFlag(MachineInstr::FmNoNans) || TM.Options.NoNaNsFPMath)
return true;
if (SNaN) {
@@ -512,40 +512,40 @@ Align llvm::inferAlignFromPtrInfo(MachineFunction &MF,
return Align(1);
}
-Register llvm::getFunctionLiveInPhysReg(MachineFunction &MF,
- const TargetInstrInfo &TII,
- MCRegister PhysReg,
- const TargetRegisterClass &RC,
- LLT RegTy) {
- DebugLoc DL; // FIXME: Is no location the right choice?
- MachineBasicBlock &EntryMBB = MF.front();
- MachineRegisterInfo &MRI = MF.getRegInfo();
- Register LiveIn = MRI.getLiveInVirtReg(PhysReg);
- if (LiveIn) {
- MachineInstr *Def = MRI.getVRegDef(LiveIn);
- if (Def) {
- // FIXME: Should the verifier check this is in the entry block?
- assert(Def->getParent() == &EntryMBB && "live-in copy not in entry block");
- return LiveIn;
- }
-
- // It's possible the incoming argument register and copy was added during
- // lowering, but later deleted due to being/becoming dead. If this happens,
- // re-insert the copy.
- } else {
- // The live in register was not present, so add it.
- LiveIn = MF.addLiveIn(PhysReg, &RC);
- if (RegTy.isValid())
- MRI.setType(LiveIn, RegTy);
- }
-
- BuildMI(EntryMBB, EntryMBB.begin(), DL, TII.get(TargetOpcode::COPY), LiveIn)
- .addReg(PhysReg);
- if (!EntryMBB.isLiveIn(PhysReg))
- EntryMBB.addLiveIn(PhysReg);
- return LiveIn;
-}
-
+Register llvm::getFunctionLiveInPhysReg(MachineFunction &MF,
+ const TargetInstrInfo &TII,
+ MCRegister PhysReg,
+ const TargetRegisterClass &RC,
+ LLT RegTy) {
+ DebugLoc DL; // FIXME: Is no location the right choice?
+ MachineBasicBlock &EntryMBB = MF.front();
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ Register LiveIn = MRI.getLiveInVirtReg(PhysReg);
+ if (LiveIn) {
+ MachineInstr *Def = MRI.getVRegDef(LiveIn);
+ if (Def) {
+ // FIXME: Should the verifier check this is in the entry block?
+ assert(Def->getParent() == &EntryMBB && "live-in copy not in entry block");
+ return LiveIn;
+ }
+
+ // It's possible the incoming argument register and copy was added during
+ // lowering, but later deleted due to being/becoming dead. If this happens,
+ // re-insert the copy.
+ } else {
+ // The live in register was not present, so add it.
+ LiveIn = MF.addLiveIn(PhysReg, &RC);
+ if (RegTy.isValid())
+ MRI.setType(LiveIn, RegTy);
+ }
+
+ BuildMI(EntryMBB, EntryMBB.begin(), DL, TII.get(TargetOpcode::COPY), LiveIn)
+ .addReg(PhysReg);
+ if (!EntryMBB.isLiveIn(PhysReg))
+ EntryMBB.addLiveIn(PhysReg);
+ return LiveIn;
+}
+
Optional<APInt> llvm::ConstantFoldExtOp(unsigned Opcode, const Register Op1,
uint64_t Imm,
const MachineRegisterInfo &MRI) {
@@ -554,262 +554,262 @@ Optional<APInt> llvm::ConstantFoldExtOp(unsigned Opcode, const Register Op1,
switch (Opcode) {
default:
break;
- case TargetOpcode::G_SEXT_INREG: {
- LLT Ty = MRI.getType(Op1);
- return MaybeOp1Cst->trunc(Imm).sext(Ty.getScalarSizeInBits());
+ case TargetOpcode::G_SEXT_INREG: {
+ LLT Ty = MRI.getType(Op1);
+ return MaybeOp1Cst->trunc(Imm).sext(Ty.getScalarSizeInBits());
+ }
}
- }
}
return None;
}
-bool llvm::isKnownToBeAPowerOfTwo(Register Reg, const MachineRegisterInfo &MRI,
- GISelKnownBits *KB) {
- Optional<DefinitionAndSourceRegister> DefSrcReg =
- getDefSrcRegIgnoringCopies(Reg, MRI);
- if (!DefSrcReg)
- return false;
-
- const MachineInstr &MI = *DefSrcReg->MI;
- const LLT Ty = MRI.getType(Reg);
-
- switch (MI.getOpcode()) {
- case TargetOpcode::G_CONSTANT: {
- unsigned BitWidth = Ty.getScalarSizeInBits();
- const ConstantInt *CI = MI.getOperand(1).getCImm();
- return CI->getValue().zextOrTrunc(BitWidth).isPowerOf2();
- }
- case TargetOpcode::G_SHL: {
- // A left-shift of a constant one will have exactly one bit set because
- // shifting the bit off the end is undefined.
-
- // TODO: Constant splat
- if (auto ConstLHS = getConstantVRegVal(MI.getOperand(1).getReg(), MRI)) {
- if (*ConstLHS == 1)
- return true;
- }
-
- break;
- }
- case TargetOpcode::G_LSHR: {
- if (auto ConstLHS = getConstantVRegVal(MI.getOperand(1).getReg(), MRI)) {
- if (ConstLHS->isSignMask())
- return true;
- }
-
- break;
- }
- default:
- break;
- }
-
- // TODO: Are all operands of a build vector constant powers of two?
- if (!KB)
- return false;
-
- // More could be done here, though the above checks are enough
- // to handle some common cases.
-
- // Fall back to computeKnownBits to catch other known cases.
- KnownBits Known = KB->getKnownBits(Reg);
- return (Known.countMaxPopulation() == 1) && (Known.countMinPopulation() == 1);
-}
-
+bool llvm::isKnownToBeAPowerOfTwo(Register Reg, const MachineRegisterInfo &MRI,
+ GISelKnownBits *KB) {
+ Optional<DefinitionAndSourceRegister> DefSrcReg =
+ getDefSrcRegIgnoringCopies(Reg, MRI);
+ if (!DefSrcReg)
+ return false;
+
+ const MachineInstr &MI = *DefSrcReg->MI;
+ const LLT Ty = MRI.getType(Reg);
+
+ switch (MI.getOpcode()) {
+ case TargetOpcode::G_CONSTANT: {
+ unsigned BitWidth = Ty.getScalarSizeInBits();
+ const ConstantInt *CI = MI.getOperand(1).getCImm();
+ return CI->getValue().zextOrTrunc(BitWidth).isPowerOf2();
+ }
+ case TargetOpcode::G_SHL: {
+ // A left-shift of a constant one will have exactly one bit set because
+ // shifting the bit off the end is undefined.
+
+ // TODO: Constant splat
+ if (auto ConstLHS = getConstantVRegVal(MI.getOperand(1).getReg(), MRI)) {
+ if (*ConstLHS == 1)
+ return true;
+ }
+
+ break;
+ }
+ case TargetOpcode::G_LSHR: {
+ if (auto ConstLHS = getConstantVRegVal(MI.getOperand(1).getReg(), MRI)) {
+ if (ConstLHS->isSignMask())
+ return true;
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+
+ // TODO: Are all operands of a build vector constant powers of two?
+ if (!KB)
+ return false;
+
+ // More could be done here, though the above checks are enough
+ // to handle some common cases.
+
+ // Fall back to computeKnownBits to catch other known cases.
+ KnownBits Known = KB->getKnownBits(Reg);
+ return (Known.countMaxPopulation() == 1) && (Known.countMinPopulation() == 1);
+}
+
void llvm::getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU) {
AU.addPreserved<StackProtector>();
}
-static unsigned getLCMSize(unsigned OrigSize, unsigned TargetSize) {
- unsigned Mul = OrigSize * TargetSize;
- unsigned GCDSize = greatestCommonDivisor(OrigSize, TargetSize);
- return Mul / GCDSize;
-}
-
-LLT llvm::getLCMType(LLT OrigTy, LLT TargetTy) {
- const unsigned OrigSize = OrigTy.getSizeInBits();
- const unsigned TargetSize = TargetTy.getSizeInBits();
-
- if (OrigSize == TargetSize)
- return OrigTy;
-
- if (OrigTy.isVector()) {
- const LLT OrigElt = OrigTy.getElementType();
-
- if (TargetTy.isVector()) {
- const LLT TargetElt = TargetTy.getElementType();
-
- if (OrigElt.getSizeInBits() == TargetElt.getSizeInBits()) {
- int GCDElts = greatestCommonDivisor(OrigTy.getNumElements(),
- TargetTy.getNumElements());
- // Prefer the original element type.
- int Mul = OrigTy.getNumElements() * TargetTy.getNumElements();
- return LLT::vector(Mul / GCDElts, OrigTy.getElementType());
- }
- } else {
- if (OrigElt.getSizeInBits() == TargetSize)
- return OrigTy;
- }
-
- unsigned LCMSize = getLCMSize(OrigSize, TargetSize);
- return LLT::vector(LCMSize / OrigElt.getSizeInBits(), OrigElt);
+static unsigned getLCMSize(unsigned OrigSize, unsigned TargetSize) {
+ unsigned Mul = OrigSize * TargetSize;
+ unsigned GCDSize = greatestCommonDivisor(OrigSize, TargetSize);
+ return Mul / GCDSize;
+}
+
+LLT llvm::getLCMType(LLT OrigTy, LLT TargetTy) {
+ const unsigned OrigSize = OrigTy.getSizeInBits();
+ const unsigned TargetSize = TargetTy.getSizeInBits();
+
+ if (OrigSize == TargetSize)
+ return OrigTy;
+
+ if (OrigTy.isVector()) {
+ const LLT OrigElt = OrigTy.getElementType();
+
+ if (TargetTy.isVector()) {
+ const LLT TargetElt = TargetTy.getElementType();
+
+ if (OrigElt.getSizeInBits() == TargetElt.getSizeInBits()) {
+ int GCDElts = greatestCommonDivisor(OrigTy.getNumElements(),
+ TargetTy.getNumElements());
+ // Prefer the original element type.
+ int Mul = OrigTy.getNumElements() * TargetTy.getNumElements();
+ return LLT::vector(Mul / GCDElts, OrigTy.getElementType());
+ }
+ } else {
+ if (OrigElt.getSizeInBits() == TargetSize)
+ return OrigTy;
+ }
+
+ unsigned LCMSize = getLCMSize(OrigSize, TargetSize);
+ return LLT::vector(LCMSize / OrigElt.getSizeInBits(), OrigElt);
}
- if (TargetTy.isVector()) {
- unsigned LCMSize = getLCMSize(OrigSize, TargetSize);
- return LLT::vector(LCMSize / OrigSize, OrigTy);
+ if (TargetTy.isVector()) {
+ unsigned LCMSize = getLCMSize(OrigSize, TargetSize);
+ return LLT::vector(LCMSize / OrigSize, OrigTy);
}
- unsigned LCMSize = getLCMSize(OrigSize, TargetSize);
-
- // Preserve pointer types.
- if (LCMSize == OrigSize)
- return OrigTy;
- if (LCMSize == TargetSize)
- return TargetTy;
-
- return LLT::scalar(LCMSize);
-}
-
-LLT llvm::getGCDType(LLT OrigTy, LLT TargetTy) {
- const unsigned OrigSize = OrigTy.getSizeInBits();
- const unsigned TargetSize = TargetTy.getSizeInBits();
-
- if (OrigSize == TargetSize)
- return OrigTy;
-
- if (OrigTy.isVector()) {
- LLT OrigElt = OrigTy.getElementType();
- if (TargetTy.isVector()) {
- LLT TargetElt = TargetTy.getElementType();
- if (OrigElt.getSizeInBits() == TargetElt.getSizeInBits()) {
- int GCD = greatestCommonDivisor(OrigTy.getNumElements(),
- TargetTy.getNumElements());
- return LLT::scalarOrVector(GCD, OrigElt);
- }
- } else {
- // If the source is a vector of pointers, return a pointer element.
- if (OrigElt.getSizeInBits() == TargetSize)
- return OrigElt;
- }
-
- unsigned GCD = greatestCommonDivisor(OrigSize, TargetSize);
- if (GCD == OrigElt.getSizeInBits())
- return OrigElt;
-
- // If we can't produce the original element type, we have to use a smaller
- // scalar.
- if (GCD < OrigElt.getSizeInBits())
- return LLT::scalar(GCD);
- return LLT::vector(GCD / OrigElt.getSizeInBits(), OrigElt);
+ unsigned LCMSize = getLCMSize(OrigSize, TargetSize);
+
+ // Preserve pointer types.
+ if (LCMSize == OrigSize)
+ return OrigTy;
+ if (LCMSize == TargetSize)
+ return TargetTy;
+
+ return LLT::scalar(LCMSize);
+}
+
+LLT llvm::getGCDType(LLT OrigTy, LLT TargetTy) {
+ const unsigned OrigSize = OrigTy.getSizeInBits();
+ const unsigned TargetSize = TargetTy.getSizeInBits();
+
+ if (OrigSize == TargetSize)
+ return OrigTy;
+
+ if (OrigTy.isVector()) {
+ LLT OrigElt = OrigTy.getElementType();
+ if (TargetTy.isVector()) {
+ LLT TargetElt = TargetTy.getElementType();
+ if (OrigElt.getSizeInBits() == TargetElt.getSizeInBits()) {
+ int GCD = greatestCommonDivisor(OrigTy.getNumElements(),
+ TargetTy.getNumElements());
+ return LLT::scalarOrVector(GCD, OrigElt);
+ }
+ } else {
+ // If the source is a vector of pointers, return a pointer element.
+ if (OrigElt.getSizeInBits() == TargetSize)
+ return OrigElt;
+ }
+
+ unsigned GCD = greatestCommonDivisor(OrigSize, TargetSize);
+ if (GCD == OrigElt.getSizeInBits())
+ return OrigElt;
+
+ // If we can't produce the original element type, we have to use a smaller
+ // scalar.
+ if (GCD < OrigElt.getSizeInBits())
+ return LLT::scalar(GCD);
+ return LLT::vector(GCD / OrigElt.getSizeInBits(), OrigElt);
+ }
+
+ if (TargetTy.isVector()) {
+ // Try to preserve the original element type.
+ LLT TargetElt = TargetTy.getElementType();
+ if (TargetElt.getSizeInBits() == OrigSize)
+ return OrigTy;
+ }
+
+ unsigned GCD = greatestCommonDivisor(OrigSize, TargetSize);
+ return LLT::scalar(GCD);
+}
+
+Optional<int> llvm::getSplatIndex(MachineInstr &MI) {
+ assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR &&
+ "Only G_SHUFFLE_VECTOR can have a splat index!");
+ ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask();
+ auto FirstDefinedIdx = find_if(Mask, [](int Elt) { return Elt >= 0; });
+
+ // If all elements are undefined, this shuffle can be considered a splat.
+ // Return 0 for better potential for callers to simplify.
+ if (FirstDefinedIdx == Mask.end())
+ return 0;
+
+ // Make sure all remaining elements are either undef or the same
+ // as the first non-undef value.
+ int SplatValue = *FirstDefinedIdx;
+ if (any_of(make_range(std::next(FirstDefinedIdx), Mask.end()),
+ [&SplatValue](int Elt) { return Elt >= 0 && Elt != SplatValue; }))
+ return None;
+
+ return SplatValue;
+}
+
+static bool isBuildVectorOp(unsigned Opcode) {
+ return Opcode == TargetOpcode::G_BUILD_VECTOR ||
+ Opcode == TargetOpcode::G_BUILD_VECTOR_TRUNC;
+}
+
+// TODO: Handle mixed undef elements.
+static bool isBuildVectorConstantSplat(const MachineInstr &MI,
+ const MachineRegisterInfo &MRI,
+ int64_t SplatValue) {
+ if (!isBuildVectorOp(MI.getOpcode()))
+ return false;
+
+ const unsigned NumOps = MI.getNumOperands();
+ for (unsigned I = 1; I != NumOps; ++I) {
+ Register Element = MI.getOperand(I).getReg();
+ if (!mi_match(Element, MRI, m_SpecificICst(SplatValue)))
+ return false;
}
- if (TargetTy.isVector()) {
- // Try to preserve the original element type.
- LLT TargetElt = TargetTy.getElementType();
- if (TargetElt.getSizeInBits() == OrigSize)
- return OrigTy;
- }
-
- unsigned GCD = greatestCommonDivisor(OrigSize, TargetSize);
- return LLT::scalar(GCD);
-}
-
-Optional<int> llvm::getSplatIndex(MachineInstr &MI) {
- assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR &&
- "Only G_SHUFFLE_VECTOR can have a splat index!");
- ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask();
- auto FirstDefinedIdx = find_if(Mask, [](int Elt) { return Elt >= 0; });
-
- // If all elements are undefined, this shuffle can be considered a splat.
- // Return 0 for better potential for callers to simplify.
- if (FirstDefinedIdx == Mask.end())
- return 0;
-
- // Make sure all remaining elements are either undef or the same
- // as the first non-undef value.
- int SplatValue = *FirstDefinedIdx;
- if (any_of(make_range(std::next(FirstDefinedIdx), Mask.end()),
- [&SplatValue](int Elt) { return Elt >= 0 && Elt != SplatValue; }))
- return None;
-
- return SplatValue;
-}
-
-static bool isBuildVectorOp(unsigned Opcode) {
- return Opcode == TargetOpcode::G_BUILD_VECTOR ||
- Opcode == TargetOpcode::G_BUILD_VECTOR_TRUNC;
-}
-
-// TODO: Handle mixed undef elements.
-static bool isBuildVectorConstantSplat(const MachineInstr &MI,
- const MachineRegisterInfo &MRI,
- int64_t SplatValue) {
- if (!isBuildVectorOp(MI.getOpcode()))
- return false;
-
- const unsigned NumOps = MI.getNumOperands();
- for (unsigned I = 1; I != NumOps; ++I) {
- Register Element = MI.getOperand(I).getReg();
- if (!mi_match(Element, MRI, m_SpecificICst(SplatValue)))
- return false;
+ return true;
+}
+
+Optional<int64_t>
+llvm::getBuildVectorConstantSplat(const MachineInstr &MI,
+ const MachineRegisterInfo &MRI) {
+ if (!isBuildVectorOp(MI.getOpcode()))
+ return None;
+
+ const unsigned NumOps = MI.getNumOperands();
+ Optional<int64_t> Scalar;
+ for (unsigned I = 1; I != NumOps; ++I) {
+ Register Element = MI.getOperand(I).getReg();
+ int64_t ElementValue;
+ if (!mi_match(Element, MRI, m_ICst(ElementValue)))
+ return None;
+ if (!Scalar)
+ Scalar = ElementValue;
+ else if (*Scalar != ElementValue)
+ return None;
}
- return true;
-}
-
-Optional<int64_t>
-llvm::getBuildVectorConstantSplat(const MachineInstr &MI,
- const MachineRegisterInfo &MRI) {
- if (!isBuildVectorOp(MI.getOpcode()))
- return None;
-
- const unsigned NumOps = MI.getNumOperands();
- Optional<int64_t> Scalar;
- for (unsigned I = 1; I != NumOps; ++I) {
- Register Element = MI.getOperand(I).getReg();
- int64_t ElementValue;
- if (!mi_match(Element, MRI, m_ICst(ElementValue)))
- return None;
- if (!Scalar)
- Scalar = ElementValue;
- else if (*Scalar != ElementValue)
- return None;
+ return Scalar;
+}
+
+bool llvm::isBuildVectorAllZeros(const MachineInstr &MI,
+ const MachineRegisterInfo &MRI) {
+ return isBuildVectorConstantSplat(MI, MRI, 0);
+}
+
+bool llvm::isBuildVectorAllOnes(const MachineInstr &MI,
+ const MachineRegisterInfo &MRI) {
+ return isBuildVectorConstantSplat(MI, MRI, -1);
+}
+
+bool llvm::isConstTrueVal(const TargetLowering &TLI, int64_t Val, bool IsVector,
+ bool IsFP) {
+ switch (TLI.getBooleanContents(IsVector, IsFP)) {
+ case TargetLowering::UndefinedBooleanContent:
+ return Val & 0x1;
+ case TargetLowering::ZeroOrOneBooleanContent:
+ return Val == 1;
+ case TargetLowering::ZeroOrNegativeOneBooleanContent:
+ return Val == -1;
}
+ llvm_unreachable("Invalid boolean contents");
+}
- return Scalar;
-}
-
-bool llvm::isBuildVectorAllZeros(const MachineInstr &MI,
- const MachineRegisterInfo &MRI) {
- return isBuildVectorConstantSplat(MI, MRI, 0);
-}
-
-bool llvm::isBuildVectorAllOnes(const MachineInstr &MI,
- const MachineRegisterInfo &MRI) {
- return isBuildVectorConstantSplat(MI, MRI, -1);
-}
-
-bool llvm::isConstTrueVal(const TargetLowering &TLI, int64_t Val, bool IsVector,
- bool IsFP) {
- switch (TLI.getBooleanContents(IsVector, IsFP)) {
- case TargetLowering::UndefinedBooleanContent:
- return Val & 0x1;
- case TargetLowering::ZeroOrOneBooleanContent:
- return Val == 1;
- case TargetLowering::ZeroOrNegativeOneBooleanContent:
- return Val == -1;
- }
- llvm_unreachable("Invalid boolean contents");
-}
-
-int64_t llvm::getICmpTrueVal(const TargetLowering &TLI, bool IsVector,
- bool IsFP) {
- switch (TLI.getBooleanContents(IsVector, IsFP)) {
- case TargetLowering::UndefinedBooleanContent:
- case TargetLowering::ZeroOrOneBooleanContent:
- return 1;
- case TargetLowering::ZeroOrNegativeOneBooleanContent:
- return -1;
- }
- llvm_unreachable("Invalid boolean contents");
-}
+int64_t llvm::getICmpTrueVal(const TargetLowering &TLI, bool IsVector,
+ bool IsFP) {
+ switch (TLI.getBooleanContents(IsVector, IsFP)) {
+ case TargetLowering::UndefinedBooleanContent:
+ case TargetLowering::ZeroOrOneBooleanContent:
+ return 1;
+ case TargetLowering::ZeroOrNegativeOneBooleanContent:
+ return -1;
+ }
+ llvm_unreachable("Invalid boolean contents");
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/ya.make b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/ya.make
index 6ede6da277..e6de0fe8d9 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalISel/ya.make
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalISel/ya.make
@@ -12,16 +12,16 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/CodeGen
- contrib/libs/llvm12/lib/CodeGen/SelectionDAG
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target
- contrib/libs/llvm12/lib/Transforms/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/CodeGen
+ contrib/libs/llvm12/lib/CodeGen/SelectionDAG
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target
+ contrib/libs/llvm12/lib/Transforms/Utils
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/CodeGen/GlobalMerge.cpp b/contrib/libs/llvm12/lib/CodeGen/GlobalMerge.cpp
index cff90b1dd4..6c1ce4c1ef 100644
--- a/contrib/libs/llvm12/lib/CodeGen/GlobalMerge.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/GlobalMerge.cpp
@@ -223,9 +223,9 @@ bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
// FIXME: Find better heuristics
llvm::stable_sort(
Globals, [&DL](const GlobalVariable *GV1, const GlobalVariable *GV2) {
- // We don't support scalable global variables.
- return DL.getTypeAllocSize(GV1->getValueType()).getFixedSize() <
- DL.getTypeAllocSize(GV2->getValueType()).getFixedSize();
+ // We don't support scalable global variables.
+ return DL.getTypeAllocSize(GV1->getValueType()).getFixedSize() <
+ DL.getTypeAllocSize(GV2->getValueType()).getFixedSize();
});
// If we want to just blindly group all globals together, do so.
diff --git a/contrib/libs/llvm12/lib/CodeGen/HardwareLoops.cpp b/contrib/libs/llvm12/lib/CodeGen/HardwareLoops.cpp
index 62972e9cb0..810b10c9c8 100644
--- a/contrib/libs/llvm12/lib/CodeGen/HardwareLoops.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/HardwareLoops.cpp
@@ -165,7 +165,7 @@ namespace {
Value *InitLoopCount();
// Insert the set_loop_iteration intrinsic.
- Value *InsertIterationSetup(Value *LoopCountInit);
+ Value *InsertIterationSetup(Value *LoopCountInit);
// Insert the loop_decrement intrinsic.
void InsertLoopDec();
@@ -187,7 +187,7 @@ namespace {
const DataLayout &DL,
OptimizationRemarkEmitter *ORE) :
SE(SE), DL(DL), ORE(ORE), L(Info.L), M(L->getHeader()->getModule()),
- TripCount(Info.TripCount),
+ TripCount(Info.TripCount),
CountType(Info.CountType),
ExitBranch(Info.ExitBranch),
LoopDecrement(Info.LoopDecrement),
@@ -202,7 +202,7 @@ namespace {
OptimizationRemarkEmitter *ORE = nullptr;
Loop *L = nullptr;
Module *M = nullptr;
- const SCEV *TripCount = nullptr;
+ const SCEV *TripCount = nullptr;
Type *CountType = nullptr;
BranchInst *ExitBranch = nullptr;
Value *LoopDecrement = nullptr;
@@ -234,7 +234,7 @@ bool HardwareLoops::runOnFunction(Function &F) {
for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I) {
Loop *L = *I;
- if (L->isOutermost())
+ if (L->isOutermost())
TryConvertLoop(L);
}
@@ -298,7 +298,7 @@ bool HardwareLoops::TryConvertLoop(HardwareLoopInfo &HWLoopInfo) {
}
assert(
- (HWLoopInfo.ExitBlock && HWLoopInfo.ExitBranch && HWLoopInfo.TripCount) &&
+ (HWLoopInfo.ExitBlock && HWLoopInfo.ExitBranch && HWLoopInfo.TripCount) &&
"Hardware Loop must have set exit info.");
BasicBlock *Preheader = L->getLoopPreheader();
@@ -325,11 +325,11 @@ void HardwareLoop::Create() {
return;
}
- Value *Setup = InsertIterationSetup(LoopCountInit);
+ Value *Setup = InsertIterationSetup(LoopCountInit);
if (UsePHICounter || ForceHardwareLoopPHI) {
Instruction *LoopDec = InsertLoopRegDec(LoopCountInit);
- Value *EltsRem = InsertPHICounter(Setup, LoopDec);
+ Value *EltsRem = InsertPHICounter(Setup, LoopDec);
LoopDec->setOperand(0, EltsRem);
UpdateBranch(LoopDec);
} else
@@ -388,8 +388,8 @@ Value *HardwareLoop::InitLoopCount() {
// to replace a conditional branch that is controlling entry to the loop. It
// is likely (guaranteed?) that the preheader has an unconditional branch to
// the loop header, so also check if it has a single predecessor.
- if (SE.isLoopEntryGuardedByCond(L, ICmpInst::ICMP_NE, TripCount,
- SE.getZero(TripCount->getType()))) {
+ if (SE.isLoopEntryGuardedByCond(L, ICmpInst::ICMP_NE, TripCount,
+ SE.getZero(TripCount->getType()))) {
LLVM_DEBUG(dbgs() << " - Attempting to use test.set counter.\n");
UseLoopGuard |= ForceGuardLoopEntry;
} else
@@ -397,23 +397,23 @@ Value *HardwareLoop::InitLoopCount() {
BasicBlock *BB = L->getLoopPreheader();
if (UseLoopGuard && BB->getSinglePredecessor() &&
- cast<BranchInst>(BB->getTerminator())->isUnconditional()) {
- BasicBlock *Predecessor = BB->getSinglePredecessor();
- // If it's not safe to create a while loop then don't force it and create a
- // do-while loop instead
- if (!isSafeToExpandAt(TripCount, Predecessor->getTerminator(), SE))
- UseLoopGuard = false;
- else
- BB = Predecessor;
- }
-
- if (!isSafeToExpandAt(TripCount, BB->getTerminator(), SE)) {
- LLVM_DEBUG(dbgs() << "- Bailing, unsafe to expand TripCount "
- << *TripCount << "\n");
+ cast<BranchInst>(BB->getTerminator())->isUnconditional()) {
+ BasicBlock *Predecessor = BB->getSinglePredecessor();
+ // If it's not safe to create a while loop then don't force it and create a
+ // do-while loop instead
+ if (!isSafeToExpandAt(TripCount, Predecessor->getTerminator(), SE))
+ UseLoopGuard = false;
+ else
+ BB = Predecessor;
+ }
+
+ if (!isSafeToExpandAt(TripCount, BB->getTerminator(), SE)) {
+ LLVM_DEBUG(dbgs() << "- Bailing, unsafe to expand TripCount "
+ << *TripCount << "\n");
return nullptr;
}
- Value *Count = SCEVE.expandCodeFor(TripCount, CountType,
+ Value *Count = SCEVE.expandCodeFor(TripCount, CountType,
BB->getTerminator());
// FIXME: We've expanded Count where we hope to insert the counter setting
@@ -432,13 +432,13 @@ Value *HardwareLoop::InitLoopCount() {
return Count;
}
-Value* HardwareLoop::InsertIterationSetup(Value *LoopCountInit) {
+Value* HardwareLoop::InsertIterationSetup(Value *LoopCountInit) {
IRBuilder<> Builder(BeginBB->getTerminator());
Type *Ty = LoopCountInit->getType();
- bool UsePhi = UsePHICounter || ForceHardwareLoopPHI;
- Intrinsic::ID ID = UseLoopGuard ? Intrinsic::test_set_loop_iterations
- : (UsePhi ? Intrinsic::start_loop_iterations
- : Intrinsic::set_loop_iterations);
+ bool UsePhi = UsePHICounter || ForceHardwareLoopPHI;
+ Intrinsic::ID ID = UseLoopGuard ? Intrinsic::test_set_loop_iterations
+ : (UsePhi ? Intrinsic::start_loop_iterations
+ : Intrinsic::set_loop_iterations);
Function *LoopIter = Intrinsic::getDeclaration(M, ID, Ty);
Value *SetCount = Builder.CreateCall(LoopIter, LoopCountInit);
@@ -454,7 +454,7 @@ Value* HardwareLoop::InsertIterationSetup(Value *LoopCountInit) {
}
LLVM_DEBUG(dbgs() << "HWLoops: Inserted loop counter: "
<< *SetCount << "\n");
- return UseLoopGuard ? LoopCountInit : SetCount;
+ return UseLoopGuard ? LoopCountInit : SetCount;
}
void HardwareLoop::InsertLoopDec() {
diff --git a/contrib/libs/llvm12/lib/CodeGen/IfConversion.cpp b/contrib/libs/llvm12/lib/CodeGen/IfConversion.cpp
index 4cdc3c0b4f..37be2eabf5 100644
--- a/contrib/libs/llvm12/lib/CodeGen/IfConversion.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/IfConversion.cpp
@@ -751,7 +751,7 @@ bool IfConverter::CountDuplicatedInstructions(
// A pred-clobbering instruction in the shared portion prevents
// if-conversion.
std::vector<MachineOperand> PredDefs;
- if (TII->ClobbersPredicate(*TIB, PredDefs, false))
+ if (TII->ClobbersPredicate(*TIB, PredDefs, false))
return false;
// If we get all the way to the branch instructions, don't count them.
if (!TIB->isBranch())
@@ -1146,7 +1146,7 @@ void IfConverter::ScanInstructions(BBInfo &BBI,
// FIXME: Make use of PredDefs? e.g. ADDC, SUBC sets predicates but are
// still potentially predicable.
std::vector<MachineOperand> PredDefs;
- if (TII->ClobbersPredicate(MI, PredDefs, true))
+ if (TII->ClobbersPredicate(MI, PredDefs, true))
BBI.ClobbersPred = true;
if (!TII->isPredicable(MI)) {
@@ -2264,7 +2264,7 @@ void IfConverter::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI, bool AddEdges) {
if (ToBBI.IsBrAnalyzable)
ToBBI.BB->normalizeSuccProbs();
- SmallVector<MachineBasicBlock *, 4> FromSuccs(FromMBB.successors());
+ SmallVector<MachineBasicBlock *, 4> FromSuccs(FromMBB.successors());
MachineBasicBlock *NBB = getNextBlock(FromMBB);
MachineBasicBlock *FallThrough = FromBBI.HasFallThrough ? NBB : nullptr;
// The edge probability from ToBBI.BB to FromMBB, which is only needed when
diff --git a/contrib/libs/llvm12/lib/CodeGen/ImplicitNullChecks.cpp b/contrib/libs/llvm12/lib/CodeGen/ImplicitNullChecks.cpp
index 93b4c06ae6..5cdaa9b74e 100644
--- a/contrib/libs/llvm12/lib/CodeGen/ImplicitNullChecks.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/ImplicitNullChecks.cpp
@@ -200,16 +200,16 @@ class ImplicitNullChecks : public MachineFunctionPass {
unsigned PointerReg,
ArrayRef<MachineInstr *> PrevInsts);
- /// Returns true if \p DependenceMI can clobber the liveIns in NullSucc block
- /// if it was hoisted to the NullCheck block. This is used by caller
- /// canHoistInst to decide if DependenceMI can be hoisted safely.
- bool canDependenceHoistingClobberLiveIns(MachineInstr *DependenceMI,
- MachineBasicBlock *NullSucc);
-
+ /// Returns true if \p DependenceMI can clobber the liveIns in NullSucc block
+ /// if it was hoisted to the NullCheck block. This is used by caller
+ /// canHoistInst to decide if DependenceMI can be hoisted safely.
+ bool canDependenceHoistingClobberLiveIns(MachineInstr *DependenceMI,
+ MachineBasicBlock *NullSucc);
+
/// Return true if \p FaultingMI can be hoisted from after the
/// instructions in \p InstsSeenSoFar to before them. Set \p Dependence to a
- /// non-null value if we also need to (and legally can) hoist a dependency.
- bool canHoistInst(MachineInstr *FaultingMI,
+ /// non-null value if we also need to (and legally can) hoist a dependency.
+ bool canHoistInst(MachineInstr *FaultingMI,
ArrayRef<MachineInstr *> InstsSeenSoFar,
MachineBasicBlock *NullSucc, MachineInstr *&Dependence);
@@ -281,12 +281,12 @@ bool ImplicitNullChecks::canReorder(const MachineInstr *A,
// between A and B here -- for instance, we should not be dealing with heap
// load-store dependencies here.
- for (const auto &MOA : A->operands()) {
+ for (const auto &MOA : A->operands()) {
if (!(MOA.isReg() && MOA.getReg()))
continue;
Register RegA = MOA.getReg();
- for (const auto &MOB : B->operands()) {
+ for (const auto &MOB : B->operands()) {
if (!(MOB.isReg() && MOB.getReg()))
continue;
@@ -353,9 +353,9 @@ ImplicitNullChecks::areMemoryOpsAliased(const MachineInstr &MI,
return AR_MayAlias;
continue;
}
- llvm::AliasResult AAResult = AA->alias(
- MemoryLocation::getAfter(MMO1->getValue(), MMO1->getAAInfo()),
- MemoryLocation::getAfter(MMO2->getValue(), MMO2->getAAInfo()));
+ llvm::AliasResult AAResult = AA->alias(
+ MemoryLocation::getAfter(MMO1->getValue(), MMO1->getAAInfo()),
+ MemoryLocation::getAfter(MMO2->getValue(), MMO2->getAAInfo()));
if (AAResult != NoAlias)
return AR_MayAlias;
}
@@ -367,105 +367,105 @@ ImplicitNullChecks::SuitabilityResult
ImplicitNullChecks::isSuitableMemoryOp(const MachineInstr &MI,
unsigned PointerReg,
ArrayRef<MachineInstr *> PrevInsts) {
- // Implementation restriction for faulting_op insertion
- // TODO: This could be relaxed if we find a test case which warrants it.
- if (MI.getDesc().getNumDefs() > 1)
- return SR_Unsuitable;
-
- if (!MI.mayLoadOrStore() || MI.isPredicable())
- return SR_Unsuitable;
- auto AM = TII->getAddrModeFromMemoryOp(MI, TRI);
- if (!AM)
- return SR_Unsuitable;
- auto AddrMode = *AM;
- const Register BaseReg = AddrMode.BaseReg, ScaledReg = AddrMode.ScaledReg;
- int64_t Displacement = AddrMode.Displacement;
-
- // We need the base of the memory instruction to be same as the register
- // where the null check is performed (i.e. PointerReg).
- if (BaseReg != PointerReg && ScaledReg != PointerReg)
+ // Implementation restriction for faulting_op insertion
+ // TODO: This could be relaxed if we find a test case which warrants it.
+ if (MI.getDesc().getNumDefs() > 1)
+ return SR_Unsuitable;
+
+ if (!MI.mayLoadOrStore() || MI.isPredicable())
+ return SR_Unsuitable;
+ auto AM = TII->getAddrModeFromMemoryOp(MI, TRI);
+ if (!AM)
+ return SR_Unsuitable;
+ auto AddrMode = *AM;
+ const Register BaseReg = AddrMode.BaseReg, ScaledReg = AddrMode.ScaledReg;
+ int64_t Displacement = AddrMode.Displacement;
+
+ // We need the base of the memory instruction to be same as the register
+ // where the null check is performed (i.e. PointerReg).
+ if (BaseReg != PointerReg && ScaledReg != PointerReg)
return SR_Unsuitable;
- const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
- unsigned PointerRegSizeInBits = TRI->getRegSizeInBits(PointerReg, MRI);
- // Bail out of the sizes of BaseReg, ScaledReg and PointerReg are not the
- // same.
- if ((BaseReg &&
- TRI->getRegSizeInBits(BaseReg, MRI) != PointerRegSizeInBits) ||
- (ScaledReg &&
- TRI->getRegSizeInBits(ScaledReg, MRI) != PointerRegSizeInBits))
- return SR_Unsuitable;
-
- // Returns true if RegUsedInAddr is used for calculating the displacement
- // depending on addressing mode. Also calculates the Displacement.
- auto CalculateDisplacementFromAddrMode = [&](Register RegUsedInAddr,
- int64_t Multiplier) {
- // The register can be NoRegister, which is defined as zero for all targets.
- // Consider instruction of interest as `movq 8(,%rdi,8), %rax`. Here the
- // ScaledReg is %rdi, while there is no BaseReg.
- if (!RegUsedInAddr)
- return false;
- assert(Multiplier && "expected to be non-zero!");
- MachineInstr *ModifyingMI = nullptr;
- for (auto It = std::next(MachineBasicBlock::const_reverse_iterator(&MI));
- It != MI.getParent()->rend(); It++) {
- const MachineInstr *CurrMI = &*It;
- if (CurrMI->modifiesRegister(RegUsedInAddr, TRI)) {
- ModifyingMI = const_cast<MachineInstr *>(CurrMI);
- break;
- }
- }
- if (!ModifyingMI)
- return false;
- // Check for the const value defined in register by ModifyingMI. This means
- // all other previous values for that register has been invalidated.
- int64_t ImmVal;
- if (!TII->getConstValDefinedInReg(*ModifyingMI, RegUsedInAddr, ImmVal))
- return false;
- // Calculate the reg size in bits, since this is needed for bailing out in
- // case of overflow.
- int32_t RegSizeInBits = TRI->getRegSizeInBits(RegUsedInAddr, MRI);
- APInt ImmValC(RegSizeInBits, ImmVal, true /*IsSigned*/);
- APInt MultiplierC(RegSizeInBits, Multiplier);
- assert(MultiplierC.isStrictlyPositive() &&
- "expected to be a positive value!");
- bool IsOverflow;
- // Sign of the product depends on the sign of the ImmVal, since Multiplier
- // is always positive.
- APInt Product = ImmValC.smul_ov(MultiplierC, IsOverflow);
- if (IsOverflow)
- return false;
- APInt DisplacementC(64, Displacement, true /*isSigned*/);
- DisplacementC = Product.sadd_ov(DisplacementC, IsOverflow);
- if (IsOverflow)
- return false;
-
- // We only handle diplacements upto 64 bits wide.
- if (DisplacementC.getActiveBits() > 64)
- return false;
- Displacement = DisplacementC.getSExtValue();
- return true;
- };
-
- // If a register used in the address is constant, fold it's effect into the
- // displacement for ease of analysis.
- bool BaseRegIsConstVal = false, ScaledRegIsConstVal = false;
- if (CalculateDisplacementFromAddrMode(BaseReg, 1))
- BaseRegIsConstVal = true;
- if (CalculateDisplacementFromAddrMode(ScaledReg, AddrMode.Scale))
- ScaledRegIsConstVal = true;
-
- // The register which is not null checked should be part of the Displacement
- // calculation, otherwise we do not know whether the Displacement is made up
- // by some symbolic values.
- // This matters because we do not want to incorrectly assume that load from
- // falls in the zeroth faulting page in the "sane offset check" below.
- if ((BaseReg && BaseReg != PointerReg && !BaseRegIsConstVal) ||
- (ScaledReg && ScaledReg != PointerReg && !ScaledRegIsConstVal))
+ const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
+ unsigned PointerRegSizeInBits = TRI->getRegSizeInBits(PointerReg, MRI);
+ // Bail out of the sizes of BaseReg, ScaledReg and PointerReg are not the
+ // same.
+ if ((BaseReg &&
+ TRI->getRegSizeInBits(BaseReg, MRI) != PointerRegSizeInBits) ||
+ (ScaledReg &&
+ TRI->getRegSizeInBits(ScaledReg, MRI) != PointerRegSizeInBits))
+ return SR_Unsuitable;
+
+ // Returns true if RegUsedInAddr is used for calculating the displacement
+ // depending on addressing mode. Also calculates the Displacement.
+ auto CalculateDisplacementFromAddrMode = [&](Register RegUsedInAddr,
+ int64_t Multiplier) {
+ // The register can be NoRegister, which is defined as zero for all targets.
+ // Consider instruction of interest as `movq 8(,%rdi,8), %rax`. Here the
+ // ScaledReg is %rdi, while there is no BaseReg.
+ if (!RegUsedInAddr)
+ return false;
+ assert(Multiplier && "expected to be non-zero!");
+ MachineInstr *ModifyingMI = nullptr;
+ for (auto It = std::next(MachineBasicBlock::const_reverse_iterator(&MI));
+ It != MI.getParent()->rend(); It++) {
+ const MachineInstr *CurrMI = &*It;
+ if (CurrMI->modifiesRegister(RegUsedInAddr, TRI)) {
+ ModifyingMI = const_cast<MachineInstr *>(CurrMI);
+ break;
+ }
+ }
+ if (!ModifyingMI)
+ return false;
+ // Check for the const value defined in register by ModifyingMI. This means
+ // all other previous values for that register has been invalidated.
+ int64_t ImmVal;
+ if (!TII->getConstValDefinedInReg(*ModifyingMI, RegUsedInAddr, ImmVal))
+ return false;
+ // Calculate the reg size in bits, since this is needed for bailing out in
+ // case of overflow.
+ int32_t RegSizeInBits = TRI->getRegSizeInBits(RegUsedInAddr, MRI);
+ APInt ImmValC(RegSizeInBits, ImmVal, true /*IsSigned*/);
+ APInt MultiplierC(RegSizeInBits, Multiplier);
+ assert(MultiplierC.isStrictlyPositive() &&
+ "expected to be a positive value!");
+ bool IsOverflow;
+ // Sign of the product depends on the sign of the ImmVal, since Multiplier
+ // is always positive.
+ APInt Product = ImmValC.smul_ov(MultiplierC, IsOverflow);
+ if (IsOverflow)
+ return false;
+ APInt DisplacementC(64, Displacement, true /*isSigned*/);
+ DisplacementC = Product.sadd_ov(DisplacementC, IsOverflow);
+ if (IsOverflow)
+ return false;
+
+ // We only handle diplacements upto 64 bits wide.
+ if (DisplacementC.getActiveBits() > 64)
+ return false;
+ Displacement = DisplacementC.getSExtValue();
+ return true;
+ };
+
+ // If a register used in the address is constant, fold it's effect into the
+ // displacement for ease of analysis.
+ bool BaseRegIsConstVal = false, ScaledRegIsConstVal = false;
+ if (CalculateDisplacementFromAddrMode(BaseReg, 1))
+ BaseRegIsConstVal = true;
+ if (CalculateDisplacementFromAddrMode(ScaledReg, AddrMode.Scale))
+ ScaledRegIsConstVal = true;
+
+ // The register which is not null checked should be part of the Displacement
+ // calculation, otherwise we do not know whether the Displacement is made up
+ // by some symbolic values.
+ // This matters because we do not want to incorrectly assume that load from
+ // falls in the zeroth faulting page in the "sane offset check" below.
+ if ((BaseReg && BaseReg != PointerReg && !BaseRegIsConstVal) ||
+ (ScaledReg && ScaledReg != PointerReg && !ScaledRegIsConstVal))
return SR_Unsuitable;
// We want the mem access to be issued at a sane offset from PointerReg,
// so that if PointerReg is null then the access reliably page faults.
- if (!(-PageSize < Displacement && Displacement < PageSize))
+ if (!(-PageSize < Displacement && Displacement < PageSize))
return SR_Unsuitable;
// Finally, check whether the current memory access aliases with previous one.
@@ -479,38 +479,38 @@ ImplicitNullChecks::isSuitableMemoryOp(const MachineInstr &MI,
return SR_Suitable;
}
-bool ImplicitNullChecks::canDependenceHoistingClobberLiveIns(
- MachineInstr *DependenceMI, MachineBasicBlock *NullSucc) {
- for (const auto &DependenceMO : DependenceMI->operands()) {
- if (!(DependenceMO.isReg() && DependenceMO.getReg()))
- continue;
-
- // Make sure that we won't clobber any live ins to the sibling block by
- // hoisting Dependency. For instance, we can't hoist INST to before the
- // null check (even if it safe, and does not violate any dependencies in
- // the non_null_block) if %rdx is live in to _null_block.
- //
- // test %rcx, %rcx
- // je _null_block
- // _non_null_block:
- // %rdx = INST
- // ...
- //
- // This restriction does not apply to the faulting load inst because in
- // case the pointer loaded from is in the null page, the load will not
- // semantically execute, and affect machine state. That is, if the load
- // was loading into %rax and it faults, the value of %rax should stay the
- // same as it would have been had the load not have executed and we'd have
- // branched to NullSucc directly.
- if (AnyAliasLiveIn(TRI, NullSucc, DependenceMO.getReg()))
- return true;
-
- }
-
- // The dependence does not clobber live-ins in NullSucc block.
- return false;
-}
-
+bool ImplicitNullChecks::canDependenceHoistingClobberLiveIns(
+ MachineInstr *DependenceMI, MachineBasicBlock *NullSucc) {
+ for (const auto &DependenceMO : DependenceMI->operands()) {
+ if (!(DependenceMO.isReg() && DependenceMO.getReg()))
+ continue;
+
+ // Make sure that we won't clobber any live ins to the sibling block by
+ // hoisting Dependency. For instance, we can't hoist INST to before the
+ // null check (even if it safe, and does not violate any dependencies in
+ // the non_null_block) if %rdx is live in to _null_block.
+ //
+ // test %rcx, %rcx
+ // je _null_block
+ // _non_null_block:
+ // %rdx = INST
+ // ...
+ //
+ // This restriction does not apply to the faulting load inst because in
+ // case the pointer loaded from is in the null page, the load will not
+ // semantically execute, and affect machine state. That is, if the load
+ // was loading into %rax and it faults, the value of %rax should stay the
+ // same as it would have been had the load not have executed and we'd have
+ // branched to NullSucc directly.
+ if (AnyAliasLiveIn(TRI, NullSucc, DependenceMO.getReg()))
+ return true;
+
+ }
+
+ // The dependence does not clobber live-ins in NullSucc block.
+ return false;
+}
+
bool ImplicitNullChecks::canHoistInst(MachineInstr *FaultingMI,
ArrayRef<MachineInstr *> InstsSeenSoFar,
MachineBasicBlock *NullSucc,
@@ -536,8 +536,8 @@ bool ImplicitNullChecks::canHoistInst(MachineInstr *FaultingMI,
if (DependenceMI->mayLoadOrStore())
return false;
- if (canDependenceHoistingClobberLiveIns(DependenceMI, NullSucc))
- return false;
+ if (canDependenceHoistingClobberLiveIns(DependenceMI, NullSucc))
+ return false;
auto DepDepResult =
computeDependence(DependenceMI, {InstsSeenSoFar.begin(), DependenceItr});
@@ -574,9 +574,9 @@ bool ImplicitNullChecks::analyzeBlockForNullChecks(
MBP.Predicate == MachineBranchPredicate::PRED_EQ)))
return false;
- // If there is a separate condition generation instruction, we chose not to
- // transform unless we can remove both condition and consuming branch.
- if (MBP.ConditionDef && !MBP.SingleUseCondition)
+ // If there is a separate condition generation instruction, we chose not to
+ // transform unless we can remove both condition and consuming branch.
+ if (MBP.ConditionDef && !MBP.SingleUseCondition)
return false;
MachineBasicBlock *NotNullSucc, *NullSucc;
@@ -596,32 +596,32 @@ bool ImplicitNullChecks::analyzeBlockForNullChecks(
const Register PointerReg = MBP.LHS.getReg();
- if (MBP.ConditionDef) {
- // To prevent the invalid transformation of the following code:
- //
- // mov %rax, %rcx
- // test %rax, %rax
- // %rax = ...
- // je throw_npe
- // mov(%rcx), %r9
- // mov(%rax), %r10
- //
- // into:
- //
- // mov %rax, %rcx
- // %rax = ....
- // faulting_load_op("movl (%rax), %r10", throw_npe)
- // mov(%rcx), %r9
- //
- // we must ensure that there are no instructions between the 'test' and
- // conditional jump that modify %rax.
- assert(MBP.ConditionDef->getParent() == &MBB &&
- "Should be in basic block");
-
- for (auto I = MBB.rbegin(); MBP.ConditionDef != &*I; ++I)
- if (I->modifiesRegister(PointerReg, TRI))
- return false;
- }
+ if (MBP.ConditionDef) {
+ // To prevent the invalid transformation of the following code:
+ //
+ // mov %rax, %rcx
+ // test %rax, %rax
+ // %rax = ...
+ // je throw_npe
+ // mov(%rcx), %r9
+ // mov(%rax), %r10
+ //
+ // into:
+ //
+ // mov %rax, %rcx
+ // %rax = ....
+ // faulting_load_op("movl (%rax), %r10", throw_npe)
+ // mov(%rcx), %r9
+ //
+ // we must ensure that there are no instructions between the 'test' and
+ // conditional jump that modify %rax.
+ assert(MBP.ConditionDef->getParent() == &MBB &&
+ "Should be in basic block");
+
+ for (auto I = MBB.rbegin(); MBP.ConditionDef != &*I; ++I)
+ if (I->modifiesRegister(PointerReg, TRI))
+ return false;
+ }
// Starting with a code fragment like:
//
// test %rax, %rax
@@ -687,15 +687,15 @@ bool ImplicitNullChecks::analyzeBlockForNullChecks(
if (SR == SR_Impossible)
return false;
if (SR == SR_Suitable &&
- canHoistInst(&MI, InstsSeenSoFar, NullSucc, Dependence)) {
+ canHoistInst(&MI, InstsSeenSoFar, NullSucc, Dependence)) {
NullCheckList.emplace_back(&MI, MBP.ConditionDef, &MBB, NotNullSucc,
NullSucc, Dependence);
return true;
}
- // If MI re-defines the PointerReg in a way that changes the value of
- // PointerReg if it was null, then we cannot move further.
- if (!TII->preservesZeroValueInReg(&MI, PointerReg, TRI))
+ // If MI re-defines the PointerReg in a way that changes the value of
+ // PointerReg if it was null, then we cannot move further.
+ if (!TII->preservesZeroValueInReg(&MI, PointerReg, TRI))
return false;
InstsSeenSoFar.push_back(&MI);
}
@@ -800,11 +800,11 @@ void ImplicitNullChecks::rewriteNullChecks(
}
NC.getMemOperation()->eraseFromParent();
- if (auto *CheckOp = NC.getCheckOperation())
- CheckOp->eraseFromParent();
+ if (auto *CheckOp = NC.getCheckOperation())
+ CheckOp->eraseFromParent();
- // Insert an *unconditional* branch to not-null successor - we expect
- // block placement to remove fallthroughs later.
+ // Insert an *unconditional* branch to not-null successor - we expect
+ // block placement to remove fallthroughs later.
TII->insertBranch(*NC.getCheckBlock(), NC.getNotNullSucc(), nullptr,
/*Cond=*/None, DL);
diff --git a/contrib/libs/llvm12/lib/CodeGen/InlineSpiller.cpp b/contrib/libs/llvm12/lib/CodeGen/InlineSpiller.cpp
index ab43fb9db9..876e1d3f93 100644
--- a/contrib/libs/llvm12/lib/CodeGen/InlineSpiller.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/InlineSpiller.cpp
@@ -153,7 +153,7 @@ public:
unsigned Original);
bool rmFromMergeableSpills(MachineInstr &Spill, int StackSlot);
void hoistAllSpills();
- void LRE_DidCloneVirtReg(Register, Register) override;
+ void LRE_DidCloneVirtReg(Register, Register) override;
};
class InlineSpiller : public Spiller {
@@ -269,14 +269,14 @@ static Register isFullCopyOf(const MachineInstr &MI, Register Reg) {
return Register();
}
-static void getVDefInterval(const MachineInstr &MI, LiveIntervals &LIS) {
- for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
- const MachineOperand &MO = MI.getOperand(I);
- if (MO.isReg() && MO.isDef() && Register::isVirtualRegister(MO.getReg()))
- LIS.getInterval(MO.getReg());
- }
-}
-
+static void getVDefInterval(const MachineInstr &MI, LiveIntervals &LIS) {
+ for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
+ const MachineOperand &MO = MI.getOperand(I);
+ if (MO.isReg() && MO.isDef() && Register::isVirtualRegister(MO.getReg()))
+ LIS.getInterval(MO.getReg());
+ }
+}
+
/// isSnippet - Identify if a live interval is a snippet that should be spilled.
/// It is assumed that SnipLI is a virtual register with the same original as
/// Edit->getReg().
@@ -297,9 +297,9 @@ bool InlineSpiller::isSnippet(const LiveInterval &SnipLI) {
// Check that all uses satisfy our criteria.
for (MachineRegisterInfo::reg_instr_nodbg_iterator
- RI = MRI.reg_instr_nodbg_begin(SnipLI.reg()),
- E = MRI.reg_instr_nodbg_end();
- RI != E;) {
+ RI = MRI.reg_instr_nodbg_begin(SnipLI.reg()),
+ E = MRI.reg_instr_nodbg_end();
+ RI != E;) {
MachineInstr &MI = *RI++;
// Allow copies to/from Reg.
@@ -308,11 +308,11 @@ bool InlineSpiller::isSnippet(const LiveInterval &SnipLI) {
// Allow stack slot loads.
int FI;
- if (SnipLI.reg() == TII.isLoadFromStackSlot(MI, FI) && FI == StackSlot)
+ if (SnipLI.reg() == TII.isLoadFromStackSlot(MI, FI) && FI == StackSlot)
continue;
// Allow stack slot stores.
- if (SnipLI.reg() == TII.isStoreToStackSlot(MI, FI) && FI == StackSlot)
+ if (SnipLI.reg() == TII.isStoreToStackSlot(MI, FI) && FI == StackSlot)
continue;
// Allow a single additional instruction.
@@ -418,21 +418,21 @@ bool InlineSpiller::hoistSpillInsideBB(LiveInterval &SpillLI,
MII = DefMI;
++MII;
}
- MachineInstrSpan MIS(MII, MBB);
+ MachineInstrSpan MIS(MII, MBB);
// Insert spill without kill flag immediately after def.
TII.storeRegToStackSlot(*MBB, MII, SrcReg, false, StackSlot,
MRI.getRegClass(SrcReg), &TRI);
- LIS.InsertMachineInstrRangeInMaps(MIS.begin(), MII);
- for (const MachineInstr &MI : make_range(MIS.begin(), MII))
- getVDefInterval(MI, LIS);
+ LIS.InsertMachineInstrRangeInMaps(MIS.begin(), MII);
+ for (const MachineInstr &MI : make_range(MIS.begin(), MII))
+ getVDefInterval(MI, LIS);
--MII; // Point to store instruction.
LLVM_DEBUG(dbgs() << "\thoisted: " << SrcVNI->def << '\t' << *MII);
- // If there is only 1 store instruction is required for spill, add it
- // to mergeable list. In X86 AMX, 2 intructions are required to store.
- // We disable the merge for this case.
- if (MIS.begin() == MII)
- HSpiller.addToMergeableSpills(*MII, StackSlot, Original);
+ // If there is only 1 store instruction is required for spill, add it
+ // to mergeable list. In X86 AMX, 2 intructions are required to store.
+ // We disable the merge for this case.
+ if (MIS.begin() == MII)
+ HSpiller.addToMergeableSpills(*MII, StackSlot, Original);
++NumSpills;
return true;
}
@@ -448,7 +448,7 @@ void InlineSpiller::eliminateRedundantSpills(LiveInterval &SLI, VNInfo *VNI) {
do {
LiveInterval *LI;
std::tie(LI, VNI) = WorkList.pop_back_val();
- Register Reg = LI->reg();
+ Register Reg = LI->reg();
LLVM_DEBUG(dbgs() << "Checking redundant spills for " << VNI->id << '@'
<< VNI->def << " in " << *LI << '\n');
@@ -527,7 +527,7 @@ void InlineSpiller::markValueUsed(LiveInterval *LI, VNInfo *VNI) {
if (!SnippetCopies.count(MI))
continue;
LiveInterval &SnipLI = LIS.getInterval(MI->getOperand(1).getReg());
- assert(isRegToSpill(SnipLI.reg()) && "Unexpected register in copy");
+ assert(isRegToSpill(SnipLI.reg()) && "Unexpected register in copy");
VNInfo *SnipVNI = SnipLI.getVNInfoAt(VNI->def.getRegSlot(true));
assert(SnipVNI && "Snippet undefined before copy");
WorkList.push_back(std::make_pair(&SnipLI, SnipVNI));
@@ -572,7 +572,7 @@ bool InlineSpiller::canGuaranteeAssignmentAfterRemat(Register VReg,
bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg, MachineInstr &MI) {
// Analyze instruction
SmallVector<std::pair<MachineInstr *, unsigned>, 8> Ops;
- VirtRegInfo RI = AnalyzeVirtRegInBundle(MI, VirtReg.reg(), &Ops);
+ VirtRegInfo RI = AnalyzeVirtRegInBundle(MI, VirtReg.reg(), &Ops);
if (!RI.Reads)
return false;
@@ -584,7 +584,7 @@ bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg, MachineInstr &MI) {
LLVM_DEBUG(dbgs() << "\tadding <undef> flags: ");
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI.getOperand(i);
- if (MO.isReg() && MO.isUse() && MO.getReg() == VirtReg.reg())
+ if (MO.isReg() && MO.isUse() && MO.getReg() == VirtReg.reg())
MO.setIsUndef();
}
LLVM_DEBUG(dbgs() << UseIdx << '\t' << MI);
@@ -624,7 +624,7 @@ bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg, MachineInstr &MI) {
// If we can't guarantee that we'll be able to actually assign the new vreg,
// we can't remat.
- if (!canGuaranteeAssignmentAfterRemat(VirtReg.reg(), MI)) {
+ if (!canGuaranteeAssignmentAfterRemat(VirtReg.reg(), MI)) {
markValueUsed(&VirtReg, ParentVNI);
LLVM_DEBUG(dbgs() << "\tcannot remat for " << UseIdx << '\t' << MI);
return false;
@@ -649,7 +649,7 @@ bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg, MachineInstr &MI) {
// Replace operands
for (const auto &OpPair : Ops) {
MachineOperand &MO = OpPair.first->getOperand(OpPair.second);
- if (MO.isReg() && MO.isUse() && MO.getReg() == VirtReg.reg()) {
+ if (MO.isReg() && MO.isUse() && MO.getReg() == VirtReg.reg()) {
MO.setReg(NewVReg);
MO.setIsKill();
}
@@ -826,14 +826,14 @@ foldMemoryOperand(ArrayRef<std::pair<MachineInstr *, unsigned>> Ops,
bool WasCopy = MI->isCopy();
Register ImpReg;
- // TII::foldMemoryOperand will do what we need here for statepoint
- // (fold load into use and remove corresponding def). We will replace
- // uses of removed def with loads (spillAroundUses).
- // For that to work we need to untie def and use to pass it through
- // foldMemoryOperand and signal foldPatchpoint that it is allowed to
- // fold them.
- bool UntieRegs = MI->getOpcode() == TargetOpcode::STATEPOINT;
-
+ // TII::foldMemoryOperand will do what we need here for statepoint
+ // (fold load into use and remove corresponding def). We will replace
+ // uses of removed def with loads (spillAroundUses).
+ // For that to work we need to untie def and use to pass it through
+ // foldMemoryOperand and signal foldPatchpoint that it is allowed to
+ // fold them.
+ bool UntieRegs = MI->getOpcode() == TargetOpcode::STATEPOINT;
+
// Spill subregs if the target allows it.
// We always want to spill subregs for stackmap/patchpoint pseudos.
bool SpillSubRegs = TII.isSubregFoldable() ||
@@ -859,7 +859,7 @@ foldMemoryOperand(ArrayRef<std::pair<MachineInstr *, unsigned>> Ops,
if (LoadMI && MO.isDef())
return false;
// Tied use operands should not be passed to foldMemoryOperand.
- if (UntieRegs || !MI->isRegTiedToDefOperand(Idx))
+ if (UntieRegs || !MI->isRegTiedToDefOperand(Idx))
FoldOps.push_back(Idx);
}
@@ -870,31 +870,31 @@ foldMemoryOperand(ArrayRef<std::pair<MachineInstr *, unsigned>> Ops,
MachineInstrSpan MIS(MI, MI->getParent());
- SmallVector<std::pair<unsigned, unsigned> > TiedOps;
- if (UntieRegs)
- for (unsigned Idx : FoldOps) {
- MachineOperand &MO = MI->getOperand(Idx);
- if (!MO.isTied())
- continue;
- unsigned Tied = MI->findTiedOperandIdx(Idx);
- if (MO.isUse())
- TiedOps.emplace_back(Tied, Idx);
- else {
- assert(MO.isDef() && "Tied to not use and def?");
- TiedOps.emplace_back(Idx, Tied);
- }
- MI->untieRegOperand(Idx);
- }
-
+ SmallVector<std::pair<unsigned, unsigned> > TiedOps;
+ if (UntieRegs)
+ for (unsigned Idx : FoldOps) {
+ MachineOperand &MO = MI->getOperand(Idx);
+ if (!MO.isTied())
+ continue;
+ unsigned Tied = MI->findTiedOperandIdx(Idx);
+ if (MO.isUse())
+ TiedOps.emplace_back(Tied, Idx);
+ else {
+ assert(MO.isDef() && "Tied to not use and def?");
+ TiedOps.emplace_back(Idx, Tied);
+ }
+ MI->untieRegOperand(Idx);
+ }
+
MachineInstr *FoldMI =
LoadMI ? TII.foldMemoryOperand(*MI, FoldOps, *LoadMI, &LIS)
: TII.foldMemoryOperand(*MI, FoldOps, StackSlot, &LIS, &VRM);
- if (!FoldMI) {
- // Re-tie operands.
- for (auto Tied : TiedOps)
- MI->tieOperands(Tied.first, Tied.second);
+ if (!FoldMI) {
+ // Re-tie operands.
+ for (auto Tied : TiedOps)
+ MI->tieOperands(Tied.first, Tied.second);
return false;
- }
+ }
// Remove LIS for any dead defs in the original MI not in FoldMI.
for (MIBundleOperands MO(*MI); MO.isValid(); ++MO) {
@@ -913,7 +913,7 @@ foldMemoryOperand(ArrayRef<std::pair<MachineInstr *, unsigned>> Ops,
// FoldMI does not define this physreg. Remove the LI segment.
assert(MO->isDead() && "Cannot fold physreg def");
SlotIndex Idx = LIS.getInstructionIndex(*MI).getRegSlot();
- LIS.removePhysRegDefAt(Reg.asMCReg(), Idx);
+ LIS.removePhysRegDefAt(Reg.asMCReg(), Idx);
}
int FI;
@@ -950,11 +950,11 @@ foldMemoryOperand(ArrayRef<std::pair<MachineInstr *, unsigned>> Ops,
++NumFolded;
else if (Ops.front().second == 0) {
++NumSpills;
- // If there is only 1 store instruction is required for spill, add it
- // to mergeable list. In X86 AMX, 2 intructions are required to store.
- // We disable the merge for this case.
- if (std::distance(MIS.begin(), MIS.end()) <= 1)
- HSpiller.addToMergeableSpills(*FoldMI, StackSlot, Original);
+ // If there is only 1 store instruction is required for spill, add it
+ // to mergeable list. In X86 AMX, 2 intructions are required to store.
+ // We disable the merge for this case.
+ if (std::distance(MIS.begin(), MIS.end()) <= 1)
+ HSpiller.addToMergeableSpills(*FoldMI, StackSlot, Original);
} else
++NumReloads;
return true;
@@ -1001,7 +1001,7 @@ void InlineSpiller::insertSpill(Register NewVReg, bool isKill,
MachineInstrSpan MIS(MI, &MBB);
MachineBasicBlock::iterator SpillBefore = std::next(MI);
bool IsRealSpill = isRealSpill(*MI);
-
+
if (IsRealSpill)
TII.storeRegToStackSlot(MBB, SpillBefore, NewVReg, isKill, StackSlot,
MRI.getRegClass(NewVReg), &TRI);
@@ -1015,16 +1015,16 @@ void InlineSpiller::insertSpill(Register NewVReg, bool isKill,
MachineBasicBlock::iterator Spill = std::next(MI);
LIS.InsertMachineInstrRangeInMaps(Spill, MIS.end());
- for (const MachineInstr &MI : make_range(Spill, MIS.end()))
- getVDefInterval(MI, LIS);
+ for (const MachineInstr &MI : make_range(Spill, MIS.end()))
+ getVDefInterval(MI, LIS);
LLVM_DEBUG(
dumpMachineInstrRangeWithSlotIndex(Spill, MIS.end(), LIS, "spill"));
++NumSpills;
- // If there is only 1 store instruction is required for spill, add it
- // to mergeable list. In X86 AMX, 2 intructions are required to store.
- // We disable the merge for this case.
- if (IsRealSpill && std::distance(Spill, MIS.end()) <= 1)
+ // If there is only 1 store instruction is required for spill, add it
+ // to mergeable list. In X86 AMX, 2 intructions are required to store.
+ // We disable the merge for this case.
+ if (IsRealSpill && std::distance(Spill, MIS.end()) <= 1)
HSpiller.addToMergeableSpills(*Spill, StackSlot, Original);
}
@@ -1214,7 +1214,7 @@ void HoistSpillHelper::addToMergeableSpills(MachineInstr &Spill, int StackSlot,
// save a copy of LiveInterval in StackSlotToOrigLI because the original
// LiveInterval may be cleared after all its references are spilled.
if (StackSlotToOrigLI.find(StackSlot) == StackSlotToOrigLI.end()) {
- auto LI = std::make_unique<LiveInterval>(OrigLI.reg(), OrigLI.weight());
+ auto LI = std::make_unique<LiveInterval>(OrigLI.reg(), OrigLI.weight());
LI->assign(OrigLI, Allocator);
StackSlotToOrigLI[StackSlot] = std::move(LI);
}
@@ -1242,7 +1242,7 @@ bool HoistSpillHelper::rmFromMergeableSpills(MachineInstr &Spill,
bool HoistSpillHelper::isSpillCandBB(LiveInterval &OrigLI, VNInfo &OrigVNI,
MachineBasicBlock &BB, Register &LiveReg) {
SlotIndex Idx;
- Register OrigReg = OrigLI.reg();
+ Register OrigReg = OrigLI.reg();
MachineBasicBlock::iterator MI = IPA.getLastInsertPointIter(OrigLI, BB);
if (MI != BB.end())
Idx = LIS.getInstructionIndex(*MI);
@@ -1570,13 +1570,13 @@ void HoistSpillHelper::hoistAllSpills() {
for (auto const &Insert : SpillsToIns) {
MachineBasicBlock *BB = Insert.first;
Register LiveReg = Insert.second;
- MachineBasicBlock::iterator MII = IPA.getLastInsertPointIter(OrigLI, *BB);
- MachineInstrSpan MIS(MII, BB);
- TII.storeRegToStackSlot(*BB, MII, LiveReg, false, Slot,
+ MachineBasicBlock::iterator MII = IPA.getLastInsertPointIter(OrigLI, *BB);
+ MachineInstrSpan MIS(MII, BB);
+ TII.storeRegToStackSlot(*BB, MII, LiveReg, false, Slot,
MRI.getRegClass(LiveReg), &TRI);
- LIS.InsertMachineInstrRangeInMaps(MIS.begin(), MII);
- for (const MachineInstr &MI : make_range(MIS.begin(), MII))
- getVDefInterval(MI, LIS);
+ LIS.InsertMachineInstrRangeInMaps(MIS.begin(), MII);
+ for (const MachineInstr &MI : make_range(MIS.begin(), MII))
+ getVDefInterval(MI, LIS);
++NumSpills;
}
@@ -1596,13 +1596,13 @@ void HoistSpillHelper::hoistAllSpills() {
/// For VirtReg clone, the \p New register should have the same physreg or
/// stackslot as the \p old register.
-void HoistSpillHelper::LRE_DidCloneVirtReg(Register New, Register Old) {
+void HoistSpillHelper::LRE_DidCloneVirtReg(Register New, Register Old) {
if (VRM.hasPhys(Old))
VRM.assignVirt2Phys(New, VRM.getPhys(Old));
else if (VRM.getStackSlot(Old) != VirtRegMap::NO_STACK_SLOT)
VRM.assignVirt2StackSlot(New, VRM.getStackSlot(Old));
else
llvm_unreachable("VReg should be assigned either physreg or stackslot");
- if (VRM.hasShape(Old))
- VRM.assignVirt2Shape(New, VRM.getShape(Old));
+ if (VRM.hasShape(Old))
+ VRM.assignVirt2Shape(New, VRM.getShape(Old));
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/InterferenceCache.cpp b/contrib/libs/llvm12/lib/CodeGen/InterferenceCache.cpp
index 9421cd48be..a56485cdbc 100644
--- a/contrib/libs/llvm12/lib/CodeGen/InterferenceCache.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/InterferenceCache.cpp
@@ -60,8 +60,8 @@ void InterferenceCache::init(MachineFunction *mf,
Entries[i].clear(mf, indexes, lis);
}
-InterferenceCache::Entry *InterferenceCache::get(MCRegister PhysReg) {
- unsigned char E = PhysRegEntries[PhysReg.id()];
+InterferenceCache::Entry *InterferenceCache::get(MCRegister PhysReg) {
+ unsigned char E = PhysRegEntries[PhysReg.id()];
if (E < CacheEntries && Entries[E].getPhysReg() == PhysReg) {
if (!Entries[E].valid(LIUArray, TRI))
Entries[E].revalidate(LIUArray, TRI);
@@ -97,7 +97,7 @@ void InterferenceCache::Entry::revalidate(LiveIntervalUnion *LIUArray,
RegUnits[i].VirtTag = LIUArray[*Units].getTag();
}
-void InterferenceCache::Entry::reset(MCRegister physReg,
+void InterferenceCache::Entry::reset(MCRegister physReg,
LiveIntervalUnion *LIUArray,
const TargetRegisterInfo *TRI,
const MachineFunction *MF) {
diff --git a/contrib/libs/llvm12/lib/CodeGen/InterferenceCache.h b/contrib/libs/llvm12/lib/CodeGen/InterferenceCache.h
index 7ede9c9d8f..ace1691c13 100644
--- a/contrib/libs/llvm12/lib/CodeGen/InterferenceCache.h
+++ b/contrib/libs/llvm12/lib/CodeGen/InterferenceCache.h
@@ -44,7 +44,7 @@ class LLVM_LIBRARY_VISIBILITY InterferenceCache {
/// of PhysReg in all basic blocks.
class Entry {
/// PhysReg - The register currently represented.
- MCRegister PhysReg = 0;
+ MCRegister PhysReg = 0;
/// Tag - Cache tag is changed when any of the underlying LiveIntervalUnions
/// change.
@@ -102,13 +102,13 @@ class LLVM_LIBRARY_VISIBILITY InterferenceCache {
void clear(MachineFunction *mf, SlotIndexes *indexes, LiveIntervals *lis) {
assert(!hasRefs() && "Cannot clear cache entry with references");
- PhysReg = MCRegister::NoRegister;
+ PhysReg = MCRegister::NoRegister;
MF = mf;
Indexes = indexes;
LIS = lis;
}
- MCRegister getPhysReg() const { return PhysReg; }
+ MCRegister getPhysReg() const { return PhysReg; }
void addRef(int Delta) { RefCount += Delta; }
@@ -120,8 +120,8 @@ class LLVM_LIBRARY_VISIBILITY InterferenceCache {
bool valid(LiveIntervalUnion *LIUArray, const TargetRegisterInfo *TRI);
/// reset - Initialize entry to represent physReg's aliases.
- void reset(MCRegister physReg, LiveIntervalUnion *LIUArray,
- const TargetRegisterInfo *TRI, const MachineFunction *MF);
+ void reset(MCRegister physReg, LiveIntervalUnion *LIUArray,
+ const TargetRegisterInfo *TRI, const MachineFunction *MF);
/// get - Return an up to date BlockInterference.
BlockInterference *get(unsigned MBBNum) {
@@ -152,7 +152,7 @@ class LLVM_LIBRARY_VISIBILITY InterferenceCache {
Entry Entries[CacheEntries];
// get - Get a valid entry for PhysReg.
- Entry *get(MCRegister PhysReg);
+ Entry *get(MCRegister PhysReg);
public:
InterferenceCache() = default;
@@ -205,11 +205,11 @@ public:
~Cursor() { setEntry(nullptr); }
/// setPhysReg - Point this cursor to PhysReg's interference.
- void setPhysReg(InterferenceCache &Cache, MCRegister PhysReg) {
+ void setPhysReg(InterferenceCache &Cache, MCRegister PhysReg) {
// Release reference before getting a new one. That guarantees we can
// actually have CacheEntries live cursors.
setEntry(nullptr);
- if (PhysReg.isValid())
+ if (PhysReg.isValid())
setEntry(Cache.get(PhysReg));
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/InterleavedAccessPass.cpp b/contrib/libs/llvm12/lib/CodeGen/InterleavedAccessPass.cpp
index feb71e2221..b22e6faeb9 100644
--- a/contrib/libs/llvm12/lib/CodeGen/InterleavedAccessPass.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/InterleavedAccessPass.cpp
@@ -22,8 +22,8 @@
//
// E.g. An interleaved load (Factor = 2):
// %wide.vec = load <8 x i32>, <8 x i32>* %ptr
-// %v0 = shuffle <8 x i32> %wide.vec, <8 x i32> poison, <0, 2, 4, 6>
-// %v1 = shuffle <8 x i32> %wide.vec, <8 x i32> poison, <1, 3, 5, 7>
+// %v0 = shuffle <8 x i32> %wide.vec, <8 x i32> poison, <0, 2, 4, 6>
+// %v1 = shuffle <8 x i32> %wide.vec, <8 x i32> poison, <1, 3, 5, 7>
//
// It could be transformed into a ld2 intrinsic in AArch64 backend or a vld2
// intrinsic in ARM backend.
@@ -66,7 +66,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/Local.h"
#include <cassert>
#include <utility>
@@ -119,15 +119,15 @@ private:
/// replacements are also performed.
bool tryReplaceExtracts(ArrayRef<ExtractElementInst *> Extracts,
ArrayRef<ShuffleVectorInst *> Shuffles);
-
- /// Given a number of shuffles of the form shuffle(binop(x,y)), convert them
- /// to binop(shuffle(x), shuffle(y)) to allow the formation of an
- /// interleaving load. Any newly created shuffles that operate on \p LI will
- /// be added to \p Shuffles. Returns true, if any changes to the IR have been
- /// made.
- bool replaceBinOpShuffles(ArrayRef<ShuffleVectorInst *> BinOpShuffles,
- SmallVectorImpl<ShuffleVectorInst *> &Shuffles,
- LoadInst *LI);
+
+ /// Given a number of shuffles of the form shuffle(binop(x,y)), convert them
+ /// to binop(shuffle(x), shuffle(y)) to allow the formation of an
+ /// interleaving load. Any newly created shuffles that operate on \p LI will
+ /// be added to \p Shuffles. Returns true, if any changes to the IR have been
+ /// made.
+ bool replaceBinOpShuffles(ArrayRef<ShuffleVectorInst *> BinOpShuffles,
+ SmallVectorImpl<ShuffleVectorInst *> &Shuffles,
+ LoadInst *LI);
};
} // end anonymous namespace.
@@ -293,97 +293,97 @@ bool InterleavedAccess::lowerInterleavedLoad(
if (!LI->isSimple() || isa<ScalableVectorType>(LI->getType()))
return false;
- // Check if all users of this load are shufflevectors. If we encounter any
- // users that are extractelement instructions or binary operators, we save
- // them to later check if they can be modified to extract from one of the
- // shufflevectors instead of the load.
-
+ // Check if all users of this load are shufflevectors. If we encounter any
+ // users that are extractelement instructions or binary operators, we save
+ // them to later check if they can be modified to extract from one of the
+ // shufflevectors instead of the load.
+
SmallVector<ShuffleVectorInst *, 4> Shuffles;
SmallVector<ExtractElementInst *, 4> Extracts;
- // BinOpShuffles need to be handled a single time in case both operands of the
- // binop are the same load.
- SmallSetVector<ShuffleVectorInst *, 4> BinOpShuffles;
+ // BinOpShuffles need to be handled a single time in case both operands of the
+ // binop are the same load.
+ SmallSetVector<ShuffleVectorInst *, 4> BinOpShuffles;
- for (auto *User : LI->users()) {
- auto *Extract = dyn_cast<ExtractElementInst>(User);
+ for (auto *User : LI->users()) {
+ auto *Extract = dyn_cast<ExtractElementInst>(User);
if (Extract && isa<ConstantInt>(Extract->getIndexOperand())) {
Extracts.push_back(Extract);
continue;
}
- auto *BI = dyn_cast<BinaryOperator>(User);
- if (BI && BI->hasOneUse()) {
- if (auto *SVI = dyn_cast<ShuffleVectorInst>(*BI->user_begin())) {
- BinOpShuffles.insert(SVI);
- continue;
- }
- }
- auto *SVI = dyn_cast<ShuffleVectorInst>(User);
+ auto *BI = dyn_cast<BinaryOperator>(User);
+ if (BI && BI->hasOneUse()) {
+ if (auto *SVI = dyn_cast<ShuffleVectorInst>(*BI->user_begin())) {
+ BinOpShuffles.insert(SVI);
+ continue;
+ }
+ }
+ auto *SVI = dyn_cast<ShuffleVectorInst>(User);
if (!SVI || !isa<UndefValue>(SVI->getOperand(1)))
return false;
Shuffles.push_back(SVI);
}
- if (Shuffles.empty() && BinOpShuffles.empty())
+ if (Shuffles.empty() && BinOpShuffles.empty())
return false;
unsigned Factor, Index;
unsigned NumLoadElements =
cast<FixedVectorType>(LI->getType())->getNumElements();
- auto *FirstSVI = Shuffles.size() > 0 ? Shuffles[0] : BinOpShuffles[0];
+ auto *FirstSVI = Shuffles.size() > 0 ? Shuffles[0] : BinOpShuffles[0];
// Check if the first shufflevector is DE-interleave shuffle.
- if (!isDeInterleaveMask(FirstSVI->getShuffleMask(), Factor, Index, MaxFactor,
- NumLoadElements))
+ if (!isDeInterleaveMask(FirstSVI->getShuffleMask(), Factor, Index, MaxFactor,
+ NumLoadElements))
return false;
// Holds the corresponding index for each DE-interleave shuffle.
SmallVector<unsigned, 4> Indices;
- Type *VecTy = FirstSVI->getType();
+ Type *VecTy = FirstSVI->getType();
// Check if other shufflevectors are also DE-interleaved of the same type
// and factor as the first shufflevector.
- for (auto *Shuffle : Shuffles) {
- if (Shuffle->getType() != VecTy)
+ for (auto *Shuffle : Shuffles) {
+ if (Shuffle->getType() != VecTy)
return false;
- if (!isDeInterleaveMaskOfFactor(Shuffle->getShuffleMask(), Factor,
+ if (!isDeInterleaveMaskOfFactor(Shuffle->getShuffleMask(), Factor,
Index))
return false;
- assert(Shuffle->getShuffleMask().size() <= NumLoadElements);
+ assert(Shuffle->getShuffleMask().size() <= NumLoadElements);
Indices.push_back(Index);
}
- for (auto *Shuffle : BinOpShuffles) {
- if (Shuffle->getType() != VecTy)
- return false;
- if (!isDeInterleaveMaskOfFactor(Shuffle->getShuffleMask(), Factor,
- Index))
- return false;
-
- assert(Shuffle->getShuffleMask().size() <= NumLoadElements);
-
- if (cast<Instruction>(Shuffle->getOperand(0))->getOperand(0) == LI)
- Indices.push_back(Index);
- if (cast<Instruction>(Shuffle->getOperand(0))->getOperand(1) == LI)
- Indices.push_back(Index);
- }
-
+ for (auto *Shuffle : BinOpShuffles) {
+ if (Shuffle->getType() != VecTy)
+ return false;
+ if (!isDeInterleaveMaskOfFactor(Shuffle->getShuffleMask(), Factor,
+ Index))
+ return false;
+
+ assert(Shuffle->getShuffleMask().size() <= NumLoadElements);
+
+ if (cast<Instruction>(Shuffle->getOperand(0))->getOperand(0) == LI)
+ Indices.push_back(Index);
+ if (cast<Instruction>(Shuffle->getOperand(0))->getOperand(1) == LI)
+ Indices.push_back(Index);
+ }
+
// Try and modify users of the load that are extractelement instructions to
// use the shufflevector instructions instead of the load.
if (!tryReplaceExtracts(Extracts, Shuffles))
return false;
- bool BinOpShuffleChanged =
- replaceBinOpShuffles(BinOpShuffles.getArrayRef(), Shuffles, LI);
-
+ bool BinOpShuffleChanged =
+ replaceBinOpShuffles(BinOpShuffles.getArrayRef(), Shuffles, LI);
+
LLVM_DEBUG(dbgs() << "IA: Found an interleaved load: " << *LI << "\n");
// Try to create target specific intrinsics to replace the load and shuffles.
- if (!TLI->lowerInterleavedLoad(LI, Shuffles, Indices, Factor)) {
- // If Extracts is not empty, tryReplaceExtracts made changes earlier.
- return !Extracts.empty() || BinOpShuffleChanged;
- }
+ if (!TLI->lowerInterleavedLoad(LI, Shuffles, Indices, Factor)) {
+ // If Extracts is not empty, tryReplaceExtracts made changes earlier.
+ return !Extracts.empty() || BinOpShuffleChanged;
+ }
for (auto SVI : Shuffles)
DeadInsts.push_back(SVI);
@@ -392,39 +392,39 @@ bool InterleavedAccess::lowerInterleavedLoad(
return true;
}
-bool InterleavedAccess::replaceBinOpShuffles(
- ArrayRef<ShuffleVectorInst *> BinOpShuffles,
- SmallVectorImpl<ShuffleVectorInst *> &Shuffles, LoadInst *LI) {
- for (auto *SVI : BinOpShuffles) {
- BinaryOperator *BI = cast<BinaryOperator>(SVI->getOperand(0));
- Type *BIOp0Ty = BI->getOperand(0)->getType();
- ArrayRef<int> Mask = SVI->getShuffleMask();
- assert(all_of(Mask, [&](int Idx) {
- return Idx < (int)cast<FixedVectorType>(BIOp0Ty)->getNumElements();
- }));
-
- auto *NewSVI1 =
- new ShuffleVectorInst(BI->getOperand(0), PoisonValue::get(BIOp0Ty),
- Mask, SVI->getName(), SVI);
- auto *NewSVI2 = new ShuffleVectorInst(
- BI->getOperand(1), PoisonValue::get(BI->getOperand(1)->getType()), Mask,
- SVI->getName(), SVI);
- Value *NewBI = BinaryOperator::Create(BI->getOpcode(), NewSVI1, NewSVI2,
- BI->getName(), SVI);
- SVI->replaceAllUsesWith(NewBI);
- LLVM_DEBUG(dbgs() << " Replaced: " << *BI << "\n And : " << *SVI
- << "\n With : " << *NewSVI1 << "\n And : "
- << *NewSVI2 << "\n And : " << *NewBI << "\n");
- RecursivelyDeleteTriviallyDeadInstructions(SVI);
- if (NewSVI1->getOperand(0) == LI)
- Shuffles.push_back(NewSVI1);
- if (NewSVI2->getOperand(0) == LI)
- Shuffles.push_back(NewSVI2);
- }
-
- return !BinOpShuffles.empty();
-}
-
+bool InterleavedAccess::replaceBinOpShuffles(
+ ArrayRef<ShuffleVectorInst *> BinOpShuffles,
+ SmallVectorImpl<ShuffleVectorInst *> &Shuffles, LoadInst *LI) {
+ for (auto *SVI : BinOpShuffles) {
+ BinaryOperator *BI = cast<BinaryOperator>(SVI->getOperand(0));
+ Type *BIOp0Ty = BI->getOperand(0)->getType();
+ ArrayRef<int> Mask = SVI->getShuffleMask();
+ assert(all_of(Mask, [&](int Idx) {
+ return Idx < (int)cast<FixedVectorType>(BIOp0Ty)->getNumElements();
+ }));
+
+ auto *NewSVI1 =
+ new ShuffleVectorInst(BI->getOperand(0), PoisonValue::get(BIOp0Ty),
+ Mask, SVI->getName(), SVI);
+ auto *NewSVI2 = new ShuffleVectorInst(
+ BI->getOperand(1), PoisonValue::get(BI->getOperand(1)->getType()), Mask,
+ SVI->getName(), SVI);
+ Value *NewBI = BinaryOperator::Create(BI->getOpcode(), NewSVI1, NewSVI2,
+ BI->getName(), SVI);
+ SVI->replaceAllUsesWith(NewBI);
+ LLVM_DEBUG(dbgs() << " Replaced: " << *BI << "\n And : " << *SVI
+ << "\n With : " << *NewSVI1 << "\n And : "
+ << *NewSVI2 << "\n And : " << *NewBI << "\n");
+ RecursivelyDeleteTriviallyDeadInstructions(SVI);
+ if (NewSVI1->getOperand(0) == LI)
+ Shuffles.push_back(NewSVI1);
+ if (NewSVI2->getOperand(0) == LI)
+ Shuffles.push_back(NewSVI2);
+ }
+
+ return !BinOpShuffles.empty();
+}
+
bool InterleavedAccess::tryReplaceExtracts(
ArrayRef<ExtractElementInst *> Extracts,
ArrayRef<ShuffleVectorInst *> Shuffles) {
@@ -494,7 +494,7 @@ bool InterleavedAccess::lowerInterleavedStore(
if (!SI->isSimple())
return false;
- auto *SVI = dyn_cast<ShuffleVectorInst>(SI->getValueOperand());
+ auto *SVI = dyn_cast<ShuffleVectorInst>(SI->getValueOperand());
if (!SVI || !SVI->hasOneUse() || isa<ScalableVectorType>(SVI->getType()))
return false;
@@ -534,10 +534,10 @@ bool InterleavedAccess::runOnFunction(Function &F) {
bool Changed = false;
for (auto &I : instructions(F)) {
- if (auto *LI = dyn_cast<LoadInst>(&I))
+ if (auto *LI = dyn_cast<LoadInst>(&I))
Changed |= lowerInterleavedLoad(LI, DeadInsts);
- if (auto *SI = dyn_cast<StoreInst>(&I))
+ if (auto *SI = dyn_cast<StoreInst>(&I))
Changed |= lowerInterleavedStore(SI, DeadInsts);
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/InterleavedLoadCombinePass.cpp b/contrib/libs/llvm12/lib/CodeGen/InterleavedLoadCombinePass.cpp
index c282052162..ff3f93d51e 100644
--- a/contrib/libs/llvm12/lib/CodeGen/InterleavedLoadCombinePass.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/InterleavedLoadCombinePass.cpp
@@ -1104,8 +1104,8 @@ InterleavedLoadCombineImpl::findFirstLoad(const std::set<LoadInst *> &LIs) {
// All LIs are within the same BB. Select the first for a reference.
BasicBlock *BB = (*LIs.begin())->getParent();
- BasicBlock::iterator FLI = llvm::find_if(
- *BB, [&LIs](Instruction &I) -> bool { return is_contained(LIs, &I); });
+ BasicBlock::iterator FLI = llvm::find_if(
+ *BB, [&LIs](Instruction &I) -> bool { return is_contained(LIs, &I); });
assert(FLI != BB->end());
return cast<LoadInst>(FLI);
@@ -1128,8 +1128,8 @@ bool InterleavedLoadCombineImpl::combine(std::list<VectorInfo> &InterleavedLoad,
std::set<Instruction *> Is;
std::set<Instruction *> SVIs;
- InstructionCost InterleavedCost;
- InstructionCost InstructionCost = 0;
+ InstructionCost InterleavedCost;
+ InstructionCost InstructionCost = 0;
// Get the interleave factor
unsigned Factor = InterleavedLoad.size();
@@ -1172,10 +1172,10 @@ bool InterleavedLoadCombineImpl::combine(std::list<VectorInfo> &InterleavedLoad,
}
}
- // We need to have a valid cost in order to proceed.
- if (!InstructionCost.isValid())
- return false;
-
+ // We need to have a valid cost in order to proceed.
+ if (!InstructionCost.isValid())
+ return false;
+
// We know that all LoadInst are within the same BB. This guarantees that
// either everything or nothing is loaded.
LoadInst *First = findFirstLoad(LIs);
@@ -1238,7 +1238,7 @@ bool InterleavedLoadCombineImpl::combine(std::list<VectorInfo> &InterleavedLoad,
Mask.push_back(i + j * Factor);
Builder.SetInsertPoint(VI.SVI);
- auto SVI = Builder.CreateShuffleVector(LI, Mask, "interleaved.shuffle");
+ auto SVI = Builder.CreateShuffleVector(LI, Mask, "interleaved.shuffle");
VI.SVI->replaceAllUsesWith(SVI);
i++;
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/IntrinsicLowering.cpp b/contrib/libs/llvm12/lib/CodeGen/IntrinsicLowering.cpp
index 3ca4b42dfd..55089d3b90 100644
--- a/contrib/libs/llvm12/lib/CodeGen/IntrinsicLowering.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/IntrinsicLowering.cpp
@@ -329,7 +329,7 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
break;
case Intrinsic::assume:
- case Intrinsic::experimental_noalias_scope_decl:
+ case Intrinsic::experimental_noalias_scope_decl:
case Intrinsic::var_annotation:
break; // Strip out these intrinsics
diff --git a/contrib/libs/llvm12/lib/CodeGen/LLVMTargetMachine.cpp b/contrib/libs/llvm12/lib/CodeGen/LLVMTargetMachine.cpp
index 0651260346..f9b7bf613f 100644
--- a/contrib/libs/llvm12/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/LLVMTargetMachine.cpp
@@ -40,16 +40,16 @@ static cl::opt<bool> EnableTrapUnreachable("trap-unreachable",
void LLVMTargetMachine::initAsmInfo() {
MRI.reset(TheTarget.createMCRegInfo(getTargetTriple().str()));
- assert(MRI && "Unable to create reg info");
+ assert(MRI && "Unable to create reg info");
MII.reset(TheTarget.createMCInstrInfo());
- assert(MII && "Unable to create instruction info");
+ assert(MII && "Unable to create instruction info");
// FIXME: Having an MCSubtargetInfo on the target machine is a hack due
// to some backends having subtarget feature dependent module level
// code generation. This is similar to the hack in the AsmPrinter for
// module level assembly etc.
STI.reset(TheTarget.createMCSubtargetInfo(
getTargetTriple().str(), getTargetCPU(), getTargetFeatureString()));
- assert(STI && "Unable to create subtarget info");
+ assert(STI && "Unable to create subtarget info");
MCAsmInfo *TmpAsmInfo = TheTarget.createMCAsmInfo(
*MRI, getTargetTriple().str(), Options.MCOptions);
@@ -61,9 +61,9 @@ void LLVMTargetMachine::initAsmInfo() {
"Make sure you include the correct TargetSelect.h"
"and that InitializeAllTargetMCs() is being invoked!");
- if (Options.BinutilsVersion.first > 0)
- TmpAsmInfo->setBinutilsVersion(Options.BinutilsVersion);
-
+ if (Options.BinutilsVersion.first > 0)
+ TmpAsmInfo->setBinutilsVersion(Options.BinutilsVersion);
+
if (Options.DisableIntegratedAS)
TmpAsmInfo->setUseIntegratedAssembler(false);
@@ -124,24 +124,24 @@ bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,
raw_pwrite_stream *DwoOut,
CodeGenFileType FileType,
MCContext &Context) {
- Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr =
- createMCStreamer(Out, DwoOut, FileType, Context);
- if (auto Err = MCStreamerOrErr.takeError())
- return true;
-
- // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
- FunctionPass *Printer =
- getTarget().createAsmPrinter(*this, std::move(*MCStreamerOrErr));
- if (!Printer)
- return true;
-
- PM.add(Printer);
- return false;
-}
-
-Expected<std::unique_ptr<MCStreamer>> LLVMTargetMachine::createMCStreamer(
- raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
- MCContext &Context) {
+ Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr =
+ createMCStreamer(Out, DwoOut, FileType, Context);
+ if (auto Err = MCStreamerOrErr.takeError())
+ return true;
+
+ // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
+ FunctionPass *Printer =
+ getTarget().createAsmPrinter(*this, std::move(*MCStreamerOrErr));
+ if (!Printer)
+ return true;
+
+ PM.add(Printer);
+ return false;
+}
+
+Expected<std::unique_ptr<MCStreamer>> LLVMTargetMachine::createMCStreamer(
+ raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
+ MCContext &Context) {
if (Options.MCOptions.MCSaveTempLabels)
Context.setAllowTemporaryLabels(false);
@@ -176,14 +176,14 @@ Expected<std::unique_ptr<MCStreamer>> LLVMTargetMachine::createMCStreamer(
// Create the code emitter for the target if it exists. If not, .o file
// emission fails.
MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, Context);
- if (!MCE)
- return make_error<StringError>("createMCCodeEmitter failed",
- inconvertibleErrorCode());
+ if (!MCE)
+ return make_error<StringError>("createMCCodeEmitter failed",
+ inconvertibleErrorCode());
MCAsmBackend *MAB =
getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);
- if (!MAB)
- return make_error<StringError>("createMCAsmBackend failed",
- inconvertibleErrorCode());
+ if (!MAB)
+ return make_error<StringError>("createMCAsmBackend failed",
+ inconvertibleErrorCode());
Triple T(getTargetTriple().str());
AsmStreamer.reset(getTarget().createMCObjectStreamer(
@@ -202,7 +202,7 @@ Expected<std::unique_ptr<MCStreamer>> LLVMTargetMachine::createMCStreamer(
break;
}
- return std::move(AsmStreamer);
+ return std::move(AsmStreamer);
}
bool LLVMTargetMachine::addPassesToEmitFile(
@@ -217,14 +217,14 @@ bool LLVMTargetMachine::addPassesToEmitFile(
if (!PassConfig)
return true;
- if (TargetPassConfig::willCompleteCodeGenPipeline()) {
- if (addAsmPrinter(PM, Out, DwoOut, FileType, MMIWP->getMMI().getContext()))
- return true;
- } else {
- // MIR printing is redundant with -filetype=null.
- if (FileType != CGFT_Null)
- PM.add(createPrintMIRPass(Out));
- }
+ if (TargetPassConfig::willCompleteCodeGenPipeline()) {
+ if (addAsmPrinter(PM, Out, DwoOut, FileType, MMIWP->getMMI().getContext()))
+ return true;
+ } else {
+ // MIR printing is redundant with -filetype=null.
+ if (FileType != CGFT_Null)
+ PM.add(createPrintMIRPass(Out));
+ }
PM.add(createFreeMachineFunctionPass());
return false;
diff --git a/contrib/libs/llvm12/lib/CodeGen/LexicalScopes.cpp b/contrib/libs/llvm12/lib/CodeGen/LexicalScopes.cpp
index e859e2430e..8139c2cbb6 100644
--- a/contrib/libs/llvm12/lib/CodeGen/LexicalScopes.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/LexicalScopes.cpp
@@ -324,7 +324,7 @@ bool LexicalScopes::dominates(const DILocation *DL, MachineBasicBlock *MBB) {
Set = std::make_unique<BlockSetT>();
getMachineBasicBlocks(DL, *Set);
}
- return Set->contains(MBB);
+ return Set->contains(MBB);
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
diff --git a/contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
index f76eb9e740..18ffe8ba06 100644
--- a/contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
@@ -1,3363 +1,3363 @@
-//===- InstrRefBasedImpl.cpp - Tracking Debug Value MIs -------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-/// \file InstrRefBasedImpl.cpp
-///
-/// This is a separate implementation of LiveDebugValues, see
-/// LiveDebugValues.cpp and VarLocBasedImpl.cpp for more information.
-///
-/// This pass propagates variable locations between basic blocks, resolving
-/// control flow conflicts between them. The problem is much like SSA
-/// construction, where each DBG_VALUE instruction assigns the *value* that
-/// a variable has, and every instruction where the variable is in scope uses
-/// that variable. The resulting map of instruction-to-value is then translated
-/// into a register (or spill) location for each variable over each instruction.
-///
-/// This pass determines which DBG_VALUE dominates which instructions, or if
-/// none do, where values must be merged (like PHI nodes). The added
-/// complication is that because codegen has already finished, a PHI node may
-/// be needed for a variable location to be correct, but no register or spill
-/// slot merges the necessary values. In these circumstances, the variable
-/// location is dropped.
-///
-/// What makes this analysis non-trivial is loops: we cannot tell in advance
-/// whether a variable location is live throughout a loop, or whether its
-/// location is clobbered (or redefined by another DBG_VALUE), without
-/// exploring all the way through.
-///
-/// To make this simpler we perform two kinds of analysis. First, we identify
-/// every value defined by every instruction (ignoring those that only move
-/// another value), then compute a map of which values are available for each
-/// instruction. This is stronger than a reaching-def analysis, as we create
-/// PHI values where other values merge.
-///
-/// Secondly, for each variable, we effectively re-construct SSA using each
-/// DBG_VALUE as a def. The DBG_VALUEs read a value-number computed by the
-/// first analysis from the location they refer to. We can then compute the
-/// dominance frontiers of where a variable has a value, and create PHI nodes
-/// where they merge.
-/// This isn't precisely SSA-construction though, because the function shape
-/// is pre-defined. If a variable location requires a PHI node, but no
-/// PHI for the relevant values is present in the function (as computed by the
-/// first analysis), the location must be dropped.
-///
-/// Once both are complete, we can pass back over all instructions knowing:
-/// * What _value_ each variable should contain, either defined by an
-/// instruction or where control flow merges
-/// * What the location of that value is (if any).
-/// Allowing us to create appropriate live-in DBG_VALUEs, and DBG_VALUEs when
-/// a value moves location. After this pass runs, all variable locations within
-/// a block should be specified by DBG_VALUEs within that block, allowing
-/// DbgEntityHistoryCalculator to focus on individual blocks.
-///
-/// This pass is able to go fast because the size of the first
-/// reaching-definition analysis is proportional to the working-set size of
-/// the function, which the compiler tries to keep small. (It's also
-/// proportional to the number of blocks). Additionally, we repeatedly perform
-/// the second reaching-definition analysis with only the variables and blocks
-/// in a single lexical scope, exploiting their locality.
-///
-/// Determining where PHIs happen is trickier with this approach, and it comes
-/// to a head in the major problem for LiveDebugValues: is a value live-through
-/// a loop, or not? Your garden-variety dataflow analysis aims to build a set of
-/// facts about a function, however this analysis needs to generate new value
-/// numbers at joins.
-///
-/// To do this, consider a lattice of all definition values, from instructions
-/// and from PHIs. Each PHI is characterised by the RPO number of the block it
-/// occurs in. Each value pair A, B can be ordered by RPO(A) < RPO(B):
-/// with non-PHI values at the top, and any PHI value in the last block (by RPO
-/// order) at the bottom.
-///
-/// (Awkwardly: lower-down-the _lattice_ means a greater RPO _number_. Below,
-/// "rank" always refers to the former).
-///
-/// At any join, for each register, we consider:
-/// * All incoming values, and
-/// * The PREVIOUS live-in value at this join.
-/// If all incoming values agree: that's the live-in value. If they do not, the
-/// incoming values are ranked according to the partial order, and the NEXT
-/// LOWEST rank after the PREVIOUS live-in value is picked (multiple values of
-/// the same rank are ignored as conflicting). If there are no candidate values,
-/// or if the rank of the live-in would be lower than the rank of the current
-/// blocks PHIs, create a new PHI value.
-///
-/// Intuitively: if it's not immediately obvious what value a join should result
-/// in, we iteratively descend from instruction-definitions down through PHI
-/// values, getting closer to the current block each time. If the current block
-/// is a loop head, this ordering is effectively searching outer levels of
-/// loops, to find a value that's live-through the current loop.
-///
-/// If there is no value that's live-through this loop, a PHI is created for
-/// this location instead. We can't use a lower-ranked PHI because by definition
-/// it doesn't dominate the current block. We can't create a PHI value any
-/// earlier, because we risk creating a PHI value at a location where values do
-/// not in fact merge, thus misrepresenting the truth, and not making the true
-/// live-through value for variable locations.
-///
-/// This algorithm applies to both calculating the availability of values in
-/// the first analysis, and the location of variables in the second. However
-/// for the second we add an extra dimension of pain: creating a variable
-/// location PHI is only valid if, for each incoming edge,
-/// * There is a value for the variable on the incoming edge, and
-/// * All the edges have that value in the same register.
-/// Or put another way: we can only create a variable-location PHI if there is
-/// a matching machine-location PHI, each input to which is the variables value
-/// in the predecessor block.
-///
-/// To accommodate this difference, each point on the lattice is split in
-/// two: a "proposed" PHI and "definite" PHI. Any PHI that can immediately
-/// have a location determined are "definite" PHIs, and no further work is
-/// needed. Otherwise, a location that all non-backedge predecessors agree
-/// on is picked and propagated as a "proposed" PHI value. If that PHI value
-/// is truly live-through, it'll appear on the loop backedges on the next
-/// dataflow iteration, after which the block live-in moves to be a "definite"
-/// PHI. If it's not truly live-through, the variable value will be downgraded
-/// further as we explore the lattice, or remains "proposed" and is considered
-/// invalid once dataflow completes.
-///
-/// ### Terminology
-///
-/// A machine location is a register or spill slot, a value is something that's
-/// defined by an instruction or PHI node, while a variable value is the value
-/// assigned to a variable. A variable location is a machine location, that must
-/// contain the appropriate variable value. A value that is a PHI node is
-/// occasionally called an mphi.
-///
-/// The first dataflow problem is the "machine value location" problem,
-/// because we're determining which machine locations contain which values.
-/// The "locations" are constant: what's unknown is what value they contain.
-///
-/// The second dataflow problem (the one for variables) is the "variable value
-/// problem", because it's determining what values a variable has, rather than
-/// what location those values are placed in. Unfortunately, it's not that
-/// simple, because producing a PHI value always involves picking a location.
-/// This is an imperfection that we just have to accept, at least for now.
-///
-/// TODO:
-/// Overlapping fragments
-/// Entry values
-/// Add back DEBUG statements for debugging this
-/// Collect statistics
-///
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/PostOrderIterator.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/UniqueVector.h"
-#include "llvm/CodeGen/LexicalScopes.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineMemOperand.h"
-#include "llvm/CodeGen/MachineOperand.h"
-#include "llvm/CodeGen/PseudoSourceValue.h"
-#include "llvm/CodeGen/RegisterScavenging.h"
-#include "llvm/CodeGen/TargetFrameLowering.h"
-#include "llvm/CodeGen/TargetInstrInfo.h"
-#include "llvm/CodeGen/TargetLowering.h"
-#include "llvm/CodeGen/TargetPassConfig.h"
-#include "llvm/CodeGen/TargetRegisterInfo.h"
-#include "llvm/CodeGen/TargetSubtargetInfo.h"
-#include "llvm/Config/llvm-config.h"
-#include "llvm/IR/DIBuilder.h"
-#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/DebugLoc.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Module.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/TypeSize.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <functional>
-#include <queue>
-#include <tuple>
-#include <utility>
-#include <vector>
-#include <limits.h>
-#include <limits>
-
-#include "LiveDebugValues.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "livedebugvalues"
-
-STATISTIC(NumInserted, "Number of DBG_VALUE instructions inserted");
-STATISTIC(NumRemoved, "Number of DBG_VALUE instructions removed");
-
-// Act more like the VarLoc implementation, by propagating some locations too
-// far and ignoring some transfers.
-static cl::opt<bool> EmulateOldLDV("emulate-old-livedebugvalues", cl::Hidden,
- cl::desc("Act like old LiveDebugValues did"),
- cl::init(false));
-
-// Rely on isStoreToStackSlotPostFE and similar to observe all stack spills.
-static cl::opt<bool>
- ObserveAllStackops("observe-all-stack-ops", cl::Hidden,
- cl::desc("Allow non-kill spill and restores"),
- cl::init(false));
-
-namespace {
-
-// The location at which a spilled value resides. It consists of a register and
-// an offset.
-struct SpillLoc {
- unsigned SpillBase;
- StackOffset SpillOffset;
- bool operator==(const SpillLoc &Other) const {
- return std::make_pair(SpillBase, SpillOffset) ==
- std::make_pair(Other.SpillBase, Other.SpillOffset);
- }
- bool operator<(const SpillLoc &Other) const {
- return std::make_tuple(SpillBase, SpillOffset.getFixed(),
- SpillOffset.getScalable()) <
- std::make_tuple(Other.SpillBase, Other.SpillOffset.getFixed(),
- Other.SpillOffset.getScalable());
- }
-};
-
-class LocIdx {
- unsigned Location;
-
- // Default constructor is private, initializing to an illegal location number.
- // Use only for "not an entry" elements in IndexedMaps.
- LocIdx() : Location(UINT_MAX) { }
-
-public:
- #define NUM_LOC_BITS 24
- LocIdx(unsigned L) : Location(L) {
- assert(L < (1 << NUM_LOC_BITS) && "Machine locations must fit in 24 bits");
- }
-
- static LocIdx MakeIllegalLoc() {
- return LocIdx();
- }
-
- bool isIllegal() const {
- return Location == UINT_MAX;
- }
-
- uint64_t asU64() const {
- return Location;
- }
-
- bool operator==(unsigned L) const {
- return Location == L;
- }
-
- bool operator==(const LocIdx &L) const {
- return Location == L.Location;
- }
-
- bool operator!=(unsigned L) const {
- return !(*this == L);
- }
-
- bool operator!=(const LocIdx &L) const {
- return !(*this == L);
- }
-
- bool operator<(const LocIdx &Other) const {
- return Location < Other.Location;
- }
-};
-
-class LocIdxToIndexFunctor {
-public:
- using argument_type = LocIdx;
- unsigned operator()(const LocIdx &L) const {
- return L.asU64();
- }
-};
-
-/// Unique identifier for a value defined by an instruction, as a value type.
-/// Casts back and forth to a uint64_t. Probably replacable with something less
-/// bit-constrained. Each value identifies the instruction and machine location
-/// where the value is defined, although there may be no corresponding machine
-/// operand for it (ex: regmasks clobbering values). The instructions are
-/// one-based, and definitions that are PHIs have instruction number zero.
-///
-/// The obvious limits of a 1M block function or 1M instruction blocks are
-/// problematic; but by that point we should probably have bailed out of
-/// trying to analyse the function.
-class ValueIDNum {
- uint64_t BlockNo : 20; /// The block where the def happens.
- uint64_t InstNo : 20; /// The Instruction where the def happens.
- /// One based, is distance from start of block.
- uint64_t LocNo : NUM_LOC_BITS; /// The machine location where the def happens.
-
-public:
- // XXX -- temporarily enabled while the live-in / live-out tables are moved
- // to something more type-y
- ValueIDNum() : BlockNo(0xFFFFF),
- InstNo(0xFFFFF),
- LocNo(0xFFFFFF) { }
-
- ValueIDNum(uint64_t Block, uint64_t Inst, uint64_t Loc)
- : BlockNo(Block), InstNo(Inst), LocNo(Loc) { }
-
- ValueIDNum(uint64_t Block, uint64_t Inst, LocIdx Loc)
- : BlockNo(Block), InstNo(Inst), LocNo(Loc.asU64()) { }
-
- uint64_t getBlock() const { return BlockNo; }
- uint64_t getInst() const { return InstNo; }
- uint64_t getLoc() const { return LocNo; }
- bool isPHI() const { return InstNo == 0; }
-
- uint64_t asU64() const {
- uint64_t TmpBlock = BlockNo;
- uint64_t TmpInst = InstNo;
- return TmpBlock << 44ull | TmpInst << NUM_LOC_BITS | LocNo;
- }
-
- static ValueIDNum fromU64(uint64_t v) {
- uint64_t L = (v & 0x3FFF);
- return {v >> 44ull, ((v >> NUM_LOC_BITS) & 0xFFFFF), L};
- }
-
- bool operator<(const ValueIDNum &Other) const {
- return asU64() < Other.asU64();
- }
-
- bool operator==(const ValueIDNum &Other) const {
- return std::tie(BlockNo, InstNo, LocNo) ==
- std::tie(Other.BlockNo, Other.InstNo, Other.LocNo);
- }
-
- bool operator!=(const ValueIDNum &Other) const { return !(*this == Other); }
-
- std::string asString(const std::string &mlocname) const {
- return Twine("Value{bb: ")
- .concat(Twine(BlockNo).concat(
- Twine(", inst: ")
- .concat((InstNo ? Twine(InstNo) : Twine("live-in"))
- .concat(Twine(", loc: ").concat(Twine(mlocname)))
- .concat(Twine("}")))))
- .str();
- }
-
- static ValueIDNum EmptyValue;
-};
-
-} // end anonymous namespace
-
-namespace {
-
-/// Meta qualifiers for a value. Pair of whatever expression is used to qualify
-/// the the value, and Boolean of whether or not it's indirect.
-class DbgValueProperties {
-public:
- DbgValueProperties(const DIExpression *DIExpr, bool Indirect)
- : DIExpr(DIExpr), Indirect(Indirect) {}
-
- /// Extract properties from an existing DBG_VALUE instruction.
- DbgValueProperties(const MachineInstr &MI) {
- assert(MI.isDebugValue());
- DIExpr = MI.getDebugExpression();
- Indirect = MI.getOperand(1).isImm();
- }
-
- bool operator==(const DbgValueProperties &Other) const {
- return std::tie(DIExpr, Indirect) == std::tie(Other.DIExpr, Other.Indirect);
- }
-
- bool operator!=(const DbgValueProperties &Other) const {
- return !(*this == Other);
- }
-
- const DIExpression *DIExpr;
- bool Indirect;
-};
-
-/// Tracker for what values are in machine locations. Listens to the Things
-/// being Done by various instructions, and maintains a table of what machine
-/// locations have what values (as defined by a ValueIDNum).
-///
-/// There are potentially a much larger number of machine locations on the
-/// target machine than the actual working-set size of the function. On x86 for
-/// example, we're extremely unlikely to want to track values through control
-/// or debug registers. To avoid doing so, MLocTracker has several layers of
-/// indirection going on, with two kinds of ``location'':
-/// * A LocID uniquely identifies a register or spill location, with a
-/// predictable value.
-/// * A LocIdx is a key (in the database sense) for a LocID and a ValueIDNum.
-/// Whenever a location is def'd or used by a MachineInstr, we automagically
-/// create a new LocIdx for a location, but not otherwise. This ensures we only
-/// account for locations that are actually used or defined. The cost is another
-/// vector lookup (of LocID -> LocIdx) over any other implementation. This is
-/// fairly cheap, and the compiler tries to reduce the working-set at any one
-/// time in the function anyway.
-///
-/// Register mask operands completely blow this out of the water; I've just
-/// piled hacks on top of hacks to get around that.
-class MLocTracker {
-public:
- MachineFunction &MF;
- const TargetInstrInfo &TII;
- const TargetRegisterInfo &TRI;
- const TargetLowering &TLI;
-
- /// IndexedMap type, mapping from LocIdx to ValueIDNum.
- using LocToValueType = IndexedMap<ValueIDNum, LocIdxToIndexFunctor>;
-
- /// Map of LocIdxes to the ValueIDNums that they store. This is tightly
- /// packed, entries only exist for locations that are being tracked.
- LocToValueType LocIdxToIDNum;
-
- /// "Map" of machine location IDs (i.e., raw register or spill number) to the
- /// LocIdx key / number for that location. There are always at least as many
- /// as the number of registers on the target -- if the value in the register
- /// is not being tracked, then the LocIdx value will be zero. New entries are
- /// appended if a new spill slot begins being tracked.
- /// This, and the corresponding reverse map persist for the analysis of the
- /// whole function, and is necessarying for decoding various vectors of
- /// values.
- std::vector<LocIdx> LocIDToLocIdx;
-
- /// Inverse map of LocIDToLocIdx.
- IndexedMap<unsigned, LocIdxToIndexFunctor> LocIdxToLocID;
-
- /// Unique-ification of spill slots. Used to number them -- their LocID
- /// number is the index in SpillLocs minus one plus NumRegs.
- UniqueVector<SpillLoc> SpillLocs;
-
- // If we discover a new machine location, assign it an mphi with this
- // block number.
- unsigned CurBB;
-
- /// Cached local copy of the number of registers the target has.
- unsigned NumRegs;
-
- /// Collection of register mask operands that have been observed. Second part
- /// of pair indicates the instruction that they happened in. Used to
- /// reconstruct where defs happened if we start tracking a location later
- /// on.
- SmallVector<std::pair<const MachineOperand *, unsigned>, 32> Masks;
-
- /// Iterator for locations and the values they contain. Dereferencing
- /// produces a struct/pair containing the LocIdx key for this location,
- /// and a reference to the value currently stored. Simplifies the process
- /// of seeking a particular location.
- class MLocIterator {
- LocToValueType &ValueMap;
- LocIdx Idx;
-
- public:
- class value_type {
- public:
- value_type(LocIdx Idx, ValueIDNum &Value) : Idx(Idx), Value(Value) { }
- const LocIdx Idx; /// Read-only index of this location.
- ValueIDNum &Value; /// Reference to the stored value at this location.
- };
-
- MLocIterator(LocToValueType &ValueMap, LocIdx Idx)
- : ValueMap(ValueMap), Idx(Idx) { }
-
- bool operator==(const MLocIterator &Other) const {
- assert(&ValueMap == &Other.ValueMap);
- return Idx == Other.Idx;
- }
-
- bool operator!=(const MLocIterator &Other) const {
- return !(*this == Other);
- }
-
- void operator++() {
- Idx = LocIdx(Idx.asU64() + 1);
- }
-
- value_type operator*() {
- return value_type(Idx, ValueMap[LocIdx(Idx)]);
- }
- };
-
- MLocTracker(MachineFunction &MF, const TargetInstrInfo &TII,
- const TargetRegisterInfo &TRI, const TargetLowering &TLI)
- : MF(MF), TII(TII), TRI(TRI), TLI(TLI),
- LocIdxToIDNum(ValueIDNum::EmptyValue),
- LocIdxToLocID(0) {
- NumRegs = TRI.getNumRegs();
- reset();
- LocIDToLocIdx.resize(NumRegs, LocIdx::MakeIllegalLoc());
- assert(NumRegs < (1u << NUM_LOC_BITS)); // Detect bit packing failure
-
- // Always track SP. This avoids the implicit clobbering caused by regmasks
- // from affectings its values. (LiveDebugValues disbelieves calls and
- // regmasks that claim to clobber SP).
- Register SP = TLI.getStackPointerRegisterToSaveRestore();
- if (SP) {
- unsigned ID = getLocID(SP, false);
- (void)lookupOrTrackRegister(ID);
- }
- }
-
- /// Produce location ID number for indexing LocIDToLocIdx. Takes the register
- /// or spill number, and flag for whether it's a spill or not.
- unsigned getLocID(Register RegOrSpill, bool isSpill) {
- return (isSpill) ? RegOrSpill.id() + NumRegs - 1 : RegOrSpill.id();
- }
-
- /// Accessor for reading the value at Idx.
- ValueIDNum getNumAtPos(LocIdx Idx) const {
- assert(Idx.asU64() < LocIdxToIDNum.size());
- return LocIdxToIDNum[Idx];
- }
-
- unsigned getNumLocs(void) const { return LocIdxToIDNum.size(); }
-
- /// Reset all locations to contain a PHI value at the designated block. Used
- /// sometimes for actual PHI values, othertimes to indicate the block entry
- /// value (before any more information is known).
- void setMPhis(unsigned NewCurBB) {
- CurBB = NewCurBB;
- for (auto Location : locations())
- Location.Value = {CurBB, 0, Location.Idx};
- }
-
- /// Load values for each location from array of ValueIDNums. Take current
- /// bbnum just in case we read a value from a hitherto untouched register.
- void loadFromArray(ValueIDNum *Locs, unsigned NewCurBB) {
- CurBB = NewCurBB;
- // Iterate over all tracked locations, and load each locations live-in
- // value into our local index.
- for (auto Location : locations())
- Location.Value = Locs[Location.Idx.asU64()];
- }
-
- /// Wipe any un-necessary location records after traversing a block.
- void reset(void) {
- // We could reset all the location values too; however either loadFromArray
- // or setMPhis should be called before this object is re-used. Just
- // clear Masks, they're definitely not needed.
- Masks.clear();
- }
-
- /// Clear all data. Destroys the LocID <=> LocIdx map, which makes most of
- /// the information in this pass uninterpretable.
- void clear(void) {
- reset();
- LocIDToLocIdx.clear();
- LocIdxToLocID.clear();
- LocIdxToIDNum.clear();
- //SpillLocs.reset(); XXX UniqueVector::reset assumes a SpillLoc casts from 0
- SpillLocs = decltype(SpillLocs)();
-
- LocIDToLocIdx.resize(NumRegs, LocIdx::MakeIllegalLoc());
- }
-
- /// Set a locaiton to a certain value.
- void setMLoc(LocIdx L, ValueIDNum Num) {
- assert(L.asU64() < LocIdxToIDNum.size());
- LocIdxToIDNum[L] = Num;
- }
-
- /// Create a LocIdx for an untracked register ID. Initialize it to either an
- /// mphi value representing a live-in, or a recent register mask clobber.
- LocIdx trackRegister(unsigned ID) {
- assert(ID != 0);
- LocIdx NewIdx = LocIdx(LocIdxToIDNum.size());
- LocIdxToIDNum.grow(NewIdx);
- LocIdxToLocID.grow(NewIdx);
-
- // Default: it's an mphi.
- ValueIDNum ValNum = {CurBB, 0, NewIdx};
- // Was this reg ever touched by a regmask?
- for (const auto &MaskPair : reverse(Masks)) {
- if (MaskPair.first->clobbersPhysReg(ID)) {
- // There was an earlier def we skipped.
- ValNum = {CurBB, MaskPair.second, NewIdx};
- break;
- }
- }
-
- LocIdxToIDNum[NewIdx] = ValNum;
- LocIdxToLocID[NewIdx] = ID;
- return NewIdx;
- }
-
- LocIdx lookupOrTrackRegister(unsigned ID) {
- LocIdx &Index = LocIDToLocIdx[ID];
- if (Index.isIllegal())
- Index = trackRegister(ID);
- return Index;
- }
-
- /// Record a definition of the specified register at the given block / inst.
- /// This doesn't take a ValueIDNum, because the definition and its location
- /// are synonymous.
- void defReg(Register R, unsigned BB, unsigned Inst) {
- unsigned ID = getLocID(R, false);
- LocIdx Idx = lookupOrTrackRegister(ID);
- ValueIDNum ValueID = {BB, Inst, Idx};
- LocIdxToIDNum[Idx] = ValueID;
- }
-
- /// Set a register to a value number. To be used if the value number is
- /// known in advance.
- void setReg(Register R, ValueIDNum ValueID) {
- unsigned ID = getLocID(R, false);
- LocIdx Idx = lookupOrTrackRegister(ID);
- LocIdxToIDNum[Idx] = ValueID;
- }
-
- ValueIDNum readReg(Register R) {
- unsigned ID = getLocID(R, false);
- LocIdx Idx = lookupOrTrackRegister(ID);
- return LocIdxToIDNum[Idx];
- }
-
- /// Reset a register value to zero / empty. Needed to replicate the
- /// VarLoc implementation where a copy to/from a register effectively
- /// clears the contents of the source register. (Values can only have one
- /// machine location in VarLocBasedImpl).
- void wipeRegister(Register R) {
- unsigned ID = getLocID(R, false);
- LocIdx Idx = LocIDToLocIdx[ID];
- LocIdxToIDNum[Idx] = ValueIDNum::EmptyValue;
- }
-
- /// Determine the LocIdx of an existing register.
- LocIdx getRegMLoc(Register R) {
- unsigned ID = getLocID(R, false);
- return LocIDToLocIdx[ID];
- }
-
- /// Record a RegMask operand being executed. Defs any register we currently
- /// track, stores a pointer to the mask in case we have to account for it
- /// later.
- void writeRegMask(const MachineOperand *MO, unsigned CurBB, unsigned InstID) {
- // Ensure SP exists, so that we don't override it later.
- Register SP = TLI.getStackPointerRegisterToSaveRestore();
-
- // Def any register we track have that isn't preserved. The regmask
- // terminates the liveness of a register, meaning its value can't be
- // relied upon -- we represent this by giving it a new value.
- for (auto Location : locations()) {
- unsigned ID = LocIdxToLocID[Location.Idx];
- // Don't clobber SP, even if the mask says it's clobbered.
- if (ID < NumRegs && ID != SP && MO->clobbersPhysReg(ID))
- defReg(ID, CurBB, InstID);
- }
- Masks.push_back(std::make_pair(MO, InstID));
- }
-
- /// Find LocIdx for SpillLoc \p L, creating a new one if it's not tracked.
- LocIdx getOrTrackSpillLoc(SpillLoc L) {
- unsigned SpillID = SpillLocs.idFor(L);
- if (SpillID == 0) {
- SpillID = SpillLocs.insert(L);
- unsigned L = getLocID(SpillID, true);
- LocIdx Idx = LocIdx(LocIdxToIDNum.size()); // New idx
- LocIdxToIDNum.grow(Idx);
- LocIdxToLocID.grow(Idx);
- LocIDToLocIdx.push_back(Idx);
- LocIdxToLocID[Idx] = L;
- return Idx;
- } else {
- unsigned L = getLocID(SpillID, true);
- LocIdx Idx = LocIDToLocIdx[L];
- return Idx;
- }
- }
-
- /// Set the value stored in a spill slot.
- void setSpill(SpillLoc L, ValueIDNum ValueID) {
- LocIdx Idx = getOrTrackSpillLoc(L);
- LocIdxToIDNum[Idx] = ValueID;
- }
-
- /// Read whatever value is in a spill slot, or None if it isn't tracked.
- Optional<ValueIDNum> readSpill(SpillLoc L) {
- unsigned SpillID = SpillLocs.idFor(L);
- if (SpillID == 0)
- return None;
-
- unsigned LocID = getLocID(SpillID, true);
- LocIdx Idx = LocIDToLocIdx[LocID];
- return LocIdxToIDNum[Idx];
- }
-
- /// Determine the LocIdx of a spill slot. Return None if it previously
- /// hasn't had a value assigned.
- Optional<LocIdx> getSpillMLoc(SpillLoc L) {
- unsigned SpillID = SpillLocs.idFor(L);
- if (SpillID == 0)
- return None;
- unsigned LocNo = getLocID(SpillID, true);
- return LocIDToLocIdx[LocNo];
- }
-
- /// Return true if Idx is a spill machine location.
- bool isSpill(LocIdx Idx) const {
- return LocIdxToLocID[Idx] >= NumRegs;
- }
-
- MLocIterator begin() {
- return MLocIterator(LocIdxToIDNum, 0);
- }
-
- MLocIterator end() {
- return MLocIterator(LocIdxToIDNum, LocIdxToIDNum.size());
- }
-
- /// Return a range over all locations currently tracked.
- iterator_range<MLocIterator> locations() {
- return llvm::make_range(begin(), end());
- }
-
- std::string LocIdxToName(LocIdx Idx) const {
- unsigned ID = LocIdxToLocID[Idx];
- if (ID >= NumRegs)
- return Twine("slot ").concat(Twine(ID - NumRegs)).str();
- else
- return TRI.getRegAsmName(ID).str();
- }
-
- std::string IDAsString(const ValueIDNum &Num) const {
- std::string DefName = LocIdxToName(Num.getLoc());
- return Num.asString(DefName);
- }
-
- LLVM_DUMP_METHOD
- void dump() {
- for (auto Location : locations()) {
- std::string MLocName = LocIdxToName(Location.Value.getLoc());
- std::string DefName = Location.Value.asString(MLocName);
- dbgs() << LocIdxToName(Location.Idx) << " --> " << DefName << "\n";
- }
- }
-
- LLVM_DUMP_METHOD
- void dump_mloc_map() {
- for (auto Location : locations()) {
- std::string foo = LocIdxToName(Location.Idx);
- dbgs() << "Idx " << Location.Idx.asU64() << " " << foo << "\n";
- }
- }
-
- /// Create a DBG_VALUE based on machine location \p MLoc. Qualify it with the
- /// information in \pProperties, for variable Var. Don't insert it anywhere,
- /// just return the builder for it.
- MachineInstrBuilder emitLoc(Optional<LocIdx> MLoc, const DebugVariable &Var,
- const DbgValueProperties &Properties) {
- DebugLoc DL = DILocation::get(Var.getVariable()->getContext(), 0, 0,
- Var.getVariable()->getScope(),
- const_cast<DILocation *>(Var.getInlinedAt()));
- auto MIB = BuildMI(MF, DL, TII.get(TargetOpcode::DBG_VALUE));
-
- const DIExpression *Expr = Properties.DIExpr;
- if (!MLoc) {
- // No location -> DBG_VALUE $noreg
- MIB.addReg(0, RegState::Debug);
- MIB.addReg(0, RegState::Debug);
- } else if (LocIdxToLocID[*MLoc] >= NumRegs) {
- unsigned LocID = LocIdxToLocID[*MLoc];
- const SpillLoc &Spill = SpillLocs[LocID - NumRegs + 1];
-
- auto *TRI = MF.getSubtarget().getRegisterInfo();
- Expr = TRI->prependOffsetExpression(Expr, DIExpression::ApplyOffset,
- Spill.SpillOffset);
- unsigned Base = Spill.SpillBase;
- MIB.addReg(Base, RegState::Debug);
- MIB.addImm(0);
- } else {
- unsigned LocID = LocIdxToLocID[*MLoc];
- MIB.addReg(LocID, RegState::Debug);
- if (Properties.Indirect)
- MIB.addImm(0);
- else
- MIB.addReg(0, RegState::Debug);
- }
-
- MIB.addMetadata(Var.getVariable());
- MIB.addMetadata(Expr);
- return MIB;
- }
-};
-
-/// Class recording the (high level) _value_ of a variable. Identifies either
-/// the value of the variable as a ValueIDNum, or a constant MachineOperand.
-/// This class also stores meta-information about how the value is qualified.
-/// Used to reason about variable values when performing the second
-/// (DebugVariable specific) dataflow analysis.
-class DbgValue {
-public:
- union {
- /// If Kind is Def, the value number that this value is based on.
- ValueIDNum ID;
- /// If Kind is Const, the MachineOperand defining this value.
- MachineOperand MO;
- /// For a NoVal DbgValue, which block it was generated in.
- unsigned BlockNo;
- };
- /// Qualifiers for the ValueIDNum above.
- DbgValueProperties Properties;
-
- typedef enum {
- Undef, // Represents a DBG_VALUE $noreg in the transfer function only.
- Def, // This value is defined by an inst, or is a PHI value.
- Const, // A constant value contained in the MachineOperand field.
- Proposed, // This is a tentative PHI value, which may be confirmed or
- // invalidated later.
- NoVal // Empty DbgValue, generated during dataflow. BlockNo stores
- // which block this was generated in.
- } KindT;
- /// Discriminator for whether this is a constant or an in-program value.
- KindT Kind;
-
- DbgValue(const ValueIDNum &Val, const DbgValueProperties &Prop, KindT Kind)
- : ID(Val), Properties(Prop), Kind(Kind) {
- assert(Kind == Def || Kind == Proposed);
- }
-
- DbgValue(unsigned BlockNo, const DbgValueProperties &Prop, KindT Kind)
- : BlockNo(BlockNo), Properties(Prop), Kind(Kind) {
- assert(Kind == NoVal);
- }
-
- DbgValue(const MachineOperand &MO, const DbgValueProperties &Prop, KindT Kind)
- : MO(MO), Properties(Prop), Kind(Kind) {
- assert(Kind == Const);
- }
-
- DbgValue(const DbgValueProperties &Prop, KindT Kind)
- : Properties(Prop), Kind(Kind) {
- assert(Kind == Undef &&
- "Empty DbgValue constructor must pass in Undef kind");
- }
-
- void dump(const MLocTracker *MTrack) const {
- if (Kind == Const) {
- MO.dump();
- } else if (Kind == NoVal) {
- dbgs() << "NoVal(" << BlockNo << ")";
- } else if (Kind == Proposed) {
- dbgs() << "VPHI(" << MTrack->IDAsString(ID) << ")";
- } else {
- assert(Kind == Def);
- dbgs() << MTrack->IDAsString(ID);
- }
- if (Properties.Indirect)
- dbgs() << " indir";
- if (Properties.DIExpr)
- dbgs() << " " << *Properties.DIExpr;
- }
-
- bool operator==(const DbgValue &Other) const {
- if (std::tie(Kind, Properties) != std::tie(Other.Kind, Other.Properties))
- return false;
- else if (Kind == Proposed && ID != Other.ID)
- return false;
- else if (Kind == Def && ID != Other.ID)
- return false;
- else if (Kind == NoVal && BlockNo != Other.BlockNo)
- return false;
- else if (Kind == Const)
- return MO.isIdenticalTo(Other.MO);
-
- return true;
- }
-
- bool operator!=(const DbgValue &Other) const { return !(*this == Other); }
-};
-
-/// Types for recording sets of variable fragments that overlap. For a given
-/// local variable, we record all other fragments of that variable that could
-/// overlap it, to reduce search time.
-using FragmentOfVar =
- std::pair<const DILocalVariable *, DIExpression::FragmentInfo>;
-using OverlapMap =
- DenseMap<FragmentOfVar, SmallVector<DIExpression::FragmentInfo, 1>>;
-
-/// Collection of DBG_VALUEs observed when traversing a block. Records each
-/// variable and the value the DBG_VALUE refers to. Requires the machine value
-/// location dataflow algorithm to have run already, so that values can be
-/// identified.
-class VLocTracker {
-public:
- /// Map DebugVariable to the latest Value it's defined to have.
- /// Needs to be a MapVector because we determine order-in-the-input-MIR from
- /// the order in this container.
- /// We only retain the last DbgValue in each block for each variable, to
- /// determine the blocks live-out variable value. The Vars container forms the
- /// transfer function for this block, as part of the dataflow analysis. The
- /// movement of values between locations inside of a block is handled at a
- /// much later stage, in the TransferTracker class.
- MapVector<DebugVariable, DbgValue> Vars;
- DenseMap<DebugVariable, const DILocation *> Scopes;
- MachineBasicBlock *MBB;
-
-public:
- VLocTracker() {}
-
- void defVar(const MachineInstr &MI, const DbgValueProperties &Properties,
- Optional<ValueIDNum> ID) {
- assert(MI.isDebugValue() || MI.isDebugRef());
- DebugVariable Var(MI.getDebugVariable(), MI.getDebugExpression(),
- MI.getDebugLoc()->getInlinedAt());
- DbgValue Rec = (ID) ? DbgValue(*ID, Properties, DbgValue::Def)
- : DbgValue(Properties, DbgValue::Undef);
-
- // Attempt insertion; overwrite if it's already mapped.
- auto Result = Vars.insert(std::make_pair(Var, Rec));
- if (!Result.second)
- Result.first->second = Rec;
- Scopes[Var] = MI.getDebugLoc().get();
- }
-
- void defVar(const MachineInstr &MI, const MachineOperand &MO) {
- // Only DBG_VALUEs can define constant-valued variables.
- assert(MI.isDebugValue());
- DebugVariable Var(MI.getDebugVariable(), MI.getDebugExpression(),
- MI.getDebugLoc()->getInlinedAt());
- DbgValueProperties Properties(MI);
- DbgValue Rec = DbgValue(MO, Properties, DbgValue::Const);
-
- // Attempt insertion; overwrite if it's already mapped.
- auto Result = Vars.insert(std::make_pair(Var, Rec));
- if (!Result.second)
- Result.first->second = Rec;
- Scopes[Var] = MI.getDebugLoc().get();
- }
-};
-
-/// Tracker for converting machine value locations and variable values into
-/// variable locations (the output of LiveDebugValues), recorded as DBG_VALUEs
-/// specifying block live-in locations and transfers within blocks.
-///
-/// Operating on a per-block basis, this class takes a (pre-loaded) MLocTracker
-/// and must be initialized with the set of variable values that are live-in to
-/// the block. The caller then repeatedly calls process(). TransferTracker picks
-/// out variable locations for the live-in variable values (if there _is_ a
-/// location) and creates the corresponding DBG_VALUEs. Then, as the block is
-/// stepped through, transfers of values between machine locations are
-/// identified and if profitable, a DBG_VALUE created.
-///
-/// This is where debug use-before-defs would be resolved: a variable with an
-/// unavailable value could materialize in the middle of a block, when the
-/// value becomes available. Or, we could detect clobbers and re-specify the
-/// variable in a backup location. (XXX these are unimplemented).
-class TransferTracker {
-public:
- const TargetInstrInfo *TII;
- /// This machine location tracker is assumed to always contain the up-to-date
- /// value mapping for all machine locations. TransferTracker only reads
- /// information from it. (XXX make it const?)
- MLocTracker *MTracker;
- MachineFunction &MF;
-
- /// Record of all changes in variable locations at a block position. Awkwardly
- /// we allow inserting either before or after the point: MBB != nullptr
- /// indicates it's before, otherwise after.
- struct Transfer {
- MachineBasicBlock::iterator Pos; /// Position to insert DBG_VALUes
- MachineBasicBlock *MBB; /// non-null if we should insert after.
- SmallVector<MachineInstr *, 4> Insts; /// Vector of DBG_VALUEs to insert.
- };
-
- typedef struct {
- LocIdx Loc;
- DbgValueProperties Properties;
- } LocAndProperties;
-
- /// Collection of transfers (DBG_VALUEs) to be inserted.
- SmallVector<Transfer, 32> Transfers;
-
- /// Local cache of what-value-is-in-what-LocIdx. Used to identify differences
- /// between TransferTrackers view of variable locations and MLocTrackers. For
- /// example, MLocTracker observes all clobbers, but TransferTracker lazily
- /// does not.
- std::vector<ValueIDNum> VarLocs;
-
- /// Map from LocIdxes to which DebugVariables are based that location.
- /// Mantained while stepping through the block. Not accurate if
- /// VarLocs[Idx] != MTracker->LocIdxToIDNum[Idx].
- std::map<LocIdx, SmallSet<DebugVariable, 4>> ActiveMLocs;
-
- /// Map from DebugVariable to it's current location and qualifying meta
- /// information. To be used in conjunction with ActiveMLocs to construct
- /// enough information for the DBG_VALUEs for a particular LocIdx.
- DenseMap<DebugVariable, LocAndProperties> ActiveVLocs;
-
- /// Temporary cache of DBG_VALUEs to be entered into the Transfers collection.
- SmallVector<MachineInstr *, 4> PendingDbgValues;
-
- /// Record of a use-before-def: created when a value that's live-in to the
- /// current block isn't available in any machine location, but it will be
- /// defined in this block.
- struct UseBeforeDef {
- /// Value of this variable, def'd in block.
- ValueIDNum ID;
- /// Identity of this variable.
- DebugVariable Var;
- /// Additional variable properties.
- DbgValueProperties Properties;
- };
-
- /// Map from instruction index (within the block) to the set of UseBeforeDefs
- /// that become defined at that instruction.
- DenseMap<unsigned, SmallVector<UseBeforeDef, 1>> UseBeforeDefs;
-
- /// The set of variables that are in UseBeforeDefs and can become a location
- /// once the relevant value is defined. An element being erased from this
- /// collection prevents the use-before-def materializing.
- DenseSet<DebugVariable> UseBeforeDefVariables;
-
- const TargetRegisterInfo &TRI;
- const BitVector &CalleeSavedRegs;
-
- TransferTracker(const TargetInstrInfo *TII, MLocTracker *MTracker,
- MachineFunction &MF, const TargetRegisterInfo &TRI,
- const BitVector &CalleeSavedRegs)
- : TII(TII), MTracker(MTracker), MF(MF), TRI(TRI),
- CalleeSavedRegs(CalleeSavedRegs) {}
-
- /// Load object with live-in variable values. \p mlocs contains the live-in
- /// values in each machine location, while \p vlocs the live-in variable
- /// values. This method picks variable locations for the live-in variables,
- /// creates DBG_VALUEs and puts them in #Transfers, then prepares the other
- /// object fields to track variable locations as we step through the block.
- /// FIXME: could just examine mloctracker instead of passing in \p mlocs?
- void loadInlocs(MachineBasicBlock &MBB, ValueIDNum *MLocs,
- SmallVectorImpl<std::pair<DebugVariable, DbgValue>> &VLocs,
- unsigned NumLocs) {
- ActiveMLocs.clear();
- ActiveVLocs.clear();
- VarLocs.clear();
- VarLocs.reserve(NumLocs);
- UseBeforeDefs.clear();
- UseBeforeDefVariables.clear();
-
- auto isCalleeSaved = [&](LocIdx L) {
- unsigned Reg = MTracker->LocIdxToLocID[L];
- if (Reg >= MTracker->NumRegs)
- return false;
- for (MCRegAliasIterator RAI(Reg, &TRI, true); RAI.isValid(); ++RAI)
- if (CalleeSavedRegs.test(*RAI))
- return true;
- return false;
- };
-
- // Map of the preferred location for each value.
- std::map<ValueIDNum, LocIdx> ValueToLoc;
-
- // Produce a map of value numbers to the current machine locs they live
- // in. When emulating VarLocBasedImpl, there should only be one
- // location; when not, we get to pick.
- for (auto Location : MTracker->locations()) {
- LocIdx Idx = Location.Idx;
- ValueIDNum &VNum = MLocs[Idx.asU64()];
- VarLocs.push_back(VNum);
- auto it = ValueToLoc.find(VNum);
- // In order of preference, pick:
- // * Callee saved registers,
- // * Other registers,
- // * Spill slots.
- if (it == ValueToLoc.end() || MTracker->isSpill(it->second) ||
- (!isCalleeSaved(it->second) && isCalleeSaved(Idx.asU64()))) {
- // Insert, or overwrite if insertion failed.
- auto PrefLocRes = ValueToLoc.insert(std::make_pair(VNum, Idx));
- if (!PrefLocRes.second)
- PrefLocRes.first->second = Idx;
- }
- }
-
- // Now map variables to their picked LocIdxes.
- for (auto Var : VLocs) {
- if (Var.second.Kind == DbgValue::Const) {
- PendingDbgValues.push_back(
- emitMOLoc(Var.second.MO, Var.first, Var.second.Properties));
- continue;
- }
-
- // If the value has no location, we can't make a variable location.
- const ValueIDNum &Num = Var.second.ID;
- auto ValuesPreferredLoc = ValueToLoc.find(Num);
- if (ValuesPreferredLoc == ValueToLoc.end()) {
- // If it's a def that occurs in this block, register it as a
- // use-before-def to be resolved as we step through the block.
- if (Num.getBlock() == (unsigned)MBB.getNumber() && !Num.isPHI())
- addUseBeforeDef(Var.first, Var.second.Properties, Num);
- continue;
- }
-
- LocIdx M = ValuesPreferredLoc->second;
- auto NewValue = LocAndProperties{M, Var.second.Properties};
- auto Result = ActiveVLocs.insert(std::make_pair(Var.first, NewValue));
- if (!Result.second)
- Result.first->second = NewValue;
- ActiveMLocs[M].insert(Var.first);
- PendingDbgValues.push_back(
- MTracker->emitLoc(M, Var.first, Var.second.Properties));
- }
- flushDbgValues(MBB.begin(), &MBB);
- }
-
- /// Record that \p Var has value \p ID, a value that becomes available
- /// later in the function.
- void addUseBeforeDef(const DebugVariable &Var,
- const DbgValueProperties &Properties, ValueIDNum ID) {
- UseBeforeDef UBD = {ID, Var, Properties};
- UseBeforeDefs[ID.getInst()].push_back(UBD);
- UseBeforeDefVariables.insert(Var);
- }
-
- /// After the instruction at index \p Inst and position \p pos has been
- /// processed, check whether it defines a variable value in a use-before-def.
- /// If so, and the variable value hasn't changed since the start of the
- /// block, create a DBG_VALUE.
- void checkInstForNewValues(unsigned Inst, MachineBasicBlock::iterator pos) {
- auto MIt = UseBeforeDefs.find(Inst);
- if (MIt == UseBeforeDefs.end())
- return;
-
- for (auto &Use : MIt->second) {
- LocIdx L = Use.ID.getLoc();
-
- // If something goes very wrong, we might end up labelling a COPY
- // instruction or similar with an instruction number, where it doesn't
- // actually define a new value, instead it moves a value. In case this
- // happens, discard.
- if (MTracker->LocIdxToIDNum[L] != Use.ID)
- continue;
-
- // If a different debug instruction defined the variable value / location
- // since the start of the block, don't materialize this use-before-def.
- if (!UseBeforeDefVariables.count(Use.Var))
- continue;
-
- PendingDbgValues.push_back(MTracker->emitLoc(L, Use.Var, Use.Properties));
- }
- flushDbgValues(pos, nullptr);
- }
-
- /// Helper to move created DBG_VALUEs into Transfers collection.
- void flushDbgValues(MachineBasicBlock::iterator Pos, MachineBasicBlock *MBB) {
- if (PendingDbgValues.size() > 0) {
- Transfers.push_back({Pos, MBB, PendingDbgValues});
- PendingDbgValues.clear();
- }
- }
-
- /// Change a variable value after encountering a DBG_VALUE inside a block.
- void redefVar(const MachineInstr &MI) {
- DebugVariable Var(MI.getDebugVariable(), MI.getDebugExpression(),
- MI.getDebugLoc()->getInlinedAt());
- DbgValueProperties Properties(MI);
-
- const MachineOperand &MO = MI.getOperand(0);
-
- // Ignore non-register locations, we don't transfer those.
- if (!MO.isReg() || MO.getReg() == 0) {
- auto It = ActiveVLocs.find(Var);
- if (It != ActiveVLocs.end()) {
- ActiveMLocs[It->second.Loc].erase(Var);
- ActiveVLocs.erase(It);
- }
- // Any use-before-defs no longer apply.
- UseBeforeDefVariables.erase(Var);
- return;
- }
-
- Register Reg = MO.getReg();
- LocIdx NewLoc = MTracker->getRegMLoc(Reg);
- redefVar(MI, Properties, NewLoc);
- }
-
- /// Handle a change in variable location within a block. Terminate the
- /// variables current location, and record the value it now refers to, so
- /// that we can detect location transfers later on.
- void redefVar(const MachineInstr &MI, const DbgValueProperties &Properties,
- Optional<LocIdx> OptNewLoc) {
- DebugVariable Var(MI.getDebugVariable(), MI.getDebugExpression(),
- MI.getDebugLoc()->getInlinedAt());
- // Any use-before-defs no longer apply.
- UseBeforeDefVariables.erase(Var);
-
- // Erase any previous location,
- auto It = ActiveVLocs.find(Var);
- if (It != ActiveVLocs.end())
- ActiveMLocs[It->second.Loc].erase(Var);
-
- // If there _is_ no new location, all we had to do was erase.
- if (!OptNewLoc)
- return;
- LocIdx NewLoc = *OptNewLoc;
-
- // Check whether our local copy of values-by-location in #VarLocs is out of
- // date. Wipe old tracking data for the location if it's been clobbered in
- // the meantime.
- if (MTracker->getNumAtPos(NewLoc) != VarLocs[NewLoc.asU64()]) {
- for (auto &P : ActiveMLocs[NewLoc]) {
- ActiveVLocs.erase(P);
- }
- ActiveMLocs[NewLoc.asU64()].clear();
- VarLocs[NewLoc.asU64()] = MTracker->getNumAtPos(NewLoc);
- }
-
- ActiveMLocs[NewLoc].insert(Var);
- if (It == ActiveVLocs.end()) {
- ActiveVLocs.insert(
- std::make_pair(Var, LocAndProperties{NewLoc, Properties}));
- } else {
- It->second.Loc = NewLoc;
- It->second.Properties = Properties;
- }
- }
-
- /// Explicitly terminate variable locations based on \p mloc. Creates undef
- /// DBG_VALUEs for any variables that were located there, and clears
- /// #ActiveMLoc / #ActiveVLoc tracking information for that location.
- void clobberMloc(LocIdx MLoc, MachineBasicBlock::iterator Pos) {
- assert(MTracker->isSpill(MLoc));
- auto ActiveMLocIt = ActiveMLocs.find(MLoc);
- if (ActiveMLocIt == ActiveMLocs.end())
- return;
-
- VarLocs[MLoc.asU64()] = ValueIDNum::EmptyValue;
-
- for (auto &Var : ActiveMLocIt->second) {
- auto ActiveVLocIt = ActiveVLocs.find(Var);
- // Create an undef. We can't feed in a nullptr DIExpression alas,
- // so use the variables last expression. Pass None as the location.
- const DIExpression *Expr = ActiveVLocIt->second.Properties.DIExpr;
- DbgValueProperties Properties(Expr, false);
- PendingDbgValues.push_back(MTracker->emitLoc(None, Var, Properties));
- ActiveVLocs.erase(ActiveVLocIt);
- }
- flushDbgValues(Pos, nullptr);
-
- ActiveMLocIt->second.clear();
- }
-
- /// Transfer variables based on \p Src to be based on \p Dst. This handles
- /// both register copies as well as spills and restores. Creates DBG_VALUEs
- /// describing the movement.
- void transferMlocs(LocIdx Src, LocIdx Dst, MachineBasicBlock::iterator Pos) {
- // Does Src still contain the value num we expect? If not, it's been
- // clobbered in the meantime, and our variable locations are stale.
- if (VarLocs[Src.asU64()] != MTracker->getNumAtPos(Src))
- return;
-
- // assert(ActiveMLocs[Dst].size() == 0);
- //^^^ Legitimate scenario on account of un-clobbered slot being assigned to?
- ActiveMLocs[Dst] = ActiveMLocs[Src];
- VarLocs[Dst.asU64()] = VarLocs[Src.asU64()];
-
- // For each variable based on Src; create a location at Dst.
- for (auto &Var : ActiveMLocs[Src]) {
- auto ActiveVLocIt = ActiveVLocs.find(Var);
- assert(ActiveVLocIt != ActiveVLocs.end());
- ActiveVLocIt->second.Loc = Dst;
-
- assert(Dst != 0);
- MachineInstr *MI =
- MTracker->emitLoc(Dst, Var, ActiveVLocIt->second.Properties);
- PendingDbgValues.push_back(MI);
- }
- ActiveMLocs[Src].clear();
- flushDbgValues(Pos, nullptr);
-
- // XXX XXX XXX "pretend to be old LDV" means dropping all tracking data
- // about the old location.
- if (EmulateOldLDV)
- VarLocs[Src.asU64()] = ValueIDNum::EmptyValue;
- }
-
- MachineInstrBuilder emitMOLoc(const MachineOperand &MO,
- const DebugVariable &Var,
- const DbgValueProperties &Properties) {
- DebugLoc DL = DILocation::get(Var.getVariable()->getContext(), 0, 0,
- Var.getVariable()->getScope(),
- const_cast<DILocation *>(Var.getInlinedAt()));
- auto MIB = BuildMI(MF, DL, TII->get(TargetOpcode::DBG_VALUE));
- MIB.add(MO);
- if (Properties.Indirect)
- MIB.addImm(0);
- else
- MIB.addReg(0);
- MIB.addMetadata(Var.getVariable());
- MIB.addMetadata(Properties.DIExpr);
- return MIB;
- }
-};
-
-class InstrRefBasedLDV : public LDVImpl {
-private:
- using FragmentInfo = DIExpression::FragmentInfo;
- using OptFragmentInfo = Optional<DIExpression::FragmentInfo>;
-
- // Helper while building OverlapMap, a map of all fragments seen for a given
- // DILocalVariable.
- using VarToFragments =
- DenseMap<const DILocalVariable *, SmallSet<FragmentInfo, 4>>;
-
- /// Machine location/value transfer function, a mapping of which locations
- /// are assigned which new values.
- using MLocTransferMap = std::map<LocIdx, ValueIDNum>;
-
- /// Live in/out structure for the variable values: a per-block map of
- /// variables to their values. XXX, better name?
- using LiveIdxT =
- DenseMap<const MachineBasicBlock *, DenseMap<DebugVariable, DbgValue> *>;
-
- using VarAndLoc = std::pair<DebugVariable, DbgValue>;
-
- /// Type for a live-in value: the predecessor block, and its value.
- using InValueT = std::pair<MachineBasicBlock *, DbgValue *>;
-
- /// Vector (per block) of a collection (inner smallvector) of live-ins.
- /// Used as the result type for the variable value dataflow problem.
- using LiveInsT = SmallVector<SmallVector<VarAndLoc, 8>, 8>;
-
- const TargetRegisterInfo *TRI;
- const TargetInstrInfo *TII;
- const TargetFrameLowering *TFI;
- BitVector CalleeSavedRegs;
- LexicalScopes LS;
- TargetPassConfig *TPC;
-
- /// Object to track machine locations as we step through a block. Could
- /// probably be a field rather than a pointer, as it's always used.
- MLocTracker *MTracker;
-
- /// Number of the current block LiveDebugValues is stepping through.
- unsigned CurBB;
-
- /// Number of the current instruction LiveDebugValues is evaluating.
- unsigned CurInst;
-
- /// Variable tracker -- listens to DBG_VALUEs occurring as InstrRefBasedImpl
- /// steps through a block. Reads the values at each location from the
- /// MLocTracker object.
- VLocTracker *VTracker;
-
- /// Tracker for transfers, listens to DBG_VALUEs and transfers of values
- /// between locations during stepping, creates new DBG_VALUEs when values move
- /// location.
- TransferTracker *TTracker;
-
- /// Blocks which are artificial, i.e. blocks which exclusively contain
- /// instructions without DebugLocs, or with line 0 locations.
- SmallPtrSet<const MachineBasicBlock *, 16> ArtificialBlocks;
-
- // Mapping of blocks to and from their RPOT order.
- DenseMap<unsigned int, MachineBasicBlock *> OrderToBB;
- DenseMap<MachineBasicBlock *, unsigned int> BBToOrder;
- DenseMap<unsigned, unsigned> BBNumToRPO;
-
- /// Pair of MachineInstr, and its 1-based offset into the containing block.
- using InstAndNum = std::pair<const MachineInstr *, unsigned>;
- /// Map from debug instruction number to the MachineInstr labelled with that
- /// number, and its location within the function. Used to transform
- /// instruction numbers in DBG_INSTR_REFs into machine value numbers.
- std::map<uint64_t, InstAndNum> DebugInstrNumToInstr;
-
- // Map of overlapping variable fragments.
- OverlapMap OverlapFragments;
- VarToFragments SeenFragments;
-
- /// Tests whether this instruction is a spill to a stack slot.
- bool isSpillInstruction(const MachineInstr &MI, MachineFunction *MF);
-
- /// Decide if @MI is a spill instruction and return true if it is. We use 2
- /// criteria to make this decision:
- /// - Is this instruction a store to a spill slot?
- /// - Is there a register operand that is both used and killed?
- /// TODO: Store optimization can fold spills into other stores (including
- /// other spills). We do not handle this yet (more than one memory operand).
- bool isLocationSpill(const MachineInstr &MI, MachineFunction *MF,
- unsigned &Reg);
-
- /// If a given instruction is identified as a spill, return the spill slot
- /// and set \p Reg to the spilled register.
- Optional<SpillLoc> isRestoreInstruction(const MachineInstr &MI,
- MachineFunction *MF, unsigned &Reg);
-
- /// Given a spill instruction, extract the register and offset used to
- /// address the spill slot in a target independent way.
- SpillLoc extractSpillBaseRegAndOffset(const MachineInstr &MI);
-
- /// Observe a single instruction while stepping through a block.
- void process(MachineInstr &MI);
-
- /// Examines whether \p MI is a DBG_VALUE and notifies trackers.
- /// \returns true if MI was recognized and processed.
- bool transferDebugValue(const MachineInstr &MI);
-
- /// Examines whether \p MI is a DBG_INSTR_REF and notifies trackers.
- /// \returns true if MI was recognized and processed.
- bool transferDebugInstrRef(MachineInstr &MI);
-
- /// Examines whether \p MI is copy instruction, and notifies trackers.
- /// \returns true if MI was recognized and processed.
- bool transferRegisterCopy(MachineInstr &MI);
-
- /// Examines whether \p MI is stack spill or restore instruction, and
- /// notifies trackers. \returns true if MI was recognized and processed.
- bool transferSpillOrRestoreInst(MachineInstr &MI);
-
- /// Examines \p MI for any registers that it defines, and notifies trackers.
- void transferRegisterDef(MachineInstr &MI);
-
- /// Copy one location to the other, accounting for movement of subregisters
- /// too.
- void performCopy(Register Src, Register Dst);
-
- void accumulateFragmentMap(MachineInstr &MI);
-
- /// Step through the function, recording register definitions and movements
- /// in an MLocTracker. Convert the observations into a per-block transfer
- /// function in \p MLocTransfer, suitable for using with the machine value
- /// location dataflow problem.
- void
- produceMLocTransferFunction(MachineFunction &MF,
- SmallVectorImpl<MLocTransferMap> &MLocTransfer,
- unsigned MaxNumBlocks);
-
- /// Solve the machine value location dataflow problem. Takes as input the
- /// transfer functions in \p MLocTransfer. Writes the output live-in and
- /// live-out arrays to the (initialized to zero) multidimensional arrays in
- /// \p MInLocs and \p MOutLocs. The outer dimension is indexed by block
- /// number, the inner by LocIdx.
- void mlocDataflow(ValueIDNum **MInLocs, ValueIDNum **MOutLocs,
- SmallVectorImpl<MLocTransferMap> &MLocTransfer);
-
- /// Perform a control flow join (lattice value meet) of the values in machine
- /// locations at \p MBB. Follows the algorithm described in the file-comment,
- /// reading live-outs of predecessors from \p OutLocs, the current live ins
- /// from \p InLocs, and assigning the newly computed live ins back into
- /// \p InLocs. \returns two bools -- the first indicates whether a change
- /// was made, the second whether a lattice downgrade occurred. If the latter
- /// is true, revisiting this block is necessary.
- std::tuple<bool, bool>
- mlocJoin(MachineBasicBlock &MBB,
- SmallPtrSet<const MachineBasicBlock *, 16> &Visited,
- ValueIDNum **OutLocs, ValueIDNum *InLocs);
-
- /// Solve the variable value dataflow problem, for a single lexical scope.
- /// Uses the algorithm from the file comment to resolve control flow joins,
- /// although there are extra hacks, see vlocJoin. Reads the
- /// locations of values from the \p MInLocs and \p MOutLocs arrays (see
- /// mlocDataflow) and reads the variable values transfer function from
- /// \p AllTheVlocs. Live-in and Live-out variable values are stored locally,
- /// with the live-ins permanently stored to \p Output once the fixedpoint is
- /// reached.
- /// \p VarsWeCareAbout contains a collection of the variables in \p Scope
- /// that we should be tracking.
- /// \p AssignBlocks contains the set of blocks that aren't in \p Scope, but
- /// which do contain DBG_VALUEs, which VarLocBasedImpl tracks locations
- /// through.
- void vlocDataflow(const LexicalScope *Scope, const DILocation *DILoc,
- const SmallSet<DebugVariable, 4> &VarsWeCareAbout,
- SmallPtrSetImpl<MachineBasicBlock *> &AssignBlocks,
- LiveInsT &Output, ValueIDNum **MOutLocs,
- ValueIDNum **MInLocs,
- SmallVectorImpl<VLocTracker> &AllTheVLocs);
-
- /// Compute the live-ins to a block, considering control flow merges according
- /// to the method in the file comment. Live out and live in variable values
- /// are stored in \p VLOCOutLocs and \p VLOCInLocs. The live-ins for \p MBB
- /// are computed and stored into \p VLOCInLocs. \returns true if the live-ins
- /// are modified.
- /// \p InLocsT Output argument, storage for calculated live-ins.
- /// \returns two bools -- the first indicates whether a change
- /// was made, the second whether a lattice downgrade occurred. If the latter
- /// is true, revisiting this block is necessary.
- std::tuple<bool, bool>
- vlocJoin(MachineBasicBlock &MBB, LiveIdxT &VLOCOutLocs, LiveIdxT &VLOCInLocs,
- SmallPtrSet<const MachineBasicBlock *, 16> *VLOCVisited,
- unsigned BBNum, const SmallSet<DebugVariable, 4> &AllVars,
- ValueIDNum **MOutLocs, ValueIDNum **MInLocs,
- SmallPtrSet<const MachineBasicBlock *, 8> &InScopeBlocks,
- SmallPtrSet<const MachineBasicBlock *, 8> &BlocksToExplore,
- DenseMap<DebugVariable, DbgValue> &InLocsT);
-
- /// Continue exploration of the variable-value lattice, as explained in the
- /// file-level comment. \p OldLiveInLocation contains the current
- /// exploration position, from which we need to descend further. \p Values
- /// contains the set of live-in values, \p CurBlockRPONum the RPO number of
- /// the current block, and \p CandidateLocations a set of locations that
- /// should be considered as PHI locations, if we reach the bottom of the
- /// lattice. \returns true if we should downgrade; the value is the agreeing
- /// value number in a non-backedge predecessor.
- bool vlocDowngradeLattice(const MachineBasicBlock &MBB,
- const DbgValue &OldLiveInLocation,
- const SmallVectorImpl<InValueT> &Values,
- unsigned CurBlockRPONum);
-
- /// For the given block and live-outs feeding into it, try to find a
- /// machine location where they all join. If a solution for all predecessors
- /// can't be found, a location where all non-backedge-predecessors join
- /// will be returned instead. While this method finds a join location, this
- /// says nothing as to whether it should be used.
- /// \returns Pair of value ID if found, and true when the correct value
- /// is available on all predecessor edges, or false if it's only available
- /// for non-backedge predecessors.
- std::tuple<Optional<ValueIDNum>, bool>
- pickVPHILoc(MachineBasicBlock &MBB, const DebugVariable &Var,
- const LiveIdxT &LiveOuts, ValueIDNum **MOutLocs,
- ValueIDNum **MInLocs,
- const SmallVectorImpl<MachineBasicBlock *> &BlockOrders);
-
- /// Given the solutions to the two dataflow problems, machine value locations
- /// in \p MInLocs and live-in variable values in \p SavedLiveIns, runs the
- /// TransferTracker class over the function to produce live-in and transfer
- /// DBG_VALUEs, then inserts them. Groups of DBG_VALUEs are inserted in the
- /// order given by AllVarsNumbering -- this could be any stable order, but
- /// right now "order of appearence in function, when explored in RPO", so
- /// that we can compare explictly against VarLocBasedImpl.
- void emitLocations(MachineFunction &MF, LiveInsT SavedLiveIns,
- ValueIDNum **MInLocs,
- DenseMap<DebugVariable, unsigned> &AllVarsNumbering);
-
- /// Boilerplate computation of some initial sets, artifical blocks and
- /// RPOT block ordering.
- void initialSetup(MachineFunction &MF);
-
- bool ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC) override;
-
-public:
- /// Default construct and initialize the pass.
- InstrRefBasedLDV();
-
- LLVM_DUMP_METHOD
- void dump_mloc_transfer(const MLocTransferMap &mloc_transfer) const;
-
- bool isCalleeSaved(LocIdx L) {
- unsigned Reg = MTracker->LocIdxToLocID[L];
- for (MCRegAliasIterator RAI(Reg, TRI, true); RAI.isValid(); ++RAI)
- if (CalleeSavedRegs.test(*RAI))
- return true;
- return false;
- }
-};
-
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// Implementation
-//===----------------------------------------------------------------------===//
-
-ValueIDNum ValueIDNum::EmptyValue = {UINT_MAX, UINT_MAX, UINT_MAX};
-
-/// Default construct and initialize the pass.
-InstrRefBasedLDV::InstrRefBasedLDV() {}
-
-//===----------------------------------------------------------------------===//
-// Debug Range Extension Implementation
-//===----------------------------------------------------------------------===//
-
-#ifndef NDEBUG
-// Something to restore in the future.
-// void InstrRefBasedLDV::printVarLocInMBB(..)
-#endif
-
-SpillLoc
-InstrRefBasedLDV::extractSpillBaseRegAndOffset(const MachineInstr &MI) {
- assert(MI.hasOneMemOperand() &&
- "Spill instruction does not have exactly one memory operand?");
- auto MMOI = MI.memoperands_begin();
- const PseudoSourceValue *PVal = (*MMOI)->getPseudoValue();
- assert(PVal->kind() == PseudoSourceValue::FixedStack &&
- "Inconsistent memory operand in spill instruction");
- int FI = cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex();
- const MachineBasicBlock *MBB = MI.getParent();
- Register Reg;
- StackOffset Offset = TFI->getFrameIndexReference(*MBB->getParent(), FI, Reg);
- return {Reg, Offset};
-}
-
-/// End all previous ranges related to @MI and start a new range from @MI
-/// if it is a DBG_VALUE instr.
-bool InstrRefBasedLDV::transferDebugValue(const MachineInstr &MI) {
- if (!MI.isDebugValue())
- return false;
-
- const DILocalVariable *Var = MI.getDebugVariable();
- const DIExpression *Expr = MI.getDebugExpression();
- const DILocation *DebugLoc = MI.getDebugLoc();
- const DILocation *InlinedAt = DebugLoc->getInlinedAt();
- assert(Var->isValidLocationForIntrinsic(DebugLoc) &&
- "Expected inlined-at fields to agree");
-
- DebugVariable V(Var, Expr, InlinedAt);
- DbgValueProperties Properties(MI);
-
- // If there are no instructions in this lexical scope, do no location tracking
- // at all, this variable shouldn't get a legitimate location range.
- auto *Scope = LS.findLexicalScope(MI.getDebugLoc().get());
- if (Scope == nullptr)
- return true; // handled it; by doing nothing
-
- const MachineOperand &MO = MI.getOperand(0);
-
- // MLocTracker needs to know that this register is read, even if it's only
- // read by a debug inst.
- if (MO.isReg() && MO.getReg() != 0)
- (void)MTracker->readReg(MO.getReg());
-
- // If we're preparing for the second analysis (variables), the machine value
- // locations are already solved, and we report this DBG_VALUE and the value
- // it refers to to VLocTracker.
- if (VTracker) {
- if (MO.isReg()) {
- // Feed defVar the new variable location, or if this is a
- // DBG_VALUE $noreg, feed defVar None.
- if (MO.getReg())
- VTracker->defVar(MI, Properties, MTracker->readReg(MO.getReg()));
- else
- VTracker->defVar(MI, Properties, None);
- } else if (MI.getOperand(0).isImm() || MI.getOperand(0).isFPImm() ||
- MI.getOperand(0).isCImm()) {
- VTracker->defVar(MI, MI.getOperand(0));
- }
- }
-
- // If performing final tracking of transfers, report this variable definition
- // to the TransferTracker too.
- if (TTracker)
- TTracker->redefVar(MI);
- return true;
-}
-
-bool InstrRefBasedLDV::transferDebugInstrRef(MachineInstr &MI) {
- if (!MI.isDebugRef())
- return false;
-
- // Only handle this instruction when we are building the variable value
- // transfer function.
- if (!VTracker)
- return false;
-
- unsigned InstNo = MI.getOperand(0).getImm();
- unsigned OpNo = MI.getOperand(1).getImm();
-
- const DILocalVariable *Var = MI.getDebugVariable();
- const DIExpression *Expr = MI.getDebugExpression();
- const DILocation *DebugLoc = MI.getDebugLoc();
- const DILocation *InlinedAt = DebugLoc->getInlinedAt();
- assert(Var->isValidLocationForIntrinsic(DebugLoc) &&
- "Expected inlined-at fields to agree");
-
- DebugVariable V(Var, Expr, InlinedAt);
-
- auto *Scope = LS.findLexicalScope(MI.getDebugLoc().get());
- if (Scope == nullptr)
- return true; // Handled by doing nothing. This variable is never in scope.
-
- const MachineFunction &MF = *MI.getParent()->getParent();
-
- // Various optimizations may have happened to the value during codegen,
- // recorded in the value substitution table. Apply any substitutions to
- // the instruction / operand number in this DBG_INSTR_REF.
- auto Sub = MF.DebugValueSubstitutions.find(std::make_pair(InstNo, OpNo));
- while (Sub != MF.DebugValueSubstitutions.end()) {
- InstNo = Sub->second.first;
- OpNo = Sub->second.second;
- Sub = MF.DebugValueSubstitutions.find(std::make_pair(InstNo, OpNo));
- }
-
- // Default machine value number is <None> -- if no instruction defines
- // the corresponding value, it must have been optimized out.
- Optional<ValueIDNum> NewID = None;
-
- // Try to lookup the instruction number, and find the machine value number
- // that it defines.
- auto InstrIt = DebugInstrNumToInstr.find(InstNo);
- if (InstrIt != DebugInstrNumToInstr.end()) {
- const MachineInstr &TargetInstr = *InstrIt->second.first;
- uint64_t BlockNo = TargetInstr.getParent()->getNumber();
-
- // Pick out the designated operand.
- assert(OpNo < TargetInstr.getNumOperands());
- const MachineOperand &MO = TargetInstr.getOperand(OpNo);
-
- // Today, this can only be a register.
- assert(MO.isReg() && MO.isDef());
-
- unsigned LocID = MTracker->getLocID(MO.getReg(), false);
- LocIdx L = MTracker->LocIDToLocIdx[LocID];
- NewID = ValueIDNum(BlockNo, InstrIt->second.second, L);
- }
-
- // We, we have a value number or None. Tell the variable value tracker about
- // it. The rest of this LiveDebugValues implementation acts exactly the same
- // for DBG_INSTR_REFs as DBG_VALUEs (just, the former can refer to values that
- // aren't immediately available).
- DbgValueProperties Properties(Expr, false);
- VTracker->defVar(MI, Properties, NewID);
-
- // If we're on the final pass through the function, decompose this INSTR_REF
- // into a plain DBG_VALUE.
- if (!TTracker)
- return true;
-
- // Pick a location for the machine value number, if such a location exists.
- // (This information could be stored in TransferTracker to make it faster).
- Optional<LocIdx> FoundLoc = None;
- for (auto Location : MTracker->locations()) {
- LocIdx CurL = Location.Idx;
- ValueIDNum ID = MTracker->LocIdxToIDNum[CurL];
- if (NewID && ID == NewID) {
- // If this is the first location with that value, pick it. Otherwise,
- // consider whether it's a "longer term" location.
- if (!FoundLoc) {
- FoundLoc = CurL;
- continue;
- }
-
- if (MTracker->isSpill(CurL))
- FoundLoc = CurL; // Spills are a longer term location.
- else if (!MTracker->isSpill(*FoundLoc) &&
- !MTracker->isSpill(CurL) &&
- !isCalleeSaved(*FoundLoc) &&
- isCalleeSaved(CurL))
- FoundLoc = CurL; // Callee saved regs are longer term than normal.
- }
- }
-
- // Tell transfer tracker that the variable value has changed.
- TTracker->redefVar(MI, Properties, FoundLoc);
-
- // If there was a value with no location; but the value is defined in a
- // later instruction in this block, this is a block-local use-before-def.
- if (!FoundLoc && NewID && NewID->getBlock() == CurBB &&
- NewID->getInst() > CurInst)
- TTracker->addUseBeforeDef(V, {MI.getDebugExpression(), false}, *NewID);
-
- // Produce a DBG_VALUE representing what this DBG_INSTR_REF meant.
- // This DBG_VALUE is potentially a $noreg / undefined location, if
- // FoundLoc is None.
- // (XXX -- could morph the DBG_INSTR_REF in the future).
- MachineInstr *DbgMI = MTracker->emitLoc(FoundLoc, V, Properties);
- TTracker->PendingDbgValues.push_back(DbgMI);
- TTracker->flushDbgValues(MI.getIterator(), nullptr);
-
- return true;
-}
-
-void InstrRefBasedLDV::transferRegisterDef(MachineInstr &MI) {
- // Meta Instructions do not affect the debug liveness of any register they
- // define.
- if (MI.isImplicitDef()) {
- // Except when there's an implicit def, and the location it's defining has
- // no value number. The whole point of an implicit def is to announce that
- // the register is live, without be specific about it's value. So define
- // a value if there isn't one already.
- ValueIDNum Num = MTracker->readReg(MI.getOperand(0).getReg());
- // Has a legitimate value -> ignore the implicit def.
- if (Num.getLoc() != 0)
- return;
- // Otherwise, def it here.
- } else if (MI.isMetaInstruction())
- return;
-
- MachineFunction *MF = MI.getMF();
- const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();
- Register SP = TLI->getStackPointerRegisterToSaveRestore();
-
- // Find the regs killed by MI, and find regmasks of preserved regs.
- // Max out the number of statically allocated elements in `DeadRegs`, as this
- // prevents fallback to std::set::count() operations.
- SmallSet<uint32_t, 32> DeadRegs;
- SmallVector<const uint32_t *, 4> RegMasks;
- SmallVector<const MachineOperand *, 4> RegMaskPtrs;
- for (const MachineOperand &MO : MI.operands()) {
- // Determine whether the operand is a register def.
- if (MO.isReg() && MO.isDef() && MO.getReg() &&
- Register::isPhysicalRegister(MO.getReg()) &&
- !(MI.isCall() && MO.getReg() == SP)) {
- // Remove ranges of all aliased registers.
- for (MCRegAliasIterator RAI(MO.getReg(), TRI, true); RAI.isValid(); ++RAI)
- // FIXME: Can we break out of this loop early if no insertion occurs?
- DeadRegs.insert(*RAI);
- } else if (MO.isRegMask()) {
- RegMasks.push_back(MO.getRegMask());
- RegMaskPtrs.push_back(&MO);
- }
- }
-
- // Tell MLocTracker about all definitions, of regmasks and otherwise.
- for (uint32_t DeadReg : DeadRegs)
- MTracker->defReg(DeadReg, CurBB, CurInst);
-
- for (auto *MO : RegMaskPtrs)
- MTracker->writeRegMask(MO, CurBB, CurInst);
-}
-
-void InstrRefBasedLDV::performCopy(Register SrcRegNum, Register DstRegNum) {
- ValueIDNum SrcValue = MTracker->readReg(SrcRegNum);
-
- MTracker->setReg(DstRegNum, SrcValue);
-
- // In all circumstances, re-def the super registers. It's definitely a new
- // value now. This doesn't uniquely identify the composition of subregs, for
- // example, two identical values in subregisters composed in different
- // places would not get equal value numbers.
- for (MCSuperRegIterator SRI(DstRegNum, TRI); SRI.isValid(); ++SRI)
- MTracker->defReg(*SRI, CurBB, CurInst);
-
- // If we're emulating VarLocBasedImpl, just define all the subregisters.
- // DBG_VALUEs of them will expect to be tracked from the DBG_VALUE, not
- // through prior copies.
- if (EmulateOldLDV) {
- for (MCSubRegIndexIterator DRI(DstRegNum, TRI); DRI.isValid(); ++DRI)
- MTracker->defReg(DRI.getSubReg(), CurBB, CurInst);
- return;
- }
-
- // Otherwise, actually copy subregisters from one location to another.
- // XXX: in addition, any subregisters of DstRegNum that don't line up with
- // the source register should be def'd.
- for (MCSubRegIndexIterator SRI(SrcRegNum, TRI); SRI.isValid(); ++SRI) {
- unsigned SrcSubReg = SRI.getSubReg();
- unsigned SubRegIdx = SRI.getSubRegIndex();
- unsigned DstSubReg = TRI->getSubReg(DstRegNum, SubRegIdx);
- if (!DstSubReg)
- continue;
-
- // Do copy. There are two matching subregisters, the source value should
- // have been def'd when the super-reg was, the latter might not be tracked
- // yet.
- // This will force SrcSubReg to be tracked, if it isn't yet.
- (void)MTracker->readReg(SrcSubReg);
- LocIdx SrcL = MTracker->getRegMLoc(SrcSubReg);
- assert(SrcL.asU64());
- (void)MTracker->readReg(DstSubReg);
- LocIdx DstL = MTracker->getRegMLoc(DstSubReg);
- assert(DstL.asU64());
- (void)DstL;
- ValueIDNum CpyValue = {SrcValue.getBlock(), SrcValue.getInst(), SrcL};
-
- MTracker->setReg(DstSubReg, CpyValue);
- }
-}
-
-bool InstrRefBasedLDV::isSpillInstruction(const MachineInstr &MI,
- MachineFunction *MF) {
- // TODO: Handle multiple stores folded into one.
- if (!MI.hasOneMemOperand())
- return false;
-
- if (!MI.getSpillSize(TII) && !MI.getFoldedSpillSize(TII))
- return false; // This is not a spill instruction, since no valid size was
- // returned from either function.
-
- return true;
-}
-
-bool InstrRefBasedLDV::isLocationSpill(const MachineInstr &MI,
- MachineFunction *MF, unsigned &Reg) {
- if (!isSpillInstruction(MI, MF))
- return false;
-
- // XXX FIXME: On x86, isStoreToStackSlotPostFE returns '1' instead of an
- // actual register number.
- if (ObserveAllStackops) {
- int FI;
- Reg = TII->isStoreToStackSlotPostFE(MI, FI);
- return Reg != 0;
- }
-
- auto isKilledReg = [&](const MachineOperand MO, unsigned &Reg) {
- if (!MO.isReg() || !MO.isUse()) {
- Reg = 0;
- return false;
- }
- Reg = MO.getReg();
- return MO.isKill();
- };
-
- for (const MachineOperand &MO : MI.operands()) {
- // In a spill instruction generated by the InlineSpiller the spilled
- // register has its kill flag set.
- if (isKilledReg(MO, Reg))
- return true;
- if (Reg != 0) {
- // Check whether next instruction kills the spilled register.
- // FIXME: Current solution does not cover search for killed register in
- // bundles and instructions further down the chain.
- auto NextI = std::next(MI.getIterator());
- // Skip next instruction that points to basic block end iterator.
- if (MI.getParent()->end() == NextI)
- continue;
- unsigned RegNext;
- for (const MachineOperand &MONext : NextI->operands()) {
- // Return true if we came across the register from the
- // previous spill instruction that is killed in NextI.
- if (isKilledReg(MONext, RegNext) && RegNext == Reg)
- return true;
- }
- }
- }
- // Return false if we didn't find spilled register.
- return false;
-}
-
-Optional<SpillLoc>
-InstrRefBasedLDV::isRestoreInstruction(const MachineInstr &MI,
- MachineFunction *MF, unsigned &Reg) {
- if (!MI.hasOneMemOperand())
- return None;
-
- // FIXME: Handle folded restore instructions with more than one memory
- // operand.
- if (MI.getRestoreSize(TII)) {
- Reg = MI.getOperand(0).getReg();
- return extractSpillBaseRegAndOffset(MI);
- }
- return None;
-}
-
-bool InstrRefBasedLDV::transferSpillOrRestoreInst(MachineInstr &MI) {
- // XXX -- it's too difficult to implement VarLocBasedImpl's stack location
- // limitations under the new model. Therefore, when comparing them, compare
- // versions that don't attempt spills or restores at all.
- if (EmulateOldLDV)
- return false;
-
- MachineFunction *MF = MI.getMF();
- unsigned Reg;
- Optional<SpillLoc> Loc;
-
- LLVM_DEBUG(dbgs() << "Examining instruction: "; MI.dump(););
-
- // First, if there are any DBG_VALUEs pointing at a spill slot that is
- // written to, terminate that variable location. The value in memory
- // will have changed. DbgEntityHistoryCalculator doesn't try to detect this.
- if (isSpillInstruction(MI, MF)) {
- Loc = extractSpillBaseRegAndOffset(MI);
-
- if (TTracker) {
- Optional<LocIdx> MLoc = MTracker->getSpillMLoc(*Loc);
- if (MLoc)
- TTracker->clobberMloc(*MLoc, MI.getIterator());
- }
- }
-
- // Try to recognise spill and restore instructions that may transfer a value.
- if (isLocationSpill(MI, MF, Reg)) {
- Loc = extractSpillBaseRegAndOffset(MI);
- auto ValueID = MTracker->readReg(Reg);
-
- // If the location is empty, produce a phi, signify it's the live-in value.
- if (ValueID.getLoc() == 0)
- ValueID = {CurBB, 0, MTracker->getRegMLoc(Reg)};
-
- MTracker->setSpill(*Loc, ValueID);
- auto OptSpillLocIdx = MTracker->getSpillMLoc(*Loc);
- assert(OptSpillLocIdx && "Spill slot set but has no LocIdx?");
- LocIdx SpillLocIdx = *OptSpillLocIdx;
-
- // Tell TransferTracker about this spill, produce DBG_VALUEs for it.
- if (TTracker)
- TTracker->transferMlocs(MTracker->getRegMLoc(Reg), SpillLocIdx,
- MI.getIterator());
- } else {
- if (!(Loc = isRestoreInstruction(MI, MF, Reg)))
- return false;
-
- // Is there a value to be restored?
- auto OptValueID = MTracker->readSpill(*Loc);
- if (OptValueID) {
- ValueIDNum ValueID = *OptValueID;
- LocIdx SpillLocIdx = *MTracker->getSpillMLoc(*Loc);
- // XXX -- can we recover sub-registers of this value? Until we can, first
- // overwrite all defs of the register being restored to.
- for (MCRegAliasIterator RAI(Reg, TRI, true); RAI.isValid(); ++RAI)
- MTracker->defReg(*RAI, CurBB, CurInst);
-
- // Now override the reg we're restoring to.
- MTracker->setReg(Reg, ValueID);
-
- // Report this restore to the transfer tracker too.
- if (TTracker)
- TTracker->transferMlocs(SpillLocIdx, MTracker->getRegMLoc(Reg),
- MI.getIterator());
- } else {
- // There isn't anything in the location; not clear if this is a code path
- // that still runs. Def this register anyway just in case.
- for (MCRegAliasIterator RAI(Reg, TRI, true); RAI.isValid(); ++RAI)
- MTracker->defReg(*RAI, CurBB, CurInst);
-
- // Force the spill slot to be tracked.
- LocIdx L = MTracker->getOrTrackSpillLoc(*Loc);
-
- // Set the restored value to be a machine phi number, signifying that it's
- // whatever the spills live-in value is in this block. Definitely has
- // a LocIdx due to the setSpill above.
- ValueIDNum ValueID = {CurBB, 0, L};
- MTracker->setReg(Reg, ValueID);
- MTracker->setSpill(*Loc, ValueID);
- }
- }
- return true;
-}
-
-bool InstrRefBasedLDV::transferRegisterCopy(MachineInstr &MI) {
- auto DestSrc = TII->isCopyInstr(MI);
- if (!DestSrc)
- return false;
-
- const MachineOperand *DestRegOp = DestSrc->Destination;
- const MachineOperand *SrcRegOp = DestSrc->Source;
-
- auto isCalleeSavedReg = [&](unsigned Reg) {
- for (MCRegAliasIterator RAI(Reg, TRI, true); RAI.isValid(); ++RAI)
- if (CalleeSavedRegs.test(*RAI))
- return true;
- return false;
- };
-
- Register SrcReg = SrcRegOp->getReg();
- Register DestReg = DestRegOp->getReg();
-
- // Ignore identity copies. Yep, these make it as far as LiveDebugValues.
- if (SrcReg == DestReg)
- return true;
-
- // For emulating VarLocBasedImpl:
- // We want to recognize instructions where destination register is callee
- // saved register. If register that could be clobbered by the call is
- // included, there would be a great chance that it is going to be clobbered
- // soon. It is more likely that previous register, which is callee saved, is
- // going to stay unclobbered longer, even if it is killed.
- //
- // For InstrRefBasedImpl, we can track multiple locations per value, so
- // ignore this condition.
- if (EmulateOldLDV && !isCalleeSavedReg(DestReg))
- return false;
-
- // InstrRefBasedImpl only followed killing copies.
- if (EmulateOldLDV && !SrcRegOp->isKill())
- return false;
-
- // Copy MTracker info, including subregs if available.
- InstrRefBasedLDV::performCopy(SrcReg, DestReg);
-
- // Only produce a transfer of DBG_VALUE within a block where old LDV
- // would have. We might make use of the additional value tracking in some
- // other way, later.
- if (TTracker && isCalleeSavedReg(DestReg) && SrcRegOp->isKill())
- TTracker->transferMlocs(MTracker->getRegMLoc(SrcReg),
- MTracker->getRegMLoc(DestReg), MI.getIterator());
-
- // VarLocBasedImpl would quit tracking the old location after copying.
- if (EmulateOldLDV && SrcReg != DestReg)
- MTracker->defReg(SrcReg, CurBB, CurInst);
-
- return true;
-}
-
-/// Accumulate a mapping between each DILocalVariable fragment and other
-/// fragments of that DILocalVariable which overlap. This reduces work during
-/// the data-flow stage from "Find any overlapping fragments" to "Check if the
-/// known-to-overlap fragments are present".
-/// \param MI A previously unprocessed DEBUG_VALUE instruction to analyze for
-/// fragment usage.
-void InstrRefBasedLDV::accumulateFragmentMap(MachineInstr &MI) {
- DebugVariable MIVar(MI.getDebugVariable(), MI.getDebugExpression(),
- MI.getDebugLoc()->getInlinedAt());
- FragmentInfo ThisFragment = MIVar.getFragmentOrDefault();
-
- // If this is the first sighting of this variable, then we are guaranteed
- // there are currently no overlapping fragments either. Initialize the set
- // of seen fragments, record no overlaps for the current one, and return.
- auto SeenIt = SeenFragments.find(MIVar.getVariable());
- if (SeenIt == SeenFragments.end()) {
- SmallSet<FragmentInfo, 4> OneFragment;
- OneFragment.insert(ThisFragment);
- SeenFragments.insert({MIVar.getVariable(), OneFragment});
-
- OverlapFragments.insert({{MIVar.getVariable(), ThisFragment}, {}});
- return;
- }
-
- // If this particular Variable/Fragment pair already exists in the overlap
- // map, it has already been accounted for.
- auto IsInOLapMap =
- OverlapFragments.insert({{MIVar.getVariable(), ThisFragment}, {}});
- if (!IsInOLapMap.second)
- return;
-
- auto &ThisFragmentsOverlaps = IsInOLapMap.first->second;
- auto &AllSeenFragments = SeenIt->second;
-
- // Otherwise, examine all other seen fragments for this variable, with "this"
- // fragment being a previously unseen fragment. Record any pair of
- // overlapping fragments.
- for (auto &ASeenFragment : AllSeenFragments) {
- // Does this previously seen fragment overlap?
- if (DIExpression::fragmentsOverlap(ThisFragment, ASeenFragment)) {
- // Yes: Mark the current fragment as being overlapped.
- ThisFragmentsOverlaps.push_back(ASeenFragment);
- // Mark the previously seen fragment as being overlapped by the current
- // one.
- auto ASeenFragmentsOverlaps =
- OverlapFragments.find({MIVar.getVariable(), ASeenFragment});
- assert(ASeenFragmentsOverlaps != OverlapFragments.end() &&
- "Previously seen var fragment has no vector of overlaps");
- ASeenFragmentsOverlaps->second.push_back(ThisFragment);
- }
- }
-
- AllSeenFragments.insert(ThisFragment);
-}
-
-void InstrRefBasedLDV::process(MachineInstr &MI) {
- // Try to interpret an MI as a debug or transfer instruction. Only if it's
- // none of these should we interpret it's register defs as new value
- // definitions.
- if (transferDebugValue(MI))
- return;
- if (transferDebugInstrRef(MI))
- return;
- if (transferRegisterCopy(MI))
- return;
- if (transferSpillOrRestoreInst(MI))
- return;
- transferRegisterDef(MI);
-}
-
-void InstrRefBasedLDV::produceMLocTransferFunction(
- MachineFunction &MF, SmallVectorImpl<MLocTransferMap> &MLocTransfer,
- unsigned MaxNumBlocks) {
- // Because we try to optimize around register mask operands by ignoring regs
- // that aren't currently tracked, we set up something ugly for later: RegMask
- // operands that are seen earlier than the first use of a register, still need
- // to clobber that register in the transfer function. But this information
- // isn't actively recorded. Instead, we track each RegMask used in each block,
- // and accumulated the clobbered but untracked registers in each block into
- // the following bitvector. Later, if new values are tracked, we can add
- // appropriate clobbers.
- SmallVector<BitVector, 32> BlockMasks;
- BlockMasks.resize(MaxNumBlocks);
-
- // Reserve one bit per register for the masks described above.
- unsigned BVWords = MachineOperand::getRegMaskSize(TRI->getNumRegs());
- for (auto &BV : BlockMasks)
- BV.resize(TRI->getNumRegs(), true);
-
- // Step through all instructions and inhale the transfer function.
- for (auto &MBB : MF) {
- // Object fields that are read by trackers to know where we are in the
- // function.
- CurBB = MBB.getNumber();
- CurInst = 1;
-
- // Set all machine locations to a PHI value. For transfer function
- // production only, this signifies the live-in value to the block.
- MTracker->reset();
- MTracker->setMPhis(CurBB);
-
- // Step through each instruction in this block.
- for (auto &MI : MBB) {
- process(MI);
- // Also accumulate fragment map.
- if (MI.isDebugValue())
- accumulateFragmentMap(MI);
-
- // Create a map from the instruction number (if present) to the
- // MachineInstr and its position.
- if (uint64_t InstrNo = MI.peekDebugInstrNum()) {
- auto InstrAndPos = std::make_pair(&MI, CurInst);
- auto InsertResult =
- DebugInstrNumToInstr.insert(std::make_pair(InstrNo, InstrAndPos));
-
- // There should never be duplicate instruction numbers.
- assert(InsertResult.second);
- (void)InsertResult;
- }
-
- ++CurInst;
- }
-
- // Produce the transfer function, a map of machine location to new value. If
- // any machine location has the live-in phi value from the start of the
- // block, it's live-through and doesn't need recording in the transfer
- // function.
- for (auto Location : MTracker->locations()) {
- LocIdx Idx = Location.Idx;
- ValueIDNum &P = Location.Value;
- if (P.isPHI() && P.getLoc() == Idx.asU64())
- continue;
-
- // Insert-or-update.
- auto &TransferMap = MLocTransfer[CurBB];
- auto Result = TransferMap.insert(std::make_pair(Idx.asU64(), P));
- if (!Result.second)
- Result.first->second = P;
- }
-
- // Accumulate any bitmask operands into the clobberred reg mask for this
- // block.
- for (auto &P : MTracker->Masks) {
- BlockMasks[CurBB].clearBitsNotInMask(P.first->getRegMask(), BVWords);
- }
- }
-
- // Compute a bitvector of all the registers that are tracked in this block.
- const TargetLowering *TLI = MF.getSubtarget().getTargetLowering();
- Register SP = TLI->getStackPointerRegisterToSaveRestore();
- BitVector UsedRegs(TRI->getNumRegs());
- for (auto Location : MTracker->locations()) {
- unsigned ID = MTracker->LocIdxToLocID[Location.Idx];
- if (ID >= TRI->getNumRegs() || ID == SP)
- continue;
- UsedRegs.set(ID);
- }
-
- // Check that any regmask-clobber of a register that gets tracked, is not
- // live-through in the transfer function. It needs to be clobbered at the
- // very least.
- for (unsigned int I = 0; I < MaxNumBlocks; ++I) {
- BitVector &BV = BlockMasks[I];
- BV.flip();
- BV &= UsedRegs;
- // This produces all the bits that we clobber, but also use. Check that
- // they're all clobbered or at least set in the designated transfer
- // elem.
- for (unsigned Bit : BV.set_bits()) {
- unsigned ID = MTracker->getLocID(Bit, false);
- LocIdx Idx = MTracker->LocIDToLocIdx[ID];
- auto &TransferMap = MLocTransfer[I];
-
- // Install a value representing the fact that this location is effectively
- // written to in this block. As there's no reserved value, instead use
- // a value number that is never generated. Pick the value number for the
- // first instruction in the block, def'ing this location, which we know
- // this block never used anyway.
- ValueIDNum NotGeneratedNum = ValueIDNum(I, 1, Idx);
- auto Result =
- TransferMap.insert(std::make_pair(Idx.asU64(), NotGeneratedNum));
- if (!Result.second) {
- ValueIDNum &ValueID = Result.first->second;
- if (ValueID.getBlock() == I && ValueID.isPHI())
- // It was left as live-through. Set it to clobbered.
- ValueID = NotGeneratedNum;
- }
- }
- }
-}
-
-std::tuple<bool, bool>
-InstrRefBasedLDV::mlocJoin(MachineBasicBlock &MBB,
- SmallPtrSet<const MachineBasicBlock *, 16> &Visited,
- ValueIDNum **OutLocs, ValueIDNum *InLocs) {
- LLVM_DEBUG(dbgs() << "join MBB: " << MBB.getNumber() << "\n");
- bool Changed = false;
- bool DowngradeOccurred = false;
-
- // Collect predecessors that have been visited. Anything that hasn't been
- // visited yet is a backedge on the first iteration, and the meet of it's
- // lattice value for all locations will be unaffected.
- SmallVector<const MachineBasicBlock *, 8> BlockOrders;
- for (auto Pred : MBB.predecessors()) {
- if (Visited.count(Pred)) {
- BlockOrders.push_back(Pred);
- }
- }
-
- // Visit predecessors in RPOT order.
- auto Cmp = [&](const MachineBasicBlock *A, const MachineBasicBlock *B) {
- return BBToOrder.find(A)->second < BBToOrder.find(B)->second;
- };
- llvm::sort(BlockOrders, Cmp);
-
- // Skip entry block.
- if (BlockOrders.size() == 0)
- return std::tuple<bool, bool>(false, false);
-
- // Step through all machine locations, then look at each predecessor and
- // detect disagreements.
- unsigned ThisBlockRPO = BBToOrder.find(&MBB)->second;
- for (auto Location : MTracker->locations()) {
- LocIdx Idx = Location.Idx;
- // Pick out the first predecessors live-out value for this location. It's
- // guaranteed to be not a backedge, as we order by RPO.
- ValueIDNum BaseVal = OutLocs[BlockOrders[0]->getNumber()][Idx.asU64()];
-
- // Some flags for whether there's a disagreement, and whether it's a
- // disagreement with a backedge or not.
- bool Disagree = false;
- bool NonBackEdgeDisagree = false;
-
- // Loop around everything that wasn't 'base'.
- for (unsigned int I = 1; I < BlockOrders.size(); ++I) {
- auto *MBB = BlockOrders[I];
- if (BaseVal != OutLocs[MBB->getNumber()][Idx.asU64()]) {
- // Live-out of a predecessor disagrees with the first predecessor.
- Disagree = true;
-
- // Test whether it's a disagreemnt in the backedges or not.
- if (BBToOrder.find(MBB)->second < ThisBlockRPO) // might be self b/e
- NonBackEdgeDisagree = true;
- }
- }
-
- bool OverRide = false;
- if (Disagree && !NonBackEdgeDisagree) {
- // Only the backedges disagree. Consider demoting the livein
- // lattice value, as per the file level comment. The value we consider
- // demoting to is the value that the non-backedge predecessors agree on.
- // The order of values is that non-PHIs are \top, a PHI at this block
- // \bot, and phis between the two are ordered by their RPO number.
- // If there's no agreement, or we've already demoted to this PHI value
- // before, replace with a PHI value at this block.
-
- // Calculate order numbers: zero means normal def, nonzero means RPO
- // number.
- unsigned BaseBlockRPONum = BBNumToRPO[BaseVal.getBlock()] + 1;
- if (!BaseVal.isPHI())
- BaseBlockRPONum = 0;
-
- ValueIDNum &InLocID = InLocs[Idx.asU64()];
- unsigned InLocRPONum = BBNumToRPO[InLocID.getBlock()] + 1;
- if (!InLocID.isPHI())
- InLocRPONum = 0;
-
- // Should we ignore the disagreeing backedges, and override with the
- // value the other predecessors agree on (in "base")?
- unsigned ThisBlockRPONum = BBNumToRPO[MBB.getNumber()] + 1;
- if (BaseBlockRPONum > InLocRPONum && BaseBlockRPONum < ThisBlockRPONum) {
- // Override.
- OverRide = true;
- DowngradeOccurred = true;
- }
- }
- // else: if we disagree in the non-backedges, then this is definitely
- // a control flow merge where different values merge. Make it a PHI.
-
- // Generate a phi...
- ValueIDNum PHI = {(uint64_t)MBB.getNumber(), 0, Idx};
- ValueIDNum NewVal = (Disagree && !OverRide) ? PHI : BaseVal;
- if (InLocs[Idx.asU64()] != NewVal) {
- Changed |= true;
- InLocs[Idx.asU64()] = NewVal;
- }
- }
-
- // TODO: Reimplement NumInserted and NumRemoved.
- return std::tuple<bool, bool>(Changed, DowngradeOccurred);
-}
-
-void InstrRefBasedLDV::mlocDataflow(
- ValueIDNum **MInLocs, ValueIDNum **MOutLocs,
- SmallVectorImpl<MLocTransferMap> &MLocTransfer) {
- std::priority_queue<unsigned int, std::vector<unsigned int>,
- std::greater<unsigned int>>
- Worklist, Pending;
-
- // We track what is on the current and pending worklist to avoid inserting
- // the same thing twice. We could avoid this with a custom priority queue,
- // but this is probably not worth it.
- SmallPtrSet<MachineBasicBlock *, 16> OnPending, OnWorklist;
-
- // Initialize worklist with every block to be visited.
- for (unsigned int I = 0; I < BBToOrder.size(); ++I) {
- Worklist.push(I);
- OnWorklist.insert(OrderToBB[I]);
- }
-
- MTracker->reset();
-
- // Set inlocs for entry block -- each as a PHI at the entry block. Represents
- // the incoming value to the function.
- MTracker->setMPhis(0);
- for (auto Location : MTracker->locations())
- MInLocs[0][Location.Idx.asU64()] = Location.Value;
-
- SmallPtrSet<const MachineBasicBlock *, 16> Visited;
- while (!Worklist.empty() || !Pending.empty()) {
- // Vector for storing the evaluated block transfer function.
- SmallVector<std::pair<LocIdx, ValueIDNum>, 32> ToRemap;
-
- while (!Worklist.empty()) {
- MachineBasicBlock *MBB = OrderToBB[Worklist.top()];
- CurBB = MBB->getNumber();
- Worklist.pop();
-
- // Join the values in all predecessor blocks.
- bool InLocsChanged, DowngradeOccurred;
- std::tie(InLocsChanged, DowngradeOccurred) =
- mlocJoin(*MBB, Visited, MOutLocs, MInLocs[CurBB]);
- InLocsChanged |= Visited.insert(MBB).second;
-
- // If a downgrade occurred, book us in for re-examination on the next
- // iteration.
- if (DowngradeOccurred && OnPending.insert(MBB).second)
- Pending.push(BBToOrder[MBB]);
-
- // Don't examine transfer function if we've visited this loc at least
- // once, and inlocs haven't changed.
- if (!InLocsChanged)
- continue;
-
- // Load the current set of live-ins into MLocTracker.
- MTracker->loadFromArray(MInLocs[CurBB], CurBB);
-
- // Each element of the transfer function can be a new def, or a read of
- // a live-in value. Evaluate each element, and store to "ToRemap".
- ToRemap.clear();
- for (auto &P : MLocTransfer[CurBB]) {
- if (P.second.getBlock() == CurBB && P.second.isPHI()) {
- // This is a movement of whatever was live in. Read it.
- ValueIDNum NewID = MTracker->getNumAtPos(P.second.getLoc());
- ToRemap.push_back(std::make_pair(P.first, NewID));
- } else {
- // It's a def. Just set it.
- assert(P.second.getBlock() == CurBB);
- ToRemap.push_back(std::make_pair(P.first, P.second));
- }
- }
-
- // Commit the transfer function changes into mloc tracker, which
- // transforms the contents of the MLocTracker into the live-outs.
- for (auto &P : ToRemap)
- MTracker->setMLoc(P.first, P.second);
-
- // Now copy out-locs from mloc tracker into out-loc vector, checking
- // whether changes have occurred. These changes can have come from both
- // the transfer function, and mlocJoin.
- bool OLChanged = false;
- for (auto Location : MTracker->locations()) {
- OLChanged |= MOutLocs[CurBB][Location.Idx.asU64()] != Location.Value;
- MOutLocs[CurBB][Location.Idx.asU64()] = Location.Value;
- }
-
- MTracker->reset();
-
- // No need to examine successors again if out-locs didn't change.
- if (!OLChanged)
- continue;
-
- // All successors should be visited: put any back-edges on the pending
- // list for the next dataflow iteration, and any other successors to be
- // visited this iteration, if they're not going to be already.
- for (auto s : MBB->successors()) {
- // Does branching to this successor represent a back-edge?
- if (BBToOrder[s] > BBToOrder[MBB]) {
- // No: visit it during this dataflow iteration.
- if (OnWorklist.insert(s).second)
- Worklist.push(BBToOrder[s]);
- } else {
- // Yes: visit it on the next iteration.
- if (OnPending.insert(s).second)
- Pending.push(BBToOrder[s]);
- }
- }
- }
-
- Worklist.swap(Pending);
- std::swap(OnPending, OnWorklist);
- OnPending.clear();
- // At this point, pending must be empty, since it was just the empty
- // worklist
- assert(Pending.empty() && "Pending should be empty");
- }
-
- // Once all the live-ins don't change on mlocJoin(), we've reached a
- // fixedpoint.
-}
-
-bool InstrRefBasedLDV::vlocDowngradeLattice(
- const MachineBasicBlock &MBB, const DbgValue &OldLiveInLocation,
- const SmallVectorImpl<InValueT> &Values, unsigned CurBlockRPONum) {
- // Ranking value preference: see file level comment, the highest rank is
- // a plain def, followed by PHI values in reverse post-order. Numerically,
- // we assign all defs the rank '0', all PHIs their blocks RPO number plus
- // one, and consider the lowest value the highest ranked.
- int OldLiveInRank = BBNumToRPO[OldLiveInLocation.ID.getBlock()] + 1;
- if (!OldLiveInLocation.ID.isPHI())
- OldLiveInRank = 0;
-
- // Allow any unresolvable conflict to be over-ridden.
- if (OldLiveInLocation.Kind == DbgValue::NoVal) {
- // Although if it was an unresolvable conflict from _this_ block, then
- // all other seeking of downgrades and PHIs must have failed before hand.
- if (OldLiveInLocation.BlockNo == (unsigned)MBB.getNumber())
- return false;
- OldLiveInRank = INT_MIN;
- }
-
- auto &InValue = *Values[0].second;
-
- if (InValue.Kind == DbgValue::Const || InValue.Kind == DbgValue::NoVal)
- return false;
-
- unsigned ThisRPO = BBNumToRPO[InValue.ID.getBlock()];
- int ThisRank = ThisRPO + 1;
- if (!InValue.ID.isPHI())
- ThisRank = 0;
-
- // Too far down the lattice?
- if (ThisRPO >= CurBlockRPONum)
- return false;
-
- // Higher in the lattice than what we've already explored?
- if (ThisRank <= OldLiveInRank)
- return false;
-
- return true;
-}
-
-std::tuple<Optional<ValueIDNum>, bool> InstrRefBasedLDV::pickVPHILoc(
- MachineBasicBlock &MBB, const DebugVariable &Var, const LiveIdxT &LiveOuts,
- ValueIDNum **MOutLocs, ValueIDNum **MInLocs,
- const SmallVectorImpl<MachineBasicBlock *> &BlockOrders) {
- // Collect a set of locations from predecessor where its live-out value can
- // be found.
- SmallVector<SmallVector<LocIdx, 4>, 8> Locs;
- unsigned NumLocs = MTracker->getNumLocs();
- unsigned BackEdgesStart = 0;
-
- for (auto p : BlockOrders) {
- // Pick out where backedges start in the list of predecessors. Relies on
- // BlockOrders being sorted by RPO.
- if (BBToOrder[p] < BBToOrder[&MBB])
- ++BackEdgesStart;
-
- // For each predecessor, create a new set of locations.
- Locs.resize(Locs.size() + 1);
- unsigned ThisBBNum = p->getNumber();
- auto LiveOutMap = LiveOuts.find(p);
- if (LiveOutMap == LiveOuts.end())
- // This predecessor isn't in scope, it must have no live-in/live-out
- // locations.
- continue;
-
- auto It = LiveOutMap->second->find(Var);
- if (It == LiveOutMap->second->end())
- // There's no value recorded for this variable in this predecessor,
- // leave an empty set of locations.
- continue;
-
- const DbgValue &OutVal = It->second;
-
- if (OutVal.Kind == DbgValue::Const || OutVal.Kind == DbgValue::NoVal)
- // Consts and no-values cannot have locations we can join on.
- continue;
-
- assert(OutVal.Kind == DbgValue::Proposed || OutVal.Kind == DbgValue::Def);
- ValueIDNum ValToLookFor = OutVal.ID;
-
- // Search the live-outs of the predecessor for the specified value.
- for (unsigned int I = 0; I < NumLocs; ++I) {
- if (MOutLocs[ThisBBNum][I] == ValToLookFor)
- Locs.back().push_back(LocIdx(I));
- }
- }
-
- // If there were no locations at all, return an empty result.
- if (Locs.empty())
- return std::tuple<Optional<ValueIDNum>, bool>(None, false);
-
- // Lambda for seeking a common location within a range of location-sets.
- using LocsIt = SmallVector<SmallVector<LocIdx, 4>, 8>::iterator;
- auto SeekLocation =
- [&Locs](llvm::iterator_range<LocsIt> SearchRange) -> Optional<LocIdx> {
- // Starting with the first set of locations, take the intersection with
- // subsequent sets.
- SmallVector<LocIdx, 4> base = Locs[0];
- for (auto &S : SearchRange) {
- SmallVector<LocIdx, 4> new_base;
- std::set_intersection(base.begin(), base.end(), S.begin(), S.end(),
- std::inserter(new_base, new_base.begin()));
- base = new_base;
- }
- if (base.empty())
- return None;
-
- // We now have a set of LocIdxes that contain the right output value in
- // each of the predecessors. Pick the lowest; if there's a register loc,
- // that'll be it.
- return *base.begin();
- };
-
- // Search for a common location for all predecessors. If we can't, then fall
- // back to only finding a common location between non-backedge predecessors.
- bool ValidForAllLocs = true;
- auto TheLoc = SeekLocation(Locs);
- if (!TheLoc) {
- ValidForAllLocs = false;
- TheLoc =
- SeekLocation(make_range(Locs.begin(), Locs.begin() + BackEdgesStart));
- }
-
- if (!TheLoc)
- return std::tuple<Optional<ValueIDNum>, bool>(None, false);
-
- // Return a PHI-value-number for the found location.
- LocIdx L = *TheLoc;
- ValueIDNum PHIVal = {(unsigned)MBB.getNumber(), 0, L};
- return std::tuple<Optional<ValueIDNum>, bool>(PHIVal, ValidForAllLocs);
-}
-
-std::tuple<bool, bool> InstrRefBasedLDV::vlocJoin(
- MachineBasicBlock &MBB, LiveIdxT &VLOCOutLocs, LiveIdxT &VLOCInLocs,
- SmallPtrSet<const MachineBasicBlock *, 16> *VLOCVisited, unsigned BBNum,
- const SmallSet<DebugVariable, 4> &AllVars, ValueIDNum **MOutLocs,
- ValueIDNum **MInLocs,
- SmallPtrSet<const MachineBasicBlock *, 8> &InScopeBlocks,
- SmallPtrSet<const MachineBasicBlock *, 8> &BlocksToExplore,
- DenseMap<DebugVariable, DbgValue> &InLocsT) {
- bool DowngradeOccurred = false;
-
- // To emulate VarLocBasedImpl, process this block if it's not in scope but
- // _does_ assign a variable value. No live-ins for this scope are transferred
- // in though, so we can return immediately.
- if (InScopeBlocks.count(&MBB) == 0 && !ArtificialBlocks.count(&MBB)) {
- if (VLOCVisited)
- return std::tuple<bool, bool>(true, false);
- return std::tuple<bool, bool>(false, false);
- }
-
- LLVM_DEBUG(dbgs() << "join MBB: " << MBB.getNumber() << "\n");
- bool Changed = false;
-
- // Find any live-ins computed in a prior iteration.
- auto ILSIt = VLOCInLocs.find(&MBB);
- assert(ILSIt != VLOCInLocs.end());
- auto &ILS = *ILSIt->second;
-
- // Order predecessors by RPOT order, for exploring them in that order.
- SmallVector<MachineBasicBlock *, 8> BlockOrders;
- for (auto p : MBB.predecessors())
- BlockOrders.push_back(p);
-
- auto Cmp = [&](MachineBasicBlock *A, MachineBasicBlock *B) {
- return BBToOrder[A] < BBToOrder[B];
- };
-
- llvm::sort(BlockOrders, Cmp);
-
- unsigned CurBlockRPONum = BBToOrder[&MBB];
-
- // Force a re-visit to loop heads in the first dataflow iteration.
- // FIXME: if we could "propose" Const values this wouldn't be needed,
- // because they'd need to be confirmed before being emitted.
- if (!BlockOrders.empty() &&
- BBToOrder[BlockOrders[BlockOrders.size() - 1]] >= CurBlockRPONum &&
- VLOCVisited)
- DowngradeOccurred = true;
-
- auto ConfirmValue = [&InLocsT](const DebugVariable &DV, DbgValue VR) {
- auto Result = InLocsT.insert(std::make_pair(DV, VR));
- (void)Result;
- assert(Result.second);
- };
-
- auto ConfirmNoVal = [&ConfirmValue, &MBB](const DebugVariable &Var, const DbgValueProperties &Properties) {
- DbgValue NoLocPHIVal(MBB.getNumber(), Properties, DbgValue::NoVal);
-
- ConfirmValue(Var, NoLocPHIVal);
- };
-
- // Attempt to join the values for each variable.
- for (auto &Var : AllVars) {
- // Collect all the DbgValues for this variable.
- SmallVector<InValueT, 8> Values;
- bool Bail = false;
- unsigned BackEdgesStart = 0;
- for (auto p : BlockOrders) {
- // If the predecessor isn't in scope / to be explored, we'll never be
- // able to join any locations.
- if (!BlocksToExplore.contains(p)) {
- Bail = true;
- break;
- }
-
- // Don't attempt to handle unvisited predecessors: they're implicitly
- // "unknown"s in the lattice.
- if (VLOCVisited && !VLOCVisited->count(p))
- continue;
-
- // If the predecessors OutLocs is absent, there's not much we can do.
- auto OL = VLOCOutLocs.find(p);
- if (OL == VLOCOutLocs.end()) {
- Bail = true;
- break;
- }
-
- // No live-out value for this predecessor also means we can't produce
- // a joined value.
- auto VIt = OL->second->find(Var);
- if (VIt == OL->second->end()) {
- Bail = true;
- break;
- }
-
- // Keep track of where back-edges begin in the Values vector. Relies on
- // BlockOrders being sorted by RPO.
- unsigned ThisBBRPONum = BBToOrder[p];
- if (ThisBBRPONum < CurBlockRPONum)
- ++BackEdgesStart;
-
- Values.push_back(std::make_pair(p, &VIt->second));
- }
-
- // If there were no values, or one of the predecessors couldn't have a
- // value, then give up immediately. It's not safe to produce a live-in
- // value.
- if (Bail || Values.size() == 0)
- continue;
-
- // Enumeration identifying the current state of the predecessors values.
- enum {
- Unset = 0,
- Agreed, // All preds agree on the variable value.
- PropDisagree, // All preds agree, but the value kind is Proposed in some.
- BEDisagree, // Only back-edges disagree on variable value.
- PHINeeded, // Non-back-edge predecessors have conflicing values.
- NoSolution // Conflicting Value metadata makes solution impossible.
- } OurState = Unset;
-
- // All (non-entry) blocks have at least one non-backedge predecessor.
- // Pick the variable value from the first of these, to compare against
- // all others.
- const DbgValue &FirstVal = *Values[0].second;
- const ValueIDNum &FirstID = FirstVal.ID;
-
- // Scan for variable values that can't be resolved: if they have different
- // DIExpressions, different indirectness, or are mixed constants /
- // non-constants.
- for (auto &V : Values) {
- if (V.second->Properties != FirstVal.Properties)
- OurState = NoSolution;
- if (V.second->Kind == DbgValue::Const && FirstVal.Kind != DbgValue::Const)
- OurState = NoSolution;
- }
-
- // Flags diagnosing _how_ the values disagree.
- bool NonBackEdgeDisagree = false;
- bool DisagreeOnPHINess = false;
- bool IDDisagree = false;
- bool Disagree = false;
- if (OurState == Unset) {
- for (auto &V : Values) {
- if (*V.second == FirstVal)
- continue; // No disagreement.
-
- Disagree = true;
-
- // Flag whether the value number actually diagrees.
- if (V.second->ID != FirstID)
- IDDisagree = true;
-
- // Distinguish whether disagreement happens in backedges or not.
- // Relies on Values (and BlockOrders) being sorted by RPO.
- unsigned ThisBBRPONum = BBToOrder[V.first];
- if (ThisBBRPONum < CurBlockRPONum)
- NonBackEdgeDisagree = true;
-
- // Is there a difference in whether the value is definite or only
- // proposed?
- if (V.second->Kind != FirstVal.Kind &&
- (V.second->Kind == DbgValue::Proposed ||
- V.second->Kind == DbgValue::Def) &&
- (FirstVal.Kind == DbgValue::Proposed ||
- FirstVal.Kind == DbgValue::Def))
- DisagreeOnPHINess = true;
- }
-
- // Collect those flags together and determine an overall state for
- // what extend the predecessors agree on a live-in value.
- if (!Disagree)
- OurState = Agreed;
- else if (!IDDisagree && DisagreeOnPHINess)
- OurState = PropDisagree;
- else if (!NonBackEdgeDisagree)
- OurState = BEDisagree;
- else
- OurState = PHINeeded;
- }
-
- // An extra indicator: if we only disagree on whether the value is a
- // Def, or proposed, then also flag whether that disagreement happens
- // in backedges only.
- bool PropOnlyInBEs = Disagree && !IDDisagree && DisagreeOnPHINess &&
- !NonBackEdgeDisagree && FirstVal.Kind == DbgValue::Def;
-
- const auto &Properties = FirstVal.Properties;
-
- auto OldLiveInIt = ILS.find(Var);
- const DbgValue *OldLiveInLocation =
- (OldLiveInIt != ILS.end()) ? &OldLiveInIt->second : nullptr;
-
- bool OverRide = false;
- if (OurState == BEDisagree && OldLiveInLocation) {
- // Only backedges disagree: we can consider downgrading. If there was a
- // previous live-in value, use it to work out whether the current
- // incoming value represents a lattice downgrade or not.
- OverRide =
- vlocDowngradeLattice(MBB, *OldLiveInLocation, Values, CurBlockRPONum);
- }
-
- // Use the current state of predecessor agreement and other flags to work
- // out what to do next. Possibilities include:
- // * Accept a value all predecessors agree on, or accept one that
- // represents a step down the exploration lattice,
- // * Use a PHI value number, if one can be found,
- // * Propose a PHI value number, and see if it gets confirmed later,
- // * Emit a 'NoVal' value, indicating we couldn't resolve anything.
- if (OurState == Agreed) {
- // Easiest solution: all predecessors agree on the variable value.
- ConfirmValue(Var, FirstVal);
- } else if (OurState == BEDisagree && OverRide) {
- // Only backedges disagree, and the other predecessors have produced
- // a new live-in value further down the exploration lattice.
- DowngradeOccurred = true;
- ConfirmValue(Var, FirstVal);
- } else if (OurState == PropDisagree) {
- // Predecessors agree on value, but some say it's only a proposed value.
- // Propagate it as proposed: unless it was proposed in this block, in
- // which case we're able to confirm the value.
- if (FirstID.getBlock() == (uint64_t)MBB.getNumber() && FirstID.isPHI()) {
- ConfirmValue(Var, DbgValue(FirstID, Properties, DbgValue::Def));
- } else if (PropOnlyInBEs) {
- // If only backedges disagree, a higher (in RPO) block confirmed this
- // location, and we need to propagate it into this loop.
- ConfirmValue(Var, DbgValue(FirstID, Properties, DbgValue::Def));
- } else {
- // Otherwise; a Def meeting a Proposed is still a Proposed.
- ConfirmValue(Var, DbgValue(FirstID, Properties, DbgValue::Proposed));
- }
- } else if ((OurState == PHINeeded || OurState == BEDisagree)) {
- // Predecessors disagree and can't be downgraded: this can only be
- // solved with a PHI. Use pickVPHILoc to go look for one.
- Optional<ValueIDNum> VPHI;
- bool AllEdgesVPHI = false;
- std::tie(VPHI, AllEdgesVPHI) =
- pickVPHILoc(MBB, Var, VLOCOutLocs, MOutLocs, MInLocs, BlockOrders);
-
- if (VPHI && AllEdgesVPHI) {
- // There's a PHI value that's valid for all predecessors -- we can use
- // it. If any of the non-backedge predecessors have proposed values
- // though, this PHI is also only proposed, until the predecessors are
- // confirmed.
- DbgValue::KindT K = DbgValue::Def;
- for (unsigned int I = 0; I < BackEdgesStart; ++I)
- if (Values[I].second->Kind == DbgValue::Proposed)
- K = DbgValue::Proposed;
-
- ConfirmValue(Var, DbgValue(*VPHI, Properties, K));
- } else if (VPHI) {
- // There's a PHI value, but it's only legal for backedges. Leave this
- // as a proposed PHI value: it might come back on the backedges,
- // and allow us to confirm it in the future.
- DbgValue NoBEValue = DbgValue(*VPHI, Properties, DbgValue::Proposed);
- ConfirmValue(Var, NoBEValue);
- } else {
- ConfirmNoVal(Var, Properties);
- }
- } else {
- // Otherwise: we don't know. Emit a "phi but no real loc" phi.
- ConfirmNoVal(Var, Properties);
- }
- }
-
- // Store newly calculated in-locs into VLOCInLocs, if they've changed.
- Changed = ILS != InLocsT;
- if (Changed)
- ILS = InLocsT;
-
- return std::tuple<bool, bool>(Changed, DowngradeOccurred);
-}
-
-void InstrRefBasedLDV::vlocDataflow(
- const LexicalScope *Scope, const DILocation *DILoc,
- const SmallSet<DebugVariable, 4> &VarsWeCareAbout,
- SmallPtrSetImpl<MachineBasicBlock *> &AssignBlocks, LiveInsT &Output,
- ValueIDNum **MOutLocs, ValueIDNum **MInLocs,
- SmallVectorImpl<VLocTracker> &AllTheVLocs) {
- // This method is much like mlocDataflow: but focuses on a single
- // LexicalScope at a time. Pick out a set of blocks and variables that are
- // to have their value assignments solved, then run our dataflow algorithm
- // until a fixedpoint is reached.
- std::priority_queue<unsigned int, std::vector<unsigned int>,
- std::greater<unsigned int>>
- Worklist, Pending;
- SmallPtrSet<MachineBasicBlock *, 16> OnWorklist, OnPending;
-
- // The set of blocks we'll be examining.
- SmallPtrSet<const MachineBasicBlock *, 8> BlocksToExplore;
-
- // The order in which to examine them (RPO).
- SmallVector<MachineBasicBlock *, 8> BlockOrders;
-
- // RPO ordering function.
- auto Cmp = [&](MachineBasicBlock *A, MachineBasicBlock *B) {
- return BBToOrder[A] < BBToOrder[B];
- };
-
- LS.getMachineBasicBlocks(DILoc, BlocksToExplore);
-
- // A separate container to distinguish "blocks we're exploring" versus
- // "blocks that are potentially in scope. See comment at start of vlocJoin.
- SmallPtrSet<const MachineBasicBlock *, 8> InScopeBlocks = BlocksToExplore;
-
- // Old LiveDebugValues tracks variable locations that come out of blocks
- // not in scope, where DBG_VALUEs occur. This is something we could
- // legitimately ignore, but lets allow it for now.
- if (EmulateOldLDV)
- BlocksToExplore.insert(AssignBlocks.begin(), AssignBlocks.end());
-
- // We also need to propagate variable values through any artificial blocks
- // that immediately follow blocks in scope.
- DenseSet<const MachineBasicBlock *> ToAdd;
-
- // Helper lambda: For a given block in scope, perform a depth first search
- // of all the artificial successors, adding them to the ToAdd collection.
- auto AccumulateArtificialBlocks =
- [this, &ToAdd, &BlocksToExplore,
- &InScopeBlocks](const MachineBasicBlock *MBB) {
- // Depth-first-search state: each node is a block and which successor
- // we're currently exploring.
- SmallVector<std::pair<const MachineBasicBlock *,
- MachineBasicBlock::const_succ_iterator>,
- 8>
- DFS;
-
- // Find any artificial successors not already tracked.
- for (auto *succ : MBB->successors()) {
- if (BlocksToExplore.count(succ) || InScopeBlocks.count(succ))
- continue;
- if (!ArtificialBlocks.count(succ))
- continue;
- DFS.push_back(std::make_pair(succ, succ->succ_begin()));
- ToAdd.insert(succ);
- }
-
- // Search all those blocks, depth first.
- while (!DFS.empty()) {
- const MachineBasicBlock *CurBB = DFS.back().first;
- MachineBasicBlock::const_succ_iterator &CurSucc = DFS.back().second;
- // Walk back if we've explored this blocks successors to the end.
- if (CurSucc == CurBB->succ_end()) {
- DFS.pop_back();
- continue;
- }
-
- // If the current successor is artificial and unexplored, descend into
- // it.
- if (!ToAdd.count(*CurSucc) && ArtificialBlocks.count(*CurSucc)) {
- DFS.push_back(std::make_pair(*CurSucc, (*CurSucc)->succ_begin()));
- ToAdd.insert(*CurSucc);
- continue;
- }
-
- ++CurSucc;
- }
- };
-
- // Search in-scope blocks and those containing a DBG_VALUE from this scope
- // for artificial successors.
- for (auto *MBB : BlocksToExplore)
- AccumulateArtificialBlocks(MBB);
- for (auto *MBB : InScopeBlocks)
- AccumulateArtificialBlocks(MBB);
-
- BlocksToExplore.insert(ToAdd.begin(), ToAdd.end());
- InScopeBlocks.insert(ToAdd.begin(), ToAdd.end());
-
- // Single block scope: not interesting! No propagation at all. Note that
- // this could probably go above ArtificialBlocks without damage, but
- // that then produces output differences from original-live-debug-values,
- // which propagates from a single block into many artificial ones.
- if (BlocksToExplore.size() == 1)
- return;
-
- // Picks out relevants blocks RPO order and sort them.
- for (auto *MBB : BlocksToExplore)
- BlockOrders.push_back(const_cast<MachineBasicBlock *>(MBB));
-
- llvm::sort(BlockOrders, Cmp);
- unsigned NumBlocks = BlockOrders.size();
-
- // Allocate some vectors for storing the live ins and live outs. Large.
- SmallVector<DenseMap<DebugVariable, DbgValue>, 32> LiveIns, LiveOuts;
- LiveIns.resize(NumBlocks);
- LiveOuts.resize(NumBlocks);
-
- // Produce by-MBB indexes of live-in/live-outs, to ease lookup within
- // vlocJoin.
- LiveIdxT LiveOutIdx, LiveInIdx;
- LiveOutIdx.reserve(NumBlocks);
- LiveInIdx.reserve(NumBlocks);
- for (unsigned I = 0; I < NumBlocks; ++I) {
- LiveOutIdx[BlockOrders[I]] = &LiveOuts[I];
- LiveInIdx[BlockOrders[I]] = &LiveIns[I];
- }
-
- for (auto *MBB : BlockOrders) {
- Worklist.push(BBToOrder[MBB]);
- OnWorklist.insert(MBB);
- }
-
- // Iterate over all the blocks we selected, propagating variable values.
- bool FirstTrip = true;
- SmallPtrSet<const MachineBasicBlock *, 16> VLOCVisited;
- while (!Worklist.empty() || !Pending.empty()) {
- while (!Worklist.empty()) {
- auto *MBB = OrderToBB[Worklist.top()];
- CurBB = MBB->getNumber();
- Worklist.pop();
-
- DenseMap<DebugVariable, DbgValue> JoinedInLocs;
-
- // Join values from predecessors. Updates LiveInIdx, and writes output
- // into JoinedInLocs.
- bool InLocsChanged, DowngradeOccurred;
- std::tie(InLocsChanged, DowngradeOccurred) = vlocJoin(
- *MBB, LiveOutIdx, LiveInIdx, (FirstTrip) ? &VLOCVisited : nullptr,
- CurBB, VarsWeCareAbout, MOutLocs, MInLocs, InScopeBlocks,
- BlocksToExplore, JoinedInLocs);
-
- bool FirstVisit = VLOCVisited.insert(MBB).second;
-
- // Always explore transfer function if inlocs changed, or if we've not
- // visited this block before.
- InLocsChanged |= FirstVisit;
-
- // If a downgrade occurred, book us in for re-examination on the next
- // iteration.
- if (DowngradeOccurred && OnPending.insert(MBB).second)
- Pending.push(BBToOrder[MBB]);
-
- if (!InLocsChanged)
- continue;
-
- // Do transfer function.
- auto &VTracker = AllTheVLocs[MBB->getNumber()];
- for (auto &Transfer : VTracker.Vars) {
- // Is this var we're mangling in this scope?
- if (VarsWeCareAbout.count(Transfer.first)) {
- // Erase on empty transfer (DBG_VALUE $noreg).
- if (Transfer.second.Kind == DbgValue::Undef) {
- JoinedInLocs.erase(Transfer.first);
- } else {
- // Insert new variable value; or overwrite.
- auto NewValuePair = std::make_pair(Transfer.first, Transfer.second);
- auto Result = JoinedInLocs.insert(NewValuePair);
- if (!Result.second)
- Result.first->second = Transfer.second;
- }
- }
- }
-
- // Did the live-out locations change?
- bool OLChanged = JoinedInLocs != *LiveOutIdx[MBB];
-
- // If they haven't changed, there's no need to explore further.
- if (!OLChanged)
- continue;
-
- // Commit to the live-out record.
- *LiveOutIdx[MBB] = JoinedInLocs;
-
- // We should visit all successors. Ensure we'll visit any non-backedge
- // successors during this dataflow iteration; book backedge successors
- // to be visited next time around.
- for (auto s : MBB->successors()) {
- // Ignore out of scope / not-to-be-explored successors.
- if (LiveInIdx.find(s) == LiveInIdx.end())
- continue;
-
- if (BBToOrder[s] > BBToOrder[MBB]) {
- if (OnWorklist.insert(s).second)
- Worklist.push(BBToOrder[s]);
- } else if (OnPending.insert(s).second && (FirstTrip || OLChanged)) {
- Pending.push(BBToOrder[s]);
- }
- }
- }
- Worklist.swap(Pending);
- std::swap(OnWorklist, OnPending);
- OnPending.clear();
- assert(Pending.empty());
- FirstTrip = false;
- }
-
- // Dataflow done. Now what? Save live-ins. Ignore any that are still marked
- // as being variable-PHIs, because those did not have their machine-PHI
- // value confirmed. Such variable values are places that could have been
- // PHIs, but are not.
- for (auto *MBB : BlockOrders) {
- auto &VarMap = *LiveInIdx[MBB];
- for (auto &P : VarMap) {
- if (P.second.Kind == DbgValue::Proposed ||
- P.second.Kind == DbgValue::NoVal)
- continue;
- Output[MBB->getNumber()].push_back(P);
- }
- }
-
- BlockOrders.clear();
- BlocksToExplore.clear();
-}
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-void InstrRefBasedLDV::dump_mloc_transfer(
- const MLocTransferMap &mloc_transfer) const {
- for (auto &P : mloc_transfer) {
- std::string foo = MTracker->LocIdxToName(P.first);
- std::string bar = MTracker->IDAsString(P.second);
- dbgs() << "Loc " << foo << " --> " << bar << "\n";
- }
-}
-#endif
-
-void InstrRefBasedLDV::emitLocations(
- MachineFunction &MF, LiveInsT SavedLiveIns, ValueIDNum **MInLocs,
- DenseMap<DebugVariable, unsigned> &AllVarsNumbering) {
- TTracker = new TransferTracker(TII, MTracker, MF, *TRI, CalleeSavedRegs);
- unsigned NumLocs = MTracker->getNumLocs();
-
- // For each block, load in the machine value locations and variable value
- // live-ins, then step through each instruction in the block. New DBG_VALUEs
- // to be inserted will be created along the way.
- for (MachineBasicBlock &MBB : MF) {
- unsigned bbnum = MBB.getNumber();
- MTracker->reset();
- MTracker->loadFromArray(MInLocs[bbnum], bbnum);
- TTracker->loadInlocs(MBB, MInLocs[bbnum], SavedLiveIns[MBB.getNumber()],
- NumLocs);
-
- CurBB = bbnum;
- CurInst = 1;
- for (auto &MI : MBB) {
- process(MI);
- TTracker->checkInstForNewValues(CurInst, MI.getIterator());
- ++CurInst;
- }
- }
-
- // We have to insert DBG_VALUEs in a consistent order, otherwise they appeaer
- // in DWARF in different orders. Use the order that they appear when walking
- // through each block / each instruction, stored in AllVarsNumbering.
- auto OrderDbgValues = [&](const MachineInstr *A,
- const MachineInstr *B) -> bool {
- DebugVariable VarA(A->getDebugVariable(), A->getDebugExpression(),
- A->getDebugLoc()->getInlinedAt());
- DebugVariable VarB(B->getDebugVariable(), B->getDebugExpression(),
- B->getDebugLoc()->getInlinedAt());
- return AllVarsNumbering.find(VarA)->second <
- AllVarsNumbering.find(VarB)->second;
- };
-
- // Go through all the transfers recorded in the TransferTracker -- this is
- // both the live-ins to a block, and any movements of values that happen
- // in the middle.
- for (auto &P : TTracker->Transfers) {
- // Sort them according to appearance order.
- llvm::sort(P.Insts, OrderDbgValues);
- // Insert either before or after the designated point...
- if (P.MBB) {
- MachineBasicBlock &MBB = *P.MBB;
- for (auto *MI : P.Insts) {
- MBB.insert(P.Pos, MI);
- }
- } else {
- MachineBasicBlock &MBB = *P.Pos->getParent();
- for (auto *MI : P.Insts) {
- MBB.insertAfter(P.Pos, MI);
- }
- }
- }
-}
-
-void InstrRefBasedLDV::initialSetup(MachineFunction &MF) {
- // Build some useful data structures.
- auto hasNonArtificialLocation = [](const MachineInstr &MI) -> bool {
- if (const DebugLoc &DL = MI.getDebugLoc())
- return DL.getLine() != 0;
- return false;
- };
- // Collect a set of all the artificial blocks.
- for (auto &MBB : MF)
- if (none_of(MBB.instrs(), hasNonArtificialLocation))
- ArtificialBlocks.insert(&MBB);
-
- // Compute mappings of block <=> RPO order.
- ReversePostOrderTraversal<MachineFunction *> RPOT(&MF);
- unsigned int RPONumber = 0;
- for (auto RI = RPOT.begin(), RE = RPOT.end(); RI != RE; ++RI) {
- OrderToBB[RPONumber] = *RI;
- BBToOrder[*RI] = RPONumber;
- BBNumToRPO[(*RI)->getNumber()] = RPONumber;
- ++RPONumber;
- }
-}
-
-/// Calculate the liveness information for the given machine function and
-/// extend ranges across basic blocks.
-bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF,
- TargetPassConfig *TPC) {
- // No subprogram means this function contains no debuginfo.
- if (!MF.getFunction().getSubprogram())
- return false;
-
- LLVM_DEBUG(dbgs() << "\nDebug Range Extension\n");
- this->TPC = TPC;
-
- TRI = MF.getSubtarget().getRegisterInfo();
- TII = MF.getSubtarget().getInstrInfo();
- TFI = MF.getSubtarget().getFrameLowering();
- TFI->getCalleeSaves(MF, CalleeSavedRegs);
- LS.initialize(MF);
-
- MTracker =
- new MLocTracker(MF, *TII, *TRI, *MF.getSubtarget().getTargetLowering());
- VTracker = nullptr;
- TTracker = nullptr;
-
- SmallVector<MLocTransferMap, 32> MLocTransfer;
- SmallVector<VLocTracker, 8> vlocs;
- LiveInsT SavedLiveIns;
-
- int MaxNumBlocks = -1;
- for (auto &MBB : MF)
- MaxNumBlocks = std::max(MBB.getNumber(), MaxNumBlocks);
- assert(MaxNumBlocks >= 0);
- ++MaxNumBlocks;
-
- MLocTransfer.resize(MaxNumBlocks);
- vlocs.resize(MaxNumBlocks);
- SavedLiveIns.resize(MaxNumBlocks);
-
- initialSetup(MF);
-
- produceMLocTransferFunction(MF, MLocTransfer, MaxNumBlocks);
-
- // Allocate and initialize two array-of-arrays for the live-in and live-out
- // machine values. The outer dimension is the block number; while the inner
- // dimension is a LocIdx from MLocTracker.
- ValueIDNum **MOutLocs = new ValueIDNum *[MaxNumBlocks];
- ValueIDNum **MInLocs = new ValueIDNum *[MaxNumBlocks];
- unsigned NumLocs = MTracker->getNumLocs();
- for (int i = 0; i < MaxNumBlocks; ++i) {
- MOutLocs[i] = new ValueIDNum[NumLocs];
- MInLocs[i] = new ValueIDNum[NumLocs];
- }
-
- // Solve the machine value dataflow problem using the MLocTransfer function,
- // storing the computed live-ins / live-outs into the array-of-arrays. We use
- // both live-ins and live-outs for decision making in the variable value
- // dataflow problem.
- mlocDataflow(MInLocs, MOutLocs, MLocTransfer);
-
- // Walk back through each block / instruction, collecting DBG_VALUE
- // instructions and recording what machine value their operands refer to.
- for (auto &OrderPair : OrderToBB) {
- MachineBasicBlock &MBB = *OrderPair.second;
- CurBB = MBB.getNumber();
- VTracker = &vlocs[CurBB];
- VTracker->MBB = &MBB;
- MTracker->loadFromArray(MInLocs[CurBB], CurBB);
- CurInst = 1;
- for (auto &MI : MBB) {
- process(MI);
- ++CurInst;
- }
- MTracker->reset();
- }
-
- // Number all variables in the order that they appear, to be used as a stable
- // insertion order later.
- DenseMap<DebugVariable, unsigned> AllVarsNumbering;
-
- // Map from one LexicalScope to all the variables in that scope.
- DenseMap<const LexicalScope *, SmallSet<DebugVariable, 4>> ScopeToVars;
-
- // Map from One lexical scope to all blocks in that scope.
- DenseMap<const LexicalScope *, SmallPtrSet<MachineBasicBlock *, 4>>
- ScopeToBlocks;
-
- // Store a DILocation that describes a scope.
- DenseMap<const LexicalScope *, const DILocation *> ScopeToDILocation;
-
- // To mirror old LiveDebugValues, enumerate variables in RPOT order. Otherwise
- // the order is unimportant, it just has to be stable.
- for (unsigned int I = 0; I < OrderToBB.size(); ++I) {
- auto *MBB = OrderToBB[I];
- auto *VTracker = &vlocs[MBB->getNumber()];
- // Collect each variable with a DBG_VALUE in this block.
- for (auto &idx : VTracker->Vars) {
- const auto &Var = idx.first;
- const DILocation *ScopeLoc = VTracker->Scopes[Var];
- assert(ScopeLoc != nullptr);
- auto *Scope = LS.findLexicalScope(ScopeLoc);
-
- // No insts in scope -> shouldn't have been recorded.
- assert(Scope != nullptr);
-
- AllVarsNumbering.insert(std::make_pair(Var, AllVarsNumbering.size()));
- ScopeToVars[Scope].insert(Var);
- ScopeToBlocks[Scope].insert(VTracker->MBB);
- ScopeToDILocation[Scope] = ScopeLoc;
- }
- }
-
- // OK. Iterate over scopes: there might be something to be said for
- // ordering them by size/locality, but that's for the future. For each scope,
- // solve the variable value problem, producing a map of variables to values
- // in SavedLiveIns.
- for (auto &P : ScopeToVars) {
- vlocDataflow(P.first, ScopeToDILocation[P.first], P.second,
- ScopeToBlocks[P.first], SavedLiveIns, MOutLocs, MInLocs,
- vlocs);
- }
-
- // Using the computed value locations and variable values for each block,
- // create the DBG_VALUE instructions representing the extended variable
- // locations.
- emitLocations(MF, SavedLiveIns, MInLocs, AllVarsNumbering);
-
- for (int Idx = 0; Idx < MaxNumBlocks; ++Idx) {
- delete[] MOutLocs[Idx];
- delete[] MInLocs[Idx];
- }
- delete[] MOutLocs;
- delete[] MInLocs;
-
- // Did we actually make any changes? If we created any DBG_VALUEs, then yes.
- bool Changed = TTracker->Transfers.size() != 0;
-
- delete MTracker;
- delete TTracker;
- MTracker = nullptr;
- VTracker = nullptr;
- TTracker = nullptr;
-
- ArtificialBlocks.clear();
- OrderToBB.clear();
- BBToOrder.clear();
- BBNumToRPO.clear();
- DebugInstrNumToInstr.clear();
-
- return Changed;
-}
-
-LDVImpl *llvm::makeInstrRefBasedLiveDebugValues() {
- return new InstrRefBasedLDV();
-}
+//===- InstrRefBasedImpl.cpp - Tracking Debug Value MIs -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file InstrRefBasedImpl.cpp
+///
+/// This is a separate implementation of LiveDebugValues, see
+/// LiveDebugValues.cpp and VarLocBasedImpl.cpp for more information.
+///
+/// This pass propagates variable locations between basic blocks, resolving
+/// control flow conflicts between them. The problem is much like SSA
+/// construction, where each DBG_VALUE instruction assigns the *value* that
+/// a variable has, and every instruction where the variable is in scope uses
+/// that variable. The resulting map of instruction-to-value is then translated
+/// into a register (or spill) location for each variable over each instruction.
+///
+/// This pass determines which DBG_VALUE dominates which instructions, or if
+/// none do, where values must be merged (like PHI nodes). The added
+/// complication is that because codegen has already finished, a PHI node may
+/// be needed for a variable location to be correct, but no register or spill
+/// slot merges the necessary values. In these circumstances, the variable
+/// location is dropped.
+///
+/// What makes this analysis non-trivial is loops: we cannot tell in advance
+/// whether a variable location is live throughout a loop, or whether its
+/// location is clobbered (or redefined by another DBG_VALUE), without
+/// exploring all the way through.
+///
+/// To make this simpler we perform two kinds of analysis. First, we identify
+/// every value defined by every instruction (ignoring those that only move
+/// another value), then compute a map of which values are available for each
+/// instruction. This is stronger than a reaching-def analysis, as we create
+/// PHI values where other values merge.
+///
+/// Secondly, for each variable, we effectively re-construct SSA using each
+/// DBG_VALUE as a def. The DBG_VALUEs read a value-number computed by the
+/// first analysis from the location they refer to. We can then compute the
+/// dominance frontiers of where a variable has a value, and create PHI nodes
+/// where they merge.
+/// This isn't precisely SSA-construction though, because the function shape
+/// is pre-defined. If a variable location requires a PHI node, but no
+/// PHI for the relevant values is present in the function (as computed by the
+/// first analysis), the location must be dropped.
+///
+/// Once both are complete, we can pass back over all instructions knowing:
+/// * What _value_ each variable should contain, either defined by an
+/// instruction or where control flow merges
+/// * What the location of that value is (if any).
+/// Allowing us to create appropriate live-in DBG_VALUEs, and DBG_VALUEs when
+/// a value moves location. After this pass runs, all variable locations within
+/// a block should be specified by DBG_VALUEs within that block, allowing
+/// DbgEntityHistoryCalculator to focus on individual blocks.
+///
+/// This pass is able to go fast because the size of the first
+/// reaching-definition analysis is proportional to the working-set size of
+/// the function, which the compiler tries to keep small. (It's also
+/// proportional to the number of blocks). Additionally, we repeatedly perform
+/// the second reaching-definition analysis with only the variables and blocks
+/// in a single lexical scope, exploiting their locality.
+///
+/// Determining where PHIs happen is trickier with this approach, and it comes
+/// to a head in the major problem for LiveDebugValues: is a value live-through
+/// a loop, or not? Your garden-variety dataflow analysis aims to build a set of
+/// facts about a function, however this analysis needs to generate new value
+/// numbers at joins.
+///
+/// To do this, consider a lattice of all definition values, from instructions
+/// and from PHIs. Each PHI is characterised by the RPO number of the block it
+/// occurs in. Each value pair A, B can be ordered by RPO(A) < RPO(B):
+/// with non-PHI values at the top, and any PHI value in the last block (by RPO
+/// order) at the bottom.
+///
+/// (Awkwardly: lower-down-the _lattice_ means a greater RPO _number_. Below,
+/// "rank" always refers to the former).
+///
+/// At any join, for each register, we consider:
+/// * All incoming values, and
+/// * The PREVIOUS live-in value at this join.
+/// If all incoming values agree: that's the live-in value. If they do not, the
+/// incoming values are ranked according to the partial order, and the NEXT
+/// LOWEST rank after the PREVIOUS live-in value is picked (multiple values of
+/// the same rank are ignored as conflicting). If there are no candidate values,
+/// or if the rank of the live-in would be lower than the rank of the current
+/// blocks PHIs, create a new PHI value.
+///
+/// Intuitively: if it's not immediately obvious what value a join should result
+/// in, we iteratively descend from instruction-definitions down through PHI
+/// values, getting closer to the current block each time. If the current block
+/// is a loop head, this ordering is effectively searching outer levels of
+/// loops, to find a value that's live-through the current loop.
+///
+/// If there is no value that's live-through this loop, a PHI is created for
+/// this location instead. We can't use a lower-ranked PHI because by definition
+/// it doesn't dominate the current block. We can't create a PHI value any
+/// earlier, because we risk creating a PHI value at a location where values do
+/// not in fact merge, thus misrepresenting the truth, and not making the true
+/// live-through value for variable locations.
+///
+/// This algorithm applies to both calculating the availability of values in
+/// the first analysis, and the location of variables in the second. However
+/// for the second we add an extra dimension of pain: creating a variable
+/// location PHI is only valid if, for each incoming edge,
+/// * There is a value for the variable on the incoming edge, and
+/// * All the edges have that value in the same register.
+/// Or put another way: we can only create a variable-location PHI if there is
+/// a matching machine-location PHI, each input to which is the variables value
+/// in the predecessor block.
+///
+/// To accommodate this difference, each point on the lattice is split in
+/// two: a "proposed" PHI and "definite" PHI. Any PHI that can immediately
+/// have a location determined are "definite" PHIs, and no further work is
+/// needed. Otherwise, a location that all non-backedge predecessors agree
+/// on is picked and propagated as a "proposed" PHI value. If that PHI value
+/// is truly live-through, it'll appear on the loop backedges on the next
+/// dataflow iteration, after which the block live-in moves to be a "definite"
+/// PHI. If it's not truly live-through, the variable value will be downgraded
+/// further as we explore the lattice, or remains "proposed" and is considered
+/// invalid once dataflow completes.
+///
+/// ### Terminology
+///
+/// A machine location is a register or spill slot, a value is something that's
+/// defined by an instruction or PHI node, while a variable value is the value
+/// assigned to a variable. A variable location is a machine location, that must
+/// contain the appropriate variable value. A value that is a PHI node is
+/// occasionally called an mphi.
+///
+/// The first dataflow problem is the "machine value location" problem,
+/// because we're determining which machine locations contain which values.
+/// The "locations" are constant: what's unknown is what value they contain.
+///
+/// The second dataflow problem (the one for variables) is the "variable value
+/// problem", because it's determining what values a variable has, rather than
+/// what location those values are placed in. Unfortunately, it's not that
+/// simple, because producing a PHI value always involves picking a location.
+/// This is an imperfection that we just have to accept, at least for now.
+///
+/// TODO:
+/// Overlapping fragments
+/// Entry values
+/// Add back DEBUG statements for debugging this
+/// Collect statistics
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/UniqueVector.h"
+#include "llvm/CodeGen/LexicalScopes.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/CodeGen/RegisterScavenging.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/Config/llvm-config.h"
+#include "llvm/IR/DIBuilder.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/TypeSize.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <functional>
+#include <queue>
+#include <tuple>
+#include <utility>
+#include <vector>
+#include <limits.h>
+#include <limits>
+
+#include "LiveDebugValues.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "livedebugvalues"
+
+STATISTIC(NumInserted, "Number of DBG_VALUE instructions inserted");
+STATISTIC(NumRemoved, "Number of DBG_VALUE instructions removed");
+
+// Act more like the VarLoc implementation, by propagating some locations too
+// far and ignoring some transfers.
+static cl::opt<bool> EmulateOldLDV("emulate-old-livedebugvalues", cl::Hidden,
+ cl::desc("Act like old LiveDebugValues did"),
+ cl::init(false));
+
+// Rely on isStoreToStackSlotPostFE and similar to observe all stack spills.
+static cl::opt<bool>
+ ObserveAllStackops("observe-all-stack-ops", cl::Hidden,
+ cl::desc("Allow non-kill spill and restores"),
+ cl::init(false));
+
+namespace {
+
+// The location at which a spilled value resides. It consists of a register and
+// an offset.
+struct SpillLoc {
+ unsigned SpillBase;
+ StackOffset SpillOffset;
+ bool operator==(const SpillLoc &Other) const {
+ return std::make_pair(SpillBase, SpillOffset) ==
+ std::make_pair(Other.SpillBase, Other.SpillOffset);
+ }
+ bool operator<(const SpillLoc &Other) const {
+ return std::make_tuple(SpillBase, SpillOffset.getFixed(),
+ SpillOffset.getScalable()) <
+ std::make_tuple(Other.SpillBase, Other.SpillOffset.getFixed(),
+ Other.SpillOffset.getScalable());
+ }
+};
+
+class LocIdx {
+ unsigned Location;
+
+ // Default constructor is private, initializing to an illegal location number.
+ // Use only for "not an entry" elements in IndexedMaps.
+ LocIdx() : Location(UINT_MAX) { }
+
+public:
+ #define NUM_LOC_BITS 24
+ LocIdx(unsigned L) : Location(L) {
+ assert(L < (1 << NUM_LOC_BITS) && "Machine locations must fit in 24 bits");
+ }
+
+ static LocIdx MakeIllegalLoc() {
+ return LocIdx();
+ }
+
+ bool isIllegal() const {
+ return Location == UINT_MAX;
+ }
+
+ uint64_t asU64() const {
+ return Location;
+ }
+
+ bool operator==(unsigned L) const {
+ return Location == L;
+ }
+
+ bool operator==(const LocIdx &L) const {
+ return Location == L.Location;
+ }
+
+ bool operator!=(unsigned L) const {
+ return !(*this == L);
+ }
+
+ bool operator!=(const LocIdx &L) const {
+ return !(*this == L);
+ }
+
+ bool operator<(const LocIdx &Other) const {
+ return Location < Other.Location;
+ }
+};
+
+class LocIdxToIndexFunctor {
+public:
+ using argument_type = LocIdx;
+ unsigned operator()(const LocIdx &L) const {
+ return L.asU64();
+ }
+};
+
+/// Unique identifier for a value defined by an instruction, as a value type.
+/// Casts back and forth to a uint64_t. Probably replacable with something less
+/// bit-constrained. Each value identifies the instruction and machine location
+/// where the value is defined, although there may be no corresponding machine
+/// operand for it (ex: regmasks clobbering values). The instructions are
+/// one-based, and definitions that are PHIs have instruction number zero.
+///
+/// The obvious limits of a 1M block function or 1M instruction blocks are
+/// problematic; but by that point we should probably have bailed out of
+/// trying to analyse the function.
+class ValueIDNum {
+ uint64_t BlockNo : 20; /// The block where the def happens.
+ uint64_t InstNo : 20; /// The Instruction where the def happens.
+ /// One based, is distance from start of block.
+ uint64_t LocNo : NUM_LOC_BITS; /// The machine location where the def happens.
+
+public:
+ // XXX -- temporarily enabled while the live-in / live-out tables are moved
+ // to something more type-y
+ ValueIDNum() : BlockNo(0xFFFFF),
+ InstNo(0xFFFFF),
+ LocNo(0xFFFFFF) { }
+
+ ValueIDNum(uint64_t Block, uint64_t Inst, uint64_t Loc)
+ : BlockNo(Block), InstNo(Inst), LocNo(Loc) { }
+
+ ValueIDNum(uint64_t Block, uint64_t Inst, LocIdx Loc)
+ : BlockNo(Block), InstNo(Inst), LocNo(Loc.asU64()) { }
+
+ uint64_t getBlock() const { return BlockNo; }
+ uint64_t getInst() const { return InstNo; }
+ uint64_t getLoc() const { return LocNo; }
+ bool isPHI() const { return InstNo == 0; }
+
+ uint64_t asU64() const {
+ uint64_t TmpBlock = BlockNo;
+ uint64_t TmpInst = InstNo;
+ return TmpBlock << 44ull | TmpInst << NUM_LOC_BITS | LocNo;
+ }
+
+ static ValueIDNum fromU64(uint64_t v) {
+ uint64_t L = (v & 0x3FFF);
+ return {v >> 44ull, ((v >> NUM_LOC_BITS) & 0xFFFFF), L};
+ }
+
+ bool operator<(const ValueIDNum &Other) const {
+ return asU64() < Other.asU64();
+ }
+
+ bool operator==(const ValueIDNum &Other) const {
+ return std::tie(BlockNo, InstNo, LocNo) ==
+ std::tie(Other.BlockNo, Other.InstNo, Other.LocNo);
+ }
+
+ bool operator!=(const ValueIDNum &Other) const { return !(*this == Other); }
+
+ std::string asString(const std::string &mlocname) const {
+ return Twine("Value{bb: ")
+ .concat(Twine(BlockNo).concat(
+ Twine(", inst: ")
+ .concat((InstNo ? Twine(InstNo) : Twine("live-in"))
+ .concat(Twine(", loc: ").concat(Twine(mlocname)))
+ .concat(Twine("}")))))
+ .str();
+ }
+
+ static ValueIDNum EmptyValue;
+};
+
+} // end anonymous namespace
+
+namespace {
+
+/// Meta qualifiers for a value. Pair of whatever expression is used to qualify
+/// the the value, and Boolean of whether or not it's indirect.
+class DbgValueProperties {
+public:
+ DbgValueProperties(const DIExpression *DIExpr, bool Indirect)
+ : DIExpr(DIExpr), Indirect(Indirect) {}
+
+ /// Extract properties from an existing DBG_VALUE instruction.
+ DbgValueProperties(const MachineInstr &MI) {
+ assert(MI.isDebugValue());
+ DIExpr = MI.getDebugExpression();
+ Indirect = MI.getOperand(1).isImm();
+ }
+
+ bool operator==(const DbgValueProperties &Other) const {
+ return std::tie(DIExpr, Indirect) == std::tie(Other.DIExpr, Other.Indirect);
+ }
+
+ bool operator!=(const DbgValueProperties &Other) const {
+ return !(*this == Other);
+ }
+
+ const DIExpression *DIExpr;
+ bool Indirect;
+};
+
+/// Tracker for what values are in machine locations. Listens to the Things
+/// being Done by various instructions, and maintains a table of what machine
+/// locations have what values (as defined by a ValueIDNum).
+///
+/// There are potentially a much larger number of machine locations on the
+/// target machine than the actual working-set size of the function. On x86 for
+/// example, we're extremely unlikely to want to track values through control
+/// or debug registers. To avoid doing so, MLocTracker has several layers of
+/// indirection going on, with two kinds of ``location'':
+/// * A LocID uniquely identifies a register or spill location, with a
+/// predictable value.
+/// * A LocIdx is a key (in the database sense) for a LocID and a ValueIDNum.
+/// Whenever a location is def'd or used by a MachineInstr, we automagically
+/// create a new LocIdx for a location, but not otherwise. This ensures we only
+/// account for locations that are actually used or defined. The cost is another
+/// vector lookup (of LocID -> LocIdx) over any other implementation. This is
+/// fairly cheap, and the compiler tries to reduce the working-set at any one
+/// time in the function anyway.
+///
+/// Register mask operands completely blow this out of the water; I've just
+/// piled hacks on top of hacks to get around that.
+class MLocTracker {
+public:
+ MachineFunction &MF;
+ const TargetInstrInfo &TII;
+ const TargetRegisterInfo &TRI;
+ const TargetLowering &TLI;
+
+ /// IndexedMap type, mapping from LocIdx to ValueIDNum.
+ using LocToValueType = IndexedMap<ValueIDNum, LocIdxToIndexFunctor>;
+
+ /// Map of LocIdxes to the ValueIDNums that they store. This is tightly
+ /// packed, entries only exist for locations that are being tracked.
+ LocToValueType LocIdxToIDNum;
+
+ /// "Map" of machine location IDs (i.e., raw register or spill number) to the
+ /// LocIdx key / number for that location. There are always at least as many
+ /// as the number of registers on the target -- if the value in the register
+ /// is not being tracked, then the LocIdx value will be zero. New entries are
+ /// appended if a new spill slot begins being tracked.
+ /// This, and the corresponding reverse map persist for the analysis of the
+ /// whole function, and is necessarying for decoding various vectors of
+ /// values.
+ std::vector<LocIdx> LocIDToLocIdx;
+
+ /// Inverse map of LocIDToLocIdx.
+ IndexedMap<unsigned, LocIdxToIndexFunctor> LocIdxToLocID;
+
+ /// Unique-ification of spill slots. Used to number them -- their LocID
+ /// number is the index in SpillLocs minus one plus NumRegs.
+ UniqueVector<SpillLoc> SpillLocs;
+
+ // If we discover a new machine location, assign it an mphi with this
+ // block number.
+ unsigned CurBB;
+
+ /// Cached local copy of the number of registers the target has.
+ unsigned NumRegs;
+
+ /// Collection of register mask operands that have been observed. Second part
+ /// of pair indicates the instruction that they happened in. Used to
+ /// reconstruct where defs happened if we start tracking a location later
+ /// on.
+ SmallVector<std::pair<const MachineOperand *, unsigned>, 32> Masks;
+
+ /// Iterator for locations and the values they contain. Dereferencing
+ /// produces a struct/pair containing the LocIdx key for this location,
+ /// and a reference to the value currently stored. Simplifies the process
+ /// of seeking a particular location.
+ class MLocIterator {
+ LocToValueType &ValueMap;
+ LocIdx Idx;
+
+ public:
+ class value_type {
+ public:
+ value_type(LocIdx Idx, ValueIDNum &Value) : Idx(Idx), Value(Value) { }
+ const LocIdx Idx; /// Read-only index of this location.
+ ValueIDNum &Value; /// Reference to the stored value at this location.
+ };
+
+ MLocIterator(LocToValueType &ValueMap, LocIdx Idx)
+ : ValueMap(ValueMap), Idx(Idx) { }
+
+ bool operator==(const MLocIterator &Other) const {
+ assert(&ValueMap == &Other.ValueMap);
+ return Idx == Other.Idx;
+ }
+
+ bool operator!=(const MLocIterator &Other) const {
+ return !(*this == Other);
+ }
+
+ void operator++() {
+ Idx = LocIdx(Idx.asU64() + 1);
+ }
+
+ value_type operator*() {
+ return value_type(Idx, ValueMap[LocIdx(Idx)]);
+ }
+ };
+
+ MLocTracker(MachineFunction &MF, const TargetInstrInfo &TII,
+ const TargetRegisterInfo &TRI, const TargetLowering &TLI)
+ : MF(MF), TII(TII), TRI(TRI), TLI(TLI),
+ LocIdxToIDNum(ValueIDNum::EmptyValue),
+ LocIdxToLocID(0) {
+ NumRegs = TRI.getNumRegs();
+ reset();
+ LocIDToLocIdx.resize(NumRegs, LocIdx::MakeIllegalLoc());
+ assert(NumRegs < (1u << NUM_LOC_BITS)); // Detect bit packing failure
+
+ // Always track SP. This avoids the implicit clobbering caused by regmasks
+ // from affectings its values. (LiveDebugValues disbelieves calls and
+ // regmasks that claim to clobber SP).
+ Register SP = TLI.getStackPointerRegisterToSaveRestore();
+ if (SP) {
+ unsigned ID = getLocID(SP, false);
+ (void)lookupOrTrackRegister(ID);
+ }
+ }
+
+ /// Produce location ID number for indexing LocIDToLocIdx. Takes the register
+ /// or spill number, and flag for whether it's a spill or not.
+ unsigned getLocID(Register RegOrSpill, bool isSpill) {
+ return (isSpill) ? RegOrSpill.id() + NumRegs - 1 : RegOrSpill.id();
+ }
+
+ /// Accessor for reading the value at Idx.
+ ValueIDNum getNumAtPos(LocIdx Idx) const {
+ assert(Idx.asU64() < LocIdxToIDNum.size());
+ return LocIdxToIDNum[Idx];
+ }
+
+ unsigned getNumLocs(void) const { return LocIdxToIDNum.size(); }
+
+ /// Reset all locations to contain a PHI value at the designated block. Used
+ /// sometimes for actual PHI values, othertimes to indicate the block entry
+ /// value (before any more information is known).
+ void setMPhis(unsigned NewCurBB) {
+ CurBB = NewCurBB;
+ for (auto Location : locations())
+ Location.Value = {CurBB, 0, Location.Idx};
+ }
+
+ /// Load values for each location from array of ValueIDNums. Take current
+ /// bbnum just in case we read a value from a hitherto untouched register.
+ void loadFromArray(ValueIDNum *Locs, unsigned NewCurBB) {
+ CurBB = NewCurBB;
+ // Iterate over all tracked locations, and load each locations live-in
+ // value into our local index.
+ for (auto Location : locations())
+ Location.Value = Locs[Location.Idx.asU64()];
+ }
+
+ /// Wipe any un-necessary location records after traversing a block.
+ void reset(void) {
+ // We could reset all the location values too; however either loadFromArray
+ // or setMPhis should be called before this object is re-used. Just
+ // clear Masks, they're definitely not needed.
+ Masks.clear();
+ }
+
+ /// Clear all data. Destroys the LocID <=> LocIdx map, which makes most of
+ /// the information in this pass uninterpretable.
+ void clear(void) {
+ reset();
+ LocIDToLocIdx.clear();
+ LocIdxToLocID.clear();
+ LocIdxToIDNum.clear();
+ //SpillLocs.reset(); XXX UniqueVector::reset assumes a SpillLoc casts from 0
+ SpillLocs = decltype(SpillLocs)();
+
+ LocIDToLocIdx.resize(NumRegs, LocIdx::MakeIllegalLoc());
+ }
+
+ /// Set a locaiton to a certain value.
+ void setMLoc(LocIdx L, ValueIDNum Num) {
+ assert(L.asU64() < LocIdxToIDNum.size());
+ LocIdxToIDNum[L] = Num;
+ }
+
+ /// Create a LocIdx for an untracked register ID. Initialize it to either an
+ /// mphi value representing a live-in, or a recent register mask clobber.
+ LocIdx trackRegister(unsigned ID) {
+ assert(ID != 0);
+ LocIdx NewIdx = LocIdx(LocIdxToIDNum.size());
+ LocIdxToIDNum.grow(NewIdx);
+ LocIdxToLocID.grow(NewIdx);
+
+ // Default: it's an mphi.
+ ValueIDNum ValNum = {CurBB, 0, NewIdx};
+ // Was this reg ever touched by a regmask?
+ for (const auto &MaskPair : reverse(Masks)) {
+ if (MaskPair.first->clobbersPhysReg(ID)) {
+ // There was an earlier def we skipped.
+ ValNum = {CurBB, MaskPair.second, NewIdx};
+ break;
+ }
+ }
+
+ LocIdxToIDNum[NewIdx] = ValNum;
+ LocIdxToLocID[NewIdx] = ID;
+ return NewIdx;
+ }
+
+ LocIdx lookupOrTrackRegister(unsigned ID) {
+ LocIdx &Index = LocIDToLocIdx[ID];
+ if (Index.isIllegal())
+ Index = trackRegister(ID);
+ return Index;
+ }
+
+ /// Record a definition of the specified register at the given block / inst.
+ /// This doesn't take a ValueIDNum, because the definition and its location
+ /// are synonymous.
+ void defReg(Register R, unsigned BB, unsigned Inst) {
+ unsigned ID = getLocID(R, false);
+ LocIdx Idx = lookupOrTrackRegister(ID);
+ ValueIDNum ValueID = {BB, Inst, Idx};
+ LocIdxToIDNum[Idx] = ValueID;
+ }
+
+ /// Set a register to a value number. To be used if the value number is
+ /// known in advance.
+ void setReg(Register R, ValueIDNum ValueID) {
+ unsigned ID = getLocID(R, false);
+ LocIdx Idx = lookupOrTrackRegister(ID);
+ LocIdxToIDNum[Idx] = ValueID;
+ }
+
+ ValueIDNum readReg(Register R) {
+ unsigned ID = getLocID(R, false);
+ LocIdx Idx = lookupOrTrackRegister(ID);
+ return LocIdxToIDNum[Idx];
+ }
+
+ /// Reset a register value to zero / empty. Needed to replicate the
+ /// VarLoc implementation where a copy to/from a register effectively
+ /// clears the contents of the source register. (Values can only have one
+ /// machine location in VarLocBasedImpl).
+ void wipeRegister(Register R) {
+ unsigned ID = getLocID(R, false);
+ LocIdx Idx = LocIDToLocIdx[ID];
+ LocIdxToIDNum[Idx] = ValueIDNum::EmptyValue;
+ }
+
+ /// Determine the LocIdx of an existing register.
+ LocIdx getRegMLoc(Register R) {
+ unsigned ID = getLocID(R, false);
+ return LocIDToLocIdx[ID];
+ }
+
+ /// Record a RegMask operand being executed. Defs any register we currently
+ /// track, stores a pointer to the mask in case we have to account for it
+ /// later.
+ void writeRegMask(const MachineOperand *MO, unsigned CurBB, unsigned InstID) {
+ // Ensure SP exists, so that we don't override it later.
+ Register SP = TLI.getStackPointerRegisterToSaveRestore();
+
+ // Def any register we track have that isn't preserved. The regmask
+ // terminates the liveness of a register, meaning its value can't be
+ // relied upon -- we represent this by giving it a new value.
+ for (auto Location : locations()) {
+ unsigned ID = LocIdxToLocID[Location.Idx];
+ // Don't clobber SP, even if the mask says it's clobbered.
+ if (ID < NumRegs && ID != SP && MO->clobbersPhysReg(ID))
+ defReg(ID, CurBB, InstID);
+ }
+ Masks.push_back(std::make_pair(MO, InstID));
+ }
+
+ /// Find LocIdx for SpillLoc \p L, creating a new one if it's not tracked.
+ LocIdx getOrTrackSpillLoc(SpillLoc L) {
+ unsigned SpillID = SpillLocs.idFor(L);
+ if (SpillID == 0) {
+ SpillID = SpillLocs.insert(L);
+ unsigned L = getLocID(SpillID, true);
+ LocIdx Idx = LocIdx(LocIdxToIDNum.size()); // New idx
+ LocIdxToIDNum.grow(Idx);
+ LocIdxToLocID.grow(Idx);
+ LocIDToLocIdx.push_back(Idx);
+ LocIdxToLocID[Idx] = L;
+ return Idx;
+ } else {
+ unsigned L = getLocID(SpillID, true);
+ LocIdx Idx = LocIDToLocIdx[L];
+ return Idx;
+ }
+ }
+
+ /// Set the value stored in a spill slot.
+ void setSpill(SpillLoc L, ValueIDNum ValueID) {
+ LocIdx Idx = getOrTrackSpillLoc(L);
+ LocIdxToIDNum[Idx] = ValueID;
+ }
+
+ /// Read whatever value is in a spill slot, or None if it isn't tracked.
+ Optional<ValueIDNum> readSpill(SpillLoc L) {
+ unsigned SpillID = SpillLocs.idFor(L);
+ if (SpillID == 0)
+ return None;
+
+ unsigned LocID = getLocID(SpillID, true);
+ LocIdx Idx = LocIDToLocIdx[LocID];
+ return LocIdxToIDNum[Idx];
+ }
+
+ /// Determine the LocIdx of a spill slot. Return None if it previously
+ /// hasn't had a value assigned.
+ Optional<LocIdx> getSpillMLoc(SpillLoc L) {
+ unsigned SpillID = SpillLocs.idFor(L);
+ if (SpillID == 0)
+ return None;
+ unsigned LocNo = getLocID(SpillID, true);
+ return LocIDToLocIdx[LocNo];
+ }
+
+ /// Return true if Idx is a spill machine location.
+ bool isSpill(LocIdx Idx) const {
+ return LocIdxToLocID[Idx] >= NumRegs;
+ }
+
+ MLocIterator begin() {
+ return MLocIterator(LocIdxToIDNum, 0);
+ }
+
+ MLocIterator end() {
+ return MLocIterator(LocIdxToIDNum, LocIdxToIDNum.size());
+ }
+
+ /// Return a range over all locations currently tracked.
+ iterator_range<MLocIterator> locations() {
+ return llvm::make_range(begin(), end());
+ }
+
+ std::string LocIdxToName(LocIdx Idx) const {
+ unsigned ID = LocIdxToLocID[Idx];
+ if (ID >= NumRegs)
+ return Twine("slot ").concat(Twine(ID - NumRegs)).str();
+ else
+ return TRI.getRegAsmName(ID).str();
+ }
+
+ std::string IDAsString(const ValueIDNum &Num) const {
+ std::string DefName = LocIdxToName(Num.getLoc());
+ return Num.asString(DefName);
+ }
+
+ LLVM_DUMP_METHOD
+ void dump() {
+ for (auto Location : locations()) {
+ std::string MLocName = LocIdxToName(Location.Value.getLoc());
+ std::string DefName = Location.Value.asString(MLocName);
+ dbgs() << LocIdxToName(Location.Idx) << " --> " << DefName << "\n";
+ }
+ }
+
+ LLVM_DUMP_METHOD
+ void dump_mloc_map() {
+ for (auto Location : locations()) {
+ std::string foo = LocIdxToName(Location.Idx);
+ dbgs() << "Idx " << Location.Idx.asU64() << " " << foo << "\n";
+ }
+ }
+
+ /// Create a DBG_VALUE based on machine location \p MLoc. Qualify it with the
+ /// information in \pProperties, for variable Var. Don't insert it anywhere,
+ /// just return the builder for it.
+ MachineInstrBuilder emitLoc(Optional<LocIdx> MLoc, const DebugVariable &Var,
+ const DbgValueProperties &Properties) {
+ DebugLoc DL = DILocation::get(Var.getVariable()->getContext(), 0, 0,
+ Var.getVariable()->getScope(),
+ const_cast<DILocation *>(Var.getInlinedAt()));
+ auto MIB = BuildMI(MF, DL, TII.get(TargetOpcode::DBG_VALUE));
+
+ const DIExpression *Expr = Properties.DIExpr;
+ if (!MLoc) {
+ // No location -> DBG_VALUE $noreg
+ MIB.addReg(0, RegState::Debug);
+ MIB.addReg(0, RegState::Debug);
+ } else if (LocIdxToLocID[*MLoc] >= NumRegs) {
+ unsigned LocID = LocIdxToLocID[*MLoc];
+ const SpillLoc &Spill = SpillLocs[LocID - NumRegs + 1];
+
+ auto *TRI = MF.getSubtarget().getRegisterInfo();
+ Expr = TRI->prependOffsetExpression(Expr, DIExpression::ApplyOffset,
+ Spill.SpillOffset);
+ unsigned Base = Spill.SpillBase;
+ MIB.addReg(Base, RegState::Debug);
+ MIB.addImm(0);
+ } else {
+ unsigned LocID = LocIdxToLocID[*MLoc];
+ MIB.addReg(LocID, RegState::Debug);
+ if (Properties.Indirect)
+ MIB.addImm(0);
+ else
+ MIB.addReg(0, RegState::Debug);
+ }
+
+ MIB.addMetadata(Var.getVariable());
+ MIB.addMetadata(Expr);
+ return MIB;
+ }
+};
+
+/// Class recording the (high level) _value_ of a variable. Identifies either
+/// the value of the variable as a ValueIDNum, or a constant MachineOperand.
+/// This class also stores meta-information about how the value is qualified.
+/// Used to reason about variable values when performing the second
+/// (DebugVariable specific) dataflow analysis.
+class DbgValue {
+public:
+ union {
+ /// If Kind is Def, the value number that this value is based on.
+ ValueIDNum ID;
+ /// If Kind is Const, the MachineOperand defining this value.
+ MachineOperand MO;
+ /// For a NoVal DbgValue, which block it was generated in.
+ unsigned BlockNo;
+ };
+ /// Qualifiers for the ValueIDNum above.
+ DbgValueProperties Properties;
+
+ typedef enum {
+ Undef, // Represents a DBG_VALUE $noreg in the transfer function only.
+ Def, // This value is defined by an inst, or is a PHI value.
+ Const, // A constant value contained in the MachineOperand field.
+ Proposed, // This is a tentative PHI value, which may be confirmed or
+ // invalidated later.
+ NoVal // Empty DbgValue, generated during dataflow. BlockNo stores
+ // which block this was generated in.
+ } KindT;
+ /// Discriminator for whether this is a constant or an in-program value.
+ KindT Kind;
+
+ DbgValue(const ValueIDNum &Val, const DbgValueProperties &Prop, KindT Kind)
+ : ID(Val), Properties(Prop), Kind(Kind) {
+ assert(Kind == Def || Kind == Proposed);
+ }
+
+ DbgValue(unsigned BlockNo, const DbgValueProperties &Prop, KindT Kind)
+ : BlockNo(BlockNo), Properties(Prop), Kind(Kind) {
+ assert(Kind == NoVal);
+ }
+
+ DbgValue(const MachineOperand &MO, const DbgValueProperties &Prop, KindT Kind)
+ : MO(MO), Properties(Prop), Kind(Kind) {
+ assert(Kind == Const);
+ }
+
+ DbgValue(const DbgValueProperties &Prop, KindT Kind)
+ : Properties(Prop), Kind(Kind) {
+ assert(Kind == Undef &&
+ "Empty DbgValue constructor must pass in Undef kind");
+ }
+
+ void dump(const MLocTracker *MTrack) const {
+ if (Kind == Const) {
+ MO.dump();
+ } else if (Kind == NoVal) {
+ dbgs() << "NoVal(" << BlockNo << ")";
+ } else if (Kind == Proposed) {
+ dbgs() << "VPHI(" << MTrack->IDAsString(ID) << ")";
+ } else {
+ assert(Kind == Def);
+ dbgs() << MTrack->IDAsString(ID);
+ }
+ if (Properties.Indirect)
+ dbgs() << " indir";
+ if (Properties.DIExpr)
+ dbgs() << " " << *Properties.DIExpr;
+ }
+
+ bool operator==(const DbgValue &Other) const {
+ if (std::tie(Kind, Properties) != std::tie(Other.Kind, Other.Properties))
+ return false;
+ else if (Kind == Proposed && ID != Other.ID)
+ return false;
+ else if (Kind == Def && ID != Other.ID)
+ return false;
+ else if (Kind == NoVal && BlockNo != Other.BlockNo)
+ return false;
+ else if (Kind == Const)
+ return MO.isIdenticalTo(Other.MO);
+
+ return true;
+ }
+
+ bool operator!=(const DbgValue &Other) const { return !(*this == Other); }
+};
+
+/// Types for recording sets of variable fragments that overlap. For a given
+/// local variable, we record all other fragments of that variable that could
+/// overlap it, to reduce search time.
+using FragmentOfVar =
+ std::pair<const DILocalVariable *, DIExpression::FragmentInfo>;
+using OverlapMap =
+ DenseMap<FragmentOfVar, SmallVector<DIExpression::FragmentInfo, 1>>;
+
+/// Collection of DBG_VALUEs observed when traversing a block. Records each
+/// variable and the value the DBG_VALUE refers to. Requires the machine value
+/// location dataflow algorithm to have run already, so that values can be
+/// identified.
+class VLocTracker {
+public:
+ /// Map DebugVariable to the latest Value it's defined to have.
+ /// Needs to be a MapVector because we determine order-in-the-input-MIR from
+ /// the order in this container.
+ /// We only retain the last DbgValue in each block for each variable, to
+ /// determine the blocks live-out variable value. The Vars container forms the
+ /// transfer function for this block, as part of the dataflow analysis. The
+ /// movement of values between locations inside of a block is handled at a
+ /// much later stage, in the TransferTracker class.
+ MapVector<DebugVariable, DbgValue> Vars;
+ DenseMap<DebugVariable, const DILocation *> Scopes;
+ MachineBasicBlock *MBB;
+
+public:
+ VLocTracker() {}
+
+ void defVar(const MachineInstr &MI, const DbgValueProperties &Properties,
+ Optional<ValueIDNum> ID) {
+ assert(MI.isDebugValue() || MI.isDebugRef());
+ DebugVariable Var(MI.getDebugVariable(), MI.getDebugExpression(),
+ MI.getDebugLoc()->getInlinedAt());
+ DbgValue Rec = (ID) ? DbgValue(*ID, Properties, DbgValue::Def)
+ : DbgValue(Properties, DbgValue::Undef);
+
+ // Attempt insertion; overwrite if it's already mapped.
+ auto Result = Vars.insert(std::make_pair(Var, Rec));
+ if (!Result.second)
+ Result.first->second = Rec;
+ Scopes[Var] = MI.getDebugLoc().get();
+ }
+
+ void defVar(const MachineInstr &MI, const MachineOperand &MO) {
+ // Only DBG_VALUEs can define constant-valued variables.
+ assert(MI.isDebugValue());
+ DebugVariable Var(MI.getDebugVariable(), MI.getDebugExpression(),
+ MI.getDebugLoc()->getInlinedAt());
+ DbgValueProperties Properties(MI);
+ DbgValue Rec = DbgValue(MO, Properties, DbgValue::Const);
+
+ // Attempt insertion; overwrite if it's already mapped.
+ auto Result = Vars.insert(std::make_pair(Var, Rec));
+ if (!Result.second)
+ Result.first->second = Rec;
+ Scopes[Var] = MI.getDebugLoc().get();
+ }
+};
+
+/// Tracker for converting machine value locations and variable values into
+/// variable locations (the output of LiveDebugValues), recorded as DBG_VALUEs
+/// specifying block live-in locations and transfers within blocks.
+///
+/// Operating on a per-block basis, this class takes a (pre-loaded) MLocTracker
+/// and must be initialized with the set of variable values that are live-in to
+/// the block. The caller then repeatedly calls process(). TransferTracker picks
+/// out variable locations for the live-in variable values (if there _is_ a
+/// location) and creates the corresponding DBG_VALUEs. Then, as the block is
+/// stepped through, transfers of values between machine locations are
+/// identified and if profitable, a DBG_VALUE created.
+///
+/// This is where debug use-before-defs would be resolved: a variable with an
+/// unavailable value could materialize in the middle of a block, when the
+/// value becomes available. Or, we could detect clobbers and re-specify the
+/// variable in a backup location. (XXX these are unimplemented).
+class TransferTracker {
+public:
+ const TargetInstrInfo *TII;
+ /// This machine location tracker is assumed to always contain the up-to-date
+ /// value mapping for all machine locations. TransferTracker only reads
+ /// information from it. (XXX make it const?)
+ MLocTracker *MTracker;
+ MachineFunction &MF;
+
+ /// Record of all changes in variable locations at a block position. Awkwardly
+ /// we allow inserting either before or after the point: MBB != nullptr
+ /// indicates it's before, otherwise after.
+ struct Transfer {
+ MachineBasicBlock::iterator Pos; /// Position to insert DBG_VALUes
+ MachineBasicBlock *MBB; /// non-null if we should insert after.
+ SmallVector<MachineInstr *, 4> Insts; /// Vector of DBG_VALUEs to insert.
+ };
+
+ typedef struct {
+ LocIdx Loc;
+ DbgValueProperties Properties;
+ } LocAndProperties;
+
+ /// Collection of transfers (DBG_VALUEs) to be inserted.
+ SmallVector<Transfer, 32> Transfers;
+
+ /// Local cache of what-value-is-in-what-LocIdx. Used to identify differences
+ /// between TransferTrackers view of variable locations and MLocTrackers. For
+ /// example, MLocTracker observes all clobbers, but TransferTracker lazily
+ /// does not.
+ std::vector<ValueIDNum> VarLocs;
+
+ /// Map from LocIdxes to which DebugVariables are based that location.
+ /// Mantained while stepping through the block. Not accurate if
+ /// VarLocs[Idx] != MTracker->LocIdxToIDNum[Idx].
+ std::map<LocIdx, SmallSet<DebugVariable, 4>> ActiveMLocs;
+
+ /// Map from DebugVariable to it's current location and qualifying meta
+ /// information. To be used in conjunction with ActiveMLocs to construct
+ /// enough information for the DBG_VALUEs for a particular LocIdx.
+ DenseMap<DebugVariable, LocAndProperties> ActiveVLocs;
+
+ /// Temporary cache of DBG_VALUEs to be entered into the Transfers collection.
+ SmallVector<MachineInstr *, 4> PendingDbgValues;
+
+ /// Record of a use-before-def: created when a value that's live-in to the
+ /// current block isn't available in any machine location, but it will be
+ /// defined in this block.
+ struct UseBeforeDef {
+ /// Value of this variable, def'd in block.
+ ValueIDNum ID;
+ /// Identity of this variable.
+ DebugVariable Var;
+ /// Additional variable properties.
+ DbgValueProperties Properties;
+ };
+
+ /// Map from instruction index (within the block) to the set of UseBeforeDefs
+ /// that become defined at that instruction.
+ DenseMap<unsigned, SmallVector<UseBeforeDef, 1>> UseBeforeDefs;
+
+ /// The set of variables that are in UseBeforeDefs and can become a location
+ /// once the relevant value is defined. An element being erased from this
+ /// collection prevents the use-before-def materializing.
+ DenseSet<DebugVariable> UseBeforeDefVariables;
+
+ const TargetRegisterInfo &TRI;
+ const BitVector &CalleeSavedRegs;
+
+ TransferTracker(const TargetInstrInfo *TII, MLocTracker *MTracker,
+ MachineFunction &MF, const TargetRegisterInfo &TRI,
+ const BitVector &CalleeSavedRegs)
+ : TII(TII), MTracker(MTracker), MF(MF), TRI(TRI),
+ CalleeSavedRegs(CalleeSavedRegs) {}
+
+ /// Load object with live-in variable values. \p mlocs contains the live-in
+ /// values in each machine location, while \p vlocs the live-in variable
+ /// values. This method picks variable locations for the live-in variables,
+ /// creates DBG_VALUEs and puts them in #Transfers, then prepares the other
+ /// object fields to track variable locations as we step through the block.
+ /// FIXME: could just examine mloctracker instead of passing in \p mlocs?
+ void loadInlocs(MachineBasicBlock &MBB, ValueIDNum *MLocs,
+ SmallVectorImpl<std::pair<DebugVariable, DbgValue>> &VLocs,
+ unsigned NumLocs) {
+ ActiveMLocs.clear();
+ ActiveVLocs.clear();
+ VarLocs.clear();
+ VarLocs.reserve(NumLocs);
+ UseBeforeDefs.clear();
+ UseBeforeDefVariables.clear();
+
+ auto isCalleeSaved = [&](LocIdx L) {
+ unsigned Reg = MTracker->LocIdxToLocID[L];
+ if (Reg >= MTracker->NumRegs)
+ return false;
+ for (MCRegAliasIterator RAI(Reg, &TRI, true); RAI.isValid(); ++RAI)
+ if (CalleeSavedRegs.test(*RAI))
+ return true;
+ return false;
+ };
+
+ // Map of the preferred location for each value.
+ std::map<ValueIDNum, LocIdx> ValueToLoc;
+
+ // Produce a map of value numbers to the current machine locs they live
+ // in. When emulating VarLocBasedImpl, there should only be one
+ // location; when not, we get to pick.
+ for (auto Location : MTracker->locations()) {
+ LocIdx Idx = Location.Idx;
+ ValueIDNum &VNum = MLocs[Idx.asU64()];
+ VarLocs.push_back(VNum);
+ auto it = ValueToLoc.find(VNum);
+ // In order of preference, pick:
+ // * Callee saved registers,
+ // * Other registers,
+ // * Spill slots.
+ if (it == ValueToLoc.end() || MTracker->isSpill(it->second) ||
+ (!isCalleeSaved(it->second) && isCalleeSaved(Idx.asU64()))) {
+ // Insert, or overwrite if insertion failed.
+ auto PrefLocRes = ValueToLoc.insert(std::make_pair(VNum, Idx));
+ if (!PrefLocRes.second)
+ PrefLocRes.first->second = Idx;
+ }
+ }
+
+ // Now map variables to their picked LocIdxes.
+ for (auto Var : VLocs) {
+ if (Var.second.Kind == DbgValue::Const) {
+ PendingDbgValues.push_back(
+ emitMOLoc(Var.second.MO, Var.first, Var.second.Properties));
+ continue;
+ }
+
+ // If the value has no location, we can't make a variable location.
+ const ValueIDNum &Num = Var.second.ID;
+ auto ValuesPreferredLoc = ValueToLoc.find(Num);
+ if (ValuesPreferredLoc == ValueToLoc.end()) {
+ // If it's a def that occurs in this block, register it as a
+ // use-before-def to be resolved as we step through the block.
+ if (Num.getBlock() == (unsigned)MBB.getNumber() && !Num.isPHI())
+ addUseBeforeDef(Var.first, Var.second.Properties, Num);
+ continue;
+ }
+
+ LocIdx M = ValuesPreferredLoc->second;
+ auto NewValue = LocAndProperties{M, Var.second.Properties};
+ auto Result = ActiveVLocs.insert(std::make_pair(Var.first, NewValue));
+ if (!Result.second)
+ Result.first->second = NewValue;
+ ActiveMLocs[M].insert(Var.first);
+ PendingDbgValues.push_back(
+ MTracker->emitLoc(M, Var.first, Var.second.Properties));
+ }
+ flushDbgValues(MBB.begin(), &MBB);
+ }
+
+ /// Record that \p Var has value \p ID, a value that becomes available
+ /// later in the function.
+ void addUseBeforeDef(const DebugVariable &Var,
+ const DbgValueProperties &Properties, ValueIDNum ID) {
+ UseBeforeDef UBD = {ID, Var, Properties};
+ UseBeforeDefs[ID.getInst()].push_back(UBD);
+ UseBeforeDefVariables.insert(Var);
+ }
+
+ /// After the instruction at index \p Inst and position \p pos has been
+ /// processed, check whether it defines a variable value in a use-before-def.
+ /// If so, and the variable value hasn't changed since the start of the
+ /// block, create a DBG_VALUE.
+ void checkInstForNewValues(unsigned Inst, MachineBasicBlock::iterator pos) {
+ auto MIt = UseBeforeDefs.find(Inst);
+ if (MIt == UseBeforeDefs.end())
+ return;
+
+ for (auto &Use : MIt->second) {
+ LocIdx L = Use.ID.getLoc();
+
+ // If something goes very wrong, we might end up labelling a COPY
+ // instruction or similar with an instruction number, where it doesn't
+ // actually define a new value, instead it moves a value. In case this
+ // happens, discard.
+ if (MTracker->LocIdxToIDNum[L] != Use.ID)
+ continue;
+
+ // If a different debug instruction defined the variable value / location
+ // since the start of the block, don't materialize this use-before-def.
+ if (!UseBeforeDefVariables.count(Use.Var))
+ continue;
+
+ PendingDbgValues.push_back(MTracker->emitLoc(L, Use.Var, Use.Properties));
+ }
+ flushDbgValues(pos, nullptr);
+ }
+
+ /// Helper to move created DBG_VALUEs into Transfers collection.
+ void flushDbgValues(MachineBasicBlock::iterator Pos, MachineBasicBlock *MBB) {
+ if (PendingDbgValues.size() > 0) {
+ Transfers.push_back({Pos, MBB, PendingDbgValues});
+ PendingDbgValues.clear();
+ }
+ }
+
+ /// Change a variable value after encountering a DBG_VALUE inside a block.
+ void redefVar(const MachineInstr &MI) {
+ DebugVariable Var(MI.getDebugVariable(), MI.getDebugExpression(),
+ MI.getDebugLoc()->getInlinedAt());
+ DbgValueProperties Properties(MI);
+
+ const MachineOperand &MO = MI.getOperand(0);
+
+ // Ignore non-register locations, we don't transfer those.
+ if (!MO.isReg() || MO.getReg() == 0) {
+ auto It = ActiveVLocs.find(Var);
+ if (It != ActiveVLocs.end()) {
+ ActiveMLocs[It->second.Loc].erase(Var);
+ ActiveVLocs.erase(It);
+ }
+ // Any use-before-defs no longer apply.
+ UseBeforeDefVariables.erase(Var);
+ return;
+ }
+
+ Register Reg = MO.getReg();
+ LocIdx NewLoc = MTracker->getRegMLoc(Reg);
+ redefVar(MI, Properties, NewLoc);
+ }
+
+ /// Handle a change in variable location within a block. Terminate the
+ /// variables current location, and record the value it now refers to, so
+ /// that we can detect location transfers later on.
+ void redefVar(const MachineInstr &MI, const DbgValueProperties &Properties,
+ Optional<LocIdx> OptNewLoc) {
+ DebugVariable Var(MI.getDebugVariable(), MI.getDebugExpression(),
+ MI.getDebugLoc()->getInlinedAt());
+ // Any use-before-defs no longer apply.
+ UseBeforeDefVariables.erase(Var);
+
+ // Erase any previous location,
+ auto It = ActiveVLocs.find(Var);
+ if (It != ActiveVLocs.end())
+ ActiveMLocs[It->second.Loc].erase(Var);
+
+ // If there _is_ no new location, all we had to do was erase.
+ if (!OptNewLoc)
+ return;
+ LocIdx NewLoc = *OptNewLoc;
+
+ // Check whether our local copy of values-by-location in #VarLocs is out of
+ // date. Wipe old tracking data for the location if it's been clobbered in
+ // the meantime.
+ if (MTracker->getNumAtPos(NewLoc) != VarLocs[NewLoc.asU64()]) {
+ for (auto &P : ActiveMLocs[NewLoc]) {
+ ActiveVLocs.erase(P);
+ }
+ ActiveMLocs[NewLoc.asU64()].clear();
+ VarLocs[NewLoc.asU64()] = MTracker->getNumAtPos(NewLoc);
+ }
+
+ ActiveMLocs[NewLoc].insert(Var);
+ if (It == ActiveVLocs.end()) {
+ ActiveVLocs.insert(
+ std::make_pair(Var, LocAndProperties{NewLoc, Properties}));
+ } else {
+ It->second.Loc = NewLoc;
+ It->second.Properties = Properties;
+ }
+ }
+
+ /// Explicitly terminate variable locations based on \p mloc. Creates undef
+ /// DBG_VALUEs for any variables that were located there, and clears
+ /// #ActiveMLoc / #ActiveVLoc tracking information for that location.
+ void clobberMloc(LocIdx MLoc, MachineBasicBlock::iterator Pos) {
+ assert(MTracker->isSpill(MLoc));
+ auto ActiveMLocIt = ActiveMLocs.find(MLoc);
+ if (ActiveMLocIt == ActiveMLocs.end())
+ return;
+
+ VarLocs[MLoc.asU64()] = ValueIDNum::EmptyValue;
+
+ for (auto &Var : ActiveMLocIt->second) {
+ auto ActiveVLocIt = ActiveVLocs.find(Var);
+ // Create an undef. We can't feed in a nullptr DIExpression alas,
+ // so use the variables last expression. Pass None as the location.
+ const DIExpression *Expr = ActiveVLocIt->second.Properties.DIExpr;
+ DbgValueProperties Properties(Expr, false);
+ PendingDbgValues.push_back(MTracker->emitLoc(None, Var, Properties));
+ ActiveVLocs.erase(ActiveVLocIt);
+ }
+ flushDbgValues(Pos, nullptr);
+
+ ActiveMLocIt->second.clear();
+ }
+
+ /// Transfer variables based on \p Src to be based on \p Dst. This handles
+ /// both register copies as well as spills and restores. Creates DBG_VALUEs
+ /// describing the movement.
+ void transferMlocs(LocIdx Src, LocIdx Dst, MachineBasicBlock::iterator Pos) {
+ // Does Src still contain the value num we expect? If not, it's been
+ // clobbered in the meantime, and our variable locations are stale.
+ if (VarLocs[Src.asU64()] != MTracker->getNumAtPos(Src))
+ return;
+
+ // assert(ActiveMLocs[Dst].size() == 0);
+ //^^^ Legitimate scenario on account of un-clobbered slot being assigned to?
+ ActiveMLocs[Dst] = ActiveMLocs[Src];
+ VarLocs[Dst.asU64()] = VarLocs[Src.asU64()];
+
+ // For each variable based on Src; create a location at Dst.
+ for (auto &Var : ActiveMLocs[Src]) {
+ auto ActiveVLocIt = ActiveVLocs.find(Var);
+ assert(ActiveVLocIt != ActiveVLocs.end());
+ ActiveVLocIt->second.Loc = Dst;
+
+ assert(Dst != 0);
+ MachineInstr *MI =
+ MTracker->emitLoc(Dst, Var, ActiveVLocIt->second.Properties);
+ PendingDbgValues.push_back(MI);
+ }
+ ActiveMLocs[Src].clear();
+ flushDbgValues(Pos, nullptr);
+
+ // XXX XXX XXX "pretend to be old LDV" means dropping all tracking data
+ // about the old location.
+ if (EmulateOldLDV)
+ VarLocs[Src.asU64()] = ValueIDNum::EmptyValue;
+ }
+
+ MachineInstrBuilder emitMOLoc(const MachineOperand &MO,
+ const DebugVariable &Var,
+ const DbgValueProperties &Properties) {
+ DebugLoc DL = DILocation::get(Var.getVariable()->getContext(), 0, 0,
+ Var.getVariable()->getScope(),
+ const_cast<DILocation *>(Var.getInlinedAt()));
+ auto MIB = BuildMI(MF, DL, TII->get(TargetOpcode::DBG_VALUE));
+ MIB.add(MO);
+ if (Properties.Indirect)
+ MIB.addImm(0);
+ else
+ MIB.addReg(0);
+ MIB.addMetadata(Var.getVariable());
+ MIB.addMetadata(Properties.DIExpr);
+ return MIB;
+ }
+};
+
+class InstrRefBasedLDV : public LDVImpl {
+private:
+ using FragmentInfo = DIExpression::FragmentInfo;
+ using OptFragmentInfo = Optional<DIExpression::FragmentInfo>;
+
+ // Helper while building OverlapMap, a map of all fragments seen for a given
+ // DILocalVariable.
+ using VarToFragments =
+ DenseMap<const DILocalVariable *, SmallSet<FragmentInfo, 4>>;
+
+ /// Machine location/value transfer function, a mapping of which locations
+ /// are assigned which new values.
+ using MLocTransferMap = std::map<LocIdx, ValueIDNum>;
+
+ /// Live in/out structure for the variable values: a per-block map of
+ /// variables to their values. XXX, better name?
+ using LiveIdxT =
+ DenseMap<const MachineBasicBlock *, DenseMap<DebugVariable, DbgValue> *>;
+
+ using VarAndLoc = std::pair<DebugVariable, DbgValue>;
+
+ /// Type for a live-in value: the predecessor block, and its value.
+ using InValueT = std::pair<MachineBasicBlock *, DbgValue *>;
+
+ /// Vector (per block) of a collection (inner smallvector) of live-ins.
+ /// Used as the result type for the variable value dataflow problem.
+ using LiveInsT = SmallVector<SmallVector<VarAndLoc, 8>, 8>;
+
+ const TargetRegisterInfo *TRI;
+ const TargetInstrInfo *TII;
+ const TargetFrameLowering *TFI;
+ BitVector CalleeSavedRegs;
+ LexicalScopes LS;
+ TargetPassConfig *TPC;
+
+ /// Object to track machine locations as we step through a block. Could
+ /// probably be a field rather than a pointer, as it's always used.
+ MLocTracker *MTracker;
+
+ /// Number of the current block LiveDebugValues is stepping through.
+ unsigned CurBB;
+
+ /// Number of the current instruction LiveDebugValues is evaluating.
+ unsigned CurInst;
+
+ /// Variable tracker -- listens to DBG_VALUEs occurring as InstrRefBasedImpl
+ /// steps through a block. Reads the values at each location from the
+ /// MLocTracker object.
+ VLocTracker *VTracker;
+
+ /// Tracker for transfers, listens to DBG_VALUEs and transfers of values
+ /// between locations during stepping, creates new DBG_VALUEs when values move
+ /// location.
+ TransferTracker *TTracker;
+
+ /// Blocks which are artificial, i.e. blocks which exclusively contain
+ /// instructions without DebugLocs, or with line 0 locations.
+ SmallPtrSet<const MachineBasicBlock *, 16> ArtificialBlocks;
+
+ // Mapping of blocks to and from their RPOT order.
+ DenseMap<unsigned int, MachineBasicBlock *> OrderToBB;
+ DenseMap<MachineBasicBlock *, unsigned int> BBToOrder;
+ DenseMap<unsigned, unsigned> BBNumToRPO;
+
+ /// Pair of MachineInstr, and its 1-based offset into the containing block.
+ using InstAndNum = std::pair<const MachineInstr *, unsigned>;
+ /// Map from debug instruction number to the MachineInstr labelled with that
+ /// number, and its location within the function. Used to transform
+ /// instruction numbers in DBG_INSTR_REFs into machine value numbers.
+ std::map<uint64_t, InstAndNum> DebugInstrNumToInstr;
+
+ // Map of overlapping variable fragments.
+ OverlapMap OverlapFragments;
+ VarToFragments SeenFragments;
+
+ /// Tests whether this instruction is a spill to a stack slot.
+ bool isSpillInstruction(const MachineInstr &MI, MachineFunction *MF);
+
+ /// Decide if @MI is a spill instruction and return true if it is. We use 2
+ /// criteria to make this decision:
+ /// - Is this instruction a store to a spill slot?
+ /// - Is there a register operand that is both used and killed?
+ /// TODO: Store optimization can fold spills into other stores (including
+ /// other spills). We do not handle this yet (more than one memory operand).
+ bool isLocationSpill(const MachineInstr &MI, MachineFunction *MF,
+ unsigned &Reg);
+
+ /// If a given instruction is identified as a spill, return the spill slot
+ /// and set \p Reg to the spilled register.
+ Optional<SpillLoc> isRestoreInstruction(const MachineInstr &MI,
+ MachineFunction *MF, unsigned &Reg);
+
+ /// Given a spill instruction, extract the register and offset used to
+ /// address the spill slot in a target independent way.
+ SpillLoc extractSpillBaseRegAndOffset(const MachineInstr &MI);
+
+ /// Observe a single instruction while stepping through a block.
+ void process(MachineInstr &MI);
+
+ /// Examines whether \p MI is a DBG_VALUE and notifies trackers.
+ /// \returns true if MI was recognized and processed.
+ bool transferDebugValue(const MachineInstr &MI);
+
+ /// Examines whether \p MI is a DBG_INSTR_REF and notifies trackers.
+ /// \returns true if MI was recognized and processed.
+ bool transferDebugInstrRef(MachineInstr &MI);
+
+ /// Examines whether \p MI is copy instruction, and notifies trackers.
+ /// \returns true if MI was recognized and processed.
+ bool transferRegisterCopy(MachineInstr &MI);
+
+ /// Examines whether \p MI is stack spill or restore instruction, and
+ /// notifies trackers. \returns true if MI was recognized and processed.
+ bool transferSpillOrRestoreInst(MachineInstr &MI);
+
+ /// Examines \p MI for any registers that it defines, and notifies trackers.
+ void transferRegisterDef(MachineInstr &MI);
+
+ /// Copy one location to the other, accounting for movement of subregisters
+ /// too.
+ void performCopy(Register Src, Register Dst);
+
+ void accumulateFragmentMap(MachineInstr &MI);
+
+ /// Step through the function, recording register definitions and movements
+ /// in an MLocTracker. Convert the observations into a per-block transfer
+ /// function in \p MLocTransfer, suitable for using with the machine value
+ /// location dataflow problem.
+ void
+ produceMLocTransferFunction(MachineFunction &MF,
+ SmallVectorImpl<MLocTransferMap> &MLocTransfer,
+ unsigned MaxNumBlocks);
+
+ /// Solve the machine value location dataflow problem. Takes as input the
+ /// transfer functions in \p MLocTransfer. Writes the output live-in and
+ /// live-out arrays to the (initialized to zero) multidimensional arrays in
+ /// \p MInLocs and \p MOutLocs. The outer dimension is indexed by block
+ /// number, the inner by LocIdx.
+ void mlocDataflow(ValueIDNum **MInLocs, ValueIDNum **MOutLocs,
+ SmallVectorImpl<MLocTransferMap> &MLocTransfer);
+
+ /// Perform a control flow join (lattice value meet) of the values in machine
+ /// locations at \p MBB. Follows the algorithm described in the file-comment,
+ /// reading live-outs of predecessors from \p OutLocs, the current live ins
+ /// from \p InLocs, and assigning the newly computed live ins back into
+ /// \p InLocs. \returns two bools -- the first indicates whether a change
+ /// was made, the second whether a lattice downgrade occurred. If the latter
+ /// is true, revisiting this block is necessary.
+ std::tuple<bool, bool>
+ mlocJoin(MachineBasicBlock &MBB,
+ SmallPtrSet<const MachineBasicBlock *, 16> &Visited,
+ ValueIDNum **OutLocs, ValueIDNum *InLocs);
+
+ /// Solve the variable value dataflow problem, for a single lexical scope.
+ /// Uses the algorithm from the file comment to resolve control flow joins,
+ /// although there are extra hacks, see vlocJoin. Reads the
+ /// locations of values from the \p MInLocs and \p MOutLocs arrays (see
+ /// mlocDataflow) and reads the variable values transfer function from
+ /// \p AllTheVlocs. Live-in and Live-out variable values are stored locally,
+ /// with the live-ins permanently stored to \p Output once the fixedpoint is
+ /// reached.
+ /// \p VarsWeCareAbout contains a collection of the variables in \p Scope
+ /// that we should be tracking.
+ /// \p AssignBlocks contains the set of blocks that aren't in \p Scope, but
+ /// which do contain DBG_VALUEs, which VarLocBasedImpl tracks locations
+ /// through.
+ void vlocDataflow(const LexicalScope *Scope, const DILocation *DILoc,
+ const SmallSet<DebugVariable, 4> &VarsWeCareAbout,
+ SmallPtrSetImpl<MachineBasicBlock *> &AssignBlocks,
+ LiveInsT &Output, ValueIDNum **MOutLocs,
+ ValueIDNum **MInLocs,
+ SmallVectorImpl<VLocTracker> &AllTheVLocs);
+
+ /// Compute the live-ins to a block, considering control flow merges according
+ /// to the method in the file comment. Live out and live in variable values
+ /// are stored in \p VLOCOutLocs and \p VLOCInLocs. The live-ins for \p MBB
+ /// are computed and stored into \p VLOCInLocs. \returns true if the live-ins
+ /// are modified.
+ /// \p InLocsT Output argument, storage for calculated live-ins.
+ /// \returns two bools -- the first indicates whether a change
+ /// was made, the second whether a lattice downgrade occurred. If the latter
+ /// is true, revisiting this block is necessary.
+ std::tuple<bool, bool>
+ vlocJoin(MachineBasicBlock &MBB, LiveIdxT &VLOCOutLocs, LiveIdxT &VLOCInLocs,
+ SmallPtrSet<const MachineBasicBlock *, 16> *VLOCVisited,
+ unsigned BBNum, const SmallSet<DebugVariable, 4> &AllVars,
+ ValueIDNum **MOutLocs, ValueIDNum **MInLocs,
+ SmallPtrSet<const MachineBasicBlock *, 8> &InScopeBlocks,
+ SmallPtrSet<const MachineBasicBlock *, 8> &BlocksToExplore,
+ DenseMap<DebugVariable, DbgValue> &InLocsT);
+
+ /// Continue exploration of the variable-value lattice, as explained in the
+ /// file-level comment. \p OldLiveInLocation contains the current
+ /// exploration position, from which we need to descend further. \p Values
+ /// contains the set of live-in values, \p CurBlockRPONum the RPO number of
+ /// the current block, and \p CandidateLocations a set of locations that
+ /// should be considered as PHI locations, if we reach the bottom of the
+ /// lattice. \returns true if we should downgrade; the value is the agreeing
+ /// value number in a non-backedge predecessor.
+ bool vlocDowngradeLattice(const MachineBasicBlock &MBB,
+ const DbgValue &OldLiveInLocation,
+ const SmallVectorImpl<InValueT> &Values,
+ unsigned CurBlockRPONum);
+
+ /// For the given block and live-outs feeding into it, try to find a
+ /// machine location where they all join. If a solution for all predecessors
+ /// can't be found, a location where all non-backedge-predecessors join
+ /// will be returned instead. While this method finds a join location, this
+ /// says nothing as to whether it should be used.
+ /// \returns Pair of value ID if found, and true when the correct value
+ /// is available on all predecessor edges, or false if it's only available
+ /// for non-backedge predecessors.
+ std::tuple<Optional<ValueIDNum>, bool>
+ pickVPHILoc(MachineBasicBlock &MBB, const DebugVariable &Var,
+ const LiveIdxT &LiveOuts, ValueIDNum **MOutLocs,
+ ValueIDNum **MInLocs,
+ const SmallVectorImpl<MachineBasicBlock *> &BlockOrders);
+
+ /// Given the solutions to the two dataflow problems, machine value locations
+ /// in \p MInLocs and live-in variable values in \p SavedLiveIns, runs the
+ /// TransferTracker class over the function to produce live-in and transfer
+ /// DBG_VALUEs, then inserts them. Groups of DBG_VALUEs are inserted in the
+ /// order given by AllVarsNumbering -- this could be any stable order, but
+ /// right now "order of appearence in function, when explored in RPO", so
+ /// that we can compare explictly against VarLocBasedImpl.
+ void emitLocations(MachineFunction &MF, LiveInsT SavedLiveIns,
+ ValueIDNum **MInLocs,
+ DenseMap<DebugVariable, unsigned> &AllVarsNumbering);
+
+ /// Boilerplate computation of some initial sets, artifical blocks and
+ /// RPOT block ordering.
+ void initialSetup(MachineFunction &MF);
+
+ bool ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC) override;
+
+public:
+ /// Default construct and initialize the pass.
+ InstrRefBasedLDV();
+
+ LLVM_DUMP_METHOD
+ void dump_mloc_transfer(const MLocTransferMap &mloc_transfer) const;
+
+ bool isCalleeSaved(LocIdx L) {
+ unsigned Reg = MTracker->LocIdxToLocID[L];
+ for (MCRegAliasIterator RAI(Reg, TRI, true); RAI.isValid(); ++RAI)
+ if (CalleeSavedRegs.test(*RAI))
+ return true;
+ return false;
+ }
+};
+
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Implementation
+//===----------------------------------------------------------------------===//
+
+ValueIDNum ValueIDNum::EmptyValue = {UINT_MAX, UINT_MAX, UINT_MAX};
+
+/// Default construct and initialize the pass.
+InstrRefBasedLDV::InstrRefBasedLDV() {}
+
+//===----------------------------------------------------------------------===//
+// Debug Range Extension Implementation
+//===----------------------------------------------------------------------===//
+
+#ifndef NDEBUG
+// Something to restore in the future.
+// void InstrRefBasedLDV::printVarLocInMBB(..)
+#endif
+
+SpillLoc
+InstrRefBasedLDV::extractSpillBaseRegAndOffset(const MachineInstr &MI) {
+ assert(MI.hasOneMemOperand() &&
+ "Spill instruction does not have exactly one memory operand?");
+ auto MMOI = MI.memoperands_begin();
+ const PseudoSourceValue *PVal = (*MMOI)->getPseudoValue();
+ assert(PVal->kind() == PseudoSourceValue::FixedStack &&
+ "Inconsistent memory operand in spill instruction");
+ int FI = cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex();
+ const MachineBasicBlock *MBB = MI.getParent();
+ Register Reg;
+ StackOffset Offset = TFI->getFrameIndexReference(*MBB->getParent(), FI, Reg);
+ return {Reg, Offset};
+}
+
+/// End all previous ranges related to @MI and start a new range from @MI
+/// if it is a DBG_VALUE instr.
+bool InstrRefBasedLDV::transferDebugValue(const MachineInstr &MI) {
+ if (!MI.isDebugValue())
+ return false;
+
+ const DILocalVariable *Var = MI.getDebugVariable();
+ const DIExpression *Expr = MI.getDebugExpression();
+ const DILocation *DebugLoc = MI.getDebugLoc();
+ const DILocation *InlinedAt = DebugLoc->getInlinedAt();
+ assert(Var->isValidLocationForIntrinsic(DebugLoc) &&
+ "Expected inlined-at fields to agree");
+
+ DebugVariable V(Var, Expr, InlinedAt);
+ DbgValueProperties Properties(MI);
+
+ // If there are no instructions in this lexical scope, do no location tracking
+ // at all, this variable shouldn't get a legitimate location range.
+ auto *Scope = LS.findLexicalScope(MI.getDebugLoc().get());
+ if (Scope == nullptr)
+ return true; // handled it; by doing nothing
+
+ const MachineOperand &MO = MI.getOperand(0);
+
+ // MLocTracker needs to know that this register is read, even if it's only
+ // read by a debug inst.
+ if (MO.isReg() && MO.getReg() != 0)
+ (void)MTracker->readReg(MO.getReg());
+
+ // If we're preparing for the second analysis (variables), the machine value
+ // locations are already solved, and we report this DBG_VALUE and the value
+ // it refers to to VLocTracker.
+ if (VTracker) {
+ if (MO.isReg()) {
+ // Feed defVar the new variable location, or if this is a
+ // DBG_VALUE $noreg, feed defVar None.
+ if (MO.getReg())
+ VTracker->defVar(MI, Properties, MTracker->readReg(MO.getReg()));
+ else
+ VTracker->defVar(MI, Properties, None);
+ } else if (MI.getOperand(0).isImm() || MI.getOperand(0).isFPImm() ||
+ MI.getOperand(0).isCImm()) {
+ VTracker->defVar(MI, MI.getOperand(0));
+ }
+ }
+
+ // If performing final tracking of transfers, report this variable definition
+ // to the TransferTracker too.
+ if (TTracker)
+ TTracker->redefVar(MI);
+ return true;
+}
+
+bool InstrRefBasedLDV::transferDebugInstrRef(MachineInstr &MI) {
+ if (!MI.isDebugRef())
+ return false;
+
+ // Only handle this instruction when we are building the variable value
+ // transfer function.
+ if (!VTracker)
+ return false;
+
+ unsigned InstNo = MI.getOperand(0).getImm();
+ unsigned OpNo = MI.getOperand(1).getImm();
+
+ const DILocalVariable *Var = MI.getDebugVariable();
+ const DIExpression *Expr = MI.getDebugExpression();
+ const DILocation *DebugLoc = MI.getDebugLoc();
+ const DILocation *InlinedAt = DebugLoc->getInlinedAt();
+ assert(Var->isValidLocationForIntrinsic(DebugLoc) &&
+ "Expected inlined-at fields to agree");
+
+ DebugVariable V(Var, Expr, InlinedAt);
+
+ auto *Scope = LS.findLexicalScope(MI.getDebugLoc().get());
+ if (Scope == nullptr)
+ return true; // Handled by doing nothing. This variable is never in scope.
+
+ const MachineFunction &MF = *MI.getParent()->getParent();
+
+ // Various optimizations may have happened to the value during codegen,
+ // recorded in the value substitution table. Apply any substitutions to
+ // the instruction / operand number in this DBG_INSTR_REF.
+ auto Sub = MF.DebugValueSubstitutions.find(std::make_pair(InstNo, OpNo));
+ while (Sub != MF.DebugValueSubstitutions.end()) {
+ InstNo = Sub->second.first;
+ OpNo = Sub->second.second;
+ Sub = MF.DebugValueSubstitutions.find(std::make_pair(InstNo, OpNo));
+ }
+
+ // Default machine value number is <None> -- if no instruction defines
+ // the corresponding value, it must have been optimized out.
+ Optional<ValueIDNum> NewID = None;
+
+ // Try to lookup the instruction number, and find the machine value number
+ // that it defines.
+ auto InstrIt = DebugInstrNumToInstr.find(InstNo);
+ if (InstrIt != DebugInstrNumToInstr.end()) {
+ const MachineInstr &TargetInstr = *InstrIt->second.first;
+ uint64_t BlockNo = TargetInstr.getParent()->getNumber();
+
+ // Pick out the designated operand.
+ assert(OpNo < TargetInstr.getNumOperands());
+ const MachineOperand &MO = TargetInstr.getOperand(OpNo);
+
+ // Today, this can only be a register.
+ assert(MO.isReg() && MO.isDef());
+
+ unsigned LocID = MTracker->getLocID(MO.getReg(), false);
+ LocIdx L = MTracker->LocIDToLocIdx[LocID];
+ NewID = ValueIDNum(BlockNo, InstrIt->second.second, L);
+ }
+
+ // We, we have a value number or None. Tell the variable value tracker about
+ // it. The rest of this LiveDebugValues implementation acts exactly the same
+ // for DBG_INSTR_REFs as DBG_VALUEs (just, the former can refer to values that
+ // aren't immediately available).
+ DbgValueProperties Properties(Expr, false);
+ VTracker->defVar(MI, Properties, NewID);
+
+ // If we're on the final pass through the function, decompose this INSTR_REF
+ // into a plain DBG_VALUE.
+ if (!TTracker)
+ return true;
+
+ // Pick a location for the machine value number, if such a location exists.
+ // (This information could be stored in TransferTracker to make it faster).
+ Optional<LocIdx> FoundLoc = None;
+ for (auto Location : MTracker->locations()) {
+ LocIdx CurL = Location.Idx;
+ ValueIDNum ID = MTracker->LocIdxToIDNum[CurL];
+ if (NewID && ID == NewID) {
+ // If this is the first location with that value, pick it. Otherwise,
+ // consider whether it's a "longer term" location.
+ if (!FoundLoc) {
+ FoundLoc = CurL;
+ continue;
+ }
+
+ if (MTracker->isSpill(CurL))
+ FoundLoc = CurL; // Spills are a longer term location.
+ else if (!MTracker->isSpill(*FoundLoc) &&
+ !MTracker->isSpill(CurL) &&
+ !isCalleeSaved(*FoundLoc) &&
+ isCalleeSaved(CurL))
+ FoundLoc = CurL; // Callee saved regs are longer term than normal.
+ }
+ }
+
+ // Tell transfer tracker that the variable value has changed.
+ TTracker->redefVar(MI, Properties, FoundLoc);
+
+ // If there was a value with no location; but the value is defined in a
+ // later instruction in this block, this is a block-local use-before-def.
+ if (!FoundLoc && NewID && NewID->getBlock() == CurBB &&
+ NewID->getInst() > CurInst)
+ TTracker->addUseBeforeDef(V, {MI.getDebugExpression(), false}, *NewID);
+
+ // Produce a DBG_VALUE representing what this DBG_INSTR_REF meant.
+ // This DBG_VALUE is potentially a $noreg / undefined location, if
+ // FoundLoc is None.
+ // (XXX -- could morph the DBG_INSTR_REF in the future).
+ MachineInstr *DbgMI = MTracker->emitLoc(FoundLoc, V, Properties);
+ TTracker->PendingDbgValues.push_back(DbgMI);
+ TTracker->flushDbgValues(MI.getIterator(), nullptr);
+
+ return true;
+}
+
+void InstrRefBasedLDV::transferRegisterDef(MachineInstr &MI) {
+ // Meta Instructions do not affect the debug liveness of any register they
+ // define.
+ if (MI.isImplicitDef()) {
+ // Except when there's an implicit def, and the location it's defining has
+ // no value number. The whole point of an implicit def is to announce that
+ // the register is live, without be specific about it's value. So define
+ // a value if there isn't one already.
+ ValueIDNum Num = MTracker->readReg(MI.getOperand(0).getReg());
+ // Has a legitimate value -> ignore the implicit def.
+ if (Num.getLoc() != 0)
+ return;
+ // Otherwise, def it here.
+ } else if (MI.isMetaInstruction())
+ return;
+
+ MachineFunction *MF = MI.getMF();
+ const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();
+ Register SP = TLI->getStackPointerRegisterToSaveRestore();
+
+ // Find the regs killed by MI, and find regmasks of preserved regs.
+ // Max out the number of statically allocated elements in `DeadRegs`, as this
+ // prevents fallback to std::set::count() operations.
+ SmallSet<uint32_t, 32> DeadRegs;
+ SmallVector<const uint32_t *, 4> RegMasks;
+ SmallVector<const MachineOperand *, 4> RegMaskPtrs;
+ for (const MachineOperand &MO : MI.operands()) {
+ // Determine whether the operand is a register def.
+ if (MO.isReg() && MO.isDef() && MO.getReg() &&
+ Register::isPhysicalRegister(MO.getReg()) &&
+ !(MI.isCall() && MO.getReg() == SP)) {
+ // Remove ranges of all aliased registers.
+ for (MCRegAliasIterator RAI(MO.getReg(), TRI, true); RAI.isValid(); ++RAI)
+ // FIXME: Can we break out of this loop early if no insertion occurs?
+ DeadRegs.insert(*RAI);
+ } else if (MO.isRegMask()) {
+ RegMasks.push_back(MO.getRegMask());
+ RegMaskPtrs.push_back(&MO);
+ }
+ }
+
+ // Tell MLocTracker about all definitions, of regmasks and otherwise.
+ for (uint32_t DeadReg : DeadRegs)
+ MTracker->defReg(DeadReg, CurBB, CurInst);
+
+ for (auto *MO : RegMaskPtrs)
+ MTracker->writeRegMask(MO, CurBB, CurInst);
+}
+
+void InstrRefBasedLDV::performCopy(Register SrcRegNum, Register DstRegNum) {
+ ValueIDNum SrcValue = MTracker->readReg(SrcRegNum);
+
+ MTracker->setReg(DstRegNum, SrcValue);
+
+ // In all circumstances, re-def the super registers. It's definitely a new
+ // value now. This doesn't uniquely identify the composition of subregs, for
+ // example, two identical values in subregisters composed in different
+ // places would not get equal value numbers.
+ for (MCSuperRegIterator SRI(DstRegNum, TRI); SRI.isValid(); ++SRI)
+ MTracker->defReg(*SRI, CurBB, CurInst);
+
+ // If we're emulating VarLocBasedImpl, just define all the subregisters.
+ // DBG_VALUEs of them will expect to be tracked from the DBG_VALUE, not
+ // through prior copies.
+ if (EmulateOldLDV) {
+ for (MCSubRegIndexIterator DRI(DstRegNum, TRI); DRI.isValid(); ++DRI)
+ MTracker->defReg(DRI.getSubReg(), CurBB, CurInst);
+ return;
+ }
+
+ // Otherwise, actually copy subregisters from one location to another.
+ // XXX: in addition, any subregisters of DstRegNum that don't line up with
+ // the source register should be def'd.
+ for (MCSubRegIndexIterator SRI(SrcRegNum, TRI); SRI.isValid(); ++SRI) {
+ unsigned SrcSubReg = SRI.getSubReg();
+ unsigned SubRegIdx = SRI.getSubRegIndex();
+ unsigned DstSubReg = TRI->getSubReg(DstRegNum, SubRegIdx);
+ if (!DstSubReg)
+ continue;
+
+ // Do copy. There are two matching subregisters, the source value should
+ // have been def'd when the super-reg was, the latter might not be tracked
+ // yet.
+ // This will force SrcSubReg to be tracked, if it isn't yet.
+ (void)MTracker->readReg(SrcSubReg);
+ LocIdx SrcL = MTracker->getRegMLoc(SrcSubReg);
+ assert(SrcL.asU64());
+ (void)MTracker->readReg(DstSubReg);
+ LocIdx DstL = MTracker->getRegMLoc(DstSubReg);
+ assert(DstL.asU64());
+ (void)DstL;
+ ValueIDNum CpyValue = {SrcValue.getBlock(), SrcValue.getInst(), SrcL};
+
+ MTracker->setReg(DstSubReg, CpyValue);
+ }
+}
+
+bool InstrRefBasedLDV::isSpillInstruction(const MachineInstr &MI,
+ MachineFunction *MF) {
+ // TODO: Handle multiple stores folded into one.
+ if (!MI.hasOneMemOperand())
+ return false;
+
+ if (!MI.getSpillSize(TII) && !MI.getFoldedSpillSize(TII))
+ return false; // This is not a spill instruction, since no valid size was
+ // returned from either function.
+
+ return true;
+}
+
+bool InstrRefBasedLDV::isLocationSpill(const MachineInstr &MI,
+ MachineFunction *MF, unsigned &Reg) {
+ if (!isSpillInstruction(MI, MF))
+ return false;
+
+ // XXX FIXME: On x86, isStoreToStackSlotPostFE returns '1' instead of an
+ // actual register number.
+ if (ObserveAllStackops) {
+ int FI;
+ Reg = TII->isStoreToStackSlotPostFE(MI, FI);
+ return Reg != 0;
+ }
+
+ auto isKilledReg = [&](const MachineOperand MO, unsigned &Reg) {
+ if (!MO.isReg() || !MO.isUse()) {
+ Reg = 0;
+ return false;
+ }
+ Reg = MO.getReg();
+ return MO.isKill();
+ };
+
+ for (const MachineOperand &MO : MI.operands()) {
+ // In a spill instruction generated by the InlineSpiller the spilled
+ // register has its kill flag set.
+ if (isKilledReg(MO, Reg))
+ return true;
+ if (Reg != 0) {
+ // Check whether next instruction kills the spilled register.
+ // FIXME: Current solution does not cover search for killed register in
+ // bundles and instructions further down the chain.
+ auto NextI = std::next(MI.getIterator());
+ // Skip next instruction that points to basic block end iterator.
+ if (MI.getParent()->end() == NextI)
+ continue;
+ unsigned RegNext;
+ for (const MachineOperand &MONext : NextI->operands()) {
+ // Return true if we came across the register from the
+ // previous spill instruction that is killed in NextI.
+ if (isKilledReg(MONext, RegNext) && RegNext == Reg)
+ return true;
+ }
+ }
+ }
+ // Return false if we didn't find spilled register.
+ return false;
+}
+
+Optional<SpillLoc>
+InstrRefBasedLDV::isRestoreInstruction(const MachineInstr &MI,
+ MachineFunction *MF, unsigned &Reg) {
+ if (!MI.hasOneMemOperand())
+ return None;
+
+ // FIXME: Handle folded restore instructions with more than one memory
+ // operand.
+ if (MI.getRestoreSize(TII)) {
+ Reg = MI.getOperand(0).getReg();
+ return extractSpillBaseRegAndOffset(MI);
+ }
+ return None;
+}
+
+bool InstrRefBasedLDV::transferSpillOrRestoreInst(MachineInstr &MI) {
+ // XXX -- it's too difficult to implement VarLocBasedImpl's stack location
+ // limitations under the new model. Therefore, when comparing them, compare
+ // versions that don't attempt spills or restores at all.
+ if (EmulateOldLDV)
+ return false;
+
+ MachineFunction *MF = MI.getMF();
+ unsigned Reg;
+ Optional<SpillLoc> Loc;
+
+ LLVM_DEBUG(dbgs() << "Examining instruction: "; MI.dump(););
+
+ // First, if there are any DBG_VALUEs pointing at a spill slot that is
+ // written to, terminate that variable location. The value in memory
+ // will have changed. DbgEntityHistoryCalculator doesn't try to detect this.
+ if (isSpillInstruction(MI, MF)) {
+ Loc = extractSpillBaseRegAndOffset(MI);
+
+ if (TTracker) {
+ Optional<LocIdx> MLoc = MTracker->getSpillMLoc(*Loc);
+ if (MLoc)
+ TTracker->clobberMloc(*MLoc, MI.getIterator());
+ }
+ }
+
+ // Try to recognise spill and restore instructions that may transfer a value.
+ if (isLocationSpill(MI, MF, Reg)) {
+ Loc = extractSpillBaseRegAndOffset(MI);
+ auto ValueID = MTracker->readReg(Reg);
+
+ // If the location is empty, produce a phi, signify it's the live-in value.
+ if (ValueID.getLoc() == 0)
+ ValueID = {CurBB, 0, MTracker->getRegMLoc(Reg)};
+
+ MTracker->setSpill(*Loc, ValueID);
+ auto OptSpillLocIdx = MTracker->getSpillMLoc(*Loc);
+ assert(OptSpillLocIdx && "Spill slot set but has no LocIdx?");
+ LocIdx SpillLocIdx = *OptSpillLocIdx;
+
+ // Tell TransferTracker about this spill, produce DBG_VALUEs for it.
+ if (TTracker)
+ TTracker->transferMlocs(MTracker->getRegMLoc(Reg), SpillLocIdx,
+ MI.getIterator());
+ } else {
+ if (!(Loc = isRestoreInstruction(MI, MF, Reg)))
+ return false;
+
+ // Is there a value to be restored?
+ auto OptValueID = MTracker->readSpill(*Loc);
+ if (OptValueID) {
+ ValueIDNum ValueID = *OptValueID;
+ LocIdx SpillLocIdx = *MTracker->getSpillMLoc(*Loc);
+ // XXX -- can we recover sub-registers of this value? Until we can, first
+ // overwrite all defs of the register being restored to.
+ for (MCRegAliasIterator RAI(Reg, TRI, true); RAI.isValid(); ++RAI)
+ MTracker->defReg(*RAI, CurBB, CurInst);
+
+ // Now override the reg we're restoring to.
+ MTracker->setReg(Reg, ValueID);
+
+ // Report this restore to the transfer tracker too.
+ if (TTracker)
+ TTracker->transferMlocs(SpillLocIdx, MTracker->getRegMLoc(Reg),
+ MI.getIterator());
+ } else {
+ // There isn't anything in the location; not clear if this is a code path
+ // that still runs. Def this register anyway just in case.
+ for (MCRegAliasIterator RAI(Reg, TRI, true); RAI.isValid(); ++RAI)
+ MTracker->defReg(*RAI, CurBB, CurInst);
+
+ // Force the spill slot to be tracked.
+ LocIdx L = MTracker->getOrTrackSpillLoc(*Loc);
+
+ // Set the restored value to be a machine phi number, signifying that it's
+ // whatever the spills live-in value is in this block. Definitely has
+ // a LocIdx due to the setSpill above.
+ ValueIDNum ValueID = {CurBB, 0, L};
+ MTracker->setReg(Reg, ValueID);
+ MTracker->setSpill(*Loc, ValueID);
+ }
+ }
+ return true;
+}
+
+bool InstrRefBasedLDV::transferRegisterCopy(MachineInstr &MI) {
+ auto DestSrc = TII->isCopyInstr(MI);
+ if (!DestSrc)
+ return false;
+
+ const MachineOperand *DestRegOp = DestSrc->Destination;
+ const MachineOperand *SrcRegOp = DestSrc->Source;
+
+ auto isCalleeSavedReg = [&](unsigned Reg) {
+ for (MCRegAliasIterator RAI(Reg, TRI, true); RAI.isValid(); ++RAI)
+ if (CalleeSavedRegs.test(*RAI))
+ return true;
+ return false;
+ };
+
+ Register SrcReg = SrcRegOp->getReg();
+ Register DestReg = DestRegOp->getReg();
+
+ // Ignore identity copies. Yep, these make it as far as LiveDebugValues.
+ if (SrcReg == DestReg)
+ return true;
+
+ // For emulating VarLocBasedImpl:
+ // We want to recognize instructions where destination register is callee
+ // saved register. If register that could be clobbered by the call is
+ // included, there would be a great chance that it is going to be clobbered
+ // soon. It is more likely that previous register, which is callee saved, is
+ // going to stay unclobbered longer, even if it is killed.
+ //
+ // For InstrRefBasedImpl, we can track multiple locations per value, so
+ // ignore this condition.
+ if (EmulateOldLDV && !isCalleeSavedReg(DestReg))
+ return false;
+
+ // InstrRefBasedImpl only followed killing copies.
+ if (EmulateOldLDV && !SrcRegOp->isKill())
+ return false;
+
+ // Copy MTracker info, including subregs if available.
+ InstrRefBasedLDV::performCopy(SrcReg, DestReg);
+
+ // Only produce a transfer of DBG_VALUE within a block where old LDV
+ // would have. We might make use of the additional value tracking in some
+ // other way, later.
+ if (TTracker && isCalleeSavedReg(DestReg) && SrcRegOp->isKill())
+ TTracker->transferMlocs(MTracker->getRegMLoc(SrcReg),
+ MTracker->getRegMLoc(DestReg), MI.getIterator());
+
+ // VarLocBasedImpl would quit tracking the old location after copying.
+ if (EmulateOldLDV && SrcReg != DestReg)
+ MTracker->defReg(SrcReg, CurBB, CurInst);
+
+ return true;
+}
+
+/// Accumulate a mapping between each DILocalVariable fragment and other
+/// fragments of that DILocalVariable which overlap. This reduces work during
+/// the data-flow stage from "Find any overlapping fragments" to "Check if the
+/// known-to-overlap fragments are present".
+/// \param MI A previously unprocessed DEBUG_VALUE instruction to analyze for
+/// fragment usage.
+void InstrRefBasedLDV::accumulateFragmentMap(MachineInstr &MI) {
+ DebugVariable MIVar(MI.getDebugVariable(), MI.getDebugExpression(),
+ MI.getDebugLoc()->getInlinedAt());
+ FragmentInfo ThisFragment = MIVar.getFragmentOrDefault();
+
+ // If this is the first sighting of this variable, then we are guaranteed
+ // there are currently no overlapping fragments either. Initialize the set
+ // of seen fragments, record no overlaps for the current one, and return.
+ auto SeenIt = SeenFragments.find(MIVar.getVariable());
+ if (SeenIt == SeenFragments.end()) {
+ SmallSet<FragmentInfo, 4> OneFragment;
+ OneFragment.insert(ThisFragment);
+ SeenFragments.insert({MIVar.getVariable(), OneFragment});
+
+ OverlapFragments.insert({{MIVar.getVariable(), ThisFragment}, {}});
+ return;
+ }
+
+ // If this particular Variable/Fragment pair already exists in the overlap
+ // map, it has already been accounted for.
+ auto IsInOLapMap =
+ OverlapFragments.insert({{MIVar.getVariable(), ThisFragment}, {}});
+ if (!IsInOLapMap.second)
+ return;
+
+ auto &ThisFragmentsOverlaps = IsInOLapMap.first->second;
+ auto &AllSeenFragments = SeenIt->second;
+
+ // Otherwise, examine all other seen fragments for this variable, with "this"
+ // fragment being a previously unseen fragment. Record any pair of
+ // overlapping fragments.
+ for (auto &ASeenFragment : AllSeenFragments) {
+ // Does this previously seen fragment overlap?
+ if (DIExpression::fragmentsOverlap(ThisFragment, ASeenFragment)) {
+ // Yes: Mark the current fragment as being overlapped.
+ ThisFragmentsOverlaps.push_back(ASeenFragment);
+ // Mark the previously seen fragment as being overlapped by the current
+ // one.
+ auto ASeenFragmentsOverlaps =
+ OverlapFragments.find({MIVar.getVariable(), ASeenFragment});
+ assert(ASeenFragmentsOverlaps != OverlapFragments.end() &&
+ "Previously seen var fragment has no vector of overlaps");
+ ASeenFragmentsOverlaps->second.push_back(ThisFragment);
+ }
+ }
+
+ AllSeenFragments.insert(ThisFragment);
+}
+
+void InstrRefBasedLDV::process(MachineInstr &MI) {
+ // Try to interpret an MI as a debug or transfer instruction. Only if it's
+ // none of these should we interpret it's register defs as new value
+ // definitions.
+ if (transferDebugValue(MI))
+ return;
+ if (transferDebugInstrRef(MI))
+ return;
+ if (transferRegisterCopy(MI))
+ return;
+ if (transferSpillOrRestoreInst(MI))
+ return;
+ transferRegisterDef(MI);
+}
+
+void InstrRefBasedLDV::produceMLocTransferFunction(
+ MachineFunction &MF, SmallVectorImpl<MLocTransferMap> &MLocTransfer,
+ unsigned MaxNumBlocks) {
+ // Because we try to optimize around register mask operands by ignoring regs
+ // that aren't currently tracked, we set up something ugly for later: RegMask
+ // operands that are seen earlier than the first use of a register, still need
+ // to clobber that register in the transfer function. But this information
+ // isn't actively recorded. Instead, we track each RegMask used in each block,
+ // and accumulated the clobbered but untracked registers in each block into
+ // the following bitvector. Later, if new values are tracked, we can add
+ // appropriate clobbers.
+ SmallVector<BitVector, 32> BlockMasks;
+ BlockMasks.resize(MaxNumBlocks);
+
+ // Reserve one bit per register for the masks described above.
+ unsigned BVWords = MachineOperand::getRegMaskSize(TRI->getNumRegs());
+ for (auto &BV : BlockMasks)
+ BV.resize(TRI->getNumRegs(), true);
+
+ // Step through all instructions and inhale the transfer function.
+ for (auto &MBB : MF) {
+ // Object fields that are read by trackers to know where we are in the
+ // function.
+ CurBB = MBB.getNumber();
+ CurInst = 1;
+
+ // Set all machine locations to a PHI value. For transfer function
+ // production only, this signifies the live-in value to the block.
+ MTracker->reset();
+ MTracker->setMPhis(CurBB);
+
+ // Step through each instruction in this block.
+ for (auto &MI : MBB) {
+ process(MI);
+ // Also accumulate fragment map.
+ if (MI.isDebugValue())
+ accumulateFragmentMap(MI);
+
+ // Create a map from the instruction number (if present) to the
+ // MachineInstr and its position.
+ if (uint64_t InstrNo = MI.peekDebugInstrNum()) {
+ auto InstrAndPos = std::make_pair(&MI, CurInst);
+ auto InsertResult =
+ DebugInstrNumToInstr.insert(std::make_pair(InstrNo, InstrAndPos));
+
+ // There should never be duplicate instruction numbers.
+ assert(InsertResult.second);
+ (void)InsertResult;
+ }
+
+ ++CurInst;
+ }
+
+ // Produce the transfer function, a map of machine location to new value. If
+ // any machine location has the live-in phi value from the start of the
+ // block, it's live-through and doesn't need recording in the transfer
+ // function.
+ for (auto Location : MTracker->locations()) {
+ LocIdx Idx = Location.Idx;
+ ValueIDNum &P = Location.Value;
+ if (P.isPHI() && P.getLoc() == Idx.asU64())
+ continue;
+
+ // Insert-or-update.
+ auto &TransferMap = MLocTransfer[CurBB];
+ auto Result = TransferMap.insert(std::make_pair(Idx.asU64(), P));
+ if (!Result.second)
+ Result.first->second = P;
+ }
+
+ // Accumulate any bitmask operands into the clobberred reg mask for this
+ // block.
+ for (auto &P : MTracker->Masks) {
+ BlockMasks[CurBB].clearBitsNotInMask(P.first->getRegMask(), BVWords);
+ }
+ }
+
+ // Compute a bitvector of all the registers that are tracked in this block.
+ const TargetLowering *TLI = MF.getSubtarget().getTargetLowering();
+ Register SP = TLI->getStackPointerRegisterToSaveRestore();
+ BitVector UsedRegs(TRI->getNumRegs());
+ for (auto Location : MTracker->locations()) {
+ unsigned ID = MTracker->LocIdxToLocID[Location.Idx];
+ if (ID >= TRI->getNumRegs() || ID == SP)
+ continue;
+ UsedRegs.set(ID);
+ }
+
+ // Check that any regmask-clobber of a register that gets tracked, is not
+ // live-through in the transfer function. It needs to be clobbered at the
+ // very least.
+ for (unsigned int I = 0; I < MaxNumBlocks; ++I) {
+ BitVector &BV = BlockMasks[I];
+ BV.flip();
+ BV &= UsedRegs;
+ // This produces all the bits that we clobber, but also use. Check that
+ // they're all clobbered or at least set in the designated transfer
+ // elem.
+ for (unsigned Bit : BV.set_bits()) {
+ unsigned ID = MTracker->getLocID(Bit, false);
+ LocIdx Idx = MTracker->LocIDToLocIdx[ID];
+ auto &TransferMap = MLocTransfer[I];
+
+ // Install a value representing the fact that this location is effectively
+ // written to in this block. As there's no reserved value, instead use
+ // a value number that is never generated. Pick the value number for the
+ // first instruction in the block, def'ing this location, which we know
+ // this block never used anyway.
+ ValueIDNum NotGeneratedNum = ValueIDNum(I, 1, Idx);
+ auto Result =
+ TransferMap.insert(std::make_pair(Idx.asU64(), NotGeneratedNum));
+ if (!Result.second) {
+ ValueIDNum &ValueID = Result.first->second;
+ if (ValueID.getBlock() == I && ValueID.isPHI())
+ // It was left as live-through. Set it to clobbered.
+ ValueID = NotGeneratedNum;
+ }
+ }
+ }
+}
+
+std::tuple<bool, bool>
+InstrRefBasedLDV::mlocJoin(MachineBasicBlock &MBB,
+ SmallPtrSet<const MachineBasicBlock *, 16> &Visited,
+ ValueIDNum **OutLocs, ValueIDNum *InLocs) {
+ LLVM_DEBUG(dbgs() << "join MBB: " << MBB.getNumber() << "\n");
+ bool Changed = false;
+ bool DowngradeOccurred = false;
+
+ // Collect predecessors that have been visited. Anything that hasn't been
+ // visited yet is a backedge on the first iteration, and the meet of it's
+ // lattice value for all locations will be unaffected.
+ SmallVector<const MachineBasicBlock *, 8> BlockOrders;
+ for (auto Pred : MBB.predecessors()) {
+ if (Visited.count(Pred)) {
+ BlockOrders.push_back(Pred);
+ }
+ }
+
+ // Visit predecessors in RPOT order.
+ auto Cmp = [&](const MachineBasicBlock *A, const MachineBasicBlock *B) {
+ return BBToOrder.find(A)->second < BBToOrder.find(B)->second;
+ };
+ llvm::sort(BlockOrders, Cmp);
+
+ // Skip entry block.
+ if (BlockOrders.size() == 0)
+ return std::tuple<bool, bool>(false, false);
+
+ // Step through all machine locations, then look at each predecessor and
+ // detect disagreements.
+ unsigned ThisBlockRPO = BBToOrder.find(&MBB)->second;
+ for (auto Location : MTracker->locations()) {
+ LocIdx Idx = Location.Idx;
+ // Pick out the first predecessors live-out value for this location. It's
+ // guaranteed to be not a backedge, as we order by RPO.
+ ValueIDNum BaseVal = OutLocs[BlockOrders[0]->getNumber()][Idx.asU64()];
+
+ // Some flags for whether there's a disagreement, and whether it's a
+ // disagreement with a backedge or not.
+ bool Disagree = false;
+ bool NonBackEdgeDisagree = false;
+
+ // Loop around everything that wasn't 'base'.
+ for (unsigned int I = 1; I < BlockOrders.size(); ++I) {
+ auto *MBB = BlockOrders[I];
+ if (BaseVal != OutLocs[MBB->getNumber()][Idx.asU64()]) {
+ // Live-out of a predecessor disagrees with the first predecessor.
+ Disagree = true;
+
+ // Test whether it's a disagreemnt in the backedges or not.
+ if (BBToOrder.find(MBB)->second < ThisBlockRPO) // might be self b/e
+ NonBackEdgeDisagree = true;
+ }
+ }
+
+ bool OverRide = false;
+ if (Disagree && !NonBackEdgeDisagree) {
+ // Only the backedges disagree. Consider demoting the livein
+ // lattice value, as per the file level comment. The value we consider
+ // demoting to is the value that the non-backedge predecessors agree on.
+ // The order of values is that non-PHIs are \top, a PHI at this block
+ // \bot, and phis between the two are ordered by their RPO number.
+ // If there's no agreement, or we've already demoted to this PHI value
+ // before, replace with a PHI value at this block.
+
+ // Calculate order numbers: zero means normal def, nonzero means RPO
+ // number.
+ unsigned BaseBlockRPONum = BBNumToRPO[BaseVal.getBlock()] + 1;
+ if (!BaseVal.isPHI())
+ BaseBlockRPONum = 0;
+
+ ValueIDNum &InLocID = InLocs[Idx.asU64()];
+ unsigned InLocRPONum = BBNumToRPO[InLocID.getBlock()] + 1;
+ if (!InLocID.isPHI())
+ InLocRPONum = 0;
+
+ // Should we ignore the disagreeing backedges, and override with the
+ // value the other predecessors agree on (in "base")?
+ unsigned ThisBlockRPONum = BBNumToRPO[MBB.getNumber()] + 1;
+ if (BaseBlockRPONum > InLocRPONum && BaseBlockRPONum < ThisBlockRPONum) {
+ // Override.
+ OverRide = true;
+ DowngradeOccurred = true;
+ }
+ }
+ // else: if we disagree in the non-backedges, then this is definitely
+ // a control flow merge where different values merge. Make it a PHI.
+
+ // Generate a phi...
+ ValueIDNum PHI = {(uint64_t)MBB.getNumber(), 0, Idx};
+ ValueIDNum NewVal = (Disagree && !OverRide) ? PHI : BaseVal;
+ if (InLocs[Idx.asU64()] != NewVal) {
+ Changed |= true;
+ InLocs[Idx.asU64()] = NewVal;
+ }
+ }
+
+ // TODO: Reimplement NumInserted and NumRemoved.
+ return std::tuple<bool, bool>(Changed, DowngradeOccurred);
+}
+
+void InstrRefBasedLDV::mlocDataflow(
+ ValueIDNum **MInLocs, ValueIDNum **MOutLocs,
+ SmallVectorImpl<MLocTransferMap> &MLocTransfer) {
+ std::priority_queue<unsigned int, std::vector<unsigned int>,
+ std::greater<unsigned int>>
+ Worklist, Pending;
+
+ // We track what is on the current and pending worklist to avoid inserting
+ // the same thing twice. We could avoid this with a custom priority queue,
+ // but this is probably not worth it.
+ SmallPtrSet<MachineBasicBlock *, 16> OnPending, OnWorklist;
+
+ // Initialize worklist with every block to be visited.
+ for (unsigned int I = 0; I < BBToOrder.size(); ++I) {
+ Worklist.push(I);
+ OnWorklist.insert(OrderToBB[I]);
+ }
+
+ MTracker->reset();
+
+ // Set inlocs for entry block -- each as a PHI at the entry block. Represents
+ // the incoming value to the function.
+ MTracker->setMPhis(0);
+ for (auto Location : MTracker->locations())
+ MInLocs[0][Location.Idx.asU64()] = Location.Value;
+
+ SmallPtrSet<const MachineBasicBlock *, 16> Visited;
+ while (!Worklist.empty() || !Pending.empty()) {
+ // Vector for storing the evaluated block transfer function.
+ SmallVector<std::pair<LocIdx, ValueIDNum>, 32> ToRemap;
+
+ while (!Worklist.empty()) {
+ MachineBasicBlock *MBB = OrderToBB[Worklist.top()];
+ CurBB = MBB->getNumber();
+ Worklist.pop();
+
+ // Join the values in all predecessor blocks.
+ bool InLocsChanged, DowngradeOccurred;
+ std::tie(InLocsChanged, DowngradeOccurred) =
+ mlocJoin(*MBB, Visited, MOutLocs, MInLocs[CurBB]);
+ InLocsChanged |= Visited.insert(MBB).second;
+
+ // If a downgrade occurred, book us in for re-examination on the next
+ // iteration.
+ if (DowngradeOccurred && OnPending.insert(MBB).second)
+ Pending.push(BBToOrder[MBB]);
+
+ // Don't examine transfer function if we've visited this loc at least
+ // once, and inlocs haven't changed.
+ if (!InLocsChanged)
+ continue;
+
+ // Load the current set of live-ins into MLocTracker.
+ MTracker->loadFromArray(MInLocs[CurBB], CurBB);
+
+ // Each element of the transfer function can be a new def, or a read of
+ // a live-in value. Evaluate each element, and store to "ToRemap".
+ ToRemap.clear();
+ for (auto &P : MLocTransfer[CurBB]) {
+ if (P.second.getBlock() == CurBB && P.second.isPHI()) {
+ // This is a movement of whatever was live in. Read it.
+ ValueIDNum NewID = MTracker->getNumAtPos(P.second.getLoc());
+ ToRemap.push_back(std::make_pair(P.first, NewID));
+ } else {
+ // It's a def. Just set it.
+ assert(P.second.getBlock() == CurBB);
+ ToRemap.push_back(std::make_pair(P.first, P.second));
+ }
+ }
+
+ // Commit the transfer function changes into mloc tracker, which
+ // transforms the contents of the MLocTracker into the live-outs.
+ for (auto &P : ToRemap)
+ MTracker->setMLoc(P.first, P.second);
+
+ // Now copy out-locs from mloc tracker into out-loc vector, checking
+ // whether changes have occurred. These changes can have come from both
+ // the transfer function, and mlocJoin.
+ bool OLChanged = false;
+ for (auto Location : MTracker->locations()) {
+ OLChanged |= MOutLocs[CurBB][Location.Idx.asU64()] != Location.Value;
+ MOutLocs[CurBB][Location.Idx.asU64()] = Location.Value;
+ }
+
+ MTracker->reset();
+
+ // No need to examine successors again if out-locs didn't change.
+ if (!OLChanged)
+ continue;
+
+ // All successors should be visited: put any back-edges on the pending
+ // list for the next dataflow iteration, and any other successors to be
+ // visited this iteration, if they're not going to be already.
+ for (auto s : MBB->successors()) {
+ // Does branching to this successor represent a back-edge?
+ if (BBToOrder[s] > BBToOrder[MBB]) {
+ // No: visit it during this dataflow iteration.
+ if (OnWorklist.insert(s).second)
+ Worklist.push(BBToOrder[s]);
+ } else {
+ // Yes: visit it on the next iteration.
+ if (OnPending.insert(s).second)
+ Pending.push(BBToOrder[s]);
+ }
+ }
+ }
+
+ Worklist.swap(Pending);
+ std::swap(OnPending, OnWorklist);
+ OnPending.clear();
+ // At this point, pending must be empty, since it was just the empty
+ // worklist
+ assert(Pending.empty() && "Pending should be empty");
+ }
+
+ // Once all the live-ins don't change on mlocJoin(), we've reached a
+ // fixedpoint.
+}
+
+bool InstrRefBasedLDV::vlocDowngradeLattice(
+ const MachineBasicBlock &MBB, const DbgValue &OldLiveInLocation,
+ const SmallVectorImpl<InValueT> &Values, unsigned CurBlockRPONum) {
+ // Ranking value preference: see file level comment, the highest rank is
+ // a plain def, followed by PHI values in reverse post-order. Numerically,
+ // we assign all defs the rank '0', all PHIs their blocks RPO number plus
+ // one, and consider the lowest value the highest ranked.
+ int OldLiveInRank = BBNumToRPO[OldLiveInLocation.ID.getBlock()] + 1;
+ if (!OldLiveInLocation.ID.isPHI())
+ OldLiveInRank = 0;
+
+ // Allow any unresolvable conflict to be over-ridden.
+ if (OldLiveInLocation.Kind == DbgValue::NoVal) {
+ // Although if it was an unresolvable conflict from _this_ block, then
+ // all other seeking of downgrades and PHIs must have failed before hand.
+ if (OldLiveInLocation.BlockNo == (unsigned)MBB.getNumber())
+ return false;
+ OldLiveInRank = INT_MIN;
+ }
+
+ auto &InValue = *Values[0].second;
+
+ if (InValue.Kind == DbgValue::Const || InValue.Kind == DbgValue::NoVal)
+ return false;
+
+ unsigned ThisRPO = BBNumToRPO[InValue.ID.getBlock()];
+ int ThisRank = ThisRPO + 1;
+ if (!InValue.ID.isPHI())
+ ThisRank = 0;
+
+ // Too far down the lattice?
+ if (ThisRPO >= CurBlockRPONum)
+ return false;
+
+ // Higher in the lattice than what we've already explored?
+ if (ThisRank <= OldLiveInRank)
+ return false;
+
+ return true;
+}
+
+std::tuple<Optional<ValueIDNum>, bool> InstrRefBasedLDV::pickVPHILoc(
+ MachineBasicBlock &MBB, const DebugVariable &Var, const LiveIdxT &LiveOuts,
+ ValueIDNum **MOutLocs, ValueIDNum **MInLocs,
+ const SmallVectorImpl<MachineBasicBlock *> &BlockOrders) {
+ // Collect a set of locations from predecessor where its live-out value can
+ // be found.
+ SmallVector<SmallVector<LocIdx, 4>, 8> Locs;
+ unsigned NumLocs = MTracker->getNumLocs();
+ unsigned BackEdgesStart = 0;
+
+ for (auto p : BlockOrders) {
+ // Pick out where backedges start in the list of predecessors. Relies on
+ // BlockOrders being sorted by RPO.
+ if (BBToOrder[p] < BBToOrder[&MBB])
+ ++BackEdgesStart;
+
+ // For each predecessor, create a new set of locations.
+ Locs.resize(Locs.size() + 1);
+ unsigned ThisBBNum = p->getNumber();
+ auto LiveOutMap = LiveOuts.find(p);
+ if (LiveOutMap == LiveOuts.end())
+ // This predecessor isn't in scope, it must have no live-in/live-out
+ // locations.
+ continue;
+
+ auto It = LiveOutMap->second->find(Var);
+ if (It == LiveOutMap->second->end())
+ // There's no value recorded for this variable in this predecessor,
+ // leave an empty set of locations.
+ continue;
+
+ const DbgValue &OutVal = It->second;
+
+ if (OutVal.Kind == DbgValue::Const || OutVal.Kind == DbgValue::NoVal)
+ // Consts and no-values cannot have locations we can join on.
+ continue;
+
+ assert(OutVal.Kind == DbgValue::Proposed || OutVal.Kind == DbgValue::Def);
+ ValueIDNum ValToLookFor = OutVal.ID;
+
+ // Search the live-outs of the predecessor for the specified value.
+ for (unsigned int I = 0; I < NumLocs; ++I) {
+ if (MOutLocs[ThisBBNum][I] == ValToLookFor)
+ Locs.back().push_back(LocIdx(I));
+ }
+ }
+
+ // If there were no locations at all, return an empty result.
+ if (Locs.empty())
+ return std::tuple<Optional<ValueIDNum>, bool>(None, false);
+
+ // Lambda for seeking a common location within a range of location-sets.
+ using LocsIt = SmallVector<SmallVector<LocIdx, 4>, 8>::iterator;
+ auto SeekLocation =
+ [&Locs](llvm::iterator_range<LocsIt> SearchRange) -> Optional<LocIdx> {
+ // Starting with the first set of locations, take the intersection with
+ // subsequent sets.
+ SmallVector<LocIdx, 4> base = Locs[0];
+ for (auto &S : SearchRange) {
+ SmallVector<LocIdx, 4> new_base;
+ std::set_intersection(base.begin(), base.end(), S.begin(), S.end(),
+ std::inserter(new_base, new_base.begin()));
+ base = new_base;
+ }
+ if (base.empty())
+ return None;
+
+ // We now have a set of LocIdxes that contain the right output value in
+ // each of the predecessors. Pick the lowest; if there's a register loc,
+ // that'll be it.
+ return *base.begin();
+ };
+
+ // Search for a common location for all predecessors. If we can't, then fall
+ // back to only finding a common location between non-backedge predecessors.
+ bool ValidForAllLocs = true;
+ auto TheLoc = SeekLocation(Locs);
+ if (!TheLoc) {
+ ValidForAllLocs = false;
+ TheLoc =
+ SeekLocation(make_range(Locs.begin(), Locs.begin() + BackEdgesStart));
+ }
+
+ if (!TheLoc)
+ return std::tuple<Optional<ValueIDNum>, bool>(None, false);
+
+ // Return a PHI-value-number for the found location.
+ LocIdx L = *TheLoc;
+ ValueIDNum PHIVal = {(unsigned)MBB.getNumber(), 0, L};
+ return std::tuple<Optional<ValueIDNum>, bool>(PHIVal, ValidForAllLocs);
+}
+
+std::tuple<bool, bool> InstrRefBasedLDV::vlocJoin(
+ MachineBasicBlock &MBB, LiveIdxT &VLOCOutLocs, LiveIdxT &VLOCInLocs,
+ SmallPtrSet<const MachineBasicBlock *, 16> *VLOCVisited, unsigned BBNum,
+ const SmallSet<DebugVariable, 4> &AllVars, ValueIDNum **MOutLocs,
+ ValueIDNum **MInLocs,
+ SmallPtrSet<const MachineBasicBlock *, 8> &InScopeBlocks,
+ SmallPtrSet<const MachineBasicBlock *, 8> &BlocksToExplore,
+ DenseMap<DebugVariable, DbgValue> &InLocsT) {
+ bool DowngradeOccurred = false;
+
+ // To emulate VarLocBasedImpl, process this block if it's not in scope but
+ // _does_ assign a variable value. No live-ins for this scope are transferred
+ // in though, so we can return immediately.
+ if (InScopeBlocks.count(&MBB) == 0 && !ArtificialBlocks.count(&MBB)) {
+ if (VLOCVisited)
+ return std::tuple<bool, bool>(true, false);
+ return std::tuple<bool, bool>(false, false);
+ }
+
+ LLVM_DEBUG(dbgs() << "join MBB: " << MBB.getNumber() << "\n");
+ bool Changed = false;
+
+ // Find any live-ins computed in a prior iteration.
+ auto ILSIt = VLOCInLocs.find(&MBB);
+ assert(ILSIt != VLOCInLocs.end());
+ auto &ILS = *ILSIt->second;
+
+ // Order predecessors by RPOT order, for exploring them in that order.
+ SmallVector<MachineBasicBlock *, 8> BlockOrders;
+ for (auto p : MBB.predecessors())
+ BlockOrders.push_back(p);
+
+ auto Cmp = [&](MachineBasicBlock *A, MachineBasicBlock *B) {
+ return BBToOrder[A] < BBToOrder[B];
+ };
+
+ llvm::sort(BlockOrders, Cmp);
+
+ unsigned CurBlockRPONum = BBToOrder[&MBB];
+
+ // Force a re-visit to loop heads in the first dataflow iteration.
+ // FIXME: if we could "propose" Const values this wouldn't be needed,
+ // because they'd need to be confirmed before being emitted.
+ if (!BlockOrders.empty() &&
+ BBToOrder[BlockOrders[BlockOrders.size() - 1]] >= CurBlockRPONum &&
+ VLOCVisited)
+ DowngradeOccurred = true;
+
+ auto ConfirmValue = [&InLocsT](const DebugVariable &DV, DbgValue VR) {
+ auto Result = InLocsT.insert(std::make_pair(DV, VR));
+ (void)Result;
+ assert(Result.second);
+ };
+
+ auto ConfirmNoVal = [&ConfirmValue, &MBB](const DebugVariable &Var, const DbgValueProperties &Properties) {
+ DbgValue NoLocPHIVal(MBB.getNumber(), Properties, DbgValue::NoVal);
+
+ ConfirmValue(Var, NoLocPHIVal);
+ };
+
+ // Attempt to join the values for each variable.
+ for (auto &Var : AllVars) {
+ // Collect all the DbgValues for this variable.
+ SmallVector<InValueT, 8> Values;
+ bool Bail = false;
+ unsigned BackEdgesStart = 0;
+ for (auto p : BlockOrders) {
+ // If the predecessor isn't in scope / to be explored, we'll never be
+ // able to join any locations.
+ if (!BlocksToExplore.contains(p)) {
+ Bail = true;
+ break;
+ }
+
+ // Don't attempt to handle unvisited predecessors: they're implicitly
+ // "unknown"s in the lattice.
+ if (VLOCVisited && !VLOCVisited->count(p))
+ continue;
+
+ // If the predecessors OutLocs is absent, there's not much we can do.
+ auto OL = VLOCOutLocs.find(p);
+ if (OL == VLOCOutLocs.end()) {
+ Bail = true;
+ break;
+ }
+
+ // No live-out value for this predecessor also means we can't produce
+ // a joined value.
+ auto VIt = OL->second->find(Var);
+ if (VIt == OL->second->end()) {
+ Bail = true;
+ break;
+ }
+
+ // Keep track of where back-edges begin in the Values vector. Relies on
+ // BlockOrders being sorted by RPO.
+ unsigned ThisBBRPONum = BBToOrder[p];
+ if (ThisBBRPONum < CurBlockRPONum)
+ ++BackEdgesStart;
+
+ Values.push_back(std::make_pair(p, &VIt->second));
+ }
+
+ // If there were no values, or one of the predecessors couldn't have a
+ // value, then give up immediately. It's not safe to produce a live-in
+ // value.
+ if (Bail || Values.size() == 0)
+ continue;
+
+ // Enumeration identifying the current state of the predecessors values.
+ enum {
+ Unset = 0,
+ Agreed, // All preds agree on the variable value.
+ PropDisagree, // All preds agree, but the value kind is Proposed in some.
+ BEDisagree, // Only back-edges disagree on variable value.
+ PHINeeded, // Non-back-edge predecessors have conflicing values.
+ NoSolution // Conflicting Value metadata makes solution impossible.
+ } OurState = Unset;
+
+ // All (non-entry) blocks have at least one non-backedge predecessor.
+ // Pick the variable value from the first of these, to compare against
+ // all others.
+ const DbgValue &FirstVal = *Values[0].second;
+ const ValueIDNum &FirstID = FirstVal.ID;
+
+ // Scan for variable values that can't be resolved: if they have different
+ // DIExpressions, different indirectness, or are mixed constants /
+ // non-constants.
+ for (auto &V : Values) {
+ if (V.second->Properties != FirstVal.Properties)
+ OurState = NoSolution;
+ if (V.second->Kind == DbgValue::Const && FirstVal.Kind != DbgValue::Const)
+ OurState = NoSolution;
+ }
+
+ // Flags diagnosing _how_ the values disagree.
+ bool NonBackEdgeDisagree = false;
+ bool DisagreeOnPHINess = false;
+ bool IDDisagree = false;
+ bool Disagree = false;
+ if (OurState == Unset) {
+ for (auto &V : Values) {
+ if (*V.second == FirstVal)
+ continue; // No disagreement.
+
+ Disagree = true;
+
+ // Flag whether the value number actually diagrees.
+ if (V.second->ID != FirstID)
+ IDDisagree = true;
+
+ // Distinguish whether disagreement happens in backedges or not.
+ // Relies on Values (and BlockOrders) being sorted by RPO.
+ unsigned ThisBBRPONum = BBToOrder[V.first];
+ if (ThisBBRPONum < CurBlockRPONum)
+ NonBackEdgeDisagree = true;
+
+ // Is there a difference in whether the value is definite or only
+ // proposed?
+ if (V.second->Kind != FirstVal.Kind &&
+ (V.second->Kind == DbgValue::Proposed ||
+ V.second->Kind == DbgValue::Def) &&
+ (FirstVal.Kind == DbgValue::Proposed ||
+ FirstVal.Kind == DbgValue::Def))
+ DisagreeOnPHINess = true;
+ }
+
+ // Collect those flags together and determine an overall state for
+ // what extend the predecessors agree on a live-in value.
+ if (!Disagree)
+ OurState = Agreed;
+ else if (!IDDisagree && DisagreeOnPHINess)
+ OurState = PropDisagree;
+ else if (!NonBackEdgeDisagree)
+ OurState = BEDisagree;
+ else
+ OurState = PHINeeded;
+ }
+
+ // An extra indicator: if we only disagree on whether the value is a
+ // Def, or proposed, then also flag whether that disagreement happens
+ // in backedges only.
+ bool PropOnlyInBEs = Disagree && !IDDisagree && DisagreeOnPHINess &&
+ !NonBackEdgeDisagree && FirstVal.Kind == DbgValue::Def;
+
+ const auto &Properties = FirstVal.Properties;
+
+ auto OldLiveInIt = ILS.find(Var);
+ const DbgValue *OldLiveInLocation =
+ (OldLiveInIt != ILS.end()) ? &OldLiveInIt->second : nullptr;
+
+ bool OverRide = false;
+ if (OurState == BEDisagree && OldLiveInLocation) {
+ // Only backedges disagree: we can consider downgrading. If there was a
+ // previous live-in value, use it to work out whether the current
+ // incoming value represents a lattice downgrade or not.
+ OverRide =
+ vlocDowngradeLattice(MBB, *OldLiveInLocation, Values, CurBlockRPONum);
+ }
+
+ // Use the current state of predecessor agreement and other flags to work
+ // out what to do next. Possibilities include:
+ // * Accept a value all predecessors agree on, or accept one that
+ // represents a step down the exploration lattice,
+ // * Use a PHI value number, if one can be found,
+ // * Propose a PHI value number, and see if it gets confirmed later,
+ // * Emit a 'NoVal' value, indicating we couldn't resolve anything.
+ if (OurState == Agreed) {
+ // Easiest solution: all predecessors agree on the variable value.
+ ConfirmValue(Var, FirstVal);
+ } else if (OurState == BEDisagree && OverRide) {
+ // Only backedges disagree, and the other predecessors have produced
+ // a new live-in value further down the exploration lattice.
+ DowngradeOccurred = true;
+ ConfirmValue(Var, FirstVal);
+ } else if (OurState == PropDisagree) {
+ // Predecessors agree on value, but some say it's only a proposed value.
+ // Propagate it as proposed: unless it was proposed in this block, in
+ // which case we're able to confirm the value.
+ if (FirstID.getBlock() == (uint64_t)MBB.getNumber() && FirstID.isPHI()) {
+ ConfirmValue(Var, DbgValue(FirstID, Properties, DbgValue::Def));
+ } else if (PropOnlyInBEs) {
+ // If only backedges disagree, a higher (in RPO) block confirmed this
+ // location, and we need to propagate it into this loop.
+ ConfirmValue(Var, DbgValue(FirstID, Properties, DbgValue::Def));
+ } else {
+ // Otherwise; a Def meeting a Proposed is still a Proposed.
+ ConfirmValue(Var, DbgValue(FirstID, Properties, DbgValue::Proposed));
+ }
+ } else if ((OurState == PHINeeded || OurState == BEDisagree)) {
+ // Predecessors disagree and can't be downgraded: this can only be
+ // solved with a PHI. Use pickVPHILoc to go look for one.
+ Optional<ValueIDNum> VPHI;
+ bool AllEdgesVPHI = false;
+ std::tie(VPHI, AllEdgesVPHI) =
+ pickVPHILoc(MBB, Var, VLOCOutLocs, MOutLocs, MInLocs, BlockOrders);
+
+ if (VPHI && AllEdgesVPHI) {
+ // There's a PHI value that's valid for all predecessors -- we can use
+ // it. If any of the non-backedge predecessors have proposed values
+ // though, this PHI is also only proposed, until the predecessors are
+ // confirmed.
+ DbgValue::KindT K = DbgValue::Def;
+ for (unsigned int I = 0; I < BackEdgesStart; ++I)
+ if (Values[I].second->Kind == DbgValue::Proposed)
+ K = DbgValue::Proposed;
+
+ ConfirmValue(Var, DbgValue(*VPHI, Properties, K));
+ } else if (VPHI) {
+ // There's a PHI value, but it's only legal for backedges. Leave this
+ // as a proposed PHI value: it might come back on the backedges,
+ // and allow us to confirm it in the future.
+ DbgValue NoBEValue = DbgValue(*VPHI, Properties, DbgValue::Proposed);
+ ConfirmValue(Var, NoBEValue);
+ } else {
+ ConfirmNoVal(Var, Properties);
+ }
+ } else {
+ // Otherwise: we don't know. Emit a "phi but no real loc" phi.
+ ConfirmNoVal(Var, Properties);
+ }
+ }
+
+ // Store newly calculated in-locs into VLOCInLocs, if they've changed.
+ Changed = ILS != InLocsT;
+ if (Changed)
+ ILS = InLocsT;
+
+ return std::tuple<bool, bool>(Changed, DowngradeOccurred);
+}
+
+void InstrRefBasedLDV::vlocDataflow(
+ const LexicalScope *Scope, const DILocation *DILoc,
+ const SmallSet<DebugVariable, 4> &VarsWeCareAbout,
+ SmallPtrSetImpl<MachineBasicBlock *> &AssignBlocks, LiveInsT &Output,
+ ValueIDNum **MOutLocs, ValueIDNum **MInLocs,
+ SmallVectorImpl<VLocTracker> &AllTheVLocs) {
+ // This method is much like mlocDataflow: but focuses on a single
+ // LexicalScope at a time. Pick out a set of blocks and variables that are
+ // to have their value assignments solved, then run our dataflow algorithm
+ // until a fixedpoint is reached.
+ std::priority_queue<unsigned int, std::vector<unsigned int>,
+ std::greater<unsigned int>>
+ Worklist, Pending;
+ SmallPtrSet<MachineBasicBlock *, 16> OnWorklist, OnPending;
+
+ // The set of blocks we'll be examining.
+ SmallPtrSet<const MachineBasicBlock *, 8> BlocksToExplore;
+
+ // The order in which to examine them (RPO).
+ SmallVector<MachineBasicBlock *, 8> BlockOrders;
+
+ // RPO ordering function.
+ auto Cmp = [&](MachineBasicBlock *A, MachineBasicBlock *B) {
+ return BBToOrder[A] < BBToOrder[B];
+ };
+
+ LS.getMachineBasicBlocks(DILoc, BlocksToExplore);
+
+ // A separate container to distinguish "blocks we're exploring" versus
+ // "blocks that are potentially in scope. See comment at start of vlocJoin.
+ SmallPtrSet<const MachineBasicBlock *, 8> InScopeBlocks = BlocksToExplore;
+
+ // Old LiveDebugValues tracks variable locations that come out of blocks
+ // not in scope, where DBG_VALUEs occur. This is something we could
+ // legitimately ignore, but lets allow it for now.
+ if (EmulateOldLDV)
+ BlocksToExplore.insert(AssignBlocks.begin(), AssignBlocks.end());
+
+ // We also need to propagate variable values through any artificial blocks
+ // that immediately follow blocks in scope.
+ DenseSet<const MachineBasicBlock *> ToAdd;
+
+ // Helper lambda: For a given block in scope, perform a depth first search
+ // of all the artificial successors, adding them to the ToAdd collection.
+ auto AccumulateArtificialBlocks =
+ [this, &ToAdd, &BlocksToExplore,
+ &InScopeBlocks](const MachineBasicBlock *MBB) {
+ // Depth-first-search state: each node is a block and which successor
+ // we're currently exploring.
+ SmallVector<std::pair<const MachineBasicBlock *,
+ MachineBasicBlock::const_succ_iterator>,
+ 8>
+ DFS;
+
+ // Find any artificial successors not already tracked.
+ for (auto *succ : MBB->successors()) {
+ if (BlocksToExplore.count(succ) || InScopeBlocks.count(succ))
+ continue;
+ if (!ArtificialBlocks.count(succ))
+ continue;
+ DFS.push_back(std::make_pair(succ, succ->succ_begin()));
+ ToAdd.insert(succ);
+ }
+
+ // Search all those blocks, depth first.
+ while (!DFS.empty()) {
+ const MachineBasicBlock *CurBB = DFS.back().first;
+ MachineBasicBlock::const_succ_iterator &CurSucc = DFS.back().second;
+ // Walk back if we've explored this blocks successors to the end.
+ if (CurSucc == CurBB->succ_end()) {
+ DFS.pop_back();
+ continue;
+ }
+
+ // If the current successor is artificial and unexplored, descend into
+ // it.
+ if (!ToAdd.count(*CurSucc) && ArtificialBlocks.count(*CurSucc)) {
+ DFS.push_back(std::make_pair(*CurSucc, (*CurSucc)->succ_begin()));
+ ToAdd.insert(*CurSucc);
+ continue;
+ }
+
+ ++CurSucc;
+ }
+ };
+
+ // Search in-scope blocks and those containing a DBG_VALUE from this scope
+ // for artificial successors.
+ for (auto *MBB : BlocksToExplore)
+ AccumulateArtificialBlocks(MBB);
+ for (auto *MBB : InScopeBlocks)
+ AccumulateArtificialBlocks(MBB);
+
+ BlocksToExplore.insert(ToAdd.begin(), ToAdd.end());
+ InScopeBlocks.insert(ToAdd.begin(), ToAdd.end());
+
+ // Single block scope: not interesting! No propagation at all. Note that
+ // this could probably go above ArtificialBlocks without damage, but
+ // that then produces output differences from original-live-debug-values,
+ // which propagates from a single block into many artificial ones.
+ if (BlocksToExplore.size() == 1)
+ return;
+
+ // Picks out relevants blocks RPO order and sort them.
+ for (auto *MBB : BlocksToExplore)
+ BlockOrders.push_back(const_cast<MachineBasicBlock *>(MBB));
+
+ llvm::sort(BlockOrders, Cmp);
+ unsigned NumBlocks = BlockOrders.size();
+
+ // Allocate some vectors for storing the live ins and live outs. Large.
+ SmallVector<DenseMap<DebugVariable, DbgValue>, 32> LiveIns, LiveOuts;
+ LiveIns.resize(NumBlocks);
+ LiveOuts.resize(NumBlocks);
+
+ // Produce by-MBB indexes of live-in/live-outs, to ease lookup within
+ // vlocJoin.
+ LiveIdxT LiveOutIdx, LiveInIdx;
+ LiveOutIdx.reserve(NumBlocks);
+ LiveInIdx.reserve(NumBlocks);
+ for (unsigned I = 0; I < NumBlocks; ++I) {
+ LiveOutIdx[BlockOrders[I]] = &LiveOuts[I];
+ LiveInIdx[BlockOrders[I]] = &LiveIns[I];
+ }
+
+ for (auto *MBB : BlockOrders) {
+ Worklist.push(BBToOrder[MBB]);
+ OnWorklist.insert(MBB);
+ }
+
+ // Iterate over all the blocks we selected, propagating variable values.
+ bool FirstTrip = true;
+ SmallPtrSet<const MachineBasicBlock *, 16> VLOCVisited;
+ while (!Worklist.empty() || !Pending.empty()) {
+ while (!Worklist.empty()) {
+ auto *MBB = OrderToBB[Worklist.top()];
+ CurBB = MBB->getNumber();
+ Worklist.pop();
+
+ DenseMap<DebugVariable, DbgValue> JoinedInLocs;
+
+ // Join values from predecessors. Updates LiveInIdx, and writes output
+ // into JoinedInLocs.
+ bool InLocsChanged, DowngradeOccurred;
+ std::tie(InLocsChanged, DowngradeOccurred) = vlocJoin(
+ *MBB, LiveOutIdx, LiveInIdx, (FirstTrip) ? &VLOCVisited : nullptr,
+ CurBB, VarsWeCareAbout, MOutLocs, MInLocs, InScopeBlocks,
+ BlocksToExplore, JoinedInLocs);
+
+ bool FirstVisit = VLOCVisited.insert(MBB).second;
+
+ // Always explore transfer function if inlocs changed, or if we've not
+ // visited this block before.
+ InLocsChanged |= FirstVisit;
+
+ // If a downgrade occurred, book us in for re-examination on the next
+ // iteration.
+ if (DowngradeOccurred && OnPending.insert(MBB).second)
+ Pending.push(BBToOrder[MBB]);
+
+ if (!InLocsChanged)
+ continue;
+
+ // Do transfer function.
+ auto &VTracker = AllTheVLocs[MBB->getNumber()];
+ for (auto &Transfer : VTracker.Vars) {
+ // Is this var we're mangling in this scope?
+ if (VarsWeCareAbout.count(Transfer.first)) {
+ // Erase on empty transfer (DBG_VALUE $noreg).
+ if (Transfer.second.Kind == DbgValue::Undef) {
+ JoinedInLocs.erase(Transfer.first);
+ } else {
+ // Insert new variable value; or overwrite.
+ auto NewValuePair = std::make_pair(Transfer.first, Transfer.second);
+ auto Result = JoinedInLocs.insert(NewValuePair);
+ if (!Result.second)
+ Result.first->second = Transfer.second;
+ }
+ }
+ }
+
+ // Did the live-out locations change?
+ bool OLChanged = JoinedInLocs != *LiveOutIdx[MBB];
+
+ // If they haven't changed, there's no need to explore further.
+ if (!OLChanged)
+ continue;
+
+ // Commit to the live-out record.
+ *LiveOutIdx[MBB] = JoinedInLocs;
+
+ // We should visit all successors. Ensure we'll visit any non-backedge
+ // successors during this dataflow iteration; book backedge successors
+ // to be visited next time around.
+ for (auto s : MBB->successors()) {
+ // Ignore out of scope / not-to-be-explored successors.
+ if (LiveInIdx.find(s) == LiveInIdx.end())
+ continue;
+
+ if (BBToOrder[s] > BBToOrder[MBB]) {
+ if (OnWorklist.insert(s).second)
+ Worklist.push(BBToOrder[s]);
+ } else if (OnPending.insert(s).second && (FirstTrip || OLChanged)) {
+ Pending.push(BBToOrder[s]);
+ }
+ }
+ }
+ Worklist.swap(Pending);
+ std::swap(OnWorklist, OnPending);
+ OnPending.clear();
+ assert(Pending.empty());
+ FirstTrip = false;
+ }
+
+ // Dataflow done. Now what? Save live-ins. Ignore any that are still marked
+ // as being variable-PHIs, because those did not have their machine-PHI
+ // value confirmed. Such variable values are places that could have been
+ // PHIs, but are not.
+ for (auto *MBB : BlockOrders) {
+ auto &VarMap = *LiveInIdx[MBB];
+ for (auto &P : VarMap) {
+ if (P.second.Kind == DbgValue::Proposed ||
+ P.second.Kind == DbgValue::NoVal)
+ continue;
+ Output[MBB->getNumber()].push_back(P);
+ }
+ }
+
+ BlockOrders.clear();
+ BlocksToExplore.clear();
+}
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+void InstrRefBasedLDV::dump_mloc_transfer(
+ const MLocTransferMap &mloc_transfer) const {
+ for (auto &P : mloc_transfer) {
+ std::string foo = MTracker->LocIdxToName(P.first);
+ std::string bar = MTracker->IDAsString(P.second);
+ dbgs() << "Loc " << foo << " --> " << bar << "\n";
+ }
+}
+#endif
+
+void InstrRefBasedLDV::emitLocations(
+ MachineFunction &MF, LiveInsT SavedLiveIns, ValueIDNum **MInLocs,
+ DenseMap<DebugVariable, unsigned> &AllVarsNumbering) {
+ TTracker = new TransferTracker(TII, MTracker, MF, *TRI, CalleeSavedRegs);
+ unsigned NumLocs = MTracker->getNumLocs();
+
+ // For each block, load in the machine value locations and variable value
+ // live-ins, then step through each instruction in the block. New DBG_VALUEs
+ // to be inserted will be created along the way.
+ for (MachineBasicBlock &MBB : MF) {
+ unsigned bbnum = MBB.getNumber();
+ MTracker->reset();
+ MTracker->loadFromArray(MInLocs[bbnum], bbnum);
+ TTracker->loadInlocs(MBB, MInLocs[bbnum], SavedLiveIns[MBB.getNumber()],
+ NumLocs);
+
+ CurBB = bbnum;
+ CurInst = 1;
+ for (auto &MI : MBB) {
+ process(MI);
+ TTracker->checkInstForNewValues(CurInst, MI.getIterator());
+ ++CurInst;
+ }
+ }
+
+ // We have to insert DBG_VALUEs in a consistent order, otherwise they appeaer
+ // in DWARF in different orders. Use the order that they appear when walking
+ // through each block / each instruction, stored in AllVarsNumbering.
+ auto OrderDbgValues = [&](const MachineInstr *A,
+ const MachineInstr *B) -> bool {
+ DebugVariable VarA(A->getDebugVariable(), A->getDebugExpression(),
+ A->getDebugLoc()->getInlinedAt());
+ DebugVariable VarB(B->getDebugVariable(), B->getDebugExpression(),
+ B->getDebugLoc()->getInlinedAt());
+ return AllVarsNumbering.find(VarA)->second <
+ AllVarsNumbering.find(VarB)->second;
+ };
+
+ // Go through all the transfers recorded in the TransferTracker -- this is
+ // both the live-ins to a block, and any movements of values that happen
+ // in the middle.
+ for (auto &P : TTracker->Transfers) {
+ // Sort them according to appearance order.
+ llvm::sort(P.Insts, OrderDbgValues);
+ // Insert either before or after the designated point...
+ if (P.MBB) {
+ MachineBasicBlock &MBB = *P.MBB;
+ for (auto *MI : P.Insts) {
+ MBB.insert(P.Pos, MI);
+ }
+ } else {
+ MachineBasicBlock &MBB = *P.Pos->getParent();
+ for (auto *MI : P.Insts) {
+ MBB.insertAfter(P.Pos, MI);
+ }
+ }
+ }
+}
+
+void InstrRefBasedLDV::initialSetup(MachineFunction &MF) {
+ // Build some useful data structures.
+ auto hasNonArtificialLocation = [](const MachineInstr &MI) -> bool {
+ if (const DebugLoc &DL = MI.getDebugLoc())
+ return DL.getLine() != 0;
+ return false;
+ };
+ // Collect a set of all the artificial blocks.
+ for (auto &MBB : MF)
+ if (none_of(MBB.instrs(), hasNonArtificialLocation))
+ ArtificialBlocks.insert(&MBB);
+
+ // Compute mappings of block <=> RPO order.
+ ReversePostOrderTraversal<MachineFunction *> RPOT(&MF);
+ unsigned int RPONumber = 0;
+ for (auto RI = RPOT.begin(), RE = RPOT.end(); RI != RE; ++RI) {
+ OrderToBB[RPONumber] = *RI;
+ BBToOrder[*RI] = RPONumber;
+ BBNumToRPO[(*RI)->getNumber()] = RPONumber;
+ ++RPONumber;
+ }
+}
+
+/// Calculate the liveness information for the given machine function and
+/// extend ranges across basic blocks.
+bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF,
+ TargetPassConfig *TPC) {
+ // No subprogram means this function contains no debuginfo.
+ if (!MF.getFunction().getSubprogram())
+ return false;
+
+ LLVM_DEBUG(dbgs() << "\nDebug Range Extension\n");
+ this->TPC = TPC;
+
+ TRI = MF.getSubtarget().getRegisterInfo();
+ TII = MF.getSubtarget().getInstrInfo();
+ TFI = MF.getSubtarget().getFrameLowering();
+ TFI->getCalleeSaves(MF, CalleeSavedRegs);
+ LS.initialize(MF);
+
+ MTracker =
+ new MLocTracker(MF, *TII, *TRI, *MF.getSubtarget().getTargetLowering());
+ VTracker = nullptr;
+ TTracker = nullptr;
+
+ SmallVector<MLocTransferMap, 32> MLocTransfer;
+ SmallVector<VLocTracker, 8> vlocs;
+ LiveInsT SavedLiveIns;
+
+ int MaxNumBlocks = -1;
+ for (auto &MBB : MF)
+ MaxNumBlocks = std::max(MBB.getNumber(), MaxNumBlocks);
+ assert(MaxNumBlocks >= 0);
+ ++MaxNumBlocks;
+
+ MLocTransfer.resize(MaxNumBlocks);
+ vlocs.resize(MaxNumBlocks);
+ SavedLiveIns.resize(MaxNumBlocks);
+
+ initialSetup(MF);
+
+ produceMLocTransferFunction(MF, MLocTransfer, MaxNumBlocks);
+
+ // Allocate and initialize two array-of-arrays for the live-in and live-out
+ // machine values. The outer dimension is the block number; while the inner
+ // dimension is a LocIdx from MLocTracker.
+ ValueIDNum **MOutLocs = new ValueIDNum *[MaxNumBlocks];
+ ValueIDNum **MInLocs = new ValueIDNum *[MaxNumBlocks];
+ unsigned NumLocs = MTracker->getNumLocs();
+ for (int i = 0; i < MaxNumBlocks; ++i) {
+ MOutLocs[i] = new ValueIDNum[NumLocs];
+ MInLocs[i] = new ValueIDNum[NumLocs];
+ }
+
+ // Solve the machine value dataflow problem using the MLocTransfer function,
+ // storing the computed live-ins / live-outs into the array-of-arrays. We use
+ // both live-ins and live-outs for decision making in the variable value
+ // dataflow problem.
+ mlocDataflow(MInLocs, MOutLocs, MLocTransfer);
+
+ // Walk back through each block / instruction, collecting DBG_VALUE
+ // instructions and recording what machine value their operands refer to.
+ for (auto &OrderPair : OrderToBB) {
+ MachineBasicBlock &MBB = *OrderPair.second;
+ CurBB = MBB.getNumber();
+ VTracker = &vlocs[CurBB];
+ VTracker->MBB = &MBB;
+ MTracker->loadFromArray(MInLocs[CurBB], CurBB);
+ CurInst = 1;
+ for (auto &MI : MBB) {
+ process(MI);
+ ++CurInst;
+ }
+ MTracker->reset();
+ }
+
+ // Number all variables in the order that they appear, to be used as a stable
+ // insertion order later.
+ DenseMap<DebugVariable, unsigned> AllVarsNumbering;
+
+ // Map from one LexicalScope to all the variables in that scope.
+ DenseMap<const LexicalScope *, SmallSet<DebugVariable, 4>> ScopeToVars;
+
+ // Map from One lexical scope to all blocks in that scope.
+ DenseMap<const LexicalScope *, SmallPtrSet<MachineBasicBlock *, 4>>
+ ScopeToBlocks;
+
+ // Store a DILocation that describes a scope.
+ DenseMap<const LexicalScope *, const DILocation *> ScopeToDILocation;
+
+ // To mirror old LiveDebugValues, enumerate variables in RPOT order. Otherwise
+ // the order is unimportant, it just has to be stable.
+ for (unsigned int I = 0; I < OrderToBB.size(); ++I) {
+ auto *MBB = OrderToBB[I];
+ auto *VTracker = &vlocs[MBB->getNumber()];
+ // Collect each variable with a DBG_VALUE in this block.
+ for (auto &idx : VTracker->Vars) {
+ const auto &Var = idx.first;
+ const DILocation *ScopeLoc = VTracker->Scopes[Var];
+ assert(ScopeLoc != nullptr);
+ auto *Scope = LS.findLexicalScope(ScopeLoc);
+
+ // No insts in scope -> shouldn't have been recorded.
+ assert(Scope != nullptr);
+
+ AllVarsNumbering.insert(std::make_pair(Var, AllVarsNumbering.size()));
+ ScopeToVars[Scope].insert(Var);
+ ScopeToBlocks[Scope].insert(VTracker->MBB);
+ ScopeToDILocation[Scope] = ScopeLoc;
+ }
+ }
+
+ // OK. Iterate over scopes: there might be something to be said for
+ // ordering them by size/locality, but that's for the future. For each scope,
+ // solve the variable value problem, producing a map of variables to values
+ // in SavedLiveIns.
+ for (auto &P : ScopeToVars) {
+ vlocDataflow(P.first, ScopeToDILocation[P.first], P.second,
+ ScopeToBlocks[P.first], SavedLiveIns, MOutLocs, MInLocs,
+ vlocs);
+ }
+
+ // Using the computed value locations and variable values for each block,
+ // create the DBG_VALUE instructions representing the extended variable
+ // locations.
+ emitLocations(MF, SavedLiveIns, MInLocs, AllVarsNumbering);
+
+ for (int Idx = 0; Idx < MaxNumBlocks; ++Idx) {
+ delete[] MOutLocs[Idx];
+ delete[] MInLocs[Idx];
+ }
+ delete[] MOutLocs;
+ delete[] MInLocs;
+
+ // Did we actually make any changes? If we created any DBG_VALUEs, then yes.
+ bool Changed = TTracker->Transfers.size() != 0;
+
+ delete MTracker;
+ delete TTracker;
+ MTracker = nullptr;
+ VTracker = nullptr;
+ TTracker = nullptr;
+
+ ArtificialBlocks.clear();
+ OrderToBB.clear();
+ BBToOrder.clear();
+ BBNumToRPO.clear();
+ DebugInstrNumToInstr.clear();
+
+ return Changed;
+}
+
+LDVImpl *llvm::makeInstrRefBasedLiveDebugValues() {
+ return new InstrRefBasedLDV();
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp b/contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp
index 943076ec74..770c46ec84 100644
--- a/contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp
@@ -1,97 +1,97 @@
-//===- LiveDebugValues.cpp - Tracking Debug Value MIs ---------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "LiveDebugValues.h"
-
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Pass.h"
-#include "llvm/Target/TargetMachine.h"
-
-/// \file LiveDebugValues.cpp
-///
-/// The LiveDebugValues pass extends the range of variable locations
-/// (specified by DBG_VALUE instructions) from single blocks to successors
-/// and any other code locations where the variable location is valid.
-/// There are currently two implementations: the "VarLoc" implementation
-/// explicitly tracks the location of a variable, while the "InstrRef"
-/// implementation tracks the values defined by instructions through locations.
-///
-/// This file implements neither; it merely registers the pass, allows the
-/// user to pick which implementation will be used to propagate variable
-/// locations.
-
-#define DEBUG_TYPE "livedebugvalues"
-
-using namespace llvm;
-
-/// Generic LiveDebugValues pass. Calls through to VarLocBasedLDV or
-/// InstrRefBasedLDV to perform location propagation, via the LDVImpl
-/// base class.
-class LiveDebugValues : public MachineFunctionPass {
-public:
- static char ID;
-
- LiveDebugValues();
- ~LiveDebugValues() {
- if (TheImpl)
- delete TheImpl;
- }
-
- /// Calculate the liveness information for the given machine function.
- bool runOnMachineFunction(MachineFunction &MF) override;
-
- MachineFunctionProperties getRequiredProperties() const override {
- return MachineFunctionProperties().set(
- MachineFunctionProperties::Property::NoVRegs);
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesCFG();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
-
-private:
- LDVImpl *TheImpl;
- TargetPassConfig *TPC;
-};
-
-char LiveDebugValues::ID = 0;
-
-char &llvm::LiveDebugValuesID = LiveDebugValues::ID;
-
-INITIALIZE_PASS(LiveDebugValues, DEBUG_TYPE, "Live DEBUG_VALUE analysis", false,
- false)
-
-/// Default construct and initialize the pass.
-LiveDebugValues::LiveDebugValues() : MachineFunctionPass(ID) {
- initializeLiveDebugValuesPass(*PassRegistry::getPassRegistry());
- TheImpl = nullptr;
-}
-
-bool LiveDebugValues::runOnMachineFunction(MachineFunction &MF) {
- if (!TheImpl) {
- TPC = getAnalysisIfAvailable<TargetPassConfig>();
-
- bool InstrRefBased = false;
- if (TPC) {
- auto &TM = TPC->getTM<TargetMachine>();
- InstrRefBased = TM.Options.ValueTrackingVariableLocations;
- }
-
- if (InstrRefBased)
- TheImpl = llvm::makeInstrRefBasedLiveDebugValues();
- else
- TheImpl = llvm::makeVarLocBasedLiveDebugValues();
- }
-
- return TheImpl->ExtendRanges(MF, TPC);
-}
+//===- LiveDebugValues.cpp - Tracking Debug Value MIs ---------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "LiveDebugValues.h"
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Target/TargetMachine.h"
+
+/// \file LiveDebugValues.cpp
+///
+/// The LiveDebugValues pass extends the range of variable locations
+/// (specified by DBG_VALUE instructions) from single blocks to successors
+/// and any other code locations where the variable location is valid.
+/// There are currently two implementations: the "VarLoc" implementation
+/// explicitly tracks the location of a variable, while the "InstrRef"
+/// implementation tracks the values defined by instructions through locations.
+///
+/// This file implements neither; it merely registers the pass, allows the
+/// user to pick which implementation will be used to propagate variable
+/// locations.
+
+#define DEBUG_TYPE "livedebugvalues"
+
+using namespace llvm;
+
+/// Generic LiveDebugValues pass. Calls through to VarLocBasedLDV or
+/// InstrRefBasedLDV to perform location propagation, via the LDVImpl
+/// base class.
+class LiveDebugValues : public MachineFunctionPass {
+public:
+ static char ID;
+
+ LiveDebugValues();
+ ~LiveDebugValues() {
+ if (TheImpl)
+ delete TheImpl;
+ }
+
+ /// Calculate the liveness information for the given machine function.
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ MachineFunctionProperties getRequiredProperties() const override {
+ return MachineFunctionProperties().set(
+ MachineFunctionProperties::Property::NoVRegs);
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesCFG();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+private:
+ LDVImpl *TheImpl;
+ TargetPassConfig *TPC;
+};
+
+char LiveDebugValues::ID = 0;
+
+char &llvm::LiveDebugValuesID = LiveDebugValues::ID;
+
+INITIALIZE_PASS(LiveDebugValues, DEBUG_TYPE, "Live DEBUG_VALUE analysis", false,
+ false)
+
+/// Default construct and initialize the pass.
+LiveDebugValues::LiveDebugValues() : MachineFunctionPass(ID) {
+ initializeLiveDebugValuesPass(*PassRegistry::getPassRegistry());
+ TheImpl = nullptr;
+}
+
+bool LiveDebugValues::runOnMachineFunction(MachineFunction &MF) {
+ if (!TheImpl) {
+ TPC = getAnalysisIfAvailable<TargetPassConfig>();
+
+ bool InstrRefBased = false;
+ if (TPC) {
+ auto &TM = TPC->getTM<TargetMachine>();
+ InstrRefBased = TM.Options.ValueTrackingVariableLocations;
+ }
+
+ if (InstrRefBased)
+ TheImpl = llvm::makeInstrRefBasedLiveDebugValues();
+ else
+ TheImpl = llvm::makeVarLocBasedLiveDebugValues();
+ }
+
+ return TheImpl->ExtendRanges(MF, TPC);
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/LiveDebugValues.h b/contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/LiveDebugValues.h
index 707b76b73e..6b05bc68d7 100644
--- a/contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/LiveDebugValues.h
+++ b/contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/LiveDebugValues.h
@@ -1,32 +1,32 @@
-//===- LiveDebugValues.cpp - Tracking Debug Value MIs ---------*- C++ -*---===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/TargetPassConfig.h"
-
-namespace llvm {
-
-// Inline namespace for types / symbols shared between different
-// LiveDebugValues implementations.
-inline namespace SharedLiveDebugValues {
-
-// Expose a base class for LiveDebugValues interfaces to inherit from. This
-// allows the generic LiveDebugValues pass handles to call into the
-// implementation.
-class LDVImpl {
-public:
- virtual bool ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC) = 0;
- virtual ~LDVImpl() {}
-};
-
-} // namespace SharedLiveDebugValues
-
-// Factory functions for LiveDebugValues implementations.
-extern LDVImpl *makeVarLocBasedLiveDebugValues();
-extern LDVImpl *makeInstrRefBasedLiveDebugValues();
-} // namespace llvm
+//===- LiveDebugValues.cpp - Tracking Debug Value MIs ---------*- C++ -*---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+
+namespace llvm {
+
+// Inline namespace for types / symbols shared between different
+// LiveDebugValues implementations.
+inline namespace SharedLiveDebugValues {
+
+// Expose a base class for LiveDebugValues interfaces to inherit from. This
+// allows the generic LiveDebugValues pass handles to call into the
+// implementation.
+class LDVImpl {
+public:
+ virtual bool ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC) = 0;
+ virtual ~LDVImpl() {}
+};
+
+} // namespace SharedLiveDebugValues
+
+// Factory functions for LiveDebugValues implementations.
+extern LDVImpl *makeVarLocBasedLiveDebugValues();
+extern LDVImpl *makeInstrRefBasedLiveDebugValues();
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp b/contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp
index 3d3d12a5b7..e2daa46fe6 100644
--- a/contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp
@@ -1,1994 +1,1994 @@
-//===- VarLocBasedImpl.cpp - Tracking Debug Value MIs with VarLoc class----===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file VarLocBasedImpl.cpp
-///
-/// LiveDebugValues is an optimistic "available expressions" dataflow
-/// algorithm. The set of expressions is the set of machine locations
-/// (registers, spill slots, constants) that a variable fragment might be
-/// located, qualified by a DIExpression and indirect-ness flag, while each
-/// variable is identified by a DebugVariable object. The availability of an
-/// expression begins when a DBG_VALUE instruction specifies the location of a
-/// DebugVariable, and continues until that location is clobbered or
-/// re-specified by a different DBG_VALUE for the same DebugVariable.
-///
-/// The output of LiveDebugValues is additional DBG_VALUE instructions,
-/// placed to extend variable locations as far they're available. This file
-/// and the VarLocBasedLDV class is an implementation that explicitly tracks
-/// locations, using the VarLoc class.
-///
-/// The canonical "available expressions" problem doesn't have expression
-/// clobbering, instead when a variable is re-assigned, any expressions using
-/// that variable get invalidated. LiveDebugValues can map onto "available
-/// expressions" by having every register represented by a variable, which is
-/// used in an expression that becomes available at a DBG_VALUE instruction.
-/// When the register is clobbered, its variable is effectively reassigned, and
-/// expressions computed from it become unavailable. A similar construct is
-/// needed when a DebugVariable has its location re-specified, to invalidate
-/// all other locations for that DebugVariable.
-///
-/// Using the dataflow analysis to compute the available expressions, we create
-/// a DBG_VALUE at the beginning of each block where the expression is
-/// live-in. This propagates variable locations into every basic block where
-/// the location can be determined, rather than only having DBG_VALUEs in blocks
-/// where locations are specified due to an assignment or some optimization.
-/// Movements of values between registers and spill slots are annotated with
-/// DBG_VALUEs too to track variable values bewteen locations. All this allows
-/// DbgEntityHistoryCalculator to focus on only the locations within individual
-/// blocks, facilitating testing and improving modularity.
-///
-/// We follow an optimisic dataflow approach, with this lattice:
-///
-/// \verbatim
-/// ┬ "Unknown"
-/// |
-/// v
-/// True
-/// |
-/// v
-/// ⊥ False
-/// \endverbatim With "True" signifying that the expression is available (and
-/// thus a DebugVariable's location is the corresponding register), while
-/// "False" signifies that the expression is unavailable. "Unknown"s never
-/// survive to the end of the analysis (see below).
-///
-/// Formally, all DebugVariable locations that are live-out of a block are
-/// initialized to \top. A blocks live-in values take the meet of the lattice
-/// value for every predecessors live-outs, except for the entry block, where
-/// all live-ins are \bot. The usual dataflow propagation occurs: the transfer
-/// function for a block assigns an expression for a DebugVariable to be "True"
-/// if a DBG_VALUE in the block specifies it; "False" if the location is
-/// clobbered; or the live-in value if it is unaffected by the block. We
-/// visit each block in reverse post order until a fixedpoint is reached. The
-/// solution produced is maximal.
-///
-/// Intuitively, we start by assuming that every expression / variable location
-/// is at least "True", and then propagate "False" from the entry block and any
-/// clobbers until there are no more changes to make. This gives us an accurate
-/// solution because all incorrect locations will have a "False" propagated into
-/// them. It also gives us a solution that copes well with loops by assuming
-/// that variable locations are live-through every loop, and then removing those
-/// that are not through dataflow.
-///
-/// Within LiveDebugValues: each variable location is represented by a
-/// VarLoc object that identifies the source variable, its current
-/// machine-location, and the DBG_VALUE inst that specifies the location. Each
-/// VarLoc is indexed in the (function-scope) \p VarLocMap, giving each VarLoc a
-/// unique index. Rather than operate directly on machine locations, the
-/// dataflow analysis in this pass identifies locations by their index in the
-/// VarLocMap, meaning all the variable locations in a block can be described
-/// by a sparse vector of VarLocMap indicies.
-///
-/// All the storage for the dataflow analysis is local to the ExtendRanges
-/// method and passed down to helper methods. "OutLocs" and "InLocs" record the
-/// in and out lattice values for each block. "OpenRanges" maintains a list of
-/// variable locations and, with the "process" method, evaluates the transfer
-/// function of each block. "flushPendingLocs" installs DBG_VALUEs for each
-/// live-in location at the start of blocks, while "Transfers" records
-/// transfers of values between machine-locations.
-///
-/// We avoid explicitly representing the "Unknown" (\top) lattice value in the
-/// implementation. Instead, unvisited blocks implicitly have all lattice
-/// values set as "Unknown". After being visited, there will be path back to
-/// the entry block where the lattice value is "False", and as the transfer
-/// function cannot make new "Unknown" locations, there are no scenarios where
-/// a block can have an "Unknown" location after being visited. Similarly, we
-/// don't enumerate all possible variable locations before exploring the
-/// function: when a new location is discovered, all blocks previously explored
-/// were implicitly "False" but unrecorded, and become explicitly "False" when
-/// a new VarLoc is created with its bit not set in predecessor InLocs or
-/// OutLocs.
-///
-//===----------------------------------------------------------------------===//
-
-#include "LiveDebugValues.h"
-
-#include "llvm/ADT/CoalescingBitVector.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/PostOrderIterator.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/UniqueVector.h"
-#include "llvm/CodeGen/LexicalScopes.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineMemOperand.h"
-#include "llvm/CodeGen/MachineOperand.h"
-#include "llvm/CodeGen/PseudoSourceValue.h"
-#include "llvm/CodeGen/RegisterScavenging.h"
-#include "llvm/CodeGen/TargetFrameLowering.h"
-#include "llvm/CodeGen/TargetInstrInfo.h"
-#include "llvm/CodeGen/TargetLowering.h"
-#include "llvm/CodeGen/TargetPassConfig.h"
-#include "llvm/CodeGen/TargetRegisterInfo.h"
-#include "llvm/CodeGen/TargetSubtargetInfo.h"
-#include "llvm/Config/llvm-config.h"
-#include "llvm/IR/DIBuilder.h"
-#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/DebugLoc.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Module.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/TypeSize.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetMachine.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <functional>
-#include <queue>
-#include <tuple>
-#include <utility>
-#include <vector>
-
-using namespace llvm;
-
-#define DEBUG_TYPE "livedebugvalues"
-
-STATISTIC(NumInserted, "Number of DBG_VALUE instructions inserted");
-
-// Options to prevent pathological compile-time behavior. If InputBBLimit and
-// InputDbgValueLimit are both exceeded, range extension is disabled.
-static cl::opt<unsigned> InputBBLimit(
- "livedebugvalues-input-bb-limit",
- cl::desc("Maximum input basic blocks before DBG_VALUE limit applies"),
- cl::init(10000), cl::Hidden);
-static cl::opt<unsigned> InputDbgValueLimit(
- "livedebugvalues-input-dbg-value-limit",
- cl::desc(
- "Maximum input DBG_VALUE insts supported by debug range extension"),
- cl::init(50000), cl::Hidden);
-
-// If @MI is a DBG_VALUE with debug value described by a defined
-// register, returns the number of this register. In the other case, returns 0.
-static Register isDbgValueDescribedByReg(const MachineInstr &MI) {
- assert(MI.isDebugValue() && "expected a DBG_VALUE");
- assert(MI.getNumOperands() == 4 && "malformed DBG_VALUE");
- // If location of variable is described using a register (directly
- // or indirectly), this register is always a first operand.
- return MI.getDebugOperand(0).isReg() ? MI.getDebugOperand(0).getReg()
- : Register();
-}
-
-/// If \p Op is a stack or frame register return true, otherwise return false.
-/// This is used to avoid basing the debug entry values on the registers, since
-/// we do not support it at the moment.
-static bool isRegOtherThanSPAndFP(const MachineOperand &Op,
- const MachineInstr &MI,
- const TargetRegisterInfo *TRI) {
- if (!Op.isReg())
- return false;
-
- const MachineFunction *MF = MI.getParent()->getParent();
- const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();
- Register SP = TLI->getStackPointerRegisterToSaveRestore();
- Register FP = TRI->getFrameRegister(*MF);
- Register Reg = Op.getReg();
-
- return Reg && Reg != SP && Reg != FP;
-}
-
-namespace {
-
-// Max out the number of statically allocated elements in DefinedRegsSet, as
-// this prevents fallback to std::set::count() operations.
-using DefinedRegsSet = SmallSet<Register, 32>;
-
-using VarLocSet = CoalescingBitVector<uint64_t>;
-
-/// A type-checked pair of {Register Location (or 0), Index}, used to index
-/// into a \ref VarLocMap. This can be efficiently converted to a 64-bit int
-/// for insertion into a \ref VarLocSet, and efficiently converted back. The
-/// type-checker helps ensure that the conversions aren't lossy.
-///
-/// Why encode a location /into/ the VarLocMap index? This makes it possible
-/// to find the open VarLocs killed by a register def very quickly. This is a
-/// performance-critical operation for LiveDebugValues.
-struct LocIndex {
- using u32_location_t = uint32_t;
- using u32_index_t = uint32_t;
-
- u32_location_t Location; // Physical registers live in the range [1;2^30) (see
- // \ref MCRegister), so we have plenty of range left
- // here to encode non-register locations.
- u32_index_t Index;
-
- /// The first location greater than 0 that is not reserved for VarLocs of
- /// kind RegisterKind.
- static constexpr u32_location_t kFirstInvalidRegLocation = 1 << 30;
-
- /// A special location reserved for VarLocs of kind SpillLocKind.
- static constexpr u32_location_t kSpillLocation = kFirstInvalidRegLocation;
-
- /// A special location reserved for VarLocs of kind EntryValueBackupKind and
- /// EntryValueCopyBackupKind.
- static constexpr u32_location_t kEntryValueBackupLocation =
- kFirstInvalidRegLocation + 1;
-
- LocIndex(u32_location_t Location, u32_index_t Index)
- : Location(Location), Index(Index) {}
-
- uint64_t getAsRawInteger() const {
- return (static_cast<uint64_t>(Location) << 32) | Index;
- }
-
- template<typename IntT> static LocIndex fromRawInteger(IntT ID) {
- static_assert(std::is_unsigned<IntT>::value &&
- sizeof(ID) == sizeof(uint64_t),
- "Cannot convert raw integer to LocIndex");
- return {static_cast<u32_location_t>(ID >> 32),
- static_cast<u32_index_t>(ID)};
- }
-
- /// Get the start of the interval reserved for VarLocs of kind RegisterKind
- /// which reside in \p Reg. The end is at rawIndexForReg(Reg+1)-1.
- static uint64_t rawIndexForReg(uint32_t Reg) {
- return LocIndex(Reg, 0).getAsRawInteger();
- }
-
- /// Return a range covering all set indices in the interval reserved for
- /// \p Location in \p Set.
- static auto indexRangeForLocation(const VarLocSet &Set,
- u32_location_t Location) {
- uint64_t Start = LocIndex(Location, 0).getAsRawInteger();
- uint64_t End = LocIndex(Location + 1, 0).getAsRawInteger();
- return Set.half_open_range(Start, End);
- }
-};
-
-class VarLocBasedLDV : public LDVImpl {
-private:
- const TargetRegisterInfo *TRI;
- const TargetInstrInfo *TII;
- const TargetFrameLowering *TFI;
- TargetPassConfig *TPC;
- BitVector CalleeSavedRegs;
- LexicalScopes LS;
- VarLocSet::Allocator Alloc;
-
- enum struct TransferKind { TransferCopy, TransferSpill, TransferRestore };
-
- using FragmentInfo = DIExpression::FragmentInfo;
- using OptFragmentInfo = Optional<DIExpression::FragmentInfo>;
-
- /// A pair of debug variable and value location.
- struct VarLoc {
- // The location at which a spilled variable resides. It consists of a
- // register and an offset.
- struct SpillLoc {
- unsigned SpillBase;
- StackOffset SpillOffset;
- bool operator==(const SpillLoc &Other) const {
- return SpillBase == Other.SpillBase && SpillOffset == Other.SpillOffset;
- }
- bool operator!=(const SpillLoc &Other) const {
- return !(*this == Other);
- }
- };
-
- /// Identity of the variable at this location.
- const DebugVariable Var;
-
- /// The expression applied to this location.
- const DIExpression *Expr;
-
- /// DBG_VALUE to clone var/expr information from if this location
- /// is moved.
- const MachineInstr &MI;
-
- enum VarLocKind {
- InvalidKind = 0,
- RegisterKind,
- SpillLocKind,
- ImmediateKind,
- EntryValueKind,
- EntryValueBackupKind,
- EntryValueCopyBackupKind
- } Kind = InvalidKind;
-
- /// The value location. Stored separately to avoid repeatedly
- /// extracting it from MI.
- union LocUnion {
- uint64_t RegNo;
- SpillLoc SpillLocation;
- uint64_t Hash;
- int64_t Immediate;
- const ConstantFP *FPImm;
- const ConstantInt *CImm;
- LocUnion() : Hash(0) {}
- } Loc;
-
- VarLoc(const MachineInstr &MI, LexicalScopes &LS)
- : Var(MI.getDebugVariable(), MI.getDebugExpression(),
- MI.getDebugLoc()->getInlinedAt()),
- Expr(MI.getDebugExpression()), MI(MI) {
- assert(MI.isDebugValue() && "not a DBG_VALUE");
- assert(MI.getNumOperands() == 4 && "malformed DBG_VALUE");
- if (int RegNo = isDbgValueDescribedByReg(MI)) {
- Kind = RegisterKind;
- Loc.RegNo = RegNo;
- } else if (MI.getDebugOperand(0).isImm()) {
- Kind = ImmediateKind;
- Loc.Immediate = MI.getDebugOperand(0).getImm();
- } else if (MI.getDebugOperand(0).isFPImm()) {
- Kind = ImmediateKind;
- Loc.FPImm = MI.getDebugOperand(0).getFPImm();
- } else if (MI.getDebugOperand(0).isCImm()) {
- Kind = ImmediateKind;
- Loc.CImm = MI.getDebugOperand(0).getCImm();
- }
-
- // We create the debug entry values from the factory functions rather than
- // from this ctor.
- assert(Kind != EntryValueKind && !isEntryBackupLoc());
- }
-
- /// Take the variable and machine-location in DBG_VALUE MI, and build an
- /// entry location using the given expression.
- static VarLoc CreateEntryLoc(const MachineInstr &MI, LexicalScopes &LS,
- const DIExpression *EntryExpr, Register Reg) {
- VarLoc VL(MI, LS);
- assert(VL.Kind == RegisterKind);
- VL.Kind = EntryValueKind;
- VL.Expr = EntryExpr;
- VL.Loc.RegNo = Reg;
- return VL;
- }
-
- /// Take the variable and machine-location from the DBG_VALUE (from the
- /// function entry), and build an entry value backup location. The backup
- /// location will turn into the normal location if the backup is valid at
- /// the time of the primary location clobbering.
- static VarLoc CreateEntryBackupLoc(const MachineInstr &MI,
- LexicalScopes &LS,
- const DIExpression *EntryExpr) {
- VarLoc VL(MI, LS);
- assert(VL.Kind == RegisterKind);
- VL.Kind = EntryValueBackupKind;
- VL.Expr = EntryExpr;
- return VL;
- }
-
- /// Take the variable and machine-location from the DBG_VALUE (from the
- /// function entry), and build a copy of an entry value backup location by
- /// setting the register location to NewReg.
- static VarLoc CreateEntryCopyBackupLoc(const MachineInstr &MI,
- LexicalScopes &LS,
- const DIExpression *EntryExpr,
- Register NewReg) {
- VarLoc VL(MI, LS);
- assert(VL.Kind == RegisterKind);
- VL.Kind = EntryValueCopyBackupKind;
- VL.Expr = EntryExpr;
- VL.Loc.RegNo = NewReg;
- return VL;
- }
-
- /// Copy the register location in DBG_VALUE MI, updating the register to
- /// be NewReg.
- static VarLoc CreateCopyLoc(const MachineInstr &MI, LexicalScopes &LS,
- Register NewReg) {
- VarLoc VL(MI, LS);
- assert(VL.Kind == RegisterKind);
- VL.Loc.RegNo = NewReg;
- return VL;
- }
-
- /// Take the variable described by DBG_VALUE MI, and create a VarLoc
- /// locating it in the specified spill location.
- static VarLoc CreateSpillLoc(const MachineInstr &MI, unsigned SpillBase,
- StackOffset SpillOffset, LexicalScopes &LS) {
- VarLoc VL(MI, LS);
- assert(VL.Kind == RegisterKind);
- VL.Kind = SpillLocKind;
- VL.Loc.SpillLocation = {SpillBase, SpillOffset};
- return VL;
- }
-
- /// Create a DBG_VALUE representing this VarLoc in the given function.
- /// Copies variable-specific information such as DILocalVariable and
- /// inlining information from the original DBG_VALUE instruction, which may
- /// have been several transfers ago.
- MachineInstr *BuildDbgValue(MachineFunction &MF) const {
- const DebugLoc &DbgLoc = MI.getDebugLoc();
- bool Indirect = MI.isIndirectDebugValue();
- const auto &IID = MI.getDesc();
- const DILocalVariable *Var = MI.getDebugVariable();
- const DIExpression *DIExpr = MI.getDebugExpression();
- NumInserted++;
-
- switch (Kind) {
- case EntryValueKind:
- // An entry value is a register location -- but with an updated
- // expression. The register location of such DBG_VALUE is always the one
- // from the entry DBG_VALUE, it does not matter if the entry value was
- // copied in to another register due to some optimizations.
- return BuildMI(MF, DbgLoc, IID, Indirect,
- MI.getDebugOperand(0).getReg(), Var, Expr);
- case RegisterKind:
- // Register locations are like the source DBG_VALUE, but with the
- // register number from this VarLoc.
- return BuildMI(MF, DbgLoc, IID, Indirect, Loc.RegNo, Var, DIExpr);
- case SpillLocKind: {
- // Spills are indirect DBG_VALUEs, with a base register and offset.
- // Use the original DBG_VALUEs expression to build the spilt location
- // on top of. FIXME: spill locations created before this pass runs
- // are not recognized, and not handled here.
- auto *TRI = MF.getSubtarget().getRegisterInfo();
- auto *SpillExpr = TRI->prependOffsetExpression(
- DIExpr, DIExpression::ApplyOffset, Loc.SpillLocation.SpillOffset);
- unsigned Base = Loc.SpillLocation.SpillBase;
- return BuildMI(MF, DbgLoc, IID, true, Base, Var, SpillExpr);
- }
- case ImmediateKind: {
- MachineOperand MO = MI.getDebugOperand(0);
- return BuildMI(MF, DbgLoc, IID, Indirect, MO, Var, DIExpr);
- }
- case EntryValueBackupKind:
- case EntryValueCopyBackupKind:
- case InvalidKind:
- llvm_unreachable(
- "Tried to produce DBG_VALUE for invalid or backup VarLoc");
- }
- llvm_unreachable("Unrecognized VarLocBasedLDV.VarLoc.Kind enum");
- }
-
- /// Is the Loc field a constant or constant object?
- bool isConstant() const { return Kind == ImmediateKind; }
-
- /// Check if the Loc field is an entry backup location.
- bool isEntryBackupLoc() const {
- return Kind == EntryValueBackupKind || Kind == EntryValueCopyBackupKind;
- }
-
- /// If this variable is described by a register holding the entry value,
- /// return it, otherwise return 0.
- unsigned getEntryValueBackupReg() const {
- if (Kind == EntryValueBackupKind)
- return Loc.RegNo;
- return 0;
- }
-
- /// If this variable is described by a register holding the copy of the
- /// entry value, return it, otherwise return 0.
- unsigned getEntryValueCopyBackupReg() const {
- if (Kind == EntryValueCopyBackupKind)
- return Loc.RegNo;
- return 0;
- }
-
- /// If this variable is described by a register, return it,
- /// otherwise return 0.
- unsigned isDescribedByReg() const {
- if (Kind == RegisterKind)
- return Loc.RegNo;
- return 0;
- }
-
- /// Determine whether the lexical scope of this value's debug location
- /// dominates MBB.
- bool dominates(LexicalScopes &LS, MachineBasicBlock &MBB) const {
- return LS.dominates(MI.getDebugLoc().get(), &MBB);
- }
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- // TRI can be null.
- void dump(const TargetRegisterInfo *TRI, raw_ostream &Out = dbgs()) const {
- Out << "VarLoc(";
- switch (Kind) {
- case RegisterKind:
- case EntryValueKind:
- case EntryValueBackupKind:
- case EntryValueCopyBackupKind:
- Out << printReg(Loc.RegNo, TRI);
- break;
- case SpillLocKind:
- Out << printReg(Loc.SpillLocation.SpillBase, TRI);
- Out << "[" << Loc.SpillLocation.SpillOffset.getFixed() << " + "
- << Loc.SpillLocation.SpillOffset.getScalable() << "x vscale"
- << "]";
- break;
- case ImmediateKind:
- Out << Loc.Immediate;
- break;
- case InvalidKind:
- llvm_unreachable("Invalid VarLoc in dump method");
- }
-
- Out << ", \"" << Var.getVariable()->getName() << "\", " << *Expr << ", ";
- if (Var.getInlinedAt())
- Out << "!" << Var.getInlinedAt()->getMetadataID() << ")\n";
- else
- Out << "(null))";
-
- if (isEntryBackupLoc())
- Out << " (backup loc)\n";
- else
- Out << "\n";
- }
-#endif
-
- bool operator==(const VarLoc &Other) const {
- if (Kind != Other.Kind || !(Var == Other.Var) || Expr != Other.Expr)
- return false;
-
- switch (Kind) {
- case SpillLocKind:
- return Loc.SpillLocation == Other.Loc.SpillLocation;
- case RegisterKind:
- case ImmediateKind:
- case EntryValueKind:
- case EntryValueBackupKind:
- case EntryValueCopyBackupKind:
- return Loc.Hash == Other.Loc.Hash;
- default:
- llvm_unreachable("Invalid kind");
- }
- }
-
- /// This operator guarantees that VarLocs are sorted by Variable first.
- bool operator<(const VarLoc &Other) const {
- switch (Kind) {
- case SpillLocKind:
- return std::make_tuple(Var, Kind, Loc.SpillLocation.SpillBase,
- Loc.SpillLocation.SpillOffset.getFixed(),
- Loc.SpillLocation.SpillOffset.getScalable(),
- Expr) <
- std::make_tuple(
- Other.Var, Other.Kind, Other.Loc.SpillLocation.SpillBase,
- Other.Loc.SpillLocation.SpillOffset.getFixed(),
- Other.Loc.SpillLocation.SpillOffset.getScalable(),
- Other.Expr);
- case RegisterKind:
- case ImmediateKind:
- case EntryValueKind:
- case EntryValueBackupKind:
- case EntryValueCopyBackupKind:
- return std::tie(Var, Kind, Loc.Hash, Expr) <
- std::tie(Other.Var, Other.Kind, Other.Loc.Hash, Other.Expr);
- default:
- llvm_unreachable("Invalid kind");
- }
- }
- };
-
- /// VarLocMap is used for two things:
- /// 1) Assigning a unique LocIndex to a VarLoc. This LocIndex can be used to
- /// virtually insert a VarLoc into a VarLocSet.
- /// 2) Given a LocIndex, look up the unique associated VarLoc.
- class VarLocMap {
- /// Map a VarLoc to an index within the vector reserved for its location
- /// within Loc2Vars.
- std::map<VarLoc, LocIndex::u32_index_t> Var2Index;
-
- /// Map a location to a vector which holds VarLocs which live in that
- /// location.
- SmallDenseMap<LocIndex::u32_location_t, std::vector<VarLoc>> Loc2Vars;
-
- /// Determine the 32-bit location reserved for \p VL, based on its kind.
- static LocIndex::u32_location_t getLocationForVar(const VarLoc &VL) {
- switch (VL.Kind) {
- case VarLoc::RegisterKind:
- assert((VL.Loc.RegNo < LocIndex::kFirstInvalidRegLocation) &&
- "Physreg out of range?");
- return VL.Loc.RegNo;
- case VarLoc::SpillLocKind:
- return LocIndex::kSpillLocation;
- case VarLoc::EntryValueBackupKind:
- case VarLoc::EntryValueCopyBackupKind:
- return LocIndex::kEntryValueBackupLocation;
- default:
- return 0;
- }
- }
-
- public:
- /// Retrieve a unique LocIndex for \p VL.
- LocIndex insert(const VarLoc &VL) {
- LocIndex::u32_location_t Location = getLocationForVar(VL);
- LocIndex::u32_index_t &Index = Var2Index[VL];
- if (!Index) {
- auto &Vars = Loc2Vars[Location];
- Vars.push_back(VL);
- Index = Vars.size();
- }
- return {Location, Index - 1};
- }
-
- /// Retrieve the unique VarLoc associated with \p ID.
- const VarLoc &operator[](LocIndex ID) const {
- auto LocIt = Loc2Vars.find(ID.Location);
- assert(LocIt != Loc2Vars.end() && "Location not tracked");
- return LocIt->second[ID.Index];
- }
- };
-
- using VarLocInMBB =
- SmallDenseMap<const MachineBasicBlock *, std::unique_ptr<VarLocSet>>;
- struct TransferDebugPair {
- MachineInstr *TransferInst; ///< Instruction where this transfer occurs.
- LocIndex LocationID; ///< Location number for the transfer dest.
- };
- using TransferMap = SmallVector<TransferDebugPair, 4>;
-
- // Types for recording sets of variable fragments that overlap. For a given
- // local variable, we record all other fragments of that variable that could
- // overlap it, to reduce search time.
- using FragmentOfVar =
- std::pair<const DILocalVariable *, DIExpression::FragmentInfo>;
- using OverlapMap =
- DenseMap<FragmentOfVar, SmallVector<DIExpression::FragmentInfo, 1>>;
-
- // Helper while building OverlapMap, a map of all fragments seen for a given
- // DILocalVariable.
- using VarToFragments =
- DenseMap<const DILocalVariable *, SmallSet<FragmentInfo, 4>>;
-
- /// This holds the working set of currently open ranges. For fast
- /// access, this is done both as a set of VarLocIDs, and a map of
- /// DebugVariable to recent VarLocID. Note that a DBG_VALUE ends all
- /// previous open ranges for the same variable. In addition, we keep
- /// two different maps (Vars/EntryValuesBackupVars), so erase/insert
- /// methods act differently depending on whether a VarLoc is primary
- /// location or backup one. In the case the VarLoc is backup location
- /// we will erase/insert from the EntryValuesBackupVars map, otherwise
- /// we perform the operation on the Vars.
- class OpenRangesSet {
- VarLocSet VarLocs;
- // Map the DebugVariable to recent primary location ID.
- SmallDenseMap<DebugVariable, LocIndex, 8> Vars;
- // Map the DebugVariable to recent backup location ID.
- SmallDenseMap<DebugVariable, LocIndex, 8> EntryValuesBackupVars;
- OverlapMap &OverlappingFragments;
-
- public:
- OpenRangesSet(VarLocSet::Allocator &Alloc, OverlapMap &_OLapMap)
- : VarLocs(Alloc), OverlappingFragments(_OLapMap) {}
-
- const VarLocSet &getVarLocs() const { return VarLocs; }
-
- /// Terminate all open ranges for VL.Var by removing it from the set.
- void erase(const VarLoc &VL);
-
- /// Terminate all open ranges listed in \c KillSet by removing
- /// them from the set.
- void erase(const VarLocSet &KillSet, const VarLocMap &VarLocIDs);
-
- /// Insert a new range into the set.
- void insert(LocIndex VarLocID, const VarLoc &VL);
-
- /// Insert a set of ranges.
- void insertFromLocSet(const VarLocSet &ToLoad, const VarLocMap &Map) {
- for (uint64_t ID : ToLoad) {
- LocIndex Idx = LocIndex::fromRawInteger(ID);
- const VarLoc &VarL = Map[Idx];
- insert(Idx, VarL);
- }
- }
-
- llvm::Optional<LocIndex> getEntryValueBackup(DebugVariable Var);
-
- /// Empty the set.
- void clear() {
- VarLocs.clear();
- Vars.clear();
- EntryValuesBackupVars.clear();
- }
-
- /// Return whether the set is empty or not.
- bool empty() const {
- assert(Vars.empty() == EntryValuesBackupVars.empty() &&
- Vars.empty() == VarLocs.empty() &&
- "open ranges are inconsistent");
- return VarLocs.empty();
- }
-
- /// Get an empty range of VarLoc IDs.
- auto getEmptyVarLocRange() const {
- return iterator_range<VarLocSet::const_iterator>(getVarLocs().end(),
- getVarLocs().end());
- }
-
- /// Get all set IDs for VarLocs of kind RegisterKind in \p Reg.
- auto getRegisterVarLocs(Register Reg) const {
- return LocIndex::indexRangeForLocation(getVarLocs(), Reg);
- }
-
- /// Get all set IDs for VarLocs of kind SpillLocKind.
- auto getSpillVarLocs() const {
- return LocIndex::indexRangeForLocation(getVarLocs(),
- LocIndex::kSpillLocation);
- }
-
- /// Get all set IDs for VarLocs of kind EntryValueBackupKind or
- /// EntryValueCopyBackupKind.
- auto getEntryValueBackupVarLocs() const {
- return LocIndex::indexRangeForLocation(
- getVarLocs(), LocIndex::kEntryValueBackupLocation);
- }
- };
-
- /// Collect all VarLoc IDs from \p CollectFrom for VarLocs of kind
- /// RegisterKind which are located in any reg in \p Regs. Insert collected IDs
- /// into \p Collected.
- void collectIDsForRegs(VarLocSet &Collected, const DefinedRegsSet &Regs,
- const VarLocSet &CollectFrom) const;
-
- /// Get the registers which are used by VarLocs of kind RegisterKind tracked
- /// by \p CollectFrom.
- void getUsedRegs(const VarLocSet &CollectFrom,
- SmallVectorImpl<uint32_t> &UsedRegs) const;
-
- VarLocSet &getVarLocsInMBB(const MachineBasicBlock *MBB, VarLocInMBB &Locs) {
- std::unique_ptr<VarLocSet> &VLS = Locs[MBB];
- if (!VLS)
- VLS = std::make_unique<VarLocSet>(Alloc);
- return *VLS.get();
- }
-
- const VarLocSet &getVarLocsInMBB(const MachineBasicBlock *MBB,
- const VarLocInMBB &Locs) const {
- auto It = Locs.find(MBB);
- assert(It != Locs.end() && "MBB not in map");
- return *It->second.get();
- }
-
- /// Tests whether this instruction is a spill to a stack location.
- bool isSpillInstruction(const MachineInstr &MI, MachineFunction *MF);
-
- /// Decide if @MI is a spill instruction and return true if it is. We use 2
- /// criteria to make this decision:
- /// - Is this instruction a store to a spill slot?
- /// - Is there a register operand that is both used and killed?
- /// TODO: Store optimization can fold spills into other stores (including
- /// other spills). We do not handle this yet (more than one memory operand).
- bool isLocationSpill(const MachineInstr &MI, MachineFunction *MF,
- Register &Reg);
-
- /// Returns true if the given machine instruction is a debug value which we
- /// can emit entry values for.
- ///
- /// Currently, we generate debug entry values only for parameters that are
- /// unmodified throughout the function and located in a register.
- bool isEntryValueCandidate(const MachineInstr &MI,
- const DefinedRegsSet &Regs) const;
-
- /// If a given instruction is identified as a spill, return the spill location
- /// and set \p Reg to the spilled register.
- Optional<VarLoc::SpillLoc> isRestoreInstruction(const MachineInstr &MI,
- MachineFunction *MF,
- Register &Reg);
- /// Given a spill instruction, extract the register and offset used to
- /// address the spill location in a target independent way.
- VarLoc::SpillLoc extractSpillBaseRegAndOffset(const MachineInstr &MI);
- void insertTransferDebugPair(MachineInstr &MI, OpenRangesSet &OpenRanges,
- TransferMap &Transfers, VarLocMap &VarLocIDs,
- LocIndex OldVarID, TransferKind Kind,
- Register NewReg = Register());
-
- void transferDebugValue(const MachineInstr &MI, OpenRangesSet &OpenRanges,
- VarLocMap &VarLocIDs);
- void transferSpillOrRestoreInst(MachineInstr &MI, OpenRangesSet &OpenRanges,
- VarLocMap &VarLocIDs, TransferMap &Transfers);
- bool removeEntryValue(const MachineInstr &MI, OpenRangesSet &OpenRanges,
- VarLocMap &VarLocIDs, const VarLoc &EntryVL);
- void emitEntryValues(MachineInstr &MI, OpenRangesSet &OpenRanges,
- VarLocMap &VarLocIDs, TransferMap &Transfers,
- VarLocSet &KillSet);
- void recordEntryValue(const MachineInstr &MI,
- const DefinedRegsSet &DefinedRegs,
- OpenRangesSet &OpenRanges, VarLocMap &VarLocIDs);
- void transferRegisterCopy(MachineInstr &MI, OpenRangesSet &OpenRanges,
- VarLocMap &VarLocIDs, TransferMap &Transfers);
- void transferRegisterDef(MachineInstr &MI, OpenRangesSet &OpenRanges,
- VarLocMap &VarLocIDs, TransferMap &Transfers);
- bool transferTerminator(MachineBasicBlock *MBB, OpenRangesSet &OpenRanges,
- VarLocInMBB &OutLocs, const VarLocMap &VarLocIDs);
-
- void process(MachineInstr &MI, OpenRangesSet &OpenRanges,
- VarLocMap &VarLocIDs, TransferMap &Transfers);
-
- void accumulateFragmentMap(MachineInstr &MI, VarToFragments &SeenFragments,
- OverlapMap &OLapMap);
-
- bool join(MachineBasicBlock &MBB, VarLocInMBB &OutLocs, VarLocInMBB &InLocs,
- const VarLocMap &VarLocIDs,
- SmallPtrSet<const MachineBasicBlock *, 16> &Visited,
- SmallPtrSetImpl<const MachineBasicBlock *> &ArtificialBlocks);
-
- /// Create DBG_VALUE insts for inlocs that have been propagated but
- /// had their instruction creation deferred.
- void flushPendingLocs(VarLocInMBB &PendingInLocs, VarLocMap &VarLocIDs);
-
- bool ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC) override;
-
-public:
- /// Default construct and initialize the pass.
- VarLocBasedLDV();
-
- ~VarLocBasedLDV();
-
- /// Print to ostream with a message.
- void printVarLocInMBB(const MachineFunction &MF, const VarLocInMBB &V,
- const VarLocMap &VarLocIDs, const char *msg,
- raw_ostream &Out) const;
-};
-
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// Implementation
-//===----------------------------------------------------------------------===//
-
-VarLocBasedLDV::VarLocBasedLDV() { }
-
-VarLocBasedLDV::~VarLocBasedLDV() { }
-
-/// Erase a variable from the set of open ranges, and additionally erase any
-/// fragments that may overlap it. If the VarLoc is a backup location, erase
-/// the variable from the EntryValuesBackupVars set, indicating we should stop
-/// tracking its backup entry location. Otherwise, if the VarLoc is primary
-/// location, erase the variable from the Vars set.
-void VarLocBasedLDV::OpenRangesSet::erase(const VarLoc &VL) {
- // Erasure helper.
- auto DoErase = [VL, this](DebugVariable VarToErase) {
- auto *EraseFrom = VL.isEntryBackupLoc() ? &EntryValuesBackupVars : &Vars;
- auto It = EraseFrom->find(VarToErase);
- if (It != EraseFrom->end()) {
- LocIndex ID = It->second;
- VarLocs.reset(ID.getAsRawInteger());
- EraseFrom->erase(It);
- }
- };
-
- DebugVariable Var = VL.Var;
-
- // Erase the variable/fragment that ends here.
- DoErase(Var);
-
- // Extract the fragment. Interpret an empty fragment as one that covers all
- // possible bits.
- FragmentInfo ThisFragment = Var.getFragmentOrDefault();
-
- // There may be fragments that overlap the designated fragment. Look them up
- // in the pre-computed overlap map, and erase them too.
- auto MapIt = OverlappingFragments.find({Var.getVariable(), ThisFragment});
- if (MapIt != OverlappingFragments.end()) {
- for (auto Fragment : MapIt->second) {
- VarLocBasedLDV::OptFragmentInfo FragmentHolder;
- if (!DebugVariable::isDefaultFragment(Fragment))
- FragmentHolder = VarLocBasedLDV::OptFragmentInfo(Fragment);
- DoErase({Var.getVariable(), FragmentHolder, Var.getInlinedAt()});
- }
- }
-}
-
-void VarLocBasedLDV::OpenRangesSet::erase(const VarLocSet &KillSet,
- const VarLocMap &VarLocIDs) {
- VarLocs.intersectWithComplement(KillSet);
- for (uint64_t ID : KillSet) {
- const VarLoc *VL = &VarLocIDs[LocIndex::fromRawInteger(ID)];
- auto *EraseFrom = VL->isEntryBackupLoc() ? &EntryValuesBackupVars : &Vars;
- EraseFrom->erase(VL->Var);
- }
-}
-
-void VarLocBasedLDV::OpenRangesSet::insert(LocIndex VarLocID,
- const VarLoc &VL) {
- auto *InsertInto = VL.isEntryBackupLoc() ? &EntryValuesBackupVars : &Vars;
- VarLocs.set(VarLocID.getAsRawInteger());
- InsertInto->insert({VL.Var, VarLocID});
-}
-
-/// Return the Loc ID of an entry value backup location, if it exists for the
-/// variable.
-llvm::Optional<LocIndex>
-VarLocBasedLDV::OpenRangesSet::getEntryValueBackup(DebugVariable Var) {
- auto It = EntryValuesBackupVars.find(Var);
- if (It != EntryValuesBackupVars.end())
- return It->second;
-
- return llvm::None;
-}
-
-void VarLocBasedLDV::collectIDsForRegs(VarLocSet &Collected,
- const DefinedRegsSet &Regs,
- const VarLocSet &CollectFrom) const {
- assert(!Regs.empty() && "Nothing to collect");
- SmallVector<uint32_t, 32> SortedRegs;
- for (Register Reg : Regs)
- SortedRegs.push_back(Reg);
- array_pod_sort(SortedRegs.begin(), SortedRegs.end());
- auto It = CollectFrom.find(LocIndex::rawIndexForReg(SortedRegs.front()));
- auto End = CollectFrom.end();
- for (uint32_t Reg : SortedRegs) {
- // The half-open interval [FirstIndexForReg, FirstInvalidIndex) contains all
- // possible VarLoc IDs for VarLocs of kind RegisterKind which live in Reg.
- uint64_t FirstIndexForReg = LocIndex::rawIndexForReg(Reg);
- uint64_t FirstInvalidIndex = LocIndex::rawIndexForReg(Reg + 1);
- It.advanceToLowerBound(FirstIndexForReg);
-
- // Iterate through that half-open interval and collect all the set IDs.
- for (; It != End && *It < FirstInvalidIndex; ++It)
- Collected.set(*It);
-
- if (It == End)
- return;
- }
-}
-
-void VarLocBasedLDV::getUsedRegs(const VarLocSet &CollectFrom,
- SmallVectorImpl<uint32_t> &UsedRegs) const {
- // All register-based VarLocs are assigned indices greater than or equal to
- // FirstRegIndex.
- uint64_t FirstRegIndex = LocIndex::rawIndexForReg(1);
- uint64_t FirstInvalidIndex =
- LocIndex::rawIndexForReg(LocIndex::kFirstInvalidRegLocation);
- for (auto It = CollectFrom.find(FirstRegIndex),
- End = CollectFrom.find(FirstInvalidIndex);
- It != End;) {
- // We found a VarLoc ID for a VarLoc that lives in a register. Figure out
- // which register and add it to UsedRegs.
- uint32_t FoundReg = LocIndex::fromRawInteger(*It).Location;
- assert((UsedRegs.empty() || FoundReg != UsedRegs.back()) &&
- "Duplicate used reg");
- UsedRegs.push_back(FoundReg);
-
- // Skip to the next /set/ register. Note that this finds a lower bound, so
- // even if there aren't any VarLocs living in `FoundReg+1`, we're still
- // guaranteed to move on to the next register (or to end()).
- uint64_t NextRegIndex = LocIndex::rawIndexForReg(FoundReg + 1);
- It.advanceToLowerBound(NextRegIndex);
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Debug Range Extension Implementation
-//===----------------------------------------------------------------------===//
-
-#ifndef NDEBUG
-void VarLocBasedLDV::printVarLocInMBB(const MachineFunction &MF,
- const VarLocInMBB &V,
- const VarLocMap &VarLocIDs,
- const char *msg,
- raw_ostream &Out) const {
- Out << '\n' << msg << '\n';
- for (const MachineBasicBlock &BB : MF) {
- if (!V.count(&BB))
- continue;
- const VarLocSet &L = getVarLocsInMBB(&BB, V);
- if (L.empty())
- continue;
- Out << "MBB: " << BB.getNumber() << ":\n";
- for (uint64_t VLL : L) {
- const VarLoc &VL = VarLocIDs[LocIndex::fromRawInteger(VLL)];
- Out << " Var: " << VL.Var.getVariable()->getName();
- Out << " MI: ";
- VL.dump(TRI, Out);
- }
- }
- Out << "\n";
-}
-#endif
-
-VarLocBasedLDV::VarLoc::SpillLoc
-VarLocBasedLDV::extractSpillBaseRegAndOffset(const MachineInstr &MI) {
- assert(MI.hasOneMemOperand() &&
- "Spill instruction does not have exactly one memory operand?");
- auto MMOI = MI.memoperands_begin();
- const PseudoSourceValue *PVal = (*MMOI)->getPseudoValue();
- assert(PVal->kind() == PseudoSourceValue::FixedStack &&
- "Inconsistent memory operand in spill instruction");
- int FI = cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex();
- const MachineBasicBlock *MBB = MI.getParent();
- Register Reg;
- StackOffset Offset = TFI->getFrameIndexReference(*MBB->getParent(), FI, Reg);
- return {Reg, Offset};
-}
-
-/// Try to salvage the debug entry value if we encounter a new debug value
-/// describing the same parameter, otherwise stop tracking the value. Return
-/// true if we should stop tracking the entry value, otherwise return false.
-bool VarLocBasedLDV::removeEntryValue(const MachineInstr &MI,
- OpenRangesSet &OpenRanges,
- VarLocMap &VarLocIDs,
- const VarLoc &EntryVL) {
- // Skip the DBG_VALUE which is the debug entry value itself.
- if (MI.isIdenticalTo(EntryVL.MI))
- return false;
-
- // If the parameter's location is not register location, we can not track
- // the entry value any more. In addition, if the debug expression from the
- // DBG_VALUE is not empty, we can assume the parameter's value has changed
- // indicating that we should stop tracking its entry value as well.
- if (!MI.getDebugOperand(0).isReg() ||
- MI.getDebugExpression()->getNumElements() != 0)
- return true;
-
- // If the DBG_VALUE comes from a copy instruction that copies the entry value,
- // it means the parameter's value has not changed and we should be able to use
- // its entry value.
- bool TrySalvageEntryValue = false;
- Register Reg = MI.getDebugOperand(0).getReg();
- auto I = std::next(MI.getReverseIterator());
- const MachineOperand *SrcRegOp, *DestRegOp;
- if (I != MI.getParent()->rend()) {
- // TODO: Try to keep tracking of an entry value if we encounter a propagated
- // DBG_VALUE describing the copy of the entry value. (Propagated entry value
- // does not indicate the parameter modification.)
- auto DestSrc = TII->isCopyInstr(*I);
- if (!DestSrc)
- return true;
-
- SrcRegOp = DestSrc->Source;
- DestRegOp = DestSrc->Destination;
- if (Reg != DestRegOp->getReg())
- return true;
- TrySalvageEntryValue = true;
- }
-
- if (TrySalvageEntryValue) {
- for (uint64_t ID : OpenRanges.getEntryValueBackupVarLocs()) {
- const VarLoc &VL = VarLocIDs[LocIndex::fromRawInteger(ID)];
- if (VL.getEntryValueCopyBackupReg() == Reg &&
- VL.MI.getDebugOperand(0).getReg() == SrcRegOp->getReg())
- return false;
- }
- }
-
- return true;
-}
-
-/// End all previous ranges related to @MI and start a new range from @MI
-/// if it is a DBG_VALUE instr.
-void VarLocBasedLDV::transferDebugValue(const MachineInstr &MI,
- OpenRangesSet &OpenRanges,
- VarLocMap &VarLocIDs) {
- if (!MI.isDebugValue())
- return;
- const DILocalVariable *Var = MI.getDebugVariable();
- const DIExpression *Expr = MI.getDebugExpression();
- const DILocation *DebugLoc = MI.getDebugLoc();
- const DILocation *InlinedAt = DebugLoc->getInlinedAt();
- assert(Var->isValidLocationForIntrinsic(DebugLoc) &&
- "Expected inlined-at fields to agree");
-
- DebugVariable V(Var, Expr, InlinedAt);
-
- // Check if this DBG_VALUE indicates a parameter's value changing.
- // If that is the case, we should stop tracking its entry value.
- auto EntryValBackupID = OpenRanges.getEntryValueBackup(V);
- if (Var->isParameter() && EntryValBackupID) {
- const VarLoc &EntryVL = VarLocIDs[*EntryValBackupID];
- if (removeEntryValue(MI, OpenRanges, VarLocIDs, EntryVL)) {
- LLVM_DEBUG(dbgs() << "Deleting a DBG entry value because of: ";
- MI.print(dbgs(), /*IsStandalone*/ false,
- /*SkipOpers*/ false, /*SkipDebugLoc*/ false,
- /*AddNewLine*/ true, TII));
- OpenRanges.erase(EntryVL);
- }
- }
-
- if (isDbgValueDescribedByReg(MI) || MI.getDebugOperand(0).isImm() ||
- MI.getDebugOperand(0).isFPImm() || MI.getDebugOperand(0).isCImm()) {
- // Use normal VarLoc constructor for registers and immediates.
- VarLoc VL(MI, LS);
- // End all previous ranges of VL.Var.
- OpenRanges.erase(VL);
-
- LocIndex ID = VarLocIDs.insert(VL);
- // Add the VarLoc to OpenRanges from this DBG_VALUE.
- OpenRanges.insert(ID, VL);
- } else if (MI.hasOneMemOperand()) {
- llvm_unreachable("DBG_VALUE with mem operand encountered after regalloc?");
- } else {
- // This must be an undefined location. If it has an open range, erase it.
- assert(MI.getDebugOperand(0).isReg() &&
- MI.getDebugOperand(0).getReg() == 0 &&
- "Unexpected non-undef DBG_VALUE encountered");
- VarLoc VL(MI, LS);
- OpenRanges.erase(VL);
- }
-}
-
-/// Turn the entry value backup locations into primary locations.
-void VarLocBasedLDV::emitEntryValues(MachineInstr &MI,
- OpenRangesSet &OpenRanges,
- VarLocMap &VarLocIDs,
- TransferMap &Transfers,
- VarLocSet &KillSet) {
- // Do not insert entry value locations after a terminator.
- if (MI.isTerminator())
- return;
-
- for (uint64_t ID : KillSet) {
- LocIndex Idx = LocIndex::fromRawInteger(ID);
- const VarLoc &VL = VarLocIDs[Idx];
- if (!VL.Var.getVariable()->isParameter())
- continue;
-
- auto DebugVar = VL.Var;
- Optional<LocIndex> EntryValBackupID =
- OpenRanges.getEntryValueBackup(DebugVar);
-
- // If the parameter has the entry value backup, it means we should
- // be able to use its entry value.
- if (!EntryValBackupID)
- continue;
-
- const VarLoc &EntryVL = VarLocIDs[*EntryValBackupID];
- VarLoc EntryLoc =
- VarLoc::CreateEntryLoc(EntryVL.MI, LS, EntryVL.Expr, EntryVL.Loc.RegNo);
- LocIndex EntryValueID = VarLocIDs.insert(EntryLoc);
- Transfers.push_back({&MI, EntryValueID});
- OpenRanges.insert(EntryValueID, EntryLoc);
- }
-}
-
-/// Create new TransferDebugPair and insert it in \p Transfers. The VarLoc
-/// with \p OldVarID should be deleted form \p OpenRanges and replaced with
-/// new VarLoc. If \p NewReg is different than default zero value then the
-/// new location will be register location created by the copy like instruction,
-/// otherwise it is variable's location on the stack.
-void VarLocBasedLDV::insertTransferDebugPair(
- MachineInstr &MI, OpenRangesSet &OpenRanges, TransferMap &Transfers,
- VarLocMap &VarLocIDs, LocIndex OldVarID, TransferKind Kind,
- Register NewReg) {
- const MachineInstr *DebugInstr = &VarLocIDs[OldVarID].MI;
-
- auto ProcessVarLoc = [&MI, &OpenRanges, &Transfers, &VarLocIDs](VarLoc &VL) {
- LocIndex LocId = VarLocIDs.insert(VL);
-
- // Close this variable's previous location range.
- OpenRanges.erase(VL);
-
- // Record the new location as an open range, and a postponed transfer
- // inserting a DBG_VALUE for this location.
- OpenRanges.insert(LocId, VL);
- assert(!MI.isTerminator() && "Cannot insert DBG_VALUE after terminator");
- TransferDebugPair MIP = {&MI, LocId};
- Transfers.push_back(MIP);
- };
-
- // End all previous ranges of VL.Var.
- OpenRanges.erase(VarLocIDs[OldVarID]);
- switch (Kind) {
- case TransferKind::TransferCopy: {
- assert(NewReg &&
- "No register supplied when handling a copy of a debug value");
- // Create a DBG_VALUE instruction to describe the Var in its new
- // register location.
- VarLoc VL = VarLoc::CreateCopyLoc(*DebugInstr, LS, NewReg);
- ProcessVarLoc(VL);
- LLVM_DEBUG({
- dbgs() << "Creating VarLoc for register copy:";
- VL.dump(TRI);
- });
- return;
- }
- case TransferKind::TransferSpill: {
- // Create a DBG_VALUE instruction to describe the Var in its spilled
- // location.
- VarLoc::SpillLoc SpillLocation = extractSpillBaseRegAndOffset(MI);
- VarLoc VL = VarLoc::CreateSpillLoc(*DebugInstr, SpillLocation.SpillBase,
- SpillLocation.SpillOffset, LS);
- ProcessVarLoc(VL);
- LLVM_DEBUG({
- dbgs() << "Creating VarLoc for spill:";
- VL.dump(TRI);
- });
- return;
- }
- case TransferKind::TransferRestore: {
- assert(NewReg &&
- "No register supplied when handling a restore of a debug value");
- // DebugInstr refers to the pre-spill location, therefore we can reuse
- // its expression.
- VarLoc VL = VarLoc::CreateCopyLoc(*DebugInstr, LS, NewReg);
- ProcessVarLoc(VL);
- LLVM_DEBUG({
- dbgs() << "Creating VarLoc for restore:";
- VL.dump(TRI);
- });
- return;
- }
- }
- llvm_unreachable("Invalid transfer kind");
-}
-
-/// A definition of a register may mark the end of a range.
-void VarLocBasedLDV::transferRegisterDef(
- MachineInstr &MI, OpenRangesSet &OpenRanges, VarLocMap &VarLocIDs,
- TransferMap &Transfers) {
-
- // Meta Instructions do not affect the debug liveness of any register they
- // define.
- if (MI.isMetaInstruction())
- return;
-
- MachineFunction *MF = MI.getMF();
- const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();
- Register SP = TLI->getStackPointerRegisterToSaveRestore();
-
- // Find the regs killed by MI, and find regmasks of preserved regs.
- DefinedRegsSet DeadRegs;
- SmallVector<const uint32_t *, 4> RegMasks;
- for (const MachineOperand &MO : MI.operands()) {
- // Determine whether the operand is a register def.
- if (MO.isReg() && MO.isDef() && MO.getReg() &&
- Register::isPhysicalRegister(MO.getReg()) &&
- !(MI.isCall() && MO.getReg() == SP)) {
- // Remove ranges of all aliased registers.
- for (MCRegAliasIterator RAI(MO.getReg(), TRI, true); RAI.isValid(); ++RAI)
- // FIXME: Can we break out of this loop early if no insertion occurs?
- DeadRegs.insert(*RAI);
- } else if (MO.isRegMask()) {
- RegMasks.push_back(MO.getRegMask());
- }
- }
-
- // Erase VarLocs which reside in one of the dead registers. For performance
- // reasons, it's critical to not iterate over the full set of open VarLocs.
- // Iterate over the set of dying/used regs instead.
- if (!RegMasks.empty()) {
- SmallVector<uint32_t, 32> UsedRegs;
- getUsedRegs(OpenRanges.getVarLocs(), UsedRegs);
- for (uint32_t Reg : UsedRegs) {
- // Remove ranges of all clobbered registers. Register masks don't usually
- // list SP as preserved. Assume that call instructions never clobber SP,
- // because some backends (e.g., AArch64) never list SP in the regmask.
- // While the debug info may be off for an instruction or two around
- // callee-cleanup calls, transferring the DEBUG_VALUE across the call is
- // still a better user experience.
- if (Reg == SP)
- continue;
- bool AnyRegMaskKillsReg =
- any_of(RegMasks, [Reg](const uint32_t *RegMask) {
- return MachineOperand::clobbersPhysReg(RegMask, Reg);
- });
- if (AnyRegMaskKillsReg)
- DeadRegs.insert(Reg);
- }
- }
-
- if (DeadRegs.empty())
- return;
-
- VarLocSet KillSet(Alloc);
- collectIDsForRegs(KillSet, DeadRegs, OpenRanges.getVarLocs());
- OpenRanges.erase(KillSet, VarLocIDs);
-
- if (TPC) {
- auto &TM = TPC->getTM<TargetMachine>();
- if (TM.Options.ShouldEmitDebugEntryValues())
- emitEntryValues(MI, OpenRanges, VarLocIDs, Transfers, KillSet);
- }
-}
-
-bool VarLocBasedLDV::isSpillInstruction(const MachineInstr &MI,
- MachineFunction *MF) {
- // TODO: Handle multiple stores folded into one.
- if (!MI.hasOneMemOperand())
- return false;
-
- if (!MI.getSpillSize(TII) && !MI.getFoldedSpillSize(TII))
- return false; // This is not a spill instruction, since no valid size was
- // returned from either function.
-
- return true;
-}
-
-bool VarLocBasedLDV::isLocationSpill(const MachineInstr &MI,
- MachineFunction *MF, Register &Reg) {
- if (!isSpillInstruction(MI, MF))
- return false;
-
- auto isKilledReg = [&](const MachineOperand MO, Register &Reg) {
- if (!MO.isReg() || !MO.isUse()) {
- Reg = 0;
- return false;
- }
- Reg = MO.getReg();
- return MO.isKill();
- };
-
- for (const MachineOperand &MO : MI.operands()) {
- // In a spill instruction generated by the InlineSpiller the spilled
- // register has its kill flag set.
- if (isKilledReg(MO, Reg))
- return true;
- if (Reg != 0) {
- // Check whether next instruction kills the spilled register.
- // FIXME: Current solution does not cover search for killed register in
- // bundles and instructions further down the chain.
- auto NextI = std::next(MI.getIterator());
- // Skip next instruction that points to basic block end iterator.
- if (MI.getParent()->end() == NextI)
- continue;
- Register RegNext;
- for (const MachineOperand &MONext : NextI->operands()) {
- // Return true if we came across the register from the
- // previous spill instruction that is killed in NextI.
- if (isKilledReg(MONext, RegNext) && RegNext == Reg)
- return true;
- }
- }
- }
- // Return false if we didn't find spilled register.
- return false;
-}
-
-Optional<VarLocBasedLDV::VarLoc::SpillLoc>
-VarLocBasedLDV::isRestoreInstruction(const MachineInstr &MI,
- MachineFunction *MF, Register &Reg) {
- if (!MI.hasOneMemOperand())
- return None;
-
- // FIXME: Handle folded restore instructions with more than one memory
- // operand.
- if (MI.getRestoreSize(TII)) {
- Reg = MI.getOperand(0).getReg();
- return extractSpillBaseRegAndOffset(MI);
- }
- return None;
-}
-
-/// A spilled register may indicate that we have to end the current range of
-/// a variable and create a new one for the spill location.
-/// A restored register may indicate the reverse situation.
-/// We don't want to insert any instructions in process(), so we just create
-/// the DBG_VALUE without inserting it and keep track of it in \p Transfers.
-/// It will be inserted into the BB when we're done iterating over the
-/// instructions.
-void VarLocBasedLDV::transferSpillOrRestoreInst(MachineInstr &MI,
- OpenRangesSet &OpenRanges,
- VarLocMap &VarLocIDs,
- TransferMap &Transfers) {
- MachineFunction *MF = MI.getMF();
- TransferKind TKind;
- Register Reg;
- Optional<VarLoc::SpillLoc> Loc;
-
- LLVM_DEBUG(dbgs() << "Examining instruction: "; MI.dump(););
-
- // First, if there are any DBG_VALUEs pointing at a spill slot that is
- // written to, then close the variable location. The value in memory
- // will have changed.
- VarLocSet KillSet(Alloc);
- if (isSpillInstruction(MI, MF)) {
- Loc = extractSpillBaseRegAndOffset(MI);
- for (uint64_t ID : OpenRanges.getSpillVarLocs()) {
- LocIndex Idx = LocIndex::fromRawInteger(ID);
- const VarLoc &VL = VarLocIDs[Idx];
- assert(VL.Kind == VarLoc::SpillLocKind && "Broken VarLocSet?");
- if (VL.Loc.SpillLocation == *Loc) {
- // This location is overwritten by the current instruction -- terminate
- // the open range, and insert an explicit DBG_VALUE $noreg.
- //
- // Doing this at a later stage would require re-interpreting all
- // DBG_VALUes and DIExpressions to identify whether they point at
- // memory, and then analysing all memory writes to see if they
- // overwrite that memory, which is expensive.
- //
- // At this stage, we already know which DBG_VALUEs are for spills and
- // where they are located; it's best to fix handle overwrites now.
- KillSet.set(ID);
- VarLoc UndefVL = VarLoc::CreateCopyLoc(VL.MI, LS, 0);
- LocIndex UndefLocID = VarLocIDs.insert(UndefVL);
- Transfers.push_back({&MI, UndefLocID});
- }
- }
- OpenRanges.erase(KillSet, VarLocIDs);
- }
-
- // Try to recognise spill and restore instructions that may create a new
- // variable location.
- if (isLocationSpill(MI, MF, Reg)) {
- TKind = TransferKind::TransferSpill;
- LLVM_DEBUG(dbgs() << "Recognized as spill: "; MI.dump(););
- LLVM_DEBUG(dbgs() << "Register: " << Reg << " " << printReg(Reg, TRI)
- << "\n");
- } else {
- if (!(Loc = isRestoreInstruction(MI, MF, Reg)))
- return;
- TKind = TransferKind::TransferRestore;
- LLVM_DEBUG(dbgs() << "Recognized as restore: "; MI.dump(););
- LLVM_DEBUG(dbgs() << "Register: " << Reg << " " << printReg(Reg, TRI)
- << "\n");
- }
- // Check if the register or spill location is the location of a debug value.
- auto TransferCandidates = OpenRanges.getEmptyVarLocRange();
- if (TKind == TransferKind::TransferSpill)
- TransferCandidates = OpenRanges.getRegisterVarLocs(Reg);
- else if (TKind == TransferKind::TransferRestore)
- TransferCandidates = OpenRanges.getSpillVarLocs();
- for (uint64_t ID : TransferCandidates) {
- LocIndex Idx = LocIndex::fromRawInteger(ID);
- const VarLoc &VL = VarLocIDs[Idx];
- if (TKind == TransferKind::TransferSpill) {
- assert(VL.isDescribedByReg() == Reg && "Broken VarLocSet?");
- LLVM_DEBUG(dbgs() << "Spilling Register " << printReg(Reg, TRI) << '('
- << VL.Var.getVariable()->getName() << ")\n");
- } else {
- assert(TKind == TransferKind::TransferRestore &&
- VL.Kind == VarLoc::SpillLocKind && "Broken VarLocSet?");
- if (VL.Loc.SpillLocation != *Loc)
- // The spill location is not the location of a debug value.
- continue;
- LLVM_DEBUG(dbgs() << "Restoring Register " << printReg(Reg, TRI) << '('
- << VL.Var.getVariable()->getName() << ")\n");
- }
- insertTransferDebugPair(MI, OpenRanges, Transfers, VarLocIDs, Idx, TKind,
- Reg);
- // FIXME: A comment should explain why it's correct to return early here,
- // if that is in fact correct.
- return;
- }
-}
-
-/// If \p MI is a register copy instruction, that copies a previously tracked
-/// value from one register to another register that is callee saved, we
-/// create new DBG_VALUE instruction described with copy destination register.
-void VarLocBasedLDV::transferRegisterCopy(MachineInstr &MI,
- OpenRangesSet &OpenRanges,
- VarLocMap &VarLocIDs,
- TransferMap &Transfers) {
- auto DestSrc = TII->isCopyInstr(MI);
- if (!DestSrc)
- return;
-
- const MachineOperand *DestRegOp = DestSrc->Destination;
- const MachineOperand *SrcRegOp = DestSrc->Source;
-
- if (!DestRegOp->isDef())
- return;
-
- auto isCalleeSavedReg = [&](Register Reg) {
- for (MCRegAliasIterator RAI(Reg, TRI, true); RAI.isValid(); ++RAI)
- if (CalleeSavedRegs.test(*RAI))
- return true;
- return false;
- };
-
- Register SrcReg = SrcRegOp->getReg();
- Register DestReg = DestRegOp->getReg();
-
- // We want to recognize instructions where destination register is callee
- // saved register. If register that could be clobbered by the call is
- // included, there would be a great chance that it is going to be clobbered
- // soon. It is more likely that previous register location, which is callee
- // saved, is going to stay unclobbered longer, even if it is killed.
- if (!isCalleeSavedReg(DestReg))
- return;
-
- // Remember an entry value movement. If we encounter a new debug value of
- // a parameter describing only a moving of the value around, rather then
- // modifying it, we are still able to use the entry value if needed.
- if (isRegOtherThanSPAndFP(*DestRegOp, MI, TRI)) {
- for (uint64_t ID : OpenRanges.getEntryValueBackupVarLocs()) {
- LocIndex Idx = LocIndex::fromRawInteger(ID);
- const VarLoc &VL = VarLocIDs[Idx];
- if (VL.getEntryValueBackupReg() == SrcReg) {
- LLVM_DEBUG(dbgs() << "Copy of the entry value: "; MI.dump(););
- VarLoc EntryValLocCopyBackup =
- VarLoc::CreateEntryCopyBackupLoc(VL.MI, LS, VL.Expr, DestReg);
-
- // Stop tracking the original entry value.
- OpenRanges.erase(VL);
-
- // Start tracking the entry value copy.
- LocIndex EntryValCopyLocID = VarLocIDs.insert(EntryValLocCopyBackup);
- OpenRanges.insert(EntryValCopyLocID, EntryValLocCopyBackup);
- break;
- }
- }
- }
-
- if (!SrcRegOp->isKill())
- return;
-
- for (uint64_t ID : OpenRanges.getRegisterVarLocs(SrcReg)) {
- LocIndex Idx = LocIndex::fromRawInteger(ID);
- assert(VarLocIDs[Idx].isDescribedByReg() == SrcReg && "Broken VarLocSet?");
- insertTransferDebugPair(MI, OpenRanges, Transfers, VarLocIDs, Idx,
- TransferKind::TransferCopy, DestReg);
- // FIXME: A comment should explain why it's correct to return early here,
- // if that is in fact correct.
- return;
- }
-}
-
-/// Terminate all open ranges at the end of the current basic block.
-bool VarLocBasedLDV::transferTerminator(MachineBasicBlock *CurMBB,
- OpenRangesSet &OpenRanges,
- VarLocInMBB &OutLocs,
- const VarLocMap &VarLocIDs) {
- bool Changed = false;
-
- LLVM_DEBUG(for (uint64_t ID
- : OpenRanges.getVarLocs()) {
- // Copy OpenRanges to OutLocs, if not already present.
- dbgs() << "Add to OutLocs in MBB #" << CurMBB->getNumber() << ": ";
- VarLocIDs[LocIndex::fromRawInteger(ID)].dump(TRI);
- });
- VarLocSet &VLS = getVarLocsInMBB(CurMBB, OutLocs);
- Changed = VLS != OpenRanges.getVarLocs();
- // New OutLocs set may be different due to spill, restore or register
- // copy instruction processing.
- if (Changed)
- VLS = OpenRanges.getVarLocs();
- OpenRanges.clear();
- return Changed;
-}
-
-/// Accumulate a mapping between each DILocalVariable fragment and other
-/// fragments of that DILocalVariable which overlap. This reduces work during
-/// the data-flow stage from "Find any overlapping fragments" to "Check if the
-/// known-to-overlap fragments are present".
-/// \param MI A previously unprocessed DEBUG_VALUE instruction to analyze for
-/// fragment usage.
-/// \param SeenFragments Map from DILocalVariable to all fragments of that
-/// Variable which are known to exist.
-/// \param OverlappingFragments The overlap map being constructed, from one
-/// Var/Fragment pair to a vector of fragments known to overlap.
-void VarLocBasedLDV::accumulateFragmentMap(MachineInstr &MI,
- VarToFragments &SeenFragments,
- OverlapMap &OverlappingFragments) {
- DebugVariable MIVar(MI.getDebugVariable(), MI.getDebugExpression(),
- MI.getDebugLoc()->getInlinedAt());
- FragmentInfo ThisFragment = MIVar.getFragmentOrDefault();
-
- // If this is the first sighting of this variable, then we are guaranteed
- // there are currently no overlapping fragments either. Initialize the set
- // of seen fragments, record no overlaps for the current one, and return.
- auto SeenIt = SeenFragments.find(MIVar.getVariable());
- if (SeenIt == SeenFragments.end()) {
- SmallSet<FragmentInfo, 4> OneFragment;
- OneFragment.insert(ThisFragment);
- SeenFragments.insert({MIVar.getVariable(), OneFragment});
-
- OverlappingFragments.insert({{MIVar.getVariable(), ThisFragment}, {}});
- return;
- }
-
- // If this particular Variable/Fragment pair already exists in the overlap
- // map, it has already been accounted for.
- auto IsInOLapMap =
- OverlappingFragments.insert({{MIVar.getVariable(), ThisFragment}, {}});
- if (!IsInOLapMap.second)
- return;
-
- auto &ThisFragmentsOverlaps = IsInOLapMap.first->second;
- auto &AllSeenFragments = SeenIt->second;
-
- // Otherwise, examine all other seen fragments for this variable, with "this"
- // fragment being a previously unseen fragment. Record any pair of
- // overlapping fragments.
- for (auto &ASeenFragment : AllSeenFragments) {
- // Does this previously seen fragment overlap?
- if (DIExpression::fragmentsOverlap(ThisFragment, ASeenFragment)) {
- // Yes: Mark the current fragment as being overlapped.
- ThisFragmentsOverlaps.push_back(ASeenFragment);
- // Mark the previously seen fragment as being overlapped by the current
- // one.
- auto ASeenFragmentsOverlaps =
- OverlappingFragments.find({MIVar.getVariable(), ASeenFragment});
- assert(ASeenFragmentsOverlaps != OverlappingFragments.end() &&
- "Previously seen var fragment has no vector of overlaps");
- ASeenFragmentsOverlaps->second.push_back(ThisFragment);
- }
- }
-
- AllSeenFragments.insert(ThisFragment);
-}
-
-/// This routine creates OpenRanges.
-void VarLocBasedLDV::process(MachineInstr &MI, OpenRangesSet &OpenRanges,
- VarLocMap &VarLocIDs, TransferMap &Transfers) {
- transferDebugValue(MI, OpenRanges, VarLocIDs);
- transferRegisterDef(MI, OpenRanges, VarLocIDs, Transfers);
- transferRegisterCopy(MI, OpenRanges, VarLocIDs, Transfers);
- transferSpillOrRestoreInst(MI, OpenRanges, VarLocIDs, Transfers);
-}
-
-/// This routine joins the analysis results of all incoming edges in @MBB by
-/// inserting a new DBG_VALUE instruction at the start of the @MBB - if the same
-/// source variable in all the predecessors of @MBB reside in the same location.
-bool VarLocBasedLDV::join(
- MachineBasicBlock &MBB, VarLocInMBB &OutLocs, VarLocInMBB &InLocs,
- const VarLocMap &VarLocIDs,
- SmallPtrSet<const MachineBasicBlock *, 16> &Visited,
- SmallPtrSetImpl<const MachineBasicBlock *> &ArtificialBlocks) {
- LLVM_DEBUG(dbgs() << "join MBB: " << MBB.getNumber() << "\n");
-
- VarLocSet InLocsT(Alloc); // Temporary incoming locations.
-
- // For all predecessors of this MBB, find the set of VarLocs that
- // can be joined.
- int NumVisited = 0;
- for (auto p : MBB.predecessors()) {
- // Ignore backedges if we have not visited the predecessor yet. As the
- // predecessor hasn't yet had locations propagated into it, most locations
- // will not yet be valid, so treat them as all being uninitialized and
- // potentially valid. If a location guessed to be correct here is
- // invalidated later, we will remove it when we revisit this block.
- if (!Visited.count(p)) {
- LLVM_DEBUG(dbgs() << " ignoring unvisited pred MBB: " << p->getNumber()
- << "\n");
- continue;
- }
- auto OL = OutLocs.find(p);
- // Join is null in case of empty OutLocs from any of the pred.
- if (OL == OutLocs.end())
- return false;
-
- // Just copy over the Out locs to incoming locs for the first visited
- // predecessor, and for all other predecessors join the Out locs.
- VarLocSet &OutLocVLS = *OL->second.get();
- if (!NumVisited)
- InLocsT = OutLocVLS;
- else
- InLocsT &= OutLocVLS;
-
- LLVM_DEBUG({
- if (!InLocsT.empty()) {
- for (uint64_t ID : InLocsT)
- dbgs() << " gathered candidate incoming var: "
- << VarLocIDs[LocIndex::fromRawInteger(ID)]
- .Var.getVariable()
- ->getName()
- << "\n";
- }
- });
-
- NumVisited++;
- }
-
- // Filter out DBG_VALUES that are out of scope.
- VarLocSet KillSet(Alloc);
- bool IsArtificial = ArtificialBlocks.count(&MBB);
- if (!IsArtificial) {
- for (uint64_t ID : InLocsT) {
- LocIndex Idx = LocIndex::fromRawInteger(ID);
- if (!VarLocIDs[Idx].dominates(LS, MBB)) {
- KillSet.set(ID);
- LLVM_DEBUG({
- auto Name = VarLocIDs[Idx].Var.getVariable()->getName();
- dbgs() << " killing " << Name << ", it doesn't dominate MBB\n";
- });
- }
- }
- }
- InLocsT.intersectWithComplement(KillSet);
-
- // As we are processing blocks in reverse post-order we
- // should have processed at least one predecessor, unless it
- // is the entry block which has no predecessor.
- assert((NumVisited || MBB.pred_empty()) &&
- "Should have processed at least one predecessor");
-
- VarLocSet &ILS = getVarLocsInMBB(&MBB, InLocs);
- bool Changed = false;
- if (ILS != InLocsT) {
- ILS = InLocsT;
- Changed = true;
- }
-
- return Changed;
-}
-
-void VarLocBasedLDV::flushPendingLocs(VarLocInMBB &PendingInLocs,
- VarLocMap &VarLocIDs) {
- // PendingInLocs records all locations propagated into blocks, which have
- // not had DBG_VALUE insts created. Go through and create those insts now.
- for (auto &Iter : PendingInLocs) {
- // Map is keyed on a constant pointer, unwrap it so we can insert insts.
- auto &MBB = const_cast<MachineBasicBlock &>(*Iter.first);
- VarLocSet &Pending = *Iter.second.get();
-
- for (uint64_t ID : Pending) {
- // The ID location is live-in to MBB -- work out what kind of machine
- // location it is and create a DBG_VALUE.
- const VarLoc &DiffIt = VarLocIDs[LocIndex::fromRawInteger(ID)];
- if (DiffIt.isEntryBackupLoc())
- continue;
- MachineInstr *MI = DiffIt.BuildDbgValue(*MBB.getParent());
- MBB.insert(MBB.instr_begin(), MI);
-
- (void)MI;
- LLVM_DEBUG(dbgs() << "Inserted: "; MI->dump(););
- }
- }
-}
-
-bool VarLocBasedLDV::isEntryValueCandidate(
- const MachineInstr &MI, const DefinedRegsSet &DefinedRegs) const {
- assert(MI.isDebugValue() && "This must be DBG_VALUE.");
-
- // TODO: Add support for local variables that are expressed in terms of
- // parameters entry values.
- // TODO: Add support for modified arguments that can be expressed
- // by using its entry value.
- auto *DIVar = MI.getDebugVariable();
- if (!DIVar->isParameter())
- return false;
-
- // Do not consider parameters that belong to an inlined function.
- if (MI.getDebugLoc()->getInlinedAt())
- return false;
-
- // Only consider parameters that are described using registers. Parameters
- // that are passed on the stack are not yet supported, so ignore debug
- // values that are described by the frame or stack pointer.
- if (!isRegOtherThanSPAndFP(MI.getDebugOperand(0), MI, TRI))
- return false;
-
- // If a parameter's value has been propagated from the caller, then the
- // parameter's DBG_VALUE may be described using a register defined by some
- // instruction in the entry block, in which case we shouldn't create an
- // entry value.
- if (DefinedRegs.count(MI.getDebugOperand(0).getReg()))
- return false;
-
- // TODO: Add support for parameters that have a pre-existing debug expressions
- // (e.g. fragments).
- if (MI.getDebugExpression()->getNumElements() > 0)
- return false;
-
- return true;
-}
-
-/// Collect all register defines (including aliases) for the given instruction.
-static void collectRegDefs(const MachineInstr &MI, DefinedRegsSet &Regs,
- const TargetRegisterInfo *TRI) {
- for (const MachineOperand &MO : MI.operands())
- if (MO.isReg() && MO.isDef() && MO.getReg())
- for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid(); ++AI)
- Regs.insert(*AI);
-}
-
-/// This routine records the entry values of function parameters. The values
-/// could be used as backup values. If we loose the track of some unmodified
-/// parameters, the backup values will be used as a primary locations.
-void VarLocBasedLDV::recordEntryValue(const MachineInstr &MI,
- const DefinedRegsSet &DefinedRegs,
- OpenRangesSet &OpenRanges,
- VarLocMap &VarLocIDs) {
- if (TPC) {
- auto &TM = TPC->getTM<TargetMachine>();
- if (!TM.Options.ShouldEmitDebugEntryValues())
- return;
- }
-
- DebugVariable V(MI.getDebugVariable(), MI.getDebugExpression(),
- MI.getDebugLoc()->getInlinedAt());
-
- if (!isEntryValueCandidate(MI, DefinedRegs) ||
- OpenRanges.getEntryValueBackup(V))
- return;
-
- LLVM_DEBUG(dbgs() << "Creating the backup entry location: "; MI.dump(););
-
- // Create the entry value and use it as a backup location until it is
- // valid. It is valid until a parameter is not changed.
- DIExpression *NewExpr =
- DIExpression::prepend(MI.getDebugExpression(), DIExpression::EntryValue);
- VarLoc EntryValLocAsBackup = VarLoc::CreateEntryBackupLoc(MI, LS, NewExpr);
- LocIndex EntryValLocID = VarLocIDs.insert(EntryValLocAsBackup);
- OpenRanges.insert(EntryValLocID, EntryValLocAsBackup);
-}
-
-/// Calculate the liveness information for the given machine function and
-/// extend ranges across basic blocks.
-bool VarLocBasedLDV::ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC) {
- LLVM_DEBUG(dbgs() << "\nDebug Range Extension\n");
-
- if (!MF.getFunction().getSubprogram())
- // VarLocBaseLDV will already have removed all DBG_VALUEs.
- return false;
-
- // Skip functions from NoDebug compilation units.
- if (MF.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
- DICompileUnit::NoDebug)
- return false;
-
- TRI = MF.getSubtarget().getRegisterInfo();
- TII = MF.getSubtarget().getInstrInfo();
- TFI = MF.getSubtarget().getFrameLowering();
- TFI->getCalleeSaves(MF, CalleeSavedRegs);
- this->TPC = TPC;
- LS.initialize(MF);
-
- bool Changed = false;
- bool OLChanged = false;
- bool MBBJoined = false;
-
- VarLocMap VarLocIDs; // Map VarLoc<>unique ID for use in bitvectors.
- OverlapMap OverlapFragments; // Map of overlapping variable fragments.
- OpenRangesSet OpenRanges(Alloc, OverlapFragments);
- // Ranges that are open until end of bb.
- VarLocInMBB OutLocs; // Ranges that exist beyond bb.
- VarLocInMBB InLocs; // Ranges that are incoming after joining.
- TransferMap Transfers; // DBG_VALUEs associated with transfers (such as
- // spills, copies and restores).
-
- VarToFragments SeenFragments;
-
- // Blocks which are artificial, i.e. blocks which exclusively contain
- // instructions without locations, or with line 0 locations.
- SmallPtrSet<const MachineBasicBlock *, 16> ArtificialBlocks;
-
- DenseMap<unsigned int, MachineBasicBlock *> OrderToBB;
- DenseMap<MachineBasicBlock *, unsigned int> BBToOrder;
- std::priority_queue<unsigned int, std::vector<unsigned int>,
- std::greater<unsigned int>>
- Worklist;
- std::priority_queue<unsigned int, std::vector<unsigned int>,
- std::greater<unsigned int>>
- Pending;
-
- // Set of register defines that are seen when traversing the entry block
- // looking for debug entry value candidates.
- DefinedRegsSet DefinedRegs;
-
- // Only in the case of entry MBB collect DBG_VALUEs representing
- // function parameters in order to generate debug entry values for them.
- MachineBasicBlock &First_MBB = *(MF.begin());
- for (auto &MI : First_MBB) {
- collectRegDefs(MI, DefinedRegs, TRI);
- if (MI.isDebugValue())
- recordEntryValue(MI, DefinedRegs, OpenRanges, VarLocIDs);
- }
-
- // Initialize per-block structures and scan for fragment overlaps.
- for (auto &MBB : MF)
- for (auto &MI : MBB)
- if (MI.isDebugValue())
- accumulateFragmentMap(MI, SeenFragments, OverlapFragments);
-
- auto hasNonArtificialLocation = [](const MachineInstr &MI) -> bool {
- if (const DebugLoc &DL = MI.getDebugLoc())
- return DL.getLine() != 0;
- return false;
- };
- for (auto &MBB : MF)
- if (none_of(MBB.instrs(), hasNonArtificialLocation))
- ArtificialBlocks.insert(&MBB);
-
- LLVM_DEBUG(printVarLocInMBB(MF, OutLocs, VarLocIDs,
- "OutLocs after initialization", dbgs()));
-
- ReversePostOrderTraversal<MachineFunction *> RPOT(&MF);
- unsigned int RPONumber = 0;
- for (auto RI = RPOT.begin(), RE = RPOT.end(); RI != RE; ++RI) {
- OrderToBB[RPONumber] = *RI;
- BBToOrder[*RI] = RPONumber;
- Worklist.push(RPONumber);
- ++RPONumber;
- }
-
- if (RPONumber > InputBBLimit) {
- unsigned NumInputDbgValues = 0;
- for (auto &MBB : MF)
- for (auto &MI : MBB)
- if (MI.isDebugValue())
- ++NumInputDbgValues;
- if (NumInputDbgValues > InputDbgValueLimit) {
- LLVM_DEBUG(dbgs() << "Disabling VarLocBasedLDV: " << MF.getName()
- << " has " << RPONumber << " basic blocks and "
- << NumInputDbgValues
- << " input DBG_VALUEs, exceeding limits.\n");
- return false;
- }
- }
-
- // This is a standard "union of predecessor outs" dataflow problem.
- // To solve it, we perform join() and process() using the two worklist method
- // until the ranges converge.
- // Ranges have converged when both worklists are empty.
- SmallPtrSet<const MachineBasicBlock *, 16> Visited;
- while (!Worklist.empty() || !Pending.empty()) {
- // We track what is on the pending worklist to avoid inserting the same
- // thing twice. We could avoid this with a custom priority queue, but this
- // is probably not worth it.
- SmallPtrSet<MachineBasicBlock *, 16> OnPending;
- LLVM_DEBUG(dbgs() << "Processing Worklist\n");
- while (!Worklist.empty()) {
- MachineBasicBlock *MBB = OrderToBB[Worklist.top()];
- Worklist.pop();
- MBBJoined = join(*MBB, OutLocs, InLocs, VarLocIDs, Visited,
- ArtificialBlocks);
- MBBJoined |= Visited.insert(MBB).second;
- if (MBBJoined) {
- MBBJoined = false;
- Changed = true;
- // Now that we have started to extend ranges across BBs we need to
- // examine spill, copy and restore instructions to see whether they
- // operate with registers that correspond to user variables.
- // First load any pending inlocs.
- OpenRanges.insertFromLocSet(getVarLocsInMBB(MBB, InLocs), VarLocIDs);
- for (auto &MI : *MBB)
- process(MI, OpenRanges, VarLocIDs, Transfers);
- OLChanged |= transferTerminator(MBB, OpenRanges, OutLocs, VarLocIDs);
-
- LLVM_DEBUG(printVarLocInMBB(MF, OutLocs, VarLocIDs,
- "OutLocs after propagating", dbgs()));
- LLVM_DEBUG(printVarLocInMBB(MF, InLocs, VarLocIDs,
- "InLocs after propagating", dbgs()));
-
- if (OLChanged) {
- OLChanged = false;
- for (auto s : MBB->successors())
- if (OnPending.insert(s).second) {
- Pending.push(BBToOrder[s]);
- }
- }
- }
- }
- Worklist.swap(Pending);
- // At this point, pending must be empty, since it was just the empty
- // worklist
- assert(Pending.empty() && "Pending should be empty");
- }
-
- // Add any DBG_VALUE instructions created by location transfers.
- for (auto &TR : Transfers) {
- assert(!TR.TransferInst->isTerminator() &&
- "Cannot insert DBG_VALUE after terminator");
- MachineBasicBlock *MBB = TR.TransferInst->getParent();
- const VarLoc &VL = VarLocIDs[TR.LocationID];
- MachineInstr *MI = VL.BuildDbgValue(MF);
- MBB->insertAfterBundle(TR.TransferInst->getIterator(), MI);
- }
- Transfers.clear();
-
- // Deferred inlocs will not have had any DBG_VALUE insts created; do
- // that now.
- flushPendingLocs(InLocs, VarLocIDs);
-
- LLVM_DEBUG(printVarLocInMBB(MF, OutLocs, VarLocIDs, "Final OutLocs", dbgs()));
- LLVM_DEBUG(printVarLocInMBB(MF, InLocs, VarLocIDs, "Final InLocs", dbgs()));
- return Changed;
-}
-
-LDVImpl *
-llvm::makeVarLocBasedLiveDebugValues()
-{
- return new VarLocBasedLDV();
-}
+//===- VarLocBasedImpl.cpp - Tracking Debug Value MIs with VarLoc class----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file VarLocBasedImpl.cpp
+///
+/// LiveDebugValues is an optimistic "available expressions" dataflow
+/// algorithm. The set of expressions is the set of machine locations
+/// (registers, spill slots, constants) that a variable fragment might be
+/// located, qualified by a DIExpression and indirect-ness flag, while each
+/// variable is identified by a DebugVariable object. The availability of an
+/// expression begins when a DBG_VALUE instruction specifies the location of a
+/// DebugVariable, and continues until that location is clobbered or
+/// re-specified by a different DBG_VALUE for the same DebugVariable.
+///
+/// The output of LiveDebugValues is additional DBG_VALUE instructions,
+/// placed to extend variable locations as far they're available. This file
+/// and the VarLocBasedLDV class is an implementation that explicitly tracks
+/// locations, using the VarLoc class.
+///
+/// The canonical "available expressions" problem doesn't have expression
+/// clobbering, instead when a variable is re-assigned, any expressions using
+/// that variable get invalidated. LiveDebugValues can map onto "available
+/// expressions" by having every register represented by a variable, which is
+/// used in an expression that becomes available at a DBG_VALUE instruction.
+/// When the register is clobbered, its variable is effectively reassigned, and
+/// expressions computed from it become unavailable. A similar construct is
+/// needed when a DebugVariable has its location re-specified, to invalidate
+/// all other locations for that DebugVariable.
+///
+/// Using the dataflow analysis to compute the available expressions, we create
+/// a DBG_VALUE at the beginning of each block where the expression is
+/// live-in. This propagates variable locations into every basic block where
+/// the location can be determined, rather than only having DBG_VALUEs in blocks
+/// where locations are specified due to an assignment or some optimization.
+/// Movements of values between registers and spill slots are annotated with
+/// DBG_VALUEs too to track variable values bewteen locations. All this allows
+/// DbgEntityHistoryCalculator to focus on only the locations within individual
+/// blocks, facilitating testing and improving modularity.
+///
+/// We follow an optimisic dataflow approach, with this lattice:
+///
+/// \verbatim
+/// ┬ "Unknown"
+/// |
+/// v
+/// True
+/// |
+/// v
+/// ⊥ False
+/// \endverbatim With "True" signifying that the expression is available (and
+/// thus a DebugVariable's location is the corresponding register), while
+/// "False" signifies that the expression is unavailable. "Unknown"s never
+/// survive to the end of the analysis (see below).
+///
+/// Formally, all DebugVariable locations that are live-out of a block are
+/// initialized to \top. A blocks live-in values take the meet of the lattice
+/// value for every predecessors live-outs, except for the entry block, where
+/// all live-ins are \bot. The usual dataflow propagation occurs: the transfer
+/// function for a block assigns an expression for a DebugVariable to be "True"
+/// if a DBG_VALUE in the block specifies it; "False" if the location is
+/// clobbered; or the live-in value if it is unaffected by the block. We
+/// visit each block in reverse post order until a fixedpoint is reached. The
+/// solution produced is maximal.
+///
+/// Intuitively, we start by assuming that every expression / variable location
+/// is at least "True", and then propagate "False" from the entry block and any
+/// clobbers until there are no more changes to make. This gives us an accurate
+/// solution because all incorrect locations will have a "False" propagated into
+/// them. It also gives us a solution that copes well with loops by assuming
+/// that variable locations are live-through every loop, and then removing those
+/// that are not through dataflow.
+///
+/// Within LiveDebugValues: each variable location is represented by a
+/// VarLoc object that identifies the source variable, its current
+/// machine-location, and the DBG_VALUE inst that specifies the location. Each
+/// VarLoc is indexed in the (function-scope) \p VarLocMap, giving each VarLoc a
+/// unique index. Rather than operate directly on machine locations, the
+/// dataflow analysis in this pass identifies locations by their index in the
+/// VarLocMap, meaning all the variable locations in a block can be described
+/// by a sparse vector of VarLocMap indicies.
+///
+/// All the storage for the dataflow analysis is local to the ExtendRanges
+/// method and passed down to helper methods. "OutLocs" and "InLocs" record the
+/// in and out lattice values for each block. "OpenRanges" maintains a list of
+/// variable locations and, with the "process" method, evaluates the transfer
+/// function of each block. "flushPendingLocs" installs DBG_VALUEs for each
+/// live-in location at the start of blocks, while "Transfers" records
+/// transfers of values between machine-locations.
+///
+/// We avoid explicitly representing the "Unknown" (\top) lattice value in the
+/// implementation. Instead, unvisited blocks implicitly have all lattice
+/// values set as "Unknown". After being visited, there will be path back to
+/// the entry block where the lattice value is "False", and as the transfer
+/// function cannot make new "Unknown" locations, there are no scenarios where
+/// a block can have an "Unknown" location after being visited. Similarly, we
+/// don't enumerate all possible variable locations before exploring the
+/// function: when a new location is discovered, all blocks previously explored
+/// were implicitly "False" but unrecorded, and become explicitly "False" when
+/// a new VarLoc is created with its bit not set in predecessor InLocs or
+/// OutLocs.
+///
+//===----------------------------------------------------------------------===//
+
+#include "LiveDebugValues.h"
+
+#include "llvm/ADT/CoalescingBitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/UniqueVector.h"
+#include "llvm/CodeGen/LexicalScopes.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/CodeGen/RegisterScavenging.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/Config/llvm-config.h"
+#include "llvm/IR/DIBuilder.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/TypeSize.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetMachine.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <functional>
+#include <queue>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "livedebugvalues"
+
+STATISTIC(NumInserted, "Number of DBG_VALUE instructions inserted");
+
+// Options to prevent pathological compile-time behavior. If InputBBLimit and
+// InputDbgValueLimit are both exceeded, range extension is disabled.
+static cl::opt<unsigned> InputBBLimit(
+ "livedebugvalues-input-bb-limit",
+ cl::desc("Maximum input basic blocks before DBG_VALUE limit applies"),
+ cl::init(10000), cl::Hidden);
+static cl::opt<unsigned> InputDbgValueLimit(
+ "livedebugvalues-input-dbg-value-limit",
+ cl::desc(
+ "Maximum input DBG_VALUE insts supported by debug range extension"),
+ cl::init(50000), cl::Hidden);
+
+// If @MI is a DBG_VALUE with debug value described by a defined
+// register, returns the number of this register. In the other case, returns 0.
+static Register isDbgValueDescribedByReg(const MachineInstr &MI) {
+ assert(MI.isDebugValue() && "expected a DBG_VALUE");
+ assert(MI.getNumOperands() == 4 && "malformed DBG_VALUE");
+ // If location of variable is described using a register (directly
+ // or indirectly), this register is always a first operand.
+ return MI.getDebugOperand(0).isReg() ? MI.getDebugOperand(0).getReg()
+ : Register();
+}
+
+/// If \p Op is a stack or frame register return true, otherwise return false.
+/// This is used to avoid basing the debug entry values on the registers, since
+/// we do not support it at the moment.
+static bool isRegOtherThanSPAndFP(const MachineOperand &Op,
+ const MachineInstr &MI,
+ const TargetRegisterInfo *TRI) {
+ if (!Op.isReg())
+ return false;
+
+ const MachineFunction *MF = MI.getParent()->getParent();
+ const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();
+ Register SP = TLI->getStackPointerRegisterToSaveRestore();
+ Register FP = TRI->getFrameRegister(*MF);
+ Register Reg = Op.getReg();
+
+ return Reg && Reg != SP && Reg != FP;
+}
+
+namespace {
+
+// Max out the number of statically allocated elements in DefinedRegsSet, as
+// this prevents fallback to std::set::count() operations.
+using DefinedRegsSet = SmallSet<Register, 32>;
+
+using VarLocSet = CoalescingBitVector<uint64_t>;
+
+/// A type-checked pair of {Register Location (or 0), Index}, used to index
+/// into a \ref VarLocMap. This can be efficiently converted to a 64-bit int
+/// for insertion into a \ref VarLocSet, and efficiently converted back. The
+/// type-checker helps ensure that the conversions aren't lossy.
+///
+/// Why encode a location /into/ the VarLocMap index? This makes it possible
+/// to find the open VarLocs killed by a register def very quickly. This is a
+/// performance-critical operation for LiveDebugValues.
+struct LocIndex {
+ using u32_location_t = uint32_t;
+ using u32_index_t = uint32_t;
+
+ u32_location_t Location; // Physical registers live in the range [1;2^30) (see
+ // \ref MCRegister), so we have plenty of range left
+ // here to encode non-register locations.
+ u32_index_t Index;
+
+ /// The first location greater than 0 that is not reserved for VarLocs of
+ /// kind RegisterKind.
+ static constexpr u32_location_t kFirstInvalidRegLocation = 1 << 30;
+
+ /// A special location reserved for VarLocs of kind SpillLocKind.
+ static constexpr u32_location_t kSpillLocation = kFirstInvalidRegLocation;
+
+ /// A special location reserved for VarLocs of kind EntryValueBackupKind and
+ /// EntryValueCopyBackupKind.
+ static constexpr u32_location_t kEntryValueBackupLocation =
+ kFirstInvalidRegLocation + 1;
+
+ LocIndex(u32_location_t Location, u32_index_t Index)
+ : Location(Location), Index(Index) {}
+
+ uint64_t getAsRawInteger() const {
+ return (static_cast<uint64_t>(Location) << 32) | Index;
+ }
+
+ template<typename IntT> static LocIndex fromRawInteger(IntT ID) {
+ static_assert(std::is_unsigned<IntT>::value &&
+ sizeof(ID) == sizeof(uint64_t),
+ "Cannot convert raw integer to LocIndex");
+ return {static_cast<u32_location_t>(ID >> 32),
+ static_cast<u32_index_t>(ID)};
+ }
+
+ /// Get the start of the interval reserved for VarLocs of kind RegisterKind
+ /// which reside in \p Reg. The end is at rawIndexForReg(Reg+1)-1.
+ static uint64_t rawIndexForReg(uint32_t Reg) {
+ return LocIndex(Reg, 0).getAsRawInteger();
+ }
+
+ /// Return a range covering all set indices in the interval reserved for
+ /// \p Location in \p Set.
+ static auto indexRangeForLocation(const VarLocSet &Set,
+ u32_location_t Location) {
+ uint64_t Start = LocIndex(Location, 0).getAsRawInteger();
+ uint64_t End = LocIndex(Location + 1, 0).getAsRawInteger();
+ return Set.half_open_range(Start, End);
+ }
+};
+
+class VarLocBasedLDV : public LDVImpl {
+private:
+ const TargetRegisterInfo *TRI;
+ const TargetInstrInfo *TII;
+ const TargetFrameLowering *TFI;
+ TargetPassConfig *TPC;
+ BitVector CalleeSavedRegs;
+ LexicalScopes LS;
+ VarLocSet::Allocator Alloc;
+
+ enum struct TransferKind { TransferCopy, TransferSpill, TransferRestore };
+
+ using FragmentInfo = DIExpression::FragmentInfo;
+ using OptFragmentInfo = Optional<DIExpression::FragmentInfo>;
+
+ /// A pair of debug variable and value location.
+ struct VarLoc {
+ // The location at which a spilled variable resides. It consists of a
+ // register and an offset.
+ struct SpillLoc {
+ unsigned SpillBase;
+ StackOffset SpillOffset;
+ bool operator==(const SpillLoc &Other) const {
+ return SpillBase == Other.SpillBase && SpillOffset == Other.SpillOffset;
+ }
+ bool operator!=(const SpillLoc &Other) const {
+ return !(*this == Other);
+ }
+ };
+
+ /// Identity of the variable at this location.
+ const DebugVariable Var;
+
+ /// The expression applied to this location.
+ const DIExpression *Expr;
+
+ /// DBG_VALUE to clone var/expr information from if this location
+ /// is moved.
+ const MachineInstr &MI;
+
+ enum VarLocKind {
+ InvalidKind = 0,
+ RegisterKind,
+ SpillLocKind,
+ ImmediateKind,
+ EntryValueKind,
+ EntryValueBackupKind,
+ EntryValueCopyBackupKind
+ } Kind = InvalidKind;
+
+ /// The value location. Stored separately to avoid repeatedly
+ /// extracting it from MI.
+ union LocUnion {
+ uint64_t RegNo;
+ SpillLoc SpillLocation;
+ uint64_t Hash;
+ int64_t Immediate;
+ const ConstantFP *FPImm;
+ const ConstantInt *CImm;
+ LocUnion() : Hash(0) {}
+ } Loc;
+
+ VarLoc(const MachineInstr &MI, LexicalScopes &LS)
+ : Var(MI.getDebugVariable(), MI.getDebugExpression(),
+ MI.getDebugLoc()->getInlinedAt()),
+ Expr(MI.getDebugExpression()), MI(MI) {
+ assert(MI.isDebugValue() && "not a DBG_VALUE");
+ assert(MI.getNumOperands() == 4 && "malformed DBG_VALUE");
+ if (int RegNo = isDbgValueDescribedByReg(MI)) {
+ Kind = RegisterKind;
+ Loc.RegNo = RegNo;
+ } else if (MI.getDebugOperand(0).isImm()) {
+ Kind = ImmediateKind;
+ Loc.Immediate = MI.getDebugOperand(0).getImm();
+ } else if (MI.getDebugOperand(0).isFPImm()) {
+ Kind = ImmediateKind;
+ Loc.FPImm = MI.getDebugOperand(0).getFPImm();
+ } else if (MI.getDebugOperand(0).isCImm()) {
+ Kind = ImmediateKind;
+ Loc.CImm = MI.getDebugOperand(0).getCImm();
+ }
+
+ // We create the debug entry values from the factory functions rather than
+ // from this ctor.
+ assert(Kind != EntryValueKind && !isEntryBackupLoc());
+ }
+
+ /// Take the variable and machine-location in DBG_VALUE MI, and build an
+ /// entry location using the given expression.
+ static VarLoc CreateEntryLoc(const MachineInstr &MI, LexicalScopes &LS,
+ const DIExpression *EntryExpr, Register Reg) {
+ VarLoc VL(MI, LS);
+ assert(VL.Kind == RegisterKind);
+ VL.Kind = EntryValueKind;
+ VL.Expr = EntryExpr;
+ VL.Loc.RegNo = Reg;
+ return VL;
+ }
+
+ /// Take the variable and machine-location from the DBG_VALUE (from the
+ /// function entry), and build an entry value backup location. The backup
+ /// location will turn into the normal location if the backup is valid at
+ /// the time of the primary location clobbering.
+ static VarLoc CreateEntryBackupLoc(const MachineInstr &MI,
+ LexicalScopes &LS,
+ const DIExpression *EntryExpr) {
+ VarLoc VL(MI, LS);
+ assert(VL.Kind == RegisterKind);
+ VL.Kind = EntryValueBackupKind;
+ VL.Expr = EntryExpr;
+ return VL;
+ }
+
+ /// Take the variable and machine-location from the DBG_VALUE (from the
+ /// function entry), and build a copy of an entry value backup location by
+ /// setting the register location to NewReg.
+ static VarLoc CreateEntryCopyBackupLoc(const MachineInstr &MI,
+ LexicalScopes &LS,
+ const DIExpression *EntryExpr,
+ Register NewReg) {
+ VarLoc VL(MI, LS);
+ assert(VL.Kind == RegisterKind);
+ VL.Kind = EntryValueCopyBackupKind;
+ VL.Expr = EntryExpr;
+ VL.Loc.RegNo = NewReg;
+ return VL;
+ }
+
+ /// Copy the register location in DBG_VALUE MI, updating the register to
+ /// be NewReg.
+ static VarLoc CreateCopyLoc(const MachineInstr &MI, LexicalScopes &LS,
+ Register NewReg) {
+ VarLoc VL(MI, LS);
+ assert(VL.Kind == RegisterKind);
+ VL.Loc.RegNo = NewReg;
+ return VL;
+ }
+
+ /// Take the variable described by DBG_VALUE MI, and create a VarLoc
+ /// locating it in the specified spill location.
+ static VarLoc CreateSpillLoc(const MachineInstr &MI, unsigned SpillBase,
+ StackOffset SpillOffset, LexicalScopes &LS) {
+ VarLoc VL(MI, LS);
+ assert(VL.Kind == RegisterKind);
+ VL.Kind = SpillLocKind;
+ VL.Loc.SpillLocation = {SpillBase, SpillOffset};
+ return VL;
+ }
+
+ /// Create a DBG_VALUE representing this VarLoc in the given function.
+ /// Copies variable-specific information such as DILocalVariable and
+ /// inlining information from the original DBG_VALUE instruction, which may
+ /// have been several transfers ago.
+ MachineInstr *BuildDbgValue(MachineFunction &MF) const {
+ const DebugLoc &DbgLoc = MI.getDebugLoc();
+ bool Indirect = MI.isIndirectDebugValue();
+ const auto &IID = MI.getDesc();
+ const DILocalVariable *Var = MI.getDebugVariable();
+ const DIExpression *DIExpr = MI.getDebugExpression();
+ NumInserted++;
+
+ switch (Kind) {
+ case EntryValueKind:
+ // An entry value is a register location -- but with an updated
+ // expression. The register location of such DBG_VALUE is always the one
+ // from the entry DBG_VALUE, it does not matter if the entry value was
+ // copied in to another register due to some optimizations.
+ return BuildMI(MF, DbgLoc, IID, Indirect,
+ MI.getDebugOperand(0).getReg(), Var, Expr);
+ case RegisterKind:
+ // Register locations are like the source DBG_VALUE, but with the
+ // register number from this VarLoc.
+ return BuildMI(MF, DbgLoc, IID, Indirect, Loc.RegNo, Var, DIExpr);
+ case SpillLocKind: {
+ // Spills are indirect DBG_VALUEs, with a base register and offset.
+ // Use the original DBG_VALUEs expression to build the spilt location
+ // on top of. FIXME: spill locations created before this pass runs
+ // are not recognized, and not handled here.
+ auto *TRI = MF.getSubtarget().getRegisterInfo();
+ auto *SpillExpr = TRI->prependOffsetExpression(
+ DIExpr, DIExpression::ApplyOffset, Loc.SpillLocation.SpillOffset);
+ unsigned Base = Loc.SpillLocation.SpillBase;
+ return BuildMI(MF, DbgLoc, IID, true, Base, Var, SpillExpr);
+ }
+ case ImmediateKind: {
+ MachineOperand MO = MI.getDebugOperand(0);
+ return BuildMI(MF, DbgLoc, IID, Indirect, MO, Var, DIExpr);
+ }
+ case EntryValueBackupKind:
+ case EntryValueCopyBackupKind:
+ case InvalidKind:
+ llvm_unreachable(
+ "Tried to produce DBG_VALUE for invalid or backup VarLoc");
+ }
+ llvm_unreachable("Unrecognized VarLocBasedLDV.VarLoc.Kind enum");
+ }
+
+ /// Is the Loc field a constant or constant object?
+ bool isConstant() const { return Kind == ImmediateKind; }
+
+ /// Check if the Loc field is an entry backup location.
+ bool isEntryBackupLoc() const {
+ return Kind == EntryValueBackupKind || Kind == EntryValueCopyBackupKind;
+ }
+
+ /// If this variable is described by a register holding the entry value,
+ /// return it, otherwise return 0.
+ unsigned getEntryValueBackupReg() const {
+ if (Kind == EntryValueBackupKind)
+ return Loc.RegNo;
+ return 0;
+ }
+
+ /// If this variable is described by a register holding the copy of the
+ /// entry value, return it, otherwise return 0.
+ unsigned getEntryValueCopyBackupReg() const {
+ if (Kind == EntryValueCopyBackupKind)
+ return Loc.RegNo;
+ return 0;
+ }
+
+ /// If this variable is described by a register, return it,
+ /// otherwise return 0.
+ unsigned isDescribedByReg() const {
+ if (Kind == RegisterKind)
+ return Loc.RegNo;
+ return 0;
+ }
+
+ /// Determine whether the lexical scope of this value's debug location
+ /// dominates MBB.
+ bool dominates(LexicalScopes &LS, MachineBasicBlock &MBB) const {
+ return LS.dominates(MI.getDebugLoc().get(), &MBB);
+ }
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ // TRI can be null.
+ void dump(const TargetRegisterInfo *TRI, raw_ostream &Out = dbgs()) const {
+ Out << "VarLoc(";
+ switch (Kind) {
+ case RegisterKind:
+ case EntryValueKind:
+ case EntryValueBackupKind:
+ case EntryValueCopyBackupKind:
+ Out << printReg(Loc.RegNo, TRI);
+ break;
+ case SpillLocKind:
+ Out << printReg(Loc.SpillLocation.SpillBase, TRI);
+ Out << "[" << Loc.SpillLocation.SpillOffset.getFixed() << " + "
+ << Loc.SpillLocation.SpillOffset.getScalable() << "x vscale"
+ << "]";
+ break;
+ case ImmediateKind:
+ Out << Loc.Immediate;
+ break;
+ case InvalidKind:
+ llvm_unreachable("Invalid VarLoc in dump method");
+ }
+
+ Out << ", \"" << Var.getVariable()->getName() << "\", " << *Expr << ", ";
+ if (Var.getInlinedAt())
+ Out << "!" << Var.getInlinedAt()->getMetadataID() << ")\n";
+ else
+ Out << "(null))";
+
+ if (isEntryBackupLoc())
+ Out << " (backup loc)\n";
+ else
+ Out << "\n";
+ }
+#endif
+
+ bool operator==(const VarLoc &Other) const {
+ if (Kind != Other.Kind || !(Var == Other.Var) || Expr != Other.Expr)
+ return false;
+
+ switch (Kind) {
+ case SpillLocKind:
+ return Loc.SpillLocation == Other.Loc.SpillLocation;
+ case RegisterKind:
+ case ImmediateKind:
+ case EntryValueKind:
+ case EntryValueBackupKind:
+ case EntryValueCopyBackupKind:
+ return Loc.Hash == Other.Loc.Hash;
+ default:
+ llvm_unreachable("Invalid kind");
+ }
+ }
+
+ /// This operator guarantees that VarLocs are sorted by Variable first.
+ bool operator<(const VarLoc &Other) const {
+ switch (Kind) {
+ case SpillLocKind:
+ return std::make_tuple(Var, Kind, Loc.SpillLocation.SpillBase,
+ Loc.SpillLocation.SpillOffset.getFixed(),
+ Loc.SpillLocation.SpillOffset.getScalable(),
+ Expr) <
+ std::make_tuple(
+ Other.Var, Other.Kind, Other.Loc.SpillLocation.SpillBase,
+ Other.Loc.SpillLocation.SpillOffset.getFixed(),
+ Other.Loc.SpillLocation.SpillOffset.getScalable(),
+ Other.Expr);
+ case RegisterKind:
+ case ImmediateKind:
+ case EntryValueKind:
+ case EntryValueBackupKind:
+ case EntryValueCopyBackupKind:
+ return std::tie(Var, Kind, Loc.Hash, Expr) <
+ std::tie(Other.Var, Other.Kind, Other.Loc.Hash, Other.Expr);
+ default:
+ llvm_unreachable("Invalid kind");
+ }
+ }
+ };
+
+ /// VarLocMap is used for two things:
+ /// 1) Assigning a unique LocIndex to a VarLoc. This LocIndex can be used to
+ /// virtually insert a VarLoc into a VarLocSet.
+ /// 2) Given a LocIndex, look up the unique associated VarLoc.
+ class VarLocMap {
+ /// Map a VarLoc to an index within the vector reserved for its location
+ /// within Loc2Vars.
+ std::map<VarLoc, LocIndex::u32_index_t> Var2Index;
+
+ /// Map a location to a vector which holds VarLocs which live in that
+ /// location.
+ SmallDenseMap<LocIndex::u32_location_t, std::vector<VarLoc>> Loc2Vars;
+
+ /// Determine the 32-bit location reserved for \p VL, based on its kind.
+ static LocIndex::u32_location_t getLocationForVar(const VarLoc &VL) {
+ switch (VL.Kind) {
+ case VarLoc::RegisterKind:
+ assert((VL.Loc.RegNo < LocIndex::kFirstInvalidRegLocation) &&
+ "Physreg out of range?");
+ return VL.Loc.RegNo;
+ case VarLoc::SpillLocKind:
+ return LocIndex::kSpillLocation;
+ case VarLoc::EntryValueBackupKind:
+ case VarLoc::EntryValueCopyBackupKind:
+ return LocIndex::kEntryValueBackupLocation;
+ default:
+ return 0;
+ }
+ }
+
+ public:
+ /// Retrieve a unique LocIndex for \p VL.
+ LocIndex insert(const VarLoc &VL) {
+ LocIndex::u32_location_t Location = getLocationForVar(VL);
+ LocIndex::u32_index_t &Index = Var2Index[VL];
+ if (!Index) {
+ auto &Vars = Loc2Vars[Location];
+ Vars.push_back(VL);
+ Index = Vars.size();
+ }
+ return {Location, Index - 1};
+ }
+
+ /// Retrieve the unique VarLoc associated with \p ID.
+ const VarLoc &operator[](LocIndex ID) const {
+ auto LocIt = Loc2Vars.find(ID.Location);
+ assert(LocIt != Loc2Vars.end() && "Location not tracked");
+ return LocIt->second[ID.Index];
+ }
+ };
+
+ using VarLocInMBB =
+ SmallDenseMap<const MachineBasicBlock *, std::unique_ptr<VarLocSet>>;
+ struct TransferDebugPair {
+ MachineInstr *TransferInst; ///< Instruction where this transfer occurs.
+ LocIndex LocationID; ///< Location number for the transfer dest.
+ };
+ using TransferMap = SmallVector<TransferDebugPair, 4>;
+
+ // Types for recording sets of variable fragments that overlap. For a given
+ // local variable, we record all other fragments of that variable that could
+ // overlap it, to reduce search time.
+ using FragmentOfVar =
+ std::pair<const DILocalVariable *, DIExpression::FragmentInfo>;
+ using OverlapMap =
+ DenseMap<FragmentOfVar, SmallVector<DIExpression::FragmentInfo, 1>>;
+
+ // Helper while building OverlapMap, a map of all fragments seen for a given
+ // DILocalVariable.
+ using VarToFragments =
+ DenseMap<const DILocalVariable *, SmallSet<FragmentInfo, 4>>;
+
+ /// This holds the working set of currently open ranges. For fast
+ /// access, this is done both as a set of VarLocIDs, and a map of
+ /// DebugVariable to recent VarLocID. Note that a DBG_VALUE ends all
+ /// previous open ranges for the same variable. In addition, we keep
+ /// two different maps (Vars/EntryValuesBackupVars), so erase/insert
+ /// methods act differently depending on whether a VarLoc is primary
+ /// location or backup one. In the case the VarLoc is backup location
+ /// we will erase/insert from the EntryValuesBackupVars map, otherwise
+ /// we perform the operation on the Vars.
+ class OpenRangesSet {
+ VarLocSet VarLocs;
+ // Map the DebugVariable to recent primary location ID.
+ SmallDenseMap<DebugVariable, LocIndex, 8> Vars;
+ // Map the DebugVariable to recent backup location ID.
+ SmallDenseMap<DebugVariable, LocIndex, 8> EntryValuesBackupVars;
+ OverlapMap &OverlappingFragments;
+
+ public:
+ OpenRangesSet(VarLocSet::Allocator &Alloc, OverlapMap &_OLapMap)
+ : VarLocs(Alloc), OverlappingFragments(_OLapMap) {}
+
+ const VarLocSet &getVarLocs() const { return VarLocs; }
+
+ /// Terminate all open ranges for VL.Var by removing it from the set.
+ void erase(const VarLoc &VL);
+
+ /// Terminate all open ranges listed in \c KillSet by removing
+ /// them from the set.
+ void erase(const VarLocSet &KillSet, const VarLocMap &VarLocIDs);
+
+ /// Insert a new range into the set.
+ void insert(LocIndex VarLocID, const VarLoc &VL);
+
+ /// Insert a set of ranges.
+ void insertFromLocSet(const VarLocSet &ToLoad, const VarLocMap &Map) {
+ for (uint64_t ID : ToLoad) {
+ LocIndex Idx = LocIndex::fromRawInteger(ID);
+ const VarLoc &VarL = Map[Idx];
+ insert(Idx, VarL);
+ }
+ }
+
+ llvm::Optional<LocIndex> getEntryValueBackup(DebugVariable Var);
+
+ /// Empty the set.
+ void clear() {
+ VarLocs.clear();
+ Vars.clear();
+ EntryValuesBackupVars.clear();
+ }
+
+ /// Return whether the set is empty or not.
+ bool empty() const {
+ assert(Vars.empty() == EntryValuesBackupVars.empty() &&
+ Vars.empty() == VarLocs.empty() &&
+ "open ranges are inconsistent");
+ return VarLocs.empty();
+ }
+
+ /// Get an empty range of VarLoc IDs.
+ auto getEmptyVarLocRange() const {
+ return iterator_range<VarLocSet::const_iterator>(getVarLocs().end(),
+ getVarLocs().end());
+ }
+
+ /// Get all set IDs for VarLocs of kind RegisterKind in \p Reg.
+ auto getRegisterVarLocs(Register Reg) const {
+ return LocIndex::indexRangeForLocation(getVarLocs(), Reg);
+ }
+
+ /// Get all set IDs for VarLocs of kind SpillLocKind.
+ auto getSpillVarLocs() const {
+ return LocIndex::indexRangeForLocation(getVarLocs(),
+ LocIndex::kSpillLocation);
+ }
+
+ /// Get all set IDs for VarLocs of kind EntryValueBackupKind or
+ /// EntryValueCopyBackupKind.
+ auto getEntryValueBackupVarLocs() const {
+ return LocIndex::indexRangeForLocation(
+ getVarLocs(), LocIndex::kEntryValueBackupLocation);
+ }
+ };
+
+ /// Collect all VarLoc IDs from \p CollectFrom for VarLocs of kind
+ /// RegisterKind which are located in any reg in \p Regs. Insert collected IDs
+ /// into \p Collected.
+ void collectIDsForRegs(VarLocSet &Collected, const DefinedRegsSet &Regs,
+ const VarLocSet &CollectFrom) const;
+
+ /// Get the registers which are used by VarLocs of kind RegisterKind tracked
+ /// by \p CollectFrom.
+ void getUsedRegs(const VarLocSet &CollectFrom,
+ SmallVectorImpl<uint32_t> &UsedRegs) const;
+
+ VarLocSet &getVarLocsInMBB(const MachineBasicBlock *MBB, VarLocInMBB &Locs) {
+ std::unique_ptr<VarLocSet> &VLS = Locs[MBB];
+ if (!VLS)
+ VLS = std::make_unique<VarLocSet>(Alloc);
+ return *VLS.get();
+ }
+
+ const VarLocSet &getVarLocsInMBB(const MachineBasicBlock *MBB,
+ const VarLocInMBB &Locs) const {
+ auto It = Locs.find(MBB);
+ assert(It != Locs.end() && "MBB not in map");
+ return *It->second.get();
+ }
+
+ /// Tests whether this instruction is a spill to a stack location.
+ bool isSpillInstruction(const MachineInstr &MI, MachineFunction *MF);
+
+ /// Decide if @MI is a spill instruction and return true if it is. We use 2
+ /// criteria to make this decision:
+ /// - Is this instruction a store to a spill slot?
+ /// - Is there a register operand that is both used and killed?
+ /// TODO: Store optimization can fold spills into other stores (including
+ /// other spills). We do not handle this yet (more than one memory operand).
+ bool isLocationSpill(const MachineInstr &MI, MachineFunction *MF,
+ Register &Reg);
+
+ /// Returns true if the given machine instruction is a debug value which we
+ /// can emit entry values for.
+ ///
+ /// Currently, we generate debug entry values only for parameters that are
+ /// unmodified throughout the function and located in a register.
+ bool isEntryValueCandidate(const MachineInstr &MI,
+ const DefinedRegsSet &Regs) const;
+
+ /// If a given instruction is identified as a spill, return the spill location
+ /// and set \p Reg to the spilled register.
+ Optional<VarLoc::SpillLoc> isRestoreInstruction(const MachineInstr &MI,
+ MachineFunction *MF,
+ Register &Reg);
+ /// Given a spill instruction, extract the register and offset used to
+ /// address the spill location in a target independent way.
+ VarLoc::SpillLoc extractSpillBaseRegAndOffset(const MachineInstr &MI);
+ void insertTransferDebugPair(MachineInstr &MI, OpenRangesSet &OpenRanges,
+ TransferMap &Transfers, VarLocMap &VarLocIDs,
+ LocIndex OldVarID, TransferKind Kind,
+ Register NewReg = Register());
+
+ void transferDebugValue(const MachineInstr &MI, OpenRangesSet &OpenRanges,
+ VarLocMap &VarLocIDs);
+ void transferSpillOrRestoreInst(MachineInstr &MI, OpenRangesSet &OpenRanges,
+ VarLocMap &VarLocIDs, TransferMap &Transfers);
+ bool removeEntryValue(const MachineInstr &MI, OpenRangesSet &OpenRanges,
+ VarLocMap &VarLocIDs, const VarLoc &EntryVL);
+ void emitEntryValues(MachineInstr &MI, OpenRangesSet &OpenRanges,
+ VarLocMap &VarLocIDs, TransferMap &Transfers,
+ VarLocSet &KillSet);
+ void recordEntryValue(const MachineInstr &MI,
+ const DefinedRegsSet &DefinedRegs,
+ OpenRangesSet &OpenRanges, VarLocMap &VarLocIDs);
+ void transferRegisterCopy(MachineInstr &MI, OpenRangesSet &OpenRanges,
+ VarLocMap &VarLocIDs, TransferMap &Transfers);
+ void transferRegisterDef(MachineInstr &MI, OpenRangesSet &OpenRanges,
+ VarLocMap &VarLocIDs, TransferMap &Transfers);
+ bool transferTerminator(MachineBasicBlock *MBB, OpenRangesSet &OpenRanges,
+ VarLocInMBB &OutLocs, const VarLocMap &VarLocIDs);
+
+ void process(MachineInstr &MI, OpenRangesSet &OpenRanges,
+ VarLocMap &VarLocIDs, TransferMap &Transfers);
+
+ void accumulateFragmentMap(MachineInstr &MI, VarToFragments &SeenFragments,
+ OverlapMap &OLapMap);
+
+ bool join(MachineBasicBlock &MBB, VarLocInMBB &OutLocs, VarLocInMBB &InLocs,
+ const VarLocMap &VarLocIDs,
+ SmallPtrSet<const MachineBasicBlock *, 16> &Visited,
+ SmallPtrSetImpl<const MachineBasicBlock *> &ArtificialBlocks);
+
+ /// Create DBG_VALUE insts for inlocs that have been propagated but
+ /// had their instruction creation deferred.
+ void flushPendingLocs(VarLocInMBB &PendingInLocs, VarLocMap &VarLocIDs);
+
+ bool ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC) override;
+
+public:
+ /// Default construct and initialize the pass.
+ VarLocBasedLDV();
+
+ ~VarLocBasedLDV();
+
+ /// Print to ostream with a message.
+ void printVarLocInMBB(const MachineFunction &MF, const VarLocInMBB &V,
+ const VarLocMap &VarLocIDs, const char *msg,
+ raw_ostream &Out) const;
+};
+
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Implementation
+//===----------------------------------------------------------------------===//
+
+VarLocBasedLDV::VarLocBasedLDV() { }
+
+VarLocBasedLDV::~VarLocBasedLDV() { }
+
+/// Erase a variable from the set of open ranges, and additionally erase any
+/// fragments that may overlap it. If the VarLoc is a backup location, erase
+/// the variable from the EntryValuesBackupVars set, indicating we should stop
+/// tracking its backup entry location. Otherwise, if the VarLoc is primary
+/// location, erase the variable from the Vars set.
+void VarLocBasedLDV::OpenRangesSet::erase(const VarLoc &VL) {
+ // Erasure helper.
+ auto DoErase = [VL, this](DebugVariable VarToErase) {
+ auto *EraseFrom = VL.isEntryBackupLoc() ? &EntryValuesBackupVars : &Vars;
+ auto It = EraseFrom->find(VarToErase);
+ if (It != EraseFrom->end()) {
+ LocIndex ID = It->second;
+ VarLocs.reset(ID.getAsRawInteger());
+ EraseFrom->erase(It);
+ }
+ };
+
+ DebugVariable Var = VL.Var;
+
+ // Erase the variable/fragment that ends here.
+ DoErase(Var);
+
+ // Extract the fragment. Interpret an empty fragment as one that covers all
+ // possible bits.
+ FragmentInfo ThisFragment = Var.getFragmentOrDefault();
+
+ // There may be fragments that overlap the designated fragment. Look them up
+ // in the pre-computed overlap map, and erase them too.
+ auto MapIt = OverlappingFragments.find({Var.getVariable(), ThisFragment});
+ if (MapIt != OverlappingFragments.end()) {
+ for (auto Fragment : MapIt->second) {
+ VarLocBasedLDV::OptFragmentInfo FragmentHolder;
+ if (!DebugVariable::isDefaultFragment(Fragment))
+ FragmentHolder = VarLocBasedLDV::OptFragmentInfo(Fragment);
+ DoErase({Var.getVariable(), FragmentHolder, Var.getInlinedAt()});
+ }
+ }
+}
+
+void VarLocBasedLDV::OpenRangesSet::erase(const VarLocSet &KillSet,
+ const VarLocMap &VarLocIDs) {
+ VarLocs.intersectWithComplement(KillSet);
+ for (uint64_t ID : KillSet) {
+ const VarLoc *VL = &VarLocIDs[LocIndex::fromRawInteger(ID)];
+ auto *EraseFrom = VL->isEntryBackupLoc() ? &EntryValuesBackupVars : &Vars;
+ EraseFrom->erase(VL->Var);
+ }
+}
+
+void VarLocBasedLDV::OpenRangesSet::insert(LocIndex VarLocID,
+ const VarLoc &VL) {
+ auto *InsertInto = VL.isEntryBackupLoc() ? &EntryValuesBackupVars : &Vars;
+ VarLocs.set(VarLocID.getAsRawInteger());
+ InsertInto->insert({VL.Var, VarLocID});
+}
+
+/// Return the Loc ID of an entry value backup location, if it exists for the
+/// variable.
+llvm::Optional<LocIndex>
+VarLocBasedLDV::OpenRangesSet::getEntryValueBackup(DebugVariable Var) {
+ auto It = EntryValuesBackupVars.find(Var);
+ if (It != EntryValuesBackupVars.end())
+ return It->second;
+
+ return llvm::None;
+}
+
+void VarLocBasedLDV::collectIDsForRegs(VarLocSet &Collected,
+ const DefinedRegsSet &Regs,
+ const VarLocSet &CollectFrom) const {
+ assert(!Regs.empty() && "Nothing to collect");
+ SmallVector<uint32_t, 32> SortedRegs;
+ for (Register Reg : Regs)
+ SortedRegs.push_back(Reg);
+ array_pod_sort(SortedRegs.begin(), SortedRegs.end());
+ auto It = CollectFrom.find(LocIndex::rawIndexForReg(SortedRegs.front()));
+ auto End = CollectFrom.end();
+ for (uint32_t Reg : SortedRegs) {
+ // The half-open interval [FirstIndexForReg, FirstInvalidIndex) contains all
+ // possible VarLoc IDs for VarLocs of kind RegisterKind which live in Reg.
+ uint64_t FirstIndexForReg = LocIndex::rawIndexForReg(Reg);
+ uint64_t FirstInvalidIndex = LocIndex::rawIndexForReg(Reg + 1);
+ It.advanceToLowerBound(FirstIndexForReg);
+
+ // Iterate through that half-open interval and collect all the set IDs.
+ for (; It != End && *It < FirstInvalidIndex; ++It)
+ Collected.set(*It);
+
+ if (It == End)
+ return;
+ }
+}
+
+void VarLocBasedLDV::getUsedRegs(const VarLocSet &CollectFrom,
+ SmallVectorImpl<uint32_t> &UsedRegs) const {
+ // All register-based VarLocs are assigned indices greater than or equal to
+ // FirstRegIndex.
+ uint64_t FirstRegIndex = LocIndex::rawIndexForReg(1);
+ uint64_t FirstInvalidIndex =
+ LocIndex::rawIndexForReg(LocIndex::kFirstInvalidRegLocation);
+ for (auto It = CollectFrom.find(FirstRegIndex),
+ End = CollectFrom.find(FirstInvalidIndex);
+ It != End;) {
+ // We found a VarLoc ID for a VarLoc that lives in a register. Figure out
+ // which register and add it to UsedRegs.
+ uint32_t FoundReg = LocIndex::fromRawInteger(*It).Location;
+ assert((UsedRegs.empty() || FoundReg != UsedRegs.back()) &&
+ "Duplicate used reg");
+ UsedRegs.push_back(FoundReg);
+
+ // Skip to the next /set/ register. Note that this finds a lower bound, so
+ // even if there aren't any VarLocs living in `FoundReg+1`, we're still
+ // guaranteed to move on to the next register (or to end()).
+ uint64_t NextRegIndex = LocIndex::rawIndexForReg(FoundReg + 1);
+ It.advanceToLowerBound(NextRegIndex);
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// Debug Range Extension Implementation
+//===----------------------------------------------------------------------===//
+
+#ifndef NDEBUG
+void VarLocBasedLDV::printVarLocInMBB(const MachineFunction &MF,
+ const VarLocInMBB &V,
+ const VarLocMap &VarLocIDs,
+ const char *msg,
+ raw_ostream &Out) const {
+ Out << '\n' << msg << '\n';
+ for (const MachineBasicBlock &BB : MF) {
+ if (!V.count(&BB))
+ continue;
+ const VarLocSet &L = getVarLocsInMBB(&BB, V);
+ if (L.empty())
+ continue;
+ Out << "MBB: " << BB.getNumber() << ":\n";
+ for (uint64_t VLL : L) {
+ const VarLoc &VL = VarLocIDs[LocIndex::fromRawInteger(VLL)];
+ Out << " Var: " << VL.Var.getVariable()->getName();
+ Out << " MI: ";
+ VL.dump(TRI, Out);
+ }
+ }
+ Out << "\n";
+}
+#endif
+
+VarLocBasedLDV::VarLoc::SpillLoc
+VarLocBasedLDV::extractSpillBaseRegAndOffset(const MachineInstr &MI) {
+ assert(MI.hasOneMemOperand() &&
+ "Spill instruction does not have exactly one memory operand?");
+ auto MMOI = MI.memoperands_begin();
+ const PseudoSourceValue *PVal = (*MMOI)->getPseudoValue();
+ assert(PVal->kind() == PseudoSourceValue::FixedStack &&
+ "Inconsistent memory operand in spill instruction");
+ int FI = cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex();
+ const MachineBasicBlock *MBB = MI.getParent();
+ Register Reg;
+ StackOffset Offset = TFI->getFrameIndexReference(*MBB->getParent(), FI, Reg);
+ return {Reg, Offset};
+}
+
+/// Try to salvage the debug entry value if we encounter a new debug value
+/// describing the same parameter, otherwise stop tracking the value. Return
+/// true if we should stop tracking the entry value, otherwise return false.
+bool VarLocBasedLDV::removeEntryValue(const MachineInstr &MI,
+ OpenRangesSet &OpenRanges,
+ VarLocMap &VarLocIDs,
+ const VarLoc &EntryVL) {
+ // Skip the DBG_VALUE which is the debug entry value itself.
+ if (MI.isIdenticalTo(EntryVL.MI))
+ return false;
+
+ // If the parameter's location is not register location, we can not track
+ // the entry value any more. In addition, if the debug expression from the
+ // DBG_VALUE is not empty, we can assume the parameter's value has changed
+ // indicating that we should stop tracking its entry value as well.
+ if (!MI.getDebugOperand(0).isReg() ||
+ MI.getDebugExpression()->getNumElements() != 0)
+ return true;
+
+ // If the DBG_VALUE comes from a copy instruction that copies the entry value,
+ // it means the parameter's value has not changed and we should be able to use
+ // its entry value.
+ bool TrySalvageEntryValue = false;
+ Register Reg = MI.getDebugOperand(0).getReg();
+ auto I = std::next(MI.getReverseIterator());
+ const MachineOperand *SrcRegOp, *DestRegOp;
+ if (I != MI.getParent()->rend()) {
+ // TODO: Try to keep tracking of an entry value if we encounter a propagated
+ // DBG_VALUE describing the copy of the entry value. (Propagated entry value
+ // does not indicate the parameter modification.)
+ auto DestSrc = TII->isCopyInstr(*I);
+ if (!DestSrc)
+ return true;
+
+ SrcRegOp = DestSrc->Source;
+ DestRegOp = DestSrc->Destination;
+ if (Reg != DestRegOp->getReg())
+ return true;
+ TrySalvageEntryValue = true;
+ }
+
+ if (TrySalvageEntryValue) {
+ for (uint64_t ID : OpenRanges.getEntryValueBackupVarLocs()) {
+ const VarLoc &VL = VarLocIDs[LocIndex::fromRawInteger(ID)];
+ if (VL.getEntryValueCopyBackupReg() == Reg &&
+ VL.MI.getDebugOperand(0).getReg() == SrcRegOp->getReg())
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/// End all previous ranges related to @MI and start a new range from @MI
+/// if it is a DBG_VALUE instr.
+void VarLocBasedLDV::transferDebugValue(const MachineInstr &MI,
+ OpenRangesSet &OpenRanges,
+ VarLocMap &VarLocIDs) {
+ if (!MI.isDebugValue())
+ return;
+ const DILocalVariable *Var = MI.getDebugVariable();
+ const DIExpression *Expr = MI.getDebugExpression();
+ const DILocation *DebugLoc = MI.getDebugLoc();
+ const DILocation *InlinedAt = DebugLoc->getInlinedAt();
+ assert(Var->isValidLocationForIntrinsic(DebugLoc) &&
+ "Expected inlined-at fields to agree");
+
+ DebugVariable V(Var, Expr, InlinedAt);
+
+ // Check if this DBG_VALUE indicates a parameter's value changing.
+ // If that is the case, we should stop tracking its entry value.
+ auto EntryValBackupID = OpenRanges.getEntryValueBackup(V);
+ if (Var->isParameter() && EntryValBackupID) {
+ const VarLoc &EntryVL = VarLocIDs[*EntryValBackupID];
+ if (removeEntryValue(MI, OpenRanges, VarLocIDs, EntryVL)) {
+ LLVM_DEBUG(dbgs() << "Deleting a DBG entry value because of: ";
+ MI.print(dbgs(), /*IsStandalone*/ false,
+ /*SkipOpers*/ false, /*SkipDebugLoc*/ false,
+ /*AddNewLine*/ true, TII));
+ OpenRanges.erase(EntryVL);
+ }
+ }
+
+ if (isDbgValueDescribedByReg(MI) || MI.getDebugOperand(0).isImm() ||
+ MI.getDebugOperand(0).isFPImm() || MI.getDebugOperand(0).isCImm()) {
+ // Use normal VarLoc constructor for registers and immediates.
+ VarLoc VL(MI, LS);
+ // End all previous ranges of VL.Var.
+ OpenRanges.erase(VL);
+
+ LocIndex ID = VarLocIDs.insert(VL);
+ // Add the VarLoc to OpenRanges from this DBG_VALUE.
+ OpenRanges.insert(ID, VL);
+ } else if (MI.hasOneMemOperand()) {
+ llvm_unreachable("DBG_VALUE with mem operand encountered after regalloc?");
+ } else {
+ // This must be an undefined location. If it has an open range, erase it.
+ assert(MI.getDebugOperand(0).isReg() &&
+ MI.getDebugOperand(0).getReg() == 0 &&
+ "Unexpected non-undef DBG_VALUE encountered");
+ VarLoc VL(MI, LS);
+ OpenRanges.erase(VL);
+ }
+}
+
+/// Turn the entry value backup locations into primary locations.
+void VarLocBasedLDV::emitEntryValues(MachineInstr &MI,
+ OpenRangesSet &OpenRanges,
+ VarLocMap &VarLocIDs,
+ TransferMap &Transfers,
+ VarLocSet &KillSet) {
+ // Do not insert entry value locations after a terminator.
+ if (MI.isTerminator())
+ return;
+
+ for (uint64_t ID : KillSet) {
+ LocIndex Idx = LocIndex::fromRawInteger(ID);
+ const VarLoc &VL = VarLocIDs[Idx];
+ if (!VL.Var.getVariable()->isParameter())
+ continue;
+
+ auto DebugVar = VL.Var;
+ Optional<LocIndex> EntryValBackupID =
+ OpenRanges.getEntryValueBackup(DebugVar);
+
+ // If the parameter has the entry value backup, it means we should
+ // be able to use its entry value.
+ if (!EntryValBackupID)
+ continue;
+
+ const VarLoc &EntryVL = VarLocIDs[*EntryValBackupID];
+ VarLoc EntryLoc =
+ VarLoc::CreateEntryLoc(EntryVL.MI, LS, EntryVL.Expr, EntryVL.Loc.RegNo);
+ LocIndex EntryValueID = VarLocIDs.insert(EntryLoc);
+ Transfers.push_back({&MI, EntryValueID});
+ OpenRanges.insert(EntryValueID, EntryLoc);
+ }
+}
+
+/// Create new TransferDebugPair and insert it in \p Transfers. The VarLoc
+/// with \p OldVarID should be deleted form \p OpenRanges and replaced with
+/// new VarLoc. If \p NewReg is different than default zero value then the
+/// new location will be register location created by the copy like instruction,
+/// otherwise it is variable's location on the stack.
+void VarLocBasedLDV::insertTransferDebugPair(
+ MachineInstr &MI, OpenRangesSet &OpenRanges, TransferMap &Transfers,
+ VarLocMap &VarLocIDs, LocIndex OldVarID, TransferKind Kind,
+ Register NewReg) {
+ const MachineInstr *DebugInstr = &VarLocIDs[OldVarID].MI;
+
+ auto ProcessVarLoc = [&MI, &OpenRanges, &Transfers, &VarLocIDs](VarLoc &VL) {
+ LocIndex LocId = VarLocIDs.insert(VL);
+
+ // Close this variable's previous location range.
+ OpenRanges.erase(VL);
+
+ // Record the new location as an open range, and a postponed transfer
+ // inserting a DBG_VALUE for this location.
+ OpenRanges.insert(LocId, VL);
+ assert(!MI.isTerminator() && "Cannot insert DBG_VALUE after terminator");
+ TransferDebugPair MIP = {&MI, LocId};
+ Transfers.push_back(MIP);
+ };
+
+ // End all previous ranges of VL.Var.
+ OpenRanges.erase(VarLocIDs[OldVarID]);
+ switch (Kind) {
+ case TransferKind::TransferCopy: {
+ assert(NewReg &&
+ "No register supplied when handling a copy of a debug value");
+ // Create a DBG_VALUE instruction to describe the Var in its new
+ // register location.
+ VarLoc VL = VarLoc::CreateCopyLoc(*DebugInstr, LS, NewReg);
+ ProcessVarLoc(VL);
+ LLVM_DEBUG({
+ dbgs() << "Creating VarLoc for register copy:";
+ VL.dump(TRI);
+ });
+ return;
+ }
+ case TransferKind::TransferSpill: {
+ // Create a DBG_VALUE instruction to describe the Var in its spilled
+ // location.
+ VarLoc::SpillLoc SpillLocation = extractSpillBaseRegAndOffset(MI);
+ VarLoc VL = VarLoc::CreateSpillLoc(*DebugInstr, SpillLocation.SpillBase,
+ SpillLocation.SpillOffset, LS);
+ ProcessVarLoc(VL);
+ LLVM_DEBUG({
+ dbgs() << "Creating VarLoc for spill:";
+ VL.dump(TRI);
+ });
+ return;
+ }
+ case TransferKind::TransferRestore: {
+ assert(NewReg &&
+ "No register supplied when handling a restore of a debug value");
+ // DebugInstr refers to the pre-spill location, therefore we can reuse
+ // its expression.
+ VarLoc VL = VarLoc::CreateCopyLoc(*DebugInstr, LS, NewReg);
+ ProcessVarLoc(VL);
+ LLVM_DEBUG({
+ dbgs() << "Creating VarLoc for restore:";
+ VL.dump(TRI);
+ });
+ return;
+ }
+ }
+ llvm_unreachable("Invalid transfer kind");
+}
+
+/// A definition of a register may mark the end of a range.
+void VarLocBasedLDV::transferRegisterDef(
+ MachineInstr &MI, OpenRangesSet &OpenRanges, VarLocMap &VarLocIDs,
+ TransferMap &Transfers) {
+
+ // Meta Instructions do not affect the debug liveness of any register they
+ // define.
+ if (MI.isMetaInstruction())
+ return;
+
+ MachineFunction *MF = MI.getMF();
+ const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();
+ Register SP = TLI->getStackPointerRegisterToSaveRestore();
+
+ // Find the regs killed by MI, and find regmasks of preserved regs.
+ DefinedRegsSet DeadRegs;
+ SmallVector<const uint32_t *, 4> RegMasks;
+ for (const MachineOperand &MO : MI.operands()) {
+ // Determine whether the operand is a register def.
+ if (MO.isReg() && MO.isDef() && MO.getReg() &&
+ Register::isPhysicalRegister(MO.getReg()) &&
+ !(MI.isCall() && MO.getReg() == SP)) {
+ // Remove ranges of all aliased registers.
+ for (MCRegAliasIterator RAI(MO.getReg(), TRI, true); RAI.isValid(); ++RAI)
+ // FIXME: Can we break out of this loop early if no insertion occurs?
+ DeadRegs.insert(*RAI);
+ } else if (MO.isRegMask()) {
+ RegMasks.push_back(MO.getRegMask());
+ }
+ }
+
+ // Erase VarLocs which reside in one of the dead registers. For performance
+ // reasons, it's critical to not iterate over the full set of open VarLocs.
+ // Iterate over the set of dying/used regs instead.
+ if (!RegMasks.empty()) {
+ SmallVector<uint32_t, 32> UsedRegs;
+ getUsedRegs(OpenRanges.getVarLocs(), UsedRegs);
+ for (uint32_t Reg : UsedRegs) {
+ // Remove ranges of all clobbered registers. Register masks don't usually
+ // list SP as preserved. Assume that call instructions never clobber SP,
+ // because some backends (e.g., AArch64) never list SP in the regmask.
+ // While the debug info may be off for an instruction or two around
+ // callee-cleanup calls, transferring the DEBUG_VALUE across the call is
+ // still a better user experience.
+ if (Reg == SP)
+ continue;
+ bool AnyRegMaskKillsReg =
+ any_of(RegMasks, [Reg](const uint32_t *RegMask) {
+ return MachineOperand::clobbersPhysReg(RegMask, Reg);
+ });
+ if (AnyRegMaskKillsReg)
+ DeadRegs.insert(Reg);
+ }
+ }
+
+ if (DeadRegs.empty())
+ return;
+
+ VarLocSet KillSet(Alloc);
+ collectIDsForRegs(KillSet, DeadRegs, OpenRanges.getVarLocs());
+ OpenRanges.erase(KillSet, VarLocIDs);
+
+ if (TPC) {
+ auto &TM = TPC->getTM<TargetMachine>();
+ if (TM.Options.ShouldEmitDebugEntryValues())
+ emitEntryValues(MI, OpenRanges, VarLocIDs, Transfers, KillSet);
+ }
+}
+
+bool VarLocBasedLDV::isSpillInstruction(const MachineInstr &MI,
+ MachineFunction *MF) {
+ // TODO: Handle multiple stores folded into one.
+ if (!MI.hasOneMemOperand())
+ return false;
+
+ if (!MI.getSpillSize(TII) && !MI.getFoldedSpillSize(TII))
+ return false; // This is not a spill instruction, since no valid size was
+ // returned from either function.
+
+ return true;
+}
+
+bool VarLocBasedLDV::isLocationSpill(const MachineInstr &MI,
+ MachineFunction *MF, Register &Reg) {
+ if (!isSpillInstruction(MI, MF))
+ return false;
+
+ auto isKilledReg = [&](const MachineOperand MO, Register &Reg) {
+ if (!MO.isReg() || !MO.isUse()) {
+ Reg = 0;
+ return false;
+ }
+ Reg = MO.getReg();
+ return MO.isKill();
+ };
+
+ for (const MachineOperand &MO : MI.operands()) {
+ // In a spill instruction generated by the InlineSpiller the spilled
+ // register has its kill flag set.
+ if (isKilledReg(MO, Reg))
+ return true;
+ if (Reg != 0) {
+ // Check whether next instruction kills the spilled register.
+ // FIXME: Current solution does not cover search for killed register in
+ // bundles and instructions further down the chain.
+ auto NextI = std::next(MI.getIterator());
+ // Skip next instruction that points to basic block end iterator.
+ if (MI.getParent()->end() == NextI)
+ continue;
+ Register RegNext;
+ for (const MachineOperand &MONext : NextI->operands()) {
+ // Return true if we came across the register from the
+ // previous spill instruction that is killed in NextI.
+ if (isKilledReg(MONext, RegNext) && RegNext == Reg)
+ return true;
+ }
+ }
+ }
+ // Return false if we didn't find spilled register.
+ return false;
+}
+
+Optional<VarLocBasedLDV::VarLoc::SpillLoc>
+VarLocBasedLDV::isRestoreInstruction(const MachineInstr &MI,
+ MachineFunction *MF, Register &Reg) {
+ if (!MI.hasOneMemOperand())
+ return None;
+
+ // FIXME: Handle folded restore instructions with more than one memory
+ // operand.
+ if (MI.getRestoreSize(TII)) {
+ Reg = MI.getOperand(0).getReg();
+ return extractSpillBaseRegAndOffset(MI);
+ }
+ return None;
+}
+
+/// A spilled register may indicate that we have to end the current range of
+/// a variable and create a new one for the spill location.
+/// A restored register may indicate the reverse situation.
+/// We don't want to insert any instructions in process(), so we just create
+/// the DBG_VALUE without inserting it and keep track of it in \p Transfers.
+/// It will be inserted into the BB when we're done iterating over the
+/// instructions.
+void VarLocBasedLDV::transferSpillOrRestoreInst(MachineInstr &MI,
+ OpenRangesSet &OpenRanges,
+ VarLocMap &VarLocIDs,
+ TransferMap &Transfers) {
+ MachineFunction *MF = MI.getMF();
+ TransferKind TKind;
+ Register Reg;
+ Optional<VarLoc::SpillLoc> Loc;
+
+ LLVM_DEBUG(dbgs() << "Examining instruction: "; MI.dump(););
+
+ // First, if there are any DBG_VALUEs pointing at a spill slot that is
+ // written to, then close the variable location. The value in memory
+ // will have changed.
+ VarLocSet KillSet(Alloc);
+ if (isSpillInstruction(MI, MF)) {
+ Loc = extractSpillBaseRegAndOffset(MI);
+ for (uint64_t ID : OpenRanges.getSpillVarLocs()) {
+ LocIndex Idx = LocIndex::fromRawInteger(ID);
+ const VarLoc &VL = VarLocIDs[Idx];
+ assert(VL.Kind == VarLoc::SpillLocKind && "Broken VarLocSet?");
+ if (VL.Loc.SpillLocation == *Loc) {
+ // This location is overwritten by the current instruction -- terminate
+ // the open range, and insert an explicit DBG_VALUE $noreg.
+ //
+ // Doing this at a later stage would require re-interpreting all
+ // DBG_VALUes and DIExpressions to identify whether they point at
+ // memory, and then analysing all memory writes to see if they
+ // overwrite that memory, which is expensive.
+ //
+ // At this stage, we already know which DBG_VALUEs are for spills and
+ // where they are located; it's best to fix handle overwrites now.
+ KillSet.set(ID);
+ VarLoc UndefVL = VarLoc::CreateCopyLoc(VL.MI, LS, 0);
+ LocIndex UndefLocID = VarLocIDs.insert(UndefVL);
+ Transfers.push_back({&MI, UndefLocID});
+ }
+ }
+ OpenRanges.erase(KillSet, VarLocIDs);
+ }
+
+ // Try to recognise spill and restore instructions that may create a new
+ // variable location.
+ if (isLocationSpill(MI, MF, Reg)) {
+ TKind = TransferKind::TransferSpill;
+ LLVM_DEBUG(dbgs() << "Recognized as spill: "; MI.dump(););
+ LLVM_DEBUG(dbgs() << "Register: " << Reg << " " << printReg(Reg, TRI)
+ << "\n");
+ } else {
+ if (!(Loc = isRestoreInstruction(MI, MF, Reg)))
+ return;
+ TKind = TransferKind::TransferRestore;
+ LLVM_DEBUG(dbgs() << "Recognized as restore: "; MI.dump(););
+ LLVM_DEBUG(dbgs() << "Register: " << Reg << " " << printReg(Reg, TRI)
+ << "\n");
+ }
+ // Check if the register or spill location is the location of a debug value.
+ auto TransferCandidates = OpenRanges.getEmptyVarLocRange();
+ if (TKind == TransferKind::TransferSpill)
+ TransferCandidates = OpenRanges.getRegisterVarLocs(Reg);
+ else if (TKind == TransferKind::TransferRestore)
+ TransferCandidates = OpenRanges.getSpillVarLocs();
+ for (uint64_t ID : TransferCandidates) {
+ LocIndex Idx = LocIndex::fromRawInteger(ID);
+ const VarLoc &VL = VarLocIDs[Idx];
+ if (TKind == TransferKind::TransferSpill) {
+ assert(VL.isDescribedByReg() == Reg && "Broken VarLocSet?");
+ LLVM_DEBUG(dbgs() << "Spilling Register " << printReg(Reg, TRI) << '('
+ << VL.Var.getVariable()->getName() << ")\n");
+ } else {
+ assert(TKind == TransferKind::TransferRestore &&
+ VL.Kind == VarLoc::SpillLocKind && "Broken VarLocSet?");
+ if (VL.Loc.SpillLocation != *Loc)
+ // The spill location is not the location of a debug value.
+ continue;
+ LLVM_DEBUG(dbgs() << "Restoring Register " << printReg(Reg, TRI) << '('
+ << VL.Var.getVariable()->getName() << ")\n");
+ }
+ insertTransferDebugPair(MI, OpenRanges, Transfers, VarLocIDs, Idx, TKind,
+ Reg);
+ // FIXME: A comment should explain why it's correct to return early here,
+ // if that is in fact correct.
+ return;
+ }
+}
+
+/// If \p MI is a register copy instruction, that copies a previously tracked
+/// value from one register to another register that is callee saved, we
+/// create new DBG_VALUE instruction described with copy destination register.
+void VarLocBasedLDV::transferRegisterCopy(MachineInstr &MI,
+ OpenRangesSet &OpenRanges,
+ VarLocMap &VarLocIDs,
+ TransferMap &Transfers) {
+ auto DestSrc = TII->isCopyInstr(MI);
+ if (!DestSrc)
+ return;
+
+ const MachineOperand *DestRegOp = DestSrc->Destination;
+ const MachineOperand *SrcRegOp = DestSrc->Source;
+
+ if (!DestRegOp->isDef())
+ return;
+
+ auto isCalleeSavedReg = [&](Register Reg) {
+ for (MCRegAliasIterator RAI(Reg, TRI, true); RAI.isValid(); ++RAI)
+ if (CalleeSavedRegs.test(*RAI))
+ return true;
+ return false;
+ };
+
+ Register SrcReg = SrcRegOp->getReg();
+ Register DestReg = DestRegOp->getReg();
+
+ // We want to recognize instructions where destination register is callee
+ // saved register. If register that could be clobbered by the call is
+ // included, there would be a great chance that it is going to be clobbered
+ // soon. It is more likely that previous register location, which is callee
+ // saved, is going to stay unclobbered longer, even if it is killed.
+ if (!isCalleeSavedReg(DestReg))
+ return;
+
+ // Remember an entry value movement. If we encounter a new debug value of
+ // a parameter describing only a moving of the value around, rather then
+ // modifying it, we are still able to use the entry value if needed.
+ if (isRegOtherThanSPAndFP(*DestRegOp, MI, TRI)) {
+ for (uint64_t ID : OpenRanges.getEntryValueBackupVarLocs()) {
+ LocIndex Idx = LocIndex::fromRawInteger(ID);
+ const VarLoc &VL = VarLocIDs[Idx];
+ if (VL.getEntryValueBackupReg() == SrcReg) {
+ LLVM_DEBUG(dbgs() << "Copy of the entry value: "; MI.dump(););
+ VarLoc EntryValLocCopyBackup =
+ VarLoc::CreateEntryCopyBackupLoc(VL.MI, LS, VL.Expr, DestReg);
+
+ // Stop tracking the original entry value.
+ OpenRanges.erase(VL);
+
+ // Start tracking the entry value copy.
+ LocIndex EntryValCopyLocID = VarLocIDs.insert(EntryValLocCopyBackup);
+ OpenRanges.insert(EntryValCopyLocID, EntryValLocCopyBackup);
+ break;
+ }
+ }
+ }
+
+ if (!SrcRegOp->isKill())
+ return;
+
+ for (uint64_t ID : OpenRanges.getRegisterVarLocs(SrcReg)) {
+ LocIndex Idx = LocIndex::fromRawInteger(ID);
+ assert(VarLocIDs[Idx].isDescribedByReg() == SrcReg && "Broken VarLocSet?");
+ insertTransferDebugPair(MI, OpenRanges, Transfers, VarLocIDs, Idx,
+ TransferKind::TransferCopy, DestReg);
+ // FIXME: A comment should explain why it's correct to return early here,
+ // if that is in fact correct.
+ return;
+ }
+}
+
+/// Terminate all open ranges at the end of the current basic block.
+bool VarLocBasedLDV::transferTerminator(MachineBasicBlock *CurMBB,
+ OpenRangesSet &OpenRanges,
+ VarLocInMBB &OutLocs,
+ const VarLocMap &VarLocIDs) {
+ bool Changed = false;
+
+ LLVM_DEBUG(for (uint64_t ID
+ : OpenRanges.getVarLocs()) {
+ // Copy OpenRanges to OutLocs, if not already present.
+ dbgs() << "Add to OutLocs in MBB #" << CurMBB->getNumber() << ": ";
+ VarLocIDs[LocIndex::fromRawInteger(ID)].dump(TRI);
+ });
+ VarLocSet &VLS = getVarLocsInMBB(CurMBB, OutLocs);
+ Changed = VLS != OpenRanges.getVarLocs();
+ // New OutLocs set may be different due to spill, restore or register
+ // copy instruction processing.
+ if (Changed)
+ VLS = OpenRanges.getVarLocs();
+ OpenRanges.clear();
+ return Changed;
+}
+
+/// Accumulate a mapping between each DILocalVariable fragment and other
+/// fragments of that DILocalVariable which overlap. This reduces work during
+/// the data-flow stage from "Find any overlapping fragments" to "Check if the
+/// known-to-overlap fragments are present".
+/// \param MI A previously unprocessed DEBUG_VALUE instruction to analyze for
+/// fragment usage.
+/// \param SeenFragments Map from DILocalVariable to all fragments of that
+/// Variable which are known to exist.
+/// \param OverlappingFragments The overlap map being constructed, from one
+/// Var/Fragment pair to a vector of fragments known to overlap.
+void VarLocBasedLDV::accumulateFragmentMap(MachineInstr &MI,
+ VarToFragments &SeenFragments,
+ OverlapMap &OverlappingFragments) {
+ DebugVariable MIVar(MI.getDebugVariable(), MI.getDebugExpression(),
+ MI.getDebugLoc()->getInlinedAt());
+ FragmentInfo ThisFragment = MIVar.getFragmentOrDefault();
+
+ // If this is the first sighting of this variable, then we are guaranteed
+ // there are currently no overlapping fragments either. Initialize the set
+ // of seen fragments, record no overlaps for the current one, and return.
+ auto SeenIt = SeenFragments.find(MIVar.getVariable());
+ if (SeenIt == SeenFragments.end()) {
+ SmallSet<FragmentInfo, 4> OneFragment;
+ OneFragment.insert(ThisFragment);
+ SeenFragments.insert({MIVar.getVariable(), OneFragment});
+
+ OverlappingFragments.insert({{MIVar.getVariable(), ThisFragment}, {}});
+ return;
+ }
+
+ // If this particular Variable/Fragment pair already exists in the overlap
+ // map, it has already been accounted for.
+ auto IsInOLapMap =
+ OverlappingFragments.insert({{MIVar.getVariable(), ThisFragment}, {}});
+ if (!IsInOLapMap.second)
+ return;
+
+ auto &ThisFragmentsOverlaps = IsInOLapMap.first->second;
+ auto &AllSeenFragments = SeenIt->second;
+
+ // Otherwise, examine all other seen fragments for this variable, with "this"
+ // fragment being a previously unseen fragment. Record any pair of
+ // overlapping fragments.
+ for (auto &ASeenFragment : AllSeenFragments) {
+ // Does this previously seen fragment overlap?
+ if (DIExpression::fragmentsOverlap(ThisFragment, ASeenFragment)) {
+ // Yes: Mark the current fragment as being overlapped.
+ ThisFragmentsOverlaps.push_back(ASeenFragment);
+ // Mark the previously seen fragment as being overlapped by the current
+ // one.
+ auto ASeenFragmentsOverlaps =
+ OverlappingFragments.find({MIVar.getVariable(), ASeenFragment});
+ assert(ASeenFragmentsOverlaps != OverlappingFragments.end() &&
+ "Previously seen var fragment has no vector of overlaps");
+ ASeenFragmentsOverlaps->second.push_back(ThisFragment);
+ }
+ }
+
+ AllSeenFragments.insert(ThisFragment);
+}
+
+/// This routine creates OpenRanges.
+void VarLocBasedLDV::process(MachineInstr &MI, OpenRangesSet &OpenRanges,
+ VarLocMap &VarLocIDs, TransferMap &Transfers) {
+ transferDebugValue(MI, OpenRanges, VarLocIDs);
+ transferRegisterDef(MI, OpenRanges, VarLocIDs, Transfers);
+ transferRegisterCopy(MI, OpenRanges, VarLocIDs, Transfers);
+ transferSpillOrRestoreInst(MI, OpenRanges, VarLocIDs, Transfers);
+}
+
+/// This routine joins the analysis results of all incoming edges in @MBB by
+/// inserting a new DBG_VALUE instruction at the start of the @MBB - if the same
+/// source variable in all the predecessors of @MBB reside in the same location.
+bool VarLocBasedLDV::join(
+ MachineBasicBlock &MBB, VarLocInMBB &OutLocs, VarLocInMBB &InLocs,
+ const VarLocMap &VarLocIDs,
+ SmallPtrSet<const MachineBasicBlock *, 16> &Visited,
+ SmallPtrSetImpl<const MachineBasicBlock *> &ArtificialBlocks) {
+ LLVM_DEBUG(dbgs() << "join MBB: " << MBB.getNumber() << "\n");
+
+ VarLocSet InLocsT(Alloc); // Temporary incoming locations.
+
+ // For all predecessors of this MBB, find the set of VarLocs that
+ // can be joined.
+ int NumVisited = 0;
+ for (auto p : MBB.predecessors()) {
+ // Ignore backedges if we have not visited the predecessor yet. As the
+ // predecessor hasn't yet had locations propagated into it, most locations
+ // will not yet be valid, so treat them as all being uninitialized and
+ // potentially valid. If a location guessed to be correct here is
+ // invalidated later, we will remove it when we revisit this block.
+ if (!Visited.count(p)) {
+ LLVM_DEBUG(dbgs() << " ignoring unvisited pred MBB: " << p->getNumber()
+ << "\n");
+ continue;
+ }
+ auto OL = OutLocs.find(p);
+ // Join is null in case of empty OutLocs from any of the pred.
+ if (OL == OutLocs.end())
+ return false;
+
+ // Just copy over the Out locs to incoming locs for the first visited
+ // predecessor, and for all other predecessors join the Out locs.
+ VarLocSet &OutLocVLS = *OL->second.get();
+ if (!NumVisited)
+ InLocsT = OutLocVLS;
+ else
+ InLocsT &= OutLocVLS;
+
+ LLVM_DEBUG({
+ if (!InLocsT.empty()) {
+ for (uint64_t ID : InLocsT)
+ dbgs() << " gathered candidate incoming var: "
+ << VarLocIDs[LocIndex::fromRawInteger(ID)]
+ .Var.getVariable()
+ ->getName()
+ << "\n";
+ }
+ });
+
+ NumVisited++;
+ }
+
+ // Filter out DBG_VALUES that are out of scope.
+ VarLocSet KillSet(Alloc);
+ bool IsArtificial = ArtificialBlocks.count(&MBB);
+ if (!IsArtificial) {
+ for (uint64_t ID : InLocsT) {
+ LocIndex Idx = LocIndex::fromRawInteger(ID);
+ if (!VarLocIDs[Idx].dominates(LS, MBB)) {
+ KillSet.set(ID);
+ LLVM_DEBUG({
+ auto Name = VarLocIDs[Idx].Var.getVariable()->getName();
+ dbgs() << " killing " << Name << ", it doesn't dominate MBB\n";
+ });
+ }
+ }
+ }
+ InLocsT.intersectWithComplement(KillSet);
+
+ // As we are processing blocks in reverse post-order we
+ // should have processed at least one predecessor, unless it
+ // is the entry block which has no predecessor.
+ assert((NumVisited || MBB.pred_empty()) &&
+ "Should have processed at least one predecessor");
+
+ VarLocSet &ILS = getVarLocsInMBB(&MBB, InLocs);
+ bool Changed = false;
+ if (ILS != InLocsT) {
+ ILS = InLocsT;
+ Changed = true;
+ }
+
+ return Changed;
+}
+
+void VarLocBasedLDV::flushPendingLocs(VarLocInMBB &PendingInLocs,
+ VarLocMap &VarLocIDs) {
+ // PendingInLocs records all locations propagated into blocks, which have
+ // not had DBG_VALUE insts created. Go through and create those insts now.
+ for (auto &Iter : PendingInLocs) {
+ // Map is keyed on a constant pointer, unwrap it so we can insert insts.
+ auto &MBB = const_cast<MachineBasicBlock &>(*Iter.first);
+ VarLocSet &Pending = *Iter.second.get();
+
+ for (uint64_t ID : Pending) {
+ // The ID location is live-in to MBB -- work out what kind of machine
+ // location it is and create a DBG_VALUE.
+ const VarLoc &DiffIt = VarLocIDs[LocIndex::fromRawInteger(ID)];
+ if (DiffIt.isEntryBackupLoc())
+ continue;
+ MachineInstr *MI = DiffIt.BuildDbgValue(*MBB.getParent());
+ MBB.insert(MBB.instr_begin(), MI);
+
+ (void)MI;
+ LLVM_DEBUG(dbgs() << "Inserted: "; MI->dump(););
+ }
+ }
+}
+
+bool VarLocBasedLDV::isEntryValueCandidate(
+ const MachineInstr &MI, const DefinedRegsSet &DefinedRegs) const {
+ assert(MI.isDebugValue() && "This must be DBG_VALUE.");
+
+ // TODO: Add support for local variables that are expressed in terms of
+ // parameters entry values.
+ // TODO: Add support for modified arguments that can be expressed
+ // by using its entry value.
+ auto *DIVar = MI.getDebugVariable();
+ if (!DIVar->isParameter())
+ return false;
+
+ // Do not consider parameters that belong to an inlined function.
+ if (MI.getDebugLoc()->getInlinedAt())
+ return false;
+
+ // Only consider parameters that are described using registers. Parameters
+ // that are passed on the stack are not yet supported, so ignore debug
+ // values that are described by the frame or stack pointer.
+ if (!isRegOtherThanSPAndFP(MI.getDebugOperand(0), MI, TRI))
+ return false;
+
+ // If a parameter's value has been propagated from the caller, then the
+ // parameter's DBG_VALUE may be described using a register defined by some
+ // instruction in the entry block, in which case we shouldn't create an
+ // entry value.
+ if (DefinedRegs.count(MI.getDebugOperand(0).getReg()))
+ return false;
+
+ // TODO: Add support for parameters that have a pre-existing debug expressions
+ // (e.g. fragments).
+ if (MI.getDebugExpression()->getNumElements() > 0)
+ return false;
+
+ return true;
+}
+
+/// Collect all register defines (including aliases) for the given instruction.
+static void collectRegDefs(const MachineInstr &MI, DefinedRegsSet &Regs,
+ const TargetRegisterInfo *TRI) {
+ for (const MachineOperand &MO : MI.operands())
+ if (MO.isReg() && MO.isDef() && MO.getReg())
+ for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid(); ++AI)
+ Regs.insert(*AI);
+}
+
+/// This routine records the entry values of function parameters. The values
+/// could be used as backup values. If we loose the track of some unmodified
+/// parameters, the backup values will be used as a primary locations.
+void VarLocBasedLDV::recordEntryValue(const MachineInstr &MI,
+ const DefinedRegsSet &DefinedRegs,
+ OpenRangesSet &OpenRanges,
+ VarLocMap &VarLocIDs) {
+ if (TPC) {
+ auto &TM = TPC->getTM<TargetMachine>();
+ if (!TM.Options.ShouldEmitDebugEntryValues())
+ return;
+ }
+
+ DebugVariable V(MI.getDebugVariable(), MI.getDebugExpression(),
+ MI.getDebugLoc()->getInlinedAt());
+
+ if (!isEntryValueCandidate(MI, DefinedRegs) ||
+ OpenRanges.getEntryValueBackup(V))
+ return;
+
+ LLVM_DEBUG(dbgs() << "Creating the backup entry location: "; MI.dump(););
+
+ // Create the entry value and use it as a backup location until it is
+ // valid. It is valid until a parameter is not changed.
+ DIExpression *NewExpr =
+ DIExpression::prepend(MI.getDebugExpression(), DIExpression::EntryValue);
+ VarLoc EntryValLocAsBackup = VarLoc::CreateEntryBackupLoc(MI, LS, NewExpr);
+ LocIndex EntryValLocID = VarLocIDs.insert(EntryValLocAsBackup);
+ OpenRanges.insert(EntryValLocID, EntryValLocAsBackup);
+}
+
+/// Calculate the liveness information for the given machine function and
+/// extend ranges across basic blocks.
+bool VarLocBasedLDV::ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC) {
+ LLVM_DEBUG(dbgs() << "\nDebug Range Extension\n");
+
+ if (!MF.getFunction().getSubprogram())
+ // VarLocBaseLDV will already have removed all DBG_VALUEs.
+ return false;
+
+ // Skip functions from NoDebug compilation units.
+ if (MF.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
+ DICompileUnit::NoDebug)
+ return false;
+
+ TRI = MF.getSubtarget().getRegisterInfo();
+ TII = MF.getSubtarget().getInstrInfo();
+ TFI = MF.getSubtarget().getFrameLowering();
+ TFI->getCalleeSaves(MF, CalleeSavedRegs);
+ this->TPC = TPC;
+ LS.initialize(MF);
+
+ bool Changed = false;
+ bool OLChanged = false;
+ bool MBBJoined = false;
+
+ VarLocMap VarLocIDs; // Map VarLoc<>unique ID for use in bitvectors.
+ OverlapMap OverlapFragments; // Map of overlapping variable fragments.
+ OpenRangesSet OpenRanges(Alloc, OverlapFragments);
+ // Ranges that are open until end of bb.
+ VarLocInMBB OutLocs; // Ranges that exist beyond bb.
+ VarLocInMBB InLocs; // Ranges that are incoming after joining.
+ TransferMap Transfers; // DBG_VALUEs associated with transfers (such as
+ // spills, copies and restores).
+
+ VarToFragments SeenFragments;
+
+ // Blocks which are artificial, i.e. blocks which exclusively contain
+ // instructions without locations, or with line 0 locations.
+ SmallPtrSet<const MachineBasicBlock *, 16> ArtificialBlocks;
+
+ DenseMap<unsigned int, MachineBasicBlock *> OrderToBB;
+ DenseMap<MachineBasicBlock *, unsigned int> BBToOrder;
+ std::priority_queue<unsigned int, std::vector<unsigned int>,
+ std::greater<unsigned int>>
+ Worklist;
+ std::priority_queue<unsigned int, std::vector<unsigned int>,
+ std::greater<unsigned int>>
+ Pending;
+
+ // Set of register defines that are seen when traversing the entry block
+ // looking for debug entry value candidates.
+ DefinedRegsSet DefinedRegs;
+
+ // Only in the case of entry MBB collect DBG_VALUEs representing
+ // function parameters in order to generate debug entry values for them.
+ MachineBasicBlock &First_MBB = *(MF.begin());
+ for (auto &MI : First_MBB) {
+ collectRegDefs(MI, DefinedRegs, TRI);
+ if (MI.isDebugValue())
+ recordEntryValue(MI, DefinedRegs, OpenRanges, VarLocIDs);
+ }
+
+ // Initialize per-block structures and scan for fragment overlaps.
+ for (auto &MBB : MF)
+ for (auto &MI : MBB)
+ if (MI.isDebugValue())
+ accumulateFragmentMap(MI, SeenFragments, OverlapFragments);
+
+ auto hasNonArtificialLocation = [](const MachineInstr &MI) -> bool {
+ if (const DebugLoc &DL = MI.getDebugLoc())
+ return DL.getLine() != 0;
+ return false;
+ };
+ for (auto &MBB : MF)
+ if (none_of(MBB.instrs(), hasNonArtificialLocation))
+ ArtificialBlocks.insert(&MBB);
+
+ LLVM_DEBUG(printVarLocInMBB(MF, OutLocs, VarLocIDs,
+ "OutLocs after initialization", dbgs()));
+
+ ReversePostOrderTraversal<MachineFunction *> RPOT(&MF);
+ unsigned int RPONumber = 0;
+ for (auto RI = RPOT.begin(), RE = RPOT.end(); RI != RE; ++RI) {
+ OrderToBB[RPONumber] = *RI;
+ BBToOrder[*RI] = RPONumber;
+ Worklist.push(RPONumber);
+ ++RPONumber;
+ }
+
+ if (RPONumber > InputBBLimit) {
+ unsigned NumInputDbgValues = 0;
+ for (auto &MBB : MF)
+ for (auto &MI : MBB)
+ if (MI.isDebugValue())
+ ++NumInputDbgValues;
+ if (NumInputDbgValues > InputDbgValueLimit) {
+ LLVM_DEBUG(dbgs() << "Disabling VarLocBasedLDV: " << MF.getName()
+ << " has " << RPONumber << " basic blocks and "
+ << NumInputDbgValues
+ << " input DBG_VALUEs, exceeding limits.\n");
+ return false;
+ }
+ }
+
+ // This is a standard "union of predecessor outs" dataflow problem.
+ // To solve it, we perform join() and process() using the two worklist method
+ // until the ranges converge.
+ // Ranges have converged when both worklists are empty.
+ SmallPtrSet<const MachineBasicBlock *, 16> Visited;
+ while (!Worklist.empty() || !Pending.empty()) {
+ // We track what is on the pending worklist to avoid inserting the same
+ // thing twice. We could avoid this with a custom priority queue, but this
+ // is probably not worth it.
+ SmallPtrSet<MachineBasicBlock *, 16> OnPending;
+ LLVM_DEBUG(dbgs() << "Processing Worklist\n");
+ while (!Worklist.empty()) {
+ MachineBasicBlock *MBB = OrderToBB[Worklist.top()];
+ Worklist.pop();
+ MBBJoined = join(*MBB, OutLocs, InLocs, VarLocIDs, Visited,
+ ArtificialBlocks);
+ MBBJoined |= Visited.insert(MBB).second;
+ if (MBBJoined) {
+ MBBJoined = false;
+ Changed = true;
+ // Now that we have started to extend ranges across BBs we need to
+ // examine spill, copy and restore instructions to see whether they
+ // operate with registers that correspond to user variables.
+ // First load any pending inlocs.
+ OpenRanges.insertFromLocSet(getVarLocsInMBB(MBB, InLocs), VarLocIDs);
+ for (auto &MI : *MBB)
+ process(MI, OpenRanges, VarLocIDs, Transfers);
+ OLChanged |= transferTerminator(MBB, OpenRanges, OutLocs, VarLocIDs);
+
+ LLVM_DEBUG(printVarLocInMBB(MF, OutLocs, VarLocIDs,
+ "OutLocs after propagating", dbgs()));
+ LLVM_DEBUG(printVarLocInMBB(MF, InLocs, VarLocIDs,
+ "InLocs after propagating", dbgs()));
+
+ if (OLChanged) {
+ OLChanged = false;
+ for (auto s : MBB->successors())
+ if (OnPending.insert(s).second) {
+ Pending.push(BBToOrder[s]);
+ }
+ }
+ }
+ }
+ Worklist.swap(Pending);
+ // At this point, pending must be empty, since it was just the empty
+ // worklist
+ assert(Pending.empty() && "Pending should be empty");
+ }
+
+ // Add any DBG_VALUE instructions created by location transfers.
+ for (auto &TR : Transfers) {
+ assert(!TR.TransferInst->isTerminator() &&
+ "Cannot insert DBG_VALUE after terminator");
+ MachineBasicBlock *MBB = TR.TransferInst->getParent();
+ const VarLoc &VL = VarLocIDs[TR.LocationID];
+ MachineInstr *MI = VL.BuildDbgValue(MF);
+ MBB->insertAfterBundle(TR.TransferInst->getIterator(), MI);
+ }
+ Transfers.clear();
+
+ // Deferred inlocs will not have had any DBG_VALUE insts created; do
+ // that now.
+ flushPendingLocs(InLocs, VarLocIDs);
+
+ LLVM_DEBUG(printVarLocInMBB(MF, OutLocs, VarLocIDs, "Final OutLocs", dbgs()));
+ LLVM_DEBUG(printVarLocInMBB(MF, InLocs, VarLocIDs, "Final InLocs", dbgs()));
+ return Changed;
+}
+
+LDVImpl *
+llvm::makeVarLocBasedLiveDebugValues()
+{
+ return new VarLocBasedLDV();
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/LiveDebugVariables.cpp b/contrib/libs/llvm12/lib/CodeGen/LiveDebugVariables.cpp
index 26a651666a..2325341070 100644
--- a/contrib/libs/llvm12/lib/CodeGen/LiveDebugVariables.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/LiveDebugVariables.cpp
@@ -95,7 +95,7 @@ LiveDebugVariables::LiveDebugVariables() : MachineFunctionPass(ID) {
enum : unsigned { UndefLocNo = ~0U };
-namespace {
+namespace {
/// Describes a debug variable value by location number and expression along
/// with some flags about the original usage of the location.
class DbgVariableValue {
@@ -136,7 +136,7 @@ private:
unsigned WasIndirect : 1;
const DIExpression *Expression = nullptr;
};
-} // namespace
+} // namespace
/// Map of where a user value is live to that value.
using LocMap = IntervalMap<SlotIndex, DbgVariableValue, 4>;
@@ -395,11 +395,11 @@ class LDVImpl {
LiveIntervals *LIS;
const TargetRegisterInfo *TRI;
- using StashedInstrRef =
- std::tuple<unsigned, unsigned, const DILocalVariable *,
- const DIExpression *, DebugLoc>;
- std::map<SlotIndex, std::vector<StashedInstrRef>> StashedInstrReferences;
-
+ using StashedInstrRef =
+ std::tuple<unsigned, unsigned, const DILocalVariable *,
+ const DIExpression *, DebugLoc>;
+ std::map<SlotIndex, std::vector<StashedInstrRef>> StashedInstrReferences;
+
/// Whether emitDebugValues is called.
bool EmitDone = false;
@@ -436,16 +436,16 @@ class LDVImpl {
/// \returns True if the DBG_VALUE instruction should be deleted.
bool handleDebugValue(MachineInstr &MI, SlotIndex Idx);
- /// Track a DBG_INSTR_REF. This needs to be removed from the MachineFunction
- /// during regalloc -- but there's no need to maintain live ranges, as we
- /// refer to a value rather than a location.
- ///
- /// \param MI DBG_INSTR_REF instruction
- /// \param Idx Last valid SlotIndex before instruction
- ///
- /// \returns True if the DBG_VALUE instruction should be deleted.
- bool handleDebugInstrRef(MachineInstr &MI, SlotIndex Idx);
-
+ /// Track a DBG_INSTR_REF. This needs to be removed from the MachineFunction
+ /// during regalloc -- but there's no need to maintain live ranges, as we
+ /// refer to a value rather than a location.
+ ///
+ /// \param MI DBG_INSTR_REF instruction
+ /// \param Idx Last valid SlotIndex before instruction
+ ///
+ /// \returns True if the DBG_VALUE instruction should be deleted.
+ bool handleDebugInstrRef(MachineInstr &MI, SlotIndex Idx);
+
/// Add DBG_LABEL instruction to UserLabel.
///
/// \param MI DBG_LABEL instruction
@@ -474,7 +474,7 @@ public:
/// Release all memory.
void clear() {
MF = nullptr;
- StashedInstrReferences.clear();
+ StashedInstrReferences.clear();
userValues.clear();
userLabels.clear();
virtRegToEqClass.clear();
@@ -682,19 +682,19 @@ bool LDVImpl::handleDebugValue(MachineInstr &MI, SlotIndex Idx) {
return true;
}
-bool LDVImpl::handleDebugInstrRef(MachineInstr &MI, SlotIndex Idx) {
- assert(MI.isDebugRef());
- unsigned InstrNum = MI.getOperand(0).getImm();
- unsigned OperandNum = MI.getOperand(1).getImm();
- auto *Var = MI.getDebugVariable();
- auto *Expr = MI.getDebugExpression();
- auto &DL = MI.getDebugLoc();
- StashedInstrRef Stashed =
- std::make_tuple(InstrNum, OperandNum, Var, Expr, DL);
- StashedInstrReferences[Idx].push_back(Stashed);
- return true;
-}
-
+bool LDVImpl::handleDebugInstrRef(MachineInstr &MI, SlotIndex Idx) {
+ assert(MI.isDebugRef());
+ unsigned InstrNum = MI.getOperand(0).getImm();
+ unsigned OperandNum = MI.getOperand(1).getImm();
+ auto *Var = MI.getDebugVariable();
+ auto *Expr = MI.getDebugExpression();
+ auto &DL = MI.getDebugLoc();
+ StashedInstrRef Stashed =
+ std::make_tuple(InstrNum, OperandNum, Var, Expr, DL);
+ StashedInstrReferences[Idx].push_back(Stashed);
+ return true;
+}
+
bool LDVImpl::handleDebugLabel(MachineInstr &MI, SlotIndex Idx) {
// DBG_LABEL label
if (MI.getNumOperands() != 1 || !MI.getOperand(0).isMetadata()) {
@@ -742,7 +742,7 @@ bool LDVImpl::collectDebugValues(MachineFunction &mf) {
// Only handle DBG_VALUE in handleDebugValue(). Skip all other
// kinds of debug instructions.
if ((MBBI->isDebugValue() && handleDebugValue(*MBBI, Idx)) ||
- (MBBI->isDebugRef() && handleDebugInstrRef(*MBBI, Idx)) ||
+ (MBBI->isDebugRef() && handleDebugInstrRef(*MBBI, Idx)) ||
(MBBI->isDebugLabel() && handleDebugLabel(*MBBI, Idx))) {
MBBI = MBB->erase(MBBI);
Changed = true;
@@ -806,12 +806,12 @@ void UserValue::addDefsFromCopies(
if (Kills.empty())
return;
// Don't track copies from physregs, there are too many uses.
- if (!Register::isVirtualRegister(LI->reg()))
+ if (!Register::isVirtualRegister(LI->reg()))
return;
// Collect all the (vreg, valno) pairs that are copies of LI.
SmallVector<std::pair<LiveInterval*, const VNInfo*>, 8> CopyValues;
- for (MachineOperand &MO : MRI.use_nodbg_operands(LI->reg())) {
+ for (MachineOperand &MO : MRI.use_nodbg_operands(LI->reg())) {
MachineInstr *MI = MO.getParent();
// Copies of the full value.
if (MO.getSubReg() || !MI->isCopy())
@@ -1022,10 +1022,10 @@ bool LDVImpl::runOnMachineFunction(MachineFunction &mf) {
return Changed;
}
-static void removeDebugInstrs(MachineFunction &mf) {
+static void removeDebugInstrs(MachineFunction &mf) {
for (MachineBasicBlock &MBB : mf) {
for (auto MBBI = MBB.begin(), MBBE = MBB.end(); MBBI != MBBE; ) {
- if (!MBBI->isDebugInstr()) {
+ if (!MBBI->isDebugInstr()) {
++MBBI;
continue;
}
@@ -1038,7 +1038,7 @@ bool LiveDebugVariables::runOnMachineFunction(MachineFunction &mf) {
if (!EnableLDV)
return false;
if (!mf.getFunction().getSubprogram()) {
- removeDebugInstrs(mf);
+ removeDebugInstrs(mf);
return false;
}
if (!pImpl)
@@ -1095,7 +1095,7 @@ UserValue::splitLocation(unsigned OldLocNo, ArrayRef<Register> NewRegs,
LII->start < LocMapI.stop()) {
// Overlapping correct location. Allocate NewLocNo now.
if (NewLocNo == UndefLocNo) {
- MachineOperand MO = MachineOperand::CreateReg(LI->reg(), false);
+ MachineOperand MO = MachineOperand::CreateReg(LI->reg(), false);
MO.setSubReg(locations[OldLocNo].getSubReg());
NewLocNo = getLocationNo(MO);
DidChange = true;
@@ -1465,28 +1465,28 @@ void LDVImpl::emitDebugValues(VirtRegMap *VRM) {
LLVM_DEBUG(userLabel->print(dbgs(), TRI));
userLabel->emitDebugLabel(*LIS, *TII);
}
-
- LLVM_DEBUG(dbgs() << "********** EMITTING INSTR REFERENCES **********\n");
-
- // Re-insert any DBG_INSTR_REFs back in the position they were. Ordering
- // is preserved by vector.
- auto Slots = LIS->getSlotIndexes();
- const MCInstrDesc &RefII = TII->get(TargetOpcode::DBG_INSTR_REF);
- for (auto &P : StashedInstrReferences) {
- const SlotIndex &Idx = P.first;
- auto *MBB = Slots->getMBBFromIndex(Idx);
- MachineBasicBlock::iterator insertPos = findInsertLocation(MBB, Idx, *LIS);
- for (auto &Stashed : P.second) {
- auto MIB = BuildMI(*MF, std::get<4>(Stashed), RefII);
- MIB.addImm(std::get<0>(Stashed));
- MIB.addImm(std::get<1>(Stashed));
- MIB.addMetadata(std::get<2>(Stashed));
- MIB.addMetadata(std::get<3>(Stashed));
- MachineInstr *New = MIB;
- MBB->insert(insertPos, New);
- }
- }
-
+
+ LLVM_DEBUG(dbgs() << "********** EMITTING INSTR REFERENCES **********\n");
+
+ // Re-insert any DBG_INSTR_REFs back in the position they were. Ordering
+ // is preserved by vector.
+ auto Slots = LIS->getSlotIndexes();
+ const MCInstrDesc &RefII = TII->get(TargetOpcode::DBG_INSTR_REF);
+ for (auto &P : StashedInstrReferences) {
+ const SlotIndex &Idx = P.first;
+ auto *MBB = Slots->getMBBFromIndex(Idx);
+ MachineBasicBlock::iterator insertPos = findInsertLocation(MBB, Idx, *LIS);
+ for (auto &Stashed : P.second) {
+ auto MIB = BuildMI(*MF, std::get<4>(Stashed), RefII);
+ MIB.addImm(std::get<0>(Stashed));
+ MIB.addImm(std::get<1>(Stashed));
+ MIB.addMetadata(std::get<2>(Stashed));
+ MIB.addMetadata(std::get<3>(Stashed));
+ MachineInstr *New = MIB;
+ MBB->insert(insertPos, New);
+ }
+ }
+
EmitDone = true;
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/LiveInterval.cpp b/contrib/libs/llvm12/lib/CodeGen/LiveInterval.cpp
index 9bdbb96d37..ce0e587720 100644
--- a/contrib/libs/llvm12/lib/CodeGen/LiveInterval.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/LiveInterval.cpp
@@ -951,9 +951,9 @@ void LiveInterval::refineSubRanges(
MatchingRange = createSubRangeFrom(Allocator, Matching, SR);
// Now that the subrange is split in half, make sure we
// only keep in the subranges the VNIs that touch the related half.
- stripValuesNotDefiningMask(reg(), *MatchingRange, Matching, Indexes, TRI,
+ stripValuesNotDefiningMask(reg(), *MatchingRange, Matching, Indexes, TRI,
ComposeSubRegIdx);
- stripValuesNotDefiningMask(reg(), SR, SR.LaneMask, Indexes, TRI,
+ stripValuesNotDefiningMask(reg(), SR, SR.LaneMask, Indexes, TRI,
ComposeSubRegIdx);
}
Apply(*MatchingRange);
@@ -977,11 +977,11 @@ void LiveInterval::computeSubRangeUndefs(SmallVectorImpl<SlotIndex> &Undefs,
LaneBitmask LaneMask,
const MachineRegisterInfo &MRI,
const SlotIndexes &Indexes) const {
- assert(Register::isVirtualRegister(reg()));
- LaneBitmask VRegMask = MRI.getMaxLaneMaskForVReg(reg());
+ assert(Register::isVirtualRegister(reg()));
+ LaneBitmask VRegMask = MRI.getMaxLaneMaskForVReg(reg());
assert((VRegMask & LaneMask).any());
const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
- for (const MachineOperand &MO : MRI.def_operands(reg())) {
+ for (const MachineOperand &MO : MRI.def_operands(reg())) {
if (!MO.isUndef())
continue;
unsigned SubReg = MO.getSubReg();
@@ -1043,12 +1043,12 @@ void LiveInterval::SubRange::print(raw_ostream &OS) const {
}
void LiveInterval::print(raw_ostream &OS) const {
- OS << printReg(reg()) << ' ';
+ OS << printReg(reg()) << ' ';
super::print(OS);
// Print subranges
for (const SubRange &SR : subranges())
OS << SR;
- OS << " weight:" << Weight;
+ OS << " weight:" << Weight;
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
@@ -1087,7 +1087,7 @@ void LiveInterval::verify(const MachineRegisterInfo *MRI) const {
// Make sure SubRanges are fine and LaneMasks are disjunct.
LaneBitmask Mask;
- LaneBitmask MaxMask = MRI != nullptr ? MRI->getMaxLaneMaskForVReg(reg())
+ LaneBitmask MaxMask = MRI != nullptr ? MRI->getMaxLaneMaskForVReg(reg())
: LaneBitmask::getAll();
for (const SubRange &SR : subranges()) {
// Subrange lanemask should be disjunct to any previous subrange masks.
@@ -1361,9 +1361,9 @@ unsigned ConnectedVNInfoEqClasses::Classify(const LiveRange &LR) {
void ConnectedVNInfoEqClasses::Distribute(LiveInterval &LI, LiveInterval *LIV[],
MachineRegisterInfo &MRI) {
// Rewrite instructions.
- for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(LI.reg()),
- RE = MRI.reg_end();
- RI != RE;) {
+ for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(LI.reg()),
+ RE = MRI.reg_end();
+ RI != RE;) {
MachineOperand &MO = *RI;
MachineInstr *MI = RI->getParent();
++RI;
@@ -1383,7 +1383,7 @@ void ConnectedVNInfoEqClasses::Distribute(LiveInterval &LI, LiveInterval *LIV[],
if (!VNI)
continue;
if (unsigned EqClass = getEqClass(VNI))
- MO.setReg(LIV[EqClass - 1]->reg());
+ MO.setReg(LIV[EqClass - 1]->reg());
}
// Distribute subregister liveranges.
diff --git a/contrib/libs/llvm12/lib/CodeGen/LiveIntervalCalc.cpp b/contrib/libs/llvm12/lib/CodeGen/LiveIntervalCalc.cpp
index f47a4ccab0..2756086cb8 100644
--- a/contrib/libs/llvm12/lib/CodeGen/LiveIntervalCalc.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/LiveIntervalCalc.cpp
@@ -60,7 +60,7 @@ void LiveIntervalCalc::calculate(LiveInterval &LI, bool TrackSubRegs) {
// Visit all def operands. If the same instruction has multiple defs of Reg,
// createDeadDef() will deduplicate.
const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
- unsigned Reg = LI.reg();
+ unsigned Reg = LI.reg();
for (const MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
if (!MO.isDef() && !MO.readsReg())
continue;
@@ -127,7 +127,7 @@ void LiveIntervalCalc::constructMainRangeFromSubranges(LiveInterval &LI) {
}
}
resetLiveOutMap();
- extendToUses(MainRange, LI.reg(), LaneBitmask::getAll(), &LI);
+ extendToUses(MainRange, LI.reg(), LaneBitmask::getAll(), &LI);
}
void LiveIntervalCalc::createDeadDefs(LiveRange &LR, Register Reg) {
@@ -202,4 +202,4 @@ void LiveIntervalCalc::extendToUses(LiveRange &LR, Register Reg,
// reading Reg multiple times. That is OK, extend() is idempotent.
extend(LR, UseIdx, Reg, Undefs);
}
-}
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/LiveIntervalUnion.cpp b/contrib/libs/llvm12/lib/CodeGen/LiveIntervalUnion.cpp
index 148fca8a76..7ccb8df4bc 100644
--- a/contrib/libs/llvm12/lib/CodeGen/LiveIntervalUnion.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/LiveIntervalUnion.cpp
@@ -85,8 +85,8 @@ LiveIntervalUnion::print(raw_ostream &OS, const TargetRegisterInfo *TRI) const {
return;
}
for (LiveSegments::const_iterator SI = Segments.begin(); SI.valid(); ++SI) {
- OS << " [" << SI.start() << ' ' << SI.stop()
- << "):" << printReg(SI.value()->reg(), TRI);
+ OS << " [" << SI.start() << ' ' << SI.stop()
+ << "):" << printReg(SI.value()->reg(), TRI);
}
OS << '\n';
}
@@ -95,20 +95,20 @@ LiveIntervalUnion::print(raw_ostream &OS, const TargetRegisterInfo *TRI) const {
// Verify the live intervals in this union and add them to the visited set.
void LiveIntervalUnion::verify(LiveVirtRegBitSet& VisitedVRegs) {
for (SegmentIter SI = Segments.begin(); SI.valid(); ++SI)
- VisitedVRegs.set(SI.value()->reg());
+ VisitedVRegs.set(SI.value()->reg());
}
#endif //!NDEBUG
-LiveInterval *LiveIntervalUnion::getOneVReg() const {
- if (empty())
- return nullptr;
- for (LiveSegments::const_iterator SI = Segments.begin(); SI.valid(); ++SI) {
- // return the first valid live interval
- return SI.value();
- }
- return nullptr;
-}
-
+LiveInterval *LiveIntervalUnion::getOneVReg() const {
+ if (empty())
+ return nullptr;
+ for (LiveSegments::const_iterator SI = Segments.begin(); SI.valid(); ++SI) {
+ // return the first valid live interval
+ return SI.value();
+ }
+ return nullptr;
+}
+
// Scan the vector of interfering virtual registers in this union. Assume it's
// quite small.
bool LiveIntervalUnion::Query::isSeenInterference(LiveInterval *VirtReg) const {
diff --git a/contrib/libs/llvm12/lib/CodeGen/LiveIntervals.cpp b/contrib/libs/llvm12/lib/CodeGen/LiveIntervals.cpp
index 586647add3..a32b486240 100644
--- a/contrib/libs/llvm12/lib/CodeGen/LiveIntervals.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/LiveIntervals.cpp
@@ -37,7 +37,7 @@
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/CodeGen/VirtRegMap.h"
#include "llvm/Config/llvm-config.h"
-#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/MC/LaneBitmask.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Pass.h"
@@ -160,7 +160,7 @@ void LiveIntervals::print(raw_ostream &OS, const Module* ) const {
// Dump the virtregs.
for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
- Register Reg = Register::index2VirtReg(i);
+ Register Reg = Register::index2VirtReg(i);
if (hasInterval(Reg))
OS << getInterval(Reg) << '\n';
}
@@ -184,7 +184,7 @@ LLVM_DUMP_METHOD void LiveIntervals::dumpInstrs() const {
}
#endif
-LiveInterval *LiveIntervals::createInterval(Register reg) {
+LiveInterval *LiveIntervals::createInterval(Register reg) {
float Weight = Register::isPhysicalRegister(reg) ? huge_valf : 0.0F;
return new LiveInterval(reg, Weight);
}
@@ -194,13 +194,13 @@ bool LiveIntervals::computeVirtRegInterval(LiveInterval &LI) {
assert(LICalc && "LICalc not initialized.");
assert(LI.empty() && "Should only compute empty intervals.");
LICalc->reset(MF, getSlotIndexes(), DomTree, &getVNInfoAllocator());
- LICalc->calculate(LI, MRI->shouldTrackSubRegLiveness(LI.reg()));
+ LICalc->calculate(LI, MRI->shouldTrackSubRegLiveness(LI.reg()));
return computeDeadValues(LI, nullptr);
}
void LiveIntervals::computeVirtRegs() {
for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
- Register Reg = Register::index2VirtReg(i);
+ Register Reg = Register::index2VirtReg(i);
if (MRI->reg_nodbg_empty(Reg))
continue;
LiveInterval &LI = createEmptyInterval(Reg);
@@ -226,15 +226,15 @@ void LiveIntervals::computeRegMasks() {
RegMaskBits.push_back(Mask);
}
- // Unwinders may clobber additional registers.
- // FIXME: This functionality can possibly be merged into
- // MachineBasicBlock::getBeginClobberMask().
- if (MBB.isEHPad())
- if (auto *Mask = TRI->getCustomEHPadPreservedMask(*MBB.getParent())) {
- RegMaskSlots.push_back(Indexes->getMBBStartIdx(&MBB));
- RegMaskBits.push_back(Mask);
- }
-
+ // Unwinders may clobber additional registers.
+ // FIXME: This functionality can possibly be merged into
+ // MachineBasicBlock::getBeginClobberMask().
+ if (MBB.isEHPad())
+ if (auto *Mask = TRI->getCustomEHPadPreservedMask(*MBB.getParent())) {
+ RegMaskSlots.push_back(Indexes->getMBBStartIdx(&MBB));
+ RegMaskBits.push_back(Mask);
+ }
+
for (const MachineInstr &MI : MBB) {
for (const MachineOperand &MO : MI.operands()) {
if (!MO.isRegMask())
@@ -287,7 +287,7 @@ void LiveIntervals::computeRegUnitRange(LiveRange &LR, unsigned Unit) {
bool IsRootReserved = true;
for (MCSuperRegIterator Super(*Root, TRI, /*IncludeSelf=*/true);
Super.isValid(); ++Super) {
- MCRegister Reg = *Super;
+ MCRegister Reg = *Super;
if (!MRI->reg_empty(Reg))
LICalc->createDeadDefs(LR, Reg);
// A register unit is considered reserved if all its roots and all their
@@ -306,7 +306,7 @@ void LiveIntervals::computeRegUnitRange(LiveRange &LR, unsigned Unit) {
for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) {
for (MCSuperRegIterator Super(*Root, TRI, /*IncludeSelf=*/true);
Super.isValid(); ++Super) {
- MCRegister Reg = *Super;
+ MCRegister Reg = *Super;
if (!MRI->reg_empty(Reg))
LICalc->extendToUses(LR, Reg);
}
@@ -372,7 +372,7 @@ static void createSegmentsForValues(LiveRange &LR,
void LiveIntervals::extendSegmentsToUses(LiveRange &Segments,
ShrinkToUsesWorkList &WorkList,
- Register Reg, LaneBitmask LaneMask) {
+ Register Reg, LaneBitmask LaneMask) {
// Keep track of the PHIs that are in use.
SmallPtrSet<VNInfo*, 8> UsedPHIs;
// Blocks that have already been added to WorkList as live-out.
@@ -454,13 +454,13 @@ void LiveIntervals::extendSegmentsToUses(LiveRange &Segments,
bool LiveIntervals::shrinkToUses(LiveInterval *li,
SmallVectorImpl<MachineInstr*> *dead) {
LLVM_DEBUG(dbgs() << "Shrink: " << *li << '\n');
- assert(Register::isVirtualRegister(li->reg()) &&
+ assert(Register::isVirtualRegister(li->reg()) &&
"Can only shrink virtual registers");
// Shrink subregister live ranges.
bool NeedsCleanup = false;
for (LiveInterval::SubRange &S : li->subranges()) {
- shrinkToUses(S, li->reg());
+ shrinkToUses(S, li->reg());
if (S.empty())
NeedsCleanup = true;
}
@@ -470,8 +470,8 @@ bool LiveIntervals::shrinkToUses(LiveInterval *li,
// Find all the values used, including PHI kills.
ShrinkToUsesWorkList WorkList;
- // Visit all instructions reading li->reg().
- Register Reg = li->reg();
+ // Visit all instructions reading li->reg().
+ Register Reg = li->reg();
for (MachineInstr &UseMI : MRI->reg_instructions(Reg)) {
if (UseMI.isDebugValue() || !UseMI.readsVirtualRegister(Reg))
continue;
@@ -524,7 +524,7 @@ bool LiveIntervals::computeDeadValues(LiveInterval &LI,
// Is the register live before? Otherwise we may have to add a read-undef
// flag for subregister defs.
- Register VReg = LI.reg();
+ Register VReg = LI.reg();
if (MRI->shouldTrackSubRegLiveness(VReg)) {
if ((I == LI.begin() || std::prev(I)->end < Def) && !VNI->isPHIDef()) {
MachineInstr *MI = getInstructionFromIndex(Def);
@@ -544,7 +544,7 @@ bool LiveIntervals::computeDeadValues(LiveInterval &LI,
// This is a dead def. Make sure the instruction knows.
MachineInstr *MI = getInstructionFromIndex(Def);
assert(MI && "No instruction defining live value");
- MI->addRegisterDead(LI.reg(), TRI);
+ MI->addRegisterDead(LI.reg(), TRI);
if (HaveDeadDef)
MayHaveSplitComponents = true;
HaveDeadDef = true;
@@ -558,7 +558,7 @@ bool LiveIntervals::computeDeadValues(LiveInterval &LI,
return MayHaveSplitComponents;
}
-void LiveIntervals::shrinkToUses(LiveInterval::SubRange &SR, Register Reg) {
+void LiveIntervals::shrinkToUses(LiveInterval::SubRange &SR, Register Reg) {
LLVM_DEBUG(dbgs() << "Shrink: " << SR << '\n');
assert(Register::isVirtualRegister(Reg) &&
"Can only shrink virtual registers");
@@ -707,7 +707,7 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
LiveRange::const_iterator>, 4> SRs;
for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
- Register Reg = Register::index2VirtReg(i);
+ Register Reg = Register::index2VirtReg(i);
if (MRI->reg_nodbg_empty(Reg))
continue;
const LiveInterval &LI = getInterval(Reg);
@@ -878,12 +878,12 @@ float LiveIntervals::getSpillWeight(bool isDef, bool isUse,
float LiveIntervals::getSpillWeight(bool isDef, bool isUse,
const MachineBlockFrequencyInfo *MBFI,
const MachineBasicBlock *MBB) {
- return (isDef + isUse) * MBFI->getBlockFreqRelativeToEntryBlock(MBB);
+ return (isDef + isUse) * MBFI->getBlockFreqRelativeToEntryBlock(MBB);
}
LiveRange::Segment
-LiveIntervals::addSegmentToEndOfBlock(Register Reg, MachineInstr &startInst) {
- LiveInterval &Interval = createEmptyInterval(Reg);
+LiveIntervals::addSegmentToEndOfBlock(Register Reg, MachineInstr &startInst) {
+ LiveInterval &Interval = createEmptyInterval(Reg);
VNInfo *VN = Interval.getNextValue(
SlotIndex(getInstructionIndex(startInst).getRegSlot()),
getVNInfoAllocator());
@@ -1038,8 +1038,8 @@ public:
// For physregs, only update the regunits that actually have a
// precomputed live range.
- for (MCRegUnitIterator Units(Reg.asMCReg(), &TRI); Units.isValid();
- ++Units)
+ for (MCRegUnitIterator Units(Reg.asMCReg(), &TRI); Units.isValid();
+ ++Units)
if (LiveRange *LR = getRegUnitLI(*Units))
updateRange(*LR, *Units, LaneBitmask::getNone());
}
@@ -1050,7 +1050,7 @@ public:
private:
/// Update a single live range, assuming an instruction has been moved from
/// OldIdx to NewIdx.
- void updateRange(LiveRange &LR, Register Reg, LaneBitmask LaneMask) {
+ void updateRange(LiveRange &LR, Register Reg, LaneBitmask LaneMask) {
if (!Updated.insert(&LR).second)
return;
LLVM_DEBUG({
@@ -1247,7 +1247,7 @@ private:
/// Update LR to reflect an instruction has been moved upwards from OldIdx
/// to NewIdx (NewIdx < OldIdx).
- void handleMoveUp(LiveRange &LR, Register Reg, LaneBitmask LaneMask) {
+ void handleMoveUp(LiveRange &LR, Register Reg, LaneBitmask LaneMask) {
LiveRange::iterator E = LR.end();
// Segment going into OldIdx.
LiveRange::iterator OldIdxIn = LR.find(OldIdx.getBaseIndex());
@@ -1429,7 +1429,7 @@ private:
}
// Return the last use of reg between NewIdx and OldIdx.
- SlotIndex findLastUseBefore(SlotIndex Before, Register Reg,
+ SlotIndex findLastUseBefore(SlotIndex Before, Register Reg,
LaneBitmask LaneMask) {
if (Register::isVirtualRegister(Reg)) {
SlotIndex LastUse = Before;
@@ -1542,17 +1542,17 @@ void LiveIntervals::handleMoveIntoNewBundle(MachineInstr &BundleStart,
void LiveIntervals::repairOldRegInRange(const MachineBasicBlock::iterator Begin,
const MachineBasicBlock::iterator End,
- const SlotIndex EndIdx, LiveRange &LR,
- const Register Reg,
+ const SlotIndex EndIdx, LiveRange &LR,
+ const Register Reg,
LaneBitmask LaneMask) {
- LiveInterval::iterator LII = LR.find(EndIdx);
+ LiveInterval::iterator LII = LR.find(EndIdx);
SlotIndex lastUseIdx;
if (LII == LR.begin()) {
// This happens when the function is called for a subregister that only
// occurs _after_ the range that is to be repaired.
return;
}
- if (LII != LR.end() && LII->start < EndIdx)
+ if (LII != LR.end() && LII->start < EndIdx)
lastUseIdx = LII->end;
else
--LII;
@@ -1646,11 +1646,11 @@ LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB,
while (End != MBB->end() && !Indexes->hasIndex(*End))
++End;
- SlotIndex EndIdx;
+ SlotIndex EndIdx;
if (End == MBB->end())
- EndIdx = getMBBEndIdx(MBB).getPrevSlot();
+ EndIdx = getMBBEndIdx(MBB).getPrevSlot();
else
- EndIdx = getInstructionIndex(*End);
+ EndIdx = getInstructionIndex(*End);
Indexes->repairIndexesInRange(MBB, Begin, End);
@@ -1679,13 +1679,13 @@ LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB,
continue;
for (LiveInterval::SubRange &S : LI.subranges())
- repairOldRegInRange(Begin, End, EndIdx, S, Reg, S.LaneMask);
+ repairOldRegInRange(Begin, End, EndIdx, S, Reg, S.LaneMask);
- repairOldRegInRange(Begin, End, EndIdx, LI, Reg);
+ repairOldRegInRange(Begin, End, EndIdx, LI, Reg);
}
}
-void LiveIntervals::removePhysRegDefAt(MCRegister Reg, SlotIndex Pos) {
+void LiveIntervals::removePhysRegDefAt(MCRegister Reg, SlotIndex Pos) {
for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) {
if (LiveRange *LR = getCachedRegUnit(*Unit))
if (VNInfo *VNI = LR->getVNInfoAt(Pos))
@@ -1718,7 +1718,7 @@ void LiveIntervals::splitSeparateComponents(LiveInterval &LI,
if (NumComp <= 1)
return;
LLVM_DEBUG(dbgs() << " Split " << NumComp << " components: " << LI << '\n');
- Register Reg = LI.reg();
+ Register Reg = LI.reg();
const TargetRegisterClass *RegClass = MRI->getRegClass(Reg);
for (unsigned I = 1; I < NumComp; ++I) {
Register NewVReg = MRI->createVirtualRegister(RegClass);
diff --git a/contrib/libs/llvm12/lib/CodeGen/LiveRangeEdit.cpp b/contrib/libs/llvm12/lib/CodeGen/LiveRangeEdit.cpp
index 737b29125c..037cb54262 100644
--- a/contrib/libs/llvm12/lib/CodeGen/LiveRangeEdit.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/LiveRangeEdit.cpp
@@ -187,7 +187,7 @@ bool LiveRangeEdit::foldAsLoad(LiveInterval *LI,
MachineInstr *DefMI = nullptr, *UseMI = nullptr;
// Check that there is a single def and a single use.
- for (MachineOperand &MO : MRI.reg_nodbg_operands(LI->reg())) {
+ for (MachineOperand &MO : MRI.reg_nodbg_operands(LI->reg())) {
MachineInstr *MI = MO.getParent();
if (MO.isDef()) {
if (DefMI && DefMI != MI)
@@ -223,7 +223,7 @@ bool LiveRangeEdit::foldAsLoad(LiveInterval *LI,
<< " into single use: " << *UseMI);
SmallVector<unsigned, 8> Ops;
- if (UseMI->readsWritesVirtualRegister(LI->reg(), &Ops).second)
+ if (UseMI->readsWritesVirtualRegister(LI->reg(), &Ops).second)
return false;
MachineInstr *FoldMI = TII.foldMemoryOperand(*UseMI, Ops, *DefMI, &LIS);
@@ -235,7 +235,7 @@ bool LiveRangeEdit::foldAsLoad(LiveInterval *LI,
if (UseMI->shouldUpdateCallSiteInfo())
UseMI->getMF()->moveCallSiteInfo(UseMI, FoldMI);
UseMI->eraseFromParent();
- DefMI->addRegisterDead(LI->reg(), nullptr);
+ DefMI->addRegisterDead(LI->reg(), nullptr);
Dead.push_back(DefMI);
++NumDCEFoldedLoads;
return true;
@@ -315,7 +315,7 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink,
if (Reg && MOI->readsReg() && !MRI.isReserved(Reg))
ReadsPhysRegs = true;
else if (MOI->isDef())
- LIS.removePhysRegDefAt(Reg.asMCReg(), Idx);
+ LIS.removePhysRegDefAt(Reg.asMCReg(), Idx);
continue;
}
LiveInterval &LI = LIS.getInterval(Reg);
@@ -331,7 +331,7 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink,
// Remove defined value.
if (MOI->isDef()) {
if (TheDelegate && LI.getVNInfoAt(Idx) != nullptr)
- TheDelegate->LRE_WillShrinkVirtReg(LI.reg());
+ TheDelegate->LRE_WillShrinkVirtReg(LI.reg());
LIS.removeVRegDefAt(LI, Idx);
if (LI.empty())
RegsToErase.push_back(Reg);
@@ -368,7 +368,7 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink,
pop_back();
DeadRemats->insert(MI);
const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
- MI->substituteRegister(Dest, NewLI.reg(), 0, TRI);
+ MI->substituteRegister(Dest, NewLI.reg(), 0, TRI);
MI->getOperand(0).setIsDead(true);
} else {
if (TheDelegate)
@@ -408,7 +408,7 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr *> &Dead,
ToShrink.pop_back();
if (foldAsLoad(LI, Dead))
continue;
- unsigned VReg = LI->reg();
+ unsigned VReg = LI->reg();
if (TheDelegate)
TheDelegate->LRE_WillShrinkVirtReg(VReg);
if (!LIS.shrinkToUses(LI, &Dead))
@@ -435,15 +435,15 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr *> &Dead,
if (!SplitLIs.empty())
++NumFracRanges;
- Register Original = VRM ? VRM->getOriginal(VReg) : Register();
+ Register Original = VRM ? VRM->getOriginal(VReg) : Register();
for (const LiveInterval *SplitLI : SplitLIs) {
// If LI is an original interval that hasn't been split yet, make the new
// intervals their own originals instead of referring to LI. The original
// interval must contain all the split products, and LI doesn't.
if (Original != VReg && Original != 0)
- VRM->setIsSplitFromReg(SplitLI->reg(), Original);
+ VRM->setIsSplitFromReg(SplitLI->reg(), Original);
if (TheDelegate)
- TheDelegate->LRE_DidCloneVirtReg(SplitLI->reg(), VReg);
+ TheDelegate->LRE_DidCloneVirtReg(SplitLI->reg(), VReg);
}
}
}
@@ -462,14 +462,14 @@ void
LiveRangeEdit::calculateRegClassAndHint(MachineFunction &MF,
const MachineLoopInfo &Loops,
const MachineBlockFrequencyInfo &MBFI) {
- VirtRegAuxInfo VRAI(MF, LIS, *VRM, Loops, MBFI);
+ VirtRegAuxInfo VRAI(MF, LIS, *VRM, Loops, MBFI);
for (unsigned I = 0, Size = size(); I < Size; ++I) {
LiveInterval &LI = LIS.getInterval(get(I));
- if (MRI.recomputeRegClass(LI.reg()))
+ if (MRI.recomputeRegClass(LI.reg()))
LLVM_DEBUG({
const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
- dbgs() << "Inflated " << printReg(LI.reg()) << " to "
- << TRI->getRegClassName(MRI.getRegClass(LI.reg())) << '\n';
+ dbgs() << "Inflated " << printReg(LI.reg()) << " to "
+ << TRI->getRegClassName(MRI.getRegClass(LI.reg())) << '\n';
});
VRAI.calculateSpillWeightAndHint(LI);
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/LiveRangeShrink.cpp b/contrib/libs/llvm12/lib/CodeGen/LiveRangeShrink.cpp
index fb7f01608d..7fa14fd902 100644
--- a/contrib/libs/llvm12/lib/CodeGen/LiveRangeShrink.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/LiveRangeShrink.cpp
@@ -156,8 +156,8 @@ bool LiveRangeShrink::runOnMachineFunction(MachineFunction &MF) {
// If MI has side effects, it should become a barrier for code motion.
// IOM is rebuild from the next instruction to prevent later
// instructions from being moved before this MI.
- if (MI.hasUnmodeledSideEffects() && !MI.isPseudoProbe() &&
- Next != MBB.end()) {
+ if (MI.hasUnmodeledSideEffects() && !MI.isPseudoProbe() &&
+ Next != MBB.end()) {
BuildInstOrderMap(Next, IOM);
SawStore = false;
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/LiveRegMatrix.cpp b/contrib/libs/llvm12/lib/CodeGen/LiveRegMatrix.cpp
index 2353f07164..a69aa6557e 100644
--- a/contrib/libs/llvm12/lib/CodeGen/LiveRegMatrix.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/LiveRegMatrix.cpp
@@ -78,7 +78,7 @@ void LiveRegMatrix::releaseMemory() {
template <typename Callable>
static bool foreachUnit(const TargetRegisterInfo *TRI,
- LiveInterval &VRegInterval, MCRegister PhysReg,
+ LiveInterval &VRegInterval, MCRegister PhysReg,
Callable Func) {
if (VRegInterval.hasSubRanges()) {
for (MCRegUnitMaskIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
@@ -101,11 +101,11 @@ static bool foreachUnit(const TargetRegisterInfo *TRI,
return false;
}
-void LiveRegMatrix::assign(LiveInterval &VirtReg, MCRegister PhysReg) {
- LLVM_DEBUG(dbgs() << "assigning " << printReg(VirtReg.reg(), TRI) << " to "
+void LiveRegMatrix::assign(LiveInterval &VirtReg, MCRegister PhysReg) {
+ LLVM_DEBUG(dbgs() << "assigning " << printReg(VirtReg.reg(), TRI) << " to "
<< printReg(PhysReg, TRI) << ':');
- assert(!VRM->hasPhys(VirtReg.reg()) && "Duplicate VirtReg assignment");
- VRM->assignVirt2Phys(VirtReg.reg(), PhysReg);
+ assert(!VRM->hasPhys(VirtReg.reg()) && "Duplicate VirtReg assignment");
+ VRM->assignVirt2Phys(VirtReg.reg(), PhysReg);
foreachUnit(
TRI, VirtReg, PhysReg, [&](unsigned Unit, const LiveRange &Range) {
@@ -119,10 +119,10 @@ void LiveRegMatrix::assign(LiveInterval &VirtReg, MCRegister PhysReg) {
}
void LiveRegMatrix::unassign(LiveInterval &VirtReg) {
- Register PhysReg = VRM->getPhys(VirtReg.reg());
- LLVM_DEBUG(dbgs() << "unassigning " << printReg(VirtReg.reg(), TRI)
- << " from " << printReg(PhysReg, TRI) << ':');
- VRM->clearVirt(VirtReg.reg());
+ Register PhysReg = VRM->getPhys(VirtReg.reg());
+ LLVM_DEBUG(dbgs() << "unassigning " << printReg(VirtReg.reg(), TRI)
+ << " from " << printReg(PhysReg, TRI) << ':');
+ VRM->clearVirt(VirtReg.reg());
foreachUnit(TRI, VirtReg, PhysReg,
[&](unsigned Unit, const LiveRange &Range) {
@@ -135,7 +135,7 @@ void LiveRegMatrix::unassign(LiveInterval &VirtReg) {
LLVM_DEBUG(dbgs() << '\n');
}
-bool LiveRegMatrix::isPhysRegUsed(MCRegister PhysReg) const {
+bool LiveRegMatrix::isPhysRegUsed(MCRegister PhysReg) const {
for (MCRegUnitIterator Unit(PhysReg, TRI); Unit.isValid(); ++Unit) {
if (!Matrix[*Unit].empty())
return true;
@@ -144,12 +144,12 @@ bool LiveRegMatrix::isPhysRegUsed(MCRegister PhysReg) const {
}
bool LiveRegMatrix::checkRegMaskInterference(LiveInterval &VirtReg,
- MCRegister PhysReg) {
+ MCRegister PhysReg) {
// Check if the cached information is valid.
// The same BitVector can be reused for all PhysRegs.
// We could cache multiple VirtRegs if it becomes necessary.
- if (RegMaskVirtReg != VirtReg.reg() || RegMaskTag != UserTag) {
- RegMaskVirtReg = VirtReg.reg();
+ if (RegMaskVirtReg != VirtReg.reg() || RegMaskTag != UserTag) {
+ RegMaskVirtReg = VirtReg.reg();
RegMaskTag = UserTag;
RegMaskUsable.clear();
LIS->checkRegMaskInterference(VirtReg, RegMaskUsable);
@@ -162,10 +162,10 @@ bool LiveRegMatrix::checkRegMaskInterference(LiveInterval &VirtReg,
}
bool LiveRegMatrix::checkRegUnitInterference(LiveInterval &VirtReg,
- MCRegister PhysReg) {
+ MCRegister PhysReg) {
if (VirtReg.empty())
return false;
- CoalescerPair CP(VirtReg.reg(), PhysReg, *TRI);
+ CoalescerPair CP(VirtReg.reg(), PhysReg, *TRI);
bool Result = foreachUnit(TRI, VirtReg, PhysReg, [&](unsigned Unit,
const LiveRange &Range) {
@@ -176,14 +176,14 @@ bool LiveRegMatrix::checkRegUnitInterference(LiveInterval &VirtReg,
}
LiveIntervalUnion::Query &LiveRegMatrix::query(const LiveRange &LR,
- MCRegister RegUnit) {
+ MCRegister RegUnit) {
LiveIntervalUnion::Query &Q = Queries[RegUnit];
Q.init(UserTag, LR, Matrix[RegUnit]);
return Q;
}
LiveRegMatrix::InterferenceKind
-LiveRegMatrix::checkInterference(LiveInterval &VirtReg, MCRegister PhysReg) {
+LiveRegMatrix::checkInterference(LiveInterval &VirtReg, MCRegister PhysReg) {
if (VirtReg.empty())
return IK_Free;
@@ -197,9 +197,9 @@ LiveRegMatrix::checkInterference(LiveInterval &VirtReg, MCRegister PhysReg) {
// Check the matrix for virtual register interference.
bool Interference = foreachUnit(TRI, VirtReg, PhysReg,
- [&](MCRegister Unit, const LiveRange &LR) {
- return query(LR, Unit).checkInterference();
- });
+ [&](MCRegister Unit, const LiveRange &LR) {
+ return query(LR, Unit).checkInterference();
+ });
if (Interference)
return IK_VirtReg;
@@ -207,7 +207,7 @@ LiveRegMatrix::checkInterference(LiveInterval &VirtReg, MCRegister PhysReg) {
}
bool LiveRegMatrix::checkInterference(SlotIndex Start, SlotIndex End,
- MCRegister PhysReg) {
+ MCRegister PhysReg) {
// Construct artificial live range containing only one segment [Start, End).
VNInfo valno(0, Start);
LiveRange::Segment Seg(Start, End, &valno);
@@ -221,13 +221,13 @@ bool LiveRegMatrix::checkInterference(SlotIndex Start, SlotIndex End,
}
return false;
}
-
-Register LiveRegMatrix::getOneVReg(unsigned PhysReg) const {
- LiveInterval *VRegInterval = nullptr;
- for (MCRegUnitIterator Unit(PhysReg, TRI); Unit.isValid(); ++Unit) {
- if ((VRegInterval = Matrix[*Unit].getOneVReg()))
- return VRegInterval->reg();
- }
-
- return MCRegister::NoRegister;
-}
+
+Register LiveRegMatrix::getOneVReg(unsigned PhysReg) const {
+ LiveInterval *VRegInterval = nullptr;
+ for (MCRegUnitIterator Unit(PhysReg, TRI); Unit.isValid(); ++Unit) {
+ if ((VRegInterval = Matrix[*Unit].getOneVReg()))
+ return VRegInterval->reg();
+ }
+
+ return MCRegister::NoRegister;
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/LiveVariables.cpp b/contrib/libs/llvm12/lib/CodeGen/LiveVariables.cpp
index 88f16ee29f..49b880c309 100644
--- a/contrib/libs/llvm12/lib/CodeGen/LiveVariables.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/LiveVariables.cpp
@@ -82,15 +82,15 @@ LLVM_DUMP_METHOD void LiveVariables::VarInfo::dump() const {
#endif
/// getVarInfo - Get (possibly creating) a VarInfo object for the given vreg.
-LiveVariables::VarInfo &LiveVariables::getVarInfo(Register Reg) {
- assert(Reg.isVirtual() && "getVarInfo: not a virtual register!");
- VirtRegInfo.grow(Reg);
- return VirtRegInfo[Reg];
+LiveVariables::VarInfo &LiveVariables::getVarInfo(Register Reg) {
+ assert(Reg.isVirtual() && "getVarInfo: not a virtual register!");
+ VirtRegInfo.grow(Reg);
+ return VirtRegInfo[Reg];
}
-void LiveVariables::MarkVirtRegAliveInBlock(
- VarInfo &VRInfo, MachineBasicBlock *DefBlock, MachineBasicBlock *MBB,
- SmallVectorImpl<MachineBasicBlock *> &WorkList) {
+void LiveVariables::MarkVirtRegAliveInBlock(
+ VarInfo &VRInfo, MachineBasicBlock *DefBlock, MachineBasicBlock *MBB,
+ SmallVectorImpl<MachineBasicBlock *> &WorkList) {
unsigned BBNum = MBB->getNumber();
// Check to see if this basic block is one of the killing blocks. If so,
@@ -116,7 +116,7 @@ void LiveVariables::MarkVirtRegAliveInBlock(
void LiveVariables::MarkVirtRegAliveInBlock(VarInfo &VRInfo,
MachineBasicBlock *DefBlock,
MachineBasicBlock *MBB) {
- SmallVector<MachineBasicBlock *, 16> WorkList;
+ SmallVector<MachineBasicBlock *, 16> WorkList;
MarkVirtRegAliveInBlock(VRInfo, DefBlock, MBB, WorkList);
while (!WorkList.empty()) {
@@ -126,13 +126,13 @@ void LiveVariables::MarkVirtRegAliveInBlock(VarInfo &VRInfo,
}
}
-void LiveVariables::HandleVirtRegUse(Register Reg, MachineBasicBlock *MBB,
+void LiveVariables::HandleVirtRegUse(Register Reg, MachineBasicBlock *MBB,
MachineInstr &MI) {
- assert(MRI->getVRegDef(Reg) && "Register use before def!");
+ assert(MRI->getVRegDef(Reg) && "Register use before def!");
unsigned BBNum = MBB->getNumber();
- VarInfo &VRInfo = getVarInfo(Reg);
+ VarInfo &VRInfo = getVarInfo(Reg);
// Check to see if this basic block is already a kill block.
if (!VRInfo.Kills.empty() && VRInfo.Kills.back()->getParent() == MBB) {
@@ -163,8 +163,8 @@ void LiveVariables::HandleVirtRegUse(Register Reg, MachineBasicBlock *MBB,
// where there is a use in a PHI node that's a predecessor to the defining
// block. We don't want to mark all predecessors as having the value "alive"
// in this case.
- if (MBB == MRI->getVRegDef(Reg)->getParent())
- return;
+ if (MBB == MRI->getVRegDef(Reg)->getParent())
+ return;
// Add a new kill entry for this basic block. If this virtual register is
// already marked as alive in this basic block, that means it is alive in at
@@ -175,10 +175,10 @@ void LiveVariables::HandleVirtRegUse(Register Reg, MachineBasicBlock *MBB,
// Update all dominating blocks to mark them as "known live".
for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(),
E = MBB->pred_end(); PI != E; ++PI)
- MarkVirtRegAliveInBlock(VRInfo, MRI->getVRegDef(Reg)->getParent(), *PI);
+ MarkVirtRegAliveInBlock(VRInfo, MRI->getVRegDef(Reg)->getParent(), *PI);
}
-void LiveVariables::HandleVirtRegDef(Register Reg, MachineInstr &MI) {
+void LiveVariables::HandleVirtRegDef(Register Reg, MachineInstr &MI) {
VarInfo &VRInfo = getVarInfo(Reg);
if (VRInfo.AliveBlocks.empty())
@@ -188,9 +188,9 @@ void LiveVariables::HandleVirtRegDef(Register Reg, MachineInstr &MI) {
/// FindLastPartialDef - Return the last partial def of the specified register.
/// Also returns the sub-registers that're defined by the instruction.
-MachineInstr *
-LiveVariables::FindLastPartialDef(Register Reg,
- SmallSet<unsigned, 4> &PartDefRegs) {
+MachineInstr *
+LiveVariables::FindLastPartialDef(Register Reg,
+ SmallSet<unsigned, 4> &PartDefRegs) {
unsigned LastDefReg = 0;
unsigned LastDefDist = 0;
MachineInstr *LastDef = nullptr;
@@ -228,7 +228,7 @@ LiveVariables::FindLastPartialDef(Register Reg,
/// HandlePhysRegUse - Turn previous partial def's into read/mod/writes. Add
/// implicit defs to a machine instruction if there was an earlier def of its
/// super-register.
-void LiveVariables::HandlePhysRegUse(Register Reg, MachineInstr &MI) {
+void LiveVariables::HandlePhysRegUse(Register Reg, MachineInstr &MI) {
MachineInstr *LastDef = PhysRegDef[Reg];
// If there was a previous use or a "full" def all is well.
if (!LastDef && !PhysRegUse[Reg]) {
@@ -278,7 +278,7 @@ void LiveVariables::HandlePhysRegUse(Register Reg, MachineInstr &MI) {
/// FindLastRefOrPartRef - Return the last reference or partial reference of
/// the specified register.
-MachineInstr *LiveVariables::FindLastRefOrPartRef(Register Reg) {
+MachineInstr *LiveVariables::FindLastRefOrPartRef(Register Reg) {
MachineInstr *LastDef = PhysRegDef[Reg];
MachineInstr *LastUse = PhysRegUse[Reg];
if (!LastDef && !LastUse)
@@ -308,7 +308,7 @@ MachineInstr *LiveVariables::FindLastRefOrPartRef(Register Reg) {
return LastRefOrPartRef;
}
-bool LiveVariables::HandlePhysRegKill(Register Reg, MachineInstr *MI) {
+bool LiveVariables::HandlePhysRegKill(Register Reg, MachineInstr *MI) {
MachineInstr *LastDef = PhysRegDef[Reg];
MachineInstr *LastUse = PhysRegUse[Reg];
if (!LastDef && !LastUse)
@@ -440,7 +440,7 @@ void LiveVariables::HandleRegMask(const MachineOperand &MO) {
}
}
-void LiveVariables::HandlePhysRegDef(Register Reg, MachineInstr *MI,
+void LiveVariables::HandlePhysRegDef(Register Reg, MachineInstr *MI,
SmallVectorImpl<unsigned> &Defs) {
// What parts of the register are previously defined?
SmallSet<unsigned, 32> Live;
@@ -486,7 +486,7 @@ void LiveVariables::HandlePhysRegDef(Register Reg, MachineInstr *MI,
void LiveVariables::UpdatePhysRegDefs(MachineInstr &MI,
SmallVectorImpl<unsigned> &Defs) {
while (!Defs.empty()) {
- Register Reg = Defs.back();
+ Register Reg = Defs.back();
Defs.pop_back();
for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true);
SubRegs.isValid(); ++SubRegs) {
@@ -653,7 +653,7 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
// Convert and transfer the dead / killed information we have gathered into
// VirtRegInfo onto MI's.
for (unsigned i = 0, e1 = VirtRegInfo.size(); i != e1; ++i) {
- const Register Reg = Register::index2VirtReg(i);
+ const Register Reg = Register::index2VirtReg(i);
for (unsigned j = 0, e2 = VirtRegInfo[Reg].Kills.size(); j != e2; ++j)
if (VirtRegInfo[Reg].Kills[j] == MRI->getVRegDef(Reg))
VirtRegInfo[Reg].Kills[j]->addRegisterDead(Reg, TRI);
@@ -666,7 +666,7 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
// other part of the code generator if this happens.
#ifndef NDEBUG
for(MachineFunction::iterator i = MF->begin(), e = MF->end(); i != e; ++i)
- assert(Visited.contains(&*i) && "unreachable basic block found");
+ assert(Visited.contains(&*i) && "unreachable basic block found");
#endif
PhysRegDef.clear();
@@ -678,7 +678,7 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
/// replaceKillInstruction - Update register kill info by replacing a kill
/// instruction with a new one.
-void LiveVariables::replaceKillInstruction(Register Reg, MachineInstr &OldMI,
+void LiveVariables::replaceKillInstruction(Register Reg, MachineInstr &OldMI,
MachineInstr &NewMI) {
VarInfo &VI = getVarInfo(Reg);
std::replace(VI.Kills.begin(), VI.Kills.end(), &OldMI, &NewMI);
@@ -718,7 +718,7 @@ void LiveVariables::analyzePHINodes(const MachineFunction& Fn) {
}
bool LiveVariables::VarInfo::isLiveIn(const MachineBasicBlock &MBB,
- Register Reg, MachineRegisterInfo &MRI) {
+ Register Reg, MachineRegisterInfo &MRI) {
unsigned Num = MBB.getNumber();
// Reg is live-through.
@@ -734,7 +734,7 @@ bool LiveVariables::VarInfo::isLiveIn(const MachineBasicBlock &MBB,
return findKill(&MBB);
}
-bool LiveVariables::isLiveOut(Register Reg, const MachineBasicBlock &MBB) {
+bool LiveVariables::isLiveOut(Register Reg, const MachineBasicBlock &MBB) {
LiveVariables::VarInfo &VI = getVarInfo(Reg);
SmallPtrSet<const MachineBasicBlock *, 8> Kills;
@@ -792,7 +792,7 @@ void LiveVariables::addNewBlock(MachineBasicBlock *BB,
// Update info for all live variables
for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
- Register Reg = Register::index2VirtReg(i);
+ Register Reg = Register::index2VirtReg(i);
// If the Defs is defined in the successor it can't be live in BB.
if (Defs.count(Reg))
@@ -818,7 +818,7 @@ void LiveVariables::addNewBlock(MachineBasicBlock *BB,
SparseBitVector<> &BV = LiveInSets[SuccBB->getNumber()];
for (auto R = BV.begin(), E = BV.end(); R != E; R++) {
- Register VirtReg = Register::index2VirtReg(*R);
+ Register VirtReg = Register::index2VirtReg(*R);
LiveVariables::VarInfo &VI = getVarInfo(VirtReg);
VI.AliveBlocks.set(NumNew);
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/LocalStackSlotAllocation.cpp b/contrib/libs/llvm12/lib/CodeGen/LocalStackSlotAllocation.cpp
index 580bcde241..ec6e693e8a 100644
--- a/contrib/libs/llvm12/lib/CodeGen/LocalStackSlotAllocation.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/LocalStackSlotAllocation.cpp
@@ -117,7 +117,7 @@ bool LocalStackSlotPass::runOnMachineFunction(MachineFunction &MF) {
// If the target doesn't want/need this pass, or if there are no locals
// to consider, early exit.
- if (LocalObjectCount == 0 || !TRI->requiresVirtualBaseRegisters(MF))
+ if (LocalObjectCount == 0 || !TRI->requiresVirtualBaseRegisters(MF))
return true;
// Make sure we have enough space to store the local offsets.
@@ -416,17 +416,17 @@ bool LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
const TargetRegisterClass *RC = TRI->getPointerRegClass(*MF);
BaseReg = Fn.getRegInfo().createVirtualRegister(RC);
- LLVM_DEBUG(dbgs() << " Materializing base register"
+ LLVM_DEBUG(dbgs() << " Materializing base register"
<< " at frame local offset "
- << LocalOffset + InstrOffset);
+ << LocalOffset + InstrOffset);
// Tell the target to insert the instruction to initialize
// the base register.
// MachineBasicBlock::iterator InsertionPt = Entry->begin();
- BaseReg = TRI->materializeFrameBaseRegister(Entry, FrameIdx, InstrOffset);
+ BaseReg = TRI->materializeFrameBaseRegister(Entry, FrameIdx, InstrOffset);
+
+ LLVM_DEBUG(dbgs() << " into " << printReg(BaseReg, TRI) << '\n');
- LLVM_DEBUG(dbgs() << " into " << printReg(BaseReg, TRI) << '\n');
-
// The base register already includes any offset specified
// by the instruction, so account for that so it doesn't get
// applied twice.
diff --git a/contrib/libs/llvm12/lib/CodeGen/LowLevelType.cpp b/contrib/libs/llvm12/lib/CodeGen/LowLevelType.cpp
index 26def14b69..2bda586db8 100644
--- a/contrib/libs/llvm12/lib/CodeGen/LowLevelType.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/LowLevelType.cpp
@@ -12,7 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/LowLevelType.h"
-#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APFloat.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/Support/raw_ostream.h"
@@ -59,18 +59,18 @@ LLT llvm::getLLTForMVT(MVT Ty) {
return LLT::vector(Ty.getVectorNumElements(),
Ty.getVectorElementType().getSizeInBits());
}
-
-const llvm::fltSemantics &llvm::getFltSemanticForLLT(LLT Ty) {
- assert(Ty.isScalar() && "Expected a scalar type.");
- switch (Ty.getSizeInBits()) {
- case 16:
- return APFloat::IEEEhalf();
- case 32:
- return APFloat::IEEEsingle();
- case 64:
- return APFloat::IEEEdouble();
- case 128:
- return APFloat::IEEEquad();
- }
- llvm_unreachable("Invalid FP type size.");
-}
+
+const llvm::fltSemantics &llvm::getFltSemanticForLLT(LLT Ty) {
+ assert(Ty.isScalar() && "Expected a scalar type.");
+ switch (Ty.getSizeInBits()) {
+ case 16:
+ return APFloat::IEEEhalf();
+ case 32:
+ return APFloat::IEEEsingle();
+ case 64:
+ return APFloat::IEEEdouble();
+ case 128:
+ return APFloat::IEEEquad();
+ }
+ llvm_unreachable("Invalid FP type size.");
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/LowerEmuTLS.cpp b/contrib/libs/llvm12/lib/CodeGen/LowerEmuTLS.cpp
index bba9fdca74..a06d1d6255 100644
--- a/contrib/libs/llvm12/lib/CodeGen/LowerEmuTLS.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/LowerEmuTLS.cpp
@@ -16,7 +16,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetPassConfig.h"
-#include "llvm/IR/Constants.h"
+#include "llvm/IR/Constants.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/InitializePasses.h"
@@ -44,7 +44,7 @@ private:
GlobalVariable *to) {
to->setLinkage(from->getLinkage());
to->setVisibility(from->getVisibility());
- to->setDSOLocal(from->isDSOLocal());
+ to->setDSOLocal(from->isDSOLocal());
if (from->hasComdat()) {
to->setComdat(M.getOrInsertComdat(to->getName()));
to->getComdat()->setSelectionKind(from->getComdat()->getSelectionKind());
diff --git a/contrib/libs/llvm12/lib/CodeGen/MBFIWrapper.cpp b/contrib/libs/llvm12/lib/CodeGen/MBFIWrapper.cpp
index d46a395839..4755defec7 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MBFIWrapper.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MBFIWrapper.cpp
@@ -30,18 +30,18 @@ void MBFIWrapper::setBlockFreq(const MachineBasicBlock *MBB,
MergedBBFreq[MBB] = F;
}
-Optional<uint64_t>
-MBFIWrapper::getBlockProfileCount(const MachineBasicBlock *MBB) const {
- auto I = MergedBBFreq.find(MBB);
-
- // Modified block frequency also impacts profile count. So we should compute
- // profile count from new block frequency if it has been changed.
- if (I != MergedBBFreq.end())
- return MBFI.getProfileCountFromFreq(I->second.getFrequency());
-
- return MBFI.getBlockProfileCount(MBB);
-}
-
+Optional<uint64_t>
+MBFIWrapper::getBlockProfileCount(const MachineBasicBlock *MBB) const {
+ auto I = MergedBBFreq.find(MBB);
+
+ // Modified block frequency also impacts profile count. So we should compute
+ // profile count from new block frequency if it has been changed.
+ if (I != MergedBBFreq.end())
+ return MBFI.getProfileCountFromFreq(I->second.getFrequency());
+
+ return MBFI.getBlockProfileCount(MBB);
+}
+
raw_ostream & MBFIWrapper::printBlockFreq(raw_ostream &OS,
const MachineBasicBlock *MBB) const {
return MBFI.printBlockFreq(OS, getBlockFreq(MBB));
diff --git a/contrib/libs/llvm12/lib/CodeGen/MIRCanonicalizerPass.cpp b/contrib/libs/llvm12/lib/CodeGen/MIRCanonicalizerPass.cpp
index f65b8d231b..8ef6aca602 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MIRCanonicalizerPass.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MIRCanonicalizerPass.cpp
@@ -85,7 +85,7 @@ static std::vector<MachineBasicBlock *> GetRPOList(MachineFunction &MF) {
return {};
ReversePostOrderTraversal<MachineBasicBlock *> RPOT(&*MF.begin());
std::vector<MachineBasicBlock *> RPOList;
- append_range(RPOList, RPOT);
+ append_range(RPOList, RPOT);
return RPOList;
}
@@ -106,7 +106,7 @@ rescheduleLexographically(std::vector<MachineInstr *> instructions,
OS.flush();
// Trim the assignment, or start from the beginning in the case of a store.
- const size_t i = S.find('=');
+ const size_t i = S.find('=');
StringInstrMap.push_back({(i == std::string::npos) ? S : S.substr(i), II});
}
@@ -196,7 +196,7 @@ static bool rescheduleCanonically(unsigned &PseudoIdempotentInstCount,
if (II->getOperand(i).isReg()) {
if (!Register::isVirtualRegister(II->getOperand(i).getReg()))
- if (!llvm::is_contained(PhysRegDefs, II->getOperand(i).getReg())) {
+ if (!llvm::is_contained(PhysRegDefs, II->getOperand(i).getReg())) {
continue;
}
}
@@ -273,9 +273,9 @@ static bool rescheduleCanonically(unsigned &PseudoIdempotentInstCount,
// Sort the defs for users of multiple defs lexographically.
for (const auto &E : MultiUserLookup) {
- auto UseI = llvm::find_if(MBB->instrs(), [&](MachineInstr &MI) -> bool {
- return &MI == E.second;
- });
+ auto UseI = llvm::find_if(MBB->instrs(), [&](MachineInstr &MI) -> bool {
+ return &MI == E.second;
+ });
if (UseI == MBB->instr_end())
continue;
diff --git a/contrib/libs/llvm12/lib/CodeGen/MIRParser/MILexer.cpp b/contrib/libs/llvm12/lib/CodeGen/MIRParser/MILexer.cpp
index cb50d73355..b86fd6b413 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MIRParser/MILexer.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MIRParser/MILexer.cpp
@@ -212,12 +212,12 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
.Case("contract", MIToken::kw_contract)
.Case("afn", MIToken::kw_afn)
.Case("reassoc", MIToken::kw_reassoc)
- .Case("nuw", MIToken::kw_nuw)
- .Case("nsw", MIToken::kw_nsw)
- .Case("exact", MIToken::kw_exact)
+ .Case("nuw", MIToken::kw_nuw)
+ .Case("nsw", MIToken::kw_nsw)
+ .Case("exact", MIToken::kw_exact)
.Case("nofpexcept", MIToken::kw_nofpexcept)
.Case("debug-location", MIToken::kw_debug_location)
- .Case("debug-instr-number", MIToken::kw_debug_instr_number)
+ .Case("debug-instr-number", MIToken::kw_debug_instr_number)
.Case("same_value", MIToken::kw_cfi_same_value)
.Case("offset", MIToken::kw_cfi_offset)
.Case("rel_offset", MIToken::kw_cfi_rel_offset)
@@ -232,8 +232,8 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
.Case("undefined", MIToken::kw_cfi_undefined)
.Case("register", MIToken::kw_cfi_register)
.Case("window_save", MIToken::kw_cfi_window_save)
- .Case("negate_ra_sign_state",
- MIToken::kw_cfi_aarch64_negate_ra_sign_state)
+ .Case("negate_ra_sign_state",
+ MIToken::kw_cfi_aarch64_negate_ra_sign_state)
.Case("blockaddress", MIToken::kw_blockaddress)
.Case("intrinsic", MIToken::kw_intrinsic)
.Case("target-index", MIToken::kw_target_index)
@@ -249,7 +249,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
.Case("dereferenceable", MIToken::kw_dereferenceable)
.Case("invariant", MIToken::kw_invariant)
.Case("align", MIToken::kw_align)
- .Case("basealign", MIToken::kw_align)
+ .Case("basealign", MIToken::kw_align)
.Case("addrspace", MIToken::kw_addrspace)
.Case("stack", MIToken::kw_stack)
.Case("got", MIToken::kw_got)
diff --git a/contrib/libs/llvm12/lib/CodeGen/MIRParser/MILexer.h b/contrib/libs/llvm12/lib/CodeGen/MIRParser/MILexer.h
index 65b60bb4ea..452eda7213 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MIRParser/MILexer.h
+++ b/contrib/libs/llvm12/lib/CodeGen/MIRParser/MILexer.h
@@ -74,7 +74,7 @@ struct MIToken {
kw_exact,
kw_nofpexcept,
kw_debug_location,
- kw_debug_instr_number,
+ kw_debug_instr_number,
kw_cfi_same_value,
kw_cfi_offset,
kw_cfi_rel_offset,
@@ -104,7 +104,7 @@ struct MIToken {
kw_non_temporal,
kw_invariant,
kw_align,
- kw_basealign,
+ kw_basealign,
kw_addrspace,
kw_stack,
kw_got,
diff --git a/contrib/libs/llvm12/lib/CodeGen/MIRParser/MIParser.cpp b/contrib/libs/llvm12/lib/CodeGen/MIRParser/MIParser.cpp
index 9aafce8dda..fe979b9818 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MIRParser/MIParser.cpp
@@ -369,7 +369,7 @@ static void initSlots2Values(const Function &F,
const Value* PerFunctionMIParsingState::getIRValue(unsigned Slot) {
if (Slots2Values.empty())
initSlots2Values(MF.getFunction(), Slots2Values);
- return Slots2Values.lookup(Slot);
+ return Slots2Values.lookup(Slot);
}
namespace {
@@ -981,7 +981,7 @@ bool MIParser::parse(MachineInstr *&MI) {
Token.isNot(MIToken::kw_post_instr_symbol) &&
Token.isNot(MIToken::kw_heap_alloc_marker) &&
Token.isNot(MIToken::kw_debug_location) &&
- Token.isNot(MIToken::kw_debug_instr_number) &&
+ Token.isNot(MIToken::kw_debug_instr_number) &&
Token.isNot(MIToken::coloncolon) && Token.isNot(MIToken::lbrace)) {
auto Loc = Token.location();
Optional<unsigned> TiedDefIdx;
@@ -1012,19 +1012,19 @@ bool MIParser::parse(MachineInstr *&MI) {
if (parseHeapAllocMarker(HeapAllocMarker))
return true;
- unsigned InstrNum = 0;
- if (Token.is(MIToken::kw_debug_instr_number)) {
- lex();
- if (Token.isNot(MIToken::IntegerLiteral))
- return error("expected an integer literal after 'debug-instr-number'");
- if (getUnsigned(InstrNum))
- return true;
- lex();
- // Lex past trailing comma if present.
- if (Token.is(MIToken::comma))
- lex();
- }
-
+ unsigned InstrNum = 0;
+ if (Token.is(MIToken::kw_debug_instr_number)) {
+ lex();
+ if (Token.isNot(MIToken::IntegerLiteral))
+ return error("expected an integer literal after 'debug-instr-number'");
+ if (getUnsigned(InstrNum))
+ return true;
+ lex();
+ // Lex past trailing comma if present.
+ if (Token.is(MIToken::comma))
+ lex();
+ }
+
DebugLoc DebugLocation;
if (Token.is(MIToken::kw_debug_location)) {
lex();
@@ -1081,8 +1081,8 @@ bool MIParser::parse(MachineInstr *&MI) {
MI->setHeapAllocMarker(MF, HeapAllocMarker);
if (!MemOperands.empty())
MI->setMemRefs(MF, MemOperands);
- if (InstrNum)
- MI->setDebugInstrNum(InstrNum);
+ if (InstrNum)
+ MI->setDebugInstrNum(InstrNum);
return false;
}
@@ -2726,7 +2726,7 @@ bool MIParser::parseOffset(int64_t &Offset) {
}
bool MIParser::parseAlignment(unsigned &Alignment) {
- assert(Token.is(MIToken::kw_align) || Token.is(MIToken::kw_basealign));
+ assert(Token.is(MIToken::kw_align) || Token.is(MIToken::kw_basealign));
lex();
if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
return error("expected an integer literal after 'align'");
@@ -3074,15 +3074,15 @@ bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) {
while (consumeIfPresent(MIToken::comma)) {
switch (Token.kind()) {
case MIToken::kw_align:
- // align is printed if it is different than size.
+ // align is printed if it is different than size.
+ if (parseAlignment(BaseAlignment))
+ return true;
+ break;
+ case MIToken::kw_basealign:
+ // basealign is printed if it is different than align.
if (parseAlignment(BaseAlignment))
return true;
break;
- case MIToken::kw_basealign:
- // basealign is printed if it is different than align.
- if (parseAlignment(BaseAlignment))
- return true;
- break;
case MIToken::kw_addrspace:
if (parseAddrspace(Ptr.AddrSpace))
return true;
@@ -3172,7 +3172,7 @@ static void initSlots2BasicBlocks(
static const BasicBlock *getIRBlockFromSlot(
unsigned Slot,
const DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) {
- return Slots2BasicBlocks.lookup(Slot);
+ return Slots2BasicBlocks.lookup(Slot);
}
const BasicBlock *MIParser::getIRBlock(unsigned Slot) {
diff --git a/contrib/libs/llvm12/lib/CodeGen/MIRParser/MIRParser.cpp b/contrib/libs/llvm12/lib/CodeGen/MIRParser/MIRParser.cpp
index 961f8eaf97..ffa9aeb21e 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -161,9 +161,9 @@ private:
SMRange SourceRange);
void computeFunctionProperties(MachineFunction &MF);
-
- void setupDebugValueTracking(MachineFunction &MF,
- PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF);
+
+ void setupDebugValueTracking(MachineFunction &MF,
+ PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF);
};
} // end namespace llvm
@@ -325,14 +325,14 @@ bool MIRParserImpl::parseMachineFunction(Module &M, MachineModuleInfo &MMI) {
static bool isSSA(const MachineFunction &MF) {
const MachineRegisterInfo &MRI = MF.getRegInfo();
for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
- Register Reg = Register::index2VirtReg(I);
+ Register Reg = Register::index2VirtReg(I);
if (!MRI.hasOneDef(Reg) && !MRI.def_empty(Reg))
return false;
-
- // Subregister defs are invalid in SSA.
- const MachineOperand *RegDef = MRI.getOneDef(Reg);
- if (RegDef && RegDef->getSubReg() != 0)
- return false;
+
+ // Subregister defs are invalid in SSA.
+ const MachineOperand *RegDef = MRI.getOneDef(Reg);
+ if (RegDef && RegDef->getSubReg() != 0)
+ return false;
}
return true;
}
@@ -405,23 +405,23 @@ bool MIRParserImpl::initializeCallSiteInfo(
return false;
}
-void MIRParserImpl::setupDebugValueTracking(
- MachineFunction &MF, PerFunctionMIParsingState &PFS,
- const yaml::MachineFunction &YamlMF) {
- // Compute the value of the "next instruction number" field.
- unsigned MaxInstrNum = 0;
- for (auto &MBB : MF)
- for (auto &MI : MBB)
- MaxInstrNum = std::max((unsigned)MI.peekDebugInstrNum(), MaxInstrNum);
- MF.setDebugInstrNumberingCount(MaxInstrNum);
-
- // Load any substitutions.
- for (auto &Sub : YamlMF.DebugValueSubstitutions) {
- MF.makeDebugValueSubstitution(std::make_pair(Sub.SrcInst, Sub.SrcOp),
- std::make_pair(Sub.DstInst, Sub.DstOp));
- }
-}
-
+void MIRParserImpl::setupDebugValueTracking(
+ MachineFunction &MF, PerFunctionMIParsingState &PFS,
+ const yaml::MachineFunction &YamlMF) {
+ // Compute the value of the "next instruction number" field.
+ unsigned MaxInstrNum = 0;
+ for (auto &MBB : MF)
+ for (auto &MI : MBB)
+ MaxInstrNum = std::max((unsigned)MI.peekDebugInstrNum(), MaxInstrNum);
+ MF.setDebugInstrNumberingCount(MaxInstrNum);
+
+ // Load any substitutions.
+ for (auto &Sub : YamlMF.DebugValueSubstitutions) {
+ MF.makeDebugValueSubstitution(std::make_pair(Sub.SrcInst, Sub.SrcOp),
+ std::make_pair(Sub.DstInst, Sub.DstOp));
+ }
+}
+
bool
MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
MachineFunction &MF) {
@@ -530,8 +530,8 @@ MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
if (initializeCallSiteInfo(PFS, YamlMF))
return false;
- setupDebugValueTracking(MF, PFS, YamlMF);
-
+ setupDebugValueTracking(MF, PFS, YamlMF);
+
MF.getSubtarget().mirFileLoaded(MF);
MF.verify();
@@ -659,12 +659,12 @@ bool MIRParserImpl::setupRegisterInfo(const PerFunctionMIParsingState &PFS,
// Compute MachineRegisterInfo::UsedPhysRegMask
for (const MachineBasicBlock &MBB : MF) {
- // Make sure MRI knows about registers clobbered by unwinder.
- const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
- if (MBB.isEHPad())
- if (auto *RegMask = TRI->getCustomEHPadPreservedMask(MF))
- MRI.addPhysRegsUsedFromRegMask(RegMask);
-
+ // Make sure MRI knows about registers clobbered by unwinder.
+ const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
+ if (MBB.isEHPad())
+ if (auto *RegMask = TRI->getCustomEHPadPreservedMask(MF))
+ MRI.addPhysRegsUsedFromRegMask(RegMask);
+
for (const MachineInstr &MI : MBB) {
for (const MachineOperand &MO : MI.operands()) {
if (!MO.isRegMask())
diff --git a/contrib/libs/llvm12/lib/CodeGen/MIRParser/ya.make b/contrib/libs/llvm12/lib/CodeGen/MIRParser/ya.make
index cb9e044925..aa8e6d8693 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MIRParser/ya.make
+++ b/contrib/libs/llvm12/lib/CodeGen/MIRParser/ya.make
@@ -12,15 +12,15 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/AsmParser
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/CodeGen
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/AsmParser
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/CodeGen
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/CodeGen/MIRPrinter.cpp b/contrib/libs/llvm12/lib/CodeGen/MIRPrinter.cpp
index 710b87cebc..eae174019b 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MIRPrinter.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MIRPrinter.cpp
@@ -220,10 +220,10 @@ void MIRPrinter::print(const MachineFunction &MF) {
convert(MST, YamlMF.FrameInfo, MF.getFrameInfo());
convertStackObjects(YamlMF, MF, MST);
convertCallSiteObjects(YamlMF, MF, MST);
- for (auto &Sub : MF.DebugValueSubstitutions)
- YamlMF.DebugValueSubstitutions.push_back({Sub.first.first, Sub.first.second,
- Sub.second.first,
- Sub.second.second});
+ for (auto &Sub : MF.DebugValueSubstitutions)
+ YamlMF.DebugValueSubstitutions.push_back({Sub.first.first, Sub.first.second,
+ Sub.second.first,
+ Sub.second.second});
if (const auto *ConstantPool = MF.getConstantPool())
convert(YamlMF, *ConstantPool);
if (const auto *JumpTableInfo = MF.getJumpTableInfo())
@@ -367,17 +367,17 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &YMF,
ModuleSlotTracker &MST) {
const MachineFrameInfo &MFI = MF.getFrameInfo();
const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
-
+
// Process fixed stack objects.
- assert(YMF.FixedStackObjects.empty());
- SmallVector<int, 32> FixedStackObjectsIdx;
- const int BeginIdx = MFI.getObjectIndexBegin();
- if (BeginIdx < 0)
- FixedStackObjectsIdx.reserve(-BeginIdx);
-
+ assert(YMF.FixedStackObjects.empty());
+ SmallVector<int, 32> FixedStackObjectsIdx;
+ const int BeginIdx = MFI.getObjectIndexBegin();
+ if (BeginIdx < 0)
+ FixedStackObjectsIdx.reserve(-BeginIdx);
+
unsigned ID = 0;
- for (int I = BeginIdx; I < 0; ++I, ++ID) {
- FixedStackObjectsIdx.push_back(-1); // Fill index for possible dead.
+ for (int I = BeginIdx; I < 0; ++I, ++ID) {
+ FixedStackObjectsIdx.push_back(-1); // Fill index for possible dead.
if (MFI.isDeadObjectIndex(I))
continue;
@@ -392,22 +392,22 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &YMF,
YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(I);
YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I);
YamlObject.IsAliased = MFI.isAliasedObjectIndex(I);
- // Save the ID' position in FixedStackObjects storage vector.
- FixedStackObjectsIdx[ID] = YMF.FixedStackObjects.size();
+ // Save the ID' position in FixedStackObjects storage vector.
+ FixedStackObjectsIdx[ID] = YMF.FixedStackObjects.size();
YMF.FixedStackObjects.push_back(YamlObject);
StackObjectOperandMapping.insert(
std::make_pair(I, FrameIndexOperand::createFixed(ID)));
}
// Process ordinary stack objects.
- assert(YMF.StackObjects.empty());
- SmallVector<unsigned, 32> StackObjectsIdx;
- const int EndIdx = MFI.getObjectIndexEnd();
- if (EndIdx > 0)
- StackObjectsIdx.reserve(EndIdx);
+ assert(YMF.StackObjects.empty());
+ SmallVector<unsigned, 32> StackObjectsIdx;
+ const int EndIdx = MFI.getObjectIndexEnd();
+ if (EndIdx > 0)
+ StackObjectsIdx.reserve(EndIdx);
ID = 0;
- for (int I = 0; I < EndIdx; ++I, ++ID) {
- StackObjectsIdx.push_back(-1); // Fill index for possible dead.
+ for (int I = 0; I < EndIdx; ++I, ++ID) {
+ StackObjectsIdx.push_back(-1); // Fill index for possible dead.
if (MFI.isDeadObjectIndex(I))
continue;
@@ -415,7 +415,7 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &YMF,
YamlObject.ID = ID;
if (const auto *Alloca = MFI.getObjectAllocation(I))
YamlObject.Name.Value = std::string(
- Alloca->hasName() ? Alloca->getName() : "");
+ Alloca->hasName() ? Alloca->getName() : "");
YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
? yaml::MachineStackObject::SpillSlot
: MFI.isVariableSizedObjectIndex(I)
@@ -426,42 +426,42 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &YMF,
YamlObject.Alignment = MFI.getObjectAlign(I);
YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(I);
- // Save the ID' position in StackObjects storage vector.
- StackObjectsIdx[ID] = YMF.StackObjects.size();
+ // Save the ID' position in StackObjects storage vector.
+ StackObjectsIdx[ID] = YMF.StackObjects.size();
YMF.StackObjects.push_back(YamlObject);
StackObjectOperandMapping.insert(std::make_pair(
I, FrameIndexOperand::create(YamlObject.Name.Value, ID)));
}
for (const auto &CSInfo : MFI.getCalleeSavedInfo()) {
- const int FrameIdx = CSInfo.getFrameIdx();
- if (!CSInfo.isSpilledToReg() && MFI.isDeadObjectIndex(FrameIdx))
+ const int FrameIdx = CSInfo.getFrameIdx();
+ if (!CSInfo.isSpilledToReg() && MFI.isDeadObjectIndex(FrameIdx))
continue;
yaml::StringValue Reg;
printRegMIR(CSInfo.getReg(), Reg, TRI);
if (!CSInfo.isSpilledToReg()) {
- assert(FrameIdx >= MFI.getObjectIndexBegin() &&
- FrameIdx < MFI.getObjectIndexEnd() &&
+ assert(FrameIdx >= MFI.getObjectIndexBegin() &&
+ FrameIdx < MFI.getObjectIndexEnd() &&
"Invalid stack object index");
- if (FrameIdx < 0) { // Negative index means fixed objects.
- auto &Object =
- YMF.FixedStackObjects
- [FixedStackObjectsIdx[FrameIdx + MFI.getNumFixedObjects()]];
- Object.CalleeSavedRegister = Reg;
- Object.CalleeSavedRestored = CSInfo.isRestored();
+ if (FrameIdx < 0) { // Negative index means fixed objects.
+ auto &Object =
+ YMF.FixedStackObjects
+ [FixedStackObjectsIdx[FrameIdx + MFI.getNumFixedObjects()]];
+ Object.CalleeSavedRegister = Reg;
+ Object.CalleeSavedRestored = CSInfo.isRestored();
} else {
- auto &Object = YMF.StackObjects[StackObjectsIdx[FrameIdx]];
- Object.CalleeSavedRegister = Reg;
- Object.CalleeSavedRestored = CSInfo.isRestored();
+ auto &Object = YMF.StackObjects[StackObjectsIdx[FrameIdx]];
+ Object.CalleeSavedRegister = Reg;
+ Object.CalleeSavedRestored = CSInfo.isRestored();
}
}
}
for (unsigned I = 0, E = MFI.getLocalFrameObjectCount(); I < E; ++I) {
auto LocalObject = MFI.getLocalFrameObjectMap(I);
- assert(LocalObject.first >= 0 && "Expected a locally mapped stack object");
- YMF.StackObjects[StackObjectsIdx[LocalObject.first]].LocalOffset =
- LocalObject.second;
+ assert(LocalObject.first >= 0 && "Expected a locally mapped stack object");
+ YMF.StackObjects[StackObjectsIdx[LocalObject.first]].LocalOffset =
+ LocalObject.second;
}
// Print the stack object references in the frame information class after
@@ -475,16 +475,16 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &YMF,
// Print the debug variable information.
for (const MachineFunction::VariableDbgInfo &DebugVar :
MF.getVariableDbgInfo()) {
- assert(DebugVar.Slot >= MFI.getObjectIndexBegin() &&
- DebugVar.Slot < MFI.getObjectIndexEnd() &&
+ assert(DebugVar.Slot >= MFI.getObjectIndexBegin() &&
+ DebugVar.Slot < MFI.getObjectIndexEnd() &&
"Invalid stack object index");
- if (DebugVar.Slot < 0) { // Negative index means fixed objects.
- auto &Object =
- YMF.FixedStackObjects[FixedStackObjectsIdx[DebugVar.Slot +
- MFI.getNumFixedObjects()]];
+ if (DebugVar.Slot < 0) { // Negative index means fixed objects.
+ auto &Object =
+ YMF.FixedStackObjects[FixedStackObjectsIdx[DebugVar.Slot +
+ MFI.getNumFixedObjects()]];
printStackObjectDbgInfo(DebugVar, Object, MST);
} else {
- auto &Object = YMF.StackObjects[StackObjectsIdx[DebugVar.Slot]];
+ auto &Object = YMF.StackObjects[StackObjectsIdx[DebugVar.Slot]];
printStackObjectDbgInfo(DebugVar, Object, MST);
}
}
@@ -630,10 +630,10 @@ bool MIPrinter::canPredictSuccessors(const MachineBasicBlock &MBB) const {
void MIPrinter::print(const MachineBasicBlock &MBB) {
assert(MBB.getNumber() >= 0 && "Invalid MBB number");
- MBB.printName(OS,
- MachineBasicBlock::PrintNameIr |
- MachineBasicBlock::PrintNameAttributes,
- &MST);
+ MBB.printName(OS,
+ MachineBasicBlock::PrintNameIr |
+ MachineBasicBlock::PrintNameAttributes,
+ &MST);
OS << ":\n";
bool HasLineAttributes = false;
@@ -792,13 +792,13 @@ void MIPrinter::print(const MachineInstr &MI) {
NeedComma = true;
}
- if (auto Num = MI.peekDebugInstrNum()) {
- if (NeedComma)
- OS << ',';
- OS << " debug-instr-number " << Num;
- NeedComma = true;
- }
-
+ if (auto Num = MI.peekDebugInstrNum()) {
+ if (NeedComma)
+ OS << ',';
+ OS << " debug-instr-number " << Num;
+ NeedComma = true;
+ }
+
if (PrintLocations) {
if (const DebugLoc &DL = MI.getDebugLoc()) {
if (NeedComma)
diff --git a/contrib/libs/llvm12/lib/CodeGen/MIRVRegNamerUtils.cpp b/contrib/libs/llvm12/lib/CodeGen/MIRVRegNamerUtils.cpp
index 98162305e2..3d4f66f311 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MIRVRegNamerUtils.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MIRVRegNamerUtils.cpp
@@ -8,7 +8,7 @@
#include "MIRVRegNamerUtils.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/MachineStableHash.h"
+#include "llvm/CodeGen/MachineStableHash.h"
#include "llvm/IR/Constants.h"
#include "llvm/Support/Debug.h"
@@ -16,11 +16,11 @@ using namespace llvm;
#define DEBUG_TYPE "mir-vregnamer-utils"
-static cl::opt<bool>
- UseStableNamerHash("mir-vreg-namer-use-stable-hash", cl::init(false),
- cl::Hidden,
- cl::desc("Use Stable Hashing for MIR VReg Renaming"));
-
+static cl::opt<bool>
+ UseStableNamerHash("mir-vreg-namer-use-stable-hash", cl::init(false),
+ cl::Hidden,
+ cl::desc("Use Stable Hashing for MIR VReg Renaming"));
+
using VRegRenameMap = std::map<unsigned, unsigned>;
bool VRegRenamer::doVRegRenaming(const VRegRenameMap &VRM) {
@@ -58,14 +58,14 @@ std::string VRegRenamer::getInstructionOpcodeHash(MachineInstr &MI) {
std::string S;
raw_string_ostream OS(S);
- if (UseStableNamerHash) {
- auto Hash = stableHashValue(MI, /* HashVRegs */ true,
- /* HashConstantPoolIndices */ true,
- /* HashMemOperands */ true);
- assert(Hash && "Expected non-zero Hash");
- return std::to_string(Hash).substr(0, 5);
- }
-
+ if (UseStableNamerHash) {
+ auto Hash = stableHashValue(MI, /* HashVRegs */ true,
+ /* HashConstantPoolIndices */ true,
+ /* HashMemOperands */ true);
+ assert(Hash && "Expected non-zero Hash");
+ return std::to_string(Hash).substr(0, 5);
+ }
+
// Gets a hashable artifact from a given MachineOperand (ie an unsigned).
auto GetHashableMO = [this](const MachineOperand &MO) -> unsigned {
switch (MO.getType()) {
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineBasicBlock.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineBasicBlock.cpp
index 5b96150b8e..b4187af029 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineBasicBlock.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineBasicBlock.cpp
@@ -61,24 +61,24 @@ MCSymbol *MachineBasicBlock::getSymbol() const {
const MachineFunction *MF = getParent();
MCContext &Ctx = MF->getContext();
- // We emit a non-temporary symbol -- with a descriptive name -- if it begins
- // a section (with basic block sections). Otherwise we fall back to use temp
- // label.
- if (MF->hasBBSections() && isBeginSection()) {
+ // We emit a non-temporary symbol -- with a descriptive name -- if it begins
+ // a section (with basic block sections). Otherwise we fall back to use temp
+ // label.
+ if (MF->hasBBSections() && isBeginSection()) {
SmallString<5> Suffix;
if (SectionID == MBBSectionID::ColdSectionID) {
Suffix += ".cold";
} else if (SectionID == MBBSectionID::ExceptionSectionID) {
Suffix += ".eh";
} else {
- // For symbols that represent basic block sections, we add ".__part." to
- // allow tools like symbolizers to know that this represents a part of
- // the original function.
- Suffix = (Suffix + Twine(".__part.") + Twine(SectionID.Number)).str();
+ // For symbols that represent basic block sections, we add ".__part." to
+ // allow tools like symbolizers to know that this represents a part of
+ // the original function.
+ Suffix = (Suffix + Twine(".__part.") + Twine(SectionID.Number)).str();
}
CachedMCSymbol = Ctx.getOrCreateSymbol(MF->getName() + Suffix);
} else {
- const StringRef Prefix = Ctx.getAsmInfo()->getPrivateLabelPrefix();
+ const StringRef Prefix = Ctx.getAsmInfo()->getPrivateLabelPrefix();
CachedMCSymbol = Ctx.getOrCreateSymbol(Twine(Prefix) + "BB" +
Twine(MF->getFunctionNumber()) +
"_" + Twine(getNumber()));
@@ -87,17 +87,17 @@ MCSymbol *MachineBasicBlock::getSymbol() const {
return CachedMCSymbol;
}
-MCSymbol *MachineBasicBlock::getEndSymbol() const {
- if (!CachedEndMCSymbol) {
- const MachineFunction *MF = getParent();
- MCContext &Ctx = MF->getContext();
- auto Prefix = Ctx.getAsmInfo()->getPrivateLabelPrefix();
- CachedEndMCSymbol = Ctx.getOrCreateSymbol(Twine(Prefix) + "BB_END" +
- Twine(MF->getFunctionNumber()) +
- "_" + Twine(getNumber()));
- }
- return CachedEndMCSymbol;
-}
+MCSymbol *MachineBasicBlock::getEndSymbol() const {
+ if (!CachedEndMCSymbol) {
+ const MachineFunction *MF = getParent();
+ MCContext &Ctx = MF->getContext();
+ auto Prefix = Ctx.getAsmInfo()->getPrivateLabelPrefix();
+ CachedEndMCSymbol = Ctx.getOrCreateSymbol(Twine(Prefix) + "BB_END" +
+ Twine(MF->getFunctionNumber()) +
+ "_" + Twine(getNumber()));
+ }
+ return CachedEndMCSymbol;
+}
raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineBasicBlock &MBB) {
MBB.print(OS);
@@ -269,10 +269,10 @@ bool MachineBasicBlock::hasEHPadSuccessor() const {
return false;
}
-bool MachineBasicBlock::isEntryBlock() const {
- return getParent()->begin() == getIterator();
-}
-
+bool MachineBasicBlock::isEntryBlock() const {
+ return getParent()->begin() == getIterator();
+}
+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void MachineBasicBlock::dump() const {
print(dbgs());
@@ -340,7 +340,7 @@ void MachineBasicBlock::print(raw_ostream &OS, ModuleSlotTracker &MST,
if (Indexes && PrintSlotIndexes)
OS << Indexes->getMBBStartIdx(this) << '\t';
- printName(OS, PrintNameIr | PrintNameAttributes, &MST);
+ printName(OS, PrintNameIr | PrintNameAttributes, &MST);
OS << ":\n";
const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
@@ -353,9 +353,9 @@ void MachineBasicBlock::print(raw_ostream &OS, ModuleSlotTracker &MST,
if (Indexes) OS << '\t';
// Don't indent(2), align with previous line attributes.
OS << "; predecessors: ";
- ListSeparator LS;
- for (auto *Pred : predecessors())
- OS << LS << printMBBReference(*Pred);
+ ListSeparator LS;
+ for (auto *Pred : predecessors())
+ OS << LS << printMBBReference(*Pred);
OS << '\n';
HasLineAttributes = true;
}
@@ -364,9 +364,9 @@ void MachineBasicBlock::print(raw_ostream &OS, ModuleSlotTracker &MST,
if (Indexes) OS << '\t';
// Print the successors
OS.indent(2) << "successors: ";
- ListSeparator LS;
+ ListSeparator LS;
for (auto I = succ_begin(), E = succ_end(); I != E; ++I) {
- OS << LS << printMBBReference(**I);
+ OS << LS << printMBBReference(**I);
if (!Probs.empty())
OS << '('
<< format("0x%08" PRIx32, getSuccProbability(I).getNumerator())
@@ -375,10 +375,10 @@ void MachineBasicBlock::print(raw_ostream &OS, ModuleSlotTracker &MST,
if (!Probs.empty() && IsStandalone) {
// Print human readable probabilities as comments.
OS << "; ";
- ListSeparator LS;
+ ListSeparator LS;
for (auto I = succ_begin(), E = succ_end(); I != E; ++I) {
const BranchProbability &BP = getSuccProbability(I);
- OS << LS << printMBBReference(**I) << '('
+ OS << LS << printMBBReference(**I) << '('
<< format("%.2f%%",
rint(((double)BP.getNumerator() / BP.getDenominator()) *
100.0 * 100.0) /
@@ -395,9 +395,9 @@ void MachineBasicBlock::print(raw_ostream &OS, ModuleSlotTracker &MST,
if (Indexes) OS << '\t';
OS.indent(2) << "liveins: ";
- ListSeparator LS;
+ ListSeparator LS;
for (const auto &LI : liveins()) {
- OS << LS << printReg(LI.PhysReg, TRI);
+ OS << LS << printReg(LI.PhysReg, TRI);
if (!LI.LaneMask.all())
OS << ":0x" << PrintLaneMask(LI.LaneMask);
}
@@ -441,99 +441,99 @@ void MachineBasicBlock::print(raw_ostream &OS, ModuleSlotTracker &MST,
}
}
-/// Print the basic block's name as:
-///
-/// bb.{number}[.{ir-name}] [(attributes...)]
-///
-/// The {ir-name} is only printed when the \ref PrintNameIr flag is passed
-/// (which is the default). If the IR block has no name, it is identified
-/// numerically using the attribute syntax as "(%ir-block.{ir-slot})".
-///
-/// When the \ref PrintNameAttributes flag is passed, additional attributes
-/// of the block are printed when set.
-///
-/// \param printNameFlags Combination of \ref PrintNameFlag flags indicating
-/// the parts to print.
-/// \param moduleSlotTracker Optional ModuleSlotTracker. This method will
-/// incorporate its own tracker when necessary to
-/// determine the block's IR name.
-void MachineBasicBlock::printName(raw_ostream &os, unsigned printNameFlags,
- ModuleSlotTracker *moduleSlotTracker) const {
- os << "bb." << getNumber();
- bool hasAttributes = false;
-
- if (printNameFlags & PrintNameIr) {
- if (const auto *bb = getBasicBlock()) {
- if (bb->hasName()) {
- os << '.' << bb->getName();
- } else {
- hasAttributes = true;
- os << " (";
-
- int slot = -1;
-
- if (moduleSlotTracker) {
- slot = moduleSlotTracker->getLocalSlot(bb);
- } else if (bb->getParent()) {
- ModuleSlotTracker tmpTracker(bb->getModule(), false);
- tmpTracker.incorporateFunction(*bb->getParent());
- slot = tmpTracker.getLocalSlot(bb);
- }
-
- if (slot == -1)
- os << "<ir-block badref>";
- else
- os << (Twine("%ir-block.") + Twine(slot)).str();
- }
- }
- }
-
- if (printNameFlags & PrintNameAttributes) {
- if (hasAddressTaken()) {
- os << (hasAttributes ? ", " : " (");
- os << "address-taken";
- hasAttributes = true;
- }
- if (isEHPad()) {
- os << (hasAttributes ? ", " : " (");
- os << "landing-pad";
- hasAttributes = true;
- }
- if (isEHFuncletEntry()) {
- os << (hasAttributes ? ", " : " (");
- os << "ehfunclet-entry";
- hasAttributes = true;
- }
- if (getAlignment() != Align(1)) {
- os << (hasAttributes ? ", " : " (");
- os << "align " << getAlignment().value();
- hasAttributes = true;
- }
- if (getSectionID() != MBBSectionID(0)) {
- os << (hasAttributes ? ", " : " (");
- os << "bbsections ";
- switch (getSectionID().Type) {
- case MBBSectionID::SectionType::Exception:
- os << "Exception";
- break;
- case MBBSectionID::SectionType::Cold:
- os << "Cold";
- break;
- default:
- os << getSectionID().Number;
- }
- hasAttributes = true;
- }
- }
-
- if (hasAttributes)
- os << ')';
-}
-
+/// Print the basic block's name as:
+///
+/// bb.{number}[.{ir-name}] [(attributes...)]
+///
+/// The {ir-name} is only printed when the \ref PrintNameIr flag is passed
+/// (which is the default). If the IR block has no name, it is identified
+/// numerically using the attribute syntax as "(%ir-block.{ir-slot})".
+///
+/// When the \ref PrintNameAttributes flag is passed, additional attributes
+/// of the block are printed when set.
+///
+/// \param printNameFlags Combination of \ref PrintNameFlag flags indicating
+/// the parts to print.
+/// \param moduleSlotTracker Optional ModuleSlotTracker. This method will
+/// incorporate its own tracker when necessary to
+/// determine the block's IR name.
+void MachineBasicBlock::printName(raw_ostream &os, unsigned printNameFlags,
+ ModuleSlotTracker *moduleSlotTracker) const {
+ os << "bb." << getNumber();
+ bool hasAttributes = false;
+
+ if (printNameFlags & PrintNameIr) {
+ if (const auto *bb = getBasicBlock()) {
+ if (bb->hasName()) {
+ os << '.' << bb->getName();
+ } else {
+ hasAttributes = true;
+ os << " (";
+
+ int slot = -1;
+
+ if (moduleSlotTracker) {
+ slot = moduleSlotTracker->getLocalSlot(bb);
+ } else if (bb->getParent()) {
+ ModuleSlotTracker tmpTracker(bb->getModule(), false);
+ tmpTracker.incorporateFunction(*bb->getParent());
+ slot = tmpTracker.getLocalSlot(bb);
+ }
+
+ if (slot == -1)
+ os << "<ir-block badref>";
+ else
+ os << (Twine("%ir-block.") + Twine(slot)).str();
+ }
+ }
+ }
+
+ if (printNameFlags & PrintNameAttributes) {
+ if (hasAddressTaken()) {
+ os << (hasAttributes ? ", " : " (");
+ os << "address-taken";
+ hasAttributes = true;
+ }
+ if (isEHPad()) {
+ os << (hasAttributes ? ", " : " (");
+ os << "landing-pad";
+ hasAttributes = true;
+ }
+ if (isEHFuncletEntry()) {
+ os << (hasAttributes ? ", " : " (");
+ os << "ehfunclet-entry";
+ hasAttributes = true;
+ }
+ if (getAlignment() != Align(1)) {
+ os << (hasAttributes ? ", " : " (");
+ os << "align " << getAlignment().value();
+ hasAttributes = true;
+ }
+ if (getSectionID() != MBBSectionID(0)) {
+ os << (hasAttributes ? ", " : " (");
+ os << "bbsections ";
+ switch (getSectionID().Type) {
+ case MBBSectionID::SectionType::Exception:
+ os << "Exception";
+ break;
+ case MBBSectionID::SectionType::Cold:
+ os << "Cold";
+ break;
+ default:
+ os << getSectionID().Number;
+ }
+ hasAttributes = true;
+ }
+ }
+
+ if (hasAttributes)
+ os << ')';
+}
+
void MachineBasicBlock::printAsOperand(raw_ostream &OS,
bool /*PrintType*/) const {
- OS << '%';
- printName(OS, 0);
+ OS << '%';
+ printName(OS, 0);
}
void MachineBasicBlock::removeLiveIn(MCPhysReg Reg, LaneBitmask LaneMask) {
@@ -583,7 +583,7 @@ void MachineBasicBlock::sortUniqueLiveIns() {
Register
MachineBasicBlock::addLiveIn(MCRegister PhysReg, const TargetRegisterClass *RC) {
assert(getParent() && "MBB must be inserted in function");
- assert(Register::isPhysicalRegister(PhysReg) && "Expected physreg");
+ assert(Register::isPhysicalRegister(PhysReg) && "Expected physreg");
assert(RC && "Register class is required");
assert((isEHPad() || this == &getParent()->front()) &&
"Only the entry block and landing pads can have physreg live ins");
@@ -749,7 +749,7 @@ void MachineBasicBlock::splitSuccessor(MachineBasicBlock *Old,
bool NormalizeSuccProbs) {
succ_iterator OldI = llvm::find(successors(), Old);
assert(OldI != succ_end() && "Old is not a successor of this block!");
- assert(!llvm::is_contained(successors(), New) &&
+ assert(!llvm::is_contained(successors(), New) &&
"New is already a successor of this block!");
// Add a new successor with equal probability as the original one. Note
@@ -828,7 +828,7 @@ void MachineBasicBlock::replaceSuccessor(MachineBasicBlock *Old,
void MachineBasicBlock::copySuccessor(MachineBasicBlock *Orig,
succ_iterator I) {
- if (!Orig->Probs.empty())
+ if (!Orig->Probs.empty())
addSuccessor(*I, Orig->getSuccProbability(I));
else
addSuccessorWithoutProb(*I);
@@ -944,47 +944,47 @@ bool MachineBasicBlock::canFallThrough() {
return getFallThrough() != nullptr;
}
-MachineBasicBlock *MachineBasicBlock::splitAt(MachineInstr &MI,
- bool UpdateLiveIns,
- LiveIntervals *LIS) {
- MachineBasicBlock::iterator SplitPoint(&MI);
- ++SplitPoint;
-
- if (SplitPoint == end()) {
- // Don't bother with a new block.
- return this;
- }
-
- MachineFunction *MF = getParent();
-
- LivePhysRegs LiveRegs;
- if (UpdateLiveIns) {
- // Make sure we add any physregs we define in the block as liveins to the
- // new block.
- MachineBasicBlock::iterator Prev(&MI);
- LiveRegs.init(*MF->getSubtarget().getRegisterInfo());
- LiveRegs.addLiveOuts(*this);
- for (auto I = rbegin(), E = Prev.getReverse(); I != E; ++I)
- LiveRegs.stepBackward(*I);
- }
-
- MachineBasicBlock *SplitBB = MF->CreateMachineBasicBlock(getBasicBlock());
-
- MF->insert(++MachineFunction::iterator(this), SplitBB);
- SplitBB->splice(SplitBB->begin(), this, SplitPoint, end());
-
- SplitBB->transferSuccessorsAndUpdatePHIs(this);
- addSuccessor(SplitBB);
-
- if (UpdateLiveIns)
- addLiveIns(*SplitBB, LiveRegs);
-
- if (LIS)
- LIS->insertMBBInMaps(SplitBB);
-
- return SplitBB;
-}
-
+MachineBasicBlock *MachineBasicBlock::splitAt(MachineInstr &MI,
+ bool UpdateLiveIns,
+ LiveIntervals *LIS) {
+ MachineBasicBlock::iterator SplitPoint(&MI);
+ ++SplitPoint;
+
+ if (SplitPoint == end()) {
+ // Don't bother with a new block.
+ return this;
+ }
+
+ MachineFunction *MF = getParent();
+
+ LivePhysRegs LiveRegs;
+ if (UpdateLiveIns) {
+ // Make sure we add any physregs we define in the block as liveins to the
+ // new block.
+ MachineBasicBlock::iterator Prev(&MI);
+ LiveRegs.init(*MF->getSubtarget().getRegisterInfo());
+ LiveRegs.addLiveOuts(*this);
+ for (auto I = rbegin(), E = Prev.getReverse(); I != E; ++I)
+ LiveRegs.stepBackward(*I);
+ }
+
+ MachineBasicBlock *SplitBB = MF->CreateMachineBasicBlock(getBasicBlock());
+
+ MF->insert(++MachineFunction::iterator(this), SplitBB);
+ SplitBB->splice(SplitBB->begin(), this, SplitPoint, end());
+
+ SplitBB->transferSuccessorsAndUpdatePHIs(this);
+ addSuccessor(SplitBB);
+
+ if (UpdateLiveIns)
+ addLiveIns(*SplitBB, LiveRegs);
+
+ if (LIS)
+ LIS->insertMBBInMaps(SplitBB);
+
+ return SplitBB;
+}
+
MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge(
MachineBasicBlock *Succ, Pass &P,
std::vector<SparseBitVector<>> *LiveInSets) {
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineBlockFrequencyInfo.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineBlockFrequencyInfo.cpp
index d375f82024..54e0a14e05 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineBlockFrequencyInfo.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineBlockFrequencyInfo.cpp
@@ -241,21 +241,21 @@ MachineBlockFrequencyInfo::getProfileCountFromFreq(uint64_t Freq) const {
return MBFI ? MBFI->getProfileCountFromFreq(F, Freq) : None;
}
-bool MachineBlockFrequencyInfo::isIrrLoopHeader(
- const MachineBasicBlock *MBB) const {
+bool MachineBlockFrequencyInfo::isIrrLoopHeader(
+ const MachineBasicBlock *MBB) const {
assert(MBFI && "Expected analysis to be available");
return MBFI->isIrrLoopHeader(MBB);
}
-void MachineBlockFrequencyInfo::onEdgeSplit(
- const MachineBasicBlock &NewPredecessor,
- const MachineBasicBlock &NewSuccessor,
- const MachineBranchProbabilityInfo &MBPI) {
+void MachineBlockFrequencyInfo::onEdgeSplit(
+ const MachineBasicBlock &NewPredecessor,
+ const MachineBasicBlock &NewSuccessor,
+ const MachineBranchProbabilityInfo &MBPI) {
assert(MBFI && "Expected analysis to be available");
- auto NewSuccFreq = MBFI->getBlockFreq(&NewPredecessor) *
- MBPI.getEdgeProbability(&NewPredecessor, &NewSuccessor);
-
- MBFI->setBlockFreq(&NewSuccessor, NewSuccFreq.getFrequency());
+ auto NewSuccFreq = MBFI->getBlockFreq(&NewPredecessor) *
+ MBPI.getEdgeProbability(&NewPredecessor, &NewSuccessor);
+
+ MBFI->setBlockFreq(&NewSuccessor, NewSuccFreq.getFrequency());
}
const MachineFunction *MachineBlockFrequencyInfo::getFunction() const {
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineBlockPlacement.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineBlockPlacement.cpp
index e075b13ed2..048baa460e 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineBlockPlacement.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineBlockPlacement.cpp
@@ -177,14 +177,14 @@ static cl::opt<unsigned> TailDupPlacementPenalty(
cl::init(2),
cl::Hidden);
-// Heuristic for tail duplication if profile count is used in cost model.
-static cl::opt<unsigned> TailDupProfilePercentThreshold(
- "tail-dup-profile-percent-threshold",
- cl::desc("If profile count information is used in tail duplication cost "
- "model, the gained fall through number from tail duplication "
- "should be at least this percent of hot count."),
- cl::init(50), cl::Hidden);
-
+// Heuristic for tail duplication if profile count is used in cost model.
+static cl::opt<unsigned> TailDupProfilePercentThreshold(
+ "tail-dup-profile-percent-threshold",
+ cl::desc("If profile count information is used in tail duplication cost "
+ "model, the gained fall through number from tail duplication "
+ "should be at least this percent of hot count."),
+ cl::init(50), cl::Hidden);
+
// Heuristic for triangle chains.
static cl::opt<unsigned> TriangleChainCount(
"triangle-chain-count",
@@ -385,10 +385,10 @@ class MachineBlockPlacement : public MachineFunctionPass {
/// Partial tail duplication threshold.
BlockFrequency DupThreshold;
- /// True: use block profile count to compute tail duplication cost.
- /// False: use block frequency to compute tail duplication cost.
- bool UseProfileCount;
-
+ /// True: use block profile count to compute tail duplication cost.
+ /// False: use block frequency to compute tail duplication cost.
+ bool UseProfileCount;
+
/// Allocator and owner of BlockChain structures.
///
/// We build BlockChains lazily while processing the loop structure of
@@ -414,19 +414,19 @@ class MachineBlockPlacement : public MachineFunctionPass {
SmallPtrSet<MachineBasicBlock *, 4> BlocksWithUnanalyzableExits;
#endif
- /// Get block profile count or frequency according to UseProfileCount.
- /// The return value is used to model tail duplication cost.
- BlockFrequency getBlockCountOrFrequency(const MachineBasicBlock *BB) {
- if (UseProfileCount) {
- auto Count = MBFI->getBlockProfileCount(BB);
- if (Count)
- return *Count;
- else
- return 0;
- } else
- return MBFI->getBlockFreq(BB);
- }
-
+ /// Get block profile count or frequency according to UseProfileCount.
+ /// The return value is used to model tail duplication cost.
+ BlockFrequency getBlockCountOrFrequency(const MachineBasicBlock *BB) {
+ if (UseProfileCount) {
+ auto Count = MBFI->getBlockProfileCount(BB);
+ if (Count)
+ return *Count;
+ else
+ return 0;
+ } else
+ return MBFI->getBlockFreq(BB);
+ }
+
/// Scale the DupThreshold according to basic block size.
BlockFrequency scaleThreshold(MachineBasicBlock *BB);
void initDupThreshold();
@@ -1673,9 +1673,9 @@ MachineBasicBlock *MachineBlockPlacement::selectBestCandidateBlock(
// worklist of already placed entries.
// FIXME: If this shows up on profiles, it could be folded (at the cost of
// some code complexity) into the loop below.
- llvm::erase_if(WorkList, [&](MachineBasicBlock *BB) {
- return BlockToChain.lookup(BB) == &Chain;
- });
+ llvm::erase_if(WorkList, [&](MachineBasicBlock *BB) {
+ return BlockToChain.lookup(BB) == &Chain;
+ });
if (WorkList.empty())
return nullptr;
@@ -2306,10 +2306,10 @@ void MachineBlockPlacement::rotateLoop(BlockChain &LoopChain,
if (Bottom == ExitingBB)
return;
- // The entry block should always be the first BB in a function.
- if (Top->isEntryBlock())
- return;
-
+ // The entry block should always be the first BB in a function.
+ if (Top->isEntryBlock())
+ return;
+
bool ViableTopFallthrough = hasViableTopFallthrough(Top, LoopBlockSet);
// If the header has viable fallthrough, check whether the current loop
@@ -2384,12 +2384,12 @@ void MachineBlockPlacement::rotateLoopWithProfile(
BlockChain &LoopChain, const MachineLoop &L,
const BlockFilterSet &LoopBlockSet) {
auto RotationPos = LoopChain.end();
- MachineBasicBlock *ChainHeaderBB = *LoopChain.begin();
+ MachineBasicBlock *ChainHeaderBB = *LoopChain.begin();
+
+ // The entry block should always be the first BB in a function.
+ if (ChainHeaderBB->isEntryBlock())
+ return;
- // The entry block should always be the first BB in a function.
- if (ChainHeaderBB->isEntryBlock())
- return;
-
BlockFrequency SmallestRotationCost = BlockFrequency::getMaxFrequency();
// A utility lambda that scales up a block frequency by dividing it by a
@@ -2543,14 +2543,14 @@ MachineBlockPlacement::collectLoopBlockSet(const MachineLoop &L) {
MBPI->getEdgeProbability(LoopPred, L.getHeader());
for (MachineBasicBlock *LoopBB : L.getBlocks()) {
- if (LoopBlockSet.count(LoopBB))
- continue;
+ if (LoopBlockSet.count(LoopBB))
+ continue;
auto Freq = MBFI->getBlockFreq(LoopBB).getFrequency();
if (Freq == 0 || LoopFreq.getFrequency() / Freq > LoopToColdBlockRatio)
continue;
- BlockChain *Chain = BlockToChain[LoopBB];
- for (MachineBasicBlock *ChainBB : *Chain)
- LoopBlockSet.insert(ChainBB);
+ BlockChain *Chain = BlockToChain[LoopBB];
+ for (MachineBasicBlock *ChainBB : *Chain)
+ LoopBlockSet.insert(ChainBB);
}
} else
LoopBlockSet.insert(L.block_begin(), L.block_end());
@@ -3042,7 +3042,7 @@ bool MachineBlockPlacement::maybeTailDuplicateBlock(
SmallVectorImpl<MachineBasicBlock *> &RemoveList = BlockWorkList;
if (RemBB->isEHPad())
RemoveList = EHPadWorkList;
- llvm::erase_value(RemoveList, RemBB);
+ llvm::erase_value(RemoveList, RemBB);
}
// Handle the filter set
@@ -3146,7 +3146,7 @@ bool MachineBlockPlacement::isBestSuccessor(MachineBasicBlock *BB,
// Compute the number of reduced taken branches if Pred falls through to BB
// instead of another successor. Then compare it with threshold.
- BlockFrequency PredFreq = getBlockCountOrFrequency(Pred);
+ BlockFrequency PredFreq = getBlockCountOrFrequency(Pred);
BlockFrequency Gain = PredFreq * (BBProb - BestProb);
return Gain > scaleThreshold(BB);
}
@@ -3160,8 +3160,8 @@ void MachineBlockPlacement::findDuplicateCandidates(
MachineBasicBlock *Fallthrough = nullptr;
BranchProbability DefaultBranchProb = BranchProbability::getZero();
BlockFrequency BBDupThreshold(scaleThreshold(BB));
- SmallVector<MachineBasicBlock *, 8> Preds(BB->predecessors());
- SmallVector<MachineBasicBlock *, 8> Succs(BB->successors());
+ SmallVector<MachineBasicBlock *, 8> Preds(BB->predecessors());
+ SmallVector<MachineBasicBlock *, 8> Succs(BB->successors());
// Sort for highest frequency.
auto CmpSucc = [&](MachineBasicBlock *A, MachineBasicBlock *B) {
@@ -3220,7 +3220,7 @@ void MachineBlockPlacement::findDuplicateCandidates(
// it. But it can beneficially fall through to BB, and duplicate BB into other
// predecessors.
for (MachineBasicBlock *Pred : Preds) {
- BlockFrequency PredFreq = getBlockCountOrFrequency(Pred);
+ BlockFrequency PredFreq = getBlockCountOrFrequency(Pred);
if (!TailDup.canTailDuplicate(BB, Pred)) {
// BB can't be duplicated into Pred, but it is possible to be layout
@@ -3269,15 +3269,15 @@ void MachineBlockPlacement::initDupThreshold() {
if (!F->getFunction().hasProfileData())
return;
- // We prefer to use prifile count.
- uint64_t HotThreshold = PSI->getOrCompHotCountThreshold();
- if (HotThreshold != UINT64_MAX) {
- UseProfileCount = true;
- DupThreshold = HotThreshold * TailDupProfilePercentThreshold / 100;
- return;
- }
-
- // Profile count is not available, we can use block frequency instead.
+ // We prefer to use prifile count.
+ uint64_t HotThreshold = PSI->getOrCompHotCountThreshold();
+ if (HotThreshold != UINT64_MAX) {
+ UseProfileCount = true;
+ DupThreshold = HotThreshold * TailDupProfilePercentThreshold / 100;
+ return;
+ }
+
+ // Profile count is not available, we can use block frequency instead.
BlockFrequency MaxFreq = 0;
for (MachineBasicBlock &MBB : *F) {
BlockFrequency Freq = MBFI->getBlockFreq(&MBB);
@@ -3287,7 +3287,7 @@ void MachineBlockPlacement::initDupThreshold() {
BranchProbability ThresholdProb(TailDupPlacementPenalty, 100);
DupThreshold = MaxFreq * ThresholdProb;
- UseProfileCount = false;
+ UseProfileCount = false;
}
bool MachineBlockPlacement::runOnMachineFunction(MachineFunction &MF) {
@@ -3360,8 +3360,8 @@ bool MachineBlockPlacement::runOnMachineFunction(MachineFunction &MF) {
// No tail merging opportunities if the block number is less than four.
if (MF.size() > 3 && EnableTailMerge) {
unsigned TailMergeSize = TailDupSize + 1;
- BranchFolder BF(/*DefaultEnableTailMerge=*/true, /*CommonHoist=*/false,
- *MBFI, *MBPI, PSI, TailMergeSize);
+ BranchFolder BF(/*DefaultEnableTailMerge=*/true, /*CommonHoist=*/false,
+ *MBFI, *MBPI, PSI, TailMergeSize);
if (BF.OptimizeFunction(MF, TII, MF.getSubtarget().getRegisterInfo(), MLI,
/*AfterPlacement=*/true)) {
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineCSE.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineCSE.cpp
index 4778c2aeb8..199fe2dc64 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineCSE.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineCSE.cpp
@@ -35,7 +35,7 @@
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/InitializePasses.h"
#include "llvm/MC/MCInstrDesc.h"
-#include "llvm/MC/MCRegister.h"
+#include "llvm/MC/MCRegister.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Pass.h"
#include "llvm/Support/Allocator.h"
@@ -116,18 +116,18 @@ namespace {
bool PerformTrivialCopyPropagation(MachineInstr *MI,
MachineBasicBlock *MBB);
- bool isPhysDefTriviallyDead(MCRegister Reg,
+ bool isPhysDefTriviallyDead(MCRegister Reg,
MachineBasicBlock::const_iterator I,
MachineBasicBlock::const_iterator E) const;
bool hasLivePhysRegDefUses(const MachineInstr *MI,
const MachineBasicBlock *MBB,
- SmallSet<MCRegister, 8> &PhysRefs,
+ SmallSet<MCRegister, 8> &PhysRefs,
PhysDefVector &PhysDefs, bool &PhysUseDef) const;
bool PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *MI,
- SmallSet<MCRegister, 8> &PhysRefs,
+ SmallSet<MCRegister, 8> &PhysRefs,
PhysDefVector &PhysDefs, bool &NonLocal) const;
bool isCSECandidate(MachineInstr *MI);
- bool isProfitableToCSE(Register CSReg, Register Reg,
+ bool isProfitableToCSE(Register CSReg, Register Reg,
MachineBasicBlock *CSBB, MachineInstr *MI);
void EnterScope(MachineBasicBlock *MBB);
void ExitScope(MachineBasicBlock *MBB);
@@ -219,9 +219,9 @@ bool MachineCSE::PerformTrivialCopyPropagation(MachineInstr *MI,
return Changed;
}
-bool MachineCSE::isPhysDefTriviallyDead(
- MCRegister Reg, MachineBasicBlock::const_iterator I,
- MachineBasicBlock::const_iterator E) const {
+bool MachineCSE::isPhysDefTriviallyDead(
+ MCRegister Reg, MachineBasicBlock::const_iterator I,
+ MachineBasicBlock::const_iterator E) const {
unsigned LookAheadLeft = LookAheadLimit;
while (LookAheadLeft) {
// Skip over dbg_value's.
@@ -255,7 +255,7 @@ bool MachineCSE::isPhysDefTriviallyDead(
return false;
}
-static bool isCallerPreservedOrConstPhysReg(MCRegister Reg,
+static bool isCallerPreservedOrConstPhysReg(MCRegister Reg,
const MachineFunction &MF,
const TargetRegisterInfo &TRI) {
// MachineRegisterInfo::isConstantPhysReg directly called by
@@ -276,7 +276,7 @@ static bool isCallerPreservedOrConstPhysReg(MCRegister Reg,
/// instruction does not uses a physical register.
bool MachineCSE::hasLivePhysRegDefUses(const MachineInstr *MI,
const MachineBasicBlock *MBB,
- SmallSet<MCRegister, 8> &PhysRefs,
+ SmallSet<MCRegister, 8> &PhysRefs,
PhysDefVector &PhysDefs,
bool &PhysUseDef) const {
// First, add all uses to PhysRefs.
@@ -289,7 +289,7 @@ bool MachineCSE::hasLivePhysRegDefUses(const MachineInstr *MI,
if (Register::isVirtualRegister(Reg))
continue;
// Reading either caller preserved or constant physregs is ok.
- if (!isCallerPreservedOrConstPhysReg(Reg.asMCReg(), *MI->getMF(), *TRI))
+ if (!isCallerPreservedOrConstPhysReg(Reg.asMCReg(), *MI->getMF(), *TRI))
for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
PhysRefs.insert(*AI);
}
@@ -308,12 +308,12 @@ bool MachineCSE::hasLivePhysRegDefUses(const MachineInstr *MI,
if (Register::isVirtualRegister(Reg))
continue;
// Check against PhysRefs even if the def is "dead".
- if (PhysRefs.count(Reg.asMCReg()))
+ if (PhysRefs.count(Reg.asMCReg()))
PhysUseDef = true;
// If the def is dead, it's ok. But the def may not marked "dead". That's
// common since this pass is run before livevariables. We can scan
// forward a few instructions and check if it is obviously dead.
- if (!MO.isDead() && !isPhysDefTriviallyDead(Reg.asMCReg(), I, MBB->end()))
+ if (!MO.isDead() && !isPhysDefTriviallyDead(Reg.asMCReg(), I, MBB->end()))
PhysDefs.push_back(std::make_pair(MOP.index(), Reg));
}
@@ -327,7 +327,7 @@ bool MachineCSE::hasLivePhysRegDefUses(const MachineInstr *MI,
}
bool MachineCSE::PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *MI,
- SmallSet<MCRegister, 8> &PhysRefs,
+ SmallSet<MCRegister, 8> &PhysRefs,
PhysDefVector &PhysDefs,
bool &NonLocal) const {
// For now conservatively returns false if the common subexpression is
@@ -382,7 +382,7 @@ bool MachineCSE::PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *MI,
Register MOReg = MO.getReg();
if (Register::isVirtualRegister(MOReg))
continue;
- if (PhysRefs.count(MOReg.asMCReg()))
+ if (PhysRefs.count(MOReg.asMCReg()))
return false;
}
@@ -429,7 +429,7 @@ bool MachineCSE::isCSECandidate(MachineInstr *MI) {
/// isProfitableToCSE - Return true if it's profitable to eliminate MI with a
/// common expression that defines Reg. CSBB is basic block where CSReg is
/// defined.
-bool MachineCSE::isProfitableToCSE(Register CSReg, Register Reg,
+bool MachineCSE::isProfitableToCSE(Register CSReg, Register Reg,
MachineBasicBlock *CSBB, MachineInstr *MI) {
// FIXME: Heuristics that works around the lack the live range splitting.
@@ -556,7 +556,7 @@ bool MachineCSE::ProcessBlockCSE(MachineBasicBlock *MBB) {
// used, then it's not safe to replace it with a common subexpression.
// It's also not safe if the instruction uses physical registers.
bool CrossMBBPhysDef = false;
- SmallSet<MCRegister, 8> PhysRefs;
+ SmallSet<MCRegister, 8> PhysRefs;
PhysDefVector PhysDefs;
bool PhysUseDef = false;
if (FoundCSE && hasLivePhysRegDefUses(MI, MBB, PhysRefs,
@@ -640,7 +640,7 @@ bool MachineCSE::ProcessBlockCSE(MachineBasicBlock *MBB) {
// Actually perform the elimination.
if (DoCSE) {
- for (const std::pair<unsigned, unsigned> &CSEPair : CSEPairs) {
+ for (const std::pair<unsigned, unsigned> &CSEPair : CSEPairs) {
unsigned OldReg = CSEPair.first;
unsigned NewReg = CSEPair.second;
// OldReg may have been unused but is used now, clear the Dead flag
@@ -656,7 +656,7 @@ bool MachineCSE::ProcessBlockCSE(MachineBasicBlock *MBB) {
// we should make sure it is not dead at CSMI.
for (unsigned ImplicitDefToUpdate : ImplicitDefsToUpdate)
CSMI->getOperand(ImplicitDefToUpdate).setIsDead(false);
- for (const auto &PhysDef : PhysDefs)
+ for (const auto &PhysDef : PhysDefs)
if (!MI->getOperand(PhysDef.first).isDead())
CSMI->getOperand(PhysDef.first).setIsDead(false);
@@ -748,7 +748,7 @@ bool MachineCSE::PerformCSE(MachineDomTreeNode *Node) {
Node = WorkList.pop_back_val();
Scopes.push_back(Node);
OpenChildren[Node] = Node->getNumChildren();
- append_range(WorkList, Node->children());
+ append_range(WorkList, Node->children());
} while (!WorkList.empty());
// Now perform CSE.
@@ -776,11 +776,11 @@ bool MachineCSE::isPRECandidate(MachineInstr *MI) {
MI->getNumExplicitDefs() != 1)
return false;
- for (const auto &def : MI->defs())
+ for (const auto &def : MI->defs())
if (!Register::isVirtualRegister(def.getReg()))
return false;
- for (const auto &use : MI->uses())
+ for (const auto &use : MI->uses())
if (use.isReg() && !Register::isVirtualRegister(use.getReg()))
return false;
@@ -860,7 +860,7 @@ bool MachineCSE::PerformSimplePRE(MachineDominatorTree *DT) {
BBs.push_back(DT->getRootNode());
do {
auto Node = BBs.pop_back_val();
- append_range(BBs, Node->children());
+ append_range(BBs, Node->children());
MachineBasicBlock *MBB = Node->getBlock();
Changed |= ProcessBlockPRE(DT, MBB);
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineCheckDebugify.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineCheckDebugify.cpp
index 9a122a0a8b..bd7f0f8629 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineCheckDebugify.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineCheckDebugify.cpp
@@ -1,126 +1,126 @@
-//===- MachineCheckDebugify.cpp - Check debug info ------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file This checks debug info after mir-debugify (+ pass-to-test). Currently
-/// it simply checks the integrity of line info in DILocation and
-/// DILocalVariable which mir-debugifiy generated before.
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/IR/DebugInfo.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Transforms/Utils/Debugify.h"
-
-#define DEBUG_TYPE "mir-check-debugify"
-
-using namespace llvm;
-
-namespace {
-
-struct CheckDebugMachineModule : public ModulePass {
- bool runOnModule(Module &M) override {
- MachineModuleInfo &MMI =
- getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
-
- NamedMDNode *NMD = M.getNamedMetadata("llvm.mir.debugify");
- if (!NMD) {
- errs() << "WARNING: Please run mir-debugify to generate "
- "llvm.mir.debugify metadata first.\n";
- return false;
- }
-
- auto getDebugifyOperand = [&](unsigned Idx) -> unsigned {
- return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0))
- ->getZExtValue();
- };
- assert(NMD->getNumOperands() == 2 &&
- "llvm.mir.debugify should have exactly 2 operands!");
- unsigned NumLines = getDebugifyOperand(0);
- unsigned NumVars = getDebugifyOperand(1);
- BitVector MissingLines{NumLines, true};
- BitVector MissingVars{NumVars, true};
-
- for (Function &F : M.functions()) {
- MachineFunction *MF = MMI.getMachineFunction(F);
- if (!MF)
- continue;
- for (MachineBasicBlock &MBB : *MF) {
- // Find missing lines.
- // TODO: Avoid meta instructions other than dbg_val.
- for (MachineInstr &MI : MBB) {
- if (MI.isDebugValue())
- continue;
- const DebugLoc DL = MI.getDebugLoc();
- if (DL && DL.getLine() != 0) {
- MissingLines.reset(DL.getLine() - 1);
- continue;
- }
-
- if (!DL) {
- errs() << "WARNING: Instruction with empty DebugLoc in function ";
- errs() << F.getName() << " --";
- MI.print(errs());
- }
- }
-
- // Find missing variables.
- // TODO: Handle DBG_INSTR_REF which is under an experimental option now.
- for (MachineInstr &MI : MBB) {
- if (!MI.isDebugValue())
- continue;
- const DILocalVariable *LocalVar = MI.getDebugVariable();
- unsigned Var = ~0U;
-
- (void)to_integer(LocalVar->getName(), Var, 10);
- assert(Var <= NumVars && "Unexpected name for DILocalVariable");
- MissingVars.reset(Var - 1);
- }
- }
- }
-
- bool Fail = false;
- for (unsigned Idx : MissingLines.set_bits()) {
- errs() << "WARNING: Missing line " << Idx + 1 << "\n";
- Fail = true;
- }
-
- for (unsigned Idx : MissingVars.set_bits()) {
- errs() << "WARNING: Missing variable " << Idx + 1 << "\n";
- Fail = true;
- }
- errs() << "Machine IR debug info check: ";
- errs() << (Fail ? "FAIL" : "PASS") << "\n";
-
- return false;
- }
-
- CheckDebugMachineModule() : ModulePass(ID) {}
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<MachineModuleInfoWrapperPass>();
- AU.addPreserved<MachineModuleInfoWrapperPass>();
- AU.setPreservesCFG();
- }
-
- static char ID; // Pass identification.
-};
-char CheckDebugMachineModule::ID = 0;
-
-} // end anonymous namespace
-
-INITIALIZE_PASS_BEGIN(CheckDebugMachineModule, DEBUG_TYPE,
- "Machine Check Debug Module", false, false)
-INITIALIZE_PASS_END(CheckDebugMachineModule, DEBUG_TYPE,
- "Machine Check Debug Module", false, false)
-
-ModulePass *llvm::createCheckDebugMachineModulePass() {
- return new CheckDebugMachineModule();
-}
+//===- MachineCheckDebugify.cpp - Check debug info ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file This checks debug info after mir-debugify (+ pass-to-test). Currently
+/// it simply checks the integrity of line info in DILocation and
+/// DILocalVariable which mir-debugifiy generated before.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils/Debugify.h"
+
+#define DEBUG_TYPE "mir-check-debugify"
+
+using namespace llvm;
+
+namespace {
+
+struct CheckDebugMachineModule : public ModulePass {
+ bool runOnModule(Module &M) override {
+ MachineModuleInfo &MMI =
+ getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
+
+ NamedMDNode *NMD = M.getNamedMetadata("llvm.mir.debugify");
+ if (!NMD) {
+ errs() << "WARNING: Please run mir-debugify to generate "
+ "llvm.mir.debugify metadata first.\n";
+ return false;
+ }
+
+ auto getDebugifyOperand = [&](unsigned Idx) -> unsigned {
+ return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0))
+ ->getZExtValue();
+ };
+ assert(NMD->getNumOperands() == 2 &&
+ "llvm.mir.debugify should have exactly 2 operands!");
+ unsigned NumLines = getDebugifyOperand(0);
+ unsigned NumVars = getDebugifyOperand(1);
+ BitVector MissingLines{NumLines, true};
+ BitVector MissingVars{NumVars, true};
+
+ for (Function &F : M.functions()) {
+ MachineFunction *MF = MMI.getMachineFunction(F);
+ if (!MF)
+ continue;
+ for (MachineBasicBlock &MBB : *MF) {
+ // Find missing lines.
+ // TODO: Avoid meta instructions other than dbg_val.
+ for (MachineInstr &MI : MBB) {
+ if (MI.isDebugValue())
+ continue;
+ const DebugLoc DL = MI.getDebugLoc();
+ if (DL && DL.getLine() != 0) {
+ MissingLines.reset(DL.getLine() - 1);
+ continue;
+ }
+
+ if (!DL) {
+ errs() << "WARNING: Instruction with empty DebugLoc in function ";
+ errs() << F.getName() << " --";
+ MI.print(errs());
+ }
+ }
+
+ // Find missing variables.
+ // TODO: Handle DBG_INSTR_REF which is under an experimental option now.
+ for (MachineInstr &MI : MBB) {
+ if (!MI.isDebugValue())
+ continue;
+ const DILocalVariable *LocalVar = MI.getDebugVariable();
+ unsigned Var = ~0U;
+
+ (void)to_integer(LocalVar->getName(), Var, 10);
+ assert(Var <= NumVars && "Unexpected name for DILocalVariable");
+ MissingVars.reset(Var - 1);
+ }
+ }
+ }
+
+ bool Fail = false;
+ for (unsigned Idx : MissingLines.set_bits()) {
+ errs() << "WARNING: Missing line " << Idx + 1 << "\n";
+ Fail = true;
+ }
+
+ for (unsigned Idx : MissingVars.set_bits()) {
+ errs() << "WARNING: Missing variable " << Idx + 1 << "\n";
+ Fail = true;
+ }
+ errs() << "Machine IR debug info check: ";
+ errs() << (Fail ? "FAIL" : "PASS") << "\n";
+
+ return false;
+ }
+
+ CheckDebugMachineModule() : ModulePass(ID) {}
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<MachineModuleInfoWrapperPass>();
+ AU.addPreserved<MachineModuleInfoWrapperPass>();
+ AU.setPreservesCFG();
+ }
+
+ static char ID; // Pass identification.
+};
+char CheckDebugMachineModule::ID = 0;
+
+} // end anonymous namespace
+
+INITIALIZE_PASS_BEGIN(CheckDebugMachineModule, DEBUG_TYPE,
+ "Machine Check Debug Module", false, false)
+INITIALIZE_PASS_END(CheckDebugMachineModule, DEBUG_TYPE,
+ "Machine Check Debug Module", false, false)
+
+ModulePass *llvm::createCheckDebugMachineModulePass() {
+ return new CheckDebugMachineModule();
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineCombiner.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineCombiner.cpp
index c9ea49aa73..e2b6cfe55c 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineCombiner.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineCombiner.cpp
@@ -22,7 +22,7 @@
#include "llvm/CodeGen/MachineSizeOpts.h"
#include "llvm/CodeGen/MachineTraceMetrics.h"
#include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/RegisterClassInfo.h"
+#include "llvm/CodeGen/RegisterClassInfo.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSchedule.h"
@@ -73,7 +73,7 @@ class MachineCombiner : public MachineFunctionPass {
MachineTraceMetrics::Ensemble *MinInstr;
MachineBlockFrequencyInfo *MBFI;
ProfileSummaryInfo *PSI;
- RegisterClassInfo RegClassInfo;
+ RegisterClassInfo RegClassInfo;
TargetSchedModel TSchedModel;
@@ -105,10 +105,10 @@ private:
SmallVectorImpl<MachineInstr *> &DelInstrs,
DenseMap<unsigned, unsigned> &InstrIdxForVirtReg,
MachineCombinerPattern Pattern, bool SlackIsAccurate);
- bool reduceRegisterPressure(MachineInstr &Root, MachineBasicBlock *MBB,
- SmallVectorImpl<MachineInstr *> &InsInstrs,
- SmallVectorImpl<MachineInstr *> &DelInstrs,
- MachineCombinerPattern Pattern);
+ bool reduceRegisterPressure(MachineInstr &Root, MachineBasicBlock *MBB,
+ SmallVectorImpl<MachineInstr *> &InsInstrs,
+ SmallVectorImpl<MachineInstr *> &DelInstrs,
+ MachineCombinerPattern Pattern);
bool preservesResourceLen(MachineBasicBlock *MBB,
MachineTraceMetrics::Trace BlockTrace,
SmallVectorImpl<MachineInstr *> &InsInstrs,
@@ -263,9 +263,9 @@ unsigned MachineCombiner::getLatency(MachineInstr *Root, MachineInstr *NewRoot,
/// The combiner's goal may differ based on which pattern it is attempting
/// to optimize.
enum class CombinerObjective {
- MustReduceDepth, // The data dependency chain must be improved.
- MustReduceRegisterPressure, // The register pressure must be reduced.
- Default // The critical path must not be lengthened.
+ MustReduceDepth, // The data dependency chain must be improved.
+ MustReduceRegisterPressure, // The register pressure must be reduced.
+ Default // The critical path must not be lengthened.
};
static CombinerObjective getCombinerObjective(MachineCombinerPattern P) {
@@ -279,9 +279,9 @@ static CombinerObjective getCombinerObjective(MachineCombinerPattern P) {
case MachineCombinerPattern::REASSOC_XY_AMM_BMM:
case MachineCombinerPattern::REASSOC_XMM_AMM_BMM:
return CombinerObjective::MustReduceDepth;
- case MachineCombinerPattern::REASSOC_XY_BCA:
- case MachineCombinerPattern::REASSOC_XY_BAC:
- return CombinerObjective::MustReduceRegisterPressure;
+ case MachineCombinerPattern::REASSOC_XY_BCA:
+ case MachineCombinerPattern::REASSOC_XY_BAC:
+ return CombinerObjective::MustReduceRegisterPressure;
default:
return CombinerObjective::Default;
}
@@ -310,18 +310,18 @@ std::pair<unsigned, unsigned> MachineCombiner::getLatenciesForInstrSequences(
return {NewRootLatency, RootLatency};
}
-bool MachineCombiner::reduceRegisterPressure(
- MachineInstr &Root, MachineBasicBlock *MBB,
- SmallVectorImpl<MachineInstr *> &InsInstrs,
- SmallVectorImpl<MachineInstr *> &DelInstrs,
- MachineCombinerPattern Pattern) {
- // FIXME: for now, we don't do any check for the register pressure patterns.
- // We treat them as always profitable. But we can do better if we make
- // RegPressureTracker class be aware of TIE attribute. Then we can get an
- // accurate compare of register pressure with DelInstrs or InsInstrs.
- return true;
-}
-
+bool MachineCombiner::reduceRegisterPressure(
+ MachineInstr &Root, MachineBasicBlock *MBB,
+ SmallVectorImpl<MachineInstr *> &InsInstrs,
+ SmallVectorImpl<MachineInstr *> &DelInstrs,
+ MachineCombinerPattern Pattern) {
+ // FIXME: for now, we don't do any check for the register pressure patterns.
+ // We treat them as always profitable. But we can do better if we make
+ // RegPressureTracker class be aware of TIE attribute. Then we can get an
+ // accurate compare of register pressure with DelInstrs or InsInstrs.
+ return true;
+}
+
/// The DAGCombine code sequence ends in MI (Machine Instruction) Root.
/// The new code sequence ends in MI NewRoot. A necessary condition for the new
/// sequence to replace the old sequence is that it cannot lengthen the critical
@@ -460,8 +460,8 @@ bool MachineCombiner::doSubstitute(unsigned NewSize, unsigned OldSize,
/// \param DelInstrs instruction to delete from \p MBB
/// \param MinInstr is a pointer to the machine trace information
/// \param RegUnits set of live registers, needed to compute instruction depths
-/// \param TII is target instruction info, used to call target hook
-/// \param Pattern is used to call target hook finalizeInsInstrs
+/// \param TII is target instruction info, used to call target hook
+/// \param Pattern is used to call target hook finalizeInsInstrs
/// \param IncrementalUpdate if true, compute instruction depths incrementally,
/// otherwise invalidate the trace
static void insertDeleteInstructions(MachineBasicBlock *MBB, MachineInstr &MI,
@@ -469,18 +469,18 @@ static void insertDeleteInstructions(MachineBasicBlock *MBB, MachineInstr &MI,
SmallVector<MachineInstr *, 16> DelInstrs,
MachineTraceMetrics::Ensemble *MinInstr,
SparseSet<LiveRegUnit> &RegUnits,
- const TargetInstrInfo *TII,
- MachineCombinerPattern Pattern,
+ const TargetInstrInfo *TII,
+ MachineCombinerPattern Pattern,
bool IncrementalUpdate) {
- // If we want to fix up some placeholder for some target, do it now.
- // We need this because in genAlternativeCodeSequence, we have not decided the
- // better pattern InsInstrs or DelInstrs, so we don't want generate some
- // sideeffect to the function. For example we need to delay the constant pool
- // entry creation here after InsInstrs is selected as better pattern.
- // Otherwise the constant pool entry created for InsInstrs will not be deleted
- // even if InsInstrs is not the better pattern.
- TII->finalizeInsInstrs(MI, Pattern, InsInstrs);
-
+ // If we want to fix up some placeholder for some target, do it now.
+ // We need this because in genAlternativeCodeSequence, we have not decided the
+ // better pattern InsInstrs or DelInstrs, so we don't want generate some
+ // sideeffect to the function. For example we need to delay the constant pool
+ // entry creation here after InsInstrs is selected as better pattern.
+ // Otherwise the constant pool entry created for InsInstrs will not be deleted
+ // even if InsInstrs is not the better pattern.
+ TII->finalizeInsInstrs(MI, Pattern, InsInstrs);
+
for (auto *InstrPtr : InsInstrs)
MBB->insert((MachineBasicBlock::iterator)&MI, InstrPtr);
@@ -557,9 +557,9 @@ bool MachineCombiner::combineInstructions(MachineBasicBlock *MBB) {
bool OptForSize = OptSize || llvm::shouldOptimizeForSize(MBB, PSI, MBFI);
- bool DoRegPressureReduce =
- TII->shouldReduceRegisterPressure(MBB, &RegClassInfo);
-
+ bool DoRegPressureReduce =
+ TII->shouldReduceRegisterPressure(MBB, &RegClassInfo);
+
while (BlockIter != MBB->end()) {
auto &MI = *BlockIter++;
SmallVector<MachineCombinerPattern, 16> Patterns;
@@ -590,7 +590,7 @@ bool MachineCombiner::combineInstructions(MachineBasicBlock *MBB) {
// machine-combiner-verify-pattern-order is enabled, all patterns are
// checked to ensure later patterns do not provide better latency savings.
- if (!TII->getMachineCombinerPatterns(MI, Patterns, DoRegPressureReduce))
+ if (!TII->getMachineCombinerPatterns(MI, Patterns, DoRegPressureReduce))
continue;
if (VerifyPatternOrder)
@@ -626,33 +626,33 @@ bool MachineCombiner::combineInstructions(MachineBasicBlock *MBB) {
if (ML && TII->isThroughputPattern(P))
SubstituteAlways = true;
- if (IncrementalUpdate && LastUpdate != BlockIter) {
+ if (IncrementalUpdate && LastUpdate != BlockIter) {
// Update depths since the last incremental update.
MinInstr->updateDepths(LastUpdate, BlockIter, RegUnits);
LastUpdate = BlockIter;
}
- if (DoRegPressureReduce &&
- getCombinerObjective(P) ==
- CombinerObjective::MustReduceRegisterPressure) {
- if (MBB->size() > inc_threshold) {
- // Use incremental depth updates for basic blocks above threshold
- IncrementalUpdate = true;
- LastUpdate = BlockIter;
- }
- if (reduceRegisterPressure(MI, MBB, InsInstrs, DelInstrs, P)) {
- // Replace DelInstrs with InsInstrs.
- insertDeleteInstructions(MBB, MI, InsInstrs, DelInstrs, MinInstr,
- RegUnits, TII, P, IncrementalUpdate);
- Changed |= true;
-
- // Go back to previous instruction as it may have ILP reassociation
- // opportunity.
- BlockIter--;
- break;
- }
- }
-
+ if (DoRegPressureReduce &&
+ getCombinerObjective(P) ==
+ CombinerObjective::MustReduceRegisterPressure) {
+ if (MBB->size() > inc_threshold) {
+ // Use incremental depth updates for basic blocks above threshold
+ IncrementalUpdate = true;
+ LastUpdate = BlockIter;
+ }
+ if (reduceRegisterPressure(MI, MBB, InsInstrs, DelInstrs, P)) {
+ // Replace DelInstrs with InsInstrs.
+ insertDeleteInstructions(MBB, MI, InsInstrs, DelInstrs, MinInstr,
+ RegUnits, TII, P, IncrementalUpdate);
+ Changed |= true;
+
+ // Go back to previous instruction as it may have ILP reassociation
+ // opportunity.
+ BlockIter--;
+ break;
+ }
+ }
+
// Substitute when we optimize for codesize and the new sequence has
// fewer instructions OR
// the new sequence neither lengthens the critical path nor increases
@@ -660,7 +660,7 @@ bool MachineCombiner::combineInstructions(MachineBasicBlock *MBB) {
if (SubstituteAlways ||
doSubstitute(NewInstCount, OldInstCount, OptForSize)) {
insertDeleteInstructions(MBB, MI, InsInstrs, DelInstrs, MinInstr,
- RegUnits, TII, P, IncrementalUpdate);
+ RegUnits, TII, P, IncrementalUpdate);
// Eagerly stop after the first pattern fires.
Changed = true;
break;
@@ -683,7 +683,7 @@ bool MachineCombiner::combineInstructions(MachineBasicBlock *MBB) {
}
insertDeleteInstructions(MBB, MI, InsInstrs, DelInstrs, MinInstr,
- RegUnits, TII, P, IncrementalUpdate);
+ RegUnits, TII, P, IncrementalUpdate);
// Eagerly stop after the first pattern fires.
Changed = true;
@@ -719,7 +719,7 @@ bool MachineCombiner::runOnMachineFunction(MachineFunction &MF) {
nullptr;
MinInstr = nullptr;
OptSize = MF.getFunction().hasOptSize();
- RegClassInfo.runOnMachineFunction(MF);
+ RegClassInfo.runOnMachineFunction(MF);
LLVM_DEBUG(dbgs() << getPassName() << ": " << MF.getName() << '\n');
if (!TII->useMachineCombiner()) {
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineCopyPropagation.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineCopyPropagation.cpp
index f7497650b8..d8659c1c78 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineCopyPropagation.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineCopyPropagation.cpp
@@ -88,18 +88,18 @@ namespace {
class CopyTracker {
struct CopyInfo {
MachineInstr *MI;
- SmallVector<MCRegister, 4> DefRegs;
+ SmallVector<MCRegister, 4> DefRegs;
bool Avail;
};
- DenseMap<MCRegister, CopyInfo> Copies;
+ DenseMap<MCRegister, CopyInfo> Copies;
public:
/// Mark all of the given registers and their subregisters as unavailable for
/// copying.
- void markRegsUnavailable(ArrayRef<MCRegister> Regs,
+ void markRegsUnavailable(ArrayRef<MCRegister> Regs,
const TargetRegisterInfo &TRI) {
- for (MCRegister Reg : Regs) {
+ for (MCRegister Reg : Regs) {
// Source of copy is no longer available for propagation.
for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) {
auto CI = Copies.find(*RUI);
@@ -110,30 +110,30 @@ public:
}
/// Remove register from copy maps.
- void invalidateRegister(MCRegister Reg, const TargetRegisterInfo &TRI) {
+ void invalidateRegister(MCRegister Reg, const TargetRegisterInfo &TRI) {
// Since Reg might be a subreg of some registers, only invalidate Reg is not
// enough. We have to find the COPY defines Reg or registers defined by Reg
// and invalidate all of them.
- SmallSet<MCRegister, 8> RegsToInvalidate;
+ SmallSet<MCRegister, 8> RegsToInvalidate;
RegsToInvalidate.insert(Reg);
for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) {
auto I = Copies.find(*RUI);
if (I != Copies.end()) {
if (MachineInstr *MI = I->second.MI) {
- RegsToInvalidate.insert(MI->getOperand(0).getReg().asMCReg());
- RegsToInvalidate.insert(MI->getOperand(1).getReg().asMCReg());
+ RegsToInvalidate.insert(MI->getOperand(0).getReg().asMCReg());
+ RegsToInvalidate.insert(MI->getOperand(1).getReg().asMCReg());
}
RegsToInvalidate.insert(I->second.DefRegs.begin(),
I->second.DefRegs.end());
}
}
- for (MCRegister InvalidReg : RegsToInvalidate)
+ for (MCRegister InvalidReg : RegsToInvalidate)
for (MCRegUnitIterator RUI(InvalidReg, &TRI); RUI.isValid(); ++RUI)
Copies.erase(*RUI);
}
/// Clobber a single register, removing it from the tracker's copy maps.
- void clobberRegister(MCRegister Reg, const TargetRegisterInfo &TRI) {
+ void clobberRegister(MCRegister Reg, const TargetRegisterInfo &TRI) {
for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) {
auto I = Copies.find(*RUI);
if (I != Copies.end()) {
@@ -143,7 +143,7 @@ public:
// When we clobber the destination of a copy, we need to clobber the
// whole register it defined.
if (MachineInstr *MI = I->second.MI)
- markRegsUnavailable({MI->getOperand(0).getReg().asMCReg()}, TRI);
+ markRegsUnavailable({MI->getOperand(0).getReg().asMCReg()}, TRI);
// Now we can erase the copy.
Copies.erase(I);
}
@@ -154,8 +154,8 @@ public:
void trackCopy(MachineInstr *MI, const TargetRegisterInfo &TRI) {
assert(MI->isCopy() && "Tracking non-copy?");
- MCRegister Def = MI->getOperand(0).getReg().asMCReg();
- MCRegister Src = MI->getOperand(1).getReg().asMCReg();
+ MCRegister Def = MI->getOperand(0).getReg().asMCReg();
+ MCRegister Src = MI->getOperand(1).getReg().asMCReg();
// Remember Def is defined by the copy.
for (MCRegUnitIterator RUI(Def, &TRI); RUI.isValid(); ++RUI)
@@ -175,9 +175,9 @@ public:
return !Copies.empty();
}
- MachineInstr *findCopyForUnit(MCRegister RegUnit,
- const TargetRegisterInfo &TRI,
- bool MustBeAvailable = false) {
+ MachineInstr *findCopyForUnit(MCRegister RegUnit,
+ const TargetRegisterInfo &TRI,
+ bool MustBeAvailable = false) {
auto CI = Copies.find(RegUnit);
if (CI == Copies.end())
return nullptr;
@@ -186,8 +186,8 @@ public:
return CI->second.MI;
}
- MachineInstr *findCopyDefViaUnit(MCRegister RegUnit,
- const TargetRegisterInfo &TRI) {
+ MachineInstr *findCopyDefViaUnit(MCRegister RegUnit,
+ const TargetRegisterInfo &TRI) {
auto CI = Copies.find(RegUnit);
if (CI == Copies.end())
return nullptr;
@@ -197,7 +197,7 @@ public:
return findCopyForUnit(*RUI, TRI, true);
}
- MachineInstr *findAvailBackwardCopy(MachineInstr &I, MCRegister Reg,
+ MachineInstr *findAvailBackwardCopy(MachineInstr &I, MCRegister Reg,
const TargetRegisterInfo &TRI) {
MCRegUnitIterator RUI(Reg, &TRI);
MachineInstr *AvailCopy = findCopyDefViaUnit(*RUI, TRI);
@@ -218,7 +218,7 @@ public:
return AvailCopy;
}
- MachineInstr *findAvailCopy(MachineInstr &DestCopy, MCRegister Reg,
+ MachineInstr *findAvailCopy(MachineInstr &DestCopy, MCRegister Reg,
const TargetRegisterInfo &TRI) {
// We check the first RegUnit here, since we'll only be interested in the
// copy if it copies the entire register anyway.
@@ -275,10 +275,10 @@ public:
private:
typedef enum { DebugUse = false, RegularUse = true } DebugType;
- void ReadRegister(MCRegister Reg, MachineInstr &Reader, DebugType DT);
+ void ReadRegister(MCRegister Reg, MachineInstr &Reader, DebugType DT);
void ForwardCopyPropagateBlock(MachineBasicBlock &MBB);
void BackwardCopyPropagateBlock(MachineBasicBlock &MBB);
- bool eraseIfRedundant(MachineInstr &Copy, MCRegister Src, MCRegister Def);
+ bool eraseIfRedundant(MachineInstr &Copy, MCRegister Src, MCRegister Def);
void forwardUses(MachineInstr &MI);
void propagateDefs(MachineInstr &MI);
bool isForwardableRegClassCopy(const MachineInstr &Copy,
@@ -287,8 +287,8 @@ private:
const MachineInstr &UseI,
unsigned UseIdx);
bool hasImplicitOverlap(const MachineInstr &MI, const MachineOperand &Use);
- bool hasOverlappingMultipleDef(const MachineInstr &MI,
- const MachineOperand &MODef, Register Def);
+ bool hasOverlappingMultipleDef(const MachineInstr &MI,
+ const MachineOperand &MODef, Register Def);
/// Candidates for deletion.
SmallSetVector<MachineInstr *, 8> MaybeDeadCopies;
@@ -310,7 +310,7 @@ char &llvm::MachineCopyPropagationID = MachineCopyPropagation::ID;
INITIALIZE_PASS(MachineCopyPropagation, DEBUG_TYPE,
"Machine Copy Propagation Pass", false, false)
-void MachineCopyPropagation::ReadRegister(MCRegister Reg, MachineInstr &Reader,
+void MachineCopyPropagation::ReadRegister(MCRegister Reg, MachineInstr &Reader,
DebugType DT) {
// If 'Reg' is defined by a copy, the copy is no longer a candidate
// for elimination. If a copy is "read" by a debug user, record the user
@@ -333,10 +333,10 @@ void MachineCopyPropagation::ReadRegister(MCRegister Reg, MachineInstr &Reader,
/// PreviousCopy. e.g.
/// isNopCopy("ecx = COPY eax", AX, CX) == true
/// isNopCopy("ecx = COPY eax", AH, CL) == false
-static bool isNopCopy(const MachineInstr &PreviousCopy, MCRegister Src,
- MCRegister Def, const TargetRegisterInfo *TRI) {
- MCRegister PreviousSrc = PreviousCopy.getOperand(1).getReg().asMCReg();
- MCRegister PreviousDef = PreviousCopy.getOperand(0).getReg().asMCReg();
+static bool isNopCopy(const MachineInstr &PreviousCopy, MCRegister Src,
+ MCRegister Def, const TargetRegisterInfo *TRI) {
+ MCRegister PreviousSrc = PreviousCopy.getOperand(1).getReg().asMCReg();
+ MCRegister PreviousDef = PreviousCopy.getOperand(0).getReg().asMCReg();
if (Src == PreviousSrc && Def == PreviousDef)
return true;
if (!TRI->isSubRegister(PreviousSrc, Src))
@@ -348,8 +348,8 @@ static bool isNopCopy(const MachineInstr &PreviousCopy, MCRegister Src,
/// Remove instruction \p Copy if there exists a previous copy that copies the
/// register \p Src to the register \p Def; This may happen indirectly by
/// copying the super registers.
-bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy,
- MCRegister Src, MCRegister Def) {
+bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy,
+ MCRegister Src, MCRegister Def) {
// Avoid eliminating a copy from/to a reserved registers as we cannot predict
// the value (Example: The sparc zero register is writable but stays zero).
if (MRI->isReserved(Src) || MRI->isReserved(Def))
@@ -460,21 +460,21 @@ bool MachineCopyPropagation::hasImplicitOverlap(const MachineInstr &MI,
return false;
}
-/// For an MI that has multiple definitions, check whether \p MI has
-/// a definition that overlaps with another of its definitions.
-/// For example, on ARM: umull r9, r9, lr, r0
-/// The umull instruction is unpredictable unless RdHi and RdLo are different.
-bool MachineCopyPropagation::hasOverlappingMultipleDef(
- const MachineInstr &MI, const MachineOperand &MODef, Register Def) {
- for (const MachineOperand &MIDef : MI.defs()) {
- if ((&MIDef != &MODef) && MIDef.isReg() &&
- TRI->regsOverlap(Def, MIDef.getReg()))
- return true;
- }
-
- return false;
-}
-
+/// For an MI that has multiple definitions, check whether \p MI has
+/// a definition that overlaps with another of its definitions.
+/// For example, on ARM: umull r9, r9, lr, r0
+/// The umull instruction is unpredictable unless RdHi and RdLo are different.
+bool MachineCopyPropagation::hasOverlappingMultipleDef(
+ const MachineInstr &MI, const MachineOperand &MODef, Register Def) {
+ for (const MachineOperand &MIDef : MI.defs()) {
+ if ((&MIDef != &MODef) && MIDef.isReg() &&
+ TRI->regsOverlap(Def, MIDef.getReg()))
+ return true;
+ }
+
+ return false;
+}
+
/// Look for available copies whose destination register is used by \p MI and
/// replace the use in \p MI with the copy's source register.
void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
@@ -505,8 +505,8 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
if (!MOUse.isRenamable())
continue;
- MachineInstr *Copy =
- Tracker.findAvailCopy(MI, MOUse.getReg().asMCReg(), *TRI);
+ MachineInstr *Copy =
+ Tracker.findAvailCopy(MI, MOUse.getReg().asMCReg(), *TRI);
if (!Copy)
continue;
@@ -578,13 +578,13 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
// Analyze copies (which don't overlap themselves).
if (MI->isCopy() && !TRI->regsOverlap(MI->getOperand(0).getReg(),
MI->getOperand(1).getReg())) {
- assert(MI->getOperand(0).getReg().isPhysical() &&
- MI->getOperand(1).getReg().isPhysical() &&
+ assert(MI->getOperand(0).getReg().isPhysical() &&
+ MI->getOperand(1).getReg().isPhysical() &&
"MachineCopyPropagation should be run after register allocation!");
- MCRegister Def = MI->getOperand(0).getReg().asMCReg();
- MCRegister Src = MI->getOperand(1).getReg().asMCReg();
-
+ MCRegister Def = MI->getOperand(0).getReg().asMCReg();
+ MCRegister Src = MI->getOperand(1).getReg().asMCReg();
+
// The two copies cancel out and the source of the first copy
// hasn't been overridden, eliminate the second one. e.g.
// %ecx = COPY %eax
@@ -606,7 +606,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
forwardUses(*MI);
// Src may have been changed by forwardUses()
- Src = MI->getOperand(1).getReg().asMCReg();
+ Src = MI->getOperand(1).getReg().asMCReg();
// If Src is defined by a previous copy, the previous copy cannot be
// eliminated.
@@ -614,7 +614,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
for (const MachineOperand &MO : MI->implicit_operands()) {
if (!MO.isReg() || !MO.readsReg())
continue;
- MCRegister Reg = MO.getReg().asMCReg();
+ MCRegister Reg = MO.getReg().asMCReg();
if (!Reg)
continue;
ReadRegister(Reg, *MI, RegularUse);
@@ -637,7 +637,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
for (const MachineOperand &MO : MI->implicit_operands()) {
if (!MO.isReg() || !MO.isDef())
continue;
- MCRegister Reg = MO.getReg().asMCReg();
+ MCRegister Reg = MO.getReg().asMCReg();
if (!Reg)
continue;
Tracker.clobberRegister(Reg, *TRI);
@@ -651,7 +651,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
// Clobber any earlyclobber regs first.
for (const MachineOperand &MO : MI->operands())
if (MO.isReg() && MO.isEarlyClobber()) {
- MCRegister Reg = MO.getReg().asMCReg();
+ MCRegister Reg = MO.getReg().asMCReg();
// If we have a tied earlyclobber, that means it is also read by this
// instruction, so we need to make sure we don't remove it as dead
// later.
@@ -663,7 +663,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
forwardUses(*MI);
// Not a copy.
- SmallVector<Register, 2> Defs;
+ SmallVector<Register, 2> Defs;
const MachineOperand *RegMask = nullptr;
for (const MachineOperand &MO : MI->operands()) {
if (MO.isRegMask())
@@ -674,14 +674,14 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
if (!Reg)
continue;
- assert(!Reg.isVirtual() &&
+ assert(!Reg.isVirtual() &&
"MachineCopyPropagation should be run after register allocation!");
if (MO.isDef() && !MO.isEarlyClobber()) {
- Defs.push_back(Reg.asMCReg());
+ Defs.push_back(Reg.asMCReg());
continue;
} else if (MO.readsReg())
- ReadRegister(Reg.asMCReg(), *MI, MO.isDebug() ? DebugUse : RegularUse);
+ ReadRegister(Reg.asMCReg(), *MI, MO.isDebug() ? DebugUse : RegularUse);
}
// The instruction has a register mask operand which means that it clobbers
@@ -693,7 +693,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
MaybeDeadCopies.begin();
DI != MaybeDeadCopies.end();) {
MachineInstr *MaybeDead = *DI;
- MCRegister Reg = MaybeDead->getOperand(0).getReg().asMCReg();
+ MCRegister Reg = MaybeDead->getOperand(0).getReg().asMCReg();
assert(!MRI->isReserved(Reg));
if (!RegMask->clobbersPhysReg(Reg)) {
@@ -718,7 +718,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
}
// Any previous copy definition or reading the Defs is no longer available.
- for (MCRegister Reg : Defs)
+ for (MCRegister Reg : Defs)
Tracker.clobberRegister(Reg, *TRI);
}
@@ -733,7 +733,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
// Update matching debug values, if any.
assert(MaybeDead->isCopy());
- Register SrcReg = MaybeDead->getOperand(1).getReg();
+ Register SrcReg = MaybeDead->getOperand(1).getReg();
MRI->updateDbgUsersToReg(SrcReg, CopyDbgUsers[MaybeDead]);
MaybeDead->eraseFromParent();
@@ -785,7 +785,7 @@ void MachineCopyPropagation::propagateDefs(MachineInstr &MI) {
continue;
MachineInstr *Copy =
- Tracker.findAvailBackwardCopy(MI, MODef.getReg().asMCReg(), *TRI);
+ Tracker.findAvailBackwardCopy(MI, MODef.getReg().asMCReg(), *TRI);
if (!Copy)
continue;
@@ -801,9 +801,9 @@ void MachineCopyPropagation::propagateDefs(MachineInstr &MI) {
if (hasImplicitOverlap(MI, MODef))
continue;
- if (hasOverlappingMultipleDef(MI, MODef, Def))
- continue;
-
+ if (hasOverlappingMultipleDef(MI, MODef, Def))
+ continue;
+
LLVM_DEBUG(dbgs() << "MCP: Replacing " << printReg(MODef.getReg(), TRI)
<< "\n with " << printReg(Def, TRI) << "\n in "
<< MI << " from " << *Copy);
@@ -833,8 +833,8 @@ void MachineCopyPropagation::BackwardCopyPropagateBlock(
!TRI->regsOverlap(MI->getOperand(0).getReg(),
MI->getOperand(1).getReg())) {
- MCRegister Def = MI->getOperand(0).getReg().asMCReg();
- MCRegister Src = MI->getOperand(1).getReg().asMCReg();
+ MCRegister Def = MI->getOperand(0).getReg().asMCReg();
+ MCRegister Src = MI->getOperand(1).getReg().asMCReg();
// Unlike forward cp, we don't invoke propagateDefs here,
// just let forward cp do COPY-to-COPY propagation.
@@ -849,7 +849,7 @@ void MachineCopyPropagation::BackwardCopyPropagateBlock(
// Invalidate any earlyclobber regs first.
for (const MachineOperand &MO : MI->operands())
if (MO.isReg() && MO.isEarlyClobber()) {
- MCRegister Reg = MO.getReg().asMCReg();
+ MCRegister Reg = MO.getReg().asMCReg();
if (!Reg)
continue;
Tracker.invalidateRegister(Reg, *TRI);
@@ -864,10 +864,10 @@ void MachineCopyPropagation::BackwardCopyPropagateBlock(
continue;
if (MO.isDef())
- Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI);
+ Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI);
if (MO.readsReg())
- Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI);
+ Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI);
}
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineDebugify.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineDebugify.cpp
index 3c9a468434..599a818475 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineDebugify.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineDebugify.cpp
@@ -14,7 +14,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -90,11 +90,11 @@ bool applyDebugifyMetadataToMachineFunction(MachineModuleInfo &MMI,
// Do this by introducing debug uses of each register definition. If that is
// not possible (e.g. we have a phi or a meta instruction), emit a constant.
uint64_t NextImm = 0;
- SmallSet<DILocalVariable *, 16> VarSet;
+ SmallSet<DILocalVariable *, 16> VarSet;
const MCInstrDesc &DbgValDesc = TII.get(TargetOpcode::DBG_VALUE);
for (MachineBasicBlock &MBB : MF) {
MachineBasicBlock::iterator FirstNonPHIIt = MBB.getFirstNonPHI();
- for (auto I = MBB.begin(), E = MBB.end(); I != E;) {
+ for (auto I = MBB.begin(), E = MBB.end(); I != E;) {
MachineInstr &MI = *I;
++I;
@@ -115,7 +115,7 @@ bool applyDebugifyMetadataToMachineFunction(MachineModuleInfo &MMI,
Line = EarliestDVI->getDebugLoc().getLine();
DILocalVariable *LocalVar = Line2Var[Line];
assert(LocalVar && "No variable for current line?");
- VarSet.insert(LocalVar);
+ VarSet.insert(LocalVar);
// Emit DBG_VALUEs for register definitions.
SmallVector<MachineOperand *, 4> RegDefs;
@@ -135,33 +135,33 @@ bool applyDebugifyMetadataToMachineFunction(MachineModuleInfo &MMI,
}
}
- // Here we save the number of lines and variables into "llvm.mir.debugify".
- // It is useful for mir-check-debugify.
- NamedMDNode *NMD = M.getNamedMetadata("llvm.mir.debugify");
- IntegerType *Int32Ty = Type::getInt32Ty(Ctx);
- if (!NMD) {
- NMD = M.getOrInsertNamedMetadata("llvm.mir.debugify");
- auto addDebugifyOperand = [&](unsigned N) {
- NMD->addOperand(MDNode::get(
- Ctx, ValueAsMetadata::getConstant(ConstantInt::get(Int32Ty, N))));
- };
- // Add number of lines.
- addDebugifyOperand(NextLine - 1);
- // Add number of variables.
- addDebugifyOperand(VarSet.size());
- } else {
- assert(NMD->getNumOperands() == 2 &&
- "llvm.mir.debugify should have exactly 2 operands!");
- auto setDebugifyOperand = [&](unsigned Idx, unsigned N) {
- NMD->setOperand(Idx, MDNode::get(Ctx, ValueAsMetadata::getConstant(
- ConstantInt::get(Int32Ty, N))));
- };
- // Set number of lines.
- setDebugifyOperand(0, NextLine - 1);
- // Set number of variables.
- setDebugifyOperand(1, VarSet.size());
- }
-
+ // Here we save the number of lines and variables into "llvm.mir.debugify".
+ // It is useful for mir-check-debugify.
+ NamedMDNode *NMD = M.getNamedMetadata("llvm.mir.debugify");
+ IntegerType *Int32Ty = Type::getInt32Ty(Ctx);
+ if (!NMD) {
+ NMD = M.getOrInsertNamedMetadata("llvm.mir.debugify");
+ auto addDebugifyOperand = [&](unsigned N) {
+ NMD->addOperand(MDNode::get(
+ Ctx, ValueAsMetadata::getConstant(ConstantInt::get(Int32Ty, N))));
+ };
+ // Add number of lines.
+ addDebugifyOperand(NextLine - 1);
+ // Add number of variables.
+ addDebugifyOperand(VarSet.size());
+ } else {
+ assert(NMD->getNumOperands() == 2 &&
+ "llvm.mir.debugify should have exactly 2 operands!");
+ auto setDebugifyOperand = [&](unsigned Idx, unsigned N) {
+ NMD->setOperand(Idx, MDNode::get(Ctx, ValueAsMetadata::getConstant(
+ ConstantInt::get(Int32Ty, N))));
+ };
+ // Set number of lines.
+ setDebugifyOperand(0, NextLine - 1);
+ // Set number of variables.
+ setDebugifyOperand(1, VarSet.size());
+ }
+
return true;
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineFunction.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineFunction.cpp
index 6675075949..3f44578b1a 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineFunction.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineFunction.cpp
@@ -273,7 +273,7 @@ getOrCreateJumpTableInfo(unsigned EntryKind) {
}
DenormalMode MachineFunction::getDenormalMode(const fltSemantics &FPType) const {
- return F.getDenormalMode(FPType);
+ return F.getDenormalMode(FPType);
}
/// Should we be emitting segmented stack stuff for the function
@@ -347,9 +347,9 @@ void MachineFunction::assignBeginEndSections() {
/// Allocate a new MachineInstr. Use this instead of `new MachineInstr'.
MachineInstr *MachineFunction::CreateMachineInstr(const MCInstrDesc &MCID,
const DebugLoc &DL,
- bool NoImplicit) {
+ bool NoImplicit) {
return new (InstructionRecycler.Allocate<MachineInstr>(Allocator))
- MachineInstr(*this, MCID, DL, NoImplicit);
+ MachineInstr(*this, MCID, DL, NoImplicit);
}
/// Create a new MachineInstr which is a copy of the 'Orig' instruction,
@@ -420,9 +420,9 @@ MachineFunction::CreateMachineBasicBlock(const BasicBlock *bb) {
void
MachineFunction::DeleteMachineBasicBlock(MachineBasicBlock *MBB) {
assert(MBB->getParent() == this && "MBB parent mismatch!");
- // Clean up any references to MBB in jump tables before deleting it.
- if (JumpTableInfo)
- JumpTableInfo->RemoveMBBFromJumpTables(MBB);
+ // Clean up any references to MBB in jump tables before deleting it.
+ if (JumpTableInfo)
+ JumpTableInfo->RemoveMBBFromJumpTables(MBB);
MBB->~MachineBasicBlock();
BasicBlockRecycler.Deallocate(Allocator, MBB);
}
@@ -437,13 +437,13 @@ MachineMemOperand *MachineFunction::getMachineMemOperand(
SSID, Ordering, FailureOrdering);
}
-MachineMemOperand *MachineFunction::getMachineMemOperand(
- const MachineMemOperand *MMO, MachinePointerInfo &PtrInfo, uint64_t Size) {
- return new (Allocator) MachineMemOperand(
- PtrInfo, MMO->getFlags(), Size, MMO->getBaseAlign(), AAMDNodes(), nullptr,
- MMO->getSyncScopeID(), MMO->getOrdering(), MMO->getFailureOrdering());
-}
-
+MachineMemOperand *MachineFunction::getMachineMemOperand(
+ const MachineMemOperand *MMO, MachinePointerInfo &PtrInfo, uint64_t Size) {
+ return new (Allocator) MachineMemOperand(
+ PtrInfo, MMO->getFlags(), Size, MMO->getBaseAlign(), AAMDNodes(), nullptr,
+ MMO->getSyncScopeID(), MMO->getOrdering(), MMO->getFailureOrdering());
+}
+
MachineMemOperand *
MachineFunction::getMachineMemOperand(const MachineMemOperand *MMO,
int64_t Offset, uint64_t Size) {
@@ -455,11 +455,11 @@ MachineFunction::getMachineMemOperand(const MachineMemOperand *MMO,
? commonAlignment(MMO->getBaseAlign(), Offset)
: MMO->getBaseAlign();
- // Do not preserve ranges, since we don't necessarily know what the high bits
- // are anymore.
+ // Do not preserve ranges, since we don't necessarily know what the high bits
+ // are anymore.
return new (Allocator)
MachineMemOperand(PtrInfo.getWithOffset(Offset), MMO->getFlags(), Size,
- Alignment, MMO->getAAInfo(), nullptr, MMO->getSyncScopeID(),
+ Alignment, MMO->getAAInfo(), nullptr, MMO->getSyncScopeID(),
MMO->getOrdering(), MMO->getFailureOrdering());
}
@@ -868,7 +868,7 @@ try_next:;
// Add the new filter.
int FilterID = -(1 + FilterIds.size());
FilterIds.reserve(FilterIds.size() + TyIds.size() + 1);
- llvm::append_range(FilterIds, TyIds);
+ llvm::append_range(FilterIds, TyIds);
FilterEnds.push_back(FilterIds.size());
FilterIds.push_back(0); // terminator
return FilterID;
@@ -946,46 +946,46 @@ void MachineFunction::moveCallSiteInfo(const MachineInstr *Old,
CallSitesInfo[New] = CSInfo;
}
-void MachineFunction::setDebugInstrNumberingCount(unsigned Num) {
- DebugInstrNumberingCount = Num;
-}
-
-void MachineFunction::makeDebugValueSubstitution(DebugInstrOperandPair A,
- DebugInstrOperandPair B) {
- auto Result = DebugValueSubstitutions.insert(std::make_pair(A, B));
- (void)Result;
- assert(Result.second && "Substitution for an already substituted value?");
-}
-
-void MachineFunction::substituteDebugValuesForInst(const MachineInstr &Old,
- MachineInstr &New,
- unsigned MaxOperand) {
- // If the Old instruction wasn't tracked at all, there is no work to do.
- unsigned OldInstrNum = Old.peekDebugInstrNum();
- if (!OldInstrNum)
- return;
-
- // Iterate over all operands looking for defs to create substitutions for.
- // Avoid creating new instr numbers unless we create a new substitution.
- // While this has no functional effect, it risks confusing someone reading
- // MIR output.
- // Examine all the operands, or the first N specified by the caller.
- MaxOperand = std::min(MaxOperand, Old.getNumOperands());
- for (unsigned int I = 0; I < Old.getNumOperands(); ++I) {
- const auto &OldMO = Old.getOperand(I);
- auto &NewMO = New.getOperand(I);
- (void)NewMO;
-
- if (!OldMO.isReg() || !OldMO.isDef())
- continue;
- assert(NewMO.isDef());
-
- unsigned NewInstrNum = New.getDebugInstrNum();
- makeDebugValueSubstitution(std::make_pair(OldInstrNum, I),
- std::make_pair(NewInstrNum, I));
- }
-}
-
+void MachineFunction::setDebugInstrNumberingCount(unsigned Num) {
+ DebugInstrNumberingCount = Num;
+}
+
+void MachineFunction::makeDebugValueSubstitution(DebugInstrOperandPair A,
+ DebugInstrOperandPair B) {
+ auto Result = DebugValueSubstitutions.insert(std::make_pair(A, B));
+ (void)Result;
+ assert(Result.second && "Substitution for an already substituted value?");
+}
+
+void MachineFunction::substituteDebugValuesForInst(const MachineInstr &Old,
+ MachineInstr &New,
+ unsigned MaxOperand) {
+ // If the Old instruction wasn't tracked at all, there is no work to do.
+ unsigned OldInstrNum = Old.peekDebugInstrNum();
+ if (!OldInstrNum)
+ return;
+
+ // Iterate over all operands looking for defs to create substitutions for.
+ // Avoid creating new instr numbers unless we create a new substitution.
+ // While this has no functional effect, it risks confusing someone reading
+ // MIR output.
+ // Examine all the operands, or the first N specified by the caller.
+ MaxOperand = std::min(MaxOperand, Old.getNumOperands());
+ for (unsigned int I = 0; I < Old.getNumOperands(); ++I) {
+ const auto &OldMO = Old.getOperand(I);
+ auto &NewMO = New.getOperand(I);
+ (void)NewMO;
+
+ if (!OldMO.isReg() || !OldMO.isDef())
+ continue;
+ assert(NewMO.isDef());
+
+ unsigned NewInstrNum = New.getDebugInstrNum();
+ makeDebugValueSubstitution(std::make_pair(OldInstrNum, I),
+ std::make_pair(NewInstrNum, I));
+ }
+}
+
/// \}
//===----------------------------------------------------------------------===//
@@ -1050,17 +1050,17 @@ bool MachineJumpTableInfo::ReplaceMBBInJumpTables(MachineBasicBlock *Old,
return MadeChange;
}
-/// If MBB is present in any jump tables, remove it.
-bool MachineJumpTableInfo::RemoveMBBFromJumpTables(MachineBasicBlock *MBB) {
- bool MadeChange = false;
- for (MachineJumpTableEntry &JTE : JumpTables) {
- auto removeBeginItr = std::remove(JTE.MBBs.begin(), JTE.MBBs.end(), MBB);
- MadeChange |= (removeBeginItr != JTE.MBBs.end());
- JTE.MBBs.erase(removeBeginItr, JTE.MBBs.end());
- }
- return MadeChange;
-}
-
+/// If MBB is present in any jump tables, remove it.
+bool MachineJumpTableInfo::RemoveMBBFromJumpTables(MachineBasicBlock *MBB) {
+ bool MadeChange = false;
+ for (MachineJumpTableEntry &JTE : JumpTables) {
+ auto removeBeginItr = std::remove(JTE.MBBs.begin(), JTE.MBBs.end(), MBB);
+ MadeChange |= (removeBeginItr != JTE.MBBs.end());
+ JTE.MBBs.erase(removeBeginItr, JTE.MBBs.end());
+ }
+ return MadeChange;
+}
+
/// If Old is a target of the jump tables, update the jump table to branch to
/// New instead.
bool MachineJumpTableInfo::ReplaceMBBInJumpTable(unsigned Idx,
@@ -1107,14 +1107,14 @@ Printable llvm::printJumpTableEntryReference(unsigned Idx) {
void MachineConstantPoolValue::anchor() {}
-unsigned MachineConstantPoolValue::getSizeInBytes(const DataLayout &DL) const {
- return DL.getTypeAllocSize(Ty);
-}
-
-unsigned MachineConstantPoolEntry::getSizeInBytes(const DataLayout &DL) const {
+unsigned MachineConstantPoolValue::getSizeInBytes(const DataLayout &DL) const {
+ return DL.getTypeAllocSize(Ty);
+}
+
+unsigned MachineConstantPoolEntry::getSizeInBytes(const DataLayout &DL) const {
if (isMachineConstantPoolEntry())
- return Val.MachineCPVal->getSizeInBytes(DL);
- return DL.getTypeAllocSize(Val.ConstVal->getType());
+ return Val.MachineCPVal->getSizeInBytes(DL);
+ return DL.getTypeAllocSize(Val.ConstVal->getType());
}
bool MachineConstantPoolEntry::needsRelocation() const {
@@ -1127,7 +1127,7 @@ SectionKind
MachineConstantPoolEntry::getSectionKind(const DataLayout *DL) const {
if (needsRelocation())
return SectionKind::getReadOnlyWithRel();
- switch (getSizeInBytes(*DL)) {
+ switch (getSizeInBytes(*DL)) {
case 4:
return SectionKind::getMergeableConst4();
case 8:
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineFunctionPrinterPass.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineFunctionPrinterPass.cpp
index dcef9a82ac..c31c065b19 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineFunctionPrinterPass.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineFunctionPrinterPass.cpp
@@ -14,7 +14,7 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/SlotIndexes.h"
-#include "llvm/IR/PrintPasses.h"
+#include "llvm/IR/PrintPasses.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
@@ -44,7 +44,7 @@ struct MachineFunctionPrinterPass : public MachineFunctionPass {
}
bool runOnMachineFunction(MachineFunction &MF) override {
- if (!isFunctionInPrintList(MF.getName()))
+ if (!isFunctionInPrintList(MF.getName()))
return false;
OS << "# " << Banner << ":\n";
MF.print(OS, getAnalysisIfAvailable<SlotIndexes>());
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineFunctionSplitter.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineFunctionSplitter.cpp
index fd5285c0e4..483809a8ed 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineFunctionSplitter.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineFunctionSplitter.cpp
@@ -1,155 +1,155 @@
-//===-- MachineFunctionSplitter.cpp - Split machine functions //-----------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// \file
-// Uses profile information to split out cold blocks.
-//
-// This pass splits out cold machine basic blocks from the parent function. This
-// implementation leverages the basic block section framework. Blocks marked
-// cold by this pass are grouped together in a separate section prefixed with
-// ".text.unlikely.*". The linker can then group these together as a cold
-// section. The split part of the function is a contiguous region identified by
-// the symbol "foo.cold". Grouping all cold blocks across functions together
-// decreases fragmentation and improves icache and itlb utilization. Note that
-// the overall changes to the binary size are negligible; only a small number of
-// additional jump instructions may be introduced.
-//
-// For the original RFC of this pass please see
-// https://groups.google.com/d/msg/llvm-dev/RUegaMg-iqc/wFAVxa6fCgAJ
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/ProfileSummaryInfo.h"
-#include "llvm/CodeGen/BasicBlockSectionUtils.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Module.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Support/CommandLine.h"
-
-using namespace llvm;
-
-// FIXME: This cutoff value is CPU dependent and should be moved to
-// TargetTransformInfo once we consider enabling this on other platforms.
-// The value is expressed as a ProfileSummaryInfo integer percentile cutoff.
-// Defaults to 999950, i.e. all blocks colder than 99.995 percentile are split.
-// The default was empirically determined to be optimal when considering cutoff
-// values between 99%-ile to 100%-ile with respect to iTLB and icache metrics on
-// Intel CPUs.
-static cl::opt<unsigned>
- PercentileCutoff("mfs-psi-cutoff",
- cl::desc("Percentile profile summary cutoff used to "
- "determine cold blocks. Unused if set to zero."),
- cl::init(999950), cl::Hidden);
-
-static cl::opt<unsigned> ColdCountThreshold(
- "mfs-count-threshold",
- cl::desc(
- "Minimum number of times a block must be executed to be retained."),
- cl::init(1), cl::Hidden);
-
-namespace {
-
-class MachineFunctionSplitter : public MachineFunctionPass {
-public:
- static char ID;
- MachineFunctionSplitter() : MachineFunctionPass(ID) {
- initializeMachineFunctionSplitterPass(*PassRegistry::getPassRegistry());
- }
-
- StringRef getPassName() const override {
- return "Machine Function Splitter Transformation";
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override;
-
- bool runOnMachineFunction(MachineFunction &F) override;
-};
-} // end anonymous namespace
-
-static bool isColdBlock(MachineBasicBlock &MBB,
- const MachineBlockFrequencyInfo *MBFI,
- ProfileSummaryInfo *PSI) {
- Optional<uint64_t> Count = MBFI->getBlockProfileCount(&MBB);
- if (!Count.hasValue())
- return true;
-
- if (PercentileCutoff > 0) {
- return PSI->isColdCountNthPercentile(PercentileCutoff, *Count);
- }
- return (*Count < ColdCountThreshold);
-}
-
-bool MachineFunctionSplitter::runOnMachineFunction(MachineFunction &MF) {
- // TODO: We only target functions with profile data. Static information may
- // also be considered but we don't see performance improvements yet.
- if (!MF.getFunction().hasProfileData())
- return false;
-
- // TODO: We don't split functions where a section attribute has been set
- // since the split part may not be placed in a contiguous region. It may also
- // be more beneficial to augment the linker to ensure contiguous layout of
- // split functions within the same section as specified by the attribute.
- if (!MF.getFunction().getSection().empty())
- return false;
-
- // We don't want to proceed further for cold functions
- // or functions of unknown hotness. Lukewarm functions have no prefix.
- Optional<StringRef> SectionPrefix = MF.getFunction().getSectionPrefix();
- if (SectionPrefix.hasValue() &&
- (SectionPrefix.getValue().equals("unlikely") ||
- SectionPrefix.getValue().equals("unknown"))) {
- return false;
- }
-
- // Renumbering blocks here preserves the order of the blocks as
- // sortBasicBlocksAndUpdateBranches uses the numeric identifier to sort
- // blocks. Preserving the order of blocks is essential to retaining decisions
- // made by prior passes such as MachineBlockPlacement.
- MF.RenumberBlocks();
- MF.setBBSectionsType(BasicBlockSection::Preset);
- auto *MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
- auto *PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
-
- for (auto &MBB : MF) {
- // FIXME: We retain the entry block and conservatively keep all landing pad
- // blocks as part of the original function. Once D73739 is submitted, we can
- // improve the handling of ehpads.
- if ((MBB.pred_empty() || MBB.isEHPad()))
- continue;
- if (isColdBlock(MBB, MBFI, PSI))
- MBB.setSectionID(MBBSectionID::ColdSectionID);
- }
-
- auto Comparator = [](const MachineBasicBlock &X, const MachineBasicBlock &Y) {
- return X.getSectionID().Type < Y.getSectionID().Type;
- };
- llvm::sortBasicBlocksAndUpdateBranches(MF, Comparator);
-
- return true;
-}
-
-void MachineFunctionSplitter::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<MachineModuleInfoWrapperPass>();
- AU.addRequired<MachineBlockFrequencyInfo>();
- AU.addRequired<ProfileSummaryInfoWrapperPass>();
-}
-
-char MachineFunctionSplitter::ID = 0;
-INITIALIZE_PASS(MachineFunctionSplitter, "machine-function-splitter",
- "Split machine functions using profile information", false,
- false)
-
-MachineFunctionPass *llvm::createMachineFunctionSplitterPass() {
- return new MachineFunctionSplitter();
-}
+//===-- MachineFunctionSplitter.cpp - Split machine functions //-----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// \file
+// Uses profile information to split out cold blocks.
+//
+// This pass splits out cold machine basic blocks from the parent function. This
+// implementation leverages the basic block section framework. Blocks marked
+// cold by this pass are grouped together in a separate section prefixed with
+// ".text.unlikely.*". The linker can then group these together as a cold
+// section. The split part of the function is a contiguous region identified by
+// the symbol "foo.cold". Grouping all cold blocks across functions together
+// decreases fragmentation and improves icache and itlb utilization. Note that
+// the overall changes to the binary size are negligible; only a small number of
+// additional jump instructions may be introduced.
+//
+// For the original RFC of this pass please see
+// https://groups.google.com/d/msg/llvm-dev/RUegaMg-iqc/wFAVxa6fCgAJ
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/ProfileSummaryInfo.h"
+#include "llvm/CodeGen/BasicBlockSectionUtils.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Support/CommandLine.h"
+
+using namespace llvm;
+
+// FIXME: This cutoff value is CPU dependent and should be moved to
+// TargetTransformInfo once we consider enabling this on other platforms.
+// The value is expressed as a ProfileSummaryInfo integer percentile cutoff.
+// Defaults to 999950, i.e. all blocks colder than 99.995 percentile are split.
+// The default was empirically determined to be optimal when considering cutoff
+// values between 99%-ile to 100%-ile with respect to iTLB and icache metrics on
+// Intel CPUs.
+static cl::opt<unsigned>
+ PercentileCutoff("mfs-psi-cutoff",
+ cl::desc("Percentile profile summary cutoff used to "
+ "determine cold blocks. Unused if set to zero."),
+ cl::init(999950), cl::Hidden);
+
+static cl::opt<unsigned> ColdCountThreshold(
+ "mfs-count-threshold",
+ cl::desc(
+ "Minimum number of times a block must be executed to be retained."),
+ cl::init(1), cl::Hidden);
+
+namespace {
+
+class MachineFunctionSplitter : public MachineFunctionPass {
+public:
+ static char ID;
+ MachineFunctionSplitter() : MachineFunctionPass(ID) {
+ initializeMachineFunctionSplitterPass(*PassRegistry::getPassRegistry());
+ }
+
+ StringRef getPassName() const override {
+ return "Machine Function Splitter Transformation";
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+ bool runOnMachineFunction(MachineFunction &F) override;
+};
+} // end anonymous namespace
+
+static bool isColdBlock(MachineBasicBlock &MBB,
+ const MachineBlockFrequencyInfo *MBFI,
+ ProfileSummaryInfo *PSI) {
+ Optional<uint64_t> Count = MBFI->getBlockProfileCount(&MBB);
+ if (!Count.hasValue())
+ return true;
+
+ if (PercentileCutoff > 0) {
+ return PSI->isColdCountNthPercentile(PercentileCutoff, *Count);
+ }
+ return (*Count < ColdCountThreshold);
+}
+
+bool MachineFunctionSplitter::runOnMachineFunction(MachineFunction &MF) {
+ // TODO: We only target functions with profile data. Static information may
+ // also be considered but we don't see performance improvements yet.
+ if (!MF.getFunction().hasProfileData())
+ return false;
+
+ // TODO: We don't split functions where a section attribute has been set
+ // since the split part may not be placed in a contiguous region. It may also
+ // be more beneficial to augment the linker to ensure contiguous layout of
+ // split functions within the same section as specified by the attribute.
+ if (!MF.getFunction().getSection().empty())
+ return false;
+
+ // We don't want to proceed further for cold functions
+ // or functions of unknown hotness. Lukewarm functions have no prefix.
+ Optional<StringRef> SectionPrefix = MF.getFunction().getSectionPrefix();
+ if (SectionPrefix.hasValue() &&
+ (SectionPrefix.getValue().equals("unlikely") ||
+ SectionPrefix.getValue().equals("unknown"))) {
+ return false;
+ }
+
+ // Renumbering blocks here preserves the order of the blocks as
+ // sortBasicBlocksAndUpdateBranches uses the numeric identifier to sort
+ // blocks. Preserving the order of blocks is essential to retaining decisions
+ // made by prior passes such as MachineBlockPlacement.
+ MF.RenumberBlocks();
+ MF.setBBSectionsType(BasicBlockSection::Preset);
+ auto *MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
+ auto *PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
+
+ for (auto &MBB : MF) {
+ // FIXME: We retain the entry block and conservatively keep all landing pad
+ // blocks as part of the original function. Once D73739 is submitted, we can
+ // improve the handling of ehpads.
+ if ((MBB.pred_empty() || MBB.isEHPad()))
+ continue;
+ if (isColdBlock(MBB, MBFI, PSI))
+ MBB.setSectionID(MBBSectionID::ColdSectionID);
+ }
+
+ auto Comparator = [](const MachineBasicBlock &X, const MachineBasicBlock &Y) {
+ return X.getSectionID().Type < Y.getSectionID().Type;
+ };
+ llvm::sortBasicBlocksAndUpdateBranches(MF, Comparator);
+
+ return true;
+}
+
+void MachineFunctionSplitter::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<MachineModuleInfoWrapperPass>();
+ AU.addRequired<MachineBlockFrequencyInfo>();
+ AU.addRequired<ProfileSummaryInfoWrapperPass>();
+}
+
+char MachineFunctionSplitter::ID = 0;
+INITIALIZE_PASS(MachineFunctionSplitter, "machine-function-splitter",
+ "Split machine functions using profile information", false,
+ false)
+
+MachineFunctionPass *llvm::createMachineFunctionSplitterPass() {
+ return new MachineFunctionSplitter();
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineInstr.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineInstr.cpp
index c6dd640fa1..b6cfd7dcbf 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineInstr.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineInstr.cpp
@@ -34,7 +34,7 @@
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
-#include "llvm/CodeGen/StackMaps.h"
+#include "llvm/CodeGen/StackMaps.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
@@ -117,7 +117,7 @@ void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) {
/// the MCInstrDesc.
MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid,
DebugLoc dl, bool NoImp)
- : MCID(&tid), debugLoc(std::move(dl)), DebugInstrNum(0) {
+ : MCID(&tid), debugLoc(std::move(dl)), DebugInstrNum(0) {
assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
// Reserve space for the expected number of operands.
@@ -131,12 +131,12 @@ MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid,
addImplicitDefUseOperands(MF);
}
-/// MachineInstr ctor - Copies MachineInstr arg exactly.
-/// Does not copy the number from debug instruction numbering, to preserve
-/// uniqueness.
+/// MachineInstr ctor - Copies MachineInstr arg exactly.
+/// Does not copy the number from debug instruction numbering, to preserve
+/// uniqueness.
MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI)
- : MCID(&MI.getDesc()), Info(MI.Info), debugLoc(MI.getDebugLoc()),
- DebugInstrNum(0) {
+ : MCID(&MI.getDesc()), Info(MI.Info), debugLoc(MI.getDebugLoc()),
+ DebugInstrNum(0) {
assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
CapOperands = OperandCapacity::get(MI.getNumOperands());
@@ -150,10 +150,10 @@ MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI)
setFlags(MI.Flags);
}
-void MachineInstr::moveBefore(MachineInstr *MovePos) {
- MovePos->getParent()->splice(MovePos, getParent(), getIterator());
-}
-
+void MachineInstr::moveBefore(MachineInstr *MovePos) {
+ MovePos->getParent()->splice(MovePos, getParent(), getIterator());
+}
+
/// getRegInfo - If this instruction is embedded into a MachineFunction,
/// return the MachineRegisterInfo object for the current function, otherwise
/// return null.
@@ -711,7 +711,7 @@ bool MachineInstr::isCandidateForCallSiteEntry(QueryType Type) const {
case TargetOpcode::PATCHPOINT:
case TargetOpcode::STACKMAP:
case TargetOpcode::STATEPOINT:
- case TargetOpcode::FENTRY_CALL:
+ case TargetOpcode::FENTRY_CALL:
return false;
}
return true;
@@ -841,27 +841,27 @@ const DILabel *MachineInstr::getDebugLabel() const {
}
const MachineOperand &MachineInstr::getDebugVariableOp() const {
- assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE");
+ assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE");
return getOperand(2);
}
MachineOperand &MachineInstr::getDebugVariableOp() {
- assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE");
+ assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE");
return getOperand(2);
}
const DILocalVariable *MachineInstr::getDebugVariable() const {
- assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE");
+ assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE");
return cast<DILocalVariable>(getOperand(2).getMetadata());
}
MachineOperand &MachineInstr::getDebugExpressionOp() {
- assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE");
+ assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE");
return getOperand(3);
}
const DIExpression *MachineInstr::getDebugExpression() const {
- assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE");
+ assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE");
return cast<DIExpression>(getOperand(3).getMetadata());
}
@@ -1100,12 +1100,12 @@ void MachineInstr::tieOperands(unsigned DefIdx, unsigned UseIdx) {
if (DefIdx < TiedMax)
UseMO.TiedTo = DefIdx + 1;
else {
- // Inline asm can use the group descriptors to find tied operands,
- // statepoint tied operands are trivial to match (1-1 reg def with reg use),
- // but on normal instruction, the tied def must be within the first TiedMax
+ // Inline asm can use the group descriptors to find tied operands,
+ // statepoint tied operands are trivial to match (1-1 reg def with reg use),
+ // but on normal instruction, the tied def must be within the first TiedMax
// operands.
- assert((isInlineAsm() || getOpcode() == TargetOpcode::STATEPOINT) &&
- "DefIdx out of range");
+ assert((isInlineAsm() || getOpcode() == TargetOpcode::STATEPOINT) &&
+ "DefIdx out of range");
UseMO.TiedTo = TiedMax;
}
@@ -1125,7 +1125,7 @@ unsigned MachineInstr::findTiedOperandIdx(unsigned OpIdx) const {
return MO.TiedTo - 1;
// Uses on normal instructions can be out of range.
- if (!isInlineAsm() && getOpcode() != TargetOpcode::STATEPOINT) {
+ if (!isInlineAsm() && getOpcode() != TargetOpcode::STATEPOINT) {
// Normal tied defs must be in the 0..TiedMax-1 range.
if (MO.isUse())
return TiedMax - 1;
@@ -1138,25 +1138,25 @@ unsigned MachineInstr::findTiedOperandIdx(unsigned OpIdx) const {
llvm_unreachable("Can't find tied use");
}
- if (getOpcode() == TargetOpcode::STATEPOINT) {
- // In STATEPOINT defs correspond 1-1 to GC pointer operands passed
- // on registers.
- StatepointOpers SO(this);
- unsigned CurUseIdx = SO.getFirstGCPtrIdx();
- assert(CurUseIdx != -1U && "only gc pointer statepoint operands can be tied");
- unsigned NumDefs = getNumDefs();
- for (unsigned CurDefIdx = 0; CurDefIdx < NumDefs; ++CurDefIdx) {
- while (!getOperand(CurUseIdx).isReg())
- CurUseIdx = StackMaps::getNextMetaArgIdx(this, CurUseIdx);
- if (OpIdx == CurDefIdx)
- return CurUseIdx;
- if (OpIdx == CurUseIdx)
- return CurDefIdx;
- CurUseIdx = StackMaps::getNextMetaArgIdx(this, CurUseIdx);
- }
- llvm_unreachable("Can't find tied use");
- }
-
+ if (getOpcode() == TargetOpcode::STATEPOINT) {
+ // In STATEPOINT defs correspond 1-1 to GC pointer operands passed
+ // on registers.
+ StatepointOpers SO(this);
+ unsigned CurUseIdx = SO.getFirstGCPtrIdx();
+ assert(CurUseIdx != -1U && "only gc pointer statepoint operands can be tied");
+ unsigned NumDefs = getNumDefs();
+ for (unsigned CurDefIdx = 0; CurDefIdx < NumDefs; ++CurDefIdx) {
+ while (!getOperand(CurUseIdx).isReg())
+ CurUseIdx = StackMaps::getNextMetaArgIdx(this, CurUseIdx);
+ if (OpIdx == CurDefIdx)
+ return CurUseIdx;
+ if (OpIdx == CurUseIdx)
+ return CurDefIdx;
+ CurUseIdx = StackMaps::getNextMetaArgIdx(this, CurUseIdx);
+ }
+ llvm_unreachable("Can't find tied use");
+ }
+
// Now deal with inline asm by parsing the operand group descriptor flags.
// Find the beginning of each operand group.
SmallVector<unsigned, 8> GroupIdx;
@@ -1240,7 +1240,7 @@ bool MachineInstr::isSafeToMove(AAResults *AA, bool &SawStore) const {
// See if this instruction does a load. If so, we have to guarantee that the
// loaded value doesn't change between the load and the its intended
- // destination. The check for isInvariantLoad gives the target the chance to
+ // destination. The check for isInvariantLoad gives the target the chance to
// classify the load as always returning a constant, e.g. a constant pool
// load.
if (mayLoad() && !isDereferenceableInvariantLoad(AA))
@@ -1251,21 +1251,21 @@ bool MachineInstr::isSafeToMove(AAResults *AA, bool &SawStore) const {
return true;
}
-static bool MemOperandsHaveAlias(const MachineFrameInfo &MFI, AAResults *AA,
- bool UseTBAA, const MachineMemOperand *MMOa,
- const MachineMemOperand *MMOb) {
- // The following interface to AA is fashioned after DAGCombiner::isAlias and
- // operates with MachineMemOperand offset with some important assumptions:
+static bool MemOperandsHaveAlias(const MachineFrameInfo &MFI, AAResults *AA,
+ bool UseTBAA, const MachineMemOperand *MMOa,
+ const MachineMemOperand *MMOb) {
+ // The following interface to AA is fashioned after DAGCombiner::isAlias and
+ // operates with MachineMemOperand offset with some important assumptions:
// - LLVM fundamentally assumes flat address spaces.
- // - MachineOperand offset can *only* result from legalization and cannot
- // affect queries other than the trivial case of overlap checking.
- // - These offsets never wrap and never step outside of allocated objects.
+ // - MachineOperand offset can *only* result from legalization and cannot
+ // affect queries other than the trivial case of overlap checking.
+ // - These offsets never wrap and never step outside of allocated objects.
// - There should never be any negative offsets here.
//
// FIXME: Modify API to hide this math from "user"
- // Even before we go to AA we can reason locally about some memory objects. It
- // can save compile time, and possibly catch some corner cases not currently
- // covered.
+ // Even before we go to AA we can reason locally about some memory objects. It
+ // can save compile time, and possibly catch some corner cases not currently
+ // covered.
int64_t OffsetA = MMOa->getOffset();
int64_t OffsetB = MMOb->getOffset();
@@ -1307,63 +1307,63 @@ static bool MemOperandsHaveAlias(const MachineFrameInfo &MFI, AAResults *AA,
assert((OffsetA >= 0) && "Negative MachineMemOperand offset");
assert((OffsetB >= 0) && "Negative MachineMemOperand offset");
- int64_t OverlapA =
- KnownWidthA ? WidthA + OffsetA - MinOffset : MemoryLocation::UnknownSize;
- int64_t OverlapB =
- KnownWidthB ? WidthB + OffsetB - MinOffset : MemoryLocation::UnknownSize;
+ int64_t OverlapA =
+ KnownWidthA ? WidthA + OffsetA - MinOffset : MemoryLocation::UnknownSize;
+ int64_t OverlapB =
+ KnownWidthB ? WidthB + OffsetB - MinOffset : MemoryLocation::UnknownSize;
AliasResult AAResult = AA->alias(
- MemoryLocation(ValA, OverlapA, UseTBAA ? MMOa->getAAInfo() : AAMDNodes()),
+ MemoryLocation(ValA, OverlapA, UseTBAA ? MMOa->getAAInfo() : AAMDNodes()),
MemoryLocation(ValB, OverlapB,
UseTBAA ? MMOb->getAAInfo() : AAMDNodes()));
return (AAResult != NoAlias);
}
-bool MachineInstr::mayAlias(AAResults *AA, const MachineInstr &Other,
- bool UseTBAA) const {
- const MachineFunction *MF = getMF();
- const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
- const MachineFrameInfo &MFI = MF->getFrameInfo();
-
- // Exclude call instruction which may alter the memory but can not be handled
- // by this function.
- if (isCall() || Other.isCall())
- return true;
-
- // If neither instruction stores to memory, they can't alias in any
- // meaningful way, even if they read from the same address.
- if (!mayStore() && !Other.mayStore())
- return false;
-
- // Both instructions must be memory operations to be able to alias.
- if (!mayLoadOrStore() || !Other.mayLoadOrStore())
- return false;
-
- // Let the target decide if memory accesses cannot possibly overlap.
- if (TII->areMemAccessesTriviallyDisjoint(*this, Other))
- return false;
-
- // Memory operations without memory operands may access anything. Be
- // conservative and assume `MayAlias`.
- if (memoperands_empty() || Other.memoperands_empty())
- return true;
-
- // Skip if there are too many memory operands.
- auto NumChecks = getNumMemOperands() * Other.getNumMemOperands();
- if (NumChecks > TII->getMemOperandAACheckLimit())
- return true;
-
- // Check each pair of memory operands from both instructions, which can't
- // alias only if all pairs won't alias.
- for (auto *MMOa : memoperands())
- for (auto *MMOb : Other.memoperands())
- if (MemOperandsHaveAlias(MFI, AA, UseTBAA, MMOa, MMOb))
- return true;
-
- return false;
-}
-
+bool MachineInstr::mayAlias(AAResults *AA, const MachineInstr &Other,
+ bool UseTBAA) const {
+ const MachineFunction *MF = getMF();
+ const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
+ const MachineFrameInfo &MFI = MF->getFrameInfo();
+
+ // Exclude call instruction which may alter the memory but can not be handled
+ // by this function.
+ if (isCall() || Other.isCall())
+ return true;
+
+ // If neither instruction stores to memory, they can't alias in any
+ // meaningful way, even if they read from the same address.
+ if (!mayStore() && !Other.mayStore())
+ return false;
+
+ // Both instructions must be memory operations to be able to alias.
+ if (!mayLoadOrStore() || !Other.mayLoadOrStore())
+ return false;
+
+ // Let the target decide if memory accesses cannot possibly overlap.
+ if (TII->areMemAccessesTriviallyDisjoint(*this, Other))
+ return false;
+
+ // Memory operations without memory operands may access anything. Be
+ // conservative and assume `MayAlias`.
+ if (memoperands_empty() || Other.memoperands_empty())
+ return true;
+
+ // Skip if there are too many memory operands.
+ auto NumChecks = getNumMemOperands() * Other.getNumMemOperands();
+ if (NumChecks > TII->getMemOperandAACheckLimit())
+ return true;
+
+ // Check each pair of memory operands from both instructions, which can't
+ // alias only if all pairs won't alias.
+ for (auto *MMOa : memoperands())
+ for (auto *MMOb : Other.memoperands())
+ if (MemOperandsHaveAlias(MFI, AA, UseTBAA, MMOa, MMOb))
+ return true;
+
+ return false;
+}
+
/// hasOrderedMemoryRef - Return true if this instruction may have an ordered
/// or volatile memory reference, or if the information describing the memory
/// reference is not available. Return false if it is known to have no ordered
@@ -1462,8 +1462,8 @@ bool MachineInstr::hasUnmodeledSideEffects() const {
}
bool MachineInstr::isLoadFoldBarrier() const {
- return mayStore() || isCall() ||
- (hasUnmodeledSideEffects() && !isPseudoProbe());
+ return mayStore() || isCall() ||
+ (hasUnmodeledSideEffects() && !isPseudoProbe());
}
/// allDefsAreDead - Return true if all the defs of this instruction are dead.
@@ -1492,8 +1492,8 @@ void MachineInstr::copyImplicitOps(MachineFunction &MF,
bool MachineInstr::hasComplexRegisterTies() const {
const MCInstrDesc &MCID = getDesc();
- if (MCID.Opcode == TargetOpcode::STATEPOINT)
- return true;
+ if (MCID.Opcode == TargetOpcode::STATEPOINT)
+ return true;
for (unsigned I = 0, E = getNumOperands(); I < E; ++I) {
const auto &Operand = getOperand(I);
if (!Operand.isReg() || Operand.isDef())
@@ -1800,12 +1800,12 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
HeapAllocMarker->printAsOperand(OS, MST);
}
- if (DebugInstrNum) {
- if (!FirstOp)
- OS << ",";
- OS << " debug-instr-number " << DebugInstrNum;
- }
-
+ if (DebugInstrNum) {
+ if (!FirstOp)
+ OS << ",";
+ OS << " debug-instr-number " << DebugInstrNum;
+ }
+
if (!SkipDebugLoc) {
if (const DebugLoc &DL = getDebugLoc()) {
if (!FirstOp)
@@ -2280,9 +2280,9 @@ MachineInstr::getFoldedRestoreSize(const TargetInstrInfo *TII) const {
return getSpillSlotSize(Accesses, getMF()->getFrameInfo());
return None;
}
-
-unsigned MachineInstr::getDebugInstrNum() {
- if (DebugInstrNum == 0)
- DebugInstrNum = getParent()->getParent()->getNewDebugInstrNum();
- return DebugInstrNum;
-}
+
+unsigned MachineInstr::getDebugInstrNum() {
+ if (DebugInstrNum == 0)
+ DebugInstrNum = getParent()->getParent()->getNewDebugInstrNum();
+ return DebugInstrNum;
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineLICM.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineLICM.cpp
index a752e40595..c06bc39b49 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineLICM.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineLICM.cpp
@@ -42,7 +42,7 @@
#include "llvm/IR/DebugLoc.h"
#include "llvm/InitializePasses.h"
#include "llvm/MC/MCInstrDesc.h"
-#include "llvm/MC/MCRegister.h"
+#include "llvm/MC/MCRegister.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
@@ -91,7 +91,7 @@ static cl::opt<UseBFI>
DisableHoistingToHotterBlocks("disable-hoisting-to-hotter-blocks",
cl::desc("Disable hoisting instructions to"
" hotter blocks"),
- cl::init(UseBFI::PGO), cl::Hidden,
+ cl::init(UseBFI::PGO), cl::Hidden,
cl::values(clEnumValN(UseBFI::None, "none",
"disable the feature"),
clEnumValN(UseBFI::PGO, "pgo",
@@ -146,7 +146,7 @@ namespace {
}
// Track 'estimated' register pressure.
- SmallSet<Register, 32> RegSeen;
+ SmallSet<Register, 32> RegSeen;
SmallVector<unsigned, 8> RegPressure;
// Register pressure "limit" per register pressure set. If the pressure
@@ -157,7 +157,7 @@ namespace {
SmallVector<SmallVector<unsigned, 8>, 16> BackTrace;
// For each opcode, keep a list of potential CSE instructions.
- DenseMap<unsigned, std::vector<MachineInstr *>> CSEMap;
+ DenseMap<unsigned, std::vector<MachineInstr *>> CSEMap;
enum {
SpeculateFalse = 0,
@@ -213,7 +213,7 @@ namespace {
BitVector &PhysRegClobbers, SmallSet<int, 32> &StoredFIs,
SmallVectorImpl<CandidateInfo> &Candidates);
- void AddToLiveIns(MCRegister Reg);
+ void AddToLiveIns(MCRegister Reg);
bool IsLICMCandidate(MachineInstr &I);
@@ -222,7 +222,7 @@ namespace {
bool HasLoopPHIUse(const MachineInstr *MI) const;
bool HasHighOperandLatency(MachineInstr &MI, unsigned DefIdx,
- Register Reg) const;
+ Register Reg) const;
bool IsCheapInstruction(MachineInstr &MI) const;
@@ -259,12 +259,12 @@ namespace {
MachineInstr *ExtractHoistableLoad(MachineInstr *MI);
- MachineInstr *LookForDuplicate(const MachineInstr *MI,
- std::vector<MachineInstr *> &PrevMIs);
+ MachineInstr *LookForDuplicate(const MachineInstr *MI,
+ std::vector<MachineInstr *> &PrevMIs);
- bool
- EliminateCSE(MachineInstr *MI,
- DenseMap<unsigned, std::vector<MachineInstr *>>::iterator &CI);
+ bool
+ EliminateCSE(MachineInstr *MI,
+ DenseMap<unsigned, std::vector<MachineInstr *>>::iterator &CI);
bool MayCSE(MachineInstr *MI);
@@ -604,7 +604,7 @@ void MachineLICMBase::HoistRegionPostRA() {
/// Add register 'Reg' to the livein sets of BBs in the current loop, and make
/// sure it is not killed by any instructions in the loop.
-void MachineLICMBase::AddToLiveIns(MCRegister Reg) {
+void MachineLICMBase::AddToLiveIns(MCRegister Reg) {
for (MachineBasicBlock *BB : CurLoop->getBlocks()) {
if (!BB->isLiveIn(Reg))
BB->addLiveIn(Reg);
@@ -800,13 +800,13 @@ void MachineLICMBase::SinkIntoLoop() {
I != Preheader->instr_end(); ++I) {
// We need to ensure that we can safely move this instruction into the loop.
// As such, it must not have side-effects, e.g. such as a call has.
- LLVM_DEBUG(dbgs() << "LICM: Analysing sink candidate: " << *I);
- if (IsLoopInvariantInst(*I) && !HasLoopPHIUse(&*I)) {
- LLVM_DEBUG(dbgs() << "LICM: Added as sink candidate.\n");
+ LLVM_DEBUG(dbgs() << "LICM: Analysing sink candidate: " << *I);
+ if (IsLoopInvariantInst(*I) && !HasLoopPHIUse(&*I)) {
+ LLVM_DEBUG(dbgs() << "LICM: Added as sink candidate.\n");
Candidates.push_back(&*I);
- continue;
- }
- LLVM_DEBUG(dbgs() << "LICM: Not added as sink candidate.\n");
+ continue;
+ }
+ LLVM_DEBUG(dbgs() << "LICM: Not added as sink candidate.\n");
}
for (MachineInstr *I : Candidates) {
@@ -816,11 +816,11 @@ void MachineLICMBase::SinkIntoLoop() {
if (!MRI->hasOneDef(MO.getReg()))
continue;
bool CanSink = true;
- MachineBasicBlock *SinkBlock = nullptr;
- LLVM_DEBUG(dbgs() << "LICM: Try sinking: " << *I);
-
+ MachineBasicBlock *SinkBlock = nullptr;
+ LLVM_DEBUG(dbgs() << "LICM: Try sinking: " << *I);
+
for (MachineInstr &MI : MRI->use_instructions(MO.getReg())) {
- LLVM_DEBUG(dbgs() << "LICM: Analysing use: "; MI.dump());
+ LLVM_DEBUG(dbgs() << "LICM: Analysing use: "; MI.dump());
// FIXME: Come up with a proper cost model that estimates whether sinking
// the instruction (and thus possibly executing it on every loop
// iteration) is more expensive than a register.
@@ -829,40 +829,40 @@ void MachineLICMBase::SinkIntoLoop() {
CanSink = false;
break;
}
- if (!SinkBlock) {
- SinkBlock = MI.getParent();
- LLVM_DEBUG(dbgs() << "LICM: Setting sink block to: "
- << printMBBReference(*SinkBlock) << "\n");
+ if (!SinkBlock) {
+ SinkBlock = MI.getParent();
+ LLVM_DEBUG(dbgs() << "LICM: Setting sink block to: "
+ << printMBBReference(*SinkBlock) << "\n");
continue;
}
- SinkBlock = DT->findNearestCommonDominator(SinkBlock, MI.getParent());
- if (!SinkBlock) {
- LLVM_DEBUG(dbgs() << "LICM: Can't find nearest dominator\n");
+ SinkBlock = DT->findNearestCommonDominator(SinkBlock, MI.getParent());
+ if (!SinkBlock) {
+ LLVM_DEBUG(dbgs() << "LICM: Can't find nearest dominator\n");
CanSink = false;
break;
}
- LLVM_DEBUG(dbgs() << "LICM: Setting nearest common dom block: " <<
- printMBBReference(*SinkBlock) << "\n");
+ LLVM_DEBUG(dbgs() << "LICM: Setting nearest common dom block: " <<
+ printMBBReference(*SinkBlock) << "\n");
+ }
+ if (!CanSink) {
+ LLVM_DEBUG(dbgs() << "LICM: Can't sink instruction.\n");
+ continue;
+ }
+ if (!SinkBlock) {
+ LLVM_DEBUG(dbgs() << "LICM: Not sinking, can't find sink block.\n");
+ continue;
}
- if (!CanSink) {
- LLVM_DEBUG(dbgs() << "LICM: Can't sink instruction.\n");
+ if (SinkBlock == Preheader) {
+ LLVM_DEBUG(dbgs() << "LICM: Not sinking, sink block is the preheader\n");
continue;
- }
- if (!SinkBlock) {
- LLVM_DEBUG(dbgs() << "LICM: Not sinking, can't find sink block.\n");
- continue;
- }
- if (SinkBlock == Preheader) {
- LLVM_DEBUG(dbgs() << "LICM: Not sinking, sink block is the preheader\n");
- continue;
- }
-
- LLVM_DEBUG(dbgs() << "LICM: Sinking to " << printMBBReference(*SinkBlock)
- << " from " << printMBBReference(*I->getParent())
- << ": " << *I);
- SinkBlock->splice(SinkBlock->getFirstNonPHI(), Preheader, I);
-
- // The instruction is moved from its basic block, so do not retain the
+ }
+
+ LLVM_DEBUG(dbgs() << "LICM: Sinking to " << printMBBReference(*SinkBlock)
+ << " from " << printMBBReference(*I->getParent())
+ << ": " << *I);
+ SinkBlock->splice(SinkBlock->getFirstNonPHI(), Preheader, I);
+
+ // The instruction is moved from its basic block, so do not retain the
// debug information.
assert(!I->isDebugInstr() && "Should not sink debug inst");
I->setDebugLoc(DebugLoc());
@@ -1000,7 +1000,7 @@ static bool isInvariantStore(const MachineInstr &MI,
Reg = TRI->lookThruCopyLike(MO.getReg(), MRI);
if (Register::isVirtualRegister(Reg))
return false;
- if (!TRI->isCallerPreservedPhysReg(Reg.asMCReg(), *MI.getMF()))
+ if (!TRI->isCallerPreservedPhysReg(Reg.asMCReg(), *MI.getMF()))
return false;
else
FoundCallerPresReg = true;
@@ -1030,7 +1030,7 @@ static bool isCopyFeedingInvariantStore(const MachineInstr &MI,
if (Register::isVirtualRegister(CopySrcReg))
return false;
- if (!TRI->isCallerPreservedPhysReg(CopySrcReg.asMCReg(), *MF))
+ if (!TRI->isCallerPreservedPhysReg(CopySrcReg.asMCReg(), *MF))
return false;
Register CopyDstReg = MI.getOperand(0).getReg();
@@ -1052,7 +1052,7 @@ bool MachineLICMBase::IsLICMCandidate(MachineInstr &I) {
bool DontMoveAcrossStore = true;
if ((!I.isSafeToMove(AA, DontMoveAcrossStore)) &&
!(HoistConstStores && isInvariantStore(I, TRI, MRI))) {
- LLVM_DEBUG(dbgs() << "LICM: Instruction not safe to move.\n");
+ LLVM_DEBUG(dbgs() << "LICM: Instruction not safe to move.\n");
return false;
}
@@ -1063,28 +1063,28 @@ bool MachineLICMBase::IsLICMCandidate(MachineInstr &I) {
// indexed load from a jump table.
// Stores and side effects are already checked by isSafeToMove.
if (I.mayLoad() && !mayLoadFromGOTOrConstantPool(I) &&
- !IsGuaranteedToExecute(I.getParent())) {
- LLVM_DEBUG(dbgs() << "LICM: Load not guaranteed to execute.\n");
+ !IsGuaranteedToExecute(I.getParent())) {
+ LLVM_DEBUG(dbgs() << "LICM: Load not guaranteed to execute.\n");
return false;
- }
-
- // Convergent attribute has been used on operations that involve inter-thread
- // communication which results are implicitly affected by the enclosing
- // control flows. It is not safe to hoist or sink such operations across
- // control flow.
- if (I.isConvergent())
- return false;
-
+ }
+
+ // Convergent attribute has been used on operations that involve inter-thread
+ // communication which results are implicitly affected by the enclosing
+ // control flows. It is not safe to hoist or sink such operations across
+ // control flow.
+ if (I.isConvergent())
+ return false;
+
return true;
}
/// Returns true if the instruction is loop invariant.
bool MachineLICMBase::IsLoopInvariantInst(MachineInstr &I) {
- if (!IsLICMCandidate(I)) {
- LLVM_DEBUG(dbgs() << "LICM: Instruction not a LICM candidate\n");
+ if (!IsLICMCandidate(I)) {
+ LLVM_DEBUG(dbgs() << "LICM: Instruction not a LICM candidate\n");
return false;
}
- return CurLoop->isLoopInvariant(I);
+ return CurLoop->isLoopInvariant(I);
}
/// Return true if the specified instruction is used by a phi node and hoisting
@@ -1124,8 +1124,8 @@ bool MachineLICMBase::HasLoopPHIUse(const MachineInstr *MI) const {
/// Compute operand latency between a def of 'Reg' and an use in the current
/// loop, return true if the target considered it high.
-bool MachineLICMBase::HasHighOperandLatency(MachineInstr &MI, unsigned DefIdx,
- Register Reg) const {
+bool MachineLICMBase::HasHighOperandLatency(MachineInstr &MI, unsigned DefIdx,
+ Register Reg) const {
if (MRI->use_nodbg_empty(Reg))
return false;
@@ -1385,10 +1385,10 @@ void MachineLICMBase::InitCSEMap(MachineBasicBlock *BB) {
/// Find an instruction amount PrevMIs that is a duplicate of MI.
/// Return this instruction if it's found.
-MachineInstr *
+MachineInstr *
MachineLICMBase::LookForDuplicate(const MachineInstr *MI,
- std::vector<MachineInstr *> &PrevMIs) {
- for (MachineInstr *PrevMI : PrevMIs)
+ std::vector<MachineInstr *> &PrevMIs) {
+ for (MachineInstr *PrevMI : PrevMIs)
if (TII->produceSameValue(*MI, *PrevMI, (PreRegAlloc ? MRI : nullptr)))
return PrevMI;
@@ -1399,15 +1399,15 @@ MachineLICMBase::LookForDuplicate(const MachineInstr *MI,
/// computes the same value. If it's found, do a RAU on with the definition of
/// the existing instruction rather than hoisting the instruction to the
/// preheader.
-bool MachineLICMBase::EliminateCSE(
- MachineInstr *MI,
- DenseMap<unsigned, std::vector<MachineInstr *>>::iterator &CI) {
+bool MachineLICMBase::EliminateCSE(
+ MachineInstr *MI,
+ DenseMap<unsigned, std::vector<MachineInstr *>>::iterator &CI) {
// Do not CSE implicit_def so ProcessImplicitDefs can properly propagate
// the undef property onto uses.
if (CI == CSEMap.end() || MI->isImplicitDef())
return false;
- if (MachineInstr *Dup = LookForDuplicate(MI, CI->second)) {
+ if (MachineInstr *Dup = LookForDuplicate(MI, CI->second)) {
LLVM_DEBUG(dbgs() << "CSEing " << *MI << " with " << *Dup);
// Replace virtual registers defined by MI by their counterparts defined
@@ -1447,9 +1447,9 @@ bool MachineLICMBase::EliminateCSE(
Register DupReg = Dup->getOperand(Idx).getReg();
MRI->replaceRegWith(Reg, DupReg);
MRI->clearKillFlags(DupReg);
- // Clear Dup dead flag if any, we reuse it for Reg.
- if (!MRI->use_nodbg_empty(DupReg))
- Dup->getOperand(Idx).setIsDead(false);
+ // Clear Dup dead flag if any, we reuse it for Reg.
+ if (!MRI->use_nodbg_empty(DupReg))
+ Dup->getOperand(Idx).setIsDead(false);
}
MI->eraseFromParent();
@@ -1463,8 +1463,8 @@ bool MachineLICMBase::EliminateCSE(
/// the loop.
bool MachineLICMBase::MayCSE(MachineInstr *MI) {
unsigned Opcode = MI->getOpcode();
- DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
- CSEMap.find(Opcode);
+ DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
+ CSEMap.find(Opcode);
// Do not CSE implicit_def so ProcessImplicitDefs can properly propagate
// the undef property onto uses.
if (CI == CSEMap.end() || MI->isImplicitDef())
@@ -1518,8 +1518,8 @@ bool MachineLICMBase::Hoist(MachineInstr *MI, MachineBasicBlock *Preheader) {
// Look for opportunity to CSE the hoisted instruction.
unsigned Opcode = MI->getOpcode();
- DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
- CSEMap.find(Opcode);
+ DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
+ CSEMap.find(Opcode);
if (!EliminateCSE(MI, CI)) {
// Otherwise, splice the instruction to the preheader.
Preheader->splice(Preheader->getFirstTerminator(),MI->getParent(),MI);
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineLoopInfo.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineLoopInfo.cpp
index 29433db9b9..78480d0e14 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineLoopInfo.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineLoopInfo.cpp
@@ -16,14 +16,14 @@
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/Analysis/LoopInfoImpl.h"
#include "llvm/CodeGen/MachineDominators.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-
+
using namespace llvm;
// Explicitly instantiate methods in LoopInfoImpl.h for MI-level Loops.
@@ -149,59 +149,59 @@ MachineLoopInfo::findLoopPreheader(MachineLoop *L,
return Preheader;
}
-bool MachineLoop::isLoopInvariant(MachineInstr &I) const {
- MachineFunction *MF = I.getParent()->getParent();
- MachineRegisterInfo *MRI = &MF->getRegInfo();
- const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
-
- // The instruction is loop invariant if all of its operands are.
- for (const MachineOperand &MO : I.operands()) {
- if (!MO.isReg())
- continue;
-
- Register Reg = MO.getReg();
- if (Reg == 0) continue;
-
- // An instruction that uses or defines a physical register can't e.g. be
- // hoisted, so mark this as not invariant.
- if (Register::isPhysicalRegister(Reg)) {
- if (MO.isUse()) {
- // If the physreg has no defs anywhere, it's just an ambient register
- // and we can freely move its uses. Alternatively, if it's allocatable,
- // it could get allocated to something with a def during allocation.
- // However, if the physreg is known to always be caller saved/restored
- // then this use is safe to hoist.
- if (!MRI->isConstantPhysReg(Reg) &&
- !(TRI->isCallerPreservedPhysReg(Reg.asMCReg(), *I.getMF())))
- return false;
- // Otherwise it's safe to move.
- continue;
- } else if (!MO.isDead()) {
- // A def that isn't dead can't be moved.
- return false;
- } else if (getHeader()->isLiveIn(Reg)) {
- // If the reg is live into the loop, we can't hoist an instruction
- // which would clobber it.
- return false;
- }
- }
-
- if (!MO.isUse())
- continue;
-
- assert(MRI->getVRegDef(Reg) &&
- "Machine instr not mapped for this vreg?!");
-
- // If the loop contains the definition of an operand, then the instruction
- // isn't loop invariant.
- if (contains(MRI->getVRegDef(Reg)))
- return false;
- }
-
- // If we got this far, the instruction is loop invariant!
- return true;
-}
-
+bool MachineLoop::isLoopInvariant(MachineInstr &I) const {
+ MachineFunction *MF = I.getParent()->getParent();
+ MachineRegisterInfo *MRI = &MF->getRegInfo();
+ const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
+
+ // The instruction is loop invariant if all of its operands are.
+ for (const MachineOperand &MO : I.operands()) {
+ if (!MO.isReg())
+ continue;
+
+ Register Reg = MO.getReg();
+ if (Reg == 0) continue;
+
+ // An instruction that uses or defines a physical register can't e.g. be
+ // hoisted, so mark this as not invariant.
+ if (Register::isPhysicalRegister(Reg)) {
+ if (MO.isUse()) {
+ // If the physreg has no defs anywhere, it's just an ambient register
+ // and we can freely move its uses. Alternatively, if it's allocatable,
+ // it could get allocated to something with a def during allocation.
+ // However, if the physreg is known to always be caller saved/restored
+ // then this use is safe to hoist.
+ if (!MRI->isConstantPhysReg(Reg) &&
+ !(TRI->isCallerPreservedPhysReg(Reg.asMCReg(), *I.getMF())))
+ return false;
+ // Otherwise it's safe to move.
+ continue;
+ } else if (!MO.isDead()) {
+ // A def that isn't dead can't be moved.
+ return false;
+ } else if (getHeader()->isLiveIn(Reg)) {
+ // If the reg is live into the loop, we can't hoist an instruction
+ // which would clobber it.
+ return false;
+ }
+ }
+
+ if (!MO.isUse())
+ continue;
+
+ assert(MRI->getVRegDef(Reg) &&
+ "Machine instr not mapped for this vreg?!");
+
+ // If the loop contains the definition of an operand, then the instruction
+ // isn't loop invariant.
+ if (contains(MRI->getVRegDef(Reg)))
+ return false;
+ }
+
+ // If we got this far, the instruction is loop invariant!
+ return true;
+}
+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void MachineLoop::dump() const {
print(dbgs());
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineModuleInfo.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineModuleInfo.cpp
index 597fb730cb..5565b9cede 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineModuleInfo.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineModuleInfo.cpp
@@ -104,8 +104,8 @@ ArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) {
BBCallbacks.back().setMap(this);
Entry.Index = BBCallbacks.size() - 1;
Entry.Fn = BB->getParent();
- MCSymbol *Sym = BB->hasAddressTaken() ? Context.createNamedTempSymbol()
- : Context.createTempSymbol();
+ MCSymbol *Sym = BB->hasAddressTaken() ? Context.createNamedTempSymbol()
+ : Context.createTempSymbol();
Entry.Symbols.push_back(Sym);
return Entry.Symbols;
}
@@ -144,7 +144,7 @@ void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) {
BBCallbacks[OldEntry.Index] = nullptr; // Update the callback.
// Otherwise, we need to add the old symbols to the new block's set.
- llvm::append_range(NewEntry.Symbols, OldEntry.Symbols);
+ llvm::append_range(NewEntry.Symbols, OldEntry.Symbols);
}
void MMIAddrLabelMapCallbackPtr::deleted() {
@@ -170,7 +170,7 @@ void MachineModuleInfo::finalize() {
AddrLabelSymbols = nullptr;
Context.reset();
- // We don't clear the ExternalContext.
+ // We don't clear the ExternalContext.
delete ObjFileMMI;
ObjFileMMI = nullptr;
@@ -179,8 +179,8 @@ void MachineModuleInfo::finalize() {
MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI)
: TM(std::move(MMI.TM)),
Context(MMI.TM.getMCAsmInfo(), MMI.TM.getMCRegisterInfo(),
- MMI.TM.getObjFileLowering(), nullptr, nullptr, false),
- MachineFunctions(std::move(MMI.MachineFunctions)) {
+ MMI.TM.getObjFileLowering(), nullptr, nullptr, false),
+ MachineFunctions(std::move(MMI.MachineFunctions)) {
ObjFileMMI = MMI.ObjFileMMI;
CurCallSite = MMI.CurCallSite;
UsesMSVCFloatingPoint = MMI.UsesMSVCFloatingPoint;
@@ -188,7 +188,7 @@ MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI)
HasSplitStack = MMI.HasSplitStack;
HasNosplitStack = MMI.HasNosplitStack;
AddrLabelSymbols = MMI.AddrLabelSymbols;
- ExternalContext = MMI.ExternalContext;
+ ExternalContext = MMI.ExternalContext;
TheModule = MMI.TheModule;
}
@@ -198,14 +198,14 @@ MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM)
initialize();
}
-MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM,
- MCContext *ExtContext)
- : TM(*TM), Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(),
- TM->getObjFileLowering(), nullptr, nullptr, false),
- ExternalContext(ExtContext) {
- initialize();
-}
-
+MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM,
+ MCContext *ExtContext)
+ : TM(*TM), Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(),
+ TM->getObjFileLowering(), nullptr, nullptr, false),
+ ExternalContext(ExtContext) {
+ initialize();
+}
+
MachineModuleInfo::~MachineModuleInfo() { finalize(); }
//===- Address of Block Management ----------------------------------------===//
@@ -214,7 +214,7 @@ ArrayRef<MCSymbol *>
MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock *BB) {
// Lazily create AddrLabelSymbols.
if (!AddrLabelSymbols)
- AddrLabelSymbols = new MMIAddrLabelMap(getContext());
+ AddrLabelSymbols = new MMIAddrLabelMap(getContext());
return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast<BasicBlock*>(BB));
}
@@ -306,12 +306,12 @@ MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
}
-MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
- const LLVMTargetMachine *TM, MCContext *ExtContext)
- : ImmutablePass(ID), MMI(TM, ExtContext) {
- initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
-}
-
+MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
+ const LLVMTargetMachine *TM, MCContext *ExtContext)
+ : ImmutablePass(ID), MMI(TM, ExtContext) {
+ initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
+}
+
// Handle the Pass registration stuff necessary to use DataLayout's.
INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo",
"Machine Module Information", false, false)
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineOperand.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineOperand.cpp
index 5c89e3ea73..9b09f52732 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineOperand.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineOperand.cpp
@@ -85,7 +85,7 @@ void MachineOperand::substVirtReg(Register Reg, unsigned SubIdx,
}
void MachineOperand::substPhysReg(MCRegister Reg, const TargetRegisterInfo &TRI) {
- assert(Register::isPhysicalRegister(Reg));
+ assert(Register::isPhysicalRegister(Reg));
if (getSubReg()) {
Reg = TRI.getSubReg(Reg, getSubReg());
// Note that getSubReg() may return 0 if the sub-register doesn't exist.
@@ -153,25 +153,25 @@ void MachineOperand::removeRegFromUses() {
/// ChangeToImmediate - Replace this operand with a new immediate operand of
/// the specified value. If an operand is known to be an immediate already,
/// the setImm method should be used.
-void MachineOperand::ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags) {
+void MachineOperand::ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags) {
assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm");
removeRegFromUses();
OpKind = MO_Immediate;
Contents.ImmVal = ImmVal;
- setTargetFlags(TargetFlags);
+ setTargetFlags(TargetFlags);
}
-void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm,
- unsigned TargetFlags) {
+void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm,
+ unsigned TargetFlags) {
assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm");
removeRegFromUses();
OpKind = MO_FPImmediate;
Contents.CFP = FPImm;
- setTargetFlags(TargetFlags);
+ setTargetFlags(TargetFlags);
}
void MachineOperand::ChangeToES(const char *SymName,
@@ -200,7 +200,7 @@ void MachineOperand::ChangeToGA(const GlobalValue *GV, int64_t Offset,
setTargetFlags(TargetFlags);
}
-void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym, unsigned TargetFlags) {
+void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym, unsigned TargetFlags) {
assert((!isReg() || !isTied()) &&
"Cannot change a tied operand into an MCSymbol");
@@ -208,10 +208,10 @@ void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym, unsigned TargetFlags) {
OpKind = MO_MCSymbol;
Contents.Sym = Sym;
- setTargetFlags(TargetFlags);
+ setTargetFlags(TargetFlags);
}
-void MachineOperand::ChangeToFrameIndex(int Idx, unsigned TargetFlags) {
+void MachineOperand::ChangeToFrameIndex(int Idx, unsigned TargetFlags) {
assert((!isReg() || !isTied()) &&
"Cannot change a tied operand into a FrameIndex");
@@ -219,7 +219,7 @@ void MachineOperand::ChangeToFrameIndex(int Idx, unsigned TargetFlags) {
OpKind = MO_FrameIndex;
setIndex(Idx);
- setTargetFlags(TargetFlags);
+ setTargetFlags(TargetFlags);
}
void MachineOperand::ChangeToTargetIndex(unsigned Idx, int64_t Offset,
@@ -420,11 +420,11 @@ static const char *getTargetIndexName(const MachineFunction &MF, int Index) {
return nullptr;
}
-const char *MachineOperand::getTargetIndexName() const {
- const MachineFunction *MF = getMFIfAvailable(*this);
- return MF ? ::getTargetIndexName(*MF, this->getIndex()) : nullptr;
-}
-
+const char *MachineOperand::getTargetIndexName() const {
+ const MachineFunction *MF = getMFIfAvailable(*this);
+ return MF ? ::getTargetIndexName(*MF, this->getIndex()) : nullptr;
+}
+
static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) {
auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
for (const auto &I : Flags) {
@@ -833,7 +833,7 @@ void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
OS << "target-index(";
const char *Name = "<unknown>";
if (const MachineFunction *MF = getMFIfAvailable(*this))
- if (const auto *TargetIndexName = ::getTargetIndexName(*MF, getIndex()))
+ if (const auto *TargetIndexName = ::getTargetIndexName(*MF, getIndex()))
Name = TargetIndexName;
OS << Name << ')';
printOperandOffset(OS, getOffset());
@@ -1152,7 +1152,7 @@ void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
const MIRFormatter *Formatter = TII->getMIRFormatter();
// FIXME: This is not necessarily the correct MIR serialization format for
// a custom pseudo source value, but at least it allows
- // MIR printing to work on a target with custom pseudo source
+ // MIR printing to work on a target with custom pseudo source
// values.
OS << "custom \"";
Formatter->printCustomPseudoSourceValue(OS, MST, *PVal);
@@ -1162,10 +1162,10 @@ void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
}
}
MachineOperand::printOperandOffset(OS, getOffset());
- if (getAlign() != getSize())
- OS << ", align " << getAlign().value();
- if (getAlign() != getBaseAlign())
- OS << ", basealign " << getBaseAlign().value();
+ if (getAlign() != getSize())
+ OS << ", align " << getAlign().value();
+ if (getAlign() != getBaseAlign())
+ OS << ", basealign " << getBaseAlign().value();
auto AAInfo = getAAInfo();
if (AAInfo.TBAA) {
OS << ", !tbaa ";
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineOutliner.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineOutliner.cpp
index 06f39d89c0..02998d41d8 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineOutliner.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineOutliner.cpp
@@ -307,8 +307,8 @@ struct InstructionMapper {
// repeated substring.
mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, UnsignedVecForMBB,
InstrListForMBB);
- llvm::append_range(InstrList, InstrListForMBB);
- llvm::append_range(UnsignedVec, UnsignedVecForMBB);
+ llvm::append_range(InstrList, InstrListForMBB);
+ llvm::append_range(UnsignedVec, UnsignedVecForMBB);
}
}
@@ -545,10 +545,10 @@ void MachineOutliner::findCandidates(
// That is, one must either
// * End before the other starts
// * Start after the other ends
- if (llvm::all_of(CandidatesForRepeatedSeq, [&StartIdx,
- &EndIdx](const Candidate &C) {
- return (EndIdx < C.getStartIdx() || StartIdx > C.getEndIdx());
- })) {
+ if (llvm::all_of(CandidatesForRepeatedSeq, [&StartIdx,
+ &EndIdx](const Candidate &C) {
+ return (EndIdx < C.getStartIdx() || StartIdx > C.getEndIdx());
+ })) {
// It doesn't overlap with anything, so we can outline it.
// Each sequence is over [StartIt, EndIt].
// Save the candidate and its location.
@@ -651,8 +651,8 @@ MachineFunction *MachineOutliner::createOutlinedFunction(
OriginalMF->getFrameInstructions();
for (auto I = FirstCand.front(), E = std::next(FirstCand.back()); I != E;
++I) {
- if (I->isDebugInstr())
- continue;
+ if (I->isDebugInstr())
+ continue;
MachineInstr *NewMI = MF.CloneMachineInstr(&*I);
if (I->isCFIInstruction()) {
unsigned CFIIndex = NewMI->getOperand(0).getCFIIndex();
@@ -688,7 +688,7 @@ MachineFunction *MachineOutliner::createOutlinedFunction(
// The live-in set for the outlined function is the union of the live-ins
// from all the outlining points.
- for (MCPhysReg Reg : CandLiveIns)
+ for (MCPhysReg Reg : CandLiveIns)
LiveIns.addReg(Reg);
}
addLiveIns(MBB, LiveIns);
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachinePassManager.cpp b/contrib/libs/llvm12/lib/CodeGen/MachinePassManager.cpp
index 4868f1f62c..e81575c889 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachinePassManager.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachinePassManager.cpp
@@ -1,121 +1,121 @@
-//===---------- MachinePassManager.cpp ------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the pass management machinery for machine functions.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/MachinePassManager.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/IR/PassManagerImpl.h"
-
-using namespace llvm;
-
-namespace llvm {
-template class AllAnalysesOn<MachineFunction>;
-template class AnalysisManager<MachineFunction>;
-template class PassManager<MachineFunction>;
-
-Error MachineFunctionPassManager::run(Module &M,
- MachineFunctionAnalysisManager &MFAM) {
- // MachineModuleAnalysis is a module analysis pass that is never invalidated
- // because we don't run any module pass in codegen pipeline. This is very
- // important because the codegen state is stored in MMI which is the analysis
- // result of MachineModuleAnalysis. MMI should not be recomputed.
- auto &MMI = MFAM.getResult<MachineModuleAnalysis>(M);
-
- (void)RequireCodeGenSCCOrder;
- assert(!RequireCodeGenSCCOrder && "not implemented");
-
- // Add a PIC to verify machine functions.
- if (VerifyMachineFunction) {
- PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(M);
-
- // No need to pop this callback later since MIR pipeline is flat which means
- // current pipeline is the top-level pipeline. Callbacks are not used after
- // current pipeline.
- PI.pushBeforeNonSkippedPassCallback([&MFAM](StringRef PassID, Any IR) {
- assert(any_isa<const MachineFunction *>(IR));
- const MachineFunction *MF = any_cast<const MachineFunction *>(IR);
- assert(MF && "Machine function should be valid for printing");
- std::string Banner = std::string("After ") + std::string(PassID);
- verifyMachineFunction(&MFAM, Banner, *MF);
- });
- }
-
- if (DebugLogging) {
- dbgs() << "Starting " << getTypeName<MachineFunction>()
- << " pass manager run.\n";
- }
-
- for (auto &F : InitializationFuncs) {
- if (auto Err = F(M, MFAM))
- return Err;
- }
-
- unsigned Idx = 0;
- size_t Size = Passes.size();
- do {
- // Run machine module passes
- for (; MachineModulePasses.count(Idx) && Idx != Size; ++Idx) {
- if (DebugLogging)
- dbgs() << "Running pass: " << Passes[Idx]->name() << " on "
- << M.getName() << '\n';
- if (auto Err = MachineModulePasses.at(Idx)(M, MFAM))
- return Err;
- }
-
- // Finish running all passes.
- if (Idx == Size)
- break;
-
- // Run machine function passes
-
- // Get index range of machine function passes.
- unsigned Begin = Idx;
- for (; !MachineModulePasses.count(Idx) && Idx != Size; ++Idx)
- ;
-
- for (Function &F : M) {
- // Do not codegen any 'available_externally' functions at all, they have
- // definitions outside the translation unit.
- if (F.hasAvailableExternallyLinkage())
- continue;
-
- MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
- PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(MF);
-
- for (unsigned I = Begin, E = Idx; I != E; ++I) {
- auto *P = Passes[I].get();
-
- if (!PI.runBeforePass<MachineFunction>(*P, MF))
- continue;
-
- // TODO: EmitSizeRemarks
- PreservedAnalyses PassPA = P->run(MF, MFAM);
- PI.runAfterPass(*P, MF, PassPA);
- MFAM.invalidate(MF, PassPA);
- }
- }
- } while (true);
-
- for (auto &F : FinalizationFuncs) {
- if (auto Err = F(M, MFAM))
- return Err;
- }
-
- if (DebugLogging) {
- dbgs() << "Finished " << getTypeName<MachineFunction>()
- << " pass manager run.\n";
- }
-
- return Error::success();
-}
-
-} // namespace llvm
+//===---------- MachinePassManager.cpp ------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the pass management machinery for machine functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/MachinePassManager.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/IR/PassManagerImpl.h"
+
+using namespace llvm;
+
+namespace llvm {
+template class AllAnalysesOn<MachineFunction>;
+template class AnalysisManager<MachineFunction>;
+template class PassManager<MachineFunction>;
+
+Error MachineFunctionPassManager::run(Module &M,
+ MachineFunctionAnalysisManager &MFAM) {
+ // MachineModuleAnalysis is a module analysis pass that is never invalidated
+ // because we don't run any module pass in codegen pipeline. This is very
+ // important because the codegen state is stored in MMI which is the analysis
+ // result of MachineModuleAnalysis. MMI should not be recomputed.
+ auto &MMI = MFAM.getResult<MachineModuleAnalysis>(M);
+
+ (void)RequireCodeGenSCCOrder;
+ assert(!RequireCodeGenSCCOrder && "not implemented");
+
+ // Add a PIC to verify machine functions.
+ if (VerifyMachineFunction) {
+ PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(M);
+
+ // No need to pop this callback later since MIR pipeline is flat which means
+ // current pipeline is the top-level pipeline. Callbacks are not used after
+ // current pipeline.
+ PI.pushBeforeNonSkippedPassCallback([&MFAM](StringRef PassID, Any IR) {
+ assert(any_isa<const MachineFunction *>(IR));
+ const MachineFunction *MF = any_cast<const MachineFunction *>(IR);
+ assert(MF && "Machine function should be valid for printing");
+ std::string Banner = std::string("After ") + std::string(PassID);
+ verifyMachineFunction(&MFAM, Banner, *MF);
+ });
+ }
+
+ if (DebugLogging) {
+ dbgs() << "Starting " << getTypeName<MachineFunction>()
+ << " pass manager run.\n";
+ }
+
+ for (auto &F : InitializationFuncs) {
+ if (auto Err = F(M, MFAM))
+ return Err;
+ }
+
+ unsigned Idx = 0;
+ size_t Size = Passes.size();
+ do {
+ // Run machine module passes
+ for (; MachineModulePasses.count(Idx) && Idx != Size; ++Idx) {
+ if (DebugLogging)
+ dbgs() << "Running pass: " << Passes[Idx]->name() << " on "
+ << M.getName() << '\n';
+ if (auto Err = MachineModulePasses.at(Idx)(M, MFAM))
+ return Err;
+ }
+
+ // Finish running all passes.
+ if (Idx == Size)
+ break;
+
+ // Run machine function passes
+
+ // Get index range of machine function passes.
+ unsigned Begin = Idx;
+ for (; !MachineModulePasses.count(Idx) && Idx != Size; ++Idx)
+ ;
+
+ for (Function &F : M) {
+ // Do not codegen any 'available_externally' functions at all, they have
+ // definitions outside the translation unit.
+ if (F.hasAvailableExternallyLinkage())
+ continue;
+
+ MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
+ PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(MF);
+
+ for (unsigned I = Begin, E = Idx; I != E; ++I) {
+ auto *P = Passes[I].get();
+
+ if (!PI.runBeforePass<MachineFunction>(*P, MF))
+ continue;
+
+ // TODO: EmitSizeRemarks
+ PreservedAnalyses PassPA = P->run(MF, MFAM);
+ PI.runAfterPass(*P, MF, PassPA);
+ MFAM.invalidate(MF, PassPA);
+ }
+ }
+ } while (true);
+
+ for (auto &F : FinalizationFuncs) {
+ if (auto Err = F(M, MFAM))
+ return Err;
+ }
+
+ if (DebugLogging) {
+ dbgs() << "Finished " << getTypeName<MachineFunction>()
+ << " pass manager run.\n";
+ }
+
+ return Error::success();
+}
+
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachinePipeliner.cpp b/contrib/libs/llvm12/lib/CodeGen/MachinePipeliner.cpp
index 1ef3f84b0a..d0fe29f65e 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachinePipeliner.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachinePipeliner.cpp
@@ -268,7 +268,7 @@ bool MachinePipeliner::scheduleLoop(MachineLoop &L) {
void MachinePipeliner::setPragmaPipelineOptions(MachineLoop &L) {
// Reset the pragma for the next loop in iteration.
disabledByPragma = false;
- II_setByPragma = 0;
+ II_setByPragma = 0;
MachineBasicBlock *LBLK = L.getTopBlock();
@@ -442,16 +442,16 @@ bool MachinePipeliner::swingModuloScheduler(MachineLoop &L) {
return SMS.hasNewSchedule();
}
-void MachinePipeliner::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<AAResultsWrapperPass>();
- AU.addPreserved<AAResultsWrapperPass>();
- AU.addRequired<MachineLoopInfo>();
- AU.addRequired<MachineDominatorTree>();
- AU.addRequired<LiveIntervals>();
- AU.addRequired<MachineOptimizationRemarkEmitterPass>();
- MachineFunctionPass::getAnalysisUsage(AU);
-}
-
+void MachinePipeliner::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<AAResultsWrapperPass>();
+ AU.addPreserved<AAResultsWrapperPass>();
+ AU.addRequired<MachineLoopInfo>();
+ AU.addRequired<MachineDominatorTree>();
+ AU.addRequired<LiveIntervals>();
+ AU.addRequired<MachineOptimizationRemarkEmitterPass>();
+ MachineFunctionPass::getAnalysisUsage(AU);
+}
+
void SwingSchedulerDAG::setMII(unsigned ResMII, unsigned RecMII) {
if (II_setByPragma > 0)
MII = II_setByPragma;
@@ -716,13 +716,13 @@ static bool isDependenceBarrier(MachineInstr &MI, AliasAnalysis *AA) {
/// This function calls the code in ValueTracking, but first checks that the
/// instruction has a memory operand.
static void getUnderlyingObjects(const MachineInstr *MI,
- SmallVectorImpl<const Value *> &Objs) {
+ SmallVectorImpl<const Value *> &Objs) {
if (!MI->hasOneMemOperand())
return;
MachineMemOperand *MM = *MI->memoperands_begin();
if (!MM->getValue())
return;
- getUnderlyingObjects(MM->getValue(), Objs);
+ getUnderlyingObjects(MM->getValue(), Objs);
for (const Value *V : Objs) {
if (!isIdentifiedObject(V)) {
Objs.clear();
@@ -746,7 +746,7 @@ void SwingSchedulerDAG::addLoopCarriedDependences(AliasAnalysis *AA) {
PendingLoads.clear();
else if (MI.mayLoad()) {
SmallVector<const Value *, 4> Objs;
- ::getUnderlyingObjects(&MI, Objs);
+ ::getUnderlyingObjects(&MI, Objs);
if (Objs.empty())
Objs.push_back(UnknownValue);
for (auto V : Objs) {
@@ -755,7 +755,7 @@ void SwingSchedulerDAG::addLoopCarriedDependences(AliasAnalysis *AA) {
}
} else if (MI.mayStore()) {
SmallVector<const Value *, 4> Objs;
- ::getUnderlyingObjects(&MI, Objs);
+ ::getUnderlyingObjects(&MI, Objs);
if (Objs.empty())
Objs.push_back(UnknownValue);
for (auto V : Objs) {
@@ -813,8 +813,8 @@ void SwingSchedulerDAG::addLoopCarriedDependences(AliasAnalysis *AA) {
continue;
}
AliasResult AAResult = AA->alias(
- MemoryLocation::getAfter(MMO1->getValue(), MMO1->getAAInfo()),
- MemoryLocation::getAfter(MMO2->getValue(), MMO2->getAAInfo()));
+ MemoryLocation::getAfter(MMO1->getValue(), MMO1->getAAInfo()),
+ MemoryLocation::getAfter(MMO2->getValue(), MMO2->getAAInfo()));
if (AAResult != NoAlias) {
SDep Dep(Load, SDep::Barrier);
@@ -1595,12 +1595,12 @@ static bool computePath(SUnit *Cur, SetVector<SUnit *> &Path,
SmallPtrSet<SUnit *, 8> &Visited) {
if (Cur->isBoundaryNode())
return false;
- if (Exclude.contains(Cur))
+ if (Exclude.contains(Cur))
return false;
- if (DestNodes.contains(Cur))
+ if (DestNodes.contains(Cur))
return true;
if (!Visited.insert(Cur).second)
- return Path.contains(Cur);
+ return Path.contains(Cur);
bool FoundPath = false;
for (auto &SI : Cur->Succs)
FoundPath |= computePath(SI.getSUnit(), Path, DestNodes, Exclude, Visited);
@@ -1640,8 +1640,8 @@ static void computeLiveOuts(MachineFunction &MF, RegPressureTracker &RPTracker,
if (Register::isVirtualRegister(Reg))
Uses.insert(Reg);
else if (MRI.isAllocatable(Reg))
- for (MCRegUnitIterator Units(Reg.asMCReg(), TRI); Units.isValid();
- ++Units)
+ for (MCRegUnitIterator Units(Reg.asMCReg(), TRI); Units.isValid();
+ ++Units)
Uses.insert(*Units);
}
}
@@ -1654,8 +1654,8 @@ static void computeLiveOuts(MachineFunction &MF, RegPressureTracker &RPTracker,
LiveOutRegs.push_back(RegisterMaskPair(Reg,
LaneBitmask::getNone()));
} else if (MRI.isAllocatable(Reg)) {
- for (MCRegUnitIterator Units(Reg.asMCReg(), TRI); Units.isValid();
- ++Units)
+ for (MCRegUnitIterator Units(Reg.asMCReg(), TRI); Units.isValid();
+ ++Units)
if (!Uses.count(*Units))
LiveOutRegs.push_back(RegisterMaskPair(*Units,
LaneBitmask::getNone()));
@@ -1955,7 +1955,7 @@ void SwingSchedulerDAG::computeNodeOrder(NodeSetType &NodeSets) {
for (const auto &I : maxHeight->Succs) {
if (Nodes.count(I.getSUnit()) == 0)
continue;
- if (NodeOrder.contains(I.getSUnit()))
+ if (NodeOrder.contains(I.getSUnit()))
continue;
if (ignoreDependence(I, false))
continue;
@@ -1967,7 +1967,7 @@ void SwingSchedulerDAG::computeNodeOrder(NodeSetType &NodeSets) {
continue;
if (Nodes.count(I.getSUnit()) == 0)
continue;
- if (NodeOrder.contains(I.getSUnit()))
+ if (NodeOrder.contains(I.getSUnit()))
continue;
R.insert(I.getSUnit());
}
@@ -2006,7 +2006,7 @@ void SwingSchedulerDAG::computeNodeOrder(NodeSetType &NodeSets) {
for (const auto &I : maxDepth->Preds) {
if (Nodes.count(I.getSUnit()) == 0)
continue;
- if (NodeOrder.contains(I.getSUnit()))
+ if (NodeOrder.contains(I.getSUnit()))
continue;
R.insert(I.getSUnit());
}
@@ -2016,7 +2016,7 @@ void SwingSchedulerDAG::computeNodeOrder(NodeSetType &NodeSets) {
continue;
if (Nodes.count(I.getSUnit()) == 0)
continue;
- if (NodeOrder.contains(I.getSUnit()))
+ if (NodeOrder.contains(I.getSUnit()))
continue;
R.insert(I.getSUnit());
}
@@ -2279,7 +2279,7 @@ void SwingSchedulerDAG::applyInstrChange(MachineInstr *MI,
/// Return the instruction in the loop that defines the register.
/// If the definition is a Phi, then follow the Phi operand to
/// the instruction in the loop.
-MachineInstr *SwingSchedulerDAG::findDefInLoop(Register Reg) {
+MachineInstr *SwingSchedulerDAG::findDefInLoop(Register Reg) {
SmallPtrSet<MachineInstr *, 8> Visited;
MachineInstr *Def = MRI.getVRegDef(Reg);
while (Def->isPHI()) {
@@ -2952,7 +2952,7 @@ void SMSchedule::finalizeSchedule(SwingSchedulerDAG *SSD) {
}
// Replace the old order with the new order.
cycleInstrs.swap(newOrderPhi);
- llvm::append_range(cycleInstrs, newOrderI);
+ llvm::append_range(cycleInstrs, newOrderI);
SSD->fixupRegisterOverlaps(cycleInstrs);
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineRegisterInfo.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineRegisterInfo.cpp
index 9c6b239e9a..5325eda9d4 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineRegisterInfo.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineRegisterInfo.cpp
@@ -417,11 +417,11 @@ MachineInstr *MachineRegisterInfo::getUniqueVRegDef(Register Reg) const {
}
bool MachineRegisterInfo::hasOneNonDBGUse(Register RegNo) const {
- return hasSingleElement(use_nodbg_operands(RegNo));
+ return hasSingleElement(use_nodbg_operands(RegNo));
}
bool MachineRegisterInfo::hasOneNonDBGUser(Register RegNo) const {
- return hasSingleElement(use_nodbg_instructions(RegNo));
+ return hasSingleElement(use_nodbg_instructions(RegNo));
}
/// clearKillFlags - Iterate over all the uses of the given register and
@@ -617,7 +617,7 @@ void MachineRegisterInfo::disableCalleeSavedRegister(MCRegister Reg) {
// Remove the register (and its aliases from the list).
for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
- llvm::erase_value(UpdatedCSRs, *AI);
+ llvm::erase_value(UpdatedCSRs, *AI);
}
const MCPhysReg *MachineRegisterInfo::getCalleeSavedRegs() const {
@@ -631,7 +631,7 @@ void MachineRegisterInfo::setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs) {
if (IsUpdatedCSRsInitialized)
UpdatedCSRs.clear();
- append_range(UpdatedCSRs, CSRs);
+ append_range(UpdatedCSRs, CSRs);
// Zero value represents the end of the register list
// (no more registers should be pushed).
@@ -645,7 +645,7 @@ bool MachineRegisterInfo::isReservedRegUnit(unsigned Unit) const {
bool IsRootReserved = true;
for (MCSuperRegIterator Super(*Root, TRI, /*IncludeSelf=*/true);
Super.isValid(); ++Super) {
- MCRegister Reg = *Super;
+ MCRegister Reg = *Super;
if (!isReserved(Reg)) {
IsRootReserved = false;
break;
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineSSAUpdater.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineSSAUpdater.cpp
index e338b64c64..462082df5d 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineSSAUpdater.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineSSAUpdater.cpp
@@ -50,20 +50,20 @@ MachineSSAUpdater::~MachineSSAUpdater() {
}
/// Initialize - Reset this object to get ready for a new set of SSA
-/// updates.
-void MachineSSAUpdater::Initialize(const TargetRegisterClass *RC) {
+/// updates.
+void MachineSSAUpdater::Initialize(const TargetRegisterClass *RC) {
if (!AV)
AV = new AvailableValsTy();
else
getAvailableVals(AV).clear();
- VRC = RC;
+ VRC = RC;
+}
+
+void MachineSSAUpdater::Initialize(Register V) {
+ Initialize(MRI->getRegClass(V));
}
-void MachineSSAUpdater::Initialize(Register V) {
- Initialize(MRI->getRegClass(V));
-}
-
/// HasValueForBlock - Return true if the MachineSSAUpdater already has a value for
/// the specified block.
bool MachineSSAUpdater::HasValueForBlock(MachineBasicBlock *BB) const {
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineScheduler.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineScheduler.cpp
index 44419a8726..8d51bb2610 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineScheduler.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineScheduler.cpp
@@ -18,7 +18,7 @@
#include "llvm/ADT/PriorityQueue.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/LiveInterval.h"
@@ -74,8 +74,8 @@ using namespace llvm;
#define DEBUG_TYPE "machine-scheduler"
-STATISTIC(NumClustered, "Number of load/store pairs clustered");
-
+STATISTIC(NumClustered, "Number of load/store pairs clustered");
+
namespace llvm {
cl::opt<bool> ForceTopDown("misched-topdown", cl::Hidden,
@@ -129,15 +129,15 @@ static cl::opt<bool> EnableCyclicPath("misched-cyclicpath", cl::Hidden,
static cl::opt<bool> EnableMemOpCluster("misched-cluster", cl::Hidden,
cl::desc("Enable memop clustering."),
cl::init(true));
-static cl::opt<bool>
- ForceFastCluster("force-fast-cluster", cl::Hidden,
- cl::desc("Switch to fast cluster algorithm with the lost "
- "of some fusion opportunities"),
- cl::init(false));
-static cl::opt<unsigned>
- FastClusterThreshold("fast-cluster-threshold", cl::Hidden,
- cl::desc("The threshold for fast cluster"),
- cl::init(1000));
+static cl::opt<bool>
+ ForceFastCluster("force-fast-cluster", cl::Hidden,
+ cl::desc("Switch to fast cluster algorithm with the lost "
+ "of some fusion opportunities"),
+ cl::init(false));
+static cl::opt<unsigned>
+ FastClusterThreshold("fast-cluster-threshold", cl::Hidden,
+ cl::desc("The threshold for fast cluster"),
+ cl::init(1000));
// DAG subtrees must have at least this many nodes.
static const unsigned MinSubtreeSize = 8;
@@ -240,13 +240,13 @@ char PostMachineScheduler::ID = 0;
char &llvm::PostMachineSchedulerID = PostMachineScheduler::ID;
-INITIALIZE_PASS_BEGIN(PostMachineScheduler, "postmisched",
- "PostRA Machine Instruction Scheduler", false, false)
-INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
-INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
-INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
-INITIALIZE_PASS_END(PostMachineScheduler, "postmisched",
- "PostRA Machine Instruction Scheduler", false, false)
+INITIALIZE_PASS_BEGIN(PostMachineScheduler, "postmisched",
+ "PostRA Machine Instruction Scheduler", false, false)
+INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
+INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
+INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
+INITIALIZE_PASS_END(PostMachineScheduler, "postmisched",
+ "PostRA Machine Instruction Scheduler", false, false)
PostMachineScheduler::PostMachineScheduler() : MachineSchedulerBase(ID) {
initializePostMachineSchedulerPass(*PassRegistry::getPassRegistry());
@@ -1115,7 +1115,7 @@ updateScheduledPressure(const SUnit *SU,
void ScheduleDAGMILive::updatePressureDiffs(
ArrayRef<RegisterMaskPair> LiveUses) {
for (const RegisterMaskPair &P : LiveUses) {
- Register Reg = P.RegUnit;
+ Register Reg = P.RegUnit;
/// FIXME: Currently assuming single-use physregs.
if (!Register::isVirtualRegister(Reg))
continue;
@@ -1315,7 +1315,7 @@ void ScheduleDAGMILive::computeDFSResult() {
/// The cyclic path estimation identifies a def-use pair that crosses the back
/// edge and considers the depth and height of the nodes. For example, consider
/// the following instruction sequence where each instruction has unit latency
-/// and defines an eponymous virtual register:
+/// and defines an eponymous virtual register:
///
/// a->b(a,c)->c(b)->d(c)->exit
///
@@ -1340,7 +1340,7 @@ unsigned ScheduleDAGMILive::computeCyclicCriticalPath() {
unsigned MaxCyclicLatency = 0;
// Visit each live out vreg def to find def/use pairs that cross iterations.
for (const RegisterMaskPair &P : RPTracker.getPressure().LiveOutRegs) {
- Register Reg = P.RegUnit;
+ Register Reg = P.RegUnit;
if (!Register::isVirtualRegister(Reg))
continue;
const LiveInterval &LI = LIS->getInterval(Reg);
@@ -1544,12 +1544,12 @@ public:
void apply(ScheduleDAGInstrs *DAGInstrs) override;
protected:
- void clusterNeighboringMemOps(ArrayRef<MemOpInfo> MemOps, bool FastCluster,
- ScheduleDAGInstrs *DAG);
- void collectMemOpRecords(std::vector<SUnit> &SUnits,
- SmallVectorImpl<MemOpInfo> &MemOpRecords);
- bool groupMemOps(ArrayRef<MemOpInfo> MemOps, ScheduleDAGInstrs *DAG,
- DenseMap<unsigned, SmallVector<MemOpInfo, 32>> &Groups);
+ void clusterNeighboringMemOps(ArrayRef<MemOpInfo> MemOps, bool FastCluster,
+ ScheduleDAGInstrs *DAG);
+ void collectMemOpRecords(std::vector<SUnit> &SUnits,
+ SmallVectorImpl<MemOpInfo> &MemOpRecords);
+ bool groupMemOps(ArrayRef<MemOpInfo> MemOps, ScheduleDAGInstrs *DAG,
+ DenseMap<unsigned, SmallVector<MemOpInfo, 32>> &Groups);
};
class StoreClusterMutation : public BaseMemOpClusterMutation {
@@ -1585,179 +1585,179 @@ createStoreClusterDAGMutation(const TargetInstrInfo *TII,
} // end namespace llvm
-// Sorting all the loads/stores first, then for each load/store, checking the
-// following load/store one by one, until reach the first non-dependent one and
-// call target hook to see if they can cluster.
-// If FastCluster is enabled, we assume that, all the loads/stores have been
-// preprocessed and now, they didn't have dependencies on each other.
+// Sorting all the loads/stores first, then for each load/store, checking the
+// following load/store one by one, until reach the first non-dependent one and
+// call target hook to see if they can cluster.
+// If FastCluster is enabled, we assume that, all the loads/stores have been
+// preprocessed and now, they didn't have dependencies on each other.
void BaseMemOpClusterMutation::clusterNeighboringMemOps(
- ArrayRef<MemOpInfo> MemOpRecords, bool FastCluster,
- ScheduleDAGInstrs *DAG) {
- // Keep track of the current cluster length and bytes for each SUnit.
- DenseMap<unsigned, std::pair<unsigned, unsigned>> SUnit2ClusterInfo;
+ ArrayRef<MemOpInfo> MemOpRecords, bool FastCluster,
+ ScheduleDAGInstrs *DAG) {
+ // Keep track of the current cluster length and bytes for each SUnit.
+ DenseMap<unsigned, std::pair<unsigned, unsigned>> SUnit2ClusterInfo;
// At this point, `MemOpRecords` array must hold atleast two mem ops. Try to
// cluster mem ops collected within `MemOpRecords` array.
for (unsigned Idx = 0, End = MemOpRecords.size(); Idx < (End - 1); ++Idx) {
// Decision to cluster mem ops is taken based on target dependent logic
auto MemOpa = MemOpRecords[Idx];
-
- // Seek for the next load/store to do the cluster.
- unsigned NextIdx = Idx + 1;
- for (; NextIdx < End; ++NextIdx)
- // Skip if MemOpb has been clustered already or has dependency with
- // MemOpa.
- if (!SUnit2ClusterInfo.count(MemOpRecords[NextIdx].SU->NodeNum) &&
- (FastCluster ||
- (!DAG->IsReachable(MemOpRecords[NextIdx].SU, MemOpa.SU) &&
- !DAG->IsReachable(MemOpa.SU, MemOpRecords[NextIdx].SU))))
- break;
- if (NextIdx == End)
+
+ // Seek for the next load/store to do the cluster.
+ unsigned NextIdx = Idx + 1;
+ for (; NextIdx < End; ++NextIdx)
+ // Skip if MemOpb has been clustered already or has dependency with
+ // MemOpa.
+ if (!SUnit2ClusterInfo.count(MemOpRecords[NextIdx].SU->NodeNum) &&
+ (FastCluster ||
+ (!DAG->IsReachable(MemOpRecords[NextIdx].SU, MemOpa.SU) &&
+ !DAG->IsReachable(MemOpa.SU, MemOpRecords[NextIdx].SU))))
+ break;
+ if (NextIdx == End)
continue;
-
- auto MemOpb = MemOpRecords[NextIdx];
- unsigned ClusterLength = 2;
- unsigned CurrentClusterBytes = MemOpa.Width + MemOpb.Width;
- if (SUnit2ClusterInfo.count(MemOpa.SU->NodeNum)) {
- ClusterLength = SUnit2ClusterInfo[MemOpa.SU->NodeNum].first + 1;
- CurrentClusterBytes =
- SUnit2ClusterInfo[MemOpa.SU->NodeNum].second + MemOpb.Width;
+
+ auto MemOpb = MemOpRecords[NextIdx];
+ unsigned ClusterLength = 2;
+ unsigned CurrentClusterBytes = MemOpa.Width + MemOpb.Width;
+ if (SUnit2ClusterInfo.count(MemOpa.SU->NodeNum)) {
+ ClusterLength = SUnit2ClusterInfo[MemOpa.SU->NodeNum].first + 1;
+ CurrentClusterBytes =
+ SUnit2ClusterInfo[MemOpa.SU->NodeNum].second + MemOpb.Width;
}
- if (!TII->shouldClusterMemOps(MemOpa.BaseOps, MemOpb.BaseOps, ClusterLength,
- CurrentClusterBytes))
- continue;
-
+ if (!TII->shouldClusterMemOps(MemOpa.BaseOps, MemOpb.BaseOps, ClusterLength,
+ CurrentClusterBytes))
+ continue;
+
SUnit *SUa = MemOpa.SU;
SUnit *SUb = MemOpb.SU;
if (SUa->NodeNum > SUb->NodeNum)
std::swap(SUa, SUb);
// FIXME: Is this check really required?
- if (!DAG->addEdge(SUb, SDep(SUa, SDep::Cluster)))
+ if (!DAG->addEdge(SUb, SDep(SUa, SDep::Cluster)))
continue;
LLVM_DEBUG(dbgs() << "Cluster ld/st SU(" << SUa->NodeNum << ") - SU("
<< SUb->NodeNum << ")\n");
- ++NumClustered;
-
- if (IsLoad) {
- // Copy successor edges from SUa to SUb. Interleaving computation
- // dependent on SUa can prevent load combining due to register reuse.
- // Predecessor edges do not need to be copied from SUb to SUa since
- // nearby loads should have effectively the same inputs.
- for (const SDep &Succ : SUa->Succs) {
- if (Succ.getSUnit() == SUb)
- continue;
- LLVM_DEBUG(dbgs() << " Copy Succ SU(" << Succ.getSUnit()->NodeNum
- << ")\n");
- DAG->addEdge(Succ.getSUnit(), SDep(SUb, SDep::Artificial));
- }
- } else {
- // Copy predecessor edges from SUb to SUa to avoid the SUnits that
- // SUb dependent on scheduled in-between SUb and SUa. Successor edges
- // do not need to be copied from SUa to SUb since no one will depend
- // on stores.
- // Notice that, we don't need to care about the memory dependency as
- // we won't try to cluster them if they have any memory dependency.
- for (const SDep &Pred : SUb->Preds) {
- if (Pred.getSUnit() == SUa)
- continue;
- LLVM_DEBUG(dbgs() << " Copy Pred SU(" << Pred.getSUnit()->NodeNum
- << ")\n");
- DAG->addEdge(SUa, SDep(Pred.getSUnit(), SDep::Artificial));
- }
+ ++NumClustered;
+
+ if (IsLoad) {
+ // Copy successor edges from SUa to SUb. Interleaving computation
+ // dependent on SUa can prevent load combining due to register reuse.
+ // Predecessor edges do not need to be copied from SUb to SUa since
+ // nearby loads should have effectively the same inputs.
+ for (const SDep &Succ : SUa->Succs) {
+ if (Succ.getSUnit() == SUb)
+ continue;
+ LLVM_DEBUG(dbgs() << " Copy Succ SU(" << Succ.getSUnit()->NodeNum
+ << ")\n");
+ DAG->addEdge(Succ.getSUnit(), SDep(SUb, SDep::Artificial));
+ }
+ } else {
+ // Copy predecessor edges from SUb to SUa to avoid the SUnits that
+ // SUb dependent on scheduled in-between SUb and SUa. Successor edges
+ // do not need to be copied from SUa to SUb since no one will depend
+ // on stores.
+ // Notice that, we don't need to care about the memory dependency as
+ // we won't try to cluster them if they have any memory dependency.
+ for (const SDep &Pred : SUb->Preds) {
+ if (Pred.getSUnit() == SUa)
+ continue;
+ LLVM_DEBUG(dbgs() << " Copy Pred SU(" << Pred.getSUnit()->NodeNum
+ << ")\n");
+ DAG->addEdge(SUa, SDep(Pred.getSUnit(), SDep::Artificial));
+ }
}
- SUnit2ClusterInfo[MemOpb.SU->NodeNum] = {ClusterLength,
- CurrentClusterBytes};
-
+ SUnit2ClusterInfo[MemOpb.SU->NodeNum] = {ClusterLength,
+ CurrentClusterBytes};
+
LLVM_DEBUG(dbgs() << " Curr cluster length: " << ClusterLength
<< ", Curr cluster bytes: " << CurrentClusterBytes
<< "\n");
}
}
-void BaseMemOpClusterMutation::collectMemOpRecords(
- std::vector<SUnit> &SUnits, SmallVectorImpl<MemOpInfo> &MemOpRecords) {
- for (auto &SU : SUnits) {
+void BaseMemOpClusterMutation::collectMemOpRecords(
+ std::vector<SUnit> &SUnits, SmallVectorImpl<MemOpInfo> &MemOpRecords) {
+ for (auto &SU : SUnits) {
if ((IsLoad && !SU.getInstr()->mayLoad()) ||
(!IsLoad && !SU.getInstr()->mayStore()))
continue;
- const MachineInstr &MI = *SU.getInstr();
- SmallVector<const MachineOperand *, 4> BaseOps;
- int64_t Offset;
- bool OffsetIsScalable;
- unsigned Width;
- if (TII->getMemOperandsWithOffsetWidth(MI, BaseOps, Offset,
- OffsetIsScalable, Width, TRI)) {
- MemOpRecords.push_back(MemOpInfo(&SU, BaseOps, Offset, Width));
-
- LLVM_DEBUG(dbgs() << "Num BaseOps: " << BaseOps.size() << ", Offset: "
- << Offset << ", OffsetIsScalable: " << OffsetIsScalable
- << ", Width: " << Width << "\n");
- }
-#ifndef NDEBUG
- for (auto *Op : BaseOps)
- assert(Op);
-#endif
- }
-}
-
-bool BaseMemOpClusterMutation::groupMemOps(
- ArrayRef<MemOpInfo> MemOps, ScheduleDAGInstrs *DAG,
- DenseMap<unsigned, SmallVector<MemOpInfo, 32>> &Groups) {
- bool FastCluster =
- ForceFastCluster ||
- MemOps.size() * DAG->SUnits.size() / 1000 > FastClusterThreshold;
-
- for (const auto &MemOp : MemOps) {
+ const MachineInstr &MI = *SU.getInstr();
+ SmallVector<const MachineOperand *, 4> BaseOps;
+ int64_t Offset;
+ bool OffsetIsScalable;
+ unsigned Width;
+ if (TII->getMemOperandsWithOffsetWidth(MI, BaseOps, Offset,
+ OffsetIsScalable, Width, TRI)) {
+ MemOpRecords.push_back(MemOpInfo(&SU, BaseOps, Offset, Width));
+
+ LLVM_DEBUG(dbgs() << "Num BaseOps: " << BaseOps.size() << ", Offset: "
+ << Offset << ", OffsetIsScalable: " << OffsetIsScalable
+ << ", Width: " << Width << "\n");
+ }
+#ifndef NDEBUG
+ for (auto *Op : BaseOps)
+ assert(Op);
+#endif
+ }
+}
+
+bool BaseMemOpClusterMutation::groupMemOps(
+ ArrayRef<MemOpInfo> MemOps, ScheduleDAGInstrs *DAG,
+ DenseMap<unsigned, SmallVector<MemOpInfo, 32>> &Groups) {
+ bool FastCluster =
+ ForceFastCluster ||
+ MemOps.size() * DAG->SUnits.size() / 1000 > FastClusterThreshold;
+
+ for (const auto &MemOp : MemOps) {
unsigned ChainPredID = DAG->SUnits.size();
- if (FastCluster) {
- for (const SDep &Pred : MemOp.SU->Preds) {
- // We only want to cluster the mem ops that have the same ctrl(non-data)
- // pred so that they didn't have ctrl dependency for each other. But for
- // store instrs, we can still cluster them if the pred is load instr.
- if ((Pred.isCtrl() &&
- (IsLoad ||
- (Pred.getSUnit() && Pred.getSUnit()->getInstr()->mayStore()))) &&
- !Pred.isArtificial()) {
- ChainPredID = Pred.getSUnit()->NodeNum;
- break;
- }
+ if (FastCluster) {
+ for (const SDep &Pred : MemOp.SU->Preds) {
+ // We only want to cluster the mem ops that have the same ctrl(non-data)
+ // pred so that they didn't have ctrl dependency for each other. But for
+ // store instrs, we can still cluster them if the pred is load instr.
+ if ((Pred.isCtrl() &&
+ (IsLoad ||
+ (Pred.getSUnit() && Pred.getSUnit()->getInstr()->mayStore()))) &&
+ !Pred.isArtificial()) {
+ ChainPredID = Pred.getSUnit()->NodeNum;
+ break;
+ }
}
- } else
- ChainPredID = 0;
-
- Groups[ChainPredID].push_back(MemOp);
- }
- return FastCluster;
-}
-
-/// Callback from DAG postProcessing to create cluster edges for loads/stores.
-void BaseMemOpClusterMutation::apply(ScheduleDAGInstrs *DAG) {
- // Collect all the clusterable loads/stores
- SmallVector<MemOpInfo, 32> MemOpRecords;
- collectMemOpRecords(DAG->SUnits, MemOpRecords);
-
- if (MemOpRecords.size() < 2)
- return;
-
- // Put the loads/stores without dependency into the same group with some
- // heuristic if the DAG is too complex to avoid compiling time blow up.
- // Notice that, some fusion pair could be lost with this.
- DenseMap<unsigned, SmallVector<MemOpInfo, 32>> Groups;
- bool FastCluster = groupMemOps(MemOpRecords, DAG, Groups);
-
- for (auto &Group : Groups) {
- // Sorting the loads/stores, so that, we can stop the cluster as early as
- // possible.
- llvm::sort(Group.second);
-
- // Trying to cluster all the neighboring loads/stores.
- clusterNeighboringMemOps(Group.second, FastCluster, DAG);
- }
+ } else
+ ChainPredID = 0;
+
+ Groups[ChainPredID].push_back(MemOp);
+ }
+ return FastCluster;
+}
+
+/// Callback from DAG postProcessing to create cluster edges for loads/stores.
+void BaseMemOpClusterMutation::apply(ScheduleDAGInstrs *DAG) {
+ // Collect all the clusterable loads/stores
+ SmallVector<MemOpInfo, 32> MemOpRecords;
+ collectMemOpRecords(DAG->SUnits, MemOpRecords);
+
+ if (MemOpRecords.size() < 2)
+ return;
+
+ // Put the loads/stores without dependency into the same group with some
+ // heuristic if the DAG is too complex to avoid compiling time blow up.
+ // Notice that, some fusion pair could be lost with this.
+ DenseMap<unsigned, SmallVector<MemOpInfo, 32>> Groups;
+ bool FastCluster = groupMemOps(MemOpRecords, DAG, Groups);
+
+ for (auto &Group : Groups) {
+ // Sorting the loads/stores, so that, we can stop the cluster as early as
+ // possible.
+ llvm::sort(Group.second);
+
+ // Trying to cluster all the neighboring loads/stores.
+ clusterNeighboringMemOps(Group.second, FastCluster, DAG);
+ }
}
//===----------------------------------------------------------------------===//
@@ -2816,11 +2816,11 @@ bool tryLatency(GenericSchedulerBase::SchedCandidate &TryCand,
GenericSchedulerBase::SchedCandidate &Cand,
SchedBoundary &Zone) {
if (Zone.isTop()) {
- // Prefer the candidate with the lesser depth, but only if one of them has
- // depth greater than the total latency scheduled so far, otherwise either
- // of them could be scheduled now with no stall.
- if (std::max(TryCand.SU->getDepth(), Cand.SU->getDepth()) >
- Zone.getScheduledLatency()) {
+ // Prefer the candidate with the lesser depth, but only if one of them has
+ // depth greater than the total latency scheduled so far, otherwise either
+ // of them could be scheduled now with no stall.
+ if (std::max(TryCand.SU->getDepth(), Cand.SU->getDepth()) >
+ Zone.getScheduledLatency()) {
if (tryLess(TryCand.SU->getDepth(), Cand.SU->getDepth(),
TryCand, Cand, GenericSchedulerBase::TopDepthReduce))
return true;
@@ -2829,11 +2829,11 @@ bool tryLatency(GenericSchedulerBase::SchedCandidate &TryCand,
TryCand, Cand, GenericSchedulerBase::TopPathReduce))
return true;
} else {
- // Prefer the candidate with the lesser height, but only if one of them has
- // height greater than the total latency scheduled so far, otherwise either
- // of them could be scheduled now with no stall.
- if (std::max(TryCand.SU->getHeight(), Cand.SU->getHeight()) >
- Zone.getScheduledLatency()) {
+ // Prefer the candidate with the lesser height, but only if one of them has
+ // height greater than the total latency scheduled so far, otherwise either
+ // of them could be scheduled now with no stall.
+ if (std::max(TryCand.SU->getHeight(), Cand.SU->getHeight()) >
+ Zone.getScheduledLatency()) {
if (tryLess(TryCand.SU->getHeight(), Cand.SU->getHeight(),
TryCand, Cand, GenericSchedulerBase::BotHeightReduce))
return true;
@@ -3456,13 +3456,13 @@ ScheduleDAGMILive *llvm::createGenericSchedLive(MachineSchedContext *C) {
return DAG;
}
-static ScheduleDAGInstrs *createConvergingSched(MachineSchedContext *C) {
+static ScheduleDAGInstrs *createConvergingSched(MachineSchedContext *C) {
return createGenericSchedLive(C);
}
static MachineSchedRegistry
GenericSchedRegistry("converge", "Standard converging scheduler.",
- createConvergingSched);
+ createConvergingSched);
//===----------------------------------------------------------------------===//
// PostGenericScheduler - Generic PostRA implementation of MachineSchedStrategy.
@@ -3836,7 +3836,7 @@ struct DOTGraphTraits<ScheduleDAGMI*> : public DefaultDOTGraphTraits {
return true;
}
- static bool isNodeHidden(const SUnit *Node, const ScheduleDAG *G) {
+ static bool isNodeHidden(const SUnit *Node, const ScheduleDAG *G) {
if (ViewMISchedCutoff == 0)
return false;
return (Node->Preds.size() > ViewMISchedCutoff
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineSink.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineSink.cpp
index 34aca6e2d3..378df1b75e 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineSink.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineSink.cpp
@@ -34,8 +34,8 @@
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachinePostDominators.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/RegisterClassInfo.h"
-#include "llvm/CodeGen/RegisterPressure.h"
+#include "llvm/CodeGen/RegisterClassInfo.h"
+#include "llvm/CodeGen/RegisterPressure.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
@@ -79,18 +79,18 @@ static cl::opt<unsigned> SplitEdgeProbabilityThreshold(
"splitted critical edge"),
cl::init(40), cl::Hidden);
-static cl::opt<unsigned> SinkLoadInstsPerBlockThreshold(
- "machine-sink-load-instrs-threshold",
- cl::desc("Do not try to find alias store for a load if there is a in-path "
- "block whose instruction number is higher than this threshold."),
- cl::init(2000), cl::Hidden);
-
-static cl::opt<unsigned> SinkLoadBlocksThreshold(
- "machine-sink-load-blocks-threshold",
- cl::desc("Do not try to find alias store for a load if the block number in "
- "the straight line is higher than this threshold."),
- cl::init(20), cl::Hidden);
-
+static cl::opt<unsigned> SinkLoadInstsPerBlockThreshold(
+ "machine-sink-load-instrs-threshold",
+ cl::desc("Do not try to find alias store for a load if there is a in-path "
+ "block whose instruction number is higher than this threshold."),
+ cl::init(2000), cl::Hidden);
+
+static cl::opt<unsigned> SinkLoadBlocksThreshold(
+ "machine-sink-load-blocks-threshold",
+ cl::desc("Do not try to find alias store for a load if the block number in "
+ "the straight line is higher than this threshold."),
+ cl::init(20), cl::Hidden);
+
STATISTIC(NumSunk, "Number of machine instructions sunk");
STATISTIC(NumSplit, "Number of critical edges split");
STATISTIC(NumCoalesces, "Number of copies coalesced");
@@ -108,7 +108,7 @@ namespace {
MachineBlockFrequencyInfo *MBFI;
const MachineBranchProbabilityInfo *MBPI;
AliasAnalysis *AA;
- RegisterClassInfo RegClassInfo;
+ RegisterClassInfo RegClassInfo;
// Remember which edges have been considered for breaking.
SmallSet<std::pair<MachineBasicBlock*, MachineBasicBlock*>, 8>
@@ -142,15 +142,15 @@ namespace {
/// current block.
DenseSet<DebugVariable> SeenDbgVars;
- std::map<std::pair<MachineBasicBlock *, MachineBasicBlock *>, bool>
- HasStoreCache;
- std::map<std::pair<MachineBasicBlock *, MachineBasicBlock *>,
- std::vector<MachineInstr *>>
- StoreInstrCache;
-
- /// Cached BB's register pressure.
- std::map<MachineBasicBlock *, std::vector<unsigned>> CachedRegisterPressure;
-
+ std::map<std::pair<MachineBasicBlock *, MachineBasicBlock *>, bool>
+ HasStoreCache;
+ std::map<std::pair<MachineBasicBlock *, MachineBasicBlock *>,
+ std::vector<MachineInstr *>>
+ StoreInstrCache;
+
+ /// Cached BB's register pressure.
+ std::map<MachineBasicBlock *, std::vector<unsigned>> CachedRegisterPressure;
+
public:
static char ID; // Pass identification
@@ -183,9 +183,9 @@ namespace {
MachineBasicBlock *From,
MachineBasicBlock *To);
- bool hasStoreBetween(MachineBasicBlock *From, MachineBasicBlock *To,
- MachineInstr &MI);
-
+ bool hasStoreBetween(MachineBasicBlock *From, MachineBasicBlock *To,
+ MachineInstr &MI);
+
/// Postpone the splitting of the given critical
/// edge (\p From, \p To).
///
@@ -211,12 +211,12 @@ namespace {
/// to the copy source.
void SalvageUnsunkDebugUsersOfCopy(MachineInstr &,
MachineBasicBlock *TargetBlock);
- bool AllUsesDominatedByBlock(Register Reg, MachineBasicBlock *MBB,
- MachineBasicBlock *DefMBB, bool &BreakPHIEdge,
- bool &LocalUse) const;
+ bool AllUsesDominatedByBlock(Register Reg, MachineBasicBlock *MBB,
+ MachineBasicBlock *DefMBB, bool &BreakPHIEdge,
+ bool &LocalUse) const;
MachineBasicBlock *FindSuccToSinkTo(MachineInstr &MI, MachineBasicBlock *MBB,
bool &BreakPHIEdge, AllSuccsCache &AllSuccessors);
- bool isProfitableToSinkTo(Register Reg, MachineInstr &MI,
+ bool isProfitableToSinkTo(Register Reg, MachineInstr &MI,
MachineBasicBlock *MBB,
MachineBasicBlock *SuccToSinkTo,
AllSuccsCache &AllSuccessors);
@@ -227,8 +227,8 @@ namespace {
SmallVector<MachineBasicBlock *, 4> &
GetAllSortedSuccessors(MachineInstr &MI, MachineBasicBlock *MBB,
AllSuccsCache &AllSuccessors) const;
-
- std::vector<unsigned> &getBBRegisterPressure(MachineBasicBlock &MBB);
+
+ std::vector<unsigned> &getBBRegisterPressure(MachineBasicBlock &MBB);
};
} // end anonymous namespace
@@ -282,11 +282,11 @@ bool MachineSinking::PerformTrivialForwardCoalescing(MachineInstr &MI,
/// occur in blocks dominated by the specified block. If any use is in the
/// definition block, then return false since it is never legal to move def
/// after uses.
-bool MachineSinking::AllUsesDominatedByBlock(Register Reg,
- MachineBasicBlock *MBB,
- MachineBasicBlock *DefMBB,
- bool &BreakPHIEdge,
- bool &LocalUse) const {
+bool MachineSinking::AllUsesDominatedByBlock(Register Reg,
+ MachineBasicBlock *MBB,
+ MachineBasicBlock *DefMBB,
+ bool &BreakPHIEdge,
+ bool &LocalUse) const {
assert(Register::isVirtualRegister(Reg) && "Only makes sense for vregs");
// Ignore debug uses because debug info doesn't affect the code.
@@ -355,7 +355,7 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
MBFI = UseBlockFreqInfo ? &getAnalysis<MachineBlockFrequencyInfo>() : nullptr;
MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
- RegClassInfo.runOnMachineFunction(MF);
+ RegClassInfo.runOnMachineFunction(MF);
bool EverMadeChange = false;
@@ -376,9 +376,9 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
<< printMBBReference(*Pair.first) << " -- "
<< printMBBReference(*NewSucc) << " -- "
<< printMBBReference(*Pair.second) << '\n');
- if (MBFI)
- MBFI->onEdgeSplit(*Pair.first, *NewSucc, *MBPI);
-
+ if (MBFI)
+ MBFI->onEdgeSplit(*Pair.first, *NewSucc, *MBPI);
+
MadeChange = true;
++NumSplit;
} else
@@ -389,9 +389,9 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
EverMadeChange = true;
}
- HasStoreCache.clear();
- StoreInstrCache.clear();
-
+ HasStoreCache.clear();
+ StoreInstrCache.clear();
+
// Now clear any kill flags for recorded registers.
for (auto I : RegsToClearKillFlags)
MRI->clearKillFlags(I);
@@ -449,8 +449,8 @@ bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) {
SeenDbgUsers.clear();
SeenDbgVars.clear();
- // recalculate the bb register pressure after sinking one BB.
- CachedRegisterPressure.clear();
+ // recalculate the bb register pressure after sinking one BB.
+ CachedRegisterPressure.clear();
return MadeChange;
}
@@ -462,7 +462,7 @@ void MachineSinking::ProcessDbgInst(MachineInstr &MI) {
DebugVariable Var(MI.getDebugVariable(), MI.getDebugExpression(),
MI.getDebugLoc()->getInlinedAt());
- bool SeenBefore = SeenDbgVars.contains(Var);
+ bool SeenBefore = SeenDbgVars.contains(Var);
MachineOperand &MO = MI.getDebugOperand(0);
if (MO.isReg() && MO.getReg().isVirtual())
@@ -593,44 +593,44 @@ bool MachineSinking::PostponeSplitCriticalEdge(MachineInstr &MI,
return true;
}
-std::vector<unsigned> &
-MachineSinking::getBBRegisterPressure(MachineBasicBlock &MBB) {
- // Currently to save compiling time, MBB's register pressure will not change
- // in one ProcessBlock iteration because of CachedRegisterPressure. but MBB's
- // register pressure is changed after sinking any instructions into it.
- // FIXME: need a accurate and cheap register pressure estiminate model here.
- auto RP = CachedRegisterPressure.find(&MBB);
- if (RP != CachedRegisterPressure.end())
- return RP->second;
-
- RegionPressure Pressure;
- RegPressureTracker RPTracker(Pressure);
-
- // Initialize the register pressure tracker.
- RPTracker.init(MBB.getParent(), &RegClassInfo, nullptr, &MBB, MBB.end(),
- /*TrackLaneMasks*/ false, /*TrackUntiedDefs=*/true);
-
- for (MachineBasicBlock::iterator MII = MBB.instr_end(),
- MIE = MBB.instr_begin();
- MII != MIE; --MII) {
- MachineInstr &MI = *std::prev(MII);
- if (MI.isDebugValue() || MI.isDebugLabel())
- continue;
- RegisterOperands RegOpers;
- RegOpers.collect(MI, *TRI, *MRI, false, false);
- RPTracker.recedeSkipDebugValues();
- assert(&*RPTracker.getPos() == &MI && "RPTracker sync error!");
- RPTracker.recede(RegOpers);
- }
-
- RPTracker.closeRegion();
- auto It = CachedRegisterPressure.insert(
- std::make_pair(&MBB, RPTracker.getPressure().MaxSetPressure));
- return It.first->second;
-}
-
+std::vector<unsigned> &
+MachineSinking::getBBRegisterPressure(MachineBasicBlock &MBB) {
+ // Currently to save compiling time, MBB's register pressure will not change
+ // in one ProcessBlock iteration because of CachedRegisterPressure. but MBB's
+ // register pressure is changed after sinking any instructions into it.
+ // FIXME: need a accurate and cheap register pressure estiminate model here.
+ auto RP = CachedRegisterPressure.find(&MBB);
+ if (RP != CachedRegisterPressure.end())
+ return RP->second;
+
+ RegionPressure Pressure;
+ RegPressureTracker RPTracker(Pressure);
+
+ // Initialize the register pressure tracker.
+ RPTracker.init(MBB.getParent(), &RegClassInfo, nullptr, &MBB, MBB.end(),
+ /*TrackLaneMasks*/ false, /*TrackUntiedDefs=*/true);
+
+ for (MachineBasicBlock::iterator MII = MBB.instr_end(),
+ MIE = MBB.instr_begin();
+ MII != MIE; --MII) {
+ MachineInstr &MI = *std::prev(MII);
+ if (MI.isDebugValue() || MI.isDebugLabel())
+ continue;
+ RegisterOperands RegOpers;
+ RegOpers.collect(MI, *TRI, *MRI, false, false);
+ RPTracker.recedeSkipDebugValues();
+ assert(&*RPTracker.getPos() == &MI && "RPTracker sync error!");
+ RPTracker.recede(RegOpers);
+ }
+
+ RPTracker.closeRegion();
+ auto It = CachedRegisterPressure.insert(
+ std::make_pair(&MBB, RPTracker.getPressure().MaxSetPressure));
+ return It.first->second;
+}
+
/// isProfitableToSinkTo - Return true if it is profitable to sink MI.
-bool MachineSinking::isProfitableToSinkTo(Register Reg, MachineInstr &MI,
+bool MachineSinking::isProfitableToSinkTo(Register Reg, MachineInstr &MI,
MachineBasicBlock *MBB,
MachineBasicBlock *SuccToSinkTo,
AllSuccsCache &AllSuccessors) {
@@ -666,73 +666,73 @@ bool MachineSinking::isProfitableToSinkTo(Register Reg, MachineInstr &MI,
FindSuccToSinkTo(MI, SuccToSinkTo, BreakPHIEdge, AllSuccessors))
return isProfitableToSinkTo(Reg, MI, SuccToSinkTo, MBB2, AllSuccessors);
- MachineLoop *ML = LI->getLoopFor(MBB);
-
- // If the instruction is not inside a loop, it is not profitable to sink MI to
- // a post dominate block SuccToSinkTo.
- if (!ML)
- return false;
-
- auto isRegisterPressureSetExceedLimit = [&](const TargetRegisterClass *RC) {
- unsigned Weight = TRI->getRegClassWeight(RC).RegWeight;
- const int *PS = TRI->getRegClassPressureSets(RC);
- // Get register pressure for block SuccToSinkTo.
- std::vector<unsigned> BBRegisterPressure =
- getBBRegisterPressure(*SuccToSinkTo);
- for (; *PS != -1; PS++)
- // check if any register pressure set exceeds limit in block SuccToSinkTo
- // after sinking.
- if (Weight + BBRegisterPressure[*PS] >=
- TRI->getRegPressureSetLimit(*MBB->getParent(), *PS))
- return true;
- return false;
- };
-
- // If this instruction is inside a loop and sinking this instruction can make
- // more registers live range shorten, it is still prifitable.
- for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
- const MachineOperand &MO = MI.getOperand(i);
- // Ignore non-register operands.
- if (!MO.isReg())
- continue;
- Register Reg = MO.getReg();
- if (Reg == 0)
- continue;
-
- // Don't handle physical register.
- if (Register::isPhysicalRegister(Reg))
- return false;
-
- // Users for the defs are all dominated by SuccToSinkTo.
- if (MO.isDef()) {
- // This def register's live range is shortened after sinking.
- bool LocalUse = false;
- if (!AllUsesDominatedByBlock(Reg, SuccToSinkTo, MBB, BreakPHIEdge,
- LocalUse))
- return false;
- } else {
- MachineInstr *DefMI = MRI->getVRegDef(Reg);
- // DefMI is defined outside of loop. There should be no live range
- // impact for this operand. Defination outside of loop means:
- // 1: defination is outside of loop.
- // 2: defination is in this loop, but it is a PHI in the loop header.
- if (LI->getLoopFor(DefMI->getParent()) != ML ||
- (DefMI->isPHI() && LI->isLoopHeader(DefMI->getParent())))
- continue;
- // The DefMI is defined inside the loop.
- // If sinking this operand makes some register pressure set exceed limit,
- // it is not profitable.
- if (isRegisterPressureSetExceedLimit(MRI->getRegClass(Reg))) {
- LLVM_DEBUG(dbgs() << "register pressure exceed limit, not profitable.");
- return false;
- }
- }
- }
-
- // If MI is in loop and all its operands are alive across the whole loop or if
- // no operand sinking make register pressure set exceed limit, it is
- // profitable to sink MI.
- return true;
+ MachineLoop *ML = LI->getLoopFor(MBB);
+
+ // If the instruction is not inside a loop, it is not profitable to sink MI to
+ // a post dominate block SuccToSinkTo.
+ if (!ML)
+ return false;
+
+ auto isRegisterPressureSetExceedLimit = [&](const TargetRegisterClass *RC) {
+ unsigned Weight = TRI->getRegClassWeight(RC).RegWeight;
+ const int *PS = TRI->getRegClassPressureSets(RC);
+ // Get register pressure for block SuccToSinkTo.
+ std::vector<unsigned> BBRegisterPressure =
+ getBBRegisterPressure(*SuccToSinkTo);
+ for (; *PS != -1; PS++)
+ // check if any register pressure set exceeds limit in block SuccToSinkTo
+ // after sinking.
+ if (Weight + BBRegisterPressure[*PS] >=
+ TRI->getRegPressureSetLimit(*MBB->getParent(), *PS))
+ return true;
+ return false;
+ };
+
+ // If this instruction is inside a loop and sinking this instruction can make
+ // more registers live range shorten, it is still prifitable.
+ for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = MI.getOperand(i);
+ // Ignore non-register operands.
+ if (!MO.isReg())
+ continue;
+ Register Reg = MO.getReg();
+ if (Reg == 0)
+ continue;
+
+ // Don't handle physical register.
+ if (Register::isPhysicalRegister(Reg))
+ return false;
+
+ // Users for the defs are all dominated by SuccToSinkTo.
+ if (MO.isDef()) {
+ // This def register's live range is shortened after sinking.
+ bool LocalUse = false;
+ if (!AllUsesDominatedByBlock(Reg, SuccToSinkTo, MBB, BreakPHIEdge,
+ LocalUse))
+ return false;
+ } else {
+ MachineInstr *DefMI = MRI->getVRegDef(Reg);
+ // DefMI is defined outside of loop. There should be no live range
+ // impact for this operand. Defination outside of loop means:
+ // 1: defination is outside of loop.
+ // 2: defination is in this loop, but it is a PHI in the loop header.
+ if (LI->getLoopFor(DefMI->getParent()) != ML ||
+ (DefMI->isPHI() && LI->isLoopHeader(DefMI->getParent())))
+ continue;
+ // The DefMI is defined inside the loop.
+ // If sinking this operand makes some register pressure set exceed limit,
+ // it is not profitable.
+ if (isRegisterPressureSetExceedLimit(MRI->getRegClass(Reg))) {
+ LLVM_DEBUG(dbgs() << "register pressure exceed limit, not profitable.");
+ return false;
+ }
+ }
+ }
+
+ // If MI is in loop and all its operands are alive across the whole loop or if
+ // no operand sinking make register pressure set exceed limit, it is
+ // profitable to sink MI.
+ return true;
}
/// Get the sorted sequence of successors for this MachineBasicBlock, possibly
@@ -745,7 +745,7 @@ MachineSinking::GetAllSortedSuccessors(MachineInstr &MI, MachineBasicBlock *MBB,
if (Succs != AllSuccessors.end())
return Succs->second;
- SmallVector<MachineBasicBlock *, 4> AllSuccs(MBB->successors());
+ SmallVector<MachineBasicBlock *, 4> AllSuccs(MBB->successors());
// Handle cases where sinking can happen but where the sink point isn't a
// successor. For example:
@@ -1007,97 +1007,97 @@ static void performSink(MachineInstr &MI, MachineBasicBlock &SuccToSinkTo,
}
}
-/// hasStoreBetween - check if there is store betweeen straight line blocks From
-/// and To.
-bool MachineSinking::hasStoreBetween(MachineBasicBlock *From,
- MachineBasicBlock *To, MachineInstr &MI) {
- // Make sure From and To are in straight line which means From dominates To
- // and To post dominates From.
- if (!DT->dominates(From, To) || !PDT->dominates(To, From))
- return true;
-
- auto BlockPair = std::make_pair(From, To);
-
- // Does these two blocks pair be queried before and have a definite cached
- // result?
- if (HasStoreCache.find(BlockPair) != HasStoreCache.end())
- return HasStoreCache[BlockPair];
-
- if (StoreInstrCache.find(BlockPair) != StoreInstrCache.end())
- return llvm::any_of(StoreInstrCache[BlockPair], [&](MachineInstr *I) {
- return I->mayAlias(AA, MI, false);
- });
-
- bool SawStore = false;
- bool HasAliasedStore = false;
- DenseSet<MachineBasicBlock *> HandledBlocks;
- DenseSet<MachineBasicBlock *> HandledDomBlocks;
- // Go through all reachable blocks from From.
- for (MachineBasicBlock *BB : depth_first(From)) {
- // We insert the instruction at the start of block To, so no need to worry
- // about stores inside To.
- // Store in block From should be already considered when just enter function
- // SinkInstruction.
- if (BB == To || BB == From)
- continue;
-
- // We already handle this BB in previous iteration.
- if (HandledBlocks.count(BB))
- continue;
-
- HandledBlocks.insert(BB);
- // To post dominates BB, it must be a path from block From.
- if (PDT->dominates(To, BB)) {
- if (!HandledDomBlocks.count(BB))
- HandledDomBlocks.insert(BB);
-
- // If this BB is too big or the block number in straight line between From
- // and To is too big, stop searching to save compiling time.
- if (BB->size() > SinkLoadInstsPerBlockThreshold ||
- HandledDomBlocks.size() > SinkLoadBlocksThreshold) {
- for (auto *DomBB : HandledDomBlocks) {
- if (DomBB != BB && DT->dominates(DomBB, BB))
- HasStoreCache[std::make_pair(DomBB, To)] = true;
- else if(DomBB != BB && DT->dominates(BB, DomBB))
- HasStoreCache[std::make_pair(From, DomBB)] = true;
- }
- HasStoreCache[BlockPair] = true;
- return true;
- }
-
- for (MachineInstr &I : *BB) {
- // Treat as alias conservatively for a call or an ordered memory
- // operation.
- if (I.isCall() || I.hasOrderedMemoryRef()) {
- for (auto *DomBB : HandledDomBlocks) {
- if (DomBB != BB && DT->dominates(DomBB, BB))
- HasStoreCache[std::make_pair(DomBB, To)] = true;
- else if(DomBB != BB && DT->dominates(BB, DomBB))
- HasStoreCache[std::make_pair(From, DomBB)] = true;
- }
- HasStoreCache[BlockPair] = true;
- return true;
- }
-
- if (I.mayStore()) {
- SawStore = true;
- // We still have chance to sink MI if all stores between are not
- // aliased to MI.
- // Cache all store instructions, so that we don't need to go through
- // all From reachable blocks for next load instruction.
- if (I.mayAlias(AA, MI, false))
- HasAliasedStore = true;
- StoreInstrCache[BlockPair].push_back(&I);
- }
- }
- }
- }
- // If there is no store at all, cache the result.
- if (!SawStore)
- HasStoreCache[BlockPair] = false;
- return HasAliasedStore;
-}
-
+/// hasStoreBetween - check if there is store betweeen straight line blocks From
+/// and To.
+bool MachineSinking::hasStoreBetween(MachineBasicBlock *From,
+ MachineBasicBlock *To, MachineInstr &MI) {
+ // Make sure From and To are in straight line which means From dominates To
+ // and To post dominates From.
+ if (!DT->dominates(From, To) || !PDT->dominates(To, From))
+ return true;
+
+ auto BlockPair = std::make_pair(From, To);
+
+ // Does these two blocks pair be queried before and have a definite cached
+ // result?
+ if (HasStoreCache.find(BlockPair) != HasStoreCache.end())
+ return HasStoreCache[BlockPair];
+
+ if (StoreInstrCache.find(BlockPair) != StoreInstrCache.end())
+ return llvm::any_of(StoreInstrCache[BlockPair], [&](MachineInstr *I) {
+ return I->mayAlias(AA, MI, false);
+ });
+
+ bool SawStore = false;
+ bool HasAliasedStore = false;
+ DenseSet<MachineBasicBlock *> HandledBlocks;
+ DenseSet<MachineBasicBlock *> HandledDomBlocks;
+ // Go through all reachable blocks from From.
+ for (MachineBasicBlock *BB : depth_first(From)) {
+ // We insert the instruction at the start of block To, so no need to worry
+ // about stores inside To.
+ // Store in block From should be already considered when just enter function
+ // SinkInstruction.
+ if (BB == To || BB == From)
+ continue;
+
+ // We already handle this BB in previous iteration.
+ if (HandledBlocks.count(BB))
+ continue;
+
+ HandledBlocks.insert(BB);
+ // To post dominates BB, it must be a path from block From.
+ if (PDT->dominates(To, BB)) {
+ if (!HandledDomBlocks.count(BB))
+ HandledDomBlocks.insert(BB);
+
+ // If this BB is too big or the block number in straight line between From
+ // and To is too big, stop searching to save compiling time.
+ if (BB->size() > SinkLoadInstsPerBlockThreshold ||
+ HandledDomBlocks.size() > SinkLoadBlocksThreshold) {
+ for (auto *DomBB : HandledDomBlocks) {
+ if (DomBB != BB && DT->dominates(DomBB, BB))
+ HasStoreCache[std::make_pair(DomBB, To)] = true;
+ else if(DomBB != BB && DT->dominates(BB, DomBB))
+ HasStoreCache[std::make_pair(From, DomBB)] = true;
+ }
+ HasStoreCache[BlockPair] = true;
+ return true;
+ }
+
+ for (MachineInstr &I : *BB) {
+ // Treat as alias conservatively for a call or an ordered memory
+ // operation.
+ if (I.isCall() || I.hasOrderedMemoryRef()) {
+ for (auto *DomBB : HandledDomBlocks) {
+ if (DomBB != BB && DT->dominates(DomBB, BB))
+ HasStoreCache[std::make_pair(DomBB, To)] = true;
+ else if(DomBB != BB && DT->dominates(BB, DomBB))
+ HasStoreCache[std::make_pair(From, DomBB)] = true;
+ }
+ HasStoreCache[BlockPair] = true;
+ return true;
+ }
+
+ if (I.mayStore()) {
+ SawStore = true;
+ // We still have chance to sink MI if all stores between are not
+ // aliased to MI.
+ // Cache all store instructions, so that we don't need to go through
+ // all From reachable blocks for next load instruction.
+ if (I.mayAlias(AA, MI, false))
+ HasAliasedStore = true;
+ StoreInstrCache[BlockPair].push_back(&I);
+ }
+ }
+ }
+ }
+ // If there is no store at all, cache the result.
+ if (!SawStore)
+ HasStoreCache[BlockPair] = false;
+ return HasAliasedStore;
+}
+
/// SinkInstruction - Determine whether it is safe to sink the specified machine
/// instruction out of its current block into a successor.
bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore,
@@ -1158,9 +1158,9 @@ bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore,
// We cannot sink a load across a critical edge - there may be stores in
// other code paths.
bool TryBreak = false;
- bool Store =
- MI.mayLoad() ? hasStoreBetween(ParentBlock, SuccToSinkTo, MI) : true;
- if (!MI.isSafeToMove(AA, Store)) {
+ bool Store =
+ MI.mayLoad() ? hasStoreBetween(ParentBlock, SuccToSinkTo, MI) : true;
+ if (!MI.isSafeToMove(AA, Store)) {
LLVM_DEBUG(dbgs() << " *** NOTE: Won't sink load along critical edge.\n");
TryBreak = true;
}
@@ -1491,9 +1491,9 @@ static bool hasRegisterDependency(MachineInstr *MI,
return HasRegDependency;
}
-static SmallSet<MCRegister, 4> getRegUnits(MCRegister Reg,
- const TargetRegisterInfo *TRI) {
- SmallSet<MCRegister, 4> RegUnits;
+static SmallSet<MCRegister, 4> getRegUnits(MCRegister Reg,
+ const TargetRegisterInfo *TRI) {
+ SmallSet<MCRegister, 4> RegUnits;
for (auto RI = MCRegUnitIterator(Reg, TRI); RI.isValid(); ++RI)
RegUnits.insert(*RI);
return RegUnits;
@@ -1543,8 +1543,8 @@ bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB,
continue;
// Record debug use of each reg unit.
- SmallSet<MCRegister, 4> Units = getRegUnits(MO.getReg(), TRI);
- for (MCRegister Reg : Units)
+ SmallSet<MCRegister, 4> Units = getRegUnits(MO.getReg(), TRI);
+ for (MCRegister Reg : Units)
SeenDbgInstrs[Reg].push_back(MI);
}
continue;
@@ -1592,13 +1592,13 @@ bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB,
if (!MO.isReg() || !MO.isDef())
continue;
- SmallSet<MCRegister, 4> Units = getRegUnits(MO.getReg(), TRI);
- for (MCRegister Reg : Units)
+ SmallSet<MCRegister, 4> Units = getRegUnits(MO.getReg(), TRI);
+ for (MCRegister Reg : Units)
for (auto *MI : SeenDbgInstrs.lookup(Reg))
DbgValsToSinkSet.insert(MI);
}
- SmallVector<MachineInstr *, 4> DbgValsToSink(DbgValsToSinkSet.begin(),
- DbgValsToSinkSet.end());
+ SmallVector<MachineInstr *, 4> DbgValsToSink(DbgValsToSinkSet.begin(),
+ DbgValsToSinkSet.end());
// Clear the kill flag if SrcReg is killed between MI and the end of the
// block.
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineStableHash.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineStableHash.cpp
index 7496a9c771..fb14f0a332 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineStableHash.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineStableHash.cpp
@@ -1,194 +1,194 @@
-//===- lib/CodeGen/MachineStableHash.cpp ----------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Stable hashing for MachineInstr and MachineOperand. Useful or getting a
-// hash across runs, modules, etc.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/MachineStableHash.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Analysis/Loads.h"
-#include "llvm/Analysis/MemoryLocation.h"
-#include "llvm/CodeGen/MIRFormatter.h"
-#include "llvm/CodeGen/MIRPrinter.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineJumpTableInfo.h"
-#include "llvm/CodeGen/MachineOperand.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/StableHashing.h"
-#include "llvm/CodeGen/TargetInstrInfo.h"
-#include "llvm/CodeGen/TargetRegisterInfo.h"
-#include "llvm/Config/llvm-config.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/IRPrintingPasses.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/ModuleSlotTracker.h"
-#include "llvm/MC/MCDwarf.h"
-#include "llvm/Target/TargetIntrinsicInfo.h"
-#include "llvm/Target/TargetMachine.h"
-
-#define DEBUG_TYPE "machine-stable-hash"
-
-using namespace llvm;
-
-STATISTIC(StableHashBailingMachineBasicBlock,
- "Number of encountered unsupported MachineOperands that were "
- "MachineBasicBlocks while computing stable hashes");
-STATISTIC(StableHashBailingConstantPoolIndex,
- "Number of encountered unsupported MachineOperands that were "
- "ConstantPoolIndex while computing stable hashes");
-STATISTIC(StableHashBailingTargetIndexNoName,
- "Number of encountered unsupported MachineOperands that were "
- "TargetIndex with no name");
-STATISTIC(StableHashBailingGlobalAddress,
- "Number of encountered unsupported MachineOperands that were "
- "GlobalAddress while computing stable hashes");
-STATISTIC(StableHashBailingBlockAddress,
- "Number of encountered unsupported MachineOperands that were "
- "BlockAddress while computing stable hashes");
-STATISTIC(StableHashBailingMetadataUnsupported,
- "Number of encountered unsupported MachineOperands that were "
- "Metadata of an unsupported kind while computing stable hashes");
-
-stable_hash llvm::stableHashValue(const MachineOperand &MO) {
- switch (MO.getType()) {
- case MachineOperand::MO_Register:
- if (Register::isVirtualRegister(MO.getReg())) {
- const MachineRegisterInfo &MRI = MO.getParent()->getMF()->getRegInfo();
- return MRI.getVRegDef(MO.getReg())->getOpcode();
- }
-
- // Register operands don't have target flags.
- return stable_hash_combine(MO.getType(), MO.getReg(), MO.getSubReg(),
- MO.isDef());
- case MachineOperand::MO_Immediate:
- return stable_hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm());
- case MachineOperand::MO_CImmediate:
- case MachineOperand::MO_FPImmediate: {
- auto Val = MO.isCImm() ? MO.getCImm()->getValue()
- : MO.getFPImm()->getValueAPF().bitcastToAPInt();
- auto ValHash =
- stable_hash_combine_array(Val.getRawData(), Val.getNumWords());
- return hash_combine(MO.getType(), MO.getTargetFlags(), ValHash);
- }
-
- case MachineOperand::MO_MachineBasicBlock:
- StableHashBailingMachineBasicBlock++;
- return 0;
- case MachineOperand::MO_ConstantPoolIndex:
- StableHashBailingConstantPoolIndex++;
- return 0;
- case MachineOperand::MO_BlockAddress:
- StableHashBailingBlockAddress++;
- return 0;
- case MachineOperand::MO_Metadata:
- StableHashBailingMetadataUnsupported++;
- return 0;
- case MachineOperand::MO_GlobalAddress:
- StableHashBailingGlobalAddress++;
- return 0;
- case MachineOperand::MO_TargetIndex: {
- if (const char *Name = MO.getTargetIndexName())
- return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
- stable_hash_combine_string(Name),
- MO.getOffset());
- StableHashBailingTargetIndexNoName++;
- return 0;
- }
-
- case MachineOperand::MO_FrameIndex:
- case MachineOperand::MO_JumpTableIndex:
- return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
- MO.getIndex());
-
- case MachineOperand::MO_ExternalSymbol:
- return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(),
- stable_hash_combine_string(MO.getSymbolName()));
-
- case MachineOperand::MO_RegisterMask:
- case MachineOperand::MO_RegisterLiveOut:
- return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask());
-
- case MachineOperand::MO_ShuffleMask: {
- std::vector<llvm::stable_hash> ShuffleMaskHashes;
-
- llvm::transform(
- MO.getShuffleMask(), std::back_inserter(ShuffleMaskHashes),
- [](int S) -> llvm::stable_hash { return llvm::stable_hash(S); });
-
- return hash_combine(MO.getType(), MO.getTargetFlags(),
- stable_hash_combine_array(ShuffleMaskHashes.data(),
- ShuffleMaskHashes.size()));
- }
- case MachineOperand::MO_MCSymbol: {
- auto SymbolName = MO.getMCSymbol()->getName();
- return hash_combine(MO.getType(), MO.getTargetFlags(),
- stable_hash_combine_string(SymbolName));
- }
- case MachineOperand::MO_CFIIndex:
- return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
- MO.getCFIIndex());
- case MachineOperand::MO_IntrinsicID:
- return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
- MO.getIntrinsicID());
- case MachineOperand::MO_Predicate:
- return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
- MO.getPredicate());
- }
- llvm_unreachable("Invalid machine operand type");
-}
-
-/// A stable hash value for machine instructions.
-/// Returns 0 if no stable hash could be computed.
-/// The hashing and equality testing functions ignore definitions so this is
-/// useful for CSE, etc.
-stable_hash llvm::stableHashValue(const MachineInstr &MI, bool HashVRegs,
- bool HashConstantPoolIndices,
- bool HashMemOperands) {
- // Build up a buffer of hash code components.
- SmallVector<stable_hash, 16> HashComponents;
- HashComponents.reserve(MI.getNumOperands() + MI.getNumMemOperands() + 2);
- HashComponents.push_back(MI.getOpcode());
- HashComponents.push_back(MI.getFlags());
- for (const MachineOperand &MO : MI.operands()) {
- if (!HashVRegs && MO.isReg() && MO.isDef() &&
- Register::isVirtualRegister(MO.getReg()))
- continue; // Skip virtual register defs.
-
- if (MO.isCPI()) {
- HashComponents.push_back(stable_hash_combine(
- MO.getType(), MO.getTargetFlags(), MO.getIndex()));
- continue;
- }
-
- stable_hash StableHash = stableHashValue(MO);
- if (!StableHash)
- return 0;
- HashComponents.push_back(StableHash);
- }
-
- for (const auto *Op : MI.memoperands()) {
- if (!HashMemOperands)
- break;
- HashComponents.push_back(static_cast<unsigned>(Op->getSize()));
- HashComponents.push_back(static_cast<unsigned>(Op->getFlags()));
- HashComponents.push_back(static_cast<unsigned>(Op->getOffset()));
- HashComponents.push_back(static_cast<unsigned>(Op->getOrdering()));
- HashComponents.push_back(static_cast<unsigned>(Op->getAddrSpace()));
- HashComponents.push_back(static_cast<unsigned>(Op->getSyncScopeID()));
- HashComponents.push_back(static_cast<unsigned>(Op->getBaseAlign().value()));
- HashComponents.push_back(static_cast<unsigned>(Op->getFailureOrdering()));
- }
-
- return stable_hash_combine_range(HashComponents.begin(),
- HashComponents.end());
-}
+//===- lib/CodeGen/MachineStableHash.cpp ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Stable hashing for MachineInstr and MachineOperand. Useful or getting a
+// hash across runs, modules, etc.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/MachineStableHash.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/Loads.h"
+#include "llvm/Analysis/MemoryLocation.h"
+#include "llvm/CodeGen/MIRFormatter.h"
+#include "llvm/CodeGen/MIRPrinter.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/StableHashing.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/Config/llvm-config.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRPrintingPasses.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/ModuleSlotTracker.h"
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/Target/TargetIntrinsicInfo.h"
+#include "llvm/Target/TargetMachine.h"
+
+#define DEBUG_TYPE "machine-stable-hash"
+
+using namespace llvm;
+
+STATISTIC(StableHashBailingMachineBasicBlock,
+ "Number of encountered unsupported MachineOperands that were "
+ "MachineBasicBlocks while computing stable hashes");
+STATISTIC(StableHashBailingConstantPoolIndex,
+ "Number of encountered unsupported MachineOperands that were "
+ "ConstantPoolIndex while computing stable hashes");
+STATISTIC(StableHashBailingTargetIndexNoName,
+ "Number of encountered unsupported MachineOperands that were "
+ "TargetIndex with no name");
+STATISTIC(StableHashBailingGlobalAddress,
+ "Number of encountered unsupported MachineOperands that were "
+ "GlobalAddress while computing stable hashes");
+STATISTIC(StableHashBailingBlockAddress,
+ "Number of encountered unsupported MachineOperands that were "
+ "BlockAddress while computing stable hashes");
+STATISTIC(StableHashBailingMetadataUnsupported,
+ "Number of encountered unsupported MachineOperands that were "
+ "Metadata of an unsupported kind while computing stable hashes");
+
+stable_hash llvm::stableHashValue(const MachineOperand &MO) {
+ switch (MO.getType()) {
+ case MachineOperand::MO_Register:
+ if (Register::isVirtualRegister(MO.getReg())) {
+ const MachineRegisterInfo &MRI = MO.getParent()->getMF()->getRegInfo();
+ return MRI.getVRegDef(MO.getReg())->getOpcode();
+ }
+
+ // Register operands don't have target flags.
+ return stable_hash_combine(MO.getType(), MO.getReg(), MO.getSubReg(),
+ MO.isDef());
+ case MachineOperand::MO_Immediate:
+ return stable_hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm());
+ case MachineOperand::MO_CImmediate:
+ case MachineOperand::MO_FPImmediate: {
+ auto Val = MO.isCImm() ? MO.getCImm()->getValue()
+ : MO.getFPImm()->getValueAPF().bitcastToAPInt();
+ auto ValHash =
+ stable_hash_combine_array(Val.getRawData(), Val.getNumWords());
+ return hash_combine(MO.getType(), MO.getTargetFlags(), ValHash);
+ }
+
+ case MachineOperand::MO_MachineBasicBlock:
+ StableHashBailingMachineBasicBlock++;
+ return 0;
+ case MachineOperand::MO_ConstantPoolIndex:
+ StableHashBailingConstantPoolIndex++;
+ return 0;
+ case MachineOperand::MO_BlockAddress:
+ StableHashBailingBlockAddress++;
+ return 0;
+ case MachineOperand::MO_Metadata:
+ StableHashBailingMetadataUnsupported++;
+ return 0;
+ case MachineOperand::MO_GlobalAddress:
+ StableHashBailingGlobalAddress++;
+ return 0;
+ case MachineOperand::MO_TargetIndex: {
+ if (const char *Name = MO.getTargetIndexName())
+ return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
+ stable_hash_combine_string(Name),
+ MO.getOffset());
+ StableHashBailingTargetIndexNoName++;
+ return 0;
+ }
+
+ case MachineOperand::MO_FrameIndex:
+ case MachineOperand::MO_JumpTableIndex:
+ return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
+ MO.getIndex());
+
+ case MachineOperand::MO_ExternalSymbol:
+ return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(),
+ stable_hash_combine_string(MO.getSymbolName()));
+
+ case MachineOperand::MO_RegisterMask:
+ case MachineOperand::MO_RegisterLiveOut:
+ return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask());
+
+ case MachineOperand::MO_ShuffleMask: {
+ std::vector<llvm::stable_hash> ShuffleMaskHashes;
+
+ llvm::transform(
+ MO.getShuffleMask(), std::back_inserter(ShuffleMaskHashes),
+ [](int S) -> llvm::stable_hash { return llvm::stable_hash(S); });
+
+ return hash_combine(MO.getType(), MO.getTargetFlags(),
+ stable_hash_combine_array(ShuffleMaskHashes.data(),
+ ShuffleMaskHashes.size()));
+ }
+ case MachineOperand::MO_MCSymbol: {
+ auto SymbolName = MO.getMCSymbol()->getName();
+ return hash_combine(MO.getType(), MO.getTargetFlags(),
+ stable_hash_combine_string(SymbolName));
+ }
+ case MachineOperand::MO_CFIIndex:
+ return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
+ MO.getCFIIndex());
+ case MachineOperand::MO_IntrinsicID:
+ return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
+ MO.getIntrinsicID());
+ case MachineOperand::MO_Predicate:
+ return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
+ MO.getPredicate());
+ }
+ llvm_unreachable("Invalid machine operand type");
+}
+
+/// A stable hash value for machine instructions.
+/// Returns 0 if no stable hash could be computed.
+/// The hashing and equality testing functions ignore definitions so this is
+/// useful for CSE, etc.
+stable_hash llvm::stableHashValue(const MachineInstr &MI, bool HashVRegs,
+ bool HashConstantPoolIndices,
+ bool HashMemOperands) {
+ // Build up a buffer of hash code components.
+ SmallVector<stable_hash, 16> HashComponents;
+ HashComponents.reserve(MI.getNumOperands() + MI.getNumMemOperands() + 2);
+ HashComponents.push_back(MI.getOpcode());
+ HashComponents.push_back(MI.getFlags());
+ for (const MachineOperand &MO : MI.operands()) {
+ if (!HashVRegs && MO.isReg() && MO.isDef() &&
+ Register::isVirtualRegister(MO.getReg()))
+ continue; // Skip virtual register defs.
+
+ if (MO.isCPI()) {
+ HashComponents.push_back(stable_hash_combine(
+ MO.getType(), MO.getTargetFlags(), MO.getIndex()));
+ continue;
+ }
+
+ stable_hash StableHash = stableHashValue(MO);
+ if (!StableHash)
+ return 0;
+ HashComponents.push_back(StableHash);
+ }
+
+ for (const auto *Op : MI.memoperands()) {
+ if (!HashMemOperands)
+ break;
+ HashComponents.push_back(static_cast<unsigned>(Op->getSize()));
+ HashComponents.push_back(static_cast<unsigned>(Op->getFlags()));
+ HashComponents.push_back(static_cast<unsigned>(Op->getOffset()));
+ HashComponents.push_back(static_cast<unsigned>(Op->getOrdering()));
+ HashComponents.push_back(static_cast<unsigned>(Op->getAddrSpace()));
+ HashComponents.push_back(static_cast<unsigned>(Op->getSyncScopeID()));
+ HashComponents.push_back(static_cast<unsigned>(Op->getBaseAlign().value()));
+ HashComponents.push_back(static_cast<unsigned>(Op->getFailureOrdering()));
+ }
+
+ return stable_hash_combine_range(HashComponents.begin(),
+ HashComponents.end());
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineTraceMetrics.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineTraceMetrics.cpp
index 34cfa4c2f1..8df23b781f 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineTraceMetrics.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineTraceMetrics.cpp
@@ -701,15 +701,15 @@ static void updatePhysDepsDownwards(const MachineInstr *UseMI,
SmallVectorImpl<DataDep> &Deps,
SparseSet<LiveRegUnit> &RegUnits,
const TargetRegisterInfo *TRI) {
- SmallVector<MCRegister, 8> Kills;
+ SmallVector<MCRegister, 8> Kills;
SmallVector<unsigned, 8> LiveDefOps;
for (MachineInstr::const_mop_iterator MI = UseMI->operands_begin(),
ME = UseMI->operands_end(); MI != ME; ++MI) {
const MachineOperand &MO = *MI;
- if (!MO.isReg() || !MO.getReg().isPhysical())
+ if (!MO.isReg() || !MO.getReg().isPhysical())
continue;
- MCRegister Reg = MO.getReg().asMCReg();
+ MCRegister Reg = MO.getReg().asMCReg();
// Track live defs and kills for updating RegUnits.
if (MO.isDef()) {
if (MO.isDead())
@@ -732,14 +732,14 @@ static void updatePhysDepsDownwards(const MachineInstr *UseMI,
// Update RegUnits to reflect live registers after UseMI.
// First kills.
- for (MCRegister Kill : Kills)
+ for (MCRegister Kill : Kills)
for (MCRegUnitIterator Units(Kill, TRI); Units.isValid(); ++Units)
RegUnits.erase(*Units);
// Second, live defs.
for (unsigned DefOp : LiveDefOps) {
- for (MCRegUnitIterator Units(UseMI->getOperand(DefOp).getReg().asMCReg(),
- TRI);
+ for (MCRegUnitIterator Units(UseMI->getOperand(DefOp).getReg().asMCReg(),
+ TRI);
Units.isValid(); ++Units) {
LiveRegUnit &LRU = RegUnits[*Units];
LRU.MI = UseMI;
@@ -765,7 +765,7 @@ computeCrossBlockCriticalPath(const TraceBlockInfo &TBI) {
assert(TBI.HasValidInstrHeights && "Missing height info");
unsigned MaxLen = 0;
for (const LiveInReg &LIR : TBI.LiveIns) {
- if (!LIR.Reg.isVirtual())
+ if (!LIR.Reg.isVirtual())
continue;
const MachineInstr *DefMI = MTM.MRI->getVRegDef(LIR.Reg);
// Ignore dependencies outside the current trace.
@@ -911,8 +911,8 @@ static unsigned updatePhysDepsUpwards(const MachineInstr &MI, unsigned Height,
continue;
// This is a def of Reg. Remove corresponding entries from RegUnits, and
// update MI Height to consider the physreg dependencies.
- for (MCRegUnitIterator Units(Reg.asMCReg(), TRI); Units.isValid();
- ++Units) {
+ for (MCRegUnitIterator Units(Reg.asMCReg(), TRI); Units.isValid();
+ ++Units) {
SparseSet<LiveRegUnit>::iterator I = RegUnits.find(*Units);
if (I == RegUnits.end())
continue;
@@ -930,15 +930,15 @@ static unsigned updatePhysDepsUpwards(const MachineInstr &MI, unsigned Height,
}
// Now we know the height of MI. Update any regunits read.
- for (size_t I = 0, E = ReadOps.size(); I != E; ++I) {
- MCRegister Reg = MI.getOperand(ReadOps[I]).getReg().asMCReg();
+ for (size_t I = 0, E = ReadOps.size(); I != E; ++I) {
+ MCRegister Reg = MI.getOperand(ReadOps[I]).getReg().asMCReg();
for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) {
LiveRegUnit &LRU = RegUnits[*Units];
// Set the height to the highest reader of the unit.
if (LRU.Cycle <= Height && LRU.MI != &MI) {
LRU.Cycle = Height;
LRU.MI = &MI;
- LRU.Op = ReadOps[I];
+ LRU.Op = ReadOps[I];
}
}
}
@@ -979,7 +979,7 @@ void MachineTraceMetrics::Ensemble::
addLiveIns(const MachineInstr *DefMI, unsigned DefOp,
ArrayRef<const MachineBasicBlock*> Trace) {
assert(!Trace.empty() && "Trace should contain at least one block");
- Register Reg = DefMI->getOperand(DefOp).getReg();
+ Register Reg = DefMI->getOperand(DefOp).getReg();
assert(Register::isVirtualRegister(Reg));
const MachineBasicBlock *DefMBB = DefMI->getParent();
@@ -1027,7 +1027,7 @@ computeInstrHeights(const MachineBasicBlock *MBB) {
if (MBB) {
TraceBlockInfo &TBI = BlockInfo[MBB->getNumber()];
for (LiveInReg &LI : TBI.LiveIns) {
- if (LI.Reg.isVirtual()) {
+ if (LI.Reg.isVirtual()) {
// For virtual registers, the def latency is included.
unsigned &Height = Heights[MTM.MRI->getVRegDef(LI.Reg)];
if (Height < LI.Height)
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineVerifier.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineVerifier.cpp
index 9e4409ac3e..0f6d9b888f 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineVerifier.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineVerifier.cpp
@@ -86,7 +86,7 @@ namespace {
struct MachineVerifier {
MachineVerifier(Pass *pass, const char *b) : PASS(pass), Banner(b) {}
- unsigned verify(const MachineFunction &MF);
+ unsigned verify(const MachineFunction &MF);
Pass *const PASS;
const char *Banner;
@@ -102,10 +102,10 @@ namespace {
bool isFunctionRegBankSelected;
bool isFunctionSelected;
- using RegVector = SmallVector<Register, 16>;
+ using RegVector = SmallVector<Register, 16>;
using RegMaskVector = SmallVector<const uint32_t *, 4>;
- using RegSet = DenseSet<Register>;
- using RegMap = DenseMap<Register, const MachineInstr *>;
+ using RegSet = DenseSet<Register>;
+ using RegMap = DenseMap<Register, const MachineInstr *>;
using BlockSet = SmallPtrSet<const MachineBasicBlock *, 8>;
const MachineInstr *FirstNonPHI;
@@ -120,10 +120,10 @@ namespace {
SlotIndex lastIndex;
// Add Reg and any sub-registers to RV
- void addRegWithSubRegs(RegVector &RV, Register Reg) {
+ void addRegWithSubRegs(RegVector &RV, Register Reg) {
RV.push_back(Reg);
- if (Reg.isPhysical())
- append_range(RV, TRI->subregs(Reg.asMCReg()));
+ if (Reg.isPhysical())
+ append_range(RV, TRI->subregs(Reg.asMCReg()));
}
struct BBInfo {
@@ -131,8 +131,8 @@ namespace {
bool reachable = false;
// Vregs that must be live in because they are used without being
- // defined. Map value is the user. vregsLiveIn doesn't include regs
- // that only are used by PHI nodes.
+ // defined. Map value is the user. vregsLiveIn doesn't include regs
+ // that only are used by PHI nodes.
RegMap vregsLiveIn;
// Regs killed in MBB. They may be defined again, and will then be in both
@@ -158,8 +158,8 @@ namespace {
// Add register to vregsRequired if it belongs there. Return true if
// anything changed.
- bool addRequired(Register Reg) {
- if (!Reg.isVirtual())
+ bool addRequired(Register Reg) {
+ if (!Reg.isVirtual())
return false;
if (regsLiveOut.count(Reg))
return false;
@@ -169,7 +169,7 @@ namespace {
// Same for a full set.
bool addRequired(const RegSet &RS) {
bool Changed = false;
- for (Register Reg : RS)
+ for (Register Reg : RS)
Changed |= addRequired(Reg);
return Changed;
}
@@ -183,7 +183,7 @@ namespace {
}
// Live-out registers are either in regsLiveOut or vregsPassed.
- bool isLiveOut(Register Reg) const {
+ bool isLiveOut(Register Reg) const {
return regsLiveOut.count(Reg) || vregsPassed.count(Reg);
}
};
@@ -191,13 +191,13 @@ namespace {
// Extra register info per MBB.
DenseMap<const MachineBasicBlock*, BBInfo> MBBInfoMap;
- bool isReserved(Register Reg) {
- return Reg.id() < regsReserved.size() && regsReserved.test(Reg.id());
+ bool isReserved(Register Reg) {
+ return Reg.id() < regsReserved.size() && regsReserved.test(Reg.id());
}
- bool isAllocatable(Register Reg) const {
- return Reg.id() < TRI->getNumRegs() && TRI->isInAllocatableClass(Reg) &&
- !regsReserved.test(Reg.id());
+ bool isAllocatable(Register Reg) const {
+ return Reg.id() < TRI->getNumRegs() && TRI->isInAllocatableClass(Reg) &&
+ !regsReserved.test(Reg.id());
}
// Analysis information if available
@@ -225,7 +225,7 @@ namespace {
LLT MOVRegType = LLT{});
void report_context(const LiveInterval &LI) const;
- void report_context(const LiveRange &LR, Register VRegUnit,
+ void report_context(const LiveRange &LR, Register VRegUnit,
LaneBitmask LaneMask) const;
void report_context(const LiveRange::Segment &S) const;
void report_context(const VNInfo &VNI) const;
@@ -233,19 +233,19 @@ namespace {
void report_context(MCPhysReg PhysReg) const;
void report_context_liverange(const LiveRange &LR) const;
void report_context_lanemask(LaneBitmask LaneMask) const;
- void report_context_vreg(Register VReg) const;
- void report_context_vreg_regunit(Register VRegOrUnit) const;
+ void report_context_vreg(Register VReg) const;
+ void report_context_vreg_regunit(Register VRegOrUnit) const;
void verifyInlineAsm(const MachineInstr *MI);
void checkLiveness(const MachineOperand *MO, unsigned MONum);
void checkLivenessAtUse(const MachineOperand *MO, unsigned MONum,
- SlotIndex UseIdx, const LiveRange &LR,
- Register VRegOrUnit,
+ SlotIndex UseIdx, const LiveRange &LR,
+ Register VRegOrUnit,
LaneBitmask LaneMask = LaneBitmask::getNone());
void checkLivenessAtDef(const MachineOperand *MO, unsigned MONum,
- SlotIndex DefIdx, const LiveRange &LR,
- Register VRegOrUnit, bool SubRangeCheck = false,
+ SlotIndex DefIdx, const LiveRange &LR,
+ Register VRegOrUnit, bool SubRangeCheck = false,
LaneBitmask LaneMask = LaneBitmask::getNone());
void markReachable(const MachineBasicBlock *MBB);
@@ -256,12 +256,12 @@ namespace {
void verifyLiveVariables();
void verifyLiveIntervals();
void verifyLiveInterval(const LiveInterval&);
- void verifyLiveRangeValue(const LiveRange &, const VNInfo *, Register,
+ void verifyLiveRangeValue(const LiveRange &, const VNInfo *, Register,
LaneBitmask);
- void verifyLiveRangeSegment(const LiveRange &,
- const LiveRange::const_iterator I, Register,
+ void verifyLiveRangeSegment(const LiveRange &,
+ const LiveRange::const_iterator I, Register,
LaneBitmask);
- void verifyLiveRange(const LiveRange &, Register,
+ void verifyLiveRange(const LiveRange &, Register,
LaneBitmask LaneMask = LaneBitmask::getNone());
void verifyStackFrame();
@@ -304,19 +304,19 @@ FunctionPass *llvm::createMachineVerifierPass(const std::string &Banner) {
return new MachineVerifierPass(Banner);
}
-void llvm::verifyMachineFunction(MachineFunctionAnalysisManager *,
- const std::string &Banner,
- const MachineFunction &MF) {
- // TODO: Use MFAM after porting below analyses.
- // LiveVariables *LiveVars;
- // LiveIntervals *LiveInts;
- // LiveStacks *LiveStks;
- // SlotIndexes *Indexes;
- unsigned FoundErrors = MachineVerifier(nullptr, Banner.c_str()).verify(MF);
- if (FoundErrors)
- report_fatal_error("Found " + Twine(FoundErrors) + " machine code errors.");
-}
-
+void llvm::verifyMachineFunction(MachineFunctionAnalysisManager *,
+ const std::string &Banner,
+ const MachineFunction &MF) {
+ // TODO: Use MFAM after porting below analyses.
+ // LiveVariables *LiveVars;
+ // LiveIntervals *LiveInts;
+ // LiveStacks *LiveStks;
+ // SlotIndexes *Indexes;
+ unsigned FoundErrors = MachineVerifier(nullptr, Banner.c_str()).verify(MF);
+ if (FoundErrors)
+ report_fatal_error("Found " + Twine(FoundErrors) + " machine code errors.");
+}
+
bool MachineFunction::verify(Pass *p, const char *Banner, bool AbortOnErrors)
const {
MachineFunction &MF = const_cast<MachineFunction&>(*this);
@@ -349,7 +349,7 @@ void MachineVerifier::verifyProperties(const MachineFunction &MF) {
report("Function has NoVRegs property but there are VReg operands", &MF);
}
-unsigned MachineVerifier::verify(const MachineFunction &MF) {
+unsigned MachineVerifier::verify(const MachineFunction &MF) {
foundErrors = 0;
this->MF = &MF;
@@ -488,7 +488,7 @@ void MachineVerifier::report(const char *msg, const MachineInstr *MI) {
errs() << "- instruction: ";
if (Indexes && Indexes->hasIndex(*MI))
errs() << Indexes->getInstructionIndex(*MI) << '\t';
- MI->print(errs(), /*IsStandalone=*/true);
+ MI->print(errs(), /*IsStandalone=*/true);
}
void MachineVerifier::report(const char *msg, const MachineOperand *MO,
@@ -508,7 +508,7 @@ void MachineVerifier::report_context(const LiveInterval &LI) const {
errs() << "- interval: " << LI << '\n';
}
-void MachineVerifier::report_context(const LiveRange &LR, Register VRegUnit,
+void MachineVerifier::report_context(const LiveRange &LR, Register VRegUnit,
LaneBitmask LaneMask) const {
report_context_liverange(LR);
report_context_vreg_regunit(VRegUnit);
@@ -532,11 +532,11 @@ void MachineVerifier::report_context(MCPhysReg PReg) const {
errs() << "- p. register: " << printReg(PReg, TRI) << '\n';
}
-void MachineVerifier::report_context_vreg(Register VReg) const {
+void MachineVerifier::report_context_vreg(Register VReg) const {
errs() << "- v. register: " << printReg(VReg, TRI) << '\n';
}
-void MachineVerifier::report_context_vreg_regunit(Register VRegOrUnit) const {
+void MachineVerifier::report_context_vreg_regunit(Register VRegOrUnit) const {
if (Register::isVirtualRegister(VRegOrUnit)) {
report_context_vreg(VRegOrUnit);
} else {
@@ -790,7 +790,7 @@ void MachineVerifier::visitMachineBundleBefore(const MachineInstr *MI) {
}
// Ensure non-terminators don't follow terminators.
- if (MI->isTerminator()) {
+ if (MI->isTerminator()) {
if (!FirstTerminator)
FirstTerminator = MI;
} else if (FirstTerminator) {
@@ -1004,15 +1004,15 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
}
case TargetOpcode::G_PHI: {
LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
- if (!DstTy.isValid() || !all_of(drop_begin(MI->operands()),
- [this, &DstTy](const MachineOperand &MO) {
- if (!MO.isReg())
- return true;
- LLT Ty = MRI->getType(MO.getReg());
- if (!Ty.isValid() || (Ty != DstTy))
- return false;
- return true;
- }))
+ if (!DstTy.isValid() || !all_of(drop_begin(MI->operands()),
+ [this, &DstTy](const MachineOperand &MO) {
+ if (!MO.isReg())
+ return true;
+ LLT Ty = MRI->getType(MO.getReg());
+ if (!Ty.isValid() || (Ty != DstTy))
+ return false;
+ return true;
+ }))
report("Generic Instruction G_PHI has operands with incompatible/missing "
"types",
MI);
@@ -1354,7 +1354,7 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
break;
}
}
-
+
break;
}
case TargetOpcode::G_SEXT_INREG: {
@@ -1432,95 +1432,95 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
}
break;
}
- case TargetOpcode::G_MEMCPY:
- case TargetOpcode::G_MEMMOVE: {
- ArrayRef<MachineMemOperand *> MMOs = MI->memoperands();
- if (MMOs.size() != 2) {
- report("memcpy/memmove must have 2 memory operands", MI);
- break;
- }
-
- if ((!MMOs[0]->isStore() || MMOs[0]->isLoad()) ||
- (MMOs[1]->isStore() || !MMOs[1]->isLoad())) {
- report("wrong memory operand types", MI);
- break;
- }
-
- if (MMOs[0]->getSize() != MMOs[1]->getSize())
- report("inconsistent memory operand sizes", MI);
-
- LLT DstPtrTy = MRI->getType(MI->getOperand(0).getReg());
- LLT SrcPtrTy = MRI->getType(MI->getOperand(1).getReg());
-
- if (!DstPtrTy.isPointer() || !SrcPtrTy.isPointer()) {
- report("memory instruction operand must be a pointer", MI);
- break;
- }
-
- if (DstPtrTy.getAddressSpace() != MMOs[0]->getAddrSpace())
- report("inconsistent store address space", MI);
- if (SrcPtrTy.getAddressSpace() != MMOs[1]->getAddrSpace())
- report("inconsistent load address space", MI);
-
- break;
- }
- case TargetOpcode::G_MEMSET: {
- ArrayRef<MachineMemOperand *> MMOs = MI->memoperands();
- if (MMOs.size() != 1) {
- report("memset must have 1 memory operand", MI);
- break;
- }
-
- if ((!MMOs[0]->isStore() || MMOs[0]->isLoad())) {
- report("memset memory operand must be a store", MI);
- break;
- }
-
- LLT DstPtrTy = MRI->getType(MI->getOperand(0).getReg());
- if (!DstPtrTy.isPointer()) {
- report("memset operand must be a pointer", MI);
- break;
- }
-
- if (DstPtrTy.getAddressSpace() != MMOs[0]->getAddrSpace())
- report("inconsistent memset address space", MI);
-
- break;
- }
- case TargetOpcode::G_VECREDUCE_SEQ_FADD:
- case TargetOpcode::G_VECREDUCE_SEQ_FMUL: {
- LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
- LLT Src1Ty = MRI->getType(MI->getOperand(1).getReg());
- LLT Src2Ty = MRI->getType(MI->getOperand(2).getReg());
- if (!DstTy.isScalar())
- report("Vector reduction requires a scalar destination type", MI);
- if (!Src1Ty.isScalar())
- report("Sequential FADD/FMUL vector reduction requires a scalar 1st operand", MI);
- if (!Src2Ty.isVector())
- report("Sequential FADD/FMUL vector reduction must have a vector 2nd operand", MI);
- break;
- }
- case TargetOpcode::G_VECREDUCE_FADD:
- case TargetOpcode::G_VECREDUCE_FMUL:
- case TargetOpcode::G_VECREDUCE_FMAX:
- case TargetOpcode::G_VECREDUCE_FMIN:
- case TargetOpcode::G_VECREDUCE_ADD:
- case TargetOpcode::G_VECREDUCE_MUL:
- case TargetOpcode::G_VECREDUCE_AND:
- case TargetOpcode::G_VECREDUCE_OR:
- case TargetOpcode::G_VECREDUCE_XOR:
- case TargetOpcode::G_VECREDUCE_SMAX:
- case TargetOpcode::G_VECREDUCE_SMIN:
- case TargetOpcode::G_VECREDUCE_UMAX:
- case TargetOpcode::G_VECREDUCE_UMIN: {
- LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
- LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
- if (!DstTy.isScalar())
- report("Vector reduction requires a scalar destination type", MI);
- if (!SrcTy.isVector())
- report("Vector reduction requires vector source=", MI);
- break;
- }
+ case TargetOpcode::G_MEMCPY:
+ case TargetOpcode::G_MEMMOVE: {
+ ArrayRef<MachineMemOperand *> MMOs = MI->memoperands();
+ if (MMOs.size() != 2) {
+ report("memcpy/memmove must have 2 memory operands", MI);
+ break;
+ }
+
+ if ((!MMOs[0]->isStore() || MMOs[0]->isLoad()) ||
+ (MMOs[1]->isStore() || !MMOs[1]->isLoad())) {
+ report("wrong memory operand types", MI);
+ break;
+ }
+
+ if (MMOs[0]->getSize() != MMOs[1]->getSize())
+ report("inconsistent memory operand sizes", MI);
+
+ LLT DstPtrTy = MRI->getType(MI->getOperand(0).getReg());
+ LLT SrcPtrTy = MRI->getType(MI->getOperand(1).getReg());
+
+ if (!DstPtrTy.isPointer() || !SrcPtrTy.isPointer()) {
+ report("memory instruction operand must be a pointer", MI);
+ break;
+ }
+
+ if (DstPtrTy.getAddressSpace() != MMOs[0]->getAddrSpace())
+ report("inconsistent store address space", MI);
+ if (SrcPtrTy.getAddressSpace() != MMOs[1]->getAddrSpace())
+ report("inconsistent load address space", MI);
+
+ break;
+ }
+ case TargetOpcode::G_MEMSET: {
+ ArrayRef<MachineMemOperand *> MMOs = MI->memoperands();
+ if (MMOs.size() != 1) {
+ report("memset must have 1 memory operand", MI);
+ break;
+ }
+
+ if ((!MMOs[0]->isStore() || MMOs[0]->isLoad())) {
+ report("memset memory operand must be a store", MI);
+ break;
+ }
+
+ LLT DstPtrTy = MRI->getType(MI->getOperand(0).getReg());
+ if (!DstPtrTy.isPointer()) {
+ report("memset operand must be a pointer", MI);
+ break;
+ }
+
+ if (DstPtrTy.getAddressSpace() != MMOs[0]->getAddrSpace())
+ report("inconsistent memset address space", MI);
+
+ break;
+ }
+ case TargetOpcode::G_VECREDUCE_SEQ_FADD:
+ case TargetOpcode::G_VECREDUCE_SEQ_FMUL: {
+ LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
+ LLT Src1Ty = MRI->getType(MI->getOperand(1).getReg());
+ LLT Src2Ty = MRI->getType(MI->getOperand(2).getReg());
+ if (!DstTy.isScalar())
+ report("Vector reduction requires a scalar destination type", MI);
+ if (!Src1Ty.isScalar())
+ report("Sequential FADD/FMUL vector reduction requires a scalar 1st operand", MI);
+ if (!Src2Ty.isVector())
+ report("Sequential FADD/FMUL vector reduction must have a vector 2nd operand", MI);
+ break;
+ }
+ case TargetOpcode::G_VECREDUCE_FADD:
+ case TargetOpcode::G_VECREDUCE_FMUL:
+ case TargetOpcode::G_VECREDUCE_FMAX:
+ case TargetOpcode::G_VECREDUCE_FMIN:
+ case TargetOpcode::G_VECREDUCE_ADD:
+ case TargetOpcode::G_VECREDUCE_MUL:
+ case TargetOpcode::G_VECREDUCE_AND:
+ case TargetOpcode::G_VECREDUCE_OR:
+ case TargetOpcode::G_VECREDUCE_XOR:
+ case TargetOpcode::G_VECREDUCE_SMAX:
+ case TargetOpcode::G_VECREDUCE_SMIN:
+ case TargetOpcode::G_VECREDUCE_UMAX:
+ case TargetOpcode::G_VECREDUCE_UMIN: {
+ LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
+ LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
+ if (!DstTy.isScalar())
+ report("Vector reduction requires a scalar destination type", MI);
+ if (!SrcTy.isVector())
+ report("Vector reduction requires vector source=", MI);
+ break;
+ }
default:
break;
}
@@ -1548,16 +1548,16 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
if (MI->isInlineAsm())
verifyInlineAsm(MI);
- // Check that unspillable terminators define a reg and have at most one use.
- if (TII->isUnspillableTerminator(MI)) {
- if (!MI->getOperand(0).isReg() || !MI->getOperand(0).isDef())
- report("Unspillable Terminator does not define a reg", MI);
- Register Def = MI->getOperand(0).getReg();
- if (Def.isVirtual() &&
- std::distance(MRI->use_nodbg_begin(Def), MRI->use_nodbg_end()) > 1)
- report("Unspillable Terminator expected to have at most one use!", MI);
- }
-
+ // Check that unspillable terminators define a reg and have at most one use.
+ if (TII->isUnspillableTerminator(MI)) {
+ if (!MI->getOperand(0).isReg() || !MI->getOperand(0).isDef())
+ report("Unspillable Terminator does not define a reg", MI);
+ Register Def = MI->getOperand(0).getReg();
+ if (Def.isVirtual() &&
+ std::distance(MRI->use_nodbg_begin(Def), MRI->use_nodbg_end()) > 1)
+ report("Unspillable Terminator expected to have at most one use!", MI);
+ }
+
// A fully-formed DBG_VALUE must have a location. Ignore partially formed
// DBG_VALUEs: these are convenient to use in tests, but should never get
// generated.
@@ -1565,11 +1565,11 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
if (!MI->getDebugLoc())
report("Missing DebugLoc for debug instruction", MI);
- // Meta instructions should never be the subject of debug value tracking,
- // they don't create a value in the output program at all.
- if (MI->isMetaInstruction() && MI->peekDebugInstrNum())
- report("Metadata instruction should not have a value tracking number", MI);
-
+ // Meta instructions should never be the subject of debug value tracking,
+ // they don't create a value in the output program at all.
+ if (MI->isMetaInstruction() && MI->peekDebugInstrNum())
+ report("Metadata instruction should not have a value tracking number", MI);
+
// Check the MachineMemOperands for basic consistency.
for (MachineMemOperand *Op : MI->memoperands()) {
if (Op->isLoad() && !MI->mayLoad())
@@ -1645,10 +1645,10 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
}
auto VerifyStackMapConstant = [&](unsigned Offset) {
- if (Offset >= MI->getNumOperands()) {
- report("stack map constant to STATEPOINT is out of range!", MI);
- return;
- }
+ if (Offset >= MI->getNumOperands()) {
+ report("stack map constant to STATEPOINT is out of range!", MI);
+ return;
+ }
if (!MI->getOperand(Offset - 1).isImm() ||
MI->getOperand(Offset - 1).getImm() != StackMaps::ConstantOp ||
!MI->getOperand(Offset).isImm())
@@ -1657,26 +1657,26 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
VerifyStackMapConstant(SO.getCCIdx());
VerifyStackMapConstant(SO.getFlagsIdx());
VerifyStackMapConstant(SO.getNumDeoptArgsIdx());
- VerifyStackMapConstant(SO.getNumGCPtrIdx());
- VerifyStackMapConstant(SO.getNumAllocaIdx());
- VerifyStackMapConstant(SO.getNumGcMapEntriesIdx());
-
- // Verify that all explicit statepoint defs are tied to gc operands as
- // they are expected to be a relocation of gc operands.
- unsigned FirstGCPtrIdx = SO.getFirstGCPtrIdx();
- unsigned LastGCPtrIdx = SO.getNumAllocaIdx() - 2;
- for (unsigned Idx = 0; Idx < MI->getNumDefs(); Idx++) {
- unsigned UseOpIdx;
- if (!MI->isRegTiedToUseOperand(Idx, &UseOpIdx)) {
- report("STATEPOINT defs expected to be tied", MI);
- break;
- }
- if (UseOpIdx < FirstGCPtrIdx || UseOpIdx > LastGCPtrIdx) {
- report("STATEPOINT def tied to non-gc operand", MI);
- break;
- }
- }
-
+ VerifyStackMapConstant(SO.getNumGCPtrIdx());
+ VerifyStackMapConstant(SO.getNumAllocaIdx());
+ VerifyStackMapConstant(SO.getNumGcMapEntriesIdx());
+
+ // Verify that all explicit statepoint defs are tied to gc operands as
+ // they are expected to be a relocation of gc operands.
+ unsigned FirstGCPtrIdx = SO.getFirstGCPtrIdx();
+ unsigned LastGCPtrIdx = SO.getNumAllocaIdx() - 2;
+ for (unsigned Idx = 0; Idx < MI->getNumDefs(); Idx++) {
+ unsigned UseOpIdx;
+ if (!MI->isRegTiedToUseOperand(Idx, &UseOpIdx)) {
+ report("STATEPOINT defs expected to be tied", MI);
+ break;
+ }
+ if (UseOpIdx < FirstGCPtrIdx || UseOpIdx > LastGCPtrIdx) {
+ report("STATEPOINT def tied to non-gc operand", MI);
+ break;
+ }
+ }
+
// TODO: verify we have properly encoded deopt arguments
} break;
}
@@ -1990,10 +1990,10 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
}
void MachineVerifier::checkLivenessAtUse(const MachineOperand *MO,
- unsigned MONum, SlotIndex UseIdx,
- const LiveRange &LR,
- Register VRegOrUnit,
- LaneBitmask LaneMask) {
+ unsigned MONum, SlotIndex UseIdx,
+ const LiveRange &LR,
+ Register VRegOrUnit,
+ LaneBitmask LaneMask) {
LiveQueryResult LRQ = LR.Query(UseIdx);
// Check if we have a segment at the use, note however that we only need one
// live subregister range, the others may be dead.
@@ -2014,11 +2014,11 @@ void MachineVerifier::checkLivenessAtUse(const MachineOperand *MO,
}
void MachineVerifier::checkLivenessAtDef(const MachineOperand *MO,
- unsigned MONum, SlotIndex DefIdx,
- const LiveRange &LR,
- Register VRegOrUnit,
- bool SubRangeCheck,
- LaneBitmask LaneMask) {
+ unsigned MONum, SlotIndex DefIdx,
+ const LiveRange &LR,
+ Register VRegOrUnit,
+ bool SubRangeCheck,
+ LaneBitmask LaneMask) {
if (const VNInfo *VNI = LR.getVNInfoAt(DefIdx)) {
assert(VNI && "NULL valno is not allowed");
if (VNI->def != DefIdx) {
@@ -2062,7 +2062,7 @@ void MachineVerifier::checkLivenessAtDef(const MachineOperand *MO,
void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
const MachineInstr *MI = MO->getParent();
- const Register Reg = MO->getReg();
+ const Register Reg = MO->getReg();
// Both use and def operands can read a register.
if (MO->readsReg()) {
@@ -2080,9 +2080,9 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
if (LiveInts && !LiveInts->isNotInMIMap(*MI)) {
SlotIndex UseIdx = LiveInts->getInstructionIndex(*MI);
// Check the cached regunit intervals.
- if (Reg.isPhysical() && !isReserved(Reg)) {
- for (MCRegUnitIterator Units(Reg.asMCReg(), TRI); Units.isValid();
- ++Units) {
+ if (Reg.isPhysical() && !isReserved(Reg)) {
+ for (MCRegUnitIterator Units(Reg.asMCReg(), TRI); Units.isValid();
+ ++Units) {
if (MRI->isReservedRegUnit(*Units))
continue;
if (const LiveRange *LR = LiveInts->getCachedRegUnit(*Units))
@@ -2228,9 +2228,9 @@ void MachineVerifier::visitMachineBundleAfter(const MachineInstr *MI) {
// Kill any masked registers.
while (!regMasks.empty()) {
const uint32_t *Mask = regMasks.pop_back_val();
- for (Register Reg : regsLive)
- if (Reg.isPhysical() &&
- MachineOperand::clobbersPhysReg(Mask, Reg.asMCReg()))
+ for (Register Reg : regsLive)
+ if (Reg.isPhysical() &&
+ MachineOperand::clobbersPhysReg(Mask, Reg.asMCReg()))
regsDead.push_back(Reg);
}
set_subtract(regsLive, regsDead); regsDead.clear();
@@ -2263,7 +2263,7 @@ struct VRegFilter {
// Add elements to the filter itself. \pre Input set \p FromRegSet must have
// no duplicates. Both virtual and physical registers are fine.
template <typename RegSetT> void add(const RegSetT &FromRegSet) {
- SmallVector<Register, 0> VRegsBuffer;
+ SmallVector<Register, 0> VRegsBuffer;
filterAndAdd(FromRegSet, VRegsBuffer);
}
// Filter \p FromRegSet through the filter and append passed elements into \p
@@ -2271,13 +2271,13 @@ struct VRegFilter {
// \returns true if anything changed.
template <typename RegSetT>
bool filterAndAdd(const RegSetT &FromRegSet,
- SmallVectorImpl<Register> &ToVRegs) {
+ SmallVectorImpl<Register> &ToVRegs) {
unsigned SparseUniverse = Sparse.size();
unsigned NewSparseUniverse = SparseUniverse;
unsigned NewDenseSize = Dense.size();
size_t Begin = ToVRegs.size();
- for (Register Reg : FromRegSet) {
- if (!Reg.isVirtual())
+ for (Register Reg : FromRegSet) {
+ if (!Reg.isVirtual())
continue;
unsigned Index = Register::virtReg2Index(Reg);
if (Index < SparseUniverseMax) {
@@ -2301,7 +2301,7 @@ struct VRegFilter {
Sparse.resize(NewSparseUniverse);
Dense.reserve(NewDenseSize);
for (unsigned I = Begin; I < End; ++I) {
- Register Reg = ToVRegs[I];
+ Register Reg = ToVRegs[I];
unsigned Index = Register::virtReg2Index(Reg);
if (Index < SparseUniverseMax)
Sparse.set(Index);
@@ -2334,7 +2334,7 @@ private:
// universe). filter_b implicitly contains all physical registers at all times.
class FilteringVRegSet {
VRegFilter Filter;
- SmallVector<Register, 0> VRegs;
+ SmallVector<Register, 0> VRegs;
public:
// Set-up the filter_b. \pre Input register set \p RS must have no duplicates.
@@ -2360,28 +2360,28 @@ public:
// can pass through an MBB live, but may not be live every time. It is assumed
// that all vregsPassed sets are empty before the call.
void MachineVerifier::calcRegsPassed() {
- if (MF->empty())
+ if (MF->empty())
// ReversePostOrderTraversal doesn't handle empty functions.
return;
-
- for (const MachineBasicBlock *MB :
+
+ for (const MachineBasicBlock *MB :
ReversePostOrderTraversal<const MachineFunction *>(MF)) {
- FilteringVRegSet VRegs;
- BBInfo &Info = MBBInfoMap[MB];
- assert(Info.reachable);
-
- VRegs.addToFilter(Info.regsKilled);
- VRegs.addToFilter(Info.regsLiveOut);
- for (const MachineBasicBlock *Pred : MB->predecessors()) {
- const BBInfo &PredInfo = MBBInfoMap[Pred];
- if (!PredInfo.reachable)
+ FilteringVRegSet VRegs;
+ BBInfo &Info = MBBInfoMap[MB];
+ assert(Info.reachable);
+
+ VRegs.addToFilter(Info.regsKilled);
+ VRegs.addToFilter(Info.regsLiveOut);
+ for (const MachineBasicBlock *Pred : MB->predecessors()) {
+ const BBInfo &PredInfo = MBBInfoMap[Pred];
+ if (!PredInfo.reachable)
continue;
-
- VRegs.add(PredInfo.regsLiveOut);
- VRegs.add(PredInfo.vregsPassed);
+
+ VRegs.add(PredInfo.regsLiveOut);
+ VRegs.add(PredInfo.vregsPassed);
}
- Info.vregsPassed.reserve(VRegs.size());
- Info.vregsPassed.insert(VRegs.begin(), VRegs.end());
+ Info.vregsPassed.reserve(VRegs.size());
+ Info.vregsPassed.insert(VRegs.begin(), VRegs.end());
}
}
@@ -2398,23 +2398,23 @@ void MachineVerifier::calcRegsRequired() {
if (PInfo.addRequired(MInfo.vregsLiveIn))
todo.insert(Pred);
}
-
- // Handle the PHI node.
- for (const MachineInstr &MI : MBB.phis()) {
- for (unsigned i = 1, e = MI.getNumOperands(); i != e; i += 2) {
- // Skip those Operands which are undef regs or not regs.
- if (!MI.getOperand(i).isReg() || !MI.getOperand(i).readsReg())
- continue;
-
- // Get register and predecessor for one PHI edge.
- Register Reg = MI.getOperand(i).getReg();
- const MachineBasicBlock *Pred = MI.getOperand(i + 1).getMBB();
-
- BBInfo &PInfo = MBBInfoMap[Pred];
- if (PInfo.addRequired(Reg))
- todo.insert(Pred);
- }
- }
+
+ // Handle the PHI node.
+ for (const MachineInstr &MI : MBB.phis()) {
+ for (unsigned i = 1, e = MI.getNumOperands(); i != e; i += 2) {
+ // Skip those Operands which are undef regs or not regs.
+ if (!MI.getOperand(i).isReg() || !MI.getOperand(i).readsReg())
+ continue;
+
+ // Get register and predecessor for one PHI edge.
+ Register Reg = MI.getOperand(i).getReg();
+ const MachineBasicBlock *Pred = MI.getOperand(i + 1).getMBB();
+
+ BBInfo &PInfo = MBBInfoMap[Pred];
+ if (PInfo.addRequired(Reg))
+ todo.insert(Pred);
+ }
+ }
}
// Iteratively push vregsRequired to predecessors. This will converge to the
@@ -2512,7 +2512,7 @@ void MachineVerifier::visitMachineFunctionAfter() {
// Check for killed virtual registers that should be live out.
for (const auto &MBB : *MF) {
BBInfo &MInfo = MBBInfoMap[&MBB];
- for (Register VReg : MInfo.vregsRequired)
+ for (Register VReg : MInfo.vregsRequired)
if (MInfo.regsKilled.count(VReg)) {
report("Virtual register killed in block, but needed live out.", &MBB);
errs() << "Virtual register " << printReg(VReg)
@@ -2522,7 +2522,7 @@ void MachineVerifier::visitMachineFunctionAfter() {
if (!MF->empty()) {
BBInfo &MInfo = MBBInfoMap[&MF->front()];
- for (Register VReg : MInfo.vregsRequired) {
+ for (Register VReg : MInfo.vregsRequired) {
report("Virtual register defs don't dominate all uses.", MF);
report_context_vreg(VReg);
}
@@ -2562,27 +2562,27 @@ void MachineVerifier::visitMachineFunctionAfter() {
for (auto CSInfo : MF->getCallSitesInfo())
if (!CSInfo.first->isCall())
report("Call site info referencing instruction that is not call", MF);
-
- // If there's debug-info, check that we don't have any duplicate value
- // tracking numbers.
- if (MF->getFunction().getSubprogram()) {
- DenseSet<unsigned> SeenNumbers;
- for (auto &MBB : *MF) {
- for (auto &MI : MBB) {
- if (auto Num = MI.peekDebugInstrNum()) {
- auto Result = SeenNumbers.insert((unsigned)Num);
- if (!Result.second)
- report("Instruction has a duplicated value tracking number", &MI);
- }
- }
- }
- }
+
+ // If there's debug-info, check that we don't have any duplicate value
+ // tracking numbers.
+ if (MF->getFunction().getSubprogram()) {
+ DenseSet<unsigned> SeenNumbers;
+ for (auto &MBB : *MF) {
+ for (auto &MI : MBB) {
+ if (auto Num = MI.peekDebugInstrNum()) {
+ auto Result = SeenNumbers.insert((unsigned)Num);
+ if (!Result.second)
+ report("Instruction has a duplicated value tracking number", &MI);
+ }
+ }
+ }
+ }
}
void MachineVerifier::verifyLiveVariables() {
assert(LiveVars && "Don't call verifyLiveVariables without LiveVars");
- for (unsigned I = 0, E = MRI->getNumVirtRegs(); I != E; ++I) {
- Register Reg = Register::index2VirtReg(I);
+ for (unsigned I = 0, E = MRI->getNumVirtRegs(); I != E; ++I) {
+ Register Reg = Register::index2VirtReg(I);
LiveVariables::VarInfo &VI = LiveVars->getVarInfo(Reg);
for (const auto &MBB : *MF) {
BBInfo &MInfo = MBBInfoMap[&MBB];
@@ -2607,8 +2607,8 @@ void MachineVerifier::verifyLiveVariables() {
void MachineVerifier::verifyLiveIntervals() {
assert(LiveInts && "Don't call verifyLiveIntervals without LiveInts");
- for (unsigned I = 0, E = MRI->getNumVirtRegs(); I != E; ++I) {
- Register Reg = Register::index2VirtReg(I);
+ for (unsigned I = 0, E = MRI->getNumVirtRegs(); I != E; ++I) {
+ Register Reg = Register::index2VirtReg(I);
// Spilling and splitting may leave unused registers around. Skip them.
if (MRI->reg_nodbg_empty(Reg))
@@ -2621,7 +2621,7 @@ void MachineVerifier::verifyLiveIntervals() {
}
const LiveInterval &LI = LiveInts->getInterval(Reg);
- assert(Reg == LI.reg() && "Invalid reg to interval mapping");
+ assert(Reg == LI.reg() && "Invalid reg to interval mapping");
verifyLiveInterval(LI);
}
@@ -2632,7 +2632,7 @@ void MachineVerifier::verifyLiveIntervals() {
}
void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
- const VNInfo *VNI, Register Reg,
+ const VNInfo *VNI, Register Reg,
LaneBitmask LaneMask) {
if (VNI->isUnused())
return;
@@ -2725,8 +2725,8 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
const LiveRange::const_iterator I,
- Register Reg,
- LaneBitmask LaneMask) {
+ Register Reg,
+ LaneBitmask LaneMask) {
const LiveRange::Segment &S = *I;
const VNInfo *VNI = S.valno;
assert(VNI && "Live segment has no valno");
@@ -2937,7 +2937,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
}
}
-void MachineVerifier::verifyLiveRange(const LiveRange &LR, Register Reg,
+void MachineVerifier::verifyLiveRange(const LiveRange &LR, Register Reg,
LaneBitmask LaneMask) {
for (const VNInfo *VNI : LR.valnos)
verifyLiveRangeValue(LR, VNI, Reg, LaneMask);
@@ -2947,7 +2947,7 @@ void MachineVerifier::verifyLiveRange(const LiveRange &LR, Register Reg,
}
void MachineVerifier::verifyLiveInterval(const LiveInterval &LI) {
- Register Reg = LI.reg();
+ Register Reg = LI.reg();
assert(Register::isVirtualRegister(Reg));
verifyLiveRange(LI, Reg);
@@ -2964,10 +2964,10 @@ void MachineVerifier::verifyLiveInterval(const LiveInterval &LI) {
}
if (SR.empty()) {
report("Subrange must not be empty", MF);
- report_context(SR, LI.reg(), SR.LaneMask);
+ report_context(SR, LI.reg(), SR.LaneMask);
}
Mask |= SR.LaneMask;
- verifyLiveRange(SR, LI.reg(), SR.LaneMask);
+ verifyLiveRange(SR, LI.reg(), SR.LaneMask);
if (!LI.covers(SR)) {
report("A Subrange is not covered by the main range", MF);
report_context(LI);
diff --git a/contrib/libs/llvm12/lib/CodeGen/MultiHazardRecognizer.cpp b/contrib/libs/llvm12/lib/CodeGen/MultiHazardRecognizer.cpp
index 7b325e504d..e4cd92ac48 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MultiHazardRecognizer.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MultiHazardRecognizer.cpp
@@ -1,92 +1,92 @@
-//===- MultiHazardRecognizer.cpp - Scheduler Support ----------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the MultiHazardRecognizer class, which is a wrapper
-// for a set of ScheduleHazardRecognizer instances
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/MultiHazardRecognizer.h"
-#include "llvm/ADT/STLExtras.h"
-#include <algorithm>
-#include <functional>
-#include <numeric>
-
-using namespace llvm;
-
-void MultiHazardRecognizer::AddHazardRecognizer(
- std::unique_ptr<ScheduleHazardRecognizer> &&R) {
- MaxLookAhead = std::max(MaxLookAhead, R->getMaxLookAhead());
- Recognizers.push_back(std::move(R));
-}
-
-bool MultiHazardRecognizer::atIssueLimit() const {
- return llvm::any_of(Recognizers,
- std::mem_fn(&ScheduleHazardRecognizer::atIssueLimit));
-}
-
-ScheduleHazardRecognizer::HazardType
-MultiHazardRecognizer::getHazardType(SUnit *SU, int Stalls) {
- for (auto &R : Recognizers) {
- auto res = R->getHazardType(SU, Stalls);
- if (res != NoHazard)
- return res;
- }
- return NoHazard;
-}
-
-void MultiHazardRecognizer::Reset() {
- for (auto &R : Recognizers)
- R->Reset();
-}
-
-void MultiHazardRecognizer::EmitInstruction(SUnit *SU) {
- for (auto &R : Recognizers)
- R->EmitInstruction(SU);
-}
-
-void MultiHazardRecognizer::EmitInstruction(MachineInstr *MI) {
- for (auto &R : Recognizers)
- R->EmitInstruction(MI);
-}
-
-unsigned MultiHazardRecognizer::PreEmitNoops(SUnit *SU) {
- auto MN = [=](unsigned a, std::unique_ptr<ScheduleHazardRecognizer> &R) {
- return std::max(a, R->PreEmitNoops(SU));
- };
- return std::accumulate(Recognizers.begin(), Recognizers.end(), 0u, MN);
-}
-
-unsigned MultiHazardRecognizer::PreEmitNoops(MachineInstr *MI) {
- auto MN = [=](unsigned a, std::unique_ptr<ScheduleHazardRecognizer> &R) {
- return std::max(a, R->PreEmitNoops(MI));
- };
- return std::accumulate(Recognizers.begin(), Recognizers.end(), 0u, MN);
-}
-
-bool MultiHazardRecognizer::ShouldPreferAnother(SUnit *SU) {
- auto SPA = [=](std::unique_ptr<ScheduleHazardRecognizer> &R) {
- return R->ShouldPreferAnother(SU);
- };
- return llvm::any_of(Recognizers, SPA);
-}
-
-void MultiHazardRecognizer::AdvanceCycle() {
- for (auto &R : Recognizers)
- R->AdvanceCycle();
-}
-
-void MultiHazardRecognizer::RecedeCycle() {
- for (auto &R : Recognizers)
- R->RecedeCycle();
-}
-
-void MultiHazardRecognizer::EmitNoop() {
- for (auto &R : Recognizers)
- R->EmitNoop();
-}
+//===- MultiHazardRecognizer.cpp - Scheduler Support ----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the MultiHazardRecognizer class, which is a wrapper
+// for a set of ScheduleHazardRecognizer instances
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/MultiHazardRecognizer.h"
+#include "llvm/ADT/STLExtras.h"
+#include <algorithm>
+#include <functional>
+#include <numeric>
+
+using namespace llvm;
+
+void MultiHazardRecognizer::AddHazardRecognizer(
+ std::unique_ptr<ScheduleHazardRecognizer> &&R) {
+ MaxLookAhead = std::max(MaxLookAhead, R->getMaxLookAhead());
+ Recognizers.push_back(std::move(R));
+}
+
+bool MultiHazardRecognizer::atIssueLimit() const {
+ return llvm::any_of(Recognizers,
+ std::mem_fn(&ScheduleHazardRecognizer::atIssueLimit));
+}
+
+ScheduleHazardRecognizer::HazardType
+MultiHazardRecognizer::getHazardType(SUnit *SU, int Stalls) {
+ for (auto &R : Recognizers) {
+ auto res = R->getHazardType(SU, Stalls);
+ if (res != NoHazard)
+ return res;
+ }
+ return NoHazard;
+}
+
+void MultiHazardRecognizer::Reset() {
+ for (auto &R : Recognizers)
+ R->Reset();
+}
+
+void MultiHazardRecognizer::EmitInstruction(SUnit *SU) {
+ for (auto &R : Recognizers)
+ R->EmitInstruction(SU);
+}
+
+void MultiHazardRecognizer::EmitInstruction(MachineInstr *MI) {
+ for (auto &R : Recognizers)
+ R->EmitInstruction(MI);
+}
+
+unsigned MultiHazardRecognizer::PreEmitNoops(SUnit *SU) {
+ auto MN = [=](unsigned a, std::unique_ptr<ScheduleHazardRecognizer> &R) {
+ return std::max(a, R->PreEmitNoops(SU));
+ };
+ return std::accumulate(Recognizers.begin(), Recognizers.end(), 0u, MN);
+}
+
+unsigned MultiHazardRecognizer::PreEmitNoops(MachineInstr *MI) {
+ auto MN = [=](unsigned a, std::unique_ptr<ScheduleHazardRecognizer> &R) {
+ return std::max(a, R->PreEmitNoops(MI));
+ };
+ return std::accumulate(Recognizers.begin(), Recognizers.end(), 0u, MN);
+}
+
+bool MultiHazardRecognizer::ShouldPreferAnother(SUnit *SU) {
+ auto SPA = [=](std::unique_ptr<ScheduleHazardRecognizer> &R) {
+ return R->ShouldPreferAnother(SU);
+ };
+ return llvm::any_of(Recognizers, SPA);
+}
+
+void MultiHazardRecognizer::AdvanceCycle() {
+ for (auto &R : Recognizers)
+ R->AdvanceCycle();
+}
+
+void MultiHazardRecognizer::RecedeCycle() {
+ for (auto &R : Recognizers)
+ R->RecedeCycle();
+}
+
+void MultiHazardRecognizer::EmitNoop() {
+ for (auto &R : Recognizers)
+ R->EmitNoop();
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/PHIElimination.cpp b/contrib/libs/llvm12/lib/CodeGen/PHIElimination.cpp
index 72c2eb06dc..8148b64d84 100644
--- a/contrib/libs/llvm12/lib/CodeGen/PHIElimination.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/PHIElimination.cpp
@@ -101,10 +101,10 @@ namespace {
// These functions are temporary abstractions around LiveVariables and
// LiveIntervals, so they can go away when LiveVariables does.
- bool isLiveIn(Register Reg, const MachineBasicBlock *MBB);
- bool isLiveOutPastPHIs(Register Reg, const MachineBasicBlock *MBB);
+ bool isLiveIn(Register Reg, const MachineBasicBlock *MBB);
+ bool isLiveOutPastPHIs(Register Reg, const MachineBasicBlock *MBB);
- using BBVRegPair = std::pair<unsigned, Register>;
+ using BBVRegPair = std::pair<unsigned, Register>;
using VRegPHIUse = DenseMap<BBVRegPair, unsigned>;
VRegPHIUse VRegPHIUseCount;
@@ -324,43 +324,43 @@ void PHIElimination::LowerPHINode(MachineBasicBlock &MBB,
// Increment use count of the newly created virtual register.
LV->setPHIJoin(IncomingReg);
- MachineInstr *OldKill = nullptr;
- bool IsPHICopyAfterOldKill = false;
-
- if (reusedIncoming && (OldKill = VI.findKill(&MBB))) {
- // Calculate whether the PHICopy is after the OldKill.
- // In general, the PHICopy is inserted as the first non-phi instruction
- // by default, so it's before the OldKill. But some Target hooks for
- // createPHIDestinationCopy() may modify the default insert position of
- // PHICopy.
- for (auto I = MBB.SkipPHIsAndLabels(MBB.begin()), E = MBB.end();
- I != E; ++I) {
- if (I == PHICopy)
- break;
-
- if (I == OldKill) {
- IsPHICopyAfterOldKill = true;
- break;
- }
+ MachineInstr *OldKill = nullptr;
+ bool IsPHICopyAfterOldKill = false;
+
+ if (reusedIncoming && (OldKill = VI.findKill(&MBB))) {
+ // Calculate whether the PHICopy is after the OldKill.
+ // In general, the PHICopy is inserted as the first non-phi instruction
+ // by default, so it's before the OldKill. But some Target hooks for
+ // createPHIDestinationCopy() may modify the default insert position of
+ // PHICopy.
+ for (auto I = MBB.SkipPHIsAndLabels(MBB.begin()), E = MBB.end();
+ I != E; ++I) {
+ if (I == PHICopy)
+ break;
+
+ if (I == OldKill) {
+ IsPHICopyAfterOldKill = true;
+ break;
+ }
}
- }
-
- // When we are reusing the incoming register and it has been marked killed
- // by OldKill, if the PHICopy is after the OldKill, we should remove the
- // killed flag from OldKill.
- if (IsPHICopyAfterOldKill) {
- LLVM_DEBUG(dbgs() << "Remove old kill from " << *OldKill);
- LV->removeVirtualRegisterKilled(IncomingReg, *OldKill);
- LLVM_DEBUG(MBB.dump());
- }
-
- // Add information to LiveVariables to know that the first used incoming
- // value or the resued incoming value whose PHICopy is after the OldKIll
- // is killed. Note that because the value is defined in several places
- // (once each for each incoming block), the "def" block and instruction
- // fields for the VarInfo is not filled in.
- if (!OldKill || IsPHICopyAfterOldKill)
- LV->addVirtualRegisterKilled(IncomingReg, *PHICopy);
+ }
+
+ // When we are reusing the incoming register and it has been marked killed
+ // by OldKill, if the PHICopy is after the OldKill, we should remove the
+ // killed flag from OldKill.
+ if (IsPHICopyAfterOldKill) {
+ LLVM_DEBUG(dbgs() << "Remove old kill from " << *OldKill);
+ LV->removeVirtualRegisterKilled(IncomingReg, *OldKill);
+ LLVM_DEBUG(MBB.dump());
+ }
+
+ // Add information to LiveVariables to know that the first used incoming
+ // value or the resued incoming value whose PHICopy is after the OldKIll
+ // is killed. Note that because the value is defined in several places
+ // (once each for each incoming block), the "def" block and instruction
+ // fields for the VarInfo is not filled in.
+ if (!OldKill || IsPHICopyAfterOldKill)
+ LV->addVirtualRegisterKilled(IncomingReg, *PHICopy);
}
// Since we are going to be deleting the PHI node, if it is the last use of
@@ -394,7 +394,7 @@ void PHIElimination::LowerPHINode(MachineBasicBlock &MBB,
}
LiveInterval &DestLI = LIS->getInterval(DestReg);
- assert(!DestLI.empty() && "PHIs should have nonempty LiveIntervals.");
+ assert(!DestLI.empty() && "PHIs should have nonempty LiveIntervals.");
if (DestLI.endIndex().isDead()) {
// A dead PHI's live range begins and ends at the start of the MBB, but
// the lowered copy, which will still be dead, needs to begin and end at
@@ -441,19 +441,19 @@ void PHIElimination::LowerPHINode(MachineBasicBlock &MBB,
if (!MBBsInsertedInto.insert(&opBlock).second)
continue; // If the copy has already been emitted, we're done.
- MachineInstr *SrcRegDef = MRI->getVRegDef(SrcReg);
- if (SrcRegDef && TII->isUnspillableTerminator(SrcRegDef)) {
- assert(SrcRegDef->getOperand(0).isReg() &&
- SrcRegDef->getOperand(0).isDef() &&
- "Expected operand 0 to be a reg def!");
- // Now that the PHI's use has been removed (as the instruction was
- // removed) there should be no other uses of the SrcReg.
- assert(MRI->use_empty(SrcReg) &&
- "Expected a single use from UnspillableTerminator");
- SrcRegDef->getOperand(0).setReg(IncomingReg);
- continue;
- }
-
+ MachineInstr *SrcRegDef = MRI->getVRegDef(SrcReg);
+ if (SrcRegDef && TII->isUnspillableTerminator(SrcRegDef)) {
+ assert(SrcRegDef->getOperand(0).isReg() &&
+ SrcRegDef->getOperand(0).isDef() &&
+ "Expected operand 0 to be a reg def!");
+ // Now that the PHI's use has been removed (as the instruction was
+ // removed) there should be no other uses of the SrcReg.
+ assert(MRI->use_empty(SrcReg) &&
+ "Expected a single use from UnspillableTerminator");
+ SrcRegDef->getOperand(0).setReg(IncomingReg);
+ continue;
+ }
+
// Find a safe location to insert the copy, this may be the first terminator
// in the block (or end()).
MachineBasicBlock::iterator InsertPos =
@@ -704,7 +704,7 @@ bool PHIElimination::SplitPHIEdges(MachineFunction &MF,
return Changed;
}
-bool PHIElimination::isLiveIn(Register Reg, const MachineBasicBlock *MBB) {
+bool PHIElimination::isLiveIn(Register Reg, const MachineBasicBlock *MBB) {
assert((LV || LIS) &&
"isLiveIn() requires either LiveVariables or LiveIntervals");
if (LIS)
@@ -713,7 +713,7 @@ bool PHIElimination::isLiveIn(Register Reg, const MachineBasicBlock *MBB) {
return LV->isLiveIn(Reg, *MBB);
}
-bool PHIElimination::isLiveOutPastPHIs(Register Reg,
+bool PHIElimination::isLiveOutPastPHIs(Register Reg,
const MachineBasicBlock *MBB) {
assert((LV || LIS) &&
"isLiveOutPastPHIs() requires either LiveVariables or LiveIntervals");
diff --git a/contrib/libs/llvm12/lib/CodeGen/PHIEliminationUtils.cpp b/contrib/libs/llvm12/lib/CodeGen/PHIEliminationUtils.cpp
index 2d47960de7..016335f420 100644
--- a/contrib/libs/llvm12/lib/CodeGen/PHIEliminationUtils.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/PHIEliminationUtils.cpp
@@ -10,7 +10,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-
+
using namespace llvm;
// findCopyInsertPoint - Find a safe place in MBB to insert a copy from SrcReg
diff --git a/contrib/libs/llvm12/lib/CodeGen/ParallelCG.cpp b/contrib/libs/llvm12/lib/CodeGen/ParallelCG.cpp
index f885708399..849b667254 100644
--- a/contrib/libs/llvm12/lib/CodeGen/ParallelCG.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/ParallelCG.cpp
@@ -28,8 +28,8 @@ static void codegen(Module *M, llvm::raw_pwrite_stream &OS,
function_ref<std::unique_ptr<TargetMachine>()> TMFactory,
CodeGenFileType FileType) {
std::unique_ptr<TargetMachine> TM = TMFactory();
- assert(TM && "Failed to create target machine!");
-
+ assert(TM && "Failed to create target machine!");
+
legacy::PassManager CodeGenPasses;
if (TM->addPassesToEmitFile(CodeGenPasses, OS, nullptr, FileType))
report_fatal_error("Failed to setup codegen");
diff --git a/contrib/libs/llvm12/lib/CodeGen/PeepholeOptimizer.cpp b/contrib/libs/llvm12/lib/CodeGen/PeepholeOptimizer.cpp
index f519182d07..34ac396c04 100644
--- a/contrib/libs/llvm12/lib/CodeGen/PeepholeOptimizer.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/PeepholeOptimizer.cpp
@@ -178,11 +178,11 @@ namespace {
}
}
- MachineFunctionProperties getRequiredProperties() const override {
- return MachineFunctionProperties()
- .set(MachineFunctionProperties::Property::IsSSA);
- }
-
+ MachineFunctionProperties getRequiredProperties() const override {
+ return MachineFunctionProperties()
+ .set(MachineFunctionProperties::Property::IsSSA);
+ }
+
/// Track Def -> Use info used for rewriting copies.
using RewriteMapTy = SmallDenseMap<RegSubRegPair, ValueTrackerResult>;
@@ -201,39 +201,39 @@ namespace {
SmallPtrSetImpl<MachineInstr *> &LocalMIs);
bool optimizeRecurrence(MachineInstr &PHI);
bool findNextSource(RegSubRegPair RegSubReg, RewriteMapTy &RewriteMap);
- bool isMoveImmediate(MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
- DenseMap<Register, MachineInstr *> &ImmDefMIs);
- bool foldImmediate(MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
- DenseMap<Register, MachineInstr *> &ImmDefMIs);
+ bool isMoveImmediate(MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
+ DenseMap<Register, MachineInstr *> &ImmDefMIs);
+ bool foldImmediate(MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
+ DenseMap<Register, MachineInstr *> &ImmDefMIs);
/// Finds recurrence cycles, but only ones that formulated around
/// a def operand and a use operand that are tied. If there is a use
/// operand commutable with the tied use operand, find recurrence cycle
/// along that operand as well.
- bool findTargetRecurrence(Register Reg,
- const SmallSet<Register, 2> &TargetReg,
+ bool findTargetRecurrence(Register Reg,
+ const SmallSet<Register, 2> &TargetReg,
RecurrenceCycle &RC);
/// If copy instruction \p MI is a virtual register copy, track it in
- /// the set \p CopyMIs. If this virtual register was previously seen as a
- /// copy, replace the uses of this copy with the previously seen copy's
- /// destination register.
+ /// the set \p CopyMIs. If this virtual register was previously seen as a
+ /// copy, replace the uses of this copy with the previously seen copy's
+ /// destination register.
bool foldRedundantCopy(MachineInstr &MI,
- DenseMap<RegSubRegPair, MachineInstr *> &CopyMIs);
+ DenseMap<RegSubRegPair, MachineInstr *> &CopyMIs);
/// Is the register \p Reg a non-allocatable physical register?
- bool isNAPhysCopy(Register Reg);
+ bool isNAPhysCopy(Register Reg);
/// If copy instruction \p MI is a non-allocatable virtual<->physical
/// register copy, track it in the \p NAPhysToVirtMIs map. If this
/// non-allocatable physical register was previously copied to a virtual
/// registered and hasn't been clobbered, the virt->phys copy can be
/// deleted.
- bool foldRedundantNAPhysCopy(
- MachineInstr &MI, DenseMap<Register, MachineInstr *> &NAPhysToVirtMIs);
+ bool foldRedundantNAPhysCopy(
+ MachineInstr &MI, DenseMap<Register, MachineInstr *> &NAPhysToVirtMIs);
bool isLoadFoldable(MachineInstr &MI,
- SmallSet<Register, 16> &FoldAsLoadDefCandidates);
+ SmallSet<Register, 16> &FoldAsLoadDefCandidates);
/// Check whether \p MI is understood by the register coalescer
/// but may require some rewriting.
@@ -294,7 +294,7 @@ namespace {
public:
ValueTrackerResult() = default;
- ValueTrackerResult(Register Reg, unsigned SubReg) {
+ ValueTrackerResult(Register Reg, unsigned SubReg) {
addSource(Reg, SubReg);
}
@@ -308,11 +308,11 @@ namespace {
Inst = nullptr;
}
- void addSource(Register SrcReg, unsigned SrcSubReg) {
+ void addSource(Register SrcReg, unsigned SrcSubReg) {
RegSrcs.push_back(RegSubRegPair(SrcReg, SrcSubReg));
}
- void setSource(int Idx, Register SrcReg, unsigned SrcSubReg) {
+ void setSource(int Idx, Register SrcReg, unsigned SrcSubReg) {
assert(Idx < getNumSources() && "Reg pair source out of index");
RegSrcs[Idx] = RegSubRegPair(SrcReg, SrcSubReg);
}
@@ -323,7 +323,7 @@ namespace {
return RegSrcs[Idx];
}
- Register getSrcReg(int Idx) const {
+ Register getSrcReg(int Idx) const {
assert(Idx < getNumSources() && "Reg source out of index");
return RegSrcs[Idx].Reg;
}
@@ -376,7 +376,7 @@ namespace {
unsigned DefSubReg;
/// The register where the value can be found.
- Register Reg;
+ Register Reg;
/// MachineRegisterInfo used to perform tracking.
const MachineRegisterInfo &MRI;
@@ -418,11 +418,11 @@ namespace {
/// Indeed, when \p Reg is a physical register that constructor does not
/// know which definition of \p Reg it should track.
/// Use the next constructor to track a physical register.
- ValueTracker(Register Reg, unsigned DefSubReg,
+ ValueTracker(Register Reg, unsigned DefSubReg,
const MachineRegisterInfo &MRI,
const TargetInstrInfo *TII = nullptr)
: DefSubReg(DefSubReg), Reg(Reg), MRI(MRI), TII(TII) {
- if (!Reg.isPhysical()) {
+ if (!Reg.isPhysical()) {
Def = MRI.getVRegDef(Reg);
DefIdx = MRI.def_begin(Reg).getOperandNo();
}
@@ -827,7 +827,7 @@ public:
/// Rewrite the current source with \p NewReg and \p NewSubReg if possible.
/// \return True if the rewriting was possible, false otherwise.
- virtual bool RewriteCurrentSource(Register NewReg, unsigned NewSubReg) = 0;
+ virtual bool RewriteCurrentSource(Register NewReg, unsigned NewSubReg) = 0;
};
/// Rewriter for COPY instructions.
@@ -855,7 +855,7 @@ public:
return true;
}
- bool RewriteCurrentSource(Register NewReg, unsigned NewSubReg) override {
+ bool RewriteCurrentSource(Register NewReg, unsigned NewSubReg) override {
if (CurrentSrcIdx != 1)
return false;
MachineOperand &MOSrc = CopyLike.getOperand(CurrentSrcIdx);
@@ -900,7 +900,7 @@ public:
return true;
}
- bool RewriteCurrentSource(Register NewReg, unsigned NewSubReg) override {
+ bool RewriteCurrentSource(Register NewReg, unsigned NewSubReg) override {
return false;
}
};
@@ -944,7 +944,7 @@ public:
return true;
}
- bool RewriteCurrentSource(Register NewReg, unsigned NewSubReg) override {
+ bool RewriteCurrentSource(Register NewReg, unsigned NewSubReg) override {
if (CurrentSrcIdx != 2)
return false;
// We are rewriting the inserted reg.
@@ -991,7 +991,7 @@ public:
return true;
}
- bool RewriteCurrentSource(Register NewReg, unsigned NewSubReg) override {
+ bool RewriteCurrentSource(Register NewReg, unsigned NewSubReg) override {
// The only source we can rewrite is the input register.
if (CurrentSrcIdx != 1)
return false;
@@ -1069,7 +1069,7 @@ public:
return MODef.getSubReg() == 0;
}
- bool RewriteCurrentSource(Register NewReg, unsigned NewSubReg) override {
+ bool RewriteCurrentSource(Register NewReg, unsigned NewSubReg) override {
// We cannot rewrite out of bound operands.
// Moreover, rewritable sources are at odd positions.
if ((CurrentSrcIdx & 1) != 1 || CurrentSrcIdx > CopyLike.getNumOperands())
@@ -1315,7 +1315,7 @@ bool PeepholeOptimizer::optimizeUncoalescableCopy(
/// We only fold loads to virtual registers and the virtual register defined
/// has a single user.
bool PeepholeOptimizer::isLoadFoldable(
- MachineInstr &MI, SmallSet<Register, 16> &FoldAsLoadDefCandidates) {
+ MachineInstr &MI, SmallSet<Register, 16> &FoldAsLoadDefCandidates) {
if (!MI.canFoldAsLoad() || !MI.mayLoad())
return false;
const MCInstrDesc &MCID = MI.getDesc();
@@ -1326,7 +1326,7 @@ bool PeepholeOptimizer::isLoadFoldable(
// To reduce compilation time, we check MRI->hasOneNonDBGUser when inserting
// loads. It should be checked when processing uses of the load, since
// uses can be removed during peephole.
- if (Reg.isVirtual() && !MI.getOperand(0).getSubReg() &&
+ if (Reg.isVirtual() && !MI.getOperand(0).getSubReg() &&
MRI->hasOneNonDBGUser(Reg)) {
FoldAsLoadDefCandidates.insert(Reg);
return true;
@@ -1335,15 +1335,15 @@ bool PeepholeOptimizer::isLoadFoldable(
}
bool PeepholeOptimizer::isMoveImmediate(
- MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
- DenseMap<Register, MachineInstr *> &ImmDefMIs) {
+ MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
+ DenseMap<Register, MachineInstr *> &ImmDefMIs) {
const MCInstrDesc &MCID = MI.getDesc();
if (!MI.isMoveImmediate())
return false;
if (MCID.getNumDefs() != 1)
return false;
Register Reg = MI.getOperand(0).getReg();
- if (Reg.isVirtual()) {
+ if (Reg.isVirtual()) {
ImmDefMIs.insert(std::make_pair(Reg, &MI));
ImmDefRegs.insert(Reg);
return true;
@@ -1355,19 +1355,19 @@ bool PeepholeOptimizer::isMoveImmediate(
/// Try folding register operands that are defined by move immediate
/// instructions, i.e. a trivial constant folding optimization, if
/// and only if the def and use are in the same BB.
-bool PeepholeOptimizer::foldImmediate(
- MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
- DenseMap<Register, MachineInstr *> &ImmDefMIs) {
+bool PeepholeOptimizer::foldImmediate(
+ MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
+ DenseMap<Register, MachineInstr *> &ImmDefMIs) {
for (unsigned i = 0, e = MI.getDesc().getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg() || MO.isDef())
continue;
Register Reg = MO.getReg();
- if (!Reg.isVirtual())
+ if (!Reg.isVirtual())
continue;
if (ImmDefRegs.count(Reg) == 0)
continue;
- DenseMap<Register, MachineInstr *>::iterator II = ImmDefMIs.find(Reg);
+ DenseMap<Register, MachineInstr *>::iterator II = ImmDefMIs.find(Reg);
assert(II != ImmDefMIs.end() && "couldn't find immediate definition");
if (TII->FoldImmediate(MI, *II->second, Reg, MRI)) {
++NumImmFold;
@@ -1391,30 +1391,30 @@ bool PeepholeOptimizer::foldImmediate(
// %2 = COPY %0:sub1
//
// Should replace %2 uses with %1:sub1
-bool PeepholeOptimizer::foldRedundantCopy(
- MachineInstr &MI, DenseMap<RegSubRegPair, MachineInstr *> &CopyMIs) {
+bool PeepholeOptimizer::foldRedundantCopy(
+ MachineInstr &MI, DenseMap<RegSubRegPair, MachineInstr *> &CopyMIs) {
assert(MI.isCopy() && "expected a COPY machine instruction");
Register SrcReg = MI.getOperand(1).getReg();
- unsigned SrcSubReg = MI.getOperand(1).getSubReg();
- if (!SrcReg.isVirtual())
+ unsigned SrcSubReg = MI.getOperand(1).getSubReg();
+ if (!SrcReg.isVirtual())
return false;
Register DstReg = MI.getOperand(0).getReg();
- if (!DstReg.isVirtual())
+ if (!DstReg.isVirtual())
return false;
- RegSubRegPair SrcPair(SrcReg, SrcSubReg);
-
- if (CopyMIs.insert(std::make_pair(SrcPair, &MI)).second) {
+ RegSubRegPair SrcPair(SrcReg, SrcSubReg);
+
+ if (CopyMIs.insert(std::make_pair(SrcPair, &MI)).second) {
// First copy of this reg seen.
return false;
}
- MachineInstr *PrevCopy = CopyMIs.find(SrcPair)->second;
+ MachineInstr *PrevCopy = CopyMIs.find(SrcPair)->second;
- assert(SrcSubReg == PrevCopy->getOperand(1).getSubReg() &&
- "Unexpected mismatching subreg!");
+ assert(SrcSubReg == PrevCopy->getOperand(1).getSubReg() &&
+ "Unexpected mismatching subreg!");
Register PrevDstReg = PrevCopy->getOperand(0).getReg();
@@ -1432,12 +1432,12 @@ bool PeepholeOptimizer::foldRedundantCopy(
return true;
}
-bool PeepholeOptimizer::isNAPhysCopy(Register Reg) {
- return Reg.isPhysical() && !MRI->isAllocatable(Reg);
+bool PeepholeOptimizer::isNAPhysCopy(Register Reg) {
+ return Reg.isPhysical() && !MRI->isAllocatable(Reg);
}
bool PeepholeOptimizer::foldRedundantNAPhysCopy(
- MachineInstr &MI, DenseMap<Register, MachineInstr *> &NAPhysToVirtMIs) {
+ MachineInstr &MI, DenseMap<Register, MachineInstr *> &NAPhysToVirtMIs) {
assert(MI.isCopy() && "expected a COPY machine instruction");
if (DisableNAPhysCopyOpt)
@@ -1446,17 +1446,17 @@ bool PeepholeOptimizer::foldRedundantNAPhysCopy(
Register DstReg = MI.getOperand(0).getReg();
Register SrcReg = MI.getOperand(1).getReg();
if (isNAPhysCopy(SrcReg) && Register::isVirtualRegister(DstReg)) {
- // %vreg = COPY $physreg
+ // %vreg = COPY $physreg
// Avoid using a datastructure which can track multiple live non-allocatable
// phys->virt copies since LLVM doesn't seem to do this.
NAPhysToVirtMIs.insert({SrcReg, &MI});
return false;
}
- if (!(SrcReg.isVirtual() && isNAPhysCopy(DstReg)))
+ if (!(SrcReg.isVirtual() && isNAPhysCopy(DstReg)))
return false;
- // $physreg = COPY %vreg
+ // $physreg = COPY %vreg
auto PrevCopy = NAPhysToVirtMIs.find(DstReg);
if (PrevCopy == NAPhysToVirtMIs.end()) {
// We can't remove the copy: there was an intervening clobber of the
@@ -1486,11 +1486,11 @@ bool PeepholeOptimizer::foldRedundantNAPhysCopy(
/// \bried Returns true if \p MO is a virtual register operand.
static bool isVirtualRegisterOperand(MachineOperand &MO) {
- return MO.isReg() && MO.getReg().isVirtual();
+ return MO.isReg() && MO.getReg().isVirtual();
}
bool PeepholeOptimizer::findTargetRecurrence(
- Register Reg, const SmallSet<Register, 2> &TargetRegs,
+ Register Reg, const SmallSet<Register, 2> &TargetRegs,
RecurrenceCycle &RC) {
// Recurrence found if Reg is in TargetRegs.
if (TargetRegs.count(Reg))
@@ -1561,7 +1561,7 @@ bool PeepholeOptimizer::findTargetRecurrence(
/// %1 of ADD instruction, the redundant move instruction can be
/// avoided.
bool PeepholeOptimizer::optimizeRecurrence(MachineInstr &PHI) {
- SmallSet<Register, 2> TargetRegs;
+ SmallSet<Register, 2> TargetRegs;
for (unsigned Idx = 1; Idx < PHI.getNumOperands(); Idx += 2) {
MachineOperand &MO = PHI.getOperand(Idx);
assert(isVirtualRegisterOperand(MO) && "Invalid PHI instruction");
@@ -1617,20 +1617,20 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
// during the scan, if a MI is not in the set, it is assumed to be located
// after. Newly created MIs have to be inserted in the set as well.
SmallPtrSet<MachineInstr*, 16> LocalMIs;
- SmallSet<Register, 4> ImmDefRegs;
- DenseMap<Register, MachineInstr *> ImmDefMIs;
- SmallSet<Register, 16> FoldAsLoadDefCandidates;
+ SmallSet<Register, 4> ImmDefRegs;
+ DenseMap<Register, MachineInstr *> ImmDefMIs;
+ SmallSet<Register, 16> FoldAsLoadDefCandidates;
// Track when a non-allocatable physical register is copied to a virtual
// register so that useless moves can be removed.
//
- // $physreg is the map index; MI is the last valid `%vreg = COPY $physreg`
- // without any intervening re-definition of $physreg.
- DenseMap<Register, MachineInstr *> NAPhysToVirtMIs;
+ // $physreg is the map index; MI is the last valid `%vreg = COPY $physreg`
+ // without any intervening re-definition of $physreg.
+ DenseMap<Register, MachineInstr *> NAPhysToVirtMIs;
- // Set of pairs of virtual registers and their subregs that are copied
- // from.
- DenseMap<RegSubRegPair, MachineInstr *> CopySrcMIs;
+ // Set of pairs of virtual registers and their subregs that are copied
+ // from.
+ DenseMap<RegSubRegPair, MachineInstr *> CopySrcMIs;
bool IsLoopHeader = MLI->isLoopHeader(&MBB);
@@ -1641,10 +1641,10 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
++MII;
LocalMIs.insert(MI);
- // Skip debug instructions. They should not affect this peephole
- // optimization.
+ // Skip debug instructions. They should not affect this peephole
+ // optimization.
if (MI->isDebugInstr())
- continue;
+ continue;
if (MI->isPosition())
continue;
@@ -1674,7 +1674,7 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
} else if (MO.isRegMask()) {
const uint32_t *RegMask = MO.getRegMask();
for (auto &RegMI : NAPhysToVirtMIs) {
- Register Def = RegMI.first;
+ Register Def = RegMI.first;
if (MachineOperand::clobbersPhysReg(RegMask, Def)) {
LLVM_DEBUG(dbgs()
<< "NAPhysCopy: invalidating because of " << *MI);
@@ -1719,8 +1719,8 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
continue;
}
- if (MI->isCopy() && (foldRedundantCopy(*MI, CopySrcMIs) ||
- foldRedundantNAPhysCopy(*MI, NAPhysToVirtMIs))) {
+ if (MI->isCopy() && (foldRedundantCopy(*MI, CopySrcMIs) ||
+ foldRedundantNAPhysCopy(*MI, NAPhysToVirtMIs))) {
LocalMIs.erase(MI);
LLVM_DEBUG(dbgs() << "Deleting redundant copy: " << *MI << "\n");
MI->eraseFromParent();
@@ -1758,13 +1758,13 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
const MachineOperand &MOp = MI->getOperand(i);
if (!MOp.isReg())
continue;
- Register FoldAsLoadDefReg = MOp.getReg();
+ Register FoldAsLoadDefReg = MOp.getReg();
if (FoldAsLoadDefCandidates.count(FoldAsLoadDefReg)) {
// We need to fold load after optimizeCmpInstr, since
// optimizeCmpInstr can enable folding by converting SUB to CMP.
// Save FoldAsLoadDefReg because optimizeLoadInstr() resets it and
// we need it for markUsesInDebugValueAsUndef().
- Register FoldedReg = FoldAsLoadDefReg;
+ Register FoldedReg = FoldAsLoadDefReg;
MachineInstr *DefMI = nullptr;
if (MachineInstr *FoldMI =
TII->optimizeLoadInstr(*MI, MRI, FoldAsLoadDefReg, DefMI)) {
diff --git a/contrib/libs/llvm12/lib/CodeGen/PostRAHazardRecognizer.cpp b/contrib/libs/llvm12/lib/CodeGen/PostRAHazardRecognizer.cpp
index 76af7c8ebc..82ed386db8 100644
--- a/contrib/libs/llvm12/lib/CodeGen/PostRAHazardRecognizer.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/PostRAHazardRecognizer.cpp
@@ -82,9 +82,9 @@ bool PostRAHazardRecognizer::runOnMachineFunction(MachineFunction &Fn) {
for (MachineInstr &MI : MBB) {
// If we need to emit noops prior to this instruction, then do so.
unsigned NumPreNoops = HazardRec->PreEmitNoops(&MI);
- HazardRec->EmitNoops(NumPreNoops);
- TII->insertNoops(MBB, MachineBasicBlock::iterator(MI), NumPreNoops);
- NumNoops += NumPreNoops;
+ HazardRec->EmitNoops(NumPreNoops);
+ TII->insertNoops(MBB, MachineBasicBlock::iterator(MI), NumPreNoops);
+ NumNoops += NumPreNoops;
HazardRec->EmitInstruction(&MI);
if (HazardRec->atIssueLimit()) {
diff --git a/contrib/libs/llvm12/lib/CodeGen/PreISelIntrinsicLowering.cpp b/contrib/libs/llvm12/lib/CodeGen/PreISelIntrinsicLowering.cpp
index 083f23e8f4..80c38f3ec3 100644
--- a/contrib/libs/llvm12/lib/CodeGen/PreISelIntrinsicLowering.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/PreISelIntrinsicLowering.cpp
@@ -96,7 +96,7 @@ static bool lowerObjCCall(Function &F, const char *NewFn,
++I;
IRBuilder<> Builder(CI->getParent(), CI->getIterator());
- SmallVector<Value *, 8> Args(CI->args());
+ SmallVector<Value *, 8> Args(CI->args());
CallInst *NewCI = Builder.CreateCall(FCache, Args);
NewCI->setName(CI->getName());
diff --git a/contrib/libs/llvm12/lib/CodeGen/PrologEpilogInserter.cpp b/contrib/libs/llvm12/lib/CodeGen/PrologEpilogInserter.cpp
index 2925adfa2f..378aaba2a6 100644
--- a/contrib/libs/llvm12/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/PrologEpilogInserter.cpp
@@ -620,12 +620,12 @@ void PEI::spillCalleeSavedRegs(MachineFunction &MF) {
if (!MFI.hasCalls())
NumLeafFuncWithSpills++;
- for (MachineBasicBlock *SaveBlock : SaveBlocks)
+ for (MachineBasicBlock *SaveBlock : SaveBlocks)
insertCSRSaves(*SaveBlock, CSI);
-
- // Update the live-in information of all the blocks up to the save point.
- updateLiveness(MF);
-
+
+ // Update the live-in information of all the blocks up to the save point.
+ updateLiveness(MF);
+
for (MachineBasicBlock *RestoreBlock : RestoreBlocks)
insertCSRRestores(*RestoreBlock, CSI);
}
@@ -1077,26 +1077,26 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &MF) {
// If the frame pointer is eliminated, all frame offsets will be relative to
// SP not FP. Align to MaxAlign so this works.
StackAlign = std::max(StackAlign, MaxAlign);
- int64_t OffsetBeforeAlignment = Offset;
+ int64_t OffsetBeforeAlignment = Offset;
Offset = alignTo(Offset, StackAlign, Skew);
-
- // If we have increased the offset to fulfill the alignment constrants,
- // then the scavenging spill slots may become harder to reach from the
- // stack pointer, float them so they stay close.
- if (OffsetBeforeAlignment != Offset && RS && !EarlyScavengingSlots) {
- SmallVector<int, 2> SFIs;
- RS->getScavengingFrameIndices(SFIs);
- LLVM_DEBUG(if (!SFIs.empty()) llvm::dbgs()
- << "Adjusting emergency spill slots!\n";);
- int64_t Delta = Offset - OffsetBeforeAlignment;
- for (SmallVectorImpl<int>::iterator I = SFIs.begin(), IE = SFIs.end();
- I != IE; ++I) {
- LLVM_DEBUG(llvm::dbgs() << "Adjusting offset of emergency spill slot #"
- << *I << " from " << MFI.getObjectOffset(*I););
- MFI.setObjectOffset(*I, MFI.getObjectOffset(*I) - Delta);
- LLVM_DEBUG(llvm::dbgs() << " to " << MFI.getObjectOffset(*I) << "\n";);
- }
- }
+
+ // If we have increased the offset to fulfill the alignment constrants,
+ // then the scavenging spill slots may become harder to reach from the
+ // stack pointer, float them so they stay close.
+ if (OffsetBeforeAlignment != Offset && RS && !EarlyScavengingSlots) {
+ SmallVector<int, 2> SFIs;
+ RS->getScavengingFrameIndices(SFIs);
+ LLVM_DEBUG(if (!SFIs.empty()) llvm::dbgs()
+ << "Adjusting emergency spill slots!\n";);
+ int64_t Delta = Offset - OffsetBeforeAlignment;
+ for (SmallVectorImpl<int>::iterator I = SFIs.begin(), IE = SFIs.end();
+ I != IE; ++I) {
+ LLVM_DEBUG(llvm::dbgs() << "Adjusting offset of emergency spill slot #"
+ << *I << " from " << MFI.getObjectOffset(*I););
+ MFI.setObjectOffset(*I, MFI.getObjectOffset(*I) - Delta);
+ LLVM_DEBUG(llvm::dbgs() << " to " << MFI.getObjectOffset(*I) << "\n";);
+ }
+ }
}
// Update frame info to pretend that this is part of the stack...
@@ -1228,7 +1228,7 @@ void PEI::replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &MF,
unsigned FrameIdx = MI.getOperand(0).getIndex();
unsigned Size = MF.getFrameInfo().getObjectSize(FrameIdx);
- StackOffset Offset =
+ StackOffset Offset =
TFI->getFrameIndexReference(MF, FrameIdx, Reg);
MI.getOperand(0).ChangeToRegister(Reg, false /*isDef*/);
MI.getOperand(0).setIsDebug();
@@ -1255,8 +1255,8 @@ void PEI::replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &MF,
// Make the DBG_VALUE direct.
MI.getDebugOffset().ChangeToRegister(0, false);
}
-
- DIExpr = TRI.prependOffsetExpression(DIExpr, PrependFlags, Offset);
+
+ DIExpr = TRI.prependOffsetExpression(DIExpr, PrependFlags, Offset);
MI.getDebugExpressionOp().setMetadata(DIExpr);
continue;
}
@@ -1272,11 +1272,11 @@ void PEI::replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &MF,
"DBG_VALUE machine instruction");
Register Reg;
MachineOperand &Offset = MI.getOperand(i + 1);
- StackOffset refOffset = TFI->getFrameIndexReferencePreferSP(
+ StackOffset refOffset = TFI->getFrameIndexReferencePreferSP(
MF, MI.getOperand(i).getIndex(), Reg, /*IgnoreSPUpdates*/ false);
- assert(!refOffset.getScalable() &&
- "Frame offsets with a scalable component are not supported");
- Offset.setImm(Offset.getImm() + refOffset.getFixed() + SPAdj);
+ assert(!refOffset.getScalable() &&
+ "Frame offsets with a scalable component are not supported");
+ Offset.setImm(Offset.getImm() + refOffset.getFixed() + SPAdj);
MI.getOperand(i).ChangeToRegister(Reg, false /*isDef*/);
continue;
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/PseudoProbeInserter.cpp b/contrib/libs/llvm12/lib/CodeGen/PseudoProbeInserter.cpp
index 8e854cf2c8..9c716a5a37 100644
--- a/contrib/libs/llvm12/lib/CodeGen/PseudoProbeInserter.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/PseudoProbeInserter.cpp
@@ -1,95 +1,95 @@
-//===- PseudoProbeInserter.cpp - Insert annotation for callsite profiling -===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements PseudoProbeInserter pass, which inserts pseudo probe
-// annotations for call instructions with a pseudo-probe-specific dwarf
-// discriminator. such discriminator indicates that the call instruction comes
-// with a pseudo probe, and the discriminator value holds information to
-// identify the corresponding counter.
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/TargetInstrInfo.h"
-#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/PseudoProbe.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Target/TargetMachine.h"
-#include <unordered_map>
-
-#define DEBUG_TYPE "pseudo-probe-inserter"
-
-using namespace llvm;
-
-namespace {
-class PseudoProbeInserter : public MachineFunctionPass {
-public:
- static char ID;
-
- PseudoProbeInserter() : MachineFunctionPass(ID) {
- initializePseudoProbeInserterPass(*PassRegistry::getPassRegistry());
- }
-
- StringRef getPassName() const override { return "Pseudo Probe Inserter"; }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
-
- bool runOnMachineFunction(MachineFunction &MF) override {
- const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
- bool Changed = false;
- for (MachineBasicBlock &MBB : MF) {
- for (MachineInstr &MI : MBB) {
- if (MI.isCall()) {
- if (DILocation *DL = MI.getDebugLoc()) {
- auto Value = DL->getDiscriminator();
- if (DILocation::isPseudoProbeDiscriminator(Value)) {
- BuildMI(MBB, MI, DL, TII->get(TargetOpcode::PSEUDO_PROBE))
- .addImm(getFuncGUID(MF.getFunction().getParent(), DL))
- .addImm(
- PseudoProbeDwarfDiscriminator::extractProbeIndex(Value))
- .addImm(
- PseudoProbeDwarfDiscriminator::extractProbeType(Value))
- .addImm(PseudoProbeDwarfDiscriminator::extractProbeAttributes(
- Value));
- Changed = true;
- }
- }
- }
- }
- }
-
- return Changed;
- }
-
-private:
- uint64_t getFuncGUID(Module *M, DILocation *DL) {
- auto *SP = DL->getScope()->getSubprogram();
- auto Name = SP->getLinkageName();
- if (Name.empty())
- Name = SP->getName();
- return Function::getGUID(Name);
- }
-};
-} // namespace
-
-char PseudoProbeInserter::ID = 0;
-INITIALIZE_PASS_BEGIN(PseudoProbeInserter, DEBUG_TYPE,
- "Insert pseudo probe annotations for value profiling",
- false, false)
-INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
-INITIALIZE_PASS_END(PseudoProbeInserter, DEBUG_TYPE,
- "Insert pseudo probe annotations for value profiling",
- false, false)
-
-FunctionPass *llvm::createPseudoProbeInserter() {
- return new PseudoProbeInserter();
-}
+//===- PseudoProbeInserter.cpp - Insert annotation for callsite profiling -===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements PseudoProbeInserter pass, which inserts pseudo probe
+// annotations for call instructions with a pseudo-probe-specific dwarf
+// discriminator. such discriminator indicates that the call instruction comes
+// with a pseudo probe, and the discriminator value holds information to
+// identify the corresponding counter.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/PseudoProbe.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Target/TargetMachine.h"
+#include <unordered_map>
+
+#define DEBUG_TYPE "pseudo-probe-inserter"
+
+using namespace llvm;
+
+namespace {
+class PseudoProbeInserter : public MachineFunctionPass {
+public:
+ static char ID;
+
+ PseudoProbeInserter() : MachineFunctionPass(ID) {
+ initializePseudoProbeInserterPass(*PassRegistry::getPassRegistry());
+ }
+
+ StringRef getPassName() const override { return "Pseudo Probe Inserter"; }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+ bool runOnMachineFunction(MachineFunction &MF) override {
+ const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
+ bool Changed = false;
+ for (MachineBasicBlock &MBB : MF) {
+ for (MachineInstr &MI : MBB) {
+ if (MI.isCall()) {
+ if (DILocation *DL = MI.getDebugLoc()) {
+ auto Value = DL->getDiscriminator();
+ if (DILocation::isPseudoProbeDiscriminator(Value)) {
+ BuildMI(MBB, MI, DL, TII->get(TargetOpcode::PSEUDO_PROBE))
+ .addImm(getFuncGUID(MF.getFunction().getParent(), DL))
+ .addImm(
+ PseudoProbeDwarfDiscriminator::extractProbeIndex(Value))
+ .addImm(
+ PseudoProbeDwarfDiscriminator::extractProbeType(Value))
+ .addImm(PseudoProbeDwarfDiscriminator::extractProbeAttributes(
+ Value));
+ Changed = true;
+ }
+ }
+ }
+ }
+ }
+
+ return Changed;
+ }
+
+private:
+ uint64_t getFuncGUID(Module *M, DILocation *DL) {
+ auto *SP = DL->getScope()->getSubprogram();
+ auto Name = SP->getLinkageName();
+ if (Name.empty())
+ Name = SP->getName();
+ return Function::getGUID(Name);
+ }
+};
+} // namespace
+
+char PseudoProbeInserter::ID = 0;
+INITIALIZE_PASS_BEGIN(PseudoProbeInserter, DEBUG_TYPE,
+ "Insert pseudo probe annotations for value profiling",
+ false, false)
+INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
+INITIALIZE_PASS_END(PseudoProbeInserter, DEBUG_TYPE,
+ "Insert pseudo probe annotations for value profiling",
+ false, false)
+
+FunctionPass *llvm::createPseudoProbeInserter() {
+ return new PseudoProbeInserter();
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/RDFLiveness.cpp b/contrib/libs/llvm12/lib/CodeGen/RDFLiveness.cpp
index 2f4c899d94..76bf0c2809 100644
--- a/contrib/libs/llvm12/lib/CodeGen/RDFLiveness.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/RDFLiveness.cpp
@@ -23,10 +23,10 @@
// <10.1145/2086696.2086706>. <hal-00647369>
//
#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineDominanceFrontier.h"
#include "llvm/CodeGen/MachineDominators.h"
@@ -47,7 +47,7 @@
#include <cstdint>
#include <iterator>
#include <map>
-#include <unordered_map>
+#include <unordered_map>
#include <utility>
#include <vector>
@@ -111,7 +111,7 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
const RegisterAggr &DefRRs) {
NodeList RDefs; // Return value.
SetVector<NodeId> DefQ;
- DenseMap<MachineInstr*, uint32_t> OrdMap;
+ DenseMap<MachineInstr*, uint32_t> OrdMap;
// Dead defs will be treated as if they were live, since they are actually
// on the data-flow path. They cannot be ignored because even though they
@@ -154,9 +154,9 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
for (auto S : DFG.getRelatedRefs(TA.Addr->getOwner(DFG), TA))
if (NodeId RD = NodeAddr<RefNode*>(S).Addr->getReachingDef())
DefQ.insert(RD);
- // Don't visit sibling defs. They share the same reaching def (which
- // will be visited anyway), but they define something not aliased to
- // this ref.
+ // Don't visit sibling defs. They share the same reaching def (which
+ // will be visited anyway), but they define something not aliased to
+ // this ref.
}
// Return the MachineBasicBlock containing a given instruction.
@@ -168,81 +168,81 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
NodeAddr<BlockNode*> BA = PA.Addr->getOwner(DFG);
return BA.Addr->getCode();
};
-
- SmallSet<NodeId,32> Defs;
-
- // Remove all non-phi defs that are not aliased to RefRR, and segregate
- // the the remaining defs into buckets for containing blocks.
- std::map<NodeId, NodeAddr<InstrNode*>> Owners;
- std::map<MachineBasicBlock*, SmallVector<NodeId,32>> Blocks;
- for (NodeId N : DefQ) {
- auto TA = DFG.addr<DefNode*>(N);
- bool IsPhi = TA.Addr->getFlags() & NodeAttrs::PhiRef;
- if (!IsPhi && !PRI.alias(RefRR, TA.Addr->getRegRef(DFG)))
- continue;
- Defs.insert(TA.Id);
- NodeAddr<InstrNode*> IA = TA.Addr->getOwner(DFG);
- Owners[TA.Id] = IA;
- Blocks[Block(IA)].push_back(IA.Id);
- }
-
- auto Precedes = [this,&OrdMap] (NodeId A, NodeId B) {
+
+ SmallSet<NodeId,32> Defs;
+
+ // Remove all non-phi defs that are not aliased to RefRR, and segregate
+ // the the remaining defs into buckets for containing blocks.
+ std::map<NodeId, NodeAddr<InstrNode*>> Owners;
+ std::map<MachineBasicBlock*, SmallVector<NodeId,32>> Blocks;
+ for (NodeId N : DefQ) {
+ auto TA = DFG.addr<DefNode*>(N);
+ bool IsPhi = TA.Addr->getFlags() & NodeAttrs::PhiRef;
+ if (!IsPhi && !PRI.alias(RefRR, TA.Addr->getRegRef(DFG)))
+ continue;
+ Defs.insert(TA.Id);
+ NodeAddr<InstrNode*> IA = TA.Addr->getOwner(DFG);
+ Owners[TA.Id] = IA;
+ Blocks[Block(IA)].push_back(IA.Id);
+ }
+
+ auto Precedes = [this,&OrdMap] (NodeId A, NodeId B) {
if (A == B)
return false;
- NodeAddr<InstrNode*> OA = DFG.addr<InstrNode*>(A);
- NodeAddr<InstrNode*> OB = DFG.addr<InstrNode*>(B);
+ NodeAddr<InstrNode*> OA = DFG.addr<InstrNode*>(A);
+ NodeAddr<InstrNode*> OB = DFG.addr<InstrNode*>(B);
bool StmtA = OA.Addr->getKind() == NodeAttrs::Stmt;
bool StmtB = OB.Addr->getKind() == NodeAttrs::Stmt;
- if (StmtA && StmtB) {
- const MachineInstr *InA = NodeAddr<StmtNode*>(OA).Addr->getCode();
- const MachineInstr *InB = NodeAddr<StmtNode*>(OB).Addr->getCode();
- assert(InA->getParent() == InB->getParent());
- auto FA = OrdMap.find(InA);
- if (FA != OrdMap.end())
- return FA->second < OrdMap.find(InB)->second;
- const MachineBasicBlock *BB = InA->getParent();
- for (auto It = BB->begin(), E = BB->end(); It != E; ++It) {
- if (It == InA->getIterator())
- return true;
- if (It == InB->getIterator())
- return false;
- }
- llvm_unreachable("InA and InB should be in the same block");
- }
- // One of them is a phi node.
- if (!StmtA && !StmtB) {
- // Both are phis, which are unordered. Break the tie by id numbers.
+ if (StmtA && StmtB) {
+ const MachineInstr *InA = NodeAddr<StmtNode*>(OA).Addr->getCode();
+ const MachineInstr *InB = NodeAddr<StmtNode*>(OB).Addr->getCode();
+ assert(InA->getParent() == InB->getParent());
+ auto FA = OrdMap.find(InA);
+ if (FA != OrdMap.end())
+ return FA->second < OrdMap.find(InB)->second;
+ const MachineBasicBlock *BB = InA->getParent();
+ for (auto It = BB->begin(), E = BB->end(); It != E; ++It) {
+ if (It == InA->getIterator())
+ return true;
+ if (It == InB->getIterator())
+ return false;
+ }
+ llvm_unreachable("InA and InB should be in the same block");
+ }
+ // One of them is a phi node.
+ if (!StmtA && !StmtB) {
+ // Both are phis, which are unordered. Break the tie by id numbers.
return A < B;
}
- // Only one of them is a phi. Phis always precede statements.
- return !StmtA;
+ // Only one of them is a phi. Phis always precede statements.
+ return !StmtA;
};
- auto GetOrder = [&OrdMap] (MachineBasicBlock &B) {
- uint32_t Pos = 0;
- for (MachineInstr &In : B)
- OrdMap.insert({&In, ++Pos});
- };
-
- // For each block, sort the nodes in it.
- std::vector<MachineBasicBlock*> TmpBB;
- for (auto &Bucket : Blocks) {
- TmpBB.push_back(Bucket.first);
- if (Bucket.second.size() > 2)
- GetOrder(*Bucket.first);
- llvm::sort(Bucket.second, Precedes);
- }
-
- // Sort the blocks with respect to dominance.
- llvm::sort(TmpBB,
- [this](auto A, auto B) { return MDT.properlyDominates(A, B); });
-
- std::vector<NodeId> TmpInst;
- for (auto I = TmpBB.rbegin(), E = TmpBB.rend(); I != E; ++I) {
- auto &Bucket = Blocks[*I];
- TmpInst.insert(TmpInst.end(), Bucket.rbegin(), Bucket.rend());
- }
-
+ auto GetOrder = [&OrdMap] (MachineBasicBlock &B) {
+ uint32_t Pos = 0;
+ for (MachineInstr &In : B)
+ OrdMap.insert({&In, ++Pos});
+ };
+
+ // For each block, sort the nodes in it.
+ std::vector<MachineBasicBlock*> TmpBB;
+ for (auto &Bucket : Blocks) {
+ TmpBB.push_back(Bucket.first);
+ if (Bucket.second.size() > 2)
+ GetOrder(*Bucket.first);
+ llvm::sort(Bucket.second, Precedes);
+ }
+
+ // Sort the blocks with respect to dominance.
+ llvm::sort(TmpBB,
+ [this](auto A, auto B) { return MDT.properlyDominates(A, B); });
+
+ std::vector<NodeId> TmpInst;
+ for (auto I = TmpBB.rbegin(), E = TmpBB.rend(); I != E; ++I) {
+ auto &Bucket = Blocks[*I];
+ TmpInst.insert(TmpInst.end(), Bucket.rbegin(), Bucket.rend());
+ }
+
// The vector is a list of instructions, so that defs coming from
// the same instruction don't need to be artificially ordered.
// Then, when computing the initial segment, and iterating over an
@@ -256,9 +256,9 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
// *d3<C> If A \incl BuC, and B \incl AuC, then *d2 would be
// covered if we added A first, and A would be covered
// if we added B first.
- // In this example we want both A and B, because we don't want to give
- // either one priority over the other, since they belong to the same
- // statement.
+ // In this example we want both A and B, because we don't want to give
+ // either one priority over the other, since they belong to the same
+ // statement.
RegisterAggr RRs(DefRRs);
@@ -266,8 +266,8 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
return TA.Addr->getKind() == NodeAttrs::Def &&
Defs.count(TA.Id);
};
-
- for (NodeId T : TmpInst) {
+
+ for (NodeId T : TmpInst) {
if (!FullChain && RRs.hasCoverOf(RefRR))
break;
auto TA = DFG.addr<InstrNode*>(T);
@@ -286,7 +286,7 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
if (FullChain || IsPhi || !RRs.hasCoverOf(QR))
Ds.push_back(DA);
}
- llvm::append_range(RDefs, Ds);
+ llvm::append_range(RDefs, Ds);
for (NodeAddr<DefNode*> DA : Ds) {
// When collecting a full chain of definitions, do not consider phi
// defs to actually define a register.
@@ -300,7 +300,7 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
auto DeadP = [](const NodeAddr<DefNode*> DA) -> bool {
return DA.Addr->getFlags() & NodeAttrs::Dead;
};
- llvm::erase_if(RDefs, DeadP);
+ llvm::erase_if(RDefs, DeadP);
return RDefs;
}
@@ -470,13 +470,13 @@ void Liveness::computePhiInfo() {
NodeList Blocks = FA.Addr->members(DFG);
for (NodeAddr<BlockNode*> BA : Blocks) {
auto Ps = BA.Addr->members_if(DFG.IsCode<NodeAttrs::Phi>, DFG);
- llvm::append_range(Phis, Ps);
+ llvm::append_range(Phis, Ps);
}
// phi use -> (map: reaching phi -> set of registers defined in between)
std::map<NodeId,std::map<NodeId,RegisterAggr>> PhiUp;
std::vector<NodeId> PhiUQ; // Work list of phis for upward propagation.
- std::unordered_map<NodeId,RegisterAggr> PhiDRs; // Phi -> registers defined by it.
+ std::unordered_map<NodeId,RegisterAggr> PhiDRs; // Phi -> registers defined by it.
// Go over all phis.
for (NodeAddr<PhiNode*> PhiA : Phis) {
@@ -514,7 +514,7 @@ void Liveness::computePhiInfo() {
NodeAddr<UseNode*> A = DFG.addr<UseNode*>(UN);
uint16_t F = A.Addr->getFlags();
if ((F & (NodeAttrs::Undef | NodeAttrs::PhiRef)) == 0) {
- RegisterRef R = A.Addr->getRegRef(DFG);
+ RegisterRef R = A.Addr->getRegRef(DFG);
RealUses[R.Reg].insert({A.Id,R.Mask});
}
UN = A.Addr->getSibling();
@@ -652,23 +652,23 @@ void Liveness::computePhiInfo() {
// is covered, or until reaching the final phi. Only assume that the
// reference reaches the phi in the latter case.
- // The operation "clearIn" can be expensive. For a given set of intervening
- // defs, cache the result of subtracting these defs from a given register
- // ref.
- using SubMap = std::unordered_map<RegisterRef, RegisterRef>;
- std::unordered_map<RegisterAggr, SubMap> Subs;
- auto ClearIn = [] (RegisterRef RR, const RegisterAggr &Mid, SubMap &SM) {
- if (Mid.empty())
- return RR;
- auto F = SM.find(RR);
- if (F != SM.end())
- return F->second;
- RegisterRef S = Mid.clearIn(RR);
- SM.insert({RR, S});
- return S;
- };
-
- // Go over all phis.
+ // The operation "clearIn" can be expensive. For a given set of intervening
+ // defs, cache the result of subtracting these defs from a given register
+ // ref.
+ using SubMap = std::unordered_map<RegisterRef, RegisterRef>;
+ std::unordered_map<RegisterAggr, SubMap> Subs;
+ auto ClearIn = [] (RegisterRef RR, const RegisterAggr &Mid, SubMap &SM) {
+ if (Mid.empty())
+ return RR;
+ auto F = SM.find(RR);
+ if (F != SM.end())
+ return F->second;
+ RegisterRef S = Mid.clearIn(RR);
+ SM.insert({RR, S});
+ return S;
+ };
+
+ // Go over all phis.
for (unsigned i = 0; i < PhiUQ.size(); ++i) {
auto PA = DFG.addr<PhiNode*>(PhiUQ[i]);
NodeList PUs = PA.Addr->members_if(DFG.IsRef<NodeAttrs::Use>, DFG);
@@ -676,7 +676,7 @@ void Liveness::computePhiInfo() {
for (NodeAddr<UseNode*> UA : PUs) {
std::map<NodeId,RegisterAggr> &PUM = PhiUp[UA.Id];
- RegisterRef UR = UA.Addr->getRegRef(DFG);
+ RegisterRef UR = UA.Addr->getRegRef(DFG);
for (const std::pair<const NodeId, RegisterAggr> &P : PUM) {
bool Changed = false;
const RegisterAggr &MidDefs = P.second;
@@ -686,7 +686,7 @@ void Liveness::computePhiInfo() {
if (MidDefs.hasCoverOf(UR))
continue;
- SubMap &SM = Subs[MidDefs];
+ SubMap &SM = Subs[MidDefs];
// General algorithm:
// for each (R,U) : U is use node of R, U is reached by PA
@@ -706,7 +706,7 @@ void Liveness::computePhiInfo() {
LaneBitmask M = R.Mask & V.second;
if (M.none())
continue;
- if (RegisterRef SS = ClearIn(RegisterRef(R.Reg, M), MidDefs, SM)) {
+ if (RegisterRef SS = ClearIn(RegisterRef(R.Reg, M), MidDefs, SM)) {
NodeRefSet &RS = RealUseMap[P.first][SS.Reg];
Changed |= RS.insert({V.first,SS.Mask}).second;
}
@@ -1130,7 +1130,7 @@ void Liveness::traverse(MachineBasicBlock *B, RefMap &LiveIn) {
for (NodeAddr<UseNode*> UA : IA.Addr->members_if(DFG.IsUse, DFG)) {
if (UA.Addr->getFlags() & NodeAttrs::Undef)
continue;
- RegisterRef RR = UA.Addr->getRegRef(DFG);
+ RegisterRef RR = UA.Addr->getRegRef(DFG);
for (NodeAddr<DefNode*> D : getAllReachingDefs(UA))
if (getBlockWithRef(D.Id) != B)
LiveIn[RR.Reg].insert({D.Id,RR.Mask});
diff --git a/contrib/libs/llvm12/lib/CodeGen/RDFRegisters.cpp b/contrib/libs/llvm12/lib/CodeGen/RDFRegisters.cpp
index 760648b05b..8760ba1189 100644
--- a/contrib/libs/llvm12/lib/CodeGen/RDFRegisters.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/RDFRegisters.cpp
@@ -84,23 +84,23 @@ PhysicalRegisterInfo::PhysicalRegisterInfo(const TargetRegisterInfo &tri,
for (uint32_t M = 1, NM = RegMasks.size(); M <= NM; ++M) {
BitVector PU(TRI.getNumRegUnits());
const uint32_t *MB = RegMasks.get(M);
- for (unsigned I = 1, E = TRI.getNumRegs(); I != E; ++I) {
- if (!(MB[I / 32] & (1u << (I % 32))))
+ for (unsigned I = 1, E = TRI.getNumRegs(); I != E; ++I) {
+ if (!(MB[I / 32] & (1u << (I % 32))))
continue;
- for (MCRegUnitIterator U(MCRegister::from(I), &TRI); U.isValid(); ++U)
+ for (MCRegUnitIterator U(MCRegister::from(I), &TRI); U.isValid(); ++U)
PU.set(*U);
}
MaskInfos[M].Units = PU.flip();
}
- AliasInfos.resize(TRI.getNumRegUnits());
- for (uint32_t U = 0, NU = TRI.getNumRegUnits(); U != NU; ++U) {
- BitVector AS(TRI.getNumRegs());
- for (MCRegUnitRootIterator R(U, &TRI); R.isValid(); ++R)
- for (MCSuperRegIterator S(*R, &TRI, true); S.isValid(); ++S)
- AS.set(*S);
- AliasInfos[U].Regs = AS;
- }
+ AliasInfos.resize(TRI.getNumRegUnits());
+ for (uint32_t U = 0, NU = TRI.getNumRegUnits(); U != NU; ++U) {
+ BitVector AS(TRI.getNumRegs());
+ for (MCRegUnitRootIterator R(U, &TRI); R.isValid(); ++R)
+ for (MCSuperRegIterator S(*R, &TRI, true); S.isValid(); ++S)
+ AS.set(*S);
+ AliasInfos[U].Regs = AS;
+ }
}
std::set<RegisterId> PhysicalRegisterInfo::getAliasSet(RegisterId Reg) const {
@@ -330,13 +330,13 @@ RegisterRef RegisterAggr::makeRegRef() const {
// in this aggregate.
// Get all the registers aliased to the first unit in the bit vector.
- BitVector Regs = PRI.getUnitAliases(U);
+ BitVector Regs = PRI.getUnitAliases(U);
U = Units.find_next(U);
// For each other unit, intersect it with the set of all registers
// aliased that unit.
while (U >= 0) {
- Regs &= PRI.getUnitAliases(U);
+ Regs &= PRI.getUnitAliases(U);
U = Units.find_next(U);
}
@@ -374,8 +374,8 @@ RegisterAggr::rr_iterator::rr_iterator(const RegisterAggr &RG,
Pos = End ? Masks.end() : Masks.begin();
Index = End ? Masks.size() : 0;
}
-
-raw_ostream &rdf::operator<<(raw_ostream &OS, const RegisterAggr &A) {
- A.print(OS);
- return OS;
-}
+
+raw_ostream &rdf::operator<<(raw_ostream &OS, const RegisterAggr &A) {
+ A.print(OS);
+ return OS;
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/ReachingDefAnalysis.cpp b/contrib/libs/llvm12/lib/CodeGen/ReachingDefAnalysis.cpp
index c488990145..d16e90a7e0 100644
--- a/contrib/libs/llvm12/lib/CodeGen/ReachingDefAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/ReachingDefAnalysis.cpp
@@ -29,7 +29,7 @@ static bool isValidRegUse(const MachineOperand &MO) {
return isValidReg(MO) && MO.isUse();
}
-static bool isValidRegUseOf(const MachineOperand &MO, MCRegister PhysReg) {
+static bool isValidRegUseOf(const MachineOperand &MO, MCRegister PhysReg) {
return isValidRegUse(MO) && MO.getReg() == PhysReg;
}
@@ -37,7 +37,7 @@ static bool isValidRegDef(const MachineOperand &MO) {
return isValidReg(MO) && MO.isDef();
}
-static bool isValidRegDefOf(const MachineOperand &MO, MCRegister PhysReg) {
+static bool isValidRegDefOf(const MachineOperand &MO, MCRegister PhysReg) {
return isValidRegDef(MO) && MO.getReg() == PhysReg;
}
@@ -121,8 +121,8 @@ void ReachingDefAnalysis::processDefs(MachineInstr *MI) {
for (auto &MO : MI->operands()) {
if (!isValidRegDef(MO))
continue;
- for (MCRegUnitIterator Unit(MO.getReg().asMCReg(), TRI); Unit.isValid();
- ++Unit) {
+ for (MCRegUnitIterator Unit(MO.getReg().asMCReg(), TRI); Unit.isValid();
+ ++Unit) {
// This instruction explicitly defines the current reg unit.
LLVM_DEBUG(dbgs() << printReg(*Unit, TRI) << ":\t" << CurInstr
<< '\t' << *MI);
@@ -144,9 +144,9 @@ void ReachingDefAnalysis::reprocessBasicBlock(MachineBasicBlock *MBB) {
"Unexpected basic block number.");
// Count number of non-debug instructions for end of block adjustment.
- auto NonDbgInsts =
- instructionsWithoutDebug(MBB->instr_begin(), MBB->instr_end());
- int NumInsts = std::distance(NonDbgInsts.begin(), NonDbgInsts.end());
+ auto NonDbgInsts =
+ instructionsWithoutDebug(MBB->instr_begin(), MBB->instr_end());
+ int NumInsts = std::distance(NonDbgInsts.begin(), NonDbgInsts.end());
// When reprocessing a block, the only thing we need to do is check whether
// there is now a more recent incoming reaching definition from a predecessor.
@@ -197,9 +197,9 @@ void ReachingDefAnalysis::processBasicBlock(
}
enterBasicBlock(MBB);
- for (MachineInstr &MI :
- instructionsWithoutDebug(MBB->instr_begin(), MBB->instr_end()))
- processDefs(&MI);
+ for (MachineInstr &MI :
+ instructionsWithoutDebug(MBB->instr_begin(), MBB->instr_end()))
+ processDefs(&MI);
leaveBasicBlock(MBB);
}
@@ -253,8 +253,8 @@ void ReachingDefAnalysis::traverse() {
#endif
}
-int ReachingDefAnalysis::getReachingDef(MachineInstr *MI,
- MCRegister PhysReg) const {
+int ReachingDefAnalysis::getReachingDef(MachineInstr *MI,
+ MCRegister PhysReg) const {
assert(InstIds.count(MI) && "Unexpected machine instuction.");
int InstId = InstIds.lookup(MI);
int DefRes = ReachingDefDefaultVal;
@@ -273,16 +273,16 @@ int ReachingDefAnalysis::getReachingDef(MachineInstr *MI,
return LatestDef;
}
-MachineInstr *
-ReachingDefAnalysis::getReachingLocalMIDef(MachineInstr *MI,
- MCRegister PhysReg) const {
- return hasLocalDefBefore(MI, PhysReg)
- ? getInstFromId(MI->getParent(), getReachingDef(MI, PhysReg))
- : nullptr;
+MachineInstr *
+ReachingDefAnalysis::getReachingLocalMIDef(MachineInstr *MI,
+ MCRegister PhysReg) const {
+ return hasLocalDefBefore(MI, PhysReg)
+ ? getInstFromId(MI->getParent(), getReachingDef(MI, PhysReg))
+ : nullptr;
}
bool ReachingDefAnalysis::hasSameReachingDef(MachineInstr *A, MachineInstr *B,
- MCRegister PhysReg) const {
+ MCRegister PhysReg) const {
MachineBasicBlock *ParentA = A->getParent();
MachineBasicBlock *ParentB = B->getParent();
if (ParentA != ParentB)
@@ -310,19 +310,19 @@ MachineInstr *ReachingDefAnalysis::getInstFromId(MachineBasicBlock *MBB,
return nullptr;
}
-int ReachingDefAnalysis::getClearance(MachineInstr *MI,
- MCRegister PhysReg) const {
+int ReachingDefAnalysis::getClearance(MachineInstr *MI,
+ MCRegister PhysReg) const {
assert(InstIds.count(MI) && "Unexpected machine instuction.");
return InstIds.lookup(MI) - getReachingDef(MI, PhysReg);
}
-bool ReachingDefAnalysis::hasLocalDefBefore(MachineInstr *MI,
- MCRegister PhysReg) const {
+bool ReachingDefAnalysis::hasLocalDefBefore(MachineInstr *MI,
+ MCRegister PhysReg) const {
return getReachingDef(MI, PhysReg) >= 0;
}
-void ReachingDefAnalysis::getReachingLocalUses(MachineInstr *Def,
- MCRegister PhysReg,
+void ReachingDefAnalysis::getReachingLocalUses(MachineInstr *Def,
+ MCRegister PhysReg,
InstSet &Uses) const {
MachineBasicBlock *MBB = Def->getParent();
MachineBasicBlock::iterator MI = MachineBasicBlock::iterator(Def);
@@ -346,11 +346,11 @@ void ReachingDefAnalysis::getReachingLocalUses(MachineInstr *Def,
}
}
-bool ReachingDefAnalysis::getLiveInUses(MachineBasicBlock *MBB,
- MCRegister PhysReg,
- InstSet &Uses) const {
- for (MachineInstr &MI :
- instructionsWithoutDebug(MBB->instr_begin(), MBB->instr_end())) {
+bool ReachingDefAnalysis::getLiveInUses(MachineBasicBlock *MBB,
+ MCRegister PhysReg,
+ InstSet &Uses) const {
+ for (MachineInstr &MI :
+ instructionsWithoutDebug(MBB->instr_begin(), MBB->instr_end())) {
for (auto &MO : MI.operands()) {
if (!isValidRegUseOf(MO, PhysReg))
continue;
@@ -359,14 +359,14 @@ bool ReachingDefAnalysis::getLiveInUses(MachineBasicBlock *MBB,
Uses.insert(&MI);
}
}
- auto Last = MBB->getLastNonDebugInstr();
- if (Last == MBB->end())
- return true;
- return isReachingDefLiveOut(&*Last, PhysReg);
+ auto Last = MBB->getLastNonDebugInstr();
+ if (Last == MBB->end())
+ return true;
+ return isReachingDefLiveOut(&*Last, PhysReg);
}
-void ReachingDefAnalysis::getGlobalUses(MachineInstr *MI, MCRegister PhysReg,
- InstSet &Uses) const {
+void ReachingDefAnalysis::getGlobalUses(MachineInstr *MI, MCRegister PhysReg,
+ InstSet &Uses) const {
MachineBasicBlock *MBB = MI->getParent();
// Collect the uses that each def touches within the block.
@@ -377,7 +377,7 @@ void ReachingDefAnalysis::getGlobalUses(MachineInstr *MI, MCRegister PhysReg,
if (LiveOut != MI)
return;
- SmallVector<MachineBasicBlock *, 4> ToVisit(MBB->successors());
+ SmallVector<MachineBasicBlock *, 4> ToVisit(MBB->successors());
SmallPtrSet<MachineBasicBlock*, 4>Visited;
while (!ToVisit.empty()) {
MachineBasicBlock *MBB = ToVisit.back();
@@ -385,33 +385,33 @@ void ReachingDefAnalysis::getGlobalUses(MachineInstr *MI, MCRegister PhysReg,
if (Visited.count(MBB) || !MBB->isLiveIn(PhysReg))
continue;
if (getLiveInUses(MBB, PhysReg, Uses))
- llvm::append_range(ToVisit, MBB->successors());
+ llvm::append_range(ToVisit, MBB->successors());
Visited.insert(MBB);
}
}
}
-void ReachingDefAnalysis::getGlobalReachingDefs(MachineInstr *MI,
- MCRegister PhysReg,
- InstSet &Defs) const {
- if (auto *Def = getUniqueReachingMIDef(MI, PhysReg)) {
- Defs.insert(Def);
- return;
- }
-
- for (auto *MBB : MI->getParent()->predecessors())
- getLiveOuts(MBB, PhysReg, Defs);
-}
-
-void ReachingDefAnalysis::getLiveOuts(MachineBasicBlock *MBB,
- MCRegister PhysReg, InstSet &Defs) const {
+void ReachingDefAnalysis::getGlobalReachingDefs(MachineInstr *MI,
+ MCRegister PhysReg,
+ InstSet &Defs) const {
+ if (auto *Def = getUniqueReachingMIDef(MI, PhysReg)) {
+ Defs.insert(Def);
+ return;
+ }
+
+ for (auto *MBB : MI->getParent()->predecessors())
+ getLiveOuts(MBB, PhysReg, Defs);
+}
+
+void ReachingDefAnalysis::getLiveOuts(MachineBasicBlock *MBB,
+ MCRegister PhysReg, InstSet &Defs) const {
SmallPtrSet<MachineBasicBlock*, 2> VisitedBBs;
getLiveOuts(MBB, PhysReg, Defs, VisitedBBs);
}
-void ReachingDefAnalysis::getLiveOuts(MachineBasicBlock *MBB,
- MCRegister PhysReg, InstSet &Defs,
- BlockSet &VisitedBBs) const {
+void ReachingDefAnalysis::getLiveOuts(MachineBasicBlock *MBB,
+ MCRegister PhysReg, InstSet &Defs,
+ BlockSet &VisitedBBs) const {
if (VisitedBBs.count(MBB))
return;
@@ -428,25 +428,25 @@ void ReachingDefAnalysis::getLiveOuts(MachineBasicBlock *MBB,
getLiveOuts(Pred, PhysReg, Defs, VisitedBBs);
}
-MachineInstr *
-ReachingDefAnalysis::getUniqueReachingMIDef(MachineInstr *MI,
- MCRegister PhysReg) const {
+MachineInstr *
+ReachingDefAnalysis::getUniqueReachingMIDef(MachineInstr *MI,
+ MCRegister PhysReg) const {
// If there's a local def before MI, return it.
MachineInstr *LocalDef = getReachingLocalMIDef(MI, PhysReg);
if (LocalDef && InstIds.lookup(LocalDef) < InstIds.lookup(MI))
return LocalDef;
SmallPtrSet<MachineInstr*, 2> Incoming;
- MachineBasicBlock *Parent = MI->getParent();
- for (auto *Pred : Parent->predecessors())
- getLiveOuts(Pred, PhysReg, Incoming);
-
- // Check that we have a single incoming value and that it does not
- // come from the same block as MI - since it would mean that the def
- // is executed after MI.
- if (Incoming.size() == 1 && (*Incoming.begin())->getParent() != Parent)
+ MachineBasicBlock *Parent = MI->getParent();
+ for (auto *Pred : Parent->predecessors())
+ getLiveOuts(Pred, PhysReg, Incoming);
+
+ // Check that we have a single incoming value and that it does not
+ // come from the same block as MI - since it would mean that the def
+ // is executed after MI.
+ if (Incoming.size() == 1 && (*Incoming.begin())->getParent() != Parent)
return *Incoming.begin();
- return nullptr;
+ return nullptr;
}
MachineInstr *ReachingDefAnalysis::getMIOperand(MachineInstr *MI,
@@ -461,8 +461,8 @@ MachineInstr *ReachingDefAnalysis::getMIOperand(MachineInstr *MI,
return getUniqueReachingMIDef(MI, MO.getReg());
}
-bool ReachingDefAnalysis::isRegUsedAfter(MachineInstr *MI,
- MCRegister PhysReg) const {
+bool ReachingDefAnalysis::isRegUsedAfter(MachineInstr *MI,
+ MCRegister PhysReg) const {
MachineBasicBlock *MBB = MI->getParent();
LivePhysRegs LiveRegs(*TRI);
LiveRegs.addLiveOuts(*MBB);
@@ -473,21 +473,21 @@ bool ReachingDefAnalysis::isRegUsedAfter(MachineInstr *MI,
// Walk backwards through the block to see if the register is live at some
// point.
- for (MachineInstr &Last :
- instructionsWithoutDebug(MBB->instr_rbegin(), MBB->instr_rend())) {
- LiveRegs.stepBackward(Last);
+ for (MachineInstr &Last :
+ instructionsWithoutDebug(MBB->instr_rbegin(), MBB->instr_rend())) {
+ LiveRegs.stepBackward(Last);
if (LiveRegs.contains(PhysReg))
- return InstIds.lookup(&Last) > InstIds.lookup(MI);
+ return InstIds.lookup(&Last) > InstIds.lookup(MI);
}
return false;
}
bool ReachingDefAnalysis::isRegDefinedAfter(MachineInstr *MI,
- MCRegister PhysReg) const {
+ MCRegister PhysReg) const {
MachineBasicBlock *MBB = MI->getParent();
- auto Last = MBB->getLastNonDebugInstr();
- if (Last != MBB->end() &&
- getReachingDef(MI, PhysReg) != getReachingDef(&*Last, PhysReg))
+ auto Last = MBB->getLastNonDebugInstr();
+ if (Last != MBB->end() &&
+ getReachingDef(MI, PhysReg) != getReachingDef(&*Last, PhysReg))
return true;
if (auto *Def = getLocalLiveOutMIDef(MBB, PhysReg))
@@ -496,17 +496,17 @@ bool ReachingDefAnalysis::isRegDefinedAfter(MachineInstr *MI,
return false;
}
-bool ReachingDefAnalysis::isReachingDefLiveOut(MachineInstr *MI,
- MCRegister PhysReg) const {
+bool ReachingDefAnalysis::isReachingDefLiveOut(MachineInstr *MI,
+ MCRegister PhysReg) const {
MachineBasicBlock *MBB = MI->getParent();
LivePhysRegs LiveRegs(*TRI);
LiveRegs.addLiveOuts(*MBB);
if (!LiveRegs.contains(PhysReg))
return false;
- auto Last = MBB->getLastNonDebugInstr();
+ auto Last = MBB->getLastNonDebugInstr();
int Def = getReachingDef(MI, PhysReg);
- if (Last != MBB->end() && getReachingDef(&*Last, PhysReg) != Def)
+ if (Last != MBB->end() && getReachingDef(&*Last, PhysReg) != Def)
return false;
// Finally check that the last instruction doesn't redefine the register.
@@ -517,22 +517,22 @@ bool ReachingDefAnalysis::isReachingDefLiveOut(MachineInstr *MI,
return true;
}
-MachineInstr *
-ReachingDefAnalysis::getLocalLiveOutMIDef(MachineBasicBlock *MBB,
- MCRegister PhysReg) const {
+MachineInstr *
+ReachingDefAnalysis::getLocalLiveOutMIDef(MachineBasicBlock *MBB,
+ MCRegister PhysReg) const {
LivePhysRegs LiveRegs(*TRI);
LiveRegs.addLiveOuts(*MBB);
if (!LiveRegs.contains(PhysReg))
return nullptr;
- auto Last = MBB->getLastNonDebugInstr();
- if (Last == MBB->end())
- return nullptr;
-
- int Def = getReachingDef(&*Last, PhysReg);
+ auto Last = MBB->getLastNonDebugInstr();
+ if (Last == MBB->end())
+ return nullptr;
+
+ int Def = getReachingDef(&*Last, PhysReg);
for (auto &MO : Last->operands())
if (isValidRegDefOf(MO, PhysReg))
- return &*Last;
+ return &*Last;
return Def < 0 ? nullptr : getInstFromId(MBB, Def);
}
@@ -549,7 +549,7 @@ static bool mayHaveSideEffects(MachineInstr &MI) {
template<typename Iterator>
bool ReachingDefAnalysis::isSafeToMove(MachineInstr *From,
MachineInstr *To) const {
- if (From->getParent() != To->getParent() || From == To)
+ if (From->getParent() != To->getParent() || From == To)
return false;
SmallSet<int, 2> Defs;
@@ -578,22 +578,22 @@ bool ReachingDefAnalysis::isSafeToMove(MachineInstr *From,
bool ReachingDefAnalysis::isSafeToMoveForwards(MachineInstr *From,
MachineInstr *To) const {
- using Iterator = MachineBasicBlock::iterator;
- // Walk forwards until we find the instruction.
- for (auto I = Iterator(From), E = From->getParent()->end(); I != E; ++I)
- if (&*I == To)
- return isSafeToMove<Iterator>(From, To);
- return false;
+ using Iterator = MachineBasicBlock::iterator;
+ // Walk forwards until we find the instruction.
+ for (auto I = Iterator(From), E = From->getParent()->end(); I != E; ++I)
+ if (&*I == To)
+ return isSafeToMove<Iterator>(From, To);
+ return false;
}
bool ReachingDefAnalysis::isSafeToMoveBackwards(MachineInstr *From,
MachineInstr *To) const {
- using Iterator = MachineBasicBlock::reverse_iterator;
- // Walk backwards until we find the instruction.
- for (auto I = Iterator(From), E = From->getParent()->rend(); I != E; ++I)
- if (&*I == To)
- return isSafeToMove<Iterator>(From, To);
- return false;
+ using Iterator = MachineBasicBlock::reverse_iterator;
+ // Walk backwards until we find the instruction.
+ for (auto I = Iterator(From), E = From->getParent()->rend(); I != E; ++I)
+ if (&*I == To)
+ return isSafeToMove<Iterator>(From, To);
+ return false;
}
bool ReachingDefAnalysis::isSafeToRemove(MachineInstr *MI,
@@ -643,10 +643,10 @@ ReachingDefAnalysis::isSafeToRemove(MachineInstr *MI, InstSet &Visited,
void ReachingDefAnalysis::collectKilledOperands(MachineInstr *MI,
InstSet &Dead) const {
Dead.insert(MI);
- auto IsDead = [this, &Dead](MachineInstr *Def, MCRegister PhysReg) {
- if (mayHaveSideEffects(*Def))
- return false;
-
+ auto IsDead = [this, &Dead](MachineInstr *Def, MCRegister PhysReg) {
+ if (mayHaveSideEffects(*Def))
+ return false;
+
unsigned LiveDefs = 0;
for (auto &MO : Def->operands()) {
if (!isValidRegDef(MO))
@@ -676,18 +676,18 @@ void ReachingDefAnalysis::collectKilledOperands(MachineInstr *MI,
}
bool ReachingDefAnalysis::isSafeToDefRegAt(MachineInstr *MI,
- MCRegister PhysReg) const {
+ MCRegister PhysReg) const {
SmallPtrSet<MachineInstr*, 1> Ignore;
return isSafeToDefRegAt(MI, PhysReg, Ignore);
}
-bool ReachingDefAnalysis::isSafeToDefRegAt(MachineInstr *MI, MCRegister PhysReg,
+bool ReachingDefAnalysis::isSafeToDefRegAt(MachineInstr *MI, MCRegister PhysReg,
InstSet &Ignore) const {
// Check for any uses of the register after MI.
if (isRegUsedAfter(MI, PhysReg)) {
if (auto *Def = getReachingLocalMIDef(MI, PhysReg)) {
SmallPtrSet<MachineInstr*, 2> Uses;
- getGlobalUses(Def, PhysReg, Uses);
+ getGlobalUses(Def, PhysReg, Uses);
for (auto *Use : Uses)
if (!Ignore.count(Use))
return false;
diff --git a/contrib/libs/llvm12/lib/CodeGen/RegAllocBase.cpp b/contrib/libs/llvm12/lib/CodeGen/RegAllocBase.cpp
index d72517de13..aa749ca43e 100644
--- a/contrib/libs/llvm12/lib/CodeGen/RegAllocBase.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/RegAllocBase.cpp
@@ -73,7 +73,7 @@ void RegAllocBase::seedLiveRegs() {
NamedRegionTimer T("seed", "Seed Live Regs", TimerGroupName,
TimerGroupDescription, TimePassesIsEnabled);
for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
- Register Reg = Register::index2VirtReg(i);
+ Register Reg = Register::index2VirtReg(i);
if (MRI->reg_nodbg_empty(Reg))
continue;
enqueue(&LIS->getInterval(Reg));
@@ -87,13 +87,13 @@ void RegAllocBase::allocatePhysRegs() {
// Continue assigning vregs one at a time to available physical registers.
while (LiveInterval *VirtReg = dequeue()) {
- assert(!VRM->hasPhys(VirtReg->reg()) && "Register already assigned");
+ assert(!VRM->hasPhys(VirtReg->reg()) && "Register already assigned");
// Unused registers can appear when the spiller coalesces snippets.
- if (MRI->reg_nodbg_empty(VirtReg->reg())) {
+ if (MRI->reg_nodbg_empty(VirtReg->reg())) {
LLVM_DEBUG(dbgs() << "Dropping unused " << *VirtReg << '\n');
aboutToRemoveInterval(*VirtReg);
- LIS->removeInterval(VirtReg->reg());
+ LIS->removeInterval(VirtReg->reg());
continue;
}
@@ -104,22 +104,22 @@ void RegAllocBase::allocatePhysRegs() {
// register if possible and populate a list of new live intervals that
// result from splitting.
LLVM_DEBUG(dbgs() << "\nselectOrSplit "
- << TRI->getRegClassName(MRI->getRegClass(VirtReg->reg()))
- << ':' << *VirtReg << " w=" << VirtReg->weight() << '\n');
+ << TRI->getRegClassName(MRI->getRegClass(VirtReg->reg()))
+ << ':' << *VirtReg << " w=" << VirtReg->weight() << '\n');
using VirtRegVec = SmallVector<Register, 4>;
VirtRegVec SplitVRegs;
- MCRegister AvailablePhysReg = selectOrSplit(*VirtReg, SplitVRegs);
+ MCRegister AvailablePhysReg = selectOrSplit(*VirtReg, SplitVRegs);
if (AvailablePhysReg == ~0u) {
// selectOrSplit failed to find a register!
// Probably caused by an inline asm.
MachineInstr *MI = nullptr;
for (MachineRegisterInfo::reg_instr_iterator
- I = MRI->reg_instr_begin(VirtReg->reg()),
- E = MRI->reg_instr_end();
- I != E;) {
+ I = MRI->reg_instr_begin(VirtReg->reg()),
+ E = MRI->reg_instr_end();
+ I != E;) {
MI = &*(I++);
if (MI->isInlineAsm())
break;
@@ -134,29 +134,29 @@ void RegAllocBase::allocatePhysRegs() {
report_fatal_error("ran out of registers during register allocation");
}
// Keep going after reporting the error.
- VRM->assignVirt2Phys(
- VirtReg->reg(),
- RegClassInfo.getOrder(MRI->getRegClass(VirtReg->reg())).front());
+ VRM->assignVirt2Phys(
+ VirtReg->reg(),
+ RegClassInfo.getOrder(MRI->getRegClass(VirtReg->reg())).front());
continue;
}
if (AvailablePhysReg)
Matrix->assign(*VirtReg, AvailablePhysReg);
- for (Register Reg : SplitVRegs) {
+ for (Register Reg : SplitVRegs) {
assert(LIS->hasInterval(Reg));
LiveInterval *SplitVirtReg = &LIS->getInterval(Reg);
- assert(!VRM->hasPhys(SplitVirtReg->reg()) && "Register already assigned");
- if (MRI->reg_nodbg_empty(SplitVirtReg->reg())) {
+ assert(!VRM->hasPhys(SplitVirtReg->reg()) && "Register already assigned");
+ if (MRI->reg_nodbg_empty(SplitVirtReg->reg())) {
assert(SplitVirtReg->empty() && "Non-empty but used interval");
LLVM_DEBUG(dbgs() << "not queueing unused " << *SplitVirtReg << '\n');
aboutToRemoveInterval(*SplitVirtReg);
- LIS->removeInterval(SplitVirtReg->reg());
+ LIS->removeInterval(SplitVirtReg->reg());
continue;
}
LLVM_DEBUG(dbgs() << "queuing new interval: " << *SplitVirtReg << "\n");
- assert(Register::isVirtualRegister(SplitVirtReg->reg()) &&
+ assert(Register::isVirtualRegister(SplitVirtReg->reg()) &&
"expect split value in virtual register");
enqueue(SplitVirtReg);
++NumNewQueued;
diff --git a/contrib/libs/llvm12/lib/CodeGen/RegAllocBase.h b/contrib/libs/llvm12/lib/CodeGen/RegAllocBase.h
index 23e24a7bf2..3144605345 100644
--- a/contrib/libs/llvm12/lib/CodeGen/RegAllocBase.h
+++ b/contrib/libs/llvm12/lib/CodeGen/RegAllocBase.h
@@ -101,8 +101,8 @@ protected:
// Each call must guarantee forward progess by returning an available PhysReg
// or new set of split live virtual registers. It is up to the splitter to
// converge quickly toward fully spilled live ranges.
- virtual MCRegister selectOrSplit(LiveInterval &VirtReg,
- SmallVectorImpl<Register> &splitLVRs) = 0;
+ virtual MCRegister selectOrSplit(LiveInterval &VirtReg,
+ SmallVectorImpl<Register> &splitLVRs) = 0;
// Use this group name for NamedRegionTimer.
static const char TimerGroupName[];
diff --git a/contrib/libs/llvm12/lib/CodeGen/RegAllocBasic.cpp b/contrib/libs/llvm12/lib/CodeGen/RegAllocBasic.cpp
index acff080e8d..8f2cb48c5d 100644
--- a/contrib/libs/llvm12/lib/CodeGen/RegAllocBasic.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/RegAllocBasic.cpp
@@ -46,7 +46,7 @@ static RegisterRegAlloc basicRegAlloc("basic", "basic register allocator",
namespace {
struct CompSpillWeight {
bool operator()(LiveInterval *A, LiveInterval *B) const {
- return A->weight() < B->weight();
+ return A->weight() < B->weight();
}
};
}
@@ -72,8 +72,8 @@ class RABasic : public MachineFunctionPass,
// selectOrSplit().
BitVector UsableRegs;
- bool LRE_CanEraseVirtReg(Register) override;
- void LRE_WillShrinkVirtReg(Register) override;
+ bool LRE_CanEraseVirtReg(Register) override;
+ void LRE_WillShrinkVirtReg(Register) override;
public:
RABasic();
@@ -100,8 +100,8 @@ public:
return LI;
}
- MCRegister selectOrSplit(LiveInterval &VirtReg,
- SmallVectorImpl<Register> &SplitVRegs) override;
+ MCRegister selectOrSplit(LiveInterval &VirtReg,
+ SmallVectorImpl<Register> &SplitVRegs) override;
/// Perform register allocation.
bool runOnMachineFunction(MachineFunction &mf) override;
@@ -111,15 +111,15 @@ public:
MachineFunctionProperties::Property::NoPHIs);
}
- MachineFunctionProperties getClearedProperties() const override {
- return MachineFunctionProperties().set(
- MachineFunctionProperties::Property::IsSSA);
- }
-
+ MachineFunctionProperties getClearedProperties() const override {
+ return MachineFunctionProperties().set(
+ MachineFunctionProperties::Property::IsSSA);
+ }
+
// Helper for spilling all live virtual registers currently unified under preg
// that interfere with the most recently queried lvr. Return true if spilling
// was successful, and append any new spilled/split intervals to splitLVRs.
- bool spillInterferences(LiveInterval &VirtReg, MCRegister PhysReg,
+ bool spillInterferences(LiveInterval &VirtReg, MCRegister PhysReg,
SmallVectorImpl<Register> &SplitVRegs);
static char ID;
@@ -146,7 +146,7 @@ INITIALIZE_PASS_DEPENDENCY(LiveRegMatrix)
INITIALIZE_PASS_END(RABasic, "regallocbasic", "Basic Register Allocator", false,
false)
-bool RABasic::LRE_CanEraseVirtReg(Register VirtReg) {
+bool RABasic::LRE_CanEraseVirtReg(Register VirtReg) {
LiveInterval &LI = LIS->getInterval(VirtReg);
if (VRM->hasPhys(VirtReg)) {
Matrix->unassign(LI);
@@ -161,7 +161,7 @@ bool RABasic::LRE_CanEraseVirtReg(Register VirtReg) {
return false;
}
-void RABasic::LRE_WillShrinkVirtReg(Register VirtReg) {
+void RABasic::LRE_WillShrinkVirtReg(Register VirtReg) {
if (!VRM->hasPhys(VirtReg))
return;
@@ -206,7 +206,7 @@ void RABasic::releaseMemory() {
// Spill or split all live virtual registers currently unified under PhysReg
// that interfere with VirtReg. The newly spilled or split live intervals are
// returned by appending them to SplitVRegs.
-bool RABasic::spillInterferences(LiveInterval &VirtReg, MCRegister PhysReg,
+bool RABasic::spillInterferences(LiveInterval &VirtReg, MCRegister PhysReg,
SmallVectorImpl<Register> &SplitVRegs) {
// Record each interference and determine if all are spillable before mutating
// either the union or live intervals.
@@ -218,7 +218,7 @@ bool RABasic::spillInterferences(LiveInterval &VirtReg, MCRegister PhysReg,
Q.collectInterferingVRegs();
for (unsigned i = Q.interferingVRegs().size(); i; --i) {
LiveInterval *Intf = Q.interferingVRegs()[i - 1];
- if (!Intf->isSpillable() || Intf->weight() > VirtReg.weight())
+ if (!Intf->isSpillable() || Intf->weight() > VirtReg.weight())
return false;
Intfs.push_back(Intf);
}
@@ -232,7 +232,7 @@ bool RABasic::spillInterferences(LiveInterval &VirtReg, MCRegister PhysReg,
LiveInterval &Spill = *Intfs[i];
// Skip duplicates.
- if (!VRM->hasPhys(Spill.reg()))
+ if (!VRM->hasPhys(Spill.reg()))
continue;
// Deallocate the interfering vreg by removing it from the union.
@@ -258,16 +258,16 @@ bool RABasic::spillInterferences(LiveInterval &VirtReg, MCRegister PhysReg,
// |vregs| * |machineregs|. And since the number of interference tests is
// minimal, there is no value in caching them outside the scope of
// selectOrSplit().
-MCRegister RABasic::selectOrSplit(LiveInterval &VirtReg,
- SmallVectorImpl<Register> &SplitVRegs) {
+MCRegister RABasic::selectOrSplit(LiveInterval &VirtReg,
+ SmallVectorImpl<Register> &SplitVRegs) {
// Populate a list of physical register spill candidates.
- SmallVector<MCRegister, 8> PhysRegSpillCands;
+ SmallVector<MCRegister, 8> PhysRegSpillCands;
// Check for an available register in this class.
- auto Order =
- AllocationOrder::create(VirtReg.reg(), *VRM, RegClassInfo, Matrix);
- for (MCRegister PhysReg : Order) {
- assert(PhysReg.isValid());
+ auto Order =
+ AllocationOrder::create(VirtReg.reg(), *VRM, RegClassInfo, Matrix);
+ for (MCRegister PhysReg : Order) {
+ assert(PhysReg.isValid());
// Check for interference in PhysReg
switch (Matrix->checkInterference(VirtReg, PhysReg)) {
case LiveRegMatrix::IK_Free:
@@ -286,9 +286,9 @@ MCRegister RABasic::selectOrSplit(LiveInterval &VirtReg,
}
// Try to spill another interfering reg with less spill weight.
- for (auto PhysRegI = PhysRegSpillCands.begin(),
- PhysRegE = PhysRegSpillCands.end();
- PhysRegI != PhysRegE; ++PhysRegI) {
+ for (auto PhysRegI = PhysRegSpillCands.begin(),
+ PhysRegE = PhysRegSpillCands.end();
+ PhysRegI != PhysRegE; ++PhysRegI) {
if (!spillInterferences(VirtReg, *PhysRegI, SplitVRegs))
continue;
@@ -318,9 +318,9 @@ bool RABasic::runOnMachineFunction(MachineFunction &mf) {
RegAllocBase::init(getAnalysis<VirtRegMap>(),
getAnalysis<LiveIntervals>(),
getAnalysis<LiveRegMatrix>());
- VirtRegAuxInfo VRAI(*MF, *LIS, *VRM, getAnalysis<MachineLoopInfo>(),
- getAnalysis<MachineBlockFrequencyInfo>());
- VRAI.calculateSpillWeightsAndHints();
+ VirtRegAuxInfo VRAI(*MF, *LIS, *VRM, getAnalysis<MachineLoopInfo>(),
+ getAnalysis<MachineBlockFrequencyInfo>());
+ VRAI.calculateSpillWeightsAndHints();
SpillerInstance.reset(createInlineSpiller(*this, *MF, *VRM));
diff --git a/contrib/libs/llvm12/lib/CodeGen/RegAllocFast.cpp b/contrib/libs/llvm12/lib/CodeGen/RegAllocFast.cpp
index 025d2ed705..6e548d4a93 100644
--- a/contrib/libs/llvm12/lib/CodeGen/RegAllocFast.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/RegAllocFast.cpp
@@ -56,10 +56,10 @@ STATISTIC(NumStores, "Number of stores added");
STATISTIC(NumLoads , "Number of loads added");
STATISTIC(NumCoalesced, "Number of copies coalesced");
-// FIXME: Remove this switch when all testcases are fixed!
-static cl::opt<bool> IgnoreMissingDefs("rafast-ignore-missing-defs",
- cl::Hidden);
-
+// FIXME: Remove this switch when all testcases are fixed!
+static cl::opt<bool> IgnoreMissingDefs("rafast-ignore-missing-defs",
+ cl::Hidden);
+
static RegisterRegAlloc
fastRegAlloc("fast", "fast register allocator", createFastRegisterAllocator);
@@ -89,9 +89,9 @@ namespace {
MachineInstr *LastUse = nullptr; ///< Last instr to use reg.
Register VirtReg; ///< Virtual register number.
MCPhysReg PhysReg = 0; ///< Currently held here.
- bool LiveOut = false; ///< Register is possibly live out.
- bool Reloaded = false; ///< Register was reloaded.
- bool Error = false; ///< Could not allocate.
+ bool LiveOut = false; ///< Register is possibly live out.
+ bool Reloaded = false; ///< Register was reloaded.
+ bool Error = false; ///< Could not allocate.
explicit LiveReg(Register VirtReg) : VirtReg(VirtReg) {}
@@ -105,39 +105,39 @@ namespace {
/// available in a physical register.
LiveRegMap LiveVirtRegs;
- /// Stores assigned virtual registers present in the bundle MI.
- DenseMap<Register, MCPhysReg> BundleVirtRegsMap;
-
+ /// Stores assigned virtual registers present in the bundle MI.
+ DenseMap<Register, MCPhysReg> BundleVirtRegsMap;
+
DenseMap<unsigned, SmallVector<MachineInstr *, 2>> LiveDbgValueMap;
- /// List of DBG_VALUE that we encountered without the vreg being assigned
- /// because they were placed after the last use of the vreg.
- DenseMap<unsigned, SmallVector<MachineInstr *, 1>> DanglingDbgValues;
+ /// List of DBG_VALUE that we encountered without the vreg being assigned
+ /// because they were placed after the last use of the vreg.
+ DenseMap<unsigned, SmallVector<MachineInstr *, 1>> DanglingDbgValues;
/// Has a bit set for every virtual register for which it was determined
/// that it is alive across blocks.
BitVector MayLiveAcrossBlocks;
- /// State of a register unit.
- enum RegUnitState {
+ /// State of a register unit.
+ enum RegUnitState {
/// A free register is not currently in use and can be allocated
/// immediately without checking aliases.
regFree,
- /// A pre-assigned register has been assigned before register allocation
- /// (e.g., setting up a call parameter).
- regPreAssigned,
+ /// A pre-assigned register has been assigned before register allocation
+ /// (e.g., setting up a call parameter).
+ regPreAssigned,
+
+ /// Used temporarily in reloadAtBegin() to mark register units that are
+ /// live-in to the basic block.
+ regLiveIn,
- /// Used temporarily in reloadAtBegin() to mark register units that are
- /// live-in to the basic block.
- regLiveIn,
-
/// A register state may also be a virtual register number, indication
/// that the physical register is currently allocated to a virtual
/// register. In that case, LiveVirtRegs contains the inverse mapping.
};
- /// Maps each physical register to a RegUnitState enum or virtual register.
- std::vector<unsigned> RegUnitStates;
+ /// Maps each physical register to a RegUnitState enum or virtual register.
+ std::vector<unsigned> RegUnitStates;
SmallVector<MachineInstr *, 32> Coalesced;
@@ -145,11 +145,11 @@ namespace {
/// Set of register units that are used in the current instruction, and so
/// cannot be allocated.
RegUnitSet UsedInInstr;
- RegUnitSet PhysRegUses;
- SmallVector<uint16_t, 8> DefOperandIndexes;
+ RegUnitSet PhysRegUses;
+ SmallVector<uint16_t, 8> DefOperandIndexes;
void setPhysRegState(MCPhysReg PhysReg, unsigned NewState);
- bool isPhysRegFree(MCPhysReg PhysReg) const;
+ bool isPhysRegFree(MCPhysReg PhysReg) const;
/// Mark a physreg as used in this instruction.
void markRegUsedInInstr(MCPhysReg PhysReg) {
@@ -158,29 +158,29 @@ namespace {
}
/// Check if a physreg or any of its aliases are used in this instruction.
- bool isRegUsedInInstr(MCPhysReg PhysReg, bool LookAtPhysRegUses) const {
- for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
+ bool isRegUsedInInstr(MCPhysReg PhysReg, bool LookAtPhysRegUses) const {
+ for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
if (UsedInInstr.count(*Units))
return true;
- if (LookAtPhysRegUses && PhysRegUses.count(*Units))
- return true;
- }
+ if (LookAtPhysRegUses && PhysRegUses.count(*Units))
+ return true;
+ }
return false;
}
- /// Mark physical register as being used in a register use operand.
- /// This is only used by the special livethrough handling code.
- void markPhysRegUsedInInstr(MCPhysReg PhysReg) {
- for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units)
- PhysRegUses.insert(*Units);
- }
-
- /// Remove mark of physical register being used in the instruction.
- void unmarkRegUsedInInstr(MCPhysReg PhysReg) {
- for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units)
- UsedInInstr.erase(*Units);
- }
-
+ /// Mark physical register as being used in a register use operand.
+ /// This is only used by the special livethrough handling code.
+ void markPhysRegUsedInInstr(MCPhysReg PhysReg) {
+ for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units)
+ PhysRegUses.insert(*Units);
+ }
+
+ /// Remove mark of physical register being used in the instruction.
+ void unmarkRegUsedInInstr(MCPhysReg PhysReg) {
+ for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units)
+ UsedInInstr.erase(*Units);
+ }
+
enum : unsigned {
spillClean = 50,
spillDirty = 100,
@@ -206,27 +206,27 @@ namespace {
MachineFunctionProperties::Property::NoVRegs);
}
- MachineFunctionProperties getClearedProperties() const override {
- return MachineFunctionProperties().set(
- MachineFunctionProperties::Property::IsSSA);
- }
-
+ MachineFunctionProperties getClearedProperties() const override {
+ return MachineFunctionProperties().set(
+ MachineFunctionProperties::Property::IsSSA);
+ }
+
private:
bool runOnMachineFunction(MachineFunction &MF) override;
void allocateBasicBlock(MachineBasicBlock &MBB);
-
- void addRegClassDefCounts(std::vector<unsigned> &RegClassDefCounts,
- Register Reg) const;
-
+
+ void addRegClassDefCounts(std::vector<unsigned> &RegClassDefCounts,
+ Register Reg) const;
+
void allocateInstruction(MachineInstr &MI);
void handleDebugValue(MachineInstr &MI);
- void handleBundle(MachineInstr &MI);
+ void handleBundle(MachineInstr &MI);
- bool usePhysReg(MachineInstr &MI, MCPhysReg PhysReg);
- bool definePhysReg(MachineInstr &MI, MCPhysReg PhysReg);
- bool displacePhysReg(MachineInstr &MI, MCPhysReg PhysReg);
- void freePhysReg(MCPhysReg PhysReg);
+ bool usePhysReg(MachineInstr &MI, MCPhysReg PhysReg);
+ bool definePhysReg(MachineInstr &MI, MCPhysReg PhysReg);
+ bool displacePhysReg(MachineInstr &MI, MCPhysReg PhysReg);
+ void freePhysReg(MCPhysReg PhysReg);
unsigned calcSpillCost(MCPhysReg PhysReg) const;
@@ -238,38 +238,38 @@ namespace {
return LiveVirtRegs.find(Register::virtReg2Index(VirtReg));
}
- void assignVirtToPhysReg(MachineInstr &MI, LiveReg &, MCPhysReg PhysReg);
- void allocVirtReg(MachineInstr &MI, LiveReg &LR, Register Hint,
- bool LookAtPhysRegUses = false);
+ void assignVirtToPhysReg(MachineInstr &MI, LiveReg &, MCPhysReg PhysReg);
+ void allocVirtReg(MachineInstr &MI, LiveReg &LR, Register Hint,
+ bool LookAtPhysRegUses = false);
void allocVirtRegUndef(MachineOperand &MO);
- void assignDanglingDebugValues(MachineInstr &Def, Register VirtReg,
- MCPhysReg Reg);
- void defineLiveThroughVirtReg(MachineInstr &MI, unsigned OpNum,
- Register VirtReg);
- void defineVirtReg(MachineInstr &MI, unsigned OpNum, Register VirtReg,
- bool LookAtPhysRegUses = false);
- void useVirtReg(MachineInstr &MI, unsigned OpNum, Register VirtReg);
-
- MachineBasicBlock::iterator
- getMBBBeginInsertionPoint(MachineBasicBlock &MBB,
- SmallSet<Register, 2> &PrologLiveIns) const;
-
- void reloadAtBegin(MachineBasicBlock &MBB);
- void setPhysReg(MachineInstr &MI, MachineOperand &MO, MCPhysReg PhysReg);
-
+ void assignDanglingDebugValues(MachineInstr &Def, Register VirtReg,
+ MCPhysReg Reg);
+ void defineLiveThroughVirtReg(MachineInstr &MI, unsigned OpNum,
+ Register VirtReg);
+ void defineVirtReg(MachineInstr &MI, unsigned OpNum, Register VirtReg,
+ bool LookAtPhysRegUses = false);
+ void useVirtReg(MachineInstr &MI, unsigned OpNum, Register VirtReg);
+
+ MachineBasicBlock::iterator
+ getMBBBeginInsertionPoint(MachineBasicBlock &MBB,
+ SmallSet<Register, 2> &PrologLiveIns) const;
+
+ void reloadAtBegin(MachineBasicBlock &MBB);
+ void setPhysReg(MachineInstr &MI, MachineOperand &MO, MCPhysReg PhysReg);
+
Register traceCopies(Register VirtReg) const;
Register traceCopyChain(Register Reg) const;
int getStackSpaceFor(Register VirtReg);
void spill(MachineBasicBlock::iterator Before, Register VirtReg,
- MCPhysReg AssignedReg, bool Kill, bool LiveOut);
+ MCPhysReg AssignedReg, bool Kill, bool LiveOut);
void reload(MachineBasicBlock::iterator Before, Register VirtReg,
MCPhysReg PhysReg);
bool mayLiveOut(Register VirtReg);
bool mayLiveIn(Register VirtReg);
- void dumpState() const;
+ void dumpState() const;
};
} // end anonymous namespace
@@ -280,18 +280,18 @@ INITIALIZE_PASS(RegAllocFast, "regallocfast", "Fast Register Allocator", false,
false)
void RegAllocFast::setPhysRegState(MCPhysReg PhysReg, unsigned NewState) {
- for (MCRegUnitIterator UI(PhysReg, TRI); UI.isValid(); ++UI)
- RegUnitStates[*UI] = NewState;
+ for (MCRegUnitIterator UI(PhysReg, TRI); UI.isValid(); ++UI)
+ RegUnitStates[*UI] = NewState;
+}
+
+bool RegAllocFast::isPhysRegFree(MCPhysReg PhysReg) const {
+ for (MCRegUnitIterator UI(PhysReg, TRI); UI.isValid(); ++UI) {
+ if (RegUnitStates[*UI] != regFree)
+ return false;
+ }
+ return true;
}
-bool RegAllocFast::isPhysRegFree(MCPhysReg PhysReg) const {
- for (MCRegUnitIterator UI(PhysReg, TRI); UI.isValid(); ++UI) {
- if (RegUnitStates[*UI] != regFree)
- return false;
- }
- return true;
-}
-
/// This allocates space for the specified virtual register to be held on the
/// stack.
int RegAllocFast::getStackSpaceFor(Register VirtReg) {
@@ -312,20 +312,20 @@ int RegAllocFast::getStackSpaceFor(Register VirtReg) {
return FrameIdx;
}
-static bool dominates(MachineBasicBlock &MBB,
- MachineBasicBlock::const_iterator A,
- MachineBasicBlock::const_iterator B) {
- auto MBBEnd = MBB.end();
- if (B == MBBEnd)
- return true;
-
- MachineBasicBlock::const_iterator I = MBB.begin();
- for (; &*I != A && &*I != B; ++I)
- ;
-
- return &*I == A;
-}
-
+static bool dominates(MachineBasicBlock &MBB,
+ MachineBasicBlock::const_iterator A,
+ MachineBasicBlock::const_iterator B) {
+ auto MBBEnd = MBB.end();
+ if (B == MBBEnd)
+ return true;
+
+ MachineBasicBlock::const_iterator I = MBB.begin();
+ for (; &*I != A && &*I != B; ++I)
+ ;
+
+ return &*I == A;
+}
+
/// Returns false if \p VirtReg is known to not live out of the current block.
bool RegAllocFast::mayLiveOut(Register VirtReg) {
if (MayLiveAcrossBlocks.test(Register::virtReg2Index(VirtReg))) {
@@ -333,38 +333,38 @@ bool RegAllocFast::mayLiveOut(Register VirtReg) {
return !MBB->succ_empty();
}
- const MachineInstr *SelfLoopDef = nullptr;
-
- // If this block loops back to itself, it is necessary to check whether the
- // use comes after the def.
+ const MachineInstr *SelfLoopDef = nullptr;
+
+ // If this block loops back to itself, it is necessary to check whether the
+ // use comes after the def.
if (MBB->isSuccessor(MBB)) {
- SelfLoopDef = MRI->getUniqueVRegDef(VirtReg);
- if (!SelfLoopDef) {
- MayLiveAcrossBlocks.set(Register::virtReg2Index(VirtReg));
- return true;
- }
+ SelfLoopDef = MRI->getUniqueVRegDef(VirtReg);
+ if (!SelfLoopDef) {
+ MayLiveAcrossBlocks.set(Register::virtReg2Index(VirtReg));
+ return true;
+ }
}
// See if the first \p Limit uses of the register are all in the current
// block.
static const unsigned Limit = 8;
unsigned C = 0;
- for (const MachineInstr &UseInst : MRI->use_nodbg_instructions(VirtReg)) {
+ for (const MachineInstr &UseInst : MRI->use_nodbg_instructions(VirtReg)) {
if (UseInst.getParent() != MBB || ++C >= Limit) {
MayLiveAcrossBlocks.set(Register::virtReg2Index(VirtReg));
// Cannot be live-out if there are no successors.
return !MBB->succ_empty();
}
-
- if (SelfLoopDef) {
- // Try to handle some simple cases to avoid spilling and reloading every
- // value inside a self looping block.
- if (SelfLoopDef == &UseInst ||
- !dominates(*MBB, SelfLoopDef->getIterator(), UseInst.getIterator())) {
- MayLiveAcrossBlocks.set(Register::virtReg2Index(VirtReg));
- return true;
- }
- }
+
+ if (SelfLoopDef) {
+ // Try to handle some simple cases to avoid spilling and reloading every
+ // value inside a self looping block.
+ if (SelfLoopDef == &UseInst ||
+ !dominates(*MBB, SelfLoopDef->getIterator(), UseInst.getIterator())) {
+ MayLiveAcrossBlocks.set(Register::virtReg2Index(VirtReg));
+ return true;
+ }
+ }
}
return false;
@@ -391,7 +391,7 @@ bool RegAllocFast::mayLiveIn(Register VirtReg) {
/// Insert spill instruction for \p AssignedReg before \p Before. Update
/// DBG_VALUEs with \p VirtReg operands with the stack slot.
void RegAllocFast::spill(MachineBasicBlock::iterator Before, Register VirtReg,
- MCPhysReg AssignedReg, bool Kill, bool LiveOut) {
+ MCPhysReg AssignedReg, bool Kill, bool LiveOut) {
LLVM_DEBUG(dbgs() << "Spilling " << printReg(VirtReg, TRI)
<< " in " << printReg(AssignedReg, TRI));
int FI = getStackSpaceFor(VirtReg);
@@ -401,32 +401,32 @@ void RegAllocFast::spill(MachineBasicBlock::iterator Before, Register VirtReg,
TII->storeRegToStackSlot(*MBB, Before, AssignedReg, Kill, FI, &RC, TRI);
++NumStores;
- MachineBasicBlock::iterator FirstTerm = MBB->getFirstTerminator();
-
- // When we spill a virtual register, we will have spill instructions behind
- // every definition of it, meaning we can switch all the DBG_VALUEs over
- // to just reference the stack slot.
+ MachineBasicBlock::iterator FirstTerm = MBB->getFirstTerminator();
+
+ // When we spill a virtual register, we will have spill instructions behind
+ // every definition of it, meaning we can switch all the DBG_VALUEs over
+ // to just reference the stack slot.
SmallVectorImpl<MachineInstr *> &LRIDbgValues = LiveDbgValueMap[VirtReg];
for (MachineInstr *DBG : LRIDbgValues) {
MachineInstr *NewDV = buildDbgValueForSpill(*MBB, Before, *DBG, FI);
assert(NewDV->getParent() == MBB && "dangling parent pointer");
(void)NewDV;
LLVM_DEBUG(dbgs() << "Inserting debug info due to spill:\n" << *NewDV);
-
- if (LiveOut) {
- // We need to insert a DBG_VALUE at the end of the block if the spill slot
- // is live out, but there is another use of the value after the
- // spill. This will allow LiveDebugValues to see the correct live out
- // value to propagate to the successors.
- MachineInstr *ClonedDV = MBB->getParent()->CloneMachineInstr(NewDV);
- MBB->insert(FirstTerm, ClonedDV);
- LLVM_DEBUG(dbgs() << "Cloning debug info due to live out spill\n");
- }
-
- // Rewrite unassigned dbg_values to use the stack slot.
- MachineOperand &MO = DBG->getOperand(0);
- if (MO.isReg() && MO.getReg() == 0)
- updateDbgValueForSpill(*DBG, FI);
+
+ if (LiveOut) {
+ // We need to insert a DBG_VALUE at the end of the block if the spill slot
+ // is live out, but there is another use of the value after the
+ // spill. This will allow LiveDebugValues to see the correct live out
+ // value to propagate to the successors.
+ MachineInstr *ClonedDV = MBB->getParent()->CloneMachineInstr(NewDV);
+ MBB->insert(FirstTerm, ClonedDV);
+ LLVM_DEBUG(dbgs() << "Cloning debug info due to live out spill\n");
+ }
+
+ // Rewrite unassigned dbg_values to use the stack slot.
+ MachineOperand &MO = DBG->getOperand(0);
+ if (MO.isReg() && MO.getReg() == 0)
+ updateDbgValueForSpill(*DBG, FI);
}
// Now this register is spilled there is should not be any DBG_VALUE
// pointing to this register because they are all pointing to spilled value
@@ -445,75 +445,75 @@ void RegAllocFast::reload(MachineBasicBlock::iterator Before, Register VirtReg,
++NumLoads;
}
-/// Get basic block begin insertion point.
-/// This is not just MBB.begin() because surprisingly we have EH_LABEL
-/// instructions marking the begin of a basic block. This means we must insert
-/// new instructions after such labels...
-MachineBasicBlock::iterator
-RegAllocFast::getMBBBeginInsertionPoint(
- MachineBasicBlock &MBB, SmallSet<Register, 2> &PrologLiveIns) const {
- MachineBasicBlock::iterator I = MBB.begin();
- while (I != MBB.end()) {
- if (I->isLabel()) {
- ++I;
- continue;
- }
-
- // Most reloads should be inserted after prolog instructions.
- if (!TII->isBasicBlockPrologue(*I))
- break;
-
- // However if a prolog instruction reads a register that needs to be
- // reloaded, the reload should be inserted before the prolog.
- for (MachineOperand &MO : I->operands()) {
- if (MO.isReg())
- PrologLiveIns.insert(MO.getReg());
- }
-
- ++I;
+/// Get basic block begin insertion point.
+/// This is not just MBB.begin() because surprisingly we have EH_LABEL
+/// instructions marking the begin of a basic block. This means we must insert
+/// new instructions after such labels...
+MachineBasicBlock::iterator
+RegAllocFast::getMBBBeginInsertionPoint(
+ MachineBasicBlock &MBB, SmallSet<Register, 2> &PrologLiveIns) const {
+ MachineBasicBlock::iterator I = MBB.begin();
+ while (I != MBB.end()) {
+ if (I->isLabel()) {
+ ++I;
+ continue;
+ }
+
+ // Most reloads should be inserted after prolog instructions.
+ if (!TII->isBasicBlockPrologue(*I))
+ break;
+
+ // However if a prolog instruction reads a register that needs to be
+ // reloaded, the reload should be inserted before the prolog.
+ for (MachineOperand &MO : I->operands()) {
+ if (MO.isReg())
+ PrologLiveIns.insert(MO.getReg());
+ }
+
+ ++I;
}
- return I;
+ return I;
}
-/// Reload all currently assigned virtual registers.
-void RegAllocFast::reloadAtBegin(MachineBasicBlock &MBB) {
- if (LiveVirtRegs.empty())
- return;
+/// Reload all currently assigned virtual registers.
+void RegAllocFast::reloadAtBegin(MachineBasicBlock &MBB) {
+ if (LiveVirtRegs.empty())
+ return;
- for (MachineBasicBlock::RegisterMaskPair P : MBB.liveins()) {
- MCPhysReg Reg = P.PhysReg;
- // Set state to live-in. This possibly overrides mappings to virtual
- // registers but we don't care anymore at this point.
- setPhysRegState(Reg, regLiveIn);
- }
+ for (MachineBasicBlock::RegisterMaskPair P : MBB.liveins()) {
+ MCPhysReg Reg = P.PhysReg;
+ // Set state to live-in. This possibly overrides mappings to virtual
+ // registers but we don't care anymore at this point.
+ setPhysRegState(Reg, regLiveIn);
+ }
- SmallSet<Register, 2> PrologLiveIns;
+ SmallSet<Register, 2> PrologLiveIns;
// The LiveRegMap is keyed by an unsigned (the virtreg number), so the order
// of spilling here is deterministic, if arbitrary.
- MachineBasicBlock::iterator InsertBefore
- = getMBBBeginInsertionPoint(MBB, PrologLiveIns);
- for (const LiveReg &LR : LiveVirtRegs) {
- MCPhysReg PhysReg = LR.PhysReg;
- if (PhysReg == 0)
+ MachineBasicBlock::iterator InsertBefore
+ = getMBBBeginInsertionPoint(MBB, PrologLiveIns);
+ for (const LiveReg &LR : LiveVirtRegs) {
+ MCPhysReg PhysReg = LR.PhysReg;
+ if (PhysReg == 0)
continue;
-
- MCRegister FirstUnit = *MCRegUnitIterator(PhysReg, TRI);
- if (RegUnitStates[FirstUnit] == regLiveIn)
+
+ MCRegister FirstUnit = *MCRegUnitIterator(PhysReg, TRI);
+ if (RegUnitStates[FirstUnit] == regLiveIn)
continue;
-
- assert((&MBB != &MBB.getParent()->front() || IgnoreMissingDefs) &&
- "no reload in start block. Missing vreg def?");
-
- if (PrologLiveIns.count(PhysReg)) {
- // FIXME: Theoretically this should use an insert point skipping labels
- // but I'm not sure how labels should interact with prolog instruction
- // that need reloads.
- reload(MBB.begin(), LR.VirtReg, PhysReg);
- } else
- reload(InsertBefore, LR.VirtReg, PhysReg);
+
+ assert((&MBB != &MBB.getParent()->front() || IgnoreMissingDefs) &&
+ "no reload in start block. Missing vreg def?");
+
+ if (PrologLiveIns.count(PhysReg)) {
+ // FIXME: Theoretically this should use an insert point skipping labels
+ // but I'm not sure how labels should interact with prolog instruction
+ // that need reloads.
+ reload(MBB.begin(), LR.VirtReg, PhysReg);
+ } else
+ reload(InsertBefore, LR.VirtReg, PhysReg);
}
LiveVirtRegs.clear();
}
@@ -521,73 +521,73 @@ void RegAllocFast::reloadAtBegin(MachineBasicBlock &MBB) {
/// Handle the direct use of a physical register. Check that the register is
/// not used by a virtreg. Kill the physreg, marking it free. This may add
/// implicit kills to MO->getParent() and invalidate MO.
-bool RegAllocFast::usePhysReg(MachineInstr &MI, MCPhysReg Reg) {
- assert(Register::isPhysicalRegister(Reg) && "expected physreg");
- bool displacedAny = displacePhysReg(MI, Reg);
- setPhysRegState(Reg, regPreAssigned);
- markRegUsedInInstr(Reg);
- return displacedAny;
-}
-
-bool RegAllocFast::definePhysReg(MachineInstr &MI, MCPhysReg Reg) {
- bool displacedAny = displacePhysReg(MI, Reg);
- setPhysRegState(Reg, regPreAssigned);
- return displacedAny;
-}
-
-/// Mark PhysReg as reserved or free after spilling any virtregs. This is very
-/// similar to defineVirtReg except the physreg is reserved instead of
-/// allocated.
-bool RegAllocFast::displacePhysReg(MachineInstr &MI, MCPhysReg PhysReg) {
- bool displacedAny = false;
-
- for (MCRegUnitIterator UI(PhysReg, TRI); UI.isValid(); ++UI) {
- unsigned Unit = *UI;
- switch (unsigned VirtReg = RegUnitStates[Unit]) {
- default: {
- LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg);
- assert(LRI != LiveVirtRegs.end() && "datastructures in sync");
- MachineBasicBlock::iterator ReloadBefore =
- std::next((MachineBasicBlock::iterator)MI.getIterator());
- reload(ReloadBefore, VirtReg, LRI->PhysReg);
-
- setPhysRegState(LRI->PhysReg, regFree);
- LRI->PhysReg = 0;
- LRI->Reloaded = true;
- displacedAny = true;
+bool RegAllocFast::usePhysReg(MachineInstr &MI, MCPhysReg Reg) {
+ assert(Register::isPhysicalRegister(Reg) && "expected physreg");
+ bool displacedAny = displacePhysReg(MI, Reg);
+ setPhysRegState(Reg, regPreAssigned);
+ markRegUsedInInstr(Reg);
+ return displacedAny;
+}
+
+bool RegAllocFast::definePhysReg(MachineInstr &MI, MCPhysReg Reg) {
+ bool displacedAny = displacePhysReg(MI, Reg);
+ setPhysRegState(Reg, regPreAssigned);
+ return displacedAny;
+}
+
+/// Mark PhysReg as reserved or free after spilling any virtregs. This is very
+/// similar to defineVirtReg except the physreg is reserved instead of
+/// allocated.
+bool RegAllocFast::displacePhysReg(MachineInstr &MI, MCPhysReg PhysReg) {
+ bool displacedAny = false;
+
+ for (MCRegUnitIterator UI(PhysReg, TRI); UI.isValid(); ++UI) {
+ unsigned Unit = *UI;
+ switch (unsigned VirtReg = RegUnitStates[Unit]) {
+ default: {
+ LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg);
+ assert(LRI != LiveVirtRegs.end() && "datastructures in sync");
+ MachineBasicBlock::iterator ReloadBefore =
+ std::next((MachineBasicBlock::iterator)MI.getIterator());
+ reload(ReloadBefore, VirtReg, LRI->PhysReg);
+
+ setPhysRegState(LRI->PhysReg, regFree);
+ LRI->PhysReg = 0;
+ LRI->Reloaded = true;
+ displacedAny = true;
+ break;
+ }
+ case regPreAssigned:
+ RegUnitStates[Unit] = regFree;
+ displacedAny = true;
break;
- }
- case regPreAssigned:
- RegUnitStates[Unit] = regFree;
- displacedAny = true;
- break;
case regFree:
break;
}
}
- return displacedAny;
+ return displacedAny;
}
-void RegAllocFast::freePhysReg(MCPhysReg PhysReg) {
- LLVM_DEBUG(dbgs() << "Freeing " << printReg(PhysReg, TRI) << ':');
-
- MCRegister FirstUnit = *MCRegUnitIterator(PhysReg, TRI);
- switch (unsigned VirtReg = RegUnitStates[FirstUnit]) {
+void RegAllocFast::freePhysReg(MCPhysReg PhysReg) {
+ LLVM_DEBUG(dbgs() << "Freeing " << printReg(PhysReg, TRI) << ':');
+
+ MCRegister FirstUnit = *MCRegUnitIterator(PhysReg, TRI);
+ switch (unsigned VirtReg = RegUnitStates[FirstUnit]) {
case regFree:
- LLVM_DEBUG(dbgs() << '\n');
+ LLVM_DEBUG(dbgs() << '\n');
return;
- case regPreAssigned:
- LLVM_DEBUG(dbgs() << '\n');
- setPhysRegState(PhysReg, regFree);
- return;
- default: {
- LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg);
- assert(LRI != LiveVirtRegs.end());
- LLVM_DEBUG(dbgs() << ' ' << printReg(LRI->VirtReg, TRI) << '\n');
- setPhysRegState(LRI->PhysReg, regFree);
- LRI->PhysReg = 0;
+ case regPreAssigned:
+ LLVM_DEBUG(dbgs() << '\n');
+ setPhysRegState(PhysReg, regFree);
+ return;
+ default: {
+ LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg);
+ assert(LRI != LiveVirtRegs.end());
+ LLVM_DEBUG(dbgs() << ' ' << printReg(LRI->VirtReg, TRI) << '\n');
+ setPhysRegState(LRI->PhysReg, regFree);
+ LRI->PhysReg = 0;
}
- return;
+ return;
}
}
@@ -596,61 +596,61 @@ void RegAllocFast::freePhysReg(MCPhysReg PhysReg) {
/// disabled - it can be allocated directly.
/// \returns spillImpossible when PhysReg or an alias can't be spilled.
unsigned RegAllocFast::calcSpillCost(MCPhysReg PhysReg) const {
- for (MCRegUnitIterator UI(PhysReg, TRI); UI.isValid(); ++UI) {
- switch (unsigned VirtReg = RegUnitStates[*UI]) {
+ for (MCRegUnitIterator UI(PhysReg, TRI); UI.isValid(); ++UI) {
+ switch (unsigned VirtReg = RegUnitStates[*UI]) {
case regFree:
break;
- case regPreAssigned:
- LLVM_DEBUG(dbgs() << "Cannot spill pre-assigned "
- << printReg(PhysReg, TRI) << '\n');
+ case regPreAssigned:
+ LLVM_DEBUG(dbgs() << "Cannot spill pre-assigned "
+ << printReg(PhysReg, TRI) << '\n');
return spillImpossible;
default: {
- bool SureSpill = StackSlotForVirtReg[VirtReg] != -1 ||
- findLiveVirtReg(VirtReg)->LiveOut;
- return SureSpill ? spillClean : spillDirty;
+ bool SureSpill = StackSlotForVirtReg[VirtReg] != -1 ||
+ findLiveVirtReg(VirtReg)->LiveOut;
+ return SureSpill ? spillClean : spillDirty;
+ }
}
+ }
+ return 0;
+}
+
+void RegAllocFast::assignDanglingDebugValues(MachineInstr &Definition,
+ Register VirtReg, MCPhysReg Reg) {
+ auto UDBGValIter = DanglingDbgValues.find(VirtReg);
+ if (UDBGValIter == DanglingDbgValues.end())
+ return;
+
+ SmallVectorImpl<MachineInstr*> &Dangling = UDBGValIter->second;
+ for (MachineInstr *DbgValue : Dangling) {
+ assert(DbgValue->isDebugValue());
+ MachineOperand &MO = DbgValue->getOperand(0);
+ if (!MO.isReg())
+ continue;
+
+ // Test whether the physreg survives from the definition to the DBG_VALUE.
+ MCPhysReg SetToReg = Reg;
+ unsigned Limit = 20;
+ for (MachineBasicBlock::iterator I = std::next(Definition.getIterator()),
+ E = DbgValue->getIterator(); I != E; ++I) {
+ if (I->modifiesRegister(Reg, TRI) || --Limit == 0) {
+ LLVM_DEBUG(dbgs() << "Register did not survive for " << *DbgValue
+ << '\n');
+ SetToReg = 0;
+ break;
+ }
}
+ MO.setReg(SetToReg);
+ if (SetToReg != 0)
+ MO.setIsRenamable();
}
- return 0;
+ Dangling.clear();
}
-void RegAllocFast::assignDanglingDebugValues(MachineInstr &Definition,
- Register VirtReg, MCPhysReg Reg) {
- auto UDBGValIter = DanglingDbgValues.find(VirtReg);
- if (UDBGValIter == DanglingDbgValues.end())
- return;
-
- SmallVectorImpl<MachineInstr*> &Dangling = UDBGValIter->second;
- for (MachineInstr *DbgValue : Dangling) {
- assert(DbgValue->isDebugValue());
- MachineOperand &MO = DbgValue->getOperand(0);
- if (!MO.isReg())
- continue;
-
- // Test whether the physreg survives from the definition to the DBG_VALUE.
- MCPhysReg SetToReg = Reg;
- unsigned Limit = 20;
- for (MachineBasicBlock::iterator I = std::next(Definition.getIterator()),
- E = DbgValue->getIterator(); I != E; ++I) {
- if (I->modifiesRegister(Reg, TRI) || --Limit == 0) {
- LLVM_DEBUG(dbgs() << "Register did not survive for " << *DbgValue
- << '\n');
- SetToReg = 0;
- break;
- }
- }
- MO.setReg(SetToReg);
- if (SetToReg != 0)
- MO.setIsRenamable();
- }
- Dangling.clear();
-}
-
/// This method updates local state so that we know that PhysReg is the
/// proper container for VirtReg now. The physical register must not be used
/// for anything else when this is called.
-void RegAllocFast::assignVirtToPhysReg(MachineInstr &AtMI, LiveReg &LR,
- MCPhysReg PhysReg) {
+void RegAllocFast::assignVirtToPhysReg(MachineInstr &AtMI, LiveReg &LR,
+ MCPhysReg PhysReg) {
Register VirtReg = LR.VirtReg;
LLVM_DEBUG(dbgs() << "Assigning " << printReg(VirtReg, TRI) << " to "
<< printReg(PhysReg, TRI) << '\n');
@@ -658,8 +658,8 @@ void RegAllocFast::assignVirtToPhysReg(MachineInstr &AtMI, LiveReg &LR,
assert(PhysReg != 0 && "Trying to assign no register");
LR.PhysReg = PhysReg;
setPhysRegState(PhysReg, VirtReg);
-
- assignDanglingDebugValues(AtMI, VirtReg, PhysReg);
+
+ assignDanglingDebugValues(AtMI, VirtReg, PhysReg);
}
static bool isCoalescable(const MachineInstr &MI) {
@@ -703,10 +703,10 @@ Register RegAllocFast::traceCopies(Register VirtReg) const {
}
/// Allocates a physical register for VirtReg.
-void RegAllocFast::allocVirtReg(MachineInstr &MI, LiveReg &LR,
- Register Hint0, bool LookAtPhysRegUses) {
+void RegAllocFast::allocVirtReg(MachineInstr &MI, LiveReg &LR,
+ Register Hint0, bool LookAtPhysRegUses) {
const Register VirtReg = LR.VirtReg;
- assert(LR.PhysReg == 0);
+ assert(LR.PhysReg == 0);
const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg);
LLVM_DEBUG(dbgs() << "Search register for " << printReg(VirtReg)
@@ -714,36 +714,36 @@ void RegAllocFast::allocVirtReg(MachineInstr &MI, LiveReg &LR,
<< " with hint " << printReg(Hint0, TRI) << '\n');
// Take hint when possible.
- if (Hint0.isPhysical() && MRI->isAllocatable(Hint0) && RC.contains(Hint0) &&
- !isRegUsedInInstr(Hint0, LookAtPhysRegUses)) {
- // Take hint if the register is currently free.
- if (isPhysRegFree(Hint0)) {
+ if (Hint0.isPhysical() && MRI->isAllocatable(Hint0) && RC.contains(Hint0) &&
+ !isRegUsedInInstr(Hint0, LookAtPhysRegUses)) {
+ // Take hint if the register is currently free.
+ if (isPhysRegFree(Hint0)) {
LLVM_DEBUG(dbgs() << "\tPreferred Register 1: " << printReg(Hint0, TRI)
<< '\n');
- assignVirtToPhysReg(MI, LR, Hint0);
+ assignVirtToPhysReg(MI, LR, Hint0);
return;
} else {
- LLVM_DEBUG(dbgs() << "\tPreferred Register 0: " << printReg(Hint0, TRI)
- << " occupied\n");
+ LLVM_DEBUG(dbgs() << "\tPreferred Register 0: " << printReg(Hint0, TRI)
+ << " occupied\n");
}
} else {
Hint0 = Register();
}
-
+
// Try other hint.
Register Hint1 = traceCopies(VirtReg);
- if (Hint1.isPhysical() && MRI->isAllocatable(Hint1) && RC.contains(Hint1) &&
- !isRegUsedInInstr(Hint1, LookAtPhysRegUses)) {
- // Take hint if the register is currently free.
- if (isPhysRegFree(Hint1)) {
+ if (Hint1.isPhysical() && MRI->isAllocatable(Hint1) && RC.contains(Hint1) &&
+ !isRegUsedInInstr(Hint1, LookAtPhysRegUses)) {
+ // Take hint if the register is currently free.
+ if (isPhysRegFree(Hint1)) {
LLVM_DEBUG(dbgs() << "\tPreferred Register 0: " << printReg(Hint1, TRI)
- << '\n');
- assignVirtToPhysReg(MI, LR, Hint1);
+ << '\n');
+ assignVirtToPhysReg(MI, LR, Hint1);
return;
} else {
- LLVM_DEBUG(dbgs() << "\tPreferred Register 1: " << printReg(Hint1, TRI)
- << " occupied\n");
+ LLVM_DEBUG(dbgs() << "\tPreferred Register 1: " << printReg(Hint1, TRI)
+ << " occupied\n");
}
} else {
Hint1 = Register();
@@ -754,20 +754,20 @@ void RegAllocFast::allocVirtReg(MachineInstr &MI, LiveReg &LR,
ArrayRef<MCPhysReg> AllocationOrder = RegClassInfo.getOrder(&RC);
for (MCPhysReg PhysReg : AllocationOrder) {
LLVM_DEBUG(dbgs() << "\tRegister: " << printReg(PhysReg, TRI) << ' ');
- if (isRegUsedInInstr(PhysReg, LookAtPhysRegUses)) {
- LLVM_DEBUG(dbgs() << "already used in instr.\n");
- continue;
- }
-
+ if (isRegUsedInInstr(PhysReg, LookAtPhysRegUses)) {
+ LLVM_DEBUG(dbgs() << "already used in instr.\n");
+ continue;
+ }
+
unsigned Cost = calcSpillCost(PhysReg);
LLVM_DEBUG(dbgs() << "Cost: " << Cost << " BestCost: " << BestCost << '\n');
// Immediate take a register with cost 0.
if (Cost == 0) {
- assignVirtToPhysReg(MI, LR, PhysReg);
+ assignVirtToPhysReg(MI, LR, PhysReg);
return;
}
- if (PhysReg == Hint0 || PhysReg == Hint1)
+ if (PhysReg == Hint0 || PhysReg == Hint1)
Cost -= spillPrefBonus;
if (Cost < BestCost) {
@@ -783,14 +783,14 @@ void RegAllocFast::allocVirtReg(MachineInstr &MI, LiveReg &LR,
MI.emitError("inline assembly requires more registers than available");
else
MI.emitError("ran out of registers during register allocation");
-
- LR.Error = true;
- LR.PhysReg = 0;
+
+ LR.Error = true;
+ LR.PhysReg = 0;
return;
}
- displacePhysReg(MI, BestReg);
- assignVirtToPhysReg(MI, LR, BestReg);
+ displacePhysReg(MI, BestReg);
+ assignVirtToPhysReg(MI, LR, BestReg);
}
void RegAllocFast::allocVirtRegUndef(MachineOperand &MO) {
@@ -818,491 +818,491 @@ void RegAllocFast::allocVirtRegUndef(MachineOperand &MO) {
MO.setIsRenamable(true);
}
-/// Variation of defineVirtReg() with special handling for livethrough regs
-/// (tied or earlyclobber) that may interfere with preassigned uses.
-void RegAllocFast::defineLiveThroughVirtReg(MachineInstr &MI, unsigned OpNum,
- Register VirtReg) {
- LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg);
- if (LRI != LiveVirtRegs.end()) {
- MCPhysReg PrevReg = LRI->PhysReg;
- if (PrevReg != 0 && isRegUsedInInstr(PrevReg, true)) {
- LLVM_DEBUG(dbgs() << "Need new assignment for " << printReg(PrevReg, TRI)
- << " (tied/earlyclobber resolution)\n");
- freePhysReg(PrevReg);
- LRI->PhysReg = 0;
- allocVirtReg(MI, *LRI, 0, true);
- MachineBasicBlock::iterator InsertBefore =
- std::next((MachineBasicBlock::iterator)MI.getIterator());
- LLVM_DEBUG(dbgs() << "Copy " << printReg(LRI->PhysReg, TRI) << " to "
- << printReg(PrevReg, TRI) << '\n');
- BuildMI(*MBB, InsertBefore, MI.getDebugLoc(),
- TII->get(TargetOpcode::COPY), PrevReg)
- .addReg(LRI->PhysReg, llvm::RegState::Kill);
- }
- MachineOperand &MO = MI.getOperand(OpNum);
- if (MO.getSubReg() && !MO.isUndef()) {
- LRI->LastUse = &MI;
- }
- }
- return defineVirtReg(MI, OpNum, VirtReg, true);
-}
-
-/// Allocates a register for VirtReg definition. Typically the register is
-/// already assigned from a use of the virtreg, however we still need to
-/// perform an allocation if:
-/// - It is a dead definition without any uses.
-/// - The value is live out and all uses are in different basic blocks.
-void RegAllocFast::defineVirtReg(MachineInstr &MI, unsigned OpNum,
- Register VirtReg, bool LookAtPhysRegUses) {
- assert(VirtReg.isVirtual() && "Not a virtual register");
- MachineOperand &MO = MI.getOperand(OpNum);
+/// Variation of defineVirtReg() with special handling for livethrough regs
+/// (tied or earlyclobber) that may interfere with preassigned uses.
+void RegAllocFast::defineLiveThroughVirtReg(MachineInstr &MI, unsigned OpNum,
+ Register VirtReg) {
+ LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg);
+ if (LRI != LiveVirtRegs.end()) {
+ MCPhysReg PrevReg = LRI->PhysReg;
+ if (PrevReg != 0 && isRegUsedInInstr(PrevReg, true)) {
+ LLVM_DEBUG(dbgs() << "Need new assignment for " << printReg(PrevReg, TRI)
+ << " (tied/earlyclobber resolution)\n");
+ freePhysReg(PrevReg);
+ LRI->PhysReg = 0;
+ allocVirtReg(MI, *LRI, 0, true);
+ MachineBasicBlock::iterator InsertBefore =
+ std::next((MachineBasicBlock::iterator)MI.getIterator());
+ LLVM_DEBUG(dbgs() << "Copy " << printReg(LRI->PhysReg, TRI) << " to "
+ << printReg(PrevReg, TRI) << '\n');
+ BuildMI(*MBB, InsertBefore, MI.getDebugLoc(),
+ TII->get(TargetOpcode::COPY), PrevReg)
+ .addReg(LRI->PhysReg, llvm::RegState::Kill);
+ }
+ MachineOperand &MO = MI.getOperand(OpNum);
+ if (MO.getSubReg() && !MO.isUndef()) {
+ LRI->LastUse = &MI;
+ }
+ }
+ return defineVirtReg(MI, OpNum, VirtReg, true);
+}
+
+/// Allocates a register for VirtReg definition. Typically the register is
+/// already assigned from a use of the virtreg, however we still need to
+/// perform an allocation if:
+/// - It is a dead definition without any uses.
+/// - The value is live out and all uses are in different basic blocks.
+void RegAllocFast::defineVirtReg(MachineInstr &MI, unsigned OpNum,
+ Register VirtReg, bool LookAtPhysRegUses) {
+ assert(VirtReg.isVirtual() && "Not a virtual register");
+ MachineOperand &MO = MI.getOperand(OpNum);
LiveRegMap::iterator LRI;
bool New;
std::tie(LRI, New) = LiveVirtRegs.insert(LiveReg(VirtReg));
- if (New) {
- if (!MO.isDead()) {
- if (mayLiveOut(VirtReg)) {
- LRI->LiveOut = true;
- } else {
- // It is a dead def without the dead flag; add the flag now.
- MO.setIsDead(true);
- }
+ if (New) {
+ if (!MO.isDead()) {
+ if (mayLiveOut(VirtReg)) {
+ LRI->LiveOut = true;
+ } else {
+ // It is a dead def without the dead flag; add the flag now.
+ MO.setIsDead(true);
+ }
}
}
- if (LRI->PhysReg == 0)
- allocVirtReg(MI, *LRI, 0, LookAtPhysRegUses);
- else {
- assert(!isRegUsedInInstr(LRI->PhysReg, LookAtPhysRegUses) &&
- "TODO: preassign mismatch");
- LLVM_DEBUG(dbgs() << "In def of " << printReg(VirtReg, TRI)
- << " use existing assignment to "
- << printReg(LRI->PhysReg, TRI) << '\n');
- }
-
- MCPhysReg PhysReg = LRI->PhysReg;
- assert(PhysReg != 0 && "Register not assigned");
- if (LRI->Reloaded || LRI->LiveOut) {
- if (!MI.isImplicitDef()) {
- MachineBasicBlock::iterator SpillBefore =
- std::next((MachineBasicBlock::iterator)MI.getIterator());
- LLVM_DEBUG(dbgs() << "Spill Reason: LO: " << LRI->LiveOut << " RL: "
- << LRI->Reloaded << '\n');
- bool Kill = LRI->LastUse == nullptr;
- spill(SpillBefore, VirtReg, PhysReg, Kill, LRI->LiveOut);
- LRI->LastUse = nullptr;
- }
- LRI->LiveOut = false;
- LRI->Reloaded = false;
- }
- if (MI.getOpcode() == TargetOpcode::BUNDLE) {
- BundleVirtRegsMap[VirtReg] = PhysReg;
- }
- markRegUsedInInstr(PhysReg);
- setPhysReg(MI, MO, PhysReg);
+ if (LRI->PhysReg == 0)
+ allocVirtReg(MI, *LRI, 0, LookAtPhysRegUses);
+ else {
+ assert(!isRegUsedInInstr(LRI->PhysReg, LookAtPhysRegUses) &&
+ "TODO: preassign mismatch");
+ LLVM_DEBUG(dbgs() << "In def of " << printReg(VirtReg, TRI)
+ << " use existing assignment to "
+ << printReg(LRI->PhysReg, TRI) << '\n');
+ }
+
+ MCPhysReg PhysReg = LRI->PhysReg;
+ assert(PhysReg != 0 && "Register not assigned");
+ if (LRI->Reloaded || LRI->LiveOut) {
+ if (!MI.isImplicitDef()) {
+ MachineBasicBlock::iterator SpillBefore =
+ std::next((MachineBasicBlock::iterator)MI.getIterator());
+ LLVM_DEBUG(dbgs() << "Spill Reason: LO: " << LRI->LiveOut << " RL: "
+ << LRI->Reloaded << '\n');
+ bool Kill = LRI->LastUse == nullptr;
+ spill(SpillBefore, VirtReg, PhysReg, Kill, LRI->LiveOut);
+ LRI->LastUse = nullptr;
+ }
+ LRI->LiveOut = false;
+ LRI->Reloaded = false;
+ }
+ if (MI.getOpcode() == TargetOpcode::BUNDLE) {
+ BundleVirtRegsMap[VirtReg] = PhysReg;
+ }
+ markRegUsedInInstr(PhysReg);
+ setPhysReg(MI, MO, PhysReg);
}
-/// Allocates a register for a VirtReg use.
-void RegAllocFast::useVirtReg(MachineInstr &MI, unsigned OpNum,
- Register VirtReg) {
- assert(VirtReg.isVirtual() && "Not a virtual register");
- MachineOperand &MO = MI.getOperand(OpNum);
+/// Allocates a register for a VirtReg use.
+void RegAllocFast::useVirtReg(MachineInstr &MI, unsigned OpNum,
+ Register VirtReg) {
+ assert(VirtReg.isVirtual() && "Not a virtual register");
+ MachineOperand &MO = MI.getOperand(OpNum);
LiveRegMap::iterator LRI;
bool New;
std::tie(LRI, New) = LiveVirtRegs.insert(LiveReg(VirtReg));
- if (New) {
- MachineOperand &MO = MI.getOperand(OpNum);
- if (!MO.isKill()) {
- if (mayLiveOut(VirtReg)) {
- LRI->LiveOut = true;
- } else {
- // It is a last (killing) use without the kill flag; add the flag now.
- MO.setIsKill(true);
- }
+ if (New) {
+ MachineOperand &MO = MI.getOperand(OpNum);
+ if (!MO.isKill()) {
+ if (mayLiveOut(VirtReg)) {
+ LRI->LiveOut = true;
+ } else {
+ // It is a last (killing) use without the kill flag; add the flag now.
+ MO.setIsKill(true);
+ }
+ }
+ } else {
+ assert((!MO.isKill() || LRI->LastUse == &MI) && "Invalid kill flag");
+ }
+
+ // If necessary allocate a register.
+ if (LRI->PhysReg == 0) {
+ assert(!MO.isTied() && "tied op should be allocated");
+ Register Hint;
+ if (MI.isCopy() && MI.getOperand(1).getSubReg() == 0) {
+ Hint = MI.getOperand(0).getReg();
+ assert(Hint.isPhysical() &&
+ "Copy destination should already be assigned");
+ }
+ allocVirtReg(MI, *LRI, Hint, false);
+ if (LRI->Error) {
+ const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg);
+ ArrayRef<MCPhysReg> AllocationOrder = RegClassInfo.getOrder(&RC);
+ setPhysReg(MI, MO, *AllocationOrder.begin());
+ return;
}
- } else {
- assert((!MO.isKill() || LRI->LastUse == &MI) && "Invalid kill flag");
}
-
- // If necessary allocate a register.
- if (LRI->PhysReg == 0) {
- assert(!MO.isTied() && "tied op should be allocated");
- Register Hint;
- if (MI.isCopy() && MI.getOperand(1).getSubReg() == 0) {
- Hint = MI.getOperand(0).getReg();
- assert(Hint.isPhysical() &&
- "Copy destination should already be assigned");
- }
- allocVirtReg(MI, *LRI, Hint, false);
- if (LRI->Error) {
- const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg);
- ArrayRef<MCPhysReg> AllocationOrder = RegClassInfo.getOrder(&RC);
- setPhysReg(MI, MO, *AllocationOrder.begin());
- return;
- }
- }
-
+
LRI->LastUse = &MI;
-
- if (MI.getOpcode() == TargetOpcode::BUNDLE) {
- BundleVirtRegsMap[VirtReg] = LRI->PhysReg;
- }
+
+ if (MI.getOpcode() == TargetOpcode::BUNDLE) {
+ BundleVirtRegsMap[VirtReg] = LRI->PhysReg;
+ }
markRegUsedInInstr(LRI->PhysReg);
- setPhysReg(MI, MO, LRI->PhysReg);
+ setPhysReg(MI, MO, LRI->PhysReg);
}
/// Changes operand OpNum in MI the refer the PhysReg, considering subregs. This
/// may invalidate any operand pointers. Return true if the operand kills its
/// register.
-void RegAllocFast::setPhysReg(MachineInstr &MI, MachineOperand &MO,
+void RegAllocFast::setPhysReg(MachineInstr &MI, MachineOperand &MO,
MCPhysReg PhysReg) {
if (!MO.getSubReg()) {
MO.setReg(PhysReg);
MO.setIsRenamable(true);
- return;
+ return;
}
// Handle subregister index.
- MO.setReg(PhysReg ? TRI->getSubReg(PhysReg, MO.getSubReg()) : MCRegister());
+ MO.setReg(PhysReg ? TRI->getSubReg(PhysReg, MO.getSubReg()) : MCRegister());
MO.setIsRenamable(true);
- // Note: We leave the subreg number around a little longer in case of defs.
- // This is so that the register freeing logic in allocateInstruction can still
- // recognize this as subregister defs. The code there will clear the number.
- if (!MO.isDef())
- MO.setSubReg(0);
+ // Note: We leave the subreg number around a little longer in case of defs.
+ // This is so that the register freeing logic in allocateInstruction can still
+ // recognize this as subregister defs. The code there will clear the number.
+ if (!MO.isDef())
+ MO.setSubReg(0);
// A kill flag implies killing the full register. Add corresponding super
// register kill.
if (MO.isKill()) {
MI.addRegisterKilled(PhysReg, TRI, true);
- return;
+ return;
}
// A <def,read-undef> of a sub-register requires an implicit def of the full
// register.
- if (MO.isDef() && MO.isUndef()) {
- if (MO.isDead())
- MI.addRegisterDead(PhysReg, TRI, true);
- else
- MI.addRegisterDefined(PhysReg, TRI);
+ if (MO.isDef() && MO.isUndef()) {
+ if (MO.isDead())
+ MI.addRegisterDead(PhysReg, TRI, true);
+ else
+ MI.addRegisterDefined(PhysReg, TRI);
}
}
#ifndef NDEBUG
-
-void RegAllocFast::dumpState() const {
- for (unsigned Unit = 1, UnitE = TRI->getNumRegUnits(); Unit != UnitE;
- ++Unit) {
- switch (unsigned VirtReg = RegUnitStates[Unit]) {
+
+void RegAllocFast::dumpState() const {
+ for (unsigned Unit = 1, UnitE = TRI->getNumRegUnits(); Unit != UnitE;
+ ++Unit) {
+ switch (unsigned VirtReg = RegUnitStates[Unit]) {
case regFree:
break;
- case regPreAssigned:
- dbgs() << " " << printRegUnit(Unit, TRI) << "[P]";
+ case regPreAssigned:
+ dbgs() << " " << printRegUnit(Unit, TRI) << "[P]";
break;
- case regLiveIn:
- llvm_unreachable("Should not have regLiveIn in map");
+ case regLiveIn:
+ llvm_unreachable("Should not have regLiveIn in map");
default: {
- dbgs() << ' ' << printRegUnit(Unit, TRI) << '=' << printReg(VirtReg);
- LiveRegMap::const_iterator I = findLiveVirtReg(VirtReg);
- assert(I != LiveVirtRegs.end() && "have LiveVirtRegs entry");
- if (I->LiveOut || I->Reloaded) {
- dbgs() << '[';
- if (I->LiveOut) dbgs() << 'O';
- if (I->Reloaded) dbgs() << 'R';
- dbgs() << ']';
- }
- assert(TRI->hasRegUnit(I->PhysReg, Unit) && "inverse mapping present");
+ dbgs() << ' ' << printRegUnit(Unit, TRI) << '=' << printReg(VirtReg);
+ LiveRegMap::const_iterator I = findLiveVirtReg(VirtReg);
+ assert(I != LiveVirtRegs.end() && "have LiveVirtRegs entry");
+ if (I->LiveOut || I->Reloaded) {
+ dbgs() << '[';
+ if (I->LiveOut) dbgs() << 'O';
+ if (I->Reloaded) dbgs() << 'R';
+ dbgs() << ']';
+ }
+ assert(TRI->hasRegUnit(I->PhysReg, Unit) && "inverse mapping present");
break;
}
}
}
dbgs() << '\n';
// Check that LiveVirtRegs is the inverse.
- for (const LiveReg &LR : LiveVirtRegs) {
- Register VirtReg = LR.VirtReg;
- assert(VirtReg.isVirtual() && "Bad map key");
- MCPhysReg PhysReg = LR.PhysReg;
- if (PhysReg != 0) {
- assert(Register::isPhysicalRegister(PhysReg) &&
- "mapped to physreg");
- for (MCRegUnitIterator UI(PhysReg, TRI); UI.isValid(); ++UI) {
- assert(RegUnitStates[*UI] == VirtReg && "inverse map valid");
- }
- }
+ for (const LiveReg &LR : LiveVirtRegs) {
+ Register VirtReg = LR.VirtReg;
+ assert(VirtReg.isVirtual() && "Bad map key");
+ MCPhysReg PhysReg = LR.PhysReg;
+ if (PhysReg != 0) {
+ assert(Register::isPhysicalRegister(PhysReg) &&
+ "mapped to physreg");
+ for (MCRegUnitIterator UI(PhysReg, TRI); UI.isValid(); ++UI) {
+ assert(RegUnitStates[*UI] == VirtReg && "inverse map valid");
+ }
+ }
}
}
#endif
-/// Count number of defs consumed from each register class by \p Reg
-void RegAllocFast::addRegClassDefCounts(std::vector<unsigned> &RegClassDefCounts,
- Register Reg) const {
- assert(RegClassDefCounts.size() == TRI->getNumRegClasses());
-
- if (Reg.isVirtual()) {
- const TargetRegisterClass *OpRC = MRI->getRegClass(Reg);
- for (unsigned RCIdx = 0, RCIdxEnd = TRI->getNumRegClasses();
- RCIdx != RCIdxEnd; ++RCIdx) {
- const TargetRegisterClass *IdxRC = TRI->getRegClass(RCIdx);
- // FIXME: Consider aliasing sub/super registers.
- if (OpRC->hasSubClassEq(IdxRC))
- ++RegClassDefCounts[RCIdx];
- }
-
- return;
+/// Count number of defs consumed from each register class by \p Reg
+void RegAllocFast::addRegClassDefCounts(std::vector<unsigned> &RegClassDefCounts,
+ Register Reg) const {
+ assert(RegClassDefCounts.size() == TRI->getNumRegClasses());
+
+ if (Reg.isVirtual()) {
+ const TargetRegisterClass *OpRC = MRI->getRegClass(Reg);
+ for (unsigned RCIdx = 0, RCIdxEnd = TRI->getNumRegClasses();
+ RCIdx != RCIdxEnd; ++RCIdx) {
+ const TargetRegisterClass *IdxRC = TRI->getRegClass(RCIdx);
+ // FIXME: Consider aliasing sub/super registers.
+ if (OpRC->hasSubClassEq(IdxRC))
+ ++RegClassDefCounts[RCIdx];
+ }
+
+ return;
}
- for (unsigned RCIdx = 0, RCIdxEnd = TRI->getNumRegClasses();
- RCIdx != RCIdxEnd; ++RCIdx) {
- const TargetRegisterClass *IdxRC = TRI->getRegClass(RCIdx);
- for (MCRegAliasIterator Alias(Reg, TRI, true); Alias.isValid(); ++Alias) {
- if (IdxRC->contains(*Alias)) {
- ++RegClassDefCounts[RCIdx];
- break;
- }
- }
- }
-}
-
-void RegAllocFast::allocateInstruction(MachineInstr &MI) {
- // The basic algorithm here is:
- // 1. Mark registers of def operands as free
- // 2. Allocate registers to use operands and place reload instructions for
- // registers displaced by the allocation.
- //
- // However we need to handle some corner cases:
- // - pre-assigned defs and uses need to be handled before the other def/use
- // operands are processed to avoid the allocation heuristics clashing with
- // the pre-assignment.
- // - The "free def operands" step has to come last instead of first for tied
- // operands and early-clobbers.
-
+ for (unsigned RCIdx = 0, RCIdxEnd = TRI->getNumRegClasses();
+ RCIdx != RCIdxEnd; ++RCIdx) {
+ const TargetRegisterClass *IdxRC = TRI->getRegClass(RCIdx);
+ for (MCRegAliasIterator Alias(Reg, TRI, true); Alias.isValid(); ++Alias) {
+ if (IdxRC->contains(*Alias)) {
+ ++RegClassDefCounts[RCIdx];
+ break;
+ }
+ }
+ }
+}
+
+void RegAllocFast::allocateInstruction(MachineInstr &MI) {
+ // The basic algorithm here is:
+ // 1. Mark registers of def operands as free
+ // 2. Allocate registers to use operands and place reload instructions for
+ // registers displaced by the allocation.
+ //
+ // However we need to handle some corner cases:
+ // - pre-assigned defs and uses need to be handled before the other def/use
+ // operands are processed to avoid the allocation heuristics clashing with
+ // the pre-assignment.
+ // - The "free def operands" step has to come last instead of first for tied
+ // operands and early-clobbers.
+
UsedInInstr.clear();
- BundleVirtRegsMap.clear();
-
- // Scan for special cases; Apply pre-assigned register defs to state.
- bool HasPhysRegUse = false;
- bool HasRegMask = false;
- bool HasVRegDef = false;
- bool HasDef = false;
- bool HasEarlyClobber = false;
- bool NeedToAssignLiveThroughs = false;
- for (MachineOperand &MO : MI.operands()) {
- if (MO.isReg()) {
- Register Reg = MO.getReg();
- if (Reg.isVirtual()) {
- if (MO.isDef()) {
- HasDef = true;
- HasVRegDef = true;
- if (MO.isEarlyClobber()) {
- HasEarlyClobber = true;
- NeedToAssignLiveThroughs = true;
- }
- if (MO.isTied() || (MO.getSubReg() != 0 && !MO.isUndef()))
- NeedToAssignLiveThroughs = true;
- }
- } else if (Reg.isPhysical()) {
- if (!MRI->isReserved(Reg)) {
- if (MO.isDef()) {
- HasDef = true;
- bool displacedAny = definePhysReg(MI, Reg);
- if (MO.isEarlyClobber())
- HasEarlyClobber = true;
- if (!displacedAny)
- MO.setIsDead(true);
- }
- if (MO.readsReg())
- HasPhysRegUse = true;
- }
- }
- } else if (MO.isRegMask()) {
- HasRegMask = true;
+ BundleVirtRegsMap.clear();
+
+ // Scan for special cases; Apply pre-assigned register defs to state.
+ bool HasPhysRegUse = false;
+ bool HasRegMask = false;
+ bool HasVRegDef = false;
+ bool HasDef = false;
+ bool HasEarlyClobber = false;
+ bool NeedToAssignLiveThroughs = false;
+ for (MachineOperand &MO : MI.operands()) {
+ if (MO.isReg()) {
+ Register Reg = MO.getReg();
+ if (Reg.isVirtual()) {
+ if (MO.isDef()) {
+ HasDef = true;
+ HasVRegDef = true;
+ if (MO.isEarlyClobber()) {
+ HasEarlyClobber = true;
+ NeedToAssignLiveThroughs = true;
+ }
+ if (MO.isTied() || (MO.getSubReg() != 0 && !MO.isUndef()))
+ NeedToAssignLiveThroughs = true;
+ }
+ } else if (Reg.isPhysical()) {
+ if (!MRI->isReserved(Reg)) {
+ if (MO.isDef()) {
+ HasDef = true;
+ bool displacedAny = definePhysReg(MI, Reg);
+ if (MO.isEarlyClobber())
+ HasEarlyClobber = true;
+ if (!displacedAny)
+ MO.setIsDead(true);
+ }
+ if (MO.readsReg())
+ HasPhysRegUse = true;
+ }
+ }
+ } else if (MO.isRegMask()) {
+ HasRegMask = true;
}
- }
-
- // Allocate virtreg defs.
- if (HasDef) {
- if (HasVRegDef) {
- // Special handling for early clobbers, tied operands or subregister defs:
- // Compared to "normal" defs these:
- // - Must not use a register that is pre-assigned for a use operand.
- // - In order to solve tricky inline assembly constraints we change the
- // heuristic to figure out a good operand order before doing
- // assignments.
- if (NeedToAssignLiveThroughs) {
- DefOperandIndexes.clear();
- PhysRegUses.clear();
-
- // Track number of defs which may consume a register from the class.
- std::vector<unsigned> RegClassDefCounts(TRI->getNumRegClasses(), 0);
- assert(RegClassDefCounts[0] == 0);
-
- LLVM_DEBUG(dbgs() << "Need to assign livethroughs\n");
- for (unsigned I = 0, E = MI.getNumOperands(); I < E; ++I) {
- const MachineOperand &MO = MI.getOperand(I);
- if (!MO.isReg())
- continue;
- Register Reg = MO.getReg();
- if (MO.readsReg()) {
- if (Reg.isPhysical()) {
- LLVM_DEBUG(dbgs() << "mark extra used: " << printReg(Reg, TRI)
- << '\n');
- markPhysRegUsedInInstr(Reg);
- }
- }
-
- if (MO.isDef()) {
- if (Reg.isVirtual())
- DefOperandIndexes.push_back(I);
-
- addRegClassDefCounts(RegClassDefCounts, Reg);
- }
- }
-
- llvm::sort(DefOperandIndexes, [&](uint16_t I0, uint16_t I1) {
- const MachineOperand &MO0 = MI.getOperand(I0);
- const MachineOperand &MO1 = MI.getOperand(I1);
- Register Reg0 = MO0.getReg();
- Register Reg1 = MO1.getReg();
- const TargetRegisterClass &RC0 = *MRI->getRegClass(Reg0);
- const TargetRegisterClass &RC1 = *MRI->getRegClass(Reg1);
-
- // Identify regclass that are easy to use up completely just in this
- // instruction.
- unsigned ClassSize0 = RegClassInfo.getOrder(&RC0).size();
- unsigned ClassSize1 = RegClassInfo.getOrder(&RC1).size();
-
- bool SmallClass0 = ClassSize0 < RegClassDefCounts[RC0.getID()];
- bool SmallClass1 = ClassSize1 < RegClassDefCounts[RC1.getID()];
- if (SmallClass0 > SmallClass1)
- return true;
- if (SmallClass0 < SmallClass1)
- return false;
-
- // Allocate early clobbers and livethrough operands first.
- bool Livethrough0 = MO0.isEarlyClobber() || MO0.isTied() ||
- (MO0.getSubReg() == 0 && !MO0.isUndef());
- bool Livethrough1 = MO1.isEarlyClobber() || MO1.isTied() ||
- (MO1.getSubReg() == 0 && !MO1.isUndef());
- if (Livethrough0 > Livethrough1)
- return true;
- if (Livethrough0 < Livethrough1)
- return false;
-
- // Tie-break rule: operand index.
- return I0 < I1;
- });
-
- for (uint16_t OpIdx : DefOperandIndexes) {
- MachineOperand &MO = MI.getOperand(OpIdx);
- LLVM_DEBUG(dbgs() << "Allocating " << MO << '\n');
- unsigned Reg = MO.getReg();
- if (MO.isEarlyClobber() || MO.isTied() ||
- (MO.getSubReg() && !MO.isUndef())) {
- defineLiveThroughVirtReg(MI, OpIdx, Reg);
- } else {
- defineVirtReg(MI, OpIdx, Reg);
- }
- }
+ }
+
+ // Allocate virtreg defs.
+ if (HasDef) {
+ if (HasVRegDef) {
+ // Special handling for early clobbers, tied operands or subregister defs:
+ // Compared to "normal" defs these:
+ // - Must not use a register that is pre-assigned for a use operand.
+ // - In order to solve tricky inline assembly constraints we change the
+ // heuristic to figure out a good operand order before doing
+ // assignments.
+ if (NeedToAssignLiveThroughs) {
+ DefOperandIndexes.clear();
+ PhysRegUses.clear();
+
+ // Track number of defs which may consume a register from the class.
+ std::vector<unsigned> RegClassDefCounts(TRI->getNumRegClasses(), 0);
+ assert(RegClassDefCounts[0] == 0);
+
+ LLVM_DEBUG(dbgs() << "Need to assign livethroughs\n");
+ for (unsigned I = 0, E = MI.getNumOperands(); I < E; ++I) {
+ const MachineOperand &MO = MI.getOperand(I);
+ if (!MO.isReg())
+ continue;
+ Register Reg = MO.getReg();
+ if (MO.readsReg()) {
+ if (Reg.isPhysical()) {
+ LLVM_DEBUG(dbgs() << "mark extra used: " << printReg(Reg, TRI)
+ << '\n');
+ markPhysRegUsedInInstr(Reg);
+ }
+ }
+
+ if (MO.isDef()) {
+ if (Reg.isVirtual())
+ DefOperandIndexes.push_back(I);
+
+ addRegClassDefCounts(RegClassDefCounts, Reg);
+ }
+ }
+
+ llvm::sort(DefOperandIndexes, [&](uint16_t I0, uint16_t I1) {
+ const MachineOperand &MO0 = MI.getOperand(I0);
+ const MachineOperand &MO1 = MI.getOperand(I1);
+ Register Reg0 = MO0.getReg();
+ Register Reg1 = MO1.getReg();
+ const TargetRegisterClass &RC0 = *MRI->getRegClass(Reg0);
+ const TargetRegisterClass &RC1 = *MRI->getRegClass(Reg1);
+
+ // Identify regclass that are easy to use up completely just in this
+ // instruction.
+ unsigned ClassSize0 = RegClassInfo.getOrder(&RC0).size();
+ unsigned ClassSize1 = RegClassInfo.getOrder(&RC1).size();
+
+ bool SmallClass0 = ClassSize0 < RegClassDefCounts[RC0.getID()];
+ bool SmallClass1 = ClassSize1 < RegClassDefCounts[RC1.getID()];
+ if (SmallClass0 > SmallClass1)
+ return true;
+ if (SmallClass0 < SmallClass1)
+ return false;
+
+ // Allocate early clobbers and livethrough operands first.
+ bool Livethrough0 = MO0.isEarlyClobber() || MO0.isTied() ||
+ (MO0.getSubReg() == 0 && !MO0.isUndef());
+ bool Livethrough1 = MO1.isEarlyClobber() || MO1.isTied() ||
+ (MO1.getSubReg() == 0 && !MO1.isUndef());
+ if (Livethrough0 > Livethrough1)
+ return true;
+ if (Livethrough0 < Livethrough1)
+ return false;
+
+ // Tie-break rule: operand index.
+ return I0 < I1;
+ });
+
+ for (uint16_t OpIdx : DefOperandIndexes) {
+ MachineOperand &MO = MI.getOperand(OpIdx);
+ LLVM_DEBUG(dbgs() << "Allocating " << MO << '\n');
+ unsigned Reg = MO.getReg();
+ if (MO.isEarlyClobber() || MO.isTied() ||
+ (MO.getSubReg() && !MO.isUndef())) {
+ defineLiveThroughVirtReg(MI, OpIdx, Reg);
+ } else {
+ defineVirtReg(MI, OpIdx, Reg);
+ }
+ }
} else {
- // Assign virtual register defs.
- for (unsigned I = 0, E = MI.getNumOperands(); I < E; ++I) {
- MachineOperand &MO = MI.getOperand(I);
- if (!MO.isReg() || !MO.isDef())
- continue;
- Register Reg = MO.getReg();
- if (Reg.isVirtual())
- defineVirtReg(MI, I, Reg);
- }
+ // Assign virtual register defs.
+ for (unsigned I = 0, E = MI.getNumOperands(); I < E; ++I) {
+ MachineOperand &MO = MI.getOperand(I);
+ if (!MO.isReg() || !MO.isDef())
+ continue;
+ Register Reg = MO.getReg();
+ if (Reg.isVirtual())
+ defineVirtReg(MI, I, Reg);
+ }
+ }
+ }
+
+ // Free registers occupied by defs.
+ // Iterate operands in reverse order, so we see the implicit super register
+ // defs first (we added them earlier in case of <def,read-undef>).
+ for (unsigned I = MI.getNumOperands(); I-- > 0;) {
+ MachineOperand &MO = MI.getOperand(I);
+ if (!MO.isReg() || !MO.isDef())
+ continue;
+
+ // subreg defs don't free the full register. We left the subreg number
+ // around as a marker in setPhysReg() to recognize this case here.
+ if (MO.getSubReg() != 0) {
+ MO.setSubReg(0);
+ continue;
}
+
+ // Do not free tied operands and early clobbers.
+ if (MO.isTied() || MO.isEarlyClobber())
+ continue;
+ Register Reg = MO.getReg();
+ if (!Reg)
+ continue;
+ assert(Reg.isPhysical());
+ if (MRI->isReserved(Reg))
+ continue;
+ freePhysReg(Reg);
+ unmarkRegUsedInInstr(Reg);
}
-
- // Free registers occupied by defs.
- // Iterate operands in reverse order, so we see the implicit super register
- // defs first (we added them earlier in case of <def,read-undef>).
- for (unsigned I = MI.getNumOperands(); I-- > 0;) {
- MachineOperand &MO = MI.getOperand(I);
- if (!MO.isReg() || !MO.isDef())
- continue;
-
- // subreg defs don't free the full register. We left the subreg number
- // around as a marker in setPhysReg() to recognize this case here.
- if (MO.getSubReg() != 0) {
- MO.setSubReg(0);
- continue;
- }
-
- // Do not free tied operands and early clobbers.
- if (MO.isTied() || MO.isEarlyClobber())
- continue;
- Register Reg = MO.getReg();
- if (!Reg)
- continue;
- assert(Reg.isPhysical());
- if (MRI->isReserved(Reg))
- continue;
- freePhysReg(Reg);
- unmarkRegUsedInInstr(Reg);
- }
}
- // Displace clobbered registers.
- if (HasRegMask) {
- for (const MachineOperand &MO : MI.operands()) {
- if (MO.isRegMask()) {
- // MRI bookkeeping.
- MRI->addPhysRegsUsedFromRegMask(MO.getRegMask());
-
- // Displace clobbered registers.
- const uint32_t *Mask = MO.getRegMask();
- for (LiveRegMap::iterator LRI = LiveVirtRegs.begin(),
- LRIE = LiveVirtRegs.end(); LRI != LRIE; ++LRI) {
- MCPhysReg PhysReg = LRI->PhysReg;
- if (PhysReg != 0 && MachineOperand::clobbersPhysReg(Mask, PhysReg))
- displacePhysReg(MI, PhysReg);
- }
- }
- }
+ // Displace clobbered registers.
+ if (HasRegMask) {
+ for (const MachineOperand &MO : MI.operands()) {
+ if (MO.isRegMask()) {
+ // MRI bookkeeping.
+ MRI->addPhysRegsUsedFromRegMask(MO.getRegMask());
+
+ // Displace clobbered registers.
+ const uint32_t *Mask = MO.getRegMask();
+ for (LiveRegMap::iterator LRI = LiveVirtRegs.begin(),
+ LRIE = LiveVirtRegs.end(); LRI != LRIE; ++LRI) {
+ MCPhysReg PhysReg = LRI->PhysReg;
+ if (PhysReg != 0 && MachineOperand::clobbersPhysReg(Mask, PhysReg))
+ displacePhysReg(MI, PhysReg);
+ }
+ }
+ }
}
- // Apply pre-assigned register uses to state.
- if (HasPhysRegUse) {
- for (MachineOperand &MO : MI.operands()) {
- if (!MO.isReg() || !MO.readsReg())
- continue;
- Register Reg = MO.getReg();
- if (!Reg.isPhysical())
- continue;
- if (MRI->isReserved(Reg))
- continue;
- bool displacedAny = usePhysReg(MI, Reg);
- if (!displacedAny && !MRI->isReserved(Reg))
- MO.setIsKill(true);
- }
- }
-
- // Allocate virtreg uses and insert reloads as necessary.
+ // Apply pre-assigned register uses to state.
+ if (HasPhysRegUse) {
+ for (MachineOperand &MO : MI.operands()) {
+ if (!MO.isReg() || !MO.readsReg())
+ continue;
+ Register Reg = MO.getReg();
+ if (!Reg.isPhysical())
+ continue;
+ if (MRI->isReserved(Reg))
+ continue;
+ bool displacedAny = usePhysReg(MI, Reg);
+ if (!displacedAny && !MRI->isReserved(Reg))
+ MO.setIsKill(true);
+ }
+ }
+
+ // Allocate virtreg uses and insert reloads as necessary.
bool HasUndefUse = false;
- for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
+ for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
MachineOperand &MO = MI.getOperand(I);
- if (!MO.isReg() || !MO.isUse())
- continue;
+ if (!MO.isReg() || !MO.isUse())
+ continue;
Register Reg = MO.getReg();
if (!Reg.isVirtual())
continue;
- if (MO.isUndef()) {
- HasUndefUse = true;
- continue;
- }
-
-
- // Populate MayLiveAcrossBlocks in case the use block is allocated before
- // the def block (removing the vreg uses).
- mayLiveIn(Reg);
-
-
- assert(!MO.isInternalRead() && "Bundles not supported");
- assert(MO.readsReg() && "reading use");
- useVirtReg(MI, I, Reg);
+ if (MO.isUndef()) {
+ HasUndefUse = true;
+ continue;
+ }
+
+
+ // Populate MayLiveAcrossBlocks in case the use block is allocated before
+ // the def block (removing the vreg uses).
+ mayLiveIn(Reg);
+
+
+ assert(!MO.isInternalRead() && "Bundles not supported");
+ assert(MO.readsReg() && "reading use");
+ useVirtReg(MI, I, Reg);
}
// Allocate undef operands. This is a separate step because in a situation
@@ -1321,40 +1321,40 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
}
}
- // Free early clobbers.
- if (HasEarlyClobber) {
- for (unsigned I = MI.getNumOperands(); I-- > 0; ) {
- MachineOperand &MO = MI.getOperand(I);
- if (!MO.isReg() || !MO.isDef() || !MO.isEarlyClobber())
- continue;
- // subreg defs don't free the full register. We left the subreg number
- // around as a marker in setPhysReg() to recognize this case here.
- if (MO.getSubReg() != 0) {
- MO.setSubReg(0);
- continue;
- }
-
+ // Free early clobbers.
+ if (HasEarlyClobber) {
+ for (unsigned I = MI.getNumOperands(); I-- > 0; ) {
+ MachineOperand &MO = MI.getOperand(I);
+ if (!MO.isReg() || !MO.isDef() || !MO.isEarlyClobber())
+ continue;
+ // subreg defs don't free the full register. We left the subreg number
+ // around as a marker in setPhysReg() to recognize this case here.
+ if (MO.getSubReg() != 0) {
+ MO.setSubReg(0);
+ continue;
+ }
+
Register Reg = MO.getReg();
- if (!Reg)
+ if (!Reg)
+ continue;
+ assert(Reg.isPhysical() && "should have register assigned");
+
+ // We sometimes get odd situations like:
+ // early-clobber %x0 = INSTRUCTION %x0
+ // which is semantically questionable as the early-clobber should
+ // apply before the use. But in practice we consider the use to
+ // happen before the early clobber now. Don't free the early clobber
+ // register in this case.
+ if (MI.readsRegister(Reg, TRI))
continue;
- assert(Reg.isPhysical() && "should have register assigned");
-
- // We sometimes get odd situations like:
- // early-clobber %x0 = INSTRUCTION %x0
- // which is semantically questionable as the early-clobber should
- // apply before the use. But in practice we consider the use to
- // happen before the early clobber now. Don't free the early clobber
- // register in this case.
- if (MI.readsRegister(Reg, TRI))
- continue;
-
- freePhysReg(Reg);
- }
+
+ freePhysReg(Reg);
+ }
}
LLVM_DEBUG(dbgs() << "<< " << MI);
- if (MI.isCopy() && MI.getOperand(0).getReg() == MI.getOperand(1).getReg() &&
- MI.getNumOperands() == 2) {
+ if (MI.isCopy() && MI.getOperand(0).getReg() == MI.getOperand(1).getReg() &&
+ MI.getNumOperands() == 2) {
LLVM_DEBUG(dbgs() << "Mark identity copy for removal\n");
Coalesced.push_back(&MI);
}
@@ -1371,22 +1371,22 @@ void RegAllocFast::handleDebugValue(MachineInstr &MI) {
if (!Register::isVirtualRegister(Reg))
return;
- // Already spilled to a stackslot?
- int SS = StackSlotForVirtReg[Reg];
- if (SS != -1) {
- // Modify DBG_VALUE now that the value is in a spill slot.
- updateDbgValueForSpill(MI, SS);
- LLVM_DEBUG(dbgs() << "Rewrite DBG_VALUE for spilled memory: " << MI);
- return;
- }
-
+ // Already spilled to a stackslot?
+ int SS = StackSlotForVirtReg[Reg];
+ if (SS != -1) {
+ // Modify DBG_VALUE now that the value is in a spill slot.
+ updateDbgValueForSpill(MI, SS);
+ LLVM_DEBUG(dbgs() << "Rewrite DBG_VALUE for spilled memory: " << MI);
+ return;
+ }
+
// See if this virtual register has already been allocated to a physical
// register or spilled to a stack slot.
LiveRegMap::iterator LRI = findLiveVirtReg(Reg);
if (LRI != LiveVirtRegs.end() && LRI->PhysReg) {
setPhysReg(MI, MO, LRI->PhysReg);
} else {
- DanglingDbgValues[Reg].push_back(&MI);
+ DanglingDbgValues[Reg].push_back(&MI);
}
// If Reg hasn't been spilled, put this DBG_VALUE in LiveDbgValueMap so
@@ -1394,46 +1394,46 @@ void RegAllocFast::handleDebugValue(MachineInstr &MI) {
LiveDbgValueMap[Reg].push_back(&MI);
}
-void RegAllocFast::handleBundle(MachineInstr &MI) {
- MachineBasicBlock::instr_iterator BundledMI = MI.getIterator();
- ++BundledMI;
- while (BundledMI->isBundledWithPred()) {
- for (unsigned I = 0; I < BundledMI->getNumOperands(); ++I) {
- MachineOperand &MO = BundledMI->getOperand(I);
- if (!MO.isReg())
- continue;
-
- Register Reg = MO.getReg();
- if (!Reg.isVirtual())
- continue;
-
- DenseMap<Register, MCPhysReg>::iterator DI;
- DI = BundleVirtRegsMap.find(Reg);
- assert(DI != BundleVirtRegsMap.end() && "Unassigned virtual register");
-
- setPhysReg(MI, MO, DI->second);
- }
-
- ++BundledMI;
- }
-}
-
+void RegAllocFast::handleBundle(MachineInstr &MI) {
+ MachineBasicBlock::instr_iterator BundledMI = MI.getIterator();
+ ++BundledMI;
+ while (BundledMI->isBundledWithPred()) {
+ for (unsigned I = 0; I < BundledMI->getNumOperands(); ++I) {
+ MachineOperand &MO = BundledMI->getOperand(I);
+ if (!MO.isReg())
+ continue;
+
+ Register Reg = MO.getReg();
+ if (!Reg.isVirtual())
+ continue;
+
+ DenseMap<Register, MCPhysReg>::iterator DI;
+ DI = BundleVirtRegsMap.find(Reg);
+ assert(DI != BundleVirtRegsMap.end() && "Unassigned virtual register");
+
+ setPhysReg(MI, MO, DI->second);
+ }
+
+ ++BundledMI;
+ }
+}
+
void RegAllocFast::allocateBasicBlock(MachineBasicBlock &MBB) {
this->MBB = &MBB;
LLVM_DEBUG(dbgs() << "\nAllocating " << MBB);
- RegUnitStates.assign(TRI->getNumRegUnits(), regFree);
+ RegUnitStates.assign(TRI->getNumRegUnits(), regFree);
assert(LiveVirtRegs.empty() && "Mapping not cleared from last block?");
- for (MachineBasicBlock *Succ : MBB.successors()) {
- for (const MachineBasicBlock::RegisterMaskPair &LI : Succ->liveins())
- setPhysRegState(LI.PhysReg, regPreAssigned);
- }
+ for (MachineBasicBlock *Succ : MBB.successors()) {
+ for (const MachineBasicBlock::RegisterMaskPair &LI : Succ->liveins())
+ setPhysRegState(LI.PhysReg, regPreAssigned);
+ }
Coalesced.clear();
- // Traverse block in reverse order allocating instructions one by one.
- for (MachineInstr &MI : reverse(MBB)) {
+ // Traverse block in reverse order allocating instructions one by one.
+ for (MachineInstr &MI : reverse(MBB)) {
LLVM_DEBUG(
dbgs() << "\n>> " << MI << "Regs:";
dumpState()
@@ -1447,22 +1447,22 @@ void RegAllocFast::allocateBasicBlock(MachineBasicBlock &MBB) {
}
allocateInstruction(MI);
-
- // Once BUNDLE header is assigned registers, same assignments need to be
- // done for bundled MIs.
- if (MI.getOpcode() == TargetOpcode::BUNDLE) {
- handleBundle(MI);
- }
+
+ // Once BUNDLE header is assigned registers, same assignments need to be
+ // done for bundled MIs.
+ if (MI.getOpcode() == TargetOpcode::BUNDLE) {
+ handleBundle(MI);
+ }
}
- LLVM_DEBUG(
- dbgs() << "Begin Regs:";
- dumpState()
- );
-
+ LLVM_DEBUG(
+ dbgs() << "Begin Regs:";
+ dumpState()
+ );
+
// Spill all physical registers holding virtual registers now.
- LLVM_DEBUG(dbgs() << "Loading live registers at begin of block.\n");
- reloadAtBegin(MBB);
+ LLVM_DEBUG(dbgs() << "Loading live registers at begin of block.\n");
+ reloadAtBegin(MBB);
// Erase all the coalesced copies. We are delaying it until now because
// LiveVirtRegs might refer to the instrs.
@@ -1470,20 +1470,20 @@ void RegAllocFast::allocateBasicBlock(MachineBasicBlock &MBB) {
MBB.erase(MI);
NumCoalesced += Coalesced.size();
- for (auto &UDBGPair : DanglingDbgValues) {
- for (MachineInstr *DbgValue : UDBGPair.second) {
- assert(DbgValue->isDebugValue() && "expected DBG_VALUE");
- MachineOperand &MO = DbgValue->getOperand(0);
- // Nothing to do if the vreg was spilled in the meantime.
- if (!MO.isReg())
- continue;
- LLVM_DEBUG(dbgs() << "Register did not survive for " << *DbgValue
- << '\n');
- MO.setReg(0);
- }
- }
- DanglingDbgValues.clear();
-
+ for (auto &UDBGPair : DanglingDbgValues) {
+ for (MachineInstr *DbgValue : UDBGPair.second) {
+ assert(DbgValue->isDebugValue() && "expected DBG_VALUE");
+ MachineOperand &MO = DbgValue->getOperand(0);
+ // Nothing to do if the vreg was spilled in the meantime.
+ if (!MO.isReg())
+ continue;
+ LLVM_DEBUG(dbgs() << "Register did not survive for " << *DbgValue
+ << '\n');
+ MO.setReg(0);
+ }
+ }
+ DanglingDbgValues.clear();
+
LLVM_DEBUG(MBB.dump());
}
@@ -1497,11 +1497,11 @@ bool RegAllocFast::runOnMachineFunction(MachineFunction &MF) {
MFI = &MF.getFrameInfo();
MRI->freezeReservedRegs(MF);
RegClassInfo.runOnMachineFunction(MF);
- unsigned NumRegUnits = TRI->getNumRegUnits();
+ unsigned NumRegUnits = TRI->getNumRegUnits();
UsedInInstr.clear();
- UsedInInstr.setUniverse(NumRegUnits);
- PhysRegUses.clear();
- PhysRegUses.setUniverse(NumRegUnits);
+ UsedInInstr.setUniverse(NumRegUnits);
+ PhysRegUses.clear();
+ PhysRegUses.setUniverse(NumRegUnits);
// initialize the virtual->physical register map to have a 'null'
// mapping for all virtual registers
diff --git a/contrib/libs/llvm12/lib/CodeGen/RegAllocGreedy.cpp b/contrib/libs/llvm12/lib/CodeGen/RegAllocGreedy.cpp
index 8a991fdbba..166414e4ff 100644
--- a/contrib/libs/llvm12/lib/CodeGen/RegAllocGreedy.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/RegAllocGreedy.cpp
@@ -147,7 +147,7 @@ class RAGreedy : public MachineFunctionPass,
// Convenient shortcuts.
using PQueue = std::priority_queue<std::pair<unsigned, unsigned>>;
using SmallLISet = SmallPtrSet<LiveInterval *, 4>;
- using SmallVirtRegSet = SmallSet<Register, 16>;
+ using SmallVirtRegSet = SmallSet<Register, 16>;
// context
MachineFunction *MF;
@@ -172,7 +172,7 @@ class RAGreedy : public MachineFunctionPass,
std::unique_ptr<Spiller> SpillerInstance;
PQueue Queue;
unsigned NextCascade;
- std::unique_ptr<VirtRegAuxInfo> VRAI;
+ std::unique_ptr<VirtRegAuxInfo> VRAI;
// Live ranges pass through a number of stages as we try to allocate them.
// Some of the stages may also create new live ranges:
@@ -248,19 +248,19 @@ class RAGreedy : public MachineFunctionPass,
IndexedMap<RegInfo, VirtReg2IndexFunctor> ExtraRegInfo;
LiveRangeStage getStage(const LiveInterval &VirtReg) const {
- return ExtraRegInfo[VirtReg.reg()].Stage;
+ return ExtraRegInfo[VirtReg.reg()].Stage;
}
void setStage(const LiveInterval &VirtReg, LiveRangeStage Stage) {
ExtraRegInfo.resize(MRI->getNumVirtRegs());
- ExtraRegInfo[VirtReg.reg()].Stage = Stage;
+ ExtraRegInfo[VirtReg.reg()].Stage = Stage;
}
template<typename Iterator>
void setStage(Iterator Begin, Iterator End, LiveRangeStage NewStage) {
ExtraRegInfo.resize(MRI->getNumVirtRegs());
for (;Begin != End; ++Begin) {
- Register Reg = *Begin;
+ Register Reg = *Begin;
if (ExtraRegInfo[Reg].Stage == RS_New)
ExtraRegInfo[Reg].Stage = NewStage;
}
@@ -291,8 +291,8 @@ class RAGreedy : public MachineFunctionPass,
public:
using EvictorInfo =
- std::pair<Register /* evictor */, MCRegister /* physreg */>;
- using EvicteeInfo = llvm::DenseMap<Register /* evictee */, EvictorInfo>;
+ std::pair<Register /* evictor */, MCRegister /* physreg */>;
+ using EvicteeInfo = llvm::DenseMap<Register /* evictee */, EvictorInfo>;
private:
/// Each Vreg that has been evicted in the last stage of selectOrSplit will
@@ -308,14 +308,14 @@ class RAGreedy : public MachineFunctionPass,
/// longer relevant.
/// \param Evictee The evictee Vreg for whom we want to clear collected
/// eviction info.
- void clearEvicteeInfo(Register Evictee) { Evictees.erase(Evictee); }
+ void clearEvicteeInfo(Register Evictee) { Evictees.erase(Evictee); }
/// Track new eviction.
/// The Evictor vreg has evicted the Evictee vreg from Physreg.
/// \param PhysReg The physical register Evictee was evicted from.
/// \param Evictor The evictor Vreg that evicted Evictee.
/// \param Evictee The evictee Vreg.
- void addEviction(MCRegister PhysReg, Register Evictor, Register Evictee) {
+ void addEviction(MCRegister PhysReg, Register Evictor, Register Evictee) {
Evictees[Evictee].first = Evictor;
Evictees[Evictee].second = PhysReg;
}
@@ -324,7 +324,7 @@ class RAGreedy : public MachineFunctionPass,
/// \param Evictee The evictee vreg.
/// \return The Evictor vreg which evicted Evictee vreg from PhysReg. 0 if
/// nobody has evicted Evictee from PhysReg.
- EvictorInfo getEvictor(Register Evictee) {
+ EvictorInfo getEvictor(Register Evictee) {
if (Evictees.count(Evictee)) {
return Evictees[Evictee];
}
@@ -349,7 +349,7 @@ class RAGreedy : public MachineFunctionPass,
/// Global live range splitting candidate info.
struct GlobalSplitCandidate {
// Register intended for assignment, or 0.
- MCRegister PhysReg;
+ MCRegister PhysReg;
// SplitKit interval index for this candidate.
unsigned IntvIdx;
@@ -361,7 +361,7 @@ class RAGreedy : public MachineFunctionPass,
BitVector LiveBundles;
SmallVector<unsigned, 8> ActiveBlocks;
- void reset(InterferenceCache &Cache, MCRegister Reg) {
+ void reset(InterferenceCache &Cache, MCRegister Reg) {
PhysReg = Reg;
IntvIdx = 0;
Intf.setPhysReg(Cache, Reg);
@@ -369,12 +369,12 @@ class RAGreedy : public MachineFunctionPass,
ActiveBlocks.clear();
}
- // Set B[I] = C for every live bundle where B[I] was NoCand.
+ // Set B[I] = C for every live bundle where B[I] was NoCand.
unsigned getBundles(SmallVectorImpl<unsigned> &B, unsigned C) {
unsigned Count = 0;
- for (unsigned I : LiveBundles.set_bits())
- if (B[I] == NoCand) {
- B[I] = C;
+ for (unsigned I : LiveBundles.set_bits())
+ if (B[I] == NoCand) {
+ B[I] = C;
Count++;
}
return Count;
@@ -418,8 +418,8 @@ public:
Spiller &spiller() override { return *SpillerInstance; }
void enqueue(LiveInterval *LI) override;
LiveInterval *dequeue() override;
- MCRegister selectOrSplit(LiveInterval &,
- SmallVectorImpl<Register> &) override;
+ MCRegister selectOrSplit(LiveInterval &,
+ SmallVectorImpl<Register> &) override;
void aboutToRemoveInterval(LiveInterval &) override;
/// Perform register allocation.
@@ -430,20 +430,20 @@ public:
MachineFunctionProperties::Property::NoPHIs);
}
- MachineFunctionProperties getClearedProperties() const override {
- return MachineFunctionProperties().set(
- MachineFunctionProperties::Property::IsSSA);
- }
-
+ MachineFunctionProperties getClearedProperties() const override {
+ return MachineFunctionProperties().set(
+ MachineFunctionProperties::Property::IsSSA);
+ }
+
static char ID;
private:
- MCRegister selectOrSplitImpl(LiveInterval &, SmallVectorImpl<Register> &,
- SmallVirtRegSet &, unsigned = 0);
+ MCRegister selectOrSplitImpl(LiveInterval &, SmallVectorImpl<Register> &,
+ SmallVirtRegSet &, unsigned = 0);
- bool LRE_CanEraseVirtReg(Register) override;
- void LRE_WillShrinkVirtReg(Register) override;
- void LRE_DidCloneVirtReg(Register, Register) override;
+ bool LRE_CanEraseVirtReg(Register) override;
+ void LRE_WillShrinkVirtReg(Register) override;
+ void LRE_DidCloneVirtReg(Register, Register) override;
void enqueue(PQueue &CurQueue, LiveInterval *LI);
LiveInterval *dequeue(PQueue &CurQueue);
@@ -451,7 +451,7 @@ private:
bool addSplitConstraints(InterferenceCache::Cursor, BlockFrequency&);
bool addThroughConstraints(InterferenceCache::Cursor, ArrayRef<unsigned>);
bool growRegion(GlobalSplitCandidate &Cand);
- bool splitCanCauseEvictionChain(Register Evictee, GlobalSplitCandidate &Cand,
+ bool splitCanCauseEvictionChain(Register Evictee, GlobalSplitCandidate &Cand,
unsigned BBNumber,
const AllocationOrder &Order);
bool splitCanCauseLocalSpill(unsigned VirtRegToSplit,
@@ -462,20 +462,20 @@ private:
bool *CanCauseEvictionChain);
bool calcCompactRegion(GlobalSplitCandidate&);
void splitAroundRegion(LiveRangeEdit&, ArrayRef<unsigned>);
- void calcGapWeights(MCRegister, SmallVectorImpl<float> &);
+ void calcGapWeights(MCRegister, SmallVectorImpl<float> &);
Register canReassign(LiveInterval &VirtReg, Register PrevReg);
bool shouldEvict(LiveInterval &A, bool, LiveInterval &B, bool);
- bool canEvictInterference(LiveInterval &, MCRegister, bool, EvictionCost &,
- const SmallVirtRegSet &);
- bool canEvictInterferenceInRange(LiveInterval &VirtReg, MCRegister PhysReg,
+ bool canEvictInterference(LiveInterval &, MCRegister, bool, EvictionCost &,
+ const SmallVirtRegSet &);
+ bool canEvictInterferenceInRange(LiveInterval &VirtReg, MCRegister PhysReg,
SlotIndex Start, SlotIndex End,
EvictionCost &MaxCost);
- MCRegister getCheapestEvicteeWeight(const AllocationOrder &Order,
- LiveInterval &VirtReg, SlotIndex Start,
- SlotIndex End, float *BestEvictWeight);
- void evictInterference(LiveInterval &, MCRegister,
- SmallVectorImpl<Register> &);
- bool mayRecolorAllInterferences(MCRegister PhysReg, LiveInterval &VirtReg,
+ MCRegister getCheapestEvicteeWeight(const AllocationOrder &Order,
+ LiveInterval &VirtReg, SlotIndex Start,
+ SlotIndex End, float *BestEvictWeight);
+ void evictInterference(LiveInterval &, MCRegister,
+ SmallVectorImpl<Register> &);
+ bool mayRecolorAllInterferences(MCRegister PhysReg, LiveInterval &VirtReg,
SmallLISet &RecoloringCandidates,
const SmallVirtRegSet &FixedRegisters);
@@ -485,8 +485,8 @@ private:
unsigned tryEvict(LiveInterval&, AllocationOrder&,
SmallVectorImpl<Register>&, unsigned,
const SmallVirtRegSet&);
- MCRegister tryRegionSplit(LiveInterval &, AllocationOrder &,
- SmallVectorImpl<Register> &);
+ MCRegister tryRegionSplit(LiveInterval &, AllocationOrder &,
+ SmallVectorImpl<Register> &);
/// Calculate cost of region splitting.
unsigned calculateRegionSplitCost(LiveInterval &VirtReg,
AllocationOrder &Order,
@@ -499,10 +499,10 @@ private:
SmallVectorImpl<Register> &NewVRegs);
/// Check other options before using a callee-saved register for the first
/// time.
- MCRegister tryAssignCSRFirstTime(LiveInterval &VirtReg,
- AllocationOrder &Order, MCRegister PhysReg,
- unsigned &CostPerUseLimit,
- SmallVectorImpl<Register> &NewVRegs);
+ MCRegister tryAssignCSRFirstTime(LiveInterval &VirtReg,
+ AllocationOrder &Order, MCRegister PhysReg,
+ unsigned &CostPerUseLimit,
+ SmallVectorImpl<Register> &NewVRegs);
void initializeCSRCost();
unsigned tryBlockSplit(LiveInterval&, AllocationOrder&,
SmallVectorImpl<Register>&);
@@ -536,8 +536,8 @@ private:
};
using HintsInfo = SmallVector<HintInfo, 4>;
- BlockFrequency getBrokenHintFreq(const HintsInfo &, MCRegister);
- void collectHintInfo(Register, HintsInfo &);
+ BlockFrequency getBrokenHintFreq(const HintsInfo &, MCRegister);
+ void collectHintInfo(Register, HintsInfo &);
bool isUnusedCalleeSavedReg(MCRegister PhysReg) const;
@@ -634,7 +634,7 @@ void RAGreedy::getAnalysisUsage(AnalysisUsage &AU) const {
// LiveRangeEdit delegate methods
//===----------------------------------------------------------------------===//
-bool RAGreedy::LRE_CanEraseVirtReg(Register VirtReg) {
+bool RAGreedy::LRE_CanEraseVirtReg(Register VirtReg) {
LiveInterval &LI = LIS->getInterval(VirtReg);
if (VRM->hasPhys(VirtReg)) {
Matrix->unassign(LI);
@@ -649,7 +649,7 @@ bool RAGreedy::LRE_CanEraseVirtReg(Register VirtReg) {
return false;
}
-void RAGreedy::LRE_WillShrinkVirtReg(Register VirtReg) {
+void RAGreedy::LRE_WillShrinkVirtReg(Register VirtReg) {
if (!VRM->hasPhys(VirtReg))
return;
@@ -659,7 +659,7 @@ void RAGreedy::LRE_WillShrinkVirtReg(Register VirtReg) {
enqueue(&LI);
}
-void RAGreedy::LRE_DidCloneVirtReg(Register New, Register Old) {
+void RAGreedy::LRE_DidCloneVirtReg(Register New, Register Old) {
// Cloning a register we haven't even heard about yet? Just ignore it.
if (!ExtraRegInfo.inBounds(Old))
return;
@@ -685,8 +685,8 @@ void RAGreedy::enqueue(PQueue &CurQueue, LiveInterval *LI) {
// Prioritize live ranges by size, assigning larger ranges first.
// The queue holds (size, reg) pairs.
const unsigned Size = LI->getSize();
- const Register Reg = LI->reg();
- assert(Reg.isVirtual() && "Can only enqueue virtual registers");
+ const Register Reg = LI->reg();
+ assert(Reg.isVirtual() && "Can only enqueue virtual registers");
unsigned Prio;
ExtraRegInfo.grow(Reg);
@@ -764,32 +764,32 @@ Register RAGreedy::tryAssign(LiveInterval &VirtReg,
SmallVectorImpl<Register> &NewVRegs,
const SmallVirtRegSet &FixedRegisters) {
Register PhysReg;
- for (auto I = Order.begin(), E = Order.end(); I != E && !PhysReg; ++I) {
- assert(*I);
- if (!Matrix->checkInterference(VirtReg, *I)) {
- if (I.isHint())
- return *I;
- else
- PhysReg = *I;
- }
- }
- if (!PhysReg.isValid())
+ for (auto I = Order.begin(), E = Order.end(); I != E && !PhysReg; ++I) {
+ assert(*I);
+ if (!Matrix->checkInterference(VirtReg, *I)) {
+ if (I.isHint())
+ return *I;
+ else
+ PhysReg = *I;
+ }
+ }
+ if (!PhysReg.isValid())
return PhysReg;
// PhysReg is available, but there may be a better choice.
// If we missed a simple hint, try to cheaply evict interference from the
// preferred register.
- if (Register Hint = MRI->getSimpleHint(VirtReg.reg()))
+ if (Register Hint = MRI->getSimpleHint(VirtReg.reg()))
if (Order.isHint(Hint)) {
- MCRegister PhysHint = Hint.asMCReg();
- LLVM_DEBUG(dbgs() << "missed hint " << printReg(PhysHint, TRI) << '\n');
+ MCRegister PhysHint = Hint.asMCReg();
+ LLVM_DEBUG(dbgs() << "missed hint " << printReg(PhysHint, TRI) << '\n');
EvictionCost MaxCost;
MaxCost.setBrokenHints(1);
- if (canEvictInterference(VirtReg, PhysHint, true, MaxCost,
- FixedRegisters)) {
- evictInterference(VirtReg, PhysHint, NewVRegs);
- return PhysHint;
+ if (canEvictInterference(VirtReg, PhysHint, true, MaxCost,
+ FixedRegisters)) {
+ evictInterference(VirtReg, PhysHint, NewVRegs);
+ return PhysHint;
}
// Record the missed hint, we may be able to recover
// at the end if the surrounding allocation changed.
@@ -814,14 +814,14 @@ Register RAGreedy::tryAssign(LiveInterval &VirtReg,
//===----------------------------------------------------------------------===//
Register RAGreedy::canReassign(LiveInterval &VirtReg, Register PrevReg) {
- auto Order =
- AllocationOrder::create(VirtReg.reg(), *VRM, RegClassInfo, Matrix);
- MCRegister PhysReg;
- for (auto I = Order.begin(), E = Order.end(); I != E && !PhysReg; ++I) {
- if ((*I).id() == PrevReg.id())
+ auto Order =
+ AllocationOrder::create(VirtReg.reg(), *VRM, RegClassInfo, Matrix);
+ MCRegister PhysReg;
+ for (auto I = Order.begin(), E = Order.end(); I != E && !PhysReg; ++I) {
+ if ((*I).id() == PrevReg.id())
continue;
- MCRegUnitIterator Units(*I, TRI);
+ MCRegUnitIterator Units(*I, TRI);
for (; Units.isValid(); ++Units) {
// Instantiate a "subquery", not to be confused with the Queries array.
LiveIntervalUnion::Query subQ(VirtReg, Matrix->getLiveUnions()[*Units]);
@@ -830,7 +830,7 @@ Register RAGreedy::canReassign(LiveInterval &VirtReg, Register PrevReg) {
}
// If no units have interference, break out with the current PhysReg.
if (!Units.isValid())
- PhysReg = *I;
+ PhysReg = *I;
}
if (PhysReg)
LLVM_DEBUG(dbgs() << "can reassign: " << VirtReg << " from "
@@ -861,8 +861,8 @@ bool RAGreedy::shouldEvict(LiveInterval &A, bool IsHint,
if (CanSplit && IsHint && !BreaksHint)
return true;
- if (A.weight() > B.weight()) {
- LLVM_DEBUG(dbgs() << "should evict: " << B << " w= " << B.weight() << '\n');
+ if (A.weight() > B.weight()) {
+ LLVM_DEBUG(dbgs() << "should evict: " << B << " w= " << B.weight() << '\n');
return true;
}
return false;
@@ -877,7 +877,7 @@ bool RAGreedy::shouldEvict(LiveInterval &A, bool IsHint,
/// @param MaxCost Only look for cheaper candidates and update with new cost
/// when returning true.
/// @returns True when interference can be evicted cheaper than MaxCost.
-bool RAGreedy::canEvictInterference(LiveInterval &VirtReg, MCRegister PhysReg,
+bool RAGreedy::canEvictInterference(LiveInterval &VirtReg, MCRegister PhysReg,
bool IsHint, EvictionCost &MaxCost,
const SmallVirtRegSet &FixedRegisters) {
// It is only possible to evict virtual register interference.
@@ -893,7 +893,7 @@ bool RAGreedy::canEvictInterference(LiveInterval &VirtReg, MCRegister PhysReg,
//
// This works out so a register without a cascade number is allowed to evict
// anything, and it can be evicted by anything.
- unsigned Cascade = ExtraRegInfo[VirtReg.reg()].Cascade;
+ unsigned Cascade = ExtraRegInfo[VirtReg.reg()].Cascade;
if (!Cascade)
Cascade = NextCascade;
@@ -905,14 +905,14 @@ bool RAGreedy::canEvictInterference(LiveInterval &VirtReg, MCRegister PhysReg,
return false;
// Check if any interfering live range is heavier than MaxWeight.
- for (LiveInterval *Intf : reverse(Q.interferingVRegs())) {
- assert(Register::isVirtualRegister(Intf->reg()) &&
+ for (LiveInterval *Intf : reverse(Q.interferingVRegs())) {
+ assert(Register::isVirtualRegister(Intf->reg()) &&
"Only expecting virtual register interference from query");
// Do not allow eviction of a virtual register if we are in the middle
// of last-chance recoloring and this virtual register is one that we
// have scavenged a physical register for.
- if (FixedRegisters.count(Intf->reg()))
+ if (FixedRegisters.count(Intf->reg()))
return false;
// Never evict spill products. They cannot split or spill.
@@ -924,14 +924,14 @@ bool RAGreedy::canEvictInterference(LiveInterval &VirtReg, MCRegister PhysReg,
//
// Also allow urgent evictions of unspillable ranges from a strictly
// larger allocation order.
- bool Urgent =
- !VirtReg.isSpillable() &&
- (Intf->isSpillable() ||
- RegClassInfo.getNumAllocatableRegs(MRI->getRegClass(VirtReg.reg())) <
- RegClassInfo.getNumAllocatableRegs(
- MRI->getRegClass(Intf->reg())));
+ bool Urgent =
+ !VirtReg.isSpillable() &&
+ (Intf->isSpillable() ||
+ RegClassInfo.getNumAllocatableRegs(MRI->getRegClass(VirtReg.reg())) <
+ RegClassInfo.getNumAllocatableRegs(
+ MRI->getRegClass(Intf->reg())));
// Only evict older cascades or live ranges without a cascade.
- unsigned IntfCascade = ExtraRegInfo[Intf->reg()].Cascade;
+ unsigned IntfCascade = ExtraRegInfo[Intf->reg()].Cascade;
if (Cascade <= IntfCascade) {
if (!Urgent)
return false;
@@ -940,10 +940,10 @@ bool RAGreedy::canEvictInterference(LiveInterval &VirtReg, MCRegister PhysReg,
Cost.BrokenHints += 10;
}
// Would this break a satisfied hint?
- bool BreaksHint = VRM->hasPreferredPhys(Intf->reg());
+ bool BreaksHint = VRM->hasPreferredPhys(Intf->reg());
// Update eviction cost.
Cost.BrokenHints += BreaksHint;
- Cost.MaxWeight = std::max(Cost.MaxWeight, Intf->weight());
+ Cost.MaxWeight = std::max(Cost.MaxWeight, Intf->weight());
// Abort if this would be too expensive.
if (!(Cost < MaxCost))
return false;
@@ -976,7 +976,7 @@ bool RAGreedy::canEvictInterference(LiveInterval &VirtReg, MCRegister PhysReg,
/// when returning true.
/// \return True when interference can be evicted cheaper than MaxCost.
bool RAGreedy::canEvictInterferenceInRange(LiveInterval &VirtReg,
- MCRegister PhysReg, SlotIndex Start,
+ MCRegister PhysReg, SlotIndex Start,
SlotIndex End,
EvictionCost &MaxCost) {
EvictionCost Cost;
@@ -985,23 +985,23 @@ bool RAGreedy::canEvictInterferenceInRange(LiveInterval &VirtReg,
LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, *Units);
// Check if any interfering live range is heavier than MaxWeight.
- for (const LiveInterval *Intf : reverse(Q.interferingVRegs())) {
+ for (const LiveInterval *Intf : reverse(Q.interferingVRegs())) {
// Check if interference overlast the segment in interest.
if (!Intf->overlaps(Start, End))
continue;
// Cannot evict non virtual reg interference.
- if (!Register::isVirtualRegister(Intf->reg()))
+ if (!Register::isVirtualRegister(Intf->reg()))
return false;
// Never evict spill products. They cannot split or spill.
if (getStage(*Intf) == RS_Done)
return false;
// Would this break a satisfied hint?
- bool BreaksHint = VRM->hasPreferredPhys(Intf->reg());
+ bool BreaksHint = VRM->hasPreferredPhys(Intf->reg());
// Update eviction cost.
Cost.BrokenHints += BreaksHint;
- Cost.MaxWeight = std::max(Cost.MaxWeight, Intf->weight());
+ Cost.MaxWeight = std::max(Cost.MaxWeight, Intf->weight());
// Abort if this would be too expensive.
if (!(Cost < MaxCost))
return false;
@@ -1026,17 +1026,17 @@ bool RAGreedy::canEvictInterferenceInRange(LiveInterval &VirtReg,
/// \param BestEvictweight The eviction cost of that eviction
/// \return The PhysReg which is the best candidate for eviction and the
/// eviction cost in BestEvictweight
-MCRegister RAGreedy::getCheapestEvicteeWeight(const AllocationOrder &Order,
- LiveInterval &VirtReg,
- SlotIndex Start, SlotIndex End,
- float *BestEvictweight) {
+MCRegister RAGreedy::getCheapestEvicteeWeight(const AllocationOrder &Order,
+ LiveInterval &VirtReg,
+ SlotIndex Start, SlotIndex End,
+ float *BestEvictweight) {
EvictionCost BestEvictCost;
BestEvictCost.setMax();
- BestEvictCost.MaxWeight = VirtReg.weight();
- MCRegister BestEvicteePhys;
+ BestEvictCost.MaxWeight = VirtReg.weight();
+ MCRegister BestEvicteePhys;
// Go over all physical registers and find the best candidate for eviction
- for (MCRegister PhysReg : Order.getOrder()) {
+ for (MCRegister PhysReg : Order.getOrder()) {
if (!canEvictInterferenceInRange(VirtReg, PhysReg, Start, End,
BestEvictCost))
@@ -1052,14 +1052,14 @@ MCRegister RAGreedy::getCheapestEvicteeWeight(const AllocationOrder &Order,
/// evictInterference - Evict any interferring registers that prevent VirtReg
/// from being assigned to Physreg. This assumes that canEvictInterference
/// returned true.
-void RAGreedy::evictInterference(LiveInterval &VirtReg, MCRegister PhysReg,
+void RAGreedy::evictInterference(LiveInterval &VirtReg, MCRegister PhysReg,
SmallVectorImpl<Register> &NewVRegs) {
// Make sure that VirtReg has a cascade number, and assign that cascade
// number to every evicted register. These live ranges than then only be
// evicted by a newer cascade, preventing infinite loops.
- unsigned Cascade = ExtraRegInfo[VirtReg.reg()].Cascade;
+ unsigned Cascade = ExtraRegInfo[VirtReg.reg()].Cascade;
if (!Cascade)
- Cascade = ExtraRegInfo[VirtReg.reg()].Cascade = NextCascade++;
+ Cascade = ExtraRegInfo[VirtReg.reg()].Cascade = NextCascade++;
LLVM_DEBUG(dbgs() << "evicting " << printReg(PhysReg, TRI)
<< " interference: Cascade " << Cascade << '\n');
@@ -1078,20 +1078,20 @@ void RAGreedy::evictInterference(LiveInterval &VirtReg, MCRegister PhysReg,
}
// Evict them second. This will invalidate the queries.
- for (LiveInterval *Intf : Intfs) {
+ for (LiveInterval *Intf : Intfs) {
// The same VirtReg may be present in multiple RegUnits. Skip duplicates.
- if (!VRM->hasPhys(Intf->reg()))
+ if (!VRM->hasPhys(Intf->reg()))
continue;
- LastEvicted.addEviction(PhysReg, VirtReg.reg(), Intf->reg());
+ LastEvicted.addEviction(PhysReg, VirtReg.reg(), Intf->reg());
Matrix->unassign(*Intf);
- assert((ExtraRegInfo[Intf->reg()].Cascade < Cascade ||
+ assert((ExtraRegInfo[Intf->reg()].Cascade < Cascade ||
VirtReg.isSpillable() < Intf->isSpillable()) &&
"Cannot decrease cascade number, illegal eviction");
- ExtraRegInfo[Intf->reg()].Cascade = Cascade;
+ ExtraRegInfo[Intf->reg()].Cascade = Cascade;
++NumEvicted;
- NewVRegs.push_back(Intf->reg());
+ NewVRegs.push_back(Intf->reg());
}
}
@@ -1120,17 +1120,17 @@ unsigned RAGreedy::tryEvict(LiveInterval &VirtReg,
// Keep track of the cheapest interference seen so far.
EvictionCost BestCost;
BestCost.setMax();
- MCRegister BestPhys;
+ MCRegister BestPhys;
unsigned OrderLimit = Order.getOrder().size();
// When we are just looking for a reduced cost per use, don't break any
// hints, and only evict smaller spill weights.
if (CostPerUseLimit < ~0u) {
BestCost.BrokenHints = 0;
- BestCost.MaxWeight = VirtReg.weight();
+ BestCost.MaxWeight = VirtReg.weight();
// Check of any registers in RC are below CostPerUseLimit.
- const TargetRegisterClass *RC = MRI->getRegClass(VirtReg.reg());
+ const TargetRegisterClass *RC = MRI->getRegClass(VirtReg.reg());
unsigned MinCost = RegClassInfo.getMinCost(RC);
if (MinCost >= CostPerUseLimit) {
LLVM_DEBUG(dbgs() << TRI->getRegClassName(RC) << " minimum cost = "
@@ -1147,10 +1147,10 @@ unsigned RAGreedy::tryEvict(LiveInterval &VirtReg,
}
}
- for (auto I = Order.begin(), E = Order.getOrderLimitEnd(OrderLimit); I != E;
- ++I) {
- MCRegister PhysReg = *I;
- assert(PhysReg);
+ for (auto I = Order.begin(), E = Order.getOrderLimitEnd(OrderLimit); I != E;
+ ++I) {
+ MCRegister PhysReg = *I;
+ assert(PhysReg);
if (TRI->getCostPerUse(PhysReg) >= CostPerUseLimit)
continue;
// The first use of a callee-saved register in a function has cost 1.
@@ -1171,7 +1171,7 @@ unsigned RAGreedy::tryEvict(LiveInterval &VirtReg,
BestPhys = PhysReg;
// Stop if the hint can be used.
- if (I.isHint())
+ if (I.isHint())
break;
}
@@ -1198,9 +1198,9 @@ bool RAGreedy::addSplitConstraints(InterferenceCache::Cursor Intf,
// Reset interference dependent info.
SplitConstraints.resize(UseBlocks.size());
BlockFrequency StaticCost = 0;
- for (unsigned I = 0; I != UseBlocks.size(); ++I) {
- const SplitAnalysis::BlockInfo &BI = UseBlocks[I];
- SpillPlacement::BlockConstraint &BC = SplitConstraints[I];
+ for (unsigned I = 0; I != UseBlocks.size(); ++I) {
+ const SplitAnalysis::BlockInfo &BI = UseBlocks[I];
+ SpillPlacement::BlockConstraint &BC = SplitConstraints[I];
BC.Number = BI.MBB->getNumber();
Intf.moveToBlock(BC.Number);
@@ -1271,7 +1271,7 @@ bool RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf,
unsigned TBS[GroupSize];
unsigned B = 0, T = 0;
- for (unsigned Number : Blocks) {
+ for (unsigned Number : Blocks) {
Intf.moveToBlock(Number);
if (!Intf.hasInterference()) {
@@ -1328,7 +1328,7 @@ bool RAGreedy::growRegion(GlobalSplitCandidate &Cand) {
while (true) {
ArrayRef<unsigned> NewBundles = SpillPlacer->getRecentPositive();
// Find new through blocks in the periphery of PrefRegBundles.
- for (unsigned Bundle : NewBundles) {
+ for (unsigned Bundle : NewBundles) {
// Look at all blocks connected to Bundle in the full graph.
ArrayRef<unsigned> Blocks = Bundles->getBlocks(Bundle);
for (ArrayRef<unsigned>::iterator I = Blocks.begin(), E = Blocks.end();
@@ -1380,7 +1380,7 @@ bool RAGreedy::calcCompactRegion(GlobalSplitCandidate &Cand) {
return false;
// Compact regions don't correspond to any physreg.
- Cand.reset(IntfCache, MCRegister::NoRegister);
+ Cand.reset(IntfCache, MCRegister::NoRegister);
LLVM_DEBUG(dbgs() << "Compact region bundles");
@@ -1408,8 +1408,8 @@ bool RAGreedy::calcCompactRegion(GlobalSplitCandidate &Cand) {
}
LLVM_DEBUG({
- for (int I : Cand.LiveBundles.set_bits())
- dbgs() << " EB#" << I;
+ for (int I : Cand.LiveBundles.set_bits())
+ dbgs() << " EB#" << I;
dbgs() << ".\n";
});
return true;
@@ -1420,7 +1420,7 @@ bool RAGreedy::calcCompactRegion(GlobalSplitCandidate &Cand) {
BlockFrequency RAGreedy::calcSpillCost() {
BlockFrequency Cost = 0;
ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA->getUseBlocks();
- for (const SplitAnalysis::BlockInfo &BI : UseBlocks) {
+ for (const SplitAnalysis::BlockInfo &BI : UseBlocks) {
unsigned Number = BI.MBB->getNumber();
// We normally only need one spill instruction - a load or a store.
Cost += SpillPlacer->getBlockFrequency(Number);
@@ -1485,20 +1485,20 @@ BlockFrequency RAGreedy::calcSpillCost() {
/// artifact of Evictee.
/// \return True if splitting Evictee may cause a bad eviction chain, false
/// otherwise.
-bool RAGreedy::splitCanCauseEvictionChain(Register Evictee,
+bool RAGreedy::splitCanCauseEvictionChain(Register Evictee,
GlobalSplitCandidate &Cand,
unsigned BBNumber,
const AllocationOrder &Order) {
EvictionTrack::EvictorInfo VregEvictorInfo = LastEvicted.getEvictor(Evictee);
unsigned Evictor = VregEvictorInfo.first;
- MCRegister PhysReg = VregEvictorInfo.second;
+ MCRegister PhysReg = VregEvictorInfo.second;
// No actual evictor.
if (!Evictor || !PhysReg)
return false;
float MaxWeight = 0;
- MCRegister FutureEvictedPhysReg =
+ MCRegister FutureEvictedPhysReg =
getCheapestEvicteeWeight(Order, LIS->getInterval(Evictee),
Cand.Intf.first(), Cand.Intf.last(), &MaxWeight);
@@ -1524,8 +1524,8 @@ bool RAGreedy::splitCanCauseEvictionChain(Register Evictee,
// expensive enough to evict somebody If so, this may cause a bad eviction
// chain.
float splitArtifactWeight =
- VRAI->futureWeight(LIS->getInterval(Evictee),
- Cand.Intf.first().getPrevIndex(), Cand.Intf.last());
+ VRAI->futureWeight(LIS->getInterval(Evictee),
+ Cand.Intf.first().getPrevIndex(), Cand.Intf.last());
if (splitArtifactWeight >= 0 && splitArtifactWeight < MaxWeight)
return false;
@@ -1559,15 +1559,15 @@ bool RAGreedy::splitCanCauseLocalSpill(unsigned VirtRegToSplit,
// Check if the local interval will evict a cheaper interval.
float CheapestEvictWeight = 0;
- MCRegister FutureEvictedPhysReg = getCheapestEvicteeWeight(
+ MCRegister FutureEvictedPhysReg = getCheapestEvicteeWeight(
Order, LIS->getInterval(VirtRegToSplit), Cand.Intf.first(),
Cand.Intf.last(), &CheapestEvictWeight);
// Have we found an interval that can be evicted?
if (FutureEvictedPhysReg) {
float splitArtifactWeight =
- VRAI->futureWeight(LIS->getInterval(VirtRegToSplit),
- Cand.Intf.first().getPrevIndex(), Cand.Intf.last());
+ VRAI->futureWeight(LIS->getInterval(VirtRegToSplit),
+ Cand.Intf.first().getPrevIndex(), Cand.Intf.last());
// Will the weight of the local interval be higher than the cheapest evictee
// weight? If so it will evict it and will not cause a spill.
if (splitArtifactWeight >= 0 && splitArtifactWeight > CheapestEvictWeight)
@@ -1588,11 +1588,11 @@ BlockFrequency RAGreedy::calcGlobalSplitCost(GlobalSplitCandidate &Cand,
bool *CanCauseEvictionChain) {
BlockFrequency GlobalCost = 0;
const BitVector &LiveBundles = Cand.LiveBundles;
- Register VirtRegToSplit = SA->getParent().reg();
+ Register VirtRegToSplit = SA->getParent().reg();
ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA->getUseBlocks();
- for (unsigned I = 0; I != UseBlocks.size(); ++I) {
- const SplitAnalysis::BlockInfo &BI = UseBlocks[I];
- SpillPlacement::BlockConstraint &BC = SplitConstraints[I];
+ for (unsigned I = 0; I != UseBlocks.size(); ++I) {
+ const SplitAnalysis::BlockInfo &BI = UseBlocks[I];
+ SpillPlacement::BlockConstraint &BC = SplitConstraints[I];
bool RegIn = LiveBundles[Bundles->getBundle(BC.Number, false)];
bool RegOut = LiveBundles[Bundles->getBundle(BC.Number, true)];
unsigned Ins = 0;
@@ -1630,7 +1630,7 @@ BlockFrequency RAGreedy::calcGlobalSplitCost(GlobalSplitCandidate &Cand,
GlobalCost += SpillPlacer->getBlockFrequency(BC.Number);
}
- for (unsigned Number : Cand.ActiveBlocks) {
+ for (unsigned Number : Cand.ActiveBlocks) {
bool RegIn = LiveBundles[Bundles->getBundle(Number, false)];
bool RegOut = LiveBundles[Bundles->getBundle(Number, true)];
if (!RegIn && !RegOut)
@@ -1688,12 +1688,12 @@ void RAGreedy::splitAroundRegion(LiveRangeEdit &LREdit,
// Isolate even single instructions when dealing with a proper sub-class.
// That guarantees register class inflation for the stack interval because it
// is all copies.
- Register Reg = SA->getParent().reg();
+ Register Reg = SA->getParent().reg();
bool SingleInstrs = RegClassInfo.isProperSubClass(MRI->getRegClass(Reg));
// First handle all the blocks with uses.
ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA->getUseBlocks();
- for (const SplitAnalysis::BlockInfo &BI : UseBlocks) {
+ for (const SplitAnalysis::BlockInfo &BI : UseBlocks) {
unsigned Number = BI.MBB->getNumber();
unsigned IntvIn = 0, IntvOut = 0;
SlotIndex IntfIn, IntfOut;
@@ -1738,7 +1738,7 @@ void RAGreedy::splitAroundRegion(LiveRangeEdit &LREdit,
BitVector Todo = SA->getThroughBlocks();
for (unsigned c = 0; c != UsedCands.size(); ++c) {
ArrayRef<unsigned> Blocks = GlobalCand[UsedCands[c]].ActiveBlocks;
- for (unsigned Number : Blocks) {
+ for (unsigned Number : Blocks) {
if (!Todo.test(Number))
continue;
Todo.reset(Number);
@@ -1781,8 +1781,8 @@ void RAGreedy::splitAroundRegion(LiveRangeEdit &LREdit,
// - Candidate intervals can be assigned to Cand.PhysReg.
// - Block-local splits are candidates for local splitting.
// - DCE leftovers should go back on the queue.
- for (unsigned I = 0, E = LREdit.size(); I != E; ++I) {
- LiveInterval &Reg = LIS->getInterval(LREdit.get(I));
+ for (unsigned I = 0, E = LREdit.size(); I != E; ++I) {
+ LiveInterval &Reg = LIS->getInterval(LREdit.get(I));
// Ignore old intervals from DCE.
if (getStage(Reg) != RS_New)
@@ -1790,14 +1790,14 @@ void RAGreedy::splitAroundRegion(LiveRangeEdit &LREdit,
// Remainder interval. Don't try splitting again, spill if it doesn't
// allocate.
- if (IntvMap[I] == 0) {
+ if (IntvMap[I] == 0) {
setStage(Reg, RS_Spill);
continue;
}
// Global intervals. Allow repeated splitting as long as the number of live
// blocks is strictly decreasing.
- if (IntvMap[I] < NumGlobalIntvs) {
+ if (IntvMap[I] < NumGlobalIntvs) {
if (SA->countLiveBlocks(&Reg) >= OrigBlocks) {
LLVM_DEBUG(dbgs() << "Main interval covers the same " << OrigBlocks
<< " blocks as original.\n");
@@ -1815,11 +1815,11 @@ void RAGreedy::splitAroundRegion(LiveRangeEdit &LREdit,
MF->verify(this, "After splitting live range around region");
}
-MCRegister RAGreedy::tryRegionSplit(LiveInterval &VirtReg,
- AllocationOrder &Order,
- SmallVectorImpl<Register> &NewVRegs) {
+MCRegister RAGreedy::tryRegionSplit(LiveInterval &VirtReg,
+ AllocationOrder &Order,
+ SmallVectorImpl<Register> &NewVRegs) {
if (!TRI->shouldRegionSplitForVirtReg(*MF, VirtReg))
- return MCRegister::NoRegister;
+ return MCRegister::NoRegister;
unsigned NumCands = 0;
BlockFrequency SpillCost = calcSpillCost();
BlockFrequency BestCost;
@@ -1849,12 +1849,12 @@ MCRegister RAGreedy::tryRegionSplit(LiveInterval &VirtReg,
// current max frequency.
if (HasCompact && (BestCost > SpillCost) && (BestCand != NoCand) &&
CanCauseEvictionChain) {
- return MCRegister::NoRegister;
+ return MCRegister::NoRegister;
}
// No solutions found, fall back to single block splitting.
if (!HasCompact && BestCand == NoCand)
- return MCRegister::NoRegister;
+ return MCRegister::NoRegister;
return doRegionSplit(VirtReg, BestCand, HasCompact, NewVRegs);
}
@@ -1865,8 +1865,8 @@ unsigned RAGreedy::calculateRegionSplitCost(LiveInterval &VirtReg,
unsigned &NumCands, bool IgnoreCSR,
bool *CanCauseEvictionChain) {
unsigned BestCand = NoCand;
- for (MCPhysReg PhysReg : Order) {
- assert(PhysReg);
+ for (MCPhysReg PhysReg : Order) {
+ assert(PhysReg);
if (IgnoreCSR && isUnusedCalleeSavedReg(PhysReg))
continue;
@@ -1875,12 +1875,12 @@ unsigned RAGreedy::calculateRegionSplitCost(LiveInterval &VirtReg,
if (NumCands == IntfCache.getMaxCursors()) {
unsigned WorstCount = ~0u;
unsigned Worst = 0;
- for (unsigned CandIndex = 0; CandIndex != NumCands; ++CandIndex) {
- if (CandIndex == BestCand || !GlobalCand[CandIndex].PhysReg)
+ for (unsigned CandIndex = 0; CandIndex != NumCands; ++CandIndex) {
+ if (CandIndex == BestCand || !GlobalCand[CandIndex].PhysReg)
continue;
- unsigned Count = GlobalCand[CandIndex].LiveBundles.count();
+ unsigned Count = GlobalCand[CandIndex].LiveBundles.count();
if (Count < WorstCount) {
- Worst = CandIndex;
+ Worst = CandIndex;
WorstCount = Count;
}
}
@@ -1931,8 +1931,8 @@ unsigned RAGreedy::calculateRegionSplitCost(LiveInterval &VirtReg,
LLVM_DEBUG({
dbgs() << ", total = ";
MBFI->printBlockFreq(dbgs(), Cost) << " with bundles";
- for (int I : Cand.LiveBundles.set_bits())
- dbgs() << " EB#" << I;
+ for (int I : Cand.LiveBundles.set_bits())
+ dbgs() << " EB#" << I;
dbgs() << ".\n";
});
if (Cost < BestCost) {
@@ -1950,7 +1950,7 @@ unsigned RAGreedy::calculateRegionSplitCost(LiveInterval &VirtReg,
// See splitCanCauseEvictionChain for detailed description of bad
// eviction chain scenarios.
LLVM_DEBUG(dbgs() << "Best split candidate of vreg "
- << printReg(VirtReg.reg(), TRI) << " may ");
+ << printReg(VirtReg.reg(), TRI) << " may ");
if (!(*CanCauseEvictionChain))
LLVM_DEBUG(dbgs() << "not ");
LLVM_DEBUG(dbgs() << "cause bad eviction chain\n");
@@ -2009,12 +2009,12 @@ unsigned RAGreedy::doRegionSplit(LiveInterval &VirtReg, unsigned BestCand,
unsigned RAGreedy::tryBlockSplit(LiveInterval &VirtReg, AllocationOrder &Order,
SmallVectorImpl<Register> &NewVRegs) {
assert(&SA->getParent() == &VirtReg && "Live range wasn't analyzed");
- Register Reg = VirtReg.reg();
+ Register Reg = VirtReg.reg();
bool SingleInstrs = RegClassInfo.isProperSubClass(MRI->getRegClass(Reg));
LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *LIS, VRM, this, &DeadRemats);
SE->reset(LREdit, SplitSpillMode);
ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA->getUseBlocks();
- for (const SplitAnalysis::BlockInfo &BI : UseBlocks) {
+ for (const SplitAnalysis::BlockInfo &BI : UseBlocks) {
if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
SE->splitSingleBlock(BI);
}
@@ -2033,9 +2033,9 @@ unsigned RAGreedy::tryBlockSplit(LiveInterval &VirtReg, AllocationOrder &Order,
// Sort out the new intervals created by splitting. The remainder interval
// goes straight to spilling, the new local ranges get to stay RS_New.
- for (unsigned I = 0, E = LREdit.size(); I != E; ++I) {
- LiveInterval &LI = LIS->getInterval(LREdit.get(I));
- if (getStage(LI) == RS_New && IntvMap[I] == 0)
+ for (unsigned I = 0, E = LREdit.size(); I != E; ++I) {
+ LiveInterval &LI = LIS->getInterval(LREdit.get(I));
+ if (getStage(LI) == RS_New && IntvMap[I] == 0)
setStage(LI, RS_Spill);
}
@@ -2051,7 +2051,7 @@ unsigned RAGreedy::tryBlockSplit(LiveInterval &VirtReg, AllocationOrder &Order,
/// Get the number of allocatable registers that match the constraints of \p Reg
/// on \p MI and that are also in \p SuperRC.
static unsigned getNumAllocatableRegsForConstraints(
- const MachineInstr *MI, Register Reg, const TargetRegisterClass *SuperRC,
+ const MachineInstr *MI, Register Reg, const TargetRegisterClass *SuperRC,
const TargetInstrInfo *TII, const TargetRegisterInfo *TRI,
const RegisterClassInfo &RCI) {
assert(SuperRC && "Invalid register class");
@@ -2074,7 +2074,7 @@ static unsigned getNumAllocatableRegsForConstraints(
unsigned
RAGreedy::tryInstructionSplit(LiveInterval &VirtReg, AllocationOrder &Order,
SmallVectorImpl<Register> &NewVRegs) {
- const TargetRegisterClass *CurRC = MRI->getRegClass(VirtReg.reg());
+ const TargetRegisterClass *CurRC = MRI->getRegClass(VirtReg.reg());
// There is no point to this if there are no larger sub-classes.
if (!RegClassInfo.isProperSubClass(CurRC))
return 0;
@@ -2098,18 +2098,18 @@ RAGreedy::tryInstructionSplit(LiveInterval &VirtReg, AllocationOrder &Order,
// the constraints on the virtual register.
// Otherwise, splitting just inserts uncoalescable copies that do not help
// the allocation.
- for (const auto &Use : Uses) {
- if (const MachineInstr *MI = Indexes->getInstructionFromIndex(Use))
+ for (const auto &Use : Uses) {
+ if (const MachineInstr *MI = Indexes->getInstructionFromIndex(Use))
if (MI->isFullCopy() ||
SuperRCNumAllocatableRegs ==
- getNumAllocatableRegsForConstraints(MI, VirtReg.reg(), SuperRC,
- TII, TRI, RCI)) {
- LLVM_DEBUG(dbgs() << " skip:\t" << Use << '\t' << *MI);
+ getNumAllocatableRegsForConstraints(MI, VirtReg.reg(), SuperRC,
+ TII, TRI, RCI)) {
+ LLVM_DEBUG(dbgs() << " skip:\t" << Use << '\t' << *MI);
continue;
}
SE->openIntv();
- SlotIndex SegStart = SE->enterIntvBefore(Use);
- SlotIndex SegStop = SE->leaveIntvAfter(Use);
+ SlotIndex SegStart = SE->enterIntvBefore(Use);
+ SlotIndex SegStop = SE->leaveIntvAfter(Use);
SE->useIntv(SegStart, SegStop);
}
@@ -2120,7 +2120,7 @@ RAGreedy::tryInstructionSplit(LiveInterval &VirtReg, AllocationOrder &Order,
SmallVector<unsigned, 8> IntvMap;
SE->finish(&IntvMap);
- DebugVars->splitRegister(VirtReg.reg(), LREdit.regs(), *LIS);
+ DebugVars->splitRegister(VirtReg.reg(), LREdit.regs(), *LIS);
ExtraRegInfo.resize(MRI->getNumVirtRegs());
// Assign all new registers to RS_Spill. This was the last chance.
@@ -2135,9 +2135,9 @@ RAGreedy::tryInstructionSplit(LiveInterval &VirtReg, AllocationOrder &Order,
/// calcGapWeights - Compute the maximum spill weight that needs to be evicted
/// in order to use PhysReg between two entries in SA->UseSlots.
///
-/// GapWeight[I] represents the gap between UseSlots[I] and UseSlots[I + 1].
+/// GapWeight[I] represents the gap between UseSlots[I] and UseSlots[I + 1].
///
-void RAGreedy::calcGapWeights(MCRegister PhysReg,
+void RAGreedy::calcGapWeights(MCRegister PhysReg,
SmallVectorImpl<float> &GapWeight) {
assert(SA->getUseBlocks().size() == 1 && "Not a local interval");
const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
@@ -2176,7 +2176,7 @@ void RAGreedy::calcGapWeights(MCRegister PhysReg,
break;
// Update the gaps covered by IntI.
- const float weight = IntI.value()->weight();
+ const float weight = IntI.value()->weight();
for (; Gap != NumGaps; ++Gap) {
GapWeight[Gap] = std::max(GapWeight[Gap], weight);
if (Uses[Gap+1].getBaseIndex() >= IntI.stop())
@@ -2238,8 +2238,8 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order,
LLVM_DEBUG({
dbgs() << "tryLocalSplit: ";
- for (const auto &Use : Uses)
- dbgs() << ' ' << Use;
+ for (const auto &Use : Uses)
+ dbgs() << ' ' << Use;
dbgs() << '\n';
});
@@ -2251,25 +2251,25 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order,
ArrayRef<SlotIndex> RMS = LIS->getRegMaskSlotsInBlock(BI.MBB->getNumber());
LLVM_DEBUG(dbgs() << RMS.size() << " regmasks in block:");
// Constrain to VirtReg's live range.
- unsigned RI =
+ unsigned RI =
llvm::lower_bound(RMS, Uses.front().getRegSlot()) - RMS.begin();
- unsigned RE = RMS.size();
- for (unsigned I = 0; I != NumGaps && RI != RE; ++I) {
- // Look for Uses[I] <= RMS <= Uses[I + 1].
- assert(!SlotIndex::isEarlierInstr(RMS[RI], Uses[I]));
- if (SlotIndex::isEarlierInstr(Uses[I + 1], RMS[RI]))
+ unsigned RE = RMS.size();
+ for (unsigned I = 0; I != NumGaps && RI != RE; ++I) {
+ // Look for Uses[I] <= RMS <= Uses[I + 1].
+ assert(!SlotIndex::isEarlierInstr(RMS[RI], Uses[I]));
+ if (SlotIndex::isEarlierInstr(Uses[I + 1], RMS[RI]))
continue;
// Skip a regmask on the same instruction as the last use. It doesn't
// overlap the live range.
- if (SlotIndex::isSameInstr(Uses[I + 1], RMS[RI]) && I + 1 == NumGaps)
+ if (SlotIndex::isSameInstr(Uses[I + 1], RMS[RI]) && I + 1 == NumGaps)
break;
- LLVM_DEBUG(dbgs() << ' ' << RMS[RI] << ':' << Uses[I] << '-'
- << Uses[I + 1]);
- RegMaskGaps.push_back(I);
+ LLVM_DEBUG(dbgs() << ' ' << RMS[RI] << ':' << Uses[I] << '-'
+ << Uses[I + 1]);
+ RegMaskGaps.push_back(I);
// Advance ri to the next gap. A regmask on one of the uses counts in
// both gaps.
- while (RI != RE && SlotIndex::isEarlierInstr(RMS[RI], Uses[I + 1]))
- ++RI;
+ while (RI != RE && SlotIndex::isEarlierInstr(RMS[RI], Uses[I + 1]))
+ ++RI;
}
LLVM_DEBUG(dbgs() << '\n');
}
@@ -2304,16 +2304,16 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order,
(1.0f / MBFI->getEntryFreq());
SmallVector<float, 8> GapWeight;
- for (MCPhysReg PhysReg : Order) {
- assert(PhysReg);
+ for (MCPhysReg PhysReg : Order) {
+ assert(PhysReg);
// Keep track of the largest spill weight that would need to be evicted in
- // order to make use of PhysReg between UseSlots[I] and UseSlots[I + 1].
+ // order to make use of PhysReg between UseSlots[I] and UseSlots[I + 1].
calcGapWeights(PhysReg, GapWeight);
// Remove any gaps with regmask clobbers.
if (Matrix->checkRegMaskInterference(VirtReg, PhysReg))
- for (unsigned I = 0, E = RegMaskGaps.size(); I != E; ++I)
- GapWeight[RegMaskGaps[I]] = huge_valf;
+ for (unsigned I = 0, E = RegMaskGaps.size(); I != E; ++I)
+ GapWeight[RegMaskGaps[I]] = huge_valf;
// Try to find the best sequence of gaps to close.
// The new spill weight must be larger than any gap interference.
@@ -2331,7 +2331,7 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order,
const bool LiveAfter = SplitAfter != NumGaps || BI.LiveOut;
LLVM_DEBUG(dbgs() << printReg(PhysReg, TRI) << ' ' << Uses[SplitBefore]
- << '-' << Uses[SplitAfter] << " I=" << MaxGap);
+ << '-' << Uses[SplitAfter] << " I=" << MaxGap);
// Stop before the interval gets so big we wouldn't be making progress.
if (!LiveBefore && !LiveAfter) {
@@ -2380,8 +2380,8 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order,
// Recompute the max when necessary.
if (GapWeight[SplitBefore - 1] >= MaxGap) {
MaxGap = GapWeight[SplitBefore];
- for (unsigned I = SplitBefore + 1; I != SplitAfter; ++I)
- MaxGap = std::max(MaxGap, GapWeight[I]);
+ for (unsigned I = SplitBefore + 1; I != SplitAfter; ++I)
+ MaxGap = std::max(MaxGap, GapWeight[I]);
}
continue;
}
@@ -2416,7 +2416,7 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order,
SE->useIntv(SegStart, SegStop);
SmallVector<unsigned, 8> IntvMap;
SE->finish(&IntvMap);
- DebugVars->splitRegister(VirtReg.reg(), LREdit.regs(), *LIS);
+ DebugVars->splitRegister(VirtReg.reg(), LREdit.regs(), *LIS);
// If the new range has the same number of instructions as before, mark it as
// RS_Split2 so the next split will be forced to make progress. Otherwise,
@@ -2427,10 +2427,10 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order,
if (NewGaps >= NumGaps) {
LLVM_DEBUG(dbgs() << "Tagging non-progress ranges: ");
assert(!ProgressRequired && "Didn't make progress when it was required.");
- for (unsigned I = 0, E = IntvMap.size(); I != E; ++I)
- if (IntvMap[I] == 1) {
- setStage(LIS->getInterval(LREdit.get(I)), RS_Split2);
- LLVM_DEBUG(dbgs() << printReg(LREdit.get(I)));
+ for (unsigned I = 0, E = IntvMap.size(); I != E; ++I)
+ if (IntvMap[I] == 1) {
+ setStage(LIS->getInterval(LREdit.get(I)), RS_Split2);
+ LLVM_DEBUG(dbgs() << printReg(LREdit.get(I)));
}
LLVM_DEBUG(dbgs() << '\n');
}
@@ -2484,7 +2484,7 @@ unsigned RAGreedy::trySplit(LiveInterval &VirtReg, AllocationOrder &Order,
// ranges already made dubious progress with region splitting, so they go
// straight to single block splitting.
if (getStage(VirtReg) < RS_Split2) {
- MCRegister PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs);
+ MCRegister PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs);
if (PhysReg || !NewVRegs.empty())
return PhysReg;
}
@@ -2514,10 +2514,10 @@ static bool hasTiedDef(MachineRegisterInfo *MRI, unsigned reg) {
/// for \p VirtReg.
/// \p FixedRegisters contains all the virtual registers that cannot be
/// recolored.
-bool RAGreedy::mayRecolorAllInterferences(
- MCRegister PhysReg, LiveInterval &VirtReg, SmallLISet &RecoloringCandidates,
- const SmallVirtRegSet &FixedRegisters) {
- const TargetRegisterClass *CurRC = MRI->getRegClass(VirtReg.reg());
+bool RAGreedy::mayRecolorAllInterferences(
+ MCRegister PhysReg, LiveInterval &VirtReg, SmallLISet &RecoloringCandidates,
+ const SmallVirtRegSet &FixedRegisters) {
+ const TargetRegisterClass *CurRC = MRI->getRegClass(VirtReg.reg());
for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, *Units);
@@ -2529,16 +2529,16 @@ bool RAGreedy::mayRecolorAllInterferences(
CutOffInfo |= CO_Interf;
return false;
}
- for (LiveInterval *Intf : reverse(Q.interferingVRegs())) {
+ for (LiveInterval *Intf : reverse(Q.interferingVRegs())) {
// If Intf is done and sit on the same register class as VirtReg,
// it would not be recolorable as it is in the same state as VirtReg.
// However, if VirtReg has tied defs and Intf doesn't, then
// there is still a point in examining if it can be recolorable.
if (((getStage(*Intf) == RS_Done &&
- MRI->getRegClass(Intf->reg()) == CurRC) &&
- !(hasTiedDef(MRI, VirtReg.reg()) &&
- !hasTiedDef(MRI, Intf->reg()))) ||
- FixedRegisters.count(Intf->reg())) {
+ MRI->getRegClass(Intf->reg()) == CurRC) &&
+ !(hasTiedDef(MRI, VirtReg.reg()) &&
+ !hasTiedDef(MRI, Intf->reg()))) ||
+ FixedRegisters.count(Intf->reg())) {
LLVM_DEBUG(
dbgs() << "Early abort: the interference is not recolorable.\n");
return false;
@@ -2593,9 +2593,9 @@ unsigned RAGreedy::tryLastChanceRecoloring(LiveInterval &VirtReg,
SmallVectorImpl<Register> &NewVRegs,
SmallVirtRegSet &FixedRegisters,
unsigned Depth) {
- if (!TRI->shouldUseLastChanceRecoloringForVirtReg(*MF, VirtReg))
- return ~0u;
-
+ if (!TRI->shouldUseLastChanceRecoloringForVirtReg(*MF, VirtReg))
+ return ~0u;
+
LLVM_DEBUG(dbgs() << "Try last chance recoloring for " << VirtReg << '\n');
// Ranges must be Done.
assert((getStage(VirtReg) >= RS_Done || !VirtReg.isSpillable()) &&
@@ -2614,15 +2614,15 @@ unsigned RAGreedy::tryLastChanceRecoloring(LiveInterval &VirtReg,
SmallLISet RecoloringCandidates;
// Record the original mapping virtual register to physical register in case
// the recoloring fails.
- DenseMap<Register, MCRegister> VirtRegToPhysReg;
+ DenseMap<Register, MCRegister> VirtRegToPhysReg;
// Mark VirtReg as fixed, i.e., it will not be recolored pass this point in
// this recoloring "session".
- assert(!FixedRegisters.count(VirtReg.reg()));
- FixedRegisters.insert(VirtReg.reg());
+ assert(!FixedRegisters.count(VirtReg.reg()));
+ FixedRegisters.insert(VirtReg.reg());
SmallVector<Register, 4> CurrentNewVRegs;
- for (MCRegister PhysReg : Order) {
- assert(PhysReg.isValid());
+ for (MCRegister PhysReg : Order) {
+ assert(PhysReg.isValid());
LLVM_DEBUG(dbgs() << "Try to assign: " << VirtReg << " to "
<< printReg(PhysReg, TRI) << '\n');
RecoloringCandidates.clear();
@@ -2653,7 +2653,7 @@ unsigned RAGreedy::tryLastChanceRecoloring(LiveInterval &VirtReg,
for (SmallLISet::iterator It = RecoloringCandidates.begin(),
EndIt = RecoloringCandidates.end();
It != EndIt; ++It) {
- Register ItVirtReg = (*It)->reg();
+ Register ItVirtReg = (*It)->reg();
enqueue(RecoloringQueue, *It);
assert(VRM->hasPhys(ItVirtReg) &&
"Interferences are supposed to be with allocated variables");
@@ -2706,10 +2706,10 @@ unsigned RAGreedy::tryLastChanceRecoloring(LiveInterval &VirtReg,
for (SmallLISet::iterator It = RecoloringCandidates.begin(),
EndIt = RecoloringCandidates.end();
It != EndIt; ++It) {
- Register ItVirtReg = (*It)->reg();
+ Register ItVirtReg = (*It)->reg();
if (VRM->hasPhys(ItVirtReg))
Matrix->unassign(**It);
- MCRegister ItPhysReg = VirtRegToPhysReg[ItVirtReg];
+ MCRegister ItPhysReg = VirtRegToPhysReg[ItVirtReg];
Matrix->assign(**It, ItPhysReg);
}
}
@@ -2733,8 +2733,8 @@ bool RAGreedy::tryRecoloringCandidates(PQueue &RecoloringQueue,
while (!RecoloringQueue.empty()) {
LiveInterval *LI = dequeue(RecoloringQueue);
LLVM_DEBUG(dbgs() << "Try to recolor: " << *LI << '\n');
- MCRegister PhysReg =
- selectOrSplitImpl(*LI, NewVRegs, FixedRegisters, Depth + 1);
+ MCRegister PhysReg =
+ selectOrSplitImpl(*LI, NewVRegs, FixedRegisters, Depth + 1);
// When splitting happens, the live-range may actually be empty.
// In that case, this is okay to continue the recoloring even
// if we did not find an alternative color for it. Indeed,
@@ -2752,7 +2752,7 @@ bool RAGreedy::tryRecoloringCandidates(PQueue &RecoloringQueue,
<< " succeeded with: " << printReg(PhysReg, TRI) << '\n');
Matrix->assign(*LI, PhysReg);
- FixedRegisters.insert(LI->reg());
+ FixedRegisters.insert(LI->reg());
}
return true;
}
@@ -2761,12 +2761,12 @@ bool RAGreedy::tryRecoloringCandidates(PQueue &RecoloringQueue,
// Main Entry Point
//===----------------------------------------------------------------------===//
-MCRegister RAGreedy::selectOrSplit(LiveInterval &VirtReg,
- SmallVectorImpl<Register> &NewVRegs) {
+MCRegister RAGreedy::selectOrSplit(LiveInterval &VirtReg,
+ SmallVectorImpl<Register> &NewVRegs) {
CutOffInfo = CO_None;
LLVMContext &Ctx = MF->getFunction().getContext();
SmallVirtRegSet FixedRegisters;
- MCRegister Reg = selectOrSplitImpl(VirtReg, NewVRegs, FixedRegisters);
+ MCRegister Reg = selectOrSplitImpl(VirtReg, NewVRegs, FixedRegisters);
if (Reg == ~0U && (CutOffInfo != CO_None)) {
uint8_t CutOffEncountered = CutOffInfo & (CO_Depth | CO_Interf);
if (CutOffEncountered == CO_Depth)
@@ -2791,10 +2791,10 @@ MCRegister RAGreedy::selectOrSplit(LiveInterval &VirtReg,
/// Spilling a live range in the cold path can have lower cost than using
/// the CSR for the first time. Returns the physical register if we decide
/// to use the CSR; otherwise return 0.
-MCRegister
-RAGreedy::tryAssignCSRFirstTime(LiveInterval &VirtReg, AllocationOrder &Order,
- MCRegister PhysReg, unsigned &CostPerUseLimit,
- SmallVectorImpl<Register> &NewVRegs) {
+MCRegister
+RAGreedy::tryAssignCSRFirstTime(LiveInterval &VirtReg, AllocationOrder &Order,
+ MCRegister PhysReg, unsigned &CostPerUseLimit,
+ SmallVectorImpl<Register> &NewVRegs) {
if (getStage(VirtReg) == RS_Spill && VirtReg.isSpillable()) {
// We choose spill over using the CSR for the first time if the spill cost
// is lower than CSRCost.
@@ -2859,7 +2859,7 @@ void RAGreedy::initializeCSRCost() {
/// Collect the hint info for \p Reg.
/// The results are stored into \p Out.
/// \p Out is not cleared before being populated.
-void RAGreedy::collectHintInfo(Register Reg, HintsInfo &Out) {
+void RAGreedy::collectHintInfo(Register Reg, HintsInfo &Out) {
for (const MachineInstr &Instr : MRI->reg_nodbg_instructions(Reg)) {
if (!Instr.isFullCopy())
continue;
@@ -2871,8 +2871,8 @@ void RAGreedy::collectHintInfo(Register Reg, HintsInfo &Out) {
continue;
}
// Get the current assignment.
- MCRegister OtherPhysReg =
- OtherReg.isPhysical() ? OtherReg.asMCReg() : VRM->getPhys(OtherReg);
+ MCRegister OtherPhysReg =
+ OtherReg.isPhysical() ? OtherReg.asMCReg() : VRM->getPhys(OtherReg);
// Push the collected information.
Out.push_back(HintInfo(MBFI->getBlockFreq(Instr.getParent()), OtherReg,
OtherPhysReg));
@@ -2883,7 +2883,7 @@ void RAGreedy::collectHintInfo(Register Reg, HintsInfo &Out) {
/// \p PhysReg was used.
/// \return The cost of \p List for \p PhysReg.
BlockFrequency RAGreedy::getBrokenHintFreq(const HintsInfo &List,
- MCRegister PhysReg) {
+ MCRegister PhysReg) {
BlockFrequency Cost = 0;
for (const HintInfo &Info : List) {
if (Info.PhysReg != PhysReg)
@@ -2904,11 +2904,11 @@ void RAGreedy::tryHintRecoloring(LiveInterval &VirtReg) {
// We have a broken hint, check if it is possible to fix it by
// reusing PhysReg for the copy-related live-ranges. Indeed, we evicted
// some register and PhysReg may be available for the other live-ranges.
- SmallSet<Register, 4> Visited;
+ SmallSet<Register, 4> Visited;
SmallVector<unsigned, 2> RecoloringCandidates;
HintsInfo Info;
- Register Reg = VirtReg.reg();
- MCRegister PhysReg = VRM->getPhys(Reg);
+ Register Reg = VirtReg.reg();
+ MCRegister PhysReg = VRM->getPhys(Reg);
// Start the recoloring algorithm from the input live-interval, then
// it will propagate to the ones that are copy-related with it.
Visited.insert(Reg);
@@ -2929,7 +2929,7 @@ void RAGreedy::tryHintRecoloring(LiveInterval &VirtReg) {
// Get the live interval mapped with this virtual register to be able
// to check for the interference with the new color.
LiveInterval &LI = LIS->getInterval(Reg);
- MCRegister CurrPhys = VRM->getPhys(Reg);
+ MCRegister CurrPhys = VRM->getPhys(Reg);
// Check that the new color matches the register class constraints and
// that it is free for this live range.
if (CurrPhys != PhysReg && (!MRI->getRegClass(Reg)->contains(PhysReg) ||
@@ -3010,35 +3010,35 @@ void RAGreedy::tryHintRecoloring(LiveInterval &VirtReg) {
/// getting rid of 2 copies.
void RAGreedy::tryHintsRecoloring() {
for (LiveInterval *LI : SetOfBrokenHints) {
- assert(Register::isVirtualRegister(LI->reg()) &&
+ assert(Register::isVirtualRegister(LI->reg()) &&
"Recoloring is possible only for virtual registers");
// Some dead defs may be around (e.g., because of debug uses).
// Ignore those.
- if (!VRM->hasPhys(LI->reg()))
+ if (!VRM->hasPhys(LI->reg()))
continue;
tryHintRecoloring(*LI);
}
}
-MCRegister RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg,
- SmallVectorImpl<Register> &NewVRegs,
- SmallVirtRegSet &FixedRegisters,
- unsigned Depth) {
+MCRegister RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg,
+ SmallVectorImpl<Register> &NewVRegs,
+ SmallVirtRegSet &FixedRegisters,
+ unsigned Depth) {
unsigned CostPerUseLimit = ~0u;
// First try assigning a free register.
- auto Order =
- AllocationOrder::create(VirtReg.reg(), *VRM, RegClassInfo, Matrix);
- if (MCRegister PhysReg =
- tryAssign(VirtReg, Order, NewVRegs, FixedRegisters)) {
+ auto Order =
+ AllocationOrder::create(VirtReg.reg(), *VRM, RegClassInfo, Matrix);
+ if (MCRegister PhysReg =
+ tryAssign(VirtReg, Order, NewVRegs, FixedRegisters)) {
// If VirtReg got an assignment, the eviction info is no longre relevant.
- LastEvicted.clearEvicteeInfo(VirtReg.reg());
+ LastEvicted.clearEvicteeInfo(VirtReg.reg());
// When NewVRegs is not empty, we may have made decisions such as evicting
// a virtual register, go with the earlier decisions and use the physical
// register.
if (CSRCost.getFrequency() && isUnusedCalleeSavedReg(PhysReg) &&
NewVRegs.empty()) {
- MCRegister CSRReg = tryAssignCSRFirstTime(VirtReg, Order, PhysReg,
- CostPerUseLimit, NewVRegs);
+ MCRegister CSRReg = tryAssignCSRFirstTime(VirtReg, Order, PhysReg,
+ CostPerUseLimit, NewVRegs);
if (CSRReg || !NewVRegs.empty())
// Return now if we decide to use a CSR or create new vregs due to
// pre-splitting.
@@ -3049,7 +3049,7 @@ MCRegister RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg,
LiveRangeStage Stage = getStage(VirtReg);
LLVM_DEBUG(dbgs() << StageName[Stage] << " Cascade "
- << ExtraRegInfo[VirtReg.reg()].Cascade << '\n');
+ << ExtraRegInfo[VirtReg.reg()].Cascade << '\n');
// Try to evict a less worthy live range, but only for ranges from the primary
// queue. The RS_Split ranges already failed to do this, and they should not
@@ -3058,7 +3058,7 @@ MCRegister RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg,
if (Register PhysReg =
tryEvict(VirtReg, Order, NewVRegs, CostPerUseLimit,
FixedRegisters)) {
- Register Hint = MRI->getSimpleHint(VirtReg.reg());
+ Register Hint = MRI->getSimpleHint(VirtReg.reg());
// If VirtReg has a hint and that hint is broken record this
// virtual register as a recoloring candidate for broken hint.
// Indeed, since we evicted a variable in its neighborhood it is
@@ -3068,7 +3068,7 @@ MCRegister RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg,
SetOfBrokenHints.insert(&VirtReg);
// If VirtReg eviction someone, the eviction info for it as an evictee is
// no longre relevant.
- LastEvicted.clearEvicteeInfo(VirtReg.reg());
+ LastEvicted.clearEvicteeInfo(VirtReg.reg());
return PhysReg;
}
@@ -3080,7 +3080,7 @@ MCRegister RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg,
if (Stage < RS_Split) {
setStage(VirtReg, RS_Split);
LLVM_DEBUG(dbgs() << "wait for second round\n");
- NewVRegs.push_back(VirtReg.reg());
+ NewVRegs.push_back(VirtReg.reg());
return 0;
}
@@ -3090,7 +3090,7 @@ MCRegister RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg,
Register PhysReg = trySplit(VirtReg, Order, NewVRegs, FixedRegisters);
if (PhysReg || (NewVRegs.size() - NewVRegSizeBefore)) {
// If VirtReg got split, the eviction info is no longer relevant.
- LastEvicted.clearEvicteeInfo(VirtReg.reg());
+ LastEvicted.clearEvicteeInfo(VirtReg.reg());
return PhysReg;
}
}
@@ -3102,16 +3102,16 @@ MCRegister RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg,
Depth);
// Finally spill VirtReg itself.
- if ((EnableDeferredSpilling ||
- TRI->shouldUseDeferredSpillingForVirtReg(*MF, VirtReg)) &&
- getStage(VirtReg) < RS_Memory) {
+ if ((EnableDeferredSpilling ||
+ TRI->shouldUseDeferredSpillingForVirtReg(*MF, VirtReg)) &&
+ getStage(VirtReg) < RS_Memory) {
// TODO: This is experimental and in particular, we do not model
// the live range splitting done by spilling correctly.
// We would need a deep integration with the spiller to do the
// right thing here. Anyway, that is still good for early testing.
setStage(VirtReg, RS_Memory);
LLVM_DEBUG(dbgs() << "Do as if this register is in memory\n");
- NewVRegs.push_back(VirtReg.reg());
+ NewVRegs.push_back(VirtReg.reg());
} else {
NamedRegionTimer T("spill", "Spiller", TimerGroupName,
TimerGroupDescription, TimePassesIsEnabled);
@@ -3122,7 +3122,7 @@ MCRegister RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg,
// Tell LiveDebugVariables about the new ranges. Ranges not being covered by
// the new regs are kept in LDV (still mapping to the old register), until
// we rewrite spilled locations in LDV at a later stage.
- DebugVars->splitRegister(VirtReg.reg(), LRE.regs(), *LIS);
+ DebugVars->splitRegister(VirtReg.reg(), LRE.regs(), *LIS);
if (VerifyEnabled)
MF->verify(this, "After spilling");
@@ -3241,10 +3241,10 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) {
initializeCSRCost();
- VRAI = std::make_unique<VirtRegAuxInfo>(*MF, *LIS, *VRM, *Loops, *MBFI);
+ VRAI = std::make_unique<VirtRegAuxInfo>(*MF, *LIS, *VRM, *Loops, *MBFI);
+
+ VRAI->calculateSpillWeightsAndHints();
- VRAI->calculateSpillWeightsAndHints();
-
LLVM_DEBUG(LIS->dump());
SA.reset(new SplitAnalysis(*VRM, *LIS, *Loops));
diff --git a/contrib/libs/llvm12/lib/CodeGen/RegAllocPBQP.cpp b/contrib/libs/llvm12/lib/CodeGen/RegAllocPBQP.cpp
index 422e29c8c3..7c5af1a0c5 100644
--- a/contrib/libs/llvm12/lib/CodeGen/RegAllocPBQP.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/RegAllocPBQP.cpp
@@ -140,13 +140,13 @@ public:
MachineFunctionProperties::Property::NoPHIs);
}
- MachineFunctionProperties getClearedProperties() const override {
- return MachineFunctionProperties().set(
- MachineFunctionProperties::Property::IsSSA);
- }
-
+ MachineFunctionProperties getClearedProperties() const override {
+ return MachineFunctionProperties().set(
+ MachineFunctionProperties::Property::IsSSA);
+ }
+
private:
- using RegSet = std::set<Register>;
+ using RegSet = std::set<Register>;
char *customPassID;
@@ -198,7 +198,7 @@ public:
for (auto NId : G.nodeIds()) {
PBQP::PBQPNum SpillCost =
- LIS.getInterval(G.getNodeMetadata(NId).getVReg()).weight();
+ LIS.getInterval(G.getNodeMetadata(NId).getVReg()).weight();
if (SpillCost == 0.0)
SpillCost = std::numeric_limits<PBQP::PBQPNum>::min();
else
@@ -230,9 +230,9 @@ private:
return false;
if (NRegs < MRegs)
- return D.contains(IKey(NRegs, MRegs));
+ return D.contains(IKey(NRegs, MRegs));
- return D.contains(IKey(MRegs, NRegs));
+ return D.contains(IKey(MRegs, NRegs));
}
void setDisjointAllowedRegs(const PBQPRAGraph &G, PBQPRAGraph::NodeId NId,
@@ -289,7 +289,7 @@ private:
// If two intervals end at the same point, we need a way to break the tie or
// the set will assume they're actually equal and refuse to insert a
// "duplicate". Just compare the vregs - fast and guaranteed unique.
- return std::get<0>(I1)->reg() < std::get<0>(I2)->reg();
+ return std::get<0>(I1)->reg() < std::get<0>(I2)->reg();
}
static bool isAtLastSegment(const IntervalInfo &I) {
@@ -330,7 +330,7 @@ public:
// Start by building the inactive set.
for (auto NId : G.nodeIds()) {
- Register VReg = G.getNodeMetadata(NId).getVReg();
+ Register VReg = G.getNodeMetadata(NId).getVReg();
LiveInterval &LI = LIS.getInterval(VReg);
assert(!LI.empty() && "PBQP graph contains node for empty interval");
Inactive.push(std::make_tuple(&LI, 0, NId));
@@ -412,9 +412,9 @@ private:
PBQPRAGraph::RawMatrix M(NRegs.size() + 1, MRegs.size() + 1, 0);
bool NodesInterfere = false;
for (unsigned I = 0; I != NRegs.size(); ++I) {
- MCRegister PRegN = NRegs[I];
+ MCRegister PRegN = NRegs[I];
for (unsigned J = 0; J != MRegs.size(); ++J) {
- MCRegister PRegM = MRegs[J];
+ MCRegister PRegM = MRegs[J];
if (TRI.regsOverlap(PRegN, PRegM)) {
M[I + 1][J + 1] = std::numeric_limits<PBQP::PBQPNum>::infinity();
NodesInterfere = true;
@@ -447,10 +447,10 @@ public:
if (!CP.setRegisters(&MI) || CP.getSrcReg() == CP.getDstReg())
continue;
- Register DstReg = CP.getDstReg();
- Register SrcReg = CP.getSrcReg();
+ Register DstReg = CP.getDstReg();
+ Register SrcReg = CP.getSrcReg();
- PBQP::PBQPNum CBenefit = MBFI.getBlockFreqRelativeToEntryBlock(&MBB);
+ PBQP::PBQPNum CBenefit = MBFI.getBlockFreqRelativeToEntryBlock(&MBB);
if (CP.isPhys()) {
if (!MF.getRegInfo().isAllocatable(DstReg))
@@ -462,7 +462,7 @@ public:
G.getNodeMetadata(NId).getAllowedRegs();
unsigned PRegOpt = 0;
- while (PRegOpt < Allowed.size() && Allowed[PRegOpt].id() != DstReg)
+ while (PRegOpt < Allowed.size() && Allowed[PRegOpt].id() != DstReg)
++PRegOpt;
if (PRegOpt < Allowed.size()) {
@@ -507,9 +507,9 @@ private:
assert(CostMat.getRows() == Allowed1.size() + 1 && "Size mismatch.");
assert(CostMat.getCols() == Allowed2.size() + 1 && "Size mismatch.");
for (unsigned I = 0; I != Allowed1.size(); ++I) {
- MCRegister PReg1 = Allowed1[I];
+ MCRegister PReg1 = Allowed1[I];
for (unsigned J = 0; J != Allowed2.size(); ++J) {
- MCRegister PReg2 = Allowed2[J];
+ MCRegister PReg2 = Allowed2[J];
if (PReg1 == PReg2)
CostMat[I + 1][J + 1] -= Benefit;
}
@@ -517,20 +517,20 @@ private:
}
};
-/// PBQP-specific implementation of weight normalization.
-class PBQPVirtRegAuxInfo final : public VirtRegAuxInfo {
- float normalize(float UseDefFreq, unsigned Size, unsigned NumInstr) override {
- // All intervals have a spill weight that is mostly proportional to the
- // number of uses, with uses in loops having a bigger weight.
- return NumInstr * VirtRegAuxInfo::normalize(UseDefFreq, Size, 1);
- }
-
-public:
- PBQPVirtRegAuxInfo(MachineFunction &MF, LiveIntervals &LIS, VirtRegMap &VRM,
- const MachineLoopInfo &Loops,
- const MachineBlockFrequencyInfo &MBFI)
- : VirtRegAuxInfo(MF, LIS, VRM, Loops, MBFI) {}
-};
+/// PBQP-specific implementation of weight normalization.
+class PBQPVirtRegAuxInfo final : public VirtRegAuxInfo {
+ float normalize(float UseDefFreq, unsigned Size, unsigned NumInstr) override {
+ // All intervals have a spill weight that is mostly proportional to the
+ // number of uses, with uses in loops having a bigger weight.
+ return NumInstr * VirtRegAuxInfo::normalize(UseDefFreq, Size, 1);
+ }
+
+public:
+ PBQPVirtRegAuxInfo(MachineFunction &MF, LiveIntervals &LIS, VirtRegMap &VRM,
+ const MachineLoopInfo &Loops,
+ const MachineBlockFrequencyInfo &MBFI)
+ : VirtRegAuxInfo(MF, LIS, VRM, Loops, MBFI) {}
+};
} // end anonymous namespace
// Out-of-line destructor/anchor for PBQPRAConstraint.
@@ -570,19 +570,19 @@ void RegAllocPBQP::findVRegIntervalsToAlloc(const MachineFunction &MF,
// Iterate over all live ranges.
for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
- Register Reg = Register::index2VirtReg(I);
+ Register Reg = Register::index2VirtReg(I);
if (MRI.reg_nodbg_empty(Reg))
continue;
VRegsToAlloc.insert(Reg);
}
}
-static bool isACalleeSavedRegister(MCRegister Reg,
- const TargetRegisterInfo &TRI,
+static bool isACalleeSavedRegister(MCRegister Reg,
+ const TargetRegisterInfo &TRI,
const MachineFunction &MF) {
const MCPhysReg *CSR = MF.getRegInfo().getCalleeSavedRegs();
for (unsigned i = 0; CSR[i] != 0; ++i)
- if (TRI.regsOverlap(Reg, CSR[i]))
+ if (TRI.regsOverlap(Reg, CSR[i]))
return true;
return false;
}
@@ -596,12 +596,12 @@ void RegAllocPBQP::initializeGraph(PBQPRAGraph &G, VirtRegMap &VRM,
const TargetRegisterInfo &TRI =
*G.getMetadata().MF.getSubtarget().getRegisterInfo();
- std::vector<Register> Worklist(VRegsToAlloc.begin(), VRegsToAlloc.end());
+ std::vector<Register> Worklist(VRegsToAlloc.begin(), VRegsToAlloc.end());
- std::map<Register, std::vector<MCRegister>> VRegAllowedMap;
+ std::map<Register, std::vector<MCRegister>> VRegAllowedMap;
while (!Worklist.empty()) {
- Register VReg = Worklist.back();
+ Register VReg = Worklist.back();
Worklist.pop_back();
LiveInterval &VRegLI = LIS.getInterval(VReg);
@@ -609,8 +609,8 @@ void RegAllocPBQP::initializeGraph(PBQPRAGraph &G, VirtRegMap &VRM,
// If this is an empty interval move it to the EmptyIntervalVRegs set then
// continue.
if (VRegLI.empty()) {
- EmptyIntervalVRegs.insert(VRegLI.reg());
- VRegsToAlloc.erase(VRegLI.reg());
+ EmptyIntervalVRegs.insert(VRegLI.reg());
+ VRegsToAlloc.erase(VRegLI.reg());
continue;
}
@@ -621,10 +621,10 @@ void RegAllocPBQP::initializeGraph(PBQPRAGraph &G, VirtRegMap &VRM,
LIS.checkRegMaskInterference(VRegLI, RegMaskOverlaps);
// Compute an initial allowed set for the current vreg.
- std::vector<MCRegister> VRegAllowed;
+ std::vector<MCRegister> VRegAllowed;
ArrayRef<MCPhysReg> RawPRegOrder = TRC->getRawAllocationOrder(MF);
for (unsigned I = 0; I != RawPRegOrder.size(); ++I) {
- MCRegister PReg(RawPRegOrder[I]);
+ MCRegister PReg(RawPRegOrder[I]);
if (MRI.isReserved(PReg))
continue;
@@ -652,11 +652,11 @@ void RegAllocPBQP::initializeGraph(PBQPRAGraph &G, VirtRegMap &VRM,
if (VRegAllowed.empty()) {
SmallVector<Register, 8> NewVRegs;
spillVReg(VReg, NewVRegs, MF, LIS, VRM, VRegSpiller);
- llvm::append_range(Worklist, NewVRegs);
+ llvm::append_range(Worklist, NewVRegs);
continue;
- }
-
- VRegAllowedMap[VReg.id()] = std::move(VRegAllowed);
+ }
+
+ VRegAllowedMap[VReg.id()] = std::move(VRegAllowed);
}
for (auto &KV : VRegAllowedMap) {
@@ -699,7 +699,7 @@ void RegAllocPBQP::spillVReg(Register VReg,
const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
(void)TRI;
LLVM_DEBUG(dbgs() << "VREG " << printReg(VReg, &TRI) << " -> SPILLED (Cost: "
- << LRE.getParent().weight() << ", New vregs: ");
+ << LRE.getParent().weight() << ", New vregs: ");
// Copy any newly inserted live intervals into the list of regs to
// allocate.
@@ -707,8 +707,8 @@ void RegAllocPBQP::spillVReg(Register VReg,
I != E; ++I) {
const LiveInterval &LI = LIS.getInterval(*I);
assert(!LI.empty() && "Empty spill range.");
- LLVM_DEBUG(dbgs() << printReg(LI.reg(), &TRI) << " ");
- VRegsToAlloc.insert(LI.reg());
+ LLVM_DEBUG(dbgs() << printReg(LI.reg(), &TRI) << " ");
+ VRegsToAlloc.insert(LI.reg());
}
LLVM_DEBUG(dbgs() << ")\n");
@@ -732,11 +732,11 @@ bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAGraph &G,
// Iterate over the nodes mapping the PBQP solution to a register
// assignment.
for (auto NId : G.nodeIds()) {
- Register VReg = G.getNodeMetadata(NId).getVReg();
- unsigned AllocOpt = Solution.getSelection(NId);
+ Register VReg = G.getNodeMetadata(NId).getVReg();
+ unsigned AllocOpt = Solution.getSelection(NId);
- if (AllocOpt != PBQP::RegAlloc::getSpillOptionIdx()) {
- MCRegister PReg = G.getNodeMetadata(NId).getAllowedRegs()[AllocOpt - 1];
+ if (AllocOpt != PBQP::RegAlloc::getSpillOptionIdx()) {
+ MCRegister PReg = G.getNodeMetadata(NId).getAllowedRegs()[AllocOpt - 1];
LLVM_DEBUG(dbgs() << "VREG " << printReg(VReg, &TRI) << " -> "
<< TRI.getName(PReg) << "\n");
assert(PReg != 0 && "Invalid preg selected.");
@@ -764,12 +764,12 @@ void RegAllocPBQP::finalizeAlloc(MachineFunction &MF,
I != E; ++I) {
LiveInterval &LI = LIS.getInterval(*I);
- Register PReg = MRI.getSimpleHint(LI.reg());
+ Register PReg = MRI.getSimpleHint(LI.reg());
if (PReg == 0) {
- const TargetRegisterClass &RC = *MRI.getRegClass(LI.reg());
+ const TargetRegisterClass &RC = *MRI.getRegClass(LI.reg());
const ArrayRef<MCPhysReg> RawPRegOrder = RC.getRawAllocationOrder(MF);
- for (MCRegister CandidateReg : RawPRegOrder) {
+ for (MCRegister CandidateReg : RawPRegOrder) {
if (!VRM.getRegInfo().isReserved(CandidateReg)) {
PReg = CandidateReg;
break;
@@ -779,7 +779,7 @@ void RegAllocPBQP::finalizeAlloc(MachineFunction &MF,
"No un-reserved physical registers in this register class");
}
- VRM.assignVirt2Phys(LI.reg(), PReg);
+ VRM.assignVirt2Phys(LI.reg(), PReg);
}
}
@@ -800,8 +800,8 @@ bool RegAllocPBQP::runOnMachineFunction(MachineFunction &MF) {
VirtRegMap &VRM = getAnalysis<VirtRegMap>();
- PBQPVirtRegAuxInfo VRAI(MF, LIS, VRM, getAnalysis<MachineLoopInfo>(), MBFI);
- VRAI.calculateSpillWeightsAndHints();
+ PBQPVirtRegAuxInfo VRAI(MF, LIS, VRM, getAnalysis<MachineLoopInfo>(), MBFI);
+ VRAI.calculateSpillWeightsAndHints();
std::unique_ptr<Spiller> VRegSpiller(createInlineSpiller(*this, MF, VRM));
@@ -885,7 +885,7 @@ static Printable PrintNodeInfo(PBQP::RegAlloc::PBQPRAGraph::NodeId NId,
return Printable([NId, &G](raw_ostream &OS) {
const MachineRegisterInfo &MRI = G.getMetadata().MF.getRegInfo();
const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
- Register VReg = G.getNodeMetadata(NId).getVReg();
+ Register VReg = G.getNodeMetadata(NId).getVReg();
const char *RegClassName = TRI->getRegClassName(MRI.getRegClass(VReg));
OS << NId << " (" << RegClassName << ':' << printReg(VReg, TRI) << ')';
});
diff --git a/contrib/libs/llvm12/lib/CodeGen/RegisterClassInfo.cpp b/contrib/libs/llvm12/lib/CodeGen/RegisterClassInfo.cpp
index 0120cee7d7..0488db3d09 100644
--- a/contrib/libs/llvm12/lib/CodeGen/RegisterClassInfo.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/RegisterClassInfo.cpp
@@ -188,14 +188,14 @@ unsigned RegisterClassInfo::computePSetLimit(unsigned Idx) const {
}
assert(RC && "Failed to find register class");
compute(RC);
- unsigned NAllocatableRegs = getNumAllocatableRegs(RC);
- unsigned RegPressureSetLimit = TRI->getRegPressureSetLimit(*MF, Idx);
- // If all the regs are reserved, return raw RegPressureSetLimit.
- // One example is VRSAVERC in PowerPC.
- // Avoid returning zero, getRegPressureSetLimit(Idx) assumes computePSetLimit
- // return non-zero value.
- if (NAllocatableRegs == 0)
- return RegPressureSetLimit;
- unsigned NReserved = RC->getNumRegs() - NAllocatableRegs;
- return RegPressureSetLimit - TRI->getRegClassWeight(RC).RegWeight * NReserved;
+ unsigned NAllocatableRegs = getNumAllocatableRegs(RC);
+ unsigned RegPressureSetLimit = TRI->getRegPressureSetLimit(*MF, Idx);
+ // If all the regs are reserved, return raw RegPressureSetLimit.
+ // One example is VRSAVERC in PowerPC.
+ // Avoid returning zero, getRegPressureSetLimit(Idx) assumes computePSetLimit
+ // return non-zero value.
+ if (NAllocatableRegs == 0)
+ return RegPressureSetLimit;
+ unsigned NReserved = RC->getNumRegs() - NAllocatableRegs;
+ return RegPressureSetLimit - TRI->getRegClassWeight(RC).RegWeight * NReserved;
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/RegisterCoalescer.cpp b/contrib/libs/llvm12/lib/CodeGen/RegisterCoalescer.cpp
index 7053a36d3c..7fdc85a6e4 100644
--- a/contrib/libs/llvm12/lib/CodeGen/RegisterCoalescer.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/RegisterCoalescer.cpp
@@ -137,13 +137,13 @@ namespace {
/// ordered-by-slot-index set of DBG_VALUEs, to help quick
/// identification of whether coalescing may change location validity.
using DbgValueLoc = std::pair<SlotIndex, MachineInstr*>;
- DenseMap<Register, std::vector<DbgValueLoc>> DbgVRegToValues;
+ DenseMap<Register, std::vector<DbgValueLoc>> DbgVRegToValues;
/// VRegs may be repeatedly coalesced, and have many DBG_VALUEs attached.
/// To avoid repeatedly merging sets of DbgValueLocs, instead record
/// which vregs have been coalesced, and where to. This map is from
/// vreg => {set of vregs merged in}.
- DenseMap<Register, SmallVector<Register, 4>> DbgMergedVRegNums;
+ DenseMap<Register, SmallVector<Register, 4>> DbgMergedVRegNums;
/// A LaneMask to remember on which subregister live ranges we need to call
/// shrinkToUses() later.
@@ -173,16 +173,16 @@ namespace {
SmallVector<MachineInstr*, 8> DeadDefs;
/// Virtual registers to be considered for register class inflation.
- SmallVector<Register, 8> InflateRegs;
+ SmallVector<Register, 8> InflateRegs;
/// The collection of live intervals which should have been updated
/// immediately after rematerialiation but delayed until
/// lateLiveIntervalUpdate is called.
- DenseSet<Register> ToBeUpdated;
+ DenseSet<Register> ToBeUpdated;
/// Record how many times the large live interval with many valnos
/// has been tried to join with other live interval.
- DenseMap<Register, unsigned long> LargeLIVisitCounter;
+ DenseMap<Register, unsigned long> LargeLIVisitCounter;
/// Recursively eliminate dead defs in DeadDefs.
void eliminateDeadDefs();
@@ -211,18 +211,18 @@ namespace {
/// live interval update is costly.
void lateLiveIntervalUpdate();
- /// Check if the incoming value defined by a COPY at \p SLRQ in the subrange
- /// has no value defined in the predecessors. If the incoming value is the
- /// same as defined by the copy itself, the value is considered undefined.
- bool copyValueUndefInPredecessors(LiveRange &S,
- const MachineBasicBlock *MBB,
- LiveQueryResult SLRQ);
-
- /// Set necessary undef flags on subregister uses after pruning out undef
- /// lane segments from the subrange.
- void setUndefOnPrunedSubRegUses(LiveInterval &LI, Register Reg,
- LaneBitmask PrunedLanes);
-
+ /// Check if the incoming value defined by a COPY at \p SLRQ in the subrange
+ /// has no value defined in the predecessors. If the incoming value is the
+ /// same as defined by the copy itself, the value is considered undefined.
+ bool copyValueUndefInPredecessors(LiveRange &S,
+ const MachineBasicBlock *MBB,
+ LiveQueryResult SLRQ);
+
+ /// Set necessary undef flags on subregister uses after pruning out undef
+ /// lane segments from the subrange.
+ void setUndefOnPrunedSubRegUses(LiveInterval &LI, Register Reg,
+ LaneBitmask PrunedLanes);
+
/// Attempt to join intervals corresponding to SrcReg/DstReg, which are the
/// src/dst of the copy instruction CopyMI. This returns true if the copy
/// was successfully coalesced away. If it is not currently possible to
@@ -297,7 +297,7 @@ namespace {
/// number if it is not zero. If DstReg is a physical register and the
/// existing subregister number of the def / use being updated is not zero,
/// make sure to set it to the correct physical subregister.
- void updateRegDefsUses(Register SrcReg, Register DstReg, unsigned SubIdx);
+ void updateRegDefsUses(Register SrcReg, Register DstReg, unsigned SubIdx);
/// If the given machine operand reads only undefined lanes add an undef
/// flag.
@@ -363,7 +363,7 @@ namespace {
JoinVals &LHSVals, LiveRange &RHS,
JoinVals &RHSVals);
- void checkMergingChangesDbgValuesImpl(Register Reg, LiveRange &OtherRange,
+ void checkMergingChangesDbgValuesImpl(Register Reg, LiveRange &OtherRange,
LiveRange &RegRange, JoinVals &Vals2);
public:
@@ -400,8 +400,8 @@ INITIALIZE_PASS_END(RegisterCoalescer, "simple-register-coalescing",
"Simple Register Coalescing", false, false)
LLVM_NODISCARD static bool isMoveInstr(const TargetRegisterInfo &tri,
- const MachineInstr *MI, Register &Src,
- Register &Dst, unsigned &SrcSub,
+ const MachineInstr *MI, Register &Src,
+ Register &Dst, unsigned &SrcSub,
unsigned &DstSub) {
if (MI->isCopy()) {
Dst = MI->getOperand(0).getReg();
@@ -436,13 +436,13 @@ static bool isSplitEdge(const MachineBasicBlock *MBB) {
}
bool CoalescerPair::setRegisters(const MachineInstr *MI) {
- SrcReg = DstReg = Register();
+ SrcReg = DstReg = Register();
SrcIdx = DstIdx = 0;
NewRC = nullptr;
Flipped = CrossClass = false;
- Register Src, Dst;
- unsigned SrcSub = 0, DstSub = 0;
+ Register Src, Dst;
+ unsigned SrcSub = 0, DstSub = 0;
if (!isMoveInstr(TRI, MI, Src, Dst, SrcSub, DstSub))
return false;
Partial = SrcSub || DstSub;
@@ -536,8 +536,8 @@ bool CoalescerPair::flip() {
bool CoalescerPair::isCoalescable(const MachineInstr *MI) const {
if (!MI)
return false;
- Register Src, Dst;
- unsigned SrcSub = 0, DstSub = 0;
+ Register Src, Dst;
+ unsigned SrcSub = 0, DstSub = 0;
if (!isMoveInstr(TRI, MI, Src, Dst, SrcSub, DstSub))
return false;
@@ -550,8 +550,8 @@ bool CoalescerPair::isCoalescable(const MachineInstr *MI) const {
}
// Now check that Dst matches DstReg.
- if (DstReg.isPhysical()) {
- if (!Dst.isPhysical())
+ if (DstReg.isPhysical()) {
+ if (!Dst.isPhysical())
return false;
assert(!DstIdx && !SrcIdx && "Inconsistent CoalescerPair state.");
// DstSub could be set for a physreg from INSERT_SUBREG.
@@ -561,7 +561,7 @@ bool CoalescerPair::isCoalescable(const MachineInstr *MI) const {
if (!SrcSub)
return DstReg == Dst;
// This is a partial register copy. Check that the parts match.
- return Register(TRI.getSubReg(DstReg, SrcSub)) == Dst;
+ return Register(TRI.getSubReg(DstReg, SrcSub)) == Dst;
} else {
// DstReg is virtual.
if (DstReg != Dst)
@@ -663,7 +663,7 @@ bool RegisterCoalescer::adjustCopiesBackFrom(const CoalescerPair &CP,
// in IntB, we can merge them.
if (ValS+1 != BS) return false;
- LLVM_DEBUG(dbgs() << "Extending: " << printReg(IntB.reg(), TRI));
+ LLVM_DEBUG(dbgs() << "Extending: " << printReg(IntB.reg(), TRI));
SlotIndex FillerStart = ValS->end, FillerEnd = BS->start;
// We are about to delete CopyMI, so need to remove it as the 'instruction
@@ -706,13 +706,13 @@ bool RegisterCoalescer::adjustCopiesBackFrom(const CoalescerPair &CP,
// If the source instruction was killing the source register before the
// merge, unset the isKill marker given the live range has been extended.
- int UIdx = ValSEndInst->findRegisterUseOperandIdx(IntB.reg(), true);
+ int UIdx = ValSEndInst->findRegisterUseOperandIdx(IntB.reg(), true);
if (UIdx != -1) {
ValSEndInst->getOperand(UIdx).setIsKill(false);
}
// Rewrite the copy.
- CopyMI->substituteRegister(IntA.reg(), IntB.reg(), 0, *TRI);
+ CopyMI->substituteRegister(IntA.reg(), IntB.reg(), 0, *TRI);
// If the copy instruction was killing the destination register or any
// subrange before the merge trim the live range.
bool RecomputeLiveRange = AS->end == CopyIdx;
@@ -831,7 +831,7 @@ RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
return { false, false };
// If DefMI is a two-address instruction then commuting it will change the
// destination register.
- int DefIdx = DefMI->findRegisterDefOperandIdx(IntA.reg());
+ int DefIdx = DefMI->findRegisterDefOperandIdx(IntA.reg());
assert(DefIdx != -1);
unsigned UseOpIdx;
if (!DefMI->isRegTiedToUseOperand(DefIdx, &UseOpIdx))
@@ -852,7 +852,7 @@ RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
MachineOperand &NewDstMO = DefMI->getOperand(NewDstIdx);
Register NewReg = NewDstMO.getReg();
- if (NewReg != IntB.reg() || !IntB.Query(AValNo->def).isKill())
+ if (NewReg != IntB.reg() || !IntB.Query(AValNo->def).isKill())
return { false, false };
// Make sure there are no other definitions of IntB that would reach the
@@ -862,7 +862,7 @@ RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
// If some of the uses of IntA.reg is already coalesced away, return false.
// It's not possible to determine whether it's safe to perform the coalescing.
- for (MachineOperand &MO : MRI->use_nodbg_operands(IntA.reg())) {
+ for (MachineOperand &MO : MRI->use_nodbg_operands(IntA.reg())) {
MachineInstr *UseMI = MO.getParent();
unsigned OpNo = &MO - &UseMI->getOperand(0);
SlotIndex UseIdx = LIS->getInstructionIndex(*UseMI);
@@ -884,9 +884,9 @@ RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
TII->commuteInstruction(*DefMI, false, UseOpIdx, NewDstIdx);
if (!NewMI)
return { false, false };
- if (Register::isVirtualRegister(IntA.reg()) &&
- Register::isVirtualRegister(IntB.reg()) &&
- !MRI->constrainRegClass(IntB.reg(), MRI->getRegClass(IntA.reg())))
+ if (Register::isVirtualRegister(IntA.reg()) &&
+ Register::isVirtualRegister(IntB.reg()) &&
+ !MRI->constrainRegClass(IntB.reg(), MRI->getRegClass(IntA.reg())))
return { false, false };
if (NewMI != DefMI) {
LIS->ReplaceMachineInstrInMaps(*DefMI, *NewMI);
@@ -905,10 +905,10 @@ RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
// = B
// Update uses of IntA of the specific Val# with IntB.
- for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(IntA.reg()),
+ for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(IntA.reg()),
UE = MRI->use_end();
- UI != UE;
- /* ++UI is below because of possible MI removal */) {
+ UI != UE;
+ /* ++UI is below because of possible MI removal */) {
MachineOperand &UseMO = *UI;
++UI;
if (UseMO.isUndef())
@@ -935,7 +935,7 @@ RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
continue;
if (!UseMI->isCopy())
continue;
- if (UseMI->getOperand(0).getReg() != IntB.reg() ||
+ if (UseMI->getOperand(0).getReg() != IntB.reg() ||
UseMI->getOperand(0).getSubReg())
continue;
@@ -966,10 +966,10 @@ RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
if (IntA.hasSubRanges() || IntB.hasSubRanges()) {
if (!IntA.hasSubRanges()) {
- LaneBitmask Mask = MRI->getMaxLaneMaskForVReg(IntA.reg());
+ LaneBitmask Mask = MRI->getMaxLaneMaskForVReg(IntA.reg());
IntA.createSubRangeFrom(Allocator, Mask, IntA);
} else if (!IntB.hasSubRanges()) {
- LaneBitmask Mask = MRI->getMaxLaneMaskForVReg(IntB.reg());
+ LaneBitmask Mask = MRI->getMaxLaneMaskForVReg(IntB.reg());
IntB.createSubRangeFrom(Allocator, Mask, IntB);
}
SlotIndex AIdx = CopyIdx.getRegSlot(true);
@@ -1115,8 +1115,8 @@ bool RegisterCoalescer::removePartialRedundancy(const CoalescerPair &CP,
continue;
}
// Check DefMI is a reverse copy and it is in BB Pred.
- if (DefMI->getOperand(0).getReg() != IntA.reg() ||
- DefMI->getOperand(1).getReg() != IntB.reg() ||
+ if (DefMI->getOperand(0).getReg() != IntA.reg() ||
+ DefMI->getOperand(1).getReg() != IntB.reg() ||
DefMI->getParent() != Pred) {
CopyLeftBB = Pred;
continue;
@@ -1173,8 +1173,8 @@ bool RegisterCoalescer::removePartialRedundancy(const CoalescerPair &CP,
// Insert new copy to CopyLeftBB.
MachineInstr *NewCopyMI = BuildMI(*CopyLeftBB, InsPos, CopyMI.getDebugLoc(),
- TII->get(TargetOpcode::COPY), IntB.reg())
- .addReg(IntA.reg());
+ TII->get(TargetOpcode::COPY), IntB.reg())
+ .addReg(IntA.reg());
SlotIndex NewCopyIdx =
LIS->InsertMachineInstrInMaps(*NewCopyMI).getRegSlot();
IntB.createDeadDef(NewCopyIdx, LIS->getVNInfoAllocator());
@@ -1227,10 +1227,10 @@ bool RegisterCoalescer::removePartialRedundancy(const CoalescerPair &CP,
}
++I;
}
- SmallVector<SlotIndex, 8> Undefs;
- IntB.computeSubRangeUndefs(Undefs, SR.LaneMask, *MRI,
- *LIS->getSlotIndexes());
- LIS->extendToIndices(SR, EndPoints, Undefs);
+ SmallVector<SlotIndex, 8> Undefs;
+ IntB.computeSubRangeUndefs(Undefs, SR.LaneMask, *MRI,
+ *LIS->getSlotIndexes());
+ LIS->extendToIndices(SR, EndPoints, Undefs);
}
// If any dead defs were extended, truncate them.
shrinkToUses(&IntB);
@@ -1242,9 +1242,9 @@ bool RegisterCoalescer::removePartialRedundancy(const CoalescerPair &CP,
/// Returns true if @p MI defines the full vreg @p Reg, as opposed to just
/// defining a subregister.
-static bool definesFullReg(const MachineInstr &MI, Register Reg) {
- assert(!Reg.isPhysical() && "This code cannot handle physreg aliasing");
-
+static bool definesFullReg(const MachineInstr &MI, Register Reg) {
+ assert(!Reg.isPhysical() && "This code cannot handle physreg aliasing");
+
for (const MachineOperand &Op : MI.operands()) {
if (!Op.isReg() || !Op.isDef() || Op.getReg() != Reg)
continue;
@@ -1260,9 +1260,9 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
MachineInstr *CopyMI,
bool &IsDefCopy) {
IsDefCopy = false;
- Register SrcReg = CP.isFlipped() ? CP.getDstReg() : CP.getSrcReg();
+ Register SrcReg = CP.isFlipped() ? CP.getDstReg() : CP.getSrcReg();
unsigned SrcIdx = CP.isFlipped() ? CP.getDstIdx() : CP.getSrcIdx();
- Register DstReg = CP.isFlipped() ? CP.getSrcReg() : CP.getDstReg();
+ Register DstReg = CP.isFlipped() ? CP.getSrcReg() : CP.getDstReg();
unsigned DstIdx = CP.isFlipped() ? CP.getSrcIdx() : CP.getDstIdx();
if (Register::isPhysicalRegister(SrcReg))
return false;
@@ -1309,8 +1309,8 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
const TargetRegisterClass *DefRC = TII->getRegClass(MCID, 0, TRI, *MF);
if (!DefMI->isImplicitDef()) {
- if (DstReg.isPhysical()) {
- Register NewDstReg = DstReg;
+ if (DstReg.isPhysical()) {
+ Register NewDstReg = DstReg;
unsigned NewDstIdx = TRI->composeSubRegIndices(CP.getSrcIdx(),
DefMI->getOperand(0).getSubReg());
@@ -1384,7 +1384,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
// NewMI may have dead implicit defs (E.g. EFLAGS for MOV<bits>r0 on X86).
// We need to remember these so we can add intervals once we insert
// NewMI into SlotIndexes.
- SmallVector<MCRegister, 4> NewMIImplDefs;
+ SmallVector<MCRegister, 4> NewMIImplDefs;
for (unsigned i = NewMI.getDesc().getNumOperands(),
e = NewMI.getNumOperands();
i != e; ++i) {
@@ -1392,11 +1392,11 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
if (MO.isReg() && MO.isDef()) {
assert(MO.isImplicit() && MO.isDead() &&
Register::isPhysicalRegister(MO.getReg()));
- NewMIImplDefs.push_back(MO.getReg().asMCReg());
+ NewMIImplDefs.push_back(MO.getReg().asMCReg());
}
}
- if (DstReg.isVirtual()) {
+ if (DstReg.isVirtual()) {
unsigned NewIdx = NewMI.getOperand(0).getSubReg();
if (DefRC != nullptr) {
@@ -1531,7 +1531,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
SlotIndex NewMIIdx = LIS->getInstructionIndex(NewMI);
for (unsigned i = 0, e = NewMIImplDefs.size(); i != e; ++i) {
- MCRegister Reg = NewMIImplDefs[i];
+ MCRegister Reg = NewMIImplDefs[i];
for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
if (LiveRange *LR = LIS->getCachedRegUnit(*Units))
LR->createDeadDef(NewMIIdx.getRegSlot(), LIS->getVNInfoAllocator());
@@ -1589,8 +1589,8 @@ MachineInstr *RegisterCoalescer::eliminateUndefCopy(MachineInstr *CopyMI) {
// Note that we do not query CoalescerPair here but redo isMoveInstr as the
// CoalescerPair may have a new register class with adjusted subreg indices
// at this point.
- Register SrcReg, DstReg;
- unsigned SrcSubIdx = 0, DstSubIdx = 0;
+ Register SrcReg, DstReg;
+ unsigned SrcSubIdx = 0, DstSubIdx = 0;
if(!isMoveInstr(*TRI, CopyMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx))
return nullptr;
@@ -1715,7 +1715,7 @@ void RegisterCoalescer::addUndefFlag(const LiveInterval &Int, SlotIndex UseIdx,
}
}
-void RegisterCoalescer::updateRegDefsUses(Register SrcReg, Register DstReg,
+void RegisterCoalescer::updateRegDefsUses(Register SrcReg, Register DstReg,
unsigned SubIdx) {
bool DstIsPhys = Register::isPhysicalRegister(DstReg);
LiveInterval *DstInt = DstIsPhys ? nullptr : &LIS->getInterval(DstReg);
@@ -1771,7 +1771,7 @@ void RegisterCoalescer::updateRegDefsUses(Register SrcReg, Register DstReg,
if (SubIdx != 0 && MO.isUse() && MRI->shouldTrackSubRegLiveness(DstReg)) {
if (!DstInt->hasSubRanges()) {
BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
- LaneBitmask FullMask = MRI->getMaxLaneMaskForVReg(DstInt->reg());
+ LaneBitmask FullMask = MRI->getMaxLaneMaskForVReg(DstInt->reg());
LaneBitmask UsedLanes = TRI->getSubRegIndexLaneMask(SubIdx);
LaneBitmask UnusedLanes = FullMask & ~UsedLanes;
DstInt->createSubRangeFrom(Allocator, UsedLanes, *DstInt);
@@ -1821,49 +1821,49 @@ bool RegisterCoalescer::canJoinPhys(const CoalescerPair &CP) {
return false;
}
-bool RegisterCoalescer::copyValueUndefInPredecessors(
- LiveRange &S, const MachineBasicBlock *MBB, LiveQueryResult SLRQ) {
- for (const MachineBasicBlock *Pred : MBB->predecessors()) {
- SlotIndex PredEnd = LIS->getMBBEndIdx(Pred);
- if (VNInfo *V = S.getVNInfoAt(PredEnd.getPrevSlot())) {
- // If this is a self loop, we may be reading the same value.
- if (V->id != SLRQ.valueOutOrDead()->id)
- return false;
- }
- }
-
- return true;
-}
-
-void RegisterCoalescer::setUndefOnPrunedSubRegUses(LiveInterval &LI,
- Register Reg,
- LaneBitmask PrunedLanes) {
- // If we had other instructions in the segment reading the undef sublane
- // value, we need to mark them with undef.
- for (MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {
- unsigned SubRegIdx = MO.getSubReg();
- if (SubRegIdx == 0 || MO.isUndef())
- continue;
-
- LaneBitmask SubRegMask = TRI->getSubRegIndexLaneMask(SubRegIdx);
- SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent());
- for (LiveInterval::SubRange &S : LI.subranges()) {
- if (!S.liveAt(Pos) && (PrunedLanes & SubRegMask).any()) {
- MO.setIsUndef();
- break;
- }
- }
- }
-
- LI.removeEmptySubRanges();
-
- // A def of a subregister may be a use of other register lanes. Replacing
- // such a def with a def of a different register will eliminate the use,
- // and may cause the recorded live range to be larger than the actual
- // liveness in the program IR.
- LIS->shrinkToUses(&LI);
-}
-
+bool RegisterCoalescer::copyValueUndefInPredecessors(
+ LiveRange &S, const MachineBasicBlock *MBB, LiveQueryResult SLRQ) {
+ for (const MachineBasicBlock *Pred : MBB->predecessors()) {
+ SlotIndex PredEnd = LIS->getMBBEndIdx(Pred);
+ if (VNInfo *V = S.getVNInfoAt(PredEnd.getPrevSlot())) {
+ // If this is a self loop, we may be reading the same value.
+ if (V->id != SLRQ.valueOutOrDead()->id)
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void RegisterCoalescer::setUndefOnPrunedSubRegUses(LiveInterval &LI,
+ Register Reg,
+ LaneBitmask PrunedLanes) {
+ // If we had other instructions in the segment reading the undef sublane
+ // value, we need to mark them with undef.
+ for (MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {
+ unsigned SubRegIdx = MO.getSubReg();
+ if (SubRegIdx == 0 || MO.isUndef())
+ continue;
+
+ LaneBitmask SubRegMask = TRI->getSubRegIndexLaneMask(SubRegIdx);
+ SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent());
+ for (LiveInterval::SubRange &S : LI.subranges()) {
+ if (!S.liveAt(Pos) && (PrunedLanes & SubRegMask).any()) {
+ MO.setIsUndef();
+ break;
+ }
+ }
+ }
+
+ LI.removeEmptySubRanges();
+
+ // A def of a subregister may be a use of other register lanes. Replacing
+ // such a def with a def of a different register will eliminate the use,
+ // and may cause the recorded live range to be larger than the actual
+ // liveness in the program IR.
+ LIS->shrinkToUses(&LI);
+}
+
bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
Again = false;
LLVM_DEBUG(dbgs() << LIS->getInstructionIndex(*CopyMI) << '\t' << *CopyMI);
@@ -1924,34 +1924,34 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
assert(ReadVNI && "No value before copy and no <undef> flag.");
assert(ReadVNI != DefVNI && "Cannot read and define the same value.");
- // Track incoming undef lanes we need to eliminate from the subrange.
- LaneBitmask PrunedLanes;
- MachineBasicBlock *MBB = CopyMI->getParent();
-
+ // Track incoming undef lanes we need to eliminate from the subrange.
+ LaneBitmask PrunedLanes;
+ MachineBasicBlock *MBB = CopyMI->getParent();
+
// Process subregister liveranges.
for (LiveInterval::SubRange &S : LI.subranges()) {
LiveQueryResult SLRQ = S.Query(CopyIdx);
if (VNInfo *SDefVNI = SLRQ.valueDefined()) {
- if (VNInfo *SReadVNI = SLRQ.valueIn())
- SDefVNI = S.MergeValueNumberInto(SDefVNI, SReadVNI);
-
- // If this copy introduced an undef subrange from an incoming value,
- // we need to eliminate the undef live in values from the subrange.
- if (copyValueUndefInPredecessors(S, MBB, SLRQ)) {
- LLVM_DEBUG(dbgs() << "Incoming sublane value is undef at copy\n");
- PrunedLanes |= S.LaneMask;
- S.removeValNo(SDefVNI);
- }
+ if (VNInfo *SReadVNI = SLRQ.valueIn())
+ SDefVNI = S.MergeValueNumberInto(SDefVNI, SReadVNI);
+
+ // If this copy introduced an undef subrange from an incoming value,
+ // we need to eliminate the undef live in values from the subrange.
+ if (copyValueUndefInPredecessors(S, MBB, SLRQ)) {
+ LLVM_DEBUG(dbgs() << "Incoming sublane value is undef at copy\n");
+ PrunedLanes |= S.LaneMask;
+ S.removeValNo(SDefVNI);
+ }
}
}
-
- LI.MergeValueNumberInto(DefVNI, ReadVNI);
- if (PrunedLanes.any()) {
- LLVM_DEBUG(dbgs() << "Pruning undef incoming lanes: "
- << PrunedLanes << '\n');
- setUndefOnPrunedSubRegUses(LI, CP.getSrcReg(), PrunedLanes);
- }
-
+
+ LI.MergeValueNumberInto(DefVNI, ReadVNI);
+ if (PrunedLanes.any()) {
+ LLVM_DEBUG(dbgs() << "Pruning undef incoming lanes: "
+ << PrunedLanes << '\n');
+ setUndefOnPrunedSubRegUses(LI, CP.getSrcReg(), PrunedLanes);
+ }
+
LLVM_DEBUG(dbgs() << "\tMerged values: " << LI << '\n');
}
deleteInstr(CopyMI);
@@ -1966,7 +1966,7 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
if (!canJoinPhys(CP)) {
// Before giving up coalescing, if definition of source is defined by
// trivial computation, try rematerializing it.
- bool IsDefCopy = false;
+ bool IsDefCopy = false;
if (reMaterializeTrivialDef(CP, CopyMI, IsDefCopy))
return true;
if (IsDefCopy)
@@ -2005,7 +2005,7 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
// If definition of source is defined by trivial computation, try
// rematerializing it.
- bool IsDefCopy = false;
+ bool IsDefCopy = false;
if (reMaterializeTrivialDef(CP, CopyMI, IsDefCopy))
return true;
@@ -2019,7 +2019,7 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
if (Changed) {
deleteInstr(CopyMI);
if (Shrink) {
- Register DstReg = CP.isFlipped() ? CP.getSrcReg() : CP.getDstReg();
+ Register DstReg = CP.isFlipped() ? CP.getSrcReg() : CP.getDstReg();
LiveInterval &DstLI = LIS->getInterval(DstReg);
shrinkToUses(&DstLI);
LLVM_DEBUG(dbgs() << "\t\tshrunk: " << DstLI << '\n');
@@ -2072,7 +2072,7 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
continue;
LLVM_DEBUG(dbgs() << "Shrink LaneUses (Lane " << PrintLaneMask(S.LaneMask)
<< ")\n");
- LIS->shrinkToUses(S, LI.reg());
+ LIS->shrinkToUses(S, LI.reg());
}
LI.removeEmptySubRanges();
}
@@ -2111,8 +2111,8 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
}
bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) {
- Register DstReg = CP.getDstReg();
- Register SrcReg = CP.getSrcReg();
+ Register DstReg = CP.getDstReg();
+ Register SrcReg = CP.getSrcReg();
assert(CP.isPhys() && "Must be a physreg copy");
assert(MRI->isReserved(DstReg) && "Not a reserved register");
LiveInterval &RHS = LIS->getInterval(SrcReg);
@@ -2209,7 +2209,7 @@ bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) {
LLVM_DEBUG(dbgs() << "\t\tRemoving phys reg def of "
<< printReg(DstReg, TRI) << " at " << CopyRegIdx << "\n");
- LIS->removePhysRegDefAt(DstReg.asMCReg(), CopyRegIdx);
+ LIS->removePhysRegDefAt(DstReg.asMCReg(), CopyRegIdx);
// Create a new dead def at the new def location.
for (MCRegUnitIterator UI(DstReg, TRI); UI.isValid(); ++UI) {
LiveRange &LR = LIS->getRegUnit(*UI);
@@ -2300,7 +2300,7 @@ class JoinVals {
LiveRange &LR;
/// (Main) register we work on.
- const Register Reg;
+ const Register Reg;
/// Reg (and therefore the values in this liverange) will end up as
/// subregister SubIdx in the coalesced register. Either CP.DstIdx or
@@ -2420,7 +2420,7 @@ class JoinVals {
LaneBitmask computeWriteLanes(const MachineInstr *DefMI, bool &Redef) const;
/// Find the ultimate value that VNI was copied from.
- std::pair<const VNInfo *, Register> followCopyChain(const VNInfo *VNI) const;
+ std::pair<const VNInfo *, Register> followCopyChain(const VNInfo *VNI) const;
bool valuesIdentical(VNInfo *Value0, VNInfo *Value1, const JoinVals &Other) const;
@@ -2459,7 +2459,7 @@ class JoinVals {
/// Return true if MI uses any of the given Lanes from Reg.
/// This does not include partial redefinitions of Reg.
- bool usesLanes(const MachineInstr &MI, Register, unsigned, LaneBitmask) const;
+ bool usesLanes(const MachineInstr &MI, Register, unsigned, LaneBitmask) const;
/// Determine if ValNo is a copy of a value number in LR or Other.LR that will
/// be pruned:
@@ -2470,15 +2470,15 @@ class JoinVals {
bool isPrunedValue(unsigned ValNo, JoinVals &Other);
public:
- JoinVals(LiveRange &LR, Register Reg, unsigned SubIdx, LaneBitmask LaneMask,
- SmallVectorImpl<VNInfo *> &newVNInfo, const CoalescerPair &cp,
+ JoinVals(LiveRange &LR, Register Reg, unsigned SubIdx, LaneBitmask LaneMask,
+ SmallVectorImpl<VNInfo *> &newVNInfo, const CoalescerPair &cp,
LiveIntervals *lis, const TargetRegisterInfo *TRI, bool SubRangeJoin,
bool TrackSubRegLiveness)
- : LR(LR), Reg(Reg), SubIdx(SubIdx), LaneMask(LaneMask),
- SubRangeJoin(SubRangeJoin), TrackSubRegLiveness(TrackSubRegLiveness),
- NewVNInfo(newVNInfo), CP(cp), LIS(lis), Indexes(LIS->getSlotIndexes()),
- TRI(TRI), Assignments(LR.getNumValNums(), -1),
- Vals(LR.getNumValNums()) {}
+ : LR(LR), Reg(Reg), SubIdx(SubIdx), LaneMask(LaneMask),
+ SubRangeJoin(SubRangeJoin), TrackSubRegLiveness(TrackSubRegLiveness),
+ NewVNInfo(newVNInfo), CP(cp), LIS(lis), Indexes(LIS->getSlotIndexes()),
+ TRI(TRI), Assignments(LR.getNumValNums(), -1),
+ Vals(LR.getNumValNums()) {}
/// Analyze defs in LR and compute a value mapping in NewVNInfo.
/// Returns false if any conflicts were impossible to resolve.
@@ -2544,9 +2544,9 @@ LaneBitmask JoinVals::computeWriteLanes(const MachineInstr *DefMI, bool &Redef)
return L;
}
-std::pair<const VNInfo *, Register>
-JoinVals::followCopyChain(const VNInfo *VNI) const {
- Register TrackReg = Reg;
+std::pair<const VNInfo *, Register>
+JoinVals::followCopyChain(const VNInfo *VNI) const {
+ Register TrackReg = Reg;
while (!VNI->isPHIDef()) {
SlotIndex Def = VNI->def;
@@ -2555,7 +2555,7 @@ JoinVals::followCopyChain(const VNInfo *VNI) const {
if (!MI->isFullCopy())
return std::make_pair(VNI, TrackReg);
Register SrcReg = MI->getOperand(1).getReg();
- if (!SrcReg.isVirtual())
+ if (!SrcReg.isVirtual())
return std::make_pair(VNI, TrackReg);
const LiveInterval &LI = LIS->getInterval(SrcReg);
@@ -2600,13 +2600,13 @@ JoinVals::followCopyChain(const VNInfo *VNI) const {
bool JoinVals::valuesIdentical(VNInfo *Value0, VNInfo *Value1,
const JoinVals &Other) const {
const VNInfo *Orig0;
- Register Reg0;
+ Register Reg0;
std::tie(Orig0, Reg0) = followCopyChain(Value0);
if (Orig0 == Value1 && Reg0 == Other.Reg)
return true;
const VNInfo *Orig1;
- Register Reg1;
+ Register Reg1;
std::tie(Orig1, Reg1) = Other.followCopyChain(Value1);
// If both values are undefined, and the source registers are the same
// register, the values are identical. Filter out cases where only one
@@ -2767,7 +2767,7 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
return CR_Replace;
// Check for simple erasable conflicts.
- if (DefMI->isImplicitDef())
+ if (DefMI->isImplicitDef())
return CR_Erase;
// Include the non-conflict where DefMI is a coalescable copy that kills
@@ -2957,7 +2957,7 @@ taintExtent(unsigned ValNo, LaneBitmask TaintedLanes, JoinVals &Other,
return true;
}
-bool JoinVals::usesLanes(const MachineInstr &MI, Register Reg, unsigned SubIdx,
+bool JoinVals::usesLanes(const MachineInstr &MI, Register Reg, unsigned SubIdx,
LaneBitmask Lanes) const {
if (MI.isDebugInstr())
return false;
@@ -3429,7 +3429,7 @@ void RegisterCoalescer::mergeSubRangeInto(LiveInterval &LI,
bool RegisterCoalescer::isHighCostLiveInterval(LiveInterval &LI) {
if (LI.valnos.size() < LargeIntervalSizeThreshold)
return false;
- auto &Counter = LargeLIVisitCounter[LI.reg()];
+ auto &Counter = LargeLIVisitCounter[LI.reg()];
if (Counter < LargeIntervalFreqThreshold) {
Counter++;
return false;
@@ -3532,8 +3532,8 @@ bool RegisterCoalescer::joinVirtRegs(CoalescerPair &CP) {
// Kill flags are going to be wrong if the live ranges were overlapping.
// Eventually, we should simply clear all kill flags when computing live
// ranges. They are reinserted after register allocation.
- MRI->clearKillFlags(LHS.reg());
- MRI->clearKillFlags(RHS.reg());
+ MRI->clearKillFlags(LHS.reg());
+ MRI->clearKillFlags(RHS.reg());
if (!EndPoints.empty()) {
// Recompute the parts of the live range we had to remove because of
@@ -3601,20 +3601,20 @@ void RegisterCoalescer::checkMergingChangesDbgValues(CoalescerPair &CP,
JoinVals &LHSVals,
LiveRange &RHS,
JoinVals &RHSVals) {
- auto ScanForDstReg = [&](Register Reg) {
+ auto ScanForDstReg = [&](Register Reg) {
checkMergingChangesDbgValuesImpl(Reg, RHS, LHS, LHSVals);
};
- auto ScanForSrcReg = [&](Register Reg) {
+ auto ScanForSrcReg = [&](Register Reg) {
checkMergingChangesDbgValuesImpl(Reg, LHS, RHS, RHSVals);
};
// Scan for potentially unsound DBG_VALUEs: examine first the register number
// Reg, and then any other vregs that may have been merged into it.
- auto PerformScan = [this](Register Reg, std::function<void(Register)> Func) {
+ auto PerformScan = [this](Register Reg, std::function<void(Register)> Func) {
Func(Reg);
if (DbgMergedVRegNums.count(Reg))
- for (Register X : DbgMergedVRegNums[Reg])
+ for (Register X : DbgMergedVRegNums[Reg])
Func(X);
};
@@ -3623,7 +3623,7 @@ void RegisterCoalescer::checkMergingChangesDbgValues(CoalescerPair &CP,
PerformScan(CP.getDstReg(), ScanForDstReg);
}
-void RegisterCoalescer::checkMergingChangesDbgValuesImpl(Register Reg,
+void RegisterCoalescer::checkMergingChangesDbgValuesImpl(Register Reg,
LiveRange &OtherLR,
LiveRange &RegLR,
JoinVals &RegVals) {
@@ -3749,7 +3749,7 @@ static bool isLocalCopy(MachineInstr *Copy, const LiveIntervals *LIS) {
}
void RegisterCoalescer::lateLiveIntervalUpdate() {
- for (Register reg : ToBeUpdated) {
+ for (Register reg : ToBeUpdated) {
if (!LIS->hasInterval(reg))
continue;
LiveInterval &LI = LIS->getInterval(reg);
@@ -3783,7 +3783,7 @@ copyCoalesceWorkList(MutableArrayRef<MachineInstr*> CurrList) {
/// Check if DstReg is a terminal node.
/// I.e., it does not have any affinity other than \p Copy.
-static bool isTerminalReg(Register DstReg, const MachineInstr &Copy,
+static bool isTerminalReg(Register DstReg, const MachineInstr &Copy,
const MachineRegisterInfo *MRI) {
assert(Copy.isCopyLike());
// Check if the destination of this copy as any other affinity.
@@ -3797,16 +3797,16 @@ bool RegisterCoalescer::applyTerminalRule(const MachineInstr &Copy) const {
assert(Copy.isCopyLike());
if (!UseTerminalRule)
return false;
- Register SrcReg, DstReg;
- unsigned SrcSubReg = 0, DstSubReg = 0;
+ Register SrcReg, DstReg;
+ unsigned SrcSubReg = 0, DstSubReg = 0;
if (!isMoveInstr(*TRI, &Copy, SrcReg, DstReg, SrcSubReg, DstSubReg))
return false;
// Check if the destination of this copy has any other affinity.
- if (DstReg.isPhysical() ||
+ if (DstReg.isPhysical() ||
// If SrcReg is a physical register, the copy won't be coalesced.
// Ignoring it may have other side effect (like missing
// rematerialization). So keep it.
- SrcReg.isPhysical() || !isTerminalReg(DstReg, Copy, MRI))
+ SrcReg.isPhysical() || !isTerminalReg(DstReg, Copy, MRI))
return false;
// DstReg is a terminal node. Check if it interferes with any other
@@ -3822,8 +3822,8 @@ bool RegisterCoalescer::applyTerminalRule(const MachineInstr &Copy) const {
// For now, just consider the copies that are in the same block.
if (&MI == &Copy || !MI.isCopyLike() || MI.getParent() != OrigBB)
continue;
- Register OtherSrcReg, OtherReg;
- unsigned OtherSrcSubReg = 0, OtherSubReg = 0;
+ Register OtherSrcReg, OtherReg;
+ unsigned OtherSrcSubReg = 0, OtherSubReg = 0;
if (!isMoveInstr(*TRI, &Copy, OtherSrcReg, OtherReg, OtherSrcSubReg,
OtherSubReg))
return false;
@@ -4008,7 +4008,7 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) {
LLVM_DEBUG(dbgs() << "Trying to inflate " << InflateRegs.size()
<< " regs.\n");
for (unsigned i = 0, e = InflateRegs.size(); i != e; ++i) {
- Register Reg = InflateRegs[i];
+ Register Reg = InflateRegs[i];
if (MRI->reg_nodbg_empty(Reg))
continue;
if (MRI->recomputeRegClass(Reg)) {
diff --git a/contrib/libs/llvm12/lib/CodeGen/RegisterCoalescer.h b/contrib/libs/llvm12/lib/CodeGen/RegisterCoalescer.h
index 72c6fcb391..f265d93fb0 100644
--- a/contrib/libs/llvm12/lib/CodeGen/RegisterCoalescer.h
+++ b/contrib/libs/llvm12/lib/CodeGen/RegisterCoalescer.h
@@ -14,8 +14,8 @@
#ifndef LLVM_LIB_CODEGEN_REGISTERCOALESCER_H
#define LLVM_LIB_CODEGEN_REGISTERCOALESCER_H
-#include "llvm/CodeGen/Register.h"
-
+#include "llvm/CodeGen/Register.h"
+
namespace llvm {
class MachineInstr;
@@ -30,10 +30,10 @@ class TargetRegisterInfo;
/// The register that will be left after coalescing. It can be a
/// virtual or physical register.
- Register DstReg;
+ Register DstReg;
/// The virtual register that will be coalesced into dstReg.
- Register SrcReg;
+ Register SrcReg;
/// The sub-register index of the old DstReg in the new coalesced register.
unsigned DstIdx = 0;
@@ -61,9 +61,9 @@ class TargetRegisterInfo;
/// Create a CoalescerPair representing a virtreg-to-physreg copy.
/// No need to call setRegisters().
- CoalescerPair(Register VirtReg, MCRegister PhysReg,
+ CoalescerPair(Register VirtReg, MCRegister PhysReg,
const TargetRegisterInfo &tri)
- : TRI(tri), DstReg(PhysReg), SrcReg(VirtReg) {}
+ : TRI(tri), DstReg(PhysReg), SrcReg(VirtReg) {}
/// Set registers to match the copy instruction MI. Return
/// false if MI is not a coalescable copy instruction.
@@ -94,10 +94,10 @@ class TargetRegisterInfo;
/// Return the register (virtual or physical) that will remain
/// after coalescing.
- Register getDstReg() const { return DstReg; }
+ Register getDstReg() const { return DstReg; }
/// Return the virtual register that will be coalesced away.
- Register getSrcReg() const { return SrcReg; }
+ Register getSrcReg() const { return SrcReg; }
/// Return the subregister index that DstReg will be coalesced into, or 0.
unsigned getDstIdx() const { return DstIdx; }
diff --git a/contrib/libs/llvm12/lib/CodeGen/RegisterPressure.cpp b/contrib/libs/llvm12/lib/CodeGen/RegisterPressure.cpp
index 5c999984f4..8f1fc103e8 100644
--- a/contrib/libs/llvm12/lib/CodeGen/RegisterPressure.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/RegisterPressure.cpp
@@ -62,7 +62,7 @@ static void increaseSetPressure(std::vector<unsigned> &CurrSetPressure,
/// Decrease pressure for each pressure set provided by TargetRegisterInfo.
static void decreaseSetPressure(std::vector<unsigned> &CurrSetPressure,
- const MachineRegisterInfo &MRI, Register Reg,
+ const MachineRegisterInfo &MRI, Register Reg,
LaneBitmask PrevMask, LaneBitmask NewMask) {
//assert((NewMask & !PrevMask) == 0 && "Must not add bits");
if (NewMask.any() || PrevMask.none())
@@ -152,7 +152,7 @@ void RegPressureDelta::dump() const {
#endif
-void RegPressureTracker::increaseRegPressure(Register RegUnit,
+void RegPressureTracker::increaseRegPressure(Register RegUnit,
LaneBitmask PreviousMask,
LaneBitmask NewMask) {
if (PreviousMask.any() || NewMask.none())
@@ -167,7 +167,7 @@ void RegPressureTracker::increaseRegPressure(Register RegUnit,
}
}
-void RegPressureTracker::decreaseRegPressure(Register RegUnit,
+void RegPressureTracker::decreaseRegPressure(Register RegUnit,
LaneBitmask PreviousMask,
LaneBitmask NewMask) {
decreaseSetPressure(CurrSetPressure, *MRI, RegUnit, PreviousMask, NewMask);
@@ -360,7 +360,7 @@ void RegPressureTracker::initLiveThru(const RegPressureTracker &RPTracker) {
LiveThruPressure.assign(TRI->getNumRegPressureSets(), 0);
assert(isBottomClosed() && "need bottom-up tracking to intialize.");
for (const RegisterMaskPair &Pair : P.LiveOutRegs) {
- Register RegUnit = Pair.RegUnit;
+ Register RegUnit = Pair.RegUnit;
if (Register::isVirtualRegister(RegUnit)
&& !RPTracker.hasUntiedDef(RegUnit))
increaseSetPressure(LiveThruPressure, *MRI, RegUnit,
@@ -369,7 +369,7 @@ void RegPressureTracker::initLiveThru(const RegPressureTracker &RPTracker) {
}
static LaneBitmask getRegLanes(ArrayRef<RegisterMaskPair> RegUnits,
- Register RegUnit) {
+ Register RegUnit) {
auto I = llvm::find_if(RegUnits, [RegUnit](const RegisterMaskPair Other) {
return Other.RegUnit == RegUnit;
});
@@ -380,7 +380,7 @@ static LaneBitmask getRegLanes(ArrayRef<RegisterMaskPair> RegUnits,
static void addRegLanes(SmallVectorImpl<RegisterMaskPair> &RegUnits,
RegisterMaskPair Pair) {
- Register RegUnit = Pair.RegUnit;
+ Register RegUnit = Pair.RegUnit;
assert(Pair.LaneMask.any());
auto I = llvm::find_if(RegUnits, [RegUnit](const RegisterMaskPair Other) {
return Other.RegUnit == RegUnit;
@@ -393,7 +393,7 @@ static void addRegLanes(SmallVectorImpl<RegisterMaskPair> &RegUnits,
}
static void setRegZero(SmallVectorImpl<RegisterMaskPair> &RegUnits,
- Register RegUnit) {
+ Register RegUnit) {
auto I = llvm::find_if(RegUnits, [RegUnit](const RegisterMaskPair Other) {
return Other.RegUnit == RegUnit;
});
@@ -406,7 +406,7 @@ static void setRegZero(SmallVectorImpl<RegisterMaskPair> &RegUnits,
static void removeRegLanes(SmallVectorImpl<RegisterMaskPair> &RegUnits,
RegisterMaskPair Pair) {
- Register RegUnit = Pair.RegUnit;
+ Register RegUnit = Pair.RegUnit;
assert(Pair.LaneMask.any());
auto I = llvm::find_if(RegUnits, [RegUnit](const RegisterMaskPair Other) {
return Other.RegUnit == RegUnit;
@@ -418,12 +418,12 @@ static void removeRegLanes(SmallVectorImpl<RegisterMaskPair> &RegUnits,
}
}
-static LaneBitmask
-getLanesWithProperty(const LiveIntervals &LIS, const MachineRegisterInfo &MRI,
- bool TrackLaneMasks, Register RegUnit, SlotIndex Pos,
- LaneBitmask SafeDefault,
- bool (*Property)(const LiveRange &LR, SlotIndex Pos)) {
- if (RegUnit.isVirtual()) {
+static LaneBitmask
+getLanesWithProperty(const LiveIntervals &LIS, const MachineRegisterInfo &MRI,
+ bool TrackLaneMasks, Register RegUnit, SlotIndex Pos,
+ LaneBitmask SafeDefault,
+ bool (*Property)(const LiveRange &LR, SlotIndex Pos)) {
+ if (RegUnit.isVirtual()) {
const LiveInterval &LI = LIS.getInterval(RegUnit);
LaneBitmask Result;
if (TrackLaneMasks && LI.hasSubRanges()) {
@@ -449,7 +449,7 @@ getLanesWithProperty(const LiveIntervals &LIS, const MachineRegisterInfo &MRI,
static LaneBitmask getLiveLanesAt(const LiveIntervals &LIS,
const MachineRegisterInfo &MRI,
- bool TrackLaneMasks, Register RegUnit,
+ bool TrackLaneMasks, Register RegUnit,
SlotIndex Pos) {
return getLanesWithProperty(LIS, MRI, TrackLaneMasks, RegUnit, Pos,
LaneBitmask::getAll(),
@@ -517,13 +517,13 @@ class RegisterOperandsCollector {
}
}
- void pushReg(Register Reg,
+ void pushReg(Register Reg,
SmallVectorImpl<RegisterMaskPair> &RegUnits) const {
- if (Reg.isVirtual()) {
+ if (Reg.isVirtual()) {
addRegLanes(RegUnits, RegisterMaskPair(Reg, LaneBitmask::getAll()));
} else if (MRI.isAllocatable(Reg)) {
- for (MCRegUnitIterator Units(Reg.asMCReg(), &TRI); Units.isValid();
- ++Units)
+ for (MCRegUnitIterator Units(Reg.asMCReg(), &TRI); Units.isValid();
+ ++Units)
addRegLanes(RegUnits, RegisterMaskPair(*Units, LaneBitmask::getAll()));
}
}
@@ -550,16 +550,16 @@ class RegisterOperandsCollector {
}
}
- void pushRegLanes(Register Reg, unsigned SubRegIdx,
+ void pushRegLanes(Register Reg, unsigned SubRegIdx,
SmallVectorImpl<RegisterMaskPair> &RegUnits) const {
- if (Reg.isVirtual()) {
+ if (Reg.isVirtual()) {
LaneBitmask LaneMask = SubRegIdx != 0
? TRI.getSubRegIndexLaneMask(SubRegIdx)
: MRI.getMaxLaneMaskForVReg(Reg);
addRegLanes(RegUnits, RegisterMaskPair(Reg, LaneMask));
} else if (MRI.isAllocatable(Reg)) {
- for (MCRegUnitIterator Units(Reg.asMCReg(), &TRI); Units.isValid();
- ++Units)
+ for (MCRegUnitIterator Units(Reg.asMCReg(), &TRI); Units.isValid();
+ ++Units)
addRegLanes(RegUnits, RegisterMaskPair(*Units, LaneBitmask::getAll()));
}
}
@@ -582,7 +582,7 @@ void RegisterOperands::detectDeadDefs(const MachineInstr &MI,
const LiveIntervals &LIS) {
SlotIndex SlotIdx = LIS.getInstructionIndex(MI);
for (auto RI = Defs.begin(); RI != Defs.end(); /*empty*/) {
- Register Reg = RI->RegUnit;
+ Register Reg = RI->RegUnit;
const LiveRange *LR = getLiveRange(LIS, Reg);
if (LR != nullptr) {
LiveQueryResult LRQ = LR->Query(SlotIdx);
@@ -607,7 +607,7 @@ void RegisterOperands::adjustLaneLiveness(const LiveIntervals &LIS,
Pos.getDeadSlot());
// If the def is all that is live after the instruction, then in case
// of a subregister def we need a read-undef flag.
- Register RegUnit = I->RegUnit;
+ Register RegUnit = I->RegUnit;
if (Register::isVirtualRegister(RegUnit) &&
AddFlagsMI != nullptr && (LiveAfter & ~I->LaneMask).none())
AddFlagsMI->setRegisterDefReadUndef(RegUnit);
@@ -633,7 +633,7 @@ void RegisterOperands::adjustLaneLiveness(const LiveIntervals &LIS,
}
if (AddFlagsMI != nullptr) {
for (const RegisterMaskPair &P : DeadDefs) {
- Register RegUnit = P.RegUnit;
+ Register RegUnit = P.RegUnit;
if (!Register::isVirtualRegister(RegUnit))
continue;
LaneBitmask LiveAfter = getLiveLanesAt(LIS, MRI, true, RegUnit,
@@ -669,7 +669,7 @@ void PressureDiffs::addInstruction(unsigned Idx,
}
/// Add a change in pressure to the pressure diff of a given instruction.
-void PressureDiff::addPressureChange(Register RegUnit, bool IsDec,
+void PressureDiff::addPressureChange(Register RegUnit, bool IsDec,
const MachineRegisterInfo *MRI) {
PSetIterator PSetI = MRI->getPressureSets(RegUnit);
int Weight = IsDec ? -PSetI.getWeight() : PSetI.getWeight();
@@ -716,7 +716,7 @@ void RegPressureTracker::discoverLiveInOrOut(RegisterMaskPair Pair,
SmallVectorImpl<RegisterMaskPair> &LiveInOrOut) {
assert(Pair.LaneMask.any());
- Register RegUnit = Pair.RegUnit;
+ Register RegUnit = Pair.RegUnit;
auto I = llvm::find_if(LiveInOrOut, [RegUnit](const RegisterMaskPair &Other) {
return Other.RegUnit == RegUnit;
});
@@ -744,13 +744,13 @@ void RegPressureTracker::discoverLiveOut(RegisterMaskPair Pair) {
void RegPressureTracker::bumpDeadDefs(ArrayRef<RegisterMaskPair> DeadDefs) {
for (const RegisterMaskPair &P : DeadDefs) {
- Register Reg = P.RegUnit;
+ Register Reg = P.RegUnit;
LaneBitmask LiveMask = LiveRegs.contains(Reg);
LaneBitmask BumpedMask = LiveMask | P.LaneMask;
increaseRegPressure(Reg, LiveMask, BumpedMask);
}
for (const RegisterMaskPair &P : DeadDefs) {
- Register Reg = P.RegUnit;
+ Register Reg = P.RegUnit;
LaneBitmask LiveMask = LiveRegs.contains(Reg);
LaneBitmask BumpedMask = LiveMask | P.LaneMask;
decreaseRegPressure(Reg, BumpedMask, LiveMask);
@@ -772,7 +772,7 @@ void RegPressureTracker::recede(const RegisterOperands &RegOpers,
// Kill liveness at live defs.
// TODO: consider earlyclobbers?
for (const RegisterMaskPair &Def : RegOpers.Defs) {
- Register Reg = Def.RegUnit;
+ Register Reg = Def.RegUnit;
LaneBitmask PreviousMask = LiveRegs.erase(Def);
LaneBitmask NewMask = PreviousMask & ~Def.LaneMask;
@@ -802,7 +802,7 @@ void RegPressureTracker::recede(const RegisterOperands &RegOpers,
// Generate liveness for uses.
for (const RegisterMaskPair &Use : RegOpers.Uses) {
- Register Reg = Use.RegUnit;
+ Register Reg = Use.RegUnit;
assert(Use.LaneMask.any());
LaneBitmask PreviousMask = LiveRegs.insert(Use);
LaneBitmask NewMask = PreviousMask | Use.LaneMask;
@@ -842,7 +842,7 @@ void RegPressureTracker::recede(const RegisterOperands &RegOpers,
}
if (TrackUntiedDefs) {
for (const RegisterMaskPair &Def : RegOpers.Defs) {
- Register RegUnit = Def.RegUnit;
+ Register RegUnit = Def.RegUnit;
if (Register::isVirtualRegister(RegUnit) &&
(LiveRegs.contains(RegUnit) & Def.LaneMask).none())
UntiedDefs.insert(RegUnit);
@@ -913,7 +913,7 @@ void RegPressureTracker::advance(const RegisterOperands &RegOpers) {
}
for (const RegisterMaskPair &Use : RegOpers.Uses) {
- Register Reg = Use.RegUnit;
+ Register Reg = Use.RegUnit;
LaneBitmask LiveMask = LiveRegs.contains(Reg);
LaneBitmask LiveIn = Use.LaneMask & ~LiveMask;
if (LiveIn.any()) {
@@ -1062,7 +1062,7 @@ void RegPressureTracker::bumpUpwardPressure(const MachineInstr *MI) {
// Kill liveness at live defs.
for (const RegisterMaskPair &P : RegOpers.Defs) {
- Register Reg = P.RegUnit;
+ Register Reg = P.RegUnit;
LaneBitmask LiveLanes = LiveRegs.contains(Reg);
LaneBitmask UseLanes = getRegLanes(RegOpers.Uses, Reg);
LaneBitmask DefLanes = P.LaneMask;
@@ -1071,7 +1071,7 @@ void RegPressureTracker::bumpUpwardPressure(const MachineInstr *MI) {
}
// Generate liveness for uses.
for (const RegisterMaskPair &P : RegOpers.Uses) {
- Register Reg = P.RegUnit;
+ Register Reg = P.RegUnit;
LaneBitmask LiveLanes = LiveRegs.contains(Reg);
LaneBitmask LiveAfter = LiveLanes | P.LaneMask;
increaseRegPressure(Reg, LiveLanes, LiveAfter);
@@ -1242,7 +1242,7 @@ static LaneBitmask findUseBetween(unsigned Reg, LaneBitmask LastUseMask,
return LastUseMask;
}
-LaneBitmask RegPressureTracker::getLiveLanesAt(Register RegUnit,
+LaneBitmask RegPressureTracker::getLiveLanesAt(Register RegUnit,
SlotIndex Pos) const {
assert(RequireIntervals);
return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit, Pos,
@@ -1252,7 +1252,7 @@ LaneBitmask RegPressureTracker::getLiveLanesAt(Register RegUnit,
});
}
-LaneBitmask RegPressureTracker::getLastUsedLanes(Register RegUnit,
+LaneBitmask RegPressureTracker::getLastUsedLanes(Register RegUnit,
SlotIndex Pos) const {
assert(RequireIntervals);
return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit,
@@ -1263,7 +1263,7 @@ LaneBitmask RegPressureTracker::getLastUsedLanes(Register RegUnit,
});
}
-LaneBitmask RegPressureTracker::getLiveThroughAt(Register RegUnit,
+LaneBitmask RegPressureTracker::getLiveThroughAt(Register RegUnit,
SlotIndex Pos) const {
assert(RequireIntervals);
return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit, Pos,
@@ -1296,7 +1296,7 @@ void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) {
if (RequireIntervals) {
for (const RegisterMaskPair &Use : RegOpers.Uses) {
- Register Reg = Use.RegUnit;
+ Register Reg = Use.RegUnit;
LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx);
if (LastUseMask.none())
continue;
@@ -1319,7 +1319,7 @@ void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) {
// Generate liveness for defs.
for (const RegisterMaskPair &Def : RegOpers.Defs) {
- Register Reg = Def.RegUnit;
+ Register Reg = Def.RegUnit;
LaneBitmask LiveMask = LiveRegs.contains(Reg);
LaneBitmask NewMask = LiveMask | Def.LaneMask;
increaseRegPressure(Reg, LiveMask, NewMask);
diff --git a/contrib/libs/llvm12/lib/CodeGen/RegisterScavenging.cpp b/contrib/libs/llvm12/lib/CodeGen/RegisterScavenging.cpp
index 9311f96771..a833895c11 100644
--- a/contrib/libs/llvm12/lib/CodeGen/RegisterScavenging.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/RegisterScavenging.cpp
@@ -91,18 +91,18 @@ void RegScavenger::enterBasicBlockEnd(MachineBasicBlock &MBB) {
LiveUnits.addLiveOuts(MBB);
// Move internal iterator at the last instruction of the block.
- if (!MBB.empty()) {
+ if (!MBB.empty()) {
MBBI = std::prev(MBB.end());
Tracking = true;
}
}
-void RegScavenger::addRegUnits(BitVector &BV, MCRegister Reg) {
+void RegScavenger::addRegUnits(BitVector &BV, MCRegister Reg) {
for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI)
BV.set(*RUI);
}
-void RegScavenger::removeRegUnits(BitVector &BV, MCRegister Reg) {
+void RegScavenger::removeRegUnits(BitVector &BV, MCRegister Reg) {
for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI)
BV.reset(*RUI);
}
@@ -134,9 +134,9 @@ void RegScavenger::determineKillsAndDefs() {
}
if (!MO.isReg())
continue;
- if (!MO.getReg().isPhysical() || isReserved(MO.getReg()))
+ if (!MO.getReg().isPhysical() || isReserved(MO.getReg()))
continue;
- MCRegister Reg = MO.getReg().asMCReg();
+ MCRegister Reg = MO.getReg().asMCReg();
if (MO.isUse()) {
// Ignore undef uses.
@@ -574,7 +574,7 @@ Register RegScavenger::scavengeRegisterBackwards(const TargetRegisterClass &RC,
MCPhysReg Reg = P.first;
MachineBasicBlock::iterator SpillBefore = P.second;
// Found an available register?
- if (Reg != 0 && SpillBefore == MBB.end()) {
+ if (Reg != 0 && SpillBefore == MBB.end()) {
LLVM_DEBUG(dbgs() << "Scavenged free register: " << printReg(Reg, TRI)
<< '\n');
return Reg;
@@ -583,8 +583,8 @@ Register RegScavenger::scavengeRegisterBackwards(const TargetRegisterClass &RC,
if (!AllowSpill)
return 0;
- assert(Reg != 0 && "No register left to scavenge!");
-
+ assert(Reg != 0 && "No register left to scavenge!");
+
MachineBasicBlock::iterator ReloadAfter =
RestoreAfter ? std::next(MBBI) : MBBI;
MachineBasicBlock::iterator ReloadBefore = std::next(ReloadAfter);
@@ -634,10 +634,10 @@ static Register scavengeVReg(MachineRegisterInfo &MRI, RegScavenger &RS,
// we get a single contiguous lifetime.
//
// Definitions in MRI.def_begin() are unordered, search for the first.
- MachineRegisterInfo::def_iterator FirstDef = llvm::find_if(
- MRI.def_operands(VReg), [VReg, &TRI](const MachineOperand &MO) {
- return !MO.getParent()->readsRegister(VReg, &TRI);
- });
+ MachineRegisterInfo::def_iterator FirstDef = llvm::find_if(
+ MRI.def_operands(VReg), [VReg, &TRI](const MachineOperand &MO) {
+ return !MO.getParent()->readsRegister(VReg, &TRI);
+ });
assert(FirstDef != MRI.def_end() &&
"Must have one definition that does not redefine vreg");
MachineInstr &DefMI = *FirstDef->getParent();
diff --git a/contrib/libs/llvm12/lib/CodeGen/RenameIndependentSubregs.cpp b/contrib/libs/llvm12/lib/CodeGen/RenameIndependentSubregs.cpp
index 433c05dcf7..0872ec3034 100644
--- a/contrib/libs/llvm12/lib/CodeGen/RenameIndependentSubregs.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/RenameIndependentSubregs.cpp
@@ -130,7 +130,7 @@ bool RenameIndependentSubregs::renameComponents(LiveInterval &LI) const {
return false;
// Create a new VReg for each class.
- unsigned Reg = LI.reg();
+ unsigned Reg = LI.reg();
const TargetRegisterClass *RegClass = MRI->getRegClass(Reg);
SmallVector<LiveInterval*, 4> Intervals;
Intervals.push_back(&LI);
@@ -175,7 +175,7 @@ bool RenameIndependentSubregs::findComponents(IntEqClasses &Classes,
// across subranges when they are affected by the same MachineOperand.
const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
Classes.grow(NumComponents);
- unsigned Reg = LI.reg();
+ unsigned Reg = LI.reg();
for (const MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
if (!MO.isDef() && !MO.readsReg())
continue;
@@ -212,7 +212,7 @@ void RenameIndependentSubregs::rewriteOperands(const IntEqClasses &Classes,
const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
const SmallVectorImpl<LiveInterval*> &Intervals) const {
const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
- unsigned Reg = Intervals[0]->reg();
+ unsigned Reg = Intervals[0]->reg();
for (MachineRegisterInfo::reg_nodbg_iterator I = MRI->reg_nodbg_begin(Reg),
E = MRI->reg_nodbg_end(); I != E; ) {
MachineOperand &MO = *I++;
@@ -242,7 +242,7 @@ void RenameIndependentSubregs::rewriteOperands(const IntEqClasses &Classes,
break;
}
- unsigned VReg = Intervals[ID]->reg();
+ unsigned VReg = Intervals[ID]->reg();
MO.setReg(VReg);
if (MO.isTied() && Reg != VReg) {
@@ -304,7 +304,7 @@ void RenameIndependentSubregs::computeMainRangesFixFlags(
const SlotIndexes &Indexes = *LIS->getSlotIndexes();
for (size_t I = 0, E = Intervals.size(); I < E; ++I) {
LiveInterval &LI = *Intervals[I];
- unsigned Reg = LI.reg();
+ unsigned Reg = LI.reg();
LI.removeEmptySubRanges();
diff --git a/contrib/libs/llvm12/lib/CodeGen/SafeStack.cpp b/contrib/libs/llvm12/lib/CodeGen/SafeStack.cpp
index 968dd3f441..31797631c9 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SafeStack.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SafeStack.cpp
@@ -151,7 +151,7 @@ class SafeStack {
Value *getStackGuard(IRBuilder<> &IRB, Function &F);
/// Load stack guard from the frame and check if it has changed.
- void checkStackGuard(IRBuilder<> &IRB, Function &F, Instruction &RI,
+ void checkStackGuard(IRBuilder<> &IRB, Function &F, Instruction &RI,
AllocaInst *StackGuardSlot, Value *StackGuard);
/// Find all static allocas, dynamic allocas, return instructions and
@@ -160,7 +160,7 @@ class SafeStack {
void findInsts(Function &F, SmallVectorImpl<AllocaInst *> &StaticAllocas,
SmallVectorImpl<AllocaInst *> &DynamicAllocas,
SmallVectorImpl<Argument *> &ByValArguments,
- SmallVectorImpl<Instruction *> &Returns,
+ SmallVectorImpl<Instruction *> &Returns,
SmallVectorImpl<Instruction *> &StackRestorePoints);
/// Calculate the allocation size of a given alloca. Returns 0 if the
@@ -168,7 +168,7 @@ class SafeStack {
uint64_t getStaticAllocaAllocationSize(const AllocaInst* AI);
/// Allocate space for all static allocas in \p StaticAllocas,
- /// replace allocas with pointers into the unsafe stack.
+ /// replace allocas with pointers into the unsafe stack.
///
/// \returns A pointer to the top of the unsafe stack after all unsafe static
/// allocas are allocated.
@@ -381,7 +381,7 @@ void SafeStack::findInsts(Function &F,
SmallVectorImpl<AllocaInst *> &StaticAllocas,
SmallVectorImpl<AllocaInst *> &DynamicAllocas,
SmallVectorImpl<Argument *> &ByValArguments,
- SmallVectorImpl<Instruction *> &Returns,
+ SmallVectorImpl<Instruction *> &Returns,
SmallVectorImpl<Instruction *> &StackRestorePoints) {
for (Instruction &I : instructions(&F)) {
if (auto AI = dyn_cast<AllocaInst>(&I)) {
@@ -399,10 +399,10 @@ void SafeStack::findInsts(Function &F,
DynamicAllocas.push_back(AI);
}
} else if (auto RI = dyn_cast<ReturnInst>(&I)) {
- if (CallInst *CI = I.getParent()->getTerminatingMustTailCall())
- Returns.push_back(CI);
- else
- Returns.push_back(RI);
+ if (CallInst *CI = I.getParent()->getTerminatingMustTailCall())
+ Returns.push_back(CI);
+ else
+ Returns.push_back(RI);
} else if (auto CI = dyn_cast<CallInst>(&I)) {
// setjmps require stack restore.
if (CI->getCalledFunction() && CI->canReturnTwice())
@@ -466,7 +466,7 @@ SafeStack::createStackRestorePoints(IRBuilder<> &IRB, Function &F,
return DynamicTop;
}
-void SafeStack::checkStackGuard(IRBuilder<> &IRB, Function &F, Instruction &RI,
+void SafeStack::checkStackGuard(IRBuilder<> &IRB, Function &F, Instruction &RI,
AllocaInst *StackGuardSlot, Value *StackGuard) {
Value *V = IRB.CreateLoad(StackPtrTy, StackGuardSlot);
Value *Cmp = IRB.CreateICmpNE(StackGuard, V);
@@ -491,8 +491,8 @@ void SafeStack::checkStackGuard(IRBuilder<> &IRB, Function &F, Instruction &RI,
/// prologue into a local variable and restore it in the epilogue.
Value *SafeStack::moveStaticAllocasToUnsafeStack(
IRBuilder<> &IRB, Function &F, ArrayRef<AllocaInst *> StaticAllocas,
- ArrayRef<Argument *> ByValArguments, Instruction *BasePointer,
- AllocaInst *StackGuardSlot) {
+ ArrayRef<Argument *> ByValArguments, Instruction *BasePointer,
+ AllocaInst *StackGuardSlot) {
if (StaticAllocas.empty() && ByValArguments.empty())
return BasePointer;
@@ -760,7 +760,7 @@ bool SafeStack::run() {
SmallVector<AllocaInst *, 16> StaticAllocas;
SmallVector<AllocaInst *, 4> DynamicAllocas;
SmallVector<Argument *, 4> ByValArguments;
- SmallVector<Instruction *, 4> Returns;
+ SmallVector<Instruction *, 4> Returns;
// Collect all points where stack gets unwound and needs to be restored
// This is only necessary because the runtime (setjmp and unwind code) is
@@ -789,8 +789,8 @@ bool SafeStack::run() {
// Calls must always have a debug location, or else inlining breaks. So
// we explicitly set a artificial debug location here.
if (DISubprogram *SP = F.getSubprogram())
- IRB.SetCurrentDebugLocation(
- DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP));
+ IRB.SetCurrentDebugLocation(
+ DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP));
if (SafeStackUsePointerAddress) {
FunctionCallee Fn = F.getParent()->getOrInsertFunction(
"__safestack_pointer_address", StackPtrTy->getPointerTo(0));
@@ -814,7 +814,7 @@ bool SafeStack::run() {
StackGuardSlot = IRB.CreateAlloca(StackPtrTy, nullptr);
IRB.CreateStore(StackGuard, StackGuardSlot);
- for (Instruction *RI : Returns) {
+ for (Instruction *RI : Returns) {
IRBuilder<> IRBRet(RI);
checkStackGuard(IRBRet, F, *RI, StackGuardSlot, StackGuard);
}
@@ -822,8 +822,8 @@ bool SafeStack::run() {
// The top of the unsafe stack after all unsafe static allocas are
// allocated.
- Value *StaticTop = moveStaticAllocasToUnsafeStack(
- IRB, F, StaticAllocas, ByValArguments, BasePointer, StackGuardSlot);
+ Value *StaticTop = moveStaticAllocasToUnsafeStack(
+ IRB, F, StaticAllocas, ByValArguments, BasePointer, StackGuardSlot);
// Safe stack object that stores the current unsafe stack top. It is updated
// as unsafe dynamic (non-constant-sized) allocas are allocated and freed.
@@ -839,7 +839,7 @@ bool SafeStack::run() {
DynamicAllocas);
// Restore the unsafe stack pointer before each return.
- for (Instruction *RI : Returns) {
+ for (Instruction *RI : Returns) {
IRB.SetInsertPoint(RI);
IRB.CreateStore(BasePointer, UnsafeStackPtr);
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/SafeStackLayout.cpp b/contrib/libs/llvm12/lib/CodeGen/SafeStackLayout.cpp
index 048371571e..5d61b3a146 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SafeStackLayout.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SafeStackLayout.cpp
@@ -140,10 +140,10 @@ void StackLayout::computeLayout() {
// Sort objects by size (largest first) to reduce fragmentation.
if (StackObjects.size() > 2)
- llvm::stable_sort(drop_begin(StackObjects),
- [](const StackObject &a, const StackObject &b) {
- return a.Size > b.Size;
- });
+ llvm::stable_sort(drop_begin(StackObjects),
+ [](const StackObject &a, const StackObject &b) {
+ return a.Size > b.Size;
+ });
for (auto &Obj : StackObjects)
layoutObject(Obj);
diff --git a/contrib/libs/llvm12/lib/CodeGen/ScheduleDAGInstrs.cpp b/contrib/libs/llvm12/lib/CodeGen/ScheduleDAGInstrs.cpp
index 41471e2503..5899da777f 100644
--- a/contrib/libs/llvm12/lib/CodeGen/ScheduleDAGInstrs.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/ScheduleDAGInstrs.cpp
@@ -154,7 +154,7 @@ static bool getUnderlyingObjectsForInstr(const MachineInstr *MI,
Objects.push_back(UnderlyingObjectsVector::value_type(PSV, MayAlias));
} else if (const Value *V = MMO->getValue()) {
SmallVector<Value *, 4> Objs;
- if (!getUnderlyingObjectsForCodeGen(V, Objs))
+ if (!getUnderlyingObjectsForCodeGen(V, Objs))
return false;
for (Value *V : Objs) {
@@ -199,10 +199,10 @@ void ScheduleDAGInstrs::exitRegion() {
}
void ScheduleDAGInstrs::addSchedBarrierDeps() {
- MachineInstr *ExitMI =
- RegionEnd != BB->end()
- ? &*skipDebugInstructionsBackward(RegionEnd, RegionBegin)
- : nullptr;
+ MachineInstr *ExitMI =
+ RegionEnd != BB->end()
+ ? &*skipDebugInstructionsBackward(RegionEnd, RegionBegin)
+ : nullptr;
ExitSU.setInstr(ExitMI);
// Add dependencies on the defs and uses of the instruction.
if (ExitMI) {
@@ -514,8 +514,8 @@ void ScheduleDAGInstrs::addVRegDefDeps(SUnit *SU, unsigned OperIdx) {
/// TODO: Handle ExitSU "uses" properly.
void ScheduleDAGInstrs::addVRegUseDeps(SUnit *SU, unsigned OperIdx) {
const MachineInstr *MI = SU->getInstr();
- assert(!MI->isDebugInstr());
-
+ assert(!MI->isDebugInstr());
+
const MachineOperand &MO = MI->getOperand(OperIdx);
Register Reg = MO.getReg();
@@ -807,7 +807,7 @@ void ScheduleDAGInstrs::buildSchedGraph(AAResults *AA,
DbgMI = nullptr;
}
- if (MI.isDebugValue() || MI.isDebugRef()) {
+ if (MI.isDebugValue() || MI.isDebugRef()) {
DbgMI = &MI;
continue;
}
@@ -1187,7 +1187,7 @@ std::string ScheduleDAGInstrs::getGraphNodeLabel(const SUnit *SU) const {
else if (SU == &ExitSU)
oss << "<exit>";
else
- SU->getInstr()->print(oss, /*IsStandalone=*/true);
+ SU->getInstr()->print(oss, /*IsStandalone=*/true);
return oss.str();
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/ScheduleDAGPrinter.cpp b/contrib/libs/llvm12/lib/CodeGen/ScheduleDAGPrinter.cpp
index d910da2ae6..05b2a3764c 100644
--- a/contrib/libs/llvm12/lib/CodeGen/ScheduleDAGPrinter.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/ScheduleDAGPrinter.cpp
@@ -35,7 +35,7 @@ namespace llvm {
return true;
}
- static bool isNodeHidden(const SUnit *Node, const ScheduleDAG *G) {
+ static bool isNodeHidden(const SUnit *Node, const ScheduleDAG *G) {
return (Node->NumPreds > 10 || Node->NumSuccs > 10);
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 505253e02f..7f2add81e8 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -24,14 +24,14 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/SmallBitVector.h"
+#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/MemoryLocation.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/CodeGen/DAGCombine.h"
#include "llvm/CodeGen/ISDOpcodes.h"
@@ -412,11 +412,11 @@ namespace {
SDValue visitSUBO(SDNode *N);
SDValue visitADDE(SDNode *N);
SDValue visitADDCARRY(SDNode *N);
- SDValue visitSADDO_CARRY(SDNode *N);
+ SDValue visitSADDO_CARRY(SDNode *N);
SDValue visitADDCARRYLike(SDValue N0, SDValue N1, SDValue CarryIn, SDNode *N);
SDValue visitSUBE(SDNode *N);
SDValue visitSUBCARRY(SDNode *N);
- SDValue visitSSUBO_CARRY(SDNode *N);
+ SDValue visitSSUBO_CARRY(SDNode *N);
SDValue visitMUL(SDNode *N);
SDValue visitMULFIX(SDNode *N);
SDValue useDivRem(SDNode *N);
@@ -468,7 +468,7 @@ namespace {
SDValue visitFREEZE(SDNode *N);
SDValue visitBUILD_PAIR(SDNode *N);
SDValue visitFADD(SDNode *N);
- SDValue visitSTRICT_FADD(SDNode *N);
+ SDValue visitSTRICT_FADD(SDNode *N);
SDValue visitFSUB(SDNode *N);
SDValue visitFMUL(SDNode *N);
SDValue visitFMA(SDNode *N);
@@ -544,7 +544,7 @@ namespace {
SDValue convertSelectOfFPConstantsToLoadOffset(
const SDLoc &DL, SDValue N0, SDValue N1, SDValue N2, SDValue N3,
ISD::CondCode CC);
- SDValue foldSignChangeInBitcast(SDNode *N);
+ SDValue foldSignChangeInBitcast(SDNode *N);
SDValue foldSelectCCToShiftAnd(const SDLoc &DL, SDValue N0, SDValue N1,
SDValue N2, SDValue N3, ISD::CondCode CC);
SDValue foldLogicOfSetCCs(bool IsAnd, SDValue N0, SDValue N1,
@@ -592,7 +592,7 @@ namespace {
const SDLoc &DL);
SDValue MatchRotate(SDValue LHS, SDValue RHS, const SDLoc &DL);
SDValue MatchLoadCombine(SDNode *N);
- SDValue mergeTruncStores(StoreSDNode *N);
+ SDValue mergeTruncStores(StoreSDNode *N);
SDValue ReduceLoadWidth(SDNode *N);
SDValue ReduceLoadOpStoreWidth(SDNode *N);
SDValue splitMergedValStore(StoreSDNode *ST);
@@ -647,18 +647,18 @@ namespace {
// Classify the origin of a stored value.
enum class StoreSource { Unknown, Constant, Extract, Load };
StoreSource getStoreSource(SDValue StoreVal) {
- switch (StoreVal.getOpcode()) {
- case ISD::Constant:
- case ISD::ConstantFP:
+ switch (StoreVal.getOpcode()) {
+ case ISD::Constant:
+ case ISD::ConstantFP:
return StoreSource::Constant;
- case ISD::EXTRACT_VECTOR_ELT:
- case ISD::EXTRACT_SUBVECTOR:
+ case ISD::EXTRACT_VECTOR_ELT:
+ case ISD::EXTRACT_SUBVECTOR:
return StoreSource::Extract;
- case ISD::LOAD:
+ case ISD::LOAD:
return StoreSource::Load;
- default:
- return StoreSource::Unknown;
- }
+ default:
+ return StoreSource::Unknown;
+ }
}
/// This is a helper function for visitMUL to check the profitability
@@ -762,7 +762,7 @@ namespace {
/// is legal or custom before legalizing operations, and whether is
/// legal (but not custom) after legalization.
bool hasOperation(unsigned Opcode, EVT VT) {
- return TLI.isOperationLegalOrCustom(Opcode, VT, LegalOperations);
+ return TLI.isOperationLegalOrCustom(Opcode, VT, LegalOperations);
}
public:
@@ -932,40 +932,40 @@ bool DAGCombiner::isOneUseSetCC(SDValue N) const {
return false;
}
-static bool isConstantSplatVectorMaskForType(SDNode *N, EVT ScalarTy) {
- if (!ScalarTy.isSimple())
- return false;
-
- uint64_t MaskForTy = 0ULL;
- switch (ScalarTy.getSimpleVT().SimpleTy) {
- case MVT::i8:
- MaskForTy = 0xFFULL;
- break;
- case MVT::i16:
- MaskForTy = 0xFFFFULL;
- break;
- case MVT::i32:
- MaskForTy = 0xFFFFFFFFULL;
- break;
- default:
- return false;
- break;
- }
-
- APInt Val;
- if (ISD::isConstantSplatVector(N, Val))
- return Val.getLimitedValue() == MaskForTy;
-
- return false;
-}
-
-// Determines if it is a constant integer or a splat/build vector of constant
+static bool isConstantSplatVectorMaskForType(SDNode *N, EVT ScalarTy) {
+ if (!ScalarTy.isSimple())
+ return false;
+
+ uint64_t MaskForTy = 0ULL;
+ switch (ScalarTy.getSimpleVT().SimpleTy) {
+ case MVT::i8:
+ MaskForTy = 0xFFULL;
+ break;
+ case MVT::i16:
+ MaskForTy = 0xFFFFULL;
+ break;
+ case MVT::i32:
+ MaskForTy = 0xFFFFFFFFULL;
+ break;
+ default:
+ return false;
+ break;
+ }
+
+ APInt Val;
+ if (ISD::isConstantSplatVector(N, Val))
+ return Val.getLimitedValue() == MaskForTy;
+
+ return false;
+}
+
+// Determines if it is a constant integer or a splat/build vector of constant
// integers (and undefs).
// Do not permit build vector implicit truncation.
static bool isConstantOrConstantVector(SDValue N, bool NoOpaques = false) {
if (ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N))
return !(Const->isOpaque() && NoOpaques);
- if (N.getOpcode() != ISD::BUILD_VECTOR && N.getOpcode() != ISD::SPLAT_VECTOR)
+ if (N.getOpcode() != ISD::BUILD_VECTOR && N.getOpcode() != ISD::SPLAT_VECTOR)
return false;
unsigned BitWidth = N.getScalarValueSizeInBits();
for (const SDValue &Op : N->op_values()) {
@@ -1579,15 +1579,15 @@ void DAGCombiner::Run(CombineLevel AtLevel) {
DAG.ReplaceAllUsesWith(N, &RV);
}
- // Push the new node and any users onto the worklist. Omit this if the
- // new node is the EntryToken (e.g. if a store managed to get optimized
- // out), because re-visiting the EntryToken and its users will not uncover
- // any additional opportunities, but there may be a large number of such
- // users, potentially causing compile time explosion.
- if (RV.getOpcode() != ISD::EntryToken) {
- AddToWorklist(RV.getNode());
- AddUsersToWorklist(RV.getNode());
- }
+ // Push the new node and any users onto the worklist. Omit this if the
+ // new node is the EntryToken (e.g. if a store managed to get optimized
+ // out), because re-visiting the EntryToken and its users will not uncover
+ // any additional opportunities, but there may be a large number of such
+ // users, potentially causing compile time explosion.
+ if (RV.getOpcode() != ISD::EntryToken) {
+ AddToWorklist(RV.getNode());
+ AddUsersToWorklist(RV.getNode());
+ }
// Finally, if the node is now dead, remove it from the graph. The node
// may not be dead if the replacement process recursively simplified to
@@ -1620,10 +1620,10 @@ SDValue DAGCombiner::visit(SDNode *N) {
case ISD::USUBO: return visitSUBO(N);
case ISD::ADDE: return visitADDE(N);
case ISD::ADDCARRY: return visitADDCARRY(N);
- case ISD::SADDO_CARRY: return visitSADDO_CARRY(N);
+ case ISD::SADDO_CARRY: return visitSADDO_CARRY(N);
case ISD::SUBE: return visitSUBE(N);
case ISD::SUBCARRY: return visitSUBCARRY(N);
- case ISD::SSUBO_CARRY: return visitSSUBO_CARRY(N);
+ case ISD::SSUBO_CARRY: return visitSSUBO_CARRY(N);
case ISD::SMULFIX:
case ISD::SMULFIXSAT:
case ISD::UMULFIX:
@@ -1679,7 +1679,7 @@ SDValue DAGCombiner::visit(SDNode *N) {
case ISD::BITCAST: return visitBITCAST(N);
case ISD::BUILD_PAIR: return visitBUILD_PAIR(N);
case ISD::FADD: return visitFADD(N);
- case ISD::STRICT_FADD: return visitSTRICT_FADD(N);
+ case ISD::STRICT_FADD: return visitSTRICT_FADD(N);
case ISD::FSUB: return visitFSUB(N);
case ISD::FMUL: return visitFMUL(N);
case ISD::FMA: return visitFMA(N);
@@ -1839,10 +1839,10 @@ SDValue DAGCombiner::visitTokenFactor(SDNode *N) {
if (OptLevel == CodeGenOpt::None)
return SDValue();
- // Don't simplify the token factor if the node itself has too many operands.
- if (N->getNumOperands() > TokenFactorInlineLimit)
- return SDValue();
-
+ // Don't simplify the token factor if the node itself has too many operands.
+ if (N->getNumOperands() > TokenFactorInlineLimit)
+ return SDValue();
+
// If the sole user is a token factor, we should make sure we have a
// chance to merge them together. This prevents TF chains from inhibiting
// optimizations.
@@ -1928,7 +1928,7 @@ SDValue DAGCombiner::visitTokenFactor(SDNode *N) {
auto AddToWorklist = [&](unsigned CurIdx, SDNode *Op, unsigned OpNumber) {
// If this is an Op, we can remove the op from the list. Remark any
// search associated with it as from the current OpNumber.
- if (SeenOps.contains(Op)) {
+ if (SeenOps.contains(Op)) {
Changed = true;
DidPruneOps = true;
unsigned OrigOpNumber = 0;
@@ -2040,62 +2040,62 @@ static ConstantSDNode *getAsNonOpaqueConstant(SDValue N) {
return Const != nullptr && !Const->isOpaque() ? Const : nullptr;
}
-/// Return true if 'Use' is a load or a store that uses N as its base pointer
-/// and that N may be folded in the load / store addressing mode.
-static bool canFoldInAddressingMode(SDNode *N, SDNode *Use, SelectionDAG &DAG,
- const TargetLowering &TLI) {
- EVT VT;
- unsigned AS;
-
- if (LoadSDNode *LD = dyn_cast<LoadSDNode>(Use)) {
- if (LD->isIndexed() || LD->getBasePtr().getNode() != N)
- return false;
- VT = LD->getMemoryVT();
- AS = LD->getAddressSpace();
- } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(Use)) {
- if (ST->isIndexed() || ST->getBasePtr().getNode() != N)
- return false;
- VT = ST->getMemoryVT();
- AS = ST->getAddressSpace();
- } else if (MaskedLoadSDNode *LD = dyn_cast<MaskedLoadSDNode>(Use)) {
- if (LD->isIndexed() || LD->getBasePtr().getNode() != N)
- return false;
- VT = LD->getMemoryVT();
- AS = LD->getAddressSpace();
- } else if (MaskedStoreSDNode *ST = dyn_cast<MaskedStoreSDNode>(Use)) {
- if (ST->isIndexed() || ST->getBasePtr().getNode() != N)
- return false;
- VT = ST->getMemoryVT();
- AS = ST->getAddressSpace();
- } else
- return false;
-
- TargetLowering::AddrMode AM;
- if (N->getOpcode() == ISD::ADD) {
- AM.HasBaseReg = true;
- ConstantSDNode *Offset = dyn_cast<ConstantSDNode>(N->getOperand(1));
- if (Offset)
- // [reg +/- imm]
- AM.BaseOffs = Offset->getSExtValue();
- else
- // [reg +/- reg]
- AM.Scale = 1;
- } else if (N->getOpcode() == ISD::SUB) {
- AM.HasBaseReg = true;
- ConstantSDNode *Offset = dyn_cast<ConstantSDNode>(N->getOperand(1));
- if (Offset)
- // [reg +/- imm]
- AM.BaseOffs = -Offset->getSExtValue();
- else
- // [reg +/- reg]
- AM.Scale = 1;
- } else
- return false;
-
- return TLI.isLegalAddressingMode(DAG.getDataLayout(), AM,
- VT.getTypeForEVT(*DAG.getContext()), AS);
-}
-
+/// Return true if 'Use' is a load or a store that uses N as its base pointer
+/// and that N may be folded in the load / store addressing mode.
+static bool canFoldInAddressingMode(SDNode *N, SDNode *Use, SelectionDAG &DAG,
+ const TargetLowering &TLI) {
+ EVT VT;
+ unsigned AS;
+
+ if (LoadSDNode *LD = dyn_cast<LoadSDNode>(Use)) {
+ if (LD->isIndexed() || LD->getBasePtr().getNode() != N)
+ return false;
+ VT = LD->getMemoryVT();
+ AS = LD->getAddressSpace();
+ } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(Use)) {
+ if (ST->isIndexed() || ST->getBasePtr().getNode() != N)
+ return false;
+ VT = ST->getMemoryVT();
+ AS = ST->getAddressSpace();
+ } else if (MaskedLoadSDNode *LD = dyn_cast<MaskedLoadSDNode>(Use)) {
+ if (LD->isIndexed() || LD->getBasePtr().getNode() != N)
+ return false;
+ VT = LD->getMemoryVT();
+ AS = LD->getAddressSpace();
+ } else if (MaskedStoreSDNode *ST = dyn_cast<MaskedStoreSDNode>(Use)) {
+ if (ST->isIndexed() || ST->getBasePtr().getNode() != N)
+ return false;
+ VT = ST->getMemoryVT();
+ AS = ST->getAddressSpace();
+ } else
+ return false;
+
+ TargetLowering::AddrMode AM;
+ if (N->getOpcode() == ISD::ADD) {
+ AM.HasBaseReg = true;
+ ConstantSDNode *Offset = dyn_cast<ConstantSDNode>(N->getOperand(1));
+ if (Offset)
+ // [reg +/- imm]
+ AM.BaseOffs = Offset->getSExtValue();
+ else
+ // [reg +/- reg]
+ AM.Scale = 1;
+ } else if (N->getOpcode() == ISD::SUB) {
+ AM.HasBaseReg = true;
+ ConstantSDNode *Offset = dyn_cast<ConstantSDNode>(N->getOperand(1));
+ if (Offset)
+ // [reg +/- imm]
+ AM.BaseOffs = -Offset->getSExtValue();
+ else
+ // [reg +/- reg]
+ AM.Scale = 1;
+ } else
+ return false;
+
+ return TLI.isLegalAddressingMode(DAG.getDataLayout(), AM,
+ VT.getTypeForEVT(*DAG.getContext()), AS);
+}
+
SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
assert(TLI.isBinOp(BO->getOpcode()) && BO->getNumValues() == 1 &&
"Unexpected binary operator");
@@ -2115,12 +2115,12 @@ SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
SDValue CT = Sel.getOperand(1);
if (!isConstantOrConstantVector(CT, true) &&
- !DAG.isConstantFPBuildVectorOrConstantFP(CT))
+ !DAG.isConstantFPBuildVectorOrConstantFP(CT))
return SDValue();
SDValue CF = Sel.getOperand(2);
if (!isConstantOrConstantVector(CF, true) &&
- !DAG.isConstantFPBuildVectorOrConstantFP(CF))
+ !DAG.isConstantFPBuildVectorOrConstantFP(CF))
return SDValue();
// Bail out if any constants are opaque because we can't constant fold those.
@@ -2137,10 +2137,10 @@ SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
SDValue CBO = BO->getOperand(SelOpNo ^ 1);
if (!CanFoldNonConst &&
!isConstantOrConstantVector(CBO, true) &&
- !DAG.isConstantFPBuildVectorOrConstantFP(CBO))
+ !DAG.isConstantFPBuildVectorOrConstantFP(CBO))
return SDValue();
- EVT VT = BO->getValueType(0);
+ EVT VT = BO->getValueType(0);
// We have a select-of-constants followed by a binary operator with a
// constant. Eliminate the binop by pulling the constant math into the select.
@@ -2150,14 +2150,14 @@ SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
: DAG.getNode(BinOpcode, DL, VT, CT, CBO);
if (!CanFoldNonConst && !NewCT.isUndef() &&
!isConstantOrConstantVector(NewCT, true) &&
- !DAG.isConstantFPBuildVectorOrConstantFP(NewCT))
+ !DAG.isConstantFPBuildVectorOrConstantFP(NewCT))
return SDValue();
SDValue NewCF = SelOpNo ? DAG.getNode(BinOpcode, DL, VT, CBO, CF)
: DAG.getNode(BinOpcode, DL, VT, CF, CBO);
if (!CanFoldNonConst && !NewCF.isUndef() &&
!isConstantOrConstantVector(NewCF, true) &&
- !DAG.isConstantFPBuildVectorOrConstantFP(NewCF))
+ !DAG.isConstantFPBuildVectorOrConstantFP(NewCF))
return SDValue();
SDValue SelectOp = DAG.getSelect(DL, VT, Sel.getOperand(0), NewCT, NewCF);
@@ -2487,8 +2487,8 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
// Fold (add (vscale * C0), (vscale * C1)) to (vscale * (C0 + C1)).
if (N0.getOpcode() == ISD::VSCALE && N1.getOpcode() == ISD::VSCALE) {
- const APInt &C0 = N0->getConstantOperandAPInt(0);
- const APInt &C1 = N1->getConstantOperandAPInt(0);
+ const APInt &C0 = N0->getConstantOperandAPInt(0);
+ const APInt &C1 = N1->getConstantOperandAPInt(0);
return DAG.getVScale(DL, VT, C0 + C1);
}
@@ -2496,9 +2496,9 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
if ((N0.getOpcode() == ISD::ADD) &&
(N0.getOperand(1).getOpcode() == ISD::VSCALE) &&
(N1.getOpcode() == ISD::VSCALE)) {
- const APInt &VS0 = N0.getOperand(1)->getConstantOperandAPInt(0);
- const APInt &VS1 = N1->getConstantOperandAPInt(0);
- SDValue VS = DAG.getVScale(DL, VT, VS0 + VS1);
+ const APInt &VS0 = N0.getOperand(1)->getConstantOperandAPInt(0);
+ const APInt &VS1 = N1->getConstantOperandAPInt(0);
+ SDValue VS = DAG.getVScale(DL, VT, VS0 + VS1);
return DAG.getNode(ISD::ADD, DL, VT, N0.getOperand(0), VS);
}
@@ -2721,13 +2721,13 @@ SDValue DAGCombiner::visitADDC(SDNode *N) {
* then the flip also occurs if computing the inverse is the same cost.
* This function returns an empty SDValue in case it cannot flip the boolean
* without increasing the cost of the computation. If you want to flip a boolean
- * no matter what, use DAG.getLogicalNOT.
+ * no matter what, use DAG.getLogicalNOT.
*/
static SDValue extractBooleanFlip(SDValue V, SelectionDAG &DAG,
const TargetLowering &TLI,
bool Force) {
if (Force && isa<ConstantSDNode>(V))
- return DAG.getLogicalNOT(SDLoc(V), V, V.getValueType());
+ return DAG.getLogicalNOT(SDLoc(V), V, V.getValueType());
if (V.getOpcode() != ISD::XOR)
return SDValue();
@@ -2754,7 +2754,7 @@ static SDValue extractBooleanFlip(SDValue V, SelectionDAG &DAG,
if (IsFlip)
return V.getOperand(0);
if (Force)
- return DAG.getLogicalNOT(SDLoc(V), V, V.getValueType());
+ return DAG.getLogicalNOT(SDLoc(V), V, V.getValueType());
return SDValue();
}
@@ -2791,8 +2791,8 @@ SDValue DAGCombiner::visitADDO(SDNode *N) {
if (isBitwiseNot(N0) && isOneOrOneSplat(N1)) {
SDValue Sub = DAG.getNode(ISD::USUBO, DL, N->getVTList(),
DAG.getConstant(0, DL, VT), N0.getOperand(0));
- return CombineTo(
- N, Sub, DAG.getLogicalNOT(DL, Sub.getValue(1), Sub->getValueType(1)));
+ return CombineTo(
+ N, Sub, DAG.getLogicalNOT(DL, Sub.getValue(1), Sub->getValueType(1)));
}
if (SDValue Combined = visitUADDOLike(N0, N1, N))
@@ -2887,28 +2887,28 @@ SDValue DAGCombiner::visitADDCARRY(SDNode *N) {
return SDValue();
}
-SDValue DAGCombiner::visitSADDO_CARRY(SDNode *N) {
- SDValue N0 = N->getOperand(0);
- SDValue N1 = N->getOperand(1);
- SDValue CarryIn = N->getOperand(2);
- SDLoc DL(N);
-
- // canonicalize constant to RHS
- ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
- ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
- if (N0C && !N1C)
- return DAG.getNode(ISD::SADDO_CARRY, DL, N->getVTList(), N1, N0, CarryIn);
-
- // fold (saddo_carry x, y, false) -> (saddo x, y)
- if (isNullConstant(CarryIn)) {
- if (!LegalOperations ||
- TLI.isOperationLegalOrCustom(ISD::SADDO, N->getValueType(0)))
- return DAG.getNode(ISD::SADDO, DL, N->getVTList(), N0, N1);
- }
-
- return SDValue();
-}
-
+SDValue DAGCombiner::visitSADDO_CARRY(SDNode *N) {
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ SDValue CarryIn = N->getOperand(2);
+ SDLoc DL(N);
+
+ // canonicalize constant to RHS
+ ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
+ ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
+ if (N0C && !N1C)
+ return DAG.getNode(ISD::SADDO_CARRY, DL, N->getVTList(), N1, N0, CarryIn);
+
+ // fold (saddo_carry x, y, false) -> (saddo x, y)
+ if (isNullConstant(CarryIn)) {
+ if (!LegalOperations ||
+ TLI.isOperationLegalOrCustom(ISD::SADDO, N->getValueType(0)))
+ return DAG.getNode(ISD::SADDO, DL, N->getVTList(), N0, N1);
+ }
+
+ return SDValue();
+}
+
/**
* If we are facing some sort of diamond carry propapagtion pattern try to
* break it up to generate something like:
@@ -3094,8 +3094,8 @@ SDValue DAGCombiner::visitADDCARRYLike(SDValue N0, SDValue N1, SDValue CarryIn,
SDLoc DL(N);
SDValue Sub = DAG.getNode(ISD::SUBCARRY, DL, N->getVTList(), N1,
N0.getOperand(0), NotC);
- return CombineTo(
- N, Sub, DAG.getLogicalNOT(DL, Sub.getValue(1), Sub->getValueType(1)));
+ return CombineTo(
+ N, Sub, DAG.getLogicalNOT(DL, Sub.getValue(1), Sub->getValueType(1)));
}
// Iff the flag result is dead:
@@ -3200,13 +3200,13 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
// 0 - X --> X if X is 0 or the minimum signed value.
return N1;
}
-
- // Convert 0 - abs(x).
- SDValue Result;
- if (N1->getOpcode() == ISD::ABS &&
- !TLI.isOperationLegalOrCustom(ISD::ABS, VT) &&
- TLI.expandABS(N1.getNode(), Result, DAG, true))
- return Result;
+
+ // Convert 0 - abs(x).
+ SDValue Result;
+ if (N1->getOpcode() == ISD::ABS &&
+ !TLI.isOperationLegalOrCustom(ISD::ABS, VT) &&
+ TLI.expandABS(N1.getNode(), Result, DAG, true))
+ return Result;
}
// Canonicalize (sub -1, x) -> ~x, i.e. (xor x, -1)
@@ -3402,9 +3402,9 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
if (N0.getOpcode() == ISD::XOR && N1.getOpcode() == ISD::SRA) {
SDValue X0 = N0.getOperand(0), X1 = N0.getOperand(1);
SDValue S0 = N1.getOperand(0);
- if ((X0 == S0 && X1 == N1) || (X0 == N1 && X1 == S0))
+ if ((X0 == S0 && X1 == N1) || (X0 == N1 && X1 == S0))
if (ConstantSDNode *C = isConstOrConstSplat(N1.getOperand(1)))
- if (C->getAPIntValue() == (VT.getScalarSizeInBits() - 1))
+ if (C->getAPIntValue() == (VT.getScalarSizeInBits() - 1))
return DAG.getNode(ISD::ABS, SDLoc(N), VT, S0);
}
}
@@ -3436,7 +3436,7 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
// canonicalize (sub X, (vscale * C)) to (add X, (vscale * -C))
if (N1.getOpcode() == ISD::VSCALE) {
- const APInt &IntVal = N1.getConstantOperandAPInt(0);
+ const APInt &IntVal = N1.getConstantOperandAPInt(0);
return DAG.getNode(ISD::ADD, DL, VT, N0, DAG.getVScale(DL, VT, -IntVal));
}
@@ -3595,21 +3595,21 @@ SDValue DAGCombiner::visitSUBCARRY(SDNode *N) {
return SDValue();
}
-SDValue DAGCombiner::visitSSUBO_CARRY(SDNode *N) {
- SDValue N0 = N->getOperand(0);
- SDValue N1 = N->getOperand(1);
- SDValue CarryIn = N->getOperand(2);
-
- // fold (ssubo_carry x, y, false) -> (ssubo x, y)
- if (isNullConstant(CarryIn)) {
- if (!LegalOperations ||
- TLI.isOperationLegalOrCustom(ISD::SSUBO, N->getValueType(0)))
- return DAG.getNode(ISD::SSUBO, SDLoc(N), N->getVTList(), N0, N1);
- }
-
- return SDValue();
-}
-
+SDValue DAGCombiner::visitSSUBO_CARRY(SDNode *N) {
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ SDValue CarryIn = N->getOperand(2);
+
+ // fold (ssubo_carry x, y, false) -> (ssubo x, y)
+ if (isNullConstant(CarryIn)) {
+ if (!LegalOperations ||
+ TLI.isOperationLegalOrCustom(ISD::SSUBO, N->getValueType(0)))
+ return DAG.getNode(ISD::SSUBO, SDLoc(N), N->getVTList(), N0, N1);
+ }
+
+ return SDValue();
+}
+
// Notice that "mulfix" can be any of SMULFIX, SMULFIXSAT, UMULFIX and
// UMULFIXSAT here.
SDValue DAGCombiner::visitMULFIX(SDNode *N) {
@@ -3715,30 +3715,30 @@ SDValue DAGCombiner::visitMUL(SDNode *N) {
getShiftAmountTy(N0.getValueType()))));
}
- // Try to transform:
- // (1) multiply-by-(power-of-2 +/- 1) into shift and add/sub.
+ // Try to transform:
+ // (1) multiply-by-(power-of-2 +/- 1) into shift and add/sub.
// mul x, (2^N + 1) --> add (shl x, N), x
// mul x, (2^N - 1) --> sub (shl x, N), x
// Examples: x * 33 --> (x << 5) + x
// x * 15 --> (x << 4) - x
// x * -33 --> -((x << 5) + x)
// x * -15 --> -((x << 4) - x) ; this reduces --> x - (x << 4)
- // (2) multiply-by-(power-of-2 +/- power-of-2) into shifts and add/sub.
- // mul x, (2^N + 2^M) --> (add (shl x, N), (shl x, M))
- // mul x, (2^N - 2^M) --> (sub (shl x, N), (shl x, M))
- // Examples: x * 0x8800 --> (x << 15) + (x << 11)
- // x * 0xf800 --> (x << 16) - (x << 11)
- // x * -0x8800 --> -((x << 15) + (x << 11))
- // x * -0xf800 --> -((x << 16) - (x << 11)) ; (x << 11) - (x << 16)
+ // (2) multiply-by-(power-of-2 +/- power-of-2) into shifts and add/sub.
+ // mul x, (2^N + 2^M) --> (add (shl x, N), (shl x, M))
+ // mul x, (2^N - 2^M) --> (sub (shl x, N), (shl x, M))
+ // Examples: x * 0x8800 --> (x << 15) + (x << 11)
+ // x * 0xf800 --> (x << 16) - (x << 11)
+ // x * -0x8800 --> -((x << 15) + (x << 11))
+ // x * -0xf800 --> -((x << 16) - (x << 11)) ; (x << 11) - (x << 16)
if (N1IsConst && TLI.decomposeMulByConstant(*DAG.getContext(), VT, N1)) {
// TODO: We could handle more general decomposition of any constant by
// having the target set a limit on number of ops and making a
// callback to determine that sequence (similar to sqrt expansion).
unsigned MathOp = ISD::DELETED_NODE;
APInt MulC = ConstValue1.abs();
- // The constant `2` should be treated as (2^0 + 1).
- unsigned TZeros = MulC == 2 ? 0 : MulC.countTrailingZeros();
- MulC.lshrInPlace(TZeros);
+ // The constant `2` should be treated as (2^0 + 1).
+ unsigned TZeros = MulC == 2 ? 0 : MulC.countTrailingZeros();
+ MulC.lshrInPlace(TZeros);
if ((MulC - 1).isPowerOf2())
MathOp = ISD::ADD;
else if ((MulC + 1).isPowerOf2())
@@ -3747,17 +3747,17 @@ SDValue DAGCombiner::visitMUL(SDNode *N) {
if (MathOp != ISD::DELETED_NODE) {
unsigned ShAmt =
MathOp == ISD::ADD ? (MulC - 1).logBase2() : (MulC + 1).logBase2();
- ShAmt += TZeros;
+ ShAmt += TZeros;
assert(ShAmt < VT.getScalarSizeInBits() &&
"multiply-by-constant generated out of bounds shift");
SDLoc DL(N);
SDValue Shl =
DAG.getNode(ISD::SHL, DL, VT, N0, DAG.getConstant(ShAmt, DL, VT));
- SDValue R =
- TZeros ? DAG.getNode(MathOp, DL, VT, Shl,
- DAG.getNode(ISD::SHL, DL, VT, N0,
- DAG.getConstant(TZeros, DL, VT)))
- : DAG.getNode(MathOp, DL, VT, Shl, N0);
+ SDValue R =
+ TZeros ? DAG.getNode(MathOp, DL, VT, Shl,
+ DAG.getNode(ISD::SHL, DL, VT, N0,
+ DAG.getConstant(TZeros, DL, VT)))
+ : DAG.getNode(MathOp, DL, VT, Shl, N0);
if (ConstValue1.isNegative())
R = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), R);
return R;
@@ -3809,42 +3809,42 @@ SDValue DAGCombiner::visitMUL(SDNode *N) {
// Fold (mul (vscale * C0), C1) to (vscale * (C0 * C1)).
if (N0.getOpcode() == ISD::VSCALE)
if (ConstantSDNode *NC1 = isConstOrConstSplat(N1)) {
- const APInt &C0 = N0.getConstantOperandAPInt(0);
- const APInt &C1 = NC1->getAPIntValue();
+ const APInt &C0 = N0.getConstantOperandAPInt(0);
+ const APInt &C1 = NC1->getAPIntValue();
return DAG.getVScale(SDLoc(N), VT, C0 * C1);
}
- // Fold ((mul x, 0/undef) -> 0,
- // (mul x, 1) -> x) -> x)
- // -> and(x, mask)
- // We can replace vectors with '0' and '1' factors with a clearing mask.
- if (VT.isFixedLengthVector()) {
- unsigned NumElts = VT.getVectorNumElements();
- SmallBitVector ClearMask;
- ClearMask.reserve(NumElts);
- auto IsClearMask = [&ClearMask](ConstantSDNode *V) {
- if (!V || V->isNullValue()) {
- ClearMask.push_back(true);
- return true;
- }
- ClearMask.push_back(false);
- return V->isOne();
- };
- if ((!LegalOperations || TLI.isOperationLegalOrCustom(ISD::AND, VT)) &&
- ISD::matchUnaryPredicate(N1, IsClearMask, /*AllowUndefs*/ true)) {
- assert(N1.getOpcode() == ISD::BUILD_VECTOR && "Unknown constant vector");
- SDLoc DL(N);
- EVT LegalSVT = N1.getOperand(0).getValueType();
- SDValue Zero = DAG.getConstant(0, DL, LegalSVT);
- SDValue AllOnes = DAG.getAllOnesConstant(DL, LegalSVT);
- SmallVector<SDValue, 16> Mask(NumElts, AllOnes);
- for (unsigned I = 0; I != NumElts; ++I)
- if (ClearMask[I])
- Mask[I] = Zero;
- return DAG.getNode(ISD::AND, DL, VT, N0, DAG.getBuildVector(VT, DL, Mask));
- }
- }
-
+ // Fold ((mul x, 0/undef) -> 0,
+ // (mul x, 1) -> x) -> x)
+ // -> and(x, mask)
+ // We can replace vectors with '0' and '1' factors with a clearing mask.
+ if (VT.isFixedLengthVector()) {
+ unsigned NumElts = VT.getVectorNumElements();
+ SmallBitVector ClearMask;
+ ClearMask.reserve(NumElts);
+ auto IsClearMask = [&ClearMask](ConstantSDNode *V) {
+ if (!V || V->isNullValue()) {
+ ClearMask.push_back(true);
+ return true;
+ }
+ ClearMask.push_back(false);
+ return V->isOne();
+ };
+ if ((!LegalOperations || TLI.isOperationLegalOrCustom(ISD::AND, VT)) &&
+ ISD::matchUnaryPredicate(N1, IsClearMask, /*AllowUndefs*/ true)) {
+ assert(N1.getOpcode() == ISD::BUILD_VECTOR && "Unknown constant vector");
+ SDLoc DL(N);
+ EVT LegalSVT = N1.getOperand(0).getValueType();
+ SDValue Zero = DAG.getConstant(0, DL, LegalSVT);
+ SDValue AllOnes = DAG.getAllOnesConstant(DL, LegalSVT);
+ SmallVector<SDValue, 16> Mask(NumElts, AllOnes);
+ for (unsigned I = 0; I != NumElts; ++I)
+ if (ClearMask[I])
+ Mask[I] = Zero;
+ return DAG.getNode(ISD::AND, DL, VT, N0, DAG.getBuildVector(VT, DL, Mask));
+ }
+ }
+
// reassociate mul
if (SDValue RMUL = reassociateOps(ISD::MUL, SDLoc(N), N0, N1, N->getFlags()))
return RMUL;
@@ -4266,7 +4266,7 @@ SDValue DAGCombiner::visitREM(SDNode *N) {
} else {
if (DAG.isKnownToBeAPowerOfTwo(N1)) {
// fold (urem x, pow2) -> (and x, pow2-1)
- SDValue NegOne = DAG.getAllOnesConstant(DL, VT);
+ SDValue NegOne = DAG.getAllOnesConstant(DL, VT);
SDValue Add = DAG.getNode(ISD::ADD, DL, VT, N1, NegOne);
AddToWorklist(Add.getNode());
return DAG.getNode(ISD::AND, DL, VT, N0, Add);
@@ -4274,7 +4274,7 @@ SDValue DAGCombiner::visitREM(SDNode *N) {
if (N1.getOpcode() == ISD::SHL &&
DAG.isKnownToBeAPowerOfTwo(N1.getOperand(0))) {
// fold (urem x, (shl pow2, y)) -> (and x, (add (shl pow2, y), -1))
- SDValue NegOne = DAG.getAllOnesConstant(DL, VT);
+ SDValue NegOne = DAG.getAllOnesConstant(DL, VT);
SDValue Add = DAG.getNode(ISD::ADD, DL, VT, N1, NegOne);
AddToWorklist(Add.getNode());
return DAG.getNode(ISD::AND, DL, VT, N0, Add);
@@ -4343,8 +4343,8 @@ SDValue DAGCombiner::visitMULHS(SDNode *N) {
// If the type twice as wide is legal, transform the mulhs to a wider multiply
// plus a shift.
- if (!TLI.isOperationLegalOrCustom(ISD::MULHS, VT) && VT.isSimple() &&
- !VT.isVector()) {
+ if (!TLI.isOperationLegalOrCustom(ISD::MULHS, VT) && VT.isSimple() &&
+ !VT.isVector()) {
MVT Simple = VT.getSimpleVT();
unsigned SimpleSize = Simple.getSizeInBits();
EVT NewVT = EVT::getIntegerVT(*DAG.getContext(), SimpleSize*2);
@@ -4400,8 +4400,8 @@ SDValue DAGCombiner::visitMULHU(SDNode *N) {
// If the type twice as wide is legal, transform the mulhu to a wider multiply
// plus a shift.
- if (!TLI.isOperationLegalOrCustom(ISD::MULHU, VT) && VT.isSimple() &&
- !VT.isVector()) {
+ if (!TLI.isOperationLegalOrCustom(ISD::MULHU, VT) && VT.isSimple() &&
+ !VT.isVector()) {
MVT Simple = VT.getSimpleVT();
unsigned SimpleSize = Simple.getSizeInBits();
EVT NewVT = EVT::getIntegerVT(*DAG.getContext(), SimpleSize*2);
@@ -4607,10 +4607,10 @@ SDValue DAGCombiner::visitIMINMAX(SDNode *N) {
return DAG.getNode(AltOpcode, SDLoc(N), VT, N0, N1);
}
- // Simplify the operands using demanded-bits information.
- if (SimplifyDemandedBits(SDValue(N, 0)))
- return SDValue(N, 0);
-
+ // Simplify the operands using demanded-bits information.
+ if (SimplifyDemandedBits(SDValue(N, 0)))
+ return SDValue(N, 0);
+
return SDValue();
}
@@ -5079,15 +5079,15 @@ bool DAGCombiner::isLegalNarrowLdSt(LSBaseSDNode *LDST,
if (!LDST->isSimple())
return false;
- EVT LdStMemVT = LDST->getMemoryVT();
-
- // Bail out when changing the scalable property, since we can't be sure that
- // we're actually narrowing here.
- if (LdStMemVT.isScalableVector() != MemVT.isScalableVector())
- return false;
-
+ EVT LdStMemVT = LDST->getMemoryVT();
+
+ // Bail out when changing the scalable property, since we can't be sure that
+ // we're actually narrowing here.
+ if (LdStMemVT.isScalableVector() != MemVT.isScalableVector())
+ return false;
+
// Verify that we are actually reducing a load width here.
- if (LdStMemVT.bitsLT(MemVT))
+ if (LdStMemVT.bitsLT(MemVT))
return false;
// Ensure that this isn't going to produce an unsupported memory access.
@@ -5442,31 +5442,31 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
return N1;
if (ISD::isBuildVectorAllOnes(N1.getNode()))
return N0;
-
- // fold (and (masked_load) (build_vec (x, ...))) to zext_masked_load
- auto *MLoad = dyn_cast<MaskedLoadSDNode>(N0);
- auto *BVec = dyn_cast<BuildVectorSDNode>(N1);
- if (MLoad && BVec && MLoad->getExtensionType() == ISD::EXTLOAD &&
- N0.hasOneUse() && N1.hasOneUse()) {
- EVT LoadVT = MLoad->getMemoryVT();
- EVT ExtVT = VT;
- if (TLI.isLoadExtLegal(ISD::ZEXTLOAD, ExtVT, LoadVT)) {
- // For this AND to be a zero extension of the masked load the elements
- // of the BuildVec must mask the bottom bits of the extended element
- // type
- if (ConstantSDNode *Splat = BVec->getConstantSplatNode()) {
- uint64_t ElementSize =
- LoadVT.getVectorElementType().getScalarSizeInBits();
- if (Splat->getAPIntValue().isMask(ElementSize)) {
- return DAG.getMaskedLoad(
- ExtVT, SDLoc(N), MLoad->getChain(), MLoad->getBasePtr(),
- MLoad->getOffset(), MLoad->getMask(), MLoad->getPassThru(),
- LoadVT, MLoad->getMemOperand(), MLoad->getAddressingMode(),
- ISD::ZEXTLOAD, MLoad->isExpandingLoad());
- }
- }
- }
- }
+
+ // fold (and (masked_load) (build_vec (x, ...))) to zext_masked_load
+ auto *MLoad = dyn_cast<MaskedLoadSDNode>(N0);
+ auto *BVec = dyn_cast<BuildVectorSDNode>(N1);
+ if (MLoad && BVec && MLoad->getExtensionType() == ISD::EXTLOAD &&
+ N0.hasOneUse() && N1.hasOneUse()) {
+ EVT LoadVT = MLoad->getMemoryVT();
+ EVT ExtVT = VT;
+ if (TLI.isLoadExtLegal(ISD::ZEXTLOAD, ExtVT, LoadVT)) {
+ // For this AND to be a zero extension of the masked load the elements
+ // of the BuildVec must mask the bottom bits of the extended element
+ // type
+ if (ConstantSDNode *Splat = BVec->getConstantSplatNode()) {
+ uint64_t ElementSize =
+ LoadVT.getVectorElementType().getScalarSizeInBits();
+ if (Splat->getAPIntValue().isMask(ElementSize)) {
+ return DAG.getMaskedLoad(
+ ExtVT, SDLoc(N), MLoad->getChain(), MLoad->getBasePtr(),
+ MLoad->getOffset(), MLoad->getMask(), MLoad->getPassThru(),
+ LoadVT, MLoad->getMemOperand(), MLoad->getAddressingMode(),
+ ISD::ZEXTLOAD, MLoad->isExpandingLoad());
+ }
+ }
+ }
+ }
}
// fold (and c1, c2) -> c1&c2
@@ -5635,28 +5635,28 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
}
}
- // fold (and (masked_gather x)) -> (zext_masked_gather x)
- if (auto *GN0 = dyn_cast<MaskedGatherSDNode>(N0)) {
- EVT MemVT = GN0->getMemoryVT();
- EVT ScalarVT = MemVT.getScalarType();
-
- if (SDValue(GN0, 0).hasOneUse() &&
- isConstantSplatVectorMaskForType(N1.getNode(), ScalarVT) &&
- TLI.isVectorLoadExtDesirable(SDValue(SDValue(GN0, 0)))) {
- SDValue Ops[] = {GN0->getChain(), GN0->getPassThru(), GN0->getMask(),
- GN0->getBasePtr(), GN0->getIndex(), GN0->getScale()};
-
- SDValue ZExtLoad = DAG.getMaskedGather(
- DAG.getVTList(VT, MVT::Other), MemVT, SDLoc(N), Ops,
- GN0->getMemOperand(), GN0->getIndexType(), ISD::ZEXTLOAD);
-
- CombineTo(N, ZExtLoad);
- AddToWorklist(ZExtLoad.getNode());
- // Avoid recheck of N.
- return SDValue(N, 0);
- }
- }
-
+ // fold (and (masked_gather x)) -> (zext_masked_gather x)
+ if (auto *GN0 = dyn_cast<MaskedGatherSDNode>(N0)) {
+ EVT MemVT = GN0->getMemoryVT();
+ EVT ScalarVT = MemVT.getScalarType();
+
+ if (SDValue(GN0, 0).hasOneUse() &&
+ isConstantSplatVectorMaskForType(N1.getNode(), ScalarVT) &&
+ TLI.isVectorLoadExtDesirable(SDValue(SDValue(GN0, 0)))) {
+ SDValue Ops[] = {GN0->getChain(), GN0->getPassThru(), GN0->getMask(),
+ GN0->getBasePtr(), GN0->getIndex(), GN0->getScale()};
+
+ SDValue ZExtLoad = DAG.getMaskedGather(
+ DAG.getVTList(VT, MVT::Other), MemVT, SDLoc(N), Ops,
+ GN0->getMemOperand(), GN0->getIndexType(), ISD::ZEXTLOAD);
+
+ CombineTo(N, ZExtLoad);
+ AddToWorklist(ZExtLoad.getNode());
+ // Avoid recheck of N.
+ return SDValue(N, 0);
+ }
+ }
+
// fold (and (load x), 255) -> (zextload x, i8)
// fold (and (extload x, i16), 255) -> (zextload x, i8)
// fold (and (any_ext (extload x, i16)), 255) -> (zextload x, i8)
@@ -5751,31 +5751,31 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
if (SDValue V = combineShiftAnd1ToBitTest(N, DAG))
return V;
- // Recognize the following pattern:
- //
- // AndVT = (and (sign_extend NarrowVT to AndVT) #bitmask)
- //
- // where bitmask is a mask that clears the upper bits of AndVT. The
- // number of bits in bitmask must be a power of two.
- auto IsAndZeroExtMask = [](SDValue LHS, SDValue RHS) {
- if (LHS->getOpcode() != ISD::SIGN_EXTEND)
- return false;
-
- auto *C = dyn_cast<ConstantSDNode>(RHS);
- if (!C)
- return false;
-
- if (!C->getAPIntValue().isMask(
- LHS.getOperand(0).getValueType().getFixedSizeInBits()))
- return false;
-
- return true;
- };
-
- // Replace (and (sign_extend ...) #bitmask) with (zero_extend ...).
- if (IsAndZeroExtMask(N0, N1))
- return DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), VT, N0.getOperand(0));
-
+ // Recognize the following pattern:
+ //
+ // AndVT = (and (sign_extend NarrowVT to AndVT) #bitmask)
+ //
+ // where bitmask is a mask that clears the upper bits of AndVT. The
+ // number of bits in bitmask must be a power of two.
+ auto IsAndZeroExtMask = [](SDValue LHS, SDValue RHS) {
+ if (LHS->getOpcode() != ISD::SIGN_EXTEND)
+ return false;
+
+ auto *C = dyn_cast<ConstantSDNode>(RHS);
+ if (!C)
+ return false;
+
+ if (!C->getAPIntValue().isMask(
+ LHS.getOperand(0).getValueType().getFixedSizeInBits()))
+ return false;
+
+ return true;
+ };
+
+ // Replace (and (sign_extend ...) #bitmask) with (zero_extend ...).
+ if (IsAndZeroExtMask(N0, N1))
+ return DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), VT, N0.getOperand(0));
+
return SDValue();
}
@@ -6517,11 +6517,11 @@ static SDValue extractShiftForRotate(SelectionDAG &DAG, SDValue OppShift,
// reduces to a rotate in direction shift2 by Pos or (equivalently) a rotate
// in direction shift1 by Neg. The range [0, EltSize) means that we only need
// to consider shift amounts with defined behavior.
-//
-// The IsRotate flag should be set when the LHS of both shifts is the same.
-// Otherwise if matching a general funnel shift, it should be clear.
+//
+// The IsRotate flag should be set when the LHS of both shifts is the same.
+// Otherwise if matching a general funnel shift, it should be clear.
static bool matchRotateSub(SDValue Pos, SDValue Neg, unsigned EltSize,
- SelectionDAG &DAG, bool IsRotate) {
+ SelectionDAG &DAG, bool IsRotate) {
// If EltSize is a power of 2 then:
//
// (a) (Pos == 0 ? 0 : EltSize - Pos) == (EltSize - Pos) & (EltSize - 1)
@@ -6553,11 +6553,11 @@ static bool matchRotateSub(SDValue Pos, SDValue Neg, unsigned EltSize,
// always invokes undefined behavior for 32-bit X.
//
// Below, Mask == EltSize - 1 when using [A] and is all-ones otherwise.
- //
- // NOTE: We can only do this when matching an AND and not a general
- // funnel shift.
+ //
+ // NOTE: We can only do this when matching an AND and not a general
+ // funnel shift.
unsigned MaskLoBits = 0;
- if (IsRotate && Neg.getOpcode() == ISD::AND && isPowerOf2_64(EltSize)) {
+ if (IsRotate && Neg.getOpcode() == ISD::AND && isPowerOf2_64(EltSize)) {
if (ConstantSDNode *NegC = isConstOrConstSplat(Neg.getOperand(1))) {
KnownBits Known = DAG.computeKnownBits(Neg.getOperand(0));
unsigned Bits = Log2_64(EltSize);
@@ -6647,8 +6647,8 @@ SDValue DAGCombiner::MatchRotatePosNeg(SDValue Shifted, SDValue Pos,
// (srl x, (*ext y))) ->
// (rotr x, y) or (rotl x, (sub 32, y))
EVT VT = Shifted.getValueType();
- if (matchRotateSub(InnerPos, InnerNeg, VT.getScalarSizeInBits(), DAG,
- /*IsRotate*/ true)) {
+ if (matchRotateSub(InnerPos, InnerNeg, VT.getScalarSizeInBits(), DAG,
+ /*IsRotate*/ true)) {
bool HasPos = TLI.isOperationLegalOrCustom(PosOpcode, VT);
return DAG.getNode(HasPos ? PosOpcode : NegOpcode, DL, VT, Shifted,
HasPos ? Pos : Neg);
@@ -6677,7 +6677,7 @@ SDValue DAGCombiner::MatchFunnelPosNeg(SDValue N0, SDValue N1, SDValue Pos,
// fold (or (shl x0, (*ext (sub 32, y))),
// (srl x1, (*ext y))) ->
// (fshr x0, x1, y) or (fshl x0, x1, (sub 32, y))
- if (matchRotateSub(InnerPos, InnerNeg, EltBits, DAG, /*IsRotate*/ N0 == N1)) {
+ if (matchRotateSub(InnerPos, InnerNeg, EltBits, DAG, /*IsRotate*/ N0 == N1)) {
bool HasPos = TLI.isOperationLegalOrCustom(PosOpcode, VT);
return DAG.getNode(HasPos ? PosOpcode : NegOpcode, DL, VT, N0, N1,
HasPos ? Pos : Neg);
@@ -7031,11 +7031,11 @@ calculateByteProvider(SDValue Op, unsigned Index, unsigned Depth,
return None;
}
-static unsigned littleEndianByteAt(unsigned BW, unsigned i) {
+static unsigned littleEndianByteAt(unsigned BW, unsigned i) {
return i;
}
-static unsigned bigEndianByteAt(unsigned BW, unsigned i) {
+static unsigned bigEndianByteAt(unsigned BW, unsigned i) {
return BW - i - 1;
}
@@ -7052,8 +7052,8 @@ static Optional<bool> isBigEndian(const ArrayRef<int64_t> ByteOffsets,
bool BigEndian = true, LittleEndian = true;
for (unsigned i = 0; i < Width; i++) {
int64_t CurrentByteOffset = ByteOffsets[i] - FirstOffset;
- LittleEndian &= CurrentByteOffset == littleEndianByteAt(Width, i);
- BigEndian &= CurrentByteOffset == bigEndianByteAt(Width, i);
+ LittleEndian &= CurrentByteOffset == littleEndianByteAt(Width, i);
+ BigEndian &= CurrentByteOffset == bigEndianByteAt(Width, i);
if (!BigEndian && !LittleEndian)
return None;
}
@@ -7096,98 +7096,98 @@ static SDValue stripTruncAndExt(SDValue Value) {
/// p[3] = (val >> 0) & 0xFF;
/// =>
/// *((i32)p) = BSWAP(val);
-SDValue DAGCombiner::mergeTruncStores(StoreSDNode *N) {
- // The matching looks for "store (trunc x)" patterns that appear early but are
- // likely to be replaced by truncating store nodes during combining.
- // TODO: If there is evidence that running this later would help, this
- // limitation could be removed. Legality checks may need to be added
- // for the created store and optional bswap/rotate.
- if (LegalOperations)
- return SDValue();
-
- // We only handle merging simple stores of 1-4 bytes.
- // TODO: Allow unordered atomics when wider type is legal (see D66309)
- EVT MemVT = N->getMemoryVT();
- if (!(MemVT == MVT::i8 || MemVT == MVT::i16 || MemVT == MVT::i32) ||
- !N->isSimple() || N->isIndexed())
- return SDValue();
-
- // Collect all of the stores in the chain.
- SDValue Chain = N->getChain();
- SmallVector<StoreSDNode *, 8> Stores = {N};
- while (auto *Store = dyn_cast<StoreSDNode>(Chain)) {
- // All stores must be the same size to ensure that we are writing all of the
- // bytes in the wide value.
- // TODO: We could allow multiple sizes by tracking each stored byte.
- if (Store->getMemoryVT() != MemVT || !Store->isSimple() ||
- Store->isIndexed())
+SDValue DAGCombiner::mergeTruncStores(StoreSDNode *N) {
+ // The matching looks for "store (trunc x)" patterns that appear early but are
+ // likely to be replaced by truncating store nodes during combining.
+ // TODO: If there is evidence that running this later would help, this
+ // limitation could be removed. Legality checks may need to be added
+ // for the created store and optional bswap/rotate.
+ if (LegalOperations)
+ return SDValue();
+
+ // We only handle merging simple stores of 1-4 bytes.
+ // TODO: Allow unordered atomics when wider type is legal (see D66309)
+ EVT MemVT = N->getMemoryVT();
+ if (!(MemVT == MVT::i8 || MemVT == MVT::i16 || MemVT == MVT::i32) ||
+ !N->isSimple() || N->isIndexed())
+ return SDValue();
+
+ // Collect all of the stores in the chain.
+ SDValue Chain = N->getChain();
+ SmallVector<StoreSDNode *, 8> Stores = {N};
+ while (auto *Store = dyn_cast<StoreSDNode>(Chain)) {
+ // All stores must be the same size to ensure that we are writing all of the
+ // bytes in the wide value.
+ // TODO: We could allow multiple sizes by tracking each stored byte.
+ if (Store->getMemoryVT() != MemVT || !Store->isSimple() ||
+ Store->isIndexed())
return SDValue();
Stores.push_back(Store);
Chain = Store->getChain();
}
- // There is no reason to continue if we do not have at least a pair of stores.
- if (Stores.size() < 2)
+ // There is no reason to continue if we do not have at least a pair of stores.
+ if (Stores.size() < 2)
return SDValue();
- // Handle simple types only.
- LLVMContext &Context = *DAG.getContext();
- unsigned NumStores = Stores.size();
- unsigned NarrowNumBits = N->getMemoryVT().getScalarSizeInBits();
- unsigned WideNumBits = NumStores * NarrowNumBits;
- EVT WideVT = EVT::getIntegerVT(Context, WideNumBits);
- if (WideVT != MVT::i16 && WideVT != MVT::i32 && WideVT != MVT::i64)
+ // Handle simple types only.
+ LLVMContext &Context = *DAG.getContext();
+ unsigned NumStores = Stores.size();
+ unsigned NarrowNumBits = N->getMemoryVT().getScalarSizeInBits();
+ unsigned WideNumBits = NumStores * NarrowNumBits;
+ EVT WideVT = EVT::getIntegerVT(Context, WideNumBits);
+ if (WideVT != MVT::i16 && WideVT != MVT::i32 && WideVT != MVT::i64)
return SDValue();
- // Check if all bytes of the source value that we are looking at are stored
- // to the same base address. Collect offsets from Base address into OffsetMap.
- SDValue SourceValue;
- SmallVector<int64_t, 8> OffsetMap(NumStores, INT64_MAX);
+ // Check if all bytes of the source value that we are looking at are stored
+ // to the same base address. Collect offsets from Base address into OffsetMap.
+ SDValue SourceValue;
+ SmallVector<int64_t, 8> OffsetMap(NumStores, INT64_MAX);
int64_t FirstOffset = INT64_MAX;
StoreSDNode *FirstStore = nullptr;
Optional<BaseIndexOffset> Base;
for (auto Store : Stores) {
- // All the stores store different parts of the CombinedValue. A truncate is
- // required to get the partial value.
+ // All the stores store different parts of the CombinedValue. A truncate is
+ // required to get the partial value.
SDValue Trunc = Store->getValue();
if (Trunc.getOpcode() != ISD::TRUNCATE)
return SDValue();
- // Other than the first/last part, a shift operation is required to get the
- // offset.
+ // Other than the first/last part, a shift operation is required to get the
+ // offset.
int64_t Offset = 0;
- SDValue WideVal = Trunc.getOperand(0);
- if ((WideVal.getOpcode() == ISD::SRL || WideVal.getOpcode() == ISD::SRA) &&
- isa<ConstantSDNode>(WideVal.getOperand(1))) {
- // The shift amount must be a constant multiple of the narrow type.
- // It is translated to the offset address in the wide source value "y".
+ SDValue WideVal = Trunc.getOperand(0);
+ if ((WideVal.getOpcode() == ISD::SRL || WideVal.getOpcode() == ISD::SRA) &&
+ isa<ConstantSDNode>(WideVal.getOperand(1))) {
+ // The shift amount must be a constant multiple of the narrow type.
+ // It is translated to the offset address in the wide source value "y".
//
- // x = srl y, ShiftAmtC
+ // x = srl y, ShiftAmtC
// i8 z = trunc x
// store z, ...
- uint64_t ShiftAmtC = WideVal.getConstantOperandVal(1);
- if (ShiftAmtC % NarrowNumBits != 0)
+ uint64_t ShiftAmtC = WideVal.getConstantOperandVal(1);
+ if (ShiftAmtC % NarrowNumBits != 0)
return SDValue();
- Offset = ShiftAmtC / NarrowNumBits;
- WideVal = WideVal.getOperand(0);
+ Offset = ShiftAmtC / NarrowNumBits;
+ WideVal = WideVal.getOperand(0);
}
- // Stores must share the same source value with different offsets.
- // Truncate and extends should be stripped to get the single source value.
- if (!SourceValue)
- SourceValue = WideVal;
- else if (stripTruncAndExt(SourceValue) != stripTruncAndExt(WideVal))
+ // Stores must share the same source value with different offsets.
+ // Truncate and extends should be stripped to get the single source value.
+ if (!SourceValue)
+ SourceValue = WideVal;
+ else if (stripTruncAndExt(SourceValue) != stripTruncAndExt(WideVal))
return SDValue();
- else if (SourceValue.getValueType() != WideVT) {
- if (WideVal.getValueType() == WideVT ||
- WideVal.getScalarValueSizeInBits() >
- SourceValue.getScalarValueSizeInBits())
- SourceValue = WideVal;
- // Give up if the source value type is smaller than the store size.
- if (SourceValue.getScalarValueSizeInBits() < WideVT.getScalarSizeInBits())
+ else if (SourceValue.getValueType() != WideVT) {
+ if (WideVal.getValueType() == WideVT ||
+ WideVal.getScalarValueSizeInBits() >
+ SourceValue.getScalarValueSizeInBits())
+ SourceValue = WideVal;
+ // Give up if the source value type is smaller than the store size.
+ if (SourceValue.getScalarValueSizeInBits() < WideVT.getScalarSizeInBits())
return SDValue();
}
- // Stores must share the same base address.
+ // Stores must share the same base address.
BaseIndexOffset Ptr = BaseIndexOffset::match(Store, DAG);
int64_t ByteOffsetFromBase = 0;
if (!Base)
@@ -7195,78 +7195,78 @@ SDValue DAGCombiner::mergeTruncStores(StoreSDNode *N) {
else if (!Base->equalBaseIndex(Ptr, DAG, ByteOffsetFromBase))
return SDValue();
- // Remember the first store.
+ // Remember the first store.
if (ByteOffsetFromBase < FirstOffset) {
FirstStore = Store;
FirstOffset = ByteOffsetFromBase;
}
// Map the offset in the store and the offset in the combined value, and
// early return if it has been set before.
- if (Offset < 0 || Offset >= NumStores || OffsetMap[Offset] != INT64_MAX)
+ if (Offset < 0 || Offset >= NumStores || OffsetMap[Offset] != INT64_MAX)
return SDValue();
- OffsetMap[Offset] = ByteOffsetFromBase;
+ OffsetMap[Offset] = ByteOffsetFromBase;
}
assert(FirstOffset != INT64_MAX && "First byte offset must be set");
assert(FirstStore && "First store must be set");
- // Check that a store of the wide type is both allowed and fast on the target
- const DataLayout &Layout = DAG.getDataLayout();
- bool Fast = false;
- bool Allowed = TLI.allowsMemoryAccess(Context, Layout, WideVT,
- *FirstStore->getMemOperand(), &Fast);
- if (!Allowed || !Fast)
- return SDValue();
-
- // Check if the pieces of the value are going to the expected places in memory
- // to merge the stores.
- auto checkOffsets = [&](bool MatchLittleEndian) {
- if (MatchLittleEndian) {
- for (unsigned i = 0; i != NumStores; ++i)
- if (OffsetMap[i] != i * (NarrowNumBits / 8) + FirstOffset)
- return false;
- } else { // MatchBigEndian by reversing loop counter.
- for (unsigned i = 0, j = NumStores - 1; i != NumStores; ++i, --j)
- if (OffsetMap[j] != i * (NarrowNumBits / 8) + FirstOffset)
- return false;
- }
- return true;
- };
-
- // Check if the offsets line up for the native data layout of this target.
- bool NeedBswap = false;
- bool NeedRotate = false;
- if (!checkOffsets(Layout.isLittleEndian())) {
- // Special-case: check if byte offsets line up for the opposite endian.
- if (NarrowNumBits == 8 && checkOffsets(Layout.isBigEndian()))
- NeedBswap = true;
- else if (NumStores == 2 && checkOffsets(Layout.isBigEndian()))
- NeedRotate = true;
- else
- return SDValue();
- }
-
- SDLoc DL(N);
- if (WideVT != SourceValue.getValueType()) {
- assert(SourceValue.getValueType().getScalarSizeInBits() > WideNumBits &&
- "Unexpected store value to merge");
- SourceValue = DAG.getNode(ISD::TRUNCATE, DL, WideVT, SourceValue);
- }
-
- // Before legalize we can introduce illegal bswaps/rotates which will be later
+ // Check that a store of the wide type is both allowed and fast on the target
+ const DataLayout &Layout = DAG.getDataLayout();
+ bool Fast = false;
+ bool Allowed = TLI.allowsMemoryAccess(Context, Layout, WideVT,
+ *FirstStore->getMemOperand(), &Fast);
+ if (!Allowed || !Fast)
+ return SDValue();
+
+ // Check if the pieces of the value are going to the expected places in memory
+ // to merge the stores.
+ auto checkOffsets = [&](bool MatchLittleEndian) {
+ if (MatchLittleEndian) {
+ for (unsigned i = 0; i != NumStores; ++i)
+ if (OffsetMap[i] != i * (NarrowNumBits / 8) + FirstOffset)
+ return false;
+ } else { // MatchBigEndian by reversing loop counter.
+ for (unsigned i = 0, j = NumStores - 1; i != NumStores; ++i, --j)
+ if (OffsetMap[j] != i * (NarrowNumBits / 8) + FirstOffset)
+ return false;
+ }
+ return true;
+ };
+
+ // Check if the offsets line up for the native data layout of this target.
+ bool NeedBswap = false;
+ bool NeedRotate = false;
+ if (!checkOffsets(Layout.isLittleEndian())) {
+ // Special-case: check if byte offsets line up for the opposite endian.
+ if (NarrowNumBits == 8 && checkOffsets(Layout.isBigEndian()))
+ NeedBswap = true;
+ else if (NumStores == 2 && checkOffsets(Layout.isBigEndian()))
+ NeedRotate = true;
+ else
+ return SDValue();
+ }
+
+ SDLoc DL(N);
+ if (WideVT != SourceValue.getValueType()) {
+ assert(SourceValue.getValueType().getScalarSizeInBits() > WideNumBits &&
+ "Unexpected store value to merge");
+ SourceValue = DAG.getNode(ISD::TRUNCATE, DL, WideVT, SourceValue);
+ }
+
+ // Before legalize we can introduce illegal bswaps/rotates which will be later
// converted to an explicit bswap sequence. This way we end up with a single
// store and byte shuffling instead of several stores and byte shuffling.
- if (NeedBswap) {
- SourceValue = DAG.getNode(ISD::BSWAP, DL, WideVT, SourceValue);
- } else if (NeedRotate) {
- assert(WideNumBits % 2 == 0 && "Unexpected type for rotate");
- SDValue RotAmt = DAG.getConstant(WideNumBits / 2, DL, WideVT);
- SourceValue = DAG.getNode(ISD::ROTR, DL, WideVT, SourceValue, RotAmt);
+ if (NeedBswap) {
+ SourceValue = DAG.getNode(ISD::BSWAP, DL, WideVT, SourceValue);
+ } else if (NeedRotate) {
+ assert(WideNumBits % 2 == 0 && "Unexpected type for rotate");
+ SDValue RotAmt = DAG.getConstant(WideNumBits / 2, DL, WideVT);
+ SourceValue = DAG.getNode(ISD::ROTR, DL, WideVT, SourceValue, RotAmt);
}
SDValue NewStore =
- DAG.getStore(Chain, DL, SourceValue, FirstStore->getBasePtr(),
- FirstStore->getPointerInfo(), FirstStore->getAlign());
+ DAG.getStore(Chain, DL, SourceValue, FirstStore->getBasePtr(),
+ FirstStore->getPointerInfo(), FirstStore->getAlign());
// Rely on other DAG combine rules to remove the other individual stores.
DAG.ReplaceAllUsesWith(N, NewStore.getNode());
@@ -7321,8 +7321,8 @@ SDValue DAGCombiner::MatchLoadCombine(SDNode *N) {
"can only analyze providers for individual bytes not bit");
unsigned LoadByteWidth = LoadBitWidth / 8;
return IsBigEndianTarget
- ? bigEndianByteAt(LoadByteWidth, P.ByteOffset)
- : littleEndianByteAt(LoadByteWidth, P.ByteOffset);
+ ? bigEndianByteAt(LoadByteWidth, P.ByteOffset)
+ : littleEndianByteAt(LoadByteWidth, P.ByteOffset);
};
Optional<BaseIndexOffset> Base;
@@ -7449,10 +7449,10 @@ SDValue DAGCombiner::MatchLoadCombine(SDNode *N) {
if (!Allowed || !Fast)
return SDValue();
- SDValue NewLoad =
- DAG.getExtLoad(NeedsZext ? ISD::ZEXTLOAD : ISD::NON_EXTLOAD, SDLoc(N), VT,
- Chain, FirstLoad->getBasePtr(),
- FirstLoad->getPointerInfo(), MemVT, FirstLoad->getAlign());
+ SDValue NewLoad =
+ DAG.getExtLoad(NeedsZext ? ISD::ZEXTLOAD : ISD::NON_EXTLOAD, SDLoc(N), VT,
+ Chain, FirstLoad->getBasePtr(),
+ FirstLoad->getPointerInfo(), MemVT, FirstLoad->getAlign());
// Transfer chain users from old loads to the new load.
for (LoadSDNode *L : Loads)
@@ -7622,9 +7622,9 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {
if (N0.hasOneUse()) {
// FIXME Can we handle multiple uses? Could we token factor the chain
// results from the new/old setcc?
- SDValue SetCC =
- DAG.getSetCC(SDLoc(N0), VT, LHS, RHS, NotCC,
- N0.getOperand(0), N0Opcode == ISD::STRICT_FSETCCS);
+ SDValue SetCC =
+ DAG.getSetCC(SDLoc(N0), VT, LHS, RHS, NotCC,
+ N0.getOperand(0), N0Opcode == ISD::STRICT_FSETCCS);
CombineTo(N, SetCC);
DAG.ReplaceAllUsesOfValueWith(N0.getValue(1), SetCC.getValue(1));
recursivelyDeleteUnusedNodes(N0.getNode());
@@ -7725,9 +7725,9 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {
if (A.getOpcode() == ISD::ADD && S.getOpcode() == ISD::SRA) {
SDValue A0 = A.getOperand(0), A1 = A.getOperand(1);
SDValue S0 = S.getOperand(0);
- if ((A0 == S && A1 == S0) || (A1 == S && A0 == S0))
+ if ((A0 == S && A1 == S0) || (A1 == S && A0 == S0))
if (ConstantSDNode *C = isConstOrConstSplat(S.getOperand(1)))
- if (C->getAPIntValue() == (VT.getScalarSizeInBits() - 1))
+ if (C->getAPIntValue() == (VT.getScalarSizeInBits() - 1))
return DAG.getNode(ISD::ABS, DL, VT, S0);
}
}
@@ -8263,9 +8263,9 @@ SDValue DAGCombiner::visitSHL(SDNode *N) {
// Fold (shl (vscale * C0), C1) to (vscale * (C0 << C1)).
if (N0.getOpcode() == ISD::VSCALE)
if (ConstantSDNode *NC1 = isConstOrConstSplat(N->getOperand(1))) {
- const APInt &C0 = N0.getConstantOperandAPInt(0);
- const APInt &C1 = NC1->getAPIntValue();
- return DAG.getVScale(SDLoc(N), VT, C0 << C1);
+ const APInt &C0 = N0.getConstantOperandAPInt(0);
+ const APInt &C1 = NC1->getAPIntValue();
+ return DAG.getVScale(SDLoc(N), VT, C0 << C1);
}
return SDValue();
@@ -8331,10 +8331,10 @@ static SDValue combineShiftToMULH(SDNode *N, SelectionDAG &DAG,
// we use mulhs. Othewise, zero extends (zext) use mulhu.
unsigned MulhOpcode = IsSignExt ? ISD::MULHS : ISD::MULHU;
- // Combine to mulh if mulh is legal/custom for the narrow type on the target.
- if (!TLI.isOperationLegalOrCustom(MulhOpcode, NarrowVT))
- return SDValue();
-
+ // Combine to mulh if mulh is legal/custom for the narrow type on the target.
+ if (!TLI.isOperationLegalOrCustom(MulhOpcode, NarrowVT))
+ return SDValue();
+
SDValue Result = DAG.getNode(MulhOpcode, DL, NarrowVT, LeftOp.getOperand(0),
RightOp.getOperand(0));
return (N->getOpcode() == ISD::SRA ? DAG.getSExtOrTrunc(Result, DL, WideVT1)
@@ -8836,8 +8836,8 @@ SDValue DAGCombiner::visitFunnelShift(SDNode *N) {
RHS->getAddressSpace(), NewAlign,
RHS->getMemOperand()->getFlags(), &Fast) &&
Fast) {
- SDValue NewPtr = DAG.getMemBasePlusOffset(
- RHS->getBasePtr(), TypeSize::Fixed(PtrOff), DL);
+ SDValue NewPtr = DAG.getMemBasePlusOffset(
+ RHS->getBasePtr(), TypeSize::Fixed(PtrOff), DL);
AddToWorklist(NewPtr.getNode());
SDValue Load = DAG.getLoad(
VT, DL, RHS->getChain(), NewPtr,
@@ -9434,75 +9434,75 @@ static SDValue ConvertSelectToConcatVector(SDNode *N, SelectionDAG &DAG) {
TopHalf->isNullValue() ? RHS->getOperand(1) : LHS->getOperand(1));
}
-bool refineUniformBase(SDValue &BasePtr, SDValue &Index, SelectionDAG &DAG) {
- if (!isNullConstant(BasePtr) || Index.getOpcode() != ISD::ADD)
- return false;
-
- // For now we check only the LHS of the add.
- SDValue LHS = Index.getOperand(0);
- SDValue SplatVal = DAG.getSplatValue(LHS);
- if (!SplatVal)
- return false;
-
- BasePtr = SplatVal;
- Index = Index.getOperand(1);
- return true;
-}
-
-// Fold sext/zext of index into index type.
-bool refineIndexType(MaskedGatherScatterSDNode *MGS, SDValue &Index,
- bool Scaled, SelectionDAG &DAG) {
- const TargetLowering &TLI = DAG.getTargetLoweringInfo();
-
- if (Index.getOpcode() == ISD::ZERO_EXTEND) {
- SDValue Op = Index.getOperand(0);
- MGS->setIndexType(Scaled ? ISD::UNSIGNED_SCALED : ISD::UNSIGNED_UNSCALED);
- if (TLI.shouldRemoveExtendFromGSIndex(Op.getValueType())) {
- Index = Op;
- return true;
- }
- }
-
- if (Index.getOpcode() == ISD::SIGN_EXTEND) {
- SDValue Op = Index.getOperand(0);
- MGS->setIndexType(Scaled ? ISD::SIGNED_SCALED : ISD::SIGNED_UNSCALED);
- if (TLI.shouldRemoveExtendFromGSIndex(Op.getValueType())) {
- Index = Op;
- return true;
- }
- }
-
- return false;
-}
-
+bool refineUniformBase(SDValue &BasePtr, SDValue &Index, SelectionDAG &DAG) {
+ if (!isNullConstant(BasePtr) || Index.getOpcode() != ISD::ADD)
+ return false;
+
+ // For now we check only the LHS of the add.
+ SDValue LHS = Index.getOperand(0);
+ SDValue SplatVal = DAG.getSplatValue(LHS);
+ if (!SplatVal)
+ return false;
+
+ BasePtr = SplatVal;
+ Index = Index.getOperand(1);
+ return true;
+}
+
+// Fold sext/zext of index into index type.
+bool refineIndexType(MaskedGatherScatterSDNode *MGS, SDValue &Index,
+ bool Scaled, SelectionDAG &DAG) {
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+
+ if (Index.getOpcode() == ISD::ZERO_EXTEND) {
+ SDValue Op = Index.getOperand(0);
+ MGS->setIndexType(Scaled ? ISD::UNSIGNED_SCALED : ISD::UNSIGNED_UNSCALED);
+ if (TLI.shouldRemoveExtendFromGSIndex(Op.getValueType())) {
+ Index = Op;
+ return true;
+ }
+ }
+
+ if (Index.getOpcode() == ISD::SIGN_EXTEND) {
+ SDValue Op = Index.getOperand(0);
+ MGS->setIndexType(Scaled ? ISD::SIGNED_SCALED : ISD::SIGNED_UNSCALED);
+ if (TLI.shouldRemoveExtendFromGSIndex(Op.getValueType())) {
+ Index = Op;
+ return true;
+ }
+ }
+
+ return false;
+}
+
SDValue DAGCombiner::visitMSCATTER(SDNode *N) {
MaskedScatterSDNode *MSC = cast<MaskedScatterSDNode>(N);
SDValue Mask = MSC->getMask();
SDValue Chain = MSC->getChain();
- SDValue Index = MSC->getIndex();
- SDValue Scale = MSC->getScale();
- SDValue StoreVal = MSC->getValue();
- SDValue BasePtr = MSC->getBasePtr();
+ SDValue Index = MSC->getIndex();
+ SDValue Scale = MSC->getScale();
+ SDValue StoreVal = MSC->getValue();
+ SDValue BasePtr = MSC->getBasePtr();
SDLoc DL(N);
// Zap scatters with a zero mask.
if (ISD::isBuildVectorAllZeros(Mask.getNode()))
return Chain;
- if (refineUniformBase(BasePtr, Index, DAG)) {
- SDValue Ops[] = {Chain, StoreVal, Mask, BasePtr, Index, Scale};
- return DAG.getMaskedScatter(
- DAG.getVTList(MVT::Other), StoreVal.getValueType(), DL, Ops,
- MSC->getMemOperand(), MSC->getIndexType(), MSC->isTruncatingStore());
- }
-
- if (refineIndexType(MSC, Index, MSC->isIndexScaled(), DAG)) {
- SDValue Ops[] = {Chain, StoreVal, Mask, BasePtr, Index, Scale};
- return DAG.getMaskedScatter(
- DAG.getVTList(MVT::Other), StoreVal.getValueType(), DL, Ops,
- MSC->getMemOperand(), MSC->getIndexType(), MSC->isTruncatingStore());
- }
-
+ if (refineUniformBase(BasePtr, Index, DAG)) {
+ SDValue Ops[] = {Chain, StoreVal, Mask, BasePtr, Index, Scale};
+ return DAG.getMaskedScatter(
+ DAG.getVTList(MVT::Other), StoreVal.getValueType(), DL, Ops,
+ MSC->getMemOperand(), MSC->getIndexType(), MSC->isTruncatingStore());
+ }
+
+ if (refineIndexType(MSC, Index, MSC->isIndexScaled(), DAG)) {
+ SDValue Ops[] = {Chain, StoreVal, Mask, BasePtr, Index, Scale};
+ return DAG.getMaskedScatter(
+ DAG.getVTList(MVT::Other), StoreVal.getValueType(), DL, Ops,
+ MSC->getMemOperand(), MSC->getIndexType(), MSC->isTruncatingStore());
+ }
+
return SDValue();
}
@@ -9516,14 +9516,14 @@ SDValue DAGCombiner::visitMSTORE(SDNode *N) {
if (ISD::isBuildVectorAllZeros(Mask.getNode()))
return Chain;
- // If this is a masked load with an all ones mask, we can use a unmasked load.
- // FIXME: Can we do this for indexed, compressing, or truncating stores?
- if (ISD::isBuildVectorAllOnes(Mask.getNode()) &&
- MST->isUnindexed() && !MST->isCompressingStore() &&
- !MST->isTruncatingStore())
- return DAG.getStore(MST->getChain(), SDLoc(N), MST->getValue(),
- MST->getBasePtr(), MST->getMemOperand());
-
+ // If this is a masked load with an all ones mask, we can use a unmasked load.
+ // FIXME: Can we do this for indexed, compressing, or truncating stores?
+ if (ISD::isBuildVectorAllOnes(Mask.getNode()) &&
+ MST->isUnindexed() && !MST->isCompressingStore() &&
+ !MST->isTruncatingStore())
+ return DAG.getStore(MST->getChain(), SDLoc(N), MST->getValue(),
+ MST->getBasePtr(), MST->getMemOperand());
+
// Try transforming N to an indexed store.
if (CombineToPreIndexedLoadStore(N) || CombineToPostIndexedLoadStore(N))
return SDValue(N, 0);
@@ -9534,33 +9534,33 @@ SDValue DAGCombiner::visitMSTORE(SDNode *N) {
SDValue DAGCombiner::visitMGATHER(SDNode *N) {
MaskedGatherSDNode *MGT = cast<MaskedGatherSDNode>(N);
SDValue Mask = MGT->getMask();
- SDValue Chain = MGT->getChain();
- SDValue Index = MGT->getIndex();
- SDValue Scale = MGT->getScale();
- SDValue PassThru = MGT->getPassThru();
- SDValue BasePtr = MGT->getBasePtr();
+ SDValue Chain = MGT->getChain();
+ SDValue Index = MGT->getIndex();
+ SDValue Scale = MGT->getScale();
+ SDValue PassThru = MGT->getPassThru();
+ SDValue BasePtr = MGT->getBasePtr();
SDLoc DL(N);
// Zap gathers with a zero mask.
if (ISD::isBuildVectorAllZeros(Mask.getNode()))
- return CombineTo(N, PassThru, MGT->getChain());
-
- if (refineUniformBase(BasePtr, Index, DAG)) {
- SDValue Ops[] = {Chain, PassThru, Mask, BasePtr, Index, Scale};
- return DAG.getMaskedGather(DAG.getVTList(N->getValueType(0), MVT::Other),
- PassThru.getValueType(), DL, Ops,
- MGT->getMemOperand(), MGT->getIndexType(),
- MGT->getExtensionType());
- }
-
- if (refineIndexType(MGT, Index, MGT->isIndexScaled(), DAG)) {
- SDValue Ops[] = {Chain, PassThru, Mask, BasePtr, Index, Scale};
- return DAG.getMaskedGather(DAG.getVTList(N->getValueType(0), MVT::Other),
- PassThru.getValueType(), DL, Ops,
- MGT->getMemOperand(), MGT->getIndexType(),
- MGT->getExtensionType());
- }
-
+ return CombineTo(N, PassThru, MGT->getChain());
+
+ if (refineUniformBase(BasePtr, Index, DAG)) {
+ SDValue Ops[] = {Chain, PassThru, Mask, BasePtr, Index, Scale};
+ return DAG.getMaskedGather(DAG.getVTList(N->getValueType(0), MVT::Other),
+ PassThru.getValueType(), DL, Ops,
+ MGT->getMemOperand(), MGT->getIndexType(),
+ MGT->getExtensionType());
+ }
+
+ if (refineIndexType(MGT, Index, MGT->isIndexScaled(), DAG)) {
+ SDValue Ops[] = {Chain, PassThru, Mask, BasePtr, Index, Scale};
+ return DAG.getMaskedGather(DAG.getVTList(N->getValueType(0), MVT::Other),
+ PassThru.getValueType(), DL, Ops,
+ MGT->getMemOperand(), MGT->getIndexType(),
+ MGT->getExtensionType());
+ }
+
return SDValue();
}
@@ -9573,16 +9573,16 @@ SDValue DAGCombiner::visitMLOAD(SDNode *N) {
if (ISD::isBuildVectorAllZeros(Mask.getNode()))
return CombineTo(N, MLD->getPassThru(), MLD->getChain());
- // If this is a masked load with an all ones mask, we can use a unmasked load.
- // FIXME: Can we do this for indexed, expanding, or extending loads?
- if (ISD::isBuildVectorAllOnes(Mask.getNode()) &&
- MLD->isUnindexed() && !MLD->isExpandingLoad() &&
- MLD->getExtensionType() == ISD::NON_EXTLOAD) {
- SDValue NewLd = DAG.getLoad(N->getValueType(0), SDLoc(N), MLD->getChain(),
- MLD->getBasePtr(), MLD->getMemOperand());
- return CombineTo(N, NewLd, NewLd.getValue(1));
- }
-
+ // If this is a masked load with an all ones mask, we can use a unmasked load.
+ // FIXME: Can we do this for indexed, expanding, or extending loads?
+ if (ISD::isBuildVectorAllOnes(Mask.getNode()) &&
+ MLD->isUnindexed() && !MLD->isExpandingLoad() &&
+ MLD->getExtensionType() == ISD::NON_EXTLOAD) {
+ SDValue NewLd = DAG.getLoad(N->getValueType(0), SDLoc(N), MLD->getChain(),
+ MLD->getBasePtr(), MLD->getMemOperand());
+ return CombineTo(N, NewLd, NewLd.getValue(1));
+ }
+
// Try transforming N to an indexed load.
if (CombineToPreIndexedLoadStore(N) || CombineToPostIndexedLoadStore(N))
return SDValue(N, 0);
@@ -9742,113 +9742,113 @@ SDValue DAGCombiner::visitVSELECT(SDNode *N) {
return DAG.getSelect(DL, N1.getValueType(), WideSetCC, N1, N2);
}
}
-
- // Match VSELECTs into add with unsigned saturation.
- if (hasOperation(ISD::UADDSAT, VT)) {
- // Check if one of the arms of the VSELECT is vector with all bits set.
- // If it's on the left side invert the predicate to simplify logic below.
- SDValue Other;
- ISD::CondCode SatCC = CC;
- if (ISD::isBuildVectorAllOnes(N1.getNode())) {
- Other = N2;
- SatCC = ISD::getSetCCInverse(SatCC, VT.getScalarType());
- } else if (ISD::isBuildVectorAllOnes(N2.getNode())) {
- Other = N1;
- }
-
- if (Other && Other.getOpcode() == ISD::ADD) {
- SDValue CondLHS = LHS, CondRHS = RHS;
- SDValue OpLHS = Other.getOperand(0), OpRHS = Other.getOperand(1);
-
- // Canonicalize condition operands.
- if (SatCC == ISD::SETUGE) {
- std::swap(CondLHS, CondRHS);
- SatCC = ISD::SETULE;
- }
-
- // We can test against either of the addition operands.
- // x <= x+y ? x+y : ~0 --> uaddsat x, y
- // x+y >= x ? x+y : ~0 --> uaddsat x, y
- if (SatCC == ISD::SETULE && Other == CondRHS &&
- (OpLHS == CondLHS || OpRHS == CondLHS))
- return DAG.getNode(ISD::UADDSAT, DL, VT, OpLHS, OpRHS);
-
- if (isa<BuildVectorSDNode>(OpRHS) && isa<BuildVectorSDNode>(CondRHS) &&
- CondLHS == OpLHS) {
- // If the RHS is a constant we have to reverse the const
- // canonicalization.
- // x >= ~C ? x+C : ~0 --> uaddsat x, C
- auto MatchUADDSAT = [](ConstantSDNode *Op, ConstantSDNode *Cond) {
- return Cond->getAPIntValue() == ~Op->getAPIntValue();
- };
- if (SatCC == ISD::SETULE &&
- ISD::matchBinaryPredicate(OpRHS, CondRHS, MatchUADDSAT))
- return DAG.getNode(ISD::UADDSAT, DL, VT, OpLHS, OpRHS);
- }
- }
- }
-
- // Match VSELECTs into sub with unsigned saturation.
- if (hasOperation(ISD::USUBSAT, VT)) {
- // Check if one of the arms of the VSELECT is a zero vector. If it's on
- // the left side invert the predicate to simplify logic below.
- SDValue Other;
- ISD::CondCode SatCC = CC;
- if (ISD::isBuildVectorAllZeros(N1.getNode())) {
- Other = N2;
- SatCC = ISD::getSetCCInverse(SatCC, VT.getScalarType());
- } else if (ISD::isBuildVectorAllZeros(N2.getNode())) {
- Other = N1;
- }
-
- if (Other && Other.getNumOperands() == 2 && Other.getOperand(0) == LHS) {
- SDValue CondRHS = RHS;
- SDValue OpLHS = Other.getOperand(0), OpRHS = Other.getOperand(1);
-
- // Look for a general sub with unsigned saturation first.
- // x >= y ? x-y : 0 --> usubsat x, y
- // x > y ? x-y : 0 --> usubsat x, y
- if ((SatCC == ISD::SETUGE || SatCC == ISD::SETUGT) &&
- Other.getOpcode() == ISD::SUB && OpRHS == CondRHS)
- return DAG.getNode(ISD::USUBSAT, DL, VT, OpLHS, OpRHS);
-
- if (auto *OpRHSBV = dyn_cast<BuildVectorSDNode>(OpRHS)) {
- if (isa<BuildVectorSDNode>(CondRHS)) {
- // If the RHS is a constant we have to reverse the const
- // canonicalization.
- // x > C-1 ? x+-C : 0 --> usubsat x, C
- auto MatchUSUBSAT = [](ConstantSDNode *Op, ConstantSDNode *Cond) {
- return (!Op && !Cond) ||
- (Op && Cond &&
- Cond->getAPIntValue() == (-Op->getAPIntValue() - 1));
- };
- if (SatCC == ISD::SETUGT && Other.getOpcode() == ISD::ADD &&
- ISD::matchBinaryPredicate(OpRHS, CondRHS, MatchUSUBSAT,
- /*AllowUndefs*/ true)) {
- OpRHS = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT),
- OpRHS);
- return DAG.getNode(ISD::USUBSAT, DL, VT, OpLHS, OpRHS);
- }
-
- // Another special case: If C was a sign bit, the sub has been
- // canonicalized into a xor.
- // FIXME: Would it be better to use computeKnownBits to determine
- // whether it's safe to decanonicalize the xor?
- // x s< 0 ? x^C : 0 --> usubsat x, C
- if (auto *OpRHSConst = OpRHSBV->getConstantSplatNode()) {
- if (SatCC == ISD::SETLT && Other.getOpcode() == ISD::XOR &&
- ISD::isBuildVectorAllZeros(CondRHS.getNode()) &&
- OpRHSConst->getAPIntValue().isSignMask()) {
- // Note that we have to rebuild the RHS constant here to ensure
- // we don't rely on particular values of undef lanes.
- OpRHS = DAG.getConstant(OpRHSConst->getAPIntValue(), DL, VT);
- return DAG.getNode(ISD::USUBSAT, DL, VT, OpLHS, OpRHS);
- }
- }
- }
- }
- }
- }
+
+ // Match VSELECTs into add with unsigned saturation.
+ if (hasOperation(ISD::UADDSAT, VT)) {
+ // Check if one of the arms of the VSELECT is vector with all bits set.
+ // If it's on the left side invert the predicate to simplify logic below.
+ SDValue Other;
+ ISD::CondCode SatCC = CC;
+ if (ISD::isBuildVectorAllOnes(N1.getNode())) {
+ Other = N2;
+ SatCC = ISD::getSetCCInverse(SatCC, VT.getScalarType());
+ } else if (ISD::isBuildVectorAllOnes(N2.getNode())) {
+ Other = N1;
+ }
+
+ if (Other && Other.getOpcode() == ISD::ADD) {
+ SDValue CondLHS = LHS, CondRHS = RHS;
+ SDValue OpLHS = Other.getOperand(0), OpRHS = Other.getOperand(1);
+
+ // Canonicalize condition operands.
+ if (SatCC == ISD::SETUGE) {
+ std::swap(CondLHS, CondRHS);
+ SatCC = ISD::SETULE;
+ }
+
+ // We can test against either of the addition operands.
+ // x <= x+y ? x+y : ~0 --> uaddsat x, y
+ // x+y >= x ? x+y : ~0 --> uaddsat x, y
+ if (SatCC == ISD::SETULE && Other == CondRHS &&
+ (OpLHS == CondLHS || OpRHS == CondLHS))
+ return DAG.getNode(ISD::UADDSAT, DL, VT, OpLHS, OpRHS);
+
+ if (isa<BuildVectorSDNode>(OpRHS) && isa<BuildVectorSDNode>(CondRHS) &&
+ CondLHS == OpLHS) {
+ // If the RHS is a constant we have to reverse the const
+ // canonicalization.
+ // x >= ~C ? x+C : ~0 --> uaddsat x, C
+ auto MatchUADDSAT = [](ConstantSDNode *Op, ConstantSDNode *Cond) {
+ return Cond->getAPIntValue() == ~Op->getAPIntValue();
+ };
+ if (SatCC == ISD::SETULE &&
+ ISD::matchBinaryPredicate(OpRHS, CondRHS, MatchUADDSAT))
+ return DAG.getNode(ISD::UADDSAT, DL, VT, OpLHS, OpRHS);
+ }
+ }
+ }
+
+ // Match VSELECTs into sub with unsigned saturation.
+ if (hasOperation(ISD::USUBSAT, VT)) {
+ // Check if one of the arms of the VSELECT is a zero vector. If it's on
+ // the left side invert the predicate to simplify logic below.
+ SDValue Other;
+ ISD::CondCode SatCC = CC;
+ if (ISD::isBuildVectorAllZeros(N1.getNode())) {
+ Other = N2;
+ SatCC = ISD::getSetCCInverse(SatCC, VT.getScalarType());
+ } else if (ISD::isBuildVectorAllZeros(N2.getNode())) {
+ Other = N1;
+ }
+
+ if (Other && Other.getNumOperands() == 2 && Other.getOperand(0) == LHS) {
+ SDValue CondRHS = RHS;
+ SDValue OpLHS = Other.getOperand(0), OpRHS = Other.getOperand(1);
+
+ // Look for a general sub with unsigned saturation first.
+ // x >= y ? x-y : 0 --> usubsat x, y
+ // x > y ? x-y : 0 --> usubsat x, y
+ if ((SatCC == ISD::SETUGE || SatCC == ISD::SETUGT) &&
+ Other.getOpcode() == ISD::SUB && OpRHS == CondRHS)
+ return DAG.getNode(ISD::USUBSAT, DL, VT, OpLHS, OpRHS);
+
+ if (auto *OpRHSBV = dyn_cast<BuildVectorSDNode>(OpRHS)) {
+ if (isa<BuildVectorSDNode>(CondRHS)) {
+ // If the RHS is a constant we have to reverse the const
+ // canonicalization.
+ // x > C-1 ? x+-C : 0 --> usubsat x, C
+ auto MatchUSUBSAT = [](ConstantSDNode *Op, ConstantSDNode *Cond) {
+ return (!Op && !Cond) ||
+ (Op && Cond &&
+ Cond->getAPIntValue() == (-Op->getAPIntValue() - 1));
+ };
+ if (SatCC == ISD::SETUGT && Other.getOpcode() == ISD::ADD &&
+ ISD::matchBinaryPredicate(OpRHS, CondRHS, MatchUSUBSAT,
+ /*AllowUndefs*/ true)) {
+ OpRHS = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT),
+ OpRHS);
+ return DAG.getNode(ISD::USUBSAT, DL, VT, OpLHS, OpRHS);
+ }
+
+ // Another special case: If C was a sign bit, the sub has been
+ // canonicalized into a xor.
+ // FIXME: Would it be better to use computeKnownBits to determine
+ // whether it's safe to decanonicalize the xor?
+ // x s< 0 ? x^C : 0 --> usubsat x, C
+ if (auto *OpRHSConst = OpRHSBV->getConstantSplatNode()) {
+ if (SatCC == ISD::SETLT && Other.getOpcode() == ISD::XOR &&
+ ISD::isBuildVectorAllZeros(CondRHS.getNode()) &&
+ OpRHSConst->getAPIntValue().isSignMask()) {
+ // Note that we have to rebuild the RHS constant here to ensure
+ // we don't rely on particular values of undef lanes.
+ OpRHS = DAG.getConstant(OpRHSConst->getAPIntValue(), DL, VT);
+ return DAG.getNode(ISD::USUBSAT, DL, VT, OpLHS, OpRHS);
+ }
+ }
+ }
+ }
+ }
+ }
}
if (SimplifySelectOps(N, N1, N2))
@@ -10207,14 +10207,14 @@ SDValue DAGCombiner::CombineExtLoad(SDNode *N) {
SDValue BasePtr = LN0->getBasePtr();
for (unsigned Idx = 0; Idx < NumSplits; Idx++) {
const unsigned Offset = Idx * Stride;
- const Align Align = commonAlignment(LN0->getAlign(), Offset);
+ const Align Align = commonAlignment(LN0->getAlign(), Offset);
SDValue SplitLoad = DAG.getExtLoad(
ExtType, SDLoc(LN0), SplitDstVT, LN0->getChain(), BasePtr,
LN0->getPointerInfo().getWithOffset(Offset), SplitSrcVT, Align,
LN0->getMemOperand()->getFlags(), LN0->getAAInfo());
- BasePtr = DAG.getMemBasePlusOffset(BasePtr, TypeSize::Fixed(Stride), DL);
+ BasePtr = DAG.getMemBasePlusOffset(BasePtr, TypeSize::Fixed(Stride), DL);
Loads.push_back(SplitLoad.getValue(0));
Chains.push_back(SplitLoad.getValue(1));
@@ -10631,7 +10631,7 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
SDValue N00 = N0.getOperand(0);
SDValue N01 = N0.getOperand(1);
ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(2))->get();
- EVT N00VT = N00.getValueType();
+ EVT N00VT = N00.getValueType();
// sext(setcc) -> sext_in_reg(vsetcc) for vectors.
// Only do this before legalize for now.
@@ -10725,29 +10725,29 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
return DAG.getNode(ISD::ADD, DL, VT, Zext, DAG.getAllOnesConstant(DL, VT));
}
- // fold sext (not i1 X) -> add (zext i1 X), -1
- // TODO: This could be extended to handle bool vectors.
- if (N0.getValueType() == MVT::i1 && isBitwiseNot(N0) && N0.hasOneUse() &&
- (!LegalOperations || (TLI.isOperationLegal(ISD::ZERO_EXTEND, VT) &&
- TLI.isOperationLegal(ISD::ADD, VT)))) {
- // If we can eliminate the 'not', the sext form should be better
- if (SDValue NewXor = visitXOR(N0.getNode())) {
- // Returning N0 is a form of in-visit replacement that may have
- // invalidated N0.
- if (NewXor.getNode() == N0.getNode()) {
- // Return SDValue here as the xor should have already been replaced in
- // this sext.
- return SDValue();
- } else {
- // Return a new sext with the new xor.
- return DAG.getNode(ISD::SIGN_EXTEND, DL, VT, NewXor);
- }
- }
-
- SDValue Zext = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, N0.getOperand(0));
- return DAG.getNode(ISD::ADD, DL, VT, Zext, DAG.getAllOnesConstant(DL, VT));
- }
-
+ // fold sext (not i1 X) -> add (zext i1 X), -1
+ // TODO: This could be extended to handle bool vectors.
+ if (N0.getValueType() == MVT::i1 && isBitwiseNot(N0) && N0.hasOneUse() &&
+ (!LegalOperations || (TLI.isOperationLegal(ISD::ZERO_EXTEND, VT) &&
+ TLI.isOperationLegal(ISD::ADD, VT)))) {
+ // If we can eliminate the 'not', the sext form should be better
+ if (SDValue NewXor = visitXOR(N0.getNode())) {
+ // Returning N0 is a form of in-visit replacement that may have
+ // invalidated N0.
+ if (NewXor.getNode() == N0.getNode()) {
+ // Return SDValue here as the xor should have already been replaced in
+ // this sext.
+ return SDValue();
+ } else {
+ // Return a new sext with the new xor.
+ return DAG.getNode(ISD::SIGN_EXTEND, DL, VT, NewXor);
+ }
+ }
+
+ SDValue Zext = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, N0.getOperand(0));
+ return DAG.getNode(ISD::ADD, DL, VT, Zext, DAG.getAllOnesConstant(DL, VT));
+ }
+
return SDValue();
}
@@ -11015,16 +11015,16 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
N0.getValueType());
}
- // zext(setcc x,y,cc) -> zext(select x, y, true, false, cc)
+ // zext(setcc x,y,cc) -> zext(select x, y, true, false, cc)
SDLoc DL(N);
- EVT N0VT = N0.getValueType();
- EVT N00VT = N0.getOperand(0).getValueType();
+ EVT N0VT = N0.getValueType();
+ EVT N00VT = N0.getOperand(0).getValueType();
if (SDValue SCC = SimplifySelectCC(
- DL, N0.getOperand(0), N0.getOperand(1),
- DAG.getBoolConstant(true, DL, N0VT, N00VT),
- DAG.getBoolConstant(false, DL, N0VT, N00VT),
+ DL, N0.getOperand(0), N0.getOperand(1),
+ DAG.getBoolConstant(true, DL, N0VT, N00VT),
+ DAG.getBoolConstant(false, DL, N0VT, N00VT),
cast<CondCodeSDNode>(N0.getOperand(2))->get(), true))
- return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, SCC);
+ return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, SCC);
}
// (zext (shl (zext x), cst)) -> (shl (zext x), cst)
@@ -11113,26 +11113,26 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
// fold (aext (load x)) -> (aext (truncate (extload x)))
// None of the supported targets knows how to perform load and any_ext
- // on vectors in one instruction, so attempt to fold to zext instead.
- if (VT.isVector()) {
- // Try to simplify (zext (load x)).
- if (SDValue foldedExt =
- tryToFoldExtOfLoad(DAG, *this, TLI, VT, LegalOperations, N, N0,
- ISD::ZEXTLOAD, ISD::ZERO_EXTEND))
- return foldedExt;
- } else if (ISD::isNON_EXTLoad(N0.getNode()) &&
- ISD::isUNINDEXEDLoad(N0.getNode()) &&
- TLI.isLoadExtLegal(ISD::EXTLOAD, VT, N0.getValueType())) {
+ // on vectors in one instruction, so attempt to fold to zext instead.
+ if (VT.isVector()) {
+ // Try to simplify (zext (load x)).
+ if (SDValue foldedExt =
+ tryToFoldExtOfLoad(DAG, *this, TLI, VT, LegalOperations, N, N0,
+ ISD::ZEXTLOAD, ISD::ZERO_EXTEND))
+ return foldedExt;
+ } else if (ISD::isNON_EXTLoad(N0.getNode()) &&
+ ISD::isUNINDEXEDLoad(N0.getNode()) &&
+ TLI.isLoadExtLegal(ISD::EXTLOAD, VT, N0.getValueType())) {
bool DoXform = true;
- SmallVector<SDNode *, 4> SetCCs;
+ SmallVector<SDNode *, 4> SetCCs;
if (!N0.hasOneUse())
- DoXform =
- ExtendUsesToFormExtLoad(VT, N, N0, ISD::ANY_EXTEND, SetCCs, TLI);
+ DoXform =
+ ExtendUsesToFormExtLoad(VT, N, N0, ISD::ANY_EXTEND, SetCCs, TLI);
if (DoXform) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
SDValue ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, SDLoc(N), VT,
- LN0->getChain(), LN0->getBasePtr(),
- N0.getValueType(), LN0->getMemOperand());
+ LN0->getChain(), LN0->getBasePtr(),
+ N0.getValueType(), LN0->getMemOperand());
ExtendSetCCUses(SetCCs, N0, ExtLoad, ISD::ANY_EXTEND);
// If the load value is used only by N, replace it via CombineTo N.
bool NoReplaceTrunc = N0.hasOneUse();
@@ -11141,8 +11141,8 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
DAG.ReplaceAllUsesOfValueWith(SDValue(LN0, 1), ExtLoad.getValue(1));
recursivelyDeleteUnusedNodes(LN0);
} else {
- SDValue Trunc =
- DAG.getNode(ISD::TRUNCATE, SDLoc(N0), N0.getValueType(), ExtLoad);
+ SDValue Trunc =
+ DAG.getNode(ISD::TRUNCATE, SDLoc(N0), N0.getValueType(), ExtLoad);
CombineTo(LN0, Trunc, ExtLoad.getValue(1));
}
return SDValue(N, 0); // Return N so it doesn't get rechecked!
@@ -11347,12 +11347,12 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) {
return SDValue();
uint64_t ShiftAmt = N01->getZExtValue();
- uint64_t MemoryWidth = LN0->getMemoryVT().getScalarSizeInBits();
+ uint64_t MemoryWidth = LN0->getMemoryVT().getScalarSizeInBits();
if (LN0->getExtensionType() != ISD::SEXTLOAD && MemoryWidth > ShiftAmt)
ExtVT = EVT::getIntegerVT(*DAG.getContext(), MemoryWidth - ShiftAmt);
else
ExtVT = EVT::getIntegerVT(*DAG.getContext(),
- VT.getScalarSizeInBits() - ShiftAmt);
+ VT.getScalarSizeInBits() - ShiftAmt);
} else if (Opc == ISD::AND) {
// An AND with a constant mask is the same as a truncate + zero-extend.
auto AndC = dyn_cast<ConstantSDNode>(N->getOperand(1));
@@ -11379,12 +11379,12 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) {
SDValue SRL = N0;
if (auto *ConstShift = dyn_cast<ConstantSDNode>(SRL.getOperand(1))) {
ShAmt = ConstShift->getZExtValue();
- unsigned EVTBits = ExtVT.getScalarSizeInBits();
+ unsigned EVTBits = ExtVT.getScalarSizeInBits();
// Is the shift amount a multiple of size of VT?
if ((ShAmt & (EVTBits-1)) == 0) {
N0 = N0.getOperand(0);
// Is the load width a multiple of size of VT?
- if ((N0.getScalarValueSizeInBits() & (EVTBits - 1)) != 0)
+ if ((N0.getScalarValueSizeInBits() & (EVTBits - 1)) != 0)
return SDValue();
}
@@ -11414,7 +11414,7 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) {
EVT MaskedVT = EVT::getIntegerVT(*DAG.getContext(),
ShiftMask.countTrailingOnes());
// If the mask is smaller, recompute the type.
- if ((ExtVT.getScalarSizeInBits() > MaskedVT.getScalarSizeInBits()) &&
+ if ((ExtVT.getScalarSizeInBits() > MaskedVT.getScalarSizeInBits()) &&
TLI.isLoadExtLegal(ExtType, N0.getValueType(), MaskedVT))
ExtVT = MaskedVT;
}
@@ -11445,9 +11445,9 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) {
return SDValue();
auto AdjustBigEndianShift = [&](unsigned ShAmt) {
- unsigned LVTStoreBits =
- LN0->getMemoryVT().getStoreSizeInBits().getFixedSize();
- unsigned EVTStoreBits = ExtVT.getStoreSizeInBits().getFixedSize();
+ unsigned LVTStoreBits =
+ LN0->getMemoryVT().getStoreSizeInBits().getFixedSize();
+ unsigned EVTStoreBits = ExtVT.getStoreSizeInBits().getFixedSize();
return LVTStoreBits - EVTStoreBits - ShAmt;
};
@@ -11457,13 +11457,13 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) {
ShAmt = AdjustBigEndianShift(ShAmt);
uint64_t PtrOff = ShAmt / 8;
- Align NewAlign = commonAlignment(LN0->getAlign(), PtrOff);
+ Align NewAlign = commonAlignment(LN0->getAlign(), PtrOff);
SDLoc DL(LN0);
// The original load itself didn't wrap, so an offset within it doesn't.
SDNodeFlags Flags;
Flags.setNoUnsignedWrap(true);
- SDValue NewPtr = DAG.getMemBasePlusOffset(LN0->getBasePtr(),
- TypeSize::Fixed(PtrOff), DL, Flags);
+ SDValue NewPtr = DAG.getMemBasePlusOffset(LN0->getBasePtr(),
+ TypeSize::Fixed(PtrOff), DL, Flags);
AddToWorklist(NewPtr.getNode());
SDValue Load;
@@ -11485,13 +11485,13 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) {
SDValue Result = Load;
if (ShLeftAmt != 0) {
EVT ShImmTy = getShiftAmountTy(Result.getValueType());
- if (!isUIntN(ShImmTy.getScalarSizeInBits(), ShLeftAmt))
+ if (!isUIntN(ShImmTy.getScalarSizeInBits(), ShLeftAmt))
ShImmTy = VT;
// If the shift amount is as large as the result size (but, presumably,
// no larger than the source) then the useful bits of the result are
// zero; we can't simply return the shortened shift, because the result
// of that operation is undefined.
- if (ShLeftAmt >= VT.getScalarSizeInBits())
+ if (ShLeftAmt >= VT.getScalarSizeInBits())
Result = DAG.getConstant(0, DL, VT);
else
Result = DAG.getNode(ISD::SHL, DL, VT,
@@ -11641,41 +11641,41 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
return SDValue(N, 0); // Return N so it doesn't get rechecked!
}
- // fold (sext_inreg (masked_load x)) -> (sext_masked_load x)
- // ignore it if the masked load is already sign extended
- if (MaskedLoadSDNode *Ld = dyn_cast<MaskedLoadSDNode>(N0)) {
- if (ExtVT == Ld->getMemoryVT() && N0.hasOneUse() &&
- Ld->getExtensionType() != ISD::LoadExtType::NON_EXTLOAD &&
- TLI.isLoadExtLegal(ISD::SEXTLOAD, VT, ExtVT)) {
- SDValue ExtMaskedLoad = DAG.getMaskedLoad(
- VT, SDLoc(N), Ld->getChain(), Ld->getBasePtr(), Ld->getOffset(),
- Ld->getMask(), Ld->getPassThru(), ExtVT, Ld->getMemOperand(),
- Ld->getAddressingMode(), ISD::SEXTLOAD, Ld->isExpandingLoad());
- CombineTo(N, ExtMaskedLoad);
- CombineTo(N0.getNode(), ExtMaskedLoad, ExtMaskedLoad.getValue(1));
- return SDValue(N, 0); // Return N so it doesn't get rechecked!
- }
- }
-
- // fold (sext_inreg (masked_gather x)) -> (sext_masked_gather x)
- if (auto *GN0 = dyn_cast<MaskedGatherSDNode>(N0)) {
- if (SDValue(GN0, 0).hasOneUse() &&
- ExtVT == GN0->getMemoryVT() &&
- TLI.isVectorLoadExtDesirable(SDValue(SDValue(GN0, 0)))) {
- SDValue Ops[] = {GN0->getChain(), GN0->getPassThru(), GN0->getMask(),
- GN0->getBasePtr(), GN0->getIndex(), GN0->getScale()};
-
- SDValue ExtLoad = DAG.getMaskedGather(
- DAG.getVTList(VT, MVT::Other), ExtVT, SDLoc(N), Ops,
- GN0->getMemOperand(), GN0->getIndexType(), ISD::SEXTLOAD);
-
- CombineTo(N, ExtLoad);
- CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1));
- AddToWorklist(ExtLoad.getNode());
- return SDValue(N, 0); // Return N so it doesn't get rechecked!
- }
- }
-
+ // fold (sext_inreg (masked_load x)) -> (sext_masked_load x)
+ // ignore it if the masked load is already sign extended
+ if (MaskedLoadSDNode *Ld = dyn_cast<MaskedLoadSDNode>(N0)) {
+ if (ExtVT == Ld->getMemoryVT() && N0.hasOneUse() &&
+ Ld->getExtensionType() != ISD::LoadExtType::NON_EXTLOAD &&
+ TLI.isLoadExtLegal(ISD::SEXTLOAD, VT, ExtVT)) {
+ SDValue ExtMaskedLoad = DAG.getMaskedLoad(
+ VT, SDLoc(N), Ld->getChain(), Ld->getBasePtr(), Ld->getOffset(),
+ Ld->getMask(), Ld->getPassThru(), ExtVT, Ld->getMemOperand(),
+ Ld->getAddressingMode(), ISD::SEXTLOAD, Ld->isExpandingLoad());
+ CombineTo(N, ExtMaskedLoad);
+ CombineTo(N0.getNode(), ExtMaskedLoad, ExtMaskedLoad.getValue(1));
+ return SDValue(N, 0); // Return N so it doesn't get rechecked!
+ }
+ }
+
+ // fold (sext_inreg (masked_gather x)) -> (sext_masked_gather x)
+ if (auto *GN0 = dyn_cast<MaskedGatherSDNode>(N0)) {
+ if (SDValue(GN0, 0).hasOneUse() &&
+ ExtVT == GN0->getMemoryVT() &&
+ TLI.isVectorLoadExtDesirable(SDValue(SDValue(GN0, 0)))) {
+ SDValue Ops[] = {GN0->getChain(), GN0->getPassThru(), GN0->getMask(),
+ GN0->getBasePtr(), GN0->getIndex(), GN0->getScale()};
+
+ SDValue ExtLoad = DAG.getMaskedGather(
+ DAG.getVTList(VT, MVT::Other), ExtVT, SDLoc(N), Ops,
+ GN0->getMemOperand(), GN0->getIndexType(), ISD::SEXTLOAD);
+
+ CombineTo(N, ExtLoad);
+ CombineTo(N0.getNode(), ExtLoad, ExtLoad.getValue(1));
+ AddToWorklist(ExtLoad.getNode());
+ return SDValue(N, 0); // Return N so it doesn't get rechecked!
+ }
+ }
+
// Form (sext_inreg (bswap >> 16)) or (sext_inreg (rotl (bswap) 16))
if (ExtVTBits <= 16 && N0.getOpcode() == ISD::OR) {
if (SDValue BSwap = MatchBSwapHWordLow(N0.getNode(), N0.getOperand(0),
@@ -11776,11 +11776,11 @@ SDValue DAGCombiner::visitTRUNCATE(SDNode *N) {
EVT ExTy = N0.getValueType();
EVT TrTy = N->getValueType(0);
- auto EltCnt = VecTy.getVectorElementCount();
+ auto EltCnt = VecTy.getVectorElementCount();
unsigned SizeRatio = ExTy.getSizeInBits()/TrTy.getSizeInBits();
- auto NewEltCnt = EltCnt * SizeRatio;
+ auto NewEltCnt = EltCnt * SizeRatio;
- EVT NVT = EVT::getVectorVT(*DAG.getContext(), TrTy, NewEltCnt);
+ EVT NVT = EVT::getVectorVT(*DAG.getContext(), TrTy, NewEltCnt);
assert(NVT.getSizeInBits() == VecTy.getSizeInBits() && "Invalid Size");
SDValue EltNo = N0->getOperand(1);
@@ -11894,7 +11894,7 @@ SDValue DAGCombiner::visitTRUNCATE(SDNode *N) {
// after truncation.
if (N0.hasOneUse() && ISD::isUNINDEXEDLoad(N0.getNode())) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
- if (LN0->isSimple() && LN0->getMemoryVT().bitsLT(VT)) {
+ if (LN0->isSimple() && LN0->getMemoryVT().bitsLT(VT)) {
SDValue NewLoad = DAG.getExtLoad(LN0->getExtensionType(), SDLoc(LN0),
VT, LN0->getChain(), LN0->getBasePtr(),
LN0->getMemoryVT(),
@@ -11967,7 +11967,7 @@ SDValue DAGCombiner::visitTRUNCATE(SDNode *N) {
}
// Simplify the operands using demanded-bits information.
- if (SimplifyDemandedBits(SDValue(N, 0)))
+ if (SimplifyDemandedBits(SDValue(N, 0)))
return SDValue(N, 0);
// (trunc adde(X, Y, Carry)) -> (adde trunc(X), trunc(Y), Carry)
@@ -12194,7 +12194,7 @@ SDValue DAGCombiner::visitBITCAST(SDNode *N) {
*LN0->getMemOperand())) {
SDValue Load =
DAG.getLoad(VT, SDLoc(N), LN0->getChain(), LN0->getBasePtr(),
- LN0->getPointerInfo(), LN0->getAlign(),
+ LN0->getPointerInfo(), LN0->getAlign(),
LN0->getMemOperand()->getFlags(), LN0->getAAInfo());
DAG.ReplaceAllUsesOfValueWith(N0.getValue(1), Load.getValue(1));
return Load;
@@ -12573,15 +12573,15 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) {
// fold (fadd (fmul x, y), z) -> (fma x, y, z)
if (isContractableFMUL(N0) && (Aggressive || N0->hasOneUse())) {
- return DAG.getNode(PreferredFusedOpcode, SL, VT, N0.getOperand(0),
- N0.getOperand(1), N1);
+ return DAG.getNode(PreferredFusedOpcode, SL, VT, N0.getOperand(0),
+ N0.getOperand(1), N1);
}
// fold (fadd x, (fmul y, z)) -> (fma y, z, x)
// Note: Commutes FADD operands.
if (isContractableFMUL(N1) && (Aggressive || N1->hasOneUse())) {
- return DAG.getNode(PreferredFusedOpcode, SL, VT, N1.getOperand(0),
- N1.getOperand(1), N0);
+ return DAG.getNode(PreferredFusedOpcode, SL, VT, N1.getOperand(0),
+ N1.getOperand(1), N0);
}
// fadd (fma A, B, (fmul C, D)), E --> fma A, B, (fma C, D, E)
@@ -12604,8 +12604,8 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) {
SDValue B = FMA.getOperand(1);
SDValue C = FMA.getOperand(2).getOperand(0);
SDValue D = FMA.getOperand(2).getOperand(1);
- SDValue CDE = DAG.getNode(PreferredFusedOpcode, SL, VT, C, D, E);
- return DAG.getNode(PreferredFusedOpcode, SL, VT, A, B, CDE);
+ SDValue CDE = DAG.getNode(PreferredFusedOpcode, SL, VT, C, D, E);
+ return DAG.getNode(PreferredFusedOpcode, SL, VT, A, B, CDE);
}
// Look through FP_EXTEND nodes to do more combining.
@@ -12617,9 +12617,9 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) {
TLI.isFPExtFoldable(DAG, PreferredFusedOpcode, VT,
N00.getValueType())) {
return DAG.getNode(PreferredFusedOpcode, SL, VT,
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N00.getOperand(0)),
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N00.getOperand(1)),
- N1);
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N00.getOperand(0)),
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N00.getOperand(1)),
+ N1);
}
}
@@ -12631,9 +12631,9 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) {
TLI.isFPExtFoldable(DAG, PreferredFusedOpcode, VT,
N10.getValueType())) {
return DAG.getNode(PreferredFusedOpcode, SL, VT,
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N10.getOperand(0)),
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N10.getOperand(1)),
- N0);
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N10.getOperand(0)),
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N10.getOperand(1)),
+ N0);
}
}
@@ -12641,13 +12641,13 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) {
if (Aggressive) {
// fold (fadd (fma x, y, (fpext (fmul u, v))), z)
// -> (fma x, y, (fma (fpext u), (fpext v), z))
- auto FoldFAddFMAFPExtFMul = [&](SDValue X, SDValue Y, SDValue U, SDValue V,
- SDValue Z) {
+ auto FoldFAddFMAFPExtFMul = [&](SDValue X, SDValue Y, SDValue U, SDValue V,
+ SDValue Z) {
return DAG.getNode(PreferredFusedOpcode, SL, VT, X, Y,
DAG.getNode(PreferredFusedOpcode, SL, VT,
DAG.getNode(ISD::FP_EXTEND, SL, VT, U),
DAG.getNode(ISD::FP_EXTEND, SL, VT, V),
- Z));
+ Z));
};
if (N0.getOpcode() == PreferredFusedOpcode) {
SDValue N02 = N0.getOperand(2);
@@ -12658,7 +12658,7 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) {
N020.getValueType())) {
return FoldFAddFMAFPExtFMul(N0.getOperand(0), N0.getOperand(1),
N020.getOperand(0), N020.getOperand(1),
- N1);
+ N1);
}
}
}
@@ -12668,14 +12668,14 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) {
// FIXME: This turns two single-precision and one double-precision
// operation into two double-precision operations, which might not be
// interesting for all targets, especially GPUs.
- auto FoldFAddFPExtFMAFMul = [&](SDValue X, SDValue Y, SDValue U, SDValue V,
- SDValue Z) {
- return DAG.getNode(
- PreferredFusedOpcode, SL, VT, DAG.getNode(ISD::FP_EXTEND, SL, VT, X),
- DAG.getNode(ISD::FP_EXTEND, SL, VT, Y),
- DAG.getNode(PreferredFusedOpcode, SL, VT,
- DAG.getNode(ISD::FP_EXTEND, SL, VT, U),
- DAG.getNode(ISD::FP_EXTEND, SL, VT, V), Z));
+ auto FoldFAddFPExtFMAFMul = [&](SDValue X, SDValue Y, SDValue U, SDValue V,
+ SDValue Z) {
+ return DAG.getNode(
+ PreferredFusedOpcode, SL, VT, DAG.getNode(ISD::FP_EXTEND, SL, VT, X),
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, Y),
+ DAG.getNode(PreferredFusedOpcode, SL, VT,
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, U),
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, V), Z));
};
if (N0.getOpcode() == ISD::FP_EXTEND) {
SDValue N00 = N0.getOperand(0);
@@ -12686,7 +12686,7 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) {
N00.getValueType())) {
return FoldFAddFPExtFMAFMul(N00.getOperand(0), N00.getOperand(1),
N002.getOperand(0), N002.getOperand(1),
- N1);
+ N1);
}
}
}
@@ -12702,7 +12702,7 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) {
N120.getValueType())) {
return FoldFAddFMAFPExtFMul(N1.getOperand(0), N1.getOperand(1),
N120.getOperand(0), N120.getOperand(1),
- N0);
+ N0);
}
}
}
@@ -12721,7 +12721,7 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) {
N10.getValueType())) {
return FoldFAddFPExtFMAFMul(N10.getOperand(0), N10.getOperand(1),
N102.getOperand(0), N102.getOperand(1),
- N0);
+ N0);
}
}
}
@@ -12779,7 +12779,7 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
auto tryToFoldXYSubZ = [&](SDValue XY, SDValue Z) {
if (isContractableFMUL(XY) && (Aggressive || XY->hasOneUse())) {
return DAG.getNode(PreferredFusedOpcode, SL, VT, XY.getOperand(0),
- XY.getOperand(1), DAG.getNode(ISD::FNEG, SL, VT, Z));
+ XY.getOperand(1), DAG.getNode(ISD::FNEG, SL, VT, Z));
}
return SDValue();
};
@@ -12790,7 +12790,7 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
if (isContractableFMUL(YZ) && (Aggressive || YZ->hasOneUse())) {
return DAG.getNode(PreferredFusedOpcode, SL, VT,
DAG.getNode(ISD::FNEG, SL, VT, YZ.getOperand(0)),
- YZ.getOperand(1), X);
+ YZ.getOperand(1), X);
}
return SDValue();
};
@@ -12821,7 +12821,7 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
SDValue N01 = N0.getOperand(0).getOperand(1);
return DAG.getNode(PreferredFusedOpcode, SL, VT,
DAG.getNode(ISD::FNEG, SL, VT, N00), N01,
- DAG.getNode(ISD::FNEG, SL, VT, N1));
+ DAG.getNode(ISD::FNEG, SL, VT, N1));
}
// Look through FP_EXTEND nodes to do more combining.
@@ -12834,9 +12834,9 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
TLI.isFPExtFoldable(DAG, PreferredFusedOpcode, VT,
N00.getValueType())) {
return DAG.getNode(PreferredFusedOpcode, SL, VT,
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N00.getOperand(0)),
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N00.getOperand(1)),
- DAG.getNode(ISD::FNEG, SL, VT, N1));
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N00.getOperand(0)),
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N00.getOperand(1)),
+ DAG.getNode(ISD::FNEG, SL, VT, N1));
}
}
@@ -12848,11 +12848,11 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
if (isContractableFMUL(N10) &&
TLI.isFPExtFoldable(DAG, PreferredFusedOpcode, VT,
N10.getValueType())) {
- return DAG.getNode(
- PreferredFusedOpcode, SL, VT,
- DAG.getNode(ISD::FNEG, SL, VT,
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N10.getOperand(0))),
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N10.getOperand(1)), N0);
+ return DAG.getNode(
+ PreferredFusedOpcode, SL, VT,
+ DAG.getNode(ISD::FNEG, SL, VT,
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N10.getOperand(0))),
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N10.getOperand(1)), N0);
}
}
@@ -12869,12 +12869,12 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
if (isContractableFMUL(N000) &&
TLI.isFPExtFoldable(DAG, PreferredFusedOpcode, VT,
N00.getValueType())) {
- return DAG.getNode(
- ISD::FNEG, SL, VT,
- DAG.getNode(PreferredFusedOpcode, SL, VT,
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N000.getOperand(0)),
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N000.getOperand(1)),
- N1));
+ return DAG.getNode(
+ ISD::FNEG, SL, VT,
+ DAG.getNode(PreferredFusedOpcode, SL, VT,
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N000.getOperand(0)),
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N000.getOperand(1)),
+ N1));
}
}
}
@@ -12892,12 +12892,12 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
if (isContractableFMUL(N000) &&
TLI.isFPExtFoldable(DAG, PreferredFusedOpcode, VT,
N000.getValueType())) {
- return DAG.getNode(
- ISD::FNEG, SL, VT,
- DAG.getNode(PreferredFusedOpcode, SL, VT,
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N000.getOperand(0)),
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N000.getOperand(1)),
- N1));
+ return DAG.getNode(
+ ISD::FNEG, SL, VT,
+ DAG.getNode(PreferredFusedOpcode, SL, VT,
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N000.getOperand(0)),
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N000.getOperand(1)),
+ N1));
}
}
}
@@ -12909,12 +12909,12 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
if (CanFuse && N0.getOpcode() == PreferredFusedOpcode &&
isContractableFMUL(N0.getOperand(2)) && N0->hasOneUse() &&
N0.getOperand(2)->hasOneUse()) {
- return DAG.getNode(PreferredFusedOpcode, SL, VT, N0.getOperand(0),
- N0.getOperand(1),
+ return DAG.getNode(PreferredFusedOpcode, SL, VT, N0.getOperand(0),
+ N0.getOperand(1),
DAG.getNode(PreferredFusedOpcode, SL, VT,
N0.getOperand(2).getOperand(0),
N0.getOperand(2).getOperand(1),
- DAG.getNode(ISD::FNEG, SL, VT, N1)));
+ DAG.getNode(ISD::FNEG, SL, VT, N1)));
}
// fold (fsub x, (fma y, z, (fmul u, v)))
@@ -12924,11 +12924,11 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
N1->hasOneUse() && NoSignedZero) {
SDValue N20 = N1.getOperand(2).getOperand(0);
SDValue N21 = N1.getOperand(2).getOperand(1);
- return DAG.getNode(
- PreferredFusedOpcode, SL, VT,
- DAG.getNode(ISD::FNEG, SL, VT, N1.getOperand(0)), N1.getOperand(1),
- DAG.getNode(PreferredFusedOpcode, SL, VT,
- DAG.getNode(ISD::FNEG, SL, VT, N20), N21, N0));
+ return DAG.getNode(
+ PreferredFusedOpcode, SL, VT,
+ DAG.getNode(ISD::FNEG, SL, VT, N1.getOperand(0)), N1.getOperand(1),
+ DAG.getNode(PreferredFusedOpcode, SL, VT,
+ DAG.getNode(ISD::FNEG, SL, VT, N20), N21, N0));
}
@@ -12942,13 +12942,13 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
if (isContractableFMUL(N020) &&
TLI.isFPExtFoldable(DAG, PreferredFusedOpcode, VT,
N020.getValueType())) {
- return DAG.getNode(
- PreferredFusedOpcode, SL, VT, N0.getOperand(0), N0.getOperand(1),
- DAG.getNode(
- PreferredFusedOpcode, SL, VT,
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N020.getOperand(0)),
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N020.getOperand(1)),
- DAG.getNode(ISD::FNEG, SL, VT, N1)));
+ return DAG.getNode(
+ PreferredFusedOpcode, SL, VT, N0.getOperand(0), N0.getOperand(1),
+ DAG.getNode(
+ PreferredFusedOpcode, SL, VT,
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N020.getOperand(0)),
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N020.getOperand(1)),
+ DAG.getNode(ISD::FNEG, SL, VT, N1)));
}
}
}
@@ -12966,15 +12966,15 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
if (isContractableFMUL(N002) &&
TLI.isFPExtFoldable(DAG, PreferredFusedOpcode, VT,
N00.getValueType())) {
- return DAG.getNode(
- PreferredFusedOpcode, SL, VT,
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N00.getOperand(0)),
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N00.getOperand(1)),
- DAG.getNode(
- PreferredFusedOpcode, SL, VT,
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N002.getOperand(0)),
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N002.getOperand(1)),
- DAG.getNode(ISD::FNEG, SL, VT, N1)));
+ return DAG.getNode(
+ PreferredFusedOpcode, SL, VT,
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N00.getOperand(0)),
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N00.getOperand(1)),
+ DAG.getNode(
+ PreferredFusedOpcode, SL, VT,
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N002.getOperand(0)),
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N002.getOperand(1)),
+ DAG.getNode(ISD::FNEG, SL, VT, N1)));
}
}
}
@@ -12990,13 +12990,13 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
N120.getValueType())) {
SDValue N1200 = N120.getOperand(0);
SDValue N1201 = N120.getOperand(1);
- return DAG.getNode(
- PreferredFusedOpcode, SL, VT,
- DAG.getNode(ISD::FNEG, SL, VT, N1.getOperand(0)), N1.getOperand(1),
- DAG.getNode(PreferredFusedOpcode, SL, VT,
- DAG.getNode(ISD::FNEG, SL, VT,
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N1200)),
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N1201), N0));
+ return DAG.getNode(
+ PreferredFusedOpcode, SL, VT,
+ DAG.getNode(ISD::FNEG, SL, VT, N1.getOperand(0)), N1.getOperand(1),
+ DAG.getNode(PreferredFusedOpcode, SL, VT,
+ DAG.getNode(ISD::FNEG, SL, VT,
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N1200)),
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N1201), N0));
}
}
@@ -13017,15 +13017,15 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
CvtSrc.getValueType())) {
SDValue N1020 = N102.getOperand(0);
SDValue N1021 = N102.getOperand(1);
- return DAG.getNode(
- PreferredFusedOpcode, SL, VT,
- DAG.getNode(ISD::FNEG, SL, VT,
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N100)),
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N101),
- DAG.getNode(PreferredFusedOpcode, SL, VT,
- DAG.getNode(ISD::FNEG, SL, VT,
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N1020)),
- DAG.getNode(ISD::FP_EXTEND, SL, VT, N1021), N0));
+ return DAG.getNode(
+ PreferredFusedOpcode, SL, VT,
+ DAG.getNode(ISD::FNEG, SL, VT,
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N100)),
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N101),
+ DAG.getNode(PreferredFusedOpcode, SL, VT,
+ DAG.getNode(ISD::FNEG, SL, VT,
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N1020)),
+ DAG.getNode(ISD::FP_EXTEND, SL, VT, N1021), N0));
}
}
}
@@ -13072,56 +13072,56 @@ SDValue DAGCombiner::visitFMULForFMADistributiveCombine(SDNode *N) {
// fold (fmul (fadd x0, +1.0), y) -> (fma x0, y, y)
// fold (fmul (fadd x0, -1.0), y) -> (fma x0, y, (fneg y))
- auto FuseFADD = [&](SDValue X, SDValue Y) {
+ auto FuseFADD = [&](SDValue X, SDValue Y) {
if (X.getOpcode() == ISD::FADD && (Aggressive || X->hasOneUse())) {
if (auto *C = isConstOrConstSplatFP(X.getOperand(1), true)) {
if (C->isExactlyValue(+1.0))
return DAG.getNode(PreferredFusedOpcode, SL, VT, X.getOperand(0), Y,
- Y);
+ Y);
if (C->isExactlyValue(-1.0))
return DAG.getNode(PreferredFusedOpcode, SL, VT, X.getOperand(0), Y,
- DAG.getNode(ISD::FNEG, SL, VT, Y));
+ DAG.getNode(ISD::FNEG, SL, VT, Y));
}
}
return SDValue();
};
- if (SDValue FMA = FuseFADD(N0, N1))
+ if (SDValue FMA = FuseFADD(N0, N1))
return FMA;
- if (SDValue FMA = FuseFADD(N1, N0))
+ if (SDValue FMA = FuseFADD(N1, N0))
return FMA;
// fold (fmul (fsub +1.0, x1), y) -> (fma (fneg x1), y, y)
// fold (fmul (fsub -1.0, x1), y) -> (fma (fneg x1), y, (fneg y))
// fold (fmul (fsub x0, +1.0), y) -> (fma x0, y, (fneg y))
// fold (fmul (fsub x0, -1.0), y) -> (fma x0, y, y)
- auto FuseFSUB = [&](SDValue X, SDValue Y) {
+ auto FuseFSUB = [&](SDValue X, SDValue Y) {
if (X.getOpcode() == ISD::FSUB && (Aggressive || X->hasOneUse())) {
if (auto *C0 = isConstOrConstSplatFP(X.getOperand(0), true)) {
if (C0->isExactlyValue(+1.0))
return DAG.getNode(PreferredFusedOpcode, SL, VT,
DAG.getNode(ISD::FNEG, SL, VT, X.getOperand(1)), Y,
- Y);
+ Y);
if (C0->isExactlyValue(-1.0))
return DAG.getNode(PreferredFusedOpcode, SL, VT,
DAG.getNode(ISD::FNEG, SL, VT, X.getOperand(1)), Y,
- DAG.getNode(ISD::FNEG, SL, VT, Y));
+ DAG.getNode(ISD::FNEG, SL, VT, Y));
}
if (auto *C1 = isConstOrConstSplatFP(X.getOperand(1), true)) {
if (C1->isExactlyValue(+1.0))
return DAG.getNode(PreferredFusedOpcode, SL, VT, X.getOperand(0), Y,
- DAG.getNode(ISD::FNEG, SL, VT, Y));
+ DAG.getNode(ISD::FNEG, SL, VT, Y));
if (C1->isExactlyValue(-1.0))
return DAG.getNode(PreferredFusedOpcode, SL, VT, X.getOperand(0), Y,
- Y);
+ Y);
}
}
return SDValue();
};
- if (SDValue FMA = FuseFSUB(N0, N1))
+ if (SDValue FMA = FuseFSUB(N0, N1))
return FMA;
- if (SDValue FMA = FuseFSUB(N1, N0))
+ if (SDValue FMA = FuseFSUB(N1, N0))
return FMA;
return SDValue();
@@ -13130,13 +13130,13 @@ SDValue DAGCombiner::visitFMULForFMADistributiveCombine(SDNode *N) {
SDValue DAGCombiner::visitFADD(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
- bool N0CFP = DAG.isConstantFPBuildVectorOrConstantFP(N0);
- bool N1CFP = DAG.isConstantFPBuildVectorOrConstantFP(N1);
+ bool N0CFP = DAG.isConstantFPBuildVectorOrConstantFP(N0);
+ bool N1CFP = DAG.isConstantFPBuildVectorOrConstantFP(N1);
EVT VT = N->getValueType(0);
SDLoc DL(N);
const TargetOptions &Options = DAG.getTarget().Options;
- SDNodeFlags Flags = N->getFlags();
- SelectionDAG::FlagInserter FlagsInserter(DAG, N);
+ SDNodeFlags Flags = N->getFlags();
+ SelectionDAG::FlagInserter FlagsInserter(DAG, N);
if (SDValue R = DAG.simplifyFPBinop(N->getOpcode(), N0, N1, Flags))
return R;
@@ -13148,11 +13148,11 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
// fold (fadd c1, c2) -> c1 + c2
if (N0CFP && N1CFP)
- return DAG.getNode(ISD::FADD, DL, VT, N0, N1);
+ return DAG.getNode(ISD::FADD, DL, VT, N0, N1);
// canonicalize constant to RHS
if (N0CFP && !N1CFP)
- return DAG.getNode(ISD::FADD, DL, VT, N1, N0);
+ return DAG.getNode(ISD::FADD, DL, VT, N1, N0);
// N0 + -0.0 --> N0 (also allowed with +0.0 and fast-math)
ConstantFPSDNode *N1C = isConstOrConstSplatFP(N1, true);
@@ -13167,13 +13167,13 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
if (!LegalOperations || TLI.isOperationLegalOrCustom(ISD::FSUB, VT))
if (SDValue NegN1 = TLI.getCheaperNegatedExpression(
N1, DAG, LegalOperations, ForCodeSize))
- return DAG.getNode(ISD::FSUB, DL, VT, N0, NegN1);
+ return DAG.getNode(ISD::FSUB, DL, VT, N0, NegN1);
// fold (fadd (fneg A), B) -> (fsub B, A)
if (!LegalOperations || TLI.isOperationLegalOrCustom(ISD::FSUB, VT))
if (SDValue NegN0 = TLI.getCheaperNegatedExpression(
N0, DAG, LegalOperations, ForCodeSize))
- return DAG.getNode(ISD::FSUB, DL, VT, N1, NegN0);
+ return DAG.getNode(ISD::FSUB, DL, VT, N1, NegN0);
auto isFMulNegTwo = [](SDValue FMul) {
if (!FMul.hasOneUse() || FMul.getOpcode() != ISD::FMUL)
@@ -13185,14 +13185,14 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
// fadd (fmul B, -2.0), A --> fsub A, (fadd B, B)
if (isFMulNegTwo(N0)) {
SDValue B = N0.getOperand(0);
- SDValue Add = DAG.getNode(ISD::FADD, DL, VT, B, B);
- return DAG.getNode(ISD::FSUB, DL, VT, N1, Add);
+ SDValue Add = DAG.getNode(ISD::FADD, DL, VT, B, B);
+ return DAG.getNode(ISD::FSUB, DL, VT, N1, Add);
}
// fadd A, (fmul B, -2.0) --> fsub A, (fadd B, B)
if (isFMulNegTwo(N1)) {
SDValue B = N1.getOperand(0);
- SDValue Add = DAG.getNode(ISD::FADD, DL, VT, B, B);
- return DAG.getNode(ISD::FSUB, DL, VT, N0, Add);
+ SDValue Add = DAG.getNode(ISD::FADD, DL, VT, B, B);
+ return DAG.getNode(ISD::FSUB, DL, VT, N0, Add);
}
// No FP constant should be created after legalization as Instruction
@@ -13218,9 +13218,9 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
AllowNewConst) {
// fadd (fadd x, c1), c2 -> fadd x, c1 + c2
if (N1CFP && N0.getOpcode() == ISD::FADD &&
- DAG.isConstantFPBuildVectorOrConstantFP(N0.getOperand(1))) {
- SDValue NewC = DAG.getNode(ISD::FADD, DL, VT, N0.getOperand(1), N1);
- return DAG.getNode(ISD::FADD, DL, VT, N0.getOperand(0), NewC);
+ DAG.isConstantFPBuildVectorOrConstantFP(N0.getOperand(1))) {
+ SDValue NewC = DAG.getNode(ISD::FADD, DL, VT, N0.getOperand(1), N1);
+ return DAG.getNode(ISD::FADD, DL, VT, N0.getOperand(0), NewC);
}
// We can fold chains of FADD's of the same value into multiplications.
@@ -13228,14 +13228,14 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
// of rounding steps.
if (TLI.isOperationLegalOrCustom(ISD::FMUL, VT) && !N0CFP && !N1CFP) {
if (N0.getOpcode() == ISD::FMUL) {
- bool CFP00 = DAG.isConstantFPBuildVectorOrConstantFP(N0.getOperand(0));
- bool CFP01 = DAG.isConstantFPBuildVectorOrConstantFP(N0.getOperand(1));
+ bool CFP00 = DAG.isConstantFPBuildVectorOrConstantFP(N0.getOperand(0));
+ bool CFP01 = DAG.isConstantFPBuildVectorOrConstantFP(N0.getOperand(1));
// (fadd (fmul x, c), x) -> (fmul x, c+1)
if (CFP01 && !CFP00 && N0.getOperand(0) == N1) {
SDValue NewCFP = DAG.getNode(ISD::FADD, DL, VT, N0.getOperand(1),
- DAG.getConstantFP(1.0, DL, VT));
- return DAG.getNode(ISD::FMUL, DL, VT, N1, NewCFP);
+ DAG.getConstantFP(1.0, DL, VT));
+ return DAG.getNode(ISD::FMUL, DL, VT, N1, NewCFP);
}
// (fadd (fmul x, c), (fadd x, x)) -> (fmul x, c+2)
@@ -13243,20 +13243,20 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
N1.getOperand(0) == N1.getOperand(1) &&
N0.getOperand(0) == N1.getOperand(0)) {
SDValue NewCFP = DAG.getNode(ISD::FADD, DL, VT, N0.getOperand(1),
- DAG.getConstantFP(2.0, DL, VT));
- return DAG.getNode(ISD::FMUL, DL, VT, N0.getOperand(0), NewCFP);
+ DAG.getConstantFP(2.0, DL, VT));
+ return DAG.getNode(ISD::FMUL, DL, VT, N0.getOperand(0), NewCFP);
}
}
if (N1.getOpcode() == ISD::FMUL) {
- bool CFP10 = DAG.isConstantFPBuildVectorOrConstantFP(N1.getOperand(0));
- bool CFP11 = DAG.isConstantFPBuildVectorOrConstantFP(N1.getOperand(1));
+ bool CFP10 = DAG.isConstantFPBuildVectorOrConstantFP(N1.getOperand(0));
+ bool CFP11 = DAG.isConstantFPBuildVectorOrConstantFP(N1.getOperand(1));
// (fadd x, (fmul x, c)) -> (fmul x, c+1)
if (CFP11 && !CFP10 && N1.getOperand(0) == N0) {
SDValue NewCFP = DAG.getNode(ISD::FADD, DL, VT, N1.getOperand(1),
- DAG.getConstantFP(1.0, DL, VT));
- return DAG.getNode(ISD::FMUL, DL, VT, N0, NewCFP);
+ DAG.getConstantFP(1.0, DL, VT));
+ return DAG.getNode(ISD::FMUL, DL, VT, N0, NewCFP);
}
// (fadd (fadd x, x), (fmul x, c)) -> (fmul x, c+2)
@@ -13264,28 +13264,28 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
N0.getOperand(0) == N0.getOperand(1) &&
N1.getOperand(0) == N0.getOperand(0)) {
SDValue NewCFP = DAG.getNode(ISD::FADD, DL, VT, N1.getOperand(1),
- DAG.getConstantFP(2.0, DL, VT));
- return DAG.getNode(ISD::FMUL, DL, VT, N1.getOperand(0), NewCFP);
+ DAG.getConstantFP(2.0, DL, VT));
+ return DAG.getNode(ISD::FMUL, DL, VT, N1.getOperand(0), NewCFP);
}
}
if (N0.getOpcode() == ISD::FADD) {
- bool CFP00 = DAG.isConstantFPBuildVectorOrConstantFP(N0.getOperand(0));
+ bool CFP00 = DAG.isConstantFPBuildVectorOrConstantFP(N0.getOperand(0));
// (fadd (fadd x, x), x) -> (fmul x, 3.0)
if (!CFP00 && N0.getOperand(0) == N0.getOperand(1) &&
(N0.getOperand(0) == N1)) {
- return DAG.getNode(ISD::FMUL, DL, VT, N1,
- DAG.getConstantFP(3.0, DL, VT));
+ return DAG.getNode(ISD::FMUL, DL, VT, N1,
+ DAG.getConstantFP(3.0, DL, VT));
}
}
if (N1.getOpcode() == ISD::FADD) {
- bool CFP10 = DAG.isConstantFPBuildVectorOrConstantFP(N1.getOperand(0));
+ bool CFP10 = DAG.isConstantFPBuildVectorOrConstantFP(N1.getOperand(0));
// (fadd x, (fadd x, x)) -> (fmul x, 3.0)
if (!CFP10 && N1.getOperand(0) == N1.getOperand(1) &&
N1.getOperand(0) == N0) {
- return DAG.getNode(ISD::FMUL, DL, VT, N0,
- DAG.getConstantFP(3.0, DL, VT));
+ return DAG.getNode(ISD::FMUL, DL, VT, N0,
+ DAG.getConstantFP(3.0, DL, VT));
}
}
@@ -13295,7 +13295,7 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
N1.getOperand(0) == N1.getOperand(1) &&
N0.getOperand(0) == N1.getOperand(0)) {
return DAG.getNode(ISD::FMUL, DL, VT, N0.getOperand(0),
- DAG.getConstantFP(4.0, DL, VT));
+ DAG.getConstantFP(4.0, DL, VT));
}
}
} // enable-unsafe-fp-math
@@ -13308,33 +13308,33 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
return SDValue();
}
-SDValue DAGCombiner::visitSTRICT_FADD(SDNode *N) {
- SDValue Chain = N->getOperand(0);
- SDValue N0 = N->getOperand(1);
- SDValue N1 = N->getOperand(2);
- EVT VT = N->getValueType(0);
- EVT ChainVT = N->getValueType(1);
- SDLoc DL(N);
- SelectionDAG::FlagInserter FlagsInserter(DAG, N);
-
- // fold (strict_fadd A, (fneg B)) -> (strict_fsub A, B)
- if (!LegalOperations || TLI.isOperationLegalOrCustom(ISD::STRICT_FSUB, VT))
- if (SDValue NegN1 = TLI.getCheaperNegatedExpression(
- N1, DAG, LegalOperations, ForCodeSize)) {
- return DAG.getNode(ISD::STRICT_FSUB, DL, DAG.getVTList(VT, ChainVT),
- {Chain, N0, NegN1});
- }
-
- // fold (strict_fadd (fneg A), B) -> (strict_fsub B, A)
- if (!LegalOperations || TLI.isOperationLegalOrCustom(ISD::STRICT_FSUB, VT))
- if (SDValue NegN0 = TLI.getCheaperNegatedExpression(
- N0, DAG, LegalOperations, ForCodeSize)) {
- return DAG.getNode(ISD::STRICT_FSUB, DL, DAG.getVTList(VT, ChainVT),
- {Chain, N1, NegN0});
- }
- return SDValue();
-}
-
+SDValue DAGCombiner::visitSTRICT_FADD(SDNode *N) {
+ SDValue Chain = N->getOperand(0);
+ SDValue N0 = N->getOperand(1);
+ SDValue N1 = N->getOperand(2);
+ EVT VT = N->getValueType(0);
+ EVT ChainVT = N->getValueType(1);
+ SDLoc DL(N);
+ SelectionDAG::FlagInserter FlagsInserter(DAG, N);
+
+ // fold (strict_fadd A, (fneg B)) -> (strict_fsub A, B)
+ if (!LegalOperations || TLI.isOperationLegalOrCustom(ISD::STRICT_FSUB, VT))
+ if (SDValue NegN1 = TLI.getCheaperNegatedExpression(
+ N1, DAG, LegalOperations, ForCodeSize)) {
+ return DAG.getNode(ISD::STRICT_FSUB, DL, DAG.getVTList(VT, ChainVT),
+ {Chain, N0, NegN1});
+ }
+
+ // fold (strict_fadd (fneg A), B) -> (strict_fsub B, A)
+ if (!LegalOperations || TLI.isOperationLegalOrCustom(ISD::STRICT_FSUB, VT))
+ if (SDValue NegN0 = TLI.getCheaperNegatedExpression(
+ N0, DAG, LegalOperations, ForCodeSize)) {
+ return DAG.getNode(ISD::STRICT_FSUB, DL, DAG.getVTList(VT, ChainVT),
+ {Chain, N1, NegN0});
+ }
+ return SDValue();
+}
+
SDValue DAGCombiner::visitFSUB(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
@@ -13344,7 +13344,7 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
SDLoc DL(N);
const TargetOptions &Options = DAG.getTarget().Options;
const SDNodeFlags Flags = N->getFlags();
- SelectionDAG::FlagInserter FlagsInserter(DAG, N);
+ SelectionDAG::FlagInserter FlagsInserter(DAG, N);
if (SDValue R = DAG.simplifyFPBinop(N->getOpcode(), N0, N1, Flags))
return R;
@@ -13356,7 +13356,7 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
// fold (fsub c1, c2) -> c1-c2
if (N0CFP && N1CFP)
- return DAG.getNode(ISD::FSUB, DL, VT, N0, N1);
+ return DAG.getNode(ISD::FSUB, DL, VT, N0, N1);
if (SDValue NewSel = foldBinOpIntoSelect(N))
return NewSel;
@@ -13379,18 +13379,18 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
if (N0CFP && N0CFP->isZero()) {
if (N0CFP->isNegative() ||
(Options.NoSignedZerosFPMath || Flags.hasNoSignedZeros())) {
- // We cannot replace an FSUB(+-0.0,X) with FNEG(X) when denormals are
- // flushed to zero, unless all users treat denorms as zero (DAZ).
- // FIXME: This transform will change the sign of a NaN and the behavior
- // of a signaling NaN. It is only valid when a NoNaN flag is present.
- DenormalMode DenormMode = DAG.getDenormalMode(VT);
- if (DenormMode == DenormalMode::getIEEE()) {
- if (SDValue NegN1 =
- TLI.getNegatedExpression(N1, DAG, LegalOperations, ForCodeSize))
- return NegN1;
- if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT))
- return DAG.getNode(ISD::FNEG, DL, VT, N1);
- }
+ // We cannot replace an FSUB(+-0.0,X) with FNEG(X) when denormals are
+ // flushed to zero, unless all users treat denorms as zero (DAZ).
+ // FIXME: This transform will change the sign of a NaN and the behavior
+ // of a signaling NaN. It is only valid when a NoNaN flag is present.
+ DenormalMode DenormMode = DAG.getDenormalMode(VT);
+ if (DenormMode == DenormalMode::getIEEE()) {
+ if (SDValue NegN1 =
+ TLI.getNegatedExpression(N1, DAG, LegalOperations, ForCodeSize))
+ return NegN1;
+ if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT))
+ return DAG.getNode(ISD::FNEG, DL, VT, N1);
+ }
}
}
@@ -13399,16 +13399,16 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
N1.getOpcode() == ISD::FADD) {
// X - (X + Y) -> -Y
if (N0 == N1->getOperand(0))
- return DAG.getNode(ISD::FNEG, DL, VT, N1->getOperand(1));
+ return DAG.getNode(ISD::FNEG, DL, VT, N1->getOperand(1));
// X - (Y + X) -> -Y
if (N0 == N1->getOperand(1))
- return DAG.getNode(ISD::FNEG, DL, VT, N1->getOperand(0));
+ return DAG.getNode(ISD::FNEG, DL, VT, N1->getOperand(0));
}
// fold (fsub A, (fneg B)) -> (fadd A, B)
if (SDValue NegN1 =
TLI.getNegatedExpression(N1, DAG, LegalOperations, ForCodeSize))
- return DAG.getNode(ISD::FADD, DL, VT, N0, NegN1);
+ return DAG.getNode(ISD::FADD, DL, VT, N0, NegN1);
// FSUB -> FMA combines:
if (SDValue Fused = visitFSUBForFMACombine(N)) {
@@ -13428,7 +13428,7 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) {
SDLoc DL(N);
const TargetOptions &Options = DAG.getTarget().Options;
const SDNodeFlags Flags = N->getFlags();
- SelectionDAG::FlagInserter FlagsInserter(DAG, N);
+ SelectionDAG::FlagInserter FlagsInserter(DAG, N);
if (SDValue R = DAG.simplifyFPBinop(N->getOpcode(), N0, N1, Flags))
return R;
@@ -13442,28 +13442,28 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) {
// fold (fmul c1, c2) -> c1*c2
if (N0CFP && N1CFP)
- return DAG.getNode(ISD::FMUL, DL, VT, N0, N1);
+ return DAG.getNode(ISD::FMUL, DL, VT, N0, N1);
// canonicalize constant to RHS
- if (DAG.isConstantFPBuildVectorOrConstantFP(N0) &&
- !DAG.isConstantFPBuildVectorOrConstantFP(N1))
- return DAG.getNode(ISD::FMUL, DL, VT, N1, N0);
+ if (DAG.isConstantFPBuildVectorOrConstantFP(N0) &&
+ !DAG.isConstantFPBuildVectorOrConstantFP(N1))
+ return DAG.getNode(ISD::FMUL, DL, VT, N1, N0);
if (SDValue NewSel = foldBinOpIntoSelect(N))
return NewSel;
if (Options.UnsafeFPMath || Flags.hasAllowReassociation()) {
// fmul (fmul X, C1), C2 -> fmul X, C1 * C2
- if (DAG.isConstantFPBuildVectorOrConstantFP(N1) &&
+ if (DAG.isConstantFPBuildVectorOrConstantFP(N1) &&
N0.getOpcode() == ISD::FMUL) {
SDValue N00 = N0.getOperand(0);
SDValue N01 = N0.getOperand(1);
// Avoid an infinite loop by making sure that N00 is not a constant
// (the inner multiply has not been constant folded yet).
- if (DAG.isConstantFPBuildVectorOrConstantFP(N01) &&
- !DAG.isConstantFPBuildVectorOrConstantFP(N00)) {
- SDValue MulConsts = DAG.getNode(ISD::FMUL, DL, VT, N01, N1);
- return DAG.getNode(ISD::FMUL, DL, VT, N00, MulConsts);
+ if (DAG.isConstantFPBuildVectorOrConstantFP(N01) &&
+ !DAG.isConstantFPBuildVectorOrConstantFP(N00)) {
+ SDValue MulConsts = DAG.getNode(ISD::FMUL, DL, VT, N01, N1);
+ return DAG.getNode(ISD::FMUL, DL, VT, N00, MulConsts);
}
}
@@ -13472,14 +13472,14 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) {
if (N0.getOpcode() == ISD::FADD && N0.hasOneUse() &&
N0.getOperand(0) == N0.getOperand(1)) {
const SDValue Two = DAG.getConstantFP(2.0, DL, VT);
- SDValue MulConsts = DAG.getNode(ISD::FMUL, DL, VT, Two, N1);
- return DAG.getNode(ISD::FMUL, DL, VT, N0.getOperand(0), MulConsts);
+ SDValue MulConsts = DAG.getNode(ISD::FMUL, DL, VT, Two, N1);
+ return DAG.getNode(ISD::FMUL, DL, VT, N0.getOperand(0), MulConsts);
}
}
// fold (fmul X, 2.0) -> (fadd X, X)
if (N1CFP && N1CFP->isExactlyValue(+2.0))
- return DAG.getNode(ISD::FADD, DL, VT, N0, N0);
+ return DAG.getNode(ISD::FADD, DL, VT, N0, N0);
// fold (fmul X, -1.0) -> (fneg X)
if (N1CFP && N1CFP->isExactlyValue(-1.0))
@@ -13498,7 +13498,7 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) {
if (NegN0 && NegN1 &&
(CostN0 == TargetLowering::NegatibleCost::Cheaper ||
CostN1 == TargetLowering::NegatibleCost::Cheaper))
- return DAG.getNode(ISD::FMUL, DL, VT, NegN0, NegN1);
+ return DAG.getNode(ISD::FMUL, DL, VT, NegN0, NegN1);
// fold (fmul X, (select (fcmp X > 0.0), -1.0, 1.0)) -> (fneg (fabs X))
// fold (fmul X, (select (fcmp X > 0.0), 1.0, -1.0)) -> (fabs X)
@@ -13565,11 +13565,11 @@ SDValue DAGCombiner::visitFMA(SDNode *N) {
SDLoc DL(N);
const TargetOptions &Options = DAG.getTarget().Options;
// FMA nodes have flags that propagate to the created nodes.
- SelectionDAG::FlagInserter FlagsInserter(DAG, N);
+ SelectionDAG::FlagInserter FlagsInserter(DAG, N);
+
+ bool UnsafeFPMath =
+ Options.UnsafeFPMath || N->getFlags().hasAllowReassociation();
- bool UnsafeFPMath =
- Options.UnsafeFPMath || N->getFlags().hasAllowReassociation();
-
// Constant fold FMA.
if (isa<ConstantFPSDNode>(N0) &&
isa<ConstantFPSDNode>(N1) &&
@@ -13589,7 +13589,7 @@ SDValue DAGCombiner::visitFMA(SDNode *N) {
if (NegN0 && NegN1 &&
(CostN0 == TargetLowering::NegatibleCost::Cheaper ||
CostN1 == TargetLowering::NegatibleCost::Cheaper))
- return DAG.getNode(ISD::FMA, DL, VT, NegN0, NegN1, N2);
+ return DAG.getNode(ISD::FMA, DL, VT, NegN0, NegN1, N2);
if (UnsafeFPMath) {
if (N0CFP && N0CFP->isZero())
@@ -13597,32 +13597,32 @@ SDValue DAGCombiner::visitFMA(SDNode *N) {
if (N1CFP && N1CFP->isZero())
return N2;
}
-
+
if (N0CFP && N0CFP->isExactlyValue(1.0))
return DAG.getNode(ISD::FADD, SDLoc(N), VT, N1, N2);
if (N1CFP && N1CFP->isExactlyValue(1.0))
return DAG.getNode(ISD::FADD, SDLoc(N), VT, N0, N2);
// Canonicalize (fma c, x, y) -> (fma x, c, y)
- if (DAG.isConstantFPBuildVectorOrConstantFP(N0) &&
- !DAG.isConstantFPBuildVectorOrConstantFP(N1))
+ if (DAG.isConstantFPBuildVectorOrConstantFP(N0) &&
+ !DAG.isConstantFPBuildVectorOrConstantFP(N1))
return DAG.getNode(ISD::FMA, SDLoc(N), VT, N1, N0, N2);
if (UnsafeFPMath) {
// (fma x, c1, (fmul x, c2)) -> (fmul x, c1+c2)
if (N2.getOpcode() == ISD::FMUL && N0 == N2.getOperand(0) &&
- DAG.isConstantFPBuildVectorOrConstantFP(N1) &&
- DAG.isConstantFPBuildVectorOrConstantFP(N2.getOperand(1))) {
+ DAG.isConstantFPBuildVectorOrConstantFP(N1) &&
+ DAG.isConstantFPBuildVectorOrConstantFP(N2.getOperand(1))) {
return DAG.getNode(ISD::FMUL, DL, VT, N0,
- DAG.getNode(ISD::FADD, DL, VT, N1, N2.getOperand(1)));
+ DAG.getNode(ISD::FADD, DL, VT, N1, N2.getOperand(1)));
}
// (fma (fmul x, c1), c2, y) -> (fma x, c1*c2, y)
if (N0.getOpcode() == ISD::FMUL &&
- DAG.isConstantFPBuildVectorOrConstantFP(N1) &&
- DAG.isConstantFPBuildVectorOrConstantFP(N0.getOperand(1))) {
- return DAG.getNode(ISD::FMA, DL, VT, N0.getOperand(0),
- DAG.getNode(ISD::FMUL, DL, VT, N1, N0.getOperand(1)),
+ DAG.isConstantFPBuildVectorOrConstantFP(N1) &&
+ DAG.isConstantFPBuildVectorOrConstantFP(N0.getOperand(1))) {
+ return DAG.getNode(ISD::FMA, DL, VT, N0.getOperand(0),
+ DAG.getNode(ISD::FMUL, DL, VT, N1, N0.getOperand(1)),
N2);
}
}
@@ -13645,23 +13645,23 @@ SDValue DAGCombiner::visitFMA(SDNode *N) {
(N1.hasOneUse() && !TLI.isFPImmLegal(N1CFP->getValueAPF(), VT,
ForCodeSize)))) {
return DAG.getNode(ISD::FMA, DL, VT, N0.getOperand(0),
- DAG.getNode(ISD::FNEG, DL, VT, N1), N2);
+ DAG.getNode(ISD::FNEG, DL, VT, N1), N2);
}
}
if (UnsafeFPMath) {
// (fma x, c, x) -> (fmul x, (c+1))
if (N1CFP && N0 == N2) {
- return DAG.getNode(
- ISD::FMUL, DL, VT, N0,
- DAG.getNode(ISD::FADD, DL, VT, N1, DAG.getConstantFP(1.0, DL, VT)));
+ return DAG.getNode(
+ ISD::FMUL, DL, VT, N0,
+ DAG.getNode(ISD::FADD, DL, VT, N1, DAG.getConstantFP(1.0, DL, VT)));
}
// (fma x, c, (fneg x)) -> (fmul x, (c-1))
if (N1CFP && N2.getOpcode() == ISD::FNEG && N2.getOperand(0) == N0) {
- return DAG.getNode(
- ISD::FMUL, DL, VT, N0,
- DAG.getNode(ISD::FADD, DL, VT, N1, DAG.getConstantFP(-1.0, DL, VT)));
+ return DAG.getNode(
+ ISD::FMUL, DL, VT, N0,
+ DAG.getNode(ISD::FADD, DL, VT, N1, DAG.getConstantFP(-1.0, DL, VT)));
}
}
@@ -13670,7 +13670,7 @@ SDValue DAGCombiner::visitFMA(SDNode *N) {
if (!TLI.isFNegFree(VT))
if (SDValue Neg = TLI.getCheaperNegatedExpression(
SDValue(N, 0), DAG, LegalOperations, ForCodeSize))
- return DAG.getNode(ISD::FNEG, DL, VT, Neg);
+ return DAG.getNode(ISD::FNEG, DL, VT, Neg);
return SDValue();
}
@@ -13691,7 +13691,7 @@ SDValue DAGCombiner::combineRepeatedFPDivisors(SDNode *N) {
return SDValue();
// Skip if current node is a reciprocal/fneg-reciprocal.
- SDValue N0 = N->getOperand(0), N1 = N->getOperand(1);
+ SDValue N0 = N->getOperand(0), N1 = N->getOperand(1);
ConstantFPSDNode *N0CFP = isConstOrConstSplatFP(N0, /* AllowUndefs */ true);
if (N0CFP && (N0CFP->isExactlyValue(1.0) || N0CFP->isExactlyValue(-1.0)))
return SDValue();
@@ -13715,13 +13715,13 @@ SDValue DAGCombiner::combineRepeatedFPDivisors(SDNode *N) {
SetVector<SDNode *> Users;
for (auto *U : N1->uses()) {
if (U->getOpcode() == ISD::FDIV && U->getOperand(1) == N1) {
- // Skip X/sqrt(X) that has not been simplified to sqrt(X) yet.
- if (U->getOperand(1).getOpcode() == ISD::FSQRT &&
- U->getOperand(0) == U->getOperand(1).getOperand(0) &&
- U->getFlags().hasAllowReassociation() &&
- U->getFlags().hasNoSignedZeros())
- continue;
-
+ // Skip X/sqrt(X) that has not been simplified to sqrt(X) yet.
+ if (U->getOperand(1).getOpcode() == ISD::FSQRT &&
+ U->getOperand(0) == U->getOperand(1).getOperand(0) &&
+ U->getFlags().hasAllowReassociation() &&
+ U->getFlags().hasNoSignedZeros())
+ continue;
+
// This division is eligible for optimization only if global unsafe math
// is enabled or if this division allows reciprocal formation.
if (UnsafeMath || U->getFlags().hasAllowReciprocal())
@@ -13763,7 +13763,7 @@ SDValue DAGCombiner::visitFDIV(SDNode *N) {
SDLoc DL(N);
const TargetOptions &Options = DAG.getTarget().Options;
SDNodeFlags Flags = N->getFlags();
- SelectionDAG::FlagInserter FlagsInserter(DAG, N);
+ SelectionDAG::FlagInserter FlagsInserter(DAG, N);
if (SDValue R = DAG.simplifyFPBinop(N->getOpcode(), N0, N1, Flags))
return R;
@@ -13775,7 +13775,7 @@ SDValue DAGCombiner::visitFDIV(SDNode *N) {
// fold (fdiv c1, c2) -> c1/c2
if (N0CFP && N1CFP)
- return DAG.getNode(ISD::FDIV, SDLoc(N), VT, N0, N1);
+ return DAG.getNode(ISD::FDIV, SDLoc(N), VT, N0, N1);
if (SDValue NewSel = foldBinOpIntoSelect(N))
return NewSel;
@@ -13800,29 +13800,29 @@ SDValue DAGCombiner::visitFDIV(SDNode *N) {
TLI.isOperationLegal(ISD::ConstantFP, VT) ||
TLI.isFPImmLegal(Recip, VT, ForCodeSize)))
return DAG.getNode(ISD::FMUL, DL, VT, N0,
- DAG.getConstantFP(Recip, DL, VT));
+ DAG.getConstantFP(Recip, DL, VT));
}
// If this FDIV is part of a reciprocal square root, it may be folded
// into a target-specific square root estimate instruction.
if (N1.getOpcode() == ISD::FSQRT) {
if (SDValue RV = buildRsqrtEstimate(N1.getOperand(0), Flags))
- return DAG.getNode(ISD::FMUL, DL, VT, N0, RV);
+ return DAG.getNode(ISD::FMUL, DL, VT, N0, RV);
} else if (N1.getOpcode() == ISD::FP_EXTEND &&
N1.getOperand(0).getOpcode() == ISD::FSQRT) {
- if (SDValue RV =
- buildRsqrtEstimate(N1.getOperand(0).getOperand(0), Flags)) {
+ if (SDValue RV =
+ buildRsqrtEstimate(N1.getOperand(0).getOperand(0), Flags)) {
RV = DAG.getNode(ISD::FP_EXTEND, SDLoc(N1), VT, RV);
AddToWorklist(RV.getNode());
- return DAG.getNode(ISD::FMUL, DL, VT, N0, RV);
+ return DAG.getNode(ISD::FMUL, DL, VT, N0, RV);
}
} else if (N1.getOpcode() == ISD::FP_ROUND &&
N1.getOperand(0).getOpcode() == ISD::FSQRT) {
- if (SDValue RV =
- buildRsqrtEstimate(N1.getOperand(0).getOperand(0), Flags)) {
+ if (SDValue RV =
+ buildRsqrtEstimate(N1.getOperand(0).getOperand(0), Flags)) {
RV = DAG.getNode(ISD::FP_ROUND, SDLoc(N1), VT, RV, N1.getOperand(1));
AddToWorklist(RV.getNode());
- return DAG.getNode(ISD::FMUL, DL, VT, N0, RV);
+ return DAG.getNode(ISD::FMUL, DL, VT, N0, RV);
}
} else if (N1.getOpcode() == ISD::FMUL) {
// Look through an FMUL. Even though this won't remove the FDIV directly,
@@ -13837,34 +13837,34 @@ SDValue DAGCombiner::visitFDIV(SDNode *N) {
}
if (Sqrt.getNode()) {
// If the other multiply operand is known positive, pull it into the
- // sqrt. That will eliminate the division if we convert to an estimate.
+ // sqrt. That will eliminate the division if we convert to an estimate.
if (Flags.hasAllowReassociation() && N1.hasOneUse() &&
- N1->getFlags().hasAllowReassociation() && Sqrt.hasOneUse()) {
- SDValue A;
- if (Y.getOpcode() == ISD::FABS && Y.hasOneUse())
- A = Y.getOperand(0);
- else if (Y == Sqrt.getOperand(0))
- A = Y;
- if (A) {
- // X / (fabs(A) * sqrt(Z)) --> X / sqrt(A*A*Z) --> X * rsqrt(A*A*Z)
- // X / (A * sqrt(A)) --> X / sqrt(A*A*A) --> X * rsqrt(A*A*A)
- SDValue AA = DAG.getNode(ISD::FMUL, DL, VT, A, A);
- SDValue AAZ =
- DAG.getNode(ISD::FMUL, DL, VT, AA, Sqrt.getOperand(0));
- if (SDValue Rsqrt = buildRsqrtEstimate(AAZ, Flags))
- return DAG.getNode(ISD::FMUL, DL, VT, N0, Rsqrt);
-
- // Estimate creation failed. Clean up speculatively created nodes.
- recursivelyDeleteUnusedNodes(AAZ.getNode());
- }
+ N1->getFlags().hasAllowReassociation() && Sqrt.hasOneUse()) {
+ SDValue A;
+ if (Y.getOpcode() == ISD::FABS && Y.hasOneUse())
+ A = Y.getOperand(0);
+ else if (Y == Sqrt.getOperand(0))
+ A = Y;
+ if (A) {
+ // X / (fabs(A) * sqrt(Z)) --> X / sqrt(A*A*Z) --> X * rsqrt(A*A*Z)
+ // X / (A * sqrt(A)) --> X / sqrt(A*A*A) --> X * rsqrt(A*A*A)
+ SDValue AA = DAG.getNode(ISD::FMUL, DL, VT, A, A);
+ SDValue AAZ =
+ DAG.getNode(ISD::FMUL, DL, VT, AA, Sqrt.getOperand(0));
+ if (SDValue Rsqrt = buildRsqrtEstimate(AAZ, Flags))
+ return DAG.getNode(ISD::FMUL, DL, VT, N0, Rsqrt);
+
+ // Estimate creation failed. Clean up speculatively created nodes.
+ recursivelyDeleteUnusedNodes(AAZ.getNode());
+ }
}
// We found a FSQRT, so try to make this fold:
// X / (Y * sqrt(Z)) -> X * (rsqrt(Z) / Y)
if (SDValue Rsqrt = buildRsqrtEstimate(Sqrt.getOperand(0), Flags)) {
- SDValue Div = DAG.getNode(ISD::FDIV, SDLoc(N1), VT, Rsqrt, Y);
+ SDValue Div = DAG.getNode(ISD::FDIV, SDLoc(N1), VT, Rsqrt, Y);
AddToWorklist(Div.getNode());
- return DAG.getNode(ISD::FMUL, DL, VT, N0, Div);
+ return DAG.getNode(ISD::FMUL, DL, VT, N0, Div);
}
}
}
@@ -13875,12 +13875,12 @@ SDValue DAGCombiner::visitFDIV(SDNode *N) {
return RV;
}
- // Fold X/Sqrt(X) -> Sqrt(X)
- if ((Options.NoSignedZerosFPMath || Flags.hasNoSignedZeros()) &&
- (Options.UnsafeFPMath || Flags.hasAllowReassociation()))
- if (N1.getOpcode() == ISD::FSQRT && N0 == N1.getOperand(0))
- return N1;
-
+ // Fold X/Sqrt(X) -> Sqrt(X)
+ if ((Options.NoSignedZerosFPMath || Flags.hasNoSignedZeros()) &&
+ (Options.UnsafeFPMath || Flags.hasAllowReassociation()))
+ if (N1.getOpcode() == ISD::FSQRT && N0 == N1.getOperand(0))
+ return N1;
+
// (fdiv (fneg X), (fneg Y)) -> (fdiv X, Y)
TargetLowering::NegatibleCost CostN0 =
TargetLowering::NegatibleCost::Expensive;
@@ -13893,7 +13893,7 @@ SDValue DAGCombiner::visitFDIV(SDNode *N) {
if (NegN0 && NegN1 &&
(CostN0 == TargetLowering::NegatibleCost::Cheaper ||
CostN1 == TargetLowering::NegatibleCost::Cheaper))
- return DAG.getNode(ISD::FDIV, SDLoc(N), VT, NegN0, NegN1);
+ return DAG.getNode(ISD::FDIV, SDLoc(N), VT, NegN0, NegN1);
return SDValue();
}
@@ -13905,14 +13905,14 @@ SDValue DAGCombiner::visitFREM(SDNode *N) {
ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1);
EVT VT = N->getValueType(0);
SDNodeFlags Flags = N->getFlags();
- SelectionDAG::FlagInserter FlagsInserter(DAG, N);
+ SelectionDAG::FlagInserter FlagsInserter(DAG, N);
if (SDValue R = DAG.simplifyFPBinop(N->getOpcode(), N0, N1, Flags))
return R;
// fold (frem c1, c2) -> fmod(c1,c2)
if (N0CFP && N1CFP)
- return DAG.getNode(ISD::FREM, SDLoc(N), VT, N0, N1);
+ return DAG.getNode(ISD::FREM, SDLoc(N), VT, N0, N1);
if (SDValue NewSel = foldBinOpIntoSelect(N))
return NewSel;
@@ -13926,7 +13926,7 @@ SDValue DAGCombiner::visitFSQRT(SDNode *N) {
// Require 'ninf' flag since sqrt(+Inf) = +Inf, but the estimation goes as:
// sqrt(+Inf) == rsqrt(+Inf) * +Inf = 0 * +Inf = NaN
- if (!Flags.hasApproximateFuncs() ||
+ if (!Flags.hasApproximateFuncs() ||
(!Options.NoInfsFPMath && !Flags.hasNoInfs()))
return SDValue();
@@ -13935,10 +13935,10 @@ SDValue DAGCombiner::visitFSQRT(SDNode *N) {
return SDValue();
// FSQRT nodes have flags that propagate to the created nodes.
- // TODO: If this is N0/sqrt(N0), and we reach this node before trying to
- // transform the fdiv, we may produce a sub-optimal estimate sequence
- // because the reciprocal calculation may not have to filter out a
- // 0.0 input.
+ // TODO: If this is N0/sqrt(N0), and we reach this node before trying to
+ // transform the fdiv, we may produce a sub-optimal estimate sequence
+ // because the reciprocal calculation may not have to filter out a
+ // 0.0 input.
return buildSqrtEstimate(N0, Flags);
}
@@ -13962,8 +13962,8 @@ static inline bool CanCombineFCOPYSIGN_EXTEND_ROUND(SDNode *N) {
SDValue DAGCombiner::visitFCOPYSIGN(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
- bool N0CFP = DAG.isConstantFPBuildVectorOrConstantFP(N0);
- bool N1CFP = DAG.isConstantFPBuildVectorOrConstantFP(N1);
+ bool N0CFP = DAG.isConstantFPBuildVectorOrConstantFP(N0);
+ bool N1CFP = DAG.isConstantFPBuildVectorOrConstantFP(N1);
EVT VT = N->getValueType(0);
if (N0CFP && N1CFP) // Constant fold
@@ -14010,7 +14010,7 @@ SDValue DAGCombiner::visitFPOW(SDNode *N) {
ConstantFPSDNode *ExponentC = isConstOrConstSplatFP(N->getOperand(1));
if (!ExponentC)
return SDValue();
- SelectionDAG::FlagInserter FlagsInserter(DAG, N);
+ SelectionDAG::FlagInserter FlagsInserter(DAG, N);
// Try to convert x ** (1/3) into cube root.
// TODO: Handle the various flavors of long double.
@@ -14037,7 +14037,7 @@ SDValue DAGCombiner::visitFPOW(SDNode *N) {
DAG.getTargetLoweringInfo().isOperationExpand(ISD::FCBRT, VT)))
return SDValue();
- return DAG.getNode(ISD::FCBRT, SDLoc(N), VT, N->getOperand(0));
+ return DAG.getNode(ISD::FCBRT, SDLoc(N), VT, N->getOperand(0));
}
// Try to convert x ** (1/4) and x ** (3/4) into square roots.
@@ -14072,12 +14072,12 @@ SDValue DAGCombiner::visitFPOW(SDNode *N) {
// pow(X, 0.25) --> sqrt(sqrt(X))
SDLoc DL(N);
- SDValue Sqrt = DAG.getNode(ISD::FSQRT, DL, VT, N->getOperand(0));
- SDValue SqrtSqrt = DAG.getNode(ISD::FSQRT, DL, VT, Sqrt);
+ SDValue Sqrt = DAG.getNode(ISD::FSQRT, DL, VT, N->getOperand(0));
+ SDValue SqrtSqrt = DAG.getNode(ISD::FSQRT, DL, VT, Sqrt);
if (ExponentIs025)
return SqrtSqrt;
// pow(X, 0.75) --> sqrt(X) * sqrt(sqrt(X))
- return DAG.getNode(ISD::FMUL, DL, VT, Sqrt, SqrtSqrt);
+ return DAG.getNode(ISD::FMUL, DL, VT, Sqrt, SqrtSqrt);
}
return SDValue();
@@ -14260,7 +14260,7 @@ SDValue DAGCombiner::visitFP_TO_SINT(SDNode *N) {
return DAG.getUNDEF(VT);
// fold (fp_to_sint c1fp) -> c1
- if (DAG.isConstantFPBuildVectorOrConstantFP(N0))
+ if (DAG.isConstantFPBuildVectorOrConstantFP(N0))
return DAG.getNode(ISD::FP_TO_SINT, SDLoc(N), VT, N0);
return FoldIntToFPToInt(N, DAG);
@@ -14275,7 +14275,7 @@ SDValue DAGCombiner::visitFP_TO_UINT(SDNode *N) {
return DAG.getUNDEF(VT);
// fold (fp_to_uint c1fp) -> c1
- if (DAG.isConstantFPBuildVectorOrConstantFP(N0))
+ if (DAG.isConstantFPBuildVectorOrConstantFP(N0))
return DAG.getNode(ISD::FP_TO_UINT, SDLoc(N), VT, N0);
return FoldIntToFPToInt(N, DAG);
@@ -14347,7 +14347,7 @@ SDValue DAGCombiner::visitFP_EXTEND(SDNode *N) {
return SDValue();
// fold (fp_extend c1fp) -> c1fp
- if (DAG.isConstantFPBuildVectorOrConstantFP(N0))
+ if (DAG.isConstantFPBuildVectorOrConstantFP(N0))
return DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT, N0);
// fold (fp_extend (fp16_to_fp op)) -> (fp16_to_fp op)
@@ -14395,7 +14395,7 @@ SDValue DAGCombiner::visitFCEIL(SDNode *N) {
EVT VT = N->getValueType(0);
// fold (fceil c1) -> fceil(c1)
- if (DAG.isConstantFPBuildVectorOrConstantFP(N0))
+ if (DAG.isConstantFPBuildVectorOrConstantFP(N0))
return DAG.getNode(ISD::FCEIL, SDLoc(N), VT, N0);
return SDValue();
@@ -14406,7 +14406,7 @@ SDValue DAGCombiner::visitFTRUNC(SDNode *N) {
EVT VT = N->getValueType(0);
// fold (ftrunc c1) -> ftrunc(c1)
- if (DAG.isConstantFPBuildVectorOrConstantFP(N0))
+ if (DAG.isConstantFPBuildVectorOrConstantFP(N0))
return DAG.getNode(ISD::FTRUNC, SDLoc(N), VT, N0);
// fold ftrunc (known rounded int x) -> x
@@ -14430,7 +14430,7 @@ SDValue DAGCombiner::visitFFLOOR(SDNode *N) {
EVT VT = N->getValueType(0);
// fold (ffloor c1) -> ffloor(c1)
- if (DAG.isConstantFPBuildVectorOrConstantFP(N0))
+ if (DAG.isConstantFPBuildVectorOrConstantFP(N0))
return DAG.getNode(ISD::FFLOOR, SDLoc(N), VT, N0);
return SDValue();
@@ -14439,10 +14439,10 @@ SDValue DAGCombiner::visitFFLOOR(SDNode *N) {
SDValue DAGCombiner::visitFNEG(SDNode *N) {
SDValue N0 = N->getOperand(0);
EVT VT = N->getValueType(0);
- SelectionDAG::FlagInserter FlagsInserter(DAG, N);
+ SelectionDAG::FlagInserter FlagsInserter(DAG, N);
// Constant fold FNEG.
- if (DAG.isConstantFPBuildVectorOrConstantFP(N0))
+ if (DAG.isConstantFPBuildVectorOrConstantFP(N0))
return DAG.getNode(ISD::FNEG, SDLoc(N), VT, N0);
if (SDValue NegN0 =
@@ -14457,11 +14457,11 @@ SDValue DAGCombiner::visitFNEG(SDNode *N) {
(DAG.getTarget().Options.NoSignedZerosFPMath ||
N->getFlags().hasNoSignedZeros()) && N0.hasOneUse()) {
return DAG.getNode(ISD::FSUB, SDLoc(N), VT, N0.getOperand(1),
- N0.getOperand(0));
+ N0.getOperand(0));
}
- if (SDValue Cast = foldSignChangeInBitcast(N))
- return Cast;
+ if (SDValue Cast = foldSignChangeInBitcast(N))
+ return Cast;
return SDValue();
}
@@ -14473,11 +14473,11 @@ static SDValue visitFMinMax(SelectionDAG &DAG, SDNode *N,
EVT VT = N->getValueType(0);
const ConstantFPSDNode *N0CFP = isConstOrConstSplatFP(N0);
const ConstantFPSDNode *N1CFP = isConstOrConstSplatFP(N1);
- const SDNodeFlags Flags = N->getFlags();
- unsigned Opc = N->getOpcode();
- bool PropagatesNaN = Opc == ISD::FMINIMUM || Opc == ISD::FMAXIMUM;
- bool IsMin = Opc == ISD::FMINNUM || Opc == ISD::FMINIMUM;
- SelectionDAG::FlagInserter FlagsInserter(DAG, N);
+ const SDNodeFlags Flags = N->getFlags();
+ unsigned Opc = N->getOpcode();
+ bool PropagatesNaN = Opc == ISD::FMINIMUM || Opc == ISD::FMAXIMUM;
+ bool IsMin = Opc == ISD::FMINNUM || Opc == ISD::FMINIMUM;
+ SelectionDAG::FlagInserter FlagsInserter(DAG, N);
if (N0CFP && N1CFP) {
const APFloat &C0 = N0CFP->getValueAPF();
@@ -14486,39 +14486,39 @@ static SDValue visitFMinMax(SelectionDAG &DAG, SDNode *N,
}
// Canonicalize to constant on RHS.
- if (DAG.isConstantFPBuildVectorOrConstantFP(N0) &&
- !DAG.isConstantFPBuildVectorOrConstantFP(N1))
+ if (DAG.isConstantFPBuildVectorOrConstantFP(N0) &&
+ !DAG.isConstantFPBuildVectorOrConstantFP(N1))
return DAG.getNode(N->getOpcode(), SDLoc(N), VT, N1, N0);
- if (N1CFP) {
- const APFloat &AF = N1CFP->getValueAPF();
-
- // minnum(X, nan) -> X
- // maxnum(X, nan) -> X
- // minimum(X, nan) -> nan
- // maximum(X, nan) -> nan
- if (AF.isNaN())
- return PropagatesNaN ? N->getOperand(1) : N->getOperand(0);
-
- // In the following folds, inf can be replaced with the largest finite
- // float, if the ninf flag is set.
- if (AF.isInfinity() || (Flags.hasNoInfs() && AF.isLargest())) {
- // minnum(X, -inf) -> -inf
- // maxnum(X, +inf) -> +inf
- // minimum(X, -inf) -> -inf if nnan
- // maximum(X, +inf) -> +inf if nnan
- if (IsMin == AF.isNegative() && (!PropagatesNaN || Flags.hasNoNaNs()))
- return N->getOperand(1);
-
- // minnum(X, +inf) -> X if nnan
- // maxnum(X, -inf) -> X if nnan
- // minimum(X, +inf) -> X
- // maximum(X, -inf) -> X
- if (IsMin != AF.isNegative() && (PropagatesNaN || Flags.hasNoNaNs()))
- return N->getOperand(0);
- }
- }
-
+ if (N1CFP) {
+ const APFloat &AF = N1CFP->getValueAPF();
+
+ // minnum(X, nan) -> X
+ // maxnum(X, nan) -> X
+ // minimum(X, nan) -> nan
+ // maximum(X, nan) -> nan
+ if (AF.isNaN())
+ return PropagatesNaN ? N->getOperand(1) : N->getOperand(0);
+
+ // In the following folds, inf can be replaced with the largest finite
+ // float, if the ninf flag is set.
+ if (AF.isInfinity() || (Flags.hasNoInfs() && AF.isLargest())) {
+ // minnum(X, -inf) -> -inf
+ // maxnum(X, +inf) -> +inf
+ // minimum(X, -inf) -> -inf if nnan
+ // maximum(X, +inf) -> +inf if nnan
+ if (IsMin == AF.isNegative() && (!PropagatesNaN || Flags.hasNoNaNs()))
+ return N->getOperand(1);
+
+ // minnum(X, +inf) -> X if nnan
+ // maxnum(X, -inf) -> X if nnan
+ // minimum(X, +inf) -> X
+ // maximum(X, -inf) -> X
+ if (IsMin != AF.isNegative() && (PropagatesNaN || Flags.hasNoNaNs()))
+ return N->getOperand(0);
+ }
+ }
+
return SDValue();
}
@@ -14543,7 +14543,7 @@ SDValue DAGCombiner::visitFABS(SDNode *N) {
EVT VT = N->getValueType(0);
// fold (fabs c1) -> fabs(c1)
- if (DAG.isConstantFPBuildVectorOrConstantFP(N0))
+ if (DAG.isConstantFPBuildVectorOrConstantFP(N0))
return DAG.getNode(ISD::FABS, SDLoc(N), VT, N0);
// fold (fabs (fabs x)) -> (fabs x)
@@ -14555,8 +14555,8 @@ SDValue DAGCombiner::visitFABS(SDNode *N) {
if (N0.getOpcode() == ISD::FNEG || N0.getOpcode() == ISD::FCOPYSIGN)
return DAG.getNode(ISD::FABS, SDLoc(N), VT, N0.getOperand(0));
- if (SDValue Cast = foldSignChangeInBitcast(N))
- return Cast;
+ if (SDValue Cast = foldSignChangeInBitcast(N))
+ return Cast;
return SDValue();
}
@@ -14566,13 +14566,13 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
SDValue N1 = N->getOperand(1);
SDValue N2 = N->getOperand(2);
- // BRCOND(FREEZE(cond)) is equivalent to BRCOND(cond) (both are
- // nondeterministic jumps).
- if (N1->getOpcode() == ISD::FREEZE && N1.hasOneUse()) {
- return DAG.getNode(ISD::BRCOND, SDLoc(N), MVT::Other, Chain,
- N1->getOperand(0), N2);
- }
-
+ // BRCOND(FREEZE(cond)) is equivalent to BRCOND(cond) (both are
+ // nondeterministic jumps).
+ if (N1->getOpcode() == ISD::FREEZE && N1.hasOneUse()) {
+ return DAG.getNode(ISD::BRCOND, SDLoc(N), MVT::Other, Chain,
+ N1->getOperand(0), N2);
+ }
+
// If N is a constant we could fold this into a fallthrough or unconditional
// branch. However that doesn't happen very often in normal code, because
// Instcombine/SimplifyCFG should have handled the available opportunities.
@@ -14954,13 +14954,13 @@ bool DAGCombiner::CombineToPreIndexedLoadStore(SDNode *N) {
// Therefore, we have:
// t0 = (x0 * offset0 - x1 * y0 * y1 *offset1) + (y0 * y1) * t1
- auto *CN = cast<ConstantSDNode>(OtherUses[i]->getOperand(OffsetIdx));
+ auto *CN = cast<ConstantSDNode>(OtherUses[i]->getOperand(OffsetIdx));
const APInt &Offset0 = CN->getAPIntValue();
- const APInt &Offset1 = cast<ConstantSDNode>(Offset)->getAPIntValue();
- int X0 = (OtherUses[i]->getOpcode() == ISD::SUB && OffsetIdx == 1) ? -1 : 1;
- int Y0 = (OtherUses[i]->getOpcode() == ISD::SUB && OffsetIdx == 0) ? -1 : 1;
- int X1 = (AM == ISD::PRE_DEC && !Swapped) ? -1 : 1;
- int Y1 = (AM == ISD::PRE_DEC && Swapped) ? -1 : 1;
+ const APInt &Offset1 = cast<ConstantSDNode>(Offset)->getAPIntValue();
+ int X0 = (OtherUses[i]->getOpcode() == ISD::SUB && OffsetIdx == 1) ? -1 : 1;
+ int Y0 = (OtherUses[i]->getOpcode() == ISD::SUB && OffsetIdx == 0) ? -1 : 1;
+ int X1 = (AM == ISD::PRE_DEC && !Swapped) ? -1 : 1;
+ int Y1 = (AM == ISD::PRE_DEC && Swapped) ? -1 : 1;
unsigned Opcode = (Y0 * Y1 < 0) ? ISD::SUB : ISD::ADD;
@@ -15152,8 +15152,8 @@ SDValue DAGCombiner::SplitIndexingFromLoad(LoadSDNode *LD) {
return DAG.getNode(Opc, SDLoc(LD), BP.getSimpleValueType(), BP, Inc);
}
-static inline ElementCount numVectorEltsOrZero(EVT T) {
- return T.isVector() ? T.getVectorElementCount() : ElementCount::getFixed(0);
+static inline ElementCount numVectorEltsOrZero(EVT T) {
+ return T.isVector() ? T.getVectorElementCount() : ElementCount::getFixed(0);
}
bool DAGCombiner::getTruncatedStoreValue(StoreSDNode *ST, SDValue &Val) {
@@ -15221,24 +15221,24 @@ SDValue DAGCombiner::ForwardStoreValueToDirectLoad(LoadSDNode *LD) {
EVT STMemType = ST->getMemoryVT();
EVT STType = ST->getValue().getValueType();
- // There are two cases to consider here:
- // 1. The store is fixed width and the load is scalable. In this case we
- // don't know at compile time if the store completely envelops the load
- // so we abandon the optimisation.
- // 2. The store is scalable and the load is fixed width. We could
- // potentially support a limited number of cases here, but there has been
- // no cost-benefit analysis to prove it's worth it.
- bool LdStScalable = LDMemType.isScalableVector();
- if (LdStScalable != STMemType.isScalableVector())
- return SDValue();
-
- // If we are dealing with scalable vectors on a big endian platform the
- // calculation of offsets below becomes trickier, since we do not know at
- // compile time the absolute size of the vector. Until we've done more
- // analysis on big-endian platforms it seems better to bail out for now.
- if (LdStScalable && DAG.getDataLayout().isBigEndian())
- return SDValue();
-
+ // There are two cases to consider here:
+ // 1. The store is fixed width and the load is scalable. In this case we
+ // don't know at compile time if the store completely envelops the load
+ // so we abandon the optimisation.
+ // 2. The store is scalable and the load is fixed width. We could
+ // potentially support a limited number of cases here, but there has been
+ // no cost-benefit analysis to prove it's worth it.
+ bool LdStScalable = LDMemType.isScalableVector();
+ if (LdStScalable != STMemType.isScalableVector())
+ return SDValue();
+
+ // If we are dealing with scalable vectors on a big endian platform the
+ // calculation of offsets below becomes trickier, since we do not know at
+ // compile time the absolute size of the vector. Until we've done more
+ // analysis on big-endian platforms it seems better to bail out for now.
+ if (LdStScalable && DAG.getDataLayout().isBigEndian())
+ return SDValue();
+
BaseIndexOffset BasePtrLD = BaseIndexOffset::match(LD, DAG);
BaseIndexOffset BasePtrST = BaseIndexOffset::match(ST, DAG);
int64_t Offset;
@@ -15250,22 +15250,22 @@ SDValue DAGCombiner::ForwardStoreValueToDirectLoad(LoadSDNode *LD) {
// the stored value). With Offset=n (for n > 0) the loaded value starts at the
// n:th least significant byte of the stored value.
if (DAG.getDataLayout().isBigEndian())
- Offset = ((int64_t)STMemType.getStoreSizeInBits().getFixedSize() -
- (int64_t)LDMemType.getStoreSizeInBits().getFixedSize()) /
- 8 -
- Offset;
+ Offset = ((int64_t)STMemType.getStoreSizeInBits().getFixedSize() -
+ (int64_t)LDMemType.getStoreSizeInBits().getFixedSize()) /
+ 8 -
+ Offset;
// Check that the stored value cover all bits that are loaded.
- bool STCoversLD;
-
- TypeSize LdMemSize = LDMemType.getSizeInBits();
- TypeSize StMemSize = STMemType.getSizeInBits();
- if (LdStScalable)
- STCoversLD = (Offset == 0) && LdMemSize == StMemSize;
- else
- STCoversLD = (Offset >= 0) && (Offset * 8 + LdMemSize.getFixedSize() <=
- StMemSize.getFixedSize());
-
+ bool STCoversLD;
+
+ TypeSize LdMemSize = LDMemType.getSizeInBits();
+ TypeSize StMemSize = STMemType.getSizeInBits();
+ if (LdStScalable)
+ STCoversLD = (Offset == 0) && LdMemSize == StMemSize;
+ else
+ STCoversLD = (Offset >= 0) && (Offset * 8 + LdMemSize.getFixedSize() <=
+ StMemSize.getFixedSize());
+
auto ReplaceLd = [&](LoadSDNode *LD, SDValue Val, SDValue Chain) -> SDValue {
if (LD->isIndexed()) {
// Cannot handle opaque target constants and we must respect the user's
@@ -15285,15 +15285,15 @@ SDValue DAGCombiner::ForwardStoreValueToDirectLoad(LoadSDNode *LD) {
// Memory as copy space (potentially masked).
if (Offset == 0 && LDType == STType && STMemType == LDMemType) {
// Simple case: Direct non-truncating forwarding
- if (LDType.getSizeInBits() == LdMemSize)
+ if (LDType.getSizeInBits() == LdMemSize)
return ReplaceLd(LD, ST->getValue(), Chain);
// Can we model the truncate and extension with an and mask?
if (STType.isInteger() && LDMemType.isInteger() && !STType.isVector() &&
!LDMemType.isVector() && LD->getExtensionType() != ISD::SEXTLOAD) {
// Mask to size of LDMemType
auto Mask =
- DAG.getConstant(APInt::getLowBitsSet(STType.getFixedSizeInBits(),
- StMemSize.getFixedSize()),
+ DAG.getConstant(APInt::getLowBitsSet(STType.getFixedSizeInBits(),
+ StMemSize.getFixedSize()),
SDLoc(ST), STType);
auto Val = DAG.getNode(ISD::AND, SDLoc(LD), LDType, ST->getValue(), Mask);
return ReplaceLd(LD, Val, Chain);
@@ -16124,7 +16124,7 @@ ShrinkLoadReplaceStoreWithStore(const std::pair<unsigned, unsigned> &MaskInfo,
SDValue Ptr = St->getBasePtr();
if (StOffset) {
SDLoc DL(IVal);
- Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(StOffset), DL);
+ Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(StOffset), DL);
}
// Truncate down to the new size.
@@ -16133,8 +16133,8 @@ ShrinkLoadReplaceStoreWithStore(const std::pair<unsigned, unsigned> &MaskInfo,
++OpsNarrowed;
return DAG
.getStore(St->getChain(), SDLoc(St), IVal, Ptr,
- St->getPointerInfo().getWithOffset(StOffset),
- St->getOriginalAlign());
+ St->getPointerInfo().getWithOffset(StOffset),
+ St->getOriginalAlign());
}
/// Look for sequence of load / op / store where op is one of 'or', 'xor', and
@@ -16238,8 +16238,8 @@ SDValue DAGCombiner::ReduceLoadOpStoreWidth(SDNode *N) {
if (NewAlign < DAG.getDataLayout().getABITypeAlign(NewVTTy))
return SDValue();
- SDValue NewPtr =
- DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(PtrOff), SDLoc(LD));
+ SDValue NewPtr =
+ DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(PtrOff), SDLoc(LD));
SDValue NewLD =
DAG.getLoad(NewVT, SDLoc(N0), LD->getChain(), NewPtr,
LD->getPointerInfo().getWithOffset(PtrOff), NewAlign,
@@ -16547,9 +16547,9 @@ bool DAGCombiner::mergeStoresOfConstantsOrVecElts(
// make sure we use trunc store if it's necessary to be legal.
SDValue NewStore;
if (!UseTrunc) {
- NewStore =
- DAG.getStore(NewChain, DL, StoredVal, FirstInChain->getBasePtr(),
- FirstInChain->getPointerInfo(), FirstInChain->getAlign());
+ NewStore =
+ DAG.getStore(NewChain, DL, StoredVal, FirstInChain->getBasePtr(),
+ FirstInChain->getPointerInfo(), FirstInChain->getAlign());
} else { // Must be realized as a trunc store
EVT LegalizedStoredValTy =
TLI.getTypeToTransformTo(*DAG.getContext(), StoredVal.getValueType());
@@ -16561,7 +16561,7 @@ bool DAGCombiner::mergeStoresOfConstantsOrVecElts(
NewStore = DAG.getTruncStore(
NewChain, DL, ExtendedStoreVal, FirstInChain->getBasePtr(),
FirstInChain->getPointerInfo(), StoredVal.getValueType() /*TVT*/,
- FirstInChain->getAlign(), FirstInChain->getMemOperand()->getFlags());
+ FirstInChain->getAlign(), FirstInChain->getMemOperand()->getFlags());
}
// Replace all merged stores with the new store.
@@ -16576,18 +16576,18 @@ void DAGCombiner::getStoreMergeCandidates(
StoreSDNode *St, SmallVectorImpl<MemOpLink> &StoreNodes,
SDNode *&RootNode) {
// This holds the base pointer, index, and the offset in bytes from the base
- // pointer. We must have a base and an offset. Do not handle stores to undef
- // base pointers.
+ // pointer. We must have a base and an offset. Do not handle stores to undef
+ // base pointers.
BaseIndexOffset BasePtr = BaseIndexOffset::match(St, DAG);
- if (!BasePtr.getBase().getNode() || BasePtr.getBase().isUndef())
- return;
+ if (!BasePtr.getBase().getNode() || BasePtr.getBase().isUndef())
+ return;
SDValue Val = peekThroughBitcasts(St->getValue());
StoreSource StoreSrc = getStoreSource(Val);
assert(StoreSrc != StoreSource::Unknown && "Expected known source for store");
-
- // Match on loadbaseptr if relevant.
- EVT MemVT = St->getMemoryVT();
+
+ // Match on loadbaseptr if relevant.
+ EVT MemVT = St->getMemoryVT();
BaseIndexOffset LBasePtr;
EVT LoadVT;
if (StoreSrc == StoreSource::Load) {
@@ -16609,7 +16609,7 @@ void DAGCombiner::getStoreMergeCandidates(
int64_t &Offset) -> bool {
// The memory operands must not be volatile/indexed/atomic.
// TODO: May be able to relax for unordered atomics (see D66309)
- if (!Other->isSimple() || Other->isIndexed())
+ if (!Other->isSimple() || Other->isIndexed())
return false;
// Don't mix temporal stores with non-temporal stores.
if (St->isNonTemporal() != Other->isNonTemporal())
@@ -16618,38 +16618,38 @@ void DAGCombiner::getStoreMergeCandidates(
// Allow merging constants of different types as integers.
bool NoTypeMatch = (MemVT.isInteger()) ? !MemVT.bitsEq(Other->getMemoryVT())
: Other->getMemoryVT() != MemVT;
- switch (StoreSrc) {
- case StoreSource::Load: {
+ switch (StoreSrc) {
+ case StoreSource::Load: {
if (NoTypeMatch)
return false;
- // The Load's Base Ptr must also match.
- auto *OtherLd = dyn_cast<LoadSDNode>(OtherBC);
- if (!OtherLd)
+ // The Load's Base Ptr must also match.
+ auto *OtherLd = dyn_cast<LoadSDNode>(OtherBC);
+ if (!OtherLd)
+ return false;
+ BaseIndexOffset LPtr = BaseIndexOffset::match(OtherLd, DAG);
+ if (LoadVT != OtherLd->getMemoryVT())
+ return false;
+ // Loads must only have one use.
+ if (!OtherLd->hasNUsesOfValue(1, 0))
return false;
- BaseIndexOffset LPtr = BaseIndexOffset::match(OtherLd, DAG);
- if (LoadVT != OtherLd->getMemoryVT())
- return false;
- // Loads must only have one use.
- if (!OtherLd->hasNUsesOfValue(1, 0))
- return false;
- // The memory operands must not be volatile/indexed/atomic.
- // TODO: May be able to relax for unordered atomics (see D66309)
- if (!OtherLd->isSimple() || OtherLd->isIndexed())
- return false;
- // Don't mix temporal loads with non-temporal loads.
- if (cast<LoadSDNode>(Val)->isNonTemporal() != OtherLd->isNonTemporal())
- return false;
- if (!(LBasePtr.equalBaseIndex(LPtr, DAG)))
- return false;
- break;
- }
- case StoreSource::Constant:
+ // The memory operands must not be volatile/indexed/atomic.
+ // TODO: May be able to relax for unordered atomics (see D66309)
+ if (!OtherLd->isSimple() || OtherLd->isIndexed())
+ return false;
+ // Don't mix temporal loads with non-temporal loads.
+ if (cast<LoadSDNode>(Val)->isNonTemporal() != OtherLd->isNonTemporal())
+ return false;
+ if (!(LBasePtr.equalBaseIndex(LPtr, DAG)))
+ return false;
+ break;
+ }
+ case StoreSource::Constant:
if (NoTypeMatch)
return false;
if (!(isa<ConstantSDNode>(OtherBC) || isa<ConstantFPSDNode>(OtherBC)))
return false;
- break;
- case StoreSource::Extract:
+ break;
+ case StoreSource::Extract:
// Do not merge truncated stores here.
if (Other->isTruncatingStore())
return false;
@@ -16658,9 +16658,9 @@ void DAGCombiner::getStoreMergeCandidates(
if (OtherBC.getOpcode() != ISD::EXTRACT_VECTOR_ELT &&
OtherBC.getOpcode() != ISD::EXTRACT_SUBVECTOR)
return false;
- break;
- default:
- llvm_unreachable("Unhandled store source for merging");
+ break;
+ default:
+ llvm_unreachable("Unhandled store source for merging");
}
Ptr = BaseIndexOffset::match(Other, DAG);
return (BasePtr.equalBaseIndex(Ptr, DAG, Offset));
@@ -16671,24 +16671,24 @@ void DAGCombiner::getStoreMergeCandidates(
auto OverLimitInDependenceCheck = [&](SDNode *StoreNode,
SDNode *RootNode) -> bool {
auto RootCount = StoreRootCountMap.find(StoreNode);
- return RootCount != StoreRootCountMap.end() &&
- RootCount->second.first == RootNode &&
- RootCount->second.second > StoreMergeDependenceLimit;
+ return RootCount != StoreRootCountMap.end() &&
+ RootCount->second.first == RootNode &&
+ RootCount->second.second > StoreMergeDependenceLimit;
+ };
+
+ auto TryToAddCandidate = [&](SDNode::use_iterator UseIter) {
+ // This must be a chain use.
+ if (UseIter.getOperandNo() != 0)
+ return;
+ if (auto *OtherStore = dyn_cast<StoreSDNode>(*UseIter)) {
+ BaseIndexOffset Ptr;
+ int64_t PtrDiff;
+ if (CandidateMatch(OtherStore, Ptr, PtrDiff) &&
+ !OverLimitInDependenceCheck(OtherStore, RootNode))
+ StoreNodes.push_back(MemOpLink(OtherStore, PtrDiff));
+ }
};
- auto TryToAddCandidate = [&](SDNode::use_iterator UseIter) {
- // This must be a chain use.
- if (UseIter.getOperandNo() != 0)
- return;
- if (auto *OtherStore = dyn_cast<StoreSDNode>(*UseIter)) {
- BaseIndexOffset Ptr;
- int64_t PtrDiff;
- if (CandidateMatch(OtherStore, Ptr, PtrDiff) &&
- !OverLimitInDependenceCheck(OtherStore, RootNode))
- StoreNodes.push_back(MemOpLink(OtherStore, PtrDiff));
- }
- };
-
// We looking for a root node which is an ancestor to all mergable
// stores. We search up through a load, to our root and then down
// through all children. For instance we will find Store{1,2,3} if
@@ -16708,21 +16708,21 @@ void DAGCombiner::getStoreMergeCandidates(
RootNode = St->getChain().getNode();
unsigned NumNodesExplored = 0;
- const unsigned MaxSearchNodes = 1024;
- if (auto *Ldn = dyn_cast<LoadSDNode>(RootNode)) {
+ const unsigned MaxSearchNodes = 1024;
+ if (auto *Ldn = dyn_cast<LoadSDNode>(RootNode)) {
RootNode = Ldn->getChain().getNode();
for (auto I = RootNode->use_begin(), E = RootNode->use_end();
- I != E && NumNodesExplored < MaxSearchNodes; ++I, ++NumNodesExplored) {
- if (I.getOperandNo() == 0 && isa<LoadSDNode>(*I)) { // walk down chain
+ I != E && NumNodesExplored < MaxSearchNodes; ++I, ++NumNodesExplored) {
+ if (I.getOperandNo() == 0 && isa<LoadSDNode>(*I)) { // walk down chain
for (auto I2 = (*I)->use_begin(), E2 = (*I)->use_end(); I2 != E2; ++I2)
- TryToAddCandidate(I2);
- }
- }
- } else {
+ TryToAddCandidate(I2);
+ }
+ }
+ } else {
for (auto I = RootNode->use_begin(), E = RootNode->use_end();
- I != E && NumNodesExplored < MaxSearchNodes; ++I, ++NumNodesExplored)
- TryToAddCandidate(I);
- }
+ I != E && NumNodesExplored < MaxSearchNodes; ++I, ++NumNodesExplored)
+ TryToAddCandidate(I);
+ }
}
// We need to check that merging these stores does not cause a loop in
@@ -17092,7 +17092,7 @@ bool DAGCombiner::tryStoreMergeOfLoads(SmallVectorImpl<MemOpLink> &StoreNodes,
}
LSBaseSDNode *FirstInChain = StoreNodes[0].MemNode;
unsigned FirstStoreAS = FirstInChain->getAddressSpace();
- Align FirstStoreAlign = FirstInChain->getAlign();
+ Align FirstStoreAlign = FirstInChain->getAlign();
LoadSDNode *FirstLoad = cast<LoadSDNode>(LoadNodes[0].MemNode);
// Scan the memory operations on the chain and find the first
@@ -17187,7 +17187,7 @@ bool DAGCombiner::tryStoreMergeOfLoads(SmallVectorImpl<MemOpLink> &StoreNodes,
// the NumElem refers to array/index size.
unsigned NumElem = std::min(NumConsecutiveStores, LastConsecutiveLoad + 1);
NumElem = std::min(LastLegalType, NumElem);
- Align FirstLoadAlign = FirstLoad->getAlign();
+ Align FirstLoadAlign = FirstLoad->getAlign();
if (NumElem < 2) {
// We know that candidate stores are in order and of correct
@@ -17199,8 +17199,8 @@ bool DAGCombiner::tryStoreMergeOfLoads(SmallVectorImpl<MemOpLink> &StoreNodes,
// can here.
unsigned NumSkip = 1;
while ((NumSkip < LoadNodes.size()) &&
- (LoadNodes[NumSkip].MemNode->getAlign() <= FirstLoadAlign) &&
- (StoreNodes[NumSkip].MemNode->getAlign() <= FirstStoreAlign))
+ (LoadNodes[NumSkip].MemNode->getAlign() <= FirstLoadAlign) &&
+ (StoreNodes[NumSkip].MemNode->getAlign() <= FirstStoreAlign))
NumSkip++;
StoreNodes.erase(StoreNodes.begin(), StoreNodes.begin() + NumSkip);
LoadNodes.erase(LoadNodes.begin(), LoadNodes.begin() + NumSkip);
@@ -17273,10 +17273,10 @@ bool DAGCombiner::tryStoreMergeOfLoads(SmallVectorImpl<MemOpLink> &StoreNodes,
FirstLoad->getChain(), FirstLoad->getBasePtr(),
FirstLoad->getPointerInfo(), JointMemOpVT,
FirstLoadAlign, LdMMOFlags);
- NewStore = DAG.getTruncStore(
- NewStoreChain, StoreDL, NewLoad, FirstInChain->getBasePtr(),
- FirstInChain->getPointerInfo(), JointMemOpVT,
- FirstInChain->getAlign(), FirstInChain->getMemOperand()->getFlags());
+ NewStore = DAG.getTruncStore(
+ NewStoreChain, StoreDL, NewLoad, FirstInChain->getBasePtr(),
+ FirstInChain->getPointerInfo(), JointMemOpVT,
+ FirstInChain->getAlign(), FirstInChain->getMemOperand()->getFlags());
}
// Transfer chain users from old loads to the new load.
@@ -17482,11 +17482,11 @@ SDValue DAGCombiner::replaceStoreOfFPConstant(StoreSDNode *ST) {
AAMDNodes AAInfo = ST->getAAInfo();
SDValue St0 = DAG.getStore(Chain, DL, Lo, Ptr, ST->getPointerInfo(),
- ST->getOriginalAlign(), MMOFlags, AAInfo);
- Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(4), DL);
+ ST->getOriginalAlign(), MMOFlags, AAInfo);
+ Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(4), DL);
SDValue St1 = DAG.getStore(Chain, DL, Hi, Ptr,
ST->getPointerInfo().getWithOffset(4),
- ST->getOriginalAlign(), MMOFlags, AAInfo);
+ ST->getOriginalAlign(), MMOFlags, AAInfo);
return DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
St0, St1);
}
@@ -17547,7 +17547,7 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
return NewST;
// Try transforming several stores into STORE (BSWAP).
- if (SDValue Store = mergeTruncStores(ST))
+ if (SDValue Store = mergeTruncStores(ST))
return Store;
if (ST->isUnindexed()) {
@@ -17620,12 +17620,12 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
!ST1->getBasePtr().isUndef() &&
// BaseIndexOffset and the code below requires knowing the size
// of a vector, so bail out if MemoryVT is scalable.
- !ST->getMemoryVT().isScalableVector() &&
+ !ST->getMemoryVT().isScalableVector() &&
!ST1->getMemoryVT().isScalableVector()) {
const BaseIndexOffset STBase = BaseIndexOffset::match(ST, DAG);
const BaseIndexOffset ChainBase = BaseIndexOffset::match(ST1, DAG);
- unsigned STBitSize = ST->getMemoryVT().getFixedSizeInBits();
- unsigned ChainBitSize = ST1->getMemoryVT().getFixedSizeInBits();
+ unsigned STBitSize = ST->getMemoryVT().getFixedSizeInBits();
+ unsigned ChainBitSize = ST1->getMemoryVT().getFixedSizeInBits();
// If this is a store who's preceding store to a subset of the current
// location and no one other node is chained to that store we can
// effectively drop the store. Do not remove stores to undef as they may
@@ -17696,7 +17696,7 @@ SDValue DAGCombiner::visitLIFETIME_END(SDNode *N) {
// We walk up the chains to find stores.
SmallVector<SDValue, 8> Chains = {N->getOperand(0)};
while (!Chains.empty()) {
- SDValue Chain = Chains.pop_back_val();
+ SDValue Chain = Chains.pop_back_val();
if (!Chain.hasOneUse())
continue;
switch (Chain.getOpcode()) {
@@ -17716,16 +17716,16 @@ SDValue DAGCombiner::visitLIFETIME_END(SDNode *N) {
// TODO: Can relax for unordered atomics (see D66309)
if (!ST->isSimple() || ST->isIndexed())
continue;
- const TypeSize StoreSize = ST->getMemoryVT().getStoreSize();
- // The bounds of a scalable store are not known until runtime, so this
- // store cannot be elided.
- if (StoreSize.isScalable())
- continue;
+ const TypeSize StoreSize = ST->getMemoryVT().getStoreSize();
+ // The bounds of a scalable store are not known until runtime, so this
+ // store cannot be elided.
+ if (StoreSize.isScalable())
+ continue;
const BaseIndexOffset StoreBase = BaseIndexOffset::match(ST, DAG);
// If we store purely within object bounds just before its lifetime ends,
// we can remove the store.
if (LifetimeEndBase.contains(DAG, LifetimeEnd->getSize() * 8, StoreBase,
- StoreSize.getFixedSize() * 8)) {
+ StoreSize.getFixedSize() * 8)) {
LLVM_DEBUG(dbgs() << "\nRemoving store:"; StoreBase.dump();
dbgs() << "\nwithin LIFETIME_END of : ";
LifetimeEndBase.dump(); dbgs() << "\n");
@@ -17836,12 +17836,12 @@ SDValue DAGCombiner::splitMergedValStore(StoreSDNode *ST) {
SDValue Ptr = ST->getBasePtr();
// Lower value store.
SDValue St0 = DAG.getStore(Chain, DL, Lo, Ptr, ST->getPointerInfo(),
- ST->getOriginalAlign(), MMOFlags, AAInfo);
- Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(HalfValBitSize / 8), DL);
+ ST->getOriginalAlign(), MMOFlags, AAInfo);
+ Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(HalfValBitSize / 8), DL);
// Higher value store.
- SDValue St1 = DAG.getStore(
- St0, DL, Hi, Ptr, ST->getPointerInfo().getWithOffset(HalfValBitSize / 8),
- ST->getOriginalAlign(), MMOFlags, AAInfo);
+ SDValue St1 = DAG.getStore(
+ St0, DL, Hi, Ptr, ST->getPointerInfo().getWithOffset(HalfValBitSize / 8),
+ ST->getOriginalAlign(), MMOFlags, AAInfo);
return St1;
}
@@ -18079,13 +18079,13 @@ SDValue DAGCombiner::scalarizeExtractedVectorLoad(SDNode *EVE, EVT InVecVT,
EVT ResultVT = EVE->getValueType(0);
EVT VecEltVT = InVecVT.getVectorElementType();
-
- // If the vector element type is not a multiple of a byte then we are unable
- // to correctly compute an address to load only the extracted element as a
- // scalar.
- if (!VecEltVT.isByteSized())
- return SDValue();
-
+
+ // If the vector element type is not a multiple of a byte then we are unable
+ // to correctly compute an address to load only the extracted element as a
+ // scalar.
+ if (!VecEltVT.isByteSized())
+ return SDValue();
+
Align Alignment = OriginalLoad->getAlign();
Align NewAlign = DAG.getDataLayout().getABITypeAlign(
VecEltVT.getTypeForEVT(*DAG.getContext()));
@@ -18721,24 +18721,24 @@ SDValue DAGCombiner::createBuildVecShuffle(const SDLoc &DL, SDNode *N,
// operands will all be based off of VecIn1, even those in VecIn2.
unsigned Vec2Offset = DidSplitVec ? 0 : InVT1.getVectorNumElements();
- uint64_t VTSize = VT.getFixedSizeInBits();
- uint64_t InVT1Size = InVT1.getFixedSizeInBits();
- uint64_t InVT2Size = InVT2.getFixedSizeInBits();
-
+ uint64_t VTSize = VT.getFixedSizeInBits();
+ uint64_t InVT1Size = InVT1.getFixedSizeInBits();
+ uint64_t InVT2Size = InVT2.getFixedSizeInBits();
+
// We can't generate a shuffle node with mismatched input and output types.
// Try to make the types match the type of the output.
if (InVT1 != VT || InVT2 != VT) {
- if ((VTSize % InVT1Size == 0) && InVT1 == InVT2) {
+ if ((VTSize % InVT1Size == 0) && InVT1 == InVT2) {
// If the output vector length is a multiple of both input lengths,
// we can concatenate them and pad the rest with undefs.
- unsigned NumConcats = VTSize / InVT1Size;
+ unsigned NumConcats = VTSize / InVT1Size;
assert(NumConcats >= 2 && "Concat needs at least two inputs!");
SmallVector<SDValue, 2> ConcatOps(NumConcats, DAG.getUNDEF(InVT1));
ConcatOps[0] = VecIn1;
ConcatOps[1] = VecIn2 ? VecIn2 : DAG.getUNDEF(InVT1);
VecIn1 = DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, ConcatOps);
VecIn2 = SDValue();
- } else if (InVT1Size == VTSize * 2) {
+ } else if (InVT1Size == VTSize * 2) {
if (!TLI.isExtractSubvectorCheap(VT, InVT1, NumElems))
return SDValue();
@@ -18751,7 +18751,7 @@ SDValue DAGCombiner::createBuildVecShuffle(const SDLoc &DL, SDNode *N,
// Since we now have shorter input vectors, adjust the offset of the
// second vector's start.
Vec2Offset = NumElems;
- } else if (InVT2Size <= InVT1Size) {
+ } else if (InVT2Size <= InVT1Size) {
// VecIn1 is wider than the output, and we have another, possibly
// smaller input. Pad the smaller input with undefs, shuffle at the
// input vector width, and extract the output.
@@ -18776,7 +18776,7 @@ SDValue DAGCombiner::createBuildVecShuffle(const SDLoc &DL, SDNode *N,
// when we start sorting the vectors by type.
return SDValue();
}
- } else if (InVT2Size * 2 == VTSize && InVT1Size == VTSize) {
+ } else if (InVT2Size * 2 == VTSize && InVT1Size == VTSize) {
SmallVector<SDValue, 2> ConcatOps(2, DAG.getUNDEF(InVT2));
ConcatOps[0] = VecIn2;
VecIn2 = DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, ConcatOps);
@@ -18967,7 +18967,7 @@ SDValue DAGCombiner::reduceBuildVecToShuffle(SDNode *N) {
// Have we seen this input vector before?
// The vectors are expected to be tiny (usually 1 or 2 elements), so using
// a map back from SDValues to numbers isn't worth it.
- unsigned Idx = std::distance(VecIn.begin(), find(VecIn, ExtractedFromVec));
+ unsigned Idx = std::distance(VecIn.begin(), find(VecIn, ExtractedFromVec));
if (Idx == VecIn.size())
VecIn.push_back(ExtractedFromVec);
@@ -19425,7 +19425,7 @@ static SDValue combineConcatVectorOfCasts(SDNode *N, SelectionDAG &DAG) {
// check the other type in the cast to make sure this is really legal.
EVT VT = N->getValueType(0);
EVT SrcEltVT = SrcVT.getVectorElementType();
- ElementCount NumElts = SrcVT.getVectorElementCount() * N->getNumOperands();
+ ElementCount NumElts = SrcVT.getVectorElementCount() * N->getNumOperands();
EVT ConcatSrcVT = EVT::getVectorVT(*DAG.getContext(), SrcEltVT, NumElts);
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
switch (CastOpcode) {
@@ -19462,8 +19462,8 @@ SDValue DAGCombiner::visitCONCAT_VECTORS(SDNode *N) {
return DAG.getUNDEF(VT);
// Optimize concat_vectors where all but the first of the vectors are undef.
- if (all_of(drop_begin(N->ops()),
- [](const SDValue &Op) { return Op.isUndef(); })) {
+ if (all_of(drop_begin(N->ops()),
+ [](const SDValue &Op) { return Op.isUndef(); })) {
SDValue In = N->getOperand(0);
assert(In.getValueType().isVector() && "Must concat vectors");
@@ -19636,16 +19636,16 @@ static SDValue getSubVectorSrc(SDValue V, SDValue Index, EVT SubVT) {
auto *IndexC = dyn_cast<ConstantSDNode>(Index);
if (IndexC && V.getOpcode() == ISD::CONCAT_VECTORS &&
V.getOperand(0).getValueType() == SubVT &&
- (IndexC->getZExtValue() % SubVT.getVectorMinNumElements()) == 0) {
- uint64_t SubIdx = IndexC->getZExtValue() / SubVT.getVectorMinNumElements();
+ (IndexC->getZExtValue() % SubVT.getVectorMinNumElements()) == 0) {
+ uint64_t SubIdx = IndexC->getZExtValue() / SubVT.getVectorMinNumElements();
return V.getOperand(SubIdx);
}
return SDValue();
}
static SDValue narrowInsertExtractVectorBinOp(SDNode *Extract,
- SelectionDAG &DAG,
- bool LegalOperations) {
+ SelectionDAG &DAG,
+ bool LegalOperations) {
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
SDValue BinOp = Extract->getOperand(0);
unsigned BinOpcode = BinOp.getOpcode();
@@ -19659,7 +19659,7 @@ static SDValue narrowInsertExtractVectorBinOp(SDNode *Extract,
SDValue Index = Extract->getOperand(1);
EVT SubVT = Extract->getValueType(0);
- if (!TLI.isOperationLegalOrCustom(BinOpcode, SubVT, LegalOperations))
+ if (!TLI.isOperationLegalOrCustom(BinOpcode, SubVT, LegalOperations))
return SDValue();
SDValue Sub0 = getSubVectorSrc(Bop0, Index, SubVT);
@@ -19680,12 +19680,12 @@ static SDValue narrowInsertExtractVectorBinOp(SDNode *Extract,
/// If we are extracting a subvector produced by a wide binary operator try
/// to use a narrow binary operator and/or avoid concatenation and extraction.
-static SDValue narrowExtractedVectorBinOp(SDNode *Extract, SelectionDAG &DAG,
- bool LegalOperations) {
+static SDValue narrowExtractedVectorBinOp(SDNode *Extract, SelectionDAG &DAG,
+ bool LegalOperations) {
// TODO: Refactor with the caller (visitEXTRACT_SUBVECTOR), so we can share
// some of these bailouts with other transforms.
- if (SDValue V = narrowInsertExtractVectorBinOp(Extract, DAG, LegalOperations))
+ if (SDValue V = narrowInsertExtractVectorBinOp(Extract, DAG, LegalOperations))
return V;
// The extract index must be a constant, so we can map it to a concat operand.
@@ -19830,16 +19830,16 @@ static SDValue narrowExtractedVectorLoad(SDNode *Extract, SelectionDAG &DAG) {
return SDValue();
unsigned Index = ExtIdx->getZExtValue();
- unsigned NumElts = VT.getVectorMinNumElements();
+ unsigned NumElts = VT.getVectorMinNumElements();
- // The definition of EXTRACT_SUBVECTOR states that the index must be a
- // multiple of the minimum number of elements in the result type.
- assert(Index % NumElts == 0 && "The extract subvector index is not a "
- "multiple of the result's element count");
+ // The definition of EXTRACT_SUBVECTOR states that the index must be a
+ // multiple of the minimum number of elements in the result type.
+ assert(Index % NumElts == 0 && "The extract subvector index is not a "
+ "multiple of the result's element count");
+
+ // It's fine to use TypeSize here as we know the offset will not be negative.
+ TypeSize Offset = VT.getStoreSize() * (Index / NumElts);
- // It's fine to use TypeSize here as we know the offset will not be negative.
- TypeSize Offset = VT.getStoreSize() * (Index / NumElts);
-
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
if (!TLI.shouldReduceLoadWidth(Ld, Ld->getExtensionType(), VT))
return SDValue();
@@ -19849,19 +19849,19 @@ static SDValue narrowExtractedVectorLoad(SDNode *Extract, SelectionDAG &DAG) {
SDLoc DL(Extract);
// TODO: Use "BaseIndexOffset" to make this more effective.
- SDValue NewAddr = DAG.getMemBasePlusOffset(Ld->getBasePtr(), Offset, DL);
-
- uint64_t StoreSize = MemoryLocation::getSizeOrUnknown(VT.getStoreSize());
+ SDValue NewAddr = DAG.getMemBasePlusOffset(Ld->getBasePtr(), Offset, DL);
+
+ uint64_t StoreSize = MemoryLocation::getSizeOrUnknown(VT.getStoreSize());
MachineFunction &MF = DAG.getMachineFunction();
- MachineMemOperand *MMO;
- if (Offset.isScalable()) {
- MachinePointerInfo MPI =
- MachinePointerInfo(Ld->getPointerInfo().getAddrSpace());
- MMO = MF.getMachineMemOperand(Ld->getMemOperand(), MPI, StoreSize);
- } else
- MMO = MF.getMachineMemOperand(Ld->getMemOperand(), Offset.getFixedSize(),
- StoreSize);
-
+ MachineMemOperand *MMO;
+ if (Offset.isScalable()) {
+ MachinePointerInfo MPI =
+ MachinePointerInfo(Ld->getPointerInfo().getAddrSpace());
+ MMO = MF.getMachineMemOperand(Ld->getMemOperand(), MPI, StoreSize);
+ } else
+ MMO = MF.getMachineMemOperand(Ld->getMemOperand(), Offset.getFixedSize(),
+ StoreSize);
+
SDValue NewLd = DAG.getLoad(VT, DL, Ld->getChain(), NewAddr, MMO);
DAG.makeEquivalentMemoryOrdering(Ld, NewLd);
return NewLd;
@@ -19914,9 +19914,9 @@ SDValue DAGCombiner::visitEXTRACT_SUBVECTOR(SDNode *N) {
}
if ((DestNumElts % SrcNumElts) == 0) {
unsigned DestSrcRatio = DestNumElts / SrcNumElts;
- if (NVT.getVectorElementCount().isKnownMultipleOf(DestSrcRatio)) {
- ElementCount NewExtEC =
- NVT.getVectorElementCount().divideCoefficientBy(DestSrcRatio);
+ if (NVT.getVectorElementCount().isKnownMultipleOf(DestSrcRatio)) {
+ ElementCount NewExtEC =
+ NVT.getVectorElementCount().divideCoefficientBy(DestSrcRatio);
EVT ScalarVT = SrcVT.getScalarType();
if ((ExtIdx % DestSrcRatio) == 0) {
SDLoc DL(N);
@@ -19930,7 +19930,7 @@ SDValue DAGCombiner::visitEXTRACT_SUBVECTOR(SDNode *N) {
V.getOperand(0), NewIndex);
return DAG.getBitcast(NVT, NewExtract);
}
- if (NewExtEC.isScalar() &&
+ if (NewExtEC.isScalar() &&
TLI.isOperationLegalOrCustom(ISD::EXTRACT_VECTOR_ELT, ScalarVT)) {
SDValue NewIndex = DAG.getVectorIdxConstant(IndexValScaled, DL);
SDValue NewExtract =
@@ -20035,7 +20035,7 @@ SDValue DAGCombiner::visitEXTRACT_SUBVECTOR(SDNode *N) {
N->getOperand(1));
}
- if (SDValue NarrowBOp = narrowExtractedVectorBinOp(N, DAG, LegalOperations))
+ if (SDValue NarrowBOp = narrowExtractedVectorBinOp(N, DAG, LegalOperations))
return NarrowBOp;
if (SimplifyDemandedVectorElts(SDValue(N, 0)))
@@ -20813,51 +20813,51 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) {
}
}
- if (Level < AfterLegalizeDAG && TLI.isTypeLegal(VT)) {
- // Canonicalize shuffles according to rules:
- // shuffle(A, shuffle(A, B)) -> shuffle(shuffle(A,B), A)
- // shuffle(B, shuffle(A, B)) -> shuffle(shuffle(A,B), B)
- // shuffle(B, shuffle(A, Undef)) -> shuffle(shuffle(A, Undef), B)
- if (N1.getOpcode() == ISD::VECTOR_SHUFFLE &&
- N0.getOpcode() != ISD::VECTOR_SHUFFLE) {
- // The incoming shuffle must be of the same type as the result of the
- // current shuffle.
- assert(N1->getOperand(0).getValueType() == VT &&
- "Shuffle types don't match");
-
- SDValue SV0 = N1->getOperand(0);
- SDValue SV1 = N1->getOperand(1);
- bool HasSameOp0 = N0 == SV0;
- bool IsSV1Undef = SV1.isUndef();
- if (HasSameOp0 || IsSV1Undef || N0 == SV1)
- // Commute the operands of this shuffle so merging below will trigger.
- return DAG.getCommutedVectorShuffle(*SVN);
- }
-
- // Canonicalize splat shuffles to the RHS to improve merging below.
- // shuffle(splat(A,u), shuffle(C,D)) -> shuffle'(shuffle(C,D), splat(A,u))
- if (N0.getOpcode() == ISD::VECTOR_SHUFFLE &&
- N1.getOpcode() == ISD::VECTOR_SHUFFLE &&
- cast<ShuffleVectorSDNode>(N0)->isSplat() &&
- !cast<ShuffleVectorSDNode>(N1)->isSplat()) {
+ if (Level < AfterLegalizeDAG && TLI.isTypeLegal(VT)) {
+ // Canonicalize shuffles according to rules:
+ // shuffle(A, shuffle(A, B)) -> shuffle(shuffle(A,B), A)
+ // shuffle(B, shuffle(A, B)) -> shuffle(shuffle(A,B), B)
+ // shuffle(B, shuffle(A, Undef)) -> shuffle(shuffle(A, Undef), B)
+ if (N1.getOpcode() == ISD::VECTOR_SHUFFLE &&
+ N0.getOpcode() != ISD::VECTOR_SHUFFLE) {
+ // The incoming shuffle must be of the same type as the result of the
+ // current shuffle.
+ assert(N1->getOperand(0).getValueType() == VT &&
+ "Shuffle types don't match");
+
+ SDValue SV0 = N1->getOperand(0);
+ SDValue SV1 = N1->getOperand(1);
+ bool HasSameOp0 = N0 == SV0;
+ bool IsSV1Undef = SV1.isUndef();
+ if (HasSameOp0 || IsSV1Undef || N0 == SV1)
+ // Commute the operands of this shuffle so merging below will trigger.
+ return DAG.getCommutedVectorShuffle(*SVN);
+ }
+
+ // Canonicalize splat shuffles to the RHS to improve merging below.
+ // shuffle(splat(A,u), shuffle(C,D)) -> shuffle'(shuffle(C,D), splat(A,u))
+ if (N0.getOpcode() == ISD::VECTOR_SHUFFLE &&
+ N1.getOpcode() == ISD::VECTOR_SHUFFLE &&
+ cast<ShuffleVectorSDNode>(N0)->isSplat() &&
+ !cast<ShuffleVectorSDNode>(N1)->isSplat()) {
return DAG.getCommutedVectorShuffle(*SVN);
- }
+ }
}
- // Compute the combined shuffle mask for a shuffle with SV0 as the first
- // operand, and SV1 as the second operand.
- // i.e. Merge SVN(OtherSVN, N1) -> shuffle(SV0, SV1, Mask).
- auto MergeInnerShuffle = [NumElts](ShuffleVectorSDNode *SVN,
- ShuffleVectorSDNode *OtherSVN, SDValue N1,
- SDValue &SV0, SDValue &SV1,
- SmallVectorImpl<int> &Mask) -> bool {
+ // Compute the combined shuffle mask for a shuffle with SV0 as the first
+ // operand, and SV1 as the second operand.
+ // i.e. Merge SVN(OtherSVN, N1) -> shuffle(SV0, SV1, Mask).
+ auto MergeInnerShuffle = [NumElts](ShuffleVectorSDNode *SVN,
+ ShuffleVectorSDNode *OtherSVN, SDValue N1,
+ SDValue &SV0, SDValue &SV1,
+ SmallVectorImpl<int> &Mask) -> bool {
// Don't try to fold splats; they're likely to simplify somehow, or they
// might be free.
- if (OtherSVN->isSplat())
- return false;
+ if (OtherSVN->isSplat())
+ return false;
- SV0 = SV1 = SDValue();
- Mask.clear();
+ SV0 = SV1 = SDValue();
+ Mask.clear();
for (unsigned i = 0; i != NumElts; ++i) {
int Idx = SVN->getMaskElt(i);
@@ -20871,14 +20871,14 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) {
if (Idx < (int)NumElts) {
// This shuffle index refers to the inner shuffle N0. Lookup the inner
// shuffle mask to identify which vector is actually referenced.
- Idx = OtherSVN->getMaskElt(Idx);
+ Idx = OtherSVN->getMaskElt(Idx);
if (Idx < 0) {
// Propagate Undef.
Mask.push_back(Idx);
continue;
}
- CurrentVec = (Idx < (int)NumElts) ? OtherSVN->getOperand(0)
- : OtherSVN->getOperand(1);
+ CurrentVec = (Idx < (int)NumElts) ? OtherSVN->getOperand(0)
+ : OtherSVN->getOperand(1);
} else {
// This shuffle index references an element within N1.
CurrentVec = N1;
@@ -20900,82 +20900,82 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) {
Mask.push_back(Idx);
continue;
}
- if (!SV1.getNode() || SV1 == CurrentVec) {
- // Ok. CurrentVec is the right hand side.
- // Update the mask accordingly.
- SV1 = CurrentVec;
- Mask.push_back(Idx + NumElts);
- continue;
- }
-
- // Last chance - see if the vector is another shuffle and if it
- // uses one of the existing candidate shuffle ops.
- if (auto *CurrentSVN = dyn_cast<ShuffleVectorSDNode>(CurrentVec)) {
- int InnerIdx = CurrentSVN->getMaskElt(Idx);
- if (InnerIdx < 0) {
- Mask.push_back(-1);
- continue;
- }
- SDValue InnerVec = (InnerIdx < (int)NumElts)
- ? CurrentSVN->getOperand(0)
- : CurrentSVN->getOperand(1);
- if (InnerVec.isUndef()) {
- Mask.push_back(-1);
- continue;
- }
- InnerIdx %= NumElts;
- if (InnerVec == SV0) {
- Mask.push_back(InnerIdx);
- continue;
- }
- if (InnerVec == SV1) {
- Mask.push_back(InnerIdx + NumElts);
- continue;
- }
- }
-
+ if (!SV1.getNode() || SV1 == CurrentVec) {
+ // Ok. CurrentVec is the right hand side.
+ // Update the mask accordingly.
+ SV1 = CurrentVec;
+ Mask.push_back(Idx + NumElts);
+ continue;
+ }
+
+ // Last chance - see if the vector is another shuffle and if it
+ // uses one of the existing candidate shuffle ops.
+ if (auto *CurrentSVN = dyn_cast<ShuffleVectorSDNode>(CurrentVec)) {
+ int InnerIdx = CurrentSVN->getMaskElt(Idx);
+ if (InnerIdx < 0) {
+ Mask.push_back(-1);
+ continue;
+ }
+ SDValue InnerVec = (InnerIdx < (int)NumElts)
+ ? CurrentSVN->getOperand(0)
+ : CurrentSVN->getOperand(1);
+ if (InnerVec.isUndef()) {
+ Mask.push_back(-1);
+ continue;
+ }
+ InnerIdx %= NumElts;
+ if (InnerVec == SV0) {
+ Mask.push_back(InnerIdx);
+ continue;
+ }
+ if (InnerVec == SV1) {
+ Mask.push_back(InnerIdx + NumElts);
+ continue;
+ }
+ }
+
// Bail out if we cannot convert the shuffle pair into a single shuffle.
- return false;
- }
- return true;
- };
-
- // Try to fold according to rules:
- // shuffle(shuffle(A, B, M0), C, M1) -> shuffle(A, B, M2)
- // shuffle(shuffle(A, B, M0), C, M1) -> shuffle(A, C, M2)
- // shuffle(shuffle(A, B, M0), C, M1) -> shuffle(B, C, M2)
- // Don't try to fold shuffles with illegal type.
- // Only fold if this shuffle is the only user of the other shuffle.
- if (N0.getOpcode() == ISD::VECTOR_SHUFFLE && N->isOnlyUserOf(N0.getNode()) &&
- Level < AfterLegalizeDAG && TLI.isTypeLegal(VT)) {
- ShuffleVectorSDNode *OtherSV = cast<ShuffleVectorSDNode>(N0);
-
- // The incoming shuffle must be of the same type as the result of the
- // current shuffle.
- assert(OtherSV->getOperand(0).getValueType() == VT &&
- "Shuffle types don't match");
-
- SDValue SV0, SV1;
- SmallVector<int, 4> Mask;
- if (MergeInnerShuffle(SVN, OtherSV, N1, SV0, SV1, Mask)) {
- // Check if all indices in Mask are Undef. In case, propagate Undef.
- if (llvm::all_of(Mask, [](int M) { return M < 0; }))
- return DAG.getUNDEF(VT);
-
- if (!SV0.getNode())
- SV0 = DAG.getUNDEF(VT);
- if (!SV1.getNode())
- SV1 = DAG.getUNDEF(VT);
-
- // Avoid introducing shuffles with illegal mask.
- // shuffle(shuffle(A, B, M0), C, M1) -> shuffle(A, B, M2)
- // shuffle(shuffle(A, B, M0), C, M1) -> shuffle(A, C, M2)
- // shuffle(shuffle(A, B, M0), C, M1) -> shuffle(B, C, M2)
- // shuffle(shuffle(A, B, M0), C, M1) -> shuffle(B, A, M2)
- // shuffle(shuffle(A, B, M0), C, M1) -> shuffle(C, A, M2)
- // shuffle(shuffle(A, B, M0), C, M1) -> shuffle(C, B, M2)
- return TLI.buildLegalVectorShuffle(VT, SDLoc(N), SV0, SV1, Mask, DAG);
- }
+ return false;
+ }
+ return true;
+ };
+
+ // Try to fold according to rules:
+ // shuffle(shuffle(A, B, M0), C, M1) -> shuffle(A, B, M2)
+ // shuffle(shuffle(A, B, M0), C, M1) -> shuffle(A, C, M2)
+ // shuffle(shuffle(A, B, M0), C, M1) -> shuffle(B, C, M2)
+ // Don't try to fold shuffles with illegal type.
+ // Only fold if this shuffle is the only user of the other shuffle.
+ if (N0.getOpcode() == ISD::VECTOR_SHUFFLE && N->isOnlyUserOf(N0.getNode()) &&
+ Level < AfterLegalizeDAG && TLI.isTypeLegal(VT)) {
+ ShuffleVectorSDNode *OtherSV = cast<ShuffleVectorSDNode>(N0);
+
+ // The incoming shuffle must be of the same type as the result of the
+ // current shuffle.
+ assert(OtherSV->getOperand(0).getValueType() == VT &&
+ "Shuffle types don't match");
+
+ SDValue SV0, SV1;
+ SmallVector<int, 4> Mask;
+ if (MergeInnerShuffle(SVN, OtherSV, N1, SV0, SV1, Mask)) {
+ // Check if all indices in Mask are Undef. In case, propagate Undef.
+ if (llvm::all_of(Mask, [](int M) { return M < 0; }))
+ return DAG.getUNDEF(VT);
+
+ if (!SV0.getNode())
+ SV0 = DAG.getUNDEF(VT);
+ if (!SV1.getNode())
+ SV1 = DAG.getUNDEF(VT);
+
+ // Avoid introducing shuffles with illegal mask.
+ // shuffle(shuffle(A, B, M0), C, M1) -> shuffle(A, B, M2)
+ // shuffle(shuffle(A, B, M0), C, M1) -> shuffle(A, C, M2)
+ // shuffle(shuffle(A, B, M0), C, M1) -> shuffle(B, C, M2)
+ // shuffle(shuffle(A, B, M0), C, M1) -> shuffle(B, A, M2)
+ // shuffle(shuffle(A, B, M0), C, M1) -> shuffle(C, A, M2)
+ // shuffle(shuffle(A, B, M0), C, M1) -> shuffle(C, B, M2)
+ return TLI.buildLegalVectorShuffle(VT, SDLoc(N), SV0, SV1, Mask, DAG);
+ }
}
if (SDValue V = foldShuffleOfConcatUndefs(SVN, DAG))
@@ -21060,8 +21060,8 @@ SDValue DAGCombiner::visitINSERT_SUBVECTOR(SDNode *N) {
if (N0.isUndef() && N1.getOpcode() == ISD::BITCAST &&
N1.getOperand(0).getOpcode() == ISD::EXTRACT_SUBVECTOR &&
N1.getOperand(0).getOperand(1) == N2 &&
- N1.getOperand(0).getOperand(0).getValueType().getVectorElementCount() ==
- VT.getVectorElementCount() &&
+ N1.getOperand(0).getOperand(0).getValueType().getVectorElementCount() ==
+ VT.getVectorElementCount() &&
N1.getOperand(0).getOperand(0).getValueType().getSizeInBits() ==
VT.getSizeInBits()) {
return DAG.getBitcast(VT, N1.getOperand(0).getOperand(0));
@@ -21078,7 +21078,7 @@ SDValue DAGCombiner::visitINSERT_SUBVECTOR(SDNode *N) {
EVT CN1VT = CN1.getValueType();
if (CN0VT.isVector() && CN1VT.isVector() &&
CN0VT.getVectorElementType() == CN1VT.getVectorElementType() &&
- CN0VT.getVectorElementCount() == VT.getVectorElementCount()) {
+ CN0VT.getVectorElementCount() == VT.getVectorElementCount()) {
SDValue NewINSERT = DAG.getNode(ISD::INSERT_SUBVECTOR, SDLoc(N),
CN0.getValueType(), CN0, CN1, N2);
return DAG.getBitcast(VT, NewINSERT);
@@ -21117,7 +21117,7 @@ SDValue DAGCombiner::visitINSERT_SUBVECTOR(SDNode *N) {
SDLoc DL(N);
SDValue NewIdx;
LLVMContext &Ctx = *DAG.getContext();
- ElementCount NumElts = VT.getVectorElementCount();
+ ElementCount NumElts = VT.getVectorElementCount();
unsigned EltSizeInBits = VT.getScalarSizeInBits();
if ((EltSizeInBits % N1SrcSVT.getSizeInBits()) == 0) {
unsigned Scale = EltSizeInBits / N1SrcSVT.getSizeInBits();
@@ -21125,9 +21125,9 @@ SDValue DAGCombiner::visitINSERT_SUBVECTOR(SDNode *N) {
NewIdx = DAG.getVectorIdxConstant(InsIdx * Scale, DL);
} else if ((N1SrcSVT.getSizeInBits() % EltSizeInBits) == 0) {
unsigned Scale = N1SrcSVT.getSizeInBits() / EltSizeInBits;
- if (NumElts.isKnownMultipleOf(Scale) && (InsIdx % Scale) == 0) {
- NewVT = EVT::getVectorVT(Ctx, N1SrcSVT,
- NumElts.divideCoefficientBy(Scale));
+ if (NumElts.isKnownMultipleOf(Scale) && (InsIdx % Scale) == 0) {
+ NewVT = EVT::getVectorVT(Ctx, N1SrcSVT,
+ NumElts.divideCoefficientBy(Scale));
NewIdx = DAG.getVectorIdxConstant(InsIdx / Scale, DL);
}
}
@@ -21159,10 +21159,10 @@ SDValue DAGCombiner::visitINSERT_SUBVECTOR(SDNode *N) {
// If the input vector is a concatenation, and the insert replaces
// one of the pieces, we can optimize into a single concat_vectors.
if (N0.getOpcode() == ISD::CONCAT_VECTORS && N0.hasOneUse() &&
- N0.getOperand(0).getValueType() == N1.getValueType() &&
- N0.getOperand(0).getValueType().isScalableVector() ==
- N1.getValueType().isScalableVector()) {
- unsigned Factor = N1.getValueType().getVectorMinNumElements();
+ N0.getOperand(0).getValueType() == N1.getValueType() &&
+ N0.getOperand(0).getValueType().isScalableVector() ==
+ N1.getValueType().isScalableVector()) {
+ unsigned Factor = N1.getValueType().getVectorMinNumElements();
SmallVector<SDValue, 8> Ops(N0->op_begin(), N0->op_end());
Ops[InsIdx / Factor] = N1;
return DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(N), VT, Ops);
@@ -21189,7 +21189,7 @@ SDValue DAGCombiner::visitFP16_TO_FP(SDNode *N) {
SDValue N0 = N->getOperand(0);
// fold fp16_to_fp(op & 0xffff) -> fp16_to_fp(op)
- if (!TLI.shouldKeepZExtForFP16Conv() && N0->getOpcode() == ISD::AND) {
+ if (!TLI.shouldKeepZExtForFP16Conv() && N0->getOpcode() == ISD::AND) {
ConstantSDNode *AndConst = getAsNonOpaqueConstant(N0.getOperand(1));
if (AndConst && AndConst->getAPIntValue() == 0xffff) {
return DAG.getNode(ISD::FP16_TO_FP, SDLoc(N), N->getValueType(0),
@@ -21206,7 +21206,7 @@ SDValue DAGCombiner::visitVECREDUCE(SDNode *N) {
unsigned Opcode = N->getOpcode();
// VECREDUCE over 1-element vector is just an extract.
- if (VT.getVectorElementCount().isScalar()) {
+ if (VT.getVectorElementCount().isScalar()) {
SDLoc dl(N);
SDValue Res =
DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT.getVectorElementType(), N0,
@@ -21445,8 +21445,8 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N) {
SDValue Z = LHS.getOperand(2);
EVT NarrowVT = X.getValueType();
if (NarrowVT == Y.getValueType() &&
- TLI.isOperationLegalOrCustomOrPromote(Opcode, NarrowVT,
- LegalOperations)) {
+ TLI.isOperationLegalOrCustomOrPromote(Opcode, NarrowVT,
+ LegalOperations)) {
// (binop undef, undef) may not return undef, so compute that result.
SDLoc DL(N);
SDValue VecC =
@@ -21459,10 +21459,10 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N) {
// Make sure all but the first op are undef or constant.
auto ConcatWithConstantOrUndef = [](SDValue Concat) {
return Concat.getOpcode() == ISD::CONCAT_VECTORS &&
- all_of(drop_begin(Concat->ops()), [](const SDValue &Op) {
- return Op.isUndef() ||
- ISD::isBuildVectorOfConstantSDNodes(Op.getNode());
- });
+ all_of(drop_begin(Concat->ops()), [](const SDValue &Op) {
+ return Op.isUndef() ||
+ ISD::isBuildVectorOfConstantSDNodes(Op.getNode());
+ });
};
// The following pattern is likely to emerge with vector reduction ops. Moving
@@ -21684,7 +21684,7 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS,
// It is safe to replace the two loads if they have different alignments,
// but the new load must be the minimum (most restrictive) alignment of the
// inputs.
- Align Alignment = std::min(LLD->getAlign(), RLD->getAlign());
+ Align Alignment = std::min(LLD->getAlign(), RLD->getAlign());
MachineMemOperand::Flags MMOFlags = LLD->getMemOperand()->getFlags();
if (!RLD->isInvariant())
MMOFlags &= ~MachineMemOperand::MOInvariant;
@@ -21790,46 +21790,46 @@ SDValue DAGCombiner::foldSelectCCToShiftAnd(const SDLoc &DL, SDValue N0,
return DAG.getNode(ISD::AND, DL, AType, Shift, N2);
}
-// Transform (fneg/fabs (bitconvert x)) to avoid loading constant pool values.
-SDValue DAGCombiner::foldSignChangeInBitcast(SDNode *N) {
- SDValue N0 = N->getOperand(0);
- EVT VT = N->getValueType(0);
- bool IsFabs = N->getOpcode() == ISD::FABS;
- bool IsFree = IsFabs ? TLI.isFAbsFree(VT) : TLI.isFNegFree(VT);
-
- if (IsFree || N0.getOpcode() != ISD::BITCAST || !N0.hasOneUse())
- return SDValue();
-
- SDValue Int = N0.getOperand(0);
- EVT IntVT = Int.getValueType();
-
- // The operand to cast should be integer.
- if (!IntVT.isInteger() || IntVT.isVector())
- return SDValue();
-
- // (fneg (bitconvert x)) -> (bitconvert (xor x sign))
- // (fabs (bitconvert x)) -> (bitconvert (and x ~sign))
- APInt SignMask;
- if (N0.getValueType().isVector()) {
- // For vector, create a sign mask (0x80...) or its inverse (for fabs,
- // 0x7f...) per element and splat it.
- SignMask = APInt::getSignMask(N0.getScalarValueSizeInBits());
- if (IsFabs)
- SignMask = ~SignMask;
- SignMask = APInt::getSplat(IntVT.getSizeInBits(), SignMask);
- } else {
- // For scalar, just use the sign mask (0x80... or the inverse, 0x7f...)
- SignMask = APInt::getSignMask(IntVT.getSizeInBits());
- if (IsFabs)
- SignMask = ~SignMask;
- }
- SDLoc DL(N0);
- Int = DAG.getNode(IsFabs ? ISD::AND : ISD::XOR, DL, IntVT, Int,
- DAG.getConstant(SignMask, DL, IntVT));
- AddToWorklist(Int.getNode());
- return DAG.getBitcast(VT, Int);
-}
-
+// Transform (fneg/fabs (bitconvert x)) to avoid loading constant pool values.
+SDValue DAGCombiner::foldSignChangeInBitcast(SDNode *N) {
+ SDValue N0 = N->getOperand(0);
+ EVT VT = N->getValueType(0);
+ bool IsFabs = N->getOpcode() == ISD::FABS;
+ bool IsFree = IsFabs ? TLI.isFAbsFree(VT) : TLI.isFNegFree(VT);
+
+ if (IsFree || N0.getOpcode() != ISD::BITCAST || !N0.hasOneUse())
+ return SDValue();
+
+ SDValue Int = N0.getOperand(0);
+ EVT IntVT = Int.getValueType();
+
+ // The operand to cast should be integer.
+ if (!IntVT.isInteger() || IntVT.isVector())
+ return SDValue();
+
+ // (fneg (bitconvert x)) -> (bitconvert (xor x sign))
+ // (fabs (bitconvert x)) -> (bitconvert (and x ~sign))
+ APInt SignMask;
+ if (N0.getValueType().isVector()) {
+ // For vector, create a sign mask (0x80...) or its inverse (for fabs,
+ // 0x7f...) per element and splat it.
+ SignMask = APInt::getSignMask(N0.getScalarValueSizeInBits());
+ if (IsFabs)
+ SignMask = ~SignMask;
+ SignMask = APInt::getSplat(IntVT.getSizeInBits(), SignMask);
+ } else {
+ // For scalar, just use the sign mask (0x80... or the inverse, 0x7f...)
+ SignMask = APInt::getSignMask(IntVT.getSizeInBits());
+ if (IsFabs)
+ SignMask = ~SignMask;
+ }
+ SDLoc DL(N0);
+ Int = DAG.getNode(IsFabs ? ISD::AND : ISD::XOR, DL, IntVT, Int,
+ DAG.getConstant(SignMask, DL, IntVT));
+ AddToWorklist(Int.getNode());
+ return DAG.getBitcast(VT, Int);
+}
+
/// Turn "(a cond b) ? 1.0f : 2.0f" into "load (tmp + ((a cond b) ? 0 : 4)"
/// where "tmp" is a constant pool entry containing an array with 1.0 and 2.0
/// in it. This may be a win when the constant is not otherwise available
@@ -22112,7 +22112,7 @@ SDValue DAGCombiner::BuildUDIV(SDNode *N) {
SDValue DAGCombiner::BuildLogBase2(SDValue V, const SDLoc &DL) {
EVT VT = V.getValueType();
SDValue Ctlz = DAG.getNode(ISD::CTLZ, DL, VT, V);
- SDValue Base = DAG.getConstant(VT.getScalarSizeInBits() - 1, DL, VT);
+ SDValue Base = DAG.getConstant(VT.getScalarSizeInBits() - 1, DL, VT);
SDValue LogBase2 = DAG.getNode(ISD::SUB, DL, VT, Base, Ctlz);
return LogBase2;
}
@@ -22290,21 +22290,21 @@ SDValue DAGCombiner::buildSqrtEstimateImpl(SDValue Op, SDNodeFlags Flags,
Reciprocal)) {
AddToWorklist(Est.getNode());
- if (Iterations)
+ if (Iterations)
Est = UseOneConstNR
? buildSqrtNROneConst(Op, Est, Iterations, Flags, Reciprocal)
: buildSqrtNRTwoConst(Op, Est, Iterations, Flags, Reciprocal);
- if (!Reciprocal) {
- SDLoc DL(Op);
- // Try the target specific test first.
- SDValue Test = TLI.getSqrtInputTest(Op, DAG, DAG.getDenormalMode(VT));
-
- // The estimate is now completely wrong if the input was exactly 0.0 or
- // possibly a denormal. Force the answer to 0.0 or value provided by
- // target for those cases.
- Est = DAG.getNode(
- Test.getValueType().isVector() ? ISD::VSELECT : ISD::SELECT, DL, VT,
- Test, TLI.getSqrtResultForDenormInput(Op, DAG), Est);
+ if (!Reciprocal) {
+ SDLoc DL(Op);
+ // Try the target specific test first.
+ SDValue Test = TLI.getSqrtInputTest(Op, DAG, DAG.getDenormalMode(VT));
+
+ // The estimate is now completely wrong if the input was exactly 0.0 or
+ // possibly a denormal. Force the answer to 0.0 or value provided by
+ // target for those cases.
+ Est = DAG.getNode(
+ Test.getValueType().isVector() ? ISD::VSELECT : ISD::SELECT, DL, VT,
+ Test, TLI.getSqrtResultForDenormInput(Op, DAG), Est);
}
return Est;
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/FastISel.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/FastISel.cpp
index 94d2762e52..0ff77d4ba1 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -158,77 +158,77 @@ bool FastISel::lowerArguments() {
/// Return the defined register if this instruction defines exactly one
/// virtual register and uses no other virtual registers. Otherwise return 0.
-static Register findLocalRegDef(MachineInstr &MI) {
+static Register findLocalRegDef(MachineInstr &MI) {
Register RegDef;
for (const MachineOperand &MO : MI.operands()) {
if (!MO.isReg())
continue;
if (MO.isDef()) {
if (RegDef)
- return Register();
+ return Register();
RegDef = MO.getReg();
} else if (MO.getReg().isVirtual()) {
- // This is another use of a vreg. Don't delete it.
+ // This is another use of a vreg. Don't delete it.
return Register();
}
}
return RegDef;
}
-static bool isRegUsedByPhiNodes(Register DefReg,
- FunctionLoweringInfo &FuncInfo) {
- for (auto &P : FuncInfo.PHINodesToUpdate)
- if (P.second == DefReg)
- return true;
- return false;
-}
-
+static bool isRegUsedByPhiNodes(Register DefReg,
+ FunctionLoweringInfo &FuncInfo) {
+ for (auto &P : FuncInfo.PHINodesToUpdate)
+ if (P.second == DefReg)
+ return true;
+ return false;
+}
+
void FastISel::flushLocalValueMap() {
- // If FastISel bails out, it could leave local value instructions behind
- // that aren't used for anything. Detect and erase those.
- if (LastLocalValue != EmitStartPt) {
- // Save the first instruction after local values, for later.
- MachineBasicBlock::iterator FirstNonValue(LastLocalValue);
- ++FirstNonValue;
-
+ // If FastISel bails out, it could leave local value instructions behind
+ // that aren't used for anything. Detect and erase those.
+ if (LastLocalValue != EmitStartPt) {
+ // Save the first instruction after local values, for later.
+ MachineBasicBlock::iterator FirstNonValue(LastLocalValue);
+ ++FirstNonValue;
+
MachineBasicBlock::reverse_iterator RE =
EmitStartPt ? MachineBasicBlock::reverse_iterator(EmitStartPt)
: FuncInfo.MBB->rend();
MachineBasicBlock::reverse_iterator RI(LastLocalValue);
for (; RI != RE;) {
MachineInstr &LocalMI = *RI;
- // Increment before erasing what it points to.
+ // Increment before erasing what it points to.
++RI;
- Register DefReg = findLocalRegDef(LocalMI);
- if (!DefReg)
+ Register DefReg = findLocalRegDef(LocalMI);
+ if (!DefReg)
continue;
- if (FuncInfo.RegsWithFixups.count(DefReg))
+ if (FuncInfo.RegsWithFixups.count(DefReg))
continue;
- bool UsedByPHI = isRegUsedByPhiNodes(DefReg, FuncInfo);
- if (!UsedByPHI && MRI.use_nodbg_empty(DefReg)) {
- if (EmitStartPt == &LocalMI)
- EmitStartPt = EmitStartPt->getPrevNode();
- LLVM_DEBUG(dbgs() << "removing dead local value materialization"
- << LocalMI);
- LocalMI.eraseFromParent();
- }
- }
-
- if (FirstNonValue != FuncInfo.MBB->end()) {
- // See if there are any local value instructions left. If so, we want to
- // make sure the first one has a debug location; if it doesn't, use the
- // first non-value instruction's debug location.
-
- // If EmitStartPt is non-null, this block had copies at the top before
- // FastISel started doing anything; it points to the last one, so the
- // first local value instruction is the one after EmitStartPt.
- // If EmitStartPt is null, the first local value instruction is at the
- // top of the block.
- MachineBasicBlock::iterator FirstLocalValue =
- EmitStartPt ? ++MachineBasicBlock::iterator(EmitStartPt)
- : FuncInfo.MBB->begin();
- if (FirstLocalValue != FirstNonValue && !FirstLocalValue->getDebugLoc())
- FirstLocalValue->setDebugLoc(FirstNonValue->getDebugLoc());
+ bool UsedByPHI = isRegUsedByPhiNodes(DefReg, FuncInfo);
+ if (!UsedByPHI && MRI.use_nodbg_empty(DefReg)) {
+ if (EmitStartPt == &LocalMI)
+ EmitStartPt = EmitStartPt->getPrevNode();
+ LLVM_DEBUG(dbgs() << "removing dead local value materialization"
+ << LocalMI);
+ LocalMI.eraseFromParent();
+ }
+ }
+
+ if (FirstNonValue != FuncInfo.MBB->end()) {
+ // See if there are any local value instructions left. If so, we want to
+ // make sure the first one has a debug location; if it doesn't, use the
+ // first non-value instruction's debug location.
+
+ // If EmitStartPt is non-null, this block had copies at the top before
+ // FastISel started doing anything; it points to the last one, so the
+ // first local value instruction is the one after EmitStartPt.
+ // If EmitStartPt is null, the first local value instruction is at the
+ // top of the block.
+ MachineBasicBlock::iterator FirstLocalValue =
+ EmitStartPt ? ++MachineBasicBlock::iterator(EmitStartPt)
+ : FuncInfo.MBB->begin();
+ if (FirstLocalValue != FirstNonValue && !FirstLocalValue->getDebugLoc())
+ FirstLocalValue->setDebugLoc(FirstNonValue->getDebugLoc());
}
}
@@ -261,13 +261,13 @@ bool FastISel::hasTrivialKill(const Value *V) {
if (GEP->hasAllZeroIndices() && !hasTrivialKill(GEP->getOperand(0)))
return false;
- // Casts and extractvalues may be trivially coalesced by fast-isel.
- if (I->getOpcode() == Instruction::BitCast ||
- I->getOpcode() == Instruction::PtrToInt ||
- I->getOpcode() == Instruction::IntToPtr ||
- I->getOpcode() == Instruction::ExtractValue)
- return false;
-
+ // Casts and extractvalues may be trivially coalesced by fast-isel.
+ if (I->getOpcode() == Instruction::BitCast ||
+ I->getOpcode() == Instruction::PtrToInt ||
+ I->getOpcode() == Instruction::IntToPtr ||
+ I->getOpcode() == Instruction::ExtractValue)
+ return false;
+
// Only instructions with a single use in the same basic block are considered
// to have trivial kills.
return I->hasOneUse() &&
@@ -347,7 +347,7 @@ Register FastISel::materializeConstant(const Value *V, MVT VT) {
getRegForValue(ConstantInt::get(V->getContext(), SIntVal));
if (IntegerReg)
Reg = fastEmit_r(IntVT.getSimpleVT(), VT, ISD::SINT_TO_FP, IntegerReg,
- /*Op0IsKill=*/false);
+ /*Op0IsKill=*/false);
}
}
} else if (const auto *Op = dyn_cast<Operator>(V)) {
@@ -477,9 +477,9 @@ void FastISel::removeDeadCode(MachineBasicBlock::iterator I,
}
FastISel::SavePoint FastISel::enterLocalValueArea() {
- SavePoint OldInsertPt = FuncInfo.InsertPt;
+ SavePoint OldInsertPt = FuncInfo.InsertPt;
recomputeInsertPt();
- return OldInsertPt;
+ return OldInsertPt;
}
void FastISel::leaveLocalValueArea(SavePoint OldInsertPt) {
@@ -487,7 +487,7 @@ void FastISel::leaveLocalValueArea(SavePoint OldInsertPt) {
LastLocalValue = &*std::prev(FuncInfo.InsertPt);
// Restore the previous insert position.
- FuncInfo.InsertPt = OldInsertPt;
+ FuncInfo.InsertPt = OldInsertPt;
}
bool FastISel::selectBinaryOp(const User *I, unsigned ISDOpcode) {
@@ -1256,8 +1256,8 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) {
case Intrinsic::sideeffect:
// Neither does the assume intrinsic; it's also OK not to codegen its operand.
case Intrinsic::assume:
- // Neither does the llvm.experimental.noalias.scope.decl intrinsic
- case Intrinsic::experimental_noalias_scope_decl:
+ // Neither does the llvm.experimental.noalias.scope.decl intrinsic
+ case Intrinsic::experimental_noalias_scope_decl:
return true;
case Intrinsic::dbg_declare: {
const DbgDeclareInst *DI = cast<DbgDeclareInst>(II);
@@ -1526,11 +1526,11 @@ void FastISel::removeDeadLocalValueCode(MachineInstr *SavedLastLocalValue)
}
bool FastISel::selectInstruction(const Instruction *I) {
- // Flush the local value map before starting each instruction.
- // This improves locality and debugging, and can reduce spills.
- // Reuse of values across IR instructions is relatively uncommon.
- flushLocalValueMap();
-
+ // Flush the local value map before starting each instruction.
+ // This improves locality and debugging, and can reduce spills.
+ // Reuse of values across IR instructions is relatively uncommon.
+ flushLocalValueMap();
+
MachineInstr *SavedLastLocalValue = getLastLocalValue();
// Just before the terminator instruction, insert instructions to
// feed PHI nodes in successor blocks.
@@ -1677,13 +1677,13 @@ bool FastISel::selectFNeg(const User *I, const Value *In) {
return false;
Register IntResultReg = fastEmit_ri_(
- IntVT.getSimpleVT(), ISD::XOR, IntReg, /*Op0IsKill=*/true,
+ IntVT.getSimpleVT(), ISD::XOR, IntReg, /*Op0IsKill=*/true,
UINT64_C(1) << (VT.getSizeInBits() - 1), IntVT.getSimpleVT());
if (!IntResultReg)
return false;
ResultReg = fastEmit_r(IntVT.getSimpleVT(), VT.getSimpleVT(), ISD::BITCAST,
- IntResultReg, /*Op0IsKill=*/true);
+ IntResultReg, /*Op0IsKill=*/true);
if (!ResultReg)
return false;
@@ -1739,7 +1739,7 @@ bool FastISel::selectOperator(const User *I, unsigned Opcode) {
return selectBinaryOp(I, ISD::FADD);
case Instruction::Sub:
return selectBinaryOp(I, ISD::SUB);
- case Instruction::FSub:
+ case Instruction::FSub:
return selectBinaryOp(I, ISD::FSUB);
case Instruction::Mul:
return selectBinaryOp(I, ISD::MUL);
@@ -2236,9 +2236,9 @@ bool FastISel::handlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) {
const Value *PHIOp = PN.getIncomingValueForBlock(LLVMBB);
- // Set the DebugLoc for the copy. Use the location of the operand if
- // there is one; otherwise no location, flushLocalValueMap will fix it.
- DbgLoc = DebugLoc();
+ // Set the DebugLoc for the copy. Use the location of the operand if
+ // there is one; otherwise no location, flushLocalValueMap will fix it.
+ DbgLoc = DebugLoc();
if (const auto *Inst = dyn_cast<Instruction>(PHIOp))
DbgLoc = Inst->getDebugLoc();
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
index e2412b6892..32a4f60df0 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
@@ -197,7 +197,7 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
// Look for inline asm that clobbers the SP register.
if (auto *Call = dyn_cast<CallBase>(&I)) {
if (Call->isInlineAsm()) {
- Register SP = TLI->getStackPointerRegisterToSaveRestore();
+ Register SP = TLI->getStackPointerRegisterToSaveRestore();
const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
std::vector<TargetLowering::AsmOperandInfo> Ops =
TLI->ParseConstraints(Fn->getParent()->getDataLayout(), TRI,
@@ -360,7 +360,7 @@ void FunctionLoweringInfo::clear() {
RegFixups.clear();
RegsWithFixups.clear();
StatepointStackSlots.clear();
- StatepointRelocationMaps.clear();
+ StatepointRelocationMaps.clear();
PreferredExtendType.clear();
}
@@ -458,7 +458,7 @@ void FunctionLoweringInfo::ComputePHILiveOutRegInfo(const PHINode *PN) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
APInt Val = CI->getValue().zextOrTrunc(BitWidth);
DestLOI.NumSignBits = Val.getNumSignBits();
- DestLOI.Known = KnownBits::makeConstant(Val);
+ DestLOI.Known = KnownBits::makeConstant(Val);
} else {
assert(ValueMap.count(V) && "V should have been placed in ValueMap when its"
"CopyToReg node was created.");
@@ -508,7 +508,7 @@ void FunctionLoweringInfo::ComputePHILiveOutRegInfo(const PHINode *PN) {
return;
}
DestLOI.NumSignBits = std::min(DestLOI.NumSignBits, SrcLOI->NumSignBits);
- DestLOI.Known = KnownBits::commonBits(DestLOI.Known, SrcLOI->Known);
+ DestLOI.Known = KnownBits::commonBits(DestLOI.Known, SrcLOI->Known);
}
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index 298f7cee42..a5978711b8 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -26,7 +26,7 @@
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
-#include "llvm/IR/PseudoProbe.h"
+#include "llvm/IR/PseudoProbe.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
@@ -201,8 +201,8 @@ void InstrEmitter::CreateVirtualRegisters(SDNode *Node,
bool HasVRegVariadicDefs = !MF->getTarget().usesPhysRegsForValues() &&
II.isVariadic() && II.variadicOpsAreDefs();
unsigned NumVRegs = HasVRegVariadicDefs ? NumResults : II.getNumDefs();
- if (Node->getMachineOpcode() == TargetOpcode::STATEPOINT)
- NumVRegs = NumResults;
+ if (Node->getMachineOpcode() == TargetOpcode::STATEPOINT)
+ NumVRegs = NumResults;
for (unsigned i = 0; i < NumVRegs; ++i) {
// If the specific node value is only used by a CopyToReg and the dest reg
// is a vreg in the same register class, use the CopyToReg'd destination
@@ -696,11 +696,11 @@ InstrEmitter::EmitDbgValue(SDDbgValue *SD,
return &*MIB;
}
- // Attempt to produce a DBG_INSTR_REF if we've been asked to.
- if (EmitDebugInstrRefs)
- if (auto *InstrRef = EmitDbgInstrRef(SD, VRBaseMap))
- return InstrRef;
-
+ // Attempt to produce a DBG_INSTR_REF if we've been asked to.
+ if (EmitDebugInstrRefs)
+ if (auto *InstrRef = EmitDbgInstrRef(SD, VRBaseMap))
+ return InstrRef;
+
if (SD->getKind() == SDDbgValue::FRAMEIX) {
// Stack address; this needs to be lowered in target-dependent fashion.
// EmitTargetCodeForFrameDebugValue is responsible for allocation.
@@ -768,63 +768,63 @@ InstrEmitter::EmitDbgValue(SDDbgValue *SD,
}
MachineInstr *
-InstrEmitter::EmitDbgInstrRef(SDDbgValue *SD,
- DenseMap<SDValue, Register> &VRBaseMap) {
- // Instruction referencing is still in a prototype state: for now we're only
- // going to support SDNodes within a block. Copies are not supported, they
- // don't actually define a value.
- if (SD->getKind() != SDDbgValue::SDNODE)
- return nullptr;
-
- SDNode *Node = SD->getSDNode();
- SDValue Op = SDValue(Node, SD->getResNo());
- DenseMap<SDValue, Register>::iterator I = VRBaseMap.find(Op);
- if (I==VRBaseMap.end())
- return nullptr; // undef value: let EmitDbgValue produce a DBG_VALUE $noreg.
-
- MDNode *Var = SD->getVariable();
- MDNode *Expr = SD->getExpression();
- DebugLoc DL = SD->getDebugLoc();
-
- // Try to pick out a defining instruction at this point.
- unsigned VReg = getVR(Op, VRBaseMap);
- MachineInstr *ResultInstr = nullptr;
-
- // No definition corresponds to scenarios where a vreg is live-in to a block,
- // and doesn't have a defining instruction (yet). This can be patched up
- // later; at this early stage of implementation, fall back to using DBG_VALUE.
- if (!MRI->hasOneDef(VReg))
- return nullptr;
-
- MachineInstr &DefMI = *MRI->def_instr_begin(VReg);
- // Some target specific opcodes can become copies. As stated above, we're
- // ignoring those for now.
- if (DefMI.isCopy() || DefMI.getOpcode() == TargetOpcode::SUBREG_TO_REG)
- return nullptr;
-
- const MCInstrDesc &RefII = TII->get(TargetOpcode::DBG_INSTR_REF);
- auto MIB = BuildMI(*MF, DL, RefII);
-
- // Find the operand which defines the specified VReg.
- unsigned OperandIdx = 0;
- for (const auto &MO : DefMI.operands()) {
- if (MO.isReg() && MO.isDef() && MO.getReg() == VReg)
- break;
- ++OperandIdx;
- }
- assert(OperandIdx < DefMI.getNumOperands());
-
- // Make the DBG_INSTR_REF refer to that instruction, and that operand.
- unsigned InstrNum = DefMI.getDebugInstrNum();
- MIB.addImm(InstrNum);
- MIB.addImm(OperandIdx);
- MIB.addMetadata(Var);
- MIB.addMetadata(Expr);
- ResultInstr = &*MIB;
- return ResultInstr;
-}
-
-MachineInstr *
+InstrEmitter::EmitDbgInstrRef(SDDbgValue *SD,
+ DenseMap<SDValue, Register> &VRBaseMap) {
+ // Instruction referencing is still in a prototype state: for now we're only
+ // going to support SDNodes within a block. Copies are not supported, they
+ // don't actually define a value.
+ if (SD->getKind() != SDDbgValue::SDNODE)
+ return nullptr;
+
+ SDNode *Node = SD->getSDNode();
+ SDValue Op = SDValue(Node, SD->getResNo());
+ DenseMap<SDValue, Register>::iterator I = VRBaseMap.find(Op);
+ if (I==VRBaseMap.end())
+ return nullptr; // undef value: let EmitDbgValue produce a DBG_VALUE $noreg.
+
+ MDNode *Var = SD->getVariable();
+ MDNode *Expr = SD->getExpression();
+ DebugLoc DL = SD->getDebugLoc();
+
+ // Try to pick out a defining instruction at this point.
+ unsigned VReg = getVR(Op, VRBaseMap);
+ MachineInstr *ResultInstr = nullptr;
+
+ // No definition corresponds to scenarios where a vreg is live-in to a block,
+ // and doesn't have a defining instruction (yet). This can be patched up
+ // later; at this early stage of implementation, fall back to using DBG_VALUE.
+ if (!MRI->hasOneDef(VReg))
+ return nullptr;
+
+ MachineInstr &DefMI = *MRI->def_instr_begin(VReg);
+ // Some target specific opcodes can become copies. As stated above, we're
+ // ignoring those for now.
+ if (DefMI.isCopy() || DefMI.getOpcode() == TargetOpcode::SUBREG_TO_REG)
+ return nullptr;
+
+ const MCInstrDesc &RefII = TII->get(TargetOpcode::DBG_INSTR_REF);
+ auto MIB = BuildMI(*MF, DL, RefII);
+
+ // Find the operand which defines the specified VReg.
+ unsigned OperandIdx = 0;
+ for (const auto &MO : DefMI.operands()) {
+ if (MO.isReg() && MO.isDef() && MO.getReg() == VReg)
+ break;
+ ++OperandIdx;
+ }
+ assert(OperandIdx < DefMI.getNumOperands());
+
+ // Make the DBG_INSTR_REF refer to that instruction, and that operand.
+ unsigned InstrNum = DefMI.getDebugInstrNum();
+ MIB.addImm(InstrNum);
+ MIB.addImm(OperandIdx);
+ MIB.addMetadata(Var);
+ MIB.addMetadata(Expr);
+ ResultInstr = &*MIB;
+ return ResultInstr;
+}
+
+MachineInstr *
InstrEmitter::EmitDbgLabel(SDDbgLabel *SD) {
MDNode *Label = SD->getLabel();
DebugLoc DL = SD->getDebugLoc();
@@ -886,8 +886,8 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned,
NumDefs = NumResults;
}
ScratchRegs = TLI->getScratchRegisters((CallingConv::ID) CC);
- } else if (Opc == TargetOpcode::STATEPOINT) {
- NumDefs = NumResults;
+ } else if (Opc == TargetOpcode::STATEPOINT) {
+ NumDefs = NumResults;
}
unsigned NumImpUses = 0;
@@ -1037,22 +1037,22 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned,
if (!UsedRegs.empty() || II.getImplicitDefs() || II.hasOptionalDef())
MIB->setPhysRegsDeadExcept(UsedRegs, *TRI);
- // STATEPOINT is too 'dynamic' to have meaningful machine description.
- // We have to manually tie operands.
- if (Opc == TargetOpcode::STATEPOINT && NumDefs > 0) {
- assert(!HasPhysRegOuts && "STATEPOINT mishandled");
- MachineInstr *MI = MIB;
- unsigned Def = 0;
- int First = StatepointOpers(MI).getFirstGCPtrIdx();
- assert(First > 0 && "Statepoint has Defs but no GC ptr list");
- unsigned Use = (unsigned)First;
- while (Def < NumDefs) {
- if (MI->getOperand(Use).isReg())
- MI->tieOperands(Def++, Use);
- Use = StackMaps::getNextMetaArgIdx(MI, Use);
- }
- }
-
+ // STATEPOINT is too 'dynamic' to have meaningful machine description.
+ // We have to manually tie operands.
+ if (Opc == TargetOpcode::STATEPOINT && NumDefs > 0) {
+ assert(!HasPhysRegOuts && "STATEPOINT mishandled");
+ MachineInstr *MI = MIB;
+ unsigned Def = 0;
+ int First = StatepointOpers(MI).getFirstGCPtrIdx();
+ assert(First > 0 && "Statepoint has Defs but no GC ptr list");
+ unsigned Use = (unsigned)First;
+ while (Def < NumDefs) {
+ if (MI->getOperand(Use).isReg())
+ MI->tieOperands(Def++, Use);
+ Use = StackMaps::getNextMetaArgIdx(MI, Use);
+ }
+ }
+
// Run post-isel target hook to adjust this instruction if needed.
if (II.hasPostISelHook())
TLI->AdjustInstrPostInstrSelection(*MIB, Node);
@@ -1125,20 +1125,20 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned,
break;
}
- case ISD::PSEUDO_PROBE: {
- unsigned TarOp = TargetOpcode::PSEUDO_PROBE;
- auto Guid = cast<PseudoProbeSDNode>(Node)->getGuid();
- auto Index = cast<PseudoProbeSDNode>(Node)->getIndex();
- auto Attr = cast<PseudoProbeSDNode>(Node)->getAttributes();
-
- BuildMI(*MBB, InsertPos, Node->getDebugLoc(), TII->get(TarOp))
- .addImm(Guid)
- .addImm(Index)
- .addImm((uint8_t)PseudoProbeType::Block)
- .addImm(Attr);
- break;
- }
-
+ case ISD::PSEUDO_PROBE: {
+ unsigned TarOp = TargetOpcode::PSEUDO_PROBE;
+ auto Guid = cast<PseudoProbeSDNode>(Node)->getGuid();
+ auto Index = cast<PseudoProbeSDNode>(Node)->getIndex();
+ auto Attr = cast<PseudoProbeSDNode>(Node)->getAttributes();
+
+ BuildMI(*MBB, InsertPos, Node->getDebugLoc(), TII->get(TarOp))
+ .addImm(Guid)
+ .addImm(Index)
+ .addImm((uint8_t)PseudoProbeType::Block)
+ .addImm(Attr);
+ break;
+ }
+
case ISD::INLINEASM:
case ISD::INLINEASM_BR: {
unsigned NumOps = Node->getNumOperands();
@@ -1254,12 +1254,12 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned,
/// InstrEmitter - Construct an InstrEmitter and set it to start inserting
/// at the given position in the given block.
-InstrEmitter::InstrEmitter(const TargetMachine &TM, MachineBasicBlock *mbb,
+InstrEmitter::InstrEmitter(const TargetMachine &TM, MachineBasicBlock *mbb,
MachineBasicBlock::iterator insertpos)
: MF(mbb->getParent()), MRI(&MF->getRegInfo()),
TII(MF->getSubtarget().getInstrInfo()),
TRI(MF->getSubtarget().getRegisterInfo()),
TLI(MF->getSubtarget().getTargetLowering()), MBB(mbb),
- InsertPos(insertpos) {
- EmitDebugInstrRefs = TM.Options.ValueTrackingVariableLocations;
-}
+ InsertPos(insertpos) {
+ EmitDebugInstrRefs = TM.Options.ValueTrackingVariableLocations;
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/InstrEmitter.h b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/InstrEmitter.h
index 78d19cde4c..09658b8143 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/InstrEmitter.h
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/InstrEmitter.h
@@ -26,7 +26,7 @@ class MCInstrDesc;
class SDDbgLabel;
class SDDbgValue;
class TargetLowering;
-class TargetMachine;
+class TargetMachine;
class LLVM_LIBRARY_VISIBILITY InstrEmitter {
MachineFunction *MF;
@@ -38,9 +38,9 @@ class LLVM_LIBRARY_VISIBILITY InstrEmitter {
MachineBasicBlock *MBB;
MachineBasicBlock::iterator InsertPos;
- /// Should we try to produce DBG_INSTR_REF instructions?
- bool EmitDebugInstrRefs;
-
+ /// Should we try to produce DBG_INSTR_REF instructions?
+ bool EmitDebugInstrRefs;
+
/// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
/// implicit physical register output.
void EmitCopyFromReg(SDNode *Node, unsigned ResNo,
@@ -113,11 +113,11 @@ public:
MachineInstr *EmitDbgValue(SDDbgValue *SD,
DenseMap<SDValue, Register> &VRBaseMap);
- /// Attempt to emit a dbg_value as a DBG_INSTR_REF. May fail and return
- /// nullptr, in which case we fall back to plain EmitDbgValue.
- MachineInstr *EmitDbgInstrRef(SDDbgValue *SD,
- DenseMap<SDValue, Register> &VRBaseMap);
-
+ /// Attempt to emit a dbg_value as a DBG_INSTR_REF. May fail and return
+ /// nullptr, in which case we fall back to plain EmitDbgValue.
+ MachineInstr *EmitDbgInstrRef(SDDbgValue *SD,
+ DenseMap<SDValue, Register> &VRBaseMap);
+
/// Generate machine instruction for a dbg_label node.
MachineInstr *EmitDbgLabel(SDDbgLabel *SD);
@@ -139,8 +139,8 @@ public:
/// InstrEmitter - Construct an InstrEmitter and set it to start inserting
/// at the given position in the given block.
- InstrEmitter(const TargetMachine &TM, MachineBasicBlock *mbb,
- MachineBasicBlock::iterator insertpos);
+ InstrEmitter(const TargetMachine &TM, MachineBasicBlock *mbb,
+ MachineBasicBlock::iterator insertpos);
private:
void EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned,
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 8530a0f43a..62d7191036 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -173,17 +173,17 @@ private:
SDValue NewIntValue) const;
SDValue ExpandFCOPYSIGN(SDNode *Node) const;
SDValue ExpandFABS(SDNode *Node) const;
- SDValue ExpandFNEG(SDNode *Node) const;
+ SDValue ExpandFNEG(SDNode *Node) const;
SDValue ExpandLegalINT_TO_FP(SDNode *Node, SDValue &Chain);
void PromoteLegalINT_TO_FP(SDNode *N, const SDLoc &dl,
SmallVectorImpl<SDValue> &Results);
void PromoteLegalFP_TO_INT(SDNode *N, const SDLoc &dl,
SmallVectorImpl<SDValue> &Results);
- SDValue PromoteLegalFP_TO_INT_SAT(SDNode *Node, const SDLoc &dl);
+ SDValue PromoteLegalFP_TO_INT_SAT(SDNode *Node, const SDLoc &dl);
SDValue ExpandBITREVERSE(SDValue Op, const SDLoc &dl);
SDValue ExpandBSWAP(SDValue Op, const SDLoc &dl);
- SDValue ExpandPARITY(SDValue Op, const SDLoc &dl);
+ SDValue ExpandPARITY(SDValue Op, const SDLoc &dl);
SDValue ExpandExtractFromVectorThroughStack(SDValue Op);
SDValue ExpandInsertToVectorThroughStack(SDValue Op);
@@ -438,16 +438,16 @@ SDValue SelectionDAGLegalize::OptimizeFloatStore(StoreSDNode* ST) {
// We generally can't do this one for long doubles.
SDValue Chain = ST->getChain();
SDValue Ptr = ST->getBasePtr();
- SDValue Value = ST->getValue();
+ SDValue Value = ST->getValue();
MachineMemOperand::Flags MMOFlags = ST->getMemOperand()->getFlags();
AAMDNodes AAInfo = ST->getAAInfo();
SDLoc dl(ST);
-
- // Don't optimise TargetConstantFP
- if (Value.getOpcode() == ISD::TargetConstantFP)
- return SDValue();
-
- if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Value)) {
+
+ // Don't optimise TargetConstantFP
+ if (Value.getOpcode() == ISD::TargetConstantFP)
+ return SDValue();
+
+ if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Value)) {
if (CFP->getValueType(0) == MVT::f32 &&
TLI.isTypeLegal(MVT::i32)) {
SDValue Con = DAG.getConstant(CFP->getValueAPF().
@@ -478,7 +478,7 @@ SDValue SelectionDAGLegalize::OptimizeFloatStore(StoreSDNode* ST) {
Lo = DAG.getStore(Chain, dl, Lo, Ptr, ST->getPointerInfo(),
ST->getOriginalAlign(), MMOFlags, AAInfo);
- Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(4), dl);
+ Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(4), dl);
Hi = DAG.getStore(Chain, dl, Hi, Ptr,
ST->getPointerInfo().getWithOffset(4),
ST->getOriginalAlign(), MMOFlags, AAInfo);
@@ -487,7 +487,7 @@ SDValue SelectionDAGLegalize::OptimizeFloatStore(StoreSDNode* ST) {
}
}
}
- return SDValue();
+ return SDValue();
}
void SelectionDAGLegalize::LegalizeStoreOps(SDNode *Node) {
@@ -548,29 +548,29 @@ void SelectionDAGLegalize::LegalizeStoreOps(SDNode *Node) {
LLVM_DEBUG(dbgs() << "Legalizing truncating store operations\n");
SDValue Value = ST->getValue();
EVT StVT = ST->getMemoryVT();
- TypeSize StWidth = StVT.getSizeInBits();
- TypeSize StSize = StVT.getStoreSizeInBits();
+ TypeSize StWidth = StVT.getSizeInBits();
+ TypeSize StSize = StVT.getStoreSizeInBits();
auto &DL = DAG.getDataLayout();
- if (StWidth != StSize) {
+ if (StWidth != StSize) {
// Promote to a byte-sized store with upper bits zero if not
// storing an integral number of bytes. For example, promote
// TRUNCSTORE:i1 X -> TRUNCSTORE:i8 (and X, 1)
- EVT NVT = EVT::getIntegerVT(*DAG.getContext(), StSize.getFixedSize());
+ EVT NVT = EVT::getIntegerVT(*DAG.getContext(), StSize.getFixedSize());
Value = DAG.getZeroExtendInReg(Value, dl, StVT);
SDValue Result =
DAG.getTruncStore(Chain, dl, Value, Ptr, ST->getPointerInfo(), NVT,
ST->getOriginalAlign(), MMOFlags, AAInfo);
ReplaceNode(SDValue(Node, 0), Result);
- } else if (!StVT.isVector() && !isPowerOf2_64(StWidth.getFixedSize())) {
+ } else if (!StVT.isVector() && !isPowerOf2_64(StWidth.getFixedSize())) {
// If not storing a power-of-2 number of bits, expand as two stores.
assert(!StVT.isVector() && "Unsupported truncstore!");
- unsigned StWidthBits = StWidth.getFixedSize();
- unsigned LogStWidth = Log2_32(StWidthBits);
+ unsigned StWidthBits = StWidth.getFixedSize();
+ unsigned LogStWidth = Log2_32(StWidthBits);
assert(LogStWidth < 32);
unsigned RoundWidth = 1 << LogStWidth;
- assert(RoundWidth < StWidthBits);
- unsigned ExtraWidth = StWidthBits - RoundWidth;
+ assert(RoundWidth < StWidthBits);
+ unsigned ExtraWidth = StWidthBits - RoundWidth;
assert(ExtraWidth < RoundWidth);
assert(!(RoundWidth % 8) && !(ExtraWidth % 8) &&
"Store size not an integral number of bytes!");
@@ -587,7 +587,7 @@ void SelectionDAGLegalize::LegalizeStoreOps(SDNode *Node) {
// Store the remaining ExtraWidth bits.
IncrementSize = RoundWidth / 8;
- Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(IncrementSize), dl);
+ Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(IncrementSize), dl);
Hi = DAG.getNode(
ISD::SRL, dl, Value.getValueType(), Value,
DAG.getConstant(RoundWidth, dl,
@@ -727,7 +727,7 @@ void SelectionDAGLegalize::LegalizeLoadOps(SDNode *Node) {
LLVM_DEBUG(dbgs() << "Legalizing extending load operation\n");
EVT SrcVT = LD->getMemoryVT();
- TypeSize SrcWidth = SrcVT.getSizeInBits();
+ TypeSize SrcWidth = SrcVT.getSizeInBits();
MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
AAMDNodes AAInfo = LD->getAAInfo();
@@ -773,15 +773,15 @@ void SelectionDAGLegalize::LegalizeLoadOps(SDNode *Node) {
Value = Result;
Chain = Ch;
- } else if (!isPowerOf2_64(SrcWidth.getKnownMinSize())) {
+ } else if (!isPowerOf2_64(SrcWidth.getKnownMinSize())) {
// If not loading a power-of-2 number of bits, expand as two loads.
assert(!SrcVT.isVector() && "Unsupported extload!");
- unsigned SrcWidthBits = SrcWidth.getFixedSize();
- unsigned LogSrcWidth = Log2_32(SrcWidthBits);
+ unsigned SrcWidthBits = SrcWidth.getFixedSize();
+ unsigned LogSrcWidth = Log2_32(SrcWidthBits);
assert(LogSrcWidth < 32);
unsigned RoundWidth = 1 << LogSrcWidth;
- assert(RoundWidth < SrcWidthBits);
- unsigned ExtraWidth = SrcWidthBits - RoundWidth;
+ assert(RoundWidth < SrcWidthBits);
+ unsigned ExtraWidth = SrcWidthBits - RoundWidth;
assert(ExtraWidth < RoundWidth);
assert(!(RoundWidth % 8) && !(ExtraWidth % 8) &&
"Load size not an integral number of bytes!");
@@ -800,7 +800,7 @@ void SelectionDAGLegalize::LegalizeLoadOps(SDNode *Node) {
// Load the remaining ExtraWidth bits.
IncrementSize = RoundWidth / 8;
- Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(IncrementSize), dl);
+ Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(IncrementSize), dl);
Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Chain, Ptr,
LD->getPointerInfo().getWithOffset(IncrementSize),
ExtraVT, LD->getOriginalAlign(), MMOFlags, AAInfo);
@@ -828,7 +828,7 @@ void SelectionDAGLegalize::LegalizeLoadOps(SDNode *Node) {
// Load the remaining ExtraWidth bits.
IncrementSize = RoundWidth / 8;
- Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(IncrementSize), dl);
+ Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(IncrementSize), dl);
Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, Node->getValueType(0), Chain, Ptr,
LD->getPointerInfo().getWithOffset(IncrementSize),
ExtraVT, LD->getOriginalAlign(), MMOFlags, AAInfo);
@@ -1113,18 +1113,18 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
// They'll be converted to Copy(To/From)Reg.
Action = TargetLowering::Legal;
break;
- case ISD::UBSANTRAP:
- Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
- if (Action == TargetLowering::Expand) {
- // replace ISD::UBSANTRAP with ISD::TRAP
- SDValue NewVal;
- NewVal = DAG.getNode(ISD::TRAP, SDLoc(Node), Node->getVTList(),
- Node->getOperand(0));
- ReplaceNode(Node, NewVal.getNode());
- LegalizeOp(NewVal.getNode());
- return;
- }
- break;
+ case ISD::UBSANTRAP:
+ Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
+ if (Action == TargetLowering::Expand) {
+ // replace ISD::UBSANTRAP with ISD::TRAP
+ SDValue NewVal;
+ NewVal = DAG.getNode(ISD::TRAP, SDLoc(Node), Node->getVTList(),
+ Node->getOperand(0));
+ ReplaceNode(Node, NewVal.getNode());
+ LegalizeOp(NewVal.getNode());
+ return;
+ }
+ break;
case ISD::DEBUGTRAP:
Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
if (Action == TargetLowering::Expand) {
@@ -1140,11 +1140,11 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
case ISD::SADDSAT:
case ISD::UADDSAT:
case ISD::SSUBSAT:
- case ISD::USUBSAT:
- case ISD::SSHLSAT:
- case ISD::USHLSAT:
- case ISD::FP_TO_SINT_SAT:
- case ISD::FP_TO_UINT_SAT:
+ case ISD::USUBSAT:
+ case ISD::SSHLSAT:
+ case ISD::USHLSAT:
+ case ISD::FP_TO_SINT_SAT:
+ case ISD::FP_TO_UINT_SAT:
Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
break;
case ISD::SMULFIX:
@@ -1184,10 +1184,10 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
Action = TLI.getOperationAction(
Node->getOpcode(), Node->getOperand(0).getValueType());
break;
- case ISD::VECREDUCE_SEQ_FADD:
- Action = TLI.getOperationAction(
- Node->getOpcode(), Node->getOperand(1).getValueType());
- break;
+ case ISD::VECREDUCE_SEQ_FADD:
+ Action = TLI.getOperationAction(
+ Node->getOpcode(), Node->getOperand(1).getValueType());
+ break;
default:
if (Node->getOpcode() >= ISD::BUILTIN_OP_END) {
Action = TargetLowering::Legal;
@@ -1440,12 +1440,12 @@ SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) {
SmallVector<SDValue, 8> Stores;
unsigned TypeByteSize = MemVT.getSizeInBits() / 8;
assert(TypeByteSize > 0 && "Vector element type too small for stack store!");
-
- // If the destination vector element type of a BUILD_VECTOR is narrower than
- // the source element type, only store the bits necessary.
- bool Truncate = isa<BuildVectorSDNode>(Node) &&
- MemVT.bitsLT(Node->getOperand(0).getValueType());
-
+
+ // If the destination vector element type of a BUILD_VECTOR is narrower than
+ // the source element type, only store the bits necessary.
+ bool Truncate = isa<BuildVectorSDNode>(Node) &&
+ MemVT.bitsLT(Node->getOperand(0).getValueType());
+
// Store (in the right endianness) the elements to memory.
for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
// Ignore undef elements.
@@ -1453,9 +1453,9 @@ SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) {
unsigned Offset = TypeByteSize*i;
- SDValue Idx = DAG.getMemBasePlusOffset(FIPtr, TypeSize::Fixed(Offset), dl);
+ SDValue Idx = DAG.getMemBasePlusOffset(FIPtr, TypeSize::Fixed(Offset), dl);
- if (Truncate)
+ if (Truncate)
Stores.push_back(DAG.getTruncStore(DAG.getEntryNode(), dl,
Node->getOperand(i), Idx,
PtrInfo.getWithOffset(Offset), MemVT));
@@ -1481,7 +1481,7 @@ void SelectionDAGLegalize::getSignAsIntValue(FloatSignAsInt &State,
const SDLoc &DL,
SDValue Value) const {
EVT FloatVT = Value.getValueType();
- unsigned NumBits = FloatVT.getScalarSizeInBits();
+ unsigned NumBits = FloatVT.getScalarSizeInBits();
State.FloatVT = FloatVT;
EVT IVT = EVT::getIntegerVT(*DAG.getContext(), NumBits);
// Convert to an integer of the same size.
@@ -1513,9 +1513,9 @@ void SelectionDAGLegalize::getSignAsIntValue(FloatSignAsInt &State,
State.IntPointerInfo = State.FloatPointerInfo;
} else {
// Advance the pointer so that the loaded byte will contain the sign bit.
- unsigned ByteOffset = (NumBits / 8) - 1;
- IntPtr =
- DAG.getMemBasePlusOffset(StackPtr, TypeSize::Fixed(ByteOffset), DL);
+ unsigned ByteOffset = (NumBits / 8) - 1;
+ IntPtr =
+ DAG.getMemBasePlusOffset(StackPtr, TypeSize::Fixed(ByteOffset), DL);
State.IntPointerInfo = MachinePointerInfo::getFixedStack(MF, FI,
ByteOffset);
}
@@ -1523,7 +1523,7 @@ void SelectionDAGLegalize::getSignAsIntValue(FloatSignAsInt &State,
State.IntPtr = IntPtr;
State.IntValue = DAG.getExtLoad(ISD::EXTLOAD, DL, LoadTy, State.Chain, IntPtr,
State.IntPointerInfo, MVT::i8);
- State.SignMask = APInt::getOneBitSet(LoadTy.getScalarSizeInBits(), 7);
+ State.SignMask = APInt::getOneBitSet(LoadTy.getScalarSizeInBits(), 7);
State.SignBit = 7;
}
@@ -1578,8 +1578,8 @@ SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode *Node) const {
// Get the signbit at the right position for MagAsInt.
int ShiftAmount = SignAsInt.SignBit - MagAsInt.SignBit;
EVT ShiftVT = IntVT;
- if (SignBit.getScalarValueSizeInBits() <
- ClearedSign.getScalarValueSizeInBits()) {
+ if (SignBit.getScalarValueSizeInBits() <
+ ClearedSign.getScalarValueSizeInBits()) {
SignBit = DAG.getNode(ISD::ZERO_EXTEND, DL, MagVT, SignBit);
ShiftVT = MagVT;
}
@@ -1590,8 +1590,8 @@ SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode *Node) const {
SDValue ShiftCnst = DAG.getConstant(-ShiftAmount, DL, ShiftVT);
SignBit = DAG.getNode(ISD::SHL, DL, ShiftVT, SignBit, ShiftCnst);
}
- if (SignBit.getScalarValueSizeInBits() >
- ClearedSign.getScalarValueSizeInBits()) {
+ if (SignBit.getScalarValueSizeInBits() >
+ ClearedSign.getScalarValueSizeInBits()) {
SignBit = DAG.getNode(ISD::TRUNCATE, DL, MagVT, SignBit);
}
@@ -1600,22 +1600,22 @@ SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode *Node) const {
return modifySignAsInt(MagAsInt, DL, CopiedSign);
}
-SDValue SelectionDAGLegalize::ExpandFNEG(SDNode *Node) const {
- // Get the sign bit as an integer.
- SDLoc DL(Node);
- FloatSignAsInt SignAsInt;
- getSignAsIntValue(SignAsInt, DL, Node->getOperand(0));
- EVT IntVT = SignAsInt.IntValue.getValueType();
-
- // Flip the sign.
- SDValue SignMask = DAG.getConstant(SignAsInt.SignMask, DL, IntVT);
- SDValue SignFlip =
- DAG.getNode(ISD::XOR, DL, IntVT, SignAsInt.IntValue, SignMask);
-
- // Convert back to float.
- return modifySignAsInt(SignAsInt, DL, SignFlip);
-}
-
+SDValue SelectionDAGLegalize::ExpandFNEG(SDNode *Node) const {
+ // Get the sign bit as an integer.
+ SDLoc DL(Node);
+ FloatSignAsInt SignAsInt;
+ getSignAsIntValue(SignAsInt, DL, Node->getOperand(0));
+ EVT IntVT = SignAsInt.IntValue.getValueType();
+
+ // Flip the sign.
+ SDValue SignMask = DAG.getConstant(SignAsInt.SignMask, DL, IntVT);
+ SDValue SignFlip =
+ DAG.getNode(ISD::XOR, DL, IntVT, SignAsInt.IntValue, SignMask);
+
+ // Convert back to float.
+ return modifySignAsInt(SignAsInt, DL, SignFlip);
+}
+
SDValue SelectionDAGLegalize::ExpandFABS(SDNode *Node) const {
SDLoc DL(Node);
SDValue Value = Node->getOperand(0);
@@ -1639,7 +1639,7 @@ SDValue SelectionDAGLegalize::ExpandFABS(SDNode *Node) const {
void SelectionDAGLegalize::ExpandDYNAMIC_STACKALLOC(SDNode* Node,
SmallVectorImpl<SDValue> &Results) {
- Register SPReg = TLI.getStackPointerRegisterToSaveRestore();
+ Register SPReg = TLI.getStackPointerRegisterToSaveRestore();
assert(SPReg && "Target cannot require DYNAMIC_STACKALLOC expansion and"
" not tell us which reg is the stack pointer!");
SDLoc dl(Node);
@@ -1733,36 +1733,36 @@ bool SelectionDAGLegalize::LegalizeSetCCCondCode(
unsigned Opc = 0;
switch (CCCode) {
default: llvm_unreachable("Don't know how to expand this condition!");
- case ISD::SETUO:
- if (TLI.isCondCodeLegal(ISD::SETUNE, OpVT)) {
- CC1 = ISD::SETUNE; CC2 = ISD::SETUNE; Opc = ISD::OR;
- break;
- }
- assert(TLI.isCondCodeLegal(ISD::SETOEQ, OpVT) &&
- "If SETUE is expanded, SETOEQ or SETUNE must be legal!");
- NeedInvert = true;
- LLVM_FALLTHROUGH;
+ case ISD::SETUO:
+ if (TLI.isCondCodeLegal(ISD::SETUNE, OpVT)) {
+ CC1 = ISD::SETUNE; CC2 = ISD::SETUNE; Opc = ISD::OR;
+ break;
+ }
+ assert(TLI.isCondCodeLegal(ISD::SETOEQ, OpVT) &&
+ "If SETUE is expanded, SETOEQ or SETUNE must be legal!");
+ NeedInvert = true;
+ LLVM_FALLTHROUGH;
case ISD::SETO:
assert(TLI.isCondCodeLegal(ISD::SETOEQ, OpVT)
&& "If SETO is expanded, SETOEQ must be legal!");
CC1 = ISD::SETOEQ; CC2 = ISD::SETOEQ; Opc = ISD::AND; break;
- case ISD::SETONE:
- case ISD::SETUEQ:
- // If the SETUO or SETO CC isn't legal, we might be able to use
- // SETOGT || SETOLT, inverting the result for SETUEQ. We only need one
- // of SETOGT/SETOLT to be legal, the other can be emulated by swapping
- // the operands.
- CC2 = ((unsigned)CCCode & 0x8U) ? ISD::SETUO : ISD::SETO;
- if (!TLI.isCondCodeLegal(CC2, OpVT) &&
- (TLI.isCondCodeLegal(ISD::SETOGT, OpVT) ||
- TLI.isCondCodeLegal(ISD::SETOLT, OpVT))) {
- CC1 = ISD::SETOGT;
- CC2 = ISD::SETOLT;
- Opc = ISD::OR;
- NeedInvert = ((unsigned)CCCode & 0x8U);
- break;
- }
- LLVM_FALLTHROUGH;
+ case ISD::SETONE:
+ case ISD::SETUEQ:
+ // If the SETUO or SETO CC isn't legal, we might be able to use
+ // SETOGT || SETOLT, inverting the result for SETUEQ. We only need one
+ // of SETOGT/SETOLT to be legal, the other can be emulated by swapping
+ // the operands.
+ CC2 = ((unsigned)CCCode & 0x8U) ? ISD::SETUO : ISD::SETO;
+ if (!TLI.isCondCodeLegal(CC2, OpVT) &&
+ (TLI.isCondCodeLegal(ISD::SETOGT, OpVT) ||
+ TLI.isCondCodeLegal(ISD::SETOLT, OpVT))) {
+ CC1 = ISD::SETOGT;
+ CC2 = ISD::SETOLT;
+ Opc = ISD::OR;
+ NeedInvert = ((unsigned)CCCode & 0x8U);
+ break;
+ }
+ LLVM_FALLTHROUGH;
case ISD::SETOEQ:
case ISD::SETOGT:
case ISD::SETOGE:
@@ -1799,16 +1799,16 @@ bool SelectionDAGLegalize::LegalizeSetCCCondCode(
if (CCCode != ISD::SETO && CCCode != ISD::SETUO) {
// If we aren't the ordered or unorder operation,
// then the pattern is (LHS CC1 RHS) Opc (LHS CC2 RHS).
- SetCC1 = DAG.getSetCC(dl, VT, LHS, RHS, CC1, Chain,
- IsSignaling);
- SetCC2 = DAG.getSetCC(dl, VT, LHS, RHS, CC2, Chain,
- IsSignaling);
+ SetCC1 = DAG.getSetCC(dl, VT, LHS, RHS, CC1, Chain,
+ IsSignaling);
+ SetCC2 = DAG.getSetCC(dl, VT, LHS, RHS, CC2, Chain,
+ IsSignaling);
} else {
// Otherwise, the pattern is (LHS CC1 LHS) Opc (RHS CC2 RHS)
- SetCC1 = DAG.getSetCC(dl, VT, LHS, LHS, CC1, Chain,
- IsSignaling);
- SetCC2 = DAG.getSetCC(dl, VT, RHS, RHS, CC2, Chain,
- IsSignaling);
+ SetCC1 = DAG.getSetCC(dl, VT, LHS, LHS, CC1, Chain,
+ IsSignaling);
+ SetCC2 = DAG.getSetCC(dl, VT, RHS, RHS, CC2, Chain,
+ IsSignaling);
}
if (Chain)
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, SetCC1.getValue(1),
@@ -1834,23 +1834,23 @@ SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp, EVT SlotVT,
SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp, EVT SlotVT,
EVT DestVT, const SDLoc &dl,
SDValue Chain) {
- unsigned SrcSize = SrcOp.getValueSizeInBits();
- unsigned SlotSize = SlotVT.getSizeInBits();
- unsigned DestSize = DestVT.getSizeInBits();
- Type *DestType = DestVT.getTypeForEVT(*DAG.getContext());
- Align DestAlign = DAG.getDataLayout().getPrefTypeAlign(DestType);
-
- // Don't convert with stack if the load/store is expensive.
- if ((SrcSize > SlotSize &&
- !TLI.isTruncStoreLegalOrCustom(SrcOp.getValueType(), SlotVT)) ||
- (SlotSize < DestSize &&
- !TLI.isLoadExtLegalOrCustom(ISD::EXTLOAD, DestVT, SlotVT)))
- return SDValue();
-
+ unsigned SrcSize = SrcOp.getValueSizeInBits();
+ unsigned SlotSize = SlotVT.getSizeInBits();
+ unsigned DestSize = DestVT.getSizeInBits();
+ Type *DestType = DestVT.getTypeForEVT(*DAG.getContext());
+ Align DestAlign = DAG.getDataLayout().getPrefTypeAlign(DestType);
+
+ // Don't convert with stack if the load/store is expensive.
+ if ((SrcSize > SlotSize &&
+ !TLI.isTruncStoreLegalOrCustom(SrcOp.getValueType(), SlotVT)) ||
+ (SlotSize < DestSize &&
+ !TLI.isLoadExtLegalOrCustom(ISD::EXTLOAD, DestVT, SlotVT)))
+ return SDValue();
+
// Create the stack frame object.
- Align SrcAlign = DAG.getDataLayout().getPrefTypeAlign(
+ Align SrcAlign = DAG.getDataLayout().getPrefTypeAlign(
SrcOp.getValueType().getTypeForEVT(*DAG.getContext()));
- SDValue FIPtr = DAG.CreateStackTemporary(SlotVT.getStoreSize(), SrcAlign);
+ SDValue FIPtr = DAG.CreateStackTemporary(SlotVT.getStoreSize(), SrcAlign);
FrameIndexSDNode *StackPtrFI = cast<FrameIndexSDNode>(FIPtr);
int SPFI = StackPtrFI->getIndex();
@@ -1861,7 +1861,7 @@ SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp, EVT SlotVT,
// later than DestVT.
SDValue Store;
- if (SrcSize > SlotSize)
+ if (SrcSize > SlotSize)
Store = DAG.getTruncStore(Chain, dl, SrcOp, FIPtr, PtrInfo,
SlotVT, SrcAlign);
else {
@@ -1873,7 +1873,7 @@ SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp, EVT SlotVT,
// Result is a load from the stack slot.
if (SlotSize == DestSize)
return DAG.getLoad(DestVT, dl, Store, FIPtr, PtrInfo, DestAlign);
-
+
assert(SlotSize < DestSize && "Unknown extension!");
return DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT, Store, FIPtr, PtrInfo, SlotVT,
DestAlign);
@@ -2194,7 +2194,7 @@ void SelectionDAGLegalize::ExpandFPLibCall(SDNode* Node,
if (Node->isStrictFPOpcode()) {
EVT RetVT = Node->getValueType(0);
- SmallVector<SDValue, 4> Ops(drop_begin(Node->ops()));
+ SmallVector<SDValue, 4> Ops(drop_begin(Node->ops()));
TargetLowering::MakeLibCallOptions CallOptions;
// FIXME: This doesn't support tail calls.
std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, RetVT,
@@ -2444,11 +2444,11 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(SDNode *Node,
// TODO: Should any fast-math-flags be set for the created nodes?
LLVM_DEBUG(dbgs() << "Legalizing INT_TO_FP\n");
- if (SrcVT == MVT::i32 && TLI.isTypeLegal(MVT::f64) &&
- (DestVT.bitsLE(MVT::f64) ||
- TLI.isOperationLegal(Node->isStrictFPOpcode() ? ISD::STRICT_FP_EXTEND
- : ISD::FP_EXTEND,
- DestVT))) {
+ if (SrcVT == MVT::i32 && TLI.isTypeLegal(MVT::f64) &&
+ (DestVT.bitsLE(MVT::f64) ||
+ TLI.isOperationLegal(Node->isStrictFPOpcode() ? ISD::STRICT_FP_EXTEND
+ : ISD::FP_EXTEND,
+ DestVT))) {
LLVM_DEBUG(dbgs() << "32-bit [signed|unsigned] integer to float/double "
"expansion\n");
@@ -2475,7 +2475,7 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(SDNode *Node,
SDValue Store1 = DAG.getStore(MemChain, dl, Lo, StackSlot,
MachinePointerInfo());
// Store the hi of the constructed double.
- SDValue HiPtr = DAG.getMemBasePlusOffset(StackSlot, TypeSize::Fixed(4), dl);
+ SDValue HiPtr = DAG.getMemBasePlusOffset(StackSlot, TypeSize::Fixed(4), dl);
SDValue Store2 =
DAG.getStore(MemChain, dl, Hi, HiPtr, MachinePointerInfo());
MemChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1, Store2);
@@ -2511,23 +2511,23 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(SDNode *Node,
return Result;
}
- if (isSigned)
- return SDValue();
-
+ if (isSigned)
+ return SDValue();
+
// TODO: Generalize this for use with other types.
- if (((SrcVT == MVT::i32 || SrcVT == MVT::i64) && DestVT == MVT::f32) ||
- (SrcVT == MVT::i64 && DestVT == MVT::f64)) {
- LLVM_DEBUG(dbgs() << "Converting unsigned i32/i64 to f32/f64\n");
+ if (((SrcVT == MVT::i32 || SrcVT == MVT::i64) && DestVT == MVT::f32) ||
+ (SrcVT == MVT::i64 && DestVT == MVT::f64)) {
+ LLVM_DEBUG(dbgs() << "Converting unsigned i32/i64 to f32/f64\n");
// For unsigned conversions, convert them to signed conversions using the
// algorithm from the x86_64 __floatundisf in compiler_rt. That method
// should be valid for i32->f32 as well.
- // More generally this transform should be valid if there are 3 more bits
- // in the integer type than the significand. Rounding uses the first bit
- // after the width of the significand and the OR of all bits after that. So
- // we need to be able to OR the shifted out bit into one of the bits that
- // participate in the OR.
-
+ // More generally this transform should be valid if there are 3 more bits
+ // in the integer type than the significand. Rounding uses the first bit
+ // after the width of the significand and the OR of all bits after that. So
+ // we need to be able to OR the shifted out bit into one of the bits that
+ // participate in the OR.
+
// TODO: This really should be implemented using a branch rather than a
// select. We happen to get lucky and machinesink does the right
// thing most of the time. This would be a good candidate for a
@@ -2571,11 +2571,11 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(SDNode *Node,
return DAG.getSelect(dl, DestVT, SignBitTest, Slow, Fast);
}
- // Don't expand it if there isn't cheap fadd.
- if (!TLI.isOperationLegalOrCustom(
- Node->isStrictFPOpcode() ? ISD::STRICT_FADD : ISD::FADD, DestVT))
- return SDValue();
-
+ // Don't expand it if there isn't cheap fadd.
+ if (!TLI.isOperationLegalOrCustom(
+ Node->isStrictFPOpcode() ? ISD::STRICT_FADD : ISD::FADD, DestVT))
+ return SDValue();
+
// The following optimization is valid only if every value in SrcVT (when
// treated as signed) is representable in DestVT. Check that the mantissa
// size of DestVT is >= than the number of bits in SrcVT -1.
@@ -2602,8 +2602,8 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(SDNode *Node,
// offset depending on the data type.
uint64_t FF;
switch (SrcVT.getSimpleVT().SimpleTy) {
- default:
- return SDValue();
+ default:
+ return SDValue();
case MVT::i8 : FF = 0x43800000ULL; break; // 2^8 (as a float)
case MVT::i16: FF = 0x47800000ULL; break; // 2^16 (as a float)
case MVT::i32: FF = 0x4F800000ULL; break; // 2^32 (as a float)
@@ -2758,30 +2758,30 @@ void SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDNode *N, const SDLoc &dl,
Results.push_back(Operation.getValue(1));
}
-/// Promote FP_TO_*INT_SAT operation to a larger result type. At this point
-/// the result and operand types are legal and there must be a legal
-/// FP_TO_*INT_SAT operation for a larger result type.
-SDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT_SAT(SDNode *Node,
- const SDLoc &dl) {
- unsigned Opcode = Node->getOpcode();
-
- // Scan for the appropriate larger type to use.
- EVT NewOutTy = Node->getValueType(0);
- while (true) {
- NewOutTy = (MVT::SimpleValueType)(NewOutTy.getSimpleVT().SimpleTy + 1);
- assert(NewOutTy.isInteger() && "Ran out of possibilities!");
-
- if (TLI.isOperationLegalOrCustom(Opcode, NewOutTy))
- break;
- }
-
- // Saturation width is determined by second operand, so we don't have to
- // perform any fixup and can directly truncate the result.
- SDValue Result = DAG.getNode(Opcode, dl, NewOutTy, Node->getOperand(0),
- Node->getOperand(1));
- return DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), Result);
-}
-
+/// Promote FP_TO_*INT_SAT operation to a larger result type. At this point
+/// the result and operand types are legal and there must be a legal
+/// FP_TO_*INT_SAT operation for a larger result type.
+SDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT_SAT(SDNode *Node,
+ const SDLoc &dl) {
+ unsigned Opcode = Node->getOpcode();
+
+ // Scan for the appropriate larger type to use.
+ EVT NewOutTy = Node->getValueType(0);
+ while (true) {
+ NewOutTy = (MVT::SimpleValueType)(NewOutTy.getSimpleVT().SimpleTy + 1);
+ assert(NewOutTy.isInteger() && "Ran out of possibilities!");
+
+ if (TLI.isOperationLegalOrCustom(Opcode, NewOutTy))
+ break;
+ }
+
+ // Saturation width is determined by second operand, so we don't have to
+ // perform any fixup and can directly truncate the result.
+ SDValue Result = DAG.getNode(Opcode, dl, NewOutTy, Node->getOperand(0),
+ Node->getOperand(1));
+ return DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), Result);
+}
+
/// Legalize a BITREVERSE scalar/vector operation as a series of mask + shifts.
SDValue SelectionDAGLegalize::ExpandBITREVERSE(SDValue Op, const SDLoc &dl) {
EVT VT = Op.getValueType();
@@ -2898,28 +2898,28 @@ SDValue SelectionDAGLegalize::ExpandBSWAP(SDValue Op, const SDLoc &dl) {
}
}
-/// Open code the operations for PARITY of the specified operation.
-SDValue SelectionDAGLegalize::ExpandPARITY(SDValue Op, const SDLoc &dl) {
- EVT VT = Op.getValueType();
- EVT ShVT = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
- unsigned Sz = VT.getScalarSizeInBits();
-
- // If CTPOP is legal, use it. Otherwise use shifts and xor.
- SDValue Result;
- if (TLI.isOperationLegal(ISD::CTPOP, VT)) {
- Result = DAG.getNode(ISD::CTPOP, dl, VT, Op);
- } else {
- Result = Op;
- for (unsigned i = Log2_32_Ceil(Sz); i != 0;) {
- SDValue Shift = DAG.getNode(ISD::SRL, dl, VT, Result,
- DAG.getConstant(1ULL << (--i), dl, ShVT));
- Result = DAG.getNode(ISD::XOR, dl, VT, Result, Shift);
- }
- }
-
- return DAG.getNode(ISD::AND, dl, VT, Result, DAG.getConstant(1, dl, VT));
-}
-
+/// Open code the operations for PARITY of the specified operation.
+SDValue SelectionDAGLegalize::ExpandPARITY(SDValue Op, const SDLoc &dl) {
+ EVT VT = Op.getValueType();
+ EVT ShVT = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
+ unsigned Sz = VT.getScalarSizeInBits();
+
+ // If CTPOP is legal, use it. Otherwise use shifts and xor.
+ SDValue Result;
+ if (TLI.isOperationLegal(ISD::CTPOP, VT)) {
+ Result = DAG.getNode(ISD::CTPOP, dl, VT, Op);
+ } else {
+ Result = Op;
+ for (unsigned i = Log2_32_Ceil(Sz); i != 0;) {
+ SDValue Shift = DAG.getNode(ISD::SRL, dl, VT, Result,
+ DAG.getConstant(1ULL << (--i), dl, ShVT));
+ Result = DAG.getNode(ISD::XOR, dl, VT, Result, Shift);
+ }
+ }
+
+ return DAG.getNode(ISD::AND, dl, VT, Result, DAG.getConstant(1, dl, VT));
+}
+
bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
LLVM_DEBUG(dbgs() << "Trying to expand node\n");
SmallVector<SDValue, 8> Results;
@@ -2951,9 +2951,9 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
case ISD::BSWAP:
Results.push_back(ExpandBSWAP(Node->getOperand(0), dl));
break;
- case ISD::PARITY:
- Results.push_back(ExpandPARITY(Node->getOperand(0), dl));
- break;
+ case ISD::PARITY:
+ Results.push_back(ExpandPARITY(Node->getOperand(0), dl));
+ break;
case ISD::FRAMEADDR:
case ISD::RETURNADDR:
case ISD::FRAME_TO_ARGS_OFFSET:
@@ -3098,19 +3098,19 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
break;
// We fall back to use stack operation when the FP_ROUND operation
// isn't available.
- if ((Tmp1 = EmitStackConvert(Node->getOperand(1), Node->getValueType(0),
- Node->getValueType(0), dl,
- Node->getOperand(0)))) {
- ReplaceNode(Node, Tmp1.getNode());
- LLVM_DEBUG(dbgs() << "Successfully expanded STRICT_FP_ROUND node\n");
- return true;
- }
- break;
+ if ((Tmp1 = EmitStackConvert(Node->getOperand(1), Node->getValueType(0),
+ Node->getValueType(0), dl,
+ Node->getOperand(0)))) {
+ ReplaceNode(Node, Tmp1.getNode());
+ LLVM_DEBUG(dbgs() << "Successfully expanded STRICT_FP_ROUND node\n");
+ return true;
+ }
+ break;
case ISD::FP_ROUND:
case ISD::BITCAST:
- if ((Tmp1 = EmitStackConvert(Node->getOperand(0), Node->getValueType(0),
- Node->getValueType(0), dl)))
- Results.push_back(Tmp1);
+ if ((Tmp1 = EmitStackConvert(Node->getOperand(0), Node->getValueType(0),
+ Node->getValueType(0), dl)))
+ Results.push_back(Tmp1);
break;
case ISD::STRICT_FP_EXTEND:
// When strict mode is enforced we can't do expansion because it
@@ -3125,19 +3125,19 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
break;
// We fall back to use stack operation when the FP_EXTEND operation
// isn't available.
- if ((Tmp1 = EmitStackConvert(
- Node->getOperand(1), Node->getOperand(1).getValueType(),
- Node->getValueType(0), dl, Node->getOperand(0)))) {
- ReplaceNode(Node, Tmp1.getNode());
- LLVM_DEBUG(dbgs() << "Successfully expanded STRICT_FP_EXTEND node\n");
- return true;
- }
- break;
+ if ((Tmp1 = EmitStackConvert(
+ Node->getOperand(1), Node->getOperand(1).getValueType(),
+ Node->getValueType(0), dl, Node->getOperand(0)))) {
+ ReplaceNode(Node, Tmp1.getNode());
+ LLVM_DEBUG(dbgs() << "Successfully expanded STRICT_FP_EXTEND node\n");
+ return true;
+ }
+ break;
case ISD::FP_EXTEND:
- if ((Tmp1 = EmitStackConvert(Node->getOperand(0),
- Node->getOperand(0).getValueType(),
- Node->getValueType(0), dl)))
- Results.push_back(Tmp1);
+ if ((Tmp1 = EmitStackConvert(Node->getOperand(0),
+ Node->getOperand(0).getValueType(),
+ Node->getValueType(0), dl)))
+ Results.push_back(Tmp1);
break;
case ISD::SIGN_EXTEND_INREG: {
EVT ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT();
@@ -3182,11 +3182,11 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
LLVM_FALLTHROUGH;
case ISD::SINT_TO_FP:
case ISD::STRICT_SINT_TO_FP:
- if ((Tmp1 = ExpandLegalINT_TO_FP(Node, Tmp2))) {
- Results.push_back(Tmp1);
- if (Node->isStrictFPOpcode())
- Results.push_back(Tmp2);
- }
+ if ((Tmp1 = ExpandLegalINT_TO_FP(Node, Tmp2))) {
+ Results.push_back(Tmp1);
+ if (Node->isStrictFPOpcode())
+ Results.push_back(Tmp2);
+ }
break;
case ISD::FP_TO_SINT:
if (TLI.expandFP_TO_SINT(Node, Tmp1, DAG))
@@ -3213,10 +3213,10 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
return true;
}
break;
- case ISD::FP_TO_SINT_SAT:
- case ISD::FP_TO_UINT_SAT:
- Results.push_back(TLI.expandFP_TO_INT_SAT(Node, DAG));
- break;
+ case ISD::FP_TO_SINT_SAT:
+ case ISD::FP_TO_UINT_SAT:
+ Results.push_back(TLI.expandFP_TO_INT_SAT(Node, DAG));
+ break;
case ISD::VAARG:
Results.push_back(DAG.expandVAArg(Node));
Results.push_back(Results[0].getValue(1));
@@ -3345,7 +3345,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
case ISD::STACKSAVE:
// Expand to CopyFromReg if the target set
// StackPointerRegisterToSaveRestore.
- if (Register SP = TLI.getStackPointerRegisterToSaveRestore()) {
+ if (Register SP = TLI.getStackPointerRegisterToSaveRestore()) {
Results.push_back(DAG.getCopyFromReg(Node->getOperand(0), dl, SP,
Node->getValueType(0)));
Results.push_back(Results[0].getValue(1));
@@ -3357,7 +3357,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
case ISD::STACKRESTORE:
// Expand to CopyToReg if the target set
// StackPointerRegisterToSaveRestore.
- if (Register SP = TLI.getStackPointerRegisterToSaveRestore()) {
+ if (Register SP = TLI.getStackPointerRegisterToSaveRestore()) {
Results.push_back(DAG.getCopyToReg(Node->getOperand(0), dl, SP,
Node->getOperand(1)));
} else {
@@ -3372,7 +3372,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
Results.push_back(ExpandFCOPYSIGN(Node));
break;
case ISD::FNEG:
- Results.push_back(ExpandFNEG(Node));
+ Results.push_back(ExpandFNEG(Node));
break;
case ISD::FABS:
Results.push_back(ExpandFABS(Node));
@@ -3468,7 +3468,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
// Check to see if this FP immediate is already legal.
// If this is a legal constant, turn it into a TargetConstantFP node.
if (!TLI.isFPImmLegal(CFP->getValueAPF(), Node->getValueType(0),
- DAG.shouldOptForSize()))
+ DAG.shouldOptForSize()))
Results.push_back(ExpandConstantFP(CFP, true));
break;
}
@@ -3547,7 +3547,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
SmallVector<SDValue, 4> Halves;
EVT HalfType = EVT(VT).getHalfSizedIntegerVT(*DAG.getContext());
assert(TLI.isTypeLegal(HalfType));
- if (TLI.expandMUL_LOHI(Node->getOpcode(), VT, dl, LHS, RHS, Halves,
+ if (TLI.expandMUL_LOHI(Node->getOpcode(), VT, dl, LHS, RHS, Halves,
HalfType, DAG,
TargetLowering::MulExpansionKind::Always)) {
for (unsigned i = 0; i < 2; ++i) {
@@ -3616,7 +3616,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
break;
case ISD::ROTL:
case ISD::ROTR:
- if (TLI.expandROT(Node, true /*AllowVectorOps*/, Tmp1, DAG))
+ if (TLI.expandROT(Node, true /*AllowVectorOps*/, Tmp1, DAG))
Results.push_back(Tmp1);
break;
case ISD::SADDSAT:
@@ -3625,10 +3625,10 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
case ISD::USUBSAT:
Results.push_back(TLI.expandAddSubSat(Node, DAG));
break;
- case ISD::SSHLSAT:
- case ISD::USHLSAT:
- Results.push_back(TLI.expandShlSat(Node, DAG));
- break;
+ case ISD::SSHLSAT:
+ case ISD::USHLSAT:
+ Results.push_back(TLI.expandShlSat(Node, DAG));
+ break;
case ISD::SMULFIX:
case ISD::SMULFIXSAT:
case ISD::UMULFIX:
@@ -3969,13 +3969,13 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
// If we expanded the SETCC by swapping LHS and RHS, create a new BR_CC
// node.
if (Tmp4.getNode()) {
- assert(!NeedInvert && "Don't know how to invert BR_CC!");
-
+ assert(!NeedInvert && "Don't know how to invert BR_CC!");
+
Tmp1 = DAG.getNode(ISD::BR_CC, dl, Node->getValueType(0), Tmp1,
Tmp4, Tmp2, Tmp3, Node->getOperand(4));
} else {
Tmp3 = DAG.getConstant(0, dl, Tmp2.getValueType());
- Tmp4 = DAG.getCondCode(NeedInvert ? ISD::SETEQ : ISD::SETNE);
+ Tmp4 = DAG.getCondCode(NeedInvert ? ISD::SETEQ : ISD::SETNE);
Tmp1 = DAG.getNode(ISD::BR_CC, dl, Node->getValueType(0), Tmp1, Tmp4,
Tmp2, Tmp3, Node->getOperand(4));
}
@@ -4056,27 +4056,27 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
== TargetLowering::Legal)
return true;
break;
- case ISD::STRICT_FSUB: {
- if (TLI.getStrictFPOperationAction(
- ISD::STRICT_FSUB, Node->getValueType(0)) == TargetLowering::Legal)
- return true;
- if (TLI.getStrictFPOperationAction(
- ISD::STRICT_FADD, Node->getValueType(0)) != TargetLowering::Legal)
- break;
-
- EVT VT = Node->getValueType(0);
- const SDNodeFlags Flags = Node->getFlags();
- SDValue Neg = DAG.getNode(ISD::FNEG, dl, VT, Node->getOperand(2), Flags);
- SDValue Fadd = DAG.getNode(ISD::STRICT_FADD, dl, Node->getVTList(),
- {Node->getOperand(0), Node->getOperand(1), Neg},
- Flags);
-
- Results.push_back(Fadd);
- Results.push_back(Fadd.getValue(1));
- break;
- }
- case ISD::STRICT_SINT_TO_FP:
- case ISD::STRICT_UINT_TO_FP:
+ case ISD::STRICT_FSUB: {
+ if (TLI.getStrictFPOperationAction(
+ ISD::STRICT_FSUB, Node->getValueType(0)) == TargetLowering::Legal)
+ return true;
+ if (TLI.getStrictFPOperationAction(
+ ISD::STRICT_FADD, Node->getValueType(0)) != TargetLowering::Legal)
+ break;
+
+ EVT VT = Node->getValueType(0);
+ const SDNodeFlags Flags = Node->getFlags();
+ SDValue Neg = DAG.getNode(ISD::FNEG, dl, VT, Node->getOperand(2), Flags);
+ SDValue Fadd = DAG.getNode(ISD::STRICT_FADD, dl, Node->getVTList(),
+ {Node->getOperand(0), Node->getOperand(1), Neg},
+ Flags);
+
+ Results.push_back(Fadd);
+ Results.push_back(Fadd.getValue(1));
+ break;
+ }
+ case ISD::STRICT_SINT_TO_FP:
+ case ISD::STRICT_UINT_TO_FP:
case ISD::STRICT_LRINT:
case ISD::STRICT_LLRINT:
case ISD::STRICT_LROUND:
@@ -4145,23 +4145,23 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
case ISD::ATOMIC_LOAD_UMAX:
case ISD::ATOMIC_CMP_SWAP: {
MVT VT = cast<AtomicSDNode>(Node)->getMemoryVT().getSimpleVT();
- AtomicOrdering Order = cast<AtomicSDNode>(Node)->getOrdering();
- RTLIB::Libcall LC = RTLIB::getOUTLINE_ATOMIC(Opc, Order, VT);
+ AtomicOrdering Order = cast<AtomicSDNode>(Node)->getOrdering();
+ RTLIB::Libcall LC = RTLIB::getOUTLINE_ATOMIC(Opc, Order, VT);
EVT RetVT = Node->getValueType(0);
TargetLowering::MakeLibCallOptions CallOptions;
- SmallVector<SDValue, 4> Ops;
- if (TLI.getLibcallName(LC)) {
- // If outline atomic available, prepare its arguments and expand.
- Ops.append(Node->op_begin() + 2, Node->op_end());
- Ops.push_back(Node->getOperand(1));
-
- } else {
- LC = RTLIB::getSYNC(Opc, VT);
- assert(LC != RTLIB::UNKNOWN_LIBCALL &&
- "Unexpected atomic op or value type!");
- // Arguments for expansion to sync libcall
- Ops.append(Node->op_begin() + 1, Node->op_end());
- }
+ SmallVector<SDValue, 4> Ops;
+ if (TLI.getLibcallName(LC)) {
+ // If outline atomic available, prepare its arguments and expand.
+ Ops.append(Node->op_begin() + 2, Node->op_end());
+ Ops.push_back(Node->getOperand(1));
+
+ } else {
+ LC = RTLIB::getSYNC(Opc, VT);
+ assert(LC != RTLIB::UNKNOWN_LIBCALL &&
+ "Unexpected atomic op or value type!");
+ // Arguments for expansion to sync libcall
+ Ops.append(Node->op_begin() + 1, Node->op_end());
+ }
std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, RetVT,
Ops, CallOptions,
SDLoc(Node),
@@ -4409,131 +4409,131 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
Results.push_back(ExpandLibCall(LC, Node, false));
break;
}
- case ISD::STRICT_SINT_TO_FP:
- case ISD::STRICT_UINT_TO_FP:
- case ISD::SINT_TO_FP:
- case ISD::UINT_TO_FP: {
- // TODO - Common the code with DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP
- bool IsStrict = Node->isStrictFPOpcode();
- bool Signed = Node->getOpcode() == ISD::SINT_TO_FP ||
- Node->getOpcode() == ISD::STRICT_SINT_TO_FP;
- EVT SVT = Node->getOperand(IsStrict ? 1 : 0).getValueType();
- EVT RVT = Node->getValueType(0);
- EVT NVT = EVT();
- SDLoc dl(Node);
-
- // Even if the input is legal, no libcall may exactly match, eg. we don't
- // have i1 -> fp conversions. So, it needs to be promoted to a larger type,
- // eg: i13 -> fp. Then, look for an appropriate libcall.
- RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
- for (unsigned t = MVT::FIRST_INTEGER_VALUETYPE;
- t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
- ++t) {
- NVT = (MVT::SimpleValueType)t;
- // The source needs to big enough to hold the operand.
- if (NVT.bitsGE(SVT))
- LC = Signed ? RTLIB::getSINTTOFP(NVT, RVT)
- : RTLIB::getUINTTOFP(NVT, RVT);
- }
- assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unable to legalize as libcall");
-
- SDValue Chain = IsStrict ? Node->getOperand(0) : SDValue();
- // Sign/zero extend the argument if the libcall takes a larger type.
- SDValue Op = DAG.getNode(Signed ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl,
- NVT, Node->getOperand(IsStrict ? 1 : 0));
- TargetLowering::MakeLibCallOptions CallOptions;
- CallOptions.setSExt(Signed);
- std::pair<SDValue, SDValue> Tmp =
- TLI.makeLibCall(DAG, LC, RVT, Op, CallOptions, dl, Chain);
- Results.push_back(Tmp.first);
- if (IsStrict)
- Results.push_back(Tmp.second);
- break;
- }
- case ISD::FP_TO_SINT:
- case ISD::FP_TO_UINT:
- case ISD::STRICT_FP_TO_SINT:
- case ISD::STRICT_FP_TO_UINT: {
- // TODO - Common the code with DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT.
- bool IsStrict = Node->isStrictFPOpcode();
- bool Signed = Node->getOpcode() == ISD::FP_TO_SINT ||
- Node->getOpcode() == ISD::STRICT_FP_TO_SINT;
-
- SDValue Op = Node->getOperand(IsStrict ? 1 : 0);
- EVT SVT = Op.getValueType();
- EVT RVT = Node->getValueType(0);
- EVT NVT = EVT();
- SDLoc dl(Node);
-
- // Even if the result is legal, no libcall may exactly match, eg. we don't
- // have fp -> i1 conversions. So, it needs to be promoted to a larger type,
- // eg: fp -> i32. Then, look for an appropriate libcall.
- RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
- for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
- IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
- ++IntVT) {
- NVT = (MVT::SimpleValueType)IntVT;
- // The type needs to big enough to hold the result.
- if (NVT.bitsGE(RVT))
- LC = Signed ? RTLIB::getFPTOSINT(SVT, NVT)
- : RTLIB::getFPTOUINT(SVT, NVT);
- }
- assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unable to legalize as libcall");
-
- SDValue Chain = IsStrict ? Node->getOperand(0) : SDValue();
- TargetLowering::MakeLibCallOptions CallOptions;
- std::pair<SDValue, SDValue> Tmp =
- TLI.makeLibCall(DAG, LC, NVT, Op, CallOptions, dl, Chain);
-
- // Truncate the result if the libcall returns a larger type.
- Results.push_back(DAG.getNode(ISD::TRUNCATE, dl, RVT, Tmp.first));
- if (IsStrict)
- Results.push_back(Tmp.second);
- break;
- }
-
- case ISD::FP_ROUND:
- case ISD::STRICT_FP_ROUND: {
- // X = FP_ROUND(Y, TRUNC)
- // TRUNC is a flag, which is always an integer that is zero or one.
- // If TRUNC is 0, this is a normal rounding, if it is 1, this FP_ROUND
- // is known to not change the value of Y.
- // We can only expand it into libcall if the TRUNC is 0.
- bool IsStrict = Node->isStrictFPOpcode();
- SDValue Op = Node->getOperand(IsStrict ? 1 : 0);
- SDValue Chain = IsStrict ? Node->getOperand(0) : SDValue();
- EVT VT = Node->getValueType(0);
- assert(cast<ConstantSDNode>(Node->getOperand(IsStrict ? 2 : 1))
- ->isNullValue() &&
- "Unable to expand as libcall if it is not normal rounding");
-
- RTLIB::Libcall LC = RTLIB::getFPROUND(Op.getValueType(), VT);
- assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unable to legalize as libcall");
-
- TargetLowering::MakeLibCallOptions CallOptions;
- std::pair<SDValue, SDValue> Tmp =
- TLI.makeLibCall(DAG, LC, VT, Op, CallOptions, SDLoc(Node), Chain);
- Results.push_back(Tmp.first);
- if (IsStrict)
- Results.push_back(Tmp.second);
- break;
- }
- case ISD::FP_EXTEND: {
- Results.push_back(
- ExpandLibCall(RTLIB::getFPEXT(Node->getOperand(0).getValueType(),
- Node->getValueType(0)),
- Node, false));
- break;
- }
- case ISD::STRICT_FP_EXTEND:
+ case ISD::STRICT_SINT_TO_FP:
+ case ISD::STRICT_UINT_TO_FP:
+ case ISD::SINT_TO_FP:
+ case ISD::UINT_TO_FP: {
+ // TODO - Common the code with DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP
+ bool IsStrict = Node->isStrictFPOpcode();
+ bool Signed = Node->getOpcode() == ISD::SINT_TO_FP ||
+ Node->getOpcode() == ISD::STRICT_SINT_TO_FP;
+ EVT SVT = Node->getOperand(IsStrict ? 1 : 0).getValueType();
+ EVT RVT = Node->getValueType(0);
+ EVT NVT = EVT();
+ SDLoc dl(Node);
+
+ // Even if the input is legal, no libcall may exactly match, eg. we don't
+ // have i1 -> fp conversions. So, it needs to be promoted to a larger type,
+ // eg: i13 -> fp. Then, look for an appropriate libcall.
+ RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
+ for (unsigned t = MVT::FIRST_INTEGER_VALUETYPE;
+ t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
+ ++t) {
+ NVT = (MVT::SimpleValueType)t;
+ // The source needs to big enough to hold the operand.
+ if (NVT.bitsGE(SVT))
+ LC = Signed ? RTLIB::getSINTTOFP(NVT, RVT)
+ : RTLIB::getUINTTOFP(NVT, RVT);
+ }
+ assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unable to legalize as libcall");
+
+ SDValue Chain = IsStrict ? Node->getOperand(0) : SDValue();
+ // Sign/zero extend the argument if the libcall takes a larger type.
+ SDValue Op = DAG.getNode(Signed ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl,
+ NVT, Node->getOperand(IsStrict ? 1 : 0));
+ TargetLowering::MakeLibCallOptions CallOptions;
+ CallOptions.setSExt(Signed);
+ std::pair<SDValue, SDValue> Tmp =
+ TLI.makeLibCall(DAG, LC, RVT, Op, CallOptions, dl, Chain);
+ Results.push_back(Tmp.first);
+ if (IsStrict)
+ Results.push_back(Tmp.second);
+ break;
+ }
+ case ISD::FP_TO_SINT:
+ case ISD::FP_TO_UINT:
+ case ISD::STRICT_FP_TO_SINT:
+ case ISD::STRICT_FP_TO_UINT: {
+ // TODO - Common the code with DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT.
+ bool IsStrict = Node->isStrictFPOpcode();
+ bool Signed = Node->getOpcode() == ISD::FP_TO_SINT ||
+ Node->getOpcode() == ISD::STRICT_FP_TO_SINT;
+
+ SDValue Op = Node->getOperand(IsStrict ? 1 : 0);
+ EVT SVT = Op.getValueType();
+ EVT RVT = Node->getValueType(0);
+ EVT NVT = EVT();
+ SDLoc dl(Node);
+
+ // Even if the result is legal, no libcall may exactly match, eg. we don't
+ // have fp -> i1 conversions. So, it needs to be promoted to a larger type,
+ // eg: fp -> i32. Then, look for an appropriate libcall.
+ RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
+ for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
+ IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
+ ++IntVT) {
+ NVT = (MVT::SimpleValueType)IntVT;
+ // The type needs to big enough to hold the result.
+ if (NVT.bitsGE(RVT))
+ LC = Signed ? RTLIB::getFPTOSINT(SVT, NVT)
+ : RTLIB::getFPTOUINT(SVT, NVT);
+ }
+ assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unable to legalize as libcall");
+
+ SDValue Chain = IsStrict ? Node->getOperand(0) : SDValue();
+ TargetLowering::MakeLibCallOptions CallOptions;
+ std::pair<SDValue, SDValue> Tmp =
+ TLI.makeLibCall(DAG, LC, NVT, Op, CallOptions, dl, Chain);
+
+ // Truncate the result if the libcall returns a larger type.
+ Results.push_back(DAG.getNode(ISD::TRUNCATE, dl, RVT, Tmp.first));
+ if (IsStrict)
+ Results.push_back(Tmp.second);
+ break;
+ }
+
+ case ISD::FP_ROUND:
+ case ISD::STRICT_FP_ROUND: {
+ // X = FP_ROUND(Y, TRUNC)
+ // TRUNC is a flag, which is always an integer that is zero or one.
+ // If TRUNC is 0, this is a normal rounding, if it is 1, this FP_ROUND
+ // is known to not change the value of Y.
+ // We can only expand it into libcall if the TRUNC is 0.
+ bool IsStrict = Node->isStrictFPOpcode();
+ SDValue Op = Node->getOperand(IsStrict ? 1 : 0);
+ SDValue Chain = IsStrict ? Node->getOperand(0) : SDValue();
+ EVT VT = Node->getValueType(0);
+ assert(cast<ConstantSDNode>(Node->getOperand(IsStrict ? 2 : 1))
+ ->isNullValue() &&
+ "Unable to expand as libcall if it is not normal rounding");
+
+ RTLIB::Libcall LC = RTLIB::getFPROUND(Op.getValueType(), VT);
+ assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unable to legalize as libcall");
+
+ TargetLowering::MakeLibCallOptions CallOptions;
+ std::pair<SDValue, SDValue> Tmp =
+ TLI.makeLibCall(DAG, LC, VT, Op, CallOptions, SDLoc(Node), Chain);
+ Results.push_back(Tmp.first);
+ if (IsStrict)
+ Results.push_back(Tmp.second);
+ break;
+ }
+ case ISD::FP_EXTEND: {
+ Results.push_back(
+ ExpandLibCall(RTLIB::getFPEXT(Node->getOperand(0).getValueType(),
+ Node->getValueType(0)),
+ Node, false));
+ break;
+ }
+ case ISD::STRICT_FP_EXTEND:
case ISD::STRICT_FP_TO_FP16: {
RTLIB::Libcall LC =
- Node->getOpcode() == ISD::STRICT_FP_TO_FP16
- ? RTLIB::getFPROUND(Node->getOperand(1).getValueType(), MVT::f16)
- : RTLIB::getFPEXT(Node->getOperand(1).getValueType(),
- Node->getValueType(0));
- assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unable to legalize as libcall");
-
+ Node->getOpcode() == ISD::STRICT_FP_TO_FP16
+ ? RTLIB::getFPROUND(Node->getOperand(1).getValueType(), MVT::f16)
+ : RTLIB::getFPEXT(Node->getOperand(1).getValueType(),
+ Node->getValueType(0));
+ assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unable to legalize as libcall");
+
TargetLowering::MakeLibCallOptions CallOptions;
std::pair<SDValue, SDValue> Tmp =
TLI.makeLibCall(DAG, LC, Node->getValueType(0), Node->getOperand(1),
@@ -4630,9 +4630,9 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node) {
OVT = Node->getOperand(0).getSimpleValueType();
}
if (Node->getOpcode() == ISD::STRICT_UINT_TO_FP ||
- Node->getOpcode() == ISD::STRICT_SINT_TO_FP ||
- Node->getOpcode() == ISD::STRICT_FSETCC ||
- Node->getOpcode() == ISD::STRICT_FSETCCS)
+ Node->getOpcode() == ISD::STRICT_SINT_TO_FP ||
+ Node->getOpcode() == ISD::STRICT_FSETCC ||
+ Node->getOpcode() == ISD::STRICT_FSETCCS)
OVT = Node->getOperand(1).getSimpleValueType();
if (Node->getOpcode() == ISD::BR_CC)
OVT = Node->getOperand(2).getSimpleValueType();
@@ -4692,10 +4692,10 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node) {
case ISD::STRICT_FP_TO_SINT:
PromoteLegalFP_TO_INT(Node, dl, Results);
break;
- case ISD::FP_TO_UINT_SAT:
- case ISD::FP_TO_SINT_SAT:
- Results.push_back(PromoteLegalFP_TO_INT_SAT(Node, dl));
- break;
+ case ISD::FP_TO_UINT_SAT:
+ case ISD::FP_TO_SINT_SAT:
+ Results.push_back(PromoteLegalFP_TO_INT_SAT(Node, dl));
+ break;
case ISD::UINT_TO_FP:
case ISD::STRICT_UINT_TO_FP:
case ISD::SINT_TO_FP:
@@ -4830,29 +4830,29 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node) {
Results.push_back(Tmp1);
break;
}
- case ISD::SETCC:
- case ISD::STRICT_FSETCC:
- case ISD::STRICT_FSETCCS: {
+ case ISD::SETCC:
+ case ISD::STRICT_FSETCC:
+ case ISD::STRICT_FSETCCS: {
unsigned ExtOp = ISD::FP_EXTEND;
if (NVT.isInteger()) {
- ISD::CondCode CCCode = cast<CondCodeSDNode>(Node->getOperand(2))->get();
+ ISD::CondCode CCCode = cast<CondCodeSDNode>(Node->getOperand(2))->get();
ExtOp = isSignedIntSetCC(CCCode) ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
}
- if (Node->isStrictFPOpcode()) {
- SDValue InChain = Node->getOperand(0);
- std::tie(Tmp1, std::ignore) =
- DAG.getStrictFPExtendOrRound(Node->getOperand(1), InChain, dl, NVT);
- std::tie(Tmp2, std::ignore) =
- DAG.getStrictFPExtendOrRound(Node->getOperand(2), InChain, dl, NVT);
- SmallVector<SDValue, 2> TmpChains = {Tmp1.getValue(1), Tmp2.getValue(1)};
- SDValue OutChain = DAG.getTokenFactor(dl, TmpChains);
- SDVTList VTs = DAG.getVTList(Node->getValueType(0), MVT::Other);
- Results.push_back(DAG.getNode(Node->getOpcode(), dl, VTs,
- {OutChain, Tmp1, Tmp2, Node->getOperand(3)},
- Node->getFlags()));
- Results.push_back(Results.back().getValue(1));
- break;
- }
+ if (Node->isStrictFPOpcode()) {
+ SDValue InChain = Node->getOperand(0);
+ std::tie(Tmp1, std::ignore) =
+ DAG.getStrictFPExtendOrRound(Node->getOperand(1), InChain, dl, NVT);
+ std::tie(Tmp2, std::ignore) =
+ DAG.getStrictFPExtendOrRound(Node->getOperand(2), InChain, dl, NVT);
+ SmallVector<SDValue, 2> TmpChains = {Tmp1.getValue(1), Tmp2.getValue(1)};
+ SDValue OutChain = DAG.getTokenFactor(dl, TmpChains);
+ SDVTList VTs = DAG.getVTList(Node->getValueType(0), MVT::Other);
+ Results.push_back(DAG.getNode(Node->getOpcode(), dl, VTs,
+ {OutChain, Tmp1, Tmp2, Node->getOperand(3)},
+ Node->getFlags()));
+ Results.push_back(Results.back().getValue(1));
+ break;
+ }
Tmp1 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(0));
Tmp2 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(1));
Results.push_back(DAG.getNode(ISD::SETCC, dl, Node->getValueType(0), Tmp1,
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index a3820fd211..966645e325 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -134,16 +134,16 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
case ISD::UINT_TO_FP: R = SoftenFloatRes_XINT_TO_FP(N); break;
case ISD::UNDEF: R = SoftenFloatRes_UNDEF(N); break;
case ISD::VAARG: R = SoftenFloatRes_VAARG(N); break;
- case ISD::VECREDUCE_FADD:
- case ISD::VECREDUCE_FMUL:
- case ISD::VECREDUCE_FMIN:
- case ISD::VECREDUCE_FMAX:
- R = SoftenFloatRes_VECREDUCE(N);
- break;
- case ISD::VECREDUCE_SEQ_FADD:
- case ISD::VECREDUCE_SEQ_FMUL:
- R = SoftenFloatRes_VECREDUCE_SEQ(N);
- break;
+ case ISD::VECREDUCE_FADD:
+ case ISD::VECREDUCE_FMUL:
+ case ISD::VECREDUCE_FMIN:
+ case ISD::VECREDUCE_FMAX:
+ R = SoftenFloatRes_VECREDUCE(N);
+ break;
+ case ISD::VECREDUCE_SEQ_FADD:
+ case ISD::VECREDUCE_SEQ_FMUL:
+ R = SoftenFloatRes_VECREDUCE_SEQ(N);
+ break;
}
// If R is null, the sub-method took care of registering the result.
@@ -782,17 +782,17 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) {
return Tmp.first;
}
-SDValue DAGTypeLegalizer::SoftenFloatRes_VECREDUCE(SDNode *N) {
- // Expand and soften recursively.
- ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduce(N, DAG));
- return SDValue();
-}
+SDValue DAGTypeLegalizer::SoftenFloatRes_VECREDUCE(SDNode *N) {
+ // Expand and soften recursively.
+ ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduce(N, DAG));
+ return SDValue();
+}
+
+SDValue DAGTypeLegalizer::SoftenFloatRes_VECREDUCE_SEQ(SDNode *N) {
+ ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduceSeq(N, DAG));
+ return SDValue();
+}
-SDValue DAGTypeLegalizer::SoftenFloatRes_VECREDUCE_SEQ(SDNode *N) {
- ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduceSeq(N, DAG));
- return SDValue();
-}
-
//===----------------------------------------------------------------------===//
// Convert Float Operand to Integer
//===----------------------------------------------------------------------===//
@@ -819,9 +819,9 @@ bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
case ISD::STRICT_FP_TO_UINT:
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT: Res = SoftenFloatOp_FP_TO_XINT(N); break;
- case ISD::FP_TO_SINT_SAT:
- case ISD::FP_TO_UINT_SAT:
- Res = SoftenFloatOp_FP_TO_XINT_SAT(N); break;
+ case ISD::FP_TO_SINT_SAT:
+ case ISD::FP_TO_UINT_SAT:
+ Res = SoftenFloatOp_FP_TO_XINT_SAT(N); break;
case ISD::STRICT_LROUND:
case ISD::LROUND: Res = SoftenFloatOp_LROUND(N); break;
case ISD::STRICT_LLROUND:
@@ -913,24 +913,24 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) {
0);
}
-// Even if the result type is legal, no libcall may exactly match. (e.g. We
-// don't have FP-i8 conversions) This helper method looks for an appropriate
-// promoted libcall.
-static RTLIB::Libcall findFPToIntLibcall(EVT SrcVT, EVT RetVT, EVT &Promoted,
- bool Signed) {
- RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
- for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
- IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
- ++IntVT) {
- Promoted = (MVT::SimpleValueType)IntVT;
- // The type needs to big enough to hold the result.
- if (Promoted.bitsGE(RetVT))
- LC = Signed ? RTLIB::getFPTOSINT(SrcVT, Promoted)
- : RTLIB::getFPTOUINT(SrcVT, Promoted);
- }
- return LC;
-}
-
+// Even if the result type is legal, no libcall may exactly match. (e.g. We
+// don't have FP-i8 conversions) This helper method looks for an appropriate
+// promoted libcall.
+static RTLIB::Libcall findFPToIntLibcall(EVT SrcVT, EVT RetVT, EVT &Promoted,
+ bool Signed) {
+ RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
+ for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
+ IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
+ ++IntVT) {
+ Promoted = (MVT::SimpleValueType)IntVT;
+ // The type needs to big enough to hold the result.
+ if (Promoted.bitsGE(RetVT))
+ LC = Signed ? RTLIB::getFPTOSINT(SrcVT, Promoted)
+ : RTLIB::getFPTOUINT(SrcVT, Promoted);
+ }
+ return LC;
+}
+
SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT(SDNode *N) {
bool IsStrict = N->isStrictFPOpcode();
bool Signed = N->getOpcode() == ISD::FP_TO_SINT ||
@@ -946,9 +946,9 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT(SDNode *N) {
// a larger type, eg: fp -> i32. Even if it is legal, no libcall may exactly
// match, eg. we don't have fp -> i8 conversions.
// Look for an appropriate libcall.
- RTLIB::Libcall LC = findFPToIntLibcall(SVT, RVT, NVT, Signed);
- assert(LC != RTLIB::UNKNOWN_LIBCALL && NVT.isSimple() &&
- "Unsupported FP_TO_XINT!");
+ RTLIB::Libcall LC = findFPToIntLibcall(SVT, RVT, NVT, Signed);
+ assert(LC != RTLIB::UNKNOWN_LIBCALL && NVT.isSimple() &&
+ "Unsupported FP_TO_XINT!");
Op = GetSoftenedFloat(Op);
SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
@@ -968,11 +968,11 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT(SDNode *N) {
return SDValue();
}
-SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT_SAT(SDNode *N) {
- SDValue Res = TLI.expandFP_TO_INT_SAT(N, DAG);
- return Res;
-}
-
+SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT_SAT(SDNode *N) {
+ SDValue Res = TLI.expandFP_TO_INT_SAT(N, DAG);
+ return Res;
+}
+
SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) {
SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
@@ -1239,8 +1239,8 @@ void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) {
case ISD::STRICT_FTRUNC:
case ISD::FTRUNC: ExpandFloatRes_FTRUNC(N, Lo, Hi); break;
case ISD::LOAD: ExpandFloatRes_LOAD(N, Lo, Hi); break;
- case ISD::STRICT_SINT_TO_FP:
- case ISD::STRICT_UINT_TO_FP:
+ case ISD::STRICT_SINT_TO_FP:
+ case ISD::STRICT_UINT_TO_FP:
case ISD::SINT_TO_FP:
case ISD::UINT_TO_FP: ExpandFloatRes_XINT_TO_FP(N, Lo, Hi); break;
case ISD::STRICT_FREM:
@@ -1313,7 +1313,7 @@ void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDValue &Lo,
void DAGTypeLegalizer::ExpandFloatRes_FMINNUM(SDNode *N, SDValue &Lo,
SDValue &Hi) {
- ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
+ ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
RTLIB::FMIN_F32, RTLIB::FMIN_F64,
RTLIB::FMIN_F80, RTLIB::FMIN_F128,
RTLIB::FMIN_PPCF128), Lo, Hi);
@@ -1639,18 +1639,18 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
assert(N->getValueType(0) == MVT::ppcf128 && "Unsupported XINT_TO_FP!");
EVT VT = N->getValueType(0);
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
- bool Strict = N->isStrictFPOpcode();
- SDValue Src = N->getOperand(Strict ? 1 : 0);
+ bool Strict = N->isStrictFPOpcode();
+ SDValue Src = N->getOperand(Strict ? 1 : 0);
EVT SrcVT = Src.getValueType();
- bool isSigned = N->getOpcode() == ISD::SINT_TO_FP ||
- N->getOpcode() == ISD::STRICT_SINT_TO_FP;
+ bool isSigned = N->getOpcode() == ISD::SINT_TO_FP ||
+ N->getOpcode() == ISD::STRICT_SINT_TO_FP;
SDLoc dl(N);
- SDValue Chain = Strict ? N->getOperand(0) : DAG.getEntryNode();
+ SDValue Chain = Strict ? N->getOperand(0) : DAG.getEntryNode();
+
+ // TODO: Any other flags to propagate?
+ SDNodeFlags Flags;
+ Flags.setNoFPExcept(N->getFlags().hasNoFPExcept());
- // TODO: Any other flags to propagate?
- SDNodeFlags Flags;
- Flags.setNoFPExcept(N->getFlags().hasNoFPExcept());
-
// First do an SINT_TO_FP, whether the original was signed or unsigned.
// When promoting partial word types to i32 we must honor the signedness,
// though.
@@ -1658,12 +1658,12 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
// The integer can be represented exactly in an f64.
Lo = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT),
APInt(NVT.getSizeInBits(), 0)), dl, NVT);
- if (Strict) {
- Hi = DAG.getNode(N->getOpcode(), dl, DAG.getVTList(NVT, MVT::Other),
- {Chain, Src}, Flags);
- Chain = Hi.getValue(1);
- } else
- Hi = DAG.getNode(N->getOpcode(), dl, NVT, Src);
+ if (Strict) {
+ Hi = DAG.getNode(N->getOpcode(), dl, DAG.getVTList(NVT, MVT::Other),
+ {Chain, Src}, Flags);
+ Chain = Hi.getValue(1);
+ } else
+ Hi = DAG.getNode(N->getOpcode(), dl, NVT, Src);
} else {
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (SrcVT.bitsLE(MVT::i64)) {
@@ -1678,25 +1678,25 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
TargetLowering::MakeLibCallOptions CallOptions;
CallOptions.setSExt(true);
- std::pair<SDValue, SDValue> Tmp =
- TLI.makeLibCall(DAG, LC, VT, Src, CallOptions, dl, Chain);
- if (Strict)
- Chain = Tmp.second;
- GetPairElements(Tmp.first, Lo, Hi);
+ std::pair<SDValue, SDValue> Tmp =
+ TLI.makeLibCall(DAG, LC, VT, Src, CallOptions, dl, Chain);
+ if (Strict)
+ Chain = Tmp.second;
+ GetPairElements(Tmp.first, Lo, Hi);
}
- // No need to complement for unsigned 32-bit integers
- if (isSigned || SrcVT.bitsLE(MVT::i32)) {
- if (Strict)
- ReplaceValueWith(SDValue(N, 1), Chain);
-
+ // No need to complement for unsigned 32-bit integers
+ if (isSigned || SrcVT.bitsLE(MVT::i32)) {
+ if (Strict)
+ ReplaceValueWith(SDValue(N, 1), Chain);
+
return;
- }
+ }
// Unsigned - fix up the SINT_TO_FP value just calculated.
- // FIXME: For unsigned i128 to ppc_fp128 conversion, we need to carefully
- // keep semantics correctness if the integer is not exactly representable
- // here. See ExpandLegalINT_TO_FP.
+ // FIXME: For unsigned i128 to ppc_fp128 conversion, we need to carefully
+ // keep semantics correctness if the integer is not exactly representable
+ // here. See ExpandLegalINT_TO_FP.
Hi = DAG.getNode(ISD::BUILD_PAIR, dl, VT, Lo, Hi);
SrcVT = Src.getValueType();
@@ -1720,16 +1720,16 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
break;
}
- // TODO: Are there other fast-math-flags to propagate to this FADD?
- SDValue NewLo = DAG.getConstantFP(
- APFloat(APFloat::PPCDoubleDouble(), APInt(128, Parts)), dl, MVT::ppcf128);
- if (Strict) {
- Lo = DAG.getNode(ISD::STRICT_FADD, dl, DAG.getVTList(VT, MVT::Other),
- {Chain, Hi, NewLo}, Flags);
- Chain = Lo.getValue(1);
- ReplaceValueWith(SDValue(N, 1), Chain);
- } else
- Lo = DAG.getNode(ISD::FADD, dl, VT, Hi, NewLo);
+ // TODO: Are there other fast-math-flags to propagate to this FADD?
+ SDValue NewLo = DAG.getConstantFP(
+ APFloat(APFloat::PPCDoubleDouble(), APInt(128, Parts)), dl, MVT::ppcf128);
+ if (Strict) {
+ Lo = DAG.getNode(ISD::STRICT_FADD, dl, DAG.getVTList(VT, MVT::Other),
+ {Chain, Hi, NewLo}, Flags);
+ Chain = Lo.getValue(1);
+ ReplaceValueWith(SDValue(N, 1), Chain);
+ } else
+ Lo = DAG.getNode(ISD::FADD, dl, VT, Hi, NewLo);
Lo = DAG.getSelectCC(dl, Src, DAG.getConstant(0, dl, SrcVT),
Lo, Hi, ISD::SETLT);
GetPairElements(Lo, Lo, Hi);
@@ -1770,15 +1770,15 @@ bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) {
case ISD::FP_ROUND: Res = ExpandFloatOp_FP_ROUND(N); break;
case ISD::STRICT_FP_TO_SINT:
case ISD::STRICT_FP_TO_UINT:
- case ISD::FP_TO_SINT:
- case ISD::FP_TO_UINT: Res = ExpandFloatOp_FP_TO_XINT(N); break;
+ case ISD::FP_TO_SINT:
+ case ISD::FP_TO_UINT: Res = ExpandFloatOp_FP_TO_XINT(N); break;
case ISD::LROUND: Res = ExpandFloatOp_LROUND(N); break;
case ISD::LLROUND: Res = ExpandFloatOp_LLROUND(N); break;
case ISD::LRINT: Res = ExpandFloatOp_LRINT(N); break;
case ISD::LLRINT: Res = ExpandFloatOp_LLRINT(N); break;
case ISD::SELECT_CC: Res = ExpandFloatOp_SELECT_CC(N); break;
- case ISD::STRICT_FSETCC:
- case ISD::STRICT_FSETCCS:
+ case ISD::STRICT_FSETCC:
+ case ISD::STRICT_FSETCCS:
case ISD::SETCC: Res = ExpandFloatOp_SETCC(N); break;
case ISD::STORE: Res = ExpandFloatOp_STORE(cast<StoreSDNode>(N),
OpNo); break;
@@ -1804,8 +1804,8 @@ bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) {
void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS,
SDValue &NewRHS,
ISD::CondCode &CCCode,
- const SDLoc &dl, SDValue &Chain,
- bool IsSignaling) {
+ const SDLoc &dl, SDValue &Chain,
+ bool IsSignaling) {
SDValue LHSLo, LHSHi, RHSLo, RHSHi;
GetExpandedFloat(NewLHS, LHSLo, LHSHi);
GetExpandedFloat(NewRHS, RHSLo, RHSHi);
@@ -1817,32 +1817,32 @@ void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS,
// BNE crN, L:
// FCMPU crN, lo1, lo2
// The following can be improved, but not that much.
- SDValue Tmp1, Tmp2, Tmp3, OutputChain;
- Tmp1 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()), LHSHi,
- RHSHi, ISD::SETOEQ, Chain, IsSignaling);
- OutputChain = Tmp1->getNumValues() > 1 ? Tmp1.getValue(1) : SDValue();
- Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSLo.getValueType()), LHSLo,
- RHSLo, CCCode, OutputChain, IsSignaling);
- OutputChain = Tmp2->getNumValues() > 1 ? Tmp2.getValue(1) : SDValue();
+ SDValue Tmp1, Tmp2, Tmp3, OutputChain;
+ Tmp1 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()), LHSHi,
+ RHSHi, ISD::SETOEQ, Chain, IsSignaling);
+ OutputChain = Tmp1->getNumValues() > 1 ? Tmp1.getValue(1) : SDValue();
+ Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSLo.getValueType()), LHSLo,
+ RHSLo, CCCode, OutputChain, IsSignaling);
+ OutputChain = Tmp2->getNumValues() > 1 ? Tmp2.getValue(1) : SDValue();
Tmp3 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2);
- Tmp1 =
- DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi,
- ISD::SETUNE, OutputChain, IsSignaling);
- OutputChain = Tmp1->getNumValues() > 1 ? Tmp1.getValue(1) : SDValue();
- Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()), LHSHi,
- RHSHi, CCCode, OutputChain, IsSignaling);
- OutputChain = Tmp2->getNumValues() > 1 ? Tmp2.getValue(1) : SDValue();
+ Tmp1 =
+ DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi,
+ ISD::SETUNE, OutputChain, IsSignaling);
+ OutputChain = Tmp1->getNumValues() > 1 ? Tmp1.getValue(1) : SDValue();
+ Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()), LHSHi,
+ RHSHi, CCCode, OutputChain, IsSignaling);
+ OutputChain = Tmp2->getNumValues() > 1 ? Tmp2.getValue(1) : SDValue();
Tmp1 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2);
NewLHS = DAG.getNode(ISD::OR, dl, Tmp1.getValueType(), Tmp1, Tmp3);
NewRHS = SDValue(); // LHS is the result, not a compare.
- Chain = OutputChain;
+ Chain = OutputChain;
}
SDValue DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode *N) {
SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
- SDValue Chain;
- FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N), Chain);
+ SDValue Chain;
+ FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N), Chain);
// If ExpandSetCCOperands returned a scalar, we need to compare the result
// against zero to select between true and false values.
@@ -1897,23 +1897,23 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) {
return SDValue();
}
-SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_XINT(SDNode *N) {
+SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_XINT(SDNode *N) {
EVT RVT = N->getValueType(0);
SDLoc dl(N);
bool IsStrict = N->isStrictFPOpcode();
- bool Signed = N->getOpcode() == ISD::FP_TO_SINT ||
- N->getOpcode() == ISD::STRICT_FP_TO_SINT;
+ bool Signed = N->getOpcode() == ISD::FP_TO_SINT ||
+ N->getOpcode() == ISD::STRICT_FP_TO_SINT;
SDValue Op = N->getOperand(IsStrict ? 1 : 0);
SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
- EVT NVT;
- RTLIB::Libcall LC = findFPToIntLibcall(Op.getValueType(), RVT, NVT, Signed);
- assert(LC != RTLIB::UNKNOWN_LIBCALL && NVT.isSimple() &&
- "Unsupported FP_TO_XINT!");
+ EVT NVT;
+ RTLIB::Libcall LC = findFPToIntLibcall(Op.getValueType(), RVT, NVT, Signed);
+ assert(LC != RTLIB::UNKNOWN_LIBCALL && NVT.isSimple() &&
+ "Unsupported FP_TO_XINT!");
TargetLowering::MakeLibCallOptions CallOptions;
- std::pair<SDValue, SDValue> Tmp =
- TLI.makeLibCall(DAG, LC, NVT, Op, CallOptions, dl, Chain);
+ std::pair<SDValue, SDValue> Tmp =
+ TLI.makeLibCall(DAG, LC, NVT, Op, CallOptions, dl, Chain);
if (!IsStrict)
return Tmp.first;
@@ -1925,8 +1925,8 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_XINT(SDNode *N) {
SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) {
SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
- SDValue Chain;
- FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N), Chain);
+ SDValue Chain;
+ FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N), Chain);
// If ExpandSetCCOperands returned a scalar, we need to compare the result
// against zero to select between true and false values.
@@ -1942,25 +1942,25 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) {
}
SDValue DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode *N) {
- bool IsStrict = N->isStrictFPOpcode();
- SDValue NewLHS = N->getOperand(IsStrict ? 1 : 0);
- SDValue NewRHS = N->getOperand(IsStrict ? 2 : 1);
- SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
- ISD::CondCode CCCode =
- cast<CondCodeSDNode>(N->getOperand(IsStrict ? 3 : 2))->get();
- FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N), Chain,
- N->getOpcode() == ISD::STRICT_FSETCCS);
-
- // FloatExpandSetCCOperands always returned a scalar.
- assert(!NewRHS.getNode() && "Expect to return scalar");
- assert(NewLHS.getValueType() == N->getValueType(0) &&
- "Unexpected setcc expansion!");
- if (Chain) {
- ReplaceValueWith(SDValue(N, 0), NewLHS);
- ReplaceValueWith(SDValue(N, 1), Chain);
- return SDValue();
+ bool IsStrict = N->isStrictFPOpcode();
+ SDValue NewLHS = N->getOperand(IsStrict ? 1 : 0);
+ SDValue NewRHS = N->getOperand(IsStrict ? 2 : 1);
+ SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
+ ISD::CondCode CCCode =
+ cast<CondCodeSDNode>(N->getOperand(IsStrict ? 3 : 2))->get();
+ FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N), Chain,
+ N->getOpcode() == ISD::STRICT_FSETCCS);
+
+ // FloatExpandSetCCOperands always returned a scalar.
+ assert(!NewRHS.getNode() && "Expect to return scalar");
+ assert(NewLHS.getValueType() == N->getValueType(0) &&
+ "Unexpected setcc expansion!");
+ if (Chain) {
+ ReplaceValueWith(SDValue(N, 0), NewLHS);
+ ReplaceValueWith(SDValue(N, 1), Chain);
+ return SDValue();
}
- return NewLHS;
+ return NewLHS;
}
SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) {
@@ -2081,9 +2081,9 @@ bool DAGTypeLegalizer::PromoteFloatOperand(SDNode *N, unsigned OpNo) {
case ISD::FCOPYSIGN: R = PromoteFloatOp_FCOPYSIGN(N, OpNo); break;
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT: R = PromoteFloatOp_FP_TO_XINT(N, OpNo); break;
- case ISD::FP_TO_SINT_SAT:
- case ISD::FP_TO_UINT_SAT:
- R = PromoteFloatOp_FP_TO_XINT_SAT(N, OpNo); break;
+ case ISD::FP_TO_SINT_SAT:
+ case ISD::FP_TO_UINT_SAT:
+ R = PromoteFloatOp_FP_TO_XINT_SAT(N, OpNo); break;
case ISD::FP_EXTEND: R = PromoteFloatOp_FP_EXTEND(N, OpNo); break;
case ISD::SELECT_CC: R = PromoteFloatOp_SELECT_CC(N, OpNo); break;
case ISD::SETCC: R = PromoteFloatOp_SETCC(N, OpNo); break;
@@ -2127,13 +2127,13 @@ SDValue DAGTypeLegalizer::PromoteFloatOp_FP_TO_XINT(SDNode *N, unsigned OpNo) {
return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0), Op);
}
-SDValue DAGTypeLegalizer::PromoteFloatOp_FP_TO_XINT_SAT(SDNode *N,
- unsigned OpNo) {
- SDValue Op = GetPromotedFloat(N->getOperand(0));
- return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0), Op,
- N->getOperand(1));
-}
-
+SDValue DAGTypeLegalizer::PromoteFloatOp_FP_TO_XINT_SAT(SDNode *N,
+ unsigned OpNo) {
+ SDValue Op = GetPromotedFloat(N->getOperand(0));
+ return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0), Op,
+ N->getOperand(1));
+}
+
SDValue DAGTypeLegalizer::PromoteFloatOp_FP_EXTEND(SDNode *N, unsigned OpNo) {
SDValue Op = GetPromotedFloat(N->getOperand(0));
EVT VT = N->getValueType(0);
@@ -2269,16 +2269,16 @@ void DAGTypeLegalizer::PromoteFloatResult(SDNode *N, unsigned ResNo) {
case ISD::UINT_TO_FP: R = PromoteFloatRes_XINT_TO_FP(N); break;
case ISD::UNDEF: R = PromoteFloatRes_UNDEF(N); break;
case ISD::ATOMIC_SWAP: R = BitcastToInt_ATOMIC_SWAP(N); break;
- case ISD::VECREDUCE_FADD:
- case ISD::VECREDUCE_FMUL:
- case ISD::VECREDUCE_FMIN:
- case ISD::VECREDUCE_FMAX:
- R = PromoteFloatRes_VECREDUCE(N);
- break;
- case ISD::VECREDUCE_SEQ_FADD:
- case ISD::VECREDUCE_SEQ_FMUL:
- R = PromoteFloatRes_VECREDUCE_SEQ(N);
- break;
+ case ISD::VECREDUCE_FADD:
+ case ISD::VECREDUCE_FMUL:
+ case ISD::VECREDUCE_FMIN:
+ case ISD::VECREDUCE_FMAX:
+ R = PromoteFloatRes_VECREDUCE(N);
+ break;
+ case ISD::VECREDUCE_SEQ_FADD:
+ case ISD::VECREDUCE_SEQ_FMUL:
+ R = PromoteFloatRes_VECREDUCE_SEQ(N);
+ break;
}
if (R.getNode())
@@ -2510,20 +2510,20 @@ SDValue DAGTypeLegalizer::PromoteFloatRes_UNDEF(SDNode *N) {
N->getValueType(0)));
}
-SDValue DAGTypeLegalizer::PromoteFloatRes_VECREDUCE(SDNode *N) {
- // Expand and promote recursively.
- // TODO: This is non-optimal, but dealing with the concurrently happening
- // vector-legalization is non-trivial. We could do something similar to
- // PromoteFloatRes_EXTRACT_VECTOR_ELT here.
- ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduce(N, DAG));
- return SDValue();
-}
-
-SDValue DAGTypeLegalizer::PromoteFloatRes_VECREDUCE_SEQ(SDNode *N) {
- ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduceSeq(N, DAG));
- return SDValue();
-}
-
+SDValue DAGTypeLegalizer::PromoteFloatRes_VECREDUCE(SDNode *N) {
+ // Expand and promote recursively.
+ // TODO: This is non-optimal, but dealing with the concurrently happening
+ // vector-legalization is non-trivial. We could do something similar to
+ // PromoteFloatRes_EXTRACT_VECTOR_ELT here.
+ ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduce(N, DAG));
+ return SDValue();
+}
+
+SDValue DAGTypeLegalizer::PromoteFloatRes_VECREDUCE_SEQ(SDNode *N) {
+ ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduceSeq(N, DAG));
+ return SDValue();
+}
+
SDValue DAGTypeLegalizer::BitcastToInt_ATOMIC_SWAP(SDNode *N) {
EVT VT = N->getValueType(0);
@@ -2632,16 +2632,16 @@ void DAGTypeLegalizer::SoftPromoteHalfResult(SDNode *N, unsigned ResNo) {
case ISD::UINT_TO_FP: R = SoftPromoteHalfRes_XINT_TO_FP(N); break;
case ISD::UNDEF: R = SoftPromoteHalfRes_UNDEF(N); break;
case ISD::ATOMIC_SWAP: R = BitcastToInt_ATOMIC_SWAP(N); break;
- case ISD::VECREDUCE_FADD:
- case ISD::VECREDUCE_FMUL:
- case ISD::VECREDUCE_FMIN:
- case ISD::VECREDUCE_FMAX:
- R = SoftPromoteHalfRes_VECREDUCE(N);
- break;
- case ISD::VECREDUCE_SEQ_FADD:
- case ISD::VECREDUCE_SEQ_FMUL:
- R = SoftPromoteHalfRes_VECREDUCE_SEQ(N);
- break;
+ case ISD::VECREDUCE_FADD:
+ case ISD::VECREDUCE_FMUL:
+ case ISD::VECREDUCE_FMIN:
+ case ISD::VECREDUCE_FMAX:
+ R = SoftPromoteHalfRes_VECREDUCE(N);
+ break;
+ case ISD::VECREDUCE_SEQ_FADD:
+ case ISD::VECREDUCE_SEQ_FMUL:
+ R = SoftPromoteHalfRes_VECREDUCE_SEQ(N);
+ break;
}
if (R.getNode())
@@ -2834,18 +2834,18 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfRes_BinOp(SDNode *N) {
return DAG.getNode(ISD::FP_TO_FP16, dl, MVT::i16, Res);
}
-SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE(SDNode *N) {
- // Expand and soften recursively.
- ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduce(N, DAG));
- return SDValue();
-}
-
-SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE_SEQ(SDNode *N) {
- // Expand and soften.
- ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduceSeq(N, DAG));
- return SDValue();
-}
-
+SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE(SDNode *N) {
+ // Expand and soften recursively.
+ ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduce(N, DAG));
+ return SDValue();
+}
+
+SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE_SEQ(SDNode *N) {
+ // Expand and soften.
+ ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduceSeq(N, DAG));
+ return SDValue();
+}
+
//===----------------------------------------------------------------------===//
// Half Operand Soft Promotion
//===----------------------------------------------------------------------===//
@@ -2877,9 +2877,9 @@ bool DAGTypeLegalizer::SoftPromoteHalfOperand(SDNode *N, unsigned OpNo) {
case ISD::FCOPYSIGN: Res = SoftPromoteHalfOp_FCOPYSIGN(N, OpNo); break;
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT: Res = SoftPromoteHalfOp_FP_TO_XINT(N); break;
- case ISD::FP_TO_SINT_SAT:
- case ISD::FP_TO_UINT_SAT:
- Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(N); break;
+ case ISD::FP_TO_SINT_SAT:
+ case ISD::FP_TO_UINT_SAT:
+ Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(N); break;
case ISD::STRICT_FP_EXTEND:
case ISD::FP_EXTEND: Res = SoftPromoteHalfOp_FP_EXTEND(N); break;
case ISD::SELECT_CC: Res = SoftPromoteHalfOp_SELECT_CC(N, OpNo); break;
@@ -2949,20 +2949,20 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT(SDNode *N) {
return DAG.getNode(N->getOpcode(), dl, N->getValueType(0), Res);
}
-SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(SDNode *N) {
- SDValue Op = N->getOperand(0);
- SDLoc dl(N);
-
- EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op.getValueType());
-
- Op = GetSoftPromotedHalf(Op);
-
- SDValue Res = DAG.getNode(ISD::FP16_TO_FP, dl, NVT, Op);
-
- return DAG.getNode(N->getOpcode(), dl, N->getValueType(0), Res,
- N->getOperand(1));
-}
-
+SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(SDNode *N) {
+ SDValue Op = N->getOperand(0);
+ SDLoc dl(N);
+
+ EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op.getValueType());
+
+ Op = GetSoftPromotedHalf(Op);
+
+ SDValue Res = DAG.getNode(ISD::FP16_TO_FP, dl, NVT, Op);
+
+ return DAG.getNode(N->getOpcode(), dl, N->getValueType(0), Res,
+ N->getOperand(1));
+}
+
SDValue DAGTypeLegalizer::SoftPromoteHalfOp_SELECT_CC(SDNode *N,
unsigned OpNo) {
assert(OpNo == 0 && "Can only soften the comparison values");
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index d9ccd1db85..4a686bc227 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -62,8 +62,8 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
case ISD::Constant: Res = PromoteIntRes_Constant(N); break;
case ISD::CTLZ_ZERO_UNDEF:
case ISD::CTLZ: Res = PromoteIntRes_CTLZ(N); break;
- case ISD::PARITY:
- case ISD::CTPOP: Res = PromoteIntRes_CTPOP_PARITY(N); break;
+ case ISD::PARITY:
+ case ISD::CTPOP: Res = PromoteIntRes_CTPOP_PARITY(N); break;
case ISD::CTTZ_ZERO_UNDEF:
case ISD::CTTZ: Res = PromoteIntRes_CTTZ(N); break;
case ISD::EXTRACT_VECTOR_ELT:
@@ -82,7 +82,7 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
case ISD::SMIN:
case ISD::SMAX: Res = PromoteIntRes_SExtIntBinOp(N); break;
case ISD::UMIN:
- case ISD::UMAX: Res = PromoteIntRes_UMINUMAX(N); break;
+ case ISD::UMAX: Res = PromoteIntRes_UMINUMAX(N); break;
case ISD::SHL: Res = PromoteIntRes_SHL(N); break;
case ISD::SIGN_EXTEND_INREG:
@@ -123,10 +123,10 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT: Res = PromoteIntRes_FP_TO_XINT(N); break;
- case ISD::FP_TO_SINT_SAT:
- case ISD::FP_TO_UINT_SAT:
- Res = PromoteIntRes_FP_TO_XINT_SAT(N); break;
-
+ case ISD::FP_TO_SINT_SAT:
+ case ISD::FP_TO_UINT_SAT:
+ Res = PromoteIntRes_FP_TO_XINT_SAT(N); break;
+
case ISD::FP_TO_FP16: Res = PromoteIntRes_FP_TO_FP16(N); break;
case ISD::FLT_ROUNDS_: Res = PromoteIntRes_FLT_ROUNDS(N); break;
@@ -156,15 +156,15 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
case ISD::ADDCARRY:
case ISD::SUBCARRY: Res = PromoteIntRes_ADDSUBCARRY(N, ResNo); break;
- case ISD::SADDO_CARRY:
- case ISD::SSUBO_CARRY: Res = PromoteIntRes_SADDSUBO_CARRY(N, ResNo); break;
-
+ case ISD::SADDO_CARRY:
+ case ISD::SSUBO_CARRY: Res = PromoteIntRes_SADDSUBO_CARRY(N, ResNo); break;
+
case ISD::SADDSAT:
case ISD::UADDSAT:
case ISD::SSUBSAT:
- case ISD::USUBSAT:
- case ISD::SSHLSAT:
- case ISD::USHLSAT: Res = PromoteIntRes_ADDSUBSHLSAT(N); break;
+ case ISD::USUBSAT:
+ case ISD::SSHLSAT:
+ case ISD::USHLSAT: Res = PromoteIntRes_ADDSUBSHLSAT(N); break;
case ISD::SMULFIX:
case ISD::SMULFIXSAT:
@@ -215,16 +215,16 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
case ISD::FREEZE:
Res = PromoteIntRes_FREEZE(N);
break;
-
- case ISD::ROTL:
- case ISD::ROTR:
- Res = PromoteIntRes_Rotate(N);
- break;
-
- case ISD::FSHL:
- case ISD::FSHR:
- Res = PromoteIntRes_FunnelShift(N);
- break;
+
+ case ISD::ROTL:
+ case ISD::ROTR:
+ Res = PromoteIntRes_Rotate(N);
+ break;
+
+ case ISD::FSHL:
+ case ISD::FSHR:
+ Res = PromoteIntRes_FunnelShift(N);
+ break;
}
// If the result is null then the sub-method took care of registering it.
@@ -511,10 +511,10 @@ SDValue DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) {
NVT));
}
-SDValue DAGTypeLegalizer::PromoteIntRes_CTPOP_PARITY(SDNode *N) {
- // Zero extend to the promoted type and do the count or parity there.
+SDValue DAGTypeLegalizer::PromoteIntRes_CTPOP_PARITY(SDNode *N) {
+ // Zero extend to the promoted type and do the count or parity there.
SDValue Op = ZExtPromotedInteger(N->getOperand(0));
- return DAG.getNode(N->getOpcode(), SDLoc(N), Op.getValueType(), Op);
+ return DAG.getNode(N->getOpcode(), SDLoc(N), Op.getValueType(), Op);
}
SDValue DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) {
@@ -579,8 +579,8 @@ SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) {
SDValue Res;
if (N->isStrictFPOpcode()) {
- Res = DAG.getNode(NewOpc, dl, {NVT, MVT::Other},
- {N->getOperand(0), N->getOperand(1)});
+ Res = DAG.getNode(NewOpc, dl, {NVT, MVT::Other},
+ {N->getOperand(0), N->getOperand(1)});
// Legalize the chain result - switch anything that used the old chain to
// use the new one.
ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
@@ -600,14 +600,14 @@ SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) {
DAG.getValueType(N->getValueType(0).getScalarType()));
}
-SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT_SAT(SDNode *N) {
- // Promote the result type, while keeping the original width in Op1.
- EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
- SDLoc dl(N);
- return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0),
- N->getOperand(1));
-}
-
+SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT_SAT(SDNode *N) {
+ // Promote the result type, while keeping the original width in Op1.
+ EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
+ SDLoc dl(N);
+ return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0),
+ N->getOperand(1));
+}
+
SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_FP16(SDNode *N) {
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
SDLoc dl(N);
@@ -691,17 +691,17 @@ SDValue DAGTypeLegalizer::PromoteIntRes_MGATHER(MaskedGatherSDNode *N) {
assert(NVT == ExtPassThru.getValueType() &&
"Gather result type and the passThru argument type should be the same");
- ISD::LoadExtType ExtType = N->getExtensionType();
- if (ExtType == ISD::NON_EXTLOAD)
- ExtType = ISD::EXTLOAD;
-
+ ISD::LoadExtType ExtType = N->getExtensionType();
+ if (ExtType == ISD::NON_EXTLOAD)
+ ExtType = ISD::EXTLOAD;
+
SDLoc dl(N);
SDValue Ops[] = {N->getChain(), ExtPassThru, N->getMask(), N->getBasePtr(),
N->getIndex(), N->getScale() };
SDValue Res = DAG.getMaskedGather(DAG.getVTList(NVT, MVT::Other),
N->getMemoryVT(), dl, Ops,
- N->getMemOperand(), N->getIndexType(),
- ExtType);
+ N->getMemOperand(), N->getIndexType(),
+ ExtType);
// Legalize the chain result - switch anything that used the old chain to
// use the new one.
ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
@@ -733,11 +733,11 @@ SDValue DAGTypeLegalizer::PromoteIntRes_Overflow(SDNode *N) {
return DAG.getBoolExtOrTrunc(Res.getValue(1), dl, NVT, VT);
}
-SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
+SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
// If the promoted type is legal, we can convert this to:
// 1. ANY_EXTEND iN to iM
// 2. SHL by M-N
- // 3. [US][ADD|SUB|SHL]SAT
+ // 3. [US][ADD|SUB|SHL]SAT
// 4. L/ASHR by M-N
// Else it is more efficient to convert this to a min and a max
// operation in the higher precision arithmetic.
@@ -747,13 +747,13 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
unsigned OldBits = Op1.getScalarValueSizeInBits();
unsigned Opcode = N->getOpcode();
- bool IsShift = Opcode == ISD::USHLSAT || Opcode == ISD::SSHLSAT;
+ bool IsShift = Opcode == ISD::USHLSAT || Opcode == ISD::SSHLSAT;
SDValue Op1Promoted, Op2Promoted;
- if (IsShift) {
- Op1Promoted = GetPromotedInteger(Op1);
- Op2Promoted = ZExtPromotedInteger(Op2);
- } else if (Opcode == ISD::UADDSAT || Opcode == ISD::USUBSAT) {
+ if (IsShift) {
+ Op1Promoted = GetPromotedInteger(Op1);
+ Op2Promoted = ZExtPromotedInteger(Op2);
+ } else if (Opcode == ISD::UADDSAT || Opcode == ISD::USUBSAT) {
Op1Promoted = ZExtPromotedInteger(Op1);
Op2Promoted = ZExtPromotedInteger(Op2);
} else {
@@ -763,24 +763,24 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
EVT PromotedType = Op1Promoted.getValueType();
unsigned NewBits = PromotedType.getScalarSizeInBits();
- // Shift cannot use a min/max expansion, we can't detect overflow if all of
- // the bits have been shifted out.
- if (IsShift || TLI.isOperationLegalOrCustom(Opcode, PromotedType)) {
+ // Shift cannot use a min/max expansion, we can't detect overflow if all of
+ // the bits have been shifted out.
+ if (IsShift || TLI.isOperationLegalOrCustom(Opcode, PromotedType)) {
unsigned ShiftOp;
switch (Opcode) {
case ISD::SADDSAT:
case ISD::SSUBSAT:
- case ISD::SSHLSAT:
+ case ISD::SSHLSAT:
ShiftOp = ISD::SRA;
break;
case ISD::UADDSAT:
case ISD::USUBSAT:
- case ISD::USHLSAT:
+ case ISD::USHLSAT:
ShiftOp = ISD::SRL;
break;
default:
llvm_unreachable("Expected opcode to be signed or unsigned saturation "
- "addition, subtraction or left shift");
+ "addition, subtraction or left shift");
}
unsigned SHLAmount = NewBits - OldBits;
@@ -788,9 +788,9 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBSHLSAT(SDNode *N) {
SDValue ShiftAmount = DAG.getConstant(SHLAmount, dl, SHVT);
Op1Promoted =
DAG.getNode(ISD::SHL, dl, PromotedType, Op1Promoted, ShiftAmount);
- if (!IsShift)
- Op2Promoted =
- DAG.getNode(ISD::SHL, dl, PromotedType, Op2Promoted, ShiftAmount);
+ if (!IsShift)
+ Op2Promoted =
+ DAG.getNode(ISD::SHL, dl, PromotedType, Op2Promoted, ShiftAmount);
SDValue Result =
DAG.getNode(Opcode, dl, PromotedType, Op1Promoted, Op2Promoted);
@@ -1118,15 +1118,15 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ZExtIntBinOp(SDNode *N) {
LHS.getValueType(), LHS, RHS);
}
-SDValue DAGTypeLegalizer::PromoteIntRes_UMINUMAX(SDNode *N) {
- // It doesn't matter if we sign extend or zero extend in the inputs. So do
- // whatever is best for the target.
- SDValue LHS = SExtOrZExtPromotedInteger(N->getOperand(0));
- SDValue RHS = SExtOrZExtPromotedInteger(N->getOperand(1));
- return DAG.getNode(N->getOpcode(), SDLoc(N),
- LHS.getValueType(), LHS, RHS);
-}
-
+SDValue DAGTypeLegalizer::PromoteIntRes_UMINUMAX(SDNode *N) {
+ // It doesn't matter if we sign extend or zero extend in the inputs. So do
+ // whatever is best for the target.
+ SDValue LHS = SExtOrZExtPromotedInteger(N->getOperand(0));
+ SDValue RHS = SExtOrZExtPromotedInteger(N->getOperand(1));
+ return DAG.getNode(N->getOpcode(), SDLoc(N),
+ LHS.getValueType(), LHS, RHS);
+}
+
SDValue DAGTypeLegalizer::PromoteIntRes_SRA(SDNode *N) {
// The input value must be properly sign extended.
SDValue LHS = SExtPromotedInteger(N->getOperand(0));
@@ -1145,60 +1145,60 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) {
return DAG.getNode(ISD::SRL, SDLoc(N), LHS.getValueType(), LHS, RHS);
}
-SDValue DAGTypeLegalizer::PromoteIntRes_Rotate(SDNode *N) {
- // Lower the rotate to shifts and ORs which can be promoted.
- SDValue Res;
- TLI.expandROT(N, true /*AllowVectorOps*/, Res, DAG);
- ReplaceValueWith(SDValue(N, 0), Res);
- return SDValue();
-}
-
-SDValue DAGTypeLegalizer::PromoteIntRes_FunnelShift(SDNode *N) {
- SDValue Hi = GetPromotedInteger(N->getOperand(0));
- SDValue Lo = GetPromotedInteger(N->getOperand(1));
- SDValue Amount = GetPromotedInteger(N->getOperand(2));
-
- SDLoc DL(N);
- EVT OldVT = N->getOperand(0).getValueType();
- EVT VT = Lo.getValueType();
- unsigned Opcode = N->getOpcode();
- bool IsFSHR = Opcode == ISD::FSHR;
- unsigned OldBits = OldVT.getScalarSizeInBits();
- unsigned NewBits = VT.getScalarSizeInBits();
-
- // Amount has to be interpreted modulo the old bit width.
- Amount =
- DAG.getNode(ISD::UREM, DL, VT, Amount, DAG.getConstant(OldBits, DL, VT));
-
- // If the promoted type is twice the size (or more), then we use the
- // traditional funnel 'double' shift codegen. This isn't necessary if the
- // shift amount is constant.
- // fshl(x,y,z) -> (((aext(x) << bw) | zext(y)) << (z % bw)) >> bw.
- // fshr(x,y,z) -> (((aext(x) << bw) | zext(y)) >> (z % bw)).
- if (NewBits >= (2 * OldBits) && !isa<ConstantSDNode>(Amount) &&
- !TLI.isOperationLegalOrCustom(Opcode, VT)) {
- SDValue HiShift = DAG.getConstant(OldBits, DL, VT);
- Hi = DAG.getNode(ISD::SHL, DL, VT, Hi, HiShift);
- Lo = DAG.getZeroExtendInReg(Lo, DL, OldVT);
- SDValue Res = DAG.getNode(ISD::OR, DL, VT, Hi, Lo);
- Res = DAG.getNode(IsFSHR ? ISD::SRL : ISD::SHL, DL, VT, Res, Amount);
- if (!IsFSHR)
- Res = DAG.getNode(ISD::SRL, DL, VT, Res, HiShift);
- return Res;
- }
-
- // Shift Lo up to occupy the upper bits of the promoted type.
- SDValue ShiftOffset = DAG.getConstant(NewBits - OldBits, DL, VT);
- Lo = DAG.getNode(ISD::SHL, DL, VT, Lo, ShiftOffset);
-
- // Increase Amount to shift the result into the lower bits of the promoted
- // type.
- if (IsFSHR)
- Amount = DAG.getNode(ISD::ADD, DL, VT, Amount, ShiftOffset);
-
- return DAG.getNode(Opcode, DL, VT, Hi, Lo, Amount);
-}
-
+SDValue DAGTypeLegalizer::PromoteIntRes_Rotate(SDNode *N) {
+ // Lower the rotate to shifts and ORs which can be promoted.
+ SDValue Res;
+ TLI.expandROT(N, true /*AllowVectorOps*/, Res, DAG);
+ ReplaceValueWith(SDValue(N, 0), Res);
+ return SDValue();
+}
+
+SDValue DAGTypeLegalizer::PromoteIntRes_FunnelShift(SDNode *N) {
+ SDValue Hi = GetPromotedInteger(N->getOperand(0));
+ SDValue Lo = GetPromotedInteger(N->getOperand(1));
+ SDValue Amount = GetPromotedInteger(N->getOperand(2));
+
+ SDLoc DL(N);
+ EVT OldVT = N->getOperand(0).getValueType();
+ EVT VT = Lo.getValueType();
+ unsigned Opcode = N->getOpcode();
+ bool IsFSHR = Opcode == ISD::FSHR;
+ unsigned OldBits = OldVT.getScalarSizeInBits();
+ unsigned NewBits = VT.getScalarSizeInBits();
+
+ // Amount has to be interpreted modulo the old bit width.
+ Amount =
+ DAG.getNode(ISD::UREM, DL, VT, Amount, DAG.getConstant(OldBits, DL, VT));
+
+ // If the promoted type is twice the size (or more), then we use the
+ // traditional funnel 'double' shift codegen. This isn't necessary if the
+ // shift amount is constant.
+ // fshl(x,y,z) -> (((aext(x) << bw) | zext(y)) << (z % bw)) >> bw.
+ // fshr(x,y,z) -> (((aext(x) << bw) | zext(y)) >> (z % bw)).
+ if (NewBits >= (2 * OldBits) && !isa<ConstantSDNode>(Amount) &&
+ !TLI.isOperationLegalOrCustom(Opcode, VT)) {
+ SDValue HiShift = DAG.getConstant(OldBits, DL, VT);
+ Hi = DAG.getNode(ISD::SHL, DL, VT, Hi, HiShift);
+ Lo = DAG.getZeroExtendInReg(Lo, DL, OldVT);
+ SDValue Res = DAG.getNode(ISD::OR, DL, VT, Hi, Lo);
+ Res = DAG.getNode(IsFSHR ? ISD::SRL : ISD::SHL, DL, VT, Res, Amount);
+ if (!IsFSHR)
+ Res = DAG.getNode(ISD::SRL, DL, VT, Res, HiShift);
+ return Res;
+ }
+
+ // Shift Lo up to occupy the upper bits of the promoted type.
+ SDValue ShiftOffset = DAG.getConstant(NewBits - OldBits, DL, VT);
+ Lo = DAG.getNode(ISD::SHL, DL, VT, Lo, ShiftOffset);
+
+ // Increase Amount to shift the result into the lower bits of the promoted
+ // type.
+ if (IsFSHR)
+ Amount = DAG.getNode(ISD::ADD, DL, VT, Amount, ShiftOffset);
+
+ return DAG.getNode(Opcode, DL, VT, Hi, Lo, Amount);
+}
+
SDValue DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) {
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
SDValue Res;
@@ -1286,7 +1286,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_UADDSUBO(SDNode *N, unsigned ResNo) {
}
// Handle promotion for the ADDE/SUBE/ADDCARRY/SUBCARRY nodes. Notice that
-// the third operand of ADDE/SUBE nodes is carry flag, which differs from
+// the third operand of ADDE/SUBE nodes is carry flag, which differs from
// the ADDCARRY/SUBCARRY nodes in that the third operand is carry Boolean.
SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBCARRY(SDNode *N, unsigned ResNo) {
if (ResNo == 1)
@@ -1317,12 +1317,12 @@ SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBCARRY(SDNode *N, unsigned ResNo) {
return SDValue(Res.getNode(), 0);
}
-SDValue DAGTypeLegalizer::PromoteIntRes_SADDSUBO_CARRY(SDNode *N,
- unsigned ResNo) {
- assert(ResNo == 1 && "Don't know how to promote other results yet.");
- return PromoteIntRes_Overflow(N);
-}
-
+SDValue DAGTypeLegalizer::PromoteIntRes_SADDSUBO_CARRY(SDNode *N,
+ unsigned ResNo) {
+ assert(ResNo == 1 && "Don't know how to promote other results yet.");
+ return PromoteIntRes_Overflow(N);
+}
+
SDValue DAGTypeLegalizer::PromoteIntRes_ABS(SDNode *N) {
SDValue Op0 = SExtPromotedInteger(N->getOperand(0));
return DAG.getNode(ISD::ABS, SDLoc(N), Op0.getValueType(), Op0);
@@ -1505,8 +1505,8 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
case ISD::ROTL:
case ISD::ROTR: Res = PromoteIntOp_Shift(N); break;
- case ISD::SADDO_CARRY:
- case ISD::SSUBO_CARRY:
+ case ISD::SADDO_CARRY:
+ case ISD::SSUBO_CARRY:
case ISD::ADDCARRY:
case ISD::SUBCARRY: Res = PromoteIntOp_ADDSUBCARRY(N, OpNo); break;
@@ -1733,9 +1733,9 @@ SDValue DAGTypeLegalizer::PromoteIntOp_SELECT(SDNode *N, unsigned OpNo) {
EVT OpTy = N->getOperand(1).getValueType();
if (N->getOpcode() == ISD::VSELECT)
- if (SDValue Res = WidenVSELECTMask(N))
- return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0),
- Res, N->getOperand(1), N->getOperand(2));
+ if (SDValue Res = WidenVSELECTMask(N))
+ return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0),
+ Res, N->getOperand(1), N->getOperand(2));
// Promote all the way up to the canonical SetCC type.
EVT OpVT = N->getOpcode() == ISD::SELECT ? OpTy.getScalarType() : OpTy;
@@ -1877,7 +1877,7 @@ SDValue DAGTypeLegalizer::PromoteIntOp_MGATHER(MaskedGatherSDNode *N,
SDValue DAGTypeLegalizer::PromoteIntOp_MSCATTER(MaskedScatterSDNode *N,
unsigned OpNo) {
- bool TruncateStore = N->isTruncatingStore();
+ bool TruncateStore = N->isTruncatingStore();
SmallVector<SDValue, 5> NewOps(N->op_begin(), N->op_end());
if (OpNo == 2) {
// The Mask
@@ -1890,17 +1890,17 @@ SDValue DAGTypeLegalizer::PromoteIntOp_MSCATTER(MaskedScatterSDNode *N,
NewOps[OpNo] = SExtPromotedInteger(N->getOperand(OpNo));
else
NewOps[OpNo] = ZExtPromotedInteger(N->getOperand(OpNo));
-
- N->setIndexType(TLI.getCanonicalIndexType(N->getIndexType(),
- N->getMemoryVT(), NewOps[OpNo]));
- } else {
+
+ N->setIndexType(TLI.getCanonicalIndexType(N->getIndexType(),
+ N->getMemoryVT(), NewOps[OpNo]));
+ } else {
NewOps[OpNo] = GetPromotedInteger(N->getOperand(OpNo));
- TruncateStore = true;
- }
-
- return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), N->getMemoryVT(),
- SDLoc(N), NewOps, N->getMemOperand(),
- N->getIndexType(), TruncateStore);
+ TruncateStore = true;
+ }
+
+ return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), N->getMemoryVT(),
+ SDLoc(N), NewOps, N->getMemOperand(),
+ N->getIndexType(), TruncateStore);
}
SDValue DAGTypeLegalizer::PromoteIntOp_TRUNCATE(SDNode *N) {
@@ -2044,7 +2044,7 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
case ISD::AssertZext: ExpandIntRes_AssertZext(N, Lo, Hi); break;
case ISD::BITREVERSE: ExpandIntRes_BITREVERSE(N, Lo, Hi); break;
case ISD::BSWAP: ExpandIntRes_BSWAP(N, Lo, Hi); break;
- case ISD::PARITY: ExpandIntRes_PARITY(N, Lo, Hi); break;
+ case ISD::PARITY: ExpandIntRes_PARITY(N, Lo, Hi); break;
case ISD::Constant: ExpandIntRes_Constant(N, Lo, Hi); break;
case ISD::ABS: ExpandIntRes_ABS(N, Lo, Hi); break;
case ISD::CTLZ_ZERO_UNDEF:
@@ -2057,8 +2057,8 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
case ISD::FP_TO_SINT: ExpandIntRes_FP_TO_SINT(N, Lo, Hi); break;
case ISD::STRICT_FP_TO_UINT:
case ISD::FP_TO_UINT: ExpandIntRes_FP_TO_UINT(N, Lo, Hi); break;
- case ISD::FP_TO_SINT_SAT:
- case ISD::FP_TO_UINT_SAT: ExpandIntRes_FP_TO_XINT_SAT(N, Lo, Hi); break;
+ case ISD::FP_TO_SINT_SAT:
+ case ISD::FP_TO_UINT_SAT: ExpandIntRes_FP_TO_XINT_SAT(N, Lo, Hi); break;
case ISD::STRICT_LLROUND:
case ISD::STRICT_LLRINT:
case ISD::LLROUND:
@@ -2135,9 +2135,9 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
case ISD::ADDCARRY:
case ISD::SUBCARRY: ExpandIntRes_ADDSUBCARRY(N, Lo, Hi); break;
- case ISD::SADDO_CARRY:
- case ISD::SSUBO_CARRY: ExpandIntRes_SADDSUBO_CARRY(N, Lo, Hi); break;
-
+ case ISD::SADDO_CARRY:
+ case ISD::SSUBO_CARRY: ExpandIntRes_SADDSUBO_CARRY(N, Lo, Hi); break;
+
case ISD::SHL:
case ISD::SRA:
case ISD::SRL: ExpandIntRes_Shift(N, Lo, Hi); break;
@@ -2154,9 +2154,9 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
case ISD::SSUBSAT:
case ISD::USUBSAT: ExpandIntRes_ADDSUBSAT(N, Lo, Hi); break;
- case ISD::SSHLSAT:
- case ISD::USHLSAT: ExpandIntRes_SHLSAT(N, Lo, Hi); break;
-
+ case ISD::SSHLSAT:
+ case ISD::USHLSAT: ExpandIntRes_SHLSAT(N, Lo, Hi); break;
+
case ISD::SMULFIX:
case ISD::SMULFIXSAT:
case ISD::UMULFIX:
@@ -2176,16 +2176,16 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
case ISD::VECREDUCE_SMIN:
case ISD::VECREDUCE_UMAX:
case ISD::VECREDUCE_UMIN: ExpandIntRes_VECREDUCE(N, Lo, Hi); break;
-
- case ISD::ROTL:
- case ISD::ROTR:
- ExpandIntRes_Rotate(N, Lo, Hi);
- break;
-
- case ISD::FSHL:
- case ISD::FSHR:
- ExpandIntRes_FunnelShift(N, Lo, Hi);
- break;
+
+ case ISD::ROTL:
+ case ISD::ROTR:
+ ExpandIntRes_Rotate(N, Lo, Hi);
+ break;
+
+ case ISD::FSHL:
+ case ISD::FSHR:
+ ExpandIntRes_FunnelShift(N, Lo, Hi);
+ break;
}
// If Lo/Hi is null, the sub-method took care of registering results etc.
@@ -2197,22 +2197,22 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
std::pair <SDValue, SDValue> DAGTypeLegalizer::ExpandAtomic(SDNode *Node) {
unsigned Opc = Node->getOpcode();
MVT VT = cast<AtomicSDNode>(Node)->getMemoryVT().getSimpleVT();
- AtomicOrdering order = cast<AtomicSDNode>(Node)->getOrdering();
- // Lower to outline atomic libcall if outline atomics enabled,
- // or to sync libcall otherwise
- RTLIB::Libcall LC = RTLIB::getOUTLINE_ATOMIC(Opc, order, VT);
+ AtomicOrdering order = cast<AtomicSDNode>(Node)->getOrdering();
+ // Lower to outline atomic libcall if outline atomics enabled,
+ // or to sync libcall otherwise
+ RTLIB::Libcall LC = RTLIB::getOUTLINE_ATOMIC(Opc, order, VT);
EVT RetVT = Node->getValueType(0);
TargetLowering::MakeLibCallOptions CallOptions;
- SmallVector<SDValue, 4> Ops;
- if (TLI.getLibcallName(LC)) {
- Ops.append(Node->op_begin() + 2, Node->op_end());
- Ops.push_back(Node->getOperand(1));
- } else {
- LC = RTLIB::getSYNC(Opc, VT);
- assert(LC != RTLIB::UNKNOWN_LIBCALL &&
- "Unexpected atomic op or value type!");
- Ops.append(Node->op_begin() + 1, Node->op_end());
- }
+ SmallVector<SDValue, 4> Ops;
+ if (TLI.getLibcallName(LC)) {
+ Ops.append(Node->op_begin() + 2, Node->op_end());
+ Ops.push_back(Node->getOperand(1));
+ } else {
+ LC = RTLIB::getSYNC(Opc, VT);
+ assert(LC != RTLIB::UNKNOWN_LIBCALL &&
+ "Unexpected atomic op or value type!");
+ Ops.append(Node->op_begin() + 1, Node->op_end());
+ }
return TLI.makeLibCall(DAG, LC, RetVT, Ops, CallOptions, SDLoc(Node),
Node->getOperand(0));
}
@@ -2771,26 +2771,26 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBCARRY(SDNode *N,
ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
}
-void DAGTypeLegalizer::ExpandIntRes_SADDSUBO_CARRY(SDNode *N,
- SDValue &Lo, SDValue &Hi) {
- // Expand the subcomponents.
- SDValue LHSL, LHSH, RHSL, RHSH;
- SDLoc dl(N);
- GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
- GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
- SDVTList VTList = DAG.getVTList(LHSL.getValueType(), N->getValueType(1));
-
- // We need to use an unsigned carry op for the lo part.
- unsigned CarryOp = N->getOpcode() == ISD::SADDO_CARRY ? ISD::ADDCARRY
- : ISD::SUBCARRY;
- Lo = DAG.getNode(CarryOp, dl, VTList, { LHSL, RHSL, N->getOperand(2) });
- Hi = DAG.getNode(N->getOpcode(), dl, VTList, { LHSH, RHSH, Lo.getValue(1) });
-
- // Legalized the flag result - switch anything that used the old flag to
- // use the new one.
- ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
-}
-
+void DAGTypeLegalizer::ExpandIntRes_SADDSUBO_CARRY(SDNode *N,
+ SDValue &Lo, SDValue &Hi) {
+ // Expand the subcomponents.
+ SDValue LHSL, LHSH, RHSL, RHSH;
+ SDLoc dl(N);
+ GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
+ GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
+ SDVTList VTList = DAG.getVTList(LHSL.getValueType(), N->getValueType(1));
+
+ // We need to use an unsigned carry op for the lo part.
+ unsigned CarryOp = N->getOpcode() == ISD::SADDO_CARRY ? ISD::ADDCARRY
+ : ISD::SUBCARRY;
+ Lo = DAG.getNode(CarryOp, dl, VTList, { LHSL, RHSL, N->getOperand(2) });
+ Hi = DAG.getNode(N->getOpcode(), dl, VTList, { LHSH, RHSH, Lo.getValue(1) });
+
+ // Legalized the flag result - switch anything that used the old flag to
+ // use the new one.
+ ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
+}
+
void DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N,
SDValue &Lo, SDValue &Hi) {
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
@@ -2872,17 +2872,17 @@ void DAGTypeLegalizer::ExpandIntRes_BSWAP(SDNode *N,
Hi = DAG.getNode(ISD::BSWAP, dl, Hi.getValueType(), Hi);
}
-void DAGTypeLegalizer::ExpandIntRes_PARITY(SDNode *N, SDValue &Lo,
- SDValue &Hi) {
- SDLoc dl(N);
- // parity(HiLo) -> parity(Lo^Hi)
- GetExpandedInteger(N->getOperand(0), Lo, Hi);
- EVT NVT = Lo.getValueType();
- Lo =
- DAG.getNode(ISD::PARITY, dl, NVT, DAG.getNode(ISD::XOR, dl, NVT, Lo, Hi));
- Hi = DAG.getConstant(0, dl, NVT);
-}
-
+void DAGTypeLegalizer::ExpandIntRes_PARITY(SDNode *N, SDValue &Lo,
+ SDValue &Hi) {
+ SDLoc dl(N);
+ // parity(HiLo) -> parity(Lo^Hi)
+ GetExpandedInteger(N->getOperand(0), Lo, Hi);
+ EVT NVT = Lo.getValueType();
+ Lo =
+ DAG.getNode(ISD::PARITY, dl, NVT, DAG.getNode(ISD::XOR, dl, NVT, Lo, Hi));
+ Hi = DAG.getConstant(0, dl, NVT);
+}
+
void DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N,
SDValue &Lo, SDValue &Hi) {
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
@@ -2900,31 +2900,31 @@ void DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N,
void DAGTypeLegalizer::ExpandIntRes_ABS(SDNode *N, SDValue &Lo, SDValue &Hi) {
SDLoc dl(N);
- SDValue N0 = N->getOperand(0);
- GetExpandedInteger(N0, Lo, Hi);
- EVT NVT = Lo.getValueType();
-
- // If we have ADDCARRY, use the expanded form of the sra+add+xor sequence we
- // use in LegalizeDAG. The ADD part of the expansion is based on
- // ExpandIntRes_ADDSUB which also uses ADDCARRY/UADDO after checking that
- // ADDCARRY is LegalOrCustom. Each of the pieces here can be further expanded
- // if needed. Shift expansion has a special case for filling with sign bits
- // so that we will only end up with one SRA.
- bool HasAddCarry = TLI.isOperationLegalOrCustom(
- ISD::ADDCARRY, TLI.getTypeToExpandTo(*DAG.getContext(), NVT));
- if (HasAddCarry) {
- EVT ShiftAmtTy = getShiftAmountTyForConstant(NVT, TLI, DAG);
- SDValue Sign =
- DAG.getNode(ISD::SRA, dl, NVT, Hi,
- DAG.getConstant(NVT.getSizeInBits() - 1, dl, ShiftAmtTy));
- SDVTList VTList = DAG.getVTList(NVT, getSetCCResultType(NVT));
- Lo = DAG.getNode(ISD::UADDO, dl, VTList, Lo, Sign);
- Hi = DAG.getNode(ISD::ADDCARRY, dl, VTList, Hi, Sign, Lo.getValue(1));
- Lo = DAG.getNode(ISD::XOR, dl, NVT, Lo, Sign);
- Hi = DAG.getNode(ISD::XOR, dl, NVT, Hi, Sign);
- return;
- }
-
+ SDValue N0 = N->getOperand(0);
+ GetExpandedInteger(N0, Lo, Hi);
+ EVT NVT = Lo.getValueType();
+
+ // If we have ADDCARRY, use the expanded form of the sra+add+xor sequence we
+ // use in LegalizeDAG. The ADD part of the expansion is based on
+ // ExpandIntRes_ADDSUB which also uses ADDCARRY/UADDO after checking that
+ // ADDCARRY is LegalOrCustom. Each of the pieces here can be further expanded
+ // if needed. Shift expansion has a special case for filling with sign bits
+ // so that we will only end up with one SRA.
+ bool HasAddCarry = TLI.isOperationLegalOrCustom(
+ ISD::ADDCARRY, TLI.getTypeToExpandTo(*DAG.getContext(), NVT));
+ if (HasAddCarry) {
+ EVT ShiftAmtTy = getShiftAmountTyForConstant(NVT, TLI, DAG);
+ SDValue Sign =
+ DAG.getNode(ISD::SRA, dl, NVT, Hi,
+ DAG.getConstant(NVT.getSizeInBits() - 1, dl, ShiftAmtTy));
+ SDVTList VTList = DAG.getVTList(NVT, getSetCCResultType(NVT));
+ Lo = DAG.getNode(ISD::UADDO, dl, VTList, Lo, Sign);
+ Hi = DAG.getNode(ISD::ADDCARRY, dl, VTList, Hi, Sign, Lo.getValue(1));
+ Lo = DAG.getNode(ISD::XOR, dl, NVT, Lo, Sign);
+ Hi = DAG.getNode(ISD::XOR, dl, NVT, Hi, Sign);
+ return;
+ }
+
// abs(HiLo) -> (Hi < 0 ? -HiLo : HiLo)
EVT VT = N->getValueType(0);
SDValue Neg = DAG.getNode(ISD::SUB, dl, VT,
@@ -3064,12 +3064,12 @@ void DAGTypeLegalizer::ExpandIntRes_FP_TO_UINT(SDNode *N, SDValue &Lo,
ReplaceValueWith(SDValue(N, 1), Tmp.second);
}
-void DAGTypeLegalizer::ExpandIntRes_FP_TO_XINT_SAT(SDNode *N, SDValue &Lo,
- SDValue &Hi) {
- SDValue Res = TLI.expandFP_TO_INT_SAT(N, DAG);
- SplitInteger(Res, Lo, Hi);
-}
-
+void DAGTypeLegalizer::ExpandIntRes_FP_TO_XINT_SAT(SDNode *N, SDValue &Lo,
+ SDValue &Hi) {
+ SDValue Res = TLI.expandFP_TO_INT_SAT(N, DAG);
+ SplitInteger(Res, Lo, Hi);
+}
+
void DAGTypeLegalizer::ExpandIntRes_LLROUND_LLRINT(SDNode *N, SDValue &Lo,
SDValue &Hi) {
SDValue Op = N->getOperand(N->isStrictFPOpcode() ? 1 : 0);
@@ -3140,7 +3140,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
ReplaceValueWith(SDValue(N, 1), Swap.getValue(2));
return;
}
-
+
if (ISD::isNormalLoad(N)) {
ExpandRes_NormalLoad(N, Lo, Hi);
return;
@@ -3194,7 +3194,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
// Increment the pointer to the other half.
unsigned IncrementSize = NVT.getSizeInBits()/8;
- Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(IncrementSize), dl);
+ Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(IncrementSize), dl);
Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr,
N->getPointerInfo().getWithOffset(IncrementSize), NEVT,
N->getOriginalAlign(), MMOFlags, AAInfo);
@@ -3218,7 +3218,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
N->getOriginalAlign(), MMOFlags, AAInfo);
// Increment the pointer to the other half.
- Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(IncrementSize), dl);
+ Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(IncrementSize), dl);
// Load the rest of the low bits.
Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, NVT, Ch, Ptr,
N->getPointerInfo().getWithOffset(IncrementSize),
@@ -3358,12 +3358,12 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBSAT(SDNode *N, SDValue &Lo,
SplitInteger(Result, Lo, Hi);
}
-void DAGTypeLegalizer::ExpandIntRes_SHLSAT(SDNode *N, SDValue &Lo,
- SDValue &Hi) {
- SDValue Result = TLI.expandShlSat(N, DAG);
- SplitInteger(Result, Lo, Hi);
-}
-
+void DAGTypeLegalizer::ExpandIntRes_SHLSAT(SDNode *N, SDValue &Lo,
+ SDValue &Hi) {
+ SDValue Result = TLI.expandShlSat(N, DAG);
+ SplitInteger(Result, Lo, Hi);
+}
+
/// This performs an expansion of the integer result for a fixed point
/// multiplication. The default expansion performs rounding down towards
/// negative infinity, though targets that do care about rounding should specify
@@ -3602,66 +3602,66 @@ void DAGTypeLegalizer::ExpandIntRes_SADDSUBO(SDNode *Node,
SDValue RHS = Node->getOperand(1);
SDLoc dl(Node);
- SDValue Ovf;
-
- unsigned CarryOp;
- switch(Node->getOpcode()) {
- default: llvm_unreachable("Node has unexpected Opcode");
- case ISD::SADDO: CarryOp = ISD::SADDO_CARRY; break;
- case ISD::SSUBO: CarryOp = ISD::SSUBO_CARRY; break;
- }
-
- bool HasCarryOp = TLI.isOperationLegalOrCustom(
- CarryOp, TLI.getTypeToExpandTo(*DAG.getContext(), LHS.getValueType()));
-
- if (HasCarryOp) {
- // Expand the subcomponents.
- SDValue LHSL, LHSH, RHSL, RHSH;
- GetExpandedInteger(LHS, LHSL, LHSH);
- GetExpandedInteger(RHS, RHSL, RHSH);
- SDVTList VTList = DAG.getVTList(LHSL.getValueType(), Node->getValueType(1));
-
- Lo = DAG.getNode(Node->getOpcode() == ISD::SADDO ?
- ISD::UADDO : ISD::USUBO, dl, VTList, { LHSL, RHSL });
- Hi = DAG.getNode(CarryOp, dl, VTList, { LHSH, RHSH, Lo.getValue(1) });
-
- Ovf = Hi.getValue(1);
- } else {
- // Expand the result by simply replacing it with the equivalent
- // non-overflow-checking operation.
- SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::SADDO ?
- ISD::ADD : ISD::SUB, dl, LHS.getValueType(),
- LHS, RHS);
- SplitInteger(Sum, Lo, Hi);
-
- // Compute the overflow.
- //
- // LHSSign -> LHS >= 0
- // RHSSign -> RHS >= 0
- // SumSign -> Sum >= 0
- //
- // Add:
- // Overflow -> (LHSSign == RHSSign) && (LHSSign != SumSign)
- // Sub:
- // Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign)
- //
- EVT OType = Node->getValueType(1);
- SDValue Zero = DAG.getConstant(0, dl, LHS.getValueType());
-
- SDValue LHSSign = DAG.getSetCC(dl, OType, LHS, Zero, ISD::SETGE);
- SDValue RHSSign = DAG.getSetCC(dl, OType, RHS, Zero, ISD::SETGE);
- SDValue SignsMatch = DAG.getSetCC(dl, OType, LHSSign, RHSSign,
- Node->getOpcode() == ISD::SADDO ?
- ISD::SETEQ : ISD::SETNE);
-
- SDValue SumSign = DAG.getSetCC(dl, OType, Sum, Zero, ISD::SETGE);
- SDValue SumSignNE = DAG.getSetCC(dl, OType, LHSSign, SumSign, ISD::SETNE);
-
- Ovf = DAG.getNode(ISD::AND, dl, OType, SignsMatch, SumSignNE);
- }
-
+ SDValue Ovf;
+
+ unsigned CarryOp;
+ switch(Node->getOpcode()) {
+ default: llvm_unreachable("Node has unexpected Opcode");
+ case ISD::SADDO: CarryOp = ISD::SADDO_CARRY; break;
+ case ISD::SSUBO: CarryOp = ISD::SSUBO_CARRY; break;
+ }
+
+ bool HasCarryOp = TLI.isOperationLegalOrCustom(
+ CarryOp, TLI.getTypeToExpandTo(*DAG.getContext(), LHS.getValueType()));
+
+ if (HasCarryOp) {
+ // Expand the subcomponents.
+ SDValue LHSL, LHSH, RHSL, RHSH;
+ GetExpandedInteger(LHS, LHSL, LHSH);
+ GetExpandedInteger(RHS, RHSL, RHSH);
+ SDVTList VTList = DAG.getVTList(LHSL.getValueType(), Node->getValueType(1));
+
+ Lo = DAG.getNode(Node->getOpcode() == ISD::SADDO ?
+ ISD::UADDO : ISD::USUBO, dl, VTList, { LHSL, RHSL });
+ Hi = DAG.getNode(CarryOp, dl, VTList, { LHSH, RHSH, Lo.getValue(1) });
+
+ Ovf = Hi.getValue(1);
+ } else {
+ // Expand the result by simply replacing it with the equivalent
+ // non-overflow-checking operation.
+ SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::SADDO ?
+ ISD::ADD : ISD::SUB, dl, LHS.getValueType(),
+ LHS, RHS);
+ SplitInteger(Sum, Lo, Hi);
+
+ // Compute the overflow.
+ //
+ // LHSSign -> LHS >= 0
+ // RHSSign -> RHS >= 0
+ // SumSign -> Sum >= 0
+ //
+ // Add:
+ // Overflow -> (LHSSign == RHSSign) && (LHSSign != SumSign)
+ // Sub:
+ // Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign)
+ //
+ EVT OType = Node->getValueType(1);
+ SDValue Zero = DAG.getConstant(0, dl, LHS.getValueType());
+
+ SDValue LHSSign = DAG.getSetCC(dl, OType, LHS, Zero, ISD::SETGE);
+ SDValue RHSSign = DAG.getSetCC(dl, OType, RHS, Zero, ISD::SETGE);
+ SDValue SignsMatch = DAG.getSetCC(dl, OType, LHSSign, RHSSign,
+ Node->getOpcode() == ISD::SADDO ?
+ ISD::SETEQ : ISD::SETNE);
+
+ SDValue SumSign = DAG.getSetCC(dl, OType, Sum, Zero, ISD::SETGE);
+ SDValue SumSignNE = DAG.getSetCC(dl, OType, LHSSign, SumSign, ISD::SETNE);
+
+ Ovf = DAG.getNode(ISD::AND, dl, OType, SignsMatch, SumSignNE);
+ }
+
// Use the calculated overflow everywhere.
- ReplaceValueWith(SDValue(Node, 1), Ovf);
+ ReplaceValueWith(SDValue(Node, 1), Ovf);
}
void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N,
@@ -4117,22 +4117,22 @@ void DAGTypeLegalizer::ExpandIntRes_VECREDUCE(SDNode *N,
SplitInteger(Res, Lo, Hi);
}
-void DAGTypeLegalizer::ExpandIntRes_Rotate(SDNode *N,
- SDValue &Lo, SDValue &Hi) {
- // Lower the rotate to shifts and ORs which can be expanded.
- SDValue Res;
- TLI.expandROT(N, true /*AllowVectorOps*/, Res, DAG);
- SplitInteger(Res, Lo, Hi);
-}
-
-void DAGTypeLegalizer::ExpandIntRes_FunnelShift(SDNode *N,
- SDValue &Lo, SDValue &Hi) {
- // Lower the funnel shift to shifts and ORs which can be expanded.
- SDValue Res;
- TLI.expandFunnelShift(N, Res, DAG);
- SplitInteger(Res, Lo, Hi);
-}
-
+void DAGTypeLegalizer::ExpandIntRes_Rotate(SDNode *N,
+ SDValue &Lo, SDValue &Hi) {
+ // Lower the rotate to shifts and ORs which can be expanded.
+ SDValue Res;
+ TLI.expandROT(N, true /*AllowVectorOps*/, Res, DAG);
+ SplitInteger(Res, Lo, Hi);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_FunnelShift(SDNode *N,
+ SDValue &Lo, SDValue &Hi) {
+ // Lower the funnel shift to shifts and ORs which can be expanded.
+ SDValue Res;
+ TLI.expandFunnelShift(N, Res, DAG);
+ SplitInteger(Res, Lo, Hi);
+}
+
//===----------------------------------------------------------------------===//
// Integer Operand Expansion
//===----------------------------------------------------------------------===//
@@ -4505,7 +4505,7 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
// Increment the pointer to the other half.
unsigned IncrementSize = NVT.getSizeInBits()/8;
- Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::Fixed(IncrementSize));
+ Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::Fixed(IncrementSize));
Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr,
N->getPointerInfo().getWithOffset(IncrementSize),
NEVT, N->getOriginalAlign(), MMOFlags, AAInfo);
@@ -4540,7 +4540,7 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
N->getOriginalAlign(), MMOFlags, AAInfo);
// Increment the pointer to the other half.
- Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::Fixed(IncrementSize));
+ Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::Fixed(IncrementSize));
// Store the lowest ExcessBits bits in the second half.
Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr,
N->getPointerInfo().getWithOffset(IncrementSize),
@@ -4845,23 +4845,23 @@ SDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_SUBVECTOR(SDNode *N) {
SDValue DAGTypeLegalizer::PromoteIntOp_CONCAT_VECTORS(SDNode *N) {
SDLoc dl(N);
-
- EVT ResVT = N->getValueType(0);
+
+ EVT ResVT = N->getValueType(0);
unsigned NumElems = N->getNumOperands();
- if (ResVT.isScalableVector()) {
- SDValue ResVec = DAG.getUNDEF(ResVT);
-
- for (unsigned OpIdx = 0; OpIdx < NumElems; ++OpIdx) {
- SDValue Op = N->getOperand(OpIdx);
- unsigned OpNumElts = Op.getValueType().getVectorMinNumElements();
- ResVec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, ResVec, Op,
- DAG.getIntPtrConstant(OpIdx * OpNumElts, dl));
- }
-
- return ResVec;
- }
-
+ if (ResVT.isScalableVector()) {
+ SDValue ResVec = DAG.getUNDEF(ResVT);
+
+ for (unsigned OpIdx = 0; OpIdx < NumElems; ++OpIdx) {
+ SDValue Op = N->getOperand(OpIdx);
+ unsigned OpNumElts = Op.getValueType().getVectorMinNumElements();
+ ResVec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, ResVec, Op,
+ DAG.getIntPtrConstant(OpIdx * OpNumElts, dl));
+ }
+
+ return ResVec;
+ }
+
EVT RetSclrTy = N->getValueType(0).getVectorElementType();
SmallVector<SDValue, 8> NewOps;
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
index dda87ad719..a59f038547 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
@@ -663,7 +663,7 @@ void DAGTypeLegalizer::ReplaceValueWith(SDValue From, SDValue To) {
// Process the list of nodes that need to be reanalyzed.
while (!NodesToAnalyze.empty()) {
- SDNode *N = NodesToAnalyze.pop_back_val();
+ SDNode *N = NodesToAnalyze.pop_back_val();
if (N->getNodeId() != DAGTypeLegalizer::NewNode)
// The node was analyzed while reanalyzing an earlier node - it is safe
// to skip. Note that this is not a morphing node - otherwise it would
@@ -752,10 +752,10 @@ void DAGTypeLegalizer::SetScalarizedVector(SDValue Op, SDValue Result) {
// Note that in some cases vector operation operands may be greater than
// the vector element type. For example BUILD_VECTOR of type <1 x i1> with
// a constant i8 operand.
-
- // We don't currently support the scalarization of scalable vector types.
- assert(Result.getValueSizeInBits().getFixedSize() >=
- Op.getScalarValueSizeInBits() &&
+
+ // We don't currently support the scalarization of scalable vector types.
+ assert(Result.getValueSizeInBits().getFixedSize() >=
+ Op.getScalarValueSizeInBits() &&
"Invalid type for scalarized vector");
AnalyzeNewValue(Result);
@@ -957,11 +957,11 @@ bool DAGTypeLegalizer::CustomWidenLowerNode(SDNode *N, EVT VT) {
assert(Results.size() == N->getNumValues() &&
"Custom lowering returned the wrong number of results!");
for (unsigned i = 0, e = Results.size(); i != e; ++i) {
- // If this is a chain output or already widened just replace it.
- bool WasWidened = SDValue(N, i).getValueType() != Results[i].getValueType();
- if (WasWidened)
- SetWidenedVector(SDValue(N, i), Results[i]);
- else
+ // If this is a chain output or already widened just replace it.
+ bool WasWidened = SDValue(N, i).getValueType() != Results[i].getValueType();
+ if (WasWidened)
+ SetWidenedVector(SDValue(N, i), Results[i]);
+ else
ReplaceValueWith(SDValue(N, i), Results[i]);
}
return true;
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 53e15d5de1..630a0a9ada 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -311,11 +311,11 @@ private:
SDValue PromoteIntRes_BUILD_PAIR(SDNode *N);
SDValue PromoteIntRes_Constant(SDNode *N);
SDValue PromoteIntRes_CTLZ(SDNode *N);
- SDValue PromoteIntRes_CTPOP_PARITY(SDNode *N);
+ SDValue PromoteIntRes_CTPOP_PARITY(SDNode *N);
SDValue PromoteIntRes_CTTZ(SDNode *N);
SDValue PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N);
SDValue PromoteIntRes_FP_TO_XINT(SDNode *N);
- SDValue PromoteIntRes_FP_TO_XINT_SAT(SDNode *N);
+ SDValue PromoteIntRes_FP_TO_XINT_SAT(SDNode *N);
SDValue PromoteIntRes_FP_TO_FP16(SDNode *N);
SDValue PromoteIntRes_FREEZE(SDNode *N);
SDValue PromoteIntRes_INT_EXTEND(SDNode *N);
@@ -332,26 +332,26 @@ private:
SDValue PromoteIntRes_SimpleIntBinOp(SDNode *N);
SDValue PromoteIntRes_ZExtIntBinOp(SDNode *N);
SDValue PromoteIntRes_SExtIntBinOp(SDNode *N);
- SDValue PromoteIntRes_UMINUMAX(SDNode *N);
+ SDValue PromoteIntRes_UMINUMAX(SDNode *N);
SDValue PromoteIntRes_SIGN_EXTEND_INREG(SDNode *N);
SDValue PromoteIntRes_SRA(SDNode *N);
SDValue PromoteIntRes_SRL(SDNode *N);
SDValue PromoteIntRes_TRUNCATE(SDNode *N);
SDValue PromoteIntRes_UADDSUBO(SDNode *N, unsigned ResNo);
SDValue PromoteIntRes_ADDSUBCARRY(SDNode *N, unsigned ResNo);
- SDValue PromoteIntRes_SADDSUBO_CARRY(SDNode *N, unsigned ResNo);
+ SDValue PromoteIntRes_SADDSUBO_CARRY(SDNode *N, unsigned ResNo);
SDValue PromoteIntRes_UNDEF(SDNode *N);
SDValue PromoteIntRes_VAARG(SDNode *N);
SDValue PromoteIntRes_VSCALE(SDNode *N);
SDValue PromoteIntRes_XMULO(SDNode *N, unsigned ResNo);
- SDValue PromoteIntRes_ADDSUBSHLSAT(SDNode *N);
+ SDValue PromoteIntRes_ADDSUBSHLSAT(SDNode *N);
SDValue PromoteIntRes_MULFIX(SDNode *N);
SDValue PromoteIntRes_DIVFIX(SDNode *N);
SDValue PromoteIntRes_FLT_ROUNDS(SDNode *N);
SDValue PromoteIntRes_VECREDUCE(SDNode *N);
SDValue PromoteIntRes_ABS(SDNode *N);
- SDValue PromoteIntRes_Rotate(SDNode *N);
- SDValue PromoteIntRes_FunnelShift(SDNode *N);
+ SDValue PromoteIntRes_Rotate(SDNode *N);
+ SDValue PromoteIntRes_FunnelShift(SDNode *N);
// Integer Operand Promotion.
bool PromoteIntegerOperand(SDNode *N, unsigned OpNo);
@@ -425,7 +425,7 @@ private:
void ExpandIntRes_FLT_ROUNDS (SDNode *N, SDValue &Lo, SDValue &Hi);
void ExpandIntRes_FP_TO_SINT (SDNode *N, SDValue &Lo, SDValue &Hi);
void ExpandIntRes_FP_TO_UINT (SDNode *N, SDValue &Lo, SDValue &Hi);
- void ExpandIntRes_FP_TO_XINT_SAT (SDNode *N, SDValue &Lo, SDValue &Hi);
+ void ExpandIntRes_FP_TO_XINT_SAT (SDNode *N, SDValue &Lo, SDValue &Hi);
void ExpandIntRes_LLROUND_LLRINT (SDNode *N, SDValue &Lo, SDValue &Hi);
void ExpandIntRes_Logical (SDNode *N, SDValue &Lo, SDValue &Hi);
@@ -433,10 +433,10 @@ private:
void ExpandIntRes_ADDSUBC (SDNode *N, SDValue &Lo, SDValue &Hi);
void ExpandIntRes_ADDSUBE (SDNode *N, SDValue &Lo, SDValue &Hi);
void ExpandIntRes_ADDSUBCARRY (SDNode *N, SDValue &Lo, SDValue &Hi);
- void ExpandIntRes_SADDSUBO_CARRY (SDNode *N, SDValue &Lo, SDValue &Hi);
+ void ExpandIntRes_SADDSUBO_CARRY (SDNode *N, SDValue &Lo, SDValue &Hi);
void ExpandIntRes_BITREVERSE (SDNode *N, SDValue &Lo, SDValue &Hi);
void ExpandIntRes_BSWAP (SDNode *N, SDValue &Lo, SDValue &Hi);
- void ExpandIntRes_PARITY (SDNode *N, SDValue &Lo, SDValue &Hi);
+ void ExpandIntRes_PARITY (SDNode *N, SDValue &Lo, SDValue &Hi);
void ExpandIntRes_MUL (SDNode *N, SDValue &Lo, SDValue &Hi);
void ExpandIntRes_SDIV (SDNode *N, SDValue &Lo, SDValue &Hi);
void ExpandIntRes_SREM (SDNode *N, SDValue &Lo, SDValue &Hi);
@@ -450,16 +450,16 @@ private:
void ExpandIntRes_UADDSUBO (SDNode *N, SDValue &Lo, SDValue &Hi);
void ExpandIntRes_XMULO (SDNode *N, SDValue &Lo, SDValue &Hi);
void ExpandIntRes_ADDSUBSAT (SDNode *N, SDValue &Lo, SDValue &Hi);
- void ExpandIntRes_SHLSAT (SDNode *N, SDValue &Lo, SDValue &Hi);
+ void ExpandIntRes_SHLSAT (SDNode *N, SDValue &Lo, SDValue &Hi);
void ExpandIntRes_MULFIX (SDNode *N, SDValue &Lo, SDValue &Hi);
void ExpandIntRes_DIVFIX (SDNode *N, SDValue &Lo, SDValue &Hi);
void ExpandIntRes_ATOMIC_LOAD (SDNode *N, SDValue &Lo, SDValue &Hi);
void ExpandIntRes_VECREDUCE (SDNode *N, SDValue &Lo, SDValue &Hi);
- void ExpandIntRes_Rotate (SDNode *N, SDValue &Lo, SDValue &Hi);
- void ExpandIntRes_FunnelShift (SDNode *N, SDValue &Lo, SDValue &Hi);
-
+ void ExpandIntRes_Rotate (SDNode *N, SDValue &Lo, SDValue &Hi);
+ void ExpandIntRes_FunnelShift (SDNode *N, SDValue &Lo, SDValue &Hi);
+
void ExpandShiftByConstant(SDNode *N, const APInt &Amt,
SDValue &Lo, SDValue &Hi);
bool ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi);
@@ -553,8 +553,8 @@ private:
SDValue SoftenFloatRes_UNDEF(SDNode *N);
SDValue SoftenFloatRes_VAARG(SDNode *N);
SDValue SoftenFloatRes_XINT_TO_FP(SDNode *N);
- SDValue SoftenFloatRes_VECREDUCE(SDNode *N);
- SDValue SoftenFloatRes_VECREDUCE_SEQ(SDNode *N);
+ SDValue SoftenFloatRes_VECREDUCE(SDNode *N);
+ SDValue SoftenFloatRes_VECREDUCE_SEQ(SDNode *N);
// Convert Float Operand to Integer.
bool SoftenFloatOperand(SDNode *N, unsigned OpNo);
@@ -563,7 +563,7 @@ private:
SDValue SoftenFloatOp_BR_CC(SDNode *N);
SDValue SoftenFloatOp_FP_ROUND(SDNode *N);
SDValue SoftenFloatOp_FP_TO_XINT(SDNode *N);
- SDValue SoftenFloatOp_FP_TO_XINT_SAT(SDNode *N);
+ SDValue SoftenFloatOp_FP_TO_XINT_SAT(SDNode *N);
SDValue SoftenFloatOp_LROUND(SDNode *N);
SDValue SoftenFloatOp_LLROUND(SDNode *N);
SDValue SoftenFloatOp_LRINT(SDNode *N);
@@ -632,7 +632,7 @@ private:
SDValue ExpandFloatOp_BR_CC(SDNode *N);
SDValue ExpandFloatOp_FCOPYSIGN(SDNode *N);
SDValue ExpandFloatOp_FP_ROUND(SDNode *N);
- SDValue ExpandFloatOp_FP_TO_XINT(SDNode *N);
+ SDValue ExpandFloatOp_FP_TO_XINT(SDNode *N);
SDValue ExpandFloatOp_LROUND(SDNode *N);
SDValue ExpandFloatOp_LLROUND(SDNode *N);
SDValue ExpandFloatOp_LRINT(SDNode *N);
@@ -642,8 +642,8 @@ private:
SDValue ExpandFloatOp_STORE(SDNode *N, unsigned OpNo);
void FloatExpandSetCCOperands(SDValue &NewLHS, SDValue &NewRHS,
- ISD::CondCode &CCCode, const SDLoc &dl,
- SDValue &Chain, bool IsSignaling = false);
+ ISD::CondCode &CCCode, const SDLoc &dl,
+ SDValue &Chain, bool IsSignaling = false);
//===--------------------------------------------------------------------===//
// Float promotion support: LegalizeFloatTypes.cpp
@@ -673,15 +673,15 @@ private:
SDValue PromoteFloatRes_UNDEF(SDNode *N);
SDValue BitcastToInt_ATOMIC_SWAP(SDNode *N);
SDValue PromoteFloatRes_XINT_TO_FP(SDNode *N);
- SDValue PromoteFloatRes_VECREDUCE(SDNode *N);
- SDValue PromoteFloatRes_VECREDUCE_SEQ(SDNode *N);
+ SDValue PromoteFloatRes_VECREDUCE(SDNode *N);
+ SDValue PromoteFloatRes_VECREDUCE_SEQ(SDNode *N);
bool PromoteFloatOperand(SDNode *N, unsigned OpNo);
SDValue PromoteFloatOp_BITCAST(SDNode *N, unsigned OpNo);
SDValue PromoteFloatOp_FCOPYSIGN(SDNode *N, unsigned OpNo);
SDValue PromoteFloatOp_FP_EXTEND(SDNode *N, unsigned OpNo);
SDValue PromoteFloatOp_FP_TO_XINT(SDNode *N, unsigned OpNo);
- SDValue PromoteFloatOp_FP_TO_XINT_SAT(SDNode *N, unsigned OpNo);
+ SDValue PromoteFloatOp_FP_TO_XINT_SAT(SDNode *N, unsigned OpNo);
SDValue PromoteFloatOp_STORE(SDNode *N, unsigned OpNo);
SDValue PromoteFloatOp_SELECT_CC(SDNode *N, unsigned OpNo);
SDValue PromoteFloatOp_SETCC(SDNode *N, unsigned OpNo);
@@ -713,15 +713,15 @@ private:
SDValue SoftPromoteHalfRes_UnaryOp(SDNode *N);
SDValue SoftPromoteHalfRes_XINT_TO_FP(SDNode *N);
SDValue SoftPromoteHalfRes_UNDEF(SDNode *N);
- SDValue SoftPromoteHalfRes_VECREDUCE(SDNode *N);
- SDValue SoftPromoteHalfRes_VECREDUCE_SEQ(SDNode *N);
+ SDValue SoftPromoteHalfRes_VECREDUCE(SDNode *N);
+ SDValue SoftPromoteHalfRes_VECREDUCE_SEQ(SDNode *N);
bool SoftPromoteHalfOperand(SDNode *N, unsigned OpNo);
SDValue SoftPromoteHalfOp_BITCAST(SDNode *N);
SDValue SoftPromoteHalfOp_FCOPYSIGN(SDNode *N, unsigned OpNo);
SDValue SoftPromoteHalfOp_FP_EXTEND(SDNode *N);
SDValue SoftPromoteHalfOp_FP_TO_XINT(SDNode *N);
- SDValue SoftPromoteHalfOp_FP_TO_XINT_SAT(SDNode *N);
+ SDValue SoftPromoteHalfOp_FP_TO_XINT_SAT(SDNode *N);
SDValue SoftPromoteHalfOp_SETCC(SDNode *N);
SDValue SoftPromoteHalfOp_SELECT_CC(SDNode *N, unsigned OpNo);
SDValue SoftPromoteHalfOp_STORE(SDNode *N, unsigned OpNo);
@@ -766,7 +766,7 @@ private:
SDValue ScalarizeVecRes_SETCC(SDNode *N);
SDValue ScalarizeVecRes_UNDEF(SDNode *N);
SDValue ScalarizeVecRes_VECTOR_SHUFFLE(SDNode *N);
- SDValue ScalarizeVecRes_FP_TO_XINT_SAT(SDNode *N);
+ SDValue ScalarizeVecRes_FP_TO_XINT_SAT(SDNode *N);
SDValue ScalarizeVecRes_FIX(SDNode *N);
@@ -782,10 +782,10 @@ private:
SDValue ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo);
SDValue ScalarizeVecOp_FP_ROUND(SDNode *N, unsigned OpNo);
SDValue ScalarizeVecOp_STRICT_FP_ROUND(SDNode *N, unsigned OpNo);
- SDValue ScalarizeVecOp_FP_EXTEND(SDNode *N);
- SDValue ScalarizeVecOp_STRICT_FP_EXTEND(SDNode *N);
+ SDValue ScalarizeVecOp_FP_EXTEND(SDNode *N);
+ SDValue ScalarizeVecOp_STRICT_FP_EXTEND(SDNode *N);
SDValue ScalarizeVecOp_VECREDUCE(SDNode *N);
- SDValue ScalarizeVecOp_VECREDUCE_SEQ(SDNode *N);
+ SDValue ScalarizeVecOp_VECREDUCE_SEQ(SDNode *N);
//===--------------------------------------------------------------------===//
// Vector Splitting Support: LegalizeVectorTypes.cpp
@@ -803,8 +803,8 @@ private:
// Helper function for incrementing the pointer when splitting
// memory operations
- void IncrementPointer(MemSDNode *N, EVT MemVT, MachinePointerInfo &MPI,
- SDValue &Ptr, uint64_t *ScaledOffset = nullptr);
+ void IncrementPointer(MemSDNode *N, EVT MemVT, MachinePointerInfo &MPI,
+ SDValue &Ptr, uint64_t *ScaledOffset = nullptr);
// Vector Result Splitting: <128 x ty> -> 2 x <64 x ty>.
void SplitVectorResult(SDNode *N, unsigned ResNo);
@@ -831,23 +831,23 @@ private:
void SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo, SDValue &Hi);
void SplitVecRes_MLOAD(MaskedLoadSDNode *MLD, SDValue &Lo, SDValue &Hi);
void SplitVecRes_MGATHER(MaskedGatherSDNode *MGT, SDValue &Lo, SDValue &Hi);
- void SplitVecRes_ScalarOp(SDNode *N, SDValue &Lo, SDValue &Hi);
+ void SplitVecRes_ScalarOp(SDNode *N, SDValue &Lo, SDValue &Hi);
void SplitVecRes_SETCC(SDNode *N, SDValue &Lo, SDValue &Hi);
void SplitVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N, SDValue &Lo,
SDValue &Hi);
void SplitVecRes_VAARG(SDNode *N, SDValue &Lo, SDValue &Hi);
- void SplitVecRes_FP_TO_XINT_SAT(SDNode *N, SDValue &Lo, SDValue &Hi);
+ void SplitVecRes_FP_TO_XINT_SAT(SDNode *N, SDValue &Lo, SDValue &Hi);
// Vector Operand Splitting: <128 x ty> -> 2 x <64 x ty>.
bool SplitVectorOperand(SDNode *N, unsigned OpNo);
SDValue SplitVecOp_VSELECT(SDNode *N, unsigned OpNo);
SDValue SplitVecOp_VECREDUCE(SDNode *N, unsigned OpNo);
- SDValue SplitVecOp_VECREDUCE_SEQ(SDNode *N);
+ SDValue SplitVecOp_VECREDUCE_SEQ(SDNode *N);
SDValue SplitVecOp_UnaryOp(SDNode *N);
SDValue SplitVecOp_TruncateHelper(SDNode *N);
SDValue SplitVecOp_BITCAST(SDNode *N);
- SDValue SplitVecOp_INSERT_SUBVECTOR(SDNode *N, unsigned OpNo);
+ SDValue SplitVecOp_INSERT_SUBVECTOR(SDNode *N, unsigned OpNo);
SDValue SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N);
SDValue SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N);
SDValue SplitVecOp_ExtVecInRegOp(SDNode *N);
@@ -859,7 +859,7 @@ private:
SDValue SplitVecOp_VSETCC(SDNode *N);
SDValue SplitVecOp_FP_ROUND(SDNode *N);
SDValue SplitVecOp_FCOPYSIGN(SDNode *N);
- SDValue SplitVecOp_FP_TO_XINT_SAT(SDNode *N);
+ SDValue SplitVecOp_FP_TO_XINT_SAT(SDNode *N);
//===--------------------------------------------------------------------===//
// Vector Widening Support: LegalizeVectorTypes.cpp
@@ -891,9 +891,9 @@ private:
SDValue WidenVecRes_LOAD(SDNode* N);
SDValue WidenVecRes_MLOAD(MaskedLoadSDNode* N);
SDValue WidenVecRes_MGATHER(MaskedGatherSDNode* N);
- SDValue WidenVecRes_ScalarOp(SDNode* N);
+ SDValue WidenVecRes_ScalarOp(SDNode* N);
SDValue WidenVecRes_SELECT(SDNode* N);
- SDValue WidenVSELECTMask(SDNode *N);
+ SDValue WidenVSELECTMask(SDNode *N);
SDValue WidenVecRes_SELECT_CC(SDNode* N);
SDValue WidenVecRes_SETCC(SDNode* N);
SDValue WidenVecRes_STRICT_FSETCC(SDNode* N);
@@ -908,7 +908,7 @@ private:
SDValue WidenVecRes_OverflowOp(SDNode *N, unsigned ResNo);
SDValue WidenVecRes_Convert(SDNode *N);
SDValue WidenVecRes_Convert_StrictFP(SDNode *N);
- SDValue WidenVecRes_FP_TO_XINT_SAT(SDNode *N);
+ SDValue WidenVecRes_FP_TO_XINT_SAT(SDNode *N);
SDValue WidenVecRes_FCOPYSIGN(SDNode *N);
SDValue WidenVecRes_POWI(SDNode *N);
SDValue WidenVecRes_Unary(SDNode *N);
@@ -930,10 +930,10 @@ private:
SDValue WidenVecOp_VSELECT(SDNode *N);
SDValue WidenVecOp_Convert(SDNode *N);
- SDValue WidenVecOp_FP_TO_XINT_SAT(SDNode *N);
+ SDValue WidenVecOp_FP_TO_XINT_SAT(SDNode *N);
SDValue WidenVecOp_FCOPYSIGN(SDNode *N);
SDValue WidenVecOp_VECREDUCE(SDNode *N);
- SDValue WidenVecOp_VECREDUCE_SEQ(SDNode *N);
+ SDValue WidenVecOp_VECREDUCE_SEQ(SDNode *N);
/// Helper function to generate a set of operations to perform
/// a vector operation for a wider type.
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
index c0a391edef..81cc2bf10d 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
@@ -175,8 +175,8 @@ void DAGTypeLegalizer::ExpandRes_BITCAST(SDNode *N, SDValue &Lo, SDValue &Hi) {
// Increment the pointer to the other half.
unsigned IncrementSize = NOutVT.getSizeInBits() / 8;
- StackPtr =
- DAG.getMemBasePlusOffset(StackPtr, TypeSize::Fixed(IncrementSize), dl);
+ StackPtr =
+ DAG.getMemBasePlusOffset(StackPtr, TypeSize::Fixed(IncrementSize), dl);
// Load the second half from the stack slot.
Hi = DAG.getLoad(NOutVT, dl, Store, StackPtr,
@@ -267,7 +267,7 @@ void DAGTypeLegalizer::ExpandRes_NormalLoad(SDNode *N, SDValue &Lo,
// Increment the pointer to the other half.
unsigned IncrementSize = NVT.getSizeInBits() / 8;
- Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(IncrementSize), dl);
+ Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(IncrementSize), dl);
Hi = DAG.getLoad(
NVT, dl, Chain, Ptr, LD->getPointerInfo().getWithOffset(IncrementSize),
LD->getOriginalAlign(), LD->getMemOperand()->getFlags(), AAInfo);
@@ -482,7 +482,7 @@ SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) {
St->getOriginalAlign(), St->getMemOperand()->getFlags(),
AAInfo);
- Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::Fixed(IncrementSize));
+ Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::Fixed(IncrementSize));
Hi = DAG.getStore(
Chain, dl, Hi, Ptr, St->getPointerInfo().getWithOffset(IncrementSize),
St->getOriginalAlign(), St->getMemOperand()->getFlags(), AAInfo);
@@ -515,8 +515,8 @@ void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDValue &Lo, SDValue &Hi) {
SDValue Cond = N->getOperand(0);
CL = CH = Cond;
if (Cond.getValueType().isVector()) {
- if (SDValue Res = WidenVSELECTMask(N))
- std::tie(CL, CH) = DAG.SplitVector(Res, dl);
+ if (SDValue Res = WidenVSELECTMask(N))
+ std::tie(CL, CH) = DAG.SplitVector(Res, dl);
// Check if there are already splitted versions of the vector available and
// use those instead of splitting the mask operand again.
else if (getTypeAction(Cond.getValueType()) ==
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
index 5e193511e4..4015a5a0ce 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
@@ -453,10 +453,10 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) {
case ISD::UADDSAT:
case ISD::SSUBSAT:
case ISD::USUBSAT:
- case ISD::SSHLSAT:
- case ISD::USHLSAT:
- case ISD::FP_TO_SINT_SAT:
- case ISD::FP_TO_UINT_SAT:
+ case ISD::SSHLSAT:
+ case ISD::USHLSAT:
+ case ISD::FP_TO_SINT_SAT:
+ case ISD::FP_TO_UINT_SAT:
Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
break;
case ISD::SMULFIX:
@@ -490,11 +490,11 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) {
Action = TLI.getOperationAction(Node->getOpcode(),
Node->getOperand(0).getValueType());
break;
- case ISD::VECREDUCE_SEQ_FADD:
- case ISD::VECREDUCE_SEQ_FMUL:
- Action = TLI.getOperationAction(Node->getOpcode(),
- Node->getOperand(1).getValueType());
- break;
+ case ISD::VECREDUCE_SEQ_FADD:
+ case ISD::VECREDUCE_SEQ_FMUL:
+ Action = TLI.getOperationAction(Node->getOpcode(),
+ Node->getOperand(1).getValueType());
+ break;
}
LLVM_DEBUG(dbgs() << "\nLegalizing vector op: "; Node->dump(&DAG));
@@ -802,7 +802,7 @@ void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
break;
case ISD::ROTL:
case ISD::ROTR:
- if (TLI.expandROT(Node, false /*AllowVectorOps*/, Tmp, DAG)) {
+ if (TLI.expandROT(Node, false /*AllowVectorOps*/, Tmp, DAG)) {
Results.push_back(Tmp);
return;
}
@@ -814,15 +814,15 @@ void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
return;
}
break;
- case ISD::SMIN:
- case ISD::SMAX:
- case ISD::UMIN:
- case ISD::UMAX:
- if (SDValue Expanded = TLI.expandIntMINMAX(Node, DAG)) {
- Results.push_back(Expanded);
- return;
- }
- break;
+ case ISD::SMIN:
+ case ISD::SMAX:
+ case ISD::UMIN:
+ case ISD::UMAX:
+ if (SDValue Expanded = TLI.expandIntMINMAX(Node, DAG)) {
+ Results.push_back(Expanded);
+ return;
+ }
+ break;
case ISD::UADDO:
case ISD::USUBO:
ExpandUADDSUBO(Node, Results);
@@ -885,10 +885,10 @@ void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
case ISD::VECREDUCE_FMIN:
Results.push_back(TLI.expandVecReduce(Node, DAG));
return;
- case ISD::VECREDUCE_SEQ_FADD:
- case ISD::VECREDUCE_SEQ_FMUL:
- Results.push_back(TLI.expandVecReduceSeq(Node, DAG));
- return;
+ case ISD::VECREDUCE_SEQ_FADD:
+ case ISD::VECREDUCE_SEQ_FMUL:
+ Results.push_back(TLI.expandVecReduceSeq(Node, DAG));
+ return;
case ISD::SREM:
case ISD::UREM:
ExpandREM(Node, Results);
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 5e878e0973..57cb364f19 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -129,8 +129,8 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
case ISD::UADDSAT:
case ISD::SSUBSAT:
case ISD::USUBSAT:
- case ISD::SSHLSAT:
- case ISD::USHLSAT:
+ case ISD::SSHLSAT:
+ case ISD::USHLSAT:
case ISD::FPOW:
case ISD::FREM:
@@ -146,13 +146,13 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
case ISD::SHL:
case ISD::SRA:
case ISD::SRL:
- case ISD::ROTL:
- case ISD::ROTR:
+ case ISD::ROTL:
+ case ISD::ROTR:
R = ScalarizeVecRes_BinOp(N);
break;
case ISD::FMA:
- case ISD::FSHL:
- case ISD::FSHR:
+ case ISD::FSHL:
+ case ISD::FSHR:
R = ScalarizeVecRes_TernaryOp(N);
break;
@@ -162,11 +162,11 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
R = ScalarizeVecRes_StrictFPOp(N);
break;
- case ISD::FP_TO_UINT_SAT:
- case ISD::FP_TO_SINT_SAT:
- R = ScalarizeVecRes_FP_TO_XINT_SAT(N);
- break;
-
+ case ISD::FP_TO_UINT_SAT:
+ case ISD::FP_TO_SINT_SAT:
+ R = ScalarizeVecRes_FP_TO_XINT_SAT(N);
+ break;
+
case ISD::UADDO:
case ISD::SADDO:
case ISD::USUBO:
@@ -521,23 +521,23 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(SDNode *N) {
return GetScalarizedVector(N->getOperand(Op));
}
-SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(SDNode *N) {
- SDValue Src = N->getOperand(0);
- EVT SrcVT = Src.getValueType();
- SDLoc dl(N);
-
- // Handle case where result is scalarized but operand is not
- if (getTypeAction(SrcVT) == TargetLowering::TypeScalarizeVector)
- Src = GetScalarizedVector(Src);
- else
- Src = DAG.getNode(
- ISD::EXTRACT_VECTOR_ELT, dl, SrcVT.getVectorElementType(), Src,
- DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
-
- EVT DstVT = N->getValueType(0).getVectorElementType();
- return DAG.getNode(N->getOpcode(), dl, DstVT, Src, N->getOperand(1));
-}
-
+SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(SDNode *N) {
+ SDValue Src = N->getOperand(0);
+ EVT SrcVT = Src.getValueType();
+ SDLoc dl(N);
+
+ // Handle case where result is scalarized but operand is not
+ if (getTypeAction(SrcVT) == TargetLowering::TypeScalarizeVector)
+ Src = GetScalarizedVector(Src);
+ else
+ Src = DAG.getNode(
+ ISD::EXTRACT_VECTOR_ELT, dl, SrcVT.getVectorElementType(), Src,
+ DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
+
+ EVT DstVT = N->getValueType(0).getVectorElementType();
+ return DAG.getNode(N->getOpcode(), dl, DstVT, Src, N->getOperand(1));
+}
+
SDValue DAGTypeLegalizer::ScalarizeVecRes_SETCC(SDNode *N) {
assert(N->getValueType(0).isVector() &&
N->getOperand(0).getValueType().isVector() &&
@@ -580,80 +580,80 @@ bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode *N, unsigned OpNo) {
dbgs() << "\n");
SDValue Res = SDValue();
- switch (N->getOpcode()) {
- default:
+ switch (N->getOpcode()) {
+ default:
#ifndef NDEBUG
- dbgs() << "ScalarizeVectorOperand Op #" << OpNo << ": ";
- N->dump(&DAG);
- dbgs() << "\n";
+ dbgs() << "ScalarizeVectorOperand Op #" << OpNo << ": ";
+ N->dump(&DAG);
+ dbgs() << "\n";
#endif
- report_fatal_error("Do not know how to scalarize this operator's "
- "operand!\n");
- case ISD::BITCAST:
- Res = ScalarizeVecOp_BITCAST(N);
- break;
- case ISD::ANY_EXTEND:
- case ISD::ZERO_EXTEND:
- case ISD::SIGN_EXTEND:
- case ISD::TRUNCATE:
- case ISD::FP_TO_SINT:
- case ISD::FP_TO_UINT:
- case ISD::SINT_TO_FP:
- case ISD::UINT_TO_FP:
- Res = ScalarizeVecOp_UnaryOp(N);
- break;
- case ISD::STRICT_SINT_TO_FP:
- case ISD::STRICT_UINT_TO_FP:
- case ISD::STRICT_FP_TO_SINT:
- case ISD::STRICT_FP_TO_UINT:
- Res = ScalarizeVecOp_UnaryOp_StrictFP(N);
- break;
- case ISD::CONCAT_VECTORS:
- Res = ScalarizeVecOp_CONCAT_VECTORS(N);
- break;
- case ISD::EXTRACT_VECTOR_ELT:
- Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(N);
- break;
- case ISD::VSELECT:
- Res = ScalarizeVecOp_VSELECT(N);
- break;
- case ISD::SETCC:
- Res = ScalarizeVecOp_VSETCC(N);
- break;
- case ISD::STORE:
- Res = ScalarizeVecOp_STORE(cast<StoreSDNode>(N), OpNo);
- break;
- case ISD::STRICT_FP_ROUND:
- Res = ScalarizeVecOp_STRICT_FP_ROUND(N, OpNo);
- break;
- case ISD::FP_ROUND:
- Res = ScalarizeVecOp_FP_ROUND(N, OpNo);
- break;
- case ISD::STRICT_FP_EXTEND:
- Res = ScalarizeVecOp_STRICT_FP_EXTEND(N);
- break;
- case ISD::FP_EXTEND:
- Res = ScalarizeVecOp_FP_EXTEND(N);
- break;
- case ISD::VECREDUCE_FADD:
- case ISD::VECREDUCE_FMUL:
- case ISD::VECREDUCE_ADD:
- case ISD::VECREDUCE_MUL:
- case ISD::VECREDUCE_AND:
- case ISD::VECREDUCE_OR:
- case ISD::VECREDUCE_XOR:
- case ISD::VECREDUCE_SMAX:
- case ISD::VECREDUCE_SMIN:
- case ISD::VECREDUCE_UMAX:
- case ISD::VECREDUCE_UMIN:
- case ISD::VECREDUCE_FMAX:
- case ISD::VECREDUCE_FMIN:
- Res = ScalarizeVecOp_VECREDUCE(N);
- break;
- case ISD::VECREDUCE_SEQ_FADD:
- case ISD::VECREDUCE_SEQ_FMUL:
- Res = ScalarizeVecOp_VECREDUCE_SEQ(N);
- break;
+ report_fatal_error("Do not know how to scalarize this operator's "
+ "operand!\n");
+ case ISD::BITCAST:
+ Res = ScalarizeVecOp_BITCAST(N);
+ break;
+ case ISD::ANY_EXTEND:
+ case ISD::ZERO_EXTEND:
+ case ISD::SIGN_EXTEND:
+ case ISD::TRUNCATE:
+ case ISD::FP_TO_SINT:
+ case ISD::FP_TO_UINT:
+ case ISD::SINT_TO_FP:
+ case ISD::UINT_TO_FP:
+ Res = ScalarizeVecOp_UnaryOp(N);
+ break;
+ case ISD::STRICT_SINT_TO_FP:
+ case ISD::STRICT_UINT_TO_FP:
+ case ISD::STRICT_FP_TO_SINT:
+ case ISD::STRICT_FP_TO_UINT:
+ Res = ScalarizeVecOp_UnaryOp_StrictFP(N);
+ break;
+ case ISD::CONCAT_VECTORS:
+ Res = ScalarizeVecOp_CONCAT_VECTORS(N);
+ break;
+ case ISD::EXTRACT_VECTOR_ELT:
+ Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(N);
+ break;
+ case ISD::VSELECT:
+ Res = ScalarizeVecOp_VSELECT(N);
+ break;
+ case ISD::SETCC:
+ Res = ScalarizeVecOp_VSETCC(N);
+ break;
+ case ISD::STORE:
+ Res = ScalarizeVecOp_STORE(cast<StoreSDNode>(N), OpNo);
+ break;
+ case ISD::STRICT_FP_ROUND:
+ Res = ScalarizeVecOp_STRICT_FP_ROUND(N, OpNo);
+ break;
+ case ISD::FP_ROUND:
+ Res = ScalarizeVecOp_FP_ROUND(N, OpNo);
+ break;
+ case ISD::STRICT_FP_EXTEND:
+ Res = ScalarizeVecOp_STRICT_FP_EXTEND(N);
+ break;
+ case ISD::FP_EXTEND:
+ Res = ScalarizeVecOp_FP_EXTEND(N);
+ break;
+ case ISD::VECREDUCE_FADD:
+ case ISD::VECREDUCE_FMUL:
+ case ISD::VECREDUCE_ADD:
+ case ISD::VECREDUCE_MUL:
+ case ISD::VECREDUCE_AND:
+ case ISD::VECREDUCE_OR:
+ case ISD::VECREDUCE_XOR:
+ case ISD::VECREDUCE_SMAX:
+ case ISD::VECREDUCE_SMIN:
+ case ISD::VECREDUCE_UMAX:
+ case ISD::VECREDUCE_UMIN:
+ case ISD::VECREDUCE_FMAX:
+ case ISD::VECREDUCE_FMIN:
+ Res = ScalarizeVecOp_VECREDUCE(N);
+ break;
+ case ISD::VECREDUCE_SEQ_FADD:
+ case ISD::VECREDUCE_SEQ_FMUL:
+ Res = ScalarizeVecOp_VECREDUCE_SEQ(N);
+ break;
}
// If the result is null, the sub-method took care of registering results etc.
@@ -798,7 +798,7 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo){
/// If the value to round is a vector that needs to be scalarized, it must be
/// <1 x ty>. Convert the element instead.
SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(SDNode *N, unsigned OpNo) {
- assert(OpNo == 0 && "Wrong operand for scalarization!");
+ assert(OpNo == 0 && "Wrong operand for scalarization!");
SDValue Elt = GetScalarizedVector(N->getOperand(0));
SDValue Res = DAG.getNode(ISD::FP_ROUND, SDLoc(N),
N->getValueType(0).getVectorElementType(), Elt,
@@ -824,37 +824,37 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(SDNode *N,
// handled all replacements since caller can only handle a single result.
ReplaceValueWith(SDValue(N, 0), Res);
return SDValue();
-}
-
-/// If the value to extend is a vector that needs to be scalarized, it must be
-/// <1 x ty>. Convert the element instead.
-SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_EXTEND(SDNode *N) {
- SDValue Elt = GetScalarizedVector(N->getOperand(0));
- SDValue Res = DAG.getNode(ISD::FP_EXTEND, SDLoc(N),
- N->getValueType(0).getVectorElementType(), Elt);
- return DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Res);
-}
-
-/// If the value to extend is a vector that needs to be scalarized, it must be
-/// <1 x ty>. Convert the element instead.
-SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(SDNode *N) {
- SDValue Elt = GetScalarizedVector(N->getOperand(1));
- SDValue Res =
- DAG.getNode(ISD::STRICT_FP_EXTEND, SDLoc(N),
- {N->getValueType(0).getVectorElementType(), MVT::Other},
- {N->getOperand(0), Elt});
- // Legalize the chain result - switch anything that used the old chain to
- // use the new one.
- ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
-
- Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Res);
-
- // Do our own replacement and return SDValue() to tell the caller that we
- // handled all replacements since caller can only handle a single result.
- ReplaceValueWith(SDValue(N, 0), Res);
- return SDValue();
-}
-
+}
+
+/// If the value to extend is a vector that needs to be scalarized, it must be
+/// <1 x ty>. Convert the element instead.
+SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_EXTEND(SDNode *N) {
+ SDValue Elt = GetScalarizedVector(N->getOperand(0));
+ SDValue Res = DAG.getNode(ISD::FP_EXTEND, SDLoc(N),
+ N->getValueType(0).getVectorElementType(), Elt);
+ return DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Res);
+}
+
+/// If the value to extend is a vector that needs to be scalarized, it must be
+/// <1 x ty>. Convert the element instead.
+SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(SDNode *N) {
+ SDValue Elt = GetScalarizedVector(N->getOperand(1));
+ SDValue Res =
+ DAG.getNode(ISD::STRICT_FP_EXTEND, SDLoc(N),
+ {N->getValueType(0).getVectorElementType(), MVT::Other},
+ {N->getOperand(0), Elt});
+ // Legalize the chain result - switch anything that used the old chain to
+ // use the new one.
+ ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
+
+ Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Res);
+
+ // Do our own replacement and return SDValue() to tell the caller that we
+ // handled all replacements since caller can only handle a single result.
+ ReplaceValueWith(SDValue(N, 0), Res);
+ return SDValue();
+}
+
SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE(SDNode *N) {
SDValue Res = GetScalarizedVector(N->getOperand(0));
// Result type may be wider than element type.
@@ -863,17 +863,17 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE(SDNode *N) {
return Res;
}
-SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(SDNode *N) {
- SDValue AccOp = N->getOperand(0);
- SDValue VecOp = N->getOperand(1);
-
- unsigned BaseOpc = ISD::getVecReduceBaseOpcode(N->getOpcode());
-
- SDValue Op = GetScalarizedVector(VecOp);
- return DAG.getNode(BaseOpc, SDLoc(N), N->getValueType(0),
- AccOp, Op, N->getFlags());
-}
-
+SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(SDNode *N) {
+ SDValue AccOp = N->getOperand(0);
+ SDValue VecOp = N->getOperand(1);
+
+ unsigned BaseOpc = ISD::getVecReduceBaseOpcode(N->getOpcode());
+
+ SDValue Op = GetScalarizedVector(VecOp);
+ return DAG.getNode(BaseOpc, SDLoc(N), N->getValueType(0),
+ AccOp, Op, N->getFlags());
+}
+
//===----------------------------------------------------------------------===//
// Result Vector Splitting
//===----------------------------------------------------------------------===//
@@ -913,10 +913,10 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
case ISD::FPOWI: SplitVecRes_FPOWI(N, Lo, Hi); break;
case ISD::FCOPYSIGN: SplitVecRes_FCOPYSIGN(N, Lo, Hi); break;
case ISD::INSERT_VECTOR_ELT: SplitVecRes_INSERT_VECTOR_ELT(N, Lo, Hi); break;
- case ISD::SPLAT_VECTOR:
- case ISD::SCALAR_TO_VECTOR:
- SplitVecRes_ScalarOp(N, Lo, Hi);
- break;
+ case ISD::SPLAT_VECTOR:
+ case ISD::SCALAR_TO_VECTOR:
+ SplitVecRes_ScalarOp(N, Lo, Hi);
+ break;
case ISD::SIGN_EXTEND_INREG: SplitVecRes_InregOp(N, Lo, Hi); break;
case ISD::LOAD:
SplitVecRes_LOAD(cast<LoadSDNode>(N), Lo, Hi);
@@ -1019,15 +1019,15 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
case ISD::UADDSAT:
case ISD::SSUBSAT:
case ISD::USUBSAT:
- case ISD::SSHLSAT:
- case ISD::USHLSAT:
- case ISD::ROTL:
- case ISD::ROTR:
+ case ISD::SSHLSAT:
+ case ISD::USHLSAT:
+ case ISD::ROTL:
+ case ISD::ROTR:
SplitVecRes_BinOp(N, Lo, Hi);
break;
case ISD::FMA:
- case ISD::FSHL:
- case ISD::FSHR:
+ case ISD::FSHL:
+ case ISD::FSHR:
SplitVecRes_TernaryOp(N, Lo, Hi);
break;
@@ -1037,11 +1037,11 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
SplitVecRes_StrictFPOp(N, Lo, Hi);
break;
- case ISD::FP_TO_UINT_SAT:
- case ISD::FP_TO_SINT_SAT:
- SplitVecRes_FP_TO_XINT_SAT(N, Lo, Hi);
- break;
-
+ case ISD::FP_TO_UINT_SAT:
+ case ISD::FP_TO_SINT_SAT:
+ SplitVecRes_FP_TO_XINT_SAT(N, Lo, Hi);
+ break;
+
case ISD::UADDO:
case ISD::SADDO:
case ISD::USUBO:
@@ -1068,26 +1068,26 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
}
void DAGTypeLegalizer::IncrementPointer(MemSDNode *N, EVT MemVT,
- MachinePointerInfo &MPI, SDValue &Ptr,
- uint64_t *ScaledOffset) {
+ MachinePointerInfo &MPI, SDValue &Ptr,
+ uint64_t *ScaledOffset) {
SDLoc DL(N);
unsigned IncrementSize = MemVT.getSizeInBits().getKnownMinSize() / 8;
if (MemVT.isScalableVector()) {
- SDNodeFlags Flags;
+ SDNodeFlags Flags;
SDValue BytesIncrement = DAG.getVScale(
DL, Ptr.getValueType(),
APInt(Ptr.getValueSizeInBits().getFixedSize(), IncrementSize));
MPI = MachinePointerInfo(N->getPointerInfo().getAddrSpace());
- Flags.setNoUnsignedWrap(true);
- if (ScaledOffset)
- *ScaledOffset += IncrementSize;
- Ptr = DAG.getNode(ISD::ADD, DL, Ptr.getValueType(), Ptr, BytesIncrement,
- Flags);
+ Flags.setNoUnsignedWrap(true);
+ if (ScaledOffset)
+ *ScaledOffset += IncrementSize;
+ Ptr = DAG.getNode(ISD::ADD, DL, Ptr.getValueType(), Ptr, BytesIncrement,
+ Flags);
} else {
MPI = N->getPointerInfo().getWithOffset(IncrementSize);
// Increment the pointer to the other half.
- Ptr = DAG.getObjectPtrOffset(DL, Ptr, TypeSize::Fixed(IncrementSize));
+ Ptr = DAG.getObjectPtrOffset(DL, Ptr, TypeSize::Fixed(IncrementSize));
}
}
@@ -1296,8 +1296,8 @@ void DAGTypeLegalizer::SplitVecRes_INSERT_SUBVECTOR(SDNode *N, SDValue &Lo,
// Increment the pointer to the other part.
unsigned IncrementSize = Lo.getValueSizeInBits() / 8;
- StackPtr =
- DAG.getMemBasePlusOffset(StackPtr, TypeSize::Fixed(IncrementSize), dl);
+ StackPtr =
+ DAG.getMemBasePlusOffset(StackPtr, TypeSize::Fixed(IncrementSize), dl);
// Load the Hi part from the stack slot.
Hi = DAG.getLoad(Hi.getValueType(), dl, Store, StackPtr,
@@ -1545,16 +1545,16 @@ void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo,
if (ConstantSDNode *CIdx = dyn_cast<ConstantSDNode>(Idx)) {
unsigned IdxVal = CIdx->getZExtValue();
- unsigned LoNumElts = Lo.getValueType().getVectorMinNumElements();
- if (IdxVal < LoNumElts) {
+ unsigned LoNumElts = Lo.getValueType().getVectorMinNumElements();
+ if (IdxVal < LoNumElts) {
Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl,
Lo.getValueType(), Lo, Elt, Idx);
- return;
- } else if (!Vec.getValueType().isScalableVector()) {
+ return;
+ } else if (!Vec.getValueType().isScalableVector()) {
Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, Hi.getValueType(), Hi, Elt,
DAG.getVectorIdxConstant(IdxVal - LoNumElts, dl));
- return;
- }
+ return;
+ }
}
// See if the target wants to custom expand this node.
@@ -1567,7 +1567,7 @@ void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo,
if (VecVT.getScalarSizeInBits() < 8) {
EltVT = MVT::i8;
VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT,
- VecVT.getVectorElementCount());
+ VecVT.getVectorElementCount());
Vec = DAG.getNode(ISD::ANY_EXTEND, dl, VecVT, Vec);
// Extend the element type to match if needed.
if (EltVT.bitsGT(Elt.getValueType()))
@@ -1592,8 +1592,8 @@ void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo,
SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
Store = DAG.getTruncStore(
Store, dl, Elt, EltPtr, MachinePointerInfo::getUnknownStack(MF), EltVT,
- commonAlignment(SmallestAlign,
- EltVT.getFixedSizeInBits() / 8));
+ commonAlignment(SmallestAlign,
+ EltVT.getFixedSizeInBits() / 8));
EVT LoVT, HiVT;
std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
@@ -1602,11 +1602,11 @@ void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo,
Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
// Increment the pointer to the other part.
- auto Load = cast<LoadSDNode>(Lo);
- MachinePointerInfo MPI = Load->getPointerInfo();
- IncrementPointer(Load, LoVT, MPI, StackPtr);
+ auto Load = cast<LoadSDNode>(Lo);
+ MachinePointerInfo MPI = Load->getPointerInfo();
+ IncrementPointer(Load, LoVT, MPI, StackPtr);
- Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
+ Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
// If we adjusted the original type, we need to truncate the results.
std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
@@ -1616,18 +1616,18 @@ void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo,
Hi = DAG.getNode(ISD::TRUNCATE, dl, HiVT, Hi);
}
-void DAGTypeLegalizer::SplitVecRes_ScalarOp(SDNode *N, SDValue &Lo,
- SDValue &Hi) {
+void DAGTypeLegalizer::SplitVecRes_ScalarOp(SDNode *N, SDValue &Lo,
+ SDValue &Hi) {
EVT LoVT, HiVT;
SDLoc dl(N);
std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
- Lo = DAG.getNode(N->getOpcode(), dl, LoVT, N->getOperand(0));
- if (N->getOpcode() == ISD::SCALAR_TO_VECTOR) {
- Hi = DAG.getUNDEF(HiVT);
- } else {
- assert(N->getOpcode() == ISD::SPLAT_VECTOR && "Unexpected opcode");
- Hi = Lo;
- }
+ Lo = DAG.getNode(N->getOpcode(), dl, LoVT, N->getOperand(0));
+ if (N->getOpcode() == ISD::SCALAR_TO_VECTOR) {
+ Hi = DAG.getUNDEF(HiVT);
+ } else {
+ assert(N->getOpcode() == ISD::SPLAT_VECTOR && "Unexpected opcode");
+ Hi = Lo;
+ }
}
void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo,
@@ -1715,10 +1715,10 @@ void DAGTypeLegalizer::SplitVecRes_MLOAD(MaskedLoadSDNode *MLD,
else
std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
- unsigned LoSize = MemoryLocation::getSizeOrUnknown(LoMemVT.getStoreSize());
+ unsigned LoSize = MemoryLocation::getSizeOrUnknown(LoMemVT.getStoreSize());
MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
- MLD->getPointerInfo(), MachineMemOperand::MOLoad, LoSize, Alignment,
- MLD->getAAInfo(), MLD->getRanges());
+ MLD->getPointerInfo(), MachineMemOperand::MOLoad, LoSize, Alignment,
+ MLD->getAAInfo(), MLD->getRanges());
Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr, Offset, MaskLo, PassThruLo, LoMemVT,
MMO, MLD->getAddressingMode(), ExtType,
@@ -1732,18 +1732,18 @@ void DAGTypeLegalizer::SplitVecRes_MLOAD(MaskedLoadSDNode *MLD,
// Generate hi masked load.
Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
MLD->isExpandingLoad());
- unsigned HiSize = MemoryLocation::getSizeOrUnknown(HiMemVT.getStoreSize());
-
- MachinePointerInfo MPI;
- if (LoMemVT.isScalableVector())
- MPI = MachinePointerInfo(MLD->getPointerInfo().getAddrSpace());
- else
- MPI = MLD->getPointerInfo().getWithOffset(
- LoMemVT.getStoreSize().getFixedSize());
-
+ unsigned HiSize = MemoryLocation::getSizeOrUnknown(HiMemVT.getStoreSize());
+
+ MachinePointerInfo MPI;
+ if (LoMemVT.isScalableVector())
+ MPI = MachinePointerInfo(MLD->getPointerInfo().getAddrSpace());
+ else
+ MPI = MLD->getPointerInfo().getWithOffset(
+ LoMemVT.getStoreSize().getFixedSize());
+
MMO = DAG.getMachineFunction().getMachineMemOperand(
- MPI, MachineMemOperand::MOLoad, HiSize, Alignment, MLD->getAAInfo(),
- MLD->getRanges());
+ MPI, MachineMemOperand::MOLoad, HiSize, Alignment, MLD->getAAInfo(),
+ MLD->getRanges());
Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr, Offset, MaskHi, PassThruHi,
HiMemVT, MMO, MLD->getAddressingMode(), ExtType,
@@ -1773,9 +1773,9 @@ void DAGTypeLegalizer::SplitVecRes_MGATHER(MaskedGatherSDNode *MGT,
SDValue PassThru = MGT->getPassThru();
SDValue Index = MGT->getIndex();
SDValue Scale = MGT->getScale();
- EVT MemoryVT = MGT->getMemoryVT();
+ EVT MemoryVT = MGT->getMemoryVT();
Align Alignment = MGT->getOriginalAlign();
- ISD::LoadExtType ExtType = MGT->getExtensionType();
+ ISD::LoadExtType ExtType = MGT->getExtensionType();
// Split Mask operand
SDValue MaskLo, MaskHi;
@@ -1788,10 +1788,10 @@ void DAGTypeLegalizer::SplitVecRes_MGATHER(MaskedGatherSDNode *MGT,
std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
}
- EVT LoMemVT, HiMemVT;
- // Split MemoryVT
- std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
-
+ EVT LoMemVT, HiMemVT;
+ // Split MemoryVT
+ std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
+
SDValue PassThruLo, PassThruHi;
if (getTypeAction(PassThru.getValueType()) == TargetLowering::TypeSplitVector)
GetSplitVector(PassThru, PassThruLo, PassThruHi);
@@ -1810,12 +1810,12 @@ void DAGTypeLegalizer::SplitVecRes_MGATHER(MaskedGatherSDNode *MGT,
MGT->getRanges());
SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo, Scale};
- Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
- MMO, MGT->getIndexType(), ExtType);
+ Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
+ MMO, MGT->getIndexType(), ExtType);
SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi, Scale};
- Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
- MMO, MGT->getIndexType(), ExtType);
+ Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
+ MMO, MGT->getIndexType(), ExtType);
// Build a factor node to remember that this load is independent of the
// other one.
@@ -1903,8 +1903,8 @@ void DAGTypeLegalizer::SplitVecRes_ExtendOp(SDNode *N, SDValue &Lo,
// more effectively move in the right direction and prevent falling down
// to scalarization in many cases due to the input vector being split too
// far.
- if (SrcVT.getVectorElementCount().isKnownEven() &&
- SrcVT.getScalarSizeInBits() * 2 < DestVT.getScalarSizeInBits()) {
+ if (SrcVT.getVectorElementCount().isKnownEven() &&
+ SrcVT.getScalarSizeInBits() * 2 < DestVT.getScalarSizeInBits()) {
LLVMContext &Ctx = *DAG.getContext();
EVT NewSrcVT = SrcVT.widenIntegerVectorElementType(Ctx);
EVT SplitSrcVT = SrcVT.getHalfNumVectorElementsVT(Ctx);
@@ -2059,23 +2059,23 @@ void DAGTypeLegalizer::SplitVecRes_VAARG(SDNode *N, SDValue &Lo, SDValue &Hi) {
ReplaceValueWith(SDValue(N, 1), Chain);
}
-void DAGTypeLegalizer::SplitVecRes_FP_TO_XINT_SAT(SDNode *N, SDValue &Lo,
- SDValue &Hi) {
- EVT DstVTLo, DstVTHi;
- std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(N->getValueType(0));
- SDLoc dl(N);
-
- SDValue SrcLo, SrcHi;
- EVT SrcVT = N->getOperand(0).getValueType();
- if (getTypeAction(SrcVT) == TargetLowering::TypeSplitVector)
- GetSplitVector(N->getOperand(0), SrcLo, SrcHi);
- else
- std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(N, 0);
-
- Lo = DAG.getNode(N->getOpcode(), dl, DstVTLo, SrcLo, N->getOperand(1));
- Hi = DAG.getNode(N->getOpcode(), dl, DstVTHi, SrcHi, N->getOperand(1));
-}
-
+void DAGTypeLegalizer::SplitVecRes_FP_TO_XINT_SAT(SDNode *N, SDValue &Lo,
+ SDValue &Hi) {
+ EVT DstVTLo, DstVTHi;
+ std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(N->getValueType(0));
+ SDLoc dl(N);
+
+ SDValue SrcLo, SrcHi;
+ EVT SrcVT = N->getOperand(0).getValueType();
+ if (getTypeAction(SrcVT) == TargetLowering::TypeSplitVector)
+ GetSplitVector(N->getOperand(0), SrcLo, SrcHi);
+ else
+ std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(N, 0);
+
+ Lo = DAG.getNode(N->getOpcode(), dl, DstVTLo, SrcLo, N->getOperand(1));
+ Hi = DAG.getNode(N->getOpcode(), dl, DstVTHi, SrcHi, N->getOperand(1));
+}
+
//===----------------------------------------------------------------------===//
// Operand Vector Splitting
//===----------------------------------------------------------------------===//
@@ -2092,95 +2092,95 @@ bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) {
if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false))
return false;
- switch (N->getOpcode()) {
- default:
+ switch (N->getOpcode()) {
+ default:
#ifndef NDEBUG
- dbgs() << "SplitVectorOperand Op #" << OpNo << ": ";
- N->dump(&DAG);
- dbgs() << "\n";
+ dbgs() << "SplitVectorOperand Op #" << OpNo << ": ";
+ N->dump(&DAG);
+ dbgs() << "\n";
#endif
- report_fatal_error("Do not know how to split this operator's "
- "operand!\n");
-
- case ISD::SETCC: Res = SplitVecOp_VSETCC(N); break;
- case ISD::BITCAST: Res = SplitVecOp_BITCAST(N); break;
- case ISD::EXTRACT_SUBVECTOR: Res = SplitVecOp_EXTRACT_SUBVECTOR(N); break;
- case ISD::INSERT_SUBVECTOR: Res = SplitVecOp_INSERT_SUBVECTOR(N, OpNo); break;
- case ISD::EXTRACT_VECTOR_ELT:Res = SplitVecOp_EXTRACT_VECTOR_ELT(N); break;
- case ISD::CONCAT_VECTORS: Res = SplitVecOp_CONCAT_VECTORS(N); break;
- case ISD::TRUNCATE:
- Res = SplitVecOp_TruncateHelper(N);
- break;
- case ISD::STRICT_FP_ROUND:
- case ISD::FP_ROUND: Res = SplitVecOp_FP_ROUND(N); break;
- case ISD::FCOPYSIGN: Res = SplitVecOp_FCOPYSIGN(N); break;
- case ISD::STORE:
- Res = SplitVecOp_STORE(cast<StoreSDNode>(N), OpNo);
- break;
- case ISD::MSTORE:
- Res = SplitVecOp_MSTORE(cast<MaskedStoreSDNode>(N), OpNo);
- break;
- case ISD::MSCATTER:
- Res = SplitVecOp_MSCATTER(cast<MaskedScatterSDNode>(N), OpNo);
- break;
- case ISD::MGATHER:
- Res = SplitVecOp_MGATHER(cast<MaskedGatherSDNode>(N), OpNo);
- break;
- case ISD::VSELECT:
- Res = SplitVecOp_VSELECT(N, OpNo);
- break;
- case ISD::STRICT_SINT_TO_FP:
- case ISD::STRICT_UINT_TO_FP:
- case ISD::SINT_TO_FP:
- case ISD::UINT_TO_FP:
- if (N->getValueType(0).bitsLT(
- N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType()))
+ report_fatal_error("Do not know how to split this operator's "
+ "operand!\n");
+
+ case ISD::SETCC: Res = SplitVecOp_VSETCC(N); break;
+ case ISD::BITCAST: Res = SplitVecOp_BITCAST(N); break;
+ case ISD::EXTRACT_SUBVECTOR: Res = SplitVecOp_EXTRACT_SUBVECTOR(N); break;
+ case ISD::INSERT_SUBVECTOR: Res = SplitVecOp_INSERT_SUBVECTOR(N, OpNo); break;
+ case ISD::EXTRACT_VECTOR_ELT:Res = SplitVecOp_EXTRACT_VECTOR_ELT(N); break;
+ case ISD::CONCAT_VECTORS: Res = SplitVecOp_CONCAT_VECTORS(N); break;
+ case ISD::TRUNCATE:
+ Res = SplitVecOp_TruncateHelper(N);
+ break;
+ case ISD::STRICT_FP_ROUND:
+ case ISD::FP_ROUND: Res = SplitVecOp_FP_ROUND(N); break;
+ case ISD::FCOPYSIGN: Res = SplitVecOp_FCOPYSIGN(N); break;
+ case ISD::STORE:
+ Res = SplitVecOp_STORE(cast<StoreSDNode>(N), OpNo);
+ break;
+ case ISD::MSTORE:
+ Res = SplitVecOp_MSTORE(cast<MaskedStoreSDNode>(N), OpNo);
+ break;
+ case ISD::MSCATTER:
+ Res = SplitVecOp_MSCATTER(cast<MaskedScatterSDNode>(N), OpNo);
+ break;
+ case ISD::MGATHER:
+ Res = SplitVecOp_MGATHER(cast<MaskedGatherSDNode>(N), OpNo);
+ break;
+ case ISD::VSELECT:
+ Res = SplitVecOp_VSELECT(N, OpNo);
+ break;
+ case ISD::STRICT_SINT_TO_FP:
+ case ISD::STRICT_UINT_TO_FP:
+ case ISD::SINT_TO_FP:
+ case ISD::UINT_TO_FP:
+ if (N->getValueType(0).bitsLT(
+ N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType()))
Res = SplitVecOp_TruncateHelper(N);
- else
+ else
Res = SplitVecOp_UnaryOp(N);
- break;
- case ISD::FP_TO_SINT_SAT:
- case ISD::FP_TO_UINT_SAT:
- Res = SplitVecOp_FP_TO_XINT_SAT(N);
- break;
- case ISD::FP_TO_SINT:
- case ISD::FP_TO_UINT:
- case ISD::STRICT_FP_TO_SINT:
- case ISD::STRICT_FP_TO_UINT:
- case ISD::STRICT_FP_EXTEND:
- case ISD::FP_EXTEND:
- case ISD::SIGN_EXTEND:
- case ISD::ZERO_EXTEND:
- case ISD::ANY_EXTEND:
- case ISD::FTRUNC:
- Res = SplitVecOp_UnaryOp(N);
- break;
-
- case ISD::ANY_EXTEND_VECTOR_INREG:
- case ISD::SIGN_EXTEND_VECTOR_INREG:
- case ISD::ZERO_EXTEND_VECTOR_INREG:
- Res = SplitVecOp_ExtVecInRegOp(N);
- break;
-
- case ISD::VECREDUCE_FADD:
- case ISD::VECREDUCE_FMUL:
- case ISD::VECREDUCE_ADD:
- case ISD::VECREDUCE_MUL:
- case ISD::VECREDUCE_AND:
- case ISD::VECREDUCE_OR:
- case ISD::VECREDUCE_XOR:
- case ISD::VECREDUCE_SMAX:
- case ISD::VECREDUCE_SMIN:
- case ISD::VECREDUCE_UMAX:
- case ISD::VECREDUCE_UMIN:
- case ISD::VECREDUCE_FMAX:
- case ISD::VECREDUCE_FMIN:
- Res = SplitVecOp_VECREDUCE(N, OpNo);
- break;
- case ISD::VECREDUCE_SEQ_FADD:
- case ISD::VECREDUCE_SEQ_FMUL:
- Res = SplitVecOp_VECREDUCE_SEQ(N);
- break;
+ break;
+ case ISD::FP_TO_SINT_SAT:
+ case ISD::FP_TO_UINT_SAT:
+ Res = SplitVecOp_FP_TO_XINT_SAT(N);
+ break;
+ case ISD::FP_TO_SINT:
+ case ISD::FP_TO_UINT:
+ case ISD::STRICT_FP_TO_SINT:
+ case ISD::STRICT_FP_TO_UINT:
+ case ISD::STRICT_FP_EXTEND:
+ case ISD::FP_EXTEND:
+ case ISD::SIGN_EXTEND:
+ case ISD::ZERO_EXTEND:
+ case ISD::ANY_EXTEND:
+ case ISD::FTRUNC:
+ Res = SplitVecOp_UnaryOp(N);
+ break;
+
+ case ISD::ANY_EXTEND_VECTOR_INREG:
+ case ISD::SIGN_EXTEND_VECTOR_INREG:
+ case ISD::ZERO_EXTEND_VECTOR_INREG:
+ Res = SplitVecOp_ExtVecInRegOp(N);
+ break;
+
+ case ISD::VECREDUCE_FADD:
+ case ISD::VECREDUCE_FMUL:
+ case ISD::VECREDUCE_ADD:
+ case ISD::VECREDUCE_MUL:
+ case ISD::VECREDUCE_AND:
+ case ISD::VECREDUCE_OR:
+ case ISD::VECREDUCE_XOR:
+ case ISD::VECREDUCE_SMAX:
+ case ISD::VECREDUCE_SMIN:
+ case ISD::VECREDUCE_UMAX:
+ case ISD::VECREDUCE_UMIN:
+ case ISD::VECREDUCE_FMAX:
+ case ISD::VECREDUCE_FMIN:
+ Res = SplitVecOp_VECREDUCE(N, OpNo);
+ break;
+ case ISD::VECREDUCE_SEQ_FADD:
+ case ISD::VECREDUCE_SEQ_FMUL:
+ Res = SplitVecOp_VECREDUCE_SEQ(N);
+ break;
}
// If the result is null, the sub-method took care of registering results etc.
@@ -2250,33 +2250,33 @@ SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(SDNode *N, unsigned OpNo) {
// Use the appropriate scalar instruction on the split subvectors before
// reducing the now partially reduced smaller vector.
- unsigned CombineOpc = ISD::getVecReduceBaseOpcode(N->getOpcode());
+ unsigned CombineOpc = ISD::getVecReduceBaseOpcode(N->getOpcode());
SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT, Lo, Hi, N->getFlags());
return DAG.getNode(N->getOpcode(), dl, ResVT, Partial, N->getFlags());
}
-SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE_SEQ(SDNode *N) {
- EVT ResVT = N->getValueType(0);
- SDValue Lo, Hi;
- SDLoc dl(N);
-
- SDValue AccOp = N->getOperand(0);
- SDValue VecOp = N->getOperand(1);
- SDNodeFlags Flags = N->getFlags();
-
- EVT VecVT = VecOp.getValueType();
- assert(VecVT.isVector() && "Can only split reduce vector operand");
- GetSplitVector(VecOp, Lo, Hi);
- EVT LoOpVT, HiOpVT;
- std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
-
- // Reduce low half.
- SDValue Partial = DAG.getNode(N->getOpcode(), dl, ResVT, AccOp, Lo, Flags);
-
- // Reduce high half, using low half result as initial value.
- return DAG.getNode(N->getOpcode(), dl, ResVT, Partial, Hi, Flags);
-}
-
+SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE_SEQ(SDNode *N) {
+ EVT ResVT = N->getValueType(0);
+ SDValue Lo, Hi;
+ SDLoc dl(N);
+
+ SDValue AccOp = N->getOperand(0);
+ SDValue VecOp = N->getOperand(1);
+ SDNodeFlags Flags = N->getFlags();
+
+ EVT VecVT = VecOp.getValueType();
+ assert(VecVT.isVector() && "Can only split reduce vector operand");
+ GetSplitVector(VecOp, Lo, Hi);
+ EVT LoOpVT, HiOpVT;
+ std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
+
+ // Reduce low half.
+ SDValue Partial = DAG.getNode(N->getOpcode(), dl, ResVT, AccOp, Lo, Flags);
+
+ // Reduce high half, using low half result as initial value.
+ return DAG.getNode(N->getOpcode(), dl, ResVT, Partial, Hi, Flags);
+}
+
SDValue DAGTypeLegalizer::SplitVecOp_UnaryOp(SDNode *N) {
// The result has a legal vector type, but the input needs splitting.
EVT ResVT = N->getValueType(0);
@@ -2326,36 +2326,36 @@ SDValue DAGTypeLegalizer::SplitVecOp_BITCAST(SDNode *N) {
JoinIntegers(Lo, Hi));
}
-SDValue DAGTypeLegalizer::SplitVecOp_INSERT_SUBVECTOR(SDNode *N,
- unsigned OpNo) {
- assert(OpNo == 1 && "Invalid OpNo; can only split SubVec.");
- // We know that the result type is legal.
- EVT ResVT = N->getValueType(0);
-
- SDValue Vec = N->getOperand(0);
- SDValue SubVec = N->getOperand(1);
- SDValue Idx = N->getOperand(2);
- SDLoc dl(N);
-
- SDValue Lo, Hi;
- GetSplitVector(SubVec, Lo, Hi);
-
- uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
- uint64_t LoElts = Lo.getValueType().getVectorMinNumElements();
-
- SDValue FirstInsertion =
- DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, Vec, Lo, Idx);
- SDValue SecondInsertion =
- DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, FirstInsertion, Hi,
- DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
-
- return SecondInsertion;
-}
-
+SDValue DAGTypeLegalizer::SplitVecOp_INSERT_SUBVECTOR(SDNode *N,
+ unsigned OpNo) {
+ assert(OpNo == 1 && "Invalid OpNo; can only split SubVec.");
+ // We know that the result type is legal.
+ EVT ResVT = N->getValueType(0);
+
+ SDValue Vec = N->getOperand(0);
+ SDValue SubVec = N->getOperand(1);
+ SDValue Idx = N->getOperand(2);
+ SDLoc dl(N);
+
+ SDValue Lo, Hi;
+ GetSplitVector(SubVec, Lo, Hi);
+
+ uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
+ uint64_t LoElts = Lo.getValueType().getVectorMinNumElements();
+
+ SDValue FirstInsertion =
+ DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, Vec, Lo, Idx);
+ SDValue SecondInsertion =
+ DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, FirstInsertion, Hi,
+ DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
+
+ return SecondInsertion;
+}
+
SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N) {
// We know that the extracted result type is legal.
EVT SubVT = N->getValueType(0);
-
+
SDValue Idx = N->getOperand(1);
SDLoc dl(N);
SDValue Lo, Hi;
@@ -2391,14 +2391,14 @@ SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
SDValue Lo, Hi;
GetSplitVector(Vec, Lo, Hi);
- uint64_t LoElts = Lo.getValueType().getVectorMinNumElements();
+ uint64_t LoElts = Lo.getValueType().getVectorMinNumElements();
if (IdxVal < LoElts)
return SDValue(DAG.UpdateNodeOperands(N, Lo, Idx), 0);
- else if (!Vec.getValueType().isScalableVector())
- return SDValue(DAG.UpdateNodeOperands(N, Hi,
- DAG.getConstant(IdxVal - LoElts, SDLoc(N),
- Idx.getValueType())), 0);
+ else if (!Vec.getValueType().isScalableVector())
+ return SDValue(DAG.UpdateNodeOperands(N, Hi,
+ DAG.getConstant(IdxVal - LoElts, SDLoc(N),
+ Idx.getValueType())), 0);
}
// See if the target wants to custom expand this node.
@@ -2411,7 +2411,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
if (VecVT.getScalarSizeInBits() < 8) {
EltVT = MVT::i8;
VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT,
- VecVT.getVectorElementCount());
+ VecVT.getVectorElementCount());
Vec = DAG.getNode(ISD::ANY_EXTEND, dl, VecVT, Vec);
}
@@ -2441,7 +2441,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
return DAG.getExtLoad(
ISD::EXTLOAD, dl, N->getValueType(0), Store, StackPtr,
MachinePointerInfo::getUnknownStack(DAG.getMachineFunction()), EltVT,
- commonAlignment(SmallestAlign, EltVT.getFixedSizeInBits() / 8));
+ commonAlignment(SmallestAlign, EltVT.getFixedSizeInBits() / 8));
}
SDValue DAGTypeLegalizer::SplitVecOp_ExtVecInRegOp(SDNode *N) {
@@ -2467,7 +2467,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_MGATHER(MaskedGatherSDNode *MGT,
SDValue Mask = MGT->getMask();
SDValue PassThru = MGT->getPassThru();
Align Alignment = MGT->getOriginalAlign();
- ISD::LoadExtType ExtType = MGT->getExtensionType();
+ ISD::LoadExtType ExtType = MGT->getExtensionType();
SDValue MaskLo, MaskHi;
if (getTypeAction(Mask.getValueType()) == TargetLowering::TypeSplitVector)
@@ -2498,12 +2498,12 @@ SDValue DAGTypeLegalizer::SplitVecOp_MGATHER(MaskedGatherSDNode *MGT,
MGT->getRanges());
SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo, Scale};
- SDValue Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
- OpsLo, MMO, MGT->getIndexType(), ExtType);
+ SDValue Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
+ OpsLo, MMO, MGT->getIndexType(), ExtType);
SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi, Scale};
- SDValue Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
- OpsHi, MMO, MGT->getIndexType(), ExtType);
+ SDValue Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
+ OpsHi, MMO, MGT->getIndexType(), ExtType);
// Build a factor node to remember that this load is independent of the
// other one.
@@ -2557,10 +2557,10 @@ SDValue DAGTypeLegalizer::SplitVecOp_MSTORE(MaskedStoreSDNode *N,
DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.getValueType(), &HiIsEmpty);
SDValue Lo, Hi, Res;
- unsigned LoSize = MemoryLocation::getSizeOrUnknown(LoMemVT.getStoreSize());
+ unsigned LoSize = MemoryLocation::getSizeOrUnknown(LoMemVT.getStoreSize());
MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
- N->getPointerInfo(), MachineMemOperand::MOStore, LoSize, Alignment,
- N->getAAInfo(), N->getRanges());
+ N->getPointerInfo(), MachineMemOperand::MOStore, LoSize, Alignment,
+ N->getAAInfo(), N->getRanges());
Lo = DAG.getMaskedStore(Ch, DL, DataLo, Ptr, Offset, MaskLo, LoMemVT, MMO,
N->getAddressingMode(), N->isTruncatingStore(),
@@ -2575,19 +2575,19 @@ SDValue DAGTypeLegalizer::SplitVecOp_MSTORE(MaskedStoreSDNode *N,
Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, DL, LoMemVT, DAG,
N->isCompressingStore());
- MachinePointerInfo MPI;
- if (LoMemVT.isScalableVector()) {
- Alignment = commonAlignment(
- Alignment, LoMemVT.getSizeInBits().getKnownMinSize() / 8);
- MPI = MachinePointerInfo(N->getPointerInfo().getAddrSpace());
- } else
- MPI = N->getPointerInfo().getWithOffset(
- LoMemVT.getStoreSize().getFixedSize());
-
- unsigned HiSize = MemoryLocation::getSizeOrUnknown(HiMemVT.getStoreSize());
+ MachinePointerInfo MPI;
+ if (LoMemVT.isScalableVector()) {
+ Alignment = commonAlignment(
+ Alignment, LoMemVT.getSizeInBits().getKnownMinSize() / 8);
+ MPI = MachinePointerInfo(N->getPointerInfo().getAddrSpace());
+ } else
+ MPI = N->getPointerInfo().getWithOffset(
+ LoMemVT.getStoreSize().getFixedSize());
+
+ unsigned HiSize = MemoryLocation::getSizeOrUnknown(HiMemVT.getStoreSize());
MMO = DAG.getMachineFunction().getMachineMemOperand(
- MPI, MachineMemOperand::MOStore, HiSize, Alignment, N->getAAInfo(),
- N->getRanges());
+ MPI, MachineMemOperand::MOStore, HiSize, Alignment, N->getAAInfo(),
+ N->getRanges());
Hi = DAG.getMaskedStore(Ch, DL, DataHi, Ptr, Offset, MaskHi, HiMemVT, MMO,
N->getAddressingMode(), N->isTruncatingStore(),
@@ -2609,15 +2609,15 @@ SDValue DAGTypeLegalizer::SplitVecOp_MSCATTER(MaskedScatterSDNode *N,
SDValue Index = N->getIndex();
SDValue Scale = N->getScale();
SDValue Data = N->getValue();
- EVT MemoryVT = N->getMemoryVT();
+ EVT MemoryVT = N->getMemoryVT();
Align Alignment = N->getOriginalAlign();
SDLoc DL(N);
// Split all operands
- EVT LoMemVT, HiMemVT;
- std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
-
+ EVT LoMemVT, HiMemVT;
+ std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
+
SDValue DataLo, DataHi;
if (getTypeAction(Data.getValueType()) == TargetLowering::TypeSplitVector)
// Split Data operand
@@ -2648,17 +2648,17 @@ SDValue DAGTypeLegalizer::SplitVecOp_MSCATTER(MaskedScatterSDNode *N,
MemoryLocation::UnknownSize, Alignment, N->getAAInfo(), N->getRanges());
SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo, Scale};
- Lo = DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
- DL, OpsLo, MMO, N->getIndexType(),
- N->isTruncatingStore());
+ Lo = DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
+ DL, OpsLo, MMO, N->getIndexType(),
+ N->isTruncatingStore());
// The order of the Scatter operation after split is well defined. The "Hi"
// part comes after the "Lo". So these two operations should be chained one
// after another.
SDValue OpsHi[] = {Lo, DataHi, MaskHi, Ptr, IndexHi, Scale};
- return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
- DL, OpsHi, MMO, N->getIndexType(),
- N->isTruncatingStore());
+ return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
+ DL, OpsHi, MMO, N->getIndexType(),
+ N->isTruncatingStore());
}
SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) {
@@ -2784,7 +2784,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_TruncateHelper(SDNode *N) {
EVT::getFloatingPointVT(InElementSize/2) :
EVT::getIntegerVT(*DAG.getContext(), InElementSize/2);
EVT HalfVT = EVT::getVectorVT(*DAG.getContext(), HalfElementVT,
- NumElements.divideCoefficientBy(2));
+ NumElements.divideCoefficientBy(2));
SDValue HalfLo;
SDValue HalfHi;
@@ -2863,7 +2863,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_FP_ROUND(SDNode *N) {
EVT InVT = Lo.getValueType();
EVT OutVT = EVT::getVectorVT(*DAG.getContext(), ResVT.getVectorElementType(),
- InVT.getVectorElementCount());
+ InVT.getVectorElementCount());
if (N->isStrictFPOpcode()) {
Lo = DAG.getNode(N->getOpcode(), DL, { OutVT, MVT::Other },
@@ -2889,23 +2889,23 @@ SDValue DAGTypeLegalizer::SplitVecOp_FCOPYSIGN(SDNode *N) {
return DAG.UnrollVectorOp(N, N->getValueType(0).getVectorNumElements());
}
-SDValue DAGTypeLegalizer::SplitVecOp_FP_TO_XINT_SAT(SDNode *N) {
- EVT ResVT = N->getValueType(0);
- SDValue Lo, Hi;
- SDLoc dl(N);
- GetSplitVector(N->getOperand(0), Lo, Hi);
- EVT InVT = Lo.getValueType();
-
- EVT NewResVT =
- EVT::getVectorVT(*DAG.getContext(), ResVT.getVectorElementType(),
- InVT.getVectorElementCount());
-
- Lo = DAG.getNode(N->getOpcode(), dl, NewResVT, Lo, N->getOperand(1));
- Hi = DAG.getNode(N->getOpcode(), dl, NewResVT, Hi, N->getOperand(1));
-
- return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResVT, Lo, Hi);
-}
-
+SDValue DAGTypeLegalizer::SplitVecOp_FP_TO_XINT_SAT(SDNode *N) {
+ EVT ResVT = N->getValueType(0);
+ SDValue Lo, Hi;
+ SDLoc dl(N);
+ GetSplitVector(N->getOperand(0), Lo, Hi);
+ EVT InVT = Lo.getValueType();
+
+ EVT NewResVT =
+ EVT::getVectorVT(*DAG.getContext(), ResVT.getVectorElementType(),
+ InVT.getVectorElementCount());
+
+ Lo = DAG.getNode(N->getOpcode(), dl, NewResVT, Lo, N->getOperand(1));
+ Hi = DAG.getNode(N->getOpcode(), dl, NewResVT, Hi, N->getOperand(1));
+
+ return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResVT, Lo, Hi);
+}
+
//===----------------------------------------------------------------------===//
// Result Vector Widening
//===----------------------------------------------------------------------===//
@@ -2935,10 +2935,10 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
case ISD::EXTRACT_SUBVECTOR: Res = WidenVecRes_EXTRACT_SUBVECTOR(N); break;
case ISD::INSERT_VECTOR_ELT: Res = WidenVecRes_INSERT_VECTOR_ELT(N); break;
case ISD::LOAD: Res = WidenVecRes_LOAD(N); break;
- case ISD::SPLAT_VECTOR:
- case ISD::SCALAR_TO_VECTOR:
- Res = WidenVecRes_ScalarOp(N);
- break;
+ case ISD::SPLAT_VECTOR:
+ case ISD::SCALAR_TO_VECTOR:
+ Res = WidenVecRes_ScalarOp(N);
+ break;
case ISD::SIGN_EXTEND_INREG: Res = WidenVecRes_InregOp(N); break;
case ISD::VSELECT:
case ISD::SELECT: Res = WidenVecRes_SELECT(N); break;
@@ -2963,9 +2963,9 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
case ISD::OR:
case ISD::SUB:
case ISD::XOR:
- case ISD::SHL:
- case ISD::SRA:
- case ISD::SRL:
+ case ISD::SHL:
+ case ISD::SRA:
+ case ISD::SRL:
case ISD::FMINNUM:
case ISD::FMAXNUM:
case ISD::FMINIMUM:
@@ -2978,10 +2978,10 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
case ISD::SADDSAT:
case ISD::USUBSAT:
case ISD::SSUBSAT:
- case ISD::SSHLSAT:
- case ISD::USHLSAT:
- case ISD::ROTL:
- case ISD::ROTR:
+ case ISD::SSHLSAT:
+ case ISD::USHLSAT:
+ case ISD::ROTL:
+ case ISD::ROTR:
Res = WidenVecRes_Binary(N);
break;
@@ -3049,11 +3049,11 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
Res = WidenVecRes_Convert(N);
break;
- case ISD::FP_TO_SINT_SAT:
- case ISD::FP_TO_UINT_SAT:
- Res = WidenVecRes_FP_TO_XINT_SAT(N);
- break;
-
+ case ISD::FP_TO_SINT_SAT:
+ case ISD::FP_TO_UINT_SAT:
+ Res = WidenVecRes_FP_TO_XINT_SAT(N);
+ break;
+
case ISD::FABS:
case ISD::FCEIL:
case ISD::FCOS:
@@ -3101,8 +3101,8 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
Res = WidenVecRes_Unary(N);
break;
case ISD::FMA:
- case ISD::FSHL:
- case ISD::FSHR:
+ case ISD::FSHL:
+ case ISD::FSHR:
Res = WidenVecRes_Ternary(N);
break;
}
@@ -3468,34 +3468,34 @@ SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(SDNode *N, unsigned ResNo) {
}
SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
- LLVMContext &Ctx = *DAG.getContext();
+ LLVMContext &Ctx = *DAG.getContext();
SDValue InOp = N->getOperand(0);
SDLoc DL(N);
- EVT WidenVT = TLI.getTypeToTransformTo(Ctx, N->getValueType(0));
+ EVT WidenVT = TLI.getTypeToTransformTo(Ctx, N->getValueType(0));
unsigned WidenNumElts = WidenVT.getVectorNumElements();
EVT InVT = InOp.getValueType();
unsigned Opcode = N->getOpcode();
- const SDNodeFlags Flags = N->getFlags();
-
- // Handle the case of ZERO_EXTEND where the promoted InVT element size does
- // not equal that of WidenVT.
- if (N->getOpcode() == ISD::ZERO_EXTEND &&
- getTypeAction(InVT) == TargetLowering::TypePromoteInteger &&
- TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
- WidenVT.getScalarSizeInBits()) {
- InOp = ZExtPromotedInteger(InOp);
- InVT = InOp.getValueType();
- if (WidenVT.getScalarSizeInBits() < InVT.getScalarSizeInBits())
- Opcode = ISD::TRUNCATE;
- }
-
- EVT InEltVT = InVT.getVectorElementType();
- EVT InWidenVT = EVT::getVectorVT(Ctx, InEltVT, WidenNumElts);
+ const SDNodeFlags Flags = N->getFlags();
+
+ // Handle the case of ZERO_EXTEND where the promoted InVT element size does
+ // not equal that of WidenVT.
+ if (N->getOpcode() == ISD::ZERO_EXTEND &&
+ getTypeAction(InVT) == TargetLowering::TypePromoteInteger &&
+ TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
+ WidenVT.getScalarSizeInBits()) {
+ InOp = ZExtPromotedInteger(InOp);
+ InVT = InOp.getValueType();
+ if (WidenVT.getScalarSizeInBits() < InVT.getScalarSizeInBits())
+ Opcode = ISD::TRUNCATE;
+ }
+
+ EVT InEltVT = InVT.getVectorElementType();
+ EVT InWidenVT = EVT::getVectorVT(Ctx, InEltVT, WidenNumElts);
unsigned InVTNumElts = InVT.getVectorNumElements();
-
+
if (getTypeAction(InVT) == TargetLowering::TypeWidenVector) {
InOp = GetWidenedVector(N->getOperand(0));
InVT = InOp.getValueType();
@@ -3563,27 +3563,27 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
return DAG.getBuildVector(WidenVT, DL, Ops);
}
-SDValue DAGTypeLegalizer::WidenVecRes_FP_TO_XINT_SAT(SDNode *N) {
- SDLoc dl(N);
- EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
- ElementCount WidenNumElts = WidenVT.getVectorElementCount();
-
- SDValue Src = N->getOperand(0);
- EVT SrcVT = Src.getValueType();
-
- // Also widen the input.
- if (getTypeAction(SrcVT) == TargetLowering::TypeWidenVector) {
- Src = GetWidenedVector(Src);
- SrcVT = Src.getValueType();
- }
-
- // Input and output not widened to the same size, give up.
- if (WidenNumElts != SrcVT.getVectorElementCount())
- return DAG.UnrollVectorOp(N, WidenNumElts.getKnownMinValue());
-
- return DAG.getNode(N->getOpcode(), dl, WidenVT, Src, N->getOperand(1));
-}
-
+SDValue DAGTypeLegalizer::WidenVecRes_FP_TO_XINT_SAT(SDNode *N) {
+ SDLoc dl(N);
+ EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
+ ElementCount WidenNumElts = WidenVT.getVectorElementCount();
+
+ SDValue Src = N->getOperand(0);
+ EVT SrcVT = Src.getValueType();
+
+ // Also widen the input.
+ if (getTypeAction(SrcVT) == TargetLowering::TypeWidenVector) {
+ Src = GetWidenedVector(Src);
+ SrcVT = Src.getValueType();
+ }
+
+ // Input and output not widened to the same size, give up.
+ if (WidenNumElts != SrcVT.getVectorElementCount())
+ return DAG.UnrollVectorOp(N, WidenNumElts.getKnownMinValue());
+
+ return DAG.getNode(N->getOpcode(), dl, WidenVT, Src, N->getOperand(1));
+}
+
SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(SDNode *N) {
SDValue InOp = N->getOperand(1);
SDLoc DL(N);
@@ -4044,13 +4044,13 @@ SDValue DAGTypeLegalizer::WidenVecRes_MGATHER(MaskedGatherSDNode *N) {
Index = ModifyToType(Index, WideIndexVT);
SDValue Ops[] = { N->getChain(), PassThru, Mask, N->getBasePtr(), Index,
Scale };
-
- // Widen the MemoryType
- EVT WideMemVT = EVT::getVectorVT(*DAG.getContext(),
- N->getMemoryVT().getScalarType(), NumElts);
+
+ // Widen the MemoryType
+ EVT WideMemVT = EVT::getVectorVT(*DAG.getContext(),
+ N->getMemoryVT().getScalarType(), NumElts);
SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
- WideMemVT, dl, Ops, N->getMemOperand(),
- N->getIndexType(), N->getExtensionType());
+ WideMemVT, dl, Ops, N->getMemOperand(),
+ N->getIndexType(), N->getExtensionType());
// Legalize the chain result - switch anything that used the old chain to
// use the new one.
@@ -4058,9 +4058,9 @@ SDValue DAGTypeLegalizer::WidenVecRes_MGATHER(MaskedGatherSDNode *N) {
return Res;
}
-SDValue DAGTypeLegalizer::WidenVecRes_ScalarOp(SDNode *N) {
+SDValue DAGTypeLegalizer::WidenVecRes_ScalarOp(SDNode *N) {
EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
- return DAG.getNode(N->getOpcode(), SDLoc(N), WidenVT, N->getOperand(0));
+ return DAG.getNode(N->getOpcode(), SDLoc(N), WidenVT, N->getOperand(0));
}
// Return true is this is a SETCC node or a strict version of it.
@@ -4180,11 +4180,11 @@ SDValue DAGTypeLegalizer::convertMask(SDValue InMask, EVT MaskVT,
return Mask;
}
-// This method tries to handle some special cases for the vselect mask
-// and if needed adjusting the mask vector type to match that of the VSELECT.
-// Without it, many cases end up with scalarization of the SETCC, with many
-// unnecessary instructions.
-SDValue DAGTypeLegalizer::WidenVSELECTMask(SDNode *N) {
+// This method tries to handle some special cases for the vselect mask
+// and if needed adjusting the mask vector type to match that of the VSELECT.
+// Without it, many cases end up with scalarization of the SETCC, with many
+// unnecessary instructions.
+SDValue DAGTypeLegalizer::WidenVSELECTMask(SDNode *N) {
LLVMContext &Ctx = *DAG.getContext();
SDValue Cond = N->getOperand(0);
@@ -4231,8 +4231,8 @@ SDValue DAGTypeLegalizer::WidenVSELECTMask(SDNode *N) {
return SDValue();
}
- // Widen the vselect result type if needed.
- if (getTypeAction(VSelVT) == TargetLowering::TypeWidenVector)
+ // Widen the vselect result type if needed.
+ if (getTypeAction(VSelVT) == TargetLowering::TypeWidenVector)
VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
// The mask of the VSELECT should have integer elements.
@@ -4282,7 +4282,7 @@ SDValue DAGTypeLegalizer::WidenVSELECTMask(SDNode *N) {
} else
return SDValue();
- return Mask;
+ return Mask;
}
SDValue DAGTypeLegalizer::WidenVecRes_SELECT(SDNode *N) {
@@ -4292,13 +4292,13 @@ SDValue DAGTypeLegalizer::WidenVecRes_SELECT(SDNode *N) {
SDValue Cond1 = N->getOperand(0);
EVT CondVT = Cond1.getValueType();
if (CondVT.isVector()) {
- if (SDValue WideCond = WidenVSELECTMask(N)) {
- SDValue InOp1 = GetWidenedVector(N->getOperand(1));
- SDValue InOp2 = GetWidenedVector(N->getOperand(2));
- assert(InOp1.getValueType() == WidenVT && InOp2.getValueType() == WidenVT);
- return DAG.getNode(N->getOpcode(), SDLoc(N),
- WidenVT, WideCond, InOp1, InOp2);
- }
+ if (SDValue WideCond = WidenVSELECTMask(N)) {
+ SDValue InOp1 = GetWidenedVector(N->getOperand(1));
+ SDValue InOp2 = GetWidenedVector(N->getOperand(2));
+ assert(InOp1.getValueType() == WidenVT && InOp2.getValueType() == WidenVT);
+ return DAG.getNode(N->getOpcode(), SDLoc(N),
+ WidenVT, WideCond, InOp1, InOp2);
+ }
EVT CondEltVT = CondVT.getVectorElementType();
EVT CondWidenVT = EVT::getVectorVT(*DAG.getContext(),
@@ -4505,11 +4505,11 @@ bool DAGTypeLegalizer::WidenVectorOperand(SDNode *N, unsigned OpNo) {
Res = WidenVecOp_Convert(N);
break;
- case ISD::FP_TO_SINT_SAT:
- case ISD::FP_TO_UINT_SAT:
- Res = WidenVecOp_FP_TO_XINT_SAT(N);
- break;
-
+ case ISD::FP_TO_SINT_SAT:
+ case ISD::FP_TO_UINT_SAT:
+ Res = WidenVecOp_FP_TO_XINT_SAT(N);
+ break;
+
case ISD::VECREDUCE_FADD:
case ISD::VECREDUCE_FMUL:
case ISD::VECREDUCE_ADD:
@@ -4525,10 +4525,10 @@ bool DAGTypeLegalizer::WidenVectorOperand(SDNode *N, unsigned OpNo) {
case ISD::VECREDUCE_FMIN:
Res = WidenVecOp_VECREDUCE(N);
break;
- case ISD::VECREDUCE_SEQ_FADD:
- case ISD::VECREDUCE_SEQ_FMUL:
- Res = WidenVecOp_VECREDUCE_SEQ(N);
- break;
+ case ISD::VECREDUCE_SEQ_FADD:
+ case ISD::VECREDUCE_SEQ_FMUL:
+ Res = WidenVecOp_VECREDUCE_SEQ(N);
+ break;
}
// If Res is null, the sub-method took care of registering the result.
@@ -4683,28 +4683,28 @@ SDValue DAGTypeLegalizer::WidenVecOp_Convert(SDNode *N) {
return DAG.getBuildVector(VT, dl, Ops);
}
-SDValue DAGTypeLegalizer::WidenVecOp_FP_TO_XINT_SAT(SDNode *N) {
- EVT DstVT = N->getValueType(0);
- SDValue Src = GetWidenedVector(N->getOperand(0));
- EVT SrcVT = Src.getValueType();
- ElementCount WideNumElts = SrcVT.getVectorElementCount();
- SDLoc dl(N);
-
- // See if a widened result type would be legal, if so widen the node.
- EVT WideDstVT = EVT::getVectorVT(*DAG.getContext(),
- DstVT.getVectorElementType(), WideNumElts);
- if (TLI.isTypeLegal(WideDstVT)) {
- SDValue Res =
- DAG.getNode(N->getOpcode(), dl, WideDstVT, Src, N->getOperand(1));
- return DAG.getNode(
- ISD::EXTRACT_SUBVECTOR, dl, DstVT, Res,
- DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
- }
-
- // Give up and unroll.
- return DAG.UnrollVectorOp(N);
-}
-
+SDValue DAGTypeLegalizer::WidenVecOp_FP_TO_XINT_SAT(SDNode *N) {
+ EVT DstVT = N->getValueType(0);
+ SDValue Src = GetWidenedVector(N->getOperand(0));
+ EVT SrcVT = Src.getValueType();
+ ElementCount WideNumElts = SrcVT.getVectorElementCount();
+ SDLoc dl(N);
+
+ // See if a widened result type would be legal, if so widen the node.
+ EVT WideDstVT = EVT::getVectorVT(*DAG.getContext(),
+ DstVT.getVectorElementType(), WideNumElts);
+ if (TLI.isTypeLegal(WideDstVT)) {
+ SDValue Res =
+ DAG.getNode(N->getOpcode(), dl, WideDstVT, Src, N->getOperand(1));
+ return DAG.getNode(
+ ISD::EXTRACT_SUBVECTOR, dl, DstVT, Res,
+ DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
+ }
+
+ // Give up and unroll.
+ return DAG.UnrollVectorOp(N);
+}
+
SDValue DAGTypeLegalizer::WidenVecOp_BITCAST(SDNode *N) {
EVT VT = N->getValueType(0);
SDValue InOp = GetWidenedVector(N->getOperand(0));
@@ -4806,11 +4806,11 @@ SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) {
return TLI.scalarizeVectorStore(ST, DAG);
if (ST->isTruncatingStore())
- return TLI.scalarizeVectorStore(ST, DAG);
+ return TLI.scalarizeVectorStore(ST, DAG);
+
+ SmallVector<SDValue, 16> StChain;
+ GenWidenVectorStores(StChain, ST);
- SmallVector<SDValue, 16> StChain;
- GenWidenVectorStores(StChain, ST);
-
if (StChain.size() == 1)
return StChain[0];
else
@@ -4871,8 +4871,8 @@ SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(SDNode *N, unsigned OpNo) {
SDValue Ops[] = {MG->getChain(), DataOp, Mask, MG->getBasePtr(), Index,
Scale};
SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl, Ops,
- MG->getMemOperand(), MG->getIndexType(),
- MG->getExtensionType());
+ MG->getMemOperand(), MG->getIndexType(),
+ MG->getExtensionType());
ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
ReplaceValueWith(SDValue(N, 0), Res.getValue(0));
return SDValue();
@@ -4884,7 +4884,7 @@ SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(SDNode *N, unsigned OpNo) {
SDValue Mask = MSC->getMask();
SDValue Index = MSC->getIndex();
SDValue Scale = MSC->getScale();
- EVT WideMemVT = MSC->getMemoryVT();
+ EVT WideMemVT = MSC->getMemoryVT();
if (OpNo == 1) {
DataOp = GetWidenedVector(DataOp);
@@ -4901,10 +4901,10 @@ SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(SDNode *N, unsigned OpNo) {
EVT WideMaskVT = EVT::getVectorVT(*DAG.getContext(),
MaskVT.getVectorElementType(), NumElts);
Mask = ModifyToType(Mask, WideMaskVT, true);
-
- // Widen the MemoryType
- WideMemVT = EVT::getVectorVT(*DAG.getContext(),
- MSC->getMemoryVT().getScalarType(), NumElts);
+
+ // Widen the MemoryType
+ WideMemVT = EVT::getVectorVT(*DAG.getContext(),
+ MSC->getMemoryVT().getScalarType(), NumElts);
} else if (OpNo == 4) {
// Just widen the index. It's allowed to have extra elements.
Index = GetWidenedVector(Index);
@@ -4913,9 +4913,9 @@ SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(SDNode *N, unsigned OpNo) {
SDValue Ops[] = {MSC->getChain(), DataOp, Mask, MSC->getBasePtr(), Index,
Scale};
- return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(N),
- Ops, MSC->getMemOperand(), MSC->getIndexType(),
- MSC->isTruncatingStore());
+ return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(N),
+ Ops, MSC->getMemOperand(), MSC->getIndexType(),
+ MSC->isTruncatingStore());
}
SDValue DAGTypeLegalizer::WidenVecOp_SETCC(SDNode *N) {
@@ -4994,12 +4994,37 @@ SDValue DAGTypeLegalizer::WidenVecOp_VECREDUCE(SDNode *N) {
EVT OrigVT = N->getOperand(0).getValueType();
EVT WideVT = Op.getValueType();
EVT ElemVT = OrigVT.getVectorElementType();
- SDNodeFlags Flags = N->getFlags();
+ SDNodeFlags Flags = N->getFlags();
+
+ unsigned Opc = N->getOpcode();
+ unsigned BaseOpc = ISD::getVecReduceBaseOpcode(Opc);
+ SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
+ assert(NeutralElem && "Neutral element must exist");
+
+ // Pad the vector with the neutral element.
+ unsigned OrigElts = OrigVT.getVectorNumElements();
+ unsigned WideElts = WideVT.getVectorNumElements();
+ for (unsigned Idx = OrigElts; Idx < WideElts; Idx++)
+ Op = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, WideVT, Op, NeutralElem,
+ DAG.getVectorIdxConstant(Idx, dl));
+
+ return DAG.getNode(Opc, dl, N->getValueType(0), Op, Flags);
+}
+
+SDValue DAGTypeLegalizer::WidenVecOp_VECREDUCE_SEQ(SDNode *N) {
+ SDLoc dl(N);
+ SDValue AccOp = N->getOperand(0);
+ SDValue VecOp = N->getOperand(1);
+ SDValue Op = GetWidenedVector(VecOp);
+
+ EVT OrigVT = VecOp.getValueType();
+ EVT WideVT = Op.getValueType();
+ EVT ElemVT = OrigVT.getVectorElementType();
+ SDNodeFlags Flags = N->getFlags();
- unsigned Opc = N->getOpcode();
- unsigned BaseOpc = ISD::getVecReduceBaseOpcode(Opc);
- SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
- assert(NeutralElem && "Neutral element must exist");
+ unsigned Opc = N->getOpcode();
+ unsigned BaseOpc = ISD::getVecReduceBaseOpcode(Opc);
+ SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
// Pad the vector with the neutral element.
unsigned OrigElts = OrigVT.getVectorNumElements();
@@ -5008,34 +5033,9 @@ SDValue DAGTypeLegalizer::WidenVecOp_VECREDUCE(SDNode *N) {
Op = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, WideVT, Op, NeutralElem,
DAG.getVectorIdxConstant(Idx, dl));
- return DAG.getNode(Opc, dl, N->getValueType(0), Op, Flags);
-}
-
-SDValue DAGTypeLegalizer::WidenVecOp_VECREDUCE_SEQ(SDNode *N) {
- SDLoc dl(N);
- SDValue AccOp = N->getOperand(0);
- SDValue VecOp = N->getOperand(1);
- SDValue Op = GetWidenedVector(VecOp);
-
- EVT OrigVT = VecOp.getValueType();
- EVT WideVT = Op.getValueType();
- EVT ElemVT = OrigVT.getVectorElementType();
- SDNodeFlags Flags = N->getFlags();
-
- unsigned Opc = N->getOpcode();
- unsigned BaseOpc = ISD::getVecReduceBaseOpcode(Opc);
- SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
-
- // Pad the vector with the neutral element.
- unsigned OrigElts = OrigVT.getVectorNumElements();
- unsigned WideElts = WideVT.getVectorNumElements();
- for (unsigned Idx = OrigElts; Idx < WideElts; Idx++)
- Op = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, WideVT, Op, NeutralElem,
- DAG.getVectorIdxConstant(Idx, dl));
-
- return DAG.getNode(Opc, dl, N->getValueType(0), AccOp, Op, Flags);
-}
-
+ return DAG.getNode(Opc, dl, N->getValueType(0), AccOp, Op, Flags);
+}
+
SDValue DAGTypeLegalizer::WidenVecOp_VSELECT(SDNode *N) {
// This only gets called in the case that the left and right inputs and
// result are of a legal odd vector type, and the condition is illegal i1 of
@@ -5076,7 +5076,7 @@ static EVT FindMemType(SelectionDAG& DAG, const TargetLowering &TLI,
// If we have one element to load/store, return it.
EVT RetVT = WidenEltVT;
- if (!Scalable && Width == WidenEltWidth)
+ if (!Scalable && Width == WidenEltWidth)
return RetVT;
// See if there is larger legal integer than the element type to load/store.
@@ -5122,14 +5122,14 @@ static EVT FindMemType(SelectionDAG& DAG, const TargetLowering &TLI,
isPowerOf2_32(WidenWidth / MemVTWidth) &&
(MemVTWidth <= Width ||
(Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
- if (RetVT.getFixedSizeInBits() < MemVTWidth || MemVT == WidenVT)
+ if (RetVT.getFixedSizeInBits() < MemVTWidth || MemVT == WidenVT)
return MemVT;
}
}
- if (Scalable)
- report_fatal_error("Using element-wise loads and stores for widening "
- "operations is not supported for scalable vectors");
+ if (Scalable)
+ report_fatal_error("Using element-wise loads and stores for widening "
+ "operations is not supported for scalable vectors");
return RetVT;
}
@@ -5175,7 +5175,7 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain,
EVT LdVT = LD->getMemoryVT();
SDLoc dl(LD);
assert(LdVT.isVector() && WidenVT.isVector());
- assert(LdVT.isScalableVector() == WidenVT.isScalableVector());
+ assert(LdVT.isScalableVector() == WidenVT.isScalableVector());
assert(LdVT.getVectorElementType() == WidenVT.getVectorElementType());
// Load information
@@ -5184,25 +5184,25 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain,
MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
AAMDNodes AAInfo = LD->getAAInfo();
- TypeSize LdWidth = LdVT.getSizeInBits();
- TypeSize WidenWidth = WidenVT.getSizeInBits();
- TypeSize WidthDiff = WidenWidth - LdWidth;
+ TypeSize LdWidth = LdVT.getSizeInBits();
+ TypeSize WidenWidth = WidenVT.getSizeInBits();
+ TypeSize WidthDiff = WidenWidth - LdWidth;
// Allow wider loads if they are sufficiently aligned to avoid memory faults
// and if the original load is simple.
unsigned LdAlign = (!LD->isSimple()) ? 0 : LD->getAlignment();
// Find the vector type that can load from.
- EVT NewVT = FindMemType(DAG, TLI, LdWidth.getKnownMinSize(), WidenVT, LdAlign,
- WidthDiff.getKnownMinSize());
- TypeSize NewVTWidth = NewVT.getSizeInBits();
+ EVT NewVT = FindMemType(DAG, TLI, LdWidth.getKnownMinSize(), WidenVT, LdAlign,
+ WidthDiff.getKnownMinSize());
+ TypeSize NewVTWidth = NewVT.getSizeInBits();
SDValue LdOp = DAG.getLoad(NewVT, dl, Chain, BasePtr, LD->getPointerInfo(),
LD->getOriginalAlign(), MMOFlags, AAInfo);
LdChain.push_back(LdOp.getValue(1));
// Check if we can load the element with one instruction.
- if (TypeSize::isKnownLE(LdWidth, NewVTWidth)) {
+ if (TypeSize::isKnownLE(LdWidth, NewVTWidth)) {
if (!NewVT.isVector()) {
- unsigned NumElts = WidenWidth.getFixedSize() / NewVTWidth.getFixedSize();
+ unsigned NumElts = WidenWidth.getFixedSize() / NewVTWidth.getFixedSize();
EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NumElts);
SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
return DAG.getNode(ISD::BITCAST, dl, WidenVT, VecOp);
@@ -5210,9 +5210,9 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain,
if (NewVT == WidenVT)
return LdOp;
- // TODO: We don't currently have any tests that exercise this code path.
- assert(WidenWidth.getFixedSize() % NewVTWidth.getFixedSize() == 0);
- unsigned NumConcat = WidenWidth.getFixedSize() / NewVTWidth.getFixedSize();
+ // TODO: We don't currently have any tests that exercise this code path.
+ assert(WidenWidth.getFixedSize() % NewVTWidth.getFixedSize() == 0);
+ unsigned NumConcat = WidenWidth.getFixedSize() / NewVTWidth.getFixedSize();
SmallVector<SDValue, 16> ConcatOps(NumConcat);
SDValue UndefVal = DAG.getUNDEF(NewVT);
ConcatOps[0] = LdOp;
@@ -5225,30 +5225,30 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain,
SmallVector<SDValue, 16> LdOps;
LdOps.push_back(LdOp);
- uint64_t ScaledOffset = 0;
- MachinePointerInfo MPI = LD->getPointerInfo();
- do {
- LdWidth -= NewVTWidth;
- IncrementPointer(cast<LoadSDNode>(LdOp), NewVT, MPI, BasePtr,
- &ScaledOffset);
+ uint64_t ScaledOffset = 0;
+ MachinePointerInfo MPI = LD->getPointerInfo();
+ do {
+ LdWidth -= NewVTWidth;
+ IncrementPointer(cast<LoadSDNode>(LdOp), NewVT, MPI, BasePtr,
+ &ScaledOffset);
- if (TypeSize::isKnownLT(LdWidth, NewVTWidth)) {
+ if (TypeSize::isKnownLT(LdWidth, NewVTWidth)) {
// The current type we are using is too large. Find a better size.
- NewVT = FindMemType(DAG, TLI, LdWidth.getKnownMinSize(), WidenVT, LdAlign,
- WidthDiff.getKnownMinSize());
+ NewVT = FindMemType(DAG, TLI, LdWidth.getKnownMinSize(), WidenVT, LdAlign,
+ WidthDiff.getKnownMinSize());
NewVTWidth = NewVT.getSizeInBits();
}
- Align NewAlign = ScaledOffset == 0
- ? LD->getOriginalAlign()
- : commonAlignment(LD->getAlign(), ScaledOffset);
- SDValue L =
- DAG.getLoad(NewVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
- LdChain.push_back(L.getValue(1));
-
+ Align NewAlign = ScaledOffset == 0
+ ? LD->getOriginalAlign()
+ : commonAlignment(LD->getAlign(), ScaledOffset);
+ SDValue L =
+ DAG.getLoad(NewVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
+ LdChain.push_back(L.getValue(1));
+
LdOps.push_back(L);
LdOp = L;
- } while (TypeSize::isKnownGT(LdWidth, NewVTWidth));
+ } while (TypeSize::isKnownGT(LdWidth, NewVTWidth));
// Build the vector from the load operations.
unsigned End = LdOps.size();
@@ -5272,18 +5272,18 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain,
}
ConcatOps[--Idx] = BuildVectorFromScalar(DAG, LdTy, LdOps, i + 1, End);
}
-
+
ConcatOps[--Idx] = LdOps[i];
for (--i; i >= 0; --i) {
EVT NewLdTy = LdOps[i].getValueType();
if (NewLdTy != LdTy) {
// Create a larger vector.
- TypeSize LdTySize = LdTy.getSizeInBits();
- TypeSize NewLdTySize = NewLdTy.getSizeInBits();
- assert(NewLdTySize.isScalable() == LdTySize.isScalable() &&
- NewLdTySize.isKnownMultipleOf(LdTySize.getKnownMinSize()));
- unsigned NumOps =
- NewLdTySize.getKnownMinSize() / LdTySize.getKnownMinSize();
+ TypeSize LdTySize = LdTy.getSizeInBits();
+ TypeSize NewLdTySize = NewLdTy.getSizeInBits();
+ assert(NewLdTySize.isScalable() == LdTySize.isScalable() &&
+ NewLdTySize.isKnownMultipleOf(LdTySize.getKnownMinSize()));
+ unsigned NumOps =
+ NewLdTySize.getKnownMinSize() / LdTySize.getKnownMinSize();
SmallVector<SDValue, 16> WidenOps(NumOps);
unsigned j = 0;
for (; j != End-Idx; ++j)
@@ -5304,8 +5304,8 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain,
makeArrayRef(&ConcatOps[Idx], End - Idx));
// We need to fill the rest with undefs to build the vector.
- unsigned NumOps =
- WidenWidth.getKnownMinSize() / LdTy.getSizeInBits().getKnownMinSize();
+ unsigned NumOps =
+ WidenWidth.getKnownMinSize() / LdTy.getSizeInBits().getKnownMinSize();
SmallVector<SDValue, 16> WidenOps(NumOps);
SDValue UndefVal = DAG.getUNDEF(LdTy);
{
@@ -5328,7 +5328,7 @@ DAGTypeLegalizer::GenWidenVectorExtLoads(SmallVectorImpl<SDValue> &LdChain,
EVT LdVT = LD->getMemoryVT();
SDLoc dl(LD);
assert(LdVT.isVector() && WidenVT.isVector());
- assert(LdVT.isScalableVector() == WidenVT.isScalableVector());
+ assert(LdVT.isScalableVector() == WidenVT.isScalableVector());
// Load information
SDValue Chain = LD->getChain();
@@ -5336,10 +5336,10 @@ DAGTypeLegalizer::GenWidenVectorExtLoads(SmallVectorImpl<SDValue> &LdChain,
MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
AAMDNodes AAInfo = LD->getAAInfo();
- if (LdVT.isScalableVector())
- report_fatal_error("Generating widen scalable extending vector loads is "
- "not yet supported");
-
+ if (LdVT.isScalableVector())
+ report_fatal_error("Generating widen scalable extending vector loads is "
+ "not yet supported");
+
EVT EltVT = WidenVT.getVectorElementType();
EVT LdEltVT = LdVT.getVectorElementType();
unsigned NumElts = LdVT.getVectorNumElements();
@@ -5354,8 +5354,8 @@ DAGTypeLegalizer::GenWidenVectorExtLoads(SmallVectorImpl<SDValue> &LdChain,
LdChain.push_back(Ops[0].getValue(1));
unsigned i = 0, Offset = Increment;
for (i=1; i < NumElts; ++i, Offset += Increment) {
- SDValue NewBasePtr =
- DAG.getObjectPtrOffset(dl, BasePtr, TypeSize::Fixed(Offset));
+ SDValue NewBasePtr =
+ DAG.getObjectPtrOffset(dl, BasePtr, TypeSize::Fixed(Offset));
Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
LD->getPointerInfo().getWithOffset(Offset), LdEltVT,
LD->getOriginalAlign(), MMOFlags, AAInfo);
@@ -5383,62 +5383,62 @@ void DAGTypeLegalizer::GenWidenVectorStores(SmallVectorImpl<SDValue> &StChain,
SDLoc dl(ST);
EVT StVT = ST->getMemoryVT();
- TypeSize StWidth = StVT.getSizeInBits();
+ TypeSize StWidth = StVT.getSizeInBits();
EVT ValVT = ValOp.getValueType();
- TypeSize ValWidth = ValVT.getSizeInBits();
+ TypeSize ValWidth = ValVT.getSizeInBits();
EVT ValEltVT = ValVT.getVectorElementType();
- unsigned ValEltWidth = ValEltVT.getFixedSizeInBits();
+ unsigned ValEltWidth = ValEltVT.getFixedSizeInBits();
assert(StVT.getVectorElementType() == ValEltVT);
- assert(StVT.isScalableVector() == ValVT.isScalableVector() &&
- "Mismatch between store and value types");
+ assert(StVT.isScalableVector() == ValVT.isScalableVector() &&
+ "Mismatch between store and value types");
int Idx = 0; // current index to store
-
- MachinePointerInfo MPI = ST->getPointerInfo();
- uint64_t ScaledOffset = 0;
- while (StWidth.isNonZero()) {
+
+ MachinePointerInfo MPI = ST->getPointerInfo();
+ uint64_t ScaledOffset = 0;
+ while (StWidth.isNonZero()) {
// Find the largest vector type we can store with.
- EVT NewVT = FindMemType(DAG, TLI, StWidth.getKnownMinSize(), ValVT);
- TypeSize NewVTWidth = NewVT.getSizeInBits();
-
+ EVT NewVT = FindMemType(DAG, TLI, StWidth.getKnownMinSize(), ValVT);
+ TypeSize NewVTWidth = NewVT.getSizeInBits();
+
if (NewVT.isVector()) {
- unsigned NumVTElts = NewVT.getVectorMinNumElements();
+ unsigned NumVTElts = NewVT.getVectorMinNumElements();
do {
- Align NewAlign = ScaledOffset == 0
- ? ST->getOriginalAlign()
- : commonAlignment(ST->getAlign(), ScaledOffset);
+ Align NewAlign = ScaledOffset == 0
+ ? ST->getOriginalAlign()
+ : commonAlignment(ST->getAlign(), ScaledOffset);
SDValue EOp = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NewVT, ValOp,
DAG.getVectorIdxConstant(Idx, dl));
- SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
- MMOFlags, AAInfo);
- StChain.push_back(PartStore);
-
+ SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
+ MMOFlags, AAInfo);
+ StChain.push_back(PartStore);
+
StWidth -= NewVTWidth;
Idx += NumVTElts;
- IncrementPointer(cast<StoreSDNode>(PartStore), NewVT, MPI, BasePtr,
- &ScaledOffset);
- } while (StWidth.isNonZero() && TypeSize::isKnownGE(StWidth, NewVTWidth));
+ IncrementPointer(cast<StoreSDNode>(PartStore), NewVT, MPI, BasePtr,
+ &ScaledOffset);
+ } while (StWidth.isNonZero() && TypeSize::isKnownGE(StWidth, NewVTWidth));
} else {
// Cast the vector to the scalar type we can store.
- unsigned NumElts = ValWidth.getFixedSize() / NewVTWidth.getFixedSize();
+ unsigned NumElts = ValWidth.getFixedSize() / NewVTWidth.getFixedSize();
EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NumElts);
SDValue VecOp = DAG.getNode(ISD::BITCAST, dl, NewVecVT, ValOp);
// Readjust index position based on new vector type.
- Idx = Idx * ValEltWidth / NewVTWidth.getFixedSize();
+ Idx = Idx * ValEltWidth / NewVTWidth.getFixedSize();
do {
SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, VecOp,
DAG.getVectorIdxConstant(Idx++, dl));
- SDValue PartStore =
- DAG.getStore(Chain, dl, EOp, BasePtr, MPI, ST->getOriginalAlign(),
- MMOFlags, AAInfo);
- StChain.push_back(PartStore);
-
+ SDValue PartStore =
+ DAG.getStore(Chain, dl, EOp, BasePtr, MPI, ST->getOriginalAlign(),
+ MMOFlags, AAInfo);
+ StChain.push_back(PartStore);
+
StWidth -= NewVTWidth;
- IncrementPointer(cast<StoreSDNode>(PartStore), NewVT, MPI, BasePtr);
- } while (StWidth.isNonZero() && TypeSize::isKnownGE(StWidth, NewVTWidth));
+ IncrementPointer(cast<StoreSDNode>(PartStore), NewVT, MPI, BasePtr);
+ } while (StWidth.isNonZero() && TypeSize::isKnownGE(StWidth, NewVTWidth));
// Restore index back to be relative to the original widen element type.
- Idx = Idx * NewVTWidth.getFixedSize() / ValEltWidth;
+ Idx = Idx * NewVTWidth.getFixedSize() / ValEltWidth;
}
}
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
index e1d2c3c771..0022e5ec31 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
@@ -760,7 +760,7 @@ void ScheduleDAGLinearize::Schedule() {
MachineBasicBlock*
ScheduleDAGLinearize::EmitSchedule(MachineBasicBlock::iterator &InsertPos) {
- InstrEmitter Emitter(DAG->getTarget(), BB, InsertPos);
+ InstrEmitter Emitter(DAG->getTarget(), BB, InsertPos);
DenseMap<SDValue, Register> VRBaseMap;
LLVM_DEBUG({ dbgs() << "\n*** Final schedule ***\n"; });
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
index 163e31165e..7a5e8ac607 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -1838,16 +1838,16 @@ protected:
template<class SF>
static SUnit *popFromQueueImpl(std::vector<SUnit *> &Q, SF &Picker) {
- unsigned BestIdx = 0;
- // Only compute the cost for the first 1000 items in the queue, to avoid
- // excessive compile-times for very large queues.
- for (unsigned I = 1, E = std::min(Q.size(), (decltype(Q.size()))1000); I != E;
- I++)
- if (Picker(Q[BestIdx], Q[I]))
- BestIdx = I;
- SUnit *V = Q[BestIdx];
- if (BestIdx + 1 != Q.size())
- std::swap(Q[BestIdx], Q.back());
+ unsigned BestIdx = 0;
+ // Only compute the cost for the first 1000 items in the queue, to avoid
+ // excessive compile-times for very large queues.
+ for (unsigned I = 1, E = std::min(Q.size(), (decltype(Q.size()))1000); I != E;
+ I++)
+ if (Picker(Q[BestIdx], Q[I]))
+ BestIdx = I;
+ SUnit *V = Q[BestIdx];
+ if (BestIdx + 1 != Q.size())
+ std::swap(Q[BestIdx], Q.back());
Q.pop_back();
return V;
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
index de0a4af09a..debfdda90e 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
@@ -125,7 +125,7 @@ static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
PhysReg = Reg;
} else if (Def->isMachineOpcode()) {
const MCInstrDesc &II = TII->get(Def->getMachineOpcode());
- if (ResNo >= II.getNumDefs() && II.hasImplicitDefOfPhysReg(Reg))
+ if (ResNo >= II.getNumDefs() && II.hasImplicitDefOfPhysReg(Reg))
PhysReg = Reg;
}
@@ -172,7 +172,7 @@ static bool AddGlue(SDNode *N, SDValue Glue, bool AddGlue, SelectionDAG *DAG) {
// Don't add glue to something that already has a glue value.
if (N->getValueType(N->getNumValues() - 1) == MVT::Glue) return false;
- SmallVector<EVT, 4> VTs(N->values());
+ SmallVector<EVT, 4> VTs(N->values());
if (AddGlue)
VTs.push_back(MVT::Glue);
@@ -829,7 +829,7 @@ EmitPhysRegCopy(SUnit *SU, DenseMap<SUnit*, Register> &VRBaseMap,
/// not necessarily refer to returned BB. The emitter may split blocks.
MachineBasicBlock *ScheduleDAGSDNodes::
EmitSchedule(MachineBasicBlock::iterator &InsertPos) {
- InstrEmitter Emitter(DAG->getTarget(), BB, InsertPos);
+ InstrEmitter Emitter(DAG->getTarget(), BB, InsertPos);
DenseMap<SDValue, Register> VRBaseMap;
DenseMap<SUnit*, Register> CopyVRBaseMap;
SmallVector<std::pair<unsigned, MachineInstr*>, 32> Orders;
@@ -1033,29 +1033,29 @@ EmitSchedule(MachineBasicBlock::iterator &InsertPos) {
}
InsertPos = Emitter.getInsertPos();
- // In some cases, DBG_VALUEs might be inserted after the first terminator,
- // which results in an invalid MBB. If that happens, move the DBG_VALUEs
- // before the first terminator.
- MachineBasicBlock *InsertBB = Emitter.getBlock();
- auto FirstTerm = InsertBB->getFirstTerminator();
- if (FirstTerm != InsertBB->end()) {
- assert(!FirstTerm->isDebugValue() &&
- "first terminator cannot be a debug value");
- for (MachineInstr &MI : make_early_inc_range(
- make_range(std::next(FirstTerm), InsertBB->end()))) {
- if (!MI.isDebugValue())
- continue;
-
- if (&MI == InsertPos)
- InsertPos = std::prev(InsertPos->getIterator());
-
- // The DBG_VALUE was referencing a value produced by a terminator. By
- // moving the DBG_VALUE, the referenced value also needs invalidating.
- MI.getOperand(0).ChangeToRegister(0, false);
- MI.moveBefore(&*FirstTerm);
- }
- }
- return InsertBB;
+ // In some cases, DBG_VALUEs might be inserted after the first terminator,
+ // which results in an invalid MBB. If that happens, move the DBG_VALUEs
+ // before the first terminator.
+ MachineBasicBlock *InsertBB = Emitter.getBlock();
+ auto FirstTerm = InsertBB->getFirstTerminator();
+ if (FirstTerm != InsertBB->end()) {
+ assert(!FirstTerm->isDebugValue() &&
+ "first terminator cannot be a debug value");
+ for (MachineInstr &MI : make_early_inc_range(
+ make_range(std::next(FirstTerm), InsertBB->end()))) {
+ if (!MI.isDebugValue())
+ continue;
+
+ if (&MI == InsertPos)
+ InsertPos = std::prev(InsertPos->getIterator());
+
+ // The DBG_VALUE was referencing a value produced by a terminator. By
+ // moving the DBG_VALUE, the referenced value also needs invalidating.
+ MI.getOperand(0).ChangeToRegister(0, false);
+ MI.moveBefore(&*FirstTerm);
+ }
+ }
+ return InsertBB;
}
/// Return the basic block label.
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index b0f50ffafd..2090762e2f 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -28,7 +28,7 @@
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/CodeGen/FunctionLoweringInfo.h"
+#include "llvm/CodeGen/FunctionLoweringInfo.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineConstantPool.h"
@@ -139,15 +139,15 @@ bool ConstantFPSDNode::isValueValidForType(EVT VT,
//===----------------------------------------------------------------------===//
bool ISD::isConstantSplatVector(const SDNode *N, APInt &SplatVal) {
- if (N->getOpcode() == ISD::SPLAT_VECTOR) {
- unsigned EltSize =
- N->getValueType(0).getVectorElementType().getSizeInBits();
- if (auto *Op0 = dyn_cast<ConstantSDNode>(N->getOperand(0))) {
- SplatVal = Op0->getAPIntValue().truncOrSelf(EltSize);
- return true;
- }
- }
-
+ if (N->getOpcode() == ISD::SPLAT_VECTOR) {
+ unsigned EltSize =
+ N->getValueType(0).getVectorElementType().getSizeInBits();
+ if (auto *Op0 = dyn_cast<ConstantSDNode>(N->getOperand(0))) {
+ SplatVal = Op0->getAPIntValue().truncOrSelf(EltSize);
+ return true;
+ }
+ }
+
auto *BV = dyn_cast<BuildVectorSDNode>(N);
if (!BV)
return false;
@@ -164,16 +164,16 @@ bool ISD::isConstantSplatVector(const SDNode *N, APInt &SplatVal) {
// FIXME: AllOnes and AllZeros duplicate a lot of code. Could these be
// specializations of the more general isConstantSplatVector()?
-bool ISD::isConstantSplatVectorAllOnes(const SDNode *N, bool BuildVectorOnly) {
+bool ISD::isConstantSplatVectorAllOnes(const SDNode *N, bool BuildVectorOnly) {
// Look through a bit convert.
while (N->getOpcode() == ISD::BITCAST)
N = N->getOperand(0).getNode();
- if (!BuildVectorOnly && N->getOpcode() == ISD::SPLAT_VECTOR) {
- APInt SplatVal;
- return isConstantSplatVector(N, SplatVal) && SplatVal.isAllOnesValue();
- }
-
+ if (!BuildVectorOnly && N->getOpcode() == ISD::SPLAT_VECTOR) {
+ APInt SplatVal;
+ return isConstantSplatVector(N, SplatVal) && SplatVal.isAllOnesValue();
+ }
+
if (N->getOpcode() != ISD::BUILD_VECTOR) return false;
unsigned i = 0, e = N->getNumOperands();
@@ -213,16 +213,16 @@ bool ISD::isConstantSplatVectorAllOnes(const SDNode *N, bool BuildVectorOnly) {
return true;
}
-bool ISD::isConstantSplatVectorAllZeros(const SDNode *N, bool BuildVectorOnly) {
+bool ISD::isConstantSplatVectorAllZeros(const SDNode *N, bool BuildVectorOnly) {
// Look through a bit convert.
while (N->getOpcode() == ISD::BITCAST)
N = N->getOperand(0).getNode();
- if (!BuildVectorOnly && N->getOpcode() == ISD::SPLAT_VECTOR) {
- APInt SplatVal;
- return isConstantSplatVector(N, SplatVal) && SplatVal.isNullValue();
- }
-
+ if (!BuildVectorOnly && N->getOpcode() == ISD::SPLAT_VECTOR) {
+ APInt SplatVal;
+ return isConstantSplatVector(N, SplatVal) && SplatVal.isNullValue();
+ }
+
if (N->getOpcode() != ISD::BUILD_VECTOR) return false;
bool IsAllUndef = true;
@@ -255,14 +255,14 @@ bool ISD::isConstantSplatVectorAllZeros(const SDNode *N, bool BuildVectorOnly) {
return true;
}
-bool ISD::isBuildVectorAllOnes(const SDNode *N) {
- return isConstantSplatVectorAllOnes(N, /*BuildVectorOnly*/ true);
-}
-
-bool ISD::isBuildVectorAllZeros(const SDNode *N) {
- return isConstantSplatVectorAllZeros(N, /*BuildVectorOnly*/ true);
-}
-
+bool ISD::isBuildVectorAllOnes(const SDNode *N) {
+ return isConstantSplatVectorAllOnes(N, /*BuildVectorOnly*/ true);
+}
+
+bool ISD::isBuildVectorAllZeros(const SDNode *N) {
+ return isConstantSplatVectorAllZeros(N, /*BuildVectorOnly*/ true);
+}
+
bool ISD::isBuildVectorOfConstantSDNodes(const SDNode *N) {
if (N->getOpcode() != ISD::BUILD_VECTOR)
return false;
@@ -306,8 +306,8 @@ bool ISD::matchUnaryPredicate(SDValue Op,
return Match(Cst);
// FIXME: Add support for vector UNDEF cases?
- if (ISD::BUILD_VECTOR != Op.getOpcode() &&
- ISD::SPLAT_VECTOR != Op.getOpcode())
+ if (ISD::BUILD_VECTOR != Op.getOpcode() &&
+ ISD::SPLAT_VECTOR != Op.getOpcode())
return false;
EVT SVT = Op.getValueType().getScalarType();
@@ -361,76 +361,76 @@ bool ISD::matchBinaryPredicate(
return true;
}
-ISD::NodeType ISD::getVecReduceBaseOpcode(unsigned VecReduceOpcode) {
- switch (VecReduceOpcode) {
- default:
- llvm_unreachable("Expected VECREDUCE opcode");
- case ISD::VECREDUCE_FADD:
- case ISD::VECREDUCE_SEQ_FADD:
- return ISD::FADD;
- case ISD::VECREDUCE_FMUL:
- case ISD::VECREDUCE_SEQ_FMUL:
- return ISD::FMUL;
- case ISD::VECREDUCE_ADD:
- return ISD::ADD;
- case ISD::VECREDUCE_MUL:
- return ISD::MUL;
- case ISD::VECREDUCE_AND:
- return ISD::AND;
- case ISD::VECREDUCE_OR:
- return ISD::OR;
- case ISD::VECREDUCE_XOR:
- return ISD::XOR;
- case ISD::VECREDUCE_SMAX:
- return ISD::SMAX;
- case ISD::VECREDUCE_SMIN:
- return ISD::SMIN;
- case ISD::VECREDUCE_UMAX:
- return ISD::UMAX;
- case ISD::VECREDUCE_UMIN:
- return ISD::UMIN;
- case ISD::VECREDUCE_FMAX:
- return ISD::FMAXNUM;
- case ISD::VECREDUCE_FMIN:
- return ISD::FMINNUM;
- }
-}
-
-bool ISD::isVPOpcode(unsigned Opcode) {
- switch (Opcode) {
- default:
- return false;
-#define BEGIN_REGISTER_VP_SDNODE(SDOPC, ...) \
- case ISD::SDOPC: \
- return true;
-#include "llvm/IR/VPIntrinsics.def"
- }
-}
-
-/// The operand position of the vector mask.
-Optional<unsigned> ISD::getVPMaskIdx(unsigned Opcode) {
- switch (Opcode) {
- default:
- return None;
-#define BEGIN_REGISTER_VP_SDNODE(SDOPC, LEGALPOS, TDNAME, MASKPOS, ...) \
- case ISD::SDOPC: \
- return MASKPOS;
-#include "llvm/IR/VPIntrinsics.def"
- }
-}
-
-/// The operand position of the explicit vector length parameter.
-Optional<unsigned> ISD::getVPExplicitVectorLengthIdx(unsigned Opcode) {
- switch (Opcode) {
- default:
- return None;
-#define BEGIN_REGISTER_VP_SDNODE(SDOPC, LEGALPOS, TDNAME, MASKPOS, EVLPOS) \
- case ISD::SDOPC: \
- return EVLPOS;
-#include "llvm/IR/VPIntrinsics.def"
- }
-}
-
+ISD::NodeType ISD::getVecReduceBaseOpcode(unsigned VecReduceOpcode) {
+ switch (VecReduceOpcode) {
+ default:
+ llvm_unreachable("Expected VECREDUCE opcode");
+ case ISD::VECREDUCE_FADD:
+ case ISD::VECREDUCE_SEQ_FADD:
+ return ISD::FADD;
+ case ISD::VECREDUCE_FMUL:
+ case ISD::VECREDUCE_SEQ_FMUL:
+ return ISD::FMUL;
+ case ISD::VECREDUCE_ADD:
+ return ISD::ADD;
+ case ISD::VECREDUCE_MUL:
+ return ISD::MUL;
+ case ISD::VECREDUCE_AND:
+ return ISD::AND;
+ case ISD::VECREDUCE_OR:
+ return ISD::OR;
+ case ISD::VECREDUCE_XOR:
+ return ISD::XOR;
+ case ISD::VECREDUCE_SMAX:
+ return ISD::SMAX;
+ case ISD::VECREDUCE_SMIN:
+ return ISD::SMIN;
+ case ISD::VECREDUCE_UMAX:
+ return ISD::UMAX;
+ case ISD::VECREDUCE_UMIN:
+ return ISD::UMIN;
+ case ISD::VECREDUCE_FMAX:
+ return ISD::FMAXNUM;
+ case ISD::VECREDUCE_FMIN:
+ return ISD::FMINNUM;
+ }
+}
+
+bool ISD::isVPOpcode(unsigned Opcode) {
+ switch (Opcode) {
+ default:
+ return false;
+#define BEGIN_REGISTER_VP_SDNODE(SDOPC, ...) \
+ case ISD::SDOPC: \
+ return true;
+#include "llvm/IR/VPIntrinsics.def"
+ }
+}
+
+/// The operand position of the vector mask.
+Optional<unsigned> ISD::getVPMaskIdx(unsigned Opcode) {
+ switch (Opcode) {
+ default:
+ return None;
+#define BEGIN_REGISTER_VP_SDNODE(SDOPC, LEGALPOS, TDNAME, MASKPOS, ...) \
+ case ISD::SDOPC: \
+ return MASKPOS;
+#include "llvm/IR/VPIntrinsics.def"
+ }
+}
+
+/// The operand position of the explicit vector length parameter.
+Optional<unsigned> ISD::getVPExplicitVectorLengthIdx(unsigned Opcode) {
+ switch (Opcode) {
+ default:
+ return None;
+#define BEGIN_REGISTER_VP_SDNODE(SDOPC, LEGALPOS, TDNAME, MASKPOS, EVLPOS) \
+ case ISD::SDOPC: \
+ return EVLPOS;
+#include "llvm/IR/VPIntrinsics.def"
+ }
+}
+
ISD::NodeType ISD::getExtForLoadExtType(bool IsFP, ISD::LoadExtType ExtType) {
switch (ExtType) {
case ISD::EXTLOAD:
@@ -635,11 +635,11 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) {
ID.AddInteger(cast<LifetimeSDNode>(N)->getOffset());
}
break;
- case ISD::PSEUDO_PROBE:
- ID.AddInteger(cast<PseudoProbeSDNode>(N)->getGuid());
- ID.AddInteger(cast<PseudoProbeSDNode>(N)->getIndex());
- ID.AddInteger(cast<PseudoProbeSDNode>(N)->getAttributes());
- break;
+ case ISD::PSEUDO_PROBE:
+ ID.AddInteger(cast<PseudoProbeSDNode>(N)->getGuid());
+ ID.AddInteger(cast<PseudoProbeSDNode>(N)->getIndex());
+ ID.AddInteger(cast<PseudoProbeSDNode>(N)->getAttributes());
+ break;
case ISD::JumpTable:
case ISD::TargetJumpTable:
ID.AddInteger(cast<JumpTableSDNode>(N)->getIndex());
@@ -1333,7 +1333,7 @@ SDValue SelectionDAG::getConstant(uint64_t Val, const SDLoc &DL, EVT VT,
bool isT, bool isO) {
EVT EltVT = VT.getScalarType();
assert((EltVT.getSizeInBits() >= 64 ||
- (uint64_t)((int64_t)Val >> EltVT.getSizeInBits()) + 1 < 2) &&
+ (uint64_t)((int64_t)Val >> EltVT.getSizeInBits()) + 1 < 2) &&
"getConstant with a uint64_t value that doesn't fit in the type!");
return getConstant(APInt(EltVT.getSizeInBits(), Val), DL, VT, isT, isO);
}
@@ -1355,10 +1355,10 @@ SDValue SelectionDAG::getConstant(const ConstantInt &Val, const SDLoc &DL,
// inserted value (the type does not need to match the vector element type).
// Any extra bits introduced will be truncated away.
if (VT.isVector() && TLI->getTypeAction(*getContext(), EltVT) ==
- TargetLowering::TypePromoteInteger) {
- EltVT = TLI->getTypeToTransformTo(*getContext(), EltVT);
- APInt NewVal = Elt->getValue().zextOrTrunc(EltVT.getSizeInBits());
- Elt = ConstantInt::get(*getContext(), NewVal);
+ TargetLowering::TypePromoteInteger) {
+ EltVT = TLI->getTypeToTransformTo(*getContext(), EltVT);
+ APInt NewVal = Elt->getValue().zextOrTrunc(EltVT.getSizeInBits());
+ Elt = ConstantInt::get(*getContext(), NewVal);
}
// In other cases the element type is illegal and needs to be expanded, for
// example v2i64 on MIPS32. In this case, find the nearest legal type, split
@@ -1368,7 +1368,7 @@ SDValue SelectionDAG::getConstant(const ConstantInt &Val, const SDLoc &DL,
// only legalize if the DAG tells us we must produce legal types.
else if (NewNodesMustHaveLegalTypes && VT.isVector() &&
TLI->getTypeAction(*getContext(), EltVT) ==
- TargetLowering::TypeExpandInteger) {
+ TargetLowering::TypeExpandInteger) {
const APInt &NewVal = Elt->getValue();
EVT ViaEltVT = TLI->getTypeToTransformTo(*getContext(), EltVT);
unsigned ViaEltSizeInBits = ViaEltVT.getSizeInBits();
@@ -1382,9 +1382,9 @@ SDValue SelectionDAG::getConstant(const ConstantInt &Val, const SDLoc &DL,
SmallVector<SDValue, 2> EltParts;
for (unsigned i = 0; i < ViaVecNumElts / VT.getVectorNumElements(); ++i) {
- EltParts.push_back(getConstant(
- NewVal.lshr(i * ViaEltSizeInBits).zextOrTrunc(ViaEltSizeInBits), DL,
- ViaEltVT, isT, isO));
+ EltParts.push_back(getConstant(
+ NewVal.lshr(i * ViaEltSizeInBits).zextOrTrunc(ViaEltSizeInBits), DL,
+ ViaEltVT, isT, isO));
}
// EltParts is currently in little endian order. If we actually want
@@ -1401,10 +1401,10 @@ SDValue SelectionDAG::getConstant(const ConstantInt &Val, const SDLoc &DL,
SmallVector<SDValue, 8> Ops;
for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i)
- llvm::append_range(Ops, EltParts);
+ llvm::append_range(Ops, EltParts);
- SDValue V =
- getNode(ISD::BITCAST, DL, VT, getBuildVector(ViaVecVT, DL, Ops));
+ SDValue V =
+ getNode(ISD::BITCAST, DL, VT, getBuildVector(ViaVecVT, DL, Ops));
return V;
}
@@ -1485,9 +1485,9 @@ SDValue SelectionDAG::getConstantFP(const ConstantFP &V, const SDLoc &DL,
}
SDValue Result(N, 0);
- if (VT.isScalableVector())
- Result = getSplatVector(VT, DL, Result);
- else if (VT.isVector())
+ if (VT.isScalableVector())
+ Result = getSplatVector(VT, DL, Result);
+ else if (VT.isVector())
Result = getSplatBuildVector(VT, DL, Result);
NewSDValueDbgMsg(Result, "Creating fp constant: ", this);
return Result;
@@ -2130,14 +2130,14 @@ Align SelectionDAG::getReducedAlign(EVT VT, bool UseABI) {
SDValue SelectionDAG::CreateStackTemporary(TypeSize Bytes, Align Alignment) {
MachineFrameInfo &MFI = MF->getFrameInfo();
- const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering();
- int StackID = 0;
- if (Bytes.isScalable())
- StackID = TFI->getStackIDForScalableVectors();
- // The stack id gives an indication of whether the object is scalable or
- // not, so it's safe to pass in the minimum size here.
- int FrameIdx = MFI.CreateStackObject(Bytes.getKnownMinSize(), Alignment,
- false, nullptr, StackID);
+ const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering();
+ int StackID = 0;
+ if (Bytes.isScalable())
+ StackID = TFI->getStackIDForScalableVectors();
+ // The stack id gives an indication of whether the object is scalable or
+ // not, so it's safe to pass in the minimum size here.
+ int FrameIdx = MFI.CreateStackObject(Bytes.getKnownMinSize(), Alignment,
+ false, nullptr, StackID);
return getFrameIndex(FrameIdx, TLI->getFrameIndexTy(getDataLayout()));
}
@@ -2149,14 +2149,14 @@ SDValue SelectionDAG::CreateStackTemporary(EVT VT, unsigned minAlign) {
}
SDValue SelectionDAG::CreateStackTemporary(EVT VT1, EVT VT2) {
- TypeSize VT1Size = VT1.getStoreSize();
- TypeSize VT2Size = VT2.getStoreSize();
- assert(VT1Size.isScalable() == VT2Size.isScalable() &&
- "Don't know how to choose the maximum size when creating a stack "
- "temporary");
- TypeSize Bytes =
- VT1Size.getKnownMinSize() > VT2Size.getKnownMinSize() ? VT1Size : VT2Size;
-
+ TypeSize VT1Size = VT1.getStoreSize();
+ TypeSize VT2Size = VT2.getStoreSize();
+ assert(VT1Size.isScalable() == VT2Size.isScalable() &&
+ "Don't know how to choose the maximum size when creating a stack "
+ "temporary");
+ TypeSize Bytes =
+ VT1Size.getKnownMinSize() > VT2Size.getKnownMinSize() ? VT1Size : VT2Size;
+
Type *Ty1 = VT1.getTypeForEVT(*getContext());
Type *Ty2 = VT2.getTypeForEVT(*getContext());
const DataLayout &DL = getDataLayout();
@@ -2325,10 +2325,10 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
/// SimplifyMultipleUseDemandedBits and not generate any new nodes.
SDValue SelectionDAG::GetDemandedBits(SDValue V, const APInt &DemandedBits) {
EVT VT = V.getValueType();
-
- if (VT.isScalableVector())
- return SDValue();
-
+
+ if (VT.isScalableVector())
+ return SDValue();
+
APInt DemandedElts = VT.isVector()
? APInt::getAllOnesValue(VT.getVectorNumElements())
: APInt(1, 1);
@@ -2410,23 +2410,23 @@ bool SelectionDAG::MaskedValueIsAllOnes(SDValue V, const APInt &Mask,
/// sense to specify which elements are demanded or undefined, therefore
/// they are simply ignored.
bool SelectionDAG::isSplatValue(SDValue V, const APInt &DemandedElts,
- APInt &UndefElts, unsigned Depth) {
+ APInt &UndefElts, unsigned Depth) {
EVT VT = V.getValueType();
assert(VT.isVector() && "Vector type expected");
if (!VT.isScalableVector() && !DemandedElts)
return false; // No demanded elts, better to assume we don't know anything.
- if (Depth >= MaxRecursionDepth)
- return false; // Limit search depth.
-
+ if (Depth >= MaxRecursionDepth)
+ return false; // Limit search depth.
+
// Deal with some common cases here that work for both fixed and scalable
// vector types.
switch (V.getOpcode()) {
case ISD::SPLAT_VECTOR:
- UndefElts = V.getOperand(0).isUndef()
- ? APInt::getAllOnesValue(DemandedElts.getBitWidth())
- : APInt(DemandedElts.getBitWidth(), 0);
+ UndefElts = V.getOperand(0).isUndef()
+ ? APInt::getAllOnesValue(DemandedElts.getBitWidth())
+ : APInt(DemandedElts.getBitWidth(), 0);
return true;
case ISD::ADD:
case ISD::SUB:
@@ -2434,17 +2434,17 @@ bool SelectionDAG::isSplatValue(SDValue V, const APInt &DemandedElts,
APInt UndefLHS, UndefRHS;
SDValue LHS = V.getOperand(0);
SDValue RHS = V.getOperand(1);
- if (isSplatValue(LHS, DemandedElts, UndefLHS, Depth + 1) &&
- isSplatValue(RHS, DemandedElts, UndefRHS, Depth + 1)) {
+ if (isSplatValue(LHS, DemandedElts, UndefLHS, Depth + 1) &&
+ isSplatValue(RHS, DemandedElts, UndefRHS, Depth + 1)) {
UndefElts = UndefLHS | UndefRHS;
return true;
}
break;
}
- case ISD::TRUNCATE:
- case ISD::SIGN_EXTEND:
- case ISD::ZERO_EXTEND:
- return isSplatValue(V.getOperand(0), DemandedElts, UndefElts, Depth + 1);
+ case ISD::TRUNCATE:
+ case ISD::SIGN_EXTEND:
+ case ISD::ZERO_EXTEND:
+ return isSplatValue(V.getOperand(0), DemandedElts, UndefElts, Depth + 1);
}
// We don't support other cases than those above for scalable vectors at
@@ -2499,7 +2499,7 @@ bool SelectionDAG::isSplatValue(SDValue V, const APInt &DemandedElts,
unsigned NumSrcElts = Src.getValueType().getVectorNumElements();
APInt UndefSrcElts;
APInt DemandedSrcElts = DemandedElts.zextOrSelf(NumSrcElts).shl(Idx);
- if (isSplatValue(Src, DemandedSrcElts, UndefSrcElts, Depth + 1)) {
+ if (isSplatValue(Src, DemandedSrcElts, UndefSrcElts, Depth + 1)) {
UndefElts = UndefSrcElts.extractBits(NumElts, Idx);
return true;
}
@@ -2696,11 +2696,11 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
if (auto *C = dyn_cast<ConstantSDNode>(Op)) {
// We know all of the bits for a constant!
- return KnownBits::makeConstant(C->getAPIntValue());
+ return KnownBits::makeConstant(C->getAPIntValue());
}
if (auto *C = dyn_cast<ConstantFPSDNode>(Op)) {
// We know all of the bits for a constant fp!
- return KnownBits::makeConstant(C->getValueAPF().bitcastToAPInt());
+ return KnownBits::makeConstant(C->getValueAPF().bitcastToAPInt());
}
if (Depth >= MaxRecursionDepth)
@@ -2735,7 +2735,7 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
}
// Known bits are the values that are shared by every demanded element.
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
// If we don't know any bits, early out.
if (Known.isUnknown())
@@ -2772,7 +2772,7 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
if (!!DemandedLHS) {
SDValue LHS = Op.getOperand(0);
Known2 = computeKnownBits(LHS, DemandedLHS, Depth + 1);
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
}
// If we don't know any bits, early out.
if (Known.isUnknown())
@@ -2780,7 +2780,7 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
if (!!DemandedRHS) {
SDValue RHS = Op.getOperand(1);
Known2 = computeKnownBits(RHS, DemandedRHS, Depth + 1);
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
}
break;
}
@@ -2796,7 +2796,7 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
if (!!DemandedSub) {
SDValue Sub = Op.getOperand(i);
Known2 = computeKnownBits(Sub, DemandedSub, Depth + 1);
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
}
// If we don't know any bits, early out.
if (Known.isUnknown())
@@ -2824,7 +2824,7 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
}
if (!!DemandedSrcElts) {
Known2 = computeKnownBits(Src, DemandedSrcElts, Depth + 1);
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
}
break;
}
@@ -2943,13 +2943,13 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
case ISD::MUL: {
Known = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
Known2 = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
- Known = KnownBits::computeForMul(Known, Known2);
+ Known = KnownBits::computeForMul(Known, Known2);
break;
}
case ISD::UDIV: {
- Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
+ Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
- Known = KnownBits::udiv(Known, Known2);
+ Known = KnownBits::udiv(Known, Known2);
break;
}
case ISD::SELECT:
@@ -2961,7 +2961,7 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth+1);
// Only known if known in both the LHS and RHS.
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
break;
case ISD::SELECT_CC:
Known = computeKnownBits(Op.getOperand(3), DemandedElts, Depth+1);
@@ -2971,7 +2971,7 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
Known2 = computeKnownBits(Op.getOperand(2), DemandedElts, Depth+1);
// Only known if known in both the LHS and RHS.
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
break;
case ISD::SMULO:
case ISD::UMULO:
@@ -3000,8 +3000,8 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
}
case ISD::SHL:
Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
- Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
- Known = KnownBits::shl(Known, Known2);
+ Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
+ Known = KnownBits::shl(Known, Known2);
// Minimum shift low bits are known zero.
if (const APInt *ShMinAmt =
@@ -3010,8 +3010,8 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
break;
case ISD::SRL:
Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
- Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
- Known = KnownBits::lshr(Known, Known2);
+ Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
+ Known = KnownBits::lshr(Known, Known2);
// Minimum shift high bits are known zero.
if (const APInt *ShMinAmt =
@@ -3019,10 +3019,10 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
Known.Zero.setHighBits(ShMinAmt->getZExtValue());
break;
case ISD::SRA:
- Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
- Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
- Known = KnownBits::ashr(Known, Known2);
- // TODO: Add minimum shift high known sign bits.
+ Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
+ Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
+ Known = KnownBits::ashr(Known, Known2);
+ // TODO: Add minimum shift high known sign bits.
break;
case ISD::FSHL:
case ISD::FSHR:
@@ -3057,9 +3057,9 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
}
break;
case ISD::SIGN_EXTEND_INREG: {
- Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
+ Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
EVT EVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
- Known = Known.sextInReg(EVT.getScalarSizeInBits());
+ Known = Known.sextInReg(EVT.getScalarSizeInBits());
break;
}
case ISD::CTTZ:
@@ -3087,11 +3087,11 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
Known.Zero.setBitsFrom(Log2_32(PossibleOnes) + 1);
break;
}
- case ISD::PARITY: {
- // Parity returns 0 everywhere but the LSB.
- Known.Zero.setBitsFrom(1);
- break;
- }
+ case ISD::PARITY: {
+ // Parity returns 0 everywhere but the LSB.
+ Known.Zero.setBitsFrom(1);
+ break;
+ }
case ISD::LOAD: {
LoadSDNode *LD = cast<LoadSDNode>(Op);
const Constant *Cst = TLI->getTargetConstantFromLoad(LD);
@@ -3135,10 +3135,10 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
}
} else if (BitWidth == CstTy->getPrimitiveSizeInBits()) {
if (auto *CInt = dyn_cast<ConstantInt>(Cst)) {
- Known = KnownBits::makeConstant(CInt->getValue());
+ Known = KnownBits::makeConstant(CInt->getValue());
} else if (auto *CFP = dyn_cast<ConstantFP>(Cst)) {
- Known =
- KnownBits::makeConstant(CFP->getValueAPF().bitcastToAPInt());
+ Known =
+ KnownBits::makeConstant(CFP->getValueAPF().bitcastToAPInt());
}
}
}
@@ -3278,16 +3278,16 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
Known = KnownBits::computeForAddCarry(Known, Known2, Carry);
break;
}
- case ISD::SREM: {
- Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
- Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
- Known = KnownBits::srem(Known, Known2);
+ case ISD::SREM: {
+ Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
+ Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
+ Known = KnownBits::srem(Known, Known2);
break;
- }
+ }
case ISD::UREM: {
Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
- Known = KnownBits::urem(Known, Known2);
+ Known = KnownBits::urem(Known, Known2);
break;
}
case ISD::EXTRACT_ELEMENT: {
@@ -3307,9 +3307,9 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
SDValue InVec = Op.getOperand(0);
SDValue EltNo = Op.getOperand(1);
EVT VecVT = InVec.getValueType();
- // computeKnownBits not yet implemented for scalable vectors.
- if (VecVT.isScalableVector())
- break;
+ // computeKnownBits not yet implemented for scalable vectors.
+ if (VecVT.isScalableVector())
+ break;
const unsigned EltBitWidth = VecVT.getScalarSizeInBits();
const unsigned NumSrcElts = VecVT.getVectorNumElements();
@@ -3350,39 +3350,39 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
Known.Zero.setAllBits();
if (DemandedVal) {
Known2 = computeKnownBits(InVal, Depth + 1);
- Known = KnownBits::commonBits(Known, Known2.zextOrTrunc(BitWidth));
+ Known = KnownBits::commonBits(Known, Known2.zextOrTrunc(BitWidth));
}
if (!!DemandedVecElts) {
Known2 = computeKnownBits(InVec, DemandedVecElts, Depth + 1);
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
}
break;
}
case ISD::BITREVERSE: {
Known2 = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
- Known = Known2.reverseBits();
+ Known = Known2.reverseBits();
break;
}
case ISD::BSWAP: {
Known2 = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
- Known = Known2.byteSwap();
+ Known = Known2.byteSwap();
break;
}
case ISD::ABS: {
Known2 = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
- Known = Known2.abs();
+ Known = Known2.abs();
break;
}
case ISD::UMIN: {
Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
- Known = KnownBits::umin(Known, Known2);
+ Known = KnownBits::umin(Known, Known2);
break;
}
case ISD::UMAX: {
Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
- Known = KnownBits::umax(Known, Known2);
+ Known = KnownBits::umax(Known, Known2);
break;
}
case ISD::SMIN:
@@ -3418,10 +3418,10 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
- if (IsMax)
- Known = KnownBits::smax(Known, Known2);
- else
- Known = KnownBits::smin(Known, Known2);
+ if (IsMax)
+ Known = KnownBits::smax(Known, Known2);
+ else
+ Known = KnownBits::smin(Known, Known2);
break;
}
case ISD::FrameIndex:
@@ -4364,16 +4364,16 @@ static SDValue foldCONCAT_VECTORS(const SDLoc &DL, EVT VT,
for (SDValue Op : Elts)
SVT = (SVT.bitsLT(Op.getValueType()) ? Op.getValueType() : SVT);
- if (SVT.bitsGT(VT.getScalarType())) {
- for (SDValue &Op : Elts) {
- if (Op.isUndef())
- Op = DAG.getUNDEF(SVT);
- else
- Op = DAG.getTargetLoweringInfo().isZExtFree(Op.getValueType(), SVT)
- ? DAG.getZExtOrTrunc(Op, DL, SVT)
- : DAG.getSExtOrTrunc(Op, DL, SVT);
- }
- }
+ if (SVT.bitsGT(VT.getScalarType())) {
+ for (SDValue &Op : Elts) {
+ if (Op.isUndef())
+ Op = DAG.getUNDEF(SVT);
+ else
+ Op = DAG.getTargetLoweringInfo().isZExtFree(Op.getValueType(), SVT)
+ ? DAG.getZExtOrTrunc(Op, DL, SVT)
+ : DAG.getSExtOrTrunc(Op, DL, SVT);
+ }
+ }
SDValue V = DAG.getBuildVector(VT, DL, Elts);
NewSDValueDbgMsg(V, "New node fold concat vectors: ", &DAG);
@@ -4399,14 +4399,14 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT) {
}
SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
- SDValue Operand) {
- SDNodeFlags Flags;
- if (Inserter)
- Flags = Inserter->getFlags();
- return getNode(Opcode, DL, VT, Operand, Flags);
-}
-
-SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
+ SDValue Operand) {
+ SDNodeFlags Flags;
+ if (Inserter)
+ Flags = Inserter->getFlags();
+ return getNode(Opcode, DL, VT, Operand, Flags);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
SDValue Operand, const SDNodeFlags Flags) {
// Constant fold unary operations with an integer constant operand. Even
// opaque constant will be folded, because the folding of unary operations
@@ -4607,8 +4607,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
Operand.getValueType().isFloatingPoint() && "Invalid FP cast!");
if (Operand.getValueType() == VT) return Operand; // noop conversion.
assert((!VT.isVector() ||
- VT.getVectorElementCount() ==
- Operand.getValueType().getVectorElementCount()) &&
+ VT.getVectorElementCount() ==
+ Operand.getValueType().getVectorElementCount()) &&
"Vector element count mismatch!");
assert(Operand.getValueType().bitsLT(VT) &&
"Invalid fpext node, dst < src!");
@@ -4793,25 +4793,25 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
case ISD::VSCALE:
assert(VT == Operand.getValueType() && "Unexpected VT!");
break;
- case ISD::CTPOP:
- if (Operand.getValueType().getScalarType() == MVT::i1)
- return Operand;
- break;
- case ISD::CTLZ:
- case ISD::CTTZ:
- if (Operand.getValueType().getScalarType() == MVT::i1)
- return getNOT(DL, Operand, Operand.getValueType());
- break;
- case ISD::VECREDUCE_SMIN:
- case ISD::VECREDUCE_UMAX:
- if (Operand.getValueType().getScalarType() == MVT::i1)
- return getNode(ISD::VECREDUCE_OR, DL, VT, Operand);
- break;
- case ISD::VECREDUCE_SMAX:
- case ISD::VECREDUCE_UMIN:
- if (Operand.getValueType().getScalarType() == MVT::i1)
- return getNode(ISD::VECREDUCE_AND, DL, VT, Operand);
- break;
+ case ISD::CTPOP:
+ if (Operand.getValueType().getScalarType() == MVT::i1)
+ return Operand;
+ break;
+ case ISD::CTLZ:
+ case ISD::CTTZ:
+ if (Operand.getValueType().getScalarType() == MVT::i1)
+ return getNOT(DL, Operand, Operand.getValueType());
+ break;
+ case ISD::VECREDUCE_SMIN:
+ case ISD::VECREDUCE_UMAX:
+ if (Operand.getValueType().getScalarType() == MVT::i1)
+ return getNode(ISD::VECREDUCE_OR, DL, VT, Operand);
+ break;
+ case ISD::VECREDUCE_SMAX:
+ case ISD::VECREDUCE_UMIN:
+ if (Operand.getValueType().getScalarType() == MVT::i1)
+ return getNode(ISD::VECREDUCE_AND, DL, VT, Operand);
+ break;
}
SDNode *N;
@@ -5234,14 +5234,14 @@ SDValue SelectionDAG::getAssertAlign(const SDLoc &DL, SDValue Val, Align A) {
}
SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
- SDValue N1, SDValue N2) {
- SDNodeFlags Flags;
- if (Inserter)
- Flags = Inserter->getFlags();
- return getNode(Opcode, DL, VT, N1, N2, Flags);
-}
-
-SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
+ SDValue N1, SDValue N2) {
+ SDNodeFlags Flags;
+ if (Inserter)
+ Flags = Inserter->getFlags();
+ return getNode(Opcode, DL, VT, N1, N2, Flags);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
SDValue N1, SDValue N2, const SDNodeFlags Flags) {
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2);
@@ -5329,22 +5329,22 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
assert(N1.getValueType() == N2.getValueType() &&
N1.getValueType() == VT && "Binary operator types must match!");
break;
- case ISD::SMIN:
- case ISD::UMAX:
- assert(VT.isInteger() && "This operator does not apply to FP types!");
- assert(N1.getValueType() == N2.getValueType() &&
- N1.getValueType() == VT && "Binary operator types must match!");
- if (VT.isVector() && VT.getVectorElementType() == MVT::i1)
- return getNode(ISD::OR, DL, VT, N1, N2);
- break;
- case ISD::SMAX:
- case ISD::UMIN:
- assert(VT.isInteger() && "This operator does not apply to FP types!");
- assert(N1.getValueType() == N2.getValueType() &&
- N1.getValueType() == VT && "Binary operator types must match!");
- if (VT.isVector() && VT.getVectorElementType() == MVT::i1)
- return getNode(ISD::AND, DL, VT, N1, N2);
- break;
+ case ISD::SMIN:
+ case ISD::UMAX:
+ assert(VT.isInteger() && "This operator does not apply to FP types!");
+ assert(N1.getValueType() == N2.getValueType() &&
+ N1.getValueType() == VT && "Binary operator types must match!");
+ if (VT.isVector() && VT.getVectorElementType() == MVT::i1)
+ return getNode(ISD::OR, DL, VT, N1, N2);
+ break;
+ case ISD::SMAX:
+ case ISD::UMIN:
+ assert(VT.isInteger() && "This operator does not apply to FP types!");
+ assert(N1.getValueType() == N2.getValueType() &&
+ N1.getValueType() == VT && "Binary operator types must match!");
+ if (VT.isVector() && VT.getVectorElementType() == MVT::i1)
+ return getNode(ISD::AND, DL, VT, N1, N2);
+ break;
case ISD::FADD:
case ISD::FSUB:
case ISD::FMUL:
@@ -5386,8 +5386,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
// amounts. This catches things like trying to shift an i1024 value by an
// i8, which is easy to fall into in generic code that uses
// TLI.getShiftAmount().
- assert(N2.getValueType().getScalarSizeInBits() >=
- Log2_32_Ceil(VT.getScalarSizeInBits()) &&
+ assert(N2.getValueType().getScalarSizeInBits() >=
+ Log2_32_Ceil(VT.getScalarSizeInBits()) &&
"Invalid use of small shift amount with oversized value!");
// Always fold shifts of i1 values so the code generator doesn't need to
@@ -5583,11 +5583,11 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
(VT.getVectorMinNumElements() + N2C->getZExtValue()) <=
N1VT.getVectorMinNumElements()) &&
"Extract subvector overflow!");
- assert(N2C->getAPIntValue().getBitWidth() ==
- TLI->getVectorIdxTy(getDataLayout())
- .getSizeInBits()
- .getFixedSize() &&
- "Constant index for EXTRACT_SUBVECTOR has an invalid size");
+ assert(N2C->getAPIntValue().getBitWidth() ==
+ TLI->getVectorIdxTy(getDataLayout())
+ .getSizeInBits()
+ .getFixedSize() &&
+ "Constant index for EXTRACT_SUBVECTOR has an invalid size");
// Trivial extraction.
if (VT == N1VT)
@@ -5599,8 +5599,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
// EXTRACT_SUBVECTOR of CONCAT_VECTOR can be simplified if the pieces of
// the concat have the same type as the extract.
- if (N1.getOpcode() == ISD::CONCAT_VECTORS && N1.getNumOperands() > 0 &&
- VT == N1.getOperand(0).getValueType()) {
+ if (N1.getOpcode() == ISD::CONCAT_VECTORS && N1.getNumOperands() > 0 &&
+ VT == N1.getOperand(0).getValueType()) {
unsigned Factor = VT.getVectorMinNumElements();
return N1.getOperand(N2C->getZExtValue() / Factor);
}
@@ -5697,14 +5697,14 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
}
SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
- SDValue N1, SDValue N2, SDValue N3) {
- SDNodeFlags Flags;
- if (Inserter)
- Flags = Inserter->getFlags();
- return getNode(Opcode, DL, VT, N1, N2, N3, Flags);
-}
-
-SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
+ SDValue N1, SDValue N2, SDValue N3) {
+ SDNodeFlags Flags;
+ if (Inserter)
+ Flags = Inserter->getFlags();
+ return getNode(Opcode, DL, VT, N1, N2, N3, Flags);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
SDValue N1, SDValue N2, SDValue N3,
const SDNodeFlags Flags) {
// Perform various simplifications.
@@ -5974,20 +5974,20 @@ static SDValue getMemsetStringVal(EVT VT, const SDLoc &dl, SelectionDAG &DAG,
return SDValue(nullptr, 0);
}
-SDValue SelectionDAG::getMemBasePlusOffset(SDValue Base, TypeSize Offset,
+SDValue SelectionDAG::getMemBasePlusOffset(SDValue Base, TypeSize Offset,
const SDLoc &DL,
const SDNodeFlags Flags) {
EVT VT = Base.getValueType();
- SDValue Index;
-
- if (Offset.isScalable())
- Index = getVScale(DL, Base.getValueType(),
- APInt(Base.getValueSizeInBits().getFixedSize(),
- Offset.getKnownMinSize()));
- else
- Index = getConstant(Offset.getFixedSize(), DL, VT);
-
- return getMemBasePlusOffset(Base, Index, DL, Flags);
+ SDValue Index;
+
+ if (Offset.isScalable())
+ Index = getVScale(DL, Base.getValueType(),
+ APInt(Base.getValueSizeInBits().getFixedSize(),
+ Offset.getKnownMinSize()));
+ else
+ Index = getConstant(Offset.getFixedSize(), DL, VT);
+
+ return getMemBasePlusOffset(Base, Index, DL, Flags);
}
SDValue SelectionDAG::getMemBasePlusOffset(SDValue Ptr, SDValue Offset,
@@ -6082,8 +6082,8 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl,
SrcAlign = Alignment;
assert(SrcAlign && "SrcAlign must be set");
ConstantDataArraySlice Slice;
- // If marked as volatile, perform a copy even when marked as constant.
- bool CopyFromConstant = !isVol && isMemSrcFromConstant(Src, Slice);
+ // If marked as volatile, perform a copy even when marked as constant.
+ bool CopyFromConstant = !isVol && isMemSrcFromConstant(Src, Slice);
bool isZeroConstant = CopyFromConstant && Slice.Array == nullptr;
unsigned Limit = AlwaysInline ? ~0U : TLI.getMaxStoresPerMemcpy(OptSize);
const MemOp Op = isZeroConstant
@@ -6155,9 +6155,9 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl,
Value = getMemsetStringVal(VT, dl, DAG, TLI, SubSlice);
if (Value.getNode()) {
Store = DAG.getStore(
- Chain, dl, Value,
- DAG.getMemBasePlusOffset(Dst, TypeSize::Fixed(DstOff), dl),
- DstPtrInfo.getWithOffset(DstOff), Alignment, MMOFlags);
+ Chain, dl, Value,
+ DAG.getMemBasePlusOffset(Dst, TypeSize::Fixed(DstOff), dl),
+ DstPtrInfo.getWithOffset(DstOff), Alignment, MMOFlags);
OutChains.push_back(Store);
}
}
@@ -6177,17 +6177,17 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl,
if (isDereferenceable)
SrcMMOFlags |= MachineMemOperand::MODereferenceable;
- Value = DAG.getExtLoad(
- ISD::EXTLOAD, dl, NVT, Chain,
- DAG.getMemBasePlusOffset(Src, TypeSize::Fixed(SrcOff), dl),
- SrcPtrInfo.getWithOffset(SrcOff), VT,
- commonAlignment(*SrcAlign, SrcOff), SrcMMOFlags);
+ Value = DAG.getExtLoad(
+ ISD::EXTLOAD, dl, NVT, Chain,
+ DAG.getMemBasePlusOffset(Src, TypeSize::Fixed(SrcOff), dl),
+ SrcPtrInfo.getWithOffset(SrcOff), VT,
+ commonAlignment(*SrcAlign, SrcOff), SrcMMOFlags);
OutLoadChains.push_back(Value.getValue(1));
Store = DAG.getTruncStore(
- Chain, dl, Value,
- DAG.getMemBasePlusOffset(Dst, TypeSize::Fixed(DstOff), dl),
- DstPtrInfo.getWithOffset(DstOff), VT, Alignment, MMOFlags);
+ Chain, dl, Value,
+ DAG.getMemBasePlusOffset(Dst, TypeSize::Fixed(DstOff), dl),
+ DstPtrInfo.getWithOffset(DstOff), VT, Alignment, MMOFlags);
OutStoreChains.push_back(Store);
}
SrcOff += VTSize;
@@ -6307,10 +6307,10 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl,
if (isDereferenceable)
SrcMMOFlags |= MachineMemOperand::MODereferenceable;
- Value =
- DAG.getLoad(VT, dl, Chain,
- DAG.getMemBasePlusOffset(Src, TypeSize::Fixed(SrcOff), dl),
- SrcPtrInfo.getWithOffset(SrcOff), *SrcAlign, SrcMMOFlags);
+ Value =
+ DAG.getLoad(VT, dl, Chain,
+ DAG.getMemBasePlusOffset(Src, TypeSize::Fixed(SrcOff), dl),
+ SrcPtrInfo.getWithOffset(SrcOff), *SrcAlign, SrcMMOFlags);
LoadValues.push_back(Value);
LoadChains.push_back(Value.getValue(1));
SrcOff += VTSize;
@@ -6322,10 +6322,10 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl,
unsigned VTSize = VT.getSizeInBits() / 8;
SDValue Store;
- Store =
- DAG.getStore(Chain, dl, LoadValues[i],
- DAG.getMemBasePlusOffset(Dst, TypeSize::Fixed(DstOff), dl),
- DstPtrInfo.getWithOffset(DstOff), Alignment, MMOFlags);
+ Store =
+ DAG.getStore(Chain, dl, LoadValues[i],
+ DAG.getMemBasePlusOffset(Dst, TypeSize::Fixed(DstOff), dl),
+ DstPtrInfo.getWithOffset(DstOff), Alignment, MMOFlags);
OutChains.push_back(Store);
DstOff += VTSize;
}
@@ -6423,9 +6423,9 @@ static SDValue getMemsetStores(SelectionDAG &DAG, const SDLoc &dl,
}
assert(Value.getValueType() == VT && "Value with wrong type.");
SDValue Store = DAG.getStore(
- Chain, dl, Value,
- DAG.getMemBasePlusOffset(Dst, TypeSize::Fixed(DstOff), dl),
- DstPtrInfo.getWithOffset(DstOff), Alignment,
+ Chain, dl, Value,
+ DAG.getMemBasePlusOffset(Dst, TypeSize::Fixed(DstOff), dl),
+ DstPtrInfo.getWithOffset(DstOff), Alignment,
isVol ? MachineMemOperand::MOVolatile : MachineMemOperand::MONone);
OutChains.push_back(Store);
DstOff += VT.getSizeInBits() / 8;
@@ -6439,7 +6439,7 @@ static void checkAddrSpaceIsValidForLibcall(const TargetLowering *TLI,
unsigned AS) {
// Lowering memcpy / memset / memmove intrinsics to calls is only valid if all
// pointer operands can be losslessly bitcasted to pointers of address space 0
- if (AS != 0 && !TLI->getTargetMachine().isNoopAddrSpaceCast(AS, 0)) {
+ if (AS != 0 && !TLI->getTargetMachine().isNoopAddrSpaceCast(AS, 0)) {
report_fatal_error("cannot lower memory intrinsic in address space " +
Twine(AS));
}
@@ -6931,30 +6931,30 @@ SDValue SelectionDAG::getLifetimeNode(bool IsStart, const SDLoc &dl,
return V;
}
-SDValue SelectionDAG::getPseudoProbeNode(const SDLoc &Dl, SDValue Chain,
- uint64_t Guid, uint64_t Index,
- uint32_t Attr) {
- const unsigned Opcode = ISD::PSEUDO_PROBE;
- const auto VTs = getVTList(MVT::Other);
- SDValue Ops[] = {Chain};
- FoldingSetNodeID ID;
- AddNodeIDNode(ID, Opcode, VTs, Ops);
- ID.AddInteger(Guid);
- ID.AddInteger(Index);
- void *IP = nullptr;
- if (SDNode *E = FindNodeOrInsertPos(ID, Dl, IP))
- return SDValue(E, 0);
-
- auto *N = newSDNode<PseudoProbeSDNode>(
- Opcode, Dl.getIROrder(), Dl.getDebugLoc(), VTs, Guid, Index, Attr);
- createOperands(N, Ops);
- CSEMap.InsertNode(N, IP);
- InsertNode(N);
- SDValue V(N, 0);
- NewSDValueDbgMsg(V, "Creating new node: ", this);
- return V;
-}
-
+SDValue SelectionDAG::getPseudoProbeNode(const SDLoc &Dl, SDValue Chain,
+ uint64_t Guid, uint64_t Index,
+ uint32_t Attr) {
+ const unsigned Opcode = ISD::PSEUDO_PROBE;
+ const auto VTs = getVTList(MVT::Other);
+ SDValue Ops[] = {Chain};
+ FoldingSetNodeID ID;
+ AddNodeIDNode(ID, Opcode, VTs, Ops);
+ ID.AddInteger(Guid);
+ ID.AddInteger(Index);
+ void *IP = nullptr;
+ if (SDNode *E = FindNodeOrInsertPos(ID, Dl, IP))
+ return SDValue(E, 0);
+
+ auto *N = newSDNode<PseudoProbeSDNode>(
+ Opcode, Dl.getIROrder(), Dl.getDebugLoc(), VTs, Guid, Index, Attr);
+ createOperands(N, Ops);
+ CSEMap.InsertNode(N, IP);
+ InsertNode(N);
+ SDValue V(N, 0);
+ NewSDValueDbgMsg(V, "Creating new node: ", this);
+ return V;
+}
+
/// InferPointerInfo - If the specified ptr/offset is a frame index, infer a
/// MachinePointerInfo record from it. This is particularly useful because the
/// code generator has many cases where it doesn't bother passing in a
@@ -7035,7 +7035,7 @@ SDValue SelectionDAG::getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
assert(VT.isVector() == MemVT.isVector() &&
"Cannot use an ext load to convert to or from a vector!");
assert((!VT.isVector() ||
- VT.getVectorElementCount() == MemVT.getVectorElementCount()) &&
+ VT.getVectorElementCount() == MemVT.getVectorElementCount()) &&
"Cannot use an ext load to change the number of vector elements!");
}
@@ -7114,7 +7114,7 @@ SDValue SelectionDAG::getIndexedLoad(SDValue OrigLoad, const SDLoc &dl,
~(MachineMemOperand::MOInvariant | MachineMemOperand::MODereferenceable);
return getLoad(AM, LD->getExtensionType(), OrigLoad.getValueType(), dl,
LD->getChain(), Base, Offset, LD->getPointerInfo(),
- LD->getMemoryVT(), LD->getAlign(), MMOFlags, LD->getAAInfo());
+ LD->getMemoryVT(), LD->getAlign(), MMOFlags, LD->getAAInfo());
}
SDValue SelectionDAG::getStore(SDValue Chain, const SDLoc &dl, SDValue Val,
@@ -7184,8 +7184,8 @@ SDValue SelectionDAG::getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val,
MachineFunction &MF = getMachineFunction();
MachineMemOperand *MMO = MF.getMachineMemOperand(
- PtrInfo, MMOFlags, MemoryLocation::getSizeOrUnknown(SVT.getStoreSize()),
- Alignment, AAInfo);
+ PtrInfo, MMOFlags, MemoryLocation::getSizeOrUnknown(SVT.getStoreSize()),
+ Alignment, AAInfo);
return getTruncStore(Chain, dl, Val, Ptr, SVT, MMO);
}
@@ -7206,7 +7206,7 @@ SDValue SelectionDAG::getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val,
assert(VT.isVector() == SVT.isVector() &&
"Cannot use trunc store to convert to or from a vector!");
assert((!VT.isVector() ||
- VT.getVectorElementCount() == SVT.getVectorElementCount()) &&
+ VT.getVectorElementCount() == SVT.getVectorElementCount()) &&
"Cannot use trunc store to change the number of vector elements!");
SDVTList VTs = getVTList(MVT::Other);
@@ -7358,15 +7358,15 @@ SDValue SelectionDAG::getIndexedMaskedStore(SDValue OrigStore, const SDLoc &dl,
SDValue SelectionDAG::getMaskedGather(SDVTList VTs, EVT VT, const SDLoc &dl,
ArrayRef<SDValue> Ops,
MachineMemOperand *MMO,
- ISD::MemIndexType IndexType,
- ISD::LoadExtType ExtTy) {
+ ISD::MemIndexType IndexType,
+ ISD::LoadExtType ExtTy) {
assert(Ops.size() == 6 && "Incompatible number of operands");
FoldingSetNodeID ID;
AddNodeIDNode(ID, ISD::MGATHER, VTs, Ops);
ID.AddInteger(VT.getRawBits());
ID.AddInteger(getSyntheticNodeSubclassData<MaskedGatherSDNode>(
- dl.getIROrder(), VTs, VT, MMO, IndexType, ExtTy));
+ dl.getIROrder(), VTs, VT, MMO, IndexType, ExtTy));
ID.AddInteger(MMO->getPointerInfo().getAddrSpace());
void *IP = nullptr;
if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) {
@@ -7374,22 +7374,22 @@ SDValue SelectionDAG::getMaskedGather(SDVTList VTs, EVT VT, const SDLoc &dl,
return SDValue(E, 0);
}
- IndexType = TLI->getCanonicalIndexType(IndexType, VT, Ops[4]);
+ IndexType = TLI->getCanonicalIndexType(IndexType, VT, Ops[4]);
auto *N = newSDNode<MaskedGatherSDNode>(dl.getIROrder(), dl.getDebugLoc(),
- VTs, VT, MMO, IndexType, ExtTy);
+ VTs, VT, MMO, IndexType, ExtTy);
createOperands(N, Ops);
assert(N->getPassThru().getValueType() == N->getValueType(0) &&
"Incompatible type of the PassThru value in MaskedGatherSDNode");
- assert(N->getMask().getValueType().getVectorElementCount() ==
- N->getValueType(0).getVectorElementCount() &&
+ assert(N->getMask().getValueType().getVectorElementCount() ==
+ N->getValueType(0).getVectorElementCount() &&
"Vector width mismatch between mask and data");
- assert(N->getIndex().getValueType().getVectorElementCount().isScalable() ==
- N->getValueType(0).getVectorElementCount().isScalable() &&
- "Scalable flags of index and data do not match");
- assert(ElementCount::isKnownGE(
- N->getIndex().getValueType().getVectorElementCount(),
- N->getValueType(0).getVectorElementCount()) &&
+ assert(N->getIndex().getValueType().getVectorElementCount().isScalable() ==
+ N->getValueType(0).getVectorElementCount().isScalable() &&
+ "Scalable flags of index and data do not match");
+ assert(ElementCount::isKnownGE(
+ N->getIndex().getValueType().getVectorElementCount(),
+ N->getValueType(0).getVectorElementCount()) &&
"Vector width mismatch between index and data");
assert(isa<ConstantSDNode>(N->getScale()) &&
cast<ConstantSDNode>(N->getScale())->getAPIntValue().isPowerOf2() &&
@@ -7405,37 +7405,37 @@ SDValue SelectionDAG::getMaskedGather(SDVTList VTs, EVT VT, const SDLoc &dl,
SDValue SelectionDAG::getMaskedScatter(SDVTList VTs, EVT VT, const SDLoc &dl,
ArrayRef<SDValue> Ops,
MachineMemOperand *MMO,
- ISD::MemIndexType IndexType,
- bool IsTrunc) {
+ ISD::MemIndexType IndexType,
+ bool IsTrunc) {
assert(Ops.size() == 6 && "Incompatible number of operands");
FoldingSetNodeID ID;
AddNodeIDNode(ID, ISD::MSCATTER, VTs, Ops);
ID.AddInteger(VT.getRawBits());
ID.AddInteger(getSyntheticNodeSubclassData<MaskedScatterSDNode>(
- dl.getIROrder(), VTs, VT, MMO, IndexType, IsTrunc));
+ dl.getIROrder(), VTs, VT, MMO, IndexType, IsTrunc));
ID.AddInteger(MMO->getPointerInfo().getAddrSpace());
void *IP = nullptr;
if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) {
cast<MaskedScatterSDNode>(E)->refineAlignment(MMO);
return SDValue(E, 0);
}
-
- IndexType = TLI->getCanonicalIndexType(IndexType, VT, Ops[4]);
+
+ IndexType = TLI->getCanonicalIndexType(IndexType, VT, Ops[4]);
auto *N = newSDNode<MaskedScatterSDNode>(dl.getIROrder(), dl.getDebugLoc(),
- VTs, VT, MMO, IndexType, IsTrunc);
+ VTs, VT, MMO, IndexType, IsTrunc);
createOperands(N, Ops);
- assert(N->getMask().getValueType().getVectorElementCount() ==
- N->getValue().getValueType().getVectorElementCount() &&
+ assert(N->getMask().getValueType().getVectorElementCount() ==
+ N->getValue().getValueType().getVectorElementCount() &&
"Vector width mismatch between mask and data");
- assert(
- N->getIndex().getValueType().getVectorElementCount().isScalable() ==
- N->getValue().getValueType().getVectorElementCount().isScalable() &&
- "Scalable flags of index and data do not match");
- assert(ElementCount::isKnownGE(
- N->getIndex().getValueType().getVectorElementCount(),
- N->getValue().getValueType().getVectorElementCount()) &&
+ assert(
+ N->getIndex().getValueType().getVectorElementCount().isScalable() ==
+ N->getValue().getValueType().getVectorElementCount().isScalable() &&
+ "Scalable flags of index and data do not match");
+ assert(ElementCount::isKnownGE(
+ N->getIndex().getValueType().getVectorElementCount(),
+ N->getValue().getValueType().getVectorElementCount()) &&
"Vector width mismatch between index and data");
assert(isa<ConstantSDNode>(N->getScale()) &&
cast<ConstantSDNode>(N->getScale())->getAPIntValue().isPowerOf2() &&
@@ -7539,11 +7539,11 @@ SDValue SelectionDAG::simplifyFPBinop(unsigned Opcode, SDValue X, SDValue Y,
if (YC->getValueAPF().isExactlyValue(1.0))
return X;
- // X * 0.0 --> 0.0
- if (Opcode == ISD::FMUL && Flags.hasNoNaNs() && Flags.hasNoSignedZeros())
- if (YC->getValueAPF().isZero())
- return getConstantFP(0.0, SDLoc(Y), Y.getValueType());
-
+ // X * 0.0 --> 0.0
+ if (Opcode == ISD::FMUL && Flags.hasNoNaNs() && Flags.hasNoSignedZeros())
+ if (YC->getValueAPF().isZero())
+ return getConstantFP(0.0, SDLoc(Y), Y.getValueType());
+
return SDValue();
}
@@ -7570,14 +7570,14 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
}
SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
- ArrayRef<SDValue> Ops) {
- SDNodeFlags Flags;
- if (Inserter)
- Flags = Inserter->getFlags();
- return getNode(Opcode, DL, VT, Ops, Flags);
-}
-
-SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
+ ArrayRef<SDValue> Ops) {
+ SDNodeFlags Flags;
+ if (Inserter)
+ Flags = Inserter->getFlags();
+ return getNode(Opcode, DL, VT, Ops, Flags);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
ArrayRef<SDValue> Ops, const SDNodeFlags Flags) {
unsigned NumOps = Ops.size();
switch (NumOps) {
@@ -7649,14 +7649,14 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL,
}
SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
- ArrayRef<SDValue> Ops) {
- SDNodeFlags Flags;
- if (Inserter)
- Flags = Inserter->getFlags();
- return getNode(Opcode, DL, VTList, Ops, Flags);
-}
-
-SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
+ ArrayRef<SDValue> Ops) {
+ SDNodeFlags Flags;
+ if (Inserter)
+ Flags = Inserter->getFlags();
+ return getNode(Opcode, DL, VTList, Ops, Flags);
+}
+
+SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
ArrayRef<SDValue> Ops, const SDNodeFlags Flags) {
if (VTList.NumVTs == 1)
return getNode(Opcode, DL, VTList.VTs[0], Ops);
@@ -8353,14 +8353,14 @@ SDValue SelectionDAG::getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT,
/// getNodeIfExists - Get the specified node if it's already available, or
/// else return NULL.
SDNode *SelectionDAG::getNodeIfExists(unsigned Opcode, SDVTList VTList,
- ArrayRef<SDValue> Ops) {
- SDNodeFlags Flags;
- if (Inserter)
- Flags = Inserter->getFlags();
- return getNodeIfExists(Opcode, VTList, Ops, Flags);
-}
-
-SDNode *SelectionDAG::getNodeIfExists(unsigned Opcode, SDVTList VTList,
+ ArrayRef<SDValue> Ops) {
+ SDNodeFlags Flags;
+ if (Inserter)
+ Flags = Inserter->getFlags();
+ return getNodeIfExists(Opcode, VTList, Ops, Flags);
+}
+
+SDNode *SelectionDAG::getNodeIfExists(unsigned Opcode, SDVTList VTList,
ArrayRef<SDValue> Ops,
const SDNodeFlags Flags) {
if (VTList.VTs[VTList.NumVTs - 1] != MVT::Glue) {
@@ -8375,19 +8375,19 @@ SDNode *SelectionDAG::getNodeIfExists(unsigned Opcode, SDVTList VTList,
return nullptr;
}
-/// doesNodeExist - Check if a node exists without modifying its flags.
-bool SelectionDAG::doesNodeExist(unsigned Opcode, SDVTList VTList,
- ArrayRef<SDValue> Ops) {
- if (VTList.VTs[VTList.NumVTs - 1] != MVT::Glue) {
- FoldingSetNodeID ID;
- AddNodeIDNode(ID, Opcode, VTList, Ops);
- void *IP = nullptr;
- if (FindNodeOrInsertPos(ID, SDLoc(), IP))
- return true;
- }
- return false;
-}
-
+/// doesNodeExist - Check if a node exists without modifying its flags.
+bool SelectionDAG::doesNodeExist(unsigned Opcode, SDVTList VTList,
+ ArrayRef<SDValue> Ops) {
+ if (VTList.VTs[VTList.NumVTs - 1] != MVT::Glue) {
+ FoldingSetNodeID ID;
+ AddNodeIDNode(ID, Opcode, VTList, Ops);
+ void *IP = nullptr;
+ if (FindNodeOrInsertPos(ID, SDLoc(), IP))
+ return true;
+ }
+ return false;
+}
+
/// getDbgValue - Creates a SDDbgValue node.
///
/// SDNode
@@ -8805,31 +8805,31 @@ namespace {
} // end anonymous namespace
-bool SelectionDAG::calculateDivergence(SDNode *N) {
- if (TLI->isSDNodeAlwaysUniform(N)) {
- assert(!TLI->isSDNodeSourceOfDivergence(N, FLI, DA) &&
- "Conflicting divergence information!");
- return false;
- }
- if (TLI->isSDNodeSourceOfDivergence(N, FLI, DA))
- return true;
+bool SelectionDAG::calculateDivergence(SDNode *N) {
+ if (TLI->isSDNodeAlwaysUniform(N)) {
+ assert(!TLI->isSDNodeSourceOfDivergence(N, FLI, DA) &&
+ "Conflicting divergence information!");
+ return false;
+ }
+ if (TLI->isSDNodeSourceOfDivergence(N, FLI, DA))
+ return true;
for (auto &Op : N->ops()) {
- if (Op.Val.getValueType() != MVT::Other && Op.getNode()->isDivergent())
- return true;
+ if (Op.Val.getValueType() != MVT::Other && Op.getNode()->isDivergent())
+ return true;
}
- return false;
-}
-
-void SelectionDAG::updateDivergence(SDNode *N) {
- SmallVector<SDNode *, 16> Worklist(1, N);
- do {
- N = Worklist.pop_back_val();
- bool IsDivergent = calculateDivergence(N);
- if (N->SDNodeBits.IsDivergent != IsDivergent) {
- N->SDNodeBits.IsDivergent = IsDivergent;
- llvm::append_range(Worklist, N->uses());
+ return false;
+}
+
+void SelectionDAG::updateDivergence(SDNode *N) {
+ SmallVector<SDNode *, 16> Worklist(1, N);
+ do {
+ N = Worklist.pop_back_val();
+ bool IsDivergent = calculateDivergence(N);
+ if (N->SDNodeBits.IsDivergent != IsDivergent) {
+ N->SDNodeBits.IsDivergent = IsDivergent;
+ llvm::append_range(Worklist, N->uses());
}
- } while (!Worklist.empty());
+ } while (!Worklist.empty());
}
void SelectionDAG::CreateTopologicalOrder(std::vector<SDNode *> &Order) {
@@ -8855,9 +8855,9 @@ void SelectionDAG::CreateTopologicalOrder(std::vector<SDNode *> &Order) {
void SelectionDAG::VerifyDAGDiverence() {
std::vector<SDNode *> TopoOrder;
CreateTopologicalOrder(TopoOrder);
- for (auto *N : TopoOrder) {
- assert(calculateDivergence(N) == N->isDivergent() &&
- "Divergence bit inconsistency detected");
+ for (auto *N : TopoOrder) {
+ assert(calculateDivergence(N) == N->isDivergent() &&
+ "Divergence bit inconsistency detected");
}
}
#endif
@@ -9026,32 +9026,32 @@ void SelectionDAG::AddDbgLabel(SDDbgLabel *DB) {
DbgInfo->add(DB);
}
-SDValue SelectionDAG::makeEquivalentMemoryOrdering(SDValue OldChain,
- SDValue NewMemOpChain) {
- assert(isa<MemSDNode>(NewMemOpChain) && "Expected a memop node");
- assert(NewMemOpChain.getValueType() == MVT::Other && "Expected a token VT");
+SDValue SelectionDAG::makeEquivalentMemoryOrdering(SDValue OldChain,
+ SDValue NewMemOpChain) {
+ assert(isa<MemSDNode>(NewMemOpChain) && "Expected a memop node");
+ assert(NewMemOpChain.getValueType() == MVT::Other && "Expected a token VT");
// The new memory operation must have the same position as the old load in
// terms of memory dependency. Create a TokenFactor for the old load and new
// memory operation and update uses of the old load's output chain to use that
// TokenFactor.
- if (OldChain == NewMemOpChain || OldChain.use_empty())
- return NewMemOpChain;
+ if (OldChain == NewMemOpChain || OldChain.use_empty())
+ return NewMemOpChain;
- SDValue TokenFactor = getNode(ISD::TokenFactor, SDLoc(OldChain), MVT::Other,
- OldChain, NewMemOpChain);
+ SDValue TokenFactor = getNode(ISD::TokenFactor, SDLoc(OldChain), MVT::Other,
+ OldChain, NewMemOpChain);
ReplaceAllUsesOfValueWith(OldChain, TokenFactor);
- UpdateNodeOperands(TokenFactor.getNode(), OldChain, NewMemOpChain);
+ UpdateNodeOperands(TokenFactor.getNode(), OldChain, NewMemOpChain);
return TokenFactor;
}
-SDValue SelectionDAG::makeEquivalentMemoryOrdering(LoadSDNode *OldLoad,
- SDValue NewMemOp) {
- assert(isa<MemSDNode>(NewMemOp.getNode()) && "Expected a memop node");
- SDValue OldChain = SDValue(OldLoad, 1);
- SDValue NewMemOpChain = NewMemOp.getValue(1);
- return makeEquivalentMemoryOrdering(OldChain, NewMemOpChain);
-}
-
+SDValue SelectionDAG::makeEquivalentMemoryOrdering(LoadSDNode *OldLoad,
+ SDValue NewMemOp) {
+ assert(isa<MemSDNode>(NewMemOp.getNode()) && "Expected a memop node");
+ SDValue OldChain = SDValue(OldLoad, 1);
+ SDValue NewMemOpChain = NewMemOp.getValue(1);
+ return makeEquivalentMemoryOrdering(OldChain, NewMemOpChain);
+}
+
SDValue SelectionDAG::getSymbolFunctionGlobalAddress(SDValue Op,
Function **OutFunction) {
assert(isa<ExternalSymbolSDNode>(Op) && "Node should be an ExternalSymbol");
@@ -9135,18 +9135,18 @@ ConstantSDNode *llvm::isConstOrConstSplat(SDValue N, bool AllowUndefs,
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N))
return CN;
- // SplatVectors can truncate their operands. Ignore that case here unless
- // AllowTruncation is set.
- if (N->getOpcode() == ISD::SPLAT_VECTOR) {
- EVT VecEltVT = N->getValueType(0).getVectorElementType();
- if (auto *CN = dyn_cast<ConstantSDNode>(N->getOperand(0))) {
- EVT CVT = CN->getValueType(0);
- assert(CVT.bitsGE(VecEltVT) && "Illegal splat_vector element extension");
- if (AllowTruncation || CVT == VecEltVT)
- return CN;
- }
- }
-
+ // SplatVectors can truncate their operands. Ignore that case here unless
+ // AllowTruncation is set.
+ if (N->getOpcode() == ISD::SPLAT_VECTOR) {
+ EVT VecEltVT = N->getValueType(0).getVectorElementType();
+ if (auto *CN = dyn_cast<ConstantSDNode>(N->getOperand(0))) {
+ EVT CVT = CN->getValueType(0);
+ assert(CVT.bitsGE(VecEltVT) && "Illegal splat_vector element extension");
+ if (AllowTruncation || CVT == VecEltVT)
+ return CN;
+ }
+ }
+
if (BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N)) {
BitVector UndefElements;
ConstantSDNode *CN = BV->getConstantSplatNode(&UndefElements);
@@ -9200,10 +9200,10 @@ ConstantFPSDNode *llvm::isConstOrConstSplatFP(SDValue N, bool AllowUndefs) {
return CN;
}
- if (N.getOpcode() == ISD::SPLAT_VECTOR)
- if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N.getOperand(0)))
- return CN;
-
+ if (N.getOpcode() == ISD::SPLAT_VECTOR)
+ if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N.getOperand(0)))
+ return CN;
+
return nullptr;
}
@@ -9365,7 +9365,7 @@ bool SDNode::areOnlyUsersOf(ArrayRef<const SDNode *> Nodes, const SDNode *N) {
bool Seen = false;
for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
SDNode *User = *I;
- if (llvm::is_contained(Nodes, User))
+ if (llvm::is_contained(Nodes, User))
Seen = true;
else
return false;
@@ -9376,7 +9376,7 @@ bool SDNode::areOnlyUsersOf(ArrayRef<const SDNode *> Nodes, const SDNode *N) {
/// isOperand - Return true if this node is an operand of N.
bool SDValue::isOperandOf(const SDNode *N) const {
- return is_contained(N->op_values(), *this);
+ return is_contained(N->op_values(), *this);
}
bool SDNode::isOperandOf(const SDNode *N) const {
@@ -9765,19 +9765,19 @@ SelectionDAG::GetDependentSplitDestVTs(const EVT &VT, const EVT &EnvVT,
// custom VL=9 with enveloping VL=8/8 yields 8/1
// custom VL=10 with enveloping VL=8/8 yields 8/2
// etc.
- ElementCount VTNumElts = VT.getVectorElementCount();
- ElementCount EnvNumElts = EnvVT.getVectorElementCount();
- assert(VTNumElts.isScalable() == EnvNumElts.isScalable() &&
- "Mixing fixed width and scalable vectors when enveloping a type");
+ ElementCount VTNumElts = VT.getVectorElementCount();
+ ElementCount EnvNumElts = EnvVT.getVectorElementCount();
+ assert(VTNumElts.isScalable() == EnvNumElts.isScalable() &&
+ "Mixing fixed width and scalable vectors when enveloping a type");
EVT LoVT, HiVT;
- if (VTNumElts.getKnownMinValue() > EnvNumElts.getKnownMinValue()) {
+ if (VTNumElts.getKnownMinValue() > EnvNumElts.getKnownMinValue()) {
LoVT = EnvVT;
- HiVT = EVT::getVectorVT(*getContext(), EltTp, VTNumElts - EnvNumElts);
+ HiVT = EVT::getVectorVT(*getContext(), EltTp, VTNumElts - EnvNumElts);
*HiIsEmpty = false;
} else {
// Flag that hi type has zero storage size, but return split envelop type
// (this would be easier if vector types with zero elements were allowed).
- LoVT = EVT::getVectorVT(*getContext(), EltTp, VTNumElts);
+ LoVT = EVT::getVectorVT(*getContext(), EltTp, VTNumElts);
HiVT = EnvVT;
*HiIsEmpty = true;
}
@@ -9912,16 +9912,16 @@ bool BuildVectorSDNode::isConstantSplat(APInt &SplatValue, APInt &SplatUndef,
SDValue BuildVectorSDNode::getSplatValue(const APInt &DemandedElts,
BitVector *UndefElements) const {
- unsigned NumOps = getNumOperands();
+ unsigned NumOps = getNumOperands();
if (UndefElements) {
UndefElements->clear();
- UndefElements->resize(NumOps);
+ UndefElements->resize(NumOps);
}
- assert(NumOps == DemandedElts.getBitWidth() && "Unexpected vector size");
+ assert(NumOps == DemandedElts.getBitWidth() && "Unexpected vector size");
if (!DemandedElts)
return SDValue();
SDValue Splatted;
- for (unsigned i = 0; i != NumOps; ++i) {
+ for (unsigned i = 0; i != NumOps; ++i) {
if (!DemandedElts[i])
continue;
SDValue Op = getOperand(i);
@@ -9950,58 +9950,58 @@ SDValue BuildVectorSDNode::getSplatValue(BitVector *UndefElements) const {
return getSplatValue(DemandedElts, UndefElements);
}
-bool BuildVectorSDNode::getRepeatedSequence(const APInt &DemandedElts,
- SmallVectorImpl<SDValue> &Sequence,
- BitVector *UndefElements) const {
- unsigned NumOps = getNumOperands();
- Sequence.clear();
- if (UndefElements) {
- UndefElements->clear();
- UndefElements->resize(NumOps);
- }
- assert(NumOps == DemandedElts.getBitWidth() && "Unexpected vector size");
- if (!DemandedElts || NumOps < 2 || !isPowerOf2_32(NumOps))
- return false;
-
- // Set the undefs even if we don't find a sequence (like getSplatValue).
- if (UndefElements)
- for (unsigned I = 0; I != NumOps; ++I)
- if (DemandedElts[I] && getOperand(I).isUndef())
- (*UndefElements)[I] = true;
-
- // Iteratively widen the sequence length looking for repetitions.
- for (unsigned SeqLen = 1; SeqLen < NumOps; SeqLen *= 2) {
- Sequence.append(SeqLen, SDValue());
- for (unsigned I = 0; I != NumOps; ++I) {
- if (!DemandedElts[I])
- continue;
- SDValue &SeqOp = Sequence[I % SeqLen];
- SDValue Op = getOperand(I);
- if (Op.isUndef()) {
- if (!SeqOp)
- SeqOp = Op;
- continue;
- }
- if (SeqOp && !SeqOp.isUndef() && SeqOp != Op) {
- Sequence.clear();
- break;
- }
- SeqOp = Op;
- }
- if (!Sequence.empty())
- return true;
- }
-
- assert(Sequence.empty() && "Failed to empty non-repeating sequence pattern");
- return false;
-}
-
-bool BuildVectorSDNode::getRepeatedSequence(SmallVectorImpl<SDValue> &Sequence,
- BitVector *UndefElements) const {
- APInt DemandedElts = APInt::getAllOnesValue(getNumOperands());
- return getRepeatedSequence(DemandedElts, Sequence, UndefElements);
-}
-
+bool BuildVectorSDNode::getRepeatedSequence(const APInt &DemandedElts,
+ SmallVectorImpl<SDValue> &Sequence,
+ BitVector *UndefElements) const {
+ unsigned NumOps = getNumOperands();
+ Sequence.clear();
+ if (UndefElements) {
+ UndefElements->clear();
+ UndefElements->resize(NumOps);
+ }
+ assert(NumOps == DemandedElts.getBitWidth() && "Unexpected vector size");
+ if (!DemandedElts || NumOps < 2 || !isPowerOf2_32(NumOps))
+ return false;
+
+ // Set the undefs even if we don't find a sequence (like getSplatValue).
+ if (UndefElements)
+ for (unsigned I = 0; I != NumOps; ++I)
+ if (DemandedElts[I] && getOperand(I).isUndef())
+ (*UndefElements)[I] = true;
+
+ // Iteratively widen the sequence length looking for repetitions.
+ for (unsigned SeqLen = 1; SeqLen < NumOps; SeqLen *= 2) {
+ Sequence.append(SeqLen, SDValue());
+ for (unsigned I = 0; I != NumOps; ++I) {
+ if (!DemandedElts[I])
+ continue;
+ SDValue &SeqOp = Sequence[I % SeqLen];
+ SDValue Op = getOperand(I);
+ if (Op.isUndef()) {
+ if (!SeqOp)
+ SeqOp = Op;
+ continue;
+ }
+ if (SeqOp && !SeqOp.isUndef() && SeqOp != Op) {
+ Sequence.clear();
+ break;
+ }
+ SeqOp = Op;
+ }
+ if (!Sequence.empty())
+ return true;
+ }
+
+ assert(Sequence.empty() && "Failed to empty non-repeating sequence pattern");
+ return false;
+}
+
+bool BuildVectorSDNode::getRepeatedSequence(SmallVectorImpl<SDValue> &Sequence,
+ BitVector *UndefElements) const {
+ APInt DemandedElts = APInt::getAllOnesValue(getNumOperands());
+ return getRepeatedSequence(DemandedElts, Sequence, UndefElements);
+}
+
ConstantSDNode *
BuildVectorSDNode::getConstantSplatNode(const APInt &DemandedElts,
BitVector *UndefElements) const {
@@ -10074,7 +10074,7 @@ bool ShuffleVectorSDNode::isSplatMask(const int *Mask, EVT VT) {
// Returns the SDNode if it is a constant integer BuildVector
// or constant integer.
-SDNode *SelectionDAG::isConstantIntBuildVectorOrConstantInt(SDValue N) const {
+SDNode *SelectionDAG::isConstantIntBuildVectorOrConstantInt(SDValue N) const {
if (isa<ConstantSDNode>(N))
return N.getNode();
if (ISD::isBuildVectorOfConstantSDNodes(N.getNode()))
@@ -10085,15 +10085,15 @@ SDNode *SelectionDAG::isConstantIntBuildVectorOrConstantInt(SDValue N) const {
if (GA->getOpcode() == ISD::GlobalAddress &&
TLI->isOffsetFoldingLegal(GA))
return GA;
- if ((N.getOpcode() == ISD::SPLAT_VECTOR) &&
- isa<ConstantSDNode>(N.getOperand(0)))
- return N.getNode();
+ if ((N.getOpcode() == ISD::SPLAT_VECTOR) &&
+ isa<ConstantSDNode>(N.getOperand(0)))
+ return N.getNode();
return nullptr;
}
-// Returns the SDNode if it is a constant float BuildVector
-// or constant float.
-SDNode *SelectionDAG::isConstantFPBuildVectorOrConstantFP(SDValue N) const {
+// Returns the SDNode if it is a constant float BuildVector
+// or constant float.
+SDNode *SelectionDAG::isConstantFPBuildVectorOrConstantFP(SDValue N) const {
if (isa<ConstantFPSDNode>(N))
return N.getNode();
@@ -10115,14 +10115,14 @@ void SelectionDAG::createOperands(SDNode *Node, ArrayRef<SDValue> Vals) {
Ops[I].setUser(Node);
Ops[I].setInitial(Vals[I]);
if (Ops[I].Val.getValueType() != MVT::Other) // Skip Chain. It does not carry divergence.
- IsDivergent |= Ops[I].getNode()->isDivergent();
+ IsDivergent |= Ops[I].getNode()->isDivergent();
}
Node->NumOperands = Vals.size();
Node->OperandList = Ops;
- if (!TLI->isSDNodeAlwaysUniform(Node)) {
- IsDivergent |= TLI->isSDNodeSourceOfDivergence(Node, FLI, DA);
+ if (!TLI->isSDNodeAlwaysUniform(Node)) {
+ IsDivergent |= TLI->isSDNodeSourceOfDivergence(Node, FLI, DA);
Node->SDNodeBits.IsDivergent = IsDivergent;
- }
+ }
checkForCycles(Node);
}
@@ -10139,44 +10139,44 @@ SDValue SelectionDAG::getTokenFactor(const SDLoc &DL,
return getNode(ISD::TokenFactor, DL, MVT::Other, Vals);
}
-SDValue SelectionDAG::getNeutralElement(unsigned Opcode, const SDLoc &DL,
- EVT VT, SDNodeFlags Flags) {
- switch (Opcode) {
- default:
- return SDValue();
- case ISD::ADD:
- case ISD::OR:
- case ISD::XOR:
- case ISD::UMAX:
- return getConstant(0, DL, VT);
- case ISD::MUL:
- return getConstant(1, DL, VT);
- case ISD::AND:
- case ISD::UMIN:
- return getAllOnesConstant(DL, VT);
- case ISD::SMAX:
- return getConstant(APInt::getSignedMinValue(VT.getSizeInBits()), DL, VT);
- case ISD::SMIN:
- return getConstant(APInt::getSignedMaxValue(VT.getSizeInBits()), DL, VT);
- case ISD::FADD:
- return getConstantFP(-0.0, DL, VT);
- case ISD::FMUL:
- return getConstantFP(1.0, DL, VT);
- case ISD::FMINNUM:
- case ISD::FMAXNUM: {
- // Neutral element for fminnum is NaN, Inf or FLT_MAX, depending on FMF.
- const fltSemantics &Semantics = EVTToAPFloatSemantics(VT);
- APFloat NeutralAF = !Flags.hasNoNaNs() ? APFloat::getQNaN(Semantics) :
- !Flags.hasNoInfs() ? APFloat::getInf(Semantics) :
- APFloat::getLargest(Semantics);
- if (Opcode == ISD::FMAXNUM)
- NeutralAF.changeSign();
-
- return getConstantFP(NeutralAF, DL, VT);
- }
- }
-}
-
+SDValue SelectionDAG::getNeutralElement(unsigned Opcode, const SDLoc &DL,
+ EVT VT, SDNodeFlags Flags) {
+ switch (Opcode) {
+ default:
+ return SDValue();
+ case ISD::ADD:
+ case ISD::OR:
+ case ISD::XOR:
+ case ISD::UMAX:
+ return getConstant(0, DL, VT);
+ case ISD::MUL:
+ return getConstant(1, DL, VT);
+ case ISD::AND:
+ case ISD::UMIN:
+ return getAllOnesConstant(DL, VT);
+ case ISD::SMAX:
+ return getConstant(APInt::getSignedMinValue(VT.getSizeInBits()), DL, VT);
+ case ISD::SMIN:
+ return getConstant(APInt::getSignedMaxValue(VT.getSizeInBits()), DL, VT);
+ case ISD::FADD:
+ return getConstantFP(-0.0, DL, VT);
+ case ISD::FMUL:
+ return getConstantFP(1.0, DL, VT);
+ case ISD::FMINNUM:
+ case ISD::FMAXNUM: {
+ // Neutral element for fminnum is NaN, Inf or FLT_MAX, depending on FMF.
+ const fltSemantics &Semantics = EVTToAPFloatSemantics(VT);
+ APFloat NeutralAF = !Flags.hasNoNaNs() ? APFloat::getQNaN(Semantics) :
+ !Flags.hasNoInfs() ? APFloat::getInf(Semantics) :
+ APFloat::getLargest(Semantics);
+ if (Opcode == ISD::FMAXNUM)
+ NeutralAF.changeSign();
+
+ return getConstantFP(NeutralAF, DL, VT);
+ }
+ }
+}
+
#ifndef NDEBUG
static void checkForCyclesHelper(const SDNode *N,
SmallPtrSetImpl<const SDNode*> &Visited,
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
index 1ffc833e7d..20c7d771bf 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/SelectionDAGAddressAnalysis.h"
-#include "llvm/Analysis/MemoryLocation.h"
+#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -97,28 +97,28 @@ bool BaseIndexOffset::computeAliasing(const SDNode *Op0,
int64_t PtrDiff;
if (NumBytes0.hasValue() && NumBytes1.hasValue() &&
BasePtr0.equalBaseIndex(BasePtr1, DAG, PtrDiff)) {
- // If the size of memory access is unknown, do not use it to analysis.
- // One example of unknown size memory access is to load/store scalable
- // vector objects on the stack.
+ // If the size of memory access is unknown, do not use it to analysis.
+ // One example of unknown size memory access is to load/store scalable
+ // vector objects on the stack.
// BasePtr1 is PtrDiff away from BasePtr0. They alias if none of the
// following situations arise:
- if (PtrDiff >= 0 &&
- *NumBytes0 != static_cast<int64_t>(MemoryLocation::UnknownSize)) {
- // [----BasePtr0----]
- // [---BasePtr1--]
- // ========PtrDiff========>
- IsAlias = !(*NumBytes0 <= PtrDiff);
- return true;
- }
- if (PtrDiff < 0 &&
- *NumBytes1 != static_cast<int64_t>(MemoryLocation::UnknownSize)) {
- // [----BasePtr0----]
- // [---BasePtr1--]
- // =====(-PtrDiff)====>
- IsAlias = !((PtrDiff + *NumBytes1) <= 0);
- return true;
- }
- return false;
+ if (PtrDiff >= 0 &&
+ *NumBytes0 != static_cast<int64_t>(MemoryLocation::UnknownSize)) {
+ // [----BasePtr0----]
+ // [---BasePtr1--]
+ // ========PtrDiff========>
+ IsAlias = !(*NumBytes0 <= PtrDiff);
+ return true;
+ }
+ if (PtrDiff < 0 &&
+ *NumBytes1 != static_cast<int64_t>(MemoryLocation::UnknownSize)) {
+ // [----BasePtr0----]
+ // [---BasePtr1--]
+ // =====(-PtrDiff)====>
+ IsAlias = !((PtrDiff + *NumBytes1) <= 0);
+ return true;
+ }
+ return false;
}
// If both BasePtr0 and BasePtr1 are FrameIndexes, we will not be
// able to calculate their relative offset if at least one arises
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index d8749cdd7c..a6bd774934 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -404,10 +404,10 @@ static SDValue getCopyFromPartsVector(SelectionDAG &DAG, const SDLoc &DL,
// vector widening case (e.g. <2 x float> -> <4 x float>). Extract the
// elements we want.
if (PartEVT.getVectorElementType() == ValueVT.getVectorElementType()) {
- assert((PartEVT.getVectorElementCount().getKnownMinValue() >
- ValueVT.getVectorElementCount().getKnownMinValue()) &&
- (PartEVT.getVectorElementCount().isScalable() ==
- ValueVT.getVectorElementCount().isScalable()) &&
+ assert((PartEVT.getVectorElementCount().getKnownMinValue() >
+ ValueVT.getVectorElementCount().getKnownMinValue()) &&
+ (PartEVT.getVectorElementCount().isScalable() ==
+ ValueVT.getVectorElementCount().isScalable()) &&
"Cannot narrow, it would be a lossy transformation");
return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, ValueVT, Val,
DAG.getVectorIdxConstant(0, DL));
@@ -435,7 +435,7 @@ static SDValue getCopyFromPartsVector(SelectionDAG &DAG, const SDLoc &DL,
// are the same size, this is an obvious bitcast.
if (ValueVT.getSizeInBits() == PartEVT.getSizeInBits()) {
return DAG.getNode(ISD::BITCAST, DL, ValueVT, Val);
- } else if (ValueVT.bitsLT(PartEVT)) {
+ } else if (ValueVT.bitsLT(PartEVT)) {
// Bitcast Val back the original type and extract the corresponding
// vector we want.
unsigned Elts = PartEVT.getSizeInBits() / ValueVT.getScalarSizeInBits();
@@ -665,14 +665,14 @@ static void getCopyToPartsVector(SelectionDAG &DAG, const SDLoc &DL,
// Promoted vector extract
Val = DAG.getAnyExtOrTrunc(Val, DL, PartVT);
} else {
- if (ValueVT.getVectorElementCount().isScalar()) {
+ if (ValueVT.getVectorElementCount().isScalar()) {
Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, PartVT, Val,
DAG.getVectorIdxConstant(0, DL));
} else {
- uint64_t ValueSize = ValueVT.getFixedSizeInBits();
- assert(PartVT.getFixedSizeInBits() > ValueSize &&
+ uint64_t ValueSize = ValueVT.getFixedSizeInBits();
+ assert(PartVT.getFixedSizeInBits() > ValueSize &&
"lossy conversion of vector to scalar type");
- EVT IntermediateType = EVT::getIntegerVT(*DAG.getContext(), ValueSize);
+ EVT IntermediateType = EVT::getIntegerVT(*DAG.getContext(), ValueSize);
Val = DAG.getBitcast(IntermediateType, Val);
Val = DAG.getAnyExtOrTrunc(Val, DL, PartVT);
}
@@ -705,15 +705,15 @@ static void getCopyToPartsVector(SelectionDAG &DAG, const SDLoc &DL,
assert(IntermediateVT.isScalableVector() == ValueVT.isScalableVector() &&
"Mixing scalable and fixed vectors when copying in parts");
- Optional<ElementCount> DestEltCnt;
+ Optional<ElementCount> DestEltCnt;
if (IntermediateVT.isVector())
DestEltCnt = IntermediateVT.getVectorElementCount() * NumIntermediates;
else
- DestEltCnt = ElementCount::getFixed(NumIntermediates);
+ DestEltCnt = ElementCount::getFixed(NumIntermediates);
EVT BuiltVectorTy = EVT::getVectorVT(
- *DAG.getContext(), IntermediateVT.getScalarType(), DestEltCnt.getValue());
+ *DAG.getContext(), IntermediateVT.getScalarType(), DestEltCnt.getValue());
if (ValueVT != BuiltVectorTy) {
if (SDValue Widened = widenVectorToPartType(DAG, Val, DL, BuiltVectorTy))
Val = Widened;
@@ -957,7 +957,7 @@ void RegsForValue::AddInlineAsmOperands(unsigned Code, bool HasMatching,
// shouldn't try to apply any sort of splitting logic to them.
assert(Regs.size() == RegVTs.size() && Regs.size() == ValueVTs.size() &&
"No 1:1 mapping from clobbers to regs?");
- Register SP = TLI.getStackPointerRegisterToSaveRestore();
+ Register SP = TLI.getStackPointerRegisterToSaveRestore();
(void)SP;
for (unsigned I = 0, E = ValueVTs.size(); I != E; ++I) {
Ops.push_back(DAG.getRegister(Regs[I], RegVTs[I]));
@@ -980,14 +980,14 @@ void RegsForValue::AddInlineAsmOperands(unsigned Code, bool HasMatching,
}
}
-SmallVector<std::pair<unsigned, TypeSize>, 4>
+SmallVector<std::pair<unsigned, TypeSize>, 4>
RegsForValue::getRegsAndSizes() const {
- SmallVector<std::pair<unsigned, TypeSize>, 4> OutVec;
+ SmallVector<std::pair<unsigned, TypeSize>, 4> OutVec;
unsigned I = 0;
for (auto CountAndVT : zip_first(RegCount, RegVTs)) {
unsigned RegCount = std::get<0>(CountAndVT);
MVT RegisterVT = std::get<1>(CountAndVT);
- TypeSize RegisterSize = RegisterVT.getSizeInBits();
+ TypeSize RegisterSize = RegisterVT.getSizeInBits();
for (unsigned E = I + RegCount; I != E; ++I)
OutVec.push_back(std::make_pair(Regs[I], RegisterSize));
}
@@ -1141,7 +1141,7 @@ void SelectionDAGBuilder::dropDanglingDebugInfo(const DILocalVariable *Variable,
if (isMatchingDbgValue(DDI))
salvageUnresolvedDbgValue(DDI);
- erase_if(DDIV, isMatchingDbgValue);
+ erase_if(DDIV, isMatchingDbgValue);
}
}
@@ -1514,9 +1514,9 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
if (const BlockAddress *BA = dyn_cast<BlockAddress>(C))
return DAG.getBlockAddress(BA, VT);
- if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(C))
- return getValue(Equiv->getGlobalValue());
-
+ if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(C))
+ return getValue(Equiv->getGlobalValue());
+
VectorType *VecTy = cast<VectorType>(V->getType());
// Now that we know the number and type of the elements, get that number of
@@ -1637,32 +1637,32 @@ void SelectionDAGBuilder::visitCleanupPad(const CleanupPadInst &CPI) {
}
}
-// In wasm EH, even though a catchpad may not catch an exception if a tag does
-// not match, it is OK to add only the first unwind destination catchpad to the
-// successors, because there will be at least one invoke instruction within the
-// catch scope that points to the next unwind destination, if one exists, so
-// CFGSort cannot mess up with BB sorting order.
-// (All catchpads with 'catch (type)' clauses have a 'llvm.rethrow' intrinsic
-// call within them, and catchpads only consisting of 'catch (...)' have a
-// '__cxa_end_catch' call within them, both of which generate invokes in case
-// the next unwind destination exists, i.e., the next unwind destination is not
-// the caller.)
-//
-// Having at most one EH pad successor is also simpler and helps later
-// transformations.
-//
-// For example,
-// current:
-// invoke void @foo to ... unwind label %catch.dispatch
-// catch.dispatch:
-// %0 = catchswitch within ... [label %catch.start] unwind label %next
-// catch.start:
-// ...
-// ... in this BB or some other child BB dominated by this BB there will be an
-// invoke that points to 'next' BB as an unwind destination
-//
-// next: ; We don't need to add this to 'current' BB's successor
-// ...
+// In wasm EH, even though a catchpad may not catch an exception if a tag does
+// not match, it is OK to add only the first unwind destination catchpad to the
+// successors, because there will be at least one invoke instruction within the
+// catch scope that points to the next unwind destination, if one exists, so
+// CFGSort cannot mess up with BB sorting order.
+// (All catchpads with 'catch (type)' clauses have a 'llvm.rethrow' intrinsic
+// call within them, and catchpads only consisting of 'catch (...)' have a
+// '__cxa_end_catch' call within them, both of which generate invokes in case
+// the next unwind destination exists, i.e., the next unwind destination is not
+// the caller.)
+//
+// Having at most one EH pad successor is also simpler and helps later
+// transformations.
+//
+// For example,
+// current:
+// invoke void @foo to ... unwind label %catch.dispatch
+// catch.dispatch:
+// %0 = catchswitch within ... [label %catch.start] unwind label %next
+// catch.start:
+// ...
+// ... in this BB or some other child BB dominated by this BB there will be an
+// invoke that points to 'next' BB as an unwind destination
+//
+// next: ; We don't need to add this to 'current' BB's successor
+// ...
static void findWasmUnwindDestinations(
FunctionLoweringInfo &FuncInfo, const BasicBlock *EHPadBB,
BranchProbability Prob,
@@ -1825,8 +1825,8 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
for (unsigned i = 0; i != NumValues; ++i) {
// An aggregate return value cannot wrap around the address space, so
// offsets to its parts don't wrap either.
- SDValue Ptr = DAG.getObjectPtrOffset(getCurSDLoc(), RetPtr,
- TypeSize::Fixed(Offsets[i]));
+ SDValue Ptr = DAG.getObjectPtrOffset(getCurSDLoc(), RetPtr,
+ TypeSize::Fixed(Offsets[i]));
SDValue Val = RetOp.getValue(RetOp.getResNo() + i);
if (MemVTs[i] != ValueVTs[i])
@@ -2107,19 +2107,19 @@ void SelectionDAGBuilder::FindMergedConditions(const Value *Cond,
}
const Instruction *BOp = dyn_cast<Instruction>(Cond);
- const Value *BOpOp0, *BOpOp1;
+ const Value *BOpOp0, *BOpOp1;
// Compute the effective opcode for Cond, taking into account whether it needs
// to be inverted, e.g.
// and (not (or A, B)), C
// gets lowered as
// and (and (not A, not B), C)
- Instruction::BinaryOps BOpc = (Instruction::BinaryOps)0;
+ Instruction::BinaryOps BOpc = (Instruction::BinaryOps)0;
if (BOp) {
- BOpc = match(BOp, m_LogicalAnd(m_Value(BOpOp0), m_Value(BOpOp1)))
- ? Instruction::And
- : (match(BOp, m_LogicalOr(m_Value(BOpOp0), m_Value(BOpOp1)))
- ? Instruction::Or
- : (Instruction::BinaryOps)0);
+ BOpc = match(BOp, m_LogicalAnd(m_Value(BOpOp0), m_Value(BOpOp1)))
+ ? Instruction::And
+ : (match(BOp, m_LogicalOr(m_Value(BOpOp0), m_Value(BOpOp1)))
+ ? Instruction::Or
+ : (Instruction::BinaryOps)0);
if (InvertCond) {
if (BOpc == Instruction::And)
BOpc = Instruction::Or;
@@ -2129,11 +2129,11 @@ void SelectionDAGBuilder::FindMergedConditions(const Value *Cond,
}
// If this node is not part of the or/and tree, emit it as a branch.
- // Note that all nodes in the tree should have same opcode.
- bool BOpIsInOrAndTree = BOpc && BOpc == Opc && BOp->hasOneUse();
- if (!BOpIsInOrAndTree || BOp->getParent() != CurBB->getBasicBlock() ||
- !InBlock(BOpOp0, CurBB->getBasicBlock()) ||
- !InBlock(BOpOp1, CurBB->getBasicBlock())) {
+ // Note that all nodes in the tree should have same opcode.
+ bool BOpIsInOrAndTree = BOpc && BOpc == Opc && BOp->hasOneUse();
+ if (!BOpIsInOrAndTree || BOp->getParent() != CurBB->getBasicBlock() ||
+ !InBlock(BOpOp0, CurBB->getBasicBlock()) ||
+ !InBlock(BOpOp1, CurBB->getBasicBlock())) {
EmitBranchForMergedCondition(Cond, TBB, FBB, CurBB, SwitchBB,
TProb, FProb, InvertCond);
return;
@@ -2169,15 +2169,15 @@ void SelectionDAGBuilder::FindMergedConditions(const Value *Cond,
auto NewTrueProb = TProb / 2;
auto NewFalseProb = TProb / 2 + FProb;
// Emit the LHS condition.
- FindMergedConditions(BOpOp0, TBB, TmpBB, CurBB, SwitchBB, Opc, NewTrueProb,
- NewFalseProb, InvertCond);
+ FindMergedConditions(BOpOp0, TBB, TmpBB, CurBB, SwitchBB, Opc, NewTrueProb,
+ NewFalseProb, InvertCond);
// Normalize A/2 and B to get A/(1+B) and 2B/(1+B).
SmallVector<BranchProbability, 2> Probs{TProb / 2, FProb};
BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
// Emit the RHS condition into TmpBB.
- FindMergedConditions(BOpOp1, TBB, FBB, TmpBB, SwitchBB, Opc, Probs[0],
- Probs[1], InvertCond);
+ FindMergedConditions(BOpOp1, TBB, FBB, TmpBB, SwitchBB, Opc, Probs[0],
+ Probs[1], InvertCond);
} else {
assert(Opc == Instruction::And && "Unknown merge op!");
// Codegen X & Y as:
@@ -2202,15 +2202,15 @@ void SelectionDAGBuilder::FindMergedConditions(const Value *Cond,
auto NewTrueProb = TProb + FProb / 2;
auto NewFalseProb = FProb / 2;
// Emit the LHS condition.
- FindMergedConditions(BOpOp0, TmpBB, FBB, CurBB, SwitchBB, Opc, NewTrueProb,
- NewFalseProb, InvertCond);
+ FindMergedConditions(BOpOp0, TmpBB, FBB, CurBB, SwitchBB, Opc, NewTrueProb,
+ NewFalseProb, InvertCond);
// Normalize A and B/2 to get 2A/(1+A) and B/(1+A).
SmallVector<BranchProbability, 2> Probs{TProb, FProb / 2};
BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
// Emit the RHS condition into TmpBB.
- FindMergedConditions(BOpOp1, TBB, FBB, TmpBB, SwitchBB, Opc, Probs[0],
- Probs[1], InvertCond);
+ FindMergedConditions(BOpOp1, TBB, FBB, TmpBB, SwitchBB, Opc, Probs[0],
+ Probs[1], InvertCond);
}
}
@@ -2287,20 +2287,20 @@ void SelectionDAGBuilder::visitBr(const BranchInst &I) {
// je foo
// cmp D, E
// jle foo
- const Instruction *BOp = dyn_cast<Instruction>(CondVal);
- if (!DAG.getTargetLoweringInfo().isJumpExpensive() && BOp &&
- BOp->hasOneUse() && !I.hasMetadata(LLVMContext::MD_unpredictable)) {
- Value *Vec;
- const Value *BOp0, *BOp1;
- Instruction::BinaryOps Opcode = (Instruction::BinaryOps)0;
- if (match(BOp, m_LogicalAnd(m_Value(BOp0), m_Value(BOp1))))
- Opcode = Instruction::And;
- else if (match(BOp, m_LogicalOr(m_Value(BOp0), m_Value(BOp1))))
- Opcode = Instruction::Or;
-
- if (Opcode && !(match(BOp0, m_ExtractElt(m_Value(Vec), m_Value())) &&
- match(BOp1, m_ExtractElt(m_Specific(Vec), m_Value())))) {
- FindMergedConditions(BOp, Succ0MBB, Succ1MBB, BrMBB, BrMBB, Opcode,
+ const Instruction *BOp = dyn_cast<Instruction>(CondVal);
+ if (!DAG.getTargetLoweringInfo().isJumpExpensive() && BOp &&
+ BOp->hasOneUse() && !I.hasMetadata(LLVMContext::MD_unpredictable)) {
+ Value *Vec;
+ const Value *BOp0, *BOp1;
+ Instruction::BinaryOps Opcode = (Instruction::BinaryOps)0;
+ if (match(BOp, m_LogicalAnd(m_Value(BOp0), m_Value(BOp1))))
+ Opcode = Instruction::And;
+ else if (match(BOp, m_LogicalOr(m_Value(BOp0), m_Value(BOp1))))
+ Opcode = Instruction::Or;
+
+ if (Opcode && !(match(BOp0, m_ExtractElt(m_Value(Vec), m_Value())) &&
+ match(BOp1, m_ExtractElt(m_Specific(Vec), m_Value())))) {
+ FindMergedConditions(BOp, Succ0MBB, Succ1MBB, BrMBB, BrMBB, Opcode,
getEdgeProbability(BrMBB, Succ0MBB),
getEdgeProbability(BrMBB, Succ1MBB),
/*InvertCond=*/false);
@@ -2549,7 +2549,7 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
SDLoc dl = getCurSDLoc();
SDValue StackSlotPtr = DAG.getFrameIndex(FI, PtrTy);
const Module &M = *ParentBB->getParent()->getFunction().getParent();
- Align Align = DL->getPrefTypeAlign(Type::getInt8PtrTy(M.getContext()));
+ Align Align = DL->getPrefTypeAlign(Type::getInt8PtrTy(M.getContext()));
// Generate code to load the content of the guard slot.
SDValue GuardVal = DAG.getLoad(
@@ -2807,7 +2807,7 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) {
case Intrinsic::experimental_gc_statepoint:
LowerStatepoint(cast<GCStatepointInst>(I), EHPadBB);
break;
- case Intrinsic::wasm_rethrow: {
+ case Intrinsic::wasm_rethrow: {
// This is usually done in visitTargetIntrinsic, but this intrinsic is
// special because it can be invoked, so we manually lower it to a DAG
// node here.
@@ -2815,7 +2815,7 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) {
Ops.push_back(getRoot()); // inchain
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
Ops.push_back(
- DAG.getTargetConstant(Intrinsic::wasm_rethrow, getCurSDLoc(),
+ DAG.getTargetConstant(Intrinsic::wasm_rethrow, getCurSDLoc(),
TLI.getPointerTy(DAG.getDataLayout())));
SDVTList VTs = DAG.getVTList(ArrayRef<EVT>({MVT::Other})); // outchain
DAG.setRoot(DAG.getNode(ISD::INTRINSIC_VOID, getCurSDLoc(), VTs, Ops));
@@ -3012,10 +3012,10 @@ void SelectionDAGBuilder::visitBinary(const User &I, unsigned Opcode) {
Flags.setNoSignedWrap(OFBinOp->hasNoSignedWrap());
Flags.setNoUnsignedWrap(OFBinOp->hasNoUnsignedWrap());
}
- if (auto *ExactOp = dyn_cast<PossiblyExactOperator>(&I))
+ if (auto *ExactOp = dyn_cast<PossiblyExactOperator>(&I))
Flags.setExact(ExactOp->isExact());
- if (auto *FPOp = dyn_cast<FPMathOperator>(&I))
- Flags.copyFMF(*FPOp);
+ if (auto *FPOp = dyn_cast<FPMathOperator>(&I))
+ Flags.copyFMF(*FPOp);
SDValue Op1 = getValue(I.getOperand(0));
SDValue Op2 = getValue(I.getOperand(1));
@@ -3125,14 +3125,14 @@ void SelectionDAGBuilder::visitFCmp(const User &I) {
SDValue Op2 = getValue(I.getOperand(1));
ISD::CondCode Condition = getFCmpCondCode(predicate);
- auto *FPMO = cast<FPMathOperator>(&I);
- if (FPMO->hasNoNaNs() || TM.Options.NoNaNsFPMath)
+ auto *FPMO = cast<FPMathOperator>(&I);
+ if (FPMO->hasNoNaNs() || TM.Options.NoNaNsFPMath)
Condition = getFCmpCodeWithoutNaN(Condition);
- SDNodeFlags Flags;
- Flags.copyFMF(*FPMO);
- SelectionDAG::FlagInserter FlagsInserter(DAG, Flags);
-
+ SDNodeFlags Flags;
+ Flags.copyFMF(*FPMO);
+ SelectionDAG::FlagInserter FlagsInserter(DAG, Flags);
+
EVT DestVT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(),
I.getType());
setValue(&I, DAG.getSetCC(getCurSDLoc(), DestVT, Op1, Op2, Condition));
@@ -3162,12 +3162,12 @@ void SelectionDAGBuilder::visitSelect(const User &I) {
Cond.getValueType().isVector() ? ISD::VSELECT : ISD::SELECT;
bool IsUnaryAbs = false;
- bool Negate = false;
+ bool Negate = false;
+
+ SDNodeFlags Flags;
+ if (auto *FPOp = dyn_cast<FPMathOperator>(&I))
+ Flags.copyFMF(*FPOp);
- SDNodeFlags Flags;
- if (auto *FPOp = dyn_cast<FPMathOperator>(&I))
- Flags.copyFMF(*FPOp);
-
// Min/max matching is only viable if all output VTs are the same.
if (is_splat(ValueVTs)) {
EVT VT = ValueVTs[0];
@@ -3227,9 +3227,9 @@ void SelectionDAGBuilder::visitSelect(const User &I) {
break;
}
break;
- case SPF_NABS:
- Negate = true;
- LLVM_FALLTHROUGH;
+ case SPF_NABS:
+ Negate = true;
+ LLVM_FALLTHROUGH;
case SPF_ABS:
IsUnaryAbs = true;
Opc = ISD::ABS;
@@ -3260,13 +3260,13 @@ void SelectionDAGBuilder::visitSelect(const User &I) {
if (IsUnaryAbs) {
for (unsigned i = 0; i != NumValues; ++i) {
- SDLoc dl = getCurSDLoc();
- EVT VT = LHSVal.getNode()->getValueType(LHSVal.getResNo() + i);
+ SDLoc dl = getCurSDLoc();
+ EVT VT = LHSVal.getNode()->getValueType(LHSVal.getResNo() + i);
Values[i] =
- DAG.getNode(OpCode, dl, VT, LHSVal.getValue(LHSVal.getResNo() + i));
- if (Negate)
- Values[i] = DAG.getNode(ISD::SUB, dl, VT, DAG.getConstant(0, dl, VT),
- Values[i]);
+ DAG.getNode(OpCode, dl, VT, LHSVal.getValue(LHSVal.getResNo() + i));
+ if (Negate)
+ Values[i] = DAG.getNode(ISD::SUB, dl, VT, DAG.getConstant(0, dl, VT),
+ Values[i]);
}
} else {
for (unsigned i = 0; i != NumValues; ++i) {
@@ -3275,7 +3275,7 @@ void SelectionDAGBuilder::visitSelect(const User &I) {
Ops.push_back(SDValue(RHSVal.getNode(), RHSVal.getResNo() + i));
Values[i] = DAG.getNode(
OpCode, getCurSDLoc(),
- LHSVal.getNode()->getValueType(LHSVal.getResNo() + i), Ops, Flags);
+ LHSVal.getNode()->getValueType(LHSVal.getResNo() + i), Ops, Flags);
}
}
@@ -3417,7 +3417,7 @@ void SelectionDAGBuilder::visitAddrSpaceCast(const User &I) {
unsigned SrcAS = SV->getType()->getPointerAddressSpace();
unsigned DestAS = I.getType()->getPointerAddressSpace();
- if (!TM.isNoopAddrSpaceCast(SrcAS, DestAS))
+ if (!TM.isNoopAddrSpaceCast(SrcAS, DestAS))
N = DAG.getAddrSpaceCast(getCurSDLoc(), DestVT, N, SrcAS, DestAS);
setValue(&I, N);
@@ -3751,12 +3751,12 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
bool IsVectorGEP = I.getType()->isVectorTy();
ElementCount VectorElementCount =
IsVectorGEP ? cast<VectorType>(I.getType())->getElementCount()
- : ElementCount::getFixed(0);
+ : ElementCount::getFixed(0);
if (IsVectorGEP && !N.getValueType().isVector()) {
LLVMContext &Context = *DAG.getContext();
EVT VT = EVT::getVectorVT(Context, N.getValueType(), VectorElementCount);
- if (VectorElementCount.isScalable())
+ if (VectorElementCount.isScalable())
N = DAG.getSplatVector(VT, dl, N);
else
N = DAG.getSplatBuildVector(VT, dl, N);
@@ -3829,7 +3829,7 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
if (!IdxN.getValueType().isVector() && IsVectorGEP) {
EVT VT = EVT::getVectorVT(*Context, IdxN.getValueType(),
VectorElementCount);
- if (VectorElementCount.isScalable())
+ if (VectorElementCount.isScalable())
IdxN = DAG.getSplatVector(VT, dl, IdxN);
else
IdxN = DAG.getSplatBuildVector(VT, dl, IdxN);
@@ -3870,13 +3870,13 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
}
}
- MVT PtrTy = TLI.getPointerTy(DAG.getDataLayout(), AS);
- MVT PtrMemTy = TLI.getPointerMemTy(DAG.getDataLayout(), AS);
- if (IsVectorGEP) {
- PtrTy = MVT::getVectorVT(PtrTy, VectorElementCount);
- PtrMemTy = MVT::getVectorVT(PtrMemTy, VectorElementCount);
- }
-
+ MVT PtrTy = TLI.getPointerTy(DAG.getDataLayout(), AS);
+ MVT PtrMemTy = TLI.getPointerMemTy(DAG.getDataLayout(), AS);
+ if (IsVectorGEP) {
+ PtrTy = MVT::getVectorVT(PtrTy, VectorElementCount);
+ PtrMemTy = MVT::getVectorVT(PtrMemTy, VectorElementCount);
+ }
+
if (PtrMemTy != PtrTy && !cast<GEPOperator>(I).isInBounds())
N = DAG.getPtrExtendInReg(N, dl, PtrMemTy);
@@ -4173,8 +4173,8 @@ void SelectionDAGBuilder::visitStore(const StoreInst &I) {
Root = Chain;
ChainI = 0;
}
- SDValue Add =
- DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(Offsets[i]), dl, Flags);
+ SDValue Add =
+ DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(Offsets[i]), dl, Flags);
SDValue Val = SDValue(Src.getNode(), Src.getResNo() + i);
if (MemVTs[i] != ValueVTs[i])
Val = DAG.getPtrExtOrTrunc(Val, dl, MemVTs[i]);
@@ -4336,12 +4336,12 @@ void SelectionDAGBuilder::visitMaskedScatter(const CallInst &I) {
if (!UniformBase) {
Base = DAG.getConstant(0, sdl, TLI.getPointerTy(DAG.getDataLayout()));
Index = getValue(Ptr);
- IndexType = ISD::SIGNED_UNSCALED;
+ IndexType = ISD::SIGNED_UNSCALED;
Scale = DAG.getTargetConstant(1, sdl, TLI.getPointerTy(DAG.getDataLayout()));
}
SDValue Ops[] = { getMemoryRoot(), Src0, Mask, Base, Index, Scale };
SDValue Scatter = DAG.getMaskedScatter(DAG.getVTList(MVT::Other), VT, sdl,
- Ops, MMO, IndexType, false);
+ Ops, MMO, IndexType, false);
DAG.setRoot(Scatter);
setValue(&I, Scatter);
}
@@ -4389,7 +4389,7 @@ void SelectionDAGBuilder::visitMaskedLoad(const CallInst &I, bool IsExpanding) {
// Do not serialize masked loads of constant memory with anything.
MemoryLocation ML;
if (VT.isScalableVector())
- ML = MemoryLocation::getAfter(PtrOperand);
+ ML = MemoryLocation::getAfter(PtrOperand);
else
ML = MemoryLocation(PtrOperand, LocationSize::precise(
DAG.getDataLayout().getTypeStoreSize(I.getType())),
@@ -4447,12 +4447,12 @@ void SelectionDAGBuilder::visitMaskedGather(const CallInst &I) {
if (!UniformBase) {
Base = DAG.getConstant(0, sdl, TLI.getPointerTy(DAG.getDataLayout()));
Index = getValue(Ptr);
- IndexType = ISD::SIGNED_UNSCALED;
+ IndexType = ISD::SIGNED_UNSCALED;
Scale = DAG.getTargetConstant(1, sdl, TLI.getPointerTy(DAG.getDataLayout()));
}
SDValue Ops[] = { Root, Src0, Mask, Base, Index, Scale };
SDValue Gather = DAG.getMaskedGather(DAG.getVTList(VT, MVT::Other), VT, sdl,
- Ops, MMO, IndexType, ISD::NON_EXTLOAD);
+ Ops, MMO, IndexType, ISD::NON_EXTLOAD);
PendingLoads.push_back(Gather.getValue(1));
setValue(&I, Gather);
@@ -4879,7 +4879,7 @@ static SDValue getLimitedPrecisionExp2(SDValue t0, const SDLoc &dl,
/// expandExp - Lower an exp intrinsic. Handles the special sequences for
/// limited-precision mode.
static SDValue expandExp(const SDLoc &dl, SDValue Op, SelectionDAG &DAG,
- const TargetLowering &TLI, SDNodeFlags Flags) {
+ const TargetLowering &TLI, SDNodeFlags Flags) {
if (Op.getValueType() == MVT::f32 &&
LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) {
@@ -4895,13 +4895,13 @@ static SDValue expandExp(const SDLoc &dl, SDValue Op, SelectionDAG &DAG,
}
// No special expansion.
- return DAG.getNode(ISD::FEXP, dl, Op.getValueType(), Op, Flags);
+ return DAG.getNode(ISD::FEXP, dl, Op.getValueType(), Op, Flags);
}
/// expandLog - Lower a log intrinsic. Handles the special sequences for
/// limited-precision mode.
static SDValue expandLog(const SDLoc &dl, SDValue Op, SelectionDAG &DAG,
- const TargetLowering &TLI, SDNodeFlags Flags) {
+ const TargetLowering &TLI, SDNodeFlags Flags) {
// TODO: What fast-math-flags should be set on the floating-point nodes?
if (Op.getValueType() == MVT::f32 &&
@@ -4994,13 +4994,13 @@ static SDValue expandLog(const SDLoc &dl, SDValue Op, SelectionDAG &DAG,
}
// No special expansion.
- return DAG.getNode(ISD::FLOG, dl, Op.getValueType(), Op, Flags);
+ return DAG.getNode(ISD::FLOG, dl, Op.getValueType(), Op, Flags);
}
/// expandLog2 - Lower a log2 intrinsic. Handles the special sequences for
/// limited-precision mode.
static SDValue expandLog2(const SDLoc &dl, SDValue Op, SelectionDAG &DAG,
- const TargetLowering &TLI, SDNodeFlags Flags) {
+ const TargetLowering &TLI, SDNodeFlags Flags) {
// TODO: What fast-math-flags should be set on the floating-point nodes?
if (Op.getValueType() == MVT::f32 &&
@@ -5091,13 +5091,13 @@ static SDValue expandLog2(const SDLoc &dl, SDValue Op, SelectionDAG &DAG,
}
// No special expansion.
- return DAG.getNode(ISD::FLOG2, dl, Op.getValueType(), Op, Flags);
+ return DAG.getNode(ISD::FLOG2, dl, Op.getValueType(), Op, Flags);
}
/// expandLog10 - Lower a log10 intrinsic. Handles the special sequences for
/// limited-precision mode.
static SDValue expandLog10(const SDLoc &dl, SDValue Op, SelectionDAG &DAG,
- const TargetLowering &TLI, SDNodeFlags Flags) {
+ const TargetLowering &TLI, SDNodeFlags Flags) {
// TODO: What fast-math-flags should be set on the floating-point nodes?
if (Op.getValueType() == MVT::f32 &&
@@ -5181,26 +5181,26 @@ static SDValue expandLog10(const SDLoc &dl, SDValue Op, SelectionDAG &DAG,
}
// No special expansion.
- return DAG.getNode(ISD::FLOG10, dl, Op.getValueType(), Op, Flags);
+ return DAG.getNode(ISD::FLOG10, dl, Op.getValueType(), Op, Flags);
}
/// expandExp2 - Lower an exp2 intrinsic. Handles the special sequences for
/// limited-precision mode.
static SDValue expandExp2(const SDLoc &dl, SDValue Op, SelectionDAG &DAG,
- const TargetLowering &TLI, SDNodeFlags Flags) {
+ const TargetLowering &TLI, SDNodeFlags Flags) {
if (Op.getValueType() == MVT::f32 &&
LimitFloatPrecision > 0 && LimitFloatPrecision <= 18)
return getLimitedPrecisionExp2(Op, dl, DAG);
// No special expansion.
- return DAG.getNode(ISD::FEXP2, dl, Op.getValueType(), Op, Flags);
+ return DAG.getNode(ISD::FEXP2, dl, Op.getValueType(), Op, Flags);
}
/// visitPow - Lower a pow intrinsic. Handles the special sequences for
/// limited-precision mode with x == 10.0f.
static SDValue expandPow(const SDLoc &dl, SDValue LHS, SDValue RHS,
- SelectionDAG &DAG, const TargetLowering &TLI,
- SDNodeFlags Flags) {
+ SelectionDAG &DAG, const TargetLowering &TLI,
+ SDNodeFlags Flags) {
bool IsExp10 = false;
if (LHS.getValueType() == MVT::f32 && RHS.getValueType() == MVT::f32 &&
LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) {
@@ -5223,7 +5223,7 @@ static SDValue expandPow(const SDLoc &dl, SDValue LHS, SDValue RHS,
}
// No special expansion.
- return DAG.getNode(ISD::FPOW, dl, LHS.getValueType(), LHS, RHS, Flags);
+ return DAG.getNode(ISD::FPOW, dl, LHS.getValueType(), LHS, RHS, Flags);
}
/// ExpandPowI - Expand a llvm.powi intrinsic.
@@ -5348,7 +5348,7 @@ static SDValue expandDivFix(unsigned Opcode, const SDLoc &DL,
// getUnderlyingArgRegs - Find underlying registers used for a truncated,
// bitcasted, or split argument. Returns a list of <Register, size in bits>
static void
-getUnderlyingArgRegs(SmallVectorImpl<std::pair<unsigned, TypeSize>> &Regs,
+getUnderlyingArgRegs(SmallVectorImpl<std::pair<unsigned, TypeSize>> &Regs,
const SDValue &N) {
switch (N.getOpcode()) {
case ISD::CopyFromReg: {
@@ -5459,7 +5459,7 @@ bool SelectionDAGBuilder::EmitFuncArgumentDbgValue(
if (FI != std::numeric_limits<int>::max())
Op = MachineOperand::CreateFI(FI);
- SmallVector<std::pair<unsigned, TypeSize>, 8> ArgRegsAndSizes;
+ SmallVector<std::pair<unsigned, TypeSize>, 8> ArgRegsAndSizes;
if (!Op && N.getNode()) {
getUnderlyingArgRegs(ArgRegsAndSizes, N);
Register Reg;
@@ -5489,8 +5489,8 @@ bool SelectionDAGBuilder::EmitFuncArgumentDbgValue(
if (!Op) {
// Create a DBG_VALUE for each decomposed value in ArgRegs to cover Reg
- auto splitMultiRegDbgValue = [&](ArrayRef<std::pair<unsigned, TypeSize>>
- SplitRegs) {
+ auto splitMultiRegDbgValue = [&](ArrayRef<std::pair<unsigned, TypeSize>>
+ SplitRegs) {
unsigned Offset = 0;
for (auto RegAndSize : SplitRegs) {
// If the expression is already a fragment, the current register
@@ -5644,10 +5644,10 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
DebugLoc dl = getCurDebugLoc();
SDValue Res;
- SDNodeFlags Flags;
- if (auto *FPOp = dyn_cast<FPMathOperator>(&I))
- Flags.copyFMF(*FPOp);
-
+ SDNodeFlags Flags;
+ if (auto *FPOp = dyn_cast<FPMathOperator>(&I))
+ Flags.copyFMF(*FPOp);
+
switch (Intrinsic) {
default:
// By default, turn this into a target intrinsic node.
@@ -6062,26 +6062,26 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
getValue(I.getArgOperand(1)), DAG));
return;
case Intrinsic::log:
- setValue(&I, expandLog(sdl, getValue(I.getArgOperand(0)), DAG, TLI, Flags));
+ setValue(&I, expandLog(sdl, getValue(I.getArgOperand(0)), DAG, TLI, Flags));
return;
case Intrinsic::log2:
- setValue(&I,
- expandLog2(sdl, getValue(I.getArgOperand(0)), DAG, TLI, Flags));
+ setValue(&I,
+ expandLog2(sdl, getValue(I.getArgOperand(0)), DAG, TLI, Flags));
return;
case Intrinsic::log10:
- setValue(&I,
- expandLog10(sdl, getValue(I.getArgOperand(0)), DAG, TLI, Flags));
+ setValue(&I,
+ expandLog10(sdl, getValue(I.getArgOperand(0)), DAG, TLI, Flags));
return;
case Intrinsic::exp:
- setValue(&I, expandExp(sdl, getValue(I.getArgOperand(0)), DAG, TLI, Flags));
+ setValue(&I, expandExp(sdl, getValue(I.getArgOperand(0)), DAG, TLI, Flags));
return;
case Intrinsic::exp2:
- setValue(&I,
- expandExp2(sdl, getValue(I.getArgOperand(0)), DAG, TLI, Flags));
+ setValue(&I,
+ expandExp2(sdl, getValue(I.getArgOperand(0)), DAG, TLI, Flags));
return;
case Intrinsic::pow:
setValue(&I, expandPow(sdl, getValue(I.getArgOperand(0)),
- getValue(I.getArgOperand(1)), DAG, TLI, Flags));
+ getValue(I.getArgOperand(1)), DAG, TLI, Flags));
return;
case Intrinsic::sqrt:
case Intrinsic::fabs:
@@ -6114,7 +6114,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
setValue(&I, DAG.getNode(Opcode, sdl,
getValue(I.getArgOperand(0)).getValueType(),
- getValue(I.getArgOperand(0)), Flags));
+ getValue(I.getArgOperand(0)), Flags));
return;
}
case Intrinsic::lround:
@@ -6139,47 +6139,47 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
setValue(&I, DAG.getNode(ISD::FMINNUM, sdl,
getValue(I.getArgOperand(0)).getValueType(),
getValue(I.getArgOperand(0)),
- getValue(I.getArgOperand(1)), Flags));
+ getValue(I.getArgOperand(1)), Flags));
return;
case Intrinsic::maxnum:
setValue(&I, DAG.getNode(ISD::FMAXNUM, sdl,
getValue(I.getArgOperand(0)).getValueType(),
getValue(I.getArgOperand(0)),
- getValue(I.getArgOperand(1)), Flags));
+ getValue(I.getArgOperand(1)), Flags));
return;
case Intrinsic::minimum:
setValue(&I, DAG.getNode(ISD::FMINIMUM, sdl,
getValue(I.getArgOperand(0)).getValueType(),
getValue(I.getArgOperand(0)),
- getValue(I.getArgOperand(1)), Flags));
+ getValue(I.getArgOperand(1)), Flags));
return;
case Intrinsic::maximum:
setValue(&I, DAG.getNode(ISD::FMAXIMUM, sdl,
getValue(I.getArgOperand(0)).getValueType(),
getValue(I.getArgOperand(0)),
- getValue(I.getArgOperand(1)), Flags));
+ getValue(I.getArgOperand(1)), Flags));
return;
case Intrinsic::copysign:
setValue(&I, DAG.getNode(ISD::FCOPYSIGN, sdl,
getValue(I.getArgOperand(0)).getValueType(),
getValue(I.getArgOperand(0)),
- getValue(I.getArgOperand(1)), Flags));
+ getValue(I.getArgOperand(1)), Flags));
return;
case Intrinsic::fma:
- setValue(&I, DAG.getNode(
- ISD::FMA, sdl, getValue(I.getArgOperand(0)).getValueType(),
- getValue(I.getArgOperand(0)), getValue(I.getArgOperand(1)),
- getValue(I.getArgOperand(2)), Flags));
+ setValue(&I, DAG.getNode(
+ ISD::FMA, sdl, getValue(I.getArgOperand(0)).getValueType(),
+ getValue(I.getArgOperand(0)), getValue(I.getArgOperand(1)),
+ getValue(I.getArgOperand(2)), Flags));
return;
#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
case Intrinsic::INTRINSIC:
#include "llvm/IR/ConstrainedOps.def"
visitConstrainedFPIntrinsic(cast<ConstrainedFPIntrinsic>(I));
return;
-#define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID:
-#include "llvm/IR/VPIntrinsics.def"
- visitVectorPredicationIntrinsic(cast<VPIntrinsic>(I));
- return;
+#define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID:
+#include "llvm/IR/VPIntrinsics.def"
+ visitVectorPredicationIntrinsic(cast<VPIntrinsic>(I));
+ return;
case Intrinsic::fmuladd: {
EVT VT = TLI.getValueType(DAG.getDataLayout(), I.getType());
if (TM.Options.AllowFPOpFusion != FPOpFusion::Strict &&
@@ -6188,15 +6188,15 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
getValue(I.getArgOperand(0)).getValueType(),
getValue(I.getArgOperand(0)),
getValue(I.getArgOperand(1)),
- getValue(I.getArgOperand(2)), Flags));
+ getValue(I.getArgOperand(2)), Flags));
} else {
// TODO: Intrinsic calls should have fast-math-flags.
- SDValue Mul = DAG.getNode(
- ISD::FMUL, sdl, getValue(I.getArgOperand(0)).getValueType(),
- getValue(I.getArgOperand(0)), getValue(I.getArgOperand(1)), Flags);
+ SDValue Mul = DAG.getNode(
+ ISD::FMUL, sdl, getValue(I.getArgOperand(0)).getValueType(),
+ getValue(I.getArgOperand(0)), getValue(I.getArgOperand(1)), Flags);
SDValue Add = DAG.getNode(ISD::FADD, sdl,
getValue(I.getArgOperand(0)).getValueType(),
- Mul, getValue(I.getArgOperand(2)), Flags);
+ Mul, getValue(I.getArgOperand(2)), Flags);
setValue(&I, Add);
}
return;
@@ -6214,20 +6214,20 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
DAG.getNode(ISD::BITCAST, sdl, MVT::f16,
getValue(I.getArgOperand(0)))));
return;
- case Intrinsic::fptosi_sat: {
- EVT Type = TLI.getValueType(DAG.getDataLayout(), I.getType());
- SDValue SatW = DAG.getConstant(Type.getScalarSizeInBits(), sdl, MVT::i32);
- setValue(&I, DAG.getNode(ISD::FP_TO_SINT_SAT, sdl, Type,
- getValue(I.getArgOperand(0)), SatW));
- return;
- }
- case Intrinsic::fptoui_sat: {
- EVT Type = TLI.getValueType(DAG.getDataLayout(), I.getType());
- SDValue SatW = DAG.getConstant(Type.getScalarSizeInBits(), sdl, MVT::i32);
- setValue(&I, DAG.getNode(ISD::FP_TO_UINT_SAT, sdl, Type,
- getValue(I.getArgOperand(0)), SatW));
- return;
- }
+ case Intrinsic::fptosi_sat: {
+ EVT Type = TLI.getValueType(DAG.getDataLayout(), I.getType());
+ SDValue SatW = DAG.getConstant(Type.getScalarSizeInBits(), sdl, MVT::i32);
+ setValue(&I, DAG.getNode(ISD::FP_TO_SINT_SAT, sdl, Type,
+ getValue(I.getArgOperand(0)), SatW));
+ return;
+ }
+ case Intrinsic::fptoui_sat: {
+ EVT Type = TLI.getValueType(DAG.getDataLayout(), I.getType());
+ SDValue SatW = DAG.getConstant(Type.getScalarSizeInBits(), sdl, MVT::i32);
+ setValue(&I, DAG.getNode(ISD::FP_TO_UINT_SAT, sdl, Type,
+ getValue(I.getArgOperand(0)), SatW));
+ return;
+ }
case Intrinsic::pcmarker: {
SDValue Tmp = getValue(I.getArgOperand(0));
DAG.setRoot(DAG.getNode(ISD::PCMARKER, sdl, MVT::Other, getRoot(), Tmp));
@@ -6281,11 +6281,11 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
SDValue Z = getValue(I.getArgOperand(2));
EVT VT = X.getValueType();
- if (X == Y) {
- auto RotateOpcode = IsFSHL ? ISD::ROTL : ISD::ROTR;
- setValue(&I, DAG.getNode(RotateOpcode, sdl, VT, X, Z));
- } else {
- auto FunnelOpcode = IsFSHL ? ISD::FSHL : ISD::FSHR;
+ if (X == Y) {
+ auto RotateOpcode = IsFSHL ? ISD::ROTL : ISD::ROTR;
+ setValue(&I, DAG.getNode(RotateOpcode, sdl, VT, X, Z));
+ } else {
+ auto FunnelOpcode = IsFSHL ? ISD::FSHL : ISD::FSHR;
setValue(&I, DAG.getNode(FunnelOpcode, sdl, VT, X, Y, Z));
}
return;
@@ -6314,18 +6314,18 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
setValue(&I, DAG.getNode(ISD::USUBSAT, sdl, Op1.getValueType(), Op1, Op2));
return;
}
- case Intrinsic::sshl_sat: {
- SDValue Op1 = getValue(I.getArgOperand(0));
- SDValue Op2 = getValue(I.getArgOperand(1));
- setValue(&I, DAG.getNode(ISD::SSHLSAT, sdl, Op1.getValueType(), Op1, Op2));
- return;
- }
- case Intrinsic::ushl_sat: {
- SDValue Op1 = getValue(I.getArgOperand(0));
- SDValue Op2 = getValue(I.getArgOperand(1));
- setValue(&I, DAG.getNode(ISD::USHLSAT, sdl, Op1.getValueType(), Op1, Op2));
- return;
- }
+ case Intrinsic::sshl_sat: {
+ SDValue Op1 = getValue(I.getArgOperand(0));
+ SDValue Op2 = getValue(I.getArgOperand(1));
+ setValue(&I, DAG.getNode(ISD::SSHLSAT, sdl, Op1.getValueType(), Op1, Op2));
+ return;
+ }
+ case Intrinsic::ushl_sat: {
+ SDValue Op1 = getValue(I.getArgOperand(0));
+ SDValue Op2 = getValue(I.getArgOperand(1));
+ setValue(&I, DAG.getNode(ISD::USHLSAT, sdl, Op1.getValueType(), Op1, Op2));
+ return;
+ }
case Intrinsic::smul_fix:
case Intrinsic::umul_fix:
case Intrinsic::smul_fix_sat:
@@ -6348,36 +6348,36 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
Op1, Op2, Op3, DAG, TLI));
return;
}
- case Intrinsic::smax: {
- SDValue Op1 = getValue(I.getArgOperand(0));
- SDValue Op2 = getValue(I.getArgOperand(1));
- setValue(&I, DAG.getNode(ISD::SMAX, sdl, Op1.getValueType(), Op1, Op2));
- return;
- }
- case Intrinsic::smin: {
- SDValue Op1 = getValue(I.getArgOperand(0));
- SDValue Op2 = getValue(I.getArgOperand(1));
- setValue(&I, DAG.getNode(ISD::SMIN, sdl, Op1.getValueType(), Op1, Op2));
- return;
- }
- case Intrinsic::umax: {
- SDValue Op1 = getValue(I.getArgOperand(0));
- SDValue Op2 = getValue(I.getArgOperand(1));
- setValue(&I, DAG.getNode(ISD::UMAX, sdl, Op1.getValueType(), Op1, Op2));
- return;
- }
- case Intrinsic::umin: {
- SDValue Op1 = getValue(I.getArgOperand(0));
- SDValue Op2 = getValue(I.getArgOperand(1));
- setValue(&I, DAG.getNode(ISD::UMIN, sdl, Op1.getValueType(), Op1, Op2));
- return;
- }
- case Intrinsic::abs: {
- // TODO: Preserve "int min is poison" arg in SDAG?
- SDValue Op1 = getValue(I.getArgOperand(0));
- setValue(&I, DAG.getNode(ISD::ABS, sdl, Op1.getValueType(), Op1));
- return;
- }
+ case Intrinsic::smax: {
+ SDValue Op1 = getValue(I.getArgOperand(0));
+ SDValue Op2 = getValue(I.getArgOperand(1));
+ setValue(&I, DAG.getNode(ISD::SMAX, sdl, Op1.getValueType(), Op1, Op2));
+ return;
+ }
+ case Intrinsic::smin: {
+ SDValue Op1 = getValue(I.getArgOperand(0));
+ SDValue Op2 = getValue(I.getArgOperand(1));
+ setValue(&I, DAG.getNode(ISD::SMIN, sdl, Op1.getValueType(), Op1, Op2));
+ return;
+ }
+ case Intrinsic::umax: {
+ SDValue Op1 = getValue(I.getArgOperand(0));
+ SDValue Op2 = getValue(I.getArgOperand(1));
+ setValue(&I, DAG.getNode(ISD::UMAX, sdl, Op1.getValueType(), Op1, Op2));
+ return;
+ }
+ case Intrinsic::umin: {
+ SDValue Op1 = getValue(I.getArgOperand(0));
+ SDValue Op2 = getValue(I.getArgOperand(1));
+ setValue(&I, DAG.getNode(ISD::UMIN, sdl, Op1.getValueType(), Op1, Op2));
+ return;
+ }
+ case Intrinsic::abs: {
+ // TODO: Preserve "int min is poison" arg in SDAG?
+ SDValue Op1 = getValue(I.getArgOperand(0));
+ setValue(&I, DAG.getNode(ISD::ABS, sdl, Op1.getValueType(), Op1));
+ return;
+ }
case Intrinsic::stacksave: {
SDValue Op = getRoot();
EVT VT = TLI.getValueType(DAG.getDataLayout(), I.getType());
@@ -6396,7 +6396,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
EVT ResTy = TLI.getValueType(DAG.getDataLayout(), I.getType());
// Result type for @llvm.get.dynamic.area.offset should match PtrTy for
// target.
- if (PtrTy.getFixedSizeInBits() < ResTy.getFixedSizeInBits())
+ if (PtrTy.getFixedSizeInBits() < ResTy.getFixedSizeInBits())
report_fatal_error("Wrong result type for @llvm.get.dynamic.area.offset"
" intrinsic!");
Res = DAG.getNode(ISD::GET_DYNAMIC_AREA_OFFSET, sdl, DAG.getVTList(ResTy),
@@ -6414,7 +6414,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
} else {
EVT PtrTy = TLI.getValueType(DAG.getDataLayout(), I.getType());
const Value *Global = TLI.getSDagStackGuard(M);
- Align Align = DL->getPrefTypeAlign(Global->getType());
+ Align Align = DL->getPrefTypeAlign(Global->getType());
Res = DAG.getLoad(PtrTy, sdl, Chain, getValue(Global),
MachinePointerInfo(Global, 0), Align,
MachineMemOperand::MOVolatile);
@@ -6445,10 +6445,10 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
SDValue FIN = DAG.getFrameIndex(FI, PtrTy);
// Store the stack protector onto the stack.
- Res = DAG.getStore(
- Chain, sdl, Src, FIN,
- MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI),
- MaybeAlign(), MachineMemOperand::MOVolatile);
+ Res = DAG.getStore(
+ Chain, sdl, Src, FIN,
+ MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI),
+ MaybeAlign(), MachineMemOperand::MOVolatile);
setValue(&I, Res);
DAG.setRoot(Res);
return;
@@ -6466,13 +6466,13 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
// Drop the intrinsic, but forward the value
setValue(&I, getValue(I.getOperand(0)));
return;
-
+
case Intrinsic::assume:
- case Intrinsic::experimental_noalias_scope_decl:
+ case Intrinsic::experimental_noalias_scope_decl:
case Intrinsic::var_annotation:
case Intrinsic::sideeffect:
- // Discard annotate attributes, noalias scope declarations, assumptions, and
- // artificial side-effects.
+ // Discard annotate attributes, noalias scope declarations, assumptions, and
+ // artificial side-effects.
return;
case Intrinsic::codeview_annotation: {
@@ -6533,7 +6533,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
setValue(&I, getValue(I.getArgOperand(0)));
return;
- case Intrinsic::ubsantrap:
+ case Intrinsic::ubsantrap:
case Intrinsic::debugtrap:
case Intrinsic::trap: {
StringRef TrapFuncName =
@@ -6541,31 +6541,31 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
.getAttribute(AttributeList::FunctionIndex, "trap-func-name")
.getValueAsString();
if (TrapFuncName.empty()) {
- switch (Intrinsic) {
- case Intrinsic::trap:
- DAG.setRoot(DAG.getNode(ISD::TRAP, sdl, MVT::Other, getRoot()));
- break;
- case Intrinsic::debugtrap:
- DAG.setRoot(DAG.getNode(ISD::DEBUGTRAP, sdl, MVT::Other, getRoot()));
- break;
- case Intrinsic::ubsantrap:
- DAG.setRoot(DAG.getNode(
- ISD::UBSANTRAP, sdl, MVT::Other, getRoot(),
- DAG.getTargetConstant(
- cast<ConstantInt>(I.getArgOperand(0))->getZExtValue(), sdl,
- MVT::i32)));
- break;
- default: llvm_unreachable("unknown trap intrinsic");
- }
+ switch (Intrinsic) {
+ case Intrinsic::trap:
+ DAG.setRoot(DAG.getNode(ISD::TRAP, sdl, MVT::Other, getRoot()));
+ break;
+ case Intrinsic::debugtrap:
+ DAG.setRoot(DAG.getNode(ISD::DEBUGTRAP, sdl, MVT::Other, getRoot()));
+ break;
+ case Intrinsic::ubsantrap:
+ DAG.setRoot(DAG.getNode(
+ ISD::UBSANTRAP, sdl, MVT::Other, getRoot(),
+ DAG.getTargetConstant(
+ cast<ConstantInt>(I.getArgOperand(0))->getZExtValue(), sdl,
+ MVT::i32)));
+ break;
+ default: llvm_unreachable("unknown trap intrinsic");
+ }
return;
}
TargetLowering::ArgListTy Args;
- if (Intrinsic == Intrinsic::ubsantrap) {
- Args.push_back(TargetLoweringBase::ArgListEntry());
- Args[0].Val = I.getArgOperand(0);
- Args[0].Node = getValue(Args[0].Val);
- Args[0].Ty = Args[0].Val->getType();
- }
+ if (Intrinsic == Intrinsic::ubsantrap) {
+ Args.push_back(TargetLoweringBase::ArgListEntry());
+ Args[0].Val = I.getArgOperand(0);
+ Args[0].Node = getValue(Args[0].Val);
+ Args[0].Ty = Args[0].Val->getType();
+ }
TargetLowering::CallLoweringInfo CLI(DAG);
CLI.setDebugLoc(sdl).setChain(getRoot()).setLibCallee(
@@ -6602,7 +6602,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
EVT OverflowVT = MVT::i1;
if (ResultVT.isVector())
OverflowVT = EVT::getVectorVT(
- *Context, OverflowVT, ResultVT.getVectorElementCount());
+ *Context, OverflowVT, ResultVT.getVectorElementCount());
SDVTList VTs = DAG.getVTList(ResultVT, OverflowVT);
setValue(&I, DAG.getNode(Op, sdl, VTs, Op1, Op2));
@@ -6640,7 +6640,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
cast<ConstantInt>(I.getArgOperand(0))->getSExtValue();
Value *const ObjectPtr = I.getArgOperand(1);
SmallVector<const Value *, 4> Allocas;
- getUnderlyingObjects(ObjectPtr, Allocas);
+ getUnderlyingObjects(ObjectPtr, Allocas);
for (SmallVectorImpl<const Value*>::iterator Object = Allocas.begin(),
E = Allocas.end(); Object != E; ++Object) {
@@ -6667,14 +6667,14 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
}
return;
}
- case Intrinsic::pseudoprobe: {
- auto Guid = cast<ConstantInt>(I.getArgOperand(0))->getZExtValue();
- auto Index = cast<ConstantInt>(I.getArgOperand(1))->getZExtValue();
- auto Attr = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue();
- Res = DAG.getPseudoProbeNode(sdl, getRoot(), Guid, Index, Attr);
- DAG.setRoot(Res);
- return;
- }
+ case Intrinsic::pseudoprobe: {
+ auto Guid = cast<ConstantInt>(I.getArgOperand(0))->getZExtValue();
+ auto Index = cast<ConstantInt>(I.getArgOperand(1))->getZExtValue();
+ auto Attr = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue();
+ Res = DAG.getPseudoProbeNode(sdl, getRoot(), Guid, Index, Attr);
+ DAG.setRoot(Res);
+ return;
+ }
case Intrinsic::invariant_start:
// Discard region information.
setValue(&I, DAG.getUNDEF(TLI.getPointerTy(DAG.getDataLayout())));
@@ -6785,7 +6785,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
// specific calling convention, and only for x86_64.
// FIXME: Support other platforms later.
const auto &Triple = DAG.getTarget().getTargetTriple();
- if (Triple.getArch() != Triple::x86_64)
+ if (Triple.getArch() != Triple::x86_64)
return;
SDLoc DL = getCurSDLoc();
@@ -6816,7 +6816,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
// specific calling convention, and only for x86_64.
// FIXME: Support other platforms later.
const auto &Triple = DAG.getTarget().getTargetTriple();
- if (Triple.getArch() != Triple::x86_64)
+ if (Triple.getArch() != Triple::x86_64)
return;
SDLoc DL = getCurSDLoc();
@@ -6850,19 +6850,19 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
LowerDeoptimizeCall(&I);
return;
- case Intrinsic::vector_reduce_fadd:
- case Intrinsic::vector_reduce_fmul:
- case Intrinsic::vector_reduce_add:
- case Intrinsic::vector_reduce_mul:
- case Intrinsic::vector_reduce_and:
- case Intrinsic::vector_reduce_or:
- case Intrinsic::vector_reduce_xor:
- case Intrinsic::vector_reduce_smax:
- case Intrinsic::vector_reduce_smin:
- case Intrinsic::vector_reduce_umax:
- case Intrinsic::vector_reduce_umin:
- case Intrinsic::vector_reduce_fmax:
- case Intrinsic::vector_reduce_fmin:
+ case Intrinsic::vector_reduce_fadd:
+ case Intrinsic::vector_reduce_fmul:
+ case Intrinsic::vector_reduce_add:
+ case Intrinsic::vector_reduce_mul:
+ case Intrinsic::vector_reduce_and:
+ case Intrinsic::vector_reduce_or:
+ case Intrinsic::vector_reduce_xor:
+ case Intrinsic::vector_reduce_smax:
+ case Intrinsic::vector_reduce_smin:
+ case Intrinsic::vector_reduce_umax:
+ case Intrinsic::vector_reduce_umin:
+ case Intrinsic::vector_reduce_fmax:
+ case Intrinsic::vector_reduce_fmin:
visitVectorReduce(I, Intrinsic);
return;
@@ -6950,58 +6950,58 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
case Intrinsic::get_active_lane_mask: {
auto DL = getCurSDLoc();
SDValue Index = getValue(I.getOperand(0));
- SDValue TripCount = getValue(I.getOperand(1));
+ SDValue TripCount = getValue(I.getOperand(1));
Type *ElementTy = I.getOperand(0)->getType();
EVT VT = TLI.getValueType(DAG.getDataLayout(), I.getType());
unsigned VecWidth = VT.getVectorNumElements();
- SmallVector<SDValue, 16> OpsTripCount;
+ SmallVector<SDValue, 16> OpsTripCount;
SmallVector<SDValue, 16> OpsIndex;
SmallVector<SDValue, 16> OpsStepConstants;
for (unsigned i = 0; i < VecWidth; i++) {
- OpsTripCount.push_back(TripCount);
+ OpsTripCount.push_back(TripCount);
OpsIndex.push_back(Index);
- OpsStepConstants.push_back(
- DAG.getConstant(i, DL, EVT::getEVT(ElementTy)));
+ OpsStepConstants.push_back(
+ DAG.getConstant(i, DL, EVT::getEVT(ElementTy)));
}
- EVT CCVT = EVT::getVectorVT(I.getContext(), MVT::i1, VecWidth);
+ EVT CCVT = EVT::getVectorVT(I.getContext(), MVT::i1, VecWidth);
- auto VecTy = EVT::getEVT(FixedVectorType::get(ElementTy, VecWidth));
+ auto VecTy = EVT::getEVT(FixedVectorType::get(ElementTy, VecWidth));
SDValue VectorIndex = DAG.getBuildVector(VecTy, DL, OpsIndex);
SDValue VectorStep = DAG.getBuildVector(VecTy, DL, OpsStepConstants);
SDValue VectorInduction = DAG.getNode(
ISD::UADDO, DL, DAG.getVTList(VecTy, CCVT), VectorIndex, VectorStep);
- SDValue VectorTripCount = DAG.getBuildVector(VecTy, DL, OpsTripCount);
+ SDValue VectorTripCount = DAG.getBuildVector(VecTy, DL, OpsTripCount);
SDValue SetCC = DAG.getSetCC(DL, CCVT, VectorInduction.getValue(0),
- VectorTripCount, ISD::CondCode::SETULT);
+ VectorTripCount, ISD::CondCode::SETULT);
setValue(&I, DAG.getNode(ISD::AND, DL, CCVT,
DAG.getNOT(DL, VectorInduction.getValue(1), CCVT),
SetCC));
return;
}
- case Intrinsic::experimental_vector_insert: {
- auto DL = getCurSDLoc();
-
- SDValue Vec = getValue(I.getOperand(0));
- SDValue SubVec = getValue(I.getOperand(1));
- SDValue Index = getValue(I.getOperand(2));
- EVT ResultVT = TLI.getValueType(DAG.getDataLayout(), I.getType());
- setValue(&I, DAG.getNode(ISD::INSERT_SUBVECTOR, DL, ResultVT, Vec, SubVec,
- Index));
- return;
- }
- case Intrinsic::experimental_vector_extract: {
- auto DL = getCurSDLoc();
-
- SDValue Vec = getValue(I.getOperand(0));
- SDValue Index = getValue(I.getOperand(1));
- EVT ResultVT = TLI.getValueType(DAG.getDataLayout(), I.getType());
-
- setValue(&I, DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, ResultVT, Vec, Index));
- return;
- }
- }
+ case Intrinsic::experimental_vector_insert: {
+ auto DL = getCurSDLoc();
+
+ SDValue Vec = getValue(I.getOperand(0));
+ SDValue SubVec = getValue(I.getOperand(1));
+ SDValue Index = getValue(I.getOperand(2));
+ EVT ResultVT = TLI.getValueType(DAG.getDataLayout(), I.getType());
+ setValue(&I, DAG.getNode(ISD::INSERT_SUBVECTOR, DL, ResultVT, Vec, SubVec,
+ Index));
+ return;
+ }
+ case Intrinsic::experimental_vector_extract: {
+ auto DL = getCurSDLoc();
+
+ SDValue Vec = getValue(I.getOperand(0));
+ SDValue Index = getValue(I.getOperand(1));
+ EVT ResultVT = TLI.getValueType(DAG.getDataLayout(), I.getType());
+
+ setValue(&I, DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, ResultVT, Vec, Index));
+ return;
+ }
+ }
}
void SelectionDAGBuilder::visitConstrainedFPIntrinsic(
@@ -7116,41 +7116,41 @@ void SelectionDAGBuilder::visitConstrainedFPIntrinsic(
setValue(&FPI, FPResult);
}
-static unsigned getISDForVPIntrinsic(const VPIntrinsic &VPIntrin) {
- Optional<unsigned> ResOPC;
- switch (VPIntrin.getIntrinsicID()) {
-#define BEGIN_REGISTER_VP_INTRINSIC(INTRIN, ...) case Intrinsic::INTRIN:
-#define BEGIN_REGISTER_VP_SDNODE(VPSDID, ...) ResOPC = ISD::VPSDID;
-#define END_REGISTER_VP_INTRINSIC(...) break;
-#include "llvm/IR/VPIntrinsics.def"
- }
-
- if (!ResOPC.hasValue())
- llvm_unreachable(
- "Inconsistency: no SDNode available for this VPIntrinsic!");
-
- return ResOPC.getValue();
-}
-
-void SelectionDAGBuilder::visitVectorPredicationIntrinsic(
- const VPIntrinsic &VPIntrin) {
- unsigned Opcode = getISDForVPIntrinsic(VPIntrin);
-
- SmallVector<EVT, 4> ValueVTs;
- const TargetLowering &TLI = DAG.getTargetLoweringInfo();
- ComputeValueVTs(TLI, DAG.getDataLayout(), VPIntrin.getType(), ValueVTs);
- SDVTList VTs = DAG.getVTList(ValueVTs);
-
- // Request operands.
- SmallVector<SDValue, 7> OpValues;
- for (int i = 0; i < (int)VPIntrin.getNumArgOperands(); ++i)
- OpValues.push_back(getValue(VPIntrin.getArgOperand(i)));
-
- SDLoc DL = getCurSDLoc();
- SDValue Result = DAG.getNode(Opcode, DL, VTs, OpValues);
- setValue(&VPIntrin, Result);
-}
-
+static unsigned getISDForVPIntrinsic(const VPIntrinsic &VPIntrin) {
+ Optional<unsigned> ResOPC;
+ switch (VPIntrin.getIntrinsicID()) {
+#define BEGIN_REGISTER_VP_INTRINSIC(INTRIN, ...) case Intrinsic::INTRIN:
+#define BEGIN_REGISTER_VP_SDNODE(VPSDID, ...) ResOPC = ISD::VPSDID;
+#define END_REGISTER_VP_INTRINSIC(...) break;
+#include "llvm/IR/VPIntrinsics.def"
+ }
+
+ if (!ResOPC.hasValue())
+ llvm_unreachable(
+ "Inconsistency: no SDNode available for this VPIntrinsic!");
+
+ return ResOPC.getValue();
+}
+
+void SelectionDAGBuilder::visitVectorPredicationIntrinsic(
+ const VPIntrinsic &VPIntrin) {
+ unsigned Opcode = getISDForVPIntrinsic(VPIntrin);
+
+ SmallVector<EVT, 4> ValueVTs;
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ ComputeValueVTs(TLI, DAG.getDataLayout(), VPIntrin.getType(), ValueVTs);
+ SDVTList VTs = DAG.getVTList(ValueVTs);
+
+ // Request operands.
+ SmallVector<SDValue, 7> OpValues;
+ for (int i = 0; i < (int)VPIntrin.getNumArgOperands(); ++i)
+ OpValues.push_back(getValue(VPIntrin.getArgOperand(i)));
+
+ SDLoc DL = getCurSDLoc();
+ SDValue Result = DAG.getNode(Opcode, DL, VTs, OpValues);
+ setValue(&VPIntrin, Result);
+}
+
std::pair<SDValue, SDValue>
SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI,
const BasicBlock *EHPadBB) {
@@ -7367,9 +7367,9 @@ static SDValue getMemCmpLoad(const Value *PtrVal, MVT LoadVT,
}
SDValue Ptr = Builder.getValue(PtrVal);
- SDValue LoadVal =
- Builder.DAG.getLoad(LoadVT, Builder.getCurSDLoc(), Root, Ptr,
- MachinePointerInfo(PtrVal), Align(1));
+ SDValue LoadVal =
+ Builder.DAG.getLoad(LoadVT, Builder.getCurSDLoc(), Root, Ptr,
+ MachinePointerInfo(PtrVal), Align(1));
if (!ConstantMemory)
Builder.PendingLoads.push_back(LoadVal.getValue(1));
@@ -7390,12 +7390,12 @@ void SelectionDAGBuilder::processIntegerCallValue(const Instruction &I,
setValue(&I, Value);
}
-/// See if we can lower a memcmp/bcmp call into an optimized form. If so, return
+/// See if we can lower a memcmp/bcmp call into an optimized form. If so, return
/// true and lower it. Otherwise return false, and it will be lowered like a
/// normal call.
/// The caller already checked that \p I calls the appropriate LibFunc with a
/// correct prototype.
-bool SelectionDAGBuilder::visitMemCmpBCmpCall(const CallInst &I) {
+bool SelectionDAGBuilder::visitMemCmpBCmpCall(const CallInst &I) {
const Value *LHS = I.getArgOperand(0), *RHS = I.getArgOperand(1);
const Value *Size = I.getArgOperand(2);
const ConstantInt *CSize = dyn_cast<ConstantInt>(Size);
@@ -7646,12 +7646,12 @@ bool SelectionDAGBuilder::visitUnaryFloatCall(const CallInst &I,
if (!I.onlyReadsMemory())
return false;
- SDNodeFlags Flags;
- Flags.copyFMF(cast<FPMathOperator>(I));
-
+ SDNodeFlags Flags;
+ Flags.copyFMF(cast<FPMathOperator>(I));
+
SDValue Tmp = getValue(I.getArgOperand(0));
- setValue(&I,
- DAG.getNode(Opcode, getCurSDLoc(), Tmp.getValueType(), Tmp, Flags));
+ setValue(&I,
+ DAG.getNode(Opcode, getCurSDLoc(), Tmp.getValueType(), Tmp, Flags));
return true;
}
@@ -7666,13 +7666,13 @@ bool SelectionDAGBuilder::visitBinaryFloatCall(const CallInst &I,
if (!I.onlyReadsMemory())
return false;
- SDNodeFlags Flags;
- Flags.copyFMF(cast<FPMathOperator>(I));
-
+ SDNodeFlags Flags;
+ Flags.copyFMF(cast<FPMathOperator>(I));
+
SDValue Tmp0 = getValue(I.getArgOperand(0));
SDValue Tmp1 = getValue(I.getArgOperand(1));
EVT VT = Tmp0.getValueType();
- setValue(&I, DAG.getNode(Opcode, getCurSDLoc(), VT, Tmp0, Tmp1, Flags));
+ setValue(&I, DAG.getNode(Opcode, getCurSDLoc(), VT, Tmp0, Tmp1, Flags));
return true;
}
@@ -7706,10 +7706,10 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
LibInfo->hasOptimizedCodeGen(Func)) {
switch (Func) {
default: break;
- case LibFunc_bcmp:
- if (visitMemCmpBCmpCall(I))
- return;
- break;
+ case LibFunc_bcmp:
+ if (visitMemCmpBCmpCall(I))
+ return;
+ break;
case LibFunc_copysign:
case LibFunc_copysignf:
case LibFunc_copysignl:
@@ -7811,7 +7811,7 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
return;
break;
case LibFunc_memcmp:
- if (visitMemCmpBCmpCall(I))
+ if (visitMemCmpBCmpCall(I))
return;
break;
case LibFunc_mempcpy:
@@ -8231,9 +8231,9 @@ void SelectionDAGBuilder::visitInlineAsm(const CallBase &Call) {
OpInfo.CallOperand = getValue(OpInfo.CallOperandVal);
}
- EVT VT = OpInfo.getCallOperandValEVT(*DAG.getContext(), TLI,
- DAG.getDataLayout());
- OpInfo.ConstraintVT = VT.isSimple() ? VT.getSimpleVT() : MVT::Other;
+ EVT VT = OpInfo.getCallOperandValEVT(*DAG.getContext(), TLI,
+ DAG.getDataLayout());
+ OpInfo.ConstraintVT = VT.isSimple() ? VT.getSimpleVT() : MVT::Other;
} else if (OpInfo.Type == InlineAsm::isOutput && !OpInfo.isIndirect) {
// The return value of the call is this value. As such, there is no
// corresponding argument.
@@ -8495,7 +8495,7 @@ void SelectionDAGBuilder::visitInlineAsm(const CallBase &Call) {
InlineAsm::getFlagWord(InlineAsm::Kind_Imm, Ops.size());
AsmNodeOperands.push_back(DAG.getTargetConstant(
ResOpType, getCurSDLoc(), TLI.getPointerTy(DAG.getDataLayout())));
- llvm::append_range(AsmNodeOperands, Ops);
+ llvm::append_range(AsmNodeOperands, Ops);
break;
}
@@ -9075,59 +9075,59 @@ void SelectionDAGBuilder::visitVectorReduce(const CallInst &I,
SDLoc dl = getCurSDLoc();
EVT VT = TLI.getValueType(DAG.getDataLayout(), I.getType());
SDValue Res;
- SDNodeFlags SDFlags;
- if (auto *FPMO = dyn_cast<FPMathOperator>(&I))
- SDFlags.copyFMF(*FPMO);
+ SDNodeFlags SDFlags;
+ if (auto *FPMO = dyn_cast<FPMathOperator>(&I))
+ SDFlags.copyFMF(*FPMO);
switch (Intrinsic) {
- case Intrinsic::vector_reduce_fadd:
- if (SDFlags.hasAllowReassociation())
+ case Intrinsic::vector_reduce_fadd:
+ if (SDFlags.hasAllowReassociation())
Res = DAG.getNode(ISD::FADD, dl, VT, Op1,
- DAG.getNode(ISD::VECREDUCE_FADD, dl, VT, Op2, SDFlags),
- SDFlags);
+ DAG.getNode(ISD::VECREDUCE_FADD, dl, VT, Op2, SDFlags),
+ SDFlags);
else
- Res = DAG.getNode(ISD::VECREDUCE_SEQ_FADD, dl, VT, Op1, Op2, SDFlags);
+ Res = DAG.getNode(ISD::VECREDUCE_SEQ_FADD, dl, VT, Op1, Op2, SDFlags);
break;
- case Intrinsic::vector_reduce_fmul:
- if (SDFlags.hasAllowReassociation())
+ case Intrinsic::vector_reduce_fmul:
+ if (SDFlags.hasAllowReassociation())
Res = DAG.getNode(ISD::FMUL, dl, VT, Op1,
- DAG.getNode(ISD::VECREDUCE_FMUL, dl, VT, Op2, SDFlags),
- SDFlags);
+ DAG.getNode(ISD::VECREDUCE_FMUL, dl, VT, Op2, SDFlags),
+ SDFlags);
else
- Res = DAG.getNode(ISD::VECREDUCE_SEQ_FMUL, dl, VT, Op1, Op2, SDFlags);
+ Res = DAG.getNode(ISD::VECREDUCE_SEQ_FMUL, dl, VT, Op1, Op2, SDFlags);
break;
- case Intrinsic::vector_reduce_add:
+ case Intrinsic::vector_reduce_add:
Res = DAG.getNode(ISD::VECREDUCE_ADD, dl, VT, Op1);
break;
- case Intrinsic::vector_reduce_mul:
+ case Intrinsic::vector_reduce_mul:
Res = DAG.getNode(ISD::VECREDUCE_MUL, dl, VT, Op1);
break;
- case Intrinsic::vector_reduce_and:
+ case Intrinsic::vector_reduce_and:
Res = DAG.getNode(ISD::VECREDUCE_AND, dl, VT, Op1);
break;
- case Intrinsic::vector_reduce_or:
+ case Intrinsic::vector_reduce_or:
Res = DAG.getNode(ISD::VECREDUCE_OR, dl, VT, Op1);
break;
- case Intrinsic::vector_reduce_xor:
+ case Intrinsic::vector_reduce_xor:
Res = DAG.getNode(ISD::VECREDUCE_XOR, dl, VT, Op1);
break;
- case Intrinsic::vector_reduce_smax:
+ case Intrinsic::vector_reduce_smax:
Res = DAG.getNode(ISD::VECREDUCE_SMAX, dl, VT, Op1);
break;
- case Intrinsic::vector_reduce_smin:
+ case Intrinsic::vector_reduce_smin:
Res = DAG.getNode(ISD::VECREDUCE_SMIN, dl, VT, Op1);
break;
- case Intrinsic::vector_reduce_umax:
+ case Intrinsic::vector_reduce_umax:
Res = DAG.getNode(ISD::VECREDUCE_UMAX, dl, VT, Op1);
break;
- case Intrinsic::vector_reduce_umin:
+ case Intrinsic::vector_reduce_umin:
Res = DAG.getNode(ISD::VECREDUCE_UMIN, dl, VT, Op1);
break;
- case Intrinsic::vector_reduce_fmax:
- Res = DAG.getNode(ISD::VECREDUCE_FMAX, dl, VT, Op1, SDFlags);
+ case Intrinsic::vector_reduce_fmax:
+ Res = DAG.getNode(ISD::VECREDUCE_FMAX, dl, VT, Op1, SDFlags);
break;
- case Intrinsic::vector_reduce_fmin:
- Res = DAG.getNode(ISD::VECREDUCE_FMIN, dl, VT, Op1, SDFlags);
+ case Intrinsic::vector_reduce_fmin:
+ Res = DAG.getNode(ISD::VECREDUCE_FMIN, dl, VT, Op1, SDFlags);
break;
default:
llvm_unreachable("Unhandled vector reduce intrinsic");
@@ -9214,7 +9214,7 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
Entry.IsSRet = true;
Entry.IsNest = false;
Entry.IsByVal = false;
- Entry.IsByRef = false;
+ Entry.IsByRef = false;
Entry.IsReturned = false;
Entry.IsSwiftSelf = false;
Entry.IsSwiftError = false;
@@ -9335,8 +9335,8 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
Flags.setCFGuardTarget();
if (Args[i].IsByVal)
Flags.setByVal();
- if (Args[i].IsByRef)
- Flags.setByRef();
+ if (Args[i].IsByRef)
+ Flags.setByRef();
if (Args[i].IsPreallocated) {
Flags.setPreallocated();
// Set the byval flag for CCAssignFn callbacks that don't know about
@@ -9542,33 +9542,33 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
return std::make_pair(Res, CLI.Chain);
}
-/// Places new result values for the node in Results (their number
-/// and types must exactly match those of the original return values of
-/// the node), or leaves Results empty, which indicates that the node is not
-/// to be custom lowered after all.
+/// Places new result values for the node in Results (their number
+/// and types must exactly match those of the original return values of
+/// the node), or leaves Results empty, which indicates that the node is not
+/// to be custom lowered after all.
void TargetLowering::LowerOperationWrapper(SDNode *N,
SmallVectorImpl<SDValue> &Results,
SelectionDAG &DAG) const {
- SDValue Res = LowerOperation(SDValue(N, 0), DAG);
-
- if (!Res.getNode())
- return;
-
- // If the original node has one result, take the return value from
- // LowerOperation as is. It might not be result number 0.
- if (N->getNumValues() == 1) {
+ SDValue Res = LowerOperation(SDValue(N, 0), DAG);
+
+ if (!Res.getNode())
+ return;
+
+ // If the original node has one result, take the return value from
+ // LowerOperation as is. It might not be result number 0.
+ if (N->getNumValues() == 1) {
Results.push_back(Res);
- return;
- }
-
- // If the original node has multiple results, then the return node should
- // have the same number of results.
- assert((N->getNumValues() == Res->getNumValues()) &&
- "Lowering returned the wrong number of results!");
-
- // Places new result values base on N result number.
- for (unsigned I = 0, E = N->getNumValues(); I != E; ++I)
- Results.push_back(Res.getValue(I));
+ return;
+ }
+
+ // If the original node has multiple results, then the return node should
+ // have the same number of results.
+ assert((N->getNumValues() == Res->getNumValues()) &&
+ "Lowering returned the wrong number of results!");
+
+ // Places new result values base on N result number.
+ for (unsigned I = 0, E = N->getNumValues(); I != E; ++I)
+ Results.push_back(Res.getValue(I));
}
SDValue TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
@@ -9660,9 +9660,9 @@ findArgumentCopyElisionCandidates(const DataLayout &DL,
// We will look through cast uses, so ignore them completely.
if (I.isCast())
continue;
- // Ignore debug info and pseudo op intrinsics, they don't escape or store
- // to allocas.
- if (I.isDebugOrPseudoInst())
+ // Ignore debug info and pseudo op intrinsics, they don't escape or store
+ // to allocas.
+ if (I.isDebugOrPseudoInst())
continue;
// This is an unknown instruction. Assume it escapes or writes to all
// static alloca operands.
@@ -9692,7 +9692,7 @@ findArgumentCopyElisionCandidates(const DataLayout &DL,
// initializes the alloca. Don't elide copies from the same argument twice.
const Value *Val = SI->getValueOperand()->stripPointerCasts();
const auto *Arg = dyn_cast<Argument>(Val);
- if (!Arg || Arg->hasPassPointeeByValueCopyAttr() ||
+ if (!Arg || Arg->hasPassPointeeByValueCopyAttr() ||
Arg->getType()->isEmptyTy() ||
DL.getTypeStoreSize(Arg->getType()) !=
DL.getTypeAllocSize(AI->getAllocatedType()) ||
@@ -9873,8 +9873,8 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
Flags.setSwiftError();
if (Arg.hasAttribute(Attribute::ByVal))
Flags.setByVal();
- if (Arg.hasAttribute(Attribute::ByRef))
- Flags.setByRef();
+ if (Arg.hasAttribute(Attribute::ByRef))
+ Flags.setByRef();
if (Arg.hasAttribute(Attribute::InAlloca)) {
Flags.setInAlloca();
// Set the byval flag for CCAssignFn callbacks that don't know about
@@ -9894,30 +9894,30 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
Flags.setByVal();
}
- Type *ArgMemTy = nullptr;
- if (Flags.isByVal() || Flags.isInAlloca() || Flags.isPreallocated() ||
- Flags.isByRef()) {
- if (!ArgMemTy)
- ArgMemTy = Arg.getPointeeInMemoryValueType();
-
- uint64_t MemSize = DL.getTypeAllocSize(ArgMemTy);
-
- // For in-memory arguments, size and alignment should be passed from FE.
- // BE will guess if this info is not there but there are cases it cannot
- // get right.
- MaybeAlign MemAlign = Arg.getParamAlign();
- if (!MemAlign)
- MemAlign = Align(TLI->getByValTypeAlignment(ArgMemTy, DL));
-
- if (Flags.isByRef()) {
- Flags.setByRefSize(MemSize);
- Flags.setByRefAlign(*MemAlign);
- } else {
- Flags.setByValSize(MemSize);
- Flags.setByValAlign(*MemAlign);
- }
+ Type *ArgMemTy = nullptr;
+ if (Flags.isByVal() || Flags.isInAlloca() || Flags.isPreallocated() ||
+ Flags.isByRef()) {
+ if (!ArgMemTy)
+ ArgMemTy = Arg.getPointeeInMemoryValueType();
+
+ uint64_t MemSize = DL.getTypeAllocSize(ArgMemTy);
+
+ // For in-memory arguments, size and alignment should be passed from FE.
+ // BE will guess if this info is not there but there are cases it cannot
+ // get right.
+ MaybeAlign MemAlign = Arg.getParamAlign();
+ if (!MemAlign)
+ MemAlign = Align(TLI->getByValTypeAlignment(ArgMemTy, DL));
+
+ if (Flags.isByRef()) {
+ Flags.setByRefSize(MemSize);
+ Flags.setByRefAlign(*MemAlign);
+ } else {
+ Flags.setByValSize(MemSize);
+ Flags.setByValAlign(*MemAlign);
+ }
}
-
+
if (Arg.hasAttribute(Attribute::Nest))
Flags.setNest();
if (NeedsRegBlock)
@@ -10794,7 +10794,7 @@ void SelectionDAGBuilder::visitSwitch(const SwitchInst &SI) {
{PeeledSwitchMBB, First, Last, nullptr, nullptr, DefaultProb});
while (!WorkList.empty()) {
- SwitchWorkListItem W = WorkList.pop_back_val();
+ SwitchWorkListItem W = WorkList.pop_back_val();
unsigned NumClusters = W.LastCluster - W.FirstCluster + 1;
if (NumClusters > 3 && TM.getOptLevel() != CodeGenOpt::None &&
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
index 97f09350cd..8f6e98c401 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -37,7 +37,7 @@
namespace llvm {
-class AAResults;
+class AAResults;
class AllocaInst;
class AtomicCmpXchgInst;
class AtomicRMWInst;
@@ -62,7 +62,7 @@ class FunctionLoweringInfo;
class GCFunctionInfo;
class GCRelocateInst;
class GCResultInst;
-class GCStatepointInst;
+class GCStatepointInst;
class IndirectBrInst;
class InvokeInst;
class LandingPadInst;
@@ -388,7 +388,7 @@ public:
SelectionDAG &DAG;
const DataLayout *DL = nullptr;
- AAResults *AA = nullptr;
+ AAResults *AA = nullptr;
const TargetLibraryInfo *LibInfo;
class SDAGSwitchLowering : public SwitchCG::SwitchLowering {
@@ -442,7 +442,7 @@ public:
SL(std::make_unique<SDAGSwitchLowering>(this, funcinfo)), FuncInfo(funcinfo),
SwiftError(swifterror) {}
- void init(GCFunctionInfo *gfi, AAResults *AA,
+ void init(GCFunctionInfo *gfi, AAResults *AA,
const TargetLibraryInfo *li);
/// Clear out the current SelectionDAG and the associated state and prepare
@@ -685,7 +685,7 @@ private:
void visitAdd(const User &I) { visitBinary(I, ISD::ADD); }
void visitFAdd(const User &I) { visitBinary(I, ISD::FADD); }
void visitSub(const User &I) { visitBinary(I, ISD::SUB); }
- void visitFSub(const User &I) { visitBinary(I, ISD::FSUB); }
+ void visitFSub(const User &I) { visitBinary(I, ISD::FSUB); }
void visitMul(const User &I) { visitBinary(I, ISD::MUL); }
void visitFMul(const User &I) { visitBinary(I, ISD::FMUL); }
void visitURem(const User &I) { visitBinary(I, ISD::UREM); }
@@ -740,7 +740,7 @@ private:
void visitFence(const FenceInst &I);
void visitPHI(const PHINode &I);
void visitCall(const CallInst &I);
- bool visitMemCmpBCmpCall(const CallInst &I);
+ bool visitMemCmpBCmpCall(const CallInst &I);
bool visitMemPCpyCall(const CallInst &I);
bool visitMemChrCall(const CallInst &I);
bool visitStrCpyCall(const CallInst &I, bool isStpcpy);
@@ -759,7 +759,7 @@ private:
void visitIntrinsicCall(const CallInst &I, unsigned Intrinsic);
void visitTargetIntrinsic(const CallInst &I, unsigned Intrinsic);
void visitConstrainedFPIntrinsic(const ConstrainedFPIntrinsic &FPI);
- void visitVectorPredicationIntrinsic(const VPIntrinsic &VPIntrin);
+ void visitVectorPredicationIntrinsic(const VPIntrinsic &VPIntrin);
void visitVAStart(const CallInst &I);
void visitVAArg(const VAArgInst &I);
@@ -896,7 +896,7 @@ struct RegsForValue {
}
/// Return a list of registers and their sizes.
- SmallVector<std::pair<unsigned, TypeSize>, 4> getRegsAndSizes() const;
+ SmallVector<std::pair<unsigned, TypeSize>, 4> getRegsAndSizes() const;
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index 8e0502abb3..d867f3e09e 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -293,7 +293,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::ADDC: return "addc";
case ISD::ADDE: return "adde";
case ISD::ADDCARRY: return "addcarry";
- case ISD::SADDO_CARRY: return "saddo_carry";
+ case ISD::SADDO_CARRY: return "saddo_carry";
case ISD::SADDO: return "saddo";
case ISD::UADDO: return "uaddo";
case ISD::SSUBO: return "ssubo";
@@ -303,7 +303,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::SUBC: return "subc";
case ISD::SUBE: return "sube";
case ISD::SUBCARRY: return "subcarry";
- case ISD::SSUBO_CARRY: return "ssubo_carry";
+ case ISD::SSUBO_CARRY: return "ssubo_carry";
case ISD::SHL_PARTS: return "shl_parts";
case ISD::SRA_PARTS: return "sra_parts";
case ISD::SRL_PARTS: return "srl_parts";
@@ -312,8 +312,8 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::UADDSAT: return "uaddsat";
case ISD::SSUBSAT: return "ssubsat";
case ISD::USUBSAT: return "usubsat";
- case ISD::SSHLSAT: return "sshlsat";
- case ISD::USHLSAT: return "ushlsat";
+ case ISD::SSHLSAT: return "sshlsat";
+ case ISD::USHLSAT: return "ushlsat";
case ISD::SMULFIX: return "smulfix";
case ISD::SMULFIXSAT: return "smulfixsat";
@@ -348,8 +348,8 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::STRICT_FP_TO_SINT: return "strict_fp_to_sint";
case ISD::FP_TO_UINT: return "fp_to_uint";
case ISD::STRICT_FP_TO_UINT: return "strict_fp_to_uint";
- case ISD::FP_TO_SINT_SAT: return "fp_to_sint_sat";
- case ISD::FP_TO_UINT_SAT: return "fp_to_uint_sat";
+ case ISD::FP_TO_SINT_SAT: return "fp_to_sint_sat";
+ case ISD::FP_TO_UINT_SAT: return "fp_to_uint_sat";
case ISD::BITCAST: return "bitcast";
case ISD::ADDRSPACECAST: return "addrspacecast";
case ISD::FP16_TO_FP: return "fp16_to_fp";
@@ -396,11 +396,11 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::STACKRESTORE: return "stackrestore";
case ISD::TRAP: return "trap";
case ISD::DEBUGTRAP: return "debugtrap";
- case ISD::UBSANTRAP: return "ubsantrap";
+ case ISD::UBSANTRAP: return "ubsantrap";
case ISD::LIFETIME_START: return "lifetime.start";
case ISD::LIFETIME_END: return "lifetime.end";
- case ISD::PSEUDO_PROBE:
- return "pseudoprobe";
+ case ISD::PSEUDO_PROBE:
+ return "pseudoprobe";
case ISD::GC_TRANSITION_START: return "gc_transition.start";
case ISD::GC_TRANSITION_END: return "gc_transition.end";
case ISD::GET_DYNAMIC_AREA_OFFSET: return "get.dynamic.area.offset";
@@ -419,7 +419,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::CTTZ_ZERO_UNDEF: return "cttz_zero_undef";
case ISD::CTLZ: return "ctlz";
case ISD::CTLZ_ZERO_UNDEF: return "ctlz_zero_undef";
- case ISD::PARITY: return "parity";
+ case ISD::PARITY: return "parity";
// Trampolines
case ISD::INIT_TRAMPOLINE: return "init_trampoline";
@@ -457,9 +457,9 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::SETFALSE2: return "setfalse2";
}
case ISD::VECREDUCE_FADD: return "vecreduce_fadd";
- case ISD::VECREDUCE_SEQ_FADD: return "vecreduce_seq_fadd";
+ case ISD::VECREDUCE_SEQ_FADD: return "vecreduce_seq_fadd";
case ISD::VECREDUCE_FMUL: return "vecreduce_fmul";
- case ISD::VECREDUCE_SEQ_FMUL: return "vecreduce_seq_fmul";
+ case ISD::VECREDUCE_SEQ_FMUL: return "vecreduce_seq_fmul";
case ISD::VECREDUCE_ADD: return "vecreduce_add";
case ISD::VECREDUCE_MUL: return "vecreduce_mul";
case ISD::VECREDUCE_AND: return "vecreduce_and";
@@ -471,12 +471,12 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::VECREDUCE_UMIN: return "vecreduce_umin";
case ISD::VECREDUCE_FMAX: return "vecreduce_fmax";
case ISD::VECREDUCE_FMIN: return "vecreduce_fmin";
-
- // Vector Predication
-#define BEGIN_REGISTER_VP_SDNODE(SDID, LEGALARG, NAME, ...) \
- case ISD::SDID: \
- return #NAME;
-#include "llvm/IR/VPIntrinsics.def"
+
+ // Vector Predication
+#define BEGIN_REGISTER_VP_SDNODE(SDID, LEGALARG, NAME, ...) \
+ case ISD::SDID: \
+ return #NAME;
+#include "llvm/IR/VPIntrinsics.def"
}
}
@@ -746,39 +746,39 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
OS << ", compressing";
OS << ">";
- } else if (const auto *MGather = dyn_cast<MaskedGatherSDNode>(this)) {
+ } else if (const auto *MGather = dyn_cast<MaskedGatherSDNode>(this)) {
+ OS << "<";
+ printMemOperand(OS, *MGather->getMemOperand(), G);
+
+ bool doExt = true;
+ switch (MGather->getExtensionType()) {
+ default: doExt = false; break;
+ case ISD::EXTLOAD: OS << ", anyext"; break;
+ case ISD::SEXTLOAD: OS << ", sext"; break;
+ case ISD::ZEXTLOAD: OS << ", zext"; break;
+ }
+ if (doExt)
+ OS << " from " << MGather->getMemoryVT().getEVTString();
+
+ auto Signed = MGather->isIndexSigned() ? "signed" : "unsigned";
+ auto Scaled = MGather->isIndexScaled() ? "scaled" : "unscaled";
+ OS << ", " << Signed << " " << Scaled << " offset";
+
+ OS << ">";
+ } else if (const auto *MScatter = dyn_cast<MaskedScatterSDNode>(this)) {
+ OS << "<";
+ printMemOperand(OS, *MScatter->getMemOperand(), G);
+
+ if (MScatter->isTruncatingStore())
+ OS << ", trunc to " << MScatter->getMemoryVT().getEVTString();
+
+ auto Signed = MScatter->isIndexSigned() ? "signed" : "unsigned";
+ auto Scaled = MScatter->isIndexScaled() ? "scaled" : "unscaled";
+ OS << ", " << Signed << " " << Scaled << " offset";
+
+ OS << ">";
+ } else if (const MemSDNode *M = dyn_cast<MemSDNode>(this)) {
OS << "<";
- printMemOperand(OS, *MGather->getMemOperand(), G);
-
- bool doExt = true;
- switch (MGather->getExtensionType()) {
- default: doExt = false; break;
- case ISD::EXTLOAD: OS << ", anyext"; break;
- case ISD::SEXTLOAD: OS << ", sext"; break;
- case ISD::ZEXTLOAD: OS << ", zext"; break;
- }
- if (doExt)
- OS << " from " << MGather->getMemoryVT().getEVTString();
-
- auto Signed = MGather->isIndexSigned() ? "signed" : "unsigned";
- auto Scaled = MGather->isIndexScaled() ? "scaled" : "unscaled";
- OS << ", " << Signed << " " << Scaled << " offset";
-
- OS << ">";
- } else if (const auto *MScatter = dyn_cast<MaskedScatterSDNode>(this)) {
- OS << "<";
- printMemOperand(OS, *MScatter->getMemOperand(), G);
-
- if (MScatter->isTruncatingStore())
- OS << ", trunc to " << MScatter->getMemoryVT().getEVTString();
-
- auto Signed = MScatter->isIndexSigned() ? "signed" : "unsigned";
- auto Scaled = MScatter->isIndexScaled() ? "scaled" : "unscaled";
- OS << ", " << Signed << " " << Scaled << " offset";
-
- OS << ">";
- } else if (const MemSDNode *M = dyn_cast<MemSDNode>(this)) {
- OS << "<";
printMemOperand(OS, *M->getMemOperand(), G);
OS << ">";
} else if (const BlockAddressSDNode *BA =
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 0bb4a5d06e..d17dd1c5ec 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -75,7 +75,7 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/IR/Metadata.h"
-#include "llvm/IR/Statepoint.h"
+#include "llvm/IR/Statepoint.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
@@ -779,11 +779,11 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
<< "'\n";
CurDAG->dump());
-#ifndef NDEBUG
- if (TTI.hasBranchDivergence())
- CurDAG->VerifyDAGDiverence();
-#endif
-
+#ifndef NDEBUG
+ if (TTI.hasBranchDivergence())
+ CurDAG->VerifyDAGDiverence();
+#endif
+
if (ViewDAGCombine1 && MatchFilterBB)
CurDAG->viewGraph("dag-combine1 input for " + BlockName);
@@ -794,11 +794,11 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
CurDAG->Combine(BeforeLegalizeTypes, AA, OptLevel);
}
- LLVM_DEBUG(dbgs() << "Optimized lowered selection DAG: "
- << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
- << "'\n";
- CurDAG->dump());
-
+ LLVM_DEBUG(dbgs() << "Optimized lowered selection DAG: "
+ << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
+ << "'\n";
+ CurDAG->dump());
+
#ifndef NDEBUG
if (TTI.hasBranchDivergence())
CurDAG->VerifyDAGDiverence();
@@ -816,11 +816,11 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
Changed = CurDAG->LegalizeTypes();
}
- LLVM_DEBUG(dbgs() << "Type-legalized selection DAG: "
- << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
- << "'\n";
- CurDAG->dump());
-
+ LLVM_DEBUG(dbgs() << "Type-legalized selection DAG: "
+ << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
+ << "'\n";
+ CurDAG->dump());
+
#ifndef NDEBUG
if (TTI.hasBranchDivergence())
CurDAG->VerifyDAGDiverence();
@@ -840,11 +840,11 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
CurDAG->Combine(AfterLegalizeTypes, AA, OptLevel);
}
- LLVM_DEBUG(dbgs() << "Optimized type-legalized selection DAG: "
- << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
- << "'\n";
- CurDAG->dump());
-
+ LLVM_DEBUG(dbgs() << "Optimized type-legalized selection DAG: "
+ << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
+ << "'\n";
+ CurDAG->dump());
+
#ifndef NDEBUG
if (TTI.hasBranchDivergence())
CurDAG->VerifyDAGDiverence();
@@ -863,11 +863,11 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
<< "'\n";
CurDAG->dump());
-#ifndef NDEBUG
- if (TTI.hasBranchDivergence())
- CurDAG->VerifyDAGDiverence();
-#endif
-
+#ifndef NDEBUG
+ if (TTI.hasBranchDivergence())
+ CurDAG->VerifyDAGDiverence();
+#endif
+
{
NamedRegionTimer T("legalize_types2", "Type Legalization 2", GroupName,
GroupDescription, TimePassesIsEnabled);
@@ -879,11 +879,11 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
<< "'\n";
CurDAG->dump());
-#ifndef NDEBUG
- if (TTI.hasBranchDivergence())
- CurDAG->VerifyDAGDiverence();
-#endif
-
+#ifndef NDEBUG
+ if (TTI.hasBranchDivergence())
+ CurDAG->VerifyDAGDiverence();
+#endif
+
if (ViewDAGCombineLT && MatchFilterBB)
CurDAG->viewGraph("dag-combine-lv input for " + BlockName);
@@ -914,11 +914,11 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
CurDAG->Legalize();
}
- LLVM_DEBUG(dbgs() << "Legalized selection DAG: "
- << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
- << "'\n";
- CurDAG->dump());
-
+ LLVM_DEBUG(dbgs() << "Legalized selection DAG: "
+ << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
+ << "'\n";
+ CurDAG->dump());
+
#ifndef NDEBUG
if (TTI.hasBranchDivergence())
CurDAG->VerifyDAGDiverence();
@@ -934,11 +934,11 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
CurDAG->Combine(AfterLegalizeDAG, AA, OptLevel);
}
- LLVM_DEBUG(dbgs() << "Optimized legalized selection DAG: "
- << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
- << "'\n";
- CurDAG->dump());
-
+ LLVM_DEBUG(dbgs() << "Optimized legalized selection DAG: "
+ << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
+ << "'\n";
+ CurDAG->dump());
+
#ifndef NDEBUG
if (TTI.hasBranchDivergence())
CurDAG->VerifyDAGDiverence();
@@ -1267,12 +1267,12 @@ bool SelectionDAGISel::PrepareEHLandingPad() {
BuildMI(*MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(), II)
.addSym(Label);
- // If the unwinder does not preserve all registers, ensure that the
- // function marks the clobbered registers as used.
- const TargetRegisterInfo &TRI = *MF->getSubtarget().getRegisterInfo();
- if (auto *RegMask = TRI.getCustomEHPadPreservedMask(*MF))
- MF->getRegInfo().addPhysRegsUsedFromRegMask(RegMask);
-
+ // If the unwinder does not preserve all registers, ensure that the
+ // function marks the clobbered registers as used.
+ const TargetRegisterInfo &TRI = *MF->getSubtarget().getRegisterInfo();
+ if (auto *RegMask = TRI.getCustomEHPadPreservedMask(*MF))
+ MF->getRegInfo().addPhysRegsUsedFromRegMask(RegMask);
+
if (Pers == EHPersonality::Wasm_CXX) {
if (const auto *CPI = dyn_cast<CatchPadInst>(LLVMBB->getFirstNonPHI()))
mapWasmLandingPadIndex(MBB, CPI);
@@ -1691,8 +1691,8 @@ static bool MIIsInTerminatorSequence(const MachineInstr &MI) {
/// terminator, but additionally the copies that move the vregs into the
/// physical registers.
static MachineBasicBlock::iterator
-FindSplitPointForStackProtector(MachineBasicBlock *BB,
- const TargetInstrInfo &TII) {
+FindSplitPointForStackProtector(MachineBasicBlock *BB,
+ const TargetInstrInfo &TII) {
MachineBasicBlock::iterator SplitPoint = BB->getFirstTerminator();
if (SplitPoint == BB->begin())
return SplitPoint;
@@ -1701,31 +1701,31 @@ FindSplitPointForStackProtector(MachineBasicBlock *BB,
MachineBasicBlock::iterator Previous = SplitPoint;
--Previous;
- if (TII.isTailCall(*SplitPoint) &&
- Previous->getOpcode() == TII.getCallFrameDestroyOpcode()) {
- // call itself, then we must insert before the sequence even starts. For
- // example:
- // <split point>
- // ADJCALLSTACKDOWN ...
- // <Moves>
- // ADJCALLSTACKUP ...
- // TAILJMP somewhere
- // On the other hand, it could be an unrelated call in which case this tail call
- // has to register moves of its own and should be the split point. For example:
- // ADJCALLSTACKDOWN
- // CALL something_else
- // ADJCALLSTACKUP
- // <split point>
- // TAILJMP somewhere
- do {
- --Previous;
- if (Previous->isCall())
- return SplitPoint;
- } while(Previous->getOpcode() != TII.getCallFrameSetupOpcode());
-
- return Previous;
- }
-
+ if (TII.isTailCall(*SplitPoint) &&
+ Previous->getOpcode() == TII.getCallFrameDestroyOpcode()) {
+ // call itself, then we must insert before the sequence even starts. For
+ // example:
+ // <split point>
+ // ADJCALLSTACKDOWN ...
+ // <Moves>
+ // ADJCALLSTACKUP ...
+ // TAILJMP somewhere
+ // On the other hand, it could be an unrelated call in which case this tail call
+ // has to register moves of its own and should be the split point. For example:
+ // ADJCALLSTACKDOWN
+ // CALL something_else
+ // ADJCALLSTACKUP
+ // <split point>
+ // TAILJMP somewhere
+ do {
+ --Previous;
+ if (Previous->isCall())
+ return SplitPoint;
+ } while(Previous->getOpcode() != TII.getCallFrameSetupOpcode());
+
+ return Previous;
+ }
+
while (MIIsInTerminatorSequence(*Previous)) {
SplitPoint = Previous;
if (Previous == Start)
@@ -1765,7 +1765,7 @@ SelectionDAGISel::FinishBasicBlock() {
// Add load and check to the basicblock.
FuncInfo->MBB = ParentMBB;
FuncInfo->InsertPt =
- FindSplitPointForStackProtector(ParentMBB, *TII);
+ FindSplitPointForStackProtector(ParentMBB, *TII);
SDB->visitSPDescriptorParent(SDB->SPDescriptor, ParentMBB);
CurDAG->setRoot(SDB->getRoot());
SDB->clear();
@@ -1784,7 +1784,7 @@ SelectionDAGISel::FinishBasicBlock() {
// register allocation issues caused by us splitting the parent mbb. The
// register allocator will clean up said virtual copies later on.
MachineBasicBlock::iterator SplitPoint =
- FindSplitPointForStackProtector(ParentMBB, *TII);
+ FindSplitPointForStackProtector(ParentMBB, *TII);
// Splice the terminator of ParentMBB into SuccessMBB.
SuccessMBB->splice(SuccessMBB->end(), ParentMBB,
@@ -2119,7 +2119,7 @@ void SelectionDAGISel::SelectInlineAsmMemoryOperands(std::vector<SDValue> &Ops,
InlineAsm::getFlagWord(InlineAsm::Kind_Mem, SelOps.size());
NewFlags = InlineAsm::getFlagWordForMem(NewFlags, ConstraintID);
Ops.push_back(CurDAG->getTargetConstant(NewFlags, DL, MVT::i32));
- llvm::append_range(Ops, SelOps);
+ llvm::append_range(Ops, SelOps);
i += 2;
}
}
@@ -2319,7 +2319,7 @@ void SelectionDAGISel::Select_FREEZE(SDNode *N) {
}
/// GetVBR - decode a vbr encoding whose top bit is set.
-LLVM_ATTRIBUTE_ALWAYS_INLINE static uint64_t
+LLVM_ATTRIBUTE_ALWAYS_INLINE static uint64_t
GetVBR(uint64_t Val, const unsigned char *MatcherTable, unsigned &Idx) {
assert(Val >= 128 && "Not a VBR");
Val &= 127; // Remove first vbr bit.
@@ -2378,7 +2378,7 @@ void SelectionDAGISel::UpdateChains(
// If the node became dead and we haven't already seen it, delete it.
if (ChainNode != NodeToMatch && ChainNode->use_empty() &&
- !llvm::is_contained(NowDeadNodes, ChainNode))
+ !llvm::is_contained(NowDeadNodes, ChainNode))
NowDeadNodes.push_back(ChainNode);
}
}
@@ -2516,9 +2516,9 @@ MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTList,
}
/// CheckSame - Implements OP_CheckSame.
-LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
-CheckSame(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N,
- const SmallVectorImpl<std::pair<SDValue, SDNode *>> &RecordedNodes) {
+LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
+CheckSame(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N,
+ const SmallVectorImpl<std::pair<SDValue, SDNode *>> &RecordedNodes) {
// Accept if it is exactly the same as a previously recorded node.
unsigned RecNo = MatcherTable[MatcherIndex++];
assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
@@ -2526,10 +2526,10 @@ CheckSame(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N,
}
/// CheckChildSame - Implements OP_CheckChildXSame.
-LLVM_ATTRIBUTE_ALWAYS_INLINE static bool CheckChildSame(
- const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N,
- const SmallVectorImpl<std::pair<SDValue, SDNode *>> &RecordedNodes,
- unsigned ChildNo) {
+LLVM_ATTRIBUTE_ALWAYS_INLINE static bool CheckChildSame(
+ const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N,
+ const SmallVectorImpl<std::pair<SDValue, SDNode *>> &RecordedNodes,
+ unsigned ChildNo) {
if (ChildNo >= N.getNumOperands())
return false; // Match fails if out of range child #.
return ::CheckSame(MatcherTable, MatcherIndex, N.getOperand(ChildNo),
@@ -2537,20 +2537,20 @@ LLVM_ATTRIBUTE_ALWAYS_INLINE static bool CheckChildSame(
}
/// CheckPatternPredicate - Implements OP_CheckPatternPredicate.
-LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
+LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckPatternPredicate(const unsigned char *MatcherTable, unsigned &MatcherIndex,
const SelectionDAGISel &SDISel) {
return SDISel.CheckPatternPredicate(MatcherTable[MatcherIndex++]);
}
/// CheckNodePredicate - Implements OP_CheckNodePredicate.
-LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
+LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckNodePredicate(const unsigned char *MatcherTable, unsigned &MatcherIndex,
const SelectionDAGISel &SDISel, SDNode *N) {
return SDISel.CheckNodePredicate(N, MatcherTable[MatcherIndex++]);
}
-LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
+LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckOpcode(const unsigned char *MatcherTable, unsigned &MatcherIndex,
SDNode *N) {
uint16_t Opc = MatcherTable[MatcherIndex++];
@@ -2558,7 +2558,7 @@ CheckOpcode(const unsigned char *MatcherTable, unsigned &MatcherIndex,
return N->getOpcode() == Opc;
}
-LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
+LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckType(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N,
const TargetLowering *TLI, const DataLayout &DL) {
MVT::SimpleValueType VT = (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
@@ -2568,7 +2568,7 @@ CheckType(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N,
return VT == MVT::iPTR && N.getValueType() == TLI->getPointerTy(DL);
}
-LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
+LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckChildType(const unsigned char *MatcherTable, unsigned &MatcherIndex,
SDValue N, const TargetLowering *TLI, const DataLayout &DL,
unsigned ChildNo) {
@@ -2578,14 +2578,14 @@ CheckChildType(const unsigned char *MatcherTable, unsigned &MatcherIndex,
DL);
}
-LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
+LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckCondCode(const unsigned char *MatcherTable, unsigned &MatcherIndex,
SDValue N) {
return cast<CondCodeSDNode>(N)->get() ==
(ISD::CondCode)MatcherTable[MatcherIndex++];
}
-LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
+LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckChild2CondCode(const unsigned char *MatcherTable, unsigned &MatcherIndex,
SDValue N) {
if (2 >= N.getNumOperands())
@@ -2593,7 +2593,7 @@ CheckChild2CondCode(const unsigned char *MatcherTable, unsigned &MatcherIndex,
return ::CheckCondCode(MatcherTable, MatcherIndex, N.getOperand(2));
}
-LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
+LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckValueType(const unsigned char *MatcherTable, unsigned &MatcherIndex,
SDValue N, const TargetLowering *TLI, const DataLayout &DL) {
MVT::SimpleValueType VT = (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
@@ -2604,7 +2604,7 @@ CheckValueType(const unsigned char *MatcherTable, unsigned &MatcherIndex,
return VT == MVT::iPTR && cast<VTSDNode>(N)->getVT() == TLI->getPointerTy(DL);
}
-LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
+LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckInteger(const unsigned char *MatcherTable, unsigned &MatcherIndex,
SDValue N) {
int64_t Val = MatcherTable[MatcherIndex++];
@@ -2615,7 +2615,7 @@ CheckInteger(const unsigned char *MatcherTable, unsigned &MatcherIndex,
return C && C->getSExtValue() == Val;
}
-LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
+LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckChildInteger(const unsigned char *MatcherTable, unsigned &MatcherIndex,
SDValue N, unsigned ChildNo) {
if (ChildNo >= N.getNumOperands())
@@ -2623,7 +2623,7 @@ CheckChildInteger(const unsigned char *MatcherTable, unsigned &MatcherIndex,
return ::CheckInteger(MatcherTable, MatcherIndex, N.getOperand(ChildNo));
}
-LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
+LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckAndImm(const unsigned char *MatcherTable, unsigned &MatcherIndex,
SDValue N, const SelectionDAGISel &SDISel) {
int64_t Val = MatcherTable[MatcherIndex++];
@@ -2636,9 +2636,9 @@ CheckAndImm(const unsigned char *MatcherTable, unsigned &MatcherIndex,
return C && SDISel.CheckAndMask(N.getOperand(0), C, Val);
}
-LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
-CheckOrImm(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N,
- const SelectionDAGISel &SDISel) {
+LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
+CheckOrImm(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N,
+ const SelectionDAGISel &SDISel) {
int64_t Val = MatcherTable[MatcherIndex++];
if (Val & 128)
Val = GetVBR(Val, MatcherTable, MatcherIndex);
@@ -2831,7 +2831,7 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
case ISD::ANNOTATION_LABEL:
case ISD::LIFETIME_START:
case ISD::LIFETIME_END:
- case ISD::PSEUDO_PROBE:
+ case ISD::PSEUDO_PROBE:
NodeToMatch->setNodeId(-1); // Mark selected.
return;
case ISD::AssertSext:
@@ -3227,12 +3227,12 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
if (!::CheckOrImm(MatcherTable, MatcherIndex, N, *this)) break;
continue;
case OPC_CheckImmAllOnesV:
- if (!ISD::isConstantSplatVectorAllOnes(N.getNode()))
- break;
+ if (!ISD::isConstantSplatVectorAllOnes(N.getNode()))
+ break;
continue;
case OPC_CheckImmAllZerosV:
- if (!ISD::isConstantSplatVectorAllZeros(N.getNode()))
- break;
+ if (!ISD::isConstantSplatVectorAllZeros(N.getNode()))
+ break;
continue;
case OPC_CheckFoldableChainNode: {
@@ -3537,7 +3537,7 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
auto &Chain = ChainNodesMatched;
assert((!E || !is_contained(Chain, N)) &&
"Chain node replaced during MorphNode");
- llvm::erase_value(Chain, N);
+ llvm::erase_value(Chain, N);
});
Res = cast<MachineSDNode>(MorphNode(NodeToMatch, TargetOpc, VTList,
Ops, EmitNodeInfo));
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
index e0701ee581..0172646c22 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
@@ -64,20 +64,20 @@ cl::opt<bool> UseRegistersForDeoptValues(
"use-registers-for-deopt-values", cl::Hidden, cl::init(false),
cl::desc("Allow using registers for non pointer deopt args"));
-cl::opt<bool> UseRegistersForGCPointersInLandingPad(
- "use-registers-for-gc-values-in-landing-pad", cl::Hidden, cl::init(false),
- cl::desc("Allow using registers for gc pointer in landing pad"));
-
-cl::opt<unsigned> MaxRegistersForGCPointers(
- "max-registers-for-gc-values", cl::Hidden, cl::init(0),
- cl::desc("Max number of VRegs allowed to pass GC pointer meta args in"));
-
-cl::opt<bool> AlwaysSpillBase("statepoint-always-spill-base", cl::Hidden,
- cl::init(true),
- cl::desc("Force spilling of base GC pointers"));
-
-typedef FunctionLoweringInfo::StatepointRelocationRecord RecordType;
-
+cl::opt<bool> UseRegistersForGCPointersInLandingPad(
+ "use-registers-for-gc-values-in-landing-pad", cl::Hidden, cl::init(false),
+ cl::desc("Allow using registers for gc pointer in landing pad"));
+
+cl::opt<unsigned> MaxRegistersForGCPointers(
+ "max-registers-for-gc-values", cl::Hidden, cl::init(0),
+ cl::desc("Max number of VRegs allowed to pass GC pointer meta args in"));
+
+cl::opt<bool> AlwaysSpillBase("statepoint-always-spill-base", cl::Hidden,
+ cl::init(true),
+ cl::desc("Force spilling of base GC pointers"));
+
+typedef FunctionLoweringInfo::StatepointRelocationRecord RecordType;
+
static void pushStackMapConstant(SmallVectorImpl<SDValue>& Ops,
SelectionDAGBuilder &Builder, uint64_t Value) {
SDLoc L = Builder.getCurSDLoc();
@@ -167,18 +167,18 @@ static Optional<int> findPreviousSpillSlot(const Value *Val,
// Spill location is known for gc relocates
if (const auto *Relocate = dyn_cast<GCRelocateInst>(Val)) {
- const auto &RelocationMap =
- Builder.FuncInfo.StatepointRelocationMaps[Relocate->getStatepoint()];
+ const auto &RelocationMap =
+ Builder.FuncInfo.StatepointRelocationMaps[Relocate->getStatepoint()];
+
+ auto It = RelocationMap.find(Relocate->getDerivedPtr());
+ if (It == RelocationMap.end())
+ return None;
- auto It = RelocationMap.find(Relocate->getDerivedPtr());
- if (It == RelocationMap.end())
+ auto &Record = It->second;
+ if (Record.type != RecordType::Spill)
return None;
- auto &Record = It->second;
- if (Record.type != RecordType::Spill)
- return None;
-
- return Record.payload.FI;
+ return Record.payload.FI;
}
// Look through bitcast instructions.
@@ -401,7 +401,7 @@ spillIncomingStatepointValue(SDValue Incoming, SDValue Chain,
StoreMMO);
MMO = getMachineMemOperand(MF, *cast<FrameIndexSDNode>(Loc));
-
+
Builder.StatepointLowering.setLocation(Incoming, Loc);
}
@@ -498,10 +498,10 @@ lowerIncomingStatepointValue(SDValue Incoming, bool RequireSpillSlot,
/// will be set to the last value spilled (if any were).
static void
lowerStatepointMetaArgs(SmallVectorImpl<SDValue> &Ops,
- SmallVectorImpl<MachineMemOperand *> &MemRefs,
- SmallVectorImpl<SDValue> &GCPtrs,
- DenseMap<SDValue, int> &LowerAsVReg,
- SelectionDAGBuilder::StatepointLoweringInfo &SI,
+ SmallVectorImpl<MachineMemOperand *> &MemRefs,
+ SmallVectorImpl<SDValue> &GCPtrs,
+ DenseMap<SDValue, int> &LowerAsVReg,
+ SelectionDAGBuilder::StatepointLoweringInfo &SI,
SelectionDAGBuilder &Builder) {
// Lower the deopt and gc arguments for this statepoint. Layout will be:
// deopt argument length, deopt arguments.., gc arguments...
@@ -547,66 +547,66 @@ lowerStatepointMetaArgs(SmallVectorImpl<SDValue> &Ops,
const bool LiveInDeopt =
SI.StatepointFlags & (uint64_t)StatepointFlags::DeoptLiveIn;
- // Decide which deriver pointers will go on VRegs
- unsigned MaxVRegPtrs = MaxRegistersForGCPointers.getValue();
-
- // Pointers used on exceptional path of invoke statepoint.
- // We cannot assing them to VRegs.
- SmallSet<SDValue, 8> LPadPointers;
- if (!UseRegistersForGCPointersInLandingPad)
- if (auto *StInvoke = dyn_cast_or_null<InvokeInst>(SI.StatepointInstr)) {
- LandingPadInst *LPI = StInvoke->getLandingPadInst();
- for (auto *Relocate : SI.GCRelocates)
- if (Relocate->getOperand(0) == LPI) {
- LPadPointers.insert(Builder.getValue(Relocate->getBasePtr()));
- LPadPointers.insert(Builder.getValue(Relocate->getDerivedPtr()));
- }
- }
-
- LLVM_DEBUG(dbgs() << "Deciding how to lower GC Pointers:\n");
-
- // List of unique lowered GC Pointer values.
- SmallSetVector<SDValue, 16> LoweredGCPtrs;
- // Map lowered GC Pointer value to the index in above vector
- DenseMap<SDValue, unsigned> GCPtrIndexMap;
-
- unsigned CurNumVRegs = 0;
-
- auto canPassGCPtrOnVReg = [&](SDValue SD) {
- if (SD.getValueType().isVector())
- return false;
- if (LPadPointers.count(SD))
- return false;
- return !willLowerDirectly(SD);
- };
-
- auto processGCPtr = [&](const Value *V) {
- SDValue PtrSD = Builder.getValue(V);
- if (!LoweredGCPtrs.insert(PtrSD))
- return; // skip duplicates
- GCPtrIndexMap[PtrSD] = LoweredGCPtrs.size() - 1;
-
- assert(!LowerAsVReg.count(PtrSD) && "must not have been seen");
- if (LowerAsVReg.size() == MaxVRegPtrs)
- return;
- assert(V->getType()->isVectorTy() == PtrSD.getValueType().isVector() &&
- "IR and SD types disagree");
- if (!canPassGCPtrOnVReg(PtrSD)) {
- LLVM_DEBUG(dbgs() << "direct/spill "; PtrSD.dump(&Builder.DAG));
- return;
- }
- LLVM_DEBUG(dbgs() << "vreg "; PtrSD.dump(&Builder.DAG));
- LowerAsVReg[PtrSD] = CurNumVRegs++;
- };
-
- // Process derived pointers first to give them more chance to go on VReg.
- for (const Value *V : SI.Ptrs)
- processGCPtr(V);
- for (const Value *V : SI.Bases)
- processGCPtr(V);
-
- LLVM_DEBUG(dbgs() << LowerAsVReg.size() << " pointers will go in vregs\n");
-
+ // Decide which deriver pointers will go on VRegs
+ unsigned MaxVRegPtrs = MaxRegistersForGCPointers.getValue();
+
+ // Pointers used on exceptional path of invoke statepoint.
+ // We cannot assing them to VRegs.
+ SmallSet<SDValue, 8> LPadPointers;
+ if (!UseRegistersForGCPointersInLandingPad)
+ if (auto *StInvoke = dyn_cast_or_null<InvokeInst>(SI.StatepointInstr)) {
+ LandingPadInst *LPI = StInvoke->getLandingPadInst();
+ for (auto *Relocate : SI.GCRelocates)
+ if (Relocate->getOperand(0) == LPI) {
+ LPadPointers.insert(Builder.getValue(Relocate->getBasePtr()));
+ LPadPointers.insert(Builder.getValue(Relocate->getDerivedPtr()));
+ }
+ }
+
+ LLVM_DEBUG(dbgs() << "Deciding how to lower GC Pointers:\n");
+
+ // List of unique lowered GC Pointer values.
+ SmallSetVector<SDValue, 16> LoweredGCPtrs;
+ // Map lowered GC Pointer value to the index in above vector
+ DenseMap<SDValue, unsigned> GCPtrIndexMap;
+
+ unsigned CurNumVRegs = 0;
+
+ auto canPassGCPtrOnVReg = [&](SDValue SD) {
+ if (SD.getValueType().isVector())
+ return false;
+ if (LPadPointers.count(SD))
+ return false;
+ return !willLowerDirectly(SD);
+ };
+
+ auto processGCPtr = [&](const Value *V) {
+ SDValue PtrSD = Builder.getValue(V);
+ if (!LoweredGCPtrs.insert(PtrSD))
+ return; // skip duplicates
+ GCPtrIndexMap[PtrSD] = LoweredGCPtrs.size() - 1;
+
+ assert(!LowerAsVReg.count(PtrSD) && "must not have been seen");
+ if (LowerAsVReg.size() == MaxVRegPtrs)
+ return;
+ assert(V->getType()->isVectorTy() == PtrSD.getValueType().isVector() &&
+ "IR and SD types disagree");
+ if (!canPassGCPtrOnVReg(PtrSD)) {
+ LLVM_DEBUG(dbgs() << "direct/spill "; PtrSD.dump(&Builder.DAG));
+ return;
+ }
+ LLVM_DEBUG(dbgs() << "vreg "; PtrSD.dump(&Builder.DAG));
+ LowerAsVReg[PtrSD] = CurNumVRegs++;
+ };
+
+ // Process derived pointers first to give them more chance to go on VReg.
+ for (const Value *V : SI.Ptrs)
+ processGCPtr(V);
+ for (const Value *V : SI.Bases)
+ processGCPtr(V);
+
+ LLVM_DEBUG(dbgs() << LowerAsVReg.size() << " pointers will go in vregs\n");
+
auto isGCValue = [&](const Value *V) {
auto *Ty = V->getType();
if (!Ty->isPtrOrPtrVectorTy())
@@ -618,9 +618,9 @@ lowerStatepointMetaArgs(SmallVectorImpl<SDValue> &Ops,
};
auto requireSpillSlot = [&](const Value *V) {
- if (isGCValue(V))
- return !LowerAsVReg.count(Builder.getValue(V));
- return !(LiveInDeopt || UseRegistersForDeoptValues);
+ if (isGCValue(V))
+ return !LowerAsVReg.count(Builder.getValue(V));
+ return !(LiveInDeopt || UseRegistersForDeoptValues);
};
// Before we actually start lowering (and allocating spill slots for values),
@@ -632,19 +632,19 @@ lowerStatepointMetaArgs(SmallVectorImpl<SDValue> &Ops,
if (requireSpillSlot(V))
reservePreviousStackSlotForValue(V, Builder);
}
-
- for (const Value *V : SI.Ptrs) {
- SDValue SDV = Builder.getValue(V);
- if (!LowerAsVReg.count(SDV))
- reservePreviousStackSlotForValue(V, Builder);
+
+ for (const Value *V : SI.Ptrs) {
+ SDValue SDV = Builder.getValue(V);
+ if (!LowerAsVReg.count(SDV))
+ reservePreviousStackSlotForValue(V, Builder);
+ }
+
+ for (const Value *V : SI.Bases) {
+ SDValue SDV = Builder.getValue(V);
+ if (!LowerAsVReg.count(SDV))
+ reservePreviousStackSlotForValue(V, Builder);
}
- for (const Value *V : SI.Bases) {
- SDValue SDV = Builder.getValue(V);
- if (!LowerAsVReg.count(SDV))
- reservePreviousStackSlotForValue(V, Builder);
- }
-
// First, prefix the list with the number of unique values to be
// lowered. Note that this is the number of *Values* not the
// number of SDValues required to lower them.
@@ -653,7 +653,7 @@ lowerStatepointMetaArgs(SmallVectorImpl<SDValue> &Ops,
// The vm state arguments are lowered in an opaque manner. We do not know
// what type of values are contained within.
- LLVM_DEBUG(dbgs() << "Lowering deopt state\n");
+ LLVM_DEBUG(dbgs() << "Lowering deopt state\n");
for (const Value *V : SI.DeoptState) {
SDValue Incoming;
// If this is a function argument at a static frame index, generate it as
@@ -665,56 +665,56 @@ lowerStatepointMetaArgs(SmallVectorImpl<SDValue> &Ops,
}
if (!Incoming.getNode())
Incoming = Builder.getValue(V);
- LLVM_DEBUG(dbgs() << "Value " << *V
- << " requireSpillSlot = " << requireSpillSlot(V) << "\n");
+ LLVM_DEBUG(dbgs() << "Value " << *V
+ << " requireSpillSlot = " << requireSpillSlot(V) << "\n");
lowerIncomingStatepointValue(Incoming, requireSpillSlot(V), Ops, MemRefs,
Builder);
}
- // Finally, go ahead and lower all the gc arguments.
- pushStackMapConstant(Ops, Builder, LoweredGCPtrs.size());
- for (SDValue SDV : LoweredGCPtrs)
- lowerIncomingStatepointValue(SDV, !LowerAsVReg.count(SDV), Ops, MemRefs,
+ // Finally, go ahead and lower all the gc arguments.
+ pushStackMapConstant(Ops, Builder, LoweredGCPtrs.size());
+ for (SDValue SDV : LoweredGCPtrs)
+ lowerIncomingStatepointValue(SDV, !LowerAsVReg.count(SDV), Ops, MemRefs,
Builder);
- // Copy to out vector. LoweredGCPtrs will be empty after this point.
- GCPtrs = LoweredGCPtrs.takeVector();
+ // Copy to out vector. LoweredGCPtrs will be empty after this point.
+ GCPtrs = LoweredGCPtrs.takeVector();
// If there are any explicit spill slots passed to the statepoint, record
// them, but otherwise do not do anything special. These are user provided
// allocas and give control over placement to the consumer. In this case,
// it is the contents of the slot which may get updated, not the pointer to
// the alloca
- SmallVector<SDValue, 4> Allocas;
+ SmallVector<SDValue, 4> Allocas;
for (Value *V : SI.GCArgs) {
SDValue Incoming = Builder.getValue(V);
if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Incoming)) {
// This handles allocas as arguments to the statepoint
assert(Incoming.getValueType() == Builder.getFrameIndexTy() &&
"Incoming value is a frame index!");
- Allocas.push_back(Builder.DAG.getTargetFrameIndex(
- FI->getIndex(), Builder.getFrameIndexTy()));
+ Allocas.push_back(Builder.DAG.getTargetFrameIndex(
+ FI->getIndex(), Builder.getFrameIndexTy()));
auto &MF = Builder.DAG.getMachineFunction();
auto *MMO = getMachineMemOperand(MF, *FI);
MemRefs.push_back(MMO);
}
}
- pushStackMapConstant(Ops, Builder, Allocas.size());
- Ops.append(Allocas.begin(), Allocas.end());
-
- // Now construct GC base/derived map;
- pushStackMapConstant(Ops, Builder, SI.Ptrs.size());
- SDLoc L = Builder.getCurSDLoc();
- for (unsigned i = 0; i < SI.Ptrs.size(); ++i) {
- SDValue Base = Builder.getValue(SI.Bases[i]);
- assert(GCPtrIndexMap.count(Base) && "base not found in index map");
- Ops.push_back(
- Builder.DAG.getTargetConstant(GCPtrIndexMap[Base], L, MVT::i64));
- SDValue Derived = Builder.getValue(SI.Ptrs[i]);
- assert(GCPtrIndexMap.count(Derived) && "derived not found in index map");
- Ops.push_back(
- Builder.DAG.getTargetConstant(GCPtrIndexMap[Derived], L, MVT::i64));
+ pushStackMapConstant(Ops, Builder, Allocas.size());
+ Ops.append(Allocas.begin(), Allocas.end());
+
+ // Now construct GC base/derived map;
+ pushStackMapConstant(Ops, Builder, SI.Ptrs.size());
+ SDLoc L = Builder.getCurSDLoc();
+ for (unsigned i = 0; i < SI.Ptrs.size(); ++i) {
+ SDValue Base = Builder.getValue(SI.Bases[i]);
+ assert(GCPtrIndexMap.count(Base) && "base not found in index map");
+ Ops.push_back(
+ Builder.DAG.getTargetConstant(GCPtrIndexMap[Base], L, MVT::i64));
+ SDValue Derived = Builder.getValue(SI.Ptrs[i]);
+ assert(GCPtrIndexMap.count(Derived) && "derived not found in index map");
+ Ops.push_back(
+ Builder.DAG.getTargetConstant(GCPtrIndexMap[Derived], L, MVT::i64));
}
}
@@ -730,7 +730,7 @@ SDValue SelectionDAGBuilder::LowerAsSTATEPOINT(
assert(SI.Bases.size() == SI.Ptrs.size() &&
SI.Ptrs.size() <= SI.GCRelocates.size());
- LLVM_DEBUG(dbgs() << "Lowering statepoint " << *SI.StatepointInstr << "\n");
+ LLVM_DEBUG(dbgs() << "Lowering statepoint " << *SI.StatepointInstr << "\n");
#ifndef NDEBUG
for (auto *Reloc : SI.GCRelocates)
if (Reloc->getParent() == SI.StatepointInstr->getParent())
@@ -738,16 +738,16 @@ SDValue SelectionDAGBuilder::LowerAsSTATEPOINT(
#endif
// Lower statepoint vmstate and gcstate arguments
-
- // All lowered meta args.
+
+ // All lowered meta args.
SmallVector<SDValue, 10> LoweredMetaArgs;
- // Lowered GC pointers (subset of above).
- SmallVector<SDValue, 16> LoweredGCArgs;
+ // Lowered GC pointers (subset of above).
+ SmallVector<SDValue, 16> LoweredGCArgs;
SmallVector<MachineMemOperand*, 16> MemRefs;
- // Maps derived pointer SDValue to statepoint result of relocated pointer.
- DenseMap<SDValue, int> LowerAsVReg;
- lowerStatepointMetaArgs(LoweredMetaArgs, MemRefs, LoweredGCArgs, LowerAsVReg,
- SI, *this);
+ // Maps derived pointer SDValue to statepoint result of relocated pointer.
+ DenseMap<SDValue, int> LowerAsVReg;
+ lowerStatepointMetaArgs(LoweredMetaArgs, MemRefs, LoweredGCArgs, LowerAsVReg,
+ SI, *this);
// Now that we've emitted the spills, we need to update the root so that the
// call sequence is ordered correctly.
@@ -847,7 +847,7 @@ SDValue SelectionDAGBuilder::LowerAsSTATEPOINT(
pushStackMapConstant(Ops, *this, Flags);
// Insert all vmstate and gcstate arguments
- llvm::append_range(Ops, LoweredMetaArgs);
+ llvm::append_range(Ops, LoweredMetaArgs);
// Add register mask from call node
Ops.push_back(*RegMaskIt);
@@ -861,79 +861,79 @@ SDValue SelectionDAGBuilder::LowerAsSTATEPOINT(
// Compute return values. Provide a glue output since we consume one as
// input. This allows someone else to chain off us as needed.
- SmallVector<EVT, 8> NodeTys;
- for (auto SD : LoweredGCArgs) {
- if (!LowerAsVReg.count(SD))
- continue;
- NodeTys.push_back(SD.getValueType());
- }
- LLVM_DEBUG(dbgs() << "Statepoint has " << NodeTys.size() << " results\n");
- assert(NodeTys.size() == LowerAsVReg.size() && "Inconsistent GC Ptr lowering");
- NodeTys.push_back(MVT::Other);
- NodeTys.push_back(MVT::Glue);
-
- unsigned NumResults = NodeTys.size();
+ SmallVector<EVT, 8> NodeTys;
+ for (auto SD : LoweredGCArgs) {
+ if (!LowerAsVReg.count(SD))
+ continue;
+ NodeTys.push_back(SD.getValueType());
+ }
+ LLVM_DEBUG(dbgs() << "Statepoint has " << NodeTys.size() << " results\n");
+ assert(NodeTys.size() == LowerAsVReg.size() && "Inconsistent GC Ptr lowering");
+ NodeTys.push_back(MVT::Other);
+ NodeTys.push_back(MVT::Glue);
+
+ unsigned NumResults = NodeTys.size();
MachineSDNode *StatepointMCNode =
DAG.getMachineNode(TargetOpcode::STATEPOINT, getCurSDLoc(), NodeTys, Ops);
DAG.setNodeMemRefs(StatepointMCNode, MemRefs);
- // For values lowered to tied-defs, create the virtual registers. Note that
- // for simplicity, we *always* create a vreg even within a single block.
- DenseMap<SDValue, Register> VirtRegs;
- for (const auto *Relocate : SI.GCRelocates) {
- Value *Derived = Relocate->getDerivedPtr();
- SDValue SD = getValue(Derived);
- if (!LowerAsVReg.count(SD))
- continue;
-
- // Handle multiple gc.relocates of the same input efficiently.
- if (VirtRegs.count(SD))
- continue;
-
- SDValue Relocated = SDValue(StatepointMCNode, LowerAsVReg[SD]);
-
- auto *RetTy = Relocate->getType();
- Register Reg = FuncInfo.CreateRegs(RetTy);
- RegsForValue RFV(*DAG.getContext(), DAG.getTargetLoweringInfo(),
- DAG.getDataLayout(), Reg, RetTy, None);
- SDValue Chain = DAG.getRoot();
- RFV.getCopyToRegs(Relocated, DAG, getCurSDLoc(), Chain, nullptr);
- PendingExports.push_back(Chain);
-
- VirtRegs[SD] = Reg;
- }
-
- // Record for later use how each relocation was lowered. This is needed to
- // allow later gc.relocates to mirror the lowering chosen.
- const Instruction *StatepointInstr = SI.StatepointInstr;
- auto &RelocationMap = FuncInfo.StatepointRelocationMaps[StatepointInstr];
- for (const GCRelocateInst *Relocate : SI.GCRelocates) {
- const Value *V = Relocate->getDerivedPtr();
- SDValue SDV = getValue(V);
- SDValue Loc = StatepointLowering.getLocation(SDV);
-
- RecordType Record;
- if (LowerAsVReg.count(SDV)) {
- Record.type = RecordType::VReg;
- assert(VirtRegs.count(SDV));
- Record.payload.Reg = VirtRegs[SDV];
- } else if (Loc.getNode()) {
- Record.type = RecordType::Spill;
- Record.payload.FI = cast<FrameIndexSDNode>(Loc)->getIndex();
- } else {
- Record.type = RecordType::NoRelocate;
- // If we didn't relocate a value, we'll essentialy end up inserting an
- // additional use of the original value when lowering the gc.relocate.
- // We need to make sure the value is available at the new use, which
- // might be in another block.
- if (Relocate->getParent() != StatepointInstr->getParent())
- ExportFromCurrentBlock(V);
- }
- RelocationMap[V] = Record;
- }
-
-
-
+ // For values lowered to tied-defs, create the virtual registers. Note that
+ // for simplicity, we *always* create a vreg even within a single block.
+ DenseMap<SDValue, Register> VirtRegs;
+ for (const auto *Relocate : SI.GCRelocates) {
+ Value *Derived = Relocate->getDerivedPtr();
+ SDValue SD = getValue(Derived);
+ if (!LowerAsVReg.count(SD))
+ continue;
+
+ // Handle multiple gc.relocates of the same input efficiently.
+ if (VirtRegs.count(SD))
+ continue;
+
+ SDValue Relocated = SDValue(StatepointMCNode, LowerAsVReg[SD]);
+
+ auto *RetTy = Relocate->getType();
+ Register Reg = FuncInfo.CreateRegs(RetTy);
+ RegsForValue RFV(*DAG.getContext(), DAG.getTargetLoweringInfo(),
+ DAG.getDataLayout(), Reg, RetTy, None);
+ SDValue Chain = DAG.getRoot();
+ RFV.getCopyToRegs(Relocated, DAG, getCurSDLoc(), Chain, nullptr);
+ PendingExports.push_back(Chain);
+
+ VirtRegs[SD] = Reg;
+ }
+
+ // Record for later use how each relocation was lowered. This is needed to
+ // allow later gc.relocates to mirror the lowering chosen.
+ const Instruction *StatepointInstr = SI.StatepointInstr;
+ auto &RelocationMap = FuncInfo.StatepointRelocationMaps[StatepointInstr];
+ for (const GCRelocateInst *Relocate : SI.GCRelocates) {
+ const Value *V = Relocate->getDerivedPtr();
+ SDValue SDV = getValue(V);
+ SDValue Loc = StatepointLowering.getLocation(SDV);
+
+ RecordType Record;
+ if (LowerAsVReg.count(SDV)) {
+ Record.type = RecordType::VReg;
+ assert(VirtRegs.count(SDV));
+ Record.payload.Reg = VirtRegs[SDV];
+ } else if (Loc.getNode()) {
+ Record.type = RecordType::Spill;
+ Record.payload.FI = cast<FrameIndexSDNode>(Loc)->getIndex();
+ } else {
+ Record.type = RecordType::NoRelocate;
+ // If we didn't relocate a value, we'll essentialy end up inserting an
+ // additional use of the original value when lowering the gc.relocate.
+ // We need to make sure the value is available at the new use, which
+ // might be in another block.
+ if (Relocate->getParent() != StatepointInstr->getParent())
+ ExportFromCurrentBlock(V);
+ }
+ RelocationMap[V] = Record;
+ }
+
+
+
SDNode *SinkNode = StatepointMCNode;
// Build the GC_TRANSITION_END node if necessary.
@@ -944,7 +944,7 @@ SDValue SelectionDAGBuilder::LowerAsSTATEPOINT(
SmallVector<SDValue, 8> TEOps;
// Add chain
- TEOps.push_back(SDValue(StatepointMCNode, NumResults - 2));
+ TEOps.push_back(SDValue(StatepointMCNode, NumResults - 2));
// Add GC transition arguments
for (const Value *V : SI.GCTransitionArgs) {
@@ -954,7 +954,7 @@ SDValue SelectionDAGBuilder::LowerAsSTATEPOINT(
}
// Add glue
- TEOps.push_back(SDValue(StatepointMCNode, NumResults - 1));
+ TEOps.push_back(SDValue(StatepointMCNode, NumResults - 1));
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
@@ -965,18 +965,18 @@ SDValue SelectionDAGBuilder::LowerAsSTATEPOINT(
}
// Replace original call
- // Call: ch,glue = CALL ...
- // Statepoint: [gc relocates],ch,glue = STATEPOINT ...
- unsigned NumSinkValues = SinkNode->getNumValues();
- SDValue StatepointValues[2] = {SDValue(SinkNode, NumSinkValues - 2),
- SDValue(SinkNode, NumSinkValues - 1)};
- DAG.ReplaceAllUsesWith(CallNode, StatepointValues);
+ // Call: ch,glue = CALL ...
+ // Statepoint: [gc relocates],ch,glue = STATEPOINT ...
+ unsigned NumSinkValues = SinkNode->getNumValues();
+ SDValue StatepointValues[2] = {SDValue(SinkNode, NumSinkValues - 2),
+ SDValue(SinkNode, NumSinkValues - 1)};
+ DAG.ReplaceAllUsesWith(CallNode, StatepointValues);
// Remove original call node
DAG.DeleteNode(CallNode);
- // Since we always emit CopyToRegs (even for local relocates), we must
- // update root, so that they are emitted before any local uses.
- (void)getControlRoot();
+ // Since we always emit CopyToRegs (even for local relocates), we must
+ // update root, so that they are emitted before any local uses.
+ (void)getControlRoot();
// TODO: A better future implementation would be to emit a single variable
// argument, variable return value STATEPOINT node here and then hookup the
@@ -1073,7 +1073,7 @@ SelectionDAGBuilder::LowerStatepoint(const GCStatepointInst &I,
setValue(&I, ReturnValue);
return;
}
-
+
// Result value will be used in a different basic block so we need to export
// it now. Default exporting mechanism will not work here because statepoint
// call has a different type than the actual call. It means that by default
@@ -1170,28 +1170,28 @@ void SelectionDAGBuilder::visitGCRelocate(const GCRelocateInst &Relocate) {
#endif
const Value *DerivedPtr = Relocate.getDerivedPtr();
- auto &RelocationMap =
- FuncInfo.StatepointRelocationMaps[Relocate.getStatepoint()];
- auto SlotIt = RelocationMap.find(DerivedPtr);
- assert(SlotIt != RelocationMap.end() && "Relocating not lowered gc value");
- const RecordType &Record = SlotIt->second;
-
- // If relocation was done via virtual register..
- if (Record.type == RecordType::VReg) {
- Register InReg = Record.payload.Reg;
- RegsForValue RFV(*DAG.getContext(), DAG.getTargetLoweringInfo(),
- DAG.getDataLayout(), InReg, Relocate.getType(),
- None); // This is not an ABI copy.
- // We generate copy to/from regs even for local uses, hence we must
- // chain with current root to ensure proper ordering of copies w.r.t.
- // statepoint.
- SDValue Chain = DAG.getRoot();
- SDValue Relocation = RFV.getCopyFromRegs(DAG, FuncInfo, getCurSDLoc(),
- Chain, nullptr, nullptr);
- setValue(&Relocate, Relocation);
- return;
- }
-
+ auto &RelocationMap =
+ FuncInfo.StatepointRelocationMaps[Relocate.getStatepoint()];
+ auto SlotIt = RelocationMap.find(DerivedPtr);
+ assert(SlotIt != RelocationMap.end() && "Relocating not lowered gc value");
+ const RecordType &Record = SlotIt->second;
+
+ // If relocation was done via virtual register..
+ if (Record.type == RecordType::VReg) {
+ Register InReg = Record.payload.Reg;
+ RegsForValue RFV(*DAG.getContext(), DAG.getTargetLoweringInfo(),
+ DAG.getDataLayout(), InReg, Relocate.getType(),
+ None); // This is not an ABI copy.
+ // We generate copy to/from regs even for local uses, hence we must
+ // chain with current root to ensure proper ordering of copies w.r.t.
+ // statepoint.
+ SDValue Chain = DAG.getRoot();
+ SDValue Relocation = RFV.getCopyFromRegs(DAG, FuncInfo, getCurSDLoc(),
+ Chain, nullptr, nullptr);
+ setValue(&Relocate, Relocation);
+ return;
+ }
+
SDValue SD = getValue(DerivedPtr);
if (SD.isUndef() && SD.getValueType().getSizeInBits() <= 64) {
@@ -1204,14 +1204,14 @@ void SelectionDAGBuilder::visitGCRelocate(const GCRelocateInst &Relocate) {
// We didn't need to spill these special cases (constants and allocas).
// See the handling in spillIncomingValueForStatepoint for detail.
- if (Record.type == RecordType::NoRelocate) {
+ if (Record.type == RecordType::NoRelocate) {
setValue(&Relocate, SD);
return;
}
- assert(Record.type == RecordType::Spill);
-
- unsigned Index = Record.payload.FI;;
+ assert(Record.type == RecordType::Spill);
+
+ unsigned Index = Record.payload.FI;;
SDValue SpillSlot = DAG.getTargetFrameIndex(Index, getFrameIndexTy());
// All the reloads are independent and are reading memory only modified by
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 2b0bf413c0..b0ad86899d 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -93,7 +93,7 @@ bool TargetLowering::parametersInCSRMatch(const MachineRegisterInfo &MRI,
SDValue Value = OutVals[I];
if (Value->getOpcode() != ISD::CopyFromReg)
return false;
- Register ArgReg = cast<RegisterSDNode>(Value->getOperand(1))->getReg();
+ Register ArgReg = cast<RegisterSDNode>(Value->getOperand(1))->getReg();
if (MRI.getLiveInPhysReg(ArgReg) != Reg)
return false;
}
@@ -250,7 +250,7 @@ bool TargetLowering::findOptimalMemOpLowering(
bool Fast;
if (NumMemOps && Op.allowOverlap() && NewVTSize < Size &&
allowsMisalignedMemoryAccesses(
- VT, DstAS, Op.isFixedDstAlign() ? Op.getDstAlign().value() : 1,
+ VT, DstAS, Op.isFixedDstAlign() ? Op.getDstAlign().value() : 1,
MachineMemOperand::MONone, &Fast) &&
Fast)
VTSize = Size;
@@ -912,17 +912,17 @@ bool TargetLowering::SimplifyDemandedBits(
if (Op.getOpcode() == ISD::Constant) {
// We know all of the bits for a constant!
- Known = KnownBits::makeConstant(cast<ConstantSDNode>(Op)->getAPIntValue());
+ Known = KnownBits::makeConstant(cast<ConstantSDNode>(Op)->getAPIntValue());
+ return false;
+ }
+
+ if (Op.getOpcode() == ISD::ConstantFP) {
+ // We know all of the bits for a floating point constant!
+ Known = KnownBits::makeConstant(
+ cast<ConstantFPSDNode>(Op)->getValueAPF().bitcastToAPInt());
return false;
}
- if (Op.getOpcode() == ISD::ConstantFP) {
- // We know all of the bits for a floating point constant!
- Known = KnownBits::makeConstant(
- cast<ConstantFPSDNode>(Op)->getValueAPF().bitcastToAPInt());
- return false;
- }
-
// Other users may use these bits.
EVT VT = Op.getValueType();
if (!Op.getNode()->hasOneUse() && !AssumeSingleUse) {
@@ -1015,8 +1015,8 @@ bool TargetLowering::SimplifyDemandedBits(
Depth + 1))
return true;
- if (!!DemandedVecElts)
- Known = KnownBits::commonBits(Known, KnownVec);
+ if (!!DemandedVecElts)
+ Known = KnownBits::commonBits(Known, KnownVec);
return false;
}
@@ -1041,10 +1041,10 @@ bool TargetLowering::SimplifyDemandedBits(
Known.Zero.setAllBits();
Known.One.setAllBits();
- if (!!DemandedSubElts)
- Known = KnownBits::commonBits(Known, KnownSub);
- if (!!DemandedSrcElts)
- Known = KnownBits::commonBits(Known, KnownSrc);
+ if (!!DemandedSubElts)
+ Known = KnownBits::commonBits(Known, KnownSub);
+ if (!!DemandedSrcElts)
+ Known = KnownBits::commonBits(Known, KnownSrc);
// Attempt to avoid multi-use src if we don't need anything from it.
if (!DemandedBits.isAllOnesValue() || !DemandedSubElts.isAllOnesValue() ||
@@ -1101,8 +1101,8 @@ bool TargetLowering::SimplifyDemandedBits(
Known2, TLO, Depth + 1))
return true;
// Known bits are shared by every demanded subvector element.
- if (!!DemandedSubElts)
- Known = KnownBits::commonBits(Known, Known2);
+ if (!!DemandedSubElts)
+ Known = KnownBits::commonBits(Known, Known2);
}
break;
}
@@ -1140,13 +1140,13 @@ bool TargetLowering::SimplifyDemandedBits(
if (SimplifyDemandedBits(Op0, DemandedBits, DemandedLHS, Known2, TLO,
Depth + 1))
return true;
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
}
if (!!DemandedRHS) {
if (SimplifyDemandedBits(Op1, DemandedBits, DemandedRHS, Known2, TLO,
Depth + 1))
return true;
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
}
// Attempt to avoid multi-use ops if we don't need anything from them.
@@ -1321,15 +1321,15 @@ bool TargetLowering::SimplifyDemandedBits(
return true;
// If all of the unknown bits are known to be zero on one side or the other
- // turn this into an *inclusive* or.
+ // turn this into an *inclusive* or.
// e.g. (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0
if (DemandedBits.isSubsetOf(Known.Zero | Known2.Zero))
return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::OR, dl, VT, Op0, Op1));
ConstantSDNode* C = isConstOrConstSplat(Op1, DemandedElts);
if (C) {
- // If one side is a constant, and all of the set bits in the constant are
- // also known set on the other side, turn this into an AND, as we know
+ // If one side is a constant, and all of the set bits in the constant are
+ // also known set on the other side, turn this into an AND, as we know
// the bits will be cleared.
// e.g. (X | C1) ^ C2 --> (X | C1) & ~C2 iff (C1&C2) == C2
// NB: it is okay if more bits are known than are requested
@@ -1373,7 +1373,7 @@ bool TargetLowering::SimplifyDemandedBits(
return true;
// Only known if known in both the LHS and RHS.
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
break;
case ISD::SELECT_CC:
if (SimplifyDemandedBits(Op.getOperand(3), DemandedBits, Known, TLO,
@@ -1390,7 +1390,7 @@ bool TargetLowering::SimplifyDemandedBits(
return true;
// Only known if known in both the LHS and RHS.
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
break;
case ISD::SETCC: {
SDValue Op0 = Op.getOperand(0);
@@ -1722,32 +1722,32 @@ bool TargetLowering::SimplifyDemandedBits(
}
break;
}
- case ISD::UMIN: {
- // Check if one arg is always less than (or equal) to the other arg.
- SDValue Op0 = Op.getOperand(0);
- SDValue Op1 = Op.getOperand(1);
- KnownBits Known0 = TLO.DAG.computeKnownBits(Op0, DemandedElts, Depth + 1);
- KnownBits Known1 = TLO.DAG.computeKnownBits(Op1, DemandedElts, Depth + 1);
- Known = KnownBits::umin(Known0, Known1);
- if (Optional<bool> IsULE = KnownBits::ule(Known0, Known1))
- return TLO.CombineTo(Op, IsULE.getValue() ? Op0 : Op1);
- if (Optional<bool> IsULT = KnownBits::ult(Known0, Known1))
- return TLO.CombineTo(Op, IsULT.getValue() ? Op0 : Op1);
- break;
- }
- case ISD::UMAX: {
- // Check if one arg is always greater than (or equal) to the other arg.
- SDValue Op0 = Op.getOperand(0);
- SDValue Op1 = Op.getOperand(1);
- KnownBits Known0 = TLO.DAG.computeKnownBits(Op0, DemandedElts, Depth + 1);
- KnownBits Known1 = TLO.DAG.computeKnownBits(Op1, DemandedElts, Depth + 1);
- Known = KnownBits::umax(Known0, Known1);
- if (Optional<bool> IsUGE = KnownBits::uge(Known0, Known1))
- return TLO.CombineTo(Op, IsUGE.getValue() ? Op0 : Op1);
- if (Optional<bool> IsUGT = KnownBits::ugt(Known0, Known1))
- return TLO.CombineTo(Op, IsUGT.getValue() ? Op0 : Op1);
- break;
- }
+ case ISD::UMIN: {
+ // Check if one arg is always less than (or equal) to the other arg.
+ SDValue Op0 = Op.getOperand(0);
+ SDValue Op1 = Op.getOperand(1);
+ KnownBits Known0 = TLO.DAG.computeKnownBits(Op0, DemandedElts, Depth + 1);
+ KnownBits Known1 = TLO.DAG.computeKnownBits(Op1, DemandedElts, Depth + 1);
+ Known = KnownBits::umin(Known0, Known1);
+ if (Optional<bool> IsULE = KnownBits::ule(Known0, Known1))
+ return TLO.CombineTo(Op, IsULE.getValue() ? Op0 : Op1);
+ if (Optional<bool> IsULT = KnownBits::ult(Known0, Known1))
+ return TLO.CombineTo(Op, IsULT.getValue() ? Op0 : Op1);
+ break;
+ }
+ case ISD::UMAX: {
+ // Check if one arg is always greater than (or equal) to the other arg.
+ SDValue Op0 = Op.getOperand(0);
+ SDValue Op1 = Op.getOperand(1);
+ KnownBits Known0 = TLO.DAG.computeKnownBits(Op0, DemandedElts, Depth + 1);
+ KnownBits Known1 = TLO.DAG.computeKnownBits(Op1, DemandedElts, Depth + 1);
+ Known = KnownBits::umax(Known0, Known1);
+ if (Optional<bool> IsUGE = KnownBits::uge(Known0, Known1))
+ return TLO.CombineTo(Op, IsUGE.getValue() ? Op0 : Op1);
+ if (Optional<bool> IsUGT = KnownBits::ugt(Known0, Known1))
+ return TLO.CombineTo(Op, IsUGT.getValue() ? Op0 : Op1);
+ break;
+ }
case ISD::BITREVERSE: {
SDValue Src = Op.getOperand(0);
APInt DemandedSrcBits = DemandedBits.reverseBits();
@@ -1768,17 +1768,17 @@ bool TargetLowering::SimplifyDemandedBits(
Known.Zero = Known2.Zero.byteSwap();
break;
}
- case ISD::CTPOP: {
- // If only 1 bit is demanded, replace with PARITY as long as we're before
- // op legalization.
- // FIXME: Limit to scalars for now.
- if (DemandedBits.isOneValue() && !TLO.LegalOps && !VT.isVector())
- return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::PARITY, dl, VT,
- Op.getOperand(0)));
-
- Known = TLO.DAG.computeKnownBits(Op, DemandedElts, Depth);
- break;
- }
+ case ISD::CTPOP: {
+ // If only 1 bit is demanded, replace with PARITY as long as we're before
+ // op legalization.
+ // FIXME: Limit to scalars for now.
+ if (DemandedBits.isOneValue() && !TLO.LegalOps && !VT.isVector())
+ return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::PARITY, dl, VT,
+ Op.getOperand(0)));
+
+ Known = TLO.DAG.computeKnownBits(Op, DemandedElts, Depth);
+ break;
+ }
case ISD::SIGN_EXTEND_INREG: {
SDValue Op0 = Op.getOperand(0);
EVT ExVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
@@ -1889,11 +1889,11 @@ bool TargetLowering::SimplifyDemandedBits(
assert(!Known.hasConflict() && "Bits known to be one AND zero?");
assert(Known.getBitWidth() == InBits && "Src width has changed?");
Known = Known.zext(BitWidth);
-
- // Attempt to avoid multi-use ops if we don't need anything from them.
- if (SDValue NewSrc = SimplifyMultipleUseDemandedBits(
- Src, InDemandedBits, InDemandedElts, TLO.DAG, Depth + 1))
- return TLO.CombineTo(Op, TLO.DAG.getNode(Op.getOpcode(), dl, VT, NewSrc));
+
+ // Attempt to avoid multi-use ops if we don't need anything from them.
+ if (SDValue NewSrc = SimplifyMultipleUseDemandedBits(
+ Src, InDemandedBits, InDemandedElts, TLO.DAG, Depth + 1))
+ return TLO.CombineTo(Op, TLO.DAG.getNode(Op.getOpcode(), dl, VT, NewSrc));
break;
}
case ISD::SIGN_EXTEND:
@@ -1942,11 +1942,11 @@ bool TargetLowering::SimplifyDemandedBits(
if (!TLO.LegalOperations() || isOperationLegal(Opc, VT))
return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, dl, VT, Src));
}
-
- // Attempt to avoid multi-use ops if we don't need anything from them.
- if (SDValue NewSrc = SimplifyMultipleUseDemandedBits(
- Src, InDemandedBits, InDemandedElts, TLO.DAG, Depth + 1))
- return TLO.CombineTo(Op, TLO.DAG.getNode(Op.getOpcode(), dl, VT, NewSrc));
+
+ // Attempt to avoid multi-use ops if we don't need anything from them.
+ if (SDValue NewSrc = SimplifyMultipleUseDemandedBits(
+ Src, InDemandedBits, InDemandedElts, TLO.DAG, Depth + 1))
+ return TLO.CombineTo(Op, TLO.DAG.getNode(Op.getOpcode(), dl, VT, NewSrc));
break;
}
case ISD::ANY_EXTEND:
@@ -1986,8 +1986,8 @@ bool TargetLowering::SimplifyDemandedBits(
// zero/one bits live out.
unsigned OperandBitWidth = Src.getScalarValueSizeInBits();
APInt TruncMask = DemandedBits.zext(OperandBitWidth);
- if (SimplifyDemandedBits(Src, TruncMask, DemandedElts, Known, TLO,
- Depth + 1))
+ if (SimplifyDemandedBits(Src, TruncMask, DemandedElts, Known, TLO,
+ Depth + 1))
return true;
Known = Known.trunc(BitWidth);
@@ -2010,9 +2010,9 @@ bool TargetLowering::SimplifyDemandedBits(
// undesirable.
break;
- const APInt *ShAmtC =
- TLO.DAG.getValidShiftAmountConstant(Src, DemandedElts);
- if (!ShAmtC || ShAmtC->uge(BitWidth))
+ const APInt *ShAmtC =
+ TLO.DAG.getValidShiftAmountConstant(Src, DemandedElts);
+ if (!ShAmtC || ShAmtC->uge(BitWidth))
break;
uint64_t ShVal = ShAmtC->getZExtValue();
@@ -2024,12 +2024,12 @@ bool TargetLowering::SimplifyDemandedBits(
if (!(HighBits & DemandedBits)) {
// None of the shifted in bits are needed. Add a truncate of the
// shift input, then shift it.
- SDValue NewShAmt = TLO.DAG.getConstant(
- ShVal, dl, getShiftAmountTy(VT, DL, TLO.LegalTypes()));
+ SDValue NewShAmt = TLO.DAG.getConstant(
+ ShVal, dl, getShiftAmountTy(VT, DL, TLO.LegalTypes()));
SDValue NewTrunc =
TLO.DAG.getNode(ISD::TRUNCATE, dl, VT, Src.getOperand(0));
return TLO.CombineTo(
- Op, TLO.DAG.getNode(ISD::SRL, dl, VT, NewTrunc, NewShAmt));
+ Op, TLO.DAG.getNode(ISD::SRL, dl, VT, NewTrunc, NewShAmt));
}
break;
}
@@ -2054,14 +2054,14 @@ bool TargetLowering::SimplifyDemandedBits(
case ISD::EXTRACT_VECTOR_ELT: {
SDValue Src = Op.getOperand(0);
SDValue Idx = Op.getOperand(1);
- ElementCount SrcEltCnt = Src.getValueType().getVectorElementCount();
+ ElementCount SrcEltCnt = Src.getValueType().getVectorElementCount();
unsigned EltBitWidth = Src.getScalarValueSizeInBits();
- if (SrcEltCnt.isScalable())
- return false;
-
+ if (SrcEltCnt.isScalable())
+ return false;
+
// Demand the bits from every vector element without a constant index.
- unsigned NumSrcElts = SrcEltCnt.getFixedValue();
+ unsigned NumSrcElts = SrcEltCnt.getFixedValue();
APInt DemandedSrcElts = APInt::getAllOnesValue(NumSrcElts);
if (auto *CIdx = dyn_cast<ConstantSDNode>(Idx))
if (CIdx->getAPIntValue().ult(NumSrcElts))
@@ -2277,11 +2277,11 @@ bool TargetLowering::SimplifyDemandedBits(
}
if (VT.isInteger())
return TLO.CombineTo(Op, TLO.DAG.getConstant(Known.One, dl, VT));
- if (VT.isFloatingPoint())
- return TLO.CombineTo(
- Op,
- TLO.DAG.getConstantFP(
- APFloat(TLO.DAG.EVTToAPFloatSemantics(VT), Known.One), dl, VT));
+ if (VT.isFloatingPoint())
+ return TLO.CombineTo(
+ Op,
+ TLO.DAG.getConstantFP(
+ APFloat(TLO.DAG.EVTToAPFloatSemantics(VT), Known.One), dl, VT));
}
return false;
@@ -2643,9 +2643,9 @@ bool TargetLowering::SimplifyDemandedVectorElts(
KnownZero, TLO, Depth + 1))
return true;
- KnownUndef.setBitVal(Idx, Scl.isUndef());
+ KnownUndef.setBitVal(Idx, Scl.isUndef());
- KnownZero.setBitVal(Idx, isNullConstant(Scl) || isNullFPConstant(Scl));
+ KnownZero.setBitVal(Idx, isNullConstant(Scl) || isNullFPConstant(Scl));
break;
}
@@ -3393,74 +3393,74 @@ SDValue TargetLowering::foldSetCCWithBinOp(EVT VT, SDValue N0, SDValue N1,
return DAG.getSetCC(DL, VT, X, YShl1, Cond);
}
-static SDValue simplifySetCCWithCTPOP(const TargetLowering &TLI, EVT VT,
- SDValue N0, const APInt &C1,
- ISD::CondCode Cond, const SDLoc &dl,
- SelectionDAG &DAG) {
- // Look through truncs that don't change the value of a ctpop.
- // FIXME: Add vector support? Need to be careful with setcc result type below.
- SDValue CTPOP = N0;
- if (N0.getOpcode() == ISD::TRUNCATE && N0.hasOneUse() && !VT.isVector() &&
- N0.getScalarValueSizeInBits() > Log2_32(N0.getOperand(0).getScalarValueSizeInBits()))
- CTPOP = N0.getOperand(0);
-
- if (CTPOP.getOpcode() != ISD::CTPOP || !CTPOP.hasOneUse())
- return SDValue();
-
- EVT CTVT = CTPOP.getValueType();
- SDValue CTOp = CTPOP.getOperand(0);
-
- // If this is a vector CTPOP, keep the CTPOP if it is legal.
- // TODO: Should we check if CTPOP is legal(or custom) for scalars?
- if (VT.isVector() && TLI.isOperationLegal(ISD::CTPOP, CTVT))
- return SDValue();
-
- // (ctpop x) u< 2 -> (x & x-1) == 0
- // (ctpop x) u> 1 -> (x & x-1) != 0
- if (Cond == ISD::SETULT || Cond == ISD::SETUGT) {
- unsigned CostLimit = TLI.getCustomCtpopCost(CTVT, Cond);
- if (C1.ugt(CostLimit + (Cond == ISD::SETULT)))
- return SDValue();
- if (C1 == 0 && (Cond == ISD::SETULT))
- return SDValue(); // This is handled elsewhere.
-
- unsigned Passes = C1.getLimitedValue() - (Cond == ISD::SETULT);
-
- SDValue NegOne = DAG.getAllOnesConstant(dl, CTVT);
- SDValue Result = CTOp;
- for (unsigned i = 0; i < Passes; i++) {
- SDValue Add = DAG.getNode(ISD::ADD, dl, CTVT, Result, NegOne);
- Result = DAG.getNode(ISD::AND, dl, CTVT, Result, Add);
- }
- ISD::CondCode CC = Cond == ISD::SETULT ? ISD::SETEQ : ISD::SETNE;
- return DAG.getSetCC(dl, VT, Result, DAG.getConstant(0, dl, CTVT), CC);
- }
-
- // If ctpop is not supported, expand a power-of-2 comparison based on it.
- if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) && C1 == 1) {
- // For scalars, keep CTPOP if it is legal or custom.
- if (!VT.isVector() && TLI.isOperationLegalOrCustom(ISD::CTPOP, CTVT))
- return SDValue();
- // This is based on X86's custom lowering for CTPOP which produces more
- // instructions than the expansion here.
-
- // (ctpop x) == 1 --> (x != 0) && ((x & x-1) == 0)
- // (ctpop x) != 1 --> (x == 0) || ((x & x-1) != 0)
- SDValue Zero = DAG.getConstant(0, dl, CTVT);
- SDValue NegOne = DAG.getAllOnesConstant(dl, CTVT);
- assert(CTVT.isInteger());
- ISD::CondCode InvCond = ISD::getSetCCInverse(Cond, CTVT);
- SDValue Add = DAG.getNode(ISD::ADD, dl, CTVT, CTOp, NegOne);
- SDValue And = DAG.getNode(ISD::AND, dl, CTVT, CTOp, Add);
- SDValue LHS = DAG.getSetCC(dl, VT, CTOp, Zero, InvCond);
- SDValue RHS = DAG.getSetCC(dl, VT, And, Zero, Cond);
- unsigned LogicOpcode = Cond == ISD::SETEQ ? ISD::AND : ISD::OR;
- return DAG.getNode(LogicOpcode, dl, VT, LHS, RHS);
- }
-
- return SDValue();
-}
-
+static SDValue simplifySetCCWithCTPOP(const TargetLowering &TLI, EVT VT,
+ SDValue N0, const APInt &C1,
+ ISD::CondCode Cond, const SDLoc &dl,
+ SelectionDAG &DAG) {
+ // Look through truncs that don't change the value of a ctpop.
+ // FIXME: Add vector support? Need to be careful with setcc result type below.
+ SDValue CTPOP = N0;
+ if (N0.getOpcode() == ISD::TRUNCATE && N0.hasOneUse() && !VT.isVector() &&
+ N0.getScalarValueSizeInBits() > Log2_32(N0.getOperand(0).getScalarValueSizeInBits()))
+ CTPOP = N0.getOperand(0);
+
+ if (CTPOP.getOpcode() != ISD::CTPOP || !CTPOP.hasOneUse())
+ return SDValue();
+
+ EVT CTVT = CTPOP.getValueType();
+ SDValue CTOp = CTPOP.getOperand(0);
+
+ // If this is a vector CTPOP, keep the CTPOP if it is legal.
+ // TODO: Should we check if CTPOP is legal(or custom) for scalars?
+ if (VT.isVector() && TLI.isOperationLegal(ISD::CTPOP, CTVT))
+ return SDValue();
+
+ // (ctpop x) u< 2 -> (x & x-1) == 0
+ // (ctpop x) u> 1 -> (x & x-1) != 0
+ if (Cond == ISD::SETULT || Cond == ISD::SETUGT) {
+ unsigned CostLimit = TLI.getCustomCtpopCost(CTVT, Cond);
+ if (C1.ugt(CostLimit + (Cond == ISD::SETULT)))
+ return SDValue();
+ if (C1 == 0 && (Cond == ISD::SETULT))
+ return SDValue(); // This is handled elsewhere.
+
+ unsigned Passes = C1.getLimitedValue() - (Cond == ISD::SETULT);
+
+ SDValue NegOne = DAG.getAllOnesConstant(dl, CTVT);
+ SDValue Result = CTOp;
+ for (unsigned i = 0; i < Passes; i++) {
+ SDValue Add = DAG.getNode(ISD::ADD, dl, CTVT, Result, NegOne);
+ Result = DAG.getNode(ISD::AND, dl, CTVT, Result, Add);
+ }
+ ISD::CondCode CC = Cond == ISD::SETULT ? ISD::SETEQ : ISD::SETNE;
+ return DAG.getSetCC(dl, VT, Result, DAG.getConstant(0, dl, CTVT), CC);
+ }
+
+ // If ctpop is not supported, expand a power-of-2 comparison based on it.
+ if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) && C1 == 1) {
+ // For scalars, keep CTPOP if it is legal or custom.
+ if (!VT.isVector() && TLI.isOperationLegalOrCustom(ISD::CTPOP, CTVT))
+ return SDValue();
+ // This is based on X86's custom lowering for CTPOP which produces more
+ // instructions than the expansion here.
+
+ // (ctpop x) == 1 --> (x != 0) && ((x & x-1) == 0)
+ // (ctpop x) != 1 --> (x == 0) || ((x & x-1) != 0)
+ SDValue Zero = DAG.getConstant(0, dl, CTVT);
+ SDValue NegOne = DAG.getAllOnesConstant(dl, CTVT);
+ assert(CTVT.isInteger());
+ ISD::CondCode InvCond = ISD::getSetCCInverse(Cond, CTVT);
+ SDValue Add = DAG.getNode(ISD::ADD, dl, CTVT, CTOp, NegOne);
+ SDValue And = DAG.getNode(ISD::AND, dl, CTVT, CTOp, Add);
+ SDValue LHS = DAG.getSetCC(dl, VT, CTOp, Zero, InvCond);
+ SDValue RHS = DAG.getSetCC(dl, VT, And, Zero, Cond);
+ unsigned LogicOpcode = Cond == ISD::SETEQ ? ISD::AND : ISD::OR;
+ return DAG.getNode(LogicOpcode, dl, VT, LHS, RHS);
+ }
+
+ return SDValue();
+}
+
/// Try to simplify a setcc built with the specified operands and cc. If it is
/// unable to simplify it, return a null SDValue.
SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
@@ -3477,11 +3477,11 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
// Ensure that the constant occurs on the RHS and fold constant comparisons.
// TODO: Handle non-splat vector constants. All undef causes trouble.
- // FIXME: We can't yet fold constant scalable vector splats, so avoid an
- // infinite loop here when we encounter one.
+ // FIXME: We can't yet fold constant scalable vector splats, so avoid an
+ // infinite loop here when we encounter one.
ISD::CondCode SwappedCC = ISD::getSetCCSwappedOperands(Cond);
if (isConstOrConstSplat(N0) &&
- (!OpVT.isScalableVector() || !isConstOrConstSplat(N1)) &&
+ (!OpVT.isScalableVector() || !isConstOrConstSplat(N1)) &&
(DCI.isBeforeLegalizeOps() ||
isCondCodeLegal(SwappedCC, N0.getSimpleValueType())))
return DAG.getSetCC(dl, VT, N1, N0, SwappedCC);
@@ -3493,46 +3493,46 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
if (!isConstOrConstSplat(N0) && !isConstOrConstSplat(N1) &&
(DCI.isBeforeLegalizeOps() ||
isCondCodeLegal(SwappedCC, N0.getSimpleValueType())) &&
- DAG.doesNodeExist(ISD::SUB, DAG.getVTList(OpVT), {N1, N0}) &&
- !DAG.doesNodeExist(ISD::SUB, DAG.getVTList(OpVT), {N0, N1}))
+ DAG.doesNodeExist(ISD::SUB, DAG.getVTList(OpVT), {N1, N0}) &&
+ !DAG.doesNodeExist(ISD::SUB, DAG.getVTList(OpVT), {N0, N1}))
return DAG.getSetCC(dl, VT, N1, N0, SwappedCC);
- if (auto *N1C = isConstOrConstSplat(N1)) {
+ if (auto *N1C = isConstOrConstSplat(N1)) {
const APInt &C1 = N1C->getAPIntValue();
- // Optimize some CTPOP cases.
- if (SDValue V = simplifySetCCWithCTPOP(*this, VT, N0, C1, Cond, dl, DAG))
- return V;
-
+ // Optimize some CTPOP cases.
+ if (SDValue V = simplifySetCCWithCTPOP(*this, VT, N0, C1, Cond, dl, DAG))
+ return V;
+
// If the LHS is '(srl (ctlz x), 5)', the RHS is 0/1, and this is an
// equality comparison, then we're just comparing whether X itself is
// zero.
if (N0.getOpcode() == ISD::SRL && (C1.isNullValue() || C1.isOneValue()) &&
N0.getOperand(0).getOpcode() == ISD::CTLZ &&
- isPowerOf2_32(N0.getScalarValueSizeInBits())) {
- if (ConstantSDNode *ShAmt = isConstOrConstSplat(N0.getOperand(1))) {
- if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
- ShAmt->getAPIntValue() == Log2_32(N0.getScalarValueSizeInBits())) {
- if ((C1 == 0) == (Cond == ISD::SETEQ)) {
- // (srl (ctlz x), 5) == 0 -> X != 0
- // (srl (ctlz x), 5) != 1 -> X != 0
- Cond = ISD::SETNE;
- } else {
- // (srl (ctlz x), 5) != 0 -> X == 0
- // (srl (ctlz x), 5) == 1 -> X == 0
- Cond = ISD::SETEQ;
- }
- SDValue Zero = DAG.getConstant(0, dl, N0.getValueType());
- return DAG.getSetCC(dl, VT, N0.getOperand(0).getOperand(0), Zero,
- Cond);
+ isPowerOf2_32(N0.getScalarValueSizeInBits())) {
+ if (ConstantSDNode *ShAmt = isConstOrConstSplat(N0.getOperand(1))) {
+ if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
+ ShAmt->getAPIntValue() == Log2_32(N0.getScalarValueSizeInBits())) {
+ if ((C1 == 0) == (Cond == ISD::SETEQ)) {
+ // (srl (ctlz x), 5) == 0 -> X != 0
+ // (srl (ctlz x), 5) != 1 -> X != 0
+ Cond = ISD::SETNE;
+ } else {
+ // (srl (ctlz x), 5) != 0 -> X == 0
+ // (srl (ctlz x), 5) == 1 -> X == 0
+ Cond = ISD::SETEQ;
+ }
+ SDValue Zero = DAG.getConstant(0, dl, N0.getValueType());
+ return DAG.getSetCC(dl, VT, N0.getOperand(0).getOperand(0), Zero,
+ Cond);
}
}
}
- }
+ }
- // FIXME: Support vectors.
- if (auto *N1C = dyn_cast<ConstantSDNode>(N1.getNode())) {
- const APInt &C1 = N1C->getAPIntValue();
+ // FIXME: Support vectors.
+ if (auto *N1C = dyn_cast<ConstantSDNode>(N1.getNode())) {
+ const APInt &C1 = N1C->getAPIntValue();
// (zext x) == C --> x == (trunc C)
// (sext x) == C --> x == (trunc C)
@@ -3666,12 +3666,12 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
shouldReduceLoadWidth(Lod, ISD::NON_EXTLOAD, newVT)) {
SDValue Ptr = Lod->getBasePtr();
if (bestOffset != 0)
- Ptr =
- DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(bestOffset), dl);
- SDValue NewLoad =
- DAG.getLoad(newVT, dl, Lod->getChain(), Ptr,
- Lod->getPointerInfo().getWithOffset(bestOffset),
- Lod->getOriginalAlign());
+ Ptr =
+ DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(bestOffset), dl);
+ SDValue NewLoad =
+ DAG.getLoad(newVT, dl, Lod->getChain(), Ptr,
+ Lod->getPointerInfo().getWithOffset(bestOffset),
+ Lod->getOriginalAlign());
return DAG.getSetCC(dl, VT,
DAG.getNode(ISD::AND, dl, newVT, NewLoad,
DAG.getConstant(bestMask.trunc(bestWidth),
@@ -3736,9 +3736,9 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
break; // todo, be more careful with signed comparisons
}
} else if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG &&
- (Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
- !isSExtCheaperThanZExt(cast<VTSDNode>(N0.getOperand(1))->getVT(),
- OpVT)) {
+ (Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
+ !isSExtCheaperThanZExt(cast<VTSDNode>(N0.getOperand(1))->getVT(),
+ OpVT)) {
EVT ExtSrcTy = cast<VTSDNode>(N0.getOperand(1))->getVT();
unsigned ExtSrcTyBits = ExtSrcTy.getSizeInBits();
EVT ExtDstTy = N0.getValueType();
@@ -3747,18 +3747,18 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
// If the constant doesn't fit into the number of bits for the source of
// the sign extension, it is impossible for both sides to be equal.
if (C1.getMinSignedBits() > ExtSrcTyBits)
- return DAG.getBoolConstant(Cond == ISD::SETNE, dl, VT, OpVT);
+ return DAG.getBoolConstant(Cond == ISD::SETNE, dl, VT, OpVT);
- assert(ExtDstTy == N0.getOperand(0).getValueType() &&
- ExtDstTy != ExtSrcTy && "Unexpected types!");
- APInt Imm = APInt::getLowBitsSet(ExtDstTyBits, ExtSrcTyBits);
- SDValue ZextOp = DAG.getNode(ISD::AND, dl, ExtDstTy, N0.getOperand(0),
- DAG.getConstant(Imm, dl, ExtDstTy));
+ assert(ExtDstTy == N0.getOperand(0).getValueType() &&
+ ExtDstTy != ExtSrcTy && "Unexpected types!");
+ APInt Imm = APInt::getLowBitsSet(ExtDstTyBits, ExtSrcTyBits);
+ SDValue ZextOp = DAG.getNode(ISD::AND, dl, ExtDstTy, N0.getOperand(0),
+ DAG.getConstant(Imm, dl, ExtDstTy));
if (!DCI.isCalledByLegalizer())
DCI.AddToWorklist(ZextOp.getNode());
// Otherwise, make this a use of a zext.
return DAG.getSetCC(dl, VT, ZextOp,
- DAG.getConstant(C1 & Imm, dl, ExtDstTy), Cond);
+ DAG.getConstant(C1 & Imm, dl, ExtDstTy), Cond);
} else if ((N1C->isNullValue() || N1C->isOne()) &&
(Cond == ISD::SETEQ || Cond == ISD::SETNE)) {
// SETCC (SETCC), [0|1], [EQ|NE] -> SETCC
@@ -3782,7 +3782,7 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
(N0.getOpcode() == ISD::AND &&
N0.getOperand(0).getOpcode() == ISD::XOR &&
N0.getOperand(1) == N0.getOperand(0).getOperand(1))) &&
- isOneConstant(N0.getOperand(1))) {
+ isOneConstant(N0.getOperand(1))) {
// If this is (X^1) == 0/1, swap the RHS and eliminate the xor. We
// can only do this if the top bits are known zero.
unsigned BitWidth = N0.getValueSizeInBits();
@@ -3826,7 +3826,7 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
return DAG.getSetCC(dl, VT, XorLHS, XorRHS, Cond);
}
}
- if (Op0.getOpcode() == ISD::AND && isOneConstant(Op0.getOperand(1))) {
+ if (Op0.getOpcode() == ISD::AND && isOneConstant(Op0.getOperand(1))) {
// If this is (X&1) == / != 1, normalize it to (X&1) != / == 0.
if (Op0.getValueType().bitsGT(VT))
Op0 = DAG.getNode(ISD::AND, dl, VT,
@@ -3964,67 +3964,67 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
if (SDValue CC = optimizeSetCCByHoistingAndByConstFromLogicalShift(
VT, N0, N1, Cond, DCI, dl))
return CC;
-
- // For all/any comparisons, replace or(x,shl(y,bw/2)) with and/or(x,y).
- // For example, when high 32-bits of i64 X are known clear:
- // all bits clear: (X | (Y<<32)) == 0 --> (X | Y) == 0
- // all bits set: (X | (Y<<32)) == -1 --> (X & Y) == -1
- bool CmpZero = N1C->getAPIntValue().isNullValue();
- bool CmpNegOne = N1C->getAPIntValue().isAllOnesValue();
- if ((CmpZero || CmpNegOne) && N0.hasOneUse()) {
- // Match or(lo,shl(hi,bw/2)) pattern.
- auto IsConcat = [&](SDValue V, SDValue &Lo, SDValue &Hi) {
- unsigned EltBits = V.getScalarValueSizeInBits();
- if (V.getOpcode() != ISD::OR || (EltBits % 2) != 0)
- return false;
- SDValue LHS = V.getOperand(0);
- SDValue RHS = V.getOperand(1);
- APInt HiBits = APInt::getHighBitsSet(EltBits, EltBits / 2);
- // Unshifted element must have zero upperbits.
- if (RHS.getOpcode() == ISD::SHL &&
- isa<ConstantSDNode>(RHS.getOperand(1)) &&
- RHS.getConstantOperandAPInt(1) == (EltBits / 2) &&
- DAG.MaskedValueIsZero(LHS, HiBits)) {
- Lo = LHS;
- Hi = RHS.getOperand(0);
- return true;
- }
- if (LHS.getOpcode() == ISD::SHL &&
- isa<ConstantSDNode>(LHS.getOperand(1)) &&
- LHS.getConstantOperandAPInt(1) == (EltBits / 2) &&
- DAG.MaskedValueIsZero(RHS, HiBits)) {
- Lo = RHS;
- Hi = LHS.getOperand(0);
- return true;
- }
- return false;
- };
-
- auto MergeConcat = [&](SDValue Lo, SDValue Hi) {
- unsigned EltBits = N0.getScalarValueSizeInBits();
- unsigned HalfBits = EltBits / 2;
- APInt HiBits = APInt::getHighBitsSet(EltBits, HalfBits);
- SDValue LoBits = DAG.getConstant(~HiBits, dl, OpVT);
- SDValue HiMask = DAG.getNode(ISD::AND, dl, OpVT, Hi, LoBits);
- SDValue NewN0 =
- DAG.getNode(CmpZero ? ISD::OR : ISD::AND, dl, OpVT, Lo, HiMask);
- SDValue NewN1 = CmpZero ? DAG.getConstant(0, dl, OpVT) : LoBits;
- return DAG.getSetCC(dl, VT, NewN0, NewN1, Cond);
- };
-
- SDValue Lo, Hi;
- if (IsConcat(N0, Lo, Hi))
- return MergeConcat(Lo, Hi);
-
- if (N0.getOpcode() == ISD::AND || N0.getOpcode() == ISD::OR) {
- SDValue Lo0, Lo1, Hi0, Hi1;
- if (IsConcat(N0.getOperand(0), Lo0, Hi0) &&
- IsConcat(N0.getOperand(1), Lo1, Hi1)) {
- return MergeConcat(DAG.getNode(N0.getOpcode(), dl, OpVT, Lo0, Lo1),
- DAG.getNode(N0.getOpcode(), dl, OpVT, Hi0, Hi1));
- }
- }
- }
+
+ // For all/any comparisons, replace or(x,shl(y,bw/2)) with and/or(x,y).
+ // For example, when high 32-bits of i64 X are known clear:
+ // all bits clear: (X | (Y<<32)) == 0 --> (X | Y) == 0
+ // all bits set: (X | (Y<<32)) == -1 --> (X & Y) == -1
+ bool CmpZero = N1C->getAPIntValue().isNullValue();
+ bool CmpNegOne = N1C->getAPIntValue().isAllOnesValue();
+ if ((CmpZero || CmpNegOne) && N0.hasOneUse()) {
+ // Match or(lo,shl(hi,bw/2)) pattern.
+ auto IsConcat = [&](SDValue V, SDValue &Lo, SDValue &Hi) {
+ unsigned EltBits = V.getScalarValueSizeInBits();
+ if (V.getOpcode() != ISD::OR || (EltBits % 2) != 0)
+ return false;
+ SDValue LHS = V.getOperand(0);
+ SDValue RHS = V.getOperand(1);
+ APInt HiBits = APInt::getHighBitsSet(EltBits, EltBits / 2);
+ // Unshifted element must have zero upperbits.
+ if (RHS.getOpcode() == ISD::SHL &&
+ isa<ConstantSDNode>(RHS.getOperand(1)) &&
+ RHS.getConstantOperandAPInt(1) == (EltBits / 2) &&
+ DAG.MaskedValueIsZero(LHS, HiBits)) {
+ Lo = LHS;
+ Hi = RHS.getOperand(0);
+ return true;
+ }
+ if (LHS.getOpcode() == ISD::SHL &&
+ isa<ConstantSDNode>(LHS.getOperand(1)) &&
+ LHS.getConstantOperandAPInt(1) == (EltBits / 2) &&
+ DAG.MaskedValueIsZero(RHS, HiBits)) {
+ Lo = RHS;
+ Hi = LHS.getOperand(0);
+ return true;
+ }
+ return false;
+ };
+
+ auto MergeConcat = [&](SDValue Lo, SDValue Hi) {
+ unsigned EltBits = N0.getScalarValueSizeInBits();
+ unsigned HalfBits = EltBits / 2;
+ APInt HiBits = APInt::getHighBitsSet(EltBits, HalfBits);
+ SDValue LoBits = DAG.getConstant(~HiBits, dl, OpVT);
+ SDValue HiMask = DAG.getNode(ISD::AND, dl, OpVT, Hi, LoBits);
+ SDValue NewN0 =
+ DAG.getNode(CmpZero ? ISD::OR : ISD::AND, dl, OpVT, Lo, HiMask);
+ SDValue NewN1 = CmpZero ? DAG.getConstant(0, dl, OpVT) : LoBits;
+ return DAG.getSetCC(dl, VT, NewN0, NewN1, Cond);
+ };
+
+ SDValue Lo, Hi;
+ if (IsConcat(N0, Lo, Hi))
+ return MergeConcat(Lo, Hi);
+
+ if (N0.getOpcode() == ISD::AND || N0.getOpcode() == ISD::OR) {
+ SDValue Lo0, Lo1, Hi0, Hi1;
+ if (IsConcat(N0.getOperand(0), Lo0, Hi0) &&
+ IsConcat(N0.getOperand(1), Lo1, Hi1)) {
+ return MergeConcat(DAG.getNode(N0.getOpcode(), dl, OpVT, Lo0, Lo1),
+ DAG.getNode(N0.getOpcode(), dl, OpVT, Hi0, Hi1));
+ }
+ }
+ }
}
// If we have "setcc X, C0", check to see if we can shrink the immediate
@@ -4032,20 +4032,20 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
// TODO: Support this for vectors after legalize ops.
if (!VT.isVector() || DCI.isBeforeLegalizeOps()) {
// SETUGT X, SINTMAX -> SETLT X, 0
- // SETUGE X, SINTMIN -> SETLT X, 0
- if ((Cond == ISD::SETUGT && C1.isMaxSignedValue()) ||
- (Cond == ISD::SETUGE && C1.isMinSignedValue()))
+ // SETUGE X, SINTMIN -> SETLT X, 0
+ if ((Cond == ISD::SETUGT && C1.isMaxSignedValue()) ||
+ (Cond == ISD::SETUGE && C1.isMinSignedValue()))
return DAG.getSetCC(dl, VT, N0,
DAG.getConstant(0, dl, N1.getValueType()),
ISD::SETLT);
// SETULT X, SINTMIN -> SETGT X, -1
- // SETULE X, SINTMAX -> SETGT X, -1
- if ((Cond == ISD::SETULT && C1.isMinSignedValue()) ||
- (Cond == ISD::SETULE && C1.isMaxSignedValue()))
- return DAG.getSetCC(dl, VT, N0,
- DAG.getAllOnesConstant(dl, N1.getValueType()),
- ISD::SETGT);
+ // SETULE X, SINTMAX -> SETGT X, -1
+ if ((Cond == ISD::SETULT && C1.isMinSignedValue()) ||
+ (Cond == ISD::SETULE && C1.isMaxSignedValue()))
+ return DAG.getSetCC(dl, VT, N0,
+ DAG.getAllOnesConstant(dl, N1.getValueType()),
+ ISD::SETGT);
}
}
@@ -4056,13 +4056,13 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
const APInt &C1 = N1C->getAPIntValue();
EVT ShValTy = N0.getValueType();
- // Fold bit comparisons when we can. This will result in an
- // incorrect value when boolean false is negative one, unless
- // the bitsize is 1 in which case the false value is the same
- // in practice regardless of the representation.
- if ((VT.getSizeInBits() == 1 ||
- getBooleanContents(N0.getValueType()) == ZeroOrOneBooleanContent) &&
- (Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
+ // Fold bit comparisons when we can. This will result in an
+ // incorrect value when boolean false is negative one, unless
+ // the bitsize is 1 in which case the false value is the same
+ // in practice regardless of the representation.
+ if ((VT.getSizeInBits() == 1 ||
+ getBooleanContents(N0.getValueType()) == ZeroOrOneBooleanContent) &&
+ (Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
(VT == ShValTy || (isTypeLegal(VT) && VT.bitsLE(ShValTy))) &&
N0.getOpcode() == ISD::AND) {
if (auto *AndRHS = dyn_cast<ConstantSDNode>(N0.getOperand(1))) {
@@ -4458,8 +4458,8 @@ const char *TargetLowering::LowerXConstraint(EVT ConstraintVT) const {
}
SDValue TargetLowering::LowerAsmOutputForConstraint(
- SDValue &Chain, SDValue &Flag, const SDLoc &DL,
- const AsmOperandInfo &OpInfo, SelectionDAG &DAG) const {
+ SDValue &Chain, SDValue &Flag, const SDLoc &DL,
+ const AsmOperandInfo &OpInfo, SelectionDAG &DAG) const {
return SDValue();
}
@@ -5033,15 +5033,15 @@ static SDValue BuildExactSDIV(const TargetLowering &TLI, SDNode *N,
return SDValue();
SDValue Shift, Factor;
- if (VT.isFixedLengthVector()) {
+ if (VT.isFixedLengthVector()) {
Shift = DAG.getBuildVector(ShVT, dl, Shifts);
Factor = DAG.getBuildVector(VT, dl, Factors);
- } else if (VT.isScalableVector()) {
- assert(Shifts.size() == 1 && Factors.size() == 1 &&
- "Expected matchUnaryPredicate to return one element for scalable "
- "vectors");
- Shift = DAG.getSplatVector(ShVT, dl, Shifts[0]);
- Factor = DAG.getSplatVector(VT, dl, Factors[0]);
+ } else if (VT.isScalableVector()) {
+ assert(Shifts.size() == 1 && Factors.size() == 1 &&
+ "Expected matchUnaryPredicate to return one element for scalable "
+ "vectors");
+ Shift = DAG.getSplatVector(ShVT, dl, Shifts[0]);
+ Factor = DAG.getSplatVector(VT, dl, Factors[0]);
} else {
Shift = Shifts[0];
Factor = Factors[0];
@@ -5134,20 +5134,20 @@ SDValue TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG,
return SDValue();
SDValue MagicFactor, Factor, Shift, ShiftMask;
- if (VT.isFixedLengthVector()) {
+ if (VT.isFixedLengthVector()) {
MagicFactor = DAG.getBuildVector(VT, dl, MagicFactors);
Factor = DAG.getBuildVector(VT, dl, Factors);
Shift = DAG.getBuildVector(ShVT, dl, Shifts);
ShiftMask = DAG.getBuildVector(VT, dl, ShiftMasks);
- } else if (VT.isScalableVector()) {
- assert(MagicFactors.size() == 1 && Factors.size() == 1 &&
- Shifts.size() == 1 && ShiftMasks.size() == 1 &&
- "Expected matchUnaryPredicate to return one element for scalable "
- "vectors");
- MagicFactor = DAG.getSplatVector(VT, dl, MagicFactors[0]);
- Factor = DAG.getSplatVector(VT, dl, Factors[0]);
- Shift = DAG.getSplatVector(ShVT, dl, Shifts[0]);
- ShiftMask = DAG.getSplatVector(VT, dl, ShiftMasks[0]);
+ } else if (VT.isScalableVector()) {
+ assert(MagicFactors.size() == 1 && Factors.size() == 1 &&
+ Shifts.size() == 1 && ShiftMasks.size() == 1 &&
+ "Expected matchUnaryPredicate to return one element for scalable "
+ "vectors");
+ MagicFactor = DAG.getSplatVector(VT, dl, MagicFactors[0]);
+ Factor = DAG.getSplatVector(VT, dl, Factors[0]);
+ Shift = DAG.getSplatVector(ShVT, dl, Shifts[0]);
+ ShiftMask = DAG.getSplatVector(VT, dl, ShiftMasks[0]);
} else {
MagicFactor = MagicFactors[0];
Factor = Factors[0];
@@ -5261,19 +5261,19 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
return SDValue();
SDValue PreShift, PostShift, MagicFactor, NPQFactor;
- if (VT.isFixedLengthVector()) {
+ if (VT.isFixedLengthVector()) {
PreShift = DAG.getBuildVector(ShVT, dl, PreShifts);
MagicFactor = DAG.getBuildVector(VT, dl, MagicFactors);
NPQFactor = DAG.getBuildVector(VT, dl, NPQFactors);
PostShift = DAG.getBuildVector(ShVT, dl, PostShifts);
- } else if (VT.isScalableVector()) {
- assert(PreShifts.size() == 1 && MagicFactors.size() == 1 &&
- NPQFactors.size() == 1 && PostShifts.size() == 1 &&
- "Expected matchUnaryPredicate to return one for scalable vectors");
- PreShift = DAG.getSplatVector(ShVT, dl, PreShifts[0]);
- MagicFactor = DAG.getSplatVector(VT, dl, MagicFactors[0]);
- NPQFactor = DAG.getSplatVector(VT, dl, NPQFactors[0]);
- PostShift = DAG.getSplatVector(ShVT, dl, PostShifts[0]);
+ } else if (VT.isScalableVector()) {
+ assert(PreShifts.size() == 1 && MagicFactors.size() == 1 &&
+ NPQFactors.size() == 1 && PostShifts.size() == 1 &&
+ "Expected matchUnaryPredicate to return one for scalable vectors");
+ PreShift = DAG.getSplatVector(ShVT, dl, PreShifts[0]);
+ MagicFactor = DAG.getSplatVector(VT, dl, MagicFactors[0]);
+ NPQFactor = DAG.getSplatVector(VT, dl, NPQFactors[0]);
+ PostShift = DAG.getSplatVector(ShVT, dl, PostShifts[0]);
} else {
PreShift = PreShifts[0];
MagicFactor = MagicFactors[0];
@@ -5325,10 +5325,10 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
Q = DAG.getNode(ISD::SRL, dl, VT, Q, PostShift);
Created.push_back(Q.getNode());
- EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
-
+ EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
+
SDValue One = DAG.getConstant(1, dl, VT);
- SDValue IsOne = DAG.getSetCC(dl, SetCCVT, N1, One, ISD::SETEQ);
+ SDValue IsOne = DAG.getSetCC(dl, SetCCVT, N1, One, ISD::SETEQ);
return DAG.getSelect(dl, VT, IsOne, N0, Q);
}
@@ -5755,7 +5755,7 @@ TargetLowering::prepareSREMEqFold(EVT SETCCVT, SDValue REMNode,
return SDValue();
SDValue PVal, AVal, KVal, QVal;
- if (VT.isFixedLengthVector()) {
+ if (VT.isFixedLengthVector()) {
if (HadOneDivisor) {
// Try to turn PAmts into a splat, since we don't care about the values
// that are currently '0'. If we can't, just keep '0'`s.
@@ -5774,15 +5774,15 @@ TargetLowering::prepareSREMEqFold(EVT SETCCVT, SDValue REMNode,
AVal = DAG.getBuildVector(VT, DL, AAmts);
KVal = DAG.getBuildVector(ShVT, DL, KAmts);
QVal = DAG.getBuildVector(VT, DL, QAmts);
- } else if (VT.isScalableVector()) {
- assert(PAmts.size() == 1 && AAmts.size() == 1 && KAmts.size() == 1 &&
- QAmts.size() == 1 &&
- "Expected matchUnaryPredicate to return one element for scalable "
- "vectors");
- PVal = DAG.getSplatVector(VT, DL, PAmts[0]);
- AVal = DAG.getSplatVector(VT, DL, AAmts[0]);
- KVal = DAG.getSplatVector(ShVT, DL, KAmts[0]);
- QVal = DAG.getSplatVector(VT, DL, QAmts[0]);
+ } else if (VT.isScalableVector()) {
+ assert(PAmts.size() == 1 && AAmts.size() == 1 && KAmts.size() == 1 &&
+ QAmts.size() == 1 &&
+ "Expected matchUnaryPredicate to return one element for scalable "
+ "vectors");
+ PVal = DAG.getSplatVector(VT, DL, PAmts[0]);
+ AVal = DAG.getSplatVector(VT, DL, AAmts[0]);
+ KVal = DAG.getSplatVector(ShVT, DL, KAmts[0]);
+ QVal = DAG.getSplatVector(VT, DL, QAmts[0]);
} else {
PVal = PAmts[0];
AVal = AAmts[0];
@@ -5877,28 +5877,28 @@ verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const {
return false;
}
-SDValue TargetLowering::getSqrtInputTest(SDValue Op, SelectionDAG &DAG,
- const DenormalMode &Mode) const {
- SDLoc DL(Op);
- EVT VT = Op.getValueType();
- EVT CCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
- SDValue FPZero = DAG.getConstantFP(0.0, DL, VT);
- // Testing it with denormal inputs to avoid wrong estimate.
- if (Mode.Input == DenormalMode::IEEE) {
- // This is specifically a check for the handling of denormal inputs,
- // not the result.
-
- // Test = fabs(X) < SmallestNormal
- const fltSemantics &FltSem = DAG.EVTToAPFloatSemantics(VT);
- APFloat SmallestNorm = APFloat::getSmallestNormalized(FltSem);
- SDValue NormC = DAG.getConstantFP(SmallestNorm, DL, VT);
- SDValue Fabs = DAG.getNode(ISD::FABS, DL, VT, Op);
- return DAG.getSetCC(DL, CCVT, Fabs, NormC, ISD::SETLT);
- }
- // Test = X == 0.0
- return DAG.getSetCC(DL, CCVT, Op, FPZero, ISD::SETEQ);
-}
-
+SDValue TargetLowering::getSqrtInputTest(SDValue Op, SelectionDAG &DAG,
+ const DenormalMode &Mode) const {
+ SDLoc DL(Op);
+ EVT VT = Op.getValueType();
+ EVT CCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
+ SDValue FPZero = DAG.getConstantFP(0.0, DL, VT);
+ // Testing it with denormal inputs to avoid wrong estimate.
+ if (Mode.Input == DenormalMode::IEEE) {
+ // This is specifically a check for the handling of denormal inputs,
+ // not the result.
+
+ // Test = fabs(X) < SmallestNormal
+ const fltSemantics &FltSem = DAG.EVTToAPFloatSemantics(VT);
+ APFloat SmallestNorm = APFloat::getSmallestNormalized(FltSem);
+ SDValue NormC = DAG.getConstantFP(SmallestNorm, DL, VT);
+ SDValue Fabs = DAG.getNode(ISD::FABS, DL, VT, Op);
+ return DAG.getSetCC(DL, CCVT, Fabs, NormC, ISD::SETLT);
+ }
+ // Test = X == 0.0
+ return DAG.getSetCC(DL, CCVT, Op, FPZero, ISD::SETEQ);
+}
+
SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
bool LegalOps, bool OptForSize,
NegatibleCost &Cost,
@@ -5935,11 +5935,11 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
SDLoc DL(Op);
- // Because getNegatedExpression can delete nodes we need a handle to keep
- // temporary nodes alive in case the recursion manages to create an identical
- // node.
- std::list<HandleSDNode> Handles;
-
+ // Because getNegatedExpression can delete nodes we need a handle to keep
+ // temporary nodes alive in case the recursion manages to create an identical
+ // node.
+ std::list<HandleSDNode> Handles;
+
switch (Opcode) {
case ISD::ConstantFP: {
// Don't invert constant FP values after legalization unless the target says
@@ -6008,18 +6008,18 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
NegatibleCost CostX = NegatibleCost::Expensive;
SDValue NegX =
getNegatedExpression(X, DAG, LegalOps, OptForSize, CostX, Depth);
- // Prevent this node from being deleted by the next call.
- if (NegX)
- Handles.emplace_back(NegX);
-
+ // Prevent this node from being deleted by the next call.
+ if (NegX)
+ Handles.emplace_back(NegX);
+
// fold (fneg (fadd X, Y)) -> (fsub (fneg Y), X)
NegatibleCost CostY = NegatibleCost::Expensive;
SDValue NegY =
getNegatedExpression(Y, DAG, LegalOps, OptForSize, CostY, Depth);
- // We're done with the handles.
- Handles.clear();
-
+ // We're done with the handles.
+ Handles.clear();
+
// Negate the X if its cost is less or equal than Y.
if (NegX && (CostX <= CostY)) {
Cost = CostX;
@@ -6064,18 +6064,18 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
NegatibleCost CostX = NegatibleCost::Expensive;
SDValue NegX =
getNegatedExpression(X, DAG, LegalOps, OptForSize, CostX, Depth);
- // Prevent this node from being deleted by the next call.
- if (NegX)
- Handles.emplace_back(NegX);
-
+ // Prevent this node from being deleted by the next call.
+ if (NegX)
+ Handles.emplace_back(NegX);
+
// fold (fneg (fmul X, Y)) -> (fmul X, (fneg Y))
NegatibleCost CostY = NegatibleCost::Expensive;
SDValue NegY =
getNegatedExpression(Y, DAG, LegalOps, OptForSize, CostY, Depth);
- // We're done with the handles.
- Handles.clear();
-
+ // We're done with the handles.
+ Handles.clear();
+
// Negate the X if its cost is less or equal than Y.
if (NegX && (CostX <= CostY)) {
Cost = CostX;
@@ -6113,25 +6113,25 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
if (!NegZ)
break;
- // Prevent this node from being deleted by the next two calls.
- Handles.emplace_back(NegZ);
-
+ // Prevent this node from being deleted by the next two calls.
+ Handles.emplace_back(NegZ);
+
// fold (fneg (fma X, Y, Z)) -> (fma (fneg X), Y, (fneg Z))
NegatibleCost CostX = NegatibleCost::Expensive;
SDValue NegX =
getNegatedExpression(X, DAG, LegalOps, OptForSize, CostX, Depth);
- // Prevent this node from being deleted by the next call.
- if (NegX)
- Handles.emplace_back(NegX);
-
+ // Prevent this node from being deleted by the next call.
+ if (NegX)
+ Handles.emplace_back(NegX);
+
// fold (fneg (fma X, Y, Z)) -> (fma X, (fneg Y), (fneg Z))
NegatibleCost CostY = NegatibleCost::Expensive;
SDValue NegY =
getNegatedExpression(Y, DAG, LegalOps, OptForSize, CostY, Depth);
- // We're done with the handles.
- Handles.clear();
-
+ // We're done with the handles.
+ Handles.clear();
+
// Negate the X if its cost is less or equal than Y.
if (NegX && (CostX <= CostY)) {
Cost = std::min(CostX, CostZ);
@@ -6172,7 +6172,7 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
// Legalization Utilities
//===----------------------------------------------------------------------===//
-bool TargetLowering::expandMUL_LOHI(unsigned Opcode, EVT VT, const SDLoc &dl,
+bool TargetLowering::expandMUL_LOHI(unsigned Opcode, EVT VT, const SDLoc &dl,
SDValue LHS, SDValue RHS,
SmallVectorImpl<SDValue> &Result,
EVT HiLoVT, SelectionDAG &DAG,
@@ -6243,9 +6243,9 @@ bool TargetLowering::expandMUL_LOHI(unsigned Opcode, EVT VT, const SDLoc &dl,
}
}
- if (!VT.isVector() && Opcode == ISD::MUL &&
- DAG.ComputeNumSignBits(LHS) > InnerBitSize &&
- DAG.ComputeNumSignBits(RHS) > InnerBitSize) {
+ if (!VT.isVector() && Opcode == ISD::MUL &&
+ DAG.ComputeNumSignBits(LHS) > InnerBitSize &&
+ DAG.ComputeNumSignBits(RHS) > InnerBitSize) {
// The input values are both sign-extended.
// TODO non-MUL case?
if (MakeMUL_LOHI(LL, RL, Lo, Hi, true)) {
@@ -6359,7 +6359,7 @@ bool TargetLowering::expandMUL(SDNode *N, SDValue &Lo, SDValue &Hi, EVT HiLoVT,
SDValue LL, SDValue LH, SDValue RL,
SDValue RH) const {
SmallVector<SDValue, 2> Result;
- bool Ok = expandMUL_LOHI(N->getOpcode(), N->getValueType(0), SDLoc(N),
+ bool Ok = expandMUL_LOHI(N->getOpcode(), N->getValueType(0), SDLoc(N),
N->getOperand(0), N->getOperand(1), Result, HiLoVT,
DAG, Kind, LL, LH, RL, RH);
if (Ok) {
@@ -6371,7 +6371,7 @@ bool TargetLowering::expandMUL(SDNode *N, SDValue &Lo, SDValue &Hi, EVT HiLoVT,
}
// Check that (every element of) Z is undef or not an exact multiple of BW.
-static bool isNonZeroModBitWidthOrUndef(SDValue Z, unsigned BW) {
+static bool isNonZeroModBitWidthOrUndef(SDValue Z, unsigned BW) {
return ISD::matchUnaryPredicate(
Z,
[=](ConstantSDNode *C) { return !C || C->getAPIntValue().urem(BW) != 0; },
@@ -6398,35 +6398,35 @@ bool TargetLowering::expandFunnelShift(SDNode *Node, SDValue &Result,
EVT ShVT = Z.getValueType();
- // If a funnel shift in the other direction is more supported, use it.
- unsigned RevOpcode = IsFSHL ? ISD::FSHR : ISD::FSHL;
- if (!isOperationLegalOrCustom(Node->getOpcode(), VT) &&
- isOperationLegalOrCustom(RevOpcode, VT) && isPowerOf2_32(BW)) {
- if (isNonZeroModBitWidthOrUndef(Z, BW)) {
- // fshl X, Y, Z -> fshr X, Y, -Z
- // fshr X, Y, Z -> fshl X, Y, -Z
- SDValue Zero = DAG.getConstant(0, DL, ShVT);
- Z = DAG.getNode(ISD::SUB, DL, VT, Zero, Z);
- } else {
- // fshl X, Y, Z -> fshr (srl X, 1), (fshr X, Y, 1), ~Z
- // fshr X, Y, Z -> fshl (fshl X, Y, 1), (shl Y, 1), ~Z
- SDValue One = DAG.getConstant(1, DL, ShVT);
- if (IsFSHL) {
- Y = DAG.getNode(RevOpcode, DL, VT, X, Y, One);
- X = DAG.getNode(ISD::SRL, DL, VT, X, One);
- } else {
- X = DAG.getNode(RevOpcode, DL, VT, X, Y, One);
- Y = DAG.getNode(ISD::SHL, DL, VT, Y, One);
- }
- Z = DAG.getNOT(DL, Z, ShVT);
- }
- Result = DAG.getNode(RevOpcode, DL, VT, X, Y, Z);
- return true;
- }
-
+ // If a funnel shift in the other direction is more supported, use it.
+ unsigned RevOpcode = IsFSHL ? ISD::FSHR : ISD::FSHL;
+ if (!isOperationLegalOrCustom(Node->getOpcode(), VT) &&
+ isOperationLegalOrCustom(RevOpcode, VT) && isPowerOf2_32(BW)) {
+ if (isNonZeroModBitWidthOrUndef(Z, BW)) {
+ // fshl X, Y, Z -> fshr X, Y, -Z
+ // fshr X, Y, Z -> fshl X, Y, -Z
+ SDValue Zero = DAG.getConstant(0, DL, ShVT);
+ Z = DAG.getNode(ISD::SUB, DL, VT, Zero, Z);
+ } else {
+ // fshl X, Y, Z -> fshr (srl X, 1), (fshr X, Y, 1), ~Z
+ // fshr X, Y, Z -> fshl (fshl X, Y, 1), (shl Y, 1), ~Z
+ SDValue One = DAG.getConstant(1, DL, ShVT);
+ if (IsFSHL) {
+ Y = DAG.getNode(RevOpcode, DL, VT, X, Y, One);
+ X = DAG.getNode(ISD::SRL, DL, VT, X, One);
+ } else {
+ X = DAG.getNode(RevOpcode, DL, VT, X, Y, One);
+ Y = DAG.getNode(ISD::SHL, DL, VT, Y, One);
+ }
+ Z = DAG.getNOT(DL, Z, ShVT);
+ }
+ Result = DAG.getNode(RevOpcode, DL, VT, X, Y, Z);
+ return true;
+ }
+
SDValue ShX, ShY;
SDValue ShAmt, InvShAmt;
- if (isNonZeroModBitWidthOrUndef(Z, BW)) {
+ if (isNonZeroModBitWidthOrUndef(Z, BW)) {
// fshl: X << C | Y >> (BW - C)
// fshr: X << (BW - C) | Y >> C
// where C = Z % BW is not zero
@@ -6466,8 +6466,8 @@ bool TargetLowering::expandFunnelShift(SDNode *Node, SDValue &Result,
}
// TODO: Merge with expandFunnelShift.
-bool TargetLowering::expandROT(SDNode *Node, bool AllowVectorOps,
- SDValue &Result, SelectionDAG &DAG) const {
+bool TargetLowering::expandROT(SDNode *Node, bool AllowVectorOps,
+ SDValue &Result, SelectionDAG &DAG) const {
EVT VT = Node->getValueType(0);
unsigned EltSizeInBits = VT.getScalarSizeInBits();
bool IsLeft = Node->getOpcode() == ISD::ROTL;
@@ -6480,45 +6480,45 @@ bool TargetLowering::expandROT(SDNode *Node, bool AllowVectorOps,
// If a rotate in the other direction is supported, use it.
unsigned RevRot = IsLeft ? ISD::ROTR : ISD::ROTL;
- if (isOperationLegalOrCustom(RevRot, VT) && isPowerOf2_32(EltSizeInBits)) {
+ if (isOperationLegalOrCustom(RevRot, VT) && isPowerOf2_32(EltSizeInBits)) {
SDValue Sub = DAG.getNode(ISD::SUB, DL, ShVT, Zero, Op1);
Result = DAG.getNode(RevRot, DL, VT, Op0, Sub);
return true;
}
- if (!AllowVectorOps && VT.isVector() &&
- (!isOperationLegalOrCustom(ISD::SHL, VT) ||
- !isOperationLegalOrCustom(ISD::SRL, VT) ||
- !isOperationLegalOrCustom(ISD::SUB, VT) ||
- !isOperationLegalOrCustomOrPromote(ISD::OR, VT) ||
- !isOperationLegalOrCustomOrPromote(ISD::AND, VT)))
+ if (!AllowVectorOps && VT.isVector() &&
+ (!isOperationLegalOrCustom(ISD::SHL, VT) ||
+ !isOperationLegalOrCustom(ISD::SRL, VT) ||
+ !isOperationLegalOrCustom(ISD::SUB, VT) ||
+ !isOperationLegalOrCustomOrPromote(ISD::OR, VT) ||
+ !isOperationLegalOrCustomOrPromote(ISD::AND, VT)))
return false;
unsigned ShOpc = IsLeft ? ISD::SHL : ISD::SRL;
unsigned HsOpc = IsLeft ? ISD::SRL : ISD::SHL;
SDValue BitWidthMinusOneC = DAG.getConstant(EltSizeInBits - 1, DL, ShVT);
- SDValue ShVal;
- SDValue HsVal;
- if (isPowerOf2_32(EltSizeInBits)) {
- // (rotl x, c) -> x << (c & (w - 1)) | x >> (-c & (w - 1))
- // (rotr x, c) -> x >> (c & (w - 1)) | x << (-c & (w - 1))
- SDValue NegOp1 = DAG.getNode(ISD::SUB, DL, ShVT, Zero, Op1);
- SDValue ShAmt = DAG.getNode(ISD::AND, DL, ShVT, Op1, BitWidthMinusOneC);
- ShVal = DAG.getNode(ShOpc, DL, VT, Op0, ShAmt);
- SDValue HsAmt = DAG.getNode(ISD::AND, DL, ShVT, NegOp1, BitWidthMinusOneC);
- HsVal = DAG.getNode(HsOpc, DL, VT, Op0, HsAmt);
- } else {
- // (rotl x, c) -> x << (c % w) | x >> 1 >> (w - 1 - (c % w))
- // (rotr x, c) -> x >> (c % w) | x << 1 << (w - 1 - (c % w))
- SDValue BitWidthC = DAG.getConstant(EltSizeInBits, DL, ShVT);
- SDValue ShAmt = DAG.getNode(ISD::UREM, DL, ShVT, Op1, BitWidthC);
- ShVal = DAG.getNode(ShOpc, DL, VT, Op0, ShAmt);
- SDValue HsAmt = DAG.getNode(ISD::SUB, DL, ShVT, BitWidthMinusOneC, ShAmt);
- SDValue One = DAG.getConstant(1, DL, ShVT);
- HsVal =
- DAG.getNode(HsOpc, DL, VT, DAG.getNode(HsOpc, DL, VT, Op0, One), HsAmt);
- }
- Result = DAG.getNode(ISD::OR, DL, VT, ShVal, HsVal);
+ SDValue ShVal;
+ SDValue HsVal;
+ if (isPowerOf2_32(EltSizeInBits)) {
+ // (rotl x, c) -> x << (c & (w - 1)) | x >> (-c & (w - 1))
+ // (rotr x, c) -> x >> (c & (w - 1)) | x << (-c & (w - 1))
+ SDValue NegOp1 = DAG.getNode(ISD::SUB, DL, ShVT, Zero, Op1);
+ SDValue ShAmt = DAG.getNode(ISD::AND, DL, ShVT, Op1, BitWidthMinusOneC);
+ ShVal = DAG.getNode(ShOpc, DL, VT, Op0, ShAmt);
+ SDValue HsAmt = DAG.getNode(ISD::AND, DL, ShVT, NegOp1, BitWidthMinusOneC);
+ HsVal = DAG.getNode(HsOpc, DL, VT, Op0, HsAmt);
+ } else {
+ // (rotl x, c) -> x << (c % w) | x >> 1 >> (w - 1 - (c % w))
+ // (rotr x, c) -> x >> (c % w) | x << 1 << (w - 1 - (c % w))
+ SDValue BitWidthC = DAG.getConstant(EltSizeInBits, DL, ShVT);
+ SDValue ShAmt = DAG.getNode(ISD::UREM, DL, ShVT, Op1, BitWidthC);
+ ShVal = DAG.getNode(ShOpc, DL, VT, Op0, ShAmt);
+ SDValue HsAmt = DAG.getNode(ISD::SUB, DL, ShVT, BitWidthMinusOneC, ShAmt);
+ SDValue One = DAG.getConstant(1, DL, ShVT);
+ HsVal =
+ DAG.getNode(HsOpc, DL, VT, DAG.getNode(HsOpc, DL, VT, Op0, One), HsAmt);
+ }
+ Result = DAG.getNode(ISD::OR, DL, VT, ShVal, HsVal);
return true;
}
@@ -6537,7 +6537,7 @@ bool TargetLowering::expandFP_TO_SINT(SDNode *Node, SDValue &Result,
if (Node->isStrictFPOpcode())
// When a NaN is converted to an integer a trap is allowed. We can't
// use this expansion here because it would eliminate that trap. Other
- // traps are also allowed and cannot be eliminated. See
+ // traps are also allowed and cannot be eliminated. See
// IEEE 754-2008 sec 5.8.
return false;
@@ -6608,7 +6608,7 @@ bool TargetLowering::expandFP_TO_UINT(SDNode *Node, SDValue &Result,
getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), DstVT);
// Only expand vector types if we have the appropriate vector bit operations.
- unsigned SIntOpcode = Node->isStrictFPOpcode() ? ISD::STRICT_FP_TO_SINT :
+ unsigned SIntOpcode = Node->isStrictFPOpcode() ? ISD::STRICT_FP_TO_SINT :
ISD::FP_TO_SINT;
if (DstVT.isVector() && (!isOperationLegalOrCustom(SIntOpcode, DstVT) ||
!isOperationLegalOrCustomOrPromote(ISD::XOR, SrcVT)))
@@ -6623,19 +6623,19 @@ bool TargetLowering::expandFP_TO_UINT(SDNode *Node, SDValue &Result,
if (APFloat::opOverflow &
APF.convertFromAPInt(SignMask, false, APFloat::rmNearestTiesToEven)) {
if (Node->isStrictFPOpcode()) {
- Result = DAG.getNode(ISD::STRICT_FP_TO_SINT, dl, { DstVT, MVT::Other },
- { Node->getOperand(0), Src });
+ Result = DAG.getNode(ISD::STRICT_FP_TO_SINT, dl, { DstVT, MVT::Other },
+ { Node->getOperand(0), Src });
Chain = Result.getValue(1);
} else
Result = DAG.getNode(ISD::FP_TO_SINT, dl, DstVT, Src);
return true;
}
- // Don't expand it if there isn't cheap fsub instruction.
- if (!isOperationLegalOrCustom(
- Node->isStrictFPOpcode() ? ISD::STRICT_FSUB : ISD::FSUB, SrcVT))
- return false;
-
+ // Don't expand it if there isn't cheap fsub instruction.
+ if (!isOperationLegalOrCustom(
+ Node->isStrictFPOpcode() ? ISD::STRICT_FSUB : ISD::FSUB, SrcVT))
+ return false;
+
SDValue Cst = DAG.getConstantFP(APF, dl, SrcVT);
SDValue Sel;
@@ -6667,9 +6667,9 @@ bool TargetLowering::expandFP_TO_UINT(SDNode *Node, SDValue &Result,
DAG.getConstant(SignMask, dl, DstVT));
SDValue SInt;
if (Node->isStrictFPOpcode()) {
- SDValue Val = DAG.getNode(ISD::STRICT_FSUB, dl, { SrcVT, MVT::Other },
+ SDValue Val = DAG.getNode(ISD::STRICT_FSUB, dl, { SrcVT, MVT::Other },
{ Chain, Src, FltOfs });
- SInt = DAG.getNode(ISD::STRICT_FP_TO_SINT, dl, { DstVT, MVT::Other },
+ SInt = DAG.getNode(ISD::STRICT_FP_TO_SINT, dl, { DstVT, MVT::Other },
{ Val.getValue(1), Val });
Chain = SInt.getValue(1);
} else {
@@ -6698,13 +6698,13 @@ bool TargetLowering::expandFP_TO_UINT(SDNode *Node, SDValue &Result,
bool TargetLowering::expandUINT_TO_FP(SDNode *Node, SDValue &Result,
SDValue &Chain,
SelectionDAG &DAG) const {
- // This transform is not correct for converting 0 when rounding mode is set
- // to round toward negative infinity which will produce -0.0. So disable under
- // strictfp.
- if (Node->isStrictFPOpcode())
- return false;
-
- SDValue Src = Node->getOperand(0);
+ // This transform is not correct for converting 0 when rounding mode is set
+ // to round toward negative infinity which will produce -0.0. So disable under
+ // strictfp.
+ if (Node->isStrictFPOpcode())
+ return false;
+
+ SDValue Src = Node->getOperand(0);
EVT SrcVT = Src.getValueType();
EVT DstVT = Node->getValueType(0);
@@ -6723,10 +6723,10 @@ bool TargetLowering::expandUINT_TO_FP(SDNode *Node, SDValue &Result,
EVT ShiftVT = getShiftAmountTy(SrcVT, DAG.getDataLayout());
// Implementation of unsigned i64 to f64 following the algorithm in
- // __floatundidf in compiler_rt. This implementation performs rounding
- // correctly in all rounding modes with the exception of converting 0
- // when rounding toward negative infinity. In that case the fsub will produce
- // -0.0. This will be added to +0.0 and produce -0.0 which is incorrect.
+ // __floatundidf in compiler_rt. This implementation performs rounding
+ // correctly in all rounding modes with the exception of converting 0
+ // when rounding toward negative infinity. In that case the fsub will produce
+ // -0.0. This will be added to +0.0 and produce -0.0 which is incorrect.
SDValue TwoP52 = DAG.getConstant(UINT64_C(0x4330000000000000), dl, SrcVT);
SDValue TwoP84PlusTwoP52 = DAG.getConstantFP(
BitsToDouble(UINT64_C(0x4530000000100000)), dl, DstVT);
@@ -6740,9 +6740,9 @@ bool TargetLowering::expandUINT_TO_FP(SDNode *Node, SDValue &Result,
SDValue HiOr = DAG.getNode(ISD::OR, dl, SrcVT, Hi, TwoP84);
SDValue LoFlt = DAG.getBitcast(DstVT, LoOr);
SDValue HiFlt = DAG.getBitcast(DstVT, HiOr);
- SDValue HiSub =
- DAG.getNode(ISD::FSUB, dl, DstVT, HiFlt, TwoP84PlusTwoP52);
- Result = DAG.getNode(ISD::FADD, dl, DstVT, LoFlt, HiSub);
+ SDValue HiSub =
+ DAG.getNode(ISD::FSUB, dl, DstVT, HiFlt, TwoP84PlusTwoP52);
+ Result = DAG.getNode(ISD::FADD, dl, DstVT, LoFlt, HiSub);
return true;
}
@@ -6752,11 +6752,11 @@ SDValue TargetLowering::expandFMINNUM_FMAXNUM(SDNode *Node,
unsigned NewOp = Node->getOpcode() == ISD::FMINNUM ?
ISD::FMINNUM_IEEE : ISD::FMAXNUM_IEEE;
EVT VT = Node->getValueType(0);
-
- if (VT.isScalableVector())
- report_fatal_error(
- "Expanding fminnum/fmaxnum for scalable vectors is undefined.");
-
+
+ if (VT.isScalableVector())
+ report_fatal_error(
+ "Expanding fminnum/fmaxnum for scalable vectors is undefined.");
+
if (isOperationLegalOrCustom(NewOp, VT)) {
SDValue Quiet0 = Node->getOperand(0);
SDValue Quiet1 = Node->getOperand(1);
@@ -6980,58 +6980,58 @@ bool TargetLowering::expandCTTZ(SDNode *Node, SDValue &Result,
}
bool TargetLowering::expandABS(SDNode *N, SDValue &Result,
- SelectionDAG &DAG, bool IsNegative) const {
+ SelectionDAG &DAG, bool IsNegative) const {
SDLoc dl(N);
EVT VT = N->getValueType(0);
EVT ShVT = getShiftAmountTy(VT, DAG.getDataLayout());
SDValue Op = N->getOperand(0);
- // abs(x) -> smax(x,sub(0,x))
- if (!IsNegative && isOperationLegal(ISD::SUB, VT) &&
- isOperationLegal(ISD::SMAX, VT)) {
- SDValue Zero = DAG.getConstant(0, dl, VT);
- Result = DAG.getNode(ISD::SMAX, dl, VT, Op,
- DAG.getNode(ISD::SUB, dl, VT, Zero, Op));
- return true;
- }
-
- // abs(x) -> umin(x,sub(0,x))
- if (!IsNegative && isOperationLegal(ISD::SUB, VT) &&
- isOperationLegal(ISD::UMIN, VT)) {
- SDValue Zero = DAG.getConstant(0, dl, VT);
- Result = DAG.getNode(ISD::UMIN, dl, VT, Op,
- DAG.getNode(ISD::SUB, dl, VT, Zero, Op));
- return true;
- }
-
- // 0 - abs(x) -> smin(x, sub(0,x))
- if (IsNegative && isOperationLegal(ISD::SUB, VT) &&
- isOperationLegal(ISD::SMIN, VT)) {
- SDValue Zero = DAG.getConstant(0, dl, VT);
- Result = DAG.getNode(ISD::SMIN, dl, VT, Op,
- DAG.getNode(ISD::SUB, dl, VT, Zero, Op));
- return true;
- }
-
+ // abs(x) -> smax(x,sub(0,x))
+ if (!IsNegative && isOperationLegal(ISD::SUB, VT) &&
+ isOperationLegal(ISD::SMAX, VT)) {
+ SDValue Zero = DAG.getConstant(0, dl, VT);
+ Result = DAG.getNode(ISD::SMAX, dl, VT, Op,
+ DAG.getNode(ISD::SUB, dl, VT, Zero, Op));
+ return true;
+ }
+
+ // abs(x) -> umin(x,sub(0,x))
+ if (!IsNegative && isOperationLegal(ISD::SUB, VT) &&
+ isOperationLegal(ISD::UMIN, VT)) {
+ SDValue Zero = DAG.getConstant(0, dl, VT);
+ Result = DAG.getNode(ISD::UMIN, dl, VT, Op,
+ DAG.getNode(ISD::SUB, dl, VT, Zero, Op));
+ return true;
+ }
+
+ // 0 - abs(x) -> smin(x, sub(0,x))
+ if (IsNegative && isOperationLegal(ISD::SUB, VT) &&
+ isOperationLegal(ISD::SMIN, VT)) {
+ SDValue Zero = DAG.getConstant(0, dl, VT);
+ Result = DAG.getNode(ISD::SMIN, dl, VT, Op,
+ DAG.getNode(ISD::SUB, dl, VT, Zero, Op));
+ return true;
+ }
+
// Only expand vector types if we have the appropriate vector operations.
- if (VT.isVector() &&
- (!isOperationLegalOrCustom(ISD::SRA, VT) ||
- (!IsNegative && !isOperationLegalOrCustom(ISD::ADD, VT)) ||
- (IsNegative && !isOperationLegalOrCustom(ISD::SUB, VT)) ||
- !isOperationLegalOrCustomOrPromote(ISD::XOR, VT)))
+ if (VT.isVector() &&
+ (!isOperationLegalOrCustom(ISD::SRA, VT) ||
+ (!IsNegative && !isOperationLegalOrCustom(ISD::ADD, VT)) ||
+ (IsNegative && !isOperationLegalOrCustom(ISD::SUB, VT)) ||
+ !isOperationLegalOrCustomOrPromote(ISD::XOR, VT)))
return false;
SDValue Shift =
DAG.getNode(ISD::SRA, dl, VT, Op,
DAG.getConstant(VT.getScalarSizeInBits() - 1, dl, ShVT));
- if (!IsNegative) {
- SDValue Add = DAG.getNode(ISD::ADD, dl, VT, Op, Shift);
- Result = DAG.getNode(ISD::XOR, dl, VT, Add, Shift);
- } else {
- // 0 - abs(x) -> Y = sra (X, size(X)-1); sub (Y, xor (X, Y))
- SDValue Xor = DAG.getNode(ISD::XOR, dl, VT, Op, Shift);
- Result = DAG.getNode(ISD::SUB, dl, VT, Shift, Xor);
- }
+ if (!IsNegative) {
+ SDValue Add = DAG.getNode(ISD::ADD, dl, VT, Op, Shift);
+ Result = DAG.getNode(ISD::XOR, dl, VT, Add, Shift);
+ } else {
+ // 0 - abs(x) -> Y = sra (X, size(X)-1); sub (Y, xor (X, Y))
+ SDValue Xor = DAG.getNode(ISD::XOR, dl, VT, Op, Shift);
+ Result = DAG.getNode(ISD::SUB, dl, VT, Shift, Xor);
+ }
return true;
}
@@ -7045,9 +7045,9 @@ TargetLowering::scalarizeVectorLoad(LoadSDNode *LD,
EVT DstVT = LD->getValueType(0);
ISD::LoadExtType ExtType = LD->getExtensionType();
- if (SrcVT.isScalableVector())
- report_fatal_error("Cannot scalarize scalable vector loads");
-
+ if (SrcVT.isScalableVector())
+ report_fatal_error("Cannot scalarize scalable vector loads");
+
unsigned NumElem = SrcVT.getVectorNumElements();
EVT SrcEltVT = SrcVT.getScalarType();
@@ -7074,7 +7074,7 @@ TargetLowering::scalarizeVectorLoad(LoadSDNode *LD,
// the codegen worse.
SDValue Load =
DAG.getExtLoad(ISD::EXTLOAD, SL, LoadVT, Chain, BasePTR,
- LD->getPointerInfo(), SrcIntVT, LD->getOriginalAlign(),
+ LD->getPointerInfo(), SrcIntVT, LD->getOriginalAlign(),
LD->getMemOperand()->getFlags(), LD->getAAInfo());
SmallVector<SDValue, 8> Vals;
@@ -7111,10 +7111,10 @@ TargetLowering::scalarizeVectorLoad(LoadSDNode *LD,
SDValue ScalarLoad =
DAG.getExtLoad(ExtType, SL, DstEltVT, Chain, BasePTR,
LD->getPointerInfo().getWithOffset(Idx * Stride),
- SrcEltVT, LD->getOriginalAlign(),
+ SrcEltVT, LD->getOriginalAlign(),
LD->getMemOperand()->getFlags(), LD->getAAInfo());
- BasePTR = DAG.getObjectPtrOffset(SL, BasePTR, TypeSize::Fixed(Stride));
+ BasePTR = DAG.getObjectPtrOffset(SL, BasePTR, TypeSize::Fixed(Stride));
Vals.push_back(ScalarLoad.getValue(0));
LoadChains.push_back(ScalarLoad.getValue(1));
@@ -7135,9 +7135,9 @@ SDValue TargetLowering::scalarizeVectorStore(StoreSDNode *ST,
SDValue Value = ST->getValue();
EVT StVT = ST->getMemoryVT();
- if (StVT.isScalableVector())
- report_fatal_error("Cannot scalarize scalable vector stores");
-
+ if (StVT.isScalableVector())
+ report_fatal_error("Cannot scalarize scalable vector stores");
+
// The type of the data we want to save
EVT RegVT = Value.getValueType();
EVT RegSclVT = RegVT.getScalarType();
@@ -7174,7 +7174,7 @@ SDValue TargetLowering::scalarizeVectorStore(StoreSDNode *ST,
}
return DAG.getStore(Chain, SL, CurrVal, BasePtr, ST->getPointerInfo(),
- ST->getOriginalAlign(), ST->getMemOperand()->getFlags(),
+ ST->getOriginalAlign(), ST->getMemOperand()->getFlags(),
ST->getAAInfo());
}
@@ -7188,14 +7188,14 @@ SDValue TargetLowering::scalarizeVectorStore(StoreSDNode *ST,
SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, RegSclVT, Value,
DAG.getVectorIdxConstant(Idx, SL));
- SDValue Ptr =
- DAG.getObjectPtrOffset(SL, BasePtr, TypeSize::Fixed(Idx * Stride));
+ SDValue Ptr =
+ DAG.getObjectPtrOffset(SL, BasePtr, TypeSize::Fixed(Idx * Stride));
// This scalar TruncStore may be illegal, but we legalize it later.
SDValue Store = DAG.getTruncStore(
Chain, SL, Elt, Ptr, ST->getPointerInfo().getWithOffset(Idx * Stride),
- MemSclVT, ST->getOriginalAlign(), ST->getMemOperand()->getFlags(),
- ST->getAAInfo());
+ MemSclVT, ST->getOriginalAlign(), ST->getMemOperand()->getFlags(),
+ ST->getAAInfo());
Stores.push_back(Store);
}
@@ -7260,7 +7260,7 @@ TargetLowering::expandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG) const {
// Load one integer register's worth from the original location.
SDValue Load = DAG.getLoad(
RegVT, dl, Chain, Ptr, LD->getPointerInfo().getWithOffset(Offset),
- LD->getOriginalAlign(), LD->getMemOperand()->getFlags(),
+ LD->getOriginalAlign(), LD->getMemOperand()->getFlags(),
LD->getAAInfo());
// Follow the load with a store to the stack slot. Remember the store.
Stores.push_back(DAG.getStore(
@@ -7279,8 +7279,8 @@ TargetLowering::expandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG) const {
SDValue Load =
DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Chain, Ptr,
LD->getPointerInfo().getWithOffset(Offset), MemVT,
- LD->getOriginalAlign(), LD->getMemOperand()->getFlags(),
- LD->getAAInfo());
+ LD->getOriginalAlign(), LD->getMemOperand()->getFlags(),
+ LD->getAAInfo());
// Follow the load with a store to the stack slot. Remember the store.
// On big-endian machines this requires a truncating store to ensure
// that the bits end up in the right place.
@@ -7310,7 +7310,7 @@ TargetLowering::expandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG) const {
NewLoadedVT = EVT::getIntegerVT(*DAG.getContext(), NumBits/2);
NumBits >>= 1;
- Align Alignment = LD->getOriginalAlign();
+ Align Alignment = LD->getOriginalAlign();
unsigned IncrementSize = NumBits / 8;
ISD::LoadExtType HiExtType = LD->getExtensionType();
@@ -7325,21 +7325,21 @@ TargetLowering::expandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG) const {
NewLoadedVT, Alignment, LD->getMemOperand()->getFlags(),
LD->getAAInfo());
- Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::Fixed(IncrementSize));
+ Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::Fixed(IncrementSize));
Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr,
LD->getPointerInfo().getWithOffset(IncrementSize),
- NewLoadedVT, Alignment, LD->getMemOperand()->getFlags(),
- LD->getAAInfo());
+ NewLoadedVT, Alignment, LD->getMemOperand()->getFlags(),
+ LD->getAAInfo());
} else {
Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, LD->getPointerInfo(),
NewLoadedVT, Alignment, LD->getMemOperand()->getFlags(),
LD->getAAInfo());
- Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::Fixed(IncrementSize));
+ Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::Fixed(IncrementSize));
Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr,
LD->getPointerInfo().getWithOffset(IncrementSize),
- NewLoadedVT, Alignment, LD->getMemOperand()->getFlags(),
- LD->getAAInfo());
+ NewLoadedVT, Alignment, LD->getMemOperand()->getFlags(),
+ LD->getAAInfo());
}
// aggregate the two parts
@@ -7363,7 +7363,7 @@ SDValue TargetLowering::expandUnalignedStore(StoreSDNode *ST,
SDValue Ptr = ST->getBasePtr();
SDValue Val = ST->getValue();
EVT VT = Val.getValueType();
- Align Alignment = ST->getOriginalAlign();
+ Align Alignment = ST->getOriginalAlign();
auto &MF = DAG.getMachineFunction();
EVT StoreMemVT = ST->getMemoryVT();
@@ -7420,7 +7420,7 @@ SDValue TargetLowering::expandUnalignedStore(StoreSDNode *ST,
// Store it to the final location. Remember the store.
Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, Ptr,
ST->getPointerInfo().getWithOffset(Offset),
- ST->getOriginalAlign(),
+ ST->getOriginalAlign(),
ST->getMemOperand()->getFlags()));
// Increment the pointers.
Offset += RegBytes;
@@ -7442,7 +7442,7 @@ SDValue TargetLowering::expandUnalignedStore(StoreSDNode *ST,
Stores.push_back(
DAG.getTruncStore(Load.getValue(1), dl, Load, Ptr,
ST->getPointerInfo().getWithOffset(Offset), LoadMemVT,
- ST->getOriginalAlign(),
+ ST->getOriginalAlign(),
ST->getMemOperand()->getFlags(), ST->getAAInfo()));
// The order of the stores doesn't matter - say it with a TokenFactor.
SDValue Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Stores);
@@ -7453,8 +7453,8 @@ SDValue TargetLowering::expandUnalignedStore(StoreSDNode *ST,
"Unaligned store of unknown type.");
// Get the half-size VT
EVT NewStoredVT = StoreMemVT.getHalfSizedIntegerVT(*DAG.getContext());
- unsigned NumBits = NewStoredVT.getFixedSizeInBits();
- unsigned IncrementSize = NumBits / 8;
+ unsigned NumBits = NewStoredVT.getFixedSizeInBits();
+ unsigned IncrementSize = NumBits / 8;
// Divide the stored value in two parts.
SDValue ShiftAmount = DAG.getConstant(
@@ -7469,7 +7469,7 @@ SDValue TargetLowering::expandUnalignedStore(StoreSDNode *ST,
Ptr, ST->getPointerInfo(), NewStoredVT, Alignment,
ST->getMemOperand()->getFlags());
- Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::Fixed(IncrementSize));
+ Ptr = DAG.getObjectPtrOffset(dl, Ptr, TypeSize::Fixed(IncrementSize));
Store2 = DAG.getTruncStore(
Chain, dl, DAG.getDataLayout().isLittleEndian() ? Hi : Lo, Ptr,
ST->getPointerInfo().getWithOffset(IncrementSize), NewStoredVT, Alignment,
@@ -7488,12 +7488,12 @@ TargetLowering::IncrementMemoryAddress(SDValue Addr, SDValue Mask,
SDValue Increment;
EVT AddrVT = Addr.getValueType();
EVT MaskVT = Mask.getValueType();
- assert(DataVT.getVectorElementCount() == MaskVT.getVectorElementCount() &&
+ assert(DataVT.getVectorElementCount() == MaskVT.getVectorElementCount() &&
"Incompatible types of Data and Mask");
if (IsCompressedMemory) {
- if (DataVT.isScalableVector())
- report_fatal_error(
- "Cannot currently handle compressed memory with scalable vectors");
+ if (DataVT.isScalableVector())
+ report_fatal_error(
+ "Cannot currently handle compressed memory with scalable vectors");
// Incrementing the pointer according to number of '1's in the mask.
EVT MaskIntVT = EVT::getIntegerVT(*DAG.getContext(), MaskVT.getSizeInBits());
SDValue MaskInIntReg = DAG.getBitcast(MaskIntVT, Mask);
@@ -7509,10 +7509,10 @@ TargetLowering::IncrementMemoryAddress(SDValue Addr, SDValue Mask,
SDValue Scale = DAG.getConstant(DataVT.getScalarSizeInBits() / 8, DL,
AddrVT);
Increment = DAG.getNode(ISD::MUL, DL, AddrVT, Increment, Scale);
- } else if (DataVT.isScalableVector()) {
- Increment = DAG.getVScale(DL, AddrVT,
- APInt(AddrVT.getFixedSizeInBits(),
- DataVT.getStoreSize().getKnownMinSize()));
+ } else if (DataVT.isScalableVector()) {
+ Increment = DAG.getVScale(DL, AddrVT,
+ APInt(AddrVT.getFixedSizeInBits(),
+ DataVT.getStoreSize().getKnownMinSize()));
} else
Increment = DAG.getConstant(DataVT.getStoreSize(), DL, AddrVT);
@@ -7523,26 +7523,26 @@ static SDValue clampDynamicVectorIndex(SelectionDAG &DAG,
SDValue Idx,
EVT VecVT,
const SDLoc &dl) {
- if (!VecVT.isScalableVector() && isa<ConstantSDNode>(Idx))
+ if (!VecVT.isScalableVector() && isa<ConstantSDNode>(Idx))
return Idx;
EVT IdxVT = Idx.getValueType();
- unsigned NElts = VecVT.getVectorMinNumElements();
- if (VecVT.isScalableVector()) {
- SDValue VS = DAG.getVScale(dl, IdxVT,
- APInt(IdxVT.getFixedSizeInBits(),
- NElts));
- SDValue Sub = DAG.getNode(ISD::SUB, dl, IdxVT, VS,
- DAG.getConstant(1, dl, IdxVT));
-
- return DAG.getNode(ISD::UMIN, dl, IdxVT, Idx, Sub);
- } else {
- if (isPowerOf2_32(NElts)) {
- APInt Imm = APInt::getLowBitsSet(IdxVT.getSizeInBits(),
- Log2_32(NElts));
- return DAG.getNode(ISD::AND, dl, IdxVT, Idx,
- DAG.getConstant(Imm, dl, IdxVT));
- }
+ unsigned NElts = VecVT.getVectorMinNumElements();
+ if (VecVT.isScalableVector()) {
+ SDValue VS = DAG.getVScale(dl, IdxVT,
+ APInt(IdxVT.getFixedSizeInBits(),
+ NElts));
+ SDValue Sub = DAG.getNode(ISD::SUB, dl, IdxVT, VS,
+ DAG.getConstant(1, dl, IdxVT));
+
+ return DAG.getNode(ISD::UMIN, dl, IdxVT, Idx, Sub);
+ } else {
+ if (isPowerOf2_32(NElts)) {
+ APInt Imm = APInt::getLowBitsSet(IdxVT.getSizeInBits(),
+ Log2_32(NElts));
+ return DAG.getNode(ISD::AND, dl, IdxVT, Idx,
+ DAG.getConstant(Imm, dl, IdxVT));
+ }
}
return DAG.getNode(ISD::UMIN, dl, IdxVT, Idx,
@@ -7559,8 +7559,8 @@ SDValue TargetLowering::getVectorElementPointer(SelectionDAG &DAG,
EVT EltVT = VecVT.getVectorElementType();
// Calculate the element offset and add it to the pointer.
- unsigned EltSize = EltVT.getFixedSizeInBits() / 8; // FIXME: should be ABI size.
- assert(EltSize * 8 == EltVT.getFixedSizeInBits() &&
+ unsigned EltSize = EltVT.getFixedSizeInBits() / 8; // FIXME: should be ABI size.
+ assert(EltSize * 8 == EltVT.getFixedSizeInBits() &&
"Converting bits to bytes lost precision");
Index = clampDynamicVectorIndex(DAG, Index, VecVT, dl);
@@ -7638,65 +7638,65 @@ SDValue TargetLowering::lowerCmpEqZeroToCtlzSrl(SDValue Op,
return SDValue();
}
-// Convert redundant addressing modes (e.g. scaling is redundant
-// when accessing bytes).
-ISD::MemIndexType
-TargetLowering::getCanonicalIndexType(ISD::MemIndexType IndexType, EVT MemVT,
- SDValue Offsets) const {
- bool IsScaledIndex =
- (IndexType == ISD::SIGNED_SCALED) || (IndexType == ISD::UNSIGNED_SCALED);
- bool IsSignedIndex =
- (IndexType == ISD::SIGNED_SCALED) || (IndexType == ISD::SIGNED_UNSCALED);
-
- // Scaling is unimportant for bytes, canonicalize to unscaled.
- if (IsScaledIndex && MemVT.getScalarType() == MVT::i8) {
- IsScaledIndex = false;
- IndexType = IsSignedIndex ? ISD::SIGNED_UNSCALED : ISD::UNSIGNED_UNSCALED;
- }
-
- return IndexType;
-}
-
-SDValue TargetLowering::expandIntMINMAX(SDNode *Node, SelectionDAG &DAG) const {
- SDValue Op0 = Node->getOperand(0);
- SDValue Op1 = Node->getOperand(1);
- EVT VT = Op0.getValueType();
- unsigned Opcode = Node->getOpcode();
- SDLoc DL(Node);
-
- // umin(x,y) -> sub(x,usubsat(x,y))
- if (Opcode == ISD::UMIN && isOperationLegal(ISD::SUB, VT) &&
- isOperationLegal(ISD::USUBSAT, VT)) {
- return DAG.getNode(ISD::SUB, DL, VT, Op0,
- DAG.getNode(ISD::USUBSAT, DL, VT, Op0, Op1));
- }
-
- // umax(x,y) -> add(x,usubsat(y,x))
- if (Opcode == ISD::UMAX && isOperationLegal(ISD::ADD, VT) &&
- isOperationLegal(ISD::USUBSAT, VT)) {
- return DAG.getNode(ISD::ADD, DL, VT, Op0,
- DAG.getNode(ISD::USUBSAT, DL, VT, Op1, Op0));
- }
-
- // Expand Y = MAX(A, B) -> Y = (A > B) ? A : B
- ISD::CondCode CC;
- switch (Opcode) {
- default: llvm_unreachable("How did we get here?");
- case ISD::SMAX: CC = ISD::SETGT; break;
- case ISD::SMIN: CC = ISD::SETLT; break;
- case ISD::UMAX: CC = ISD::SETUGT; break;
- case ISD::UMIN: CC = ISD::SETULT; break;
- }
-
- // FIXME: Should really try to split the vector in case it's legal on a
- // subvector.
- if (VT.isVector() && !isOperationLegalOrCustom(ISD::VSELECT, VT))
- return DAG.UnrollVectorOp(Node);
-
- SDValue Cond = DAG.getSetCC(DL, VT, Op0, Op1, CC);
- return DAG.getSelect(DL, VT, Cond, Op0, Op1);
-}
-
+// Convert redundant addressing modes (e.g. scaling is redundant
+// when accessing bytes).
+ISD::MemIndexType
+TargetLowering::getCanonicalIndexType(ISD::MemIndexType IndexType, EVT MemVT,
+ SDValue Offsets) const {
+ bool IsScaledIndex =
+ (IndexType == ISD::SIGNED_SCALED) || (IndexType == ISD::UNSIGNED_SCALED);
+ bool IsSignedIndex =
+ (IndexType == ISD::SIGNED_SCALED) || (IndexType == ISD::SIGNED_UNSCALED);
+
+ // Scaling is unimportant for bytes, canonicalize to unscaled.
+ if (IsScaledIndex && MemVT.getScalarType() == MVT::i8) {
+ IsScaledIndex = false;
+ IndexType = IsSignedIndex ? ISD::SIGNED_UNSCALED : ISD::UNSIGNED_UNSCALED;
+ }
+
+ return IndexType;
+}
+
+SDValue TargetLowering::expandIntMINMAX(SDNode *Node, SelectionDAG &DAG) const {
+ SDValue Op0 = Node->getOperand(0);
+ SDValue Op1 = Node->getOperand(1);
+ EVT VT = Op0.getValueType();
+ unsigned Opcode = Node->getOpcode();
+ SDLoc DL(Node);
+
+ // umin(x,y) -> sub(x,usubsat(x,y))
+ if (Opcode == ISD::UMIN && isOperationLegal(ISD::SUB, VT) &&
+ isOperationLegal(ISD::USUBSAT, VT)) {
+ return DAG.getNode(ISD::SUB, DL, VT, Op0,
+ DAG.getNode(ISD::USUBSAT, DL, VT, Op0, Op1));
+ }
+
+ // umax(x,y) -> add(x,usubsat(y,x))
+ if (Opcode == ISD::UMAX && isOperationLegal(ISD::ADD, VT) &&
+ isOperationLegal(ISD::USUBSAT, VT)) {
+ return DAG.getNode(ISD::ADD, DL, VT, Op0,
+ DAG.getNode(ISD::USUBSAT, DL, VT, Op1, Op0));
+ }
+
+ // Expand Y = MAX(A, B) -> Y = (A > B) ? A : B
+ ISD::CondCode CC;
+ switch (Opcode) {
+ default: llvm_unreachable("How did we get here?");
+ case ISD::SMAX: CC = ISD::SETGT; break;
+ case ISD::SMIN: CC = ISD::SETLT; break;
+ case ISD::UMAX: CC = ISD::SETUGT; break;
+ case ISD::UMIN: CC = ISD::SETULT; break;
+ }
+
+ // FIXME: Should really try to split the vector in case it's legal on a
+ // subvector.
+ if (VT.isVector() && !isOperationLegalOrCustom(ISD::VSELECT, VT))
+ return DAG.UnrollVectorOp(Node);
+
+ SDValue Cond = DAG.getSetCC(DL, VT, Op0, Op1, CC);
+ return DAG.getSelect(DL, VT, Cond, Op0, Op1);
+}
+
SDValue TargetLowering::expandAddSubSat(SDNode *Node, SelectionDAG &DAG) const {
unsigned Opcode = Node->getOpcode();
SDValue LHS = Node->getOperand(0);
@@ -7708,13 +7708,13 @@ SDValue TargetLowering::expandAddSubSat(SDNode *Node, SelectionDAG &DAG) const {
assert(VT.isInteger() && "Expected operands to be integers");
// usub.sat(a, b) -> umax(a, b) - b
- if (Opcode == ISD::USUBSAT && isOperationLegal(ISD::UMAX, VT)) {
+ if (Opcode == ISD::USUBSAT && isOperationLegal(ISD::UMAX, VT)) {
SDValue Max = DAG.getNode(ISD::UMAX, dl, VT, LHS, RHS);
return DAG.getNode(ISD::SUB, dl, VT, Max, RHS);
}
- // uadd.sat(a, b) -> umin(a, ~b) + b
- if (Opcode == ISD::UADDSAT && isOperationLegal(ISD::UMIN, VT)) {
+ // uadd.sat(a, b) -> umin(a, ~b) + b
+ if (Opcode == ISD::UADDSAT && isOperationLegal(ISD::UMIN, VT)) {
SDValue InvRHS = DAG.getNOT(dl, RHS, VT);
SDValue Min = DAG.getNode(ISD::UMIN, dl, VT, LHS, InvRHS);
return DAG.getNode(ISD::ADD, dl, VT, Min, RHS);
@@ -7739,11 +7739,11 @@ SDValue TargetLowering::expandAddSubSat(SDNode *Node, SelectionDAG &DAG) const {
"addition or subtraction node.");
}
- // FIXME: Should really try to split the vector in case it's legal on a
- // subvector.
- if (VT.isVector() && !isOperationLegalOrCustom(ISD::VSELECT, VT))
- return DAG.UnrollVectorOp(Node);
-
+ // FIXME: Should really try to split the vector in case it's legal on a
+ // subvector.
+ if (VT.isVector() && !isOperationLegalOrCustom(ISD::VSELECT, VT))
+ return DAG.UnrollVectorOp(Node);
+
unsigned BitWidth = LHS.getScalarValueSizeInBits();
EVT BoolVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
SDValue Result = DAG.getNode(OverflowOp, dl, DAG.getVTList(VT, BoolVT),
@@ -7783,41 +7783,41 @@ SDValue TargetLowering::expandAddSubSat(SDNode *Node, SelectionDAG &DAG) const {
}
}
-SDValue TargetLowering::expandShlSat(SDNode *Node, SelectionDAG &DAG) const {
- unsigned Opcode = Node->getOpcode();
- bool IsSigned = Opcode == ISD::SSHLSAT;
- SDValue LHS = Node->getOperand(0);
- SDValue RHS = Node->getOperand(1);
- EVT VT = LHS.getValueType();
- SDLoc dl(Node);
-
- assert((Node->getOpcode() == ISD::SSHLSAT ||
- Node->getOpcode() == ISD::USHLSAT) &&
- "Expected a SHLSAT opcode");
- assert(VT == RHS.getValueType() && "Expected operands to be the same type");
- assert(VT.isInteger() && "Expected operands to be integers");
-
- // If LHS != (LHS << RHS) >> RHS, we have overflow and must saturate.
-
- unsigned BW = VT.getScalarSizeInBits();
- SDValue Result = DAG.getNode(ISD::SHL, dl, VT, LHS, RHS);
- SDValue Orig =
- DAG.getNode(IsSigned ? ISD::SRA : ISD::SRL, dl, VT, Result, RHS);
-
- SDValue SatVal;
- if (IsSigned) {
- SDValue SatMin = DAG.getConstant(APInt::getSignedMinValue(BW), dl, VT);
- SDValue SatMax = DAG.getConstant(APInt::getSignedMaxValue(BW), dl, VT);
- SatVal = DAG.getSelectCC(dl, LHS, DAG.getConstant(0, dl, VT),
- SatMin, SatMax, ISD::SETLT);
- } else {
- SatVal = DAG.getConstant(APInt::getMaxValue(BW), dl, VT);
- }
- Result = DAG.getSelectCC(dl, LHS, Orig, SatVal, Result, ISD::SETNE);
-
- return Result;
-}
-
+SDValue TargetLowering::expandShlSat(SDNode *Node, SelectionDAG &DAG) const {
+ unsigned Opcode = Node->getOpcode();
+ bool IsSigned = Opcode == ISD::SSHLSAT;
+ SDValue LHS = Node->getOperand(0);
+ SDValue RHS = Node->getOperand(1);
+ EVT VT = LHS.getValueType();
+ SDLoc dl(Node);
+
+ assert((Node->getOpcode() == ISD::SSHLSAT ||
+ Node->getOpcode() == ISD::USHLSAT) &&
+ "Expected a SHLSAT opcode");
+ assert(VT == RHS.getValueType() && "Expected operands to be the same type");
+ assert(VT.isInteger() && "Expected operands to be integers");
+
+ // If LHS != (LHS << RHS) >> RHS, we have overflow and must saturate.
+
+ unsigned BW = VT.getScalarSizeInBits();
+ SDValue Result = DAG.getNode(ISD::SHL, dl, VT, LHS, RHS);
+ SDValue Orig =
+ DAG.getNode(IsSigned ? ISD::SRA : ISD::SRL, dl, VT, Result, RHS);
+
+ SDValue SatVal;
+ if (IsSigned) {
+ SDValue SatMin = DAG.getConstant(APInt::getSignedMinValue(BW), dl, VT);
+ SDValue SatMax = DAG.getConstant(APInt::getSignedMaxValue(BW), dl, VT);
+ SatVal = DAG.getSelectCC(dl, LHS, DAG.getConstant(0, dl, VT),
+ SatMin, SatMax, ISD::SETLT);
+ } else {
+ SatVal = DAG.getConstant(APInt::getMaxValue(BW), dl, VT);
+ }
+ Result = DAG.getSelectCC(dl, LHS, Orig, SatVal, Result, ISD::SETNE);
+
+ return Result;
+}
+
SDValue
TargetLowering::expandFixedPointMul(SDNode *Node, SelectionDAG &DAG) const {
assert((Node->getOpcode() == ISD::SMULFIX ||
@@ -8191,7 +8191,7 @@ bool TargetLowering::expandMULO(SDNode *Node, SDValue &Result,
if (isSigned) {
// The high part is obtained by SRA'ing all but one of the bits of low
// part.
- unsigned LoSize = VT.getFixedSizeInBits();
+ unsigned LoSize = VT.getFixedSizeInBits();
HiLHS =
DAG.getNode(ISD::SRA, dl, VT, LHS,
DAG.getConstant(LoSize - 1, dl,
@@ -8250,7 +8250,7 @@ bool TargetLowering::expandMULO(SDNode *Node, SDValue &Result,
// Truncate the result if SetCC returns a larger type than needed.
EVT RType = Node->getValueType(1);
- if (RType.bitsLT(Overflow.getValueType()))
+ if (RType.bitsLT(Overflow.getValueType()))
Overflow = DAG.getNode(ISD::TRUNCATE, dl, RType, Overflow);
assert(RType.getSizeInBits() == Overflow.getValueSizeInBits() &&
@@ -8260,14 +8260,14 @@ bool TargetLowering::expandMULO(SDNode *Node, SDValue &Result,
SDValue TargetLowering::expandVecReduce(SDNode *Node, SelectionDAG &DAG) const {
SDLoc dl(Node);
- unsigned BaseOpcode = ISD::getVecReduceBaseOpcode(Node->getOpcode());
+ unsigned BaseOpcode = ISD::getVecReduceBaseOpcode(Node->getOpcode());
SDValue Op = Node->getOperand(0);
EVT VT = Op.getValueType();
- if (VT.isScalableVector())
- report_fatal_error(
- "Expanding reductions for scalable vectors is undefined.");
-
+ if (VT.isScalableVector())
+ report_fatal_error(
+ "Expanding reductions for scalable vectors is undefined.");
+
// Try to use a shuffle reduction for power of two vectors.
if (VT.isPow2VectorType()) {
while (VT.getVectorNumElements() > 1) {
@@ -8298,33 +8298,33 @@ SDValue TargetLowering::expandVecReduce(SDNode *Node, SelectionDAG &DAG) const {
return Res;
}
-SDValue TargetLowering::expandVecReduceSeq(SDNode *Node, SelectionDAG &DAG) const {
- SDLoc dl(Node);
- SDValue AccOp = Node->getOperand(0);
- SDValue VecOp = Node->getOperand(1);
- SDNodeFlags Flags = Node->getFlags();
-
- EVT VT = VecOp.getValueType();
- EVT EltVT = VT.getVectorElementType();
-
- if (VT.isScalableVector())
- report_fatal_error(
- "Expanding reductions for scalable vectors is undefined.");
-
- unsigned NumElts = VT.getVectorNumElements();
-
- SmallVector<SDValue, 8> Ops;
- DAG.ExtractVectorElements(VecOp, Ops, 0, NumElts);
-
- unsigned BaseOpcode = ISD::getVecReduceBaseOpcode(Node->getOpcode());
-
- SDValue Res = AccOp;
- for (unsigned i = 0; i < NumElts; i++)
- Res = DAG.getNode(BaseOpcode, dl, EltVT, Res, Ops[i], Flags);
-
- return Res;
-}
-
+SDValue TargetLowering::expandVecReduceSeq(SDNode *Node, SelectionDAG &DAG) const {
+ SDLoc dl(Node);
+ SDValue AccOp = Node->getOperand(0);
+ SDValue VecOp = Node->getOperand(1);
+ SDNodeFlags Flags = Node->getFlags();
+
+ EVT VT = VecOp.getValueType();
+ EVT EltVT = VT.getVectorElementType();
+
+ if (VT.isScalableVector())
+ report_fatal_error(
+ "Expanding reductions for scalable vectors is undefined.");
+
+ unsigned NumElts = VT.getVectorNumElements();
+
+ SmallVector<SDValue, 8> Ops;
+ DAG.ExtractVectorElements(VecOp, Ops, 0, NumElts);
+
+ unsigned BaseOpcode = ISD::getVecReduceBaseOpcode(Node->getOpcode());
+
+ SDValue Res = AccOp;
+ for (unsigned i = 0; i < NumElts; i++)
+ Res = DAG.getNode(BaseOpcode, dl, EltVT, Res, Ops[i], Flags);
+
+ return Res;
+}
+
bool TargetLowering::expandREM(SDNode *Node, SDValue &Result,
SelectionDAG &DAG) const {
EVT VT = Node->getValueType(0);
@@ -8347,105 +8347,105 @@ bool TargetLowering::expandREM(SDNode *Node, SDValue &Result,
}
return false;
}
-
-SDValue TargetLowering::expandFP_TO_INT_SAT(SDNode *Node,
- SelectionDAG &DAG) const {
- bool IsSigned = Node->getOpcode() == ISD::FP_TO_SINT_SAT;
- SDLoc dl(SDValue(Node, 0));
- SDValue Src = Node->getOperand(0);
-
- // DstVT is the result type, while SatVT is the size to which we saturate
- EVT SrcVT = Src.getValueType();
- EVT DstVT = Node->getValueType(0);
-
- unsigned SatWidth = Node->getConstantOperandVal(1);
- unsigned DstWidth = DstVT.getScalarSizeInBits();
- assert(SatWidth <= DstWidth &&
- "Expected saturation width smaller than result width");
-
- // Determine minimum and maximum integer values and their corresponding
- // floating-point values.
- APInt MinInt, MaxInt;
- if (IsSigned) {
- MinInt = APInt::getSignedMinValue(SatWidth).sextOrSelf(DstWidth);
- MaxInt = APInt::getSignedMaxValue(SatWidth).sextOrSelf(DstWidth);
- } else {
- MinInt = APInt::getMinValue(SatWidth).zextOrSelf(DstWidth);
- MaxInt = APInt::getMaxValue(SatWidth).zextOrSelf(DstWidth);
- }
-
- // We cannot risk emitting FP_TO_XINT nodes with a source VT of f16, as
- // libcall emission cannot handle this. Large result types will fail.
- if (SrcVT == MVT::f16) {
- Src = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f32, Src);
- SrcVT = Src.getValueType();
- }
-
- APFloat MinFloat(DAG.EVTToAPFloatSemantics(SrcVT));
- APFloat MaxFloat(DAG.EVTToAPFloatSemantics(SrcVT));
-
- APFloat::opStatus MinStatus =
- MinFloat.convertFromAPInt(MinInt, IsSigned, APFloat::rmTowardZero);
- APFloat::opStatus MaxStatus =
- MaxFloat.convertFromAPInt(MaxInt, IsSigned, APFloat::rmTowardZero);
- bool AreExactFloatBounds = !(MinStatus & APFloat::opStatus::opInexact) &&
- !(MaxStatus & APFloat::opStatus::opInexact);
-
- SDValue MinFloatNode = DAG.getConstantFP(MinFloat, dl, SrcVT);
- SDValue MaxFloatNode = DAG.getConstantFP(MaxFloat, dl, SrcVT);
-
- // If the integer bounds are exactly representable as floats and min/max are
- // legal, emit a min+max+fptoi sequence. Otherwise we have to use a sequence
- // of comparisons and selects.
- bool MinMaxLegal = isOperationLegal(ISD::FMINNUM, SrcVT) &&
- isOperationLegal(ISD::FMAXNUM, SrcVT);
- if (AreExactFloatBounds && MinMaxLegal) {
- SDValue Clamped = Src;
-
- // Clamp Src by MinFloat from below. If Src is NaN the result is MinFloat.
- Clamped = DAG.getNode(ISD::FMAXNUM, dl, SrcVT, Clamped, MinFloatNode);
- // Clamp by MaxFloat from above. NaN cannot occur.
- Clamped = DAG.getNode(ISD::FMINNUM, dl, SrcVT, Clamped, MaxFloatNode);
- // Convert clamped value to integer.
- SDValue FpToInt = DAG.getNode(IsSigned ? ISD::FP_TO_SINT : ISD::FP_TO_UINT,
- dl, DstVT, Clamped);
-
- // In the unsigned case we're done, because we mapped NaN to MinFloat,
- // which will cast to zero.
- if (!IsSigned)
- return FpToInt;
-
- // Otherwise, select 0 if Src is NaN.
- SDValue ZeroInt = DAG.getConstant(0, dl, DstVT);
- return DAG.getSelectCC(dl, Src, Src, ZeroInt, FpToInt,
- ISD::CondCode::SETUO);
- }
-
- SDValue MinIntNode = DAG.getConstant(MinInt, dl, DstVT);
- SDValue MaxIntNode = DAG.getConstant(MaxInt, dl, DstVT);
-
- // Result of direct conversion. The assumption here is that the operation is
- // non-trapping and it's fine to apply it to an out-of-range value if we
- // select it away later.
- SDValue FpToInt =
- DAG.getNode(IsSigned ? ISD::FP_TO_SINT : ISD::FP_TO_UINT, dl, DstVT, Src);
-
- SDValue Select = FpToInt;
-
- // If Src ULT MinFloat, select MinInt. In particular, this also selects
- // MinInt if Src is NaN.
- Select = DAG.getSelectCC(dl, Src, MinFloatNode, MinIntNode, Select,
- ISD::CondCode::SETULT);
- // If Src OGT MaxFloat, select MaxInt.
- Select = DAG.getSelectCC(dl, Src, MaxFloatNode, MaxIntNode, Select,
- ISD::CondCode::SETOGT);
-
- // In the unsigned case we are done, because we mapped NaN to MinInt, which
- // is already zero.
- if (!IsSigned)
- return Select;
-
- // Otherwise, select 0 if Src is NaN.
- SDValue ZeroInt = DAG.getConstant(0, dl, DstVT);
- return DAG.getSelectCC(dl, Src, Src, ZeroInt, Select, ISD::CondCode::SETUO);
-}
+
+SDValue TargetLowering::expandFP_TO_INT_SAT(SDNode *Node,
+ SelectionDAG &DAG) const {
+ bool IsSigned = Node->getOpcode() == ISD::FP_TO_SINT_SAT;
+ SDLoc dl(SDValue(Node, 0));
+ SDValue Src = Node->getOperand(0);
+
+ // DstVT is the result type, while SatVT is the size to which we saturate
+ EVT SrcVT = Src.getValueType();
+ EVT DstVT = Node->getValueType(0);
+
+ unsigned SatWidth = Node->getConstantOperandVal(1);
+ unsigned DstWidth = DstVT.getScalarSizeInBits();
+ assert(SatWidth <= DstWidth &&
+ "Expected saturation width smaller than result width");
+
+ // Determine minimum and maximum integer values and their corresponding
+ // floating-point values.
+ APInt MinInt, MaxInt;
+ if (IsSigned) {
+ MinInt = APInt::getSignedMinValue(SatWidth).sextOrSelf(DstWidth);
+ MaxInt = APInt::getSignedMaxValue(SatWidth).sextOrSelf(DstWidth);
+ } else {
+ MinInt = APInt::getMinValue(SatWidth).zextOrSelf(DstWidth);
+ MaxInt = APInt::getMaxValue(SatWidth).zextOrSelf(DstWidth);
+ }
+
+ // We cannot risk emitting FP_TO_XINT nodes with a source VT of f16, as
+ // libcall emission cannot handle this. Large result types will fail.
+ if (SrcVT == MVT::f16) {
+ Src = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f32, Src);
+ SrcVT = Src.getValueType();
+ }
+
+ APFloat MinFloat(DAG.EVTToAPFloatSemantics(SrcVT));
+ APFloat MaxFloat(DAG.EVTToAPFloatSemantics(SrcVT));
+
+ APFloat::opStatus MinStatus =
+ MinFloat.convertFromAPInt(MinInt, IsSigned, APFloat::rmTowardZero);
+ APFloat::opStatus MaxStatus =
+ MaxFloat.convertFromAPInt(MaxInt, IsSigned, APFloat::rmTowardZero);
+ bool AreExactFloatBounds = !(MinStatus & APFloat::opStatus::opInexact) &&
+ !(MaxStatus & APFloat::opStatus::opInexact);
+
+ SDValue MinFloatNode = DAG.getConstantFP(MinFloat, dl, SrcVT);
+ SDValue MaxFloatNode = DAG.getConstantFP(MaxFloat, dl, SrcVT);
+
+ // If the integer bounds are exactly representable as floats and min/max are
+ // legal, emit a min+max+fptoi sequence. Otherwise we have to use a sequence
+ // of comparisons and selects.
+ bool MinMaxLegal = isOperationLegal(ISD::FMINNUM, SrcVT) &&
+ isOperationLegal(ISD::FMAXNUM, SrcVT);
+ if (AreExactFloatBounds && MinMaxLegal) {
+ SDValue Clamped = Src;
+
+ // Clamp Src by MinFloat from below. If Src is NaN the result is MinFloat.
+ Clamped = DAG.getNode(ISD::FMAXNUM, dl, SrcVT, Clamped, MinFloatNode);
+ // Clamp by MaxFloat from above. NaN cannot occur.
+ Clamped = DAG.getNode(ISD::FMINNUM, dl, SrcVT, Clamped, MaxFloatNode);
+ // Convert clamped value to integer.
+ SDValue FpToInt = DAG.getNode(IsSigned ? ISD::FP_TO_SINT : ISD::FP_TO_UINT,
+ dl, DstVT, Clamped);
+
+ // In the unsigned case we're done, because we mapped NaN to MinFloat,
+ // which will cast to zero.
+ if (!IsSigned)
+ return FpToInt;
+
+ // Otherwise, select 0 if Src is NaN.
+ SDValue ZeroInt = DAG.getConstant(0, dl, DstVT);
+ return DAG.getSelectCC(dl, Src, Src, ZeroInt, FpToInt,
+ ISD::CondCode::SETUO);
+ }
+
+ SDValue MinIntNode = DAG.getConstant(MinInt, dl, DstVT);
+ SDValue MaxIntNode = DAG.getConstant(MaxInt, dl, DstVT);
+
+ // Result of direct conversion. The assumption here is that the operation is
+ // non-trapping and it's fine to apply it to an out-of-range value if we
+ // select it away later.
+ SDValue FpToInt =
+ DAG.getNode(IsSigned ? ISD::FP_TO_SINT : ISD::FP_TO_UINT, dl, DstVT, Src);
+
+ SDValue Select = FpToInt;
+
+ // If Src ULT MinFloat, select MinInt. In particular, this also selects
+ // MinInt if Src is NaN.
+ Select = DAG.getSelectCC(dl, Src, MinFloatNode, MinIntNode, Select,
+ ISD::CondCode::SETULT);
+ // If Src OGT MaxFloat, select MaxInt.
+ Select = DAG.getSelectCC(dl, Src, MaxFloatNode, MaxIntNode, Select,
+ ISD::CondCode::SETOGT);
+
+ // In the unsigned case we are done, because we mapped NaN to MinInt, which
+ // is already zero.
+ if (!IsSigned)
+ return Select;
+
+ // Otherwise, select 0 if Src is NaN.
+ SDValue ZeroInt = DAG.getConstant(0, dl, DstVT);
+ return DAG.getSelectCC(dl, Src, Src, ZeroInt, Select, ISD::CondCode::SETUO);
+}
diff --git a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ya.make b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ya.make
index 147d550458..9fa4f90d2f 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ya.make
+++ b/contrib/libs/llvm12/lib/CodeGen/SelectionDAG/ya.make
@@ -12,15 +12,15 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/CodeGen
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target
- contrib/libs/llvm12/lib/Transforms/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/CodeGen
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target
+ contrib/libs/llvm12/lib/Transforms/Utils
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/CodeGen/ShrinkWrap.cpp b/contrib/libs/llvm12/lib/CodeGen/ShrinkWrap.cpp
index 068c1466f5..f89069e9f7 100644
--- a/contrib/libs/llvm12/lib/CodeGen/ShrinkWrap.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/ShrinkWrap.cpp
@@ -144,7 +144,7 @@ class ShrinkWrap : public MachineFunctionPass {
unsigned FrameDestroyOpcode;
/// Stack pointer register, used by llvm.{savestack,restorestack}
- Register SP;
+ Register SP;
/// Entry block.
const MachineBasicBlock *Entry;
@@ -331,7 +331,7 @@ void ShrinkWrap::updateSaveRestorePoints(MachineBasicBlock &MBB,
Save = &MBB;
else
Save = MDT->findNearestCommonDominator(Save, &MBB);
- assert(Save);
+ assert(Save);
if (!Restore)
Restore = &MBB;
@@ -377,7 +377,7 @@ void ShrinkWrap::updateSaveRestorePoints(MachineBasicBlock &MBB,
// C. Save and Restore are in the same loop.
bool SaveDominatesRestore = false;
bool RestorePostDominatesSave = false;
- while (Restore &&
+ while (Restore &&
(!(SaveDominatesRestore = MDT->dominates(Save, Restore)) ||
!(RestorePostDominatesSave = MPDT->dominates(Restore, Save)) ||
// Post-dominance is not enough in loops to ensure that all uses/defs
@@ -408,7 +408,7 @@ void ShrinkWrap::updateSaveRestorePoints(MachineBasicBlock &MBB,
Restore = MPDT->findNearestCommonDominator(Restore, Save);
// Fix (C).
- if (Restore && (MLI->getLoopFor(Save) || MLI->getLoopFor(Restore))) {
+ if (Restore && (MLI->getLoopFor(Save) || MLI->getLoopFor(Restore))) {
if (MLI->getLoopDepth(Save) > MLI->getLoopDepth(Restore)) {
// Push Save outside of this loop if immediate dominator is different
// from save block. If immediate dominator is not different, bail out.
diff --git a/contrib/libs/llvm12/lib/CodeGen/SjLjEHPrepare.cpp b/contrib/libs/llvm12/lib/CodeGen/SjLjEHPrepare.cpp
index 87abdde45a..d2fd4a6d8f 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SjLjEHPrepare.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SjLjEHPrepare.cpp
@@ -142,7 +142,7 @@ static void MarkBlocksLiveIn(BasicBlock *BB,
/// instruction with those returned by the personality function.
void SjLjEHPrepare::substituteLPadValues(LandingPadInst *LPI, Value *ExnVal,
Value *SelVal) {
- SmallVector<Value *, 8> UseWorkList(LPI->users());
+ SmallVector<Value *, 8> UseWorkList(LPI->users());
while (!UseWorkList.empty()) {
Value *Val = UseWorkList.pop_back_val();
auto *EVI = dyn_cast<ExtractValueInst>(Val);
diff --git a/contrib/libs/llvm12/lib/CodeGen/SplitKit.cpp b/contrib/libs/llvm12/lib/CodeGen/SplitKit.cpp
index 73282e9c0d..a6a3149ae2 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SplitKit.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SplitKit.cpp
@@ -168,7 +168,7 @@ void SplitAnalysis::analyzeUses() {
// Get use slots form the use-def chain.
const MachineRegisterInfo &MRI = MF.getRegInfo();
- for (MachineOperand &MO : MRI.use_nodbg_operands(CurLI->reg()))
+ for (MachineOperand &MO : MRI.use_nodbg_operands(CurLI->reg()))
if (!MO.isUndef())
UseSlots.push_back(LIS.getInstructionIndex(*MO.getParent()).getRegSlot());
@@ -333,7 +333,7 @@ unsigned SplitAnalysis::countLiveBlocks(const LiveInterval *cli) const {
}
bool SplitAnalysis::isOriginalEndpoint(SlotIndex Idx) const {
- unsigned OrigReg = VRM.getOriginal(CurLI->reg());
+ unsigned OrigReg = VRM.getOriginal(CurLI->reg());
const LiveInterval &Orig = LIS.getInterval(OrigReg);
assert(!Orig.empty() && "Splitting empty interval?");
LiveInterval::const_iterator I = Orig.find(Idx);
@@ -399,18 +399,18 @@ LLVM_DUMP_METHOD void SplitEditor::dump() const {
}
#endif
-LiveInterval::SubRange &SplitEditor::getSubRangeForMaskExact(LaneBitmask LM,
- LiveInterval &LI) {
- for (LiveInterval::SubRange &S : LI.subranges())
- if (S.LaneMask == LM)
- return S;
- llvm_unreachable("SubRange for this mask not found");
-}
-
+LiveInterval::SubRange &SplitEditor::getSubRangeForMaskExact(LaneBitmask LM,
+ LiveInterval &LI) {
+ for (LiveInterval::SubRange &S : LI.subranges())
+ if (S.LaneMask == LM)
+ return S;
+ llvm_unreachable("SubRange for this mask not found");
+}
+
LiveInterval::SubRange &SplitEditor::getSubRangeForMask(LaneBitmask LM,
LiveInterval &LI) {
for (LiveInterval::SubRange &S : LI.subranges())
- if ((S.LaneMask & LM) == LM)
+ if ((S.LaneMask & LM) == LM)
return S;
llvm_unreachable("SubRange for this mask not found");
}
@@ -441,7 +441,7 @@ void SplitEditor::addDeadDef(LiveInterval &LI, VNInfo *VNI, bool Original) {
LaneBitmask LM;
for (const MachineOperand &DefOp : DefMI->defs()) {
Register R = DefOp.getReg();
- if (R != LI.reg())
+ if (R != LI.reg())
continue;
if (unsigned SR = DefOp.getSubReg())
LM |= TRI.getSubRegIndexLaneMask(SR);
@@ -512,7 +512,7 @@ void SplitEditor::forceRecompute(unsigned RegIdx, const VNInfo &ParentVNI) {
VFP = ValueForcePair(nullptr, true);
}
-SlotIndex SplitEditor::buildSingleSubRegCopy(Register FromReg, Register ToReg,
+SlotIndex SplitEditor::buildSingleSubRegCopy(Register FromReg, Register ToReg,
MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore,
unsigned SubIdx, LiveInterval &DestLI, bool Late, SlotIndex Def) {
const MCInstrDesc &Desc = TII.get(TargetOpcode::COPY);
@@ -538,7 +538,7 @@ SlotIndex SplitEditor::buildSingleSubRegCopy(Register FromReg, Register ToReg,
return Def;
}
-SlotIndex SplitEditor::buildCopy(Register FromReg, Register ToReg,
+SlotIndex SplitEditor::buildCopy(Register FromReg, Register ToReg,
LaneBitmask LaneMask, MachineBasicBlock &MBB,
MachineBasicBlock::iterator InsertBefore, bool Late, unsigned RegIdx) {
const MCInstrDesc &Desc = TII.get(TargetOpcode::COPY);
@@ -644,7 +644,7 @@ VNInfo *SplitEditor::defFromParent(unsigned RegIdx,
LiveInterval &OrigLI = LIS.getInterval(Original);
VNInfo *OrigVNI = OrigLI.getVNInfoAt(UseIdx);
- Register Reg = LI->reg();
+ Register Reg = LI->reg();
bool DidRemat = false;
if (OrigVNI) {
LiveRangeEdit::Remat RM(ParentVNI);
@@ -657,25 +657,25 @@ VNInfo *SplitEditor::defFromParent(unsigned RegIdx,
}
if (!DidRemat) {
LaneBitmask LaneMask;
- if (OrigLI.hasSubRanges()) {
+ if (OrigLI.hasSubRanges()) {
LaneMask = LaneBitmask::getNone();
- for (LiveInterval::SubRange &S : OrigLI.subranges()) {
- if (S.liveAt(UseIdx))
- LaneMask |= S.LaneMask;
- }
+ for (LiveInterval::SubRange &S : OrigLI.subranges()) {
+ if (S.liveAt(UseIdx))
+ LaneMask |= S.LaneMask;
+ }
} else {
LaneMask = LaneBitmask::getAll();
}
- if (LaneMask.none()) {
- const MCInstrDesc &Desc = TII.get(TargetOpcode::IMPLICIT_DEF);
- MachineInstr *ImplicitDef = BuildMI(MBB, I, DebugLoc(), Desc, Reg);
- SlotIndexes &Indexes = *LIS.getSlotIndexes();
- Def = Indexes.insertMachineInstrInMaps(*ImplicitDef, Late).getRegSlot();
- } else {
- ++NumCopies;
- Def = buildCopy(Edit->getReg(), Reg, LaneMask, MBB, I, Late, RegIdx);
- }
+ if (LaneMask.none()) {
+ const MCInstrDesc &Desc = TII.get(TargetOpcode::IMPLICIT_DEF);
+ MachineInstr *ImplicitDef = BuildMI(MBB, I, DebugLoc(), Desc, Reg);
+ SlotIndexes &Indexes = *LIS.getSlotIndexes();
+ Def = Indexes.insertMachineInstrInMaps(*ImplicitDef, Late).getRegSlot();
+ } else {
+ ++NumCopies;
+ Def = buildCopy(Edit->getReg(), Reg, LaneMask, MBB, I, Late, RegIdx);
+ }
}
// Define the value in Reg.
@@ -998,7 +998,7 @@ void SplitEditor::computeRedundantBackCopies(
}
if (!DominatedVNIs.empty()) {
forceRecompute(0, *ParentVNI);
- append_range(BackCopies, DominatedVNIs);
+ append_range(BackCopies, DominatedVNIs);
DominatedVNIs.clear();
}
}
@@ -1259,8 +1259,8 @@ void SplitEditor::extendPHIRange(MachineBasicBlock &B, LiveIntervalCalc &LIC,
LiveInterval &PLI = Edit->getParent();
// Need the cast because the inputs to ?: would otherwise be deemed
// "incompatible": SubRange vs LiveInterval.
- LiveRange &PSR = !LM.all() ? getSubRangeForMaskExact(LM, PLI)
- : static_cast<LiveRange &>(PLI);
+ LiveRange &PSR = !LM.all() ? getSubRangeForMaskExact(LM, PLI)
+ : static_cast<LiveRange &>(PLI);
if (PSR.liveAt(LastUse))
LIC.extend(LR, End, /*PhysReg=*/0, Undefs);
}
@@ -1295,7 +1295,7 @@ void SplitEditor::extendPHIKillRanges() {
continue;
unsigned RegIdx = RegAssign.lookup(V->def);
LiveInterval &LI = LIS.getInterval(Edit->get(RegIdx));
- LiveInterval::SubRange &S = getSubRangeForMaskExact(PS.LaneMask, LI);
+ LiveInterval::SubRange &S = getSubRangeForMaskExact(PS.LaneMask, LI);
if (removeDeadSegment(V->def, S))
continue;
@@ -1344,7 +1344,7 @@ void SplitEditor::rewriteAssigned(bool ExtendRanges) {
// Rewrite to the mapped register at Idx.
unsigned RegIdx = RegAssign.lookup(Idx);
LiveInterval &LI = LIS.getInterval(Edit->get(RegIdx));
- MO.setReg(LI.reg());
+ MO.setReg(LI.reg());
LLVM_DEBUG(dbgs() << " rewr " << printMBBReference(*MI->getParent())
<< '\t' << Idx << ':' << RegIdx << '\t' << *MI);
@@ -1404,7 +1404,7 @@ void SplitEditor::rewriteAssigned(bool ExtendRanges) {
}
}
- for (Register R : *Edit) {
+ for (Register R : *Edit) {
LiveInterval &LI = LIS.getInterval(R);
if (!LI.hasSubRanges())
continue;
@@ -1426,7 +1426,7 @@ void SplitEditor::deleteRematVictims() {
continue;
MachineInstr *MI = LIS.getInstructionFromIndex(S.valno->def);
assert(MI && "Missing instruction for dead def");
- MI->addRegisterDead(LI->reg(), &TRI);
+ MI->addRegisterDead(LI->reg(), &TRI);
if (!MI->allDefsAreDead())
continue;
@@ -1523,7 +1523,7 @@ void SplitEditor::finish(SmallVectorImpl<unsigned> *LRMap) {
deleteRematVictims();
// Get rid of unused values and set phi-kill flags.
- for (Register Reg : *Edit) {
+ for (Register Reg : *Edit) {
LiveInterval &LI = LIS.getInterval(Reg);
LI.removeEmptySubRanges();
LI.RenumberValues();
@@ -1540,13 +1540,13 @@ void SplitEditor::finish(SmallVectorImpl<unsigned> *LRMap) {
ConnectedVNInfoEqClasses ConEQ(LIS);
for (unsigned i = 0, e = Edit->size(); i != e; ++i) {
// Don't use iterators, they are invalidated by create() below.
- Register VReg = Edit->get(i);
+ Register VReg = Edit->get(i);
LiveInterval &LI = LIS.getInterval(VReg);
SmallVector<LiveInterval*, 8> SplitLIs;
LIS.splitSeparateComponents(LI, SplitLIs);
- Register Original = VRM.getOriginal(VReg);
+ Register Original = VRM.getOriginal(VReg);
for (LiveInterval *SplitLI : SplitLIs)
- VRM.setIsSplitFromReg(SplitLI->reg(), Original);
+ VRM.setIsSplitFromReg(SplitLI->reg(), Original);
// The new intervals all map back to i.
if (LRMap)
diff --git a/contrib/libs/llvm12/lib/CodeGen/SplitKit.h b/contrib/libs/llvm12/lib/CodeGen/SplitKit.h
index 69c05c4939..a94518f5a4 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SplitKit.h
+++ b/contrib/libs/llvm12/lib/CodeGen/SplitKit.h
@@ -345,17 +345,17 @@ private:
return LICalc[SpillMode != SM_Partition && RegIdx != 0];
}
- /// Find a subrange corresponding to the exact lane mask @p LM in the live
+ /// Find a subrange corresponding to the exact lane mask @p LM in the live
/// interval @p LI. The interval @p LI is assumed to contain such a subrange.
/// This function is used to find corresponding subranges between the
/// original interval and the new intervals.
- LiveInterval::SubRange &getSubRangeForMaskExact(LaneBitmask LM,
- LiveInterval &LI);
-
- /// Find a subrange corresponding to the lane mask @p LM, or a superset of it,
- /// in the live interval @p LI. The interval @p LI is assumed to contain such
- /// a subrange. This function is used to find corresponding subranges between
- /// the original interval and the new intervals.
+ LiveInterval::SubRange &getSubRangeForMaskExact(LaneBitmask LM,
+ LiveInterval &LI);
+
+ /// Find a subrange corresponding to the lane mask @p LM, or a superset of it,
+ /// in the live interval @p LI. The interval @p LI is assumed to contain such
+ /// a subrange. This function is used to find corresponding subranges between
+ /// the original interval and the new intervals.
LiveInterval::SubRange &getSubRangeForMask(LaneBitmask LM, LiveInterval &LI);
/// Add a segment to the interval LI for the value number VNI. If LI has
@@ -439,11 +439,11 @@ private:
/// Add a copy instruction copying \p FromReg to \p ToReg before
/// \p InsertBefore. This can be invoked with a \p LaneMask which may make it
/// necessary to construct a sequence of copies to cover it exactly.
- SlotIndex buildCopy(Register FromReg, Register ToReg, LaneBitmask LaneMask,
+ SlotIndex buildCopy(Register FromReg, Register ToReg, LaneBitmask LaneMask,
MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore,
bool Late, unsigned RegIdx);
- SlotIndex buildSingleSubRegCopy(Register FromReg, Register ToReg,
+ SlotIndex buildSingleSubRegCopy(Register FromReg, Register ToReg,
MachineBasicBlock &MB, MachineBasicBlock::iterator InsertBefore,
unsigned SubIdx, LiveInterval &DestLI, bool Late, SlotIndex Def);
diff --git a/contrib/libs/llvm12/lib/CodeGen/StackColoring.cpp b/contrib/libs/llvm12/lib/CodeGen/StackColoring.cpp
index 644abd3886..af58204f6d 100644
--- a/contrib/libs/llvm12/lib/CodeGen/StackColoring.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/StackColoring.cpp
@@ -373,36 +373,36 @@ STATISTIC(EscapedAllocas, "Number of allocas that escaped the lifetime region");
// before visiting the memcpy block (which will contain the lifetime start
// for "b" then it will appear that 'b' has a degenerate lifetime.
//
-// Handle Windows Exception with LifetimeStartOnFirstUse:
-// -----------------
-//
-// There was a bug for using LifetimeStartOnFirstUse in win32.
-// class Type1 {
-// ...
-// ~Type1(){ write memory;}
-// }
-// ...
-// try{
-// Type1 V
-// ...
-// } catch (Type2 X){
-// ...
-// }
-// For variable X in catch(X), we put point pX=&(&X) into ConservativeSlots
-// to prevent using LifetimeStartOnFirstUse. Because pX may merged with
-// object V which may call destructor after implicitly writing pX. All these
-// are done in C++ EH runtime libs (through CxxThrowException), and can't
-// obviously check it in IR level.
-//
-// The loader of pX, without obvious writing IR, is usually the first LOAD MI
-// in EHPad, Some like:
-// bb.x.catch.i (landing-pad, ehfunclet-entry):
-// ; predecessors: %bb...
-// successors: %bb...
-// %n:gr32 = MOV32rm %stack.pX ...
-// ...
-// The Type2** %stack.pX will only be written in EH runtime libs, so we
-// check the StoreSlots to screen it out.
+// Handle Windows Exception with LifetimeStartOnFirstUse:
+// -----------------
+//
+// There was a bug for using LifetimeStartOnFirstUse in win32.
+// class Type1 {
+// ...
+// ~Type1(){ write memory;}
+// }
+// ...
+// try{
+// Type1 V
+// ...
+// } catch (Type2 X){
+// ...
+// }
+// For variable X in catch(X), we put point pX=&(&X) into ConservativeSlots
+// to prevent using LifetimeStartOnFirstUse. Because pX may merged with
+// object V which may call destructor after implicitly writing pX. All these
+// are done in C++ EH runtime libs (through CxxThrowException), and can't
+// obviously check it in IR level.
+//
+// The loader of pX, without obvious writing IR, is usually the first LOAD MI
+// in EHPad, Some like:
+// bb.x.catch.i (landing-pad, ehfunclet-entry):
+// ; predecessors: %bb...
+// successors: %bb...
+// %n:gr32 = MOV32rm %stack.pX ...
+// ...
+// The Type2** %stack.pX will only be written in EH runtime libs, so we
+// check the StoreSlots to screen it out.
namespace {
@@ -464,9 +464,9 @@ class StackColoring : public MachineFunctionPass {
/// slots lifetime-start-on-first-use is disabled).
BitVector ConservativeSlots;
- /// Record the FI slots referenced by a 'may write to memory'.
- BitVector StoreSlots;
-
+ /// Record the FI slots referenced by a 'may write to memory'.
+ BitVector StoreSlots;
+
/// Number of iterations taken during data flow analysis.
unsigned NumIterations;
@@ -662,13 +662,13 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) {
InterestingSlots.resize(NumSlot);
ConservativeSlots.clear();
ConservativeSlots.resize(NumSlot);
- StoreSlots.clear();
- StoreSlots.resize(NumSlot);
+ StoreSlots.clear();
+ StoreSlots.resize(NumSlot);
// number of start and end lifetime ops for each slot
SmallVector<int, 8> NumStartLifetimes(NumSlot, 0);
SmallVector<int, 8> NumEndLifetimes(NumSlot, 0);
- SmallVector<int, 8> NumLoadInCatchPad(NumSlot, 0);
+ SmallVector<int, 8> NumLoadInCatchPad(NumSlot, 0);
// Step 1: collect markers and populate the "InterestingSlots"
// and "ConservativeSlots" sets.
@@ -723,13 +723,13 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) {
if (! BetweenStartEnd.test(Slot)) {
ConservativeSlots.set(Slot);
}
- // Here we check the StoreSlots to screen catch point out. For more
- // information, please refer "Handle Windows Exception with
- // LifetimeStartOnFirstUse" at the head of this file.
- if (MI.mayStore())
- StoreSlots.set(Slot);
- if (MF->getWinEHFuncInfo() && MBB->isEHPad() && MI.mayLoad())
- NumLoadInCatchPad[Slot] += 1;
+ // Here we check the StoreSlots to screen catch point out. For more
+ // information, please refer "Handle Windows Exception with
+ // LifetimeStartOnFirstUse" at the head of this file.
+ if (MI.mayStore())
+ StoreSlots.set(Slot);
+ if (MF->getWinEHFuncInfo() && MBB->isEHPad() && MI.mayLoad())
+ NumLoadInCatchPad[Slot] += 1;
}
}
}
@@ -740,14 +740,14 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) {
return 0;
}
- // 1) PR27903: slots with multiple start or end lifetime ops are not
+ // 1) PR27903: slots with multiple start or end lifetime ops are not
// safe to enable for "lifetime-start-on-first-use".
- // 2) And also not safe for variable X in catch(X) in windows.
- for (unsigned slot = 0; slot < NumSlot; ++slot) {
- if (NumStartLifetimes[slot] > 1 || NumEndLifetimes[slot] > 1 ||
- (NumLoadInCatchPad[slot] > 1 && !StoreSlots.test(slot)))
+ // 2) And also not safe for variable X in catch(X) in windows.
+ for (unsigned slot = 0; slot < NumSlot; ++slot) {
+ if (NumStartLifetimes[slot] > 1 || NumEndLifetimes[slot] > 1 ||
+ (NumLoadInCatchPad[slot] > 1 && !StoreSlots.test(slot)))
ConservativeSlots.set(slot);
- }
+ }
LLVM_DEBUG(dumpBV("Conservative slots", ConservativeSlots));
// Step 2: compute begin/end sets for each block
@@ -1094,7 +1094,7 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
if (MMO->getAAInfo()) {
if (const Value *MMOV = MMO->getValue()) {
SmallVector<Value *, 4> Objs;
- getUnderlyingObjectsForCodeGen(MMOV, Objs);
+ getUnderlyingObjectsForCodeGen(MMOV, Objs);
if (Objs.empty())
MayHaveConflictingAAMD = true;
@@ -1287,7 +1287,7 @@ bool StackColoring::runOnMachineFunction(MachineFunction &Func) {
// This is a simple greedy algorithm for merging allocas. First, sort the
// slots, placing the largest slots first. Next, perform an n^2 scan and look
- // for disjoint slots. When you find disjoint slots, merge the smaller one
+ // for disjoint slots. When you find disjoint slots, merge the smaller one
// into the bigger one and update the live interval. Remove the small alloca
// and continue.
diff --git a/contrib/libs/llvm12/lib/CodeGen/StackMaps.cpp b/contrib/libs/llvm12/lib/CodeGen/StackMaps.cpp
index b8ad78fd42..faf07e90c3 100644
--- a/contrib/libs/llvm12/lib/CodeGen/StackMaps.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/StackMaps.cpp
@@ -45,14 +45,14 @@ static cl::opt<int> StackMapVersion(
const char *StackMaps::WSMP = "Stack Maps: ";
-static uint64_t getConstMetaVal(const MachineInstr &MI, unsigned Idx) {
- assert(MI.getOperand(Idx).isImm() &&
- MI.getOperand(Idx).getImm() == StackMaps::ConstantOp);
- const auto &MO = MI.getOperand(Idx + 1);
- assert(MO.isImm());
- return MO.getImm();
-}
-
+static uint64_t getConstMetaVal(const MachineInstr &MI, unsigned Idx) {
+ assert(MI.getOperand(Idx).isImm() &&
+ MI.getOperand(Idx).getImm() == StackMaps::ConstantOp);
+ const auto &MO = MI.getOperand(Idx + 1);
+ assert(MO.isImm());
+ return MO.getImm();
+}
+
StackMapOpers::StackMapOpers(const MachineInstr *MI)
: MI(MI) {
assert(getVarIdx() <= MI->getNumOperands() &&
@@ -91,89 +91,89 @@ unsigned PatchPointOpers::getNextScratchIdx(unsigned StartIdx) const {
return ScratchIdx;
}
-unsigned StatepointOpers::getNumGcMapEntriesIdx() {
- // Take index of num of allocas and skip all allocas records.
- unsigned CurIdx = getNumAllocaIdx();
- unsigned NumAllocas = getConstMetaVal(*MI, CurIdx - 1);
- CurIdx++;
- while (NumAllocas--)
- CurIdx = StackMaps::getNextMetaArgIdx(MI, CurIdx);
- return CurIdx + 1; // skip <StackMaps::ConstantOp>
-}
-
-unsigned StatepointOpers::getNumAllocaIdx() {
- // Take index of num of gc ptrs and skip all gc ptr records.
- unsigned CurIdx = getNumGCPtrIdx();
- unsigned NumGCPtrs = getConstMetaVal(*MI, CurIdx - 1);
- CurIdx++;
- while (NumGCPtrs--)
- CurIdx = StackMaps::getNextMetaArgIdx(MI, CurIdx);
- return CurIdx + 1; // skip <StackMaps::ConstantOp>
-}
-
-unsigned StatepointOpers::getNumGCPtrIdx() {
- // Take index of num of deopt args and skip all deopt records.
- unsigned CurIdx = getNumDeoptArgsIdx();
- unsigned NumDeoptArgs = getConstMetaVal(*MI, CurIdx - 1);
- CurIdx++;
- while (NumDeoptArgs--) {
- CurIdx = StackMaps::getNextMetaArgIdx(MI, CurIdx);
- }
- return CurIdx + 1; // skip <StackMaps::ConstantOp>
-}
-
-int StatepointOpers::getFirstGCPtrIdx() {
- unsigned NumGCPtrsIdx = getNumGCPtrIdx();
- unsigned NumGCPtrs = getConstMetaVal(*MI, NumGCPtrsIdx - 1);
- if (NumGCPtrs == 0)
- return -1;
- ++NumGCPtrsIdx; // skip <num gc ptrs>
- assert(NumGCPtrsIdx < MI->getNumOperands());
- return (int)NumGCPtrsIdx;
-}
-
-unsigned StatepointOpers::getGCPointerMap(
- SmallVectorImpl<std::pair<unsigned, unsigned>> &GCMap) {
- unsigned CurIdx = getNumGcMapEntriesIdx();
- unsigned GCMapSize = getConstMetaVal(*MI, CurIdx - 1);
- CurIdx++;
- for (unsigned N = 0; N < GCMapSize; ++N) {
- unsigned B = MI->getOperand(CurIdx++).getImm();
- unsigned D = MI->getOperand(CurIdx++).getImm();
- GCMap.push_back(std::make_pair(B, D));
- }
-
- return GCMapSize;
-}
-
+unsigned StatepointOpers::getNumGcMapEntriesIdx() {
+ // Take index of num of allocas and skip all allocas records.
+ unsigned CurIdx = getNumAllocaIdx();
+ unsigned NumAllocas = getConstMetaVal(*MI, CurIdx - 1);
+ CurIdx++;
+ while (NumAllocas--)
+ CurIdx = StackMaps::getNextMetaArgIdx(MI, CurIdx);
+ return CurIdx + 1; // skip <StackMaps::ConstantOp>
+}
+
+unsigned StatepointOpers::getNumAllocaIdx() {
+ // Take index of num of gc ptrs and skip all gc ptr records.
+ unsigned CurIdx = getNumGCPtrIdx();
+ unsigned NumGCPtrs = getConstMetaVal(*MI, CurIdx - 1);
+ CurIdx++;
+ while (NumGCPtrs--)
+ CurIdx = StackMaps::getNextMetaArgIdx(MI, CurIdx);
+ return CurIdx + 1; // skip <StackMaps::ConstantOp>
+}
+
+unsigned StatepointOpers::getNumGCPtrIdx() {
+ // Take index of num of deopt args and skip all deopt records.
+ unsigned CurIdx = getNumDeoptArgsIdx();
+ unsigned NumDeoptArgs = getConstMetaVal(*MI, CurIdx - 1);
+ CurIdx++;
+ while (NumDeoptArgs--) {
+ CurIdx = StackMaps::getNextMetaArgIdx(MI, CurIdx);
+ }
+ return CurIdx + 1; // skip <StackMaps::ConstantOp>
+}
+
+int StatepointOpers::getFirstGCPtrIdx() {
+ unsigned NumGCPtrsIdx = getNumGCPtrIdx();
+ unsigned NumGCPtrs = getConstMetaVal(*MI, NumGCPtrsIdx - 1);
+ if (NumGCPtrs == 0)
+ return -1;
+ ++NumGCPtrsIdx; // skip <num gc ptrs>
+ assert(NumGCPtrsIdx < MI->getNumOperands());
+ return (int)NumGCPtrsIdx;
+}
+
+unsigned StatepointOpers::getGCPointerMap(
+ SmallVectorImpl<std::pair<unsigned, unsigned>> &GCMap) {
+ unsigned CurIdx = getNumGcMapEntriesIdx();
+ unsigned GCMapSize = getConstMetaVal(*MI, CurIdx - 1);
+ CurIdx++;
+ for (unsigned N = 0; N < GCMapSize; ++N) {
+ unsigned B = MI->getOperand(CurIdx++).getImm();
+ unsigned D = MI->getOperand(CurIdx++).getImm();
+ GCMap.push_back(std::make_pair(B, D));
+ }
+
+ return GCMapSize;
+}
+
StackMaps::StackMaps(AsmPrinter &AP) : AP(AP) {
if (StackMapVersion != 3)
llvm_unreachable("Unsupported stackmap version!");
}
-unsigned StackMaps::getNextMetaArgIdx(const MachineInstr *MI, unsigned CurIdx) {
- assert(CurIdx < MI->getNumOperands() && "Bad meta arg index");
- const auto &MO = MI->getOperand(CurIdx);
- if (MO.isImm()) {
- switch (MO.getImm()) {
- default:
- llvm_unreachable("Unrecognized operand type.");
- case StackMaps::DirectMemRefOp:
- CurIdx += 2;
- break;
- case StackMaps::IndirectMemRefOp:
- CurIdx += 3;
- break;
- case StackMaps::ConstantOp:
- ++CurIdx;
- break;
- }
- }
- ++CurIdx;
- assert(CurIdx < MI->getNumOperands() && "points past operand list");
- return CurIdx;
-}
-
+unsigned StackMaps::getNextMetaArgIdx(const MachineInstr *MI, unsigned CurIdx) {
+ assert(CurIdx < MI->getNumOperands() && "Bad meta arg index");
+ const auto &MO = MI->getOperand(CurIdx);
+ if (MO.isImm()) {
+ switch (MO.getImm()) {
+ default:
+ llvm_unreachable("Unrecognized operand type.");
+ case StackMaps::DirectMemRefOp:
+ CurIdx += 2;
+ break;
+ case StackMaps::IndirectMemRefOp:
+ CurIdx += 3;
+ break;
+ case StackMaps::ConstantOp:
+ ++CurIdx;
+ break;
+ }
+ }
+ ++CurIdx;
+ assert(CurIdx < MI->getNumOperands() && "points past operand list");
+ return CurIdx;
+}
+
/// Go up the super-register chain until we hit a valid dwarf register number.
static unsigned getDwarfRegNum(unsigned Reg, const TargetRegisterInfo *TRI) {
int RegNum = TRI->getDwarfRegNum(Reg, false);
@@ -234,12 +234,12 @@ StackMaps::parseOperand(MachineInstr::const_mop_iterator MOI,
if (MOI->isImplicit())
return ++MOI;
- if (MOI->isUndef()) {
- // Record `undef` register as constant. Use same value as ISel uses.
- Locs.emplace_back(Location::Constant, sizeof(int64_t), 0, 0xFEFEFEFE);
- return ++MOI;
- }
-
+ if (MOI->isUndef()) {
+ // Record `undef` register as constant. Use same value as ISel uses.
+ Locs.emplace_back(Location::Constant, sizeof(int64_t), 0, 0xFEFEFEFE);
+ return ++MOI;
+ }
+
assert(Register::isPhysicalRegister(MOI->getReg()) &&
"Virtreg operands should have been rewritten before now.");
const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(MOI->getReg());
@@ -378,82 +378,82 @@ StackMaps::parseRegisterLiveOutMask(const uint32_t *Mask) const {
}
}
- llvm::erase_if(LiveOuts, [](const LiveOutReg &LO) { return LO.Reg == 0; });
+ llvm::erase_if(LiveOuts, [](const LiveOutReg &LO) { return LO.Reg == 0; });
return LiveOuts;
}
-// See statepoint MI format description in StatepointOpers' class comment
-// in include/llvm/CodeGen/StackMaps.h
-void StackMaps::parseStatepointOpers(const MachineInstr &MI,
- MachineInstr::const_mop_iterator MOI,
- MachineInstr::const_mop_iterator MOE,
- LocationVec &Locations,
- LiveOutVec &LiveOuts) {
- LLVM_DEBUG(dbgs() << "record statepoint : " << MI << "\n");
- StatepointOpers SO(&MI);
- MOI = parseOperand(MOI, MOE, Locations, LiveOuts); // CC
- MOI = parseOperand(MOI, MOE, Locations, LiveOuts); // Flags
- MOI = parseOperand(MOI, MOE, Locations, LiveOuts); // Num Deopts
-
- // Record Deopt Args.
- unsigned NumDeoptArgs = Locations.back().Offset;
- assert(Locations.back().Type == Location::Constant);
- assert(NumDeoptArgs == SO.getNumDeoptArgs());
-
- while (NumDeoptArgs--)
- MOI = parseOperand(MOI, MOE, Locations, LiveOuts);
-
- // Record gc base/derived pairs
- assert(MOI->isImm() && MOI->getImm() == StackMaps::ConstantOp);
- ++MOI;
- assert(MOI->isImm());
- unsigned NumGCPointers = MOI->getImm();
- ++MOI;
- if (NumGCPointers) {
- // Map logical index of GC ptr to MI operand index.
- SmallVector<unsigned, 8> GCPtrIndices;
- unsigned GCPtrIdx = (unsigned)SO.getFirstGCPtrIdx();
- assert((int)GCPtrIdx != -1);
- assert(MOI - MI.operands_begin() == GCPtrIdx + 0LL);
- while (NumGCPointers--) {
- GCPtrIndices.push_back(GCPtrIdx);
- GCPtrIdx = StackMaps::getNextMetaArgIdx(&MI, GCPtrIdx);
- }
-
- SmallVector<std::pair<unsigned, unsigned>, 8> GCPairs;
- unsigned NumGCPairs = SO.getGCPointerMap(GCPairs);
- (void)NumGCPairs;
- LLVM_DEBUG(dbgs() << "NumGCPairs = " << NumGCPairs << "\n");
-
- auto MOB = MI.operands_begin();
- for (auto &P : GCPairs) {
- assert(P.first < GCPtrIndices.size() && "base pointer index not found");
- assert(P.second < GCPtrIndices.size() &&
- "derived pointer index not found");
- unsigned BaseIdx = GCPtrIndices[P.first];
- unsigned DerivedIdx = GCPtrIndices[P.second];
- LLVM_DEBUG(dbgs() << "Base : " << BaseIdx << " Derived : " << DerivedIdx
- << "\n");
- (void)parseOperand(MOB + BaseIdx, MOE, Locations, LiveOuts);
- (void)parseOperand(MOB + DerivedIdx, MOE, Locations, LiveOuts);
- }
-
- MOI = MOB + GCPtrIdx;
- }
-
- // Record gc allocas
- assert(MOI < MOE);
- assert(MOI->isImm() && MOI->getImm() == StackMaps::ConstantOp);
- ++MOI;
- unsigned NumAllocas = MOI->getImm();
- ++MOI;
- while (NumAllocas--) {
- MOI = parseOperand(MOI, MOE, Locations, LiveOuts);
- assert(MOI < MOE);
- }
-}
-
+// See statepoint MI format description in StatepointOpers' class comment
+// in include/llvm/CodeGen/StackMaps.h
+void StackMaps::parseStatepointOpers(const MachineInstr &MI,
+ MachineInstr::const_mop_iterator MOI,
+ MachineInstr::const_mop_iterator MOE,
+ LocationVec &Locations,
+ LiveOutVec &LiveOuts) {
+ LLVM_DEBUG(dbgs() << "record statepoint : " << MI << "\n");
+ StatepointOpers SO(&MI);
+ MOI = parseOperand(MOI, MOE, Locations, LiveOuts); // CC
+ MOI = parseOperand(MOI, MOE, Locations, LiveOuts); // Flags
+ MOI = parseOperand(MOI, MOE, Locations, LiveOuts); // Num Deopts
+
+ // Record Deopt Args.
+ unsigned NumDeoptArgs = Locations.back().Offset;
+ assert(Locations.back().Type == Location::Constant);
+ assert(NumDeoptArgs == SO.getNumDeoptArgs());
+
+ while (NumDeoptArgs--)
+ MOI = parseOperand(MOI, MOE, Locations, LiveOuts);
+
+ // Record gc base/derived pairs
+ assert(MOI->isImm() && MOI->getImm() == StackMaps::ConstantOp);
+ ++MOI;
+ assert(MOI->isImm());
+ unsigned NumGCPointers = MOI->getImm();
+ ++MOI;
+ if (NumGCPointers) {
+ // Map logical index of GC ptr to MI operand index.
+ SmallVector<unsigned, 8> GCPtrIndices;
+ unsigned GCPtrIdx = (unsigned)SO.getFirstGCPtrIdx();
+ assert((int)GCPtrIdx != -1);
+ assert(MOI - MI.operands_begin() == GCPtrIdx + 0LL);
+ while (NumGCPointers--) {
+ GCPtrIndices.push_back(GCPtrIdx);
+ GCPtrIdx = StackMaps::getNextMetaArgIdx(&MI, GCPtrIdx);
+ }
+
+ SmallVector<std::pair<unsigned, unsigned>, 8> GCPairs;
+ unsigned NumGCPairs = SO.getGCPointerMap(GCPairs);
+ (void)NumGCPairs;
+ LLVM_DEBUG(dbgs() << "NumGCPairs = " << NumGCPairs << "\n");
+
+ auto MOB = MI.operands_begin();
+ for (auto &P : GCPairs) {
+ assert(P.first < GCPtrIndices.size() && "base pointer index not found");
+ assert(P.second < GCPtrIndices.size() &&
+ "derived pointer index not found");
+ unsigned BaseIdx = GCPtrIndices[P.first];
+ unsigned DerivedIdx = GCPtrIndices[P.second];
+ LLVM_DEBUG(dbgs() << "Base : " << BaseIdx << " Derived : " << DerivedIdx
+ << "\n");
+ (void)parseOperand(MOB + BaseIdx, MOE, Locations, LiveOuts);
+ (void)parseOperand(MOB + DerivedIdx, MOE, Locations, LiveOuts);
+ }
+
+ MOI = MOB + GCPtrIdx;
+ }
+
+ // Record gc allocas
+ assert(MOI < MOE);
+ assert(MOI->isImm() && MOI->getImm() == StackMaps::ConstantOp);
+ ++MOI;
+ unsigned NumAllocas = MOI->getImm();
+ ++MOI;
+ while (NumAllocas--) {
+ MOI = parseOperand(MOI, MOE, Locations, LiveOuts);
+ assert(MOI < MOE);
+ }
+}
+
void StackMaps::recordStackMapOpers(const MCSymbol &MILabel,
const MachineInstr &MI, uint64_t ID,
MachineInstr::const_mop_iterator MOI,
@@ -471,11 +471,11 @@ void StackMaps::recordStackMapOpers(const MCSymbol &MILabel,
}
// Parse operands.
- if (MI.getOpcode() == TargetOpcode::STATEPOINT)
- parseStatepointOpers(MI, MOI, MOE, Locations, LiveOuts);
- else
- while (MOI != MOE)
- MOI = parseOperand(MOI, MOE, Locations, LiveOuts);
+ if (MI.getOpcode() == TargetOpcode::STATEPOINT)
+ parseStatepointOpers(MI, MOI, MOE, Locations, LiveOuts);
+ else
+ while (MOI != MOE)
+ MOI = parseOperand(MOI, MOE, Locations, LiveOuts);
// Move large constants into the constant pool.
for (auto &Loc : Locations) {
@@ -564,7 +564,7 @@ void StackMaps::recordStatepoint(const MCSymbol &L, const MachineInstr &MI) {
/// Emit the stackmap header.
///
/// Header {
-/// uint8 : Stack Map Version (currently 3)
+/// uint8 : Stack Map Version (currently 3)
/// uint8 : Reserved (expected to be 0)
/// uint16 : Reserved (expected to be 0)
/// }
diff --git a/contrib/libs/llvm12/lib/CodeGen/StackProtector.cpp b/contrib/libs/llvm12/lib/CodeGen/StackProtector.cpp
index f12009af93..10c6dcbdb0 100644
--- a/contrib/libs/llvm12/lib/CodeGen/StackProtector.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/StackProtector.cpp
@@ -170,8 +170,8 @@ bool StackProtector::HasAddressTaken(const Instruction *AI,
// If this instruction accesses memory make sure it doesn't access beyond
// the bounds of the allocated object.
Optional<MemoryLocation> MemLoc = MemoryLocation::getOrNone(I);
- if (MemLoc.hasValue() && MemLoc->Size.hasValue() &&
- MemLoc->Size.getValue() > AllocSize)
+ if (MemLoc.hasValue() && MemLoc->Size.hasValue() &&
+ MemLoc->Size.getValue() > AllocSize)
return true;
switch (I->getOpcode()) {
case Instruction::Store:
@@ -192,7 +192,7 @@ bool StackProtector::HasAddressTaken(const Instruction *AI,
// Ignore intrinsics that do not become real instructions.
// TODO: Narrow this to intrinsics that have store-like effects.
const auto *CI = cast<CallInst>(I);
- if (!CI->isDebugOrPseudoInst() && !CI->isLifetimeStartOrEnd())
+ if (!CI->isDebugOrPseudoInst() && !CI->isLifetimeStartOrEnd())
return true;
break;
}
@@ -252,9 +252,9 @@ bool StackProtector::HasAddressTaken(const Instruction *AI,
static const CallInst *findStackProtectorIntrinsic(Function &F) {
for (const BasicBlock &BB : F)
for (const Instruction &I : BB)
- if (const auto *II = dyn_cast<IntrinsicInst>(&I))
- if (II->getIntrinsicID() == Intrinsic::stackprotector)
- return II;
+ if (const auto *II = dyn_cast<IntrinsicInst>(&I))
+ if (II->getIntrinsicID() == Intrinsic::stackprotector)
+ return II;
return nullptr;
}
@@ -378,10 +378,10 @@ bool StackProtector::RequiresStackProtector() {
static Value *getStackGuard(const TargetLoweringBase *TLI, Module *M,
IRBuilder<> &B,
bool *SupportsSelectionDAGSP = nullptr) {
- Value *Guard = TLI->getIRStackGuard(B);
- auto GuardMode = TLI->getTargetMachine().Options.StackProtectorGuard;
- if ((GuardMode == llvm::StackProtectorGuards::TLS ||
- GuardMode == llvm::StackProtectorGuards::None) && Guard)
+ Value *Guard = TLI->getIRStackGuard(B);
+ auto GuardMode = TLI->getTargetMachine().Options.StackProtectorGuard;
+ if ((GuardMode == llvm::StackProtectorGuards::TLS ||
+ GuardMode == llvm::StackProtectorGuards::None) && Guard)
return B.CreateLoad(B.getInt8PtrTy(), Guard, true, "StackGuard");
// Use SelectionDAG SSP handling, since there isn't an IR guard.
@@ -470,36 +470,36 @@ bool StackProtector::InsertStackProtectors() {
// instrumentation has already been generated.
HasIRCheck = true;
- // If we're instrumenting a block with a musttail call, the check has to be
- // inserted before the call rather than between it and the return. The
- // verifier guarantees that a musttail call is either directly before the
- // return or with a single correct bitcast of the return value in between so
- // we don't need to worry about many situations here.
- Instruction *CheckLoc = RI;
- Instruction *Prev = RI->getPrevNonDebugInstruction();
- if (Prev && isa<CallInst>(Prev) && cast<CallInst>(Prev)->isMustTailCall())
- CheckLoc = Prev;
- else if (Prev) {
- Prev = Prev->getPrevNonDebugInstruction();
- if (Prev && isa<CallInst>(Prev) && cast<CallInst>(Prev)->isMustTailCall())
- CheckLoc = Prev;
- }
-
+ // If we're instrumenting a block with a musttail call, the check has to be
+ // inserted before the call rather than between it and the return. The
+ // verifier guarantees that a musttail call is either directly before the
+ // return or with a single correct bitcast of the return value in between so
+ // we don't need to worry about many situations here.
+ Instruction *CheckLoc = RI;
+ Instruction *Prev = RI->getPrevNonDebugInstruction();
+ if (Prev && isa<CallInst>(Prev) && cast<CallInst>(Prev)->isMustTailCall())
+ CheckLoc = Prev;
+ else if (Prev) {
+ Prev = Prev->getPrevNonDebugInstruction();
+ if (Prev && isa<CallInst>(Prev) && cast<CallInst>(Prev)->isMustTailCall())
+ CheckLoc = Prev;
+ }
+
// Generate epilogue instrumentation. The epilogue intrumentation can be
// function-based or inlined depending on which mechanism the target is
// providing.
if (Function *GuardCheck = TLI->getSSPStackGuardCheck(*M)) {
// Generate the function-based epilogue instrumentation.
// The target provides a guard check function, generate a call to it.
- IRBuilder<> B(CheckLoc);
+ IRBuilder<> B(CheckLoc);
LoadInst *Guard = B.CreateLoad(B.getInt8PtrTy(), AI, true, "Guard");
CallInst *Call = B.CreateCall(GuardCheck, {Guard});
Call->setAttributes(GuardCheck->getAttributes());
Call->setCallingConv(GuardCheck->getCallingConv());
} else {
// Generate the epilogue with inline instrumentation.
- // If we do not support SelectionDAG based calls, generate IR level
- // calls.
+ // If we do not support SelectionDAG based calls, generate IR level
+ // calls.
//
// For each block with a return instruction, convert this:
//
@@ -529,8 +529,8 @@ bool StackProtector::InsertStackProtectors() {
BasicBlock *FailBB = CreateFailBB();
// Split the basic block before the return instruction.
- BasicBlock *NewBB =
- BB->splitBasicBlock(CheckLoc->getIterator(), "SP_return");
+ BasicBlock *NewBB =
+ BB->splitBasicBlock(CheckLoc->getIterator(), "SP_return");
// Update the dominator tree if we need to.
if (DT && DT->isReachableFromEntry(BB)) {
@@ -572,9 +572,9 @@ BasicBlock *StackProtector::CreateFailBB() {
LLVMContext &Context = F->getContext();
BasicBlock *FailBB = BasicBlock::Create(Context, "CallStackCheckFailBlk", F);
IRBuilder<> B(FailBB);
- if (F->getSubprogram())
- B.SetCurrentDebugLocation(
- DILocation::get(Context, 0, 0, F->getSubprogram()));
+ if (F->getSubprogram())
+ B.SetCurrentDebugLocation(
+ DILocation::get(Context, 0, 0, F->getSubprogram()));
if (Trip.isOSOpenBSD()) {
FunctionCallee StackChkFail = M->getOrInsertFunction(
"__stack_smash_handler", Type::getVoidTy(Context),
diff --git a/contrib/libs/llvm12/lib/CodeGen/StackSlotColoring.cpp b/contrib/libs/llvm12/lib/CodeGen/StackSlotColoring.cpp
index a6f675ecbf..a6f8974f33 100644
--- a/contrib/libs/llvm12/lib/CodeGen/StackSlotColoring.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/StackSlotColoring.cpp
@@ -145,7 +145,7 @@ namespace {
// their weight.
struct IntervalSorter {
bool operator()(LiveInterval* LHS, LiveInterval* RHS) const {
- return LHS->weight() > RHS->weight();
+ return LHS->weight() > RHS->weight();
}
};
@@ -174,8 +174,8 @@ void StackSlotColoring::ScanForSpillSlotRefs(MachineFunction &MF) {
continue;
LiveInterval &li = LS->getInterval(FI);
if (!MI.isDebugValue())
- li.incrementWeight(
- LiveIntervals::getSpillWeight(false, true, MBFI, MI));
+ li.incrementWeight(
+ LiveIntervals::getSpillWeight(false, true, MBFI, MI));
}
for (MachineInstr::mmo_iterator MMOI = MI.memoperands_begin(),
EE = MI.memoperands_end();
@@ -223,7 +223,7 @@ void StackSlotColoring::InitializeSlots() {
for (auto *I : Intervals) {
LiveInterval &li = I->second;
LLVM_DEBUG(li.dump());
- int FI = Register::stackSlot2Index(li.reg());
+ int FI = Register::stackSlot2Index(li.reg());
if (MFI->isDeadObjectIndex(FI))
continue;
@@ -270,7 +270,7 @@ StackSlotColoring::OverlapWithAssignments(LiveInterval *li, int Color) const {
int StackSlotColoring::ColorSlot(LiveInterval *li) {
int Color = -1;
bool Share = false;
- int FI = Register::stackSlot2Index(li->reg());
+ int FI = Register::stackSlot2Index(li->reg());
uint8_t StackID = MFI->getStackID(FI);
if (!DisableSharing) {
@@ -332,12 +332,12 @@ bool StackSlotColoring::ColorSlots(MachineFunction &MF) {
bool Changed = false;
for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
LiveInterval *li = SSIntervals[i];
- int SS = Register::stackSlot2Index(li->reg());
+ int SS = Register::stackSlot2Index(li->reg());
int NewSS = ColorSlot(li);
assert(NewSS >= 0 && "Stack coloring failed?");
SlotMapping[SS] = NewSS;
RevMap[NewSS].push_back(SS);
- SlotWeights[NewSS] += li->weight();
+ SlotWeights[NewSS] += li->weight();
UsedColors.set(NewSS);
Changed |= (SS != NewSS);
}
@@ -345,8 +345,8 @@ bool StackSlotColoring::ColorSlots(MachineFunction &MF) {
LLVM_DEBUG(dbgs() << "\nSpill slots after coloring:\n");
for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
LiveInterval *li = SSIntervals[i];
- int SS = Register::stackSlot2Index(li->reg());
- li->setWeight(SlotWeights[SS]);
+ int SS = Register::stackSlot2Index(li->reg());
+ li->setWeight(SlotWeights[SS]);
}
// Sort them by new weight.
llvm::stable_sort(SSIntervals, IntervalSorter());
diff --git a/contrib/libs/llvm12/lib/CodeGen/SwiftErrorValueTracking.cpp b/contrib/libs/llvm12/lib/CodeGen/SwiftErrorValueTracking.cpp
index 762cb1e36d..4408011c95 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SwiftErrorValueTracking.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SwiftErrorValueTracking.cpp
@@ -202,8 +202,8 @@ void SwiftErrorValueTracking::propagateVRegs() {
// downward defs.
bool needPHI =
VRegs.size() >= 1 &&
- llvm::find_if(
- VRegs,
+ llvm::find_if(
+ VRegs,
[&](const std::pair<const MachineBasicBlock *, Register> &V)
-> bool { return V.second != VRegs[0].second; }) !=
VRegs.end();
diff --git a/contrib/libs/llvm12/lib/CodeGen/SwitchLoweringUtils.cpp b/contrib/libs/llvm12/lib/CodeGen/SwitchLoweringUtils.cpp
index 2958978cb6..dfcec32d95 100644
--- a/contrib/libs/llvm12/lib/CodeGen/SwitchLoweringUtils.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/SwitchLoweringUtils.cpp
@@ -11,10 +11,10 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/CodeGen/SwitchLoweringUtils.h"
-#include "llvm/CodeGen/FunctionLoweringInfo.h"
+#include "llvm/CodeGen/SwitchLoweringUtils.h"
+#include "llvm/CodeGen/FunctionLoweringInfo.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
-#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
diff --git a/contrib/libs/llvm12/lib/CodeGen/TailDuplicator.cpp b/contrib/libs/llvm12/lib/CodeGen/TailDuplicator.cpp
index 6ff9617293..575bf555c4 100644
--- a/contrib/libs/llvm12/lib/CodeGen/TailDuplicator.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/TailDuplicator.cpp
@@ -720,7 +720,7 @@ bool TailDuplicator::duplicateSimpleBB(
SmallVectorImpl<MachineInstr *> &Copies) {
SmallPtrSet<MachineBasicBlock *, 8> Succs(TailBB->succ_begin(),
TailBB->succ_end());
- SmallVector<MachineBasicBlock *, 8> Preds(TailBB->predecessors());
+ SmallVector<MachineBasicBlock *, 8> Preds(TailBB->predecessors());
bool Changed = false;
for (MachineBasicBlock *PredBB : Preds) {
if (PredBB->hasEHPadSuccessor() || PredBB->mayHaveInlineAsmBr())
diff --git a/contrib/libs/llvm12/lib/CodeGen/TargetFrameLoweringImpl.cpp b/contrib/libs/llvm12/lib/CodeGen/TargetFrameLoweringImpl.cpp
index 5dc9749090..b0594ec086 100644
--- a/contrib/libs/llvm12/lib/CodeGen/TargetFrameLoweringImpl.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/TargetFrameLoweringImpl.cpp
@@ -41,9 +41,9 @@ bool TargetFrameLowering::enableCalleeSaveSkip(const MachineFunction &MF) const
/// frame of the specified index, along with the frame register used
/// (in output arg FrameReg). This is the default implementation which
/// is overridden for some targets.
-StackOffset
-TargetFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
- Register &FrameReg) const {
+StackOffset
+TargetFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
+ Register &FrameReg) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo();
@@ -52,9 +52,9 @@ TargetFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
// something different.
FrameReg = RI->getFrameRegister(MF);
- return StackOffset::getFixed(MFI.getObjectOffset(FI) + MFI.getStackSize() -
- getOffsetOfLocalArea() +
- MFI.getOffsetAdjustment());
+ return StackOffset::getFixed(MFI.getObjectOffset(FI) + MFI.getStackSize() -
+ getOffsetOfLocalArea() +
+ MFI.getOffsetAdjustment());
}
bool TargetFrameLowering::needsFrameIndexResolution(
diff --git a/contrib/libs/llvm12/lib/CodeGen/TargetInstrInfo.cpp b/contrib/libs/llvm12/lib/CodeGen/TargetInstrInfo.cpp
index ab3aadc2ae..165860ef1a 100644
--- a/contrib/libs/llvm12/lib/CodeGen/TargetInstrInfo.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/TargetInstrInfo.cpp
@@ -69,15 +69,15 @@ void TargetInstrInfo::insertNoop(MachineBasicBlock &MBB,
llvm_unreachable("Target didn't implement insertNoop!");
}
-/// insertNoops - Insert noops into the instruction stream at the specified
-/// point.
-void TargetInstrInfo::insertNoops(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI,
- unsigned Quantity) const {
- for (unsigned i = 0; i < Quantity; ++i)
- insertNoop(MBB, MI);
-}
-
+/// insertNoops - Insert noops into the instruction stream at the specified
+/// point.
+void TargetInstrInfo::insertNoops(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ unsigned Quantity) const {
+ for (unsigned i = 0; i < Quantity; ++i)
+ insertNoop(MBB, MI);
+}
+
static bool isAsmComment(const char *Str, const MCAsmInfo &MAI) {
return strncmp(Str, MAI.getCommentString().data(),
MAI.getCommentString().size()) == 0;
@@ -480,7 +480,7 @@ static MachineInstr *foldPatchpoint(MachineFunction &MF, MachineInstr &MI,
ArrayRef<unsigned> Ops, int FrameIndex,
const TargetInstrInfo &TII) {
unsigned StartIdx = 0;
- unsigned NumDefs = 0;
+ unsigned NumDefs = 0;
switch (MI.getOpcode()) {
case TargetOpcode::STACKMAP: {
// StackMapLiveValues are foldable
@@ -496,26 +496,26 @@ static MachineInstr *foldPatchpoint(MachineFunction &MF, MachineInstr &MI,
case TargetOpcode::STATEPOINT: {
// For statepoints, fold deopt and gc arguments, but not call arguments.
StartIdx = StatepointOpers(&MI).getVarIdx();
- NumDefs = MI.getNumDefs();
+ NumDefs = MI.getNumDefs();
break;
}
default:
llvm_unreachable("unexpected stackmap opcode");
}
- unsigned DefToFoldIdx = MI.getNumOperands();
-
+ unsigned DefToFoldIdx = MI.getNumOperands();
+
// Return false if any operands requested for folding are not foldable (not
// part of the stackmap's live values).
for (unsigned Op : Ops) {
- if (Op < NumDefs) {
- assert(DefToFoldIdx == MI.getNumOperands() && "Folding multiple defs");
- DefToFoldIdx = Op;
- } else if (Op < StartIdx) {
+ if (Op < NumDefs) {
+ assert(DefToFoldIdx == MI.getNumOperands() && "Folding multiple defs");
+ DefToFoldIdx = Op;
+ } else if (Op < StartIdx) {
+ return nullptr;
+ }
+ if (MI.getOperand(Op).isTied())
return nullptr;
- }
- if (MI.getOperand(Op).isTied())
- return nullptr;
}
MachineInstr *NewMI =
@@ -524,16 +524,16 @@ static MachineInstr *foldPatchpoint(MachineFunction &MF, MachineInstr &MI,
// No need to fold return, the meta data, and function arguments
for (unsigned i = 0; i < StartIdx; ++i)
- if (i != DefToFoldIdx)
- MIB.add(MI.getOperand(i));
+ if (i != DefToFoldIdx)
+ MIB.add(MI.getOperand(i));
- for (unsigned i = StartIdx, e = MI.getNumOperands(); i < e; ++i) {
+ for (unsigned i = StartIdx, e = MI.getNumOperands(); i < e; ++i) {
MachineOperand &MO = MI.getOperand(i);
- unsigned TiedTo = e;
- (void)MI.isRegTiedToDefOperand(i, &TiedTo);
-
+ unsigned TiedTo = e;
+ (void)MI.isRegTiedToDefOperand(i, &TiedTo);
+
if (is_contained(Ops, i)) {
- assert(TiedTo == e && "Cannot fold tied operands");
+ assert(TiedTo == e && "Cannot fold tied operands");
unsigned SpillSize;
unsigned SpillOffset;
// Compute the spill slot size and offset.
@@ -547,14 +547,14 @@ static MachineInstr *foldPatchpoint(MachineFunction &MF, MachineInstr &MI,
MIB.addImm(SpillSize);
MIB.addFrameIndex(FrameIndex);
MIB.addImm(SpillOffset);
- } else {
- MIB.add(MO);
- if (TiedTo < e) {
- assert(TiedTo < NumDefs && "Bad tied operand");
- if (TiedTo > DefToFoldIdx)
- --TiedTo;
- NewMI->tieOperands(TiedTo, NewMI->getNumOperands() - 1);
- }
+ } else {
+ MIB.add(MO);
+ if (TiedTo < e) {
+ assert(TiedTo < NumDefs && "Bad tied operand");
+ if (TiedTo > DefToFoldIdx)
+ --TiedTo;
+ NewMI->tieOperands(TiedTo, NewMI->getNumOperands() - 1);
+ }
}
}
return NewMI;
@@ -778,8 +778,8 @@ bool TargetInstrInfo::isReassociationCandidate(const MachineInstr &Inst,
// instruction is known to not increase the critical path, then don't match
// that pattern.
bool TargetInstrInfo::getMachineCombinerPatterns(
- MachineInstr &Root, SmallVectorImpl<MachineCombinerPattern> &Patterns,
- bool DoRegPressureReduce) const {
+ MachineInstr &Root, SmallVectorImpl<MachineCombinerPattern> &Patterns,
+ bool DoRegPressureReduce) const {
bool Commute;
if (isReassociationCandidate(Root, Commute)) {
// We found a sequence of instructions that may be suitable for a
diff --git a/contrib/libs/llvm12/lib/CodeGen/TargetLoweringBase.cpp b/contrib/libs/llvm12/lib/CodeGen/TargetLoweringBase.cpp
index 173069d36b..28c8bd0a7d 100644
--- a/contrib/libs/llvm12/lib/CodeGen/TargetLoweringBase.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/TargetLoweringBase.cpp
@@ -135,28 +135,28 @@ void TargetLoweringBase::InitLibcalls(const Triple &TT) {
setLibcallCallingConv((RTLIB::Libcall)LC, CallingConv::C);
// For IEEE quad-precision libcall names, PPC uses "kf" instead of "tf".
- if (TT.isPPC()) {
+ if (TT.isPPC()) {
setLibcallName(RTLIB::ADD_F128, "__addkf3");
setLibcallName(RTLIB::SUB_F128, "__subkf3");
setLibcallName(RTLIB::MUL_F128, "__mulkf3");
setLibcallName(RTLIB::DIV_F128, "__divkf3");
- setLibcallName(RTLIB::POWI_F128, "__powikf2");
+ setLibcallName(RTLIB::POWI_F128, "__powikf2");
setLibcallName(RTLIB::FPEXT_F32_F128, "__extendsfkf2");
setLibcallName(RTLIB::FPEXT_F64_F128, "__extenddfkf2");
setLibcallName(RTLIB::FPROUND_F128_F32, "__trunckfsf2");
setLibcallName(RTLIB::FPROUND_F128_F64, "__trunckfdf2");
setLibcallName(RTLIB::FPTOSINT_F128_I32, "__fixkfsi");
setLibcallName(RTLIB::FPTOSINT_F128_I64, "__fixkfdi");
- setLibcallName(RTLIB::FPTOSINT_F128_I128, "__fixkfti");
+ setLibcallName(RTLIB::FPTOSINT_F128_I128, "__fixkfti");
setLibcallName(RTLIB::FPTOUINT_F128_I32, "__fixunskfsi");
setLibcallName(RTLIB::FPTOUINT_F128_I64, "__fixunskfdi");
- setLibcallName(RTLIB::FPTOUINT_F128_I128, "__fixunskfti");
+ setLibcallName(RTLIB::FPTOUINT_F128_I128, "__fixunskfti");
setLibcallName(RTLIB::SINTTOFP_I32_F128, "__floatsikf");
setLibcallName(RTLIB::SINTTOFP_I64_F128, "__floatdikf");
- setLibcallName(RTLIB::SINTTOFP_I128_F128, "__floattikf");
+ setLibcallName(RTLIB::SINTTOFP_I128_F128, "__floattikf");
setLibcallName(RTLIB::UINTTOFP_I32_F128, "__floatunsikf");
setLibcallName(RTLIB::UINTTOFP_I64_F128, "__floatundikf");
- setLibcallName(RTLIB::UINTTOFP_I128_F128, "__floatuntikf");
+ setLibcallName(RTLIB::UINTTOFP_I128_F128, "__floatuntikf");
setLibcallName(RTLIB::OEQ_F128, "__eqkf2");
setLibcallName(RTLIB::UNE_F128, "__nekf2");
setLibcallName(RTLIB::OGE_F128, "__gekf2");
@@ -229,10 +229,10 @@ RTLIB::Libcall RTLIB::getFPEXT(EVT OpVT, EVT RetVT) {
if (OpVT == MVT::f16) {
if (RetVT == MVT::f32)
return FPEXT_F16_F32;
- if (RetVT == MVT::f64)
- return FPEXT_F16_F64;
- if (RetVT == MVT::f128)
- return FPEXT_F16_F128;
+ if (RetVT == MVT::f64)
+ return FPEXT_F16_F64;
+ if (RetVT == MVT::f128)
+ return FPEXT_F16_F128;
} else if (OpVT == MVT::f32) {
if (RetVT == MVT::f64)
return FPEXT_F32_F64;
@@ -294,15 +294,15 @@ RTLIB::Libcall RTLIB::getFPROUND(EVT OpVT, EVT RetVT) {
/// getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or
/// UNKNOWN_LIBCALL if there is none.
RTLIB::Libcall RTLIB::getFPTOSINT(EVT OpVT, EVT RetVT) {
- if (OpVT == MVT::f16) {
+ if (OpVT == MVT::f16) {
+ if (RetVT == MVT::i32)
+ return FPTOSINT_F16_I32;
+ if (RetVT == MVT::i64)
+ return FPTOSINT_F16_I64;
+ if (RetVT == MVT::i128)
+ return FPTOSINT_F16_I128;
+ } else if (OpVT == MVT::f32) {
if (RetVT == MVT::i32)
- return FPTOSINT_F16_I32;
- if (RetVT == MVT::i64)
- return FPTOSINT_F16_I64;
- if (RetVT == MVT::i128)
- return FPTOSINT_F16_I128;
- } else if (OpVT == MVT::f32) {
- if (RetVT == MVT::i32)
return FPTOSINT_F32_I32;
if (RetVT == MVT::i64)
return FPTOSINT_F32_I64;
@@ -343,15 +343,15 @@ RTLIB::Libcall RTLIB::getFPTOSINT(EVT OpVT, EVT RetVT) {
/// getFPTOUINT - Return the FPTOUINT_*_* value for the given types, or
/// UNKNOWN_LIBCALL if there is none.
RTLIB::Libcall RTLIB::getFPTOUINT(EVT OpVT, EVT RetVT) {
- if (OpVT == MVT::f16) {
+ if (OpVT == MVT::f16) {
+ if (RetVT == MVT::i32)
+ return FPTOUINT_F16_I32;
+ if (RetVT == MVT::i64)
+ return FPTOUINT_F16_I64;
+ if (RetVT == MVT::i128)
+ return FPTOUINT_F16_I128;
+ } else if (OpVT == MVT::f32) {
if (RetVT == MVT::i32)
- return FPTOUINT_F16_I32;
- if (RetVT == MVT::i64)
- return FPTOUINT_F16_I64;
- if (RetVT == MVT::i128)
- return FPTOUINT_F16_I128;
- } else if (OpVT == MVT::f32) {
- if (RetVT == MVT::i32)
return FPTOUINT_F32_I32;
if (RetVT == MVT::i64)
return FPTOUINT_F32_I64;
@@ -393,8 +393,8 @@ RTLIB::Libcall RTLIB::getFPTOUINT(EVT OpVT, EVT RetVT) {
/// UNKNOWN_LIBCALL if there is none.
RTLIB::Libcall RTLIB::getSINTTOFP(EVT OpVT, EVT RetVT) {
if (OpVT == MVT::i32) {
- if (RetVT == MVT::f16)
- return SINTTOFP_I32_F16;
+ if (RetVT == MVT::f16)
+ return SINTTOFP_I32_F16;
if (RetVT == MVT::f32)
return SINTTOFP_I32_F32;
if (RetVT == MVT::f64)
@@ -406,8 +406,8 @@ RTLIB::Libcall RTLIB::getSINTTOFP(EVT OpVT, EVT RetVT) {
if (RetVT == MVT::ppcf128)
return SINTTOFP_I32_PPCF128;
} else if (OpVT == MVT::i64) {
- if (RetVT == MVT::f16)
- return SINTTOFP_I64_F16;
+ if (RetVT == MVT::f16)
+ return SINTTOFP_I64_F16;
if (RetVT == MVT::f32)
return SINTTOFP_I64_F32;
if (RetVT == MVT::f64)
@@ -419,8 +419,8 @@ RTLIB::Libcall RTLIB::getSINTTOFP(EVT OpVT, EVT RetVT) {
if (RetVT == MVT::ppcf128)
return SINTTOFP_I64_PPCF128;
} else if (OpVT == MVT::i128) {
- if (RetVT == MVT::f16)
- return SINTTOFP_I128_F16;
+ if (RetVT == MVT::f16)
+ return SINTTOFP_I128_F16;
if (RetVT == MVT::f32)
return SINTTOFP_I128_F32;
if (RetVT == MVT::f64)
@@ -439,8 +439,8 @@ RTLIB::Libcall RTLIB::getSINTTOFP(EVT OpVT, EVT RetVT) {
/// UNKNOWN_LIBCALL if there is none.
RTLIB::Libcall RTLIB::getUINTTOFP(EVT OpVT, EVT RetVT) {
if (OpVT == MVT::i32) {
- if (RetVT == MVT::f16)
- return UINTTOFP_I32_F16;
+ if (RetVT == MVT::f16)
+ return UINTTOFP_I32_F16;
if (RetVT == MVT::f32)
return UINTTOFP_I32_F32;
if (RetVT == MVT::f64)
@@ -452,8 +452,8 @@ RTLIB::Libcall RTLIB::getUINTTOFP(EVT OpVT, EVT RetVT) {
if (RetVT == MVT::ppcf128)
return UINTTOFP_I32_PPCF128;
} else if (OpVT == MVT::i64) {
- if (RetVT == MVT::f16)
- return UINTTOFP_I64_F16;
+ if (RetVT == MVT::f16)
+ return UINTTOFP_I64_F16;
if (RetVT == MVT::f32)
return UINTTOFP_I64_F32;
if (RetVT == MVT::f64)
@@ -465,8 +465,8 @@ RTLIB::Libcall RTLIB::getUINTTOFP(EVT OpVT, EVT RetVT) {
if (RetVT == MVT::ppcf128)
return UINTTOFP_I64_PPCF128;
} else if (OpVT == MVT::i128) {
- if (RetVT == MVT::f16)
- return UINTTOFP_I128_F16;
+ if (RetVT == MVT::f16)
+ return UINTTOFP_I128_F16;
if (RetVT == MVT::f32)
return UINTTOFP_I128_F32;
if (RetVT == MVT::f64)
@@ -481,83 +481,83 @@ RTLIB::Libcall RTLIB::getUINTTOFP(EVT OpVT, EVT RetVT) {
return UNKNOWN_LIBCALL;
}
-RTLIB::Libcall RTLIB::getOUTLINE_ATOMIC(unsigned Opc, AtomicOrdering Order,
- MVT VT) {
- unsigned ModeN, ModelN;
- switch (VT.SimpleTy) {
- case MVT::i8:
- ModeN = 0;
- break;
- case MVT::i16:
- ModeN = 1;
- break;
- case MVT::i32:
- ModeN = 2;
- break;
- case MVT::i64:
- ModeN = 3;
- break;
- case MVT::i128:
- ModeN = 4;
- break;
- default:
- return UNKNOWN_LIBCALL;
- }
-
- switch (Order) {
- case AtomicOrdering::Monotonic:
- ModelN = 0;
- break;
- case AtomicOrdering::Acquire:
- ModelN = 1;
- break;
- case AtomicOrdering::Release:
- ModelN = 2;
- break;
- case AtomicOrdering::AcquireRelease:
- case AtomicOrdering::SequentiallyConsistent:
- ModelN = 3;
- break;
- default:
- return UNKNOWN_LIBCALL;
- }
-
-#define LCALLS(A, B) \
- { A##B##_RELAX, A##B##_ACQ, A##B##_REL, A##B##_ACQ_REL }
-#define LCALL5(A) \
- LCALLS(A, 1), LCALLS(A, 2), LCALLS(A, 4), LCALLS(A, 8), LCALLS(A, 16)
- switch (Opc) {
- case ISD::ATOMIC_CMP_SWAP: {
- const Libcall LC[5][4] = {LCALL5(OUTLINE_ATOMIC_CAS)};
- return LC[ModeN][ModelN];
- }
- case ISD::ATOMIC_SWAP: {
- const Libcall LC[5][4] = {LCALL5(OUTLINE_ATOMIC_SWP)};
- return LC[ModeN][ModelN];
- }
- case ISD::ATOMIC_LOAD_ADD: {
- const Libcall LC[5][4] = {LCALL5(OUTLINE_ATOMIC_LDADD)};
- return LC[ModeN][ModelN];
- }
- case ISD::ATOMIC_LOAD_OR: {
- const Libcall LC[5][4] = {LCALL5(OUTLINE_ATOMIC_LDSET)};
- return LC[ModeN][ModelN];
- }
- case ISD::ATOMIC_LOAD_CLR: {
- const Libcall LC[5][4] = {LCALL5(OUTLINE_ATOMIC_LDCLR)};
- return LC[ModeN][ModelN];
- }
- case ISD::ATOMIC_LOAD_XOR: {
- const Libcall LC[5][4] = {LCALL5(OUTLINE_ATOMIC_LDEOR)};
- return LC[ModeN][ModelN];
- }
- default:
- return UNKNOWN_LIBCALL;
- }
-#undef LCALLS
-#undef LCALL5
-}
-
+RTLIB::Libcall RTLIB::getOUTLINE_ATOMIC(unsigned Opc, AtomicOrdering Order,
+ MVT VT) {
+ unsigned ModeN, ModelN;
+ switch (VT.SimpleTy) {
+ case MVT::i8:
+ ModeN = 0;
+ break;
+ case MVT::i16:
+ ModeN = 1;
+ break;
+ case MVT::i32:
+ ModeN = 2;
+ break;
+ case MVT::i64:
+ ModeN = 3;
+ break;
+ case MVT::i128:
+ ModeN = 4;
+ break;
+ default:
+ return UNKNOWN_LIBCALL;
+ }
+
+ switch (Order) {
+ case AtomicOrdering::Monotonic:
+ ModelN = 0;
+ break;
+ case AtomicOrdering::Acquire:
+ ModelN = 1;
+ break;
+ case AtomicOrdering::Release:
+ ModelN = 2;
+ break;
+ case AtomicOrdering::AcquireRelease:
+ case AtomicOrdering::SequentiallyConsistent:
+ ModelN = 3;
+ break;
+ default:
+ return UNKNOWN_LIBCALL;
+ }
+
+#define LCALLS(A, B) \
+ { A##B##_RELAX, A##B##_ACQ, A##B##_REL, A##B##_ACQ_REL }
+#define LCALL5(A) \
+ LCALLS(A, 1), LCALLS(A, 2), LCALLS(A, 4), LCALLS(A, 8), LCALLS(A, 16)
+ switch (Opc) {
+ case ISD::ATOMIC_CMP_SWAP: {
+ const Libcall LC[5][4] = {LCALL5(OUTLINE_ATOMIC_CAS)};
+ return LC[ModeN][ModelN];
+ }
+ case ISD::ATOMIC_SWAP: {
+ const Libcall LC[5][4] = {LCALL5(OUTLINE_ATOMIC_SWP)};
+ return LC[ModeN][ModelN];
+ }
+ case ISD::ATOMIC_LOAD_ADD: {
+ const Libcall LC[5][4] = {LCALL5(OUTLINE_ATOMIC_LDADD)};
+ return LC[ModeN][ModelN];
+ }
+ case ISD::ATOMIC_LOAD_OR: {
+ const Libcall LC[5][4] = {LCALL5(OUTLINE_ATOMIC_LDSET)};
+ return LC[ModeN][ModelN];
+ }
+ case ISD::ATOMIC_LOAD_CLR: {
+ const Libcall LC[5][4] = {LCALL5(OUTLINE_ATOMIC_LDCLR)};
+ return LC[ModeN][ModelN];
+ }
+ case ISD::ATOMIC_LOAD_XOR: {
+ const Libcall LC[5][4] = {LCALL5(OUTLINE_ATOMIC_LDEOR)};
+ return LC[ModeN][ModelN];
+ }
+ default:
+ return UNKNOWN_LIBCALL;
+ }
+#undef LCALLS
+#undef LCALL5
+}
+
RTLIB::Libcall RTLIB::getSYNC(unsigned Opc, MVT VT) {
#define OP_TO_LIBCALL(Name, Enum) \
case Name: \
@@ -727,7 +727,7 @@ void TargetLoweringBase::initActions() {
std::end(TargetDAGCombineArray), 0);
for (MVT VT : MVT::fp_valuetypes()) {
- MVT IntVT = MVT::getIntegerVT(VT.getFixedSizeInBits());
+ MVT IntVT = MVT::getIntegerVT(VT.getFixedSizeInBits());
if (IntVT.isValid()) {
setOperationAction(ISD::ATOMIC_SWAP, VT, Promote);
AddPromotedToType(ISD::ATOMIC_SWAP, VT, IntVT);
@@ -769,8 +769,8 @@ void TargetLoweringBase::initActions() {
setOperationAction(ISD::UADDSAT, VT, Expand);
setOperationAction(ISD::SSUBSAT, VT, Expand);
setOperationAction(ISD::USUBSAT, VT, Expand);
- setOperationAction(ISD::SSHLSAT, VT, Expand);
- setOperationAction(ISD::USHLSAT, VT, Expand);
+ setOperationAction(ISD::SSHLSAT, VT, Expand);
+ setOperationAction(ISD::USHLSAT, VT, Expand);
setOperationAction(ISD::SMULFIX, VT, Expand);
setOperationAction(ISD::SMULFIXSAT, VT, Expand);
setOperationAction(ISD::UMULFIX, VT, Expand);
@@ -779,8 +779,8 @@ void TargetLoweringBase::initActions() {
setOperationAction(ISD::SDIVFIXSAT, VT, Expand);
setOperationAction(ISD::UDIVFIX, VT, Expand);
setOperationAction(ISD::UDIVFIXSAT, VT, Expand);
- setOperationAction(ISD::FP_TO_SINT_SAT, VT, Expand);
- setOperationAction(ISD::FP_TO_UINT_SAT, VT, Expand);
+ setOperationAction(ISD::FP_TO_SINT_SAT, VT, Expand);
+ setOperationAction(ISD::FP_TO_UINT_SAT, VT, Expand);
// Overflow operations default to expand
setOperationAction(ISD::SADDO, VT, Expand);
@@ -794,8 +794,8 @@ void TargetLoweringBase::initActions() {
setOperationAction(ISD::ADDCARRY, VT, Expand);
setOperationAction(ISD::SUBCARRY, VT, Expand);
setOperationAction(ISD::SETCCCARRY, VT, Expand);
- setOperationAction(ISD::SADDO_CARRY, VT, Expand);
- setOperationAction(ISD::SSUBO_CARRY, VT, Expand);
+ setOperationAction(ISD::SADDO_CARRY, VT, Expand);
+ setOperationAction(ISD::SSUBO_CARRY, VT, Expand);
// ADDC/ADDE/SUBC/SUBE default to expand.
setOperationAction(ISD::ADDC, VT, Expand);
@@ -808,7 +808,7 @@ void TargetLoweringBase::initActions() {
setOperationAction(ISD::CTTZ_ZERO_UNDEF, VT, Expand);
setOperationAction(ISD::BITREVERSE, VT, Expand);
- setOperationAction(ISD::PARITY, VT, Expand);
+ setOperationAction(ISD::PARITY, VT, Expand);
// These library functions default to expand.
setOperationAction(ISD::FROUND, VT, Expand);
@@ -847,8 +847,8 @@ void TargetLoweringBase::initActions() {
setOperationAction(ISD::VECREDUCE_UMIN, VT, Expand);
setOperationAction(ISD::VECREDUCE_FMAX, VT, Expand);
setOperationAction(ISD::VECREDUCE_FMIN, VT, Expand);
- setOperationAction(ISD::VECREDUCE_SEQ_FADD, VT, Expand);
- setOperationAction(ISD::VECREDUCE_SEQ_FMUL, VT, Expand);
+ setOperationAction(ISD::VECREDUCE_SEQ_FADD, VT, Expand);
+ setOperationAction(ISD::VECREDUCE_SEQ_FMUL, VT, Expand);
}
// Most targets ignore the @llvm.prefetch intrinsic.
@@ -893,8 +893,8 @@ void TargetLoweringBase::initActions() {
// On most systems, DEBUGTRAP and TRAP have no difference. The "Expand"
// here is to inform DAG Legalizer to replace DEBUGTRAP with TRAP.
setOperationAction(ISD::DEBUGTRAP, MVT::Other, Expand);
-
- setOperationAction(ISD::UBSANTRAP, MVT::Other, Expand);
+
+ setOperationAction(ISD::UBSANTRAP, MVT::Other, Expand);
}
MVT TargetLoweringBase::getScalarShiftAmountTy(const DataLayout &DL,
@@ -924,11 +924,11 @@ bool TargetLoweringBase::canOpTrap(unsigned Op, EVT VT) const {
}
}
-bool TargetLoweringBase::isFreeAddrSpaceCast(unsigned SrcAS,
- unsigned DestAS) const {
- return TM.isNoopAddrSpaceCast(SrcAS, DestAS);
-}
-
+bool TargetLoweringBase::isFreeAddrSpaceCast(unsigned SrcAS,
+ unsigned DestAS) const {
+ return TM.isNoopAddrSpaceCast(SrcAS, DestAS);
+}
+
void TargetLoweringBase::setJumpIsExpensive(bool isExpensive) {
// If the command-line option was specified, ignore this request.
if (!JumpIsExpensiveOverride.getNumOccurrences())
@@ -951,7 +951,7 @@ TargetLoweringBase::getTypeConversion(LLVMContext &Context, EVT VT) const {
"Promote may not follow Expand or Promote");
if (LA == TypeSplitVector)
- return LegalizeKind(LA, EVT(SVT).getHalfNumVectorElementsVT(Context));
+ return LegalizeKind(LA, EVT(SVT).getHalfNumVectorElementsVT(Context));
if (LA == TypeScalarizeVector)
return LegalizeKind(LA, SVT.getVectorElementType());
return LegalizeKind(LA, NVT);
@@ -982,10 +982,10 @@ TargetLoweringBase::getTypeConversion(LLVMContext &Context, EVT VT) const {
EVT EltVT = VT.getVectorElementType();
// Vectors with only one element are always scalarized.
- if (NumElts.isScalar())
+ if (NumElts.isScalar())
return LegalizeKind(TypeScalarizeVector, EltVT);
- if (VT.getVectorElementCount() == ElementCount::getScalable(1))
+ if (VT.getVectorElementCount() == ElementCount::getScalable(1))
report_fatal_error("Cannot legalize this vector");
// Try to widen vector elements until the element type is a power of two and
@@ -995,7 +995,7 @@ TargetLoweringBase::getTypeConversion(LLVMContext &Context, EVT VT) const {
// Vectors with a number of elements that is not a power of two are always
// widened, for example <3 x i8> -> <4 x i8>.
if (!VT.isPow2VectorType()) {
- NumElts = NumElts.coefficientNextPowerOf2();
+ NumElts = NumElts.coefficientNextPowerOf2();
EVT NVT = EVT::getVectorVT(Context, EltVT, NumElts);
return LegalizeKind(TypeWidenVector, NVT);
}
@@ -1007,7 +1007,7 @@ TargetLoweringBase::getTypeConversion(LLVMContext &Context, EVT VT) const {
// <4 x i140> -> <2 x i140>
if (LK.first == TypeExpandInteger)
return LegalizeKind(TypeSplitVector,
- VT.getHalfNumVectorElementsVT(Context));
+ VT.getHalfNumVectorElementsVT(Context));
// Promote the integer element types until a legal vector type is found
// or until the element integer type is too big. If a legal type was not
@@ -1044,7 +1044,7 @@ TargetLoweringBase::getTypeConversion(LLVMContext &Context, EVT VT) const {
// If there is no wider legal type, split the vector.
while (true) {
// Round up to the next power of 2.
- NumElts = NumElts.coefficientNextPowerOf2();
+ NumElts = NumElts.coefficientNextPowerOf2();
// If there is no simple vector type with this many elements then there
// cannot be a larger legal vector type. Note that this assumes that
@@ -1067,8 +1067,8 @@ TargetLoweringBase::getTypeConversion(LLVMContext &Context, EVT VT) const {
}
// Vectors with illegal element types are expanded.
- EVT NVT = EVT::getVectorVT(Context, EltVT,
- VT.getVectorElementCount().divideCoefficientBy(2));
+ EVT NVT = EVT::getVectorVT(Context, EltVT,
+ VT.getVectorElementCount().divideCoefficientBy(2));
return LegalizeKind(TypeSplitVector, NVT);
}
@@ -1084,24 +1084,24 @@ static unsigned getVectorTypeBreakdownMVT(MVT VT, MVT &IntermediateVT,
// Scalable vectors cannot be scalarized, so splitting or widening is
// required.
- if (VT.isScalableVector() && !isPowerOf2_32(EC.getKnownMinValue()))
+ if (VT.isScalableVector() && !isPowerOf2_32(EC.getKnownMinValue()))
llvm_unreachable(
"Splitting or widening of non-power-of-2 MVTs is not implemented.");
// FIXME: We don't support non-power-of-2-sized vectors for now.
// Ideally we could break down into LHS/RHS like LegalizeDAG does.
- if (!isPowerOf2_32(EC.getKnownMinValue())) {
+ if (!isPowerOf2_32(EC.getKnownMinValue())) {
// Split EC to unit size (scalable property is preserved).
- NumVectorRegs = EC.getKnownMinValue();
- EC = ElementCount::getFixed(1);
+ NumVectorRegs = EC.getKnownMinValue();
+ EC = ElementCount::getFixed(1);
}
// Divide the input until we get to a supported size. This will
// always end up with an EC that represent a scalar or a scalable
// scalar.
- while (EC.getKnownMinValue() > 1 &&
- !TLI->isTypeLegal(MVT::getVectorVT(EltTy, EC))) {
- EC = EC.divideCoefficientBy(2);
+ while (EC.getKnownMinValue() > 1 &&
+ !TLI->isTypeLegal(MVT::getVectorVT(EltTy, EC))) {
+ EC = EC.divideCoefficientBy(2);
NumVectorRegs <<= 1;
}
@@ -1112,7 +1112,7 @@ static unsigned getVectorTypeBreakdownMVT(MVT VT, MVT &IntermediateVT,
NewVT = EltTy;
IntermediateVT = NewVT;
- unsigned LaneSizeInBits = NewVT.getScalarSizeInBits();
+ unsigned LaneSizeInBits = NewVT.getScalarSizeInBits();
// Convert sizes such as i33 to i64.
if (!isPowerOf2_32(LaneSizeInBits))
@@ -1121,7 +1121,7 @@ static unsigned getVectorTypeBreakdownMVT(MVT VT, MVT &IntermediateVT,
MVT DestVT = TLI->getRegisterType(NewVT);
RegisterVT = DestVT;
if (EVT(DestVT).bitsLT(NewVT)) // Value is expanded, e.g. i64 -> i16.
- return NumVectorRegs * (LaneSizeInBits / DestVT.getScalarSizeInBits());
+ return NumVectorRegs * (LaneSizeInBits / DestVT.getScalarSizeInBits());
// Otherwise, promotion or legal types use the same number of registers as
// the vector decimated to the appropriate level.
@@ -1168,19 +1168,19 @@ TargetLoweringBase::emitPatchPoint(MachineInstr &InitialMI,
// Inherit previous memory operands.
MIB.cloneMemRefs(*MI);
- for (unsigned i = 0; i < MI->getNumOperands(); ++i) {
- MachineOperand &MO = MI->getOperand(i);
+ for (unsigned i = 0; i < MI->getNumOperands(); ++i) {
+ MachineOperand &MO = MI->getOperand(i);
if (!MO.isFI()) {
- // Index of Def operand this Use it tied to.
- // Since Defs are coming before Uses, if Use is tied, then
- // index of Def must be smaller that index of that Use.
- // Also, Defs preserve their position in new MI.
- unsigned TiedTo = i;
- if (MO.isReg() && MO.isTied())
- TiedTo = MI->findTiedOperandIdx(i);
+ // Index of Def operand this Use it tied to.
+ // Since Defs are coming before Uses, if Use is tied, then
+ // index of Def must be smaller that index of that Use.
+ // Also, Defs preserve their position in new MI.
+ unsigned TiedTo = i;
+ if (MO.isReg() && MO.isTied())
+ TiedTo = MI->findTiedOperandIdx(i);
MIB.add(MO);
- if (TiedTo < i)
- MIB->tieOperands(TiedTo, MIB->getNumOperands() - 1);
+ if (TiedTo < i)
+ MIB->tieOperands(TiedTo, MIB->getNumOperands() - 1);
continue;
}
@@ -1389,7 +1389,7 @@ void TargetLoweringBase::computeRegisterProperties(
MVT SVT = (MVT::SimpleValueType) nVT;
// Promote vectors of integers to vectors with the same number
// of elements, with a wider element type.
- if (SVT.getScalarSizeInBits() > EltVT.getFixedSizeInBits() &&
+ if (SVT.getScalarSizeInBits() > EltVT.getFixedSizeInBits() &&
SVT.getVectorElementCount() == EC && isTypeLegal(SVT)) {
TransformToType[i] = SVT;
RegisterTypeForVT[i] = SVT;
@@ -1405,15 +1405,15 @@ void TargetLoweringBase::computeRegisterProperties(
}
case TypeWidenVector:
- if (isPowerOf2_32(EC.getKnownMinValue())) {
+ if (isPowerOf2_32(EC.getKnownMinValue())) {
// Try to widen the vector.
for (unsigned nVT = i + 1; nVT <= MVT::LAST_VECTOR_VALUETYPE; ++nVT) {
MVT SVT = (MVT::SimpleValueType) nVT;
if (SVT.getVectorElementType() == EltVT &&
SVT.isScalableVector() == IsScalable &&
- SVT.getVectorElementCount().getKnownMinValue() >
- EC.getKnownMinValue() &&
- isTypeLegal(SVT)) {
+ SVT.getVectorElementCount().getKnownMinValue() >
+ EC.getKnownMinValue() &&
+ isTypeLegal(SVT)) {
TransformToType[i] = SVT;
RegisterTypeForVT[i] = SVT;
NumRegistersForVT[i] = 1;
@@ -1457,10 +1457,10 @@ void TargetLoweringBase::computeRegisterProperties(
ValueTypeActions.setTypeAction(VT, TypeScalarizeVector);
else if (PreferredAction == TypeSplitVector)
ValueTypeActions.setTypeAction(VT, TypeSplitVector);
- else if (EC.getKnownMinValue() > 1)
+ else if (EC.getKnownMinValue() > 1)
ValueTypeActions.setTypeAction(VT, TypeSplitVector);
else
- ValueTypeActions.setTypeAction(VT, EC.isScalable()
+ ValueTypeActions.setTypeAction(VT, EC.isScalable()
? TypeScalarizeScalableVector
: TypeScalarizeVector);
} else {
@@ -1518,8 +1518,8 @@ unsigned TargetLoweringBase::getVectorTypeBreakdown(LLVMContext &Context, EVT VT
// This handles things like <2 x float> -> <4 x float> and
// <4 x i1> -> <4 x i32>.
LegalizeTypeAction TA = getTypeAction(Context, VT);
- if (EltCnt.getKnownMinValue() != 1 &&
- (TA == TypeWidenVector || TA == TypePromoteInteger)) {
+ if (EltCnt.getKnownMinValue() != 1 &&
+ (TA == TypeWidenVector || TA == TypePromoteInteger)) {
EVT RegisterEVT = getTypeToTransformTo(Context, VT);
if (isTypeLegal(RegisterEVT)) {
IntermediateVT = RegisterEVT;
@@ -1536,7 +1536,7 @@ unsigned TargetLoweringBase::getVectorTypeBreakdown(LLVMContext &Context, EVT VT
// Scalable vectors cannot be scalarized, so handle the legalisation of the
// types like done elsewhere in SelectionDAG.
- if (VT.isScalableVector() && !isPowerOf2_32(EltCnt.getKnownMinValue())) {
+ if (VT.isScalableVector() && !isPowerOf2_32(EltCnt.getKnownMinValue())) {
LegalizeKind LK;
EVT PartVT = VT;
do {
@@ -1545,15 +1545,15 @@ unsigned TargetLoweringBase::getVectorTypeBreakdown(LLVMContext &Context, EVT VT
PartVT = LK.second;
} while (LK.first != TypeLegal);
- NumIntermediates = VT.getVectorElementCount().getKnownMinValue() /
- PartVT.getVectorElementCount().getKnownMinValue();
+ NumIntermediates = VT.getVectorElementCount().getKnownMinValue() /
+ PartVT.getVectorElementCount().getKnownMinValue();
// FIXME: This code needs to be extended to handle more complex vector
// breakdowns, like nxv7i64 -> nxv8i64 -> 4 x nxv2i64. Currently the only
// supported cases are vectors that are broken down into equal parts
// such as nxv6i64 -> 3 x nxv2i64.
- assert((PartVT.getVectorElementCount() * NumIntermediates) ==
- VT.getVectorElementCount() &&
+ assert((PartVT.getVectorElementCount() * NumIntermediates) ==
+ VT.getVectorElementCount() &&
"Expected an integer multiple of PartVT");
IntermediateVT = PartVT;
RegisterVT = getRegisterType(Context, IntermediateVT);
@@ -1562,16 +1562,16 @@ unsigned TargetLoweringBase::getVectorTypeBreakdown(LLVMContext &Context, EVT VT
// FIXME: We don't support non-power-of-2-sized vectors for now. Ideally
// we could break down into LHS/RHS like LegalizeDAG does.
- if (!isPowerOf2_32(EltCnt.getKnownMinValue())) {
- NumVectorRegs = EltCnt.getKnownMinValue();
- EltCnt = ElementCount::getFixed(1);
+ if (!isPowerOf2_32(EltCnt.getKnownMinValue())) {
+ NumVectorRegs = EltCnt.getKnownMinValue();
+ EltCnt = ElementCount::getFixed(1);
}
// Divide the input until we get to a supported size. This will always
// end with a scalar if the target doesn't support vectors.
- while (EltCnt.getKnownMinValue() > 1 &&
+ while (EltCnt.getKnownMinValue() > 1 &&
!isTypeLegal(EVT::getVectorVT(Context, EltTy, EltCnt))) {
- EltCnt = EltCnt.divideCoefficientBy(2);
+ EltCnt = EltCnt.divideCoefficientBy(2);
NumVectorRegs <<= 1;
}
@@ -1589,7 +1589,7 @@ unsigned TargetLoweringBase::getVectorTypeBreakdown(LLVMContext &Context, EVT VT
TypeSize NewVTSize = NewVT.getSizeInBits();
// Convert sizes such as i33 to i64.
if (!isPowerOf2_32(NewVTSize.getKnownMinSize()))
- NewVTSize = NewVTSize.coefficientNextPowerOf2();
+ NewVTSize = NewVTSize.coefficientNextPowerOf2();
return NumVectorRegs*(NewVTSize/DestVT.getSizeInBits());
}
@@ -1726,14 +1726,14 @@ bool TargetLoweringBase::allowsMemoryAccess(LLVMContext &Context,
MMO.getFlags(), Fast);
}
-bool TargetLoweringBase::allowsMemoryAccess(LLVMContext &Context,
- const DataLayout &DL, LLT Ty,
- const MachineMemOperand &MMO,
- bool *Fast) const {
- return allowsMemoryAccess(Context, DL, getMVTForLLT(Ty), MMO.getAddrSpace(),
- MMO.getAlign(), MMO.getFlags(), Fast);
-}
-
+bool TargetLoweringBase::allowsMemoryAccess(LLVMContext &Context,
+ const DataLayout &DL, LLT Ty,
+ const MachineMemOperand &MMO,
+ bool *Fast) const {
+ return allowsMemoryAccess(Context, DL, getMVTForLLT(Ty), MMO.getAddrSpace(),
+ MMO.getAlign(), MMO.getFlags(), Fast);
+}
+
BranchProbability TargetLoweringBase::getPredictableBranchThreshold() const {
return BranchProbability(MinPercentageForPredictableBranch, 100);
}
@@ -1956,14 +1956,14 @@ Value *TargetLoweringBase::getIRStackGuard(IRBuilder<> &IRB) const {
// Currently only support "standard" __stack_chk_guard.
// TODO: add LOAD_STACK_GUARD support.
void TargetLoweringBase::insertSSPDeclarations(Module &M) const {
- if (!M.getNamedValue("__stack_chk_guard")) {
- auto *GV = new GlobalVariable(M, Type::getInt8PtrTy(M.getContext()), false,
- GlobalVariable::ExternalLinkage, nullptr,
- "__stack_chk_guard");
- if (TM.getRelocationModel() == Reloc::Static &&
- !TM.getTargetTriple().isWindowsGNUEnvironment())
- GV->setDSOLocal(true);
- }
+ if (!M.getNamedValue("__stack_chk_guard")) {
+ auto *GV = new GlobalVariable(M, Type::getInt8PtrTy(M.getContext()), false,
+ GlobalVariable::ExternalLinkage, nullptr,
+ "__stack_chk_guard");
+ if (TM.getRelocationModel() == Reloc::Static &&
+ !TM.getTargetTriple().isWindowsGNUEnvironment())
+ GV->setDSOLocal(true);
+ }
}
// Currently only support "standard" __stack_chk_guard.
@@ -2047,7 +2047,7 @@ static bool parseRefinementStep(StringRef In, size_t &Position,
// step parameter.
if (RefStepString.size() == 1) {
char RefStepChar = RefStepString[0];
- if (isDigit(RefStepChar)) {
+ if (isDigit(RefStepChar)) {
Value = RefStepChar - '0';
return true;
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/contrib/libs/llvm12/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index e6c4ecd66f..fe64b38cf0 100644
--- a/contrib/libs/llvm12/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -21,7 +21,7 @@
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/BinaryFormat/MachO.h"
-#include "llvm/CodeGen/BasicBlockSectionUtils.h"
+#include "llvm/CodeGen/BasicBlockSectionUtils.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
@@ -40,7 +40,7 @@
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/PseudoProbe.h"
+#include "llvm/IR/PseudoProbe.h"
#include "llvm/IR/Type.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
@@ -106,11 +106,11 @@ static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags,
// ELF
//===----------------------------------------------------------------------===//
-TargetLoweringObjectFileELF::TargetLoweringObjectFileELF()
- : TargetLoweringObjectFile() {
- SupportDSOLocalEquivalentLowering = true;
-}
-
+TargetLoweringObjectFileELF::TargetLoweringObjectFileELF()
+ : TargetLoweringObjectFile() {
+ SupportDSOLocalEquivalentLowering = true;
+}
+
void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
const TargetMachine &TgtM) {
TargetLoweringObjectFile::Initialize(Ctx, TgtM);
@@ -128,7 +128,7 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
// Fallthrough if not using EHABI
LLVM_FALLTHROUGH;
case Triple::ppc:
- case Triple::ppcle:
+ case Triple::ppcle:
case Triple::x86:
PersonalityEncoding = isPositionIndependent()
? dwarf::DW_EH_PE_indirect |
@@ -181,20 +181,20 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
// will be in memory. Most of these could end up >2GB away so even a signed
// pc-relative 32-bit address is insufficient, theoretically.
if (isPositionIndependent()) {
- // ILP32 uses sdata4 instead of sdata8
- if (TgtM.getTargetTriple().getEnvironment() == Triple::GNUILP32) {
- PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
- dwarf::DW_EH_PE_sdata4;
- LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
- TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
- dwarf::DW_EH_PE_sdata4;
- } else {
- PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
- dwarf::DW_EH_PE_sdata8;
- LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8;
- TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
- dwarf::DW_EH_PE_sdata8;
- }
+ // ILP32 uses sdata4 instead of sdata8
+ if (TgtM.getTargetTriple().getEnvironment() == Triple::GNUILP32) {
+ PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+ dwarf::DW_EH_PE_sdata4;
+ LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
+ TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+ dwarf::DW_EH_PE_sdata4;
+ } else {
+ PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+ dwarf::DW_EH_PE_sdata8;
+ LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8;
+ TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+ dwarf::DW_EH_PE_sdata8;
+ }
} else {
PersonalityEncoding = dwarf::DW_EH_PE_absptr;
LSDAEncoding = dwarf::DW_EH_PE_absptr;
@@ -326,29 +326,29 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer,
}
}
- if (NamedMDNode *FuncInfo = M.getNamedMetadata(PseudoProbeDescMetadataName)) {
- // Emit a descriptor for every function including functions that have an
- // available external linkage. We may not want this for imported functions
- // that has code in another thinLTO module but we don't have a good way to
- // tell them apart from inline functions defined in header files. Therefore
- // we put each descriptor in a separate comdat section and rely on the
- // linker to deduplicate.
- for (const auto *Operand : FuncInfo->operands()) {
- const auto *MD = cast<MDNode>(Operand);
- auto *GUID = mdconst::dyn_extract<ConstantInt>(MD->getOperand(0));
- auto *Hash = mdconst::dyn_extract<ConstantInt>(MD->getOperand(1));
- auto *Name = cast<MDString>(MD->getOperand(2));
- auto *S = C.getObjectFileInfo()->getPseudoProbeDescSection(
- TM->getFunctionSections() ? Name->getString() : StringRef());
-
- Streamer.SwitchSection(S);
- Streamer.emitInt64(GUID->getZExtValue());
- Streamer.emitInt64(Hash->getZExtValue());
- Streamer.emitULEB128IntValue(Name->getString().size());
- Streamer.emitBytes(Name->getString());
- }
- }
-
+ if (NamedMDNode *FuncInfo = M.getNamedMetadata(PseudoProbeDescMetadataName)) {
+ // Emit a descriptor for every function including functions that have an
+ // available external linkage. We may not want this for imported functions
+ // that has code in another thinLTO module but we don't have a good way to
+ // tell them apart from inline functions defined in header files. Therefore
+ // we put each descriptor in a separate comdat section and rely on the
+ // linker to deduplicate.
+ for (const auto *Operand : FuncInfo->operands()) {
+ const auto *MD = cast<MDNode>(Operand);
+ auto *GUID = mdconst::dyn_extract<ConstantInt>(MD->getOperand(0));
+ auto *Hash = mdconst::dyn_extract<ConstantInt>(MD->getOperand(1));
+ auto *Name = cast<MDString>(MD->getOperand(2));
+ auto *S = C.getObjectFileInfo()->getPseudoProbeDescSection(
+ TM->getFunctionSections() ? Name->getString() : StringRef());
+
+ Streamer.SwitchSection(S);
+ Streamer.emitInt64(GUID->getZExtValue());
+ Streamer.emitInt64(Hash->getZExtValue());
+ Streamer.emitULEB128IntValue(Name->getString().size());
+ Streamer.emitBytes(Name->getString());
+ }
+ }
+
unsigned Version = 0;
unsigned Flags = 0;
StringRef Section;
@@ -363,7 +363,7 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer,
Streamer.AddBlankLine();
}
- emitCGProfileMetadata(Streamer, M);
+ emitCGProfileMetadata(Streamer, M);
}
MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol(
@@ -436,8 +436,8 @@ static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) {
if (Name == getInstrProfSectionName(IPSK_covmap, Triple::ELF,
/*AddSegmentInfo=*/false) ||
Name == getInstrProfSectionName(IPSK_covfun, Triple::ELF,
- /*AddSegmentInfo=*/false) ||
- Name == ".llvmbc" || Name == ".llvmcmd")
+ /*AddSegmentInfo=*/false) ||
+ Name == ".llvmbc" || Name == ".llvmcmd")
return SectionKind::getMetadata();
if (Name.empty() || Name[0] != '.') return K;
@@ -615,7 +615,7 @@ getELFSectionNameForGlobal(const GlobalObject *GO, SectionKind Kind,
bool HasPrefix = false;
if (const auto *F = dyn_cast<Function>(GO)) {
if (Optional<StringRef> Prefix = F->getSectionPrefix()) {
- raw_svector_ostream(Name) << '.' << *Prefix;
+ raw_svector_ostream(Name) << '.' << *Prefix;
HasPrefix = true;
}
}
@@ -681,12 +681,12 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
// MD_associated in a unique section.
unsigned UniqueID = MCContext::GenericSectionID;
const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM);
- if (GO->getMetadata(LLVMContext::MD_associated)) {
+ if (GO->getMetadata(LLVMContext::MD_associated)) {
UniqueID = NextUniqueID++;
Flags |= ELF::SHF_LINK_ORDER;
} else {
- if (getContext().getAsmInfo()->useIntegratedAssembler() ||
- getContext().getAsmInfo()->binutilsIsAtLeast(2, 35)) {
+ if (getContext().getAsmInfo()->useIntegratedAssembler() ||
+ getContext().getAsmInfo()->binutilsIsAtLeast(2, 35)) {
// Symbols must be placed into sections with compatible entry
// sizes. Generate unique sections for symbols that have not
// been assigned to compatible sections.
@@ -737,9 +737,9 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
assert(Section->getLinkedToSymbol() == LinkedToSym &&
"Associated symbol mismatch between sections");
- if (!(getContext().getAsmInfo()->useIntegratedAssembler() ||
- getContext().getAsmInfo()->binutilsIsAtLeast(2, 35))) {
- // If we are using GNU as before 2.35, then this symbol might have
+ if (!(getContext().getAsmInfo()->useIntegratedAssembler() ||
+ getContext().getAsmInfo()->binutilsIsAtLeast(2, 35))) {
+ // If we are using GNU as before 2.35, then this symbol might have
// been placed in an incompatible mergeable section. Emit an error if this
// is the case to avoid creating broken output.
if ((Section->getFlags() & ELF::SHF_MERGE) &&
@@ -834,43 +834,43 @@ MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(
/* AssociatedSymbol */ nullptr);
}
-MCSection *
-TargetLoweringObjectFileELF::getSectionForLSDA(const Function &F,
- const TargetMachine &TM) const {
- // If neither COMDAT nor function sections, use the monolithic LSDA section.
- // Re-use this path if LSDASection is null as in the Arm EHABI.
- if (!LSDASection || (!F.hasComdat() && !TM.getFunctionSections()))
- return LSDASection;
-
- const auto *LSDA = cast<MCSectionELF>(LSDASection);
- unsigned Flags = LSDA->getFlags();
- StringRef Group;
- if (F.hasComdat()) {
- Group = F.getComdat()->getName();
- Flags |= ELF::SHF_GROUP;
- }
-
- // Append the function name as the suffix like GCC, assuming
- // -funique-section-names applies to .gcc_except_table sections.
- if (TM.getUniqueSectionNames())
- return getContext().getELFSection(LSDA->getName() + "." + F.getName(),
- LSDA->getType(), Flags, 0, Group,
- MCSection::NonUniqueID, nullptr);
-
- // Allocate a unique ID if function sections && (integrated assembler or GNU
- // as>=2.35). Note we could use SHF_LINK_ORDER to facilitate --gc-sections but
- // that would require that we know the linker is a modern LLD (12.0 or later).
- // GNU ld as of 2.35 does not support mixed SHF_LINK_ORDER &
- // non-SHF_LINK_ORDER components in an output section
- // https://sourceware.org/bugzilla/show_bug.cgi?id=26256
- unsigned ID = TM.getFunctionSections() &&
- getContext().getAsmInfo()->useIntegratedAssembler()
- ? NextUniqueID++
- : MCSection::NonUniqueID;
- return getContext().getELFSection(LSDA->getName(), LSDA->getType(), Flags, 0,
- Group, ID, nullptr);
-}
-
+MCSection *
+TargetLoweringObjectFileELF::getSectionForLSDA(const Function &F,
+ const TargetMachine &TM) const {
+ // If neither COMDAT nor function sections, use the monolithic LSDA section.
+ // Re-use this path if LSDASection is null as in the Arm EHABI.
+ if (!LSDASection || (!F.hasComdat() && !TM.getFunctionSections()))
+ return LSDASection;
+
+ const auto *LSDA = cast<MCSectionELF>(LSDASection);
+ unsigned Flags = LSDA->getFlags();
+ StringRef Group;
+ if (F.hasComdat()) {
+ Group = F.getComdat()->getName();
+ Flags |= ELF::SHF_GROUP;
+ }
+
+ // Append the function name as the suffix like GCC, assuming
+ // -funique-section-names applies to .gcc_except_table sections.
+ if (TM.getUniqueSectionNames())
+ return getContext().getELFSection(LSDA->getName() + "." + F.getName(),
+ LSDA->getType(), Flags, 0, Group,
+ MCSection::NonUniqueID, nullptr);
+
+ // Allocate a unique ID if function sections && (integrated assembler or GNU
+ // as>=2.35). Note we could use SHF_LINK_ORDER to facilitate --gc-sections but
+ // that would require that we know the linker is a modern LLD (12.0 or later).
+ // GNU ld as of 2.35 does not support mixed SHF_LINK_ORDER &
+ // non-SHF_LINK_ORDER components in an output section
+ // https://sourceware.org/bugzilla/show_bug.cgi?id=26256
+ unsigned ID = TM.getFunctionSections() &&
+ getContext().getAsmInfo()->useIntegratedAssembler()
+ ? NextUniqueID++
+ : MCSection::NonUniqueID;
+ return getContext().getELFSection(LSDA->getName(), LSDA->getType(), Flags, 0,
+ Group, ID, nullptr);
+}
+
bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection(
bool UsesLabelDifference, const Function &F) const {
// We can always create relative relocations, so use another section
@@ -905,14 +905,14 @@ MCSection *TargetLoweringObjectFileELF::getSectionForMachineBasicBlock(
assert(MBB.isBeginSection() && "Basic block does not start a section!");
unsigned UniqueID = MCContext::GenericSectionID;
- // For cold sections use the .text.split. prefix along with the parent
+ // For cold sections use the .text.split. prefix along with the parent
// function name. All cold blocks for the same function go to the same
// section. Similarly all exception blocks are grouped by symbol name
// under the .text.eh prefix. For regular sections, we either use a unique
// name, or a unique ID for the section.
SmallString<128> Name;
if (MBB.getSectionID() == MBBSectionID::ColdSectionID) {
- Name += BBSectionsColdTextPrefix;
+ Name += BBSectionsColdTextPrefix;
Name += MBB.getParent()->getName();
} else if (MBB.getSectionID() == MBBSectionID::ExceptionSectionID) {
Name += ".text.eh.";
@@ -928,7 +928,7 @@ MCSection *TargetLoweringObjectFileELF::getSectionForMachineBasicBlock(
}
unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_EXECINSTR;
- std::string GroupName;
+ std::string GroupName;
if (F.hasComdat()) {
Flags |= ELF::SHF_GROUP;
GroupName = F.getComdat()->getName().str();
@@ -1008,20 +1008,20 @@ const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference(
MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext());
}
-const MCExpr *TargetLoweringObjectFileELF::lowerDSOLocalEquivalent(
- const DSOLocalEquivalent *Equiv, const TargetMachine &TM) const {
- assert(supportDSOLocalEquivalentLowering());
-
- const auto *GV = Equiv->getGlobalValue();
-
- // A PLT entry is not needed for dso_local globals.
- if (GV->isDSOLocal() || GV->isImplicitDSOLocal())
- return MCSymbolRefExpr::create(TM.getSymbol(GV), getContext());
-
- return MCSymbolRefExpr::create(TM.getSymbol(GV), PLTRelativeVariantKind,
- getContext());
-}
-
+const MCExpr *TargetLoweringObjectFileELF::lowerDSOLocalEquivalent(
+ const DSOLocalEquivalent *Equiv, const TargetMachine &TM) const {
+ assert(supportDSOLocalEquivalentLowering());
+
+ const auto *GV = Equiv->getGlobalValue();
+
+ // A PLT entry is not needed for dso_local globals.
+ if (GV->isDSOLocal() || GV->isImplicitDSOLocal())
+ return MCSymbolRefExpr::create(TM.getSymbol(GV), getContext());
+
+ return MCSymbolRefExpr::create(TM.getSymbol(GV), PLTRelativeVariantKind,
+ getContext());
+}
+
MCSection *TargetLoweringObjectFileELF::getSectionForCommandLines() const {
// Use ".GCC.command.line" since this feature is to support clang's
// -frecord-gcc-switches which in turn attempts to mimic GCC's switch of the
@@ -1569,10 +1569,10 @@ MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal(
MCSymbol *Sym = TM.getSymbol(ComdatGV);
StringRef COMDATSymName = Sym->getName();
- if (const auto *F = dyn_cast<Function>(GO))
- if (Optional<StringRef> Prefix = F->getSectionPrefix())
- raw_svector_ostream(Name) << '$' << *Prefix;
-
+ if (const auto *F = dyn_cast<Function>(GO))
+ if (Optional<StringRef> Prefix = F->getSectionPrefix())
+ raw_svector_ostream(Name) << '$' << *Prefix;
+
// Append "$symbol" to the section name *before* IR-level mangling is
// applied when targetting mingw. This is what GCC does, and the ld.bfd
// COFF linker will not properly handle comdats otherwise.
@@ -1648,31 +1648,31 @@ MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable(
void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer,
Module &M) const {
- emitLinkerDirectives(Streamer, M);
-
- unsigned Version = 0;
- unsigned Flags = 0;
- StringRef Section;
-
- GetObjCImageInfo(M, Version, Flags, Section);
- if (!Section.empty()) {
- auto &C = getContext();
- auto *S = C.getCOFFSection(Section,
- COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
- COFF::IMAGE_SCN_MEM_READ,
- SectionKind::getReadOnly());
- Streamer.SwitchSection(S);
- Streamer.emitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));
- Streamer.emitInt32(Version);
- Streamer.emitInt32(Flags);
- Streamer.AddBlankLine();
- }
-
- emitCGProfileMetadata(Streamer, M);
-}
-
-void TargetLoweringObjectFileCOFF::emitLinkerDirectives(
- MCStreamer &Streamer, Module &M) const {
+ emitLinkerDirectives(Streamer, M);
+
+ unsigned Version = 0;
+ unsigned Flags = 0;
+ StringRef Section;
+
+ GetObjCImageInfo(M, Version, Flags, Section);
+ if (!Section.empty()) {
+ auto &C = getContext();
+ auto *S = C.getCOFFSection(Section,
+ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getReadOnly());
+ Streamer.SwitchSection(S);
+ Streamer.emitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));
+ Streamer.emitInt32(Version);
+ Streamer.emitInt32(Flags);
+ Streamer.AddBlankLine();
+ }
+
+ emitCGProfileMetadata(Streamer, M);
+}
+
+void TargetLoweringObjectFileCOFF::emitLinkerDirectives(
+ MCStreamer &Streamer, Module &M) const {
if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {
// Emit the linker options to the linker .drectve section. According to the
// spec, this section is a space-separated string containing flags for
@@ -1689,51 +1689,51 @@ void TargetLoweringObjectFileCOFF::emitLinkerDirectives(
}
}
- // Emit /EXPORT: flags for each exported global as necessary.
- std::string Flags;
- for (const GlobalValue &GV : M.global_values()) {
- raw_string_ostream OS(Flags);
- emitLinkerFlagsForGlobalCOFF(OS, &GV, getTargetTriple(), getMangler());
- OS.flush();
- if (!Flags.empty()) {
- Streamer.SwitchSection(getDrectveSection());
- Streamer.emitBytes(Flags);
- }
- Flags.clear();
- }
-
- // Emit /INCLUDE: flags for each used global as necessary.
- if (const auto *LU = M.getNamedGlobal("llvm.used")) {
- assert(LU->hasInitializer() && "expected llvm.used to have an initializer");
- assert(isa<ArrayType>(LU->getValueType()) &&
- "expected llvm.used to be an array type");
- if (const auto *A = cast<ConstantArray>(LU->getInitializer())) {
- for (const Value *Op : A->operands()) {
- const auto *GV = cast<GlobalValue>(Op->stripPointerCasts());
- // Global symbols with internal or private linkage are not visible to
- // the linker, and thus would cause an error when the linker tried to
- // preserve the symbol due to the `/include:` directive.
- if (GV->hasLocalLinkage())
- continue;
-
- raw_string_ostream OS(Flags);
- emitLinkerFlagsForUsedCOFF(OS, GV, getTargetTriple(), getMangler());
- OS.flush();
-
- if (!Flags.empty()) {
- Streamer.SwitchSection(getDrectveSection());
- Streamer.emitBytes(Flags);
- }
- Flags.clear();
- }
- }
- }
+ // Emit /EXPORT: flags for each exported global as necessary.
+ std::string Flags;
+ for (const GlobalValue &GV : M.global_values()) {
+ raw_string_ostream OS(Flags);
+ emitLinkerFlagsForGlobalCOFF(OS, &GV, getTargetTriple(), getMangler());
+ OS.flush();
+ if (!Flags.empty()) {
+ Streamer.SwitchSection(getDrectveSection());
+ Streamer.emitBytes(Flags);
+ }
+ Flags.clear();
+ }
+
+ // Emit /INCLUDE: flags for each used global as necessary.
+ if (const auto *LU = M.getNamedGlobal("llvm.used")) {
+ assert(LU->hasInitializer() && "expected llvm.used to have an initializer");
+ assert(isa<ArrayType>(LU->getValueType()) &&
+ "expected llvm.used to be an array type");
+ if (const auto *A = cast<ConstantArray>(LU->getInitializer())) {
+ for (const Value *Op : A->operands()) {
+ const auto *GV = cast<GlobalValue>(Op->stripPointerCasts());
+ // Global symbols with internal or private linkage are not visible to
+ // the linker, and thus would cause an error when the linker tried to
+ // preserve the symbol due to the `/include:` directive.
+ if (GV->hasLocalLinkage())
+ continue;
+
+ raw_string_ostream OS(Flags);
+ emitLinkerFlagsForUsedCOFF(OS, GV, getTargetTriple(), getMangler());
+ OS.flush();
+
+ if (!Flags.empty()) {
+ Streamer.SwitchSection(getDrectveSection());
+ Streamer.emitBytes(Flags);
+ }
+ Flags.clear();
+ }
+ }
+ }
}
void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx,
const TargetMachine &TM) {
TargetLoweringObjectFile::Initialize(Ctx, TM);
- this->TM = &TM;
+ this->TM = &TM;
const Triple &T = TM.getTargetTriple();
if (T.isWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) {
StaticCtorSection =
@@ -1978,7 +1978,7 @@ static MCSectionWasm *selectWasmSectionForGlobal(
if (const auto *F = dyn_cast<Function>(GO)) {
const auto &OptionalPrefix = F->getSectionPrefix();
if (OptionalPrefix)
- raw_svector_ostream(Name) << '.' << *OptionalPrefix;
+ raw_svector_ostream(Name) << '.' << *OptionalPrefix;
}
if (EmitUniqueSection && UniqueSectionNames) {
@@ -2066,36 +2066,36 @@ MCSection *TargetLoweringObjectFileWasm::getStaticDtorSection(
//===----------------------------------------------------------------------===//
// XCOFF
//===----------------------------------------------------------------------===//
-bool TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(
- const MachineFunction *MF) {
- if (!MF->getLandingPads().empty())
- return true;
-
- const Function &F = MF->getFunction();
- if (!F.hasPersonalityFn() || !F.needsUnwindTableEntry())
- return false;
-
- const Function *Per =
- dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
- if (isNoOpWithoutInvoke(classifyEHPersonality(Per)))
- return false;
-
- return true;
-}
-
+bool TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(
+ const MachineFunction *MF) {
+ if (!MF->getLandingPads().empty())
+ return true;
+
+ const Function &F = MF->getFunction();
+ if (!F.hasPersonalityFn() || !F.needsUnwindTableEntry())
+ return false;
+
+ const Function *Per =
+ dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
+ if (isNoOpWithoutInvoke(classifyEHPersonality(Per)))
+ return false;
+
+ return true;
+}
+
+MCSymbol *
+TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(const MachineFunction *MF) {
+ return MF->getMMI().getContext().getOrCreateSymbol(
+ "__ehinfo." + Twine(MF->getFunctionNumber()));
+}
+
MCSymbol *
-TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(const MachineFunction *MF) {
- return MF->getMMI().getContext().getOrCreateSymbol(
- "__ehinfo." + Twine(MF->getFunctionNumber()));
-}
-
-MCSymbol *
TargetLoweringObjectFileXCOFF::getTargetSymbol(const GlobalValue *GV,
const TargetMachine &TM) const {
// We always use a qualname symbol for a GV that represents
// a declaration, a function descriptor, or a common symbol.
- // If a GV represents a GlobalVariable and -fdata-sections is enabled, we
- // also return a qualname so that a label symbol could be avoided.
+ // If a GV represents a GlobalVariable and -fdata-sections is enabled, we
+ // also return a qualname so that a label symbol could be avoided.
// It is inherently ambiguous when the GO represents the address of a
// function, as the GO could either represent a function descriptor or a
// function entry point. We choose to always return a function descriptor
@@ -2110,8 +2110,8 @@ TargetLoweringObjectFileXCOFF::getTargetSymbol(const GlobalValue *GV,
return cast<MCSectionXCOFF>(
getSectionForFunctionDescriptor(cast<Function>(GO), TM))
->getQualNameSymbol();
- if ((TM.getDataSections() && !GO->hasSection()) || GOKind.isCommon() ||
- GOKind.isBSSLocal())
+ if ((TM.getDataSections() && !GO->hasSection()) || GOKind.isCommon() ||
+ GOKind.isBSSLocal())
return cast<MCSectionXCOFF>(SectionForGlobal(GO, GOKind, TM))
->getQualNameSymbol();
}
@@ -2122,22 +2122,22 @@ TargetLoweringObjectFileXCOFF::getTargetSymbol(const GlobalValue *GV,
MCSection *TargetLoweringObjectFileXCOFF::getExplicitSectionGlobal(
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
- if (!GO->hasSection())
- report_fatal_error("#pragma clang section is not yet supported");
-
- StringRef SectionName = GO->getSection();
- XCOFF::StorageMappingClass MappingClass;
- if (Kind.isText())
- MappingClass = XCOFF::XMC_PR;
- else if (Kind.isData() || Kind.isReadOnlyWithRel() || Kind.isBSS())
- MappingClass = XCOFF::XMC_RW;
- else if (Kind.isReadOnly())
- MappingClass = XCOFF::XMC_RO;
- else
- report_fatal_error("XCOFF other section types not yet implemented.");
-
- return getContext().getXCOFFSection(SectionName, MappingClass, XCOFF::XTY_SD,
- Kind, /* MultiSymbolsAllowed*/ true);
+ if (!GO->hasSection())
+ report_fatal_error("#pragma clang section is not yet supported");
+
+ StringRef SectionName = GO->getSection();
+ XCOFF::StorageMappingClass MappingClass;
+ if (Kind.isText())
+ MappingClass = XCOFF::XMC_PR;
+ else if (Kind.isData() || Kind.isReadOnlyWithRel() || Kind.isBSS())
+ MappingClass = XCOFF::XMC_RW;
+ else if (Kind.isReadOnly())
+ MappingClass = XCOFF::XMC_RO;
+ else
+ report_fatal_error("XCOFF other section types not yet implemented.");
+
+ return getContext().getXCOFFSection(SectionName, MappingClass, XCOFF::XTY_SD,
+ Kind, /* MultiSymbolsAllowed*/ true);
}
MCSection *TargetLoweringObjectFileXCOFF::getSectionForExternalReference(
@@ -2151,7 +2151,7 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForExternalReference(
// Externals go into a csect of type ER.
return getContext().getXCOFFSection(
Name, isa<Function>(GO) ? XCOFF::XMC_DS : XCOFF::XMC_UA, XCOFF::XTY_ER,
- SectionKind::getMetadata());
+ SectionKind::getMetadata());
}
MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal(
@@ -2163,7 +2163,7 @@ MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal(
getNameWithPrefix(Name, GO, TM);
return getContext().getXCOFFSection(
Name, Kind.isBSSLocal() ? XCOFF::XMC_BS : XCOFF::XMC_RW, XCOFF::XTY_CM,
- Kind);
+ Kind);
}
if (Kind.isMergeableCString()) {
@@ -2175,48 +2175,48 @@ MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal(
SmallString<128> Name;
Name = SizeSpec + utostr(Alignment.value());
- if (TM.getDataSections())
- getNameWithPrefix(Name, GO, TM);
-
+ if (TM.getDataSections())
+ getNameWithPrefix(Name, GO, TM);
+
return getContext().getXCOFFSection(
- Name, XCOFF::XMC_RO, XCOFF::XTY_SD, Kind,
- /* MultiSymbolsAllowed*/ !TM.getDataSections());
+ Name, XCOFF::XMC_RO, XCOFF::XTY_SD, Kind,
+ /* MultiSymbolsAllowed*/ !TM.getDataSections());
}
- if (Kind.isText()) {
- if (TM.getFunctionSections()) {
- return cast<MCSymbolXCOFF>(getFunctionEntryPointSymbol(GO, TM))
- ->getRepresentedCsect();
- }
+ if (Kind.isText()) {
+ if (TM.getFunctionSections()) {
+ return cast<MCSymbolXCOFF>(getFunctionEntryPointSymbol(GO, TM))
+ ->getRepresentedCsect();
+ }
return TextSection;
- }
-
- // TODO: We may put Kind.isReadOnlyWithRel() under option control, because
- // user may want to have read-only data with relocations placed into a
- // read-only section by the compiler.
- // For BSS kind, zero initialized data must be emitted to the .data section
- // because external linkage control sections that get mapped to the .bss
- // section will be linked as tentative defintions, which is only appropriate
- // for SectionKind::Common.
- if (Kind.isData() || Kind.isReadOnlyWithRel() || Kind.isBSS()) {
- if (TM.getDataSections()) {
- SmallString<128> Name;
- getNameWithPrefix(Name, GO, TM);
- return getContext().getXCOFFSection(Name, XCOFF::XMC_RW, XCOFF::XTY_SD,
- SectionKind::getData());
- }
+ }
+
+ // TODO: We may put Kind.isReadOnlyWithRel() under option control, because
+ // user may want to have read-only data with relocations placed into a
+ // read-only section by the compiler.
+ // For BSS kind, zero initialized data must be emitted to the .data section
+ // because external linkage control sections that get mapped to the .bss
+ // section will be linked as tentative defintions, which is only appropriate
+ // for SectionKind::Common.
+ if (Kind.isData() || Kind.isReadOnlyWithRel() || Kind.isBSS()) {
+ if (TM.getDataSections()) {
+ SmallString<128> Name;
+ getNameWithPrefix(Name, GO, TM);
+ return getContext().getXCOFFSection(Name, XCOFF::XMC_RW, XCOFF::XTY_SD,
+ SectionKind::getData());
+ }
return DataSection;
- }
-
- if (Kind.isReadOnly()) {
- if (TM.getDataSections()) {
- SmallString<128> Name;
- getNameWithPrefix(Name, GO, TM);
- return getContext().getXCOFFSection(Name, XCOFF::XMC_RO, XCOFF::XTY_SD,
- SectionKind::getReadOnly());
- }
+ }
+
+ if (Kind.isReadOnly()) {
+ if (TM.getDataSections()) {
+ SmallString<128> Name;
+ getNameWithPrefix(Name, GO, TM);
+ return getContext().getXCOFFSection(Name, XCOFF::XMC_RO, XCOFF::XTY_SD,
+ SectionKind::getReadOnly());
+ }
return ReadOnlySection;
- }
+ }
report_fatal_error("XCOFF other section types not yet implemented.");
}
@@ -2224,16 +2224,16 @@ MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal(
MCSection *TargetLoweringObjectFileXCOFF::getSectionForJumpTable(
const Function &F, const TargetMachine &TM) const {
assert (!F.getComdat() && "Comdat not supported on XCOFF.");
-
- if (!TM.getFunctionSections())
- return ReadOnlySection;
-
- // If the function can be removed, produce a unique section so that
- // the table doesn't prevent the removal.
- SmallString<128> NameStr(".rodata.jmp..");
- getNameWithPrefix(NameStr, &F, TM);
- return getContext().getXCOFFSection(NameStr, XCOFF::XMC_RO, XCOFF::XTY_SD,
- SectionKind::getReadOnly());
+
+ if (!TM.getFunctionSections())
+ return ReadOnlySection;
+
+ // If the function can be removed, produce a unique section so that
+ // the table doesn't prevent the removal.
+ SmallString<128> NameStr(".rodata.jmp..");
+ getNameWithPrefix(NameStr, &F, TM);
+ return getContext().getXCOFFSection(NameStr, XCOFF::XMC_RO, XCOFF::XTY_SD,
+ SectionKind::getReadOnly());
}
bool TargetLoweringObjectFileXCOFF::shouldPutJumpTableInFunctionSection(
@@ -2253,23 +2253,23 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForConstant(
void TargetLoweringObjectFileXCOFF::Initialize(MCContext &Ctx,
const TargetMachine &TgtM) {
TargetLoweringObjectFile::Initialize(Ctx, TgtM);
- TTypeEncoding =
- dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_datarel |
- (TgtM.getTargetTriple().isArch32Bit() ? dwarf::DW_EH_PE_sdata4
- : dwarf::DW_EH_PE_sdata8);
+ TTypeEncoding =
+ dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_datarel |
+ (TgtM.getTargetTriple().isArch32Bit() ? dwarf::DW_EH_PE_sdata4
+ : dwarf::DW_EH_PE_sdata8);
PersonalityEncoding = 0;
LSDAEncoding = 0;
- CallSiteEncoding = dwarf::DW_EH_PE_udata4;
+ CallSiteEncoding = dwarf::DW_EH_PE_udata4;
}
MCSection *TargetLoweringObjectFileXCOFF::getStaticCtorSection(
- unsigned Priority, const MCSymbol *KeySym) const {
- report_fatal_error("no static constructor section on AIX");
+ unsigned Priority, const MCSymbol *KeySym) const {
+ report_fatal_error("no static constructor section on AIX");
}
MCSection *TargetLoweringObjectFileXCOFF::getStaticDtorSection(
- unsigned Priority, const MCSymbol *KeySym) const {
- report_fatal_error("no static destructor section on AIX");
+ unsigned Priority, const MCSymbol *KeySym) const {
+ report_fatal_error("no static destructor section on AIX");
}
const MCExpr *TargetLoweringObjectFileXCOFF::lowerRelativeReference(
@@ -2278,11 +2278,11 @@ const MCExpr *TargetLoweringObjectFileXCOFF::lowerRelativeReference(
report_fatal_error("XCOFF not yet implemented.");
}
-XCOFF::StorageClass
-TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(const GlobalValue *GV) {
- assert(!isa<GlobalIFunc>(GV) && "GlobalIFunc is not supported on AIX.");
-
- switch (GV->getLinkage()) {
+XCOFF::StorageClass
+TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(const GlobalValue *GV) {
+ assert(!isa<GlobalIFunc>(GV) && "GlobalIFunc is not supported on AIX.");
+
+ switch (GV->getLinkage()) {
case GlobalValue::InternalLinkage:
case GlobalValue::PrivateLinkage:
return XCOFF::C_HIDEXT;
@@ -2304,32 +2304,32 @@ TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(const GlobalValue *GV) {
}
MCSymbol *TargetLoweringObjectFileXCOFF::getFunctionEntryPointSymbol(
- const GlobalValue *Func, const TargetMachine &TM) const {
- assert(
- (isa<Function>(Func) ||
- (isa<GlobalAlias>(Func) &&
- isa_and_nonnull<Function>(cast<GlobalAlias>(Func)->getBaseObject()))) &&
- "Func must be a function or an alias which has a function as base "
- "object.");
-
+ const GlobalValue *Func, const TargetMachine &TM) const {
+ assert(
+ (isa<Function>(Func) ||
+ (isa<GlobalAlias>(Func) &&
+ isa_and_nonnull<Function>(cast<GlobalAlias>(Func)->getBaseObject()))) &&
+ "Func must be a function or an alias which has a function as base "
+ "object.");
+
SmallString<128> NameStr;
NameStr.push_back('.');
- getNameWithPrefix(NameStr, Func, TM);
-
- // When -function-sections is enabled and explicit section is not specified,
- // it's not necessary to emit function entry point label any more. We will use
- // function entry point csect instead. And for function delcarations, the
- // undefined symbols gets treated as csect with XTY_ER property.
- if (((TM.getFunctionSections() && !Func->hasSection()) ||
- Func->isDeclaration()) &&
- isa<Function>(Func)) {
- return getContext()
- .getXCOFFSection(NameStr, XCOFF::XMC_PR,
- Func->isDeclaration() ? XCOFF::XTY_ER : XCOFF::XTY_SD,
- SectionKind::getText())
- ->getQualNameSymbol();
- }
-
+ getNameWithPrefix(NameStr, Func, TM);
+
+ // When -function-sections is enabled and explicit section is not specified,
+ // it's not necessary to emit function entry point label any more. We will use
+ // function entry point csect instead. And for function delcarations, the
+ // undefined symbols gets treated as csect with XTY_ER property.
+ if (((TM.getFunctionSections() && !Func->hasSection()) ||
+ Func->isDeclaration()) &&
+ isa<Function>(Func)) {
+ return getContext()
+ .getXCOFFSection(NameStr, XCOFF::XMC_PR,
+ Func->isDeclaration() ? XCOFF::XTY_ER : XCOFF::XTY_SD,
+ SectionKind::getText())
+ ->getQualNameSymbol();
+ }
+
return getContext().getOrCreateSymbol(NameStr);
}
@@ -2342,11 +2342,11 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForFunctionDescriptor(
}
MCSection *TargetLoweringObjectFileXCOFF::getSectionForTOCEntry(
- const MCSymbol *Sym, const TargetMachine &TM) const {
- // Use TE storage-mapping class when large code model is enabled so that
- // the chance of needing -bbigtoc is decreased.
+ const MCSymbol *Sym, const TargetMachine &TM) const {
+ // Use TE storage-mapping class when large code model is enabled so that
+ // the chance of needing -bbigtoc is decreased.
return getContext().getXCOFFSection(
- cast<MCSymbolXCOFF>(Sym)->getSymbolTableName(),
- TM.getCodeModel() == CodeModel::Large ? XCOFF::XMC_TE : XCOFF::XMC_TC,
- XCOFF::XTY_SD, SectionKind::getData());
+ cast<MCSymbolXCOFF>(Sym)->getSymbolTableName(),
+ TM.getCodeModel() == CodeModel::Large ? XCOFF::XMC_TE : XCOFF::XMC_TC,
+ XCOFF::XTY_SD, SectionKind::getData());
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/TargetOptionsImpl.cpp b/contrib/libs/llvm12/lib/CodeGen/TargetOptionsImpl.cpp
index cdbdf108c5..0731cf9b28 100644
--- a/contrib/libs/llvm12/lib/CodeGen/TargetOptionsImpl.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/TargetOptionsImpl.cpp
@@ -47,11 +47,11 @@ bool TargetOptions::HonorSignDependentRoundingFPMath() const {
}
/// NOTE: There are targets that still do not support the debug entry values
-/// production and that is being controlled with the SupportsDebugEntryValues.
-/// In addition, SCE debugger does not have the feature implemented, so prefer
-/// not to emit the debug entry values in that case.
-/// The EnableDebugEntryValues can be used for the testing purposes.
+/// production and that is being controlled with the SupportsDebugEntryValues.
+/// In addition, SCE debugger does not have the feature implemented, so prefer
+/// not to emit the debug entry values in that case.
+/// The EnableDebugEntryValues can be used for the testing purposes.
bool TargetOptions::ShouldEmitDebugEntryValues() const {
- return (SupportsDebugEntryValues && DebuggerTuning != DebuggerKind::SCE) ||
- EnableDebugEntryValues;
+ return (SupportsDebugEntryValues && DebuggerTuning != DebuggerKind::SCE) ||
+ EnableDebugEntryValues;
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/TargetPassConfig.cpp b/contrib/libs/llvm12/lib/CodeGen/TargetPassConfig.cpp
index 8979fe8135..e844d03854 100644
--- a/contrib/libs/llvm12/lib/CodeGen/TargetPassConfig.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/TargetPassConfig.cpp
@@ -29,7 +29,7 @@
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/IR/PassInstrumentation.h"
+#include "llvm/IR/PassInstrumentation.h"
#include "llvm/IR/Verifier.h"
#include "llvm/InitializePasses.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -42,7 +42,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/Threading.h"
-#include "llvm/Target/CGPassBuilderOption.h"
+#include "llvm/Target/CGPassBuilderOption.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils.h"
@@ -122,22 +122,22 @@ static cl::opt<cl::boolOrDefault> DebugifyAndStripAll(
"Debugify MIR before and Strip debug after "
"each pass except those known to be unsafe when debug info is present"),
cl::ZeroOrMore);
-static cl::opt<cl::boolOrDefault> DebugifyCheckAndStripAll(
- "debugify-check-and-strip-all-safe", cl::Hidden,
- cl::desc(
- "Debugify MIR before, by checking and stripping the debug info after, "
- "each pass except those known to be unsafe when debug info is present"),
- cl::ZeroOrMore);
+static cl::opt<cl::boolOrDefault> DebugifyCheckAndStripAll(
+ "debugify-check-and-strip-all-safe", cl::Hidden,
+ cl::desc(
+ "Debugify MIR before, by checking and stripping the debug info after, "
+ "each pass except those known to be unsafe when debug info is present"),
+ cl::ZeroOrMore);
// Enable or disable the MachineOutliner.
static cl::opt<RunOutliner> EnableMachineOutliner(
"enable-machine-outliner", cl::desc("Enable the machine outliner"),
- cl::Hidden, cl::ValueOptional, cl::init(RunOutliner::TargetDefault),
- cl::values(clEnumValN(RunOutliner::AlwaysOutline, "always",
+ cl::Hidden, cl::ValueOptional, cl::init(RunOutliner::TargetDefault),
+ cl::values(clEnumValN(RunOutliner::AlwaysOutline, "always",
"Run on all functions guaranteed to be beneficial"),
- clEnumValN(RunOutliner::NeverOutline, "never",
- "Disable all outlining"),
+ clEnumValN(RunOutliner::NeverOutline, "never",
+ "Disable all outlining"),
// Sentinel value for unspecified option.
- clEnumValN(RunOutliner::AlwaysOutline, "", "")));
+ clEnumValN(RunOutliner::AlwaysOutline, "", "")));
// Enable or disable FastISel. Both options are needed, because
// FastISel is enabled by default with -fast, and we wish to be
// able to enable or disable fast-isel independently from -O0.
@@ -149,11 +149,11 @@ static cl::opt<cl::boolOrDefault> EnableGlobalISelOption(
"global-isel", cl::Hidden,
cl::desc("Enable the \"global\" instruction selector"));
-// FIXME: remove this after switching to NPM or GlobalISel, whichever gets there
-// first...
-static cl::opt<bool>
- PrintAfterISel("print-after-isel", cl::init(false), cl::Hidden,
- cl::desc("Print machine instrs after ISel"));
+// FIXME: remove this after switching to NPM or GlobalISel, whichever gets there
+// first...
+static cl::opt<bool>
+ PrintAfterISel("print-after-isel", cl::init(false), cl::Hidden,
+ cl::desc("Print machine instrs after ISel"));
static cl::opt<GlobalISelAbortMode> EnableGlobalISelAbort(
"global-isel-abort", cl::Hidden,
@@ -219,17 +219,17 @@ static cl::opt<std::string>
cl::desc("Stop compilation before a specific pass"),
cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
-/// Enable the machine function splitter pass.
-static cl::opt<bool> EnableMachineFunctionSplitter(
- "enable-split-machine-functions", cl::Hidden,
- cl::desc("Split out cold blocks from machine functions based on profile "
- "information."));
-
-/// Disable the expand reductions pass for testing.
-static cl::opt<bool> DisableExpandReductions(
- "disable-expand-reductions", cl::init(false), cl::Hidden,
- cl::desc("Disable the expand reduction intrinsics pass from running"));
-
+/// Enable the machine function splitter pass.
+static cl::opt<bool> EnableMachineFunctionSplitter(
+ "enable-split-machine-functions", cl::Hidden,
+ cl::desc("Split out cold blocks from machine functions based on profile "
+ "information."));
+
+/// Disable the expand reductions pass for testing.
+static cl::opt<bool> DisableExpandReductions(
+ "disable-expand-reductions", cl::init(false), cl::Hidden,
+ cl::desc("Disable the expand reduction intrinsics pass from running"));
+
/// Allow standard passes to be disabled by command line options. This supports
/// simple binary flags that either suppress the pass or do nothing.
/// i.e. -disable-mypass=false has no effect.
@@ -316,9 +316,9 @@ struct InsertedPass {
bool VerifyAfter;
InsertedPass(AnalysisID TargetPassID, IdentifyingPassPtr InsertedPassID,
- bool VerifyAfter)
+ bool VerifyAfter)
: TargetPassID(TargetPassID), InsertedPassID(InsertedPassID),
- VerifyAfter(VerifyAfter) {}
+ VerifyAfter(VerifyAfter) {}
Pass *getInsertedPass() const {
assert(InsertedPassID.isValid() && "Illegal Pass ID!");
@@ -416,145 +416,145 @@ void TargetPassConfig::setStartStopPasses() {
Started = (StartAfter == nullptr) && (StartBefore == nullptr);
}
-CGPassBuilderOption llvm::getCGPassBuilderOption() {
- CGPassBuilderOption Opt;
-
-#define SET_OPTION(Option) \
- if (Option.getNumOccurrences()) \
- Opt.Option = Option;
-
- SET_OPTION(EnableFastISelOption)
- SET_OPTION(EnableGlobalISelAbort)
- SET_OPTION(EnableGlobalISelOption)
- SET_OPTION(EnableIPRA)
- SET_OPTION(OptimizeRegAlloc)
- SET_OPTION(VerifyMachineCode)
-
-#define SET_BOOLEAN_OPTION(Option) Opt.Option = Option;
-
- SET_BOOLEAN_OPTION(EarlyLiveIntervals)
- SET_BOOLEAN_OPTION(EnableBlockPlacementStats)
- SET_BOOLEAN_OPTION(EnableImplicitNullChecks)
- SET_BOOLEAN_OPTION(EnableMachineOutliner)
- SET_BOOLEAN_OPTION(MISchedPostRA)
- SET_BOOLEAN_OPTION(UseCFLAA)
- SET_BOOLEAN_OPTION(DisableMergeICmps)
- SET_BOOLEAN_OPTION(DisableLSR)
- SET_BOOLEAN_OPTION(DisableConstantHoisting)
- SET_BOOLEAN_OPTION(DisableCGP)
- SET_BOOLEAN_OPTION(DisablePartialLibcallInlining)
- SET_BOOLEAN_OPTION(PrintLSR)
- SET_BOOLEAN_OPTION(PrintISelInput)
- SET_BOOLEAN_OPTION(PrintGCInfo)
-
- return Opt;
-}
-
-static void registerPartialPipelineCallback(PassInstrumentationCallbacks &PIC,
- LLVMTargetMachine &LLVMTM) {
- StringRef StartBefore;
- StringRef StartAfter;
- StringRef StopBefore;
- StringRef StopAfter;
-
- unsigned StartBeforeInstanceNum = 0;
- unsigned StartAfterInstanceNum = 0;
- unsigned StopBeforeInstanceNum = 0;
- unsigned StopAfterInstanceNum = 0;
-
- std::tie(StartBefore, StartBeforeInstanceNum) =
- getPassNameAndInstanceNum(StartBeforeOpt);
- std::tie(StartAfter, StartAfterInstanceNum) =
- getPassNameAndInstanceNum(StartAfterOpt);
- std::tie(StopBefore, StopBeforeInstanceNum) =
- getPassNameAndInstanceNum(StopBeforeOpt);
- std::tie(StopAfter, StopAfterInstanceNum) =
- getPassNameAndInstanceNum(StopAfterOpt);
-
- if (StartBefore.empty() && StartAfter.empty() && StopBefore.empty() &&
- StopAfter.empty())
- return;
-
- std::tie(StartBefore, std::ignore) =
- LLVMTM.getPassNameFromLegacyName(StartBefore);
- std::tie(StartAfter, std::ignore) =
- LLVMTM.getPassNameFromLegacyName(StartAfter);
- std::tie(StopBefore, std::ignore) =
- LLVMTM.getPassNameFromLegacyName(StopBefore);
- std::tie(StopAfter, std::ignore) =
- LLVMTM.getPassNameFromLegacyName(StopAfter);
- if (!StartBefore.empty() && !StartAfter.empty())
- report_fatal_error(Twine(StartBeforeOptName) + Twine(" and ") +
- Twine(StartAfterOptName) + Twine(" specified!"));
- if (!StopBefore.empty() && !StopAfter.empty())
- report_fatal_error(Twine(StopBeforeOptName) + Twine(" and ") +
- Twine(StopAfterOptName) + Twine(" specified!"));
-
- PIC.registerShouldRunOptionalPassCallback(
- [=, EnableCurrent = StartBefore.empty() && StartAfter.empty(),
- EnableNext = Optional<bool>(), StartBeforeCount = 0u,
- StartAfterCount = 0u, StopBeforeCount = 0u,
- StopAfterCount = 0u](StringRef P, Any) mutable {
- bool StartBeforePass = !StartBefore.empty() && P.contains(StartBefore);
- bool StartAfterPass = !StartAfter.empty() && P.contains(StartAfter);
- bool StopBeforePass = !StopBefore.empty() && P.contains(StopBefore);
- bool StopAfterPass = !StopAfter.empty() && P.contains(StopAfter);
-
- // Implement -start-after/-stop-after
- if (EnableNext) {
- EnableCurrent = *EnableNext;
- EnableNext.reset();
- }
-
- // Using PIC.registerAfterPassCallback won't work because if this
- // callback returns false, AfterPassCallback is also skipped.
- if (StartAfterPass && StartAfterCount++ == StartAfterInstanceNum) {
- assert(!EnableNext && "Error: assign to EnableNext more than once");
- EnableNext = true;
- }
- if (StopAfterPass && StopAfterCount++ == StopAfterInstanceNum) {
- assert(!EnableNext && "Error: assign to EnableNext more than once");
- EnableNext = false;
- }
-
- if (StartBeforePass && StartBeforeCount++ == StartBeforeInstanceNum)
- EnableCurrent = true;
- if (StopBeforePass && StopBeforeCount++ == StopBeforeInstanceNum)
- EnableCurrent = false;
- return EnableCurrent;
- });
-}
-
-void llvm::registerCodeGenCallback(PassInstrumentationCallbacks &PIC,
- LLVMTargetMachine &LLVMTM) {
-
- // Register a callback for disabling passes.
- PIC.registerShouldRunOptionalPassCallback([](StringRef P, Any) {
-
-#define DISABLE_PASS(Option, Name) \
- if (Option && P.contains(#Name)) \
- return false;
- DISABLE_PASS(DisableBlockPlacement, MachineBlockPlacementPass)
- DISABLE_PASS(DisableBranchFold, BranchFolderPass)
- DISABLE_PASS(DisableCopyProp, MachineCopyPropagationPass)
- DISABLE_PASS(DisableEarlyIfConversion, EarlyIfConverterPass)
- DISABLE_PASS(DisableEarlyTailDup, EarlyTailDuplicatePass)
- DISABLE_PASS(DisableMachineCSE, MachineCSEPass)
- DISABLE_PASS(DisableMachineDCE, DeadMachineInstructionElimPass)
- DISABLE_PASS(DisableMachineLICM, EarlyMachineLICMPass)
- DISABLE_PASS(DisableMachineSink, MachineSinkingPass)
- DISABLE_PASS(DisablePostRAMachineLICM, MachineLICMPass)
- DISABLE_PASS(DisablePostRAMachineSink, PostRAMachineSinkingPass)
- DISABLE_PASS(DisablePostRASched, PostRASchedulerPass)
- DISABLE_PASS(DisableSSC, StackSlotColoringPass)
- DISABLE_PASS(DisableTailDuplicate, TailDuplicatePass)
-
- return true;
- });
-
- registerPartialPipelineCallback(PIC, LLVMTM);
-}
-
+CGPassBuilderOption llvm::getCGPassBuilderOption() {
+ CGPassBuilderOption Opt;
+
+#define SET_OPTION(Option) \
+ if (Option.getNumOccurrences()) \
+ Opt.Option = Option;
+
+ SET_OPTION(EnableFastISelOption)
+ SET_OPTION(EnableGlobalISelAbort)
+ SET_OPTION(EnableGlobalISelOption)
+ SET_OPTION(EnableIPRA)
+ SET_OPTION(OptimizeRegAlloc)
+ SET_OPTION(VerifyMachineCode)
+
+#define SET_BOOLEAN_OPTION(Option) Opt.Option = Option;
+
+ SET_BOOLEAN_OPTION(EarlyLiveIntervals)
+ SET_BOOLEAN_OPTION(EnableBlockPlacementStats)
+ SET_BOOLEAN_OPTION(EnableImplicitNullChecks)
+ SET_BOOLEAN_OPTION(EnableMachineOutliner)
+ SET_BOOLEAN_OPTION(MISchedPostRA)
+ SET_BOOLEAN_OPTION(UseCFLAA)
+ SET_BOOLEAN_OPTION(DisableMergeICmps)
+ SET_BOOLEAN_OPTION(DisableLSR)
+ SET_BOOLEAN_OPTION(DisableConstantHoisting)
+ SET_BOOLEAN_OPTION(DisableCGP)
+ SET_BOOLEAN_OPTION(DisablePartialLibcallInlining)
+ SET_BOOLEAN_OPTION(PrintLSR)
+ SET_BOOLEAN_OPTION(PrintISelInput)
+ SET_BOOLEAN_OPTION(PrintGCInfo)
+
+ return Opt;
+}
+
+static void registerPartialPipelineCallback(PassInstrumentationCallbacks &PIC,
+ LLVMTargetMachine &LLVMTM) {
+ StringRef StartBefore;
+ StringRef StartAfter;
+ StringRef StopBefore;
+ StringRef StopAfter;
+
+ unsigned StartBeforeInstanceNum = 0;
+ unsigned StartAfterInstanceNum = 0;
+ unsigned StopBeforeInstanceNum = 0;
+ unsigned StopAfterInstanceNum = 0;
+
+ std::tie(StartBefore, StartBeforeInstanceNum) =
+ getPassNameAndInstanceNum(StartBeforeOpt);
+ std::tie(StartAfter, StartAfterInstanceNum) =
+ getPassNameAndInstanceNum(StartAfterOpt);
+ std::tie(StopBefore, StopBeforeInstanceNum) =
+ getPassNameAndInstanceNum(StopBeforeOpt);
+ std::tie(StopAfter, StopAfterInstanceNum) =
+ getPassNameAndInstanceNum(StopAfterOpt);
+
+ if (StartBefore.empty() && StartAfter.empty() && StopBefore.empty() &&
+ StopAfter.empty())
+ return;
+
+ std::tie(StartBefore, std::ignore) =
+ LLVMTM.getPassNameFromLegacyName(StartBefore);
+ std::tie(StartAfter, std::ignore) =
+ LLVMTM.getPassNameFromLegacyName(StartAfter);
+ std::tie(StopBefore, std::ignore) =
+ LLVMTM.getPassNameFromLegacyName(StopBefore);
+ std::tie(StopAfter, std::ignore) =
+ LLVMTM.getPassNameFromLegacyName(StopAfter);
+ if (!StartBefore.empty() && !StartAfter.empty())
+ report_fatal_error(Twine(StartBeforeOptName) + Twine(" and ") +
+ Twine(StartAfterOptName) + Twine(" specified!"));
+ if (!StopBefore.empty() && !StopAfter.empty())
+ report_fatal_error(Twine(StopBeforeOptName) + Twine(" and ") +
+ Twine(StopAfterOptName) + Twine(" specified!"));
+
+ PIC.registerShouldRunOptionalPassCallback(
+ [=, EnableCurrent = StartBefore.empty() && StartAfter.empty(),
+ EnableNext = Optional<bool>(), StartBeforeCount = 0u,
+ StartAfterCount = 0u, StopBeforeCount = 0u,
+ StopAfterCount = 0u](StringRef P, Any) mutable {
+ bool StartBeforePass = !StartBefore.empty() && P.contains(StartBefore);
+ bool StartAfterPass = !StartAfter.empty() && P.contains(StartAfter);
+ bool StopBeforePass = !StopBefore.empty() && P.contains(StopBefore);
+ bool StopAfterPass = !StopAfter.empty() && P.contains(StopAfter);
+
+ // Implement -start-after/-stop-after
+ if (EnableNext) {
+ EnableCurrent = *EnableNext;
+ EnableNext.reset();
+ }
+
+ // Using PIC.registerAfterPassCallback won't work because if this
+ // callback returns false, AfterPassCallback is also skipped.
+ if (StartAfterPass && StartAfterCount++ == StartAfterInstanceNum) {
+ assert(!EnableNext && "Error: assign to EnableNext more than once");
+ EnableNext = true;
+ }
+ if (StopAfterPass && StopAfterCount++ == StopAfterInstanceNum) {
+ assert(!EnableNext && "Error: assign to EnableNext more than once");
+ EnableNext = false;
+ }
+
+ if (StartBeforePass && StartBeforeCount++ == StartBeforeInstanceNum)
+ EnableCurrent = true;
+ if (StopBeforePass && StopBeforeCount++ == StopBeforeInstanceNum)
+ EnableCurrent = false;
+ return EnableCurrent;
+ });
+}
+
+void llvm::registerCodeGenCallback(PassInstrumentationCallbacks &PIC,
+ LLVMTargetMachine &LLVMTM) {
+
+ // Register a callback for disabling passes.
+ PIC.registerShouldRunOptionalPassCallback([](StringRef P, Any) {
+
+#define DISABLE_PASS(Option, Name) \
+ if (Option && P.contains(#Name)) \
+ return false;
+ DISABLE_PASS(DisableBlockPlacement, MachineBlockPlacementPass)
+ DISABLE_PASS(DisableBranchFold, BranchFolderPass)
+ DISABLE_PASS(DisableCopyProp, MachineCopyPropagationPass)
+ DISABLE_PASS(DisableEarlyIfConversion, EarlyIfConverterPass)
+ DISABLE_PASS(DisableEarlyTailDup, EarlyTailDuplicatePass)
+ DISABLE_PASS(DisableMachineCSE, MachineCSEPass)
+ DISABLE_PASS(DisableMachineDCE, DeadMachineInstructionElimPass)
+ DISABLE_PASS(DisableMachineLICM, EarlyMachineLICMPass)
+ DISABLE_PASS(DisableMachineSink, MachineSinkingPass)
+ DISABLE_PASS(DisablePostRAMachineLICM, MachineLICMPass)
+ DISABLE_PASS(DisablePostRAMachineSink, PostRAMachineSinkingPass)
+ DISABLE_PASS(DisablePostRASched, PostRASchedulerPass)
+ DISABLE_PASS(DisableSSC, StackSlotColoringPass)
+ DISABLE_PASS(DisableTailDuplicate, TailDuplicatePass)
+
+ return true;
+ });
+
+ registerPartialPipelineCallback(PIC, LLVMTM);
+}
+
// Out of line constructor provides default values for pass options and
// registers all common codegen passes.
TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm)
@@ -592,13 +592,13 @@ CodeGenOpt::Level TargetPassConfig::getOptLevel() const {
/// Insert InsertedPassID pass after TargetPassID.
void TargetPassConfig::insertPass(AnalysisID TargetPassID,
IdentifyingPassPtr InsertedPassID,
- bool VerifyAfter) {
+ bool VerifyAfter) {
assert(((!InsertedPassID.isInstance() &&
TargetPassID != InsertedPassID.getID()) ||
(InsertedPassID.isInstance() &&
TargetPassID != InsertedPassID.getInstance()->getPassID())) &&
"Insert a pass after itself!");
- Impl->InsertedPasses.emplace_back(TargetPassID, InsertedPassID, VerifyAfter);
+ Impl->InsertedPasses.emplace_back(TargetPassID, InsertedPassID, VerifyAfter);
}
/// createPassConfig - Create a pass configuration object to be used by
@@ -676,7 +676,7 @@ bool TargetPassConfig::isPassSubstitutedOrOverridden(AnalysisID ID) const {
/// a later pass or that it should stop after an earlier pass, then do not add
/// the pass. Finally, compare the current pass against the StartAfter
/// and StopAfter options and change the Started/Stopped flags accordingly.
-void TargetPassConfig::addPass(Pass *P, bool verifyAfter) {
+void TargetPassConfig::addPass(Pass *P, bool verifyAfter) {
assert(!Initialized && "PassConfig is immutable");
// Cache the Pass ID here in case the pass manager finds this pass is
@@ -694,16 +694,16 @@ void TargetPassConfig::addPass(Pass *P, bool verifyAfter) {
addMachinePrePasses();
std::string Banner;
// Construct banner message before PM->add() as that may delete the pass.
- if (AddingMachinePasses && verifyAfter)
+ if (AddingMachinePasses && verifyAfter)
Banner = std::string("After ") + std::string(P->getPassName());
PM->add(P);
if (AddingMachinePasses)
- addMachinePostPasses(Banner, /*AllowVerify*/ verifyAfter);
+ addMachinePostPasses(Banner, /*AllowVerify*/ verifyAfter);
// Add the passes after the pass P if there is any.
- for (const auto &IP : Impl->InsertedPasses) {
+ for (const auto &IP : Impl->InsertedPasses) {
if (IP.TargetPassID == PassID)
- addPass(IP.getInsertedPass(), IP.VerifyAfter);
+ addPass(IP.getInsertedPass(), IP.VerifyAfter);
}
} else {
delete P;
@@ -723,7 +723,7 @@ void TargetPassConfig::addPass(Pass *P, bool verifyAfter) {
///
/// addPass cannot return a pointer to the pass instance because is internal the
/// PassManager and the instance we create here may already be freed.
-AnalysisID TargetPassConfig::addPass(AnalysisID PassID, bool verifyAfter) {
+AnalysisID TargetPassConfig::addPass(AnalysisID PassID, bool verifyAfter) {
IdentifyingPassPtr TargetID = getPassSubstitution(PassID);
IdentifyingPassPtr FinalPtr = overridePass(PassID, TargetID);
if (!FinalPtr.isValid())
@@ -738,7 +738,7 @@ AnalysisID TargetPassConfig::addPass(AnalysisID PassID, bool verifyAfter) {
llvm_unreachable("Pass ID not registered");
}
AnalysisID FinalID = P->getPassID();
- addPass(P, verifyAfter); // Ends the lifetime of P.
+ addPass(P, verifyAfter); // Ends the lifetime of P.
return FinalID;
}
@@ -749,7 +749,7 @@ void TargetPassConfig::printAndVerify(const std::string &Banner) {
}
void TargetPassConfig::addPrintPass(const std::string &Banner) {
- if (PrintAfterISel)
+ if (PrintAfterISel)
PM->add(createMachineFunctionPrinterPass(dbgs(), Banner));
}
@@ -771,26 +771,26 @@ void TargetPassConfig::addStripDebugPass() {
PM->add(createStripDebugMachineModulePass(/*OnlyDebugified=*/true));
}
-void TargetPassConfig::addCheckDebugPass() {
- PM->add(createCheckDebugMachineModulePass());
-}
-
+void TargetPassConfig::addCheckDebugPass() {
+ PM->add(createCheckDebugMachineModulePass());
+}
+
void TargetPassConfig::addMachinePrePasses(bool AllowDebugify) {
- if (AllowDebugify && DebugifyIsSafe &&
- (DebugifyAndStripAll == cl::BOU_TRUE ||
- DebugifyCheckAndStripAll == cl::BOU_TRUE))
+ if (AllowDebugify && DebugifyIsSafe &&
+ (DebugifyAndStripAll == cl::BOU_TRUE ||
+ DebugifyCheckAndStripAll == cl::BOU_TRUE))
addDebugifyPass();
}
void TargetPassConfig::addMachinePostPasses(const std::string &Banner,
- bool AllowVerify, bool AllowStrip) {
- if (DebugifyIsSafe) {
- if (DebugifyCheckAndStripAll == cl::BOU_TRUE) {
- addCheckDebugPass();
- addStripDebugPass();
- } else if (DebugifyAndStripAll == cl::BOU_TRUE)
- addStripDebugPass();
- }
+ bool AllowVerify, bool AllowStrip) {
+ if (DebugifyIsSafe) {
+ if (DebugifyCheckAndStripAll == cl::BOU_TRUE) {
+ addCheckDebugPass();
+ addStripDebugPass();
+ } else if (DebugifyAndStripAll == cl::BOU_TRUE)
+ addStripDebugPass();
+ }
if (AllowVerify)
addVerifyPass(Banner);
}
@@ -867,12 +867,12 @@ void TargetPassConfig::addIRPasses() {
// Add scalarization of target's unsupported masked memory intrinsics pass.
// the unsupported intrinsic will be replaced with a chain of basic blocks,
// that stores/loads element one-by-one if the appropriate mask bit is set.
- addPass(createScalarizeMaskedMemIntrinLegacyPass());
+ addPass(createScalarizeMaskedMemIntrinLegacyPass());
// Expand reduction intrinsics into shuffle sequences if the target wants to.
- // Allow disabling it for testing purposes.
- if (!DisableExpandReductions)
- addPass(createExpandReductionsPass());
+ // Allow disabling it for testing purposes.
+ if (!DisableExpandReductions)
+ addPass(createExpandReductionsPass());
}
/// Turn exception handling constructs into something the code generators can
@@ -892,7 +892,7 @@ void TargetPassConfig::addPassesToHandleExceptions() {
LLVM_FALLTHROUGH;
case ExceptionHandling::DwarfCFI:
case ExceptionHandling::ARM:
- case ExceptionHandling::AIX:
+ case ExceptionHandling::AIX:
addPass(createDwarfEHPass(getOptLevel()));
break;
case ExceptionHandling::WinEH:
@@ -1042,7 +1042,7 @@ bool TargetPassConfig::addISelPasses() {
addPass(createLowerEmuTLSPass());
addPass(createPreISelIntrinsicLoweringPass());
- PM->add(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));
+ PM->add(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));
addIRPasses();
addCodeGenPrepare();
addPassesToHandleExceptions();
@@ -1149,7 +1149,7 @@ void TargetPassConfig::addMachinePasses() {
// GC
if (addGCPasses()) {
if (PrintGCInfo)
- addPass(createGCInfoPrinter(dbgs()), false);
+ addPass(createGCInfoPrinter(dbgs()), false);
}
// Basic block placement.
@@ -1177,31 +1177,31 @@ void TargetPassConfig::addMachinePasses() {
addPass(&LiveDebugValuesID, false);
if (TM->Options.EnableMachineOutliner && getOptLevel() != CodeGenOpt::None &&
- EnableMachineOutliner != RunOutliner::NeverOutline) {
- bool RunOnAllFunctions =
- (EnableMachineOutliner == RunOutliner::AlwaysOutline);
- bool AddOutliner =
- RunOnAllFunctions || TM->Options.SupportsDefaultOutlining;
+ EnableMachineOutliner != RunOutliner::NeverOutline) {
+ bool RunOnAllFunctions =
+ (EnableMachineOutliner == RunOutliner::AlwaysOutline);
+ bool AddOutliner =
+ RunOnAllFunctions || TM->Options.SupportsDefaultOutlining;
if (AddOutliner)
addPass(createMachineOutlinerPass(RunOnAllFunctions));
}
- // Machine function splitter uses the basic block sections feature. Both
- // cannot be enabled at the same time.
- if (TM->Options.EnableMachineFunctionSplitter ||
- EnableMachineFunctionSplitter) {
- addPass(createMachineFunctionSplitterPass());
- } else if (TM->getBBSectionsType() != llvm::BasicBlockSection::None) {
- addPass(llvm::createBasicBlockSectionsPass(TM->getBBSectionsFuncListBuf()));
- }
+ // Machine function splitter uses the basic block sections feature. Both
+ // cannot be enabled at the same time.
+ if (TM->Options.EnableMachineFunctionSplitter ||
+ EnableMachineFunctionSplitter) {
+ addPass(createMachineFunctionSplitterPass());
+ } else if (TM->getBBSectionsType() != llvm::BasicBlockSection::None) {
+ addPass(llvm::createBasicBlockSectionsPass(TM->getBBSectionsFuncListBuf()));
+ }
// Add passes that directly emit MI after all other MI passes.
addPreEmitPass2();
- // Insert pseudo probe annotation for callsite profiling
- if (TM->Options.PseudoProbeForProfiling)
- addPass(createPseudoProbeInserter());
-
+ // Insert pseudo probe annotation for callsite profiling
+ if (TM->Options.PseudoProbeForProfiling)
+ addPass(createPseudoProbeInserter());
+
AddingMachinePasses = false;
}
@@ -1308,7 +1308,7 @@ FunctionPass *TargetPassConfig::createRegAllocPass(bool Optimized) {
return createTargetRegisterAllocator(Optimized);
}
-bool TargetPassConfig::addRegAssignAndRewriteFast() {
+bool TargetPassConfig::addRegAssignAndRewriteFast() {
if (RegAlloc != &useDefaultRegisterAllocator &&
RegAlloc != &createFastRegisterAllocator)
report_fatal_error("Must use fast (default) register allocator for unoptimized regalloc.");
@@ -1317,7 +1317,7 @@ bool TargetPassConfig::addRegAssignAndRewriteFast() {
return true;
}
-bool TargetPassConfig::addRegAssignAndRewriteOptimized() {
+bool TargetPassConfig::addRegAssignAndRewriteOptimized() {
// Add the selected register allocation pass.
addPass(createRegAllocPass(true));
@@ -1342,7 +1342,7 @@ void TargetPassConfig::addFastRegAlloc() {
addPass(&PHIEliminationID, false);
addPass(&TwoAddressInstructionPassID, false);
- addRegAssignAndRewriteFast();
+ addRegAssignAndRewriteFast();
}
/// Add standard target-independent passes that are tightly coupled with
@@ -1359,11 +1359,11 @@ void TargetPassConfig::addOptimizedRegAlloc() {
// LiveVariables can be removed completely, and LiveIntervals can be directly
// computed. (We still either need to regenerate kill flags after regalloc, or
// preferably fix the scavenger to not depend on them).
- // FIXME: UnreachableMachineBlockElim is a dependant pass of LiveVariables.
- // When LiveVariables is removed this has to be removed/moved either.
- // Explicit addition of UnreachableMachineBlockElim allows stopping before or
- // after it with -stop-before/-stop-after.
- addPass(&UnreachableMachineBlockElimID, false);
+ // FIXME: UnreachableMachineBlockElim is a dependant pass of LiveVariables.
+ // When LiveVariables is removed this has to be removed/moved either.
+ // Explicit addition of UnreachableMachineBlockElim allows stopping before or
+ // after it with -stop-before/-stop-after.
+ addPass(&UnreachableMachineBlockElimID, false);
addPass(&LiveVariablesID, false);
// Edge splitting is smarter with machine loop info.
@@ -1385,13 +1385,13 @@ void TargetPassConfig::addOptimizedRegAlloc() {
// PreRA instruction scheduling.
addPass(&MachineSchedulerID);
- if (addRegAssignAndRewriteOptimized()) {
- // Perform stack slot coloring and post-ra machine LICM.
- //
- // FIXME: Re-enable coloring with register when it's capable of adding
- // kill markers.
- addPass(&StackSlotColoringID);
-
+ if (addRegAssignAndRewriteOptimized()) {
+ // Perform stack slot coloring and post-ra machine LICM.
+ //
+ // FIXME: Re-enable coloring with register when it's capable of adding
+ // kill markers.
+ addPass(&StackSlotColoringID);
+
// Allow targets to expand pseudo instructions depending on the choice of
// registers before MachineCopyPropagation.
addPostRewrite();
diff --git a/contrib/libs/llvm12/lib/CodeGen/TargetRegisterInfo.cpp b/contrib/libs/llvm12/lib/CodeGen/TargetRegisterInfo.cpp
index 1dbf0c43b6..5fd7eef580 100644
--- a/contrib/libs/llvm12/lib/CodeGen/TargetRegisterInfo.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/TargetRegisterInfo.cpp
@@ -26,7 +26,7 @@
#include "llvm/CodeGen/VirtRegMap.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Attributes.h"
-#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Function.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
@@ -69,7 +69,7 @@ bool TargetRegisterInfo::shouldRegionSplitForVirtReg(
const MachineFunction &MF, const LiveInterval &VirtReg) const {
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
const MachineRegisterInfo &MRI = MF.getRegInfo();
- MachineInstr *MI = MRI.getUniqueVRegDef(VirtReg.reg());
+ MachineInstr *MI = MRI.getUniqueVRegDef(VirtReg.reg());
if (MI && TII->isTriviallyReMaterializable(*MI) &&
VirtReg.size() > HugeSizeForSplit)
return false;
@@ -533,56 +533,56 @@ TargetRegisterInfo::lookThruCopyLike(Register SrcReg,
}
}
-Register TargetRegisterInfo::lookThruSingleUseCopyChain(
- Register SrcReg, const MachineRegisterInfo *MRI) const {
- while (true) {
- const MachineInstr *MI = MRI->getVRegDef(SrcReg);
- // Found the real definition, return it if it has a single use.
- if (!MI->isCopyLike())
- return MRI->hasOneNonDBGUse(SrcReg) ? SrcReg : Register();
-
- Register CopySrcReg;
- if (MI->isCopy())
- CopySrcReg = MI->getOperand(1).getReg();
- else {
- assert(MI->isSubregToReg() && "Bad opcode for lookThruCopyLike");
- CopySrcReg = MI->getOperand(2).getReg();
- }
-
- // Continue only if the next definition in the chain is for a virtual
- // register that has a single use.
- if (!CopySrcReg.isVirtual() || !MRI->hasOneNonDBGUse(CopySrcReg))
- return Register();
-
- SrcReg = CopySrcReg;
- }
-}
-
-void TargetRegisterInfo::getOffsetOpcodes(
- const StackOffset &Offset, SmallVectorImpl<uint64_t> &Ops) const {
- assert(!Offset.getScalable() && "Scalable offsets are not handled");
- DIExpression::appendOffset(Ops, Offset.getFixed());
-}
-
-DIExpression *
-TargetRegisterInfo::prependOffsetExpression(const DIExpression *Expr,
- unsigned PrependFlags,
- const StackOffset &Offset) const {
- assert((PrependFlags &
- ~(DIExpression::DerefBefore | DIExpression::DerefAfter |
- DIExpression::StackValue | DIExpression::EntryValue)) == 0 &&
- "Unsupported prepend flag");
- SmallVector<uint64_t, 16> OffsetExpr;
- if (PrependFlags & DIExpression::DerefBefore)
- OffsetExpr.push_back(dwarf::DW_OP_deref);
- getOffsetOpcodes(Offset, OffsetExpr);
- if (PrependFlags & DIExpression::DerefAfter)
- OffsetExpr.push_back(dwarf::DW_OP_deref);
- return DIExpression::prependOpcodes(Expr, OffsetExpr,
- PrependFlags & DIExpression::StackValue,
- PrependFlags & DIExpression::EntryValue);
-}
-
+Register TargetRegisterInfo::lookThruSingleUseCopyChain(
+ Register SrcReg, const MachineRegisterInfo *MRI) const {
+ while (true) {
+ const MachineInstr *MI = MRI->getVRegDef(SrcReg);
+ // Found the real definition, return it if it has a single use.
+ if (!MI->isCopyLike())
+ return MRI->hasOneNonDBGUse(SrcReg) ? SrcReg : Register();
+
+ Register CopySrcReg;
+ if (MI->isCopy())
+ CopySrcReg = MI->getOperand(1).getReg();
+ else {
+ assert(MI->isSubregToReg() && "Bad opcode for lookThruCopyLike");
+ CopySrcReg = MI->getOperand(2).getReg();
+ }
+
+ // Continue only if the next definition in the chain is for a virtual
+ // register that has a single use.
+ if (!CopySrcReg.isVirtual() || !MRI->hasOneNonDBGUse(CopySrcReg))
+ return Register();
+
+ SrcReg = CopySrcReg;
+ }
+}
+
+void TargetRegisterInfo::getOffsetOpcodes(
+ const StackOffset &Offset, SmallVectorImpl<uint64_t> &Ops) const {
+ assert(!Offset.getScalable() && "Scalable offsets are not handled");
+ DIExpression::appendOffset(Ops, Offset.getFixed());
+}
+
+DIExpression *
+TargetRegisterInfo::prependOffsetExpression(const DIExpression *Expr,
+ unsigned PrependFlags,
+ const StackOffset &Offset) const {
+ assert((PrependFlags &
+ ~(DIExpression::DerefBefore | DIExpression::DerefAfter |
+ DIExpression::StackValue | DIExpression::EntryValue)) == 0 &&
+ "Unsupported prepend flag");
+ SmallVector<uint64_t, 16> OffsetExpr;
+ if (PrependFlags & DIExpression::DerefBefore)
+ OffsetExpr.push_back(dwarf::DW_OP_deref);
+ getOffsetOpcodes(Offset, OffsetExpr);
+ if (PrependFlags & DIExpression::DerefAfter)
+ OffsetExpr.push_back(dwarf::DW_OP_deref);
+ return DIExpression::prependOpcodes(Expr, OffsetExpr,
+ PrependFlags & DIExpression::StackValue,
+ PrependFlags & DIExpression::EntryValue);
+}
+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD
void TargetRegisterInfo::dumpReg(Register Reg, unsigned SubRegIndex,
diff --git a/contrib/libs/llvm12/lib/CodeGen/TargetSubtargetInfo.cpp b/contrib/libs/llvm12/lib/CodeGen/TargetSubtargetInfo.cpp
index 24890661e6..e4520d8ccb 100644
--- a/contrib/libs/llvm12/lib/CodeGen/TargetSubtargetInfo.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/TargetSubtargetInfo.cpp
@@ -15,12 +15,12 @@
using namespace llvm;
TargetSubtargetInfo::TargetSubtargetInfo(
- const Triple &TT, StringRef CPU, StringRef TuneCPU, StringRef FS,
+ const Triple &TT, StringRef CPU, StringRef TuneCPU, StringRef FS,
ArrayRef<SubtargetFeatureKV> PF, ArrayRef<SubtargetSubTypeKV> PD,
- const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL,
- const MCReadAdvanceEntry *RA, const InstrStage *IS, const unsigned *OC,
- const unsigned *FP)
- : MCSubtargetInfo(TT, CPU, TuneCPU, FS, PF, PD, WPR, WL, RA, IS, OC, FP) {}
+ const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL,
+ const MCReadAdvanceEntry *RA, const InstrStage *IS, const unsigned *OC,
+ const unsigned *FP)
+ : MCSubtargetInfo(TT, CPU, TuneCPU, FS, PF, PD, WPR, WL, RA, IS, OC, FP) {}
TargetSubtargetInfo::~TargetSubtargetInfo() = default;
diff --git a/contrib/libs/llvm12/lib/CodeGen/TwoAddressInstructionPass.cpp b/contrib/libs/llvm12/lib/CodeGen/TwoAddressInstructionPass.cpp
index 26fe0b254b..2a9132bd2f 100644
--- a/contrib/libs/llvm12/lib/CodeGen/TwoAddressInstructionPass.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/TwoAddressInstructionPass.cpp
@@ -111,35 +111,35 @@ class TwoAddressInstructionPass : public MachineFunctionPass {
// A map from virtual registers to physical registers which are likely targets
// to be coalesced to due to copies from physical registers to virtual
// registers. e.g. v1024 = move r0.
- DenseMap<Register, Register> SrcRegMap;
+ DenseMap<Register, Register> SrcRegMap;
// A map from virtual registers to physical registers which are likely targets
// to be coalesced to due to copies to physical registers from virtual
// registers. e.g. r1 = move v1024.
- DenseMap<Register, Register> DstRegMap;
+ DenseMap<Register, Register> DstRegMap;
- bool isRevCopyChain(Register FromReg, Register ToReg, int Maxlen);
+ bool isRevCopyChain(Register FromReg, Register ToReg, int Maxlen);
- bool noUseAfterLastDef(Register Reg, unsigned Dist, unsigned &LastDef);
+ bool noUseAfterLastDef(Register Reg, unsigned Dist, unsigned &LastDef);
- bool isProfitableToCommute(Register RegA, Register RegB, Register RegC,
+ bool isProfitableToCommute(Register RegA, Register RegB, Register RegC,
MachineInstr *MI, unsigned Dist);
bool commuteInstruction(MachineInstr *MI, unsigned DstIdx,
unsigned RegBIdx, unsigned RegCIdx, unsigned Dist);
- bool isProfitableToConv3Addr(Register RegA, Register RegB);
+ bool isProfitableToConv3Addr(Register RegA, Register RegB);
bool convertInstTo3Addr(MachineBasicBlock::iterator &mi,
- MachineBasicBlock::iterator &nmi, Register RegA,
- Register RegB, unsigned Dist);
+ MachineBasicBlock::iterator &nmi, Register RegA,
+ Register RegB, unsigned Dist);
- bool isDefTooClose(Register Reg, unsigned Dist, MachineInstr *MI);
+ bool isDefTooClose(Register Reg, unsigned Dist, MachineInstr *MI);
bool rescheduleMIBelowKill(MachineBasicBlock::iterator &mi,
- MachineBasicBlock::iterator &nmi, Register Reg);
+ MachineBasicBlock::iterator &nmi, Register Reg);
bool rescheduleKillAboveMI(MachineBasicBlock::iterator &mi,
- MachineBasicBlock::iterator &nmi, Register Reg);
+ MachineBasicBlock::iterator &nmi, Register Reg);
bool tryInstructionTransform(MachineBasicBlock::iterator &mi,
MachineBasicBlock::iterator &nmi,
@@ -151,7 +151,7 @@ class TwoAddressInstructionPass : public MachineFunctionPass {
unsigned BaseOpIdx,
bool BaseOpKilled,
unsigned Dist);
- void scanUses(Register DstReg);
+ void scanUses(Register DstReg);
void processCopy(MachineInstr *MI);
@@ -197,10 +197,10 @@ INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_END(TwoAddressInstructionPass, DEBUG_TYPE,
"Two-Address instruction pass", false, false)
-static bool isPlainlyKilled(MachineInstr *MI, Register Reg, LiveIntervals *LIS);
+static bool isPlainlyKilled(MachineInstr *MI, Register Reg, LiveIntervals *LIS);
/// Return the MachineInstr* if it is the single def of the Reg in current BB.
-static MachineInstr *getSingleDef(Register Reg, MachineBasicBlock *BB,
+static MachineInstr *getSingleDef(Register Reg, MachineBasicBlock *BB,
const MachineRegisterInfo *MRI) {
MachineInstr *Ret = nullptr;
for (MachineInstr &DefMI : MRI->def_instructions(Reg)) {
@@ -221,9 +221,9 @@ static MachineInstr *getSingleDef(Register Reg, MachineBasicBlock *BB,
/// %Tmp2 = copy %ToReg;
/// MaxLen specifies the maximum length of the copy chain the func
/// can walk through.
-bool TwoAddressInstructionPass::isRevCopyChain(Register FromReg, Register ToReg,
+bool TwoAddressInstructionPass::isRevCopyChain(Register FromReg, Register ToReg,
int Maxlen) {
- Register TmpReg = FromReg;
+ Register TmpReg = FromReg;
for (int i = 0; i < Maxlen; i++) {
MachineInstr *Def = getSingleDef(TmpReg, MBB, MRI);
if (!Def || !Def->isCopy())
@@ -241,7 +241,7 @@ bool TwoAddressInstructionPass::isRevCopyChain(Register FromReg, Register ToReg,
/// in the MBB that defines the specified register and the two-address
/// instruction which is being processed. It also returns the last def location
/// by reference.
-bool TwoAddressInstructionPass::noUseAfterLastDef(Register Reg, unsigned Dist,
+bool TwoAddressInstructionPass::noUseAfterLastDef(Register Reg, unsigned Dist,
unsigned &LastDef) {
LastDef = 0;
unsigned LastUse = Dist;
@@ -265,8 +265,8 @@ bool TwoAddressInstructionPass::noUseAfterLastDef(Register Reg, unsigned Dist,
/// instruction. It also returns the source and destination registers and
/// whether they are physical registers by reference.
static bool isCopyToReg(MachineInstr &MI, const TargetInstrInfo *TII,
- Register &SrcReg, Register &DstReg, bool &IsSrcPhys,
- bool &IsDstPhys) {
+ Register &SrcReg, Register &DstReg, bool &IsSrcPhys,
+ bool &IsDstPhys) {
SrcReg = 0;
DstReg = 0;
if (MI.isCopy()) {
@@ -275,20 +275,20 @@ static bool isCopyToReg(MachineInstr &MI, const TargetInstrInfo *TII,
} else if (MI.isInsertSubreg() || MI.isSubregToReg()) {
DstReg = MI.getOperand(0).getReg();
SrcReg = MI.getOperand(2).getReg();
- } else {
+ } else {
return false;
- }
+ }
- IsSrcPhys = SrcReg.isPhysical();
- IsDstPhys = DstReg.isPhysical();
+ IsSrcPhys = SrcReg.isPhysical();
+ IsDstPhys = DstReg.isPhysical();
return true;
}
/// Test if the given register value, which is used by the
/// given instruction, is killed by the given instruction.
-static bool isPlainlyKilled(MachineInstr *MI, Register Reg,
+static bool isPlainlyKilled(MachineInstr *MI, Register Reg,
LiveIntervals *LIS) {
- if (LIS && Reg.isVirtual() && !LIS->isNotInMIMap(*MI)) {
+ if (LIS && Reg.isVirtual() && !LIS->isNotInMIMap(*MI)) {
// FIXME: Sometimes tryInstructionTransform() will add instructions and
// test whether they can be folded before keeping them. In this case it
// sets a kill before recursively calling tryInstructionTransform() again.
@@ -327,17 +327,17 @@ static bool isPlainlyKilled(MachineInstr *MI, Register Reg,
///
/// If allowFalsePositives is true then likely kills are treated as kills even
/// if it can't be proven that they are kills.
-static bool isKilled(MachineInstr &MI, Register Reg,
- const MachineRegisterInfo *MRI, const TargetInstrInfo *TII,
- LiveIntervals *LIS, bool allowFalsePositives) {
+static bool isKilled(MachineInstr &MI, Register Reg,
+ const MachineRegisterInfo *MRI, const TargetInstrInfo *TII,
+ LiveIntervals *LIS, bool allowFalsePositives) {
MachineInstr *DefMI = &MI;
while (true) {
// All uses of physical registers are likely to be kills.
- if (Reg.isPhysical() && (allowFalsePositives || MRI->hasOneUse(Reg)))
+ if (Reg.isPhysical() && (allowFalsePositives || MRI->hasOneUse(Reg)))
return true;
if (!isPlainlyKilled(DefMI, Reg, LIS))
return false;
- if (Reg.isPhysical())
+ if (Reg.isPhysical())
return true;
MachineRegisterInfo::def_iterator Begin = MRI->def_begin(Reg);
// If there are multiple defs, we can't do a simple analysis, so just
@@ -346,7 +346,7 @@ static bool isKilled(MachineInstr &MI, Register Reg,
return true;
DefMI = Begin->getParent();
bool IsSrcPhys, IsDstPhys;
- Register SrcReg, DstReg;
+ Register SrcReg, DstReg;
// If the def is something other than a copy, then it isn't going to
// be coalesced, so follow the kill flag.
if (!isCopyToReg(*DefMI, TII, SrcReg, DstReg, IsSrcPhys, IsDstPhys))
@@ -357,7 +357,7 @@ static bool isKilled(MachineInstr &MI, Register Reg,
/// Return true if the specified MI uses the specified register as a two-address
/// use. If so, return the destination register by reference.
-static bool isTwoAddrUse(MachineInstr &MI, Register Reg, Register &DstReg) {
+static bool isTwoAddrUse(MachineInstr &MI, Register Reg, Register &DstReg) {
for (unsigned i = 0, NumOps = MI.getNumOperands(); i != NumOps; ++i) {
const MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg() || !MO.isUse() || MO.getReg() != Reg)
@@ -373,17 +373,17 @@ static bool isTwoAddrUse(MachineInstr &MI, Register Reg, Register &DstReg) {
/// Given a register, if has a single in-basic block use, return the use
/// instruction if it's a copy or a two-address use.
-static MachineInstr *
-findOnlyInterestingUse(Register Reg, MachineBasicBlock *MBB,
- MachineRegisterInfo *MRI, const TargetInstrInfo *TII,
- bool &IsCopy, Register &DstReg, bool &IsDstPhys) {
+static MachineInstr *
+findOnlyInterestingUse(Register Reg, MachineBasicBlock *MBB,
+ MachineRegisterInfo *MRI, const TargetInstrInfo *TII,
+ bool &IsCopy, Register &DstReg, bool &IsDstPhys) {
if (!MRI->hasOneNonDBGUse(Reg))
// None or more than one use.
return nullptr;
MachineInstr &UseMI = *MRI->use_instr_nodbg_begin(Reg);
if (UseMI.getParent() != MBB)
return nullptr;
- Register SrcReg;
+ Register SrcReg;
bool IsSrcPhys;
if (isCopyToReg(UseMI, TII, SrcReg, DstReg, IsSrcPhys, IsDstPhys)) {
IsCopy = true;
@@ -391,7 +391,7 @@ findOnlyInterestingUse(Register Reg, MachineBasicBlock *MBB,
}
IsDstPhys = false;
if (isTwoAddrUse(UseMI, Reg, DstReg)) {
- IsDstPhys = DstReg.isPhysical();
+ IsDstPhys = DstReg.isPhysical();
return &UseMI;
}
return nullptr;
@@ -399,22 +399,22 @@ findOnlyInterestingUse(Register Reg, MachineBasicBlock *MBB,
/// Return the physical register the specified virtual register might be mapped
/// to.
-static MCRegister getMappedReg(Register Reg,
- DenseMap<Register, Register> &RegMap) {
- while (Reg.isVirtual()) {
- DenseMap<Register, Register>::iterator SI = RegMap.find(Reg);
+static MCRegister getMappedReg(Register Reg,
+ DenseMap<Register, Register> &RegMap) {
+ while (Reg.isVirtual()) {
+ DenseMap<Register, Register>::iterator SI = RegMap.find(Reg);
if (SI == RegMap.end())
return 0;
Reg = SI->second;
}
- if (Reg.isPhysical())
+ if (Reg.isPhysical())
return Reg;
return 0;
}
/// Return true if the two registers are equal or aliased.
-static bool regsAreCompatible(Register RegA, Register RegB,
- const TargetRegisterInfo *TRI) {
+static bool regsAreCompatible(Register RegA, Register RegB,
+ const TargetRegisterInfo *TRI) {
if (RegA == RegB)
return true;
if (!RegA || !RegB)
@@ -423,7 +423,7 @@ static bool regsAreCompatible(Register RegA, Register RegB,
}
// Returns true if Reg is equal or aliased to at least one register in Set.
-static bool regOverlapsSet(const SmallVectorImpl<Register> &Set, Register Reg,
+static bool regOverlapsSet(const SmallVectorImpl<Register> &Set, Register Reg,
const TargetRegisterInfo *TRI) {
for (unsigned R : Set)
if (TRI->regsOverlap(R, Reg))
@@ -434,11 +434,11 @@ static bool regOverlapsSet(const SmallVectorImpl<Register> &Set, Register Reg,
/// Return true if it's potentially profitable to commute the two-address
/// instruction that's being processed.
-bool TwoAddressInstructionPass::isProfitableToCommute(Register RegA,
- Register RegB,
- Register RegC,
- MachineInstr *MI,
- unsigned Dist) {
+bool TwoAddressInstructionPass::isProfitableToCommute(Register RegA,
+ Register RegB,
+ Register RegC,
+ MachineInstr *MI,
+ unsigned Dist) {
if (OptLevel == CodeGenOpt::None)
return false;
@@ -460,7 +460,7 @@ bool TwoAddressInstructionPass::isProfitableToCommute(Register RegA,
// insert => %reg1030 = COPY %reg1029
// %reg1030 = ADD8rr killed %reg1029, killed %reg1028, implicit dead %eflags
- if (!isPlainlyKilled(MI, RegC, LIS))
+ if (!isPlainlyKilled(MI, RegC, LIS))
return false;
// Ok, we have something like:
@@ -473,10 +473,10 @@ bool TwoAddressInstructionPass::isProfitableToCommute(Register RegA,
// %reg1026 = ADD %reg1024, %reg1025
// r0 = MOV %reg1026
// Commute the ADD to hopefully eliminate an otherwise unavoidable copy.
- MCRegister ToRegA = getMappedReg(RegA, DstRegMap);
+ MCRegister ToRegA = getMappedReg(RegA, DstRegMap);
if (ToRegA) {
- MCRegister FromRegB = getMappedReg(RegB, SrcRegMap);
- MCRegister FromRegC = getMappedReg(RegC, SrcRegMap);
+ MCRegister FromRegB = getMappedReg(RegB, SrcRegMap);
+ MCRegister FromRegC = getMappedReg(RegC, SrcRegMap);
bool CompB = FromRegB && regsAreCompatible(FromRegB, ToRegA, TRI);
bool CompC = FromRegC && regsAreCompatible(FromRegC, ToRegA, TRI);
@@ -494,16 +494,16 @@ bool TwoAddressInstructionPass::isProfitableToCommute(Register RegA,
return false;
}
- // If there is a use of RegC between its last def (could be livein) and this
+ // If there is a use of RegC between its last def (could be livein) and this
// instruction, then bail.
unsigned LastDefC = 0;
- if (!noUseAfterLastDef(RegC, Dist, LastDefC))
+ if (!noUseAfterLastDef(RegC, Dist, LastDefC))
return false;
- // If there is a use of RegB between its last def (could be livein) and this
+ // If there is a use of RegB between its last def (could be livein) and this
// instruction, then go ahead and make this transformation.
unsigned LastDefB = 0;
- if (!noUseAfterLastDef(RegB, Dist, LastDefB))
+ if (!noUseAfterLastDef(RegB, Dist, LastDefB))
return true;
// Look for situation like this:
@@ -521,14 +521,14 @@ bool TwoAddressInstructionPass::isProfitableToCommute(Register RegA,
// To more generally minimize register copies, ideally the logic of two addr
// instruction pass should be integrated with register allocation pass where
// interference graph is available.
- if (isRevCopyChain(RegC, RegA, MaxDataFlowEdge))
+ if (isRevCopyChain(RegC, RegA, MaxDataFlowEdge))
return true;
- if (isRevCopyChain(RegB, RegA, MaxDataFlowEdge))
+ if (isRevCopyChain(RegB, RegA, MaxDataFlowEdge))
return false;
// Since there are no intervening uses for both registers, then commute
- // if the def of RegC is closer. Its live interval is shorter.
+ // if the def of RegC is closer. Its live interval is shorter.
return LastDefB && LastDefC && LastDefC > LastDefB;
}
@@ -554,7 +554,7 @@ bool TwoAddressInstructionPass::commuteInstruction(MachineInstr *MI,
"instruction unless it was requested.");
// Update source register map.
- MCRegister FromRegC = getMappedReg(RegC, SrcRegMap);
+ MCRegister FromRegC = getMappedReg(RegC, SrcRegMap);
if (FromRegC) {
Register RegA = MI->getOperand(DstIdx).getReg();
SrcRegMap[RegA] = FromRegC;
@@ -565,26 +565,26 @@ bool TwoAddressInstructionPass::commuteInstruction(MachineInstr *MI,
/// Return true if it is profitable to convert the given 2-address instruction
/// to a 3-address one.
-bool TwoAddressInstructionPass::isProfitableToConv3Addr(Register RegA,
- Register RegB) {
+bool TwoAddressInstructionPass::isProfitableToConv3Addr(Register RegA,
+ Register RegB) {
// Look for situations like this:
// %reg1024 = MOV r1
// %reg1025 = MOV r0
// %reg1026 = ADD %reg1024, %reg1025
// r2 = MOV %reg1026
// Turn ADD into a 3-address instruction to avoid a copy.
- MCRegister FromRegB = getMappedReg(RegB, SrcRegMap);
+ MCRegister FromRegB = getMappedReg(RegB, SrcRegMap);
if (!FromRegB)
return false;
- MCRegister ToRegA = getMappedReg(RegA, DstRegMap);
+ MCRegister ToRegA = getMappedReg(RegA, DstRegMap);
return (ToRegA && !regsAreCompatible(FromRegB, ToRegA, TRI));
}
/// Convert the specified two-address instruction into a three address one.
/// Return true if this transformation was successful.
-bool TwoAddressInstructionPass::convertInstTo3Addr(
- MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi,
- Register RegA, Register RegB, unsigned Dist) {
+bool TwoAddressInstructionPass::convertInstTo3Addr(
+ MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi,
+ Register RegA, Register RegB, unsigned Dist) {
// FIXME: Why does convertToThreeAddress() need an iterator reference?
MachineFunction::iterator MFI = MBB->getIterator();
MachineInstr *NewMI = TII->convertToThreeAddress(MFI, *mi, LV);
@@ -599,24 +599,24 @@ bool TwoAddressInstructionPass::convertInstTo3Addr(
if (LIS)
LIS->ReplaceMachineInstrInMaps(*mi, *NewMI);
- // If the old instruction is debug value tracked, an update is required.
- if (auto OldInstrNum = mi->peekDebugInstrNum()) {
- // Sanity check.
- assert(mi->getNumExplicitDefs() == 1);
- assert(NewMI->getNumExplicitDefs() == 1);
-
- // Find the old and new def location.
- auto OldIt = mi->defs().begin();
- auto NewIt = NewMI->defs().begin();
- unsigned OldIdx = mi->getOperandNo(OldIt);
- unsigned NewIdx = NewMI->getOperandNo(NewIt);
-
- // Record that one def has been replaced by the other.
- unsigned NewInstrNum = NewMI->getDebugInstrNum();
- MF->makeDebugValueSubstitution(std::make_pair(OldInstrNum, OldIdx),
- std::make_pair(NewInstrNum, NewIdx));
- }
-
+ // If the old instruction is debug value tracked, an update is required.
+ if (auto OldInstrNum = mi->peekDebugInstrNum()) {
+ // Sanity check.
+ assert(mi->getNumExplicitDefs() == 1);
+ assert(NewMI->getNumExplicitDefs() == 1);
+
+ // Find the old and new def location.
+ auto OldIt = mi->defs().begin();
+ auto NewIt = NewMI->defs().begin();
+ unsigned OldIdx = mi->getOperandNo(OldIt);
+ unsigned NewIdx = NewMI->getOperandNo(NewIt);
+
+ // Record that one def has been replaced by the other.
+ unsigned NewInstrNum = NewMI->getDebugInstrNum();
+ MF->makeDebugValueSubstitution(std::make_pair(OldInstrNum, OldIdx),
+ std::make_pair(NewInstrNum, NewIdx));
+ }
+
MBB->erase(mi); // Nuke the old inst.
DistanceMap.insert(std::make_pair(NewMI, Dist));
@@ -631,12 +631,12 @@ bool TwoAddressInstructionPass::convertInstTo3Addr(
/// Scan forward recursively for only uses, update maps if the use is a copy or
/// a two-address instruction.
-void TwoAddressInstructionPass::scanUses(Register DstReg) {
- SmallVector<Register, 4> VirtRegPairs;
+void TwoAddressInstructionPass::scanUses(Register DstReg) {
+ SmallVector<Register, 4> VirtRegPairs;
bool IsDstPhys;
bool IsCopy = false;
- Register NewReg;
- Register Reg = DstReg;
+ Register NewReg;
+ Register Reg = DstReg;
while (MachineInstr *UseMI = findOnlyInterestingUse(Reg, MBB, MRI, TII,IsCopy,
NewReg, IsDstPhys)) {
if (IsCopy && !Processed.insert(UseMI).second)
@@ -692,13 +692,13 @@ void TwoAddressInstructionPass::processCopy(MachineInstr *MI) {
return;
bool IsSrcPhys, IsDstPhys;
- Register SrcReg, DstReg;
+ Register SrcReg, DstReg;
if (!isCopyToReg(*MI, TII, SrcReg, DstReg, IsSrcPhys, IsDstPhys))
return;
- if (IsDstPhys && !IsSrcPhys) {
+ if (IsDstPhys && !IsSrcPhys) {
DstRegMap.insert(std::make_pair(SrcReg, DstReg));
- } else if (!IsDstPhys && IsSrcPhys) {
+ } else if (!IsDstPhys && IsSrcPhys) {
bool isNew = SrcRegMap.insert(std::make_pair(DstReg, SrcReg)).second;
if (!isNew)
assert(SrcRegMap[DstReg] == SrcReg &&
@@ -713,9 +713,9 @@ void TwoAddressInstructionPass::processCopy(MachineInstr *MI) {
/// If there is one more local instruction that reads 'Reg' and it kills 'Reg,
/// consider moving the instruction below the kill instruction in order to
/// eliminate the need for the copy.
-bool TwoAddressInstructionPass::rescheduleMIBelowKill(
- MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi,
- Register Reg) {
+bool TwoAddressInstructionPass::rescheduleMIBelowKill(
+ MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi,
+ Register Reg) {
// Bail immediately if we don't have LV or LIS available. We use them to find
// kills efficiently.
if (!LV && !LIS)
@@ -752,7 +752,7 @@ bool TwoAddressInstructionPass::rescheduleMIBelowKill(
// Don't move pass calls, etc.
return false;
- Register DstReg;
+ Register DstReg;
if (isTwoAddrUse(*KillMI, Reg, DstReg))
return false;
@@ -764,9 +764,9 @@ bool TwoAddressInstructionPass::rescheduleMIBelowKill(
// FIXME: Needs more sophisticated heuristics.
return false;
- SmallVector<Register, 2> Uses;
- SmallVector<Register, 2> Kills;
- SmallVector<Register, 2> Defs;
+ SmallVector<Register, 2> Uses;
+ SmallVector<Register, 2> Kills;
+ SmallVector<Register, 2> Defs;
for (const MachineOperand &MO : MI->operands()) {
if (!MO.isReg())
continue;
@@ -801,8 +801,8 @@ bool TwoAddressInstructionPass::rescheduleMIBelowKill(
MachineBasicBlock::iterator KillPos = KillMI;
++KillPos;
for (MachineInstr &OtherMI : make_range(End, KillPos)) {
- // Debug or pseudo instructions cannot be counted against the limit.
- if (OtherMI.isDebugOrPseudoInstr())
+ // Debug or pseudo instructions cannot be counted against the limit.
+ if (OtherMI.isDebugOrPseudoInstr())
continue;
if (NumVisited > 10) // FIXME: Arbitrary limit to reduce compile time cost.
return false;
@@ -881,7 +881,7 @@ bool TwoAddressInstructionPass::rescheduleMIBelowKill(
/// Return true if the re-scheduling will put the given instruction too close
/// to the defs of its register dependencies.
-bool TwoAddressInstructionPass::isDefTooClose(Register Reg, unsigned Dist,
+bool TwoAddressInstructionPass::isDefTooClose(Register Reg, unsigned Dist,
MachineInstr *MI) {
for (MachineInstr &DefMI : MRI->def_instructions(Reg)) {
if (DefMI.getParent() != MBB || DefMI.isCopy() || DefMI.isCopyLike())
@@ -902,9 +902,9 @@ bool TwoAddressInstructionPass::isDefTooClose(Register Reg, unsigned Dist,
/// If there is one more local instruction that reads 'Reg' and it kills 'Reg,
/// consider moving the kill instruction above the current two-address
/// instruction in order to eliminate the need for the copy.
-bool TwoAddressInstructionPass::rescheduleKillAboveMI(
- MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi,
- Register Reg) {
+bool TwoAddressInstructionPass::rescheduleKillAboveMI(
+ MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi,
+ Register Reg) {
// Bail immediately if we don't have LV or LIS available. We use them to find
// kills efficiently.
if (!LV && !LIS)
@@ -936,7 +936,7 @@ bool TwoAddressInstructionPass::rescheduleKillAboveMI(
// Don't mess with copies, they may be coalesced later.
return false;
- Register DstReg;
+ Register DstReg;
if (isTwoAddrUse(*KillMI, Reg, DstReg))
return false;
@@ -944,10 +944,10 @@ bool TwoAddressInstructionPass::rescheduleKillAboveMI(
if (!KillMI->isSafeToMove(AA, SeenStore))
return false;
- SmallVector<Register, 2> Uses;
- SmallVector<Register, 2> Kills;
- SmallVector<Register, 2> Defs;
- SmallVector<Register, 2> LiveDefs;
+ SmallVector<Register, 2> Uses;
+ SmallVector<Register, 2> Kills;
+ SmallVector<Register, 2> Defs;
+ SmallVector<Register, 2> LiveDefs;
for (const MachineOperand &MO : KillMI->operands()) {
if (!MO.isReg())
continue;
@@ -960,13 +960,13 @@ bool TwoAddressInstructionPass::rescheduleKillAboveMI(
bool isKill = MO.isKill() || (LIS && isPlainlyKilled(KillMI, MOReg, LIS));
if (MOReg == Reg && !isKill)
return false;
- Uses.push_back(MOReg);
+ Uses.push_back(MOReg);
if (isKill && MOReg != Reg)
- Kills.push_back(MOReg);
- } else if (MOReg.isPhysical()) {
- Defs.push_back(MOReg);
+ Kills.push_back(MOReg);
+ } else if (MOReg.isPhysical()) {
+ Defs.push_back(MOReg);
if (!MO.isDead())
- LiveDefs.push_back(MOReg);
+ LiveDefs.push_back(MOReg);
}
}
@@ -974,8 +974,8 @@ bool TwoAddressInstructionPass::rescheduleKillAboveMI(
unsigned NumVisited = 0;
for (MachineInstr &OtherMI :
make_range(mi, MachineBasicBlock::iterator(KillMI))) {
- // Debug or pseudo instructions cannot be counted against the limit.
- if (OtherMI.isDebugOrPseudoInstr())
+ // Debug or pseudo instructions cannot be counted against the limit.
+ if (OtherMI.isDebugOrPseudoInstr())
continue;
if (NumVisited > 10) // FIXME: Arbitrary limit to reduce compile time cost.
return false;
@@ -984,7 +984,7 @@ bool TwoAddressInstructionPass::rescheduleKillAboveMI(
OtherMI.isBranch() || OtherMI.isTerminator())
// Don't move pass calls, etc.
return false;
- SmallVector<Register, 2> OtherDefs;
+ SmallVector<Register, 2> OtherDefs;
for (const MachineOperand &MO : OtherMI.operands()) {
if (!MO.isReg())
continue;
@@ -992,11 +992,11 @@ bool TwoAddressInstructionPass::rescheduleKillAboveMI(
if (!MOReg)
continue;
if (MO.isUse()) {
- if (regOverlapsSet(Defs, MOReg, TRI))
+ if (regOverlapsSet(Defs, MOReg, TRI))
// Moving KillMI can clobber the physical register if the def has
// not been seen.
return false;
- if (regOverlapsSet(Kills, MOReg, TRI))
+ if (regOverlapsSet(Kills, MOReg, TRI))
// Don't want to extend other live ranges and update kills.
return false;
if (&OtherMI != MI && MOReg == Reg &&
@@ -1009,13 +1009,13 @@ bool TwoAddressInstructionPass::rescheduleKillAboveMI(
}
for (unsigned i = 0, e = OtherDefs.size(); i != e; ++i) {
- Register MOReg = OtherDefs[i];
- if (regOverlapsSet(Uses, MOReg, TRI))
+ Register MOReg = OtherDefs[i];
+ if (regOverlapsSet(Uses, MOReg, TRI))
return false;
- if (MOReg.isPhysical() && regOverlapsSet(LiveDefs, MOReg, TRI))
+ if (MOReg.isPhysical() && regOverlapsSet(LiveDefs, MOReg, TRI))
return false;
// Physical register def is seen.
- llvm::erase_value(Defs, MOReg);
+ llvm::erase_value(Defs, MOReg);
}
}
@@ -1133,10 +1133,10 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi,
Register regA = MI.getOperand(DstIdx).getReg();
Register regB = MI.getOperand(SrcIdx).getReg();
- assert(regB.isVirtual() && "cannot make instruction into two-address form");
+ assert(regB.isVirtual() && "cannot make instruction into two-address form");
bool regBKilled = isKilled(MI, regB, MRI, TII, LIS, true);
- if (regA.isVirtual())
+ if (regA.isVirtual())
scanUses(regA);
bool Commuted = tryInstructionCommute(&MI, DstIdx, SrcIdx, regBKilled, Dist);
@@ -1252,7 +1252,7 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi,
if (LV) {
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI.getOperand(i);
- if (MO.isReg() && MO.getReg().isVirtual()) {
+ if (MO.isReg() && MO.getReg().isVirtual()) {
if (MO.isUse()) {
if (MO.isKill()) {
if (NewMIs[0]->killsRegister(MO.getReg()))
@@ -1337,7 +1337,7 @@ collectTiedOperands(MachineInstr *MI, TiedOperandMap &TiedOperands) {
// Deal with undef uses immediately - simply rewrite the src operand.
if (SrcMO.isUndef() && !DstMO.getSubReg()) {
// Constrain the DstReg register class if required.
- if (DstReg.isVirtual())
+ if (DstReg.isVirtual())
if (const TargetRegisterClass *RC = TII->getRegClass(MCID, SrcIdx,
TRI, *MF))
MRI->constrainRegClass(DstReg, RC);
@@ -1367,7 +1367,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
bool AllUsesCopied = true;
unsigned LastCopiedReg = 0;
SlotIndex LastCopyIdx;
- Register RegB = 0;
+ Register RegB = 0;
unsigned SubRegB = 0;
for (unsigned tpi = 0, tpe = TiedPairs.size(); tpi != tpe; ++tpi) {
unsigned SrcIdx = TiedPairs[tpi].first;
@@ -1390,7 +1390,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
}
LastCopiedReg = RegA;
- assert(RegB.isVirtual() && "cannot make instruction into two-address form");
+ assert(RegB.isVirtual() && "cannot make instruction into two-address form");
#ifndef NDEBUG
// First, verify that we don't have a use of "a" in the instruction
@@ -1410,7 +1410,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
MIB.addReg(RegB, 0, SubRegB);
const TargetRegisterClass *RC = MRI->getRegClass(RegB);
if (SubRegB) {
- if (RegA.isVirtual()) {
+ if (RegA.isVirtual()) {
assert(TRI->getMatchingSuperRegClass(RC, MRI->getRegClass(RegA),
SubRegB) &&
"tied subregister must be a truncation");
@@ -1431,7 +1431,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
if (LIS) {
LastCopyIdx = LIS->InsertMachineInstrInMaps(*PrevMI).getRegSlot();
- if (RegA.isVirtual()) {
+ if (RegA.isVirtual()) {
LiveInterval &LI = LIS->getInterval(RegA);
VNInfo *VNI = LI.getNextValue(LastCopyIdx, LIS->getVNInfoAllocator());
SlotIndex endIdx =
@@ -1451,7 +1451,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
}
// Make sure regA is a legal regclass for the SrcIdx operand.
- if (RegA.isVirtual() && RegB.isVirtual())
+ if (RegA.isVirtual() && RegB.isVirtual())
MRI->constrainRegClass(RegA, RC);
MO.setReg(RegA);
// The getMatchingSuper asserts guarantee that the register class projected
@@ -1655,7 +1655,7 @@ void TwoAddressInstructionPass::
eliminateRegSequence(MachineBasicBlock::iterator &MBBI) {
MachineInstr &MI = *MBBI;
Register DstReg = MI.getOperand(0).getReg();
- if (MI.getOperand(0).getSubReg() || DstReg.isPhysical() ||
+ if (MI.getOperand(0).getSubReg() || DstReg.isPhysical() ||
!(MI.getNumOperands() & 1)) {
LLVM_DEBUG(dbgs() << "Illegal REG_SEQUENCE instruction:" << MI);
llvm_unreachable(nullptr);
@@ -1705,7 +1705,7 @@ eliminateRegSequence(MachineBasicBlock::iterator &MBBI) {
DefEmitted = true;
// Update LiveVariables' kill info.
- if (LV && isKill && !SrcReg.isPhysical())
+ if (LV && isKill && !SrcReg.isPhysical())
LV->replaceKillInstruction(SrcReg, MI, *CopyMI);
LLVM_DEBUG(dbgs() << "Inserted: " << *CopyMI);
diff --git a/contrib/libs/llvm12/lib/CodeGen/TypePromotion.cpp b/contrib/libs/llvm12/lib/CodeGen/TypePromotion.cpp
index 9b7813b7b6..a42095d871 100644
--- a/contrib/libs/llvm12/lib/CodeGen/TypePromotion.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/TypePromotion.cpp
@@ -134,9 +134,9 @@ public:
Ctx(C), OrigTy(Ty), PromotedWidth(Width), Visited(visited),
Sources(sources), Sinks(sinks), SafeWrap(wrap) {
ExtTy = IntegerType::get(Ctx, PromotedWidth);
- assert(OrigTy->getPrimitiveSizeInBits().getFixedSize() <
- ExtTy->getPrimitiveSizeInBits().getFixedSize() &&
- "Original type not smaller than extended type");
+ assert(OrigTy->getPrimitiveSizeInBits().getFixedSize() <
+ ExtTy->getPrimitiveSizeInBits().getFixedSize() &&
+ "Original type not smaller than extended type");
}
void Mutate();
@@ -810,7 +810,7 @@ bool TypePromotion::isLegalToPromote(Value *V) {
bool TypePromotion::TryToPromote(Value *V, unsigned PromotedWidth) {
Type *OrigTy = V->getType();
- TypeSize = OrigTy->getPrimitiveSizeInBits().getFixedSize();
+ TypeSize = OrigTy->getPrimitiveSizeInBits().getFixedSize();
SafeToPromote.clear();
SafeWrap.clear();
@@ -982,13 +982,13 @@ bool TypePromotion::runOnFunction(Function &F) {
TargetLowering::TypePromoteInteger)
break;
EVT PromotedVT = TLI->getTypeToTransformTo(ICmp->getContext(), SrcVT);
- if (RegisterBitWidth < PromotedVT.getFixedSizeInBits()) {
+ if (RegisterBitWidth < PromotedVT.getFixedSizeInBits()) {
LLVM_DEBUG(dbgs() << "IR Promotion: Couldn't find target register "
<< "for promoted type\n");
break;
}
- MadeChange |= TryToPromote(I, PromotedVT.getFixedSizeInBits());
+ MadeChange |= TryToPromote(I, PromotedVT.getFixedSizeInBits());
break;
}
}
diff --git a/contrib/libs/llvm12/lib/CodeGen/ValueTypes.cpp b/contrib/libs/llvm12/lib/CodeGen/ValueTypes.cpp
index a32c77b7e5..978357d8f5 100644
--- a/contrib/libs/llvm12/lib/CodeGen/ValueTypes.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/ValueTypes.cpp
@@ -49,7 +49,7 @@ EVT EVT::getExtendedVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements,
EVT EVT::getExtendedVectorVT(LLVMContext &Context, EVT VT, ElementCount EC) {
EVT ResultVT;
- ResultVT.LLVMTy = VectorType::get(VT.getTypeForEVT(Context), EC);
+ ResultVT.LLVMTy = VectorType::get(VT.getTypeForEVT(Context), EC);
assert(ResultVT.isExtended() && "Type is not extended!");
return ResultVT;
}
@@ -122,13 +122,13 @@ EVT EVT::getExtendedVectorElementType() const {
unsigned EVT::getExtendedVectorNumElements() const {
assert(isExtended() && "Type is not extended!");
ElementCount EC = cast<VectorType>(LLVMTy)->getElementCount();
- if (EC.isScalable()) {
+ if (EC.isScalable()) {
WithColor::warning()
<< "The code that requested the fixed number of elements has made the "
"assumption that this vector is not scalable. This assumption was "
"not correct, and this may lead to broken code\n";
}
- return EC.getKnownMinValue();
+ return EC.getKnownMinValue();
}
ElementCount EVT::getExtendedVectorElementCount() const {
@@ -150,25 +150,25 @@ std::string EVT::getEVTString() const {
switch (V.SimpleTy) {
default:
if (isVector())
- return (isScalableVector() ? "nxv" : "v") +
- utostr(getVectorElementCount().getKnownMinValue()) +
- getVectorElementType().getEVTString();
+ return (isScalableVector() ? "nxv" : "v") +
+ utostr(getVectorElementCount().getKnownMinValue()) +
+ getVectorElementType().getEVTString();
if (isInteger())
return "i" + utostr(getSizeInBits());
if (isFloatingPoint())
return "f" + utostr(getSizeInBits());
llvm_unreachable("Invalid EVT!");
- case MVT::bf16: return "bf16";
- case MVT::ppcf128: return "ppcf128";
- case MVT::isVoid: return "isVoid";
- case MVT::Other: return "ch";
- case MVT::Glue: return "glue";
- case MVT::x86mmx: return "x86mmx";
- case MVT::x86amx: return "x86amx";
- case MVT::Metadata: return "Metadata";
- case MVT::Untyped: return "Untyped";
- case MVT::funcref: return "funcref";
- case MVT::externref: return "externref";
+ case MVT::bf16: return "bf16";
+ case MVT::ppcf128: return "ppcf128";
+ case MVT::isVoid: return "isVoid";
+ case MVT::Other: return "ch";
+ case MVT::Glue: return "glue";
+ case MVT::x86mmx: return "x86mmx";
+ case MVT::x86amx: return "x86amx";
+ case MVT::Metadata: return "Metadata";
+ case MVT::Untyped: return "Untyped";
+ case MVT::funcref: return "funcref";
+ case MVT::externref: return "externref";
}
}
@@ -195,7 +195,7 @@ Type *EVT::getTypeForEVT(LLVMContext &Context) const {
case MVT::f128: return Type::getFP128Ty(Context);
case MVT::ppcf128: return Type::getPPC_FP128Ty(Context);
case MVT::x86mmx: return Type::getX86_MMXTy(Context);
- case MVT::x86amx: return Type::getX86_AMXTy(Context);
+ case MVT::x86amx: return Type::getX86_AMXTy(Context);
case MVT::v1i1:
return FixedVectorType::get(Type::getInt1Ty(Context), 1);
case MVT::v2i1:
@@ -294,12 +294,12 @@ Type *EVT::getTypeForEVT(LLVMContext &Context) const {
return FixedVectorType::get(Type::getInt64Ty(Context), 16);
case MVT::v32i64:
return FixedVectorType::get(Type::getInt64Ty(Context), 32);
- case MVT::v64i64:
- return FixedVectorType::get(Type::getInt64Ty(Context), 64);
- case MVT::v128i64:
- return FixedVectorType::get(Type::getInt64Ty(Context), 128);
- case MVT::v256i64:
- return FixedVectorType::get(Type::getInt64Ty(Context), 256);
+ case MVT::v64i64:
+ return FixedVectorType::get(Type::getInt64Ty(Context), 64);
+ case MVT::v128i64:
+ return FixedVectorType::get(Type::getInt64Ty(Context), 128);
+ case MVT::v256i64:
+ return FixedVectorType::get(Type::getInt64Ty(Context), 256);
case MVT::v1i128:
return FixedVectorType::get(Type::getInt128Ty(Context), 1);
case MVT::v2f16:
@@ -315,9 +315,9 @@ Type *EVT::getTypeForEVT(LLVMContext &Context) const {
case MVT::v32f16:
return FixedVectorType::get(Type::getHalfTy(Context), 32);
case MVT::v64f16:
- return FixedVectorType::get(Type::getHalfTy(Context), 64);
+ return FixedVectorType::get(Type::getHalfTy(Context), 64);
case MVT::v128f16:
- return FixedVectorType::get(Type::getHalfTy(Context), 128);
+ return FixedVectorType::get(Type::getHalfTy(Context), 128);
case MVT::v2bf16:
return FixedVectorType::get(Type::getBFloatTy(Context), 2);
case MVT::v3bf16:
@@ -374,12 +374,12 @@ Type *EVT::getTypeForEVT(LLVMContext &Context) const {
return FixedVectorType::get(Type::getDoubleTy(Context), 16);
case MVT::v32f64:
return FixedVectorType::get(Type::getDoubleTy(Context), 32);
- case MVT::v64f64:
- return FixedVectorType::get(Type::getDoubleTy(Context), 64);
- case MVT::v128f64:
- return FixedVectorType::get(Type::getDoubleTy(Context), 128);
- case MVT::v256f64:
- return FixedVectorType::get(Type::getDoubleTy(Context), 256);
+ case MVT::v64f64:
+ return FixedVectorType::get(Type::getDoubleTy(Context), 64);
+ case MVT::v128f64:
+ return FixedVectorType::get(Type::getDoubleTy(Context), 128);
+ case MVT::v256f64:
+ return FixedVectorType::get(Type::getDoubleTy(Context), 256);
case MVT::nxv1i1:
return ScalableVectorType::get(Type::getInt1Ty(Context), 1);
case MVT::nxv2i1:
@@ -502,7 +502,7 @@ MVT MVT::getVT(Type *Ty, bool HandleUnknown){
case Type::DoubleTyID: return MVT(MVT::f64);
case Type::X86_FP80TyID: return MVT(MVT::f80);
case Type::X86_MMXTyID: return MVT(MVT::x86mmx);
- case Type::X86_AMXTyID: return MVT(MVT::x86amx);
+ case Type::X86_AMXTyID: return MVT(MVT::x86amx);
case Type::FP128TyID: return MVT(MVT::f128);
case Type::PPC_FP128TyID: return MVT(MVT::ppcf128);
case Type::PointerTyID: return MVT(MVT::iPTR);
diff --git a/contrib/libs/llvm12/lib/CodeGen/VirtRegMap.cpp b/contrib/libs/llvm12/lib/CodeGen/VirtRegMap.cpp
index d57287d9ed..5e0ff9d909 100644
--- a/contrib/libs/llvm12/lib/CodeGen/VirtRegMap.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/VirtRegMap.cpp
@@ -68,7 +68,7 @@ bool VirtRegMap::runOnMachineFunction(MachineFunction &mf) {
Virt2PhysMap.clear();
Virt2StackSlotMap.clear();
Virt2SplitMap.clear();
- Virt2ShapeMap.clear();
+ Virt2ShapeMap.clear();
grow();
return false;
@@ -105,7 +105,7 @@ bool VirtRegMap::hasPreferredPhys(Register VirtReg) {
return false;
if (Hint.isVirtual())
Hint = getPhys(Hint);
- return Register(getPhys(VirtReg)) == Hint;
+ return Register(getPhys(VirtReg)) == Hint;
}
bool VirtRegMap::hasKnownPreference(Register VirtReg) {
@@ -188,7 +188,7 @@ class VirtRegRewriter : public MachineFunctionPass {
void addLiveInsForSubRanges(const LiveInterval &LI, Register PhysReg) const;
void handleIdentityCopy(MachineInstr &MI) const;
void expandCopyBundle(MachineInstr &MI) const;
- bool subRegLiveThrough(const MachineInstr &MI, MCRegister SuperPhysReg) const;
+ bool subRegLiveThrough(const MachineInstr &MI, MCRegister SuperPhysReg) const;
public:
static char ID;
@@ -401,18 +401,18 @@ void VirtRegRewriter::handleIdentityCopy(MachineInstr &MI) const {
/// after processing the last in the bundle. Does not update LiveIntervals
/// which we shouldn't need for this instruction anymore.
void VirtRegRewriter::expandCopyBundle(MachineInstr &MI) const {
- if (!MI.isCopy() && !MI.isKill())
+ if (!MI.isCopy() && !MI.isKill())
return;
if (MI.isBundledWithPred() && !MI.isBundledWithSucc()) {
SmallVector<MachineInstr *, 2> MIs({&MI});
- // Only do this when the complete bundle is made out of COPYs and KILLs.
+ // Only do this when the complete bundle is made out of COPYs and KILLs.
MachineBasicBlock &MBB = *MI.getParent();
for (MachineBasicBlock::reverse_instr_iterator I =
std::next(MI.getReverseIterator()), E = MBB.instr_rend();
I != E && I->isBundledWithSucc(); ++I) {
- if (!I->isCopy() && !I->isKill())
+ if (!I->isCopy() && !I->isKill())
return;
MIs.push_back(&*I);
}
@@ -453,7 +453,7 @@ void VirtRegRewriter::expandCopyBundle(MachineInstr &MI) const {
// instruction, the bundle will have been completely undone.
if (BundledMI != BundleStart) {
BundledMI->removeFromBundle();
- MBB.insert(BundleStart, BundledMI);
+ MBB.insert(BundleStart, BundledMI);
} else if (BundledMI->isBundledWithSucc()) {
BundledMI->unbundleFromSucc();
BundleStart = &*std::next(BundledMI->getIterator());
@@ -469,7 +469,7 @@ void VirtRegRewriter::expandCopyBundle(MachineInstr &MI) const {
/// \pre \p MI defines a subregister of a virtual register that
/// has been assigned to \p SuperPhysReg.
bool VirtRegRewriter::subRegLiveThrough(const MachineInstr &MI,
- MCRegister SuperPhysReg) const {
+ MCRegister SuperPhysReg) const {
SlotIndex MIIndex = LIS->getInstructionIndex(MI);
SlotIndex BeforeMIUses = MIIndex.getBaseIndex();
SlotIndex AfterMIDefs = MIIndex.getBoundaryIndex();
@@ -516,7 +516,7 @@ void VirtRegRewriter::rewrite() {
if (!MO.isReg() || !MO.getReg().isVirtual())
continue;
Register VirtReg = MO.getReg();
- MCRegister PhysReg = VRM->getPhys(VirtReg);
+ MCRegister PhysReg = VRM->getPhys(VirtReg);
assert(PhysReg != VirtRegMap::NO_PHYS_REG &&
"Instruction uses unmapped VirtReg");
assert(!MRI->isReserved(PhysReg) && "Reserved register assignment");
diff --git a/contrib/libs/llvm12/lib/CodeGen/WasmEHPrepare.cpp b/contrib/libs/llvm12/lib/CodeGen/WasmEHPrepare.cpp
index 771d881eaf..5342455668 100644
--- a/contrib/libs/llvm12/lib/CodeGen/WasmEHPrepare.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/WasmEHPrepare.cpp
@@ -23,7 +23,7 @@
//
// - After:
// catchpad ...
-// exn = wasm.catch(WebAssembly::CPP_EXCEPTION);
+// exn = wasm.catch(WebAssembly::CPP_EXCEPTION);
// // Only add below in case it's not a single catch (...)
// wasm.landingpad.index(index);
// __wasm_lpad_context.lpad_index = index;
@@ -112,7 +112,7 @@ class WasmEHPrepare : public FunctionPass {
Function *LPadIndexF = nullptr; // wasm.landingpad.index() intrinsic
Function *LSDAF = nullptr; // wasm.lsda() intrinsic
Function *GetExnF = nullptr; // wasm.get.exception() intrinsic
- Function *CatchF = nullptr; // wasm.catch() intrinsic
+ Function *CatchF = nullptr; // wasm.catch() intrinsic
Function *GetSelectorF = nullptr; // wasm.get.ehselector() intrinsic
FunctionCallee CallPersonalityF =
nullptr; // _Unwind_CallPersonality() wrapper
@@ -168,7 +168,7 @@ static void eraseDeadBBsAndChildren(const Container &BBs, DomTreeUpdater *DTU) {
SmallVector<BasicBlock *, 8> WL(BBs.begin(), BBs.end());
while (!WL.empty()) {
auto *BB = WL.pop_back_val();
- if (!pred_empty(BB))
+ if (!pred_empty(BB))
continue;
WL.append(succ_begin(BB), succ_end(BB));
DeleteDeadBlock(BB, DTU);
@@ -204,7 +204,7 @@ bool WasmEHPrepare::prepareThrows(Function &F) {
continue;
Changed = true;
auto *BB = ThrowI->getParent();
- SmallVector<BasicBlock *, 4> Succs(successors(BB));
+ SmallVector<BasicBlock *, 4> Succs(successors(BB));
auto &InstList = BB->getInstList();
InstList.erase(std::next(BasicBlock::iterator(ThrowI)), InstList.end());
IRB.SetInsertPoint(BB);
@@ -327,9 +327,9 @@ void WasmEHPrepare::setupEHPadFunctions(Function &F) {
GetExnF = Intrinsic::getDeclaration(&M, Intrinsic::wasm_get_exception);
GetSelectorF = Intrinsic::getDeclaration(&M, Intrinsic::wasm_get_ehselector);
- // wasm.catch() will be lowered down to wasm 'catch' instruction in
- // instruction selection.
- CatchF = Intrinsic::getDeclaration(&M, Intrinsic::wasm_catch);
+ // wasm.catch() will be lowered down to wasm 'catch' instruction in
+ // instruction selection.
+ CatchF = Intrinsic::getDeclaration(&M, Intrinsic::wasm_catch);
// _Unwind_CallPersonality() wrapper function, which calls the personality
CallPersonalityF = M.getOrInsertFunction(
@@ -369,13 +369,13 @@ void WasmEHPrepare::prepareEHPad(BasicBlock *BB, bool NeedPersonality,
return;
}
- // Replace wasm.get.exception intrinsic with wasm.catch intrinsic, which will
- // be lowered to wasm 'catch' instruction. We do this mainly because
- // instruction selection cannot handle wasm.get.exception intrinsic's token
- // argument.
- Instruction *CatchCI =
- IRB.CreateCall(CatchF, {IRB.getInt32(WebAssembly::CPP_EXCEPTION)}, "exn");
- GetExnCI->replaceAllUsesWith(CatchCI);
+ // Replace wasm.get.exception intrinsic with wasm.catch intrinsic, which will
+ // be lowered to wasm 'catch' instruction. We do this mainly because
+ // instruction selection cannot handle wasm.get.exception intrinsic's token
+ // argument.
+ Instruction *CatchCI =
+ IRB.CreateCall(CatchF, {IRB.getInt32(WebAssembly::CPP_EXCEPTION)}, "exn");
+ GetExnCI->replaceAllUsesWith(CatchCI);
GetExnCI->eraseFromParent();
// In case it is a catchpad with single catch (...) or a cleanuppad, we don't
@@ -388,7 +388,7 @@ void WasmEHPrepare::prepareEHPad(BasicBlock *BB, bool NeedPersonality,
}
return;
}
- IRB.SetInsertPoint(CatchCI->getNextNode());
+ IRB.SetInsertPoint(CatchCI->getNextNode());
// This is to create a map of <landingpad EH label, landingpad index> in
// SelectionDAGISel, which is to be used in EHStreamer to emit LSDA tables.
@@ -404,7 +404,7 @@ void WasmEHPrepare::prepareEHPad(BasicBlock *BB, bool NeedPersonality,
IRB.CreateStore(IRB.CreateCall(LSDAF), LSDAField);
// Pseudocode: _Unwind_CallPersonality(exn);
- CallInst *PersCI = IRB.CreateCall(CallPersonalityF, CatchCI,
+ CallInst *PersCI = IRB.CreateCall(CallPersonalityF, CatchCI,
OperandBundleDef("funclet", CPI));
PersCI->setDoesNotThrow();
diff --git a/contrib/libs/llvm12/lib/CodeGen/WinEHPrepare.cpp b/contrib/libs/llvm12/lib/CodeGen/WinEHPrepare.cpp
index 2b92df0a15..96d256ba57 100644
--- a/contrib/libs/llvm12/lib/CodeGen/WinEHPrepare.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/WinEHPrepare.cpp
@@ -804,9 +804,9 @@ void WinEHPrepare::cloneCommonBlocks(Function &F) {
<< "\' to block \'" << NewBlock->getName()
<< "\'.\n");
- llvm::erase_value(BlocksInFunclet, OldBlock);
+ llvm::erase_value(BlocksInFunclet, OldBlock);
ColorVector &OldColors = BlockColors[OldBlock];
- llvm::erase_value(OldColors, FuncletPadBB);
+ llvm::erase_value(OldColors, FuncletPadBB);
DEBUG_WITH_TYPE("winehprepare-coloring",
dbgs() << " Removed color \'" << FuncletPadBB->getName()
diff --git a/contrib/libs/llvm12/lib/CodeGen/XRayInstrumentation.cpp b/contrib/libs/llvm12/lib/CodeGen/XRayInstrumentation.cpp
index 961046a723..11d1b309aa 100644
--- a/contrib/libs/llvm12/lib/CodeGen/XRayInstrumentation.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/XRayInstrumentation.cpp
@@ -145,22 +145,22 @@ void XRayInstrumentation::prependRetWithPatchableExit(
bool XRayInstrumentation::runOnMachineFunction(MachineFunction &MF) {
auto &F = MF.getFunction();
auto InstrAttr = F.getFnAttribute("function-instrument");
- bool AlwaysInstrument = InstrAttr.isStringAttribute() &&
+ bool AlwaysInstrument = InstrAttr.isStringAttribute() &&
InstrAttr.getValueAsString() == "xray-always";
- bool NeverInstrument = InstrAttr.isStringAttribute() &&
- InstrAttr.getValueAsString() == "xray-never";
- if (NeverInstrument && !AlwaysInstrument)
- return false;
+ bool NeverInstrument = InstrAttr.isStringAttribute() &&
+ InstrAttr.getValueAsString() == "xray-never";
+ if (NeverInstrument && !AlwaysInstrument)
+ return false;
auto ThresholdAttr = F.getFnAttribute("xray-instruction-threshold");
auto IgnoreLoopsAttr = F.getFnAttribute("xray-ignore-loops");
unsigned int XRayThreshold = 0;
if (!AlwaysInstrument) {
- if (!ThresholdAttr.isStringAttribute())
+ if (!ThresholdAttr.isStringAttribute())
return false; // XRay threshold attribute not found.
if (ThresholdAttr.getValueAsString().getAsInteger(10, XRayThreshold))
return false; // Invalid value for threshold.
- bool IgnoreLoops = IgnoreLoopsAttr.isValid();
+ bool IgnoreLoops = IgnoreLoopsAttr.isValid();
// Count the number of MachineInstr`s in MachineFunction
int64_t MICount = 0;
diff --git a/contrib/libs/llvm12/lib/CodeGen/ya.make b/contrib/libs/llvm12/lib/CodeGen/ya.make
index 0d91878793..ed4f607e74 100644
--- a/contrib/libs/llvm12/lib/CodeGen/ya.make
+++ b/contrib/libs/llvm12/lib/CodeGen/ya.make
@@ -15,18 +15,18 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/Bitcode/Reader
- contrib/libs/llvm12/lib/Bitcode/Writer
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/ProfileData
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target
- contrib/libs/llvm12/lib/Transforms/Scalar
- contrib/libs/llvm12/lib/Transforms/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/Bitcode/Reader
+ contrib/libs/llvm12/lib/Bitcode/Writer
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/ProfileData
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target
+ contrib/libs/llvm12/lib/Transforms/Scalar
+ contrib/libs/llvm12/lib/Transforms/Utils
)
ADDINCL(
@@ -42,7 +42,7 @@ SRCS(
AllocationOrder.cpp
Analysis.cpp
AtomicExpandPass.cpp
- BasicBlockSections.cpp
+ BasicBlockSections.cpp
BasicTargetTransformInfo.cpp
BranchFolding.cpp
BranchRelaxation.cpp
@@ -53,7 +53,7 @@ SRCS(
CalcSpillWeights.cpp
CallingConvLower.cpp
CodeGen.cpp
- CodeGenPassBuilder.cpp
+ CodeGenPassBuilder.cpp
CodeGenPrepare.cpp
CommandFlags.cpp
CriticalAntiDepBreaker.cpp
@@ -90,9 +90,9 @@ SRCS(
LatencyPriorityQueue.cpp
LazyMachineBlockFrequencyInfo.cpp
LexicalScopes.cpp
- LiveDebugValues/InstrRefBasedImpl.cpp
- LiveDebugValues/LiveDebugValues.cpp
- LiveDebugValues/VarLocBasedImpl.cpp
+ LiveDebugValues/InstrRefBasedImpl.cpp
+ LiveDebugValues/LiveDebugValues.cpp
+ LiveDebugValues/VarLocBasedImpl.cpp
LiveDebugVariables.cpp
LiveInterval.cpp
LiveIntervalCalc.cpp
@@ -121,7 +121,7 @@ SRCS(
MachineBlockPlacement.cpp
MachineBranchProbabilityInfo.cpp
MachineCSE.cpp
- MachineCheckDebugify.cpp
+ MachineCheckDebugify.cpp
MachineCombiner.cpp
MachineCopyPropagation.cpp
MachineDebugify.cpp
@@ -131,7 +131,7 @@ SRCS(
MachineFunction.cpp
MachineFunctionPass.cpp
MachineFunctionPrinterPass.cpp
- MachineFunctionSplitter.cpp
+ MachineFunctionSplitter.cpp
MachineInstr.cpp
MachineInstrBundle.cpp
MachineLICM.cpp
@@ -142,7 +142,7 @@ SRCS(
MachineOperand.cpp
MachineOptimizationRemarkEmitter.cpp
MachineOutliner.cpp
- MachinePassManager.cpp
+ MachinePassManager.cpp
MachinePipeliner.cpp
MachinePostDominators.cpp
MachineRegionInfo.cpp
@@ -151,13 +151,13 @@ SRCS(
MachineScheduler.cpp
MachineSink.cpp
MachineSizeOpts.cpp
- MachineStableHash.cpp
+ MachineStableHash.cpp
MachineStripDebug.cpp
MachineTraceMetrics.cpp
MachineVerifier.cpp
MacroFusion.cpp
ModuloSchedule.cpp
- MultiHazardRecognizer.cpp
+ MultiHazardRecognizer.cpp
NonRelocatableStringpool.cpp
OptimizePHIs.cpp
PHIElimination.cpp
@@ -170,7 +170,7 @@ SRCS(
PreISelIntrinsicLowering.cpp
ProcessImplicitDefs.cpp
PrologEpilogInserter.cpp
- PseudoProbeInserter.cpp
+ PseudoProbeInserter.cpp
PseudoSourceValue.cpp
RDFGraph.cpp
RDFLiveness.cpp
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp
index 2e029feb5e..9bc69abea1 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp
@@ -47,9 +47,9 @@ Error DebugFrameDataSubsection::commit(BinaryStreamWriter &Writer) const {
}
std::vector<FrameData> SortedFrames(Frames.begin(), Frames.end());
- llvm::sort(SortedFrames, [](const FrameData &LHS, const FrameData &RHS) {
- return LHS.RvaStart < RHS.RvaStart;
- });
+ llvm::sort(SortedFrames, [](const FrameData &LHS, const FrameData &RHS) {
+ return LHS.RvaStart < RHS.RvaStart;
+ });
if (auto EC = Writer.writeArray(makeArrayRef(SortedFrames)))
return EC;
return Error::success();
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/EnumTables.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/EnumTables.cpp
index 46bd73b4bc..949707bf54 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/EnumTables.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/EnumTables.cpp
@@ -39,14 +39,14 @@ static const EnumEntry<uint16_t> RegisterNames_X86[] = {
#undef CV_REGISTERS_X86
};
-static const EnumEntry<uint16_t> RegisterNames_ARM[] = {
-#define CV_REGISTERS_ARM
-#define CV_REGISTER(name, val) CV_ENUM_CLASS_ENT(RegisterId, name),
-#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
-#undef CV_REGISTER
-#undef CV_REGISTERS_ARM
-};
-
+static const EnumEntry<uint16_t> RegisterNames_ARM[] = {
+#define CV_REGISTERS_ARM
+#define CV_REGISTER(name, val) CV_ENUM_CLASS_ENT(RegisterId, name),
+#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
+#undef CV_REGISTER
+#undef CV_REGISTERS_ARM
+};
+
static const EnumEntry<uint16_t> RegisterNames_ARM64[] = {
#define CV_REGISTERS_ARM64
#define CV_REGISTER(name, val) CV_ENUM_CLASS_ENT(RegisterId, name),
@@ -442,9 +442,9 @@ ArrayRef<EnumEntry<TypeLeafKind>> getTypeLeafNames() {
}
ArrayRef<EnumEntry<uint16_t>> getRegisterNames(CPUType Cpu) {
- if (Cpu == CPUType::ARMNT) {
- return makeArrayRef(RegisterNames_ARM);
- } else if (Cpu == CPUType::ARM64) {
+ if (Cpu == CPUType::ARMNT) {
+ return makeArrayRef(RegisterNames_ARM);
+ } else if (Cpu == CPUType::ARM64) {
return makeArrayRef(RegisterNames_ARM64);
}
return makeArrayRef(RegisterNames_X86);
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
index d924a5809d..c0fc3e0ef6 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
@@ -172,10 +172,10 @@ Error LazyRandomTypeCollection::visitRangeForType(TypeIndex TI) {
if (PartialOffsets.empty())
return fullScanForType(TI);
- auto Next = llvm::upper_bound(PartialOffsets, TI,
- [](TypeIndex Value, const TypeIndexOffset &IO) {
- return Value < IO.Type;
- });
+ auto Next = llvm::upper_bound(PartialOffsets, TI,
+ [](TypeIndex Value, const TypeIndexOffset &IO) {
+ return Value < IO.Type;
+ });
assert(Next != PartialOffsets.begin());
auto Prev = std::prev(Next);
@@ -185,7 +185,7 @@ Error LazyRandomTypeCollection::visitRangeForType(TypeIndex TI) {
// They've asked us to fetch a type index, but the entry we found in the
// partial offsets array has already been visited. Since we visit an entire
// block every time, that means this record should have been previously
- // discovered. Ultimately, this means this is a request for a non-existent
+ // discovered. Ultimately, this means this is a request for a non-existent
// type index.
return make_error<CodeViewError>("Invalid type index");
}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordName.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordName.cpp
index 80c3408491..1ca899789b 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordName.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordName.cpp
@@ -9,7 +9,7 @@
#include "llvm/DebugInfo/CodeView/RecordName.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
@@ -78,10 +78,10 @@ Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArgListRecord &Args) {
uint32_t Size = Indices.size();
Name = "(";
for (uint32_t I = 0; I < Size; ++I) {
- if (Indices[I] < CurrentTypeIndex)
- Name.append(Types.getTypeName(Indices[I]));
- else
- Name.append("<unknown 0x" + utohexstr(Indices[I].getIndex()) + ">");
+ if (Indices[I] < CurrentTypeIndex)
+ Name.append(Types.getTypeName(Indices[I]));
+ else
+ Name.append("<unknown 0x" + utohexstr(Indices[I].getIndex()) + ">");
if (I + 1 != Size)
Name.append(", ");
}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordSerialization.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordSerialization.cpp
index 68a2a7b715..63ce302a4e 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordSerialization.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordSerialization.cpp
@@ -34,7 +34,7 @@ StringRef llvm::codeview::getBytesAsCString(ArrayRef<uint8_t> LeafData) {
}
Error llvm::codeview::consume(BinaryStreamReader &Reader, APSInt &Num) {
- // Used to avoid overload ambiguity on APInt constructor.
+ // Used to avoid overload ambiguity on APInt constructor.
bool FalseVal = false;
uint16_t Short;
if (auto EC = Reader.readInteger(Short))
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
index a8af5419e7..682747a2b8 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
@@ -5,9 +5,9 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-
+
#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Endian.h"
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeRecordMapping.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
index b049252f09..7ac3761561 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
@@ -232,7 +232,7 @@ Error TypeRecordMapping::visitMemberBegin(CVMemberRecord &Record) {
// The largest possible subrecord is one in which there is a record prefix,
// followed by the subrecord, followed by a continuation, and that entire
- // sequence spawns `MaxRecordLength` bytes. So the record's length is
+ // sequence spawns `MaxRecordLength` bytes. So the record's length is
// calculated as follows.
constexpr uint32_t ContinuationLength = 8;
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
index 52c8621738..587a68142a 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
@@ -38,7 +38,7 @@ namespace {
/// 0x1000.
///
/// Type records are only allowed to use type indices smaller than their own, so
-/// a type stream is effectively a topologically sorted DAG. Cycles occurring in
+/// a type stream is effectively a topologically sorted DAG. Cycles occurring in
/// the type graph of the source program are resolved with forward declarations
/// of composite types. This class implements the following type stream merging
/// algorithm, which relies on this DAG structure:
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/ya.make b/contrib/libs/llvm12/lib/DebugInfo/CodeView/ya.make
index 000c00e8e9..8829a8f09f 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/ya.make
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/ya.make
@@ -12,9 +12,9 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/DebugInfo/MSF
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/DebugInfo/MSF
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAddressRange.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
index 96766c48db..25d2e852a7 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
@@ -18,9 +18,9 @@ void DWARFAddressRange::dump(raw_ostream &OS, uint32_t AddressSize,
const DWARFObject *Obj) const {
OS << (DumpOpts.DisplayRawContents ? " " : "[");
- DWARFFormValue::dumpAddress(OS, AddressSize, LowPC);
- OS << ", ";
- DWARFFormValue::dumpAddress(OS, AddressSize, HighPC);
+ DWARFFormValue::dumpAddress(OS, AddressSize, LowPC);
+ OS << ", ";
+ DWARFFormValue::dumpAddress(OS, AddressSize, HighPC);
OS << (DumpOpts.DisplayRawContents ? "" : ")");
if (Obj)
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
index c3fceaa00f..2b08120ef4 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
@@ -22,10 +22,10 @@ void DWARFCompileUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
<< ", version = " << format("0x%04x", getVersion());
if (getVersion() >= 5)
OS << ", unit_type = " << dwarf::UnitTypeString(getUnitType());
- OS << ", abbr_offset = " << format("0x%04" PRIx64, getAbbrOffset());
- if (!getAbbreviations())
- OS << " (invalid)";
- OS << ", addr_size = " << format("0x%02x", getAddressByteSize());
+ OS << ", abbr_offset = " << format("0x%04" PRIx64, getAbbrOffset());
+ if (!getAbbreviations())
+ OS << " (invalid)";
+ OS << ", addr_size = " << format("0x%02x", getAddressByteSize());
if (getVersion() >= 5 && getUnitType() != dwarf::DW_UT_compile)
OS << ", DWO_id = " << format("0x%016" PRIx64, *getDWOId());
OS << " (next unit at " << format("0x%08" PRIx64, getNextUnitOffset())
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFContext.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFContext.cpp
index 52cb9387e8..749d738af9 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -255,7 +255,7 @@ static void dumpRnglistsSection(
break;
Offset = TableOffset + Length;
} else {
- Rnglists.dump(rnglistData, OS, LookupPooledAddress, DumpOpts);
+ Rnglists.dump(rnglistData, OS, LookupPooledAddress, DumpOpts);
}
}
}
@@ -316,7 +316,7 @@ static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
return;
}
- Header.dump(Data, OS, DumpOpts);
+ Header.dump(Data, OS, DumpOpts);
uint64_t EndOffset = Header.length() + Header.getHeaderOffset();
Data.setAddressSize(Header.getAddrSize());
@@ -457,7 +457,7 @@ void DWARFContext::dump(
shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
DObj->getFrameSection().Data)) {
if (Expected<const DWARFDebugFrame *> DF = getDebugFrame())
- (*DF)->dump(OS, DumpOpts, getRegisterInfo(), *Off);
+ (*DF)->dump(OS, DumpOpts, getRegisterInfo(), *Off);
else
RecoverableErrorHandler(DF.takeError());
}
@@ -466,7 +466,7 @@ void DWARFContext::dump(
shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
DObj->getEHFrameSection().Data)) {
if (Expected<const DWARFDebugFrame *> DF = getEHFrame())
- (*DF)->dump(OS, DumpOpts, getRegisterInfo(), *Off);
+ (*DF)->dump(OS, DumpOpts, getRegisterInfo(), *Off);
else
RecoverableErrorHandler(DF.takeError());
}
@@ -502,8 +502,8 @@ void DWARFContext::dump(
0);
DWARFDebugArangeSet set;
while (arangesData.isValidOffset(offset)) {
- if (Error E =
- set.extract(arangesData, &offset, DumpOpts.WarningHandler)) {
+ if (Error E =
+ set.extract(arangesData, &offset, DumpOpts.WarningHandler)) {
RecoverableErrorHandler(std::move(E));
break;
}
@@ -526,29 +526,29 @@ void DWARFContext::dump(
}
};
- auto DumpStrSection = [&](StringRef Section) {
- DataExtractor StrData(Section, isLittleEndian(), 0);
- uint64_t Offset = 0;
- uint64_t StrOffset = 0;
- while (StrData.isValidOffset(Offset)) {
- Error Err = Error::success();
- const char *CStr = StrData.getCStr(&Offset, &Err);
- if (Err) {
- DumpOpts.WarningHandler(std::move(Err));
- return;
- }
- OS << format("0x%8.8" PRIx64 ": \"", StrOffset);
- OS.write_escaped(CStr);
- OS << "\"\n";
- StrOffset = Offset;
- }
- };
-
+ auto DumpStrSection = [&](StringRef Section) {
+ DataExtractor StrData(Section, isLittleEndian(), 0);
+ uint64_t Offset = 0;
+ uint64_t StrOffset = 0;
+ while (StrData.isValidOffset(Offset)) {
+ Error Err = Error::success();
+ const char *CStr = StrData.getCStr(&Offset, &Err);
+ if (Err) {
+ DumpOpts.WarningHandler(std::move(Err));
+ return;
+ }
+ OS << format("0x%8.8" PRIx64 ": \"", StrOffset);
+ OS.write_escaped(CStr);
+ OS << "\"\n";
+ StrOffset = Offset;
+ }
+ };
+
if (const auto *Off = shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine,
DObj->getLineSection().Data)) {
DWARFDataExtractor LineData(*DObj, DObj->getLineSection(), isLittleEndian(),
0);
- DWARFDebugLine::SectionParser Parser(LineData, *this, normal_units());
+ DWARFDebugLine::SectionParser Parser(LineData, *this, normal_units());
DumpLineSection(Parser, DumpOpts, *Off);
}
@@ -557,7 +557,7 @@ void DWARFContext::dump(
DObj->getLineDWOSection().Data)) {
DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(),
isLittleEndian(), 0);
- DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_units());
+ DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_units());
DumpLineSection(Parser, DumpOpts, *Off);
}
@@ -572,16 +572,16 @@ void DWARFContext::dump(
}
if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr,
- DObj->getStrSection()))
- DumpStrSection(DObj->getStrSection());
-
+ DObj->getStrSection()))
+ DumpStrSection(DObj->getStrSection());
+
if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr,
- DObj->getStrDWOSection()))
- DumpStrSection(DObj->getStrDWOSection());
-
+ DObj->getStrDWOSection()))
+ DumpStrSection(DObj->getStrDWOSection());
+
if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr,
- DObj->getLineStrSection()))
- DumpStrSection(DObj->getLineStrSection());
+ DObj->getLineStrSection()))
+ DumpStrSection(DObj->getLineStrSection());
if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr,
DObj->getAddrSection().Data)) {
@@ -1034,9 +1034,9 @@ DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address) {
static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU,
uint64_t Address,
FunctionNameKind Kind,
- DILineInfoSpecifier::FileLineInfoKind FileNameKind,
+ DILineInfoSpecifier::FileLineInfoKind FileNameKind,
std::string &FunctionName,
- std::string &StartFile,
+ std::string &StartFile,
uint32_t &StartLine) {
// The address may correspond to instruction in some inlined function,
// so we have to build the chain of inlined functions and take the
@@ -1053,11 +1053,11 @@ static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU,
FunctionName = Name;
FoundResult = true;
}
- std::string DeclFile = DIE.getDeclFile(FileNameKind);
- if (!DeclFile.empty()) {
- StartFile = DeclFile;
- FoundResult = true;
- }
+ std::string DeclFile = DIE.getDeclFile(FileNameKind);
+ if (!DeclFile.empty()) {
+ StartFile = DeclFile;
+ FoundResult = true;
+ }
if (auto DeclLineResult = DIE.getDeclLine()) {
StartLine = DeclLineResult;
FoundResult = true;
@@ -1229,9 +1229,9 @@ DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
if (!CU)
return Result;
- getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, Spec.FLIKind,
- Result.FunctionName,
- Result.StartFileName, Result.StartLine);
+ getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, Spec.FLIKind,
+ Result.FunctionName,
+ Result.StartFileName, Result.StartLine);
if (Spec.FLIKind != FileLineInfoKind::None) {
if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) {
LineTable->getFileLineInfoForAddress(
@@ -1250,17 +1250,17 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(
return Lines;
uint32_t StartLine = 0;
- std::string StartFileName;
+ std::string StartFileName;
std::string FunctionName(DILineInfo::BadString);
- getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, Spec.FLIKind,
- FunctionName, StartFileName, StartLine);
+ getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, Spec.FLIKind,
+ FunctionName, StartFileName, StartLine);
// If the Specifier says we don't need FileLineInfo, just
// return the top-most function at the starting address.
if (Spec.FLIKind == FileLineInfoKind::None) {
DILineInfo Result;
Result.FunctionName = FunctionName;
- Result.StartFileName = StartFileName;
+ Result.StartFileName = StartFileName;
Result.StartLine = StartLine;
Lines.push_back(std::make_pair(Address.Address, Result));
return Lines;
@@ -1284,7 +1284,7 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(
Result.FunctionName = FunctionName;
Result.Line = Row.Line;
Result.Column = Row.Column;
- Result.StartFileName = StartFileName;
+ Result.StartFileName = StartFileName;
Result.StartLine = StartLine;
Lines.push_back(std::make_pair(Row.Address.Address, Result));
}
@@ -1327,7 +1327,7 @@ DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address,
Frame.FunctionName = Name;
if (auto DeclLineResult = FunctionDIE.getDeclLine())
Frame.StartLine = DeclLineResult;
- Frame.StartFileName = FunctionDIE.getDeclFile(Spec.FLIKind);
+ Frame.StartFileName = FunctionDIE.getDeclFile(Spec.FLIKind);
if (Spec.FLIKind != FileLineInfoKind::None) {
if (i == 0) {
// For the topmost frame, initialize the line table of this
@@ -1709,17 +1709,17 @@ public:
// FIXME: Use the other dwo range section when we emit it.
RangesDWOSection.Data = Data;
}
- } else if (InfoSectionMap *Sections =
- StringSwitch<InfoSectionMap *>(Name)
- .Case("debug_info", &InfoSections)
- .Case("debug_info.dwo", &InfoDWOSections)
- .Case("debug_types", &TypesSections)
- .Case("debug_types.dwo", &TypesDWOSections)
- .Default(nullptr)) {
+ } else if (InfoSectionMap *Sections =
+ StringSwitch<InfoSectionMap *>(Name)
+ .Case("debug_info", &InfoSections)
+ .Case("debug_info.dwo", &InfoDWOSections)
+ .Case("debug_types", &TypesSections)
+ .Case("debug_types.dwo", &TypesDWOSections)
+ .Default(nullptr)) {
// Find debug_info and debug_types data by section rather than name as
// there are multiple, comdat grouped, of these sections.
- DWARFSectionMap &S = (*Sections)[Section];
- S.Data = Data;
+ DWARFSectionMap &S = (*Sections)[Section];
+ S.Data = Data;
}
if (RelocatedSection == Obj.section_end())
@@ -1780,7 +1780,7 @@ public:
// Symbol to [address, section index] cache mapping.
std::map<SymbolRef, SymInfo> AddrCache;
- SupportsRelocation Supports;
+ SupportsRelocation Supports;
RelocationResolver Resolver;
std::tie(Supports, Resolver) = getRelocationResolver(Obj);
for (const RelocationRef &Reloc : Section.relocations()) {
@@ -1998,6 +1998,6 @@ uint8_t DWARFContext::getCUAddrSize() {
// first compile unit. In practice the address size field is repeated across
// various DWARF headers (at least in version 5) to make it easier to dump
// them independently, not to enable varying the address size.
- auto CUs = compile_units();
+ auto CUs = compile_units();
return CUs.empty() ? 0 : (*CUs.begin())->getAddressByteSize();
}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
index fb16d8b35a..da6f6ad903 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
@@ -53,16 +53,16 @@ uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint64_t *Off,
ErrorAsOutParameter ErrAsOut(Err);
Optional<RelocAddrEntry> E = Obj->find(*Section, *Off);
- uint64_t LocData = getUnsigned(Off, Size, Err);
+ uint64_t LocData = getUnsigned(Off, Size, Err);
if (!E || (Err && *Err))
- return LocData;
+ return LocData;
if (SecNdx)
*SecNdx = E->SectionIndex;
-
- uint64_t R =
- object::resolveRelocation(E->Resolver, E->Reloc, E->SymbolValue, LocData);
+
+ uint64_t R =
+ object::resolveRelocation(E->Resolver, E->Reloc, E->SymbolValue, LocData);
if (E->Reloc2)
- R = object::resolveRelocation(E->Resolver, *E->Reloc2, E->SymbolValue2, R);
+ R = object::resolveRelocation(E->Resolver, *E->Reloc2, E->SymbolValue2, R);
return R;
}
@@ -106,10 +106,10 @@ DWARFDataExtractor::getEncodedPointer(uint64_t *Offset, uint8_t Encoding,
Result = getSigned(Offset, 2);
break;
case dwarf::DW_EH_PE_sdata4:
- Result = SignExtend64<32>(getRelocatedValue(4, Offset));
+ Result = SignExtend64<32>(getRelocatedValue(4, Offset));
break;
case dwarf::DW_EH_PE_sdata8:
- Result = getRelocatedValue(8, Offset);
+ Result = getRelocatedValue(8, Offset);
break;
default:
return None;
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
index 8a7809598d..598e3ecee3 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
@@ -8,7 +8,7 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
@@ -21,11 +21,11 @@ using namespace llvm;
void DWARFDebugArangeSet::Descriptor::dump(raw_ostream &OS,
uint32_t AddressSize) const {
- OS << '[';
- DWARFFormValue::dumpAddress(OS, AddressSize, Address);
- OS << ", ";
- DWARFFormValue::dumpAddress(OS, AddressSize, getEndAddress());
- OS << ')';
+ OS << '[';
+ DWARFFormValue::dumpAddress(OS, AddressSize, Address);
+ OS << ", ";
+ DWARFFormValue::dumpAddress(OS, AddressSize, getEndAddress());
+ OS << ')';
}
void DWARFDebugArangeSet::clear() {
@@ -35,8 +35,8 @@ void DWARFDebugArangeSet::clear() {
}
Error DWARFDebugArangeSet::extract(DWARFDataExtractor data,
- uint64_t *offset_ptr,
- function_ref<void(Error)> WarningHandler) {
+ uint64_t *offset_ptr,
+ function_ref<void(Error)> WarningHandler) {
assert(data.isValidOffset(*offset_ptr));
ArangeDescriptors.clear();
Offset = *offset_ptr;
@@ -145,11 +145,11 @@ Error DWARFDebugArangeSet::extract(DWARFDataExtractor data,
if (arangeDescriptor.Length == 0 && arangeDescriptor.Address == 0) {
if (*offset_ptr == end_offset)
return ErrorSuccess();
- WarningHandler(createStringError(
+ WarningHandler(createStringError(
errc::invalid_argument,
"address range table at offset 0x%" PRIx64
" has a premature terminator entry at offset 0x%" PRIx64,
- Offset, EntryOffset));
+ Offset, EntryOffset));
}
ArangeDescriptors.push_back(arangeDescriptor);
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
index fbbf8af840..e0db469752 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
@@ -28,8 +28,8 @@ void DWARFDebugAranges::extract(
DWARFDebugArangeSet Set;
while (DebugArangesData.isValidOffset(Offset)) {
- if (Error E =
- Set.extract(DebugArangesData, &Offset, RecoverableErrorHandler)) {
+ if (Error E =
+ Set.extract(DebugArangesData, &Offset, RecoverableErrorHandler)) {
RecoverableErrorHandler(std::move(E));
return;
}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
index 788ea89400..b74ecac681 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
@@ -12,7 +12,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataExtractor.h"
@@ -30,18 +30,18 @@
using namespace llvm;
using namespace dwarf;
-static void printRegister(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
- unsigned RegNum) {
- if (MRI) {
- if (Optional<unsigned> LLVMRegNum = MRI->getLLVMRegNum(RegNum, IsEH)) {
- if (const char *RegName = MRI->getName(*LLVMRegNum)) {
- OS << RegName;
- return;
- }
- }
- }
- OS << "reg" << RegNum;
-}
+static void printRegister(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
+ unsigned RegNum) {
+ if (MRI) {
+ if (Optional<unsigned> LLVMRegNum = MRI->getLLVMRegNum(RegNum, IsEH)) {
+ if (const char *RegName = MRI->getName(*LLVMRegNum)) {
+ OS << RegName;
+ return;
+ }
+ }
+ }
+ OS << "reg" << RegNum;
+}
// See DWARF standard v3, section 7.23
const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
@@ -234,10 +234,10 @@ ArrayRef<CFIProgram::OperandType[2]> CFIProgram::getOperandTypes() {
}
/// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
-void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
- const MCRegisterInfo *MRI, bool IsEH,
- const Instruction &Instr, unsigned OperandIdx,
- uint64_t Operand) const {
+void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
+ const MCRegisterInfo *MRI, bool IsEH,
+ const Instruction &Instr, unsigned OperandIdx,
+ uint64_t Operand) const {
assert(OperandIdx < 2);
uint8_t Opcode = Instr.Opcode;
OperandType Type = getOperandTypes()[Opcode][OperandIdx];
@@ -282,19 +282,19 @@ void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
OS << format(" %" PRId64 "*data_alignment_factor" , Operand);
break;
case OT_Register:
- OS << ' ';
- printRegister(OS, MRI, IsEH, Operand);
+ OS << ' ';
+ printRegister(OS, MRI, IsEH, Operand);
break;
case OT_Expression:
assert(Instr.Expression && "missing DWARFExpression object");
OS << " ";
- Instr.Expression->print(OS, DumpOpts, MRI, nullptr, IsEH);
+ Instr.Expression->print(OS, DumpOpts, MRI, nullptr, IsEH);
break;
}
}
-void CFIProgram::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
- const MCRegisterInfo *MRI, bool IsEH,
+void CFIProgram::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
+ const MCRegisterInfo *MRI, bool IsEH,
unsigned IndentLevel) const {
for (const auto &Instr : Instructions) {
uint8_t Opcode = Instr.Opcode;
@@ -303,7 +303,7 @@ void CFIProgram::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
OS.indent(2 * IndentLevel);
OS << CallFrameString(Opcode, Arch) << ":";
for (unsigned i = 0; i < Instr.Ops.size(); ++i)
- printOperand(OS, DumpOpts, MRI, IsEH, Instr, i, Instr.Ops[i]);
+ printOperand(OS, DumpOpts, MRI, IsEH, Instr, i, Instr.Ops[i]);
OS << '\n';
}
}
@@ -320,8 +320,8 @@ constexpr uint64_t getCIEId(bool IsDWARF64, bool IsEH) {
return DW_CIE_ID;
}
-void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
- const MCRegisterInfo *MRI, bool IsEH) const {
+void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
+ const MCRegisterInfo *MRI, bool IsEH) const {
// A CIE with a zero length is a terminator entry in the .eh_frame section.
if (IsEH && Length == 0) {
OS << format("%08" PRIx64, Offset) << " ZERO terminator\n";
@@ -353,12 +353,12 @@ void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
OS << "\n";
}
OS << "\n";
- CFIs.dump(OS, DumpOpts, MRI, IsEH);
+ CFIs.dump(OS, DumpOpts, MRI, IsEH);
OS << "\n";
}
-void FDE::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
- const MCRegisterInfo *MRI, bool IsEH) const {
+void FDE::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
+ const MCRegisterInfo *MRI, bool IsEH) const {
OS << format("%08" PRIx64, Offset)
<< format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length)
<< format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, CIEPointer)
@@ -372,7 +372,7 @@ void FDE::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
OS << " Format: " << FormatString(IsDWARF64) << "\n";
if (LSDAAddress)
OS << format(" LSDA Address: %016" PRIx64 "\n", *LSDAAddress);
- CFIs.dump(OS, DumpOpts, MRI, IsEH);
+ CFIs.dump(OS, DumpOpts, MRI, IsEH);
OS << "\n";
}
@@ -539,9 +539,9 @@ Error DWARFDebugFrame::parse(DWARFDataExtractor Data) {
"parsing FDE data at 0x%" PRIx64
" failed due to missing CIE",
StartOffset);
- if (auto Val =
- Data.getEncodedPointer(&Offset, Cie->getFDEPointerEncoding(),
- EHFrameAddress + Offset)) {
+ if (auto Val =
+ Data.getEncodedPointer(&Offset, Cie->getFDEPointerEncoding(),
+ EHFrameAddress + Offset)) {
InitialLocation = *Val;
}
if (auto Val = Data.getEncodedPointer(
@@ -601,16 +601,16 @@ FrameEntry *DWARFDebugFrame::getEntryAtOffset(uint64_t Offset) const {
return nullptr;
}
-void DWARFDebugFrame::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
- const MCRegisterInfo *MRI,
+void DWARFDebugFrame::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
+ const MCRegisterInfo *MRI,
Optional<uint64_t> Offset) const {
if (Offset) {
if (auto *Entry = getEntryAtOffset(*Offset))
- Entry->dump(OS, DumpOpts, MRI, IsEH);
+ Entry->dump(OS, DumpOpts, MRI, IsEH);
return;
}
OS << "\n";
for (const auto &Entry : Entries)
- Entry->dump(OS, DumpOpts, MRI, IsEH);
+ Entry->dump(OS, DumpOpts, MRI, IsEH);
}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
index ce3a49201f..2b7d0c3363 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
@@ -38,8 +38,8 @@ bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint64_t *OffsetPtr,
AbbrevDecl = nullptr;
return true;
}
- if (const auto *AbbrevSet = U.getAbbreviations())
- AbbrevDecl = AbbrevSet->getAbbreviationDeclaration(AbbrCode);
+ if (const auto *AbbrevSet = U.getAbbreviations())
+ AbbrevDecl = AbbrevSet->getAbbreviationDeclaration(AbbrCode);
if (nullptr == AbbrevDecl) {
// Restore the original offset.
*OffsetPtr = Offset;
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index a0758247a6..bda41b1f34 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -79,18 +79,18 @@ bool DWARFDebugLine::Prologue::hasFileAtIndex(uint64_t FileIndex) const {
return FileIndex != 0 && FileIndex <= FileNames.size();
}
-Optional<uint64_t> DWARFDebugLine::Prologue::getLastValidFileIndex() const {
- if (FileNames.empty())
- return None;
- uint16_t DwarfVersion = getVersion();
- assert(DwarfVersion != 0 &&
- "line table prologue has no dwarf version information");
- // In DWARF v5 the file names are 0-indexed.
- if (DwarfVersion >= 5)
- return FileNames.size() - 1;
- return FileNames.size();
-}
-
+Optional<uint64_t> DWARFDebugLine::Prologue::getLastValidFileIndex() const {
+ if (FileNames.empty())
+ return None;
+ uint16_t DwarfVersion = getVersion();
+ assert(DwarfVersion != 0 &&
+ "line table prologue has no dwarf version information");
+ // In DWARF v5 the file names are 0-indexed.
+ if (DwarfVersion >= 5)
+ return FileNames.size() - 1;
+ return FileNames.size();
+}
+
const llvm::DWARFDebugLine::FileNameEntry &
DWARFDebugLine::Prologue::getFileNameEntry(uint64_t Index) const {
uint16_t DwarfVersion = getVersion();
@@ -783,18 +783,18 @@ Error DWARFDebugLine::LineTable::parse(
*OS << '\n';
Row::dumpTableHeader(*OS, /*Indent=*/Verbose ? 12 : 0);
}
- bool TombstonedAddress = false;
- auto EmitRow = [&] {
- if (!TombstonedAddress) {
- if (Verbose) {
- *OS << "\n";
- OS->indent(12);
- }
- if (OS)
- State.Row.dump(*OS);
- State.appendRowToMatrix();
- }
- };
+ bool TombstonedAddress = false;
+ auto EmitRow = [&] {
+ if (!TombstonedAddress) {
+ if (Verbose) {
+ *OS << "\n";
+ OS->indent(12);
+ }
+ if (OS)
+ State.Row.dump(*OS);
+ State.appendRowToMatrix();
+ }
+ };
while (*OffsetPtr < EndOffset) {
DataExtractor::Cursor Cursor(*OffsetPtr);
@@ -846,7 +846,7 @@ Error DWARFDebugLine::LineTable::parse(
// No need to test the Cursor is valid here, since it must be to get
// into this code path - if it were invalid, the default case would be
// followed.
- EmitRow();
+ EmitRow();
State.resetRowAndSequence();
break;
@@ -888,20 +888,20 @@ Error DWARFDebugLine::LineTable::parse(
State.Row.Address.Address = TableData.getRelocatedAddress(
Cursor, &State.Row.Address.SectionIndex);
- uint64_t Tombstone =
- dwarf::computeTombstoneAddress(OpcodeAddressSize);
- TombstonedAddress = State.Row.Address.Address == Tombstone;
-
+ uint64_t Tombstone =
+ dwarf::computeTombstoneAddress(OpcodeAddressSize);
+ TombstonedAddress = State.Row.Address.Address == Tombstone;
+
// Restore the address size if the extractor already had it.
if (ExtractorAddressSize != 0)
TableData.setAddressSize(ExtractorAddressSize);
}
- if (Cursor && Verbose) {
- *OS << " (";
- DWARFFormValue::dumpAddress(*OS, OpcodeAddressSize, State.Row.Address.Address);
- *OS << ')';
- }
+ if (Cursor && Verbose) {
+ *OS << " (";
+ DWARFFormValue::dumpAddress(*OS, OpcodeAddressSize, State.Row.Address.Address);
+ *OS << ')';
+ }
}
break;
@@ -994,7 +994,7 @@ Error DWARFDebugLine::LineTable::parse(
case DW_LNS_copy:
// Takes no arguments. Append a row to the matrix using the
// current values of the state-machine registers.
- EmitRow();
+ EmitRow();
break;
case DW_LNS_advance_pc:
@@ -1159,9 +1159,9 @@ Error DWARFDebugLine::LineTable::parse(
ParsingState::AddrAndLineDelta Delta =
State.handleSpecialOpcode(Opcode, OpcodeOffset);
- if (Verbose)
- *OS << "address += " << Delta.Address << ", line += " << Delta.Line;
- EmitRow();
+ if (Verbose)
+ *OS << "address += " << Delta.Address << ", line += " << Delta.Line;
+ EmitRow();
*OffsetPtr = Cursor.tell();
}
@@ -1419,20 +1419,20 @@ bool DWARFDebugLine::LineTable::getFileLineInfoForAddress(
// Therefore, collect up handles on all the Units that point into the
// line-table section.
static DWARFDebugLine::SectionParser::LineToUnitMap
-buildLineToUnitMap(DWARFUnitVector::iterator_range Units) {
+buildLineToUnitMap(DWARFUnitVector::iterator_range Units) {
DWARFDebugLine::SectionParser::LineToUnitMap LineToUnit;
- for (const auto &U : Units)
- if (auto CUDIE = U->getUnitDIE())
+ for (const auto &U : Units)
+ if (auto CUDIE = U->getUnitDIE())
if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list)))
- LineToUnit.insert(std::make_pair(*StmtOffset, &*U));
+ LineToUnit.insert(std::make_pair(*StmtOffset, &*U));
return LineToUnit;
}
-DWARFDebugLine::SectionParser::SectionParser(
- DWARFDataExtractor &Data, const DWARFContext &C,
- DWARFUnitVector::iterator_range Units)
+DWARFDebugLine::SectionParser::SectionParser(
+ DWARFDataExtractor &Data, const DWARFContext &C,
+ DWARFUnitVector::iterator_range Units)
: DebugLineData(Data), Context(C) {
- LineToUnit = buildLineToUnitMap(Units);
+ LineToUnit = buildLineToUnitMap(Units);
if (!DebugLineData.isValidOffset(Offset))
Done = true;
}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
index 710a0536fa..cdffb36741 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
@@ -106,16 +106,16 @@ DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) {
}
}
-static void dumpExpression(raw_ostream &OS, DIDumpOptions DumpOpts,
- ArrayRef<uint8_t> Data, bool IsLittleEndian,
- unsigned AddressSize, const MCRegisterInfo *MRI,
- DWARFUnit *U) {
+static void dumpExpression(raw_ostream &OS, DIDumpOptions DumpOpts,
+ ArrayRef<uint8_t> Data, bool IsLittleEndian,
+ unsigned AddressSize, const MCRegisterInfo *MRI,
+ DWARFUnit *U) {
DWARFDataExtractor Extractor(Data, IsLittleEndian, AddressSize);
// Note. We do not pass any format to DWARFExpression, even if the
// corresponding unit is known. For now, there is only one operation,
// DW_OP_call_ref, which depends on the format; it is rarely used, and
// is unexpected in location tables.
- DWARFExpression(Extractor, AddressSize).print(OS, DumpOpts, MRI, U);
+ DWARFExpression(Extractor, AddressSize).print(OS, DumpOpts, MRI, U);
}
bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
@@ -155,8 +155,8 @@ bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
E.Kind != dwarf::DW_LLE_base_addressx &&
E.Kind != dwarf::DW_LLE_end_of_list) {
OS << ": ";
- dumpExpression(OS, DumpOpts, E.Loc, Data.isLittleEndian(),
- Data.getAddressSize(), MRI, U);
+ dumpExpression(OS, DumpOpts, E.Loc, Data.isLittleEndian(),
+ Data.getAddressSize(), MRI, U);
}
return true;
});
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
index c153186b61..80ffd81b34 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
@@ -40,7 +40,7 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const {
unsigned IndLevel = 0;
for (const auto &Macros : MacroLists) {
OS << format("0x%08" PRIx64 ":\n", Macros.Offset);
- if (Macros.IsDebugMacro)
+ if (Macros.IsDebugMacro)
Macros.Header.dumpMacroHeader(OS);
for (const Entry &E : Macros.Macros) {
// There should not be DW_MACINFO_end_file when IndLevel is Zero. However,
@@ -52,10 +52,10 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const {
OS << " ";
IndLevel += (E.Type == DW_MACINFO_start_file);
// Based on which version we are handling choose appropriate macro forms.
- if (Macros.IsDebugMacro)
- WithColor(OS, HighlightColor::Macro).get()
- << (Macros.Header.Version < 5 ? GnuMacroString(E.Type)
- : MacroString(E.Type));
+ if (Macros.IsDebugMacro)
+ WithColor(OS, HighlightColor::Macro).get()
+ << (Macros.Header.Version < 5 ? GnuMacroString(E.Type)
+ : MacroString(E.Type));
else
WithColor(OS, HighlightColor::Macro).get() << MacinfoString(E.Type);
switch (E.Type) {
@@ -69,9 +69,9 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const {
// DW_MACRO_start_file == DW_MACINFO_start_file
// DW_MACRO_end_file == DW_MACINFO_end_file
// For readability/uniformity we are using DW_MACRO_*.
- //
- // The GNU .debug_macro extension's entries have the same encoding
- // as DWARF 5's DW_MACRO_* entries, so we only use the latter here.
+ //
+ // The GNU .debug_macro extension's entries have the same encoding
+ // as DWARF 5's DW_MACRO_* entries, so we only use the latter here.
case DW_MACRO_define:
case DW_MACRO_undef:
case DW_MACRO_define_strp:
@@ -102,7 +102,7 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const {
}
Error DWARFDebugMacro::parseImpl(
- Optional<DWARFUnitVector::compile_unit_range> Units,
+ Optional<DWARFUnitVector::compile_unit_range> Units,
Optional<DataExtractor> StringExtractor, DWARFDataExtractor Data,
bool IsMacro) {
uint64_t Offset = 0;
@@ -123,7 +123,7 @@ Error DWARFDebugMacro::parseImpl(
MacroLists.emplace_back();
M = &MacroLists.back();
M->Offset = Offset;
- M->IsDebugMacro = IsMacro;
+ M->IsDebugMacro = IsMacro;
if (IsMacro) {
auto Err = M->Header.parseMacroHeader(Data, &Offset);
if (Err)
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
index 38bc79c3ed..dc7da5d934 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
@@ -70,9 +70,9 @@ void DWARFDebugRangeList::dump(raw_ostream &OS) const {
DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
llvm::Optional<object::SectionedAddress> BaseAddr) const {
DWARFAddressRangesVector Res;
- // debug_addr can't use the max integer tombstone because that's used for the
- // base address specifier entry - so use max-1.
- uint64_t Tombstone = dwarf::computeTombstoneAddress(AddressSize) - 1;
+ // debug_addr can't use the max integer tombstone because that's used for the
+ // base address specifier entry - so use max-1.
+ uint64_t Tombstone = dwarf::computeTombstoneAddress(AddressSize) - 1;
for (const RangeListEntry &RLE : Entries) {
if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
BaseAddr = {RLE.EndAddress, RLE.SectionIndex};
@@ -81,16 +81,16 @@ DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
DWARFAddressRange E;
E.LowPC = RLE.StartAddress;
- if (E.LowPC == Tombstone)
- continue;
+ if (E.LowPC == Tombstone)
+ continue;
E.HighPC = RLE.EndAddress;
E.SectionIndex = RLE.SectionIndex;
// Base address of a range list entry is determined by the closest preceding
// base address selection entry in the same range list. It defaults to the
// base address of the compilation unit if there is no such entry.
if (BaseAddr) {
- if (BaseAddr->Address == Tombstone)
- continue;
+ if (BaseAddr->Address == Tombstone)
+ continue;
E.LowPC += BaseAddr->Address;
E.HighPC += BaseAddr->Address;
if (E.SectionIndex == -1ULL)
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
index bca8512467..d12acca196 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
@@ -8,7 +8,7 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
@@ -17,87 +17,87 @@
using namespace llvm;
-Error RangeListEntry::extract(DWARFDataExtractor Data, uint64_t *OffsetPtr) {
+Error RangeListEntry::extract(DWARFDataExtractor Data, uint64_t *OffsetPtr) {
Offset = *OffsetPtr;
SectionIndex = -1ULL;
// The caller should guarantee that we have at least 1 byte available, so
// we just assert instead of revalidate.
- assert(*OffsetPtr < Data.size() &&
+ assert(*OffsetPtr < Data.size() &&
"not enough space to extract a rangelist encoding");
uint8_t Encoding = Data.getU8(OffsetPtr);
- DataExtractor::Cursor C(*OffsetPtr);
+ DataExtractor::Cursor C(*OffsetPtr);
switch (Encoding) {
case dwarf::DW_RLE_end_of_list:
Value0 = Value1 = 0;
break;
// TODO: Support other encodings.
case dwarf::DW_RLE_base_addressx: {
- Value0 = Data.getULEB128(C);
+ Value0 = Data.getULEB128(C);
break;
}
case dwarf::DW_RLE_startx_endx:
- Value0 = Data.getULEB128(C);
- Value1 = Data.getULEB128(C);
- break;
+ Value0 = Data.getULEB128(C);
+ Value1 = Data.getULEB128(C);
+ break;
case dwarf::DW_RLE_startx_length: {
- Value0 = Data.getULEB128(C);
- Value1 = Data.getULEB128(C);
+ Value0 = Data.getULEB128(C);
+ Value1 = Data.getULEB128(C);
break;
}
case dwarf::DW_RLE_offset_pair: {
- Value0 = Data.getULEB128(C);
- Value1 = Data.getULEB128(C);
+ Value0 = Data.getULEB128(C);
+ Value1 = Data.getULEB128(C);
break;
}
case dwarf::DW_RLE_base_address: {
- Value0 = Data.getRelocatedAddress(C, &SectionIndex);
+ Value0 = Data.getRelocatedAddress(C, &SectionIndex);
break;
}
case dwarf::DW_RLE_start_end: {
- Value0 = Data.getRelocatedAddress(C, &SectionIndex);
- Value1 = Data.getRelocatedAddress(C);
+ Value0 = Data.getRelocatedAddress(C, &SectionIndex);
+ Value1 = Data.getRelocatedAddress(C);
break;
}
case dwarf::DW_RLE_start_length: {
- Value0 = Data.getRelocatedAddress(C, &SectionIndex);
- Value1 = Data.getULEB128(C);
+ Value0 = Data.getRelocatedAddress(C, &SectionIndex);
+ Value1 = Data.getULEB128(C);
break;
}
default:
- consumeError(C.takeError());
+ consumeError(C.takeError());
return createStringError(errc::not_supported,
- "unknown rnglists encoding 0x%" PRIx32
- " at offset 0x%" PRIx64,
- uint32_t(Encoding), Offset);
+ "unknown rnglists encoding 0x%" PRIx32
+ " at offset 0x%" PRIx64,
+ uint32_t(Encoding), Offset);
+ }
+
+ if (!C) {
+ consumeError(C.takeError());
+ return createStringError(
+ errc::invalid_argument,
+ "read past end of table when reading %s encoding at offset 0x%" PRIx64,
+ dwarf::RLEString(Encoding).data(), Offset);
}
- if (!C) {
- consumeError(C.takeError());
- return createStringError(
- errc::invalid_argument,
- "read past end of table when reading %s encoding at offset 0x%" PRIx64,
- dwarf::RLEString(Encoding).data(), Offset);
- }
-
- *OffsetPtr = C.tell();
+ *OffsetPtr = C.tell();
EntryKind = Encoding;
return Error::success();
}
DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
llvm::Optional<object::SectionedAddress> BaseAddr, DWARFUnit &U) const {
- return getAbsoluteRanges(
- BaseAddr, U.getAddressByteSize(),
- [&](uint32_t Index) { return U.getAddrOffsetSectionItem(Index); });
+ return getAbsoluteRanges(
+ BaseAddr, U.getAddressByteSize(),
+ [&](uint32_t Index) { return U.getAddrOffsetSectionItem(Index); });
}
DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
- Optional<object::SectionedAddress> BaseAddr, uint8_t AddressByteSize,
+ Optional<object::SectionedAddress> BaseAddr, uint8_t AddressByteSize,
function_ref<Optional<object::SectionedAddress>(uint32_t)>
LookupPooledAddress) const {
DWARFAddressRangesVector Res;
- uint64_t Tombstone = dwarf::computeTombstoneAddress(AddressByteSize);
+ uint64_t Tombstone = dwarf::computeTombstoneAddress(AddressByteSize);
for (const RangeListEntry &RLE : Entries) {
if (RLE.EntryKind == dwarf::DW_RLE_end_of_list)
break;
@@ -120,12 +120,12 @@ DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
switch (RLE.EntryKind) {
case dwarf::DW_RLE_offset_pair:
E.LowPC = RLE.Value0;
- if (E.LowPC == Tombstone)
- continue;
+ if (E.LowPC == Tombstone)
+ continue;
E.HighPC = RLE.Value1;
if (BaseAddr) {
- if (BaseAddr->Address == Tombstone)
- continue;
+ if (BaseAddr->Address == Tombstone)
+ continue;
E.LowPC += BaseAddr->Address;
E.HighPC += BaseAddr->Address;
}
@@ -147,26 +147,26 @@ DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
E.HighPC = E.LowPC + RLE.Value1;
break;
}
- case dwarf::DW_RLE_startx_endx: {
- auto Start = LookupPooledAddress(RLE.Value0);
- if (!Start)
- Start = {0, -1ULL};
- auto End = LookupPooledAddress(RLE.Value1);
- if (!End)
- End = {0, -1ULL};
- // FIXME: Some error handling if Start.SectionIndex != End.SectionIndex
- E.SectionIndex = Start->SectionIndex;
- E.LowPC = Start->Address;
- E.HighPC = End->Address;
- break;
- }
+ case dwarf::DW_RLE_startx_endx: {
+ auto Start = LookupPooledAddress(RLE.Value0);
+ if (!Start)
+ Start = {0, -1ULL};
+ auto End = LookupPooledAddress(RLE.Value1);
+ if (!End)
+ End = {0, -1ULL};
+ // FIXME: Some error handling if Start.SectionIndex != End.SectionIndex
+ E.SectionIndex = Start->SectionIndex;
+ E.LowPC = Start->Address;
+ E.HighPC = End->Address;
+ break;
+ }
default:
// Unsupported encodings should have been reported during extraction,
// so we should not run into any here.
llvm_unreachable("Unsupported range list encoding");
}
- if (E.LowPC == Tombstone)
- continue;
+ if (E.LowPC == Tombstone)
+ continue;
Res.push_back(E);
}
return Res;
@@ -199,8 +199,8 @@ void RangeListEntry::dump(
OS << ": ";
}
- uint64_t Tombstone = dwarf::computeTombstoneAddress(AddrSize);
-
+ uint64_t Tombstone = dwarf::computeTombstoneAddress(AddrSize);
+
switch (EntryKind) {
case dwarf::DW_RLE_end_of_list:
OS << (DumpOpts.Verbose ? "" : "<End of list>");
@@ -212,7 +212,7 @@ void RangeListEntry::dump(
CurrentBase = Value0;
if (!DumpOpts.Verbose)
return;
- DWARFFormValue::dumpAddress(OS << ' ', AddrSize, Value0);
+ DWARFFormValue::dumpAddress(OS << ' ', AddrSize, Value0);
break;
}
case dwarf::DW_RLE_base_address:
@@ -220,7 +220,7 @@ void RangeListEntry::dump(
CurrentBase = Value0;
if (!DumpOpts.Verbose)
return;
- DWARFFormValue::dumpAddress(OS << ' ', AddrSize, Value0);
+ DWARFFormValue::dumpAddress(OS << ' ', AddrSize, Value0);
break;
case dwarf::DW_RLE_start_length:
PrintRawEntry(OS, *this, AddrSize, DumpOpts);
@@ -228,11 +228,11 @@ void RangeListEntry::dump(
break;
case dwarf::DW_RLE_offset_pair:
PrintRawEntry(OS, *this, AddrSize, DumpOpts);
- if (CurrentBase != Tombstone)
- DWARFAddressRange(Value0 + CurrentBase, Value1 + CurrentBase)
- .dump(OS, AddrSize, DumpOpts);
- else
- OS << "dead code";
+ if (CurrentBase != Tombstone)
+ DWARFAddressRange(Value0 + CurrentBase, Value1 + CurrentBase)
+ .dump(OS, AddrSize, DumpOpts);
+ else
+ OS << "dead code";
break;
case dwarf::DW_RLE_start_end:
DWARFAddressRange(Value0, Value1).dump(OS, AddrSize, DumpOpts);
@@ -245,17 +245,17 @@ void RangeListEntry::dump(
DWARFAddressRange(Start, Start + Value1).dump(OS, AddrSize, DumpOpts);
break;
}
- case dwarf::DW_RLE_startx_endx: {
- PrintRawEntry(OS, *this, AddrSize, DumpOpts);
- uint64_t Start = 0;
- if (auto SA = LookupPooledAddress(Value0))
- Start = SA->Address;
- uint64_t End = 0;
- if (auto SA = LookupPooledAddress(Value1))
- End = SA->Address;
- DWARFAddressRange(Start, End).dump(OS, AddrSize, DumpOpts);
- break;
- }
+ case dwarf::DW_RLE_startx_endx: {
+ PrintRawEntry(OS, *this, AddrSize, DumpOpts);
+ uint64_t Start = 0;
+ if (auto SA = LookupPooledAddress(Value0))
+ Start = SA->Address;
+ uint64_t End = 0;
+ if (auto SA = LookupPooledAddress(Value1))
+ End = SA->Address;
+ DWARFAddressRange(Start, End).dump(OS, AddrSize, DumpOpts);
+ break;
+ }
default:
llvm_unreachable("Unsupported range list encoding");
}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDie.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDie.cpp
index ad67e8af85..5a55f3a041 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -69,7 +69,7 @@ static void dumpRanges(const DWARFObject &Obj, raw_ostream &OS,
}
}
-static void dumpLocation(raw_ostream &OS, const DWARFFormValue &FormValue,
+static void dumpLocation(raw_ostream &OS, const DWARFFormValue &FormValue,
DWARFUnit *U, unsigned Indent,
DIDumpOptions DumpOpts) {
DWARFContext &Ctx = U->getContext();
@@ -80,7 +80,7 @@ static void dumpLocation(raw_ostream &OS, const DWARFFormValue &FormValue,
DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
Ctx.isLittleEndian(), 0);
DWARFExpression(Data, U->getAddressByteSize(), U->getFormParams().Format)
- .print(OS, DumpOpts, MRI, U);
+ .print(OS, DumpOpts, MRI, U);
return;
}
@@ -230,22 +230,22 @@ static void dumpTypeName(raw_ostream &OS, const DWARFDie &D) {
}
static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
- const DWARFAttribute &AttrValue, unsigned Indent,
+ const DWARFAttribute &AttrValue, unsigned Indent,
DIDumpOptions DumpOpts) {
if (!Die.isValid())
return;
const char BaseIndent[] = " ";
OS << BaseIndent;
OS.indent(Indent + 2);
- dwarf::Attribute Attr = AttrValue.Attr;
+ dwarf::Attribute Attr = AttrValue.Attr;
WithColor(OS, HighlightColor::Attribute) << formatv("{0}", Attr);
- dwarf::Form Form = AttrValue.Value.getForm();
+ dwarf::Form Form = AttrValue.Value.getForm();
if (DumpOpts.Verbose || DumpOpts.ShowForm)
OS << formatv(" [{0}]", Form);
DWARFUnit *U = Die.getDwarfUnit();
- const DWARFFormValue &FormValue = AttrValue.Value;
+ const DWARFFormValue &FormValue = AttrValue.Value;
OS << "\t(";
@@ -269,23 +269,23 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
WithColor(OS, Color) << Name;
else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line)
OS << *FormValue.getAsUnsignedConstant();
- else if (Attr == DW_AT_low_pc &&
- (FormValue.getAsAddress() ==
- dwarf::computeTombstoneAddress(U->getAddressByteSize()))) {
- if (DumpOpts.Verbose) {
- FormValue.dump(OS, DumpOpts);
- OS << " (";
- }
- OS << "dead code";
- if (DumpOpts.Verbose)
- OS << ')';
- } else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose &&
- FormValue.getAsUnsignedConstant()) {
+ else if (Attr == DW_AT_low_pc &&
+ (FormValue.getAsAddress() ==
+ dwarf::computeTombstoneAddress(U->getAddressByteSize()))) {
+ if (DumpOpts.Verbose) {
+ FormValue.dump(OS, DumpOpts);
+ OS << " (";
+ }
+ OS << "dead code";
+ if (DumpOpts.Verbose)
+ OS << ')';
+ } else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose &&
+ FormValue.getAsUnsignedConstant()) {
if (DumpOpts.ShowAddresses) {
// Print the actual address rather than the offset.
uint64_t LowPC, HighPC, Index;
if (Die.getLowAndHighPC(LowPC, HighPC, Index))
- DWARFFormValue::dumpAddress(OS, U->getAddressByteSize(), HighPC);
+ DWARFFormValue::dumpAddress(OS, U->getAddressByteSize(), HighPC);
else
FormValue.dump(OS, DumpOpts);
}
@@ -378,7 +378,7 @@ DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const {
Seen.insert(*this);
while (!Worklist.empty()) {
- DWARFDie Die = Worklist.pop_back_val();
+ DWARFDie Die = Worklist.pop_back_val();
if (!Die.isValid())
continue;
@@ -425,9 +425,9 @@ Optional<uint64_t> DWARFDie::getLocBaseAttribute() const {
}
Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const {
- uint64_t Tombstone = dwarf::computeTombstoneAddress(U->getAddressByteSize());
- if (LowPC == Tombstone)
- return None;
+ uint64_t Tombstone = dwarf::computeTombstoneAddress(U->getAddressByteSize());
+ if (LowPC == Tombstone)
+ return None;
if (auto FormValue = find(DW_AT_high_pc)) {
if (auto Address = FormValue->getAsAddress()) {
// High PC is an address.
@@ -479,7 +479,7 @@ void DWARFDie::collectChildrenAddressRanges(
return;
if (isSubprogramDIE()) {
if (auto DIERangesOrError = getAddressRanges())
- llvm::append_range(Ranges, DIERangesOrError.get());
+ llvm::append_range(Ranges, DIERangesOrError.get());
else
llvm::consumeError(DIERangesOrError.takeError());
}
@@ -569,17 +569,17 @@ uint64_t DWARFDie::getDeclLine() const {
return toUnsigned(findRecursively(DW_AT_decl_line), 0);
}
-std::string
-DWARFDie::getDeclFile(DILineInfoSpecifier::FileLineInfoKind Kind) const {
- std::string FileName;
- if (auto DeclFile = toUnsigned(findRecursively(DW_AT_decl_file))) {
- if (const auto *LT = U->getContext().getLineTableForUnit(U)) {
- LT->getFileNameByIndex(*DeclFile, U->getCompilationDir(), Kind, FileName);
- }
- }
- return FileName;
-}
-
+std::string
+DWARFDie::getDeclFile(DILineInfoSpecifier::FileLineInfoKind Kind) const {
+ std::string FileName;
+ if (auto DeclFile = toUnsigned(findRecursively(DW_AT_decl_file))) {
+ if (const auto *LT = U->getContext().getLineTableForUnit(U)) {
+ LT->getFileNameByIndex(*DeclFile, U->getCompilationDir(), Kind, FileName);
+ }
+ }
+ return FileName;
+}
+
void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
uint32_t &CallColumn,
uint32_t &CallDiscriminator) const {
@@ -632,8 +632,8 @@ void DWARFDie::dump(raw_ostream &OS, unsigned Indent,
OS << '\n';
// Dump all data in the DIE for the attributes.
- for (const DWARFAttribute &AttrValue : attributes())
- dumpAttribute(OS, *this, AttrValue, Indent, DumpOpts);
+ for (const DWARFAttribute &AttrValue : attributes())
+ dumpAttribute(OS, *this, AttrValue, Indent, DumpOpts);
DWARFDie child = getFirstChild();
if (DumpOpts.ShowChildren && DumpOpts.ChildRecurseDepth > 0 && child) {
@@ -716,16 +716,16 @@ void DWARFDie::attribute_iterator::updateForIndex(
// Add the previous byte size of any previous attribute value.
AttrValue.Offset += AttrValue.ByteSize;
uint64_t ParseOffset = AttrValue.Offset;
- if (AbbrDecl.getAttrIsImplicitConstByIndex(Index))
- AttrValue.Value = DWARFFormValue::createFromSValue(
- AbbrDecl.getFormByIndex(Index),
- AbbrDecl.getAttrImplicitConstValueByIndex(Index));
- else {
- auto U = Die.getDwarfUnit();
- assert(U && "Die must have valid DWARF unit");
- AttrValue.Value = DWARFFormValue::createFromUnit(
- AbbrDecl.getFormByIndex(Index), U, &ParseOffset);
- }
+ if (AbbrDecl.getAttrIsImplicitConstByIndex(Index))
+ AttrValue.Value = DWARFFormValue::createFromSValue(
+ AbbrDecl.getFormByIndex(Index),
+ AbbrDecl.getAttrImplicitConstValueByIndex(Index));
+ else {
+ auto U = Die.getDwarfUnit();
+ assert(U && "Die must have valid DWARF unit");
+ AttrValue.Value = DWARFFormValue::createFromUnit(
+ AbbrDecl.getFormByIndex(Index), U, &ParseOffset);
+ }
AttrValue.ByteSize = ParseOffset - AttrValue.Offset;
} else {
assert(Index == NumAttrs && "Indexes should be [0, NumAttrs) only");
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFExpression.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFExpression.cpp
index aeb9063d7a..811716111b 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFExpression.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFExpression.cpp
@@ -204,15 +204,15 @@ bool DWARFExpression::Operation::extract(DataExtractor Data,
}
static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS,
- DIDumpOptions DumpOpts, uint64_t Operands[2],
- unsigned Operand) {
+ DIDumpOptions DumpOpts, uint64_t Operands[2],
+ unsigned Operand) {
assert(Operand < 2 && "operand out of bounds");
auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
- OS << " (";
- if (DumpOpts.Verbose)
- OS << format("0x%08" PRIx64 " -> ", Operands[Operand]);
- OS << format("0x%08" PRIx64 ")", U->getOffset() + Operands[Operand]);
+ OS << " (";
+ if (DumpOpts.Verbose)
+ OS << format("0x%08" PRIx64 " -> ", Operands[Operand]);
+ OS << format("0x%08" PRIx64 ")", U->getOffset() + Operands[Operand]);
if (auto Name = Die.find(dwarf::DW_AT_name))
OS << " \"" << Name->getAsCString() << "\"";
} else {
@@ -221,8 +221,8 @@ static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS,
}
}
-static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
- DIDumpOptions DumpOpts, uint8_t Opcode,
+static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
+ DIDumpOptions DumpOpts, uint8_t Opcode,
uint64_t Operands[2],
const MCRegisterInfo *MRI, bool isEH) {
if (!MRI)
@@ -248,7 +248,7 @@ static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
OS << ' ' << RegName;
if (Opcode == DW_OP_regval_type)
- prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, 1);
+ prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, 1);
return true;
}
}
@@ -256,10 +256,10 @@ static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
return false;
}
-bool DWARFExpression::Operation::print(raw_ostream &OS, DIDumpOptions DumpOpts,
+bool DWARFExpression::Operation::print(raw_ostream &OS, DIDumpOptions DumpOpts,
const DWARFExpression *Expr,
const MCRegisterInfo *RegInfo,
- DWARFUnit *U, bool isEH) {
+ DWARFUnit *U, bool isEH) {
if (Error) {
OS << "<decoding error>";
return false;
@@ -273,7 +273,7 @@ bool DWARFExpression::Operation::print(raw_ostream &OS, DIDumpOptions DumpOpts,
(Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) ||
Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
Opcode == DW_OP_regval_type)
- if (prettyPrintRegisterOp(U, OS, DumpOpts, Opcode, Operands, RegInfo, isEH))
+ if (prettyPrintRegisterOp(U, OS, DumpOpts, Opcode, Operands, RegInfo, isEH))
return true;
for (unsigned Operand = 0; Operand < 2; ++Operand) {
@@ -290,7 +290,7 @@ bool DWARFExpression::Operation::print(raw_ostream &OS, DIDumpOptions DumpOpts,
if (Opcode == DW_OP_convert && Operands[Operand] == 0)
OS << " 0x0";
else
- prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, Operand);
+ prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, Operand);
} else if (Size == Operation::WasmLocationArg) {
assert(Operand == 1);
switch (Operands[0]) {
@@ -315,12 +315,12 @@ bool DWARFExpression::Operation::print(raw_ostream &OS, DIDumpOptions DumpOpts,
return true;
}
-void DWARFExpression::print(raw_ostream &OS, DIDumpOptions DumpOpts,
- const MCRegisterInfo *RegInfo, DWARFUnit *U,
- bool IsEH) const {
+void DWARFExpression::print(raw_ostream &OS, DIDumpOptions DumpOpts,
+ const MCRegisterInfo *RegInfo, DWARFUnit *U,
+ bool IsEH) const {
uint32_t EntryValExprSize = 0;
for (auto &Op : *this) {
- if (!Op.print(OS, DumpOpts, this, RegInfo, U, IsEH)) {
+ if (!Op.print(OS, DumpOpts, this, RegInfo, U, IsEH)) {
uint64_t FailOffset = Op.getEndOffset();
while (FailOffset < Data.getData().size())
OS << format(" %02x", Data.getU8(&FailOffset));
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFFormValue.cpp
index 4e1f7b1d48..2559765876 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFFormValue.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFFormValue.cpp
@@ -168,7 +168,7 @@ bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
case DW_FORM_line_strp:
case DW_FORM_GNU_ref_alt:
case DW_FORM_GNU_strp_alt:
- case DW_FORM_implicit_const:
+ case DW_FORM_implicit_const:
if (Optional<uint8_t> FixedSize =
dwarf::getFixedFormByteSize(Form, Params)) {
*OffsetPtr += *FixedSize;
@@ -346,9 +346,9 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
case DW_FORM_ref_sig8:
Value.uval = Data.getU64(OffsetPtr, &Err);
break;
- case DW_FORM_implicit_const:
- // Value has been already set by DWARFFormValue::createFromSValue.
- break;
+ case DW_FORM_implicit_const:
+ // Value has been already set by DWARFFormValue::createFromSValue.
+ break;
default:
// DWARFFormValue::skipValue() will have caught this and caused all
// DWARF DIEs to fail to be parsed, so this code is not be reachable.
@@ -362,16 +362,16 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
return !errorToBool(std::move(Err));
}
-void DWARFFormValue::dumpAddress(raw_ostream &OS, uint8_t AddressSize,
- uint64_t Address) {
- uint8_t HexDigits = AddressSize * 2;
- OS << format("0x%*.*" PRIx64, HexDigits, HexDigits, Address);
-}
-
+void DWARFFormValue::dumpAddress(raw_ostream &OS, uint8_t AddressSize,
+ uint64_t Address) {
+ uint8_t HexDigits = AddressSize * 2;
+ OS << format("0x%*.*" PRIx64, HexDigits, HexDigits, Address);
+}
+
void DWARFFormValue::dumpSectionedAddress(raw_ostream &OS,
DIDumpOptions DumpOpts,
object::SectionedAddress SA) const {
- dumpAddress(OS, U->getAddressByteSize(), SA.Address);
+ dumpAddress(OS, U->getAddressByteSize(), SA.Address);
dumpAddressSection(U->getContext().getDWARFObj(), OS, DumpOpts,
SA.SectionIndex);
}
@@ -486,7 +486,7 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
break;
case DW_FORM_sdata:
- case DW_FORM_implicit_const:
+ case DW_FORM_implicit_const:
OS << Value.sval;
break;
case DW_FORM_udata:
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
index caee9f333d..ace7000f07 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
@@ -71,8 +71,8 @@ void DWARFGdbIndex::dumpSymbolTable(raw_ostream &OS) const {
StringRef Name = ConstantPoolStrings.substr(
ConstantPoolOffset - StringPoolOffset + E.NameOffset);
- auto CuVector = llvm::find_if(
- ConstantPoolVectors,
+ auto CuVector = llvm::find_if(
+ ConstantPoolVectors,
[&](const std::pair<uint32_t, SmallVector<uint32_t, 0>> &V) {
return V.first == E.VecOffset;
});
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFListTable.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFListTable.cpp
index 9d9b85b472..c876af1e9b 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFListTable.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFListTable.cpp
@@ -71,12 +71,12 @@ Error DWARFListTableHeader::extract(DWARFDataExtractor Data,
") than there is space for",
SectionName.data(), HeaderOffset, HeaderData.OffsetEntryCount);
Data.setAddressSize(HeaderData.AddrSize);
- *OffsetPtr += HeaderData.OffsetEntryCount * OffsetByteSize;
+ *OffsetPtr += HeaderData.OffsetEntryCount * OffsetByteSize;
return Error::success();
}
-void DWARFListTableHeader::dump(DataExtractor Data, raw_ostream &OS,
- DIDumpOptions DumpOpts) const {
+void DWARFListTableHeader::dump(DataExtractor Data, raw_ostream &OS,
+ DIDumpOptions DumpOpts) const {
if (DumpOpts.Verbose)
OS << format("0x%8.8" PRIx64 ": ", HeaderOffset);
int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format);
@@ -91,8 +91,8 @@ void DWARFListTableHeader::dump(DataExtractor Data, raw_ostream &OS,
if (HeaderData.OffsetEntryCount > 0) {
OS << "offsets: [";
- for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I) {
- auto Off = *getOffsetEntry(Data, I);
+ for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I) {
+ auto Off = *getOffsetEntry(Data, I);
OS << format("\n0x%0*" PRIx64, OffsetDumpWidth, Off);
if (DumpOpts.Verbose)
OS << format(" => 0x%08" PRIx64,
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
index 527e3cbcaf..a301b65dd4 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
@@ -36,10 +36,10 @@ void DWARFTypeUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
<< ", version = " << format("0x%04x", getVersion());
if (getVersion() >= 5)
OS << ", unit_type = " << dwarf::UnitTypeString(getUnitType());
- OS << ", abbr_offset = " << format("0x%04" PRIx64, getAbbrOffset());
- if (!getAbbreviations())
- OS << " (invalid)";
- OS << ", addr_size = " << format("0x%02x", getAddressByteSize())
+ OS << ", abbr_offset = " << format("0x%04" PRIx64, getAbbrOffset());
+ if (!getAbbreviations())
+ OS << " (invalid)";
+ OS << ", addr_size = " << format("0x%02x", getAddressByteSize())
<< ", name = '" << Name << "'"
<< ", type_signature = " << format("0x%016" PRIx64, getTypeHash())
<< ", type_offset = " << format("0x%04" PRIx64, getTypeOffset())
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFUnit.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 3688321ad6..8493950a29 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -198,8 +198,8 @@ DWARFUnit::getAddrOffsetSectionItem(uint32_t Index) const {
// probably shouldn't be valid, but if a use case is found, here's where to
// support it (probably have to linearly search for the matching skeleton CU
// here)
- if (hasSingleElement(R))
- return (*R.begin())->getAddrOffsetSectionItem(Index);
+ if (hasSingleElement(R))
+ return (*R.begin())->getAddrOffsetSectionItem(Index);
}
if (!AddrOffsetSectionBase)
return None;
@@ -467,7 +467,7 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
if (getVersion() >= 5) {
// In case of DWP, the base offset from the index has to be added.
if (IsDWO) {
- uint64_t ContributionBaseOffset = 0;
+ uint64_t ContributionBaseOffset = 0;
if (auto *IndexEntry = Header.getIndexEntry())
if (auto *Contrib = IndexEntry->getContribution(DW_SECT_RNGLISTS))
ContributionBaseOffset = Contrib->Offset;
@@ -477,36 +477,36 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
DWARFListTableHeader::getHeaderSize(Header.getFormat()));
} else
setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
- toSectionOffset(UnitDie.find(DW_AT_rnglists_base),
- DWARFListTableHeader::getHeaderSize(
- Header.getFormat())));
- }
-
- if (IsDWO) {
- // If we are reading a package file, we need to adjust the location list
- // data based on the index entries.
- StringRef Data = Header.getVersion() >= 5
- ? Context.getDWARFObj().getLoclistsDWOSection().Data
- : Context.getDWARFObj().getLocDWOSection().Data;
- if (auto *IndexEntry = Header.getIndexEntry())
- if (const auto *C = IndexEntry->getContribution(
- Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))
- Data = Data.substr(C->Offset, C->Length);
-
- DWARFDataExtractor DWARFData(Data, isLittleEndian, getAddressByteSize());
- LocTable =
- std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion());
- LocSectionBase = DWARFListTableHeader::getHeaderSize(Header.getFormat());
- } else if (getVersion() >= 5) {
- LocTable = std::make_unique<DWARFDebugLoclists>(
- DWARFDataExtractor(Context.getDWARFObj(),
- Context.getDWARFObj().getLoclistsSection(),
- isLittleEndian, getAddressByteSize()),
- getVersion());
- } else {
- LocTable = std::make_unique<DWARFDebugLoc>(DWARFDataExtractor(
- Context.getDWARFObj(), Context.getDWARFObj().getLocSection(),
- isLittleEndian, getAddressByteSize()));
+ toSectionOffset(UnitDie.find(DW_AT_rnglists_base),
+ DWARFListTableHeader::getHeaderSize(
+ Header.getFormat())));
+ }
+
+ if (IsDWO) {
+ // If we are reading a package file, we need to adjust the location list
+ // data based on the index entries.
+ StringRef Data = Header.getVersion() >= 5
+ ? Context.getDWARFObj().getLoclistsDWOSection().Data
+ : Context.getDWARFObj().getLocDWOSection().Data;
+ if (auto *IndexEntry = Header.getIndexEntry())
+ if (const auto *C = IndexEntry->getContribution(
+ Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))
+ Data = Data.substr(C->Offset, C->Length);
+
+ DWARFDataExtractor DWARFData(Data, isLittleEndian, getAddressByteSize());
+ LocTable =
+ std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion());
+ LocSectionBase = DWARFListTableHeader::getHeaderSize(Header.getFormat());
+ } else if (getVersion() >= 5) {
+ LocTable = std::make_unique<DWARFDebugLoclists>(
+ DWARFDataExtractor(Context.getDWARFObj(),
+ Context.getDWARFObj().getLoclistsSection(),
+ isLittleEndian, getAddressByteSize()),
+ getVersion());
+ } else {
+ LocTable = std::make_unique<DWARFDebugLoc>(DWARFDataExtractor(
+ Context.getDWARFObj(), Context.getDWARFObj().getLocSection(),
+ isLittleEndian, getAddressByteSize()));
}
// Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
@@ -549,8 +549,8 @@ bool DWARFUnit::parseDWO() {
if (AddrOffsetSectionBase)
DWO->setAddrOffsetSection(AddrOffsetSection, *AddrOffsetSectionBase);
if (getVersion() >= 5) {
- DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(),
- DWARFListTableHeader::getHeaderSize(getFormat()));
+ DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(),
+ DWARFListTableHeader::getHeaderSize(getFormat()));
} else {
auto DWORangesBase = UnitDie.getRangesBaseAttribute();
DWO->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0);
@@ -574,13 +574,13 @@ DWARFUnit::findRnglistFromOffset(uint64_t Offset) {
return std::move(E);
return RangeList.getAbsoluteRanges(getBaseAddress());
}
- DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
- isLittleEndian, Header.getAddressByteSize());
- DWARFDebugRnglistTable RnglistTable;
- auto RangeListOrError = RnglistTable.findList(RangesData, Offset);
- if (RangeListOrError)
- return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this);
- return RangeListOrError.takeError();
+ DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
+ isLittleEndian, Header.getAddressByteSize());
+ DWARFDebugRnglistTable RnglistTable;
+ auto RangeListOrError = RnglistTable.findList(RangesData, Offset);
+ if (RangeListOrError)
+ return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this);
+ return RangeListOrError.takeError();
}
Expected<DWARFAddressRangesVector>
@@ -589,9 +589,9 @@ DWARFUnit::findRnglistFromIndex(uint32_t Index) {
return findRnglistFromOffset(*Offset);
return createStringError(errc::invalid_argument,
- "invalid range list table index %d (possibly "
- "missing the entire range list table)",
- Index);
+ "invalid range list table index %d (possibly "
+ "missing the entire range list table)",
+ Index);
}
Expected<DWARFAddressRangesVector> DWARFUnit::collectAddressRanges() {
@@ -921,35 +921,35 @@ DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor & DA) {
// Prior to DWARF v5, we derive the contribution size from the
// index table (in a package file). In a .dwo file it is simply
// the length of the string offsets section.
- StrOffsetsContributionDescriptor Desc;
+ StrOffsetsContributionDescriptor Desc;
if (C)
- Desc = StrOffsetsContributionDescriptor(C->Offset, C->Length, 4,
- Header.getFormat());
- else if (!IndexEntry && !StringOffsetSection.Data.empty())
- Desc = StrOffsetsContributionDescriptor(0, StringOffsetSection.Data.size(),
- 4, Header.getFormat());
- else
- return None;
- auto DescOrError = Desc.validateContributionSize(DA);
- if (!DescOrError)
- return DescOrError.takeError();
- return *DescOrError;
-}
-
-Optional<uint64_t> DWARFUnit::getRnglistOffset(uint32_t Index) {
- DataExtractor RangesData(RangeSection->Data, isLittleEndian,
- getAddressByteSize());
- DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
- isLittleEndian, 0);
- if (Optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry(
- RangesData, RangeSectionBase, getFormat(), Index))
- return *Off + RangeSectionBase;
+ Desc = StrOffsetsContributionDescriptor(C->Offset, C->Length, 4,
+ Header.getFormat());
+ else if (!IndexEntry && !StringOffsetSection.Data.empty())
+ Desc = StrOffsetsContributionDescriptor(0, StringOffsetSection.Data.size(),
+ 4, Header.getFormat());
+ else
+ return None;
+ auto DescOrError = Desc.validateContributionSize(DA);
+ if (!DescOrError)
+ return DescOrError.takeError();
+ return *DescOrError;
+}
+
+Optional<uint64_t> DWARFUnit::getRnglistOffset(uint32_t Index) {
+ DataExtractor RangesData(RangeSection->Data, isLittleEndian,
+ getAddressByteSize());
+ DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
+ isLittleEndian, 0);
+ if (Optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry(
+ RangesData, RangeSectionBase, getFormat(), Index))
+ return *Off + RangeSectionBase;
+ return None;
+}
+
+Optional<uint64_t> DWARFUnit::getLoclistOffset(uint32_t Index) {
+ if (Optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry(
+ LocTable->getData(), LocSectionBase, getFormat(), Index))
+ return *Off + LocSectionBase;
return None;
}
-
-Optional<uint64_t> DWARFUnit::getLoclistOffset(uint32_t Index) {
- if (Optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry(
- LocTable->getData(), LocSectionBase, getFormat(), Index))
- return *Off + LocSectionBase;
- return None;
-}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index 34f7d70883..ac624ec8b8 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -172,15 +172,15 @@ unsigned DWARFVerifier::verifyUnitContents(DWARFUnit &Unit) {
NumUnitErrors += verifyDebugInfoForm(Die, AttrValue);
}
- if (Die.hasChildren()) {
- if (Die.getFirstChild().isValid() &&
- Die.getFirstChild().getTag() == DW_TAG_null) {
- warn() << dwarf::TagString(Die.getTag())
- << " has DW_CHILDREN_yes but DIE has no children: ";
- Die.dump(OS);
- }
- }
-
+ if (Die.hasChildren()) {
+ if (Die.getFirstChild().isValid() &&
+ Die.getFirstChild().getTag() == DW_TAG_null) {
+ warn() << dwarf::TagString(Die.getTag())
+ << " has DW_CHILDREN_yes but DIE has no children: ";
+ Die.dump(OS);
+ }
+ }
+
NumUnitErrors += verifyDebugInfoCallSite(Die);
}
@@ -547,39 +547,39 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
}
break;
}
- case DW_AT_call_file:
- case DW_AT_decl_file: {
- if (auto FileIdx = AttrValue.Value.getAsUnsignedConstant()) {
- DWARFUnit *U = Die.getDwarfUnit();
- const auto *LT = U->getContext().getLineTableForUnit(U);
- if (LT) {
- if (!LT->hasFileAtIndex(*FileIdx)) {
- bool IsZeroIndexed = LT->Prologue.getVersion() >= 5;
- if (Optional<uint64_t> LastFileIdx = LT->getLastValidFileIndex()) {
- ReportError("DIE has " + AttributeString(Attr) +
- " with an invalid file index " +
- llvm::formatv("{0}", *FileIdx) +
- " (valid values are [" + (IsZeroIndexed ? "0-" : "1-") +
- llvm::formatv("{0}", *LastFileIdx) + "])");
- } else {
- ReportError("DIE has " + AttributeString(Attr) +
- " with an invalid file index " +
- llvm::formatv("{0}", *FileIdx) +
- " (the file table in the prologue is empty)");
- }
- }
- } else {
- ReportError("DIE has " + AttributeString(Attr) +
- " that references a file with index " +
- llvm::formatv("{0}", *FileIdx) +
- " and the compile unit has no line table");
- }
- } else {
- ReportError("DIE has " + AttributeString(Attr) +
- " with invalid encoding");
- }
- break;
- }
+ case DW_AT_call_file:
+ case DW_AT_decl_file: {
+ if (auto FileIdx = AttrValue.Value.getAsUnsignedConstant()) {
+ DWARFUnit *U = Die.getDwarfUnit();
+ const auto *LT = U->getContext().getLineTableForUnit(U);
+ if (LT) {
+ if (!LT->hasFileAtIndex(*FileIdx)) {
+ bool IsZeroIndexed = LT->Prologue.getVersion() >= 5;
+ if (Optional<uint64_t> LastFileIdx = LT->getLastValidFileIndex()) {
+ ReportError("DIE has " + AttributeString(Attr) +
+ " with an invalid file index " +
+ llvm::formatv("{0}", *FileIdx) +
+ " (valid values are [" + (IsZeroIndexed ? "0-" : "1-") +
+ llvm::formatv("{0}", *LastFileIdx) + "])");
+ } else {
+ ReportError("DIE has " + AttributeString(Attr) +
+ " with an invalid file index " +
+ llvm::formatv("{0}", *FileIdx) +
+ " (the file table in the prologue is empty)");
+ }
+ }
+ } else {
+ ReportError("DIE has " + AttributeString(Attr) +
+ " that references a file with index " +
+ llvm::formatv("{0}", *FileIdx) +
+ " and the compile unit has no line table");
+ }
+ } else {
+ ReportError("DIE has " + AttributeString(Attr) +
+ " with invalid encoding");
+ }
+ break;
+ }
default:
break;
}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/ya.make b/contrib/libs/llvm12/lib/DebugInfo/DWARF/ya.make
index c17506f9d5..5cb9397828 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/ya.make
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/ya.make
@@ -12,11 +12,11 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/DebugInfo/MSF/MSFBuilder.cpp b/contrib/libs/llvm12/lib/DebugInfo/MSF/MSFBuilder.cpp
index 7c5356908f..f946dd4860 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/MSF/MSFBuilder.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/MSF/MSFBuilder.cpp
@@ -204,7 +204,7 @@ Error MSFBuilder::setStreamSize(uint32_t Idx, uint32_t Size) {
if (auto EC = allocateBlocks(AddedBlocks, AddedBlockList))
return EC;
auto &CurrentBlocks = StreamData[Idx].second;
- llvm::append_range(CurrentBlocks, AddedBlockList);
+ llvm::append_range(CurrentBlocks, AddedBlockList);
} else if (OldBlocks > NewBlocks) {
// For shrinking, free all the Blocks in the Block map, update the stream
// data, then shrink the directory.
@@ -267,7 +267,7 @@ Expected<MSFLayout> MSFBuilder::generateLayout() {
ExtraBlocks.resize(NumExtraBlocks);
if (auto EC = allocateBlocks(NumExtraBlocks, ExtraBlocks))
return std::move(EC);
- llvm::append_range(DirectoryBlocks, ExtraBlocks);
+ llvm::append_range(DirectoryBlocks, ExtraBlocks);
} else if (NumDirectoryBlocks < DirectoryBlocks.size()) {
uint32_t NumUnnecessaryBlocks = DirectoryBlocks.size() - NumDirectoryBlocks;
for (auto B :
diff --git a/contrib/libs/llvm12/lib/DebugInfo/MSF/ya.make b/contrib/libs/llvm12/lib/DebugInfo/MSF/ya.make
index d114fb5377..a9daa7d1aa 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/MSF/ya.make
+++ b/contrib/libs/llvm12/lib/DebugInfo/MSF/ya.make
@@ -12,8 +12,8 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
index 4fcf0f60e2..b6f11a942a 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
@@ -74,7 +74,7 @@ void DbiModuleDescriptorBuilder::addSymbolsInBulk(
if (BulkSymbols.empty())
return;
- Symbols.push_back(SymbolListWrapper(BulkSymbols));
+ Symbols.push_back(SymbolListWrapper(BulkSymbols));
// Symbols written to a PDB file are required to be 4 byte aligned. The same
// is not true of object files.
assert(BulkSymbols.size() % alignOf(CodeViewContainer::Pdb) == 0 &&
@@ -82,18 +82,18 @@ void DbiModuleDescriptorBuilder::addSymbolsInBulk(
SymbolByteSize += BulkSymbols.size();
}
-void DbiModuleDescriptorBuilder::addUnmergedSymbols(void *SymSrc,
- uint32_t SymLength) {
- assert(SymLength > 0);
- Symbols.push_back(SymbolListWrapper(SymSrc, SymLength));
-
- // Symbols written to a PDB file are required to be 4 byte aligned. The same
- // is not true of object files.
- assert(SymLength % alignOf(CodeViewContainer::Pdb) == 0 &&
- "Invalid Symbol alignment!");
- SymbolByteSize += SymLength;
-}
-
+void DbiModuleDescriptorBuilder::addUnmergedSymbols(void *SymSrc,
+ uint32_t SymLength) {
+ assert(SymLength > 0);
+ Symbols.push_back(SymbolListWrapper(SymSrc, SymLength));
+
+ // Symbols written to a PDB file are required to be 4 byte aligned. The same
+ // is not true of object files.
+ assert(SymLength % alignOf(CodeViewContainer::Pdb) == 0 &&
+ "Invalid Symbol alignment!");
+ SymbolByteSize += SymLength;
+}
+
void DbiModuleDescriptorBuilder::addSourceFile(StringRef Path) {
SourceFiles.push_back(std::string(Path));
}
@@ -143,7 +143,7 @@ Error DbiModuleDescriptorBuilder::finalizeMsfLayout() {
return Error::success();
}
-Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter) {
+Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter) {
// We write the Modi record to the `ModiWriter`, but we additionally write its
// symbol stream to a brand new stream.
if (auto EC = ModiWriter.writeObject(Layout))
@@ -154,55 +154,55 @@ Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter) {
return EC;
if (auto EC = ModiWriter.padToAlignment(sizeof(uint32_t)))
return EC;
- return Error::success();
-}
-
-Error DbiModuleDescriptorBuilder::commitSymbolStream(
- const msf::MSFLayout &MsfLayout, WritableBinaryStreamRef MsfBuffer) {
- if (Layout.ModDiStream == kInvalidStreamIndex)
- return Error::success();
-
- auto NS = WritableMappedBlockStream::createIndexedStream(
- MsfLayout, MsfBuffer, Layout.ModDiStream, MSF.getAllocator());
- WritableBinaryStreamRef Ref(*NS);
- BinaryStreamWriter SymbolWriter(Ref);
- // Write the symbols.
- if (auto EC = SymbolWriter.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC))
- return EC;
- for (const SymbolListWrapper &Sym : Symbols) {
- if (Sym.NeedsToBeMerged) {
- assert(MergeSymsCallback);
- if (auto EC = MergeSymsCallback(MergeSymsCtx, Sym.SymPtr, SymbolWriter))
+ return Error::success();
+}
+
+Error DbiModuleDescriptorBuilder::commitSymbolStream(
+ const msf::MSFLayout &MsfLayout, WritableBinaryStreamRef MsfBuffer) {
+ if (Layout.ModDiStream == kInvalidStreamIndex)
+ return Error::success();
+
+ auto NS = WritableMappedBlockStream::createIndexedStream(
+ MsfLayout, MsfBuffer, Layout.ModDiStream, MSF.getAllocator());
+ WritableBinaryStreamRef Ref(*NS);
+ BinaryStreamWriter SymbolWriter(Ref);
+ // Write the symbols.
+ if (auto EC = SymbolWriter.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC))
+ return EC;
+ for (const SymbolListWrapper &Sym : Symbols) {
+ if (Sym.NeedsToBeMerged) {
+ assert(MergeSymsCallback);
+ if (auto EC = MergeSymsCallback(MergeSymsCtx, Sym.SymPtr, SymbolWriter))
return EC;
- } else {
- if (auto EC = SymbolWriter.writeBytes(Sym.asArray()))
+ } else {
+ if (auto EC = SymbolWriter.writeBytes(Sym.asArray()))
return EC;
}
- }
-
- // Apply the string table fixups.
- auto SavedOffset = SymbolWriter.getOffset();
- for (const StringTableFixup &Fixup : StringTableFixups) {
- SymbolWriter.setOffset(Fixup.SymOffsetOfReference);
- if (auto E = SymbolWriter.writeInteger<uint32_t>(Fixup.StrTabOffset))
- return E;
- }
- SymbolWriter.setOffset(SavedOffset);
-
- assert(SymbolWriter.getOffset() % alignOf(CodeViewContainer::Pdb) == 0 &&
- "Invalid debug section alignment!");
- // TODO: Write C11 Line data
- for (const auto &Builder : C13Builders) {
- if (auto EC = Builder.commit(SymbolWriter, CodeViewContainer::Pdb))
+ }
+
+ // Apply the string table fixups.
+ auto SavedOffset = SymbolWriter.getOffset();
+ for (const StringTableFixup &Fixup : StringTableFixups) {
+ SymbolWriter.setOffset(Fixup.SymOffsetOfReference);
+ if (auto E = SymbolWriter.writeInteger<uint32_t>(Fixup.StrTabOffset))
+ return E;
+ }
+ SymbolWriter.setOffset(SavedOffset);
+
+ assert(SymbolWriter.getOffset() % alignOf(CodeViewContainer::Pdb) == 0 &&
+ "Invalid debug section alignment!");
+ // TODO: Write C11 Line data
+ for (const auto &Builder : C13Builders) {
+ if (auto EC = Builder.commit(SymbolWriter, CodeViewContainer::Pdb))
return EC;
}
-
- // TODO: Figure out what GlobalRefs substream actually is and populate it.
- if (auto EC = SymbolWriter.writeInteger<uint32_t>(0))
- return EC;
- if (SymbolWriter.bytesRemaining() > 0)
- return make_error<RawError>(raw_error_code::stream_too_long);
-
+
+ // TODO: Figure out what GlobalRefs substream actually is and populate it.
+ if (auto EC = SymbolWriter.writeInteger<uint32_t>(0))
+ return EC;
+ if (SymbolWriter.bytesRemaining() > 0)
+ return make_error<RawError>(raw_error_code::stream_too_long);
+
return Error::success();
}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
index 48321ae3d9..98a8acaffd 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
@@ -18,7 +18,7 @@
#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/Object/COFF.h"
#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Parallel.h"
+#include "llvm/Support/Parallel.h"
using namespace llvm;
using namespace llvm::codeview;
@@ -395,17 +395,17 @@ Error DbiStreamBuilder::commit(const msf::MSFLayout &Layout,
return EC;
for (auto &M : ModiList) {
- if (auto EC = M->commit(Writer))
+ if (auto EC = M->commit(Writer))
return EC;
}
- // Commit symbol streams. This is a lot of data, so do it in parallel.
- if (auto EC = parallelForEachError(
- ModiList, [&](std::unique_ptr<DbiModuleDescriptorBuilder> &M) {
- return M->commitSymbolStream(Layout, MsfBuffer);
- }))
- return EC;
-
+ // Commit symbol streams. This is a lot of data, so do it in parallel.
+ if (auto EC = parallelForEachError(
+ ModiList, [&](std::unique_ptr<DbiModuleDescriptorBuilder> &M) {
+ return M->commitSymbolStream(Layout, MsfBuffer);
+ }))
+ return EC;
+
if (!SectionContribs.empty()) {
if (auto EC = Writer.writeEnum(DbiSecContribVer60))
return EC;
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
index 6cad5474bb..52df26b679 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
@@ -162,7 +162,7 @@ static int gsiRecordCmp(StringRef S1, StringRef S2) {
if (LLVM_UNLIKELY(!isAsciiString(S1) || !isAsciiString(S2)))
return memcmp(S1.data(), S2.data(), LS);
- // Both strings are ascii, perform a case-insensitive comparison.
+ // Both strings are ascii, perform a case-insensitive comparison.
return S1.compare_lower(S2.data());
}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
index dfe545c889..1d873b87b3 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
@@ -116,7 +116,7 @@ StringMap<uint32_t> NamedStreamMap::entries() const {
uint32_t NamedStreamMap::appendStringData(StringRef S) {
uint32_t Offset = NamesBuffer.size();
- llvm::append_range(NamesBuffer, S);
+ llvm::append_range(NamesBuffer, S);
NamesBuffer.push_back('\0');
return Offset;
}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumSymbols.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumSymbols.cpp
index c861163b3f..feede1dbc9 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumSymbols.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumSymbols.cpp
@@ -1,41 +1,41 @@
-//==- NativeEnumSymbols.cpp - Native Symbol Enumerator impl ------*- C++ -*-==//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h"
-
-#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
-#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::pdb;
-
-NativeEnumSymbols::NativeEnumSymbols(NativeSession &PDBSession,
- std::vector<SymIndexId> Symbols)
- : Symbols(std::move(Symbols)), Index(0), Session(PDBSession) {}
-
-uint32_t NativeEnumSymbols::getChildCount() const {
- return static_cast<uint32_t>(Symbols.size());
-}
-
-std::unique_ptr<PDBSymbol>
-NativeEnumSymbols::getChildAtIndex(uint32_t N) const {
- if (N < Symbols.size()) {
- return Session.getSymbolCache().getSymbolById(Symbols[N]);
- }
- return nullptr;
-}
-
-std::unique_ptr<PDBSymbol> NativeEnumSymbols::getNext() {
- return getChildAtIndex(Index++);
-}
-
-void NativeEnumSymbols::reset() { Index = 0; }
+//==- NativeEnumSymbols.cpp - Native Symbol Enumerator impl ------*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h"
+
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeEnumSymbols::NativeEnumSymbols(NativeSession &PDBSession,
+ std::vector<SymIndexId> Symbols)
+ : Symbols(std::move(Symbols)), Index(0), Session(PDBSession) {}
+
+uint32_t NativeEnumSymbols::getChildCount() const {
+ return static_cast<uint32_t>(Symbols.size());
+}
+
+std::unique_ptr<PDBSymbol>
+NativeEnumSymbols::getChildAtIndex(uint32_t N) const {
+ if (N < Symbols.size()) {
+ return Session.getSymbolCache().getSymbolById(Symbols[N]);
+ }
+ return nullptr;
+}
+
+std::unique_ptr<PDBSymbol> NativeEnumSymbols::getNext() {
+ return getChildAtIndex(Index++);
+}
+
+void NativeEnumSymbols::reset() { Index = 0; }
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp
index 0a8d3de330..7f3b35c297 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp
@@ -8,9 +8,9 @@
#include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h"
-#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h"
#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
@@ -20,10 +20,10 @@ using namespace llvm::pdb;
NativeFunctionSymbol::NativeFunctionSymbol(NativeSession &Session,
SymIndexId Id,
- const codeview::ProcSym &Sym,
- uint32_t Offset)
- : NativeRawSymbol(Session, PDB_SymType::Function, Id), Sym(Sym),
- RecordOffset(Offset) {}
+ const codeview::ProcSym &Sym,
+ uint32_t Offset)
+ : NativeRawSymbol(Session, PDB_SymType::Function, Id), Sym(Sym),
+ RecordOffset(Offset) {}
NativeFunctionSymbol::~NativeFunctionSymbol() {}
@@ -55,89 +55,89 @@ uint32_t NativeFunctionSymbol::getRelativeVirtualAddress() const {
uint64_t NativeFunctionSymbol::getVirtualAddress() const {
return Session.getVAFromSectOffset(Sym.Segment, Sym.CodeOffset);
}
-
-static bool inlineSiteContainsAddress(InlineSiteSym &IS,
- uint32_t OffsetInFunc) {
- // Returns true if inline site contains the offset.
- bool Found = false;
- uint32_t CodeOffset = 0;
- for (auto &Annot : IS.annotations()) {
- switch (Annot.OpCode) {
- case BinaryAnnotationsOpCode::CodeOffset:
- case BinaryAnnotationsOpCode::ChangeCodeOffset:
- case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
- CodeOffset += Annot.U1;
- if (OffsetInFunc >= CodeOffset)
- Found = true;
- break;
- case BinaryAnnotationsOpCode::ChangeCodeLength:
- CodeOffset += Annot.U1;
- if (Found && OffsetInFunc < CodeOffset)
- return true;
- Found = false;
- break;
- case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
- CodeOffset += Annot.U2;
- if (OffsetInFunc >= CodeOffset && OffsetInFunc < CodeOffset + Annot.U1)
- return true;
- Found = false;
- break;
- default:
- break;
- }
- }
- return false;
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-NativeFunctionSymbol::findInlineFramesByVA(uint64_t VA) const {
- uint16_t Modi;
- if (!Session.moduleIndexForVA(VA, Modi))
- return nullptr;
-
- Expected<ModuleDebugStreamRef> ModS = Session.getModuleDebugStream(Modi);
- if (!ModS) {
- consumeError(ModS.takeError());
- return nullptr;
- }
- CVSymbolArray Syms = ModS->getSymbolArray();
-
- // Search for inline sites. There should be one matching top level inline
- // site. Then search in its nested inline sites.
- std::vector<SymIndexId> Frames;
- uint32_t CodeOffset = VA - getVirtualAddress();
- auto Start = Syms.at(RecordOffset);
- auto End = Syms.at(Sym.End);
- while (Start != End) {
- bool Found = false;
- // Find matching inline site within Start and End.
- for (; Start != End; ++Start) {
- if (Start->kind() != S_INLINESITE)
- continue;
-
- InlineSiteSym IS =
- cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(*Start));
- if (inlineSiteContainsAddress(IS, CodeOffset)) {
- // Insert frames in reverse order.
- SymIndexId Id = Session.getSymbolCache().getOrCreateInlineSymbol(
- IS, getVirtualAddress(), Modi, Start.offset());
- Frames.insert(Frames.begin(), Id);
-
- // Update offsets to search within this inline site.
- ++Start;
- End = Syms.at(IS.End);
- Found = true;
- break;
- }
-
- Start = Syms.at(IS.End);
- if (Start == End)
- break;
- }
-
- if (!Found)
- break;
- }
-
- return std::make_unique<NativeEnumSymbols>(Session, std::move(Frames));
-}
+
+static bool inlineSiteContainsAddress(InlineSiteSym &IS,
+ uint32_t OffsetInFunc) {
+ // Returns true if inline site contains the offset.
+ bool Found = false;
+ uint32_t CodeOffset = 0;
+ for (auto &Annot : IS.annotations()) {
+ switch (Annot.OpCode) {
+ case BinaryAnnotationsOpCode::CodeOffset:
+ case BinaryAnnotationsOpCode::ChangeCodeOffset:
+ case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
+ CodeOffset += Annot.U1;
+ if (OffsetInFunc >= CodeOffset)
+ Found = true;
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeLength:
+ CodeOffset += Annot.U1;
+ if (Found && OffsetInFunc < CodeOffset)
+ return true;
+ Found = false;
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
+ CodeOffset += Annot.U2;
+ if (OffsetInFunc >= CodeOffset && OffsetInFunc < CodeOffset + Annot.U1)
+ return true;
+ Found = false;
+ break;
+ default:
+ break;
+ }
+ }
+ return false;
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeFunctionSymbol::findInlineFramesByVA(uint64_t VA) const {
+ uint16_t Modi;
+ if (!Session.moduleIndexForVA(VA, Modi))
+ return nullptr;
+
+ Expected<ModuleDebugStreamRef> ModS = Session.getModuleDebugStream(Modi);
+ if (!ModS) {
+ consumeError(ModS.takeError());
+ return nullptr;
+ }
+ CVSymbolArray Syms = ModS->getSymbolArray();
+
+ // Search for inline sites. There should be one matching top level inline
+ // site. Then search in its nested inline sites.
+ std::vector<SymIndexId> Frames;
+ uint32_t CodeOffset = VA - getVirtualAddress();
+ auto Start = Syms.at(RecordOffset);
+ auto End = Syms.at(Sym.End);
+ while (Start != End) {
+ bool Found = false;
+ // Find matching inline site within Start and End.
+ for (; Start != End; ++Start) {
+ if (Start->kind() != S_INLINESITE)
+ continue;
+
+ InlineSiteSym IS =
+ cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(*Start));
+ if (inlineSiteContainsAddress(IS, CodeOffset)) {
+ // Insert frames in reverse order.
+ SymIndexId Id = Session.getSymbolCache().getOrCreateInlineSymbol(
+ IS, getVirtualAddress(), Modi, Start.offset());
+ Frames.insert(Frames.begin(), Id);
+
+ // Update offsets to search within this inline site.
+ ++Start;
+ End = Syms.at(IS.End);
+ Found = true;
+ break;
+ }
+
+ Start = Syms.at(IS.End);
+ if (Start == End)
+ break;
+ }
+
+ if (!Found)
+ break;
+ }
+
+ return std::make_unique<NativeEnumSymbols>(Session, std::move(Frames));
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeInlineSiteSymbol.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeInlineSiteSymbol.cpp
index 9708976f28..8314353c38 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeInlineSiteSymbol.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeInlineSiteSymbol.cpp
@@ -1,177 +1,177 @@
-//===- NativeInlineSiteSymbol.cpp - info about inline sites -----*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeInlineSiteSymbol.h"
-
-#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
-#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
-#include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h"
-#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::pdb;
-
-NativeInlineSiteSymbol::NativeInlineSiteSymbol(
- NativeSession &Session, SymIndexId Id, const codeview::InlineSiteSym &Sym,
- uint64_t ParentAddr)
- : NativeRawSymbol(Session, PDB_SymType::InlineSite, Id), Sym(Sym),
- ParentAddr(ParentAddr) {}
-
-NativeInlineSiteSymbol::~NativeInlineSiteSymbol() {}
-
-void NativeInlineSiteSymbol::dump(raw_ostream &OS, int Indent,
- PdbSymbolIdField ShowIdFields,
- PdbSymbolIdField RecurseIdFields) const {
- NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
- dumpSymbolField(OS, "name", getName(), Indent);
-}
-
-static Optional<InlineeSourceLine>
-findInlineeByTypeIndex(TypeIndex Id, ModuleDebugStreamRef &ModS) {
- for (const auto &SS : ModS.getSubsectionsArray()) {
- if (SS.kind() != DebugSubsectionKind::InlineeLines)
- continue;
-
- DebugInlineeLinesSubsectionRef InlineeLines;
- BinaryStreamReader Reader(SS.getRecordData());
- if (auto EC = InlineeLines.initialize(Reader)) {
- consumeError(std::move(EC));
- continue;
- }
-
- for (const InlineeSourceLine &Line : InlineeLines)
- if (Line.Header->Inlinee == Id)
- return Line;
- }
- return None;
-}
-
-std::string NativeInlineSiteSymbol::getName() const {
- auto Tpi = Session.getPDBFile().getPDBTpiStream();
- if (!Tpi) {
- consumeError(Tpi.takeError());
- return "";
- }
- auto Ipi = Session.getPDBFile().getPDBIpiStream();
- if (!Ipi) {
- consumeError(Ipi.takeError());
- return "";
- }
-
- LazyRandomTypeCollection &Types = Tpi->typeCollection();
- LazyRandomTypeCollection &Ids = Ipi->typeCollection();
- CVType InlineeType = Ids.getType(Sym.Inlinee);
- std::string QualifiedName;
- if (InlineeType.kind() == LF_MFUNC_ID) {
- MemberFuncIdRecord MFRecord;
- cantFail(TypeDeserializer::deserializeAs<MemberFuncIdRecord>(InlineeType,
- MFRecord));
- TypeIndex ClassTy = MFRecord.getClassType();
- QualifiedName.append(std::string(Types.getTypeName(ClassTy)));
- QualifiedName.append("::");
- } else if (InlineeType.kind() == LF_FUNC_ID) {
- FuncIdRecord FRecord;
- cantFail(
- TypeDeserializer::deserializeAs<FuncIdRecord>(InlineeType, FRecord));
- TypeIndex ParentScope = FRecord.getParentScope();
- if (!ParentScope.isNoneType()) {
- QualifiedName.append(std::string(Ids.getTypeName(ParentScope)));
- QualifiedName.append("::");
- }
- }
-
- QualifiedName.append(std::string(Ids.getTypeName(Sym.Inlinee)));
- return QualifiedName;
-}
-
-void NativeInlineSiteSymbol::getLineOffset(uint32_t OffsetInFunc,
- uint32_t &LineOffset,
- uint32_t &FileOffset) const {
- LineOffset = 0;
- FileOffset = 0;
- uint32_t CodeOffset = 0;
- for (const auto &Annot : Sym.annotations()) {
- switch (Annot.OpCode) {
- case BinaryAnnotationsOpCode::CodeOffset:
- case BinaryAnnotationsOpCode::ChangeCodeOffset:
- case BinaryAnnotationsOpCode::ChangeCodeLength:
- CodeOffset += Annot.U1;
- break;
- case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
- CodeOffset += Annot.U2;
- break;
- case BinaryAnnotationsOpCode::ChangeLineOffset:
- case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
- CodeOffset += Annot.U1;
- LineOffset += Annot.S1;
- break;
- case BinaryAnnotationsOpCode::ChangeFile:
- FileOffset = Annot.U1;
- break;
- default:
- break;
- }
-
- if (CodeOffset >= OffsetInFunc)
- return;
- }
-}
-
-std::unique_ptr<IPDBEnumLineNumbers>
-NativeInlineSiteSymbol::findInlineeLinesByVA(uint64_t VA,
- uint32_t Length) const {
- uint16_t Modi;
- if (!Session.moduleIndexForVA(VA, Modi))
- return nullptr;
-
- Expected<ModuleDebugStreamRef> ModS = Session.getModuleDebugStream(Modi);
- if (!ModS) {
- consumeError(ModS.takeError());
- return nullptr;
- }
-
- Expected<DebugChecksumsSubsectionRef> Checksums =
- ModS->findChecksumsSubsection();
- if (!Checksums) {
- consumeError(Checksums.takeError());
- return nullptr;
- }
-
- // Get the line number offset and source file offset.
- uint32_t SrcLineOffset;
- uint32_t SrcFileOffset;
- getLineOffset(VA - ParentAddr, SrcLineOffset, SrcFileOffset);
-
- // Get line info from inlinee line table.
- Optional<InlineeSourceLine> Inlinee =
- findInlineeByTypeIndex(Sym.Inlinee, ModS.get());
-
- if (!Inlinee)
- return nullptr;
-
- uint32_t SrcLine = Inlinee->Header->SourceLineNum + SrcLineOffset;
- uint32_t SrcCol = 0; // Inline sites don't seem to have column info.
- uint32_t FileChecksumOffset =
- (SrcFileOffset == 0) ? Inlinee->Header->FileID : SrcFileOffset;
-
- auto ChecksumIter = Checksums->getArray().at(FileChecksumOffset);
- uint32_t SrcFileId =
- Session.getSymbolCache().getOrCreateSourceFile(*ChecksumIter);
-
- uint32_t LineSect, LineOff;
- Session.addressForVA(VA, LineSect, LineOff);
- NativeLineNumber LineNum(Session, SrcLine, SrcCol, LineSect, LineOff, Length,
- SrcFileId, Modi);
- auto SrcFile = Session.getSymbolCache().getSourceFileById(SrcFileId);
- std::vector<NativeLineNumber> Lines{LineNum};
-
- return std::make_unique<NativeEnumLineNumbers>(std::move(Lines));
-}
+//===- NativeInlineSiteSymbol.cpp - info about inline sites -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeInlineSiteSymbol.h"
+
+#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeInlineSiteSymbol::NativeInlineSiteSymbol(
+ NativeSession &Session, SymIndexId Id, const codeview::InlineSiteSym &Sym,
+ uint64_t ParentAddr)
+ : NativeRawSymbol(Session, PDB_SymType::InlineSite, Id), Sym(Sym),
+ ParentAddr(ParentAddr) {}
+
+NativeInlineSiteSymbol::~NativeInlineSiteSymbol() {}
+
+void NativeInlineSiteSymbol::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+ dumpSymbolField(OS, "name", getName(), Indent);
+}
+
+static Optional<InlineeSourceLine>
+findInlineeByTypeIndex(TypeIndex Id, ModuleDebugStreamRef &ModS) {
+ for (const auto &SS : ModS.getSubsectionsArray()) {
+ if (SS.kind() != DebugSubsectionKind::InlineeLines)
+ continue;
+
+ DebugInlineeLinesSubsectionRef InlineeLines;
+ BinaryStreamReader Reader(SS.getRecordData());
+ if (auto EC = InlineeLines.initialize(Reader)) {
+ consumeError(std::move(EC));
+ continue;
+ }
+
+ for (const InlineeSourceLine &Line : InlineeLines)
+ if (Line.Header->Inlinee == Id)
+ return Line;
+ }
+ return None;
+}
+
+std::string NativeInlineSiteSymbol::getName() const {
+ auto Tpi = Session.getPDBFile().getPDBTpiStream();
+ if (!Tpi) {
+ consumeError(Tpi.takeError());
+ return "";
+ }
+ auto Ipi = Session.getPDBFile().getPDBIpiStream();
+ if (!Ipi) {
+ consumeError(Ipi.takeError());
+ return "";
+ }
+
+ LazyRandomTypeCollection &Types = Tpi->typeCollection();
+ LazyRandomTypeCollection &Ids = Ipi->typeCollection();
+ CVType InlineeType = Ids.getType(Sym.Inlinee);
+ std::string QualifiedName;
+ if (InlineeType.kind() == LF_MFUNC_ID) {
+ MemberFuncIdRecord MFRecord;
+ cantFail(TypeDeserializer::deserializeAs<MemberFuncIdRecord>(InlineeType,
+ MFRecord));
+ TypeIndex ClassTy = MFRecord.getClassType();
+ QualifiedName.append(std::string(Types.getTypeName(ClassTy)));
+ QualifiedName.append("::");
+ } else if (InlineeType.kind() == LF_FUNC_ID) {
+ FuncIdRecord FRecord;
+ cantFail(
+ TypeDeserializer::deserializeAs<FuncIdRecord>(InlineeType, FRecord));
+ TypeIndex ParentScope = FRecord.getParentScope();
+ if (!ParentScope.isNoneType()) {
+ QualifiedName.append(std::string(Ids.getTypeName(ParentScope)));
+ QualifiedName.append("::");
+ }
+ }
+
+ QualifiedName.append(std::string(Ids.getTypeName(Sym.Inlinee)));
+ return QualifiedName;
+}
+
+void NativeInlineSiteSymbol::getLineOffset(uint32_t OffsetInFunc,
+ uint32_t &LineOffset,
+ uint32_t &FileOffset) const {
+ LineOffset = 0;
+ FileOffset = 0;
+ uint32_t CodeOffset = 0;
+ for (const auto &Annot : Sym.annotations()) {
+ switch (Annot.OpCode) {
+ case BinaryAnnotationsOpCode::CodeOffset:
+ case BinaryAnnotationsOpCode::ChangeCodeOffset:
+ case BinaryAnnotationsOpCode::ChangeCodeLength:
+ CodeOffset += Annot.U1;
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
+ CodeOffset += Annot.U2;
+ break;
+ case BinaryAnnotationsOpCode::ChangeLineOffset:
+ case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
+ CodeOffset += Annot.U1;
+ LineOffset += Annot.S1;
+ break;
+ case BinaryAnnotationsOpCode::ChangeFile:
+ FileOffset = Annot.U1;
+ break;
+ default:
+ break;
+ }
+
+ if (CodeOffset >= OffsetInFunc)
+ return;
+ }
+}
+
+std::unique_ptr<IPDBEnumLineNumbers>
+NativeInlineSiteSymbol::findInlineeLinesByVA(uint64_t VA,
+ uint32_t Length) const {
+ uint16_t Modi;
+ if (!Session.moduleIndexForVA(VA, Modi))
+ return nullptr;
+
+ Expected<ModuleDebugStreamRef> ModS = Session.getModuleDebugStream(Modi);
+ if (!ModS) {
+ consumeError(ModS.takeError());
+ return nullptr;
+ }
+
+ Expected<DebugChecksumsSubsectionRef> Checksums =
+ ModS->findChecksumsSubsection();
+ if (!Checksums) {
+ consumeError(Checksums.takeError());
+ return nullptr;
+ }
+
+ // Get the line number offset and source file offset.
+ uint32_t SrcLineOffset;
+ uint32_t SrcFileOffset;
+ getLineOffset(VA - ParentAddr, SrcLineOffset, SrcFileOffset);
+
+ // Get line info from inlinee line table.
+ Optional<InlineeSourceLine> Inlinee =
+ findInlineeByTypeIndex(Sym.Inlinee, ModS.get());
+
+ if (!Inlinee)
+ return nullptr;
+
+ uint32_t SrcLine = Inlinee->Header->SourceLineNum + SrcLineOffset;
+ uint32_t SrcCol = 0; // Inline sites don't seem to have column info.
+ uint32_t FileChecksumOffset =
+ (SrcFileOffset == 0) ? Inlinee->Header->FileID : SrcFileOffset;
+
+ auto ChecksumIter = Checksums->getArray().at(FileChecksumOffset);
+ uint32_t SrcFileId =
+ Session.getSymbolCache().getOrCreateSourceFile(*ChecksumIter);
+
+ uint32_t LineSect, LineOff;
+ Session.addressForVA(VA, LineSect, LineOff);
+ NativeLineNumber LineNum(Session, SrcLine, SrcCol, LineSect, LineOff, Length,
+ SrcFileId, Modi);
+ auto SrcFile = Session.getSymbolCache().getSourceFileById(SrcFileId);
+ std::vector<NativeLineNumber> Lines{LineNum};
+
+ return std::make_unique<NativeEnumLineNumbers>(std::move(Lines));
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp
index aefacfd23f..155ed0cdb8 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp
@@ -15,10 +15,10 @@ NativeLineNumber::NativeLineNumber(const NativeSession &Session,
const codeview::LineInfo Line,
uint32_t ColumnNumber, uint32_t Section,
uint32_t Offset, uint32_t Length,
- uint32_t SrcFileId, uint32_t CompilandId)
+ uint32_t SrcFileId, uint32_t CompilandId)
: Session(Session), Line(Line), ColumnNumber(ColumnNumber),
- Section(Section), Offset(Offset), Length(Length), SrcFileId(SrcFileId),
- CompilandId(CompilandId) {}
+ Section(Section), Offset(Offset), Length(Length), SrcFileId(SrcFileId),
+ CompilandId(CompilandId) {}
uint32_t NativeLineNumber::getLineNumber() const { return Line.getStartLine(); }
@@ -46,6 +46,6 @@ uint32_t NativeLineNumber::getLength() const { return Length; }
uint32_t NativeLineNumber::getSourceFileId() const { return SrcFileId; }
-uint32_t NativeLineNumber::getCompilandId() const { return CompilandId; }
+uint32_t NativeLineNumber::getCompilandId() const { return CompilandId; }
bool NativeLineNumber::isStatement() const { return Line.isStatement(); }
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp
index 501b3003ba..1265e688b8 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp
@@ -18,7 +18,7 @@ using namespace llvm::pdb;
NativePublicSymbol::NativePublicSymbol(NativeSession &Session, SymIndexId Id,
const codeview::PublicSym32 &Sym)
- : NativeRawSymbol(Session, PDB_SymType::PublicSymbol, Id), Sym(Sym) {}
+ : NativeRawSymbol(Session, PDB_SymType::PublicSymbol, Id), Sym(Sym) {}
NativePublicSymbol::~NativePublicSymbol() {}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSession.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSession.cpp
index 6a7e7ee4d8..5d7946cdc2 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSession.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSession.cpp
@@ -13,7 +13,7 @@
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
-#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
+#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumInjectedSources.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
@@ -57,7 +57,7 @@ static DbiStream *getDbiStreamPtr(PDBFile &File) {
NativeSession::NativeSession(std::unique_ptr<PDBFile> PdbFile,
std::unique_ptr<BumpPtrAllocator> Allocator)
: Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)),
- Cache(*this, getDbiStreamPtr(*Pdb)), AddrToModuleIndex(IMapAllocator) {}
+ Cache(*this, getDbiStreamPtr(*Pdb)), AddrToModuleIndex(IMapAllocator) {}
NativeSession::~NativeSession() = default;
@@ -256,9 +256,9 @@ std::unique_ptr<PDBSymbol> NativeSession::findSymbolByRVA(uint32_t RVA,
std::unique_ptr<PDBSymbol>
NativeSession::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
PDB_SymType Type) {
- if (AddrToModuleIndex.empty())
- parseSectionContribs();
-
+ if (AddrToModuleIndex.empty())
+ parseSectionContribs();
+
return Cache.findSymbolBySectOffset(Sect, Offset, Type);
}
@@ -276,14 +276,14 @@ NativeSession::findLineNumbersByAddress(uint64_t Address,
std::unique_ptr<IPDBEnumLineNumbers>
NativeSession::findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const {
- return Cache.findLineNumbersByVA(getLoadAddress() + RVA, Length);
+ return Cache.findLineNumbersByVA(getLoadAddress() + RVA, Length);
}
std::unique_ptr<IPDBEnumLineNumbers>
NativeSession::findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset,
uint32_t Length) const {
uint64_t VA = getVAFromSectOffset(Section, Offset);
- return Cache.findLineNumbersByVA(VA, Length);
+ return Cache.findLineNumbersByVA(VA, Length);
}
std::unique_ptr<IPDBEnumSourceFiles>
@@ -390,74 +390,74 @@ uint64_t NativeSession::getVAFromSectOffset(uint32_t Section,
uint32_t Offset) const {
return LoadAddress + getRVAFromSectOffset(Section, Offset);
}
-
-bool NativeSession::moduleIndexForVA(uint64_t VA, uint16_t &ModuleIndex) const {
- ModuleIndex = 0;
- auto Iter = AddrToModuleIndex.find(VA);
- if (Iter == AddrToModuleIndex.end())
- return false;
- ModuleIndex = Iter.value();
- return true;
-}
-
-bool NativeSession::moduleIndexForSectOffset(uint32_t Sect, uint32_t Offset,
- uint16_t &ModuleIndex) const {
- ModuleIndex = 0;
- auto Iter = AddrToModuleIndex.find(getVAFromSectOffset(Sect, Offset));
- if (Iter == AddrToModuleIndex.end())
- return false;
- ModuleIndex = Iter.value();
- return true;
-}
-
-void NativeSession::parseSectionContribs() {
- auto Dbi = Pdb->getPDBDbiStream();
- if (!Dbi)
- return;
-
- class Visitor : public ISectionContribVisitor {
- NativeSession &Session;
- IMap &AddrMap;
-
- public:
- Visitor(NativeSession &Session, IMap &AddrMap)
- : Session(Session), AddrMap(AddrMap) {}
- void visit(const SectionContrib &C) override {
- if (C.Size == 0)
- return;
-
- uint64_t VA = Session.getVAFromSectOffset(C.ISect, C.Off);
- uint64_t End = VA + C.Size;
-
- // Ignore overlapping sections based on the assumption that a valid
- // PDB file should not have overlaps.
- if (!AddrMap.overlaps(VA, End))
- AddrMap.insert(VA, End, C.Imod);
- }
- void visit(const SectionContrib2 &C) override { visit(C.Base); }
- };
-
- Visitor V(*this, AddrToModuleIndex);
- Dbi->visitSectionContributions(V);
-}
-
-Expected<ModuleDebugStreamRef>
-NativeSession::getModuleDebugStream(uint32_t Index) const {
- auto *Dbi = getDbiStreamPtr(*Pdb);
- assert(Dbi && "Dbi stream not present");
-
- DbiModuleDescriptor Modi = Dbi->modules().getModuleDescriptor(Index);
-
- uint16_t ModiStream = Modi.getModuleStreamIndex();
- if (ModiStream == kInvalidStreamIndex)
- return make_error<RawError>("Module stream not present");
-
- std::unique_ptr<msf::MappedBlockStream> ModStreamData =
- Pdb->createIndexedStream(ModiStream);
-
- ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData));
- if (auto EC = ModS.reload())
- return std::move(EC);
-
- return std::move(ModS);
-}
+
+bool NativeSession::moduleIndexForVA(uint64_t VA, uint16_t &ModuleIndex) const {
+ ModuleIndex = 0;
+ auto Iter = AddrToModuleIndex.find(VA);
+ if (Iter == AddrToModuleIndex.end())
+ return false;
+ ModuleIndex = Iter.value();
+ return true;
+}
+
+bool NativeSession::moduleIndexForSectOffset(uint32_t Sect, uint32_t Offset,
+ uint16_t &ModuleIndex) const {
+ ModuleIndex = 0;
+ auto Iter = AddrToModuleIndex.find(getVAFromSectOffset(Sect, Offset));
+ if (Iter == AddrToModuleIndex.end())
+ return false;
+ ModuleIndex = Iter.value();
+ return true;
+}
+
+void NativeSession::parseSectionContribs() {
+ auto Dbi = Pdb->getPDBDbiStream();
+ if (!Dbi)
+ return;
+
+ class Visitor : public ISectionContribVisitor {
+ NativeSession &Session;
+ IMap &AddrMap;
+
+ public:
+ Visitor(NativeSession &Session, IMap &AddrMap)
+ : Session(Session), AddrMap(AddrMap) {}
+ void visit(const SectionContrib &C) override {
+ if (C.Size == 0)
+ return;
+
+ uint64_t VA = Session.getVAFromSectOffset(C.ISect, C.Off);
+ uint64_t End = VA + C.Size;
+
+ // Ignore overlapping sections based on the assumption that a valid
+ // PDB file should not have overlaps.
+ if (!AddrMap.overlaps(VA, End))
+ AddrMap.insert(VA, End, C.Imod);
+ }
+ void visit(const SectionContrib2 &C) override { visit(C.Base); }
+ };
+
+ Visitor V(*this, AddrToModuleIndex);
+ Dbi->visitSectionContributions(V);
+}
+
+Expected<ModuleDebugStreamRef>
+NativeSession::getModuleDebugStream(uint32_t Index) const {
+ auto *Dbi = getDbiStreamPtr(*Pdb);
+ assert(Dbi && "Dbi stream not present");
+
+ DbiModuleDescriptor Modi = Dbi->modules().getModuleDescriptor(Index);
+
+ uint16_t ModiStream = Modi.getModuleStreamIndex();
+ if (ModiStream == kInvalidStreamIndex)
+ return make_error<RawError>("Module stream not present");
+
+ std::unique_ptr<msf::MappedBlockStream> ModStreamData =
+ Pdb->createIndexedStream(ModiStream);
+
+ ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData));
+ if (auto EC = ModS.reload())
+ return std::move(EC);
+
+ return std::move(ModS);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp
index e494635182..fd813dee6b 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp
@@ -1,4 +1,4 @@
-//===- NativeSourceFile.cpp - Native line number implementation -*- C++ -*-===//
+//===- NativeSourceFile.cpp - Native line number implementation -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp
index 401efc0511..917ec14e58 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp
@@ -120,7 +120,7 @@ PDB_UdtType NativeTypeUDT::getUdtKind() const {
case TypeRecordKind::Interface:
return PDB_UdtType::Interface;
default:
- llvm_unreachable("Unexpected udt kind");
+ llvm_unreachable("Unexpected udt kind");
}
}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolCache.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolCache.cpp
index 5bf434f845..fd9a0deb54 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolCache.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolCache.cpp
@@ -1,6 +1,6 @@
#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
-#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
@@ -11,10 +11,10 @@
#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h"
-#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
#include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h"
-#include "llvm/DebugInfo/PDB/Native/NativeInlineSiteSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeInlineSiteSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativePublicSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
@@ -71,7 +71,7 @@ static const struct BuiltinTypeEntry {
};
SymbolCache::SymbolCache(NativeSession &Session, DbiStream *Dbi)
- : Session(Session), Dbi(Dbi) {
+ : Session(Session), Dbi(Dbi) {
// Id 0 is reserved for the invalid symbol.
Cache.push_back(nullptr);
SourceFiles.push_back(nullptr);
@@ -104,15 +104,15 @@ SymbolCache::createGlobalsEnumerator(codeview::SymbolKind Kind) {
}
SymIndexId SymbolCache::createSimpleType(TypeIndex Index,
- ModifierOptions Mods) const {
+ ModifierOptions Mods) const {
if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct)
return createSymbol<NativeTypePointer>(Index);
const auto Kind = Index.getSimpleKind();
- const auto It =
- llvm::find_if(BuiltinTypes, [Kind](const BuiltinTypeEntry &Builtin) {
- return Builtin.Kind == Kind;
- });
+ const auto It =
+ llvm::find_if(BuiltinTypes, [Kind](const BuiltinTypeEntry &Builtin) {
+ return Builtin.Kind == Kind;
+ });
if (It == std::end(BuiltinTypes))
return 0;
return createSymbol<NativeTypeBuiltin>(Mods, It->Type, It->Size);
@@ -120,7 +120,7 @@ SymIndexId SymbolCache::createSimpleType(TypeIndex Index,
SymIndexId
SymbolCache::createSymbolForModifiedType(codeview::TypeIndex ModifierTI,
- codeview::CVType CVT) const {
+ codeview::CVType CVT) const {
ModifierRecord Record;
if (auto EC = TypeDeserializer::deserializeAs<ModifierRecord>(CVT, Record)) {
consumeError(std::move(EC));
@@ -150,7 +150,7 @@ SymbolCache::createSymbolForModifiedType(codeview::TypeIndex ModifierTI,
return 0;
}
-SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) const {
+SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) const {
// First see if it's already in our cache.
const auto Entry = TypeIndexToSymbolId.find(Index);
if (Entry != TypeIndexToSymbolId.end())
@@ -247,7 +247,7 @@ SymbolCache::getSymbolById(SymIndexId SymbolId) const {
return nullptr;
// Make sure to handle the case where we've inserted a placeholder symbol
- // for types we don't yet support.
+ // for types we don't yet support.
NativeRawSymbol *NRS = Cache[SymbolId].get();
if (!NRS)
return nullptr;
@@ -292,17 +292,17 @@ SymIndexId SymbolCache::getOrCreateGlobalSymbolByOffset(uint32_t Offset) {
return Id;
}
-SymIndexId SymbolCache::getOrCreateInlineSymbol(InlineSiteSym Sym,
- uint64_t ParentAddr,
- uint16_t Modi,
- uint32_t RecordOffset) const {
- auto Iter = SymTabOffsetToSymbolId.find({Modi, RecordOffset});
- if (Iter != SymTabOffsetToSymbolId.end())
- return Iter->second;
-
- SymIndexId Id = createSymbol<NativeInlineSiteSymbol>(Sym, ParentAddr);
- SymTabOffsetToSymbolId.insert({{Modi, RecordOffset}, Id});
- return Id;
+SymIndexId SymbolCache::getOrCreateInlineSymbol(InlineSiteSym Sym,
+ uint64_t ParentAddr,
+ uint16_t Modi,
+ uint32_t RecordOffset) const {
+ auto Iter = SymTabOffsetToSymbolId.find({Modi, RecordOffset});
+ if (Iter != SymTabOffsetToSymbolId.end())
+ return Iter->second;
+
+ SymIndexId Id = createSymbol<NativeInlineSiteSymbol>(Sym, ParentAddr);
+ SymTabOffsetToSymbolId.insert({{Modi, RecordOffset}, Id});
+ return Id;
}
std::unique_ptr<PDBSymbol>
@@ -313,15 +313,15 @@ SymbolCache::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
return findFunctionSymbolBySectOffset(Sect, Offset);
case PDB_SymType::PublicSymbol:
return findPublicSymbolBySectOffset(Sect, Offset);
- case PDB_SymType::Compiland: {
- uint16_t Modi;
- if (!Session.moduleIndexForSectOffset(Sect, Offset, Modi))
- return nullptr;
- return getOrCreateCompiland(Modi);
- }
+ case PDB_SymType::Compiland: {
+ uint16_t Modi;
+ if (!Session.moduleIndexForSectOffset(Sect, Offset, Modi))
+ return nullptr;
+ return getOrCreateCompiland(Modi);
+ }
case PDB_SymType::None: {
- // FIXME: Implement for PDB_SymType::Data. The symbolizer calls this but
- // only uses it to find the symbol length.
+ // FIXME: Implement for PDB_SymType::Data. The symbolizer calls this but
+ // only uses it to find the symbol length.
if (auto Sym = findFunctionSymbolBySectOffset(Sect, Offset))
return Sym;
return nullptr;
@@ -333,19 +333,19 @@ SymbolCache::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
std::unique_ptr<PDBSymbol>
SymbolCache::findFunctionSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
- auto Iter = AddressToSymbolId.find({Sect, Offset});
- if (Iter != AddressToSymbolId.end())
+ auto Iter = AddressToSymbolId.find({Sect, Offset});
+ if (Iter != AddressToSymbolId.end())
return getSymbolById(Iter->second);
if (!Dbi)
return nullptr;
- uint16_t Modi;
- if (!Session.moduleIndexForSectOffset(Sect, Offset, Modi))
+ uint16_t Modi;
+ if (!Session.moduleIndexForSectOffset(Sect, Offset, Modi))
return nullptr;
- Expected<ModuleDebugStreamRef> ExpectedModS =
- Session.getModuleDebugStream(Modi);
+ Expected<ModuleDebugStreamRef> ExpectedModS =
+ Session.getModuleDebugStream(Modi);
if (!ExpectedModS) {
consumeError(ExpectedModS.takeError());
return nullptr;
@@ -359,14 +359,14 @@ SymbolCache::findFunctionSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
auto PS = cantFail(SymbolDeserializer::deserializeAs<ProcSym>(*I));
if (Sect == PS.Segment && Offset >= PS.CodeOffset &&
Offset < PS.CodeOffset + PS.CodeSize) {
- // Check if the symbol is already cached.
- auto Found = AddressToSymbolId.find({PS.Segment, PS.CodeOffset});
- if (Found != AddressToSymbolId.end())
- return getSymbolById(Found->second);
-
- // Otherwise, create a new symbol.
- SymIndexId Id = createSymbol<NativeFunctionSymbol>(PS, I.offset());
- AddressToSymbolId.insert({{PS.Segment, PS.CodeOffset}, Id});
+ // Check if the symbol is already cached.
+ auto Found = AddressToSymbolId.find({PS.Segment, PS.CodeOffset});
+ if (Found != AddressToSymbolId.end())
+ return getSymbolById(Found->second);
+
+ // Otherwise, create a new symbol.
+ SymIndexId Id = createSymbol<NativeFunctionSymbol>(PS, I.offset());
+ AddressToSymbolId.insert({{PS.Segment, PS.CodeOffset}, Id});
return getSymbolById(Id);
}
@@ -426,16 +426,16 @@ SymbolCache::findPublicSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
consumeError(Sym.takeError());
return nullptr;
}
-
- // Check if the symbol is already cached.
+
+ // Check if the symbol is already cached.
auto PS = cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get()));
- auto Found = AddressToPublicSymId.find({PS.Segment, PS.Offset});
- if (Found != AddressToPublicSymId.end())
- return getSymbolById(Found->second);
-
- // Otherwise, create a new symbol.
+ auto Found = AddressToPublicSymId.find({PS.Segment, PS.Offset});
+ if (Found != AddressToPublicSymId.end())
+ return getSymbolById(Found->second);
+
+ // Otherwise, create a new symbol.
SymIndexId Id = createSymbol<NativePublicSymbol>(PS);
- AddressToPublicSymId.insert({{PS.Segment, PS.Offset}, Id});
+ AddressToPublicSymId.insert({{PS.Segment, PS.Offset}, Id});
return getSymbolById(Id);
}
@@ -450,8 +450,8 @@ SymbolCache::findLineTable(uint16_t Modi) const {
// If there is an error or there are no lines, just return the
// empty vector.
- Expected<ModuleDebugStreamRef> ExpectedModS =
- Session.getModuleDebugStream(Modi);
+ Expected<ModuleDebugStreamRef> ExpectedModS =
+ Session.getModuleDebugStream(Modi);
if (!ExpectedModS) {
consumeError(ExpectedModS.takeError());
return ModuleLineTable;
@@ -482,19 +482,19 @@ SymbolCache::findLineTable(uint16_t Modi) const {
auto ColIt = Group.Columns.begin();
auto ColsEnd = Group.Columns.end();
- // Add a line to mark the beginning of this section.
- uint64_t StartAddr =
- Session.getVAFromSectOffset(RelocSegment, RelocOffset);
- LineInfo FirstLine(Group.LineNumbers.front().Flags);
- uint32_t ColNum =
- (Lines.hasColumnInfo()) ? Group.Columns.front().StartColumn : 0;
- Entries.push_back({StartAddr, FirstLine, ColNum, Group.NameIndex, false});
-
+ // Add a line to mark the beginning of this section.
+ uint64_t StartAddr =
+ Session.getVAFromSectOffset(RelocSegment, RelocOffset);
+ LineInfo FirstLine(Group.LineNumbers.front().Flags);
+ uint32_t ColNum =
+ (Lines.hasColumnInfo()) ? Group.Columns.front().StartColumn : 0;
+ Entries.push_back({StartAddr, FirstLine, ColNum, Group.NameIndex, false});
+
for (const LineNumberEntry &LN : Group.LineNumbers) {
uint64_t VA =
Session.getVAFromSectOffset(RelocSegment, RelocOffset + LN.Offset);
LineInfo Line(LN.Flags);
- ColNum = 0;
+ ColNum = 0;
if (Lines.hasColumnInfo() && ColIt != ColsEnd) {
ColNum = ColIt->StartColumn;
@@ -504,30 +504,30 @@ SymbolCache::findLineTable(uint16_t Modi) const {
}
// Add a terminal entry line to mark the end of this subsection.
- uint64_t EndAddr = StartAddr + Lines.header()->CodeSize;
+ uint64_t EndAddr = StartAddr + Lines.header()->CodeSize;
LineInfo LastLine(Group.LineNumbers.back().Flags);
- ColNum = (Lines.hasColumnInfo()) ? Group.Columns.back().StartColumn : 0;
- Entries.push_back({EndAddr, LastLine, ColNum, Group.NameIndex, true});
+ ColNum = (Lines.hasColumnInfo()) ? Group.Columns.back().StartColumn : 0;
+ Entries.push_back({EndAddr, LastLine, ColNum, Group.NameIndex, true});
EntryList.push_back(Entries);
}
}
// Sort EntryList, and add flattened contents to the line table.
- llvm::sort(EntryList, [](const std::vector<LineTableEntry> &LHS,
- const std::vector<LineTableEntry> &RHS) {
- return LHS[0].Addr < RHS[0].Addr;
- });
+ llvm::sort(EntryList, [](const std::vector<LineTableEntry> &LHS,
+ const std::vector<LineTableEntry> &RHS) {
+ return LHS[0].Addr < RHS[0].Addr;
+ });
for (size_t I = 0; I < EntryList.size(); ++I)
- llvm::append_range(ModuleLineTable, EntryList[I]);
+ llvm::append_range(ModuleLineTable, EntryList[I]);
return ModuleLineTable;
}
std::unique_ptr<IPDBEnumLineNumbers>
SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const {
- uint16_t Modi;
- if (!Session.moduleIndexForVA(VA, Modi))
+ uint16_t Modi;
+ if (!Session.moduleIndexForVA(VA, Modi))
return nullptr;
std::vector<LineTableEntry> Lines = findLineTable(Modi);
@@ -547,8 +547,8 @@ SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const {
--LineIter;
}
- Expected<ModuleDebugStreamRef> ExpectedModS =
- Session.getModuleDebugStream(Modi);
+ Expected<ModuleDebugStreamRef> ExpectedModS =
+ Session.getModuleDebugStream(Modi);
if (!ExpectedModS) {
consumeError(ExpectedModS.takeError());
return nullptr;
@@ -563,7 +563,7 @@ SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const {
// Populate a vector of NativeLineNumbers that have addresses in the given
// address range.
std::vector<NativeLineNumber> LineNumbers;
- while (LineIter != Lines.end()) {
+ while (LineIter != Lines.end()) {
if (LineIter->IsTerminalEntry) {
++LineIter;
continue;
@@ -581,7 +581,7 @@ SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const {
ExpectedChecksums->getArray().at(LineIter->FileNameIndex);
uint32_t SrcFileId = getOrCreateSourceFile(*ChecksumIter);
NativeLineNumber LineNum(Session, LineIter->Line, LineIter->ColumnNumber,
- LineSect, LineOff, LineLength, SrcFileId, Modi);
+ LineSect, LineOff, LineLength, SrcFileId, Modi);
LineNumbers.push_back(LineNum);
++LineIter;
}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
index da44463f39..5f4f497690 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
@@ -25,7 +25,7 @@
#include "llvm/Support/Error.h"
#include <algorithm>
#include <cstdint>
-#include <numeric>
+#include <numeric>
using namespace llvm;
using namespace llvm::msf;
@@ -42,58 +42,58 @@ void TpiStreamBuilder::setVersionHeader(PdbRaw_TpiVer Version) {
VerHeader = Version;
}
-void TpiStreamBuilder::updateTypeIndexOffsets(ArrayRef<uint16_t> Sizes) {
- // If we just crossed an 8KB threshold, add a type index offset.
- for (uint16_t Size : Sizes) {
- size_t NewSize = TypeRecordBytes + Size;
- constexpr size_t EightKB = 8 * 1024;
- if (NewSize / EightKB > TypeRecordBytes / EightKB || TypeRecordCount == 0) {
- TypeIndexOffsets.push_back(
- {codeview::TypeIndex(codeview::TypeIndex::FirstNonSimpleIndex +
- TypeRecordCount),
- ulittle32_t(TypeRecordBytes)});
- }
- ++TypeRecordCount;
- TypeRecordBytes = NewSize;
- }
-}
-
+void TpiStreamBuilder::updateTypeIndexOffsets(ArrayRef<uint16_t> Sizes) {
+ // If we just crossed an 8KB threshold, add a type index offset.
+ for (uint16_t Size : Sizes) {
+ size_t NewSize = TypeRecordBytes + Size;
+ constexpr size_t EightKB = 8 * 1024;
+ if (NewSize / EightKB > TypeRecordBytes / EightKB || TypeRecordCount == 0) {
+ TypeIndexOffsets.push_back(
+ {codeview::TypeIndex(codeview::TypeIndex::FirstNonSimpleIndex +
+ TypeRecordCount),
+ ulittle32_t(TypeRecordBytes)});
+ }
+ ++TypeRecordCount;
+ TypeRecordBytes = NewSize;
+ }
+}
+
void TpiStreamBuilder::addTypeRecord(ArrayRef<uint8_t> Record,
Optional<uint32_t> Hash) {
assert(((Record.size() & 3) == 0) &&
"The type record's size is not a multiple of 4 bytes which will "
"cause misalignment in the output TPI stream!");
- assert(Record.size() <= codeview::MaxRecordLength);
- uint16_t OneSize = (uint16_t)Record.size();
- updateTypeIndexOffsets(makeArrayRef(&OneSize, 1));
+ assert(Record.size() <= codeview::MaxRecordLength);
+ uint16_t OneSize = (uint16_t)Record.size();
+ updateTypeIndexOffsets(makeArrayRef(&OneSize, 1));
- TypeRecBuffers.push_back(Record);
- // FIXME: Require it.
+ TypeRecBuffers.push_back(Record);
+ // FIXME: Require it.
if (Hash)
TypeHashes.push_back(*Hash);
}
-void TpiStreamBuilder::addTypeRecords(ArrayRef<uint8_t> Types,
- ArrayRef<uint16_t> Sizes,
- ArrayRef<uint32_t> Hashes) {
- // Ignore empty type buffers. There should be no hashes or sizes in this case.
- if (Types.empty()) {
- assert(Sizes.empty() && Hashes.empty());
- return;
- }
-
- assert(((Types.size() & 3) == 0) &&
- "The type record's size is not a multiple of 4 bytes which will "
- "cause misalignment in the output TPI stream!");
- assert(Sizes.size() == Hashes.size() && "sizes and hashes should be in sync");
- assert(std::accumulate(Sizes.begin(), Sizes.end(), 0U) == Types.size() &&
- "sizes of type records should sum to the size of the types");
- updateTypeIndexOffsets(Sizes);
-
- TypeRecBuffers.push_back(Types);
- llvm::append_range(TypeHashes, Hashes);
-}
-
+void TpiStreamBuilder::addTypeRecords(ArrayRef<uint8_t> Types,
+ ArrayRef<uint16_t> Sizes,
+ ArrayRef<uint32_t> Hashes) {
+ // Ignore empty type buffers. There should be no hashes or sizes in this case.
+ if (Types.empty()) {
+ assert(Sizes.empty() && Hashes.empty());
+ return;
+ }
+
+ assert(((Types.size() & 3) == 0) &&
+ "The type record's size is not a multiple of 4 bytes which will "
+ "cause misalignment in the output TPI stream!");
+ assert(Sizes.size() == Hashes.size() && "sizes and hashes should be in sync");
+ assert(std::accumulate(Sizes.begin(), Sizes.end(), 0U) == Types.size() &&
+ "sizes of type records should sum to the size of the types");
+ updateTypeIndexOffsets(Sizes);
+
+ TypeRecBuffers.push_back(Types);
+ llvm::append_range(TypeHashes, Hashes);
+}
+
Error TpiStreamBuilder::finalize() {
if (Header)
return Error::success();
@@ -103,7 +103,7 @@ Error TpiStreamBuilder::finalize() {
H->Version = VerHeader;
H->HeaderSize = sizeof(TpiStreamHeader);
H->TypeIndexBegin = codeview::TypeIndex::FirstNonSimpleIndex;
- H->TypeIndexEnd = H->TypeIndexBegin + TypeRecordCount;
+ H->TypeIndexEnd = H->TypeIndexBegin + TypeRecordCount;
H->TypeRecordBytes = TypeRecordBytes;
H->HashStreamIndex = HashStreamIndex;
@@ -134,7 +134,7 @@ uint32_t TpiStreamBuilder::calculateSerializedLength() {
}
uint32_t TpiStreamBuilder::calculateHashBufferSize() const {
- assert((TypeRecordCount == TypeHashes.size() || TypeHashes.empty()) &&
+ assert((TypeRecordCount == TypeHashes.size() || TypeHashes.empty()) &&
"either all or no type records should have hashes");
return TypeHashes.size() * sizeof(ulittle32_t);
}
@@ -185,7 +185,7 @@ Error TpiStreamBuilder::commit(const msf::MSFLayout &Layout,
if (auto EC = Writer.writeObject(*Header))
return EC;
- for (auto Rec : TypeRecBuffers) {
+ for (auto Rec : TypeRecBuffers) {
assert(!Rec.empty() && "Attempting to write an empty type record shifts "
"all offsets in the TPI stream!");
assert(((Rec.size() & 3) == 0) &&
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDB.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDB.cpp
index 50e48bfbdb..6dc42715fb 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDB.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDB.cpp
@@ -11,7 +11,7 @@
#include "llvm/Config/config.h"
#include "llvm/DebugInfo/PDB/GenericError.h"
#if LLVM_ENABLE_DIA_SDK
-#error #include "llvm/DebugInfo/PDB/DIA/DIASession.h"
+#error #include "llvm/DebugInfo/PDB/DIA/DIASession.h"
#endif
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/Support/Error.h"
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBContext.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBContext.cpp
index 2fca37dd38..0ebb70e010 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBContext.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBContext.cpp
@@ -86,43 +86,43 @@ DIInliningInfo
PDBContext::getInliningInfoForAddress(object::SectionedAddress Address,
DILineInfoSpecifier Specifier) {
DIInliningInfo InlineInfo;
- DILineInfo CurrentLine = getLineInfoForAddress(Address, Specifier);
-
- // Find the function at this address.
- std::unique_ptr<PDBSymbol> ParentFunc =
- Session->findSymbolByAddress(Address.Address, PDB_SymType::Function);
- if (!ParentFunc) {
- InlineInfo.addFrame(CurrentLine);
- return InlineInfo;
- }
-
- auto Frames = ParentFunc->findInlineFramesByVA(Address.Address);
- if (!Frames || Frames->getChildCount() == 0) {
- InlineInfo.addFrame(CurrentLine);
- return InlineInfo;
- }
-
- while (auto Frame = Frames->getNext()) {
- uint32_t Length = 1;
- auto LineNumbers = Frame->findInlineeLinesByVA(Address.Address, Length);
- if (!LineNumbers || LineNumbers->getChildCount() == 0)
- break;
-
- std::unique_ptr<IPDBLineNumber> Line = LineNumbers->getNext();
- assert(Line);
-
- DILineInfo LineInfo;
- LineInfo.FunctionName = Frame->getName();
- auto SourceFile = Session->getSourceFileById(Line->getSourceFileId());
- if (SourceFile &&
- Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None)
- LineInfo.FileName = SourceFile->getFileName();
- LineInfo.Line = Line->getLineNumber();
- LineInfo.Column = Line->getColumnNumber();
- InlineInfo.addFrame(LineInfo);
- }
-
- InlineInfo.addFrame(CurrentLine);
+ DILineInfo CurrentLine = getLineInfoForAddress(Address, Specifier);
+
+ // Find the function at this address.
+ std::unique_ptr<PDBSymbol> ParentFunc =
+ Session->findSymbolByAddress(Address.Address, PDB_SymType::Function);
+ if (!ParentFunc) {
+ InlineInfo.addFrame(CurrentLine);
+ return InlineInfo;
+ }
+
+ auto Frames = ParentFunc->findInlineFramesByVA(Address.Address);
+ if (!Frames || Frames->getChildCount() == 0) {
+ InlineInfo.addFrame(CurrentLine);
+ return InlineInfo;
+ }
+
+ while (auto Frame = Frames->getNext()) {
+ uint32_t Length = 1;
+ auto LineNumbers = Frame->findInlineeLinesByVA(Address.Address, Length);
+ if (!LineNumbers || LineNumbers->getChildCount() == 0)
+ break;
+
+ std::unique_ptr<IPDBLineNumber> Line = LineNumbers->getNext();
+ assert(Line);
+
+ DILineInfo LineInfo;
+ LineInfo.FunctionName = Frame->getName();
+ auto SourceFile = Session->getSourceFileById(Line->getSourceFileId());
+ if (SourceFile &&
+ Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None)
+ LineInfo.FileName = SourceFile->getFileName();
+ LineInfo.Line = Line->getLineNumber();
+ LineInfo.Column = Line->getColumnNumber();
+ InlineInfo.addFrame(LineInfo);
+ }
+
+ InlineInfo.addFrame(CurrentLine);
return InlineInfo;
}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBExtras.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBExtras.cpp
index 1be88c16a5..25962e5152 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBExtras.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBExtras.cpp
@@ -118,22 +118,22 @@ raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_DataKind &Data) {
raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
const llvm::codeview::CPURegister &CpuReg) {
- if (CpuReg.Cpu == llvm::codeview::CPUType::ARMNT) {
+ if (CpuReg.Cpu == llvm::codeview::CPUType::ARMNT) {
+ switch (CpuReg.Reg) {
+#define CV_REGISTERS_ARM
+#define CV_REGISTER(name, val) \
+ case codeview::RegisterId::name: \
+ OS << #name; \
+ return OS;
+#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
+#undef CV_REGISTER
+#undef CV_REGISTERS_ARM
+
+ default:
+ break;
+ }
+ } else if (CpuReg.Cpu == llvm::codeview::CPUType::ARM64) {
switch (CpuReg.Reg) {
-#define CV_REGISTERS_ARM
-#define CV_REGISTER(name, val) \
- case codeview::RegisterId::name: \
- OS << #name; \
- return OS;
-#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
-#undef CV_REGISTER
-#undef CV_REGISTERS_ARM
-
- default:
- break;
- }
- } else if (CpuReg.Cpu == llvm::codeview::CPUType::ARM64) {
- switch (CpuReg.Reg) {
#define CV_REGISTERS_ARM64
#define CV_REGISTER(name, val) \
case codeview::RegisterId::name: \
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp
index 325e937dac..d51091d809 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp
@@ -1,4 +1,4 @@
-//===- PDBInterfaceAnchors.h - defines class anchor functions ---*- C++ -*-===//
+//===- PDBInterfaceAnchors.h - defines class anchor functions ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
// Class anchors are necessary per the LLVM Coding style guide, to ensure that
// the vtable is only generated in this object file, and not in every object
-// file that includes the corresponding header.
+// file that includes the corresponding header.
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/IPDBDataStream.h"
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbol.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbol.cpp
index c60065b9cc..d6bc7ee9c9 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbol.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbol.cpp
@@ -161,27 +161,27 @@ PDBSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name,
}
std::unique_ptr<IPDBEnumSymbols>
-PDBSymbol::findInlineFramesByVA(uint64_t VA) const {
- return RawSymbol->findInlineFramesByVA(VA);
-}
-
-std::unique_ptr<IPDBEnumSymbols>
+PDBSymbol::findInlineFramesByVA(uint64_t VA) const {
+ return RawSymbol->findInlineFramesByVA(VA);
+}
+
+std::unique_ptr<IPDBEnumSymbols>
PDBSymbol::findInlineFramesByRVA(uint32_t RVA) const {
return RawSymbol->findInlineFramesByRVA(RVA);
}
-std::unique_ptr<IPDBEnumLineNumbers>
-PDBSymbol::findInlineeLinesByVA(uint64_t VA, uint32_t Length) const {
- return RawSymbol->findInlineeLinesByVA(VA, Length);
-}
-
-std::unique_ptr<IPDBEnumLineNumbers>
-PDBSymbol::findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const {
- return RawSymbol->findInlineeLinesByRVA(RVA, Length);
-}
-
-std::string PDBSymbol::getName() const { return RawSymbol->getName(); }
-
+std::unique_ptr<IPDBEnumLineNumbers>
+PDBSymbol::findInlineeLinesByVA(uint64_t VA, uint32_t Length) const {
+ return RawSymbol->findInlineeLinesByVA(VA, Length);
+}
+
+std::unique_ptr<IPDBEnumLineNumbers>
+PDBSymbol::findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const {
+ return RawSymbol->findInlineeLinesByRVA(RVA, Length);
+}
+
+std::string PDBSymbol::getName() const { return RawSymbol->getName(); }
+
std::unique_ptr<IPDBEnumSymbols>
PDBSymbol::getChildStats(TagStats &Stats) const {
std::unique_ptr<IPDBEnumSymbols> Result(findAllChildren());
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/UDTLayout.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/UDTLayout.cpp
index b6e5fe2612..55854bb498 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/UDTLayout.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/UDTLayout.cpp
@@ -289,10 +289,10 @@ void UDTLayoutBase::addChildToLayout(std::unique_ptr<LayoutItemBase> Child) {
UsedBytes |= ChildBytes;
if (ChildBytes.count() > 0) {
- auto Loc = llvm::upper_bound(
- LayoutItems, Begin, [](uint32_t Off, const LayoutItemBase *Item) {
- return (Off < Item->getOffsetInParent());
- });
+ auto Loc = llvm::upper_bound(
+ LayoutItems, Begin, [](uint32_t Off, const LayoutItemBase *Item) {
+ return (Off < Item->getOffsetInParent());
+ });
LayoutItems.insert(Loc, Child.get());
}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/ya.make b/contrib/libs/llvm12/lib/DebugInfo/PDB/ya.make
index 6a5df3009b..daa2f8ed3a 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/ya.make
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/ya.make
@@ -12,12 +12,12 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/DebugInfo/CodeView
- contrib/libs/llvm12/lib/DebugInfo/MSF
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/DebugInfo/CodeView
+ contrib/libs/llvm12/lib/DebugInfo/MSF
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
@@ -51,11 +51,11 @@ SRCS(
Native/NativeEnumInjectedSources.cpp
Native/NativeEnumLineNumbers.cpp
Native/NativeEnumModules.cpp
- Native/NativeEnumSymbols.cpp
+ Native/NativeEnumSymbols.cpp
Native/NativeEnumTypes.cpp
Native/NativeExeSymbol.cpp
Native/NativeFunctionSymbol.cpp
- Native/NativeInlineSiteSymbol.cpp
+ Native/NativeInlineSiteSymbol.cpp
Native/NativeLineNumber.cpp
Native/NativePublicSymbol.cpp
Native/NativeRawSymbol.cpp
diff --git a/contrib/libs/llvm12/lib/DebugInfo/Symbolize/DIPrinter.cpp b/contrib/libs/llvm12/lib/DebugInfo/Symbolize/DIPrinter.cpp
index fdcaa702c7..01dc31d849 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/Symbolize/DIPrinter.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/Symbolize/DIPrinter.cpp
@@ -84,10 +84,10 @@ void DIPrinter::print(const DILineInfo &Info, bool Inlined) {
return;
}
OS << " Filename: " << Filename << "\n";
- if (Info.StartLine) {
- OS << " Function start filename: " << Info.StartFileName << "\n";
- OS << " Function start line: " << Info.StartLine << "\n";
- }
+ if (Info.StartLine) {
+ OS << " Function start filename: " << Info.StartFileName << "\n";
+ OS << " Function start line: " << Info.StartLine << "\n";
+ }
OS << " Line: " << Info.Line << "\n";
OS << " Column: " << Info.Column << "\n";
if (Info.Discriminator)
diff --git a/contrib/libs/llvm12/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h b/contrib/libs/llvm12/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
index a04ff84ac9..be3c66df05 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
+++ b/contrib/libs/llvm12/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
@@ -15,12 +15,12 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
-#include "llvm/Support/Error.h"
+#include "llvm/Support/Error.h"
#include <cstdint>
#include <memory>
#include <string>
-#include <utility>
-#include <vector>
+#include <utility>
+#include <vector>
namespace llvm {
diff --git a/contrib/libs/llvm12/lib/DebugInfo/Symbolize/Symbolize.cpp b/contrib/libs/llvm12/lib/DebugInfo/Symbolize/Symbolize.cpp
index 4168f8118c..da157a5a25 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/Symbolize/Symbolize.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/Symbolize/Symbolize.cpp
@@ -16,7 +16,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/BinaryFormat/COFF.h"
-#include "llvm/Config/config.h"
+#include "llvm/Config/config.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/PDB/PDB.h"
#include "llvm/DebugInfo/PDB/PDBContext.h"
@@ -287,8 +287,8 @@ bool darwinDsymMatchesBinary(const MachOObjectFile *DbgObj,
}
template <typename ELFT>
-Optional<ArrayRef<uint8_t>> getBuildID(const ELFFile<ELFT> &Obj) {
- auto PhdrsOrErr = Obj.program_headers();
+Optional<ArrayRef<uint8_t>> getBuildID(const ELFFile<ELFT> &Obj) {
+ auto PhdrsOrErr = Obj.program_headers();
if (!PhdrsOrErr) {
consumeError(PhdrsOrErr.takeError());
return {};
@@ -297,7 +297,7 @@ Optional<ArrayRef<uint8_t>> getBuildID(const ELFFile<ELFT> &Obj) {
if (P.p_type != ELF::PT_NOTE)
continue;
Error Err = Error::success();
- for (auto N : Obj.notes(P, Err))
+ for (auto N : Obj.notes(P, Err))
if (N.getType() == ELF::NT_GNU_BUILD_ID && N.getName() == ELF::ELF_NOTE_GNU)
return N.getDesc();
consumeError(std::move(Err));
@@ -554,9 +554,9 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) {
if (!EC && DebugInfo != nullptr && !PDBFileName.empty()) {
using namespace pdb;
std::unique_ptr<IPDBSession> Session;
-
- PDB_ReaderType ReaderType =
- Opts.UseDIA ? PDB_ReaderType::DIA : PDB_ReaderType::Native;
+
+ PDB_ReaderType ReaderType =
+ Opts.UseDIA ? PDB_ReaderType::DIA : PDB_ReaderType::Native;
if (auto Err = loadDataForEXE(ReaderType, Objects.first->getFileName(),
Session)) {
Modules.emplace(ModuleName, std::unique_ptr<SymbolizableModule>());
@@ -589,7 +589,7 @@ StringRef demanglePE32ExternCFunc(StringRef SymbolName) {
if (Front != '?') {
size_t AtPos = SymbolName.rfind('@');
if (AtPos != StringRef::npos &&
- all_of(drop_begin(SymbolName, AtPos + 1), isDigit))
+ all_of(drop_begin(SymbolName, AtPos + 1), isDigit))
SymbolName = SymbolName.substr(0, AtPos);
}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/Symbolize/ya.make b/contrib/libs/llvm12/lib/DebugInfo/Symbolize/ya.make
index 487d1503c8..b627533f82 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/Symbolize/ya.make
+++ b/contrib/libs/llvm12/lib/DebugInfo/Symbolize/ya.make
@@ -12,12 +12,12 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/DebugInfo/DWARF
- contrib/libs/llvm12/lib/DebugInfo/PDB
- contrib/libs/llvm12/lib/Demangle
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/DebugInfo/DWARF
+ contrib/libs/llvm12/lib/DebugInfo/PDB
+ contrib/libs/llvm12/lib/Demangle
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/Demangle/Demangle.cpp b/contrib/libs/llvm12/lib/Demangle/Demangle.cpp
index 2444171b8d..000f75b6a9 100644
--- a/contrib/libs/llvm12/lib/Demangle/Demangle.cpp
+++ b/contrib/libs/llvm12/lib/Demangle/Demangle.cpp
@@ -31,6 +31,6 @@ std::string llvm::demangle(const std::string &MangledName) {
return MangledName;
std::string Ret = Demangled;
- std::free(Demangled);
+ std::free(Demangled);
return Ret;
}
diff --git a/contrib/libs/llvm12/lib/Demangle/ya.make b/contrib/libs/llvm12/lib/Demangle/ya.make
index f46b150de7..16c0cf64f7 100644
--- a/contrib/libs/llvm12/lib/Demangle/ya.make
+++ b/contrib/libs/llvm12/lib/Demangle/ya.make
@@ -12,7 +12,7 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
+ contrib/libs/llvm12
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/ExecutionEngine/ExecutionEngine.cpp b/contrib/libs/llvm12/lib/ExecutionEngine/ExecutionEngine.cpp
index 2352e8734d..c8bbf0bcdf 100644
--- a/contrib/libs/llvm12/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/contrib/libs/llvm12/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -471,7 +471,7 @@ EngineBuilder::EngineBuilder() : EngineBuilder(nullptr) {}
EngineBuilder::EngineBuilder(std::unique_ptr<Module> M)
: M(std::move(M)), WhichEngine(EngineKind::Either), ErrorStr(nullptr),
- OptLevel(CodeGenOpt::Default), MemMgr(nullptr), Resolver(nullptr) {
+ OptLevel(CodeGenOpt::Default), MemMgr(nullptr), Resolver(nullptr) {
// IR module verification is enabled by default in debug builds, and disabled
// by default in release builds.
#ifndef NDEBUG
@@ -534,7 +534,7 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
}
ExecutionEngine *EE = nullptr;
- if (ExecutionEngine::MCJITCtor)
+ if (ExecutionEngine::MCJITCtor)
EE = ExecutionEngine::MCJITCtor(std::move(M), ErrorStr, std::move(MemMgr),
std::move(Resolver), std::move(TheTM));
diff --git a/contrib/libs/llvm12/lib/ExecutionEngine/MCJIT/MCJIT.h b/contrib/libs/llvm12/lib/ExecutionEngine/MCJIT/MCJIT.h
index d737e78437..52e7eda903 100644
--- a/contrib/libs/llvm12/lib/ExecutionEngine/MCJIT/MCJIT.h
+++ b/contrib/libs/llvm12/lib/ExecutionEngine/MCJIT/MCJIT.h
@@ -102,22 +102,22 @@ class MCJIT : public ExecutionEngine {
}
bool hasModuleBeenAddedButNotLoaded(Module *M) {
- return AddedModules.contains(M);
+ return AddedModules.contains(M);
}
bool hasModuleBeenLoaded(Module *M) {
// If the module is in either the "loaded" or "finalized" sections it
// has been loaded.
- return LoadedModules.contains(M) || FinalizedModules.contains(M);
+ return LoadedModules.contains(M) || FinalizedModules.contains(M);
}
bool hasModuleBeenFinalized(Module *M) {
- return FinalizedModules.contains(M);
+ return FinalizedModules.contains(M);
}
bool ownsModule(Module* M) {
- return AddedModules.contains(M) || LoadedModules.contains(M) ||
- FinalizedModules.contains(M);
+ return AddedModules.contains(M) || LoadedModules.contains(M) ||
+ FinalizedModules.contains(M);
}
void markModuleAsLoaded(Module *M) {
diff --git a/contrib/libs/llvm12/lib/ExecutionEngine/MCJIT/ya.make b/contrib/libs/llvm12/lib/ExecutionEngine/MCJIT/ya.make
index 05253d65e8..71377b654c 100644
--- a/contrib/libs/llvm12/lib/ExecutionEngine/MCJIT/ya.make
+++ b/contrib/libs/llvm12/lib/ExecutionEngine/MCJIT/ya.make
@@ -12,14 +12,14 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/ExecutionEngine
- contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/ExecutionEngine
+ contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/ExecutionEngine/PerfJITEvents/ya.make b/contrib/libs/llvm12/lib/ExecutionEngine/PerfJITEvents/ya.make
index 3c266bef99..dc91e6b801 100644
--- a/contrib/libs/llvm12/lib/ExecutionEngine/PerfJITEvents/ya.make
+++ b/contrib/libs/llvm12/lib/ExecutionEngine/PerfJITEvents/ya.make
@@ -12,14 +12,14 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/CodeGen
- contrib/libs/llvm12/lib/DebugInfo/DWARF
- contrib/libs/llvm12/lib/ExecutionEngine
- contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/CodeGen
+ contrib/libs/llvm12/lib/DebugInfo/DWARF
+ contrib/libs/llvm12/lib/ExecutionEngine
+ contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp b/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp
index 136f7a5d74..741aa58350 100644
--- a/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp
+++ b/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp
@@ -31,8 +31,8 @@ namespace llvm {
RTDyldMemoryManager::~RTDyldMemoryManager() {}
-#if defined(HAVE_REGISTER_FRAME) && defined(HAVE_DEREGISTER_FRAME) && \
- !defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
+#if defined(HAVE_REGISTER_FRAME) && defined(HAVE_DEREGISTER_FRAME) && \
+ !defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
extern "C" void __register_frame(void *);
extern "C" void __deregister_frame(void *);
#else
diff --git a/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
index b5c64db21f..e49e6e541f 100644
--- a/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -1206,19 +1206,19 @@ Error RuntimeDyldImpl::resolveExternalSymbols() {
void RuntimeDyldImpl::finalizeAsync(
std::unique_ptr<RuntimeDyldImpl> This,
- unique_function<void(object::OwningBinary<object::ObjectFile>,
- std::unique_ptr<RuntimeDyld::LoadedObjectInfo>, Error)>
+ unique_function<void(object::OwningBinary<object::ObjectFile>,
+ std::unique_ptr<RuntimeDyld::LoadedObjectInfo>, Error)>
OnEmitted,
- object::OwningBinary<object::ObjectFile> O,
- std::unique_ptr<RuntimeDyld::LoadedObjectInfo> Info) {
+ object::OwningBinary<object::ObjectFile> O,
+ std::unique_ptr<RuntimeDyld::LoadedObjectInfo> Info) {
auto SharedThis = std::shared_ptr<RuntimeDyldImpl>(std::move(This));
auto PostResolveContinuation =
- [SharedThis, OnEmitted = std::move(OnEmitted), O = std::move(O),
- Info = std::move(Info)](
+ [SharedThis, OnEmitted = std::move(OnEmitted), O = std::move(O),
+ Info = std::move(Info)](
Expected<JITSymbolResolver::LookupResult> Result) mutable {
if (!Result) {
- OnEmitted(std::move(O), std::move(Info), Result.takeError());
+ OnEmitted(std::move(O), std::move(Info), Result.takeError());
return;
}
@@ -1232,11 +1232,11 @@ void RuntimeDyldImpl::finalizeAsync(
SharedThis->registerEHFrames();
std::string ErrMsg;
if (SharedThis->MemMgr.finalizeMemory(&ErrMsg))
- OnEmitted(std::move(O), std::move(Info),
+ OnEmitted(std::move(O), std::move(Info),
make_error<StringError>(std::move(ErrMsg),
inconvertibleErrorCode()));
else
- OnEmitted(std::move(O), std::move(Info), Error::success());
+ OnEmitted(std::move(O), std::move(Info), Error::success());
};
JITSymbolResolver::LookupSet Symbols;
@@ -1428,12 +1428,12 @@ void jitLinkForORC(
object::OwningBinary<object::ObjectFile> O,
RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver,
bool ProcessAllSections,
- unique_function<Error(const object::ObjectFile &Obj,
- RuntimeDyld::LoadedObjectInfo &LoadedObj,
- std::map<StringRef, JITEvaluatedSymbol>)>
+ unique_function<Error(const object::ObjectFile &Obj,
+ RuntimeDyld::LoadedObjectInfo &LoadedObj,
+ std::map<StringRef, JITEvaluatedSymbol>)>
OnLoaded,
- unique_function<void(object::OwningBinary<object::ObjectFile>,
- std::unique_ptr<RuntimeDyld::LoadedObjectInfo>, Error)>
+ unique_function<void(object::OwningBinary<object::ObjectFile>,
+ std::unique_ptr<RuntimeDyld::LoadedObjectInfo>, Error)>
OnEmitted) {
RuntimeDyld RTDyld(MemMgr, Resolver);
@@ -1442,17 +1442,17 @@ void jitLinkForORC(
auto Info = RTDyld.loadObject(*O.getBinary());
if (RTDyld.hasError()) {
- OnEmitted(std::move(O), std::move(Info),
- make_error<StringError>(RTDyld.getErrorString(),
- inconvertibleErrorCode()));
+ OnEmitted(std::move(O), std::move(Info),
+ make_error<StringError>(RTDyld.getErrorString(),
+ inconvertibleErrorCode()));
return;
}
- if (auto Err = OnLoaded(*O.getBinary(), *Info, RTDyld.getSymbolTable()))
- OnEmitted(std::move(O), std::move(Info), std::move(Err));
+ if (auto Err = OnLoaded(*O.getBinary(), *Info, RTDyld.getSymbolTable()))
+ OnEmitted(std::move(O), std::move(Info), std::move(Err));
RuntimeDyldImpl::finalizeAsync(std::move(RTDyld.Dyld), std::move(OnEmitted),
- std::move(O), std::move(Info));
+ std::move(O), std::move(Info));
}
} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
index 31d8109bf7..2fbe707ce8 100644
--- a/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
+++ b/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
@@ -352,7 +352,7 @@ private:
RemainingExpr = RemainingExpr.substr(1).ltrim();
uint64_t StubAddr;
- std::string ErrorMsg;
+ std::string ErrorMsg;
std::tie(StubAddr, ErrorMsg) = Checker.getStubOrGOTAddrFor(
StubContainerName, Symbol, PCtx.IsInsideLoad, IsStubAddr);
@@ -389,7 +389,7 @@ private:
RemainingExpr = RemainingExpr.substr(1).ltrim();
uint64_t StubAddr;
- std::string ErrorMsg;
+ std::string ErrorMsg;
std::tie(StubAddr, ErrorMsg) = Checker.getSectionAddr(
FileName, SectionName, PCtx.IsInsideLoad);
diff --git a/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index 03e62bf025..28e1faab5a 100644
--- a/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -954,8 +954,8 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section,
resolveARMRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type,
(uint32_t)(Addend & 0xffffffffL));
break;
- case Triple::ppc: // Fall through.
- case Triple::ppcle:
+ case Triple::ppc: // Fall through.
+ case Triple::ppcle:
resolvePPC32Relocation(Section, Offset, Value, Type, Addend);
break;
case Triple::ppc64: // Fall through.
@@ -1670,33 +1670,33 @@ RuntimeDyldELF::processRelocationRef(
if (Value.SymbolName) {
// This is a call to an external function.
// Look for an existing stub.
- SectionEntry *Section = &Sections[SectionID];
+ SectionEntry *Section = &Sections[SectionID];
StubMap::const_iterator i = Stubs.find(Value);
uintptr_t StubAddress;
if (i != Stubs.end()) {
- StubAddress = uintptr_t(Section->getAddress()) + i->second;
+ StubAddress = uintptr_t(Section->getAddress()) + i->second;
LLVM_DEBUG(dbgs() << " Stub function found\n");
} else {
// Create a new stub function (equivalent to a PLT entry).
LLVM_DEBUG(dbgs() << " Create a new stub function\n");
- uintptr_t BaseAddress = uintptr_t(Section->getAddress());
+ uintptr_t BaseAddress = uintptr_t(Section->getAddress());
uintptr_t StubAlignment = getStubAlignment();
StubAddress =
- (BaseAddress + Section->getStubOffset() + StubAlignment - 1) &
+ (BaseAddress + Section->getStubOffset() + StubAlignment - 1) &
-StubAlignment;
unsigned StubOffset = StubAddress - BaseAddress;
Stubs[Value] = StubOffset;
createStubFunction((uint8_t *)StubAddress);
// Bump our stub offset counter
- Section->advanceStubOffset(getMaxStubSize());
+ Section->advanceStubOffset(getMaxStubSize());
// Allocate a GOT Entry
uint64_t GOTOffset = allocateGOTEntries(1);
- // This potentially creates a new Section which potentially
- // invalidates the Section pointer, so reload it.
- Section = &Sections[SectionID];
+ // This potentially creates a new Section which potentially
+ // invalidates the Section pointer, so reload it.
+ Section = &Sections[SectionID];
// The load of the GOT address has an addend of -4
resolveGOTOffsetRelocation(SectionID, StubOffset + 2, GOTOffset - 4,
@@ -1709,7 +1709,7 @@ RuntimeDyldELF::processRelocationRef(
}
// Make the target call a call into the stub table.
- resolveRelocation(*Section, Offset, StubAddress, ELF::R_X86_64_PC32,
+ resolveRelocation(*Section, Offset, StubAddress, ELF::R_X86_64_PC32,
Addend);
} else {
RelocationEntry RE(SectionID, Offset, ELF::R_X86_64_PC32, Value.Addend,
diff --git a/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
index 49e3dbc7fe..d34fae9aaf 100644
--- a/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
+++ b/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
@@ -535,12 +535,12 @@ public:
static void finalizeAsync(
std::unique_ptr<RuntimeDyldImpl> This,
- unique_function<void(object::OwningBinary<object::ObjectFile>,
- std::unique_ptr<RuntimeDyld::LoadedObjectInfo>,
- Error)>
+ unique_function<void(object::OwningBinary<object::ObjectFile>,
+ std::unique_ptr<RuntimeDyld::LoadedObjectInfo>,
+ Error)>
OnEmitted,
- object::OwningBinary<object::ObjectFile> O,
- std::unique_ptr<RuntimeDyld::LoadedObjectInfo> Info);
+ object::OwningBinary<object::ObjectFile> O,
+ std::unique_ptr<RuntimeDyld::LoadedObjectInfo> Info);
void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
diff --git a/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h b/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h
index f600432e0b..9df3e2e3c3 100644
--- a/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h
+++ b/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h
@@ -113,10 +113,10 @@ public:
// The MemoryManager can make sure this is always true by forcing the
// memory layout to be: CodeSection < ReadOnlySection < ReadWriteSection.
const uint64_t ImageBase = getImageBase();
- if (Value < ImageBase || ((Value - ImageBase) > UINT32_MAX))
- report_fatal_error("IMAGE_REL_AMD64_ADDR32NB relocation requires an "
- "ordered section layout");
- else {
+ if (Value < ImageBase || ((Value - ImageBase) > UINT32_MAX))
+ report_fatal_error("IMAGE_REL_AMD64_ADDR32NB relocation requires an "
+ "ordered section layout");
+ else {
write32BitOffset(Target, RE.Addend, Value - ImageBase);
}
break;
diff --git a/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/ya.make b/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/ya.make
index 68dac33fc3..44d7dea118 100644
--- a/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/ya.make
+++ b/contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld/ya.make
@@ -12,12 +12,12 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/ExecutionEngine/SectionMemoryManager.cpp b/contrib/libs/llvm12/lib/ExecutionEngine/SectionMemoryManager.cpp
index ba25ea0839..6690dd07d9 100644
--- a/contrib/libs/llvm12/lib/ExecutionEngine/SectionMemoryManager.cpp
+++ b/contrib/libs/llvm12/lib/ExecutionEngine/SectionMemoryManager.cpp
@@ -112,15 +112,15 @@ uint8_t *SectionMemoryManager::allocateSection(
// Save this address as the basis for our next request
MemGroup.Near = MB;
- // Copy the address to all the other groups, if they have not
- // been initialized.
- if (CodeMem.Near.base() == 0)
- CodeMem.Near = MB;
- if (RODataMem.Near.base() == 0)
- RODataMem.Near = MB;
- if (RWDataMem.Near.base() == 0)
- RWDataMem.Near = MB;
-
+ // Copy the address to all the other groups, if they have not
+ // been initialized.
+ if (CodeMem.Near.base() == 0)
+ CodeMem.Near = MB;
+ if (RODataMem.Near.base() == 0)
+ RODataMem.Near = MB;
+ if (RWDataMem.Near.base() == 0)
+ RWDataMem.Near = MB;
+
// Remember that we allocated this memory
MemGroup.AllocatedMem.push_back(MB);
Addr = (uintptr_t)MB.base();
@@ -161,7 +161,7 @@ bool SectionMemoryManager::finalizeMemory(std::string *ErrMsg) {
}
// Make read-only data memory read-only.
- ec = applyMemoryGroupPermissions(RODataMem, sys::Memory::MF_READ);
+ ec = applyMemoryGroupPermissions(RODataMem, sys::Memory::MF_READ);
if (ec) {
if (ErrMsg) {
*ErrMsg = ec.message();
@@ -218,9 +218,9 @@ SectionMemoryManager::applyMemoryGroupPermissions(MemoryGroup &MemGroup,
}
// Remove all blocks which are now empty
- erase_if(MemGroup.FreeMem, [](FreeMemBlock &FreeMB) {
- return FreeMB.Free.allocatedSize() == 0;
- });
+ erase_if(MemGroup.FreeMem, [](FreeMemBlock &FreeMB) {
+ return FreeMB.Free.allocatedSize() == 0;
+ });
return std::error_code();
}
diff --git a/contrib/libs/llvm12/lib/ExecutionEngine/ya.make b/contrib/libs/llvm12/lib/ExecutionEngine/ya.make
index 3eeadb4e79..38849572cb 100644
--- a/contrib/libs/llvm12/lib/ExecutionEngine/ya.make
+++ b/contrib/libs/llvm12/lib/ExecutionEngine/ya.make
@@ -12,14 +12,14 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/Frontend/OpenMP/OMPContext.cpp b/contrib/libs/llvm12/lib/Frontend/OpenMP/OMPContext.cpp
index b94e7950f9..11d8da097c 100644
--- a/contrib/libs/llvm12/lib/Frontend/OpenMP/OMPContext.cpp
+++ b/contrib/libs/llvm12/lib/Frontend/OpenMP/OMPContext.cpp
@@ -14,9 +14,9 @@
#include "llvm/Frontend/OpenMP/OMPContext.h"
#include "llvm/ADT/SetOperations.h"
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
@@ -42,7 +42,7 @@ OMPContext::OMPContext(bool IsDeviceCompilation, Triple TargetTriple) {
case Triple::mips64:
case Triple::mips64el:
case Triple::ppc:
- case Triple::ppcle:
+ case Triple::ppcle:
case Triple::ppc64:
case Triple::ppc64le:
case Triple::x86:
@@ -60,13 +60,13 @@ OMPContext::OMPContext(bool IsDeviceCompilation, Triple TargetTriple) {
// Add the appropriate device architecture trait based on the triple.
#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
- if (TraitSelector::TraitSelectorEnum == TraitSelector::device_arch) { \
+ if (TraitSelector::TraitSelectorEnum == TraitSelector::device_arch) { \
if (TargetTriple.getArch() == TargetTriple.getArchTypeForLLVMName(Str)) \
- ActiveTraits.set(unsigned(TraitProperty::Enum)); \
- if (StringRef(Str) == StringRef("x86_64") && \
- TargetTriple.getArch() == Triple::x86_64) \
- ActiveTraits.set(unsigned(TraitProperty::Enum)); \
- }
+ ActiveTraits.set(unsigned(TraitProperty::Enum)); \
+ if (StringRef(Str) == StringRef("x86_64") && \
+ TargetTriple.getArch() == Triple::x86_64) \
+ ActiveTraits.set(unsigned(TraitProperty::Enum)); \
+ }
#include "llvm/Frontend/OpenMP/OMPKinds.def"
// TODO: What exactly do we want to see as device ISA trait?
@@ -182,11 +182,11 @@ static int isVariantApplicableInContextHelper(
LLVM_DEBUG({
if (MK == MK_ALL)
dbgs() << "[" << DEBUG_TYPE << "] Property "
- << getOpenMPContextTraitPropertyName(Property, "")
+ << getOpenMPContextTraitPropertyName(Property, "")
<< " was not in the OpenMP context but match kind is all.\n";
if (MK == MK_NONE)
dbgs() << "[" << DEBUG_TYPE << "] Property "
- << getOpenMPContextTraitPropertyName(Property, "")
+ << getOpenMPContextTraitPropertyName(Property, "")
<< " was in the OpenMP context but match kind is none.\n";
});
return false;
@@ -205,14 +205,14 @@ static int isVariantApplicableInContextHelper(
continue;
bool IsActiveTrait = Ctx.ActiveTraits.test(unsigned(Property));
-
- // We overwrite the isa trait as it is actually up to the OMPContext hook to
- // check the raw string(s).
- if (Property == TraitProperty::device_isa___ANY)
- IsActiveTrait = llvm::all_of(VMI.ISATraits, [&](StringRef RawString) {
- return Ctx.matchesISATrait(RawString);
- });
-
+
+ // We overwrite the isa trait as it is actually up to the OMPContext hook to
+ // check the raw string(s).
+ if (Property == TraitProperty::device_isa___ANY)
+ IsActiveTrait = llvm::all_of(VMI.ISATraits, [&](StringRef RawString) {
+ return Ctx.matchesISATrait(RawString);
+ });
+
Optional<bool> Result = HandleTrait(Property, IsActiveTrait);
if (Result.hasValue())
return Result.getValue();
@@ -240,7 +240,7 @@ static int isVariantApplicableInContextHelper(
if (!FoundInOrder) {
LLVM_DEBUG(dbgs() << "[" << DEBUG_TYPE << "] Construct property "
- << getOpenMPContextTraitPropertyName(Property, "")
+ << getOpenMPContextTraitPropertyName(Property, "")
<< " was not nested properly.\n");
return false;
}
@@ -440,12 +440,12 @@ StringRef llvm::omp::getOpenMPContextTraitSelectorName(TraitSelector Kind) {
llvm_unreachable("Unknown trait selector!");
}
-TraitProperty llvm::omp::getOpenMPContextTraitPropertyKind(
- TraitSet Set, TraitSelector Selector, StringRef S) {
- // Special handling for `device={isa(...)}` as we accept anything here. It is
- // up to the target to decide if the feature is available.
- if (Set == TraitSet::device && Selector == TraitSelector::device_isa)
- return TraitProperty::device_isa___ANY;
+TraitProperty llvm::omp::getOpenMPContextTraitPropertyKind(
+ TraitSet Set, TraitSelector Selector, StringRef S) {
+ // Special handling for `device={isa(...)}` as we accept anything here. It is
+ // up to the target to decide if the feature is available.
+ if (Set == TraitSet::device && Selector == TraitSelector::device_isa)
+ return TraitProperty::device_isa___ANY;
#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
if (Set == TraitSet::TraitSetEnum && Str == S) \
return TraitProperty::Enum;
@@ -463,10 +463,10 @@ llvm::omp::getOpenMPContextTraitPropertyForSelector(TraitSelector Selector) {
#include "llvm/Frontend/OpenMP/OMPKinds.def"
.Default(TraitProperty::invalid);
}
-StringRef llvm::omp::getOpenMPContextTraitPropertyName(TraitProperty Kind,
- StringRef RawString) {
- if (Kind == TraitProperty::device_isa___ANY)
- return RawString;
+StringRef llvm::omp::getOpenMPContextTraitPropertyName(TraitProperty Kind,
+ StringRef RawString) {
+ if (Kind == TraitProperty::device_isa___ANY)
+ return RawString;
switch (Kind) {
#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
case TraitProperty::Enum: \
diff --git a/contrib/libs/llvm12/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/contrib/libs/llvm12/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index 4efe06f0f7..1f67aecb57 100644
--- a/contrib/libs/llvm12/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/contrib/libs/llvm12/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -15,7 +15,7 @@
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/IRBuilder.h"
@@ -126,7 +126,7 @@ Function *OpenMPIRBuilder::getOrCreateRuntimeFunctionPtr(RuntimeFunction FnID) {
void OpenMPIRBuilder::initialize() { initializeTypes(M); }
-void OpenMPIRBuilder::finalize(bool AllowExtractorSinking) {
+void OpenMPIRBuilder::finalize(bool AllowExtractorSinking) {
SmallPtrSet<BasicBlock *, 32> ParallelRegionBlockSet;
SmallVector<BasicBlock *, 32> Blocks;
for (OutlineInfo &OI : OutlineInfos) {
@@ -169,25 +169,25 @@ void OpenMPIRBuilder::finalize(bool AllowExtractorSinking) {
BasicBlock &ArtificialEntry = OutlinedFn->getEntryBlock();
assert(ArtificialEntry.getUniqueSuccessor() == OI.EntryBB);
assert(OI.EntryBB->getUniquePredecessor() == &ArtificialEntry);
- if (AllowExtractorSinking) {
- // Move instructions from the to-be-deleted ArtificialEntry to the entry
- // basic block of the parallel region. CodeExtractor may have sunk
- // allocas/bitcasts for values that are solely used in the outlined
- // region and do not escape.
- assert(!ArtificialEntry.empty() &&
- "Expected instructions to sink in the outlined region");
- for (BasicBlock::iterator It = ArtificialEntry.begin(),
- End = ArtificialEntry.end();
- It != End;) {
- Instruction &I = *It;
- It++;
-
- if (I.isTerminator())
- continue;
-
- I.moveBefore(*OI.EntryBB, OI.EntryBB->getFirstInsertionPt());
- }
- }
+ if (AllowExtractorSinking) {
+ // Move instructions from the to-be-deleted ArtificialEntry to the entry
+ // basic block of the parallel region. CodeExtractor may have sunk
+ // allocas/bitcasts for values that are solely used in the outlined
+ // region and do not escape.
+ assert(!ArtificialEntry.empty() &&
+ "Expected instructions to sink in the outlined region");
+ for (BasicBlock::iterator It = ArtificialEntry.begin(),
+ End = ArtificialEntry.end();
+ It != End;) {
+ Instruction &I = *It;
+ It++;
+
+ if (I.isTerminator())
+ continue;
+
+ I.moveBefore(*OI.EntryBB, OI.EntryBB->getFirstInsertionPt());
+ }
+ }
OI.EntryBB->moveBefore(&ArtificialEntry);
ArtificialEntry.eraseFromParent();
}
@@ -233,17 +233,17 @@ Value *OpenMPIRBuilder::getOrCreateIdent(Constant *SrcLocStr,
GV->setAlignment(Align(8));
Ident = GV;
}
- return Builder.CreatePointerCast(Ident, IdentPtr);
+ return Builder.CreatePointerCast(Ident, IdentPtr);
+}
+
+Type *OpenMPIRBuilder::getLanemaskType() {
+ LLVMContext &Ctx = M.getContext();
+ Triple triple(M.getTargetTriple());
+
+ // This test is adequate until deviceRTL has finer grained lane widths
+ return triple.isAMDGCN() ? Type::getInt64Ty(Ctx) : Type::getInt32Ty(Ctx);
}
-Type *OpenMPIRBuilder::getLanemaskType() {
- LLVMContext &Ctx = M.getContext();
- Triple triple(M.getTargetTriple());
-
- // This test is adequate until deviceRTL has finer grained lane widths
- return triple.isAMDGCN() ? Type::getInt64Ty(Ctx) : Type::getInt32Ty(Ctx);
-}
-
Constant *OpenMPIRBuilder::getOrCreateSrcLocStr(StringRef LocStr) {
Constant *&SrcLocStr = SrcLocStrMap[LocStr];
if (!SrcLocStr) {
@@ -290,10 +290,10 @@ OpenMPIRBuilder::getOrCreateSrcLocStr(const LocationDescription &Loc) {
DILocation *DIL = Loc.DL.get();
if (!DIL)
return getOrCreateDefaultSrcLocStr();
- StringRef FileName = M.getName();
- if (DIFile *DIF = DIL->getFile())
- if (Optional<StringRef> Source = DIF->getSource())
- FileName = *Source;
+ StringRef FileName = M.getName();
+ if (DIFile *DIF = DIL->getFile())
+ if (Optional<StringRef> Source = DIF->getSource())
+ FileName = *Source;
StringRef Function = DIL->getScope()->getSubprogram()->getName();
Function =
!Function.empty() ? Function : Loc.IP.getBlock()->getParent()->getName();
@@ -308,7 +308,7 @@ Value *OpenMPIRBuilder::getOrCreateThreadID(Value *Ident) {
}
OpenMPIRBuilder::InsertPointTy
-OpenMPIRBuilder::createBarrier(const LocationDescription &Loc, Directive DK,
+OpenMPIRBuilder::createBarrier(const LocationDescription &Loc, Directive DK,
bool ForceSimpleCall, bool CheckCancelFlag) {
if (!updateToLocation(Loc))
return Loc.IP;
@@ -363,7 +363,7 @@ OpenMPIRBuilder::emitBarrierImpl(const LocationDescription &Loc, Directive Kind,
}
OpenMPIRBuilder::InsertPointTy
-OpenMPIRBuilder::createCancel(const LocationDescription &Loc,
+OpenMPIRBuilder::createCancel(const LocationDescription &Loc,
Value *IfCondition,
omp::Directive CanceledDirective) {
if (!updateToLocation(Loc))
@@ -440,11 +440,11 @@ void OpenMPIRBuilder::emitCancelationCheckImpl(
Builder.SetInsertPoint(NonCancellationBlock, NonCancellationBlock->begin());
}
-IRBuilder<>::InsertPoint OpenMPIRBuilder::createParallel(
- const LocationDescription &Loc, InsertPointTy OuterAllocaIP,
- BodyGenCallbackTy BodyGenCB, PrivatizeCallbackTy PrivCB,
- FinalizeCallbackTy FiniCB, Value *IfCondition, Value *NumThreads,
- omp::ProcBindKind ProcBind, bool IsCancellable) {
+IRBuilder<>::InsertPoint OpenMPIRBuilder::createParallel(
+ const LocationDescription &Loc, InsertPointTy OuterAllocaIP,
+ BodyGenCallbackTy BodyGenCB, PrivatizeCallbackTy PrivCB,
+ FinalizeCallbackTy FiniCB, Value *IfCondition, Value *NumThreads,
+ omp::ProcBindKind ProcBind, bool IsCancellable) {
if (!updateToLocation(Loc))
return Loc.IP;
@@ -473,17 +473,17 @@ IRBuilder<>::InsertPoint OpenMPIRBuilder::createParallel(
BasicBlock *InsertBB = Builder.GetInsertBlock();
Function *OuterFn = InsertBB->getParent();
- // Save the outer alloca block because the insertion iterator may get
- // invalidated and we still need this later.
- BasicBlock *OuterAllocaBlock = OuterAllocaIP.getBlock();
-
+ // Save the outer alloca block because the insertion iterator may get
+ // invalidated and we still need this later.
+ BasicBlock *OuterAllocaBlock = OuterAllocaIP.getBlock();
+
// Vector to remember instructions we used only during the modeling but which
// we want to delete at the end.
SmallVector<Instruction *, 4> ToBeDeleted;
- // Change the location to the outer alloca insertion point to create and
- // initialize the allocas we pass into the parallel region.
- Builder.restoreIP(OuterAllocaIP);
+ // Change the location to the outer alloca insertion point to create and
+ // initialize the allocas we pass into the parallel region.
+ Builder.restoreIP(OuterAllocaIP);
AllocaInst *TIDAddr = Builder.CreateAlloca(Int32, nullptr, "tid.addr");
AllocaInst *ZeroAddr = Builder.CreateAlloca(Int32, nullptr, "zero.addr");
@@ -535,17 +535,17 @@ IRBuilder<>::InsertPoint OpenMPIRBuilder::createParallel(
// Generate the privatization allocas in the block that will become the entry
// of the outlined function.
- Builder.SetInsertPoint(PRegEntryBB->getTerminator());
- InsertPointTy InnerAllocaIP = Builder.saveIP();
-
+ Builder.SetInsertPoint(PRegEntryBB->getTerminator());
+ InsertPointTy InnerAllocaIP = Builder.saveIP();
+
AllocaInst *PrivTIDAddr =
Builder.CreateAlloca(Int32, nullptr, "tid.addr.local");
Instruction *PrivTID = Builder.CreateLoad(PrivTIDAddr, "tid");
// Add some fake uses for OpenMP provided arguments.
ToBeDeleted.push_back(Builder.CreateLoad(TIDAddr, "tid.addr.use"));
- Instruction *ZeroAddrUse = Builder.CreateLoad(ZeroAddr, "zero.addr.use");
- ToBeDeleted.push_back(ZeroAddrUse);
+ Instruction *ZeroAddrUse = Builder.CreateLoad(ZeroAddr, "zero.addr.use");
+ ToBeDeleted.push_back(ZeroAddrUse);
// ThenBB
// |
@@ -567,7 +567,7 @@ IRBuilder<>::InsertPoint OpenMPIRBuilder::createParallel(
// Let the caller create the body.
assert(BodyGenCB && "Expected body generation callback!");
InsertPointTy CodeGenIP(PRegBodyBB, PRegBodyBB->begin());
- BodyGenCB(InnerAllocaIP, CodeGenIP, *PRegPreFiniBB);
+ BodyGenCB(InnerAllocaIP, CodeGenIP, *PRegPreFiniBB);
LLVM_DEBUG(dbgs() << "After body codegen: " << *OuterFn << "\n");
@@ -714,45 +714,45 @@ IRBuilder<>::InsertPoint OpenMPIRBuilder::createParallel(
if (&V == TIDAddr || &V == ZeroAddr)
return;
- SetVector<Use *> Uses;
+ SetVector<Use *> Uses;
for (Use &U : V.uses())
if (auto *UserI = dyn_cast<Instruction>(U.getUser()))
if (ParallelRegionBlockSet.count(UserI->getParent()))
- Uses.insert(&U);
-
- // __kmpc_fork_call expects extra arguments as pointers. If the input
- // already has a pointer type, everything is fine. Otherwise, store the
- // value onto stack and load it back inside the to-be-outlined region. This
- // will ensure only the pointer will be passed to the function.
- // FIXME: if there are more than 15 trailing arguments, they must be
- // additionally packed in a struct.
- Value *Inner = &V;
- if (!V.getType()->isPointerTy()) {
- IRBuilder<>::InsertPointGuard Guard(Builder);
- LLVM_DEBUG(llvm::dbgs() << "Forwarding input as pointer: " << V << "\n");
-
- Builder.restoreIP(OuterAllocaIP);
- Value *Ptr =
- Builder.CreateAlloca(V.getType(), nullptr, V.getName() + ".reloaded");
-
- // Store to stack at end of the block that currently branches to the entry
- // block of the to-be-outlined region.
- Builder.SetInsertPoint(InsertBB,
- InsertBB->getTerminator()->getIterator());
- Builder.CreateStore(&V, Ptr);
-
- // Load back next to allocations in the to-be-outlined region.
- Builder.restoreIP(InnerAllocaIP);
- Inner = Builder.CreateLoad(Ptr);
- }
-
+ Uses.insert(&U);
+
+ // __kmpc_fork_call expects extra arguments as pointers. If the input
+ // already has a pointer type, everything is fine. Otherwise, store the
+ // value onto stack and load it back inside the to-be-outlined region. This
+ // will ensure only the pointer will be passed to the function.
+ // FIXME: if there are more than 15 trailing arguments, they must be
+ // additionally packed in a struct.
+ Value *Inner = &V;
+ if (!V.getType()->isPointerTy()) {
+ IRBuilder<>::InsertPointGuard Guard(Builder);
+ LLVM_DEBUG(llvm::dbgs() << "Forwarding input as pointer: " << V << "\n");
+
+ Builder.restoreIP(OuterAllocaIP);
+ Value *Ptr =
+ Builder.CreateAlloca(V.getType(), nullptr, V.getName() + ".reloaded");
+
+ // Store to stack at end of the block that currently branches to the entry
+ // block of the to-be-outlined region.
+ Builder.SetInsertPoint(InsertBB,
+ InsertBB->getTerminator()->getIterator());
+ Builder.CreateStore(&V, Ptr);
+
+ // Load back next to allocations in the to-be-outlined region.
+ Builder.restoreIP(InnerAllocaIP);
+ Inner = Builder.CreateLoad(Ptr);
+ }
+
Value *ReplacementValue = nullptr;
CallInst *CI = dyn_cast<CallInst>(&V);
if (CI && CI->getCalledFunction() == TIDRTLFn.getCallee()) {
ReplacementValue = PrivTID;
} else {
Builder.restoreIP(
- PrivCB(InnerAllocaIP, Builder.saveIP(), V, *Inner, ReplacementValue));
+ PrivCB(InnerAllocaIP, Builder.saveIP(), V, *Inner, ReplacementValue));
assert(ReplacementValue &&
"Expected copy/create callback to set replacement value!");
if (ReplacementValue == &V)
@@ -763,28 +763,28 @@ IRBuilder<>::InsertPoint OpenMPIRBuilder::createParallel(
UPtr->set(ReplacementValue);
};
- // Reset the inner alloca insertion as it will be used for loading the values
- // wrapped into pointers before passing them into the to-be-outlined region.
- // Configure it to insert immediately after the fake use of zero address so
- // that they are available in the generated body and so that the
- // OpenMP-related values (thread ID and zero address pointers) remain leading
- // in the argument list.
- InnerAllocaIP = IRBuilder<>::InsertPoint(
- ZeroAddrUse->getParent(), ZeroAddrUse->getNextNode()->getIterator());
-
- // Reset the outer alloca insertion point to the entry of the relevant block
- // in case it was invalidated.
- OuterAllocaIP = IRBuilder<>::InsertPoint(
- OuterAllocaBlock, OuterAllocaBlock->getFirstInsertionPt());
-
+ // Reset the inner alloca insertion as it will be used for loading the values
+ // wrapped into pointers before passing them into the to-be-outlined region.
+ // Configure it to insert immediately after the fake use of zero address so
+ // that they are available in the generated body and so that the
+ // OpenMP-related values (thread ID and zero address pointers) remain leading
+ // in the argument list.
+ InnerAllocaIP = IRBuilder<>::InsertPoint(
+ ZeroAddrUse->getParent(), ZeroAddrUse->getNextNode()->getIterator());
+
+ // Reset the outer alloca insertion point to the entry of the relevant block
+ // in case it was invalidated.
+ OuterAllocaIP = IRBuilder<>::InsertPoint(
+ OuterAllocaBlock, OuterAllocaBlock->getFirstInsertionPt());
+
for (Value *Input : Inputs) {
LLVM_DEBUG(dbgs() << "Captured input: " << *Input << "\n");
PrivHelper(*Input);
}
- LLVM_DEBUG({
- for (Value *Output : Outputs)
- LLVM_DEBUG(dbgs() << "Captured output: " << *Output << "\n");
- });
+ LLVM_DEBUG({
+ for (Value *Output : Outputs)
+ LLVM_DEBUG(dbgs() << "Captured output: " << *Output << "\n");
+ });
assert(Outputs.empty() &&
"OpenMP outlining should not produce live-out values!");
@@ -811,7 +811,7 @@ void OpenMPIRBuilder::emitFlush(const LocationDescription &Loc) {
Builder.CreateCall(getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_flush), Args);
}
-void OpenMPIRBuilder::createFlush(const LocationDescription &Loc) {
+void OpenMPIRBuilder::createFlush(const LocationDescription &Loc) {
if (!updateToLocation(Loc))
return;
emitFlush(Loc);
@@ -829,7 +829,7 @@ void OpenMPIRBuilder::emitTaskwaitImpl(const LocationDescription &Loc) {
Args);
}
-void OpenMPIRBuilder::createTaskwait(const LocationDescription &Loc) {
+void OpenMPIRBuilder::createTaskwait(const LocationDescription &Loc) {
if (!updateToLocation(Loc))
return;
emitTaskwaitImpl(Loc);
@@ -846,14 +846,14 @@ void OpenMPIRBuilder::emitTaskyieldImpl(const LocationDescription &Loc) {
Args);
}
-void OpenMPIRBuilder::createTaskyield(const LocationDescription &Loc) {
+void OpenMPIRBuilder::createTaskyield(const LocationDescription &Loc) {
if (!updateToLocation(Loc))
return;
emitTaskyieldImpl(Loc);
}
OpenMPIRBuilder::InsertPointTy
-OpenMPIRBuilder::createMaster(const LocationDescription &Loc,
+OpenMPIRBuilder::createMaster(const LocationDescription &Loc,
BodyGenCallbackTy BodyGenCB,
FinalizeCallbackTy FiniCB) {
@@ -876,597 +876,597 @@ OpenMPIRBuilder::createMaster(const LocationDescription &Loc,
/*Conditional*/ true, /*hasFinalize*/ true);
}
-CanonicalLoopInfo *OpenMPIRBuilder::createLoopSkeleton(
- DebugLoc DL, Value *TripCount, Function *F, BasicBlock *PreInsertBefore,
- BasicBlock *PostInsertBefore, const Twine &Name) {
- Module *M = F->getParent();
- LLVMContext &Ctx = M->getContext();
- Type *IndVarTy = TripCount->getType();
-
- // Create the basic block structure.
- BasicBlock *Preheader =
- BasicBlock::Create(Ctx, "omp_" + Name + ".preheader", F, PreInsertBefore);
- BasicBlock *Header =
- BasicBlock::Create(Ctx, "omp_" + Name + ".header", F, PreInsertBefore);
- BasicBlock *Cond =
- BasicBlock::Create(Ctx, "omp_" + Name + ".cond", F, PreInsertBefore);
- BasicBlock *Body =
- BasicBlock::Create(Ctx, "omp_" + Name + ".body", F, PreInsertBefore);
- BasicBlock *Latch =
- BasicBlock::Create(Ctx, "omp_" + Name + ".inc", F, PostInsertBefore);
- BasicBlock *Exit =
- BasicBlock::Create(Ctx, "omp_" + Name + ".exit", F, PostInsertBefore);
- BasicBlock *After =
- BasicBlock::Create(Ctx, "omp_" + Name + ".after", F, PostInsertBefore);
-
- // Use specified DebugLoc for new instructions.
- Builder.SetCurrentDebugLocation(DL);
-
- Builder.SetInsertPoint(Preheader);
- Builder.CreateBr(Header);
-
- Builder.SetInsertPoint(Header);
- PHINode *IndVarPHI = Builder.CreatePHI(IndVarTy, 2, "omp_" + Name + ".iv");
- IndVarPHI->addIncoming(ConstantInt::get(IndVarTy, 0), Preheader);
- Builder.CreateBr(Cond);
-
- Builder.SetInsertPoint(Cond);
- Value *Cmp =
- Builder.CreateICmpULT(IndVarPHI, TripCount, "omp_" + Name + ".cmp");
- Builder.CreateCondBr(Cmp, Body, Exit);
-
- Builder.SetInsertPoint(Body);
- Builder.CreateBr(Latch);
-
- Builder.SetInsertPoint(Latch);
- Value *Next = Builder.CreateAdd(IndVarPHI, ConstantInt::get(IndVarTy, 1),
- "omp_" + Name + ".next", /*HasNUW=*/true);
- Builder.CreateBr(Header);
- IndVarPHI->addIncoming(Next, Latch);
-
- Builder.SetInsertPoint(Exit);
- Builder.CreateBr(After);
-
- // Remember and return the canonical control flow.
- LoopInfos.emplace_front();
- CanonicalLoopInfo *CL = &LoopInfos.front();
-
- CL->Preheader = Preheader;
- CL->Header = Header;
- CL->Cond = Cond;
- CL->Body = Body;
- CL->Latch = Latch;
- CL->Exit = Exit;
- CL->After = After;
-
- CL->IsValid = true;
-
-#ifndef NDEBUG
- CL->assertOK();
-#endif
- return CL;
-}
-
-CanonicalLoopInfo *
-OpenMPIRBuilder::createCanonicalLoop(const LocationDescription &Loc,
- LoopBodyGenCallbackTy BodyGenCB,
- Value *TripCount, const Twine &Name) {
- BasicBlock *BB = Loc.IP.getBlock();
- BasicBlock *NextBB = BB->getNextNode();
-
- CanonicalLoopInfo *CL = createLoopSkeleton(Loc.DL, TripCount, BB->getParent(),
- NextBB, NextBB, Name);
- BasicBlock *After = CL->getAfter();
-
- // If location is not set, don't connect the loop.
- if (updateToLocation(Loc)) {
- // Split the loop at the insertion point: Branch to the preheader and move
- // every following instruction to after the loop (the After BB). Also, the
- // new successor is the loop's after block.
- Builder.CreateBr(CL->Preheader);
- After->getInstList().splice(After->begin(), BB->getInstList(),
- Builder.GetInsertPoint(), BB->end());
- After->replaceSuccessorsPhiUsesWith(BB, After);
- }
-
- // Emit the body content. We do it after connecting the loop to the CFG to
- // avoid that the callback encounters degenerate BBs.
- BodyGenCB(CL->getBodyIP(), CL->getIndVar());
-
-#ifndef NDEBUG
- CL->assertOK();
-#endif
- return CL;
-}
-
-CanonicalLoopInfo *OpenMPIRBuilder::createCanonicalLoop(
- const LocationDescription &Loc, LoopBodyGenCallbackTy BodyGenCB,
- Value *Start, Value *Stop, Value *Step, bool IsSigned, bool InclusiveStop,
- InsertPointTy ComputeIP, const Twine &Name) {
-
- // Consider the following difficulties (assuming 8-bit signed integers):
- // * Adding \p Step to the loop counter which passes \p Stop may overflow:
- // DO I = 1, 100, 50
- /// * A \p Step of INT_MIN cannot not be normalized to a positive direction:
- // DO I = 100, 0, -128
-
- // Start, Stop and Step must be of the same integer type.
- auto *IndVarTy = cast<IntegerType>(Start->getType());
- assert(IndVarTy == Stop->getType() && "Stop type mismatch");
- assert(IndVarTy == Step->getType() && "Step type mismatch");
-
- LocationDescription ComputeLoc =
- ComputeIP.isSet() ? LocationDescription(ComputeIP, Loc.DL) : Loc;
- updateToLocation(ComputeLoc);
-
- ConstantInt *Zero = ConstantInt::get(IndVarTy, 0);
- ConstantInt *One = ConstantInt::get(IndVarTy, 1);
-
- // Like Step, but always positive.
- Value *Incr = Step;
-
- // Distance between Start and Stop; always positive.
- Value *Span;
-
- // Condition whether there are no iterations are executed at all, e.g. because
- // UB < LB.
- Value *ZeroCmp;
-
- if (IsSigned) {
- // Ensure that increment is positive. If not, negate and invert LB and UB.
- Value *IsNeg = Builder.CreateICmpSLT(Step, Zero);
- Incr = Builder.CreateSelect(IsNeg, Builder.CreateNeg(Step), Step);
- Value *LB = Builder.CreateSelect(IsNeg, Stop, Start);
- Value *UB = Builder.CreateSelect(IsNeg, Start, Stop);
- Span = Builder.CreateSub(UB, LB, "", false, true);
- ZeroCmp = Builder.CreateICmp(
- InclusiveStop ? CmpInst::ICMP_SLT : CmpInst::ICMP_SLE, UB, LB);
- } else {
- Span = Builder.CreateSub(Stop, Start, "", true);
- ZeroCmp = Builder.CreateICmp(
- InclusiveStop ? CmpInst::ICMP_ULT : CmpInst::ICMP_ULE, Stop, Start);
- }
-
- Value *CountIfLooping;
- if (InclusiveStop) {
- CountIfLooping = Builder.CreateAdd(Builder.CreateUDiv(Span, Incr), One);
- } else {
- // Avoid incrementing past stop since it could overflow.
- Value *CountIfTwo = Builder.CreateAdd(
- Builder.CreateUDiv(Builder.CreateSub(Span, One), Incr), One);
- Value *OneCmp = Builder.CreateICmp(
- InclusiveStop ? CmpInst::ICMP_ULT : CmpInst::ICMP_ULE, Span, Incr);
- CountIfLooping = Builder.CreateSelect(OneCmp, One, CountIfTwo);
- }
- Value *TripCount = Builder.CreateSelect(ZeroCmp, Zero, CountIfLooping,
- "omp_" + Name + ".tripcount");
-
- auto BodyGen = [=](InsertPointTy CodeGenIP, Value *IV) {
- Builder.restoreIP(CodeGenIP);
- Value *Span = Builder.CreateMul(IV, Step);
- Value *IndVar = Builder.CreateAdd(Span, Start);
- BodyGenCB(Builder.saveIP(), IndVar);
- };
- LocationDescription LoopLoc = ComputeIP.isSet() ? Loc.IP : Builder.saveIP();
- return createCanonicalLoop(LoopLoc, BodyGen, TripCount, Name);
-}
-
-// Returns an LLVM function to call for initializing loop bounds using OpenMP
-// static scheduling depending on `type`. Only i32 and i64 are supported by the
-// runtime. Always interpret integers as unsigned similarly to
-// CanonicalLoopInfo.
-static FunctionCallee getKmpcForStaticInitForType(Type *Ty, Module &M,
- OpenMPIRBuilder &OMPBuilder) {
- unsigned Bitwidth = Ty->getIntegerBitWidth();
- if (Bitwidth == 32)
- return OMPBuilder.getOrCreateRuntimeFunction(
- M, omp::RuntimeFunction::OMPRTL___kmpc_for_static_init_4u);
- if (Bitwidth == 64)
- return OMPBuilder.getOrCreateRuntimeFunction(
- M, omp::RuntimeFunction::OMPRTL___kmpc_for_static_init_8u);
- llvm_unreachable("unknown OpenMP loop iterator bitwidth");
-}
-
-// Sets the number of loop iterations to the given value. This value must be
-// valid in the condition block (i.e., defined in the preheader) and is
-// interpreted as an unsigned integer.
-void setCanonicalLoopTripCount(CanonicalLoopInfo *CLI, Value *TripCount) {
- Instruction *CmpI = &CLI->getCond()->front();
- assert(isa<CmpInst>(CmpI) && "First inst must compare IV with TripCount");
- CmpI->setOperand(1, TripCount);
- CLI->assertOK();
-}
-
-CanonicalLoopInfo *OpenMPIRBuilder::createStaticWorkshareLoop(
- const LocationDescription &Loc, CanonicalLoopInfo *CLI,
- InsertPointTy AllocaIP, bool NeedsBarrier, Value *Chunk) {
- // Set up the source location value for OpenMP runtime.
- if (!updateToLocation(Loc))
- return nullptr;
-
- Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
- Value *SrcLoc = getOrCreateIdent(SrcLocStr);
-
- // Declare useful OpenMP runtime functions.
- Value *IV = CLI->getIndVar();
- Type *IVTy = IV->getType();
- FunctionCallee StaticInit = getKmpcForStaticInitForType(IVTy, M, *this);
- FunctionCallee StaticFini =
- getOrCreateRuntimeFunction(M, omp::OMPRTL___kmpc_for_static_fini);
-
- // Allocate space for computed loop bounds as expected by the "init" function.
- Builder.restoreIP(AllocaIP);
- Type *I32Type = Type::getInt32Ty(M.getContext());
- Value *PLastIter = Builder.CreateAlloca(I32Type, nullptr, "p.lastiter");
- Value *PLowerBound = Builder.CreateAlloca(IVTy, nullptr, "p.lowerbound");
- Value *PUpperBound = Builder.CreateAlloca(IVTy, nullptr, "p.upperbound");
- Value *PStride = Builder.CreateAlloca(IVTy, nullptr, "p.stride");
-
- // At the end of the preheader, prepare for calling the "init" function by
- // storing the current loop bounds into the allocated space. A canonical loop
- // always iterates from 0 to trip-count with step 1. Note that "init" expects
- // and produces an inclusive upper bound.
- Builder.SetInsertPoint(CLI->getPreheader()->getTerminator());
- Constant *Zero = ConstantInt::get(IVTy, 0);
- Constant *One = ConstantInt::get(IVTy, 1);
- Builder.CreateStore(Zero, PLowerBound);
- Value *UpperBound = Builder.CreateSub(CLI->getTripCount(), One);
- Builder.CreateStore(UpperBound, PUpperBound);
- Builder.CreateStore(One, PStride);
-
- if (!Chunk)
- Chunk = One;
-
- Value *ThreadNum = getOrCreateThreadID(SrcLoc);
-
- // TODO: extract scheduling type and map it to OMP constant. This is curently
- // happening in kmp.h and its ilk and needs to be moved to OpenMP.td first.
- constexpr int StaticSchedType = 34;
- Constant *SchedulingType = ConstantInt::get(I32Type, StaticSchedType);
-
- // Call the "init" function and update the trip count of the loop with the
- // value it produced.
- Builder.CreateCall(StaticInit,
- {SrcLoc, ThreadNum, SchedulingType, PLastIter, PLowerBound,
- PUpperBound, PStride, One, Chunk});
- Value *LowerBound = Builder.CreateLoad(PLowerBound);
- Value *InclusiveUpperBound = Builder.CreateLoad(PUpperBound);
- Value *TripCountMinusOne = Builder.CreateSub(InclusiveUpperBound, LowerBound);
- Value *TripCount = Builder.CreateAdd(TripCountMinusOne, One);
- setCanonicalLoopTripCount(CLI, TripCount);
-
- // Update all uses of the induction variable except the one in the condition
- // block that compares it with the actual upper bound, and the increment in
- // the latch block.
- // TODO: this can eventually move to CanonicalLoopInfo or to a new
- // CanonicalLoopInfoUpdater interface.
- Builder.SetInsertPoint(CLI->getBody(), CLI->getBody()->getFirstInsertionPt());
- Value *UpdatedIV = Builder.CreateAdd(IV, LowerBound);
- IV->replaceUsesWithIf(UpdatedIV, [&](Use &U) {
- auto *Instr = dyn_cast<Instruction>(U.getUser());
- return !Instr ||
- (Instr->getParent() != CLI->getCond() &&
- Instr->getParent() != CLI->getLatch() && Instr != UpdatedIV);
- });
-
- // In the "exit" block, call the "fini" function.
- Builder.SetInsertPoint(CLI->getExit(),
- CLI->getExit()->getTerminator()->getIterator());
- Builder.CreateCall(StaticFini, {SrcLoc, ThreadNum});
-
- // Add the barrier if requested.
- if (NeedsBarrier)
- createBarrier(LocationDescription(Builder.saveIP(), Loc.DL),
- omp::Directive::OMPD_for, /* ForceSimpleCall */ false,
- /* CheckCancelFlag */ false);
-
- CLI->assertOK();
- return CLI;
-}
-
-/// Make \p Source branch to \p Target.
-///
-/// Handles two situations:
-/// * \p Source already has an unconditional branch.
-/// * \p Source is a degenerate block (no terminator because the BB is
-/// the current head of the IR construction).
-static void redirectTo(BasicBlock *Source, BasicBlock *Target, DebugLoc DL) {
- if (Instruction *Term = Source->getTerminator()) {
- auto *Br = cast<BranchInst>(Term);
- assert(!Br->isConditional() &&
- "BB's terminator must be an unconditional branch (or degenerate)");
- BasicBlock *Succ = Br->getSuccessor(0);
- Succ->removePredecessor(Source, /*KeepOneInputPHIs=*/true);
- Br->setSuccessor(0, Target);
- return;
- }
-
- auto *NewBr = BranchInst::Create(Target, Source);
- NewBr->setDebugLoc(DL);
-}
-
-/// Redirect all edges that branch to \p OldTarget to \p NewTarget. That is,
-/// after this \p OldTarget will be orphaned.
-static void redirectAllPredecessorsTo(BasicBlock *OldTarget,
- BasicBlock *NewTarget, DebugLoc DL) {
- for (BasicBlock *Pred : make_early_inc_range(predecessors(OldTarget)))
- redirectTo(Pred, NewTarget, DL);
-}
-
-/// Determine which blocks in \p BBs are reachable from outside and remove the
-/// ones that are not reachable from the function.
-static void removeUnusedBlocksFromParent(ArrayRef<BasicBlock *> BBs) {
- SmallPtrSet<BasicBlock *, 6> BBsToErase{BBs.begin(), BBs.end()};
- auto HasRemainingUses = [&BBsToErase](BasicBlock *BB) {
- for (Use &U : BB->uses()) {
- auto *UseInst = dyn_cast<Instruction>(U.getUser());
- if (!UseInst)
- continue;
- if (BBsToErase.count(UseInst->getParent()))
- continue;
- return true;
- }
- return false;
- };
-
- while (true) {
- bool Changed = false;
- for (BasicBlock *BB : make_early_inc_range(BBsToErase)) {
- if (HasRemainingUses(BB)) {
- BBsToErase.erase(BB);
- Changed = true;
- }
- }
- if (!Changed)
- break;
- }
-
- SmallVector<BasicBlock *, 7> BBVec(BBsToErase.begin(), BBsToErase.end());
- DeleteDeadBlocks(BBVec);
-}
-
-std::vector<CanonicalLoopInfo *>
-OpenMPIRBuilder::tileLoops(DebugLoc DL, ArrayRef<CanonicalLoopInfo *> Loops,
- ArrayRef<Value *> TileSizes) {
- assert(TileSizes.size() == Loops.size() &&
- "Must pass as many tile sizes as there are loops");
- int NumLoops = Loops.size();
- assert(NumLoops >= 1 && "At least one loop to tile required");
-
- CanonicalLoopInfo *OutermostLoop = Loops.front();
- CanonicalLoopInfo *InnermostLoop = Loops.back();
- Function *F = OutermostLoop->getBody()->getParent();
- BasicBlock *InnerEnter = InnermostLoop->getBody();
- BasicBlock *InnerLatch = InnermostLoop->getLatch();
-
- // Collect original trip counts and induction variable to be accessible by
- // index. Also, the structure of the original loops is not preserved during
- // the construction of the tiled loops, so do it before we scavenge the BBs of
- // any original CanonicalLoopInfo.
- SmallVector<Value *, 4> OrigTripCounts, OrigIndVars;
- for (CanonicalLoopInfo *L : Loops) {
- OrigTripCounts.push_back(L->getTripCount());
- OrigIndVars.push_back(L->getIndVar());
- }
-
- // Collect the code between loop headers. These may contain SSA definitions
- // that are used in the loop nest body. To be usable with in the innermost
- // body, these BasicBlocks will be sunk into the loop nest body. That is,
- // these instructions may be executed more often than before the tiling.
- // TODO: It would be sufficient to only sink them into body of the
- // corresponding tile loop.
- SmallVector<std::pair<BasicBlock *, BasicBlock *>, 4> InbetweenCode;
- for (int i = 0; i < NumLoops - 1; ++i) {
- CanonicalLoopInfo *Surrounding = Loops[i];
- CanonicalLoopInfo *Nested = Loops[i + 1];
-
- BasicBlock *EnterBB = Surrounding->getBody();
- BasicBlock *ExitBB = Nested->getHeader();
- InbetweenCode.emplace_back(EnterBB, ExitBB);
- }
-
- // Compute the trip counts of the floor loops.
- Builder.SetCurrentDebugLocation(DL);
- Builder.restoreIP(OutermostLoop->getPreheaderIP());
- SmallVector<Value *, 4> FloorCount, FloorRems;
- for (int i = 0; i < NumLoops; ++i) {
- Value *TileSize = TileSizes[i];
- Value *OrigTripCount = OrigTripCounts[i];
- Type *IVType = OrigTripCount->getType();
-
- Value *FloorTripCount = Builder.CreateUDiv(OrigTripCount, TileSize);
- Value *FloorTripRem = Builder.CreateURem(OrigTripCount, TileSize);
-
- // 0 if tripcount divides the tilesize, 1 otherwise.
- // 1 means we need an additional iteration for a partial tile.
- //
- // Unfortunately we cannot just use the roundup-formula
- // (tripcount + tilesize - 1)/tilesize
- // because the summation might overflow. We do not want introduce undefined
- // behavior when the untiled loop nest did not.
- Value *FloorTripOverflow =
- Builder.CreateICmpNE(FloorTripRem, ConstantInt::get(IVType, 0));
-
- FloorTripOverflow = Builder.CreateZExt(FloorTripOverflow, IVType);
- FloorTripCount =
- Builder.CreateAdd(FloorTripCount, FloorTripOverflow,
- "omp_floor" + Twine(i) + ".tripcount", true);
-
- // Remember some values for later use.
- FloorCount.push_back(FloorTripCount);
- FloorRems.push_back(FloorTripRem);
- }
-
- // Generate the new loop nest, from the outermost to the innermost.
- std::vector<CanonicalLoopInfo *> Result;
- Result.reserve(NumLoops * 2);
-
- // The basic block of the surrounding loop that enters the nest generated
- // loop.
- BasicBlock *Enter = OutermostLoop->getPreheader();
-
- // The basic block of the surrounding loop where the inner code should
- // continue.
- BasicBlock *Continue = OutermostLoop->getAfter();
-
- // Where the next loop basic block should be inserted.
- BasicBlock *OutroInsertBefore = InnermostLoop->getExit();
-
- auto EmbeddNewLoop =
- [this, DL, F, InnerEnter, &Enter, &Continue, &OutroInsertBefore](
- Value *TripCount, const Twine &Name) -> CanonicalLoopInfo * {
- CanonicalLoopInfo *EmbeddedLoop = createLoopSkeleton(
- DL, TripCount, F, InnerEnter, OutroInsertBefore, Name);
- redirectTo(Enter, EmbeddedLoop->getPreheader(), DL);
- redirectTo(EmbeddedLoop->getAfter(), Continue, DL);
-
- // Setup the position where the next embedded loop connects to this loop.
- Enter = EmbeddedLoop->getBody();
- Continue = EmbeddedLoop->getLatch();
- OutroInsertBefore = EmbeddedLoop->getLatch();
- return EmbeddedLoop;
- };
-
- auto EmbeddNewLoops = [&Result, &EmbeddNewLoop](ArrayRef<Value *> TripCounts,
- const Twine &NameBase) {
- for (auto P : enumerate(TripCounts)) {
- CanonicalLoopInfo *EmbeddedLoop =
- EmbeddNewLoop(P.value(), NameBase + Twine(P.index()));
- Result.push_back(EmbeddedLoop);
- }
- };
-
- EmbeddNewLoops(FloorCount, "floor");
-
- // Within the innermost floor loop, emit the code that computes the tile
- // sizes.
- Builder.SetInsertPoint(Enter->getTerminator());
- SmallVector<Value *, 4> TileCounts;
- for (int i = 0; i < NumLoops; ++i) {
- CanonicalLoopInfo *FloorLoop = Result[i];
- Value *TileSize = TileSizes[i];
-
- Value *FloorIsEpilogue =
- Builder.CreateICmpEQ(FloorLoop->getIndVar(), FloorCount[i]);
- Value *TileTripCount =
- Builder.CreateSelect(FloorIsEpilogue, FloorRems[i], TileSize);
-
- TileCounts.push_back(TileTripCount);
- }
-
- // Create the tile loops.
- EmbeddNewLoops(TileCounts, "tile");
-
- // Insert the inbetween code into the body.
- BasicBlock *BodyEnter = Enter;
- BasicBlock *BodyEntered = nullptr;
- for (std::pair<BasicBlock *, BasicBlock *> P : InbetweenCode) {
- BasicBlock *EnterBB = P.first;
- BasicBlock *ExitBB = P.second;
-
- if (BodyEnter)
- redirectTo(BodyEnter, EnterBB, DL);
- else
- redirectAllPredecessorsTo(BodyEntered, EnterBB, DL);
-
- BodyEnter = nullptr;
- BodyEntered = ExitBB;
- }
-
- // Append the original loop nest body into the generated loop nest body.
- if (BodyEnter)
- redirectTo(BodyEnter, InnerEnter, DL);
- else
- redirectAllPredecessorsTo(BodyEntered, InnerEnter, DL);
- redirectAllPredecessorsTo(InnerLatch, Continue, DL);
-
- // Replace the original induction variable with an induction variable computed
- // from the tile and floor induction variables.
- Builder.restoreIP(Result.back()->getBodyIP());
- for (int i = 0; i < NumLoops; ++i) {
- CanonicalLoopInfo *FloorLoop = Result[i];
- CanonicalLoopInfo *TileLoop = Result[NumLoops + i];
- Value *OrigIndVar = OrigIndVars[i];
- Value *Size = TileSizes[i];
-
- Value *Scale =
- Builder.CreateMul(Size, FloorLoop->getIndVar(), {}, /*HasNUW=*/true);
- Value *Shift =
- Builder.CreateAdd(Scale, TileLoop->getIndVar(), {}, /*HasNUW=*/true);
- OrigIndVar->replaceAllUsesWith(Shift);
- }
-
- // Remove unused parts of the original loops.
- SmallVector<BasicBlock *, 12> OldControlBBs;
- OldControlBBs.reserve(6 * Loops.size());
- for (CanonicalLoopInfo *Loop : Loops)
- Loop->collectControlBlocks(OldControlBBs);
- removeUnusedBlocksFromParent(OldControlBBs);
-
-#ifndef NDEBUG
- for (CanonicalLoopInfo *GenL : Result)
- GenL->assertOK();
-#endif
- return Result;
-}
-
-OpenMPIRBuilder::InsertPointTy
-OpenMPIRBuilder::createCopyPrivate(const LocationDescription &Loc,
- llvm::Value *BufSize, llvm::Value *CpyBuf,
- llvm::Value *CpyFn, llvm::Value *DidIt) {
- if (!updateToLocation(Loc))
- return Loc.IP;
-
- Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
- Value *Ident = getOrCreateIdent(SrcLocStr);
- Value *ThreadId = getOrCreateThreadID(Ident);
-
- llvm::Value *DidItLD = Builder.CreateLoad(DidIt);
-
- Value *Args[] = {Ident, ThreadId, BufSize, CpyBuf, CpyFn, DidItLD};
-
- Function *Fn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_copyprivate);
- Builder.CreateCall(Fn, Args);
-
- return Builder.saveIP();
-}
-
-OpenMPIRBuilder::InsertPointTy
-OpenMPIRBuilder::createSingle(const LocationDescription &Loc,
- BodyGenCallbackTy BodyGenCB,
- FinalizeCallbackTy FiniCB, llvm::Value *DidIt) {
-
- if (!updateToLocation(Loc))
- return Loc.IP;
-
- // If needed (i.e. not null), initialize `DidIt` with 0
- if (DidIt) {
- Builder.CreateStore(Builder.getInt32(0), DidIt);
- }
-
- Directive OMPD = Directive::OMPD_single;
- Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
- Value *Ident = getOrCreateIdent(SrcLocStr);
- Value *ThreadId = getOrCreateThreadID(Ident);
- Value *Args[] = {Ident, ThreadId};
-
- Function *EntryRTLFn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_single);
- Instruction *EntryCall = Builder.CreateCall(EntryRTLFn, Args);
-
- Function *ExitRTLFn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_end_single);
- Instruction *ExitCall = Builder.CreateCall(ExitRTLFn, Args);
-
- // generates the following:
- // if (__kmpc_single()) {
- // .... single region ...
- // __kmpc_end_single
- // }
-
- return EmitOMPInlinedRegion(OMPD, EntryCall, ExitCall, BodyGenCB, FiniCB,
- /*Conditional*/ true, /*hasFinalize*/ true);
-}
-
-OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createCritical(
+CanonicalLoopInfo *OpenMPIRBuilder::createLoopSkeleton(
+ DebugLoc DL, Value *TripCount, Function *F, BasicBlock *PreInsertBefore,
+ BasicBlock *PostInsertBefore, const Twine &Name) {
+ Module *M = F->getParent();
+ LLVMContext &Ctx = M->getContext();
+ Type *IndVarTy = TripCount->getType();
+
+ // Create the basic block structure.
+ BasicBlock *Preheader =
+ BasicBlock::Create(Ctx, "omp_" + Name + ".preheader", F, PreInsertBefore);
+ BasicBlock *Header =
+ BasicBlock::Create(Ctx, "omp_" + Name + ".header", F, PreInsertBefore);
+ BasicBlock *Cond =
+ BasicBlock::Create(Ctx, "omp_" + Name + ".cond", F, PreInsertBefore);
+ BasicBlock *Body =
+ BasicBlock::Create(Ctx, "omp_" + Name + ".body", F, PreInsertBefore);
+ BasicBlock *Latch =
+ BasicBlock::Create(Ctx, "omp_" + Name + ".inc", F, PostInsertBefore);
+ BasicBlock *Exit =
+ BasicBlock::Create(Ctx, "omp_" + Name + ".exit", F, PostInsertBefore);
+ BasicBlock *After =
+ BasicBlock::Create(Ctx, "omp_" + Name + ".after", F, PostInsertBefore);
+
+ // Use specified DebugLoc for new instructions.
+ Builder.SetCurrentDebugLocation(DL);
+
+ Builder.SetInsertPoint(Preheader);
+ Builder.CreateBr(Header);
+
+ Builder.SetInsertPoint(Header);
+ PHINode *IndVarPHI = Builder.CreatePHI(IndVarTy, 2, "omp_" + Name + ".iv");
+ IndVarPHI->addIncoming(ConstantInt::get(IndVarTy, 0), Preheader);
+ Builder.CreateBr(Cond);
+
+ Builder.SetInsertPoint(Cond);
+ Value *Cmp =
+ Builder.CreateICmpULT(IndVarPHI, TripCount, "omp_" + Name + ".cmp");
+ Builder.CreateCondBr(Cmp, Body, Exit);
+
+ Builder.SetInsertPoint(Body);
+ Builder.CreateBr(Latch);
+
+ Builder.SetInsertPoint(Latch);
+ Value *Next = Builder.CreateAdd(IndVarPHI, ConstantInt::get(IndVarTy, 1),
+ "omp_" + Name + ".next", /*HasNUW=*/true);
+ Builder.CreateBr(Header);
+ IndVarPHI->addIncoming(Next, Latch);
+
+ Builder.SetInsertPoint(Exit);
+ Builder.CreateBr(After);
+
+ // Remember and return the canonical control flow.
+ LoopInfos.emplace_front();
+ CanonicalLoopInfo *CL = &LoopInfos.front();
+
+ CL->Preheader = Preheader;
+ CL->Header = Header;
+ CL->Cond = Cond;
+ CL->Body = Body;
+ CL->Latch = Latch;
+ CL->Exit = Exit;
+ CL->After = After;
+
+ CL->IsValid = true;
+
+#ifndef NDEBUG
+ CL->assertOK();
+#endif
+ return CL;
+}
+
+CanonicalLoopInfo *
+OpenMPIRBuilder::createCanonicalLoop(const LocationDescription &Loc,
+ LoopBodyGenCallbackTy BodyGenCB,
+ Value *TripCount, const Twine &Name) {
+ BasicBlock *BB = Loc.IP.getBlock();
+ BasicBlock *NextBB = BB->getNextNode();
+
+ CanonicalLoopInfo *CL = createLoopSkeleton(Loc.DL, TripCount, BB->getParent(),
+ NextBB, NextBB, Name);
+ BasicBlock *After = CL->getAfter();
+
+ // If location is not set, don't connect the loop.
+ if (updateToLocation(Loc)) {
+ // Split the loop at the insertion point: Branch to the preheader and move
+ // every following instruction to after the loop (the After BB). Also, the
+ // new successor is the loop's after block.
+ Builder.CreateBr(CL->Preheader);
+ After->getInstList().splice(After->begin(), BB->getInstList(),
+ Builder.GetInsertPoint(), BB->end());
+ After->replaceSuccessorsPhiUsesWith(BB, After);
+ }
+
+ // Emit the body content. We do it after connecting the loop to the CFG to
+ // avoid that the callback encounters degenerate BBs.
+ BodyGenCB(CL->getBodyIP(), CL->getIndVar());
+
+#ifndef NDEBUG
+ CL->assertOK();
+#endif
+ return CL;
+}
+
+CanonicalLoopInfo *OpenMPIRBuilder::createCanonicalLoop(
+ const LocationDescription &Loc, LoopBodyGenCallbackTy BodyGenCB,
+ Value *Start, Value *Stop, Value *Step, bool IsSigned, bool InclusiveStop,
+ InsertPointTy ComputeIP, const Twine &Name) {
+
+ // Consider the following difficulties (assuming 8-bit signed integers):
+ // * Adding \p Step to the loop counter which passes \p Stop may overflow:
+ // DO I = 1, 100, 50
+ /// * A \p Step of INT_MIN cannot not be normalized to a positive direction:
+ // DO I = 100, 0, -128
+
+ // Start, Stop and Step must be of the same integer type.
+ auto *IndVarTy = cast<IntegerType>(Start->getType());
+ assert(IndVarTy == Stop->getType() && "Stop type mismatch");
+ assert(IndVarTy == Step->getType() && "Step type mismatch");
+
+ LocationDescription ComputeLoc =
+ ComputeIP.isSet() ? LocationDescription(ComputeIP, Loc.DL) : Loc;
+ updateToLocation(ComputeLoc);
+
+ ConstantInt *Zero = ConstantInt::get(IndVarTy, 0);
+ ConstantInt *One = ConstantInt::get(IndVarTy, 1);
+
+ // Like Step, but always positive.
+ Value *Incr = Step;
+
+ // Distance between Start and Stop; always positive.
+ Value *Span;
+
+ // Condition whether there are no iterations are executed at all, e.g. because
+ // UB < LB.
+ Value *ZeroCmp;
+
+ if (IsSigned) {
+ // Ensure that increment is positive. If not, negate and invert LB and UB.
+ Value *IsNeg = Builder.CreateICmpSLT(Step, Zero);
+ Incr = Builder.CreateSelect(IsNeg, Builder.CreateNeg(Step), Step);
+ Value *LB = Builder.CreateSelect(IsNeg, Stop, Start);
+ Value *UB = Builder.CreateSelect(IsNeg, Start, Stop);
+ Span = Builder.CreateSub(UB, LB, "", false, true);
+ ZeroCmp = Builder.CreateICmp(
+ InclusiveStop ? CmpInst::ICMP_SLT : CmpInst::ICMP_SLE, UB, LB);
+ } else {
+ Span = Builder.CreateSub(Stop, Start, "", true);
+ ZeroCmp = Builder.CreateICmp(
+ InclusiveStop ? CmpInst::ICMP_ULT : CmpInst::ICMP_ULE, Stop, Start);
+ }
+
+ Value *CountIfLooping;
+ if (InclusiveStop) {
+ CountIfLooping = Builder.CreateAdd(Builder.CreateUDiv(Span, Incr), One);
+ } else {
+ // Avoid incrementing past stop since it could overflow.
+ Value *CountIfTwo = Builder.CreateAdd(
+ Builder.CreateUDiv(Builder.CreateSub(Span, One), Incr), One);
+ Value *OneCmp = Builder.CreateICmp(
+ InclusiveStop ? CmpInst::ICMP_ULT : CmpInst::ICMP_ULE, Span, Incr);
+ CountIfLooping = Builder.CreateSelect(OneCmp, One, CountIfTwo);
+ }
+ Value *TripCount = Builder.CreateSelect(ZeroCmp, Zero, CountIfLooping,
+ "omp_" + Name + ".tripcount");
+
+ auto BodyGen = [=](InsertPointTy CodeGenIP, Value *IV) {
+ Builder.restoreIP(CodeGenIP);
+ Value *Span = Builder.CreateMul(IV, Step);
+ Value *IndVar = Builder.CreateAdd(Span, Start);
+ BodyGenCB(Builder.saveIP(), IndVar);
+ };
+ LocationDescription LoopLoc = ComputeIP.isSet() ? Loc.IP : Builder.saveIP();
+ return createCanonicalLoop(LoopLoc, BodyGen, TripCount, Name);
+}
+
+// Returns an LLVM function to call for initializing loop bounds using OpenMP
+// static scheduling depending on `type`. Only i32 and i64 are supported by the
+// runtime. Always interpret integers as unsigned similarly to
+// CanonicalLoopInfo.
+static FunctionCallee getKmpcForStaticInitForType(Type *Ty, Module &M,
+ OpenMPIRBuilder &OMPBuilder) {
+ unsigned Bitwidth = Ty->getIntegerBitWidth();
+ if (Bitwidth == 32)
+ return OMPBuilder.getOrCreateRuntimeFunction(
+ M, omp::RuntimeFunction::OMPRTL___kmpc_for_static_init_4u);
+ if (Bitwidth == 64)
+ return OMPBuilder.getOrCreateRuntimeFunction(
+ M, omp::RuntimeFunction::OMPRTL___kmpc_for_static_init_8u);
+ llvm_unreachable("unknown OpenMP loop iterator bitwidth");
+}
+
+// Sets the number of loop iterations to the given value. This value must be
+// valid in the condition block (i.e., defined in the preheader) and is
+// interpreted as an unsigned integer.
+void setCanonicalLoopTripCount(CanonicalLoopInfo *CLI, Value *TripCount) {
+ Instruction *CmpI = &CLI->getCond()->front();
+ assert(isa<CmpInst>(CmpI) && "First inst must compare IV with TripCount");
+ CmpI->setOperand(1, TripCount);
+ CLI->assertOK();
+}
+
+CanonicalLoopInfo *OpenMPIRBuilder::createStaticWorkshareLoop(
+ const LocationDescription &Loc, CanonicalLoopInfo *CLI,
+ InsertPointTy AllocaIP, bool NeedsBarrier, Value *Chunk) {
+ // Set up the source location value for OpenMP runtime.
+ if (!updateToLocation(Loc))
+ return nullptr;
+
+ Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
+ Value *SrcLoc = getOrCreateIdent(SrcLocStr);
+
+ // Declare useful OpenMP runtime functions.
+ Value *IV = CLI->getIndVar();
+ Type *IVTy = IV->getType();
+ FunctionCallee StaticInit = getKmpcForStaticInitForType(IVTy, M, *this);
+ FunctionCallee StaticFini =
+ getOrCreateRuntimeFunction(M, omp::OMPRTL___kmpc_for_static_fini);
+
+ // Allocate space for computed loop bounds as expected by the "init" function.
+ Builder.restoreIP(AllocaIP);
+ Type *I32Type = Type::getInt32Ty(M.getContext());
+ Value *PLastIter = Builder.CreateAlloca(I32Type, nullptr, "p.lastiter");
+ Value *PLowerBound = Builder.CreateAlloca(IVTy, nullptr, "p.lowerbound");
+ Value *PUpperBound = Builder.CreateAlloca(IVTy, nullptr, "p.upperbound");
+ Value *PStride = Builder.CreateAlloca(IVTy, nullptr, "p.stride");
+
+ // At the end of the preheader, prepare for calling the "init" function by
+ // storing the current loop bounds into the allocated space. A canonical loop
+ // always iterates from 0 to trip-count with step 1. Note that "init" expects
+ // and produces an inclusive upper bound.
+ Builder.SetInsertPoint(CLI->getPreheader()->getTerminator());
+ Constant *Zero = ConstantInt::get(IVTy, 0);
+ Constant *One = ConstantInt::get(IVTy, 1);
+ Builder.CreateStore(Zero, PLowerBound);
+ Value *UpperBound = Builder.CreateSub(CLI->getTripCount(), One);
+ Builder.CreateStore(UpperBound, PUpperBound);
+ Builder.CreateStore(One, PStride);
+
+ if (!Chunk)
+ Chunk = One;
+
+ Value *ThreadNum = getOrCreateThreadID(SrcLoc);
+
+ // TODO: extract scheduling type and map it to OMP constant. This is curently
+ // happening in kmp.h and its ilk and needs to be moved to OpenMP.td first.
+ constexpr int StaticSchedType = 34;
+ Constant *SchedulingType = ConstantInt::get(I32Type, StaticSchedType);
+
+ // Call the "init" function and update the trip count of the loop with the
+ // value it produced.
+ Builder.CreateCall(StaticInit,
+ {SrcLoc, ThreadNum, SchedulingType, PLastIter, PLowerBound,
+ PUpperBound, PStride, One, Chunk});
+ Value *LowerBound = Builder.CreateLoad(PLowerBound);
+ Value *InclusiveUpperBound = Builder.CreateLoad(PUpperBound);
+ Value *TripCountMinusOne = Builder.CreateSub(InclusiveUpperBound, LowerBound);
+ Value *TripCount = Builder.CreateAdd(TripCountMinusOne, One);
+ setCanonicalLoopTripCount(CLI, TripCount);
+
+ // Update all uses of the induction variable except the one in the condition
+ // block that compares it with the actual upper bound, and the increment in
+ // the latch block.
+ // TODO: this can eventually move to CanonicalLoopInfo or to a new
+ // CanonicalLoopInfoUpdater interface.
+ Builder.SetInsertPoint(CLI->getBody(), CLI->getBody()->getFirstInsertionPt());
+ Value *UpdatedIV = Builder.CreateAdd(IV, LowerBound);
+ IV->replaceUsesWithIf(UpdatedIV, [&](Use &U) {
+ auto *Instr = dyn_cast<Instruction>(U.getUser());
+ return !Instr ||
+ (Instr->getParent() != CLI->getCond() &&
+ Instr->getParent() != CLI->getLatch() && Instr != UpdatedIV);
+ });
+
+ // In the "exit" block, call the "fini" function.
+ Builder.SetInsertPoint(CLI->getExit(),
+ CLI->getExit()->getTerminator()->getIterator());
+ Builder.CreateCall(StaticFini, {SrcLoc, ThreadNum});
+
+ // Add the barrier if requested.
+ if (NeedsBarrier)
+ createBarrier(LocationDescription(Builder.saveIP(), Loc.DL),
+ omp::Directive::OMPD_for, /* ForceSimpleCall */ false,
+ /* CheckCancelFlag */ false);
+
+ CLI->assertOK();
+ return CLI;
+}
+
+/// Make \p Source branch to \p Target.
+///
+/// Handles two situations:
+/// * \p Source already has an unconditional branch.
+/// * \p Source is a degenerate block (no terminator because the BB is
+/// the current head of the IR construction).
+static void redirectTo(BasicBlock *Source, BasicBlock *Target, DebugLoc DL) {
+ if (Instruction *Term = Source->getTerminator()) {
+ auto *Br = cast<BranchInst>(Term);
+ assert(!Br->isConditional() &&
+ "BB's terminator must be an unconditional branch (or degenerate)");
+ BasicBlock *Succ = Br->getSuccessor(0);
+ Succ->removePredecessor(Source, /*KeepOneInputPHIs=*/true);
+ Br->setSuccessor(0, Target);
+ return;
+ }
+
+ auto *NewBr = BranchInst::Create(Target, Source);
+ NewBr->setDebugLoc(DL);
+}
+
+/// Redirect all edges that branch to \p OldTarget to \p NewTarget. That is,
+/// after this \p OldTarget will be orphaned.
+static void redirectAllPredecessorsTo(BasicBlock *OldTarget,
+ BasicBlock *NewTarget, DebugLoc DL) {
+ for (BasicBlock *Pred : make_early_inc_range(predecessors(OldTarget)))
+ redirectTo(Pred, NewTarget, DL);
+}
+
+/// Determine which blocks in \p BBs are reachable from outside and remove the
+/// ones that are not reachable from the function.
+static void removeUnusedBlocksFromParent(ArrayRef<BasicBlock *> BBs) {
+ SmallPtrSet<BasicBlock *, 6> BBsToErase{BBs.begin(), BBs.end()};
+ auto HasRemainingUses = [&BBsToErase](BasicBlock *BB) {
+ for (Use &U : BB->uses()) {
+ auto *UseInst = dyn_cast<Instruction>(U.getUser());
+ if (!UseInst)
+ continue;
+ if (BBsToErase.count(UseInst->getParent()))
+ continue;
+ return true;
+ }
+ return false;
+ };
+
+ while (true) {
+ bool Changed = false;
+ for (BasicBlock *BB : make_early_inc_range(BBsToErase)) {
+ if (HasRemainingUses(BB)) {
+ BBsToErase.erase(BB);
+ Changed = true;
+ }
+ }
+ if (!Changed)
+ break;
+ }
+
+ SmallVector<BasicBlock *, 7> BBVec(BBsToErase.begin(), BBsToErase.end());
+ DeleteDeadBlocks(BBVec);
+}
+
+std::vector<CanonicalLoopInfo *>
+OpenMPIRBuilder::tileLoops(DebugLoc DL, ArrayRef<CanonicalLoopInfo *> Loops,
+ ArrayRef<Value *> TileSizes) {
+ assert(TileSizes.size() == Loops.size() &&
+ "Must pass as many tile sizes as there are loops");
+ int NumLoops = Loops.size();
+ assert(NumLoops >= 1 && "At least one loop to tile required");
+
+ CanonicalLoopInfo *OutermostLoop = Loops.front();
+ CanonicalLoopInfo *InnermostLoop = Loops.back();
+ Function *F = OutermostLoop->getBody()->getParent();
+ BasicBlock *InnerEnter = InnermostLoop->getBody();
+ BasicBlock *InnerLatch = InnermostLoop->getLatch();
+
+ // Collect original trip counts and induction variable to be accessible by
+ // index. Also, the structure of the original loops is not preserved during
+ // the construction of the tiled loops, so do it before we scavenge the BBs of
+ // any original CanonicalLoopInfo.
+ SmallVector<Value *, 4> OrigTripCounts, OrigIndVars;
+ for (CanonicalLoopInfo *L : Loops) {
+ OrigTripCounts.push_back(L->getTripCount());
+ OrigIndVars.push_back(L->getIndVar());
+ }
+
+ // Collect the code between loop headers. These may contain SSA definitions
+ // that are used in the loop nest body. To be usable with in the innermost
+ // body, these BasicBlocks will be sunk into the loop nest body. That is,
+ // these instructions may be executed more often than before the tiling.
+ // TODO: It would be sufficient to only sink them into body of the
+ // corresponding tile loop.
+ SmallVector<std::pair<BasicBlock *, BasicBlock *>, 4> InbetweenCode;
+ for (int i = 0; i < NumLoops - 1; ++i) {
+ CanonicalLoopInfo *Surrounding = Loops[i];
+ CanonicalLoopInfo *Nested = Loops[i + 1];
+
+ BasicBlock *EnterBB = Surrounding->getBody();
+ BasicBlock *ExitBB = Nested->getHeader();
+ InbetweenCode.emplace_back(EnterBB, ExitBB);
+ }
+
+ // Compute the trip counts of the floor loops.
+ Builder.SetCurrentDebugLocation(DL);
+ Builder.restoreIP(OutermostLoop->getPreheaderIP());
+ SmallVector<Value *, 4> FloorCount, FloorRems;
+ for (int i = 0; i < NumLoops; ++i) {
+ Value *TileSize = TileSizes[i];
+ Value *OrigTripCount = OrigTripCounts[i];
+ Type *IVType = OrigTripCount->getType();
+
+ Value *FloorTripCount = Builder.CreateUDiv(OrigTripCount, TileSize);
+ Value *FloorTripRem = Builder.CreateURem(OrigTripCount, TileSize);
+
+ // 0 if tripcount divides the tilesize, 1 otherwise.
+ // 1 means we need an additional iteration for a partial tile.
+ //
+ // Unfortunately we cannot just use the roundup-formula
+ // (tripcount + tilesize - 1)/tilesize
+ // because the summation might overflow. We do not want introduce undefined
+ // behavior when the untiled loop nest did not.
+ Value *FloorTripOverflow =
+ Builder.CreateICmpNE(FloorTripRem, ConstantInt::get(IVType, 0));
+
+ FloorTripOverflow = Builder.CreateZExt(FloorTripOverflow, IVType);
+ FloorTripCount =
+ Builder.CreateAdd(FloorTripCount, FloorTripOverflow,
+ "omp_floor" + Twine(i) + ".tripcount", true);
+
+ // Remember some values for later use.
+ FloorCount.push_back(FloorTripCount);
+ FloorRems.push_back(FloorTripRem);
+ }
+
+ // Generate the new loop nest, from the outermost to the innermost.
+ std::vector<CanonicalLoopInfo *> Result;
+ Result.reserve(NumLoops * 2);
+
+ // The basic block of the surrounding loop that enters the nest generated
+ // loop.
+ BasicBlock *Enter = OutermostLoop->getPreheader();
+
+ // The basic block of the surrounding loop where the inner code should
+ // continue.
+ BasicBlock *Continue = OutermostLoop->getAfter();
+
+ // Where the next loop basic block should be inserted.
+ BasicBlock *OutroInsertBefore = InnermostLoop->getExit();
+
+ auto EmbeddNewLoop =
+ [this, DL, F, InnerEnter, &Enter, &Continue, &OutroInsertBefore](
+ Value *TripCount, const Twine &Name) -> CanonicalLoopInfo * {
+ CanonicalLoopInfo *EmbeddedLoop = createLoopSkeleton(
+ DL, TripCount, F, InnerEnter, OutroInsertBefore, Name);
+ redirectTo(Enter, EmbeddedLoop->getPreheader(), DL);
+ redirectTo(EmbeddedLoop->getAfter(), Continue, DL);
+
+ // Setup the position where the next embedded loop connects to this loop.
+ Enter = EmbeddedLoop->getBody();
+ Continue = EmbeddedLoop->getLatch();
+ OutroInsertBefore = EmbeddedLoop->getLatch();
+ return EmbeddedLoop;
+ };
+
+ auto EmbeddNewLoops = [&Result, &EmbeddNewLoop](ArrayRef<Value *> TripCounts,
+ const Twine &NameBase) {
+ for (auto P : enumerate(TripCounts)) {
+ CanonicalLoopInfo *EmbeddedLoop =
+ EmbeddNewLoop(P.value(), NameBase + Twine(P.index()));
+ Result.push_back(EmbeddedLoop);
+ }
+ };
+
+ EmbeddNewLoops(FloorCount, "floor");
+
+ // Within the innermost floor loop, emit the code that computes the tile
+ // sizes.
+ Builder.SetInsertPoint(Enter->getTerminator());
+ SmallVector<Value *, 4> TileCounts;
+ for (int i = 0; i < NumLoops; ++i) {
+ CanonicalLoopInfo *FloorLoop = Result[i];
+ Value *TileSize = TileSizes[i];
+
+ Value *FloorIsEpilogue =
+ Builder.CreateICmpEQ(FloorLoop->getIndVar(), FloorCount[i]);
+ Value *TileTripCount =
+ Builder.CreateSelect(FloorIsEpilogue, FloorRems[i], TileSize);
+
+ TileCounts.push_back(TileTripCount);
+ }
+
+ // Create the tile loops.
+ EmbeddNewLoops(TileCounts, "tile");
+
+ // Insert the inbetween code into the body.
+ BasicBlock *BodyEnter = Enter;
+ BasicBlock *BodyEntered = nullptr;
+ for (std::pair<BasicBlock *, BasicBlock *> P : InbetweenCode) {
+ BasicBlock *EnterBB = P.first;
+ BasicBlock *ExitBB = P.second;
+
+ if (BodyEnter)
+ redirectTo(BodyEnter, EnterBB, DL);
+ else
+ redirectAllPredecessorsTo(BodyEntered, EnterBB, DL);
+
+ BodyEnter = nullptr;
+ BodyEntered = ExitBB;
+ }
+
+ // Append the original loop nest body into the generated loop nest body.
+ if (BodyEnter)
+ redirectTo(BodyEnter, InnerEnter, DL);
+ else
+ redirectAllPredecessorsTo(BodyEntered, InnerEnter, DL);
+ redirectAllPredecessorsTo(InnerLatch, Continue, DL);
+
+ // Replace the original induction variable with an induction variable computed
+ // from the tile and floor induction variables.
+ Builder.restoreIP(Result.back()->getBodyIP());
+ for (int i = 0; i < NumLoops; ++i) {
+ CanonicalLoopInfo *FloorLoop = Result[i];
+ CanonicalLoopInfo *TileLoop = Result[NumLoops + i];
+ Value *OrigIndVar = OrigIndVars[i];
+ Value *Size = TileSizes[i];
+
+ Value *Scale =
+ Builder.CreateMul(Size, FloorLoop->getIndVar(), {}, /*HasNUW=*/true);
+ Value *Shift =
+ Builder.CreateAdd(Scale, TileLoop->getIndVar(), {}, /*HasNUW=*/true);
+ OrigIndVar->replaceAllUsesWith(Shift);
+ }
+
+ // Remove unused parts of the original loops.
+ SmallVector<BasicBlock *, 12> OldControlBBs;
+ OldControlBBs.reserve(6 * Loops.size());
+ for (CanonicalLoopInfo *Loop : Loops)
+ Loop->collectControlBlocks(OldControlBBs);
+ removeUnusedBlocksFromParent(OldControlBBs);
+
+#ifndef NDEBUG
+ for (CanonicalLoopInfo *GenL : Result)
+ GenL->assertOK();
+#endif
+ return Result;
+}
+
+OpenMPIRBuilder::InsertPointTy
+OpenMPIRBuilder::createCopyPrivate(const LocationDescription &Loc,
+ llvm::Value *BufSize, llvm::Value *CpyBuf,
+ llvm::Value *CpyFn, llvm::Value *DidIt) {
+ if (!updateToLocation(Loc))
+ return Loc.IP;
+
+ Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
+ Value *Ident = getOrCreateIdent(SrcLocStr);
+ Value *ThreadId = getOrCreateThreadID(Ident);
+
+ llvm::Value *DidItLD = Builder.CreateLoad(DidIt);
+
+ Value *Args[] = {Ident, ThreadId, BufSize, CpyBuf, CpyFn, DidItLD};
+
+ Function *Fn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_copyprivate);
+ Builder.CreateCall(Fn, Args);
+
+ return Builder.saveIP();
+}
+
+OpenMPIRBuilder::InsertPointTy
+OpenMPIRBuilder::createSingle(const LocationDescription &Loc,
+ BodyGenCallbackTy BodyGenCB,
+ FinalizeCallbackTy FiniCB, llvm::Value *DidIt) {
+
+ if (!updateToLocation(Loc))
+ return Loc.IP;
+
+ // If needed (i.e. not null), initialize `DidIt` with 0
+ if (DidIt) {
+ Builder.CreateStore(Builder.getInt32(0), DidIt);
+ }
+
+ Directive OMPD = Directive::OMPD_single;
+ Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
+ Value *Ident = getOrCreateIdent(SrcLocStr);
+ Value *ThreadId = getOrCreateThreadID(Ident);
+ Value *Args[] = {Ident, ThreadId};
+
+ Function *EntryRTLFn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_single);
+ Instruction *EntryCall = Builder.CreateCall(EntryRTLFn, Args);
+
+ Function *ExitRTLFn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_end_single);
+ Instruction *ExitCall = Builder.CreateCall(ExitRTLFn, Args);
+
+ // generates the following:
+ // if (__kmpc_single()) {
+ // .... single region ...
+ // __kmpc_end_single
+ // }
+
+ return EmitOMPInlinedRegion(OMPD, EntryCall, ExitCall, BodyGenCB, FiniCB,
+ /*Conditional*/ true, /*hasFinalize*/ true);
+}
+
+OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createCritical(
const LocationDescription &Loc, BodyGenCallbackTy BodyGenCB,
FinalizeCallbackTy FiniCB, StringRef CriticalName, Value *HintInst) {
@@ -1630,7 +1630,7 @@ OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::emitCommonDirectiveExit(
ExitCall->getIterator());
}
-OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createCopyinClauseBlocks(
+OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createCopyinClauseBlocks(
InsertPointTy IP, Value *MasterAddr, Value *PrivateAddr,
llvm::IntegerType *IntPtrTy, bool BranchtoEnd) {
if (!IP.isSet())
@@ -1680,7 +1680,7 @@ OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createCopyinClauseBlocks(
return Builder.saveIP();
}
-CallInst *OpenMPIRBuilder::createOMPAlloc(const LocationDescription &Loc,
+CallInst *OpenMPIRBuilder::createOMPAlloc(const LocationDescription &Loc,
Value *Size, Value *Allocator,
std::string Name) {
IRBuilder<>::InsertPointGuard IPG(Builder);
@@ -1696,7 +1696,7 @@ CallInst *OpenMPIRBuilder::createOMPAlloc(const LocationDescription &Loc,
return Builder.CreateCall(Fn, Args, Name);
}
-CallInst *OpenMPIRBuilder::createOMPFree(const LocationDescription &Loc,
+CallInst *OpenMPIRBuilder::createOMPFree(const LocationDescription &Loc,
Value *Addr, Value *Allocator,
std::string Name) {
IRBuilder<>::InsertPointGuard IPG(Builder);
@@ -1710,7 +1710,7 @@ CallInst *OpenMPIRBuilder::createOMPFree(const LocationDescription &Loc,
return Builder.CreateCall(Fn, Args, Name);
}
-CallInst *OpenMPIRBuilder::createCachedThreadPrivate(
+CallInst *OpenMPIRBuilder::createCachedThreadPrivate(
const LocationDescription &Loc, llvm::Value *Pointer,
llvm::ConstantInt *Size, const llvm::Twine &Name) {
IRBuilder<>::InsertPointGuard IPG(Builder);
@@ -1791,7 +1791,7 @@ void OpenMPIRBuilder::initializeTypes(Module &M) {
VarName = FunctionType::get(ReturnType, {__VA_ARGS__}, IsVarArg); \
VarName##Ptr = PointerType::getUnqual(VarName);
#define OMP_STRUCT_TYPE(VarName, StructName, ...) \
- T = StructType::getTypeByName(Ctx, StructName); \
+ T = StructType::getTypeByName(Ctx, StructName); \
if (!T) \
T = StructType::create(Ctx, {__VA_ARGS__}, StructName); \
VarName = T; \
@@ -1815,102 +1815,102 @@ void OpenMPIRBuilder::OutlineInfo::collectBlocks(
Worklist.push_back(SuccBB);
}
}
-
-void CanonicalLoopInfo::collectControlBlocks(
- SmallVectorImpl<BasicBlock *> &BBs) {
- // We only count those BBs as control block for which we do not need to
- // reverse the CFG, i.e. not the loop body which can contain arbitrary control
- // flow. For consistency, this also means we do not add the Body block, which
- // is just the entry to the body code.
- BBs.reserve(BBs.size() + 6);
- BBs.append({Preheader, Header, Cond, Latch, Exit, After});
-}
-
-void CanonicalLoopInfo::assertOK() const {
-#ifndef NDEBUG
- if (!IsValid)
- return;
-
- // Verify standard control-flow we use for OpenMP loops.
- assert(Preheader);
- assert(isa<BranchInst>(Preheader->getTerminator()) &&
- "Preheader must terminate with unconditional branch");
- assert(Preheader->getSingleSuccessor() == Header &&
- "Preheader must jump to header");
-
- assert(Header);
- assert(isa<BranchInst>(Header->getTerminator()) &&
- "Header must terminate with unconditional branch");
- assert(Header->getSingleSuccessor() == Cond &&
- "Header must jump to exiting block");
-
- assert(Cond);
- assert(Cond->getSinglePredecessor() == Header &&
- "Exiting block only reachable from header");
-
- assert(isa<BranchInst>(Cond->getTerminator()) &&
- "Exiting block must terminate with conditional branch");
- assert(size(successors(Cond)) == 2 &&
- "Exiting block must have two successors");
- assert(cast<BranchInst>(Cond->getTerminator())->getSuccessor(0) == Body &&
- "Exiting block's first successor jump to the body");
- assert(cast<BranchInst>(Cond->getTerminator())->getSuccessor(1) == Exit &&
- "Exiting block's second successor must exit the loop");
-
- assert(Body);
- assert(Body->getSinglePredecessor() == Cond &&
- "Body only reachable from exiting block");
- assert(!isa<PHINode>(Body->front()));
-
- assert(Latch);
- assert(isa<BranchInst>(Latch->getTerminator()) &&
- "Latch must terminate with unconditional branch");
- assert(Latch->getSingleSuccessor() == Header && "Latch must jump to header");
- // TODO: To support simple redirecting of the end of the body code that has
- // multiple; introduce another auxiliary basic block like preheader and after.
- assert(Latch->getSinglePredecessor() != nullptr);
- assert(!isa<PHINode>(Latch->front()));
-
- assert(Exit);
- assert(isa<BranchInst>(Exit->getTerminator()) &&
- "Exit block must terminate with unconditional branch");
- assert(Exit->getSingleSuccessor() == After &&
- "Exit block must jump to after block");
-
- assert(After);
- assert(After->getSinglePredecessor() == Exit &&
- "After block only reachable from exit block");
- assert(After->empty() || !isa<PHINode>(After->front()));
-
- Instruction *IndVar = getIndVar();
- assert(IndVar && "Canonical induction variable not found?");
- assert(isa<IntegerType>(IndVar->getType()) &&
- "Induction variable must be an integer");
- assert(cast<PHINode>(IndVar)->getParent() == Header &&
- "Induction variable must be a PHI in the loop header");
- assert(cast<PHINode>(IndVar)->getIncomingBlock(0) == Preheader);
- assert(
- cast<ConstantInt>(cast<PHINode>(IndVar)->getIncomingValue(0))->isZero());
- assert(cast<PHINode>(IndVar)->getIncomingBlock(1) == Latch);
-
- auto *NextIndVar = cast<PHINode>(IndVar)->getIncomingValue(1);
- assert(cast<Instruction>(NextIndVar)->getParent() == Latch);
- assert(cast<BinaryOperator>(NextIndVar)->getOpcode() == BinaryOperator::Add);
- assert(cast<BinaryOperator>(NextIndVar)->getOperand(0) == IndVar);
- assert(cast<ConstantInt>(cast<BinaryOperator>(NextIndVar)->getOperand(1))
- ->isOne());
-
- Value *TripCount = getTripCount();
- assert(TripCount && "Loop trip count not found?");
- assert(IndVar->getType() == TripCount->getType() &&
- "Trip count and induction variable must have the same type");
-
- auto *CmpI = cast<CmpInst>(&Cond->front());
- assert(CmpI->getPredicate() == CmpInst::ICMP_ULT &&
- "Exit condition must be a signed less-than comparison");
- assert(CmpI->getOperand(0) == IndVar &&
- "Exit condition must compare the induction variable");
- assert(CmpI->getOperand(1) == TripCount &&
- "Exit condition must compare with the trip count");
-#endif
-}
+
+void CanonicalLoopInfo::collectControlBlocks(
+ SmallVectorImpl<BasicBlock *> &BBs) {
+ // We only count those BBs as control block for which we do not need to
+ // reverse the CFG, i.e. not the loop body which can contain arbitrary control
+ // flow. For consistency, this also means we do not add the Body block, which
+ // is just the entry to the body code.
+ BBs.reserve(BBs.size() + 6);
+ BBs.append({Preheader, Header, Cond, Latch, Exit, After});
+}
+
+void CanonicalLoopInfo::assertOK() const {
+#ifndef NDEBUG
+ if (!IsValid)
+ return;
+
+ // Verify standard control-flow we use for OpenMP loops.
+ assert(Preheader);
+ assert(isa<BranchInst>(Preheader->getTerminator()) &&
+ "Preheader must terminate with unconditional branch");
+ assert(Preheader->getSingleSuccessor() == Header &&
+ "Preheader must jump to header");
+
+ assert(Header);
+ assert(isa<BranchInst>(Header->getTerminator()) &&
+ "Header must terminate with unconditional branch");
+ assert(Header->getSingleSuccessor() == Cond &&
+ "Header must jump to exiting block");
+
+ assert(Cond);
+ assert(Cond->getSinglePredecessor() == Header &&
+ "Exiting block only reachable from header");
+
+ assert(isa<BranchInst>(Cond->getTerminator()) &&
+ "Exiting block must terminate with conditional branch");
+ assert(size(successors(Cond)) == 2 &&
+ "Exiting block must have two successors");
+ assert(cast<BranchInst>(Cond->getTerminator())->getSuccessor(0) == Body &&
+ "Exiting block's first successor jump to the body");
+ assert(cast<BranchInst>(Cond->getTerminator())->getSuccessor(1) == Exit &&
+ "Exiting block's second successor must exit the loop");
+
+ assert(Body);
+ assert(Body->getSinglePredecessor() == Cond &&
+ "Body only reachable from exiting block");
+ assert(!isa<PHINode>(Body->front()));
+
+ assert(Latch);
+ assert(isa<BranchInst>(Latch->getTerminator()) &&
+ "Latch must terminate with unconditional branch");
+ assert(Latch->getSingleSuccessor() == Header && "Latch must jump to header");
+ // TODO: To support simple redirecting of the end of the body code that has
+ // multiple; introduce another auxiliary basic block like preheader and after.
+ assert(Latch->getSinglePredecessor() != nullptr);
+ assert(!isa<PHINode>(Latch->front()));
+
+ assert(Exit);
+ assert(isa<BranchInst>(Exit->getTerminator()) &&
+ "Exit block must terminate with unconditional branch");
+ assert(Exit->getSingleSuccessor() == After &&
+ "Exit block must jump to after block");
+
+ assert(After);
+ assert(After->getSinglePredecessor() == Exit &&
+ "After block only reachable from exit block");
+ assert(After->empty() || !isa<PHINode>(After->front()));
+
+ Instruction *IndVar = getIndVar();
+ assert(IndVar && "Canonical induction variable not found?");
+ assert(isa<IntegerType>(IndVar->getType()) &&
+ "Induction variable must be an integer");
+ assert(cast<PHINode>(IndVar)->getParent() == Header &&
+ "Induction variable must be a PHI in the loop header");
+ assert(cast<PHINode>(IndVar)->getIncomingBlock(0) == Preheader);
+ assert(
+ cast<ConstantInt>(cast<PHINode>(IndVar)->getIncomingValue(0))->isZero());
+ assert(cast<PHINode>(IndVar)->getIncomingBlock(1) == Latch);
+
+ auto *NextIndVar = cast<PHINode>(IndVar)->getIncomingValue(1);
+ assert(cast<Instruction>(NextIndVar)->getParent() == Latch);
+ assert(cast<BinaryOperator>(NextIndVar)->getOpcode() == BinaryOperator::Add);
+ assert(cast<BinaryOperator>(NextIndVar)->getOperand(0) == IndVar);
+ assert(cast<ConstantInt>(cast<BinaryOperator>(NextIndVar)->getOperand(1))
+ ->isOne());
+
+ Value *TripCount = getTripCount();
+ assert(TripCount && "Loop trip count not found?");
+ assert(IndVar->getType() == TripCount->getType() &&
+ "Trip count and induction variable must have the same type");
+
+ auto *CmpI = cast<CmpInst>(&Cond->front());
+ assert(CmpI->getPredicate() == CmpInst::ICMP_ULT &&
+ "Exit condition must be a signed less-than comparison");
+ assert(CmpI->getOperand(0) == IndVar &&
+ "Exit condition must compare the induction variable");
+ assert(CmpI->getOperand(1) == TripCount &&
+ "Exit condition must compare with the trip count");
+#endif
+}
diff --git a/contrib/libs/llvm12/lib/Frontend/OpenMP/ya.make b/contrib/libs/llvm12/lib/Frontend/OpenMP/ya.make
index d70bd22597..3a64ea8b69 100644
--- a/contrib/libs/llvm12/lib/Frontend/OpenMP/ya.make
+++ b/contrib/libs/llvm12/lib/Frontend/OpenMP/ya.make
@@ -12,11 +12,11 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Transforms/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Transforms/Utils
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/IR/AsmWriter.cpp b/contrib/libs/llvm12/lib/IR/AsmWriter.cpp
index 536f500dc6..69abf8769e 100644
--- a/contrib/libs/llvm12/lib/IR/AsmWriter.cpp
+++ b/contrib/libs/llvm12/lib/IR/AsmWriter.cpp
@@ -116,15 +116,15 @@ struct OrderMap {
} // end anonymous namespace
-/// Look for a value that might be wrapped as metadata, e.g. a value in a
-/// metadata operand. Returns the input value as-is if it is not wrapped.
-static const Value *skipMetadataWrapper(const Value *V) {
- if (const auto *MAV = dyn_cast<MetadataAsValue>(V))
- if (const auto *VAM = dyn_cast<ValueAsMetadata>(MAV->getMetadata()))
- return VAM->getValue();
- return V;
-}
-
+/// Look for a value that might be wrapped as metadata, e.g. a value in a
+/// metadata operand. Returns the input value as-is if it is not wrapped.
+static const Value *skipMetadataWrapper(const Value *V) {
+ if (const auto *MAV = dyn_cast<MetadataAsValue>(V))
+ if (const auto *VAM = dyn_cast<ValueAsMetadata>(MAV->getMetadata()))
+ return VAM->getValue();
+ return V;
+}
+
static void orderValue(const Value *V, OrderMap &OM) {
if (OM.lookup(V).first)
return;
@@ -174,12 +174,12 @@ static OrderMap orderModule(const Module *M) {
for (const BasicBlock &BB : F) {
orderValue(&BB, OM);
for (const Instruction &I : BB) {
- for (const Value *Op : I.operands()) {
- Op = skipMetadataWrapper(Op);
+ for (const Value *Op : I.operands()) {
+ Op = skipMetadataWrapper(Op);
if ((isa<Constant>(*Op) && !isa<GlobalValue>(*Op)) ||
isa<InlineAsm>(*Op))
orderValue(Op, OM);
- }
+ }
orderValue(&I, OM);
}
}
@@ -293,11 +293,11 @@ static UseListOrderStack predictUseListOrder(const Module *M) {
predictValueUseListOrder(&A, &F, OM, Stack);
for (const BasicBlock &BB : F)
for (const Instruction &I : BB)
- for (const Value *Op : I.operands()) {
- Op = skipMetadataWrapper(Op);
+ for (const Value *Op : I.operands()) {
+ Op = skipMetadataWrapper(Op);
if (isa<Constant>(*Op) || isa<InlineAsm>(*Op)) // Visit GlobalValues.
predictValueUseListOrder(Op, &F, OM, Stack);
- }
+ }
for (const BasicBlock &BB : F)
for (const Instruction &I : BB)
predictValueUseListOrder(&I, &F, OM, Stack);
@@ -399,7 +399,7 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) {
case CallingConv::AMDGPU_PS: Out << "amdgpu_ps"; break;
case CallingConv::AMDGPU_CS: Out << "amdgpu_cs"; break;
case CallingConv::AMDGPU_KERNEL: Out << "amdgpu_kernel"; break;
- case CallingConv::AMDGPU_Gfx: Out << "amdgpu_gfx"; break;
+ case CallingConv::AMDGPU_Gfx: Out << "amdgpu_gfx"; break;
}
}
@@ -609,7 +609,7 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) {
case Type::LabelTyID: OS << "label"; return;
case Type::MetadataTyID: OS << "metadata"; return;
case Type::X86_MMXTyID: OS << "x86_mmx"; return;
- case Type::X86_AMXTyID: OS << "x86_amx"; return;
+ case Type::X86_AMXTyID: OS << "x86_amx"; return;
case Type::TokenTyID: OS << "token"; return;
case Type::IntegerTyID:
OS << 'i' << cast<IntegerType>(Ty)->getBitWidth();
@@ -669,9 +669,9 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) {
VectorType *PTy = cast<VectorType>(Ty);
ElementCount EC = PTy->getElementCount();
OS << "<";
- if (EC.isScalable())
+ if (EC.isScalable())
OS << "vscale x ";
- OS << EC.getKnownMinValue() << " x ";
+ OS << EC.getKnownMinValue() << " x ";
print(PTy->getElementType(), OS);
OS << '>';
return;
@@ -1368,8 +1368,8 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
// "Inf" or NaN, that atof will accept, but the lexer will not. Check
// that the string matches the "[-+]?[0-9]" regex.
//
- assert((isDigit(StrVal[0]) || ((StrVal[0] == '-' || StrVal[0] == '+') &&
- isDigit(StrVal[1]))) &&
+ assert((isDigit(StrVal[0]) || ((StrVal[0] == '-' || StrVal[0] == '+') &&
+ isDigit(StrVal[1]))) &&
"[-+]?[0-9] regex does not match!");
// Reparse stringized version!
if (APFloat(APFloat::IEEEdouble(), StrVal).convertToDouble() == Val) {
@@ -1385,19 +1385,19 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
"assuming that double is 64 bits!");
APFloat apf = APF;
// Floats are represented in ASCII IR as double, convert.
- // FIXME: We should allow 32-bit hex float and remove this.
- if (!isDouble) {
- // A signaling NaN is quieted on conversion, so we need to recreate the
- // expected value after convert (quiet bit of the payload is clear).
- bool IsSNAN = apf.isSignaling();
+ // FIXME: We should allow 32-bit hex float and remove this.
+ if (!isDouble) {
+ // A signaling NaN is quieted on conversion, so we need to recreate the
+ // expected value after convert (quiet bit of the payload is clear).
+ bool IsSNAN = apf.isSignaling();
apf.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
- &ignored);
- if (IsSNAN) {
- APInt Payload = apf.bitcastToAPInt();
- apf = APFloat::getSNaN(APFloat::IEEEdouble(), apf.isNegative(),
- &Payload);
- }
- }
+ &ignored);
+ if (IsSNAN) {
+ APInt Payload = apf.bitcastToAPInt();
+ apf = APFloat::getSNaN(APFloat::IEEEdouble(), apf.isNegative(),
+ &Payload);
+ }
+ }
Out << format_hex(apf.bitcastToAPInt().getZExtValue(), 0, /*Upper=*/true);
return;
}
@@ -1455,13 +1455,13 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
return;
}
- if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(CV)) {
- Out << "dso_local_equivalent ";
- WriteAsOperandInternal(Out, Equiv->getGlobalValue(), &TypePrinter, Machine,
- Context);
- return;
- }
-
+ if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(CV)) {
+ Out << "dso_local_equivalent ";
+ WriteAsOperandInternal(Out, Equiv->getGlobalValue(), &TypePrinter, Machine,
+ Context);
+ return;
+ }
+
if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
Type *ETy = CA->getType()->getElementType();
Out << '[';
@@ -1540,7 +1540,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
}
if (isa<ConstantVector>(CV) || isa<ConstantDataVector>(CV)) {
- auto *CVVTy = cast<FixedVectorType>(CV->getType());
+ auto *CVVTy = cast<FixedVectorType>(CV->getType());
Type *ETy = CVVTy->getElementType();
Out << '<';
TypePrinter.print(ETy, Out);
@@ -1568,11 +1568,11 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
return;
}
- if (isa<PoisonValue>(CV)) {
- Out << "poison";
- return;
- }
-
+ if (isa<PoisonValue>(CV)) {
+ Out << "poison";
+ return;
+ }
+
if (isa<UndefValue>(CV)) {
Out << "undef";
return;
@@ -1923,57 +1923,57 @@ static void writeDISubrange(raw_ostream &Out, const DISubrange *N,
Out << ")";
}
-static void writeDIGenericSubrange(raw_ostream &Out, const DIGenericSubrange *N,
- TypePrinting *TypePrinter,
- SlotTracker *Machine,
- const Module *Context) {
- Out << "!DIGenericSubrange(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
-
- auto IsConstant = [&](Metadata *Bound) -> bool {
- if (auto *BE = dyn_cast_or_null<DIExpression>(Bound)) {
- return BE->isSignedConstant();
- }
- return false;
- };
-
- auto GetConstant = [&](Metadata *Bound) -> int64_t {
- assert(IsConstant(Bound) && "Expected constant");
- auto *BE = dyn_cast_or_null<DIExpression>(Bound);
- return static_cast<int64_t>(BE->getElement(1));
- };
-
- auto *Count = N->getRawCountNode();
- if (IsConstant(Count))
- Printer.printInt("count", GetConstant(Count),
- /* ShouldSkipZero */ false);
- else
- Printer.printMetadata("count", Count, /*ShouldSkipNull */ true);
-
- auto *LBound = N->getRawLowerBound();
- if (IsConstant(LBound))
- Printer.printInt("lowerBound", GetConstant(LBound),
- /* ShouldSkipZero */ false);
- else
- Printer.printMetadata("lowerBound", LBound, /*ShouldSkipNull */ true);
-
- auto *UBound = N->getRawUpperBound();
- if (IsConstant(UBound))
- Printer.printInt("upperBound", GetConstant(UBound),
- /* ShouldSkipZero */ false);
- else
- Printer.printMetadata("upperBound", UBound, /*ShouldSkipNull */ true);
-
- auto *Stride = N->getRawStride();
- if (IsConstant(Stride))
- Printer.printInt("stride", GetConstant(Stride),
- /* ShouldSkipZero */ false);
- else
- Printer.printMetadata("stride", Stride, /*ShouldSkipNull */ true);
-
- Out << ")";
-}
-
+static void writeDIGenericSubrange(raw_ostream &Out, const DIGenericSubrange *N,
+ TypePrinting *TypePrinter,
+ SlotTracker *Machine,
+ const Module *Context) {
+ Out << "!DIGenericSubrange(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+
+ auto IsConstant = [&](Metadata *Bound) -> bool {
+ if (auto *BE = dyn_cast_or_null<DIExpression>(Bound)) {
+ return BE->isSignedConstant();
+ }
+ return false;
+ };
+
+ auto GetConstant = [&](Metadata *Bound) -> int64_t {
+ assert(IsConstant(Bound) && "Expected constant");
+ auto *BE = dyn_cast_or_null<DIExpression>(Bound);
+ return static_cast<int64_t>(BE->getElement(1));
+ };
+
+ auto *Count = N->getRawCountNode();
+ if (IsConstant(Count))
+ Printer.printInt("count", GetConstant(Count),
+ /* ShouldSkipZero */ false);
+ else
+ Printer.printMetadata("count", Count, /*ShouldSkipNull */ true);
+
+ auto *LBound = N->getRawLowerBound();
+ if (IsConstant(LBound))
+ Printer.printInt("lowerBound", GetConstant(LBound),
+ /* ShouldSkipZero */ false);
+ else
+ Printer.printMetadata("lowerBound", LBound, /*ShouldSkipNull */ true);
+
+ auto *UBound = N->getRawUpperBound();
+ if (IsConstant(UBound))
+ Printer.printInt("upperBound", GetConstant(UBound),
+ /* ShouldSkipZero */ false);
+ else
+ Printer.printMetadata("upperBound", UBound, /*ShouldSkipNull */ true);
+
+ auto *Stride = N->getRawStride();
+ if (IsConstant(Stride))
+ Printer.printInt("stride", GetConstant(Stride),
+ /* ShouldSkipZero */ false);
+ else
+ Printer.printMetadata("stride", Stride, /*ShouldSkipNull */ true);
+
+ Out << ")";
+}
+
static void writeDIEnumerator(raw_ostream &Out, const DIEnumerator *N,
TypePrinting *, SlotTracker *, const Module *) {
Out << "!DIEnumerator(";
@@ -2001,23 +2001,23 @@ static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N,
Out << ")";
}
-static void writeDIStringType(raw_ostream &Out, const DIStringType *N,
- TypePrinting *TypePrinter, SlotTracker *Machine,
- const Module *Context) {
- Out << "!DIStringType(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
- if (N->getTag() != dwarf::DW_TAG_string_type)
- Printer.printTag(N);
- Printer.printString("name", N->getName());
- Printer.printMetadata("stringLength", N->getRawStringLength());
- Printer.printMetadata("stringLengthExpression", N->getRawStringLengthExp());
- Printer.printInt("size", N->getSizeInBits());
- Printer.printInt("align", N->getAlignInBits());
- Printer.printDwarfEnum("encoding", N->getEncoding(),
- dwarf::AttributeEncodingString);
- Out << ")";
-}
-
+static void writeDIStringType(raw_ostream &Out, const DIStringType *N,
+ TypePrinting *TypePrinter, SlotTracker *Machine,
+ const Module *Context) {
+ Out << "!DIStringType(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ if (N->getTag() != dwarf::DW_TAG_string_type)
+ Printer.printTag(N);
+ Printer.printString("name", N->getName());
+ Printer.printMetadata("stringLength", N->getRawStringLength());
+ Printer.printMetadata("stringLengthExpression", N->getRawStringLengthExp());
+ Printer.printInt("size", N->getSizeInBits());
+ Printer.printInt("align", N->getAlignInBits());
+ Printer.printDwarfEnum("encoding", N->getEncoding(),
+ dwarf::AttributeEncodingString);
+ Out << ")";
+}
+
static void writeDIDerivedType(raw_ostream &Out, const DIDerivedType *N,
TypePrinting *TypePrinter, SlotTracker *Machine,
const Module *Context) {
@@ -2064,13 +2064,13 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
Printer.printString("identifier", N->getIdentifier());
Printer.printMetadata("discriminator", N->getRawDiscriminator());
Printer.printMetadata("dataLocation", N->getRawDataLocation());
- Printer.printMetadata("associated", N->getRawAssociated());
- Printer.printMetadata("allocated", N->getRawAllocated());
- if (auto *RankConst = N->getRankConst())
- Printer.printInt("rank", RankConst->getSExtValue(),
- /* ShouldSkipZero */ false);
- else
- Printer.printMetadata("rank", N->getRawRank(), /*ShouldSkipNull */ true);
+ Printer.printMetadata("associated", N->getRawAssociated());
+ Printer.printMetadata("allocated", N->getRawAllocated());
+ if (auto *RankConst = N->getRankConst())
+ Printer.printInt("rank", RankConst->getSExtValue(),
+ /* ShouldSkipZero */ false);
+ else
+ Printer.printMetadata("rank", N->getRawRank(), /*ShouldSkipNull */ true);
Out << ")";
}
@@ -2245,7 +2245,7 @@ static void writeDIModule(raw_ostream &Out, const DIModule *N,
Printer.printString("apinotes", N->getAPINotesFile());
Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLineNo());
- Printer.printBool("isDecl", N->getIsDecl(), /* Default */ false);
+ Printer.printBool("isDecl", N->getIsDecl(), /* Default */ false);
Out << ")";
}
@@ -3197,7 +3197,7 @@ void AssemblyWriter::printFunctionSummary(const FunctionSummary *FS) {
printTypeIdInfo(*TIdInfo);
auto PrintRange = [&](const ConstantRange &Range) {
- Out << "[" << Range.getSignedMin() << ", " << Range.getSignedMax() << "]";
+ Out << "[" << Range.getSignedMin() << ", " << Range.getSignedMax() << "]";
};
if (!FS->paramAccesses().empty()) {
@@ -3213,7 +3213,7 @@ void AssemblyWriter::printFunctionSummary(const FunctionSummary *FS) {
FieldSeparator IFS;
for (auto &Call : PS.Calls) {
Out << IFS;
- Out << "(callee: ^" << Machine.getGUIDSlot(Call.Callee.getGUID());
+ Out << "(callee: ^" << Machine.getGUIDSlot(Call.Callee.getGUID());
Out << ", param: " << Call.ParamNo;
Out << ", offset: ";
PrintRange(Call.Offsets);
@@ -4379,17 +4379,17 @@ void AssemblyWriter::writeAttribute(const Attribute &Attr, bool InAttrGroup) {
}
assert((Attr.hasAttribute(Attribute::ByVal) ||
- Attr.hasAttribute(Attribute::StructRet) ||
- Attr.hasAttribute(Attribute::ByRef) ||
+ Attr.hasAttribute(Attribute::StructRet) ||
+ Attr.hasAttribute(Attribute::ByRef) ||
Attr.hasAttribute(Attribute::Preallocated)) &&
"unexpected type attr");
if (Attr.hasAttribute(Attribute::ByVal)) {
Out << "byval";
- } else if (Attr.hasAttribute(Attribute::StructRet)) {
- Out << "sret";
- } else if (Attr.hasAttribute(Attribute::ByRef)) {
- Out << "byref";
+ } else if (Attr.hasAttribute(Attribute::StructRet)) {
+ Out << "sret";
+ } else if (Attr.hasAttribute(Attribute::ByRef)) {
+ Out << "byref";
} else {
Out << "preallocated";
}
@@ -4482,7 +4482,7 @@ void Function::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
void BasicBlock::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
bool ShouldPreserveUseListOrder,
bool IsForDebug) const {
- SlotTracker SlotTable(this->getParent());
+ SlotTracker SlotTable(this->getParent());
formatted_raw_ostream OS(ROS);
AssemblyWriter W(OS, SlotTable, this->getModule(), AAW,
IsForDebug,
diff --git a/contrib/libs/llvm12/lib/IR/Assumptions.cpp b/contrib/libs/llvm12/lib/IR/Assumptions.cpp
index 8e6ee41993..1bd8b7f51e 100644
--- a/contrib/libs/llvm12/lib/IR/Assumptions.cpp
+++ b/contrib/libs/llvm12/lib/IR/Assumptions.cpp
@@ -1,36 +1,36 @@
-//===- Assumptions.cpp ------ Collection of helpers for assumptions -------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/IR/Assumptions.h"
-#include "llvm/IR/Attributes.h"
-#include "llvm/IR/Function.h"
-
-using namespace llvm;
-
-bool llvm::hasAssumption(Function &F,
- const KnownAssumptionString &AssumptionStr) {
- const Attribute &A = F.getFnAttribute(AssumptionAttrKey);
- if (!A.isValid())
- return false;
- assert(A.isStringAttribute() && "Expected a string attribute!");
-
- SmallVector<StringRef, 8> Strings;
- A.getValueAsString().split(Strings, ",");
-
- return llvm::any_of(Strings, [=](StringRef Assumption) {
- return Assumption == AssumptionStr;
- });
-}
-
-StringSet<> llvm::KnownAssumptionStrings({
- "omp_no_openmp", // OpenMP 5.1
- "omp_no_openmp_routines", // OpenMP 5.1
- "omp_no_parallelism", // OpenMP 5.1
-});
+//===- Assumptions.cpp ------ Collection of helpers for assumptions -------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/Assumptions.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Function.h"
+
+using namespace llvm;
+
+bool llvm::hasAssumption(Function &F,
+ const KnownAssumptionString &AssumptionStr) {
+ const Attribute &A = F.getFnAttribute(AssumptionAttrKey);
+ if (!A.isValid())
+ return false;
+ assert(A.isStringAttribute() && "Expected a string attribute!");
+
+ SmallVector<StringRef, 8> Strings;
+ A.getValueAsString().split(Strings, ",");
+
+ return llvm::any_of(Strings, [=](StringRef Assumption) {
+ return Assumption == AssumptionStr;
+ });
+}
+
+StringSet<> llvm::KnownAssumptionStrings({
+ "omp_no_openmp", // OpenMP 5.1
+ "omp_no_openmp_routines", // OpenMP 5.1
+ "omp_no_parallelism", // OpenMP 5.1
+});
diff --git a/contrib/libs/llvm12/lib/IR/AttributeImpl.h b/contrib/libs/llvm12/lib/IR/AttributeImpl.h
index 9bf9574c8a..c69fe3fe08 100644
--- a/contrib/libs/llvm12/lib/IR/AttributeImpl.h
+++ b/contrib/libs/llvm12/lib/IR/AttributeImpl.h
@@ -121,10 +121,10 @@ protected:
public:
EnumAttributeImpl(Attribute::AttrKind Kind)
- : AttributeImpl(EnumAttrEntry), Kind(Kind) {
- assert(Kind != Attribute::AttrKind::None &&
- "Can't create a None attribute!");
- }
+ : AttributeImpl(EnumAttrEntry), Kind(Kind) {
+ assert(Kind != Attribute::AttrKind::None &&
+ "Can't create a None attribute!");
+ }
Attribute::AttrKind getEnumKind() const { return Kind; }
};
@@ -254,8 +254,8 @@ public:
std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
std::string getAsString(bool InAttrGrp) const;
Type *getByValType() const;
- Type *getStructRetType() const;
- Type *getByRefType() const;
+ Type *getStructRetType() const;
+ Type *getByRefType() const;
Type *getPreallocatedType() const;
using iterator = const Attribute *;
diff --git a/contrib/libs/llvm12/lib/IR/Attributes.cpp b/contrib/libs/llvm12/lib/IR/Attributes.cpp
index 58e23c7885..c4629decc6 100644
--- a/contrib/libs/llvm12/lib/IR/Attributes.cpp
+++ b/contrib/libs/llvm12/lib/IR/Attributes.cpp
@@ -172,14 +172,14 @@ Attribute Attribute::getWithByValType(LLVMContext &Context, Type *Ty) {
return get(Context, ByVal, Ty);
}
-Attribute Attribute::getWithStructRetType(LLVMContext &Context, Type *Ty) {
- return get(Context, StructRet, Ty);
-}
-
-Attribute Attribute::getWithByRefType(LLVMContext &Context, Type *Ty) {
- return get(Context, ByRef, Ty);
-}
-
+Attribute Attribute::getWithStructRetType(LLVMContext &Context, Type *Ty) {
+ return get(Context, StructRet, Ty);
+}
+
+Attribute Attribute::getWithByRefType(LLVMContext &Context, Type *Ty) {
+ return get(Context, ByRef, Ty);
+}
+
Attribute Attribute::getWithPreallocatedType(LLVMContext &Context, Type *Ty) {
return get(Context, Preallocated, Ty);
}
@@ -371,8 +371,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
return "noalias";
if (hasAttribute(Attribute::NoBuiltin))
return "nobuiltin";
- if (hasAttribute(Attribute::NoCallback))
- return "nocallback";
+ if (hasAttribute(Attribute::NoCallback))
+ return "nocallback";
if (hasAttribute(Attribute::NoCapture))
return "nocapture";
if (hasAttribute(Attribute::NoDuplicate))
@@ -403,8 +403,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
return "nocf_check";
if (hasAttribute(Attribute::NoRecurse))
return "norecurse";
- if (hasAttribute(Attribute::NoProfile))
- return "noprofile";
+ if (hasAttribute(Attribute::NoProfile))
+ return "noprofile";
if (hasAttribute(Attribute::NoUnwind))
return "nounwind";
if (hasAttribute(Attribute::OptForFuzzing))
@@ -451,19 +451,19 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
return "zeroext";
if (hasAttribute(Attribute::Cold))
return "cold";
- if (hasAttribute(Attribute::Hot))
- return "hot";
+ if (hasAttribute(Attribute::Hot))
+ return "hot";
if (hasAttribute(Attribute::ImmArg))
return "immarg";
if (hasAttribute(Attribute::NoUndef))
return "noundef";
- if (hasAttribute(Attribute::MustProgress))
- return "mustprogress";
+ if (hasAttribute(Attribute::MustProgress))
+ return "mustprogress";
- const bool IsByVal = hasAttribute(Attribute::ByVal);
- if (IsByVal || hasAttribute(Attribute::StructRet)) {
+ const bool IsByVal = hasAttribute(Attribute::ByVal);
+ if (IsByVal || hasAttribute(Attribute::StructRet)) {
std::string Result;
- Result += IsByVal ? "byval" : "sret";
+ Result += IsByVal ? "byval" : "sret";
if (Type *Ty = getValueAsType()) {
raw_string_ostream OS(Result);
Result += '(';
@@ -474,9 +474,9 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
return Result;
}
- const bool IsByRef = hasAttribute(Attribute::ByRef);
- if (IsByRef || hasAttribute(Attribute::Preallocated)) {
- std::string Result = IsByRef ? "byref" : "preallocated";
+ const bool IsByRef = hasAttribute(Attribute::ByRef);
+ if (IsByRef || hasAttribute(Attribute::Preallocated)) {
+ std::string Result = IsByRef ? "byref" : "preallocated";
raw_string_ostream OS(Result);
Result += '(';
getValueAsType()->print(OS, false, true);
@@ -757,18 +757,18 @@ uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
}
-Type *AttributeSet::getByRefType() const {
- return SetNode ? SetNode->getByRefType() : nullptr;
-}
-
+Type *AttributeSet::getByRefType() const {
+ return SetNode ? SetNode->getByRefType() : nullptr;
+}
+
Type *AttributeSet::getByValType() const {
return SetNode ? SetNode->getByValType() : nullptr;
}
-Type *AttributeSet::getStructRetType() const {
- return SetNode ? SetNode->getStructRetType() : nullptr;
-}
-
+Type *AttributeSet::getStructRetType() const {
+ return SetNode ? SetNode->getStructRetType() : nullptr;
+}
+
Type *AttributeSet::getPreallocatedType() const {
return SetNode ? SetNode->getPreallocatedType() : nullptr;
}
@@ -865,12 +865,12 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) {
case Attribute::ByVal:
Attr = Attribute::getWithByValType(C, B.getByValType());
break;
- case Attribute::StructRet:
- Attr = Attribute::getWithStructRetType(C, B.getStructRetType());
- break;
- case Attribute::ByRef:
- Attr = Attribute::getWithByRefType(C, B.getByRefType());
- break;
+ case Attribute::StructRet:
+ Attr = Attribute::getWithStructRetType(C, B.getStructRetType());
+ break;
+ case Attribute::ByRef:
+ Attr = Attribute::getWithByRefType(C, B.getByRefType());
+ break;
case Attribute::Preallocated:
Attr = Attribute::getWithPreallocatedType(C, B.getPreallocatedType());
break;
@@ -954,25 +954,25 @@ MaybeAlign AttributeSetNode::getStackAlignment() const {
Type *AttributeSetNode::getByValType() const {
if (auto A = findEnumAttribute(Attribute::ByVal))
return A->getValueAsType();
- return nullptr;
-}
-
-Type *AttributeSetNode::getStructRetType() const {
- if (auto A = findEnumAttribute(Attribute::StructRet))
- return A->getValueAsType();
- return nullptr;
-}
-
-Type *AttributeSetNode::getByRefType() const {
- if (auto A = findEnumAttribute(Attribute::ByRef))
- return A->getValueAsType();
- return nullptr;
-}
-
+ return nullptr;
+}
+
+Type *AttributeSetNode::getStructRetType() const {
+ if (auto A = findEnumAttribute(Attribute::StructRet))
+ return A->getValueAsType();
+ return nullptr;
+}
+
+Type *AttributeSetNode::getByRefType() const {
+ if (auto A = findEnumAttribute(Attribute::ByRef))
+ return A->getValueAsType();
+ return nullptr;
+}
+
Type *AttributeSetNode::getPreallocatedType() const {
- if (auto A = findEnumAttribute(Attribute::Preallocated))
- return A->getValueAsType();
- return nullptr;
+ if (auto A = findEnumAttribute(Attribute::Preallocated))
+ return A->getValueAsType();
+ return nullptr;
}
uint64_t AttributeSetNode::getDereferenceableBytes() const {
@@ -1010,7 +1010,7 @@ std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
/// Map from AttributeList index to the internal array index. Adding one happens
/// to work, because -1 wraps around to 0.
-static unsigned attrIdxToArrayIdx(unsigned Index) {
+static unsigned attrIdxToArrayIdx(unsigned Index) {
return Index + 1;
}
@@ -1023,7 +1023,7 @@ AttributeListImpl::AttributeListImpl(ArrayRef<AttributeSet> Sets)
// Initialize AvailableFunctionAttrs and AvailableSomewhereAttrs
// summary bitsets.
- for (const auto &I : Sets[attrIdxToArrayIdx(AttributeList::FunctionIndex)])
+ for (const auto &I : Sets[attrIdxToArrayIdx(AttributeList::FunctionIndex)])
if (!I.isStringAttribute())
AvailableFunctionAttrs.addAttribute(I.getKindAsEnum());
@@ -1111,10 +1111,10 @@ AttributeList::get(LLVMContext &C,
return LHS.first < RHS.first;
}) &&
"Misordered Attributes list!");
- assert(llvm::all_of(Attrs,
- [](const std::pair<unsigned, Attribute> &Pair) {
- return Pair.second.isValid();
- }) &&
+ assert(llvm::all_of(Attrs,
+ [](const std::pair<unsigned, Attribute> &Pair) {
+ return Pair.second.isValid();
+ }) &&
"Pointless attribute!");
// Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
@@ -1202,7 +1202,7 @@ AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs,
if (NumSets > 2) {
// Drop the empty argument attribute sets at the end.
ArgAttrs = ArgAttrs.take_front(NumSets - 2);
- llvm::append_range(AttrSets, ArgAttrs);
+ llvm::append_range(AttrSets, ArgAttrs);
}
return getImpl(C, AttrSets);
@@ -1274,11 +1274,11 @@ AttributeList AttributeList::get(LLVMContext &C,
AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
Attribute::AttrKind Kind) const {
if (hasAttribute(Index, Kind)) return *this;
- AttributeSet Attrs = getAttributes(Index);
- // TODO: Insert at correct position and avoid sort.
- SmallVector<Attribute, 8> NewAttrs(Attrs.begin(), Attrs.end());
- NewAttrs.push_back(Attribute::get(C, Kind));
- return setAttributes(C, Index, AttributeSet::get(C, NewAttrs));
+ AttributeSet Attrs = getAttributes(Index);
+ // TODO: Insert at correct position and avoid sort.
+ SmallVector<Attribute, 8> NewAttrs(Attrs.begin(), Attrs.end());
+ NewAttrs.push_back(Attribute::get(C, Kind));
+ return setAttributes(C, Index, AttributeSet::get(C, NewAttrs));
}
AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
@@ -1296,16 +1296,16 @@ AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
return addAttributes(C, Index, B);
}
-AttributeList AttributeList::setAttributes(LLVMContext &C, unsigned Index,
- AttributeSet Attrs) const {
- Index = attrIdxToArrayIdx(Index);
- SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
- if (Index >= AttrSets.size())
- AttrSets.resize(Index + 1);
- AttrSets[Index] = Attrs;
- return AttributeList::getImpl(C, AttrSets);
-}
-
+AttributeList AttributeList::setAttributes(LLVMContext &C, unsigned Index,
+ AttributeSet Attrs) const {
+ Index = attrIdxToArrayIdx(Index);
+ SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
+ if (Index >= AttrSets.size())
+ AttrSets.resize(Index + 1);
+ AttrSets[Index] = Attrs;
+ return AttributeList::getImpl(C, AttrSets);
+}
+
AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
const AttrBuilder &B) const {
if (!B.hasAttributes())
@@ -1323,9 +1323,9 @@ AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
"Attempt to change alignment!");
#endif
- AttrBuilder Merged(getAttributes(Index));
+ AttrBuilder Merged(getAttributes(Index));
Merged.merge(B);
- return setAttributes(C, Index, AttributeSet::get(C, Merged));
+ return setAttributes(C, Index, AttributeSet::get(C, Merged));
}
AttributeList AttributeList::addParamAttribute(LLVMContext &C,
@@ -1495,14 +1495,14 @@ Type *AttributeList::getParamByValType(unsigned Index) const {
return getAttributes(Index+FirstArgIndex).getByValType();
}
-Type *AttributeList::getParamStructRetType(unsigned Index) const {
- return getAttributes(Index + FirstArgIndex).getStructRetType();
-}
-
-Type *AttributeList::getParamByRefType(unsigned Index) const {
- return getAttributes(Index + FirstArgIndex).getByRefType();
-}
-
+Type *AttributeList::getParamStructRetType(unsigned Index) const {
+ return getAttributes(Index + FirstArgIndex).getStructRetType();
+}
+
+Type *AttributeList::getParamByRefType(unsigned Index) const {
+ return getAttributes(Index + FirstArgIndex).getByRefType();
+}
+
Type *AttributeList::getParamPreallocatedType(unsigned Index) const {
return getAttributes(Index + FirstArgIndex).getPreallocatedType();
}
@@ -1588,8 +1588,8 @@ void AttrBuilder::clear() {
DerefBytes = DerefOrNullBytes = 0;
AllocSizeArgs = 0;
ByValType = nullptr;
- StructRetType = nullptr;
- ByRefType = nullptr;
+ StructRetType = nullptr;
+ ByRefType = nullptr;
PreallocatedType = nullptr;
}
@@ -1608,10 +1608,10 @@ AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
StackAlignment = Attr.getStackAlignment();
else if (Kind == Attribute::ByVal)
ByValType = Attr.getValueAsType();
- else if (Kind == Attribute::StructRet)
- StructRetType = Attr.getValueAsType();
- else if (Kind == Attribute::ByRef)
- ByRefType = Attr.getValueAsType();
+ else if (Kind == Attribute::StructRet)
+ StructRetType = Attr.getValueAsType();
+ else if (Kind == Attribute::ByRef)
+ ByRefType = Attr.getValueAsType();
else if (Kind == Attribute::Preallocated)
PreallocatedType = Attr.getValueAsType();
else if (Kind == Attribute::Dereferenceable)
@@ -1638,10 +1638,10 @@ AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
StackAlignment.reset();
else if (Val == Attribute::ByVal)
ByValType = nullptr;
- else if (Val == Attribute::StructRet)
- StructRetType = nullptr;
- else if (Val == Attribute::ByRef)
- ByRefType = nullptr;
+ else if (Val == Attribute::StructRet)
+ StructRetType = nullptr;
+ else if (Val == Attribute::ByRef)
+ ByRefType = nullptr;
else if (Val == Attribute::Preallocated)
PreallocatedType = nullptr;
else if (Val == Attribute::Dereferenceable)
@@ -1732,18 +1732,18 @@ AttrBuilder &AttrBuilder::addByValAttr(Type *Ty) {
return *this;
}
-AttrBuilder &AttrBuilder::addStructRetAttr(Type *Ty) {
- Attrs[Attribute::StructRet] = true;
- StructRetType = Ty;
- return *this;
-}
-
-AttrBuilder &AttrBuilder::addByRefAttr(Type *Ty) {
- Attrs[Attribute::ByRef] = true;
- ByRefType = Ty;
- return *this;
-}
-
+AttrBuilder &AttrBuilder::addStructRetAttr(Type *Ty) {
+ Attrs[Attribute::StructRet] = true;
+ StructRetType = Ty;
+ return *this;
+}
+
+AttrBuilder &AttrBuilder::addByRefAttr(Type *Ty) {
+ Attrs[Attribute::ByRef] = true;
+ ByRefType = Ty;
+ return *this;
+}
+
AttrBuilder &AttrBuilder::addPreallocatedAttr(Type *Ty) {
Attrs[Attribute::Preallocated] = true;
PreallocatedType = Ty;
@@ -1770,12 +1770,12 @@ AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
if (!ByValType)
ByValType = B.ByValType;
- if (!StructRetType)
- StructRetType = B.StructRetType;
-
- if (!ByRefType)
- ByRefType = B.ByRefType;
-
+ if (!StructRetType)
+ StructRetType = B.StructRetType;
+
+ if (!ByRefType)
+ ByRefType = B.ByRefType;
+
if (!PreallocatedType)
PreallocatedType = B.PreallocatedType;
@@ -1807,12 +1807,12 @@ AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) {
if (B.ByValType)
ByValType = nullptr;
- if (B.StructRetType)
- StructRetType = nullptr;
-
- if (B.ByRefType)
- ByRefType = nullptr;
-
+ if (B.StructRetType)
+ StructRetType = nullptr;
+
+ if (B.ByRefType)
+ ByRefType = nullptr;
+
if (B.PreallocatedType)
PreallocatedType = nullptr;
@@ -1876,7 +1876,7 @@ bool AttrBuilder::operator==(const AttrBuilder &B) const {
return Alignment == B.Alignment && StackAlignment == B.StackAlignment &&
DerefBytes == B.DerefBytes && ByValType == B.ByValType &&
- StructRetType == B.StructRetType && ByRefType == B.ByRefType &&
+ StructRetType == B.StructRetType && ByRefType == B.ByRefType &&
PreallocatedType == B.PreallocatedType;
}
@@ -1899,21 +1899,21 @@ AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
.addAttribute(Attribute::NoAlias)
.addAttribute(Attribute::NoCapture)
.addAttribute(Attribute::NonNull)
- .addAlignmentAttr(1) // the int here is ignored
+ .addAlignmentAttr(1) // the int here is ignored
.addDereferenceableAttr(1) // the int here is ignored
.addDereferenceableOrNullAttr(1) // the int here is ignored
.addAttribute(Attribute::ReadNone)
.addAttribute(Attribute::ReadOnly)
.addAttribute(Attribute::InAlloca)
.addPreallocatedAttr(Ty)
- .addByValAttr(Ty)
- .addStructRetAttr(Ty)
- .addByRefAttr(Ty);
-
- // Some attributes can apply to all "values" but there are no `void` values.
- if (Ty->isVoidTy())
- Incompatible.addAttribute(Attribute::NoUndef);
-
+ .addByValAttr(Ty)
+ .addStructRetAttr(Ty)
+ .addByRefAttr(Ty);
+
+ // Some attributes can apply to all "values" but there are no `void` values.
+ if (Ty->isVoidTy())
+ Incompatible.addAttribute(Attribute::NoUndef);
+
return Incompatible;
}
@@ -1950,16 +1950,16 @@ static void setOR(Function &Caller, const Function &Callee) {
/// If the inlined function had a higher stack protection level than the
/// calling function, then bump up the caller's stack protection level.
static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
-#ifndef NDEBUG
- if (!Callee.hasFnAttribute(Attribute::AlwaysInline)) {
- assert(!(!Callee.hasStackProtectorFnAttr() &&
- Caller.hasStackProtectorFnAttr()) &&
- "stack protected caller but callee requested no stack protector");
- assert(!(!Caller.hasStackProtectorFnAttr() &&
- Callee.hasStackProtectorFnAttr()) &&
- "stack protected callee but caller requested no stack protector");
- }
-#endif
+#ifndef NDEBUG
+ if (!Callee.hasFnAttribute(Attribute::AlwaysInline)) {
+ assert(!(!Callee.hasStackProtectorFnAttr() &&
+ Caller.hasStackProtectorFnAttr()) &&
+ "stack protected caller but callee requested no stack protector");
+ assert(!(!Caller.hasStackProtectorFnAttr() &&
+ Callee.hasStackProtectorFnAttr()) &&
+ "stack protected callee but caller requested no stack protector");
+ }
+#endif
// If upgrading the SSP attribute, clear out the old SSP Attributes first.
// Having multiple SSP attributes doesn't actually hurt, but it adds useless
// clutter to the IR.
@@ -1995,19 +1995,19 @@ static void adjustCallerStackProbes(Function &Caller, const Function &Callee) {
/// that is no larger.
static void
adjustCallerStackProbeSize(Function &Caller, const Function &Callee) {
- Attribute CalleeAttr = Callee.getFnAttribute("stack-probe-size");
- if (CalleeAttr.isValid()) {
- Attribute CallerAttr = Caller.getFnAttribute("stack-probe-size");
- if (CallerAttr.isValid()) {
- uint64_t CallerStackProbeSize, CalleeStackProbeSize;
- CallerAttr.getValueAsString().getAsInteger(0, CallerStackProbeSize);
- CalleeAttr.getValueAsString().getAsInteger(0, CalleeStackProbeSize);
-
+ Attribute CalleeAttr = Callee.getFnAttribute("stack-probe-size");
+ if (CalleeAttr.isValid()) {
+ Attribute CallerAttr = Caller.getFnAttribute("stack-probe-size");
+ if (CallerAttr.isValid()) {
+ uint64_t CallerStackProbeSize, CalleeStackProbeSize;
+ CallerAttr.getValueAsString().getAsInteger(0, CallerStackProbeSize);
+ CalleeAttr.getValueAsString().getAsInteger(0, CalleeStackProbeSize);
+
if (CallerStackProbeSize > CalleeStackProbeSize) {
- Caller.addFnAttr(CalleeAttr);
+ Caller.addFnAttr(CalleeAttr);
}
} else {
- Caller.addFnAttr(CalleeAttr);
+ Caller.addFnAttr(CalleeAttr);
}
}
}
@@ -2023,15 +2023,15 @@ adjustCallerStackProbeSize(Function &Caller, const Function &Callee) {
/// handled as part of inline cost analysis.
static void
adjustMinLegalVectorWidth(Function &Caller, const Function &Callee) {
- Attribute CallerAttr = Caller.getFnAttribute("min-legal-vector-width");
- if (CallerAttr.isValid()) {
- Attribute CalleeAttr = Callee.getFnAttribute("min-legal-vector-width");
- if (CalleeAttr.isValid()) {
- uint64_t CallerVectorWidth, CalleeVectorWidth;
- CallerAttr.getValueAsString().getAsInteger(0, CallerVectorWidth);
- CalleeAttr.getValueAsString().getAsInteger(0, CalleeVectorWidth);
+ Attribute CallerAttr = Caller.getFnAttribute("min-legal-vector-width");
+ if (CallerAttr.isValid()) {
+ Attribute CalleeAttr = Callee.getFnAttribute("min-legal-vector-width");
+ if (CalleeAttr.isValid()) {
+ uint64_t CallerVectorWidth, CalleeVectorWidth;
+ CallerAttr.getValueAsString().getAsInteger(0, CallerVectorWidth);
+ CalleeAttr.getValueAsString().getAsInteger(0, CalleeVectorWidth);
if (CallerVectorWidth < CalleeVectorWidth)
- Caller.addFnAttr(CalleeAttr);
+ Caller.addFnAttr(CalleeAttr);
} else {
// If the callee doesn't have the attribute then we don't know anything
// and must drop the attribute from the caller.
@@ -2098,25 +2098,25 @@ bool AttributeFuncs::areInlineCompatible(const Function &Caller,
return hasCompatibleFnAttrs(Caller, Callee);
}
-bool AttributeFuncs::areOutlineCompatible(const Function &A,
- const Function &B) {
- return hasCompatibleFnAttrs(A, B);
-}
-
+bool AttributeFuncs::areOutlineCompatible(const Function &A,
+ const Function &B) {
+ return hasCompatibleFnAttrs(A, B);
+}
+
void AttributeFuncs::mergeAttributesForInlining(Function &Caller,
const Function &Callee) {
mergeFnAttrs(Caller, Callee);
}
-
-void AttributeFuncs::mergeAttributesForOutlining(Function &Base,
- const Function &ToMerge) {
-
- // We merge functions so that they meet the most general case.
- // For example, if the NoNansFPMathAttr is set in one function, but not in
- // the other, in the merged function we can say that the NoNansFPMathAttr
- // is not set.
- // However if we have the SpeculativeLoadHardeningAttr set true in one
- // function, but not the other, we make sure that the function retains
- // that aspect in the merged function.
- mergeFnAttrs(Base, ToMerge);
-}
+
+void AttributeFuncs::mergeAttributesForOutlining(Function &Base,
+ const Function &ToMerge) {
+
+ // We merge functions so that they meet the most general case.
+ // For example, if the NoNansFPMathAttr is set in one function, but not in
+ // the other, in the merged function we can say that the NoNansFPMathAttr
+ // is not set.
+ // However if we have the SpeculativeLoadHardeningAttr set true in one
+ // function, but not the other, we make sure that the function retains
+ // that aspect in the merged function.
+ mergeFnAttrs(Base, ToMerge);
+}
diff --git a/contrib/libs/llvm12/lib/IR/AutoUpgrade.cpp b/contrib/libs/llvm12/lib/IR/AutoUpgrade.cpp
index bed972c02b..7d83cf5dcf 100644
--- a/contrib/libs/llvm12/lib/IR/AutoUpgrade.cpp
+++ b/contrib/libs/llvm12/lib/IR/AutoUpgrade.cpp
@@ -23,7 +23,7 @@
#include "llvm/IR/Instruction.h"
#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsAArch64.h"
#include "llvm/IR/IntrinsicsARM.h"
#include "llvm/IR/IntrinsicsX86.h"
@@ -69,19 +69,19 @@ static bool UpgradeX86IntrinsicsWith8BitMask(Function *F, Intrinsic::ID IID,
return true;
}
-// Upgrade the declaration of fp compare intrinsics that change return type
-// from scalar to vXi1 mask.
-static bool UpgradeX86MaskedFPCompare(Function *F, Intrinsic::ID IID,
- Function *&NewFn) {
- // Check if the return type is a vector.
- if (F->getReturnType()->isVectorTy())
- return false;
-
- rename(F);
- NewFn = Intrinsic::getDeclaration(F->getParent(), IID);
- return true;
-}
-
+// Upgrade the declaration of fp compare intrinsics that change return type
+// from scalar to vXi1 mask.
+static bool UpgradeX86MaskedFPCompare(Function *F, Intrinsic::ID IID,
+ Function *&NewFn) {
+ // Check if the return type is a vector.
+ if (F->getReturnType()->isVectorTy())
+ return false;
+
+ rename(F);
+ NewFn = Intrinsic::getDeclaration(F->getParent(), IID);
+ return true;
+}
+
static bool ShouldUpgradeX86Intrinsic(Function *F, StringRef Name) {
// All of the intrinsics matches below should be marked with which llvm
// version started autoupgrading them. At some point in the future we would
@@ -255,7 +255,7 @@ static bool ShouldUpgradeX86Intrinsic(Function *F, StringRef Name) {
Name.startswith("avx512.mask.cmp.d") || // Added in 5.0
Name.startswith("avx512.mask.cmp.q") || // Added in 5.0
Name.startswith("avx512.mask.cmp.w") || // Added in 5.0
- Name.startswith("avx512.cmp.p") || // Added in 12.0
+ Name.startswith("avx512.cmp.p") || // Added in 12.0
Name.startswith("avx512.mask.ucmp.") || // Added in 5.0
Name.startswith("avx512.cvtb2mask.") || // Added in 7.0
Name.startswith("avx512.cvtw2mask.") || // Added in 7.0
@@ -470,24 +470,24 @@ static bool UpgradeX86IntrinsicFunction(Function *F, StringRef Name,
if (Name == "avx2.mpsadbw") // Added in 3.6
return UpgradeX86IntrinsicsWith8BitMask(F, Intrinsic::x86_avx2_mpsadbw,
NewFn);
- if (Name == "avx512.mask.cmp.pd.128") // Added in 7.0
- return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_pd_128,
- NewFn);
- if (Name == "avx512.mask.cmp.pd.256") // Added in 7.0
- return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_pd_256,
- NewFn);
- if (Name == "avx512.mask.cmp.pd.512") // Added in 7.0
- return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_pd_512,
- NewFn);
- if (Name == "avx512.mask.cmp.ps.128") // Added in 7.0
- return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_ps_128,
- NewFn);
- if (Name == "avx512.mask.cmp.ps.256") // Added in 7.0
- return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_ps_256,
- NewFn);
- if (Name == "avx512.mask.cmp.ps.512") // Added in 7.0
- return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_ps_512,
- NewFn);
+ if (Name == "avx512.mask.cmp.pd.128") // Added in 7.0
+ return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_pd_128,
+ NewFn);
+ if (Name == "avx512.mask.cmp.pd.256") // Added in 7.0
+ return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_pd_256,
+ NewFn);
+ if (Name == "avx512.mask.cmp.pd.512") // Added in 7.0
+ return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_pd_512,
+ NewFn);
+ if (Name == "avx512.mask.cmp.ps.128") // Added in 7.0
+ return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_ps_128,
+ NewFn);
+ if (Name == "avx512.mask.cmp.ps.256") // Added in 7.0
+ return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_ps_256,
+ NewFn);
+ if (Name == "avx512.mask.cmp.ps.512") // Added in 7.0
+ return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_ps_512,
+ NewFn);
// frcz.ss/sd may need to have an argument dropped. Added in 3.2
if (Name.startswith("xop.vfrcz.ss") && F->arg_size() == 2) {
@@ -633,63 +633,63 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
return true;
}
}
-
- // Changed in 12.0: bfdot accept v4bf16 and v8bf16 instead of v8i8 and v16i8
- // respectively
- if ((Name.startswith("arm.neon.bfdot.") ||
- Name.startswith("aarch64.neon.bfdot.")) &&
- Name.endswith("i8")) {
- Intrinsic::ID IID =
- StringSwitch<Intrinsic::ID>(Name)
- .Cases("arm.neon.bfdot.v2f32.v8i8",
- "arm.neon.bfdot.v4f32.v16i8",
- Intrinsic::arm_neon_bfdot)
- .Cases("aarch64.neon.bfdot.v2f32.v8i8",
- "aarch64.neon.bfdot.v4f32.v16i8",
- Intrinsic::aarch64_neon_bfdot)
- .Default(Intrinsic::not_intrinsic);
- if (IID == Intrinsic::not_intrinsic)
- break;
-
- size_t OperandWidth = F->getReturnType()->getPrimitiveSizeInBits();
- assert((OperandWidth == 64 || OperandWidth == 128) &&
- "Unexpected operand width");
- LLVMContext &Ctx = F->getParent()->getContext();
- std::array<Type *, 2> Tys {{
- F->getReturnType(),
- FixedVectorType::get(Type::getBFloatTy(Ctx), OperandWidth / 16)
- }};
- NewFn = Intrinsic::getDeclaration(F->getParent(), IID, Tys);
- return true;
- }
-
- // Changed in 12.0: bfmmla, bfmlalb and bfmlalt are not polymorphic anymore
- // and accept v8bf16 instead of v16i8
- if ((Name.startswith("arm.neon.bfm") ||
- Name.startswith("aarch64.neon.bfm")) &&
- Name.endswith(".v4f32.v16i8")) {
- Intrinsic::ID IID =
- StringSwitch<Intrinsic::ID>(Name)
- .Case("arm.neon.bfmmla.v4f32.v16i8",
- Intrinsic::arm_neon_bfmmla)
- .Case("arm.neon.bfmlalb.v4f32.v16i8",
- Intrinsic::arm_neon_bfmlalb)
- .Case("arm.neon.bfmlalt.v4f32.v16i8",
- Intrinsic::arm_neon_bfmlalt)
- .Case("aarch64.neon.bfmmla.v4f32.v16i8",
- Intrinsic::aarch64_neon_bfmmla)
- .Case("aarch64.neon.bfmlalb.v4f32.v16i8",
- Intrinsic::aarch64_neon_bfmlalb)
- .Case("aarch64.neon.bfmlalt.v4f32.v16i8",
- Intrinsic::aarch64_neon_bfmlalt)
- .Default(Intrinsic::not_intrinsic);
- if (IID == Intrinsic::not_intrinsic)
- break;
-
- std::array<Type *, 0> Tys;
- NewFn = Intrinsic::getDeclaration(F->getParent(), IID, Tys);
- return true;
- }
+
+ // Changed in 12.0: bfdot accept v4bf16 and v8bf16 instead of v8i8 and v16i8
+ // respectively
+ if ((Name.startswith("arm.neon.bfdot.") ||
+ Name.startswith("aarch64.neon.bfdot.")) &&
+ Name.endswith("i8")) {
+ Intrinsic::ID IID =
+ StringSwitch<Intrinsic::ID>(Name)
+ .Cases("arm.neon.bfdot.v2f32.v8i8",
+ "arm.neon.bfdot.v4f32.v16i8",
+ Intrinsic::arm_neon_bfdot)
+ .Cases("aarch64.neon.bfdot.v2f32.v8i8",
+ "aarch64.neon.bfdot.v4f32.v16i8",
+ Intrinsic::aarch64_neon_bfdot)
+ .Default(Intrinsic::not_intrinsic);
+ if (IID == Intrinsic::not_intrinsic)
+ break;
+
+ size_t OperandWidth = F->getReturnType()->getPrimitiveSizeInBits();
+ assert((OperandWidth == 64 || OperandWidth == 128) &&
+ "Unexpected operand width");
+ LLVMContext &Ctx = F->getParent()->getContext();
+ std::array<Type *, 2> Tys {{
+ F->getReturnType(),
+ FixedVectorType::get(Type::getBFloatTy(Ctx), OperandWidth / 16)
+ }};
+ NewFn = Intrinsic::getDeclaration(F->getParent(), IID, Tys);
+ return true;
+ }
+
+ // Changed in 12.0: bfmmla, bfmlalb and bfmlalt are not polymorphic anymore
+ // and accept v8bf16 instead of v16i8
+ if ((Name.startswith("arm.neon.bfm") ||
+ Name.startswith("aarch64.neon.bfm")) &&
+ Name.endswith(".v4f32.v16i8")) {
+ Intrinsic::ID IID =
+ StringSwitch<Intrinsic::ID>(Name)
+ .Case("arm.neon.bfmmla.v4f32.v16i8",
+ Intrinsic::arm_neon_bfmmla)
+ .Case("arm.neon.bfmlalb.v4f32.v16i8",
+ Intrinsic::arm_neon_bfmlalb)
+ .Case("arm.neon.bfmlalt.v4f32.v16i8",
+ Intrinsic::arm_neon_bfmlalt)
+ .Case("aarch64.neon.bfmmla.v4f32.v16i8",
+ Intrinsic::aarch64_neon_bfmmla)
+ .Case("aarch64.neon.bfmlalb.v4f32.v16i8",
+ Intrinsic::aarch64_neon_bfmlalb)
+ .Case("aarch64.neon.bfmlalt.v4f32.v16i8",
+ Intrinsic::aarch64_neon_bfmlalt)
+ .Default(Intrinsic::not_intrinsic);
+ if (IID == Intrinsic::not_intrinsic)
+ break;
+
+ std::array<Type *, 0> Tys;
+ NewFn = Intrinsic::getDeclaration(F->getParent(), IID, Tys);
+ return true;
+ }
break;
}
@@ -718,42 +718,42 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
}
case 'e': {
SmallVector<StringRef, 2> Groups;
- static const Regex R("^experimental.vector.reduce.([a-z]+)\\.[a-z][0-9]+");
+ static const Regex R("^experimental.vector.reduce.([a-z]+)\\.[a-z][0-9]+");
if (R.match(Name, &Groups)) {
- Intrinsic::ID ID;
- ID = StringSwitch<Intrinsic::ID>(Groups[1])
- .Case("add", Intrinsic::vector_reduce_add)
- .Case("mul", Intrinsic::vector_reduce_mul)
- .Case("and", Intrinsic::vector_reduce_and)
- .Case("or", Intrinsic::vector_reduce_or)
- .Case("xor", Intrinsic::vector_reduce_xor)
- .Case("smax", Intrinsic::vector_reduce_smax)
- .Case("smin", Intrinsic::vector_reduce_smin)
- .Case("umax", Intrinsic::vector_reduce_umax)
- .Case("umin", Intrinsic::vector_reduce_umin)
- .Case("fmax", Intrinsic::vector_reduce_fmax)
- .Case("fmin", Intrinsic::vector_reduce_fmin)
- .Default(Intrinsic::not_intrinsic);
- if (ID != Intrinsic::not_intrinsic) {
- rename(F);
- auto Args = F->getFunctionType()->params();
- NewFn = Intrinsic::getDeclaration(F->getParent(), ID, {Args[0]});
- return true;
- }
- }
- static const Regex R2(
- "^experimental.vector.reduce.v2.([a-z]+)\\.[fi][0-9]+");
- Groups.clear();
- if (R2.match(Name, &Groups)) {
+ Intrinsic::ID ID;
+ ID = StringSwitch<Intrinsic::ID>(Groups[1])
+ .Case("add", Intrinsic::vector_reduce_add)
+ .Case("mul", Intrinsic::vector_reduce_mul)
+ .Case("and", Intrinsic::vector_reduce_and)
+ .Case("or", Intrinsic::vector_reduce_or)
+ .Case("xor", Intrinsic::vector_reduce_xor)
+ .Case("smax", Intrinsic::vector_reduce_smax)
+ .Case("smin", Intrinsic::vector_reduce_smin)
+ .Case("umax", Intrinsic::vector_reduce_umax)
+ .Case("umin", Intrinsic::vector_reduce_umin)
+ .Case("fmax", Intrinsic::vector_reduce_fmax)
+ .Case("fmin", Intrinsic::vector_reduce_fmin)
+ .Default(Intrinsic::not_intrinsic);
+ if (ID != Intrinsic::not_intrinsic) {
+ rename(F);
+ auto Args = F->getFunctionType()->params();
+ NewFn = Intrinsic::getDeclaration(F->getParent(), ID, {Args[0]});
+ return true;
+ }
+ }
+ static const Regex R2(
+ "^experimental.vector.reduce.v2.([a-z]+)\\.[fi][0-9]+");
+ Groups.clear();
+ if (R2.match(Name, &Groups)) {
Intrinsic::ID ID = Intrinsic::not_intrinsic;
if (Groups[1] == "fadd")
- ID = Intrinsic::vector_reduce_fadd;
+ ID = Intrinsic::vector_reduce_fadd;
if (Groups[1] == "fmul")
- ID = Intrinsic::vector_reduce_fmul;
+ ID = Intrinsic::vector_reduce_fmul;
if (ID != Intrinsic::not_intrinsic) {
rename(F);
auto Args = F->getFunctionType()->params();
- Type *Tys[] = {Args[1]};
+ Type *Tys[] = {Args[1]};
NewFn = Intrinsic::getDeclaration(F->getParent(), ID, Tys);
return true;
}
@@ -937,12 +937,12 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
Intrinsic::getDeclaration(F->getParent(), Intrinsic::prefetch, Tys);
return true;
}
- } else if (Name.startswith("ptr.annotation.") && F->arg_size() == 4) {
- rename(F);
- NewFn = Intrinsic::getDeclaration(F->getParent(),
- Intrinsic::ptr_annotation,
- F->arg_begin()->getType());
- return true;
+ } else if (Name.startswith("ptr.annotation.") && F->arg_size() == 4) {
+ rename(F);
+ NewFn = Intrinsic::getDeclaration(F->getParent(),
+ Intrinsic::ptr_annotation,
+ F->arg_begin()->getType());
+ return true;
}
break;
@@ -953,16 +953,16 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
}
break;
- case 'v': {
- if (Name == "var.annotation" && F->arg_size() == 4) {
- rename(F);
- NewFn = Intrinsic::getDeclaration(F->getParent(),
- Intrinsic::var_annotation);
- return true;
- }
- break;
- }
-
+ case 'v': {
+ if (Name == "var.annotation" && F->arg_size() == 4) {
+ rename(F);
+ NewFn = Intrinsic::getDeclaration(F->getParent(),
+ Intrinsic::var_annotation);
+ return true;
+ }
+ break;
+ }
+
case 'x':
if (UpgradeX86IntrinsicFunction(F, Name, NewFn))
return true;
@@ -1029,7 +1029,7 @@ GlobalVariable *llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
// to byte shuffles.
static Value *UpgradeX86PSLLDQIntrinsics(IRBuilder<> &Builder,
Value *Op, unsigned Shift) {
- auto *ResultTy = cast<FixedVectorType>(Op->getType());
+ auto *ResultTy = cast<FixedVectorType>(Op->getType());
unsigned NumElts = ResultTy->getNumElements() * 8;
// Bitcast from a 64-bit element type to a byte element type.
@@ -1063,7 +1063,7 @@ static Value *UpgradeX86PSLLDQIntrinsics(IRBuilder<> &Builder,
// to byte shuffles.
static Value *UpgradeX86PSRLDQIntrinsics(IRBuilder<> &Builder, Value *Op,
unsigned Shift) {
- auto *ResultTy = cast<FixedVectorType>(Op->getType());
+ auto *ResultTy = cast<FixedVectorType>(Op->getType());
unsigned NumElts = ResultTy->getNumElements() * 8;
// Bitcast from a 64-bit element type to a byte element type.
@@ -1095,19 +1095,19 @@ static Value *UpgradeX86PSRLDQIntrinsics(IRBuilder<> &Builder, Value *Op,
static Value *getX86MaskVec(IRBuilder<> &Builder, Value *Mask,
unsigned NumElts) {
- assert(isPowerOf2_32(NumElts) && "Expected power-of-2 mask elements");
+ assert(isPowerOf2_32(NumElts) && "Expected power-of-2 mask elements");
llvm::VectorType *MaskTy = FixedVectorType::get(
Builder.getInt1Ty(), cast<IntegerType>(Mask->getType())->getBitWidth());
Mask = Builder.CreateBitCast(Mask, MaskTy);
- // If we have less than 8 elements (1, 2 or 4), then the starting mask was an
- // i8 and we need to extract down to the right number of elements.
- if (NumElts <= 4) {
+ // If we have less than 8 elements (1, 2 or 4), then the starting mask was an
+ // i8 and we need to extract down to the right number of elements.
+ if (NumElts <= 4) {
int Indices[4];
for (unsigned i = 0; i != NumElts; ++i)
Indices[i] = i;
- Mask = Builder.CreateShuffleVector(
- Mask, Mask, makeArrayRef(Indices, NumElts), "extract");
+ Mask = Builder.CreateShuffleVector(
+ Mask, Mask, makeArrayRef(Indices, NumElts), "extract");
}
return Mask;
@@ -1121,7 +1121,7 @@ static Value *EmitX86Select(IRBuilder<> &Builder, Value *Mask,
return Op0;
Mask = getX86MaskVec(Builder, Mask,
- cast<FixedVectorType>(Op0->getType())->getNumElements());
+ cast<FixedVectorType>(Op0->getType())->getNumElements());
return Builder.CreateSelect(Mask, Op0, Op1);
}
@@ -1148,7 +1148,7 @@ static Value *UpgradeX86ALIGNIntrinsics(IRBuilder<> &Builder, Value *Op0,
bool IsVALIGN) {
unsigned ShiftVal = cast<llvm::ConstantInt>(Shift)->getZExtValue();
- unsigned NumElts = cast<FixedVectorType>(Op0->getType())->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(Op0->getType())->getNumElements();
assert((IsVALIGN || NumElts % 16 == 0) && "Illegal NumElts for PALIGNR!");
assert((!IsVALIGN || NumElts <= 16) && "NumElts too large for VALIGN!");
assert(isPowerOf2_32(NumElts) && "NumElts not a power of 2!");
@@ -1249,8 +1249,8 @@ static Value *UpgradeX86VPERMT2Intrinsics(IRBuilder<> &Builder, CallInst &CI,
return EmitX86Select(Builder, CI.getArgOperand(3), V, PassThru);
}
-static Value *UpgradeX86BinaryIntrinsics(IRBuilder<> &Builder, CallInst &CI,
- Intrinsic::ID IID) {
+static Value *UpgradeX86BinaryIntrinsics(IRBuilder<> &Builder, CallInst &CI,
+ Intrinsic::ID IID) {
Type *Ty = CI.getType();
Value *Op0 = CI.getOperand(0);
Value *Op1 = CI.getOperand(1);
@@ -1275,7 +1275,7 @@ static Value *upgradeX86Rotate(IRBuilder<> &Builder, CallInst &CI,
// Funnel shifts amounts are treated as modulo and types are all power-of-2 so
// we only care about the lowest log2 bits anyway.
if (Amt->getType() != Ty) {
- unsigned NumElts = cast<FixedVectorType>(Ty)->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(Ty)->getNumElements();
Amt = Builder.CreateIntCast(Amt, Ty->getScalarType(), false);
Amt = Builder.CreateVectorSplat(NumElts, Amt);
}
@@ -1345,7 +1345,7 @@ static Value *upgradeX86ConcatShift(IRBuilder<> &Builder, CallInst &CI,
// Funnel shifts amounts are treated as modulo and types are all power-of-2 so
// we only care about the lowest log2 bits anyway.
if (Amt->getType() != Ty) {
- unsigned NumElts = cast<FixedVectorType>(Ty)->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(Ty)->getNumElements();
Amt = Builder.CreateIntCast(Amt, Ty->getScalarType(), false);
Amt = Builder.CreateVectorSplat(NumElts, Amt);
}
@@ -1382,7 +1382,7 @@ static Value *UpgradeMaskedStore(IRBuilder<> &Builder,
return Builder.CreateAlignedStore(Data, Ptr, Alignment);
// Convert the mask from an integer type to a vector of i1.
- unsigned NumElts = cast<FixedVectorType>(Data->getType())->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(Data->getType())->getNumElements();
Mask = getX86MaskVec(Builder, Mask, NumElts);
return Builder.CreateMaskedStore(Data, Ptr, Alignment, Mask);
}
@@ -1405,19 +1405,19 @@ static Value *UpgradeMaskedLoad(IRBuilder<> &Builder,
return Builder.CreateAlignedLoad(ValTy, Ptr, Alignment);
// Convert the mask from an integer type to a vector of i1.
- unsigned NumElts =
- cast<FixedVectorType>(Passthru->getType())->getNumElements();
+ unsigned NumElts =
+ cast<FixedVectorType>(Passthru->getType())->getNumElements();
Mask = getX86MaskVec(Builder, Mask, NumElts);
return Builder.CreateMaskedLoad(Ptr, Alignment, Mask, Passthru);
}
static Value *upgradeAbs(IRBuilder<> &Builder, CallInst &CI) {
- Type *Ty = CI.getType();
+ Type *Ty = CI.getType();
Value *Op0 = CI.getArgOperand(0);
- Function *F = Intrinsic::getDeclaration(CI.getModule(), Intrinsic::abs, Ty);
- Value *Res = Builder.CreateCall(F, {Op0, Builder.getInt1(false)});
+ Function *F = Intrinsic::getDeclaration(CI.getModule(), Intrinsic::abs, Ty);
+ Value *Res = Builder.CreateCall(F, {Op0, Builder.getInt1(false)});
if (CI.getNumArgOperands() == 3)
- Res = EmitX86Select(Builder, CI.getArgOperand(2), Res, CI.getArgOperand(1));
+ Res = EmitX86Select(Builder, CI.getArgOperand(2), Res, CI.getArgOperand(1));
return Res;
}
@@ -1453,7 +1453,7 @@ static Value *upgradePMULDQ(IRBuilder<> &Builder, CallInst &CI, bool IsSigned) {
// Applying mask on vector of i1's and make sure result is at least 8 bits wide.
static Value *ApplyX86MaskOn1BitsVec(IRBuilder<> &Builder, Value *Vec,
Value *Mask) {
- unsigned NumElts = cast<FixedVectorType>(Vec->getType())->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(Vec->getType())->getNumElements();
if (Mask) {
const auto *C = dyn_cast<Constant>(Mask);
if (!C || !C->isAllOnesValue())
@@ -1476,7 +1476,7 @@ static Value *ApplyX86MaskOn1BitsVec(IRBuilder<> &Builder, Value *Vec,
static Value *upgradeMaskedCompare(IRBuilder<> &Builder, CallInst &CI,
unsigned CC, bool Signed) {
Value *Op0 = CI.getArgOperand(0);
- unsigned NumElts = cast<FixedVectorType>(Op0->getType())->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(Op0->getType())->getNumElements();
Value *Cmp;
if (CC == 3) {
@@ -1531,7 +1531,7 @@ static Value* upgradeMaskedMove(IRBuilder<> &Builder, CallInst &CI) {
static Value* UpgradeMaskToInt(IRBuilder<> &Builder, CallInst &CI) {
Value* Op = CI.getArgOperand(0);
Type* ReturnOp = CI.getType();
- unsigned NumElts = cast<FixedVectorType>(CI.getType())->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(CI.getType())->getNumElements();
Value *Mask = getX86MaskVec(Builder, Op, NumElts);
return Builder.CreateSExt(Mask, ReturnOp, "vpmovm2");
}
@@ -1979,8 +1979,8 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Rep = Builder.CreateICmp(Pred, Rep, Zero);
Rep = ApplyX86MaskOn1BitsVec(Builder, Rep, Mask);
} else if (IsX86 && (Name.startswith("avx512.mask.pbroadcast"))){
- unsigned NumElts = cast<FixedVectorType>(CI->getArgOperand(1)->getType())
- ->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(CI->getArgOperand(1)->getType())
+ ->getNumElements();
Rep = Builder.CreateVectorSplat(NumElts, CI->getArgOperand(0));
Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep,
CI->getArgOperand(1));
@@ -2108,36 +2108,36 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Rep = Builder.CreateCall(Intrinsic::getDeclaration(F->getParent(), IID),
{ CI->getOperand(0), CI->getArgOperand(1) });
Rep = ApplyX86MaskOn1BitsVec(Builder, Rep, CI->getArgOperand(2));
- } else if (IsX86 && Name.startswith("avx512.cmp.p")) {
- SmallVector<Value *, 4> Args(CI->arg_operands().begin(),
- CI->arg_operands().end());
- Type *OpTy = Args[0]->getType();
+ } else if (IsX86 && Name.startswith("avx512.cmp.p")) {
+ SmallVector<Value *, 4> Args(CI->arg_operands().begin(),
+ CI->arg_operands().end());
+ Type *OpTy = Args[0]->getType();
unsigned VecWidth = OpTy->getPrimitiveSizeInBits();
unsigned EltWidth = OpTy->getScalarSizeInBits();
Intrinsic::ID IID;
if (VecWidth == 128 && EltWidth == 32)
- IID = Intrinsic::x86_avx512_mask_cmp_ps_128;
+ IID = Intrinsic::x86_avx512_mask_cmp_ps_128;
else if (VecWidth == 256 && EltWidth == 32)
- IID = Intrinsic::x86_avx512_mask_cmp_ps_256;
+ IID = Intrinsic::x86_avx512_mask_cmp_ps_256;
else if (VecWidth == 512 && EltWidth == 32)
- IID = Intrinsic::x86_avx512_mask_cmp_ps_512;
+ IID = Intrinsic::x86_avx512_mask_cmp_ps_512;
else if (VecWidth == 128 && EltWidth == 64)
- IID = Intrinsic::x86_avx512_mask_cmp_pd_128;
+ IID = Intrinsic::x86_avx512_mask_cmp_pd_128;
else if (VecWidth == 256 && EltWidth == 64)
- IID = Intrinsic::x86_avx512_mask_cmp_pd_256;
+ IID = Intrinsic::x86_avx512_mask_cmp_pd_256;
else if (VecWidth == 512 && EltWidth == 64)
- IID = Intrinsic::x86_avx512_mask_cmp_pd_512;
+ IID = Intrinsic::x86_avx512_mask_cmp_pd_512;
else
llvm_unreachable("Unexpected intrinsic");
- Value *Mask = Constant::getAllOnesValue(CI->getType());
- if (VecWidth == 512)
- std::swap(Mask, Args.back());
- Args.push_back(Mask);
+ Value *Mask = Constant::getAllOnesValue(CI->getType());
+ if (VecWidth == 512)
+ std::swap(Mask, Args.back());
+ Args.push_back(Mask);
Rep = Builder.CreateCall(Intrinsic::getDeclaration(F->getParent(), IID),
Args);
- } else if (IsX86 && Name.startswith("avx512.mask.cmp.")) {
+ } else if (IsX86 && Name.startswith("avx512.mask.cmp.")) {
// Integer compare intrinsics.
unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
Rep = upgradeMaskedCompare(Builder, *CI, Imm, true);
@@ -2163,25 +2163,25 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Name == "sse41.pmaxsd" ||
Name.startswith("avx2.pmaxs") ||
Name.startswith("avx512.mask.pmaxs"))) {
- Rep = UpgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::smax);
+ Rep = UpgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::smax);
} else if (IsX86 && (Name == "sse2.pmaxu.b" ||
Name == "sse41.pmaxuw" ||
Name == "sse41.pmaxud" ||
Name.startswith("avx2.pmaxu") ||
Name.startswith("avx512.mask.pmaxu"))) {
- Rep = UpgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::umax);
+ Rep = UpgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::umax);
} else if (IsX86 && (Name == "sse41.pminsb" ||
Name == "sse2.pmins.w" ||
Name == "sse41.pminsd" ||
Name.startswith("avx2.pmins") ||
Name.startswith("avx512.mask.pmins"))) {
- Rep = UpgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::smin);
+ Rep = UpgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::smin);
} else if (IsX86 && (Name == "sse2.pminu.b" ||
Name == "sse41.pminuw" ||
Name == "sse41.pminud" ||
Name.startswith("avx2.pminu") ||
Name.startswith("avx512.mask.pminu"))) {
- Rep = UpgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::umin);
+ Rep = UpgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::umin);
} else if (IsX86 && (Name == "sse2.pmulu.dq" ||
Name == "avx2.pmulu.dq" ||
Name == "avx512.pmulu.dq.512" ||
@@ -2228,9 +2228,9 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Name == "avx.cvt.ps2.pd.256" ||
Name == "avx512.mask.cvtps2pd.128" ||
Name == "avx512.mask.cvtps2pd.256")) {
- auto *DstTy = cast<FixedVectorType>(CI->getType());
+ auto *DstTy = cast<FixedVectorType>(CI->getType());
Rep = CI->getArgOperand(0);
- auto *SrcTy = cast<FixedVectorType>(Rep->getType());
+ auto *SrcTy = cast<FixedVectorType>(Rep->getType());
unsigned NumDstElts = DstTy->getNumElements();
if (NumDstElts < SrcTy->getNumElements()) {
@@ -2260,9 +2260,9 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
CI->getArgOperand(1));
} else if (IsX86 && (Name.startswith("avx512.mask.vcvtph2ps.") ||
Name.startswith("vcvtph2ps."))) {
- auto *DstTy = cast<FixedVectorType>(CI->getType());
+ auto *DstTy = cast<FixedVectorType>(CI->getType());
Rep = CI->getArgOperand(0);
- auto *SrcTy = cast<FixedVectorType>(Rep->getType());
+ auto *SrcTy = cast<FixedVectorType>(Rep->getType());
unsigned NumDstElts = DstTy->getNumElements();
if (NumDstElts != SrcTy->getNumElements()) {
assert(NumDstElts == 4 && "Unexpected vector size");
@@ -2283,7 +2283,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
CI->getArgOperand(1),CI->getArgOperand(2),
/*Aligned*/true);
} else if (IsX86 && Name.startswith("avx512.mask.expand.load.")) {
- auto *ResultTy = cast<FixedVectorType>(CI->getType());
+ auto *ResultTy = cast<FixedVectorType>(CI->getType());
Type *PtrTy = ResultTy->getElementType();
// Cast the pointer to element type.
@@ -2305,9 +2305,9 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Value *Ptr = Builder.CreateBitCast(CI->getOperand(0),
llvm::PointerType::getUnqual(PtrTy));
- Value *MaskVec =
- getX86MaskVec(Builder, CI->getArgOperand(2),
- cast<FixedVectorType>(ResultTy)->getNumElements());
+ Value *MaskVec =
+ getX86MaskVec(Builder, CI->getArgOperand(2),
+ cast<FixedVectorType>(ResultTy)->getNumElements());
Function *CSt = Intrinsic::getDeclaration(F->getParent(),
Intrinsic::masked_compressstore,
@@ -2315,7 +2315,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Rep = Builder.CreateCall(CSt, { CI->getArgOperand(1), Ptr, MaskVec });
} else if (IsX86 && (Name.startswith("avx512.mask.compress.") ||
Name.startswith("avx512.mask.expand."))) {
- auto *ResultTy = cast<FixedVectorType>(CI->getType());
+ auto *ResultTy = cast<FixedVectorType>(CI->getType());
Value *MaskVec = getX86MaskVec(Builder, CI->getArgOperand(2),
ResultTy->getNumElements());
@@ -2395,7 +2395,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
} else if (IsX86 && (Name.startswith("avx.vbroadcast.s") ||
Name.startswith("avx512.vbroadcast.s"))) {
// Replace broadcasts with a series of insertelements.
- auto *VecTy = cast<FixedVectorType>(CI->getType());
+ auto *VecTy = cast<FixedVectorType>(CI->getType());
Type *EltTy = VecTy->getElementType();
unsigned EltNum = VecTy->getNumElements();
Value *Cast = Builder.CreateBitCast(CI->getArgOperand(0),
@@ -2412,7 +2412,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Name.startswith("avx2.pmovzx") ||
Name.startswith("avx512.mask.pmovsx") ||
Name.startswith("avx512.mask.pmovzx"))) {
- auto *DstTy = cast<FixedVectorType>(CI->getType());
+ auto *DstTy = cast<FixedVectorType>(CI->getType());
unsigned NumDstElts = DstTy->getNumElements();
// Extract a subvector of the first NumDstElts lanes and sign/zero extend.
@@ -2420,8 +2420,8 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
for (unsigned i = 0; i != NumDstElts; ++i)
ShuffleMask[i] = i;
- Value *SV =
- Builder.CreateShuffleVector(CI->getArgOperand(0), ShuffleMask);
+ Value *SV =
+ Builder.CreateShuffleVector(CI->getArgOperand(0), ShuffleMask);
bool DoSext = (StringRef::npos != Name.find("pmovsx"));
Rep = DoSext ? Builder.CreateSExt(SV, DstTy)
@@ -2448,10 +2448,10 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
PointerType::getUnqual(VT));
Value *Load = Builder.CreateAlignedLoad(VT, Op, Align(1));
if (NumSrcElts == 2)
- Rep = Builder.CreateShuffleVector(Load, ArrayRef<int>{0, 1, 0, 1});
- else
+ Rep = Builder.CreateShuffleVector(Load, ArrayRef<int>{0, 1, 0, 1});
+ else
Rep = Builder.CreateShuffleVector(
- Load, ArrayRef<int>{0, 1, 2, 3, 0, 1, 2, 3});
+ Load, ArrayRef<int>{0, 1, 2, 3, 0, 1, 2, 3});
} else if (IsX86 && (Name.startswith("avx512.mask.shuf.i") ||
Name.startswith("avx512.mask.shuf.f"))) {
unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
@@ -2477,10 +2477,10 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
}else if (IsX86 && (Name.startswith("avx512.mask.broadcastf") ||
Name.startswith("avx512.mask.broadcasti"))) {
unsigned NumSrcElts =
- cast<FixedVectorType>(CI->getArgOperand(0)->getType())
- ->getNumElements();
- unsigned NumDstElts =
- cast<FixedVectorType>(CI->getType())->getNumElements();
+ cast<FixedVectorType>(CI->getArgOperand(0)->getType())
+ ->getNumElements();
+ unsigned NumDstElts =
+ cast<FixedVectorType>(CI->getType())->getNumElements();
SmallVector<int, 8> ShuffleMask(NumDstElts);
for (unsigned i = 0; i != NumDstElts; ++i)
@@ -2499,31 +2499,31 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Value *Op = CI->getArgOperand(0);
ElementCount EC = cast<VectorType>(CI->getType())->getElementCount();
Type *MaskTy = VectorType::get(Type::getInt32Ty(C), EC);
- SmallVector<int, 8> M;
- ShuffleVectorInst::getShuffleMask(Constant::getNullValue(MaskTy), M);
- Rep = Builder.CreateShuffleVector(Op, M);
+ SmallVector<int, 8> M;
+ ShuffleVectorInst::getShuffleMask(Constant::getNullValue(MaskTy), M);
+ Rep = Builder.CreateShuffleVector(Op, M);
if (CI->getNumArgOperands() == 3)
Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep,
CI->getArgOperand(1));
} else if (IsX86 && (Name.startswith("sse2.padds.") ||
Name.startswith("avx2.padds.") ||
- Name.startswith("avx512.padds.") ||
- Name.startswith("avx512.mask.padds."))) {
- Rep = UpgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::sadd_sat);
- } else if (IsX86 && (Name.startswith("sse2.psubs.") ||
+ Name.startswith("avx512.padds.") ||
+ Name.startswith("avx512.mask.padds."))) {
+ Rep = UpgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::sadd_sat);
+ } else if (IsX86 && (Name.startswith("sse2.psubs.") ||
Name.startswith("avx2.psubs.") ||
Name.startswith("avx512.psubs.") ||
Name.startswith("avx512.mask.psubs."))) {
- Rep = UpgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::ssub_sat);
+ Rep = UpgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::ssub_sat);
} else if (IsX86 && (Name.startswith("sse2.paddus.") ||
Name.startswith("avx2.paddus.") ||
- Name.startswith("avx512.mask.paddus."))) {
- Rep = UpgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::uadd_sat);
- } else if (IsX86 && (Name.startswith("sse2.psubus.") ||
+ Name.startswith("avx512.mask.paddus."))) {
+ Rep = UpgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::uadd_sat);
+ } else if (IsX86 && (Name.startswith("sse2.psubus.") ||
Name.startswith("avx2.psubus.") ||
Name.startswith("avx512.mask.psubus."))) {
- Rep = UpgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::usub_sat);
+ Rep = UpgradeX86BinaryIntrinsics(Builder, *CI, Intrinsic::usub_sat);
} else if (IsX86 && Name.startswith("avx512.mask.palignr.")) {
Rep = UpgradeX86ALIGNIntrinsics(Builder, CI->getArgOperand(0),
CI->getArgOperand(1),
@@ -2570,7 +2570,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Value *Op0 = CI->getArgOperand(0);
Value *Op1 = CI->getArgOperand(1);
unsigned Imm = cast <ConstantInt>(CI->getArgOperand(2))->getZExtValue();
- auto *VecTy = cast<FixedVectorType>(CI->getType());
+ auto *VecTy = cast<FixedVectorType>(CI->getType());
unsigned NumElts = VecTy->getNumElements();
SmallVector<int, 16> Idxs(NumElts);
@@ -2584,10 +2584,10 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Value *Op0 = CI->getArgOperand(0);
Value *Op1 = CI->getArgOperand(1);
unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
- unsigned DstNumElts =
- cast<FixedVectorType>(CI->getType())->getNumElements();
- unsigned SrcNumElts =
- cast<FixedVectorType>(Op1->getType())->getNumElements();
+ unsigned DstNumElts =
+ cast<FixedVectorType>(CI->getType())->getNumElements();
+ unsigned SrcNumElts =
+ cast<FixedVectorType>(Op1->getType())->getNumElements();
unsigned Scale = DstNumElts / SrcNumElts;
// Mask off the high bits of the immediate value; hardware ignores those.
@@ -2599,7 +2599,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Idxs[i] = i;
for (unsigned i = SrcNumElts; i != DstNumElts; ++i)
Idxs[i] = SrcNumElts;
- Rep = Builder.CreateShuffleVector(Op1, Idxs);
+ Rep = Builder.CreateShuffleVector(Op1, Idxs);
// Insert the second operand into the first operand.
@@ -2629,10 +2629,10 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Name.startswith("avx512.mask.vextract"))) {
Value *Op0 = CI->getArgOperand(0);
unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
- unsigned DstNumElts =
- cast<FixedVectorType>(CI->getType())->getNumElements();
- unsigned SrcNumElts =
- cast<FixedVectorType>(Op0->getType())->getNumElements();
+ unsigned DstNumElts =
+ cast<FixedVectorType>(CI->getType())->getNumElements();
+ unsigned SrcNumElts =
+ cast<FixedVectorType>(Op0->getType())->getNumElements();
unsigned Scale = SrcNumElts / DstNumElts;
// Mask off the high bits of the immediate value; hardware ignores those.
@@ -2655,7 +2655,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Name.startswith("avx512.mask.perm.di."))) {
Value *Op0 = CI->getArgOperand(0);
unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
- auto *VecTy = cast<FixedVectorType>(CI->getType());
+ auto *VecTy = cast<FixedVectorType>(CI->getType());
unsigned NumElts = VecTy->getNumElements();
SmallVector<int, 8> Idxs(NumElts);
@@ -2679,7 +2679,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
uint8_t Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
- unsigned NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
unsigned HalfSize = NumElts / 2;
SmallVector<int, 8> ShuffleMask(NumElts);
@@ -2709,7 +2709,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Name.startswith("avx512.mask.pshuf.d."))) {
Value *Op0 = CI->getArgOperand(0);
unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
- auto *VecTy = cast<FixedVectorType>(CI->getType());
+ auto *VecTy = cast<FixedVectorType>(CI->getType());
unsigned NumElts = VecTy->getNumElements();
// Calculate the size of each index in the immediate.
unsigned IdxSize = 64 / VecTy->getScalarSizeInBits();
@@ -2731,7 +2731,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Name.startswith("avx512.mask.pshufl.w."))) {
Value *Op0 = CI->getArgOperand(0);
unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
- unsigned NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
SmallVector<int, 16> Idxs(NumElts);
for (unsigned l = 0; l != NumElts; l += 8) {
@@ -2750,7 +2750,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Name.startswith("avx512.mask.pshufh.w."))) {
Value *Op0 = CI->getArgOperand(0);
unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
- unsigned NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
SmallVector<int, 16> Idxs(NumElts);
for (unsigned l = 0; l != NumElts; l += 8) {
@@ -2769,7 +2769,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Value *Op0 = CI->getArgOperand(0);
Value *Op1 = CI->getArgOperand(1);
unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
- unsigned NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
unsigned NumLaneElts = 128/CI->getType()->getScalarSizeInBits();
unsigned HalfLaneElts = NumLaneElts / 2;
@@ -2794,7 +2794,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Name.startswith("avx512.mask.movshdup") ||
Name.startswith("avx512.mask.movsldup"))) {
Value *Op0 = CI->getArgOperand(0);
- unsigned NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
unsigned NumLaneElts = 128/CI->getType()->getScalarSizeInBits();
unsigned Offset = 0;
@@ -2816,7 +2816,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Name.startswith("avx512.mask.unpckl."))) {
Value *Op0 = CI->getArgOperand(0);
Value *Op1 = CI->getArgOperand(1);
- int NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
+ int NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
int NumLaneElts = 128/CI->getType()->getScalarSizeInBits();
SmallVector<int, 64> Idxs(NumElts);
@@ -2832,7 +2832,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Name.startswith("avx512.mask.unpckh."))) {
Value *Op0 = CI->getArgOperand(0);
Value *Op1 = CI->getArgOperand(1);
- int NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
+ int NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
int NumLaneElts = 128/CI->getType()->getScalarSizeInBits();
SmallVector<int, 64> Idxs(NumElts);
@@ -3400,7 +3400,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Rep = Builder.CreateCall(Intrinsic::getDeclaration(F->getParent(), IID),
Ops);
} else {
- int NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
+ int NumElts = cast<FixedVectorType>(CI->getType())->getNumElements();
Value *Ops[] = { CI->getArgOperand(0), CI->getArgOperand(1),
CI->getArgOperand(2) };
@@ -3677,30 +3677,30 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
break;
}
- case Intrinsic::arm_neon_bfdot:
- case Intrinsic::arm_neon_bfmmla:
- case Intrinsic::arm_neon_bfmlalb:
- case Intrinsic::arm_neon_bfmlalt:
- case Intrinsic::aarch64_neon_bfdot:
- case Intrinsic::aarch64_neon_bfmmla:
- case Intrinsic::aarch64_neon_bfmlalb:
- case Intrinsic::aarch64_neon_bfmlalt: {
- SmallVector<Value *, 3> Args;
- assert(CI->getNumArgOperands() == 3 &&
- "Mismatch between function args and call args");
- size_t OperandWidth =
- CI->getArgOperand(1)->getType()->getPrimitiveSizeInBits();
- assert((OperandWidth == 64 || OperandWidth == 128) &&
- "Unexpected operand width");
- Type *NewTy = FixedVectorType::get(Type::getBFloatTy(C), OperandWidth / 16);
- auto Iter = CI->arg_operands().begin();
- Args.push_back(*Iter++);
- Args.push_back(Builder.CreateBitCast(*Iter++, NewTy));
- Args.push_back(Builder.CreateBitCast(*Iter++, NewTy));
- NewCall = Builder.CreateCall(NewFn, Args);
- break;
- }
-
+ case Intrinsic::arm_neon_bfdot:
+ case Intrinsic::arm_neon_bfmmla:
+ case Intrinsic::arm_neon_bfmlalb:
+ case Intrinsic::arm_neon_bfmlalt:
+ case Intrinsic::aarch64_neon_bfdot:
+ case Intrinsic::aarch64_neon_bfmmla:
+ case Intrinsic::aarch64_neon_bfmlalb:
+ case Intrinsic::aarch64_neon_bfmlalt: {
+ SmallVector<Value *, 3> Args;
+ assert(CI->getNumArgOperands() == 3 &&
+ "Mismatch between function args and call args");
+ size_t OperandWidth =
+ CI->getArgOperand(1)->getType()->getPrimitiveSizeInBits();
+ assert((OperandWidth == 64 || OperandWidth == 128) &&
+ "Unexpected operand width");
+ Type *NewTy = FixedVectorType::get(Type::getBFloatTy(C), OperandWidth / 16);
+ auto Iter = CI->arg_operands().begin();
+ Args.push_back(*Iter++);
+ Args.push_back(Builder.CreateBitCast(*Iter++, NewTy));
+ Args.push_back(Builder.CreateBitCast(*Iter++, NewTy));
+ NewCall = Builder.CreateCall(NewFn, Args);
+ break;
+ }
+
case Intrinsic::bitreverse:
NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)});
break;
@@ -3746,32 +3746,32 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
CI->eraseFromParent();
return;
- case Intrinsic::ptr_annotation:
- // Upgrade from versions that lacked the annotation attribute argument.
- assert(CI->getNumArgOperands() == 4 &&
- "Before LLVM 12.0 this intrinsic took four arguments");
- // Create a new call with an added null annotation attribute argument.
- NewCall = Builder.CreateCall(
- NewFn,
- {CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(2),
- CI->getArgOperand(3), Constant::getNullValue(Builder.getInt8PtrTy())});
- NewCall->takeName(CI);
- CI->replaceAllUsesWith(NewCall);
- CI->eraseFromParent();
- return;
-
- case Intrinsic::var_annotation:
- // Upgrade from versions that lacked the annotation attribute argument.
- assert(CI->getNumArgOperands() == 4 &&
- "Before LLVM 12.0 this intrinsic took four arguments");
- // Create a new call with an added null annotation attribute argument.
- NewCall = Builder.CreateCall(
- NewFn,
- {CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(2),
- CI->getArgOperand(3), Constant::getNullValue(Builder.getInt8PtrTy())});
- CI->eraseFromParent();
- return;
-
+ case Intrinsic::ptr_annotation:
+ // Upgrade from versions that lacked the annotation attribute argument.
+ assert(CI->getNumArgOperands() == 4 &&
+ "Before LLVM 12.0 this intrinsic took four arguments");
+ // Create a new call with an added null annotation attribute argument.
+ NewCall = Builder.CreateCall(
+ NewFn,
+ {CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(2),
+ CI->getArgOperand(3), Constant::getNullValue(Builder.getInt8PtrTy())});
+ NewCall->takeName(CI);
+ CI->replaceAllUsesWith(NewCall);
+ CI->eraseFromParent();
+ return;
+
+ case Intrinsic::var_annotation:
+ // Upgrade from versions that lacked the annotation attribute argument.
+ assert(CI->getNumArgOperands() == 4 &&
+ "Before LLVM 12.0 this intrinsic took four arguments");
+ // Create a new call with an added null annotation attribute argument.
+ NewCall = Builder.CreateCall(
+ NewFn,
+ {CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(2),
+ CI->getArgOperand(3), Constant::getNullValue(Builder.getInt8PtrTy())});
+ CI->eraseFromParent();
+ return;
+
case Intrinsic::x86_xop_vfrcz_ss:
case Intrinsic::x86_xop_vfrcz_sd:
NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(1)});
@@ -3829,7 +3829,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
// Replace the original call result with the first result of the new call.
Value *TSC = Builder.CreateExtractValue(NewCall, 0);
- NewCall->takeName(CI);
+ NewCall->takeName(CI);
CI->replaceAllUsesWith(TSC);
CI->eraseFromParent();
return;
@@ -3852,27 +3852,27 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
break;
}
- case Intrinsic::x86_avx512_mask_cmp_pd_128:
- case Intrinsic::x86_avx512_mask_cmp_pd_256:
- case Intrinsic::x86_avx512_mask_cmp_pd_512:
- case Intrinsic::x86_avx512_mask_cmp_ps_128:
- case Intrinsic::x86_avx512_mask_cmp_ps_256:
- case Intrinsic::x86_avx512_mask_cmp_ps_512: {
- SmallVector<Value *, 4> Args(CI->arg_operands().begin(),
- CI->arg_operands().end());
- unsigned NumElts =
- cast<FixedVectorType>(Args[0]->getType())->getNumElements();
- Args[3] = getX86MaskVec(Builder, Args[3], NumElts);
-
- NewCall = Builder.CreateCall(NewFn, Args);
- Value *Res = ApplyX86MaskOn1BitsVec(Builder, NewCall, nullptr);
-
- NewCall->takeName(CI);
- CI->replaceAllUsesWith(Res);
- CI->eraseFromParent();
- return;
- }
-
+ case Intrinsic::x86_avx512_mask_cmp_pd_128:
+ case Intrinsic::x86_avx512_mask_cmp_pd_256:
+ case Intrinsic::x86_avx512_mask_cmp_pd_512:
+ case Intrinsic::x86_avx512_mask_cmp_ps_128:
+ case Intrinsic::x86_avx512_mask_cmp_ps_256:
+ case Intrinsic::x86_avx512_mask_cmp_ps_512: {
+ SmallVector<Value *, 4> Args(CI->arg_operands().begin(),
+ CI->arg_operands().end());
+ unsigned NumElts =
+ cast<FixedVectorType>(Args[0]->getType())->getNumElements();
+ Args[3] = getX86MaskVec(Builder, Args[3], NumElts);
+
+ NewCall = Builder.CreateCall(NewFn, Args);
+ Value *Res = ApplyX86MaskOn1BitsVec(Builder, NewCall, nullptr);
+
+ NewCall->takeName(CI);
+ CI->replaceAllUsesWith(Res);
+ CI->eraseFromParent();
+ return;
+ }
+
case Intrinsic::thread_pointer: {
NewCall = Builder.CreateCall(NewFn, {});
break;
@@ -3921,7 +3921,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
}
assert(NewCall && "Should have either set this variable or returned through "
"the default case");
- NewCall->takeName(CI);
+ NewCall->takeName(CI);
CI->replaceAllUsesWith(NewCall);
CI->eraseFromParent();
}
@@ -3935,8 +3935,8 @@ void llvm::UpgradeCallsToIntrinsic(Function *F) {
if (UpgradeIntrinsicFunction(F, NewFn)) {
// Replace all users of the old function with the new function or new
// instructions. This is not a range loop because the call is deleted.
- for (User *U : make_early_inc_range(F->users()))
- if (CallInst *CI = dyn_cast<CallInst>(U))
+ for (User *U : make_early_inc_range(F->users()))
+ if (CallInst *CI = dyn_cast<CallInst>(U))
UpgradeIntrinsicCall(CI, NewFn);
// Remove old function, no longer used, from the module.
@@ -4072,8 +4072,8 @@ void llvm::UpgradeARCRuntime(Module &M) {
Function *NewFn = llvm::Intrinsic::getDeclaration(&M, IntrinsicFunc);
- for (User *U : make_early_inc_range(Fn->users())) {
- CallInst *CI = dyn_cast<CallInst>(U);
+ for (User *U : make_early_inc_range(Fn->users())) {
+ CallInst *CI = dyn_cast<CallInst>(U);
if (!CI || CI->getCalledFunction() != Fn)
continue;
@@ -4114,7 +4114,7 @@ void llvm::UpgradeARCRuntime(Module &M) {
// Create a call instruction that calls the new function.
CallInst *NewCall = Builder.CreateCall(NewFuncTy, NewFn, Args);
NewCall->setTailCallKind(cast<CallInst>(CI)->getTailCallKind());
- NewCall->takeName(CI);
+ NewCall->takeName(CI);
// Bitcast the return value back to the type of the old call.
Value *NewRetVal = Builder.CreateBitCast(NewCall, CI->getType());
@@ -4353,13 +4353,13 @@ void llvm::UpgradeFunctionAttributes(Function &F) {
StrictFPUpgradeVisitor SFPV;
SFPV.visit(F);
}
-
- if (F.getCallingConv() == CallingConv::X86_INTR &&
- !F.arg_empty() && !F.hasParamAttribute(0, Attribute::ByVal)) {
- Type *ByValTy = cast<PointerType>(F.getArg(0)->getType())->getElementType();
- Attribute NewAttr = Attribute::getWithByValType(F.getContext(), ByValTy);
- F.addParamAttr(0, NewAttr);
- }
+
+ if (F.getCallingConv() == CallingConv::X86_INTR &&
+ !F.arg_empty() && !F.hasParamAttribute(0, Attribute::ByVal)) {
+ Type *ByValTy = cast<PointerType>(F.getArg(0)->getType())->getElementType();
+ Attribute NewAttr = Attribute::getWithByValType(F.getContext(), ByValTy);
+ F.addParamAttr(0, NewAttr);
+ }
}
static bool isOldLoopArgument(Metadata *MD) {
@@ -4425,17 +4425,17 @@ MDNode *llvm::upgradeInstructionLoopAttachment(MDNode &N) {
}
std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) {
- Triple T(TT);
- // For AMDGPU we uprgrade older DataLayouts to include the default globals
- // address space of 1.
- if (T.isAMDGPU() && !DL.contains("-G") && !DL.startswith("G")) {
- return DL.empty() ? std::string("G1") : (DL + "-G1").str();
- }
-
+ Triple T(TT);
+ // For AMDGPU we uprgrade older DataLayouts to include the default globals
+ // address space of 1.
+ if (T.isAMDGPU() && !DL.contains("-G") && !DL.startswith("G")) {
+ return DL.empty() ? std::string("G1") : (DL + "-G1").str();
+ }
+
std::string AddrSpaces = "-p270:32:32-p271:32:32-p272:64:64";
// If X86, and the datalayout matches the expected format, add pointer size
// address spaces to the datalayout.
- if (!T.isX86() || DL.contains(AddrSpaces))
+ if (!T.isX86() || DL.contains(AddrSpaces))
return std::string(DL);
SmallVector<StringRef, 4> Groups;
@@ -4443,7 +4443,7 @@ std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) {
if (!R.match(DL, &Groups))
return std::string(DL);
- return (Groups[1] + AddrSpaces + Groups[3]).str();
+ return (Groups[1] + AddrSpaces + Groups[3]).str();
}
void llvm::UpgradeAttributes(AttrBuilder &B) {
diff --git a/contrib/libs/llvm12/lib/IR/BasicBlock.cpp b/contrib/libs/llvm12/lib/IR/BasicBlock.cpp
index 217386b4bb..00ef10dd53 100644
--- a/contrib/libs/llvm12/lib/IR/BasicBlock.cpp
+++ b/contrib/libs/llvm12/lib/IR/BasicBlock.cpp
@@ -97,20 +97,20 @@ void BasicBlock::setParent(Function *parent) {
iterator_range<filter_iterator<BasicBlock::const_iterator,
std::function<bool(const Instruction &)>>>
-BasicBlock::instructionsWithoutDebug(bool SkipPseudoOp) const {
- std::function<bool(const Instruction &)> Fn = [=](const Instruction &I) {
- return !isa<DbgInfoIntrinsic>(I) &&
- !(SkipPseudoOp && isa<PseudoProbeInst>(I));
+BasicBlock::instructionsWithoutDebug(bool SkipPseudoOp) const {
+ std::function<bool(const Instruction &)> Fn = [=](const Instruction &I) {
+ return !isa<DbgInfoIntrinsic>(I) &&
+ !(SkipPseudoOp && isa<PseudoProbeInst>(I));
};
return make_filter_range(*this, Fn);
}
-iterator_range<
- filter_iterator<BasicBlock::iterator, std::function<bool(Instruction &)>>>
-BasicBlock::instructionsWithoutDebug(bool SkipPseudoOp) {
- std::function<bool(Instruction &)> Fn = [=](Instruction &I) {
- return !isa<DbgInfoIntrinsic>(I) &&
- !(SkipPseudoOp && isa<PseudoProbeInst>(I));
+iterator_range<
+ filter_iterator<BasicBlock::iterator, std::function<bool(Instruction &)>>>
+BasicBlock::instructionsWithoutDebug(bool SkipPseudoOp) {
+ std::function<bool(Instruction &)> Fn = [=](Instruction &I) {
+ return !isa<DbgInfoIntrinsic>(I) &&
+ !(SkipPseudoOp && isa<PseudoProbeInst>(I));
};
return make_filter_range(*this, Fn);
}
@@ -216,21 +216,21 @@ const Instruction* BasicBlock::getFirstNonPHI() const {
return nullptr;
}
-const Instruction *BasicBlock::getFirstNonPHIOrDbg(bool SkipPseudoOp) const {
- for (const Instruction &I : *this) {
- if (isa<PHINode>(I) || isa<DbgInfoIntrinsic>(I))
- continue;
-
- if (SkipPseudoOp && isa<PseudoProbeInst>(I))
- continue;
-
- return &I;
- }
+const Instruction *BasicBlock::getFirstNonPHIOrDbg(bool SkipPseudoOp) const {
+ for (const Instruction &I : *this) {
+ if (isa<PHINode>(I) || isa<DbgInfoIntrinsic>(I))
+ continue;
+
+ if (SkipPseudoOp && isa<PseudoProbeInst>(I))
+ continue;
+
+ return &I;
+ }
return nullptr;
}
-const Instruction *
-BasicBlock::getFirstNonPHIOrDbgOrLifetime(bool SkipPseudoOp) const {
+const Instruction *
+BasicBlock::getFirstNonPHIOrDbgOrLifetime(bool SkipPseudoOp) const {
for (const Instruction &I : *this) {
if (isa<PHINode>(I) || isa<DbgInfoIntrinsic>(I))
continue;
@@ -238,9 +238,9 @@ BasicBlock::getFirstNonPHIOrDbgOrLifetime(bool SkipPseudoOp) const {
if (I.isLifetimeStartOrEnd())
continue;
- if (SkipPseudoOp && isa<PseudoProbeInst>(I))
- continue;
-
+ if (SkipPseudoOp && isa<PseudoProbeInst>(I))
+ continue;
+
return &I;
}
return nullptr;
@@ -321,28 +321,28 @@ iterator_range<BasicBlock::phi_iterator> BasicBlock::phis() {
void BasicBlock::removePredecessor(BasicBlock *Pred,
bool KeepOneInputPHIs) {
// Use hasNUsesOrMore to bound the cost of this assertion for complex CFGs.
- assert((hasNUsesOrMore(16) || llvm::is_contained(predecessors(this), Pred)) &&
+ assert((hasNUsesOrMore(16) || llvm::is_contained(predecessors(this), Pred)) &&
"Pred is not a predecessor!");
// Return early if there are no PHI nodes to update.
- if (empty() || !isa<PHINode>(begin()))
+ if (empty() || !isa<PHINode>(begin()))
return;
-
+
unsigned NumPreds = cast<PHINode>(front()).getNumIncomingValues();
- for (PHINode &Phi : make_early_inc_range(phis())) {
- Phi.removeIncomingValue(Pred, !KeepOneInputPHIs);
- if (KeepOneInputPHIs)
- continue;
-
- // If we have a single predecessor, removeIncomingValue may have erased the
- // PHI node itself.
- if (NumPreds == 1)
- continue;
-
- // Try to replace the PHI node with a constant value.
- if (Value *PhiConstant = Phi.hasConstantValue()) {
- Phi.replaceAllUsesWith(PhiConstant);
- Phi.eraseFromParent();
+ for (PHINode &Phi : make_early_inc_range(phis())) {
+ Phi.removeIncomingValue(Pred, !KeepOneInputPHIs);
+ if (KeepOneInputPHIs)
+ continue;
+
+ // If we have a single predecessor, removeIncomingValue may have erased the
+ // PHI node itself.
+ if (NumPreds == 1)
+ continue;
+
+ // Try to replace the PHI node with a constant value.
+ if (Value *PhiConstant = Phi.hasConstantValue()) {
+ Phi.replaceAllUsesWith(PhiConstant);
+ Phi.eraseFromParent();
}
}
}
@@ -372,11 +372,11 @@ bool BasicBlock::isLegalToHoistInto() const {
return !Term->isExceptionalTerminator();
}
-BasicBlock *BasicBlock::splitBasicBlock(iterator I, const Twine &BBName,
- bool Before) {
- if (Before)
- return splitBasicBlockBefore(I, BBName);
-
+BasicBlock *BasicBlock::splitBasicBlock(iterator I, const Twine &BBName,
+ bool Before) {
+ if (Before)
+ return splitBasicBlockBefore(I, BBName);
+
assert(getTerminator() && "Can't use splitBasicBlock on degenerate BB!");
assert(I != InstList.end() &&
"Trying to get me to create degenerate basic block!");
@@ -403,40 +403,40 @@ BasicBlock *BasicBlock::splitBasicBlock(iterator I, const Twine &BBName,
return New;
}
-BasicBlock *BasicBlock::splitBasicBlockBefore(iterator I, const Twine &BBName) {
- assert(getTerminator() &&
- "Can't use splitBasicBlockBefore on degenerate BB!");
- assert(I != InstList.end() &&
- "Trying to get me to create degenerate basic block!");
-
- assert((!isa<PHINode>(*I) || getSinglePredecessor()) &&
- "cannot split on multi incoming phis");
-
- BasicBlock *New = BasicBlock::Create(getContext(), BBName, getParent(), this);
- // Save DebugLoc of split point before invalidating iterator.
- DebugLoc Loc = I->getDebugLoc();
- // Move all of the specified instructions from the original basic block into
- // the new basic block.
- New->getInstList().splice(New->end(), this->getInstList(), begin(), I);
-
- // Loop through all of the predecessors of the 'this' block (which will be the
- // predecessors of the New block), replace the specified successor 'this'
- // block to point at the New block and update any PHI nodes in 'this' block.
- // If there were PHI nodes in 'this' block, the PHI nodes are updated
- // to reflect that the incoming branches will be from the New block and not
- // from predecessors of the 'this' block.
- for (BasicBlock *Pred : predecessors(this)) {
- Instruction *TI = Pred->getTerminator();
- TI->replaceSuccessorWith(this, New);
- this->replacePhiUsesWith(Pred, New);
- }
- // Add a branch instruction from "New" to "this" Block.
- BranchInst *BI = BranchInst::Create(this, New);
- BI->setDebugLoc(Loc);
-
- return New;
-}
-
+BasicBlock *BasicBlock::splitBasicBlockBefore(iterator I, const Twine &BBName) {
+ assert(getTerminator() &&
+ "Can't use splitBasicBlockBefore on degenerate BB!");
+ assert(I != InstList.end() &&
+ "Trying to get me to create degenerate basic block!");
+
+ assert((!isa<PHINode>(*I) || getSinglePredecessor()) &&
+ "cannot split on multi incoming phis");
+
+ BasicBlock *New = BasicBlock::Create(getContext(), BBName, getParent(), this);
+ // Save DebugLoc of split point before invalidating iterator.
+ DebugLoc Loc = I->getDebugLoc();
+ // Move all of the specified instructions from the original basic block into
+ // the new basic block.
+ New->getInstList().splice(New->end(), this->getInstList(), begin(), I);
+
+ // Loop through all of the predecessors of the 'this' block (which will be the
+ // predecessors of the New block), replace the specified successor 'this'
+ // block to point at the New block and update any PHI nodes in 'this' block.
+ // If there were PHI nodes in 'this' block, the PHI nodes are updated
+ // to reflect that the incoming branches will be from the New block and not
+ // from predecessors of the 'this' block.
+ for (BasicBlock *Pred : predecessors(this)) {
+ Instruction *TI = Pred->getTerminator();
+ TI->replaceSuccessorWith(this, New);
+ this->replacePhiUsesWith(Pred, New);
+ }
+ // Add a branch instruction from "New" to "this" Block.
+ BranchInst *BI = BranchInst::Create(this, New);
+ BI->setDebugLoc(Loc);
+
+ return New;
+}
+
void BasicBlock::replacePhiUsesWith(BasicBlock *Old, BasicBlock *New) {
// N.B. This might not be a complete BasicBlock, so don't assume
// that it ends with a non-phi instruction.
diff --git a/contrib/libs/llvm12/lib/IR/ConstantFold.cpp b/contrib/libs/llvm12/lib/IR/ConstantFold.cpp
index 56a95ad639..95dd55237e 100644
--- a/contrib/libs/llvm12/lib/IR/ConstantFold.cpp
+++ b/contrib/libs/llvm12/lib/IR/ConstantFold.cpp
@@ -522,9 +522,9 @@ static Constant *getFoldedOffsetOf(Type *Ty, Constant *FieldNo, Type *DestTy,
Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
Type *DestTy) {
- if (isa<PoisonValue>(V))
- return PoisonValue::get(DestTy);
-
+ if (isa<PoisonValue>(V))
+ return PoisonValue::get(DestTy);
+
if (isa<UndefValue>(V)) {
// zext(undef) = 0, because the top bits will be zero.
// sext(undef) = 0, because the top bits will all be the same.
@@ -535,7 +535,7 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
return UndefValue::get(DestTy);
}
- if (V->isNullValue() && !DestTy->isX86_MMXTy() && !DestTy->isX86_AMXTy() &&
+ if (V->isNullValue() && !DestTy->isX86_MMXTy() && !DestTy->isX86_AMXTy() &&
opc != Instruction::AddrSpaceCast)
return Constant::getNullValue(DestTy);
@@ -762,9 +762,9 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond,
Constant *V2Element = ConstantExpr::getExtractElement(V2,
ConstantInt::get(Ty, i));
auto *Cond = cast<Constant>(CondV->getOperand(i));
- if (isa<PoisonValue>(Cond)) {
- V = PoisonValue::get(V1Element->getType());
- } else if (V1Element == V2Element) {
+ if (isa<PoisonValue>(Cond)) {
+ V = PoisonValue::get(V1Element->getType());
+ } else if (V1Element == V2Element) {
V = V1Element;
} else if (isa<UndefValue>(Cond)) {
V = isa<UndefValue>(V1Element) ? V1Element : V2Element;
@@ -780,45 +780,45 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond,
return ConstantVector::get(Result);
}
- if (isa<PoisonValue>(Cond))
- return PoisonValue::get(V1->getType());
-
+ if (isa<PoisonValue>(Cond))
+ return PoisonValue::get(V1->getType());
+
if (isa<UndefValue>(Cond)) {
if (isa<UndefValue>(V1)) return V1;
return V2;
}
-
+
if (V1 == V2) return V1;
- if (isa<PoisonValue>(V1))
- return V2;
- if (isa<PoisonValue>(V2))
- return V1;
-
- // If the true or false value is undef, we can fold to the other value as
- // long as the other value isn't poison.
- auto NotPoison = [](Constant *C) {
- if (isa<PoisonValue>(C))
- return false;
-
- // TODO: We can analyze ConstExpr by opcode to determine if there is any
- // possibility of poison.
- if (isa<ConstantExpr>(C))
- return false;
-
- if (isa<ConstantInt>(C) || isa<GlobalVariable>(C) || isa<ConstantFP>(C) ||
- isa<ConstantPointerNull>(C) || isa<Function>(C))
- return true;
-
- if (C->getType()->isVectorTy())
- return !C->containsPoisonElement() && !C->containsConstantExpression();
-
- // TODO: Recursively analyze aggregates or other constants.
- return false;
- };
- if (isa<UndefValue>(V1) && NotPoison(V2)) return V2;
- if (isa<UndefValue>(V2) && NotPoison(V1)) return V1;
-
+ if (isa<PoisonValue>(V1))
+ return V2;
+ if (isa<PoisonValue>(V2))
+ return V1;
+
+ // If the true or false value is undef, we can fold to the other value as
+ // long as the other value isn't poison.
+ auto NotPoison = [](Constant *C) {
+ if (isa<PoisonValue>(C))
+ return false;
+
+ // TODO: We can analyze ConstExpr by opcode to determine if there is any
+ // possibility of poison.
+ if (isa<ConstantExpr>(C))
+ return false;
+
+ if (isa<ConstantInt>(C) || isa<GlobalVariable>(C) || isa<ConstantFP>(C) ||
+ isa<ConstantPointerNull>(C) || isa<Function>(C))
+ return true;
+
+ if (C->getType()->isVectorTy())
+ return !C->containsPoisonElement() && !C->containsConstantExpression();
+
+ // TODO: Recursively analyze aggregates or other constants.
+ return false;
+ };
+ if (isa<UndefValue>(V1) && NotPoison(V2)) return V2;
+ if (isa<UndefValue>(V2) && NotPoison(V1)) return V1;
+
if (ConstantExpr *TrueVal = dyn_cast<ConstantExpr>(V1)) {
if (TrueVal->getOpcode() == Instruction::Select)
if (TrueVal->getOperand(0) == Cond)
@@ -837,13 +837,13 @@ Constant *llvm::ConstantFoldExtractElementInstruction(Constant *Val,
Constant *Idx) {
auto *ValVTy = cast<VectorType>(Val->getType());
- // extractelt poison, C -> poison
- // extractelt C, undef -> poison
- if (isa<PoisonValue>(Val) || isa<UndefValue>(Idx))
- return PoisonValue::get(ValVTy->getElementType());
-
+ // extractelt poison, C -> poison
+ // extractelt C, undef -> poison
+ if (isa<PoisonValue>(Val) || isa<UndefValue>(Idx))
+ return PoisonValue::get(ValVTy->getElementType());
+
// extractelt undef, C -> undef
- if (isa<UndefValue>(Val))
+ if (isa<UndefValue>(Val))
return UndefValue::get(ValVTy->getElementType());
auto *CIdx = dyn_cast<ConstantInt>(Idx);
@@ -851,9 +851,9 @@ Constant *llvm::ConstantFoldExtractElementInstruction(Constant *Val,
return nullptr;
if (auto *ValFVTy = dyn_cast<FixedVectorType>(Val->getType())) {
- // ee({w,x,y,z}, wrong_value) -> poison
+ // ee({w,x,y,z}, wrong_value) -> poison
if (CIdx->uge(ValFVTy->getNumElements()))
- return PoisonValue::get(ValFVTy->getElementType());
+ return PoisonValue::get(ValFVTy->getElementType());
}
// ee (gep (ptr, idx0, ...), idx) -> gep (ee (ptr, idx), ee (idx0, idx), ...)
@@ -873,15 +873,15 @@ Constant *llvm::ConstantFoldExtractElementInstruction(Constant *Val,
}
return CE->getWithOperands(Ops, ValVTy->getElementType(), false,
Ops[0]->getType()->getPointerElementType());
- } else if (CE->getOpcode() == Instruction::InsertElement) {
- if (const auto *IEIdx = dyn_cast<ConstantInt>(CE->getOperand(2))) {
- if (APSInt::isSameValue(APSInt(IEIdx->getValue()),
- APSInt(CIdx->getValue()))) {
- return CE->getOperand(1);
- } else {
- return ConstantExpr::getExtractElement(CE->getOperand(0), CIdx);
- }
- }
+ } else if (CE->getOpcode() == Instruction::InsertElement) {
+ if (const auto *IEIdx = dyn_cast<ConstantInt>(CE->getOperand(2))) {
+ if (APSInt::isSameValue(APSInt(IEIdx->getValue()),
+ APSInt(CIdx->getValue()))) {
+ return CE->getOperand(1);
+ } else {
+ return ConstantExpr::getExtractElement(CE->getOperand(0), CIdx);
+ }
+ }
}
}
@@ -902,7 +902,7 @@ Constant *llvm::ConstantFoldInsertElementInstruction(Constant *Val,
Constant *Elt,
Constant *Idx) {
if (isa<UndefValue>(Idx))
- return PoisonValue::get(Val->getType());
+ return PoisonValue::get(Val->getType());
ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx);
if (!CIdx) return nullptr;
@@ -939,8 +939,8 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(Constant *V1, Constant *V2,
ArrayRef<int> Mask) {
auto *V1VTy = cast<VectorType>(V1->getType());
unsigned MaskNumElts = Mask.size();
- auto MaskEltCount =
- ElementCount::get(MaskNumElts, isa<ScalableVectorType>(V1VTy));
+ auto MaskEltCount =
+ ElementCount::get(MaskNumElts, isa<ScalableVectorType>(V1VTy));
Type *EltTy = V1VTy->getElementType();
// Undefined shuffle mask -> undefined value.
@@ -951,7 +951,7 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(Constant *V1, Constant *V2,
// If the mask is all zeros this is a splat, no need to go through all
// elements.
if (all_of(Mask, [](int Elt) { return Elt == 0; }) &&
- !MaskEltCount.isScalable()) {
+ !MaskEltCount.isScalable()) {
Type *Ty = IntegerType::get(V1->getContext(), 32);
Constant *Elt =
ConstantExpr::getExtractElement(V1, ConstantInt::get(Ty, 0));
@@ -962,7 +962,7 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(Constant *V1, Constant *V2,
if (isa<ScalableVectorType>(V1VTy))
return nullptr;
- unsigned SrcNumElts = V1VTy->getElementCount().getKnownMinValue();
+ unsigned SrcNumElts = V1VTy->getElementCount().getKnownMinValue();
// Loop over the shuffle mask, evaluating each element.
SmallVector<Constant*, 32> Result;
@@ -1104,17 +1104,17 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
return C1;
}
- // Binary operations propagate poison.
- // FIXME: Currently, or/and i1 poison aren't folded into poison because
- // it causes miscompilation when combined with another optimization in
- // InstCombine (select i1 -> and/or). The select fold is wrong, but
- // fixing it requires an effort, so temporarily disable this until it is
- // fixed.
- bool PoisonFold = !C1->getType()->isIntegerTy(1) ||
- (Opcode != Instruction::Or && Opcode != Instruction::And);
- if (PoisonFold && (isa<PoisonValue>(C1) || isa<PoisonValue>(C2)))
- return PoisonValue::get(C1->getType());
-
+ // Binary operations propagate poison.
+ // FIXME: Currently, or/and i1 poison aren't folded into poison because
+ // it causes miscompilation when combined with another optimization in
+ // InstCombine (select i1 -> and/or). The select fold is wrong, but
+ // fixing it requires an effort, so temporarily disable this until it is
+ // fixed.
+ bool PoisonFold = !C1->getType()->isIntegerTy(1) ||
+ (Opcode != Instruction::Or && Opcode != Instruction::And);
+ if (PoisonFold && (isa<PoisonValue>(C1) || isa<PoisonValue>(C2)))
+ return PoisonValue::get(C1->getType());
+
// Handle scalar UndefValue and scalable vector UndefValue. Fixed-length
// vectors are always evaluated per element.
bool IsScalableVector = isa<ScalableVectorType>(C1->getType());
@@ -1439,7 +1439,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
return ConstantFP::get(C1->getContext(), C3V);
}
}
- } else if (auto *VTy = dyn_cast<VectorType>(C1->getType())) {
+ } else if (auto *VTy = dyn_cast<VectorType>(C1->getType())) {
// Fast path for splatted constants.
if (Constant *C2Splat = C2->getSplatValue()) {
if (Instruction::isIntDivRem(Opcode) && C2Splat->isNullValue())
@@ -1451,23 +1451,23 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
}
}
- if (auto *FVTy = dyn_cast<FixedVectorType>(VTy)) {
- // Fold each element and create a vector constant from those constants.
- SmallVector<Constant*, 16> Result;
- Type *Ty = IntegerType::get(FVTy->getContext(), 32);
- for (unsigned i = 0, e = FVTy->getNumElements(); i != e; ++i) {
- Constant *ExtractIdx = ConstantInt::get(Ty, i);
- Constant *LHS = ConstantExpr::getExtractElement(C1, ExtractIdx);
- Constant *RHS = ConstantExpr::getExtractElement(C2, ExtractIdx);
-
- // If any element of a divisor vector is zero, the whole op is undef.
- if (Instruction::isIntDivRem(Opcode) && RHS->isNullValue())
- return UndefValue::get(VTy);
-
- Result.push_back(ConstantExpr::get(Opcode, LHS, RHS));
- }
-
- return ConstantVector::get(Result);
+ if (auto *FVTy = dyn_cast<FixedVectorType>(VTy)) {
+ // Fold each element and create a vector constant from those constants.
+ SmallVector<Constant*, 16> Result;
+ Type *Ty = IntegerType::get(FVTy->getContext(), 32);
+ for (unsigned i = 0, e = FVTy->getNumElements(); i != e; ++i) {
+ Constant *ExtractIdx = ConstantInt::get(Ty, i);
+ Constant *LHS = ConstantExpr::getExtractElement(C1, ExtractIdx);
+ Constant *RHS = ConstantExpr::getExtractElement(C2, ExtractIdx);
+
+ // If any element of a divisor vector is zero, the whole op is undef.
+ if (Instruction::isIntDivRem(Opcode) && RHS->isNullValue())
+ return UndefValue::get(VTy);
+
+ Result.push_back(ConstantExpr::get(Opcode, LHS, RHS));
+ }
+
+ return ConstantVector::get(Result);
}
}
@@ -1782,13 +1782,13 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2,
case Instruction::FPToSI:
break; // We can't evaluate floating point casts or truncations.
- case Instruction::BitCast:
- // If this is a global value cast, check to see if the RHS is also a
- // GlobalValue.
- if (const GlobalValue *GV = dyn_cast<GlobalValue>(CE1Op0))
- if (const GlobalValue *GV2 = dyn_cast<GlobalValue>(V2))
- return areGlobalsPotentiallyEqual(GV, GV2);
- LLVM_FALLTHROUGH;
+ case Instruction::BitCast:
+ // If this is a global value cast, check to see if the RHS is also a
+ // GlobalValue.
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(CE1Op0))
+ if (const GlobalValue *GV2 = dyn_cast<GlobalValue>(V2))
+ return areGlobalsPotentiallyEqual(GV, GV2);
+ LLVM_FALLTHROUGH;
case Instruction::UIToFP:
case Instruction::SIToFP:
case Instruction::ZExt:
@@ -1953,9 +1953,9 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
return Constant::getAllOnesValue(ResultTy);
// Handle some degenerate cases first
- if (isa<PoisonValue>(C1) || isa<PoisonValue>(C2))
- return PoisonValue::get(ResultTy);
-
+ if (isa<PoisonValue>(C1) || isa<PoisonValue>(C2))
+ return PoisonValue::get(ResultTy);
+
if (isa<UndefValue>(C1) || isa<UndefValue>(C2)) {
CmpInst::Predicate Predicate = CmpInst::Predicate(pred);
bool isIntegerPredicate = ICmpInst::isIntPredicate(Predicate);
@@ -2083,22 +2083,22 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
C1VTy->getElementCount(),
ConstantExpr::getCompare(pred, C1Splat, C2Splat));
- // Do not iterate on scalable vector. The number of elements is unknown at
- // compile-time.
- if (isa<ScalableVectorType>(C1VTy))
- return nullptr;
-
+ // Do not iterate on scalable vector. The number of elements is unknown at
+ // compile-time.
+ if (isa<ScalableVectorType>(C1VTy))
+ return nullptr;
+
// If we can constant fold the comparison of each element, constant fold
// the whole vector comparison.
SmallVector<Constant*, 4> ResElts;
Type *Ty = IntegerType::get(C1->getContext(), 32);
// Compare the elements, producing an i1 result or constant expr.
- for (unsigned I = 0, E = C1VTy->getElementCount().getKnownMinValue();
- I != E; ++I) {
+ for (unsigned I = 0, E = C1VTy->getElementCount().getKnownMinValue();
+ I != E; ++I) {
Constant *C1E =
- ConstantExpr::getExtractElement(C1, ConstantInt::get(Ty, I));
+ ConstantExpr::getExtractElement(C1, ConstantInt::get(Ty, I));
Constant *C2E =
- ConstantExpr::getExtractElement(C2, ConstantInt::get(Ty, I));
+ ConstantExpr::getExtractElement(C2, ConstantInt::get(Ty, I));
ResElts.push_back(ConstantExpr::getCompare(pred, C1E, C2E));
}
@@ -2341,9 +2341,9 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
Type *GEPTy = GetElementPtrInst::getGEPReturnType(
PointeeTy, C, makeArrayRef((Value *const *)Idxs.data(), Idxs.size()));
- if (isa<PoisonValue>(C))
- return PoisonValue::get(GEPTy);
-
+ if (isa<PoisonValue>(C))
+ return PoisonValue::get(GEPTy);
+
if (isa<UndefValue>(C))
return UndefValue::get(GEPTy);
diff --git a/contrib/libs/llvm12/lib/IR/ConstantRange.cpp b/contrib/libs/llvm12/lib/IR/ConstantRange.cpp
index 0277ab5b5c..4b0ad1bd25 100644
--- a/contrib/libs/llvm12/lib/IR/ConstantRange.cpp
+++ b/contrib/libs/llvm12/lib/IR/ConstantRange.cpp
@@ -26,7 +26,7 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Operator.h"
#include "llvm/Support/Compiler.h"
@@ -413,21 +413,21 @@ bool ConstantRange::contains(const ConstantRange &Other) const {
return Other.getUpper().ule(Upper) && Lower.ule(Other.getLower());
}
-unsigned ConstantRange::getActiveBits() const {
- if (isEmptySet())
- return 0;
-
- return getUnsignedMax().getActiveBits();
-}
-
-unsigned ConstantRange::getMinSignedBits() const {
- if (isEmptySet())
- return 0;
-
- return std::max(getSignedMin().getMinSignedBits(),
- getSignedMax().getMinSignedBits());
-}
-
+unsigned ConstantRange::getActiveBits() const {
+ if (isEmptySet())
+ return 0;
+
+ return getUnsignedMax().getActiveBits();
+}
+
+unsigned ConstantRange::getMinSignedBits() const {
+ if (isEmptySet())
+ return 0;
+
+ return std::max(getSignedMin().getMinSignedBits(),
+ getSignedMax().getMinSignedBits());
+}
+
ConstantRange ConstantRange::subtract(const APInt &Val) const {
assert(Val.getBitWidth() == getBitWidth() && "Wrong bit width");
// If the set is empty or full, don't modify the endpoints.
@@ -851,54 +851,54 @@ ConstantRange ConstantRange::overflowingBinaryOp(Instruction::BinaryOps BinOp,
}
}
-bool ConstantRange::isIntrinsicSupported(Intrinsic::ID IntrinsicID) {
- switch (IntrinsicID) {
- case Intrinsic::uadd_sat:
- case Intrinsic::usub_sat:
- case Intrinsic::sadd_sat:
- case Intrinsic::ssub_sat:
- case Intrinsic::umin:
- case Intrinsic::umax:
- case Intrinsic::smin:
- case Intrinsic::smax:
- case Intrinsic::abs:
- return true;
- default:
- return false;
- }
-}
-
-ConstantRange ConstantRange::intrinsic(Intrinsic::ID IntrinsicID,
- ArrayRef<ConstantRange> Ops) {
- switch (IntrinsicID) {
- case Intrinsic::uadd_sat:
- return Ops[0].uadd_sat(Ops[1]);
- case Intrinsic::usub_sat:
- return Ops[0].usub_sat(Ops[1]);
- case Intrinsic::sadd_sat:
- return Ops[0].sadd_sat(Ops[1]);
- case Intrinsic::ssub_sat:
- return Ops[0].ssub_sat(Ops[1]);
- case Intrinsic::umin:
- return Ops[0].umin(Ops[1]);
- case Intrinsic::umax:
- return Ops[0].umax(Ops[1]);
- case Intrinsic::smin:
- return Ops[0].smin(Ops[1]);
- case Intrinsic::smax:
- return Ops[0].smax(Ops[1]);
- case Intrinsic::abs: {
- const APInt *IntMinIsPoison = Ops[1].getSingleElement();
- assert(IntMinIsPoison && "Must be known (immarg)");
- assert(IntMinIsPoison->getBitWidth() == 1 && "Must be boolean");
- return Ops[0].abs(IntMinIsPoison->getBoolValue());
- }
- default:
- assert(!isIntrinsicSupported(IntrinsicID) && "Shouldn't be supported");
- llvm_unreachable("Unsupported intrinsic");
- }
-}
-
+bool ConstantRange::isIntrinsicSupported(Intrinsic::ID IntrinsicID) {
+ switch (IntrinsicID) {
+ case Intrinsic::uadd_sat:
+ case Intrinsic::usub_sat:
+ case Intrinsic::sadd_sat:
+ case Intrinsic::ssub_sat:
+ case Intrinsic::umin:
+ case Intrinsic::umax:
+ case Intrinsic::smin:
+ case Intrinsic::smax:
+ case Intrinsic::abs:
+ return true;
+ default:
+ return false;
+ }
+}
+
+ConstantRange ConstantRange::intrinsic(Intrinsic::ID IntrinsicID,
+ ArrayRef<ConstantRange> Ops) {
+ switch (IntrinsicID) {
+ case Intrinsic::uadd_sat:
+ return Ops[0].uadd_sat(Ops[1]);
+ case Intrinsic::usub_sat:
+ return Ops[0].usub_sat(Ops[1]);
+ case Intrinsic::sadd_sat:
+ return Ops[0].sadd_sat(Ops[1]);
+ case Intrinsic::ssub_sat:
+ return Ops[0].ssub_sat(Ops[1]);
+ case Intrinsic::umin:
+ return Ops[0].umin(Ops[1]);
+ case Intrinsic::umax:
+ return Ops[0].umax(Ops[1]);
+ case Intrinsic::smin:
+ return Ops[0].smin(Ops[1]);
+ case Intrinsic::smax:
+ return Ops[0].smax(Ops[1]);
+ case Intrinsic::abs: {
+ const APInt *IntMinIsPoison = Ops[1].getSingleElement();
+ assert(IntMinIsPoison && "Must be known (immarg)");
+ assert(IntMinIsPoison->getBitWidth() == 1 && "Must be boolean");
+ return Ops[0].abs(IntMinIsPoison->getBoolValue());
+ }
+ default:
+ assert(!isIntrinsicSupported(IntrinsicID) && "Shouldn't be supported");
+ llvm_unreachable("Unsupported intrinsic");
+ }
+}
+
ConstantRange
ConstantRange::add(const ConstantRange &Other) const {
if (isEmptySet() || Other.isEmptySet())
@@ -1255,16 +1255,16 @@ ConstantRange ConstantRange::srem(const ConstantRange &RHS) const {
return ConstantRange(std::move(Lower), std::move(Upper));
}
-ConstantRange ConstantRange::binaryNot() const {
- if (isEmptySet())
- return getEmpty();
-
- if (isWrappedSet())
- return getFull();
-
- return ConstantRange(APInt::getAllOnesValue(getBitWidth())).sub(*this);
-}
-
+ConstantRange ConstantRange::binaryNot() const {
+ if (isEmptySet())
+ return getEmpty();
+
+ if (isWrappedSet())
+ return getFull();
+
+ return ConstantRange(APInt::getAllOnesValue(getBitWidth())).sub(*this);
+}
+
ConstantRange
ConstantRange::binaryAnd(const ConstantRange &Other) const {
if (isEmptySet() || Other.isEmptySet())
@@ -1303,12 +1303,12 @@ ConstantRange ConstantRange::binaryXor(const ConstantRange &Other) const {
if (isSingleElement() && Other.isSingleElement())
return {*getSingleElement() ^ *Other.getSingleElement()};
- // Special-case binary complement, since we can give a precise answer.
- if (Other.isSingleElement() && Other.getSingleElement()->isAllOnesValue())
- return binaryNot();
- if (isSingleElement() && getSingleElement()->isAllOnesValue())
- return Other.binaryNot();
-
+ // Special-case binary complement, since we can give a precise answer.
+ if (Other.isSingleElement() && Other.getSingleElement()->isAllOnesValue())
+ return binaryNot();
+ if (isSingleElement() && getSingleElement()->isAllOnesValue())
+ return Other.binaryNot();
+
// TODO: replace this with something less conservative
return getFull();
}
@@ -1498,7 +1498,7 @@ ConstantRange ConstantRange::inverse() const {
return ConstantRange(Upper, Lower);
}
-ConstantRange ConstantRange::abs(bool IntMinIsPoison) const {
+ConstantRange ConstantRange::abs(bool IntMinIsPoison) const {
if (isEmptySet())
return getEmpty();
@@ -1510,23 +1510,23 @@ ConstantRange ConstantRange::abs(bool IntMinIsPoison) const {
else
Lo = APIntOps::umin(Lower, -Upper + 1);
- // If SignedMin is not poison, then it is included in the result range.
- if (IntMinIsPoison)
- return ConstantRange(Lo, APInt::getSignedMinValue(getBitWidth()));
- else
- return ConstantRange(Lo, APInt::getSignedMinValue(getBitWidth()) + 1);
+ // If SignedMin is not poison, then it is included in the result range.
+ if (IntMinIsPoison)
+ return ConstantRange(Lo, APInt::getSignedMinValue(getBitWidth()));
+ else
+ return ConstantRange(Lo, APInt::getSignedMinValue(getBitWidth()) + 1);
}
APInt SMin = getSignedMin(), SMax = getSignedMax();
- // Skip SignedMin if it is poison.
- if (IntMinIsPoison && SMin.isMinSignedValue()) {
- // The range may become empty if it *only* contains SignedMin.
- if (SMax.isMinSignedValue())
- return getEmpty();
- ++SMin;
- }
-
+ // Skip SignedMin if it is poison.
+ if (IntMinIsPoison && SMin.isMinSignedValue()) {
+ // The range may become empty if it *only* contains SignedMin.
+ if (SMax.isMinSignedValue())
+ return getEmpty();
+ ++SMin;
+ }
+
// All non-negative.
if (SMin.isNonNegative())
return *this;
diff --git a/contrib/libs/llvm12/lib/IR/Constants.cpp b/contrib/libs/llvm12/lib/IR/Constants.cpp
index 2c93f98c5d..9f05917cf7 100644
--- a/contrib/libs/llvm12/lib/IR/Constants.cpp
+++ b/contrib/libs/llvm12/lib/IR/Constants.cpp
@@ -161,7 +161,7 @@ bool Constant::isNotOneValue() const {
// Check that vectors don't contain 1
if (auto *VTy = dyn_cast<VectorType>(this->getType())) {
- unsigned NumElts = cast<FixedVectorType>(VTy)->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(VTy)->getNumElements();
for (unsigned i = 0; i != NumElts; ++i) {
Constant *Elt = this->getAggregateElement(i);
if (!Elt || !Elt->isNotOneValue())
@@ -211,7 +211,7 @@ bool Constant::isNotMinSignedValue() const {
// Check that vectors don't contain INT_MIN
if (auto *VTy = dyn_cast<VectorType>(this->getType())) {
- unsigned NumElts = cast<FixedVectorType>(VTy)->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(VTy)->getNumElements();
for (unsigned i = 0; i != NumElts; ++i) {
Constant *Elt = this->getAggregateElement(i);
if (!Elt || !Elt->isNotMinSignedValue())
@@ -227,7 +227,7 @@ bool Constant::isNotMinSignedValue() const {
bool Constant::isFiniteNonZeroFP() const {
if (auto *CFP = dyn_cast<ConstantFP>(this))
return CFP->getValueAPF().isFiniteNonZero();
- auto *VTy = dyn_cast<FixedVectorType>(getType());
+ auto *VTy = dyn_cast<FixedVectorType>(getType());
if (!VTy)
return false;
for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) {
@@ -304,38 +304,38 @@ bool Constant::isElementWiseEqual(Value *Y) const {
return isa<UndefValue>(CmpEq) || match(CmpEq, m_One());
}
-static bool
-containsUndefinedElement(const Constant *C,
- function_ref<bool(const Constant *)> HasFn) {
- if (auto *VTy = dyn_cast<VectorType>(C->getType())) {
- if (HasFn(C))
- return true;
- if (isa<ConstantAggregateZero>(C))
- return false;
- if (isa<ScalableVectorType>(C->getType()))
- return false;
-
- for (unsigned i = 0, e = cast<FixedVectorType>(VTy)->getNumElements();
- i != e; ++i)
- if (HasFn(C->getAggregateElement(i)))
+static bool
+containsUndefinedElement(const Constant *C,
+ function_ref<bool(const Constant *)> HasFn) {
+ if (auto *VTy = dyn_cast<VectorType>(C->getType())) {
+ if (HasFn(C))
+ return true;
+ if (isa<ConstantAggregateZero>(C))
+ return false;
+ if (isa<ScalableVectorType>(C->getType()))
+ return false;
+
+ for (unsigned i = 0, e = cast<FixedVectorType>(VTy)->getNumElements();
+ i != e; ++i)
+ if (HasFn(C->getAggregateElement(i)))
return true;
}
return false;
}
-bool Constant::containsUndefOrPoisonElement() const {
- return containsUndefinedElement(
- this, [&](const auto *C) { return isa<UndefValue>(C); });
-}
-
-bool Constant::containsPoisonElement() const {
- return containsUndefinedElement(
- this, [&](const auto *C) { return isa<PoisonValue>(C); });
-}
-
+bool Constant::containsUndefOrPoisonElement() const {
+ return containsUndefinedElement(
+ this, [&](const auto *C) { return isa<UndefValue>(C); });
+}
+
+bool Constant::containsPoisonElement() const {
+ return containsUndefinedElement(
+ this, [&](const auto *C) { return isa<PoisonValue>(C); });
+}
+
bool Constant::containsConstantExpression() const {
- if (auto *VTy = dyn_cast<FixedVectorType>(getType())) {
+ if (auto *VTy = dyn_cast<FixedVectorType>(getType())) {
for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
if (isa<ConstantExpr>(getAggregateElement(i)))
return true;
@@ -419,23 +419,23 @@ Constant *Constant::getAllOnesValue(Type *Ty) {
}
Constant *Constant::getAggregateElement(unsigned Elt) const {
- if (const auto *CC = dyn_cast<ConstantAggregate>(this))
+ if (const auto *CC = dyn_cast<ConstantAggregate>(this))
return Elt < CC->getNumOperands() ? CC->getOperand(Elt) : nullptr;
- // FIXME: getNumElements() will fail for non-fixed vector types.
- if (isa<ScalableVectorType>(getType()))
- return nullptr;
-
- if (const auto *CAZ = dyn_cast<ConstantAggregateZero>(this))
+ // FIXME: getNumElements() will fail for non-fixed vector types.
+ if (isa<ScalableVectorType>(getType()))
+ return nullptr;
+
+ if (const auto *CAZ = dyn_cast<ConstantAggregateZero>(this))
return Elt < CAZ->getNumElements() ? CAZ->getElementValue(Elt) : nullptr;
- if (const auto *PV = dyn_cast<PoisonValue>(this))
- return Elt < PV->getNumElements() ? PV->getElementValue(Elt) : nullptr;
-
- if (const auto *UV = dyn_cast<UndefValue>(this))
+ if (const auto *PV = dyn_cast<PoisonValue>(this))
+ return Elt < PV->getNumElements() ? PV->getElementValue(Elt) : nullptr;
+
+ if (const auto *UV = dyn_cast<UndefValue>(this))
return Elt < UV->getNumElements() ? UV->getElementValue(Elt) : nullptr;
- if (const auto *CDS = dyn_cast<ConstantDataSequential>(this))
+ if (const auto *CDS = dyn_cast<ConstantDataSequential>(this))
return Elt < CDS->getNumElements() ? CDS->getElementAsConstant(Elt)
: nullptr;
return nullptr;
@@ -527,15 +527,15 @@ void llvm::deleteConstant(Constant *C) {
case Constant::BlockAddressVal:
delete static_cast<BlockAddress *>(C);
break;
- case Constant::DSOLocalEquivalentVal:
- delete static_cast<DSOLocalEquivalent *>(C);
- break;
+ case Constant::DSOLocalEquivalentVal:
+ delete static_cast<DSOLocalEquivalent *>(C);
+ break;
case Constant::UndefValueVal:
delete static_cast<UndefValue *>(C);
break;
- case Constant::PoisonValueVal:
- delete static_cast<PoisonValue *>(C);
- break;
+ case Constant::PoisonValueVal:
+ delete static_cast<PoisonValue *>(C);
+ break;
case Constant::ConstantExprVal:
if (isa<UnaryConstantExpr>(C))
delete static_cast<UnaryConstantExpr *>(C);
@@ -678,17 +678,17 @@ bool Constant::needsRelocation() const {
return false;
// Relative pointers do not need to be dynamically relocated.
- if (auto *RHSGV =
- dyn_cast<GlobalValue>(RHSOp0->stripInBoundsConstantOffsets())) {
- auto *LHS = LHSOp0->stripInBoundsConstantOffsets();
- if (auto *LHSGV = dyn_cast<GlobalValue>(LHS)) {
+ if (auto *RHSGV =
+ dyn_cast<GlobalValue>(RHSOp0->stripInBoundsConstantOffsets())) {
+ auto *LHS = LHSOp0->stripInBoundsConstantOffsets();
+ if (auto *LHSGV = dyn_cast<GlobalValue>(LHS)) {
if (LHSGV->isDSOLocal() && RHSGV->isDSOLocal())
return false;
- } else if (isa<DSOLocalEquivalent>(LHS)) {
- if (RHSGV->isDSOLocal())
- return false;
- }
- }
+ } else if (isa<DSOLocalEquivalent>(LHS)) {
+ if (RHSGV->isDSOLocal())
+ return false;
+ }
+ }
}
}
}
@@ -768,53 +768,53 @@ Constant *Constant::replaceUndefsWith(Constant *C, Constant *Replacement) {
return ConstantVector::get(NewC);
}
-Constant *Constant::mergeUndefsWith(Constant *C, Constant *Other) {
- assert(C && Other && "Expected non-nullptr constant arguments");
- if (match(C, m_Undef()))
- return C;
-
- Type *Ty = C->getType();
- if (match(Other, m_Undef()))
- return UndefValue::get(Ty);
-
- auto *VTy = dyn_cast<FixedVectorType>(Ty);
- if (!VTy)
- return C;
-
- Type *EltTy = VTy->getElementType();
- unsigned NumElts = VTy->getNumElements();
- assert(isa<FixedVectorType>(Other->getType()) &&
- cast<FixedVectorType>(Other->getType())->getNumElements() == NumElts &&
- "Type mismatch");
-
- bool FoundExtraUndef = false;
- SmallVector<Constant *, 32> NewC(NumElts);
- for (unsigned I = 0; I != NumElts; ++I) {
- NewC[I] = C->getAggregateElement(I);
- Constant *OtherEltC = Other->getAggregateElement(I);
- assert(NewC[I] && OtherEltC && "Unknown vector element");
- if (!match(NewC[I], m_Undef()) && match(OtherEltC, m_Undef())) {
- NewC[I] = UndefValue::get(EltTy);
- FoundExtraUndef = true;
- }
- }
- if (FoundExtraUndef)
- return ConstantVector::get(NewC);
- return C;
-}
-
-bool Constant::isManifestConstant() const {
- if (isa<ConstantData>(this))
- return true;
- if (isa<ConstantAggregate>(this) || isa<ConstantExpr>(this)) {
- for (const Value *Op : operand_values())
- if (!cast<Constant>(Op)->isManifestConstant())
- return false;
- return true;
- }
- return false;
-}
-
+Constant *Constant::mergeUndefsWith(Constant *C, Constant *Other) {
+ assert(C && Other && "Expected non-nullptr constant arguments");
+ if (match(C, m_Undef()))
+ return C;
+
+ Type *Ty = C->getType();
+ if (match(Other, m_Undef()))
+ return UndefValue::get(Ty);
+
+ auto *VTy = dyn_cast<FixedVectorType>(Ty);
+ if (!VTy)
+ return C;
+
+ Type *EltTy = VTy->getElementType();
+ unsigned NumElts = VTy->getNumElements();
+ assert(isa<FixedVectorType>(Other->getType()) &&
+ cast<FixedVectorType>(Other->getType())->getNumElements() == NumElts &&
+ "Type mismatch");
+
+ bool FoundExtraUndef = false;
+ SmallVector<Constant *, 32> NewC(NumElts);
+ for (unsigned I = 0; I != NumElts; ++I) {
+ NewC[I] = C->getAggregateElement(I);
+ Constant *OtherEltC = Other->getAggregateElement(I);
+ assert(NewC[I] && OtherEltC && "Unknown vector element");
+ if (!match(NewC[I], m_Undef()) && match(OtherEltC, m_Undef())) {
+ NewC[I] = UndefValue::get(EltTy);
+ FoundExtraUndef = true;
+ }
+ }
+ if (FoundExtraUndef)
+ return ConstantVector::get(NewC);
+ return C;
+}
+
+bool Constant::isManifestConstant() const {
+ if (isa<ConstantData>(this))
+ return true;
+ if (isa<ConstantAggregate>(this) || isa<ConstantExpr>(this)) {
+ for (const Value *Op : operand_values())
+ if (!cast<Constant>(Op)->isManifestConstant())
+ return false;
+ return true;
+ }
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// ConstantInt
//===----------------------------------------------------------------------===//
@@ -838,10 +838,10 @@ ConstantInt *ConstantInt::getFalse(LLVMContext &Context) {
return pImpl->TheFalseVal;
}
-ConstantInt *ConstantInt::getBool(LLVMContext &Context, bool V) {
- return V ? getTrue(Context) : getFalse(Context);
-}
-
+ConstantInt *ConstantInt::getBool(LLVMContext &Context, bool V) {
+ return V ? getTrue(Context) : getFalse(Context);
+}
+
Constant *ConstantInt::getTrue(Type *Ty) {
assert(Ty->isIntOrIntVectorTy(1) && "Type not i1 or vector of i1.");
ConstantInt *TrueC = ConstantInt::getTrue(Ty->getContext());
@@ -858,10 +858,10 @@ Constant *ConstantInt::getFalse(Type *Ty) {
return FalseC;
}
-Constant *ConstantInt::getBool(Type *Ty, bool V) {
- return V ? getTrue(Ty) : getFalse(Ty);
-}
-
+Constant *ConstantInt::getBool(Type *Ty, bool V) {
+ return V ? getTrue(Ty) : getFalse(Ty);
+}
+
// Get a ConstantInt from an APInt.
ConstantInt *ConstantInt::get(LLVMContext &Context, const APInt &V) {
// get an existing value or the insertion position
@@ -928,7 +928,7 @@ Constant *ConstantFP::get(Type *Ty, double V) {
APFloat FV(V);
bool ignored;
- FV.convert(Ty->getScalarType()->getFltSemantics(),
+ FV.convert(Ty->getScalarType()->getFltSemantics(),
APFloat::rmNearestTiesToEven, &ignored);
Constant *C = get(Context, FV);
@@ -954,7 +954,7 @@ Constant *ConstantFP::get(Type *Ty, const APFloat &V) {
Constant *ConstantFP::get(Type *Ty, StringRef Str) {
LLVMContext &Context = Ty->getContext();
- APFloat FV(Ty->getScalarType()->getFltSemantics(), Str);
+ APFloat FV(Ty->getScalarType()->getFltSemantics(), Str);
Constant *C = get(Context, FV);
// For vectors, broadcast the value.
@@ -965,7 +965,7 @@ Constant *ConstantFP::get(Type *Ty, StringRef Str) {
}
Constant *ConstantFP::getNaN(Type *Ty, bool Negative, uint64_t Payload) {
- const fltSemantics &Semantics = Ty->getScalarType()->getFltSemantics();
+ const fltSemantics &Semantics = Ty->getScalarType()->getFltSemantics();
APFloat NaN = APFloat::getNaN(Semantics, Negative, Payload);
Constant *C = get(Ty->getContext(), NaN);
@@ -976,7 +976,7 @@ Constant *ConstantFP::getNaN(Type *Ty, bool Negative, uint64_t Payload) {
}
Constant *ConstantFP::getQNaN(Type *Ty, bool Negative, APInt *Payload) {
- const fltSemantics &Semantics = Ty->getScalarType()->getFltSemantics();
+ const fltSemantics &Semantics = Ty->getScalarType()->getFltSemantics();
APFloat NaN = APFloat::getQNaN(Semantics, Negative, Payload);
Constant *C = get(Ty->getContext(), NaN);
@@ -987,7 +987,7 @@ Constant *ConstantFP::getQNaN(Type *Ty, bool Negative, APInt *Payload) {
}
Constant *ConstantFP::getSNaN(Type *Ty, bool Negative, APInt *Payload) {
- const fltSemantics &Semantics = Ty->getScalarType()->getFltSemantics();
+ const fltSemantics &Semantics = Ty->getScalarType()->getFltSemantics();
APFloat NaN = APFloat::getSNaN(Semantics, Negative, Payload);
Constant *C = get(Ty->getContext(), NaN);
@@ -998,7 +998,7 @@ Constant *ConstantFP::getSNaN(Type *Ty, bool Negative, APInt *Payload) {
}
Constant *ConstantFP::getNegativeZero(Type *Ty) {
- const fltSemantics &Semantics = Ty->getScalarType()->getFltSemantics();
+ const fltSemantics &Semantics = Ty->getScalarType()->getFltSemantics();
APFloat NegZero = APFloat::getZero(Semantics, /*Negative=*/true);
Constant *C = get(Ty->getContext(), NegZero);
@@ -1024,7 +1024,7 @@ ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& V) {
std::unique_ptr<ConstantFP> &Slot = pImpl->FPConstants[V];
if (!Slot) {
- Type *Ty = Type::getFloatingPointTy(Context, V.getSemantics());
+ Type *Ty = Type::getFloatingPointTy(Context, V.getSemantics());
Slot.reset(new ConstantFP(Ty, V));
}
@@ -1032,7 +1032,7 @@ ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& V) {
}
Constant *ConstantFP::getInfinity(Type *Ty, bool Negative) {
- const fltSemantics &Semantics = Ty->getScalarType()->getFltSemantics();
+ const fltSemantics &Semantics = Ty->getScalarType()->getFltSemantics();
Constant *C = get(Ty->getContext(), APFloat::getInf(Semantics, Negative));
if (VectorType *VTy = dyn_cast<VectorType>(Ty))
@@ -1043,7 +1043,7 @@ Constant *ConstantFP::getInfinity(Type *Ty, bool Negative) {
ConstantFP::ConstantFP(Type *Ty, const APFloat &V)
: ConstantData(Ty, ConstantFPVal), Val(V) {
- assert(&V.getSemantics() == &Ty->getFltSemantics() &&
+ assert(&V.getSemantics() == &Ty->getFltSemantics() &&
"FP type Mismatch");
}
@@ -1087,7 +1087,7 @@ unsigned ConstantAggregateZero::getNumElements() const {
if (auto *AT = dyn_cast<ArrayType>(Ty))
return AT->getNumElements();
if (auto *VT = dyn_cast<VectorType>(Ty))
- return cast<FixedVectorType>(VT)->getNumElements();
+ return cast<FixedVectorType>(VT)->getNumElements();
return Ty->getStructNumElements();
}
@@ -1122,37 +1122,37 @@ unsigned UndefValue::getNumElements() const {
if (auto *AT = dyn_cast<ArrayType>(Ty))
return AT->getNumElements();
if (auto *VT = dyn_cast<VectorType>(Ty))
- return cast<FixedVectorType>(VT)->getNumElements();
+ return cast<FixedVectorType>(VT)->getNumElements();
return Ty->getStructNumElements();
}
//===----------------------------------------------------------------------===//
-// PoisonValue Implementation
-//===----------------------------------------------------------------------===//
-
-PoisonValue *PoisonValue::getSequentialElement() const {
- if (ArrayType *ATy = dyn_cast<ArrayType>(getType()))
- return PoisonValue::get(ATy->getElementType());
- return PoisonValue::get(cast<VectorType>(getType())->getElementType());
-}
-
-PoisonValue *PoisonValue::getStructElement(unsigned Elt) const {
- return PoisonValue::get(getType()->getStructElementType(Elt));
-}
-
-PoisonValue *PoisonValue::getElementValue(Constant *C) const {
- if (isa<ArrayType>(getType()) || isa<VectorType>(getType()))
- return getSequentialElement();
- return getStructElement(cast<ConstantInt>(C)->getZExtValue());
-}
-
-PoisonValue *PoisonValue::getElementValue(unsigned Idx) const {
- if (isa<ArrayType>(getType()) || isa<VectorType>(getType()))
- return getSequentialElement();
- return getStructElement(Idx);
-}
-
-//===----------------------------------------------------------------------===//
+// PoisonValue Implementation
+//===----------------------------------------------------------------------===//
+
+PoisonValue *PoisonValue::getSequentialElement() const {
+ if (ArrayType *ATy = dyn_cast<ArrayType>(getType()))
+ return PoisonValue::get(ATy->getElementType());
+ return PoisonValue::get(cast<VectorType>(getType())->getElementType());
+}
+
+PoisonValue *PoisonValue::getStructElement(unsigned Elt) const {
+ return PoisonValue::get(getType()->getStructElementType(Elt));
+}
+
+PoisonValue *PoisonValue::getElementValue(Constant *C) const {
+ if (isa<ArrayType>(getType()) || isa<VectorType>(getType()))
+ return getSequentialElement();
+ return getStructElement(cast<ConstantInt>(C)->getZExtValue());
+}
+
+PoisonValue *PoisonValue::getElementValue(unsigned Idx) const {
+ if (isa<ArrayType>(getType()) || isa<VectorType>(getType()))
+ return getSequentialElement();
+ return getStructElement(Idx);
+}
+
+//===----------------------------------------------------------------------===//
// ConstantXXX Classes
//===----------------------------------------------------------------------===//
@@ -1330,7 +1330,7 @@ Constant *ConstantStruct::get(StructType *ST, ArrayRef<Constant*> V) {
ConstantVector::ConstantVector(VectorType *T, ArrayRef<Constant *> V)
: ConstantAggregate(T, ConstantVectorVal, V) {
- assert(V.size() == cast<FixedVectorType>(T)->getNumElements() &&
+ assert(V.size() == cast<FixedVectorType>(T)->getNumElements() &&
"Invalid initializer for constant vector");
}
@@ -1351,20 +1351,20 @@ Constant *ConstantVector::getImpl(ArrayRef<Constant*> V) {
Constant *C = V[0];
bool isZero = C->isNullValue();
bool isUndef = isa<UndefValue>(C);
- bool isPoison = isa<PoisonValue>(C);
+ bool isPoison = isa<PoisonValue>(C);
if (isZero || isUndef) {
for (unsigned i = 1, e = V.size(); i != e; ++i)
if (V[i] != C) {
- isZero = isUndef = isPoison = false;
+ isZero = isUndef = isPoison = false;
break;
}
}
if (isZero)
return ConstantAggregateZero::get(T);
- if (isPoison)
- return PoisonValue::get(T);
+ if (isPoison)
+ return PoisonValue::get(T);
if (isUndef)
return UndefValue::get(T);
@@ -1379,14 +1379,14 @@ Constant *ConstantVector::getImpl(ArrayRef<Constant*> V) {
}
Constant *ConstantVector::getSplat(ElementCount EC, Constant *V) {
- if (!EC.isScalable()) {
+ if (!EC.isScalable()) {
// If this splat is compatible with ConstantDataVector, use it instead of
// ConstantVector.
if ((isa<ConstantFP>(V) || isa<ConstantInt>(V)) &&
ConstantDataSequential::isElementTypeCompatible(V->getType()))
- return ConstantDataVector::getSplat(EC.getKnownMinValue(), V);
+ return ConstantDataVector::getSplat(EC.getKnownMinValue(), V);
- SmallVector<Constant *, 32> Elts(EC.getKnownMinValue(), V);
+ SmallVector<Constant *, 32> Elts(EC.getKnownMinValue(), V);
return get(Elts);
}
@@ -1403,7 +1403,7 @@ Constant *ConstantVector::getSplat(ElementCount EC, Constant *V) {
Constant *UndefV = UndefValue::get(VTy);
V = ConstantExpr::getInsertElement(UndefV, V, ConstantInt::get(I32Ty, 0));
// Build shuffle mask to perform the splat.
- SmallVector<int, 8> Zeros(EC.getKnownMinValue(), 0);
+ SmallVector<int, 8> Zeros(EC.getKnownMinValue(), 0);
// Splat.
return ConstantExpr::getShuffleVector(V, UndefV, Zeros);
}
@@ -1528,8 +1528,8 @@ Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
OnlyIfReducedTy);
case Instruction::ExtractValue:
return ConstantExpr::getExtractValue(Ops[0], getIndices(), OnlyIfReducedTy);
- case Instruction::FNeg:
- return ConstantExpr::getFNeg(Ops[0]);
+ case Instruction::FNeg:
+ return ConstantExpr::getFNeg(Ops[0]);
case Instruction::ShuffleVector:
return ConstantExpr::getShuffleVector(Ops[0], Ops[1], getShuffleMask(),
OnlyIfReducedTy);
@@ -1690,7 +1690,7 @@ Constant *Constant::getSplatValue(bool AllowUndefs) const {
ConstantInt *Index = dyn_cast<ConstantInt>(IElt->getOperand(2));
if (Index && Index->getValue() == 0 &&
- llvm::all_of(Mask, [](int I) { return I == 0; }))
+ llvm::all_of(Mask, [](int I) { return I == 0; }))
return SplatVal;
}
}
@@ -1762,28 +1762,28 @@ UndefValue *UndefValue::get(Type *Ty) {
/// Remove the constant from the constant table.
void UndefValue::destroyConstantImpl() {
// Free the constant and any dangling references to it.
- if (getValueID() == UndefValueVal) {
- getContext().pImpl->UVConstants.erase(getType());
- } else if (getValueID() == PoisonValueVal) {
- getContext().pImpl->PVConstants.erase(getType());
- }
- llvm_unreachable("Not a undef or a poison!");
-}
-
-PoisonValue *PoisonValue::get(Type *Ty) {
- std::unique_ptr<PoisonValue> &Entry = Ty->getContext().pImpl->PVConstants[Ty];
- if (!Entry)
- Entry.reset(new PoisonValue(Ty));
-
- return Entry.get();
-}
-
-/// Remove the constant from the constant table.
-void PoisonValue::destroyConstantImpl() {
- // Free the constant and any dangling references to it.
- getContext().pImpl->PVConstants.erase(getType());
-}
-
+ if (getValueID() == UndefValueVal) {
+ getContext().pImpl->UVConstants.erase(getType());
+ } else if (getValueID() == PoisonValueVal) {
+ getContext().pImpl->PVConstants.erase(getType());
+ }
+ llvm_unreachable("Not a undef or a poison!");
+}
+
+PoisonValue *PoisonValue::get(Type *Ty) {
+ std::unique_ptr<PoisonValue> &Entry = Ty->getContext().pImpl->PVConstants[Ty];
+ if (!Entry)
+ Entry.reset(new PoisonValue(Ty));
+
+ return Entry.get();
+}
+
+/// Remove the constant from the constant table.
+void PoisonValue::destroyConstantImpl() {
+ // Free the constant and any dangling references to it.
+ getContext().pImpl->PVConstants.erase(getType());
+}
+
BlockAddress *BlockAddress::get(BasicBlock *BB) {
assert(BB->getParent() && "Block must have a parent");
return get(BB->getParent(), BB);
@@ -1862,58 +1862,58 @@ Value *BlockAddress::handleOperandChangeImpl(Value *From, Value *To) {
return nullptr;
}
-DSOLocalEquivalent *DSOLocalEquivalent::get(GlobalValue *GV) {
- DSOLocalEquivalent *&Equiv = GV->getContext().pImpl->DSOLocalEquivalents[GV];
- if (!Equiv)
- Equiv = new DSOLocalEquivalent(GV);
-
- assert(Equiv->getGlobalValue() == GV &&
- "DSOLocalFunction does not match the expected global value");
- return Equiv;
-}
-
-DSOLocalEquivalent::DSOLocalEquivalent(GlobalValue *GV)
- : Constant(GV->getType(), Value::DSOLocalEquivalentVal, &Op<0>(), 1) {
- setOperand(0, GV);
-}
-
-/// Remove the constant from the constant table.
-void DSOLocalEquivalent::destroyConstantImpl() {
- const GlobalValue *GV = getGlobalValue();
- GV->getContext().pImpl->DSOLocalEquivalents.erase(GV);
-}
-
-Value *DSOLocalEquivalent::handleOperandChangeImpl(Value *From, Value *To) {
- assert(From == getGlobalValue() && "Changing value does not match operand.");
- assert(isa<Constant>(To) && "Can only replace the operands with a constant");
-
- // The replacement is with another global value.
- if (const auto *ToObj = dyn_cast<GlobalValue>(To)) {
- DSOLocalEquivalent *&NewEquiv =
- getContext().pImpl->DSOLocalEquivalents[ToObj];
- if (NewEquiv)
- return llvm::ConstantExpr::getBitCast(NewEquiv, getType());
- }
-
- // If the argument is replaced with a null value, just replace this constant
- // with a null value.
- if (cast<Constant>(To)->isNullValue())
- return To;
-
- // The replacement could be a bitcast or an alias to another function. We can
- // replace it with a bitcast to the dso_local_equivalent of that function.
- auto *Func = cast<Function>(To->stripPointerCastsAndAliases());
- DSOLocalEquivalent *&NewEquiv = getContext().pImpl->DSOLocalEquivalents[Func];
- if (NewEquiv)
- return llvm::ConstantExpr::getBitCast(NewEquiv, getType());
-
- // Replace this with the new one.
- getContext().pImpl->DSOLocalEquivalents.erase(getGlobalValue());
- NewEquiv = this;
- setOperand(0, Func);
- return nullptr;
-}
-
+DSOLocalEquivalent *DSOLocalEquivalent::get(GlobalValue *GV) {
+ DSOLocalEquivalent *&Equiv = GV->getContext().pImpl->DSOLocalEquivalents[GV];
+ if (!Equiv)
+ Equiv = new DSOLocalEquivalent(GV);
+
+ assert(Equiv->getGlobalValue() == GV &&
+ "DSOLocalFunction does not match the expected global value");
+ return Equiv;
+}
+
+DSOLocalEquivalent::DSOLocalEquivalent(GlobalValue *GV)
+ : Constant(GV->getType(), Value::DSOLocalEquivalentVal, &Op<0>(), 1) {
+ setOperand(0, GV);
+}
+
+/// Remove the constant from the constant table.
+void DSOLocalEquivalent::destroyConstantImpl() {
+ const GlobalValue *GV = getGlobalValue();
+ GV->getContext().pImpl->DSOLocalEquivalents.erase(GV);
+}
+
+Value *DSOLocalEquivalent::handleOperandChangeImpl(Value *From, Value *To) {
+ assert(From == getGlobalValue() && "Changing value does not match operand.");
+ assert(isa<Constant>(To) && "Can only replace the operands with a constant");
+
+ // The replacement is with another global value.
+ if (const auto *ToObj = dyn_cast<GlobalValue>(To)) {
+ DSOLocalEquivalent *&NewEquiv =
+ getContext().pImpl->DSOLocalEquivalents[ToObj];
+ if (NewEquiv)
+ return llvm::ConstantExpr::getBitCast(NewEquiv, getType());
+ }
+
+ // If the argument is replaced with a null value, just replace this constant
+ // with a null value.
+ if (cast<Constant>(To)->isNullValue())
+ return To;
+
+ // The replacement could be a bitcast or an alias to another function. We can
+ // replace it with a bitcast to the dso_local_equivalent of that function.
+ auto *Func = cast<Function>(To->stripPointerCastsAndAliases());
+ DSOLocalEquivalent *&NewEquiv = getContext().pImpl->DSOLocalEquivalents[Func];
+ if (NewEquiv)
+ return llvm::ConstantExpr::getBitCast(NewEquiv, getType());
+
+ // Replace this with the new one.
+ getContext().pImpl->DSOLocalEquivalents.erase(getGlobalValue());
+ NewEquiv = this;
+ setOperand(0, Func);
+ return nullptr;
+}
+
//---- ConstantExpr::get() implementations.
//
@@ -2162,8 +2162,8 @@ Constant *ConstantExpr::getPtrToInt(Constant *C, Type *DstTy,
"PtrToInt destination must be integer or integer vector");
assert(isa<VectorType>(C->getType()) == isa<VectorType>(DstTy));
if (isa<VectorType>(C->getType()))
- assert(cast<FixedVectorType>(C->getType())->getNumElements() ==
- cast<FixedVectorType>(DstTy)->getNumElements() &&
+ assert(cast<FixedVectorType>(C->getType())->getNumElements() ==
+ cast<FixedVectorType>(DstTy)->getNumElements() &&
"Invalid cast between a different number of vector elements");
return getFoldedCast(Instruction::PtrToInt, C, DstTy, OnlyIfReduced);
}
@@ -2176,8 +2176,8 @@ Constant *ConstantExpr::getIntToPtr(Constant *C, Type *DstTy,
"IntToPtr destination must be a pointer or pointer vector");
assert(isa<VectorType>(C->getType()) == isa<VectorType>(DstTy));
if (isa<VectorType>(C->getType()))
- assert(cast<VectorType>(C->getType())->getElementCount() ==
- cast<VectorType>(DstTy)->getElementCount() &&
+ assert(cast<VectorType>(C->getType())->getElementCount() ==
+ cast<VectorType>(DstTy)->getElementCount() &&
"Invalid cast between a different number of vector elements");
return getFoldedCast(Instruction::IntToPtr, C, DstTy, OnlyIfReduced);
}
@@ -2208,8 +2208,8 @@ Constant *ConstantExpr::getAddrSpaceCast(Constant *C, Type *DstTy,
Type *MidTy = PointerType::get(DstElemTy, SrcScalarTy->getAddressSpace());
if (VectorType *VT = dyn_cast<VectorType>(DstTy)) {
// Handle vectors of pointers.
- MidTy = FixedVectorType::get(MidTy,
- cast<FixedVectorType>(VT)->getNumElements());
+ MidTy = FixedVectorType::get(MidTy,
+ cast<FixedVectorType>(VT)->getNumElements());
}
C = getBitCast(C, MidTy);
}
@@ -2406,7 +2406,7 @@ Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C,
unsigned AS = C->getType()->getPointerAddressSpace();
Type *ReqTy = DestTy->getPointerTo(AS);
- auto EltCount = ElementCount::getFixed(0);
+ auto EltCount = ElementCount::getFixed(0);
if (VectorType *VecTy = dyn_cast<VectorType>(C->getType()))
EltCount = VecTy->getElementCount();
else
@@ -2414,7 +2414,7 @@ Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C,
if (VectorType *VecTy = dyn_cast<VectorType>(Idx->getType()))
EltCount = VecTy->getElementCount();
- if (EltCount.isNonZero())
+ if (EltCount.isNonZero())
ReqTy = VectorType::get(ReqTy, EltCount);
if (OnlyIfReducedTy == ReqTy)
@@ -2434,7 +2434,7 @@ Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C,
if (GTI.isStruct() && Idx->getType()->isVectorTy()) {
Idx = Idx->getSplatValue();
- } else if (GTI.isSequential() && EltCount.isNonZero() &&
+ } else if (GTI.isSequential() && EltCount.isNonZero() &&
!Idx->getType()->isVectorTy()) {
Idx = ConstantVector::getSplat(EltCount, Idx);
}
@@ -2710,11 +2710,11 @@ Constant *ConstantExpr::getXor(Constant *C1, Constant *C2) {
return get(Instruction::Xor, C1, C2);
}
-Constant *ConstantExpr::getUMin(Constant *C1, Constant *C2) {
- Constant *Cmp = ConstantExpr::getICmp(CmpInst::ICMP_ULT, C1, C2);
- return getSelect(Cmp, C1, C2);
-}
-
+Constant *ConstantExpr::getUMin(Constant *C1, Constant *C2) {
+ Constant *Cmp = ConstantExpr::getICmp(CmpInst::ICMP_ULT, C1, C2);
+ return getSelect(Cmp, C1, C2);
+}
+
Constant *ConstantExpr::getShl(Constant *C1, Constant *C2,
bool HasNUW, bool HasNSW) {
unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) |
@@ -2732,35 +2732,35 @@ Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2, bool isExact) {
isExact ? PossiblyExactOperator::IsExact : 0);
}
-Constant *ConstantExpr::getExactLogBase2(Constant *C) {
- Type *Ty = C->getType();
- const APInt *IVal;
- if (match(C, m_APInt(IVal)) && IVal->isPowerOf2())
- return ConstantInt::get(Ty, IVal->logBase2());
-
- // FIXME: We can extract pow of 2 of splat constant for scalable vectors.
- auto *VecTy = dyn_cast<FixedVectorType>(Ty);
- if (!VecTy)
- return nullptr;
-
- SmallVector<Constant *, 4> Elts;
- for (unsigned I = 0, E = VecTy->getNumElements(); I != E; ++I) {
- Constant *Elt = C->getAggregateElement(I);
- if (!Elt)
- return nullptr;
- // Note that log2(iN undef) is *NOT* iN undef, because log2(iN undef) u< N.
- if (isa<UndefValue>(Elt)) {
- Elts.push_back(Constant::getNullValue(Ty->getScalarType()));
- continue;
- }
- if (!match(Elt, m_APInt(IVal)) || !IVal->isPowerOf2())
- return nullptr;
- Elts.push_back(ConstantInt::get(Ty->getScalarType(), IVal->logBase2()));
- }
-
- return ConstantVector::get(Elts);
-}
-
+Constant *ConstantExpr::getExactLogBase2(Constant *C) {
+ Type *Ty = C->getType();
+ const APInt *IVal;
+ if (match(C, m_APInt(IVal)) && IVal->isPowerOf2())
+ return ConstantInt::get(Ty, IVal->logBase2());
+
+ // FIXME: We can extract pow of 2 of splat constant for scalable vectors.
+ auto *VecTy = dyn_cast<FixedVectorType>(Ty);
+ if (!VecTy)
+ return nullptr;
+
+ SmallVector<Constant *, 4> Elts;
+ for (unsigned I = 0, E = VecTy->getNumElements(); I != E; ++I) {
+ Constant *Elt = C->getAggregateElement(I);
+ if (!Elt)
+ return nullptr;
+ // Note that log2(iN undef) is *NOT* iN undef, because log2(iN undef) u< N.
+ if (isa<UndefValue>(Elt)) {
+ Elts.push_back(Constant::getNullValue(Ty->getScalarType()));
+ continue;
+ }
+ if (!match(Elt, m_APInt(IVal)) || !IVal->isPowerOf2())
+ return nullptr;
+ Elts.push_back(ConstantInt::get(Ty->getScalarType(), IVal->logBase2()));
+ }
+
+ return ConstantVector::get(Elts);
+}
+
Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty,
bool AllowRHSConstant) {
assert(Instruction::isBinaryOp(Opcode) && "Only binops allowed");
@@ -2885,7 +2885,7 @@ bool ConstantDataSequential::isElementTypeCompatible(Type *Ty) {
unsigned ConstantDataSequential::getNumElements() const {
if (ArrayType *AT = dyn_cast<ArrayType>(getType()))
return AT->getNumElements();
- return cast<FixedVectorType>(getType())->getNumElements();
+ return cast<FixedVectorType>(getType())->getNumElements();
}
@@ -2934,57 +2934,57 @@ Constant *ConstantDataSequential::getImpl(StringRef Elements, Type *Ty) {
// body but different types. For example, 0,0,0,1 could be a 4 element array
// of i8, or a 1-element array of i32. They'll both end up in the same
/// StringMap bucket, linked up by their Next pointers. Walk the list.
- std::unique_ptr<ConstantDataSequential> *Entry = &Slot.second;
- for (; *Entry; Entry = &(*Entry)->Next)
- if ((*Entry)->getType() == Ty)
- return Entry->get();
+ std::unique_ptr<ConstantDataSequential> *Entry = &Slot.second;
+ for (; *Entry; Entry = &(*Entry)->Next)
+ if ((*Entry)->getType() == Ty)
+ return Entry->get();
// Okay, we didn't get a hit. Create a node of the right class, link it in,
// and return it.
- if (isa<ArrayType>(Ty)) {
- // Use reset because std::make_unique can't access the constructor.
- Entry->reset(new ConstantDataArray(Ty, Slot.first().data()));
- return Entry->get();
- }
+ if (isa<ArrayType>(Ty)) {
+ // Use reset because std::make_unique can't access the constructor.
+ Entry->reset(new ConstantDataArray(Ty, Slot.first().data()));
+ return Entry->get();
+ }
assert(isa<VectorType>(Ty));
- // Use reset because std::make_unique can't access the constructor.
- Entry->reset(new ConstantDataVector(Ty, Slot.first().data()));
- return Entry->get();
+ // Use reset because std::make_unique can't access the constructor.
+ Entry->reset(new ConstantDataVector(Ty, Slot.first().data()));
+ return Entry->get();
}
void ConstantDataSequential::destroyConstantImpl() {
// Remove the constant from the StringMap.
- StringMap<std::unique_ptr<ConstantDataSequential>> &CDSConstants =
- getType()->getContext().pImpl->CDSConstants;
+ StringMap<std::unique_ptr<ConstantDataSequential>> &CDSConstants =
+ getType()->getContext().pImpl->CDSConstants;
- auto Slot = CDSConstants.find(getRawDataValues());
+ auto Slot = CDSConstants.find(getRawDataValues());
assert(Slot != CDSConstants.end() && "CDS not found in uniquing table");
- std::unique_ptr<ConstantDataSequential> *Entry = &Slot->getValue();
+ std::unique_ptr<ConstantDataSequential> *Entry = &Slot->getValue();
// Remove the entry from the hash table.
if (!(*Entry)->Next) {
// If there is only one value in the bucket (common case) it must be this
// entry, and removing the entry should remove the bucket completely.
- assert(Entry->get() == this && "Hash mismatch in ConstantDataSequential");
+ assert(Entry->get() == this && "Hash mismatch in ConstantDataSequential");
getContext().pImpl->CDSConstants.erase(Slot);
- return;
- }
-
- // Otherwise, there are multiple entries linked off the bucket, unlink the
- // node we care about but keep the bucket around.
- while (true) {
- std::unique_ptr<ConstantDataSequential> &Node = *Entry;
- assert(Node && "Didn't find entry in its uniquing hash table!");
- // If we found our entry, unlink it from the list and we're done.
- if (Node.get() == this) {
- Node = std::move(Node->Next);
- return;
+ return;
+ }
+
+ // Otherwise, there are multiple entries linked off the bucket, unlink the
+ // node we care about but keep the bucket around.
+ while (true) {
+ std::unique_ptr<ConstantDataSequential> &Node = *Entry;
+ assert(Node && "Didn't find entry in its uniquing hash table!");
+ // If we found our entry, unlink it from the list and we're done.
+ if (Node.get() == this) {
+ Node = std::move(Node->Next);
+ return;
}
-
- Entry = &Node->Next;
+
+ Entry = &Node->Next;
}
}
@@ -3135,7 +3135,7 @@ Constant *ConstantDataVector::getSplat(unsigned NumElts, Constant *V) {
return getFP(V->getType(), Elts);
}
}
- return ConstantVector::getSplat(ElementCount::getFixed(NumElts), V);
+ return ConstantVector::getSplat(ElementCount::getFixed(NumElts), V);
}
@@ -3445,7 +3445,7 @@ Value *ConstantExpr::handleOperandChangeImpl(Value *From, Value *ToV) {
}
Instruction *ConstantExpr::getAsInstruction() const {
- SmallVector<Value *, 4> ValueOperands(operands());
+ SmallVector<Value *, 4> ValueOperands(operands());
ArrayRef<Value*> Ops(ValueOperands);
switch (getOpcode()) {
diff --git a/contrib/libs/llvm12/lib/IR/Core.cpp b/contrib/libs/llvm12/lib/IR/Core.cpp
index 0f3a0b08cf..039b34ace6 100644
--- a/contrib/libs/llvm12/lib/IR/Core.cpp
+++ b/contrib/libs/llvm12/lib/IR/Core.cpp
@@ -145,11 +145,11 @@ LLVMAttributeRef LLVMCreateEnumAttribute(LLVMContextRef C, unsigned KindID,
return wrap(Attribute::getWithByValType(Ctx, NULL));
}
- if (AttrKind == Attribute::AttrKind::StructRet) {
- // Same as byval.
- return wrap(Attribute::getWithStructRetType(Ctx, NULL));
- }
-
+ if (AttrKind == Attribute::AttrKind::StructRet) {
+ // Same as byval.
+ return wrap(Attribute::getWithStructRetType(Ctx, NULL));
+ }
+
return wrap(Attribute::get(Ctx, AttrKind, Val));
}
@@ -164,18 +164,18 @@ uint64_t LLVMGetEnumAttributeValue(LLVMAttributeRef A) {
return Attr.getValueAsInt();
}
-LLVMAttributeRef LLVMCreateTypeAttribute(LLVMContextRef C, unsigned KindID,
- LLVMTypeRef type_ref) {
- auto &Ctx = *unwrap(C);
- auto AttrKind = (Attribute::AttrKind)KindID;
- return wrap(Attribute::get(Ctx, AttrKind, unwrap(type_ref)));
-}
-
-LLVMTypeRef LLVMGetTypeAttributeValue(LLVMAttributeRef A) {
- auto Attr = unwrap(A);
- return wrap(Attr.getValueAsType());
-}
-
+LLVMAttributeRef LLVMCreateTypeAttribute(LLVMContextRef C, unsigned KindID,
+ LLVMTypeRef type_ref) {
+ auto &Ctx = *unwrap(C);
+ auto AttrKind = (Attribute::AttrKind)KindID;
+ return wrap(Attribute::get(Ctx, AttrKind, unwrap(type_ref)));
+}
+
+LLVMTypeRef LLVMGetTypeAttributeValue(LLVMAttributeRef A) {
+ auto Attr = unwrap(A);
+ return wrap(Attr.getValueAsType());
+}
+
LLVMAttributeRef LLVMCreateStringAttribute(LLVMContextRef C,
const char *K, unsigned KLength,
const char *V, unsigned VLength) {
@@ -206,10 +206,10 @@ LLVMBool LLVMIsStringAttribute(LLVMAttributeRef A) {
return unwrap(A).isStringAttribute();
}
-LLVMBool LLVMIsTypeAttribute(LLVMAttributeRef A) {
- return unwrap(A).isTypeAttribute();
-}
-
+LLVMBool LLVMIsTypeAttribute(LLVMAttributeRef A) {
+ return unwrap(A).isTypeAttribute();
+}
+
char *LLVMGetDiagInfoDescription(LLVMDiagnosticInfoRef DI) {
std::string MsgStorage;
raw_string_ostream Stream(MsgStorage);
@@ -527,8 +527,8 @@ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) {
return LLVMVectorTypeKind;
case Type::X86_MMXTyID:
return LLVMX86_MMXTypeKind;
- case Type::X86_AMXTyID:
- return LLVMX86_AMXTypeKind;
+ case Type::X86_AMXTyID:
+ return LLVMX86_AMXTypeKind;
case Type::TokenTyID:
return LLVMTokenTypeKind;
case Type::ScalableVectorTyID:
@@ -640,9 +640,9 @@ LLVMTypeRef LLVMPPCFP128TypeInContext(LLVMContextRef C) {
LLVMTypeRef LLVMX86MMXTypeInContext(LLVMContextRef C) {
return (LLVMTypeRef) Type::getX86_MMXTy(*unwrap(C));
}
-LLVMTypeRef LLVMX86AMXTypeInContext(LLVMContextRef C) {
- return (LLVMTypeRef) Type::getX86_AMXTy(*unwrap(C));
-}
+LLVMTypeRef LLVMX86AMXTypeInContext(LLVMContextRef C) {
+ return (LLVMTypeRef) Type::getX86_AMXTy(*unwrap(C));
+}
LLVMTypeRef LLVMHalfType(void) {
return LLVMHalfTypeInContext(LLVMGetGlobalContext());
@@ -668,9 +668,9 @@ LLVMTypeRef LLVMPPCFP128Type(void) {
LLVMTypeRef LLVMX86MMXType(void) {
return LLVMX86MMXTypeInContext(LLVMGetGlobalContext());
}
-LLVMTypeRef LLVMX86AMXType(void) {
- return LLVMX86AMXTypeInContext(LLVMGetGlobalContext());
-}
+LLVMTypeRef LLVMX86AMXType(void) {
+ return LLVMX86AMXTypeInContext(LLVMGetGlobalContext());
+}
/*--.. Operations on function types ........................................--*/
@@ -762,13 +762,13 @@ LLVMBool LLVMIsLiteralStruct(LLVMTypeRef StructTy) {
}
LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name) {
- return wrap(StructType::getTypeByName(unwrap(M)->getContext(), Name));
+ return wrap(StructType::getTypeByName(unwrap(M)->getContext(), Name));
+}
+
+LLVMTypeRef LLVMGetTypeByName2(LLVMContextRef C, const char *Name) {
+ return wrap(StructType::getTypeByName(*unwrap(C), Name));
}
-LLVMTypeRef LLVMGetTypeByName2(LLVMContextRef C, const char *Name) {
- return wrap(StructType::getTypeByName(*unwrap(C), Name));
-}
-
/*--.. Operations on array, pointer, and vector types (sequence types) .....--*/
void LLVMGetSubtypes(LLVMTypeRef Tp, LLVMTypeRef *Arr) {
@@ -791,11 +791,11 @@ LLVMTypeRef LLVMVectorType(LLVMTypeRef ElementType, unsigned ElementCount) {
return wrap(FixedVectorType::get(unwrap(ElementType), ElementCount));
}
-LLVMTypeRef LLVMScalableVectorType(LLVMTypeRef ElementType,
- unsigned ElementCount) {
- return wrap(ScalableVectorType::get(unwrap(ElementType), ElementCount));
-}
-
+LLVMTypeRef LLVMScalableVectorType(LLVMTypeRef ElementType,
+ unsigned ElementCount) {
+ return wrap(ScalableVectorType::get(unwrap(ElementType), ElementCount));
+}
+
LLVMTypeRef LLVMGetElementType(LLVMTypeRef WrappedTy) {
auto *Ty = unwrap<Type>(WrappedTy);
if (auto *PTy = dyn_cast<PointerType>(Ty))
@@ -818,7 +818,7 @@ unsigned LLVMGetPointerAddressSpace(LLVMTypeRef PointerTy) {
}
unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy) {
- return unwrap<VectorType>(VectorTy)->getElementCount().getKnownMinValue();
+ return unwrap<VectorType>(VectorTy)->getElementCount().getKnownMinValue();
}
/*--.. Operations on other types ...........................................--*/
@@ -853,7 +853,7 @@ LLVMTypeRef LLVMTypeOf(LLVMValueRef Val) {
LLVMValueKind LLVMGetValueKind(LLVMValueRef Val) {
switch(unwrap(Val)->getValueID()) {
-#define LLVM_C_API 1
+#define LLVM_C_API 1
#define HANDLE_VALUE(Name) \
case Value::Name##Val: \
return LLVM##Name##ValueKind;
@@ -963,7 +963,7 @@ LLVMValueMetadataEntry *
LLVMInstructionGetAllMetadataOtherThanDebugLoc(LLVMValueRef Value,
size_t *NumEntries) {
return llvm_getMetadata(NumEntries, [&Value](MetadataEntries &Entries) {
- Entries.clear();
+ Entries.clear();
unwrap<Instruction>(Value)->getAllMetadata(Entries);
});
}
@@ -1073,10 +1073,10 @@ LLVMValueRef LLVMGetUndef(LLVMTypeRef Ty) {
return wrap(UndefValue::get(unwrap(Ty)));
}
-LLVMValueRef LLVMGetPoison(LLVMTypeRef Ty) {
- return wrap(PoisonValue::get(unwrap(Ty)));
-}
-
+LLVMValueRef LLVMGetPoison(LLVMTypeRef Ty) {
+ return wrap(PoisonValue::get(unwrap(Ty)));
+}
+
LLVMBool LLVMIsConstant(LLVMValueRef Ty) {
return isa<Constant>(unwrap(Ty));
}
@@ -1091,10 +1091,10 @@ LLVMBool LLVMIsUndef(LLVMValueRef Val) {
return isa<UndefValue>(unwrap(Val));
}
-LLVMBool LLVMIsPoison(LLVMValueRef Val) {
- return isa<PoisonValue>(unwrap(Val));
-}
-
+LLVMBool LLVMIsPoison(LLVMValueRef Val) {
+ return isa<PoisonValue>(unwrap(Val));
+}
+
LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty) {
return wrap(ConstantPointerNull::get(unwrap<PointerType>(Ty)));
}
@@ -2081,7 +2081,7 @@ void LLVMSetAlignment(LLVMValueRef V, unsigned Bytes) {
LLVMValueMetadataEntry *LLVMGlobalCopyAllMetadata(LLVMValueRef Value,
size_t *NumEntries) {
return llvm_getMetadata(NumEntries, [&Value](MetadataEntries &Entries) {
- Entries.clear();
+ Entries.clear();
if (Instruction *Instr = dyn_cast<Instruction>(unwrap(Value))) {
Instr->getAllMetadata(Entries);
} else {
diff --git a/contrib/libs/llvm12/lib/IR/DIBuilder.cpp b/contrib/libs/llvm12/lib/IR/DIBuilder.cpp
index 169174544a..5104dc349d 100644
--- a/contrib/libs/llvm12/lib/IR/DIBuilder.cpp
+++ b/contrib/libs/llvm12/lib/IR/DIBuilder.cpp
@@ -267,12 +267,12 @@ DIBasicType *DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits,
0, Encoding, Flags);
}
-DIStringType *DIBuilder::createStringType(StringRef Name, uint64_t SizeInBits) {
- assert(!Name.empty() && "Unable to create type without name");
- return DIStringType::get(VMContext, dwarf::DW_TAG_string_type, Name,
- SizeInBits, 0);
-}
-
+DIStringType *DIBuilder::createStringType(StringRef Name, uint64_t SizeInBits) {
+ assert(!Name.empty() && "Unable to create type without name");
+ return DIStringType::get(VMContext, dwarf::DW_TAG_string_type, Name,
+ SizeInBits, 0);
+}
+
DIDerivedType *DIBuilder::createQualifiedType(unsigned Tag, DIType *FromTy) {
return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, FromTy, 0,
0, 0, None, DINode::FlagZero);
@@ -525,24 +525,24 @@ DICompositeType *DIBuilder::createEnumerationType(
return CTy;
}
-DICompositeType *DIBuilder::createArrayType(
- uint64_t Size, uint32_t AlignInBits, DIType *Ty, DINodeArray Subscripts,
- PointerUnion<DIExpression *, DIVariable *> DL,
- PointerUnion<DIExpression *, DIVariable *> AS,
- PointerUnion<DIExpression *, DIVariable *> AL,
- PointerUnion<DIExpression *, DIVariable *> RK) {
- auto *R = DICompositeType::get(
- VMContext, dwarf::DW_TAG_array_type, "", nullptr, 0,
- nullptr, Ty, Size, AlignInBits, 0, DINode::FlagZero,
- Subscripts, 0, nullptr, nullptr, "", nullptr,
- DL.is<DIExpression *>() ? (Metadata *)DL.get<DIExpression *>()
- : (Metadata *)DL.get<DIVariable *>(),
- AS.is<DIExpression *>() ? (Metadata *)AS.get<DIExpression *>()
- : (Metadata *)AS.get<DIVariable *>(),
- AL.is<DIExpression *>() ? (Metadata *)AL.get<DIExpression *>()
- : (Metadata *)AL.get<DIVariable *>(),
- RK.is<DIExpression *>() ? (Metadata *)RK.get<DIExpression *>()
- : (Metadata *)RK.get<DIVariable *>());
+DICompositeType *DIBuilder::createArrayType(
+ uint64_t Size, uint32_t AlignInBits, DIType *Ty, DINodeArray Subscripts,
+ PointerUnion<DIExpression *, DIVariable *> DL,
+ PointerUnion<DIExpression *, DIVariable *> AS,
+ PointerUnion<DIExpression *, DIVariable *> AL,
+ PointerUnion<DIExpression *, DIVariable *> RK) {
+ auto *R = DICompositeType::get(
+ VMContext, dwarf::DW_TAG_array_type, "", nullptr, 0,
+ nullptr, Ty, Size, AlignInBits, 0, DINode::FlagZero,
+ Subscripts, 0, nullptr, nullptr, "", nullptr,
+ DL.is<DIExpression *>() ? (Metadata *)DL.get<DIExpression *>()
+ : (Metadata *)DL.get<DIVariable *>(),
+ AS.is<DIExpression *>() ? (Metadata *)AS.get<DIExpression *>()
+ : (Metadata *)AS.get<DIVariable *>(),
+ AL.is<DIExpression *>() ? (Metadata *)AL.get<DIExpression *>()
+ : (Metadata *)AL.get<DIVariable *>(),
+ RK.is<DIExpression *>() ? (Metadata *)RK.get<DIExpression *>()
+ : (Metadata *)RK.get<DIVariable *>());
trackIfUnresolved(R);
return R;
}
@@ -661,18 +661,18 @@ DISubrange *DIBuilder::getOrCreateSubrange(Metadata *CountNode, Metadata *LB,
return DISubrange::get(VMContext, CountNode, LB, UB, Stride);
}
-DIGenericSubrange *DIBuilder::getOrCreateGenericSubrange(
- DIGenericSubrange::BoundType CountNode, DIGenericSubrange::BoundType LB,
- DIGenericSubrange::BoundType UB, DIGenericSubrange::BoundType Stride) {
- auto ConvToMetadata = [&](DIGenericSubrange::BoundType Bound) -> Metadata * {
- return Bound.is<DIExpression *>() ? (Metadata *)Bound.get<DIExpression *>()
- : (Metadata *)Bound.get<DIVariable *>();
- };
- return DIGenericSubrange::get(VMContext, ConvToMetadata(CountNode),
- ConvToMetadata(LB), ConvToMetadata(UB),
- ConvToMetadata(Stride));
-}
-
+DIGenericSubrange *DIBuilder::getOrCreateGenericSubrange(
+ DIGenericSubrange::BoundType CountNode, DIGenericSubrange::BoundType LB,
+ DIGenericSubrange::BoundType UB, DIGenericSubrange::BoundType Stride) {
+ auto ConvToMetadata = [&](DIGenericSubrange::BoundType Bound) -> Metadata * {
+ return Bound.is<DIExpression *>() ? (Metadata *)Bound.get<DIExpression *>()
+ : (Metadata *)Bound.get<DIVariable *>();
+ };
+ return DIGenericSubrange::get(VMContext, ConvToMetadata(CountNode),
+ ConvToMetadata(LB), ConvToMetadata(UB),
+ ConvToMetadata(Stride));
+}
+
static void checkGlobalVariableScope(DIScope *Context) {
#ifndef NDEBUG
if (auto *CT =
@@ -874,10 +874,10 @@ DINamespace *DIBuilder::createNameSpace(DIScope *Scope, StringRef Name,
DIModule *DIBuilder::createModule(DIScope *Scope, StringRef Name,
StringRef ConfigurationMacros,
StringRef IncludePath, StringRef APINotesFile,
- DIFile *File, unsigned LineNo, bool IsDecl) {
+ DIFile *File, unsigned LineNo, bool IsDecl) {
return DIModule::get(VMContext, File, getNonCompileUnitScope(Scope), Name,
- ConfigurationMacros, IncludePath, APINotesFile, LineNo,
- IsDecl);
+ ConfigurationMacros, IncludePath, APINotesFile, LineNo,
+ IsDecl);
}
DILexicalBlockFile *DIBuilder::createLexicalBlockFile(DIScope *Scope,
diff --git a/contrib/libs/llvm12/lib/IR/DataLayout.cpp b/contrib/libs/llvm12/lib/IR/DataLayout.cpp
index 3a6ae1d647..274ea0aa5f 100644
--- a/contrib/libs/llvm12/lib/IR/DataLayout.cpp
+++ b/contrib/libs/llvm12/lib/IR/DataLayout.cpp
@@ -27,7 +27,7 @@
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/Error.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/TypeSize.h"
@@ -65,8 +65,8 @@ StructLayout::StructLayout(StructType *ST, const DataLayout &DL) {
StructAlignment = std::max(TyAlign, StructAlignment);
MemberOffsets[i] = StructSize;
- // Consume space for this data item
- StructSize += DL.getTypeAllocSize(Ty).getFixedValue();
+ // Consume space for this data item
+ StructSize += DL.getTypeAllocSize(Ty).getFixedValue();
}
// Add padding to the end of the struct so that it could be put in an array
@@ -183,7 +183,7 @@ void DataLayout::reset(StringRef Desc) {
AllocaAddrSpace = 0;
StackNaturalAlign.reset();
ProgramAddrSpace = 0;
- DefaultGlobalsAddrSpace = 0;
+ DefaultGlobalsAddrSpace = 0;
FunctionPtrAlign.reset();
TheFunctionPtrAlignType = FunctionPtrAlignType::Independent;
ManglingMode = MM_None;
@@ -191,80 +191,80 @@ void DataLayout::reset(StringRef Desc) {
// Default alignments
for (const LayoutAlignElem &E : DefaultAlignments) {
- if (Error Err = setAlignment((AlignTypeEnum)E.AlignType, E.ABIAlign,
- E.PrefAlign, E.TypeBitWidth))
- return report_fatal_error(std::move(Err));
+ if (Error Err = setAlignment((AlignTypeEnum)E.AlignType, E.ABIAlign,
+ E.PrefAlign, E.TypeBitWidth))
+ return report_fatal_error(std::move(Err));
}
- if (Error Err = setPointerAlignment(0, Align(8), Align(8), 8, 8))
- return report_fatal_error(std::move(Err));
-
- if (Error Err = parseSpecifier(Desc))
- return report_fatal_error(std::move(Err));
-}
-
-Expected<DataLayout> DataLayout::parse(StringRef LayoutDescription) {
- DataLayout Layout("");
- if (Error Err = Layout.parseSpecifier(LayoutDescription))
- return std::move(Err);
- return Layout;
-}
-
-static Error reportError(const Twine &Message) {
- return createStringError(inconvertibleErrorCode(), Message);
-}
-
+ if (Error Err = setPointerAlignment(0, Align(8), Align(8), 8, 8))
+ return report_fatal_error(std::move(Err));
+
+ if (Error Err = parseSpecifier(Desc))
+ return report_fatal_error(std::move(Err));
+}
+
+Expected<DataLayout> DataLayout::parse(StringRef LayoutDescription) {
+ DataLayout Layout("");
+ if (Error Err = Layout.parseSpecifier(LayoutDescription))
+ return std::move(Err);
+ return Layout;
+}
+
+static Error reportError(const Twine &Message) {
+ return createStringError(inconvertibleErrorCode(), Message);
+}
+
/// Checked version of split, to ensure mandatory subparts.
-static Error split(StringRef Str, char Separator,
- std::pair<StringRef, StringRef> &Split) {
+static Error split(StringRef Str, char Separator,
+ std::pair<StringRef, StringRef> &Split) {
assert(!Str.empty() && "parse error, string can't be empty here");
- Split = Str.split(Separator);
+ Split = Str.split(Separator);
if (Split.second.empty() && Split.first != Str)
- return reportError("Trailing separator in datalayout string");
+ return reportError("Trailing separator in datalayout string");
if (!Split.second.empty() && Split.first.empty())
- return reportError("Expected token before separator in datalayout string");
- return Error::success();
+ return reportError("Expected token before separator in datalayout string");
+ return Error::success();
}
/// Get an unsigned integer, including error checks.
-template <typename IntTy> static Error getInt(StringRef R, IntTy &Result) {
+template <typename IntTy> static Error getInt(StringRef R, IntTy &Result) {
bool error = R.getAsInteger(10, Result); (void)error;
if (error)
- return reportError("not a number, or does not fit in an unsigned int");
- return Error::success();
+ return reportError("not a number, or does not fit in an unsigned int");
+ return Error::success();
}
-/// Get an unsigned integer representing the number of bits and convert it into
-/// bytes. Error out of not a byte width multiple.
-template <typename IntTy>
-static Error getIntInBytes(StringRef R, IntTy &Result) {
- if (Error Err = getInt<IntTy>(R, Result))
- return Err;
- if (Result % 8)
- return reportError("number of bits must be a byte width multiple");
- Result /= 8;
- return Error::success();
+/// Get an unsigned integer representing the number of bits and convert it into
+/// bytes. Error out of not a byte width multiple.
+template <typename IntTy>
+static Error getIntInBytes(StringRef R, IntTy &Result) {
+ if (Error Err = getInt<IntTy>(R, Result))
+ return Err;
+ if (Result % 8)
+ return reportError("number of bits must be a byte width multiple");
+ Result /= 8;
+ return Error::success();
}
-static Error getAddrSpace(StringRef R, unsigned &AddrSpace) {
- if (Error Err = getInt(R, AddrSpace))
- return Err;
+static Error getAddrSpace(StringRef R, unsigned &AddrSpace) {
+ if (Error Err = getInt(R, AddrSpace))
+ return Err;
if (!isUInt<24>(AddrSpace))
- return reportError("Invalid address space, must be a 24-bit integer");
- return Error::success();
+ return reportError("Invalid address space, must be a 24-bit integer");
+ return Error::success();
}
-Error DataLayout::parseSpecifier(StringRef Desc) {
+Error DataLayout::parseSpecifier(StringRef Desc) {
StringRepresentation = std::string(Desc);
while (!Desc.empty()) {
// Split at '-'.
- std::pair<StringRef, StringRef> Split;
- if (Error Err = split(Desc, '-', Split))
- return Err;
+ std::pair<StringRef, StringRef> Split;
+ if (Error Err = split(Desc, '-', Split))
+ return Err;
Desc = Split.second;
// Split at ':'.
- if (Error Err = split(Split.first, ':', Split))
- return Err;
+ if (Error Err = split(Split.first, ':', Split))
+ return Err;
// Aliases used below.
StringRef &Tok = Split.first; // Current token.
@@ -272,14 +272,14 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
if (Tok == "ni") {
do {
- if (Error Err = split(Rest, ':', Split))
- return Err;
+ if (Error Err = split(Rest, ':', Split))
+ return Err;
Rest = Split.second;
- unsigned AS;
- if (Error Err = getInt(Split.first, AS))
- return Err;
+ unsigned AS;
+ if (Error Err = getInt(Split.first, AS))
+ return Err;
if (AS == 0)
- return reportError("Address space 0 can never be non-integral");
+ return reportError("Address space 0 can never be non-integral");
NonIntegralAddressSpaces.push_back(AS);
} while (!Rest.empty());
@@ -302,36 +302,36 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
break;
case 'p': {
// Address space.
- unsigned AddrSpace = 0;
- if (!Tok.empty())
- if (Error Err = getInt(Tok, AddrSpace))
- return Err;
+ unsigned AddrSpace = 0;
+ if (!Tok.empty())
+ if (Error Err = getInt(Tok, AddrSpace))
+ return Err;
if (!isUInt<24>(AddrSpace))
- return reportError("Invalid address space, must be a 24bit integer");
+ return reportError("Invalid address space, must be a 24bit integer");
// Size.
if (Rest.empty())
- return reportError(
+ return reportError(
"Missing size specification for pointer in datalayout string");
- if (Error Err = split(Rest, ':', Split))
- return Err;
- unsigned PointerMemSize;
- if (Error Err = getIntInBytes(Tok, PointerMemSize))
- return Err;
+ if (Error Err = split(Rest, ':', Split))
+ return Err;
+ unsigned PointerMemSize;
+ if (Error Err = getIntInBytes(Tok, PointerMemSize))
+ return Err;
if (!PointerMemSize)
- return reportError("Invalid pointer size of 0 bytes");
+ return reportError("Invalid pointer size of 0 bytes");
// ABI alignment.
if (Rest.empty())
- return reportError(
+ return reportError(
"Missing alignment specification for pointer in datalayout string");
- if (Error Err = split(Rest, ':', Split))
- return Err;
- unsigned PointerABIAlign;
- if (Error Err = getIntInBytes(Tok, PointerABIAlign))
- return Err;
+ if (Error Err = split(Rest, ':', Split))
+ return Err;
+ unsigned PointerABIAlign;
+ if (Error Err = getIntInBytes(Tok, PointerABIAlign))
+ return Err;
if (!isPowerOf2_64(PointerABIAlign))
- return reportError("Pointer ABI alignment must be a power of 2");
+ return reportError("Pointer ABI alignment must be a power of 2");
// Size of index used in GEP for address calculation.
// The parameter is optional. By default it is equal to size of pointer.
@@ -340,28 +340,28 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
// Preferred alignment.
unsigned PointerPrefAlign = PointerABIAlign;
if (!Rest.empty()) {
- if (Error Err = split(Rest, ':', Split))
- return Err;
- if (Error Err = getIntInBytes(Tok, PointerPrefAlign))
- return Err;
+ if (Error Err = split(Rest, ':', Split))
+ return Err;
+ if (Error Err = getIntInBytes(Tok, PointerPrefAlign))
+ return Err;
if (!isPowerOf2_64(PointerPrefAlign))
- return reportError(
- "Pointer preferred alignment must be a power of 2");
+ return reportError(
+ "Pointer preferred alignment must be a power of 2");
// Now read the index. It is the second optional parameter here.
if (!Rest.empty()) {
- if (Error Err = split(Rest, ':', Split))
- return Err;
- if (Error Err = getIntInBytes(Tok, IndexSize))
- return Err;
+ if (Error Err = split(Rest, ':', Split))
+ return Err;
+ if (Error Err = getIntInBytes(Tok, IndexSize))
+ return Err;
if (!IndexSize)
- return reportError("Invalid index size of 0 bytes");
+ return reportError("Invalid index size of 0 bytes");
}
}
- if (Error Err = setPointerAlignment(
- AddrSpace, assumeAligned(PointerABIAlign),
- assumeAligned(PointerPrefAlign), PointerMemSize, IndexSize))
- return Err;
+ if (Error Err = setPointerAlignment(
+ AddrSpace, assumeAligned(PointerABIAlign),
+ assumeAligned(PointerPrefAlign), PointerMemSize, IndexSize))
+ return Err;
break;
}
case 'i':
@@ -378,75 +378,75 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
}
// Bit size.
- unsigned Size = 0;
- if (!Tok.empty())
- if (Error Err = getInt(Tok, Size))
- return Err;
+ unsigned Size = 0;
+ if (!Tok.empty())
+ if (Error Err = getInt(Tok, Size))
+ return Err;
if (AlignType == AGGREGATE_ALIGN && Size != 0)
- return reportError(
+ return reportError(
"Sized aggregate specification in datalayout string");
// ABI alignment.
if (Rest.empty())
- return reportError(
+ return reportError(
"Missing alignment specification in datalayout string");
- if (Error Err = split(Rest, ':', Split))
- return Err;
- unsigned ABIAlign;
- if (Error Err = getIntInBytes(Tok, ABIAlign))
- return Err;
+ if (Error Err = split(Rest, ':', Split))
+ return Err;
+ unsigned ABIAlign;
+ if (Error Err = getIntInBytes(Tok, ABIAlign))
+ return Err;
if (AlignType != AGGREGATE_ALIGN && !ABIAlign)
- return reportError(
+ return reportError(
"ABI alignment specification must be >0 for non-aggregate types");
if (!isUInt<16>(ABIAlign))
- return reportError("Invalid ABI alignment, must be a 16bit integer");
+ return reportError("Invalid ABI alignment, must be a 16bit integer");
if (ABIAlign != 0 && !isPowerOf2_64(ABIAlign))
- return reportError("Invalid ABI alignment, must be a power of 2");
+ return reportError("Invalid ABI alignment, must be a power of 2");
// Preferred alignment.
unsigned PrefAlign = ABIAlign;
if (!Rest.empty()) {
- if (Error Err = split(Rest, ':', Split))
- return Err;
- if (Error Err = getIntInBytes(Tok, PrefAlign))
- return Err;
+ if (Error Err = split(Rest, ':', Split))
+ return Err;
+ if (Error Err = getIntInBytes(Tok, PrefAlign))
+ return Err;
}
if (!isUInt<16>(PrefAlign))
- return reportError(
+ return reportError(
"Invalid preferred alignment, must be a 16bit integer");
if (PrefAlign != 0 && !isPowerOf2_64(PrefAlign))
- return reportError("Invalid preferred alignment, must be a power of 2");
+ return reportError("Invalid preferred alignment, must be a power of 2");
- if (Error Err = setAlignment(AlignType, assumeAligned(ABIAlign),
- assumeAligned(PrefAlign), Size))
- return Err;
+ if (Error Err = setAlignment(AlignType, assumeAligned(ABIAlign),
+ assumeAligned(PrefAlign), Size))
+ return Err;
break;
}
case 'n': // Native integer types.
while (true) {
- unsigned Width;
- if (Error Err = getInt(Tok, Width))
- return Err;
+ unsigned Width;
+ if (Error Err = getInt(Tok, Width))
+ return Err;
if (Width == 0)
- return reportError(
+ return reportError(
"Zero width native integer type in datalayout string");
LegalIntWidths.push_back(Width);
if (Rest.empty())
break;
- if (Error Err = split(Rest, ':', Split))
- return Err;
+ if (Error Err = split(Rest, ':', Split))
+ return Err;
}
break;
case 'S': { // Stack natural alignment.
- uint64_t Alignment;
- if (Error Err = getIntInBytes(Tok, Alignment))
- return Err;
+ uint64_t Alignment;
+ if (Error Err = getIntInBytes(Tok, Alignment))
+ return Err;
if (Alignment != 0 && !llvm::isPowerOf2_64(Alignment))
- return reportError("Alignment is neither 0 nor a power of 2");
+ return reportError("Alignment is neither 0 nor a power of 2");
StackNaturalAlign = MaybeAlign(Alignment);
break;
}
@@ -459,44 +459,44 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
TheFunctionPtrAlignType = FunctionPtrAlignType::MultipleOfFunctionAlign;
break;
default:
- return reportError("Unknown function pointer alignment type in "
+ return reportError("Unknown function pointer alignment type in "
"datalayout string");
}
Tok = Tok.substr(1);
- uint64_t Alignment;
- if (Error Err = getIntInBytes(Tok, Alignment))
- return Err;
+ uint64_t Alignment;
+ if (Error Err = getIntInBytes(Tok, Alignment))
+ return Err;
if (Alignment != 0 && !llvm::isPowerOf2_64(Alignment))
- return reportError("Alignment is neither 0 nor a power of 2");
+ return reportError("Alignment is neither 0 nor a power of 2");
FunctionPtrAlign = MaybeAlign(Alignment);
break;
}
case 'P': { // Function address space.
- if (Error Err = getAddrSpace(Tok, ProgramAddrSpace))
- return Err;
+ if (Error Err = getAddrSpace(Tok, ProgramAddrSpace))
+ return Err;
break;
}
case 'A': { // Default stack/alloca address space.
- if (Error Err = getAddrSpace(Tok, AllocaAddrSpace))
- return Err;
+ if (Error Err = getAddrSpace(Tok, AllocaAddrSpace))
+ return Err;
+ break;
+ }
+ case 'G': { // Default address space for global variables.
+ if (Error Err = getAddrSpace(Tok, DefaultGlobalsAddrSpace))
+ return Err;
break;
}
- case 'G': { // Default address space for global variables.
- if (Error Err = getAddrSpace(Tok, DefaultGlobalsAddrSpace))
- return Err;
- break;
- }
case 'm':
if (!Tok.empty())
- return reportError("Unexpected trailing characters after mangling "
- "specifier in datalayout string");
+ return reportError("Unexpected trailing characters after mangling "
+ "specifier in datalayout string");
if (Rest.empty())
- return reportError("Expected mangling specifier in datalayout string");
+ return reportError("Expected mangling specifier in datalayout string");
if (Rest.size() > 1)
- return reportError("Unknown mangling specifier in datalayout string");
+ return reportError("Unknown mangling specifier in datalayout string");
switch(Rest[0]) {
default:
- return reportError("Unknown mangling in datalayout string");
+ return reportError("Unknown mangling in datalayout string");
case 'e':
ManglingMode = MM_ELF;
break;
@@ -518,12 +518,12 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
}
break;
default:
- return reportError("Unknown specifier in datalayout string");
+ return reportError("Unknown specifier in datalayout string");
break;
}
}
-
- return Error::success();
+
+ return Error::success();
}
DataLayout::DataLayout(const Module *M) {
@@ -537,7 +537,7 @@ bool DataLayout::operator==(const DataLayout &Other) const {
AllocaAddrSpace == Other.AllocaAddrSpace &&
StackNaturalAlign == Other.StackNaturalAlign &&
ProgramAddrSpace == Other.ProgramAddrSpace &&
- DefaultGlobalsAddrSpace == Other.DefaultGlobalsAddrSpace &&
+ DefaultGlobalsAddrSpace == Other.DefaultGlobalsAddrSpace &&
FunctionPtrAlign == Other.FunctionPtrAlign &&
TheFunctionPtrAlignType == Other.TheFunctionPtrAlignType &&
ManglingMode == Other.ManglingMode &&
@@ -556,17 +556,17 @@ DataLayout::findAlignmentLowerBound(AlignTypeEnum AlignType,
});
}
-Error DataLayout::setAlignment(AlignTypeEnum align_type, Align abi_align,
- Align pref_align, uint32_t bit_width) {
+Error DataLayout::setAlignment(AlignTypeEnum align_type, Align abi_align,
+ Align pref_align, uint32_t bit_width) {
// AlignmentsTy::ABIAlign and AlignmentsTy::PrefAlign were once stored as
// uint16_t, it is unclear if there are requirements for alignment to be less
// than 2^16 other than storage. In the meantime we leave the restriction as
// an assert. See D67400 for context.
assert(Log2(abi_align) < 16 && Log2(pref_align) < 16 && "Alignment too big");
if (!isUInt<24>(bit_width))
- return reportError("Invalid bit width, must be a 24bit integer");
+ return reportError("Invalid bit width, must be a 24bit integer");
if (pref_align < abi_align)
- return reportError(
+ return reportError(
"Preferred alignment cannot be less than the ABI alignment");
AlignmentsTy::iterator I = findAlignmentLowerBound(align_type, bit_width);
@@ -580,35 +580,35 @@ Error DataLayout::setAlignment(AlignTypeEnum align_type, Align abi_align,
Alignments.insert(I, LayoutAlignElem::get(align_type, abi_align,
pref_align, bit_width));
}
- return Error::success();
-}
-
-const PointerAlignElem &
-DataLayout::getPointerAlignElem(uint32_t AddressSpace) const {
- if (AddressSpace != 0) {
- auto I = lower_bound(Pointers, AddressSpace,
- [](const PointerAlignElem &A, uint32_t AddressSpace) {
- return A.AddressSpace < AddressSpace;
- });
- if (I != Pointers.end() && I->AddressSpace == AddressSpace)
- return *I;
- }
-
- assert(Pointers[0].AddressSpace == 0);
- return Pointers[0];
-}
-
-Error DataLayout::setPointerAlignment(uint32_t AddrSpace, Align ABIAlign,
- Align PrefAlign, uint32_t TypeByteWidth,
- uint32_t IndexWidth) {
+ return Error::success();
+}
+
+const PointerAlignElem &
+DataLayout::getPointerAlignElem(uint32_t AddressSpace) const {
+ if (AddressSpace != 0) {
+ auto I = lower_bound(Pointers, AddressSpace,
+ [](const PointerAlignElem &A, uint32_t AddressSpace) {
+ return A.AddressSpace < AddressSpace;
+ });
+ if (I != Pointers.end() && I->AddressSpace == AddressSpace)
+ return *I;
+ }
+
+ assert(Pointers[0].AddressSpace == 0);
+ return Pointers[0];
+}
+
+Error DataLayout::setPointerAlignment(uint32_t AddrSpace, Align ABIAlign,
+ Align PrefAlign, uint32_t TypeByteWidth,
+ uint32_t IndexWidth) {
if (PrefAlign < ABIAlign)
- return reportError(
+ return reportError(
"Preferred alignment cannot be less than the ABI alignment");
- auto I = lower_bound(Pointers, AddrSpace,
- [](const PointerAlignElem &A, uint32_t AddressSpace) {
- return A.AddressSpace < AddressSpace;
- });
+ auto I = lower_bound(Pointers, AddrSpace,
+ [](const PointerAlignElem &A, uint32_t AddressSpace) {
+ return A.AddressSpace < AddressSpace;
+ });
if (I == Pointers.end() || I->AddressSpace != AddrSpace) {
Pointers.insert(I, PointerAlignElem::get(AddrSpace, ABIAlign, PrefAlign,
TypeByteWidth, IndexWidth));
@@ -618,19 +618,19 @@ Error DataLayout::setPointerAlignment(uint32_t AddrSpace, Align ABIAlign,
I->TypeByteWidth = TypeByteWidth;
I->IndexWidth = IndexWidth;
}
- return Error::success();
+ return Error::success();
}
-Align DataLayout::getIntegerAlignment(uint32_t BitWidth,
- bool abi_or_pref) const {
- auto I = findAlignmentLowerBound(INTEGER_ALIGN, BitWidth);
- // If we don't have an exact match, use alignment of next larger integer
- // type. If there is none, use alignment of largest integer type by going
- // back one element.
- if (I == Alignments.end() || I->AlignType != INTEGER_ALIGN)
- --I;
- assert(I->AlignType == INTEGER_ALIGN && "Must be integer alignment");
- return abi_or_pref ? I->ABIAlign : I->PrefAlign;
+Align DataLayout::getIntegerAlignment(uint32_t BitWidth,
+ bool abi_or_pref) const {
+ auto I = findAlignmentLowerBound(INTEGER_ALIGN, BitWidth);
+ // If we don't have an exact match, use alignment of next larger integer
+ // type. If there is none, use alignment of largest integer type by going
+ // back one element.
+ if (I == Alignments.end() || I->AlignType != INTEGER_ALIGN)
+ --I;
+ assert(I->AlignType == INTEGER_ALIGN && "Must be integer alignment");
+ return abi_or_pref ? I->ABIAlign : I->PrefAlign;
}
namespace {
@@ -692,15 +692,15 @@ const StructLayout *DataLayout::getStructLayout(StructType *Ty) const {
}
Align DataLayout::getPointerABIAlignment(unsigned AS) const {
- return getPointerAlignElem(AS).ABIAlign;
+ return getPointerAlignElem(AS).ABIAlign;
}
Align DataLayout::getPointerPrefAlignment(unsigned AS) const {
- return getPointerAlignElem(AS).PrefAlign;
+ return getPointerAlignElem(AS).PrefAlign;
}
unsigned DataLayout::getPointerSize(unsigned AS) const {
- return getPointerAlignElem(AS).TypeByteWidth;
+ return getPointerAlignElem(AS).TypeByteWidth;
}
unsigned DataLayout::getMaxPointerSize() const {
@@ -719,7 +719,7 @@ unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const {
}
unsigned DataLayout::getIndexSize(unsigned AS) const {
- return getPointerAlignElem(AS).IndexWidth;
+ return getPointerAlignElem(AS).IndexWidth;
}
unsigned DataLayout::getIndexTypeSizeInBits(Type *Ty) const {
@@ -758,15 +758,15 @@ Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
// Get the layout annotation... which is lazily created on demand.
const StructLayout *Layout = getStructLayout(cast<StructType>(Ty));
- const LayoutAlignElem &AggregateAlign = Alignments[0];
- assert(AggregateAlign.AlignType == AGGREGATE_ALIGN &&
- "Aggregate alignment must be first alignment entry");
- const Align Align =
- abi_or_pref ? AggregateAlign.ABIAlign : AggregateAlign.PrefAlign;
+ const LayoutAlignElem &AggregateAlign = Alignments[0];
+ assert(AggregateAlign.AlignType == AGGREGATE_ALIGN &&
+ "Aggregate alignment must be first alignment entry");
+ const Align Align =
+ abi_or_pref ? AggregateAlign.ABIAlign : AggregateAlign.PrefAlign;
return std::max(Align, Layout->getAlignment());
}
case Type::IntegerTyID:
- return getIntegerAlignment(Ty->getIntegerBitWidth(), abi_or_pref);
+ return getIntegerAlignment(Ty->getIntegerBitWidth(), abi_or_pref);
case Type::HalfTyID:
case Type::BFloatTyID:
case Type::FloatTyID:
@@ -775,44 +775,44 @@ Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
// same size and alignment, so they look the same here.
case Type::PPC_FP128TyID:
case Type::FP128TyID:
- case Type::X86_FP80TyID: {
- unsigned BitWidth = getTypeSizeInBits(Ty).getFixedSize();
- auto I = findAlignmentLowerBound(FLOAT_ALIGN, BitWidth);
- if (I != Alignments.end() && I->AlignType == FLOAT_ALIGN &&
- I->TypeBitWidth == BitWidth)
- return abi_or_pref ? I->ABIAlign : I->PrefAlign;
-
- // If we still couldn't find a reasonable default alignment, fall back
- // to a simple heuristic that the alignment is the first power of two
- // greater-or-equal to the store size of the type. This is a reasonable
- // approximation of reality, and if the user wanted something less
- // less conservative, they should have specified it explicitly in the data
- // layout.
- return Align(PowerOf2Ceil(BitWidth / 8));
- }
+ case Type::X86_FP80TyID: {
+ unsigned BitWidth = getTypeSizeInBits(Ty).getFixedSize();
+ auto I = findAlignmentLowerBound(FLOAT_ALIGN, BitWidth);
+ if (I != Alignments.end() && I->AlignType == FLOAT_ALIGN &&
+ I->TypeBitWidth == BitWidth)
+ return abi_or_pref ? I->ABIAlign : I->PrefAlign;
+
+ // If we still couldn't find a reasonable default alignment, fall back
+ // to a simple heuristic that the alignment is the first power of two
+ // greater-or-equal to the store size of the type. This is a reasonable
+ // approximation of reality, and if the user wanted something less
+ // less conservative, they should have specified it explicitly in the data
+ // layout.
+ return Align(PowerOf2Ceil(BitWidth / 8));
+ }
case Type::X86_MMXTyID:
case Type::FixedVectorTyID:
- case Type::ScalableVectorTyID: {
- unsigned BitWidth = getTypeSizeInBits(Ty).getKnownMinSize();
- auto I = findAlignmentLowerBound(VECTOR_ALIGN, BitWidth);
- if (I != Alignments.end() && I->AlignType == VECTOR_ALIGN &&
- I->TypeBitWidth == BitWidth)
- return abi_or_pref ? I->ABIAlign : I->PrefAlign;
-
- // By default, use natural alignment for vector types. This is consistent
- // with what clang and llvm-gcc do.
- // TODO: This should probably not be using the alloc size.
- unsigned Alignment =
- getTypeAllocSize(cast<VectorType>(Ty)->getElementType());
- // We're only calculating a natural alignment, so it doesn't have to be
- // based on the full size for scalable vectors. Using the minimum element
- // count should be enough here.
- Alignment *= cast<VectorType>(Ty)->getElementCount().getKnownMinValue();
- Alignment = PowerOf2Ceil(Alignment);
- return Align(Alignment);
- }
- case Type::X86_AMXTyID:
- return Align(64);
+ case Type::ScalableVectorTyID: {
+ unsigned BitWidth = getTypeSizeInBits(Ty).getKnownMinSize();
+ auto I = findAlignmentLowerBound(VECTOR_ALIGN, BitWidth);
+ if (I != Alignments.end() && I->AlignType == VECTOR_ALIGN &&
+ I->TypeBitWidth == BitWidth)
+ return abi_or_pref ? I->ABIAlign : I->PrefAlign;
+
+ // By default, use natural alignment for vector types. This is consistent
+ // with what clang and llvm-gcc do.
+ // TODO: This should probably not be using the alloc size.
+ unsigned Alignment =
+ getTypeAllocSize(cast<VectorType>(Ty)->getElementType());
+ // We're only calculating a natural alignment, so it doesn't have to be
+ // based on the full size for scalable vectors. Using the minimum element
+ // count should be enough here.
+ Alignment *= cast<VectorType>(Ty)->getElementCount().getKnownMinValue();
+ Alignment = PowerOf2Ceil(Alignment);
+ return Align(Alignment);
+ }
+ case Type::X86_AMXTyID:
+ return Align(64);
default:
llvm_unreachable("Bad type for getAlignment!!!");
}
diff --git a/contrib/libs/llvm12/lib/IR/DebugInfo.cpp b/contrib/libs/llvm12/lib/IR/DebugInfo.cpp
index 9f9d4aad5b..d7656b9dd1 100644
--- a/contrib/libs/llvm12/lib/IR/DebugInfo.cpp
+++ b/contrib/libs/llvm12/lib/IR/DebugInfo.cpp
@@ -652,8 +652,8 @@ bool llvm::stripNonLineTableDebugInfo(Module &M) {
MDNode *InlinedAt = DL.getInlinedAt();
Scope = remap(Scope);
InlinedAt = remap(InlinedAt);
- return DILocation::get(M.getContext(), DL.getLine(), DL.getCol(),
- Scope, InlinedAt);
+ return DILocation::get(M.getContext(), DL.getLine(), DL.getCol(),
+ Scope, InlinedAt);
};
if (I.getDebugLoc() != DebugLoc())
@@ -697,38 +697,38 @@ void Instruction::applyMergedLocation(const DILocation *LocA,
setDebugLoc(DILocation::getMergedLocation(LocA, LocB));
}
-void Instruction::updateLocationAfterHoist() { dropLocation(); }
-
-void Instruction::dropLocation() {
- const DebugLoc &DL = getDebugLoc();
- if (!DL)
- return;
-
- // If this isn't a call, drop the location to allow a location from a
- // preceding instruction to propagate.
- if (!isa<CallBase>(this)) {
- setDebugLoc(DebugLoc());
- return;
- }
-
- // Set a line 0 location for calls to preserve scope information in case
- // inlining occurs.
- DISubprogram *SP = getFunction()->getSubprogram();
- if (SP)
- // If a function scope is available, set it on the line 0 location. When
- // hoisting a call to a predecessor block, using the function scope avoids
- // making it look like the callee was reached earlier than it should be.
- setDebugLoc(DILocation::get(getContext(), 0, 0, SP));
- else
- // The parent function has no scope. Go ahead and drop the location. If
- // the parent function is inlined, and the callee has a subprogram, the
- // inliner will attach a location to the call.
- //
- // One alternative is to set a line 0 location with the existing scope and
- // inlinedAt info. The location might be sensitive to when inlining occurs.
- setDebugLoc(DebugLoc());
-}
-
+void Instruction::updateLocationAfterHoist() { dropLocation(); }
+
+void Instruction::dropLocation() {
+ const DebugLoc &DL = getDebugLoc();
+ if (!DL)
+ return;
+
+ // If this isn't a call, drop the location to allow a location from a
+ // preceding instruction to propagate.
+ if (!isa<CallBase>(this)) {
+ setDebugLoc(DebugLoc());
+ return;
+ }
+
+ // Set a line 0 location for calls to preserve scope information in case
+ // inlining occurs.
+ DISubprogram *SP = getFunction()->getSubprogram();
+ if (SP)
+ // If a function scope is available, set it on the line 0 location. When
+ // hoisting a call to a predecessor block, using the function scope avoids
+ // making it look like the callee was reached earlier than it should be.
+ setDebugLoc(DILocation::get(getContext(), 0, 0, SP));
+ else
+ // The parent function has no scope. Go ahead and drop the location. If
+ // the parent function is inlined, and the callee has a subprogram, the
+ // inliner will attach a location to the call.
+ //
+ // One alternative is to set a line 0 location with the existing scope and
+ // inlinedAt info. The location might be sensitive to when inlining occurs.
+ setDebugLoc(DebugLoc());
+}
+
//===----------------------------------------------------------------------===//
// LLVM C API implementations.
//===----------------------------------------------------------------------===//
diff --git a/contrib/libs/llvm12/lib/IR/DebugInfoMetadata.cpp b/contrib/libs/llvm12/lib/IR/DebugInfoMetadata.cpp
index fde585a38f..77bba9f7ed 100644
--- a/contrib/libs/llvm12/lib/IR/DebugInfoMetadata.cpp
+++ b/contrib/libs/llvm12/lib/IR/DebugInfoMetadata.cpp
@@ -133,7 +133,7 @@ const DILocation *DILocation::getMergedLocation(const DILocation *LocA,
}
Optional<unsigned> DILocation::encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI) {
- std::array<unsigned, 3> Components = {BD, DF, CI};
+ std::array<unsigned, 3> Components = {BD, DF, CI};
uint64_t RemainingWork = 0U;
// We use RemainingWork to figure out if we have no remaining components to
// encode. For example: if BD != 0 but DF == 0 && CI == 0, we don't need to
@@ -435,84 +435,84 @@ DISubrange::BoundType DISubrange::getStride() const {
return BoundType();
}
-DIGenericSubrange *DIGenericSubrange::getImpl(LLVMContext &Context,
- Metadata *CountNode, Metadata *LB,
- Metadata *UB, Metadata *Stride,
- StorageType Storage,
- bool ShouldCreate) {
- DEFINE_GETIMPL_LOOKUP(DIGenericSubrange, (CountNode, LB, UB, Stride));
- Metadata *Ops[] = {CountNode, LB, UB, Stride};
- DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIGenericSubrange, Ops);
-}
-
-DIGenericSubrange::BoundType DIGenericSubrange::getCount() const {
- Metadata *CB = getRawCountNode();
- if (!CB)
- return BoundType();
-
- assert((isa<DIVariable>(CB) || isa<DIExpression>(CB)) &&
- "Count must be signed constant or DIVariable or DIExpression");
-
- if (auto *MD = dyn_cast<DIVariable>(CB))
- return BoundType(MD);
-
- if (auto *MD = dyn_cast<DIExpression>(CB))
- return BoundType(MD);
-
- return BoundType();
-}
-
-DIGenericSubrange::BoundType DIGenericSubrange::getLowerBound() const {
- Metadata *LB = getRawLowerBound();
- if (!LB)
- return BoundType();
-
- assert((isa<DIVariable>(LB) || isa<DIExpression>(LB)) &&
- "LowerBound must be signed constant or DIVariable or DIExpression");
-
- if (auto *MD = dyn_cast<DIVariable>(LB))
- return BoundType(MD);
-
- if (auto *MD = dyn_cast<DIExpression>(LB))
- return BoundType(MD);
-
- return BoundType();
-}
-
-DIGenericSubrange::BoundType DIGenericSubrange::getUpperBound() const {
- Metadata *UB = getRawUpperBound();
- if (!UB)
- return BoundType();
-
- assert((isa<DIVariable>(UB) || isa<DIExpression>(UB)) &&
- "UpperBound must be signed constant or DIVariable or DIExpression");
-
- if (auto *MD = dyn_cast<DIVariable>(UB))
- return BoundType(MD);
-
- if (auto *MD = dyn_cast<DIExpression>(UB))
- return BoundType(MD);
-
- return BoundType();
-}
-
-DIGenericSubrange::BoundType DIGenericSubrange::getStride() const {
- Metadata *ST = getRawStride();
- if (!ST)
- return BoundType();
-
- assert((isa<DIVariable>(ST) || isa<DIExpression>(ST)) &&
- "Stride must be signed constant or DIVariable or DIExpression");
-
- if (auto *MD = dyn_cast<DIVariable>(ST))
- return BoundType(MD);
-
- if (auto *MD = dyn_cast<DIExpression>(ST))
- return BoundType(MD);
-
- return BoundType();
-}
-
+DIGenericSubrange *DIGenericSubrange::getImpl(LLVMContext &Context,
+ Metadata *CountNode, Metadata *LB,
+ Metadata *UB, Metadata *Stride,
+ StorageType Storage,
+ bool ShouldCreate) {
+ DEFINE_GETIMPL_LOOKUP(DIGenericSubrange, (CountNode, LB, UB, Stride));
+ Metadata *Ops[] = {CountNode, LB, UB, Stride};
+ DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIGenericSubrange, Ops);
+}
+
+DIGenericSubrange::BoundType DIGenericSubrange::getCount() const {
+ Metadata *CB = getRawCountNode();
+ if (!CB)
+ return BoundType();
+
+ assert((isa<DIVariable>(CB) || isa<DIExpression>(CB)) &&
+ "Count must be signed constant or DIVariable or DIExpression");
+
+ if (auto *MD = dyn_cast<DIVariable>(CB))
+ return BoundType(MD);
+
+ if (auto *MD = dyn_cast<DIExpression>(CB))
+ return BoundType(MD);
+
+ return BoundType();
+}
+
+DIGenericSubrange::BoundType DIGenericSubrange::getLowerBound() const {
+ Metadata *LB = getRawLowerBound();
+ if (!LB)
+ return BoundType();
+
+ assert((isa<DIVariable>(LB) || isa<DIExpression>(LB)) &&
+ "LowerBound must be signed constant or DIVariable or DIExpression");
+
+ if (auto *MD = dyn_cast<DIVariable>(LB))
+ return BoundType(MD);
+
+ if (auto *MD = dyn_cast<DIExpression>(LB))
+ return BoundType(MD);
+
+ return BoundType();
+}
+
+DIGenericSubrange::BoundType DIGenericSubrange::getUpperBound() const {
+ Metadata *UB = getRawUpperBound();
+ if (!UB)
+ return BoundType();
+
+ assert((isa<DIVariable>(UB) || isa<DIExpression>(UB)) &&
+ "UpperBound must be signed constant or DIVariable or DIExpression");
+
+ if (auto *MD = dyn_cast<DIVariable>(UB))
+ return BoundType(MD);
+
+ if (auto *MD = dyn_cast<DIExpression>(UB))
+ return BoundType(MD);
+
+ return BoundType();
+}
+
+DIGenericSubrange::BoundType DIGenericSubrange::getStride() const {
+ Metadata *ST = getRawStride();
+ if (!ST)
+ return BoundType();
+
+ assert((isa<DIVariable>(ST) || isa<DIExpression>(ST)) &&
+ "Stride must be signed constant or DIVariable or DIExpression");
+
+ if (auto *MD = dyn_cast<DIVariable>(ST))
+ return BoundType(MD);
+
+ if (auto *MD = dyn_cast<DIExpression>(ST))
+ return BoundType(MD);
+
+ return BoundType();
+}
+
DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, const APInt &Value,
bool IsUnsigned, MDString *Name,
StorageType Storage, bool ShouldCreate) {
@@ -548,20 +548,20 @@ Optional<DIBasicType::Signedness> DIBasicType::getSignedness() const {
}
}
-DIStringType *DIStringType::getImpl(LLVMContext &Context, unsigned Tag,
- MDString *Name, Metadata *StringLength,
- Metadata *StringLengthExp,
- uint64_t SizeInBits, uint32_t AlignInBits,
- unsigned Encoding, StorageType Storage,
- bool ShouldCreate) {
- assert(isCanonical(Name) && "Expected canonical MDString");
- DEFINE_GETIMPL_LOOKUP(DIStringType, (Tag, Name, StringLength, StringLengthExp,
- SizeInBits, AlignInBits, Encoding));
- Metadata *Ops[] = {nullptr, nullptr, Name, StringLength, StringLengthExp};
- DEFINE_GETIMPL_STORE(DIStringType, (Tag, SizeInBits, AlignInBits, Encoding),
- Ops);
-}
-
+DIStringType *DIStringType::getImpl(LLVMContext &Context, unsigned Tag,
+ MDString *Name, Metadata *StringLength,
+ Metadata *StringLengthExp,
+ uint64_t SizeInBits, uint32_t AlignInBits,
+ unsigned Encoding, StorageType Storage,
+ bool ShouldCreate) {
+ assert(isCanonical(Name) && "Expected canonical MDString");
+ DEFINE_GETIMPL_LOOKUP(DIStringType, (Tag, Name, StringLength, StringLengthExp,
+ SizeInBits, AlignInBits, Encoding));
+ Metadata *Ops[] = {nullptr, nullptr, Name, StringLength, StringLengthExp};
+ DEFINE_GETIMPL_STORE(DIStringType, (Tag, SizeInBits, AlignInBits, Encoding),
+ Ops);
+}
+
DIDerivedType *DIDerivedType::getImpl(
LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
@@ -585,20 +585,20 @@ DICompositeType *DICompositeType::getImpl(
uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator,
- Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
- Metadata *Rank, StorageType Storage, bool ShouldCreate) {
+ Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
+ Metadata *Rank, StorageType Storage, bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
// Keep this in sync with buildODRType.
- DEFINE_GETIMPL_LOOKUP(
- DICompositeType,
- (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
- OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
- Identifier, Discriminator, DataLocation, Associated, Allocated, Rank));
+ DEFINE_GETIMPL_LOOKUP(
+ DICompositeType,
+ (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
+ Identifier, Discriminator, DataLocation, Associated, Allocated, Rank));
Metadata *Ops[] = {File, Scope, Name, BaseType,
Elements, VTableHolder, TemplateParams, Identifier,
- Discriminator, DataLocation, Associated, Allocated,
- Rank};
+ Discriminator, DataLocation, Associated, Allocated,
+ Rank};
DEFINE_GETIMPL_STORE(DICompositeType, (Tag, Line, RuntimeLang, SizeInBits,
AlignInBits, OffsetInBits, Flags),
Ops);
@@ -610,8 +610,8 @@ DICompositeType *DICompositeType::buildODRType(
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
- Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
- Metadata *Rank) {
+ Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
+ Metadata *Rank) {
assert(!Identifier.getString().empty() && "Expected valid identifier");
if (!Context.isODRUniquingDebugTypes())
return nullptr;
@@ -621,7 +621,7 @@ DICompositeType *DICompositeType::buildODRType(
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
VTableHolder, TemplateParams, &Identifier, Discriminator,
- DataLocation, Associated, Allocated, Rank);
+ DataLocation, Associated, Allocated, Rank);
// Only mutate CT if it's a forward declaration and the new operands aren't.
assert(CT->getRawIdentifier() == &Identifier && "Wrong ODR identifier?");
@@ -633,8 +633,8 @@ DICompositeType *DICompositeType::buildODRType(
Flags);
Metadata *Ops[] = {File, Scope, Name, BaseType,
Elements, VTableHolder, TemplateParams, &Identifier,
- Discriminator, DataLocation, Associated, Allocated,
- Rank};
+ Discriminator, DataLocation, Associated, Allocated,
+ Rank};
assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() &&
"Mismatched number of operands");
for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I)
@@ -649,8 +649,8 @@ DICompositeType *DICompositeType::getODRType(
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
- Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
- Metadata *Rank) {
+ Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
+ Metadata *Rank) {
assert(!Identifier.getString().empty() && "Expected valid identifier");
if (!Context.isODRUniquingDebugTypes())
return nullptr;
@@ -659,8 +659,8 @@ DICompositeType *DICompositeType::getODRType(
CT = DICompositeType::getDistinct(
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder,
- TemplateParams, &Identifier, Discriminator, DataLocation, Associated,
- Allocated, Rank);
+ TemplateParams, &Identifier, Discriminator, DataLocation, Associated,
+ Allocated, Rank);
return CT;
}
@@ -926,14 +926,14 @@ DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *File,
Metadata *Scope, MDString *Name,
MDString *ConfigurationMacros,
MDString *IncludePath, MDString *APINotesFile,
- unsigned LineNo, bool IsDecl, StorageType Storage,
+ unsigned LineNo, bool IsDecl, StorageType Storage,
bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
DEFINE_GETIMPL_LOOKUP(DIModule, (File, Scope, Name, ConfigurationMacros,
- IncludePath, APINotesFile, LineNo, IsDecl));
+ IncludePath, APINotesFile, LineNo, IsDecl));
Metadata *Ops[] = {File, Scope, Name, ConfigurationMacros,
IncludePath, APINotesFile};
- DEFINE_GETIMPL_STORE(DIModule, (LineNo, IsDecl), Ops);
+ DEFINE_GETIMPL_STORE(DIModule, (LineNo, IsDecl), Ops);
}
DITemplateTypeParameter *
@@ -1114,7 +1114,7 @@ bool DIExpression::isValid() const {
return I->get() == expr_op_begin()->get() && I->getArg(0) == 1 &&
getNumElements() == 2;
}
- case dwarf::DW_OP_LLVM_implicit_pointer:
+ case dwarf::DW_OP_LLVM_implicit_pointer:
case dwarf::DW_OP_LLVM_convert:
case dwarf::DW_OP_LLVM_tag_offset:
case dwarf::DW_OP_constu:
@@ -1139,8 +1139,8 @@ bool DIExpression::isValid() const {
case dwarf::DW_OP_regx:
case dwarf::DW_OP_bregx:
case dwarf::DW_OP_push_object_address:
- case dwarf::DW_OP_over:
- case dwarf::DW_OP_consts:
+ case dwarf::DW_OP_over:
+ case dwarf::DW_OP_consts:
break;
}
}
@@ -1414,15 +1414,15 @@ bool DIExpression::isConstant() const {
return true;
}
-bool DIExpression::isSignedConstant() const {
- // Recognize DW_OP_consts C
- if (getNumElements() != 2)
- return false;
- if (getElement(0) != dwarf::DW_OP_consts)
- return false;
- return true;
-}
-
+bool DIExpression::isSignedConstant() const {
+ // Recognize DW_OP_consts C
+ if (getNumElements() != 2)
+ return false;
+ if (getElement(0) != dwarf::DW_OP_consts)
+ return false;
+ return true;
+}
+
DIExpression::ExtOps DIExpression::getExtOps(unsigned FromSize, unsigned ToSize,
bool Signed) {
dwarf::TypeKind TK = Signed ? dwarf::DW_ATE_signed : dwarf::DW_ATE_unsigned;
diff --git a/contrib/libs/llvm12/lib/IR/DebugLoc.cpp b/contrib/libs/llvm12/lib/IR/DebugLoc.cpp
index 5ea0145aff..993f3a39e6 100644
--- a/contrib/libs/llvm12/lib/IR/DebugLoc.cpp
+++ b/contrib/libs/llvm12/lib/IR/DebugLoc.cpp
@@ -50,7 +50,7 @@ DebugLoc DebugLoc::getFnDebugLoc() const {
// FIXME: Add a method on \a DILocation that does this work.
const MDNode *Scope = getInlinedAtScope();
if (auto *SP = getDISubprogram(Scope))
- return DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
+ return DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
return DebugLoc();
}
@@ -70,7 +70,7 @@ void DebugLoc::setImplicitCode(bool ImplicitCode) {
DebugLoc DebugLoc::appendInlinedAt(const DebugLoc &DL, DILocation *InlinedAt,
LLVMContext &Ctx,
- DenseMap<const MDNode *, MDNode *> &Cache) {
+ DenseMap<const MDNode *, MDNode *> &Cache) {
SmallVector<DILocation *, 3> InlinedAtLocations;
DILocation *Last = InlinedAt;
DILocation *CurInlinedAt = DL;
diff --git a/contrib/libs/llvm12/lib/IR/DiagnosticInfo.cpp b/contrib/libs/llvm12/lib/IR/DiagnosticInfo.cpp
index 1ca85a3ec4..8820a79421 100644
--- a/contrib/libs/llvm12/lib/IR/DiagnosticInfo.cpp
+++ b/contrib/libs/llvm12/lib/IR/DiagnosticInfo.cpp
@@ -32,7 +32,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/InstructionCost.h"
+#include "llvm/Support/InstructionCost.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/ScopedPrinter.h"
@@ -214,20 +214,20 @@ DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
unsigned long long N)
: Key(std::string(Key)), Val(utostr(N)) {}
-DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
- ElementCount EC)
- : Key(std::string(Key)) {
- raw_string_ostream OS(Val);
- EC.print(OS);
-}
-
-DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
- InstructionCost C)
- : Key(std::string(Key)) {
- raw_string_ostream OS(Val);
- C.print(OS);
-}
-
+DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
+ ElementCount EC)
+ : Key(std::string(Key)) {
+ raw_string_ostream OS(Val);
+ EC.print(OS);
+}
+
+DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
+ InstructionCost C)
+ : Key(std::string(Key)) {
+ raw_string_ostream OS(Val);
+ C.print(OS);
+}
+
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, DebugLoc Loc)
: Key(std::string(Key)), Loc(Loc) {
if (Loc) {
diff --git a/contrib/libs/llvm12/lib/IR/Dominators.cpp b/contrib/libs/llvm12/lib/IR/Dominators.cpp
index 3bcd512283..fbc28c202a 100644
--- a/contrib/libs/llvm12/lib/IR/Dominators.cpp
+++ b/contrib/libs/llvm12/lib/IR/Dominators.cpp
@@ -90,11 +90,11 @@ template void llvm::DomTreeBuilder::DeleteEdge<DomTreeBuilder::BBPostDomTree>(
DomTreeBuilder::BBPostDomTree &DT, BasicBlock *From, BasicBlock *To);
template void llvm::DomTreeBuilder::ApplyUpdates<DomTreeBuilder::BBDomTree>(
- DomTreeBuilder::BBDomTree &DT, DomTreeBuilder::BBDomTreeGraphDiff &,
- DomTreeBuilder::BBDomTreeGraphDiff *);
+ DomTreeBuilder::BBDomTree &DT, DomTreeBuilder::BBDomTreeGraphDiff &,
+ DomTreeBuilder::BBDomTreeGraphDiff *);
template void llvm::DomTreeBuilder::ApplyUpdates<DomTreeBuilder::BBPostDomTree>(
- DomTreeBuilder::BBPostDomTree &DT, DomTreeBuilder::BBPostDomTreeGraphDiff &,
- DomTreeBuilder::BBPostDomTreeGraphDiff *);
+ DomTreeBuilder::BBPostDomTree &DT, DomTreeBuilder::BBPostDomTreeGraphDiff &,
+ DomTreeBuilder::BBPostDomTreeGraphDiff *);
template bool llvm::DomTreeBuilder::Verify<DomTreeBuilder::BBDomTree>(
const DomTreeBuilder::BBDomTree &DT,
@@ -115,15 +115,15 @@ bool DominatorTree::invalidate(Function &F, const PreservedAnalyses &PA,
// dominates - 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!
-bool DominatorTree::dominates(const Value *DefV,
+bool DominatorTree::dominates(const Value *DefV,
const Instruction *User) const {
- const Instruction *Def = dyn_cast<Instruction>(DefV);
- if (!Def) {
- assert((isa<Argument>(DefV) || isa<Constant>(DefV)) &&
- "Should be called with an instruction, argument or constant");
- return true; // Arguments and constants dominate everything.
- }
-
+ const Instruction *Def = dyn_cast<Instruction>(DefV);
+ if (!Def) {
+ assert((isa<Argument>(DefV) || isa<Constant>(DefV)) &&
+ "Should be called with an instruction, argument or constant");
+ return true; // Arguments and constants dominate everything.
+ }
+
const BasicBlock *UseBB = User->getParent();
const BasicBlock *DefBB = Def->getParent();
@@ -257,14 +257,14 @@ bool DominatorTree::dominates(const BasicBlockEdge &BBE, const Use &U) const {
return dominates(BBE, UseBB);
}
-bool DominatorTree::dominates(const Value *DefV, const Use &U) const {
- const Instruction *Def = dyn_cast<Instruction>(DefV);
- if (!Def) {
- assert((isa<Argument>(DefV) || isa<Constant>(DefV)) &&
- "Should be called with an instruction, argument or constant");
- return true; // Arguments and constants dominate everything.
- }
-
+bool DominatorTree::dominates(const Value *DefV, const Use &U) const {
+ const Instruction *Def = dyn_cast<Instruction>(DefV);
+ if (!Def) {
+ assert((isa<Argument>(DefV) || isa<Constant>(DefV)) &&
+ "Should be called with an instruction, argument or constant");
+ return true; // Arguments and constants dominate everything.
+ }
+
Instruction *UserInst = cast<Instruction>(U.getUser());
const BasicBlock *DefBB = Def->getParent();
diff --git a/contrib/libs/llvm12/lib/IR/Function.cpp b/contrib/libs/llvm12/lib/IR/Function.cpp
index 42c226de9d..17247123f8 100644
--- a/contrib/libs/llvm12/lib/IR/Function.cpp
+++ b/contrib/libs/llvm12/lib/IR/Function.cpp
@@ -43,7 +43,7 @@
#include "llvm/IR/IntrinsicsR600.h"
#include "llvm/IR/IntrinsicsRISCV.h"
#include "llvm/IR/IntrinsicsS390.h"
-#include "llvm/IR/IntrinsicsVE.h"
+#include "llvm/IR/IntrinsicsVE.h"
#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/IR/IntrinsicsX86.h"
#include "llvm/IR/IntrinsicsXCore.h"
@@ -87,11 +87,11 @@ void Argument::setParent(Function *parent) {
Parent = parent;
}
-bool Argument::hasNonNullAttr(bool AllowUndefOrPoison) const {
+bool Argument::hasNonNullAttr(bool AllowUndefOrPoison) const {
if (!getType()->isPointerTy()) return false;
- if (getParent()->hasParamAttribute(getArgNo(), Attribute::NonNull) &&
- (AllowUndefOrPoison ||
- getParent()->hasParamAttribute(getArgNo(), Attribute::NoUndef)))
+ if (getParent()->hasParamAttribute(getArgNo(), Attribute::NonNull) &&
+ (AllowUndefOrPoison ||
+ getParent()->hasParamAttribute(getArgNo(), Attribute::NoUndef)))
return true;
else if (getDereferenceableBytes() > 0 &&
!NullPointerIsDefined(getParent(),
@@ -105,12 +105,12 @@ bool Argument::hasByValAttr() const {
return hasAttribute(Attribute::ByVal);
}
-bool Argument::hasByRefAttr() const {
- if (!getType()->isPointerTy())
- return false;
- return hasAttribute(Attribute::ByRef);
-}
-
+bool Argument::hasByRefAttr() const {
+ if (!getType()->isPointerTy())
+ return false;
+ return hasAttribute(Attribute::ByRef);
+}
+
bool Argument::hasSwiftSelfAttr() const {
return getParent()->hasParamAttribute(getArgNo(), Attribute::SwiftSelf);
}
@@ -130,7 +130,7 @@ bool Argument::hasPreallocatedAttr() const {
return hasAttribute(Attribute::Preallocated);
}
-bool Argument::hasPassPointeeByValueCopyAttr() const {
+bool Argument::hasPassPointeeByValueCopyAttr() const {
if (!getType()->isPointerTy()) return false;
AttributeList Attrs = getParent()->getAttributes();
return Attrs.hasParamAttribute(getArgNo(), Attribute::ByVal) ||
@@ -138,54 +138,54 @@ bool Argument::hasPassPointeeByValueCopyAttr() const {
Attrs.hasParamAttribute(getArgNo(), Attribute::Preallocated);
}
-bool Argument::hasPointeeInMemoryValueAttr() const {
- if (!getType()->isPointerTy())
- return false;
- AttributeList Attrs = getParent()->getAttributes();
- return Attrs.hasParamAttribute(getArgNo(), Attribute::ByVal) ||
- Attrs.hasParamAttribute(getArgNo(), Attribute::StructRet) ||
- Attrs.hasParamAttribute(getArgNo(), Attribute::InAlloca) ||
- Attrs.hasParamAttribute(getArgNo(), Attribute::Preallocated) ||
- Attrs.hasParamAttribute(getArgNo(), Attribute::ByRef);
-}
-
-/// For a byval, sret, inalloca, or preallocated parameter, get the in-memory
-/// parameter type.
-static Type *getMemoryParamAllocType(AttributeSet ParamAttrs, Type *ArgTy) {
+bool Argument::hasPointeeInMemoryValueAttr() const {
+ if (!getType()->isPointerTy())
+ return false;
+ AttributeList Attrs = getParent()->getAttributes();
+ return Attrs.hasParamAttribute(getArgNo(), Attribute::ByVal) ||
+ Attrs.hasParamAttribute(getArgNo(), Attribute::StructRet) ||
+ Attrs.hasParamAttribute(getArgNo(), Attribute::InAlloca) ||
+ Attrs.hasParamAttribute(getArgNo(), Attribute::Preallocated) ||
+ Attrs.hasParamAttribute(getArgNo(), Attribute::ByRef);
+}
+
+/// For a byval, sret, inalloca, or preallocated parameter, get the in-memory
+/// parameter type.
+static Type *getMemoryParamAllocType(AttributeSet ParamAttrs, Type *ArgTy) {
// FIXME: All the type carrying attributes are mutually exclusive, so there
// should be a single query to get the stored type that handles any of them.
if (Type *ByValTy = ParamAttrs.getByValType())
- return ByValTy;
- if (Type *ByRefTy = ParamAttrs.getByRefType())
- return ByRefTy;
+ return ByValTy;
+ if (Type *ByRefTy = ParamAttrs.getByRefType())
+ return ByRefTy;
if (Type *PreAllocTy = ParamAttrs.getPreallocatedType())
- return PreAllocTy;
+ return PreAllocTy;
- // FIXME: sret and inalloca always depends on pointee element type. It's also
- // possible for byval to miss it.
+ // FIXME: sret and inalloca always depends on pointee element type. It's also
+ // possible for byval to miss it.
if (ParamAttrs.hasAttribute(Attribute::InAlloca) ||
ParamAttrs.hasAttribute(Attribute::ByVal) ||
- ParamAttrs.hasAttribute(Attribute::StructRet) ||
+ ParamAttrs.hasAttribute(Attribute::StructRet) ||
ParamAttrs.hasAttribute(Attribute::Preallocated))
- return cast<PointerType>(ArgTy)->getElementType();
-
- return nullptr;
-}
-
-uint64_t Argument::getPassPointeeByValueCopySize(const DataLayout &DL) const {
- AttributeSet ParamAttrs =
- getParent()->getAttributes().getParamAttributes(getArgNo());
- if (Type *MemTy = getMemoryParamAllocType(ParamAttrs, getType()))
- return DL.getTypeAllocSize(MemTy);
+ return cast<PointerType>(ArgTy)->getElementType();
+
+ return nullptr;
+}
+
+uint64_t Argument::getPassPointeeByValueCopySize(const DataLayout &DL) const {
+ AttributeSet ParamAttrs =
+ getParent()->getAttributes().getParamAttributes(getArgNo());
+ if (Type *MemTy = getMemoryParamAllocType(ParamAttrs, getType()))
+ return DL.getTypeAllocSize(MemTy);
return 0;
}
-Type *Argument::getPointeeInMemoryValueType() const {
- AttributeSet ParamAttrs =
- getParent()->getAttributes().getParamAttributes(getArgNo());
- return getMemoryParamAllocType(ParamAttrs, getType());
-}
-
+Type *Argument::getPointeeInMemoryValueType() const {
+ AttributeSet ParamAttrs =
+ getParent()->getAttributes().getParamAttributes(getArgNo());
+ return getMemoryParamAllocType(ParamAttrs, getType());
+}
+
unsigned Argument::getParamAlignment() const {
assert(getType()->isPointerTy() && "Only pointers have alignments");
return getParent()->getParamAlignment(getArgNo());
@@ -201,16 +201,16 @@ Type *Argument::getParamByValType() const {
return getParent()->getParamByValType(getArgNo());
}
-Type *Argument::getParamStructRetType() const {
- assert(getType()->isPointerTy() && "Only pointers have sret types");
- return getParent()->getParamStructRetType(getArgNo());
-}
-
-Type *Argument::getParamByRefType() const {
- assert(getType()->isPointerTy() && "Only pointers have byval types");
- return getParent()->getParamByRefType(getArgNo());
-}
-
+Type *Argument::getParamStructRetType() const {
+ assert(getType()->isPointerTy() && "Only pointers have sret types");
+ return getParent()->getParamStructRetType(getArgNo());
+}
+
+Type *Argument::getParamByRefType() const {
+ assert(getType()->isPointerTy() && "Only pointers have byval types");
+ return getParent()->getParamByRefType(getArgNo());
+}
+
uint64_t Argument::getDereferenceableBytes() const {
assert(getType()->isPointerTy() &&
"Only pointers have dereferenceable bytes");
@@ -580,21 +580,21 @@ void Function::addDereferenceableOrNullParamAttr(unsigned ArgNo,
setAttributes(PAL);
}
-DenormalMode Function::getDenormalMode(const fltSemantics &FPType) const {
- if (&FPType == &APFloat::IEEEsingle()) {
- Attribute Attr = getFnAttribute("denormal-fp-math-f32");
- StringRef Val = Attr.getValueAsString();
- if (!Val.empty())
- return parseDenormalFPAttribute(Val);
-
- // If the f32 variant of the attribute isn't specified, try to use the
- // generic one.
- }
-
- Attribute Attr = getFnAttribute("denormal-fp-math");
- return parseDenormalFPAttribute(Attr.getValueAsString());
-}
-
+DenormalMode Function::getDenormalMode(const fltSemantics &FPType) const {
+ if (&FPType == &APFloat::IEEEsingle()) {
+ Attribute Attr = getFnAttribute("denormal-fp-math-f32");
+ StringRef Val = Attr.getValueAsString();
+ if (!Val.empty())
+ return parseDenormalFPAttribute(Val);
+
+ // If the f32 variant of the attribute isn't specified, try to use the
+ // generic one.
+ }
+
+ Attribute Attr = getFnAttribute("denormal-fp-math");
+ return parseDenormalFPAttribute(Attr.getValueAsString());
+}
+
const std::string &Function::getGC() const {
assert(hasGC() && "Function has no collector");
return getContext().getGC(*this);
@@ -612,12 +612,12 @@ void Function::clearGC() {
setValueSubclassDataBit(14, false);
}
-bool Function::hasStackProtectorFnAttr() const {
- return hasFnAttribute(Attribute::StackProtect) ||
- hasFnAttribute(Attribute::StackProtectStrong) ||
- hasFnAttribute(Attribute::StackProtectReq);
-}
-
+bool Function::hasStackProtectorFnAttr() const {
+ return hasFnAttribute(Attribute::StackProtect) ||
+ hasFnAttribute(Attribute::StackProtectStrong) ||
+ hasFnAttribute(Attribute::StackProtectReq);
+}
+
/// Copy all additional attributes (those not needed to create a Function) from
/// the Function Src to this one.
void Function::copyAttributesFrom(const Function *Src) {
@@ -649,14 +649,14 @@ static const char * const IntrinsicNameTable[] = {
#include "llvm/IR/IntrinsicImpl.inc"
#undef GET_INTRINSIC_TARGET_DATA
-bool Function::isTargetIntrinsic(Intrinsic::ID IID) {
- return IID > TargetInfos[0].Count;
-}
-
-bool Function::isTargetIntrinsic() const {
- return isTargetIntrinsic(IntID);
-}
-
+bool Function::isTargetIntrinsic(Intrinsic::ID IID) {
+ return IID > TargetInfos[0].Count;
+}
+
+bool Function::isTargetIntrinsic() const {
+ return isTargetIntrinsic(IntID);
+}
+
/// Find the segment of \c IntrinsicNameTable for intrinsics with the same
/// target as \c Name, or the generic table if \c Name is not target specific.
///
@@ -749,10 +749,10 @@ static std::string getMangledTypeStr(Type* Ty) {
Result += "f";
} else if (VectorType* VTy = dyn_cast<VectorType>(Ty)) {
ElementCount EC = VTy->getElementCount();
- if (EC.isScalable())
+ if (EC.isScalable())
Result += "nx";
- Result += "v" + utostr(EC.getKnownMinValue()) +
- getMangledTypeStr(VTy->getElementType());
+ Result += "v" + utostr(EC.getKnownMinValue()) +
+ getMangledTypeStr(VTy->getElementType());
} else if (Ty) {
switch (Ty->getTypeID()) {
default: llvm_unreachable("Unhandled type");
@@ -766,7 +766,7 @@ static std::string getMangledTypeStr(Type* Ty) {
case Type::FP128TyID: Result += "f128"; break;
case Type::PPC_FP128TyID: Result += "ppcf128"; break;
case Type::X86_MMXTyID: Result += "x86mmx"; break;
- case Type::X86_AMXTyID: Result += "x86amx"; break;
+ case Type::X86_AMXTyID: Result += "x86amx"; break;
case Type::IntegerTyID:
Result += "i" + utostr(cast<IntegerType>(Ty)->getBitWidth());
break;
@@ -784,8 +784,8 @@ StringRef Intrinsic::getName(ID id) {
std::string Intrinsic::getName(ID id, ArrayRef<Type*> Tys) {
assert(id < num_intrinsics && "Invalid intrinsic ID!");
- assert((Tys.empty() || Intrinsic::isOverloaded(id)) &&
- "This version of getName is for overloaded intrinsics only");
+ assert((Tys.empty() || Intrinsic::isOverloaded(id)) &&
+ "This version of getName is for overloaded intrinsics only");
std::string Result(IntrinsicNameTable[id]);
for (Type *Ty : Tys) {
Result += "." + getMangledTypeStr(Ty);
@@ -849,10 +849,10 @@ enum IIT_Info {
IIT_SUBDIVIDE4_ARG = 45,
IIT_VEC_OF_BITCASTS_TO_INT = 46,
IIT_V128 = 47,
- IIT_BF16 = 48,
- IIT_STRUCT9 = 49,
- IIT_V256 = 50,
- IIT_AMX = 51
+ IIT_BF16 = 48,
+ IIT_STRUCT9 = 49,
+ IIT_V256 = 50,
+ IIT_AMX = 51
};
static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
@@ -875,9 +875,9 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
case IIT_MMX:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::MMX, 0));
return;
- case IIT_AMX:
- OutputTable.push_back(IITDescriptor::get(IITDescriptor::AMX, 0));
- return;
+ case IIT_AMX:
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::AMX, 0));
+ return;
case IIT_TOKEN:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Token, 0));
return;
@@ -949,10 +949,10 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
OutputTable.push_back(IITDescriptor::getVector(128, IsScalableVector));
DecodeIITType(NextElt, Infos, Info, OutputTable);
return;
- case IIT_V256:
- OutputTable.push_back(IITDescriptor::getVector(256, IsScalableVector));
- DecodeIITType(NextElt, Infos, Info, OutputTable);
- return;
+ case IIT_V256:
+ OutputTable.push_back(IITDescriptor::getVector(256, IsScalableVector));
+ DecodeIITType(NextElt, Infos, Info, OutputTable);
+ return;
case IIT_V512:
OutputTable.push_back(IITDescriptor::getVector(512, IsScalableVector));
DecodeIITType(NextElt, Infos, Info, OutputTable);
@@ -1021,7 +1021,7 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
case IIT_EMPTYSTRUCT:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct, 0));
return;
- case IIT_STRUCT9: ++StructElts; LLVM_FALLTHROUGH;
+ case IIT_STRUCT9: ++StructElts; LLVM_FALLTHROUGH;
case IIT_STRUCT8: ++StructElts; LLVM_FALLTHROUGH;
case IIT_STRUCT7: ++StructElts; LLVM_FALLTHROUGH;
case IIT_STRUCT6: ++StructElts; LLVM_FALLTHROUGH;
@@ -1115,7 +1115,7 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
case IITDescriptor::Void: return Type::getVoidTy(Context);
case IITDescriptor::VarArg: return Type::getVoidTy(Context);
case IITDescriptor::MMX: return Type::getX86_MMXTy(Context);
- case IITDescriptor::AMX: return Type::getX86_AMXTy(Context);
+ case IITDescriptor::AMX: return Type::getX86_AMXTy(Context);
case IITDescriptor::Token: return Type::getTokenTy(Context);
case IITDescriptor::Metadata: return Type::getMetadataTy(Context);
case IITDescriptor::Half: return Type::getHalfTy(Context);
@@ -1253,7 +1253,7 @@ Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) {
// There can never be multiple globals with the same name of different types,
// because intrinsics must be a specific type.
return cast<Function>(
- M->getOrInsertFunction(Tys.empty() ? getName(id) : getName(id, Tys),
+ M->getOrInsertFunction(Tys.empty() ? getName(id) : getName(id, Tys),
getType(M->getContext(), id, Tys))
.getCallee());
}
@@ -1295,7 +1295,7 @@ static bool matchIntrinsicType(
case IITDescriptor::Void: return !Ty->isVoidTy();
case IITDescriptor::VarArg: return true;
case IITDescriptor::MMX: return !Ty->isX86_MMXTy();
- case IITDescriptor::AMX: return !Ty->isX86_AMXTy();
+ case IITDescriptor::AMX: return !Ty->isX86_AMXTy();
case IITDescriptor::Token: return !Ty->isTokenTy();
case IITDescriptor::Metadata: return !Ty->isMetadataTy();
case IITDescriptor::Half: return !Ty->isHalfTy();
@@ -1448,10 +1448,10 @@ static bool matchIntrinsicType(
// Verify the overloaded type "matches" the Ref type.
// i.e. Ty is a vector with the same width as Ref.
// Composed of pointers to the same element type as Ref.
- auto *ReferenceType = dyn_cast<VectorType>(ArgTys[RefArgNumber]);
- auto *ThisArgVecTy = dyn_cast<VectorType>(Ty);
+ auto *ReferenceType = dyn_cast<VectorType>(ArgTys[RefArgNumber]);
+ auto *ThisArgVecTy = dyn_cast<VectorType>(Ty);
if (!ThisArgVecTy || !ReferenceType ||
- (ReferenceType->getElementCount() != ThisArgVecTy->getElementCount()))
+ (ReferenceType->getElementCount() != ThisArgVecTy->getElementCount()))
return true;
PointerType *ThisArgEltTy =
dyn_cast<PointerType>(ThisArgVecTy->getElementType());
diff --git a/contrib/libs/llvm12/lib/IR/Globals.cpp b/contrib/libs/llvm12/lib/IR/Globals.cpp
index e6571e3914..c2cbe7dddd 100644
--- a/contrib/libs/llvm12/lib/IR/Globals.cpp
+++ b/contrib/libs/llvm12/lib/IR/Globals.cpp
@@ -352,15 +352,15 @@ GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link,
GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant,
LinkageTypes Link, Constant *InitVal,
const Twine &Name, GlobalVariable *Before,
- ThreadLocalMode TLMode,
- Optional<unsigned> AddressSpace,
+ ThreadLocalMode TLMode,
+ Optional<unsigned> AddressSpace,
bool isExternallyInitialized)
: GlobalObject(Ty, Value::GlobalVariableVal,
OperandTraits<GlobalVariable>::op_begin(this),
- InitVal != nullptr, Link, Name,
- AddressSpace
- ? *AddressSpace
- : M.getDataLayout().getDefaultGlobalsAddressSpace()),
+ InitVal != nullptr, Link, Name,
+ AddressSpace
+ ? *AddressSpace
+ : M.getDataLayout().getDefaultGlobalsAddressSpace()),
isConstantGlobal(constant),
isExternallyInitializedConstant(isExternallyInitialized) {
assert(!Ty->isFunctionTy() && PointerType::isValidElementType(Ty) &&
diff --git a/contrib/libs/llvm12/lib/IR/IRBuilder.cpp b/contrib/libs/llvm12/lib/IR/IRBuilder.cpp
index 26de152afa..91ca984b75 100644
--- a/contrib/libs/llvm12/lib/IR/IRBuilder.cpp
+++ b/contrib/libs/llvm12/lib/IR/IRBuilder.cpp
@@ -72,25 +72,25 @@ Value *IRBuilderBase::getCastedInt8PtrValue(Value *Ptr) {
static CallInst *createCallHelper(Function *Callee, ArrayRef<Value *> Ops,
IRBuilderBase *Builder,
const Twine &Name = "",
- Instruction *FMFSource = nullptr,
- ArrayRef<OperandBundleDef> OpBundles = {}) {
- CallInst *CI = Builder->CreateCall(Callee, Ops, OpBundles, Name);
+ Instruction *FMFSource = nullptr,
+ ArrayRef<OperandBundleDef> OpBundles = {}) {
+ CallInst *CI = Builder->CreateCall(Callee, Ops, OpBundles, Name);
if (FMFSource)
CI->copyFastMathFlags(FMFSource);
return CI;
}
-Value *IRBuilderBase::CreateVScale(Constant *Scaling, const Twine &Name) {
- Module *M = GetInsertBlock()->getParent()->getParent();
- assert(isa<ConstantInt>(Scaling) && "Expected constant integer");
- Function *TheFn =
- Intrinsic::getDeclaration(M, Intrinsic::vscale, {Scaling->getType()});
- CallInst *CI = createCallHelper(TheFn, {}, this, Name);
- return cast<ConstantInt>(Scaling)->getSExtValue() == 1
- ? CI
- : CreateMul(CI, Scaling);
-}
-
+Value *IRBuilderBase::CreateVScale(Constant *Scaling, const Twine &Name) {
+ Module *M = GetInsertBlock()->getParent()->getParent();
+ assert(isa<ConstantInt>(Scaling) && "Expected constant integer");
+ Function *TheFn =
+ Intrinsic::getDeclaration(M, Intrinsic::vscale, {Scaling->getType()});
+ CallInst *CI = createCallHelper(TheFn, {}, this, Name);
+ return cast<ConstantInt>(Scaling)->getSExtValue() == 1
+ ? CI
+ : CreateMul(CI, Scaling);
+}
+
CallInst *IRBuilderBase::CreateMemSet(Value *Ptr, Value *Val, Value *Size,
MaybeAlign Align, bool isVolatile,
MDNode *TBAATag, MDNode *ScopeTag,
@@ -147,21 +147,21 @@ CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemSet(
return CI;
}
-CallInst *IRBuilderBase::CreateMemTransferInst(
- Intrinsic::ID IntrID, Value *Dst, MaybeAlign DstAlign, Value *Src,
- MaybeAlign SrcAlign, Value *Size, bool isVolatile, MDNode *TBAATag,
- MDNode *TBAAStructTag, MDNode *ScopeTag, MDNode *NoAliasTag) {
+CallInst *IRBuilderBase::CreateMemTransferInst(
+ Intrinsic::ID IntrID, Value *Dst, MaybeAlign DstAlign, Value *Src,
+ MaybeAlign SrcAlign, Value *Size, bool isVolatile, MDNode *TBAATag,
+ MDNode *TBAAStructTag, MDNode *ScopeTag, MDNode *NoAliasTag) {
Dst = getCastedInt8PtrValue(Dst);
Src = getCastedInt8PtrValue(Src);
Value *Ops[] = {Dst, Src, Size, getInt1(isVolatile)};
Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
Module *M = BB->getParent()->getParent();
- Function *TheFn = Intrinsic::getDeclaration(M, IntrID, Tys);
+ Function *TheFn = Intrinsic::getDeclaration(M, IntrID, Tys);
CallInst *CI = createCallHelper(TheFn, Ops, this);
- auto* MCI = cast<MemTransferInst>(CI);
+ auto* MCI = cast<MemTransferInst>(CI);
if (DstAlign)
MCI->setDestAlignment(*DstAlign);
if (SrcAlign)
@@ -335,57 +335,57 @@ static CallInst *getReductionIntrinsic(IRBuilderBase *Builder, Intrinsic::ID ID,
CallInst *IRBuilderBase::CreateFAddReduce(Value *Acc, Value *Src) {
Module *M = GetInsertBlock()->getParent()->getParent();
Value *Ops[] = {Acc, Src};
- auto Decl = Intrinsic::getDeclaration(M, Intrinsic::vector_reduce_fadd,
- {Src->getType()});
+ auto Decl = Intrinsic::getDeclaration(M, Intrinsic::vector_reduce_fadd,
+ {Src->getType()});
return createCallHelper(Decl, Ops, this);
}
CallInst *IRBuilderBase::CreateFMulReduce(Value *Acc, Value *Src) {
Module *M = GetInsertBlock()->getParent()->getParent();
Value *Ops[] = {Acc, Src};
- auto Decl = Intrinsic::getDeclaration(M, Intrinsic::vector_reduce_fmul,
- {Src->getType()});
+ auto Decl = Intrinsic::getDeclaration(M, Intrinsic::vector_reduce_fmul,
+ {Src->getType()});
return createCallHelper(Decl, Ops, this);
}
CallInst *IRBuilderBase::CreateAddReduce(Value *Src) {
- return getReductionIntrinsic(this, Intrinsic::vector_reduce_add, Src);
+ return getReductionIntrinsic(this, Intrinsic::vector_reduce_add, Src);
}
CallInst *IRBuilderBase::CreateMulReduce(Value *Src) {
- return getReductionIntrinsic(this, Intrinsic::vector_reduce_mul, Src);
+ return getReductionIntrinsic(this, Intrinsic::vector_reduce_mul, Src);
}
CallInst *IRBuilderBase::CreateAndReduce(Value *Src) {
- return getReductionIntrinsic(this, Intrinsic::vector_reduce_and, Src);
+ return getReductionIntrinsic(this, Intrinsic::vector_reduce_and, Src);
}
CallInst *IRBuilderBase::CreateOrReduce(Value *Src) {
- return getReductionIntrinsic(this, Intrinsic::vector_reduce_or, Src);
+ return getReductionIntrinsic(this, Intrinsic::vector_reduce_or, Src);
}
CallInst *IRBuilderBase::CreateXorReduce(Value *Src) {
- return getReductionIntrinsic(this, Intrinsic::vector_reduce_xor, Src);
+ return getReductionIntrinsic(this, Intrinsic::vector_reduce_xor, Src);
}
CallInst *IRBuilderBase::CreateIntMaxReduce(Value *Src, bool IsSigned) {
- auto ID =
- IsSigned ? Intrinsic::vector_reduce_smax : Intrinsic::vector_reduce_umax;
+ auto ID =
+ IsSigned ? Intrinsic::vector_reduce_smax : Intrinsic::vector_reduce_umax;
return getReductionIntrinsic(this, ID, Src);
}
CallInst *IRBuilderBase::CreateIntMinReduce(Value *Src, bool IsSigned) {
- auto ID =
- IsSigned ? Intrinsic::vector_reduce_smin : Intrinsic::vector_reduce_umin;
+ auto ID =
+ IsSigned ? Intrinsic::vector_reduce_smin : Intrinsic::vector_reduce_umin;
return getReductionIntrinsic(this, ID, Src);
}
-CallInst *IRBuilderBase::CreateFPMaxReduce(Value *Src) {
- return getReductionIntrinsic(this, Intrinsic::vector_reduce_fmax, Src);
+CallInst *IRBuilderBase::CreateFPMaxReduce(Value *Src) {
+ return getReductionIntrinsic(this, Intrinsic::vector_reduce_fmax, Src);
}
-CallInst *IRBuilderBase::CreateFPMinReduce(Value *Src) {
- return getReductionIntrinsic(this, Intrinsic::vector_reduce_fmin, Src);
+CallInst *IRBuilderBase::CreateFPMinReduce(Value *Src) {
+ return getReductionIntrinsic(this, Intrinsic::vector_reduce_fmin, Src);
}
CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) {
@@ -440,25 +440,25 @@ CallInst *IRBuilderBase::CreateInvariantStart(Value *Ptr, ConstantInt *Size) {
return createCallHelper(TheFn, Ops, this);
}
-CallInst *
-IRBuilderBase::CreateAssumption(Value *Cond,
- ArrayRef<OperandBundleDef> OpBundles) {
+CallInst *
+IRBuilderBase::CreateAssumption(Value *Cond,
+ ArrayRef<OperandBundleDef> OpBundles) {
assert(Cond->getType() == getInt1Ty() &&
"an assumption condition must be of type i1");
Value *Ops[] = { Cond };
Module *M = BB->getParent()->getParent();
Function *FnAssume = Intrinsic::getDeclaration(M, Intrinsic::assume);
- return createCallHelper(FnAssume, Ops, this, "", nullptr, OpBundles);
+ return createCallHelper(FnAssume, Ops, this, "", nullptr, OpBundles);
+}
+
+Instruction *IRBuilderBase::CreateNoAliasScopeDeclaration(Value *Scope) {
+ Module *M = BB->getModule();
+ auto *FnIntrinsic = Intrinsic::getDeclaration(
+ M, Intrinsic::experimental_noalias_scope_decl, {});
+ return createCallHelper(FnIntrinsic, {Scope}, this);
}
-Instruction *IRBuilderBase::CreateNoAliasScopeDeclaration(Value *Scope) {
- Module *M = BB->getModule();
- auto *FnIntrinsic = Intrinsic::getDeclaration(
- M, Intrinsic::experimental_noalias_scope_decl, {});
- return createCallHelper(FnIntrinsic, {Scope}, this);
-}
-
/// Create a call to a Masked Load intrinsic.
/// \p Ptr - base pointer for the load
/// \p Alignment - alignment of the source location
@@ -522,8 +522,8 @@ CallInst *IRBuilderBase::CreateMaskedIntrinsic(Intrinsic::ID Id,
CallInst *IRBuilderBase::CreateMaskedGather(Value *Ptrs, Align Alignment,
Value *Mask, Value *PassThru,
const Twine &Name) {
- auto *PtrsTy = cast<FixedVectorType>(Ptrs->getType());
- auto *PtrTy = cast<PointerType>(PtrsTy->getElementType());
+ auto *PtrsTy = cast<FixedVectorType>(Ptrs->getType());
+ auto *PtrTy = cast<PointerType>(PtrsTy->getElementType());
unsigned NumElts = PtrsTy->getNumElements();
auto *DataTy = FixedVectorType::get(PtrTy->getElementType(), NumElts);
@@ -552,8 +552,8 @@ CallInst *IRBuilderBase::CreateMaskedGather(Value *Ptrs, Align Alignment,
/// be accessed in memory
CallInst *IRBuilderBase::CreateMaskedScatter(Value *Data, Value *Ptrs,
Align Alignment, Value *Mask) {
- auto *PtrsTy = cast<FixedVectorType>(Ptrs->getType());
- auto *DataTy = cast<FixedVectorType>(Data->getType());
+ auto *PtrsTy = cast<FixedVectorType>(Ptrs->getType());
+ auto *DataTy = cast<FixedVectorType>(Data->getType());
unsigned NumElts = PtrsTy->getNumElements();
#ifndef NDEBUG
@@ -585,7 +585,7 @@ getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes,
Args.push_back(ActualCallee);
Args.push_back(B.getInt32(CallArgs.size()));
Args.push_back(B.getInt32(Flags));
- llvm::append_range(Args, CallArgs);
+ llvm::append_range(Args, CallArgs);
// GC Transition and Deopt args are now always handled via operand bundle.
// They will be removed from the signature of gc.statepoint shortly.
Args.push_back(B.getInt32(0));
@@ -602,17 +602,17 @@ getStatepointBundles(Optional<ArrayRef<T1>> TransitionArgs,
std::vector<OperandBundleDef> Rval;
if (DeoptArgs) {
SmallVector<Value*, 16> DeoptValues;
- llvm::append_range(DeoptValues, *DeoptArgs);
+ llvm::append_range(DeoptValues, *DeoptArgs);
Rval.emplace_back("deopt", DeoptValues);
}
if (TransitionArgs) {
SmallVector<Value*, 16> TransitionValues;
- llvm::append_range(TransitionValues, *TransitionArgs);
+ llvm::append_range(TransitionValues, *TransitionArgs);
Rval.emplace_back("gc-transition", TransitionValues);
}
if (GCArgs.size()) {
SmallVector<Value*, 16> LiveValues;
- llvm::append_range(LiveValues, GCArgs);
+ llvm::append_range(LiveValues, GCArgs);
Rval.emplace_back("gc-live", LiveValues);
}
return Rval;
@@ -658,10 +658,10 @@ CallInst *IRBuilderBase::CreateGCStatepointCall(
CallInst *IRBuilderBase::CreateGCStatepointCall(
uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint32_t Flags,
- ArrayRef<Value *> CallArgs, Optional<ArrayRef<Use>> TransitionArgs,
+ ArrayRef<Value *> CallArgs, Optional<ArrayRef<Use>> TransitionArgs,
Optional<ArrayRef<Use>> DeoptArgs, ArrayRef<Value *> GCArgs,
const Twine &Name) {
- return CreateGCStatepointCallCommon<Value *, Use, Use, Value *>(
+ return CreateGCStatepointCallCommon<Value *, Use, Use, Value *>(
this, ID, NumPatchBytes, ActualCallee, Flags, CallArgs, TransitionArgs,
DeoptArgs, GCArgs, Name);
}
@@ -716,9 +716,9 @@ InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags,
- ArrayRef<Value *> InvokeArgs, Optional<ArrayRef<Use>> TransitionArgs,
+ ArrayRef<Value *> InvokeArgs, Optional<ArrayRef<Use>> TransitionArgs,
Optional<ArrayRef<Use>> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
- return CreateGCStatepointInvokeCommon<Value *, Use, Use, Value *>(
+ return CreateGCStatepointInvokeCommon<Value *, Use, Use, Value *>(
this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, Flags,
InvokeArgs, TransitionArgs, DeoptArgs, GCArgs, Name);
}
@@ -995,24 +995,24 @@ Value *IRBuilderBase::CreateStripInvariantGroup(Value *Ptr) {
Value *IRBuilderBase::CreateVectorSplat(unsigned NumElts, Value *V,
const Twine &Name) {
- auto EC = ElementCount::getFixed(NumElts);
- return CreateVectorSplat(EC, V, Name);
-}
-
-Value *IRBuilderBase::CreateVectorSplat(ElementCount EC, Value *V,
- const Twine &Name) {
- assert(EC.isNonZero() && "Cannot splat to an empty vector!");
-
- // First insert it into a poison vector so we can shuffle it.
+ auto EC = ElementCount::getFixed(NumElts);
+ return CreateVectorSplat(EC, V, Name);
+}
+
+Value *IRBuilderBase::CreateVectorSplat(ElementCount EC, Value *V,
+ const Twine &Name) {
+ assert(EC.isNonZero() && "Cannot splat to an empty vector!");
+
+ // First insert it into a poison vector so we can shuffle it.
Type *I32Ty = getInt32Ty();
- Value *Poison = PoisonValue::get(VectorType::get(V->getType(), EC));
- V = CreateInsertElement(Poison, V, ConstantInt::get(I32Ty, 0),
+ Value *Poison = PoisonValue::get(VectorType::get(V->getType(), EC));
+ V = CreateInsertElement(Poison, V, ConstantInt::get(I32Ty, 0),
Name + ".splatinsert");
// Shuffle the value across the desired number of elements.
- SmallVector<int, 16> Zeros;
- Zeros.resize(EC.getKnownMinValue());
- return CreateShuffleVector(V, Zeros, Name + ".splat");
+ SmallVector<int, 16> Zeros;
+ Zeros.resize(EC.getKnownMinValue());
+ return CreateShuffleVector(V, Zeros, Name + ".splat");
}
Value *IRBuilderBase::CreateExtractInteger(
@@ -1047,7 +1047,7 @@ Value *IRBuilderBase::CreatePreserveArrayAccessIndex(
Value *LastIndexV = getInt32(LastIndex);
Constant *Zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
- SmallVector<Value *, 4> IdxList(Dimension, Zero);
+ SmallVector<Value *, 4> IdxList(Dimension, Zero);
IdxList.push_back(LastIndexV);
Type *ResultType =
@@ -1110,37 +1110,37 @@ Value *IRBuilderBase::CreatePreserveStructAccessIndex(
return Fn;
}
-CallInst *IRBuilderBase::CreateAlignmentAssumptionHelper(const DataLayout &DL,
- Value *PtrValue,
- Value *AlignValue,
- Value *OffsetValue) {
- SmallVector<Value *, 4> Vals({PtrValue, AlignValue});
- if (OffsetValue)
- Vals.push_back(OffsetValue);
- OperandBundleDefT<Value *> AlignOpB("align", Vals);
- return CreateAssumption(ConstantInt::getTrue(getContext()), {AlignOpB});
+CallInst *IRBuilderBase::CreateAlignmentAssumptionHelper(const DataLayout &DL,
+ Value *PtrValue,
+ Value *AlignValue,
+ Value *OffsetValue) {
+ SmallVector<Value *, 4> Vals({PtrValue, AlignValue});
+ if (OffsetValue)
+ Vals.push_back(OffsetValue);
+ OperandBundleDefT<Value *> AlignOpB("align", Vals);
+ return CreateAssumption(ConstantInt::getTrue(getContext()), {AlignOpB});
}
-CallInst *IRBuilderBase::CreateAlignmentAssumption(const DataLayout &DL,
- Value *PtrValue,
- unsigned Alignment,
- Value *OffsetValue) {
+CallInst *IRBuilderBase::CreateAlignmentAssumption(const DataLayout &DL,
+ Value *PtrValue,
+ unsigned Alignment,
+ Value *OffsetValue) {
assert(isa<PointerType>(PtrValue->getType()) &&
"trying to create an alignment assumption on a non-pointer?");
assert(Alignment != 0 && "Invalid Alignment");
auto *PtrTy = cast<PointerType>(PtrValue->getType());
Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace());
- Value *AlignValue = ConstantInt::get(IntPtrTy, Alignment);
- return CreateAlignmentAssumptionHelper(DL, PtrValue, AlignValue, OffsetValue);
+ Value *AlignValue = ConstantInt::get(IntPtrTy, Alignment);
+ return CreateAlignmentAssumptionHelper(DL, PtrValue, AlignValue, OffsetValue);
}
-CallInst *IRBuilderBase::CreateAlignmentAssumption(const DataLayout &DL,
- Value *PtrValue,
- Value *Alignment,
- Value *OffsetValue) {
+CallInst *IRBuilderBase::CreateAlignmentAssumption(const DataLayout &DL,
+ Value *PtrValue,
+ Value *Alignment,
+ Value *OffsetValue) {
assert(isa<PointerType>(PtrValue->getType()) &&
"trying to create an alignment assumption on a non-pointer?");
- return CreateAlignmentAssumptionHelper(DL, PtrValue, Alignment, OffsetValue);
+ return CreateAlignmentAssumptionHelper(DL, PtrValue, Alignment, OffsetValue);
}
IRBuilderDefaultInserter::~IRBuilderDefaultInserter() {}
diff --git a/contrib/libs/llvm12/lib/IR/IRPrintingPasses.cpp b/contrib/libs/llvm12/lib/IR/IRPrintingPasses.cpp
index e9caec326c..8d6fe1eb61 100644
--- a/contrib/libs/llvm12/lib/IR/IRPrintingPasses.cpp
+++ b/contrib/libs/llvm12/lib/IR/IRPrintingPasses.cpp
@@ -11,15 +11,15 @@
//===----------------------------------------------------------------------===//
#include "llvm/IR/IRPrintingPasses.h"
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/PrintPasses.h"
+#include "llvm/IR/PrintPasses.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-
+
using namespace llvm;
PrintModulePass::PrintModulePass() : OS(dbgs()) {}
diff --git a/contrib/libs/llvm12/lib/IR/Instruction.cpp b/contrib/libs/llvm12/lib/IR/Instruction.cpp
index b34f097498..8e52dd3ddc 100644
--- a/contrib/libs/llvm12/lib/IR/Instruction.cpp
+++ b/contrib/libs/llvm12/lib/IR/Instruction.cpp
@@ -485,7 +485,7 @@ bool Instruction::isIdenticalToWhenDefined(const Instruction *I) const {
if (!std::equal(op_begin(), op_end(), I->op_begin()))
return false;
- // WARNING: this logic must be kept in sync with EliminateDuplicatePHINodes()!
+ // WARNING: this logic must be kept in sync with EliminateDuplicatePHINodes()!
if (const PHINode *thisPHI = dyn_cast<PHINode>(this)) {
const PHINode *otherPHI = cast<PHINode>(I);
return std::equal(thisPHI->block_begin(), thisPHI->block_end(),
@@ -633,16 +633,16 @@ bool Instruction::isSafeToRemove() const {
!this->isTerminator();
}
-bool Instruction::willReturn() const {
- if (const auto *CB = dyn_cast<CallBase>(this))
- // FIXME: Temporarily assume that all side-effect free intrinsics will
- // return. Remove this workaround once all intrinsics are appropriately
- // annotated.
- return CB->hasFnAttr(Attribute::WillReturn) ||
- (isa<IntrinsicInst>(CB) && CB->onlyReadsMemory());
- return true;
-}
-
+bool Instruction::willReturn() const {
+ if (const auto *CB = dyn_cast<CallBase>(this))
+ // FIXME: Temporarily assume that all side-effect free intrinsics will
+ // return. Remove this workaround once all intrinsics are appropriately
+ // annotated.
+ return CB->hasFnAttr(Attribute::WillReturn) ||
+ (isa<IntrinsicInst>(CB) && CB->onlyReadsMemory());
+ return true;
+}
+
bool Instruction::isLifetimeStartOrEnd() const {
auto II = dyn_cast<IntrinsicInst>(this);
if (!II)
@@ -651,22 +651,22 @@ bool Instruction::isLifetimeStartOrEnd() const {
return ID == Intrinsic::lifetime_start || ID == Intrinsic::lifetime_end;
}
-bool Instruction::isDebugOrPseudoInst() const {
- return isa<DbgInfoIntrinsic>(this) || isa<PseudoProbeInst>(this);
-}
-
-const Instruction *
-Instruction::getNextNonDebugInstruction(bool SkipPseudoOp) const {
+bool Instruction::isDebugOrPseudoInst() const {
+ return isa<DbgInfoIntrinsic>(this) || isa<PseudoProbeInst>(this);
+}
+
+const Instruction *
+Instruction::getNextNonDebugInstruction(bool SkipPseudoOp) const {
for (const Instruction *I = getNextNode(); I; I = I->getNextNode())
- if (!isa<DbgInfoIntrinsic>(I) && !(SkipPseudoOp && isa<PseudoProbeInst>(I)))
+ if (!isa<DbgInfoIntrinsic>(I) && !(SkipPseudoOp && isa<PseudoProbeInst>(I)))
return I;
return nullptr;
}
-const Instruction *
-Instruction::getPrevNonDebugInstruction(bool SkipPseudoOp) const {
+const Instruction *
+Instruction::getPrevNonDebugInstruction(bool SkipPseudoOp) const {
for (const Instruction *I = getPrevNode(); I; I = I->getPrevNode())
- if (!isa<DbgInfoIntrinsic>(I) && !(SkipPseudoOp && isa<PseudoProbeInst>(I)))
+ if (!isa<DbgInfoIntrinsic>(I) && !(SkipPseudoOp && isa<PseudoProbeInst>(I)))
return I;
return nullptr;
}
@@ -686,13 +686,13 @@ bool Instruction::isAssociative() const {
}
}
-bool Instruction::isCommutative() const {
- if (auto *II = dyn_cast<IntrinsicInst>(this))
- return II->isCommutative();
- // TODO: Should allow icmp/fcmp?
- return isCommutative(getOpcode());
-}
-
+bool Instruction::isCommutative() const {
+ if (auto *II = dyn_cast<IntrinsicInst>(this))
+ return II->isCommutative();
+ // TODO: Should allow icmp/fcmp?
+ return isCommutative(getOpcode());
+}
+
unsigned Instruction::getNumSuccessors() const {
switch (getOpcode()) {
#define HANDLE_TERM_INST(N, OPC, CLASS) \
diff --git a/contrib/libs/llvm12/lib/IR/Instructions.cpp b/contrib/libs/llvm12/lib/IR/Instructions.cpp
index 429fe390f2..36db1098a1 100644
--- a/contrib/libs/llvm12/lib/IR/Instructions.cpp
+++ b/contrib/libs/llvm12/lib/IR/Instructions.cpp
@@ -49,14 +49,14 @@ using namespace llvm;
// AllocaInst Class
//===----------------------------------------------------------------------===//
-Optional<TypeSize>
+Optional<TypeSize>
AllocaInst::getAllocationSizeInBits(const DataLayout &DL) const {
- TypeSize Size = DL.getTypeAllocSizeInBits(getAllocatedType());
+ TypeSize Size = DL.getTypeAllocSizeInBits(getAllocatedType());
if (isArrayAllocation()) {
auto *C = dyn_cast<ConstantInt>(getArraySize());
if (!C)
return None;
- assert(!Size.isScalable() && "Array elements cannot have a scalable size");
+ assert(!Size.isScalable() && "Array elements cannot have a scalable size");
Size *= C->getZExtValue();
}
return Size;
@@ -400,7 +400,7 @@ CallBase::BundleOpInfo &CallBase::getBundleOpInfoForOperand(unsigned OpIdx) {
bundle_op_iterator Begin = bundle_op_info_begin();
bundle_op_iterator End = bundle_op_info_end();
- bundle_op_iterator Current = Begin;
+ bundle_op_iterator Current = Begin;
while (Begin != End) {
unsigned ScaledOperandPerBundle =
@@ -506,18 +506,18 @@ CallInst *CallInst::Create(CallInst *CI, ArrayRef<OperandBundleDef> OpB,
return NewCI;
}
-CallInst *CallInst::CreateWithReplacedBundle(CallInst *CI, OperandBundleDef OpB,
- Instruction *InsertPt) {
- SmallVector<OperandBundleDef, 2> OpDefs;
- for (unsigned i = 0, e = CI->getNumOperandBundles(); i < e; ++i) {
- auto ChildOB = CI->getOperandBundleAt(i);
- if (ChildOB.getTagName() != OpB.getTag())
- OpDefs.emplace_back(ChildOB);
- }
- OpDefs.emplace_back(OpB);
- return CallInst::Create(CI, OpDefs, InsertPt);
-}
-
+CallInst *CallInst::CreateWithReplacedBundle(CallInst *CI, OperandBundleDef OpB,
+ Instruction *InsertPt) {
+ SmallVector<OperandBundleDef, 2> OpDefs;
+ for (unsigned i = 0, e = CI->getNumOperandBundles(); i < e; ++i) {
+ auto ChildOB = CI->getOperandBundleAt(i);
+ if (ChildOB.getTagName() != OpB.getTag())
+ OpDefs.emplace_back(ChildOB);
+ }
+ OpDefs.emplace_back(OpB);
+ return CallInst::Create(CI, OpDefs, InsertPt);
+}
+
// Update profile weight for call instruction by scaling it using the ratio
// of S/T. The meaning of "branch_weights" meta data for call instruction is
// transfered to represent call count.
@@ -551,9 +551,9 @@ void CallInst::updateProfWeight(uint64_t S, uint64_t T) {
->getValue()
.getZExtValue());
Val *= APS;
- Vals.push_back(MDB.createConstant(
- ConstantInt::get(Type::getInt32Ty(getContext()),
- Val.udiv(APT).getLimitedValue(UINT32_MAX))));
+ Vals.push_back(MDB.createConstant(
+ ConstantInt::get(Type::getInt32Ty(getContext()),
+ Val.udiv(APT).getLimitedValue(UINT32_MAX))));
} else if (ProfDataName->getString().equals("VP"))
for (unsigned i = 1; i < ProfileData->getNumOperands(); i += 2) {
// The first value is the key of the value profile, which will not change.
@@ -830,18 +830,18 @@ InvokeInst *InvokeInst::Create(InvokeInst *II, ArrayRef<OperandBundleDef> OpB,
return NewII;
}
-InvokeInst *InvokeInst::CreateWithReplacedBundle(InvokeInst *II,
- OperandBundleDef OpB,
- Instruction *InsertPt) {
- SmallVector<OperandBundleDef, 2> OpDefs;
- for (unsigned i = 0, e = II->getNumOperandBundles(); i < e; ++i) {
- auto ChildOB = II->getOperandBundleAt(i);
- if (ChildOB.getTagName() != OpB.getTag())
- OpDefs.emplace_back(ChildOB);
- }
- OpDefs.emplace_back(OpB);
- return InvokeInst::Create(II, OpDefs, InsertPt);
-}
+InvokeInst *InvokeInst::CreateWithReplacedBundle(InvokeInst *II,
+ OperandBundleDef OpB,
+ Instruction *InsertPt) {
+ SmallVector<OperandBundleDef, 2> OpDefs;
+ for (unsigned i = 0, e = II->getNumOperandBundles(); i < e; ++i) {
+ auto ChildOB = II->getOperandBundleAt(i);
+ if (ChildOB.getTagName() != OpB.getTag())
+ OpDefs.emplace_back(ChildOB);
+ }
+ OpDefs.emplace_back(OpB);
+ return InvokeInst::Create(II, OpDefs, InsertPt);
+}
LandingPadInst *InvokeInst::getLandingPadInst() const {
return cast<LandingPadInst>(getUnwindDest()->getFirstNonPHI());
@@ -1935,7 +1935,7 @@ ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, ArrayRef<int> Mask,
}
void ShuffleVectorInst::commute() {
- int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
+ int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
int NumMaskElts = ShuffleMask.size();
SmallVector<int, 16> NewMask(NumMaskElts);
for (int i = 0; i != NumMaskElts; ++i) {
@@ -1959,8 +1959,8 @@ bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2,
return false;
// Make sure the mask elements make sense.
- int V1Size =
- cast<VectorType>(V1->getType())->getElementCount().getKnownMinValue();
+ int V1Size =
+ cast<VectorType>(V1->getType())->getElementCount().getKnownMinValue();
for (int Elem : Mask)
if (Elem != UndefMaskElem && Elem >= V1Size * 2)
return false;
@@ -1990,7 +1990,7 @@ bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2,
return true;
if (const auto *MV = dyn_cast<ConstantVector>(Mask)) {
- unsigned V1Size = cast<FixedVectorType>(V1->getType())->getNumElements();
+ unsigned V1Size = cast<FixedVectorType>(V1->getType())->getNumElements();
for (Value *Op : MV->operands()) {
if (auto *CI = dyn_cast<ConstantInt>(Op)) {
if (CI->uge(V1Size*2))
@@ -2003,9 +2003,9 @@ bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2,
}
if (const auto *CDS = dyn_cast<ConstantDataSequential>(Mask)) {
- unsigned V1Size = cast<FixedVectorType>(V1->getType())->getNumElements();
- for (unsigned i = 0, e = cast<FixedVectorType>(MaskTy)->getNumElements();
- i != e; ++i)
+ unsigned V1Size = cast<FixedVectorType>(V1->getType())->getNumElements();
+ for (unsigned i = 0, e = cast<FixedVectorType>(MaskTy)->getNumElements();
+ i != e; ++i)
if (CDS->getElementAsInteger(i) >= V1Size*2)
return false;
return true;
@@ -2016,26 +2016,26 @@ bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2,
void ShuffleVectorInst::getShuffleMask(const Constant *Mask,
SmallVectorImpl<int> &Result) {
- ElementCount EC = cast<VectorType>(Mask->getType())->getElementCount();
-
+ ElementCount EC = cast<VectorType>(Mask->getType())->getElementCount();
+
if (isa<ConstantAggregateZero>(Mask)) {
- Result.resize(EC.getKnownMinValue(), 0);
+ Result.resize(EC.getKnownMinValue(), 0);
+ return;
+ }
+
+ Result.reserve(EC.getKnownMinValue());
+
+ if (EC.isScalable()) {
+ assert((isa<ConstantAggregateZero>(Mask) || isa<UndefValue>(Mask)) &&
+ "Scalable vector shuffle mask must be undef or zeroinitializer");
+ int MaskVal = isa<UndefValue>(Mask) ? -1 : 0;
+ for (unsigned I = 0; I < EC.getKnownMinValue(); ++I)
+ Result.emplace_back(MaskVal);
return;
}
-
- Result.reserve(EC.getKnownMinValue());
-
- if (EC.isScalable()) {
- assert((isa<ConstantAggregateZero>(Mask) || isa<UndefValue>(Mask)) &&
- "Scalable vector shuffle mask must be undef or zeroinitializer");
- int MaskVal = isa<UndefValue>(Mask) ? -1 : 0;
- for (unsigned I = 0; I < EC.getKnownMinValue(); ++I)
- Result.emplace_back(MaskVal);
- return;
- }
-
- unsigned NumElts = EC.getKnownMinValue();
-
+
+ unsigned NumElts = EC.getKnownMinValue();
+
if (auto *CDS = dyn_cast<ConstantDataSequential>(Mask)) {
for (unsigned i = 0; i != NumElts; ++i)
Result.push_back(CDS->getElementAsInteger(i));
@@ -2217,14 +2217,14 @@ bool ShuffleVectorInst::isExtractSubvectorMask(ArrayRef<int> Mask,
bool ShuffleVectorInst::isIdentityWithPadding() const {
if (isa<UndefValue>(Op<2>()))
return false;
-
- // FIXME: Not currently possible to express a shuffle mask for a scalable
- // vector for this case.
- if (isa<ScalableVectorType>(getType()))
- return false;
-
- int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
- int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements();
+
+ // FIXME: Not currently possible to express a shuffle mask for a scalable
+ // vector for this case.
+ if (isa<ScalableVectorType>(getType()))
+ return false;
+
+ int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
+ int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements();
if (NumMaskElts <= NumOpElts)
return false;
@@ -2246,7 +2246,7 @@ bool ShuffleVectorInst::isIdentityWithExtract() const {
return false;
// FIXME: Not currently possible to express a shuffle mask for a scalable
- // vector for this case.
+ // vector for this case.
if (isa<ScalableVectorType>(getType()))
return false;
@@ -2264,13 +2264,13 @@ bool ShuffleVectorInst::isConcat() const {
isa<UndefValue>(Op<2>()))
return false;
- // FIXME: Not currently possible to express a shuffle mask for a scalable
- // vector for this case.
- if (isa<ScalableVectorType>(getType()))
- return false;
-
- int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
- int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements();
+ // FIXME: Not currently possible to express a shuffle mask for a scalable
+ // vector for this case.
+ if (isa<ScalableVectorType>(getType()))
+ return false;
+
+ int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
+ int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements();
if (NumMaskElts != NumOpElts * 2)
return false;
@@ -2671,7 +2671,7 @@ bool CastInst::isNoopCast(Instruction::CastOps Opcode,
Type *SrcTy,
Type *DestTy,
const DataLayout &DL) {
- assert(castIsValid(Opcode, SrcTy, DestTy) && "method precondition");
+ assert(castIsValid(Opcode, SrcTy, DestTy) && "method precondition");
switch (Opcode) {
default: llvm_unreachable("Invalid CastOp");
case Instruction::Trunc:
@@ -3026,8 +3026,8 @@ CastInst *CastInst::CreatePointerCast(Value *S, Type *Ty,
"Invalid cast");
assert(Ty->isVectorTy() == S->getType()->isVectorTy() && "Invalid cast");
assert((!Ty->isVectorTy() ||
- cast<VectorType>(Ty)->getElementCount() ==
- cast<VectorType>(S->getType())->getElementCount()) &&
+ cast<VectorType>(Ty)->getElementCount() ==
+ cast<VectorType>(S->getType())->getElementCount()) &&
"Invalid cast");
if (Ty->isIntOrIntVectorTy())
@@ -3045,8 +3045,8 @@ CastInst *CastInst::CreatePointerCast(Value *S, Type *Ty,
"Invalid cast");
assert(Ty->isVectorTy() == S->getType()->isVectorTy() && "Invalid cast");
assert((!Ty->isVectorTy() ||
- cast<VectorType>(Ty)->getElementCount() ==
- cast<VectorType>(S->getType())->getElementCount()) &&
+ cast<VectorType>(Ty)->getElementCount() ==
+ cast<VectorType>(S->getType())->getElementCount()) &&
"Invalid cast");
if (Ty->isIntOrIntVectorTy())
@@ -3221,7 +3221,7 @@ CastInst::getCastOpcode(
// FIXME: Check address space sizes here
if (VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy))
if (VectorType *DestVecTy = dyn_cast<VectorType>(DestTy))
- if (SrcVecTy->getElementCount() == DestVecTy->getElementCount()) {
+ if (SrcVecTy->getElementCount() == DestVecTy->getElementCount()) {
// An element by element cast. Find the appropriate opcode based on the
// element types.
SrcTy = SrcVecTy->getElementType();
@@ -3311,7 +3311,7 @@ CastInst::getCastOpcode(
/// it in one place and to eliminate the redundant code for getting the sizes
/// of the types involved.
bool
-CastInst::castIsValid(Instruction::CastOps op, Type *SrcTy, Type *DstTy) {
+CastInst::castIsValid(Instruction::CastOps op, Type *SrcTy, Type *DstTy) {
if (!SrcTy->isFirstClassType() || !DstTy->isFirstClassType() ||
SrcTy->isAggregateType() || DstTy->isAggregateType())
return false;
@@ -3327,9 +3327,9 @@ CastInst::castIsValid(Instruction::CastOps op, Type *SrcTy, Type *DstTy) {
// scalar types means that checking that vector lengths match also checks that
// scalars are not being converted to vectors or vectors to scalars).
ElementCount SrcEC = SrcIsVec ? cast<VectorType>(SrcTy)->getElementCount()
- : ElementCount::getFixed(0);
+ : ElementCount::getFixed(0);
ElementCount DstEC = DstIsVec ? cast<VectorType>(DstTy)->getElementCount()
- : ElementCount::getFixed(0);
+ : ElementCount::getFixed(0);
// Switch on the opcode provided
switch (op) {
@@ -3387,9 +3387,9 @@ CastInst::castIsValid(Instruction::CastOps op, Type *SrcTy, Type *DstTy) {
if (SrcIsVec && DstIsVec)
return SrcEC == DstEC;
if (SrcIsVec)
- return SrcEC == ElementCount::getFixed(1);
+ return SrcEC == ElementCount::getFixed(1);
if (DstIsVec)
- return DstEC == ElementCount::getFixed(1);
+ return DstEC == ElementCount::getFixed(1);
return true;
}
@@ -3640,12 +3640,12 @@ bool CmpInst::isCommutative() const {
return cast<FCmpInst>(this)->isCommutative();
}
-bool CmpInst::isEquality(Predicate P) {
- if (ICmpInst::isIntPredicate(P))
- return ICmpInst::isEquality(P);
- if (FCmpInst::isFPPredicate(P))
- return FCmpInst::isEquality(P);
- llvm_unreachable("Unsupported predicate kind");
+bool CmpInst::isEquality(Predicate P) {
+ if (ICmpInst::isIntPredicate(P))
+ return ICmpInst::isEquality(P);
+ if (FCmpInst::isFPPredicate(P))
+ return FCmpInst::isEquality(P);
+ llvm_unreachable("Unsupported predicate kind");
}
CmpInst::Predicate CmpInst::getInversePredicate(Predicate pred) {
@@ -3769,97 +3769,97 @@ CmpInst::Predicate CmpInst::getSwappedPredicate(Predicate pred) {
}
}
-bool CmpInst::isNonStrictPredicate(Predicate pred) {
- switch (pred) {
- case ICMP_SGE:
- case ICMP_SLE:
- case ICMP_UGE:
- case ICMP_ULE:
- case FCMP_OGE:
- case FCMP_OLE:
- case FCMP_UGE:
- case FCMP_ULE:
- return true;
- default:
- return false;
- }
-}
-
-bool CmpInst::isStrictPredicate(Predicate pred) {
- switch (pred) {
- case ICMP_SGT:
- case ICMP_SLT:
- case ICMP_UGT:
- case ICMP_ULT:
- case FCMP_OGT:
- case FCMP_OLT:
- case FCMP_UGT:
- case FCMP_ULT:
- return true;
- default:
- return false;
- }
-}
-
-CmpInst::Predicate CmpInst::getStrictPredicate(Predicate pred) {
- switch (pred) {
- case ICMP_SGE:
- return ICMP_SGT;
- case ICMP_SLE:
- return ICMP_SLT;
- case ICMP_UGE:
- return ICMP_UGT;
- case ICMP_ULE:
- return ICMP_ULT;
- case FCMP_OGE:
- return FCMP_OGT;
- case FCMP_OLE:
- return FCMP_OLT;
- case FCMP_UGE:
- return FCMP_UGT;
- case FCMP_ULE:
- return FCMP_ULT;
- default:
- return pred;
- }
-}
-
+bool CmpInst::isNonStrictPredicate(Predicate pred) {
+ switch (pred) {
+ case ICMP_SGE:
+ case ICMP_SLE:
+ case ICMP_UGE:
+ case ICMP_ULE:
+ case FCMP_OGE:
+ case FCMP_OLE:
+ case FCMP_UGE:
+ case FCMP_ULE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool CmpInst::isStrictPredicate(Predicate pred) {
+ switch (pred) {
+ case ICMP_SGT:
+ case ICMP_SLT:
+ case ICMP_UGT:
+ case ICMP_ULT:
+ case FCMP_OGT:
+ case FCMP_OLT:
+ case FCMP_UGT:
+ case FCMP_ULT:
+ return true;
+ default:
+ return false;
+ }
+}
+
+CmpInst::Predicate CmpInst::getStrictPredicate(Predicate pred) {
+ switch (pred) {
+ case ICMP_SGE:
+ return ICMP_SGT;
+ case ICMP_SLE:
+ return ICMP_SLT;
+ case ICMP_UGE:
+ return ICMP_UGT;
+ case ICMP_ULE:
+ return ICMP_ULT;
+ case FCMP_OGE:
+ return FCMP_OGT;
+ case FCMP_OLE:
+ return FCMP_OLT;
+ case FCMP_UGE:
+ return FCMP_UGT;
+ case FCMP_ULE:
+ return FCMP_ULT;
+ default:
+ return pred;
+ }
+}
+
CmpInst::Predicate CmpInst::getNonStrictPredicate(Predicate pred) {
switch (pred) {
- case ICMP_SGT:
- return ICMP_SGE;
- case ICMP_SLT:
- return ICMP_SLE;
- case ICMP_UGT:
- return ICMP_UGE;
- case ICMP_ULT:
- return ICMP_ULE;
- case FCMP_OGT:
- return FCMP_OGE;
- case FCMP_OLT:
- return FCMP_OLE;
- case FCMP_UGT:
- return FCMP_UGE;
- case FCMP_ULT:
- return FCMP_ULE;
- default:
- return pred;
+ case ICMP_SGT:
+ return ICMP_SGE;
+ case ICMP_SLT:
+ return ICMP_SLE;
+ case ICMP_UGT:
+ return ICMP_UGE;
+ case ICMP_ULT:
+ return ICMP_ULE;
+ case FCMP_OGT:
+ return FCMP_OGE;
+ case FCMP_OLT:
+ return FCMP_OLE;
+ case FCMP_UGT:
+ return FCMP_UGE;
+ case FCMP_ULT:
+ return FCMP_ULE;
+ default:
+ return pred;
}
}
-CmpInst::Predicate CmpInst::getFlippedStrictnessPredicate(Predicate pred) {
- assert(CmpInst::isRelational(pred) && "Call only with relational predicate!");
-
- if (isStrictPredicate(pred))
- return getNonStrictPredicate(pred);
- if (isNonStrictPredicate(pred))
- return getStrictPredicate(pred);
-
- llvm_unreachable("Unknown predicate!");
-}
-
+CmpInst::Predicate CmpInst::getFlippedStrictnessPredicate(Predicate pred) {
+ assert(CmpInst::isRelational(pred) && "Call only with relational predicate!");
+
+ if (isStrictPredicate(pred))
+ return getNonStrictPredicate(pred);
+ if (isNonStrictPredicate(pred))
+ return getStrictPredicate(pred);
+
+ llvm_unreachable("Unknown predicate!");
+}
+
CmpInst::Predicate CmpInst::getSignedPredicate(Predicate pred) {
- assert(CmpInst::isUnsigned(pred) && "Call only with unsigned predicates!");
+ assert(CmpInst::isUnsigned(pred) && "Call only with unsigned predicates!");
switch (pred) {
default:
@@ -3875,23 +3875,23 @@ CmpInst::Predicate CmpInst::getSignedPredicate(Predicate pred) {
}
}
-CmpInst::Predicate CmpInst::getUnsignedPredicate(Predicate pred) {
- assert(CmpInst::isSigned(pred) && "Call only with signed predicates!");
-
- switch (pred) {
- default:
- llvm_unreachable("Unknown predicate!");
- case CmpInst::ICMP_SLT:
- return CmpInst::ICMP_ULT;
- case CmpInst::ICMP_SLE:
- return CmpInst::ICMP_ULE;
- case CmpInst::ICMP_SGT:
- return CmpInst::ICMP_UGT;
- case CmpInst::ICMP_SGE:
- return CmpInst::ICMP_UGE;
- }
-}
-
+CmpInst::Predicate CmpInst::getUnsignedPredicate(Predicate pred) {
+ assert(CmpInst::isSigned(pred) && "Call only with signed predicates!");
+
+ switch (pred) {
+ default:
+ llvm_unreachable("Unknown predicate!");
+ case CmpInst::ICMP_SLT:
+ return CmpInst::ICMP_ULT;
+ case CmpInst::ICMP_SLE:
+ return CmpInst::ICMP_ULE;
+ case CmpInst::ICMP_SGT:
+ return CmpInst::ICMP_UGT;
+ case CmpInst::ICMP_SGE:
+ return CmpInst::ICMP_UGE;
+ }
+}
+
bool CmpInst::isUnsigned(Predicate predicate) {
switch (predicate) {
default: return false;
@@ -3908,18 +3908,18 @@ bool CmpInst::isSigned(Predicate predicate) {
}
}
-CmpInst::Predicate CmpInst::getFlippedSignednessPredicate(Predicate pred) {
- assert(CmpInst::isRelational(pred) &&
- "Call only with non-equality predicates!");
-
- if (isSigned(pred))
- return getUnsignedPredicate(pred);
- if (isUnsigned(pred))
- return getSignedPredicate(pred);
-
- llvm_unreachable("Unknown predicate!");
-}
-
+CmpInst::Predicate CmpInst::getFlippedSignednessPredicate(Predicate pred) {
+ assert(CmpInst::isRelational(pred) &&
+ "Call only with non-equality predicates!");
+
+ if (isSigned(pred))
+ return getUnsignedPredicate(pred);
+ if (isUnsigned(pred))
+ return getSignedPredicate(pred);
+
+ llvm_unreachable("Unknown predicate!");
+}
+
bool CmpInst::isOrdered(Predicate predicate) {
switch (predicate) {
default: return false;
diff --git a/contrib/libs/llvm12/lib/IR/IntrinsicInst.cpp b/contrib/libs/llvm12/lib/IR/IntrinsicInst.cpp
index 7b35a7b6d8..3d1ea28535 100644
--- a/contrib/libs/llvm12/lib/IR/IntrinsicInst.cpp
+++ b/contrib/libs/llvm12/lib/IR/IntrinsicInst.cpp
@@ -208,7 +208,7 @@ Optional<int> VPIntrinsic::GetMaskParamPos(Intrinsic::ID IntrinsicID) {
default:
return None;
-#define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \
+#define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \
case Intrinsic::VPID: \
return MASKPOS;
#include "llvm/IR/VPIntrinsics.def"
@@ -220,7 +220,7 @@ Optional<int> VPIntrinsic::GetVectorLengthParamPos(Intrinsic::ID IntrinsicID) {
default:
return None;
-#define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \
+#define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \
case Intrinsic::VPID: \
return VLENPOS;
#include "llvm/IR/VPIntrinsics.def"
@@ -232,7 +232,7 @@ bool VPIntrinsic::IsVPIntrinsic(Intrinsic::ID ID) {
default:
return false;
-#define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \
+#define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \
case Intrinsic::VPID: \
break;
#include "llvm/IR/VPIntrinsics.def"
@@ -242,26 +242,26 @@ bool VPIntrinsic::IsVPIntrinsic(Intrinsic::ID ID) {
// Equivalent non-predicated opcode
unsigned VPIntrinsic::GetFunctionalOpcodeForVP(Intrinsic::ID ID) {
- unsigned FunctionalOC = Instruction::Call;
+ unsigned FunctionalOC = Instruction::Call;
switch (ID) {
default:
- break;
-#define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID:
-#define HANDLE_VP_TO_OPC(OPC) FunctionalOC = Instruction::OPC;
-#define END_REGISTER_VP_INTRINSIC(...) break;
+ break;
+#define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID:
+#define HANDLE_VP_TO_OPC(OPC) FunctionalOC = Instruction::OPC;
+#define END_REGISTER_VP_INTRINSIC(...) break;
#include "llvm/IR/VPIntrinsics.def"
}
-
- return FunctionalOC;
+
+ return FunctionalOC;
}
-Intrinsic::ID VPIntrinsic::GetForOpcode(unsigned IROPC) {
- switch (IROPC) {
+Intrinsic::ID VPIntrinsic::GetForOpcode(unsigned IROPC) {
+ switch (IROPC) {
default:
return Intrinsic::not_intrinsic;
-#define HANDLE_VP_TO_OPC(OPC) case Instruction::OPC:
-#define END_REGISTER_VP_INTRINSIC(VPID) return Intrinsic::VPID;
+#define HANDLE_VP_TO_OPC(OPC) case Instruction::OPC:
+#define END_REGISTER_VP_INTRINSIC(VPID) return Intrinsic::VPID;
#include "llvm/IR/VPIntrinsics.def"
}
}
@@ -281,8 +281,8 @@ bool VPIntrinsic::canIgnoreVectorLengthParam() const {
// the operation. This function returns true when this is detected statically
// in the IR.
- // Check whether "W == vscale * EC.getKnownMinValue()"
- if (EC.isScalable()) {
+ // Check whether "W == vscale * EC.getKnownMinValue()"
+ if (EC.isScalable()) {
// Undig the DL
auto ParMod = this->getModule();
if (!ParMod)
@@ -292,8 +292,8 @@ bool VPIntrinsic::canIgnoreVectorLengthParam() const {
// Compare vscale patterns
uint64_t VScaleFactor;
if (match(VLParam, m_c_Mul(m_ConstantInt(VScaleFactor), m_VScale(DL))))
- return VScaleFactor >= EC.getKnownMinValue();
- return (EC.getKnownMinValue() == 1) && match(VLParam, m_VScale(DL));
+ return VScaleFactor >= EC.getKnownMinValue();
+ return (EC.getKnownMinValue() == 1) && match(VLParam, m_VScale(DL));
}
// standard SIMD operation
@@ -302,7 +302,7 @@ bool VPIntrinsic::canIgnoreVectorLengthParam() const {
return false;
uint64_t VLNum = VLConst->getZExtValue();
- if (VLNum >= EC.getKnownMinValue())
+ if (VLNum >= EC.getKnownMinValue())
return true;
return false;
diff --git a/contrib/libs/llvm12/lib/IR/LLVMContext.cpp b/contrib/libs/llvm12/lib/IR/LLVMContext.cpp
index 2637420dae..4f29210125 100644
--- a/contrib/libs/llvm12/lib/IR/LLVMContext.cpp
+++ b/contrib/libs/llvm12/lib/IR/LLVMContext.cpp
@@ -146,18 +146,18 @@ bool LLVMContext::getDiagnosticsHotnessRequested() const {
return pImpl->DiagnosticsHotnessRequested;
}
-void LLVMContext::setDiagnosticsHotnessThreshold(Optional<uint64_t> Threshold) {
+void LLVMContext::setDiagnosticsHotnessThreshold(Optional<uint64_t> Threshold) {
pImpl->DiagnosticsHotnessThreshold = Threshold;
}
-
+
uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const {
- return pImpl->DiagnosticsHotnessThreshold.getValueOr(UINT64_MAX);
+ return pImpl->DiagnosticsHotnessThreshold.getValueOr(UINT64_MAX);
+}
+
+bool LLVMContext::isDiagnosticsHotnessThresholdSetFromPSI() const {
+ return !pImpl->DiagnosticsHotnessThreshold.hasValue();
}
-bool LLVMContext::isDiagnosticsHotnessThresholdSetFromPSI() const {
- return !pImpl->DiagnosticsHotnessThreshold.hasValue();
-}
-
remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() {
return pImpl->MainRemarkStreamer.get();
}
diff --git a/contrib/libs/llvm12/lib/IR/LLVMContextImpl.cpp b/contrib/libs/llvm12/lib/IR/LLVMContextImpl.cpp
index 0e7e3d6b31..e998138ec3 100644
--- a/contrib/libs/llvm12/lib/IR/LLVMContextImpl.cpp
+++ b/contrib/libs/llvm12/lib/IR/LLVMContextImpl.cpp
@@ -35,7 +35,7 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
FP128Ty(C, Type::FP128TyID),
PPC_FP128Ty(C, Type::PPC_FP128TyID),
X86_MMXTy(C, Type::X86_MMXTyID),
- X86_AMXTy(C, Type::X86_AMXTyID),
+ X86_AMXTy(C, Type::X86_AMXTyID),
Int1Ty(C, 1),
Int8Ty(C, 8),
Int16Ty(C, 16),
@@ -51,10 +51,10 @@ LLVMContextImpl::~LLVMContextImpl() {
delete *OwnedModules.begin();
#ifndef NDEBUG
- // Check for metadata references from leaked Values.
- for (auto &Pair : ValueMetadata)
+ // Check for metadata references from leaked Values.
+ for (auto &Pair : ValueMetadata)
Pair.first->dump();
- assert(ValueMetadata.empty() && "Values with metadata have been leaked");
+ assert(ValueMetadata.empty() && "Values with metadata have been leaked");
#endif
// Drop references for MDNodes. Do this before Values get deleted to avoid
@@ -98,7 +98,7 @@ LLVMContextImpl::~LLVMContextImpl() {
CAZConstants.clear();
CPNConstants.clear();
UVConstants.clear();
- PVConstants.clear();
+ PVConstants.clear();
IntConstants.clear();
FPConstants.clear();
CDSConstants.clear();
@@ -127,16 +127,16 @@ LLVMContextImpl::~LLVMContextImpl() {
}
void LLVMContextImpl::dropTriviallyDeadConstantArrays() {
- SmallSetVector<ConstantArray *, 4> WorkList;
-
- // When ArrayConstants are of substantial size and only a few in them are
- // dead, starting WorkList with all elements of ArrayConstants can be
- // wasteful. Instead, starting WorkList with only elements that have empty
- // uses.
- for (ConstantArray *C : ArrayConstants)
- if (C->use_empty())
- WorkList.insert(C);
-
+ SmallSetVector<ConstantArray *, 4> WorkList;
+
+ // When ArrayConstants are of substantial size and only a few in them are
+ // dead, starting WorkList with all elements of ArrayConstants can be
+ // wasteful. Instead, starting WorkList with only elements that have empty
+ // uses.
+ for (ConstantArray *C : ArrayConstants)
+ if (C->use_empty())
+ WorkList.insert(C);
+
while (!WorkList.empty()) {
ConstantArray *C = WorkList.pop_back_val();
if (C->use_empty()) {
@@ -176,7 +176,7 @@ unsigned MDNodeOpsKey::calculateHash(MDNode *N, unsigned Offset) {
unsigned Hash = hash_combine_range(N->op_begin() + Offset, N->op_end());
#ifndef NDEBUG
{
- SmallVector<Metadata *, 8> MDs(drop_begin(N->operands(), Offset));
+ SmallVector<Metadata *, 8> MDs(drop_begin(N->operands(), Offset));
unsigned RawHash = calculateHash(MDs);
assert(Hash == RawHash &&
"Expected hash of MDOperand to equal hash of Metadata*");
@@ -220,8 +220,8 @@ void LLVMContextImpl::getSyncScopeNames(
SSNs[SSE.second] = SSE.first();
}
-/// Gets the OptPassGate for this LLVMContextImpl, which defaults to the
-/// singleton OptBisect if not explicitly set.
+/// Gets the OptPassGate for this LLVMContextImpl, which defaults to the
+/// singleton OptBisect if not explicitly set.
OptPassGate &LLVMContextImpl::getOptPassGate() const {
if (!OPG)
OPG = &(*OptBisector);
diff --git a/contrib/libs/llvm12/lib/IR/LLVMContextImpl.h b/contrib/libs/llvm12/lib/IR/LLVMContextImpl.h
index f466baf587..05fd1814e2 100644
--- a/contrib/libs/llvm12/lib/IR/LLVMContextImpl.h
+++ b/contrib/libs/llvm12/lib/IR/LLVMContextImpl.h
@@ -57,7 +57,7 @@ class Type;
class Value;
class ValueHandleBase;
-using DenseMapAPIntKeyInfo = DenseMapInfo<APInt>;
+using DenseMapAPIntKeyInfo = DenseMapInfo<APInt>;
struct DenseMapAPFloatKeyInfo {
static inline APFloat getEmptyKey() { return APFloat(APFloat::Bogus(), 1); }
@@ -346,36 +346,36 @@ template <> struct MDNodeKeyImpl<DISubrange> {
}
};
-template <> struct MDNodeKeyImpl<DIGenericSubrange> {
- Metadata *CountNode;
- Metadata *LowerBound;
- Metadata *UpperBound;
- Metadata *Stride;
-
- MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound,
- Metadata *Stride)
- : CountNode(CountNode), LowerBound(LowerBound), UpperBound(UpperBound),
- Stride(Stride) {}
- MDNodeKeyImpl(const DIGenericSubrange *N)
- : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
- UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
-
- bool isKeyOf(const DIGenericSubrange *RHS) const {
- return (CountNode == RHS->getRawCountNode()) &&
- (LowerBound == RHS->getRawLowerBound()) &&
- (UpperBound == RHS->getRawUpperBound()) &&
- (Stride == RHS->getRawStride());
- }
-
- unsigned getHashValue() const {
- auto *MD = dyn_cast_or_null<ConstantAsMetadata>(CountNode);
- if (CountNode && MD)
- return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
- LowerBound, UpperBound, Stride);
- return hash_combine(CountNode, LowerBound, UpperBound, Stride);
- }
-};
-
+template <> struct MDNodeKeyImpl<DIGenericSubrange> {
+ Metadata *CountNode;
+ Metadata *LowerBound;
+ Metadata *UpperBound;
+ Metadata *Stride;
+
+ MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound,
+ Metadata *Stride)
+ : CountNode(CountNode), LowerBound(LowerBound), UpperBound(UpperBound),
+ Stride(Stride) {}
+ MDNodeKeyImpl(const DIGenericSubrange *N)
+ : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
+ UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
+
+ bool isKeyOf(const DIGenericSubrange *RHS) const {
+ return (CountNode == RHS->getRawCountNode()) &&
+ (LowerBound == RHS->getRawLowerBound()) &&
+ (UpperBound == RHS->getRawUpperBound()) &&
+ (Stride == RHS->getRawStride());
+ }
+
+ unsigned getHashValue() const {
+ auto *MD = dyn_cast_or_null<ConstantAsMetadata>(CountNode);
+ if (CountNode && MD)
+ return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
+ LowerBound, UpperBound, Stride);
+ return hash_combine(CountNode, LowerBound, UpperBound, Stride);
+ }
+};
+
template <> struct MDNodeKeyImpl<DIEnumerator> {
APInt Value;
MDString *Name;
@@ -427,37 +427,37 @@ template <> struct MDNodeKeyImpl<DIBasicType> {
}
};
-template <> struct MDNodeKeyImpl<DIStringType> {
- unsigned Tag;
- MDString *Name;
- Metadata *StringLength;
- Metadata *StringLengthExp;
- uint64_t SizeInBits;
- uint32_t AlignInBits;
- unsigned Encoding;
-
- MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *StringLength,
- Metadata *StringLengthExp, uint64_t SizeInBits,
- uint32_t AlignInBits, unsigned Encoding)
- : Tag(Tag), Name(Name), StringLength(StringLength),
- StringLengthExp(StringLengthExp), SizeInBits(SizeInBits),
- AlignInBits(AlignInBits), Encoding(Encoding) {}
- MDNodeKeyImpl(const DIStringType *N)
- : Tag(N->getTag()), Name(N->getRawName()),
- StringLength(N->getRawStringLength()),
- StringLengthExp(N->getRawStringLengthExp()),
- SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()),
- Encoding(N->getEncoding()) {}
-
- bool isKeyOf(const DIStringType *RHS) const {
- return Tag == RHS->getTag() && Name == RHS->getRawName() &&
- SizeInBits == RHS->getSizeInBits() &&
- AlignInBits == RHS->getAlignInBits() &&
- Encoding == RHS->getEncoding();
- }
- unsigned getHashValue() const { return hash_combine(Tag, Name, Encoding); }
-};
-
+template <> struct MDNodeKeyImpl<DIStringType> {
+ unsigned Tag;
+ MDString *Name;
+ Metadata *StringLength;
+ Metadata *StringLengthExp;
+ uint64_t SizeInBits;
+ uint32_t AlignInBits;
+ unsigned Encoding;
+
+ MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *StringLength,
+ Metadata *StringLengthExp, uint64_t SizeInBits,
+ uint32_t AlignInBits, unsigned Encoding)
+ : Tag(Tag), Name(Name), StringLength(StringLength),
+ StringLengthExp(StringLengthExp), SizeInBits(SizeInBits),
+ AlignInBits(AlignInBits), Encoding(Encoding) {}
+ MDNodeKeyImpl(const DIStringType *N)
+ : Tag(N->getTag()), Name(N->getRawName()),
+ StringLength(N->getRawStringLength()),
+ StringLengthExp(N->getRawStringLengthExp()),
+ SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()),
+ Encoding(N->getEncoding()) {}
+
+ bool isKeyOf(const DIStringType *RHS) const {
+ return Tag == RHS->getTag() && Name == RHS->getRawName() &&
+ SizeInBits == RHS->getSizeInBits() &&
+ AlignInBits == RHS->getAlignInBits() &&
+ Encoding == RHS->getEncoding();
+ }
+ unsigned getHashValue() const { return hash_combine(Tag, Name, Encoding); }
+};
+
template <> struct MDNodeKeyImpl<DIDerivedType> {
unsigned Tag;
MDString *Name;
@@ -566,9 +566,9 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
MDString *Identifier;
Metadata *Discriminator;
Metadata *DataLocation;
- Metadata *Associated;
- Metadata *Allocated;
- Metadata *Rank;
+ Metadata *Associated;
+ Metadata *Allocated;
+ Metadata *Rank;
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
@@ -576,15 +576,15 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
Metadata *Elements, unsigned RuntimeLang,
Metadata *VTableHolder, Metadata *TemplateParams,
MDString *Identifier, Metadata *Discriminator,
- Metadata *DataLocation, Metadata *Associated,
- Metadata *Allocated, Metadata *Rank)
+ Metadata *DataLocation, Metadata *Associated,
+ Metadata *Allocated, Metadata *Rank)
: Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
AlignInBits(AlignInBits), Flags(Flags), Elements(Elements),
RuntimeLang(RuntimeLang), VTableHolder(VTableHolder),
TemplateParams(TemplateParams), Identifier(Identifier),
- Discriminator(Discriminator), DataLocation(DataLocation),
- Associated(Associated), Allocated(Allocated), Rank(Rank) {}
+ Discriminator(Discriminator), DataLocation(DataLocation),
+ Associated(Associated), Allocated(Allocated), Rank(Rank) {}
MDNodeKeyImpl(const DICompositeType *N)
: Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
Line(N->getLine()), Scope(N->getRawScope()),
@@ -595,9 +595,9 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
TemplateParams(N->getRawTemplateParams()),
Identifier(N->getRawIdentifier()),
Discriminator(N->getRawDiscriminator()),
- DataLocation(N->getRawDataLocation()),
- Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()),
- Rank(N->getRawRank()) {}
+ DataLocation(N->getRawDataLocation()),
+ Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()),
+ Rank(N->getRawRank()) {}
bool isKeyOf(const DICompositeType *RHS) const {
return Tag == RHS->getTag() && Name == RHS->getRawName() &&
@@ -612,9 +612,9 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
TemplateParams == RHS->getRawTemplateParams() &&
Identifier == RHS->getRawIdentifier() &&
Discriminator == RHS->getRawDiscriminator() &&
- DataLocation == RHS->getRawDataLocation() &&
- Associated == RHS->getRawAssociated() &&
- Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank();
+ DataLocation == RHS->getRawDataLocation() &&
+ Associated == RHS->getRawAssociated() &&
+ Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank();
}
unsigned getHashValue() const {
@@ -891,28 +891,28 @@ template <> struct MDNodeKeyImpl<DIModule> {
MDString *IncludePath;
MDString *APINotesFile;
unsigned LineNo;
- bool IsDecl;
+ bool IsDecl;
MDNodeKeyImpl(Metadata *File, Metadata *Scope, MDString *Name,
MDString *ConfigurationMacros, MDString *IncludePath,
- MDString *APINotesFile, unsigned LineNo, bool IsDecl)
+ MDString *APINotesFile, unsigned LineNo, bool IsDecl)
: File(File), Scope(Scope), Name(Name),
ConfigurationMacros(ConfigurationMacros), IncludePath(IncludePath),
- APINotesFile(APINotesFile), LineNo(LineNo), IsDecl(IsDecl) {}
+ APINotesFile(APINotesFile), LineNo(LineNo), IsDecl(IsDecl) {}
MDNodeKeyImpl(const DIModule *N)
: File(N->getRawFile()), Scope(N->getRawScope()), Name(N->getRawName()),
ConfigurationMacros(N->getRawConfigurationMacros()),
IncludePath(N->getRawIncludePath()),
- APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()),
- IsDecl(N->getIsDecl()) {}
+ APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()),
+ IsDecl(N->getIsDecl()) {}
bool isKeyOf(const DIModule *RHS) const {
return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
ConfigurationMacros == RHS->getRawConfigurationMacros() &&
IncludePath == RHS->getRawIncludePath() &&
APINotesFile == RHS->getRawAPINotesFile() &&
- File == RHS->getRawFile() && LineNo == RHS->getLineNo() &&
- IsDecl == RHS->getIsDecl();
+ File == RHS->getRawFile() && LineNo == RHS->getLineNo() &&
+ IsDecl == RHS->getIsDecl();
}
unsigned getHashValue() const {
@@ -1257,54 +1257,54 @@ template <class NodeTy> struct MDNodeInfo {
#define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>;
#include "llvm/IR/Metadata.def"
-/// Multimap-like storage for metadata attachments.
-class MDAttachments {
-public:
- struct Attachment {
- unsigned MDKind;
- TrackingMDNodeRef Node;
- };
-
-private:
- SmallVector<Attachment, 1> Attachments;
-
+/// Multimap-like storage for metadata attachments.
+class MDAttachments {
+public:
+ struct Attachment {
+ unsigned MDKind;
+ TrackingMDNodeRef Node;
+ };
+
+private:
+ SmallVector<Attachment, 1> Attachments;
+
public:
bool empty() const { return Attachments.empty(); }
size_t size() const { return Attachments.size(); }
- /// Returns the first attachment with the given ID or nullptr if no such
- /// attachment exists.
+ /// Returns the first attachment with the given ID or nullptr if no such
+ /// attachment exists.
MDNode *lookup(unsigned ID) const;
- /// Appends all attachments with the given ID to \c Result in insertion order.
- /// If the global has no attachments with the given ID, or if ID is invalid,
- /// leaves Result unchanged.
- void get(unsigned ID, SmallVectorImpl<MDNode *> &Result) const;
-
- /// Appends all attachments for the global to \c Result, sorting by attachment
- /// ID. Attachments with the same ID appear in insertion order. This function
- /// does \em not clear \c Result.
- void getAll(SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const;
-
+ /// Appends all attachments with the given ID to \c Result in insertion order.
+ /// If the global has no attachments with the given ID, or if ID is invalid,
+ /// leaves Result unchanged.
+ void get(unsigned ID, SmallVectorImpl<MDNode *> &Result) const;
+
+ /// Appends all attachments for the global to \c Result, sorting by attachment
+ /// ID. Attachments with the same ID appear in insertion order. This function
+ /// does \em not clear \c Result.
+ void getAll(SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const;
+
/// Set an attachment to a particular node.
///
- /// Set the \c ID attachment to \c MD, replacing the current attachments at \c
+ /// Set the \c ID attachment to \c MD, replacing the current attachments at \c
/// ID (if anyway).
- void set(unsigned ID, MDNode *MD);
+ void set(unsigned ID, MDNode *MD);
- /// Adds an attachment to a particular node.
- void insert(unsigned ID, MDNode &MD);
-
- /// Remove attachments with the given ID.
+ /// Adds an attachment to a particular node.
+ void insert(unsigned ID, MDNode &MD);
+
+ /// Remove attachments with the given ID.
///
- /// Remove the attachments at \c ID, if any.
+ /// Remove the attachments at \c ID, if any.
bool erase(unsigned ID);
/// Erase matching attachments.
///
/// Erases all attachments matching the \c shouldRemove predicate.
template <class PredTy> void remove_if(PredTy shouldRemove) {
- llvm::erase_if(Attachments, shouldRemove);
+ llvm::erase_if(Attachments, shouldRemove);
}
};
@@ -1325,26 +1325,26 @@ public:
std::unique_ptr<DiagnosticHandler> DiagHandler;
bool RespectDiagnosticFilters = false;
bool DiagnosticsHotnessRequested = false;
- /// The minimum hotness value a diagnostic needs in order to be included in
- /// optimization diagnostics.
- ///
- /// The threshold is an Optional value, which maps to one of the 3 states:
- /// 1). 0 => threshold disabled. All emarks will be printed.
- /// 2). positive int => manual threshold by user. Remarks with hotness exceed
- /// threshold will be printed.
- /// 3). None => 'auto' threshold by user. The actual value is not
- /// available at command line, but will be synced with
- /// hotness threhold from profile summary during
- /// compilation.
- ///
- /// State 1 and 2 are considered as terminal states. State transition is
- /// only allowed from 3 to 2, when the threshold is first synced with profile
- /// summary. This ensures that the threshold is set only once and stays
- /// constant.
- ///
- /// If threshold option is not specified, it is disabled (0) by default.
- Optional<uint64_t> DiagnosticsHotnessThreshold = 0;
-
+ /// The minimum hotness value a diagnostic needs in order to be included in
+ /// optimization diagnostics.
+ ///
+ /// The threshold is an Optional value, which maps to one of the 3 states:
+ /// 1). 0 => threshold disabled. All emarks will be printed.
+ /// 2). positive int => manual threshold by user. Remarks with hotness exceed
+ /// threshold will be printed.
+ /// 3). None => 'auto' threshold by user. The actual value is not
+ /// available at command line, but will be synced with
+ /// hotness threhold from profile summary during
+ /// compilation.
+ ///
+ /// State 1 and 2 are considered as terminal states. State transition is
+ /// only allowed from 3 to 2, when the threshold is first synced with profile
+ /// summary. This ensures that the threshold is set only once and stays
+ /// constant.
+ ///
+ /// If threshold option is not specified, it is disabled (0) by default.
+ Optional<uint64_t> DiagnosticsHotnessThreshold = 0;
+
/// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
@@ -1397,15 +1397,15 @@ public:
DenseMap<Type *, std::unique_ptr<UndefValue>> UVConstants;
- DenseMap<Type *, std::unique_ptr<PoisonValue>> PVConstants;
+ DenseMap<Type *, std::unique_ptr<PoisonValue>> PVConstants;
+
+ StringMap<std::unique_ptr<ConstantDataSequential>> CDSConstants;
- StringMap<std::unique_ptr<ConstantDataSequential>> CDSConstants;
-
DenseMap<std::pair<const Function *, const BasicBlock *>, BlockAddress *>
BlockAddresses;
-
- DenseMap<const GlobalValue *, DSOLocalEquivalent *> DSOLocalEquivalents;
-
+
+ DenseMap<const GlobalValue *, DSOLocalEquivalent *> DSOLocalEquivalents;
+
ConstantUniqueMap<ConstantExpr> ExprConstants;
ConstantUniqueMap<InlineAsm> InlineAsms;
@@ -1418,7 +1418,7 @@ public:
// Basic type instances.
Type VoidTy, LabelTy, HalfTy, BFloatTy, FloatTy, DoubleTy, MetadataTy,
TokenTy;
- Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy, X86_AMXTy;
+ Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy, X86_AMXTy;
IntegerType Int1Ty, Int8Ty, Int16Ty, Int32Ty, Int64Ty, Int128Ty;
BumpPtrAllocator Alloc;
@@ -1447,8 +1447,8 @@ public:
/// CustomMDKindNames - Map to hold the metadata string to ID mapping.
StringMap<unsigned> CustomMDKindNames;
- /// Collection of metadata used in this context.
- DenseMap<const Value *, MDAttachments> ValueMetadata;
+ /// Collection of metadata used in this context.
+ DenseMap<const Value *, MDAttachments> ValueMetadata;
/// Collection of per-GlobalObject sections used in this context.
DenseMap<const GlobalObject *, StringRef> GlobalObjectSections;
diff --git a/contrib/libs/llvm12/lib/IR/LLVMRemarkStreamer.cpp b/contrib/libs/llvm12/lib/IR/LLVMRemarkStreamer.cpp
index ae65ecdf48..18b47611c9 100644
--- a/contrib/libs/llvm12/lib/IR/LLVMRemarkStreamer.cpp
+++ b/contrib/libs/llvm12/lib/IR/LLVMRemarkStreamer.cpp
@@ -92,11 +92,11 @@ char LLVMRemarkSetupFormatError::ID = 0;
Expected<std::unique_ptr<ToolOutputFile>> llvm::setupLLVMOptimizationRemarks(
LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses,
StringRef RemarksFormat, bool RemarksWithHotness,
- Optional<uint64_t> RemarksHotnessThreshold) {
+ Optional<uint64_t> RemarksHotnessThreshold) {
if (RemarksWithHotness)
Context.setDiagnosticsHotnessRequested(true);
- Context.setDiagnosticsHotnessThreshold(RemarksHotnessThreshold);
+ Context.setDiagnosticsHotnessThreshold(RemarksHotnessThreshold);
if (RemarksFilename.empty())
return nullptr;
@@ -136,14 +136,14 @@ Expected<std::unique_ptr<ToolOutputFile>> llvm::setupLLVMOptimizationRemarks(
return std::move(RemarksFile);
}
-Error llvm::setupLLVMOptimizationRemarks(
- LLVMContext &Context, raw_ostream &OS, StringRef RemarksPasses,
- StringRef RemarksFormat, bool RemarksWithHotness,
- Optional<uint64_t> RemarksHotnessThreshold) {
+Error llvm::setupLLVMOptimizationRemarks(
+ LLVMContext &Context, raw_ostream &OS, StringRef RemarksPasses,
+ StringRef RemarksFormat, bool RemarksWithHotness,
+ Optional<uint64_t> RemarksHotnessThreshold) {
if (RemarksWithHotness)
Context.setDiagnosticsHotnessRequested(true);
- Context.setDiagnosticsHotnessThreshold(RemarksHotnessThreshold);
+ Context.setDiagnosticsHotnessThreshold(RemarksHotnessThreshold);
Expected<remarks::Format> Format = remarks::parseFormat(RemarksFormat);
if (Error E = Format.takeError())
diff --git a/contrib/libs/llvm12/lib/IR/LegacyPassManager.cpp b/contrib/libs/llvm12/lib/IR/LegacyPassManager.cpp
index a25d1e7f1a..4547c3a012 100644
--- a/contrib/libs/llvm12/lib/IR/LegacyPassManager.cpp
+++ b/contrib/libs/llvm12/lib/IR/LegacyPassManager.cpp
@@ -20,8 +20,8 @@
#include "llvm/IR/LegacyPassNameParser.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassTimingInfo.h"
-#include "llvm/IR/PrintPasses.h"
-#include "llvm/IR/StructuralHash.h"
+#include "llvm/IR/PrintPasses.h"
+#include "llvm/IR/StructuralHash.h"
#include "llvm/Support/Chrono.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -50,7 +50,7 @@ namespace {
enum PassDebugLevel {
Disabled, Arguments, Structure, Executions, Details
};
-} // namespace
+} // namespace
static cl::opt<enum PassDebugLevel>
PassDebugging("debug-pass", cl::Hidden,
@@ -137,7 +137,7 @@ void PMDataManager::emitInstrCountChangedRemark(
// remarks. Since it's possible that the first function in the module
// doesn't actually contain a basic block, we have to go and find one that's
// suitable for emitting remarks.
- auto It = llvm::find_if(M, [](const Function &Fn) { return !Fn.empty(); });
+ auto It = llvm::find_if(M, [](const Function &Fn) { return !Fn.empty(); });
// Didn't find a function. Quit.
if (It == M.end())
@@ -568,12 +568,12 @@ PMTopLevelManager::setLastUser(ArrayRef<Pass*> AnalysisPasses, Pass *P) {
PDepth = P->getResolver()->getPMDataManager().getDepth();
for (Pass *AP : AnalysisPasses) {
- // Record P as the new last user of AP.
- auto &LastUserOfAP = LastUser[AP];
- if (LastUserOfAP)
- InversedLastUser[LastUserOfAP].erase(AP);
- LastUserOfAP = P;
- InversedLastUser[P].insert(AP);
+ // Record P as the new last user of AP.
+ auto &LastUserOfAP = LastUser[AP];
+ if (LastUserOfAP)
+ InversedLastUser[LastUserOfAP].erase(AP);
+ LastUserOfAP = P;
+ InversedLastUser[P].insert(AP);
if (P == AP)
continue;
@@ -605,23 +605,23 @@ PMTopLevelManager::setLastUser(ArrayRef<Pass*> AnalysisPasses, Pass *P) {
// If AP is the last user of other passes then make P last user of
// such passes.
- auto &LastUsedByAP = InversedLastUser[AP];
- for (Pass *L : LastUsedByAP)
- LastUser[L] = P;
- InversedLastUser[P].insert(LastUsedByAP.begin(), LastUsedByAP.end());
- LastUsedByAP.clear();
+ auto &LastUsedByAP = InversedLastUser[AP];
+ for (Pass *L : LastUsedByAP)
+ LastUser[L] = P;
+ InversedLastUser[P].insert(LastUsedByAP.begin(), LastUsedByAP.end());
+ LastUsedByAP.clear();
}
}
/// Collect passes whose last user is P
void PMTopLevelManager::collectLastUses(SmallVectorImpl<Pass *> &LastUses,
Pass *P) {
- auto DMI = InversedLastUser.find(P);
+ auto DMI = InversedLastUser.find(P);
if (DMI == InversedLastUser.end())
return;
- auto &LU = DMI->second;
- LastUses.append(LU.begin(), LU.end());
+ auto &LU = DMI->second;
+ LastUses.append(LU.begin(), LU.end());
}
AnalysisUsage *PMTopLevelManager::findAnalysisUsage(Pass *P) {
@@ -1151,8 +1151,8 @@ Pass *PMDataManager::findAnalysisPass(AnalysisID AID, bool SearchParent) {
// Print list of passes that are last used by P.
void PMDataManager::dumpLastUses(Pass *P, unsigned Offset) const{
- if (PassDebugging < Details)
- return;
+ if (PassDebugging < Details)
+ return;
SmallVector<Pass *, 12> LUses;
@@ -1308,8 +1308,8 @@ PMDataManager::~PMDataManager() {
//===----------------------------------------------------------------------===//
// NOTE: Is this the right place to define this method ?
// getAnalysisIfAvailable - Return analysis result or null if it doesn't exist.
-Pass *AnalysisResolver::getAnalysisIfAvailable(AnalysisID ID) const {
- return PM.findAnalysisPass(ID, true);
+Pass *AnalysisResolver::getAnalysisIfAvailable(AnalysisID ID) const {
+ return PM.findAnalysisPass(ID, true);
}
std::tuple<Pass *, bool>
@@ -1429,19 +1429,19 @@ bool FPPassManager::runOnFunction(Function &F) {
{
PassManagerPrettyStackEntry X(FP, F);
TimeRegion PassTimer(getPassTimer(FP));
-#ifdef EXPENSIVE_CHECKS
- uint64_t RefHash = StructuralHash(F);
-#endif
+#ifdef EXPENSIVE_CHECKS
+ uint64_t RefHash = StructuralHash(F);
+#endif
LocalChanged |= FP->runOnFunction(F);
-
-#if defined(EXPENSIVE_CHECKS) && !defined(NDEBUG)
- if (!LocalChanged && (RefHash != StructuralHash(F))) {
- llvm::errs() << "Pass modifies its input and doesn't report it: "
- << FP->getPassName() << "\n";
- llvm_unreachable("Pass modifies its input and doesn't report it");
- }
-#endif
-
+
+#if defined(EXPENSIVE_CHECKS) && !defined(NDEBUG)
+ if (!LocalChanged && (RefHash != StructuralHash(F))) {
+ llvm::errs() << "Pass modifies its input and doesn't report it: "
+ << FP->getPassName() << "\n";
+ llvm_unreachable("Pass modifies its input and doesn't report it");
+ }
+#endif
+
if (EmitICRemark) {
unsigned NewSize = F.getInstructionCount();
@@ -1465,8 +1465,8 @@ bool FPPassManager::runOnFunction(Function &F) {
dumpUsedSet(FP);
verifyPreservedAnalysis(FP);
- if (LocalChanged)
- removeNotPreservedAnalysis(FP);
+ if (LocalChanged)
+ removeNotPreservedAnalysis(FP);
recordAvailableAnalysis(FP);
removeDeadPasses(FP, F.getName(), ON_FUNCTION_MSG);
}
@@ -1543,17 +1543,17 @@ MPPassManager::runOnModule(Module &M) {
PassManagerPrettyStackEntry X(MP, M);
TimeRegion PassTimer(getPassTimer(MP));
-#ifdef EXPENSIVE_CHECKS
- uint64_t RefHash = StructuralHash(M);
-#endif
-
+#ifdef EXPENSIVE_CHECKS
+ uint64_t RefHash = StructuralHash(M);
+#endif
+
LocalChanged |= MP->runOnModule(M);
-
-#ifdef EXPENSIVE_CHECKS
- assert((LocalChanged || (RefHash == StructuralHash(M))) &&
- "Pass modifies its input and doesn't report it.");
-#endif
-
+
+#ifdef EXPENSIVE_CHECKS
+ assert((LocalChanged || (RefHash == StructuralHash(M))) &&
+ "Pass modifies its input and doesn't report it.");
+#endif
+
if (EmitICRemark) {
// Update the size of the module.
unsigned ModuleCount = M.getInstructionCount();
@@ -1575,8 +1575,8 @@ MPPassManager::runOnModule(Module &M) {
dumpUsedSet(MP);
verifyPreservedAnalysis(MP);
- if (LocalChanged)
- removeNotPreservedAnalysis(MP);
+ if (LocalChanged)
+ removeNotPreservedAnalysis(MP);
recordAvailableAnalysis(MP);
removeDeadPasses(MP, M.getModuleIdentifier(), ON_MODULE_MSG);
}
diff --git a/contrib/libs/llvm12/lib/IR/MDBuilder.cpp b/contrib/libs/llvm12/lib/IR/MDBuilder.cpp
index 1acfa4fe54..35af849028 100644
--- a/contrib/libs/llvm12/lib/IR/MDBuilder.cpp
+++ b/contrib/libs/llvm12/lib/IR/MDBuilder.cpp
@@ -151,20 +151,20 @@ MDNode *MDBuilder::mergeCallbackEncodings(MDNode *ExistingCallbacks,
}
MDNode *MDBuilder::createAnonymousAARoot(StringRef Name, MDNode *Extra) {
- SmallVector<Metadata *, 3> Args(1, nullptr);
+ SmallVector<Metadata *, 3> Args(1, nullptr);
if (Extra)
Args.push_back(Extra);
if (!Name.empty())
Args.push_back(createString(Name));
- MDNode *Root = MDNode::getDistinct(Context, Args);
+ MDNode *Root = MDNode::getDistinct(Context, Args);
// At this point we have
- // !0 = distinct !{null} <- root
- // Replace the reserved operand with the root node itself.
+ // !0 = distinct !{null} <- root
+ // Replace the reserved operand with the root node itself.
Root->replaceOperandWith(0, Root);
// We now have
- // !0 = distinct !{!0} <- root
+ // !0 = distinct !{!0} <- root
return Root;
}
@@ -306,12 +306,12 @@ MDNode *MDBuilder::createIrrLoopHeaderWeight(uint64_t Weight) {
return MDNode::get(Context, Vals);
}
-MDNode *MDBuilder::createPseudoProbeDesc(uint64_t GUID, uint64_t Hash,
- Function *F) {
- auto *Int64Ty = Type::getInt64Ty(Context);
- SmallVector<Metadata *, 3> Ops(3);
- Ops[0] = createConstant(ConstantInt::get(Int64Ty, GUID));
- Ops[1] = createConstant(ConstantInt::get(Int64Ty, Hash));
- Ops[2] = createString(F->getName());
- return MDNode::get(Context, Ops);
+MDNode *MDBuilder::createPseudoProbeDesc(uint64_t GUID, uint64_t Hash,
+ Function *F) {
+ auto *Int64Ty = Type::getInt64Ty(Context);
+ SmallVector<Metadata *, 3> Ops(3);
+ Ops[0] = createConstant(ConstantInt::get(Int64Ty, GUID));
+ Ops[1] = createConstant(ConstantInt::get(Int64Ty, Hash));
+ Ops[2] = createString(F->getName());
+ return MDNode::get(Context, Ops);
}
diff --git a/contrib/libs/llvm12/lib/IR/Mangler.cpp b/contrib/libs/llvm12/lib/IR/Mangler.cpp
index f067d517b8..674ba3cdaa 100644
--- a/contrib/libs/llvm12/lib/IR/Mangler.cpp
+++ b/contrib/libs/llvm12/lib/IR/Mangler.cpp
@@ -12,7 +12,7 @@
#include "llvm/IR/Mangler.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
#include "llvm/IR/DataLayout.h"
@@ -101,7 +101,7 @@ static void addByteCountSuffix(raw_ostream &OS, const Function *F,
for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
AI != AE; ++AI) {
// 'Dereference' type in case of byval or inalloca parameter attribute.
- uint64_t AllocSize = AI->hasPassPointeeByValueCopyAttr() ?
+ uint64_t AllocSize = AI->hasPassPointeeByValueCopyAttr() ?
AI->getPassPointeeByValueCopySize(DL) :
DL.getTypeAllocSize(AI->getType());
@@ -185,25 +185,25 @@ void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
getNameWithPrefix(OS, GV, CannotUsePrivateLabel);
}
-// Check if the name needs quotes to be safe for the linker to interpret.
-static bool canBeUnquotedInDirective(char C) {
- return isAlnum(C) || C == '_' || C == '$' || C == '.' || C == '@';
-}
-
-static bool canBeUnquotedInDirective(StringRef Name) {
- if (Name.empty())
- return false;
-
- // If any of the characters in the string is an unacceptable character, force
- // quotes.
- for (char C : Name) {
- if (!canBeUnquotedInDirective(C))
- return false;
- }
-
- return true;
-}
-
+// Check if the name needs quotes to be safe for the linker to interpret.
+static bool canBeUnquotedInDirective(char C) {
+ return isAlnum(C) || C == '_' || C == '$' || C == '.' || C == '@';
+}
+
+static bool canBeUnquotedInDirective(StringRef Name) {
+ if (Name.empty())
+ return false;
+
+ // If any of the characters in the string is an unacceptable character, force
+ // quotes.
+ for (char C : Name) {
+ if (!canBeUnquotedInDirective(C))
+ return false;
+ }
+
+ return true;
+}
+
void llvm::emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
const Triple &TT, Mangler &Mangler) {
if (!GV->hasDLLExportStorageClass() || GV->isDeclaration())
@@ -214,9 +214,9 @@ void llvm::emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
else
OS << " -export:";
- bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName());
- if (NeedQuotes)
- OS << "\"";
+ bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName());
+ if (NeedQuotes)
+ OS << "\"";
if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) {
std::string Flag;
raw_string_ostream FlagOS(Flag);
@@ -229,8 +229,8 @@ void llvm::emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
} else {
Mangler.getNameWithPrefix(OS, GV, false);
}
- if (NeedQuotes)
- OS << "\"";
+ if (NeedQuotes)
+ OS << "\"";
if (!GV->getValueType()->isFunctionTy()) {
if (TT.isWindowsMSVCEnvironment())
@@ -246,11 +246,11 @@ void llvm::emitLinkerFlagsForUsedCOFF(raw_ostream &OS, const GlobalValue *GV,
return;
OS << " /INCLUDE:";
- bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName());
- if (NeedQuotes)
- OS << "\"";
+ bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName());
+ if (NeedQuotes)
+ OS << "\"";
M.getNameWithPrefix(OS, GV, false);
- if (NeedQuotes)
- OS << "\"";
+ if (NeedQuotes)
+ OS << "\"";
}
diff --git a/contrib/libs/llvm12/lib/IR/Metadata.cpp b/contrib/libs/llvm12/lib/IR/Metadata.cpp
index 0dd6734cbd..7ca538995d 100644
--- a/contrib/libs/llvm12/lib/IR/Metadata.cpp
+++ b/contrib/libs/llvm12/lib/IR/Metadata.cpp
@@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Metadata.h"
#include "LLVMContextImpl.h"
#include "MetadataImpl.h"
#include "SymbolTableListTraitsImpl.h"
@@ -39,7 +39,7 @@
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/MDBuilder.h"
+#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/TrackingMDRef.h"
#include "llvm/IR/Type.h"
@@ -641,7 +641,7 @@ void MDNode::resolveCycles() {
}
static bool hasSelfReference(MDNode *N) {
- return llvm::is_contained(N->operands(), N);
+ return llvm::is_contained(N->operands(), N);
}
MDNode *MDNode::replaceWithPermanentImpl() {
@@ -923,32 +923,32 @@ MDNode *MDNode::getMostGenericAliasScope(MDNode *A, MDNode *B) {
if (!A || !B)
return nullptr;
- // Take the intersection of domains then union the scopes
- // within those domains
- SmallPtrSet<const MDNode *, 16> ADomains;
- SmallPtrSet<const MDNode *, 16> IntersectDomains;
- SmallSetVector<Metadata *, 4> MDs;
- for (const MDOperand &MDOp : A->operands())
- if (const MDNode *NAMD = dyn_cast<MDNode>(MDOp))
- if (const MDNode *Domain = AliasScopeNode(NAMD).getDomain())
- ADomains.insert(Domain);
-
- for (const MDOperand &MDOp : B->operands())
- if (const MDNode *NAMD = dyn_cast<MDNode>(MDOp))
- if (const MDNode *Domain = AliasScopeNode(NAMD).getDomain())
- if (ADomains.contains(Domain)) {
- IntersectDomains.insert(Domain);
- MDs.insert(MDOp);
- }
-
- for (const MDOperand &MDOp : A->operands())
- if (const MDNode *NAMD = dyn_cast<MDNode>(MDOp))
- if (const MDNode *Domain = AliasScopeNode(NAMD).getDomain())
- if (IntersectDomains.contains(Domain))
- MDs.insert(MDOp);
-
- return MDs.empty() ? nullptr
- : getOrSelfReference(A->getContext(), MDs.getArrayRef());
+ // Take the intersection of domains then union the scopes
+ // within those domains
+ SmallPtrSet<const MDNode *, 16> ADomains;
+ SmallPtrSet<const MDNode *, 16> IntersectDomains;
+ SmallSetVector<Metadata *, 4> MDs;
+ for (const MDOperand &MDOp : A->operands())
+ if (const MDNode *NAMD = dyn_cast<MDNode>(MDOp))
+ if (const MDNode *Domain = AliasScopeNode(NAMD).getDomain())
+ ADomains.insert(Domain);
+
+ for (const MDOperand &MDOp : B->operands())
+ if (const MDNode *NAMD = dyn_cast<MDNode>(MDOp))
+ if (const MDNode *Domain = AliasScopeNode(NAMD).getDomain())
+ if (ADomains.contains(Domain)) {
+ IntersectDomains.insert(Domain);
+ MDs.insert(MDOp);
+ }
+
+ for (const MDOperand &MDOp : A->operands())
+ if (const MDNode *NAMD = dyn_cast<MDNode>(MDOp))
+ if (const MDNode *Domain = AliasScopeNode(NAMD).getDomain())
+ if (IntersectDomains.contains(Domain))
+ MDs.insert(MDOp);
+
+ return MDs.empty() ? nullptr
+ : getOrSelfReference(A->getContext(), MDs.getArrayRef());
}
MDNode *MDNode::getMostGenericFPMath(MDNode *A, MDNode *B) {
@@ -1124,160 +1124,160 @@ StringRef NamedMDNode::getName() const { return StringRef(Name); }
//===----------------------------------------------------------------------===//
// Instruction Metadata method implementations.
//
-
-MDNode *MDAttachments::lookup(unsigned ID) const {
- for (const auto &A : Attachments)
- if (A.MDKind == ID)
- return A.Node;
- return nullptr;
-}
-
-void MDAttachments::get(unsigned ID, SmallVectorImpl<MDNode *> &Result) const {
- for (const auto &A : Attachments)
- if (A.MDKind == ID)
- Result.push_back(A.Node);
-}
-
-void MDAttachments::getAll(
- SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const {
- for (const auto &A : Attachments)
- Result.emplace_back(A.MDKind, A.Node);
-
- // Sort the resulting array so it is stable with respect to metadata IDs. We
- // need to preserve the original insertion order though.
- if (Result.size() > 1)
- llvm::stable_sort(Result, less_first());
-}
-
-void MDAttachments::set(unsigned ID, MDNode *MD) {
- erase(ID);
- if (MD)
- insert(ID, *MD);
-}
-
-void MDAttachments::insert(unsigned ID, MDNode &MD) {
- Attachments.push_back({ID, TrackingMDNodeRef(&MD)});
-}
-
-bool MDAttachments::erase(unsigned ID) {
+
+MDNode *MDAttachments::lookup(unsigned ID) const {
+ for (const auto &A : Attachments)
+ if (A.MDKind == ID)
+ return A.Node;
+ return nullptr;
+}
+
+void MDAttachments::get(unsigned ID, SmallVectorImpl<MDNode *> &Result) const {
+ for (const auto &A : Attachments)
+ if (A.MDKind == ID)
+ Result.push_back(A.Node);
+}
+
+void MDAttachments::getAll(
+ SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const {
+ for (const auto &A : Attachments)
+ Result.emplace_back(A.MDKind, A.Node);
+
+ // Sort the resulting array so it is stable with respect to metadata IDs. We
+ // need to preserve the original insertion order though.
+ if (Result.size() > 1)
+ llvm::stable_sort(Result, less_first());
+}
+
+void MDAttachments::set(unsigned ID, MDNode *MD) {
+ erase(ID);
+ if (MD)
+ insert(ID, *MD);
+}
+
+void MDAttachments::insert(unsigned ID, MDNode &MD) {
+ Attachments.push_back({ID, TrackingMDNodeRef(&MD)});
+}
+
+bool MDAttachments::erase(unsigned ID) {
if (empty())
return false;
- // Common case is one value.
- if (Attachments.size() == 1 && Attachments.back().MDKind == ID) {
+ // Common case is one value.
+ if (Attachments.size() == 1 && Attachments.back().MDKind == ID) {
Attachments.pop_back();
return true;
}
- auto OldSize = Attachments.size();
- llvm::erase_if(Attachments,
- [ID](const Attachment &A) { return A.MDKind == ID; });
- return OldSize != Attachments.size();
-}
-
-MDNode *Value::getMetadata(unsigned KindID) const {
- if (!hasMetadata())
- return nullptr;
- const auto &Info = getContext().pImpl->ValueMetadata[this];
- assert(!Info.empty() && "bit out of sync with hash table");
- return Info.lookup(KindID);
-}
-
-MDNode *Value::getMetadata(StringRef Kind) const {
- if (!hasMetadata())
- return nullptr;
- const auto &Info = getContext().pImpl->ValueMetadata[this];
- assert(!Info.empty() && "bit out of sync with hash table");
- return Info.lookup(getContext().getMDKindID(Kind));
-}
-
-void Value::getMetadata(unsigned KindID, SmallVectorImpl<MDNode *> &MDs) const {
- if (hasMetadata())
- getContext().pImpl->ValueMetadata[this].get(KindID, MDs);
-}
-
-void Value::getMetadata(StringRef Kind, SmallVectorImpl<MDNode *> &MDs) const {
- if (hasMetadata())
- getMetadata(getContext().getMDKindID(Kind), MDs);
-}
-
-void Value::getAllMetadata(
- SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const {
- if (hasMetadata()) {
- assert(getContext().pImpl->ValueMetadata.count(this) &&
- "bit out of sync with hash table");
- const auto &Info = getContext().pImpl->ValueMetadata.find(this)->second;
- assert(!Info.empty() && "Shouldn't have called this");
- Info.getAll(MDs);
- }
-}
-
-void Value::setMetadata(unsigned KindID, MDNode *Node) {
- assert(isa<Instruction>(this) || isa<GlobalObject>(this));
-
- // Handle the case when we're adding/updating metadata on a value.
- if (Node) {
- auto &Info = getContext().pImpl->ValueMetadata[this];
- assert(!Info.empty() == HasMetadata && "bit out of sync with hash table");
- if (Info.empty())
- HasMetadata = true;
- Info.set(KindID, Node);
- return;
- }
-
- // Otherwise, we're removing metadata from an instruction.
- assert((HasMetadata == (getContext().pImpl->ValueMetadata.count(this) > 0)) &&
- "bit out of sync with hash table");
- if (!HasMetadata)
- return; // Nothing to remove!
- auto &Info = getContext().pImpl->ValueMetadata[this];
-
- // Handle removal of an existing value.
- Info.erase(KindID);
- if (!Info.empty())
- return;
- getContext().pImpl->ValueMetadata.erase(this);
- HasMetadata = false;
-}
-
-void Value::setMetadata(StringRef Kind, MDNode *Node) {
- if (!Node && !HasMetadata)
- return;
- setMetadata(getContext().getMDKindID(Kind), Node);
-}
-
-void Value::addMetadata(unsigned KindID, MDNode &MD) {
- assert(isa<Instruction>(this) || isa<GlobalObject>(this));
- if (!HasMetadata)
- HasMetadata = true;
- getContext().pImpl->ValueMetadata[this].insert(KindID, MD);
-}
-
-void Value::addMetadata(StringRef Kind, MDNode &MD) {
- addMetadata(getContext().getMDKindID(Kind), MD);
-}
-
-bool Value::eraseMetadata(unsigned KindID) {
- // Nothing to unset.
- if (!HasMetadata)
- return false;
-
- auto &Store = getContext().pImpl->ValueMetadata[this];
- bool Changed = Store.erase(KindID);
- if (Store.empty())
- clearMetadata();
- return Changed;
-}
-
-void Value::clearMetadata() {
- if (!HasMetadata)
- return;
- assert(getContext().pImpl->ValueMetadata.count(this) &&
- "bit out of sync with hash table");
- getContext().pImpl->ValueMetadata.erase(this);
- HasMetadata = false;
-}
-
+ auto OldSize = Attachments.size();
+ llvm::erase_if(Attachments,
+ [ID](const Attachment &A) { return A.MDKind == ID; });
+ return OldSize != Attachments.size();
+}
+
+MDNode *Value::getMetadata(unsigned KindID) const {
+ if (!hasMetadata())
+ return nullptr;
+ const auto &Info = getContext().pImpl->ValueMetadata[this];
+ assert(!Info.empty() && "bit out of sync with hash table");
+ return Info.lookup(KindID);
+}
+
+MDNode *Value::getMetadata(StringRef Kind) const {
+ if (!hasMetadata())
+ return nullptr;
+ const auto &Info = getContext().pImpl->ValueMetadata[this];
+ assert(!Info.empty() && "bit out of sync with hash table");
+ return Info.lookup(getContext().getMDKindID(Kind));
+}
+
+void Value::getMetadata(unsigned KindID, SmallVectorImpl<MDNode *> &MDs) const {
+ if (hasMetadata())
+ getContext().pImpl->ValueMetadata[this].get(KindID, MDs);
+}
+
+void Value::getMetadata(StringRef Kind, SmallVectorImpl<MDNode *> &MDs) const {
+ if (hasMetadata())
+ getMetadata(getContext().getMDKindID(Kind), MDs);
+}
+
+void Value::getAllMetadata(
+ SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const {
+ if (hasMetadata()) {
+ assert(getContext().pImpl->ValueMetadata.count(this) &&
+ "bit out of sync with hash table");
+ const auto &Info = getContext().pImpl->ValueMetadata.find(this)->second;
+ assert(!Info.empty() && "Shouldn't have called this");
+ Info.getAll(MDs);
+ }
+}
+
+void Value::setMetadata(unsigned KindID, MDNode *Node) {
+ assert(isa<Instruction>(this) || isa<GlobalObject>(this));
+
+ // Handle the case when we're adding/updating metadata on a value.
+ if (Node) {
+ auto &Info = getContext().pImpl->ValueMetadata[this];
+ assert(!Info.empty() == HasMetadata && "bit out of sync with hash table");
+ if (Info.empty())
+ HasMetadata = true;
+ Info.set(KindID, Node);
+ return;
+ }
+
+ // Otherwise, we're removing metadata from an instruction.
+ assert((HasMetadata == (getContext().pImpl->ValueMetadata.count(this) > 0)) &&
+ "bit out of sync with hash table");
+ if (!HasMetadata)
+ return; // Nothing to remove!
+ auto &Info = getContext().pImpl->ValueMetadata[this];
+
+ // Handle removal of an existing value.
+ Info.erase(KindID);
+ if (!Info.empty())
+ return;
+ getContext().pImpl->ValueMetadata.erase(this);
+ HasMetadata = false;
+}
+
+void Value::setMetadata(StringRef Kind, MDNode *Node) {
+ if (!Node && !HasMetadata)
+ return;
+ setMetadata(getContext().getMDKindID(Kind), Node);
+}
+
+void Value::addMetadata(unsigned KindID, MDNode &MD) {
+ assert(isa<Instruction>(this) || isa<GlobalObject>(this));
+ if (!HasMetadata)
+ HasMetadata = true;
+ getContext().pImpl->ValueMetadata[this].insert(KindID, MD);
+}
+
+void Value::addMetadata(StringRef Kind, MDNode &MD) {
+ addMetadata(getContext().getMDKindID(Kind), MD);
+}
+
+bool Value::eraseMetadata(unsigned KindID) {
+ // Nothing to unset.
+ if (!HasMetadata)
+ return false;
+
+ auto &Store = getContext().pImpl->ValueMetadata[this];
+ bool Changed = Store.erase(KindID);
+ if (Store.empty())
+ clearMetadata();
+ return Changed;
+}
+
+void Value::clearMetadata() {
+ if (!HasMetadata)
+ return;
+ assert(getContext().pImpl->ValueMetadata.count(this) &&
+ "bit out of sync with hash table");
+ getContext().pImpl->ValueMetadata.erase(this);
+ HasMetadata = false;
+}
+
void Instruction::setMetadata(StringRef Kind, MDNode *Node) {
if (!Node && !hasMetadata())
return;
@@ -1289,28 +1289,28 @@ MDNode *Instruction::getMetadataImpl(StringRef Kind) const {
}
void Instruction::dropUnknownNonDebugMetadata(ArrayRef<unsigned> KnownIDs) {
- if (!Value::hasMetadata())
+ if (!Value::hasMetadata())
return; // Nothing to remove!
- if (KnownIDs.empty()) {
+ if (KnownIDs.empty()) {
// Just drop our entry at the store.
- clearMetadata();
+ clearMetadata();
return;
}
- SmallSet<unsigned, 4> KnownSet;
- KnownSet.insert(KnownIDs.begin(), KnownIDs.end());
-
- auto &MetadataStore = getContext().pImpl->ValueMetadata;
- auto &Info = MetadataStore[this];
- assert(!Info.empty() && "bit out of sync with hash table");
- Info.remove_if([&KnownSet](const MDAttachments::Attachment &I) {
- return !KnownSet.count(I.MDKind);
+ SmallSet<unsigned, 4> KnownSet;
+ KnownSet.insert(KnownIDs.begin(), KnownIDs.end());
+
+ auto &MetadataStore = getContext().pImpl->ValueMetadata;
+ auto &Info = MetadataStore[this];
+ assert(!Info.empty() && "bit out of sync with hash table");
+ Info.remove_if([&KnownSet](const MDAttachments::Attachment &I) {
+ return !KnownSet.count(I.MDKind);
});
if (Info.empty()) {
// Drop our entry at the store.
- clearMetadata();
+ clearMetadata();
}
}
@@ -1324,28 +1324,28 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) {
return;
}
- Value::setMetadata(KindID, Node);
-}
+ Value::setMetadata(KindID, Node);
+}
-void Instruction::addAnnotationMetadata(StringRef Name) {
- MDBuilder MDB(getContext());
+void Instruction::addAnnotationMetadata(StringRef Name) {
+ MDBuilder MDB(getContext());
- auto *Existing = getMetadata(LLVMContext::MD_annotation);
- SmallVector<Metadata *, 4> Names;
- bool AppendName = true;
- if (Existing) {
- auto *Tuple = cast<MDTuple>(Existing);
- for (auto &N : Tuple->operands()) {
- if (cast<MDString>(N.get())->getString() == Name)
- AppendName = false;
- Names.push_back(N.get());
- }
- }
- if (AppendName)
- Names.push_back(MDB.createString(Name));
+ auto *Existing = getMetadata(LLVMContext::MD_annotation);
+ SmallVector<Metadata *, 4> Names;
+ bool AppendName = true;
+ if (Existing) {
+ auto *Tuple = cast<MDTuple>(Existing);
+ for (auto &N : Tuple->operands()) {
+ if (cast<MDString>(N.get())->getString() == Name)
+ AppendName = false;
+ Names.push_back(N.get());
+ }
+ }
+ if (AppendName)
+ Names.push_back(MDB.createString(Name));
- MDNode *MD = MDTuple::get(getContext(), Names);
- setMetadata(LLVMContext::MD_annotation, MD);
+ MDNode *MD = MDTuple::get(getContext(), Names);
+ setMetadata(LLVMContext::MD_annotation, MD);
}
void Instruction::setAAMetadata(const AAMDNodes &N) {
@@ -1359,7 +1359,7 @@ MDNode *Instruction::getMetadataImpl(unsigned KindID) const {
// Handle 'dbg' as a special case since it is not stored in the hash table.
if (KindID == LLVMContext::MD_dbg)
return DbgLoc.getAsMDNode();
- return Value::getMetadata(KindID);
+ return Value::getMetadata(KindID);
}
void Instruction::getAllMetadataImpl(
@@ -1371,7 +1371,7 @@ void Instruction::getAllMetadataImpl(
Result.push_back(
std::make_pair((unsigned)LLVMContext::MD_dbg, DbgLoc.getAsMDNode()));
}
- Value::getAllMetadata(Result);
+ Value::getAllMetadata(Result);
}
bool Instruction::extractProfMetadata(uint64_t &TrueVal,
diff --git a/contrib/libs/llvm12/lib/IR/Module.cpp b/contrib/libs/llvm12/lib/IR/Module.cpp
index 2064d50f1e..b4f10e2e2d 100644
--- a/contrib/libs/llvm12/lib/IR/Module.cpp
+++ b/contrib/libs/llvm12/lib/IR/Module.cpp
@@ -582,7 +582,7 @@ void Module::setProfileSummary(Metadata *M, ProfileSummary::Kind Kind) {
setModuleFlag(ModFlagBehavior::Error, "ProfileSummary", M);
}
-Metadata *Module::getProfileSummary(bool IsCS) const {
+Metadata *Module::getProfileSummary(bool IsCS) const {
return (IsCS ? getModuleFlag("CSProfileSummary")
: getModuleFlag("ProfileSummary"));
}
diff --git a/contrib/libs/llvm12/lib/IR/ModuleSummaryIndex.cpp b/contrib/libs/llvm12/lib/IR/ModuleSummaryIndex.cpp
index ca7ebf98c5..5d21ca759f 100644
--- a/contrib/libs/llvm12/lib/IR/ModuleSummaryIndex.cpp
+++ b/contrib/libs/llvm12/lib/IR/ModuleSummaryIndex.cpp
@@ -163,9 +163,9 @@ bool ModuleSummaryIndex::isGUIDLive(GlobalValue::GUID GUID) const {
return false;
}
-static void
-propagateAttributesToRefs(GlobalValueSummary *S,
- DenseSet<ValueInfo> &MarkedNonReadWriteOnly) {
+static void
+propagateAttributesToRefs(GlobalValueSummary *S,
+ DenseSet<ValueInfo> &MarkedNonReadWriteOnly) {
// If reference is not readonly or writeonly then referenced summary is not
// read/writeonly either. Note that:
// - All references from GlobalVarSummary are conservatively considered as
@@ -176,11 +176,11 @@ propagateAttributesToRefs(GlobalValueSummary *S,
// for them.
for (auto &VI : S->refs()) {
assert(VI.getAccessSpecifier() == 0 || isa<FunctionSummary>(S));
- if (!VI.getAccessSpecifier()) {
- if (!MarkedNonReadWriteOnly.insert(VI).second)
- continue;
- } else if (MarkedNonReadWriteOnly.contains(VI))
- continue;
+ if (!VI.getAccessSpecifier()) {
+ if (!MarkedNonReadWriteOnly.insert(VI).second)
+ continue;
+ } else if (MarkedNonReadWriteOnly.contains(VI))
+ continue;
for (auto &Ref : VI.getSummaryList())
// If references to alias is not read/writeonly then aliasee
// is not read/writeonly
@@ -223,24 +223,24 @@ void ModuleSummaryIndex::propagateAttributes(
const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) {
if (!PropagateAttrs)
return;
- DenseSet<ValueInfo> MarkedNonReadWriteOnly;
+ DenseSet<ValueInfo> MarkedNonReadWriteOnly;
for (auto &P : *this)
for (auto &S : P.second.SummaryList) {
- if (!isGlobalValueLive(S.get())) {
- // computeDeadSymbols should have marked all copies live. Note that
- // it is possible that there is a GUID collision between internal
- // symbols with the same name in different files of the same name but
- // not enough distinguishing path. Because computeDeadSymbols should
- // conservatively mark all copies live we can assert here that all are
- // dead if any copy is dead.
- assert(llvm::none_of(
- P.second.SummaryList,
- [&](const std::unique_ptr<GlobalValueSummary> &Summary) {
- return isGlobalValueLive(Summary.get());
- }));
+ if (!isGlobalValueLive(S.get())) {
+ // computeDeadSymbols should have marked all copies live. Note that
+ // it is possible that there is a GUID collision between internal
+ // symbols with the same name in different files of the same name but
+ // not enough distinguishing path. Because computeDeadSymbols should
+ // conservatively mark all copies live we can assert here that all are
+ // dead if any copy is dead.
+ assert(llvm::none_of(
+ P.second.SummaryList,
+ [&](const std::unique_ptr<GlobalValueSummary> &Summary) {
+ return isGlobalValueLive(Summary.get());
+ }));
// We don't examine references from dead objects
- break;
- }
+ break;
+ }
// Global variable can't be marked read/writeonly if it is not eligible
// to import since we need to ensure that all external references get
@@ -260,7 +260,7 @@ void ModuleSummaryIndex::propagateAttributes(
GVS->setReadOnly(false);
GVS->setWriteOnly(false);
}
- propagateAttributesToRefs(S.get(), MarkedNonReadWriteOnly);
+ propagateAttributesToRefs(S.get(), MarkedNonReadWriteOnly);
}
setWithAttributePropagation();
if (llvm::AreStatisticsEnabled())
diff --git a/contrib/libs/llvm12/lib/IR/Operator.cpp b/contrib/libs/llvm12/lib/IR/Operator.cpp
index b22afc4300..69181f3582 100644
--- a/contrib/libs/llvm12/lib/IR/Operator.cpp
+++ b/contrib/libs/llvm12/lib/IR/Operator.cpp
@@ -61,17 +61,17 @@ Align GEPOperator::getMaxPreservedAlignment(const DataLayout &DL) const {
bool GEPOperator::accumulateConstantOffset(
const DataLayout &DL, APInt &Offset,
function_ref<bool(Value &, APInt &)> ExternalAnalysis) const {
- assert(Offset.getBitWidth() ==
- DL.getIndexSizeInBits(getPointerAddressSpace()) &&
- "The offset bit width does not match DL specification.");
- SmallVector<const Value *> Index(value_op_begin() + 1, value_op_end());
- return GEPOperator::accumulateConstantOffset(getSourceElementType(), Index,
- DL, Offset, ExternalAnalysis);
-}
+ assert(Offset.getBitWidth() ==
+ DL.getIndexSizeInBits(getPointerAddressSpace()) &&
+ "The offset bit width does not match DL specification.");
+ SmallVector<const Value *> Index(value_op_begin() + 1, value_op_end());
+ return GEPOperator::accumulateConstantOffset(getSourceElementType(), Index,
+ DL, Offset, ExternalAnalysis);
+}
-bool GEPOperator::accumulateConstantOffset(
- Type *SourceType, ArrayRef<const Value *> Index, const DataLayout &DL,
- APInt &Offset, function_ref<bool(Value &, APInt &)> ExternalAnalysis) {
+bool GEPOperator::accumulateConstantOffset(
+ Type *SourceType, ArrayRef<const Value *> Index, const DataLayout &DL,
+ APInt &Offset, function_ref<bool(Value &, APInt &)> ExternalAnalysis) {
bool UsedExternalAnalysis = false;
auto AccumulateOffset = [&](APInt Index, uint64_t Size) -> bool {
Index = Index.sextOrTrunc(Offset.getBitWidth());
@@ -92,10 +92,10 @@ bool GEPOperator::accumulateConstantOffset(
}
return true;
};
- auto begin = generic_gep_type_iterator<decltype(Index.begin())>::begin(
- SourceType, Index.begin());
- auto end = generic_gep_type_iterator<decltype(Index.end())>::end(Index.end());
- for (auto GTI = begin, GTE = end; GTI != GTE; ++GTI) {
+ auto begin = generic_gep_type_iterator<decltype(Index.begin())>::begin(
+ SourceType, Index.begin());
+ auto end = generic_gep_type_iterator<decltype(Index.end())>::end(Index.end());
+ for (auto GTI = begin, GTE = end; GTI != GTE; ++GTI) {
// Scalable vectors are multiplied by a runtime constant.
bool ScalableType = false;
if (isa<ScalableVectorType>(GTI.getIndexedType()))
diff --git a/contrib/libs/llvm12/lib/IR/OptBisect.cpp b/contrib/libs/llvm12/lib/IR/OptBisect.cpp
index 9a88d3a1b9..dc85e1316d 100644
--- a/contrib/libs/llvm12/lib/IR/OptBisect.cpp
+++ b/contrib/libs/llvm12/lib/IR/OptBisect.cpp
@@ -54,5 +54,5 @@ bool OptBisect::checkPass(const StringRef PassName,
printPassMessage(PassName, CurBisectNum, TargetDesc, ShouldRun);
return ShouldRun;
}
-
-ManagedStatic<OptBisect> llvm::OptBisector;
+
+ManagedStatic<OptBisect> llvm::OptBisector;
diff --git a/contrib/libs/llvm12/lib/IR/Pass.cpp b/contrib/libs/llvm12/lib/IR/Pass.cpp
index 7ac9d618b6..755ea57c63 100644
--- a/contrib/libs/llvm12/lib/IR/Pass.cpp
+++ b/contrib/libs/llvm12/lib/IR/Pass.cpp
@@ -62,7 +62,7 @@ bool ModulePass::skipModule(Module &M) const {
}
bool Pass::mustPreserveAnalysisID(char &AID) const {
- return Resolver->getAnalysisIfAvailable(&AID) != nullptr;
+ return Resolver->getAnalysisIfAvailable(&AID) != nullptr;
}
// dumpPassStructure - Implement the -debug-pass=Structure option
@@ -259,23 +259,23 @@ void AnalysisUsage::setPreservesCFG() {
AnalysisUsage &AnalysisUsage::addPreserved(StringRef Arg) {
const PassInfo *PI = Pass::lookupPassInfo(Arg);
// If the pass exists, preserve it. Otherwise silently do nothing.
- if (PI)
- pushUnique(Preserved, PI->getTypeInfo());
+ if (PI)
+ pushUnique(Preserved, PI->getTypeInfo());
return *this;
}
AnalysisUsage &AnalysisUsage::addRequiredID(const void *ID) {
- pushUnique(Required, ID);
+ pushUnique(Required, ID);
return *this;
}
AnalysisUsage &AnalysisUsage::addRequiredID(char &ID) {
- pushUnique(Required, &ID);
+ pushUnique(Required, &ID);
return *this;
}
AnalysisUsage &AnalysisUsage::addRequiredTransitiveID(char &ID) {
- pushUnique(Required, &ID);
- pushUnique(RequiredTransitive, &ID);
+ pushUnique(Required, &ID);
+ pushUnique(RequiredTransitive, &ID);
return *this;
}
diff --git a/contrib/libs/llvm12/lib/IR/PassInstrumentation.cpp b/contrib/libs/llvm12/lib/IR/PassInstrumentation.cpp
index cea4f023e4..56a36db21e 100644
--- a/contrib/libs/llvm12/lib/IR/PassInstrumentation.cpp
+++ b/contrib/libs/llvm12/lib/IR/PassInstrumentation.cpp
@@ -12,29 +12,29 @@
//===----------------------------------------------------------------------===//
#include "llvm/IR/PassInstrumentation.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
-void PassInstrumentationCallbacks::addClassToPassName(StringRef ClassName,
- StringRef PassName) {
- ClassToPassName[ClassName] = PassName.str();
-}
-
-StringRef
-PassInstrumentationCallbacks::getPassNameForClassName(StringRef ClassName) {
- return ClassToPassName[ClassName];
-}
-
+void PassInstrumentationCallbacks::addClassToPassName(StringRef ClassName,
+ StringRef PassName) {
+ ClassToPassName[ClassName] = PassName.str();
+}
+
+StringRef
+PassInstrumentationCallbacks::getPassNameForClassName(StringRef ClassName) {
+ return ClassToPassName[ClassName];
+}
+
AnalysisKey PassInstrumentationAnalysis::Key;
-bool isSpecialPass(StringRef PassID, const std::vector<StringRef> &Specials) {
- size_t Pos = PassID.find('<');
- StringRef Prefix = PassID;
- if (Pos != StringRef::npos)
- Prefix = PassID.substr(0, Pos);
- return any_of(Specials, [Prefix](StringRef S) { return Prefix.endswith(S); });
-}
-
+bool isSpecialPass(StringRef PassID, const std::vector<StringRef> &Specials) {
+ size_t Pos = PassID.find('<');
+ StringRef Prefix = PassID;
+ if (Pos != StringRef::npos)
+ Prefix = PassID.substr(0, Pos);
+ return any_of(Specials, [Prefix](StringRef S) { return Prefix.endswith(S); });
+}
+
} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/IR/PassManager.cpp b/contrib/libs/llvm12/lib/IR/PassManager.cpp
index 8a64175049..4cf7ab2a60 100644
--- a/contrib/libs/llvm12/lib/IR/PassManager.cpp
+++ b/contrib/libs/llvm12/lib/IR/PassManager.cpp
@@ -91,54 +91,54 @@ bool FunctionAnalysisManagerModuleProxy::Result::invalidate(
}
} // namespace llvm
-PreservedAnalyses ModuleToFunctionPassAdaptor::run(Module &M,
- ModuleAnalysisManager &AM) {
- FunctionAnalysisManager &FAM =
- AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
-
- // Request PassInstrumentation from analysis manager, will use it to run
- // instrumenting callbacks for the passes later.
- PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(M);
-
- PreservedAnalyses PA = PreservedAnalyses::all();
- for (Function &F : M) {
- if (F.isDeclaration())
- continue;
-
- // Check the PassInstrumentation's BeforePass callbacks before running the
- // pass, skip its execution completely if asked to (callback returns
- // false).
- if (!PI.runBeforePass<Function>(*Pass, F))
- continue;
-
- PreservedAnalyses PassPA;
- {
- TimeTraceScope TimeScope(Pass->name(), F.getName());
- PassPA = Pass->run(F, FAM);
- }
-
- PI.runAfterPass(*Pass, F, PassPA);
-
- // We know that the function pass couldn't have invalidated any other
- // function's analyses (that's the contract of a function pass), so
- // directly handle the function analysis manager's invalidation here.
- FAM.invalidate(F, PassPA);
-
- // Then intersect the preserved set so that invalidation of module
- // analyses will eventually occur when the module pass completes.
- PA.intersect(std::move(PassPA));
- }
-
- // The FunctionAnalysisManagerModuleProxy is preserved because (we assume)
- // the function passes we ran didn't add or remove any functions.
- //
- // We also preserve all analyses on Functions, because we did all the
- // invalidation we needed to do above.
- PA.preserveSet<AllAnalysesOn<Function>>();
- PA.preserve<FunctionAnalysisManagerModuleProxy>();
- return PA;
-}
-
+PreservedAnalyses ModuleToFunctionPassAdaptor::run(Module &M,
+ ModuleAnalysisManager &AM) {
+ FunctionAnalysisManager &FAM =
+ AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+
+ // Request PassInstrumentation from analysis manager, will use it to run
+ // instrumenting callbacks for the passes later.
+ PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(M);
+
+ PreservedAnalyses PA = PreservedAnalyses::all();
+ for (Function &F : M) {
+ if (F.isDeclaration())
+ continue;
+
+ // Check the PassInstrumentation's BeforePass callbacks before running the
+ // pass, skip its execution completely if asked to (callback returns
+ // false).
+ if (!PI.runBeforePass<Function>(*Pass, F))
+ continue;
+
+ PreservedAnalyses PassPA;
+ {
+ TimeTraceScope TimeScope(Pass->name(), F.getName());
+ PassPA = Pass->run(F, FAM);
+ }
+
+ PI.runAfterPass(*Pass, F, PassPA);
+
+ // We know that the function pass couldn't have invalidated any other
+ // function's analyses (that's the contract of a function pass), so
+ // directly handle the function analysis manager's invalidation here.
+ FAM.invalidate(F, PassPA);
+
+ // Then intersect the preserved set so that invalidation of module
+ // analyses will eventually occur when the module pass completes.
+ PA.intersect(std::move(PassPA));
+ }
+
+ // The FunctionAnalysisManagerModuleProxy is preserved because (we assume)
+ // the function passes we ran didn't add or remove any functions.
+ //
+ // We also preserve all analyses on Functions, because we did all the
+ // invalidation we needed to do above.
+ PA.preserveSet<AllAnalysesOn<Function>>();
+ PA.preserve<FunctionAnalysisManagerModuleProxy>();
+ return PA;
+}
+
AnalysisSetKey CFGAnalyses::SetKey;
AnalysisSetKey PreservedAnalyses::AllAnalysesKey;
diff --git a/contrib/libs/llvm12/lib/IR/PassRegistry.cpp b/contrib/libs/llvm12/lib/IR/PassRegistry.cpp
index 20a5bce75e..94f607afec 100644
--- a/contrib/libs/llvm12/lib/IR/PassRegistry.cpp
+++ b/contrib/libs/llvm12/lib/IR/PassRegistry.cpp
@@ -40,12 +40,12 @@ PassRegistry::~PassRegistry() = default;
const PassInfo *PassRegistry::getPassInfo(const void *TI) const {
sys::SmartScopedReader<true> Guard(Lock);
- return PassInfoMap.lookup(TI);
+ return PassInfoMap.lookup(TI);
}
const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const {
sys::SmartScopedReader<true> Guard(Lock);
- return PassInfoStringMap.lookup(Arg);
+ return PassInfoStringMap.lookup(Arg);
}
//===----------------------------------------------------------------------===//
diff --git a/contrib/libs/llvm12/lib/IR/PassTimingInfo.cpp b/contrib/libs/llvm12/lib/IR/PassTimingInfo.cpp
index 47c1f9d1d5..d0c1517f48 100644
--- a/contrib/libs/llvm12/lib/IR/PassTimingInfo.cpp
+++ b/contrib/libs/llvm12/lib/IR/PassTimingInfo.cpp
@@ -24,7 +24,7 @@
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Mutex.h"
-#include "llvm/Support/TypeName.h"
+#include "llvm/Support/TypeName.h"
#include "llvm/Support/raw_ostream.h"
#include <string>
@@ -35,17 +35,17 @@ using namespace llvm;
namespace llvm {
bool TimePassesIsEnabled = false;
-bool TimePassesPerRun = false;
+bool TimePassesPerRun = false;
static cl::opt<bool, true> EnableTiming(
"time-passes", cl::location(TimePassesIsEnabled), cl::Hidden,
cl::desc("Time each pass, printing elapsed time for each on exit"));
-static cl::opt<bool, true> EnableTimingPerRun(
- "time-passes-per-run", cl::location(TimePassesPerRun), cl::Hidden,
- cl::desc("Time each pass run, printing elapsed time for each run on exit"),
- cl::callback([](const bool &) { TimePassesIsEnabled = true; }));
-
+static cl::opt<bool, true> EnableTimingPerRun(
+ "time-passes-per-run", cl::location(TimePassesPerRun), cl::Hidden,
+ cl::desc("Time each pass run, printing elapsed time for each run on exit"),
+ cl::callback([](const bool &) { TimePassesIsEnabled = true; }));
+
namespace {
namespace legacy {
@@ -171,13 +171,13 @@ void reportAndResetTimings(raw_ostream *OutStream) {
/// Returns the timer for the specified pass invocation of \p PassID.
/// Each time it creates a new timer.
Timer &TimePassesHandler::getPassTimer(StringRef PassID) {
- if (!PerRun) {
- TimerVector &Timers = TimingData[PassID];
- if (Timers.size() == 0)
- Timers.emplace_back(new Timer(PassID, PassID, TG));
- return *Timers.front();
- }
-
+ if (!PerRun) {
+ TimerVector &Timers = TimingData[PassID];
+ if (Timers.size() == 0)
+ Timers.emplace_back(new Timer(PassID, PassID, TG));
+ return *Timers.front();
+ }
+
// Take a vector of Timers created for this \p PassID and append
// one more timer to it.
TimerVector &Timers = TimingData[PassID];
@@ -192,13 +192,13 @@ Timer &TimePassesHandler::getPassTimer(StringRef PassID) {
return *T;
}
-TimePassesHandler::TimePassesHandler(bool Enabled, bool PerRun)
- : TG("pass", "... Pass execution timing report ..."), Enabled(Enabled),
- PerRun(PerRun) {}
+TimePassesHandler::TimePassesHandler(bool Enabled, bool PerRun)
+ : TG("pass", "... Pass execution timing report ..."), Enabled(Enabled),
+ PerRun(PerRun) {}
+
+TimePassesHandler::TimePassesHandler()
+ : TimePassesHandler(TimePassesIsEnabled, TimePassesPerRun) {}
-TimePassesHandler::TimePassesHandler()
- : TimePassesHandler(TimePassesIsEnabled, TimePassesPerRun) {}
-
void TimePassesHandler::setOutStream(raw_ostream &Out) {
OutStream = &Out;
}
@@ -248,10 +248,10 @@ void TimePassesHandler::stopTimer(StringRef PassID) {
MyTimer->stopTimer();
}
-void TimePassesHandler::runBeforePass(StringRef PassID) {
- if (isSpecialPass(PassID,
- {"PassManager", "PassAdaptor", "AnalysisManagerProxy"}))
- return;
+void TimePassesHandler::runBeforePass(StringRef PassID) {
+ if (isSpecialPass(PassID,
+ {"PassManager", "PassAdaptor", "AnalysisManagerProxy"}))
+ return;
startTimer(PassID);
@@ -260,8 +260,8 @@ void TimePassesHandler::runBeforePass(StringRef PassID) {
}
void TimePassesHandler::runAfterPass(StringRef PassID) {
- if (isSpecialPass(PassID,
- {"PassManager", "PassAdaptor", "AnalysisManagerProxy"}))
+ if (isSpecialPass(PassID,
+ {"PassManager", "PassAdaptor", "AnalysisManagerProxy"}))
return;
stopTimer(PassID);
@@ -274,16 +274,16 @@ void TimePassesHandler::registerCallbacks(PassInstrumentationCallbacks &PIC) {
if (!Enabled)
return;
- PIC.registerBeforeNonSkippedPassCallback(
- [this](StringRef P, Any) { this->runBeforePass(P); });
+ PIC.registerBeforeNonSkippedPassCallback(
+ [this](StringRef P, Any) { this->runBeforePass(P); });
PIC.registerAfterPassCallback(
- [this](StringRef P, Any, const PreservedAnalyses &) {
- this->runAfterPass(P);
- });
+ [this](StringRef P, Any, const PreservedAnalyses &) {
+ this->runAfterPass(P);
+ });
PIC.registerAfterPassInvalidatedCallback(
- [this](StringRef P, const PreservedAnalyses &) {
- this->runAfterPass(P);
- });
+ [this](StringRef P, const PreservedAnalyses &) {
+ this->runAfterPass(P);
+ });
PIC.registerBeforeAnalysisCallback(
[this](StringRef P, Any) { this->runBeforePass(P); });
PIC.registerAfterAnalysisCallback(
diff --git a/contrib/libs/llvm12/lib/IR/PrintPasses.cpp b/contrib/libs/llvm12/lib/IR/PrintPasses.cpp
index bda40d173b..83b8c93e76 100644
--- a/contrib/libs/llvm12/lib/IR/PrintPasses.cpp
+++ b/contrib/libs/llvm12/lib/IR/PrintPasses.cpp
@@ -1,88 +1,88 @@
-//===- PrintPasses.cpp ----------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/IR/PrintPasses.h"
-#include "llvm/Support/CommandLine.h"
-#include <unordered_set>
-
-using namespace llvm;
-
-// Print IR out before/after specified passes.
-static cl::list<std::string>
- PrintBefore("print-before",
- llvm::cl::desc("Print IR before specified passes"),
- cl::CommaSeparated, cl::Hidden);
-
-static cl::list<std::string>
- PrintAfter("print-after", llvm::cl::desc("Print IR after specified passes"),
- cl::CommaSeparated, cl::Hidden);
-
-static cl::opt<bool> PrintBeforeAll("print-before-all",
- llvm::cl::desc("Print IR before each pass"),
- cl::init(false), cl::Hidden);
-static cl::opt<bool> PrintAfterAll("print-after-all",
- llvm::cl::desc("Print IR after each pass"),
- cl::init(false), cl::Hidden);
-
-static cl::opt<bool>
- PrintModuleScope("print-module-scope",
- cl::desc("When printing IR for print-[before|after]{-all} "
- "always print a module IR"),
- cl::init(false), cl::Hidden);
-
-static cl::list<std::string>
- PrintFuncsList("filter-print-funcs", cl::value_desc("function names"),
- cl::desc("Only print IR for functions whose name "
- "match this for all print-[before|after][-all] "
- "options"),
- cl::CommaSeparated, cl::Hidden);
-
-/// This is a helper to determine whether to print IR before or
-/// after a pass.
-
-bool llvm::shouldPrintBeforeSomePass() {
- return PrintBeforeAll || !PrintBefore.empty();
-}
-
-bool llvm::shouldPrintAfterSomePass() {
- return PrintAfterAll || !PrintAfter.empty();
-}
-
-static bool shouldPrintBeforeOrAfterPass(StringRef PassID,
- ArrayRef<std::string> PassesToPrint) {
- return llvm::is_contained(PassesToPrint, PassID);
-}
-
-bool llvm::shouldPrintBeforeAll() { return PrintBeforeAll; }
-
-bool llvm::shouldPrintAfterAll() { return PrintAfterAll; }
-
-bool llvm::shouldPrintBeforePass(StringRef PassID) {
- return PrintBeforeAll || shouldPrintBeforeOrAfterPass(PassID, PrintBefore);
-}
-
-bool llvm::shouldPrintAfterPass(StringRef PassID) {
- return PrintAfterAll || shouldPrintBeforeOrAfterPass(PassID, PrintAfter);
-}
-
-std::vector<std::string> llvm::printBeforePasses() {
- return std::vector<std::string>(PrintBefore);
-}
-
-std::vector<std::string> llvm::printAfterPasses() {
- return std::vector<std::string>(PrintAfter);
-}
-
-bool llvm::forcePrintModuleIR() { return PrintModuleScope; }
-
-bool llvm::isFunctionInPrintList(StringRef FunctionName) {
- static std::unordered_set<std::string> PrintFuncNames(PrintFuncsList.begin(),
- PrintFuncsList.end());
- return PrintFuncNames.empty() ||
- PrintFuncNames.count(std::string(FunctionName));
-}
+//===- PrintPasses.cpp ----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/PrintPasses.h"
+#include "llvm/Support/CommandLine.h"
+#include <unordered_set>
+
+using namespace llvm;
+
+// Print IR out before/after specified passes.
+static cl::list<std::string>
+ PrintBefore("print-before",
+ llvm::cl::desc("Print IR before specified passes"),
+ cl::CommaSeparated, cl::Hidden);
+
+static cl::list<std::string>
+ PrintAfter("print-after", llvm::cl::desc("Print IR after specified passes"),
+ cl::CommaSeparated, cl::Hidden);
+
+static cl::opt<bool> PrintBeforeAll("print-before-all",
+ llvm::cl::desc("Print IR before each pass"),
+ cl::init(false), cl::Hidden);
+static cl::opt<bool> PrintAfterAll("print-after-all",
+ llvm::cl::desc("Print IR after each pass"),
+ cl::init(false), cl::Hidden);
+
+static cl::opt<bool>
+ PrintModuleScope("print-module-scope",
+ cl::desc("When printing IR for print-[before|after]{-all} "
+ "always print a module IR"),
+ cl::init(false), cl::Hidden);
+
+static cl::list<std::string>
+ PrintFuncsList("filter-print-funcs", cl::value_desc("function names"),
+ cl::desc("Only print IR for functions whose name "
+ "match this for all print-[before|after][-all] "
+ "options"),
+ cl::CommaSeparated, cl::Hidden);
+
+/// This is a helper to determine whether to print IR before or
+/// after a pass.
+
+bool llvm::shouldPrintBeforeSomePass() {
+ return PrintBeforeAll || !PrintBefore.empty();
+}
+
+bool llvm::shouldPrintAfterSomePass() {
+ return PrintAfterAll || !PrintAfter.empty();
+}
+
+static bool shouldPrintBeforeOrAfterPass(StringRef PassID,
+ ArrayRef<std::string> PassesToPrint) {
+ return llvm::is_contained(PassesToPrint, PassID);
+}
+
+bool llvm::shouldPrintBeforeAll() { return PrintBeforeAll; }
+
+bool llvm::shouldPrintAfterAll() { return PrintAfterAll; }
+
+bool llvm::shouldPrintBeforePass(StringRef PassID) {
+ return PrintBeforeAll || shouldPrintBeforeOrAfterPass(PassID, PrintBefore);
+}
+
+bool llvm::shouldPrintAfterPass(StringRef PassID) {
+ return PrintAfterAll || shouldPrintBeforeOrAfterPass(PassID, PrintAfter);
+}
+
+std::vector<std::string> llvm::printBeforePasses() {
+ return std::vector<std::string>(PrintBefore);
+}
+
+std::vector<std::string> llvm::printAfterPasses() {
+ return std::vector<std::string>(PrintAfter);
+}
+
+bool llvm::forcePrintModuleIR() { return PrintModuleScope; }
+
+bool llvm::isFunctionInPrintList(StringRef FunctionName) {
+ static std::unordered_set<std::string> PrintFuncNames(PrintFuncsList.begin(),
+ PrintFuncsList.end());
+ return PrintFuncNames.empty() ||
+ PrintFuncNames.count(std::string(FunctionName));
+}
diff --git a/contrib/libs/llvm12/lib/IR/ProfileSummary.cpp b/contrib/libs/llvm12/lib/IR/ProfileSummary.cpp
index 7cef3bc83d..453a278a7f 100644
--- a/contrib/libs/llvm12/lib/IR/ProfileSummary.cpp
+++ b/contrib/libs/llvm12/lib/IR/ProfileSummary.cpp
@@ -259,7 +259,7 @@ void ProfileSummary::printSummary(raw_ostream &OS) {
void ProfileSummary::printDetailedSummary(raw_ostream &OS) {
OS << "Detailed summary:\n";
- for (const auto &Entry : DetailedSummary) {
+ for (const auto &Entry : DetailedSummary) {
OS << Entry.NumCounts << " blocks with count >= " << Entry.MinCount
<< " account for "
<< format("%0.6g", (float)Entry.Cutoff / Scale * 100)
diff --git a/contrib/libs/llvm12/lib/IR/PseudoProbe.cpp b/contrib/libs/llvm12/lib/IR/PseudoProbe.cpp
index 24f38b8888..80d2963938 100644
--- a/contrib/libs/llvm12/lib/IR/PseudoProbe.cpp
+++ b/contrib/libs/llvm12/lib/IR/PseudoProbe.cpp
@@ -1,99 +1,99 @@
-//===- PseudoProbe.cpp - Pseudo Probe Helpers -----------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the helpers to manipulate pseudo probe IR intrinsic
-// calls.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/IR/PseudoProbe.h"
-#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Instruction.h"
-
-using namespace llvm;
-
-namespace llvm {
-
-Optional<PseudoProbe> extractProbeFromDiscriminator(const Instruction &Inst) {
- assert(isa<CallBase>(&Inst) && !isa<IntrinsicInst>(&Inst) &&
- "Only call instructions should have pseudo probe encodes as their "
- "Dwarf discriminators");
- if (const DebugLoc &DLoc = Inst.getDebugLoc()) {
- const DILocation *DIL = DLoc;
- auto Discriminator = DIL->getDiscriminator();
- if (DILocation::isPseudoProbeDiscriminator(Discriminator)) {
- PseudoProbe Probe;
- Probe.Id =
- PseudoProbeDwarfDiscriminator::extractProbeIndex(Discriminator);
- Probe.Type =
- PseudoProbeDwarfDiscriminator::extractProbeType(Discriminator);
- Probe.Attr =
- PseudoProbeDwarfDiscriminator::extractProbeAttributes(Discriminator);
- Probe.Factor =
- PseudoProbeDwarfDiscriminator::extractProbeFactor(Discriminator) /
- (float)PseudoProbeDwarfDiscriminator::FullDistributionFactor;
- return Probe;
- }
- }
- return None;
-}
-
-Optional<PseudoProbe> extractProbe(const Instruction &Inst) {
- if (const auto *II = dyn_cast<PseudoProbeInst>(&Inst)) {
- PseudoProbe Probe;
- Probe.Id = II->getIndex()->getZExtValue();
- Probe.Type = (uint32_t)PseudoProbeType::Block;
- Probe.Attr = II->getAttributes()->getZExtValue();
- Probe.Factor = II->getFactor()->getZExtValue() /
- (float)PseudoProbeFullDistributionFactor;
- return Probe;
- }
-
- if (isa<CallBase>(&Inst) && !isa<IntrinsicInst>(&Inst))
- return extractProbeFromDiscriminator(Inst);
-
- return None;
-}
-
-void setProbeDistributionFactor(Instruction &Inst, float Factor) {
- assert(Factor >= 0 && Factor <= 1 &&
- "Distribution factor must be in [0, 1.0]");
- if (auto *II = dyn_cast<PseudoProbeInst>(&Inst)) {
- IRBuilder<> Builder(&Inst);
- uint64_t IntFactor = PseudoProbeFullDistributionFactor;
- if (Factor < 1)
- IntFactor *= Factor;
- auto OrigFactor = II->getFactor()->getZExtValue();
- if (IntFactor != OrigFactor)
- II->replaceUsesOfWith(II->getFactor(), Builder.getInt64(IntFactor));
- } else if (isa<CallBase>(&Inst) && !isa<IntrinsicInst>(&Inst)) {
- if (const DebugLoc &DLoc = Inst.getDebugLoc()) {
- const DILocation *DIL = DLoc;
- auto Discriminator = DIL->getDiscriminator();
- if (DILocation::isPseudoProbeDiscriminator(Discriminator)) {
- auto Index =
- PseudoProbeDwarfDiscriminator::extractProbeIndex(Discriminator);
- auto Type =
- PseudoProbeDwarfDiscriminator::extractProbeType(Discriminator);
- auto Attr = PseudoProbeDwarfDiscriminator::extractProbeAttributes(
- Discriminator);
- // Round small factors to 0 to avoid over-counting.
- uint32_t IntFactor =
- PseudoProbeDwarfDiscriminator::FullDistributionFactor;
- if (Factor < 1)
- IntFactor *= Factor;
- uint32_t V = PseudoProbeDwarfDiscriminator::packProbeData(
- Index, Type, Attr, IntFactor);
- DIL = DIL->cloneWithDiscriminator(V);
- Inst.setDebugLoc(DIL);
- }
- }
- }
-}
-} // namespace llvm
+//===- PseudoProbe.cpp - Pseudo Probe Helpers -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the helpers to manipulate pseudo probe IR intrinsic
+// calls.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/PseudoProbe.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Instruction.h"
+
+using namespace llvm;
+
+namespace llvm {
+
+Optional<PseudoProbe> extractProbeFromDiscriminator(const Instruction &Inst) {
+ assert(isa<CallBase>(&Inst) && !isa<IntrinsicInst>(&Inst) &&
+ "Only call instructions should have pseudo probe encodes as their "
+ "Dwarf discriminators");
+ if (const DebugLoc &DLoc = Inst.getDebugLoc()) {
+ const DILocation *DIL = DLoc;
+ auto Discriminator = DIL->getDiscriminator();
+ if (DILocation::isPseudoProbeDiscriminator(Discriminator)) {
+ PseudoProbe Probe;
+ Probe.Id =
+ PseudoProbeDwarfDiscriminator::extractProbeIndex(Discriminator);
+ Probe.Type =
+ PseudoProbeDwarfDiscriminator::extractProbeType(Discriminator);
+ Probe.Attr =
+ PseudoProbeDwarfDiscriminator::extractProbeAttributes(Discriminator);
+ Probe.Factor =
+ PseudoProbeDwarfDiscriminator::extractProbeFactor(Discriminator) /
+ (float)PseudoProbeDwarfDiscriminator::FullDistributionFactor;
+ return Probe;
+ }
+ }
+ return None;
+}
+
+Optional<PseudoProbe> extractProbe(const Instruction &Inst) {
+ if (const auto *II = dyn_cast<PseudoProbeInst>(&Inst)) {
+ PseudoProbe Probe;
+ Probe.Id = II->getIndex()->getZExtValue();
+ Probe.Type = (uint32_t)PseudoProbeType::Block;
+ Probe.Attr = II->getAttributes()->getZExtValue();
+ Probe.Factor = II->getFactor()->getZExtValue() /
+ (float)PseudoProbeFullDistributionFactor;
+ return Probe;
+ }
+
+ if (isa<CallBase>(&Inst) && !isa<IntrinsicInst>(&Inst))
+ return extractProbeFromDiscriminator(Inst);
+
+ return None;
+}
+
+void setProbeDistributionFactor(Instruction &Inst, float Factor) {
+ assert(Factor >= 0 && Factor <= 1 &&
+ "Distribution factor must be in [0, 1.0]");
+ if (auto *II = dyn_cast<PseudoProbeInst>(&Inst)) {
+ IRBuilder<> Builder(&Inst);
+ uint64_t IntFactor = PseudoProbeFullDistributionFactor;
+ if (Factor < 1)
+ IntFactor *= Factor;
+ auto OrigFactor = II->getFactor()->getZExtValue();
+ if (IntFactor != OrigFactor)
+ II->replaceUsesOfWith(II->getFactor(), Builder.getInt64(IntFactor));
+ } else if (isa<CallBase>(&Inst) && !isa<IntrinsicInst>(&Inst)) {
+ if (const DebugLoc &DLoc = Inst.getDebugLoc()) {
+ const DILocation *DIL = DLoc;
+ auto Discriminator = DIL->getDiscriminator();
+ if (DILocation::isPseudoProbeDiscriminator(Discriminator)) {
+ auto Index =
+ PseudoProbeDwarfDiscriminator::extractProbeIndex(Discriminator);
+ auto Type =
+ PseudoProbeDwarfDiscriminator::extractProbeType(Discriminator);
+ auto Attr = PseudoProbeDwarfDiscriminator::extractProbeAttributes(
+ Discriminator);
+ // Round small factors to 0 to avoid over-counting.
+ uint32_t IntFactor =
+ PseudoProbeDwarfDiscriminator::FullDistributionFactor;
+ if (Factor < 1)
+ IntFactor *= Factor;
+ uint32_t V = PseudoProbeDwarfDiscriminator::packProbeData(
+ Index, Type, Attr, IntFactor);
+ DIL = DIL->cloneWithDiscriminator(V);
+ Inst.setDebugLoc(DIL);
+ }
+ }
+ }
+}
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/IR/ReplaceConstant.cpp b/contrib/libs/llvm12/lib/IR/ReplaceConstant.cpp
index b06e838d60..7efa525d42 100644
--- a/contrib/libs/llvm12/lib/IR/ReplaceConstant.cpp
+++ b/contrib/libs/llvm12/lib/IR/ReplaceConstant.cpp
@@ -1,70 +1,70 @@
-//===- ReplaceConstant.cpp - Replace LLVM constant expression--------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements a utility function for replacing LLVM constant
-// expressions by instructions.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/IR/ReplaceConstant.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/NoFolder.h"
-
-namespace llvm {
-// Replace a constant expression by instructions with equivalent operations at
-// a specified location.
-Instruction *createReplacementInstr(ConstantExpr *CE, Instruction *Instr) {
- IRBuilder<NoFolder> Builder(Instr);
- unsigned OpCode = CE->getOpcode();
- switch (OpCode) {
- case Instruction::GetElementPtr: {
- SmallVector<Value *, 4> CEOpVec(CE->operands());
- ArrayRef<Value *> CEOps(CEOpVec);
- return dyn_cast<Instruction>(
- Builder.CreateInBoundsGEP(cast<GEPOperator>(CE)->getSourceElementType(),
- CEOps[0], CEOps.slice(1)));
- }
- case Instruction::Add:
- case Instruction::Sub:
- case Instruction::Mul:
- case Instruction::UDiv:
- case Instruction::SDiv:
- case Instruction::FDiv:
- case Instruction::URem:
- case Instruction::SRem:
- case Instruction::FRem:
- case Instruction::Shl:
- case Instruction::LShr:
- case Instruction::AShr:
- case Instruction::And:
- case Instruction::Or:
- case Instruction::Xor:
- return dyn_cast<Instruction>(
- Builder.CreateBinOp((Instruction::BinaryOps)OpCode, CE->getOperand(0),
- CE->getOperand(1), CE->getName()));
- case Instruction::Trunc:
- case Instruction::ZExt:
- case Instruction::SExt:
- case Instruction::FPToUI:
- case Instruction::FPToSI:
- case Instruction::UIToFP:
- case Instruction::SIToFP:
- case Instruction::FPTrunc:
- case Instruction::FPExt:
- case Instruction::PtrToInt:
- case Instruction::IntToPtr:
- case Instruction::BitCast:
- return dyn_cast<Instruction>(
- Builder.CreateCast((Instruction::CastOps)OpCode, CE->getOperand(0),
- CE->getType(), CE->getName()));
- default:
- llvm_unreachable("Unhandled constant expression!\n");
- }
-}
-} // namespace llvm
+//===- ReplaceConstant.cpp - Replace LLVM constant expression--------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a utility function for replacing LLVM constant
+// expressions by instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/ReplaceConstant.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/NoFolder.h"
+
+namespace llvm {
+// Replace a constant expression by instructions with equivalent operations at
+// a specified location.
+Instruction *createReplacementInstr(ConstantExpr *CE, Instruction *Instr) {
+ IRBuilder<NoFolder> Builder(Instr);
+ unsigned OpCode = CE->getOpcode();
+ switch (OpCode) {
+ case Instruction::GetElementPtr: {
+ SmallVector<Value *, 4> CEOpVec(CE->operands());
+ ArrayRef<Value *> CEOps(CEOpVec);
+ return dyn_cast<Instruction>(
+ Builder.CreateInBoundsGEP(cast<GEPOperator>(CE)->getSourceElementType(),
+ CEOps[0], CEOps.slice(1)));
+ }
+ case Instruction::Add:
+ case Instruction::Sub:
+ case Instruction::Mul:
+ case Instruction::UDiv:
+ case Instruction::SDiv:
+ case Instruction::FDiv:
+ case Instruction::URem:
+ case Instruction::SRem:
+ case Instruction::FRem:
+ case Instruction::Shl:
+ case Instruction::LShr:
+ case Instruction::AShr:
+ case Instruction::And:
+ case Instruction::Or:
+ case Instruction::Xor:
+ return dyn_cast<Instruction>(
+ Builder.CreateBinOp((Instruction::BinaryOps)OpCode, CE->getOperand(0),
+ CE->getOperand(1), CE->getName()));
+ case Instruction::Trunc:
+ case Instruction::ZExt:
+ case Instruction::SExt:
+ case Instruction::FPToUI:
+ case Instruction::FPToSI:
+ case Instruction::UIToFP:
+ case Instruction::SIToFP:
+ case Instruction::FPTrunc:
+ case Instruction::FPExt:
+ case Instruction::PtrToInt:
+ case Instruction::IntToPtr:
+ case Instruction::BitCast:
+ return dyn_cast<Instruction>(
+ Builder.CreateCast((Instruction::CastOps)OpCode, CE->getOperand(0),
+ CE->getType(), CE->getName()));
+ default:
+ llvm_unreachable("Unhandled constant expression!\n");
+ }
+}
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/IR/SafepointIRVerifier.cpp b/contrib/libs/llvm12/lib/IR/SafepointIRVerifier.cpp
index 444f714f8f..8ed31b6668 100644
--- a/contrib/libs/llvm12/lib/IR/SafepointIRVerifier.cpp
+++ b/contrib/libs/llvm12/lib/IR/SafepointIRVerifier.cpp
@@ -561,7 +561,7 @@ GCPtrTracker::GCPtrTracker(const Function &F, const DominatorTree &DT,
}
BasicBlockState *GCPtrTracker::getBasicBlockState(const BasicBlock *BB) {
- return BlockMap.lookup(BB);
+ return BlockMap.lookup(BB);
}
const BasicBlockState *GCPtrTracker::getBasicBlockState(
diff --git a/contrib/libs/llvm12/lib/IR/StructuralHash.cpp b/contrib/libs/llvm12/lib/IR/StructuralHash.cpp
index cf8e7cb1d6..5a6e074513 100644
--- a/contrib/libs/llvm12/lib/IR/StructuralHash.cpp
+++ b/contrib/libs/llvm12/lib/IR/StructuralHash.cpp
@@ -1,84 +1,84 @@
-//===-- StructuralHash.cpp - IR Hash for expensive checks -------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-
-#ifdef EXPENSIVE_CHECKS
-
-#include "llvm/IR/StructuralHash.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Module.h"
-
-using namespace llvm;
-
-namespace {
-namespace details {
-
-// Basic hashing mechanism to detect structural change to the IR, used to verify
-// pass return status consistency with actual change. Loosely copied from
-// llvm/lib/Transforms/Utils/FunctionComparator.cpp
-
-class StructuralHash {
- uint64_t Hash = 0x6acaa36bef8325c5ULL;
-
- void update(uint64_t V) { Hash = hashing::detail::hash_16_bytes(Hash, V); }
-
-public:
- StructuralHash() = default;
-
- void update(const Function &F) {
- if (F.empty())
- return;
-
- update(F.isVarArg());
- update(F.arg_size());
-
- SmallVector<const BasicBlock *, 8> BBs;
- SmallPtrSet<const BasicBlock *, 16> VisitedBBs;
-
- BBs.push_back(&F.getEntryBlock());
- VisitedBBs.insert(BBs[0]);
- while (!BBs.empty()) {
- const BasicBlock *BB = BBs.pop_back_val();
- update(45798); // Block header
- for (auto &Inst : *BB)
- update(Inst.getOpcode());
-
- const Instruction *Term = BB->getTerminator();
- for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
- if (!VisitedBBs.insert(Term->getSuccessor(i)).second)
- continue;
- BBs.push_back(Term->getSuccessor(i));
- }
- }
- }
-
- void update(const Module &M) {
- for (const Function &F : M)
- update(F);
- }
-
- uint64_t getHash() const { return Hash; }
-};
-
-} // namespace details
-
-} // namespace
-
-uint64_t llvm::StructuralHash(const Function &F) {
- details::StructuralHash H;
- H.update(F);
- return H.getHash();
-}
-
-uint64_t llvm::StructuralHash(const Module &M) {
- details::StructuralHash H;
- H.update(M);
- return H.getHash();
-}
-
-#endif
+//===-- StructuralHash.cpp - IR Hash for expensive checks -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+
+#ifdef EXPENSIVE_CHECKS
+
+#include "llvm/IR/StructuralHash.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+
+using namespace llvm;
+
+namespace {
+namespace details {
+
+// Basic hashing mechanism to detect structural change to the IR, used to verify
+// pass return status consistency with actual change. Loosely copied from
+// llvm/lib/Transforms/Utils/FunctionComparator.cpp
+
+class StructuralHash {
+ uint64_t Hash = 0x6acaa36bef8325c5ULL;
+
+ void update(uint64_t V) { Hash = hashing::detail::hash_16_bytes(Hash, V); }
+
+public:
+ StructuralHash() = default;
+
+ void update(const Function &F) {
+ if (F.empty())
+ return;
+
+ update(F.isVarArg());
+ update(F.arg_size());
+
+ SmallVector<const BasicBlock *, 8> BBs;
+ SmallPtrSet<const BasicBlock *, 16> VisitedBBs;
+
+ BBs.push_back(&F.getEntryBlock());
+ VisitedBBs.insert(BBs[0]);
+ while (!BBs.empty()) {
+ const BasicBlock *BB = BBs.pop_back_val();
+ update(45798); // Block header
+ for (auto &Inst : *BB)
+ update(Inst.getOpcode());
+
+ const Instruction *Term = BB->getTerminator();
+ for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
+ if (!VisitedBBs.insert(Term->getSuccessor(i)).second)
+ continue;
+ BBs.push_back(Term->getSuccessor(i));
+ }
+ }
+ }
+
+ void update(const Module &M) {
+ for (const Function &F : M)
+ update(F);
+ }
+
+ uint64_t getHash() const { return Hash; }
+};
+
+} // namespace details
+
+} // namespace
+
+uint64_t llvm::StructuralHash(const Function &F) {
+ details::StructuralHash H;
+ H.update(F);
+ return H.getHash();
+}
+
+uint64_t llvm::StructuralHash(const Module &M) {
+ details::StructuralHash H;
+ H.update(M);
+ return H.getHash();
+}
+
+#endif
diff --git a/contrib/libs/llvm12/lib/IR/Type.cpp b/contrib/libs/llvm12/lib/IR/Type.cpp
index 13a6e116c3..bade7dc325 100644
--- a/contrib/libs/llvm12/lib/IR/Type.cpp
+++ b/contrib/libs/llvm12/lib/IR/Type.cpp
@@ -49,7 +49,7 @@ Type *Type::getPrimitiveType(LLVMContext &C, TypeID IDNumber) {
case LabelTyID : return getLabelTy(C);
case MetadataTyID : return getMetadataTy(C);
case X86_MMXTyID : return getX86_MMXTy(C);
- case X86_AMXTyID : return getX86_AMXTy(C);
+ case X86_AMXTyID : return getX86_AMXTy(C);
case TokenTyID : return getTokenTy(C);
default:
return nullptr;
@@ -82,14 +82,14 @@ bool Type::canLosslesslyBitCastTo(Type *Ty) const {
Ty->getPrimitiveSizeInBits().getFixedSize() == 64)
return true;
- // 8192-bit fixed width vector types can be losslessly converted to x86amx.
- if (((isa<FixedVectorType>(this)) && Ty->isX86_AMXTy()) &&
- getPrimitiveSizeInBits().getFixedSize() == 8192)
- return true;
- if ((isX86_AMXTy() && isa<FixedVectorType>(Ty)) &&
- Ty->getPrimitiveSizeInBits().getFixedSize() == 8192)
- return true;
-
+ // 8192-bit fixed width vector types can be losslessly converted to x86amx.
+ if (((isa<FixedVectorType>(this)) && Ty->isX86_AMXTy()) &&
+ getPrimitiveSizeInBits().getFixedSize() == 8192)
+ return true;
+ if ((isX86_AMXTy() && isa<FixedVectorType>(Ty)) &&
+ Ty->getPrimitiveSizeInBits().getFixedSize() == 8192)
+ return true;
+
// At this point we have only various mismatches of the first class types
// remaining and ptr->ptr. Just select the lossless conversions. Everything
// else is not lossless. Conservatively assume we can't losslessly convert
@@ -129,7 +129,7 @@ TypeSize Type::getPrimitiveSizeInBits() const {
case Type::FP128TyID: return TypeSize::Fixed(128);
case Type::PPC_FP128TyID: return TypeSize::Fixed(128);
case Type::X86_MMXTyID: return TypeSize::Fixed(64);
- case Type::X86_AMXTyID: return TypeSize::Fixed(8192);
+ case Type::X86_AMXTyID: return TypeSize::Fixed(8192);
case Type::IntegerTyID:
return TypeSize::Fixed(cast<IntegerType>(this)->getBitWidth());
case Type::FixedVectorTyID:
@@ -138,7 +138,7 @@ TypeSize Type::getPrimitiveSizeInBits() const {
ElementCount EC = VTy->getElementCount();
TypeSize ETS = VTy->getElementType()->getPrimitiveSizeInBits();
assert(!ETS.isScalable() && "Vector type should have fixed-width elements");
- return {ETS.getFixedSize() * EC.getKnownMinValue(), EC.isScalable()};
+ return {ETS.getFixedSize() * EC.getKnownMinValue(), EC.isScalable()};
}
default: return TypeSize::Fixed(0);
}
@@ -189,7 +189,7 @@ Type *Type::getX86_FP80Ty(LLVMContext &C) { return &C.pImpl->X86_FP80Ty; }
Type *Type::getFP128Ty(LLVMContext &C) { return &C.pImpl->FP128Ty; }
Type *Type::getPPC_FP128Ty(LLVMContext &C) { return &C.pImpl->PPC_FP128Ty; }
Type *Type::getX86_MMXTy(LLVMContext &C) { return &C.pImpl->X86_MMXTy; }
-Type *Type::getX86_AMXTy(LLVMContext &C) { return &C.pImpl->X86_AMXTy; }
+Type *Type::getX86_AMXTy(LLVMContext &C) { return &C.pImpl->X86_AMXTy; }
IntegerType *Type::getInt1Ty(LLVMContext &C) { return &C.pImpl->Int1Ty; }
IntegerType *Type::getInt8Ty(LLVMContext &C) { return &C.pImpl->Int8Ty; }
@@ -234,10 +234,10 @@ PointerType *Type::getX86_MMXPtrTy(LLVMContext &C, unsigned AS) {
return getX86_MMXTy(C)->getPointerTo(AS);
}
-PointerType *Type::getX86_AMXPtrTy(LLVMContext &C, unsigned AS) {
- return getX86_AMXTy(C)->getPointerTo(AS);
-}
-
+PointerType *Type::getX86_AMXPtrTy(LLVMContext &C, unsigned AS) {
+ return getX86_AMXTy(C)->getPointerTo(AS);
+}
+
PointerType *Type::getIntNPtrTy(LLVMContext &C, unsigned N, unsigned AS) {
return getIntNTy(C, N)->getPointerTo(AS);
}
@@ -390,18 +390,18 @@ StructType *StructType::get(LLVMContext &Context, ArrayRef<Type*> ETypes,
return ST;
}
-bool StructType::containsScalableVectorType() const {
- for (Type *Ty : elements()) {
- if (isa<ScalableVectorType>(Ty))
- return true;
- if (auto *STy = dyn_cast<StructType>(Ty))
- if (STy->containsScalableVectorType())
- return true;
- }
-
- return false;
-}
-
+bool StructType::containsScalableVectorType() const {
+ for (Type *Ty : elements()) {
+ if (isa<ScalableVectorType>(Ty))
+ return true;
+ if (auto *STy = dyn_cast<StructType>(Ty))
+ if (STy->containsScalableVectorType())
+ return true;
+ }
+
+ return false;
+}
+
void StructType::setBody(ArrayRef<Type*> Elements, bool isPacked) {
assert(isOpaque() && "Struct body already set!");
@@ -521,14 +521,14 @@ bool StructType::isSized(SmallPtrSetImpl<Type*> *Visited) const {
// Okay, our struct is sized if all of the elements are, but if one of the
// elements is opaque, the struct isn't sized *yet*, but may become sized in
// the future, so just bail out without caching.
- for (Type *Ty : elements()) {
- // If the struct contains a scalable vector type, don't consider it sized.
- // This prevents it from being used in loads/stores/allocas/GEPs.
- if (isa<ScalableVectorType>(Ty))
+ for (Type *Ty : elements()) {
+ // If the struct contains a scalable vector type, don't consider it sized.
+ // This prevents it from being used in loads/stores/allocas/GEPs.
+ if (isa<ScalableVectorType>(Ty))
+ return false;
+ if (!Ty->isSized(Visited))
return false;
- if (!Ty->isSized(Visited))
- return false;
- }
+ }
// Here we cheat a bit and cast away const-ness. The goal is to memoize when
// we find a sized type, as types can only move from opaque to sized, not the
@@ -548,7 +548,7 @@ StringRef StructType::getName() const {
bool StructType::isValidElementType(Type *ElemTy) {
return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
!ElemTy->isMetadataTy() && !ElemTy->isFunctionTy() &&
- !ElemTy->isTokenTy();
+ !ElemTy->isTokenTy();
}
bool StructType::isLayoutIdentical(StructType *Other) const {
@@ -580,10 +580,10 @@ bool StructType::indexValid(const Value *V) const {
return CU && CU->getZExtValue() < getNumElements();
}
-StructType *StructType::getTypeByName(LLVMContext &C, StringRef Name) {
- return C.pImpl->NamedStructTypes.lookup(Name);
-}
-
+StructType *StructType::getTypeByName(LLVMContext &C, StringRef Name) {
+ return C.pImpl->NamedStructTypes.lookup(Name);
+}
+
//===----------------------------------------------------------------------===//
// ArrayType Implementation
//===----------------------------------------------------------------------===//
@@ -625,10 +625,10 @@ VectorType::VectorType(Type *ElType, unsigned EQ, Type::TypeID TID)
}
VectorType *VectorType::get(Type *ElementType, ElementCount EC) {
- if (EC.isScalable())
- return ScalableVectorType::get(ElementType, EC.getKnownMinValue());
+ if (EC.isScalable())
+ return ScalableVectorType::get(ElementType, EC.getKnownMinValue());
else
- return FixedVectorType::get(ElementType, EC.getKnownMinValue());
+ return FixedVectorType::get(ElementType, EC.getKnownMinValue());
}
bool VectorType::isValidElementType(Type *ElemTy) {
@@ -646,7 +646,7 @@ FixedVectorType *FixedVectorType::get(Type *ElementType, unsigned NumElts) {
"be an integer, floating point, or "
"pointer type.");
- auto EC = ElementCount::getFixed(NumElts);
+ auto EC = ElementCount::getFixed(NumElts);
LLVMContextImpl *pImpl = ElementType->getContext().pImpl;
VectorType *&Entry = ElementType->getContext()
@@ -668,7 +668,7 @@ ScalableVectorType *ScalableVectorType::get(Type *ElementType,
"be an integer, floating point, or "
"pointer type.");
- auto EC = ElementCount::getScalable(MinNumElts);
+ auto EC = ElementCount::getScalable(MinNumElts);
LLVMContextImpl *pImpl = ElementType->getContext().pImpl;
VectorType *&Entry = ElementType->getContext()
diff --git a/contrib/libs/llvm12/lib/IR/Use.cpp b/contrib/libs/llvm12/lib/IR/Use.cpp
index 7e326871f6..99049c0232 100644
--- a/contrib/libs/llvm12/lib/IR/Use.cpp
+++ b/contrib/libs/llvm12/lib/IR/Use.cpp
@@ -17,17 +17,17 @@ void Use::swap(Use &RHS) {
if (Val == RHS.Val)
return;
- std::swap(Val, RHS.Val);
- std::swap(Next, RHS.Next);
- std::swap(Prev, RHS.Prev);
+ std::swap(Val, RHS.Val);
+ std::swap(Next, RHS.Next);
+ std::swap(Prev, RHS.Prev);
- *Prev = this;
- if (Next)
- Next->Prev = &Next;
+ *Prev = this;
+ if (Next)
+ Next->Prev = &Next;
- *RHS.Prev = &RHS;
- if (RHS.Next)
- RHS.Next->Prev = &RHS.Next;
+ *RHS.Prev = &RHS;
+ if (RHS.Next)
+ RHS.Next->Prev = &RHS.Next;
}
unsigned Use::getOperandNo() const {
diff --git a/contrib/libs/llvm12/lib/IR/User.cpp b/contrib/libs/llvm12/lib/IR/User.cpp
index e5f77136ac..9105c6fbd2 100644
--- a/contrib/libs/llvm12/lib/IR/User.cpp
+++ b/contrib/libs/llvm12/lib/IR/User.cpp
@@ -29,7 +29,7 @@ void User::replaceUsesOfWith(Value *From, Value *To) {
// The side effects of this setOperand call include linking to
// "To", adding "this" to the uses list of To, and
// most importantly, removing "this" from the use list of "From".
- setOperand(i, To);
+ setOperand(i, To);
}
}
diff --git a/contrib/libs/llvm12/lib/IR/Value.cpp b/contrib/libs/llvm12/lib/IR/Value.cpp
index 6f1256b4c7..572f37a324 100644
--- a/contrib/libs/llvm12/lib/IR/Value.cpp
+++ b/contrib/libs/llvm12/lib/IR/Value.cpp
@@ -51,9 +51,9 @@ static inline Type *checkType(Type *Ty) {
}
Value::Value(Type *ty, unsigned scid)
- : VTy(checkType(ty)), UseList(nullptr), SubclassID(scid), HasValueHandle(0),
- SubclassOptionalData(0), SubclassData(0), NumUserOperands(0),
- IsUsedByMD(false), HasName(false), HasMetadata(false) {
+ : VTy(checkType(ty)), UseList(nullptr), SubclassID(scid), HasValueHandle(0),
+ SubclassOptionalData(0), SubclassData(0), NumUserOperands(0),
+ IsUsedByMD(false), HasName(false), HasMetadata(false) {
static_assert(ConstantFirstVal == 0, "!(SubclassID < ConstantFirstVal)");
// FIXME: Why isn't this in the subclass gunk??
// Note, we cannot call isa<CallInst> before the CallInst has been
@@ -77,10 +77,10 @@ Value::~Value() {
if (isUsedByMetadata())
ValueAsMetadata::handleDeletion(this);
- // Remove associated metadata from context.
- if (HasMetadata)
- clearMetadata();
-
+ // Remove associated metadata from context.
+ if (HasMetadata)
+ clearMetadata();
+
#ifndef NDEBUG // Only in -g mode...
// Check to make sure that there are no uses of this value that are still
// around when the value is destroyed. If there are, then we have a dangling
@@ -151,14 +151,14 @@ bool Value::hasNUsesOrMore(unsigned N) const {
return hasNItemsOrMore(use_begin(), use_end(), N);
}
-bool Value::hasOneUser() const {
- if (use_empty())
- return false;
- if (hasOneUse())
- return true;
- return std::equal(++user_begin(), user_end(), user_begin());
-}
-
+bool Value::hasOneUser() const {
+ if (use_empty())
+ return false;
+ if (hasOneUse())
+ return true;
+ return std::equal(++user_begin(), user_end(), user_begin());
+}
+
static bool isUnDroppableUser(const User *U) { return !U->isDroppable(); }
Use *Value::getSingleUndroppableUse() {
@@ -187,36 +187,36 @@ void Value::dropDroppableUses(
for (Use &U : uses())
if (U.getUser()->isDroppable() && ShouldDrop(&U))
ToBeEdited.push_back(&U);
- for (Use *U : ToBeEdited)
- dropDroppableUse(*U);
-}
-
-void Value::dropDroppableUsesIn(User &Usr) {
- assert(Usr.isDroppable() && "Expected a droppable user!");
- for (Use &UsrOp : Usr.operands()) {
- if (UsrOp.get() == this)
- dropDroppableUse(UsrOp);
+ for (Use *U : ToBeEdited)
+ dropDroppableUse(*U);
+}
+
+void Value::dropDroppableUsesIn(User &Usr) {
+ assert(Usr.isDroppable() && "Expected a droppable user!");
+ for (Use &UsrOp : Usr.operands()) {
+ if (UsrOp.get() == this)
+ dropDroppableUse(UsrOp);
}
}
-void Value::dropDroppableUse(Use &U) {
- U.removeFromList();
- if (auto *Assume = dyn_cast<IntrinsicInst>(U.getUser())) {
- assert(Assume->getIntrinsicID() == Intrinsic::assume);
- unsigned OpNo = U.getOperandNo();
- if (OpNo == 0)
- U.set(ConstantInt::getTrue(Assume->getContext()));
- else {
- U.set(UndefValue::get(U.get()->getType()));
- CallInst::BundleOpInfo &BOI = Assume->getBundleOpInfoForOperand(OpNo);
- BOI.Tag = Assume->getContext().pImpl->getOrInsertBundleTag("ignore");
- }
- return;
- }
-
- llvm_unreachable("unkown droppable use");
-}
-
+void Value::dropDroppableUse(Use &U) {
+ U.removeFromList();
+ if (auto *Assume = dyn_cast<IntrinsicInst>(U.getUser())) {
+ assert(Assume->getIntrinsicID() == Intrinsic::assume);
+ unsigned OpNo = U.getOperandNo();
+ if (OpNo == 0)
+ U.set(ConstantInt::getTrue(Assume->getContext()));
+ else {
+ U.set(UndefValue::get(U.get()->getType()));
+ CallInst::BundleOpInfo &BOI = Assume->getBundleOpInfoForOperand(OpNo);
+ BOI.Tag = Assume->getContext().pImpl->getOrInsertBundleTag("ignore");
+ }
+ return;
+ }
+
+ llvm_unreachable("unkown droppable use");
+}
+
bool Value::isUsedInBasicBlock(const BasicBlock *BB) const {
// This can be computed either by scanning the instructions in BB, or by
// scanning the use list of this Value. Both lists can be very long, but
@@ -430,18 +430,18 @@ void Value::takeName(Value *V) {
ST->reinsertValue(this);
}
-#ifndef NDEBUG
-std::string Value::getNameOrAsOperand() const {
- if (!getName().empty())
- return std::string(getName());
-
- std::string BBName;
- raw_string_ostream OS(BBName);
- printAsOperand(OS, false);
- return OS.str();
-}
-#endif
-
+#ifndef NDEBUG
+std::string Value::getNameOrAsOperand() const {
+ if (!getName().empty())
+ return std::string(getName());
+
+ std::string BBName;
+ raw_string_ostream OS(BBName);
+ printAsOperand(OS, false);
+ return OS.str();
+}
+#endif
+
void Value::assertModuleIsMaterializedImpl() const {
#ifndef NDEBUG
const GlobalValue *GV = dyn_cast<GlobalValue>(this);
@@ -728,16 +728,16 @@ uint64_t Value::getPointerDereferenceableBytes(const DataLayout &DL,
CanBeNull = false;
if (const Argument *A = dyn_cast<Argument>(this)) {
DerefBytes = A->getDereferenceableBytes();
- if (DerefBytes == 0) {
- // Handle byval/byref/inalloca/preallocated arguments
- if (Type *ArgMemTy = A->getPointeeInMemoryValueType()) {
- if (ArgMemTy->isSized()) {
- // FIXME: Why isn't this the type alloc size?
- DerefBytes = DL.getTypeStoreSize(ArgMemTy).getKnownMinSize();
- }
- }
+ if (DerefBytes == 0) {
+ // Handle byval/byref/inalloca/preallocated arguments
+ if (Type *ArgMemTy = A->getPointeeInMemoryValueType()) {
+ if (ArgMemTy->isSized()) {
+ // FIXME: Why isn't this the type alloc size?
+ DerefBytes = DL.getTypeStoreSize(ArgMemTy).getKnownMinSize();
+ }
+ }
}
-
+
if (DerefBytes == 0) {
DerefBytes = A->getDereferenceableOrNullBytes();
CanBeNull = true;
@@ -825,7 +825,7 @@ Align Value::getPointerAlignment(const DataLayout &DL) const {
const MaybeAlign Alignment = A->getParamAlign();
if (!Alignment && A->hasStructRetAttr()) {
// An sret parameter has at least the ABI alignment of the return type.
- Type *EltTy = A->getParamStructRetType();
+ Type *EltTy = A->getParamStructRetType();
if (EltTy->isSized())
return DL.getABITypeAlign(EltTy);
}
diff --git a/contrib/libs/llvm12/lib/IR/Verifier.cpp b/contrib/libs/llvm12/lib/IR/Verifier.cpp
index 71152f7176..6dd299ee98 100644
--- a/contrib/libs/llvm12/lib/IR/Verifier.cpp
+++ b/contrib/libs/llvm12/lib/IR/Verifier.cpp
@@ -115,11 +115,11 @@
using namespace llvm;
-static cl::opt<bool> VerifyNoAliasScopeDomination(
- "verify-noalias-scope-decl-dom", cl::Hidden, cl::init(false),
- cl::desc("Ensure that llvm.experimental.noalias.scope.decl for identical "
- "scopes are not dominating"));
-
+static cl::opt<bool> VerifyNoAliasScopeDomination(
+ "verify-noalias-scope-decl-dom", cl::Hidden, cl::init(false),
+ cl::desc("Ensure that llvm.experimental.noalias.scope.decl for identical "
+ "scopes are not dominating"));
+
namespace llvm {
struct VerifierSupport {
@@ -287,9 +287,9 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
/// Whether the current function has a DISubprogram attached to it.
bool HasDebugInfo = false;
- /// The current source language.
- dwarf::SourceLanguage CurrentSourceLang = dwarf::DW_LANG_lo_user;
-
+ /// The current source language.
+ dwarf::SourceLanguage CurrentSourceLang = dwarf::DW_LANG_lo_user;
+
/// Whether source was present on the first DIFile encountered in each CU.
DenseMap<const DICompileUnit *, bool> HasSourceDebugInfo;
@@ -318,8 +318,8 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
TBAAVerifier TBAAVerifyHelper;
- SmallVector<IntrinsicInst *, 4> NoAliasScopeDecls;
-
+ SmallVector<IntrinsicInst *, 4> NoAliasScopeDecls;
+
void checkAtomicMemAccessSize(Type *Ty, const Instruction *I);
public:
@@ -367,8 +367,8 @@ public:
LandingPadResultTy = nullptr;
SawFrameEscape = false;
SiblingFuncletInfo.clear();
- verifyNoAliasScopeDecl();
- NoAliasScopeDecls.clear();
+ verifyNoAliasScopeDecl();
+ NoAliasScopeDecls.clear();
return !Broken;
}
@@ -436,7 +436,7 @@ private:
void visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty);
void visitDereferenceableMetadata(Instruction &I, MDNode *MD);
void visitProfMetadata(Instruction &I, MDNode *MD);
- void visitAnnotationMetadata(MDNode *Annotation);
+ void visitAnnotationMetadata(MDNode *Annotation);
template <class Ty> bool isValidMetadataArray(const MDTuple &N);
#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N);
@@ -545,9 +545,9 @@ private:
/// Verify all-or-nothing property of DIFile source attribute within a CU.
void verifySourceDebugInfo(const DICompileUnit &U, const DIFile &F);
-
- /// Verify the llvm.experimental.noalias.scope.decl declarations
- void verifyNoAliasScopeDecl();
+
+ /// Verify the llvm.experimental.noalias.scope.decl declarations
+ void verifyNoAliasScopeDecl();
};
} // end anonymous namespace
@@ -603,8 +603,8 @@ void Verifier::visitGlobalValue(const GlobalValue &GV) {
Assert(!GV.isDSOLocal(),
"GlobalValue with DLLImport Storage is dso_local!", &GV);
- Assert((GV.isDeclaration() &&
- (GV.hasExternalLinkage() || GV.hasExternalWeakLinkage())) ||
+ Assert((GV.isDeclaration() &&
+ (GV.hasExternalLinkage() || GV.hasExternalWeakLinkage())) ||
GV.hasAvailableExternallyLinkage(),
"Global is marked as dllimport, but not external", &GV);
}
@@ -714,16 +714,16 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) {
}
// Scalable vectors cannot be global variables, since we don't know
- // the runtime size. If the global is an array containing scalable vectors,
- // that will be caught by the isValidElementType methods in StructType or
- // ArrayType instead.
+ // the runtime size. If the global is an array containing scalable vectors,
+ // that will be caught by the isValidElementType methods in StructType or
+ // ArrayType instead.
Assert(!isa<ScalableVectorType>(GV.getValueType()),
"Globals cannot contain scalable vectors", &GV);
- if (auto *STy = dyn_cast<StructType>(GV.getValueType()))
- Assert(!STy->containsScalableVectorType(),
- "Globals cannot contain scalable vectors", &GV);
-
+ if (auto *STy = dyn_cast<StructType>(GV.getValueType()))
+ Assert(!STy->containsScalableVectorType(),
+ "Globals cannot contain scalable vectors", &GV);
+
if (!GV.hasInitializer()) {
visitGlobalValue(GV);
return;
@@ -913,9 +913,9 @@ void Verifier::visitDIScope(const DIScope &N) {
void Verifier::visitDISubrange(const DISubrange &N) {
AssertDI(N.getTag() == dwarf::DW_TAG_subrange_type, "invalid tag", &N);
- bool HasAssumedSizedArraySupport = dwarf::isFortran(CurrentSourceLang);
- AssertDI(HasAssumedSizedArraySupport || N.getRawCountNode() ||
- N.getRawUpperBound(),
+ bool HasAssumedSizedArraySupport = dwarf::isFortran(CurrentSourceLang);
+ AssertDI(HasAssumedSizedArraySupport || N.getRawCountNode() ||
+ N.getRawUpperBound(),
"Subrange must contain count or upperBound", &N);
AssertDI(!N.getRawCountNode() || !N.getRawUpperBound(),
"Subrange can have any one of count or upperBound", &N);
@@ -941,43 +941,43 @@ void Verifier::visitDISubrange(const DISubrange &N) {
"Stride must be signed constant or DIVariable or DIExpression", &N);
}
-void Verifier::visitDIGenericSubrange(const DIGenericSubrange &N) {
- AssertDI(N.getTag() == dwarf::DW_TAG_generic_subrange, "invalid tag", &N);
- AssertDI(N.getRawCountNode() || N.getRawUpperBound(),
- "GenericSubrange must contain count or upperBound", &N);
- AssertDI(!N.getRawCountNode() || !N.getRawUpperBound(),
- "GenericSubrange can have any one of count or upperBound", &N);
- auto *CBound = N.getRawCountNode();
- AssertDI(!CBound || isa<DIVariable>(CBound) || isa<DIExpression>(CBound),
- "Count must be signed constant or DIVariable or DIExpression", &N);
- auto *LBound = N.getRawLowerBound();
- AssertDI(LBound, "GenericSubrange must contain lowerBound", &N);
- AssertDI(isa<DIVariable>(LBound) || isa<DIExpression>(LBound),
- "LowerBound must be signed constant or DIVariable or DIExpression",
- &N);
- auto *UBound = N.getRawUpperBound();
- AssertDI(!UBound || isa<DIVariable>(UBound) || isa<DIExpression>(UBound),
- "UpperBound must be signed constant or DIVariable or DIExpression",
- &N);
- auto *Stride = N.getRawStride();
- AssertDI(Stride, "GenericSubrange must contain stride", &N);
- AssertDI(isa<DIVariable>(Stride) || isa<DIExpression>(Stride),
- "Stride must be signed constant or DIVariable or DIExpression", &N);
-}
-
+void Verifier::visitDIGenericSubrange(const DIGenericSubrange &N) {
+ AssertDI(N.getTag() == dwarf::DW_TAG_generic_subrange, "invalid tag", &N);
+ AssertDI(N.getRawCountNode() || N.getRawUpperBound(),
+ "GenericSubrange must contain count or upperBound", &N);
+ AssertDI(!N.getRawCountNode() || !N.getRawUpperBound(),
+ "GenericSubrange can have any one of count or upperBound", &N);
+ auto *CBound = N.getRawCountNode();
+ AssertDI(!CBound || isa<DIVariable>(CBound) || isa<DIExpression>(CBound),
+ "Count must be signed constant or DIVariable or DIExpression", &N);
+ auto *LBound = N.getRawLowerBound();
+ AssertDI(LBound, "GenericSubrange must contain lowerBound", &N);
+ AssertDI(isa<DIVariable>(LBound) || isa<DIExpression>(LBound),
+ "LowerBound must be signed constant or DIVariable or DIExpression",
+ &N);
+ auto *UBound = N.getRawUpperBound();
+ AssertDI(!UBound || isa<DIVariable>(UBound) || isa<DIExpression>(UBound),
+ "UpperBound must be signed constant or DIVariable or DIExpression",
+ &N);
+ auto *Stride = N.getRawStride();
+ AssertDI(Stride, "GenericSubrange must contain stride", &N);
+ AssertDI(isa<DIVariable>(Stride) || isa<DIExpression>(Stride),
+ "Stride must be signed constant or DIVariable or DIExpression", &N);
+}
+
void Verifier::visitDIEnumerator(const DIEnumerator &N) {
AssertDI(N.getTag() == dwarf::DW_TAG_enumerator, "invalid tag", &N);
}
void Verifier::visitDIBasicType(const DIBasicType &N) {
AssertDI(N.getTag() == dwarf::DW_TAG_base_type ||
- N.getTag() == dwarf::DW_TAG_unspecified_type ||
- N.getTag() == dwarf::DW_TAG_string_type,
+ N.getTag() == dwarf::DW_TAG_unspecified_type ||
+ N.getTag() == dwarf::DW_TAG_string_type,
"invalid tag", &N);
-}
-
-void Verifier::visitDIStringType(const DIStringType &N) {
- AssertDI(N.getTag() == dwarf::DW_TAG_string_type, "invalid tag", &N);
+}
+
+void Verifier::visitDIStringType(const DIStringType &N) {
+ AssertDI(N.getTag() == dwarf::DW_TAG_string_type, "invalid tag", &N);
AssertDI(!(N.isBigEndian() && N.isLittleEndian()) ,
"has conflicting flags", &N);
}
@@ -1079,21 +1079,21 @@ void Verifier::visitDICompositeType(const DICompositeType &N) {
AssertDI(N.getTag() == dwarf::DW_TAG_array_type,
"dataLocation can only appear in array type");
}
-
- if (N.getRawAssociated()) {
- AssertDI(N.getTag() == dwarf::DW_TAG_array_type,
- "associated can only appear in array type");
- }
-
- if (N.getRawAllocated()) {
- AssertDI(N.getTag() == dwarf::DW_TAG_array_type,
- "allocated can only appear in array type");
- }
-
- if (N.getRawRank()) {
- AssertDI(N.getTag() == dwarf::DW_TAG_array_type,
- "rank can only appear in array type");
- }
+
+ if (N.getRawAssociated()) {
+ AssertDI(N.getTag() == dwarf::DW_TAG_array_type,
+ "associated can only appear in array type");
+ }
+
+ if (N.getRawAllocated()) {
+ AssertDI(N.getTag() == dwarf::DW_TAG_array_type,
+ "allocated can only appear in array type");
+ }
+
+ if (N.getRawRank()) {
+ AssertDI(N.getTag() == dwarf::DW_TAG_array_type,
+ "rank can only appear in array type");
+ }
}
void Verifier::visitDISubroutineType(const DISubroutineType &N) {
@@ -1143,8 +1143,8 @@ void Verifier::visitDICompileUnit(const DICompileUnit &N) {
AssertDI(!N.getFile()->getFilename().empty(), "invalid filename", &N,
N.getFile());
- CurrentSourceLang = (dwarf::SourceLanguage)N.getSourceLanguage();
-
+ CurrentSourceLang = (dwarf::SourceLanguage)N.getSourceLanguage();
+
verifySourceDebugInfo(N, *N.getFile());
AssertDI((N.getEmissionKind() <= DICompileUnit::LastEmissionKind),
@@ -1586,8 +1586,8 @@ void Verifier::visitModuleFlagCGProfileEntry(const MDOperand &MDO) {
if (!FuncMDO)
return;
auto F = dyn_cast<ValueAsMetadata>(FuncMDO);
- Assert(F && isa<Function>(F->getValue()->stripPointerCasts()),
- "expected a Function or null", FuncMDO);
+ Assert(F && isa<Function>(F->getValue()->stripPointerCasts()),
+ "expected a Function or null", FuncMDO);
};
auto Node = dyn_cast_or_null<MDNode>(MDO);
Assert(Node && Node->getNumOperands() == 3, "expected a MDNode triple", MDO);
@@ -1605,7 +1605,7 @@ static bool isFuncOnlyAttr(Attribute::AttrKind Kind) {
case Attribute::NoReturn:
case Attribute::NoSync:
case Attribute::WillReturn:
- case Attribute::NoCallback:
+ case Attribute::NoCallback:
case Attribute::NoCfCheck:
case Attribute::NoUnwind:
case Attribute::NoInline:
@@ -1634,7 +1634,7 @@ static bool isFuncOnlyAttr(Attribute::AttrKind Kind) {
case Attribute::Builtin:
case Attribute::NoBuiltin:
case Attribute::Cold:
- case Attribute::Hot:
+ case Attribute::Hot:
case Attribute::OptForFuzzing:
case Attribute::OptimizeNone:
case Attribute::JumpTable:
@@ -1648,8 +1648,8 @@ static bool isFuncOnlyAttr(Attribute::AttrKind Kind) {
case Attribute::Speculatable:
case Attribute::StrictFP:
case Attribute::NullPointerIsValid:
- case Attribute::MustProgress:
- case Attribute::NoProfile:
+ case Attribute::MustProgress:
+ case Attribute::NoProfile:
return true;
default:
break;
@@ -1717,10 +1717,10 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, Type *Ty,
AttrCount += Attrs.hasAttribute(Attribute::StructRet) ||
Attrs.hasAttribute(Attribute::InReg);
AttrCount += Attrs.hasAttribute(Attribute::Nest);
- AttrCount += Attrs.hasAttribute(Attribute::ByRef);
+ AttrCount += Attrs.hasAttribute(Attribute::ByRef);
Assert(AttrCount <= 1,
"Attributes 'byval', 'inalloca', 'preallocated', 'inreg', 'nest', "
- "'byref', and 'sret' are incompatible!",
+ "'byref', and 'sret' are incompatible!",
V);
Assert(!(Attrs.hasAttribute(Attribute::InAlloca) &&
@@ -1775,10 +1775,10 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, Type *Ty,
SmallPtrSet<Type*, 4> Visited;
if (!PTy->getElementType()->isSized(&Visited)) {
Assert(!Attrs.hasAttribute(Attribute::ByVal) &&
- !Attrs.hasAttribute(Attribute::ByRef) &&
- !Attrs.hasAttribute(Attribute::InAlloca) &&
- !Attrs.hasAttribute(Attribute::Preallocated),
- "Attributes 'byval', 'byref', 'inalloca', and 'preallocated' do not "
+ !Attrs.hasAttribute(Attribute::ByRef) &&
+ !Attrs.hasAttribute(Attribute::InAlloca) &&
+ !Attrs.hasAttribute(Attribute::Preallocated),
+ "Attributes 'byval', 'byref', 'inalloca', and 'preallocated' do not "
"support unsized types!",
V);
}
@@ -1787,28 +1787,28 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, Type *Ty,
"Attribute 'swifterror' only applies to parameters "
"with pointer to pointer type!",
V);
-
- if (Attrs.hasAttribute(Attribute::ByRef)) {
- Assert(Attrs.getByRefType() == PTy->getElementType(),
- "Attribute 'byref' type does not match parameter!", V);
- }
-
- if (Attrs.hasAttribute(Attribute::ByVal) && Attrs.getByValType()) {
- Assert(Attrs.getByValType() == PTy->getElementType(),
- "Attribute 'byval' type does not match parameter!", V);
- }
-
- if (Attrs.hasAttribute(Attribute::Preallocated)) {
- Assert(Attrs.getPreallocatedType() == PTy->getElementType(),
- "Attribute 'preallocated' type does not match parameter!", V);
- }
+
+ if (Attrs.hasAttribute(Attribute::ByRef)) {
+ Assert(Attrs.getByRefType() == PTy->getElementType(),
+ "Attribute 'byref' type does not match parameter!", V);
+ }
+
+ if (Attrs.hasAttribute(Attribute::ByVal) && Attrs.getByValType()) {
+ Assert(Attrs.getByValType() == PTy->getElementType(),
+ "Attribute 'byval' type does not match parameter!", V);
+ }
+
+ if (Attrs.hasAttribute(Attribute::Preallocated)) {
+ Assert(Attrs.getPreallocatedType() == PTy->getElementType(),
+ "Attribute 'preallocated' type does not match parameter!", V);
+ }
} else {
Assert(!Attrs.hasAttribute(Attribute::ByVal),
"Attribute 'byval' only applies to parameters with pointer type!",
V);
- Assert(!Attrs.hasAttribute(Attribute::ByRef),
- "Attribute 'byref' only applies to parameters with pointer type!",
- V);
+ Assert(!Attrs.hasAttribute(Attribute::ByRef),
+ "Attribute 'byref' only applies to parameters with pointer type!",
+ V);
Assert(!Attrs.hasAttribute(Attribute::SwiftError),
"Attribute 'swifterror' only applies to parameters "
"with pointer type!",
@@ -1839,11 +1839,11 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
!RetAttrs.hasAttribute(Attribute::Returned) &&
!RetAttrs.hasAttribute(Attribute::InAlloca) &&
!RetAttrs.hasAttribute(Attribute::Preallocated) &&
- !RetAttrs.hasAttribute(Attribute::ByRef) &&
+ !RetAttrs.hasAttribute(Attribute::ByRef) &&
!RetAttrs.hasAttribute(Attribute::SwiftSelf) &&
!RetAttrs.hasAttribute(Attribute::SwiftError)),
- "Attributes 'byval', 'inalloca', 'preallocated', 'byref', "
- "'nest', 'sret', 'nocapture', 'nofree', "
+ "Attributes 'byval', 'inalloca', 'preallocated', 'byref', "
+ "'nest', 'sret', 'nocapture', 'nofree', "
"'returned', 'swiftself', and 'swifterror' do not apply to return "
"values!",
V);
@@ -2177,8 +2177,8 @@ void Verifier::verifyStatepoint(const CallBase &Call) {
Call);
const int NumTransitionArgs =
cast<ConstantInt>(NumTransitionArgsV)->getZExtValue();
- Assert(NumTransitionArgs == 0,
- "gc.statepoint w/inline transition bundle is deprecated", Call);
+ Assert(NumTransitionArgs == 0,
+ "gc.statepoint w/inline transition bundle is deprecated", Call);
const int EndTransitionArgsInx = EndCallArgsInx + 1 + NumTransitionArgs;
const Value *NumDeoptArgsV = Call.getArgOperand(EndTransitionArgsInx + 1);
@@ -2187,12 +2187,12 @@ void Verifier::verifyStatepoint(const CallBase &Call) {
"must be constant integer",
Call);
const int NumDeoptArgs = cast<ConstantInt>(NumDeoptArgsV)->getZExtValue();
- Assert(NumDeoptArgs == 0,
- "gc.statepoint w/inline deopt operands is deprecated", Call);
+ Assert(NumDeoptArgs == 0,
+ "gc.statepoint w/inline deopt operands is deprecated", Call);
- const int ExpectedNumArgs = 7 + NumCallArgs;
- Assert(ExpectedNumArgs == (int)Call.arg_size(),
- "gc.statepoint too many arguments", Call);
+ const int ExpectedNumArgs = 7 + NumCallArgs;
+ Assert(ExpectedNumArgs == (int)Call.arg_size(),
+ "gc.statepoint too many arguments", Call);
// Check that the only uses of this gc.statepoint are gc.result or
// gc.relocate calls which are tied to this statepoint and thus part
@@ -2338,11 +2338,11 @@ void Verifier::visitFunction(const Function &F) {
default:
case CallingConv::C:
break;
- case CallingConv::X86_INTR: {
- Assert(F.arg_empty() || Attrs.hasParamAttribute(0, Attribute::ByVal),
- "Calling convention parameter requires byval", &F);
- break;
- }
+ case CallingConv::X86_INTR: {
+ Assert(F.arg_empty() || Attrs.hasParamAttribute(0, Attribute::ByVal),
+ "Calling convention parameter requires byval", &F);
+ break;
+ }
case CallingConv::AMDGPU_KERNEL:
case CallingConv::SPIR_KERNEL:
Assert(F.getReturnType()->isVoidTy(),
@@ -2355,28 +2355,28 @@ void Verifier::visitFunction(const Function &F) {
case CallingConv::AMDGPU_CS:
Assert(!F.hasStructRetAttr(),
"Calling convention does not allow sret", &F);
- if (F.getCallingConv() != CallingConv::SPIR_KERNEL) {
- const unsigned StackAS = DL.getAllocaAddrSpace();
- unsigned i = 0;
- for (const Argument &Arg : F.args()) {
- Assert(!Attrs.hasParamAttribute(i, Attribute::ByVal),
- "Calling convention disallows byval", &F);
- Assert(!Attrs.hasParamAttribute(i, Attribute::Preallocated),
- "Calling convention disallows preallocated", &F);
- Assert(!Attrs.hasParamAttribute(i, Attribute::InAlloca),
- "Calling convention disallows inalloca", &F);
-
- if (Attrs.hasParamAttribute(i, Attribute::ByRef)) {
- // FIXME: Should also disallow LDS and GDS, but we don't have the enum
- // value here.
- Assert(Arg.getType()->getPointerAddressSpace() != StackAS,
- "Calling convention disallows stack byref", &F);
- }
-
- ++i;
- }
- }
-
+ if (F.getCallingConv() != CallingConv::SPIR_KERNEL) {
+ const unsigned StackAS = DL.getAllocaAddrSpace();
+ unsigned i = 0;
+ for (const Argument &Arg : F.args()) {
+ Assert(!Attrs.hasParamAttribute(i, Attribute::ByVal),
+ "Calling convention disallows byval", &F);
+ Assert(!Attrs.hasParamAttribute(i, Attribute::Preallocated),
+ "Calling convention disallows preallocated", &F);
+ Assert(!Attrs.hasParamAttribute(i, Attribute::InAlloca),
+ "Calling convention disallows inalloca", &F);
+
+ if (Attrs.hasParamAttribute(i, Attribute::ByRef)) {
+ // FIXME: Should also disallow LDS and GDS, but we don't have the enum
+ // value here.
+ Assert(Arg.getType()->getPointerAddressSpace() != StackAS,
+ "Calling convention disallows stack byref", &F);
+ }
+
+ ++i;
+ }
+ }
+
LLVM_FALLTHROUGH;
case CallingConv::Fast:
case CallingConv::Cold:
@@ -2479,10 +2479,10 @@ void Verifier::visitFunction(const Function &F) {
"function must have a single !dbg attachment", &F, I.second);
AssertDI(isa<DISubprogram>(I.second),
"function !dbg attachment must be a subprogram", &F, I.second);
- AssertDI(cast<DISubprogram>(I.second)->isDistinct(),
- "function definition may only have a distinct !dbg attachment",
- &F);
-
+ AssertDI(cast<DISubprogram>(I.second)->isDistinct(),
+ "function definition may only have a distinct !dbg attachment",
+ &F);
+
auto *SP = cast<DISubprogram>(I.second);
const Function *&AttachedTo = DISubprogramAttachments[SP];
AssertDI(!AttachedTo || AttachedTo == &F,
@@ -2577,7 +2577,7 @@ void Verifier::visitBasicBlock(BasicBlock &BB) {
// Check constraints that this basic block imposes on all of the PHI nodes in
// it.
if (isa<PHINode>(BB.front())) {
- SmallVector<BasicBlock *, 8> Preds(predecessors(&BB));
+ SmallVector<BasicBlock *, 8> Preds(predecessors(&BB));
SmallVector<std::pair<BasicBlock*, Value*>, 8> Values;
llvm::sort(Preds);
for (const PHINode &PN : BB.phis()) {
@@ -2971,8 +2971,8 @@ void Verifier::visitAddrSpaceCastInst(AddrSpaceCastInst &I) {
Assert(SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace(),
"AddrSpaceCast must be between different address spaces", &I);
if (auto *SrcVTy = dyn_cast<VectorType>(SrcTy))
- Assert(SrcVTy->getElementCount() ==
- cast<VectorType>(DestTy)->getElementCount(),
+ Assert(SrcVTy->getElementCount() ==
+ cast<VectorType>(DestTy)->getElementCount(),
"AddrSpaceCast vector pointer number of elements mismatch", &I);
visitInstruction(I);
}
@@ -3258,19 +3258,19 @@ static bool isTypeCongruent(Type *L, Type *R) {
static AttrBuilder getParameterABIAttributes(int I, AttributeList Attrs) {
static const Attribute::AttrKind ABIAttrs[] = {
- Attribute::StructRet, Attribute::ByVal, Attribute::InAlloca,
- Attribute::InReg, Attribute::SwiftSelf, Attribute::SwiftError,
- Attribute::Preallocated, Attribute::ByRef};
+ Attribute::StructRet, Attribute::ByVal, Attribute::InAlloca,
+ Attribute::InReg, Attribute::SwiftSelf, Attribute::SwiftError,
+ Attribute::Preallocated, Attribute::ByRef};
AttrBuilder Copy;
for (auto AK : ABIAttrs) {
if (Attrs.hasParamAttribute(I, AK))
Copy.addAttribute(AK);
}
-
- // `align` is ABI-affecting only in combination with `byval` or `byref`.
+
+ // `align` is ABI-affecting only in combination with `byval` or `byref`.
if (Attrs.hasParamAttribute(I, Attribute::Alignment) &&
- (Attrs.hasParamAttribute(I, Attribute::ByVal) ||
- Attrs.hasParamAttribute(I, Attribute::ByRef)))
+ (Attrs.hasParamAttribute(I, Attribute::ByVal) ||
+ Attrs.hasParamAttribute(I, Attribute::ByRef)))
Copy.addAlignmentAttr(Attrs.getParamAlignment(I));
return Copy;
}
@@ -3506,7 +3506,7 @@ void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) {
"GEP base pointer is not a vector or a vector of pointers", &GEP);
Assert(GEP.getSourceElementType()->isSized(), "GEP into unsized type!", &GEP);
- SmallVector<Value *, 16> Idxs(GEP.indices());
+ SmallVector<Value *, 16> Idxs(GEP.indices());
Assert(all_of(
Idxs, [](Value* V) { return V->getType()->isIntOrIntVectorTy(); }),
"GEP indexes must be integers", &GEP);
@@ -4291,14 +4291,14 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) {
}
}
-void Verifier::visitAnnotationMetadata(MDNode *Annotation) {
- Assert(isa<MDTuple>(Annotation), "annotation must be a tuple");
- Assert(Annotation->getNumOperands() >= 1,
- "annotation must have at least one operand");
- for (const MDOperand &Op : Annotation->operands())
- Assert(isa<MDString>(Op.get()), "operands must be strings");
-}
-
+void Verifier::visitAnnotationMetadata(MDNode *Annotation) {
+ Assert(isa<MDTuple>(Annotation), "annotation must be a tuple");
+ Assert(Annotation->getNumOperands() >= 1,
+ "annotation must have at least one operand");
+ for (const MDOperand &Op : Annotation->operands())
+ Assert(isa<MDString>(Op.get()), "operands must be strings");
+}
+
/// verifyInstruction - Verify that an instruction is well formed.
///
void Verifier::visitInstruction(Instruction &I) {
@@ -4368,7 +4368,7 @@ void Verifier::visitInstruction(Instruction &I) {
F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void ||
F->getIntrinsicID() == Intrinsic::experimental_patchpoint_i64 ||
F->getIntrinsicID() == Intrinsic::experimental_gc_statepoint ||
- F->getIntrinsicID() == Intrinsic::wasm_rethrow,
+ F->getIntrinsicID() == Intrinsic::wasm_rethrow,
"Cannot invoke an intrinsic other than donothing, patchpoint, "
"statepoint, coro_resume or coro_destroy",
&I);
@@ -4459,9 +4459,9 @@ void Verifier::visitInstruction(Instruction &I) {
if (MDNode *MD = I.getMetadata(LLVMContext::MD_prof))
visitProfMetadata(I, MD);
- if (MDNode *Annotation = I.getMetadata(LLVMContext::MD_annotation))
- visitAnnotationMetadata(Annotation);
-
+ if (MDNode *Annotation = I.getMetadata(LLVMContext::MD_annotation))
+ visitAnnotationMetadata(Annotation);
+
if (MDNode *N = I.getDebugLoc().getAsMDNode()) {
AssertDI(isa<DILocation>(N), "invalid !dbg metadata attachment", &I, N);
visitMDNode(*N, AreDebugLocsAllowed::Yes);
@@ -4548,30 +4548,30 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
"tags must be valid attribute names");
Attribute::AttrKind Kind =
Attribute::getAttrKindFromName(Elem.Tag->getKey());
- unsigned ArgCount = Elem.End - Elem.Begin;
- if (Kind == Attribute::Alignment) {
- Assert(ArgCount <= 3 && ArgCount >= 2,
- "alignment assumptions should have 2 or 3 arguments");
- Assert(Call.getOperand(Elem.Begin)->getType()->isPointerTy(),
- "first argument should be a pointer");
- Assert(Call.getOperand(Elem.Begin + 1)->getType()->isIntegerTy(),
- "second argument should be an integer");
- if (ArgCount == 3)
- Assert(Call.getOperand(Elem.Begin + 2)->getType()->isIntegerTy(),
- "third argument should be an integer if present");
- return;
- }
- Assert(ArgCount <= 2, "to many arguments");
+ unsigned ArgCount = Elem.End - Elem.Begin;
+ if (Kind == Attribute::Alignment) {
+ Assert(ArgCount <= 3 && ArgCount >= 2,
+ "alignment assumptions should have 2 or 3 arguments");
+ Assert(Call.getOperand(Elem.Begin)->getType()->isPointerTy(),
+ "first argument should be a pointer");
+ Assert(Call.getOperand(Elem.Begin + 1)->getType()->isIntegerTy(),
+ "second argument should be an integer");
+ if (ArgCount == 3)
+ Assert(Call.getOperand(Elem.Begin + 2)->getType()->isIntegerTy(),
+ "third argument should be an integer if present");
+ return;
+ }
+ Assert(ArgCount <= 2, "to many arguments");
if (Kind == Attribute::None)
break;
if (Attribute::doesAttrKindHaveArgument(Kind)) {
- Assert(ArgCount == 2, "this attribute should have 2 arguments");
+ Assert(ArgCount == 2, "this attribute should have 2 arguments");
Assert(isa<ConstantInt>(Call.getOperand(Elem.Begin + 1)),
"the second argument should be a constant integral value");
} else if (isFuncOnlyAttr(Kind)) {
- Assert((ArgCount) == 0, "this attribute has no argument");
+ Assert((ArgCount) == 0, "this attribute has no argument");
} else if (!isFuncOrArgAttr(Kind)) {
- Assert((ArgCount) == 1, "this attribute should have one argument");
+ Assert((ArgCount) == 1, "this attribute should have one argument");
}
}
break;
@@ -5010,17 +5010,17 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
case Intrinsic::sadd_sat:
case Intrinsic::uadd_sat:
case Intrinsic::ssub_sat:
- case Intrinsic::usub_sat:
- case Intrinsic::sshl_sat:
- case Intrinsic::ushl_sat: {
+ case Intrinsic::usub_sat:
+ case Intrinsic::sshl_sat:
+ case Intrinsic::ushl_sat: {
Value *Op1 = Call.getArgOperand(0);
Value *Op2 = Call.getArgOperand(1);
Assert(Op1->getType()->isIntOrIntVectorTy(),
- "first operand of [us][add|sub|shl]_sat must be an int type or "
- "vector of ints");
+ "first operand of [us][add|sub|shl]_sat must be an int type or "
+ "vector of ints");
Assert(Op2->getType()->isIntOrIntVectorTy(),
- "second operand of [us][add|sub|shl]_sat must be an int type or "
- "vector of ints");
+ "second operand of [us][add|sub|shl]_sat must be an int type or "
+ "vector of ints");
break;
}
case Intrinsic::smul_fix:
@@ -5073,14 +5073,14 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
Assert(Size % 16 == 0, "bswap must be an even number of bytes", &Call);
break;
}
- case Intrinsic::invariant_start: {
- ConstantInt *InvariantSize = dyn_cast<ConstantInt>(Call.getArgOperand(0));
- Assert(InvariantSize &&
- (!InvariantSize->isNegative() || InvariantSize->isMinusOne()),
- "invariant_start parameter must be -1, 0 or a positive number",
- &Call);
- break;
- }
+ case Intrinsic::invariant_start: {
+ ConstantInt *InvariantSize = dyn_cast<ConstantInt>(Call.getArgOperand(0));
+ Assert(InvariantSize &&
+ (!InvariantSize->isNegative() || InvariantSize->isMinusOne()),
+ "invariant_start parameter must be -1, 0 or a positive number",
+ &Call);
+ break;
+ }
case Intrinsic::matrix_multiply:
case Intrinsic::matrix_transpose:
case Intrinsic::matrix_column_major_load:
@@ -5144,7 +5144,7 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
"Vector element type mismatch of the result and second operand "
"vector!", IF);
- Assert(cast<FixedVectorType>(ResultTy)->getNumElements() ==
+ Assert(cast<FixedVectorType>(ResultTy)->getNumElements() ==
NumRows->getZExtValue() * NumColumns->getZExtValue(),
"Result of a matrix operation does not fit in the returned vector!");
@@ -5154,30 +5154,30 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
break;
}
- case Intrinsic::experimental_vector_insert: {
- VectorType *VecTy = cast<VectorType>(Call.getArgOperand(0)->getType());
- VectorType *SubVecTy = cast<VectorType>(Call.getArgOperand(1)->getType());
-
- Assert(VecTy->getElementType() == SubVecTy->getElementType(),
- "experimental_vector_insert parameters must have the same element "
- "type.",
- &Call);
- break;
- }
- case Intrinsic::experimental_vector_extract: {
- VectorType *ResultTy = cast<VectorType>(Call.getType());
- VectorType *VecTy = cast<VectorType>(Call.getArgOperand(0)->getType());
-
- Assert(ResultTy->getElementType() == VecTy->getElementType(),
- "experimental_vector_extract result must have the same element "
- "type as the input vector.",
- &Call);
- break;
- }
- case Intrinsic::experimental_noalias_scope_decl: {
- NoAliasScopeDecls.push_back(cast<IntrinsicInst>(&Call));
- break;
- }
+ case Intrinsic::experimental_vector_insert: {
+ VectorType *VecTy = cast<VectorType>(Call.getArgOperand(0)->getType());
+ VectorType *SubVecTy = cast<VectorType>(Call.getArgOperand(1)->getType());
+
+ Assert(VecTy->getElementType() == SubVecTy->getElementType(),
+ "experimental_vector_insert parameters must have the same element "
+ "type.",
+ &Call);
+ break;
+ }
+ case Intrinsic::experimental_vector_extract: {
+ VectorType *ResultTy = cast<VectorType>(Call.getType());
+ VectorType *VecTy = cast<VectorType>(Call.getArgOperand(0)->getType());
+
+ Assert(ResultTy->getElementType() == VecTy->getElementType(),
+ "experimental_vector_extract result must have the same element "
+ "type as the input vector.",
+ &Call);
+ break;
+ }
+ case Intrinsic::experimental_noalias_scope_decl: {
+ NoAliasScopeDecls.push_back(cast<IntrinsicInst>(&Call));
+ break;
+ }
};
}
@@ -5254,7 +5254,7 @@ void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) {
Assert(Operand->getType()->isFPOrFPVectorTy(),
"Intrinsic first argument must be floating point", &FPI);
if (auto *OperandT = dyn_cast<VectorType>(Operand->getType())) {
- NumSrcElem = cast<FixedVectorType>(OperandT)->getNumElements();
+ NumSrcElem = cast<FixedVectorType>(OperandT)->getNumElements();
}
Operand = &FPI;
@@ -5263,7 +5263,7 @@ void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) {
Assert(Operand->getType()->isIntOrIntVectorTy(),
"Intrinsic result must be an integer", &FPI);
if (auto *OperandT = dyn_cast<VectorType>(Operand->getType())) {
- Assert(NumSrcElem == cast<FixedVectorType>(OperandT)->getNumElements(),
+ Assert(NumSrcElem == cast<FixedVectorType>(OperandT)->getNumElements(),
"Intrinsic first argument and result vector lengths must be equal",
&FPI);
}
@@ -5277,7 +5277,7 @@ void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) {
Assert(Operand->getType()->isIntOrIntVectorTy(),
"Intrinsic first argument must be integer", &FPI);
if (auto *OperandT = dyn_cast<VectorType>(Operand->getType())) {
- NumSrcElem = cast<FixedVectorType>(OperandT)->getNumElements();
+ NumSrcElem = cast<FixedVectorType>(OperandT)->getNumElements();
}
Operand = &FPI;
@@ -5286,7 +5286,7 @@ void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) {
Assert(Operand->getType()->isFPOrFPVectorTy(),
"Intrinsic result must be a floating point", &FPI);
if (auto *OperandT = dyn_cast<VectorType>(Operand->getType())) {
- Assert(NumSrcElem == cast<FixedVectorType>(OperandT)->getNumElements(),
+ Assert(NumSrcElem == cast<FixedVectorType>(OperandT)->getNumElements(),
"Intrinsic first argument and result vector lengths must be equal",
&FPI);
}
@@ -5305,8 +5305,8 @@ void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) {
Assert(OperandTy->isVectorTy() == ResultTy->isVectorTy(),
"Intrinsic first argument and result disagree on vector use", &FPI);
if (OperandTy->isVectorTy()) {
- Assert(cast<FixedVectorType>(OperandTy)->getNumElements() ==
- cast<FixedVectorType>(ResultTy)->getNumElements(),
+ Assert(cast<FixedVectorType>(OperandTy)->getNumElements() ==
+ cast<FixedVectorType>(ResultTy)->getNumElements(),
"Intrinsic first argument and result vector lengths must be equal",
&FPI);
}
@@ -5528,75 +5528,75 @@ void Verifier::verifySourceDebugInfo(const DICompileUnit &U, const DIFile &F) {
"inconsistent use of embedded source");
}
-void Verifier::verifyNoAliasScopeDecl() {
- if (NoAliasScopeDecls.empty())
- return;
-
- // only a single scope must be declared at a time.
- for (auto *II : NoAliasScopeDecls) {
- assert(II->getIntrinsicID() == Intrinsic::experimental_noalias_scope_decl &&
- "Not a llvm.experimental.noalias.scope.decl ?");
- const auto *ScopeListMV = dyn_cast<MetadataAsValue>(
- II->getOperand(Intrinsic::NoAliasScopeDeclScopeArg));
- Assert(ScopeListMV != nullptr,
- "llvm.experimental.noalias.scope.decl must have a MetadataAsValue "
- "argument",
- II);
-
- const auto *ScopeListMD = dyn_cast<MDNode>(ScopeListMV->getMetadata());
- Assert(ScopeListMD != nullptr, "!id.scope.list must point to an MDNode",
- II);
- Assert(ScopeListMD->getNumOperands() == 1,
- "!id.scope.list must point to a list with a single scope", II);
- }
-
- // Only check the domination rule when requested. Once all passes have been
- // adapted this option can go away.
- if (!VerifyNoAliasScopeDomination)
- return;
-
- // Now sort the intrinsics based on the scope MDNode so that declarations of
- // the same scopes are next to each other.
- auto GetScope = [](IntrinsicInst *II) {
- const auto *ScopeListMV = cast<MetadataAsValue>(
- II->getOperand(Intrinsic::NoAliasScopeDeclScopeArg));
- return &cast<MDNode>(ScopeListMV->getMetadata())->getOperand(0);
- };
-
- // We are sorting on MDNode pointers here. For valid input IR this is ok.
- // TODO: Sort on Metadata ID to avoid non-deterministic error messages.
- auto Compare = [GetScope](IntrinsicInst *Lhs, IntrinsicInst *Rhs) {
- return GetScope(Lhs) < GetScope(Rhs);
- };
-
- llvm::sort(NoAliasScopeDecls, Compare);
-
- // Go over the intrinsics and check that for the same scope, they are not
- // dominating each other.
- auto ItCurrent = NoAliasScopeDecls.begin();
- while (ItCurrent != NoAliasScopeDecls.end()) {
- auto CurScope = GetScope(*ItCurrent);
- auto ItNext = ItCurrent;
- do {
- ++ItNext;
- } while (ItNext != NoAliasScopeDecls.end() &&
- GetScope(*ItNext) == CurScope);
-
- // [ItCurrent, ItNext) represents the declarations for the same scope.
- // Ensure they are not dominating each other.. but only if it is not too
- // expensive.
- if (ItNext - ItCurrent < 32)
- for (auto *I : llvm::make_range(ItCurrent, ItNext))
- for (auto *J : llvm::make_range(ItCurrent, ItNext))
- if (I != J)
- Assert(!DT.dominates(I, J),
- "llvm.experimental.noalias.scope.decl dominates another one "
- "with the same scope",
- I);
- ItCurrent = ItNext;
- }
-}
-
+void Verifier::verifyNoAliasScopeDecl() {
+ if (NoAliasScopeDecls.empty())
+ return;
+
+ // only a single scope must be declared at a time.
+ for (auto *II : NoAliasScopeDecls) {
+ assert(II->getIntrinsicID() == Intrinsic::experimental_noalias_scope_decl &&
+ "Not a llvm.experimental.noalias.scope.decl ?");
+ const auto *ScopeListMV = dyn_cast<MetadataAsValue>(
+ II->getOperand(Intrinsic::NoAliasScopeDeclScopeArg));
+ Assert(ScopeListMV != nullptr,
+ "llvm.experimental.noalias.scope.decl must have a MetadataAsValue "
+ "argument",
+ II);
+
+ const auto *ScopeListMD = dyn_cast<MDNode>(ScopeListMV->getMetadata());
+ Assert(ScopeListMD != nullptr, "!id.scope.list must point to an MDNode",
+ II);
+ Assert(ScopeListMD->getNumOperands() == 1,
+ "!id.scope.list must point to a list with a single scope", II);
+ }
+
+ // Only check the domination rule when requested. Once all passes have been
+ // adapted this option can go away.
+ if (!VerifyNoAliasScopeDomination)
+ return;
+
+ // Now sort the intrinsics based on the scope MDNode so that declarations of
+ // the same scopes are next to each other.
+ auto GetScope = [](IntrinsicInst *II) {
+ const auto *ScopeListMV = cast<MetadataAsValue>(
+ II->getOperand(Intrinsic::NoAliasScopeDeclScopeArg));
+ return &cast<MDNode>(ScopeListMV->getMetadata())->getOperand(0);
+ };
+
+ // We are sorting on MDNode pointers here. For valid input IR this is ok.
+ // TODO: Sort on Metadata ID to avoid non-deterministic error messages.
+ auto Compare = [GetScope](IntrinsicInst *Lhs, IntrinsicInst *Rhs) {
+ return GetScope(Lhs) < GetScope(Rhs);
+ };
+
+ llvm::sort(NoAliasScopeDecls, Compare);
+
+ // Go over the intrinsics and check that for the same scope, they are not
+ // dominating each other.
+ auto ItCurrent = NoAliasScopeDecls.begin();
+ while (ItCurrent != NoAliasScopeDecls.end()) {
+ auto CurScope = GetScope(*ItCurrent);
+ auto ItNext = ItCurrent;
+ do {
+ ++ItNext;
+ } while (ItNext != NoAliasScopeDecls.end() &&
+ GetScope(*ItNext) == CurScope);
+
+ // [ItCurrent, ItNext) represents the declarations for the same scope.
+ // Ensure they are not dominating each other.. but only if it is not too
+ // expensive.
+ if (ItNext - ItCurrent < 32)
+ for (auto *I : llvm::make_range(ItCurrent, ItNext))
+ for (auto *J : llvm::make_range(ItCurrent, ItNext))
+ if (I != J)
+ Assert(!DT.dominates(I, J),
+ "llvm.experimental.noalias.scope.decl dominates another one "
+ "with the same scope",
+ I);
+ ItCurrent = ItNext;
+ }
+}
+
//===----------------------------------------------------------------------===//
// Implement the public interfaces to this file...
//===----------------------------------------------------------------------===//
diff --git a/contrib/libs/llvm12/lib/IR/ya.make b/contrib/libs/llvm12/lib/IR/ya.make
index 0f5f8b0084..5c27c5b009 100644
--- a/contrib/libs/llvm12/lib/IR/ya.make
+++ b/contrib/libs/llvm12/lib/IR/ya.make
@@ -12,11 +12,11 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/Remarks
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/Remarks
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
@@ -30,7 +30,7 @@ NO_UTIL()
SRCS(
AbstractCallSite.cpp
AsmWriter.cpp
- Assumptions.cpp
+ Assumptions.cpp
Attributes.cpp
AutoUpgrade.cpp
BasicBlock.cpp
@@ -74,13 +74,13 @@ SRCS(
PassManager.cpp
PassRegistry.cpp
PassTimingInfo.cpp
- PrintPasses.cpp
+ PrintPasses.cpp
ProfileSummary.cpp
- PseudoProbe.cpp
- ReplaceConstant.cpp
+ PseudoProbe.cpp
+ ReplaceConstant.cpp
SafepointIRVerifier.cpp
Statepoint.cpp
- StructuralHash.cpp
+ StructuralHash.cpp
Type.cpp
TypeFinder.cpp
Use.cpp
diff --git a/contrib/libs/llvm12/lib/IRReader/IRReader.cpp b/contrib/libs/llvm12/lib/IRReader/IRReader.cpp
index 152a0a8210..e7fd835f8a 100644
--- a/contrib/libs/llvm12/lib/IRReader/IRReader.cpp
+++ b/contrib/libs/llvm12/lib/IRReader/IRReader.cpp
@@ -24,10 +24,10 @@ namespace llvm {
extern bool TimePassesIsEnabled;
}
-const char TimeIRParsingGroupName[] = "irparse";
-const char TimeIRParsingGroupDescription[] = "LLVM IR Parsing";
-const char TimeIRParsingName[] = "parse";
-const char TimeIRParsingDescription[] = "Parse IR";
+const char TimeIRParsingGroupName[] = "irparse";
+const char TimeIRParsingGroupDescription[] = "LLVM IR Parsing";
+const char TimeIRParsingName[] = "parse";
+const char TimeIRParsingDescription[] = "Parse IR";
std::unique_ptr<Module>
llvm::getLazyIRModule(std::unique_ptr<MemoryBuffer> Buffer, SMDiagnostic &Err,
diff --git a/contrib/libs/llvm12/lib/IRReader/ya.make b/contrib/libs/llvm12/lib/IRReader/ya.make
index a7c0d5d79a..6ccecf0b7c 100644
--- a/contrib/libs/llvm12/lib/IRReader/ya.make
+++ b/contrib/libs/llvm12/lib/IRReader/ya.make
@@ -12,12 +12,12 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/AsmParser
- contrib/libs/llvm12/lib/Bitcode/Reader
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/AsmParser
+ contrib/libs/llvm12/lib/Bitcode/Reader
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/Linker/IRMover.cpp b/contrib/libs/llvm12/lib/Linker/IRMover.cpp
index 47d818d01b..6a2f84bb48 100644
--- a/contrib/libs/llvm12/lib/Linker/IRMover.cpp
+++ b/contrib/libs/llvm12/lib/Linker/IRMover.cpp
@@ -17,7 +17,7 @@
#include "llvm/IR/GVMaterializer.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/TypeFinder.h"
-#include "llvm/Object/ModuleSymbolTable.h"
+#include "llvm/Object/ModuleSymbolTable.h"
#include "llvm/Support/Error.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include <utility>
@@ -250,7 +250,7 @@ Type *TypeMapTy::get(Type *Ty, SmallPtrSet<StructType *, 8> &Visited) {
}
#endif
- if (!Visited.insert(cast<StructType>(Ty)).second) {
+ if (!Visited.insert(cast<StructType>(Ty)).second) {
StructType *DTy = StructType::create(Ty->getContext());
return *Entry = DTy;
}
@@ -571,13 +571,13 @@ Value *IRLinker::materialize(Value *V, bool ForIndirectSymbol) {
if (!SGV)
return nullptr;
- // When linking a global from other modules than source & dest, skip
- // materializing it because it would be mapped later when its containing
- // module is linked. Linking it now would potentially pull in many types that
- // may not be mapped properly.
- if (SGV->getParent() != &DstM && SGV->getParent() != SrcM.get())
- return nullptr;
-
+ // When linking a global from other modules than source & dest, skip
+ // materializing it because it would be mapped later when its containing
+ // module is linked. Linking it now would potentially pull in many types that
+ // may not be mapped properly.
+ if (SGV->getParent() != &DstM && SGV->getParent() != SrcM.get())
+ return nullptr;
+
Expected<Constant *> NewProto = linkGlobalValueProto(SGV, ForIndirectSymbol);
if (!NewProto) {
setError(NewProto.takeError());
@@ -639,14 +639,14 @@ GlobalVariable *IRLinker::copyGlobalVariableProto(const GlobalVariable *SGVar) {
AttributeList IRLinker::mapAttributeTypes(LLVMContext &C, AttributeList Attrs) {
for (unsigned i = 0; i < Attrs.getNumAttrSets(); ++i) {
- for (Attribute::AttrKind TypedAttr :
- {Attribute::ByVal, Attribute::StructRet, Attribute::ByRef}) {
- if (Attrs.hasAttribute(i, TypedAttr)) {
- if (Type *Ty = Attrs.getAttribute(i, TypedAttr).getValueAsType()) {
- Attrs = Attrs.replaceAttributeType(C, i, TypedAttr, TypeMap.get(Ty));
- break;
- }
- }
+ for (Attribute::AttrKind TypedAttr :
+ {Attribute::ByVal, Attribute::StructRet, Attribute::ByRef}) {
+ if (Attrs.hasAttribute(i, TypedAttr)) {
+ if (Type *Ty = Attrs.getAttribute(i, TypedAttr).getValueAsType()) {
+ Attrs = Attrs.replaceAttributeType(C, i, TypedAttr, TypeMap.get(Ty));
+ break;
+ }
+ }
}
}
return Attrs;
@@ -797,11 +797,11 @@ void IRLinker::computeTypeMapping() {
}
auto STTypePrefix = getTypeNamePrefix(ST->getName());
- if (STTypePrefix.size() == ST->getName().size())
+ if (STTypePrefix.size() == ST->getName().size())
continue;
// Check to see if the destination module has a struct with the prefix name.
- StructType *DST = StructType::getTypeByName(ST->getContext(), STTypePrefix);
+ StructType *DST = StructType::getTypeByName(ST->getContext(), STTypePrefix);
if (!DST)
continue;
@@ -843,38 +843,38 @@ static void getArrayElements(const Constant *C,
Expected<Constant *>
IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
const GlobalVariable *SrcGV) {
- // Check that both variables have compatible properties.
- if (DstGV && !DstGV->isDeclaration() && !SrcGV->isDeclaration()) {
- if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage())
- return stringErr(
- "Linking globals named '" + SrcGV->getName() +
- "': can only link appending global with another appending "
- "global!");
-
- if (DstGV->isConstant() != SrcGV->isConstant())
- return stringErr("Appending variables linked with different const'ness!");
-
- if (DstGV->getAlignment() != SrcGV->getAlignment())
- return stringErr(
- "Appending variables with different alignment need to be linked!");
-
- if (DstGV->getVisibility() != SrcGV->getVisibility())
- return stringErr(
- "Appending variables with different visibility need to be linked!");
-
- if (DstGV->hasGlobalUnnamedAddr() != SrcGV->hasGlobalUnnamedAddr())
- return stringErr(
- "Appending variables with different unnamed_addr need to be linked!");
-
- if (DstGV->getSection() != SrcGV->getSection())
- return stringErr(
- "Appending variables with different section name need to be linked!");
- }
-
- // Do not need to do anything if source is a declaration.
- if (SrcGV->isDeclaration())
- return DstGV;
-
+ // Check that both variables have compatible properties.
+ if (DstGV && !DstGV->isDeclaration() && !SrcGV->isDeclaration()) {
+ if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage())
+ return stringErr(
+ "Linking globals named '" + SrcGV->getName() +
+ "': can only link appending global with another appending "
+ "global!");
+
+ if (DstGV->isConstant() != SrcGV->isConstant())
+ return stringErr("Appending variables linked with different const'ness!");
+
+ if (DstGV->getAlignment() != SrcGV->getAlignment())
+ return stringErr(
+ "Appending variables with different alignment need to be linked!");
+
+ if (DstGV->getVisibility() != SrcGV->getVisibility())
+ return stringErr(
+ "Appending variables with different visibility need to be linked!");
+
+ if (DstGV->hasGlobalUnnamedAddr() != SrcGV->hasGlobalUnnamedAddr())
+ return stringErr(
+ "Appending variables with different unnamed_addr need to be linked!");
+
+ if (DstGV->getSection() != SrcGV->getSection())
+ return stringErr(
+ "Appending variables with different section name need to be linked!");
+ }
+
+ // Do not need to do anything if source is a declaration.
+ if (SrcGV->isDeclaration())
+ return DstGV;
+
Type *EltTy = cast<ArrayType>(TypeMap.get(SrcGV->getValueType()))
->getElementType();
@@ -900,7 +900,7 @@ IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
}
uint64_t DstNumElements = 0;
- if (DstGV && !DstGV->isDeclaration()) {
+ if (DstGV && !DstGV->isDeclaration()) {
ArrayType *DstTy = cast<ArrayType>(DstGV->getValueType());
DstNumElements = DstTy->getNumElements();
@@ -913,7 +913,7 @@ IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
getArrayElements(SrcGV->getInitializer(), SrcElements);
if (IsNewStructor) {
- erase_if(SrcElements, [this](Constant *E) {
+ erase_if(SrcElements, [this](Constant *E) {
auto *Key =
dyn_cast<GlobalValue>(E->getAggregateElement(2)->stripPointerCasts());
if (!Key)
@@ -936,10 +936,10 @@ IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
Constant *Ret = ConstantExpr::getBitCast(NG, TypeMap.get(SrcGV->getType()));
- Mapper.scheduleMapAppendingVariable(
- *NG,
- (DstGV && !DstGV->isDeclaration()) ? DstGV->getInitializer() : nullptr,
- IsOldStructor, SrcElements);
+ Mapper.scheduleMapAppendingVariable(
+ *NG,
+ (DstGV && !DstGV->isDeclaration()) ? DstGV->getInitializer() : nullptr,
+ IsOldStructor, SrcElements);
// Replace any uses of the two global variables with uses of the new
// global.
@@ -992,7 +992,7 @@ Expected<Constant *> IRLinker::linkGlobalValueProto(GlobalValue *SGV,
DGV = nullptr;
// Handle the ultra special appending linkage case first.
- if (SGV->hasAppendingLinkage() || (DGV && DGV->hasAppendingLinkage()))
+ if (SGV->hasAppendingLinkage() || (DGV && DGV->hasAppendingLinkage()))
return linkAppendingVarProto(cast_or_null<GlobalVariable>(DGV),
cast<GlobalVariable>(SGV));
@@ -1132,13 +1132,13 @@ void IRLinker::prepareCompileUnitsForImport() {
assert(CU && "Expected valid compile unit");
// Enums, macros, and retained types don't need to be listed on the
// imported DICompileUnit. This means they will only be imported
- // if reached from the mapped IR.
- CU->replaceEnumTypes(nullptr);
- CU->replaceMacros(nullptr);
- CU->replaceRetainedTypes(nullptr);
-
+ // if reached from the mapped IR.
+ CU->replaceEnumTypes(nullptr);
+ CU->replaceMacros(nullptr);
+ CU->replaceRetainedTypes(nullptr);
+
// The original definition (or at least its debug info - if the variable is
- // internalized and optimized away) will remain in the source module, so
+ // internalized and optimized away) will remain in the source module, so
// there's no need to import them.
// If LLVM ever does more advanced optimizations on global variables
// (removing/localizing write operations, for instance) that can track
@@ -1146,7 +1146,7 @@ void IRLinker::prepareCompileUnitsForImport() {
// with care when it comes to debug info size. Emitting small CUs containing
// only a few imported entities into every destination module may be very
// size inefficient.
- CU->replaceGlobalVariables(nullptr);
+ CU->replaceGlobalVariables(nullptr);
// Imported entities only need to be mapped in if they have local
// scope, as those might correspond to an imported entity inside a
@@ -1179,7 +1179,7 @@ void IRLinker::prepareCompileUnitsForImport() {
else
// If there were no local scope imported entities, we can map
// the whole list to nullptr.
- CU->replaceImportedEntities(nullptr);
+ CU->replaceImportedEntities(nullptr);
}
}
}
@@ -1438,7 +1438,7 @@ Error IRLinker::run() {
if (!SrcM->getTargetTriple().empty()&&
!SrcTriple.isCompatibleWith(DstTriple))
- emitWarning("Linking two modules of different target triples: '" +
+ emitWarning("Linking two modules of different target triples: '" +
SrcM->getModuleIdentifier() + "' is '" +
SrcM->getTargetTriple() + "' whereas '" +
DstM.getModuleIdentifier() + "' is '" + DstM.getTargetTriple() +
@@ -1476,24 +1476,24 @@ Error IRLinker::run() {
// are properly remapped.
linkNamedMDNodes();
- if (!IsPerformingImport && !SrcM->getModuleInlineAsm().empty()) {
- // Append the module inline asm string.
- DstM.appendModuleInlineAsm(adjustInlineAsm(SrcM->getModuleInlineAsm(),
- SrcTriple));
- } else if (IsPerformingImport) {
- // Import any symver directives for symbols in DstM.
- ModuleSymbolTable::CollectAsmSymvers(*SrcM,
- [&](StringRef Name, StringRef Alias) {
- if (DstM.getNamedValue(Name)) {
- SmallString<256> S(".symver ");
- S += Name;
- S += ", ";
- S += Alias;
- DstM.appendModuleInlineAsm(S);
- }
- });
- }
-
+ if (!IsPerformingImport && !SrcM->getModuleInlineAsm().empty()) {
+ // Append the module inline asm string.
+ DstM.appendModuleInlineAsm(adjustInlineAsm(SrcM->getModuleInlineAsm(),
+ SrcTriple));
+ } else if (IsPerformingImport) {
+ // Import any symver directives for symbols in DstM.
+ ModuleSymbolTable::CollectAsmSymvers(*SrcM,
+ [&](StringRef Name, StringRef Alias) {
+ if (DstM.getNamedValue(Name)) {
+ SmallString<256> S(".symver ");
+ S += Name;
+ S += ", ";
+ S += Alias;
+ DstM.appendModuleInlineAsm(S);
+ }
+ });
+ }
+
// Merge the module flags into the DstM module.
return linkModuleFlagsMetadata();
}
diff --git a/contrib/libs/llvm12/lib/Linker/LinkModules.cpp b/contrib/libs/llvm12/lib/Linker/LinkModules.cpp
index 06ca3d5d0f..98793c5873 100644
--- a/contrib/libs/llvm12/lib/Linker/LinkModules.cpp
+++ b/contrib/libs/llvm12/lib/Linker/LinkModules.cpp
@@ -248,7 +248,7 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,
}
// We always have to add Src if it has appending linkage.
- if (Src.hasAppendingLinkage() || Dest.hasAppendingLinkage()) {
+ if (Src.hasAppendingLinkage() || Dest.hasAppendingLinkage()) {
LinkFromSrc = true;
return false;
}
diff --git a/contrib/libs/llvm12/lib/Linker/ya.make b/contrib/libs/llvm12/lib/Linker/ya.make
index 20123be4ac..7dc901efba 100644
--- a/contrib/libs/llvm12/lib/Linker/ya.make
+++ b/contrib/libs/llvm12/lib/Linker/ya.make
@@ -12,12 +12,12 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Transforms/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Transforms/Utils
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/MC/ELFObjectWriter.cpp b/contrib/libs/llvm12/lib/MC/ELFObjectWriter.cpp
index 43a9121893..2d810ffd35 100644
--- a/contrib/libs/llvm12/lib/MC/ELFObjectWriter.cpp
+++ b/contrib/libs/llvm12/lib/MC/ELFObjectWriter.cpp
@@ -464,7 +464,7 @@ void ELFWriter::writeHeader(const MCAssembler &Asm) {
uint64_t ELFWriter::SymbolValue(const MCSymbol &Sym,
const MCAsmLayout &Layout) {
- if (Sym.isCommon())
+ if (Sym.isCommon())
return Sym.getCommonAlignment();
uint64_t Res;
@@ -1024,13 +1024,13 @@ void ELFWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
}
if (Section.getFlags() & ELF::SHF_LINK_ORDER) {
- // If the value in the associated metadata is not a definition, Sym will be
- // undefined. Represent this with sh_link=0.
+ // If the value in the associated metadata is not a definition, Sym will be
+ // undefined. Represent this with sh_link=0.
const MCSymbol *Sym = Section.getLinkedToSymbol();
- if (Sym && Sym->isInSection()) {
- const MCSectionELF *Sec = cast<MCSectionELF>(&Sym->getSection());
- sh_link = SectionIndexMap.lookup(Sec);
- }
+ if (Sym && Sym->isInSection()) {
+ const MCSectionELF *Sec = cast<MCSectionELF>(&Sym->getSection());
+ sh_link = SectionIndexMap.lookup(Sec);
+ }
}
WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getName()),
@@ -1258,9 +1258,9 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) {
// The presence of symbol versions causes undefined symbols and
// versions declared with @@@ to be renamed.
- for (const MCAssembler::Symver &S : Asm.Symvers) {
- StringRef AliasName = S.Name;
- const auto &Symbol = cast<MCSymbolELF>(*S.Sym);
+ for (const MCAssembler::Symver &S : Asm.Symvers) {
+ StringRef AliasName = S.Name;
+ const auto &Symbol = cast<MCSymbolELF>(*S.Sym);
size_t Pos = AliasName.find('@');
assert(Pos != StringRef::npos);
@@ -1279,7 +1279,7 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
// Aliases defined with .symvar copy the binding from the symbol they alias.
// This is the first place we are able to copy this information.
Alias->setBinding(Symbol.getBinding());
- Alias->setVisibility(Symbol.getVisibility());
+ Alias->setVisibility(Symbol.getVisibility());
Alias->setOther(Symbol.getOther());
if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
@@ -1287,14 +1287,14 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
if (Symbol.isUndefined() && Rest.startswith("@@") &&
!Rest.startswith("@@@")) {
- Asm.getContext().reportError(S.Loc, "default version symbol " +
- AliasName + " must be defined");
+ Asm.getContext().reportError(S.Loc, "default version symbol " +
+ AliasName + " must be defined");
continue;
}
if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) {
- Asm.getContext().reportError(S.Loc, Twine("multiple versions for ") +
- Symbol.getName());
+ Asm.getContext().reportError(S.Loc, Twine("multiple versions for ") +
+ Symbol.getName());
continue;
}
@@ -1392,22 +1392,22 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
if (C != 0)
return true;
- // gold<2.34 incorrectly ignored the addend for R_386_GOTOFF (9)
- // (http://sourceware.org/PR16794).
- if (TargetObjectWriter->getEMachine() == ELF::EM_386 &&
- Type == ELF::R_386_GOTOFF)
+ // gold<2.34 incorrectly ignored the addend for R_386_GOTOFF (9)
+ // (http://sourceware.org/PR16794).
+ if (TargetObjectWriter->getEMachine() == ELF::EM_386 &&
+ Type == ELF::R_386_GOTOFF)
+ return true;
+
+ // ld.lld handles R_MIPS_HI16/R_MIPS_LO16 separately, not as a whole, so
+ // it doesn't know that an R_MIPS_HI16 with implicit addend 1 and an
+ // R_MIPS_LO16 with implicit addend -32768 represents 32768, which is in
+ // range of a MergeInputSection. We could introduce a new RelExpr member
+ // (like R_RISCV_PC_INDIRECT for R_RISCV_PCREL_HI20 / R_RISCV_PCREL_LO12)
+ // but the complexity is unnecessary given that GNU as keeps the original
+ // symbol for this case as well.
+ if (TargetObjectWriter->getEMachine() == ELF::EM_MIPS &&
+ !hasRelocationAddend())
return true;
-
- // ld.lld handles R_MIPS_HI16/R_MIPS_LO16 separately, not as a whole, so
- // it doesn't know that an R_MIPS_HI16 with implicit addend 1 and an
- // R_MIPS_LO16 with implicit addend -32768 represents 32768, which is in
- // range of a MergeInputSection. We could introduce a new RelExpr member
- // (like R_RISCV_PC_INDIRECT for R_RISCV_PCREL_HI20 / R_RISCV_PCREL_LO12)
- // but the complexity is unnecessary given that GNU as keeps the original
- // symbol for this case as well.
- if (TargetObjectWriter->getEMachine() == ELF::EM_MIPS &&
- !hasRelocationAddend())
- return true;
}
// Most TLS relocations use a got, so they need the symbol. Even those that
diff --git a/contrib/libs/llvm12/lib/MC/MCAsmBackend.cpp b/contrib/libs/llvm12/lib/MC/MCAsmBackend.cpp
index 2c4ab96363..0d32e71c2d 100644
--- a/contrib/libs/llvm12/lib/MC/MCAsmBackend.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCAsmBackend.cpp
@@ -54,17 +54,17 @@ std::unique_ptr<MCObjectWriter>
MCAsmBackend::createDwoObjectWriter(raw_pwrite_stream &OS,
raw_pwrite_stream &DwoOS) const {
auto TW = createObjectTargetWriter();
- switch (TW->getFormat()) {
- case Triple::ELF:
- return createELFDwoObjectWriter(
- cast<MCELFObjectTargetWriter>(std::move(TW)), OS, DwoOS,
- Endian == support::little);
- case Triple::Wasm:
- return createWasmDwoObjectWriter(
- cast<MCWasmObjectTargetWriter>(std::move(TW)), OS, DwoOS);
- default:
- report_fatal_error("dwo only supported with ELF and Wasm");
- }
+ switch (TW->getFormat()) {
+ case Triple::ELF:
+ return createELFDwoObjectWriter(
+ cast<MCELFObjectTargetWriter>(std::move(TW)), OS, DwoOS,
+ Endian == support::little);
+ case Triple::Wasm:
+ return createWasmDwoObjectWriter(
+ cast<MCWasmObjectTargetWriter>(std::move(TW)), OS, DwoOS);
+ default:
+ report_fatal_error("dwo only supported with ELF and Wasm");
+ }
}
Optional<MCFixupKind> MCAsmBackend::getFixupKind(StringRef Name) const {
diff --git a/contrib/libs/llvm12/lib/MC/MCAsmInfo.cpp b/contrib/libs/llvm12/lib/MC/MCAsmInfo.cpp
index 0ed9b1ec26..620d3e7cff 100644
--- a/contrib/libs/llvm12/lib/MC/MCAsmInfo.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCAsmInfo.cpp
@@ -28,12 +28,12 @@ static cl::opt<DefaultOnOff> DwarfExtendedLoc(
clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")),
cl::init(Default));
-cl::opt<cl::boolOrDefault> UseLEB128Directives(
- "use-leb128-directives", cl::Hidden,
- cl::desc(
- "Disable the usage of LEB128 directives, and generate .byte instead."),
- cl::init(cl::BOU_UNSET));
-
+cl::opt<cl::boolOrDefault> UseLEB128Directives(
+ "use-leb128-directives", cl::Hidden,
+ cl::desc(
+ "Disable the usage of LEB128 directives, and generate .byte instead."),
+ cl::init(cl::BOU_UNSET));
+
MCAsmInfo::MCAsmInfo() {
SeparatorString = ";";
CommentString = "#";
@@ -57,8 +57,8 @@ MCAsmInfo::MCAsmInfo() {
WeakDirective = "\t.weak\t";
if (DwarfExtendedLoc != Default)
SupportsExtendedDwarfLocDirective = DwarfExtendedLoc == Enable;
- if (UseLEB128Directives != cl::BOU_UNSET)
- HasLEB128Directives = UseLEB128Directives == cl::BOU_TRUE;
+ if (UseLEB128Directives != cl::BOU_UNSET)
+ HasLEB128Directives = UseLEB128Directives == cl::BOU_TRUE;
// FIXME: Clang's logic should be synced with the logic used to initialize
// this member and the two implementations should be merged.
@@ -109,7 +109,7 @@ MCAsmInfo::getExprForFDESymbol(const MCSymbol *Sym,
}
bool MCAsmInfo::isAcceptableChar(char C) const {
- return isAlnum(C) || C == '_' || C == '$' || C == '.' || C == '@';
+ return isAlnum(C) || C == '_' || C == '$' || C == '.' || C == '@';
}
bool MCAsmInfo::isValidUnquotedName(StringRef Name) const {
diff --git a/contrib/libs/llvm12/lib/MC/MCAsmInfoXCOFF.cpp b/contrib/libs/llvm12/lib/MC/MCAsmInfoXCOFF.cpp
index 5674478681..2f8bc6a49b 100644
--- a/contrib/libs/llvm12/lib/MC/MCAsmInfoXCOFF.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCAsmInfoXCOFF.cpp
@@ -8,12 +8,12 @@
#include "llvm/MC/MCAsmInfoXCOFF.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/CommandLine.h"
using namespace llvm;
-extern cl::opt<cl::boolOrDefault> UseLEB128Directives;
-
+extern cl::opt<cl::boolOrDefault> UseLEB128Directives;
+
void MCAsmInfoXCOFF::anchor() {}
MCAsmInfoXCOFF::MCAsmInfoXCOFF() {
@@ -23,14 +23,14 @@ MCAsmInfoXCOFF::MCAsmInfoXCOFF() {
PrivateLabelPrefix = "L..";
SupportsQuotedNames = false;
UseDotAlignForAlignment = true;
- if (UseLEB128Directives == cl::BOU_UNSET)
- HasLEB128Directives = false;
+ if (UseLEB128Directives == cl::BOU_UNSET)
+ HasLEB128Directives = false;
ZeroDirective = "\t.space\t";
ZeroDirectiveSupportsNonZeroValue = false;
AsciiDirective = nullptr; // not supported
AscizDirective = nullptr; // not supported
- ByteListDirective = "\t.byte\t";
- CharacterLiteralSyntax = ACLS_SingleQuotePrefix;
+ ByteListDirective = "\t.byte\t";
+ CharacterLiteralSyntax = ACLS_SingleQuotePrefix;
// Use .vbyte for data definition to avoid directives that apply an implicit
// alignment.
@@ -42,8 +42,8 @@ MCAsmInfoXCOFF::MCAsmInfoXCOFF() {
HasDotTypeDotSizeDirective = false;
UseIntegratedAssembler = false;
NeedsFunctionDescriptors = true;
-
- ExceptionsType = ExceptionHandling::AIX;
+
+ ExceptionsType = ExceptionHandling::AIX;
}
bool MCAsmInfoXCOFF::isAcceptableChar(char C) const {
diff --git a/contrib/libs/llvm12/lib/MC/MCAsmMacro.cpp b/contrib/libs/llvm12/lib/MC/MCAsmMacro.cpp
index fe30787b4a..bc95f98f29 100644
--- a/contrib/libs/llvm12/lib/MC/MCAsmMacro.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCAsmMacro.cpp
@@ -38,11 +38,11 @@ void MCAsmMacro::dump(raw_ostream &OS) const {
OS << " ";
P.dump();
}
- if (!Locals.empty()) {
- OS << " Locals:\n";
- for (StringRef L : Locals)
- OS << " " << L << '\n';
- }
+ if (!Locals.empty()) {
+ OS << " Locals:\n";
+ for (StringRef L : Locals)
+ OS << " " << L << '\n';
+ }
OS << " (BEGIN BODY)" << Body << "(END BODY)\n";
}
#endif
diff --git a/contrib/libs/llvm12/lib/MC/MCAsmStreamer.cpp b/contrib/libs/llvm12/lib/MC/MCAsmStreamer.cpp
index cd89aa8557..10d72553fe 100644
--- a/contrib/libs/llvm12/lib/MC/MCAsmStreamer.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCAsmStreamer.cpp
@@ -24,7 +24,7 @@
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectWriter.h"
-#include "llvm/MC/MCPseudoProbe.h"
+#include "llvm/MC/MCPseudoProbe.h"
#include "llvm/MC/MCRegister.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionMachO.h"
@@ -145,11 +145,11 @@ public:
const MCSymbol *Aliasee) override;
void emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;
-
- StringRef getMnemonic(MCInst &MI) override {
- return InstPrinter->getMnemonic(&MI).first;
- }
-
+
+ StringRef getMnemonic(MCInst &MI) override {
+ return InstPrinter->getMnemonic(&MI).first;
+ }
+
void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
void emitAssemblerFlag(MCAssemblerFlag Flag) override;
@@ -351,10 +351,10 @@ public:
void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
- void emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type,
- uint64_t Attr,
- const MCPseudoProbeInlineStack &InlineStack) override;
-
+ void emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type,
+ uint64_t Attr,
+ const MCPseudoProbeInlineStack &InlineStack) override;
+
void emitBundleAlignMode(unsigned AlignPow2) override;
void emitBundleLock(bool AlignToEnd) override;
void emitBundleUnlock() override;
@@ -590,7 +590,7 @@ static const char *getPlatformName(MachO::PlatformType Type) {
case MachO::PLATFORM_IOSSIMULATOR: return "iossimulator";
case MachO::PLATFORM_TVOSSIMULATOR: return "tvossimulator";
case MachO::PLATFORM_WATCHOSSIMULATOR: return "watchossimulator";
- case MachO::PLATFORM_DRIVERKIT: return "driverkit";
+ case MachO::PLATFORM_DRIVERKIT: return "driverkit";
}
llvm_unreachable("Invalid Mach-O platform type");
}
@@ -807,12 +807,12 @@ void MCAsmStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym,
OS << ',' << Log2_32(ByteAlignment);
EmitEOL();
-
- // Print symbol's rename (original name contains invalid character(s)) if
- // there is one.
- MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(CsectSym);
- if (XSym->hasRename())
- emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());
+
+ // Print symbol's rename (original name contains invalid character(s)) if
+ // there is one.
+ MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(CsectSym);
+ if (XSym->hasRename())
+ emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());
}
void MCAsmStreamer::emitXCOFFSymbolLinkageWithVisibility(
@@ -851,12 +851,12 @@ void MCAsmStreamer::emitXCOFFSymbolLinkageWithVisibility(
report_fatal_error("unexpected value for Visibility type");
}
EmitEOL();
-
- // Print symbol's rename (original name contains invalid character(s)) if
- // there is one.
- if (cast<MCSymbolXCOFF>(Symbol)->hasRename())
- emitXCOFFRenameDirective(Symbol,
- cast<MCSymbolXCOFF>(Symbol)->getSymbolTableName());
+
+ // Print symbol's rename (original name contains invalid character(s)) if
+ // there is one.
+ if (cast<MCSymbolXCOFF>(Symbol)->hasRename())
+ emitXCOFFRenameDirective(Symbol,
+ cast<MCSymbolXCOFF>(Symbol)->getSymbolTableName());
}
void MCAsmStreamer::emitXCOFFRenameDirective(const MCSymbol *Name,
@@ -897,13 +897,13 @@ void MCAsmStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
OS << ',' << Log2_32(ByteAlignment);
}
EmitEOL();
-
- // Print symbol's rename (original name contains invalid character(s)) if
- // there is one.
- MCSymbolXCOFF *XSym = dyn_cast<MCSymbolXCOFF>(Symbol);
- if (XSym && XSym->hasRename())
- emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());
-
+
+ // Print symbol's rename (original name contains invalid character(s)) if
+ // there is one.
+ MCSymbolXCOFF *XSym = dyn_cast<MCSymbolXCOFF>(Symbol);
+ if (XSym && XSym->hasRename())
+ emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());
+
}
void MCAsmStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
@@ -981,47 +981,47 @@ void MCAsmStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
static inline char toOctal(int X) { return (X&7)+'0'; }
-static void PrintByteList(StringRef Data, raw_ostream &OS,
- MCAsmInfo::AsmCharLiteralSyntax ACLS) {
- assert(!Data.empty() && "Cannot generate an empty list.");
- const auto printCharacterInOctal = [&OS](unsigned char C) {
- OS << '0';
- OS << toOctal(C >> 6);
- OS << toOctal(C >> 3);
- OS << toOctal(C >> 0);
- };
- const auto printOneCharacterFor = [printCharacterInOctal](
- auto printOnePrintingCharacter) {
- return [printCharacterInOctal, printOnePrintingCharacter](unsigned char C) {
- if (isPrint(C)) {
- printOnePrintingCharacter(static_cast<char>(C));
- return;
- }
- printCharacterInOctal(C);
- };
- };
- const auto printCharacterList = [Data, &OS](const auto &printOneCharacter) {
- const auto BeginPtr = Data.begin(), EndPtr = Data.end();
- for (const unsigned char C : make_range(BeginPtr, EndPtr - 1)) {
- printOneCharacter(C);
- OS << ',';
- }
- printOneCharacter(*(EndPtr - 1));
- };
- switch (ACLS) {
- case MCAsmInfo::ACLS_Unknown:
- printCharacterList(printCharacterInOctal);
- return;
- case MCAsmInfo::ACLS_SingleQuotePrefix:
- printCharacterList(printOneCharacterFor([&OS](char C) {
- const char AsmCharLitBuf[2] = {'\'', C};
- OS << StringRef(AsmCharLitBuf, sizeof(AsmCharLitBuf));
- }));
- return;
- }
- llvm_unreachable("Invalid AsmCharLiteralSyntax value!");
-}
-
+static void PrintByteList(StringRef Data, raw_ostream &OS,
+ MCAsmInfo::AsmCharLiteralSyntax ACLS) {
+ assert(!Data.empty() && "Cannot generate an empty list.");
+ const auto printCharacterInOctal = [&OS](unsigned char C) {
+ OS << '0';
+ OS << toOctal(C >> 6);
+ OS << toOctal(C >> 3);
+ OS << toOctal(C >> 0);
+ };
+ const auto printOneCharacterFor = [printCharacterInOctal](
+ auto printOnePrintingCharacter) {
+ return [printCharacterInOctal, printOnePrintingCharacter](unsigned char C) {
+ if (isPrint(C)) {
+ printOnePrintingCharacter(static_cast<char>(C));
+ return;
+ }
+ printCharacterInOctal(C);
+ };
+ };
+ const auto printCharacterList = [Data, &OS](const auto &printOneCharacter) {
+ const auto BeginPtr = Data.begin(), EndPtr = Data.end();
+ for (const unsigned char C : make_range(BeginPtr, EndPtr - 1)) {
+ printOneCharacter(C);
+ OS << ',';
+ }
+ printOneCharacter(*(EndPtr - 1));
+ };
+ switch (ACLS) {
+ case MCAsmInfo::ACLS_Unknown:
+ printCharacterList(printCharacterInOctal);
+ return;
+ case MCAsmInfo::ACLS_SingleQuotePrefix:
+ printCharacterList(printOneCharacterFor([&OS](char C) {
+ const char AsmCharLitBuf[2] = {'\'', C};
+ OS << StringRef(AsmCharLitBuf, sizeof(AsmCharLitBuf));
+ }));
+ return;
+ }
+ llvm_unreachable("Invalid AsmCharLiteralSyntax value!");
+}
+
static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
OS << '"';
@@ -1060,42 +1060,42 @@ void MCAsmStreamer::emitBytes(StringRef Data) {
"Cannot emit contents before setting section!");
if (Data.empty()) return;
- const auto emitAsString = [this](StringRef Data) {
- // If the data ends with 0 and the target supports .asciz, use it, otherwise
- // use .ascii or a byte-list directive
- if (MAI->getAscizDirective() && Data.back() == 0) {
- OS << MAI->getAscizDirective();
- Data = Data.substr(0, Data.size() - 1);
- } else if (LLVM_LIKELY(MAI->getAsciiDirective())) {
- OS << MAI->getAsciiDirective();
- } else if (MAI->getByteListDirective()) {
- OS << MAI->getByteListDirective();
- PrintByteList(Data, OS, MAI->characterLiteralSyntax());
- EmitEOL();
- return true;
+ const auto emitAsString = [this](StringRef Data) {
+ // If the data ends with 0 and the target supports .asciz, use it, otherwise
+ // use .ascii or a byte-list directive
+ if (MAI->getAscizDirective() && Data.back() == 0) {
+ OS << MAI->getAscizDirective();
+ Data = Data.substr(0, Data.size() - 1);
+ } else if (LLVM_LIKELY(MAI->getAsciiDirective())) {
+ OS << MAI->getAsciiDirective();
+ } else if (MAI->getByteListDirective()) {
+ OS << MAI->getByteListDirective();
+ PrintByteList(Data, OS, MAI->characterLiteralSyntax());
+ EmitEOL();
+ return true;
} else {
- return false;
+ return false;
}
-
- PrintQuotedString(Data, OS);
- EmitEOL();
- return true;
- };
-
- if (Data.size() != 1 && emitAsString(Data))
+
+ PrintQuotedString(Data, OS);
+ EmitEOL();
+ return true;
+ };
+
+ if (Data.size() != 1 && emitAsString(Data))
return;
- // Only single byte is provided or no ascii, asciz, or byte-list directives
- // are applicable. Emit as vector of individual 8bits data elements.
- if (MCTargetStreamer *TS = getTargetStreamer()) {
- TS->emitRawBytes(Data);
- return;
+ // Only single byte is provided or no ascii, asciz, or byte-list directives
+ // are applicable. Emit as vector of individual 8bits data elements.
+ if (MCTargetStreamer *TS = getTargetStreamer()) {
+ TS->emitRawBytes(Data);
+ return;
+ }
+ const char *Directive = MAI->getData8bitsDirective();
+ for (const unsigned char C : Data.bytes()) {
+ OS << Directive << (unsigned)C;
+ EmitEOL();
}
- const char *Directive = MAI->getData8bitsDirective();
- for (const unsigned char C : Data.bytes()) {
- OS << Directive << (unsigned)C;
- EmitEOL();
- }
}
void MCAsmStreamer::emitBinaryData(StringRef Data) {
@@ -1883,10 +1883,10 @@ void MCAsmStreamer::EmitWinCFIEndProc(SMLoc Loc) {
}
void MCAsmStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
- MCStreamer::EmitWinCFIFuncletOrFuncEnd(Loc);
-
- OS << "\t.seh_endfunclet";
- EmitEOL();
+ MCStreamer::EmitWinCFIFuncletOrFuncEnd(Loc);
+
+ OS << "\t.seh_endfunclet";
+ EmitEOL();
}
void MCAsmStreamer::EmitWinCFIStartChained(SMLoc Loc) {
@@ -2127,18 +2127,18 @@ void MCAsmStreamer::emitInstruction(const MCInst &Inst,
EmitEOL();
}
-void MCAsmStreamer::emitPseudoProbe(
- uint64_t Guid, uint64_t Index, uint64_t Type, uint64_t Attr,
- const MCPseudoProbeInlineStack &InlineStack) {
- OS << "\t.pseudoprobe\t" << Guid << " " << Index << " " << Type << " "
- << Attr;
- // Emit inline stack like
- // @ GUIDmain:3 @ GUIDCaller:1 @ GUIDDirectCaller:11
- for (const auto &Site : InlineStack)
- OS << " @ " << std::get<0>(Site) << ":" << std::get<1>(Site);
- EmitEOL();
-}
-
+void MCAsmStreamer::emitPseudoProbe(
+ uint64_t Guid, uint64_t Index, uint64_t Type, uint64_t Attr,
+ const MCPseudoProbeInlineStack &InlineStack) {
+ OS << "\t.pseudoprobe\t" << Guid << " " << Index << " " << Type << " "
+ << Attr;
+ // Emit inline stack like
+ // @ GUIDmain:3 @ GUIDCaller:1 @ GUIDDirectCaller:11
+ for (const auto &Site : InlineStack)
+ OS << " @ " << std::get<0>(Site) << ":" << std::get<1>(Site);
+ EmitEOL();
+}
+
void MCAsmStreamer::emitBundleAlignMode(unsigned AlignPow2) {
OS << "\t.bundle_align_mode " << AlignPow2;
EmitEOL();
diff --git a/contrib/libs/llvm12/lib/MC/MCAssembler.cpp b/contrib/libs/llvm12/lib/MC/MCAssembler.cpp
index 6531b3f752..ce296d7faa 100644
--- a/contrib/libs/llvm12/lib/MC/MCAssembler.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCAssembler.cpp
@@ -62,8 +62,8 @@ STATISTIC(EmittedAlignFragments,
"Number of emitted assembler fragments - align");
STATISTIC(EmittedFillFragments,
"Number of emitted assembler fragments - fill");
-STATISTIC(EmittedNopsFragments, "Number of emitted assembler fragments - nops");
-STATISTIC(EmittedOrgFragments, "Number of emitted assembler fragments - org");
+STATISTIC(EmittedNopsFragments, "Number of emitted assembler fragments - nops");
+STATISTIC(EmittedOrgFragments, "Number of emitted assembler fragments - org");
STATISTIC(evaluateFixup, "Number of evaluated fixups");
STATISTIC(FragmentLayouts, "Number of fragment layouts");
STATISTIC(ObjectBytes, "Number of emitted object file bytes");
@@ -312,9 +312,9 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
return Size;
}
- case MCFragment::FT_Nops:
- return cast<MCNopsFragment>(F).getNumBytes();
-
+ case MCFragment::FT_Nops:
+ return cast<MCNopsFragment>(F).getNumBytes();
+
case MCFragment::FT_LEB:
return cast<MCLEBFragment>(F).getContents().size();
@@ -383,8 +383,8 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
return cast<MCCVInlineLineTableFragment>(F).getContents().size();
case MCFragment::FT_CVDefRange:
return cast<MCCVDefRangeFragment>(F).getContents().size();
- case MCFragment::FT_PseudoProbe:
- return cast<MCPseudoProbeAddrFragment>(F).getContents().size();
+ case MCFragment::FT_PseudoProbe:
+ return cast<MCPseudoProbeAddrFragment>(F).getContents().size();
case MCFragment::FT_Dummy:
llvm_unreachable("Should not have been added");
}
@@ -618,45 +618,45 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
break;
}
- case MCFragment::FT_Nops: {
- ++stats::EmittedNopsFragments;
- const MCNopsFragment &NF = cast<MCNopsFragment>(F);
- int64_t NumBytes = NF.getNumBytes();
- int64_t ControlledNopLength = NF.getControlledNopLength();
- int64_t MaximumNopLength = Asm.getBackend().getMaximumNopSize();
-
- assert(NumBytes > 0 && "Expected positive NOPs fragment size");
- assert(ControlledNopLength >= 0 && "Expected non-negative NOP size");
-
- if (ControlledNopLength > MaximumNopLength) {
- Asm.getContext().reportError(NF.getLoc(),
- "illegal NOP size " +
- std::to_string(ControlledNopLength) +
- ". (expected within [0, " +
- std::to_string(MaximumNopLength) + "])");
- // Clamp the NOP length as reportError does not stop the execution
- // immediately.
- ControlledNopLength = MaximumNopLength;
- }
-
- // Use maximum value if the size of each NOP is not specified
- if (!ControlledNopLength)
- ControlledNopLength = MaximumNopLength;
-
- while (NumBytes) {
- uint64_t NumBytesToEmit =
- (uint64_t)std::min(NumBytes, ControlledNopLength);
- assert(NumBytesToEmit && "try to emit empty NOP instruction");
- if (!Asm.getBackend().writeNopData(OS, NumBytesToEmit)) {
- report_fatal_error("unable to write nop sequence of the remaining " +
- Twine(NumBytesToEmit) + " bytes");
- break;
- }
- NumBytes -= NumBytesToEmit;
- }
- break;
- }
-
+ case MCFragment::FT_Nops: {
+ ++stats::EmittedNopsFragments;
+ const MCNopsFragment &NF = cast<MCNopsFragment>(F);
+ int64_t NumBytes = NF.getNumBytes();
+ int64_t ControlledNopLength = NF.getControlledNopLength();
+ int64_t MaximumNopLength = Asm.getBackend().getMaximumNopSize();
+
+ assert(NumBytes > 0 && "Expected positive NOPs fragment size");
+ assert(ControlledNopLength >= 0 && "Expected non-negative NOP size");
+
+ if (ControlledNopLength > MaximumNopLength) {
+ Asm.getContext().reportError(NF.getLoc(),
+ "illegal NOP size " +
+ std::to_string(ControlledNopLength) +
+ ". (expected within [0, " +
+ std::to_string(MaximumNopLength) + "])");
+ // Clamp the NOP length as reportError does not stop the execution
+ // immediately.
+ ControlledNopLength = MaximumNopLength;
+ }
+
+ // Use maximum value if the size of each NOP is not specified
+ if (!ControlledNopLength)
+ ControlledNopLength = MaximumNopLength;
+
+ while (NumBytes) {
+ uint64_t NumBytesToEmit =
+ (uint64_t)std::min(NumBytes, ControlledNopLength);
+ assert(NumBytesToEmit && "try to emit empty NOP instruction");
+ if (!Asm.getBackend().writeNopData(OS, NumBytesToEmit)) {
+ report_fatal_error("unable to write nop sequence of the remaining " +
+ Twine(NumBytesToEmit) + " bytes");
+ break;
+ }
+ NumBytes -= NumBytesToEmit;
+ }
+ break;
+ }
+
case MCFragment::FT_LEB: {
const MCLEBFragment &LF = cast<MCLEBFragment>(F);
OS << LF.getContents();
@@ -706,11 +706,11 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
OS << DRF.getContents();
break;
}
- case MCFragment::FT_PseudoProbe: {
- const MCPseudoProbeAddrFragment &PF = cast<MCPseudoProbeAddrFragment>(F);
- OS << PF.getContents();
- break;
- }
+ case MCFragment::FT_PseudoProbe: {
+ const MCPseudoProbeAddrFragment &PF = cast<MCPseudoProbeAddrFragment>(F);
+ OS << PF.getContents();
+ break;
+ }
case MCFragment::FT_Dummy:
llvm_unreachable("Should not have been added");
}
@@ -761,8 +761,8 @@ void MCAssembler::writeSectionData(raw_ostream &OS, const MCSection *Sec,
assert((cast<MCFillFragment>(F).getValue() == 0) &&
"Invalid fill in virtual section!");
break;
- case MCFragment::FT_Org:
- break;
+ case MCFragment::FT_Org:
+ break;
}
}
@@ -775,8 +775,8 @@ void MCAssembler::writeSectionData(raw_ostream &OS, const MCSection *Sec,
for (const MCFragment &F : *Sec)
writeFragment(OS, *this, Layout, F);
- assert(getContext().hadError() ||
- OS.tell() - Start == Layout.getSectionAddressSize(Sec));
+ assert(getContext().hadError() ||
+ OS.tell() - Start == Layout.getSectionAddressSize(Sec));
}
std::tuple<MCValue, uint64_t, bool>
@@ -922,13 +922,13 @@ void MCAssembler::layout(MCAsmLayout &Layout) {
Contents = DF.getContents();
break;
}
- case MCFragment::FT_PseudoProbe: {
- MCPseudoProbeAddrFragment &PF = cast<MCPseudoProbeAddrFragment>(Frag);
- Fixups = PF.getFixups();
- Contents = PF.getContents();
- break;
+ case MCFragment::FT_PseudoProbe: {
+ MCPseudoProbeAddrFragment &PF = cast<MCPseudoProbeAddrFragment>(Frag);
+ Fixups = PF.getFixups();
+ Contents = PF.getContents();
+ break;
+ }
}
- }
for (const MCFixup &Fixup : Fixups) {
uint64_t FixedValue;
bool IsResolved;
@@ -1119,9 +1119,9 @@ bool MCAssembler::relaxDwarfLineAddr(MCAsmLayout &Layout,
} else {
uint32_t Offset;
uint32_t Size;
- bool SetDelta;
- std::tie(Offset, Size, SetDelta) =
- MCDwarfLineAddr::fixedEncode(Context, LineDelta, AddrDelta, OSE);
+ bool SetDelta;
+ std::tie(Offset, Size, SetDelta) =
+ MCDwarfLineAddr::fixedEncode(Context, LineDelta, AddrDelta, OSE);
// Add Fixups for address delta or new address.
const MCExpr *FixupExpr;
if (SetDelta) {
@@ -1182,27 +1182,27 @@ bool MCAssembler::relaxCVDefRange(MCAsmLayout &Layout,
return OldSize != F.getContents().size();
}
-bool MCAssembler::relaxPseudoProbeAddr(MCAsmLayout &Layout,
- MCPseudoProbeAddrFragment &PF) {
- uint64_t OldSize = PF.getContents().size();
- int64_t AddrDelta;
- bool Abs = PF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, Layout);
- assert(Abs && "We created a pseudo probe with an invalid expression");
- (void)Abs;
- SmallVectorImpl<char> &Data = PF.getContents();
- Data.clear();
- raw_svector_ostream OSE(Data);
- PF.getFixups().clear();
-
- // Relocations should not be needed in general except on RISC-V which we are
- // not targeted for now.
- assert(!getBackend().requiresDiffExpressionRelocations() &&
- "cannot relax relocations");
- // AddrDelta is a signed integer
- encodeSLEB128(AddrDelta, OSE, OldSize);
- return OldSize != Data.size();
-}
-
+bool MCAssembler::relaxPseudoProbeAddr(MCAsmLayout &Layout,
+ MCPseudoProbeAddrFragment &PF) {
+ uint64_t OldSize = PF.getContents().size();
+ int64_t AddrDelta;
+ bool Abs = PF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, Layout);
+ assert(Abs && "We created a pseudo probe with an invalid expression");
+ (void)Abs;
+ SmallVectorImpl<char> &Data = PF.getContents();
+ Data.clear();
+ raw_svector_ostream OSE(Data);
+ PF.getFixups().clear();
+
+ // Relocations should not be needed in general except on RISC-V which we are
+ // not targeted for now.
+ assert(!getBackend().requiresDiffExpressionRelocations() &&
+ "cannot relax relocations");
+ // AddrDelta is a signed integer
+ encodeSLEB128(AddrDelta, OSE, OldSize);
+ return OldSize != Data.size();
+}
+
bool MCAssembler::relaxFragment(MCAsmLayout &Layout, MCFragment &F) {
switch(F.getKind()) {
default:
@@ -1224,8 +1224,8 @@ bool MCAssembler::relaxFragment(MCAsmLayout &Layout, MCFragment &F) {
return relaxCVInlineLineTable(Layout, cast<MCCVInlineLineTableFragment>(F));
case MCFragment::FT_CVDefRange:
return relaxCVDefRange(Layout, cast<MCCVDefRangeFragment>(F));
- case MCFragment::FT_PseudoProbe:
- return relaxPseudoProbeAddr(Layout, cast<MCPseudoProbeAddrFragment>(F));
+ case MCFragment::FT_PseudoProbe:
+ return relaxPseudoProbeAddr(Layout, cast<MCPseudoProbeAddrFragment>(F));
}
}
diff --git a/contrib/libs/llvm12/lib/MC/MCCodeView.cpp b/contrib/libs/llvm12/lib/MC/MCCodeView.cpp
index 3515a69471..3da1a9c3e3 100644
--- a/contrib/libs/llvm12/lib/MC/MCCodeView.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCCodeView.cpp
@@ -563,7 +563,7 @@ void CodeViewContext::encodeInlineLineTable(MCAsmLayout &Layout,
int LineDelta = CurSourceLoc.Line - LastSourceLoc.Line;
unsigned EncodedLineDelta = encodeSignedNumber(LineDelta);
unsigned CodeDelta = computeLabelDiff(Layout, LastLabel, Loc.getLabel());
- if (EncodedLineDelta < 0x8 && CodeDelta <= 0xf) {
+ if (EncodedLineDelta < 0x8 && CodeDelta <= 0xf) {
// The ChangeCodeOffsetAndLineOffset combination opcode is used when the
// encoded line delta uses 3 or fewer set bits and the code offset fits
// in one nibble.
diff --git a/contrib/libs/llvm12/lib/MC/MCContext.cpp b/contrib/libs/llvm12/lib/MC/MCContext.cpp
index 5a5858c9c9..9dab8a6c09 100644
--- a/contrib/libs/llvm12/lib/MC/MCContext.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCContext.cpp
@@ -90,7 +90,7 @@ void MCContext::reset() {
ELFAllocator.DestroyAll();
MachOAllocator.DestroyAll();
XCOFFAllocator.DestroyAll();
- MCInstAllocator.DestroyAll();
+ MCInstAllocator.DestroyAll();
MCSubtargetAllocator.DestroyAll();
InlineAsmUsedLabelNames.clear();
@@ -128,14 +128,14 @@ void MCContext::reset() {
}
//===----------------------------------------------------------------------===//
-// MCInst Management
-//===----------------------------------------------------------------------===//
-
-MCInst *MCContext::createMCInst() {
- return new (MCInstAllocator.Allocate()) MCInst;
-}
-
-//===----------------------------------------------------------------------===//
+// MCInst Management
+//===----------------------------------------------------------------------===//
+
+MCInst *MCContext::createMCInst() {
+ return new (MCInstAllocator.Allocate()) MCInst;
+}
+
+//===----------------------------------------------------------------------===//
// Symbol Manipulation
//===----------------------------------------------------------------------===//
@@ -232,28 +232,28 @@ MCSymbol *MCContext::createSymbol(StringRef Name, bool AlwaysAddSuffix,
llvm_unreachable("Infinite loop");
}
-MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix) {
+MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix) {
+ SmallString<128> NameSV;
+ raw_svector_ostream(NameSV) << MAI->getPrivateGlobalPrefix() << Name;
+ return createSymbol(NameSV, AlwaysAddSuffix, true);
+}
+
+MCSymbol *MCContext::createNamedTempSymbol(const Twine &Name) {
SmallString<128> NameSV;
raw_svector_ostream(NameSV) << MAI->getPrivateGlobalPrefix() << Name;
- return createSymbol(NameSV, AlwaysAddSuffix, true);
+ return createSymbol(NameSV, true, false);
}
-MCSymbol *MCContext::createNamedTempSymbol(const Twine &Name) {
- SmallString<128> NameSV;
- raw_svector_ostream(NameSV) << MAI->getPrivateGlobalPrefix() << Name;
- return createSymbol(NameSV, true, false);
-}
-
MCSymbol *MCContext::createLinkerPrivateTempSymbol() {
SmallString<128> NameSV;
raw_svector_ostream(NameSV) << MAI->getLinkerPrivateGlobalPrefix() << "tmp";
return createSymbol(NameSV, true, false);
}
-MCSymbol *MCContext::createTempSymbol() { return createTempSymbol("tmp"); }
-
-MCSymbol *MCContext::createNamedTempSymbol() {
- return createNamedTempSymbol("tmp");
+MCSymbol *MCContext::createTempSymbol() { return createTempSymbol("tmp"); }
+
+MCSymbol *MCContext::createNamedTempSymbol() {
+ return createNamedTempSymbol("tmp");
}
unsigned MCContext::NextInstance(unsigned LocalLabelVal) {
@@ -274,7 +274,7 @@ MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
unsigned Instance) {
MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)];
if (!Sym)
- Sym = createNamedTempSymbol();
+ Sym = createNamedTempSymbol();
return Sym;
}
@@ -651,7 +651,7 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind,
StringRef CachedName = Entry.first.SectionName;
- MCSymbol *Begin = createSymbol(CachedName, true, false);
+ MCSymbol *Begin = createSymbol(CachedName, true, false);
cast<MCSymbolWasm>(Begin)->setType(wasm::WASM_SYMBOL_TYPE_SECTION);
MCSectionWasm *Result = new (WasmAllocator.Allocate())
@@ -666,22 +666,22 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind,
return Result;
}
-MCSectionXCOFF *
-MCContext::getXCOFFSection(StringRef Section, XCOFF::StorageMappingClass SMC,
- XCOFF::SymbolType Type, SectionKind Kind,
- bool MultiSymbolsAllowed, const char *BeginSymName) {
+MCSectionXCOFF *
+MCContext::getXCOFFSection(StringRef Section, XCOFF::StorageMappingClass SMC,
+ XCOFF::SymbolType Type, SectionKind Kind,
+ bool MultiSymbolsAllowed, const char *BeginSymName) {
// Do the lookup. If we have a hit, return it.
auto IterBool = XCOFFUniquingMap.insert(
std::make_pair(XCOFFSectionKey{Section.str(), SMC}, nullptr));
auto &Entry = *IterBool.first;
- if (!IterBool.second) {
- MCSectionXCOFF *ExistedEntry = Entry.second;
- if (ExistedEntry->isMultiSymbolsAllowed() != MultiSymbolsAllowed)
- report_fatal_error("section's multiply symbols policy does not match");
-
- return ExistedEntry;
- }
-
+ if (!IterBool.second) {
+ MCSectionXCOFF *ExistedEntry = Entry.second;
+ if (ExistedEntry->isMultiSymbolsAllowed() != MultiSymbolsAllowed)
+ report_fatal_error("section's multiply symbols policy does not match");
+
+ return ExistedEntry;
+ }
+
// Otherwise, return a new section.
StringRef CachedName = Entry.first.SectionName;
MCSymbolXCOFF *QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol(
@@ -694,8 +694,8 @@ MCContext::getXCOFFSection(StringRef Section, XCOFF::StorageMappingClass SMC,
// QualName->getUnqualifiedName() and CachedName are the same except when
// CachedName contains invalid character(s) such as '$' for an XCOFF symbol.
MCSectionXCOFF *Result = new (XCOFFAllocator.Allocate())
- MCSectionXCOFF(QualName->getUnqualifiedName(), SMC, Type, Kind, QualName,
- Begin, CachedName, MultiSymbolsAllowed);
+ MCSectionXCOFF(QualName->getUnqualifiedName(), SMC, Type, Kind, QualName,
+ Begin, CachedName, MultiSymbolsAllowed);
Entry.second = Result;
auto *F = new MCDataFragment();
@@ -832,13 +832,13 @@ void MCContext::reportError(SMLoc Loc, const Twine &Msg) {
// If we have a source manager use it. Otherwise, try using the inline source
// manager.
- // If that fails, construct a temporary SourceMgr.
+ // If that fails, construct a temporary SourceMgr.
if (SrcMgr)
SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
else if (InlineSrcMgr)
InlineSrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
else
- SourceMgr().PrintMessage(Loc, SourceMgr::DK_Error, Msg);
+ SourceMgr().PrintMessage(Loc, SourceMgr::DK_Error, Msg);
}
void MCContext::reportWarning(SMLoc Loc, const Twine &Msg) {
diff --git a/contrib/libs/llvm12/lib/MC/MCDisassembler/ya.make b/contrib/libs/llvm12/lib/MC/MCDisassembler/ya.make
index 1f6d2c8654..160728d237 100644
--- a/contrib/libs/llvm12/lib/MC/MCDisassembler/ya.make
+++ b/contrib/libs/llvm12/lib/MC/MCDisassembler/ya.make
@@ -12,9 +12,9 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/MC/MCDwarf.cpp b/contrib/libs/llvm12/lib/MC/MCDwarf.cpp
index fe0c0d6bd4..f86d4266a1 100644
--- a/contrib/libs/llvm12/lib/MC/MCDwarf.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCDwarf.cpp
@@ -46,8 +46,8 @@
using namespace llvm;
MCSymbol *mcdwarf::emitListsTableHeaderStart(MCStreamer &S) {
- MCSymbol *Start = S.getContext().createTempSymbol("debug_list_header_start");
- MCSymbol *End = S.getContext().createTempSymbol("debug_list_header_end");
+ MCSymbol *Start = S.getContext().createTempSymbol("debug_list_header_start");
+ MCSymbol *End = S.getContext().createTempSymbol("debug_list_header_end");
auto DwarfFormat = S.getContext().getDwarfFormat();
if (DwarfFormat == dwarf::DWARF64) {
S.AddComment("DWARF64 mark");
@@ -766,10 +766,10 @@ void MCDwarfLineAddr::Encode(MCContext &Context, MCDwarfLineTableParams Params,
}
}
-std::tuple<uint32_t, uint32_t, bool>
-MCDwarfLineAddr::fixedEncode(MCContext &Context, int64_t LineDelta,
- uint64_t AddrDelta, raw_ostream &OS) {
- uint32_t Offset, Size;
+std::tuple<uint32_t, uint32_t, bool>
+MCDwarfLineAddr::fixedEncode(MCContext &Context, int64_t LineDelta,
+ uint64_t AddrDelta, raw_ostream &OS) {
+ uint32_t Offset, Size;
if (LineDelta != INT64_MAX) {
OS << char(dwarf::DW_LNS_advance_line);
encodeSLEB128(LineDelta, OS);
@@ -789,15 +789,15 @@ MCDwarfLineAddr::fixedEncode(MCContext &Context, int64_t LineDelta,
encodeULEB128(1 + AddrSize, OS);
OS << char(dwarf::DW_LNE_set_address);
// Generate fixup for the address.
- Offset = OS.tell();
- Size = AddrSize;
+ Offset = OS.tell();
+ Size = AddrSize;
SetDelta = false;
OS.write_zeros(AddrSize);
} else {
OS << char(dwarf::DW_LNS_fixed_advance_pc);
// Generate fixup for 2-bytes address delta.
- Offset = OS.tell();
- Size = 2;
+ Offset = OS.tell();
+ Size = 2;
SetDelta = true;
OS << char(0);
OS << char(0);
@@ -811,7 +811,7 @@ MCDwarfLineAddr::fixedEncode(MCContext &Context, int64_t LineDelta,
OS << char(dwarf::DW_LNS_copy);
}
- return std::make_tuple(Offset, Size, SetDelta);
+ return std::make_tuple(Offset, Size, SetDelta);
}
// Utility function to write a tuple for .debug_abbrev.
@@ -1137,7 +1137,7 @@ static MCSymbol *emitGenDwarfRanges(MCStreamer *MCOS) {
MCSymbol *EndSymbol = mcdwarf::emitListsTableHeaderStart(*MCOS);
MCOS->AddComment("Offset entry count");
MCOS->emitInt32(0);
- RangesSymbol = context.createTempSymbol("debug_rnglist0_start");
+ RangesSymbol = context.createTempSymbol("debug_rnglist0_start");
MCOS->emitLabel(RangesSymbol);
for (MCSection *Sec : Sections) {
const MCSymbol *StartSymbol = Sec->getBeginSymbol();
@@ -1154,7 +1154,7 @@ static MCSymbol *emitGenDwarfRanges(MCStreamer *MCOS) {
MCOS->emitLabel(EndSymbol);
} else {
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection());
- RangesSymbol = context.createTempSymbol("debug_ranges_start");
+ RangesSymbol = context.createTempSymbol("debug_ranges_start");
MCOS->emitLabel(RangesSymbol);
for (MCSection *Sec : Sections) {
const MCSymbol *StartSymbol = Sec->getBeginSymbol();
diff --git a/contrib/libs/llvm12/lib/MC/MCELFStreamer.cpp b/contrib/libs/llvm12/lib/MC/MCELFStreamer.cpp
index b2ead90bf8..db45aef7d5 100644
--- a/contrib/libs/llvm12/lib/MC/MCELFStreamer.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCELFStreamer.cpp
@@ -224,31 +224,31 @@ bool MCELFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
break;
case MCSA_Global:
- // For `.weak x; .global x`, GNU as sets the binding to STB_WEAK while we
- // traditionally set the binding to STB_GLOBAL. This is error-prone, so we
- // error on such cases. Note, we also disallow changed binding from .local.
- if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_GLOBAL)
- getContext().reportError(getStartTokLoc(),
- Symbol->getName() +
- " changed binding to STB_GLOBAL");
+ // For `.weak x; .global x`, GNU as sets the binding to STB_WEAK while we
+ // traditionally set the binding to STB_GLOBAL. This is error-prone, so we
+ // error on such cases. Note, we also disallow changed binding from .local.
+ if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_GLOBAL)
+ getContext().reportError(getStartTokLoc(),
+ Symbol->getName() +
+ " changed binding to STB_GLOBAL");
Symbol->setBinding(ELF::STB_GLOBAL);
break;
case MCSA_WeakReference:
case MCSA_Weak:
- // For `.global x; .weak x`, both MC and GNU as set the binding to STB_WEAK.
- // We emit a warning for now but may switch to an error in the future.
- if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_WEAK)
- getContext().reportWarning(
- getStartTokLoc(), Symbol->getName() + " changed binding to STB_WEAK");
+ // For `.global x; .weak x`, both MC and GNU as set the binding to STB_WEAK.
+ // We emit a warning for now but may switch to an error in the future.
+ if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_WEAK)
+ getContext().reportWarning(
+ getStartTokLoc(), Symbol->getName() + " changed binding to STB_WEAK");
Symbol->setBinding(ELF::STB_WEAK);
break;
case MCSA_Local:
- if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_LOCAL)
- getContext().reportError(getStartTokLoc(),
- Symbol->getName() +
- " changed binding to STB_LOCAL");
+ if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_LOCAL)
+ getContext().reportError(getStartTokLoc(),
+ Symbol->getName() +
+ " changed binding to STB_LOCAL");
Symbol->setBinding(ELF::STB_LOCAL);
break;
@@ -304,7 +304,7 @@ void MCELFStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size,
auto *Symbol = cast<MCSymbolELF>(S);
getAssembler().registerSymbol(*Symbol);
- if (!Symbol->isBindingSet())
+ if (!Symbol->isBindingSet())
Symbol->setBinding(ELF::STB_GLOBAL);
Symbol->setType(ELF::STT_OBJECT);
@@ -336,8 +336,8 @@ void MCELFStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
void MCELFStreamer::emitELFSymverDirective(StringRef AliasName,
const MCSymbol *Aliasee) {
- getAssembler().Symvers.push_back(
- MCAssembler::Symver{AliasName, Aliasee, getStartTokLoc()});
+ getAssembler().Symvers.push_back(
+ MCAssembler::Symver{AliasName, Aliasee, getStartTokLoc()});
}
void MCELFStreamer::emitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
@@ -443,18 +443,18 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
- case MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL:
+ case MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL:
case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
case MCSymbolRefExpr::VK_PPC_TLS:
- case MCSymbolRefExpr::VK_PPC_TLS_PCREL:
+ case MCSymbolRefExpr::VK_PPC_TLS_PCREL:
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
- case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL:
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL:
case MCSymbolRefExpr::VK_PPC_TLSGD:
case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
@@ -492,7 +492,7 @@ void MCELFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE) {
// Not a temporary, referece it as a weak undefined.
bool Created;
getAssembler().registerSymbol(*S, &Created);
- if (Created)
+ if (Created)
cast<MCSymbolELF>(S)->setBinding(ELF::STB_WEAK);
}
diff --git a/contrib/libs/llvm12/lib/MC/MCExpr.cpp b/contrib/libs/llvm12/lib/MC/MCExpr.cpp
index 39a9853b75..3b123a46d9 100644
--- a/contrib/libs/llvm12/lib/MC/MCExpr.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCExpr.cpp
@@ -47,8 +47,8 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens) const {
auto Value = cast<MCConstantExpr>(*this).getValue();
auto PrintInHex = cast<MCConstantExpr>(*this).useHexFormat();
auto SizeInBytes = cast<MCConstantExpr>(*this).getSizeInBytes();
- if (Value < 0 && MAI && !MAI->supportsSignedData())
- PrintInHex = true;
+ if (Value < 0 && MAI && !MAI->supportsSignedData())
+ PrintInHex = true;
if (PrintInHex)
switch (SizeInBytes) {
default:
@@ -85,13 +85,13 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens) const {
} else
Sym.print(OS, MAI);
- const MCSymbolRefExpr::VariantKind Kind = SRE.getKind();
- if (Kind != MCSymbolRefExpr::VK_None) {
- if (MAI && MAI->useParensForSymbolVariant()) // ARM
- OS << '(' << MCSymbolRefExpr::getVariantKindName(Kind) << ')';
- else
- OS << '@' << MCSymbolRefExpr::getVariantKindName(Kind);
- }
+ const MCSymbolRefExpr::VariantKind Kind = SRE.getKind();
+ if (Kind != MCSymbolRefExpr::VK_None) {
+ if (MAI && MAI->useParensForSymbolVariant()) // ARM
+ OS << '(' << MCSymbolRefExpr::getVariantKindName(Kind) << ')';
+ else
+ OS << '@' << MCSymbolRefExpr::getVariantKindName(Kind);
+ }
return;
}
@@ -150,7 +150,7 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens) const {
case MCBinaryExpr::Mul: OS << '*'; break;
case MCBinaryExpr::NE: OS << "!="; break;
case MCBinaryExpr::Or: OS << '|'; break;
- case MCBinaryExpr::OrNot: OS << '!'; break;
+ case MCBinaryExpr::OrNot: OS << '!'; break;
case MCBinaryExpr::Shl: OS << "<<"; break;
case MCBinaryExpr::Sub: OS << '-'; break;
case MCBinaryExpr::Xor: OS << '^'; break;
@@ -202,7 +202,7 @@ const MCConstantExpr *MCConstantExpr::create(int64_t Value, MCContext &Ctx,
MCSymbolRefExpr::MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
const MCAsmInfo *MAI, SMLoc Loc)
: MCExpr(MCExpr::SymbolRef, Loc,
- encodeSubclassData(Kind, MAI->hasSubsectionsViaSymbols())),
+ encodeSubclassData(Kind, MAI->hasSubsectionsViaSymbols())),
Symbol(Symbol) {
assert(Symbol);
}
@@ -253,7 +253,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_SIZE: return "SIZE";
case VK_WEAKREF: return "WEAKREF";
case VK_X86_ABS8: return "ABS8";
- case VK_X86_PLTOFF: return "PLTOFF";
+ case VK_X86_PLTOFF: return "PLTOFF";
case VK_ARM_NONE: return "none";
case VK_ARM_GOT_PREL: return "GOT_PREL";
case VK_ARM_TARGET1: return "target1";
@@ -327,18 +327,18 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_PPC_GOT_TLSLD_HA: return "got@tlsld@ha";
case VK_PPC_GOT_PCREL:
return "got@pcrel";
- case VK_PPC_GOT_TLSGD_PCREL:
- return "got@tlsgd@pcrel";
- case VK_PPC_GOT_TLSLD_PCREL:
- return "got@tlsld@pcrel";
- case VK_PPC_GOT_TPREL_PCREL:
- return "got@tprel@pcrel";
- case VK_PPC_TLS_PCREL:
- return "tls@pcrel";
+ case VK_PPC_GOT_TLSGD_PCREL:
+ return "got@tlsgd@pcrel";
+ case VK_PPC_GOT_TLSLD_PCREL:
+ return "got@tlsld@pcrel";
+ case VK_PPC_GOT_TPREL_PCREL:
+ return "got@tprel@pcrel";
+ case VK_PPC_TLS_PCREL:
+ return "tls@pcrel";
case VK_PPC_TLSLD: return "tlsld";
case VK_PPC_LOCAL: return "local";
case VK_PPC_NOTOC: return "notoc";
- case VK_PPC_PCREL_OPT: return "<<invalid>>";
+ case VK_PPC_PCREL_OPT: return "<<invalid>>";
case VK_COFF_IMGREL32: return "IMGREL";
case VK_Hexagon_LO16: return "LO16";
case VK_Hexagon_HI16: return "HI16";
@@ -351,7 +351,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_Hexagon_IE_GOT: return "IEGOT";
case VK_WASM_TYPEINDEX: return "TYPEINDEX";
case VK_WASM_MBREL: return "MBREL";
- case VK_WASM_TLSREL: return "TLSREL";
+ case VK_WASM_TLSREL: return "TLSREL";
case VK_WASM_TBREL: return "TBREL";
case VK_AMDGPU_GOTPCREL32_LO: return "gotpcrel32@lo";
case VK_AMDGPU_GOTPCREL32_HI: return "gotpcrel32@hi";
@@ -411,7 +411,7 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
.Case("secrel32", VK_SECREL)
.Case("size", VK_SIZE)
.Case("abs8", VK_X86_ABS8)
- .Case("pltoff", VK_X86_PLTOFF)
+ .Case("pltoff", VK_X86_PLTOFF)
.Case("l", VK_PPC_LO)
.Case("h", VK_PPC_HI)
.Case("ha", VK_PPC_HA)
@@ -469,10 +469,10 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
.Case("got@tlsld@h", VK_PPC_GOT_TLSLD_HI)
.Case("got@tlsld@ha", VK_PPC_GOT_TLSLD_HA)
.Case("got@pcrel", VK_PPC_GOT_PCREL)
- .Case("got@tlsgd@pcrel", VK_PPC_GOT_TLSGD_PCREL)
- .Case("got@tlsld@pcrel", VK_PPC_GOT_TLSLD_PCREL)
- .Case("got@tprel@pcrel", VK_PPC_GOT_TPREL_PCREL)
- .Case("tls@pcrel", VK_PPC_TLS_PCREL)
+ .Case("got@tlsgd@pcrel", VK_PPC_GOT_TLSGD_PCREL)
+ .Case("got@tlsld@pcrel", VK_PPC_GOT_TLSLD_PCREL)
+ .Case("got@tprel@pcrel", VK_PPC_GOT_TPREL_PCREL)
+ .Case("tls@pcrel", VK_PPC_TLS_PCREL)
.Case("notoc", VK_PPC_NOTOC)
.Case("gdgot", VK_Hexagon_GD_GOT)
.Case("gdplt", VK_Hexagon_GD_PLT)
@@ -493,7 +493,7 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
.Case("typeindex", VK_WASM_TYPEINDEX)
.Case("tbrel", VK_WASM_TBREL)
.Case("mbrel", VK_WASM_MBREL)
- .Case("tlsrel", VK_WASM_TLSREL)
+ .Case("tlsrel", VK_WASM_TLSREL)
.Case("gotpcrel32@lo", VK_AMDGPU_GOTPCREL32_LO)
.Case("gotpcrel32@hi", VK_AMDGPU_GOTPCREL32_HI)
.Case("rel32@lo", VK_AMDGPU_REL32_LO)
@@ -592,7 +592,7 @@ static void AttemptToFoldSymbolOffsetDifference(
if (!Asm->getWriter().isSymbolRefDifferenceFullyResolved(*Asm, A, B, InSet))
return;
- auto FinalizeFolding = [&]() {
+ auto FinalizeFolding = [&]() {
// Pointers to Thumb symbols need to have their low-bit set to allow
// for interworking.
if (Asm->isThumbFunc(&SA))
@@ -606,16 +606,16 @@ static void AttemptToFoldSymbolOffsetDifference(
// Clear the symbol expr pointers to indicate we have folded these
// operands.
A = B = nullptr;
- };
-
- const MCFragment *FA = SA.getFragment();
- const MCFragment *FB = SB.getFragment();
- // If both symbols are in the same fragment, return the difference of their
- // offsets
- if (FA == FB && !SA.isVariable() && !SA.isUnset() && !SB.isVariable() &&
- !SB.isUnset()) {
- Addend += SA.getOffset() - SB.getOffset();
- return FinalizeFolding();
+ };
+
+ const MCFragment *FA = SA.getFragment();
+ const MCFragment *FB = SB.getFragment();
+ // If both symbols are in the same fragment, return the difference of their
+ // offsets
+ if (FA == FB && !SA.isVariable() && !SA.isUnset() && !SB.isVariable() &&
+ !SB.isUnset()) {
+ Addend += SA.getOffset() - SB.getOffset();
+ return FinalizeFolding();
}
const MCSection &SecA = *FA->getParent();
@@ -624,46 +624,46 @@ static void AttemptToFoldSymbolOffsetDifference(
if ((&SecA != &SecB) && !Addrs)
return;
- if (Layout) {
- // One of the symbol involved is part of a fragment being laid out. Quit now
- // to avoid a self loop.
- if (!Layout->canGetFragmentOffset(FA) || !Layout->canGetFragmentOffset(FB))
- return;
-
- // Eagerly evaluate when layout is finalized.
- Addend += Layout->getSymbolOffset(A->getSymbol()) -
- Layout->getSymbolOffset(B->getSymbol());
- if (Addrs && (&SecA != &SecB))
- Addend += (Addrs->lookup(&SecA) - Addrs->lookup(&SecB));
-
- FinalizeFolding();
- } else {
- // When layout is not finalized, our ability to resolve differences between
- // symbols is limited to specific cases where the fragments between two
- // symbols (including the fragments the symbols are defined in) are
- // fixed-size fragments so the difference can be calculated. For example,
- // this is important when the Subtarget is changed and a new MCDataFragment
- // is created in the case of foo: instr; .arch_extension ext; instr .if . -
- // foo.
- if (SA.isVariable() || SA.isUnset() || SB.isVariable() || SB.isUnset() ||
- FA->getKind() != MCFragment::FT_Data ||
- FB->getKind() != MCFragment::FT_Data ||
- FA->getSubsectionNumber() != FB->getSubsectionNumber())
- return;
- // Try to find a constant displacement from FA to FB, add the displacement
- // between the offset in FA of SA and the offset in FB of SB.
- int64_t Displacement = SA.getOffset() - SB.getOffset();
- for (auto FI = FB->getIterator(), FE = SecA.end(); FI != FE; ++FI) {
- if (&*FI == FA) {
- Addend += Displacement;
- return FinalizeFolding();
- }
-
- if (FI->getKind() != MCFragment::FT_Data)
- return;
- Displacement += cast<MCDataFragment>(FI)->getContents().size();
- }
- }
+ if (Layout) {
+ // One of the symbol involved is part of a fragment being laid out. Quit now
+ // to avoid a self loop.
+ if (!Layout->canGetFragmentOffset(FA) || !Layout->canGetFragmentOffset(FB))
+ return;
+
+ // Eagerly evaluate when layout is finalized.
+ Addend += Layout->getSymbolOffset(A->getSymbol()) -
+ Layout->getSymbolOffset(B->getSymbol());
+ if (Addrs && (&SecA != &SecB))
+ Addend += (Addrs->lookup(&SecA) - Addrs->lookup(&SecB));
+
+ FinalizeFolding();
+ } else {
+ // When layout is not finalized, our ability to resolve differences between
+ // symbols is limited to specific cases where the fragments between two
+ // symbols (including the fragments the symbols are defined in) are
+ // fixed-size fragments so the difference can be calculated. For example,
+ // this is important when the Subtarget is changed and a new MCDataFragment
+ // is created in the case of foo: instr; .arch_extension ext; instr .if . -
+ // foo.
+ if (SA.isVariable() || SA.isUnset() || SB.isVariable() || SB.isUnset() ||
+ FA->getKind() != MCFragment::FT_Data ||
+ FB->getKind() != MCFragment::FT_Data ||
+ FA->getSubsectionNumber() != FB->getSubsectionNumber())
+ return;
+ // Try to find a constant displacement from FA to FB, add the displacement
+ // between the offset in FA of SA and the offset in FB of SB.
+ int64_t Displacement = SA.getOffset() - SB.getOffset();
+ for (auto FI = FB->getIterator(), FE = SecA.end(); FI != FE; ++FI) {
+ if (&*FI == FA) {
+ Addend += Displacement;
+ return FinalizeFolding();
+ }
+
+ if (FI->getKind() != MCFragment::FT_Data)
+ return;
+ Displacement += cast<MCDataFragment>(FI)->getContents().size();
+ }
+ }
}
static bool canFold(const MCAssembler *Asm, const MCSymbolRefExpr *A,
@@ -804,30 +804,30 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
case SymbolRef: {
const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this);
const MCSymbol &Sym = SRE->getSymbol();
- const auto Kind = SRE->getKind();
+ const auto Kind = SRE->getKind();
// Evaluate recursively if this is a variable.
- if (Sym.isVariable() && (Kind == MCSymbolRefExpr::VK_None || Layout) &&
+ if (Sym.isVariable() && (Kind == MCSymbolRefExpr::VK_None || Layout) &&
canExpand(Sym, InSet)) {
bool IsMachO = SRE->hasSubsectionsViaSymbols();
if (Sym.getVariableValue()->evaluateAsRelocatableImpl(
Res, Asm, Layout, Fixup, Addrs, InSet || IsMachO)) {
- if (Kind != MCSymbolRefExpr::VK_None) {
- if (Res.isAbsolute()) {
- Res = MCValue::get(SRE, nullptr, 0);
- return true;
- }
- // If the reference has a variant kind, we can only handle expressions
- // which evaluate exactly to a single unadorned symbol. Attach the
- // original VariantKind to SymA of the result.
- if (Res.getRefKind() != MCSymbolRefExpr::VK_None || !Res.getSymA() ||
- Res.getSymB() || Res.getConstant())
- return false;
- Res =
- MCValue::get(MCSymbolRefExpr::create(&Res.getSymA()->getSymbol(),
- Kind, Asm->getContext()),
- Res.getSymB(), Res.getConstant(), Res.getRefKind());
- }
+ if (Kind != MCSymbolRefExpr::VK_None) {
+ if (Res.isAbsolute()) {
+ Res = MCValue::get(SRE, nullptr, 0);
+ return true;
+ }
+ // If the reference has a variant kind, we can only handle expressions
+ // which evaluate exactly to a single unadorned symbol. Attach the
+ // original VariantKind to SymA of the result.
+ if (Res.getRefKind() != MCSymbolRefExpr::VK_None || !Res.getSymA() ||
+ Res.getSymB() || Res.getConstant())
+ return false;
+ Res =
+ MCValue::get(MCSymbolRefExpr::create(&Res.getSymA()->getSymbol(),
+ Kind, Asm->getContext()),
+ Res.getSymB(), Res.getConstant(), Res.getRefKind());
+ }
if (!IsMachO)
return true;
@@ -968,7 +968,7 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
case MCBinaryExpr::Mul: Result = LHS * RHS; break;
case MCBinaryExpr::NE: Result = LHS != RHS; break;
case MCBinaryExpr::Or: Result = LHS | RHS; break;
- case MCBinaryExpr::OrNot: Result = LHS | ~RHS; break;
+ case MCBinaryExpr::OrNot: Result = LHS | ~RHS; break;
case MCBinaryExpr::Shl: Result = uint64_t(LHS) << uint64_t(RHS); break;
case MCBinaryExpr::Sub: Result = LHS - RHS; break;
case MCBinaryExpr::Xor: Result = LHS ^ RHS; break;
diff --git a/contrib/libs/llvm12/lib/MC/MCFragment.cpp b/contrib/libs/llvm12/lib/MC/MCFragment.cpp
index ca90696064..0f8543f510 100644
--- a/contrib/libs/llvm12/lib/MC/MCFragment.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCFragment.cpp
@@ -279,9 +279,9 @@ void MCFragment::destroy() {
case FT_Fill:
delete cast<MCFillFragment>(this);
return;
- case FT_Nops:
- delete cast<MCNopsFragment>(this);
- return;
+ case FT_Nops:
+ delete cast<MCNopsFragment>(this);
+ return;
case FT_Relaxable:
delete cast<MCRelaxableFragment>(this);
return;
@@ -309,9 +309,9 @@ void MCFragment::destroy() {
case FT_CVDefRange:
delete cast<MCCVDefRangeFragment>(this);
return;
- case FT_PseudoProbe:
- delete cast<MCPseudoProbeAddrFragment>(this);
- return;
+ case FT_PseudoProbe:
+ delete cast<MCPseudoProbeAddrFragment>(this);
+ return;
case FT_Dummy:
delete cast<MCDummyFragment>(this);
return;
@@ -342,9 +342,9 @@ LLVM_DUMP_METHOD void MCFragment::dump() const {
case MCFragment::FT_CompactEncodedInst:
OS << "MCCompactEncodedInstFragment"; break;
case MCFragment::FT_Fill: OS << "MCFillFragment"; break;
- case MCFragment::FT_Nops:
- OS << "MCFNopsFragment";
- break;
+ case MCFragment::FT_Nops:
+ OS << "MCFNopsFragment";
+ break;
case MCFragment::FT_Relaxable: OS << "MCRelaxableFragment"; break;
case MCFragment::FT_Org: OS << "MCOrgFragment"; break;
case MCFragment::FT_Dwarf: OS << "MCDwarfFragment"; break;
@@ -354,9 +354,9 @@ LLVM_DUMP_METHOD void MCFragment::dump() const {
case MCFragment::FT_SymbolId: OS << "MCSymbolIdFragment"; break;
case MCFragment::FT_CVInlineLines: OS << "MCCVInlineLineTableFragment"; break;
case MCFragment::FT_CVDefRange: OS << "MCCVDefRangeTableFragment"; break;
- case MCFragment::FT_PseudoProbe:
- OS << "MCPseudoProbe";
- break;
+ case MCFragment::FT_PseudoProbe:
+ OS << "MCPseudoProbe";
+ break;
case MCFragment::FT_Dummy: OS << "MCDummyFragment"; break;
}
@@ -420,12 +420,12 @@ LLVM_DUMP_METHOD void MCFragment::dump() const {
<< " NumValues:" << FF->getNumValues();
break;
}
- case MCFragment::FT_Nops: {
- const auto *NF = cast<MCNopsFragment>(this);
- OS << " NumBytes:" << NF->getNumBytes()
- << " ControlledNopLength:" << NF->getControlledNopLength();
- break;
- }
+ case MCFragment::FT_Nops: {
+ const auto *NF = cast<MCNopsFragment>(this);
+ OS << " NumBytes:" << NF->getNumBytes()
+ << " ControlledNopLength:" << NF->getControlledNopLength();
+ break;
+ }
case MCFragment::FT_Relaxable: {
const auto *F = cast<MCRelaxableFragment>(this);
OS << "\n ";
@@ -490,12 +490,12 @@ LLVM_DUMP_METHOD void MCFragment::dump() const {
}
break;
}
- case MCFragment::FT_PseudoProbe: {
- const auto *OF = cast<MCPseudoProbeAddrFragment>(this);
- OS << "\n ";
- OS << " AddrDelta:" << OF->getAddrDelta();
- break;
- }
+ case MCFragment::FT_PseudoProbe: {
+ const auto *OF = cast<MCPseudoProbeAddrFragment>(this);
+ OS << "\n ";
+ OS << " AddrDelta:" << OF->getAddrDelta();
+ break;
+ }
case MCFragment::FT_Dummy:
break;
}
diff --git a/contrib/libs/llvm12/lib/MC/MCObjectFileInfo.cpp b/contrib/libs/llvm12/lib/MC/MCObjectFileInfo.cpp
index 23761956ca..398de873fe 100644
--- a/contrib/libs/llvm12/lib/MC/MCObjectFileInfo.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCObjectFileInfo.cpp
@@ -497,10 +497,10 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
Ctx->getELFSection(".eh_frame", EHSectionType, EHSectionFlags);
StackSizesSection = Ctx->getELFSection(".stack_sizes", ELF::SHT_PROGBITS, 0);
-
- PseudoProbeSection = Ctx->getELFSection(".pseudo_probe", DebugSecType, 0);
- PseudoProbeDescSection =
- Ctx->getELFSection(".pseudo_probe_desc", DebugSecType, 0);
+
+ PseudoProbeSection = Ctx->getELFSection(".pseudo_probe", DebugSecType, 0);
+ PseudoProbeDescSection =
+ Ctx->getELFSection(".pseudo_probe_desc", DebugSecType, 0);
}
void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
@@ -758,11 +758,11 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
COFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
- GIATsSection = Ctx->getCOFFSection(".giats$y",
- COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
- COFF::IMAGE_SCN_MEM_READ,
- SectionKind::getMetadata());
-
+ GIATsSection = Ctx->getCOFFSection(".giats$y",
+ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
+
GLJMPSection = Ctx->getCOFFSection(".gljmp$y",
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ,
@@ -807,10 +807,10 @@ void MCObjectFileInfo::initWasmMCObjectFileInfo(const Triple &T) {
DwarfFrameSection = Ctx->getWasmSection(".debug_frame", SectionKind::getMetadata());
DwarfPubNamesSection = Ctx->getWasmSection(".debug_pubnames", SectionKind::getMetadata());
DwarfPubTypesSection = Ctx->getWasmSection(".debug_pubtypes", SectionKind::getMetadata());
- DwarfGnuPubNamesSection =
- Ctx->getWasmSection(".debug_gnu_pubnames", SectionKind::getMetadata());
- DwarfGnuPubTypesSection =
- Ctx->getWasmSection(".debug_gnu_pubtypes", SectionKind::getMetadata());
+ DwarfGnuPubNamesSection =
+ Ctx->getWasmSection(".debug_gnu_pubnames", SectionKind::getMetadata());
+ DwarfGnuPubTypesSection =
+ Ctx->getWasmSection(".debug_gnu_pubtypes", SectionKind::getMetadata());
DwarfDebugNamesSection =
Ctx->getWasmSection(".debug_names", SectionKind::getMetadata());
@@ -823,37 +823,37 @@ void MCObjectFileInfo::initWasmMCObjectFileInfo(const Triple &T) {
DwarfLoclistsSection =
Ctx->getWasmSection(".debug_loclists", SectionKind::getMetadata());
- // Fission Sections
- DwarfInfoDWOSection =
- Ctx->getWasmSection(".debug_info.dwo", SectionKind::getMetadata());
- DwarfTypesDWOSection =
- Ctx->getWasmSection(".debug_types.dwo", SectionKind::getMetadata());
- DwarfAbbrevDWOSection =
- Ctx->getWasmSection(".debug_abbrev.dwo", SectionKind::getMetadata());
- DwarfStrDWOSection =
- Ctx->getWasmSection(".debug_str.dwo", SectionKind::getMetadata());
- DwarfLineDWOSection =
- Ctx->getWasmSection(".debug_line.dwo", SectionKind::getMetadata());
- DwarfLocDWOSection =
- Ctx->getWasmSection(".debug_loc.dwo", SectionKind::getMetadata());
- DwarfStrOffDWOSection =
- Ctx->getWasmSection(".debug_str_offsets.dwo", SectionKind::getMetadata());
- DwarfRnglistsDWOSection =
- Ctx->getWasmSection(".debug_rnglists.dwo", SectionKind::getMetadata());
- DwarfMacinfoDWOSection =
- Ctx->getWasmSection(".debug_macinfo.dwo", SectionKind::getMetadata());
- DwarfMacroDWOSection =
- Ctx->getWasmSection(".debug_macro.dwo", SectionKind::getMetadata());
-
- DwarfLoclistsDWOSection =
- Ctx->getWasmSection(".debug_loclists.dwo", SectionKind::getMetadata());
-
- // DWP Sections
- DwarfCUIndexSection =
- Ctx->getWasmSection(".debug_cu_index", SectionKind::getMetadata(), 0);
- DwarfTUIndexSection =
- Ctx->getWasmSection(".debug_tu_index", SectionKind::getMetadata(), 0);
-
+ // Fission Sections
+ DwarfInfoDWOSection =
+ Ctx->getWasmSection(".debug_info.dwo", SectionKind::getMetadata());
+ DwarfTypesDWOSection =
+ Ctx->getWasmSection(".debug_types.dwo", SectionKind::getMetadata());
+ DwarfAbbrevDWOSection =
+ Ctx->getWasmSection(".debug_abbrev.dwo", SectionKind::getMetadata());
+ DwarfStrDWOSection =
+ Ctx->getWasmSection(".debug_str.dwo", SectionKind::getMetadata());
+ DwarfLineDWOSection =
+ Ctx->getWasmSection(".debug_line.dwo", SectionKind::getMetadata());
+ DwarfLocDWOSection =
+ Ctx->getWasmSection(".debug_loc.dwo", SectionKind::getMetadata());
+ DwarfStrOffDWOSection =
+ Ctx->getWasmSection(".debug_str_offsets.dwo", SectionKind::getMetadata());
+ DwarfRnglistsDWOSection =
+ Ctx->getWasmSection(".debug_rnglists.dwo", SectionKind::getMetadata());
+ DwarfMacinfoDWOSection =
+ Ctx->getWasmSection(".debug_macinfo.dwo", SectionKind::getMetadata());
+ DwarfMacroDWOSection =
+ Ctx->getWasmSection(".debug_macro.dwo", SectionKind::getMetadata());
+
+ DwarfLoclistsDWOSection =
+ Ctx->getWasmSection(".debug_loclists.dwo", SectionKind::getMetadata());
+
+ // DWP Sections
+ DwarfCUIndexSection =
+ Ctx->getWasmSection(".debug_cu_index", SectionKind::getMetadata(), 0);
+ DwarfTUIndexSection =
+ Ctx->getWasmSection(".debug_tu_index", SectionKind::getMetadata(), 0);
+
// Wasm use data section for LSDA.
// TODO Consider putting each function's exception table in a separate
// section, as in -function-sections, to facilitate lld's --gc-section.
@@ -870,31 +870,31 @@ void MCObjectFileInfo::initXCOFFMCObjectFileInfo(const Triple &T) {
// csect for program code.
TextSection = Ctx->getXCOFFSection(
".text", XCOFF::StorageMappingClass::XMC_PR, XCOFF::XTY_SD,
- SectionKind::getText(), /* MultiSymbolsAllowed*/ true);
+ SectionKind::getText(), /* MultiSymbolsAllowed*/ true);
DataSection = Ctx->getXCOFFSection(
".data", XCOFF::StorageMappingClass::XMC_RW, XCOFF::XTY_SD,
- SectionKind::getData(), /* MultiSymbolsAllowed*/ true);
+ SectionKind::getData(), /* MultiSymbolsAllowed*/ true);
ReadOnlySection = Ctx->getXCOFFSection(
".rodata", XCOFF::StorageMappingClass::XMC_RO, XCOFF::XTY_SD,
- SectionKind::getReadOnly(), /* MultiSymbolsAllowed*/ true);
+ SectionKind::getReadOnly(), /* MultiSymbolsAllowed*/ true);
- TOCBaseSection =
- Ctx->getXCOFFSection("TOC", XCOFF::StorageMappingClass::XMC_TC0,
- XCOFF::XTY_SD, SectionKind::getData());
+ TOCBaseSection =
+ Ctx->getXCOFFSection("TOC", XCOFF::StorageMappingClass::XMC_TC0,
+ XCOFF::XTY_SD, SectionKind::getData());
// The TOC-base always has 0 size, but 4 byte alignment.
TOCBaseSection->setAlignment(Align(4));
- LSDASection = Ctx->getXCOFFSection(".gcc_except_table",
- XCOFF::StorageMappingClass::XMC_RO,
- XCOFF::XTY_SD, SectionKind::getReadOnly());
-
- CompactUnwindSection =
- Ctx->getXCOFFSection(".eh_info_table", XCOFF::StorageMappingClass::XMC_RW,
- XCOFF::XTY_SD, SectionKind::getData());
-
+ LSDASection = Ctx->getXCOFFSection(".gcc_except_table",
+ XCOFF::StorageMappingClass::XMC_RO,
+ XCOFF::XTY_SD, SectionKind::getReadOnly());
+
+ CompactUnwindSection =
+ Ctx->getXCOFFSection(".eh_info_table", XCOFF::StorageMappingClass::XMC_RW,
+ XCOFF::XTY_SD, SectionKind::getData());
+
// DWARF sections for XCOFF are not csects. They are special STYP_DWARF
// sections, and the individual DWARF sections are distinguished by their
// section subtype.
@@ -958,9 +958,9 @@ void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC,
Env = IsWasm;
initWasmMCObjectFileInfo(TT);
break;
- case Triple::GOFF:
- report_fatal_error("Cannot initialize MC for GOFF object file format");
- break;
+ case Triple::GOFF:
+ report_fatal_error("Cannot initialize MC for GOFF object file format");
+ break;
case Triple::XCOFF:
Env = IsXCOFF;
initXCOFFMCObjectFileInfo(TT);
@@ -977,12 +977,12 @@ MCSection *MCObjectFileInfo::getDwarfComdatSection(const char *Name,
case Triple::ELF:
return Ctx->getELFSection(Name, ELF::SHT_PROGBITS, ELF::SHF_GROUP, 0,
utostr(Hash));
- case Triple::Wasm:
- return Ctx->getWasmSection(Name, SectionKind::getMetadata(), utostr(Hash),
- MCContext::GenericSectionID);
+ case Triple::Wasm:
+ return Ctx->getWasmSection(Name, SectionKind::getMetadata(), utostr(Hash),
+ MCContext::GenericSectionID);
case Triple::MachO:
case Triple::COFF:
- case Triple::GOFF:
+ case Triple::GOFF:
case Triple::XCOFF:
case Triple::UnknownObjectFormat:
report_fatal_error("Cannot get DWARF comdat section for this object file "
@@ -1006,64 +1006,64 @@ MCObjectFileInfo::getStackSizesSection(const MCSection &TextSec) const {
}
return Ctx->getELFSection(".stack_sizes", ELF::SHT_PROGBITS, Flags, 0,
- GroupName, ElfSec.getUniqueID(),
+ GroupName, ElfSec.getUniqueID(),
+ cast<MCSymbolELF>(TextSec.getBeginSymbol()));
+}
+
+MCSection *
+MCObjectFileInfo::getBBAddrMapSection(const MCSection &TextSec) const {
+ if (Env != IsELF)
+ return nullptr;
+
+ const MCSectionELF &ElfSec = static_cast<const MCSectionELF &>(TextSec);
+ unsigned Flags = ELF::SHF_LINK_ORDER;
+ StringRef GroupName;
+ if (const MCSymbol *Group = ElfSec.getGroup()) {
+ GroupName = Group->getName();
+ Flags |= ELF::SHF_GROUP;
+ }
+
+ // Use the text section's begin symbol and unique ID to create a separate
+ // .llvm_bb_addr_map section associated with every unique text section.
+ return Ctx->getELFSection(".llvm_bb_addr_map", ELF::SHT_LLVM_BB_ADDR_MAP,
+ Flags, 0, GroupName, ElfSec.getUniqueID(),
cast<MCSymbolELF>(TextSec.getBeginSymbol()));
}
-
-MCSection *
-MCObjectFileInfo::getBBAddrMapSection(const MCSection &TextSec) const {
- if (Env != IsELF)
- return nullptr;
-
- const MCSectionELF &ElfSec = static_cast<const MCSectionELF &>(TextSec);
- unsigned Flags = ELF::SHF_LINK_ORDER;
- StringRef GroupName;
- if (const MCSymbol *Group = ElfSec.getGroup()) {
- GroupName = Group->getName();
- Flags |= ELF::SHF_GROUP;
- }
-
- // Use the text section's begin symbol and unique ID to create a separate
- // .llvm_bb_addr_map section associated with every unique text section.
- return Ctx->getELFSection(".llvm_bb_addr_map", ELF::SHT_LLVM_BB_ADDR_MAP,
- Flags, 0, GroupName, ElfSec.getUniqueID(),
- cast<MCSymbolELF>(TextSec.getBeginSymbol()));
-}
-
-MCSection *
-MCObjectFileInfo::getPseudoProbeSection(const MCSection *TextSec) const {
- if (Env == IsELF) {
- const auto *ElfSec = static_cast<const MCSectionELF *>(TextSec);
- // Create a separate section for probes that comes with a comdat function.
- if (const MCSymbol *Group = ElfSec->getGroup()) {
- auto *S = static_cast<MCSectionELF *>(PseudoProbeSection);
- auto Flags = S->getFlags() | ELF::SHF_GROUP;
- return Ctx->getELFSection(S->getName(), S->getType(), Flags,
- S->getEntrySize(), Group->getName());
- }
- }
- return PseudoProbeSection;
-}
-
-MCSection *
-MCObjectFileInfo::getPseudoProbeDescSection(StringRef FuncName) const {
- if (Env == IsELF) {
- // Create a separate comdat group for each function's descriptor in order
- // for the linker to deduplicate. The duplication, must be from different
- // tranlation unit, can come from:
- // 1. Inline functions defined in header files;
- // 2. ThinLTO imported funcions;
- // 3. Weak-linkage definitions.
- // Use a concatenation of the section name and the function name as the
- // group name so that descriptor-only groups won't be folded with groups of
- // code.
- if (TT.supportsCOMDAT() && !FuncName.empty()) {
- auto *S = static_cast<MCSectionELF *>(PseudoProbeDescSection);
- auto Flags = S->getFlags() | ELF::SHF_GROUP;
- return Ctx->getELFSection(S->getName(), S->getType(), Flags,
- S->getEntrySize(),
- S->getName() + "_" + FuncName);
- }
- }
- return PseudoProbeDescSection;
-}
+
+MCSection *
+MCObjectFileInfo::getPseudoProbeSection(const MCSection *TextSec) const {
+ if (Env == IsELF) {
+ const auto *ElfSec = static_cast<const MCSectionELF *>(TextSec);
+ // Create a separate section for probes that comes with a comdat function.
+ if (const MCSymbol *Group = ElfSec->getGroup()) {
+ auto *S = static_cast<MCSectionELF *>(PseudoProbeSection);
+ auto Flags = S->getFlags() | ELF::SHF_GROUP;
+ return Ctx->getELFSection(S->getName(), S->getType(), Flags,
+ S->getEntrySize(), Group->getName());
+ }
+ }
+ return PseudoProbeSection;
+}
+
+MCSection *
+MCObjectFileInfo::getPseudoProbeDescSection(StringRef FuncName) const {
+ if (Env == IsELF) {
+ // Create a separate comdat group for each function's descriptor in order
+ // for the linker to deduplicate. The duplication, must be from different
+ // tranlation unit, can come from:
+ // 1. Inline functions defined in header files;
+ // 2. ThinLTO imported funcions;
+ // 3. Weak-linkage definitions.
+ // Use a concatenation of the section name and the function name as the
+ // group name so that descriptor-only groups won't be folded with groups of
+ // code.
+ if (TT.supportsCOMDAT() && !FuncName.empty()) {
+ auto *S = static_cast<MCSectionELF *>(PseudoProbeDescSection);
+ auto Flags = S->getFlags() | ELF::SHF_GROUP;
+ return Ctx->getELFSection(S->getName(), S->getType(), Flags,
+ S->getEntrySize(),
+ S->getName() + "_" + FuncName);
+ }
+ }
+ return PseudoProbeDescSection;
+}
diff --git a/contrib/libs/llvm12/lib/MC/MCObjectStreamer.cpp b/contrib/libs/llvm12/lib/MC/MCObjectStreamer.cpp
index 10cbc00bc5..1c23d31f87 100644
--- a/contrib/libs/llvm12/lib/MC/MCObjectStreamer.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCObjectStreamer.cpp
@@ -248,7 +248,7 @@ void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
}
MCSymbol *MCObjectStreamer::emitCFILabel() {
- MCSymbol *Label = getContext().createTempSymbol("cfi");
+ MCSymbol *Label = getContext().createTempSymbol("cfi");
emitLabel(Label);
return Label;
}
@@ -665,68 +665,68 @@ void MCObjectStreamer::emitGPRel64Value(const MCExpr *Value) {
DF->getContents().resize(DF->getContents().size() + 8, 0);
}
-static Optional<std::pair<bool, std::string>>
-getOffsetAndDataFragment(const MCSymbol &Symbol, uint32_t &RelocOffset,
- MCDataFragment *&DF) {
- if (Symbol.isVariable()) {
- const MCExpr *SymbolExpr = Symbol.getVariableValue();
- MCValue OffsetVal;
- if(!SymbolExpr->evaluateAsRelocatable(OffsetVal, nullptr, nullptr))
- return std::make_pair(false,
- std::string("symbol in .reloc offset is not "
- "relocatable"));
- if (OffsetVal.isAbsolute()) {
- RelocOffset = OffsetVal.getConstant();
- MCFragment *Fragment = Symbol.getFragment();
- // FIXME Support symbols with no DF. For example:
- // .reloc .data, ENUM_VALUE, <some expr>
- if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
- return std::make_pair(false,
- std::string("symbol in offset has no data "
- "fragment"));
- DF = cast<MCDataFragment>(Fragment);
- return None;
- }
-
- if (OffsetVal.getSymB())
- return std::make_pair(false,
- std::string(".reloc symbol offset is not "
- "representable"));
-
- const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*OffsetVal.getSymA());
- if (!SRE.getSymbol().isDefined())
- return std::make_pair(false,
- std::string("symbol used in the .reloc offset is "
- "not defined"));
-
- if (SRE.getSymbol().isVariable())
- return std::make_pair(false,
- std::string("symbol used in the .reloc offset is "
- "variable"));
-
- MCFragment *Fragment = SRE.getSymbol().getFragment();
- // FIXME Support symbols with no DF. For example:
- // .reloc .data, ENUM_VALUE, <some expr>
- if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
- return std::make_pair(false,
- std::string("symbol in offset has no data "
- "fragment"));
- RelocOffset = SRE.getSymbol().getOffset() + OffsetVal.getConstant();
- DF = cast<MCDataFragment>(Fragment);
- } else {
- RelocOffset = Symbol.getOffset();
- MCFragment *Fragment = Symbol.getFragment();
- // FIXME Support symbols with no DF. For example:
- // .reloc .data, ENUM_VALUE, <some expr>
- if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
- return std::make_pair(false,
- std::string("symbol in offset has no data "
- "fragment"));
- DF = cast<MCDataFragment>(Fragment);
- }
- return None;
-}
-
+static Optional<std::pair<bool, std::string>>
+getOffsetAndDataFragment(const MCSymbol &Symbol, uint32_t &RelocOffset,
+ MCDataFragment *&DF) {
+ if (Symbol.isVariable()) {
+ const MCExpr *SymbolExpr = Symbol.getVariableValue();
+ MCValue OffsetVal;
+ if(!SymbolExpr->evaluateAsRelocatable(OffsetVal, nullptr, nullptr))
+ return std::make_pair(false,
+ std::string("symbol in .reloc offset is not "
+ "relocatable"));
+ if (OffsetVal.isAbsolute()) {
+ RelocOffset = OffsetVal.getConstant();
+ MCFragment *Fragment = Symbol.getFragment();
+ // FIXME Support symbols with no DF. For example:
+ // .reloc .data, ENUM_VALUE, <some expr>
+ if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
+ return std::make_pair(false,
+ std::string("symbol in offset has no data "
+ "fragment"));
+ DF = cast<MCDataFragment>(Fragment);
+ return None;
+ }
+
+ if (OffsetVal.getSymB())
+ return std::make_pair(false,
+ std::string(".reloc symbol offset is not "
+ "representable"));
+
+ const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*OffsetVal.getSymA());
+ if (!SRE.getSymbol().isDefined())
+ return std::make_pair(false,
+ std::string("symbol used in the .reloc offset is "
+ "not defined"));
+
+ if (SRE.getSymbol().isVariable())
+ return std::make_pair(false,
+ std::string("symbol used in the .reloc offset is "
+ "variable"));
+
+ MCFragment *Fragment = SRE.getSymbol().getFragment();
+ // FIXME Support symbols with no DF. For example:
+ // .reloc .data, ENUM_VALUE, <some expr>
+ if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
+ return std::make_pair(false,
+ std::string("symbol in offset has no data "
+ "fragment"));
+ RelocOffset = SRE.getSymbol().getOffset() + OffsetVal.getConstant();
+ DF = cast<MCDataFragment>(Fragment);
+ } else {
+ RelocOffset = Symbol.getOffset();
+ MCFragment *Fragment = Symbol.getFragment();
+ // FIXME Support symbols with no DF. For example:
+ // .reloc .data, ENUM_VALUE, <some expr>
+ if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
+ return std::make_pair(false,
+ std::string("symbol in offset has no data "
+ "fragment"));
+ DF = cast<MCDataFragment>(Fragment);
+ }
+ return None;
+}
+
Optional<std::pair<bool, std::string>>
MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name,
const MCExpr *Expr, SMLoc Loc,
@@ -760,17 +760,17 @@ MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name,
std::string(".reloc offset is not representable"));
const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*OffsetVal.getSymA());
- const MCSymbol &Symbol = SRE.getSymbol();
- if (Symbol.isDefined()) {
- uint32_t SymbolOffset = 0;
- Optional<std::pair<bool, std::string>> Error;
- Error = getOffsetAndDataFragment(Symbol, SymbolOffset, DF);
-
- if (Error != None)
- return Error;
-
+ const MCSymbol &Symbol = SRE.getSymbol();
+ if (Symbol.isDefined()) {
+ uint32_t SymbolOffset = 0;
+ Optional<std::pair<bool, std::string>> Error;
+ Error = getOffsetAndDataFragment(Symbol, SymbolOffset, DF);
+
+ if (Error != None)
+ return Error;
+
DF->getFixups().push_back(
- MCFixup::create(SymbolOffset + OffsetVal.getConstant(),
+ MCFixup::create(SymbolOffset + OffsetVal.getConstant(),
Expr, Kind, Loc));
return None;
}
@@ -819,16 +819,16 @@ void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
insert(new MCFillFragment(Expr, Size, NumValues, Loc));
}
-void MCObjectStreamer::emitNops(int64_t NumBytes, int64_t ControlledNopLength,
- SMLoc Loc) {
- // Emit an NOP fragment.
- MCDataFragment *DF = getOrCreateDataFragment();
- flushPendingLabels(DF, DF->getContents().size());
-
- assert(getCurrentSectionOnly() && "need a section");
- insert(new MCNopsFragment(NumBytes, ControlledNopLength, Loc));
-}
-
+void MCObjectStreamer::emitNops(int64_t NumBytes, int64_t ControlledNopLength,
+ SMLoc Loc) {
+ // Emit an NOP fragment.
+ MCDataFragment *DF = getOrCreateDataFragment();
+ flushPendingLabels(DF, DF->getContents().size());
+
+ assert(getCurrentSectionOnly() && "need a section");
+ insert(new MCNopsFragment(NumBytes, ControlledNopLength, Loc));
+}
+
void MCObjectStreamer::emitFileDirective(StringRef Filename) {
getAssembler().addFileName(Filename);
}
@@ -852,9 +852,9 @@ void MCObjectStreamer::finishImpl() {
// Dump out the dwarf file & directory tables and line tables.
MCDwarfLineTable::Emit(this, getAssembler().getDWARFLinetableParams());
- // Emit pseudo probes for the current module.
- MCPseudoProbeTable::emit(this);
-
+ // Emit pseudo probes for the current module.
+ MCPseudoProbeTable::emit(this);
+
// Update any remaining pending labels with empty data fragments.
flushPendingLabels();
diff --git a/contrib/libs/llvm12/lib/MC/MCParser/AsmLexer.cpp b/contrib/libs/llvm12/lib/MC/MCParser/AsmLexer.cpp
index 43c36f8eab..1fa22ab000 100644
--- a/contrib/libs/llvm12/lib/MC/MCParser/AsmLexer.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCParser/AsmLexer.cpp
@@ -18,7 +18,7 @@
#include "llvm/ADT/StringSwitch.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
-#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SaveAndRestore.h"
#include <cassert>
@@ -64,12 +64,12 @@ int AsmLexer::getNextChar() {
return (unsigned char)*CurPtr++;
}
-int AsmLexer::peekNextChar() {
- if (CurPtr == CurBuf.end())
- return EOF;
- return (unsigned char)*CurPtr;
-}
-
+int AsmLexer::peekNextChar() {
+ if (CurPtr == CurBuf.end())
+ return EOF;
+ return (unsigned char)*CurPtr;
+}
+
/// The leading integral digit sequence and dot should have already been
/// consumed, some or all of the fractional digit sequence *can* have been
/// consumed.
@@ -278,34 +278,34 @@ static unsigned doHexLookAhead(const char *&CurPtr, unsigned DefaultRadix,
return DefaultRadix;
}
-static const char *findLastDigit(const char *CurPtr, unsigned DefaultRadix) {
- while (hexDigitValue(*CurPtr) < DefaultRadix) {
- ++CurPtr;
- }
- return CurPtr;
-}
-
-static AsmToken intToken(StringRef Ref, APInt &Value) {
+static const char *findLastDigit(const char *CurPtr, unsigned DefaultRadix) {
+ while (hexDigitValue(*CurPtr) < DefaultRadix) {
+ ++CurPtr;
+ }
+ return CurPtr;
+}
+
+static AsmToken intToken(StringRef Ref, APInt &Value) {
if (Value.isIntN(64))
return AsmToken(AsmToken::Integer, Ref, Value);
return AsmToken(AsmToken::BigNum, Ref, Value);
}
-static std::string radixName(unsigned Radix) {
- switch (Radix) {
- case 2:
- return "binary";
- case 8:
- return "octal";
- case 10:
- return "decimal";
- case 16:
- return "hexadecimal";
- default:
- return "base-" + std::to_string(Radix);
- }
-}
-
+static std::string radixName(unsigned Radix) {
+ switch (Radix) {
+ case 2:
+ return "binary";
+ case 8:
+ return "octal";
+ case 10:
+ return "decimal";
+ case 16:
+ return "hexadecimal";
+ default:
+ return "base-" + std::to_string(Radix);
+ }
+}
+
/// LexDigit: First character is [0-9].
/// Local Label: [0-9][:]
/// Forward/Backward Label: [0-9][fb]
@@ -314,113 +314,113 @@ static std::string radixName(unsigned Radix) {
/// Hex integer: 0x[0-9a-fA-F]+ or [0x]?[0-9][0-9a-fA-F]*[hH]
/// Decimal integer: [1-9][0-9]*
AsmToken AsmLexer::LexDigit() {
- // MASM-flavor binary integer: [01]+[yY] (if DefaultRadix < 16, [bByY])
- // MASM-flavor octal integer: [0-7]+[oOqQ]
- // MASM-flavor decimal integer: [0-9]+[tT] (if DefaultRadix < 16, [dDtT])
+ // MASM-flavor binary integer: [01]+[yY] (if DefaultRadix < 16, [bByY])
+ // MASM-flavor octal integer: [0-7]+[oOqQ]
+ // MASM-flavor decimal integer: [0-9]+[tT] (if DefaultRadix < 16, [dDtT])
// MASM-flavor hexadecimal integer: [0-9][0-9a-fA-F]*[hH]
if (LexMasmIntegers && isdigit(CurPtr[-1])) {
- const char *FirstNonBinary =
- (CurPtr[-1] != '0' && CurPtr[-1] != '1') ? CurPtr - 1 : nullptr;
- const char *FirstNonDecimal =
- (CurPtr[-1] < '0' || CurPtr[-1] > '9') ? CurPtr - 1 : nullptr;
+ const char *FirstNonBinary =
+ (CurPtr[-1] != '0' && CurPtr[-1] != '1') ? CurPtr - 1 : nullptr;
+ const char *FirstNonDecimal =
+ (CurPtr[-1] < '0' || CurPtr[-1] > '9') ? CurPtr - 1 : nullptr;
const char *OldCurPtr = CurPtr;
while (isHexDigit(*CurPtr)) {
- switch (*CurPtr) {
- default:
- if (!FirstNonDecimal) {
- FirstNonDecimal = CurPtr;
- }
- LLVM_FALLTHROUGH;
- case '9':
- case '8':
- case '7':
- case '6':
- case '5':
- case '4':
- case '3':
- case '2':
- if (!FirstNonBinary) {
- FirstNonBinary = CurPtr;
- }
- break;
- case '1':
- case '0':
- break;
- }
+ switch (*CurPtr) {
+ default:
+ if (!FirstNonDecimal) {
+ FirstNonDecimal = CurPtr;
+ }
+ LLVM_FALLTHROUGH;
+ case '9':
+ case '8':
+ case '7':
+ case '6':
+ case '5':
+ case '4':
+ case '3':
+ case '2':
+ if (!FirstNonBinary) {
+ FirstNonBinary = CurPtr;
+ }
+ break;
+ case '1':
+ case '0':
+ break;
+ }
++CurPtr;
}
- if (*CurPtr == '.') {
- // MASM float literals (other than hex floats) always contain a ".", and
- // are always written in decimal.
- ++CurPtr;
- return LexFloatLiteral();
- }
-
- if (LexMasmHexFloats && (*CurPtr == 'r' || *CurPtr == 'R')) {
- ++CurPtr;
- return AsmToken(AsmToken::Real, StringRef(TokStart, CurPtr - TokStart));
- }
-
+ if (*CurPtr == '.') {
+ // MASM float literals (other than hex floats) always contain a ".", and
+ // are always written in decimal.
+ ++CurPtr;
+ return LexFloatLiteral();
+ }
+
+ if (LexMasmHexFloats && (*CurPtr == 'r' || *CurPtr == 'R')) {
+ ++CurPtr;
+ return AsmToken(AsmToken::Real, StringRef(TokStart, CurPtr - TokStart));
+ }
+
unsigned Radix = 0;
if (*CurPtr == 'h' || *CurPtr == 'H') {
// hexadecimal number
++CurPtr;
Radix = 16;
- } else if (*CurPtr == 't' || *CurPtr == 'T') {
- // decimal number
- ++CurPtr;
- Radix = 10;
- } else if (*CurPtr == 'o' || *CurPtr == 'O' || *CurPtr == 'q' ||
- *CurPtr == 'Q') {
- // octal number
- ++CurPtr;
- Radix = 8;
- } else if (*CurPtr == 'y' || *CurPtr == 'Y') {
- // binary number
- ++CurPtr;
- Radix = 2;
- } else if (FirstNonDecimal && FirstNonDecimal + 1 == CurPtr &&
- DefaultRadix < 14 &&
- (*FirstNonDecimal == 'd' || *FirstNonDecimal == 'D')) {
- Radix = 10;
+ } else if (*CurPtr == 't' || *CurPtr == 'T') {
+ // decimal number
+ ++CurPtr;
+ Radix = 10;
+ } else if (*CurPtr == 'o' || *CurPtr == 'O' || *CurPtr == 'q' ||
+ *CurPtr == 'Q') {
+ // octal number
+ ++CurPtr;
+ Radix = 8;
+ } else if (*CurPtr == 'y' || *CurPtr == 'Y') {
+ // binary number
+ ++CurPtr;
+ Radix = 2;
+ } else if (FirstNonDecimal && FirstNonDecimal + 1 == CurPtr &&
+ DefaultRadix < 14 &&
+ (*FirstNonDecimal == 'd' || *FirstNonDecimal == 'D')) {
+ Radix = 10;
} else if (FirstNonBinary && FirstNonBinary + 1 == CurPtr &&
- DefaultRadix < 12 &&
- (*FirstNonBinary == 'b' || *FirstNonBinary == 'B')) {
+ DefaultRadix < 12 &&
+ (*FirstNonBinary == 'b' || *FirstNonBinary == 'B')) {
Radix = 2;
- }
+ }
- if (Radix) {
+ if (Radix) {
StringRef Result(TokStart, CurPtr - TokStart);
APInt Value(128, 0, true);
if (Result.drop_back().getAsInteger(Radix, Value))
- return ReturnError(TokStart, "invalid " + radixName(Radix) + " number");
+ return ReturnError(TokStart, "invalid " + radixName(Radix) + " number");
// MSVC accepts and ignores type suffices on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
return intToken(Result, Value);
- }
+ }
- // default-radix integers, or floating point numbers, fall through
+ // default-radix integers, or floating point numbers, fall through
CurPtr = OldCurPtr;
}
- // MASM default-radix integers: [0-9a-fA-F]+
- // (All other integer literals have a radix specifier.)
- if (LexMasmIntegers && UseMasmDefaultRadix) {
- CurPtr = findLastDigit(CurPtr, 16);
- StringRef Result(TokStart, CurPtr - TokStart);
-
- APInt Value(128, 0, true);
- if (Result.getAsInteger(DefaultRadix, Value)) {
- return ReturnError(TokStart,
- "invalid " + radixName(DefaultRadix) + " number");
- }
-
- return intToken(Result, Value);
- }
-
+ // MASM default-radix integers: [0-9a-fA-F]+
+ // (All other integer literals have a radix specifier.)
+ if (LexMasmIntegers && UseMasmDefaultRadix) {
+ CurPtr = findLastDigit(CurPtr, 16);
+ StringRef Result(TokStart, CurPtr - TokStart);
+
+ APInt Value(128, 0, true);
+ if (Result.getAsInteger(DefaultRadix, Value)) {
+ return ReturnError(TokStart,
+ "invalid " + radixName(DefaultRadix) + " number");
+ }
+
+ return intToken(Result, Value);
+ }
+
// Decimal integer: [1-9][0-9]*
if (CurPtr[-1] != '0' || CurPtr[0] == '.') {
unsigned Radix = doHexLookAhead(CurPtr, 10, LexMasmIntegers);
@@ -435,9 +435,9 @@ AsmToken AsmLexer::LexDigit() {
StringRef Result(TokStart, CurPtr - TokStart);
APInt Value(128, 0, true);
- if (Result.getAsInteger(Radix, Value)) {
- return ReturnError(TokStart, "invalid " + radixName(Radix) + " number");
- }
+ if (Result.getAsInteger(Radix, Value)) {
+ return ReturnError(TokStart, "invalid " + radixName(Radix) + " number");
+ }
// The darwin/x86 (and x86-64) assembler accepts and ignores type
// suffices on integer literals.
@@ -510,7 +510,7 @@ AsmToken AsmLexer::LexDigit() {
unsigned Radix = doHexLookAhead(CurPtr, 8, LexMasmIntegers);
StringRef Result(TokStart, CurPtr - TokStart);
if (Result.getAsInteger(Radix, Value))
- return ReturnError(TokStart, "invalid " + radixName(Radix) + " number");
+ return ReturnError(TokStart, "invalid " + radixName(Radix) + " number");
// Consume the [hH].
if (Radix == 16)
@@ -527,24 +527,24 @@ AsmToken AsmLexer::LexDigit() {
AsmToken AsmLexer::LexSingleQuote() {
int CurChar = getNextChar();
- if (LexMasmStrings) {
- while (CurChar != EOF) {
- if (CurChar != '\'') {
- CurChar = getNextChar();
- } else if (peekNextChar() == '\'') {
- // In MASM single-quote strings, doubled single-quotes mean an escaped
- // single quote, so should be lexed in.
- getNextChar();
- CurChar = getNextChar();
- } else {
- break;
- }
- }
- if (CurChar == EOF)
- return ReturnError(TokStart, "unterminated string constant");
- return AsmToken(AsmToken::String, StringRef(TokStart, CurPtr - TokStart));
- }
-
+ if (LexMasmStrings) {
+ while (CurChar != EOF) {
+ if (CurChar != '\'') {
+ CurChar = getNextChar();
+ } else if (peekNextChar() == '\'') {
+ // In MASM single-quote strings, doubled single-quotes mean an escaped
+ // single quote, so should be lexed in.
+ getNextChar();
+ CurChar = getNextChar();
+ } else {
+ break;
+ }
+ }
+ if (CurChar == EOF)
+ return ReturnError(TokStart, "unterminated string constant");
+ return AsmToken(AsmToken::String, StringRef(TokStart, CurPtr - TokStart));
+ }
+
if (CurChar == '\\')
CurChar = getNextChar();
@@ -579,24 +579,24 @@ AsmToken AsmLexer::LexSingleQuote() {
/// LexQuote: String: "..."
AsmToken AsmLexer::LexQuote() {
int CurChar = getNextChar();
- if (LexMasmStrings) {
- while (CurChar != EOF) {
- if (CurChar != '"') {
- CurChar = getNextChar();
- } else if (peekNextChar() == '"') {
- // In MASM double-quoted strings, doubled double-quotes mean an escaped
- // double quote, so should be lexed in.
- getNextChar();
- CurChar = getNextChar();
- } else {
- break;
- }
- }
- if (CurChar == EOF)
- return ReturnError(TokStart, "unterminated string constant");
- return AsmToken(AsmToken::String, StringRef(TokStart, CurPtr - TokStart));
- }
-
+ if (LexMasmStrings) {
+ while (CurChar != EOF) {
+ if (CurChar != '"') {
+ CurChar = getNextChar();
+ } else if (peekNextChar() == '"') {
+ // In MASM double-quoted strings, doubled double-quotes mean an escaped
+ // double quote, so should be lexed in.
+ getNextChar();
+ CurChar = getNextChar();
+ } else {
+ break;
+ }
+ }
+ if (CurChar == EOF)
+ return ReturnError(TokStart, "unterminated string constant");
+ return AsmToken(AsmToken::String, StringRef(TokStart, CurPtr - TokStart));
+ }
+
// TODO: does gas allow multiline string constants?
while (CurChar != '"') {
if (CurChar == '\\') {
@@ -715,7 +715,7 @@ AsmToken AsmLexer::LexToken() {
if (CurChar == EOF && !IsAtStartOfStatement && EndStatementAtEOF) {
IsAtStartOfLine = true;
IsAtStartOfStatement = true;
- return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 0));
+ return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 0));
}
IsAtStartOfLine = false;
bool OldIsAtStartOfStatement = IsAtStartOfStatement;
diff --git a/contrib/libs/llvm12/lib/MC/MCParser/AsmParser.cpp b/contrib/libs/llvm12/lib/MC/MCParser/AsmParser.cpp
index 32ae3b1122..c5ff241ead 100644
--- a/contrib/libs/llvm12/lib/MC/MCParser/AsmParser.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCParser/AsmParser.cpp
@@ -126,7 +126,7 @@ private:
SourceMgr::DiagHandlerTy SavedDiagHandler;
void *SavedDiagContext;
std::unique_ptr<MCAsmParserExtension> PlatformParser;
- SMLoc StartTokLoc;
+ SMLoc StartTokLoc;
/// This is the current buffer index we're lexing from as managed by the
/// SourceMgr object.
@@ -245,8 +245,8 @@ public:
bool parseExpression(const MCExpr *&Res);
bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
- bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
- AsmTypeInfo *TypeInfo) override;
+ bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
+ AsmTypeInfo *TypeInfo) override;
bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
SMLoc &EndLoc) override;
@@ -515,7 +515,7 @@ private:
DK_PRINT,
DK_ADDRSIG,
DK_ADDRSIG_SYM,
- DK_PSEUDO_PROBE,
+ DK_PSEUDO_PROBE,
DK_END
};
@@ -679,9 +679,9 @@ private:
// .print <double-quotes-string>
bool parseDirectivePrint(SMLoc DirectiveLoc);
- // .pseudoprobe
- bool parseDirectivePseudoProbe();
-
+ // .pseudoprobe
+ bool parseDirectivePseudoProbe();
+
// Directives to support address-significance tables.
bool parseDirectiveAddrsig();
bool parseDirectiveAddrsigSym();
@@ -714,8 +714,8 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
// Set our own handler which calls the saved handler.
SrcMgr.setDiagHandler(DiagHandler, this);
Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
- // Make MCStreamer aware of the StartTokLoc for locations in diagnostics.
- Out.setStartTokLocPtr(&StartTokLoc);
+ // Make MCStreamer aware of the StartTokLoc for locations in diagnostics.
+ Out.setStartTokLocPtr(&StartTokLoc);
// Initialize the platform / file format parser.
switch (Ctx.getObjectFileInfo()->getObjectFileType()) {
@@ -749,8 +749,8 @@ AsmParser::~AsmParser() {
assert((HadError || ActiveMacros.empty()) &&
"Unexpected active macro instantiation!");
- // Remove MCStreamer's reference to the parser SMLoc.
- Out.setStartTokLocPtr(nullptr);
+ // Remove MCStreamer's reference to the parser SMLoc.
+ Out.setStartTokLocPtr(nullptr);
// Restore the saved diagnostics handler and context for use during
// finalization.
SrcMgr.setDiagHandler(SavedDiagHandler, SavedDiagContext);
@@ -998,7 +998,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// Finalize the output stream if there are no errors and if the client wants
// us to.
if (!HadError && !NoFinalize)
- Out.Finish(Lexer.getLoc());
+ Out.Finish(Lexer.getLoc());
return HadError || getContext().hadError();
}
@@ -1078,8 +1078,8 @@ bool AsmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
/// primaryexpr ::= number
/// primaryexpr ::= '.'
/// primaryexpr ::= ~,+,- primaryexpr
-bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
- AsmTypeInfo *TypeInfo) {
+bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
+ AsmTypeInfo *TypeInfo) {
SMLoc FirstTokenLoc = getLexer().getLoc();
AsmToken::TokenKind FirstTokenKind = Lexer.getKind();
switch (FirstTokenKind) {
@@ -1090,7 +1090,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
return true;
case AsmToken::Exclaim:
Lex(); // Eat the operator.
- if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
+ if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
return true;
Res = MCUnaryExpr::createLNot(Res, getContext(), FirstTokenLoc);
return false;
@@ -1249,19 +1249,19 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
return parseBracketExpr(Res, EndLoc);
case AsmToken::Minus:
Lex(); // Eat the operator.
- if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
+ if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
return true;
Res = MCUnaryExpr::createMinus(Res, getContext(), FirstTokenLoc);
return false;
case AsmToken::Plus:
Lex(); // Eat the operator.
- if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
+ if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
return true;
Res = MCUnaryExpr::createPlus(Res, getContext(), FirstTokenLoc);
return false;
case AsmToken::Tilde:
Lex(); // Eat the operator.
- if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
+ if (parsePrimaryExpr(Res, EndLoc, TypeInfo))
return true;
Res = MCUnaryExpr::createNot(Res, getContext(), FirstTokenLoc);
return false;
@@ -1568,8 +1568,8 @@ static unsigned getDarwinBinOpPrecedence(AsmToken::TokenKind K,
}
}
-static unsigned getGNUBinOpPrecedence(const MCAsmInfo &MAI,
- AsmToken::TokenKind K,
+static unsigned getGNUBinOpPrecedence(const MCAsmInfo &MAI,
+ AsmToken::TokenKind K,
MCBinaryExpr::Opcode &Kind,
bool ShouldUseLogicalShr) {
switch (K) {
@@ -1613,18 +1613,18 @@ static unsigned getGNUBinOpPrecedence(const MCAsmInfo &MAI,
Kind = MCBinaryExpr::Sub;
return 4;
- // High Intermediate Precedence: |, !, &, ^
+ // High Intermediate Precedence: |, !, &, ^
//
case AsmToken::Pipe:
Kind = MCBinaryExpr::Or;
return 5;
- case AsmToken::Exclaim:
- // Hack to support ARM compatible aliases (implied 'sp' operand in 'srs*'
- // instructions like 'srsda #31!') and not parse ! as an infix operator.
- if (MAI.getCommentString() == "@")
- return 0;
- Kind = MCBinaryExpr::OrNot;
- return 5;
+ case AsmToken::Exclaim:
+ // Hack to support ARM compatible aliases (implied 'sp' operand in 'srs*'
+ // instructions like 'srsda #31!') and not parse ! as an infix operator.
+ if (MAI.getCommentString() == "@")
+ return 0;
+ Kind = MCBinaryExpr::OrNot;
+ return 5;
case AsmToken::Caret:
Kind = MCBinaryExpr::Xor;
return 5;
@@ -1655,7 +1655,7 @@ unsigned AsmParser::getBinOpPrecedence(AsmToken::TokenKind K,
MCBinaryExpr::Opcode &Kind) {
bool ShouldUseLogicalShr = MAI.shouldUseLogicalShr();
return IsDarwin ? getDarwinBinOpPrecedence(K, Kind, ShouldUseLogicalShr)
- : getGNUBinOpPrecedence(MAI, K, Kind, ShouldUseLogicalShr);
+ : getGNUBinOpPrecedence(MAI, K, Kind, ShouldUseLogicalShr);
}
/// Parse all binary operators with precedence >= 'Precedence'.
@@ -1714,7 +1714,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
SMLoc IDLoc = ID.getLoc();
StringRef IDVal;
int64_t LocalLabelVal = -1;
- StartTokLoc = ID.getLoc();
+ StartTokLoc = ID.getLoc();
if (Lexer.is(AsmToken::HashDirective))
return parseCppHashLineFilenameComment(IDLoc,
!isInsideMacroInstantiation());
@@ -2206,8 +2206,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
return parseDirectiveAddrsig();
case DK_ADDRSIG_SYM:
return parseDirectiveAddrsigSym();
- case DK_PSEUDO_PROBE:
- return parseDirectivePseudoProbe();
+ case DK_PSEUDO_PROBE:
+ return parseDirectivePseudoProbe();
}
return Error(IDLoc, "unknown directive");
@@ -3008,20 +3008,20 @@ bool AsmParser::parseAngleBracketString(std::string &Data) {
}
/// parseDirectiveAscii:
-// ::= .ascii [ "string"+ ( , "string"+ )* ]
-/// ::= ( .asciz | .string ) [ "string" ( , "string" )* ]
+// ::= .ascii [ "string"+ ( , "string"+ )* ]
+/// ::= ( .asciz | .string ) [ "string" ( , "string" )* ]
bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
auto parseOp = [&]() -> bool {
std::string Data;
- if (checkForValidSection())
+ if (checkForValidSection())
return true;
- // Only support spaces as separators for .ascii directive for now. See the
- // discusssion at https://reviews.llvm.org/D91460 for more details.
- do {
- if (parseEscapedString(Data))
- return true;
- getStreamer().emitBytes(Data);
- } while (!ZeroTerminated && getTok().is(AsmToken::String));
+ // Only support spaces as separators for .ascii directive for now. See the
+ // discusssion at https://reviews.llvm.org/D91460 for more details.
+ do {
+ if (parseEscapedString(Data))
+ return true;
+ getStreamer().emitBytes(Data);
+ } while (!ZeroTerminated && getTok().is(AsmToken::String));
if (ZeroTerminated)
getStreamer().emitBytes(StringRef("\0", 1));
return false;
@@ -3349,8 +3349,8 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
Alignment = 1;
if (!isPowerOf2_64(Alignment))
ReturnVal |= Error(AlignmentLoc, "alignment must be a power of 2");
- if (!isUInt<32>(Alignment))
- ReturnVal |= Error(AlignmentLoc, "alignment must be smaller than 2**32");
+ if (!isUInt<32>(Alignment))
+ ReturnVal |= Error(AlignmentLoc, "alignment must be smaller than 2**32");
}
// Diagnose non-sensical max bytes to align.
@@ -4092,9 +4092,9 @@ bool AsmParser::parseDirectiveCFISections() {
Debug = true;
}
- if (parseToken(AsmToken::EndOfStatement))
- return addErrorSuffix(" in '.cfi_sections' directive");
-
+ if (parseToken(AsmToken::EndOfStatement))
+ return addErrorSuffix(" in '.cfi_sections' directive");
+
getStreamer().emitCFISections(EH, Debug);
return false;
}
@@ -4122,8 +4122,8 @@ bool AsmParser::parseDirectiveCFIStartProc() {
/// parseDirectiveCFIEndProc
/// ::= .cfi_endproc
bool AsmParser::parseDirectiveCFIEndProc() {
- if (parseToken(AsmToken::EndOfStatement))
- return addErrorSuffix(" in '.cfi_endproc' directive");
+ if (parseToken(AsmToken::EndOfStatement))
+ return addErrorSuffix(" in '.cfi_endproc' directive");
getStreamer().emitCFIEndProc();
return false;
}
@@ -5535,7 +5535,7 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".print"] = DK_PRINT;
DirectiveKindMap[".addrsig"] = DK_ADDRSIG;
DirectiveKindMap[".addrsig_sym"] = DK_ADDRSIG_SYM;
- DirectiveKindMap[".pseudoprobe"] = DK_PSEUDO_PROBE;
+ DirectiveKindMap[".pseudoprobe"] = DK_PSEUDO_PROBE;
}
MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
@@ -5791,69 +5791,69 @@ bool AsmParser::parseDirectiveAddrsigSym() {
return false;
}
-bool AsmParser::parseDirectivePseudoProbe() {
- int64_t Guid;
- int64_t Index;
- int64_t Type;
- int64_t Attr;
-
- if (getLexer().is(AsmToken::Integer)) {
- if (parseIntToken(Guid, "unexpected token in '.pseudoprobe' directive"))
- return true;
- }
-
- if (getLexer().is(AsmToken::Integer)) {
- if (parseIntToken(Index, "unexpected token in '.pseudoprobe' directive"))
- return true;
- }
-
- if (getLexer().is(AsmToken::Integer)) {
- if (parseIntToken(Type, "unexpected token in '.pseudoprobe' directive"))
- return true;
- }
-
- if (getLexer().is(AsmToken::Integer)) {
- if (parseIntToken(Attr, "unexpected token in '.pseudoprobe' directive"))
- return true;
- }
-
- // Parse inline stack like @ GUID:11:12 @ GUID:1:11 @ GUID:3:21
- MCPseudoProbeInlineStack InlineStack;
-
- while (getLexer().is(AsmToken::At)) {
- // eat @
- Lex();
-
- int64_t CallerGuid = 0;
- if (getLexer().is(AsmToken::Integer)) {
- if (parseIntToken(CallerGuid,
- "unexpected token in '.pseudoprobe' directive"))
- return true;
- }
-
- // eat colon
- if (getLexer().is(AsmToken::Colon))
- Lex();
-
- int64_t CallerProbeId = 0;
- if (getLexer().is(AsmToken::Integer)) {
- if (parseIntToken(CallerProbeId,
- "unexpected token in '.pseudoprobe' directive"))
- return true;
- }
-
- InlineSite Site(CallerGuid, CallerProbeId);
- InlineStack.push_back(Site);
- }
-
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.pseudoprobe' directive"))
- return true;
-
- getStreamer().emitPseudoProbe(Guid, Index, Type, Attr, InlineStack);
- return false;
-}
-
+bool AsmParser::parseDirectivePseudoProbe() {
+ int64_t Guid;
+ int64_t Index;
+ int64_t Type;
+ int64_t Attr;
+
+ if (getLexer().is(AsmToken::Integer)) {
+ if (parseIntToken(Guid, "unexpected token in '.pseudoprobe' directive"))
+ return true;
+ }
+
+ if (getLexer().is(AsmToken::Integer)) {
+ if (parseIntToken(Index, "unexpected token in '.pseudoprobe' directive"))
+ return true;
+ }
+
+ if (getLexer().is(AsmToken::Integer)) {
+ if (parseIntToken(Type, "unexpected token in '.pseudoprobe' directive"))
+ return true;
+ }
+
+ if (getLexer().is(AsmToken::Integer)) {
+ if (parseIntToken(Attr, "unexpected token in '.pseudoprobe' directive"))
+ return true;
+ }
+
+ // Parse inline stack like @ GUID:11:12 @ GUID:1:11 @ GUID:3:21
+ MCPseudoProbeInlineStack InlineStack;
+
+ while (getLexer().is(AsmToken::At)) {
+ // eat @
+ Lex();
+
+ int64_t CallerGuid = 0;
+ if (getLexer().is(AsmToken::Integer)) {
+ if (parseIntToken(CallerGuid,
+ "unexpected token in '.pseudoprobe' directive"))
+ return true;
+ }
+
+ // eat colon
+ if (getLexer().is(AsmToken::Colon))
+ Lex();
+
+ int64_t CallerProbeId = 0;
+ if (getLexer().is(AsmToken::Integer)) {
+ if (parseIntToken(CallerProbeId,
+ "unexpected token in '.pseudoprobe' directive"))
+ return true;
+ }
+
+ InlineSite Site(CallerGuid, CallerProbeId);
+ InlineStack.push_back(Site);
+ }
+
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.pseudoprobe' directive"))
+ return true;
+
+ getStreamer().emitPseudoProbe(Guid, Index, Type, Attr, InlineStack);
+ return false;
+}
+
// We are comparing pointers, but the pointers are relative to a single string.
// Thus, this should always be deterministic.
static int rewritesSort(const AsmRewrite *AsmRewriteA,
@@ -5975,7 +5975,7 @@ bool AsmParser::parseMSInlineAsm(
// Consider implicit defs to be clobbers. Think of cpuid and push.
ArrayRef<MCPhysReg> ImpDefs(Desc.getImplicitDefs(),
Desc.getNumImplicitDefs());
- llvm::append_range(ClobberRegs, ImpDefs);
+ llvm::append_range(ClobberRegs, ImpDefs);
}
// Set the number of Outputs and Inputs.
diff --git a/contrib/libs/llvm12/lib/MC/MCParser/COFFAsmParser.cpp b/contrib/libs/llvm12/lib/MC/MCParser/COFFAsmParser.cpp
index d823afa49c..3ac6a88341 100644
--- a/contrib/libs/llvm12/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCParser/COFFAsmParser.cpp
@@ -77,8 +77,8 @@ class COFFAsmParser : public MCAsmParserExtension {
".seh_proc");
addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
".seh_endproc");
- addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndFuncletOrFunc>(
- ".seh_endfunclet");
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndFuncletOrFunc>(
+ ".seh_endfunclet");
addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
".seh_startchained");
addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
@@ -133,7 +133,7 @@ class COFFAsmParser : public MCAsmParserExtension {
// Win64 EH directives.
bool ParseSEHDirectiveStartProc(StringRef, SMLoc);
bool ParseSEHDirectiveEndProc(StringRef, SMLoc);
- bool ParseSEHDirectiveEndFuncletOrFunc(StringRef, SMLoc);
+ bool ParseSEHDirectiveEndFuncletOrFunc(StringRef, SMLoc);
bool ParseSEHDirectiveStartChained(StringRef, SMLoc);
bool ParseSEHDirectiveEndChained(StringRef, SMLoc);
bool ParseSEHDirectiveHandler(StringRef, SMLoc);
@@ -631,12 +631,12 @@ bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc Loc) {
return false;
}
-bool COFFAsmParser::ParseSEHDirectiveEndFuncletOrFunc(StringRef, SMLoc Loc) {
- Lex();
- getStreamer().EmitWinCFIFuncletOrFuncEnd(Loc);
- return false;
-}
-
+bool COFFAsmParser::ParseSEHDirectiveEndFuncletOrFunc(StringRef, SMLoc Loc) {
+ Lex();
+ getStreamer().EmitWinCFIFuncletOrFuncEnd(Loc);
+ return false;
+}
+
bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc Loc) {
Lex();
getStreamer().EmitWinCFIStartChained(Loc);
diff --git a/contrib/libs/llvm12/lib/MC/MCParser/COFFMasmParser.cpp b/contrib/libs/llvm12/lib/MC/MCParser/COFFMasmParser.cpp
index 89b44bf6ba..95128cf7d1 100644
--- a/contrib/libs/llvm12/lib/MC/MCParser/COFFMasmParser.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCParser/COFFMasmParser.cpp
@@ -20,7 +20,7 @@
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCSymbolCOFF.h"
+#include "llvm/MC/MCSymbolCOFF.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/SMLoc.h"
#include <cassert>
@@ -53,11 +53,11 @@ class COFFMasmParser : public MCAsmParserExtension {
bool ParseDirectiveSegmentEnd(StringRef, SMLoc);
bool ParseDirectiveIncludelib(StringRef, SMLoc);
- bool ParseDirectiveAlias(StringRef, SMLoc);
-
- bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
- bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
-
+ bool ParseDirectiveAlias(StringRef, SMLoc);
+
+ bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
+ bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
+
bool IgnoreDirective(StringRef, SMLoc) {
while (!getLexer().is(AsmToken::EndOfStatement)) {
Lex();
@@ -70,10 +70,10 @@ class COFFMasmParser : public MCAsmParserExtension {
MCAsmParserExtension::Initialize(Parser);
// x64 directives
- addDirectiveHandler<&COFFMasmParser::ParseSEHDirectiveAllocStack>(
- ".allocstack");
- addDirectiveHandler<&COFFMasmParser::ParseSEHDirectiveEndProlog>(
- ".endprolog");
+ addDirectiveHandler<&COFFMasmParser::ParseSEHDirectiveAllocStack>(
+ ".allocstack");
+ addDirectiveHandler<&COFFMasmParser::ParseSEHDirectiveEndProlog>(
+ ".endprolog");
// Code label directives
// label
@@ -95,10 +95,10 @@ class COFFMasmParser : public MCAsmParserExtension {
// Data allocation directives
// align
// even
- // mmword
+ // mmword
// tbyte
- // xmmword
- // ymmword
+ // xmmword
+ // ymmword
// Listing control directives
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".cref");
@@ -120,7 +120,7 @@ class COFFMasmParser : public MCAsmParserExtension {
// goto
// Miscellaneous directives
- addDirectiveHandler<&COFFMasmParser::ParseDirectiveAlias>("alias");
+ addDirectiveHandler<&COFFMasmParser::ParseDirectiveAlias>("alias");
// assume
// .fpo
addDirectiveHandler<&COFFMasmParser::ParseDirectiveIncludelib>(
@@ -136,7 +136,7 @@ class COFFMasmParser : public MCAsmParserExtension {
addDirectiveHandler<&COFFMasmParser::ParseDirectiveProc>("proc");
// proto
- // Processor directives; all ignored
+ // Processor directives; all ignored
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".386");
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".386P");
addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(".387");
@@ -212,7 +212,7 @@ class COFFMasmParser : public MCAsmParserExtension {
}
StringRef CurrentProcedure;
- bool CurrentProcedureFramed;
+ bool CurrentProcedureFramed;
public:
COFFMasmParser() = default;
@@ -332,23 +332,23 @@ bool COFFMasmParser::ParseDirectiveProc(StringRef Directive, SMLoc Loc) {
nextLoc = getTok().getLoc();
}
}
- MCSymbolCOFF *Sym = cast<MCSymbolCOFF>(getContext().getOrCreateSymbol(Label));
-
- // Define symbol as simple external function
- Sym->setExternal(true);
- Sym->setType(COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT);
-
- bool Framed = false;
- if (getLexer().is(AsmToken::Identifier) &&
- getTok().getString().equals_lower("frame")) {
- Lex();
- Framed = true;
- getStreamer().EmitWinCFIStartProc(Sym, Loc);
- }
+ MCSymbolCOFF *Sym = cast<MCSymbolCOFF>(getContext().getOrCreateSymbol(Label));
+
+ // Define symbol as simple external function
+ Sym->setExternal(true);
+ Sym->setType(COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT);
+
+ bool Framed = false;
+ if (getLexer().is(AsmToken::Identifier) &&
+ getTok().getString().equals_lower("frame")) {
+ Lex();
+ Framed = true;
+ getStreamer().EmitWinCFIStartProc(Sym, Loc);
+ }
getStreamer().emitLabel(Sym, Loc);
-
+
CurrentProcedure = Label;
- CurrentProcedureFramed = Framed;
+ CurrentProcedureFramed = Framed;
return false;
}
bool COFFMasmParser::ParseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
@@ -362,52 +362,52 @@ bool COFFMasmParser::ParseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
else if (CurrentProcedure != Label)
return Error(LabelLoc, "endp does not match current procedure '" +
CurrentProcedure + "'");
-
- if (CurrentProcedureFramed) {
- getStreamer().EmitWinCFIEndProc(Loc);
- }
- CurrentProcedure = "";
- CurrentProcedureFramed = false;
+
+ if (CurrentProcedureFramed) {
+ getStreamer().EmitWinCFIEndProc(Loc);
+ }
+ CurrentProcedure = "";
+ CurrentProcedureFramed = false;
+ return false;
+}
+
+bool COFFMasmParser::ParseDirectiveAlias(StringRef Directive, SMLoc Loc) {
+ std::string AliasName, ActualName;
+ if (getTok().isNot(AsmToken::Less) ||
+ getParser().parseAngleBracketString(AliasName))
+ return Error(getTok().getLoc(), "expected <aliasName>");
+ if (getParser().parseToken(AsmToken::Equal))
+ return addErrorSuffix(" in " + Directive + " directive");
+ if (getTok().isNot(AsmToken::Less) ||
+ getParser().parseAngleBracketString(ActualName))
+ return Error(getTok().getLoc(), "expected <actualName>");
+
+ MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
+ MCSymbol *Actual = getContext().getOrCreateSymbol(ActualName);
+
+ getStreamer().emitWeakReference(Alias, Actual);
+
+ return false;
+}
+
+bool COFFMasmParser::ParseSEHDirectiveAllocStack(StringRef Directive,
+ SMLoc Loc) {
+ int64_t Size;
+ SMLoc SizeLoc = getTok().getLoc();
+ if (getParser().parseAbsoluteExpression(Size))
+ return Error(SizeLoc, "expected integer size");
+ if (Size % 8 != 0)
+ return Error(SizeLoc, "stack size must be a multiple of 8");
+ getStreamer().EmitWinCFIAllocStack(static_cast<unsigned>(Size), Loc);
+ return false;
+}
+
+bool COFFMasmParser::ParseSEHDirectiveEndProlog(StringRef Directive,
+ SMLoc Loc) {
+ getStreamer().EmitWinCFIEndProlog(Loc);
return false;
}
-bool COFFMasmParser::ParseDirectiveAlias(StringRef Directive, SMLoc Loc) {
- std::string AliasName, ActualName;
- if (getTok().isNot(AsmToken::Less) ||
- getParser().parseAngleBracketString(AliasName))
- return Error(getTok().getLoc(), "expected <aliasName>");
- if (getParser().parseToken(AsmToken::Equal))
- return addErrorSuffix(" in " + Directive + " directive");
- if (getTok().isNot(AsmToken::Less) ||
- getParser().parseAngleBracketString(ActualName))
- return Error(getTok().getLoc(), "expected <actualName>");
-
- MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
- MCSymbol *Actual = getContext().getOrCreateSymbol(ActualName);
-
- getStreamer().emitWeakReference(Alias, Actual);
-
- return false;
-}
-
-bool COFFMasmParser::ParseSEHDirectiveAllocStack(StringRef Directive,
- SMLoc Loc) {
- int64_t Size;
- SMLoc SizeLoc = getTok().getLoc();
- if (getParser().parseAbsoluteExpression(Size))
- return Error(SizeLoc, "expected integer size");
- if (Size % 8 != 0)
- return Error(SizeLoc, "stack size must be a multiple of 8");
- getStreamer().EmitWinCFIAllocStack(static_cast<unsigned>(Size), Loc);
- return false;
-}
-
-bool COFFMasmParser::ParseSEHDirectiveEndProlog(StringRef Directive,
- SMLoc Loc) {
- getStreamer().EmitWinCFIEndProlog(Loc);
- return false;
-}
-
namespace llvm {
MCAsmParserExtension *createCOFFMasmParser() { return new COFFMasmParser; }
diff --git a/contrib/libs/llvm12/lib/MC/MCParser/DarwinAsmParser.cpp b/contrib/libs/llvm12/lib/MC/MCParser/DarwinAsmParser.cpp
index 0d0067f99d..9264834512 100644
--- a/contrib/libs/llvm12/lib/MC/MCParser/DarwinAsmParser.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -1152,7 +1152,7 @@ static Triple::OSType getOSTypeFromPlatform(MachO::PlatformType Type) {
case MachO::PLATFORM_IOSSIMULATOR: /* silence warning */ break;
case MachO::PLATFORM_TVOSSIMULATOR: /* silence warning */ break;
case MachO::PLATFORM_WATCHOSSIMULATOR: /* silence warning */ break;
- case MachO::PLATFORM_DRIVERKIT: /* silence warning */ break;
+ case MachO::PLATFORM_DRIVERKIT: /* silence warning */ break;
}
llvm_unreachable("Invalid mach-o platform type");
}
diff --git a/contrib/libs/llvm12/lib/MC/MCParser/ELFAsmParser.cpp b/contrib/libs/llvm12/lib/MC/MCParser/ELFAsmParser.cpp
index b270ac543d..65ac1d6b5b 100644
--- a/contrib/libs/llvm12/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCParser/ELFAsmParser.cpp
@@ -450,14 +450,14 @@ bool ELFAsmParser::parseLinkedToSym(MCSymbolELF *&LinkedToSym) {
Lex();
StringRef Name;
SMLoc StartLoc = L.getLoc();
- if (getParser().parseIdentifier(Name)) {
- if (getParser().getTok().getString() == "0") {
- getParser().Lex();
- LinkedToSym = nullptr;
- return false;
- }
+ if (getParser().parseIdentifier(Name)) {
+ if (getParser().getTok().getString() == "0") {
+ getParser().Lex();
+ LinkedToSym = nullptr;
+ return false;
+ }
return TokError("invalid linked-to symbol");
- }
+ }
LinkedToSym = dyn_cast_or_null<MCSymbolELF>(getContext().lookupSymbol(Name));
if (!LinkedToSym || !LinkedToSym->isInSection())
return Error(StartLoc, "linked-to symbol is not in a section: " + Name);
@@ -626,8 +626,8 @@ EndStmt:
Type = ELF::SHT_LLVM_DEPENDENT_LIBRARIES;
else if (TypeName == "llvm_sympart")
Type = ELF::SHT_LLVM_SYMPART;
- else if (TypeName == "llvm_bb_addr_map")
- Type = ELF::SHT_LLVM_BB_ADDR_MAP;
+ else if (TypeName == "llvm_bb_addr_map")
+ Type = ELF::SHT_LLVM_BB_ADDR_MAP;
else if (TypeName.getAsInteger(0, Type))
return TokError("unknown section type");
}
@@ -662,9 +662,9 @@ EndStmt:
Error(loc, "changed section entsize for " + SectionName +
", expected: " + Twine(Section->getEntrySize()));
- if (getContext().getGenDwarfForAssembly() &&
- (Section->getFlags() & ELF::SHF_ALLOC) &&
- (Section->getFlags() & ELF::SHF_EXECINSTR)) {
+ if (getContext().getGenDwarfForAssembly() &&
+ (Section->getFlags() & ELF::SHF_ALLOC) &&
+ (Section->getFlags() & ELF::SHF_EXECINSTR)) {
bool InsertResult = getContext().addGenDwarfSection(Section);
if (InsertResult) {
if (getContext().getDwarfVersion() <= 2)
diff --git a/contrib/libs/llvm12/lib/MC/MCParser/MasmParser.cpp b/contrib/libs/llvm12/lib/MC/MCParser/MasmParser.cpp
index 7ec0c16abe..4957ee7a03 100644
--- a/contrib/libs/llvm12/lib/MC/MCParser/MasmParser.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCParser/MasmParser.cpp
@@ -14,14 +14,14 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
@@ -52,7 +52,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Format.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -108,9 +108,9 @@ struct ParseStatementInfo {
/// Was there an error parsing the inline assembly?
bool ParseError = false;
- /// The value associated with a macro exit.
- Optional<std::string> ExitValue;
-
+ /// The value associated with a macro exit.
+ Optional<std::string> ExitValue;
+
SmallVectorImpl<AsmRewrite> *AsmRewrites = nullptr;
ParseStatementInfo() = delete;
@@ -128,14 +128,14 @@ struct FieldInfo;
struct StructInfo {
StringRef Name;
bool IsUnion = false;
- unsigned Alignment = 0;
- unsigned Size = 0;
- unsigned AlignmentSize = 0;
+ unsigned Alignment = 0;
+ unsigned Size = 0;
+ unsigned AlignmentSize = 0;
std::vector<FieldInfo> Fields;
StringMap<size_t> FieldsByName;
- FieldInfo &addField(StringRef FieldName, FieldType FT,
- unsigned FieldAlignmentSize);
+ FieldInfo &addField(StringRef FieldName, FieldType FT,
+ unsigned FieldAlignmentSize);
StructInfo() = default;
@@ -325,32 +325,32 @@ struct FieldInfo {
size_t Offset = 0;
// Total size of the field (= LengthOf * Type).
- unsigned SizeOf = 0;
+ unsigned SizeOf = 0;
// Number of elements in the field (1 if scalar, >1 if an array).
- unsigned LengthOf = 0;
+ unsigned LengthOf = 0;
// Size of a single entry in this field, in bytes ("type" in MASM standards).
- unsigned Type = 0;
+ unsigned Type = 0;
FieldInitializer Contents;
FieldInfo(FieldType FT) : Contents(FT) {}
};
-FieldInfo &StructInfo::addField(StringRef FieldName, FieldType FT,
- unsigned FieldAlignmentSize) {
+FieldInfo &StructInfo::addField(StringRef FieldName, FieldType FT,
+ unsigned FieldAlignmentSize) {
if (!FieldName.empty())
- FieldsByName[FieldName.lower()] = Fields.size();
+ FieldsByName[FieldName.lower()] = Fields.size();
Fields.emplace_back(FT);
FieldInfo &Field = Fields.back();
if (IsUnion) {
Field.Offset = 0;
} else {
- Size = llvm::alignTo(Size, std::min(Alignment, FieldAlignmentSize));
+ Size = llvm::alignTo(Size, std::min(Alignment, FieldAlignmentSize));
Field.Offset = Size;
}
- AlignmentSize = std::max(AlignmentSize, FieldAlignmentSize);
+ AlignmentSize = std::max(AlignmentSize, FieldAlignmentSize);
return Field;
}
@@ -371,7 +371,7 @@ private:
/// This is the current buffer index we're lexing from as managed by the
/// SourceMgr object.
unsigned CurBuffer;
- std::vector<bool> EndStatementAtEOFStack;
+ std::vector<bool> EndStatementAtEOFStack;
AsmCond TheCondState;
std::vector<AsmCond> TheCondStack;
@@ -397,8 +397,8 @@ private:
/// Maps struct tags to struct definitions.
StringMap<StructInfo> Structs;
- /// Maps data location names to types.
- StringMap<AsmTypeInfo> KnownType;
+ /// Maps data location names to types.
+ StringMap<AsmTypeInfo> KnownType;
/// Stack of active macro instantiations.
std::vector<MacroInstantiation*> ActiveMacros;
@@ -441,9 +441,9 @@ private:
// Current <...> expression depth.
unsigned AngleBracketDepth = 0U;
- // Number of locals defined.
- uint16_t LocalCounter = 0;
-
+ // Number of locals defined.
+ uint16_t LocalCounter = 0;
+
public:
MasmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
const MCAsmInfo &MAI, unsigned CB);
@@ -501,14 +501,14 @@ public:
bool isParsingMasm() const override { return true; }
- bool defineMacro(StringRef Name, StringRef Value) override;
+ bool defineMacro(StringRef Name, StringRef Value) override;
+
+ bool lookUpField(StringRef Name, AsmFieldInfo &Info) const override;
+ bool lookUpField(StringRef Base, StringRef Member,
+ AsmFieldInfo &Info) const override;
+
+ bool lookUpType(StringRef Name, AsmTypeInfo &Info) const override;
- bool lookUpField(StringRef Name, AsmFieldInfo &Info) const override;
- bool lookUpField(StringRef Base, StringRef Member,
- AsmFieldInfo &Info) const override;
-
- bool lookUpType(StringRef Name, AsmTypeInfo &Info) const override;
-
bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
unsigned &NumOutputs, unsigned &NumInputs,
SmallVectorImpl<std::pair<void *,bool>> &OpDecls,
@@ -519,8 +519,8 @@ public:
bool parseExpression(const MCExpr *&Res);
bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
- bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
- AsmTypeInfo *TypeInfo) override;
+ bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
+ AsmTypeInfo *TypeInfo) override;
bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
SMLoc &EndLoc) override;
@@ -547,8 +547,8 @@ private:
bool expandMacro(raw_svector_ostream &OS, StringRef Body,
ArrayRef<MCAsmMacroParameter> Parameters,
- ArrayRef<MCAsmMacroArgument> A,
- const std::vector<std::string> &Locals, SMLoc L);
+ ArrayRef<MCAsmMacroArgument> A,
+ const std::vector<std::string> &Locals, SMLoc L);
/// Are we inside a macro instantiation?
bool isInsideMacroInstantiation() {return !ActiveMacros.empty();}
@@ -557,33 +557,33 @@ private:
///
/// \param M The macro.
/// \param NameLoc Instantiation location.
- bool handleMacroEntry(
- const MCAsmMacro *M, SMLoc NameLoc,
- AsmToken::TokenKind ArgumentEndTok = AsmToken::EndOfStatement);
-
- /// Handle invocation of macro function.
- ///
- /// \param M The macro.
- /// \param NameLoc Invocation location.
- bool handleMacroInvocation(const MCAsmMacro *M, SMLoc NameLoc);
-
+ bool handleMacroEntry(
+ const MCAsmMacro *M, SMLoc NameLoc,
+ AsmToken::TokenKind ArgumentEndTok = AsmToken::EndOfStatement);
+
+ /// Handle invocation of macro function.
+ ///
+ /// \param M The macro.
+ /// \param NameLoc Invocation location.
+ bool handleMacroInvocation(const MCAsmMacro *M, SMLoc NameLoc);
+
/// Handle exit from macro instantiation.
void handleMacroExit();
/// Extract AsmTokens for a macro argument.
- bool
- parseMacroArgument(const MCAsmMacroParameter *MP, MCAsmMacroArgument &MA,
- AsmToken::TokenKind EndTok = AsmToken::EndOfStatement);
+ bool
+ parseMacroArgument(const MCAsmMacroParameter *MP, MCAsmMacroArgument &MA,
+ AsmToken::TokenKind EndTok = AsmToken::EndOfStatement);
/// Parse all macro arguments for a given macro.
- bool
- parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A,
- AsmToken::TokenKind EndTok = AsmToken::EndOfStatement);
+ bool
+ parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A,
+ AsmToken::TokenKind EndTok = AsmToken::EndOfStatement);
void printMacroInstantiations();
-
- bool expandStatement(SMLoc Loc);
-
+
+ bool expandStatement(SMLoc Loc);
+
void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
SMRange Range = None) const {
ArrayRef<SMRange> Ranges(Range);
@@ -592,7 +592,7 @@ private:
static void DiagHandler(const SMDiagnostic &Diag, void *Context);
bool lookUpField(const StructInfo &Structure, StringRef Member,
- AsmFieldInfo &Info) const;
+ AsmFieldInfo &Info) const;
/// Should we emit DWARF describing this assembler source? (Returns false if
/// the source has .file directives, which means we don't want to generate
@@ -608,19 +608,19 @@ private:
///
/// \param InBuffer If not 0, should be the known buffer id that contains the
/// location.
- void jumpToLoc(SMLoc Loc, unsigned InBuffer = 0,
- bool EndStatementAtEOF = true);
-
- /// Parse up to a token of kind \p EndTok and return the contents from the
- /// current token up to (but not including) this token; the current token on
- /// exit will be either this kind or EOF. Reads through instantiated macro
- /// functions and text macros.
- SmallVector<StringRef, 1> parseStringRefsTo(AsmToken::TokenKind EndTok);
- std::string parseStringTo(AsmToken::TokenKind EndTok);
-
- /// 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.
+ void jumpToLoc(SMLoc Loc, unsigned InBuffer = 0,
+ bool EndStatementAtEOF = true);
+
+ /// Parse up to a token of kind \p EndTok and return the contents from the
+ /// current token up to (but not including) this token; the current token on
+ /// exit will be either this kind or EOF. Reads through instantiated macro
+ /// functions and text macros.
+ SmallVector<StringRef, 1> parseStringRefsTo(AsmToken::TokenKind EndTok);
+ std::string parseStringTo(AsmToken::TokenKind EndTok);
+
+ /// 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.
StringRef parseStringToEndOfStatement() override;
bool parseTextItem(std::string &Data);
@@ -658,12 +658,12 @@ private:
DK_SQWORD,
DK_DB,
DK_DD,
- DK_DF,
+ DK_DF,
DK_DQ,
DK_DW,
DK_REAL4,
DK_REAL8,
- DK_REAL10,
+ DK_REAL10,
DK_ALIGN,
DK_ORG,
DK_ENDR,
@@ -672,10 +672,10 @@ private:
DK_COMM,
DK_COMMENT,
DK_INCLUDE,
- DK_REPEAT,
- DK_WHILE,
- DK_FOR,
- DK_FORC,
+ DK_REPEAT,
+ DK_WHILE,
+ DK_FOR,
+ DK_FORC,
DK_IF,
DK_IFE,
DK_IFB,
@@ -739,7 +739,7 @@ private:
DK_MACRO,
DK_EXITM,
DK_ENDM,
- DK_PURGE,
+ DK_PURGE,
DK_ERR,
DK_ERRB,
DK_ERRNB,
@@ -755,21 +755,21 @@ private:
DK_STRUCT,
DK_UNION,
DK_ENDS,
- DK_END,
- DK_PUSHFRAME,
- DK_PUSHREG,
- DK_SAVEREG,
- DK_SAVEXMM128,
- DK_SETFRAME,
- DK_RADIX,
+ DK_END,
+ DK_PUSHFRAME,
+ DK_PUSHREG,
+ DK_SAVEREG,
+ DK_SAVEXMM128,
+ DK_SETFRAME,
+ DK_RADIX,
};
/// Maps directive name --> DirectiveKind enum, for directives parsed by this
/// class.
StringMap<DirectiveKind> DirectiveKindMap;
- bool isMacroLikeDirective();
-
+ bool isMacroLikeDirective();
+
// Codeview def_range type parsing.
enum CVDefRangeType {
CVDR_DEFRANGE = 0, // Placeholder
@@ -794,24 +794,24 @@ private:
bool parseScalarInstList(
unsigned Size, SmallVectorImpl<const MCExpr *> &Values,
const AsmToken::TokenKind EndToken = AsmToken::EndOfStatement);
- bool emitIntegralValues(unsigned Size, unsigned *Count = nullptr);
+ bool emitIntegralValues(unsigned Size, unsigned *Count = nullptr);
bool addIntegralField(StringRef Name, unsigned Size);
bool parseDirectiveValue(StringRef IDVal, unsigned Size);
- bool parseDirectiveNamedValue(StringRef TypeName, unsigned Size,
- StringRef Name, SMLoc NameLoc);
-
- // "real4", "real8", "real10"
- bool emitRealValues(const fltSemantics &Semantics, unsigned *Count = nullptr);
- bool addRealField(StringRef Name, const fltSemantics &Semantics, size_t Size);
- bool parseDirectiveRealValue(StringRef IDVal, const fltSemantics &Semantics,
- size_t Size);
+ bool parseDirectiveNamedValue(StringRef TypeName, unsigned Size,
+ StringRef Name, SMLoc NameLoc);
+
+ // "real4", "real8", "real10"
+ bool emitRealValues(const fltSemantics &Semantics, unsigned *Count = nullptr);
+ bool addRealField(StringRef Name, const fltSemantics &Semantics, size_t Size);
+ bool parseDirectiveRealValue(StringRef IDVal, const fltSemantics &Semantics,
+ size_t Size);
bool parseRealInstList(
const fltSemantics &Semantics, SmallVectorImpl<APInt> &Values,
const AsmToken::TokenKind EndToken = AsmToken::EndOfStatement);
- bool parseDirectiveNamedRealValue(StringRef TypeName,
+ bool parseDirectiveNamedRealValue(StringRef TypeName,
const fltSemantics &Semantics,
- unsigned Size, StringRef Name,
- SMLoc NameLoc);
+ unsigned Size, StringRef Name,
+ SMLoc NameLoc);
bool parseOptionalAngleBracketOpen();
bool parseAngleBracketClose(const Twine &Msg = "expected '>'");
@@ -855,7 +855,7 @@ private:
const StructInitializer &Initializer);
// User-defined types (structs, unions):
- bool emitStructValues(const StructInfo &Structure, unsigned *Count = nullptr);
+ bool emitStructValues(const StructInfo &Structure, unsigned *Count = nullptr);
bool addStructField(StringRef Name, const StructInfo &Structure);
bool parseDirectiveStructValue(const StructInfo &Structure,
StringRef Directive, SMLoc DirLoc);
@@ -915,10 +915,10 @@ private:
// macro directives
bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);
- bool parseDirectiveExitMacro(SMLoc DirectiveLoc, StringRef Directive,
- std::string &Value);
+ bool parseDirectiveExitMacro(SMLoc DirectiveLoc, StringRef Directive,
+ std::string &Value);
bool parseDirectiveEndMacro(StringRef Directive);
- bool parseDirectiveMacro(StringRef Name, SMLoc NameLoc);
+ bool parseDirectiveMacro(StringRef Name, SMLoc NameLoc);
bool parseDirectiveStruct(StringRef Directive, DirectiveKind DirKind,
StringRef Name, SMLoc NameLoc);
@@ -965,12 +965,12 @@ private:
MCAsmMacro *parseMacroLikeBody(SMLoc DirectiveLoc);
void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
raw_svector_ostream &OS);
- void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
- SMLoc ExitLoc, raw_svector_ostream &OS);
- bool parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Directive);
- bool parseDirectiveFor(SMLoc DirectiveLoc, StringRef Directive);
- bool parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive);
- bool parseDirectiveWhile(SMLoc DirectiveLoc);
+ void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
+ SMLoc ExitLoc, raw_svector_ostream &OS);
+ bool parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Directive);
+ bool parseDirectiveFor(SMLoc DirectiveLoc, StringRef Directive);
+ bool parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive);
+ bool parseDirectiveWhile(SMLoc DirectiveLoc);
// "_emit" or "__emit"
bool parseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info,
@@ -995,9 +995,9 @@ private:
// ".erre" or ".errnz", depending on ExpectZero.
bool parseDirectiveErrorIfe(SMLoc DirectiveLoc, bool ExpectZero);
- // ".radix"
- bool parseDirectiveRadix(SMLoc DirectiveLoc);
-
+ // ".radix"
+ bool parseDirectiveRadix(SMLoc DirectiveLoc);
+
// "echo"
bool parseDirectiveEcho();
@@ -1026,7 +1026,7 @@ MasmParser::MasmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
// Set our own handler which calls the saved handler.
SrcMgr.setDiagHandler(DiagHandler, this);
Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
- EndStatementAtEOFStack.push_back(true);
+ EndStatementAtEOFStack.push_back(true);
// Initialize the platform / file format parser.
switch (Ctx.getObjectFileInfo()->getObjectFileType()) {
@@ -1096,15 +1096,15 @@ bool MasmParser::enterIncludeFile(const std::string &Filename) {
CurBuffer = NewBuf;
Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
- EndStatementAtEOFStack.push_back(true);
+ EndStatementAtEOFStack.push_back(true);
return false;
}
-void MasmParser::jumpToLoc(SMLoc Loc, unsigned InBuffer,
- bool EndStatementAtEOF) {
+void MasmParser::jumpToLoc(SMLoc Loc, unsigned InBuffer,
+ bool EndStatementAtEOF) {
CurBuffer = InBuffer ? InBuffer : SrcMgr.FindBufferContainingLoc(Loc);
Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(),
- Loc.getPointer(), EndStatementAtEOF);
+ Loc.getPointer(), EndStatementAtEOF);
}
const AsmToken &MasmParser::Lex() {
@@ -1122,11 +1122,11 @@ const AsmToken &MasmParser::Lex() {
const AsmToken *tok = &Lexer.Lex();
while (tok->is(AsmToken::Identifier)) {
- auto it = Variables.find(tok->getIdentifier().lower());
- const llvm::MCAsmMacro *M =
- getContext().lookupMacro(tok->getIdentifier().lower());
+ auto it = Variables.find(tok->getIdentifier().lower());
+ const llvm::MCAsmMacro *M =
+ getContext().lookupMacro(tok->getIdentifier().lower());
if (it != Variables.end() && it->second.IsText) {
- // This is a textmacro; expand it in place.
+ // This is a textmacro; expand it in place.
std::unique_ptr<MemoryBuffer> Instantiation =
MemoryBuffer::getMemBufferCopy(it->second.TextValue,
"<instantiation>");
@@ -1136,17 +1136,17 @@ const AsmToken &MasmParser::Lex() {
getTok().getEndLoc());
Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(), nullptr,
/*EndStatementAtEOF=*/false);
- EndStatementAtEOFStack.push_back(false);
+ EndStatementAtEOFStack.push_back(false);
+ tok = &Lexer.Lex();
+ } else if (M && M->IsFunction && Lexer.peekTok().is(AsmToken::LParen)) {
+ // This is a macro function invocation; expand it in place.
+ const AsmToken MacroTok = *tok;
tok = &Lexer.Lex();
- } else if (M && M->IsFunction && Lexer.peekTok().is(AsmToken::LParen)) {
- // This is a macro function invocation; expand it in place.
- const AsmToken MacroTok = *tok;
- tok = &Lexer.Lex();
- if (handleMacroInvocation(M, MacroTok.getLoc())) {
- Lexer.UnLex(AsmToken(AsmToken::Error, MacroTok.getIdentifier()));
- tok = &Lexer.Lex();
- }
- continue;
+ if (handleMacroInvocation(M, MacroTok.getLoc())) {
+ Lexer.UnLex(AsmToken(AsmToken::Error, MacroTok.getIdentifier()));
+ tok = &Lexer.Lex();
+ }
+ continue;
} else {
break;
}
@@ -1159,25 +1159,25 @@ const AsmToken &MasmParser::Lex() {
tok = &Lexer.Lex();
}
- // Recognize and bypass line continuations.
- while (tok->is(AsmToken::BackSlash) &&
- Lexer.peekTok().is(AsmToken::EndOfStatement)) {
- // Eat both the backslash and the end of statement.
- Lexer.Lex();
- tok = &Lexer.Lex();
- }
-
+ // Recognize and bypass line continuations.
+ while (tok->is(AsmToken::BackSlash) &&
+ Lexer.peekTok().is(AsmToken::EndOfStatement)) {
+ // Eat both the backslash and the end of statement.
+ Lexer.Lex();
+ tok = &Lexer.Lex();
+ }
+
if (tok->is(AsmToken::Eof)) {
// If this is the end of an included file, pop the parent file off the
// include stack.
SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
if (ParentIncludeLoc != SMLoc()) {
- EndStatementAtEOFStack.pop_back();
- jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
+ EndStatementAtEOFStack.pop_back();
+ jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
return Lex();
}
- EndStatementAtEOFStack.pop_back();
- assert(EndStatementAtEOFStack.empty());
+ EndStatementAtEOFStack.pop_back();
+ assert(EndStatementAtEOFStack.empty());
}
return *tok;
@@ -1236,12 +1236,12 @@ bool MasmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
}
// While we have input, parse each statement.
- while (Lexer.isNot(AsmToken::Eof) ||
- SrcMgr.getParentIncludeLoc(CurBuffer) != SMLoc()) {
- // Skip through the EOF at the end of an inclusion.
- if (Lexer.is(AsmToken::Eof))
- Lex();
-
+ while (Lexer.isNot(AsmToken::Eof) ||
+ SrcMgr.getParentIncludeLoc(CurBuffer) != SMLoc()) {
+ // Skip through the EOF at the end of an inclusion.
+ if (Lexer.is(AsmToken::Eof))
+ Lex();
+
ParseStatementInfo Info(&AsmStrRewrites);
bool Parsed = parseStatement(Info, nullptr);
@@ -1319,7 +1319,7 @@ bool MasmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// Finalize the output stream if there are no errors and if the client wants
// us to.
if (!HadError && !NoFinalize)
- Out.Finish(Lexer.getLoc());
+ Out.Finish(Lexer.getLoc());
return HadError || getContext().hadError();
}
@@ -1335,58 +1335,58 @@ bool MasmParser::checkForValidSection() {
/// Throw away the rest of the line for testing purposes.
void MasmParser::eatToEndOfStatement() {
- while (Lexer.isNot(AsmToken::EndOfStatement)) {
- if (Lexer.is(AsmToken::Eof)) {
- SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
- if (ParentIncludeLoc == SMLoc()) {
- break;
- }
-
- EndStatementAtEOFStack.pop_back();
- jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
- }
-
+ while (Lexer.isNot(AsmToken::EndOfStatement)) {
+ if (Lexer.is(AsmToken::Eof)) {
+ SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
+ if (ParentIncludeLoc == SMLoc()) {
+ break;
+ }
+
+ EndStatementAtEOFStack.pop_back();
+ jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
+ }
+
Lexer.Lex();
- }
+ }
// Eat EOL.
if (Lexer.is(AsmToken::EndOfStatement))
Lexer.Lex();
}
-SmallVector<StringRef, 1>
-MasmParser::parseStringRefsTo(AsmToken::TokenKind EndTok) {
- SmallVector<StringRef, 1> Refs;
- const char *Start = getTok().getLoc().getPointer();
- while (Lexer.isNot(EndTok)) {
- if (Lexer.is(AsmToken::Eof)) {
- SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
- if (ParentIncludeLoc == SMLoc()) {
- break;
- }
- Refs.emplace_back(Start, getTok().getLoc().getPointer() - Start);
-
- EndStatementAtEOFStack.pop_back();
- jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
- Lexer.Lex();
- Start = getTok().getLoc().getPointer();
- } else {
- Lexer.Lex();
- }
- }
- Refs.emplace_back(Start, getTok().getLoc().getPointer() - Start);
- return Refs;
-}
-
-std::string MasmParser::parseStringTo(AsmToken::TokenKind EndTok) {
- SmallVector<StringRef, 1> Refs = parseStringRefsTo(EndTok);
- std::string Str;
- for (StringRef S : Refs) {
- Str.append(S.str());
- }
- return Str;
-}
-
+SmallVector<StringRef, 1>
+MasmParser::parseStringRefsTo(AsmToken::TokenKind EndTok) {
+ SmallVector<StringRef, 1> Refs;
+ const char *Start = getTok().getLoc().getPointer();
+ while (Lexer.isNot(EndTok)) {
+ if (Lexer.is(AsmToken::Eof)) {
+ SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
+ if (ParentIncludeLoc == SMLoc()) {
+ break;
+ }
+ Refs.emplace_back(Start, getTok().getLoc().getPointer() - Start);
+
+ EndStatementAtEOFStack.pop_back();
+ jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
+ Lexer.Lex();
+ Start = getTok().getLoc().getPointer();
+ } else {
+ Lexer.Lex();
+ }
+ }
+ Refs.emplace_back(Start, getTok().getLoc().getPointer() - Start);
+ return Refs;
+}
+
+std::string MasmParser::parseStringTo(AsmToken::TokenKind EndTok) {
+ SmallVector<StringRef, 1> Refs = parseStringRefsTo(EndTok);
+ std::string Str;
+ for (StringRef S : Refs) {
+ Str.append(S.str());
+ }
+ return Str;
+}
+
StringRef MasmParser::parseStringToEndOfStatement() {
const char *Start = getTok().getLoc().getPointer();
@@ -1431,11 +1431,11 @@ bool MasmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
/// primaryexpr ::= symbol
/// primaryexpr ::= number
/// primaryexpr ::= '.'
-/// primaryexpr ::= ~,+,-,'not' primaryexpr
-/// primaryexpr ::= string
-/// (a string is interpreted as a 64-bit number in big-endian base-256)
-bool MasmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
- AsmTypeInfo *TypeInfo) {
+/// primaryexpr ::= ~,+,-,'not' primaryexpr
+/// primaryexpr ::= string
+/// (a string is interpreted as a 64-bit number in big-endian base-256)
+bool MasmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
+ AsmTypeInfo *TypeInfo) {
SMLoc FirstTokenLoc = getLexer().getLoc();
AsmToken::TokenKind FirstTokenKind = Lexer.getKind();
switch (FirstTokenKind) {
@@ -1446,7 +1446,7 @@ bool MasmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
return true;
case AsmToken::Exclaim:
Lex(); // Eat the operator.
- if (parsePrimaryExpr(Res, EndLoc, nullptr))
+ if (parsePrimaryExpr(Res, EndLoc, nullptr))
return true;
Res = MCUnaryExpr::createLNot(Res, getContext(), FirstTokenLoc);
return false;
@@ -1471,13 +1471,13 @@ bool MasmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
return Error(FirstTokenLoc, "invalid token in expression");
}
}
- // Parse named bitwise negation.
- if (Identifier.equals_lower("not")) {
- if (parsePrimaryExpr(Res, EndLoc, nullptr))
- return true;
- Res = MCUnaryExpr::createNot(Res, getContext(), FirstTokenLoc);
- return false;
- }
+ // Parse named bitwise negation.
+ if (Identifier.equals_lower("not")) {
+ if (parsePrimaryExpr(Res, EndLoc, nullptr))
+ return true;
+ Res = MCUnaryExpr::createNot(Res, getContext(), FirstTokenLoc);
+ return false;
+ }
// Parse symbol variant.
std::pair<StringRef, StringRef> Split;
if (!MAI.useParensForSymbolVariant()) {
@@ -1528,18 +1528,18 @@ bool MasmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
}
// Find the field offset if used.
- AsmFieldInfo Info;
+ AsmFieldInfo Info;
Split = SymbolName.split('.');
- if (Split.second.empty()) {
- } else {
+ if (Split.second.empty()) {
+ } else {
SymbolName = Split.first;
- if (lookUpField(SymbolName, Split.second, Info)) {
- std::pair<StringRef, StringRef> BaseMember = Split.second.split('.');
- StringRef Base = BaseMember.first, Member = BaseMember.second;
- lookUpField(Base, Member, Info);
- } else if (Structs.count(SymbolName.lower())) {
+ if (lookUpField(SymbolName, Split.second, Info)) {
+ std::pair<StringRef, StringRef> BaseMember = Split.second.split('.');
+ StringRef Base = BaseMember.first, Member = BaseMember.second;
+ lookUpField(Base, Member, Info);
+ } else if (Structs.count(SymbolName.lower())) {
// This is actually a reference to a field offset.
- Res = MCConstantExpr::create(Info.Offset, getContext());
+ Res = MCConstantExpr::create(Info.Offset, getContext());
return false;
}
}
@@ -1566,23 +1566,23 @@ bool MasmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
// Otherwise create a symbol ref.
const MCExpr *SymRef =
MCSymbolRefExpr::create(Sym, Variant, getContext(), FirstTokenLoc);
- if (Info.Offset) {
- Res = MCBinaryExpr::create(
- MCBinaryExpr::Add, SymRef,
- MCConstantExpr::create(Info.Offset, getContext()), getContext());
+ if (Info.Offset) {
+ Res = MCBinaryExpr::create(
+ MCBinaryExpr::Add, SymRef,
+ MCConstantExpr::create(Info.Offset, getContext()), getContext());
} else {
Res = SymRef;
}
- if (TypeInfo) {
- if (Info.Type.Name.empty()) {
- auto TypeIt = KnownType.find(Identifier.lower());
- if (TypeIt != KnownType.end()) {
- Info.Type = TypeIt->second;
- }
- }
-
- *TypeInfo = Info.Type;
- }
+ if (TypeInfo) {
+ if (Info.Type.Name.empty()) {
+ auto TypeIt = KnownType.find(Identifier.lower());
+ if (TypeIt != KnownType.end()) {
+ Info.Type = TypeIt->second;
+ }
+ }
+
+ *TypeInfo = Info.Type;
+ }
return false;
}
case AsmToken::BigNum:
@@ -1618,20 +1618,20 @@ bool MasmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
}
return false;
}
- case AsmToken::String: {
- // MASM strings (used as constants) are interpreted as big-endian base-256.
- SMLoc ValueLoc = getTok().getLoc();
- std::string Value;
- if (parseEscapedString(Value))
- return true;
- if (Value.size() > 8)
- return Error(ValueLoc, "literal value out of range");
- uint64_t IntValue = 0;
- for (const unsigned char CharVal : Value)
- IntValue = (IntValue << 8) | CharVal;
- Res = MCConstantExpr::create(IntValue, getContext());
- return false;
- }
+ case AsmToken::String: {
+ // MASM strings (used as constants) are interpreted as big-endian base-256.
+ SMLoc ValueLoc = getTok().getLoc();
+ std::string Value;
+ if (parseEscapedString(Value))
+ return true;
+ if (Value.size() > 8)
+ return Error(ValueLoc, "literal value out of range");
+ uint64_t IntValue = 0;
+ for (const unsigned char CharVal : Value)
+ IntValue = (IntValue << 8) | CharVal;
+ Res = MCConstantExpr::create(IntValue, getContext());
+ return false;
+ }
case AsmToken::Real: {
APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
@@ -1660,19 +1660,19 @@ bool MasmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
return parseBracketExpr(Res, EndLoc);
case AsmToken::Minus:
Lex(); // Eat the operator.
- if (parsePrimaryExpr(Res, EndLoc, nullptr))
+ if (parsePrimaryExpr(Res, EndLoc, nullptr))
return true;
Res = MCUnaryExpr::createMinus(Res, getContext(), FirstTokenLoc);
return false;
case AsmToken::Plus:
Lex(); // Eat the operator.
- if (parsePrimaryExpr(Res, EndLoc, nullptr))
+ if (parsePrimaryExpr(Res, EndLoc, nullptr))
return true;
Res = MCUnaryExpr::createPlus(Res, getContext(), FirstTokenLoc);
return false;
case AsmToken::Tilde:
Lex(); // Eat the operator.
- if (parsePrimaryExpr(Res, EndLoc, nullptr))
+ if (parsePrimaryExpr(Res, EndLoc, nullptr))
return true;
Res = MCUnaryExpr::createNot(Res, getContext(), FirstTokenLoc);
return false;
@@ -1745,12 +1745,12 @@ static bool isAngleBracketString(SMLoc &StrLoc, SMLoc &EndLoc) {
}
/// creating a string without the escape characters '!'.
-static std::string angleBracketString(StringRef BracketContents) {
+static std::string angleBracketString(StringRef BracketContents) {
std::string Res;
- for (size_t Pos = 0; Pos < BracketContents.size(); Pos++) {
- if (BracketContents[Pos] == '!')
+ for (size_t Pos = 0; Pos < BracketContents.size(); Pos++) {
+ if (BracketContents[Pos] == '!')
Pos++;
- Res += BracketContents[Pos];
+ Res += BracketContents[Pos];
}
return Res;
}
@@ -1912,22 +1912,22 @@ bool MasmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
SMLoc &EndLoc) {
SMLoc StartLoc = Lexer.getLoc();
while (true) {
- AsmToken::TokenKind TokKind = Lexer.getKind();
- if (Lexer.getKind() == AsmToken::Identifier) {
- TokKind = StringSwitch<AsmToken::TokenKind>(Lexer.getTok().getString())
- .CaseLower("and", AsmToken::Amp)
- .CaseLower("not", AsmToken::Exclaim)
- .CaseLower("or", AsmToken::Pipe)
- .CaseLower("eq", AsmToken::EqualEqual)
- .CaseLower("ne", AsmToken::ExclaimEqual)
- .CaseLower("lt", AsmToken::Less)
- .CaseLower("le", AsmToken::LessEqual)
- .CaseLower("gt", AsmToken::Greater)
- .CaseLower("ge", AsmToken::GreaterEqual)
- .Default(TokKind);
- }
+ AsmToken::TokenKind TokKind = Lexer.getKind();
+ if (Lexer.getKind() == AsmToken::Identifier) {
+ TokKind = StringSwitch<AsmToken::TokenKind>(Lexer.getTok().getString())
+ .CaseLower("and", AsmToken::Amp)
+ .CaseLower("not", AsmToken::Exclaim)
+ .CaseLower("or", AsmToken::Pipe)
+ .CaseLower("eq", AsmToken::EqualEqual)
+ .CaseLower("ne", AsmToken::ExclaimEqual)
+ .CaseLower("lt", AsmToken::Less)
+ .CaseLower("le", AsmToken::LessEqual)
+ .CaseLower("gt", AsmToken::Greater)
+ .CaseLower("ge", AsmToken::GreaterEqual)
+ .Default(TokKind);
+ }
MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
- unsigned TokPrec = getBinOpPrecedence(TokKind, Kind);
+ unsigned TokPrec = getBinOpPrecedence(TokKind, Kind);
// If the next token is lower precedence than we are allowed to eat, return
// successfully with what we ate already.
@@ -1954,7 +1954,7 @@ bool MasmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
}
/// ParseStatement:
-/// ::= % statement
+/// ::= % statement
/// ::= EndOfStatement
/// ::= Label* Directive ...Operands... EndOfStatement
/// ::= Label* Identifier OperandList* EndOfStatement
@@ -1972,15 +1972,15 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
Lex();
return false;
}
-
- // If preceded by an expansion operator, first expand all text macros and
- // macro functions.
- if (getTok().is(AsmToken::Percent)) {
- SMLoc ExpansionLoc = getTok().getLoc();
- if (parseToken(AsmToken::Percent) || expandStatement(ExpansionLoc))
- return true;
- }
-
+
+ // If preceded by an expansion operator, first expand all text macros and
+ // macro functions.
+ if (getTok().is(AsmToken::Percent)) {
+ SMLoc ExpansionLoc = getTok().getLoc();
+ if (parseToken(AsmToken::Percent) || expandStatement(ExpansionLoc))
+ return true;
+ }
+
// Statements always start with an identifier, unless we're dealing with a
// processor directive (.386, .686, etc.) that lexes as a real.
AsmToken ID = getTok();
@@ -2032,11 +2032,11 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
Lex(); // always eat a token
if (!IDVal.startswith("."))
return Error(IDLoc, "unexpected token at start of statement");
- } else if (Lexer.is(AsmToken::Identifier) &&
- getTok().getString().equals_lower("echo")) {
- // Intercept echo early to avoid lexical substitution in its message, and
- // delegate all handling to the appropriate function.
- return parseDirectiveEcho();
+ } else if (Lexer.is(AsmToken::Identifier) &&
+ getTok().getString().equals_lower("echo")) {
+ // Intercept echo early to avoid lexical substitution in its message, and
+ // delegate all handling to the appropriate function.
+ return parseDirectiveEcho();
} else if (parseIdentifier(IDVal)) {
if (!TheCondState.Ignore) {
Lex(); // always eat a token
@@ -2156,7 +2156,7 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
// does not understand Labels. This may cause us to see a Hash
// here instead of a preprocessor line comment.
if (getTok().is(AsmToken::Hash)) {
- std::string CommentStr = parseStringTo(AsmToken::EndOfStatement);
+ std::string CommentStr = parseStringTo(AsmToken::EndOfStatement);
Lexer.Lex();
Lexer.UnLex(AsmToken(AsmToken::EndOfStatement, CommentStr));
}
@@ -2189,7 +2189,7 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
}
// If macros are enabled, check to see if this is a macro instantiation.
- if (const MCAsmMacro *M = getContext().lookupMacro(IDVal.lower())) {
+ if (const MCAsmMacro *M = getContext().lookupMacro(IDVal.lower())) {
return handleMacroEntry(M, IDLoc);
}
@@ -2264,18 +2264,18 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
case DK_DD:
return parseDirectiveValue(IDVal, 4);
case DK_FWORD:
- case DK_DF:
+ case DK_DF:
return parseDirectiveValue(IDVal, 6);
case DK_QWORD:
case DK_SQWORD:
case DK_DQ:
return parseDirectiveValue(IDVal, 8);
case DK_REAL4:
- return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle(), 4);
+ return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle(), 4);
case DK_REAL8:
- return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble(), 8);
- case DK_REAL10:
- return parseDirectiveRealValue(IDVal, APFloat::x87DoubleExtended(), 10);
+ return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble(), 8);
+ case DK_REAL10:
+ return parseDirectiveRealValue(IDVal, APFloat::x87DoubleExtended(), 10);
case DK_STRUCT:
case DK_UNION:
return parseDirectiveNestedStruct(IDVal, DirKind);
@@ -2296,14 +2296,14 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
return parseDirectiveComment(IDLoc);
case DK_INCLUDE:
return parseDirectiveInclude();
- case DK_REPEAT:
- return parseDirectiveRepeat(IDLoc, IDVal);
- case DK_WHILE:
- return parseDirectiveWhile(IDLoc);
- case DK_FOR:
- return parseDirectiveFor(IDLoc, IDVal);
- case DK_FORC:
- return parseDirectiveForc(IDLoc, IDVal);
+ case DK_REPEAT:
+ return parseDirectiveRepeat(IDLoc, IDVal);
+ case DK_WHILE:
+ return parseDirectiveWhile(IDLoc);
+ case DK_FOR:
+ return parseDirectiveFor(IDLoc, IDVal);
+ case DK_FORC:
+ return parseDirectiveForc(IDLoc, IDVal);
case DK_FILE:
return parseDirectiveFile(IDLoc);
case DK_LINE:
@@ -2379,12 +2379,12 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
case DK_CFI_WINDOW_SAVE:
return parseDirectiveCFIWindowSave();
case DK_EXITM:
- Info.ExitValue = "";
- return parseDirectiveExitMacro(IDLoc, IDVal, *Info.ExitValue);
+ Info.ExitValue = "";
+ return parseDirectiveExitMacro(IDLoc, IDVal, *Info.ExitValue);
case DK_ENDM:
- Info.ExitValue = "";
+ Info.ExitValue = "";
return parseDirectiveEndMacro(IDVal);
- case DK_PURGE:
+ case DK_PURGE:
return parseDirectivePurgeMacro(IDLoc);
case DK_END:
return parseDirectiveEnd(IDLoc);
@@ -2414,8 +2414,8 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
return parseDirectiveErrorIfe(IDLoc, true);
case DK_ERRNZ:
return parseDirectiveErrorIfe(IDLoc, false);
- case DK_RADIX:
- return parseDirectiveRadix(IDLoc);
+ case DK_RADIX:
+ return parseDirectiveRadix(IDLoc);
}
return Error(IDLoc, "unknown directive");
@@ -2475,41 +2475,41 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
Lex();
return parseDirectiveEquate(nextVal, IDVal, DirKind);
case DK_BYTE:
- case DK_SBYTE:
+ case DK_SBYTE:
case DK_DB:
Lex();
return parseDirectiveNamedValue(nextVal, 1, IDVal, IDLoc);
case DK_WORD:
- case DK_SWORD:
+ case DK_SWORD:
case DK_DW:
Lex();
return parseDirectiveNamedValue(nextVal, 2, IDVal, IDLoc);
case DK_DWORD:
- case DK_SDWORD:
+ case DK_SDWORD:
case DK_DD:
Lex();
return parseDirectiveNamedValue(nextVal, 4, IDVal, IDLoc);
case DK_FWORD:
- case DK_DF:
+ case DK_DF:
Lex();
return parseDirectiveNamedValue(nextVal, 6, IDVal, IDLoc);
case DK_QWORD:
- case DK_SQWORD:
+ case DK_SQWORD:
case DK_DQ:
Lex();
return parseDirectiveNamedValue(nextVal, 8, IDVal, IDLoc);
case DK_REAL4:
Lex();
- return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEsingle(), 4,
- IDVal, IDLoc);
+ return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEsingle(), 4,
+ IDVal, IDLoc);
case DK_REAL8:
Lex();
- return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEdouble(), 8,
- IDVal, IDLoc);
- case DK_REAL10:
- Lex();
- return parseDirectiveNamedRealValue(nextVal, APFloat::x87DoubleExtended(),
- 10, IDVal, IDLoc);
+ return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEdouble(), 8,
+ IDVal, IDLoc);
+ case DK_REAL10:
+ Lex();
+ return parseDirectiveNamedRealValue(nextVal, APFloat::x87DoubleExtended(),
+ 10, IDVal, IDLoc);
case DK_STRUCT:
case DK_UNION:
Lex();
@@ -2517,9 +2517,9 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
case DK_ENDS:
Lex();
return parseDirectiveEnds(IDVal, IDLoc);
- case DK_MACRO:
- Lex();
- return parseDirectiveMacro(IDVal, IDLoc);
+ case DK_MACRO:
+ Lex();
+ return parseDirectiveMacro(IDVal, IDLoc);
}
// Finally, we check if this is allocating a variable with user-defined type.
@@ -2713,69 +2713,69 @@ void MasmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
NewDiag.print(nullptr, OS);
}
-// This is similar to the IsIdentifierChar function in AsmLexer.cpp, but does
-// not accept '.'.
-static bool isMacroParameterChar(char C) {
- return isAlnum(C) || C == '_' || C == '$' || C == '@' || C == '?';
+// This is similar to the IsIdentifierChar function in AsmLexer.cpp, but does
+// not accept '.'.
+static bool isMacroParameterChar(char C) {
+ return isAlnum(C) || C == '_' || C == '$' || C == '@' || C == '?';
}
bool MasmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
ArrayRef<MCAsmMacroParameter> Parameters,
ArrayRef<MCAsmMacroArgument> A,
- const std::vector<std::string> &Locals, SMLoc L) {
+ const std::vector<std::string> &Locals, SMLoc L) {
unsigned NParameters = Parameters.size();
- if (NParameters != A.size())
+ if (NParameters != A.size())
return Error(L, "Wrong number of arguments");
- StringMap<std::string> LocalSymbols;
- std::string Name;
- Name.reserve(6);
- for (StringRef Local : Locals) {
- raw_string_ostream LocalName(Name);
- LocalName << "??"
- << format_hex_no_prefix(LocalCounter++, 4, /*Upper=*/true);
- LocalSymbols.insert({Local, LocalName.str()});
- Name.clear();
- }
-
- Optional<char> CurrentQuote;
+ StringMap<std::string> LocalSymbols;
+ std::string Name;
+ Name.reserve(6);
+ for (StringRef Local : Locals) {
+ raw_string_ostream LocalName(Name);
+ LocalName << "??"
+ << format_hex_no_prefix(LocalCounter++, 4, /*Upper=*/true);
+ LocalSymbols.insert({Local, LocalName.str()});
+ Name.clear();
+ }
+
+ Optional<char> CurrentQuote;
while (!Body.empty()) {
// Scan for the next substitution.
std::size_t End = Body.size(), Pos = 0;
- std::size_t IdentifierPos = End;
+ std::size_t IdentifierPos = End;
for (; Pos != End; ++Pos) {
- // Find the next possible macro parameter, including preceding a '&'
- // inside quotes.
- if (Body[Pos] == '&')
- break;
- if (isMacroParameterChar(Body[Pos])) {
- if (!CurrentQuote.hasValue())
+ // Find the next possible macro parameter, including preceding a '&'
+ // inside quotes.
+ if (Body[Pos] == '&')
+ break;
+ if (isMacroParameterChar(Body[Pos])) {
+ if (!CurrentQuote.hasValue())
break;
- if (IdentifierPos == End)
- IdentifierPos = Pos;
+ if (IdentifierPos == End)
+ IdentifierPos = Pos;
} else {
- IdentifierPos = End;
+ IdentifierPos = End;
+ }
+
+ // Track quotation status
+ if (!CurrentQuote.hasValue()) {
+ if (Body[Pos] == '\'' || Body[Pos] == '"')
+ CurrentQuote = Body[Pos];
+ } else if (Body[Pos] == CurrentQuote) {
+ if (Pos + 1 != End && Body[Pos + 1] == CurrentQuote) {
+ // Escaped quote, and quotes aren't identifier chars; skip
+ ++Pos;
+ continue;
+ } else {
+ CurrentQuote.reset();
+ }
}
-
- // Track quotation status
- if (!CurrentQuote.hasValue()) {
- if (Body[Pos] == '\'' || Body[Pos] == '"')
- CurrentQuote = Body[Pos];
- } else if (Body[Pos] == CurrentQuote) {
- if (Pos + 1 != End && Body[Pos + 1] == CurrentQuote) {
- // Escaped quote, and quotes aren't identifier chars; skip
- ++Pos;
- continue;
- } else {
- CurrentQuote.reset();
- }
- }
}
- if (IdentifierPos != End) {
- // We've recognized an identifier before an apostrophe inside quotes;
- // check once to see if we can expand it.
- Pos = IdentifierPos;
- IdentifierPos = End;
- }
+ if (IdentifierPos != End) {
+ // We've recognized an identifier before an apostrophe inside quotes;
+ // check once to see if we can expand it.
+ Pos = IdentifierPos;
+ IdentifierPos = End;
+ }
// Add the prefix.
OS << Body.slice(0, Pos);
@@ -2784,51 +2784,51 @@ bool MasmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
if (Pos == End)
break;
- unsigned I = Pos;
- bool InitialAmpersand = (Body[I] == '&');
- if (InitialAmpersand) {
- ++I;
- ++Pos;
- }
- while (I < End && isMacroParameterChar(Body[I]))
- ++I;
-
- const char *Begin = Body.data() + Pos;
- StringRef Argument(Begin, I - Pos);
- unsigned Index = 0;
-
- for (; Index < NParameters; ++Index)
- if (Parameters[Index].Name == Argument)
+ unsigned I = Pos;
+ bool InitialAmpersand = (Body[I] == '&');
+ if (InitialAmpersand) {
+ ++I;
+ ++Pos;
+ }
+ while (I < End && isMacroParameterChar(Body[I]))
+ ++I;
+
+ const char *Begin = Body.data() + Pos;
+ StringRef Argument(Begin, I - Pos);
+ unsigned Index = 0;
+
+ for (; Index < NParameters; ++Index)
+ if (Parameters[Index].Name == Argument)
break;
- if (Index == NParameters) {
- if (InitialAmpersand)
- OS << '&';
- auto it = LocalSymbols.find(Argument.lower());
- if (it != LocalSymbols.end())
- OS << it->second;
- else
- OS << Argument;
- Pos = I;
- } else {
- for (const AsmToken &Token : A[Index]) {
- // In MASM, you can write '%expr'.
- // The prefix '%' evaluates the expression 'expr'
- // and uses the result as a string (e.g. replace %(1+2) with the
- // string "3").
- // Here, we identify the integer token which is the result of the
- // absolute expression evaluation and replace it with its string
- // representation.
- if (Token.getString().front() == '%' && Token.is(AsmToken::Integer))
- // Emit an integer value to the buffer.
- OS << Token.getIntVal();
- else
+ if (Index == NParameters) {
+ if (InitialAmpersand)
+ OS << '&';
+ auto it = LocalSymbols.find(Argument.lower());
+ if (it != LocalSymbols.end())
+ OS << it->second;
+ else
+ OS << Argument;
+ Pos = I;
+ } else {
+ for (const AsmToken &Token : A[Index]) {
+ // In MASM, you can write '%expr'.
+ // The prefix '%' evaluates the expression 'expr'
+ // and uses the result as a string (e.g. replace %(1+2) with the
+ // string "3").
+ // Here, we identify the integer token which is the result of the
+ // absolute expression evaluation and replace it with its string
+ // representation.
+ if (Token.getString().front() == '%' && Token.is(AsmToken::Integer))
+ // Emit an integer value to the buffer.
+ OS << Token.getIntVal();
+ else
OS << Token.getString();
}
- Pos += Argument.size();
- if (Pos < End && Body[Pos] == '&') {
- ++Pos;
+ Pos += Argument.size();
+ if (Pos < End && Body[Pos] == '&') {
+ ++Pos;
}
}
// Update the scan point.
@@ -2886,30 +2886,30 @@ private:
} // end anonymous namespace
-bool MasmParser::parseMacroArgument(const MCAsmMacroParameter *MP,
- MCAsmMacroArgument &MA,
- AsmToken::TokenKind EndTok) {
- if (MP && MP->Vararg) {
- if (Lexer.isNot(EndTok)) {
- SmallVector<StringRef, 1> Str = parseStringRefsTo(EndTok);
- for (StringRef S : Str) {
- MA.emplace_back(AsmToken::String, S);
- }
+bool MasmParser::parseMacroArgument(const MCAsmMacroParameter *MP,
+ MCAsmMacroArgument &MA,
+ AsmToken::TokenKind EndTok) {
+ if (MP && MP->Vararg) {
+ if (Lexer.isNot(EndTok)) {
+ SmallVector<StringRef, 1> Str = parseStringRefsTo(EndTok);
+ for (StringRef S : Str) {
+ MA.emplace_back(AsmToken::String, S);
+ }
}
return false;
}
- SMLoc StrLoc = Lexer.getLoc(), EndLoc;
- if (Lexer.is(AsmToken::Less) && isAngleBracketString(StrLoc, EndLoc)) {
- const char *StrChar = StrLoc.getPointer() + 1;
- const char *EndChar = EndLoc.getPointer() - 1;
- jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
- /// Eat from '<' to '>'.
- Lex();
- MA.emplace_back(AsmToken::String, StringRef(StrChar, EndChar - StrChar));
- return false;
- }
-
+ SMLoc StrLoc = Lexer.getLoc(), EndLoc;
+ if (Lexer.is(AsmToken::Less) && isAngleBracketString(StrLoc, EndLoc)) {
+ const char *StrChar = StrLoc.getPointer() + 1;
+ const char *EndChar = EndLoc.getPointer() - 1;
+ jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
+ /// Eat from '<' to '>'.
+ Lex();
+ MA.emplace_back(AsmToken::String, StringRef(StrChar, EndChar - StrChar));
+ return false;
+ }
+
unsigned ParenLevel = 0;
// Darwin doesn't use spaces to delmit arguments.
@@ -2920,7 +2920,7 @@ bool MasmParser::parseMacroArgument(const MCAsmMacroParameter *MP,
while (true) {
SpaceEaten = false;
if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal))
- return TokError("unexpected token");
+ return TokError("unexpected token");
if (ParenLevel == 0) {
if (Lexer.is(AsmToken::Comma))
@@ -2928,20 +2928,20 @@ bool MasmParser::parseMacroArgument(const MCAsmMacroParameter *MP,
if (Lexer.is(AsmToken::Space)) {
SpaceEaten = true;
- Lex(); // Eat spaces.
+ Lex(); // Eat spaces.
}
// Spaces can delimit parameters, but could also be part an expression.
// If the token after a space is an operator, add the token and the next
// one into this argument
if (!IsDarwin) {
- if (isOperator(Lexer.getKind()) && Lexer.isNot(EndTok)) {
+ if (isOperator(Lexer.getKind()) && Lexer.isNot(EndTok)) {
MA.push_back(getTok());
- Lex();
+ Lex();
// Whitespace after an operator can be ignored.
if (Lexer.is(AsmToken::Space))
- Lex();
+ Lex();
continue;
}
@@ -2952,7 +2952,7 @@ bool MasmParser::parseMacroArgument(const MCAsmMacroParameter *MP,
// handleMacroEntry relies on not advancing the lexer here
// to be able to fill in the remaining default parameter values
- if (Lexer.is(EndTok) && (EndTok != AsmToken::RParen || ParenLevel == 0))
+ if (Lexer.is(EndTok) && (EndTok != AsmToken::RParen || ParenLevel == 0))
break;
// Adjust the current parentheses level.
@@ -2963,27 +2963,27 @@ bool MasmParser::parseMacroArgument(const MCAsmMacroParameter *MP,
// Append the token to the current argument list.
MA.push_back(getTok());
- Lex();
+ Lex();
}
if (ParenLevel != 0)
- return TokError("unbalanced parentheses in argument");
-
- if (MA.empty() && MP) {
- if (MP->Required) {
- return TokError("missing value for required parameter '" + MP->Name +
- "'");
- } else {
- MA = MP->Value;
- }
- }
+ return TokError("unbalanced parentheses in argument");
+
+ if (MA.empty() && MP) {
+ if (MP->Required) {
+ return TokError("missing value for required parameter '" + MP->Name +
+ "'");
+ } else {
+ MA = MP->Value;
+ }
+ }
return false;
}
// Parse the macro instantiation arguments.
bool MasmParser::parseMacroArguments(const MCAsmMacro *M,
- MCAsmMacroArguments &A,
- AsmToken::TokenKind EndTok) {
+ MCAsmMacroArguments &A,
+ AsmToken::TokenKind EndTok) {
const unsigned NParameters = M ? M->Parameters.size() : 0;
bool NamedParametersFound = false;
SmallVector<SMLoc, 4> FALocs;
@@ -3014,27 +3014,27 @@ bool MasmParser::parseMacroArguments(const MCAsmMacro *M,
if (NamedParametersFound && FA.Name.empty())
return Error(IDLoc, "cannot mix positional and keyword arguments");
- unsigned PI = Parameter;
- if (!FA.Name.empty()) {
- assert(M && "expected macro to be defined");
- unsigned FAI = 0;
- for (FAI = 0; FAI < NParameters; ++FAI)
- if (M->Parameters[FAI].Name == FA.Name)
- break;
-
- if (FAI >= NParameters) {
- return Error(IDLoc, "parameter named '" + FA.Name +
- "' does not exist for macro '" + M->Name + "'");
- }
- PI = FAI;
- }
- const MCAsmMacroParameter *MP = nullptr;
- if (M && PI < NParameters)
- MP = &M->Parameters[PI];
-
+ unsigned PI = Parameter;
+ if (!FA.Name.empty()) {
+ assert(M && "expected macro to be defined");
+ unsigned FAI = 0;
+ for (FAI = 0; FAI < NParameters; ++FAI)
+ if (M->Parameters[FAI].Name == FA.Name)
+ break;
+
+ if (FAI >= NParameters) {
+ return Error(IDLoc, "parameter named '" + FA.Name +
+ "' does not exist for macro '" + M->Name + "'");
+ }
+ PI = FAI;
+ }
+ const MCAsmMacroParameter *MP = nullptr;
+ if (M && PI < NParameters)
+ MP = &M->Parameters[PI];
+
SMLoc StrLoc = Lexer.getLoc();
SMLoc EndLoc;
- if (Lexer.is(AsmToken::Percent)) {
+ if (Lexer.is(AsmToken::Percent)) {
const MCExpr *AbsoluteExp;
int64_t Value;
/// Eat '%'.
@@ -3049,11 +3049,11 @@ bool MasmParser::parseMacroArguments(const MCAsmMacro *M,
AsmToken newToken(AsmToken::Integer,
StringRef(StrChar, EndChar - StrChar), Value);
FA.Value.push_back(newToken);
- } else if (parseMacroArgument(MP, FA.Value, EndTok)) {
- if (M)
- return addErrorSuffix(" in '" + M->Name + "' macro");
- else
- return true;
+ } else if (parseMacroArgument(MP, FA.Value, EndTok)) {
+ if (M)
+ return addErrorSuffix(" in '" + M->Name + "' macro");
+ else
+ return true;
}
if (!FA.Value.empty()) {
@@ -3070,15 +3070,15 @@ bool MasmParser::parseMacroArguments(const MCAsmMacro *M,
// At the end of the statement, fill in remaining arguments that have
// default values. If there aren't any, then the next argument is
// required but missing
- if (Lexer.is(EndTok)) {
+ if (Lexer.is(EndTok)) {
bool Failure = false;
for (unsigned FAI = 0; FAI < NParameters; ++FAI) {
if (A[FAI].empty()) {
if (M->Parameters[FAI].Required) {
Error(FALocs[FAI].isValid() ? FALocs[FAI] : Lexer.getLoc(),
"missing value for required parameter "
- "'" +
- M->Parameters[FAI].Name + "' in macro '" + M->Name + "'");
+ "'" +
+ M->Parameters[FAI].Name + "' in macro '" + M->Name + "'");
Failure = true;
}
@@ -3096,8 +3096,8 @@ bool MasmParser::parseMacroArguments(const MCAsmMacro *M,
return TokError("too many positional arguments");
}
-bool MasmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc,
- AsmToken::TokenKind ArgumentEndTok) {
+bool MasmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc,
+ AsmToken::TokenKind ArgumentEndTok) {
// Arbitrarily limit macro nesting depth (default matches 'as'). We can
// eliminate this, although we should protect against infinite loops.
unsigned MaxNestingDepth = AsmMacroMaxNestingDepth;
@@ -3111,7 +3111,7 @@ bool MasmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc,
}
MCAsmMacroArguments A;
- if (parseMacroArguments(M, A, ArgumentEndTok))
+ if (parseMacroArguments(M, A, ArgumentEndTok))
return true;
// Macro instantiation is lexical, unfortunately. We construct a new buffer
@@ -3120,12 +3120,12 @@ bool MasmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc,
StringRef Body = M->Body;
raw_svector_ostream OS(Buf);
- if (expandMacro(OS, Body, M->Parameters, A, M->Locals, getTok().getLoc()))
+ if (expandMacro(OS, Body, M->Parameters, A, M->Locals, getTok().getLoc()))
return true;
- // We include the endm in the buffer as our cue to exit the macro
+ // We include the endm in the buffer as our cue to exit the macro
// instantiation.
- OS << "endm\n";
+ OS << "endm\n";
std::unique_ptr<MemoryBuffer> Instantiation =
MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
@@ -3141,17 +3141,17 @@ bool MasmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc,
// Jump to the macro instantiation and prime the lexer.
CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
- EndStatementAtEOFStack.push_back(true);
+ EndStatementAtEOFStack.push_back(true);
Lex();
return false;
}
void MasmParser::handleMacroExit() {
- // Jump to the token we should return to, and consume it.
- EndStatementAtEOFStack.pop_back();
- jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer,
- EndStatementAtEOFStack.back());
+ // Jump to the token we should return to, and consume it.
+ EndStatementAtEOFStack.pop_back();
+ jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer,
+ EndStatementAtEOFStack.back());
Lex();
// Pop the instantiation entry.
@@ -3159,63 +3159,63 @@ void MasmParser::handleMacroExit() {
ActiveMacros.pop_back();
}
-bool MasmParser::handleMacroInvocation(const MCAsmMacro *M, SMLoc NameLoc) {
- if (!M->IsFunction)
- return Error(NameLoc, "cannot invoke macro procedure as function");
-
- if (parseToken(AsmToken::LParen, "invoking macro function '" + M->Name +
- "' requires arguments in parentheses") ||
- handleMacroEntry(M, NameLoc, AsmToken::RParen))
- return true;
-
- // Parse all statements in the macro, retrieving the exit value when it ends.
- std::string ExitValue;
- SmallVector<AsmRewrite, 4> AsmStrRewrites;
- while (Lexer.isNot(AsmToken::Eof)) {
- ParseStatementInfo Info(&AsmStrRewrites);
- bool Parsed = parseStatement(Info, nullptr);
-
- if (!Parsed && Info.ExitValue.hasValue()) {
- ExitValue = std::move(*Info.ExitValue);
- break;
- }
-
- // If we have a Lexer Error we are on an Error Token. Load in Lexer Error
- // for printing ErrMsg via Lex() only if no (presumably better) parser error
- // exists.
- if (Parsed && !hasPendingError() && Lexer.getTok().is(AsmToken::Error)) {
- Lex();
- }
-
- // parseStatement returned true so may need to emit an error.
- printPendingErrors();
-
- // Skipping to the next line if needed.
- if (Parsed && !getLexer().isAtStartOfStatement())
- eatToEndOfStatement();
- }
-
- // Consume the right-parenthesis on the other side of the arguments.
- if (parseToken(AsmToken::RParen, "invoking macro function '" + M->Name +
- "' requires arguments in parentheses"))
- return true;
-
- // Exit values may require lexing, unfortunately. We construct a new buffer to
- // hold the exit value.
- std::unique_ptr<MemoryBuffer> MacroValue =
- MemoryBuffer::getMemBufferCopy(ExitValue, "<macro-value>");
-
- // Jump from this location to the instantiated exit value, and prime the
- // lexer.
- CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(MacroValue), Lexer.getLoc());
- Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(), nullptr,
- /*EndStatementAtEOF=*/false);
- EndStatementAtEOFStack.push_back(false);
- Lex();
-
- return false;
-}
-
+bool MasmParser::handleMacroInvocation(const MCAsmMacro *M, SMLoc NameLoc) {
+ if (!M->IsFunction)
+ return Error(NameLoc, "cannot invoke macro procedure as function");
+
+ if (parseToken(AsmToken::LParen, "invoking macro function '" + M->Name +
+ "' requires arguments in parentheses") ||
+ handleMacroEntry(M, NameLoc, AsmToken::RParen))
+ return true;
+
+ // Parse all statements in the macro, retrieving the exit value when it ends.
+ std::string ExitValue;
+ SmallVector<AsmRewrite, 4> AsmStrRewrites;
+ while (Lexer.isNot(AsmToken::Eof)) {
+ ParseStatementInfo Info(&AsmStrRewrites);
+ bool Parsed = parseStatement(Info, nullptr);
+
+ if (!Parsed && Info.ExitValue.hasValue()) {
+ ExitValue = std::move(*Info.ExitValue);
+ break;
+ }
+
+ // If we have a Lexer Error we are on an Error Token. Load in Lexer Error
+ // for printing ErrMsg via Lex() only if no (presumably better) parser error
+ // exists.
+ if (Parsed && !hasPendingError() && Lexer.getTok().is(AsmToken::Error)) {
+ Lex();
+ }
+
+ // parseStatement returned true so may need to emit an error.
+ printPendingErrors();
+
+ // Skipping to the next line if needed.
+ if (Parsed && !getLexer().isAtStartOfStatement())
+ eatToEndOfStatement();
+ }
+
+ // Consume the right-parenthesis on the other side of the arguments.
+ if (parseToken(AsmToken::RParen, "invoking macro function '" + M->Name +
+ "' requires arguments in parentheses"))
+ return true;
+
+ // Exit values may require lexing, unfortunately. We construct a new buffer to
+ // hold the exit value.
+ std::unique_ptr<MemoryBuffer> MacroValue =
+ MemoryBuffer::getMemBufferCopy(ExitValue, "<macro-value>");
+
+ // Jump from this location to the instantiated exit value, and prime the
+ // lexer.
+ CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(MacroValue), Lexer.getLoc());
+ Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(), nullptr,
+ /*EndStatementAtEOF=*/false);
+ EndStatementAtEOFStack.push_back(false);
+ Lex();
+
+ return false;
+}
+
/// parseIdentifier:
/// ::= identifier
/// ::= string
@@ -3284,7 +3284,7 @@ bool MasmParser::parseDirectiveEquate(StringRef IDVal, StringRef Name,
// Accept a text-list, not just one text-item.
auto parseItem = [&]() -> bool {
if (parseTextItem(Value))
- return TokError("expected text item");
+ return TokError("expected text item");
Var.TextValue += Value;
return false;
};
@@ -3302,11 +3302,11 @@ bool MasmParser::parseDirectiveEquate(StringRef IDVal, StringRef Name,
SMLoc EndLoc, StartLoc = Lexer.getLoc();
if (parseExpression(Expr, EndLoc))
return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
- MCSymbol *Sym = getContext().getOrCreateSymbol(Var.Name);
- Sym->setRedefinable(Var.Redefinable);
- Sym->setVariableValue(Expr);
- Sym->setExternal(false);
-
+ MCSymbol *Sym = getContext().getOrCreateSymbol(Var.Name);
+ Sym->setRedefinable(Var.Redefinable);
+ Sym->setVariableValue(Expr);
+ Sym->setExternal(false);
+
if (Expr->evaluateAsAbsolute(Var.NumericValue,
getStreamer().getAssemblerPtr()))
return false;
@@ -3323,18 +3323,18 @@ bool MasmParser::parseEscapedString(std::string &Data) {
return true;
Data = "";
- char Quote = getTok().getString().front();
+ char Quote = getTok().getString().front();
StringRef Str = getTok().getStringContents();
- Data.reserve(Str.size());
- for (size_t i = 0, e = Str.size(); i != e; ++i) {
- Data.push_back(Str[i]);
- if (Str[i] == Quote) {
- // MASM treats doubled delimiting quotes as an escaped delimiting quote.
- // If we're escaping the string's trailing delimiter, we're definitely
- // missing a quotation mark.
- if (i + 1 == Str.size())
- return Error(getTok().getLoc(), "missing quotation mark in string");
- if (Str[i + 1] == Quote)
+ Data.reserve(Str.size());
+ for (size_t i = 0, e = Str.size(); i != e; ++i) {
+ Data.push_back(Str[i]);
+ if (Str[i] == Quote) {
+ // MASM treats doubled delimiting quotes as an escaped delimiting quote.
+ // If we're escaping the string's trailing delimiter, we're definitely
+ // missing a quotation mark.
+ if (i + 1 == Str.size())
+ return Error(getTok().getLoc(), "missing quotation mark in string");
+ if (Str[i + 1] == Quote)
++i;
}
}
@@ -3348,7 +3348,7 @@ bool MasmParser::parseAngleBracketString(std::string &Data) {
if (isAngleBracketString(StartLoc, EndLoc)) {
const char *StartChar = StartLoc.getPointer() + 1;
const char *EndChar = EndLoc.getPointer() - 1;
- jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
+ jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
// Eat from '<' to '>'.
Lex();
@@ -3360,42 +3360,42 @@ bool MasmParser::parseAngleBracketString(std::string &Data) {
/// textItem ::= textLiteral | textMacroID | % constExpr
bool MasmParser::parseTextItem(std::string &Data) {
- switch (getTok().getKind()) {
- default:
- return true;
- case AsmToken::Percent: {
- int64_t Res;
- if (parseToken(AsmToken::Percent) || parseAbsoluteExpression(Res))
- return true;
- Data = std::to_string(Res);
- return false;
- }
- case AsmToken::Less:
- case AsmToken::LessEqual:
- case AsmToken::LessLess:
- case AsmToken::LessGreater:
- return parseAngleBracketString(Data);
- case AsmToken::Identifier: {
- StringRef ID;
- if (parseIdentifier(ID))
- return true;
- Data = ID.str();
-
- auto it = Variables.find(ID);
- if (it == Variables.end())
- return true;
-
- while (it != Variables.end()) {
- const Variable &Var = it->second;
- if (!Var.IsText)
- return true;
- Data = Var.TextValue;
- it = Variables.find(Data);
- }
- return false;
- }
- }
- llvm_unreachable("unhandled token kind");
+ switch (getTok().getKind()) {
+ default:
+ return true;
+ case AsmToken::Percent: {
+ int64_t Res;
+ if (parseToken(AsmToken::Percent) || parseAbsoluteExpression(Res))
+ return true;
+ Data = std::to_string(Res);
+ return false;
+ }
+ case AsmToken::Less:
+ case AsmToken::LessEqual:
+ case AsmToken::LessLess:
+ case AsmToken::LessGreater:
+ return parseAngleBracketString(Data);
+ case AsmToken::Identifier: {
+ StringRef ID;
+ if (parseIdentifier(ID))
+ return true;
+ Data = ID.str();
+
+ auto it = Variables.find(ID);
+ if (it == Variables.end())
+ return true;
+
+ while (it != Variables.end()) {
+ const Variable &Var = it->second;
+ if (!Var.IsText)
+ return true;
+ Data = Var.TextValue;
+ it = Variables.find(Data);
+ }
+ return false;
+ }
+ }
+ llvm_unreachable("unhandled token kind");
}
/// parseDirectiveAscii:
@@ -3439,20 +3439,20 @@ bool MasmParser::emitIntValue(const MCExpr *Value, unsigned Size) {
bool MasmParser::parseScalarInitializer(unsigned Size,
SmallVectorImpl<const MCExpr *> &Values,
unsigned StringPadLength) {
- if (Size == 1 && getTok().is(AsmToken::String)) {
- std::string Value;
- if (parseEscapedString(Value))
- return true;
- // Treat each character as an initializer.
- for (const unsigned char CharVal : Value)
- Values.push_back(MCConstantExpr::create(CharVal, getContext()));
-
- // Pad the string with spaces to the specified length.
- for (size_t i = Value.size(); i < StringPadLength; ++i)
- Values.push_back(MCConstantExpr::create(' ', getContext()));
+ if (Size == 1 && getTok().is(AsmToken::String)) {
+ std::string Value;
+ if (parseEscapedString(Value))
+ return true;
+ // Treat each character as an initializer.
+ for (const unsigned char CharVal : Value)
+ Values.push_back(MCConstantExpr::create(CharVal, getContext()));
+
+ // Pad the string with spaces to the specified length.
+ for (size_t i = Value.size(); i < StringPadLength; ++i)
+ Values.push_back(MCConstantExpr::create(' ', getContext()));
} else {
const MCExpr *Value;
- if (parseExpression(Value))
+ if (parseExpression(Value))
return true;
if (getTok().is(AsmToken::Identifier) &&
getTok().getString().equals_lower("dup")) {
@@ -3498,7 +3498,7 @@ bool MasmParser::parseScalarInstList(unsigned Size,
return false;
}
-bool MasmParser::emitIntegralValues(unsigned Size, unsigned *Count) {
+bool MasmParser::emitIntegralValues(unsigned Size, unsigned *Count) {
SmallVector<const MCExpr *, 1> Values;
if (checkForValidSection() || parseScalarInstList(Size, Values))
return true;
@@ -3506,15 +3506,15 @@ bool MasmParser::emitIntegralValues(unsigned Size, unsigned *Count) {
for (auto Value : Values) {
emitIntValue(Value, Size);
}
- if (Count)
- *Count = Values.size();
+ if (Count)
+ *Count = Values.size();
return false;
}
// Add a field to the current structure.
bool MasmParser::addIntegralField(StringRef Name, unsigned Size) {
StructInfo &Struct = StructInProgress.back();
- FieldInfo &Field = Struct.addField(Name, FT_INTEGRAL, Size);
+ FieldInfo &Field = Struct.addField(Name, FT_INTEGRAL, Size);
IntFieldInfo &IntInfo = Field.Contents.IntInfo;
Field.Type = Size;
@@ -3547,24 +3547,24 @@ bool MasmParser::parseDirectiveValue(StringRef IDVal, unsigned Size) {
/// parseDirectiveNamedValue
/// ::= name (byte | word | ... ) [ expression (, expression)* ]
-bool MasmParser::parseDirectiveNamedValue(StringRef TypeName, unsigned Size,
+bool MasmParser::parseDirectiveNamedValue(StringRef TypeName, unsigned Size,
StringRef Name, SMLoc NameLoc) {
if (StructInProgress.empty()) {
// Initialize named data value.
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
getStreamer().emitLabel(Sym);
- unsigned Count;
- if (emitIntegralValues(Size, &Count))
- return addErrorSuffix(" in '" + Twine(TypeName) + "' directive");
-
- AsmTypeInfo Type;
- Type.Name = TypeName;
- Type.Size = Size * Count;
- Type.ElementSize = Size;
- Type.Length = Count;
- KnownType[Name.lower()] = Type;
+ unsigned Count;
+ if (emitIntegralValues(Size, &Count))
+ return addErrorSuffix(" in '" + Twine(TypeName) + "' directive");
+
+ AsmTypeInfo Type;
+ Type.Name = TypeName;
+ Type.Size = Size * Count;
+ Type.ElementSize = Size;
+ Type.Length = Count;
+ KnownType[Name.lower()] = Type;
} else if (addIntegralField(Name, Size)) {
- return addErrorSuffix(" in '" + Twine(TypeName) + "' directive");
+ return addErrorSuffix(" in '" + Twine(TypeName) + "' directive");
}
return false;
@@ -3593,13 +3593,13 @@ bool MasmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) {
// We don't truly support arithmetic on floating point expressions, so we
// have to manually parse unary prefixes.
bool IsNeg = false;
- SMLoc SignLoc;
+ SMLoc SignLoc;
if (getLexer().is(AsmToken::Minus)) {
- SignLoc = getLexer().getLoc();
+ SignLoc = getLexer().getLoc();
Lexer.Lex();
IsNeg = true;
} else if (getLexer().is(AsmToken::Plus)) {
- SignLoc = getLexer().getLoc();
+ SignLoc = getLexer().getLoc();
Lexer.Lex();
}
@@ -3621,20 +3621,20 @@ bool MasmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) {
Value = APFloat::getZero(Semantics);
else
return TokError("invalid floating point literal");
- } else if (IDVal.consume_back("r") || IDVal.consume_back("R")) {
- // MASM hexadecimal floating-point literal; no APFloat conversion needed.
- // To match ML64.exe, ignore the initial sign.
- unsigned SizeInBits = Value.getSizeInBits(Semantics);
- if (SizeInBits != (IDVal.size() << 2))
- return TokError("invalid floating point literal");
-
- // Consume the numeric token.
- Lex();
-
- Res = APInt(SizeInBits, IDVal, 16);
- if (SignLoc.isValid())
- return Warning(SignLoc, "MASM-style hex floats ignore explicit sign");
- return false;
+ } else if (IDVal.consume_back("r") || IDVal.consume_back("R")) {
+ // MASM hexadecimal floating-point literal; no APFloat conversion needed.
+ // To match ML64.exe, ignore the initial sign.
+ unsigned SizeInBits = Value.getSizeInBits(Semantics);
+ if (SizeInBits != (IDVal.size() << 2))
+ return TokError("invalid floating point literal");
+
+ // Consume the numeric token.
+ Lex();
+
+ Res = APInt(SizeInBits, IDVal, 16);
+ if (SignLoc.isValid())
+ return Warning(SignLoc, "MASM-style hex floats ignore explicit sign");
+ return false;
} else if (errorToBool(
Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven)
.takeError())) {
@@ -3698,33 +3698,33 @@ bool MasmParser::parseRealInstList(const fltSemantics &Semantics,
}
// Initialize real data values.
-bool MasmParser::emitRealValues(const fltSemantics &Semantics,
- unsigned *Count) {
- if (checkForValidSection())
- return true;
-
+bool MasmParser::emitRealValues(const fltSemantics &Semantics,
+ unsigned *Count) {
+ if (checkForValidSection())
+ return true;
+
SmallVector<APInt, 1> ValuesAsInt;
if (parseRealInstList(Semantics, ValuesAsInt))
return true;
for (const APInt &AsInt : ValuesAsInt) {
- getStreamer().emitIntValue(AsInt);
+ getStreamer().emitIntValue(AsInt);
}
- if (Count)
- *Count = ValuesAsInt.size();
+ if (Count)
+ *Count = ValuesAsInt.size();
return false;
}
// Add a real field to the current struct.
-bool MasmParser::addRealField(StringRef Name, const fltSemantics &Semantics,
- size_t Size) {
+bool MasmParser::addRealField(StringRef Name, const fltSemantics &Semantics,
+ size_t Size) {
StructInfo &Struct = StructInProgress.back();
- FieldInfo &Field = Struct.addField(Name, FT_REAL, Size);
+ FieldInfo &Field = Struct.addField(Name, FT_REAL, Size);
RealFieldInfo &RealInfo = Field.Contents.RealInfo;
Field.SizeOf = 0;
- if (parseRealInstList(Semantics, RealInfo.AsIntValues))
+ if (parseRealInstList(Semantics, RealInfo.AsIntValues))
return true;
Field.Type = RealInfo.AsIntValues.back().getBitWidth() / 8;
@@ -3738,42 +3738,42 @@ bool MasmParser::addRealField(StringRef Name, const fltSemantics &Semantics,
}
/// parseDirectiveRealValue
-/// ::= (real4 | real8 | real10) [ expression (, expression)* ]
+/// ::= (real4 | real8 | real10) [ expression (, expression)* ]
bool MasmParser::parseDirectiveRealValue(StringRef IDVal,
- const fltSemantics &Semantics,
- size_t Size) {
+ const fltSemantics &Semantics,
+ size_t Size) {
if (StructInProgress.empty()) {
// Initialize data value.
if (emitRealValues(Semantics))
return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
- } else if (addRealField("", Semantics, Size)) {
+ } else if (addRealField("", Semantics, Size)) {
return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
}
return false;
}
/// parseDirectiveNamedRealValue
-/// ::= name (real4 | real8 | real10) [ expression (, expression)* ]
-bool MasmParser::parseDirectiveNamedRealValue(StringRef TypeName,
+/// ::= name (real4 | real8 | real10) [ expression (, expression)* ]
+bool MasmParser::parseDirectiveNamedRealValue(StringRef TypeName,
const fltSemantics &Semantics,
- unsigned Size, StringRef Name,
- SMLoc NameLoc) {
+ unsigned Size, StringRef Name,
+ SMLoc NameLoc) {
if (StructInProgress.empty()) {
// Initialize named data value.
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
getStreamer().emitLabel(Sym);
- unsigned Count;
- if (emitRealValues(Semantics, &Count))
- return addErrorSuffix(" in '" + TypeName + "' directive");
-
- AsmTypeInfo Type;
- Type.Name = TypeName;
- Type.Size = Size * Count;
- Type.ElementSize = Size;
- Type.Length = Count;
- KnownType[Name.lower()] = Type;
- } else if (addRealField(Name, Semantics, Size)) {
- return addErrorSuffix(" in '" + TypeName + "' directive");
+ unsigned Count;
+ if (emitRealValues(Semantics, &Count))
+ return addErrorSuffix(" in '" + TypeName + "' directive");
+
+ AsmTypeInfo Type;
+ Type.Name = TypeName;
+ Type.Size = Size * Count;
+ Type.ElementSize = Size;
+ Type.Length = Count;
+ KnownType[Name.lower()] = Type;
+ } else if (addRealField(Name, Semantics, Size)) {
+ return addErrorSuffix(" in '" + TypeName + "' directive");
}
return false;
}
@@ -3847,20 +3847,20 @@ bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
const RealFieldInfo &Contents,
FieldInitializer &Initializer) {
- const fltSemantics *Semantics;
- switch (Field.Type) {
- case 4:
- Semantics = &APFloat::IEEEsingle();
- break;
- case 8:
- Semantics = &APFloat::IEEEdouble();
- break;
- case 10:
- Semantics = &APFloat::x87DoubleExtended();
- break;
- default:
- llvm_unreachable("unknown real field type");
- }
+ const fltSemantics *Semantics;
+ switch (Field.Type) {
+ case 4:
+ Semantics = &APFloat::IEEEsingle();
+ break;
+ case 8:
+ Semantics = &APFloat::IEEEdouble();
+ break;
+ case 10:
+ Semantics = &APFloat::x87DoubleExtended();
+ break;
+ default:
+ llvm_unreachable("unknown real field type");
+ }
SMLoc Loc = getTok().getLoc();
@@ -3868,20 +3868,20 @@ bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
if (parseOptionalToken(AsmToken::LCurly)) {
if (Field.LengthOf == 1)
return Error(Loc, "Cannot initialize scalar field with array value");
- if (parseRealInstList(*Semantics, AsIntValues, AsmToken::RCurly) ||
+ if (parseRealInstList(*Semantics, AsIntValues, AsmToken::RCurly) ||
parseToken(AsmToken::RCurly))
return true;
} else if (parseOptionalAngleBracketOpen()) {
if (Field.LengthOf == 1)
return Error(Loc, "Cannot initialize scalar field with array value");
- if (parseRealInstList(*Semantics, AsIntValues, AsmToken::Greater) ||
+ if (parseRealInstList(*Semantics, AsIntValues, AsmToken::Greater) ||
parseAngleBracketClose())
return true;
} else if (Field.LengthOf > 1) {
return Error(Loc, "Cannot initialize array field with scalar value");
} else {
AsIntValues.emplace_back();
- if (parseRealValue(*Semantics, AsIntValues.back()))
+ if (parseRealValue(*Semantics, AsIntValues.back()))
return true;
}
@@ -4044,7 +4044,7 @@ bool MasmParser::parseStructInstList(
return true;
for (int i = 0; i < Repetitions; ++i)
- llvm::append_range(Initializers, DuplicatedValues);
+ llvm::append_range(Initializers, DuplicatedValues);
} else {
Initializers.emplace_back();
if (parseStructInitializer(Structure, Initializers.back()))
@@ -4197,8 +4197,8 @@ bool MasmParser::emitStructInitializer(const StructInfo &Structure,
}
// Set data values from initializers.
-bool MasmParser::emitStructValues(const StructInfo &Structure,
- unsigned *Count) {
+bool MasmParser::emitStructValues(const StructInfo &Structure,
+ unsigned *Count) {
std::vector<StructInitializer> Initializers;
if (parseStructInstList(Structure, Initializers))
return true;
@@ -4208,16 +4208,16 @@ bool MasmParser::emitStructValues(const StructInfo &Structure,
return true;
}
- if (Count)
- *Count = Initializers.size();
+ if (Count)
+ *Count = Initializers.size();
return false;
}
// Declare a field in the current struct.
bool MasmParser::addStructField(StringRef Name, const StructInfo &Structure) {
StructInfo &OwningStruct = StructInProgress.back();
- FieldInfo &Field =
- OwningStruct.addField(Name, FT_STRUCT, Structure.AlignmentSize);
+ FieldInfo &Field =
+ OwningStruct.addField(Name, FT_STRUCT, Structure.AlignmentSize);
StructFieldInfo &StructInfo = Field.Contents.StructInfo;
StructInfo.Structure = Structure;
@@ -4260,15 +4260,15 @@ bool MasmParser::parseDirectiveNamedStructValue(const StructInfo &Structure,
// Initialize named data value.
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
getStreamer().emitLabel(Sym);
- unsigned Count;
- if (emitStructValues(Structure, &Count))
+ unsigned Count;
+ if (emitStructValues(Structure, &Count))
return true;
- AsmTypeInfo Type;
- Type.Name = Structure.Name;
- Type.Size = Structure.Size * Count;
- Type.ElementSize = Structure.Size;
- Type.Length = Count;
- KnownType[Name.lower()] = Type;
+ AsmTypeInfo Type;
+ Type.Name = Structure.Name;
+ Type.Size = Structure.Size * Count;
+ Type.ElementSize = Structure.Size;
+ Type.Length = Count;
+ KnownType[Name.lower()] = Type;
} else if (addStructField(Name, Structure)) {
return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
}
@@ -4337,9 +4337,9 @@ bool MasmParser::parseDirectiveNestedStruct(StringRef Directive,
if (parseToken(AsmToken::EndOfStatement))
return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
- // Reserve space to ensure Alignment doesn't get invalidated when
- // StructInProgress grows.
- StructInProgress.reserve(StructInProgress.size() + 1);
+ // Reserve space to ensure Alignment doesn't get invalidated when
+ // StructInProgress grows.
+ StructInProgress.reserve(StructInProgress.size() + 1);
StructInProgress.emplace_back(Name, DirKind == DK_UNION,
StructInProgress.back().Alignment);
return false;
@@ -4354,10 +4354,10 @@ bool MasmParser::parseDirectiveEnds(StringRef Name, SMLoc NameLoc) {
return Error(NameLoc, "mismatched name in ENDS directive; expected '" +
StructInProgress.back().Name + "'");
StructInfo Structure = StructInProgress.pop_back_val();
- // Pad to make the structure's size divisible by the smaller of its alignment
- // and the size of its largest field.
- Structure.Size = llvm::alignTo(
- Structure.Size, std::min(Structure.Alignment, Structure.AlignmentSize));
+ // Pad to make the structure's size divisible by the smaller of its alignment
+ // and the size of its largest field.
+ Structure.Size = llvm::alignTo(
+ Structure.Size, std::min(Structure.Alignment, Structure.AlignmentSize));
Structs[Name.lower()] = Structure;
if (parseToken(AsmToken::EndOfStatement))
@@ -4402,8 +4402,8 @@ bool MasmParser::parseDirectiveNestedEnds() {
else
ParentStruct.Size += Structure.Size;
} else {
- FieldInfo &Field = ParentStruct.addField(Structure.Name, FT_STRUCT,
- Structure.AlignmentSize);
+ FieldInfo &Field = ParentStruct.addField(Structure.Name, FT_STRUCT,
+ Structure.AlignmentSize);
StructFieldInfo &StructInfo = Field.Contents.StructInfo;
Field.Type = Structure.Size;
Field.LengthOf = 1;
@@ -5476,59 +5476,59 @@ bool MasmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
}
/// parseDirectiveMacro
-/// ::= name macro [parameters]
-/// ["LOCAL" identifiers]
-/// parameters ::= parameter [, parameter]*
-/// parameter ::= name ":" qualifier
-/// qualifier ::= "req" | "vararg" | "=" macro_argument
-bool MasmParser::parseDirectiveMacro(StringRef Name, SMLoc NameLoc) {
+/// ::= name macro [parameters]
+/// ["LOCAL" identifiers]
+/// parameters ::= parameter [, parameter]*
+/// parameter ::= name ":" qualifier
+/// qualifier ::= "req" | "vararg" | "=" macro_argument
+bool MasmParser::parseDirectiveMacro(StringRef Name, SMLoc NameLoc) {
MCAsmMacroParameters Parameters;
while (getLexer().isNot(AsmToken::EndOfStatement)) {
if (!Parameters.empty() && Parameters.back().Vararg)
return Error(Lexer.getLoc(),
"Vararg parameter '" + Parameters.back().Name +
- "' should be last in the list of parameters");
+ "' should be last in the list of parameters");
MCAsmMacroParameter Parameter;
if (parseIdentifier(Parameter.Name))
- return TokError("expected identifier in 'macro' directive");
+ return TokError("expected identifier in 'macro' directive");
// Emit an error if two (or more) named parameters share the same name.
for (const MCAsmMacroParameter& CurrParam : Parameters)
- if (CurrParam.Name.equals_lower(Parameter.Name))
+ if (CurrParam.Name.equals_lower(Parameter.Name))
return TokError("macro '" + Name + "' has multiple parameters"
" named '" + Parameter.Name + "'");
if (Lexer.is(AsmToken::Colon)) {
Lex(); // consume ':'
- if (parseOptionalToken(AsmToken::Equal)) {
- // Default value
- SMLoc ParamLoc;
-
- ParamLoc = Lexer.getLoc();
- if (parseMacroArgument(nullptr, Parameter.Value))
- return true;
- } else {
- SMLoc QualLoc;
- StringRef Qualifier;
-
- QualLoc = Lexer.getLoc();
- if (parseIdentifier(Qualifier))
- return Error(QualLoc, "missing parameter qualifier for "
- "'" +
- Parameter.Name + "' in macro '" + Name +
- "'");
-
- if (Qualifier.equals_lower("req"))
- Parameter.Required = true;
- else if (Qualifier.equals_lower("vararg"))
- Parameter.Vararg = true;
- else
- return Error(QualLoc,
- Qualifier + " is not a valid parameter qualifier for '" +
- Parameter.Name + "' in macro '" + Name + "'");
- }
+ if (parseOptionalToken(AsmToken::Equal)) {
+ // Default value
+ SMLoc ParamLoc;
+
+ ParamLoc = Lexer.getLoc();
+ if (parseMacroArgument(nullptr, Parameter.Value))
+ return true;
+ } else {
+ SMLoc QualLoc;
+ StringRef Qualifier;
+
+ QualLoc = Lexer.getLoc();
+ if (parseIdentifier(Qualifier))
+ return Error(QualLoc, "missing parameter qualifier for "
+ "'" +
+ Parameter.Name + "' in macro '" + Name +
+ "'");
+
+ if (Qualifier.equals_lower("req"))
+ Parameter.Required = true;
+ else if (Qualifier.equals_lower("vararg"))
+ Parameter.Vararg = true;
+ else
+ return Error(QualLoc,
+ Qualifier + " is not a valid parameter qualifier for '" +
+ Parameter.Name + "' in macro '" + Name + "'");
+ }
}
Parameters.push_back(std::move(Parameter));
@@ -5540,28 +5540,28 @@ bool MasmParser::parseDirectiveMacro(StringRef Name, SMLoc NameLoc) {
// Eat just the end of statement.
Lexer.Lex();
- std::vector<std::string> Locals;
- if (getTok().is(AsmToken::Identifier) &&
- getTok().getIdentifier().equals_lower("local")) {
- Lex(); // Eat the LOCAL directive.
-
- StringRef ID;
- while (true) {
- if (parseIdentifier(ID))
- return true;
- Locals.push_back(ID.lower());
-
- // If we see a comma, continue (and allow line continuation).
- if (!parseOptionalToken(AsmToken::Comma))
- break;
- parseOptionalToken(AsmToken::EndOfStatement);
- }
- }
-
+ std::vector<std::string> Locals;
+ if (getTok().is(AsmToken::Identifier) &&
+ getTok().getIdentifier().equals_lower("local")) {
+ Lex(); // Eat the LOCAL directive.
+
+ StringRef ID;
+ while (true) {
+ if (parseIdentifier(ID))
+ return true;
+ Locals.push_back(ID.lower());
+
+ // If we see a comma, continue (and allow line continuation).
+ if (!parseOptionalToken(AsmToken::Comma))
+ break;
+ parseOptionalToken(AsmToken::EndOfStatement);
+ }
+ }
+
// Consuming deferred text, so use Lexer.Lex to ignore Lexing Errors.
AsmToken EndToken, StartToken = getTok();
unsigned MacroDepth = 0;
- bool IsMacroFunction = false;
+ bool IsMacroFunction = false;
// Lex the macro definition.
while (true) {
// Ignore Lexing errors in macros.
@@ -5571,12 +5571,12 @@ bool MasmParser::parseDirectiveMacro(StringRef Name, SMLoc NameLoc) {
// Check whether we have reached the end of the file.
if (getLexer().is(AsmToken::Eof))
- return Error(NameLoc, "no matching 'endm' in definition");
+ return Error(NameLoc, "no matching 'endm' in definition");
- // Otherwise, check whether we have reached the 'endm'... and determine if
- // this is a macro function.
+ // Otherwise, check whether we have reached the 'endm'... and determine if
+ // this is a macro function.
if (getLexer().is(AsmToken::Identifier)) {
- if (getTok().getIdentifier().equals_lower("endm")) {
+ if (getTok().getIdentifier().equals_lower("endm")) {
if (MacroDepth == 0) { // Outermost macro.
EndToken = getTok();
Lexer.Lex();
@@ -5588,14 +5588,14 @@ bool MasmParser::parseDirectiveMacro(StringRef Name, SMLoc NameLoc) {
// Otherwise we just found the end of an inner macro.
--MacroDepth;
}
- } else if (getTok().getIdentifier().equals_lower("exitm")) {
- if (MacroDepth == 0 &&
- getLexer().peekTok().isNot(AsmToken::EndOfStatement)) {
- IsMacroFunction = true;
- }
- } else if (isMacroLikeDirective()) {
- // We allow nested macros. Those aren't instantiated until the
- // outermost macro is expanded so just ignore them for now.
+ } else if (getTok().getIdentifier().equals_lower("exitm")) {
+ if (MacroDepth == 0 &&
+ getLexer().peekTok().isNot(AsmToken::EndOfStatement)) {
+ IsMacroFunction = true;
+ }
+ } else if (isMacroLikeDirective()) {
+ // We allow nested macros. Those aren't instantiated until the
+ // outermost macro is expanded so just ignore them for now.
++MacroDepth;
}
}
@@ -5604,15 +5604,15 @@ bool MasmParser::parseDirectiveMacro(StringRef Name, SMLoc NameLoc) {
eatToEndOfStatement();
}
- if (getContext().lookupMacro(Name.lower())) {
- return Error(NameLoc, "macro '" + Name + "' is already defined");
+ if (getContext().lookupMacro(Name.lower())) {
+ return Error(NameLoc, "macro '" + Name + "' is already defined");
}
const char *BodyStart = StartToken.getLoc().getPointer();
const char *BodyEnd = EndToken.getLoc().getPointer();
StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
- MCAsmMacro Macro(Name, Body, std::move(Parameters), std::move(Locals),
- IsMacroFunction);
+ MCAsmMacro Macro(Name, Body, std::move(Parameters), std::move(Locals),
+ IsMacroFunction);
DEBUG_WITH_TYPE("asm-macros", dbgs() << "Defining new macro:\n";
Macro.dump());
getContext().defineMacro(Name, std::move(Macro));
@@ -5620,15 +5620,15 @@ bool MasmParser::parseDirectiveMacro(StringRef Name, SMLoc NameLoc) {
}
/// parseDirectiveExitMacro
-/// ::= "exitm" [textitem]
-bool MasmParser::parseDirectiveExitMacro(SMLoc DirectiveLoc,
- StringRef Directive,
- std::string &Value) {
- SMLoc EndLoc = getTok().getLoc();
- if (getTok().isNot(AsmToken::EndOfStatement) && parseTextItem(Value))
- return Error(EndLoc,
- "unable to parse text item in '" + Directive + "' directive");
- eatToEndOfStatement();
+/// ::= "exitm" [textitem]
+bool MasmParser::parseDirectiveExitMacro(SMLoc DirectiveLoc,
+ StringRef Directive,
+ std::string &Value) {
+ SMLoc EndLoc = getTok().getLoc();
+ if (getTok().isNot(AsmToken::EndOfStatement) && parseTextItem(Value))
+ return Error(EndLoc,
+ "unable to parse text item in '" + Directive + "' directive");
+ eatToEndOfStatement();
if (!isInsideMacroInstantiation())
return TokError("unexpected '" + Directive + "' in file, "
@@ -5645,7 +5645,7 @@ bool MasmParser::parseDirectiveExitMacro(SMLoc DirectiveLoc,
}
/// parseDirectiveEndMacro
-/// ::= endm
+/// ::= endm
bool MasmParser::parseDirectiveEndMacro(StringRef Directive) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '" + Directive + "' directive");
@@ -5664,27 +5664,27 @@ bool MasmParser::parseDirectiveEndMacro(StringRef Directive) {
}
/// parseDirectivePurgeMacro
-/// ::= purge identifier ( , identifier )*
+/// ::= purge identifier ( , identifier )*
bool MasmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
StringRef Name;
- while (true) {
- SMLoc NameLoc;
- if (parseTokenLoc(NameLoc) ||
- check(parseIdentifier(Name), NameLoc,
- "expected identifier in 'purge' directive"))
- return true;
-
- DEBUG_WITH_TYPE("asm-macros", dbgs()
- << "Un-defining macro: " << Name << "\n");
- if (!getContext().lookupMacro(Name.lower()))
- return Error(NameLoc, "macro '" + Name + "' is not defined");
- getContext().undefineMacro(Name.lower());
-
- if (!parseOptionalToken(AsmToken::Comma))
- break;
- parseOptionalToken(AsmToken::EndOfStatement);
- }
-
+ while (true) {
+ SMLoc NameLoc;
+ if (parseTokenLoc(NameLoc) ||
+ check(parseIdentifier(Name), NameLoc,
+ "expected identifier in 'purge' directive"))
+ return true;
+
+ DEBUG_WITH_TYPE("asm-macros", dbgs()
+ << "Un-defining macro: " << Name << "\n");
+ if (!getContext().lookupMacro(Name.lower()))
+ return Error(NameLoc, "macro '" + Name + "' is not defined");
+ getContext().undefineMacro(Name.lower());
+
+ if (!parseOptionalToken(AsmToken::Comma))
+ break;
+ parseOptionalToken(AsmToken::EndOfStatement);
+ }
+
return false;
}
@@ -5792,17 +5792,17 @@ bool MasmParser::parseDirectiveComm(bool IsLocal) {
/// [[text]]
/// [[text]] delimiter [[text]]
bool MasmParser::parseDirectiveComment(SMLoc DirectiveLoc) {
- std::string FirstLine = parseStringTo(AsmToken::EndOfStatement);
+ std::string FirstLine = parseStringTo(AsmToken::EndOfStatement);
size_t DelimiterEnd = FirstLine.find_first_of("\b\t\v\f\r\x1A ");
- StringRef Delimiter = StringRef(FirstLine).take_front(DelimiterEnd);
+ StringRef Delimiter = StringRef(FirstLine).take_front(DelimiterEnd);
if (Delimiter.empty())
return Error(DirectiveLoc, "no delimiter in 'comment' directive");
do {
if (getTok().is(AsmToken::Eof))
return Error(DirectiveLoc, "unmatched delimiter in 'comment' directive");
Lex(); // eat end of statement
- } while (
- !StringRef(parseStringTo(AsmToken::EndOfStatement)).contains(Delimiter));
+ } while (
+ !StringRef(parseStringTo(AsmToken::EndOfStatement)).contains(Delimiter));
return parseToken(AsmToken::EndOfStatement,
"unexpected token in 'comment' directive");
}
@@ -5816,7 +5816,7 @@ bool MasmParser::parseDirectiveInclude() {
SMLoc IncludeLoc = getTok().getLoc();
if (!parseAngleBracketString(Filename))
- Filename = parseStringTo(AsmToken::EndOfStatement);
+ Filename = parseStringTo(AsmToken::EndOfStatement);
if (check(!Filename.empty(), "missing filename in 'include' directive") ||
check(getTok().isNot(AsmToken::EndOfStatement),
"unexpected token in 'include' directive") ||
@@ -5861,7 +5861,7 @@ bool MasmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
}
/// parseDirectiveIfb
-/// ::= .ifb textitem
+/// ::= .ifb textitem
bool MasmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
TheCondStack.push_back(TheCondState);
TheCondState.TheCond = AsmCond::IfCond;
@@ -5871,7 +5871,7 @@ bool MasmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
} else {
std::string Str;
if (parseTextItem(Str))
- return TokError("expected text item parameter for 'ifb' directive");
+ return TokError("expected text item parameter for 'ifb' directive");
if (parseToken(AsmToken::EndOfStatement,
"unexpected token in 'ifb' directive"))
@@ -5885,15 +5885,15 @@ bool MasmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
}
/// parseDirectiveIfidn
-/// ::= ifidn textitem, textitem
-bool MasmParser::parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
- bool CaseInsensitive) {
+/// ::= ifidn textitem, textitem
+bool MasmParser::parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
+ bool CaseInsensitive) {
std::string String1, String2;
if (parseTextItem(String1)) {
if (ExpectEqual)
- return TokError("expected text item parameter for 'ifidn' directive");
- return TokError("expected text item parameter for 'ifdif' directive");
+ return TokError("expected text item parameter for 'ifidn' directive");
+ return TokError("expected text item parameter for 'ifdif' directive");
}
if (Lexer.isNot(AsmToken::Comma)) {
@@ -5906,8 +5906,8 @@ bool MasmParser::parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
if (parseTextItem(String2)) {
if (ExpectEqual)
- return TokError("expected text item parameter for 'ifidn' directive");
- return TokError("expected text item parameter for 'ifdif' directive");
+ return TokError("expected text item parameter for 'ifidn' directive");
+ return TokError("expected text item parameter for 'ifdif' directive");
}
TheCondStack.push_back(TheCondState);
@@ -6001,7 +6001,7 @@ bool MasmParser::parseDirectiveElseIf(SMLoc DirectiveLoc,
}
/// parseDirectiveElseIfb
-/// ::= elseifb textitem
+/// ::= elseifb textitem
bool MasmParser::parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
if (TheCondState.TheCond != AsmCond::IfCond &&
TheCondState.TheCond != AsmCond::ElseIfCond)
@@ -6017,11 +6017,11 @@ bool MasmParser::parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
eatToEndOfStatement();
} else {
std::string Str;
- if (parseTextItem(Str)) {
- if (ExpectBlank)
- return TokError("expected text item parameter for 'elseifb' directive");
- return TokError("expected text item parameter for 'elseifnb' directive");
- }
+ if (parseTextItem(Str)) {
+ if (ExpectBlank)
+ return TokError("expected text item parameter for 'elseifb' directive");
+ return TokError("expected text item parameter for 'elseifnb' directive");
+ }
if (parseToken(AsmToken::EndOfStatement,
"unexpected token in 'elseifb' directive"))
@@ -6081,7 +6081,7 @@ bool MasmParser::parseDirectiveElseIfdef(SMLoc DirectiveLoc,
}
/// parseDirectiveElseIfidn
-/// ::= elseifidn textitem, textitem
+/// ::= elseifidn textitem, textitem
bool MasmParser::parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
bool CaseInsensitive) {
if (TheCondState.TheCond != AsmCond::IfCond &&
@@ -6101,9 +6101,9 @@ bool MasmParser::parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
if (parseTextItem(String1)) {
if (ExpectEqual)
- return TokError(
- "expected text item parameter for 'elseifidn' directive");
- return TokError("expected text item parameter for 'elseifdif' directive");
+ return TokError(
+ "expected text item parameter for 'elseifidn' directive");
+ return TokError("expected text item parameter for 'elseifdif' directive");
}
if (Lexer.isNot(AsmToken::Comma)) {
@@ -6117,9 +6117,9 @@ bool MasmParser::parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
if (parseTextItem(String2)) {
if (ExpectEqual)
- return TokError(
- "expected text item parameter for 'elseifidn' directive");
- return TokError("expected text item parameter for 'elseifdif' directive");
+ return TokError(
+ "expected text item parameter for 'elseifidn' directive");
+ return TokError("expected text item parameter for 'elseifdif' directive");
}
if (CaseInsensitive)
@@ -6179,9 +6179,9 @@ bool MasmParser::parseDirectiveError(SMLoc DirectiveLoc) {
}
}
- std::string Message = ".err directive invoked in source file";
+ std::string Message = ".err directive invoked in source file";
if (Lexer.isNot(AsmToken::EndOfStatement))
- Message = parseStringTo(AsmToken::EndOfStatement);
+ Message = parseStringTo(AsmToken::EndOfStatement);
Lex();
return Error(DirectiveLoc, Message);
@@ -6201,11 +6201,11 @@ bool MasmParser::parseDirectiveErrorIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
if (parseTextItem(Text))
return Error(getTok().getLoc(), "missing text item in '.errb' directive");
- std::string Message = ".errb directive invoked in source file";
+ std::string Message = ".errb directive invoked in source file";
if (Lexer.isNot(AsmToken::EndOfStatement)) {
if (parseToken(AsmToken::Comma))
return addErrorSuffix(" in '.errb' directive");
- Message = parseStringTo(AsmToken::EndOfStatement);
+ Message = parseStringTo(AsmToken::EndOfStatement);
}
Lex();
@@ -6243,11 +6243,11 @@ bool MasmParser::parseDirectiveErrorIfdef(SMLoc DirectiveLoc,
}
}
- std::string Message = ".errdef directive invoked in source file";
+ std::string Message = ".errdef directive invoked in source file";
if (Lexer.isNot(AsmToken::EndOfStatement)) {
if (parseToken(AsmToken::Comma))
return addErrorSuffix(" in '.errdef' directive");
- Message = parseStringTo(AsmToken::EndOfStatement);
+ Message = parseStringTo(AsmToken::EndOfStatement);
}
Lex();
@@ -6257,7 +6257,7 @@ bool MasmParser::parseDirectiveErrorIfdef(SMLoc DirectiveLoc,
}
/// parseDirectiveErrorIfidn
-/// ::= .erridn textitem, textitem[, message]
+/// ::= .erridn textitem, textitem[, message]
bool MasmParser::parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
bool CaseInsensitive) {
if (!TheCondStack.empty()) {
@@ -6290,7 +6290,7 @@ bool MasmParser::parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
return TokError("expected string parameter for '.errdif' directive");
}
- std::string Message;
+ std::string Message;
if (ExpectEqual)
Message = ".erridn directive invoked in source file";
else
@@ -6298,7 +6298,7 @@ bool MasmParser::parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
if (Lexer.isNot(AsmToken::EndOfStatement)) {
if (parseToken(AsmToken::Comma))
return addErrorSuffix(" in '.erridn' directive");
- Message = parseStringTo(AsmToken::EndOfStatement);
+ Message = parseStringTo(AsmToken::EndOfStatement);
}
Lex();
@@ -6330,11 +6330,11 @@ bool MasmParser::parseDirectiveErrorIfe(SMLoc DirectiveLoc, bool ExpectZero) {
if (parseAbsoluteExpression(ExprValue))
return addErrorSuffix(" in '.erre' directive");
- std::string Message = ".erre directive invoked in source file";
+ std::string Message = ".erre directive invoked in source file";
if (Lexer.isNot(AsmToken::EndOfStatement)) {
if (parseToken(AsmToken::Comma))
return addErrorSuffix(" in '.erre' directive");
- Message = parseStringTo(AsmToken::EndOfStatement);
+ Message = parseStringTo(AsmToken::EndOfStatement);
}
Lex();
@@ -6379,7 +6379,7 @@ void MasmParser::initializeDirectiveKindMap() {
DirectiveKindMap["sqword"] = DK_SQWORD;
DirectiveKindMap["real4"] = DK_REAL4;
DirectiveKindMap["real8"] = DK_REAL8;
- DirectiveKindMap["real10"] = DK_REAL10;
+ DirectiveKindMap["real10"] = DK_REAL10;
DirectiveKindMap["align"] = DK_ALIGN;
// DirectiveKindMap[".org"] = DK_ORG;
DirectiveKindMap["extern"] = DK_EXTERN;
@@ -6387,13 +6387,13 @@ void MasmParser::initializeDirectiveKindMap() {
// DirectiveKindMap[".comm"] = DK_COMM;
DirectiveKindMap["comment"] = DK_COMMENT;
DirectiveKindMap["include"] = DK_INCLUDE;
- DirectiveKindMap["repeat"] = DK_REPEAT;
- DirectiveKindMap["rept"] = DK_REPEAT;
- DirectiveKindMap["while"] = DK_WHILE;
- DirectiveKindMap["for"] = DK_FOR;
- DirectiveKindMap["irp"] = DK_FOR;
- DirectiveKindMap["forc"] = DK_FORC;
- DirectiveKindMap["irpc"] = DK_FORC;
+ DirectiveKindMap["repeat"] = DK_REPEAT;
+ DirectiveKindMap["rept"] = DK_REPEAT;
+ DirectiveKindMap["while"] = DK_WHILE;
+ DirectiveKindMap["for"] = DK_FOR;
+ DirectiveKindMap["irp"] = DK_FOR;
+ DirectiveKindMap["forc"] = DK_FORC;
+ DirectiveKindMap["irpc"] = DK_FORC;
DirectiveKindMap["if"] = DK_IF;
DirectiveKindMap["ife"] = DK_IFE;
DirectiveKindMap["ifb"] = DK_IFB;
@@ -6450,10 +6450,10 @@ void MasmParser::initializeDirectiveKindMap() {
// DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
// DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
// DirectiveKindMap[".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME;
- DirectiveKindMap["macro"] = DK_MACRO;
- DirectiveKindMap["exitm"] = DK_EXITM;
- DirectiveKindMap["endm"] = DK_ENDM;
- DirectiveKindMap["purge"] = DK_PURGE;
+ DirectiveKindMap["macro"] = DK_MACRO;
+ DirectiveKindMap["exitm"] = DK_EXITM;
+ DirectiveKindMap["endm"] = DK_ENDM;
+ DirectiveKindMap["purge"] = DK_PURGE;
DirectiveKindMap[".err"] = DK_ERR;
DirectiveKindMap[".errb"] = DK_ERRB;
DirectiveKindMap[".errnb"] = DK_ERRNB;
@@ -6465,15 +6465,15 @@ void MasmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".erridni"] = DK_ERRIDNI;
DirectiveKindMap[".erre"] = DK_ERRE;
DirectiveKindMap[".errnz"] = DK_ERRNZ;
- DirectiveKindMap[".pushframe"] = DK_PUSHFRAME;
- DirectiveKindMap[".pushreg"] = DK_PUSHREG;
- DirectiveKindMap[".savereg"] = DK_SAVEREG;
- DirectiveKindMap[".savexmm128"] = DK_SAVEXMM128;
- DirectiveKindMap[".setframe"] = DK_SETFRAME;
- DirectiveKindMap[".radix"] = DK_RADIX;
+ DirectiveKindMap[".pushframe"] = DK_PUSHFRAME;
+ DirectiveKindMap[".pushreg"] = DK_PUSHREG;
+ DirectiveKindMap[".savereg"] = DK_SAVEREG;
+ DirectiveKindMap[".savexmm128"] = DK_SAVEXMM128;
+ DirectiveKindMap[".setframe"] = DK_SETFRAME;
+ DirectiveKindMap[".radix"] = DK_RADIX;
DirectiveKindMap["db"] = DK_DB;
DirectiveKindMap["dd"] = DK_DD;
- DirectiveKindMap["df"] = DK_DF;
+ DirectiveKindMap["df"] = DK_DF;
DirectiveKindMap["dq"] = DK_DQ;
DirectiveKindMap["dw"] = DK_DW;
DirectiveKindMap["echo"] = DK_ECHO;
@@ -6483,24 +6483,24 @@ void MasmParser::initializeDirectiveKindMap() {
DirectiveKindMap["ends"] = DK_ENDS;
}
-bool MasmParser::isMacroLikeDirective() {
- if (getLexer().is(AsmToken::Identifier)) {
- bool IsMacroLike = StringSwitch<bool>(getTok().getIdentifier())
- .CasesLower("repeat", "rept", true)
- .CaseLower("while", true)
- .CasesLower("for", "irp", true)
- .CasesLower("forc", "irpc", true)
- .Default(false);
- if (IsMacroLike)
- return true;
- }
- if (getLexer().peekTok().is(AsmToken::Identifier) &&
- getLexer().peekTok().getIdentifier().equals_lower("macro"))
- return true;
-
- return false;
-}
-
+bool MasmParser::isMacroLikeDirective() {
+ if (getLexer().is(AsmToken::Identifier)) {
+ bool IsMacroLike = StringSwitch<bool>(getTok().getIdentifier())
+ .CasesLower("repeat", "rept", true)
+ .CaseLower("while", true)
+ .CasesLower("for", "irp", true)
+ .CasesLower("forc", "irpc", true)
+ .Default(false);
+ if (IsMacroLike)
+ return true;
+ }
+ if (getLexer().peekTok().is(AsmToken::Identifier) &&
+ getLexer().peekTok().getIdentifier().equals_lower("macro"))
+ return true;
+
+ return false;
+}
+
MCAsmMacro *MasmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
AsmToken EndToken, StartToken = getTok();
@@ -6508,21 +6508,21 @@ MCAsmMacro *MasmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
while (true) {
// Check whether we have reached the end of the file.
if (getLexer().is(AsmToken::Eof)) {
- printError(DirectiveLoc, "no matching 'endm' in definition");
+ printError(DirectiveLoc, "no matching 'endm' in definition");
return nullptr;
}
- if (isMacroLikeDirective())
+ if (isMacroLikeDirective())
++NestLevel;
- // Otherwise, check whether we have reached the endm.
- if (Lexer.is(AsmToken::Identifier) &&
- getTok().getIdentifier().equals_lower("endm")) {
+ // Otherwise, check whether we have reached the endm.
+ if (Lexer.is(AsmToken::Identifier) &&
+ getTok().getIdentifier().equals_lower("endm")) {
if (NestLevel == 0) {
EndToken = getTok();
Lex();
if (Lexer.isNot(AsmToken::EndOfStatement)) {
- printError(getTok().getLoc(), "unexpected token in 'endm' directive");
+ printError(getTok().getLoc(), "unexpected token in 'endm' directive");
return nullptr;
}
break;
@@ -6543,73 +6543,73 @@ MCAsmMacro *MasmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
return &MacroLikeBodies.back();
}
-bool MasmParser::expandStatement(SMLoc Loc) {
- std::string Body = parseStringTo(AsmToken::EndOfStatement);
- SMLoc EndLoc = getTok().getLoc();
-
- MCAsmMacroParameters Parameters;
- MCAsmMacroArguments Arguments;
- for (const auto &V : Variables) {
- const Variable &Var = V.getValue();
- if (Var.IsText) {
- Parameters.emplace_back();
- Arguments.emplace_back();
- MCAsmMacroParameter &P = Parameters.back();
- MCAsmMacroArgument &A = Arguments.back();
- P.Name = Var.Name;
- P.Required = true;
- A.push_back(AsmToken(AsmToken::String, Var.TextValue));
- }
- }
- MacroLikeBodies.emplace_back(StringRef(), Body, Parameters);
- MCAsmMacro M = MacroLikeBodies.back();
-
- // Expand the statement in a new buffer.
- SmallString<80> Buf;
- raw_svector_ostream OS(Buf);
- if (expandMacro(OS, M.Body, M.Parameters, Arguments, M.Locals, EndLoc))
- return true;
- std::unique_ptr<MemoryBuffer> Expansion =
- MemoryBuffer::getMemBufferCopy(OS.str(), "<expansion>");
-
- // Jump to the expanded statement and prime the lexer.
- CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Expansion), EndLoc);
- Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
- EndStatementAtEOFStack.push_back(false);
- Lex();
- return false;
-}
-
+bool MasmParser::expandStatement(SMLoc Loc) {
+ std::string Body = parseStringTo(AsmToken::EndOfStatement);
+ SMLoc EndLoc = getTok().getLoc();
+
+ MCAsmMacroParameters Parameters;
+ MCAsmMacroArguments Arguments;
+ for (const auto &V : Variables) {
+ const Variable &Var = V.getValue();
+ if (Var.IsText) {
+ Parameters.emplace_back();
+ Arguments.emplace_back();
+ MCAsmMacroParameter &P = Parameters.back();
+ MCAsmMacroArgument &A = Arguments.back();
+ P.Name = Var.Name;
+ P.Required = true;
+ A.push_back(AsmToken(AsmToken::String, Var.TextValue));
+ }
+ }
+ MacroLikeBodies.emplace_back(StringRef(), Body, Parameters);
+ MCAsmMacro M = MacroLikeBodies.back();
+
+ // Expand the statement in a new buffer.
+ SmallString<80> Buf;
+ raw_svector_ostream OS(Buf);
+ if (expandMacro(OS, M.Body, M.Parameters, Arguments, M.Locals, EndLoc))
+ return true;
+ std::unique_ptr<MemoryBuffer> Expansion =
+ MemoryBuffer::getMemBufferCopy(OS.str(), "<expansion>");
+
+ // Jump to the expanded statement and prime the lexer.
+ CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Expansion), EndLoc);
+ Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
+ EndStatementAtEOFStack.push_back(false);
+ Lex();
+ return false;
+}
+
+void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
+ raw_svector_ostream &OS) {
+ instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/getTok().getLoc(), OS);
+}
void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
+ SMLoc ExitLoc,
raw_svector_ostream &OS) {
- instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/getTok().getLoc(), OS);
-}
-void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
- SMLoc ExitLoc,
- raw_svector_ostream &OS) {
- OS << "endm\n";
+ OS << "endm\n";
std::unique_ptr<MemoryBuffer> Instantiation =
MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
// Create the macro instantiation object and add to the current macro
// instantiation stack.
- MacroInstantiation *MI = new MacroInstantiation{DirectiveLoc, CurBuffer,
- ExitLoc, TheCondStack.size()};
+ MacroInstantiation *MI = new MacroInstantiation{DirectiveLoc, CurBuffer,
+ ExitLoc, TheCondStack.size()};
ActiveMacros.push_back(MI);
// Jump to the macro instantiation and prime the lexer.
CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
- EndStatementAtEOFStack.push_back(true);
+ EndStatementAtEOFStack.push_back(true);
Lex();
}
-/// parseDirectiveRepeat
-/// ::= ("repeat" | "rept") count
-/// body
-/// endm
-bool MasmParser::parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Dir) {
+/// parseDirectiveRepeat
+/// ::= ("repeat" | "rept") count
+/// body
+/// endm
+bool MasmParser::parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Dir) {
const MCExpr *CountExpr;
SMLoc CountLoc = getTok().getLoc();
if (parseExpression(CountExpr))
@@ -6625,7 +6625,7 @@ bool MasmParser::parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Dir) {
"unexpected token in '" + Dir + "' directive"))
return true;
- // Lex the repeat definition.
+ // Lex the repeat definition.
MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
if (!M)
return true;
@@ -6635,7 +6635,7 @@ bool MasmParser::parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Dir) {
SmallString<256> Buf;
raw_svector_ostream OS(Buf);
while (Count--) {
- if (expandMacro(OS, M->Body, None, None, M->Locals, getTok().getLoc()))
+ if (expandMacro(OS, M->Body, None, None, M->Locals, getTok().getLoc()))
return true;
}
instantiateMacroLikeBody(M, DirectiveLoc, OS);
@@ -6643,104 +6643,104 @@ bool MasmParser::parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Dir) {
return false;
}
-/// parseDirectiveWhile
-/// ::= "while" expression
-/// body
-/// endm
-bool MasmParser::parseDirectiveWhile(SMLoc DirectiveLoc) {
- const MCExpr *CondExpr;
- SMLoc CondLoc = getTok().getLoc();
- if (parseExpression(CondExpr))
- return true;
-
- // Lex the repeat definition.
- MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
- if (!M)
- return true;
-
- // Macro instantiation is lexical, unfortunately. We construct a new buffer
- // to hold the macro body with substitutions.
- SmallString<256> Buf;
- raw_svector_ostream OS(Buf);
- int64_t Condition;
- if (!CondExpr->evaluateAsAbsolute(Condition, getStreamer().getAssemblerPtr()))
- return Error(CondLoc, "expected absolute expression in 'while' directive");
- if (Condition) {
- // Instantiate the macro, then resume at this directive to recheck the
- // condition.
- if (expandMacro(OS, M->Body, None, None, M->Locals, getTok().getLoc()))
- return true;
- instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/DirectiveLoc, OS);
- }
-
- return false;
-}
-
-/// parseDirectiveFor
-/// ::= ("for" | "irp") symbol [":" qualifier], <values>
-/// body
-/// endm
-bool MasmParser::parseDirectiveFor(SMLoc DirectiveLoc, StringRef Dir) {
+/// parseDirectiveWhile
+/// ::= "while" expression
+/// body
+/// endm
+bool MasmParser::parseDirectiveWhile(SMLoc DirectiveLoc) {
+ const MCExpr *CondExpr;
+ SMLoc CondLoc = getTok().getLoc();
+ if (parseExpression(CondExpr))
+ return true;
+
+ // Lex the repeat definition.
+ MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
+ if (!M)
+ return true;
+
+ // Macro instantiation is lexical, unfortunately. We construct a new buffer
+ // to hold the macro body with substitutions.
+ SmallString<256> Buf;
+ raw_svector_ostream OS(Buf);
+ int64_t Condition;
+ if (!CondExpr->evaluateAsAbsolute(Condition, getStreamer().getAssemblerPtr()))
+ return Error(CondLoc, "expected absolute expression in 'while' directive");
+ if (Condition) {
+ // Instantiate the macro, then resume at this directive to recheck the
+ // condition.
+ if (expandMacro(OS, M->Body, None, None, M->Locals, getTok().getLoc()))
+ return true;
+ instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/DirectiveLoc, OS);
+ }
+
+ return false;
+}
+
+/// parseDirectiveFor
+/// ::= ("for" | "irp") symbol [":" qualifier], <values>
+/// body
+/// endm
+bool MasmParser::parseDirectiveFor(SMLoc DirectiveLoc, StringRef Dir) {
MCAsmMacroParameter Parameter;
MCAsmMacroArguments A;
if (check(parseIdentifier(Parameter.Name),
- "expected identifier in '" + Dir + "' directive"))
- return true;
-
- // Parse optional qualifier (default value, or "req")
- if (parseOptionalToken(AsmToken::Colon)) {
- if (parseOptionalToken(AsmToken::Equal)) {
- // Default value
- SMLoc ParamLoc;
-
- ParamLoc = Lexer.getLoc();
- if (parseMacroArgument(nullptr, Parameter.Value))
- return true;
- } else {
- SMLoc QualLoc;
- StringRef Qualifier;
-
- QualLoc = Lexer.getLoc();
- if (parseIdentifier(Qualifier))
- return Error(QualLoc, "missing parameter qualifier for "
- "'" +
- Parameter.Name + "' in '" + Dir +
- "' directive");
-
- if (Qualifier.equals_lower("req"))
- Parameter.Required = true;
- else
- return Error(QualLoc,
- Qualifier + " is not a valid parameter qualifier for '" +
- Parameter.Name + "' in '" + Dir + "' directive");
- }
- }
-
- if (parseToken(AsmToken::Comma,
- "expected comma in '" + Dir + "' directive") ||
- parseToken(AsmToken::Less,
- "values in '" + Dir +
- "' directive must be enclosed in angle brackets"))
- return true;
-
- while (true) {
- A.emplace_back();
- if (parseMacroArgument(&Parameter, A.back(), /*EndTok=*/AsmToken::Greater))
- return addErrorSuffix(" in arguments for '" + Dir + "' directive");
-
- // If we see a comma, continue, and allow line continuation.
- if (!parseOptionalToken(AsmToken::Comma))
- break;
- parseOptionalToken(AsmToken::EndOfStatement);
- }
-
- if (parseToken(AsmToken::Greater,
- "values in '" + Dir +
- "' directive must be enclosed in angle brackets") ||
+ "expected identifier in '" + Dir + "' directive"))
+ return true;
+
+ // Parse optional qualifier (default value, or "req")
+ if (parseOptionalToken(AsmToken::Colon)) {
+ if (parseOptionalToken(AsmToken::Equal)) {
+ // Default value
+ SMLoc ParamLoc;
+
+ ParamLoc = Lexer.getLoc();
+ if (parseMacroArgument(nullptr, Parameter.Value))
+ return true;
+ } else {
+ SMLoc QualLoc;
+ StringRef Qualifier;
+
+ QualLoc = Lexer.getLoc();
+ if (parseIdentifier(Qualifier))
+ return Error(QualLoc, "missing parameter qualifier for "
+ "'" +
+ Parameter.Name + "' in '" + Dir +
+ "' directive");
+
+ if (Qualifier.equals_lower("req"))
+ Parameter.Required = true;
+ else
+ return Error(QualLoc,
+ Qualifier + " is not a valid parameter qualifier for '" +
+ Parameter.Name + "' in '" + Dir + "' directive");
+ }
+ }
+
+ if (parseToken(AsmToken::Comma,
+ "expected comma in '" + Dir + "' directive") ||
+ parseToken(AsmToken::Less,
+ "values in '" + Dir +
+ "' directive must be enclosed in angle brackets"))
+ return true;
+
+ while (true) {
+ A.emplace_back();
+ if (parseMacroArgument(&Parameter, A.back(), /*EndTok=*/AsmToken::Greater))
+ return addErrorSuffix(" in arguments for '" + Dir + "' directive");
+
+ // If we see a comma, continue, and allow line continuation.
+ if (!parseOptionalToken(AsmToken::Comma))
+ break;
+ parseOptionalToken(AsmToken::EndOfStatement);
+ }
+
+ if (parseToken(AsmToken::Greater,
+ "values in '" + Dir +
+ "' directive must be enclosed in angle brackets") ||
parseToken(AsmToken::EndOfStatement, "expected End of Statement"))
return true;
- // Lex the for definition.
+ // Lex the for definition.
MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
if (!M)
return true;
@@ -6751,7 +6751,7 @@ bool MasmParser::parseDirectiveFor(SMLoc DirectiveLoc, StringRef Dir) {
raw_svector_ostream OS(Buf);
for (const MCAsmMacroArgument &Arg : A) {
- if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc()))
+ if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc()))
return true;
}
@@ -6760,33 +6760,33 @@ bool MasmParser::parseDirectiveFor(SMLoc DirectiveLoc, StringRef Dir) {
return false;
}
-/// parseDirectiveForc
-/// ::= ("forc" | "irpc") symbol, <string>
-/// body
-/// endm
-bool MasmParser::parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive) {
+/// parseDirectiveForc
+/// ::= ("forc" | "irpc") symbol, <string>
+/// body
+/// endm
+bool MasmParser::parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive) {
MCAsmMacroParameter Parameter;
- std::string Argument;
+ std::string Argument;
if (check(parseIdentifier(Parameter.Name),
- "expected identifier in '" + Directive + "' directive") ||
- parseToken(AsmToken::Comma,
- "expected comma in '" + Directive + "' directive"))
+ "expected identifier in '" + Directive + "' directive") ||
+ parseToken(AsmToken::Comma,
+ "expected comma in '" + Directive + "' directive"))
return true;
- if (parseAngleBracketString(Argument)) {
- // Match ml64.exe; treat all characters to end of statement as a string,
- // ignoring comment markers, then discard anything following a space (using
- // the C locale).
- Argument = parseStringTo(AsmToken::EndOfStatement);
- if (getTok().is(AsmToken::EndOfStatement))
- Argument += getTok().getString();
- size_t End = 0;
- for (; End < Argument.size(); ++End) {
- if (isSpace(Argument[End]))
- break;
- }
- Argument.resize(End);
- }
+ if (parseAngleBracketString(Argument)) {
+ // Match ml64.exe; treat all characters to end of statement as a string,
+ // ignoring comment markers, then discard anything following a space (using
+ // the C locale).
+ Argument = parseStringTo(AsmToken::EndOfStatement);
+ if (getTok().is(AsmToken::EndOfStatement))
+ Argument += getTok().getString();
+ size_t End = 0;
+ for (; End < Argument.size(); ++End) {
+ if (isSpace(Argument[End]))
+ break;
+ }
+ Argument.resize(End);
+ }
if (parseToken(AsmToken::EndOfStatement, "expected end of statement"))
return true;
@@ -6800,12 +6800,12 @@ bool MasmParser::parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive) {
SmallString<256> Buf;
raw_svector_ostream OS(Buf);
- StringRef Values(Argument);
+ StringRef Values(Argument);
for (std::size_t I = 0, End = Values.size(); I != End; ++I) {
MCAsmMacroArgument Arg;
Arg.emplace_back(AsmToken::Identifier, Values.slice(I, I + 1));
- if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc()))
+ if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc()))
return true;
}
@@ -6847,37 +6847,37 @@ bool MasmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
return false;
}
-bool MasmParser::parseDirectiveRadix(SMLoc DirectiveLoc) {
- const SMLoc Loc = getLexer().getLoc();
- std::string RadixStringRaw = parseStringTo(AsmToken::EndOfStatement);
- StringRef RadixString = StringRef(RadixStringRaw).trim();
- unsigned Radix;
- if (RadixString.getAsInteger(10, Radix)) {
- return Error(Loc,
- "radix must be a decimal number in the range 2 to 16; was " +
- RadixString);
- }
- if (Radix < 2 || Radix > 16)
- return Error(Loc, "radix must be in the range 2 to 16; was " +
- std::to_string(Radix));
- getLexer().setMasmDefaultRadix(Radix);
- return false;
-}
-
-/// parseDirectiveEcho
-/// ::= "echo" message
+bool MasmParser::parseDirectiveRadix(SMLoc DirectiveLoc) {
+ const SMLoc Loc = getLexer().getLoc();
+ std::string RadixStringRaw = parseStringTo(AsmToken::EndOfStatement);
+ StringRef RadixString = StringRef(RadixStringRaw).trim();
+ unsigned Radix;
+ if (RadixString.getAsInteger(10, Radix)) {
+ return Error(Loc,
+ "radix must be a decimal number in the range 2 to 16; was " +
+ RadixString);
+ }
+ if (Radix < 2 || Radix > 16)
+ return Error(Loc, "radix must be in the range 2 to 16; was " +
+ std::to_string(Radix));
+ getLexer().setMasmDefaultRadix(Radix);
+ return false;
+}
+
+/// parseDirectiveEcho
+/// ::= "echo" message
bool MasmParser::parseDirectiveEcho() {
- // We're called before the directive is parsed, to avoid triggering lexical
- // substitutions in the message. Assert that the next token is the directive,
- // then eat it without using the Parser's Lex method.
- assert(getTok().is(AsmToken::Identifier) &&
- getTok().getString().equals_lower("echo"));
- Lexer.Lex();
-
- std::string Message = parseStringTo(AsmToken::EndOfStatement);
- llvm::outs() << Message;
- if (!StringRef(Message).endswith("\n"))
- llvm::outs() << '\n';
+ // We're called before the directive is parsed, to avoid triggering lexical
+ // substitutions in the message. Assert that the next token is the directive,
+ // then eat it without using the Parser's Lex method.
+ assert(getTok().is(AsmToken::Identifier) &&
+ getTok().getString().equals_lower("echo"));
+ Lexer.Lex();
+
+ std::string Message = parseStringTo(AsmToken::EndOfStatement);
+ llvm::outs() << Message;
+ if (!StringRef(Message).endswith("\n"))
+ llvm::outs() << '\n';
return false;
}
@@ -6904,52 +6904,52 @@ static int rewritesSort(const AsmRewrite *AsmRewriteA,
llvm_unreachable("Unstable rewrite sort.");
}
-bool MasmParser::defineMacro(StringRef Name, StringRef Value) {
- Variable &Var = Variables[Name.lower()];
- if (Var.Name.empty()) {
- Var.Name = Name;
- } else if (!Var.Redefinable) {
- return TokError("invalid variable redefinition");
- }
- Var.Redefinable = true;
- Var.IsText = true;
- Var.TextValue = Value.str();
- return false;
-}
-
-bool MasmParser::lookUpField(StringRef Name, AsmFieldInfo &Info) const {
+bool MasmParser::defineMacro(StringRef Name, StringRef Value) {
+ Variable &Var = Variables[Name.lower()];
+ if (Var.Name.empty()) {
+ Var.Name = Name;
+ } else if (!Var.Redefinable) {
+ return TokError("invalid variable redefinition");
+ }
+ Var.Redefinable = true;
+ Var.IsText = true;
+ Var.TextValue = Value.str();
+ return false;
+}
+
+bool MasmParser::lookUpField(StringRef Name, AsmFieldInfo &Info) const {
const std::pair<StringRef, StringRef> BaseMember = Name.split('.');
const StringRef Base = BaseMember.first, Member = BaseMember.second;
- return lookUpField(Base, Member, Info);
+ return lookUpField(Base, Member, Info);
}
-bool MasmParser::lookUpField(StringRef Base, StringRef Member,
- AsmFieldInfo &Info) const {
+bool MasmParser::lookUpField(StringRef Base, StringRef Member,
+ AsmFieldInfo &Info) const {
if (Base.empty())
return true;
- AsmFieldInfo BaseInfo;
- if (Base.contains('.') && !lookUpField(Base, BaseInfo))
- Base = BaseInfo.Type.Name;
+ AsmFieldInfo BaseInfo;
+ if (Base.contains('.') && !lookUpField(Base, BaseInfo))
+ Base = BaseInfo.Type.Name;
auto StructIt = Structs.find(Base.lower());
- auto TypeIt = KnownType.find(Base.lower());
- if (TypeIt != KnownType.end()) {
- StructIt = Structs.find(TypeIt->second.Name.lower());
- }
+ auto TypeIt = KnownType.find(Base.lower());
+ if (TypeIt != KnownType.end()) {
+ StructIt = Structs.find(TypeIt->second.Name.lower());
+ }
if (StructIt != Structs.end())
- return lookUpField(StructIt->second, Member, Info);
+ return lookUpField(StructIt->second, Member, Info);
return true;
}
bool MasmParser::lookUpField(const StructInfo &Structure, StringRef Member,
- AsmFieldInfo &Info) const {
+ AsmFieldInfo &Info) const {
if (Member.empty()) {
- Info.Type.Name = Structure.Name;
- Info.Type.Size = Structure.Size;
- Info.Type.ElementSize = Structure.Size;
- Info.Type.Length = 1;
+ Info.Type.Name = Structure.Name;
+ Info.Type.Size = Structure.Size;
+ Info.Type.ElementSize = Structure.Size;
+ Info.Type.Length = 1;
return false;
}
@@ -6958,7 +6958,7 @@ bool MasmParser::lookUpField(const StructInfo &Structure, StringRef Member,
auto StructIt = Structs.find(FieldName.lower());
if (StructIt != Structs.end())
- return lookUpField(StructIt->second, FieldMember, Info);
+ return lookUpField(StructIt->second, FieldMember, Info);
auto FieldIt = Structure.FieldsByName.find(FieldName.lower());
if (FieldIt == Structure.FieldsByName.end())
@@ -6966,14 +6966,14 @@ bool MasmParser::lookUpField(const StructInfo &Structure, StringRef Member,
const FieldInfo &Field = Structure.Fields[FieldIt->second];
if (FieldMember.empty()) {
- Info.Offset += Field.Offset;
- Info.Type.Size = Field.SizeOf;
- Info.Type.ElementSize = Field.Type;
- Info.Type.Length = Field.LengthOf;
+ Info.Offset += Field.Offset;
+ Info.Type.Size = Field.SizeOf;
+ Info.Type.ElementSize = Field.Type;
+ Info.Type.Length = Field.LengthOf;
if (Field.Contents.FT == FT_STRUCT)
- Info.Type.Name = Field.Contents.StructInfo.Structure.Name;
- else
- Info.Type.Name = "";
+ Info.Type.Name = Field.Contents.StructInfo.Structure.Name;
+ else
+ Info.Type.Name = "";
return false;
}
@@ -6981,45 +6981,45 @@ bool MasmParser::lookUpField(const StructInfo &Structure, StringRef Member,
return true;
const StructFieldInfo &StructInfo = Field.Contents.StructInfo;
- if (lookUpField(StructInfo.Structure, FieldMember, Info))
+ if (lookUpField(StructInfo.Structure, FieldMember, Info))
return true;
- Info.Offset += Field.Offset;
+ Info.Offset += Field.Offset;
return false;
}
-bool MasmParser::lookUpType(StringRef Name, AsmTypeInfo &Info) const {
- unsigned Size = StringSwitch<unsigned>(Name)
- .CasesLower("byte", "db", "sbyte", 1)
- .CasesLower("word", "dw", "sword", 2)
- .CasesLower("dword", "dd", "sdword", 4)
- .CasesLower("fword", "df", 6)
- .CasesLower("qword", "dq", "sqword", 8)
- .CaseLower("real4", 4)
- .CaseLower("real8", 8)
- .CaseLower("real10", 10)
- .Default(0);
- if (Size) {
- Info.Name = Name;
- Info.ElementSize = Size;
- Info.Length = 1;
- Info.Size = Size;
- return false;
- }
-
- auto StructIt = Structs.find(Name.lower());
- if (StructIt != Structs.end()) {
- const StructInfo &Structure = StructIt->second;
- Info.Name = Name;
- Info.ElementSize = Structure.Size;
- Info.Length = 1;
- Info.Size = Structure.Size;
- return false;
- }
-
- return true;
-}
-
+bool MasmParser::lookUpType(StringRef Name, AsmTypeInfo &Info) const {
+ unsigned Size = StringSwitch<unsigned>(Name)
+ .CasesLower("byte", "db", "sbyte", 1)
+ .CasesLower("word", "dw", "sword", 2)
+ .CasesLower("dword", "dd", "sdword", 4)
+ .CasesLower("fword", "df", 6)
+ .CasesLower("qword", "dq", "sqword", 8)
+ .CaseLower("real4", 4)
+ .CaseLower("real8", 8)
+ .CaseLower("real10", 10)
+ .Default(0);
+ if (Size) {
+ Info.Name = Name;
+ Info.ElementSize = Size;
+ Info.Length = 1;
+ Info.Size = Size;
+ return false;
+ }
+
+ auto StructIt = Structs.find(Name.lower());
+ if (StructIt != Structs.end()) {
+ const StructInfo &Structure = StructIt->second;
+ Info.Name = Name;
+ Info.ElementSize = Structure.Size;
+ Info.Length = 1;
+ Info.Size = Structure.Size;
+ return false;
+ }
+
+ return true;
+}
+
bool MasmParser::parseMSInlineAsm(
void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
@@ -7118,7 +7118,7 @@ bool MasmParser::parseMSInlineAsm(
// Consider implicit defs to be clobbers. Think of cpuid and push.
ArrayRef<MCPhysReg> ImpDefs(Desc.getImplicitDefs(),
Desc.getNumImplicitDefs());
- llvm::append_range(ClobberRegs, ImpDefs);
+ llvm::append_range(ClobberRegs, ImpDefs);
}
// Set the number of Outputs and Inputs.
diff --git a/contrib/libs/llvm12/lib/MC/MCParser/WasmAsmParser.cpp b/contrib/libs/llvm12/lib/MC/MCParser/WasmAsmParser.cpp
index d0673c2a44..0c255ef02d 100644
--- a/contrib/libs/llvm12/lib/MC/MCParser/WasmAsmParser.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCParser/WasmAsmParser.cpp
@@ -90,44 +90,44 @@ public:
return false;
}
- bool parseSectionFlags(StringRef FlagStr, bool &Passive, bool &Group) {
- for (char C : FlagStr) {
- switch (C) {
- case 'p':
+ bool parseSectionFlags(StringRef FlagStr, bool &Passive, bool &Group) {
+ for (char C : FlagStr) {
+ switch (C) {
+ case 'p':
Passive = true;
- break;
- case 'G':
- Group = true;
- break;
- default:
- return Parser->Error(getTok().getLoc(),
- StringRef("Unexepcted section flag: ") + FlagStr);
- }
+ break;
+ case 'G':
+ Group = true;
+ break;
+ default:
+ return Parser->Error(getTok().getLoc(),
+ StringRef("Unexepcted section flag: ") + FlagStr);
+ }
+ }
+ return false;
+ }
+
+ bool parseGroup(StringRef &GroupName) {
+ if (Lexer->isNot(AsmToken::Comma))
+ return TokError("expected group name");
+ Lex();
+ if (Lexer->is(AsmToken::Integer)) {
+ GroupName = getTok().getString();
+ Lex();
+ } else if (Parser->parseIdentifier(GroupName)) {
+ return TokError("invalid group name");
+ }
+ if (Lexer->is(AsmToken::Comma)) {
+ Lex();
+ StringRef Linkage;
+ if (Parser->parseIdentifier(Linkage))
+ return TokError("invalid linkage");
+ if (Linkage != "comdat")
+ return TokError("Linkage must be 'comdat'");
}
return false;
}
- bool parseGroup(StringRef &GroupName) {
- if (Lexer->isNot(AsmToken::Comma))
- return TokError("expected group name");
- Lex();
- if (Lexer->is(AsmToken::Integer)) {
- GroupName = getTok().getString();
- Lex();
- } else if (Parser->parseIdentifier(GroupName)) {
- return TokError("invalid group name");
- }
- if (Lexer->is(AsmToken::Comma)) {
- Lex();
- StringRef Linkage;
- if (Parser->parseIdentifier(Linkage))
- return TokError("invalid linkage");
- if (Linkage != "comdat")
- return TokError("Linkage must be 'comdat'");
- }
- return false;
- }
-
bool parseSectionDirective(StringRef, SMLoc) {
StringRef Name;
if (Parser->parseIdentifier(Name))
@@ -141,8 +141,8 @@ public:
auto Kind = StringSwitch<Optional<SectionKind>>(Name)
.StartsWith(".data", SectionKind::getData())
- .StartsWith(".tdata", SectionKind::getThreadData())
- .StartsWith(".tbss", SectionKind::getThreadBSS())
+ .StartsWith(".tdata", SectionKind::getThreadData())
+ .StartsWith(".tbss", SectionKind::getThreadBSS())
.StartsWith(".rodata", SectionKind::getReadOnly())
.StartsWith(".text", SectionKind::getText())
.StartsWith(".custom_section", SectionKind::getMetadata())
@@ -158,30 +158,30 @@ public:
// Update section flags if present in this .section directive
bool Passive = false;
- bool Group = false;
- if (parseSectionFlags(getTok().getStringContents(), Passive, Group))
+ bool Group = false;
+ if (parseSectionFlags(getTok().getStringContents(), Passive, Group))
+ return true;
+
+ Lex();
+
+ if (expect(AsmToken::Comma, ",") || expect(AsmToken::At, "@"))
+ return true;
+
+ StringRef GroupName;
+ if (Group && parseGroup(GroupName))
+ return true;
+
+ if (expect(AsmToken::EndOfStatement, "eol"))
return true;
- Lex();
-
- if (expect(AsmToken::Comma, ",") || expect(AsmToken::At, "@"))
- return true;
-
- StringRef GroupName;
- if (Group && parseGroup(GroupName))
- return true;
-
- if (expect(AsmToken::EndOfStatement, "eol"))
- return true;
-
- // TODO: Parse UniqueID
- MCSectionWasm *WS = getContext().getWasmSection(
- Name, Kind.getValue(), GroupName, MCContext::GenericSectionID);
+ // TODO: Parse UniqueID
+ MCSectionWasm *WS = getContext().getWasmSection(
+ Name, Kind.getValue(), GroupName, MCContext::GenericSectionID);
if (Passive) {
- if (!WS->isWasmData())
+ if (!WS->isWasmData())
return Parser->Error(getTok().getLoc(),
"Only data sections can be passive");
- WS->setPassive();
+ WS->setPassive();
}
getStreamer().SwitchSection(WS);
return false;
@@ -221,13 +221,13 @@ public:
Lexer->is(AsmToken::Identifier)))
return error("Expected label,@type declaration, got: ", Lexer->getTok());
auto TypeName = Lexer->getTok().getString();
- if (TypeName == "function") {
+ if (TypeName == "function") {
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
- auto *Current =
- cast<MCSectionWasm>(getStreamer().getCurrentSection().first);
- if (Current->getGroup())
- WasmSym->setComdat(true);
- } else if (TypeName == "global")
+ auto *Current =
+ cast<MCSectionWasm>(getStreamer().getCurrentSection().first);
+ if (Current->getGroup())
+ WasmSym->setComdat(true);
+ } else if (TypeName == "global")
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
else if (TypeName == "object")
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_DATA);
diff --git a/contrib/libs/llvm12/lib/MC/MCParser/ya.make b/contrib/libs/llvm12/lib/MC/MCParser/ya.make
index f9e468b1c9..304ad7d65a 100644
--- a/contrib/libs/llvm12/lib/MC/MCParser/ya.make
+++ b/contrib/libs/llvm12/lib/MC/MCParser/ya.make
@@ -12,9 +12,9 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/MC/MCPseudoProbe.cpp b/contrib/libs/llvm12/lib/MC/MCPseudoProbe.cpp
index 9892994dc3..731831d3bc 100644
--- a/contrib/libs/llvm12/lib/MC/MCPseudoProbe.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCPseudoProbe.cpp
@@ -1,213 +1,213 @@
-//===- lib/MC/MCPseudoProbe.cpp - Pseudo probe encoding support ----------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/MC/MCPseudoProbe.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCObjectFileInfo.h"
-#include "llvm/MC/MCObjectStreamer.h"
-#include "llvm/MC/MCStreamer.h"
-
-#define DEBUG_TYPE "mcpseudoprobe"
-
-using namespace llvm;
-
-#ifndef NDEBUG
-int MCPseudoProbeTable::DdgPrintIndent = 0;
-#endif
-
-static const MCExpr *buildSymbolDiff(MCObjectStreamer *MCOS, const MCSymbol *A,
- const MCSymbol *B) {
- MCContext &Context = MCOS->getContext();
- MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
- const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
- const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
- const MCExpr *AddrDelta =
- MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context);
- return AddrDelta;
-}
-
-void MCPseudoProbe::emit(MCObjectStreamer *MCOS,
- const MCPseudoProbe *LastProbe) const {
- // Emit Index
- MCOS->emitULEB128IntValue(Index);
- // Emit Type and the flag:
- // Type (bit 0 to 3), with bit 4 to 6 for attributes.
- // Flag (bit 7, 0 - code address, 1 - address delta). This indicates whether
- // the following field is a symbolic code address or an address delta.
- assert(Type <= 0xF && "Probe type too big to encode, exceeding 15");
- assert(Attributes <= 0x7 &&
- "Probe attributes too big to encode, exceeding 7");
- uint8_t PackedType = Type | (Attributes << 4);
- uint8_t Flag = LastProbe ? ((int8_t)MCPseudoProbeFlag::AddressDelta << 7) : 0;
- MCOS->emitInt8(Flag | PackedType);
-
- if (LastProbe) {
- // Emit the delta between the address label and LastProbe.
- const MCExpr *AddrDelta =
- buildSymbolDiff(MCOS, Label, LastProbe->getLabel());
- int64_t Delta;
- if (AddrDelta->evaluateAsAbsolute(Delta, MCOS->getAssemblerPtr())) {
- MCOS->emitSLEB128IntValue(Delta);
- } else {
- MCOS->insert(new MCPseudoProbeAddrFragment(AddrDelta));
- }
- } else {
- // Emit label as a symbolic code address.
- MCOS->emitSymbolValue(
- Label, MCOS->getContext().getAsmInfo()->getCodePointerSize());
- }
-
- LLVM_DEBUG({
- dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
- dbgs() << "Probe: " << Index << "\n";
- });
-}
-
-MCPseudoProbeInlineTree::~MCPseudoProbeInlineTree() {
- for (auto &Inlinee : Inlinees)
- delete Inlinee.second;
-}
-
-MCPseudoProbeInlineTree *
-MCPseudoProbeInlineTree::getOrAddNode(InlineSite Site) {
- auto Iter = Inlinees.find(Site);
- if (Iter == Inlinees.end()) {
- auto *Node = new MCPseudoProbeInlineTree(std::get<0>(Site));
- Inlinees[Site] = Node;
- return Node;
- } else {
- return Iter->second;
- }
-}
-
-void MCPseudoProbeInlineTree::addPseudoProbe(
- const MCPseudoProbe &Probe, const MCPseudoProbeInlineStack &InlineStack) {
- // The function should not be called on the root.
- assert(isRoot() && "Should not be called on root");
-
- // When it comes here, the input look like:
- // Probe: GUID of C, ...
- // InlineStack: [88, A], [66, B]
- // which means, Function A inlines function B at call site with a probe id of
- // 88, and B inlines C at probe 66. The tri-tree expects a tree path like {[0,
- // A], [88, B], [66, C]} to locate the tree node where the probe should be
- // added. Note that the edge [0, A] means A is the top-level function we are
- // emitting probes for.
-
- // Make a [0, A] edge.
- // An empty inline stack means the function that the probe originates from
- // is a top-level function.
- InlineSite Top;
- if (InlineStack.empty()) {
- Top = InlineSite(Probe.getGuid(), 0);
- } else {
- Top = InlineSite(std::get<0>(InlineStack.front()), 0);
- }
-
- auto *Cur = getOrAddNode(Top);
-
- // Make interior edges by walking the inline stack. Once it's done, Cur should
- // point to the node that the probe originates from.
- if (!InlineStack.empty()) {
- auto Iter = InlineStack.begin();
- auto Index = std::get<1>(*Iter);
- Iter++;
- for (; Iter != InlineStack.end(); Iter++) {
- // Make an edge by using the previous probe id and current GUID.
- Cur = Cur->getOrAddNode(InlineSite(std::get<0>(*Iter), Index));
- Index = std::get<1>(*Iter);
- }
- Cur = Cur->getOrAddNode(InlineSite(Probe.getGuid(), Index));
- }
-
- Cur->Probes.push_back(Probe);
-}
-
-void MCPseudoProbeInlineTree::emit(MCObjectStreamer *MCOS,
- const MCPseudoProbe *&LastProbe) {
- LLVM_DEBUG({
- dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
- dbgs() << "Group [\n";
- MCPseudoProbeTable::DdgPrintIndent += 2;
- });
- // Emit probes grouped by GUID.
- if (Guid != 0) {
- LLVM_DEBUG({
- dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
- dbgs() << "GUID: " << Guid << "\n";
- });
- // Emit Guid
- MCOS->emitInt64(Guid);
- // Emit number of probes in this node
- MCOS->emitULEB128IntValue(Probes.size());
- // Emit number of direct inlinees
- MCOS->emitULEB128IntValue(Inlinees.size());
- // Emit probes in this group
- for (const auto &Probe : Probes) {
- Probe.emit(MCOS, LastProbe);
- LastProbe = &Probe;
- }
- } else {
- assert(Probes.empty() && "Root should not have probes");
- }
-
- // Emit descendent
- for (const auto &Inlinee : Inlinees) {
- if (Guid) {
- // Emit probe index
- MCOS->emitULEB128IntValue(std::get<1>(Inlinee.first));
- LLVM_DEBUG({
- dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
- dbgs() << "InlineSite: " << std::get<1>(Inlinee.first) << "\n";
- });
- }
- // Emit the group
- Inlinee.second->emit(MCOS, LastProbe);
- }
-
- LLVM_DEBUG({
- MCPseudoProbeTable::DdgPrintIndent -= 2;
- dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
- dbgs() << "]\n";
- });
-}
-
-void MCPseudoProbeSection::emit(MCObjectStreamer *MCOS) {
- MCContext &Ctx = MCOS->getContext();
-
- for (auto &ProbeSec : MCProbeDivisions) {
- const MCPseudoProbe *LastProbe = nullptr;
- if (auto *S =
- Ctx.getObjectFileInfo()->getPseudoProbeSection(ProbeSec.first)) {
- // Switch to the .pseudoprobe section or a comdat group.
- MCOS->SwitchSection(S);
- // Emit probes grouped by GUID.
- ProbeSec.second.emit(MCOS, LastProbe);
- }
- }
-}
-
-//
-// This emits the pseudo probe tables.
-//
-void MCPseudoProbeTable::emit(MCObjectStreamer *MCOS) {
- MCContext &Ctx = MCOS->getContext();
- auto &ProbeTable = Ctx.getMCPseudoProbeTable();
-
- // Bail out early so we don't switch to the pseudo_probe section needlessly
- // and in doing so create an unnecessary (if empty) section.
- auto &ProbeSections = ProbeTable.getProbeSections();
- if (ProbeSections.empty())
- return;
-
- LLVM_DEBUG(MCPseudoProbeTable::DdgPrintIndent = 0);
-
- // Put out the probe.
- ProbeSections.emit(MCOS);
-}
+//===- lib/MC/MCPseudoProbe.cpp - Pseudo probe encoding support ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCPseudoProbe.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/MCStreamer.h"
+
+#define DEBUG_TYPE "mcpseudoprobe"
+
+using namespace llvm;
+
+#ifndef NDEBUG
+int MCPseudoProbeTable::DdgPrintIndent = 0;
+#endif
+
+static const MCExpr *buildSymbolDiff(MCObjectStreamer *MCOS, const MCSymbol *A,
+ const MCSymbol *B) {
+ MCContext &Context = MCOS->getContext();
+ MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
+ const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
+ const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
+ const MCExpr *AddrDelta =
+ MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context);
+ return AddrDelta;
+}
+
+void MCPseudoProbe::emit(MCObjectStreamer *MCOS,
+ const MCPseudoProbe *LastProbe) const {
+ // Emit Index
+ MCOS->emitULEB128IntValue(Index);
+ // Emit Type and the flag:
+ // Type (bit 0 to 3), with bit 4 to 6 for attributes.
+ // Flag (bit 7, 0 - code address, 1 - address delta). This indicates whether
+ // the following field is a symbolic code address or an address delta.
+ assert(Type <= 0xF && "Probe type too big to encode, exceeding 15");
+ assert(Attributes <= 0x7 &&
+ "Probe attributes too big to encode, exceeding 7");
+ uint8_t PackedType = Type | (Attributes << 4);
+ uint8_t Flag = LastProbe ? ((int8_t)MCPseudoProbeFlag::AddressDelta << 7) : 0;
+ MCOS->emitInt8(Flag | PackedType);
+
+ if (LastProbe) {
+ // Emit the delta between the address label and LastProbe.
+ const MCExpr *AddrDelta =
+ buildSymbolDiff(MCOS, Label, LastProbe->getLabel());
+ int64_t Delta;
+ if (AddrDelta->evaluateAsAbsolute(Delta, MCOS->getAssemblerPtr())) {
+ MCOS->emitSLEB128IntValue(Delta);
+ } else {
+ MCOS->insert(new MCPseudoProbeAddrFragment(AddrDelta));
+ }
+ } else {
+ // Emit label as a symbolic code address.
+ MCOS->emitSymbolValue(
+ Label, MCOS->getContext().getAsmInfo()->getCodePointerSize());
+ }
+
+ LLVM_DEBUG({
+ dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
+ dbgs() << "Probe: " << Index << "\n";
+ });
+}
+
+MCPseudoProbeInlineTree::~MCPseudoProbeInlineTree() {
+ for (auto &Inlinee : Inlinees)
+ delete Inlinee.second;
+}
+
+MCPseudoProbeInlineTree *
+MCPseudoProbeInlineTree::getOrAddNode(InlineSite Site) {
+ auto Iter = Inlinees.find(Site);
+ if (Iter == Inlinees.end()) {
+ auto *Node = new MCPseudoProbeInlineTree(std::get<0>(Site));
+ Inlinees[Site] = Node;
+ return Node;
+ } else {
+ return Iter->second;
+ }
+}
+
+void MCPseudoProbeInlineTree::addPseudoProbe(
+ const MCPseudoProbe &Probe, const MCPseudoProbeInlineStack &InlineStack) {
+ // The function should not be called on the root.
+ assert(isRoot() && "Should not be called on root");
+
+ // When it comes here, the input look like:
+ // Probe: GUID of C, ...
+ // InlineStack: [88, A], [66, B]
+ // which means, Function A inlines function B at call site with a probe id of
+ // 88, and B inlines C at probe 66. The tri-tree expects a tree path like {[0,
+ // A], [88, B], [66, C]} to locate the tree node where the probe should be
+ // added. Note that the edge [0, A] means A is the top-level function we are
+ // emitting probes for.
+
+ // Make a [0, A] edge.
+ // An empty inline stack means the function that the probe originates from
+ // is a top-level function.
+ InlineSite Top;
+ if (InlineStack.empty()) {
+ Top = InlineSite(Probe.getGuid(), 0);
+ } else {
+ Top = InlineSite(std::get<0>(InlineStack.front()), 0);
+ }
+
+ auto *Cur = getOrAddNode(Top);
+
+ // Make interior edges by walking the inline stack. Once it's done, Cur should
+ // point to the node that the probe originates from.
+ if (!InlineStack.empty()) {
+ auto Iter = InlineStack.begin();
+ auto Index = std::get<1>(*Iter);
+ Iter++;
+ for (; Iter != InlineStack.end(); Iter++) {
+ // Make an edge by using the previous probe id and current GUID.
+ Cur = Cur->getOrAddNode(InlineSite(std::get<0>(*Iter), Index));
+ Index = std::get<1>(*Iter);
+ }
+ Cur = Cur->getOrAddNode(InlineSite(Probe.getGuid(), Index));
+ }
+
+ Cur->Probes.push_back(Probe);
+}
+
+void MCPseudoProbeInlineTree::emit(MCObjectStreamer *MCOS,
+ const MCPseudoProbe *&LastProbe) {
+ LLVM_DEBUG({
+ dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
+ dbgs() << "Group [\n";
+ MCPseudoProbeTable::DdgPrintIndent += 2;
+ });
+ // Emit probes grouped by GUID.
+ if (Guid != 0) {
+ LLVM_DEBUG({
+ dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
+ dbgs() << "GUID: " << Guid << "\n";
+ });
+ // Emit Guid
+ MCOS->emitInt64(Guid);
+ // Emit number of probes in this node
+ MCOS->emitULEB128IntValue(Probes.size());
+ // Emit number of direct inlinees
+ MCOS->emitULEB128IntValue(Inlinees.size());
+ // Emit probes in this group
+ for (const auto &Probe : Probes) {
+ Probe.emit(MCOS, LastProbe);
+ LastProbe = &Probe;
+ }
+ } else {
+ assert(Probes.empty() && "Root should not have probes");
+ }
+
+ // Emit descendent
+ for (const auto &Inlinee : Inlinees) {
+ if (Guid) {
+ // Emit probe index
+ MCOS->emitULEB128IntValue(std::get<1>(Inlinee.first));
+ LLVM_DEBUG({
+ dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
+ dbgs() << "InlineSite: " << std::get<1>(Inlinee.first) << "\n";
+ });
+ }
+ // Emit the group
+ Inlinee.second->emit(MCOS, LastProbe);
+ }
+
+ LLVM_DEBUG({
+ MCPseudoProbeTable::DdgPrintIndent -= 2;
+ dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
+ dbgs() << "]\n";
+ });
+}
+
+void MCPseudoProbeSection::emit(MCObjectStreamer *MCOS) {
+ MCContext &Ctx = MCOS->getContext();
+
+ for (auto &ProbeSec : MCProbeDivisions) {
+ const MCPseudoProbe *LastProbe = nullptr;
+ if (auto *S =
+ Ctx.getObjectFileInfo()->getPseudoProbeSection(ProbeSec.first)) {
+ // Switch to the .pseudoprobe section or a comdat group.
+ MCOS->SwitchSection(S);
+ // Emit probes grouped by GUID.
+ ProbeSec.second.emit(MCOS, LastProbe);
+ }
+ }
+}
+
+//
+// This emits the pseudo probe tables.
+//
+void MCPseudoProbeTable::emit(MCObjectStreamer *MCOS) {
+ MCContext &Ctx = MCOS->getContext();
+ auto &ProbeTable = Ctx.getMCPseudoProbeTable();
+
+ // Bail out early so we don't switch to the pseudo_probe section needlessly
+ // and in doing so create an unnecessary (if empty) section.
+ auto &ProbeSections = ProbeTable.getProbeSections();
+ if (ProbeSections.empty())
+ return;
+
+ LLVM_DEBUG(MCPseudoProbeTable::DdgPrintIndent = 0);
+
+ // Put out the probe.
+ ProbeSections.emit(MCOS);
+}
diff --git a/contrib/libs/llvm12/lib/MC/MCSchedule.cpp b/contrib/libs/llvm12/lib/MC/MCSchedule.cpp
index cf768b0fe1..db08e20441 100644
--- a/contrib/libs/llvm12/lib/MC/MCSchedule.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCSchedule.cpp
@@ -74,7 +74,7 @@ int MCSchedModel::computeInstrLatency(const MCSubtargetInfo &STI,
unsigned CPUID = getProcessorID();
while (SCDesc->isVariant()) {
- SchedClass = STI.resolveVariantSchedClass(SchedClass, &Inst, &MCII, CPUID);
+ SchedClass = STI.resolveVariantSchedClass(SchedClass, &Inst, &MCII, CPUID);
SCDesc = getSchedClassDesc(SchedClass);
}
@@ -120,7 +120,7 @@ MCSchedModel::getReciprocalThroughput(const MCSubtargetInfo &STI,
unsigned CPUID = getProcessorID();
while (SCDesc->isVariant()) {
- SchedClass = STI.resolveVariantSchedClass(SchedClass, &Inst, &MCII, CPUID);
+ SchedClass = STI.resolveVariantSchedClass(SchedClass, &Inst, &MCII, CPUID);
SCDesc = getSchedClassDesc(SchedClass);
}
diff --git a/contrib/libs/llvm12/lib/MC/MCSection.cpp b/contrib/libs/llvm12/lib/MC/MCSection.cpp
index c64af2bc0a..7997b237a7 100644
--- a/contrib/libs/llvm12/lib/MC/MCSection.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCSection.cpp
@@ -28,7 +28,7 @@ MCSection::MCSection(SectionVariant V, StringRef Name, SectionKind K,
MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) {
if (!End)
- End = Ctx.createTempSymbol("sec_end");
+ End = Ctx.createTempSymbol("sec_end");
return End;
}
@@ -82,7 +82,7 @@ MCSection::getSubsectionInsertionPoint(unsigned Subsection) {
SubsectionFragmentMap.insert(MI, std::make_pair(Subsection, F));
getFragmentList().insert(IP, F);
F->setParent(this);
- F->setSubsectionNumber(Subsection);
+ F->setSubsectionNumber(Subsection);
}
return IP;
diff --git a/contrib/libs/llvm12/lib/MC/MCSectionELF.cpp b/contrib/libs/llvm12/lib/MC/MCSectionELF.cpp
index b51be9dcaa..27694cb144 100644
--- a/contrib/libs/llvm12/lib/MC/MCSectionELF.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCSectionELF.cpp
@@ -156,8 +156,8 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
OS << "llvm_dependent_libraries";
else if (Type == ELF::SHT_LLVM_SYMPART)
OS << "llvm_sympart";
- else if (Type == ELF::SHT_LLVM_BB_ADDR_MAP)
- OS << "llvm_bb_addr_map";
+ else if (Type == ELF::SHT_LLVM_BB_ADDR_MAP)
+ OS << "llvm_bb_addr_map";
else
report_fatal_error("unsupported type 0x" + Twine::utohexstr(Type) +
" for section " + getName());
@@ -175,10 +175,10 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
if (Flags & ELF::SHF_LINK_ORDER) {
OS << ",";
- if (LinkedToSym)
- printName(OS, LinkedToSym->getName());
- else
- OS << '0';
+ if (LinkedToSym)
+ printName(OS, LinkedToSym->getName());
+ else
+ OS << '0';
}
if (isUnique())
diff --git a/contrib/libs/llvm12/lib/MC/MCSectionMachO.cpp b/contrib/libs/llvm12/lib/MC/MCSectionMachO.cpp
index a54968d7b4..794d2c52d7 100644
--- a/contrib/libs/llvm12/lib/MC/MCSectionMachO.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCSectionMachO.cpp
@@ -215,11 +215,11 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In.
return "";
// Figure out which section type it is.
- auto TypeDescriptor =
- llvm::find_if(SectionTypeDescriptors,
- [&](decltype(*SectionTypeDescriptors) &Descriptor) {
- return SectionType == Descriptor.AssemblerName;
- });
+ auto TypeDescriptor =
+ llvm::find_if(SectionTypeDescriptors,
+ [&](decltype(*SectionTypeDescriptors) &Descriptor) {
+ return SectionType == Descriptor.AssemblerName;
+ });
// If we didn't find the section type, reject it.
if (TypeDescriptor == std::end(SectionTypeDescriptors))
@@ -243,11 +243,11 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In.
Attrs.split(SectionAttrs, '+', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
for (StringRef &SectionAttr : SectionAttrs) {
- auto AttrDescriptorI =
- llvm::find_if(SectionAttrDescriptors,
- [&](decltype(*SectionAttrDescriptors) &Descriptor) {
- return SectionAttr.trim() == Descriptor.AssemblerName;
- });
+ auto AttrDescriptorI =
+ llvm::find_if(SectionAttrDescriptors,
+ [&](decltype(*SectionAttrDescriptors) &Descriptor) {
+ return SectionAttr.trim() == Descriptor.AssemblerName;
+ });
if (AttrDescriptorI == std::end(SectionAttrDescriptors))
return "mach-o section specifier has invalid attribute";
diff --git a/contrib/libs/llvm12/lib/MC/MCSectionWasm.cpp b/contrib/libs/llvm12/lib/MC/MCSectionWasm.cpp
index ce9e1b19cf..81dc4329be 100644
--- a/contrib/libs/llvm12/lib/MC/MCSectionWasm.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCSectionWasm.cpp
@@ -64,9 +64,9 @@ void MCSectionWasm::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
OS << ",\"";
if (IsPassive)
- OS << "p";
- if (Group)
- OS << "G";
+ OS << "p";
+ if (Group)
+ OS << "G";
OS << '"';
@@ -80,12 +80,12 @@ void MCSectionWasm::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
// TODO: Print section type.
- if (Group) {
- OS << ",";
- printName(OS, Group->getName());
- OS << ",comdat";
- }
-
+ if (Group) {
+ OS << ",";
+ printName(OS, Group->getName());
+ OS << ",comdat";
+ }
+
if (isUnique())
OS << ",unique," << UniqueID;
diff --git a/contrib/libs/llvm12/lib/MC/MCSectionXCOFF.cpp b/contrib/libs/llvm12/lib/MC/MCSectionXCOFF.cpp
index 6a036ae884..17b7b60a04 100644
--- a/contrib/libs/llvm12/lib/MC/MCSectionXCOFF.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCSectionXCOFF.cpp
@@ -45,7 +45,7 @@ void MCSectionXCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
printCsectDirective(OS);
break;
case XCOFF::XMC_TC:
- case XCOFF::XMC_TE:
+ case XCOFF::XMC_TE:
break;
case XCOFF::XMC_TC0:
OS << "\t.toc\n";
diff --git a/contrib/libs/llvm12/lib/MC/MCStreamer.cpp b/contrib/libs/llvm12/lib/MC/MCStreamer.cpp
index 50d3fc3c28..4b5ae3cc20 100644
--- a/contrib/libs/llvm12/lib/MC/MCStreamer.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCStreamer.cpp
@@ -22,7 +22,7 @@
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCObjectFileInfo.h"
-#include "llvm/MC/MCPseudoProbe.h"
+#include "llvm/MC/MCPseudoProbe.h"
#include "llvm/MC/MCRegister.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSection.h"
@@ -91,7 +91,7 @@ void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
MCStreamer::MCStreamer(MCContext &Ctx)
: Context(Ctx), CurrentWinFrameInfo(nullptr),
- CurrentProcWinFrameInfoStartIndex(0), UseAssemblerInfoForParsing(false) {
+ CurrentProcWinFrameInfoStartIndex(0), UseAssemblerInfoForParsing(false) {
SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
}
@@ -139,22 +139,22 @@ void MCStreamer::emitIntValue(uint64_t Value, unsigned Size) {
unsigned Index = IsLittleEndian ? 0 : 8 - Size;
emitBytes(StringRef(reinterpret_cast<char *>(&Swapped) + Index, Size));
}
-void MCStreamer::emitIntValue(APInt Value) {
- if (Value.getNumWords() == 1) {
- emitIntValue(Value.getLimitedValue(), Value.getBitWidth() / 8);
- return;
- }
-
- const bool IsLittleEndianTarget = Context.getAsmInfo()->isLittleEndian();
- const bool ShouldSwap = sys::IsLittleEndianHost != IsLittleEndianTarget;
- const APInt Swapped = ShouldSwap ? Value.byteSwap() : Value;
- const unsigned Size = Value.getBitWidth() / 8;
- SmallString<10> Tmp;
- Tmp.resize(Size);
- StoreIntToMemory(Swapped, reinterpret_cast<uint8_t *>(Tmp.data()), Size);
- emitBytes(Tmp.str());
-}
-
+void MCStreamer::emitIntValue(APInt Value) {
+ if (Value.getNumWords() == 1) {
+ emitIntValue(Value.getLimitedValue(), Value.getBitWidth() / 8);
+ return;
+ }
+
+ const bool IsLittleEndianTarget = Context.getAsmInfo()->isLittleEndian();
+ const bool ShouldSwap = sys::IsLittleEndianHost != IsLittleEndianTarget;
+ const APInt Swapped = ShouldSwap ? Value.byteSwap() : Value;
+ const unsigned Size = Value.getBitWidth() / 8;
+ SmallString<10> Tmp;
+ Tmp.resize(Size);
+ StoreIntToMemory(Swapped, reinterpret_cast<uint8_t *>(Tmp.data()), Size);
+ emitBytes(Tmp.str());
+}
+
/// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
/// client having to pass in a MCExpr for constant integers.
void MCStreamer::emitULEB128IntValue(uint64_t Value, unsigned PadTo) {
@@ -218,9 +218,9 @@ void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
emitFill(*MCConstantExpr::create(NumBytes, getContext()), FillValue);
}
-void llvm::MCStreamer::emitNops(int64_t NumBytes, int64_t ControlledNopLen,
- llvm::SMLoc) {}
-
+void llvm::MCStreamer::emitNops(int64_t NumBytes, int64_t ControlledNopLen,
+ llvm::SMLoc) {}
+
/// The implementation in this class just redirects to emitFill.
void MCStreamer::emitZeros(uint64_t NumBytes) { emitFill(NumBytes, 0); }
@@ -274,9 +274,9 @@ bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
if (!hasUnfinishedDwarfFrameInfo()) {
- getContext().reportError(getStartTokLoc(),
- "this directive must appear between "
- ".cfi_startproc and .cfi_endproc directives");
+ getContext().reportError(getStartTokLoc(),
+ "this directive must appear between "
+ ".cfi_startproc and .cfi_endproc directives");
return nullptr;
}
return &DwarfFrameInfos.back();
@@ -693,7 +693,7 @@ void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
MCSymbol *StartProc = emitCFILabel();
- CurrentProcWinFrameInfoStartIndex = WinFrameInfos.size();
+ CurrentProcWinFrameInfoStartIndex = WinFrameInfos.size();
WinFrameInfos.emplace_back(
std::make_unique<WinEH::FrameInfo>(Symbol, StartProc));
CurrentWinFrameInfo = WinFrameInfos.back().get();
@@ -709,13 +709,13 @@ void MCStreamer::EmitWinCFIEndProc(SMLoc Loc) {
MCSymbol *Label = emitCFILabel();
CurFrame->End = Label;
- if (!CurFrame->FuncletOrFuncEnd)
- CurFrame->FuncletOrFuncEnd = CurFrame->End;
-
- for (size_t I = CurrentProcWinFrameInfoStartIndex, E = WinFrameInfos.size();
- I != E; ++I)
- EmitWindowsUnwindTables(WinFrameInfos[I].get());
- SwitchSection(CurFrame->TextSection);
+ if (!CurFrame->FuncletOrFuncEnd)
+ CurFrame->FuncletOrFuncEnd = CurFrame->End;
+
+ for (size_t I = CurrentProcWinFrameInfoStartIndex, E = WinFrameInfos.size();
+ I != E; ++I)
+ EmitWindowsUnwindTables(WinFrameInfos[I].get());
+ SwitchSection(CurFrame->TextSection);
}
void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
@@ -974,13 +974,13 @@ void MCStreamer::emitRawText(const Twine &T) {
void MCStreamer::EmitWindowsUnwindTables() {
}
-void MCStreamer::EmitWindowsUnwindTables(WinEH::FrameInfo *Frame) {
-}
-
-void MCStreamer::Finish(SMLoc EndLoc) {
+void MCStreamer::EmitWindowsUnwindTables(WinEH::FrameInfo *Frame) {
+}
+
+void MCStreamer::Finish(SMLoc EndLoc) {
if ((!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End) ||
(!WinFrameInfos.empty() && !WinFrameInfos.back()->End)) {
- getContext().reportError(EndLoc, "Unfinished frame!");
+ getContext().reportError(EndLoc, "Unfinished frame!");
return;
}
@@ -1043,25 +1043,25 @@ void MCStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &) {
visitUsedExpr(*Inst.getOperand(i).getExpr());
}
-void MCStreamer::emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type,
- uint64_t Attr,
- const MCPseudoProbeInlineStack &InlineStack) {
- auto &Context = getContext();
-
- // Create a symbol at in the current section for use in the probe.
- MCSymbol *ProbeSym = Context.createTempSymbol();
-
- // Set the value of the symbol to use for the MCPseudoProbe.
- emitLabel(ProbeSym);
-
- // Create a (local) probe entry with the symbol.
- MCPseudoProbe Probe(ProbeSym, Guid, Index, Type, Attr);
-
- // Add the probe entry to this section's entries.
- Context.getMCPseudoProbeTable().getProbeSections().addPseudoProbe(
- getCurrentSectionOnly(), Probe, InlineStack);
-}
-
+void MCStreamer::emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type,
+ uint64_t Attr,
+ const MCPseudoProbeInlineStack &InlineStack) {
+ auto &Context = getContext();
+
+ // Create a symbol at in the current section for use in the probe.
+ MCSymbol *ProbeSym = Context.createTempSymbol();
+
+ // Set the value of the symbol to use for the MCPseudoProbe.
+ emitLabel(ProbeSym);
+
+ // Create a (local) probe entry with the symbol.
+ MCPseudoProbe Probe(ProbeSym, Guid, Index, Type, Attr);
+
+ // Add the probe entry to this section's entries.
+ Context.getMCPseudoProbeTable().getProbeSections().addPseudoProbe(
+ getCurrentSectionOnly(), Probe, InlineStack);
+}
+
void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
unsigned Size) {
// Get the Hi-Lo expression.
@@ -1076,7 +1076,7 @@ void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
}
// Otherwise, emit with .set (aka assignment).
- MCSymbol *SetLabel = Context.createTempSymbol("set");
+ MCSymbol *SetLabel = Context.createTempSymbol("set");
emitAssignment(SetLabel, Diff);
emitSymbolValue(SetLabel, Size);
}
diff --git a/contrib/libs/llvm12/lib/MC/MCSubtargetInfo.cpp b/contrib/libs/llvm12/lib/MC/MCSubtargetInfo.cpp
index 18bace3057..55ada91857 100644
--- a/contrib/libs/llvm12/lib/MC/MCSubtargetInfo.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCSubtargetInfo.cpp
@@ -147,7 +147,7 @@ static void cpuHelp(ArrayRef<SubtargetSubTypeKV> CPUTable) {
PrintOnce = true;
}
-static FeatureBitset getFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS,
+static FeatureBitset getFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS,
ArrayRef<SubtargetSubTypeKV> ProcDesc,
ArrayRef<SubtargetFeatureKV> ProcFeatures) {
SubtargetFeatures Features(FS);
@@ -178,19 +178,19 @@ static FeatureBitset getFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS,
}
}
- if (!TuneCPU.empty()) {
- const SubtargetSubTypeKV *CPUEntry = Find(TuneCPU, ProcDesc);
-
- // If there is a match
- if (CPUEntry) {
- // Set the features implied by this CPU feature, if any.
- SetImpliedBits(Bits, CPUEntry->TuneImplies.getAsBitset(), ProcFeatures);
- } else if (TuneCPU != CPU) {
- errs() << "'" << TuneCPU << "' is not a recognized processor for this "
- << "target (ignoring processor)\n";
- }
- }
-
+ if (!TuneCPU.empty()) {
+ const SubtargetSubTypeKV *CPUEntry = Find(TuneCPU, ProcDesc);
+
+ // If there is a match
+ if (CPUEntry) {
+ // Set the features implied by this CPU feature, if any.
+ SetImpliedBits(Bits, CPUEntry->TuneImplies.getAsBitset(), ProcFeatures);
+ } else if (TuneCPU != CPU) {
+ errs() << "'" << TuneCPU << "' is not a recognized processor for this "
+ << "target (ignoring processor)\n";
+ }
+ }
+
// Iterate through each feature
for (const std::string &Feature : Features.getFeatures()) {
// Check for help
@@ -205,33 +205,33 @@ static FeatureBitset getFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS,
return Bits;
}
-void MCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef TuneCPU,
- StringRef FS) {
- FeatureBits = getFeatures(CPU, TuneCPU, FS, ProcDesc, ProcFeatures);
- if (!TuneCPU.empty())
- CPUSchedModel = &getSchedModelForCPU(TuneCPU);
+void MCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef TuneCPU,
+ StringRef FS) {
+ FeatureBits = getFeatures(CPU, TuneCPU, FS, ProcDesc, ProcFeatures);
+ if (!TuneCPU.empty())
+ CPUSchedModel = &getSchedModelForCPU(TuneCPU);
else
CPUSchedModel = &MCSchedModel::GetDefaultSchedModel();
}
-void MCSubtargetInfo::setDefaultFeatures(StringRef CPU, StringRef TuneCPU,
- StringRef FS) {
- FeatureBits = getFeatures(CPU, TuneCPU, FS, ProcDesc, ProcFeatures);
+void MCSubtargetInfo::setDefaultFeatures(StringRef CPU, StringRef TuneCPU,
+ StringRef FS) {
+ FeatureBits = getFeatures(CPU, TuneCPU, FS, ProcDesc, ProcFeatures);
}
-MCSubtargetInfo::MCSubtargetInfo(const Triple &TT, StringRef C, StringRef TC,
- StringRef FS, ArrayRef<SubtargetFeatureKV> PF,
+MCSubtargetInfo::MCSubtargetInfo(const Triple &TT, StringRef C, StringRef TC,
+ StringRef FS, ArrayRef<SubtargetFeatureKV> PF,
ArrayRef<SubtargetSubTypeKV> PD,
const MCWriteProcResEntry *WPR,
const MCWriteLatencyEntry *WL,
const MCReadAdvanceEntry *RA,
const InstrStage *IS, const unsigned *OC,
const unsigned *FP)
- : TargetTriple(TT), CPU(std::string(C)), TuneCPU(std::string(TC)),
- ProcFeatures(PF), ProcDesc(PD), WriteProcResTable(WPR),
- WriteLatencyTable(WL), ReadAdvanceTable(RA), Stages(IS),
- OperandCycles(OC), ForwardingPaths(FP) {
- InitMCProcessorInfo(CPU, TuneCPU, FS);
+ : TargetTriple(TT), CPU(std::string(C)), TuneCPU(std::string(TC)),
+ ProcFeatures(PF), ProcDesc(PD), WriteProcResTable(WPR),
+ WriteLatencyTable(WL), ReadAdvanceTable(RA), Stages(IS),
+ OperandCycles(OC), ForwardingPaths(FP) {
+ InitMCProcessorInfo(CPU, TuneCPU, FS);
}
FeatureBitset MCSubtargetInfo::ToggleFeature(uint64_t FB) {
diff --git a/contrib/libs/llvm12/lib/MC/MCSymbolXCOFF.cpp b/contrib/libs/llvm12/lib/MC/MCSymbolXCOFF.cpp
index 3f53ebfb26..b9dd2908b4 100644
--- a/contrib/libs/llvm12/lib/MC/MCSymbolXCOFF.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCSymbolXCOFF.cpp
@@ -13,7 +13,7 @@ using namespace llvm;
MCSectionXCOFF *MCSymbolXCOFF::getRepresentedCsect() const {
assert(RepresentedCsect &&
"Trying to get csect representation of this symbol but none was set.");
- assert(!getName().equals(getUnqualifiedName()) &&
+ assert(!getName().equals(getUnqualifiedName()) &&
"Symbol does not represent a csect; MCSectionXCOFF that represents "
"the symbol should not be (but is) set.");
assert(getSymbolTableName().equals(RepresentedCsect->getSymbolTableName()) &&
@@ -25,9 +25,9 @@ MCSectionXCOFF *MCSymbolXCOFF::getRepresentedCsect() const {
void MCSymbolXCOFF::setRepresentedCsect(MCSectionXCOFF *C) {
assert(C && "Assigned csect should not be null.");
assert((!RepresentedCsect || RepresentedCsect == C) &&
- "Trying to set a csect that doesn't match the one that this symbol is "
- "already mapped to.");
- assert(!getName().equals(getUnqualifiedName()) &&
+ "Trying to set a csect that doesn't match the one that this symbol is "
+ "already mapped to.");
+ assert(!getName().equals(getUnqualifiedName()) &&
"Symbol does not represent a csect; can only set a MCSectionXCOFF "
"representation for a csect.");
assert(getSymbolTableName().equals(C->getSymbolTableName()) &&
diff --git a/contrib/libs/llvm12/lib/MC/MCWin64EH.cpp b/contrib/libs/llvm12/lib/MC/MCWin64EH.cpp
index d1f6dca06c..de1b0fd3c7 100644
--- a/contrib/libs/llvm12/lib/MC/MCWin64EH.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCWin64EH.cpp
@@ -238,9 +238,9 @@ void llvm::Win64EH::UnwindEmitter::Emit(MCStreamer &Streamer) const {
}
}
-void llvm::Win64EH::UnwindEmitter::EmitUnwindInfo(MCStreamer &Streamer,
- WinEH::FrameInfo *info,
- bool HandlerData) const {
+void llvm::Win64EH::UnwindEmitter::EmitUnwindInfo(MCStreamer &Streamer,
+ WinEH::FrameInfo *info,
+ bool HandlerData) const {
// Switch sections (the static function above is meant to be called from
// here and from Emit().
MCSection *XData = Streamer.getAssociatedXDataSection(info->TextSection);
@@ -265,7 +265,7 @@ static int64_t GetAbsDifference(MCStreamer &Streamer, const MCSymbol *LHS,
return value;
}
-static uint32_t ARM64CountOfUnwindCodes(ArrayRef<WinEH::Instruction> Insns) {
+static uint32_t ARM64CountOfUnwindCodes(ArrayRef<WinEH::Instruction> Insns) {
uint32_t Count = 0;
for (const auto &I : Insns) {
switch (static_cast<Win64EH::UnwindOpcodes>(I.Operation)) {
@@ -280,9 +280,9 @@ static uint32_t ARM64CountOfUnwindCodes(ArrayRef<WinEH::Instruction> Insns) {
case Win64EH::UOP_AllocLarge:
Count += 4;
break;
- case Win64EH::UOP_SaveR19R20X:
- Count += 1;
- break;
+ case Win64EH::UOP_SaveR19R20X:
+ Count += 1;
+ break;
case Win64EH::UOP_SaveFPLRX:
Count += 1;
break;
@@ -301,9 +301,9 @@ static uint32_t ARM64CountOfUnwindCodes(ArrayRef<WinEH::Instruction> Insns) {
case Win64EH::UOP_SaveRegX:
Count += 2;
break;
- case Win64EH::UOP_SaveLRPair:
- Count += 2;
- break;
+ case Win64EH::UOP_SaveLRPair:
+ Count += 2;
+ break;
case Win64EH::UOP_SaveFReg:
Count += 2;
break;
@@ -328,21 +328,21 @@ static uint32_t ARM64CountOfUnwindCodes(ArrayRef<WinEH::Instruction> Insns) {
case Win64EH::UOP_End:
Count += 1;
break;
- case Win64EH::UOP_SaveNext:
- Count += 1;
- break;
- case Win64EH::UOP_TrapFrame:
- Count += 1;
- break;
- case Win64EH::UOP_PushMachFrame:
- Count += 1;
- break;
- case Win64EH::UOP_Context:
- Count += 1;
- break;
- case Win64EH::UOP_ClearUnwoundToCall:
- Count += 1;
- break;
+ case Win64EH::UOP_SaveNext:
+ Count += 1;
+ break;
+ case Win64EH::UOP_TrapFrame:
+ Count += 1;
+ break;
+ case Win64EH::UOP_PushMachFrame:
+ Count += 1;
+ break;
+ case Win64EH::UOP_Context:
+ Count += 1;
+ break;
+ case Win64EH::UOP_ClearUnwoundToCall:
+ Count += 1;
+ break;
}
}
return Count;
@@ -396,11 +396,11 @@ static void ARM64EmitUnwindCode(MCStreamer &streamer, const MCSymbol *begin,
b = 0xE3;
streamer.emitInt8(b);
break;
- case Win64EH::UOP_SaveR19R20X:
- b = 0x20;
- b |= (inst.Offset >> 3) & 0x1F;
- streamer.emitInt8(b);
- break;
+ case Win64EH::UOP_SaveR19R20X:
+ b = 0x20;
+ b |= (inst.Offset >> 3) & 0x1F;
+ streamer.emitInt8(b);
+ break;
case Win64EH::UOP_SaveFPLRX:
b = 0x80;
b |= ((inst.Offset - 1) >> 3) & 0x3F;
@@ -443,16 +443,16 @@ static void ARM64EmitUnwindCode(MCStreamer &streamer, const MCSymbol *begin,
b = ((reg & 0x3) << 6) | ((inst.Offset >> 3) - 1);
streamer.emitInt8(b);
break;
- case Win64EH::UOP_SaveLRPair:
- assert(inst.Register >= 19 && "Saved reg must be >= 19");
- reg = inst.Register - 19;
- assert((reg % 2) == 0 && "Saved reg must be 19+2*X");
- reg /= 2;
- b = 0xD6 | ((reg & 0x7) >> 2);
- streamer.emitInt8(b);
- b = ((reg & 0x3) << 6) | (inst.Offset >> 3);
- streamer.emitInt8(b);
- break;
+ case Win64EH::UOP_SaveLRPair:
+ assert(inst.Register >= 19 && "Saved reg must be >= 19");
+ reg = inst.Register - 19;
+ assert((reg % 2) == 0 && "Saved reg must be 19+2*X");
+ reg /= 2;
+ b = 0xD6 | ((reg & 0x7) >> 2);
+ streamer.emitInt8(b);
+ b = ((reg & 0x3) << 6) | (inst.Offset >> 3);
+ streamer.emitInt8(b);
+ break;
case Win64EH::UOP_SaveFReg:
assert(inst.Register >= 8 && "Saved dreg must be >= 8");
reg = inst.Register - 8;
@@ -489,26 +489,26 @@ static void ARM64EmitUnwindCode(MCStreamer &streamer, const MCSymbol *begin,
b = 0xE4;
streamer.emitInt8(b);
break;
- case Win64EH::UOP_SaveNext:
- b = 0xE6;
- streamer.emitInt8(b);
- break;
- case Win64EH::UOP_TrapFrame:
- b = 0xE8;
- streamer.emitInt8(b);
- break;
- case Win64EH::UOP_PushMachFrame:
- b = 0xE9;
- streamer.emitInt8(b);
- break;
- case Win64EH::UOP_Context:
- b = 0xEA;
- streamer.emitInt8(b);
- break;
- case Win64EH::UOP_ClearUnwoundToCall:
- b = 0xEC;
- streamer.emitInt8(b);
- break;
+ case Win64EH::UOP_SaveNext:
+ b = 0xE6;
+ streamer.emitInt8(b);
+ break;
+ case Win64EH::UOP_TrapFrame:
+ b = 0xE8;
+ streamer.emitInt8(b);
+ break;
+ case Win64EH::UOP_PushMachFrame:
+ b = 0xE9;
+ streamer.emitInt8(b);
+ break;
+ case Win64EH::UOP_Context:
+ b = 0xEA;
+ streamer.emitInt8(b);
+ break;
+ case Win64EH::UOP_ClearUnwoundToCall:
+ b = 0xEC;
+ streamer.emitInt8(b);
+ break;
}
}
@@ -544,367 +544,367 @@ FindMatchingEpilog(const std::vector<WinEH::Instruction>& EpilogInstrs,
return nullptr;
}
-static void simplifyOpcodes(std::vector<WinEH::Instruction> &Instructions,
- bool Reverse) {
- unsigned PrevOffset = -1;
- unsigned PrevRegister = -1;
-
- auto VisitInstruction = [&](WinEH::Instruction &Inst) {
- // Convert 2-byte opcodes into equivalent 1-byte ones.
- if (Inst.Operation == Win64EH::UOP_SaveRegP && Inst.Register == 29) {
- Inst.Operation = Win64EH::UOP_SaveFPLR;
- Inst.Register = -1;
- } else if (Inst.Operation == Win64EH::UOP_SaveRegPX &&
- Inst.Register == 29) {
- Inst.Operation = Win64EH::UOP_SaveFPLRX;
- Inst.Register = -1;
- } else if (Inst.Operation == Win64EH::UOP_SaveRegPX &&
- Inst.Register == 19 && Inst.Offset <= 248) {
- Inst.Operation = Win64EH::UOP_SaveR19R20X;
- Inst.Register = -1;
- } else if (Inst.Operation == Win64EH::UOP_AddFP && Inst.Offset == 0) {
- Inst.Operation = Win64EH::UOP_SetFP;
- } else if (Inst.Operation == Win64EH::UOP_SaveRegP &&
- Inst.Register == PrevRegister + 2 &&
- Inst.Offset == PrevOffset + 16) {
- Inst.Operation = Win64EH::UOP_SaveNext;
- Inst.Register = -1;
- Inst.Offset = 0;
- // Intentionally not creating UOP_SaveNext for float register pairs,
- // as current versions of Windows (up to at least 20.04) is buggy
- // regarding SaveNext for float pairs.
- }
- // Update info about the previous instruction, for detecting if
- // the next one can be made a UOP_SaveNext
- if (Inst.Operation == Win64EH::UOP_SaveR19R20X) {
- PrevOffset = 0;
- PrevRegister = 19;
- } else if (Inst.Operation == Win64EH::UOP_SaveRegPX) {
- PrevOffset = 0;
- PrevRegister = Inst.Register;
- } else if (Inst.Operation == Win64EH::UOP_SaveRegP) {
- PrevOffset = Inst.Offset;
- PrevRegister = Inst.Register;
- } else if (Inst.Operation == Win64EH::UOP_SaveNext) {
- PrevRegister += 2;
- PrevOffset += 16;
- } else {
- PrevRegister = -1;
- PrevOffset = -1;
- }
- };
-
- // Iterate over instructions in a forward order (for prologues),
- // backwards for epilogues (i.e. always reverse compared to how the
- // opcodes are stored).
- if (Reverse) {
- for (auto It = Instructions.rbegin(); It != Instructions.rend(); It++)
- VisitInstruction(*It);
- } else {
- for (WinEH::Instruction &Inst : Instructions)
- VisitInstruction(Inst);
- }
-}
-
-static int checkPackedEpilog(MCStreamer &streamer, WinEH::FrameInfo *info,
- int PrologCodeBytes) {
- // Can only pack if there's one single epilog
- if (info->EpilogMap.size() != 1)
- return -1;
-
- const std::vector<WinEH::Instruction> &Epilog =
- info->EpilogMap.begin()->second;
-
- // Can pack if the epilog is a subset of the prolog but not vice versa
- if (Epilog.size() > info->Instructions.size())
- return -1;
-
- // Check that the epilog actually is a perfect match for the end (backwrds)
- // of the prolog.
- for (int I = Epilog.size() - 1; I >= 0; I--) {
- if (info->Instructions[I] != Epilog[Epilog.size() - 1 - I])
- return -1;
- }
-
- // Check that the epilog actually is at the very end of the function,
- // otherwise it can't be packed.
- uint32_t DistanceFromEnd = (uint32_t)GetAbsDifference(
- streamer, info->FuncletOrFuncEnd, info->EpilogMap.begin()->first);
- if (DistanceFromEnd / 4 != Epilog.size())
- return -1;
-
- int Offset = Epilog.size() == info->Instructions.size()
- ? 0
- : ARM64CountOfUnwindCodes(ArrayRef<WinEH::Instruction>(
- &info->Instructions[Epilog.size()],
- info->Instructions.size() - Epilog.size()));
-
- // Check that the offset and prolog size fits in the first word; it's
- // unclear whether the epilog count in the extension word can be taken
- // as packed epilog offset.
- if (Offset > 31 || PrologCodeBytes > 124)
- return -1;
-
- info->EpilogMap.clear();
- return Offset;
-}
-
-static bool tryPackedUnwind(WinEH::FrameInfo *info, uint32_t FuncLength,
- int PackedEpilogOffset) {
- if (PackedEpilogOffset == 0) {
- // Fully symmetric prolog and epilog, should be ok for packed format.
- // For CR=3, the corresponding synthesized epilog actually lacks the
- // SetFP opcode, but unwinding should work just fine despite that
- // (if at the SetFP opcode, the unwinder considers it as part of the
- // function body and just unwinds the full prolog instead).
- } else if (PackedEpilogOffset == 1) {
- // One single case of differences between prolog and epilog is allowed:
- // The epilog can lack a single SetFP that is the last opcode in the
- // prolog, for the CR=3 case.
- if (info->Instructions.back().Operation != Win64EH::UOP_SetFP)
- return false;
- } else {
- // Too much difference between prolog and epilog.
- return false;
- }
- unsigned RegI = 0, RegF = 0;
- int Predecrement = 0;
- enum {
- Start,
- Start2,
- IntRegs,
- FloatRegs,
- InputArgs,
- StackAdjust,
- FrameRecord,
- End
- } Location = Start;
- bool StandaloneLR = false, FPLRPair = false;
- int StackOffset = 0;
- int Nops = 0;
- // Iterate over the prolog and check that all opcodes exactly match
- // the canonical order and form. A more lax check could verify that
- // all saved registers are in the expected locations, but not enforce
- // the order - that would work fine when unwinding from within
- // functions, but not be exactly right if unwinding happens within
- // prologs/epilogs.
- for (const WinEH::Instruction &Inst : info->Instructions) {
- switch (Inst.Operation) {
- case Win64EH::UOP_End:
- if (Location != Start)
- return false;
- Location = Start2;
- break;
- case Win64EH::UOP_SaveR19R20X:
- if (Location != Start2)
- return false;
- Predecrement = Inst.Offset;
- RegI = 2;
- Location = IntRegs;
- break;
- case Win64EH::UOP_SaveRegX:
- if (Location != Start2)
- return false;
- Predecrement = Inst.Offset;
- if (Inst.Register == 19)
- RegI += 1;
- else if (Inst.Register == 30)
- StandaloneLR = true;
- else
- return false;
- // Odd register; can't be any further int registers.
- Location = FloatRegs;
- break;
- case Win64EH::UOP_SaveRegPX:
- // Can't have this in a canonical prologue. Either this has been
- // canonicalized into SaveR19R20X or SaveFPLRX, or it's an unsupported
- // register pair.
- // It can't be canonicalized into SaveR19R20X if the offset is
- // larger than 248 bytes, but even with the maximum case with
- // RegI=10/RegF=8/CR=1/H=1, we end up with SavSZ = 216, which should
- // fit into SaveR19R20X.
- // The unwinding opcodes can't describe the otherwise seemingly valid
- // case for RegI=1 CR=1, that would start with a
- // "stp x19, lr, [sp, #-...]!" as that fits neither SaveRegPX nor
- // SaveLRPair.
- return false;
- case Win64EH::UOP_SaveRegP:
- if (Location != IntRegs || Inst.Offset != 8 * RegI ||
- Inst.Register != 19 + RegI)
- return false;
- RegI += 2;
- break;
- case Win64EH::UOP_SaveReg:
- if (Location != IntRegs || Inst.Offset != 8 * RegI)
- return false;
- if (Inst.Register == 19 + RegI)
- RegI += 1;
- else if (Inst.Register == 30)
- StandaloneLR = true;
- else
- return false;
- // Odd register; can't be any further int registers.
- Location = FloatRegs;
- break;
- case Win64EH::UOP_SaveLRPair:
- if (Location != IntRegs || Inst.Offset != 8 * RegI ||
- Inst.Register != 19 + RegI)
- return false;
- RegI += 1;
- StandaloneLR = true;
- Location = FloatRegs;
- break;
- case Win64EH::UOP_SaveFRegX:
- // Packed unwind can't handle prologs that only save one single
- // float register.
- return false;
- case Win64EH::UOP_SaveFReg:
- if (Location != FloatRegs || RegF == 0 || Inst.Register != 8 + RegF ||
- Inst.Offset != 8 * (RegI + (StandaloneLR ? 1 : 0) + RegF))
- return false;
- RegF += 1;
- Location = InputArgs;
- break;
- case Win64EH::UOP_SaveFRegPX:
- if (Location != Start2 || Inst.Register != 8)
- return false;
- Predecrement = Inst.Offset;
- RegF = 2;
- Location = FloatRegs;
- break;
- case Win64EH::UOP_SaveFRegP:
- if ((Location != IntRegs && Location != FloatRegs) ||
- Inst.Register != 8 + RegF ||
- Inst.Offset != 8 * (RegI + (StandaloneLR ? 1 : 0) + RegF))
- return false;
- RegF += 2;
- Location = FloatRegs;
- break;
- case Win64EH::UOP_SaveNext:
- if (Location == IntRegs)
- RegI += 2;
- else if (Location == FloatRegs)
- RegF += 2;
- else
- return false;
- break;
- case Win64EH::UOP_Nop:
- if (Location != IntRegs && Location != FloatRegs && Location != InputArgs)
- return false;
- Location = InputArgs;
- Nops++;
- break;
- case Win64EH::UOP_AllocSmall:
- case Win64EH::UOP_AllocMedium:
- if (Location != Start2 && Location != IntRegs && Location != FloatRegs &&
- Location != InputArgs && Location != StackAdjust)
- return false;
- // Can have either a single decrement, or a pair of decrements with
- // 4080 and another decrement.
- if (StackOffset == 0)
- StackOffset = Inst.Offset;
- else if (StackOffset != 4080)
- return false;
- else
- StackOffset += Inst.Offset;
- Location = StackAdjust;
- break;
- case Win64EH::UOP_SaveFPLRX:
- // Not allowing FPLRX after StackAdjust; if a StackAdjust is used, it
- // should be followed by a FPLR instead.
- if (Location != Start2 && Location != IntRegs && Location != FloatRegs &&
- Location != InputArgs)
- return false;
- StackOffset = Inst.Offset;
- Location = FrameRecord;
- FPLRPair = true;
- break;
- case Win64EH::UOP_SaveFPLR:
- // This can only follow after a StackAdjust
- if (Location != StackAdjust || Inst.Offset != 0)
- return false;
- Location = FrameRecord;
- FPLRPair = true;
- break;
- case Win64EH::UOP_SetFP:
- if (Location != FrameRecord)
- return false;
- Location = End;
- break;
- }
- }
- if (RegI > 10 || RegF > 8)
- return false;
- if (StandaloneLR && FPLRPair)
- return false;
- if (FPLRPair && Location != End)
- return false;
- if (Nops != 0 && Nops != 4)
- return false;
- int H = Nops == 4;
- int IntSZ = 8 * RegI;
- if (StandaloneLR)
- IntSZ += 8;
- int FpSZ = 8 * RegF; // RegF not yet decremented
- int SavSZ = (IntSZ + FpSZ + 8 * 8 * H + 0xF) & ~0xF;
- if (Predecrement != SavSZ)
- return false;
- if (FPLRPair && StackOffset < 16)
- return false;
- if (StackOffset % 16)
- return false;
- uint32_t FrameSize = (StackOffset + SavSZ) / 16;
- if (FrameSize > 0x1FF)
- return false;
- assert(RegF != 1 && "One single float reg not allowed");
- if (RegF > 0)
- RegF--; // Convert from actual number of registers, to value stored
- assert(FuncLength <= 0x7FF && "FuncLength should have been checked earlier");
- int Flag = 0x01; // Function segments not supported yet
- int CR = FPLRPair ? 3 : StandaloneLR ? 1 : 0;
- info->PackedInfo |= Flag << 0;
- info->PackedInfo |= (FuncLength & 0x7FF) << 2;
- info->PackedInfo |= (RegF & 0x7) << 13;
- info->PackedInfo |= (RegI & 0xF) << 16;
- info->PackedInfo |= (H & 0x1) << 20;
- info->PackedInfo |= (CR & 0x3) << 21;
- info->PackedInfo |= (FrameSize & 0x1FF) << 23;
- return true;
-}
-
+static void simplifyOpcodes(std::vector<WinEH::Instruction> &Instructions,
+ bool Reverse) {
+ unsigned PrevOffset = -1;
+ unsigned PrevRegister = -1;
+
+ auto VisitInstruction = [&](WinEH::Instruction &Inst) {
+ // Convert 2-byte opcodes into equivalent 1-byte ones.
+ if (Inst.Operation == Win64EH::UOP_SaveRegP && Inst.Register == 29) {
+ Inst.Operation = Win64EH::UOP_SaveFPLR;
+ Inst.Register = -1;
+ } else if (Inst.Operation == Win64EH::UOP_SaveRegPX &&
+ Inst.Register == 29) {
+ Inst.Operation = Win64EH::UOP_SaveFPLRX;
+ Inst.Register = -1;
+ } else if (Inst.Operation == Win64EH::UOP_SaveRegPX &&
+ Inst.Register == 19 && Inst.Offset <= 248) {
+ Inst.Operation = Win64EH::UOP_SaveR19R20X;
+ Inst.Register = -1;
+ } else if (Inst.Operation == Win64EH::UOP_AddFP && Inst.Offset == 0) {
+ Inst.Operation = Win64EH::UOP_SetFP;
+ } else if (Inst.Operation == Win64EH::UOP_SaveRegP &&
+ Inst.Register == PrevRegister + 2 &&
+ Inst.Offset == PrevOffset + 16) {
+ Inst.Operation = Win64EH::UOP_SaveNext;
+ Inst.Register = -1;
+ Inst.Offset = 0;
+ // Intentionally not creating UOP_SaveNext for float register pairs,
+ // as current versions of Windows (up to at least 20.04) is buggy
+ // regarding SaveNext for float pairs.
+ }
+ // Update info about the previous instruction, for detecting if
+ // the next one can be made a UOP_SaveNext
+ if (Inst.Operation == Win64EH::UOP_SaveR19R20X) {
+ PrevOffset = 0;
+ PrevRegister = 19;
+ } else if (Inst.Operation == Win64EH::UOP_SaveRegPX) {
+ PrevOffset = 0;
+ PrevRegister = Inst.Register;
+ } else if (Inst.Operation == Win64EH::UOP_SaveRegP) {
+ PrevOffset = Inst.Offset;
+ PrevRegister = Inst.Register;
+ } else if (Inst.Operation == Win64EH::UOP_SaveNext) {
+ PrevRegister += 2;
+ PrevOffset += 16;
+ } else {
+ PrevRegister = -1;
+ PrevOffset = -1;
+ }
+ };
+
+ // Iterate over instructions in a forward order (for prologues),
+ // backwards for epilogues (i.e. always reverse compared to how the
+ // opcodes are stored).
+ if (Reverse) {
+ for (auto It = Instructions.rbegin(); It != Instructions.rend(); It++)
+ VisitInstruction(*It);
+ } else {
+ for (WinEH::Instruction &Inst : Instructions)
+ VisitInstruction(Inst);
+ }
+}
+
+static int checkPackedEpilog(MCStreamer &streamer, WinEH::FrameInfo *info,
+ int PrologCodeBytes) {
+ // Can only pack if there's one single epilog
+ if (info->EpilogMap.size() != 1)
+ return -1;
+
+ const std::vector<WinEH::Instruction> &Epilog =
+ info->EpilogMap.begin()->second;
+
+ // Can pack if the epilog is a subset of the prolog but not vice versa
+ if (Epilog.size() > info->Instructions.size())
+ return -1;
+
+ // Check that the epilog actually is a perfect match for the end (backwrds)
+ // of the prolog.
+ for (int I = Epilog.size() - 1; I >= 0; I--) {
+ if (info->Instructions[I] != Epilog[Epilog.size() - 1 - I])
+ return -1;
+ }
+
+ // Check that the epilog actually is at the very end of the function,
+ // otherwise it can't be packed.
+ uint32_t DistanceFromEnd = (uint32_t)GetAbsDifference(
+ streamer, info->FuncletOrFuncEnd, info->EpilogMap.begin()->first);
+ if (DistanceFromEnd / 4 != Epilog.size())
+ return -1;
+
+ int Offset = Epilog.size() == info->Instructions.size()
+ ? 0
+ : ARM64CountOfUnwindCodes(ArrayRef<WinEH::Instruction>(
+ &info->Instructions[Epilog.size()],
+ info->Instructions.size() - Epilog.size()));
+
+ // Check that the offset and prolog size fits in the first word; it's
+ // unclear whether the epilog count in the extension word can be taken
+ // as packed epilog offset.
+ if (Offset > 31 || PrologCodeBytes > 124)
+ return -1;
+
+ info->EpilogMap.clear();
+ return Offset;
+}
+
+static bool tryPackedUnwind(WinEH::FrameInfo *info, uint32_t FuncLength,
+ int PackedEpilogOffset) {
+ if (PackedEpilogOffset == 0) {
+ // Fully symmetric prolog and epilog, should be ok for packed format.
+ // For CR=3, the corresponding synthesized epilog actually lacks the
+ // SetFP opcode, but unwinding should work just fine despite that
+ // (if at the SetFP opcode, the unwinder considers it as part of the
+ // function body and just unwinds the full prolog instead).
+ } else if (PackedEpilogOffset == 1) {
+ // One single case of differences between prolog and epilog is allowed:
+ // The epilog can lack a single SetFP that is the last opcode in the
+ // prolog, for the CR=3 case.
+ if (info->Instructions.back().Operation != Win64EH::UOP_SetFP)
+ return false;
+ } else {
+ // Too much difference between prolog and epilog.
+ return false;
+ }
+ unsigned RegI = 0, RegF = 0;
+ int Predecrement = 0;
+ enum {
+ Start,
+ Start2,
+ IntRegs,
+ FloatRegs,
+ InputArgs,
+ StackAdjust,
+ FrameRecord,
+ End
+ } Location = Start;
+ bool StandaloneLR = false, FPLRPair = false;
+ int StackOffset = 0;
+ int Nops = 0;
+ // Iterate over the prolog and check that all opcodes exactly match
+ // the canonical order and form. A more lax check could verify that
+ // all saved registers are in the expected locations, but not enforce
+ // the order - that would work fine when unwinding from within
+ // functions, but not be exactly right if unwinding happens within
+ // prologs/epilogs.
+ for (const WinEH::Instruction &Inst : info->Instructions) {
+ switch (Inst.Operation) {
+ case Win64EH::UOP_End:
+ if (Location != Start)
+ return false;
+ Location = Start2;
+ break;
+ case Win64EH::UOP_SaveR19R20X:
+ if (Location != Start2)
+ return false;
+ Predecrement = Inst.Offset;
+ RegI = 2;
+ Location = IntRegs;
+ break;
+ case Win64EH::UOP_SaveRegX:
+ if (Location != Start2)
+ return false;
+ Predecrement = Inst.Offset;
+ if (Inst.Register == 19)
+ RegI += 1;
+ else if (Inst.Register == 30)
+ StandaloneLR = true;
+ else
+ return false;
+ // Odd register; can't be any further int registers.
+ Location = FloatRegs;
+ break;
+ case Win64EH::UOP_SaveRegPX:
+ // Can't have this in a canonical prologue. Either this has been
+ // canonicalized into SaveR19R20X or SaveFPLRX, or it's an unsupported
+ // register pair.
+ // It can't be canonicalized into SaveR19R20X if the offset is
+ // larger than 248 bytes, but even with the maximum case with
+ // RegI=10/RegF=8/CR=1/H=1, we end up with SavSZ = 216, which should
+ // fit into SaveR19R20X.
+ // The unwinding opcodes can't describe the otherwise seemingly valid
+ // case for RegI=1 CR=1, that would start with a
+ // "stp x19, lr, [sp, #-...]!" as that fits neither SaveRegPX nor
+ // SaveLRPair.
+ return false;
+ case Win64EH::UOP_SaveRegP:
+ if (Location != IntRegs || Inst.Offset != 8 * RegI ||
+ Inst.Register != 19 + RegI)
+ return false;
+ RegI += 2;
+ break;
+ case Win64EH::UOP_SaveReg:
+ if (Location != IntRegs || Inst.Offset != 8 * RegI)
+ return false;
+ if (Inst.Register == 19 + RegI)
+ RegI += 1;
+ else if (Inst.Register == 30)
+ StandaloneLR = true;
+ else
+ return false;
+ // Odd register; can't be any further int registers.
+ Location = FloatRegs;
+ break;
+ case Win64EH::UOP_SaveLRPair:
+ if (Location != IntRegs || Inst.Offset != 8 * RegI ||
+ Inst.Register != 19 + RegI)
+ return false;
+ RegI += 1;
+ StandaloneLR = true;
+ Location = FloatRegs;
+ break;
+ case Win64EH::UOP_SaveFRegX:
+ // Packed unwind can't handle prologs that only save one single
+ // float register.
+ return false;
+ case Win64EH::UOP_SaveFReg:
+ if (Location != FloatRegs || RegF == 0 || Inst.Register != 8 + RegF ||
+ Inst.Offset != 8 * (RegI + (StandaloneLR ? 1 : 0) + RegF))
+ return false;
+ RegF += 1;
+ Location = InputArgs;
+ break;
+ case Win64EH::UOP_SaveFRegPX:
+ if (Location != Start2 || Inst.Register != 8)
+ return false;
+ Predecrement = Inst.Offset;
+ RegF = 2;
+ Location = FloatRegs;
+ break;
+ case Win64EH::UOP_SaveFRegP:
+ if ((Location != IntRegs && Location != FloatRegs) ||
+ Inst.Register != 8 + RegF ||
+ Inst.Offset != 8 * (RegI + (StandaloneLR ? 1 : 0) + RegF))
+ return false;
+ RegF += 2;
+ Location = FloatRegs;
+ break;
+ case Win64EH::UOP_SaveNext:
+ if (Location == IntRegs)
+ RegI += 2;
+ else if (Location == FloatRegs)
+ RegF += 2;
+ else
+ return false;
+ break;
+ case Win64EH::UOP_Nop:
+ if (Location != IntRegs && Location != FloatRegs && Location != InputArgs)
+ return false;
+ Location = InputArgs;
+ Nops++;
+ break;
+ case Win64EH::UOP_AllocSmall:
+ case Win64EH::UOP_AllocMedium:
+ if (Location != Start2 && Location != IntRegs && Location != FloatRegs &&
+ Location != InputArgs && Location != StackAdjust)
+ return false;
+ // Can have either a single decrement, or a pair of decrements with
+ // 4080 and another decrement.
+ if (StackOffset == 0)
+ StackOffset = Inst.Offset;
+ else if (StackOffset != 4080)
+ return false;
+ else
+ StackOffset += Inst.Offset;
+ Location = StackAdjust;
+ break;
+ case Win64EH::UOP_SaveFPLRX:
+ // Not allowing FPLRX after StackAdjust; if a StackAdjust is used, it
+ // should be followed by a FPLR instead.
+ if (Location != Start2 && Location != IntRegs && Location != FloatRegs &&
+ Location != InputArgs)
+ return false;
+ StackOffset = Inst.Offset;
+ Location = FrameRecord;
+ FPLRPair = true;
+ break;
+ case Win64EH::UOP_SaveFPLR:
+ // This can only follow after a StackAdjust
+ if (Location != StackAdjust || Inst.Offset != 0)
+ return false;
+ Location = FrameRecord;
+ FPLRPair = true;
+ break;
+ case Win64EH::UOP_SetFP:
+ if (Location != FrameRecord)
+ return false;
+ Location = End;
+ break;
+ }
+ }
+ if (RegI > 10 || RegF > 8)
+ return false;
+ if (StandaloneLR && FPLRPair)
+ return false;
+ if (FPLRPair && Location != End)
+ return false;
+ if (Nops != 0 && Nops != 4)
+ return false;
+ int H = Nops == 4;
+ int IntSZ = 8 * RegI;
+ if (StandaloneLR)
+ IntSZ += 8;
+ int FpSZ = 8 * RegF; // RegF not yet decremented
+ int SavSZ = (IntSZ + FpSZ + 8 * 8 * H + 0xF) & ~0xF;
+ if (Predecrement != SavSZ)
+ return false;
+ if (FPLRPair && StackOffset < 16)
+ return false;
+ if (StackOffset % 16)
+ return false;
+ uint32_t FrameSize = (StackOffset + SavSZ) / 16;
+ if (FrameSize > 0x1FF)
+ return false;
+ assert(RegF != 1 && "One single float reg not allowed");
+ if (RegF > 0)
+ RegF--; // Convert from actual number of registers, to value stored
+ assert(FuncLength <= 0x7FF && "FuncLength should have been checked earlier");
+ int Flag = 0x01; // Function segments not supported yet
+ int CR = FPLRPair ? 3 : StandaloneLR ? 1 : 0;
+ info->PackedInfo |= Flag << 0;
+ info->PackedInfo |= (FuncLength & 0x7FF) << 2;
+ info->PackedInfo |= (RegF & 0x7) << 13;
+ info->PackedInfo |= (RegI & 0xF) << 16;
+ info->PackedInfo |= (H & 0x1) << 20;
+ info->PackedInfo |= (CR & 0x3) << 21;
+ info->PackedInfo |= (FrameSize & 0x1FF) << 23;
+ return true;
+}
+
// Populate the .xdata section. The format of .xdata on ARM64 is documented at
// https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
-static void ARM64EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info,
- bool TryPacked = true) {
+static void ARM64EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info,
+ bool TryPacked = true) {
// If this UNWIND_INFO already has a symbol, it's already been emitted.
if (info->Symbol)
return;
- // If there's no unwind info here (not even a terminating UOP_End), the
- // unwind info is considered bogus and skipped. If this was done in
- // response to an explicit .seh_handlerdata, the associated trailing
- // handler data is left orphaned in the xdata section.
- if (info->empty()) {
- info->EmitAttempted = true;
- return;
- }
- if (info->EmitAttempted) {
- // If we tried to emit unwind info before (due to an explicit
- // .seh_handlerdata directive), but skipped it (because there was no
- // valid information to emit at the time), and it later got valid unwind
- // opcodes, we can't emit it here, because the trailing handler data
- // was already emitted elsewhere in the xdata section.
- streamer.getContext().reportError(
- SMLoc(), "Earlier .seh_handlerdata for " + info->Function->getName() +
- " skipped due to no unwind info at the time "
- "(.seh_handlerdata too early?), but the function later "
- "did get unwind info that can't be emitted");
- return;
- }
-
- simplifyOpcodes(info->Instructions, false);
- for (auto &I : info->EpilogMap)
- simplifyOpcodes(I.second, true);
-
+ // If there's no unwind info here (not even a terminating UOP_End), the
+ // unwind info is considered bogus and skipped. If this was done in
+ // response to an explicit .seh_handlerdata, the associated trailing
+ // handler data is left orphaned in the xdata section.
+ if (info->empty()) {
+ info->EmitAttempted = true;
+ return;
+ }
+ if (info->EmitAttempted) {
+ // If we tried to emit unwind info before (due to an explicit
+ // .seh_handlerdata directive), but skipped it (because there was no
+ // valid information to emit at the time), and it later got valid unwind
+ // opcodes, we can't emit it here, because the trailing handler data
+ // was already emitted elsewhere in the xdata section.
+ streamer.getContext().reportError(
+ SMLoc(), "Earlier .seh_handlerdata for " + info->Function->getName() +
+ " skipped due to no unwind info at the time "
+ "(.seh_handlerdata too early?), but the function later "
+ "did get unwind info that can't be emitted");
+ return;
+ }
+
+ simplifyOpcodes(info->Instructions, false);
+ for (auto &I : info->EpilogMap)
+ simplifyOpcodes(I.second, true);
+
MCContext &context = streamer.getContext();
MCSymbol *Label = context.createTempSymbol();
@@ -914,7 +914,7 @@ static void ARM64EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info,
int64_t RawFuncLength;
if (!info->FuncletOrFuncEnd) {
- report_fatal_error("FuncletOrFuncEnd not set");
+ report_fatal_error("FuncletOrFuncEnd not set");
} else {
// FIXME: GetAbsDifference tries to compute the length of the function
// immediately, before the whole file is emitted, but in general
@@ -951,22 +951,22 @@ static void ARM64EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info,
uint32_t PrologCodeBytes = ARM64CountOfUnwindCodes(info->Instructions);
uint32_t TotalCodeBytes = PrologCodeBytes;
- int PackedEpilogOffset = checkPackedEpilog(streamer, info, PrologCodeBytes);
-
- if (PackedEpilogOffset >= 0 && !info->HandlesExceptions &&
- FuncLength <= 0x7ff && TryPacked) {
- // Matching prolog/epilog and no exception handlers; check if the
- // prolog matches the patterns that can be described by the packed
- // format.
-
- // info->Symbol was already set even if we didn't actually write any
- // unwind info there. Keep using that as indicator that this unwind
- // info has been generated already.
-
- if (tryPackedUnwind(info, FuncLength, PackedEpilogOffset))
- return;
- }
-
+ int PackedEpilogOffset = checkPackedEpilog(streamer, info, PrologCodeBytes);
+
+ if (PackedEpilogOffset >= 0 && !info->HandlesExceptions &&
+ FuncLength <= 0x7ff && TryPacked) {
+ // Matching prolog/epilog and no exception handlers; check if the
+ // prolog matches the patterns that can be described by the packed
+ // format.
+
+ // info->Symbol was already set even if we didn't actually write any
+ // unwind info there. Keep using that as indicator that this unwind
+ // info has been generated already.
+
+ if (tryPackedUnwind(info, FuncLength, PackedEpilogOffset))
+ return;
+ }
+
// Process epilogs.
MapVector<MCSymbol *, uint32_t> EpilogInfo;
// Epilogs processed so far.
@@ -999,8 +999,8 @@ static void ARM64EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info,
uint32_t CodeWordsMod = TotalCodeBytes % 4;
if (CodeWordsMod)
CodeWords++;
- uint32_t EpilogCount =
- PackedEpilogOffset >= 0 ? PackedEpilogOffset : info->EpilogMap.size();
+ uint32_t EpilogCount =
+ PackedEpilogOffset >= 0 ? PackedEpilogOffset : info->EpilogMap.size();
bool ExtensionWord = EpilogCount > 31 || TotalCodeBytes > 124;
if (!ExtensionWord) {
row1 |= (EpilogCount & 0x1F) << 22;
@@ -1008,8 +1008,8 @@ static void ARM64EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info,
}
if (info->HandlesExceptions) // X
row1 |= 1 << 20;
- if (PackedEpilogOffset >= 0) // E
- row1 |= 1 << 21;
+ if (PackedEpilogOffset >= 0) // E
+ row1 |= 1 << 21;
row1 |= FuncLength & 0x3FFFF;
streamer.emitInt32(row1);
@@ -1074,56 +1074,56 @@ static void ARM64EmitRuntimeFunction(MCStreamer &streamer,
streamer.emitValueToAlignment(4);
EmitSymbolRefWithOfs(streamer, info->Function, info->Begin);
- if (info->PackedInfo)
- streamer.emitInt32(info->PackedInfo);
- else
- streamer.emitValue(
- MCSymbolRefExpr::create(info->Symbol, MCSymbolRefExpr::VK_COFF_IMGREL32,
- context),
- 4);
+ if (info->PackedInfo)
+ streamer.emitInt32(info->PackedInfo);
+ else
+ streamer.emitValue(
+ MCSymbolRefExpr::create(info->Symbol, MCSymbolRefExpr::VK_COFF_IMGREL32,
+ context),
+ 4);
}
void llvm::Win64EH::ARM64UnwindEmitter::Emit(MCStreamer &Streamer) const {
// Emit the unwind info structs first.
for (const auto &CFI : Streamer.getWinFrameInfos()) {
- WinEH::FrameInfo *Info = CFI.get();
- if (Info->empty())
- continue;
+ WinEH::FrameInfo *Info = CFI.get();
+ if (Info->empty())
+ continue;
MCSection *XData = Streamer.getAssociatedXDataSection(CFI->TextSection);
Streamer.SwitchSection(XData);
- ARM64EmitUnwindInfo(Streamer, Info);
+ ARM64EmitUnwindInfo(Streamer, Info);
}
// Now emit RUNTIME_FUNCTION entries.
for (const auto &CFI : Streamer.getWinFrameInfos()) {
- WinEH::FrameInfo *Info = CFI.get();
- // ARM64EmitUnwindInfo above clears the info struct, so we can't check
- // empty here. But if a Symbol is set, we should create the corresponding
- // pdata entry.
- if (!Info->Symbol)
- continue;
+ WinEH::FrameInfo *Info = CFI.get();
+ // ARM64EmitUnwindInfo above clears the info struct, so we can't check
+ // empty here. But if a Symbol is set, we should create the corresponding
+ // pdata entry.
+ if (!Info->Symbol)
+ continue;
MCSection *PData = Streamer.getAssociatedPDataSection(CFI->TextSection);
Streamer.SwitchSection(PData);
- ARM64EmitRuntimeFunction(Streamer, Info);
+ ARM64EmitRuntimeFunction(Streamer, Info);
}
}
-void llvm::Win64EH::ARM64UnwindEmitter::EmitUnwindInfo(MCStreamer &Streamer,
- WinEH::FrameInfo *info,
- bool HandlerData) const {
- // Called if there's an .seh_handlerdata directive before the end of the
- // function. This forces writing the xdata record already here - and
- // in this case, the function isn't actually ended already, but the xdata
- // record needs to know the function length. In these cases, if the funclet
- // end hasn't been marked yet, the xdata function length won't cover the
- // whole function, only up to this point.
- if (!info->FuncletOrFuncEnd) {
- Streamer.SwitchSection(info->TextSection);
- info->FuncletOrFuncEnd = Streamer.emitCFILabel();
- }
+void llvm::Win64EH::ARM64UnwindEmitter::EmitUnwindInfo(MCStreamer &Streamer,
+ WinEH::FrameInfo *info,
+ bool HandlerData) const {
+ // Called if there's an .seh_handlerdata directive before the end of the
+ // function. This forces writing the xdata record already here - and
+ // in this case, the function isn't actually ended already, but the xdata
+ // record needs to know the function length. In these cases, if the funclet
+ // end hasn't been marked yet, the xdata function length won't cover the
+ // whole function, only up to this point.
+ if (!info->FuncletOrFuncEnd) {
+ Streamer.SwitchSection(info->TextSection);
+ info->FuncletOrFuncEnd = Streamer.emitCFILabel();
+ }
// Switch sections (the static function above is meant to be called from
// here and from Emit().
MCSection *XData = Streamer.getAssociatedXDataSection(info->TextSection);
Streamer.SwitchSection(XData);
- ARM64EmitUnwindInfo(Streamer, info, /* TryPacked = */ !HandlerData);
+ ARM64EmitUnwindInfo(Streamer, info, /* TryPacked = */ !HandlerData);
}
diff --git a/contrib/libs/llvm12/lib/MC/MCWinCOFFStreamer.cpp b/contrib/libs/llvm12/lib/MC/MCWinCOFFStreamer.cpp
index 6bc934cecf..97cceac74a 100644
--- a/contrib/libs/llvm12/lib/MC/MCWinCOFFStreamer.cpp
+++ b/contrib/libs/llvm12/lib/MC/MCWinCOFFStreamer.cpp
@@ -308,16 +308,16 @@ void MCWinCOFFStreamer::emitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
PopSection();
}
-void MCWinCOFFStreamer::emitWeakReference(MCSymbol *AliasS,
- const MCSymbol *Symbol) {
- auto *Alias = cast<MCSymbolCOFF>(AliasS);
- emitSymbolAttribute(Alias, MCSA_Weak);
-
- getAssembler().registerSymbol(*Symbol);
- Alias->setVariableValue(MCSymbolRefExpr::create(
- Symbol, MCSymbolRefExpr::VK_WEAKREF, getContext()));
-}
-
+void MCWinCOFFStreamer::emitWeakReference(MCSymbol *AliasS,
+ const MCSymbol *Symbol) {
+ auto *Alias = cast<MCSymbolCOFF>(AliasS);
+ emitSymbolAttribute(Alias, MCSA_Weak);
+
+ getAssembler().registerSymbol(*Symbol);
+ Alias->setVariableValue(MCSymbolRefExpr::create(
+ Symbol, MCSymbolRefExpr::VK_WEAKREF, getContext()));
+}
+
void MCWinCOFFStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment,
SMLoc Loc) {
@@ -350,7 +350,7 @@ void MCWinCOFFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE) {
const MCSymbol *S = &SRE->getSymbol();
bool Created;
getAssembler().registerSymbol(*S, &Created);
- if (Created)
+ if (Created)
cast<MCSymbolCOFF>(S)->setExternal(true);
}
diff --git a/contrib/libs/llvm12/lib/MC/StringTableBuilder.cpp b/contrib/libs/llvm12/lib/MC/StringTableBuilder.cpp
index dd852d6ef7..973c59057c 100644
--- a/contrib/libs/llvm12/lib/MC/StringTableBuilder.cpp
+++ b/contrib/libs/llvm12/lib/MC/StringTableBuilder.cpp
@@ -33,12 +33,12 @@ void StringTableBuilder::initSize() {
case DWARF:
Size = 0;
break;
- case MachOLinked:
- case MachO64Linked:
- Size = 2;
- break;
+ case MachOLinked:
+ case MachO64Linked:
+ Size = 2;
+ break;
case MachO:
- case MachO64:
+ case MachO64:
case ELF:
// Start the table with a NUL byte.
Size = 1;
@@ -166,17 +166,17 @@ void StringTableBuilder::finalizeStringTable(bool Optimize) {
}
}
- if (K == MachO || K == MachOLinked)
+ if (K == MachO || K == MachOLinked)
Size = alignTo(Size, 4); // Pad to multiple of 4.
- if (K == MachO64 || K == MachO64Linked)
- Size = alignTo(Size, 8); // Pad to multiple of 8.
-
- // According to ld64 the string table of a final linked Mach-O binary starts
- // with " ", i.e. the first byte is ' ' and the second byte is zero. In
- // 'initSize()' we reserved the first two bytes for holding this string.
- if (K == MachOLinked || K == MachO64Linked)
- StringIndexMap[CachedHashStringRef(" ")] = 0;
-
+ if (K == MachO64 || K == MachO64Linked)
+ Size = alignTo(Size, 8); // Pad to multiple of 8.
+
+ // According to ld64 the string table of a final linked Mach-O binary starts
+ // with " ", i.e. the first byte is ' ' and the second byte is zero. In
+ // 'initSize()' we reserved the first two bytes for holding this string.
+ if (K == MachOLinked || K == MachO64Linked)
+ StringIndexMap[CachedHashStringRef(" ")] = 0;
+
// The first byte in an ELF string table must be null, according to the ELF
// specification. In 'initSize()' we reserved the first byte to hold null for
// this purpose and here we actually add the string to allow 'getOffset()' to
diff --git a/contrib/libs/llvm12/lib/MC/WasmObjectWriter.cpp b/contrib/libs/llvm12/lib/MC/WasmObjectWriter.cpp
index e99bcb980e..930413e834 100644
--- a/contrib/libs/llvm12/lib/MC/WasmObjectWriter.cpp
+++ b/contrib/libs/llvm12/lib/MC/WasmObjectWriter.cpp
@@ -13,7 +13,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/BinaryFormat/Wasm.h"
-#include "llvm/BinaryFormat/WasmTraits.h"
+#include "llvm/BinaryFormat/WasmTraits.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmLayout.h"
@@ -40,8 +40,8 @@ using namespace llvm;
namespace {
-// When we create the indirect function table we start at 1, so that there is
-// and empty slot at 0 and therefore calling a null function pointer will trap.
+// When we create the indirect function table we start at 1, so that there is
+// and empty slot at 0 and therefore calling a null function pointer will trap.
static const uint32_t InitialTableOffset = 1;
// For patching purposes, we need to remember where each section starts, both
@@ -173,12 +173,12 @@ static void patchI64(raw_pwrite_stream &Stream, uint64_t X, uint64_t Offset) {
Stream.pwrite((char *)Buffer, sizeof(Buffer), Offset);
}
-bool isDwoSection(const MCSection &Sec) {
- return Sec.getName().endswith(".dwo");
-}
-
+bool isDwoSection(const MCSection &Sec) {
+ return Sec.getName().endswith(".dwo");
+}
+
class WasmObjectWriter : public MCObjectWriter {
- support::endian::Writer *W;
+ support::endian::Writer *W;
/// The target specific Wasm writer instance.
std::unique_ptr<MCWasmObjectTargetWriter> TargetObjectWriter;
@@ -194,8 +194,8 @@ class WasmObjectWriter : public MCObjectWriter {
// Maps function symbols to the table element index space. Used
// for TABLE_INDEX relocation types (i.e. address taken functions).
DenseMap<const MCSymbolWasm *, uint32_t> TableIndices;
- // Maps function/global/table symbols to the
- // function/global/table/event/section index space.
+ // Maps function/global/table symbols to the
+ // function/global/table/event/section index space.
DenseMap<const MCSymbolWasm *, uint32_t> WasmIndices;
DenseMap<const MCSymbolWasm *, uint32_t> GOTIndices;
// Maps data symbols to the Wasm segment and offset/size with the segment.
@@ -213,25 +213,25 @@ class WasmObjectWriter : public MCObjectWriter {
// Map from section to defining function symbol.
DenseMap<const MCSection *, const MCSymbol *> SectionFunctions;
- DenseMap<wasm::WasmSignature, uint32_t> SignatureIndices;
- SmallVector<wasm::WasmSignature, 4> Signatures;
+ DenseMap<wasm::WasmSignature, uint32_t> SignatureIndices;
+ SmallVector<wasm::WasmSignature, 4> Signatures;
SmallVector<WasmDataSegment, 4> DataSegments;
unsigned NumFunctionImports = 0;
unsigned NumGlobalImports = 0;
- unsigned NumTableImports = 0;
+ unsigned NumTableImports = 0;
unsigned NumEventImports = 0;
uint32_t SectionCount = 0;
- enum class DwoMode {
- AllSections,
- NonDwoOnly,
- DwoOnly,
- };
- bool IsSplitDwarf = false;
- raw_pwrite_stream *OS = nullptr;
- raw_pwrite_stream *DwoOS = nullptr;
-
- // TargetObjectWriter wranppers.
+ enum class DwoMode {
+ AllSections,
+ NonDwoOnly,
+ DwoOnly,
+ };
+ bool IsSplitDwarf = false;
+ raw_pwrite_stream *OS = nullptr;
+ raw_pwrite_stream *DwoOS = nullptr;
+
+ // TargetObjectWriter wranppers.
bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
bool isEmscripten() const { return TargetObjectWriter->isEmscripten(); }
@@ -241,14 +241,14 @@ class WasmObjectWriter : public MCObjectWriter {
public:
WasmObjectWriter(std::unique_ptr<MCWasmObjectTargetWriter> MOTW,
- raw_pwrite_stream &OS_)
- : TargetObjectWriter(std::move(MOTW)), OS(&OS_) {}
-
- WasmObjectWriter(std::unique_ptr<MCWasmObjectTargetWriter> MOTW,
- raw_pwrite_stream &OS_, raw_pwrite_stream &DwoOS_)
- : TargetObjectWriter(std::move(MOTW)), IsSplitDwarf(true), OS(&OS_),
- DwoOS(&DwoOS_) {}
-
+ raw_pwrite_stream &OS_)
+ : TargetObjectWriter(std::move(MOTW)), OS(&OS_) {}
+
+ WasmObjectWriter(std::unique_ptr<MCWasmObjectTargetWriter> MOTW,
+ raw_pwrite_stream &OS_, raw_pwrite_stream &DwoOS_)
+ : TargetObjectWriter(std::move(MOTW)), IsSplitDwarf(true), OS(&OS_),
+ DwoOS(&DwoOS_) {}
+
private:
void reset() override {
CodeRelocations.clear();
@@ -268,7 +268,7 @@ private:
SectionFunctions.clear();
NumFunctionImports = 0;
NumGlobalImports = 0;
- NumTableImports = 0;
+ NumTableImports = 0;
MCObjectWriter::reset();
}
@@ -280,33 +280,33 @@ private:
void executePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) override;
- void prepareImports(SmallVectorImpl<wasm::WasmImport> &Imports,
- MCAssembler &Asm, const MCAsmLayout &Layout);
+ void prepareImports(SmallVectorImpl<wasm::WasmImport> &Imports,
+ MCAssembler &Asm, const MCAsmLayout &Layout);
uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
- uint64_t writeOneObject(MCAssembler &Asm, const MCAsmLayout &Layout,
- DwoMode Mode);
-
+ uint64_t writeOneObject(MCAssembler &Asm, const MCAsmLayout &Layout,
+ DwoMode Mode);
+
void writeString(const StringRef Str) {
- encodeULEB128(Str.size(), W->OS);
- W->OS << Str;
+ encodeULEB128(Str.size(), W->OS);
+ W->OS << Str;
}
void writeI32(int32_t val) {
char Buffer[4];
support::endian::write32le(Buffer, val);
- W->OS.write(Buffer, sizeof(Buffer));
+ W->OS.write(Buffer, sizeof(Buffer));
}
void writeI64(int64_t val) {
char Buffer[8];
support::endian::write64le(Buffer, val);
- W->OS.write(Buffer, sizeof(Buffer));
+ W->OS.write(Buffer, sizeof(Buffer));
}
- void writeValueType(wasm::ValType Ty) { W->OS << static_cast<char>(Ty); }
+ void writeValueType(wasm::ValType Ty) { W->OS << static_cast<char>(Ty); }
- void writeTypeSection(ArrayRef<wasm::WasmSignature> Signatures);
+ void writeTypeSection(ArrayRef<wasm::WasmSignature> Signatures);
void writeImportSection(ArrayRef<wasm::WasmImport> Imports, uint64_t DataSize,
uint32_t NumElements);
void writeFunctionSection(ArrayRef<WasmFunction> Functions);
@@ -318,7 +318,7 @@ private:
uint32_t writeDataSection(const MCAsmLayout &Layout);
void writeEventSection(ArrayRef<wasm::WasmEventType> Events);
void writeGlobalSection(ArrayRef<wasm::WasmGlobal> Globals);
- void writeTableSection(ArrayRef<wasm::WasmTable> Tables);
+ void writeTableSection(ArrayRef<wasm::WasmTable> Tables);
void writeRelocSection(uint32_t SectionIndex, StringRef Name,
std::vector<WasmRelocationEntry> &Relocations);
void writeLinkingMetaDataSection(
@@ -347,17 +347,17 @@ private:
void WasmObjectWriter::startSection(SectionBookkeeping &Section,
unsigned SectionId) {
LLVM_DEBUG(dbgs() << "startSection " << SectionId << "\n");
- W->OS << char(SectionId);
+ W->OS << char(SectionId);
- Section.SizeOffset = W->OS.tell();
+ Section.SizeOffset = W->OS.tell();
// The section size. We don't know the size yet, so reserve enough space
// for any 32-bit value; we'll patch it later.
- encodeULEB128(0, W->OS, 5);
+ encodeULEB128(0, W->OS, 5);
// The position where the section starts, for measuring its size.
- Section.ContentsOffset = W->OS.tell();
- Section.PayloadOffset = W->OS.tell();
+ Section.ContentsOffset = W->OS.tell();
+ Section.PayloadOffset = W->OS.tell();
Section.Index = SectionCount++;
}
@@ -367,19 +367,19 @@ void WasmObjectWriter::startCustomSection(SectionBookkeeping &Section,
startSection(Section, wasm::WASM_SEC_CUSTOM);
// The position where the section header ends, for measuring its size.
- Section.PayloadOffset = W->OS.tell();
+ Section.PayloadOffset = W->OS.tell();
// Custom sections in wasm also have a string identifier.
writeString(Name);
// The position where the custom section starts.
- Section.ContentsOffset = W->OS.tell();
+ Section.ContentsOffset = W->OS.tell();
}
// Now that the section is complete and we know how big it is, patch up the
// section size field at the start of the section.
void WasmObjectWriter::endSection(SectionBookkeeping &Section) {
- uint64_t Size = W->OS.tell();
+ uint64_t Size = W->OS.tell();
// /dev/null doesn't support seek/tell and can report offset of 0.
// Simply skip this patching in that case.
if (!Size)
@@ -393,25 +393,25 @@ void WasmObjectWriter::endSection(SectionBookkeeping &Section) {
// Write the final section size to the payload_len field, which follows
// the section id byte.
- writePatchableLEB<5>(static_cast<raw_pwrite_stream &>(W->OS), Size,
+ writePatchableLEB<5>(static_cast<raw_pwrite_stream &>(W->OS), Size,
Section.SizeOffset);
}
// Emit the Wasm header.
void WasmObjectWriter::writeHeader(const MCAssembler &Asm) {
- W->OS.write(wasm::WasmMagic, sizeof(wasm::WasmMagic));
- W->write<uint32_t>(wasm::WasmVersion);
+ W->OS.write(wasm::WasmMagic, sizeof(wasm::WasmMagic));
+ W->write<uint32_t>(wasm::WasmVersion);
}
void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) {
- // As a stopgap measure until call_indirect instructions start explicitly
- // referencing the indirect function table via TABLE_NUMBER relocs, ensure
- // that the indirect function table import makes it to the output if anything
- // in the compilation unit has caused it to be present.
- if (auto *Sym = Asm.getContext().lookupSymbol("__indirect_function_table"))
- Asm.registerSymbol(*Sym);
-
+ // As a stopgap measure until call_indirect instructions start explicitly
+ // referencing the indirect function table via TABLE_NUMBER relocs, ensure
+ // that the indirect function table import makes it to the output if anything
+ // in the compilation unit has caused it to be present.
+ if (auto *Sym = Asm.getContext().lookupSymbol("__indirect_function_table"))
+ Asm.registerSymbol(*Sym);
+
// Build a map of sections to the function that defines them, for use
// in recordRelocation.
for (const MCSymbol &S : Asm.symbols()) {
@@ -480,7 +480,7 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
// Currently only supported for for metadata sections.
// See: test/MC/WebAssembly/blockaddress.ll
if (Type == wasm::R_WASM_FUNCTION_OFFSET_I32 ||
- Type == wasm::R_WASM_FUNCTION_OFFSET_I64 ||
+ Type == wasm::R_WASM_FUNCTION_OFFSET_I64 ||
Type == wasm::R_WASM_SECTION_OFFSET_I32) {
if (!FixupSection.getKind().isMetadata())
report_fatal_error("relocations for function or section offsets are "
@@ -499,29 +499,29 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
SymA = cast<MCSymbolWasm>(SectionSymbol);
}
- if (Type == wasm::R_WASM_TABLE_INDEX_REL_SLEB ||
- Type == wasm::R_WASM_TABLE_INDEX_SLEB ||
- Type == wasm::R_WASM_TABLE_INDEX_SLEB64 ||
- Type == wasm::R_WASM_TABLE_INDEX_I32 ||
- Type == wasm::R_WASM_TABLE_INDEX_I64) {
- // TABLE_INDEX relocs implicitly use the default indirect function table.
- auto TableName = "__indirect_function_table";
- MCSymbolWasm *Sym = cast_or_null<MCSymbolWasm>(Ctx.lookupSymbol(TableName));
- if (Sym) {
- if (!Sym->isFunctionTable())
- Ctx.reportError(
- Fixup.getLoc(),
- "symbol '__indirect_function_table' is not a function table");
- } else {
- Sym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(TableName));
- Sym->setFunctionTable();
- // The default function table is synthesized by the linker.
- Sym->setUndefined();
- }
- Sym->setUsedInReloc();
- Asm.registerSymbol(*Sym);
- }
-
+ if (Type == wasm::R_WASM_TABLE_INDEX_REL_SLEB ||
+ Type == wasm::R_WASM_TABLE_INDEX_SLEB ||
+ Type == wasm::R_WASM_TABLE_INDEX_SLEB64 ||
+ Type == wasm::R_WASM_TABLE_INDEX_I32 ||
+ Type == wasm::R_WASM_TABLE_INDEX_I64) {
+ // TABLE_INDEX relocs implicitly use the default indirect function table.
+ auto TableName = "__indirect_function_table";
+ MCSymbolWasm *Sym = cast_or_null<MCSymbolWasm>(Ctx.lookupSymbol(TableName));
+ if (Sym) {
+ if (!Sym->isFunctionTable())
+ Ctx.reportError(
+ Fixup.getLoc(),
+ "symbol '__indirect_function_table' is not a function table");
+ } else {
+ Sym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(TableName));
+ Sym->setFunctionTable();
+ // The default function table is synthesized by the linker.
+ Sym->setUndefined();
+ }
+ Sym->setUsedInReloc();
+ Asm.registerSymbol(*Sym);
+ }
+
// Relocation other than R_WASM_TYPE_INDEX_LEB are required to be
// against a named symbol.
if (Type != wasm::R_WASM_TYPE_INDEX_LEB) {
@@ -566,9 +566,9 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry,
switch (RelEntry.Type) {
case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
case wasm::R_WASM_TABLE_INDEX_SLEB:
- case wasm::R_WASM_TABLE_INDEX_SLEB64:
- case wasm::R_WASM_TABLE_INDEX_I32:
- case wasm::R_WASM_TABLE_INDEX_I64: {
+ case wasm::R_WASM_TABLE_INDEX_SLEB64:
+ case wasm::R_WASM_TABLE_INDEX_I32:
+ case wasm::R_WASM_TABLE_INDEX_I64: {
// Provisional value is table address of the resolved symbol itself
const MCSymbolWasm *Base =
cast<MCSymbolWasm>(Layout.getBaseSymbol(*RelEntry.Symbol));
@@ -585,12 +585,12 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry,
case wasm::R_WASM_GLOBAL_INDEX_LEB:
case wasm::R_WASM_GLOBAL_INDEX_I32:
case wasm::R_WASM_EVENT_INDEX_LEB:
- case wasm::R_WASM_TABLE_NUMBER_LEB:
+ case wasm::R_WASM_TABLE_NUMBER_LEB:
// Provisional value is function/global/event Wasm index
assert(WasmIndices.count(RelEntry.Symbol) > 0 && "symbol not found in wasm index space");
return WasmIndices[RelEntry.Symbol];
case wasm::R_WASM_FUNCTION_OFFSET_I32:
- case wasm::R_WASM_FUNCTION_OFFSET_I64:
+ case wasm::R_WASM_FUNCTION_OFFSET_I64:
case wasm::R_WASM_SECTION_OFFSET_I32: {
const auto &Section =
static_cast<const MCSectionWasm &>(RelEntry.Symbol->getSection());
@@ -603,19 +603,19 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry,
case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64:
case wasm::R_WASM_MEMORY_ADDR_I32:
- case wasm::R_WASM_MEMORY_ADDR_I64:
- case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB: {
- // Provisional value is address of the global plus the offset
+ case wasm::R_WASM_MEMORY_ADDR_I64:
+ case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB: {
+ // Provisional value is address of the global plus the offset
const MCSymbolWasm *Base =
cast<MCSymbolWasm>(Layout.getBaseSymbol(*RelEntry.Symbol));
// For undefined symbols, use zero
if (!Base->isDefined())
return 0;
- const wasm::WasmDataReference &BaseRef = DataLocations[Base],
- &SymRef = DataLocations[RelEntry.Symbol];
- const WasmDataSegment &Segment = DataSegments[BaseRef.Segment];
+ const wasm::WasmDataReference &BaseRef = DataLocations[Base],
+ &SymRef = DataLocations[RelEntry.Symbol];
+ const WasmDataSegment &Segment = DataSegments[BaseRef.Segment];
// Ignore overflow. LLVM allows address arithmetic to silently wrap.
- return Segment.Offset + BaseRef.Offset + SymRef.Offset + RelEntry.Addend;
+ return Segment.Offset + BaseRef.Offset + SymRef.Offset + RelEntry.Addend;
}
default:
llvm_unreachable("invalid relocation type");
@@ -649,11 +649,11 @@ static void addData(SmallVectorImpl<char> &DataBytes,
Fill->getValue());
} else if (auto *LEB = dyn_cast<MCLEBFragment>(&Frag)) {
const SmallVectorImpl<char> &Contents = LEB->getContents();
- llvm::append_range(DataBytes, Contents);
+ llvm::append_range(DataBytes, Contents);
} else {
const auto &DataFrag = cast<MCDataFragment>(Frag);
const SmallVectorImpl<char> &Contents = DataFrag.getContents();
- llvm::append_range(DataBytes, Contents);
+ llvm::append_range(DataBytes, Contents);
}
}
@@ -677,7 +677,7 @@ WasmObjectWriter::getRelocationIndexValue(const WasmRelocationEntry &RelEntry) {
void WasmObjectWriter::applyRelocations(
ArrayRef<WasmRelocationEntry> Relocations, uint64_t ContentsOffset,
const MCAsmLayout &Layout) {
- auto &Stream = static_cast<raw_pwrite_stream &>(W->OS);
+ auto &Stream = static_cast<raw_pwrite_stream &>(W->OS);
for (const WasmRelocationEntry &RelEntry : Relocations) {
uint64_t Offset = ContentsOffset +
RelEntry.FixupSection->getSectionOffset() +
@@ -692,7 +692,7 @@ void WasmObjectWriter::applyRelocations(
case wasm::R_WASM_GLOBAL_INDEX_LEB:
case wasm::R_WASM_MEMORY_ADDR_LEB:
case wasm::R_WASM_EVENT_INDEX_LEB:
- case wasm::R_WASM_TABLE_NUMBER_LEB:
+ case wasm::R_WASM_TABLE_NUMBER_LEB:
writePatchableLEB<5>(Stream, Value, Offset);
break;
case wasm::R_WASM_MEMORY_ADDR_LEB64:
@@ -705,19 +705,19 @@ void WasmObjectWriter::applyRelocations(
case wasm::R_WASM_GLOBAL_INDEX_I32:
patchI32(Stream, Value, Offset);
break;
- case wasm::R_WASM_TABLE_INDEX_I64:
+ case wasm::R_WASM_TABLE_INDEX_I64:
case wasm::R_WASM_MEMORY_ADDR_I64:
- case wasm::R_WASM_FUNCTION_OFFSET_I64:
+ case wasm::R_WASM_FUNCTION_OFFSET_I64:
patchI64(Stream, Value, Offset);
break;
case wasm::R_WASM_TABLE_INDEX_SLEB:
case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
case wasm::R_WASM_MEMORY_ADDR_SLEB:
case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
- case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB:
+ case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB:
writePatchableSLEB<5>(Stream, Value, Offset);
break;
- case wasm::R_WASM_TABLE_INDEX_SLEB64:
+ case wasm::R_WASM_TABLE_INDEX_SLEB64:
case wasm::R_WASM_MEMORY_ADDR_SLEB64:
case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64:
writePatchableSLEB<10>(Stream, Value, Offset);
@@ -728,22 +728,22 @@ void WasmObjectWriter::applyRelocations(
}
}
-void WasmObjectWriter::writeTypeSection(
- ArrayRef<wasm::WasmSignature> Signatures) {
+void WasmObjectWriter::writeTypeSection(
+ ArrayRef<wasm::WasmSignature> Signatures) {
if (Signatures.empty())
return;
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_TYPE);
- encodeULEB128(Signatures.size(), W->OS);
+ encodeULEB128(Signatures.size(), W->OS);
- for (const wasm::WasmSignature &Sig : Signatures) {
- W->OS << char(wasm::WASM_TYPE_FUNC);
- encodeULEB128(Sig.Params.size(), W->OS);
+ for (const wasm::WasmSignature &Sig : Signatures) {
+ W->OS << char(wasm::WASM_TYPE_FUNC);
+ encodeULEB128(Sig.Params.size(), W->OS);
for (wasm::ValType Ty : Sig.Params)
writeValueType(Ty);
- encodeULEB128(Sig.Returns.size(), W->OS);
+ encodeULEB128(Sig.Returns.size(), W->OS);
for (wasm::ValType Ty : Sig.Returns)
writeValueType(Ty);
}
@@ -762,32 +762,32 @@ void WasmObjectWriter::writeImportSection(ArrayRef<wasm::WasmImport> Imports,
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_IMPORT);
- encodeULEB128(Imports.size(), W->OS);
+ encodeULEB128(Imports.size(), W->OS);
for (const wasm::WasmImport &Import : Imports) {
writeString(Import.Module);
writeString(Import.Field);
- W->OS << char(Import.Kind);
+ W->OS << char(Import.Kind);
switch (Import.Kind) {
case wasm::WASM_EXTERNAL_FUNCTION:
- encodeULEB128(Import.SigIndex, W->OS);
+ encodeULEB128(Import.SigIndex, W->OS);
break;
case wasm::WASM_EXTERNAL_GLOBAL:
- W->OS << char(Import.Global.Type);
- W->OS << char(Import.Global.Mutable ? 1 : 0);
+ W->OS << char(Import.Global.Type);
+ W->OS << char(Import.Global.Mutable ? 1 : 0);
break;
case wasm::WASM_EXTERNAL_MEMORY:
- encodeULEB128(Import.Memory.Flags, W->OS);
- encodeULEB128(NumPages, W->OS); // initial
+ encodeULEB128(Import.Memory.Flags, W->OS);
+ encodeULEB128(NumPages, W->OS); // initial
break;
case wasm::WASM_EXTERNAL_TABLE:
- W->OS << char(Import.Table.ElemType);
- encodeULEB128(0, W->OS); // flags
- encodeULEB128(NumElements, W->OS); // initial
+ W->OS << char(Import.Table.ElemType);
+ encodeULEB128(0, W->OS); // flags
+ encodeULEB128(NumElements, W->OS); // initial
break;
case wasm::WASM_EXTERNAL_EVENT:
- encodeULEB128(Import.Event.Attribute, W->OS);
- encodeULEB128(Import.Event.SigIndex, W->OS);
+ encodeULEB128(Import.Event.Attribute, W->OS);
+ encodeULEB128(Import.Event.SigIndex, W->OS);
break;
default:
llvm_unreachable("unsupported import kind");
@@ -804,9 +804,9 @@ void WasmObjectWriter::writeFunctionSection(ArrayRef<WasmFunction> Functions) {
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_FUNCTION);
- encodeULEB128(Functions.size(), W->OS);
+ encodeULEB128(Functions.size(), W->OS);
for (const WasmFunction &Func : Functions)
- encodeULEB128(Func.SigIndex, W->OS);
+ encodeULEB128(Func.SigIndex, W->OS);
endSection(Section);
}
@@ -818,10 +818,10 @@ void WasmObjectWriter::writeEventSection(ArrayRef<wasm::WasmEventType> Events) {
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_EVENT);
- encodeULEB128(Events.size(), W->OS);
+ encodeULEB128(Events.size(), W->OS);
for (const wasm::WasmEventType &Event : Events) {
- encodeULEB128(Event.Attribute, W->OS);
- encodeULEB128(Event.SigIndex, W->OS);
+ encodeULEB128(Event.Attribute, W->OS);
+ encodeULEB128(Event.SigIndex, W->OS);
}
endSection(Section);
@@ -834,17 +834,17 @@ void WasmObjectWriter::writeGlobalSection(ArrayRef<wasm::WasmGlobal> Globals) {
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_GLOBAL);
- encodeULEB128(Globals.size(), W->OS);
+ encodeULEB128(Globals.size(), W->OS);
for (const wasm::WasmGlobal &Global : Globals) {
- encodeULEB128(Global.Type.Type, W->OS);
- W->OS << char(Global.Type.Mutable);
- W->OS << char(Global.InitExpr.Opcode);
+ encodeULEB128(Global.Type.Type, W->OS);
+ W->OS << char(Global.Type.Mutable);
+ W->OS << char(Global.InitExpr.Opcode);
switch (Global.Type.Type) {
case wasm::WASM_TYPE_I32:
- encodeSLEB128(0, W->OS);
+ encodeSLEB128(0, W->OS);
break;
case wasm::WASM_TYPE_I64:
- encodeSLEB128(0, W->OS);
+ encodeSLEB128(0, W->OS);
break;
case wasm::WASM_TYPE_F32:
writeI32(0);
@@ -858,30 +858,30 @@ void WasmObjectWriter::writeGlobalSection(ArrayRef<wasm::WasmGlobal> Globals) {
default:
llvm_unreachable("unexpected type");
}
- W->OS << char(wasm::WASM_OPCODE_END);
+ W->OS << char(wasm::WASM_OPCODE_END);
}
endSection(Section);
}
-void WasmObjectWriter::writeTableSection(ArrayRef<wasm::WasmTable> Tables) {
- if (Tables.empty())
- return;
-
- SectionBookkeeping Section;
- startSection(Section, wasm::WASM_SEC_TABLE);
-
- encodeULEB128(Tables.size(), W->OS);
- for (const wasm::WasmTable &Table : Tables) {
- encodeULEB128(Table.Type.ElemType, W->OS);
- encodeULEB128(Table.Type.Limits.Flags, W->OS);
- encodeULEB128(Table.Type.Limits.Initial, W->OS);
- if (Table.Type.Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
- encodeULEB128(Table.Type.Limits.Maximum, W->OS);
- }
- endSection(Section);
-}
-
+void WasmObjectWriter::writeTableSection(ArrayRef<wasm::WasmTable> Tables) {
+ if (Tables.empty())
+ return;
+
+ SectionBookkeeping Section;
+ startSection(Section, wasm::WASM_SEC_TABLE);
+
+ encodeULEB128(Tables.size(), W->OS);
+ for (const wasm::WasmTable &Table : Tables) {
+ encodeULEB128(Table.Type.ElemType, W->OS);
+ encodeULEB128(Table.Type.Limits.Flags, W->OS);
+ encodeULEB128(Table.Type.Limits.Initial, W->OS);
+ if (Table.Type.Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
+ encodeULEB128(Table.Type.Limits.Maximum, W->OS);
+ }
+ endSection(Section);
+}
+
void WasmObjectWriter::writeExportSection(ArrayRef<wasm::WasmExport> Exports) {
if (Exports.empty())
return;
@@ -889,11 +889,11 @@ void WasmObjectWriter::writeExportSection(ArrayRef<wasm::WasmExport> Exports) {
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_EXPORT);
- encodeULEB128(Exports.size(), W->OS);
+ encodeULEB128(Exports.size(), W->OS);
for (const wasm::WasmExport &Export : Exports) {
writeString(Export.Name);
- W->OS << char(Export.Kind);
- encodeULEB128(Export.Index, W->OS);
+ W->OS << char(Export.Kind);
+ encodeULEB128(Export.Index, W->OS);
}
endSection(Section);
@@ -906,17 +906,17 @@ void WasmObjectWriter::writeElemSection(ArrayRef<uint32_t> TableElems) {
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_ELEM);
- encodeULEB128(1, W->OS); // number of "segments"
- encodeULEB128(0, W->OS); // the table index
+ encodeULEB128(1, W->OS); // number of "segments"
+ encodeULEB128(0, W->OS); // the table index
// init expr for starting offset
- W->OS << char(wasm::WASM_OPCODE_I32_CONST);
- encodeSLEB128(InitialTableOffset, W->OS);
- W->OS << char(wasm::WASM_OPCODE_END);
+ W->OS << char(wasm::WASM_OPCODE_I32_CONST);
+ encodeSLEB128(InitialTableOffset, W->OS);
+ W->OS << char(wasm::WASM_OPCODE_END);
- encodeULEB128(TableElems.size(), W->OS);
+ encodeULEB128(TableElems.size(), W->OS);
for (uint32_t Elem : TableElems)
- encodeULEB128(Elem, W->OS);
+ encodeULEB128(Elem, W->OS);
endSection(Section);
}
@@ -927,7 +927,7 @@ void WasmObjectWriter::writeDataCountSection() {
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_DATACOUNT);
- encodeULEB128(DataSegments.size(), W->OS);
+ encodeULEB128(DataSegments.size(), W->OS);
endSection(Section);
}
@@ -940,7 +940,7 @@ uint32_t WasmObjectWriter::writeCodeSection(const MCAssembler &Asm,
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_CODE);
- encodeULEB128(Functions.size(), W->OS);
+ encodeULEB128(Functions.size(), W->OS);
for (const WasmFunction &Func : Functions) {
auto &FuncSection = static_cast<MCSectionWasm &>(Func.Sym->getSection());
@@ -949,9 +949,9 @@ uint32_t WasmObjectWriter::writeCodeSection(const MCAssembler &Asm,
if (!Func.Sym->getSize()->evaluateAsAbsolute(Size, Layout))
report_fatal_error(".size expression must be evaluatable");
- encodeULEB128(Size, W->OS);
- FuncSection.setSectionOffset(W->OS.tell() - Section.ContentsOffset);
- Asm.writeSectionData(W->OS, &FuncSection, Layout);
+ encodeULEB128(Size, W->OS);
+ FuncSection.setSectionOffset(W->OS.tell() - Section.ContentsOffset);
+ Asm.writeSectionData(W->OS, &FuncSection, Layout);
}
// Apply fixups.
@@ -968,21 +968,21 @@ uint32_t WasmObjectWriter::writeDataSection(const MCAsmLayout &Layout) {
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_DATA);
- encodeULEB128(DataSegments.size(), W->OS); // count
+ encodeULEB128(DataSegments.size(), W->OS); // count
for (const WasmDataSegment &Segment : DataSegments) {
- encodeULEB128(Segment.InitFlags, W->OS); // flags
- if (Segment.InitFlags & wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX)
- encodeULEB128(0, W->OS); // memory index
- if ((Segment.InitFlags & wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0) {
- W->OS << char(Segment.Offset > INT32_MAX ? wasm::WASM_OPCODE_I64_CONST
- : wasm::WASM_OPCODE_I32_CONST);
- encodeSLEB128(Segment.Offset, W->OS); // offset
- W->OS << char(wasm::WASM_OPCODE_END);
+ encodeULEB128(Segment.InitFlags, W->OS); // flags
+ if (Segment.InitFlags & wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX)
+ encodeULEB128(0, W->OS); // memory index
+ if ((Segment.InitFlags & wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0) {
+ W->OS << char(Segment.Offset > INT32_MAX ? wasm::WASM_OPCODE_I64_CONST
+ : wasm::WASM_OPCODE_I32_CONST);
+ encodeSLEB128(Segment.Offset, W->OS); // offset
+ W->OS << char(wasm::WASM_OPCODE_END);
}
- encodeULEB128(Segment.Data.size(), W->OS); // size
- Segment.Section->setSectionOffset(W->OS.tell() - Section.ContentsOffset);
- W->OS << Segment.Data; // data
+ encodeULEB128(Segment.Data.size(), W->OS); // size
+ Segment.Section->setSectionOffset(W->OS.tell() - Section.ContentsOffset);
+ W->OS << Segment.Data; // data
}
// Apply fixups.
@@ -1015,18 +1015,18 @@ void WasmObjectWriter::writeRelocSection(
SectionBookkeeping Section;
startCustomSection(Section, std::string("reloc.") + Name.str());
- encodeULEB128(SectionIndex, W->OS);
- encodeULEB128(Relocs.size(), W->OS);
+ encodeULEB128(SectionIndex, W->OS);
+ encodeULEB128(Relocs.size(), W->OS);
for (const WasmRelocationEntry &RelEntry : Relocs) {
uint64_t Offset =
RelEntry.Offset + RelEntry.FixupSection->getSectionOffset();
uint32_t Index = getRelocationIndexValue(RelEntry);
- W->OS << char(RelEntry.Type);
- encodeULEB128(Offset, W->OS);
- encodeULEB128(Index, W->OS);
+ W->OS << char(RelEntry.Type);
+ encodeULEB128(Offset, W->OS);
+ encodeULEB128(Index, W->OS);
if (RelEntry.hasAddend())
- encodeSLEB128(RelEntry.Addend, W->OS);
+ encodeSLEB128(RelEntry.Addend, W->OS);
}
endSection(Section);
@@ -1045,21 +1045,21 @@ void WasmObjectWriter::writeLinkingMetaDataSection(
const std::map<StringRef, std::vector<WasmComdatEntry>> &Comdats) {
SectionBookkeeping Section;
startCustomSection(Section, "linking");
- encodeULEB128(wasm::WasmMetadataVersion, W->OS);
+ encodeULEB128(wasm::WasmMetadataVersion, W->OS);
SectionBookkeeping SubSection;
if (SymbolInfos.size() != 0) {
startSection(SubSection, wasm::WASM_SYMBOL_TABLE);
- encodeULEB128(SymbolInfos.size(), W->OS);
+ encodeULEB128(SymbolInfos.size(), W->OS);
for (const wasm::WasmSymbolInfo &Sym : SymbolInfos) {
- encodeULEB128(Sym.Kind, W->OS);
- encodeULEB128(Sym.Flags, W->OS);
+ encodeULEB128(Sym.Kind, W->OS);
+ encodeULEB128(Sym.Flags, W->OS);
switch (Sym.Kind) {
case wasm::WASM_SYMBOL_TYPE_FUNCTION:
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
case wasm::WASM_SYMBOL_TYPE_EVENT:
- case wasm::WASM_SYMBOL_TYPE_TABLE:
- encodeULEB128(Sym.ElementIndex, W->OS);
+ case wasm::WASM_SYMBOL_TYPE_TABLE:
+ encodeULEB128(Sym.ElementIndex, W->OS);
if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 ||
(Sym.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
writeString(Sym.Name);
@@ -1067,15 +1067,15 @@ void WasmObjectWriter::writeLinkingMetaDataSection(
case wasm::WASM_SYMBOL_TYPE_DATA:
writeString(Sym.Name);
if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
- encodeULEB128(Sym.DataRef.Segment, W->OS);
- encodeULEB128(Sym.DataRef.Offset, W->OS);
- encodeULEB128(Sym.DataRef.Size, W->OS);
+ encodeULEB128(Sym.DataRef.Segment, W->OS);
+ encodeULEB128(Sym.DataRef.Offset, W->OS);
+ encodeULEB128(Sym.DataRef.Size, W->OS);
}
break;
case wasm::WASM_SYMBOL_TYPE_SECTION: {
const uint32_t SectionIndex =
CustomSections[Sym.ElementIndex].OutputIndex;
- encodeULEB128(SectionIndex, W->OS);
+ encodeULEB128(SectionIndex, W->OS);
break;
}
default:
@@ -1087,35 +1087,35 @@ void WasmObjectWriter::writeLinkingMetaDataSection(
if (DataSegments.size()) {
startSection(SubSection, wasm::WASM_SEGMENT_INFO);
- encodeULEB128(DataSegments.size(), W->OS);
+ encodeULEB128(DataSegments.size(), W->OS);
for (const WasmDataSegment &Segment : DataSegments) {
writeString(Segment.Name);
- encodeULEB128(Segment.Alignment, W->OS);
- encodeULEB128(Segment.LinkerFlags, W->OS);
+ encodeULEB128(Segment.Alignment, W->OS);
+ encodeULEB128(Segment.LinkerFlags, W->OS);
}
endSection(SubSection);
}
if (!InitFuncs.empty()) {
startSection(SubSection, wasm::WASM_INIT_FUNCS);
- encodeULEB128(InitFuncs.size(), W->OS);
+ encodeULEB128(InitFuncs.size(), W->OS);
for (auto &StartFunc : InitFuncs) {
- encodeULEB128(StartFunc.first, W->OS); // priority
- encodeULEB128(StartFunc.second, W->OS); // function index
+ encodeULEB128(StartFunc.first, W->OS); // priority
+ encodeULEB128(StartFunc.second, W->OS); // function index
}
endSection(SubSection);
}
if (Comdats.size()) {
startSection(SubSection, wasm::WASM_COMDAT_INFO);
- encodeULEB128(Comdats.size(), W->OS);
+ encodeULEB128(Comdats.size(), W->OS);
for (const auto &C : Comdats) {
writeString(C.first);
- encodeULEB128(0, W->OS); // flags for future use
- encodeULEB128(C.second.size(), W->OS);
+ encodeULEB128(0, W->OS); // flags for future use
+ encodeULEB128(C.second.size(), W->OS);
for (const WasmComdatEntry &Entry : C.second) {
- encodeULEB128(Entry.Kind, W->OS);
- encodeULEB128(Entry.Index, W->OS);
+ encodeULEB128(Entry.Kind, W->OS);
+ encodeULEB128(Entry.Index, W->OS);
}
}
endSection(SubSection);
@@ -1131,8 +1131,8 @@ void WasmObjectWriter::writeCustomSection(WasmCustomSection &CustomSection,
auto *Sec = CustomSection.Section;
startCustomSection(Section, CustomSection.Name);
- Sec->setSectionOffset(W->OS.tell() - Section.ContentsOffset);
- Asm.writeSectionData(W->OS, Sec, Layout);
+ Sec->setSectionOffset(W->OS.tell() - Section.ContentsOffset);
+ Asm.writeSectionData(W->OS, Sec, Layout);
CustomSection.OutputContentsOffset = Section.ContentsOffset;
CustomSection.OutputIndex = Section.Index;
@@ -1159,7 +1159,7 @@ uint32_t WasmObjectWriter::getEventType(const MCSymbolWasm &Symbol) {
void WasmObjectWriter::registerFunctionType(const MCSymbolWasm &Symbol) {
assert(Symbol.isFunction());
- wasm::WasmSignature S;
+ wasm::WasmSignature S;
if (auto *Sig = Symbol.getSignature()) {
S.Returns = Sig->Returns;
@@ -1181,7 +1181,7 @@ void WasmObjectWriter::registerEventType(const MCSymbolWasm &Symbol) {
// TODO Currently we don't generate imported exceptions, but if we do, we
// should have a way of infering types of imported exceptions.
- wasm::WasmSignature S;
+ wasm::WasmSignature S;
if (auto *Sig = Symbol.getSignature()) {
S.Returns = Sig->Returns;
S.Params = Sig->Params;
@@ -1213,9 +1213,9 @@ static bool isInSymtab(const MCSymbolWasm &Sym) {
return true;
}
-void WasmObjectWriter::prepareImports(
- SmallVectorImpl<wasm::WasmImport> &Imports, MCAssembler &Asm,
- const MCAsmLayout &Layout) {
+void WasmObjectWriter::prepareImports(
+ SmallVectorImpl<wasm::WasmImport> &Imports, MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
// For now, always emit the memory import, since loads and stores are not
// valid without it. In the future, we could perhaps be more clever and omit
// it if there are no loads or stores.
@@ -1236,11 +1236,11 @@ void WasmObjectWriter::prepareImports(
// Register types for all functions, including those with private linkage
// (because wasm always needs a type signature).
if (WS.isFunction()) {
- const auto *BS = Layout.getBaseSymbol(S);
- if (!BS)
- report_fatal_error(Twine(S.getName()) +
- ": absolute addressing not supported!");
- registerFunctionType(*cast<MCSymbolWasm>(BS));
+ const auto *BS = Layout.getBaseSymbol(S);
+ if (!BS)
+ report_fatal_error(Twine(S.getName()) +
+ ": absolute addressing not supported!");
+ registerFunctionType(*cast<MCSymbolWasm>(BS));
}
if (WS.isEvent())
@@ -1285,23 +1285,23 @@ void WasmObjectWriter::prepareImports(
Imports.push_back(Import);
assert(WasmIndices.count(&WS) == 0);
WasmIndices[&WS] = NumEventImports++;
- } else if (WS.isTable()) {
- if (WS.isWeak())
- report_fatal_error("undefined table symbol cannot be weak");
-
- wasm::WasmImport Import;
- Import.Module = WS.getImportModule();
- Import.Field = WS.getImportName();
- Import.Kind = wasm::WASM_EXTERNAL_TABLE;
- wasm::ValType ElemType = WS.getTableType();
- Import.Table.ElemType = uint8_t(ElemType);
- // FIXME: Extend table type to include limits? For now we don't specify
- // a min or max which does not place any restrictions on the size of the
- // imported table.
- Import.Table.Limits = {wasm::WASM_LIMITS_FLAG_NONE, 0, 0};
- Imports.push_back(Import);
- assert(WasmIndices.count(&WS) == 0);
- WasmIndices[&WS] = NumTableImports++;
+ } else if (WS.isTable()) {
+ if (WS.isWeak())
+ report_fatal_error("undefined table symbol cannot be weak");
+
+ wasm::WasmImport Import;
+ Import.Module = WS.getImportModule();
+ Import.Field = WS.getImportName();
+ Import.Kind = wasm::WASM_EXTERNAL_TABLE;
+ wasm::ValType ElemType = WS.getTableType();
+ Import.Table.ElemType = uint8_t(ElemType);
+ // FIXME: Extend table type to include limits? For now we don't specify
+ // a min or max which does not place any restrictions on the size of the
+ // imported table.
+ Import.Table.Limits = {wasm::WASM_LIMITS_FLAG_NONE, 0, 0};
+ Imports.push_back(Import);
+ assert(WasmIndices.count(&WS) == 0);
+ WasmIndices[&WS] = NumTableImports++;
}
}
}
@@ -1323,62 +1323,62 @@ void WasmObjectWriter::prepareImports(
GOTIndices[&WS] = NumGlobalImports++;
}
}
-}
-
-uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
- const MCAsmLayout &Layout) {
- support::endian::Writer MainWriter(*OS, support::little);
- W = &MainWriter;
- if (IsSplitDwarf) {
- uint64_t TotalSize = writeOneObject(Asm, Layout, DwoMode::NonDwoOnly);
- assert(DwoOS);
- support::endian::Writer DwoWriter(*DwoOS, support::little);
- W = &DwoWriter;
- return TotalSize + writeOneObject(Asm, Layout, DwoMode::DwoOnly);
- } else {
- return writeOneObject(Asm, Layout, DwoMode::AllSections);
- }
-}
-
-uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
- const MCAsmLayout &Layout,
- DwoMode Mode) {
- uint64_t StartOffset = W->OS.tell();
- SectionCount = 0;
- CustomSections.clear();
-
- LLVM_DEBUG(dbgs() << "WasmObjectWriter::writeObject\n");
-
- // Collect information from the available symbols.
- SmallVector<WasmFunction, 4> Functions;
- SmallVector<uint32_t, 4> TableElems;
- SmallVector<wasm::WasmImport, 4> Imports;
- SmallVector<wasm::WasmExport, 4> Exports;
- SmallVector<wasm::WasmEventType, 1> Events;
- SmallVector<wasm::WasmGlobal, 1> Globals;
- SmallVector<wasm::WasmTable, 1> Tables;
- SmallVector<wasm::WasmSymbolInfo, 4> SymbolInfos;
- SmallVector<std::pair<uint16_t, uint32_t>, 2> InitFuncs;
- std::map<StringRef, std::vector<WasmComdatEntry>> Comdats;
- uint64_t DataSize = 0;
- if (Mode != DwoMode::DwoOnly) {
- prepareImports(Imports, Asm, Layout);
- }
-
+}
+
+uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+ support::endian::Writer MainWriter(*OS, support::little);
+ W = &MainWriter;
+ if (IsSplitDwarf) {
+ uint64_t TotalSize = writeOneObject(Asm, Layout, DwoMode::NonDwoOnly);
+ assert(DwoOS);
+ support::endian::Writer DwoWriter(*DwoOS, support::little);
+ W = &DwoWriter;
+ return TotalSize + writeOneObject(Asm, Layout, DwoMode::DwoOnly);
+ } else {
+ return writeOneObject(Asm, Layout, DwoMode::AllSections);
+ }
+}
+
+uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ DwoMode Mode) {
+ uint64_t StartOffset = W->OS.tell();
+ SectionCount = 0;
+ CustomSections.clear();
+
+ LLVM_DEBUG(dbgs() << "WasmObjectWriter::writeObject\n");
+
+ // Collect information from the available symbols.
+ SmallVector<WasmFunction, 4> Functions;
+ SmallVector<uint32_t, 4> TableElems;
+ SmallVector<wasm::WasmImport, 4> Imports;
+ SmallVector<wasm::WasmExport, 4> Exports;
+ SmallVector<wasm::WasmEventType, 1> Events;
+ SmallVector<wasm::WasmGlobal, 1> Globals;
+ SmallVector<wasm::WasmTable, 1> Tables;
+ SmallVector<wasm::WasmSymbolInfo, 4> SymbolInfos;
+ SmallVector<std::pair<uint16_t, uint32_t>, 2> InitFuncs;
+ std::map<StringRef, std::vector<WasmComdatEntry>> Comdats;
+ uint64_t DataSize = 0;
+ if (Mode != DwoMode::DwoOnly) {
+ prepareImports(Imports, Asm, Layout);
+ }
+
// Populate DataSegments and CustomSections, which must be done before
// populating DataLocations.
for (MCSection &Sec : Asm) {
auto &Section = static_cast<MCSectionWasm &>(Sec);
StringRef SectionName = Section.getName();
- if (Mode == DwoMode::NonDwoOnly && isDwoSection(Sec))
- continue;
- if (Mode == DwoMode::DwoOnly && !isDwoSection(Sec))
- continue;
-
- LLVM_DEBUG(dbgs() << "Processing Section " << SectionName << " group "
- << Section.getGroup() << "\n";);
-
+ if (Mode == DwoMode::NonDwoOnly && isDwoSection(Sec))
+ continue;
+ if (Mode == DwoMode::DwoOnly && !isDwoSection(Sec))
+ continue;
+
+ LLVM_DEBUG(dbgs() << "Processing Section " << SectionName << " group "
+ << Section.getGroup() << "\n";);
+
// .init_array sections are handled specially elsewhere.
if (SectionName.startswith(".init_array"))
continue;
@@ -1393,9 +1393,9 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
DataSegments.emplace_back();
WasmDataSegment &Segment = DataSegments.back();
Segment.Name = SectionName;
- Segment.InitFlags = Section.getPassive()
- ? (uint32_t)wasm::WASM_DATA_SEGMENT_IS_PASSIVE
- : 0;
+ Segment.InitFlags = Section.getPassive()
+ ? (uint32_t)wasm::WASM_DATA_SEGMENT_IS_PASSIVE
+ : 0;
Segment.Offset = DataSize;
Segment.Section = &Section;
addData(Segment.Data, Section);
@@ -1420,7 +1420,7 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
MCSymbol *Begin = Sec.getBeginSymbol();
if (Begin) {
- assert(WasmIndices.count(cast<MCSymbolWasm>(Begin)) == 0);
+ assert(WasmIndices.count(cast<MCSymbolWasm>(Begin)) == 0);
WasmIndices[cast<MCSymbolWasm>(Begin)] = CustomSections.size();
}
@@ -1435,232 +1435,232 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
continue;
}
- // Custom sections can also belong to COMDAT groups. In this case the
- // decriptor's "index" field is the section index (in the final object
- // file), but that is not known until after layout, so it must be fixed up
- // later
- if (const MCSymbolWasm *C = Section.getGroup()) {
- Comdats[C->getName()].emplace_back(
- WasmComdatEntry{wasm::WASM_COMDAT_SECTION,
- static_cast<uint32_t>(CustomSections.size())});
- }
-
+ // Custom sections can also belong to COMDAT groups. In this case the
+ // decriptor's "index" field is the section index (in the final object
+ // file), but that is not known until after layout, so it must be fixed up
+ // later
+ if (const MCSymbolWasm *C = Section.getGroup()) {
+ Comdats[C->getName()].emplace_back(
+ WasmComdatEntry{wasm::WASM_COMDAT_SECTION,
+ static_cast<uint32_t>(CustomSections.size())});
+ }
+
CustomSections.emplace_back(Name, &Section);
}
}
- if (Mode != DwoMode::DwoOnly) {
- // Populate WasmIndices and DataLocations for defined symbols.
- for (const MCSymbol &S : Asm.symbols()) {
- // Ignore unnamed temporary symbols, which aren't ever exported, imported,
- // or used in relocations.
- if (S.isTemporary() && S.getName().empty())
- continue;
-
- const auto &WS = static_cast<const MCSymbolWasm &>(S);
- LLVM_DEBUG(
- dbgs() << "MCSymbol: " << toString(WS.getType()) << " '" << S << "'"
- << " isDefined=" << S.isDefined() << " isExternal="
- << S.isExternal() << " isTemporary=" << S.isTemporary()
- << " isWeak=" << WS.isWeak() << " isHidden=" << WS.isHidden()
- << " isVariable=" << WS.isVariable() << "\n");
-
- if (WS.isVariable())
- continue;
- if (WS.isComdat() && !WS.isDefined())
- continue;
-
- if (WS.isFunction()) {
- unsigned Index;
- if (WS.isDefined()) {
- if (WS.getOffset() != 0)
- report_fatal_error(
- "function sections must contain one function each");
-
- if (WS.getSize() == nullptr)
- report_fatal_error(
- "function symbols must have a size set with .size");
-
- // A definition. Write out the function body.
- Index = NumFunctionImports + Functions.size();
- WasmFunction Func;
- Func.SigIndex = getFunctionType(WS);
- Func.Sym = &WS;
- assert(WasmIndices.count(&WS) == 0);
- WasmIndices[&WS] = Index;
- Functions.push_back(Func);
-
- auto &Section = static_cast<MCSectionWasm &>(WS.getSection());
- if (const MCSymbolWasm *C = Section.getGroup()) {
- Comdats[C->getName()].emplace_back(
- WasmComdatEntry{wasm::WASM_COMDAT_FUNCTION, Index});
- }
-
- if (WS.hasExportName()) {
- wasm::WasmExport Export;
- Export.Name = WS.getExportName();
- Export.Kind = wasm::WASM_EXTERNAL_FUNCTION;
- Export.Index = Index;
- Exports.push_back(Export);
- }
- } else {
- // An import; the index was assigned above.
- Index = WasmIndices.find(&WS)->second;
+ if (Mode != DwoMode::DwoOnly) {
+ // Populate WasmIndices and DataLocations for defined symbols.
+ for (const MCSymbol &S : Asm.symbols()) {
+ // Ignore unnamed temporary symbols, which aren't ever exported, imported,
+ // or used in relocations.
+ if (S.isTemporary() && S.getName().empty())
+ continue;
+
+ const auto &WS = static_cast<const MCSymbolWasm &>(S);
+ LLVM_DEBUG(
+ dbgs() << "MCSymbol: " << toString(WS.getType()) << " '" << S << "'"
+ << " isDefined=" << S.isDefined() << " isExternal="
+ << S.isExternal() << " isTemporary=" << S.isTemporary()
+ << " isWeak=" << WS.isWeak() << " isHidden=" << WS.isHidden()
+ << " isVariable=" << WS.isVariable() << "\n");
+
+ if (WS.isVariable())
+ continue;
+ if (WS.isComdat() && !WS.isDefined())
+ continue;
+
+ if (WS.isFunction()) {
+ unsigned Index;
+ if (WS.isDefined()) {
+ if (WS.getOffset() != 0)
+ report_fatal_error(
+ "function sections must contain one function each");
+
+ if (WS.getSize() == nullptr)
+ report_fatal_error(
+ "function symbols must have a size set with .size");
+
+ // A definition. Write out the function body.
+ Index = NumFunctionImports + Functions.size();
+ WasmFunction Func;
+ Func.SigIndex = getFunctionType(WS);
+ Func.Sym = &WS;
+ assert(WasmIndices.count(&WS) == 0);
+ WasmIndices[&WS] = Index;
+ Functions.push_back(Func);
+
+ auto &Section = static_cast<MCSectionWasm &>(WS.getSection());
+ if (const MCSymbolWasm *C = Section.getGroup()) {
+ Comdats[C->getName()].emplace_back(
+ WasmComdatEntry{wasm::WASM_COMDAT_FUNCTION, Index});
+ }
+
+ if (WS.hasExportName()) {
+ wasm::WasmExport Export;
+ Export.Name = WS.getExportName();
+ Export.Kind = wasm::WASM_EXTERNAL_FUNCTION;
+ Export.Index = Index;
+ Exports.push_back(Export);
+ }
+ } else {
+ // An import; the index was assigned above.
+ Index = WasmIndices.find(&WS)->second;
}
- LLVM_DEBUG(dbgs() << " -> function index: " << Index << "\n");
-
- } else if (WS.isData()) {
- if (!isInSymtab(WS))
- continue;
-
- if (!WS.isDefined()) {
- LLVM_DEBUG(dbgs() << " -> segment index: -1"
- << "\n");
- continue;
- }
-
- if (!WS.getSize())
- report_fatal_error("data symbols must have a size set with .size: " +
- WS.getName());
-
- int64_t Size = 0;
- if (!WS.getSize()->evaluateAsAbsolute(Size, Layout))
- report_fatal_error(".size expression must be evaluatable");
-
- auto &DataSection = static_cast<MCSectionWasm &>(WS.getSection());
- if (!DataSection.isWasmData())
- report_fatal_error("data symbols must live in a data section: " +
- WS.getName());
-
- // For each data symbol, export it in the symtab as a reference to the
- // corresponding Wasm data segment.
- wasm::WasmDataReference Ref = wasm::WasmDataReference{
- DataSection.getSegmentIndex(), Layout.getSymbolOffset(WS),
- static_cast<uint64_t>(Size)};
- assert(DataLocations.count(&WS) == 0);
- DataLocations[&WS] = Ref;
- LLVM_DEBUG(dbgs() << " -> segment index: " << Ref.Segment << "\n");
-
- } else if (WS.isGlobal()) {
- // A "true" Wasm global (currently just __stack_pointer)
- if (WS.isDefined()) {
- wasm::WasmGlobal Global;
- Global.Type = WS.getGlobalType();
- Global.Index = NumGlobalImports + Globals.size();
- switch (Global.Type.Type) {
- case wasm::WASM_TYPE_I32:
- Global.InitExpr.Opcode = wasm::WASM_OPCODE_I32_CONST;
- break;
- case wasm::WASM_TYPE_I64:
- Global.InitExpr.Opcode = wasm::WASM_OPCODE_I64_CONST;
- break;
- case wasm::WASM_TYPE_F32:
- Global.InitExpr.Opcode = wasm::WASM_OPCODE_F32_CONST;
- break;
- case wasm::WASM_TYPE_F64:
- Global.InitExpr.Opcode = wasm::WASM_OPCODE_F64_CONST;
- break;
- case wasm::WASM_TYPE_EXTERNREF:
- Global.InitExpr.Opcode = wasm::WASM_OPCODE_REF_NULL;
- break;
- default:
- llvm_unreachable("unexpected type");
- }
- assert(WasmIndices.count(&WS) == 0);
- WasmIndices[&WS] = Global.Index;
- Globals.push_back(Global);
- } else {
- // An import; the index was assigned above
- LLVM_DEBUG(dbgs() << " -> global index: "
- << WasmIndices.find(&WS)->second << "\n");
+ LLVM_DEBUG(dbgs() << " -> function index: " << Index << "\n");
+
+ } else if (WS.isData()) {
+ if (!isInSymtab(WS))
+ continue;
+
+ if (!WS.isDefined()) {
+ LLVM_DEBUG(dbgs() << " -> segment index: -1"
+ << "\n");
+ continue;
}
- } else if (WS.isTable()) {
- if (WS.isDefined()) {
- wasm::WasmTable Table;
- Table.Index = NumTableImports + Tables.size();
- Table.Type.ElemType = static_cast<uint8_t>(WS.getTableType());
- // FIXME: Work on custom limits is ongoing
- Table.Type.Limits = {wasm::WASM_LIMITS_FLAG_NONE, 0, 0};
- assert(WasmIndices.count(&WS) == 0);
- WasmIndices[&WS] = Table.Index;
- Tables.push_back(Table);
- }
- LLVM_DEBUG(dbgs() << " -> table index: "
+
+ if (!WS.getSize())
+ report_fatal_error("data symbols must have a size set with .size: " +
+ WS.getName());
+
+ int64_t Size = 0;
+ if (!WS.getSize()->evaluateAsAbsolute(Size, Layout))
+ report_fatal_error(".size expression must be evaluatable");
+
+ auto &DataSection = static_cast<MCSectionWasm &>(WS.getSection());
+ if (!DataSection.isWasmData())
+ report_fatal_error("data symbols must live in a data section: " +
+ WS.getName());
+
+ // For each data symbol, export it in the symtab as a reference to the
+ // corresponding Wasm data segment.
+ wasm::WasmDataReference Ref = wasm::WasmDataReference{
+ DataSection.getSegmentIndex(), Layout.getSymbolOffset(WS),
+ static_cast<uint64_t>(Size)};
+ assert(DataLocations.count(&WS) == 0);
+ DataLocations[&WS] = Ref;
+ LLVM_DEBUG(dbgs() << " -> segment index: " << Ref.Segment << "\n");
+
+ } else if (WS.isGlobal()) {
+ // A "true" Wasm global (currently just __stack_pointer)
+ if (WS.isDefined()) {
+ wasm::WasmGlobal Global;
+ Global.Type = WS.getGlobalType();
+ Global.Index = NumGlobalImports + Globals.size();
+ switch (Global.Type.Type) {
+ case wasm::WASM_TYPE_I32:
+ Global.InitExpr.Opcode = wasm::WASM_OPCODE_I32_CONST;
+ break;
+ case wasm::WASM_TYPE_I64:
+ Global.InitExpr.Opcode = wasm::WASM_OPCODE_I64_CONST;
+ break;
+ case wasm::WASM_TYPE_F32:
+ Global.InitExpr.Opcode = wasm::WASM_OPCODE_F32_CONST;
+ break;
+ case wasm::WASM_TYPE_F64:
+ Global.InitExpr.Opcode = wasm::WASM_OPCODE_F64_CONST;
+ break;
+ case wasm::WASM_TYPE_EXTERNREF:
+ Global.InitExpr.Opcode = wasm::WASM_OPCODE_REF_NULL;
+ break;
+ default:
+ llvm_unreachable("unexpected type");
+ }
+ assert(WasmIndices.count(&WS) == 0);
+ WasmIndices[&WS] = Global.Index;
+ Globals.push_back(Global);
+ } else {
+ // An import; the index was assigned above
+ LLVM_DEBUG(dbgs() << " -> global index: "
+ << WasmIndices.find(&WS)->second << "\n");
+ }
+ } else if (WS.isTable()) {
+ if (WS.isDefined()) {
+ wasm::WasmTable Table;
+ Table.Index = NumTableImports + Tables.size();
+ Table.Type.ElemType = static_cast<uint8_t>(WS.getTableType());
+ // FIXME: Work on custom limits is ongoing
+ Table.Type.Limits = {wasm::WASM_LIMITS_FLAG_NONE, 0, 0};
+ assert(WasmIndices.count(&WS) == 0);
+ WasmIndices[&WS] = Table.Index;
+ Tables.push_back(Table);
+ }
+ LLVM_DEBUG(dbgs() << " -> table index: "
<< WasmIndices.find(&WS)->second << "\n");
- } else if (WS.isEvent()) {
- // C++ exception symbol (__cpp_exception)
- unsigned Index;
- if (WS.isDefined()) {
- Index = NumEventImports + Events.size();
- wasm::WasmEventType Event;
- Event.SigIndex = getEventType(WS);
- Event.Attribute = wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION;
- assert(WasmIndices.count(&WS) == 0);
- WasmIndices[&WS] = Index;
- Events.push_back(Event);
- } else {
- // An import; the index was assigned above.
- assert(WasmIndices.count(&WS) > 0);
- }
- LLVM_DEBUG(dbgs() << " -> event index: "
- << WasmIndices.find(&WS)->second << "\n");
-
+ } else if (WS.isEvent()) {
+ // C++ exception symbol (__cpp_exception)
+ unsigned Index;
+ if (WS.isDefined()) {
+ Index = NumEventImports + Events.size();
+ wasm::WasmEventType Event;
+ Event.SigIndex = getEventType(WS);
+ Event.Attribute = wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION;
+ assert(WasmIndices.count(&WS) == 0);
+ WasmIndices[&WS] = Index;
+ Events.push_back(Event);
+ } else {
+ // An import; the index was assigned above.
+ assert(WasmIndices.count(&WS) > 0);
+ }
+ LLVM_DEBUG(dbgs() << " -> event index: "
+ << WasmIndices.find(&WS)->second << "\n");
+
} else {
- assert(WS.isSection());
+ assert(WS.isSection());
}
}
- // Populate WasmIndices and DataLocations for aliased symbols. We need to
- // process these in a separate pass because we need to have processed the
- // target of the alias before the alias itself and the symbols are not
- // necessarily ordered in this way.
- for (const MCSymbol &S : Asm.symbols()) {
- if (!S.isVariable())
- continue;
-
- assert(S.isDefined());
-
- const auto *BS = Layout.getBaseSymbol(S);
- if (!BS)
- report_fatal_error(Twine(S.getName()) +
- ": absolute addressing not supported!");
- const MCSymbolWasm *Base = cast<MCSymbolWasm>(BS);
-
- // Find the target symbol of this weak alias and export that index
- const auto &WS = static_cast<const MCSymbolWasm &>(S);
- LLVM_DEBUG(dbgs() << WS.getName() << ": weak alias of '" << *Base
- << "'\n");
-
- if (Base->isFunction()) {
- assert(WasmIndices.count(Base) > 0);
- uint32_t WasmIndex = WasmIndices.find(Base)->second;
- assert(WasmIndices.count(&WS) == 0);
- WasmIndices[&WS] = WasmIndex;
- LLVM_DEBUG(dbgs() << " -> index:" << WasmIndex << "\n");
- } else if (Base->isData()) {
- auto &DataSection = static_cast<MCSectionWasm &>(WS.getSection());
- uint64_t Offset = Layout.getSymbolOffset(S);
- int64_t Size = 0;
- // For data symbol alias we use the size of the base symbol as the
- // size of the alias. When an offset from the base is involved this
- // can result in a offset + size goes past the end of the data section
- // which out object format doesn't support. So we must clamp it.
- if (!Base->getSize()->evaluateAsAbsolute(Size, Layout))
- report_fatal_error(".size expression must be evaluatable");
- const WasmDataSegment &Segment =
- DataSegments[DataSection.getSegmentIndex()];
- Size =
- std::min(static_cast<uint64_t>(Size), Segment.Data.size() - Offset);
- wasm::WasmDataReference Ref = wasm::WasmDataReference{
- DataSection.getSegmentIndex(),
- static_cast<uint32_t>(Layout.getSymbolOffset(S)),
- static_cast<uint32_t>(Size)};
- DataLocations[&WS] = Ref;
- LLVM_DEBUG(dbgs() << " -> index:" << Ref.Segment << "\n");
- } else {
- report_fatal_error("don't yet support global/event aliases");
- }
+ // Populate WasmIndices and DataLocations for aliased symbols. We need to
+ // process these in a separate pass because we need to have processed the
+ // target of the alias before the alias itself and the symbols are not
+ // necessarily ordered in this way.
+ for (const MCSymbol &S : Asm.symbols()) {
+ if (!S.isVariable())
+ continue;
+
+ assert(S.isDefined());
+
+ const auto *BS = Layout.getBaseSymbol(S);
+ if (!BS)
+ report_fatal_error(Twine(S.getName()) +
+ ": absolute addressing not supported!");
+ const MCSymbolWasm *Base = cast<MCSymbolWasm>(BS);
+
+ // Find the target symbol of this weak alias and export that index
+ const auto &WS = static_cast<const MCSymbolWasm &>(S);
+ LLVM_DEBUG(dbgs() << WS.getName() << ": weak alias of '" << *Base
+ << "'\n");
+
+ if (Base->isFunction()) {
+ assert(WasmIndices.count(Base) > 0);
+ uint32_t WasmIndex = WasmIndices.find(Base)->second;
+ assert(WasmIndices.count(&WS) == 0);
+ WasmIndices[&WS] = WasmIndex;
+ LLVM_DEBUG(dbgs() << " -> index:" << WasmIndex << "\n");
+ } else if (Base->isData()) {
+ auto &DataSection = static_cast<MCSectionWasm &>(WS.getSection());
+ uint64_t Offset = Layout.getSymbolOffset(S);
+ int64_t Size = 0;
+ // For data symbol alias we use the size of the base symbol as the
+ // size of the alias. When an offset from the base is involved this
+ // can result in a offset + size goes past the end of the data section
+ // which out object format doesn't support. So we must clamp it.
+ if (!Base->getSize()->evaluateAsAbsolute(Size, Layout))
+ report_fatal_error(".size expression must be evaluatable");
+ const WasmDataSegment &Segment =
+ DataSegments[DataSection.getSegmentIndex()];
+ Size =
+ std::min(static_cast<uint64_t>(Size), Segment.Data.size() - Offset);
+ wasm::WasmDataReference Ref = wasm::WasmDataReference{
+ DataSection.getSegmentIndex(),
+ static_cast<uint32_t>(Layout.getSymbolOffset(S)),
+ static_cast<uint32_t>(Size)};
+ DataLocations[&WS] = Ref;
+ LLVM_DEBUG(dbgs() << " -> index:" << Ref.Segment << "\n");
+ } else {
+ report_fatal_error("don't yet support global/event aliases");
+ }
}
}
@@ -1671,10 +1671,10 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
WS.setIndex(InvalidIndex);
continue;
}
- if (WS.isTable() && WS.getName() == "__indirect_function_table") {
- // For the moment, don't emit table symbols -- wasm-ld can't handle them.
- continue;
- }
+ if (WS.isTable() && WS.getName() == "__indirect_function_table") {
+ // For the moment, don't emit table symbols -- wasm-ld can't handle them.
+ continue;
+ }
LLVM_DEBUG(dbgs() << "adding to symtab: " << WS << "\n");
uint32_t Flags = 0;
@@ -1718,9 +1718,9 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
// purely to make the object file's provisional values readable, and is
// ignored by the linker, which re-calculates the relocations itself.
if (Rel.Type != wasm::R_WASM_TABLE_INDEX_I32 &&
- Rel.Type != wasm::R_WASM_TABLE_INDEX_I64 &&
+ Rel.Type != wasm::R_WASM_TABLE_INDEX_I64 &&
Rel.Type != wasm::R_WASM_TABLE_INDEX_SLEB &&
- Rel.Type != wasm::R_WASM_TABLE_INDEX_SLEB64 &&
+ Rel.Type != wasm::R_WASM_TABLE_INDEX_SLEB64 &&
Rel.Type != wasm::R_WASM_TABLE_INDEX_REL_SLEB)
return;
assert(Rel.Symbol->isFunction());
@@ -1810,41 +1810,41 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
// Write out the Wasm header.
writeHeader(Asm);
- uint32_t CodeSectionIndex, DataSectionIndex;
- if (Mode != DwoMode::DwoOnly) {
- writeTypeSection(Signatures);
- writeImportSection(Imports, DataSize, TableElems.size());
- writeFunctionSection(Functions);
- writeTableSection(Tables);
- // Skip the "memory" section; we import the memory instead.
- writeEventSection(Events);
- writeGlobalSection(Globals);
- writeExportSection(Exports);
- writeElemSection(TableElems);
- writeDataCountSection();
-
- CodeSectionIndex = writeCodeSection(Asm, Layout, Functions);
- DataSectionIndex = writeDataSection(Layout);
- }
-
- // The Sections in the COMDAT list have placeholder indices (their index among
- // custom sections, rather than among all sections). Fix them up here.
- for (auto &Group : Comdats) {
- for (auto &Entry : Group.second) {
- if (Entry.Kind == wasm::WASM_COMDAT_SECTION) {
- Entry.Index += SectionCount;
- }
- }
- }
+ uint32_t CodeSectionIndex, DataSectionIndex;
+ if (Mode != DwoMode::DwoOnly) {
+ writeTypeSection(Signatures);
+ writeImportSection(Imports, DataSize, TableElems.size());
+ writeFunctionSection(Functions);
+ writeTableSection(Tables);
+ // Skip the "memory" section; we import the memory instead.
+ writeEventSection(Events);
+ writeGlobalSection(Globals);
+ writeExportSection(Exports);
+ writeElemSection(TableElems);
+ writeDataCountSection();
+
+ CodeSectionIndex = writeCodeSection(Asm, Layout, Functions);
+ DataSectionIndex = writeDataSection(Layout);
+ }
+
+ // The Sections in the COMDAT list have placeholder indices (their index among
+ // custom sections, rather than among all sections). Fix them up here.
+ for (auto &Group : Comdats) {
+ for (auto &Entry : Group.second) {
+ if (Entry.Kind == wasm::WASM_COMDAT_SECTION) {
+ Entry.Index += SectionCount;
+ }
+ }
+ }
for (auto &CustomSection : CustomSections)
writeCustomSection(CustomSection, Asm, Layout);
-
- if (Mode != DwoMode::DwoOnly) {
- writeLinkingMetaDataSection(SymbolInfos, InitFuncs, Comdats);
-
- writeRelocSection(CodeSectionIndex, "CODE", CodeRelocations);
- writeRelocSection(DataSectionIndex, "DATA", DataRelocations);
- }
+
+ if (Mode != DwoMode::DwoOnly) {
+ writeLinkingMetaDataSection(SymbolInfos, InitFuncs, Comdats);
+
+ writeRelocSection(CodeSectionIndex, "CODE", CodeRelocations);
+ writeRelocSection(DataSectionIndex, "DATA", DataRelocations);
+ }
writeCustomRelocSections();
if (ProducersSection)
writeCustomSection(*ProducersSection, Asm, Layout);
@@ -1852,7 +1852,7 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
writeCustomSection(*TargetFeaturesSection, Asm, Layout);
// TODO: Translate the .comment section to the output.
- return W->OS.tell() - StartOffset;
+ return W->OS.tell() - StartOffset;
}
std::unique_ptr<MCObjectWriter>
@@ -1860,10 +1860,10 @@ llvm::createWasmObjectWriter(std::unique_ptr<MCWasmObjectTargetWriter> MOTW,
raw_pwrite_stream &OS) {
return std::make_unique<WasmObjectWriter>(std::move(MOTW), OS);
}
-
-std::unique_ptr<MCObjectWriter>
-llvm::createWasmDwoObjectWriter(std::unique_ptr<MCWasmObjectTargetWriter> MOTW,
- raw_pwrite_stream &OS,
- raw_pwrite_stream &DwoOS) {
- return std::make_unique<WasmObjectWriter>(std::move(MOTW), OS, DwoOS);
-}
+
+std::unique_ptr<MCObjectWriter>
+llvm::createWasmDwoObjectWriter(std::unique_ptr<MCWasmObjectTargetWriter> MOTW,
+ raw_pwrite_stream &OS,
+ raw_pwrite_stream &DwoOS) {
+ return std::make_unique<WasmObjectWriter>(std::move(MOTW), OS, DwoOS);
+}
diff --git a/contrib/libs/llvm12/lib/MC/WinCOFFObjectWriter.cpp b/contrib/libs/llvm12/lib/MC/WinCOFFObjectWriter.cpp
index 08ae059f7e..901d2c06e7 100644
--- a/contrib/libs/llvm12/lib/MC/WinCOFFObjectWriter.cpp
+++ b/contrib/libs/llvm12/lib/MC/WinCOFFObjectWriter.cpp
@@ -353,9 +353,9 @@ COFFSymbol *WinCOFFObjectWriter::getLinkedSymbol(const MCSymbol &Symbol) {
return nullptr;
const MCSymbol &Aliasee = SymRef->getSymbol();
- if (Aliasee.isUndefined() || Aliasee.isExternal())
- return GetOrCreateCOFFSymbol(&Aliasee);
- else
+ if (Aliasee.isUndefined() || Aliasee.isExternal())
+ return GetOrCreateCOFFSymbol(&Aliasee);
+ else
return nullptr;
}
diff --git a/contrib/libs/llvm12/lib/MC/XCOFFObjectWriter.cpp b/contrib/libs/llvm12/lib/MC/XCOFFObjectWriter.cpp
index bec0d1d8da..031eceaadf 100644
--- a/contrib/libs/llvm12/lib/MC/XCOFFObjectWriter.cpp
+++ b/contrib/libs/llvm12/lib/MC/XCOFFObjectWriter.cpp
@@ -138,13 +138,13 @@ struct Section {
Group->clear();
}
- Section(StringRef N, XCOFF::SectionTypeFlags Flags, bool IsVirtual,
+ Section(StringRef N, XCOFF::SectionTypeFlags Flags, bool IsVirtual,
CsectGroups Groups)
- : Name(), Address(0), Size(0), FileOffsetToData(0),
- FileOffsetToRelocations(0), RelocationCount(0), Flags(Flags),
- Index(UninitializedIndex), IsVirtual(IsVirtual), Groups(Groups) {
- assert(N.size() <= XCOFF::NameSize && "section name too long");
- memcpy(Name, N.data(), N.size());
+ : Name(), Address(0), Size(0), FileOffsetToData(0),
+ FileOffsetToRelocations(0), RelocationCount(0), Flags(Flags),
+ Index(UninitializedIndex), IsVirtual(IsVirtual), Groups(Groups) {
+ assert(N.size() <= XCOFF::NameSize && "section name too long");
+ memcpy(Name, N.data(), N.size());
}
};
@@ -305,7 +305,7 @@ CsectGroup &XCOFFObjectWriter::getCsectGroup(const MCSectionXCOFF *MCSec) {
"in this CsectGroup.");
return TOCCsects;
case XCOFF::XMC_TC:
- case XCOFF::XMC_TE:
+ case XCOFF::XMC_TE:
assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
"Only an initialized csect can contain TC entry.");
assert(!TOCCsects.empty() &&
@@ -429,19 +429,19 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
// The FixedValue should be symbol's virtual address in this object file
// plus any constant value that we might get.
FixedValue = getVirtualAddress(SymA, SymASec) + Target.getConstant();
- else if (Type == XCOFF::RelocationType::R_TOC ||
- Type == XCOFF::RelocationType::R_TOCL) {
- // The FixedValue should be the TOC entry offset from the TOC-base plus any
- // constant offset value.
- const int64_t TOCEntryOffset = SectionMap[SymASec]->Address -
- TOCCsects.front().Address +
- Target.getConstant();
- if (Type == XCOFF::RelocationType::R_TOC && !isInt<16>(TOCEntryOffset))
- report_fatal_error("TOCEntryOffset overflows in small code model mode");
-
- FixedValue = TOCEntryOffset;
- }
-
+ else if (Type == XCOFF::RelocationType::R_TOC ||
+ Type == XCOFF::RelocationType::R_TOCL) {
+ // The FixedValue should be the TOC entry offset from the TOC-base plus any
+ // constant offset value.
+ const int64_t TOCEntryOffset = SectionMap[SymASec]->Address -
+ TOCCsects.front().Address +
+ Target.getConstant();
+ if (Type == XCOFF::RelocationType::R_TOC && !isInt<16>(TOCEntryOffset))
+ report_fatal_error("TOCEntryOffset overflows in small code model mode");
+
+ FixedValue = TOCEntryOffset;
+ }
+
assert(
(TargetObjectWriter->is64Bit() ||
Fixup.getOffset() <= UINT32_MAX - Layout.getFragmentOffset(Fragment)) &&
diff --git a/contrib/libs/llvm12/lib/MC/ya.make b/contrib/libs/llvm12/lib/MC/ya.make
index cd151df722..3d136d7426 100644
--- a/contrib/libs/llvm12/lib/MC/ya.make
+++ b/contrib/libs/llvm12/lib/MC/ya.make
@@ -12,10 +12,10 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/DebugInfo/CodeView
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/DebugInfo/CodeView
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
@@ -60,7 +60,7 @@ SRCS(
MCObjectFileInfo.cpp
MCObjectStreamer.cpp
MCObjectWriter.cpp
- MCPseudoProbe.cpp
+ MCPseudoProbe.cpp
MCRegisterInfo.cpp
MCSchedule.cpp
MCSection.cpp
diff --git a/contrib/libs/llvm12/lib/Object/Archive.cpp b/contrib/libs/llvm12/lib/Object/Archive.cpp
index 3883de192f..11c9de4455 100644
--- a/contrib/libs/llvm12/lib/Object/Archive.cpp
+++ b/contrib/libs/llvm12/lib/Object/Archive.cpp
@@ -38,8 +38,8 @@ using namespace llvm;
using namespace object;
using namespace llvm::support::endian;
-const char Magic[] = "!<arch>\n";
-const char ThinMagic[] = "!<thin>\n";
+const char Magic[] = "!<arch>\n";
+const char ThinMagic[] = "!<thin>\n";
void Archive::anchor() {}
diff --git a/contrib/libs/llvm12/lib/Object/ArchiveWriter.cpp b/contrib/libs/llvm12/lib/Object/ArchiveWriter.cpp
index ea3f3929b5..ce997464ca 100644
--- a/contrib/libs/llvm12/lib/Object/ArchiveWriter.cpp
+++ b/contrib/libs/llvm12/lib/Object/ArchiveWriter.cpp
@@ -26,7 +26,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/SmallVectorMemoryBuffer.h"
+#include "llvm/Support/SmallVectorMemoryBuffer.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/raw_ostream.h"
@@ -286,12 +286,12 @@ static void printNBits(raw_ostream &Out, object::Archive::Kind Kind,
print<uint32_t>(Out, Kind, Val);
}
-static uint64_t computeSymbolTableSize(object::Archive::Kind Kind,
- uint64_t NumSyms, uint64_t OffsetSize,
- StringRef StringTable,
- uint32_t *Padding = nullptr) {
- assert((OffsetSize == 4 || OffsetSize == 8) && "Unsupported OffsetSize");
- uint64_t Size = OffsetSize; // Number of entries
+static uint64_t computeSymbolTableSize(object::Archive::Kind Kind,
+ uint64_t NumSyms, uint64_t OffsetSize,
+ StringRef StringTable,
+ uint32_t *Padding = nullptr) {
+ assert((OffsetSize == 4 || OffsetSize == 8) && "Unsupported OffsetSize");
+ uint64_t Size = OffsetSize; // Number of entries
if (isBSDLike(Kind))
Size += NumSyms * OffsetSize * 2; // Table
else
@@ -303,15 +303,15 @@ static uint64_t computeSymbolTableSize(object::Archive::Kind Kind,
// least 4-byte aligned for 32-bit content. Opt for the larger encoding
// uniformly.
// We do this for all bsd formats because it simplifies aligning members.
- uint32_t Pad = offsetToAlignment(Size, Align(isBSDLike(Kind) ? 8 : 2));
+ uint32_t Pad = offsetToAlignment(Size, Align(isBSDLike(Kind) ? 8 : 2));
Size += Pad;
- if (Padding)
- *Padding = Pad;
- return Size;
-}
+ if (Padding)
+ *Padding = Pad;
+ return Size;
+}
-static void writeSymbolTableHeader(raw_ostream &Out, object::Archive::Kind Kind,
- bool Deterministic, uint64_t Size) {
+static void writeSymbolTableHeader(raw_ostream &Out, object::Archive::Kind Kind,
+ bool Deterministic, uint64_t Size) {
if (isBSDLike(Kind)) {
const char *Name = is64BitKind(Kind) ? "__.SYMDEF_64" : "__.SYMDEF";
printBSDMemberHeader(Out, Out.tell(), Name, now(Deterministic), 0, 0, 0,
@@ -320,25 +320,25 @@ static void writeSymbolTableHeader(raw_ostream &Out, object::Archive::Kind Kind,
const char *Name = is64BitKind(Kind) ? "/SYM64" : "";
printGNUSmallMemberHeader(Out, Name, now(Deterministic), 0, 0, 0, Size);
}
-}
-
-static void writeSymbolTable(raw_ostream &Out, object::Archive::Kind Kind,
- bool Deterministic, ArrayRef<MemberData> Members,
- StringRef StringTable) {
- // We don't write a symbol table on an archive with no members -- except on
- // Darwin, where the linker will abort unless the archive has a symbol table.
- if (StringTable.empty() && !isDarwin(Kind))
- return;
-
- unsigned NumSyms = 0;
- for (const MemberData &M : Members)
- NumSyms += M.Symbols.size();
-
- uint64_t OffsetSize = is64BitKind(Kind) ? 8 : 4;
- uint32_t Pad;
- uint64_t Size = computeSymbolTableSize(Kind, NumSyms, OffsetSize, StringTable, &Pad);
- writeSymbolTableHeader(Out, Kind, Deterministic, Size);
-
+}
+
+static void writeSymbolTable(raw_ostream &Out, object::Archive::Kind Kind,
+ bool Deterministic, ArrayRef<MemberData> Members,
+ StringRef StringTable) {
+ // We don't write a symbol table on an archive with no members -- except on
+ // Darwin, where the linker will abort unless the archive has a symbol table.
+ if (StringTable.empty() && !isDarwin(Kind))
+ return;
+
+ unsigned NumSyms = 0;
+ for (const MemberData &M : Members)
+ NumSyms += M.Symbols.size();
+
+ uint64_t OffsetSize = is64BitKind(Kind) ? 8 : 4;
+ uint32_t Pad;
+ uint64_t Size = computeSymbolTableSize(Kind, NumSyms, OffsetSize, StringTable, &Pad);
+ writeSymbolTableHeader(Out, Kind, Deterministic, Size);
+
uint64_t Pos = Out.tell() + Size;
if (isBSDLike(Kind))
@@ -372,21 +372,21 @@ getSymbols(MemoryBufferRef Buf, raw_ostream &SymNames, bool &HasObject) {
// reference to it, thus SymbolicFile should be destroyed first.
LLVMContext Context;
std::unique_ptr<object::SymbolicFile> Obj;
-
- const file_magic Type = identify_magic(Buf.getBuffer());
- // Treat unsupported file types as having no symbols.
- if (!object::SymbolicFile::isSymbolicFile(Type, &Context))
- return Ret;
- if (Type == file_magic::bitcode) {
+
+ const file_magic Type = identify_magic(Buf.getBuffer());
+ // Treat unsupported file types as having no symbols.
+ if (!object::SymbolicFile::isSymbolicFile(Type, &Context))
+ return Ret;
+ if (Type == file_magic::bitcode) {
auto ObjOrErr = object::SymbolicFile::createSymbolicFile(
Buf, file_magic::bitcode, &Context);
- if (!ObjOrErr)
- return ObjOrErr.takeError();
+ if (!ObjOrErr)
+ return ObjOrErr.takeError();
Obj = std::move(*ObjOrErr);
} else {
auto ObjOrErr = object::SymbolicFile::createSymbolicFile(Buf);
- if (!ObjOrErr)
- return ObjOrErr.takeError();
+ if (!ObjOrErr)
+ return ObjOrErr.takeError();
Obj = std::move(*ObjOrErr);
}
@@ -405,7 +405,7 @@ getSymbols(MemoryBufferRef Buf, raw_ostream &SymNames, bool &HasObject) {
static Expected<std::vector<MemberData>>
computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
object::Archive::Kind Kind, bool Thin, bool Deterministic,
- bool NeedSymbols, ArrayRef<NewArchiveMember> NewMembers) {
+ bool NeedSymbols, ArrayRef<NewArchiveMember> NewMembers) {
static char PaddingData[8] = {'\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n'};
// This ignores the symbol table, but we only need the value mod 8 and the
@@ -506,17 +506,17 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
ModTime, Size);
Out.flush();
- std::vector<unsigned> Symbols;
- if (NeedSymbols) {
- Expected<std::vector<unsigned>> SymbolsOrErr =
- getSymbols(Buf, SymNames, HasObject);
- if (auto E = SymbolsOrErr.takeError())
- return std::move(E);
- Symbols = std::move(*SymbolsOrErr);
- }
+ std::vector<unsigned> Symbols;
+ if (NeedSymbols) {
+ Expected<std::vector<unsigned>> SymbolsOrErr =
+ getSymbols(Buf, SymNames, HasObject);
+ if (auto E = SymbolsOrErr.takeError())
+ return std::move(E);
+ Symbols = std::move(*SymbolsOrErr);
+ }
Pos += Header.size() + Data.size() + Padding.size();
- Ret.push_back({std::move(Symbols), std::move(Header), Data, Padding});
+ Ret.push_back({std::move(Symbols), std::move(Header), Data, Padding});
}
// If there are no symbols, emit an empty symbol table, to satisfy Solaris
// tools, older versions of which expect a symbol table in a non-empty
@@ -569,10 +569,10 @@ Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To) {
return std::string(Relative.str());
}
-static Error writeArchiveToStream(raw_ostream &Out,
- ArrayRef<NewArchiveMember> NewMembers,
- bool WriteSymtab, object::Archive::Kind Kind,
- bool Deterministic, bool Thin) {
+static Error writeArchiveToStream(raw_ostream &Out,
+ ArrayRef<NewArchiveMember> NewMembers,
+ bool WriteSymtab, object::Archive::Kind Kind,
+ bool Deterministic, bool Thin) {
assert((!Thin || !isBSDLike(Kind)) && "Only the gnu format has a thin mode");
SmallString<0> SymNamesBuf;
@@ -580,9 +580,9 @@ static Error writeArchiveToStream(raw_ostream &Out,
SmallString<0> StringTableBuf;
raw_svector_ostream StringTable(StringTableBuf);
- Expected<std::vector<MemberData>> DataOrErr =
- computeMemberData(StringTable, SymNames, Kind, Thin, Deterministic,
- WriteSymtab, NewMembers);
+ Expected<std::vector<MemberData>> DataOrErr =
+ computeMemberData(StringTable, SymNames, Kind, Thin, Deterministic,
+ WriteSymtab, NewMembers);
if (Error E = DataOrErr.takeError())
return E;
std::vector<MemberData> &Data = *DataOrErr;
@@ -592,28 +592,28 @@ static Error writeArchiveToStream(raw_ostream &Out,
// We would like to detect if we need to switch to a 64-bit symbol table.
if (WriteSymtab) {
- uint64_t MaxOffset = 8; // For the file signature.
+ uint64_t MaxOffset = 8; // For the file signature.
uint64_t LastOffset = MaxOffset;
- uint64_t NumSyms = 0;
+ uint64_t NumSyms = 0;
for (const auto &M : Data) {
// Record the start of the member's offset
LastOffset = MaxOffset;
// Account for the size of each part associated with the member.
MaxOffset += M.Header.size() + M.Data.size() + M.Padding.size();
- NumSyms += M.Symbols.size();
+ NumSyms += M.Symbols.size();
}
- // We assume 32-bit offsets to see if 32-bit symbols are possible or not.
- uint64_t SymtabSize = computeSymbolTableSize(Kind, NumSyms, 4, SymNamesBuf);
- auto computeSymbolTableHeaderSize =
- [=] {
- SmallString<0> TmpBuf;
- raw_svector_ostream Tmp(TmpBuf);
- writeSymbolTableHeader(Tmp, Kind, Deterministic, SymtabSize);
- return TmpBuf.size();
- };
- LastOffset += computeSymbolTableHeaderSize() + SymtabSize;
-
+ // We assume 32-bit offsets to see if 32-bit symbols are possible or not.
+ uint64_t SymtabSize = computeSymbolTableSize(Kind, NumSyms, 4, SymNamesBuf);
+ auto computeSymbolTableHeaderSize =
+ [=] {
+ SmallString<0> TmpBuf;
+ raw_svector_ostream Tmp(TmpBuf);
+ writeSymbolTableHeader(Tmp, Kind, Deterministic, SymtabSize);
+ return TmpBuf.size();
+ };
+ LastOffset += computeSymbolTableHeaderSize() + SymtabSize;
+
// The SYM64 format is used when an archive's member offsets are larger than
// 32-bits can hold. The need for this shift in format is detected by
// writeArchive. To test this we need to generate a file with a member that
@@ -621,7 +621,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
// speed the test up we use this environment variable to pretend like the
// cutoff happens before 32-bits and instead happens at some much smaller
// value.
- uint64_t Sym64Threshold = 1ULL << 32;
+ uint64_t Sym64Threshold = 1ULL << 32;
const char *Sym64Env = std::getenv("SYM64_THRESHOLD");
if (Sym64Env)
StringRef(Sym64Env).getAsInteger(10, Sym64Threshold);
@@ -629,7 +629,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
// If LastOffset isn't going to fit in a 32-bit varible we need to switch
// to 64-bit. Note that the file can be larger than 4GB as long as the last
// member starts before the 4GB offset.
- if (LastOffset >= Sym64Threshold) {
+ if (LastOffset >= Sym64Threshold) {
if (Kind == object::Archive::K_DARWIN)
Kind = object::Archive::K_DARWIN64;
else
@@ -649,26 +649,26 @@ static Error writeArchiveToStream(raw_ostream &Out,
Out << M.Header << M.Data << M.Padding;
Out.flush();
- return Error::success();
-}
-
-Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
- bool WriteSymtab, object::Archive::Kind Kind,
- bool Deterministic, bool Thin,
- std::unique_ptr<MemoryBuffer> OldArchiveBuf) {
- Expected<sys::fs::TempFile> Temp =
- sys::fs::TempFile::create(ArcName + ".temp-archive-%%%%%%%.a");
- if (!Temp)
- return Temp.takeError();
- raw_fd_ostream Out(Temp->FD, false);
-
- if (Error E = writeArchiveToStream(Out, NewMembers, WriteSymtab, Kind,
- Deterministic, Thin)) {
- if (Error DiscardError = Temp->discard())
- return joinErrors(std::move(E), std::move(DiscardError));
- return E;
- }
-
+ return Error::success();
+}
+
+Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
+ bool WriteSymtab, object::Archive::Kind Kind,
+ bool Deterministic, bool Thin,
+ std::unique_ptr<MemoryBuffer> OldArchiveBuf) {
+ Expected<sys::fs::TempFile> Temp =
+ sys::fs::TempFile::create(ArcName + ".temp-archive-%%%%%%%.a");
+ if (!Temp)
+ return Temp.takeError();
+ raw_fd_ostream Out(Temp->FD, false);
+
+ if (Error E = writeArchiveToStream(Out, NewMembers, WriteSymtab, Kind,
+ Deterministic, Thin)) {
+ if (Error DiscardError = Temp->discard())
+ return joinErrors(std::move(E), std::move(DiscardError));
+ return E;
+ }
+
// At this point, we no longer need whatever backing memory
// was used to generate the NewMembers. On Windows, this buffer
// could be a mapped view of the file we want to replace (if
@@ -684,19 +684,19 @@ Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
return Temp->keep(ArcName);
}
-Expected<std::unique_ptr<MemoryBuffer>>
-writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers, bool WriteSymtab,
- object::Archive::Kind Kind, bool Deterministic,
- bool Thin) {
- SmallVector<char, 0> ArchiveBufferVector;
- raw_svector_ostream ArchiveStream(ArchiveBufferVector);
-
- if (Error E = writeArchiveToStream(ArchiveStream, NewMembers, WriteSymtab,
- Kind, Deterministic, Thin))
- return std::move(E);
-
- return std::make_unique<SmallVectorMemoryBuffer>(
- std::move(ArchiveBufferVector));
-}
-
+Expected<std::unique_ptr<MemoryBuffer>>
+writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers, bool WriteSymtab,
+ object::Archive::Kind Kind, bool Deterministic,
+ bool Thin) {
+ SmallVector<char, 0> ArchiveBufferVector;
+ raw_svector_ostream ArchiveStream(ArchiveBufferVector);
+
+ if (Error E = writeArchiveToStream(ArchiveStream, NewMembers, WriteSymtab,
+ Kind, Deterministic, Thin))
+ return std::move(E);
+
+ return std::make_unique<SmallVectorMemoryBuffer>(
+ std::move(ArchiveBufferVector));
+}
+
} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/Object/Binary.cpp b/contrib/libs/llvm12/lib/Object/Binary.cpp
index 5ed8bd9e79..e741cbba28 100644
--- a/contrib/libs/llvm12/lib/Object/Binary.cpp
+++ b/contrib/libs/llvm12/lib/Object/Binary.cpp
@@ -44,8 +44,8 @@ StringRef Binary::getFileName() const { return Data.getBufferIdentifier(); }
MemoryBufferRef Binary::getMemoryBufferRef() const { return Data; }
Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
- LLVMContext *Context,
- bool InitContent) {
+ LLVMContext *Context,
+ bool InitContent) {
file_magic Type = identify_magic(Buffer.getBuffer());
switch (Type) {
@@ -74,7 +74,7 @@ Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
case file_magic::xcoff_object_32:
case file_magic::xcoff_object_64:
case file_magic::wasm_object:
- return ObjectFile::createSymbolicFile(Buffer, Type, Context, InitContent);
+ return ObjectFile::createSymbolicFile(Buffer, Type, Context, InitContent);
case file_magic::macho_universal_binary:
return MachOUniversalBinary::create(Buffer);
case file_magic::windows_resource:
@@ -94,8 +94,8 @@ Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
llvm_unreachable("Unexpected Binary File Type");
}
-Expected<OwningBinary<Binary>>
-object::createBinary(StringRef Path, LLVMContext *Context, bool InitContent) {
+Expected<OwningBinary<Binary>>
+object::createBinary(StringRef Path, LLVMContext *Context, bool InitContent) {
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
MemoryBuffer::getFileOrSTDIN(Path, /*FileSize=*/-1,
/*RequiresNullTerminator=*/false);
@@ -104,7 +104,7 @@ object::createBinary(StringRef Path, LLVMContext *Context, bool InitContent) {
std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();
Expected<std::unique_ptr<Binary>> BinOrErr =
- createBinary(Buffer->getMemBufferRef(), Context, InitContent);
+ createBinary(Buffer->getMemBufferRef(), Context, InitContent);
if (!BinOrErr)
return BinOrErr.takeError();
std::unique_ptr<Binary> &Bin = BinOrErr.get();
diff --git a/contrib/libs/llvm12/lib/Object/COFFObjectFile.cpp b/contrib/libs/llvm12/lib/Object/COFFObjectFile.cpp
index 43601ed58d..6e9a8eb35d 100644
--- a/contrib/libs/llvm12/lib/Object/COFFObjectFile.cpp
+++ b/contrib/libs/llvm12/lib/Object/COFFObjectFile.cpp
@@ -28,7 +28,7 @@
#include "llvm/Support/MemoryBuffer.h"
#include <algorithm>
#include <cassert>
-#include <cinttypes>
+#include <cinttypes>
#include <cstddef>
#include <cstring>
#include <limits>
@@ -57,7 +57,7 @@ static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size) {
template <typename T>
static Error getObject(const T *&Obj, MemoryBufferRef M, const void *Ptr,
const uint64_t Size = sizeof(T)) {
- uintptr_t Addr = reinterpret_cast<uintptr_t>(Ptr);
+ uintptr_t Addr = reinterpret_cast<uintptr_t>(Ptr);
if (Error E = Binary::checkOffset(M, Addr, Size))
return E;
Obj = reinterpret_cast<const T *>(Addr);
@@ -103,11 +103,11 @@ const coff_symbol_type *COFFObjectFile::toSymb(DataRefImpl Ref) const {
const coff_symbol_type *Addr =
reinterpret_cast<const coff_symbol_type *>(Ref.p);
- assert(!checkOffset(Data, reinterpret_cast<uintptr_t>(Addr), sizeof(*Addr)));
+ assert(!checkOffset(Data, reinterpret_cast<uintptr_t>(Addr), sizeof(*Addr)));
#ifndef NDEBUG
// Verify that the symbol points to a valid entry in the symbol table.
- uintptr_t Offset =
- reinterpret_cast<uintptr_t>(Addr) - reinterpret_cast<uintptr_t>(base());
+ uintptr_t Offset =
+ reinterpret_cast<uintptr_t>(Addr) - reinterpret_cast<uintptr_t>(base());
assert((Offset - getPointerToSymbolTable()) % sizeof(coff_symbol_type) == 0 &&
"Symbol did not point to the beginning of a symbol");
@@ -124,8 +124,8 @@ const coff_section *COFFObjectFile::toSec(DataRefImpl Ref) const {
if (Addr < SectionTable || Addr >= (SectionTable + getNumberOfSections()))
report_fatal_error("Section was outside of section table.");
- uintptr_t Offset = reinterpret_cast<uintptr_t>(Addr) -
- reinterpret_cast<uintptr_t>(SectionTable);
+ uintptr_t Offset = reinterpret_cast<uintptr_t>(Addr) -
+ reinterpret_cast<uintptr_t>(SectionTable);
assert(Offset % sizeof(coff_section) == 0 &&
"Section did not point to the beginning of a section");
#endif
@@ -334,7 +334,7 @@ bool COFFObjectFile::isDebugSection(StringRef SectionName) const {
unsigned COFFObjectFile::getSectionID(SectionRef Sec) const {
uintptr_t Offset =
- Sec.getRawDataRefImpl().p - reinterpret_cast<uintptr_t>(SectionTable);
+ Sec.getRawDataRefImpl().p - reinterpret_cast<uintptr_t>(SectionTable);
assert((Offset % sizeof(coff_section)) == 0);
return (Offset / sizeof(coff_section)) + 1;
}
@@ -378,7 +378,7 @@ getFirstReloc(const coff_section *Sec, MemoryBufferRef M, const uint8_t *Base) {
// relocations.
begin++;
}
- if (auto E = Binary::checkOffset(M, reinterpret_cast<uintptr_t>(begin),
+ if (auto E = Binary::checkOffset(M, reinterpret_cast<uintptr_t>(begin),
sizeof(coff_relocation) * NumRelocs)) {
consumeError(std::move(E));
return nullptr;
@@ -469,8 +469,8 @@ Error COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize;
if (SectionStart <= Addr && Addr < SectionEnd) {
uint32_t Offset = Addr - SectionStart;
- Res = reinterpret_cast<uintptr_t>(base()) + Section->PointerToRawData +
- Offset;
+ Res = reinterpret_cast<uintptr_t>(base()) + Section->PointerToRawData +
+ Offset;
return Error::success();
}
}
@@ -487,8 +487,8 @@ Error COFFObjectFile::getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
uint32_t OffsetIntoSection = RVA - SectionStart;
if (SectionStart <= RVA && OffsetIntoSection < Section->VirtualSize &&
Size <= Section->VirtualSize - OffsetIntoSection) {
- uintptr_t Begin = reinterpret_cast<uintptr_t>(base()) +
- Section->PointerToRawData + OffsetIntoSection;
+ uintptr_t Begin = reinterpret_cast<uintptr_t>(base()) +
+ Section->PointerToRawData + OffsetIntoSection;
Contents =
ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Begin), Size);
return Error::success();
@@ -652,38 +652,38 @@ Error COFFObjectFile::initDebugDirectoryPtr() {
return Error::success();
}
-Error COFFObjectFile::initTLSDirectoryPtr() {
- // Get the RVA of the TLS directory. Do nothing if it does not exist.
- const data_directory *DataEntry = getDataDirectory(COFF::TLS_TABLE);
- if (!DataEntry)
- return Error::success();
-
- // Do nothing if the RVA is NULL.
- if (DataEntry->RelativeVirtualAddress == 0)
- return Error::success();
-
- uint64_t DirSize =
- is64() ? sizeof(coff_tls_directory64) : sizeof(coff_tls_directory32);
-
- // Check that the size is correct.
- if (DataEntry->Size != DirSize)
- return createStringError(
- object_error::parse_failed,
- "TLS Directory size (%u) is not the expected size (%" PRIu64 ").",
- static_cast<uint32_t>(DataEntry->Size), DirSize);
-
- uintptr_t IntPtr = 0;
- if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
- return E;
-
- if (is64())
- TLSDirectory64 = reinterpret_cast<const coff_tls_directory64 *>(IntPtr);
- else
- TLSDirectory32 = reinterpret_cast<const coff_tls_directory32 *>(IntPtr);
-
- return Error::success();
-}
-
+Error COFFObjectFile::initTLSDirectoryPtr() {
+ // Get the RVA of the TLS directory. Do nothing if it does not exist.
+ const data_directory *DataEntry = getDataDirectory(COFF::TLS_TABLE);
+ if (!DataEntry)
+ return Error::success();
+
+ // Do nothing if the RVA is NULL.
+ if (DataEntry->RelativeVirtualAddress == 0)
+ return Error::success();
+
+ uint64_t DirSize =
+ is64() ? sizeof(coff_tls_directory64) : sizeof(coff_tls_directory32);
+
+ // Check that the size is correct.
+ if (DataEntry->Size != DirSize)
+ return createStringError(
+ object_error::parse_failed,
+ "TLS Directory size (%u) is not the expected size (%" PRIu64 ").",
+ static_cast<uint32_t>(DataEntry->Size), DirSize);
+
+ uintptr_t IntPtr = 0;
+ if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
+ return E;
+
+ if (is64())
+ TLSDirectory64 = reinterpret_cast<const coff_tls_directory64 *>(IntPtr);
+ else
+ TLSDirectory32 = reinterpret_cast<const coff_tls_directory32 *>(IntPtr);
+
+ return Error::success();
+}
+
Error COFFObjectFile::initLoadConfigPtr() {
// Get the RVA of the debug directory. Do nothing if it does not exist.
const data_directory *DataEntry = getDataDirectory(COFF::LOAD_CONFIG_TABLE);
@@ -717,8 +717,8 @@ COFFObjectFile::COFFObjectFile(MemoryBufferRef Object)
ImportDirectory(nullptr), DelayImportDirectory(nullptr),
NumberOfDelayImportDirectory(0), ExportDirectory(nullptr),
BaseRelocHeader(nullptr), BaseRelocEnd(nullptr),
- DebugDirectoryBegin(nullptr), DebugDirectoryEnd(nullptr),
- TLSDirectory32(nullptr), TLSDirectory64(nullptr) {}
+ DebugDirectoryBegin(nullptr), DebugDirectoryEnd(nullptr),
+ TLSDirectory32(nullptr), TLSDirectory64(nullptr) {}
Error COFFObjectFile::initialize() {
// Check that we at least have enough room for a header.
@@ -845,14 +845,14 @@ Error COFFObjectFile::initialize() {
if (Error E = initBaseRelocPtr())
return E;
- // Initialize the pointer to the debug directory.
+ // Initialize the pointer to the debug directory.
if (Error E = initDebugDirectoryPtr())
return E;
- // Initialize the pointer to the TLS directory.
- if (Error E = initTLSDirectoryPtr())
- return E;
-
+ // Initialize the pointer to the TLS directory.
+ if (Error E = initTLSDirectoryPtr())
+ return E;
+
if (Error E = initLoadConfigPtr())
return E;
@@ -1130,8 +1130,8 @@ Error COFFObjectFile::getSectionContents(const coff_section *Sec,
// The only thing that we need to verify is that the contents is contained
// within the file bounds. We don't need to make sure it doesn't cover other
// data, as there's nothing that says that is not allowed.
- uintptr_t ConStart =
- reinterpret_cast<uintptr_t>(base()) + Sec->PointerToRawData;
+ uintptr_t ConStart =
+ reinterpret_cast<uintptr_t>(base()) + Sec->PointerToRawData;
uint32_t SectionSize = getSectionSize(Sec);
if (Error E = checkOffset(Data, ConStart, SectionSize))
return E;
@@ -1791,9 +1791,9 @@ Error ResourceSectionRef::load(const COFFObjectFile *O, const SectionRef &S) {
Relocs.reserve(OrigRelocs.size());
for (const coff_relocation &R : OrigRelocs)
Relocs.push_back(&R);
- llvm::sort(Relocs, [](const coff_relocation *A, const coff_relocation *B) {
- return A->VirtualAddress < B->VirtualAddress;
- });
+ llvm::sort(Relocs, [](const coff_relocation *A, const coff_relocation *B) {
+ return A->VirtualAddress < B->VirtualAddress;
+ });
return Error::success();
}
diff --git a/contrib/libs/llvm12/lib/Object/ELF.cpp b/contrib/libs/llvm12/lib/Object/ELF.cpp
index 15d169f8c8..264f115ddb 100644
--- a/contrib/libs/llvm12/lib/Object/ELF.cpp
+++ b/contrib/libs/llvm12/lib/Object/ELF.cpp
@@ -152,13 +152,13 @@ StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine,
break;
}
break;
- case ELF::EM_CSKY:
- switch (Type) {
-#include "llvm/BinaryFormat/ELFRelocs/CSKY.def"
- default:
- break;
- }
- break;
+ case ELF::EM_CSKY:
+ switch (Type) {
+#include "llvm/BinaryFormat/ELFRelocs/CSKY.def"
+ default:
+ break;
+ }
+ break;
default:
break;
}
@@ -201,8 +201,8 @@ uint32_t llvm::object::getELFRelativeRelocationType(uint32_t Machine) {
case ELF::EM_SPARC32PLUS:
case ELF::EM_SPARCV9:
return ELF::R_SPARC_RELATIVE;
- case ELF::EM_CSKY:
- return ELF::R_CKCORE_RELATIVE;
+ case ELF::EM_CSKY:
+ return ELF::R_CKCORE_RELATIVE;
case ELF::EM_AMDGPU:
break;
case ELF::EM_BPF:
@@ -276,7 +276,7 @@ StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_SYMPART);
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_EHDR);
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_PHDR);
- STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP);
+ STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP);
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES);
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH);
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef);
@@ -288,7 +288,7 @@ StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
}
template <class ELFT>
-std::vector<typename ELFT::Rel>
+std::vector<typename ELFT::Rel>
ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const {
// This function decodes the contents of an SHT_RELR packed relocation
// section.
@@ -320,10 +320,10 @@ ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const {
// even means address, odd means bitmap.
// 2. Just a simple list of addresses is a valid encoding.
- Elf_Rel Rel;
- Rel.r_info = 0;
- Rel.setType(getRelativeRelocationType(), false);
- std::vector<Elf_Rel> Relocs;
+ Elf_Rel Rel;
+ Rel.r_info = 0;
+ Rel.setType(getRelativeRelocationType(), false);
+ std::vector<Elf_Rel> Relocs;
// Word type: uint32_t for Elf32, and uint64_t for Elf64.
typedef typename ELFT::uint Word;
@@ -340,8 +340,8 @@ ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const {
Word Entry = R;
if ((Entry&1) == 0) {
// Even entry: encodes the offset for next relocation.
- Rel.r_offset = Entry;
- Relocs.push_back(Rel);
+ Rel.r_offset = Entry;
+ Relocs.push_back(Rel);
// Set base offset for subsequent bitmap entries.
Base = Entry + WordSize;
continue;
@@ -352,8 +352,8 @@ ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const {
while (Entry != 0) {
Entry >>= 1;
if ((Entry&1) != 0) {
- Rel.r_offset = Offset;
- Relocs.push_back(Rel);
+ Rel.r_offset = Offset;
+ Relocs.push_back(Rel);
}
Offset += WordSize;
}
@@ -367,7 +367,7 @@ ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const {
template <class ELFT>
Expected<std::vector<typename ELFT::Rela>>
-ELFFile<ELFT>::android_relas(const Elf_Shdr &Sec) const {
+ELFFile<ELFT>::android_relas(const Elf_Shdr &Sec) const {
// This function reads relocations in Android's packed relocation format,
// which is based on SLEB128 and delta encoding.
Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
@@ -512,7 +512,7 @@ std::string ELFFile<ELFT>::getDynamicTagAsString(unsigned Arch,
template <class ELFT>
std::string ELFFile<ELFT>::getDynamicTagAsString(uint64_t Type) const {
- return getDynamicTagAsString(getHeader().e_machine, Type);
+ return getDynamicTagAsString(getHeader().e_machine, Type);
}
template <class ELFT>
@@ -542,7 +542,7 @@ Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const {
for (const Elf_Shdr &Sec : *SectionsOrError) {
if (Sec.sh_type == ELF::SHT_DYNAMIC) {
Expected<ArrayRef<Elf_Dyn>> DynOrError =
- getSectionContentsAsArray<Elf_Dyn>(Sec);
+ getSectionContentsAsArray<Elf_Dyn>(Sec);
if (!DynOrError)
return DynOrError.takeError();
Dyn = *DynOrError;
@@ -566,8 +566,8 @@ Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const {
}
template <class ELFT>
-Expected<const uint8_t *>
-ELFFile<ELFT>::toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler) const {
+Expected<const uint8_t *>
+ELFFile<ELFT>::toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler) const {
auto ProgramHeadersOrError = program_headers();
if (!ProgramHeadersOrError)
return ProgramHeadersOrError.takeError();
@@ -578,22 +578,22 @@ ELFFile<ELFT>::toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler) const {
if (Phdr.p_type == ELF::PT_LOAD)
LoadSegments.push_back(const_cast<Elf_Phdr *>(&Phdr));
- auto SortPred = [](const Elf_Phdr_Impl<ELFT> *A,
- const Elf_Phdr_Impl<ELFT> *B) {
- return A->p_vaddr < B->p_vaddr;
- };
- if (!llvm::is_sorted(LoadSegments, SortPred)) {
- if (Error E =
- WarnHandler("loadable segments are unsorted by virtual address"))
- return std::move(E);
- llvm::stable_sort(LoadSegments, SortPred);
- }
-
- const Elf_Phdr *const *I = llvm::upper_bound(
- LoadSegments, VAddr, [](uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) {
- return VAddr < Phdr->p_vaddr;
- });
-
+ auto SortPred = [](const Elf_Phdr_Impl<ELFT> *A,
+ const Elf_Phdr_Impl<ELFT> *B) {
+ return A->p_vaddr < B->p_vaddr;
+ };
+ if (!llvm::is_sorted(LoadSegments, SortPred)) {
+ if (Error E =
+ WarnHandler("loadable segments are unsorted by virtual address"))
+ return std::move(E);
+ llvm::stable_sort(LoadSegments, SortPred);
+ }
+
+ const Elf_Phdr *const *I = llvm::upper_bound(
+ LoadSegments, VAddr, [](uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) {
+ return VAddr < Phdr->p_vaddr;
+ });
+
if (I == LoadSegments.begin())
return createError("virtual address is not in any segment: 0x" +
Twine::utohexstr(VAddr));
diff --git a/contrib/libs/llvm12/lib/Object/ELFObjectFile.cpp b/contrib/libs/llvm12/lib/Object/ELFObjectFile.cpp
index 86b8d5e262..91871a6255 100644
--- a/contrib/libs/llvm12/lib/Object/ELFObjectFile.cpp
+++ b/contrib/libs/llvm12/lib/Object/ELFObjectFile.cpp
@@ -61,36 +61,36 @@ ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
template <class ELFT>
static Expected<std::unique_ptr<ELFObjectFile<ELFT>>>
-createPtr(MemoryBufferRef Object, bool InitContent) {
- auto Ret = ELFObjectFile<ELFT>::create(Object, InitContent);
+createPtr(MemoryBufferRef Object, bool InitContent) {
+ auto Ret = ELFObjectFile<ELFT>::create(Object, InitContent);
if (Error E = Ret.takeError())
return std::move(E);
return std::make_unique<ELFObjectFile<ELFT>>(std::move(*Ret));
}
Expected<std::unique_ptr<ObjectFile>>
-ObjectFile::createELFObjectFile(MemoryBufferRef Obj, bool InitContent) {
+ObjectFile::createELFObjectFile(MemoryBufferRef Obj, bool InitContent) {
std::pair<unsigned char, unsigned char> Ident =
getElfArchType(Obj.getBuffer());
std::size_t MaxAlignment =
- 1ULL << countTrailingZeros(
- reinterpret_cast<uintptr_t>(Obj.getBufferStart()));
+ 1ULL << countTrailingZeros(
+ reinterpret_cast<uintptr_t>(Obj.getBufferStart()));
if (MaxAlignment < 2)
return createError("Insufficient alignment");
if (Ident.first == ELF::ELFCLASS32) {
if (Ident.second == ELF::ELFDATA2LSB)
- return createPtr<ELF32LE>(Obj, InitContent);
+ return createPtr<ELF32LE>(Obj, InitContent);
else if (Ident.second == ELF::ELFDATA2MSB)
- return createPtr<ELF32BE>(Obj, InitContent);
+ return createPtr<ELF32BE>(Obj, InitContent);
else
return createError("Invalid ELF data");
} else if (Ident.first == ELF::ELFCLASS64) {
if (Ident.second == ELF::ELFDATA2LSB)
- return createPtr<ELF64LE>(Obj, InitContent);
+ return createPtr<ELF64LE>(Obj, InitContent);
else if (Ident.second == ELF::ELFDATA2MSB)
- return createPtr<ELF64BE>(Obj, InitContent);
+ return createPtr<ELF64BE>(Obj, InitContent);
else
return createError("Invalid ELF data");
}
@@ -356,130 +356,130 @@ SubtargetFeatures ELFObjectFileBase::getFeatures() const {
}
}
-Optional<StringRef> ELFObjectFileBase::tryGetCPUName() const {
- switch (getEMachine()) {
- case ELF::EM_AMDGPU:
- return getAMDGPUCPUName();
- default:
- return None;
- }
-}
-
-StringRef ELFObjectFileBase::getAMDGPUCPUName() const {
- assert(getEMachine() == ELF::EM_AMDGPU);
- unsigned CPU = getPlatformFlags() & ELF::EF_AMDGPU_MACH;
-
- switch (CPU) {
- // Radeon HD 2000/3000 Series (R600).
- case ELF::EF_AMDGPU_MACH_R600_R600:
- return "r600";
- case ELF::EF_AMDGPU_MACH_R600_R630:
- return "r630";
- case ELF::EF_AMDGPU_MACH_R600_RS880:
- return "rs880";
- case ELF::EF_AMDGPU_MACH_R600_RV670:
- return "rv670";
-
- // Radeon HD 4000 Series (R700).
- case ELF::EF_AMDGPU_MACH_R600_RV710:
- return "rv710";
- case ELF::EF_AMDGPU_MACH_R600_RV730:
- return "rv730";
- case ELF::EF_AMDGPU_MACH_R600_RV770:
- return "rv770";
-
- // Radeon HD 5000 Series (Evergreen).
- case ELF::EF_AMDGPU_MACH_R600_CEDAR:
- return "cedar";
- case ELF::EF_AMDGPU_MACH_R600_CYPRESS:
- return "cypress";
- case ELF::EF_AMDGPU_MACH_R600_JUNIPER:
- return "juniper";
- case ELF::EF_AMDGPU_MACH_R600_REDWOOD:
- return "redwood";
- case ELF::EF_AMDGPU_MACH_R600_SUMO:
- return "sumo";
-
- // Radeon HD 6000 Series (Northern Islands).
- case ELF::EF_AMDGPU_MACH_R600_BARTS:
- return "barts";
- case ELF::EF_AMDGPU_MACH_R600_CAICOS:
- return "caicos";
- case ELF::EF_AMDGPU_MACH_R600_CAYMAN:
- return "cayman";
- case ELF::EF_AMDGPU_MACH_R600_TURKS:
- return "turks";
-
- // AMDGCN GFX6.
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX600:
- return "gfx600";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX601:
- return "gfx601";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX602:
- return "gfx602";
-
- // AMDGCN GFX7.
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX700:
- return "gfx700";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX701:
- return "gfx701";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX702:
- return "gfx702";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX703:
- return "gfx703";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX704:
- return "gfx704";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX705:
- return "gfx705";
-
- // AMDGCN GFX8.
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX801:
- return "gfx801";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX802:
- return "gfx802";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX803:
- return "gfx803";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX805:
- return "gfx805";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX810:
- return "gfx810";
-
- // AMDGCN GFX9.
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX900:
- return "gfx900";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX902:
- return "gfx902";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX904:
- return "gfx904";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX906:
- return "gfx906";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX908:
- return "gfx908";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX909:
- return "gfx909";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX90C:
- return "gfx90c";
-
- // AMDGCN GFX10.
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1010:
- return "gfx1010";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1011:
- return "gfx1011";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1012:
- return "gfx1012";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1030:
- return "gfx1030";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1031:
- return "gfx1031";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1032:
- return "gfx1032";
- case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1033:
- return "gfx1033";
- default:
- llvm_unreachable("Unknown EF_AMDGPU_MACH value");
- }
-}
-
+Optional<StringRef> ELFObjectFileBase::tryGetCPUName() const {
+ switch (getEMachine()) {
+ case ELF::EM_AMDGPU:
+ return getAMDGPUCPUName();
+ default:
+ return None;
+ }
+}
+
+StringRef ELFObjectFileBase::getAMDGPUCPUName() const {
+ assert(getEMachine() == ELF::EM_AMDGPU);
+ unsigned CPU = getPlatformFlags() & ELF::EF_AMDGPU_MACH;
+
+ switch (CPU) {
+ // Radeon HD 2000/3000 Series (R600).
+ case ELF::EF_AMDGPU_MACH_R600_R600:
+ return "r600";
+ case ELF::EF_AMDGPU_MACH_R600_R630:
+ return "r630";
+ case ELF::EF_AMDGPU_MACH_R600_RS880:
+ return "rs880";
+ case ELF::EF_AMDGPU_MACH_R600_RV670:
+ return "rv670";
+
+ // Radeon HD 4000 Series (R700).
+ case ELF::EF_AMDGPU_MACH_R600_RV710:
+ return "rv710";
+ case ELF::EF_AMDGPU_MACH_R600_RV730:
+ return "rv730";
+ case ELF::EF_AMDGPU_MACH_R600_RV770:
+ return "rv770";
+
+ // Radeon HD 5000 Series (Evergreen).
+ case ELF::EF_AMDGPU_MACH_R600_CEDAR:
+ return "cedar";
+ case ELF::EF_AMDGPU_MACH_R600_CYPRESS:
+ return "cypress";
+ case ELF::EF_AMDGPU_MACH_R600_JUNIPER:
+ return "juniper";
+ case ELF::EF_AMDGPU_MACH_R600_REDWOOD:
+ return "redwood";
+ case ELF::EF_AMDGPU_MACH_R600_SUMO:
+ return "sumo";
+
+ // Radeon HD 6000 Series (Northern Islands).
+ case ELF::EF_AMDGPU_MACH_R600_BARTS:
+ return "barts";
+ case ELF::EF_AMDGPU_MACH_R600_CAICOS:
+ return "caicos";
+ case ELF::EF_AMDGPU_MACH_R600_CAYMAN:
+ return "cayman";
+ case ELF::EF_AMDGPU_MACH_R600_TURKS:
+ return "turks";
+
+ // AMDGCN GFX6.
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX600:
+ return "gfx600";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX601:
+ return "gfx601";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX602:
+ return "gfx602";
+
+ // AMDGCN GFX7.
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX700:
+ return "gfx700";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX701:
+ return "gfx701";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX702:
+ return "gfx702";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX703:
+ return "gfx703";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX704:
+ return "gfx704";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX705:
+ return "gfx705";
+
+ // AMDGCN GFX8.
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX801:
+ return "gfx801";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX802:
+ return "gfx802";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX803:
+ return "gfx803";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX805:
+ return "gfx805";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX810:
+ return "gfx810";
+
+ // AMDGCN GFX9.
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX900:
+ return "gfx900";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX902:
+ return "gfx902";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX904:
+ return "gfx904";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX906:
+ return "gfx906";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX908:
+ return "gfx908";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX909:
+ return "gfx909";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX90C:
+ return "gfx90c";
+
+ // AMDGCN GFX10.
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1010:
+ return "gfx1010";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1011:
+ return "gfx1011";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1012:
+ return "gfx1012";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1030:
+ return "gfx1030";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1031:
+ return "gfx1031";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1032:
+ return "gfx1032";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1033:
+ return "gfx1033";
+ default:
+ llvm_unreachable("Unknown EF_AMDGPU_MACH value");
+ }
+}
+
// FIXME Encode from a tablegen description or target parser.
void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
if (TheTriple.getSubArch() != Triple::NoSubArch)
@@ -565,7 +565,7 @@ void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
TheTriple.setArchName(Triple);
}
-std::vector<std::pair<Optional<DataRefImpl>, uint64_t>>
+std::vector<std::pair<Optional<DataRefImpl>, uint64_t>>
ELFObjectFileBase::getPltAddresses() const {
std::string Err;
const auto Triple = makeTriple();
@@ -623,18 +623,18 @@ ELFObjectFileBase::getPltAddresses() const {
GotToPlt.insert(std::make_pair(Entry.second, Entry.first));
// Find the relocations in the dynamic relocation table that point to
// locations in the GOT for which we know the corresponding PLT entry.
- std::vector<std::pair<Optional<DataRefImpl>, uint64_t>> Result;
+ std::vector<std::pair<Optional<DataRefImpl>, uint64_t>> Result;
for (const auto &Relocation : RelaPlt->relocations()) {
if (Relocation.getType() != JumpSlotReloc)
continue;
auto PltEntryIter = GotToPlt.find(Relocation.getOffset());
- if (PltEntryIter != GotToPlt.end()) {
- symbol_iterator Sym = Relocation.getSymbol();
- if (Sym == symbol_end())
- Result.emplace_back(None, PltEntryIter->second);
- else
- Result.emplace_back(Sym->getRawDataRefImpl(), PltEntryIter->second);
- }
+ if (PltEntryIter != GotToPlt.end()) {
+ symbol_iterator Sym = Relocation.getSymbol();
+ if (Sym == symbol_end())
+ Result.emplace_back(None, PltEntryIter->second);
+ else
+ Result.emplace_back(Sym->getRawDataRefImpl(), PltEntryIter->second);
+ }
}
return Result;
}
diff --git a/contrib/libs/llvm12/lib/Object/MachOObjectFile.cpp b/contrib/libs/llvm12/lib/Object/MachOObjectFile.cpp
index f9a538ed43..3022559262 100644
--- a/contrib/libs/llvm12/lib/Object/MachOObjectFile.cpp
+++ b/contrib/libs/llvm12/lib/Object/MachOObjectFile.cpp
@@ -1596,9 +1596,9 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
if ((Err = checkTwoLevelHintsCommand(*this, Load, I,
&TwoLevelHintsLoadCmd, Elements)))
return;
- } else if (Load.C.cmd == MachO::LC_IDENT) {
- // Note: LC_IDENT is ignored.
- continue;
+ } else if (Load.C.cmd == MachO::LC_IDENT) {
+ // Note: LC_IDENT is ignored.
+ continue;
} else if (isLoadCommandObsolete(Load.C.cmd)) {
Err = malformedError("load command " + Twine(I) + " for cmd value of: " +
Twine(Load.C.cmd) + " is obsolete and not "
@@ -2035,9 +2035,9 @@ bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
bool MachOObjectFile::isDebugSection(StringRef SectionName) const {
return SectionName.startswith("__debug") ||
- SectionName.startswith("__zdebug") ||
- SectionName.startswith("__apple") || SectionName == "__gdb_index" ||
- SectionName == "__swift_ast";
+ SectionName.startswith("__zdebug") ||
+ SectionName.startswith("__apple") || SectionName == "__gdb_index" ||
+ SectionName == "__swift_ast";
}
unsigned MachOObjectFile::getSectionID(SectionRef Sec) const {
@@ -2694,12 +2694,12 @@ Triple MachOObjectFile::getArchTriple(uint32_t CPUType, uint32_t CPUSubType,
if (ArchFlag)
*ArchFlag = "arm64";
return Triple("arm64-apple-darwin");
- case MachO::CPU_SUBTYPE_ARM64E:
- if (McpuDefault)
- *McpuDefault = "apple-a12";
- if (ArchFlag)
- *ArchFlag = "arm64e";
- return Triple("arm64e-apple-darwin");
+ case MachO::CPU_SUBTYPE_ARM64E:
+ if (McpuDefault)
+ *McpuDefault = "apple-a12";
+ if (ArchFlag)
+ *ArchFlag = "arm64e";
+ return Triple("arm64e-apple-darwin");
default:
return Triple();
}
@@ -2743,32 +2743,32 @@ Triple MachOObjectFile::getHostArch() {
bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
auto validArchs = getValidArchs();
- return llvm::is_contained(validArchs, ArchFlag);
+ return llvm::is_contained(validArchs, ArchFlag);
}
ArrayRef<StringRef> MachOObjectFile::getValidArchs() {
- static const std::array<StringRef, 18> ValidArchs = {{
- "i386",
- "x86_64",
- "x86_64h",
- "armv4t",
- "arm",
- "armv5e",
- "armv6",
- "armv6m",
- "armv7",
- "armv7em",
- "armv7k",
- "armv7m",
- "armv7s",
- "arm64",
- "arm64e",
- "arm64_32",
- "ppc",
- "ppc64",
+ static const std::array<StringRef, 18> ValidArchs = {{
+ "i386",
+ "x86_64",
+ "x86_64h",
+ "armv4t",
+ "arm",
+ "armv5e",
+ "armv6",
+ "armv6m",
+ "armv7",
+ "armv7em",
+ "armv7k",
+ "armv7m",
+ "armv7s",
+ "arm64",
+ "arm64e",
+ "arm64_32",
+ "ppc",
+ "ppc64",
}};
- return ValidArchs;
+ return ValidArchs;
}
Triple::ArchType MachOObjectFile::getArch() const {
diff --git a/contrib/libs/llvm12/lib/Object/MachOUniversal.cpp b/contrib/libs/llvm12/lib/Object/MachOUniversal.cpp
index 0433c78bce..f3ce005e6e 100644
--- a/contrib/libs/llvm12/lib/Object/MachOUniversal.cpp
+++ b/contrib/libs/llvm12/lib/Object/MachOUniversal.cpp
@@ -12,7 +12,7 @@
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/Archive.h"
-#include "llvm/Object/IRObjectFile.h"
+#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Casting.h"
@@ -81,25 +81,25 @@ MachOUniversalBinary::ObjectForArch::getAsObjectFile() const {
return ObjectFile::createMachOObjectFile(ObjBuffer, cputype, Index);
}
-Expected<std::unique_ptr<IRObjectFile>>
-MachOUniversalBinary::ObjectForArch::getAsIRObject(LLVMContext &Ctx) const {
- if (!Parent)
- report_fatal_error("MachOUniversalBinary::ObjectForArch::getAsIRObject() "
- "called when Parent is a nullptr");
-
- StringRef ParentData = Parent->getData();
- StringRef ObjectData;
- if (Parent->getMagic() == MachO::FAT_MAGIC) {
- ObjectData = ParentData.substr(Header.offset, Header.size);
- } else { // Parent->getMagic() == MachO::FAT_MAGIC_64
- ObjectData = ParentData.substr(Header64.offset, Header64.size);
- }
- StringRef ObjectName = Parent->getFileName();
- MemoryBufferRef ObjBuffer(ObjectData, ObjectName);
-
- return IRObjectFile::create(ObjBuffer, Ctx);
-}
-
+Expected<std::unique_ptr<IRObjectFile>>
+MachOUniversalBinary::ObjectForArch::getAsIRObject(LLVMContext &Ctx) const {
+ if (!Parent)
+ report_fatal_error("MachOUniversalBinary::ObjectForArch::getAsIRObject() "
+ "called when Parent is a nullptr");
+
+ StringRef ParentData = Parent->getData();
+ StringRef ObjectData;
+ if (Parent->getMagic() == MachO::FAT_MAGIC) {
+ ObjectData = ParentData.substr(Header.offset, Header.size);
+ } else { // Parent->getMagic() == MachO::FAT_MAGIC_64
+ ObjectData = ParentData.substr(Header64.offset, Header64.size);
+ }
+ StringRef ObjectName = Parent->getFileName();
+ MemoryBufferRef ObjBuffer(ObjectData, ObjectName);
+
+ return IRObjectFile::create(ObjBuffer, Ctx);
+}
+
Expected<std::unique_ptr<Archive>>
MachOUniversalBinary::ObjectForArch::getAsArchive() const {
if (!Parent)
@@ -254,15 +254,15 @@ MachOUniversalBinary::getMachOObjectForArch(StringRef ArchName) const {
return O->getAsObjectFile();
}
-Expected<std::unique_ptr<IRObjectFile>>
-MachOUniversalBinary::getIRObjectForArch(StringRef ArchName,
- LLVMContext &Ctx) const {
- Expected<ObjectForArch> O = getObjectForArch(ArchName);
- if (!O)
- return O.takeError();
- return O->getAsIRObject(Ctx);
-}
-
+Expected<std::unique_ptr<IRObjectFile>>
+MachOUniversalBinary::getIRObjectForArch(StringRef ArchName,
+ LLVMContext &Ctx) const {
+ Expected<ObjectForArch> O = getObjectForArch(ArchName);
+ if (!O)
+ return O.takeError();
+ return O->getAsIRObject(Ctx);
+}
+
Expected<std::unique_ptr<Archive>>
MachOUniversalBinary::getArchiveForArch(StringRef ArchName) const {
Expected<ObjectForArch> O = getObjectForArch(ArchName);
diff --git a/contrib/libs/llvm12/lib/Object/MachOUniversalWriter.cpp b/contrib/libs/llvm12/lib/Object/MachOUniversalWriter.cpp
index 45cb72bbbf..4bb467e56a 100644
--- a/contrib/libs/llvm12/lib/Object/MachOUniversalWriter.cpp
+++ b/contrib/libs/llvm12/lib/Object/MachOUniversalWriter.cpp
@@ -1,337 +1,337 @@
-//===- MachOUniversalWriter.cpp - MachO universal binary writer---*- C++-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Defines the Slice class and writeUniversalBinary function for writing a MachO
-// universal binary file.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Object/MachOUniversalWriter.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Object/Archive.h"
-#include "llvm/Object/Binary.h"
-#include "llvm/Object/Error.h"
-#include "llvm/Object/IRObjectFile.h"
-#include "llvm/Object/MachO.h"
-#include "llvm/Object/MachOUniversal.h"
-#include "llvm/Support/SmallVectorMemoryBuffer.h"
-
-using namespace llvm;
-using namespace object;
-
-// For compatibility with cctools lipo, a file's alignment is calculated as the
-// minimum aligment of all segments. For object files, the file's alignment is
-// the maximum alignment of its sections.
-static uint32_t calculateFileAlignment(const MachOObjectFile &O) {
- uint32_t P2CurrentAlignment;
- uint32_t P2MinAlignment = MachOUniversalBinary::MaxSectionAlignment;
- const bool Is64Bit = O.is64Bit();
-
- for (const auto &LC : O.load_commands()) {
- if (LC.C.cmd != (Is64Bit ? MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT))
- continue;
- if (O.getHeader().filetype == MachO::MH_OBJECT) {
- unsigned NumberOfSections =
- (Is64Bit ? O.getSegment64LoadCommand(LC).nsects
- : O.getSegmentLoadCommand(LC).nsects);
- P2CurrentAlignment = NumberOfSections ? 2 : P2MinAlignment;
- for (unsigned SI = 0; SI < NumberOfSections; ++SI) {
- P2CurrentAlignment = std::max(P2CurrentAlignment,
- (Is64Bit ? O.getSection64(LC, SI).align
- : O.getSection(LC, SI).align));
- }
- } else {
- P2CurrentAlignment =
- countTrailingZeros(Is64Bit ? O.getSegment64LoadCommand(LC).vmaddr
- : O.getSegmentLoadCommand(LC).vmaddr);
- }
- P2MinAlignment = std::min(P2MinAlignment, P2CurrentAlignment);
- }
- // return a value >= 4 byte aligned, and less than MachO MaxSectionAlignment
- return std::max(
- static_cast<uint32_t>(2),
- std::min(P2MinAlignment, static_cast<uint32_t>(
- MachOUniversalBinary::MaxSectionAlignment)));
-}
-
-static uint32_t calculateAlignment(const MachOObjectFile &ObjectFile) {
- switch (ObjectFile.getHeader().cputype) {
- case MachO::CPU_TYPE_I386:
- case MachO::CPU_TYPE_X86_64:
- case MachO::CPU_TYPE_POWERPC:
- case MachO::CPU_TYPE_POWERPC64:
- return 12; // log2 value of page size(4k) for x86 and PPC
- case MachO::CPU_TYPE_ARM:
- case MachO::CPU_TYPE_ARM64:
- case MachO::CPU_TYPE_ARM64_32:
- return 14; // log2 value of page size(16k) for Darwin ARM
- default:
- return calculateFileAlignment(ObjectFile);
- }
-}
-
-Slice::Slice(const Archive &A, uint32_t CPUType, uint32_t CPUSubType,
- std::string ArchName, uint32_t Align)
- : B(&A), CPUType(CPUType), CPUSubType(CPUSubType),
- ArchName(std::move(ArchName)), P2Alignment(Align) {}
-
-Slice::Slice(const MachOObjectFile &O, uint32_t Align)
- : B(&O), CPUType(O.getHeader().cputype),
- CPUSubType(O.getHeader().cpusubtype),
- ArchName(std::string(O.getArchTriple().getArchName())),
- P2Alignment(Align) {}
-
-Slice::Slice(const IRObjectFile &IRO, uint32_t CPUType, uint32_t CPUSubType,
- std::string ArchName, uint32_t Align)
- : B(&IRO), CPUType(CPUType), CPUSubType(CPUSubType),
- ArchName(std::move(ArchName)), P2Alignment(Align) {}
-
-Slice::Slice(const MachOObjectFile &O) : Slice(O, calculateAlignment(O)) {}
-
-using MachoCPUTy = std::pair<unsigned, unsigned>;
-
-static Expected<MachoCPUTy> getMachoCPUFromTriple(Triple TT) {
- auto CPU = std::make_pair(MachO::getCPUType(TT), MachO::getCPUSubType(TT));
- if (!CPU.first) {
- return CPU.first.takeError();
- }
- if (!CPU.second) {
- return CPU.second.takeError();
- }
- return std::make_pair(*CPU.first, *CPU.second);
-}
-
-static Expected<MachoCPUTy> getMachoCPUFromTriple(StringRef TT) {
- return getMachoCPUFromTriple(Triple{TT});
-}
-
-Expected<Slice> Slice::create(const Archive &A, LLVMContext *LLVMCtx) {
- Error Err = Error::success();
- std::unique_ptr<MachOObjectFile> MFO = nullptr;
- std::unique_ptr<IRObjectFile> IRFO = nullptr;
- for (const Archive::Child &Child : A.children(Err)) {
- Expected<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary(LLVMCtx);
- if (!ChildOrErr)
- return createFileError(A.getFileName(), ChildOrErr.takeError());
- Binary *Bin = ChildOrErr.get().get();
- if (Bin->isMachOUniversalBinary())
- return createStringError(std::errc::invalid_argument,
- ("archive member " + Bin->getFileName() +
- " is a fat file (not allowed in an archive)")
- .str()
- .c_str());
- if (Bin->isMachO()) {
- MachOObjectFile *O = cast<MachOObjectFile>(Bin);
- if (IRFO) {
- return createStringError(
- std::errc::invalid_argument,
- "archive member %s is a MachO, while previous archive member "
- "%s was an IR LLVM object",
- O->getFileName().str().c_str(), IRFO->getFileName().str().c_str());
- }
- if (MFO &&
- std::tie(MFO->getHeader().cputype, MFO->getHeader().cpusubtype) !=
- std::tie(O->getHeader().cputype, O->getHeader().cpusubtype)) {
- return createStringError(
- std::errc::invalid_argument,
- ("archive member " + O->getFileName() + " cputype (" +
- Twine(O->getHeader().cputype) + ") and cpusubtype(" +
- Twine(O->getHeader().cpusubtype) +
- ") does not match previous archive members cputype (" +
- Twine(MFO->getHeader().cputype) + ") and cpusubtype(" +
- Twine(MFO->getHeader().cpusubtype) +
- ") (all members must match) " + MFO->getFileName())
- .str()
- .c_str());
- }
- if (!MFO) {
- ChildOrErr.get().release();
- MFO.reset(O);
- }
- } else if (Bin->isIR()) {
- IRObjectFile *O = cast<IRObjectFile>(Bin);
- if (MFO) {
- return createStringError(std::errc::invalid_argument,
- "archive member '%s' is an LLVM IR object, "
- "while previous archive member "
- "'%s' was a MachO",
- O->getFileName().str().c_str(),
- MFO->getFileName().str().c_str());
- }
- if (IRFO) {
- Expected<MachoCPUTy> CPUO = getMachoCPUFromTriple(O->getTargetTriple());
- Expected<MachoCPUTy> CPUFO =
- getMachoCPUFromTriple(IRFO->getTargetTriple());
- if (!CPUO)
- return CPUO.takeError();
- if (!CPUFO)
- return CPUFO.takeError();
- if (*CPUO != *CPUFO) {
- return createStringError(
- std::errc::invalid_argument,
- ("archive member " + O->getFileName() + " cputype (" +
- Twine(CPUO->first) + ") and cpusubtype(" + Twine(CPUO->second) +
- ") does not match previous archive members cputype (" +
- Twine(CPUFO->first) + ") and cpusubtype(" +
- Twine(CPUFO->second) + ") (all members must match) " +
- IRFO->getFileName())
- .str()
- .c_str());
- }
- } else {
- ChildOrErr.get().release();
- IRFO.reset(O);
- }
- } else
- return createStringError(std::errc::invalid_argument,
- ("archive member " + Bin->getFileName() +
- " is neither a MachO file or an LLVM IR file "
- "(not allowed in an archive)")
- .str()
- .c_str());
- }
- if (Err)
- return createFileError(A.getFileName(), std::move(Err));
- if (!MFO && !IRFO)
- return createStringError(
- std::errc::invalid_argument,
- ("empty archive with no architecture specification: " +
- A.getFileName() + " (can't determine architecture for it)")
- .str()
- .c_str());
-
- if (MFO) {
- Slice ArchiveSlice(*(MFO.get()), MFO->is64Bit() ? 3 : 2);
- ArchiveSlice.B = &A;
- return ArchiveSlice;
- }
-
- // For IR objects
- Expected<Slice> ArchiveSliceOrErr = Slice::create(*IRFO, 0);
- if (!ArchiveSliceOrErr)
- return createFileError(A.getFileName(), ArchiveSliceOrErr.takeError());
- auto &ArchiveSlice = ArchiveSliceOrErr.get();
- ArchiveSlice.B = &A;
- return std::move(ArchiveSlice);
-}
-
-Expected<Slice> Slice::create(const IRObjectFile &IRO, uint32_t Align) {
- Expected<MachoCPUTy> CPUOrErr = getMachoCPUFromTriple(IRO.getTargetTriple());
- if (!CPUOrErr)
- return CPUOrErr.takeError();
- unsigned CPUType, CPUSubType;
- std::tie(CPUType, CPUSubType) = CPUOrErr.get();
- // We don't directly use the architecture name of the target triple T, as,
- // for instance, thumb is treated as ARM by the MachOUniversal object.
- std::string ArchName(
- MachOObjectFile::getArchTriple(CPUType, CPUSubType).getArchName());
- return Slice{IRO, CPUType, CPUSubType, std::move(ArchName), Align};
-}
-
-static Expected<SmallVector<MachO::fat_arch, 2>>
-buildFatArchList(ArrayRef<Slice> Slices) {
- SmallVector<MachO::fat_arch, 2> FatArchList;
- uint64_t Offset =
- sizeof(MachO::fat_header) + Slices.size() * sizeof(MachO::fat_arch);
-
- for (const auto &S : Slices) {
- Offset = alignTo(Offset, 1ull << S.getP2Alignment());
- if (Offset > UINT32_MAX)
- return createStringError(
- std::errc::invalid_argument,
- ("fat file too large to be created because the offset "
- "field in struct fat_arch is only 32-bits and the offset " +
- Twine(Offset) + " for " + S.getBinary()->getFileName() +
- " for architecture " + S.getArchString() + "exceeds that.")
- .str()
- .c_str());
-
- MachO::fat_arch FatArch;
- FatArch.cputype = S.getCPUType();
- FatArch.cpusubtype = S.getCPUSubType();
- FatArch.offset = Offset;
- FatArch.size = S.getBinary()->getMemoryBufferRef().getBufferSize();
- FatArch.align = S.getP2Alignment();
- Offset += FatArch.size;
- FatArchList.push_back(FatArch);
- }
- return FatArchList;
-}
-
-static Error writeUniversalBinaryToStream(ArrayRef<Slice> Slices,
- raw_ostream &Out) {
- MachO::fat_header FatHeader;
- FatHeader.magic = MachO::FAT_MAGIC;
- FatHeader.nfat_arch = Slices.size();
-
- Expected<SmallVector<MachO::fat_arch, 2>> FatArchListOrErr =
- buildFatArchList(Slices);
- if (!FatArchListOrErr)
- return FatArchListOrErr.takeError();
- SmallVector<MachO::fat_arch, 2> FatArchList = *FatArchListOrErr;
-
- if (sys::IsLittleEndianHost)
- MachO::swapStruct(FatHeader);
- Out.write(reinterpret_cast<const char *>(&FatHeader),
- sizeof(MachO::fat_header));
-
- if (sys::IsLittleEndianHost)
- for (MachO::fat_arch &FA : FatArchList)
- MachO::swapStruct(FA);
- Out.write(reinterpret_cast<const char *>(FatArchList.data()),
- sizeof(MachO::fat_arch) * FatArchList.size());
-
- if (sys::IsLittleEndianHost)
- for (MachO::fat_arch &FA : FatArchList)
- MachO::swapStruct(FA);
-
- size_t Offset =
- sizeof(MachO::fat_header) + sizeof(MachO::fat_arch) * FatArchList.size();
- for (size_t Index = 0, Size = Slices.size(); Index < Size; ++Index) {
- MemoryBufferRef BufferRef = Slices[Index].getBinary()->getMemoryBufferRef();
- assert((Offset <= FatArchList[Index].offset) && "Incorrect slice offset");
- Out.write_zeros(FatArchList[Index].offset - Offset);
- Out.write(BufferRef.getBufferStart(), BufferRef.getBufferSize());
- Offset = FatArchList[Index].offset + BufferRef.getBufferSize();
- }
-
- Out.flush();
- return Error::success();
-}
-
-Error object::writeUniversalBinary(ArrayRef<Slice> Slices,
- StringRef OutputFileName) {
- const bool IsExecutable = any_of(Slices, [](Slice S) {
- return sys::fs::can_execute(S.getBinary()->getFileName());
- });
- unsigned Mode = sys::fs::all_read | sys::fs::all_write;
- if (IsExecutable)
- Mode |= sys::fs::all_exe;
- Expected<sys::fs::TempFile> Temp = sys::fs::TempFile::create(
- OutputFileName + ".temp-universal-%%%%%%", Mode);
- if (!Temp)
- return Temp.takeError();
- raw_fd_ostream Out(Temp->FD, false);
- if (Error E = writeUniversalBinaryToStream(Slices, Out)) {
- if (Error DiscardError = Temp->discard())
- return joinErrors(std::move(E), std::move(DiscardError));
- return E;
- }
- return Temp->keep(OutputFileName);
-}
-
-Expected<std::unique_ptr<MemoryBuffer>>
-object::writeUniversalBinaryToBuffer(ArrayRef<Slice> Slices) {
- SmallVector<char, 0> Buffer;
- raw_svector_ostream Out(Buffer);
-
- if (Error E = writeUniversalBinaryToStream(Slices, Out))
- return std::move(E);
-
- return std::make_unique<SmallVectorMemoryBuffer>(std::move(Buffer));
-}
+//===- MachOUniversalWriter.cpp - MachO universal binary writer---*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines the Slice class and writeUniversalBinary function for writing a MachO
+// universal binary file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Object/MachOUniversalWriter.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Object/Archive.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Object/IRObjectFile.h"
+#include "llvm/Object/MachO.h"
+#include "llvm/Object/MachOUniversal.h"
+#include "llvm/Support/SmallVectorMemoryBuffer.h"
+
+using namespace llvm;
+using namespace object;
+
+// For compatibility with cctools lipo, a file's alignment is calculated as the
+// minimum aligment of all segments. For object files, the file's alignment is
+// the maximum alignment of its sections.
+static uint32_t calculateFileAlignment(const MachOObjectFile &O) {
+ uint32_t P2CurrentAlignment;
+ uint32_t P2MinAlignment = MachOUniversalBinary::MaxSectionAlignment;
+ const bool Is64Bit = O.is64Bit();
+
+ for (const auto &LC : O.load_commands()) {
+ if (LC.C.cmd != (Is64Bit ? MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT))
+ continue;
+ if (O.getHeader().filetype == MachO::MH_OBJECT) {
+ unsigned NumberOfSections =
+ (Is64Bit ? O.getSegment64LoadCommand(LC).nsects
+ : O.getSegmentLoadCommand(LC).nsects);
+ P2CurrentAlignment = NumberOfSections ? 2 : P2MinAlignment;
+ for (unsigned SI = 0; SI < NumberOfSections; ++SI) {
+ P2CurrentAlignment = std::max(P2CurrentAlignment,
+ (Is64Bit ? O.getSection64(LC, SI).align
+ : O.getSection(LC, SI).align));
+ }
+ } else {
+ P2CurrentAlignment =
+ countTrailingZeros(Is64Bit ? O.getSegment64LoadCommand(LC).vmaddr
+ : O.getSegmentLoadCommand(LC).vmaddr);
+ }
+ P2MinAlignment = std::min(P2MinAlignment, P2CurrentAlignment);
+ }
+ // return a value >= 4 byte aligned, and less than MachO MaxSectionAlignment
+ return std::max(
+ static_cast<uint32_t>(2),
+ std::min(P2MinAlignment, static_cast<uint32_t>(
+ MachOUniversalBinary::MaxSectionAlignment)));
+}
+
+static uint32_t calculateAlignment(const MachOObjectFile &ObjectFile) {
+ switch (ObjectFile.getHeader().cputype) {
+ case MachO::CPU_TYPE_I386:
+ case MachO::CPU_TYPE_X86_64:
+ case MachO::CPU_TYPE_POWERPC:
+ case MachO::CPU_TYPE_POWERPC64:
+ return 12; // log2 value of page size(4k) for x86 and PPC
+ case MachO::CPU_TYPE_ARM:
+ case MachO::CPU_TYPE_ARM64:
+ case MachO::CPU_TYPE_ARM64_32:
+ return 14; // log2 value of page size(16k) for Darwin ARM
+ default:
+ return calculateFileAlignment(ObjectFile);
+ }
+}
+
+Slice::Slice(const Archive &A, uint32_t CPUType, uint32_t CPUSubType,
+ std::string ArchName, uint32_t Align)
+ : B(&A), CPUType(CPUType), CPUSubType(CPUSubType),
+ ArchName(std::move(ArchName)), P2Alignment(Align) {}
+
+Slice::Slice(const MachOObjectFile &O, uint32_t Align)
+ : B(&O), CPUType(O.getHeader().cputype),
+ CPUSubType(O.getHeader().cpusubtype),
+ ArchName(std::string(O.getArchTriple().getArchName())),
+ P2Alignment(Align) {}
+
+Slice::Slice(const IRObjectFile &IRO, uint32_t CPUType, uint32_t CPUSubType,
+ std::string ArchName, uint32_t Align)
+ : B(&IRO), CPUType(CPUType), CPUSubType(CPUSubType),
+ ArchName(std::move(ArchName)), P2Alignment(Align) {}
+
+Slice::Slice(const MachOObjectFile &O) : Slice(O, calculateAlignment(O)) {}
+
+using MachoCPUTy = std::pair<unsigned, unsigned>;
+
+static Expected<MachoCPUTy> getMachoCPUFromTriple(Triple TT) {
+ auto CPU = std::make_pair(MachO::getCPUType(TT), MachO::getCPUSubType(TT));
+ if (!CPU.first) {
+ return CPU.first.takeError();
+ }
+ if (!CPU.second) {
+ return CPU.second.takeError();
+ }
+ return std::make_pair(*CPU.first, *CPU.second);
+}
+
+static Expected<MachoCPUTy> getMachoCPUFromTriple(StringRef TT) {
+ return getMachoCPUFromTriple(Triple{TT});
+}
+
+Expected<Slice> Slice::create(const Archive &A, LLVMContext *LLVMCtx) {
+ Error Err = Error::success();
+ std::unique_ptr<MachOObjectFile> MFO = nullptr;
+ std::unique_ptr<IRObjectFile> IRFO = nullptr;
+ for (const Archive::Child &Child : A.children(Err)) {
+ Expected<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary(LLVMCtx);
+ if (!ChildOrErr)
+ return createFileError(A.getFileName(), ChildOrErr.takeError());
+ Binary *Bin = ChildOrErr.get().get();
+ if (Bin->isMachOUniversalBinary())
+ return createStringError(std::errc::invalid_argument,
+ ("archive member " + Bin->getFileName() +
+ " is a fat file (not allowed in an archive)")
+ .str()
+ .c_str());
+ if (Bin->isMachO()) {
+ MachOObjectFile *O = cast<MachOObjectFile>(Bin);
+ if (IRFO) {
+ return createStringError(
+ std::errc::invalid_argument,
+ "archive member %s is a MachO, while previous archive member "
+ "%s was an IR LLVM object",
+ O->getFileName().str().c_str(), IRFO->getFileName().str().c_str());
+ }
+ if (MFO &&
+ std::tie(MFO->getHeader().cputype, MFO->getHeader().cpusubtype) !=
+ std::tie(O->getHeader().cputype, O->getHeader().cpusubtype)) {
+ return createStringError(
+ std::errc::invalid_argument,
+ ("archive member " + O->getFileName() + " cputype (" +
+ Twine(O->getHeader().cputype) + ") and cpusubtype(" +
+ Twine(O->getHeader().cpusubtype) +
+ ") does not match previous archive members cputype (" +
+ Twine(MFO->getHeader().cputype) + ") and cpusubtype(" +
+ Twine(MFO->getHeader().cpusubtype) +
+ ") (all members must match) " + MFO->getFileName())
+ .str()
+ .c_str());
+ }
+ if (!MFO) {
+ ChildOrErr.get().release();
+ MFO.reset(O);
+ }
+ } else if (Bin->isIR()) {
+ IRObjectFile *O = cast<IRObjectFile>(Bin);
+ if (MFO) {
+ return createStringError(std::errc::invalid_argument,
+ "archive member '%s' is an LLVM IR object, "
+ "while previous archive member "
+ "'%s' was a MachO",
+ O->getFileName().str().c_str(),
+ MFO->getFileName().str().c_str());
+ }
+ if (IRFO) {
+ Expected<MachoCPUTy> CPUO = getMachoCPUFromTriple(O->getTargetTriple());
+ Expected<MachoCPUTy> CPUFO =
+ getMachoCPUFromTriple(IRFO->getTargetTriple());
+ if (!CPUO)
+ return CPUO.takeError();
+ if (!CPUFO)
+ return CPUFO.takeError();
+ if (*CPUO != *CPUFO) {
+ return createStringError(
+ std::errc::invalid_argument,
+ ("archive member " + O->getFileName() + " cputype (" +
+ Twine(CPUO->first) + ") and cpusubtype(" + Twine(CPUO->second) +
+ ") does not match previous archive members cputype (" +
+ Twine(CPUFO->first) + ") and cpusubtype(" +
+ Twine(CPUFO->second) + ") (all members must match) " +
+ IRFO->getFileName())
+ .str()
+ .c_str());
+ }
+ } else {
+ ChildOrErr.get().release();
+ IRFO.reset(O);
+ }
+ } else
+ return createStringError(std::errc::invalid_argument,
+ ("archive member " + Bin->getFileName() +
+ " is neither a MachO file or an LLVM IR file "
+ "(not allowed in an archive)")
+ .str()
+ .c_str());
+ }
+ if (Err)
+ return createFileError(A.getFileName(), std::move(Err));
+ if (!MFO && !IRFO)
+ return createStringError(
+ std::errc::invalid_argument,
+ ("empty archive with no architecture specification: " +
+ A.getFileName() + " (can't determine architecture for it)")
+ .str()
+ .c_str());
+
+ if (MFO) {
+ Slice ArchiveSlice(*(MFO.get()), MFO->is64Bit() ? 3 : 2);
+ ArchiveSlice.B = &A;
+ return ArchiveSlice;
+ }
+
+ // For IR objects
+ Expected<Slice> ArchiveSliceOrErr = Slice::create(*IRFO, 0);
+ if (!ArchiveSliceOrErr)
+ return createFileError(A.getFileName(), ArchiveSliceOrErr.takeError());
+ auto &ArchiveSlice = ArchiveSliceOrErr.get();
+ ArchiveSlice.B = &A;
+ return std::move(ArchiveSlice);
+}
+
+Expected<Slice> Slice::create(const IRObjectFile &IRO, uint32_t Align) {
+ Expected<MachoCPUTy> CPUOrErr = getMachoCPUFromTriple(IRO.getTargetTriple());
+ if (!CPUOrErr)
+ return CPUOrErr.takeError();
+ unsigned CPUType, CPUSubType;
+ std::tie(CPUType, CPUSubType) = CPUOrErr.get();
+ // We don't directly use the architecture name of the target triple T, as,
+ // for instance, thumb is treated as ARM by the MachOUniversal object.
+ std::string ArchName(
+ MachOObjectFile::getArchTriple(CPUType, CPUSubType).getArchName());
+ return Slice{IRO, CPUType, CPUSubType, std::move(ArchName), Align};
+}
+
+static Expected<SmallVector<MachO::fat_arch, 2>>
+buildFatArchList(ArrayRef<Slice> Slices) {
+ SmallVector<MachO::fat_arch, 2> FatArchList;
+ uint64_t Offset =
+ sizeof(MachO::fat_header) + Slices.size() * sizeof(MachO::fat_arch);
+
+ for (const auto &S : Slices) {
+ Offset = alignTo(Offset, 1ull << S.getP2Alignment());
+ if (Offset > UINT32_MAX)
+ return createStringError(
+ std::errc::invalid_argument,
+ ("fat file too large to be created because the offset "
+ "field in struct fat_arch is only 32-bits and the offset " +
+ Twine(Offset) + " for " + S.getBinary()->getFileName() +
+ " for architecture " + S.getArchString() + "exceeds that.")
+ .str()
+ .c_str());
+
+ MachO::fat_arch FatArch;
+ FatArch.cputype = S.getCPUType();
+ FatArch.cpusubtype = S.getCPUSubType();
+ FatArch.offset = Offset;
+ FatArch.size = S.getBinary()->getMemoryBufferRef().getBufferSize();
+ FatArch.align = S.getP2Alignment();
+ Offset += FatArch.size;
+ FatArchList.push_back(FatArch);
+ }
+ return FatArchList;
+}
+
+static Error writeUniversalBinaryToStream(ArrayRef<Slice> Slices,
+ raw_ostream &Out) {
+ MachO::fat_header FatHeader;
+ FatHeader.magic = MachO::FAT_MAGIC;
+ FatHeader.nfat_arch = Slices.size();
+
+ Expected<SmallVector<MachO::fat_arch, 2>> FatArchListOrErr =
+ buildFatArchList(Slices);
+ if (!FatArchListOrErr)
+ return FatArchListOrErr.takeError();
+ SmallVector<MachO::fat_arch, 2> FatArchList = *FatArchListOrErr;
+
+ if (sys::IsLittleEndianHost)
+ MachO::swapStruct(FatHeader);
+ Out.write(reinterpret_cast<const char *>(&FatHeader),
+ sizeof(MachO::fat_header));
+
+ if (sys::IsLittleEndianHost)
+ for (MachO::fat_arch &FA : FatArchList)
+ MachO::swapStruct(FA);
+ Out.write(reinterpret_cast<const char *>(FatArchList.data()),
+ sizeof(MachO::fat_arch) * FatArchList.size());
+
+ if (sys::IsLittleEndianHost)
+ for (MachO::fat_arch &FA : FatArchList)
+ MachO::swapStruct(FA);
+
+ size_t Offset =
+ sizeof(MachO::fat_header) + sizeof(MachO::fat_arch) * FatArchList.size();
+ for (size_t Index = 0, Size = Slices.size(); Index < Size; ++Index) {
+ MemoryBufferRef BufferRef = Slices[Index].getBinary()->getMemoryBufferRef();
+ assert((Offset <= FatArchList[Index].offset) && "Incorrect slice offset");
+ Out.write_zeros(FatArchList[Index].offset - Offset);
+ Out.write(BufferRef.getBufferStart(), BufferRef.getBufferSize());
+ Offset = FatArchList[Index].offset + BufferRef.getBufferSize();
+ }
+
+ Out.flush();
+ return Error::success();
+}
+
+Error object::writeUniversalBinary(ArrayRef<Slice> Slices,
+ StringRef OutputFileName) {
+ const bool IsExecutable = any_of(Slices, [](Slice S) {
+ return sys::fs::can_execute(S.getBinary()->getFileName());
+ });
+ unsigned Mode = sys::fs::all_read | sys::fs::all_write;
+ if (IsExecutable)
+ Mode |= sys::fs::all_exe;
+ Expected<sys::fs::TempFile> Temp = sys::fs::TempFile::create(
+ OutputFileName + ".temp-universal-%%%%%%", Mode);
+ if (!Temp)
+ return Temp.takeError();
+ raw_fd_ostream Out(Temp->FD, false);
+ if (Error E = writeUniversalBinaryToStream(Slices, Out)) {
+ if (Error DiscardError = Temp->discard())
+ return joinErrors(std::move(E), std::move(DiscardError));
+ return E;
+ }
+ return Temp->keep(OutputFileName);
+}
+
+Expected<std::unique_ptr<MemoryBuffer>>
+object::writeUniversalBinaryToBuffer(ArrayRef<Slice> Slices) {
+ SmallVector<char, 0> Buffer;
+ raw_svector_ostream Out(Buffer);
+
+ if (Error E = writeUniversalBinaryToStream(Slices, Out))
+ return std::move(E);
+
+ return std::make_unique<SmallVectorMemoryBuffer>(std::move(Buffer));
+}
diff --git a/contrib/libs/llvm12/lib/Object/ObjectFile.cpp b/contrib/libs/llvm12/lib/Object/ObjectFile.cpp
index c494f99045..cf09a66d9c 100644
--- a/contrib/libs/llvm12/lib/Object/ObjectFile.cpp
+++ b/contrib/libs/llvm12/lib/Object/ObjectFile.cpp
@@ -132,8 +132,8 @@ Triple ObjectFile::makeTriple() const {
}
Expected<std::unique_ptr<ObjectFile>>
-ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type,
- bool InitContent) {
+ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type,
+ bool InitContent) {
StringRef Data = Object.getBuffer();
if (Type == file_magic::unknown)
Type = identify_magic(Data);
@@ -155,7 +155,7 @@ ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type,
case file_magic::elf_executable:
case file_magic::elf_shared_object:
case file_magic::elf_core:
- return createELFObjectFile(Object, InitContent);
+ return createELFObjectFile(Object, InitContent);
case file_magic::macho_object:
case file_magic::macho_executable:
case file_magic::macho_fixed_virtual_memory_shared_lib:
diff --git a/contrib/libs/llvm12/lib/Object/RelocationResolver.cpp b/contrib/libs/llvm12/lib/Object/RelocationResolver.cpp
index b6978b8c09..204577af72 100644
--- a/contrib/libs/llvm12/lib/Object/RelocationResolver.cpp
+++ b/contrib/libs/llvm12/lib/Object/RelocationResolver.cpp
@@ -39,21 +39,21 @@ static bool supportsX86_64(uint64_t Type) {
}
}
-static uint64_t resolveX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t LocData, int64_t Addend) {
- switch (Type) {
+static uint64_t resolveX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t LocData, int64_t Addend) {
+ switch (Type) {
case ELF::R_X86_64_NONE:
- return LocData;
+ return LocData;
case ELF::R_X86_64_64:
case ELF::R_X86_64_DTPOFF32:
case ELF::R_X86_64_DTPOFF64:
- return S + Addend;
+ return S + Addend;
case ELF::R_X86_64_PC32:
case ELF::R_X86_64_PC64:
- return S + Addend - Offset;
+ return S + Addend - Offset;
case ELF::R_X86_64_32:
case ELF::R_X86_64_32S:
- return (S + Addend) & 0xFFFFFFFF;
+ return (S + Addend) & 0xFFFFFFFF;
default:
llvm_unreachable("Invalid relocation type");
}
@@ -71,17 +71,17 @@ static bool supportsAArch64(uint64_t Type) {
}
}
-static uint64_t resolveAArch64(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t /*LocData*/, int64_t Addend) {
- switch (Type) {
+static uint64_t resolveAArch64(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t /*LocData*/, int64_t Addend) {
+ switch (Type) {
case ELF::R_AARCH64_ABS32:
- return (S + Addend) & 0xFFFFFFFF;
+ return (S + Addend) & 0xFFFFFFFF;
case ELF::R_AARCH64_ABS64:
- return S + Addend;
+ return S + Addend;
case ELF::R_AARCH64_PREL32:
- return (S + Addend - Offset) & 0xFFFFFFFF;
+ return (S + Addend - Offset) & 0xFFFFFFFF;
case ELF::R_AARCH64_PREL64:
- return S + Addend - Offset;
+ return S + Addend - Offset;
default:
llvm_unreachable("Invalid relocation type");
}
@@ -97,13 +97,13 @@ static bool supportsBPF(uint64_t Type) {
}
}
-static uint64_t resolveBPF(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t LocData, int64_t /*Addend*/) {
- switch (Type) {
+static uint64_t resolveBPF(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t LocData, int64_t /*Addend*/) {
+ switch (Type) {
case ELF::R_BPF_64_32:
- return (S + LocData) & 0xFFFFFFFF;
+ return (S + LocData) & 0xFFFFFFFF;
case ELF::R_BPF_64_64:
- return S + LocData;
+ return S + LocData;
default:
llvm_unreachable("Invalid relocation type");
}
@@ -121,17 +121,17 @@ static bool supportsMips64(uint64_t Type) {
}
}
-static uint64_t resolveMips64(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t /*LocData*/, int64_t Addend) {
- switch (Type) {
+static uint64_t resolveMips64(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t /*LocData*/, int64_t Addend) {
+ switch (Type) {
case ELF::R_MIPS_32:
- return (S + Addend) & 0xFFFFFFFF;
+ return (S + Addend) & 0xFFFFFFFF;
case ELF::R_MIPS_64:
- return S + Addend;
+ return S + Addend;
case ELF::R_MIPS_TLS_DTPREL64:
- return S + Addend - 0x8000;
+ return S + Addend - 0x8000;
case ELF::R_MIPS_PC32:
- return S + Addend - Offset;
+ return S + Addend - Offset;
default:
llvm_unreachable("Invalid relocation type");
}
@@ -147,13 +147,13 @@ static bool supportsMSP430(uint64_t Type) {
}
}
-static uint64_t resolveMSP430(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t /*LocData*/, int64_t Addend) {
- switch (Type) {
+static uint64_t resolveMSP430(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t /*LocData*/, int64_t Addend) {
+ switch (Type) {
case ELF::R_MSP430_32:
- return (S + Addend) & 0xFFFFFFFF;
+ return (S + Addend) & 0xFFFFFFFF;
case ELF::R_MSP430_16_BYTE:
- return (S + Addend) & 0xFFFF;
+ return (S + Addend) & 0xFFFF;
default:
llvm_unreachable("Invalid relocation type");
}
@@ -171,17 +171,17 @@ static bool supportsPPC64(uint64_t Type) {
}
}
-static uint64_t resolvePPC64(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t /*LocData*/, int64_t Addend) {
- switch (Type) {
+static uint64_t resolvePPC64(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t /*LocData*/, int64_t Addend) {
+ switch (Type) {
case ELF::R_PPC64_ADDR32:
- return (S + Addend) & 0xFFFFFFFF;
+ return (S + Addend) & 0xFFFFFFFF;
case ELF::R_PPC64_ADDR64:
- return S + Addend;
+ return S + Addend;
case ELF::R_PPC64_REL32:
- return (S + Addend - Offset) & 0xFFFFFFFF;
+ return (S + Addend - Offset) & 0xFFFFFFFF;
case ELF::R_PPC64_REL64:
- return S + Addend - Offset;
+ return S + Addend - Offset;
default:
llvm_unreachable("Invalid relocation type");
}
@@ -197,13 +197,13 @@ static bool supportsSystemZ(uint64_t Type) {
}
}
-static uint64_t resolveSystemZ(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t /*LocData*/, int64_t Addend) {
- switch (Type) {
+static uint64_t resolveSystemZ(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t /*LocData*/, int64_t Addend) {
+ switch (Type) {
case ELF::R_390_32:
- return (S + Addend) & 0xFFFFFFFF;
+ return (S + Addend) & 0xFFFFFFFF;
case ELF::R_390_64:
- return S + Addend;
+ return S + Addend;
default:
llvm_unreachable("Invalid relocation type");
}
@@ -221,14 +221,14 @@ static bool supportsSparc64(uint64_t Type) {
}
}
-static uint64_t resolveSparc64(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t /*LocData*/, int64_t Addend) {
- switch (Type) {
+static uint64_t resolveSparc64(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t /*LocData*/, int64_t Addend) {
+ switch (Type) {
case ELF::R_SPARC_32:
case ELF::R_SPARC_64:
case ELF::R_SPARC_UA32:
case ELF::R_SPARC_UA64:
- return S + Addend;
+ return S + Addend;
default:
llvm_unreachable("Invalid relocation type");
}
@@ -244,12 +244,12 @@ static bool supportsAmdgpu(uint64_t Type) {
}
}
-static uint64_t resolveAmdgpu(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t /*LocData*/, int64_t Addend) {
- switch (Type) {
+static uint64_t resolveAmdgpu(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t /*LocData*/, int64_t Addend) {
+ switch (Type) {
case ELF::R_AMDGPU_ABS32:
case ELF::R_AMDGPU_ABS64:
- return S + Addend;
+ return S + Addend;
default:
llvm_unreachable("Invalid relocation type");
}
@@ -266,15 +266,15 @@ static bool supportsX86(uint64_t Type) {
}
}
-static uint64_t resolveX86(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t LocData, int64_t /*Addend*/) {
- switch (Type) {
+static uint64_t resolveX86(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t LocData, int64_t /*Addend*/) {
+ switch (Type) {
case ELF::R_386_NONE:
- return LocData;
+ return LocData;
case ELF::R_386_32:
- return S + LocData;
+ return S + LocData;
case ELF::R_386_PC32:
- return S - Offset + LocData;
+ return S - Offset + LocData;
default:
llvm_unreachable("Invalid relocation type");
}
@@ -290,35 +290,35 @@ static bool supportsPPC32(uint64_t Type) {
}
}
-static uint64_t resolvePPC32(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t /*LocData*/, int64_t Addend) {
- switch (Type) {
+static uint64_t resolvePPC32(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t /*LocData*/, int64_t Addend) {
+ switch (Type) {
case ELF::R_PPC_ADDR32:
- return (S + Addend) & 0xFFFFFFFF;
+ return (S + Addend) & 0xFFFFFFFF;
case ELF::R_PPC_REL32:
- return (S + Addend - Offset) & 0xFFFFFFFF;
+ return (S + Addend - Offset) & 0xFFFFFFFF;
}
llvm_unreachable("Invalid relocation type");
}
static bool supportsARM(uint64_t Type) {
- switch (Type) {
- case ELF::R_ARM_ABS32:
- case ELF::R_ARM_REL32:
- return true;
- default:
- return false;
- }
-}
-
-static uint64_t resolveARM(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t LocData, int64_t /*Addend*/) {
- switch (Type) {
- case ELF::R_ARM_ABS32:
- return (S + LocData) & 0xFFFFFFFF;
- case ELF::R_ARM_REL32:
- return (S + LocData - Offset) & 0xFFFFFFFF;
- }
+ switch (Type) {
+ case ELF::R_ARM_ABS32:
+ case ELF::R_ARM_REL32:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static uint64_t resolveARM(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t LocData, int64_t /*Addend*/) {
+ switch (Type) {
+ case ELF::R_ARM_ABS32:
+ return (S + LocData) & 0xFFFFFFFF;
+ case ELF::R_ARM_REL32:
+ return (S + LocData - Offset) & 0xFFFFFFFF;
+ }
llvm_unreachable("Invalid relocation type");
}
@@ -332,13 +332,13 @@ static bool supportsAVR(uint64_t Type) {
}
}
-static uint64_t resolveAVR(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t /*LocData*/, int64_t Addend) {
- switch (Type) {
+static uint64_t resolveAVR(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t /*LocData*/, int64_t Addend) {
+ switch (Type) {
case ELF::R_AVR_16:
- return (S + Addend) & 0xFFFF;
+ return (S + Addend) & 0xFFFF;
case ELF::R_AVR_32:
- return (S + Addend) & 0xFFFFFFFF;
+ return (S + Addend) & 0xFFFFFFFF;
default:
llvm_unreachable("Invalid relocation type");
}
@@ -348,10 +348,10 @@ static bool supportsLanai(uint64_t Type) {
return Type == ELF::R_LANAI_32;
}
-static uint64_t resolveLanai(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t /*LocData*/, int64_t Addend) {
- if (Type == ELF::R_LANAI_32)
- return (S + Addend) & 0xFFFFFFFF;
+static uint64_t resolveLanai(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t /*LocData*/, int64_t Addend) {
+ if (Type == ELF::R_LANAI_32)
+ return (S + Addend) & 0xFFFFFFFF;
llvm_unreachable("Invalid relocation type");
}
@@ -365,13 +365,13 @@ static bool supportsMips32(uint64_t Type) {
}
}
-static uint64_t resolveMips32(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t LocData, int64_t /*Addend*/) {
+static uint64_t resolveMips32(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t LocData, int64_t /*Addend*/) {
// FIXME: Take in account implicit addends to get correct results.
- if (Type == ELF::R_MIPS_32)
- return (S + LocData) & 0xFFFFFFFF;
- if (Type == ELF::R_MIPS_TLS_DTPREL32)
- return (S + LocData) & 0xFFFFFFFF;
+ if (Type == ELF::R_MIPS_32)
+ return (S + LocData) & 0xFFFFFFFF;
+ if (Type == ELF::R_MIPS_TLS_DTPREL32)
+ return (S + LocData) & 0xFFFFFFFF;
llvm_unreachable("Invalid relocation type");
}
@@ -385,21 +385,21 @@ static bool supportsSparc32(uint64_t Type) {
}
}
-static uint64_t resolveSparc32(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t LocData, int64_t Addend) {
- if (Type == ELF::R_SPARC_32 || Type == ELF::R_SPARC_UA32)
- return S + Addend;
- return LocData;
+static uint64_t resolveSparc32(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t LocData, int64_t Addend) {
+ if (Type == ELF::R_SPARC_32 || Type == ELF::R_SPARC_UA32)
+ return S + Addend;
+ return LocData;
}
static bool supportsHexagon(uint64_t Type) {
return Type == ELF::R_HEX_32;
}
-static uint64_t resolveHexagon(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t /*LocData*/, int64_t Addend) {
- if (Type == ELF::R_HEX_32)
- return S + Addend;
+static uint64_t resolveHexagon(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t /*LocData*/, int64_t Addend) {
+ if (Type == ELF::R_HEX_32)
+ return S + Addend;
llvm_unreachable("Invalid relocation type");
}
@@ -425,17 +425,17 @@ static bool supportsRISCV(uint64_t Type) {
}
}
-static uint64_t resolveRISCV(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t LocData, int64_t Addend) {
- int64_t RA = Addend;
- uint64_t A = LocData;
- switch (Type) {
+static uint64_t resolveRISCV(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t LocData, int64_t Addend) {
+ int64_t RA = Addend;
+ uint64_t A = LocData;
+ switch (Type) {
case ELF::R_RISCV_NONE:
- return LocData;
+ return LocData;
case ELF::R_RISCV_32:
return (S + RA) & 0xFFFFFFFF;
case ELF::R_RISCV_32_PCREL:
- return (S + RA - Offset) & 0xFFFFFFFF;
+ return (S + RA - Offset) & 0xFFFFFFFF;
case ELF::R_RISCV_64:
return S + RA;
case ELF::R_RISCV_SET6:
@@ -473,12 +473,12 @@ static bool supportsCOFFX86(uint64_t Type) {
}
}
-static uint64_t resolveCOFFX86(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t LocData, int64_t /*Addend*/) {
- switch (Type) {
+static uint64_t resolveCOFFX86(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t LocData, int64_t /*Addend*/) {
+ switch (Type) {
case COFF::IMAGE_REL_I386_SECREL:
case COFF::IMAGE_REL_I386_DIR32:
- return (S + LocData) & 0xFFFFFFFF;
+ return (S + LocData) & 0xFFFFFFFF;
default:
llvm_unreachable("Invalid relocation type");
}
@@ -494,13 +494,13 @@ static bool supportsCOFFX86_64(uint64_t Type) {
}
}
-static uint64_t resolveCOFFX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t LocData, int64_t /*Addend*/) {
- switch (Type) {
+static uint64_t resolveCOFFX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t LocData, int64_t /*Addend*/) {
+ switch (Type) {
case COFF::IMAGE_REL_AMD64_SECREL:
- return (S + LocData) & 0xFFFFFFFF;
+ return (S + LocData) & 0xFFFFFFFF;
case COFF::IMAGE_REL_AMD64_ADDR64:
- return S + LocData;
+ return S + LocData;
default:
llvm_unreachable("Invalid relocation type");
}
@@ -516,12 +516,12 @@ static bool supportsCOFFARM(uint64_t Type) {
}
}
-static uint64_t resolveCOFFARM(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t LocData, int64_t /*Addend*/) {
- switch (Type) {
+static uint64_t resolveCOFFARM(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t LocData, int64_t /*Addend*/) {
+ switch (Type) {
case COFF::IMAGE_REL_ARM_SECREL:
case COFF::IMAGE_REL_ARM_ADDR32:
- return (S + LocData) & 0xFFFFFFFF;
+ return (S + LocData) & 0xFFFFFFFF;
default:
llvm_unreachable("Invalid relocation type");
}
@@ -537,13 +537,13 @@ static bool supportsCOFFARM64(uint64_t Type) {
}
}
-static uint64_t resolveCOFFARM64(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t LocData, int64_t /*Addend*/) {
- switch (Type) {
+static uint64_t resolveCOFFARM64(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t LocData, int64_t /*Addend*/) {
+ switch (Type) {
case COFF::IMAGE_REL_ARM64_SECREL:
- return (S + LocData) & 0xFFFFFFFF;
+ return (S + LocData) & 0xFFFFFFFF;
case COFF::IMAGE_REL_ARM64_ADDR64:
- return S + LocData;
+ return S + LocData;
default:
llvm_unreachable("Invalid relocation type");
}
@@ -553,9 +553,9 @@ static bool supportsMachOX86_64(uint64_t Type) {
return Type == MachO::X86_64_RELOC_UNSIGNED;
}
-static uint64_t resolveMachOX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t LocData, int64_t /*Addend*/) {
- if (Type == MachO::X86_64_RELOC_UNSIGNED)
+static uint64_t resolveMachOX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t LocData, int64_t /*Addend*/) {
+ if (Type == MachO::X86_64_RELOC_UNSIGNED)
return S;
llvm_unreachable("Invalid relocation type");
}
@@ -574,7 +574,7 @@ static bool supportsWasm32(uint64_t Type) {
case wasm::R_WASM_SECTION_OFFSET_I32:
case wasm::R_WASM_EVENT_INDEX_LEB:
case wasm::R_WASM_GLOBAL_INDEX_I32:
- case wasm::R_WASM_TABLE_NUMBER_LEB:
+ case wasm::R_WASM_TABLE_NUMBER_LEB:
return true;
default:
return false;
@@ -586,18 +586,18 @@ static bool supportsWasm64(uint64_t Type) {
case wasm::R_WASM_MEMORY_ADDR_LEB64:
case wasm::R_WASM_MEMORY_ADDR_SLEB64:
case wasm::R_WASM_MEMORY_ADDR_I64:
- case wasm::R_WASM_TABLE_INDEX_SLEB64:
- case wasm::R_WASM_TABLE_INDEX_I64:
- case wasm::R_WASM_FUNCTION_OFFSET_I64:
+ case wasm::R_WASM_TABLE_INDEX_SLEB64:
+ case wasm::R_WASM_TABLE_INDEX_I64:
+ case wasm::R_WASM_FUNCTION_OFFSET_I64:
return true;
default:
return supportsWasm32(Type);
}
}
-static uint64_t resolveWasm32(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t LocData, int64_t /*Addend*/) {
- switch (Type) {
+static uint64_t resolveWasm32(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t LocData, int64_t /*Addend*/) {
+ switch (Type) {
case wasm::R_WASM_FUNCTION_INDEX_LEB:
case wasm::R_WASM_TABLE_INDEX_SLEB:
case wasm::R_WASM_TABLE_INDEX_I32:
@@ -610,31 +610,31 @@ static uint64_t resolveWasm32(uint64_t Type, uint64_t Offset, uint64_t S,
case wasm::R_WASM_SECTION_OFFSET_I32:
case wasm::R_WASM_EVENT_INDEX_LEB:
case wasm::R_WASM_GLOBAL_INDEX_I32:
- case wasm::R_WASM_TABLE_NUMBER_LEB:
+ case wasm::R_WASM_TABLE_NUMBER_LEB:
// For wasm section, its offset at 0 -- ignoring Value
- return LocData;
+ return LocData;
default:
llvm_unreachable("Invalid relocation type");
}
}
-static uint64_t resolveWasm64(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t LocData, int64_t Addend) {
- switch (Type) {
+static uint64_t resolveWasm64(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t LocData, int64_t Addend) {
+ switch (Type) {
case wasm::R_WASM_MEMORY_ADDR_LEB64:
case wasm::R_WASM_MEMORY_ADDR_SLEB64:
case wasm::R_WASM_MEMORY_ADDR_I64:
- case wasm::R_WASM_TABLE_INDEX_SLEB64:
- case wasm::R_WASM_TABLE_INDEX_I64:
- case wasm::R_WASM_FUNCTION_OFFSET_I64:
+ case wasm::R_WASM_TABLE_INDEX_SLEB64:
+ case wasm::R_WASM_TABLE_INDEX_I64:
+ case wasm::R_WASM_FUNCTION_OFFSET_I64:
// For wasm section, its offset at 0 -- ignoring Value
- return LocData;
+ return LocData;
default:
- return resolveWasm32(Type, Offset, S, LocData, Addend);
+ return resolveWasm32(Type, Offset, S, LocData, Addend);
}
}
-std::pair<SupportsRelocation, RelocationResolver>
+std::pair<SupportsRelocation, RelocationResolver>
getRelocationResolver(const ObjectFile &Obj) {
if (Obj.isCOFF()) {
switch (Obj.getArch()) {
@@ -687,7 +687,7 @@ getRelocationResolver(const ObjectFile &Obj) {
switch (Obj.getArch()) {
case Triple::x86:
return {supportsX86, resolveX86};
- case Triple::ppcle:
+ case Triple::ppcle:
case Triple::ppc:
return {supportsPPC32, resolvePPC32};
case Triple::arm:
@@ -726,38 +726,38 @@ getRelocationResolver(const ObjectFile &Obj) {
llvm_unreachable("Invalid object file");
}
-uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,
- uint64_t S, uint64_t LocData) {
- if (const ObjectFile *Obj = R.getObject()) {
- int64_t Addend = 0;
- if (Obj->isELF()) {
- auto GetRelSectionType = [&]() -> unsigned {
- if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))
- return Elf32LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
- if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))
- return Elf64LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
- if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))
- return Elf32BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
- auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj);
- return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
- };
-
- if (GetRelSectionType() == ELF::SHT_RELA)
- Addend = getELFAddend(R);
- }
-
- return Resolver(R.getType(), R.getOffset(), S, LocData, Addend);
- }
-
- // Sometimes the caller might want to use its own specific implementation of
- // the resolver function. E.g. this is used by LLD when it resolves debug
- // relocations and assumes that all of them have the same computation (S + A).
- // The relocation R has no owner object in this case and we don't need to
- // provide Type and Offset fields. It is also assumed the DataRefImpl.p
- // contains the addend, provided by the caller.
- return Resolver(/*Type=*/0, /*Offset=*/0, S, LocData,
- R.getRawDataRefImpl().p);
-}
-
+uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,
+ uint64_t S, uint64_t LocData) {
+ if (const ObjectFile *Obj = R.getObject()) {
+ int64_t Addend = 0;
+ if (Obj->isELF()) {
+ auto GetRelSectionType = [&]() -> unsigned {
+ if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))
+ return Elf32LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
+ if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))
+ return Elf64LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
+ if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))
+ return Elf32BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
+ auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj);
+ return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
+ };
+
+ if (GetRelSectionType() == ELF::SHT_RELA)
+ Addend = getELFAddend(R);
+ }
+
+ return Resolver(R.getType(), R.getOffset(), S, LocData, Addend);
+ }
+
+ // Sometimes the caller might want to use its own specific implementation of
+ // the resolver function. E.g. this is used by LLD when it resolves debug
+ // relocations and assumes that all of them have the same computation (S + A).
+ // The relocation R has no owner object in this case and we don't need to
+ // provide Type and Offset fields. It is also assumed the DataRefImpl.p
+ // contains the addend, provided by the caller.
+ return Resolver(/*Type=*/0, /*Offset=*/0, S, LocData,
+ R.getRawDataRefImpl().p);
+}
+
} // namespace object
} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/Object/SymbolSize.cpp b/contrib/libs/llvm12/lib/Object/SymbolSize.cpp
index 15d3c1fe7d..97baabec08 100644
--- a/contrib/libs/llvm12/lib/Object/SymbolSize.cpp
+++ b/contrib/libs/llvm12/lib/Object/SymbolSize.cpp
@@ -48,7 +48,7 @@ llvm::object::computeSymbolSizes(const ObjectFile &O) {
if (const auto *E = dyn_cast<ELFObjectFileBase>(&O)) {
auto Syms = E->symbols();
- if (Syms.empty())
+ if (Syms.empty())
Syms = E->getDynamicSymbolIterators();
for (ELFSymbolRef Sym : Syms)
Ret.push_back({Sym, Sym.getSize()});
diff --git a/contrib/libs/llvm12/lib/Object/SymbolicFile.cpp b/contrib/libs/llvm12/lib/Object/SymbolicFile.cpp
index 5b35000565..34a2c5e1c1 100644
--- a/contrib/libs/llvm12/lib/Object/SymbolicFile.cpp
+++ b/contrib/libs/llvm12/lib/Object/SymbolicFile.cpp
@@ -36,19 +36,19 @@ SymbolicFile::~SymbolicFile() = default;
Expected<std::unique_ptr<SymbolicFile>>
SymbolicFile::createSymbolicFile(MemoryBufferRef Object, file_magic Type,
- LLVMContext *Context, bool InitContent) {
+ LLVMContext *Context, bool InitContent) {
StringRef Data = Object.getBuffer();
if (Type == file_magic::unknown)
Type = identify_magic(Data);
- if (!isSymbolicFile(Type, Context))
- return errorCodeToError(object_error::invalid_file_type);
-
+ if (!isSymbolicFile(Type, Context))
+ return errorCodeToError(object_error::invalid_file_type);
+
switch (Type) {
case file_magic::bitcode:
- // Context is guaranteed to be non-null here, because bitcode magic only
- // indicates a symbolic file when Context is non-null.
- return IRObjectFile::create(Object, *Context);
+ // Context is guaranteed to be non-null here, because bitcode magic only
+ // indicates a symbolic file when Context is non-null.
+ return IRObjectFile::create(Object, *Context);
case file_magic::elf:
case file_magic::elf_executable:
case file_magic::elf_shared_object:
@@ -67,14 +67,14 @@ SymbolicFile::createSymbolicFile(MemoryBufferRef Object, file_magic Type,
case file_magic::xcoff_object_32:
case file_magic::xcoff_object_64:
case file_magic::wasm_object:
- return ObjectFile::createObjectFile(Object, Type, InitContent);
+ return ObjectFile::createObjectFile(Object, Type, InitContent);
case file_magic::coff_import_library:
return std::unique_ptr<SymbolicFile>(new COFFImportFile(Object));
case file_magic::elf_relocatable:
case file_magic::macho_object:
case file_magic::coff_object: {
Expected<std::unique_ptr<ObjectFile>> Obj =
- ObjectFile::createObjectFile(Object, Type, InitContent);
+ ObjectFile::createObjectFile(Object, Type, InitContent);
if (!Obj || !Context)
return std::move(Obj);
@@ -89,39 +89,39 @@ SymbolicFile::createSymbolicFile(MemoryBufferRef Object, file_magic Type,
MemoryBufferRef(BCData->getBuffer(), Object.getBufferIdentifier()),
*Context);
}
- default:
- llvm_unreachable("Unexpected Binary File Type");
+ default:
+ llvm_unreachable("Unexpected Binary File Type");
+ }
+}
+
+bool SymbolicFile::isSymbolicFile(file_magic Type, const LLVMContext *Context) {
+ switch (Type) {
+ case file_magic::bitcode:
+ return Context != nullptr;
+ case file_magic::elf:
+ case file_magic::elf_executable:
+ case file_magic::elf_shared_object:
+ case file_magic::elf_core:
+ case file_magic::macho_executable:
+ case file_magic::macho_fixed_virtual_memory_shared_lib:
+ case file_magic::macho_core:
+ case file_magic::macho_preload_executable:
+ case file_magic::macho_dynamically_linked_shared_lib:
+ case file_magic::macho_dynamic_linker:
+ case file_magic::macho_bundle:
+ case file_magic::macho_dynamically_linked_shared_lib_stub:
+ case file_magic::macho_dsym_companion:
+ case file_magic::macho_kext_bundle:
+ case file_magic::pecoff_executable:
+ case file_magic::xcoff_object_32:
+ case file_magic::xcoff_object_64:
+ case file_magic::wasm_object:
+ case file_magic::coff_import_library:
+ case file_magic::elf_relocatable:
+ case file_magic::macho_object:
+ case file_magic::coff_object:
+ return true;
+ default:
+ return false;
}
}
-
-bool SymbolicFile::isSymbolicFile(file_magic Type, const LLVMContext *Context) {
- switch (Type) {
- case file_magic::bitcode:
- return Context != nullptr;
- case file_magic::elf:
- case file_magic::elf_executable:
- case file_magic::elf_shared_object:
- case file_magic::elf_core:
- case file_magic::macho_executable:
- case file_magic::macho_fixed_virtual_memory_shared_lib:
- case file_magic::macho_core:
- case file_magic::macho_preload_executable:
- case file_magic::macho_dynamically_linked_shared_lib:
- case file_magic::macho_dynamic_linker:
- case file_magic::macho_bundle:
- case file_magic::macho_dynamically_linked_shared_lib_stub:
- case file_magic::macho_dsym_companion:
- case file_magic::macho_kext_bundle:
- case file_magic::pecoff_executable:
- case file_magic::xcoff_object_32:
- case file_magic::xcoff_object_64:
- case file_magic::wasm_object:
- case file_magic::coff_import_library:
- case file_magic::elf_relocatable:
- case file_magic::macho_object:
- case file_magic::coff_object:
- return true;
- default:
- return false;
- }
-}
diff --git a/contrib/libs/llvm12/lib/Object/WasmObjectFile.cpp b/contrib/libs/llvm12/lib/Object/WasmObjectFile.cpp
index 52cb9abec8..40f468881e 100644
--- a/contrib/libs/llvm12/lib/Object/WasmObjectFile.cpp
+++ b/contrib/libs/llvm12/lib/Object/WasmObjectFile.cpp
@@ -187,19 +187,19 @@ static Error readInitExpr(wasm::WasmInitExpr &Expr,
case wasm::WASM_OPCODE_REF_NULL: {
wasm::ValType Ty = static_cast<wasm::ValType>(readULEB128(Ctx));
if (Ty != wasm::ValType::EXTERNREF) {
- return make_error<GenericBinaryError>("invalid type for ref.null",
+ return make_error<GenericBinaryError>("invalid type for ref.null",
object_error::parse_failed);
}
break;
}
default:
- return make_error<GenericBinaryError>("invalid opcode in init_expr",
+ return make_error<GenericBinaryError>("invalid opcode in init_expr",
object_error::parse_failed);
}
uint8_t EndOpcode = readOpcode(Ctx);
if (EndOpcode != wasm::WASM_OPCODE_END) {
- return make_error<GenericBinaryError>("invalid init_expr",
+ return make_error<GenericBinaryError>("invalid init_expr",
object_error::parse_failed);
}
return Error::success();
@@ -214,11 +214,11 @@ static wasm::WasmLimits readLimits(WasmObjectFile::ReadContext &Ctx) {
return Result;
}
-static wasm::WasmTableType readTableType(WasmObjectFile::ReadContext &Ctx) {
- wasm::WasmTableType TableType;
- TableType.ElemType = readUint8(Ctx);
- TableType.Limits = readLimits(Ctx);
- return TableType;
+static wasm::WasmTableType readTableType(WasmObjectFile::ReadContext &Ctx) {
+ wasm::WasmTableType TableType;
+ TableType.ElemType = readUint8(Ctx);
+ TableType.Limits = readLimits(Ctx);
+ return TableType;
}
static Error readSection(WasmSection &Section, WasmObjectFile::ReadContext &Ctx,
@@ -228,10 +228,10 @@ static Error readSection(WasmSection &Section, WasmObjectFile::ReadContext &Ctx,
LLVM_DEBUG(dbgs() << "readSection type=" << Section.Type << "\n");
uint32_t Size = readVaruint32(Ctx);
if (Size == 0)
- return make_error<StringError>("zero length section",
+ return make_error<StringError>("zero length section",
object_error::parse_failed);
if (Ctx.Ptr + Size > Ctx.End)
- return make_error<StringError>("section too large",
+ return make_error<StringError>("section too large",
object_error::parse_failed);
if (Section.Type == wasm::WASM_SEC_CUSTOM) {
WasmObjectFile::ReadContext SectionCtx;
@@ -247,7 +247,7 @@ static Error readSection(WasmSection &Section, WasmObjectFile::ReadContext &Ctx,
}
if (!Checker.isValidSectionOrder(Section.Type, Section.Name)) {
- return make_error<StringError>("out of order section type: " +
+ return make_error<StringError>("out of order section type: " +
llvm::to_string(Section.Type),
object_error::parse_failed);
}
@@ -262,8 +262,8 @@ WasmObjectFile::WasmObjectFile(MemoryBufferRef Buffer, Error &Err)
ErrorAsOutParameter ErrAsOutParam(&Err);
Header.Magic = getData().substr(0, 4);
if (Header.Magic != StringRef("\0asm", 4)) {
- Err = make_error<StringError>("invalid magic number",
- object_error::parse_failed);
+ Err = make_error<StringError>("invalid magic number",
+ object_error::parse_failed);
return;
}
@@ -273,15 +273,15 @@ WasmObjectFile::WasmObjectFile(MemoryBufferRef Buffer, Error &Err)
Ctx.End = Ctx.Start + getData().size();
if (Ctx.Ptr + 4 > Ctx.End) {
- Err = make_error<StringError>("missing version number",
+ Err = make_error<StringError>("missing version number",
object_error::parse_failed);
return;
}
Header.Version = readUint32(Ctx);
if (Header.Version != wasm::WasmVersion) {
- Err = make_error<StringError>("invalid version number: " +
- Twine(Header.Version),
+ Err = make_error<StringError>("invalid version number: " +
+ Twine(Header.Version),
object_error::parse_failed);
return;
}
@@ -334,7 +334,7 @@ Error WasmObjectFile::parseSection(WasmSection &Sec) {
return parseDataCountSection(Ctx);
default:
return make_error<GenericBinaryError>(
- "invalid section type: " + Twine(Sec.Type), object_error::parse_failed);
+ "invalid section type: " + Twine(Sec.Type), object_error::parse_failed);
}
}
@@ -356,11 +356,11 @@ Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) {
}
Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
- llvm::DenseSet<uint64_t> SeenFunctions;
- llvm::DenseSet<uint64_t> SeenGlobals;
- llvm::DenseSet<uint64_t> SeenSegments;
+ llvm::DenseSet<uint64_t> SeenFunctions;
+ llvm::DenseSet<uint64_t> SeenGlobals;
+ llvm::DenseSet<uint64_t> SeenSegments;
if (FunctionTypes.size() && !SeenCodeSection) {
- return make_error<GenericBinaryError>("names must come after code section",
+ return make_error<GenericBinaryError>("names must come after code section",
object_error::parse_failed);
}
@@ -369,42 +369,42 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
uint32_t Size = readVaruint32(Ctx);
const uint8_t *SubSectionEnd = Ctx.Ptr + Size;
switch (Type) {
- case wasm::WASM_NAMES_FUNCTION:
- case wasm::WASM_NAMES_GLOBAL:
- case wasm::WASM_NAMES_DATA_SEGMENT: {
+ case wasm::WASM_NAMES_FUNCTION:
+ case wasm::WASM_NAMES_GLOBAL:
+ case wasm::WASM_NAMES_DATA_SEGMENT: {
uint32_t Count = readVaruint32(Ctx);
while (Count--) {
uint32_t Index = readVaruint32(Ctx);
StringRef Name = readString(Ctx);
- wasm::NameType nameType = wasm::NameType::FUNCTION;
- if (Type == wasm::WASM_NAMES_FUNCTION) {
- if (!SeenFunctions.insert(Index).second)
- return make_error<GenericBinaryError>(
- "function named more than once", object_error::parse_failed);
- if (!isValidFunctionIndex(Index) || Name.empty())
- return make_error<GenericBinaryError>("invalid name entry",
- object_error::parse_failed);
-
- if (isDefinedFunctionIndex(Index))
- getDefinedFunction(Index).DebugName = Name;
- } else if (Type == wasm::WASM_NAMES_GLOBAL) {
- nameType = wasm::NameType::GLOBAL;
- if (!SeenGlobals.insert(Index).second)
- return make_error<GenericBinaryError>("global named more than once",
- object_error::parse_failed);
- if (!isValidGlobalIndex(Index) || Name.empty())
- return make_error<GenericBinaryError>("invalid name entry",
- object_error::parse_failed);
- } else {
- nameType = wasm::NameType::DATA_SEGMENT;
- if (!SeenSegments.insert(Index).second)
- return make_error<GenericBinaryError>(
- "segment named more than once", object_error::parse_failed);
- if (Index > DataSegments.size())
- return make_error<GenericBinaryError>("invalid named data segment",
- object_error::parse_failed);
- }
- DebugNames.push_back(wasm::WasmDebugName{nameType, Index, Name});
+ wasm::NameType nameType = wasm::NameType::FUNCTION;
+ if (Type == wasm::WASM_NAMES_FUNCTION) {
+ if (!SeenFunctions.insert(Index).second)
+ return make_error<GenericBinaryError>(
+ "function named more than once", object_error::parse_failed);
+ if (!isValidFunctionIndex(Index) || Name.empty())
+ return make_error<GenericBinaryError>("invalid name entry",
+ object_error::parse_failed);
+
+ if (isDefinedFunctionIndex(Index))
+ getDefinedFunction(Index).DebugName = Name;
+ } else if (Type == wasm::WASM_NAMES_GLOBAL) {
+ nameType = wasm::NameType::GLOBAL;
+ if (!SeenGlobals.insert(Index).second)
+ return make_error<GenericBinaryError>("global named more than once",
+ object_error::parse_failed);
+ if (!isValidGlobalIndex(Index) || Name.empty())
+ return make_error<GenericBinaryError>("invalid name entry",
+ object_error::parse_failed);
+ } else {
+ nameType = wasm::NameType::DATA_SEGMENT;
+ if (!SeenSegments.insert(Index).second)
+ return make_error<GenericBinaryError>(
+ "segment named more than once", object_error::parse_failed);
+ if (Index > DataSegments.size())
+ return make_error<GenericBinaryError>("invalid named data segment",
+ object_error::parse_failed);
+ }
+ DebugNames.push_back(wasm::WasmDebugName{nameType, Index, Name});
}
break;
}
@@ -416,11 +416,11 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
}
if (Ctx.Ptr != SubSectionEnd)
return make_error<GenericBinaryError>(
- "name sub-section ended prematurely", object_error::parse_failed);
+ "name sub-section ended prematurely", object_error::parse_failed);
}
if (Ctx.Ptr != Ctx.End)
- return make_error<GenericBinaryError>("name section ended prematurely",
+ return make_error<GenericBinaryError>("name section ended prematurely",
object_error::parse_failed);
return Error::success();
}
@@ -429,14 +429,14 @@ Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) {
HasLinkingSection = true;
if (FunctionTypes.size() && !SeenCodeSection) {
return make_error<GenericBinaryError>(
- "linking data must come after code section",
+ "linking data must come after code section",
object_error::parse_failed);
}
LinkingData.Version = readVaruint32(Ctx);
if (LinkingData.Version != wasm::WasmMetadataVersion) {
return make_error<GenericBinaryError>(
- "unexpected metadata version: " + Twine(LinkingData.Version) +
+ "unexpected metadata version: " + Twine(LinkingData.Version) +
" (Expected: " + Twine(wasm::WasmMetadataVersion) + ")",
object_error::parse_failed);
}
@@ -457,7 +457,7 @@ Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) {
case wasm::WASM_SEGMENT_INFO: {
uint32_t Count = readVaruint32(Ctx);
if (Count > DataSegments.size())
- return make_error<GenericBinaryError>("too many segment names",
+ return make_error<GenericBinaryError>("too many segment names",
object_error::parse_failed);
for (uint32_t I = 0; I < Count; I++) {
DataSegments[I].Data.Name = readString(Ctx);
@@ -474,7 +474,7 @@ Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) {
Init.Priority = readVaruint32(Ctx);
Init.Symbol = readVaruint32(Ctx);
if (!isValidFunctionSymbol(Init.Symbol))
- return make_error<GenericBinaryError>("invalid function symbol: " +
+ return make_error<GenericBinaryError>("invalid function symbol: " +
Twine(Init.Symbol),
object_error::parse_failed);
LinkingData.InitFunctions.emplace_back(Init);
@@ -491,10 +491,10 @@ Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) {
}
if (Ctx.Ptr != Ctx.End)
return make_error<GenericBinaryError>(
- "linking sub-section ended prematurely", object_error::parse_failed);
+ "linking sub-section ended prematurely", object_error::parse_failed);
}
if (Ctx.Ptr != OrigEnd)
- return make_error<GenericBinaryError>("linking section ended prematurely",
+ return make_error<GenericBinaryError>("linking section ended prematurely",
object_error::parse_failed);
return Error::success();
}
@@ -508,11 +508,11 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
std::vector<wasm::WasmImport *> ImportedGlobals;
std::vector<wasm::WasmImport *> ImportedFunctions;
std::vector<wasm::WasmImport *> ImportedEvents;
- std::vector<wasm::WasmImport *> ImportedTables;
+ std::vector<wasm::WasmImport *> ImportedTables;
ImportedGlobals.reserve(Imports.size());
ImportedFunctions.reserve(Imports.size());
ImportedEvents.reserve(Imports.size());
- ImportedTables.reserve(Imports.size());
+ ImportedTables.reserve(Imports.size());
for (auto &I : Imports) {
if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION)
ImportedFunctions.emplace_back(&I);
@@ -520,15 +520,15 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
ImportedGlobals.emplace_back(&I);
else if (I.Kind == wasm::WASM_EXTERNAL_EVENT)
ImportedEvents.emplace_back(&I);
- else if (I.Kind == wasm::WASM_EXTERNAL_TABLE)
- ImportedTables.emplace_back(&I);
+ else if (I.Kind == wasm::WASM_EXTERNAL_TABLE)
+ ImportedTables.emplace_back(&I);
}
while (Count--) {
wasm::WasmSymbolInfo Info;
const wasm::WasmSignature *Signature = nullptr;
const wasm::WasmGlobalType *GlobalType = nullptr;
- const wasm::WasmTableType *TableType = nullptr;
+ const wasm::WasmTableType *TableType = nullptr;
const wasm::WasmEventType *EventType = nullptr;
Info.Kind = readUint8(Ctx);
@@ -596,38 +596,38 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
}
break;
- case wasm::WASM_SYMBOL_TYPE_TABLE:
- Info.ElementIndex = readVaruint32(Ctx);
- if (!isValidTableIndex(Info.ElementIndex) ||
- IsDefined != isDefinedTableIndex(Info.ElementIndex))
- return make_error<GenericBinaryError>("invalid table symbol index",
- object_error::parse_failed);
- if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
- wasm::WASM_SYMBOL_BINDING_WEAK)
- return make_error<GenericBinaryError>("undefined weak table symbol",
- object_error::parse_failed);
- if (IsDefined) {
- Info.Name = readString(Ctx);
- unsigned TableIndex = Info.ElementIndex - NumImportedTables;
- wasm::WasmTable &Table = Tables[TableIndex];
- TableType = &Table.Type;
- if (Table.SymbolName.empty())
- Table.SymbolName = Info.Name;
- } else {
- wasm::WasmImport &Import = *ImportedTables[Info.ElementIndex];
- if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
- Info.Name = readString(Ctx);
- Info.ImportName = Import.Field;
- } else {
- Info.Name = Import.Field;
- }
- TableType = &Import.Table;
- if (!Import.Module.empty()) {
- Info.ImportModule = Import.Module;
- }
- }
- break;
-
+ case wasm::WASM_SYMBOL_TYPE_TABLE:
+ Info.ElementIndex = readVaruint32(Ctx);
+ if (!isValidTableIndex(Info.ElementIndex) ||
+ IsDefined != isDefinedTableIndex(Info.ElementIndex))
+ return make_error<GenericBinaryError>("invalid table symbol index",
+ object_error::parse_failed);
+ if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
+ wasm::WASM_SYMBOL_BINDING_WEAK)
+ return make_error<GenericBinaryError>("undefined weak table symbol",
+ object_error::parse_failed);
+ if (IsDefined) {
+ Info.Name = readString(Ctx);
+ unsigned TableIndex = Info.ElementIndex - NumImportedTables;
+ wasm::WasmTable &Table = Tables[TableIndex];
+ TableType = &Table.Type;
+ if (Table.SymbolName.empty())
+ Table.SymbolName = Info.Name;
+ } else {
+ wasm::WasmImport &Import = *ImportedTables[Info.ElementIndex];
+ if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
+ Info.Name = readString(Ctx);
+ Info.ImportName = Import.Field;
+ } else {
+ Info.Name = Import.Field;
+ }
+ TableType = &Import.Table;
+ if (!Import.Module.empty()) {
+ Info.ImportModule = Import.Module;
+ }
+ }
+ break;
+
case wasm::WASM_SYMBOL_TYPE_DATA:
Info.Name = readString(Ctx);
if (IsDefined) {
@@ -648,7 +648,7 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
wasm::WASM_SYMBOL_BINDING_LOCAL)
return make_error<GenericBinaryError>(
- "section symbols must have local binding",
+ "section symbols must have local binding",
object_error::parse_failed);
Info.ElementIndex = readVaruint32(Ctx);
// Use somewhat unique section name as symbol name.
@@ -694,20 +694,20 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
}
default:
- return make_error<GenericBinaryError>("invalid symbol type: " +
- Twine(unsigned(Info.Kind)),
+ return make_error<GenericBinaryError>("invalid symbol type: " +
+ Twine(unsigned(Info.Kind)),
object_error::parse_failed);
}
if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
wasm::WASM_SYMBOL_BINDING_LOCAL &&
!SymbolNames.insert(Info.Name).second)
- return make_error<GenericBinaryError>("duplicate symbol name " +
+ return make_error<GenericBinaryError>("duplicate symbol name " +
Twine(Info.Name),
object_error::parse_failed);
LinkingData.SymbolTable.emplace_back(Info);
- Symbols.emplace_back(LinkingData.SymbolTable.back(), GlobalType, TableType,
- EventType, Signature);
+ Symbols.emplace_back(LinkingData.SymbolTable.back(), GlobalType, TableType,
+ EventType, Signature);
LLVM_DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n");
}
@@ -720,13 +720,13 @@ Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
for (unsigned ComdatIndex = 0; ComdatIndex < ComdatCount; ++ComdatIndex) {
StringRef Name = readString(Ctx);
if (Name.empty() || !ComdatSet.insert(Name).second)
- return make_error<GenericBinaryError>("bad/duplicate COMDAT name " +
+ return make_error<GenericBinaryError>("bad/duplicate COMDAT name " +
Twine(Name),
object_error::parse_failed);
LinkingData.Comdats.emplace_back(Name);
uint32_t Flags = readVaruint32(Ctx);
if (Flags != 0)
- return make_error<GenericBinaryError>("unsupported COMDAT flags",
+ return make_error<GenericBinaryError>("unsupported COMDAT flags",
object_error::parse_failed);
uint32_t EntryCount = readVaruint32(Ctx);
@@ -735,14 +735,14 @@ Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
unsigned Index = readVaruint32(Ctx);
switch (Kind) {
default:
- return make_error<GenericBinaryError>("invalid COMDAT entry type",
+ return make_error<GenericBinaryError>("invalid COMDAT entry type",
object_error::parse_failed);
case wasm::WASM_COMDAT_DATA:
if (Index >= DataSegments.size())
return make_error<GenericBinaryError>(
"COMDAT data index out of range", object_error::parse_failed);
if (DataSegments[Index].Data.Comdat != UINT32_MAX)
- return make_error<GenericBinaryError>("data segment in two COMDATs",
+ return make_error<GenericBinaryError>("data segment in two COMDATs",
object_error::parse_failed);
DataSegments[Index].Data.Comdat = ComdatIndex;
break;
@@ -751,19 +751,19 @@ Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
return make_error<GenericBinaryError>(
"COMDAT function index out of range", object_error::parse_failed);
if (getDefinedFunction(Index).Comdat != UINT32_MAX)
- return make_error<GenericBinaryError>("function in two COMDATs",
+ return make_error<GenericBinaryError>("function in two COMDATs",
object_error::parse_failed);
getDefinedFunction(Index).Comdat = ComdatIndex;
break;
- case wasm::WASM_COMDAT_SECTION:
- if (Index >= Sections.size())
- return make_error<GenericBinaryError>(
- "COMDAT section index out of range", object_error::parse_failed);
- if (Sections[Index].Type != wasm::WASM_SEC_CUSTOM)
- return make_error<GenericBinaryError>(
- "non-custom section in a COMDAT", object_error::parse_failed);
- Sections[Index].Comdat = ComdatIndex;
- break;
+ case wasm::WASM_COMDAT_SECTION:
+ if (Index >= Sections.size())
+ return make_error<GenericBinaryError>(
+ "COMDAT section index out of range", object_error::parse_failed);
+ if (Sections[Index].Type != wasm::WASM_SEC_CUSTOM)
+ return make_error<GenericBinaryError>(
+ "non-custom section in a COMDAT", object_error::parse_failed);
+ Sections[Index].Comdat = ComdatIndex;
+ break;
}
}
}
@@ -777,7 +777,7 @@ Error WasmObjectFile::parseProducersSection(ReadContext &Ctx) {
StringRef FieldName = readString(Ctx);
if (!FieldsSeen.insert(FieldName).second)
return make_error<GenericBinaryError>(
- "producers section does not have unique fields",
+ "producers section does not have unique fields",
object_error::parse_failed);
std::vector<std::pair<std::string, std::string>> *ProducerVec = nullptr;
if (FieldName == "language") {
@@ -788,7 +788,7 @@ Error WasmObjectFile::parseProducersSection(ReadContext &Ctx) {
ProducerVec = &ProducerInfo.SDKs;
} else {
return make_error<GenericBinaryError>(
- "producers section field is not named one of language, processed-by, "
+ "producers section field is not named one of language, processed-by, "
"or sdk",
object_error::parse_failed);
}
@@ -799,14 +799,14 @@ Error WasmObjectFile::parseProducersSection(ReadContext &Ctx) {
StringRef Version = readString(Ctx);
if (!ProducersSeen.insert(Name).second) {
return make_error<GenericBinaryError>(
- "producers section contains repeated producer",
+ "producers section contains repeated producer",
object_error::parse_failed);
}
ProducerVec->emplace_back(std::string(Name), std::string(Version));
}
}
if (Ctx.Ptr != Ctx.End)
- return make_error<GenericBinaryError>("producers section ended prematurely",
+ return make_error<GenericBinaryError>("producers section ended prematurely",
object_error::parse_failed);
return Error::success();
}
@@ -823,20 +823,20 @@ Error WasmObjectFile::parseTargetFeaturesSection(ReadContext &Ctx) {
case wasm::WASM_FEATURE_PREFIX_DISALLOWED:
break;
default:
- return make_error<GenericBinaryError>("unknown feature policy prefix",
+ return make_error<GenericBinaryError>("unknown feature policy prefix",
object_error::parse_failed);
}
Feature.Name = std::string(readString(Ctx));
if (!FeaturesSeen.insert(Feature.Name).second)
return make_error<GenericBinaryError>(
- "target features section contains repeated feature \"" +
+ "target features section contains repeated feature \"" +
Feature.Name + "\"",
object_error::parse_failed);
TargetFeatures.push_back(Feature);
}
if (Ctx.Ptr != Ctx.End)
return make_error<GenericBinaryError>(
- "target features section ended prematurely",
+ "target features section ended prematurely",
object_error::parse_failed);
return Error::success();
}
@@ -844,7 +844,7 @@ Error WasmObjectFile::parseTargetFeaturesSection(ReadContext &Ctx) {
Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
uint32_t SectionIndex = readVaruint32(Ctx);
if (SectionIndex >= Sections.size())
- return make_error<GenericBinaryError>("invalid section index",
+ return make_error<GenericBinaryError>("invalid section index",
object_error::parse_failed);
WasmSection &Section = Sections[SectionIndex];
uint32_t RelocCount = readVaruint32(Ctx);
@@ -852,33 +852,33 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
uint32_t PreviousOffset = 0;
while (RelocCount--) {
wasm::WasmRelocation Reloc = {};
- uint32_t type = readVaruint32(Ctx);
- Reloc.Type = type;
+ uint32_t type = readVaruint32(Ctx);
+ Reloc.Type = type;
Reloc.Offset = readVaruint32(Ctx);
if (Reloc.Offset < PreviousOffset)
- return make_error<GenericBinaryError>("relocations not in offset order",
+ return make_error<GenericBinaryError>("relocations not in offset order",
object_error::parse_failed);
PreviousOffset = Reloc.Offset;
Reloc.Index = readVaruint32(Ctx);
- switch (type) {
+ switch (type) {
case wasm::R_WASM_FUNCTION_INDEX_LEB:
case wasm::R_WASM_TABLE_INDEX_SLEB:
- case wasm::R_WASM_TABLE_INDEX_SLEB64:
+ case wasm::R_WASM_TABLE_INDEX_SLEB64:
case wasm::R_WASM_TABLE_INDEX_I32:
- case wasm::R_WASM_TABLE_INDEX_I64:
+ case wasm::R_WASM_TABLE_INDEX_I64:
case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
if (!isValidFunctionSymbol(Reloc.Index))
- return make_error<GenericBinaryError>(
- "invalid relocation function index", object_error::parse_failed);
- break;
- case wasm::R_WASM_TABLE_NUMBER_LEB:
- if (!isValidTableSymbol(Reloc.Index))
- return make_error<GenericBinaryError>("invalid relocation table index",
+ return make_error<GenericBinaryError>(
+ "invalid relocation function index", object_error::parse_failed);
+ break;
+ case wasm::R_WASM_TABLE_NUMBER_LEB:
+ if (!isValidTableSymbol(Reloc.Index))
+ return make_error<GenericBinaryError>("invalid relocation table index",
object_error::parse_failed);
break;
case wasm::R_WASM_TYPE_INDEX_LEB:
if (Reloc.Index >= Signatures.size())
- return make_error<GenericBinaryError>("invalid relocation type index",
+ return make_error<GenericBinaryError>("invalid relocation type index",
object_error::parse_failed);
break;
case wasm::R_WASM_GLOBAL_INDEX_LEB:
@@ -887,26 +887,26 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
if (!isValidGlobalSymbol(Reloc.Index) &&
!isValidDataSymbol(Reloc.Index) &&
!isValidFunctionSymbol(Reloc.Index))
- return make_error<GenericBinaryError>("invalid relocation global index",
+ return make_error<GenericBinaryError>("invalid relocation global index",
object_error::parse_failed);
break;
case wasm::R_WASM_GLOBAL_INDEX_I32:
if (!isValidGlobalSymbol(Reloc.Index))
- return make_error<GenericBinaryError>("invalid relocation global index",
+ return make_error<GenericBinaryError>("invalid relocation global index",
object_error::parse_failed);
break;
case wasm::R_WASM_EVENT_INDEX_LEB:
if (!isValidEventSymbol(Reloc.Index))
- return make_error<GenericBinaryError>("invalid relocation event index",
+ return make_error<GenericBinaryError>("invalid relocation event index",
object_error::parse_failed);
break;
case wasm::R_WASM_MEMORY_ADDR_LEB:
case wasm::R_WASM_MEMORY_ADDR_SLEB:
case wasm::R_WASM_MEMORY_ADDR_I32:
case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
- case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB:
+ case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB:
if (!isValidDataSymbol(Reloc.Index))
- return make_error<GenericBinaryError>("invalid relocation data index",
+ return make_error<GenericBinaryError>("invalid relocation data index",
object_error::parse_failed);
Reloc.Addend = readVarint32(Ctx);
break;
@@ -915,31 +915,31 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
case wasm::R_WASM_MEMORY_ADDR_I64:
case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64:
if (!isValidDataSymbol(Reloc.Index))
- return make_error<GenericBinaryError>("invalid relocation data index",
+ return make_error<GenericBinaryError>("invalid relocation data index",
object_error::parse_failed);
Reloc.Addend = readVarint64(Ctx);
break;
case wasm::R_WASM_FUNCTION_OFFSET_I32:
if (!isValidFunctionSymbol(Reloc.Index))
- return make_error<GenericBinaryError>(
- "invalid relocation function index", object_error::parse_failed);
+ return make_error<GenericBinaryError>(
+ "invalid relocation function index", object_error::parse_failed);
Reloc.Addend = readVarint32(Ctx);
break;
- case wasm::R_WASM_FUNCTION_OFFSET_I64:
- if (!isValidFunctionSymbol(Reloc.Index))
- return make_error<GenericBinaryError>(
- "invalid relocation function index", object_error::parse_failed);
- Reloc.Addend = readVarint64(Ctx);
- break;
+ case wasm::R_WASM_FUNCTION_OFFSET_I64:
+ if (!isValidFunctionSymbol(Reloc.Index))
+ return make_error<GenericBinaryError>(
+ "invalid relocation function index", object_error::parse_failed);
+ Reloc.Addend = readVarint64(Ctx);
+ break;
case wasm::R_WASM_SECTION_OFFSET_I32:
if (!isValidSectionSymbol(Reloc.Index))
- return make_error<GenericBinaryError>(
- "invalid relocation section index", object_error::parse_failed);
+ return make_error<GenericBinaryError>(
+ "invalid relocation section index", object_error::parse_failed);
Reloc.Addend = readVarint32(Ctx);
break;
default:
- return make_error<GenericBinaryError>("invalid relocation type: " +
- Twine(type),
+ return make_error<GenericBinaryError>("invalid relocation type: " +
+ Twine(type),
object_error::parse_failed);
}
@@ -957,18 +957,18 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I32 ||
Reloc.Type == wasm::R_WASM_GLOBAL_INDEX_I32)
Size = 4;
- if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I64 ||
- Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I64 ||
- Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I64)
+ if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I64 ||
+ Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I64 ||
+ Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I64)
Size = 8;
if (Reloc.Offset + Size > EndOffset)
- return make_error<GenericBinaryError>("invalid relocation offset",
+ return make_error<GenericBinaryError>("invalid relocation offset",
object_error::parse_failed);
Section.Relocations.push_back(Reloc);
}
if (Ctx.Ptr != Ctx.End)
- return make_error<GenericBinaryError>("reloc section ended prematurely",
+ return make_error<GenericBinaryError>("reloc section ended prematurely",
object_error::parse_failed);
return Error::success();
}
@@ -1003,7 +1003,7 @@ Error WasmObjectFile::parseTypeSection(ReadContext &Ctx) {
wasm::WasmSignature Sig;
uint8_t Form = readUint8(Ctx);
if (Form != wasm::WASM_TYPE_FUNC) {
- return make_error<GenericBinaryError>("invalid signature type",
+ return make_error<GenericBinaryError>("invalid signature type",
object_error::parse_failed);
}
uint32_t ParamCount = readVaruint32(Ctx);
@@ -1020,7 +1020,7 @@ Error WasmObjectFile::parseTypeSection(ReadContext &Ctx) {
Signatures.push_back(std::move(Sig));
}
if (Ctx.Ptr != Ctx.End)
- return make_error<GenericBinaryError>("type section ended prematurely",
+ return make_error<GenericBinaryError>("type section ended prematurely",
object_error::parse_failed);
return Error::success();
}
@@ -1045,32 +1045,32 @@ Error WasmObjectFile::parseImportSection(ReadContext &Ctx) {
break;
case wasm::WASM_EXTERNAL_MEMORY:
Im.Memory = readLimits(Ctx);
- if (Im.Memory.Flags & wasm::WASM_LIMITS_FLAG_IS_64)
- HasMemory64 = true;
+ if (Im.Memory.Flags & wasm::WASM_LIMITS_FLAG_IS_64)
+ HasMemory64 = true;
break;
- case wasm::WASM_EXTERNAL_TABLE: {
- Im.Table = readTableType(Ctx);
- NumImportedTables++;
- auto ElemType = Im.Table.ElemType;
- if (ElemType != wasm::WASM_TYPE_FUNCREF &&
- ElemType != wasm::WASM_TYPE_EXTERNREF)
- return make_error<GenericBinaryError>("invalid table element type",
+ case wasm::WASM_EXTERNAL_TABLE: {
+ Im.Table = readTableType(Ctx);
+ NumImportedTables++;
+ auto ElemType = Im.Table.ElemType;
+ if (ElemType != wasm::WASM_TYPE_FUNCREF &&
+ ElemType != wasm::WASM_TYPE_EXTERNREF)
+ return make_error<GenericBinaryError>("invalid table element type",
object_error::parse_failed);
break;
- }
+ }
case wasm::WASM_EXTERNAL_EVENT:
NumImportedEvents++;
Im.Event.Attribute = readVarint32(Ctx);
Im.Event.SigIndex = readVarint32(Ctx);
break;
default:
- return make_error<GenericBinaryError>("unexpected import kind",
+ return make_error<GenericBinaryError>("unexpected import kind",
object_error::parse_failed);
}
Imports.push_back(Im);
}
if (Ctx.Ptr != Ctx.End)
- return make_error<GenericBinaryError>("import section ended prematurely",
+ return make_error<GenericBinaryError>("import section ended prematurely",
object_error::parse_failed);
return Error::success();
}
@@ -1083,34 +1083,34 @@ Error WasmObjectFile::parseFunctionSection(ReadContext &Ctx) {
while (Count--) {
uint32_t Type = readVaruint32(Ctx);
if (Type >= NumTypes)
- return make_error<GenericBinaryError>("invalid function type",
+ return make_error<GenericBinaryError>("invalid function type",
object_error::parse_failed);
FunctionTypes.push_back(Type);
}
if (Ctx.Ptr != Ctx.End)
- return make_error<GenericBinaryError>("function section ended prematurely",
+ return make_error<GenericBinaryError>("function section ended prematurely",
object_error::parse_failed);
return Error::success();
}
Error WasmObjectFile::parseTableSection(ReadContext &Ctx) {
- TableSection = Sections.size();
+ TableSection = Sections.size();
uint32_t Count = readVaruint32(Ctx);
Tables.reserve(Count);
while (Count--) {
- wasm::WasmTable T;
- T.Type = readTableType(Ctx);
- T.Index = NumImportedTables + Tables.size();
- Tables.push_back(T);
- auto ElemType = Tables.back().Type.ElemType;
- if (ElemType != wasm::WASM_TYPE_FUNCREF &&
- ElemType != wasm::WASM_TYPE_EXTERNREF) {
- return make_error<GenericBinaryError>("invalid table element type",
+ wasm::WasmTable T;
+ T.Type = readTableType(Ctx);
+ T.Index = NumImportedTables + Tables.size();
+ Tables.push_back(T);
+ auto ElemType = Tables.back().Type.ElemType;
+ if (ElemType != wasm::WASM_TYPE_FUNCREF &&
+ ElemType != wasm::WASM_TYPE_EXTERNREF) {
+ return make_error<GenericBinaryError>("invalid table element type",
object_error::parse_failed);
}
}
if (Ctx.Ptr != Ctx.End)
- return make_error<GenericBinaryError>("table section ended prematurely",
+ return make_error<GenericBinaryError>("table section ended prematurely",
object_error::parse_failed);
return Error::success();
}
@@ -1119,13 +1119,13 @@ Error WasmObjectFile::parseMemorySection(ReadContext &Ctx) {
uint32_t Count = readVaruint32(Ctx);
Memories.reserve(Count);
while (Count--) {
- auto Limits = readLimits(Ctx);
- if (Limits.Flags & wasm::WASM_LIMITS_FLAG_IS_64)
- HasMemory64 = true;
- Memories.push_back(Limits);
+ auto Limits = readLimits(Ctx);
+ if (Limits.Flags & wasm::WASM_LIMITS_FLAG_IS_64)
+ HasMemory64 = true;
+ Memories.push_back(Limits);
}
if (Ctx.Ptr != Ctx.End)
- return make_error<GenericBinaryError>("memory section ended prematurely",
+ return make_error<GenericBinaryError>("memory section ended prematurely",
object_error::parse_failed);
return Error::success();
}
@@ -1143,7 +1143,7 @@ Error WasmObjectFile::parseEventSection(ReadContext &Ctx) {
}
if (Ctx.Ptr != Ctx.End)
- return make_error<GenericBinaryError>("event section ended prematurely",
+ return make_error<GenericBinaryError>("event section ended prematurely",
object_error::parse_failed);
return Error::success();
}
@@ -1162,7 +1162,7 @@ Error WasmObjectFile::parseGlobalSection(ReadContext &Ctx) {
Globals.push_back(Global);
}
if (Ctx.Ptr != Ctx.End)
- return make_error<GenericBinaryError>("global section ended prematurely",
+ return make_error<GenericBinaryError>("global section ended prematurely",
object_error::parse_failed);
return Error::success();
}
@@ -1179,31 +1179,31 @@ Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {
case wasm::WASM_EXTERNAL_FUNCTION:
if (!isDefinedFunctionIndex(Ex.Index))
- return make_error<GenericBinaryError>("invalid function export",
+ return make_error<GenericBinaryError>("invalid function export",
object_error::parse_failed);
getDefinedFunction(Ex.Index).ExportName = Ex.Name;
break;
case wasm::WASM_EXTERNAL_GLOBAL:
if (!isValidGlobalIndex(Ex.Index))
- return make_error<GenericBinaryError>("invalid global export",
+ return make_error<GenericBinaryError>("invalid global export",
object_error::parse_failed);
break;
case wasm::WASM_EXTERNAL_EVENT:
if (!isValidEventIndex(Ex.Index))
- return make_error<GenericBinaryError>("invalid event export",
+ return make_error<GenericBinaryError>("invalid event export",
object_error::parse_failed);
break;
case wasm::WASM_EXTERNAL_MEMORY:
case wasm::WASM_EXTERNAL_TABLE:
break;
default:
- return make_error<GenericBinaryError>("unexpected export kind",
+ return make_error<GenericBinaryError>("unexpected export kind",
object_error::parse_failed);
}
Exports.push_back(Ex);
}
if (Ctx.Ptr != Ctx.End)
- return make_error<GenericBinaryError>("export section ended prematurely",
+ return make_error<GenericBinaryError>("export section ended prematurely",
object_error::parse_failed);
return Error::success();
}
@@ -1220,18 +1220,18 @@ bool WasmObjectFile::isValidGlobalIndex(uint32_t Index) const {
return Index < NumImportedGlobals + Globals.size();
}
-bool WasmObjectFile::isValidTableIndex(uint32_t Index) const {
- return Index < NumImportedTables + Tables.size();
-}
-
+bool WasmObjectFile::isValidTableIndex(uint32_t Index) const {
+ return Index < NumImportedTables + Tables.size();
+}
+
bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const {
return Index >= NumImportedGlobals && isValidGlobalIndex(Index);
}
-bool WasmObjectFile::isDefinedTableIndex(uint32_t Index) const {
- return Index >= NumImportedTables && isValidTableIndex(Index);
-}
-
+bool WasmObjectFile::isDefinedTableIndex(uint32_t Index) const {
+ return Index >= NumImportedTables && isValidTableIndex(Index);
+}
+
bool WasmObjectFile::isValidEventIndex(uint32_t Index) const {
return Index < NumImportedEvents + Events.size();
}
@@ -1244,10 +1244,10 @@ bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const {
return Index < Symbols.size() && Symbols[Index].isTypeFunction();
}
-bool WasmObjectFile::isValidTableSymbol(uint32_t Index) const {
- return Index < Symbols.size() && Symbols[Index].isTypeTable();
-}
-
+bool WasmObjectFile::isValidTableSymbol(uint32_t Index) const {
+ return Index < Symbols.size() && Symbols[Index].isTypeTable();
+}
+
bool WasmObjectFile::isValidGlobalSymbol(uint32_t Index) const {
return Index < Symbols.size() && Symbols[Index].isTypeGlobal();
}
@@ -1288,7 +1288,7 @@ wasm::WasmEvent &WasmObjectFile::getDefinedEvent(uint32_t Index) {
Error WasmObjectFile::parseStartSection(ReadContext &Ctx) {
StartFunction = readVaruint32(Ctx);
if (!isValidFunctionIndex(StartFunction))
- return make_error<GenericBinaryError>("invalid start function",
+ return make_error<GenericBinaryError>("invalid start function",
object_error::parse_failed);
return Error::success();
}
@@ -1298,7 +1298,7 @@ Error WasmObjectFile::parseCodeSection(ReadContext &Ctx) {
CodeSection = Sections.size();
uint32_t FunctionCount = readVaruint32(Ctx);
if (FunctionCount != FunctionTypes.size()) {
- return make_error<GenericBinaryError>("invalid function count",
+ return make_error<GenericBinaryError>("invalid function count",
object_error::parse_failed);
}
@@ -1330,7 +1330,7 @@ Error WasmObjectFile::parseCodeSection(ReadContext &Ctx) {
assert(Ctx.Ptr == FunctionEnd);
}
if (Ctx.Ptr != Ctx.End)
- return make_error<GenericBinaryError>("code section ended prematurely",
+ return make_error<GenericBinaryError>("code section ended prematurely",
object_error::parse_failed);
return Error::success();
}
@@ -1342,7 +1342,7 @@ Error WasmObjectFile::parseElemSection(ReadContext &Ctx) {
wasm::WasmElemSegment Segment;
Segment.TableIndex = readVaruint32(Ctx);
if (Segment.TableIndex != 0) {
- return make_error<GenericBinaryError>("invalid TableIndex",
+ return make_error<GenericBinaryError>("invalid TableIndex",
object_error::parse_failed);
}
if (Error Err = readInitExpr(Segment.Offset, Ctx))
@@ -1354,7 +1354,7 @@ Error WasmObjectFile::parseElemSection(ReadContext &Ctx) {
ElemSegments.push_back(Segment);
}
if (Ctx.Ptr != Ctx.End)
- return make_error<GenericBinaryError>("elem section ended prematurely",
+ return make_error<GenericBinaryError>("elem section ended prematurely",
object_error::parse_failed);
return Error::success();
}
@@ -1364,16 +1364,16 @@ Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
uint32_t Count = readVaruint32(Ctx);
if (DataCount && Count != DataCount.getValue())
return make_error<GenericBinaryError>(
- "number of data segments does not match DataCount section");
+ "number of data segments does not match DataCount section");
DataSegments.reserve(Count);
while (Count--) {
WasmSegment Segment;
Segment.Data.InitFlags = readVaruint32(Ctx);
- Segment.Data.MemoryIndex =
- (Segment.Data.InitFlags & wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX)
- ? readVaruint32(Ctx)
- : 0;
- if ((Segment.Data.InitFlags & wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0) {
+ Segment.Data.MemoryIndex =
+ (Segment.Data.InitFlags & wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX)
+ ? readVaruint32(Ctx)
+ : 0;
+ if ((Segment.Data.InitFlags & wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0) {
if (Error Err = readInitExpr(Segment.Data.Offset, Ctx))
return Err;
} else {
@@ -1382,7 +1382,7 @@ Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
}
uint32_t Size = readVaruint32(Ctx);
if (Size > (size_t)(Ctx.End - Ctx.Ptr))
- return make_error<GenericBinaryError>("invalid segment size",
+ return make_error<GenericBinaryError>("invalid segment size",
object_error::parse_failed);
Segment.Data.Content = ArrayRef<uint8_t>(Ctx.Ptr, Size);
// The rest of these Data fields are set later, when reading in the linking
@@ -1395,7 +1395,7 @@ Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
DataSegments.push_back(Segment);
}
if (Ctx.Ptr != Ctx.End)
- return make_error<GenericBinaryError>("data section ended prematurely",
+ return make_error<GenericBinaryError>("data section ended prematurely",
object_error::parse_failed);
return Error::success();
}
@@ -1469,7 +1469,7 @@ uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol &Sym) const {
case wasm::WASM_SYMBOL_TYPE_FUNCTION:
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
case wasm::WASM_SYMBOL_TYPE_EVENT:
- case wasm::WASM_SYMBOL_TYPE_TABLE:
+ case wasm::WASM_SYMBOL_TYPE_TABLE:
return Sym.Info.ElementIndex;
case wasm::WASM_SYMBOL_TYPE_DATA: {
// The value of a data symbol is the segment offset, plus the symbol
@@ -1519,11 +1519,11 @@ WasmObjectFile::getSymbolType(DataRefImpl Symb) const {
return SymbolRef::ST_Debug;
case wasm::WASM_SYMBOL_TYPE_EVENT:
return SymbolRef::ST_Other;
- case wasm::WASM_SYMBOL_TYPE_TABLE:
- return SymbolRef::ST_Other;
+ case wasm::WASM_SYMBOL_TYPE_TABLE:
+ return SymbolRef::ST_Other;
}
- llvm_unreachable("unknown WasmSymbol::SymbolType");
+ llvm_unreachable("unknown WasmSymbol::SymbolType");
return SymbolRef::ST_Other;
}
@@ -1555,10 +1555,10 @@ uint32_t WasmObjectFile::getSymbolSectionIdImpl(const WasmSymbol &Sym) const {
return Sym.Info.ElementIndex;
case wasm::WASM_SYMBOL_TYPE_EVENT:
return EventSection;
- case wasm::WASM_SYMBOL_TYPE_TABLE:
- return TableSection;
+ case wasm::WASM_SYMBOL_TYPE_TABLE:
+ return TableSection;
default:
- llvm_unreachable("unknown WasmSymbol::SymbolType");
+ llvm_unreachable("unknown WasmSymbol::SymbolType");
}
}
@@ -1698,15 +1698,15 @@ section_iterator WasmObjectFile::section_end() const {
return section_iterator(SectionRef(Ref, this));
}
-uint8_t WasmObjectFile::getBytesInAddress() const {
- return HasMemory64 ? 8 : 4;
-}
+uint8_t WasmObjectFile::getBytesInAddress() const {
+ return HasMemory64 ? 8 : 4;
+}
StringRef WasmObjectFile::getFileFormatName() const { return "WASM"; }
-Triple::ArchType WasmObjectFile::getArch() const {
- return HasMemory64 ? Triple::wasm64 : Triple::wasm32;
-}
+Triple::ArchType WasmObjectFile::getArch() const {
+ return HasMemory64 ? Triple::wasm64 : Triple::wasm32;
+}
SubtargetFeatures WasmObjectFile::getFeatures() const {
return SubtargetFeatures();
diff --git a/contrib/libs/llvm12/lib/Object/XCOFFObjectFile.cpp b/contrib/libs/llvm12/lib/Object/XCOFFObjectFile.cpp
index 5e3a6809bd..a16a458168 100644
--- a/contrib/libs/llvm12/lib/Object/XCOFFObjectFile.cpp
+++ b/contrib/libs/llvm12/lib/Object/XCOFFObjectFile.cpp
@@ -12,14 +12,14 @@
#include "llvm/Object/XCOFFObjectFile.h"
#include "llvm/MC/SubtargetFeature.h"
-#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/DataExtractor.h"
#include <cstddef>
#include <cstring>
namespace llvm {
-
-using namespace XCOFF;
-
+
+using namespace XCOFF;
+
namespace object {
static const uint8_t FunctionSym = 0x20;
@@ -31,7 +31,7 @@ static const uint16_t NoRelMask = 0x0001;
template <typename T>
static Expected<const T *> getObject(MemoryBufferRef M, const void *Ptr,
const uint64_t Size = sizeof(T)) {
- uintptr_t Addr = reinterpret_cast<uintptr_t>(Ptr);
+ uintptr_t Addr = reinterpret_cast<uintptr_t>(Ptr);
if (Error E = Binary::checkOffset(M, Addr, Size))
return std::move(E);
return reinterpret_cast<const T *>(Addr);
@@ -283,7 +283,7 @@ XCOFFObjectFile::getSectionContents(DataRefImpl Sec) const {
const uint8_t * ContentStart = base() + OffsetToRaw;
uint64_t SectionSize = getSectionSize(Sec);
- if (checkOffset(Data, reinterpret_cast<uintptr_t>(ContentStart), SectionSize))
+ if (checkOffset(Data, reinterpret_cast<uintptr_t>(ContentStart), SectionSize))
return make_error<BinaryError>();
return makeArrayRef(ContentStart,SectionSize);
@@ -655,8 +655,8 @@ XCOFFObjectFile::relocations(const XCOFFSectionHeader32 &Sec) const {
uint32_t NumRelocEntries = NumRelocEntriesOrErr.get();
- static_assert(
- sizeof(XCOFFRelocation32) == XCOFF::RelocationSerializationSize32, "");
+ static_assert(
+ sizeof(XCOFFRelocation32) == XCOFF::RelocationSerializationSize32, "");
auto RelocationOrErr =
getObject<XCOFFRelocation32>(Data, reinterpret_cast<void *>(RelocAddr),
NumRelocEntries * sizeof(XCOFFRelocation32));
@@ -839,297 +839,297 @@ bool XCOFFSymbolRef::isFunction() const {
template struct XCOFFSectionHeader<XCOFFSectionHeader32>;
template struct XCOFFSectionHeader<XCOFFSectionHeader64>;
-bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes) {
- if (Bytes.size() < 4)
- return false;
-
- return support::endian::read32be(Bytes.data()) == 0;
-}
-
-TBVectorExt::TBVectorExt(StringRef TBvectorStrRef) {
- const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(TBvectorStrRef.data());
- Data = support::endian::read16be(Ptr);
- VecParmsInfo = support::endian::read32be(Ptr + 2);
-}
-
-#define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
-#define GETVALUEWITHMASKSHIFT(X, S) \
- ((Data & (TracebackTable::X)) >> (TracebackTable::S))
-uint8_t TBVectorExt::getNumberOfVRSaved() const {
- return GETVALUEWITHMASKSHIFT(NumberOfVRSavedMask, NumberOfVRSavedShift);
-}
-
-bool TBVectorExt::isVRSavedOnStack() const {
- return GETVALUEWITHMASK(IsVRSavedOnStackMask);
-}
-
-bool TBVectorExt::hasVarArgs() const {
- return GETVALUEWITHMASK(HasVarArgsMask);
-}
-uint8_t TBVectorExt::getNumberOfVectorParms() const {
- return GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask,
- NumberOfVectorParmsShift);
-}
-
-bool TBVectorExt::hasVMXInstruction() const {
- return GETVALUEWITHMASK(HasVMXInstructionMask);
-}
-#undef GETVALUEWITHMASK
-#undef GETVALUEWITHMASKSHIFT
-
-SmallString<32> TBVectorExt::getVectorParmsInfoString() const {
- SmallString<32> ParmsType;
- uint32_t Value = VecParmsInfo;
- for (uint8_t I = 0; I < getNumberOfVectorParms(); ++I) {
- if (I != 0)
- ParmsType += ", ";
- switch (Value & TracebackTable::ParmTypeMask) {
- case TracebackTable::ParmTypeIsVectorCharBit:
- ParmsType += "vc";
- break;
-
- case TracebackTable::ParmTypeIsVectorShortBit:
- ParmsType += "vs";
- break;
-
- case TracebackTable::ParmTypeIsVectorIntBit:
- ParmsType += "vi";
- break;
-
- case TracebackTable::ParmTypeIsVectorFloatBit:
- ParmsType += "vf";
- break;
- }
- Value <<= 2;
- }
- return ParmsType;
-}
-
-static SmallString<32> parseParmsTypeWithVecInfo(uint32_t Value,
- unsigned int ParmsNum) {
- SmallString<32> ParmsType;
- unsigned I = 0;
- bool Begin = false;
- while (I < ParmsNum || Value) {
- if (Begin)
- ParmsType += ", ";
- else
- Begin = true;
-
- switch (Value & TracebackTable::ParmTypeMask) {
- case TracebackTable::ParmTypeIsFixedBits:
- ParmsType += "i";
- ++I;
- break;
- case TracebackTable::ParmTypeIsVectorBits:
- ParmsType += "v";
- break;
- case TracebackTable::ParmTypeIsFloatingBits:
- ParmsType += "f";
- ++I;
- break;
- case TracebackTable::ParmTypeIsDoubleBits:
- ParmsType += "d";
- ++I;
- break;
- default:
- assert(false && "Unrecognized bits in ParmsType.");
- }
- Value <<= 2;
- }
- assert(I == ParmsNum &&
- "The total parameters number of fixed-point or floating-point "
- "parameters not equal to the number in the parameter type!");
- return ParmsType;
-}
-
-Expected<XCOFFTracebackTable> XCOFFTracebackTable::create(const uint8_t *Ptr,
- uint64_t &Size) {
- Error Err = Error::success();
- XCOFFTracebackTable TBT(Ptr, Size, Err);
- if (Err)
- return std::move(Err);
- return TBT;
-}
-
-XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
- Error &Err)
- : TBPtr(Ptr) {
- ErrorAsOutParameter EAO(&Err);
- DataExtractor DE(ArrayRef<uint8_t>(Ptr, Size), /*IsLittleEndian=*/false,
- /*AddressSize=*/0);
- DataExtractor::Cursor Cur(/*Offset=*/0);
-
- // Skip 8 bytes of mandatory fields.
- DE.getU64(Cur);
-
- // Begin to parse optional fields.
- if (Cur) {
- unsigned ParmNum = getNumberOfFixedParms() + getNumberOfFPParms();
-
- // As long as there are no "fixed-point" or floating-point parameters, this
- // field remains not present even when hasVectorInfo gives true and
- // indicates the presence of vector parameters.
- if (ParmNum > 0) {
- uint32_t ParamsTypeValue = DE.getU32(Cur);
- if (Cur)
- ParmsType = hasVectorInfo()
- ? parseParmsTypeWithVecInfo(ParamsTypeValue, ParmNum)
- : parseParmsType(ParamsTypeValue, ParmNum);
- }
- }
-
- if (Cur && hasTraceBackTableOffset())
- TraceBackTableOffset = DE.getU32(Cur);
-
- if (Cur && isInterruptHandler())
- HandlerMask = DE.getU32(Cur);
-
- if (Cur && hasControlledStorage()) {
- NumOfCtlAnchors = DE.getU32(Cur);
- if (Cur && NumOfCtlAnchors) {
- SmallVector<uint32_t, 8> Disp;
- Disp.reserve(NumOfCtlAnchors.getValue());
- for (uint32_t I = 0; I < NumOfCtlAnchors && Cur; ++I)
- Disp.push_back(DE.getU32(Cur));
- if (Cur)
- ControlledStorageInfoDisp = std::move(Disp);
- }
- }
-
- if (Cur && isFuncNamePresent()) {
- uint16_t FunctionNameLen = DE.getU16(Cur);
- if (Cur)
- FunctionName = DE.getBytes(Cur, FunctionNameLen);
- }
-
- if (Cur && isAllocaUsed())
- AllocaRegister = DE.getU8(Cur);
-
- if (Cur && hasVectorInfo()) {
- StringRef VectorExtRef = DE.getBytes(Cur, 6);
- if (Cur)
- VecExt = TBVectorExt(VectorExtRef);
- }
-
- if (Cur && hasExtensionTable())
- ExtensionTable = DE.getU8(Cur);
-
- if (!Cur)
- Err = Cur.takeError();
- Size = Cur.tell();
-}
-
-#define GETBITWITHMASK(P, X) \
- (support::endian::read32be(TBPtr + (P)) & (TracebackTable::X))
-#define GETBITWITHMASKSHIFT(P, X, S) \
- ((support::endian::read32be(TBPtr + (P)) & (TracebackTable::X)) >> \
- (TracebackTable::S))
-
-uint8_t XCOFFTracebackTable::getVersion() const {
- return GETBITWITHMASKSHIFT(0, VersionMask, VersionShift);
-}
-
-uint8_t XCOFFTracebackTable::getLanguageID() const {
- return GETBITWITHMASKSHIFT(0, LanguageIdMask, LanguageIdShift);
-}
-
-bool XCOFFTracebackTable::isGlobalLinkage() const {
- return GETBITWITHMASK(0, IsGlobaLinkageMask);
-}
-
-bool XCOFFTracebackTable::isOutOfLineEpilogOrPrologue() const {
- return GETBITWITHMASK(0, IsOutOfLineEpilogOrPrologueMask);
-}
-
-bool XCOFFTracebackTable::hasTraceBackTableOffset() const {
- return GETBITWITHMASK(0, HasTraceBackTableOffsetMask);
-}
-
-bool XCOFFTracebackTable::isInternalProcedure() const {
- return GETBITWITHMASK(0, IsInternalProcedureMask);
-}
-
-bool XCOFFTracebackTable::hasControlledStorage() const {
- return GETBITWITHMASK(0, HasControlledStorageMask);
-}
-
-bool XCOFFTracebackTable::isTOCless() const {
- return GETBITWITHMASK(0, IsTOClessMask);
-}
-
-bool XCOFFTracebackTable::isFloatingPointPresent() const {
- return GETBITWITHMASK(0, IsFloatingPointPresentMask);
-}
-
-bool XCOFFTracebackTable::isFloatingPointOperationLogOrAbortEnabled() const {
- return GETBITWITHMASK(0, IsFloatingPointOperationLogOrAbortEnabledMask);
-}
-
-bool XCOFFTracebackTable::isInterruptHandler() const {
- return GETBITWITHMASK(0, IsInterruptHandlerMask);
-}
-
-bool XCOFFTracebackTable::isFuncNamePresent() const {
- return GETBITWITHMASK(0, IsFunctionNamePresentMask);
-}
-
-bool XCOFFTracebackTable::isAllocaUsed() const {
- return GETBITWITHMASK(0, IsAllocaUsedMask);
-}
-
-uint8_t XCOFFTracebackTable::getOnConditionDirective() const {
- return GETBITWITHMASKSHIFT(0, OnConditionDirectiveMask,
- OnConditionDirectiveShift);
-}
-
-bool XCOFFTracebackTable::isCRSaved() const {
- return GETBITWITHMASK(0, IsCRSavedMask);
-}
-
-bool XCOFFTracebackTable::isLRSaved() const {
- return GETBITWITHMASK(0, IsLRSavedMask);
-}
-
-bool XCOFFTracebackTable::isBackChainStored() const {
- return GETBITWITHMASK(4, IsBackChainStoredMask);
-}
-
-bool XCOFFTracebackTable::isFixup() const {
- return GETBITWITHMASK(4, IsFixupMask);
-}
-
-uint8_t XCOFFTracebackTable::getNumOfFPRsSaved() const {
- return GETBITWITHMASKSHIFT(4, FPRSavedMask, FPRSavedShift);
-}
-
-bool XCOFFTracebackTable::hasExtensionTable() const {
- return GETBITWITHMASK(4, HasExtensionTableMask);
-}
-
-bool XCOFFTracebackTable::hasVectorInfo() const {
- return GETBITWITHMASK(4, HasVectorInfoMask);
-}
-
-uint8_t XCOFFTracebackTable::getNumOfGPRsSaved() const {
- return GETBITWITHMASKSHIFT(4, GPRSavedMask, GPRSavedShift);
-}
-
-uint8_t XCOFFTracebackTable::getNumberOfFixedParms() const {
- return GETBITWITHMASKSHIFT(4, NumberOfFixedParmsMask,
- NumberOfFixedParmsShift);
-}
-
-uint8_t XCOFFTracebackTable::getNumberOfFPParms() const {
- return GETBITWITHMASKSHIFT(4, NumberOfFloatingPointParmsMask,
- NumberOfFloatingPointParmsShift);
-}
-
-bool XCOFFTracebackTable::hasParmsOnStack() const {
- return GETBITWITHMASK(4, HasParmsOnStackMask);
-}
-
-#undef GETBITWITHMASK
-#undef GETBITWITHMASKSHIFT
+bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes) {
+ if (Bytes.size() < 4)
+ return false;
+
+ return support::endian::read32be(Bytes.data()) == 0;
+}
+
+TBVectorExt::TBVectorExt(StringRef TBvectorStrRef) {
+ const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(TBvectorStrRef.data());
+ Data = support::endian::read16be(Ptr);
+ VecParmsInfo = support::endian::read32be(Ptr + 2);
+}
+
+#define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
+#define GETVALUEWITHMASKSHIFT(X, S) \
+ ((Data & (TracebackTable::X)) >> (TracebackTable::S))
+uint8_t TBVectorExt::getNumberOfVRSaved() const {
+ return GETVALUEWITHMASKSHIFT(NumberOfVRSavedMask, NumberOfVRSavedShift);
+}
+
+bool TBVectorExt::isVRSavedOnStack() const {
+ return GETVALUEWITHMASK(IsVRSavedOnStackMask);
+}
+
+bool TBVectorExt::hasVarArgs() const {
+ return GETVALUEWITHMASK(HasVarArgsMask);
+}
+uint8_t TBVectorExt::getNumberOfVectorParms() const {
+ return GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask,
+ NumberOfVectorParmsShift);
+}
+
+bool TBVectorExt::hasVMXInstruction() const {
+ return GETVALUEWITHMASK(HasVMXInstructionMask);
+}
+#undef GETVALUEWITHMASK
+#undef GETVALUEWITHMASKSHIFT
+
+SmallString<32> TBVectorExt::getVectorParmsInfoString() const {
+ SmallString<32> ParmsType;
+ uint32_t Value = VecParmsInfo;
+ for (uint8_t I = 0; I < getNumberOfVectorParms(); ++I) {
+ if (I != 0)
+ ParmsType += ", ";
+ switch (Value & TracebackTable::ParmTypeMask) {
+ case TracebackTable::ParmTypeIsVectorCharBit:
+ ParmsType += "vc";
+ break;
+
+ case TracebackTable::ParmTypeIsVectorShortBit:
+ ParmsType += "vs";
+ break;
+
+ case TracebackTable::ParmTypeIsVectorIntBit:
+ ParmsType += "vi";
+ break;
+
+ case TracebackTable::ParmTypeIsVectorFloatBit:
+ ParmsType += "vf";
+ break;
+ }
+ Value <<= 2;
+ }
+ return ParmsType;
+}
+
+static SmallString<32> parseParmsTypeWithVecInfo(uint32_t Value,
+ unsigned int ParmsNum) {
+ SmallString<32> ParmsType;
+ unsigned I = 0;
+ bool Begin = false;
+ while (I < ParmsNum || Value) {
+ if (Begin)
+ ParmsType += ", ";
+ else
+ Begin = true;
+
+ switch (Value & TracebackTable::ParmTypeMask) {
+ case TracebackTable::ParmTypeIsFixedBits:
+ ParmsType += "i";
+ ++I;
+ break;
+ case TracebackTable::ParmTypeIsVectorBits:
+ ParmsType += "v";
+ break;
+ case TracebackTable::ParmTypeIsFloatingBits:
+ ParmsType += "f";
+ ++I;
+ break;
+ case TracebackTable::ParmTypeIsDoubleBits:
+ ParmsType += "d";
+ ++I;
+ break;
+ default:
+ assert(false && "Unrecognized bits in ParmsType.");
+ }
+ Value <<= 2;
+ }
+ assert(I == ParmsNum &&
+ "The total parameters number of fixed-point or floating-point "
+ "parameters not equal to the number in the parameter type!");
+ return ParmsType;
+}
+
+Expected<XCOFFTracebackTable> XCOFFTracebackTable::create(const uint8_t *Ptr,
+ uint64_t &Size) {
+ Error Err = Error::success();
+ XCOFFTracebackTable TBT(Ptr, Size, Err);
+ if (Err)
+ return std::move(Err);
+ return TBT;
+}
+
+XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
+ Error &Err)
+ : TBPtr(Ptr) {
+ ErrorAsOutParameter EAO(&Err);
+ DataExtractor DE(ArrayRef<uint8_t>(Ptr, Size), /*IsLittleEndian=*/false,
+ /*AddressSize=*/0);
+ DataExtractor::Cursor Cur(/*Offset=*/0);
+
+ // Skip 8 bytes of mandatory fields.
+ DE.getU64(Cur);
+
+ // Begin to parse optional fields.
+ if (Cur) {
+ unsigned ParmNum = getNumberOfFixedParms() + getNumberOfFPParms();
+
+ // As long as there are no "fixed-point" or floating-point parameters, this
+ // field remains not present even when hasVectorInfo gives true and
+ // indicates the presence of vector parameters.
+ if (ParmNum > 0) {
+ uint32_t ParamsTypeValue = DE.getU32(Cur);
+ if (Cur)
+ ParmsType = hasVectorInfo()
+ ? parseParmsTypeWithVecInfo(ParamsTypeValue, ParmNum)
+ : parseParmsType(ParamsTypeValue, ParmNum);
+ }
+ }
+
+ if (Cur && hasTraceBackTableOffset())
+ TraceBackTableOffset = DE.getU32(Cur);
+
+ if (Cur && isInterruptHandler())
+ HandlerMask = DE.getU32(Cur);
+
+ if (Cur && hasControlledStorage()) {
+ NumOfCtlAnchors = DE.getU32(Cur);
+ if (Cur && NumOfCtlAnchors) {
+ SmallVector<uint32_t, 8> Disp;
+ Disp.reserve(NumOfCtlAnchors.getValue());
+ for (uint32_t I = 0; I < NumOfCtlAnchors && Cur; ++I)
+ Disp.push_back(DE.getU32(Cur));
+ if (Cur)
+ ControlledStorageInfoDisp = std::move(Disp);
+ }
+ }
+
+ if (Cur && isFuncNamePresent()) {
+ uint16_t FunctionNameLen = DE.getU16(Cur);
+ if (Cur)
+ FunctionName = DE.getBytes(Cur, FunctionNameLen);
+ }
+
+ if (Cur && isAllocaUsed())
+ AllocaRegister = DE.getU8(Cur);
+
+ if (Cur && hasVectorInfo()) {
+ StringRef VectorExtRef = DE.getBytes(Cur, 6);
+ if (Cur)
+ VecExt = TBVectorExt(VectorExtRef);
+ }
+
+ if (Cur && hasExtensionTable())
+ ExtensionTable = DE.getU8(Cur);
+
+ if (!Cur)
+ Err = Cur.takeError();
+ Size = Cur.tell();
+}
+
+#define GETBITWITHMASK(P, X) \
+ (support::endian::read32be(TBPtr + (P)) & (TracebackTable::X))
+#define GETBITWITHMASKSHIFT(P, X, S) \
+ ((support::endian::read32be(TBPtr + (P)) & (TracebackTable::X)) >> \
+ (TracebackTable::S))
+
+uint8_t XCOFFTracebackTable::getVersion() const {
+ return GETBITWITHMASKSHIFT(0, VersionMask, VersionShift);
+}
+
+uint8_t XCOFFTracebackTable::getLanguageID() const {
+ return GETBITWITHMASKSHIFT(0, LanguageIdMask, LanguageIdShift);
+}
+
+bool XCOFFTracebackTable::isGlobalLinkage() const {
+ return GETBITWITHMASK(0, IsGlobaLinkageMask);
+}
+
+bool XCOFFTracebackTable::isOutOfLineEpilogOrPrologue() const {
+ return GETBITWITHMASK(0, IsOutOfLineEpilogOrPrologueMask);
+}
+
+bool XCOFFTracebackTable::hasTraceBackTableOffset() const {
+ return GETBITWITHMASK(0, HasTraceBackTableOffsetMask);
+}
+
+bool XCOFFTracebackTable::isInternalProcedure() const {
+ return GETBITWITHMASK(0, IsInternalProcedureMask);
+}
+
+bool XCOFFTracebackTable::hasControlledStorage() const {
+ return GETBITWITHMASK(0, HasControlledStorageMask);
+}
+
+bool XCOFFTracebackTable::isTOCless() const {
+ return GETBITWITHMASK(0, IsTOClessMask);
+}
+
+bool XCOFFTracebackTable::isFloatingPointPresent() const {
+ return GETBITWITHMASK(0, IsFloatingPointPresentMask);
+}
+
+bool XCOFFTracebackTable::isFloatingPointOperationLogOrAbortEnabled() const {
+ return GETBITWITHMASK(0, IsFloatingPointOperationLogOrAbortEnabledMask);
+}
+
+bool XCOFFTracebackTable::isInterruptHandler() const {
+ return GETBITWITHMASK(0, IsInterruptHandlerMask);
+}
+
+bool XCOFFTracebackTable::isFuncNamePresent() const {
+ return GETBITWITHMASK(0, IsFunctionNamePresentMask);
+}
+
+bool XCOFFTracebackTable::isAllocaUsed() const {
+ return GETBITWITHMASK(0, IsAllocaUsedMask);
+}
+
+uint8_t XCOFFTracebackTable::getOnConditionDirective() const {
+ return GETBITWITHMASKSHIFT(0, OnConditionDirectiveMask,
+ OnConditionDirectiveShift);
+}
+
+bool XCOFFTracebackTable::isCRSaved() const {
+ return GETBITWITHMASK(0, IsCRSavedMask);
+}
+
+bool XCOFFTracebackTable::isLRSaved() const {
+ return GETBITWITHMASK(0, IsLRSavedMask);
+}
+
+bool XCOFFTracebackTable::isBackChainStored() const {
+ return GETBITWITHMASK(4, IsBackChainStoredMask);
+}
+
+bool XCOFFTracebackTable::isFixup() const {
+ return GETBITWITHMASK(4, IsFixupMask);
+}
+
+uint8_t XCOFFTracebackTable::getNumOfFPRsSaved() const {
+ return GETBITWITHMASKSHIFT(4, FPRSavedMask, FPRSavedShift);
+}
+
+bool XCOFFTracebackTable::hasExtensionTable() const {
+ return GETBITWITHMASK(4, HasExtensionTableMask);
+}
+
+bool XCOFFTracebackTable::hasVectorInfo() const {
+ return GETBITWITHMASK(4, HasVectorInfoMask);
+}
+
+uint8_t XCOFFTracebackTable::getNumOfGPRsSaved() const {
+ return GETBITWITHMASKSHIFT(4, GPRSavedMask, GPRSavedShift);
+}
+
+uint8_t XCOFFTracebackTable::getNumberOfFixedParms() const {
+ return GETBITWITHMASKSHIFT(4, NumberOfFixedParmsMask,
+ NumberOfFixedParmsShift);
+}
+
+uint8_t XCOFFTracebackTable::getNumberOfFPParms() const {
+ return GETBITWITHMASKSHIFT(4, NumberOfFloatingPointParmsMask,
+ NumberOfFloatingPointParmsShift);
+}
+
+bool XCOFFTracebackTable::hasParmsOnStack() const {
+ return GETBITWITHMASK(4, HasParmsOnStackMask);
+}
+
+#undef GETBITWITHMASK
+#undef GETBITWITHMASKSHIFT
} // namespace object
} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/Object/ya.make b/contrib/libs/llvm12/lib/Object/ya.make
index 3d9da8deaa..3d746aaa36 100644
--- a/contrib/libs/llvm12/lib/Object/ya.make
+++ b/contrib/libs/llvm12/lib/Object/ya.make
@@ -12,15 +12,15 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/Bitcode/Reader
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/MC/MCParser
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/TextAPI/MachO
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/Bitcode/Reader
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/MC/MCParser
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/TextAPI/MachO
)
ADDINCL(
@@ -46,7 +46,7 @@ SRCS(
IRSymtab.cpp
MachOObjectFile.cpp
MachOUniversal.cpp
- MachOUniversalWriter.cpp
+ MachOUniversalWriter.cpp
Minidump.cpp
ModuleSymbolTable.cpp
Object.cpp
diff --git a/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMapping.cpp b/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMapping.cpp
index 3307b782e2..cdbcde50d3 100644
--- a/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -249,12 +249,12 @@ Error CoverageMapping::loadFunctionRecord(
consumeError(std::move(E));
return Error::success();
}
- Expected<int64_t> AltExecutionCount = Ctx.evaluate(Region.FalseCount);
- if (auto E = AltExecutionCount.takeError()) {
- consumeError(std::move(E));
- return Error::success();
- }
- Function.pushRegion(Region, *ExecutionCount, *AltExecutionCount);
+ Expected<int64_t> AltExecutionCount = Ctx.evaluate(Region.FalseCount);
+ if (auto E = AltExecutionCount.takeError()) {
+ consumeError(std::move(E));
+ return Error::success();
+ }
+ Function.pushRegion(Region, *ExecutionCount, *AltExecutionCount);
}
// Don't create records for (filenames, function) pairs we've already seen.
@@ -490,15 +490,15 @@ class SegmentBuilder {
if (CurStartLoc == CR.value().endLoc()) {
// Avoid making zero-length regions active. If it's the last region,
// emit a skipped segment. Otherwise use its predecessor's count.
- const bool Skipped =
- (CR.index() + 1) == Regions.size() ||
- CR.value().Kind == CounterMappingRegion::SkippedRegion;
+ const bool Skipped =
+ (CR.index() + 1) == Regions.size() ||
+ CR.value().Kind == CounterMappingRegion::SkippedRegion;
startSegment(ActiveRegions.empty() ? CR.value() : *ActiveRegions.back(),
CurStartLoc, !GapRegion, Skipped);
- // If it is skipped segment, create a segment with last pushed
- // regions's count at CurStartLoc.
- if (Skipped && !ActiveRegions.empty())
- startSegment(*ActiveRegions.back(), CurStartLoc, false);
+ // If it is skipped segment, create a segment with last pushed
+ // regions's count at CurStartLoc.
+ if (Skipped && !ActiveRegions.empty())
+ startSegment(*ActiveRegions.back(), CurStartLoc, false);
continue;
}
if (CR.index() + 1 == Regions.size() ||
@@ -598,8 +598,8 @@ public:
const auto &L = Segments[I - 1];
const auto &R = Segments[I];
if (!(L.Line < R.Line) && !(L.Line == R.Line && L.Col < R.Col)) {
- if (L.Line == R.Line && L.Col == R.Col && !L.HasCount)
- continue;
+ if (L.Line == R.Line && L.Col == R.Col && !L.HasCount)
+ continue;
LLVM_DEBUG(dbgs() << " ! Segment " << L.Line << ":" << L.Col
<< " followed by " << R.Line << ":" << R.Col << "\n");
assert(false && "Coverage segments not unique or sorted");
@@ -616,7 +616,7 @@ public:
std::vector<StringRef> CoverageMapping::getUniqueSourceFiles() const {
std::vector<StringRef> Filenames;
for (const auto &Function : getCoveredFunctions())
- llvm::append_range(Filenames, Function.Filenames);
+ llvm::append_range(Filenames, Function.Filenames);
llvm::sort(Filenames);
auto Last = std::unique(Filenames.begin(), Filenames.end());
Filenames.erase(Last, Filenames.end());
@@ -676,10 +676,10 @@ CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const {
if (MainFileID && isExpansion(CR, *MainFileID))
FileCoverage.Expansions.emplace_back(CR, Function);
}
- // Capture branch regions specific to the function (excluding expansions).
- for (const auto &CR : Function.CountedBranchRegions)
- if (FileIDs.test(CR.FileID) && (CR.FileID == CR.ExpandedFileID))
- FileCoverage.BranchRegions.push_back(CR);
+ // Capture branch regions specific to the function (excluding expansions).
+ for (const auto &CR : Function.CountedBranchRegions)
+ if (FileIDs.test(CR.FileID) && (CR.FileID == CR.ExpandedFileID))
+ FileCoverage.BranchRegions.push_back(CR);
}
LLVM_DEBUG(dbgs() << "Emitting segments for file: " << Filename << "\n");
@@ -727,10 +727,10 @@ CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const {
if (isExpansion(CR, *MainFileID))
FunctionCoverage.Expansions.emplace_back(CR, Function);
}
- // Capture branch regions specific to the function (excluding expansions).
- for (const auto &CR : Function.CountedBranchRegions)
- if (CR.FileID == *MainFileID)
- FunctionCoverage.BranchRegions.push_back(CR);
+ // Capture branch regions specific to the function (excluding expansions).
+ for (const auto &CR : Function.CountedBranchRegions)
+ if (CR.FileID == *MainFileID)
+ FunctionCoverage.BranchRegions.push_back(CR);
LLVM_DEBUG(dbgs() << "Emitting segments for function: " << Function.Name
<< "\n");
@@ -750,10 +750,10 @@ CoverageData CoverageMapping::getCoverageForExpansion(
if (isExpansion(CR, Expansion.FileID))
ExpansionCoverage.Expansions.emplace_back(CR, Expansion.Function);
}
- for (const auto &CR : Expansion.Function.CountedBranchRegions)
- // Capture branch regions that only pertain to the corresponding expansion.
- if (CR.FileID == Expansion.FileID)
- ExpansionCoverage.BranchRegions.push_back(CR);
+ for (const auto &CR : Expansion.Function.CountedBranchRegions)
+ // Capture branch regions that only pertain to the corresponding expansion.
+ if (CR.FileID == Expansion.FileID)
+ ExpansionCoverage.BranchRegions.push_back(CR);
LLVM_DEBUG(dbgs() << "Emitting segments for expansion of file "
<< Expansion.FileID << "\n");
@@ -831,8 +831,8 @@ static std::string getCoverageMapErrString(coveragemap_error Err) {
return "Malformed coverage data";
case coveragemap_error::decompression_failed:
return "Failed to decompress coverage data (zlib)";
- case coveragemap_error::invalid_or_missing_arch_specifier:
- return "`-arch` specifier is invalid or missing for universal binary";
+ case coveragemap_error::invalid_or_missing_arch_specifier:
+ return "`-arch` specifier is invalid or missing for universal binary";
}
llvm_unreachable("A value of coveragemap_error has no message.");
}
diff --git a/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMappingReader.cpp
index 54b63a2af0..1acdcb4beb 100644
--- a/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMappingReader.cpp
+++ b/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMappingReader.cpp
@@ -213,7 +213,7 @@ Error RawCoverageMappingReader::readMappingRegionsSubArray(
return Err;
unsigned LineStart = 0;
for (size_t I = 0; I < NumRegions; ++I) {
- Counter C, C2;
+ Counter C, C2;
CounterMappingRegion::RegionKind Kind = CounterMappingRegion::CodeRegion;
// Read the combined counter + region kind.
@@ -223,18 +223,18 @@ Error RawCoverageMappingReader::readMappingRegionsSubArray(
return Err;
unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
uint64_t ExpandedFileID = 0;
-
- // If Tag does not represent a ZeroCounter, then it is understood to refer
- // to a counter or counter expression with region kind assumed to be
- // "CodeRegion". In that case, EncodedCounterAndRegion actually encodes the
- // referenced counter or counter expression (and nothing else).
- //
- // If Tag represents a ZeroCounter and EncodingExpansionRegionBit is set,
- // then EncodedCounterAndRegion is interpreted to represent an
- // ExpansionRegion. In all other cases, EncodedCounterAndRegion is
- // interpreted to refer to a specific region kind, after which additional
- // fields may be read (e.g. BranchRegions have two encoded counters that
- // follow an encoded region kind value).
+
+ // If Tag does not represent a ZeroCounter, then it is understood to refer
+ // to a counter or counter expression with region kind assumed to be
+ // "CodeRegion". In that case, EncodedCounterAndRegion actually encodes the
+ // referenced counter or counter expression (and nothing else).
+ //
+ // If Tag represents a ZeroCounter and EncodingExpansionRegionBit is set,
+ // then EncodedCounterAndRegion is interpreted to represent an
+ // ExpansionRegion. In all other cases, EncodedCounterAndRegion is
+ // interpreted to refer to a specific region kind, after which additional
+ // fields may be read (e.g. BranchRegions have two encoded counters that
+ // follow an encoded region kind value).
if (Tag != Counter::Zero) {
if (auto Err = decodeCounter(EncodedCounterAndRegion, C))
return Err;
@@ -255,14 +255,14 @@ Error RawCoverageMappingReader::readMappingRegionsSubArray(
case CounterMappingRegion::SkippedRegion:
Kind = CounterMappingRegion::SkippedRegion;
break;
- case CounterMappingRegion::BranchRegion:
- // For a Branch Region, read two successive counters.
- Kind = CounterMappingRegion::BranchRegion;
- if (auto Err = readCounter(C))
- return Err;
- if (auto Err = readCounter(C2))
- return Err;
- break;
+ case CounterMappingRegion::BranchRegion:
+ // For a Branch Region, read two successive counters.
+ Kind = CounterMappingRegion::BranchRegion;
+ if (auto Err = readCounter(C))
+ return Err;
+ if (auto Err = readCounter(C2))
+ return Err;
+ break;
default:
return make_error<CoverageMapError>(coveragemap_error::malformed);
}
@@ -314,7 +314,7 @@ Error RawCoverageMappingReader::readMappingRegionsSubArray(
dbgs() << "\n";
});
- auto CMR = CounterMappingRegion(C, C2, InferredFileID, ExpandedFileID,
+ auto CMR = CounterMappingRegion(C, C2, InferredFileID, ExpandedFileID,
LineStart, ColumnStart,
LineStart + NumLines, ColumnEnd, Kind);
if (CMR.startLoc() > CMR.endLoc())
@@ -620,7 +620,7 @@ public:
CovBuf += FilenamesSize;
FilenameRange FileRange(FilenamesBegin, Filenames.size() - FilenamesBegin);
- if (Version >= CovMapVersion::Version4) {
+ if (Version >= CovMapVersion::Version4) {
// Map a hash of the filenames region to the filename range associated
// with this coverage header.
int64_t FilenamesRef =
@@ -648,7 +648,7 @@ public:
// This is a no-op in Version4 (coverage mappings are not affixed to the
// coverage header).
const char *MappingBuf = CovBuf;
- if (Version >= CovMapVersion::Version4 && CoverageSize != 0)
+ if (Version >= CovMapVersion::Version4 && CoverageSize != 0)
return make_error<CoverageMapError>(coveragemap_error::malformed);
CovBuf += CoverageSize;
const char *MappingEnd = CovBuf;
@@ -702,7 +702,7 @@ public:
if (FileRange && !FileRange->isInvalid()) {
StringRef Mapping =
CFR->template getCoverageMapping<Endian>(OutOfLineMappingBuf);
- if (Version >= CovMapVersion::Version4 &&
+ if (Version >= CovMapVersion::Version4 &&
Mapping.data() + Mapping.size() > FuncRecBufEnd)
return make_error<CoverageMapError>(coveragemap_error::malformed);
if (Error Err = insertFunctionRecordIfNeeded(CFR, Mapping, *FileRange))
@@ -731,7 +731,7 @@ Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
case CovMapVersion::Version2:
case CovMapVersion::Version3:
case CovMapVersion::Version4:
- case CovMapVersion::Version5:
+ case CovMapVersion::Version5:
// Decompress the name data.
if (Error E = P.create(P.getNameData()))
return std::move(E);
@@ -744,9 +744,9 @@ Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
else if (Version == CovMapVersion::Version4)
return std::make_unique<VersionedCovMapFuncRecordReader<
CovMapVersion::Version4, IntPtrT, Endian>>(P, R, F);
- else if (Version == CovMapVersion::Version5)
- return std::make_unique<VersionedCovMapFuncRecordReader<
- CovMapVersion::Version5, IntPtrT, Endian>>(P, R, F);
+ else if (Version == CovMapVersion::Version5)
+ return std::make_unique<VersionedCovMapFuncRecordReader<
+ CovMapVersion::Version5, IntPtrT, Endian>>(P, R, F);
}
llvm_unreachable("Unsupported version");
}
@@ -790,7 +790,7 @@ static Error readCoverageMappingData(
}
// In Version4, function records are not affixed to coverage headers. Read
// the records from their dedicated section.
- if (Version >= CovMapVersion::Version4)
+ if (Version >= CovMapVersion::Version4)
return Reader->readFunctionRecords(FuncRecBuf, FuncRecBufEnd, None, nullptr,
nullptr);
return Error::success();
@@ -974,19 +974,19 @@ loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch) {
BytesInAddress, Endian);
}
-/// Determine whether \p Arch is invalid or empty, given \p Bin.
-static bool isArchSpecifierInvalidOrMissing(Binary *Bin, StringRef Arch) {
- // If we have a universal binary and Arch doesn't identify any of its slices,
- // it's user error.
- if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin)) {
- for (auto &ObjForArch : Universal->objects())
- if (Arch == ObjForArch.getArchFlagName())
- return false;
- return true;
- }
- return false;
-}
-
+/// Determine whether \p Arch is invalid or empty, given \p Bin.
+static bool isArchSpecifierInvalidOrMissing(Binary *Bin, StringRef Arch) {
+ // If we have a universal binary and Arch doesn't identify any of its slices,
+ // it's user error.
+ if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin)) {
+ for (auto &ObjForArch : Universal->objects())
+ if (Arch == ObjForArch.getArchFlagName())
+ return false;
+ return true;
+ }
+ return false;
+}
+
Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>>
BinaryCoverageReader::create(
MemoryBufferRef ObjectBuffer, StringRef Arch,
@@ -1007,10 +1007,10 @@ BinaryCoverageReader::create(
return BinOrErr.takeError();
std::unique_ptr<Binary> Bin = std::move(BinOrErr.get());
- if (isArchSpecifierInvalidOrMissing(Bin.get(), Arch))
- return make_error<CoverageMapError>(
- coveragemap_error::invalid_or_missing_arch_specifier);
-
+ if (isArchSpecifierInvalidOrMissing(Bin.get(), Arch))
+ return make_error<CoverageMapError>(
+ coveragemap_error::invalid_or_missing_arch_specifier);
+
// MachO universal binaries which contain archives need to be treated as
// archives, not as regular binaries.
if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
diff --git a/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMappingWriter.cpp b/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
index a9ad67f63b..65b83d1f41 100644
--- a/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
+++ b/contrib/libs/llvm12/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
@@ -80,14 +80,14 @@ public:
ArrayRef<CounterMappingRegion> MappingRegions)
: Expressions(Expressions) {
AdjustedExpressionIDs.resize(Expressions.size(), 0);
- for (const auto &I : MappingRegions) {
+ for (const auto &I : MappingRegions) {
mark(I.Count);
- mark(I.FalseCount);
- }
- for (const auto &I : MappingRegions) {
+ mark(I.FalseCount);
+ }
+ for (const auto &I : MappingRegions) {
gatherUsed(I.Count);
- gatherUsed(I.FalseCount);
- }
+ gatherUsed(I.FalseCount);
+ }
}
void mark(Counter C) {
@@ -205,7 +205,7 @@ void CoverageMappingWriter::write(raw_ostream &OS) {
PrevLineStart = 0;
}
Counter Count = Minimizer.adjust(I->Count);
- Counter FalseCount = Minimizer.adjust(I->FalseCount);
+ Counter FalseCount = Minimizer.adjust(I->FalseCount);
switch (I->Kind) {
case CounterMappingRegion::CodeRegion:
case CounterMappingRegion::GapRegion:
@@ -231,13 +231,13 @@ void CoverageMappingWriter::write(raw_ostream &OS) {
<< Counter::EncodingCounterTagAndExpansionRegionTagBits,
OS);
break;
- case CounterMappingRegion::BranchRegion:
- encodeULEB128(unsigned(I->Kind)
- << Counter::EncodingCounterTagAndExpansionRegionTagBits,
- OS);
- writeCounter(MinExpressions, Count, OS);
- writeCounter(MinExpressions, FalseCount, OS);
- break;
+ case CounterMappingRegion::BranchRegion:
+ encodeULEB128(unsigned(I->Kind)
+ << Counter::EncodingCounterTagAndExpansionRegionTagBits,
+ OS);
+ writeCounter(MinExpressions, Count, OS);
+ writeCounter(MinExpressions, FalseCount, OS);
+ break;
}
assert(I->LineStart >= PrevLineStart);
encodeULEB128(I->LineStart - PrevLineStart, OS);
diff --git a/contrib/libs/llvm12/lib/ProfileData/Coverage/ya.make b/contrib/libs/llvm12/lib/ProfileData/Coverage/ya.make
index efd850fcac..7485f519d1 100644
--- a/contrib/libs/llvm12/lib/ProfileData/Coverage/ya.make
+++ b/contrib/libs/llvm12/lib/ProfileData/Coverage/ya.make
@@ -12,11 +12,11 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/ProfileData
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/ProfileData
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/ProfileData/GCOV.cpp b/contrib/libs/llvm12/lib/ProfileData/GCOV.cpp
index aef75c8c61..3332a89860 100644
--- a/contrib/libs/llvm12/lib/ProfileData/GCOV.cpp
+++ b/contrib/libs/llvm12/lib/ProfileData/GCOV.cpp
@@ -14,16 +14,16 @@
#include "llvm/ProfileData/GCOV.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Config/llvm-config.h"
-#include "llvm/Demangle/Demangle.h"
+#include "llvm/Demangle/Demangle.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
-#include "llvm/Support/MD5.h"
+#include "llvm/Support/MD5.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <system_error>
-#include <unordered_map>
+#include <unordered_map>
using namespace llvm;
@@ -41,59 +41,59 @@ enum : uint32_t {
GCOV_TAG_PROGRAM_SUMMARY = 0xa3000000,
};
-namespace {
-struct Summary {
- Summary(StringRef Name) : Name(Name) {}
-
- StringRef Name;
- uint64_t lines = 0;
- uint64_t linesExec = 0;
- uint64_t branches = 0;
- uint64_t branchesExec = 0;
- uint64_t branchesTaken = 0;
-};
-
-struct LineInfo {
- SmallVector<const GCOVBlock *, 1> blocks;
- uint64_t count = 0;
- bool exists = false;
-};
-
-struct SourceInfo {
- StringRef filename;
- SmallString<0> displayName;
- std::vector<std::vector<const GCOVFunction *>> startLineToFunctions;
- std::vector<LineInfo> lines;
- bool ignored = false;
- SourceInfo(StringRef filename) : filename(filename) {}
-};
-
-class Context {
-public:
- Context(const GCOV::Options &Options) : options(Options) {}
- void print(StringRef filename, StringRef gcno, StringRef gcda,
- GCOVFile &file);
-
-private:
- std::string getCoveragePath(StringRef filename, StringRef mainFilename) const;
- void printFunctionDetails(const GCOVFunction &f, raw_ostream &os) const;
- void printBranchInfo(const GCOVBlock &Block, uint32_t &edgeIdx,
- raw_ostream &OS) const;
- void printSummary(const Summary &summary, raw_ostream &os) const;
-
- void collectFunction(GCOVFunction &f, Summary &summary);
- void collectSourceLine(SourceInfo &si, Summary *summary, LineInfo &line,
- size_t lineNum) const;
- void collectSource(SourceInfo &si, Summary &summary) const;
- void annotateSource(SourceInfo &si, const GCOVFile &file, StringRef gcno,
- StringRef gcda, raw_ostream &os) const;
- void printSourceToIntermediate(const SourceInfo &si, raw_ostream &os) const;
-
- const GCOV::Options &options;
- std::vector<SourceInfo> sources;
-};
-} // namespace
-
+namespace {
+struct Summary {
+ Summary(StringRef Name) : Name(Name) {}
+
+ StringRef Name;
+ uint64_t lines = 0;
+ uint64_t linesExec = 0;
+ uint64_t branches = 0;
+ uint64_t branchesExec = 0;
+ uint64_t branchesTaken = 0;
+};
+
+struct LineInfo {
+ SmallVector<const GCOVBlock *, 1> blocks;
+ uint64_t count = 0;
+ bool exists = false;
+};
+
+struct SourceInfo {
+ StringRef filename;
+ SmallString<0> displayName;
+ std::vector<std::vector<const GCOVFunction *>> startLineToFunctions;
+ std::vector<LineInfo> lines;
+ bool ignored = false;
+ SourceInfo(StringRef filename) : filename(filename) {}
+};
+
+class Context {
+public:
+ Context(const GCOV::Options &Options) : options(Options) {}
+ void print(StringRef filename, StringRef gcno, StringRef gcda,
+ GCOVFile &file);
+
+private:
+ std::string getCoveragePath(StringRef filename, StringRef mainFilename) const;
+ void printFunctionDetails(const GCOVFunction &f, raw_ostream &os) const;
+ void printBranchInfo(const GCOVBlock &Block, uint32_t &edgeIdx,
+ raw_ostream &OS) const;
+ void printSummary(const Summary &summary, raw_ostream &os) const;
+
+ void collectFunction(GCOVFunction &f, Summary &summary);
+ void collectSourceLine(SourceInfo &si, Summary *summary, LineInfo &line,
+ size_t lineNum) const;
+ void collectSource(SourceInfo &si, Summary &summary) const;
+ void annotateSource(SourceInfo &si, const GCOVFile &file, StringRef gcno,
+ StringRef gcda, raw_ostream &os) const;
+ void printSourceToIntermediate(const SourceInfo &si, raw_ostream &os) const;
+
+ const GCOV::Options &options;
+ std::vector<SourceInfo> sources;
+};
+} // namespace
+
//===----------------------------------------------------------------------===//
// GCOVFile implementation.
@@ -111,13 +111,13 @@ bool GCOVFile::readGCNO(GCOVBuffer &buf) {
buf.getWord(); // hasUnexecutedBlocks
uint32_t tag, length;
- GCOVFunction *fn = nullptr;
+ GCOVFunction *fn = nullptr;
while ((tag = buf.getWord())) {
if (!buf.readInt(length))
return false;
if (tag == GCOV_TAG_FUNCTION) {
- functions.push_back(std::make_unique<GCOVFunction>(*this));
- fn = functions.back().get();
+ functions.push_back(std::make_unique<GCOVFunction>(*this));
+ fn = functions.back().get();
fn->ident = buf.getWord();
fn->linenoChecksum = buf.getWord();
if (Version >= GCOV::V407)
@@ -145,40 +145,40 @@ bool GCOVFile::readGCNO(GCOVBuffer &buf) {
if (Version < GCOV::V800) {
for (uint32_t i = 0; i != length; ++i) {
buf.getWord(); // Ignored block flags
- fn->blocks.push_back(std::make_unique<GCOVBlock>(i));
+ fn->blocks.push_back(std::make_unique<GCOVBlock>(i));
}
} else {
uint32_t num = buf.getWord();
for (uint32_t i = 0; i != num; ++i)
- fn->blocks.push_back(std::make_unique<GCOVBlock>(i));
+ fn->blocks.push_back(std::make_unique<GCOVBlock>(i));
}
} else if (tag == GCOV_TAG_ARCS && fn) {
uint32_t srcNo = buf.getWord();
- if (srcNo >= fn->blocks.size()) {
+ if (srcNo >= fn->blocks.size()) {
errs() << "unexpected block number: " << srcNo << " (in "
- << fn->blocks.size() << ")\n";
+ << fn->blocks.size() << ")\n";
return false;
}
- GCOVBlock *src = fn->blocks[srcNo].get();
+ GCOVBlock *src = fn->blocks[srcNo].get();
for (uint32_t i = 0, e = (length - 1) / 2; i != e; ++i) {
uint32_t dstNo = buf.getWord(), flags = buf.getWord();
- GCOVBlock *dst = fn->blocks[dstNo].get();
- auto arc = std::make_unique<GCOVArc>(*src, *dst, flags);
+ GCOVBlock *dst = fn->blocks[dstNo].get();
+ auto arc = std::make_unique<GCOVArc>(*src, *dst, flags);
src->addDstEdge(arc.get());
dst->addSrcEdge(arc.get());
- if (arc->onTree())
+ if (arc->onTree())
fn->treeArcs.push_back(std::move(arc));
else
fn->arcs.push_back(std::move(arc));
}
} else if (tag == GCOV_TAG_LINES && fn) {
uint32_t srcNo = buf.getWord();
- if (srcNo >= fn->blocks.size()) {
+ if (srcNo >= fn->blocks.size()) {
errs() << "unexpected block number: " << srcNo << " (in "
- << fn->blocks.size() << ")\n";
+ << fn->blocks.size() << ")\n";
return false;
}
- GCOVBlock &Block = *fn->blocks[srcNo];
+ GCOVBlock &Block = *fn->blocks[srcNo];
for (;;) {
uint32_t line = buf.getWord();
if (line)
@@ -273,25 +273,25 @@ bool GCOVFile::readGCDA(GCOVBuffer &buf) {
return false;
}
for (std::unique_ptr<GCOVArc> &arc : fn->arcs) {
- if (!buf.readInt64(arc->count))
+ if (!buf.readInt64(arc->count))
return false;
- arc->src.count += arc->count;
+ arc->src.count += arc->count;
+ }
+
+ if (fn->blocks.size() >= 2) {
+ GCOVBlock &src = *fn->blocks[0];
+ GCOVBlock &sink =
+ Version < GCOV::V408 ? *fn->blocks.back() : *fn->blocks[1];
+ auto arc = std::make_unique<GCOVArc>(sink, src, GCOV_ARC_ON_TREE);
+ sink.addDstEdge(arc.get());
+ src.addSrcEdge(arc.get());
+ fn->treeArcs.push_back(std::move(arc));
+
+ for (GCOVBlock &block : fn->blocksRange())
+ fn->propagateCounts(block, nullptr);
+ for (size_t i = fn->treeArcs.size() - 1; i; --i)
+ fn->treeArcs[i - 1]->src.count += fn->treeArcs[i - 1]->count;
}
-
- if (fn->blocks.size() >= 2) {
- GCOVBlock &src = *fn->blocks[0];
- GCOVBlock &sink =
- Version < GCOV::V408 ? *fn->blocks.back() : *fn->blocks[1];
- auto arc = std::make_unique<GCOVArc>(sink, src, GCOV_ARC_ON_TREE);
- sink.addDstEdge(arc.get());
- src.addSrcEdge(arc.get());
- fn->treeArcs.push_back(std::move(arc));
-
- for (GCOVBlock &block : fn->blocksRange())
- fn->propagateCounts(block, nullptr);
- for (size_t i = fn->treeArcs.size() - 1; i; --i)
- fn->treeArcs[i - 1]->src.count += fn->treeArcs[i - 1]->count;
- }
}
pos += 4 * length;
if (pos < buf.cursor.tell())
@@ -312,71 +312,71 @@ void GCOVFile::print(raw_ostream &OS) const {
LLVM_DUMP_METHOD void GCOVFile::dump() const { print(dbgs()); }
#endif
-bool GCOVArc::onTree() const { return flags & GCOV_ARC_ON_TREE; }
+bool GCOVArc::onTree() const { return flags & GCOV_ARC_ON_TREE; }
//===----------------------------------------------------------------------===//
// GCOVFunction implementation.
-StringRef GCOVFunction::getName(bool demangle) const {
- if (!demangle)
- return Name;
- if (demangled.empty()) {
- do {
- if (Name.startswith("_Z")) {
- int status = 0;
- // Name is guaranteed to be NUL-terminated.
- char *res = itaniumDemangle(Name.data(), nullptr, nullptr, &status);
- if (status == 0) {
- demangled = res;
- free(res);
- break;
- }
- }
- demangled = Name;
- } while (0);
- }
- return demangled;
-}
+StringRef GCOVFunction::getName(bool demangle) const {
+ if (!demangle)
+ return Name;
+ if (demangled.empty()) {
+ do {
+ if (Name.startswith("_Z")) {
+ int status = 0;
+ // Name is guaranteed to be NUL-terminated.
+ char *res = itaniumDemangle(Name.data(), nullptr, nullptr, &status);
+ if (status == 0) {
+ demangled = res;
+ free(res);
+ break;
+ }
+ }
+ demangled = Name;
+ } while (0);
+ }
+ return demangled;
+}
StringRef GCOVFunction::getFilename() const { return file.filenames[srcIdx]; }
/// getEntryCount - Get the number of times the function was called by
/// retrieving the entry block's count.
uint64_t GCOVFunction::getEntryCount() const {
- return blocks.front()->getCount();
+ return blocks.front()->getCount();
+}
+
+GCOVBlock &GCOVFunction::getExitBlock() const {
+ return file.getVersion() < GCOV::V408 ? *blocks.back() : *blocks[1];
}
-GCOVBlock &GCOVFunction::getExitBlock() const {
- return file.getVersion() < GCOV::V408 ? *blocks.back() : *blocks[1];
+// For each basic block, the sum of incoming edge counts equals the sum of
+// outgoing edge counts by Kirchoff's circuit law. If the unmeasured arcs form a
+// spanning tree, the count for each unmeasured arc (GCOV_ARC_ON_TREE) can be
+// uniquely identified.
+uint64_t GCOVFunction::propagateCounts(const GCOVBlock &v, GCOVArc *pred) {
+ // If GCOV_ARC_ON_TREE edges do form a tree, visited is not needed; otherwise
+ // this prevents infinite recursion.
+ if (!visited.insert(&v).second)
+ return 0;
+
+ uint64_t excess = 0;
+ for (GCOVArc *e : v.srcs())
+ if (e != pred)
+ excess += e->onTree() ? propagateCounts(e->src, e) : e->count;
+ for (GCOVArc *e : v.dsts())
+ if (e != pred)
+ excess -= e->onTree() ? propagateCounts(e->dst, e) : e->count;
+ if (int64_t(excess) < 0)
+ excess = -excess;
+ if (pred)
+ pred->count = excess;
+ return excess;
}
-// For each basic block, the sum of incoming edge counts equals the sum of
-// outgoing edge counts by Kirchoff's circuit law. If the unmeasured arcs form a
-// spanning tree, the count for each unmeasured arc (GCOV_ARC_ON_TREE) can be
-// uniquely identified.
-uint64_t GCOVFunction::propagateCounts(const GCOVBlock &v, GCOVArc *pred) {
- // If GCOV_ARC_ON_TREE edges do form a tree, visited is not needed; otherwise
- // this prevents infinite recursion.
- if (!visited.insert(&v).second)
- return 0;
-
- uint64_t excess = 0;
- for (GCOVArc *e : v.srcs())
- if (e != pred)
- excess += e->onTree() ? propagateCounts(e->src, e) : e->count;
- for (GCOVArc *e : v.dsts())
- if (e != pred)
- excess -= e->onTree() ? propagateCounts(e->dst, e) : e->count;
- if (int64_t(excess) < 0)
- excess = -excess;
- if (pred)
- pred->count = excess;
- return excess;
-}
-
void GCOVFunction::print(raw_ostream &OS) const {
OS << "===== " << Name << " (" << ident << ") @ " << getFilename() << ":"
<< startLine << "\n";
- for (const auto &Block : blocks)
+ for (const auto &Block : blocks)
Block->print(OS);
}
@@ -392,25 +392,25 @@ LLVM_DUMP_METHOD void GCOVFunction::dump() const { print(dbgs()); }
// GCOVBlock implementation.
void GCOVBlock::print(raw_ostream &OS) const {
- OS << "Block : " << number << " Counter : " << count << "\n";
+ OS << "Block : " << number << " Counter : " << count << "\n";
if (!pred.empty()) {
OS << "\tSource Edges : ";
for (const GCOVArc *Edge : pred)
- OS << Edge->src.number << " (" << Edge->count << "), ";
+ OS << Edge->src.number << " (" << Edge->count << "), ";
OS << "\n";
}
if (!succ.empty()) {
OS << "\tDestination Edges : ";
- for (const GCOVArc *Edge : succ) {
- if (Edge->flags & GCOV_ARC_ON_TREE)
- OS << '*';
- OS << Edge->dst.number << " (" << Edge->count << "), ";
- }
+ for (const GCOVArc *Edge : succ) {
+ if (Edge->flags & GCOV_ARC_ON_TREE)
+ OS << '*';
+ OS << Edge->dst.number << " (" << Edge->count << "), ";
+ }
OS << "\n";
}
- if (!lines.empty()) {
+ if (!lines.empty()) {
OS << "\tLines : ";
- for (uint32_t N : lines)
+ for (uint32_t N : lines)
OS << (N) << ",";
OS << "\n";
}
@@ -421,96 +421,96 @@ void GCOVBlock::print(raw_ostream &OS) const {
LLVM_DUMP_METHOD void GCOVBlock::dump() const { print(dbgs()); }
#endif
-uint64_t
-GCOVBlock::augmentOneCycle(GCOVBlock *src,
- std::vector<std::pair<GCOVBlock *, size_t>> &stack) {
- GCOVBlock *u;
- size_t i;
- stack.clear();
- stack.emplace_back(src, 0);
- src->incoming = (GCOVArc *)1; // Mark u available for cycle detection
- for (;;) {
- std::tie(u, i) = stack.back();
- if (i == u->succ.size()) {
- u->traversable = false;
- stack.pop_back();
- if (stack.empty())
- break;
+uint64_t
+GCOVBlock::augmentOneCycle(GCOVBlock *src,
+ std::vector<std::pair<GCOVBlock *, size_t>> &stack) {
+ GCOVBlock *u;
+ size_t i;
+ stack.clear();
+ stack.emplace_back(src, 0);
+ src->incoming = (GCOVArc *)1; // Mark u available for cycle detection
+ for (;;) {
+ std::tie(u, i) = stack.back();
+ if (i == u->succ.size()) {
+ u->traversable = false;
+ stack.pop_back();
+ if (stack.empty())
+ break;
continue;
}
- ++stack.back().second;
- GCOVArc *succ = u->succ[i];
- // Ignore saturated arcs (cycleCount has been reduced to 0) and visited
- // blocks. Ignore self arcs to guard against bad input (.gcno has no
- // self arcs).
- if (succ->cycleCount == 0 || !succ->dst.traversable || &succ->dst == u)
- continue;
- if (succ->dst.incoming == nullptr) {
- succ->dst.incoming = succ;
- stack.emplace_back(&succ->dst, 0);
- continue;
+ ++stack.back().second;
+ GCOVArc *succ = u->succ[i];
+ // Ignore saturated arcs (cycleCount has been reduced to 0) and visited
+ // blocks. Ignore self arcs to guard against bad input (.gcno has no
+ // self arcs).
+ if (succ->cycleCount == 0 || !succ->dst.traversable || &succ->dst == u)
+ continue;
+ if (succ->dst.incoming == nullptr) {
+ succ->dst.incoming = succ;
+ stack.emplace_back(&succ->dst, 0);
+ continue;
+ }
+ uint64_t minCount = succ->cycleCount;
+ for (GCOVBlock *v = u;;) {
+ minCount = std::min(minCount, v->incoming->cycleCount);
+ v = &v->incoming->src;
+ if (v == &succ->dst)
+ break;
}
- uint64_t minCount = succ->cycleCount;
- for (GCOVBlock *v = u;;) {
- minCount = std::min(minCount, v->incoming->cycleCount);
- v = &v->incoming->src;
- if (v == &succ->dst)
- break;
+ succ->cycleCount -= minCount;
+ for (GCOVBlock *v = u;;) {
+ v->incoming->cycleCount -= minCount;
+ v = &v->incoming->src;
+ if (v == &succ->dst)
+ break;
}
- succ->cycleCount -= minCount;
- for (GCOVBlock *v = u;;) {
- v->incoming->cycleCount -= minCount;
- v = &v->incoming->src;
- if (v == &succ->dst)
- break;
- }
- return minCount;
+ return minCount;
}
- return 0;
+ return 0;
}
-// Get the total execution count of loops among blocks on the same line.
-// Assuming a reducible flow graph, the count is the sum of back edge counts.
-// Identifying loops is complex, so we simply find cycles and perform cycle
-// cancelling iteratively.
-uint64_t GCOVBlock::getCyclesCount(const BlockVector &blocks) {
- std::vector<std::pair<GCOVBlock *, size_t>> stack;
- uint64_t count = 0, d;
- for (;;) {
- // Make blocks on the line traversable and try finding a cycle.
- for (auto b : blocks) {
- const_cast<GCOVBlock *>(b)->traversable = true;
- const_cast<GCOVBlock *>(b)->incoming = nullptr;
+// Get the total execution count of loops among blocks on the same line.
+// Assuming a reducible flow graph, the count is the sum of back edge counts.
+// Identifying loops is complex, so we simply find cycles and perform cycle
+// cancelling iteratively.
+uint64_t GCOVBlock::getCyclesCount(const BlockVector &blocks) {
+ std::vector<std::pair<GCOVBlock *, size_t>> stack;
+ uint64_t count = 0, d;
+ for (;;) {
+ // Make blocks on the line traversable and try finding a cycle.
+ for (auto b : blocks) {
+ const_cast<GCOVBlock *>(b)->traversable = true;
+ const_cast<GCOVBlock *>(b)->incoming = nullptr;
}
- d = 0;
- for (auto block : blocks) {
- auto *b = const_cast<GCOVBlock *>(block);
- if (b->traversable && (d = augmentOneCycle(b, stack)) > 0)
- break;
+ d = 0;
+ for (auto block : blocks) {
+ auto *b = const_cast<GCOVBlock *>(block);
+ if (b->traversable && (d = augmentOneCycle(b, stack)) > 0)
+ break;
}
- if (d == 0)
- break;
- count += d;
+ if (d == 0)
+ break;
+ count += d;
}
- // If there is no more loop, all traversable bits should have been cleared.
- // This property is needed by subsequent calls.
- for (auto b : blocks) {
- assert(!b->traversable);
- (void)b;
- }
- return count;
+ // If there is no more loop, all traversable bits should have been cleared.
+ // This property is needed by subsequent calls.
+ for (auto b : blocks) {
+ assert(!b->traversable);
+ (void)b;
+ }
+ return count;
}
//===----------------------------------------------------------------------===//
// FileInfo implementation.
-// Format dividend/divisor as a percentage. Return 1 if the result is greater
-// than 0% and less than 1%.
-static uint32_t formatPercentage(uint64_t dividend, uint64_t divisor) {
- if (!dividend || !divisor)
+// Format dividend/divisor as a percentage. Return 1 if the result is greater
+// than 0% and less than 1%.
+static uint32_t formatPercentage(uint64_t dividend, uint64_t divisor) {
+ if (!dividend || !divisor)
return 0;
- dividend *= 100;
- return dividend < divisor ? 1 : dividend / divisor;
+ dividend *= 100;
+ return dividend < divisor ? 1 : dividend / divisor;
}
// This custom division function mimics gcov's branch ouputs:
@@ -561,11 +561,11 @@ class LineConsumer {
public:
LineConsumer() = default;
LineConsumer(StringRef Filename) {
- // Open source files without requiring a NUL terminator. The concurrent
- // modification may nullify the NUL terminator condition.
+ // Open source files without requiring a NUL terminator. The concurrent
+ // modification may nullify the NUL terminator condition.
ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
- MemoryBuffer::getFileOrSTDIN(Filename, -1,
- /*RequiresNullTerminator=*/false);
+ MemoryBuffer::getFileOrSTDIN(Filename, -1,
+ /*RequiresNullTerminator=*/false);
if (std::error_code EC = BufferOrErr.getError()) {
errs() << Filename << ": " << EC.message() << "\n";
Remaining = "";
@@ -621,23 +621,23 @@ static std::string mangleCoveragePath(StringRef Filename, bool PreservePaths) {
return std::string(Result.str());
}
-std::string Context::getCoveragePath(StringRef filename,
- StringRef mainFilename) const {
- if (options.NoOutput)
+std::string Context::getCoveragePath(StringRef filename,
+ StringRef mainFilename) const {
+ if (options.NoOutput)
// This is probably a bug in gcov, but when -n is specified, paths aren't
// mangled at all, and the -l and -p options are ignored. Here, we do the
// same.
- return std::string(filename);
+ return std::string(filename);
std::string CoveragePath;
- if (options.LongFileNames && !filename.equals(mainFilename))
+ if (options.LongFileNames && !filename.equals(mainFilename))
CoveragePath =
- mangleCoveragePath(mainFilename, options.PreservePaths) + "##";
- CoveragePath += mangleCoveragePath(filename, options.PreservePaths);
- if (options.HashFilenames) {
+ mangleCoveragePath(mainFilename, options.PreservePaths) + "##";
+ CoveragePath += mangleCoveragePath(filename, options.PreservePaths);
+ if (options.HashFilenames) {
MD5 Hasher;
MD5::MD5Result Result;
- Hasher.update(filename.str());
+ Hasher.update(filename.str());
Hasher.final(Result);
CoveragePath += "##" + std::string(Result.digest());
}
@@ -645,302 +645,302 @@ std::string Context::getCoveragePath(StringRef filename,
return CoveragePath;
}
-void Context::collectFunction(GCOVFunction &f, Summary &summary) {
- SourceInfo &si = sources[f.srcIdx];
- if (f.startLine >= si.startLineToFunctions.size())
- si.startLineToFunctions.resize(f.startLine + 1);
- si.startLineToFunctions[f.startLine].push_back(&f);
- for (const GCOVBlock &b : f.blocksRange()) {
- if (b.lines.empty())
- continue;
- uint32_t maxLineNum = *std::max_element(b.lines.begin(), b.lines.end());
- if (maxLineNum >= si.lines.size())
- si.lines.resize(maxLineNum + 1);
- for (uint32_t lineNum : b.lines) {
- LineInfo &line = si.lines[lineNum];
- if (!line.exists)
- ++summary.lines;
- if (line.count == 0 && b.count)
- ++summary.linesExec;
- line.exists = true;
- line.count += b.count;
- line.blocks.push_back(&b);
- }
+void Context::collectFunction(GCOVFunction &f, Summary &summary) {
+ SourceInfo &si = sources[f.srcIdx];
+ if (f.startLine >= si.startLineToFunctions.size())
+ si.startLineToFunctions.resize(f.startLine + 1);
+ si.startLineToFunctions[f.startLine].push_back(&f);
+ for (const GCOVBlock &b : f.blocksRange()) {
+ if (b.lines.empty())
+ continue;
+ uint32_t maxLineNum = *std::max_element(b.lines.begin(), b.lines.end());
+ if (maxLineNum >= si.lines.size())
+ si.lines.resize(maxLineNum + 1);
+ for (uint32_t lineNum : b.lines) {
+ LineInfo &line = si.lines[lineNum];
+ if (!line.exists)
+ ++summary.lines;
+ if (line.count == 0 && b.count)
+ ++summary.linesExec;
+ line.exists = true;
+ line.count += b.count;
+ line.blocks.push_back(&b);
+ }
}
}
-void Context::collectSourceLine(SourceInfo &si, Summary *summary,
- LineInfo &line, size_t lineNum) const {
- uint64_t count = 0;
- for (const GCOVBlock *b : line.blocks) {
- if (b->number == 0) {
- // For nonstandard control flows, arcs into the exit block may be
- // duplicately counted (fork) or not be counted (abnormal exit), and thus
- // the (exit,entry) counter may be inaccurate. Count the entry block with
- // the outgoing arcs.
- for (const GCOVArc *arc : b->succ)
- count += arc->count;
- } else {
- // Add counts from predecessors that are not on the same line.
- for (const GCOVArc *arc : b->pred)
- if (!llvm::is_contained(line.blocks, &arc->src))
- count += arc->count;
- }
- for (GCOVArc *arc : b->succ)
- arc->cycleCount = arc->count;
- }
-
- count += GCOVBlock::getCyclesCount(line.blocks);
- line.count = count;
- if (line.exists) {
- ++summary->lines;
- if (line.count != 0)
- ++summary->linesExec;
- }
-
- if (options.BranchInfo)
- for (const GCOVBlock *b : line.blocks) {
- if (b->getLastLine() != lineNum)
- continue;
- int branches = 0, execBranches = 0, takenBranches = 0;
- for (const GCOVArc *arc : b->succ) {
- ++branches;
- if (count != 0)
- ++execBranches;
- if (arc->count != 0)
- ++takenBranches;
+void Context::collectSourceLine(SourceInfo &si, Summary *summary,
+ LineInfo &line, size_t lineNum) const {
+ uint64_t count = 0;
+ for (const GCOVBlock *b : line.blocks) {
+ if (b->number == 0) {
+ // For nonstandard control flows, arcs into the exit block may be
+ // duplicately counted (fork) or not be counted (abnormal exit), and thus
+ // the (exit,entry) counter may be inaccurate. Count the entry block with
+ // the outgoing arcs.
+ for (const GCOVArc *arc : b->succ)
+ count += arc->count;
+ } else {
+ // Add counts from predecessors that are not on the same line.
+ for (const GCOVArc *arc : b->pred)
+ if (!llvm::is_contained(line.blocks, &arc->src))
+ count += arc->count;
+ }
+ for (GCOVArc *arc : b->succ)
+ arc->cycleCount = arc->count;
+ }
+
+ count += GCOVBlock::getCyclesCount(line.blocks);
+ line.count = count;
+ if (line.exists) {
+ ++summary->lines;
+ if (line.count != 0)
+ ++summary->linesExec;
+ }
+
+ if (options.BranchInfo)
+ for (const GCOVBlock *b : line.blocks) {
+ if (b->getLastLine() != lineNum)
+ continue;
+ int branches = 0, execBranches = 0, takenBranches = 0;
+ for (const GCOVArc *arc : b->succ) {
+ ++branches;
+ if (count != 0)
+ ++execBranches;
+ if (arc->count != 0)
+ ++takenBranches;
+ }
+ if (branches > 1) {
+ summary->branches += branches;
+ summary->branchesExec += execBranches;
+ summary->branchesTaken += takenBranches;
}
- if (branches > 1) {
- summary->branches += branches;
- summary->branchesExec += execBranches;
- summary->branchesTaken += takenBranches;
- }
- }
-}
-
-void Context::collectSource(SourceInfo &si, Summary &summary) const {
- size_t lineNum = 0;
- for (LineInfo &line : si.lines) {
- collectSourceLine(si, &summary, line, lineNum);
- ++lineNum;
- }
-}
-
-void Context::annotateSource(SourceInfo &si, const GCOVFile &file,
- StringRef gcno, StringRef gcda,
- raw_ostream &os) const {
- auto source =
- options.Intermediate ? LineConsumer() : LineConsumer(si.filename);
-
- os << " -: 0:Source:" << si.displayName << '\n';
- os << " -: 0:Graph:" << gcno << '\n';
- os << " -: 0:Data:" << gcda << '\n';
- os << " -: 0:Runs:" << file.RunCount << '\n';
- if (file.Version < GCOV::V900)
- os << " -: 0:Programs:" << file.ProgramCount << '\n';
-
- for (size_t lineNum = 1; !source.empty(); ++lineNum) {
- if (lineNum >= si.lines.size()) {
- os << " -:";
- source.printNext(os, lineNum);
- continue;
- }
-
- const LineInfo &line = si.lines[lineNum];
- if (options.BranchInfo && lineNum < si.startLineToFunctions.size())
- for (const auto *f : si.startLineToFunctions[lineNum])
- printFunctionDetails(*f, os);
- if (!line.exists)
- os << " -:";
- else if (line.count == 0)
- os << " #####:";
- else
- os << format("%9" PRIu64 ":", line.count);
- source.printNext(os, lineNum);
-
- uint32_t blockIdx = 0, edgeIdx = 0;
- for (const GCOVBlock *b : line.blocks) {
- if (b->getLastLine() != lineNum)
- continue;
- if (options.AllBlocks) {
- if (b->getCount() == 0)
- os << " $$$$$:";
- else
- os << format("%9" PRIu64 ":", b->count);
- os << format("%5u-block %2u\n", lineNum, blockIdx++);
- }
- if (options.BranchInfo) {
- size_t NumEdges = b->succ.size();
- if (NumEdges > 1)
- printBranchInfo(*b, edgeIdx, os);
- else if (options.UncondBranch && NumEdges == 1) {
- uint64_t count = b->succ[0]->count;
- os << format("unconditional %2u ", edgeIdx++)
- << formatBranchInfo(options, count, count) << '\n';
+ }
+}
+
+void Context::collectSource(SourceInfo &si, Summary &summary) const {
+ size_t lineNum = 0;
+ for (LineInfo &line : si.lines) {
+ collectSourceLine(si, &summary, line, lineNum);
+ ++lineNum;
+ }
+}
+
+void Context::annotateSource(SourceInfo &si, const GCOVFile &file,
+ StringRef gcno, StringRef gcda,
+ raw_ostream &os) const {
+ auto source =
+ options.Intermediate ? LineConsumer() : LineConsumer(si.filename);
+
+ os << " -: 0:Source:" << si.displayName << '\n';
+ os << " -: 0:Graph:" << gcno << '\n';
+ os << " -: 0:Data:" << gcda << '\n';
+ os << " -: 0:Runs:" << file.RunCount << '\n';
+ if (file.Version < GCOV::V900)
+ os << " -: 0:Programs:" << file.ProgramCount << '\n';
+
+ for (size_t lineNum = 1; !source.empty(); ++lineNum) {
+ if (lineNum >= si.lines.size()) {
+ os << " -:";
+ source.printNext(os, lineNum);
+ continue;
+ }
+
+ const LineInfo &line = si.lines[lineNum];
+ if (options.BranchInfo && lineNum < si.startLineToFunctions.size())
+ for (const auto *f : si.startLineToFunctions[lineNum])
+ printFunctionDetails(*f, os);
+ if (!line.exists)
+ os << " -:";
+ else if (line.count == 0)
+ os << " #####:";
+ else
+ os << format("%9" PRIu64 ":", line.count);
+ source.printNext(os, lineNum);
+
+ uint32_t blockIdx = 0, edgeIdx = 0;
+ for (const GCOVBlock *b : line.blocks) {
+ if (b->getLastLine() != lineNum)
+ continue;
+ if (options.AllBlocks) {
+ if (b->getCount() == 0)
+ os << " $$$$$:";
+ else
+ os << format("%9" PRIu64 ":", b->count);
+ os << format("%5u-block %2u\n", lineNum, blockIdx++);
+ }
+ if (options.BranchInfo) {
+ size_t NumEdges = b->succ.size();
+ if (NumEdges > 1)
+ printBranchInfo(*b, edgeIdx, os);
+ else if (options.UncondBranch && NumEdges == 1) {
+ uint64_t count = b->succ[0]->count;
+ os << format("unconditional %2u ", edgeIdx++)
+ << formatBranchInfo(options, count, count) << '\n';
}
}
}
}
-}
-
-void Context::printSourceToIntermediate(const SourceInfo &si,
- raw_ostream &os) const {
- os << "file:" << si.filename << '\n';
- for (const auto &fs : si.startLineToFunctions)
- for (const GCOVFunction *f : fs)
- os << "function:" << f->startLine << ',' << f->getEntryCount() << ','
- << f->getName(options.Demangle) << '\n';
- for (size_t lineNum = 1, size = si.lines.size(); lineNum < size; ++lineNum) {
- const LineInfo &line = si.lines[lineNum];
- if (line.blocks.empty())
- continue;
- // GCC 8 (r254259) added third third field for Ada:
- // lcount:<line>,<count>,<has_unexecuted_blocks>
- // We don't need the third field.
- os << "lcount:" << lineNum << ',' << line.count << '\n';
-
- if (!options.BranchInfo)
- continue;
- for (const GCOVBlock *b : line.blocks) {
- if (b->succ.size() < 2 || b->getLastLine() != lineNum)
- continue;
- for (const GCOVArc *arc : b->succ) {
- const char *type =
- b->getCount() ? arc->count ? "taken" : "nottaken" : "notexec";
- os << "branch:" << lineNum << ',' << type << '\n';
+}
+
+void Context::printSourceToIntermediate(const SourceInfo &si,
+ raw_ostream &os) const {
+ os << "file:" << si.filename << '\n';
+ for (const auto &fs : si.startLineToFunctions)
+ for (const GCOVFunction *f : fs)
+ os << "function:" << f->startLine << ',' << f->getEntryCount() << ','
+ << f->getName(options.Demangle) << '\n';
+ for (size_t lineNum = 1, size = si.lines.size(); lineNum < size; ++lineNum) {
+ const LineInfo &line = si.lines[lineNum];
+ if (line.blocks.empty())
+ continue;
+ // GCC 8 (r254259) added third third field for Ada:
+ // lcount:<line>,<count>,<has_unexecuted_blocks>
+ // We don't need the third field.
+ os << "lcount:" << lineNum << ',' << line.count << '\n';
+
+ if (!options.BranchInfo)
+ continue;
+ for (const GCOVBlock *b : line.blocks) {
+ if (b->succ.size() < 2 || b->getLastLine() != lineNum)
+ continue;
+ for (const GCOVArc *arc : b->succ) {
+ const char *type =
+ b->getCount() ? arc->count ? "taken" : "nottaken" : "notexec";
+ os << "branch:" << lineNum << ',' << type << '\n';
}
}
}
-}
-
-void Context::print(StringRef filename, StringRef gcno, StringRef gcda,
- GCOVFile &file) {
- for (StringRef filename : file.filenames) {
- sources.emplace_back(filename);
- SourceInfo &si = sources.back();
- si.displayName = si.filename;
- if (!options.SourcePrefix.empty() &&
- sys::path::replace_path_prefix(si.displayName, options.SourcePrefix,
- "") &&
- !si.displayName.empty()) {
- // TODO replace_path_prefix may strip the prefix even if the remaining
- // part does not start with a separator.
- if (sys::path::is_separator(si.displayName[0]))
- si.displayName.erase(si.displayName.begin());
- else
- si.displayName = si.filename;
- }
- if (options.RelativeOnly && sys::path::is_absolute(si.displayName))
- si.ignored = true;
+}
+
+void Context::print(StringRef filename, StringRef gcno, StringRef gcda,
+ GCOVFile &file) {
+ for (StringRef filename : file.filenames) {
+ sources.emplace_back(filename);
+ SourceInfo &si = sources.back();
+ si.displayName = si.filename;
+ if (!options.SourcePrefix.empty() &&
+ sys::path::replace_path_prefix(si.displayName, options.SourcePrefix,
+ "") &&
+ !si.displayName.empty()) {
+ // TODO replace_path_prefix may strip the prefix even if the remaining
+ // part does not start with a separator.
+ if (sys::path::is_separator(si.displayName[0]))
+ si.displayName.erase(si.displayName.begin());
+ else
+ si.displayName = si.filename;
+ }
+ if (options.RelativeOnly && sys::path::is_absolute(si.displayName))
+ si.ignored = true;
}
- raw_ostream &os = llvm::outs();
- for (GCOVFunction &f : make_pointee_range(file.functions)) {
- Summary summary(f.getName(options.Demangle));
- collectFunction(f, summary);
- if (options.FuncCoverage && !options.UseStdout) {
- os << "Function '" << summary.Name << "'\n";
- printSummary(summary, os);
- os << '\n';
- }
+ raw_ostream &os = llvm::outs();
+ for (GCOVFunction &f : make_pointee_range(file.functions)) {
+ Summary summary(f.getName(options.Demangle));
+ collectFunction(f, summary);
+ if (options.FuncCoverage && !options.UseStdout) {
+ os << "Function '" << summary.Name << "'\n";
+ printSummary(summary, os);
+ os << '\n';
+ }
}
- for (SourceInfo &si : sources) {
- if (si.ignored)
- continue;
- Summary summary(si.displayName);
- collectSource(si, summary);
-
- // Print file summary unless -t is specified.
- std::string gcovName = getCoveragePath(si.filename, filename);
- if (!options.UseStdout) {
- os << "File '" << summary.Name << "'\n";
- printSummary(summary, os);
- if (!options.NoOutput && !options.Intermediate)
- os << "Creating '" << gcovName << "'\n";
- os << '\n';
- }
-
- if (options.NoOutput || options.Intermediate)
- continue;
- Optional<raw_fd_ostream> os;
- if (!options.UseStdout) {
- std::error_code ec;
- os.emplace(gcovName, ec, sys::fs::OF_Text);
- if (ec) {
- errs() << ec.message() << '\n';
- continue;
- }
+ for (SourceInfo &si : sources) {
+ if (si.ignored)
+ continue;
+ Summary summary(si.displayName);
+ collectSource(si, summary);
+
+ // Print file summary unless -t is specified.
+ std::string gcovName = getCoveragePath(si.filename, filename);
+ if (!options.UseStdout) {
+ os << "File '" << summary.Name << "'\n";
+ printSummary(summary, os);
+ if (!options.NoOutput && !options.Intermediate)
+ os << "Creating '" << gcovName << "'\n";
+ os << '\n';
}
- annotateSource(si, file, gcno, gcda,
- options.UseStdout ? llvm::outs() : *os);
+
+ if (options.NoOutput || options.Intermediate)
+ continue;
+ Optional<raw_fd_ostream> os;
+ if (!options.UseStdout) {
+ std::error_code ec;
+ os.emplace(gcovName, ec, sys::fs::OF_Text);
+ if (ec) {
+ errs() << ec.message() << '\n';
+ continue;
+ }
+ }
+ annotateSource(si, file, gcno, gcda,
+ options.UseStdout ? llvm::outs() : *os);
+ }
+
+ if (options.Intermediate && !options.NoOutput) {
+ // gcov 7.* unexpectedly create multiple .gcov files, which was fixed in 8.0
+ // (PR GCC/82702). We create just one file.
+ std::string outputPath(sys::path::filename(filename));
+ std::error_code ec;
+ raw_fd_ostream os(outputPath + ".gcov", ec, sys::fs::OF_Text);
+ if (ec) {
+ errs() << ec.message() << '\n';
+ return;
+ }
+
+ for (const SourceInfo &si : sources)
+ printSourceToIntermediate(si, os);
}
+}
- if (options.Intermediate && !options.NoOutput) {
- // gcov 7.* unexpectedly create multiple .gcov files, which was fixed in 8.0
- // (PR GCC/82702). We create just one file.
- std::string outputPath(sys::path::filename(filename));
- std::error_code ec;
- raw_fd_ostream os(outputPath + ".gcov", ec, sys::fs::OF_Text);
- if (ec) {
- errs() << ec.message() << '\n';
- return;
- }
-
- for (const SourceInfo &si : sources)
- printSourceToIntermediate(si, os);
- }
+void Context::printFunctionDetails(const GCOVFunction &f,
+ raw_ostream &os) const {
+ const uint64_t entryCount = f.getEntryCount();
+ uint32_t blocksExec = 0;
+ const GCOVBlock &exitBlock = f.getExitBlock();
+ uint64_t exitCount = 0;
+ for (const GCOVArc *arc : exitBlock.pred)
+ exitCount += arc->count;
+ for (const GCOVBlock &b : f.blocksRange())
+ if (b.number != 0 && &b != &exitBlock && b.getCount())
+ ++blocksExec;
+
+ os << "function " << f.getName(options.Demangle) << " called " << entryCount
+ << " returned " << formatPercentage(exitCount, entryCount)
+ << "% blocks executed "
+ << formatPercentage(blocksExec, f.blocks.size() - 2) << "%\n";
}
-void Context::printFunctionDetails(const GCOVFunction &f,
- raw_ostream &os) const {
- const uint64_t entryCount = f.getEntryCount();
- uint32_t blocksExec = 0;
- const GCOVBlock &exitBlock = f.getExitBlock();
- uint64_t exitCount = 0;
- for (const GCOVArc *arc : exitBlock.pred)
- exitCount += arc->count;
- for (const GCOVBlock &b : f.blocksRange())
- if (b.number != 0 && &b != &exitBlock && b.getCount())
- ++blocksExec;
-
- os << "function " << f.getName(options.Demangle) << " called " << entryCount
- << " returned " << formatPercentage(exitCount, entryCount)
- << "% blocks executed "
- << formatPercentage(blocksExec, f.blocks.size() - 2) << "%\n";
+/// printBranchInfo - Print conditional branch probabilities.
+void Context::printBranchInfo(const GCOVBlock &Block, uint32_t &edgeIdx,
+ raw_ostream &os) const {
+ uint64_t total = 0;
+ for (const GCOVArc *arc : Block.dsts())
+ total += arc->count;
+ for (const GCOVArc *arc : Block.dsts())
+ os << format("branch %2u ", edgeIdx++)
+ << formatBranchInfo(options, arc->count, total) << '\n';
}
-/// printBranchInfo - Print conditional branch probabilities.
-void Context::printBranchInfo(const GCOVBlock &Block, uint32_t &edgeIdx,
- raw_ostream &os) const {
- uint64_t total = 0;
- for (const GCOVArc *arc : Block.dsts())
- total += arc->count;
- for (const GCOVArc *arc : Block.dsts())
- os << format("branch %2u ", edgeIdx++)
- << formatBranchInfo(options, arc->count, total) << '\n';
-}
-
-void Context::printSummary(const Summary &summary, raw_ostream &os) const {
- os << format("Lines executed:%.2f%% of %" PRIu64 "\n",
- double(summary.linesExec) * 100 / summary.lines, summary.lines);
- if (options.BranchInfo) {
- if (summary.branches == 0) {
- os << "No branches\n";
+void Context::printSummary(const Summary &summary, raw_ostream &os) const {
+ os << format("Lines executed:%.2f%% of %" PRIu64 "\n",
+ double(summary.linesExec) * 100 / summary.lines, summary.lines);
+ if (options.BranchInfo) {
+ if (summary.branches == 0) {
+ os << "No branches\n";
} else {
- os << format("Branches executed:%.2f%% of %" PRIu64 "\n",
- double(summary.branchesExec) * 100 / summary.branches,
- summary.branches);
- os << format("Taken at least once:%.2f%% of %" PRIu64 "\n",
- double(summary.branchesTaken) * 100 / summary.branches,
- summary.branches);
+ os << format("Branches executed:%.2f%% of %" PRIu64 "\n",
+ double(summary.branchesExec) * 100 / summary.branches,
+ summary.branches);
+ os << format("Taken at least once:%.2f%% of %" PRIu64 "\n",
+ double(summary.branchesTaken) * 100 / summary.branches,
+ summary.branches);
}
- os << "No calls\n";
+ os << "No calls\n";
}
}
-void llvm::gcovOneInput(const GCOV::Options &options, StringRef filename,
- StringRef gcno, StringRef gcda, GCOVFile &file) {
- Context fi(options);
- fi.print(filename, gcno, gcda, file);
+void llvm::gcovOneInput(const GCOV::Options &options, StringRef filename,
+ StringRef gcno, StringRef gcda, GCOVFile &file) {
+ Context fi(options);
+ fi.print(filename, gcno, gcda, file);
}
diff --git a/contrib/libs/llvm12/lib/ProfileData/InstrProf.cpp b/contrib/libs/llvm12/lib/ProfileData/InstrProf.cpp
index 167ce44cc4..4a0cee6708 100644
--- a/contrib/libs/llvm12/lib/ProfileData/InstrProf.cpp
+++ b/contrib/libs/llvm12/lib/ProfileData/InstrProf.cpp
@@ -625,11 +625,11 @@ void InstrProfValueSiteRecord::merge(InstrProfValueSiteRecord &Input,
}
}
-void InstrProfValueSiteRecord::scale(uint64_t N, uint64_t D,
+void InstrProfValueSiteRecord::scale(uint64_t N, uint64_t D,
function_ref<void(instrprof_error)> Warn) {
for (auto I = ValueData.begin(), IE = ValueData.end(); I != IE; ++I) {
bool Overflowed;
- I->Count = SaturatingMultiply(I->Count, N, &Overflowed) / D;
+ I->Count = SaturatingMultiply(I->Count, N, &Overflowed) / D;
if (Overflowed)
Warn(instrprof_error::counter_overflow);
}
@@ -678,23 +678,23 @@ void InstrProfRecord::merge(InstrProfRecord &Other, uint64_t Weight,
}
void InstrProfRecord::scaleValueProfData(
- uint32_t ValueKind, uint64_t N, uint64_t D,
+ uint32_t ValueKind, uint64_t N, uint64_t D,
function_ref<void(instrprof_error)> Warn) {
for (auto &R : getValueSitesForKind(ValueKind))
- R.scale(N, D, Warn);
+ R.scale(N, D, Warn);
}
-void InstrProfRecord::scale(uint64_t N, uint64_t D,
+void InstrProfRecord::scale(uint64_t N, uint64_t D,
function_ref<void(instrprof_error)> Warn) {
- assert(D != 0 && "D cannot be 0");
+ assert(D != 0 && "D cannot be 0");
for (auto &Count : this->Counts) {
bool Overflowed;
- Count = SaturatingMultiply(Count, N, &Overflowed) / D;
+ Count = SaturatingMultiply(Count, N, &Overflowed) / D;
if (Overflowed)
Warn(instrprof_error::counter_overflow);
}
for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
- scaleValueProfData(Kind, N, D, Warn);
+ scaleValueProfData(Kind, N, D, Warn);
}
// Map indirect call target name hash to name string.
@@ -1114,15 +1114,15 @@ bool canRenameComdatFunc(const Function &F, bool CheckAddressTaken) {
// Create a COMDAT variable INSTR_PROF_RAW_VERSION_VAR to make the runtime
// aware this is an ir_level profile so it can set the version flag.
-void createIRLevelProfileFlagVar(Module &M, bool IsCS,
- bool InstrEntryBBEnabled) {
+void createIRLevelProfileFlagVar(Module &M, bool IsCS,
+ bool InstrEntryBBEnabled) {
const StringRef VarName(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR));
Type *IntTy64 = Type::getInt64Ty(M.getContext());
uint64_t ProfileVersion = (INSTR_PROF_RAW_VERSION | VARIANT_MASK_IR_PROF);
if (IsCS)
ProfileVersion |= VARIANT_MASK_CSIR_PROF;
- if (InstrEntryBBEnabled)
- ProfileVersion |= VARIANT_MASK_INSTR_ENTRY;
+ if (InstrEntryBBEnabled)
+ ProfileVersion |= VARIANT_MASK_INSTR_ENTRY;
auto IRLevelVersionVariable = new GlobalVariable(
M, IntTy64, true, GlobalValue::WeakAnyLinkage,
Constant::getIntegerValue(IntTy64, APInt(64, ProfileVersion)), VarName);
diff --git a/contrib/libs/llvm12/lib/ProfileData/InstrProfReader.cpp b/contrib/libs/llvm12/lib/ProfileData/InstrProfReader.cpp
index 665df44249..9581e5b486 100644
--- a/contrib/libs/llvm12/lib/ProfileData/InstrProfReader.cpp
+++ b/contrib/libs/llvm12/lib/ProfileData/InstrProfReader.cpp
@@ -154,29 +154,29 @@ bool TextInstrProfReader::hasFormat(const MemoryBuffer &Buffer) {
Error TextInstrProfReader::readHeader() {
Symtab.reset(new InstrProfSymtab());
bool IsIRInstr = false;
- bool IsEntryFirst = false;
- bool IsCS = false;
-
- while (Line->startswith(":")) {
- StringRef Str = Line->substr(1);
- if (Str.equals_lower("ir"))
- IsIRInstr = true;
- else if (Str.equals_lower("fe"))
- IsIRInstr = false;
- else if (Str.equals_lower("csir")) {
- IsIRInstr = true;
- IsCS = true;
- } else if (Str.equals_lower("entry_first"))
- IsEntryFirst = true;
- else if (Str.equals_lower("not_entry_first"))
- IsEntryFirst = false;
- else
- return error(instrprof_error::bad_header);
- ++Line;
+ bool IsEntryFirst = false;
+ bool IsCS = false;
+
+ while (Line->startswith(":")) {
+ StringRef Str = Line->substr(1);
+ if (Str.equals_lower("ir"))
+ IsIRInstr = true;
+ else if (Str.equals_lower("fe"))
+ IsIRInstr = false;
+ else if (Str.equals_lower("csir")) {
+ IsIRInstr = true;
+ IsCS = true;
+ } else if (Str.equals_lower("entry_first"))
+ IsEntryFirst = true;
+ else if (Str.equals_lower("not_entry_first"))
+ IsEntryFirst = false;
+ else
+ return error(instrprof_error::bad_header);
+ ++Line;
}
IsIRLevelProfile = IsIRInstr;
- InstrEntryBBEnabled = IsEntryFirst;
- HasCSIRLevelProfile = IsCS;
+ InstrEntryBBEnabled = IsEntryFirst;
+ HasCSIRLevelProfile = IsCS;
return success();
}
diff --git a/contrib/libs/llvm12/lib/ProfileData/InstrProfWriter.cpp b/contrib/libs/llvm12/lib/ProfileData/InstrProfWriter.cpp
index aa1fe31ccc..d076683223 100644
--- a/contrib/libs/llvm12/lib/ProfileData/InstrProfWriter.cpp
+++ b/contrib/libs/llvm12/lib/ProfileData/InstrProfWriter.cpp
@@ -165,9 +165,9 @@ public:
} // end namespace llvm
-InstrProfWriter::InstrProfWriter(bool Sparse, bool InstrEntryBBEnabled)
- : Sparse(Sparse), InstrEntryBBEnabled(InstrEntryBBEnabled),
- InfoObj(new InstrProfRecordWriterTrait()) {}
+InstrProfWriter::InstrProfWriter(bool Sparse, bool InstrEntryBBEnabled)
+ : Sparse(Sparse), InstrEntryBBEnabled(InstrEntryBBEnabled),
+ InfoObj(new InstrProfRecordWriterTrait()) {}
InstrProfWriter::~InstrProfWriter() { delete InfoObj; }
@@ -241,7 +241,7 @@ void InstrProfWriter::addRecord(StringRef Name, uint64_t Hash,
// We've never seen a function with this name and hash, add it.
Dest = std::move(I);
if (Weight > 1)
- Dest.scale(Weight, 1, MapWarn);
+ Dest.scale(Weight, 1, MapWarn);
} else {
// We're updating a function we've seen before.
Dest.merge(I, Weight, MapWarn);
@@ -309,9 +309,9 @@ void InstrProfWriter::writeImpl(ProfOStream &OS) {
Header.Version |= VARIANT_MASK_IR_PROF;
Header.Version |= VARIANT_MASK_CSIR_PROF;
}
- if (InstrEntryBBEnabled)
- Header.Version |= VARIANT_MASK_INSTR_ENTRY;
-
+ if (InstrEntryBBEnabled)
+ Header.Version |= VARIANT_MASK_INSTR_ENTRY;
+
Header.Unused = 0;
Header.HashType = static_cast<uint64_t>(IndexedInstrProf::HashType);
Header.HashOffset = 0;
@@ -445,8 +445,8 @@ Error InstrProfWriter::writeText(raw_fd_ostream &OS) {
OS << "# IR level Instrumentation Flag\n:ir\n";
else if (ProfileKind == PF_IRLevelWithCS)
OS << "# CSIR level Instrumentation Flag\n:csir\n";
- if (InstrEntryBBEnabled)
- OS << "# Always instrument the function entry block\n:entry_first\n";
+ if (InstrEntryBBEnabled)
+ OS << "# Always instrument the function entry block\n:entry_first\n";
InstrProfSymtab Symtab;
using FuncPair = detail::DenseMapPair<uint64_t, InstrProfRecord>;
diff --git a/contrib/libs/llvm12/lib/ProfileData/ProfileSummaryBuilder.cpp b/contrib/libs/llvm12/lib/ProfileData/ProfileSummaryBuilder.cpp
index 0f1e6d1a65..0e03aa5017 100644
--- a/contrib/libs/llvm12/lib/ProfileData/ProfileSummaryBuilder.cpp
+++ b/contrib/libs/llvm12/lib/ProfileData/ProfileSummaryBuilder.cpp
@@ -18,14 +18,14 @@
#include "llvm/ProfileData/ProfileCommon.h"
#include "llvm/ProfileData/SampleProf.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/CommandLine.h"
using namespace llvm;
-cl::opt<bool> UseContextLessSummary(
- "profile-summary-contextless", cl::Hidden, cl::init(false), cl::ZeroOrMore,
- cl::desc("Merge context profiles before calculating thresholds."));
-
+cl::opt<bool> UseContextLessSummary(
+ "profile-summary-contextless", cl::Hidden, cl::init(false), cl::ZeroOrMore,
+ cl::desc("Merge context profiles before calculating thresholds."));
+
// A set of cutoff values. Each value, when divided by ProfileSummary::Scale
// (which is 1000000) is a desired percentile of total counts.
static const uint32_t DefaultCutoffsData[] = {
@@ -116,35 +116,35 @@ std::unique_ptr<ProfileSummary> SampleProfileSummaryBuilder::getSummary() {
MaxFunctionCount, NumCounts, NumFunctions);
}
-std::unique_ptr<ProfileSummary>
-SampleProfileSummaryBuilder::computeSummaryForProfiles(
- const StringMap<sampleprof::FunctionSamples> &Profiles) {
- assert(NumFunctions == 0 &&
- "This can only be called on an empty summary builder");
- StringMap<sampleprof::FunctionSamples> ContextLessProfiles;
- const StringMap<sampleprof::FunctionSamples> *ProfilesToUse = &Profiles;
- // For CSSPGO, context-sensitive profile effectively split a function profile
- // into many copies each representing the CFG profile of a particular calling
- // context. That makes the count distribution looks more flat as we now have
- // more function profiles each with lower counts, which in turn leads to lower
- // hot thresholds. To compensate for that, by defauly we merge context
- // profiles before coumputing profile summary.
- if (UseContextLessSummary || (sampleprof::FunctionSamples::ProfileIsCS &&
- !UseContextLessSummary.getNumOccurrences())) {
- for (const auto &I : Profiles) {
- ContextLessProfiles[I.second.getName()].merge(I.second);
- }
- ProfilesToUse = &ContextLessProfiles;
- }
-
- for (const auto &I : *ProfilesToUse) {
- const sampleprof::FunctionSamples &Profile = I.second;
- addRecord(Profile);
- }
-
- return getSummary();
-}
-
+std::unique_ptr<ProfileSummary>
+SampleProfileSummaryBuilder::computeSummaryForProfiles(
+ const StringMap<sampleprof::FunctionSamples> &Profiles) {
+ assert(NumFunctions == 0 &&
+ "This can only be called on an empty summary builder");
+ StringMap<sampleprof::FunctionSamples> ContextLessProfiles;
+ const StringMap<sampleprof::FunctionSamples> *ProfilesToUse = &Profiles;
+ // For CSSPGO, context-sensitive profile effectively split a function profile
+ // into many copies each representing the CFG profile of a particular calling
+ // context. That makes the count distribution looks more flat as we now have
+ // more function profiles each with lower counts, which in turn leads to lower
+ // hot thresholds. To compensate for that, by defauly we merge context
+ // profiles before coumputing profile summary.
+ if (UseContextLessSummary || (sampleprof::FunctionSamples::ProfileIsCS &&
+ !UseContextLessSummary.getNumOccurrences())) {
+ for (const auto &I : Profiles) {
+ ContextLessProfiles[I.second.getName()].merge(I.second);
+ }
+ ProfilesToUse = &ContextLessProfiles;
+ }
+
+ for (const auto &I : *ProfilesToUse) {
+ const sampleprof::FunctionSamples &Profile = I.second;
+ addRecord(Profile);
+ }
+
+ return getSummary();
+}
+
std::unique_ptr<ProfileSummary> InstrProfSummaryBuilder::getSummary() {
computeDetailedSummary();
return std::make_unique<ProfileSummary>(
@@ -153,22 +153,22 @@ std::unique_ptr<ProfileSummary> InstrProfSummaryBuilder::getSummary() {
}
void InstrProfSummaryBuilder::addEntryCount(uint64_t Count) {
- NumFunctions++;
-
- // Skip invalid count.
- if (Count == (uint64_t)-1)
- return;
-
+ NumFunctions++;
+
+ // Skip invalid count.
+ if (Count == (uint64_t)-1)
+ return;
+
addCount(Count);
if (Count > MaxFunctionCount)
MaxFunctionCount = Count;
}
void InstrProfSummaryBuilder::addInternalCount(uint64_t Count) {
- // Skip invalid count.
- if (Count == (uint64_t)-1)
- return;
-
+ // Skip invalid count.
+ if (Count == (uint64_t)-1)
+ return;
+
addCount(Count);
if (Count > MaxInternalBlockCount)
MaxInternalBlockCount = Count;
diff --git a/contrib/libs/llvm12/lib/ProfileData/SampleProf.cpp b/contrib/libs/llvm12/lib/ProfileData/SampleProf.cpp
index 669976d795..d6acc00e1a 100644
--- a/contrib/libs/llvm12/lib/ProfileData/SampleProf.cpp
+++ b/contrib/libs/llvm12/lib/ProfileData/SampleProf.cpp
@@ -14,8 +14,8 @@
#include "llvm/ProfileData/SampleProf.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/PseudoProbe.h"
-#include "llvm/ProfileData/SampleProfReader.h"
+#include "llvm/IR/PseudoProbe.h"
+#include "llvm/ProfileData/SampleProfReader.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Error.h"
@@ -32,8 +32,8 @@ using namespace sampleprof;
namespace llvm {
namespace sampleprof {
SampleProfileFormat FunctionSamples::Format;
-bool FunctionSamples::ProfileIsProbeBased = false;
-bool FunctionSamples::ProfileIsCS = false;
+bool FunctionSamples::ProfileIsProbeBased = false;
+bool FunctionSamples::ProfileIsCS = false;
bool FunctionSamples::UseMD5;
} // namespace sampleprof
} // namespace llvm
@@ -79,8 +79,8 @@ class SampleProfErrorCategoryType : public std::error_category {
return "Uncompress failure";
case sampleprof_error::zlib_unavailable:
return "Zlib is unavailable";
- case sampleprof_error::hash_mismatch:
- return "Function hash mismatch";
+ case sampleprof_error::hash_mismatch:
+ return "Function hash mismatch";
}
llvm_unreachable("A value of sampleprof_error has no message.");
}
@@ -133,9 +133,9 @@ raw_ostream &llvm::sampleprof::operator<<(raw_ostream &OS,
/// Print the samples collected for a function on stream \p OS.
void FunctionSamples::print(raw_ostream &OS, unsigned Indent) const {
- if (getFunctionHash())
- OS << "CFG checksum " << getFunctionHash() << "\n";
-
+ if (getFunctionHash())
+ OS << "CFG checksum " << getFunctionHash() << "\n";
+
OS << TotalSamples << ", " << TotalHeadSamples << ", " << BodySamples.size()
<< " sampled lines\n";
@@ -183,22 +183,22 @@ unsigned FunctionSamples::getOffset(const DILocation *DIL) {
0xffff;
}
-LineLocation FunctionSamples::getCallSiteIdentifier(const DILocation *DIL) {
- if (FunctionSamples::ProfileIsProbeBased)
- // In a pseudo-probe based profile, a callsite is simply represented by the
- // ID of the probe associated with the call instruction. The probe ID is
- // encoded in the Discriminator field of the call instruction's debug
- // metadata.
- return LineLocation(PseudoProbeDwarfDiscriminator::extractProbeIndex(
- DIL->getDiscriminator()),
- 0);
- else
- return LineLocation(FunctionSamples::getOffset(DIL),
- DIL->getBaseDiscriminator());
-}
-
-const FunctionSamples *FunctionSamples::findFunctionSamples(
- const DILocation *DIL, SampleProfileReaderItaniumRemapper *Remapper) const {
+LineLocation FunctionSamples::getCallSiteIdentifier(const DILocation *DIL) {
+ if (FunctionSamples::ProfileIsProbeBased)
+ // In a pseudo-probe based profile, a callsite is simply represented by the
+ // ID of the probe associated with the call instruction. The probe ID is
+ // encoded in the Discriminator field of the call instruction's debug
+ // metadata.
+ return LineLocation(PseudoProbeDwarfDiscriminator::extractProbeIndex(
+ DIL->getDiscriminator()),
+ 0);
+ else
+ return LineLocation(FunctionSamples::getOffset(DIL),
+ DIL->getBaseDiscriminator());
+}
+
+const FunctionSamples *FunctionSamples::findFunctionSamples(
+ const DILocation *DIL, SampleProfileReaderItaniumRemapper *Remapper) const {
assert(DIL);
SmallVector<std::pair<LineLocation, StringRef>, 10> S;
@@ -213,59 +213,59 @@ const FunctionSamples *FunctionSamples::findFunctionSamples(
return this;
const FunctionSamples *FS = this;
for (int i = S.size() - 1; i >= 0 && FS != nullptr; i--) {
- FS = FS->findFunctionSamplesAt(S[i].first, S[i].second, Remapper);
+ FS = FS->findFunctionSamplesAt(S[i].first, S[i].second, Remapper);
}
return FS;
}
-void FunctionSamples::findAllNames(DenseSet<StringRef> &NameSet) const {
- NameSet.insert(Name);
- for (const auto &BS : BodySamples)
- for (const auto &TS : BS.second.getCallTargets())
- NameSet.insert(TS.getKey());
-
- for (const auto &CS : CallsiteSamples) {
- for (const auto &NameFS : CS.second) {
- NameSet.insert(NameFS.first);
- NameFS.second.findAllNames(NameSet);
- }
- }
-}
-
-const FunctionSamples *FunctionSamples::findFunctionSamplesAt(
- const LineLocation &Loc, StringRef CalleeName,
- SampleProfileReaderItaniumRemapper *Remapper) const {
- std::string CalleeGUID;
- CalleeName = getRepInFormat(CalleeName, UseMD5, CalleeGUID);
-
- auto iter = CallsiteSamples.find(Loc);
- if (iter == CallsiteSamples.end())
- return nullptr;
- auto FS = iter->second.find(CalleeName);
- if (FS != iter->second.end())
- return &FS->second;
- if (Remapper) {
- if (auto NameInProfile = Remapper->lookUpNameInProfile(CalleeName)) {
- auto FS = iter->second.find(*NameInProfile);
- if (FS != iter->second.end())
- return &FS->second;
- }
- }
- // If we cannot find exact match of the callee name, return the FS with
- // the max total count. Only do this when CalleeName is not provided,
- // i.e., only for indirect calls.
- if (!CalleeName.empty())
- return nullptr;
- uint64_t MaxTotalSamples = 0;
- const FunctionSamples *R = nullptr;
- for (const auto &NameFS : iter->second)
- if (NameFS.second.getTotalSamples() >= MaxTotalSamples) {
- MaxTotalSamples = NameFS.second.getTotalSamples();
- R = &NameFS.second;
- }
- return R;
-}
-
+void FunctionSamples::findAllNames(DenseSet<StringRef> &NameSet) const {
+ NameSet.insert(Name);
+ for (const auto &BS : BodySamples)
+ for (const auto &TS : BS.second.getCallTargets())
+ NameSet.insert(TS.getKey());
+
+ for (const auto &CS : CallsiteSamples) {
+ for (const auto &NameFS : CS.second) {
+ NameSet.insert(NameFS.first);
+ NameFS.second.findAllNames(NameSet);
+ }
+ }
+}
+
+const FunctionSamples *FunctionSamples::findFunctionSamplesAt(
+ const LineLocation &Loc, StringRef CalleeName,
+ SampleProfileReaderItaniumRemapper *Remapper) const {
+ std::string CalleeGUID;
+ CalleeName = getRepInFormat(CalleeName, UseMD5, CalleeGUID);
+
+ auto iter = CallsiteSamples.find(Loc);
+ if (iter == CallsiteSamples.end())
+ return nullptr;
+ auto FS = iter->second.find(CalleeName);
+ if (FS != iter->second.end())
+ return &FS->second;
+ if (Remapper) {
+ if (auto NameInProfile = Remapper->lookUpNameInProfile(CalleeName)) {
+ auto FS = iter->second.find(*NameInProfile);
+ if (FS != iter->second.end())
+ return &FS->second;
+ }
+ }
+ // If we cannot find exact match of the callee name, return the FS with
+ // the max total count. Only do this when CalleeName is not provided,
+ // i.e., only for indirect calls.
+ if (!CalleeName.empty())
+ return nullptr;
+ uint64_t MaxTotalSamples = 0;
+ const FunctionSamples *R = nullptr;
+ for (const auto &NameFS : iter->second)
+ if (NameFS.second.getTotalSamples() >= MaxTotalSamples) {
+ MaxTotalSamples = NameFS.second.getTotalSamples();
+ R = &NameFS.second;
+ }
+ return R;
+}
+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void FunctionSamples::dump() const { print(dbgs(), 0); }
#endif
@@ -287,7 +287,7 @@ std::error_code ProfileSymbolList::read(const uint8_t *Data,
std::error_code ProfileSymbolList::write(raw_ostream &OS) {
// Sort the symbols before output. If doing compression.
// It will make the compression much more effective.
- std::vector<StringRef> SortedList(Syms.begin(), Syms.end());
+ std::vector<StringRef> SortedList(Syms.begin(), Syms.end());
llvm::sort(SortedList);
std::string OutputString;
@@ -302,7 +302,7 @@ std::error_code ProfileSymbolList::write(raw_ostream &OS) {
void ProfileSymbolList::dump(raw_ostream &OS) const {
OS << "======== Dump profile symbol list ========\n";
- std::vector<StringRef> SortedList(Syms.begin(), Syms.end());
+ std::vector<StringRef> SortedList(Syms.begin(), Syms.end());
llvm::sort(SortedList);
for (auto &Sym : SortedList)
diff --git a/contrib/libs/llvm12/lib/ProfileData/SampleProfReader.cpp b/contrib/libs/llvm12/lib/ProfileData/SampleProfReader.cpp
index ba9d456097..38cbca844c 100644
--- a/contrib/libs/llvm12/lib/ProfileData/SampleProfReader.cpp
+++ b/contrib/libs/llvm12/lib/ProfileData/SampleProfReader.cpp
@@ -83,52 +83,52 @@ static bool ParseHead(const StringRef &Input, StringRef &FName,
/// Returns true if line offset \p L is legal (only has 16 bits).
static bool isOffsetLegal(unsigned L) { return (L & 0xffff) == L; }
-/// Parse \p Input that contains metadata.
-/// Possible metadata:
-/// - CFG Checksum information:
-/// !CFGChecksum: 12345
-/// Stores the FunctionHash (a.k.a. CFG Checksum) into \p FunctionHash.
-static bool parseMetadata(const StringRef &Input, uint64_t &FunctionHash) {
- if (!Input.startswith("!CFGChecksum:"))
- return false;
-
- StringRef CFGInfo = Input.substr(strlen("!CFGChecksum:")).trim();
- return !CFGInfo.getAsInteger(10, FunctionHash);
-}
-
-enum class LineType {
- CallSiteProfile,
- BodyProfile,
- Metadata,
-};
-
+/// Parse \p Input that contains metadata.
+/// Possible metadata:
+/// - CFG Checksum information:
+/// !CFGChecksum: 12345
+/// Stores the FunctionHash (a.k.a. CFG Checksum) into \p FunctionHash.
+static bool parseMetadata(const StringRef &Input, uint64_t &FunctionHash) {
+ if (!Input.startswith("!CFGChecksum:"))
+ return false;
+
+ StringRef CFGInfo = Input.substr(strlen("!CFGChecksum:")).trim();
+ return !CFGInfo.getAsInteger(10, FunctionHash);
+}
+
+enum class LineType {
+ CallSiteProfile,
+ BodyProfile,
+ Metadata,
+};
+
/// Parse \p Input as line sample.
///
/// \param Input input line.
-/// \param LineTy Type of this line.
+/// \param LineTy Type of this line.
/// \param Depth the depth of the inline stack.
/// \param NumSamples total samples of the line/inlined callsite.
/// \param LineOffset line offset to the start of the function.
/// \param Discriminator discriminator of the line.
/// \param TargetCountMap map from indirect call target to count.
-/// \param FunctionHash the function's CFG hash, used by pseudo probe.
+/// \param FunctionHash the function's CFG hash, used by pseudo probe.
///
/// returns true if parsing is successful.
-static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth,
+static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth,
uint64_t &NumSamples, uint32_t &LineOffset,
uint32_t &Discriminator, StringRef &CalleeName,
- DenseMap<StringRef, uint64_t> &TargetCountMap,
- uint64_t &FunctionHash) {
+ DenseMap<StringRef, uint64_t> &TargetCountMap,
+ uint64_t &FunctionHash) {
for (Depth = 0; Input[Depth] == ' '; Depth++)
;
if (Depth == 0)
return false;
- if (Depth == 1 && Input[Depth] == '!') {
- LineTy = LineType::Metadata;
- return parseMetadata(Input.substr(Depth), FunctionHash);
- }
-
+ if (Depth == 1 && Input[Depth] == '!') {
+ LineTy = LineType::Metadata;
+ return parseMetadata(Input.substr(Depth), FunctionHash);
+ }
+
size_t n1 = Input.find(':');
StringRef Loc = Input.substr(Depth, n1 - Depth);
size_t n2 = Loc.find('.');
@@ -144,8 +144,8 @@ static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth,
}
StringRef Rest = Input.substr(n1 + 2);
- if (isDigit(Rest[0])) {
- LineTy = LineType::BodyProfile;
+ if (isDigit(Rest[0])) {
+ LineTy = LineType::BodyProfile;
size_t n3 = Rest.find(' ');
if (n3 == StringRef::npos) {
if (Rest.getAsInteger(10, NumSamples))
@@ -202,7 +202,7 @@ static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth,
n3 = n4;
}
} else {
- LineTy = LineType::CallSiteProfile;
+ LineTy = LineType::CallSiteProfile;
size_t n3 = Rest.find_last_of(':');
CalleeName = Rest.substr(0, n3);
if (Rest.substr(n3 + 1).getAsInteger(10, NumSamples))
@@ -222,12 +222,12 @@ std::error_code SampleProfileReaderText::readImpl() {
sampleprof_error Result = sampleprof_error::success;
InlineCallStack InlineStack;
- uint32_t ProbeProfileCount = 0;
+ uint32_t ProbeProfileCount = 0;
+
+ // SeenMetadata tracks whether we have processed metadata for the current
+ // top-level function profile.
+ bool SeenMetadata = false;
- // SeenMetadata tracks whether we have processed metadata for the current
- // top-level function profile.
- bool SeenMetadata = false;
-
for (; !LineIt.is_at_eof(); ++LineIt) {
if ((*LineIt)[(*LineIt).find_first_not_of(' ')] == '#')
continue;
@@ -251,14 +251,14 @@ std::error_code SampleProfileReaderText::readImpl() {
"Expected 'mangled_name:NUM:NUM', found " + *LineIt);
return sampleprof_error::malformed;
}
- SeenMetadata = false;
- SampleContext FContext(FName);
- if (FContext.hasContext())
- ++CSProfileCount;
- Profiles[FContext] = FunctionSamples();
- FunctionSamples &FProfile = Profiles[FContext];
- FProfile.setName(FContext.getNameWithoutContext());
- FProfile.setContext(FContext);
+ SeenMetadata = false;
+ SampleContext FContext(FName);
+ if (FContext.hasContext())
+ ++CSProfileCount;
+ Profiles[FContext] = FunctionSamples();
+ FunctionSamples &FProfile = Profiles[FContext];
+ FProfile.setName(FContext.getNameWithoutContext());
+ FProfile.setContext(FContext);
MergeResult(Result, FProfile.addTotalSamples(NumSamples));
MergeResult(Result, FProfile.addHeadSamples(NumHeadSamples));
InlineStack.clear();
@@ -268,34 +268,34 @@ std::error_code SampleProfileReaderText::readImpl() {
StringRef FName;
DenseMap<StringRef, uint64_t> TargetCountMap;
uint32_t Depth, LineOffset, Discriminator;
- LineType LineTy;
- uint64_t FunctionHash;
- if (!ParseLine(*LineIt, LineTy, Depth, NumSamples, LineOffset,
- Discriminator, FName, TargetCountMap, FunctionHash)) {
+ LineType LineTy;
+ uint64_t FunctionHash;
+ if (!ParseLine(*LineIt, LineTy, Depth, NumSamples, LineOffset,
+ Discriminator, FName, TargetCountMap, FunctionHash)) {
reportError(LineIt.line_number(),
"Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found " +
*LineIt);
return sampleprof_error::malformed;
}
- if (SeenMetadata && LineTy != LineType::Metadata) {
- // Metadata must be put at the end of a function profile.
- reportError(LineIt.line_number(),
- "Found non-metadata after metadata: " + *LineIt);
- return sampleprof_error::malformed;
- }
- while (InlineStack.size() > Depth) {
- InlineStack.pop_back();
- }
- switch (LineTy) {
- case LineType::CallSiteProfile: {
+ if (SeenMetadata && LineTy != LineType::Metadata) {
+ // Metadata must be put at the end of a function profile.
+ reportError(LineIt.line_number(),
+ "Found non-metadata after metadata: " + *LineIt);
+ return sampleprof_error::malformed;
+ }
+ while (InlineStack.size() > Depth) {
+ InlineStack.pop_back();
+ }
+ switch (LineTy) {
+ case LineType::CallSiteProfile: {
FunctionSamples &FSamples = InlineStack.back()->functionSamplesAt(
LineLocation(LineOffset, Discriminator))[std::string(FName)];
FSamples.setName(FName);
MergeResult(Result, FSamples.addTotalSamples(NumSamples));
InlineStack.push_back(&FSamples);
- break;
- }
- case LineType::BodyProfile: {
+ break;
+ }
+ case LineType::BodyProfile: {
while (InlineStack.size() > Depth) {
InlineStack.pop_back();
}
@@ -307,28 +307,28 @@ std::error_code SampleProfileReaderText::readImpl() {
}
MergeResult(Result, FProfile.addBodySamples(LineOffset, Discriminator,
NumSamples));
- break;
+ break;
+ }
+ case LineType::Metadata: {
+ FunctionSamples &FProfile = *InlineStack.back();
+ FProfile.setFunctionHash(FunctionHash);
+ ++ProbeProfileCount;
+ SeenMetadata = true;
+ break;
+ }
}
- case LineType::Metadata: {
- FunctionSamples &FProfile = *InlineStack.back();
- FProfile.setFunctionHash(FunctionHash);
- ++ProbeProfileCount;
- SeenMetadata = true;
- break;
- }
- }
}
}
-
- assert((CSProfileCount == 0 || CSProfileCount == Profiles.size()) &&
- "Cannot have both context-sensitive and regular profile");
- ProfileIsCS = (CSProfileCount > 0);
- assert((ProbeProfileCount == 0 || ProbeProfileCount == Profiles.size()) &&
- "Cannot have both probe-based profiles and regular profiles");
- ProfileIsProbeBased = (ProbeProfileCount > 0);
- FunctionSamples::ProfileIsProbeBased = ProfileIsProbeBased;
- FunctionSamples::ProfileIsCS = ProfileIsCS;
-
+
+ assert((CSProfileCount == 0 || CSProfileCount == Profiles.size()) &&
+ "Cannot have both context-sensitive and regular profile");
+ ProfileIsCS = (CSProfileCount > 0);
+ assert((ProbeProfileCount == 0 || ProbeProfileCount == Profiles.size()) &&
+ "Cannot have both probe-based profiles and regular profiles");
+ ProfileIsProbeBased = (ProbeProfileCount > 0);
+ FunctionSamples::ProfileIsProbeBased = ProfileIsProbeBased;
+ FunctionSamples::ProfileIsCS = ProfileIsCS;
+
if (Result == sampleprof_error::success)
computeSummary();
@@ -419,34 +419,34 @@ ErrorOr<StringRef> SampleProfileReaderBinary::readStringFromTable() {
return NameTable[*Idx];
}
-ErrorOr<StringRef> SampleProfileReaderExtBinaryBase::readStringFromTable() {
- if (!FixedLengthMD5)
- return SampleProfileReaderBinary::readStringFromTable();
-
- // read NameTable index.
- auto Idx = readStringIndex(NameTable);
- if (std::error_code EC = Idx.getError())
- return EC;
-
- // Check whether the name to be accessed has been accessed before,
- // if not, read it from memory directly.
- StringRef &SR = NameTable[*Idx];
- if (SR.empty()) {
- const uint8_t *SavedData = Data;
- Data = MD5NameMemStart + ((*Idx) * sizeof(uint64_t));
- auto FID = readUnencodedNumber<uint64_t>();
- if (std::error_code EC = FID.getError())
- return EC;
- // Save the string converted from uint64_t in MD5StringBuf. All the
- // references to the name are all StringRefs refering to the string
- // in MD5StringBuf.
- MD5StringBuf->push_back(std::to_string(*FID));
- SR = MD5StringBuf->back();
- Data = SavedData;
- }
- return SR;
-}
-
+ErrorOr<StringRef> SampleProfileReaderExtBinaryBase::readStringFromTable() {
+ if (!FixedLengthMD5)
+ return SampleProfileReaderBinary::readStringFromTable();
+
+ // read NameTable index.
+ auto Idx = readStringIndex(NameTable);
+ if (std::error_code EC = Idx.getError())
+ return EC;
+
+ // Check whether the name to be accessed has been accessed before,
+ // if not, read it from memory directly.
+ StringRef &SR = NameTable[*Idx];
+ if (SR.empty()) {
+ const uint8_t *SavedData = Data;
+ Data = MD5NameMemStart + ((*Idx) * sizeof(uint64_t));
+ auto FID = readUnencodedNumber<uint64_t>();
+ if (std::error_code EC = FID.getError())
+ return EC;
+ // Save the string converted from uint64_t in MD5StringBuf. All the
+ // references to the name are all StringRefs refering to the string
+ // in MD5StringBuf.
+ MD5StringBuf->push_back(std::to_string(*FID));
+ SR = MD5StringBuf->back();
+ Data = SavedData;
+ }
+ return SR;
+}
+
ErrorOr<StringRef> SampleProfileReaderCompactBinary::readStringFromTable() {
auto Idx = readStringIndex(NameTable);
if (std::error_code EC = Idx.getError())
@@ -543,16 +543,16 @@ SampleProfileReaderBinary::readFuncProfile(const uint8_t *Start) {
if (std::error_code EC = FName.getError())
return EC;
- SampleContext FContext(*FName);
- Profiles[FContext] = FunctionSamples();
- FunctionSamples &FProfile = Profiles[FContext];
- FProfile.setName(FContext.getNameWithoutContext());
- FProfile.setContext(FContext);
+ SampleContext FContext(*FName);
+ Profiles[FContext] = FunctionSamples();
+ FunctionSamples &FProfile = Profiles[FContext];
+ FProfile.setName(FContext.getNameWithoutContext());
+ FProfile.setContext(FContext);
FProfile.addHeadSamples(*NumHeadSamples);
- if (FContext.hasContext())
- CSProfileCount++;
-
+ if (FContext.hasContext())
+ CSProfileCount++;
+
if (std::error_code EC = readProfile(FProfile))
return EC;
return sampleprof_error::success;
@@ -567,7 +567,7 @@ std::error_code SampleProfileReaderBinary::readImpl() {
return sampleprof_error::success;
}
-std::error_code SampleProfileReaderExtBinaryBase::readOneSection(
+std::error_code SampleProfileReaderExtBinaryBase::readOneSection(
const uint8_t *Start, uint64_t Size, const SecHdrTableEntry &Entry) {
Data = Start;
End = Start + Size;
@@ -578,56 +578,56 @@ std::error_code SampleProfileReaderExtBinaryBase::readOneSection(
if (hasSecFlag(Entry, SecProfSummaryFlags::SecFlagPartial))
Summary->setPartialProfile(true);
break;
- case SecNameTable: {
- FixedLengthMD5 =
- hasSecFlag(Entry, SecNameTableFlags::SecFlagFixedLengthMD5);
- bool UseMD5 = hasSecFlag(Entry, SecNameTableFlags::SecFlagMD5Name);
- assert((!FixedLengthMD5 || UseMD5) &&
- "If FixedLengthMD5 is true, UseMD5 has to be true");
- if (std::error_code EC = readNameTableSec(UseMD5))
+ case SecNameTable: {
+ FixedLengthMD5 =
+ hasSecFlag(Entry, SecNameTableFlags::SecFlagFixedLengthMD5);
+ bool UseMD5 = hasSecFlag(Entry, SecNameTableFlags::SecFlagMD5Name);
+ assert((!FixedLengthMD5 || UseMD5) &&
+ "If FixedLengthMD5 is true, UseMD5 has to be true");
+ if (std::error_code EC = readNameTableSec(UseMD5))
return EC;
break;
- }
+ }
case SecLBRProfile:
if (std::error_code EC = readFuncProfiles())
return EC;
break;
- case SecFuncOffsetTable:
- if (std::error_code EC = readFuncOffsetTable())
- return EC;
- break;
- case SecFuncMetadata:
- ProfileIsProbeBased =
- hasSecFlag(Entry, SecFuncMetadataFlags::SecFlagIsProbeBased);
- FunctionSamples::ProfileIsProbeBased = ProfileIsProbeBased;
- if (std::error_code EC = readFuncMetadata())
- return EC;
- break;
+ case SecFuncOffsetTable:
+ if (std::error_code EC = readFuncOffsetTable())
+ return EC;
+ break;
+ case SecFuncMetadata:
+ ProfileIsProbeBased =
+ hasSecFlag(Entry, SecFuncMetadataFlags::SecFlagIsProbeBased);
+ FunctionSamples::ProfileIsProbeBased = ProfileIsProbeBased;
+ if (std::error_code EC = readFuncMetadata())
+ return EC;
+ break;
case SecProfileSymbolList:
if (std::error_code EC = readProfileSymbolList())
return EC;
break;
- default:
- if (std::error_code EC = readCustomSection(Entry))
+ default:
+ if (std::error_code EC = readCustomSection(Entry))
return EC;
break;
}
return sampleprof_error::success;
}
-void SampleProfileReaderExtBinaryBase::collectFuncsFrom(const Module &M) {
+void SampleProfileReaderExtBinaryBase::collectFuncsFrom(const Module &M) {
UseAllFuncs = false;
FuncsToUse.clear();
for (auto &F : M)
FuncsToUse.insert(FunctionSamples::getCanonicalFnName(F));
}
-std::error_code SampleProfileReaderExtBinaryBase::readFuncOffsetTable() {
- // If there are more than one FuncOffsetTable, the profile read associated
- // with previous FuncOffsetTable has to be done before next FuncOffsetTable
- // is read.
- FuncOffsetTable.clear();
-
+std::error_code SampleProfileReaderExtBinaryBase::readFuncOffsetTable() {
+ // If there are more than one FuncOffsetTable, the profile read associated
+ // with previous FuncOffsetTable has to be done before next FuncOffsetTable
+ // is read.
+ FuncOffsetTable.clear();
+
auto Size = readNumber<uint64_t>();
if (std::error_code EC = Size.getError())
return EC;
@@ -647,7 +647,7 @@ std::error_code SampleProfileReaderExtBinaryBase::readFuncOffsetTable() {
return sampleprof_error::success;
}
-std::error_code SampleProfileReaderExtBinaryBase::readFuncProfiles() {
+std::error_code SampleProfileReaderExtBinaryBase::readFuncProfiles() {
const uint8_t *Start = Data;
if (UseAllFuncs) {
while (Data < End) {
@@ -655,48 +655,48 @@ std::error_code SampleProfileReaderExtBinaryBase::readFuncProfiles() {
return EC;
}
assert(Data == End && "More data is read than expected");
- } else {
- if (Remapper) {
- for (auto Name : FuncsToUse) {
- Remapper->insert(Name);
- }
+ } else {
+ if (Remapper) {
+ for (auto Name : FuncsToUse) {
+ Remapper->insert(Name);
+ }
}
- if (useMD5()) {
- for (auto Name : FuncsToUse) {
- auto GUID = std::to_string(MD5Hash(Name));
- auto iter = FuncOffsetTable.find(StringRef(GUID));
- if (iter == FuncOffsetTable.end())
- continue;
- const uint8_t *FuncProfileAddr = Start + iter->second;
- assert(FuncProfileAddr < End && "out of LBRProfile section");
- if (std::error_code EC = readFuncProfile(FuncProfileAddr))
- return EC;
- }
- } else {
- for (auto NameOffset : FuncOffsetTable) {
- SampleContext FContext(NameOffset.first);
- auto FuncName = FContext.getNameWithoutContext();
- if (!FuncsToUse.count(FuncName) &&
- (!Remapper || !Remapper->exist(FuncName)))
- continue;
- const uint8_t *FuncProfileAddr = Start + NameOffset.second;
- assert(FuncProfileAddr < End && "out of LBRProfile section");
- if (std::error_code EC = readFuncProfile(FuncProfileAddr))
- return EC;
- }
+ if (useMD5()) {
+ for (auto Name : FuncsToUse) {
+ auto GUID = std::to_string(MD5Hash(Name));
+ auto iter = FuncOffsetTable.find(StringRef(GUID));
+ if (iter == FuncOffsetTable.end())
+ continue;
+ const uint8_t *FuncProfileAddr = Start + iter->second;
+ assert(FuncProfileAddr < End && "out of LBRProfile section");
+ if (std::error_code EC = readFuncProfile(FuncProfileAddr))
+ return EC;
+ }
+ } else {
+ for (auto NameOffset : FuncOffsetTable) {
+ SampleContext FContext(NameOffset.first);
+ auto FuncName = FContext.getNameWithoutContext();
+ if (!FuncsToUse.count(FuncName) &&
+ (!Remapper || !Remapper->exist(FuncName)))
+ continue;
+ const uint8_t *FuncProfileAddr = Start + NameOffset.second;
+ assert(FuncProfileAddr < End && "out of LBRProfile section");
+ if (std::error_code EC = readFuncProfile(FuncProfileAddr))
+ return EC;
+ }
}
- Data = End;
+ Data = End;
}
- assert((CSProfileCount == 0 || CSProfileCount == Profiles.size()) &&
- "Cannot have both context-sensitive and regular profile");
- ProfileIsCS = (CSProfileCount > 0);
- FunctionSamples::ProfileIsCS = ProfileIsCS;
+ assert((CSProfileCount == 0 || CSProfileCount == Profiles.size()) &&
+ "Cannot have both context-sensitive and regular profile");
+ ProfileIsCS = (CSProfileCount > 0);
+ FunctionSamples::ProfileIsCS = ProfileIsCS;
return sampleprof_error::success;
}
-std::error_code SampleProfileReaderExtBinaryBase::readProfileSymbolList() {
+std::error_code SampleProfileReaderExtBinaryBase::readProfileSymbolList() {
if (!ProfSymList)
ProfSymList = std::make_unique<ProfileSymbolList>();
@@ -745,10 +745,10 @@ std::error_code SampleProfileReaderExtBinaryBase::readImpl() {
if (!Entry.Size)
continue;
- // Skip sections without context when SkipFlatProf is true.
- if (SkipFlatProf && hasSecFlag(Entry, SecCommonFlags::SecFlagFlat))
- continue;
-
+ // Skip sections without context when SkipFlatProf is true.
+ if (SkipFlatProf && hasSecFlag(Entry, SecCommonFlags::SecFlagFlat))
+ continue;
+
const uint8_t *SecStart = BufStart + Entry.Offset;
uint64_t SecSize = Entry.Size;
@@ -833,7 +833,7 @@ std::error_code SampleProfileReaderBinary::readNameTable() {
auto Size = readNumber<uint32_t>();
if (std::error_code EC = Size.getError())
return EC;
- NameTable.reserve(*Size + NameTable.size());
+ NameTable.reserve(*Size + NameTable.size());
for (uint32_t I = 0; I < *Size; ++I) {
auto Name(readString());
if (std::error_code EC = Name.getError())
@@ -844,24 +844,24 @@ std::error_code SampleProfileReaderBinary::readNameTable() {
return sampleprof_error::success;
}
-std::error_code SampleProfileReaderExtBinaryBase::readMD5NameTable() {
+std::error_code SampleProfileReaderExtBinaryBase::readMD5NameTable() {
auto Size = readNumber<uint64_t>();
if (std::error_code EC = Size.getError())
return EC;
MD5StringBuf = std::make_unique<std::vector<std::string>>();
MD5StringBuf->reserve(*Size);
- if (FixedLengthMD5) {
- // Preallocate and initialize NameTable so we can check whether a name
- // index has been read before by checking whether the element in the
- // NameTable is empty, meanwhile readStringIndex can do the boundary
- // check using the size of NameTable.
- NameTable.resize(*Size + NameTable.size());
-
- MD5NameMemStart = Data;
- Data = Data + (*Size) * sizeof(uint64_t);
- return sampleprof_error::success;
- }
- NameTable.reserve(*Size);
+ if (FixedLengthMD5) {
+ // Preallocate and initialize NameTable so we can check whether a name
+ // index has been read before by checking whether the element in the
+ // NameTable is empty, meanwhile readStringIndex can do the boundary
+ // check using the size of NameTable.
+ NameTable.resize(*Size + NameTable.size());
+
+ MD5NameMemStart = Data;
+ Data = Data + (*Size) * sizeof(uint64_t);
+ return sampleprof_error::success;
+ }
+ NameTable.reserve(*Size);
for (uint32_t I = 0; I < *Size; ++I) {
auto FID = readNumber<uint64_t>();
if (std::error_code EC = FID.getError())
@@ -874,35 +874,35 @@ std::error_code SampleProfileReaderExtBinaryBase::readMD5NameTable() {
return sampleprof_error::success;
}
-std::error_code SampleProfileReaderExtBinaryBase::readNameTableSec(bool IsMD5) {
+std::error_code SampleProfileReaderExtBinaryBase::readNameTableSec(bool IsMD5) {
if (IsMD5)
return readMD5NameTable();
return SampleProfileReaderBinary::readNameTable();
}
-std::error_code SampleProfileReaderExtBinaryBase::readFuncMetadata() {
- if (!ProfileIsProbeBased)
- return sampleprof_error::success;
- while (Data < End) {
- auto FName(readStringFromTable());
- if (std::error_code EC = FName.getError())
- return EC;
-
- auto Checksum = readNumber<uint64_t>();
- if (std::error_code EC = Checksum.getError())
- return EC;
-
- SampleContext FContext(*FName);
- // No need to load metadata for profiles that are not loaded in the current
- // module.
- if (Profiles.count(FContext))
- Profiles[FContext].setFunctionHash(*Checksum);
- }
-
- assert(Data == End && "More data is read than expected");
- return sampleprof_error::success;
-}
-
+std::error_code SampleProfileReaderExtBinaryBase::readFuncMetadata() {
+ if (!ProfileIsProbeBased)
+ return sampleprof_error::success;
+ while (Data < End) {
+ auto FName(readStringFromTable());
+ if (std::error_code EC = FName.getError())
+ return EC;
+
+ auto Checksum = readNumber<uint64_t>();
+ if (std::error_code EC = Checksum.getError())
+ return EC;
+
+ SampleContext FContext(*FName);
+ // No need to load metadata for profiles that are not loaded in the current
+ // module.
+ if (Profiles.count(FContext))
+ Profiles[FContext].setFunctionHash(*Checksum);
+ }
+
+ assert(Data == End && "More data is read than expected");
+ return sampleprof_error::success;
+}
+
std::error_code SampleProfileReaderCompactBinary::readNameTable() {
auto Size = readNumber<uint64_t>();
if (std::error_code EC = Size.getError())
@@ -917,8 +917,8 @@ std::error_code SampleProfileReaderCompactBinary::readNameTable() {
return sampleprof_error::success;
}
-std::error_code
-SampleProfileReaderExtBinaryBase::readSecHdrTableEntry(uint32_t Idx) {
+std::error_code
+SampleProfileReaderExtBinaryBase::readSecHdrTableEntry(uint32_t Idx) {
SecHdrTableEntry Entry;
auto Type = readUnencodedNumber<uint64_t>();
if (std::error_code EC = Type.getError())
@@ -940,7 +940,7 @@ SampleProfileReaderExtBinaryBase::readSecHdrTableEntry(uint32_t Idx) {
return EC;
Entry.Size = *Size;
- Entry.LayoutIndex = Idx;
+ Entry.LayoutIndex = Idx;
SecHdrTable.push_back(std::move(Entry));
return sampleprof_error::success;
}
@@ -951,7 +951,7 @@ std::error_code SampleProfileReaderExtBinaryBase::readSecHdrTable() {
return EC;
for (uint32_t i = 0; i < (*EntryNum); i++)
- if (std::error_code EC = readSecHdrTableEntry(i))
+ if (std::error_code EC = readSecHdrTableEntry(i))
return EC;
return sampleprof_error::success;
@@ -973,12 +973,12 @@ std::error_code SampleProfileReaderExtBinaryBase::readHeader() {
}
uint64_t SampleProfileReaderExtBinaryBase::getSectionSize(SecType Type) {
- uint64_t Size = 0;
+ uint64_t Size = 0;
for (auto &Entry : SecHdrTable) {
if (Entry.Type == Type)
- Size += Entry.Size;
+ Size += Entry.Size;
}
- return Size;
+ return Size;
}
uint64_t SampleProfileReaderExtBinaryBase::getFileSize() {
@@ -1001,14 +1001,14 @@ static std::string getSecFlagsStr(const SecHdrTableEntry &Entry) {
else
Flags.append("{");
- if (hasSecFlag(Entry, SecCommonFlags::SecFlagFlat))
- Flags.append("flat,");
-
+ if (hasSecFlag(Entry, SecCommonFlags::SecFlagFlat))
+ Flags.append("flat,");
+
switch (Entry.Type) {
case SecNameTable:
- if (hasSecFlag(Entry, SecNameTableFlags::SecFlagFixedLengthMD5))
- Flags.append("fixlenmd5,");
- else if (hasSecFlag(Entry, SecNameTableFlags::SecFlagMD5Name))
+ if (hasSecFlag(Entry, SecNameTableFlags::SecFlagFixedLengthMD5))
+ Flags.append("fixlenmd5,");
+ else if (hasSecFlag(Entry, SecNameTableFlags::SecFlagMD5Name))
Flags.append("md5,");
break;
case SecProfSummary:
@@ -1033,7 +1033,7 @@ bool SampleProfileReaderExtBinaryBase::dumpSectionInfo(raw_ostream &OS) {
<< ", Size: " << Entry.Size << ", Flags: " << getSecFlagsStr(Entry)
<< "\n";
;
- TotalSecsSize += Entry.Size;
+ TotalSecsSize += Entry.Size;
}
uint64_t HeaderSize = SecHdrTable.front().Offset;
assert(HeaderSize + TotalSecsSize == getFileSize() &&
@@ -1367,7 +1367,7 @@ std::error_code SampleProfileReaderGCC::readOneFunctionProfile(
InlineCallStack NewStack;
NewStack.push_back(FProfile);
- llvm::append_range(NewStack, InlineStack);
+ llvm::append_range(NewStack, InlineStack);
if (Update) {
// Walk up the inline stack, adding the samples on this line to
// the total sample count of the callers in the chain.
@@ -1415,7 +1415,7 @@ std::error_code SampleProfileReaderGCC::readOneFunctionProfile(
return sampleprof_error::truncated;
InlineCallStack NewStack;
NewStack.push_back(FProfile);
- llvm::append_range(NewStack, InlineStack);
+ llvm::append_range(NewStack, InlineStack);
if (std::error_code EC = readOneFunctionProfile(NewStack, Update, Offset))
return EC;
}
@@ -1456,25 +1456,25 @@ void SampleProfileReaderItaniumRemapper::applyRemapping(LLVMContext &Ctx) {
return;
}
- // CSSPGO-TODO: Remapper is not yet supported.
- // We will need to remap the entire context string.
+ // CSSPGO-TODO: Remapper is not yet supported.
+ // We will need to remap the entire context string.
assert(Remappings && "should be initialized while creating remapper");
- for (auto &Sample : Reader.getProfiles()) {
- DenseSet<StringRef> NamesInSample;
- Sample.second.findAllNames(NamesInSample);
- for (auto &Name : NamesInSample)
- if (auto Key = Remappings->insert(Name))
- NameMap.insert({Key, Name});
- }
+ for (auto &Sample : Reader.getProfiles()) {
+ DenseSet<StringRef> NamesInSample;
+ Sample.second.findAllNames(NamesInSample);
+ for (auto &Name : NamesInSample)
+ if (auto Key = Remappings->insert(Name))
+ NameMap.insert({Key, Name});
+ }
RemappingApplied = true;
}
-Optional<StringRef>
-SampleProfileReaderItaniumRemapper::lookUpNameInProfile(StringRef Fname) {
+Optional<StringRef>
+SampleProfileReaderItaniumRemapper::lookUpNameInProfile(StringRef Fname) {
if (auto Key = Remappings->lookup(Fname))
- return NameMap.lookup(Key);
- return None;
+ return NameMap.lookup(Key);
+ return None;
}
/// Prepare a memory buffer for the contents of \p Filename.
@@ -1610,5 +1610,5 @@ SampleProfileReader::create(std::unique_ptr<MemoryBuffer> &B, LLVMContext &C,
// profile. Binary format has the profile summary in its header.
void SampleProfileReader::computeSummary() {
SampleProfileSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs);
- Summary = Builder.computeSummaryForProfiles(Profiles);
+ Summary = Builder.computeSummaryForProfiles(Profiles);
}
diff --git a/contrib/libs/llvm12/lib/ProfileData/SampleProfWriter.cpp b/contrib/libs/llvm12/lib/ProfileData/SampleProfWriter.cpp
index 0122712a0c..8017f2a828 100644
--- a/contrib/libs/llvm12/lib/ProfileData/SampleProfWriter.cpp
+++ b/contrib/libs/llvm12/lib/ProfileData/SampleProfWriter.cpp
@@ -19,7 +19,7 @@
#include "llvm/ProfileData/SampleProfWriter.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/ProfileData/ProfileCommon.h"
#include "llvm/ProfileData/SampleProf.h"
#include "llvm/Support/Compression.h"
@@ -75,15 +75,15 @@ SampleProfileWriter::write(const StringMap<FunctionSamples> &ProfileMap) {
}
/// Return the current position and prepare to use it as the start
-/// position of a section given the section type \p Type and its position
-/// \p LayoutIdx in SectionHdrLayout.
-uint64_t
-SampleProfileWriterExtBinaryBase::markSectionStart(SecType Type,
- uint32_t LayoutIdx) {
+/// position of a section given the section type \p Type and its position
+/// \p LayoutIdx in SectionHdrLayout.
+uint64_t
+SampleProfileWriterExtBinaryBase::markSectionStart(SecType Type,
+ uint32_t LayoutIdx) {
uint64_t SectionStart = OutputStream->tell();
- assert(LayoutIdx < SectionHdrLayout.size() && "LayoutIdx out of range");
- const auto &Entry = SectionHdrLayout[LayoutIdx];
- assert(Entry.Type == Type && "Unexpected section type");
+ assert(LayoutIdx < SectionHdrLayout.size() && "LayoutIdx out of range");
+ const auto &Entry = SectionHdrLayout[LayoutIdx];
+ assert(Entry.Type == Type && "Unexpected section type");
// Use LocalBuf as a temporary output for writting data.
if (hasSecFlag(Entry, SecCommonFlags::SecFlagCompress))
LocalBufStream.swap(OutputStream);
@@ -110,21 +110,21 @@ std::error_code SampleProfileWriterExtBinaryBase::compressAndOutput() {
return sampleprof_error::success;
}
-/// Add a new section into section header table given the section type
-/// \p Type, its position \p LayoutIdx in SectionHdrLayout and the
-/// location \p SectionStart where the section should be written to.
-std::error_code SampleProfileWriterExtBinaryBase::addNewSection(
- SecType Type, uint32_t LayoutIdx, uint64_t SectionStart) {
- assert(LayoutIdx < SectionHdrLayout.size() && "LayoutIdx out of range");
- const auto &Entry = SectionHdrLayout[LayoutIdx];
- assert(Entry.Type == Type && "Unexpected section type");
+/// Add a new section into section header table given the section type
+/// \p Type, its position \p LayoutIdx in SectionHdrLayout and the
+/// location \p SectionStart where the section should be written to.
+std::error_code SampleProfileWriterExtBinaryBase::addNewSection(
+ SecType Type, uint32_t LayoutIdx, uint64_t SectionStart) {
+ assert(LayoutIdx < SectionHdrLayout.size() && "LayoutIdx out of range");
+ const auto &Entry = SectionHdrLayout[LayoutIdx];
+ assert(Entry.Type == Type && "Unexpected section type");
if (hasSecFlag(Entry, SecCommonFlags::SecFlagCompress)) {
LocalBufStream.swap(OutputStream);
if (std::error_code EC = compressAndOutput())
return EC;
}
SecHdrTable.push_back({Type, Entry.Flags, SectionStart - FileStart,
- OutputStream->tell() - SectionStart, LayoutIdx});
+ OutputStream->tell() - SectionStart, LayoutIdx});
return sampleprof_error::success;
}
@@ -145,15 +145,15 @@ std::error_code SampleProfileWriterExtBinaryBase::write(
}
std::error_code
-SampleProfileWriterExtBinaryBase::writeSample(const FunctionSamples &S) {
+SampleProfileWriterExtBinaryBase::writeSample(const FunctionSamples &S) {
uint64_t Offset = OutputStream->tell();
- StringRef Name = S.getNameWithContext(true);
+ StringRef Name = S.getNameWithContext(true);
FuncOffsetTable[Name] = Offset - SecLBRProfileStart;
encodeULEB128(S.getHeadSamples(), *OutputStream);
return writeBody(S);
}
-std::error_code SampleProfileWriterExtBinaryBase::writeFuncOffsetTable() {
+std::error_code SampleProfileWriterExtBinaryBase::writeFuncOffsetTable() {
auto &OS = *OutputStream;
// Write out the table size.
@@ -164,23 +164,23 @@ std::error_code SampleProfileWriterExtBinaryBase::writeFuncOffsetTable() {
writeNameIdx(entry.first);
encodeULEB128(entry.second, OS);
}
- FuncOffsetTable.clear();
+ FuncOffsetTable.clear();
return sampleprof_error::success;
}
-std::error_code SampleProfileWriterExtBinaryBase::writeFuncMetadata(
- const StringMap<FunctionSamples> &Profiles) {
- if (!FunctionSamples::ProfileIsProbeBased)
- return sampleprof_error::success;
- auto &OS = *OutputStream;
- for (const auto &Entry : Profiles) {
- writeNameIdx(Entry.first());
- encodeULEB128(Entry.second.getFunctionHash(), OS);
- }
- return sampleprof_error::success;
-}
-
-std::error_code SampleProfileWriterExtBinaryBase::writeNameTable() {
+std::error_code SampleProfileWriterExtBinaryBase::writeFuncMetadata(
+ const StringMap<FunctionSamples> &Profiles) {
+ if (!FunctionSamples::ProfileIsProbeBased)
+ return sampleprof_error::success;
+ auto &OS = *OutputStream;
+ for (const auto &Entry : Profiles) {
+ writeNameIdx(Entry.first());
+ encodeULEB128(Entry.second.getFunctionHash(), OS);
+ }
+ return sampleprof_error::success;
+}
+
+std::error_code SampleProfileWriterExtBinaryBase::writeNameTable() {
if (!UseMD5)
return SampleProfileWriterBinary::writeNameTable();
@@ -188,159 +188,159 @@ std::error_code SampleProfileWriterExtBinaryBase::writeNameTable() {
std::set<StringRef> V;
stablizeNameTable(V);
- // Write out the MD5 name table. We wrote unencoded MD5 so reader can
- // retrieve the name using the name index without having to read the
- // whole name table.
+ // Write out the MD5 name table. We wrote unencoded MD5 so reader can
+ // retrieve the name using the name index without having to read the
+ // whole name table.
encodeULEB128(NameTable.size(), OS);
- support::endian::Writer Writer(OS, support::little);
- for (auto N : V)
- Writer.write(MD5Hash(N));
+ support::endian::Writer Writer(OS, support::little);
+ for (auto N : V)
+ Writer.write(MD5Hash(N));
return sampleprof_error::success;
}
-std::error_code SampleProfileWriterExtBinaryBase::writeNameTableSection(
+std::error_code SampleProfileWriterExtBinaryBase::writeNameTableSection(
const StringMap<FunctionSamples> &ProfileMap) {
for (const auto &I : ProfileMap) {
addName(I.first());
addNames(I.second);
}
- if (auto EC = writeNameTable())
+ if (auto EC = writeNameTable())
return EC;
- return sampleprof_error::success;
-}
-
-std::error_code
-SampleProfileWriterExtBinaryBase::writeProfileSymbolListSection() {
- if (ProfSymList && ProfSymList->size() > 0)
- if (std::error_code EC = ProfSymList->write(*OutputStream))
- return EC;
-
- return sampleprof_error::success;
-}
-
-std::error_code SampleProfileWriterExtBinaryBase::writeOneSection(
- SecType Type, uint32_t LayoutIdx,
- const StringMap<FunctionSamples> &ProfileMap) {
- // The setting of SecFlagCompress should happen before markSectionStart.
- if (Type == SecProfileSymbolList && ProfSymList && ProfSymList->toCompress())
+ return sampleprof_error::success;
+}
+
+std::error_code
+SampleProfileWriterExtBinaryBase::writeProfileSymbolListSection() {
+ if (ProfSymList && ProfSymList->size() > 0)
+ if (std::error_code EC = ProfSymList->write(*OutputStream))
+ return EC;
+
+ return sampleprof_error::success;
+}
+
+std::error_code SampleProfileWriterExtBinaryBase::writeOneSection(
+ SecType Type, uint32_t LayoutIdx,
+ const StringMap<FunctionSamples> &ProfileMap) {
+ // The setting of SecFlagCompress should happen before markSectionStart.
+ if (Type == SecProfileSymbolList && ProfSymList && ProfSymList->toCompress())
setToCompressSection(SecProfileSymbolList);
- if (Type == SecFuncMetadata && FunctionSamples::ProfileIsProbeBased)
- addSectionFlag(SecFuncMetadata, SecFuncMetadataFlags::SecFlagIsProbeBased);
-
- uint64_t SectionStart = markSectionStart(Type, LayoutIdx);
- switch (Type) {
- case SecProfSummary:
- computeSummary(ProfileMap);
- if (auto EC = writeSummary())
+ if (Type == SecFuncMetadata && FunctionSamples::ProfileIsProbeBased)
+ addSectionFlag(SecFuncMetadata, SecFuncMetadataFlags::SecFlagIsProbeBased);
+
+ uint64_t SectionStart = markSectionStart(Type, LayoutIdx);
+ switch (Type) {
+ case SecProfSummary:
+ computeSummary(ProfileMap);
+ if (auto EC = writeSummary())
+ return EC;
+ break;
+ case SecNameTable:
+ if (auto EC = writeNameTableSection(ProfileMap))
+ return EC;
+ break;
+ case SecLBRProfile:
+ SecLBRProfileStart = OutputStream->tell();
+ if (std::error_code EC = writeFuncProfiles(ProfileMap))
+ return EC;
+ break;
+ case SecFuncOffsetTable:
+ if (auto EC = writeFuncOffsetTable())
+ return EC;
+ break;
+ case SecFuncMetadata:
+ if (std::error_code EC = writeFuncMetadata(ProfileMap))
+ return EC;
+ break;
+ case SecProfileSymbolList:
+ if (auto EC = writeProfileSymbolListSection())
+ return EC;
+ break;
+ default:
+ if (auto EC = writeCustomSection(Type))
return EC;
- break;
- case SecNameTable:
- if (auto EC = writeNameTableSection(ProfileMap))
- return EC;
- break;
- case SecLBRProfile:
- SecLBRProfileStart = OutputStream->tell();
- if (std::error_code EC = writeFuncProfiles(ProfileMap))
- return EC;
- break;
- case SecFuncOffsetTable:
- if (auto EC = writeFuncOffsetTable())
- return EC;
- break;
- case SecFuncMetadata:
- if (std::error_code EC = writeFuncMetadata(ProfileMap))
- return EC;
- break;
- case SecProfileSymbolList:
- if (auto EC = writeProfileSymbolListSection())
- return EC;
- break;
- default:
- if (auto EC = writeCustomSection(Type))
- return EC;
- break;
- }
- if (std::error_code EC = addNewSection(Type, LayoutIdx, SectionStart))
+ break;
+ }
+ if (std::error_code EC = addNewSection(Type, LayoutIdx, SectionStart))
+ return EC;
+ return sampleprof_error::success;
+}
+
+std::error_code SampleProfileWriterExtBinary::writeDefaultLayout(
+ const StringMap<FunctionSamples> &ProfileMap) {
+ // The const indices passed to writeOneSection below are specifying the
+ // positions of the sections in SectionHdrLayout. Look at
+ // initSectionHdrLayout to find out where each section is located in
+ // SectionHdrLayout.
+ if (auto EC = writeOneSection(SecProfSummary, 0, ProfileMap))
+ return EC;
+ if (auto EC = writeOneSection(SecNameTable, 1, ProfileMap))
return EC;
- return sampleprof_error::success;
-}
-
-std::error_code SampleProfileWriterExtBinary::writeDefaultLayout(
- const StringMap<FunctionSamples> &ProfileMap) {
- // The const indices passed to writeOneSection below are specifying the
- // positions of the sections in SectionHdrLayout. Look at
- // initSectionHdrLayout to find out where each section is located in
- // SectionHdrLayout.
- if (auto EC = writeOneSection(SecProfSummary, 0, ProfileMap))
+ if (auto EC = writeOneSection(SecLBRProfile, 3, ProfileMap))
return EC;
- if (auto EC = writeOneSection(SecNameTable, 1, ProfileMap))
+ if (auto EC = writeOneSection(SecProfileSymbolList, 4, ProfileMap))
+ return EC;
+ if (auto EC = writeOneSection(SecFuncOffsetTable, 2, ProfileMap))
+ return EC;
+ if (auto EC = writeOneSection(SecFuncMetadata, 5, ProfileMap))
return EC;
- if (auto EC = writeOneSection(SecLBRProfile, 3, ProfileMap))
- return EC;
- if (auto EC = writeOneSection(SecProfileSymbolList, 4, ProfileMap))
- return EC;
- if (auto EC = writeOneSection(SecFuncOffsetTable, 2, ProfileMap))
- return EC;
- if (auto EC = writeOneSection(SecFuncMetadata, 5, ProfileMap))
- return EC;
- return sampleprof_error::success;
-}
-
-static void
-splitProfileMapToTwo(const StringMap<FunctionSamples> &ProfileMap,
- StringMap<FunctionSamples> &ContextProfileMap,
- StringMap<FunctionSamples> &NoContextProfileMap) {
- for (const auto &I : ProfileMap) {
- if (I.second.getCallsiteSamples().size())
- ContextProfileMap.insert({I.first(), I.second});
- else
- NoContextProfileMap.insert({I.first(), I.second});
- }
-}
-
-std::error_code SampleProfileWriterExtBinary::writeCtxSplitLayout(
- const StringMap<FunctionSamples> &ProfileMap) {
- StringMap<FunctionSamples> ContextProfileMap, NoContextProfileMap;
- splitProfileMapToTwo(ProfileMap, ContextProfileMap, NoContextProfileMap);
-
- if (auto EC = writeOneSection(SecProfSummary, 0, ProfileMap))
- return EC;
- if (auto EC = writeOneSection(SecNameTable, 1, ProfileMap))
- return EC;
- if (auto EC = writeOneSection(SecLBRProfile, 3, ContextProfileMap))
- return EC;
- if (auto EC = writeOneSection(SecFuncOffsetTable, 2, ContextProfileMap))
- return EC;
- // Mark the section to have no context. Note section flag needs to be set
- // before writing the section.
- addSectionFlag(5, SecCommonFlags::SecFlagFlat);
- if (auto EC = writeOneSection(SecLBRProfile, 5, NoContextProfileMap))
- return EC;
- // Mark the section to have no context. Note section flag needs to be set
- // before writing the section.
- addSectionFlag(4, SecCommonFlags::SecFlagFlat);
- if (auto EC = writeOneSection(SecFuncOffsetTable, 4, NoContextProfileMap))
- return EC;
- if (auto EC = writeOneSection(SecProfileSymbolList, 6, ProfileMap))
- return EC;
- if (auto EC = writeOneSection(SecFuncMetadata, 7, ProfileMap))
- return EC;
-
return sampleprof_error::success;
}
-std::error_code SampleProfileWriterExtBinary::writeSections(
- const StringMap<FunctionSamples> &ProfileMap) {
- std::error_code EC;
- if (SecLayout == DefaultLayout)
- EC = writeDefaultLayout(ProfileMap);
- else if (SecLayout == CtxSplitLayout)
- EC = writeCtxSplitLayout(ProfileMap);
- else
- llvm_unreachable("Unsupported layout");
- return EC;
-}
-
+static void
+splitProfileMapToTwo(const StringMap<FunctionSamples> &ProfileMap,
+ StringMap<FunctionSamples> &ContextProfileMap,
+ StringMap<FunctionSamples> &NoContextProfileMap) {
+ for (const auto &I : ProfileMap) {
+ if (I.second.getCallsiteSamples().size())
+ ContextProfileMap.insert({I.first(), I.second});
+ else
+ NoContextProfileMap.insert({I.first(), I.second});
+ }
+}
+
+std::error_code SampleProfileWriterExtBinary::writeCtxSplitLayout(
+ const StringMap<FunctionSamples> &ProfileMap) {
+ StringMap<FunctionSamples> ContextProfileMap, NoContextProfileMap;
+ splitProfileMapToTwo(ProfileMap, ContextProfileMap, NoContextProfileMap);
+
+ if (auto EC = writeOneSection(SecProfSummary, 0, ProfileMap))
+ return EC;
+ if (auto EC = writeOneSection(SecNameTable, 1, ProfileMap))
+ return EC;
+ if (auto EC = writeOneSection(SecLBRProfile, 3, ContextProfileMap))
+ return EC;
+ if (auto EC = writeOneSection(SecFuncOffsetTable, 2, ContextProfileMap))
+ return EC;
+ // Mark the section to have no context. Note section flag needs to be set
+ // before writing the section.
+ addSectionFlag(5, SecCommonFlags::SecFlagFlat);
+ if (auto EC = writeOneSection(SecLBRProfile, 5, NoContextProfileMap))
+ return EC;
+ // Mark the section to have no context. Note section flag needs to be set
+ // before writing the section.
+ addSectionFlag(4, SecCommonFlags::SecFlagFlat);
+ if (auto EC = writeOneSection(SecFuncOffsetTable, 4, NoContextProfileMap))
+ return EC;
+ if (auto EC = writeOneSection(SecProfileSymbolList, 6, ProfileMap))
+ return EC;
+ if (auto EC = writeOneSection(SecFuncMetadata, 7, ProfileMap))
+ return EC;
+
+ return sampleprof_error::success;
+}
+
+std::error_code SampleProfileWriterExtBinary::writeSections(
+ const StringMap<FunctionSamples> &ProfileMap) {
+ std::error_code EC;
+ if (SecLayout == DefaultLayout)
+ EC = writeDefaultLayout(ProfileMap);
+ else if (SecLayout == CtxSplitLayout)
+ EC = writeCtxSplitLayout(ProfileMap);
+ else
+ llvm_unreachable("Unsupported layout");
+ return EC;
+}
+
std::error_code SampleProfileWriterCompactBinary::write(
const StringMap<FunctionSamples> &ProfileMap) {
if (std::error_code EC = SampleProfileWriter::write(ProfileMap))
@@ -360,7 +360,7 @@ std::error_code SampleProfileWriterCompactBinary::write(
/// it needs to be parsed by the SampleProfileReaderText class.
std::error_code SampleProfileWriterText::writeSample(const FunctionSamples &S) {
auto &OS = *OutputStream;
- OS << S.getNameWithContext(true) << ":" << S.getTotalSamples();
+ OS << S.getNameWithContext(true) << ":" << S.getTotalSamples();
if (Indent == 0)
OS << ":" << S.getHeadSamples();
OS << "\n";
@@ -399,13 +399,13 @@ std::error_code SampleProfileWriterText::writeSample(const FunctionSamples &S) {
}
Indent -= 1;
- if (Indent == 0) {
- if (FunctionSamples::ProfileIsProbeBased) {
- OS.indent(Indent + 1);
- OS << "!CFGChecksum: " << S.getFunctionHash() << "\n";
- }
- }
-
+ if (Indent == 0) {
+ if (FunctionSamples::ProfileIsProbeBased) {
+ OS.indent(Indent + 1);
+ OS << "!CFGChecksum: " << S.getFunctionHash() << "\n";
+ }
+ }
+
return sampleprof_error::success;
}
@@ -556,31 +556,31 @@ std::error_code SampleProfileWriterExtBinaryBase::writeSecHdrTable() {
return sampleprof_error::ostream_seek_unsupported;
support::endian::Writer Writer(*OutputStream, support::little);
- assert(SecHdrTable.size() == SectionHdrLayout.size() &&
- "SecHdrTable entries doesn't match SectionHdrLayout");
- SmallVector<uint32_t, 16> IndexMap(SecHdrTable.size(), -1);
- for (uint32_t TableIdx = 0; TableIdx < SecHdrTable.size(); TableIdx++) {
- IndexMap[SecHdrTable[TableIdx].LayoutIndex] = TableIdx;
+ assert(SecHdrTable.size() == SectionHdrLayout.size() &&
+ "SecHdrTable entries doesn't match SectionHdrLayout");
+ SmallVector<uint32_t, 16> IndexMap(SecHdrTable.size(), -1);
+ for (uint32_t TableIdx = 0; TableIdx < SecHdrTable.size(); TableIdx++) {
+ IndexMap[SecHdrTable[TableIdx].LayoutIndex] = TableIdx;
}
// Write the section header table in the order specified in
- // SectionHdrLayout. SectionHdrLayout specifies the sections
- // order in which profile reader expect to read, so the section
- // header table should be written in the order in SectionHdrLayout.
- // Note that the section order in SecHdrTable may be different
- // from the order in SectionHdrLayout, for example, SecFuncOffsetTable
- // needs to be computed after SecLBRProfile (the order in SecHdrTable),
- // but it needs to be read before SecLBRProfile (the order in
- // SectionHdrLayout). So we use IndexMap above to switch the order.
- for (uint32_t LayoutIdx = 0; LayoutIdx < SectionHdrLayout.size();
- LayoutIdx++) {
- assert(IndexMap[LayoutIdx] < SecHdrTable.size() &&
- "Incorrect LayoutIdx in SecHdrTable");
- auto Entry = SecHdrTable[IndexMap[LayoutIdx]];
- Writer.write(static_cast<uint64_t>(Entry.Type));
- Writer.write(static_cast<uint64_t>(Entry.Flags));
- Writer.write(static_cast<uint64_t>(Entry.Offset));
- Writer.write(static_cast<uint64_t>(Entry.Size));
+ // SectionHdrLayout. SectionHdrLayout specifies the sections
+ // order in which profile reader expect to read, so the section
+ // header table should be written in the order in SectionHdrLayout.
+ // Note that the section order in SecHdrTable may be different
+ // from the order in SectionHdrLayout, for example, SecFuncOffsetTable
+ // needs to be computed after SecLBRProfile (the order in SecHdrTable),
+ // but it needs to be read before SecLBRProfile (the order in
+ // SectionHdrLayout). So we use IndexMap above to switch the order.
+ for (uint32_t LayoutIdx = 0; LayoutIdx < SectionHdrLayout.size();
+ LayoutIdx++) {
+ assert(IndexMap[LayoutIdx] < SecHdrTable.size() &&
+ "Incorrect LayoutIdx in SecHdrTable");
+ auto Entry = SecHdrTable[IndexMap[LayoutIdx]];
+ Writer.write(static_cast<uint64_t>(Entry.Type));
+ Writer.write(static_cast<uint64_t>(Entry.Flags));
+ Writer.write(static_cast<uint64_t>(Entry.Offset));
+ Writer.write(static_cast<uint64_t>(Entry.Size));
}
// Reset OutputStream.
@@ -632,7 +632,7 @@ std::error_code SampleProfileWriterBinary::writeSummary() {
std::error_code SampleProfileWriterBinary::writeBody(const FunctionSamples &S) {
auto &OS = *OutputStream;
- if (std::error_code EC = writeNameIdx(S.getNameWithContext(true)))
+ if (std::error_code EC = writeNameIdx(S.getNameWithContext(true)))
return EC;
encodeULEB128(S.getTotalSamples(), OS);
@@ -749,5 +749,5 @@ SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS,
void SampleProfileWriter::computeSummary(
const StringMap<FunctionSamples> &ProfileMap) {
SampleProfileSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs);
- Summary = Builder.computeSummaryForProfiles(ProfileMap);
+ Summary = Builder.computeSummaryForProfiles(ProfileMap);
}
diff --git a/contrib/libs/llvm12/lib/ProfileData/ya.make b/contrib/libs/llvm12/lib/ProfileData/ya.make
index 24c01a162b..1c3b40612f 100644
--- a/contrib/libs/llvm12/lib/ProfileData/ya.make
+++ b/contrib/libs/llvm12/lib/ProfileData/ya.make
@@ -12,11 +12,11 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Demangle
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Demangle
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/Remarks/BitstreamRemarkParser.h b/contrib/libs/llvm12/lib/Remarks/BitstreamRemarkParser.h
index 856257445e..0e40e5d66e 100644
--- a/contrib/libs/llvm12/lib/Remarks/BitstreamRemarkParser.h
+++ b/contrib/libs/llvm12/lib/Remarks/BitstreamRemarkParser.h
@@ -14,12 +14,12 @@
#define LLVM_LIB_REMARKS_BITSTREAM_REMARK_PARSER_H
#include "llvm/ADT/Optional.h"
-#include "llvm/Remarks/BitstreamRemarkContainer.h"
+#include "llvm/Remarks/BitstreamRemarkContainer.h"
#include "llvm/Remarks/BitstreamRemarkParser.h"
-#include "llvm/Remarks/Remark.h"
+#include "llvm/Remarks/Remark.h"
#include "llvm/Remarks/RemarkFormat.h"
#include "llvm/Remarks/RemarkParser.h"
-#include <cstdint>
+#include <cstdint>
#include <memory>
namespace llvm {
diff --git a/contrib/libs/llvm12/lib/Remarks/ya.make b/contrib/libs/llvm12/lib/Remarks/ya.make
index 9ee63e79f8..4308033577 100644
--- a/contrib/libs/llvm12/lib/Remarks/ya.make
+++ b/contrib/libs/llvm12/lib/Remarks/ya.make
@@ -12,9 +12,9 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/Bitstream/Reader
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/Bitstream/Reader
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/Support/AArch64TargetParser.cpp b/contrib/libs/llvm12/lib/Support/AArch64TargetParser.cpp
index 9580c26af6..503a7bd49d 100644
--- a/contrib/libs/llvm12/lib/Support/AArch64TargetParser.cpp
+++ b/contrib/libs/llvm12/lib/Support/AArch64TargetParser.cpp
@@ -35,11 +35,11 @@ unsigned AArch64::getDefaultFPU(StringRef CPU, AArch64::ArchKind AK) {
.Default(ARM::FK_INVALID);
}
-uint64_t AArch64::getDefaultExtensions(StringRef CPU, AArch64::ArchKind AK) {
+uint64_t AArch64::getDefaultExtensions(StringRef CPU, AArch64::ArchKind AK) {
if (CPU == "generic")
return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
- return StringSwitch<uint64_t>(CPU)
+ return StringSwitch<uint64_t>(CPU)
#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
.Case(NAME, AArch64ARCHNames[static_cast<unsigned>(ArchKind::ID)] \
.ArchBaseExtensions | \
@@ -59,7 +59,7 @@ AArch64::ArchKind AArch64::getCPUArchKind(StringRef CPU) {
.Default(ArchKind::INVALID);
}
-bool AArch64::getExtensionFeatures(uint64_t Extensions,
+bool AArch64::getExtensionFeatures(uint64_t Extensions,
std::vector<StringRef> &Features) {
if (Extensions == AArch64::AEK_INVALID)
return false;
@@ -100,12 +100,12 @@ bool AArch64::getExtensionFeatures(uint64_t Extensions,
Features.push_back("+sve2-bitperm");
if (Extensions & AEK_RCPC)
Features.push_back("+rcpc");
- if (Extensions & AEK_BRBE)
- Features.push_back("+brbe");
- if (Extensions & AEK_PAUTH)
- Features.push_back("+pauth");
- if (Extensions & AEK_FLAGM)
- Features.push_back("+flagm");
+ if (Extensions & AEK_BRBE)
+ Features.push_back("+brbe");
+ if (Extensions & AEK_PAUTH)
+ Features.push_back("+pauth");
+ if (Extensions & AEK_FLAGM)
+ Features.push_back("+flagm");
return true;
}
@@ -124,10 +124,10 @@ bool AArch64::getArchFeatures(AArch64::ArchKind AK,
Features.push_back("+v8.5a");
if (AK == AArch64::ArchKind::ARMV8_6A)
Features.push_back("+v8.6a");
- if (AK == AArch64::ArchKind::ARMV8_7A)
- Features.push_back("+v8.7a");
- if(AK == AArch64::ArchKind::ARMV8R)
- Features.push_back("+v8r");
+ if (AK == AArch64::ArchKind::ARMV8_7A)
+ Features.push_back("+v8.7a");
+ if(AK == AArch64::ArchKind::ARMV8R)
+ Features.push_back("+v8r");
return AK != ArchKind::INVALID;
}
diff --git a/contrib/libs/llvm12/lib/Support/AMDGPUMetadata.cpp b/contrib/libs/llvm12/lib/Support/AMDGPUMetadata.cpp
index 57ec007030..3d6325134d 100644
--- a/contrib/libs/llvm12/lib/Support/AMDGPUMetadata.cpp
+++ b/contrib/libs/llvm12/lib/Support/AMDGPUMetadata.cpp
@@ -210,7 +210,7 @@ struct MappingTraits<HSAMD::Metadata> {
namespace AMDGPU {
namespace HSAMD {
-std::error_code fromString(StringRef String, Metadata &HSAMetadata) {
+std::error_code fromString(StringRef String, Metadata &HSAMetadata) {
yaml::Input YamlInput(String);
YamlInput >> HSAMetadata;
return YamlInput.error();
diff --git a/contrib/libs/llvm12/lib/Support/APFixedPoint.cpp b/contrib/libs/llvm12/lib/Support/APFixedPoint.cpp
index ff11333f51..9764dd51f5 100644
--- a/contrib/libs/llvm12/lib/Support/APFixedPoint.cpp
+++ b/contrib/libs/llvm12/lib/Support/APFixedPoint.cpp
@@ -1,574 +1,574 @@
-//===- APFixedPoint.cpp - Fixed point constant handling ---------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file
-/// Defines the implementation for the fixed point number interface.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/APFixedPoint.h"
-#include "llvm/ADT/APFloat.h"
-
-namespace llvm {
-
-APFixedPoint APFixedPoint::convert(const FixedPointSemantics &DstSema,
- bool *Overflow) const {
- APSInt NewVal = Val;
- unsigned DstWidth = DstSema.getWidth();
- unsigned DstScale = DstSema.getScale();
- bool Upscaling = DstScale > getScale();
- if (Overflow)
- *Overflow = false;
-
- if (Upscaling) {
- NewVal = NewVal.extend(NewVal.getBitWidth() + DstScale - getScale());
- NewVal <<= (DstScale - getScale());
- } else {
- NewVal >>= (getScale() - DstScale);
- }
-
- auto Mask = APInt::getBitsSetFrom(
- NewVal.getBitWidth(),
- std::min(DstScale + DstSema.getIntegralBits(), NewVal.getBitWidth()));
- APInt Masked(NewVal & Mask);
-
- // Change in the bits above the sign
- if (!(Masked == Mask || Masked == 0)) {
- // Found overflow in the bits above the sign
- if (DstSema.isSaturated())
- NewVal = NewVal.isNegative() ? Mask : ~Mask;
- else if (Overflow)
- *Overflow = true;
- }
-
- // If the dst semantics are unsigned, but our value is signed and negative, we
- // clamp to zero.
- if (!DstSema.isSigned() && NewVal.isSigned() && NewVal.isNegative()) {
- // Found negative overflow for unsigned result
- if (DstSema.isSaturated())
- NewVal = 0;
- else if (Overflow)
- *Overflow = true;
- }
-
- NewVal = NewVal.extOrTrunc(DstWidth);
- NewVal.setIsSigned(DstSema.isSigned());
- return APFixedPoint(NewVal, DstSema);
-}
-
-int APFixedPoint::compare(const APFixedPoint &Other) const {
- APSInt ThisVal = getValue();
- APSInt OtherVal = Other.getValue();
- bool ThisSigned = Val.isSigned();
- bool OtherSigned = OtherVal.isSigned();
- unsigned OtherScale = Other.getScale();
- unsigned OtherWidth = OtherVal.getBitWidth();
-
- unsigned CommonWidth = std::max(Val.getBitWidth(), OtherWidth);
-
- // Prevent overflow in the event the widths are the same but the scales differ
- CommonWidth += getScale() >= OtherScale ? getScale() - OtherScale
- : OtherScale - getScale();
-
- ThisVal = ThisVal.extOrTrunc(CommonWidth);
- OtherVal = OtherVal.extOrTrunc(CommonWidth);
-
- unsigned CommonScale = std::max(getScale(), OtherScale);
- ThisVal = ThisVal.shl(CommonScale - getScale());
- OtherVal = OtherVal.shl(CommonScale - OtherScale);
-
- if (ThisSigned && OtherSigned) {
- if (ThisVal.sgt(OtherVal))
- return 1;
- else if (ThisVal.slt(OtherVal))
- return -1;
- } else if (!ThisSigned && !OtherSigned) {
- if (ThisVal.ugt(OtherVal))
- return 1;
- else if (ThisVal.ult(OtherVal))
- return -1;
- } else if (ThisSigned && !OtherSigned) {
- if (ThisVal.isSignBitSet())
- return -1;
- else if (ThisVal.ugt(OtherVal))
- return 1;
- else if (ThisVal.ult(OtherVal))
- return -1;
- } else {
- // !ThisSigned && OtherSigned
- if (OtherVal.isSignBitSet())
- return 1;
- else if (ThisVal.ugt(OtherVal))
- return 1;
- else if (ThisVal.ult(OtherVal))
- return -1;
- }
-
- return 0;
-}
-
-APFixedPoint APFixedPoint::getMax(const FixedPointSemantics &Sema) {
- bool IsUnsigned = !Sema.isSigned();
- auto Val = APSInt::getMaxValue(Sema.getWidth(), IsUnsigned);
- if (IsUnsigned && Sema.hasUnsignedPadding())
- Val = Val.lshr(1);
- return APFixedPoint(Val, Sema);
-}
-
-APFixedPoint APFixedPoint::getMin(const FixedPointSemantics &Sema) {
- auto Val = APSInt::getMinValue(Sema.getWidth(), !Sema.isSigned());
- return APFixedPoint(Val, Sema);
-}
-
-bool FixedPointSemantics::fitsInFloatSemantics(
- const fltSemantics &FloatSema) const {
- // A fixed point semantic fits in a floating point semantic if the maximum
- // and minimum values as integers of the fixed point semantic can fit in the
- // floating point semantic.
-
- // If these values do not fit, then a floating point rescaling of the true
- // maximum/minimum value will not fit either, so the floating point semantic
- // cannot be used to perform such a rescaling.
-
- APSInt MaxInt = APFixedPoint::getMax(*this).getValue();
- APFloat F(FloatSema);
- APFloat::opStatus Status = F.convertFromAPInt(MaxInt, MaxInt.isSigned(),
- APFloat::rmNearestTiesToAway);
- if ((Status & APFloat::opOverflow) || !isSigned())
- return !(Status & APFloat::opOverflow);
-
- APSInt MinInt = APFixedPoint::getMin(*this).getValue();
- Status = F.convertFromAPInt(MinInt, MinInt.isSigned(),
- APFloat::rmNearestTiesToAway);
- return !(Status & APFloat::opOverflow);
-}
-
-FixedPointSemantics FixedPointSemantics::getCommonSemantics(
- const FixedPointSemantics &Other) const {
- unsigned CommonScale = std::max(getScale(), Other.getScale());
- unsigned CommonWidth =
- std::max(getIntegralBits(), Other.getIntegralBits()) + CommonScale;
-
- bool ResultIsSigned = isSigned() || Other.isSigned();
- bool ResultIsSaturated = isSaturated() || Other.isSaturated();
- bool ResultHasUnsignedPadding = false;
- if (!ResultIsSigned) {
- // Both are unsigned.
- ResultHasUnsignedPadding = hasUnsignedPadding() &&
- Other.hasUnsignedPadding() && !ResultIsSaturated;
- }
-
- // If the result is signed, add an extra bit for the sign. Otherwise, if it is
- // unsigned and has unsigned padding, we only need to add the extra padding
- // bit back if we are not saturating.
- if (ResultIsSigned || ResultHasUnsignedPadding)
- CommonWidth++;
-
- return FixedPointSemantics(CommonWidth, CommonScale, ResultIsSigned,
- ResultIsSaturated, ResultHasUnsignedPadding);
-}
-
-APFixedPoint APFixedPoint::add(const APFixedPoint &Other,
- bool *Overflow) const {
- auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics());
- APFixedPoint ConvertedThis = convert(CommonFXSema);
- APFixedPoint ConvertedOther = Other.convert(CommonFXSema);
- APSInt ThisVal = ConvertedThis.getValue();
- APSInt OtherVal = ConvertedOther.getValue();
- bool Overflowed = false;
-
- APSInt Result;
- if (CommonFXSema.isSaturated()) {
- Result = CommonFXSema.isSigned() ? ThisVal.sadd_sat(OtherVal)
- : ThisVal.uadd_sat(OtherVal);
- } else {
- Result = ThisVal.isSigned() ? ThisVal.sadd_ov(OtherVal, Overflowed)
- : ThisVal.uadd_ov(OtherVal, Overflowed);
- }
-
- if (Overflow)
- *Overflow = Overflowed;
-
- return APFixedPoint(Result, CommonFXSema);
-}
-
-APFixedPoint APFixedPoint::sub(const APFixedPoint &Other,
- bool *Overflow) const {
- auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics());
- APFixedPoint ConvertedThis = convert(CommonFXSema);
- APFixedPoint ConvertedOther = Other.convert(CommonFXSema);
- APSInt ThisVal = ConvertedThis.getValue();
- APSInt OtherVal = ConvertedOther.getValue();
- bool Overflowed = false;
-
- APSInt Result;
- if (CommonFXSema.isSaturated()) {
- Result = CommonFXSema.isSigned() ? ThisVal.ssub_sat(OtherVal)
- : ThisVal.usub_sat(OtherVal);
- } else {
- Result = ThisVal.isSigned() ? ThisVal.ssub_ov(OtherVal, Overflowed)
- : ThisVal.usub_ov(OtherVal, Overflowed);
- }
-
- if (Overflow)
- *Overflow = Overflowed;
-
- return APFixedPoint(Result, CommonFXSema);
-}
-
-APFixedPoint APFixedPoint::mul(const APFixedPoint &Other,
- bool *Overflow) const {
- auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics());
- APFixedPoint ConvertedThis = convert(CommonFXSema);
- APFixedPoint ConvertedOther = Other.convert(CommonFXSema);
- APSInt ThisVal = ConvertedThis.getValue();
- APSInt OtherVal = ConvertedOther.getValue();
- bool Overflowed = false;
-
- // Widen the LHS and RHS so we can perform a full multiplication.
- unsigned Wide = CommonFXSema.getWidth() * 2;
- if (CommonFXSema.isSigned()) {
- ThisVal = ThisVal.sextOrSelf(Wide);
- OtherVal = OtherVal.sextOrSelf(Wide);
- } else {
- ThisVal = ThisVal.zextOrSelf(Wide);
- OtherVal = OtherVal.zextOrSelf(Wide);
- }
-
- // Perform the full multiplication and downscale to get the same scale.
- //
- // Note that the right shifts here perform an implicit downwards rounding.
- // This rounding could discard bits that would technically place the result
- // outside the representable range. We interpret the spec as allowing us to
- // perform the rounding step first, avoiding the overflow case that would
- // arise.
- APSInt Result;
- if (CommonFXSema.isSigned())
- Result = ThisVal.smul_ov(OtherVal, Overflowed)
- .ashr(CommonFXSema.getScale());
- else
- Result = ThisVal.umul_ov(OtherVal, Overflowed)
- .lshr(CommonFXSema.getScale());
- assert(!Overflowed && "Full multiplication cannot overflow!");
- Result.setIsSigned(CommonFXSema.isSigned());
-
- // If our result lies outside of the representative range of the common
- // semantic, we either have overflow or saturation.
- APSInt Max = APFixedPoint::getMax(CommonFXSema).getValue()
- .extOrTrunc(Wide);
- APSInt Min = APFixedPoint::getMin(CommonFXSema).getValue()
- .extOrTrunc(Wide);
- if (CommonFXSema.isSaturated()) {
- if (Result < Min)
- Result = Min;
- else if (Result > Max)
- Result = Max;
- } else
- Overflowed = Result < Min || Result > Max;
-
- if (Overflow)
- *Overflow = Overflowed;
-
- return APFixedPoint(Result.sextOrTrunc(CommonFXSema.getWidth()),
- CommonFXSema);
-}
-
-APFixedPoint APFixedPoint::div(const APFixedPoint &Other,
- bool *Overflow) const {
- auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics());
- APFixedPoint ConvertedThis = convert(CommonFXSema);
- APFixedPoint ConvertedOther = Other.convert(CommonFXSema);
- APSInt ThisVal = ConvertedThis.getValue();
- APSInt OtherVal = ConvertedOther.getValue();
- bool Overflowed = false;
-
- // Widen the LHS and RHS so we can perform a full division.
- unsigned Wide = CommonFXSema.getWidth() * 2;
- if (CommonFXSema.isSigned()) {
- ThisVal = ThisVal.sextOrSelf(Wide);
- OtherVal = OtherVal.sextOrSelf(Wide);
- } else {
- ThisVal = ThisVal.zextOrSelf(Wide);
- OtherVal = OtherVal.zextOrSelf(Wide);
- }
-
- // Upscale to compensate for the loss of precision from division, and
- // perform the full division.
- ThisVal = ThisVal.shl(CommonFXSema.getScale());
- APSInt Result;
- if (CommonFXSema.isSigned()) {
- APInt Rem;
- APInt::sdivrem(ThisVal, OtherVal, Result, Rem);
- // If the quotient is negative and the remainder is nonzero, round
- // towards negative infinity by subtracting epsilon from the result.
- if (ThisVal.isNegative() != OtherVal.isNegative() && !Rem.isNullValue())
- Result = Result - 1;
- } else
- Result = ThisVal.udiv(OtherVal);
- Result.setIsSigned(CommonFXSema.isSigned());
-
- // If our result lies outside of the representative range of the common
- // semantic, we either have overflow or saturation.
- APSInt Max = APFixedPoint::getMax(CommonFXSema).getValue()
- .extOrTrunc(Wide);
- APSInt Min = APFixedPoint::getMin(CommonFXSema).getValue()
- .extOrTrunc(Wide);
- if (CommonFXSema.isSaturated()) {
- if (Result < Min)
- Result = Min;
- else if (Result > Max)
- Result = Max;
- } else
- Overflowed = Result < Min || Result > Max;
-
- if (Overflow)
- *Overflow = Overflowed;
-
- return APFixedPoint(Result.sextOrTrunc(CommonFXSema.getWidth()),
- CommonFXSema);
-}
-
-APFixedPoint APFixedPoint::shl(unsigned Amt, bool *Overflow) const {
- APSInt ThisVal = Val;
- bool Overflowed = false;
-
- // Widen the LHS.
- unsigned Wide = Sema.getWidth() * 2;
- if (Sema.isSigned())
- ThisVal = ThisVal.sextOrSelf(Wide);
- else
- ThisVal = ThisVal.zextOrSelf(Wide);
-
- // Clamp the shift amount at the original width, and perform the shift.
- Amt = std::min(Amt, ThisVal.getBitWidth());
- APSInt Result = ThisVal << Amt;
- Result.setIsSigned(Sema.isSigned());
-
- // If our result lies outside of the representative range of the
- // semantic, we either have overflow or saturation.
- APSInt Max = APFixedPoint::getMax(Sema).getValue().extOrTrunc(Wide);
- APSInt Min = APFixedPoint::getMin(Sema).getValue().extOrTrunc(Wide);
- if (Sema.isSaturated()) {
- if (Result < Min)
- Result = Min;
- else if (Result > Max)
- Result = Max;
- } else
- Overflowed = Result < Min || Result > Max;
-
- if (Overflow)
- *Overflow = Overflowed;
-
- return APFixedPoint(Result.sextOrTrunc(Sema.getWidth()), Sema);
-}
-
-void APFixedPoint::toString(SmallVectorImpl<char> &Str) const {
- APSInt Val = getValue();
- unsigned Scale = getScale();
-
- if (Val.isSigned() && Val.isNegative() && Val != -Val) {
- Val = -Val;
- Str.push_back('-');
- }
-
- APSInt IntPart = Val >> Scale;
-
- // Add 4 digits to hold the value after multiplying 10 (the radix)
- unsigned Width = Val.getBitWidth() + 4;
- APInt FractPart = Val.zextOrTrunc(Scale).zext(Width);
- APInt FractPartMask = APInt::getAllOnesValue(Scale).zext(Width);
- APInt RadixInt = APInt(Width, 10);
-
- IntPart.toString(Str, /*Radix=*/10);
- Str.push_back('.');
- do {
- (FractPart * RadixInt)
- .lshr(Scale)
- .toString(Str, /*Radix=*/10, Val.isSigned());
- FractPart = (FractPart * RadixInt) & FractPartMask;
- } while (FractPart != 0);
-}
-
-APFixedPoint APFixedPoint::negate(bool *Overflow) const {
- if (!isSaturated()) {
- if (Overflow)
- *Overflow =
- (!isSigned() && Val != 0) || (isSigned() && Val.isMinSignedValue());
- return APFixedPoint(-Val, Sema);
- }
-
- // We never overflow for saturation
- if (Overflow)
- *Overflow = false;
-
- if (isSigned())
- return Val.isMinSignedValue() ? getMax(Sema) : APFixedPoint(-Val, Sema);
- else
- return APFixedPoint(Sema);
-}
-
-APSInt APFixedPoint::convertToInt(unsigned DstWidth, bool DstSign,
- bool *Overflow) const {
- APSInt Result = getIntPart();
- unsigned SrcWidth = getWidth();
-
- APSInt DstMin = APSInt::getMinValue(DstWidth, !DstSign);
- APSInt DstMax = APSInt::getMaxValue(DstWidth, !DstSign);
-
- if (SrcWidth < DstWidth) {
- Result = Result.extend(DstWidth);
- } else if (SrcWidth > DstWidth) {
- DstMin = DstMin.extend(SrcWidth);
- DstMax = DstMax.extend(SrcWidth);
- }
-
- if (Overflow) {
- if (Result.isSigned() && !DstSign) {
- *Overflow = Result.isNegative() || Result.ugt(DstMax);
- } else if (Result.isUnsigned() && DstSign) {
- *Overflow = Result.ugt(DstMax);
- } else {
- *Overflow = Result < DstMin || Result > DstMax;
- }
- }
-
- Result.setIsSigned(DstSign);
- return Result.extOrTrunc(DstWidth);
-}
-
-const fltSemantics *APFixedPoint::promoteFloatSemantics(const fltSemantics *S) {
- if (S == &APFloat::BFloat())
- return &APFloat::IEEEdouble();
- else if (S == &APFloat::IEEEhalf())
- return &APFloat::IEEEsingle();
- else if (S == &APFloat::IEEEsingle())
- return &APFloat::IEEEdouble();
- else if (S == &APFloat::IEEEdouble())
- return &APFloat::IEEEquad();
- llvm_unreachable("Could not promote float type!");
-}
-
-APFloat APFixedPoint::convertToFloat(const fltSemantics &FloatSema) const {
- // For some operations, rounding mode has an effect on the result, while
- // other operations are lossless and should never result in rounding.
- // To signify which these operations are, we define two rounding modes here.
- APFloat::roundingMode RM = APFloat::rmNearestTiesToEven;
- APFloat::roundingMode LosslessRM = APFloat::rmTowardZero;
-
- // Make sure that we are operating in a type that works with this fixed-point
- // semantic.
- const fltSemantics *OpSema = &FloatSema;
- while (!Sema.fitsInFloatSemantics(*OpSema))
- OpSema = promoteFloatSemantics(OpSema);
-
- // Convert the fixed point value bits as an integer. If the floating point
- // value does not have the required precision, we will round according to the
- // given mode.
- APFloat Flt(*OpSema);
- APFloat::opStatus S = Flt.convertFromAPInt(Val, Sema.isSigned(), RM);
-
- // If we cared about checking for precision loss, we could look at this
- // status.
- (void)S;
-
- // Scale down the integer value in the float to match the correct scaling
- // factor.
- APFloat ScaleFactor(std::pow(2, -(int)Sema.getScale()));
- bool Ignored;
- ScaleFactor.convert(*OpSema, LosslessRM, &Ignored);
- Flt.multiply(ScaleFactor, LosslessRM);
-
- if (OpSema != &FloatSema)
- Flt.convert(FloatSema, RM, &Ignored);
-
- return Flt;
-}
-
-APFixedPoint APFixedPoint::getFromIntValue(const APSInt &Value,
- const FixedPointSemantics &DstFXSema,
- bool *Overflow) {
- FixedPointSemantics IntFXSema = FixedPointSemantics::GetIntegerSemantics(
- Value.getBitWidth(), Value.isSigned());
- return APFixedPoint(Value, IntFXSema).convert(DstFXSema, Overflow);
-}
-
-APFixedPoint
-APFixedPoint::getFromFloatValue(const APFloat &Value,
- const FixedPointSemantics &DstFXSema,
- bool *Overflow) {
- // For some operations, rounding mode has an effect on the result, while
- // other operations are lossless and should never result in rounding.
- // To signify which these operations are, we define two rounding modes here,
- // even though they are the same mode.
- APFloat::roundingMode RM = APFloat::rmTowardZero;
- APFloat::roundingMode LosslessRM = APFloat::rmTowardZero;
-
- const fltSemantics &FloatSema = Value.getSemantics();
-
- if (Value.isNaN()) {
- // Handle NaN immediately.
- if (Overflow)
- *Overflow = true;
- return APFixedPoint(DstFXSema);
- }
-
- // Make sure that we are operating in a type that works with this fixed-point
- // semantic.
- const fltSemantics *OpSema = &FloatSema;
- while (!DstFXSema.fitsInFloatSemantics(*OpSema))
- OpSema = promoteFloatSemantics(OpSema);
-
- APFloat Val = Value;
-
- bool Ignored;
- if (&FloatSema != OpSema)
- Val.convert(*OpSema, LosslessRM, &Ignored);
-
- // Scale up the float so that the 'fractional' part of the mantissa ends up in
- // the integer range instead. Rounding mode is irrelevant here.
- // It is fine if this overflows to infinity even for saturating types,
- // since we will use floating point comparisons to check for saturation.
- APFloat ScaleFactor(std::pow(2, DstFXSema.getScale()));
- ScaleFactor.convert(*OpSema, LosslessRM, &Ignored);
- Val.multiply(ScaleFactor, LosslessRM);
-
- // Convert to the integral representation of the value. This rounding mode
- // is significant.
- APSInt Res(DstFXSema.getWidth(), !DstFXSema.isSigned());
- Val.convertToInteger(Res, RM, &Ignored);
-
- // Round the integral value and scale back. This makes the
- // overflow calculations below work properly. If we do not round here,
- // we risk checking for overflow with a value that is outside the
- // representable range of the fixed-point semantic even though no overflow
- // would occur had we rounded first.
- ScaleFactor = APFloat(std::pow(2, -(int)DstFXSema.getScale()));
- ScaleFactor.convert(*OpSema, LosslessRM, &Ignored);
- Val.roundToIntegral(RM);
- Val.multiply(ScaleFactor, LosslessRM);
-
- // Check for overflow/saturation by checking if the floating point value
- // is outside the range representable by the fixed-point value.
- APFloat FloatMax = getMax(DstFXSema).convertToFloat(*OpSema);
- APFloat FloatMin = getMin(DstFXSema).convertToFloat(*OpSema);
- bool Overflowed = false;
- if (DstFXSema.isSaturated()) {
- if (Val > FloatMax)
- Res = getMax(DstFXSema).getValue();
- else if (Val < FloatMin)
- Res = getMin(DstFXSema).getValue();
- } else
- Overflowed = Val > FloatMax || Val < FloatMin;
-
- if (Overflow)
- *Overflow = Overflowed;
-
- return APFixedPoint(Res, DstFXSema);
-}
-
-} // namespace llvm
+//===- APFixedPoint.cpp - Fixed point constant handling ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// Defines the implementation for the fixed point number interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/APFixedPoint.h"
+#include "llvm/ADT/APFloat.h"
+
+namespace llvm {
+
+APFixedPoint APFixedPoint::convert(const FixedPointSemantics &DstSema,
+ bool *Overflow) const {
+ APSInt NewVal = Val;
+ unsigned DstWidth = DstSema.getWidth();
+ unsigned DstScale = DstSema.getScale();
+ bool Upscaling = DstScale > getScale();
+ if (Overflow)
+ *Overflow = false;
+
+ if (Upscaling) {
+ NewVal = NewVal.extend(NewVal.getBitWidth() + DstScale - getScale());
+ NewVal <<= (DstScale - getScale());
+ } else {
+ NewVal >>= (getScale() - DstScale);
+ }
+
+ auto Mask = APInt::getBitsSetFrom(
+ NewVal.getBitWidth(),
+ std::min(DstScale + DstSema.getIntegralBits(), NewVal.getBitWidth()));
+ APInt Masked(NewVal & Mask);
+
+ // Change in the bits above the sign
+ if (!(Masked == Mask || Masked == 0)) {
+ // Found overflow in the bits above the sign
+ if (DstSema.isSaturated())
+ NewVal = NewVal.isNegative() ? Mask : ~Mask;
+ else if (Overflow)
+ *Overflow = true;
+ }
+
+ // If the dst semantics are unsigned, but our value is signed and negative, we
+ // clamp to zero.
+ if (!DstSema.isSigned() && NewVal.isSigned() && NewVal.isNegative()) {
+ // Found negative overflow for unsigned result
+ if (DstSema.isSaturated())
+ NewVal = 0;
+ else if (Overflow)
+ *Overflow = true;
+ }
+
+ NewVal = NewVal.extOrTrunc(DstWidth);
+ NewVal.setIsSigned(DstSema.isSigned());
+ return APFixedPoint(NewVal, DstSema);
+}
+
+int APFixedPoint::compare(const APFixedPoint &Other) const {
+ APSInt ThisVal = getValue();
+ APSInt OtherVal = Other.getValue();
+ bool ThisSigned = Val.isSigned();
+ bool OtherSigned = OtherVal.isSigned();
+ unsigned OtherScale = Other.getScale();
+ unsigned OtherWidth = OtherVal.getBitWidth();
+
+ unsigned CommonWidth = std::max(Val.getBitWidth(), OtherWidth);
+
+ // Prevent overflow in the event the widths are the same but the scales differ
+ CommonWidth += getScale() >= OtherScale ? getScale() - OtherScale
+ : OtherScale - getScale();
+
+ ThisVal = ThisVal.extOrTrunc(CommonWidth);
+ OtherVal = OtherVal.extOrTrunc(CommonWidth);
+
+ unsigned CommonScale = std::max(getScale(), OtherScale);
+ ThisVal = ThisVal.shl(CommonScale - getScale());
+ OtherVal = OtherVal.shl(CommonScale - OtherScale);
+
+ if (ThisSigned && OtherSigned) {
+ if (ThisVal.sgt(OtherVal))
+ return 1;
+ else if (ThisVal.slt(OtherVal))
+ return -1;
+ } else if (!ThisSigned && !OtherSigned) {
+ if (ThisVal.ugt(OtherVal))
+ return 1;
+ else if (ThisVal.ult(OtherVal))
+ return -1;
+ } else if (ThisSigned && !OtherSigned) {
+ if (ThisVal.isSignBitSet())
+ return -1;
+ else if (ThisVal.ugt(OtherVal))
+ return 1;
+ else if (ThisVal.ult(OtherVal))
+ return -1;
+ } else {
+ // !ThisSigned && OtherSigned
+ if (OtherVal.isSignBitSet())
+ return 1;
+ else if (ThisVal.ugt(OtherVal))
+ return 1;
+ else if (ThisVal.ult(OtherVal))
+ return -1;
+ }
+
+ return 0;
+}
+
+APFixedPoint APFixedPoint::getMax(const FixedPointSemantics &Sema) {
+ bool IsUnsigned = !Sema.isSigned();
+ auto Val = APSInt::getMaxValue(Sema.getWidth(), IsUnsigned);
+ if (IsUnsigned && Sema.hasUnsignedPadding())
+ Val = Val.lshr(1);
+ return APFixedPoint(Val, Sema);
+}
+
+APFixedPoint APFixedPoint::getMin(const FixedPointSemantics &Sema) {
+ auto Val = APSInt::getMinValue(Sema.getWidth(), !Sema.isSigned());
+ return APFixedPoint(Val, Sema);
+}
+
+bool FixedPointSemantics::fitsInFloatSemantics(
+ const fltSemantics &FloatSema) const {
+ // A fixed point semantic fits in a floating point semantic if the maximum
+ // and minimum values as integers of the fixed point semantic can fit in the
+ // floating point semantic.
+
+ // If these values do not fit, then a floating point rescaling of the true
+ // maximum/minimum value will not fit either, so the floating point semantic
+ // cannot be used to perform such a rescaling.
+
+ APSInt MaxInt = APFixedPoint::getMax(*this).getValue();
+ APFloat F(FloatSema);
+ APFloat::opStatus Status = F.convertFromAPInt(MaxInt, MaxInt.isSigned(),
+ APFloat::rmNearestTiesToAway);
+ if ((Status & APFloat::opOverflow) || !isSigned())
+ return !(Status & APFloat::opOverflow);
+
+ APSInt MinInt = APFixedPoint::getMin(*this).getValue();
+ Status = F.convertFromAPInt(MinInt, MinInt.isSigned(),
+ APFloat::rmNearestTiesToAway);
+ return !(Status & APFloat::opOverflow);
+}
+
+FixedPointSemantics FixedPointSemantics::getCommonSemantics(
+ const FixedPointSemantics &Other) const {
+ unsigned CommonScale = std::max(getScale(), Other.getScale());
+ unsigned CommonWidth =
+ std::max(getIntegralBits(), Other.getIntegralBits()) + CommonScale;
+
+ bool ResultIsSigned = isSigned() || Other.isSigned();
+ bool ResultIsSaturated = isSaturated() || Other.isSaturated();
+ bool ResultHasUnsignedPadding = false;
+ if (!ResultIsSigned) {
+ // Both are unsigned.
+ ResultHasUnsignedPadding = hasUnsignedPadding() &&
+ Other.hasUnsignedPadding() && !ResultIsSaturated;
+ }
+
+ // If the result is signed, add an extra bit for the sign. Otherwise, if it is
+ // unsigned and has unsigned padding, we only need to add the extra padding
+ // bit back if we are not saturating.
+ if (ResultIsSigned || ResultHasUnsignedPadding)
+ CommonWidth++;
+
+ return FixedPointSemantics(CommonWidth, CommonScale, ResultIsSigned,
+ ResultIsSaturated, ResultHasUnsignedPadding);
+}
+
+APFixedPoint APFixedPoint::add(const APFixedPoint &Other,
+ bool *Overflow) const {
+ auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics());
+ APFixedPoint ConvertedThis = convert(CommonFXSema);
+ APFixedPoint ConvertedOther = Other.convert(CommonFXSema);
+ APSInt ThisVal = ConvertedThis.getValue();
+ APSInt OtherVal = ConvertedOther.getValue();
+ bool Overflowed = false;
+
+ APSInt Result;
+ if (CommonFXSema.isSaturated()) {
+ Result = CommonFXSema.isSigned() ? ThisVal.sadd_sat(OtherVal)
+ : ThisVal.uadd_sat(OtherVal);
+ } else {
+ Result = ThisVal.isSigned() ? ThisVal.sadd_ov(OtherVal, Overflowed)
+ : ThisVal.uadd_ov(OtherVal, Overflowed);
+ }
+
+ if (Overflow)
+ *Overflow = Overflowed;
+
+ return APFixedPoint(Result, CommonFXSema);
+}
+
+APFixedPoint APFixedPoint::sub(const APFixedPoint &Other,
+ bool *Overflow) const {
+ auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics());
+ APFixedPoint ConvertedThis = convert(CommonFXSema);
+ APFixedPoint ConvertedOther = Other.convert(CommonFXSema);
+ APSInt ThisVal = ConvertedThis.getValue();
+ APSInt OtherVal = ConvertedOther.getValue();
+ bool Overflowed = false;
+
+ APSInt Result;
+ if (CommonFXSema.isSaturated()) {
+ Result = CommonFXSema.isSigned() ? ThisVal.ssub_sat(OtherVal)
+ : ThisVal.usub_sat(OtherVal);
+ } else {
+ Result = ThisVal.isSigned() ? ThisVal.ssub_ov(OtherVal, Overflowed)
+ : ThisVal.usub_ov(OtherVal, Overflowed);
+ }
+
+ if (Overflow)
+ *Overflow = Overflowed;
+
+ return APFixedPoint(Result, CommonFXSema);
+}
+
+APFixedPoint APFixedPoint::mul(const APFixedPoint &Other,
+ bool *Overflow) const {
+ auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics());
+ APFixedPoint ConvertedThis = convert(CommonFXSema);
+ APFixedPoint ConvertedOther = Other.convert(CommonFXSema);
+ APSInt ThisVal = ConvertedThis.getValue();
+ APSInt OtherVal = ConvertedOther.getValue();
+ bool Overflowed = false;
+
+ // Widen the LHS and RHS so we can perform a full multiplication.
+ unsigned Wide = CommonFXSema.getWidth() * 2;
+ if (CommonFXSema.isSigned()) {
+ ThisVal = ThisVal.sextOrSelf(Wide);
+ OtherVal = OtherVal.sextOrSelf(Wide);
+ } else {
+ ThisVal = ThisVal.zextOrSelf(Wide);
+ OtherVal = OtherVal.zextOrSelf(Wide);
+ }
+
+ // Perform the full multiplication and downscale to get the same scale.
+ //
+ // Note that the right shifts here perform an implicit downwards rounding.
+ // This rounding could discard bits that would technically place the result
+ // outside the representable range. We interpret the spec as allowing us to
+ // perform the rounding step first, avoiding the overflow case that would
+ // arise.
+ APSInt Result;
+ if (CommonFXSema.isSigned())
+ Result = ThisVal.smul_ov(OtherVal, Overflowed)
+ .ashr(CommonFXSema.getScale());
+ else
+ Result = ThisVal.umul_ov(OtherVal, Overflowed)
+ .lshr(CommonFXSema.getScale());
+ assert(!Overflowed && "Full multiplication cannot overflow!");
+ Result.setIsSigned(CommonFXSema.isSigned());
+
+ // If our result lies outside of the representative range of the common
+ // semantic, we either have overflow or saturation.
+ APSInt Max = APFixedPoint::getMax(CommonFXSema).getValue()
+ .extOrTrunc(Wide);
+ APSInt Min = APFixedPoint::getMin(CommonFXSema).getValue()
+ .extOrTrunc(Wide);
+ if (CommonFXSema.isSaturated()) {
+ if (Result < Min)
+ Result = Min;
+ else if (Result > Max)
+ Result = Max;
+ } else
+ Overflowed = Result < Min || Result > Max;
+
+ if (Overflow)
+ *Overflow = Overflowed;
+
+ return APFixedPoint(Result.sextOrTrunc(CommonFXSema.getWidth()),
+ CommonFXSema);
+}
+
+APFixedPoint APFixedPoint::div(const APFixedPoint &Other,
+ bool *Overflow) const {
+ auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics());
+ APFixedPoint ConvertedThis = convert(CommonFXSema);
+ APFixedPoint ConvertedOther = Other.convert(CommonFXSema);
+ APSInt ThisVal = ConvertedThis.getValue();
+ APSInt OtherVal = ConvertedOther.getValue();
+ bool Overflowed = false;
+
+ // Widen the LHS and RHS so we can perform a full division.
+ unsigned Wide = CommonFXSema.getWidth() * 2;
+ if (CommonFXSema.isSigned()) {
+ ThisVal = ThisVal.sextOrSelf(Wide);
+ OtherVal = OtherVal.sextOrSelf(Wide);
+ } else {
+ ThisVal = ThisVal.zextOrSelf(Wide);
+ OtherVal = OtherVal.zextOrSelf(Wide);
+ }
+
+ // Upscale to compensate for the loss of precision from division, and
+ // perform the full division.
+ ThisVal = ThisVal.shl(CommonFXSema.getScale());
+ APSInt Result;
+ if (CommonFXSema.isSigned()) {
+ APInt Rem;
+ APInt::sdivrem(ThisVal, OtherVal, Result, Rem);
+ // If the quotient is negative and the remainder is nonzero, round
+ // towards negative infinity by subtracting epsilon from the result.
+ if (ThisVal.isNegative() != OtherVal.isNegative() && !Rem.isNullValue())
+ Result = Result - 1;
+ } else
+ Result = ThisVal.udiv(OtherVal);
+ Result.setIsSigned(CommonFXSema.isSigned());
+
+ // If our result lies outside of the representative range of the common
+ // semantic, we either have overflow or saturation.
+ APSInt Max = APFixedPoint::getMax(CommonFXSema).getValue()
+ .extOrTrunc(Wide);
+ APSInt Min = APFixedPoint::getMin(CommonFXSema).getValue()
+ .extOrTrunc(Wide);
+ if (CommonFXSema.isSaturated()) {
+ if (Result < Min)
+ Result = Min;
+ else if (Result > Max)
+ Result = Max;
+ } else
+ Overflowed = Result < Min || Result > Max;
+
+ if (Overflow)
+ *Overflow = Overflowed;
+
+ return APFixedPoint(Result.sextOrTrunc(CommonFXSema.getWidth()),
+ CommonFXSema);
+}
+
+APFixedPoint APFixedPoint::shl(unsigned Amt, bool *Overflow) const {
+ APSInt ThisVal = Val;
+ bool Overflowed = false;
+
+ // Widen the LHS.
+ unsigned Wide = Sema.getWidth() * 2;
+ if (Sema.isSigned())
+ ThisVal = ThisVal.sextOrSelf(Wide);
+ else
+ ThisVal = ThisVal.zextOrSelf(Wide);
+
+ // Clamp the shift amount at the original width, and perform the shift.
+ Amt = std::min(Amt, ThisVal.getBitWidth());
+ APSInt Result = ThisVal << Amt;
+ Result.setIsSigned(Sema.isSigned());
+
+ // If our result lies outside of the representative range of the
+ // semantic, we either have overflow or saturation.
+ APSInt Max = APFixedPoint::getMax(Sema).getValue().extOrTrunc(Wide);
+ APSInt Min = APFixedPoint::getMin(Sema).getValue().extOrTrunc(Wide);
+ if (Sema.isSaturated()) {
+ if (Result < Min)
+ Result = Min;
+ else if (Result > Max)
+ Result = Max;
+ } else
+ Overflowed = Result < Min || Result > Max;
+
+ if (Overflow)
+ *Overflow = Overflowed;
+
+ return APFixedPoint(Result.sextOrTrunc(Sema.getWidth()), Sema);
+}
+
+void APFixedPoint::toString(SmallVectorImpl<char> &Str) const {
+ APSInt Val = getValue();
+ unsigned Scale = getScale();
+
+ if (Val.isSigned() && Val.isNegative() && Val != -Val) {
+ Val = -Val;
+ Str.push_back('-');
+ }
+
+ APSInt IntPart = Val >> Scale;
+
+ // Add 4 digits to hold the value after multiplying 10 (the radix)
+ unsigned Width = Val.getBitWidth() + 4;
+ APInt FractPart = Val.zextOrTrunc(Scale).zext(Width);
+ APInt FractPartMask = APInt::getAllOnesValue(Scale).zext(Width);
+ APInt RadixInt = APInt(Width, 10);
+
+ IntPart.toString(Str, /*Radix=*/10);
+ Str.push_back('.');
+ do {
+ (FractPart * RadixInt)
+ .lshr(Scale)
+ .toString(Str, /*Radix=*/10, Val.isSigned());
+ FractPart = (FractPart * RadixInt) & FractPartMask;
+ } while (FractPart != 0);
+}
+
+APFixedPoint APFixedPoint::negate(bool *Overflow) const {
+ if (!isSaturated()) {
+ if (Overflow)
+ *Overflow =
+ (!isSigned() && Val != 0) || (isSigned() && Val.isMinSignedValue());
+ return APFixedPoint(-Val, Sema);
+ }
+
+ // We never overflow for saturation
+ if (Overflow)
+ *Overflow = false;
+
+ if (isSigned())
+ return Val.isMinSignedValue() ? getMax(Sema) : APFixedPoint(-Val, Sema);
+ else
+ return APFixedPoint(Sema);
+}
+
+APSInt APFixedPoint::convertToInt(unsigned DstWidth, bool DstSign,
+ bool *Overflow) const {
+ APSInt Result = getIntPart();
+ unsigned SrcWidth = getWidth();
+
+ APSInt DstMin = APSInt::getMinValue(DstWidth, !DstSign);
+ APSInt DstMax = APSInt::getMaxValue(DstWidth, !DstSign);
+
+ if (SrcWidth < DstWidth) {
+ Result = Result.extend(DstWidth);
+ } else if (SrcWidth > DstWidth) {
+ DstMin = DstMin.extend(SrcWidth);
+ DstMax = DstMax.extend(SrcWidth);
+ }
+
+ if (Overflow) {
+ if (Result.isSigned() && !DstSign) {
+ *Overflow = Result.isNegative() || Result.ugt(DstMax);
+ } else if (Result.isUnsigned() && DstSign) {
+ *Overflow = Result.ugt(DstMax);
+ } else {
+ *Overflow = Result < DstMin || Result > DstMax;
+ }
+ }
+
+ Result.setIsSigned(DstSign);
+ return Result.extOrTrunc(DstWidth);
+}
+
+const fltSemantics *APFixedPoint::promoteFloatSemantics(const fltSemantics *S) {
+ if (S == &APFloat::BFloat())
+ return &APFloat::IEEEdouble();
+ else if (S == &APFloat::IEEEhalf())
+ return &APFloat::IEEEsingle();
+ else if (S == &APFloat::IEEEsingle())
+ return &APFloat::IEEEdouble();
+ else if (S == &APFloat::IEEEdouble())
+ return &APFloat::IEEEquad();
+ llvm_unreachable("Could not promote float type!");
+}
+
+APFloat APFixedPoint::convertToFloat(const fltSemantics &FloatSema) const {
+ // For some operations, rounding mode has an effect on the result, while
+ // other operations are lossless and should never result in rounding.
+ // To signify which these operations are, we define two rounding modes here.
+ APFloat::roundingMode RM = APFloat::rmNearestTiesToEven;
+ APFloat::roundingMode LosslessRM = APFloat::rmTowardZero;
+
+ // Make sure that we are operating in a type that works with this fixed-point
+ // semantic.
+ const fltSemantics *OpSema = &FloatSema;
+ while (!Sema.fitsInFloatSemantics(*OpSema))
+ OpSema = promoteFloatSemantics(OpSema);
+
+ // Convert the fixed point value bits as an integer. If the floating point
+ // value does not have the required precision, we will round according to the
+ // given mode.
+ APFloat Flt(*OpSema);
+ APFloat::opStatus S = Flt.convertFromAPInt(Val, Sema.isSigned(), RM);
+
+ // If we cared about checking for precision loss, we could look at this
+ // status.
+ (void)S;
+
+ // Scale down the integer value in the float to match the correct scaling
+ // factor.
+ APFloat ScaleFactor(std::pow(2, -(int)Sema.getScale()));
+ bool Ignored;
+ ScaleFactor.convert(*OpSema, LosslessRM, &Ignored);
+ Flt.multiply(ScaleFactor, LosslessRM);
+
+ if (OpSema != &FloatSema)
+ Flt.convert(FloatSema, RM, &Ignored);
+
+ return Flt;
+}
+
+APFixedPoint APFixedPoint::getFromIntValue(const APSInt &Value,
+ const FixedPointSemantics &DstFXSema,
+ bool *Overflow) {
+ FixedPointSemantics IntFXSema = FixedPointSemantics::GetIntegerSemantics(
+ Value.getBitWidth(), Value.isSigned());
+ return APFixedPoint(Value, IntFXSema).convert(DstFXSema, Overflow);
+}
+
+APFixedPoint
+APFixedPoint::getFromFloatValue(const APFloat &Value,
+ const FixedPointSemantics &DstFXSema,
+ bool *Overflow) {
+ // For some operations, rounding mode has an effect on the result, while
+ // other operations are lossless and should never result in rounding.
+ // To signify which these operations are, we define two rounding modes here,
+ // even though they are the same mode.
+ APFloat::roundingMode RM = APFloat::rmTowardZero;
+ APFloat::roundingMode LosslessRM = APFloat::rmTowardZero;
+
+ const fltSemantics &FloatSema = Value.getSemantics();
+
+ if (Value.isNaN()) {
+ // Handle NaN immediately.
+ if (Overflow)
+ *Overflow = true;
+ return APFixedPoint(DstFXSema);
+ }
+
+ // Make sure that we are operating in a type that works with this fixed-point
+ // semantic.
+ const fltSemantics *OpSema = &FloatSema;
+ while (!DstFXSema.fitsInFloatSemantics(*OpSema))
+ OpSema = promoteFloatSemantics(OpSema);
+
+ APFloat Val = Value;
+
+ bool Ignored;
+ if (&FloatSema != OpSema)
+ Val.convert(*OpSema, LosslessRM, &Ignored);
+
+ // Scale up the float so that the 'fractional' part of the mantissa ends up in
+ // the integer range instead. Rounding mode is irrelevant here.
+ // It is fine if this overflows to infinity even for saturating types,
+ // since we will use floating point comparisons to check for saturation.
+ APFloat ScaleFactor(std::pow(2, DstFXSema.getScale()));
+ ScaleFactor.convert(*OpSema, LosslessRM, &Ignored);
+ Val.multiply(ScaleFactor, LosslessRM);
+
+ // Convert to the integral representation of the value. This rounding mode
+ // is significant.
+ APSInt Res(DstFXSema.getWidth(), !DstFXSema.isSigned());
+ Val.convertToInteger(Res, RM, &Ignored);
+
+ // Round the integral value and scale back. This makes the
+ // overflow calculations below work properly. If we do not round here,
+ // we risk checking for overflow with a value that is outside the
+ // representable range of the fixed-point semantic even though no overflow
+ // would occur had we rounded first.
+ ScaleFactor = APFloat(std::pow(2, -(int)DstFXSema.getScale()));
+ ScaleFactor.convert(*OpSema, LosslessRM, &Ignored);
+ Val.roundToIntegral(RM);
+ Val.multiply(ScaleFactor, LosslessRM);
+
+ // Check for overflow/saturation by checking if the floating point value
+ // is outside the range representable by the fixed-point value.
+ APFloat FloatMax = getMax(DstFXSema).convertToFloat(*OpSema);
+ APFloat FloatMin = getMin(DstFXSema).convertToFloat(*OpSema);
+ bool Overflowed = false;
+ if (DstFXSema.isSaturated()) {
+ if (Val > FloatMax)
+ Res = getMax(DstFXSema).getValue();
+ else if (Val < FloatMin)
+ Res = getMin(DstFXSema).getValue();
+ } else
+ Overflowed = Val > FloatMax || Val < FloatMin;
+
+ if (Overflow)
+ *Overflow = Overflowed;
+
+ return APFixedPoint(Res, DstFXSema);
+}
+
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/Support/APFloat.cpp b/contrib/libs/llvm12/lib/Support/APFloat.cpp
index 59961d9bab..5dea98ee39 100644
--- a/contrib/libs/llvm12/lib/Support/APFloat.cpp
+++ b/contrib/libs/llvm12/lib/Support/APFloat.cpp
@@ -755,7 +755,7 @@ void IEEEFloat::copySignificand(const IEEEFloat &rhs) {
void IEEEFloat::makeNaN(bool SNaN, bool Negative, const APInt *fill) {
category = fcNaN;
sign = Negative;
- exponent = exponentNaN();
+ exponent = exponentNaN();
integerPart *significand = significandParts();
unsigned numParts = partCount();
@@ -842,7 +842,7 @@ bool IEEEFloat::isSignificandAllOnes() const {
// Test if the significand excluding the integral bit is all ones. This allows
// us to test for binade boundaries.
const integerPart *Parts = significandParts();
- const unsigned PartCount = partCountForBits(semantics->precision);
+ const unsigned PartCount = partCountForBits(semantics->precision);
for (unsigned i = 0; i < PartCount - 1; i++)
if (~Parts[i])
return false;
@@ -850,8 +850,8 @@ bool IEEEFloat::isSignificandAllOnes() const {
// Set the unused high bits to all ones when we compare.
const unsigned NumHighBits =
PartCount*integerPartWidth - semantics->precision + 1;
- assert(NumHighBits <= integerPartWidth && NumHighBits > 0 &&
- "Can not have more high bits to fill than integerPartWidth");
+ assert(NumHighBits <= integerPartWidth && NumHighBits > 0 &&
+ "Can not have more high bits to fill than integerPartWidth");
const integerPart HighBitFill =
~integerPart(0) << (integerPartWidth - NumHighBits);
if (~(Parts[PartCount - 1] | HighBitFill))
@@ -864,16 +864,16 @@ bool IEEEFloat::isSignificandAllZeros() const {
// Test if the significand excluding the integral bit is all zeros. This
// allows us to test for binade boundaries.
const integerPart *Parts = significandParts();
- const unsigned PartCount = partCountForBits(semantics->precision);
+ const unsigned PartCount = partCountForBits(semantics->precision);
for (unsigned i = 0; i < PartCount - 1; i++)
if (Parts[i])
return false;
- // Compute how many bits are used in the final word.
+ // Compute how many bits are used in the final word.
const unsigned NumHighBits =
PartCount*integerPartWidth - semantics->precision + 1;
- assert(NumHighBits < integerPartWidth && "Can not have more high bits to "
+ assert(NumHighBits < integerPartWidth && "Can not have more high bits to "
"clear than integerPartWidth");
const integerPart HighBitMask = ~integerPart(0) >> NumHighBits;
@@ -927,7 +927,7 @@ IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics, integerPart value) {
IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics) {
initialize(&ourSemantics);
- makeZero(false);
+ makeZero(false);
}
// Delegate to the previous constructor, because later copy constructor may
@@ -2243,14 +2243,14 @@ IEEEFloat::opStatus IEEEFloat::convert(const fltSemantics &toSemantics,
if (!X86SpecialNan && semantics == &semX87DoubleExtended)
APInt::tcSetBit(significandParts(), semantics->precision - 1);
- // Convert of sNaN creates qNaN and raises an exception (invalid op).
- // This also guarantees that a sNaN does not become Inf on a truncation
- // that loses all payload bits.
- if (isSignaling()) {
- makeQuiet();
- fs = opInvalidOp;
- } else {
- fs = opOK;
+ // Convert of sNaN creates qNaN and raises an exception (invalid op).
+ // This also guarantees that a sNaN does not become Inf on a truncation
+ // that loses all payload bits.
+ if (isSignaling()) {
+ makeQuiet();
+ fs = opInvalidOp;
+ } else {
+ fs = opOK;
}
} else {
*losesInfo = false;
@@ -3384,13 +3384,13 @@ void IEEEFloat::initFromF80LongDoubleAPInt(const APInt &api) {
sign = static_cast<unsigned int>(i2>>15);
if (myexponent == 0 && mysignificand == 0) {
- makeZero(sign);
+ makeZero(sign);
} else if (myexponent==0x7fff && mysignificand==0x8000000000000000ULL) {
- makeInf(sign);
+ makeInf(sign);
} else if ((myexponent == 0x7fff && mysignificand != 0x8000000000000000ULL) ||
(myexponent != 0x7fff && myexponent != 0 && myintegerbit == 0)) {
category = fcNaN;
- exponent = exponentNaN();
+ exponent = exponentNaN();
significandParts()[0] = mysignificand;
significandParts()[1] = 0;
} else {
@@ -3441,14 +3441,14 @@ void IEEEFloat::initFromQuadrupleAPInt(const APInt &api) {
sign = static_cast<unsigned int>(i2>>63);
if (myexponent==0 &&
(mysignificand==0 && mysignificand2==0)) {
- makeZero(sign);
+ makeZero(sign);
} else if (myexponent==0x7fff &&
(mysignificand==0 && mysignificand2==0)) {
- makeInf(sign);
+ makeInf(sign);
} else if (myexponent==0x7fff &&
(mysignificand!=0 || mysignificand2 !=0)) {
category = fcNaN;
- exponent = exponentNaN();
+ exponent = exponentNaN();
significandParts()[0] = mysignificand;
significandParts()[1] = mysignificand2;
} else {
@@ -3474,12 +3474,12 @@ void IEEEFloat::initFromDoubleAPInt(const APInt &api) {
sign = static_cast<unsigned int>(i>>63);
if (myexponent==0 && mysignificand==0) {
- makeZero(sign);
+ makeZero(sign);
} else if (myexponent==0x7ff && mysignificand==0) {
- makeInf(sign);
+ makeInf(sign);
} else if (myexponent==0x7ff && mysignificand!=0) {
category = fcNaN;
- exponent = exponentNaN();
+ exponent = exponentNaN();
*significandParts() = mysignificand;
} else {
category = fcNormal;
@@ -3503,12 +3503,12 @@ void IEEEFloat::initFromFloatAPInt(const APInt &api) {
sign = i >> 31;
if (myexponent==0 && mysignificand==0) {
- makeZero(sign);
+ makeZero(sign);
} else if (myexponent==0xff && mysignificand==0) {
- makeInf(sign);
+ makeInf(sign);
} else if (myexponent==0xff && mysignificand!=0) {
category = fcNaN;
- exponent = exponentNaN();
+ exponent = exponentNaN();
*significandParts() = mysignificand;
} else {
category = fcNormal;
@@ -3532,12 +3532,12 @@ void IEEEFloat::initFromBFloatAPInt(const APInt &api) {
sign = i >> 15;
if (myexponent == 0 && mysignificand == 0) {
- makeZero(sign);
+ makeZero(sign);
} else if (myexponent == 0xff && mysignificand == 0) {
- makeInf(sign);
+ makeInf(sign);
} else if (myexponent == 0xff && mysignificand != 0) {
category = fcNaN;
- exponent = exponentNaN();
+ exponent = exponentNaN();
*significandParts() = mysignificand;
} else {
category = fcNormal;
@@ -3561,12 +3561,12 @@ void IEEEFloat::initFromHalfAPInt(const APInt &api) {
sign = i >> 15;
if (myexponent==0 && mysignificand==0) {
- makeZero(sign);
+ makeZero(sign);
} else if (myexponent==0x1f && mysignificand==0) {
- makeInf(sign);
+ makeInf(sign);
} else if (myexponent==0x1f && mysignificand!=0) {
category = fcNaN;
- exponent = exponentNaN();
+ exponent = exponentNaN();
*significandParts() = mysignificand;
} else {
category = fcNormal;
@@ -4124,29 +4124,29 @@ IEEEFloat::opStatus IEEEFloat::next(bool nextDown) {
return result;
}
-APFloatBase::ExponentType IEEEFloat::exponentNaN() const {
- return semantics->maxExponent + 1;
-}
-
-APFloatBase::ExponentType IEEEFloat::exponentInf() const {
- return semantics->maxExponent + 1;
-}
-
-APFloatBase::ExponentType IEEEFloat::exponentZero() const {
- return semantics->minExponent - 1;
-}
-
+APFloatBase::ExponentType IEEEFloat::exponentNaN() const {
+ return semantics->maxExponent + 1;
+}
+
+APFloatBase::ExponentType IEEEFloat::exponentInf() const {
+ return semantics->maxExponent + 1;
+}
+
+APFloatBase::ExponentType IEEEFloat::exponentZero() const {
+ return semantics->minExponent - 1;
+}
+
void IEEEFloat::makeInf(bool Negative) {
category = fcInfinity;
sign = Negative;
- exponent = exponentInf();
+ exponent = exponentInf();
APInt::tcSet(significandParts(), 0, partCount());
}
void IEEEFloat::makeZero(bool Negative) {
category = fcZero;
sign = Negative;
- exponent = exponentZero();
+ exponent = exponentZero();
APInt::tcSet(significandParts(), 0, partCount());
}
@@ -4874,6 +4874,6 @@ APFloat::opStatus APFloat::convertToInteger(APSInt &result,
return status;
}
-} // namespace llvm
+} // namespace llvm
#undef APFLOAT_DISPATCH_ON_SEMANTICS
diff --git a/contrib/libs/llvm12/lib/Support/APInt.cpp b/contrib/libs/llvm12/lib/Support/APInt.cpp
index 895e530a59..12ceb2df11 100644
--- a/contrib/libs/llvm12/lib/Support/APInt.cpp
+++ b/contrib/libs/llvm12/lib/Support/APInt.cpp
@@ -338,7 +338,7 @@ void APInt::flipAllBitsSlowCase() {
/// Toggles a given bit to its opposite value.
void APInt::flipBit(unsigned bitPosition) {
assert(bitPosition < BitWidth && "Out of the bit-width range!");
- setBitVal(bitPosition, !(*this)[bitPosition]);
+ setBitVal(bitPosition, !(*this)[bitPosition]);
}
void APInt::insertBits(const APInt &subBits, unsigned bitPosition) {
@@ -392,8 +392,8 @@ void APInt::insertBits(const APInt &subBits, unsigned bitPosition) {
// General case - set/clear individual bits in dst based on src.
// TODO - there is scope for optimization here, but at the moment this code
// path is barely used so prefer readability over performance.
- for (unsigned i = 0; i != subBitWidth; ++i)
- setBitVal(bitPosition + i, subBits[i]);
+ for (unsigned i = 0; i != subBitWidth; ++i)
+ setBitVal(bitPosition + i, subBits[i]);
}
void APInt::insertBits(uint64_t subBits, unsigned bitPosition, unsigned numBits) {
@@ -961,12 +961,12 @@ APInt APInt::sextOrTrunc(unsigned width) const {
return *this;
}
-APInt APInt::truncOrSelf(unsigned width) const {
- if (BitWidth > width)
- return trunc(width);
- return *this;
-}
-
+APInt APInt::truncOrSelf(unsigned width) const {
+ if (BitWidth > width)
+ return trunc(width);
+ return *this;
+}
+
APInt APInt::zextOrSelf(unsigned width) const {
if (BitWidth < width)
return zext(width);
diff --git a/contrib/libs/llvm12/lib/Support/ARMAttributeParser.cpp b/contrib/libs/llvm12/lib/Support/ARMAttributeParser.cpp
index 5076d8548e..459691923a 100644
--- a/contrib/libs/llvm12/lib/Support/ARMAttributeParser.cpp
+++ b/contrib/libs/llvm12/lib/Support/ARMAttributeParser.cpp
@@ -113,7 +113,7 @@ Error ARMAttributeParser::ARM_ISA_use(AttrType tag) {
}
Error ARMAttributeParser::THUMB_ISA_use(AttrType tag) {
- static const char *strings[] = {"Not Permitted", "Thumb-1", "Thumb-2", "Permitted"};
+ static const char *strings[] = {"Not Permitted", "Thumb-1", "Thumb-2", "Permitted"};
return parseStringAttribute("THUMB_ISA_use", tag, makeArrayRef(strings));
}
diff --git a/contrib/libs/llvm12/lib/Support/ARMTargetParser.cpp b/contrib/libs/llvm12/lib/Support/ARMTargetParser.cpp
index 028fb5d413..eb425cbb1d 100644
--- a/contrib/libs/llvm12/lib/Support/ARMTargetParser.cpp
+++ b/contrib/libs/llvm12/lib/Support/ARMTargetParser.cpp
@@ -76,7 +76,7 @@ unsigned ARM::parseArchVersion(StringRef Arch) {
case ArchKind::ARMV8_4A:
case ArchKind::ARMV8_5A:
case ArchKind::ARMV8_6A:
- case ArchKind::ARMV8_7A:
+ case ArchKind::ARMV8_7A:
case ArchKind::ARMV8R:
case ArchKind::ARMV8MBaseline:
case ArchKind::ARMV8MMainline:
@@ -112,7 +112,7 @@ ARM::ProfileKind ARM::parseArchProfile(StringRef Arch) {
case ArchKind::ARMV8_4A:
case ArchKind::ARMV8_5A:
case ArchKind::ARMV8_6A:
- case ArchKind::ARMV8_7A:
+ case ArchKind::ARMV8_7A:
return ProfileKind::A;
case ArchKind::ARMV2:
case ArchKind::ARMV2A:
@@ -156,7 +156,7 @@ StringRef ARM::getArchSynonym(StringRef Arch) {
.Case("v8.4a", "v8.4-a")
.Case("v8.5a", "v8.5-a")
.Case("v8.6a", "v8.6-a")
- .Case("v8.7a", "v8.7-a")
+ .Case("v8.7a", "v8.7-a")
.Case("v8r", "v8-r")
.Case("v8m.base", "v8-m.base")
.Case("v8m.main", "v8-m.main")
@@ -258,7 +258,7 @@ ARM::ISAKind ARM::parseArchISA(StringRef Arch) {
unsigned ARM::parseFPU(StringRef FPU) {
StringRef Syn = getFPUSynonym(FPU);
- for (const auto &F : FPUNames) {
+ for (const auto &F : FPUNames) {
if (Syn == F.getName())
return F.ID;
}
@@ -283,8 +283,8 @@ StringRef ARM::getCanonicalArchName(StringRef Arch) {
// Begins with "arm" / "thumb", move past it.
if (A.startswith("arm64_32"))
offset = 8;
- else if (A.startswith("arm64e"))
- offset = 6;
+ else if (A.startswith("arm64e"))
+ offset = 6;
else if (A.startswith("arm64"))
offset = 5;
else if (A.startswith("aarch64_32"))
@@ -414,7 +414,7 @@ bool ARM::getExtensionFeatures(uint64_t Extensions,
if (Extensions == AEK_INVALID)
return false;
- for (const auto &AE : ARCHExtNames) {
+ for (const auto &AE : ARCHExtNames) {
if ((Extensions & AE.ID) == AE.ID && AE.Feature)
Features.push_back(AE.Feature);
else if (AE.NegFeature)
@@ -441,7 +441,7 @@ unsigned ARM::getArchAttr(ARM::ArchKind AK) {
}
StringRef ARM::getArchExtName(uint64_t ArchExtKind) {
- for (const auto &AE : ARCHExtNames) {
+ for (const auto &AE : ARCHExtNames) {
if (ArchExtKind == AE.ID)
return AE.getName();
}
@@ -458,7 +458,7 @@ static bool stripNegationPrefix(StringRef &Name) {
StringRef ARM::getArchExtFeature(StringRef ArchExt) {
bool Negated = stripNegationPrefix(ArchExt);
- for (const auto &AE : ARCHExtNames) {
+ for (const auto &AE : ARCHExtNames) {
if (AE.Feature && ArchExt == AE.getName())
return StringRef(Negated ? AE.NegFeature : AE.Feature);
}
@@ -495,10 +495,10 @@ static unsigned findDoublePrecisionFPU(unsigned InputFPUKind) {
return ARM::FK_INVALID;
}
-bool ARM::appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK,
- StringRef ArchExt,
- std::vector<StringRef> &Features,
- unsigned &ArgFPUID) {
+bool ARM::appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK,
+ StringRef ArchExt,
+ std::vector<StringRef> &Features,
+ unsigned &ArgFPUID) {
size_t StartingNumFeatures = Features.size();
const bool Negated = stripNegationPrefix(ArchExt);
@@ -507,7 +507,7 @@ bool ARM::appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK,
if (ID == AEK_INVALID)
return false;
- for (const auto &AE : ARCHExtNames) {
+ for (const auto &AE : ARCHExtNames) {
if (Negated) {
if ((AE.ID & ID) == ID && AE.NegFeature)
Features.push_back(AE.NegFeature);
@@ -533,14 +533,14 @@ bool ARM::appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK,
} else {
FPUKind = getDefaultFPU(CPU, AK);
}
- ArgFPUID = FPUKind;
+ ArgFPUID = FPUKind;
return ARM::getFPUFeatures(FPUKind, Features);
}
return StartingNumFeatures != Features.size();
}
StringRef ARM::getHWDivName(uint64_t HWDivKind) {
- for (const auto &D : HWDivNames) {
+ for (const auto &D : HWDivNames) {
if (HWDivKind == D.ID)
return D.getName();
}
@@ -553,7 +553,7 @@ StringRef ARM::getDefaultCPU(StringRef Arch) {
return StringRef();
// Look for multiple AKs to find the default for pair AK+Name.
- for (const auto &CPU : CPUNames) {
+ for (const auto &CPU : CPUNames) {
if (CPU.ArchID == AK && CPU.Default)
return CPU.getName();
}
@@ -564,7 +564,7 @@ StringRef ARM::getDefaultCPU(StringRef Arch) {
uint64_t ARM::parseHWDiv(StringRef HWDiv) {
StringRef Syn = getHWDivSynonym(HWDiv);
- for (const auto &D : HWDivNames) {
+ for (const auto &D : HWDivNames) {
if (Syn == D.getName())
return D.ID;
}
@@ -572,7 +572,7 @@ uint64_t ARM::parseHWDiv(StringRef HWDiv) {
}
uint64_t ARM::parseArchExt(StringRef ArchExt) {
- for (const auto &A : ARCHExtNames) {
+ for (const auto &A : ARCHExtNames) {
if (ArchExt == A.getName())
return A.ID;
}
@@ -580,7 +580,7 @@ uint64_t ARM::parseArchExt(StringRef ArchExt) {
}
ARM::ArchKind ARM::parseCPUArch(StringRef CPU) {
- for (const auto &C : CPUNames) {
+ for (const auto &C : CPUNames) {
if (CPU == C.getName())
return C.ArchID;
}
diff --git a/contrib/libs/llvm12/lib/Support/CRC.cpp b/contrib/libs/llvm12/lib/Support/CRC.cpp
index 58d18eb89c..2bc668beed 100644
--- a/contrib/libs/llvm12/lib/Support/CRC.cpp
+++ b/contrib/libs/llvm12/lib/Support/CRC.cpp
@@ -25,7 +25,7 @@
using namespace llvm;
-#if !LLVM_ENABLE_ZLIB
+#if !LLVM_ENABLE_ZLIB
static const uint32_t CRCTable[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
diff --git a/contrib/libs/llvm12/lib/Support/CachePruning.cpp b/contrib/libs/llvm12/lib/Support/CachePruning.cpp
index ed9825af35..5c5759ffba 100644
--- a/contrib/libs/llvm12/lib/Support/CachePruning.cpp
+++ b/contrib/libs/llvm12/lib/Support/CachePruning.cpp
@@ -211,12 +211,12 @@ bool llvm::pruneCache(StringRef Path, CachePruningPolicy Policy) {
// Walk all of the files within this directory.
for (sys::fs::directory_iterator File(CachePathNative, EC), FileEnd;
File != FileEnd && !EC; File.increment(EC)) {
- // Ignore filenames not beginning with "llvmcache-" or "Thin-". This
+ // Ignore filenames not beginning with "llvmcache-" or "Thin-". This
// includes the timestamp file as well as any files created by the user.
// This acts as a safeguard against data loss if the user specifies the
// wrong directory as their cache directory.
- StringRef filename = sys::path::filename(File->path());
- if (!filename.startswith("llvmcache-") && !filename.startswith("Thin-"))
+ StringRef filename = sys::path::filename(File->path());
+ if (!filename.startswith("llvmcache-") && !filename.startswith("Thin-"))
continue;
// Look at this file. If we can't stat it, there's nothing interesting
diff --git a/contrib/libs/llvm12/lib/Support/CommandLine.cpp b/contrib/libs/llvm12/lib/Support/CommandLine.cpp
index fef6bc3687..123a23a524 100644
--- a/contrib/libs/llvm12/lib/Support/CommandLine.cpp
+++ b/contrib/libs/llvm12/lib/Support/CommandLine.cpp
@@ -464,7 +464,7 @@ void Option::addCategory(OptionCategory &C) {
// must be explicitly added if you want multiple categories that include it.
if (&C != &GeneralCategory && Categories[0] == &GeneralCategory)
Categories[0] = &C;
- else if (!is_contained(Categories, &C))
+ else if (!is_contained(Categories, &C))
Categories.push_back(&C);
}
@@ -531,7 +531,7 @@ Option *CommandLineParser::LookupOption(SubCommand &Sub, StringRef &Arg,
// If we have an equals sign, remember the value.
if (EqualPos == StringRef::npos) {
// Look up the option.
- return Sub.OptionsMap.lookup(Arg);
+ return Sub.OptionsMap.lookup(Arg);
}
// If the argument before the = is a valid option name and the option allows
@@ -828,7 +828,7 @@ void cl::TokenizeGNUCommandLine(StringRef Src, StringSaver &Saver,
// Consume runs of whitespace.
if (Token.empty()) {
while (I != E && isWhitespace(Src[I])) {
- // Mark the end of lines in response files.
+ // Mark the end of lines in response files.
if (MarkEOLs && Src[I] == '\n')
NewArgv.push_back(nullptr);
++I;
@@ -865,9 +865,9 @@ void cl::TokenizeGNUCommandLine(StringRef Src, StringSaver &Saver,
if (isWhitespace(C)) {
if (!Token.empty())
NewArgv.push_back(Saver.save(StringRef(Token)).data());
- // Mark the end of lines in response files.
- if (MarkEOLs && C == '\n')
- NewArgv.push_back(nullptr);
+ // Mark the end of lines in response files.
+ if (MarkEOLs && C == '\n')
+ NewArgv.push_back(nullptr);
Token.clear();
continue;
}
@@ -955,8 +955,8 @@ tokenizeWindowsCommandLineImpl(StringRef Src, StringSaver &Saver,
// No special characters: slice out the substring and start the next
// token. Copy the string if the caller asks us to.
AddToken(AlwaysCopy ? Saver.save(NormalChars) : NormalChars);
- if (I < E && Src[I] == '\n')
- MarkEOL();
+ if (I < E && Src[I] == '\n')
+ MarkEOL();
} else if (Src[I] == '\"') {
Token += NormalChars;
State = QUOTED;
@@ -1204,7 +1204,7 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
};
// Check for recursive response files.
- if (any_of(drop_begin(FileStack), IsEquivalent)) {
+ if (any_of(drop_begin(FileStack), IsEquivalent)) {
// This file is recursive, so we leave it in the argument stream and
// move on.
AllExpanded = false;
@@ -1247,22 +1247,22 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
return AllExpanded;
}
-bool cl::expandResponseFiles(int Argc, const char *const *Argv,
- const char *EnvVar, StringSaver &Saver,
- SmallVectorImpl<const char *> &NewArgv) {
- auto Tokenize = Triple(sys::getProcessTriple()).isOSWindows()
- ? cl::TokenizeWindowsCommandLine
- : cl::TokenizeGNUCommandLine;
- // The environment variable specifies initial options.
- if (EnvVar)
- if (llvm::Optional<std::string> EnvValue = sys::Process::GetEnv(EnvVar))
- Tokenize(*EnvValue, Saver, NewArgv, /*MarkEOLs=*/false);
-
- // Command line options can override the environment variable.
- NewArgv.append(Argv + 1, Argv + Argc);
- return ExpandResponseFiles(Saver, Tokenize, NewArgv);
-}
-
+bool cl::expandResponseFiles(int Argc, const char *const *Argv,
+ const char *EnvVar, StringSaver &Saver,
+ SmallVectorImpl<const char *> &NewArgv) {
+ auto Tokenize = Triple(sys::getProcessTriple()).isOSWindows()
+ ? cl::TokenizeWindowsCommandLine
+ : cl::TokenizeGNUCommandLine;
+ // The environment variable specifies initial options.
+ if (EnvVar)
+ if (llvm::Optional<std::string> EnvValue = sys::Process::GetEnv(EnvVar))
+ Tokenize(*EnvValue, Saver, NewArgv, /*MarkEOLs=*/false);
+
+ // Command line options can override the environment variable.
+ NewArgv.append(Argv + 1, Argv + Argc);
+ return ExpandResponseFiles(Saver, Tokenize, NewArgv);
+}
+
bool cl::readConfigFile(StringRef CfgFile, StringSaver &Saver,
SmallVectorImpl<const char *> &Argv) {
SmallString<128> AbsPath;
@@ -1726,19 +1726,19 @@ void Option::printHelpStr(StringRef HelpStr, size_t Indent,
}
}
-void Option::printEnumValHelpStr(StringRef HelpStr, size_t BaseIndent,
- size_t FirstLineIndentedBy) {
- const StringRef ValHelpPrefix = " ";
- assert(BaseIndent >= FirstLineIndentedBy);
- std::pair<StringRef, StringRef> Split = HelpStr.split('\n');
- outs().indent(BaseIndent - FirstLineIndentedBy)
- << ArgHelpPrefix << ValHelpPrefix << Split.first << "\n";
- while (!Split.second.empty()) {
- Split = Split.second.split('\n');
- outs().indent(BaseIndent + ValHelpPrefix.size()) << Split.first << "\n";
- }
-}
-
+void Option::printEnumValHelpStr(StringRef HelpStr, size_t BaseIndent,
+ size_t FirstLineIndentedBy) {
+ const StringRef ValHelpPrefix = " ";
+ assert(BaseIndent >= FirstLineIndentedBy);
+ std::pair<StringRef, StringRef> Split = HelpStr.split('\n');
+ outs().indent(BaseIndent - FirstLineIndentedBy)
+ << ArgHelpPrefix << ValHelpPrefix << Split.first << "\n";
+ while (!Split.second.empty()) {
+ Split = Split.second.split('\n');
+ outs().indent(BaseIndent + ValHelpPrefix.size()) << Split.first << "\n";
+ }
+}
+
// Print out the option for the alias.
void alias::printOptionInfo(size_t GlobalWidth) const {
outs() << PrintArg(ArgStr);
@@ -1984,17 +1984,17 @@ void generic_parser_base::printOptionInfo(const Option &O,
StringRef Description = getDescription(i);
if (!shouldPrintOption(OptionName, Description, O))
continue;
- size_t FirstLineIndent = OptionName.size() + OptionPrefixesSize;
+ size_t FirstLineIndent = OptionName.size() + OptionPrefixesSize;
outs() << OptionPrefix << OptionName;
if (OptionName.empty()) {
outs() << EmptyOption;
- assert(FirstLineIndent >= EmptyOption.size());
- FirstLineIndent += EmptyOption.size();
+ assert(FirstLineIndent >= EmptyOption.size());
+ FirstLineIndent += EmptyOption.size();
}
if (!Description.empty())
- Option::printEnumValHelpStr(Description, GlobalWidth, FirstLineIndent);
- else
- outs() << '\n';
+ Option::printEnumValHelpStr(Description, GlobalWidth, FirstLineIndent);
+ else
+ outs() << '\n';
}
} else {
if (!O.HelpStr.empty())
@@ -2599,7 +2599,7 @@ void cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories,
SubCommand &Sub) {
for (auto &I : Sub.OptionsMap) {
for (auto &Cat : I.second->Categories) {
- if (!is_contained(Categories, Cat) && Cat != &GenericCategory)
+ if (!is_contained(Categories, Cat) && Cat != &GenericCategory)
I.second->setHiddenFlag(cl::ReallyHidden);
}
}
diff --git a/contrib/libs/llvm12/lib/Support/Compression.cpp b/contrib/libs/llvm12/lib/Support/Compression.cpp
index a6a73ac879..b8c77cf69b 100644
--- a/contrib/libs/llvm12/lib/Support/Compression.cpp
+++ b/contrib/libs/llvm12/lib/Support/Compression.cpp
@@ -17,13 +17,13 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
-#if LLVM_ENABLE_ZLIB
+#if LLVM_ENABLE_ZLIB
#include <zlib.h>
#endif
using namespace llvm;
-#if LLVM_ENABLE_ZLIB
+#if LLVM_ENABLE_ZLIB
static Error createError(StringRef Err) {
return make_error<StringError>(Err, inconvertibleErrorCode());
}
diff --git a/contrib/libs/llvm12/lib/Support/ConvertUTFWrapper.cpp b/contrib/libs/llvm12/lib/Support/ConvertUTFWrapper.cpp
index 429c0c50f4..d8d46712a5 100644
--- a/contrib/libs/llvm12/lib/Support/ConvertUTFWrapper.cpp
+++ b/contrib/libs/llvm12/lib/Support/ConvertUTFWrapper.cpp
@@ -97,8 +97,8 @@ bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out) {
const UTF16 *Src = reinterpret_cast<const UTF16 *>(SrcBytes.begin());
const UTF16 *SrcEnd = reinterpret_cast<const UTF16 *>(SrcBytes.end());
- assert((uintptr_t)Src % sizeof(UTF16) == 0);
-
+ assert((uintptr_t)Src % sizeof(UTF16) == 0);
+
// Byteswap if necessary.
std::vector<UTF16> ByteSwapped;
if (Src[0] == UNI_UTF16_BYTE_ORDER_MARK_SWAPPED) {
diff --git a/contrib/libs/llvm12/lib/Support/CrashRecoveryContext.cpp b/contrib/libs/llvm12/lib/Support/CrashRecoveryContext.cpp
index 6c2529df51..3d3ca7f567 100644
--- a/contrib/libs/llvm12/lib/Support/CrashRecoveryContext.cpp
+++ b/contrib/libs/llvm12/lib/Support/CrashRecoveryContext.cpp
@@ -9,7 +9,7 @@
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/ExitCodes.h"
+#include "llvm/Support/ExitCodes.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/ThreadLocal.h"
@@ -95,13 +95,13 @@ static void uninstallExceptionOrSignalHandlers();
CrashRecoveryContextCleanup::~CrashRecoveryContextCleanup() {}
-CrashRecoveryContext::CrashRecoveryContext() {
- // On Windows, if abort() was previously triggered (and caught by a previous
- // CrashRecoveryContext) the Windows CRT removes our installed signal handler,
- // so we need to install it again.
- sys::DisableSystemDialogsOnCrash();
-}
-
+CrashRecoveryContext::CrashRecoveryContext() {
+ // On Windows, if abort() was previously triggered (and caught by a previous
+ // CrashRecoveryContext) the Windows CRT removes our installed signal handler,
+ // so we need to install it again.
+ sys::DisableSystemDialogsOnCrash();
+}
+
CrashRecoveryContext::~CrashRecoveryContext() {
// Reclaim registered resources.
CrashRecoveryContextCleanup *i = head;
@@ -375,10 +375,10 @@ static void CrashRecoverySignalHandler(int Signal) {
sigaddset(&SigMask, Signal);
sigprocmask(SIG_UNBLOCK, &SigMask, nullptr);
- // Return the same error code as if the program crashed, as mentioned in the
- // section "Exit Status for Commands":
- // https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xcu_chap02.html
- int RetCode = 128 + Signal;
+ // Return the same error code as if the program crashed, as mentioned in the
+ // section "Exit Status for Commands":
+ // https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xcu_chap02.html
+ int RetCode = 128 + Signal;
// Don't consider a broken pipe as a crash (see clang/lib/Driver/Driver.cpp)
if (Signal == SIGPIPE)
@@ -442,27 +442,27 @@ void CrashRecoveryContext::HandleExit(int RetCode) {
llvm_unreachable("Most likely setjmp wasn't called!");
}
-bool CrashRecoveryContext::throwIfCrash(int RetCode) {
-#if defined(_WIN32)
- // On Windows, the high bits are reserved for kernel return codes. Values
- // starting with 0x80000000 are reserved for "warnings"; values of 0xC0000000
- // and up are for "errors". In practice, both are interpreted as a
- // non-continuable signal.
- unsigned Code = ((unsigned)RetCode & 0xF0000000) >> 28;
- if (Code != 0xC && Code != 8)
- return false;
- ::RaiseException(RetCode, 0, 0, NULL);
-#else
- // On Unix, signals are represented by return codes of 128 or higher.
- // Exit code 128 is a reserved value and should not be raised as a signal.
- if (RetCode <= 128)
- return false;
- llvm::sys::unregisterHandlers();
- raise(RetCode - 128);
-#endif
- return true;
-}
-
+bool CrashRecoveryContext::throwIfCrash(int RetCode) {
+#if defined(_WIN32)
+ // On Windows, the high bits are reserved for kernel return codes. Values
+ // starting with 0x80000000 are reserved for "warnings"; values of 0xC0000000
+ // and up are for "errors". In practice, both are interpreted as a
+ // non-continuable signal.
+ unsigned Code = ((unsigned)RetCode & 0xF0000000) >> 28;
+ if (Code != 0xC && Code != 8)
+ return false;
+ ::RaiseException(RetCode, 0, 0, NULL);
+#else
+ // On Unix, signals are represented by return codes of 128 or higher.
+ // Exit code 128 is a reserved value and should not be raised as a signal.
+ if (RetCode <= 128)
+ return false;
+ llvm::sys::unregisterHandlers();
+ raise(RetCode - 128);
+#endif
+ return true;
+}
+
// FIXME: Portability.
static void setThreadBackgroundPriority() {
#ifdef __APPLE__
diff --git a/contrib/libs/llvm12/lib/Support/DebugCounter.cpp b/contrib/libs/llvm12/lib/Support/DebugCounter.cpp
index 2269b9c126..7bb231c792 100644
--- a/contrib/libs/llvm12/lib/Support/DebugCounter.cpp
+++ b/contrib/libs/llvm12/lib/Support/DebugCounter.cpp
@@ -118,7 +118,7 @@ void DebugCounter::push_back(const std::string &Val) {
void DebugCounter::print(raw_ostream &OS) const {
SmallVector<StringRef, 16> CounterNames(RegisteredCounters.begin(),
RegisteredCounters.end());
- sort(CounterNames);
+ sort(CounterNames);
auto &Us = instance();
OS << "Counters and values:\n";
diff --git a/contrib/libs/llvm12/lib/Support/DynamicLibrary.cpp b/contrib/libs/llvm12/lib/Support/DynamicLibrary.cpp
index d645dd3e7c..bdf7462367 100644
--- a/contrib/libs/llvm12/lib/Support/DynamicLibrary.cpp
+++ b/contrib/libs/llvm12/lib/Support/DynamicLibrary.cpp
@@ -39,7 +39,7 @@ public:
HandleSet() : Process(nullptr) {}
~HandleSet();
- HandleList::iterator Find(void *Handle) { return find(Handles, Handle); }
+ HandleList::iterator Find(void *Handle) { return find(Handles, Handle); }
bool Contains(void *Handle) {
return Handle == Process || Find(Handle) != Handles.end();
diff --git a/contrib/libs/llvm12/lib/Support/ELFAttributeParser.cpp b/contrib/libs/llvm12/lib/Support/ELFAttributeParser.cpp
index 1f784c0970..2a30794bc1 100644
--- a/contrib/libs/llvm12/lib/Support/ELFAttributeParser.cpp
+++ b/contrib/libs/llvm12/lib/Support/ELFAttributeParser.cpp
@@ -200,7 +200,7 @@ Error ELFAttributeParser::parse(ArrayRef<uint8_t> section,
// Unrecognized format-version.
uint8_t formatVersion = de.getU8(cursor);
- if (formatVersion != ELFAttrs::Format_Version)
+ if (formatVersion != ELFAttrs::Format_Version)
return createStringError(errc::invalid_argument,
"unrecognized format-version: 0x" +
utohexstr(formatVersion));
diff --git a/contrib/libs/llvm12/lib/Support/Error.cpp b/contrib/libs/llvm12/lib/Support/Error.cpp
index b8d1b5e63c..e7ab4387df 100644
--- a/contrib/libs/llvm12/lib/Support/Error.cpp
+++ b/contrib/libs/llvm12/lib/Support/Error.cpp
@@ -168,7 +168,7 @@ void LLVMDisposeErrorMessage(char *ErrMsg) { delete[] ErrMsg; }
LLVMErrorTypeId LLVMGetStringErrorTypeId() {
return reinterpret_cast<void *>(&StringError::ID);
}
-
-LLVMErrorRef LLVMCreateStringError(const char *ErrMsg) {
- return wrap(make_error<StringError>(ErrMsg, inconvertibleErrorCode()));
-}
+
+LLVMErrorRef LLVMCreateStringError(const char *ErrMsg) {
+ return wrap(make_error<StringError>(ErrMsg, inconvertibleErrorCode()));
+}
diff --git a/contrib/libs/llvm12/lib/Support/ErrorHandling.cpp b/contrib/libs/llvm12/lib/Support/ErrorHandling.cpp
index d8b607773b..ce6344284f 100644
--- a/contrib/libs/llvm12/lib/Support/ErrorHandling.cpp
+++ b/contrib/libs/llvm12/lib/Support/ErrorHandling.cpp
@@ -168,11 +168,11 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) {
#else
// Don't call the normal error handler. It may allocate memory. Directly write
// an OOM to stderr and abort.
- const char *OOMMessage = "LLVM ERROR: out of memory\n";
- const char *Newline = "\n";
- (void)!::write(2, OOMMessage, strlen(OOMMessage));
- (void)!::write(2, Reason, strlen(Reason));
- (void)!::write(2, Newline, strlen(Newline));
+ const char *OOMMessage = "LLVM ERROR: out of memory\n";
+ const char *Newline = "\n";
+ (void)!::write(2, OOMMessage, strlen(OOMMessage));
+ (void)!::write(2, Reason, strlen(Reason));
+ (void)!::write(2, Newline, strlen(Newline));
abort();
#endif
}
@@ -194,8 +194,8 @@ static void out_of_memory_new_handler() {
void llvm::install_out_of_memory_new_handler() {
std::new_handler old = std::set_new_handler(out_of_memory_new_handler);
(void)old;
- assert((old == nullptr || old == out_of_memory_new_handler) &&
- "new-handler already installed");
+ assert((old == nullptr || old == out_of_memory_new_handler) &&
+ "new-handler already installed");
}
#endif
diff --git a/contrib/libs/llvm12/lib/Support/FileCollector.cpp b/contrib/libs/llvm12/lib/Support/FileCollector.cpp
index 3ff2871a38..99482075f6 100644
--- a/contrib/libs/llvm12/lib/Support/FileCollector.cpp
+++ b/contrib/libs/llvm12/lib/Support/FileCollector.cpp
@@ -15,22 +15,22 @@
using namespace llvm;
-FileCollectorBase::FileCollectorBase() = default;
-FileCollectorBase::~FileCollectorBase() = default;
-
-void FileCollectorBase::addFile(const Twine &File) {
- std::lock_guard<std::mutex> lock(Mutex);
- std::string FileStr = File.str();
- if (markAsSeen(FileStr))
- addFileImpl(FileStr);
-}
-
-void FileCollectorBase::addDirectory(const Twine &Dir) {
- assert(sys::fs::is_directory(Dir));
- std::error_code EC;
- addDirectoryImpl(Dir, vfs::getRealFileSystem(), EC);
-}
-
+FileCollectorBase::FileCollectorBase() = default;
+FileCollectorBase::~FileCollectorBase() = default;
+
+void FileCollectorBase::addFile(const Twine &File) {
+ std::lock_guard<std::mutex> lock(Mutex);
+ std::string FileStr = File.str();
+ if (markAsSeen(FileStr))
+ addFileImpl(FileStr);
+}
+
+void FileCollectorBase::addDirectory(const Twine &Dir) {
+ assert(sys::fs::is_directory(Dir));
+ std::error_code EC;
+ addDirectoryImpl(Dir, vfs::getRealFileSystem(), EC);
+}
+
static bool isCaseSensitivePath(StringRef Path) {
SmallString<256> TmpDest = Path, UpperDest, RealDest;
@@ -53,82 +53,82 @@ FileCollector::FileCollector(std::string Root, std::string OverlayRoot)
: Root(std::move(Root)), OverlayRoot(std::move(OverlayRoot)) {
}
-void FileCollector::PathCanonicalizer::updateWithRealPath(
- SmallVectorImpl<char> &Path) {
- StringRef SrcPath(Path.begin(), Path.size());
- StringRef Filename = sys::path::filename(SrcPath);
- StringRef Directory = sys::path::parent_path(SrcPath);
-
- // Use real_path to fix any symbolic link component present in the directory
- // part of the path, caching the search because computing the real path is
- // expensive.
+void FileCollector::PathCanonicalizer::updateWithRealPath(
+ SmallVectorImpl<char> &Path) {
+ StringRef SrcPath(Path.begin(), Path.size());
+ StringRef Filename = sys::path::filename(SrcPath);
+ StringRef Directory = sys::path::parent_path(SrcPath);
+
+ // Use real_path to fix any symbolic link component present in the directory
+ // part of the path, caching the search because computing the real path is
+ // expensive.
SmallString<256> RealPath;
- auto DirWithSymlink = CachedDirs.find(Directory);
- if (DirWithSymlink == CachedDirs.end()) {
- // FIXME: Should this be a call to FileSystem::getRealpath(), in some
- // cases? What if there is nothing on disk?
- if (sys::fs::real_path(Directory, RealPath))
- return;
- CachedDirs[Directory] = std::string(RealPath.str());
+ auto DirWithSymlink = CachedDirs.find(Directory);
+ if (DirWithSymlink == CachedDirs.end()) {
+ // FIXME: Should this be a call to FileSystem::getRealpath(), in some
+ // cases? What if there is nothing on disk?
+ if (sys::fs::real_path(Directory, RealPath))
+ return;
+ CachedDirs[Directory] = std::string(RealPath.str());
} else {
RealPath = DirWithSymlink->second;
}
- // Finish recreating the path by appending the original filename, since we
- // don't need to resolve symlinks in the filename.
- //
- // FIXME: If we can cope with this, maybe we can cope without calling
- // getRealPath() at all when there's no ".." component.
- sys::path::append(RealPath, Filename);
+ // Finish recreating the path by appending the original filename, since we
+ // don't need to resolve symlinks in the filename.
+ //
+ // FIXME: If we can cope with this, maybe we can cope without calling
+ // getRealPath() at all when there's no ".." component.
+ sys::path::append(RealPath, Filename);
- // Swap to create the output.
- Path.swap(RealPath);
+ // Swap to create the output.
+ Path.swap(RealPath);
}
-/// Make Path absolute.
-static void makeAbsolute(SmallVectorImpl<char> &Path) {
+/// Make Path absolute.
+static void makeAbsolute(SmallVectorImpl<char> &Path) {
// We need an absolute src path to append to the root.
- sys::fs::make_absolute(Path);
+ sys::fs::make_absolute(Path);
// Canonicalize src to a native path to avoid mixed separator styles.
- sys::path::native(Path);
+ sys::path::native(Path);
// Remove redundant leading "./" pieces and consecutive separators.
- Path.erase(Path.begin(), sys::path::remove_leading_dotslash(
- StringRef(Path.begin(), Path.size()))
- .begin());
-}
+ Path.erase(Path.begin(), sys::path::remove_leading_dotslash(
+ StringRef(Path.begin(), Path.size()))
+ .begin());
+}
-FileCollector::PathCanonicalizer::PathStorage
-FileCollector::PathCanonicalizer::canonicalize(StringRef SrcPath) {
- PathStorage Paths;
- Paths.VirtualPath = SrcPath;
- makeAbsolute(Paths.VirtualPath);
+FileCollector::PathCanonicalizer::PathStorage
+FileCollector::PathCanonicalizer::canonicalize(StringRef SrcPath) {
+ PathStorage Paths;
+ Paths.VirtualPath = SrcPath;
+ makeAbsolute(Paths.VirtualPath);
// If a ".." component is present after a symlink component, remove_dots may
// lead to the wrong real destination path. Let the source be canonicalized
// like that but make sure we always use the real path for the destination.
- Paths.CopyFrom = Paths.VirtualPath;
- updateWithRealPath(Paths.CopyFrom);
-
- // Canonicalize the virtual path by removing "..", "." components.
- sys::path::remove_dots(Paths.VirtualPath, /*remove_dot_dot=*/true);
-
- return Paths;
-}
-
-void FileCollector::addFileImpl(StringRef SrcPath) {
- PathCanonicalizer::PathStorage Paths = Canonicalizer.canonicalize(SrcPath);
-
+ Paths.CopyFrom = Paths.VirtualPath;
+ updateWithRealPath(Paths.CopyFrom);
+
+ // Canonicalize the virtual path by removing "..", "." components.
+ sys::path::remove_dots(Paths.VirtualPath, /*remove_dot_dot=*/true);
+
+ return Paths;
+}
+
+void FileCollector::addFileImpl(StringRef SrcPath) {
+ PathCanonicalizer::PathStorage Paths = Canonicalizer.canonicalize(SrcPath);
+
SmallString<256> DstPath = StringRef(Root);
- sys::path::append(DstPath, sys::path::relative_path(Paths.CopyFrom));
+ sys::path::append(DstPath, sys::path::relative_path(Paths.CopyFrom));
// Always map a canonical src path to its real path into the YAML, by doing
// this we map different virtual src paths to the same entry in the VFS
// overlay, which is a way to emulate symlink inside the VFS; this is also
// needed for correctness, not doing that can lead to module redefinition
// errors.
- addFileToMapping(Paths.VirtualPath, DstPath);
+ addFileToMapping(Paths.VirtualPath, DstPath);
}
llvm::vfs::directory_iterator
@@ -182,18 +182,18 @@ std::error_code FileCollector::copyFiles(bool StopOnError) {
std::lock_guard<std::mutex> lock(Mutex);
for (auto &entry : VFSWriter.getMappings()) {
- // Get the status of the original file/directory.
- sys::fs::file_status Stat;
- if (std::error_code EC = sys::fs::status(entry.VPath, Stat)) {
- if (StopOnError)
- return EC;
- continue;
- }
-
- // Continue if the file doesn't exist.
- if (Stat.type() == sys::fs::file_type::file_not_found)
- continue;
-
+ // Get the status of the original file/directory.
+ sys::fs::file_status Stat;
+ if (std::error_code EC = sys::fs::status(entry.VPath, Stat)) {
+ if (StopOnError)
+ return EC;
+ continue;
+ }
+
+ // Continue if the file doesn't exist.
+ if (Stat.type() == sys::fs::file_type::file_not_found)
+ continue;
+
// Create directory tree.
if (std::error_code EC =
sys::fs::create_directories(sys::path::parent_path(entry.RPath),
diff --git a/contrib/libs/llvm12/lib/Support/FormatVariadic.cpp b/contrib/libs/llvm12/lib/Support/FormatVariadic.cpp
index 06d423907a..f6d48bcd50 100644
--- a/contrib/libs/llvm12/lib/Support/FormatVariadic.cpp
+++ b/contrib/libs/llvm12/lib/Support/FormatVariadic.cpp
@@ -91,26 +91,26 @@ formatv_object_base::parseReplacementItem(StringRef Spec) {
std::pair<ReplacementItem, StringRef>
formatv_object_base::splitLiteralAndReplacement(StringRef Fmt) {
- while (!Fmt.empty()) {
+ while (!Fmt.empty()) {
// Everything up until the first brace is a literal.
- if (Fmt.front() != '{') {
- std::size_t BO = Fmt.find_first_of('{');
+ if (Fmt.front() != '{') {
+ std::size_t BO = Fmt.find_first_of('{');
return std::make_pair(ReplacementItem{Fmt.substr(0, BO)}, Fmt.substr(BO));
- }
+ }
- StringRef Braces = Fmt.take_while([](char C) { return C == '{'; });
+ StringRef Braces = Fmt.take_while([](char C) { return C == '{'; });
// If there is more than one brace, then some of them are escaped. Treat
// these as replacements.
if (Braces.size() > 1) {
size_t NumEscapedBraces = Braces.size() / 2;
- StringRef Middle = Fmt.take_front(NumEscapedBraces);
- StringRef Right = Fmt.drop_front(NumEscapedBraces * 2);
+ StringRef Middle = Fmt.take_front(NumEscapedBraces);
+ StringRef Right = Fmt.drop_front(NumEscapedBraces * 2);
return std::make_pair(ReplacementItem{Middle}, Right);
}
// An unterminated open brace is undefined. We treat the rest of the string
// as a literal replacement, but we assert to indicate that this is
// undefined and that we consider it an error.
- std::size_t BC = Fmt.find_first_of('}');
+ std::size_t BC = Fmt.find_first_of('}');
if (BC == StringRef::npos) {
assert(
false &&
@@ -121,12 +121,12 @@ formatv_object_base::splitLiteralAndReplacement(StringRef Fmt) {
// Even if there is a closing brace, if there is another open brace before
// this closing brace, treat this portion as literal, and try again with the
// next one.
- std::size_t BO2 = Fmt.find_first_of('{', 1);
+ std::size_t BO2 = Fmt.find_first_of('{', 1);
if (BO2 < BC)
return std::make_pair(ReplacementItem{Fmt.substr(0, BO2)},
Fmt.substr(BO2));
- StringRef Spec = Fmt.slice(1, BC);
+ StringRef Spec = Fmt.slice(1, BC);
StringRef Right = Fmt.substr(BC + 1);
auto RI = parseReplacementItem(Spec);
@@ -135,7 +135,7 @@ formatv_object_base::splitLiteralAndReplacement(StringRef Fmt) {
// If there was an error parsing the replacement item, treat it as an
// invalid replacement spec, and just continue.
- Fmt = Fmt.drop_front(BC + 1);
+ Fmt = Fmt.drop_front(BC + 1);
}
return std::make_pair(ReplacementItem{Fmt}, StringRef());
}
diff --git a/contrib/libs/llvm12/lib/Support/Host.cpp b/contrib/libs/llvm12/lib/Support/Host.cpp
index 4f09e7d3b9..09146c47ff 100644
--- a/contrib/libs/llvm12/lib/Support/Host.cpp
+++ b/contrib/libs/llvm12/lib/Support/Host.cpp
@@ -161,14 +161,14 @@ StringRef sys::detail::getHostCPUNameForARM(StringRef ProcCpuinfoContent) {
// Look for the CPU implementer line.
StringRef Implementer;
StringRef Hardware;
- StringRef Part;
+ StringRef Part;
for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
if (Lines[I].startswith("CPU implementer"))
Implementer = Lines[I].substr(15).ltrim("\t :");
if (Lines[I].startswith("Hardware"))
Hardware = Lines[I].substr(8).ltrim("\t :");
- if (Lines[I].startswith("CPU part"))
- Part = Lines[I].substr(8).ltrim("\t :");
+ if (Lines[I].startswith("CPU part"))
+ Part = Lines[I].substr(8).ltrim("\t :");
}
if (Implementer == "0x41") { // ARM Ltd.
@@ -178,89 +178,89 @@ StringRef sys::detail::getHostCPUNameForARM(StringRef ProcCpuinfoContent) {
return "cortex-a53";
- // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
- // values correspond to the "Part number" in the CP15/c0 register. The
- // contents are specified in the various processor manuals.
- // This corresponds to the Main ID Register in Technical Reference Manuals.
- // and is used in programs like sys-utils
- return StringSwitch<const char *>(Part)
- .Case("0x926", "arm926ej-s")
- .Case("0xb02", "mpcore")
- .Case("0xb36", "arm1136j-s")
- .Case("0xb56", "arm1156t2-s")
- .Case("0xb76", "arm1176jz-s")
- .Case("0xc08", "cortex-a8")
- .Case("0xc09", "cortex-a9")
- .Case("0xc0f", "cortex-a15")
- .Case("0xc20", "cortex-m0")
- .Case("0xc23", "cortex-m3")
- .Case("0xc24", "cortex-m4")
- .Case("0xd22", "cortex-m55")
- .Case("0xd02", "cortex-a34")
- .Case("0xd04", "cortex-a35")
- .Case("0xd03", "cortex-a53")
- .Case("0xd07", "cortex-a57")
- .Case("0xd08", "cortex-a72")
- .Case("0xd09", "cortex-a73")
- .Case("0xd0a", "cortex-a75")
- .Case("0xd0b", "cortex-a76")
- .Case("0xd0d", "cortex-a77")
- .Case("0xd41", "cortex-a78")
- .Case("0xd44", "cortex-x1")
- .Case("0xd0c", "neoverse-n1")
- .Case("0xd49", "neoverse-n2")
- .Default("generic");
+ // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
+ // values correspond to the "Part number" in the CP15/c0 register. The
+ // contents are specified in the various processor manuals.
+ // This corresponds to the Main ID Register in Technical Reference Manuals.
+ // and is used in programs like sys-utils
+ return StringSwitch<const char *>(Part)
+ .Case("0x926", "arm926ej-s")
+ .Case("0xb02", "mpcore")
+ .Case("0xb36", "arm1136j-s")
+ .Case("0xb56", "arm1156t2-s")
+ .Case("0xb76", "arm1176jz-s")
+ .Case("0xc08", "cortex-a8")
+ .Case("0xc09", "cortex-a9")
+ .Case("0xc0f", "cortex-a15")
+ .Case("0xc20", "cortex-m0")
+ .Case("0xc23", "cortex-m3")
+ .Case("0xc24", "cortex-m4")
+ .Case("0xd22", "cortex-m55")
+ .Case("0xd02", "cortex-a34")
+ .Case("0xd04", "cortex-a35")
+ .Case("0xd03", "cortex-a53")
+ .Case("0xd07", "cortex-a57")
+ .Case("0xd08", "cortex-a72")
+ .Case("0xd09", "cortex-a73")
+ .Case("0xd0a", "cortex-a75")
+ .Case("0xd0b", "cortex-a76")
+ .Case("0xd0d", "cortex-a77")
+ .Case("0xd41", "cortex-a78")
+ .Case("0xd44", "cortex-x1")
+ .Case("0xd0c", "neoverse-n1")
+ .Case("0xd49", "neoverse-n2")
+ .Default("generic");
}
if (Implementer == "0x42" || Implementer == "0x43") { // Broadcom | Cavium.
- return StringSwitch<const char *>(Part)
- .Case("0x516", "thunderx2t99")
- .Case("0x0516", "thunderx2t99")
- .Case("0xaf", "thunderx2t99")
- .Case("0x0af", "thunderx2t99")
- .Case("0xa1", "thunderxt88")
- .Case("0x0a1", "thunderxt88")
- .Default("generic");
+ return StringSwitch<const char *>(Part)
+ .Case("0x516", "thunderx2t99")
+ .Case("0x0516", "thunderx2t99")
+ .Case("0xaf", "thunderx2t99")
+ .Case("0x0af", "thunderx2t99")
+ .Case("0xa1", "thunderxt88")
+ .Case("0x0a1", "thunderxt88")
+ .Default("generic");
}
if (Implementer == "0x46") { // Fujitsu Ltd.
- return StringSwitch<const char *>(Part)
- .Case("0x001", "a64fx")
- .Default("generic");
+ return StringSwitch<const char *>(Part)
+ .Case("0x001", "a64fx")
+ .Default("generic");
}
if (Implementer == "0x4e") { // NVIDIA Corporation
- return StringSwitch<const char *>(Part)
- .Case("0x004", "carmel")
- .Default("generic");
+ return StringSwitch<const char *>(Part)
+ .Case("0x004", "carmel")
+ .Default("generic");
}
if (Implementer == "0x48") // HiSilicon Technologies, Inc.
- // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
- // values correspond to the "Part number" in the CP15/c0 register. The
- // contents are specified in the various processor manuals.
- return StringSwitch<const char *>(Part)
- .Case("0xd01", "tsv110")
- .Default("generic");
+ // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
+ // values correspond to the "Part number" in the CP15/c0 register. The
+ // contents are specified in the various processor manuals.
+ return StringSwitch<const char *>(Part)
+ .Case("0xd01", "tsv110")
+ .Default("generic");
if (Implementer == "0x51") // Qualcomm Technologies, Inc.
- // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
- // values correspond to the "Part number" in the CP15/c0 register. The
- // contents are specified in the various processor manuals.
- return StringSwitch<const char *>(Part)
- .Case("0x06f", "krait") // APQ8064
- .Case("0x201", "kryo")
- .Case("0x205", "kryo")
- .Case("0x211", "kryo")
- .Case("0x800", "cortex-a73") // Kryo 2xx Gold
- .Case("0x801", "cortex-a73") // Kryo 2xx Silver
- .Case("0x802", "cortex-a75") // Kryo 3xx Gold
- .Case("0x803", "cortex-a75") // Kryo 3xx Silver
- .Case("0x804", "cortex-a76") // Kryo 4xx Gold
- .Case("0x805", "cortex-a76") // Kryo 4xx/5xx Silver
- .Case("0xc00", "falkor")
- .Case("0xc01", "saphira")
- .Default("generic");
+ // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
+ // values correspond to the "Part number" in the CP15/c0 register. The
+ // contents are specified in the various processor manuals.
+ return StringSwitch<const char *>(Part)
+ .Case("0x06f", "krait") // APQ8064
+ .Case("0x201", "kryo")
+ .Case("0x205", "kryo")
+ .Case("0x211", "kryo")
+ .Case("0x800", "cortex-a73") // Kryo 2xx Gold
+ .Case("0x801", "cortex-a73") // Kryo 2xx Silver
+ .Case("0x802", "cortex-a75") // Kryo 3xx Gold
+ .Case("0x803", "cortex-a75") // Kryo 3xx Silver
+ .Case("0x804", "cortex-a76") // Kryo 4xx Gold
+ .Case("0x805", "cortex-a76") // Kryo 4xx/5xx Silver
+ .Case("0xc00", "falkor")
+ .Case("0xc01", "saphira")
+ .Default("generic");
if (Implementer == "0x53") { // Samsung Electronics Co., Ltd.
// The Exynos chips have a convoluted ID scheme that doesn't seem to follow
// any predictive pattern across variants and parts.
@@ -305,7 +305,7 @@ StringRef sys::detail::getHostCPUNameForS390x(StringRef ProcCpuinfoContent) {
SmallVector<StringRef, 32> CPUFeatures;
for (unsigned I = 0, E = Lines.size(); I != E; ++I)
if (Lines[I].startswith("features")) {
- size_t Pos = Lines[I].find(':');
+ size_t Pos = Lines[I].find(':');
if (Pos != StringRef::npos) {
Lines[I].drop_front(Pos + 1).split(CPUFeatures, ' ');
break;
@@ -490,42 +490,42 @@ static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
#endif
}
-namespace llvm {
-namespace sys {
-namespace detail {
-namespace x86 {
-
-VendorSignatures getVendorSignature(unsigned *MaxLeaf) {
- unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
- if (MaxLeaf == nullptr)
- MaxLeaf = &EAX;
- else
- *MaxLeaf = 0;
-
- if (!isCpuIdSupported())
- return VendorSignatures::UNKNOWN;
-
- if (getX86CpuIDAndInfo(0, MaxLeaf, &EBX, &ECX, &EDX) || *MaxLeaf < 1)
- return VendorSignatures::UNKNOWN;
-
- // "Genu ineI ntel"
- if (EBX == 0x756e6547 && EDX == 0x49656e69 && ECX == 0x6c65746e)
- return VendorSignatures::GENUINE_INTEL;
-
- // "Auth enti cAMD"
- if (EBX == 0x68747541 && EDX == 0x69746e65 && ECX == 0x444d4163)
- return VendorSignatures::AUTHENTIC_AMD;
-
- return VendorSignatures::UNKNOWN;
-}
-
-} // namespace x86
-} // namespace detail
-} // namespace sys
-} // namespace llvm
-
-using namespace llvm::sys::detail::x86;
-
+namespace llvm {
+namespace sys {
+namespace detail {
+namespace x86 {
+
+VendorSignatures getVendorSignature(unsigned *MaxLeaf) {
+ unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
+ if (MaxLeaf == nullptr)
+ MaxLeaf = &EAX;
+ else
+ *MaxLeaf = 0;
+
+ if (!isCpuIdSupported())
+ return VendorSignatures::UNKNOWN;
+
+ if (getX86CpuIDAndInfo(0, MaxLeaf, &EBX, &ECX, &EDX) || *MaxLeaf < 1)
+ return VendorSignatures::UNKNOWN;
+
+ // "Genu ineI ntel"
+ if (EBX == 0x756e6547 && EDX == 0x49656e69 && ECX == 0x6c65746e)
+ return VendorSignatures::GENUINE_INTEL;
+
+ // "Auth enti cAMD"
+ if (EBX == 0x68747541 && EDX == 0x69746e65 && ECX == 0x444d4163)
+ return VendorSignatures::AUTHENTIC_AMD;
+
+ return VendorSignatures::UNKNOWN;
+}
+
+} // namespace x86
+} // namespace detail
+} // namespace sys
+} // namespace llvm
+
+using namespace llvm::sys::detail::x86;
+
/// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return
/// the 4 values in the specified arguments. If we can't run cpuid on the host,
/// return true.
@@ -743,13 +743,13 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
*Subtype = X86::INTEL_COREI7_ICELAKE_SERVER;
break;
- // Sapphire Rapids:
- case 0x8f:
- CPU = "sapphirerapids";
- *Type = X86::INTEL_COREI7;
- *Subtype = X86::INTEL_COREI7_SAPPHIRERAPIDS;
- break;
-
+ // Sapphire Rapids:
+ case 0x8f:
+ CPU = "sapphirerapids";
+ *Type = X86::INTEL_COREI7;
+ *Subtype = X86::INTEL_COREI7_SAPPHIRERAPIDS;
+ break;
+
case 0x1c: // Most 45 nm Intel Atom processors
case 0x26: // 45 nm Atom Lincroft
case 0x27: // 32 nm Atom Medfield
@@ -976,14 +976,14 @@ getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model,
break; // 00h-0Fh: Zen1
}
break;
- case 25:
- CPU = "znver3";
- *Type = X86::AMDFAM19H;
- if (Model <= 0x0f) {
- *Subtype = X86::AMDFAM19H_ZNVER3;
- break; // 00h-0Fh: Zen3
- }
- break;
+ case 25:
+ CPU = "znver3";
+ *Type = X86::AMDFAM19H;
+ if (Model <= 0x0f) {
+ *Subtype = X86::AMDFAM19H_ZNVER3;
+ break; // 00h-0Fh: Zen3
+ }
+ break;
default:
break; // Unknown AMD CPU.
}
@@ -1123,12 +1123,12 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
}
StringRef sys::getHostCPUName() {
- unsigned MaxLeaf = 0;
- const VendorSignatures Vendor = getVendorSignature(&MaxLeaf);
- if (Vendor == VendorSignatures::UNKNOWN)
+ unsigned MaxLeaf = 0;
+ const VendorSignatures Vendor = getVendorSignature(&MaxLeaf);
+ if (Vendor == VendorSignatures::UNKNOWN)
return "generic";
- unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
+ unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
unsigned Family = 0, Model = 0;
@@ -1143,10 +1143,10 @@ StringRef sys::getHostCPUName() {
StringRef CPU;
- if (Vendor == VendorSignatures::GENUINE_INTEL) {
+ if (Vendor == VendorSignatures::GENUINE_INTEL) {
CPU = getIntelProcessorTypeAndSubtype(Family, Model, Features, &Type,
&Subtype);
- } else if (Vendor == VendorSignatures::AUTHENTIC_AMD) {
+ } else if (Vendor == VendorSignatures::AUTHENTIC_AMD) {
CPU = getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type,
&Subtype);
}
@@ -1248,19 +1248,19 @@ StringRef sys::getHostCPUName() {
}
#else
StringRef sys::getHostCPUName() { return "generic"; }
-namespace llvm {
-namespace sys {
-namespace detail {
-namespace x86 {
-
-VendorSignatures getVendorSignature(unsigned *MaxLeaf) {
- return VendorSignatures::UNKNOWN;
-}
-
-} // namespace x86
-} // namespace detail
-} // namespace sys
-} // namespace llvm
+namespace llvm {
+namespace sys {
+namespace detail {
+namespace x86 {
+
+VendorSignatures getVendorSignature(unsigned *MaxLeaf) {
+ return VendorSignatures::UNKNOWN;
+}
+
+} // namespace x86
+} // namespace detail
+} // namespace sys
+} // namespace llvm
#endif
#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
@@ -1311,27 +1311,27 @@ int computeHostNumPhysicalCores() {
}
return CPU_COUNT(&Enabled);
}
-#elif defined(__linux__) && defined(__powerpc__)
-int computeHostNumPhysicalCores() {
- cpu_set_t Affinity;
- if (sched_getaffinity(0, sizeof(Affinity), &Affinity) == 0)
- return CPU_COUNT(&Affinity);
-
- // The call to sched_getaffinity() may have failed because the Affinity
- // mask is too small for the number of CPU's on the system (i.e. the
- // system has more than 1024 CPUs). Allocate a mask large enough for
- // twice as many CPUs.
- cpu_set_t *DynAffinity;
- DynAffinity = CPU_ALLOC(2048);
- if (sched_getaffinity(0, CPU_ALLOC_SIZE(2048), DynAffinity) == 0) {
- int NumCPUs = CPU_COUNT(DynAffinity);
- CPU_FREE(DynAffinity);
- return NumCPUs;
- }
- return -1;
-}
-#elif defined(__linux__) && defined(__s390x__)
-int computeHostNumPhysicalCores() { return sysconf(_SC_NPROCESSORS_ONLN); }
+#elif defined(__linux__) && defined(__powerpc__)
+int computeHostNumPhysicalCores() {
+ cpu_set_t Affinity;
+ if (sched_getaffinity(0, sizeof(Affinity), &Affinity) == 0)
+ return CPU_COUNT(&Affinity);
+
+ // The call to sched_getaffinity() may have failed because the Affinity
+ // mask is too small for the number of CPU's on the system (i.e. the
+ // system has more than 1024 CPUs). Allocate a mask large enough for
+ // twice as many CPUs.
+ cpu_set_t *DynAffinity;
+ DynAffinity = CPU_ALLOC(2048);
+ if (sched_getaffinity(0, CPU_ALLOC_SIZE(2048), DynAffinity) == 0) {
+ int NumCPUs = CPU_COUNT(DynAffinity);
+ CPU_FREE(DynAffinity);
+ return NumCPUs;
+ }
+ return -1;
+}
+#elif defined(__linux__) && defined(__s390x__)
+int computeHostNumPhysicalCores() { return sysconf(_SC_NPROCESSORS_ONLN); }
#elif defined(__APPLE__) && defined(__x86_64__)
#include <sys/param.h>
#include <sys/sysctl.h>
@@ -1351,28 +1351,28 @@ int computeHostNumPhysicalCores() {
}
return count;
}
-#elif defined(__MVS__)
-int computeHostNumPhysicalCores() {
- enum {
- // Byte offset of the pointer to the Communications Vector Table (CVT) in
- // the Prefixed Save Area (PSA). The table entry is a 31-bit pointer and
- // will be zero-extended to uintptr_t.
- FLCCVT = 16,
- // Byte offset of the pointer to the Common System Data Area (CSD) in the
- // CVT. The table entry is a 31-bit pointer and will be zero-extended to
- // uintptr_t.
- CVTCSD = 660,
- // Byte offset to the number of live CPs in the LPAR, stored as a signed
- // 32-bit value in the table.
- CSD_NUMBER_ONLINE_STANDARD_CPS = 264,
- };
- char *PSA = 0;
- char *CVT = reinterpret_cast<char *>(
- static_cast<uintptr_t>(reinterpret_cast<unsigned int &>(PSA[FLCCVT])));
- char *CSD = reinterpret_cast<char *>(
- static_cast<uintptr_t>(reinterpret_cast<unsigned int &>(CVT[CVTCSD])));
- return reinterpret_cast<int &>(CSD[CSD_NUMBER_ONLINE_STANDARD_CPS]);
-}
+#elif defined(__MVS__)
+int computeHostNumPhysicalCores() {
+ enum {
+ // Byte offset of the pointer to the Communications Vector Table (CVT) in
+ // the Prefixed Save Area (PSA). The table entry is a 31-bit pointer and
+ // will be zero-extended to uintptr_t.
+ FLCCVT = 16,
+ // Byte offset of the pointer to the Common System Data Area (CSD) in the
+ // CVT. The table entry is a 31-bit pointer and will be zero-extended to
+ // uintptr_t.
+ CVTCSD = 660,
+ // Byte offset to the number of live CPs in the LPAR, stored as a signed
+ // 32-bit value in the table.
+ CSD_NUMBER_ONLINE_STANDARD_CPS = 264,
+ };
+ char *PSA = 0;
+ char *CVT = reinterpret_cast<char *>(
+ static_cast<uintptr_t>(reinterpret_cast<unsigned int &>(PSA[FLCCVT])));
+ char *CSD = reinterpret_cast<char *>(
+ static_cast<uintptr_t>(reinterpret_cast<unsigned int &>(CVT[CVTCSD])));
+ return reinterpret_cast<int &>(CSD[CSD_NUMBER_ONLINE_STANDARD_CPS]);
+}
#elif defined(_WIN32) && LLVM_ENABLE_THREADS != 0
// Defined in llvm/lib/Support/Windows/Threading.inc
int computeHostNumPhysicalCores();
@@ -1502,13 +1502,13 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
Features["avx512bitalg"] = HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save;
Features["avx512vpopcntdq"] = HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save;
Features["rdpid"] = HasLeaf7 && ((ECX >> 22) & 1);
- Features["kl"] = HasLeaf7 && ((ECX >> 23) & 1); // key locker
+ Features["kl"] = HasLeaf7 && ((ECX >> 23) & 1); // key locker
Features["cldemote"] = HasLeaf7 && ((ECX >> 25) & 1);
Features["movdiri"] = HasLeaf7 && ((ECX >> 27) & 1);
Features["movdir64b"] = HasLeaf7 && ((ECX >> 28) & 1);
Features["enqcmd"] = HasLeaf7 && ((ECX >> 29) & 1);
- Features["uintr"] = HasLeaf7 && ((EDX >> 5) & 1);
+ Features["uintr"] = HasLeaf7 && ((EDX >> 5) & 1);
Features["avx512vp2intersect"] =
HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save;
Features["serialize"] = HasLeaf7 && ((EDX >> 14) & 1);
@@ -1529,9 +1529,9 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
Features["amx-int8"] = HasLeaf7 && ((EDX >> 25) & 1) && HasAMXSave;
bool HasLeaf7Subleaf1 =
MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
- Features["avxvnni"] = HasLeaf7Subleaf1 && ((EAX >> 4) & 1) && HasAVXSave;
+ Features["avxvnni"] = HasLeaf7Subleaf1 && ((EAX >> 4) & 1) && HasAVXSave;
Features["avx512bf16"] = HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save;
- Features["hreset"] = HasLeaf7Subleaf1 && ((EAX >> 22) & 1);
+ Features["hreset"] = HasLeaf7Subleaf1 && ((EAX >> 22) & 1);
bool HasLeafD = MaxLevel >= 0xd &&
!getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
@@ -1546,10 +1546,10 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
Features["ptwrite"] = HasLeaf14 && ((EBX >> 4) & 1);
- bool HasLeaf19 =
- MaxLevel >= 0x19 && !getX86CpuIDAndInfo(0x19, &EAX, &EBX, &ECX, &EDX);
- Features["widekl"] = HasLeaf7 && HasLeaf19 && ((EBX >> 2) & 1);
-
+ bool HasLeaf19 =
+ MaxLevel >= 0x19 && !getX86CpuIDAndInfo(0x19, &EAX, &EBX, &ECX, &EDX);
+ Features["widekl"] = HasLeaf7 && HasLeaf19 && ((EBX >> 2) & 1);
+
return true;
}
#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
diff --git a/contrib/libs/llvm12/lib/Support/InitLLVM.cpp b/contrib/libs/llvm12/lib/Support/InitLLVM.cpp
index e81b5d1fd1..152de6ebae 100644
--- a/contrib/libs/llvm12/lib/Support/InitLLVM.cpp
+++ b/contrib/libs/llvm12/lib/Support/InitLLVM.cpp
@@ -22,17 +22,17 @@ using namespace llvm;
using namespace llvm::sys;
InitLLVM::InitLLVM(int &Argc, const char **&Argv,
- bool InstallPipeSignalExitHandler) {
+ bool InstallPipeSignalExitHandler) {
if (InstallPipeSignalExitHandler)
- // The pipe signal handler must be installed before any other handlers are
- // registered. This is because the Unix \ref RegisterHandlers function does
- // not perform a sigaction() for SIGPIPE unless a one-shot handler is
- // present, to allow long-lived processes (like lldb) to fully opt-out of
- // llvm's SIGPIPE handling and ignore the signal safely.
+ // The pipe signal handler must be installed before any other handlers are
+ // registered. This is because the Unix \ref RegisterHandlers function does
+ // not perform a sigaction() for SIGPIPE unless a one-shot handler is
+ // present, to allow long-lived processes (like lldb) to fully opt-out of
+ // llvm's SIGPIPE handling and ignore the signal safely.
sys::SetOneShotPipeSignalFunction(sys::DefaultOneShotPipeSignalHandler);
- // Initialize the stack printer after installing the one-shot pipe signal
- // handler, so we can perform a sigaction() for SIGPIPE on Unix if requested.
- StackPrinter.emplace(Argc, Argv);
+ // Initialize the stack printer after installing the one-shot pipe signal
+ // handler, so we can perform a sigaction() for SIGPIPE on Unix if requested.
+ StackPrinter.emplace(Argc, Argv);
sys::PrintStackTraceOnErrorSignal(Argv[0]);
install_out_of_memory_new_handler();
diff --git a/contrib/libs/llvm12/lib/Support/InstructionCost.cpp b/contrib/libs/llvm12/lib/Support/InstructionCost.cpp
index 17ea31b7d1..c485ce9107 100644
--- a/contrib/libs/llvm12/lib/Support/InstructionCost.cpp
+++ b/contrib/libs/llvm12/lib/Support/InstructionCost.cpp
@@ -1,24 +1,24 @@
-//===- InstructionCost.cpp --------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// This file includes the function definitions for the InstructionCost class
-/// that is used when calculating the cost of an instruction, or a group of
-/// instructions.
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/InstructionCost.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace llvm;
-
-void InstructionCost::print(raw_ostream &OS) const {
- if (isValid())
- OS << Value;
- else
- OS << "Invalid";
-}
+//===- InstructionCost.cpp --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file includes the function definitions for the InstructionCost class
+/// that is used when calculating the cost of an instruction, or a group of
+/// instructions.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/InstructionCost.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+void InstructionCost::print(raw_ostream &OS) const {
+ if (isValid())
+ OS << Value;
+ else
+ OS << "Invalid";
+}
diff --git a/contrib/libs/llvm12/lib/Support/JSON.cpp b/contrib/libs/llvm12/lib/Support/JSON.cpp
index f23694efc4..dbfd673553 100644
--- a/contrib/libs/llvm12/lib/Support/JSON.cpp
+++ b/contrib/libs/llvm12/lib/Support/JSON.cpp
@@ -7,11 +7,11 @@
//===---------------------------------------------------------------------===//
#include "llvm/Support/JSON.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/Error.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/raw_ostream.h"
#include <cctype>
namespace llvm {
@@ -109,7 +109,7 @@ void Value::copyFrom(const Value &M) {
case T_Boolean:
case T_Double:
case T_Integer:
- memcpy(&Union, &M.Union, sizeof(Union));
+ memcpy(&Union, &M.Union, sizeof(Union));
break;
case T_StringRef:
create<StringRef>(M.as<StringRef>());
@@ -133,7 +133,7 @@ void Value::moveFrom(const Value &&M) {
case T_Boolean:
case T_Double:
case T_Integer:
- memcpy(&Union, &M.Union, sizeof(Union));
+ memcpy(&Union, &M.Union, sizeof(Union));
break;
case T_StringRef:
create<StringRef>(M.as<StringRef>());
@@ -201,161 +201,161 @@ bool operator==(const Value &L, const Value &R) {
llvm_unreachable("Unknown value kind");
}
-void Path::report(llvm::StringLiteral Msg) {
- // Walk up to the root context, and count the number of segments.
- unsigned Count = 0;
- const Path *P;
- for (P = this; P->Parent != nullptr; P = P->Parent)
- ++Count;
- Path::Root *R = P->Seg.root();
- // Fill in the error message and copy the path (in reverse order).
- R->ErrorMessage = Msg;
- R->ErrorPath.resize(Count);
- auto It = R->ErrorPath.begin();
- for (P = this; P->Parent != nullptr; P = P->Parent)
- *It++ = P->Seg;
-}
-
-Error Path::Root::getError() const {
- std::string S;
- raw_string_ostream OS(S);
- OS << (ErrorMessage.empty() ? "invalid JSON contents" : ErrorMessage);
- if (ErrorPath.empty()) {
- if (!Name.empty())
- OS << " when parsing " << Name;
- } else {
- OS << " at " << (Name.empty() ? "(root)" : Name);
- for (const Path::Segment &S : llvm::reverse(ErrorPath)) {
- if (S.isField())
- OS << '.' << S.field();
- else
- OS << '[' << S.index() << ']';
- }
- }
- return createStringError(llvm::inconvertibleErrorCode(), OS.str());
-}
-
+void Path::report(llvm::StringLiteral Msg) {
+ // Walk up to the root context, and count the number of segments.
+ unsigned Count = 0;
+ const Path *P;
+ for (P = this; P->Parent != nullptr; P = P->Parent)
+ ++Count;
+ Path::Root *R = P->Seg.root();
+ // Fill in the error message and copy the path (in reverse order).
+ R->ErrorMessage = Msg;
+ R->ErrorPath.resize(Count);
+ auto It = R->ErrorPath.begin();
+ for (P = this; P->Parent != nullptr; P = P->Parent)
+ *It++ = P->Seg;
+}
+
+Error Path::Root::getError() const {
+ std::string S;
+ raw_string_ostream OS(S);
+ OS << (ErrorMessage.empty() ? "invalid JSON contents" : ErrorMessage);
+ if (ErrorPath.empty()) {
+ if (!Name.empty())
+ OS << " when parsing " << Name;
+ } else {
+ OS << " at " << (Name.empty() ? "(root)" : Name);
+ for (const Path::Segment &S : llvm::reverse(ErrorPath)) {
+ if (S.isField())
+ OS << '.' << S.field();
+ else
+ OS << '[' << S.index() << ']';
+ }
+ }
+ return createStringError(llvm::inconvertibleErrorCode(), OS.str());
+}
+
+namespace {
+
+std::vector<const Object::value_type *> sortedElements(const Object &O) {
+ std::vector<const Object::value_type *> Elements;
+ for (const auto &E : O)
+ Elements.push_back(&E);
+ llvm::sort(Elements,
+ [](const Object::value_type *L, const Object::value_type *R) {
+ return L->first < R->first;
+ });
+ return Elements;
+}
+
+// Prints a one-line version of a value that isn't our main focus.
+// We interleave writes to OS and JOS, exploiting the lack of extra buffering.
+// This is OK as we own the implementation.
+void abbreviate(const Value &V, OStream &JOS) {
+ switch (V.kind()) {
+ case Value::Array:
+ JOS.rawValue(V.getAsArray()->empty() ? "[]" : "[ ... ]");
+ break;
+ case Value::Object:
+ JOS.rawValue(V.getAsObject()->empty() ? "{}" : "{ ... }");
+ break;
+ case Value::String: {
+ llvm::StringRef S = *V.getAsString();
+ if (S.size() < 40) {
+ JOS.value(V);
+ } else {
+ std::string Truncated = fixUTF8(S.take_front(37));
+ Truncated.append("...");
+ JOS.value(Truncated);
+ }
+ break;
+ }
+ default:
+ JOS.value(V);
+ }
+}
+
+// Prints a semi-expanded version of a value that is our main focus.
+// Array/Object entries are printed, but not recursively as they may be huge.
+void abbreviateChildren(const Value &V, OStream &JOS) {
+ switch (V.kind()) {
+ case Value::Array:
+ JOS.array([&] {
+ for (const auto &I : *V.getAsArray())
+ abbreviate(I, JOS);
+ });
+ break;
+ case Value::Object:
+ JOS.object([&] {
+ for (const auto *KV : sortedElements(*V.getAsObject())) {
+ JOS.attributeBegin(KV->first);
+ abbreviate(KV->second, JOS);
+ JOS.attributeEnd();
+ }
+ });
+ break;
+ default:
+ JOS.value(V);
+ }
+}
+
+} // namespace
+
+void Path::Root::printErrorContext(const Value &R, raw_ostream &OS) const {
+ OStream JOS(OS, /*IndentSize=*/2);
+ // PrintValue recurses down the path, printing the ancestors of our target.
+ // Siblings of nodes along the path are printed with abbreviate(), and the
+ // target itself is printed with the somewhat richer abbreviateChildren().
+ // 'Recurse' is the lambda itself, to allow recursive calls.
+ auto PrintValue = [&](const Value &V, ArrayRef<Segment> Path, auto &Recurse) {
+ // Print the target node itself, with the error as a comment.
+ // Also used if we can't follow our path, e.g. it names a field that
+ // *should* exist but doesn't.
+ auto HighlightCurrent = [&] {
+ std::string Comment = "error: ";
+ Comment.append(ErrorMessage.data(), ErrorMessage.size());
+ JOS.comment(Comment);
+ abbreviateChildren(V, JOS);
+ };
+ if (Path.empty()) // We reached our target.
+ return HighlightCurrent();
+ const Segment &S = Path.back(); // Path is in reverse order.
+ if (S.isField()) {
+ // Current node is an object, path names a field.
+ llvm::StringRef FieldName = S.field();
+ const Object *O = V.getAsObject();
+ if (!O || !O->get(FieldName))
+ return HighlightCurrent();
+ JOS.object([&] {
+ for (const auto *KV : sortedElements(*O)) {
+ JOS.attributeBegin(KV->first);
+ if (FieldName.equals(KV->first))
+ Recurse(KV->second, Path.drop_back(), Recurse);
+ else
+ abbreviate(KV->second, JOS);
+ JOS.attributeEnd();
+ }
+ });
+ } else {
+ // Current node is an array, path names an element.
+ const Array *A = V.getAsArray();
+ if (!A || S.index() >= A->size())
+ return HighlightCurrent();
+ JOS.array([&] {
+ unsigned Current = 0;
+ for (const auto &V : *A) {
+ if (Current++ == S.index())
+ Recurse(V, Path.drop_back(), Recurse);
+ else
+ abbreviate(V, JOS);
+ }
+ });
+ }
+ };
+ PrintValue(R, ErrorPath, PrintValue);
+}
+
namespace {
-
-std::vector<const Object::value_type *> sortedElements(const Object &O) {
- std::vector<const Object::value_type *> Elements;
- for (const auto &E : O)
- Elements.push_back(&E);
- llvm::sort(Elements,
- [](const Object::value_type *L, const Object::value_type *R) {
- return L->first < R->first;
- });
- return Elements;
-}
-
-// Prints a one-line version of a value that isn't our main focus.
-// We interleave writes to OS and JOS, exploiting the lack of extra buffering.
-// This is OK as we own the implementation.
-void abbreviate(const Value &V, OStream &JOS) {
- switch (V.kind()) {
- case Value::Array:
- JOS.rawValue(V.getAsArray()->empty() ? "[]" : "[ ... ]");
- break;
- case Value::Object:
- JOS.rawValue(V.getAsObject()->empty() ? "{}" : "{ ... }");
- break;
- case Value::String: {
- llvm::StringRef S = *V.getAsString();
- if (S.size() < 40) {
- JOS.value(V);
- } else {
- std::string Truncated = fixUTF8(S.take_front(37));
- Truncated.append("...");
- JOS.value(Truncated);
- }
- break;
- }
- default:
- JOS.value(V);
- }
-}
-
-// Prints a semi-expanded version of a value that is our main focus.
-// Array/Object entries are printed, but not recursively as they may be huge.
-void abbreviateChildren(const Value &V, OStream &JOS) {
- switch (V.kind()) {
- case Value::Array:
- JOS.array([&] {
- for (const auto &I : *V.getAsArray())
- abbreviate(I, JOS);
- });
- break;
- case Value::Object:
- JOS.object([&] {
- for (const auto *KV : sortedElements(*V.getAsObject())) {
- JOS.attributeBegin(KV->first);
- abbreviate(KV->second, JOS);
- JOS.attributeEnd();
- }
- });
- break;
- default:
- JOS.value(V);
- }
-}
-
-} // namespace
-
-void Path::Root::printErrorContext(const Value &R, raw_ostream &OS) const {
- OStream JOS(OS, /*IndentSize=*/2);
- // PrintValue recurses down the path, printing the ancestors of our target.
- // Siblings of nodes along the path are printed with abbreviate(), and the
- // target itself is printed with the somewhat richer abbreviateChildren().
- // 'Recurse' is the lambda itself, to allow recursive calls.
- auto PrintValue = [&](const Value &V, ArrayRef<Segment> Path, auto &Recurse) {
- // Print the target node itself, with the error as a comment.
- // Also used if we can't follow our path, e.g. it names a field that
- // *should* exist but doesn't.
- auto HighlightCurrent = [&] {
- std::string Comment = "error: ";
- Comment.append(ErrorMessage.data(), ErrorMessage.size());
- JOS.comment(Comment);
- abbreviateChildren(V, JOS);
- };
- if (Path.empty()) // We reached our target.
- return HighlightCurrent();
- const Segment &S = Path.back(); // Path is in reverse order.
- if (S.isField()) {
- // Current node is an object, path names a field.
- llvm::StringRef FieldName = S.field();
- const Object *O = V.getAsObject();
- if (!O || !O->get(FieldName))
- return HighlightCurrent();
- JOS.object([&] {
- for (const auto *KV : sortedElements(*O)) {
- JOS.attributeBegin(KV->first);
- if (FieldName.equals(KV->first))
- Recurse(KV->second, Path.drop_back(), Recurse);
- else
- abbreviate(KV->second, JOS);
- JOS.attributeEnd();
- }
- });
- } else {
- // Current node is an array, path names an element.
- const Array *A = V.getAsArray();
- if (!A || S.index() >= A->size())
- return HighlightCurrent();
- JOS.array([&] {
- unsigned Current = 0;
- for (const auto &V : *A) {
- if (Current++ == S.index())
- Recurse(V, Path.drop_back(), Recurse);
- else
- abbreviate(V, JOS);
- }
- });
- }
- };
- PrintValue(R, ErrorPath, PrintValue);
-}
-
-namespace {
// Simple recursive-descent JSON parser.
class Parser {
public:
@@ -779,40 +779,40 @@ void llvm::json::OStream::valueBegin() {
}
if (Stack.back().Ctx == Array)
newline();
- flushComment();
+ flushComment();
Stack.back().HasValue = true;
}
-void OStream::comment(llvm::StringRef Comment) {
- assert(PendingComment.empty() && "Only one comment per value!");
- PendingComment = Comment;
-}
-
-void OStream::flushComment() {
- if (PendingComment.empty())
- return;
- OS << (IndentSize ? "/* " : "/*");
- // Be sure not to accidentally emit "*/". Transform to "* /".
- while (!PendingComment.empty()) {
- auto Pos = PendingComment.find("*/");
- if (Pos == StringRef::npos) {
- OS << PendingComment;
- PendingComment = "";
- } else {
- OS << PendingComment.take_front(Pos) << "* /";
- PendingComment = PendingComment.drop_front(Pos + 2);
- }
- }
- OS << (IndentSize ? " */" : "*/");
- // Comments are on their own line unless attached to an attribute value.
- if (Stack.size() > 1 && Stack.back().Ctx == Singleton) {
- if (IndentSize)
- OS << ' ';
- } else {
- newline();
- }
-}
-
+void OStream::comment(llvm::StringRef Comment) {
+ assert(PendingComment.empty() && "Only one comment per value!");
+ PendingComment = Comment;
+}
+
+void OStream::flushComment() {
+ if (PendingComment.empty())
+ return;
+ OS << (IndentSize ? "/* " : "/*");
+ // Be sure not to accidentally emit "*/". Transform to "* /".
+ while (!PendingComment.empty()) {
+ auto Pos = PendingComment.find("*/");
+ if (Pos == StringRef::npos) {
+ OS << PendingComment;
+ PendingComment = "";
+ } else {
+ OS << PendingComment.take_front(Pos) << "* /";
+ PendingComment = PendingComment.drop_front(Pos + 2);
+ }
+ }
+ OS << (IndentSize ? " */" : "*/");
+ // Comments are on their own line unless attached to an attribute value.
+ if (Stack.size() > 1 && Stack.back().Ctx == Singleton) {
+ if (IndentSize)
+ OS << ' ';
+ } else {
+ newline();
+ }
+}
+
void llvm::json::OStream::newline() {
if (IndentSize) {
OS.write('\n');
@@ -834,7 +834,7 @@ void llvm::json::OStream::arrayEnd() {
if (Stack.back().HasValue)
newline();
OS << ']';
- assert(PendingComment.empty());
+ assert(PendingComment.empty());
Stack.pop_back();
assert(!Stack.empty());
}
@@ -853,7 +853,7 @@ void llvm::json::OStream::objectEnd() {
if (Stack.back().HasValue)
newline();
OS << '}';
- assert(PendingComment.empty());
+ assert(PendingComment.empty());
Stack.pop_back();
assert(!Stack.empty());
}
@@ -863,7 +863,7 @@ void llvm::json::OStream::attributeBegin(llvm::StringRef Key) {
if (Stack.back().HasValue)
OS << ',';
newline();
- flushComment();
+ flushComment();
Stack.back().HasValue = true;
Stack.emplace_back();
Stack.back().Ctx = Singleton;
@@ -881,23 +881,23 @@ void llvm::json::OStream::attributeBegin(llvm::StringRef Key) {
void llvm::json::OStream::attributeEnd() {
assert(Stack.back().Ctx == Singleton);
assert(Stack.back().HasValue && "Attribute must have a value");
- assert(PendingComment.empty());
+ assert(PendingComment.empty());
Stack.pop_back();
assert(Stack.back().Ctx == Object);
}
-raw_ostream &llvm::json::OStream::rawValueBegin() {
- valueBegin();
- Stack.emplace_back();
- Stack.back().Ctx = RawValue;
- return OS;
-}
-
-void llvm::json::OStream::rawValueEnd() {
- assert(Stack.back().Ctx == RawValue);
- Stack.pop_back();
-}
-
+raw_ostream &llvm::json::OStream::rawValueBegin() {
+ valueBegin();
+ Stack.emplace_back();
+ Stack.back().Ctx = RawValue;
+ return OS;
+}
+
+void llvm::json::OStream::rawValueEnd() {
+ assert(Stack.back().Ctx == RawValue);
+ Stack.pop_back();
+}
+
} // namespace json
} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/Support/KnownBits.cpp b/contrib/libs/llvm12/lib/Support/KnownBits.cpp
index dcd51675e9..3623a54ae4 100644
--- a/contrib/libs/llvm12/lib/Support/KnownBits.cpp
+++ b/contrib/libs/llvm12/lib/Support/KnownBits.cpp
@@ -83,403 +83,403 @@ KnownBits KnownBits::computeForAddSub(bool Add, bool NSW,
return KnownOut;
}
-KnownBits KnownBits::sextInReg(unsigned SrcBitWidth) const {
- unsigned BitWidth = getBitWidth();
- assert(0 < SrcBitWidth && SrcBitWidth <= BitWidth &&
- "Illegal sext-in-register");
-
- if (SrcBitWidth == BitWidth)
- return *this;
-
- unsigned ExtBits = BitWidth - SrcBitWidth;
- KnownBits Result;
- Result.One = One << ExtBits;
- Result.Zero = Zero << ExtBits;
- Result.One.ashrInPlace(ExtBits);
- Result.Zero.ashrInPlace(ExtBits);
- return Result;
-}
-
-KnownBits KnownBits::makeGE(const APInt &Val) const {
- // Count the number of leading bit positions where our underlying value is
- // known to be less than or equal to Val.
- unsigned N = (Zero | Val).countLeadingOnes();
-
- // For each of those bit positions, if Val has a 1 in that bit then our
- // underlying value must also have a 1.
- APInt MaskedVal(Val);
- MaskedVal.clearLowBits(getBitWidth() - N);
- return KnownBits(Zero, One | MaskedVal);
-}
-
-KnownBits KnownBits::umax(const KnownBits &LHS, const KnownBits &RHS) {
- // If we can prove that LHS >= RHS then use LHS as the result. Likewise for
- // RHS. Ideally our caller would already have spotted these cases and
- // optimized away the umax operation, but we handle them here for
- // completeness.
- if (LHS.getMinValue().uge(RHS.getMaxValue()))
- return LHS;
- if (RHS.getMinValue().uge(LHS.getMaxValue()))
- return RHS;
-
- // If the result of the umax is LHS then it must be greater than or equal to
- // the minimum possible value of RHS. Likewise for RHS. Any known bits that
- // are common to these two values are also known in the result.
- KnownBits L = LHS.makeGE(RHS.getMinValue());
- KnownBits R = RHS.makeGE(LHS.getMinValue());
- return KnownBits::commonBits(L, R);
-}
-
-KnownBits KnownBits::umin(const KnownBits &LHS, const KnownBits &RHS) {
- // Flip the range of values: [0, 0xFFFFFFFF] <-> [0xFFFFFFFF, 0]
- auto Flip = [](const KnownBits &Val) { return KnownBits(Val.One, Val.Zero); };
- return Flip(umax(Flip(LHS), Flip(RHS)));
-}
-
-KnownBits KnownBits::smax(const KnownBits &LHS, const KnownBits &RHS) {
- // Flip the range of values: [-0x80000000, 0x7FFFFFFF] <-> [0, 0xFFFFFFFF]
- auto Flip = [](const KnownBits &Val) {
- unsigned SignBitPosition = Val.getBitWidth() - 1;
- APInt Zero = Val.Zero;
- APInt One = Val.One;
- Zero.setBitVal(SignBitPosition, Val.One[SignBitPosition]);
- One.setBitVal(SignBitPosition, Val.Zero[SignBitPosition]);
- return KnownBits(Zero, One);
- };
- return Flip(umax(Flip(LHS), Flip(RHS)));
-}
-
-KnownBits KnownBits::smin(const KnownBits &LHS, const KnownBits &RHS) {
- // Flip the range of values: [-0x80000000, 0x7FFFFFFF] <-> [0xFFFFFFFF, 0]
- auto Flip = [](const KnownBits &Val) {
- unsigned SignBitPosition = Val.getBitWidth() - 1;
- APInt Zero = Val.One;
- APInt One = Val.Zero;
- Zero.setBitVal(SignBitPosition, Val.Zero[SignBitPosition]);
- One.setBitVal(SignBitPosition, Val.One[SignBitPosition]);
- return KnownBits(Zero, One);
- };
- return Flip(umax(Flip(LHS), Flip(RHS)));
-}
-
-KnownBits KnownBits::shl(const KnownBits &LHS, const KnownBits &RHS) {
- unsigned BitWidth = LHS.getBitWidth();
- KnownBits Known(BitWidth);
-
- // If the shift amount is a valid constant then transform LHS directly.
- if (RHS.isConstant() && RHS.getConstant().ult(BitWidth)) {
- unsigned Shift = RHS.getConstant().getZExtValue();
- Known = LHS;
- Known.Zero <<= Shift;
- Known.One <<= Shift;
- // Low bits are known zero.
- Known.Zero.setLowBits(Shift);
- return Known;
- }
-
- // No matter the shift amount, the trailing zeros will stay zero.
- unsigned MinTrailingZeros = LHS.countMinTrailingZeros();
-
- // Minimum shift amount low bits are known zero.
- if (RHS.getMinValue().ult(BitWidth)) {
- MinTrailingZeros += RHS.getMinValue().getZExtValue();
- MinTrailingZeros = std::min(MinTrailingZeros, BitWidth);
- }
-
- Known.Zero.setLowBits(MinTrailingZeros);
- return Known;
-}
-
-KnownBits KnownBits::lshr(const KnownBits &LHS, const KnownBits &RHS) {
- unsigned BitWidth = LHS.getBitWidth();
- KnownBits Known(BitWidth);
-
- if (RHS.isConstant() && RHS.getConstant().ult(BitWidth)) {
- unsigned Shift = RHS.getConstant().getZExtValue();
- Known = LHS;
- Known.Zero.lshrInPlace(Shift);
- Known.One.lshrInPlace(Shift);
- // High bits are known zero.
- Known.Zero.setHighBits(Shift);
- return Known;
- }
-
- // No matter the shift amount, the leading zeros will stay zero.
- unsigned MinLeadingZeros = LHS.countMinLeadingZeros();
-
- // Minimum shift amount high bits are known zero.
- if (RHS.getMinValue().ult(BitWidth)) {
- MinLeadingZeros += RHS.getMinValue().getZExtValue();
- MinLeadingZeros = std::min(MinLeadingZeros, BitWidth);
- }
-
- Known.Zero.setHighBits(MinLeadingZeros);
- return Known;
-}
-
-KnownBits KnownBits::ashr(const KnownBits &LHS, const KnownBits &RHS) {
- unsigned BitWidth = LHS.getBitWidth();
- KnownBits Known(BitWidth);
-
- if (RHS.isConstant() && RHS.getConstant().ult(BitWidth)) {
- unsigned Shift = RHS.getConstant().getZExtValue();
- Known = LHS;
- Known.Zero.ashrInPlace(Shift);
- Known.One.ashrInPlace(Shift);
- return Known;
- }
-
- // No matter the shift amount, the leading sign bits will stay.
- unsigned MinLeadingZeros = LHS.countMinLeadingZeros();
- unsigned MinLeadingOnes = LHS.countMinLeadingOnes();
-
- // Minimum shift amount high bits are known sign bits.
- if (RHS.getMinValue().ult(BitWidth)) {
- if (MinLeadingZeros) {
- MinLeadingZeros += RHS.getMinValue().getZExtValue();
- MinLeadingZeros = std::min(MinLeadingZeros, BitWidth);
- }
- if (MinLeadingOnes) {
- MinLeadingOnes += RHS.getMinValue().getZExtValue();
- MinLeadingOnes = std::min(MinLeadingOnes, BitWidth);
- }
- }
-
- Known.Zero.setHighBits(MinLeadingZeros);
- Known.One.setHighBits(MinLeadingOnes);
- return Known;
-}
-
-Optional<bool> KnownBits::eq(const KnownBits &LHS, const KnownBits &RHS) {
- if (LHS.isConstant() && RHS.isConstant())
- return Optional<bool>(LHS.getConstant() == RHS.getConstant());
- if (LHS.One.intersects(RHS.Zero) || RHS.One.intersects(LHS.Zero))
- return Optional<bool>(false);
- return None;
-}
-
-Optional<bool> KnownBits::ne(const KnownBits &LHS, const KnownBits &RHS) {
- if (Optional<bool> KnownEQ = eq(LHS, RHS))
- return Optional<bool>(!KnownEQ.getValue());
- return None;
-}
-
-Optional<bool> KnownBits::ugt(const KnownBits &LHS, const KnownBits &RHS) {
- // LHS >u RHS -> false if umax(LHS) <= umax(RHS)
- if (LHS.getMaxValue().ule(RHS.getMinValue()))
- return Optional<bool>(false);
- // LHS >u RHS -> true if umin(LHS) > umax(RHS)
- if (LHS.getMinValue().ugt(RHS.getMaxValue()))
- return Optional<bool>(true);
- return None;
-}
-
-Optional<bool> KnownBits::uge(const KnownBits &LHS, const KnownBits &RHS) {
- if (Optional<bool> IsUGT = ugt(RHS, LHS))
- return Optional<bool>(!IsUGT.getValue());
- return None;
-}
-
-Optional<bool> KnownBits::ult(const KnownBits &LHS, const KnownBits &RHS) {
- return ugt(RHS, LHS);
-}
-
-Optional<bool> KnownBits::ule(const KnownBits &LHS, const KnownBits &RHS) {
- return uge(RHS, LHS);
-}
-
-Optional<bool> KnownBits::sgt(const KnownBits &LHS, const KnownBits &RHS) {
- // LHS >s RHS -> false if smax(LHS) <= smax(RHS)
- if (LHS.getSignedMaxValue().sle(RHS.getSignedMinValue()))
- return Optional<bool>(false);
- // LHS >s RHS -> true if smin(LHS) > smax(RHS)
- if (LHS.getSignedMinValue().sgt(RHS.getSignedMaxValue()))
- return Optional<bool>(true);
- return None;
-}
-
-Optional<bool> KnownBits::sge(const KnownBits &LHS, const KnownBits &RHS) {
- if (Optional<bool> KnownSGT = sgt(RHS, LHS))
- return Optional<bool>(!KnownSGT.getValue());
- return None;
-}
-
-Optional<bool> KnownBits::slt(const KnownBits &LHS, const KnownBits &RHS) {
- return sgt(RHS, LHS);
-}
-
-Optional<bool> KnownBits::sle(const KnownBits &LHS, const KnownBits &RHS) {
- return sge(RHS, LHS);
-}
-
-KnownBits KnownBits::abs(bool IntMinIsPoison) const {
- // If the source's MSB is zero then we know the rest of the bits already.
- if (isNonNegative())
- return *this;
-
- // Absolute value preserves trailing zero count.
- KnownBits KnownAbs(getBitWidth());
- KnownAbs.Zero.setLowBits(countMinTrailingZeros());
-
- // We only know that the absolute values's MSB will be zero if INT_MIN is
- // poison, or there is a set bit that isn't the sign bit (otherwise it could
- // be INT_MIN).
- if (IntMinIsPoison || (!One.isNullValue() && !One.isMinSignedValue()))
- KnownAbs.Zero.setSignBit();
-
- // FIXME: Handle known negative input?
- // FIXME: Calculate the negated Known bits and combine them?
- return KnownAbs;
-}
-
-KnownBits KnownBits::computeForMul(const KnownBits &LHS, const KnownBits &RHS) {
- unsigned BitWidth = LHS.getBitWidth();
-
- assert(!LHS.hasConflict() && !RHS.hasConflict());
- // Compute a conservative estimate for high known-0 bits.
- unsigned LeadZ =
- std::max(LHS.countMinLeadingZeros() + RHS.countMinLeadingZeros(),
- BitWidth) -
- BitWidth;
- LeadZ = std::min(LeadZ, BitWidth);
-
- // The result of the bottom bits of an integer multiply can be
- // inferred by looking at the bottom bits of both operands and
- // multiplying them together.
- // We can infer at least the minimum number of known trailing bits
- // of both operands. Depending on number of trailing zeros, we can
- // infer more bits, because (a*b) <=> ((a/m) * (b/n)) * (m*n) assuming
- // a and b are divisible by m and n respectively.
- // We then calculate how many of those bits are inferrable and set
- // the output. For example, the i8 mul:
- // a = XXXX1100 (12)
- // b = XXXX1110 (14)
- // We know the bottom 3 bits are zero since the first can be divided by
- // 4 and the second by 2, thus having ((12/4) * (14/2)) * (2*4).
- // Applying the multiplication to the trimmed arguments gets:
- // XX11 (3)
- // X111 (7)
- // -------
- // XX11
- // XX11
- // XX11
- // XX11
- // -------
- // XXXXX01
- // Which allows us to infer the 2 LSBs. Since we're multiplying the result
- // by 8, the bottom 3 bits will be 0, so we can infer a total of 5 bits.
- // The proof for this can be described as:
- // Pre: (C1 >= 0) && (C1 < (1 << C5)) && (C2 >= 0) && (C2 < (1 << C6)) &&
- // (C7 == (1 << (umin(countTrailingZeros(C1), C5) +
- // umin(countTrailingZeros(C2), C6) +
- // umin(C5 - umin(countTrailingZeros(C1), C5),
- // C6 - umin(countTrailingZeros(C2), C6)))) - 1)
- // %aa = shl i8 %a, C5
- // %bb = shl i8 %b, C6
- // %aaa = or i8 %aa, C1
- // %bbb = or i8 %bb, C2
- // %mul = mul i8 %aaa, %bbb
- // %mask = and i8 %mul, C7
- // =>
- // %mask = i8 ((C1*C2)&C7)
- // Where C5, C6 describe the known bits of %a, %b
- // C1, C2 describe the known bottom bits of %a, %b.
- // C7 describes the mask of the known bits of the result.
- const APInt &Bottom0 = LHS.One;
- const APInt &Bottom1 = RHS.One;
-
- // How many times we'd be able to divide each argument by 2 (shr by 1).
- // This gives us the number of trailing zeros on the multiplication result.
- unsigned TrailBitsKnown0 = (LHS.Zero | LHS.One).countTrailingOnes();
- unsigned TrailBitsKnown1 = (RHS.Zero | RHS.One).countTrailingOnes();
- unsigned TrailZero0 = LHS.countMinTrailingZeros();
- unsigned TrailZero1 = RHS.countMinTrailingZeros();
- unsigned TrailZ = TrailZero0 + TrailZero1;
-
- // Figure out the fewest known-bits operand.
- unsigned SmallestOperand =
- std::min(TrailBitsKnown0 - TrailZero0, TrailBitsKnown1 - TrailZero1);
- unsigned ResultBitsKnown = std::min(SmallestOperand + TrailZ, BitWidth);
-
- APInt BottomKnown =
- Bottom0.getLoBits(TrailBitsKnown0) * Bottom1.getLoBits(TrailBitsKnown1);
-
- KnownBits Res(BitWidth);
- Res.Zero.setHighBits(LeadZ);
- Res.Zero |= (~BottomKnown).getLoBits(ResultBitsKnown);
- Res.One = BottomKnown.getLoBits(ResultBitsKnown);
- return Res;
-}
-
-KnownBits KnownBits::udiv(const KnownBits &LHS, const KnownBits &RHS) {
- unsigned BitWidth = LHS.getBitWidth();
- assert(!LHS.hasConflict() && !RHS.hasConflict());
- KnownBits Known(BitWidth);
-
- // For the purposes of computing leading zeros we can conservatively
- // treat a udiv as a logical right shift by the power of 2 known to
- // be less than the denominator.
- unsigned LeadZ = LHS.countMinLeadingZeros();
- unsigned RHSMaxLeadingZeros = RHS.countMaxLeadingZeros();
-
- if (RHSMaxLeadingZeros != BitWidth)
- LeadZ = std::min(BitWidth, LeadZ + BitWidth - RHSMaxLeadingZeros - 1);
-
- Known.Zero.setHighBits(LeadZ);
- return Known;
-}
-
-KnownBits KnownBits::urem(const KnownBits &LHS, const KnownBits &RHS) {
- unsigned BitWidth = LHS.getBitWidth();
- assert(!LHS.hasConflict() && !RHS.hasConflict());
- KnownBits Known(BitWidth);
-
- if (RHS.isConstant() && RHS.getConstant().isPowerOf2()) {
- // The upper bits are all zero, the lower ones are unchanged.
- APInt LowBits = RHS.getConstant() - 1;
- Known.Zero = LHS.Zero | ~LowBits;
- Known.One = LHS.One & LowBits;
- return Known;
- }
-
- // Since the result is less than or equal to either operand, any leading
- // zero bits in either operand must also exist in the result.
- uint32_t Leaders =
- std::max(LHS.countMinLeadingZeros(), RHS.countMinLeadingZeros());
- Known.Zero.setHighBits(Leaders);
- return Known;
-}
-
-KnownBits KnownBits::srem(const KnownBits &LHS, const KnownBits &RHS) {
- unsigned BitWidth = LHS.getBitWidth();
- assert(!LHS.hasConflict() && !RHS.hasConflict());
- KnownBits Known(BitWidth);
-
- if (RHS.isConstant() && RHS.getConstant().isPowerOf2()) {
- // The low bits of the first operand are unchanged by the srem.
- APInt LowBits = RHS.getConstant() - 1;
- Known.Zero = LHS.Zero & LowBits;
- Known.One = LHS.One & LowBits;
-
- // If the first operand is non-negative or has all low bits zero, then
- // the upper bits are all zero.
- if (LHS.isNonNegative() || LowBits.isSubsetOf(LHS.Zero))
- Known.Zero |= ~LowBits;
-
- // If the first operand is negative and not all low bits are zero, then
- // the upper bits are all one.
- if (LHS.isNegative() && LowBits.intersects(LHS.One))
- Known.One |= ~LowBits;
- return Known;
- }
-
- // The sign bit is the LHS's sign bit, except when the result of the
- // remainder is zero. If it's known zero, our sign bit is also zero.
- if (LHS.isNonNegative())
- Known.makeNonNegative();
- return Known;
-}
-
+KnownBits KnownBits::sextInReg(unsigned SrcBitWidth) const {
+ unsigned BitWidth = getBitWidth();
+ assert(0 < SrcBitWidth && SrcBitWidth <= BitWidth &&
+ "Illegal sext-in-register");
+
+ if (SrcBitWidth == BitWidth)
+ return *this;
+
+ unsigned ExtBits = BitWidth - SrcBitWidth;
+ KnownBits Result;
+ Result.One = One << ExtBits;
+ Result.Zero = Zero << ExtBits;
+ Result.One.ashrInPlace(ExtBits);
+ Result.Zero.ashrInPlace(ExtBits);
+ return Result;
+}
+
+KnownBits KnownBits::makeGE(const APInt &Val) const {
+ // Count the number of leading bit positions where our underlying value is
+ // known to be less than or equal to Val.
+ unsigned N = (Zero | Val).countLeadingOnes();
+
+ // For each of those bit positions, if Val has a 1 in that bit then our
+ // underlying value must also have a 1.
+ APInt MaskedVal(Val);
+ MaskedVal.clearLowBits(getBitWidth() - N);
+ return KnownBits(Zero, One | MaskedVal);
+}
+
+KnownBits KnownBits::umax(const KnownBits &LHS, const KnownBits &RHS) {
+ // If we can prove that LHS >= RHS then use LHS as the result. Likewise for
+ // RHS. Ideally our caller would already have spotted these cases and
+ // optimized away the umax operation, but we handle them here for
+ // completeness.
+ if (LHS.getMinValue().uge(RHS.getMaxValue()))
+ return LHS;
+ if (RHS.getMinValue().uge(LHS.getMaxValue()))
+ return RHS;
+
+ // If the result of the umax is LHS then it must be greater than or equal to
+ // the minimum possible value of RHS. Likewise for RHS. Any known bits that
+ // are common to these two values are also known in the result.
+ KnownBits L = LHS.makeGE(RHS.getMinValue());
+ KnownBits R = RHS.makeGE(LHS.getMinValue());
+ return KnownBits::commonBits(L, R);
+}
+
+KnownBits KnownBits::umin(const KnownBits &LHS, const KnownBits &RHS) {
+ // Flip the range of values: [0, 0xFFFFFFFF] <-> [0xFFFFFFFF, 0]
+ auto Flip = [](const KnownBits &Val) { return KnownBits(Val.One, Val.Zero); };
+ return Flip(umax(Flip(LHS), Flip(RHS)));
+}
+
+KnownBits KnownBits::smax(const KnownBits &LHS, const KnownBits &RHS) {
+ // Flip the range of values: [-0x80000000, 0x7FFFFFFF] <-> [0, 0xFFFFFFFF]
+ auto Flip = [](const KnownBits &Val) {
+ unsigned SignBitPosition = Val.getBitWidth() - 1;
+ APInt Zero = Val.Zero;
+ APInt One = Val.One;
+ Zero.setBitVal(SignBitPosition, Val.One[SignBitPosition]);
+ One.setBitVal(SignBitPosition, Val.Zero[SignBitPosition]);
+ return KnownBits(Zero, One);
+ };
+ return Flip(umax(Flip(LHS), Flip(RHS)));
+}
+
+KnownBits KnownBits::smin(const KnownBits &LHS, const KnownBits &RHS) {
+ // Flip the range of values: [-0x80000000, 0x7FFFFFFF] <-> [0xFFFFFFFF, 0]
+ auto Flip = [](const KnownBits &Val) {
+ unsigned SignBitPosition = Val.getBitWidth() - 1;
+ APInt Zero = Val.One;
+ APInt One = Val.Zero;
+ Zero.setBitVal(SignBitPosition, Val.Zero[SignBitPosition]);
+ One.setBitVal(SignBitPosition, Val.One[SignBitPosition]);
+ return KnownBits(Zero, One);
+ };
+ return Flip(umax(Flip(LHS), Flip(RHS)));
+}
+
+KnownBits KnownBits::shl(const KnownBits &LHS, const KnownBits &RHS) {
+ unsigned BitWidth = LHS.getBitWidth();
+ KnownBits Known(BitWidth);
+
+ // If the shift amount is a valid constant then transform LHS directly.
+ if (RHS.isConstant() && RHS.getConstant().ult(BitWidth)) {
+ unsigned Shift = RHS.getConstant().getZExtValue();
+ Known = LHS;
+ Known.Zero <<= Shift;
+ Known.One <<= Shift;
+ // Low bits are known zero.
+ Known.Zero.setLowBits(Shift);
+ return Known;
+ }
+
+ // No matter the shift amount, the trailing zeros will stay zero.
+ unsigned MinTrailingZeros = LHS.countMinTrailingZeros();
+
+ // Minimum shift amount low bits are known zero.
+ if (RHS.getMinValue().ult(BitWidth)) {
+ MinTrailingZeros += RHS.getMinValue().getZExtValue();
+ MinTrailingZeros = std::min(MinTrailingZeros, BitWidth);
+ }
+
+ Known.Zero.setLowBits(MinTrailingZeros);
+ return Known;
+}
+
+KnownBits KnownBits::lshr(const KnownBits &LHS, const KnownBits &RHS) {
+ unsigned BitWidth = LHS.getBitWidth();
+ KnownBits Known(BitWidth);
+
+ if (RHS.isConstant() && RHS.getConstant().ult(BitWidth)) {
+ unsigned Shift = RHS.getConstant().getZExtValue();
+ Known = LHS;
+ Known.Zero.lshrInPlace(Shift);
+ Known.One.lshrInPlace(Shift);
+ // High bits are known zero.
+ Known.Zero.setHighBits(Shift);
+ return Known;
+ }
+
+ // No matter the shift amount, the leading zeros will stay zero.
+ unsigned MinLeadingZeros = LHS.countMinLeadingZeros();
+
+ // Minimum shift amount high bits are known zero.
+ if (RHS.getMinValue().ult(BitWidth)) {
+ MinLeadingZeros += RHS.getMinValue().getZExtValue();
+ MinLeadingZeros = std::min(MinLeadingZeros, BitWidth);
+ }
+
+ Known.Zero.setHighBits(MinLeadingZeros);
+ return Known;
+}
+
+KnownBits KnownBits::ashr(const KnownBits &LHS, const KnownBits &RHS) {
+ unsigned BitWidth = LHS.getBitWidth();
+ KnownBits Known(BitWidth);
+
+ if (RHS.isConstant() && RHS.getConstant().ult(BitWidth)) {
+ unsigned Shift = RHS.getConstant().getZExtValue();
+ Known = LHS;
+ Known.Zero.ashrInPlace(Shift);
+ Known.One.ashrInPlace(Shift);
+ return Known;
+ }
+
+ // No matter the shift amount, the leading sign bits will stay.
+ unsigned MinLeadingZeros = LHS.countMinLeadingZeros();
+ unsigned MinLeadingOnes = LHS.countMinLeadingOnes();
+
+ // Minimum shift amount high bits are known sign bits.
+ if (RHS.getMinValue().ult(BitWidth)) {
+ if (MinLeadingZeros) {
+ MinLeadingZeros += RHS.getMinValue().getZExtValue();
+ MinLeadingZeros = std::min(MinLeadingZeros, BitWidth);
+ }
+ if (MinLeadingOnes) {
+ MinLeadingOnes += RHS.getMinValue().getZExtValue();
+ MinLeadingOnes = std::min(MinLeadingOnes, BitWidth);
+ }
+ }
+
+ Known.Zero.setHighBits(MinLeadingZeros);
+ Known.One.setHighBits(MinLeadingOnes);
+ return Known;
+}
+
+Optional<bool> KnownBits::eq(const KnownBits &LHS, const KnownBits &RHS) {
+ if (LHS.isConstant() && RHS.isConstant())
+ return Optional<bool>(LHS.getConstant() == RHS.getConstant());
+ if (LHS.One.intersects(RHS.Zero) || RHS.One.intersects(LHS.Zero))
+ return Optional<bool>(false);
+ return None;
+}
+
+Optional<bool> KnownBits::ne(const KnownBits &LHS, const KnownBits &RHS) {
+ if (Optional<bool> KnownEQ = eq(LHS, RHS))
+ return Optional<bool>(!KnownEQ.getValue());
+ return None;
+}
+
+Optional<bool> KnownBits::ugt(const KnownBits &LHS, const KnownBits &RHS) {
+ // LHS >u RHS -> false if umax(LHS) <= umax(RHS)
+ if (LHS.getMaxValue().ule(RHS.getMinValue()))
+ return Optional<bool>(false);
+ // LHS >u RHS -> true if umin(LHS) > umax(RHS)
+ if (LHS.getMinValue().ugt(RHS.getMaxValue()))
+ return Optional<bool>(true);
+ return None;
+}
+
+Optional<bool> KnownBits::uge(const KnownBits &LHS, const KnownBits &RHS) {
+ if (Optional<bool> IsUGT = ugt(RHS, LHS))
+ return Optional<bool>(!IsUGT.getValue());
+ return None;
+}
+
+Optional<bool> KnownBits::ult(const KnownBits &LHS, const KnownBits &RHS) {
+ return ugt(RHS, LHS);
+}
+
+Optional<bool> KnownBits::ule(const KnownBits &LHS, const KnownBits &RHS) {
+ return uge(RHS, LHS);
+}
+
+Optional<bool> KnownBits::sgt(const KnownBits &LHS, const KnownBits &RHS) {
+ // LHS >s RHS -> false if smax(LHS) <= smax(RHS)
+ if (LHS.getSignedMaxValue().sle(RHS.getSignedMinValue()))
+ return Optional<bool>(false);
+ // LHS >s RHS -> true if smin(LHS) > smax(RHS)
+ if (LHS.getSignedMinValue().sgt(RHS.getSignedMaxValue()))
+ return Optional<bool>(true);
+ return None;
+}
+
+Optional<bool> KnownBits::sge(const KnownBits &LHS, const KnownBits &RHS) {
+ if (Optional<bool> KnownSGT = sgt(RHS, LHS))
+ return Optional<bool>(!KnownSGT.getValue());
+ return None;
+}
+
+Optional<bool> KnownBits::slt(const KnownBits &LHS, const KnownBits &RHS) {
+ return sgt(RHS, LHS);
+}
+
+Optional<bool> KnownBits::sle(const KnownBits &LHS, const KnownBits &RHS) {
+ return sge(RHS, LHS);
+}
+
+KnownBits KnownBits::abs(bool IntMinIsPoison) const {
+ // If the source's MSB is zero then we know the rest of the bits already.
+ if (isNonNegative())
+ return *this;
+
+ // Absolute value preserves trailing zero count.
+ KnownBits KnownAbs(getBitWidth());
+ KnownAbs.Zero.setLowBits(countMinTrailingZeros());
+
+ // We only know that the absolute values's MSB will be zero if INT_MIN is
+ // poison, or there is a set bit that isn't the sign bit (otherwise it could
+ // be INT_MIN).
+ if (IntMinIsPoison || (!One.isNullValue() && !One.isMinSignedValue()))
+ KnownAbs.Zero.setSignBit();
+
+ // FIXME: Handle known negative input?
+ // FIXME: Calculate the negated Known bits and combine them?
+ return KnownAbs;
+}
+
+KnownBits KnownBits::computeForMul(const KnownBits &LHS, const KnownBits &RHS) {
+ unsigned BitWidth = LHS.getBitWidth();
+
+ assert(!LHS.hasConflict() && !RHS.hasConflict());
+ // Compute a conservative estimate for high known-0 bits.
+ unsigned LeadZ =
+ std::max(LHS.countMinLeadingZeros() + RHS.countMinLeadingZeros(),
+ BitWidth) -
+ BitWidth;
+ LeadZ = std::min(LeadZ, BitWidth);
+
+ // The result of the bottom bits of an integer multiply can be
+ // inferred by looking at the bottom bits of both operands and
+ // multiplying them together.
+ // We can infer at least the minimum number of known trailing bits
+ // of both operands. Depending on number of trailing zeros, we can
+ // infer more bits, because (a*b) <=> ((a/m) * (b/n)) * (m*n) assuming
+ // a and b are divisible by m and n respectively.
+ // We then calculate how many of those bits are inferrable and set
+ // the output. For example, the i8 mul:
+ // a = XXXX1100 (12)
+ // b = XXXX1110 (14)
+ // We know the bottom 3 bits are zero since the first can be divided by
+ // 4 and the second by 2, thus having ((12/4) * (14/2)) * (2*4).
+ // Applying the multiplication to the trimmed arguments gets:
+ // XX11 (3)
+ // X111 (7)
+ // -------
+ // XX11
+ // XX11
+ // XX11
+ // XX11
+ // -------
+ // XXXXX01
+ // Which allows us to infer the 2 LSBs. Since we're multiplying the result
+ // by 8, the bottom 3 bits will be 0, so we can infer a total of 5 bits.
+ // The proof for this can be described as:
+ // Pre: (C1 >= 0) && (C1 < (1 << C5)) && (C2 >= 0) && (C2 < (1 << C6)) &&
+ // (C7 == (1 << (umin(countTrailingZeros(C1), C5) +
+ // umin(countTrailingZeros(C2), C6) +
+ // umin(C5 - umin(countTrailingZeros(C1), C5),
+ // C6 - umin(countTrailingZeros(C2), C6)))) - 1)
+ // %aa = shl i8 %a, C5
+ // %bb = shl i8 %b, C6
+ // %aaa = or i8 %aa, C1
+ // %bbb = or i8 %bb, C2
+ // %mul = mul i8 %aaa, %bbb
+ // %mask = and i8 %mul, C7
+ // =>
+ // %mask = i8 ((C1*C2)&C7)
+ // Where C5, C6 describe the known bits of %a, %b
+ // C1, C2 describe the known bottom bits of %a, %b.
+ // C7 describes the mask of the known bits of the result.
+ const APInt &Bottom0 = LHS.One;
+ const APInt &Bottom1 = RHS.One;
+
+ // How many times we'd be able to divide each argument by 2 (shr by 1).
+ // This gives us the number of trailing zeros on the multiplication result.
+ unsigned TrailBitsKnown0 = (LHS.Zero | LHS.One).countTrailingOnes();
+ unsigned TrailBitsKnown1 = (RHS.Zero | RHS.One).countTrailingOnes();
+ unsigned TrailZero0 = LHS.countMinTrailingZeros();
+ unsigned TrailZero1 = RHS.countMinTrailingZeros();
+ unsigned TrailZ = TrailZero0 + TrailZero1;
+
+ // Figure out the fewest known-bits operand.
+ unsigned SmallestOperand =
+ std::min(TrailBitsKnown0 - TrailZero0, TrailBitsKnown1 - TrailZero1);
+ unsigned ResultBitsKnown = std::min(SmallestOperand + TrailZ, BitWidth);
+
+ APInt BottomKnown =
+ Bottom0.getLoBits(TrailBitsKnown0) * Bottom1.getLoBits(TrailBitsKnown1);
+
+ KnownBits Res(BitWidth);
+ Res.Zero.setHighBits(LeadZ);
+ Res.Zero |= (~BottomKnown).getLoBits(ResultBitsKnown);
+ Res.One = BottomKnown.getLoBits(ResultBitsKnown);
+ return Res;
+}
+
+KnownBits KnownBits::udiv(const KnownBits &LHS, const KnownBits &RHS) {
+ unsigned BitWidth = LHS.getBitWidth();
+ assert(!LHS.hasConflict() && !RHS.hasConflict());
+ KnownBits Known(BitWidth);
+
+ // For the purposes of computing leading zeros we can conservatively
+ // treat a udiv as a logical right shift by the power of 2 known to
+ // be less than the denominator.
+ unsigned LeadZ = LHS.countMinLeadingZeros();
+ unsigned RHSMaxLeadingZeros = RHS.countMaxLeadingZeros();
+
+ if (RHSMaxLeadingZeros != BitWidth)
+ LeadZ = std::min(BitWidth, LeadZ + BitWidth - RHSMaxLeadingZeros - 1);
+
+ Known.Zero.setHighBits(LeadZ);
+ return Known;
+}
+
+KnownBits KnownBits::urem(const KnownBits &LHS, const KnownBits &RHS) {
+ unsigned BitWidth = LHS.getBitWidth();
+ assert(!LHS.hasConflict() && !RHS.hasConflict());
+ KnownBits Known(BitWidth);
+
+ if (RHS.isConstant() && RHS.getConstant().isPowerOf2()) {
+ // The upper bits are all zero, the lower ones are unchanged.
+ APInt LowBits = RHS.getConstant() - 1;
+ Known.Zero = LHS.Zero | ~LowBits;
+ Known.One = LHS.One & LowBits;
+ return Known;
+ }
+
+ // Since the result is less than or equal to either operand, any leading
+ // zero bits in either operand must also exist in the result.
+ uint32_t Leaders =
+ std::max(LHS.countMinLeadingZeros(), RHS.countMinLeadingZeros());
+ Known.Zero.setHighBits(Leaders);
+ return Known;
+}
+
+KnownBits KnownBits::srem(const KnownBits &LHS, const KnownBits &RHS) {
+ unsigned BitWidth = LHS.getBitWidth();
+ assert(!LHS.hasConflict() && !RHS.hasConflict());
+ KnownBits Known(BitWidth);
+
+ if (RHS.isConstant() && RHS.getConstant().isPowerOf2()) {
+ // The low bits of the first operand are unchanged by the srem.
+ APInt LowBits = RHS.getConstant() - 1;
+ Known.Zero = LHS.Zero & LowBits;
+ Known.One = LHS.One & LowBits;
+
+ // If the first operand is non-negative or has all low bits zero, then
+ // the upper bits are all zero.
+ if (LHS.isNonNegative() || LowBits.isSubsetOf(LHS.Zero))
+ Known.Zero |= ~LowBits;
+
+ // If the first operand is negative and not all low bits are zero, then
+ // the upper bits are all one.
+ if (LHS.isNegative() && LowBits.intersects(LHS.One))
+ Known.One |= ~LowBits;
+ return Known;
+ }
+
+ // The sign bit is the LHS's sign bit, except when the result of the
+ // remainder is zero. If it's known zero, our sign bit is also zero.
+ if (LHS.isNonNegative())
+ Known.makeNonNegative();
+ return Known;
+}
+
KnownBits &KnownBits::operator&=(const KnownBits &RHS) {
// Result bit is 0 if either operand bit is 0.
Zero |= RHS.Zero;
diff --git a/contrib/libs/llvm12/lib/Support/LineIterator.cpp b/contrib/libs/llvm12/lib/Support/LineIterator.cpp
index 6b0a3f3886..7bdf1271ac 100644
--- a/contrib/libs/llvm12/lib/Support/LineIterator.cpp
+++ b/contrib/libs/llvm12/lib/Support/LineIterator.cpp
@@ -33,11 +33,11 @@ static bool skipIfAtLineEnd(const char *&P) {
line_iterator::line_iterator(const MemoryBuffer &Buffer, bool SkipBlanks,
char CommentMarker)
- : line_iterator(Buffer.getMemBufferRef(), SkipBlanks, CommentMarker) {}
-
-line_iterator::line_iterator(const MemoryBufferRef &Buffer, bool SkipBlanks,
- char CommentMarker)
- : Buffer(Buffer.getBufferSize() ? Optional<MemoryBufferRef>(Buffer) : None),
+ : line_iterator(Buffer.getMemBufferRef(), SkipBlanks, CommentMarker) {}
+
+line_iterator::line_iterator(const MemoryBufferRef &Buffer, bool SkipBlanks,
+ char CommentMarker)
+ : Buffer(Buffer.getBufferSize() ? Optional<MemoryBufferRef>(Buffer) : None),
CommentMarker(CommentMarker), SkipBlanks(SkipBlanks), LineNumber(1),
CurrentLine(Buffer.getBufferSize() ? Buffer.getBufferStart() : nullptr,
0) {
@@ -82,7 +82,7 @@ void line_iterator::advance() {
if (*Pos == '\0') {
// We've hit the end of the buffer, reset ourselves to the end state.
- Buffer = None;
+ Buffer = None;
CurrentLine = StringRef();
return;
}
diff --git a/contrib/libs/llvm12/lib/Support/LowLevelType.cpp b/contrib/libs/llvm12/lib/Support/LowLevelType.cpp
index cd406ae649..63559d5ac3 100644
--- a/contrib/libs/llvm12/lib/Support/LowLevelType.cpp
+++ b/contrib/libs/llvm12/lib/Support/LowLevelType.cpp
@@ -23,7 +23,7 @@ LLT::LLT(MVT VT) {
} else if (VT.isValid()) {
// Aggregates are no different from real scalars as far as GlobalISel is
// concerned.
- assert(VT.getSizeInBits().isNonZero() && "invalid zero-sized type");
+ assert(VT.getSizeInBits().isNonZero() && "invalid zero-sized type");
init(/*IsPointer=*/false, /*IsVector=*/false, /*NumElements=*/0,
VT.getSizeInBits(), /*AddressSpace=*/0);
} else {
diff --git a/contrib/libs/llvm12/lib/Support/MemoryBufferRef.cpp b/contrib/libs/llvm12/lib/Support/MemoryBufferRef.cpp
index e37aa357e8..a93853c0ac 100644
--- a/contrib/libs/llvm12/lib/Support/MemoryBufferRef.cpp
+++ b/contrib/libs/llvm12/lib/Support/MemoryBufferRef.cpp
@@ -1,19 +1,19 @@
-//===- MemoryBufferRef.cpp - Memory Buffer Reference ----------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the MemoryBufferRef interface.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/MemoryBufferRef.h"
-#include "llvm/Support/MemoryBuffer.h"
-
-using namespace llvm;
-
-MemoryBufferRef::MemoryBufferRef(const MemoryBuffer &Buffer)
- : Buffer(Buffer.getBuffer()), Identifier(Buffer.getBufferIdentifier()) {}
+//===- MemoryBufferRef.cpp - Memory Buffer Reference ----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the MemoryBufferRef interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/MemoryBufferRef.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+using namespace llvm;
+
+MemoryBufferRef::MemoryBufferRef(const MemoryBuffer &Buffer)
+ : Buffer(Buffer.getBuffer()), Identifier(Buffer.getBufferIdentifier()) {}
diff --git a/contrib/libs/llvm12/lib/Support/Path.cpp b/contrib/libs/llvm12/lib/Support/Path.cpp
index 4319bd23a8..ef223ae5ac 100644
--- a/contrib/libs/llvm12/lib/Support/Path.cpp
+++ b/contrib/libs/llvm12/lib/Support/Path.cpp
@@ -355,8 +355,8 @@ StringRef root_path(StringRef path, Style style) {
// {C:/,//net/}, so get the first two components.
return path.substr(0, b->size() + pos->size());
}
- // just {C:,//net}, return the first component.
- return *b;
+ // just {C:,//net}, return the first component.
+ return *b;
}
// POSIX style root directory.
@@ -466,7 +466,7 @@ StringRef parent_path(StringRef path, Style style) {
size_t end_pos = parent_path_end(path, style);
if (end_pos == StringRef::npos)
return StringRef();
- return path.substr(0, end_pos);
+ return path.substr(0, end_pos);
}
void remove_filename(SmallVectorImpl<char> &path, Style style) {
@@ -579,10 +579,10 @@ StringRef stem(StringRef path, Style style) {
size_t pos = fname.find_last_of('.');
if (pos == StringRef::npos)
return fname;
- if ((fname.size() == 1 && fname == ".") ||
- (fname.size() == 2 && fname == ".."))
- return fname;
- return fname.substr(0, pos);
+ if ((fname.size() == 1 && fname == ".") ||
+ (fname.size() == 2 && fname == ".."))
+ return fname;
+ return fname.substr(0, pos);
}
StringRef extension(StringRef path, Style style) {
@@ -590,10 +590,10 @@ StringRef extension(StringRef path, Style style) {
size_t pos = fname.find_last_of('.');
if (pos == StringRef::npos)
return StringRef();
- if ((fname.size() == 1 && fname == ".") ||
- (fname.size() == 2 && fname == ".."))
- return StringRef();
- return fname.substr(pos);
+ if ((fname.size() == 1 && fname == ".") ||
+ (fname.size() == 2 && fname == ".."))
+ return StringRef();
+ return fname.substr(pos);
}
bool is_separator(char value, Style style) {
@@ -677,24 +677,24 @@ bool is_absolute(const Twine &path, Style style) {
return rootDir && rootName;
}
-bool is_absolute_gnu(const Twine &path, Style style) {
- SmallString<128> path_storage;
- StringRef p = path.toStringRef(path_storage);
-
- // Handle '/' which is absolute for both Windows and POSIX systems.
- // Handle '\\' on Windows.
- if (!p.empty() && is_separator(p.front(), style))
- return true;
-
- if (real_style(style) == Style::windows) {
- // Handle drive letter pattern (a character followed by ':') on Windows.
- if (p.size() >= 2 && (p[0] && p[1] == ':'))
- return true;
- }
-
- return false;
-}
-
+bool is_absolute_gnu(const Twine &path, Style style) {
+ SmallString<128> path_storage;
+ StringRef p = path.toStringRef(path_storage);
+
+ // Handle '/' which is absolute for both Windows and POSIX systems.
+ // Handle '\\' on Windows.
+ if (!p.empty() && is_separator(p.front(), style))
+ return true;
+
+ if (real_style(style) == Style::windows) {
+ // Handle drive letter pattern (a character followed by ':') on Windows.
+ if (p.size() >= 2 && (p[0] && p[1] == ':'))
+ return true;
+ }
+
+ return false;
+}
+
bool is_relative(const Twine &path, Style style) {
return !is_absolute(path, style);
}
@@ -1293,7 +1293,7 @@ Expected<TempFile> TempFile::create(const Twine &Model, unsigned Mode) {
#endif
return std::move(Ret);
}
-} // namespace fs
+} // namespace fs
-} // namespace sys
-} // namespace llvm
+} // namespace sys
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/Support/PrettyStackTrace.cpp b/contrib/libs/llvm12/lib/Support/PrettyStackTrace.cpp
index 49c6d24917..5d3d95b5e7 100644
--- a/contrib/libs/llvm12/lib/Support/PrettyStackTrace.cpp
+++ b/contrib/libs/llvm12/lib/Support/PrettyStackTrace.cpp
@@ -25,7 +25,7 @@
#include <cassert>
#include <cstdarg>
#include <cstdio>
-#include <cstring>
+#include <cstring>
#include <tuple>
#ifdef HAVE_CRASHREPORTERCLIENT_H
@@ -254,16 +254,16 @@ void PrettyStackTraceFormat::print(raw_ostream &OS) const { OS << Str << "\n"; }
void PrettyStackTraceProgram::print(raw_ostream &OS) const {
OS << "Program arguments: ";
// Print the argument list.
- for (int I = 0; I < ArgC; ++I) {
- const bool HaveSpace = ::strchr(ArgV[I], ' ');
- if (I)
- OS << ' ';
- if (HaveSpace)
- OS << '"';
- OS.write_escaped(ArgV[I]);
- if (HaveSpace)
- OS << '"';
- }
+ for (int I = 0; I < ArgC; ++I) {
+ const bool HaveSpace = ::strchr(ArgV[I], ' ');
+ if (I)
+ OS << ' ';
+ if (HaveSpace)
+ OS << '"';
+ OS.write_escaped(ArgV[I]);
+ if (HaveSpace)
+ OS << '"';
+ }
OS << '\n';
}
diff --git a/contrib/libs/llvm12/lib/Support/Process.cpp b/contrib/libs/llvm12/lib/Support/Process.cpp
index c80f01e6db..e081444487 100644
--- a/contrib/libs/llvm12/lib/Support/Process.cpp
+++ b/contrib/libs/llvm12/lib/Support/Process.cpp
@@ -20,8 +20,8 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
-#include <stdlib.h> // for _Exit
-
+#include <stdlib.h> // for _Exit
+
using namespace llvm;
using namespace sys;
@@ -30,22 +30,22 @@ using namespace sys;
//=== independent code.
//===----------------------------------------------------------------------===//
-Optional<std::string>
-Process::FindInEnvPath(StringRef EnvName, StringRef FileName, char Separator) {
- return FindInEnvPath(EnvName, FileName, {}, Separator);
+Optional<std::string>
+Process::FindInEnvPath(StringRef EnvName, StringRef FileName, char Separator) {
+ return FindInEnvPath(EnvName, FileName, {}, Separator);
}
Optional<std::string> Process::FindInEnvPath(StringRef EnvName,
StringRef FileName,
- ArrayRef<std::string> IgnoreList,
- char Separator) {
+ ArrayRef<std::string> IgnoreList,
+ char Separator) {
assert(!path::is_absolute(FileName));
Optional<std::string> FoundPath;
Optional<std::string> OptPath = Process::GetEnv(EnvName);
if (!OptPath.hasValue())
return FoundPath;
- const char EnvPathSeparatorStr[] = {Separator, '\0'};
+ const char EnvPathSeparatorStr[] = {Separator, '\0'};
SmallVector<StringRef, 8> Dirs;
SplitString(OptPath.getValue(), Dirs, EnvPathSeparatorStr);
@@ -93,14 +93,14 @@ static bool coreFilesPrevented = !LLVM_ENABLE_CRASH_DUMPS;
bool Process::AreCoreFilesPrevented() { return coreFilesPrevented; }
LLVM_ATTRIBUTE_NORETURN
-void Process::Exit(int RetCode, bool NoCleanup) {
+void Process::Exit(int RetCode, bool NoCleanup) {
if (CrashRecoveryContext *CRC = CrashRecoveryContext::GetCurrent())
CRC->HandleExit(RetCode);
-
- if (NoCleanup)
- _Exit(RetCode);
- else
- ::exit(RetCode);
+
+ if (NoCleanup)
+ _Exit(RetCode);
+ else
+ ::exit(RetCode);
}
// Include the platform-specific parts of this class.
diff --git a/contrib/libs/llvm12/lib/Support/Program.cpp b/contrib/libs/llvm12/lib/Support/Program.cpp
index 6505a40034..c7a59642b2 100644
--- a/contrib/libs/llvm12/lib/Support/Program.cpp
+++ b/contrib/libs/llvm12/lib/Support/Program.cpp
@@ -26,20 +26,20 @@ using namespace sys;
static bool Execute(ProcessInfo &PI, StringRef Program,
ArrayRef<StringRef> Args, Optional<ArrayRef<StringRef>> Env,
ArrayRef<Optional<StringRef>> Redirects,
- unsigned MemoryLimit, std::string *ErrMsg,
- BitVector *AffinityMask);
+ unsigned MemoryLimit, std::string *ErrMsg,
+ BitVector *AffinityMask);
int sys::ExecuteAndWait(StringRef Program, ArrayRef<StringRef> Args,
Optional<ArrayRef<StringRef>> Env,
ArrayRef<Optional<StringRef>> Redirects,
unsigned SecondsToWait, unsigned MemoryLimit,
std::string *ErrMsg, bool *ExecutionFailed,
- Optional<ProcessStatistics> *ProcStat,
- BitVector *AffinityMask) {
+ Optional<ProcessStatistics> *ProcStat,
+ BitVector *AffinityMask) {
assert(Redirects.empty() || Redirects.size() == 3);
ProcessInfo PI;
- if (Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg,
- AffinityMask)) {
+ if (Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg,
+ AffinityMask)) {
if (ExecutionFailed)
*ExecutionFailed = false;
ProcessInfo Result =
@@ -58,13 +58,13 @@ ProcessInfo sys::ExecuteNoWait(StringRef Program, ArrayRef<StringRef> Args,
Optional<ArrayRef<StringRef>> Env,
ArrayRef<Optional<StringRef>> Redirects,
unsigned MemoryLimit, std::string *ErrMsg,
- bool *ExecutionFailed, BitVector *AffinityMask) {
+ bool *ExecutionFailed, BitVector *AffinityMask) {
assert(Redirects.empty() || Redirects.size() == 3);
ProcessInfo PI;
if (ExecutionFailed)
*ExecutionFailed = false;
- if (!Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg,
- AffinityMask))
+ if (!Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg,
+ AffinityMask))
if (ExecutionFailed)
*ExecutionFailed = true;
diff --git a/contrib/libs/llvm12/lib/Support/SHA1.cpp b/contrib/libs/llvm12/lib/Support/SHA1.cpp
index 8d2bb97907..5dce44af9e 100644
--- a/contrib/libs/llvm12/lib/Support/SHA1.cpp
+++ b/contrib/libs/llvm12/lib/Support/SHA1.cpp
@@ -225,7 +225,7 @@ void SHA1::update(ArrayRef<uint8_t> Data) {
// Fast buffer filling for large inputs.
while (Data.size() >= BLOCK_LENGTH) {
assert(InternalState.BufferOffset == 0);
- static_assert(BLOCK_LENGTH % 4 == 0, "");
+ static_assert(BLOCK_LENGTH % 4 == 0, "");
constexpr size_t BLOCK_LENGTH_32 = BLOCK_LENGTH / 4;
for (size_t I = 0; I < BLOCK_LENGTH_32; ++I)
InternalState.Buffer.L[I] = support::endian::read32be(&Data[I * 4]);
diff --git a/contrib/libs/llvm12/lib/Support/Signals.cpp b/contrib/libs/llvm12/lib/Support/Signals.cpp
index 02e9f801d5..29be4df959 100644
--- a/contrib/libs/llvm12/lib/Support/Signals.cpp
+++ b/contrib/libs/llvm12/lib/Support/Signals.cpp
@@ -44,9 +44,9 @@ static cl::opt<bool, true>
cl::desc("Disable symbolizing crash backtraces."),
cl::location(DisableSymbolicationFlag), cl::Hidden);
-constexpr char DisableSymbolizationEnv[] = "LLVM_DISABLE_SYMBOLIZATION";
-constexpr char LLVMSymbolizerPathEnv[] = "LLVM_SYMBOLIZER_PATH";
-
+constexpr char DisableSymbolizationEnv[] = "LLVM_DISABLE_SYMBOLIZATION";
+constexpr char LLVMSymbolizerPathEnv[] = "LLVM_SYMBOLIZER_PATH";
+
// Callbacks to run in signal handler must be lock-free because a signal handler
// could be running as we add new callbacks. We don't add unbounded numbers of
// callbacks, an array is therefore sufficient.
@@ -108,7 +108,7 @@ static FormattedNumber format_ptr(void *PC) {
LLVM_ATTRIBUTE_USED
static bool printSymbolizedStackTrace(StringRef Argv0, void **StackTrace,
int Depth, llvm::raw_ostream &OS) {
- if (DisableSymbolicationFlag || getenv(DisableSymbolizationEnv))
+ if (DisableSymbolicationFlag || getenv(DisableSymbolizationEnv))
return false;
// Don't recursively invoke the llvm-symbolizer binary.
@@ -120,9 +120,9 @@ static bool printSymbolizedStackTrace(StringRef Argv0, void **StackTrace,
// Use llvm-symbolizer tool to symbolize the stack traces. First look for it
// alongside our binary, then in $PATH.
ErrorOr<std::string> LLVMSymbolizerPathOrErr = std::error_code();
- if (const char *Path = getenv(LLVMSymbolizerPathEnv)) {
- LLVMSymbolizerPathOrErr = sys::findProgramByName(Path);
- } else if (!Argv0.empty()) {
+ if (const char *Path = getenv(LLVMSymbolizerPathEnv)) {
+ LLVMSymbolizerPathOrErr = sys::findProgramByName(Path);
+ } else if (!Argv0.empty()) {
StringRef Parent = llvm::sys::path::parent_path(Argv0);
if (!Parent.empty())
LLVMSymbolizerPathOrErr = sys::findProgramByName("llvm-symbolizer", Parent);
diff --git a/contrib/libs/llvm12/lib/Support/Signposts.cpp b/contrib/libs/llvm12/lib/Support/Signposts.cpp
index 9408373912..8de6e0cc04 100644
--- a/contrib/libs/llvm12/lib/Support/Signposts.cpp
+++ b/contrib/libs/llvm12/lib/Support/Signposts.cpp
@@ -13,7 +13,7 @@
#include "llvm/Config/config.h"
#if LLVM_SUPPORT_XCODE_SIGNPOSTS
#include "llvm/ADT/DenseMap.h"
-#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Mutex.h"
#error #include <os/signpost.h>
#endif // if LLVM_SUPPORT_XCODE_SIGNPOSTS
@@ -34,22 +34,22 @@ void LogDeleter(os_log_t *X) {
namespace llvm {
class SignpostEmitterImpl {
- using LogPtrTy = std::unique_ptr<os_log_t, std::function<void(os_log_t *)>>;
+ using LogPtrTy = std::unique_ptr<os_log_t, std::function<void(os_log_t *)>>;
using LogTy = LogPtrTy::element_type;
LogPtrTy SignpostLog;
- DenseMap<const void *, os_signpost_id_t> Signposts;
- sys::SmartMutex<true> Mutex;
+ DenseMap<const void *, os_signpost_id_t> Signposts;
+ sys::SmartMutex<true> Mutex;
LogTy &getLogger() const { return *SignpostLog; }
- os_signpost_id_t getSignpostForObject(const void *O) {
- sys::SmartScopedLock<true> Lock(Mutex);
- const auto &I = Signposts.find(O);
+ os_signpost_id_t getSignpostForObject(const void *O) {
+ sys::SmartScopedLock<true> Lock(Mutex);
+ const auto &I = Signposts.find(O);
if (I != Signposts.end())
return I->second;
const auto &Inserted = Signposts.insert(
- std::make_pair(O, os_signpost_id_make_with_pointer(getLogger(), O)));
+ std::make_pair(O, os_signpost_id_make_with_pointer(getLogger(), O)));
return Inserted.first->second;
}
@@ -58,19 +58,19 @@ public:
bool isEnabled() const { return os_signpost_enabled(*SignpostLog); }
- void startInterval(const void *O, llvm::StringRef Name) {
+ void startInterval(const void *O, llvm::StringRef Name) {
if (isEnabled()) {
- // Both strings used here are required to be constant literal strings.
- os_signpost_interval_begin(getLogger(), getSignpostForObject(O),
- "LLVM Timers", "Begin %s", Name.data());
+ // Both strings used here are required to be constant literal strings.
+ os_signpost_interval_begin(getLogger(), getSignpostForObject(O),
+ "LLVM Timers", "Begin %s", Name.data());
}
}
- void endInterval(const void *O, llvm::StringRef Name) {
+ void endInterval(const void *O, llvm::StringRef Name) {
if (isEnabled()) {
- // Both strings used here are required to be constant literal strings.
- os_signpost_interval_end(getLogger(), getSignpostForObject(O),
- "LLVM Timers", "End %s", Name.data());
+ // Both strings used here are required to be constant literal strings.
+ os_signpost_interval_end(getLogger(), getSignpostForObject(O),
+ "LLVM Timers", "End %s", Name.data());
}
}
};
@@ -86,7 +86,7 @@ public:
SignpostEmitter::SignpostEmitter() {
#if HAVE_ANY_SIGNPOST_IMPL
Impl = new SignpostEmitterImpl();
-#else // if HAVE_ANY_SIGNPOST_IMPL
+#else // if HAVE_ANY_SIGNPOST_IMPL
Impl = nullptr;
#endif // if !HAVE_ANY_SIGNPOST_IMPL
}
@@ -105,18 +105,18 @@ bool SignpostEmitter::isEnabled() const {
#endif // if !HAVE_ANY_SIGNPOST_IMPL
}
-void SignpostEmitter::startInterval(const void *O, StringRef Name) {
+void SignpostEmitter::startInterval(const void *O, StringRef Name) {
#if HAVE_ANY_SIGNPOST_IMPL
if (Impl == nullptr)
return;
- return Impl->startInterval(O, Name);
+ return Impl->startInterval(O, Name);
#endif // if !HAVE_ANY_SIGNPOST_IMPL
}
-void SignpostEmitter::endInterval(const void *O, StringRef Name) {
+void SignpostEmitter::endInterval(const void *O, StringRef Name) {
#if HAVE_ANY_SIGNPOST_IMPL
if (Impl == nullptr)
return;
- Impl->endInterval(O, Name);
+ Impl->endInterval(O, Name);
#endif // if !HAVE_ANY_SIGNPOST_IMPL
}
diff --git a/contrib/libs/llvm12/lib/Support/SmallVector.cpp b/contrib/libs/llvm12/lib/Support/SmallVector.cpp
index f25422dc2f..0005f78409 100644
--- a/contrib/libs/llvm12/lib/Support/SmallVector.cpp
+++ b/contrib/libs/llvm12/lib/Support/SmallVector.cpp
@@ -12,9 +12,9 @@
#include "llvm/ADT/SmallVector.h"
#include <cstdint>
-#ifdef LLVM_ENABLE_EXCEPTIONS
-#include <stdexcept>
-#endif
+#ifdef LLVM_ENABLE_EXCEPTIONS
+#include <stdexcept>
+#endif
using namespace llvm;
// Check that no bytes are wasted and everything is well-aligned.
@@ -45,72 +45,72 @@ static_assert(sizeof(SmallVector<char, 0>) ==
sizeof(void *) * 2 + sizeof(void *),
"1 byte elements have word-sized type for size and capacity");
-/// Report that MinSize doesn't fit into this vector's size type. Throws
-/// std::length_error or calls report_fatal_error.
-LLVM_ATTRIBUTE_NORETURN
-static void report_size_overflow(size_t MinSize, size_t MaxSize);
-static void report_size_overflow(size_t MinSize, size_t MaxSize) {
- std::string Reason = "SmallVector unable to grow. Requested capacity (" +
- std::to_string(MinSize) +
- ") is larger than maximum value for size type (" +
- std::to_string(MaxSize) + ")";
-#ifdef LLVM_ENABLE_EXCEPTIONS
- throw std::length_error(Reason);
-#else
- report_fatal_error(Reason);
-#endif
-}
-
-/// Report that this vector is already at maximum capacity. Throws
-/// std::length_error or calls report_fatal_error.
-LLVM_ATTRIBUTE_NORETURN static void report_at_maximum_capacity(size_t MaxSize);
-static void report_at_maximum_capacity(size_t MaxSize) {
- std::string Reason =
- "SmallVector capacity unable to grow. Already at maximum size " +
- std::to_string(MaxSize);
-#ifdef LLVM_ENABLE_EXCEPTIONS
- throw std::length_error(Reason);
-#else
- report_fatal_error(Reason);
-#endif
-}
-
+/// Report that MinSize doesn't fit into this vector's size type. Throws
+/// std::length_error or calls report_fatal_error.
+LLVM_ATTRIBUTE_NORETURN
+static void report_size_overflow(size_t MinSize, size_t MaxSize);
+static void report_size_overflow(size_t MinSize, size_t MaxSize) {
+ std::string Reason = "SmallVector unable to grow. Requested capacity (" +
+ std::to_string(MinSize) +
+ ") is larger than maximum value for size type (" +
+ std::to_string(MaxSize) + ")";
+#ifdef LLVM_ENABLE_EXCEPTIONS
+ throw std::length_error(Reason);
+#else
+ report_fatal_error(Reason);
+#endif
+}
+
+/// Report that this vector is already at maximum capacity. Throws
+/// std::length_error or calls report_fatal_error.
+LLVM_ATTRIBUTE_NORETURN static void report_at_maximum_capacity(size_t MaxSize);
+static void report_at_maximum_capacity(size_t MaxSize) {
+ std::string Reason =
+ "SmallVector capacity unable to grow. Already at maximum size " +
+ std::to_string(MaxSize);
+#ifdef LLVM_ENABLE_EXCEPTIONS
+ throw std::length_error(Reason);
+#else
+ report_fatal_error(Reason);
+#endif
+}
+
// Note: Moving this function into the header may cause performance regression.
template <class Size_T>
-static size_t getNewCapacity(size_t MinSize, size_t TSize, size_t OldCapacity) {
- constexpr size_t MaxSize = std::numeric_limits<Size_T>::max();
-
+static size_t getNewCapacity(size_t MinSize, size_t TSize, size_t OldCapacity) {
+ constexpr size_t MaxSize = std::numeric_limits<Size_T>::max();
+
// Ensure we can fit the new capacity.
// This is only going to be applicable when the capacity is 32 bit.
- if (MinSize > MaxSize)
- report_size_overflow(MinSize, MaxSize);
+ if (MinSize > MaxSize)
+ report_size_overflow(MinSize, MaxSize);
// Ensure we can meet the guarantee of space for at least one more element.
// The above check alone will not catch the case where grow is called with a
- // default MinSize of 0, but the current capacity cannot be increased.
+ // default MinSize of 0, but the current capacity cannot be increased.
// This is only going to be applicable when the capacity is 32 bit.
- if (OldCapacity == MaxSize)
- report_at_maximum_capacity(MaxSize);
+ if (OldCapacity == MaxSize)
+ report_at_maximum_capacity(MaxSize);
// In theory 2*capacity can overflow if the capacity is 64 bit, but the
// original capacity would never be large enough for this to be a problem.
- size_t NewCapacity = 2 * OldCapacity + 1; // Always grow.
- return std::min(std::max(NewCapacity, MinSize), MaxSize);
-}
-
-// Note: Moving this function into the header may cause performance regression.
-template <class Size_T>
-void *SmallVectorBase<Size_T>::mallocForGrow(size_t MinSize, size_t TSize,
- size_t &NewCapacity) {
- NewCapacity = getNewCapacity<Size_T>(MinSize, TSize, this->capacity());
- return llvm::safe_malloc(NewCapacity * TSize);
-}
-
-// Note: Moving this function into the header may cause performance regression.
-template <class Size_T>
-void SmallVectorBase<Size_T>::grow_pod(void *FirstEl, size_t MinSize,
- size_t TSize) {
- size_t NewCapacity = getNewCapacity<Size_T>(MinSize, TSize, this->capacity());
+ size_t NewCapacity = 2 * OldCapacity + 1; // Always grow.
+ return std::min(std::max(NewCapacity, MinSize), MaxSize);
+}
+
+// Note: Moving this function into the header may cause performance regression.
+template <class Size_T>
+void *SmallVectorBase<Size_T>::mallocForGrow(size_t MinSize, size_t TSize,
+ size_t &NewCapacity) {
+ NewCapacity = getNewCapacity<Size_T>(MinSize, TSize, this->capacity());
+ return llvm::safe_malloc(NewCapacity * TSize);
+}
+
+// Note: Moving this function into the header may cause performance regression.
+template <class Size_T>
+void SmallVectorBase<Size_T>::grow_pod(void *FirstEl, size_t MinSize,
+ size_t TSize) {
+ size_t NewCapacity = getNewCapacity<Size_T>(MinSize, TSize, this->capacity());
void *NewElts;
if (BeginX == FirstEl) {
NewElts = safe_malloc(NewCapacity * TSize);
@@ -129,7 +129,7 @@ void SmallVectorBase<Size_T>::grow_pod(void *FirstEl, size_t MinSize,
template class llvm::SmallVectorBase<uint32_t>;
// Disable the uint64_t instantiation for 32-bit builds.
-// Both uint32_t and uint64_t instantiations are needed for 64-bit builds.
+// Both uint32_t and uint64_t instantiations are needed for 64-bit builds.
// This instantiation will never be used in 32-bit builds, and will cause
// warnings when sizeof(Size_T) > sizeof(size_t).
#if SIZE_MAX > UINT32_MAX
diff --git a/contrib/libs/llvm12/lib/Support/SourceMgr.cpp b/contrib/libs/llvm12/lib/Support/SourceMgr.cpp
index 63ee3d49a8..89b7dc939d 100644
--- a/contrib/libs/llvm12/lib/Support/SourceMgr.cpp
+++ b/contrib/libs/llvm12/lib/Support/SourceMgr.cpp
@@ -180,7 +180,7 @@ std::pair<unsigned, unsigned>
SourceMgr::getLineAndColumn(SMLoc Loc, unsigned BufferID) const {
if (!BufferID)
BufferID = FindBufferContainingLoc(Loc);
- assert(BufferID && "Invalid location!");
+ assert(BufferID && "Invalid location!");
auto &SB = getBufferInfo(BufferID);
const char *Ptr = Loc.getPointer();
@@ -193,30 +193,30 @@ SourceMgr::getLineAndColumn(SMLoc Loc, unsigned BufferID) const {
return std::make_pair(LineNo, Ptr - BufStart - NewlineOffs);
}
-// FIXME: Note that the formatting of source locations is spread between
-// multiple functions, some in SourceMgr and some in SMDiagnostic. A better
-// solution would be a general-purpose source location formatter
-// in one of those two classes, or possibly in SMLoc.
-
-/// Get a string with the source location formatted in the standard
-/// style, but without the line offset. If \p IncludePath is true, the path
-/// is included. If false, only the file name and extension are included.
-std::string SourceMgr::getFormattedLocationNoOffset(SMLoc Loc,
- bool IncludePath) const {
- auto BufferID = FindBufferContainingLoc(Loc);
- assert(BufferID && "Invalid location!");
- auto FileSpec = getBufferInfo(BufferID).Buffer->getBufferIdentifier();
-
- if (IncludePath) {
- return FileSpec.str() + ":" + std::to_string(FindLineNumber(Loc, BufferID));
- } else {
- auto I = FileSpec.find_last_of("/\\");
- I = (I == FileSpec.size()) ? 0 : (I + 1);
- return FileSpec.substr(I).str() + ":" +
- std::to_string(FindLineNumber(Loc, BufferID));
- }
-}
-
+// FIXME: Note that the formatting of source locations is spread between
+// multiple functions, some in SourceMgr and some in SMDiagnostic. A better
+// solution would be a general-purpose source location formatter
+// in one of those two classes, or possibly in SMLoc.
+
+/// Get a string with the source location formatted in the standard
+/// style, but without the line offset. If \p IncludePath is true, the path
+/// is included. If false, only the file name and extension are included.
+std::string SourceMgr::getFormattedLocationNoOffset(SMLoc Loc,
+ bool IncludePath) const {
+ auto BufferID = FindBufferContainingLoc(Loc);
+ assert(BufferID && "Invalid location!");
+ auto FileSpec = getBufferInfo(BufferID).Buffer->getBufferIdentifier();
+
+ if (IncludePath) {
+ return FileSpec.str() + ":" + std::to_string(FindLineNumber(Loc, BufferID));
+ } else {
+ auto I = FileSpec.find_last_of("/\\");
+ I = (I == FileSpec.size()) ? 0 : (I + 1);
+ return FileSpec.substr(I).str() + ":" +
+ std::to_string(FindLineNumber(Loc, BufferID));
+ }
+}
+
/// Given a line and column number in a mapped buffer, turn it into an SMLoc.
/// This will return a null SMLoc if the line/column location is invalid.
SMLoc SourceMgr::FindLocForLineAndColumn(unsigned BufferID, unsigned LineNo,
@@ -267,7 +267,7 @@ SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
SmallVector<std::pair<unsigned, unsigned>, 4> ColRanges;
std::pair<unsigned, unsigned> LineAndCol;
StringRef BufferID = "<unknown>";
- StringRef LineStr;
+ StringRef LineStr;
if (Loc.isValid()) {
unsigned CurBuf = FindBufferContainingLoc(Loc);
@@ -288,7 +288,7 @@ SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
const char *BufEnd = CurMB->getBufferEnd();
while (LineEnd != BufEnd && LineEnd[0] != '\n' && LineEnd[0] != '\r')
++LineEnd;
- LineStr = StringRef(LineStart, LineEnd - LineStart);
+ LineStr = StringRef(LineStart, LineEnd - LineStart);
// Convert any ranges to column ranges that only intersect the line of the
// location.
@@ -370,8 +370,8 @@ SMDiagnostic::SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN, int Line,
ArrayRef<std::pair<unsigned, unsigned>> Ranges,
ArrayRef<SMFixIt> Hints)
: SM(&sm), Loc(L), Filename(std::string(FN)), LineNo(Line), ColumnNo(Col),
- Kind(Kind), Message(Msg), LineContents(LineStr), Ranges(Ranges.vec()),
- FixIts(Hints.begin(), Hints.end()) {
+ Kind(Kind), Message(Msg), LineContents(LineStr), Ranges(Ranges.vec()),
+ FixIts(Hints.begin(), Hints.end()) {
llvm::sort(FixIts);
}
@@ -386,12 +386,12 @@ static void buildFixItLine(std::string &CaretLine, std::string &FixItLine,
size_t PrevHintEndCol = 0;
- for (const llvm::SMFixIt &Fixit : FixIts) {
+ for (const llvm::SMFixIt &Fixit : FixIts) {
// If the fixit contains a newline or tab, ignore it.
- if (Fixit.getText().find_first_of("\n\r\t") != StringRef::npos)
+ if (Fixit.getText().find_first_of("\n\r\t") != StringRef::npos)
continue;
- SMRange R = Fixit.getRange();
+ SMRange R = Fixit.getRange();
// If the line doesn't contain any part of the range, then ignore it.
if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
@@ -420,15 +420,15 @@ static void buildFixItLine(std::string &CaretLine, std::string &FixItLine,
// FIXME: This assertion is intended to catch unintended use of multibyte
// characters in fixits. If we decide to do this, we'll have to track
// separate byte widths for the source and fixit lines.
- assert((size_t)sys::locale::columnWidth(Fixit.getText()) ==
- Fixit.getText().size());
+ assert((size_t)sys::locale::columnWidth(Fixit.getText()) ==
+ Fixit.getText().size());
// This relies on one byte per column in our fixit hints.
- unsigned LastColumnModified = HintCol + Fixit.getText().size();
+ unsigned LastColumnModified = HintCol + Fixit.getText().size();
if (LastColumnModified > FixItLine.size())
FixItLine.resize(LastColumnModified, ' ');
- llvm::copy(Fixit.getText(), FixItLine.begin() + HintCol);
+ llvm::copy(Fixit.getText(), FixItLine.begin() + HintCol);
PrevHintEndCol = LastColumnModified;
@@ -522,7 +522,7 @@ void SMDiagnostic::print(const char *ProgName, raw_ostream &OS, bool ShowColors,
// map like Clang's TextDiagnostic. For now, we'll just handle tabs by
// expanding them later, and bail out rather than show incorrect ranges and
// misaligned fixits for any other odd characters.
- if (any_of(LineContents, isNonASCII)) {
+ if (any_of(LineContents, isNonASCII)) {
printSourceLine(OS, LineContents);
return;
}
@@ -532,7 +532,7 @@ void SMDiagnostic::print(const char *ProgName, raw_ostream &OS, bool ShowColors,
std::string CaretLine(NumColumns + 1, ' ');
// Expand any ranges.
- for (const std::pair<unsigned, unsigned> &R : Ranges)
+ for (const std::pair<unsigned, unsigned> &R : Ranges)
std::fill(&CaretLine[R.first],
&CaretLine[std::min((size_t)R.second, CaretLine.size())], '~');
diff --git a/contrib/libs/llvm12/lib/Support/TargetParser.cpp b/contrib/libs/llvm12/lib/Support/TargetParser.cpp
index 9cf604de34..3ccdc55b30 100644
--- a/contrib/libs/llvm12/lib/Support/TargetParser.cpp
+++ b/contrib/libs/llvm12/lib/Support/TargetParser.cpp
@@ -30,7 +30,7 @@ struct GPUInfo {
unsigned Features;
};
-constexpr GPUInfo R600GPUs[] = {
+constexpr GPUInfo R600GPUs[] = {
// Name Canonical Kind Features
// Name
{{"r600"}, {"r600"}, GK_R600, FEATURE_NONE },
@@ -63,7 +63,7 @@ constexpr GPUInfo R600GPUs[] = {
// This table should be sorted by the value of GPUKind
// Don't bother listing the implicitly true features
-constexpr GPUInfo AMDGCNGPUs[] = {
+constexpr GPUInfo AMDGCNGPUs[] = {
// Name Canonical Kind Features
// Name
{{"gfx600"}, {"gfx600"}, GK_GFX600, FEATURE_FAST_FMA_F32},
@@ -71,9 +71,9 @@ constexpr GPUInfo AMDGCNGPUs[] = {
{{"gfx601"}, {"gfx601"}, GK_GFX601, FEATURE_NONE},
{{"pitcairn"}, {"gfx601"}, GK_GFX601, FEATURE_NONE},
{{"verde"}, {"gfx601"}, GK_GFX601, FEATURE_NONE},
- {{"gfx602"}, {"gfx602"}, GK_GFX602, FEATURE_NONE},
- {{"hainan"}, {"gfx602"}, GK_GFX602, FEATURE_NONE},
- {{"oland"}, {"gfx602"}, GK_GFX602, FEATURE_NONE},
+ {{"gfx602"}, {"gfx602"}, GK_GFX602, FEATURE_NONE},
+ {{"hainan"}, {"gfx602"}, GK_GFX602, FEATURE_NONE},
+ {{"oland"}, {"gfx602"}, GK_GFX602, FEATURE_NONE},
{{"gfx700"}, {"gfx700"}, GK_GFX700, FEATURE_NONE},
{{"kaveri"}, {"gfx700"}, GK_GFX700, FEATURE_NONE},
{{"gfx701"}, {"gfx701"}, GK_GFX701, FEATURE_FAST_FMA_F32},
@@ -84,43 +84,43 @@ constexpr GPUInfo AMDGCNGPUs[] = {
{{"mullins"}, {"gfx703"}, GK_GFX703, FEATURE_NONE},
{{"gfx704"}, {"gfx704"}, GK_GFX704, FEATURE_NONE},
{{"bonaire"}, {"gfx704"}, GK_GFX704, FEATURE_NONE},
- {{"gfx705"}, {"gfx705"}, GK_GFX705, FEATURE_NONE},
- {{"gfx801"}, {"gfx801"}, GK_GFX801, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
- {{"carrizo"}, {"gfx801"}, GK_GFX801, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
- {{"gfx802"}, {"gfx802"}, GK_GFX802, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
- {{"iceland"}, {"gfx802"}, GK_GFX802, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
- {{"tonga"}, {"gfx802"}, GK_GFX802, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
- {{"gfx803"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
- {{"fiji"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
- {{"polaris10"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
- {{"polaris11"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
- {{"gfx805"}, {"gfx805"}, GK_GFX805, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
- {{"tongapro"}, {"gfx805"}, GK_GFX805, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
- {{"gfx810"}, {"gfx810"}, GK_GFX810, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
- {{"stoney"}, {"gfx810"}, GK_GFX810, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
- {{"gfx900"}, {"gfx900"}, GK_GFX900, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
- {{"gfx902"}, {"gfx902"}, GK_GFX902, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
- {{"gfx904"}, {"gfx904"}, GK_GFX904, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
- {{"gfx906"}, {"gfx906"}, GK_GFX906, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK|FEATURE_SRAMECC},
- {{"gfx908"}, {"gfx908"}, GK_GFX908, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK|FEATURE_SRAMECC},
- {{"gfx909"}, {"gfx909"}, GK_GFX909, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
- {{"gfx90c"}, {"gfx90c"}, GK_GFX90C, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
- {{"gfx1010"}, {"gfx1010"}, GK_GFX1010, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32|FEATURE_XNACK},
- {{"gfx1011"}, {"gfx1011"}, GK_GFX1011, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32|FEATURE_XNACK},
- {{"gfx1012"}, {"gfx1012"}, GK_GFX1012, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32|FEATURE_XNACK},
+ {{"gfx705"}, {"gfx705"}, GK_GFX705, FEATURE_NONE},
+ {{"gfx801"}, {"gfx801"}, GK_GFX801, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
+ {{"carrizo"}, {"gfx801"}, GK_GFX801, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
+ {{"gfx802"}, {"gfx802"}, GK_GFX802, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
+ {{"iceland"}, {"gfx802"}, GK_GFX802, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
+ {{"tonga"}, {"gfx802"}, GK_GFX802, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
+ {{"gfx803"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
+ {{"fiji"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
+ {{"polaris10"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
+ {{"polaris11"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
+ {{"gfx805"}, {"gfx805"}, GK_GFX805, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
+ {{"tongapro"}, {"gfx805"}, GK_GFX805, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
+ {{"gfx810"}, {"gfx810"}, GK_GFX810, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
+ {{"stoney"}, {"gfx810"}, GK_GFX810, FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
+ {{"gfx900"}, {"gfx900"}, GK_GFX900, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
+ {{"gfx902"}, {"gfx902"}, GK_GFX902, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
+ {{"gfx904"}, {"gfx904"}, GK_GFX904, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
+ {{"gfx906"}, {"gfx906"}, GK_GFX906, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK|FEATURE_SRAMECC},
+ {{"gfx908"}, {"gfx908"}, GK_GFX908, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK|FEATURE_SRAMECC},
+ {{"gfx909"}, {"gfx909"}, GK_GFX909, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
+ {{"gfx90c"}, {"gfx90c"}, GK_GFX90C, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_XNACK},
+ {{"gfx1010"}, {"gfx1010"}, GK_GFX1010, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32|FEATURE_XNACK},
+ {{"gfx1011"}, {"gfx1011"}, GK_GFX1011, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32|FEATURE_XNACK},
+ {{"gfx1012"}, {"gfx1012"}, GK_GFX1012, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32|FEATURE_XNACK},
{{"gfx1030"}, {"gfx1030"}, GK_GFX1030, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32},
- {{"gfx1031"}, {"gfx1031"}, GK_GFX1031, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32},
- {{"gfx1032"}, {"gfx1032"}, GK_GFX1032, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32},
- {{"gfx1033"}, {"gfx1033"}, GK_GFX1033, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32},
+ {{"gfx1031"}, {"gfx1031"}, GK_GFX1031, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32},
+ {{"gfx1032"}, {"gfx1032"}, GK_GFX1032, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32},
+ {{"gfx1033"}, {"gfx1033"}, GK_GFX1033, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32},
};
const GPUInfo *getArchEntry(AMDGPU::GPUKind AK, ArrayRef<GPUInfo> Table) {
GPUInfo Search = { {""}, {""}, AK, AMDGPU::FEATURE_NONE };
- auto I =
- llvm::lower_bound(Table, Search, [](const GPUInfo &A, const GPUInfo &B) {
- return A.Kind < B.Kind;
- });
+ auto I =
+ llvm::lower_bound(Table, Search, [](const GPUInfo &A, const GPUInfo &B) {
+ return A.Kind < B.Kind;
+ });
if (I == Table.end())
return nullptr;
@@ -195,17 +195,17 @@ AMDGPU::IsaVersion AMDGPU::getIsaVersion(StringRef GPU) {
switch (AK) {
case GK_GFX600: return {6, 0, 0};
case GK_GFX601: return {6, 0, 1};
- case GK_GFX602: return {6, 0, 2};
+ case GK_GFX602: return {6, 0, 2};
case GK_GFX700: return {7, 0, 0};
case GK_GFX701: return {7, 0, 1};
case GK_GFX702: return {7, 0, 2};
case GK_GFX703: return {7, 0, 3};
case GK_GFX704: return {7, 0, 4};
- case GK_GFX705: return {7, 0, 5};
+ case GK_GFX705: return {7, 0, 5};
case GK_GFX801: return {8, 0, 1};
case GK_GFX802: return {8, 0, 2};
case GK_GFX803: return {8, 0, 3};
- case GK_GFX805: return {8, 0, 5};
+ case GK_GFX805: return {8, 0, 5};
case GK_GFX810: return {8, 1, 0};
case GK_GFX900: return {9, 0, 0};
case GK_GFX902: return {9, 0, 2};
@@ -213,27 +213,27 @@ AMDGPU::IsaVersion AMDGPU::getIsaVersion(StringRef GPU) {
case GK_GFX906: return {9, 0, 6};
case GK_GFX908: return {9, 0, 8};
case GK_GFX909: return {9, 0, 9};
- case GK_GFX90C: return {9, 0, 12};
+ case GK_GFX90C: return {9, 0, 12};
case GK_GFX1010: return {10, 1, 0};
case GK_GFX1011: return {10, 1, 1};
case GK_GFX1012: return {10, 1, 2};
case GK_GFX1030: return {10, 3, 0};
- case GK_GFX1031: return {10, 3, 1};
- case GK_GFX1032: return {10, 3, 2};
- case GK_GFX1033: return {10, 3, 3};
+ case GK_GFX1031: return {10, 3, 1};
+ case GK_GFX1032: return {10, 3, 2};
+ case GK_GFX1033: return {10, 3, 3};
default: return {0, 0, 0};
}
}
-StringRef AMDGPU::getCanonicalArchName(const Triple &T, StringRef Arch) {
- assert(T.isAMDGPU());
- auto ProcKind = T.isAMDGCN() ? parseArchAMDGCN(Arch) : parseArchR600(Arch);
- if (ProcKind == GK_NONE)
- return StringRef();
-
- return T.isAMDGCN() ? getArchNameAMDGCN(ProcKind) : getArchNameR600(ProcKind);
-}
-
+StringRef AMDGPU::getCanonicalArchName(const Triple &T, StringRef Arch) {
+ assert(T.isAMDGPU());
+ auto ProcKind = T.isAMDGCN() ? parseArchAMDGCN(Arch) : parseArchR600(Arch);
+ if (ProcKind == GK_NONE)
+ return StringRef();
+
+ return T.isAMDGCN() ? getArchNameAMDGCN(ProcKind) : getArchNameR600(ProcKind);
+}
+
namespace llvm {
namespace RISCV {
@@ -257,12 +257,12 @@ bool checkCPUKind(CPUKind Kind, bool IsRV64) {
return RISCVCPUInfo[static_cast<unsigned>(Kind)].is64Bit() == IsRV64;
}
-bool checkTuneCPUKind(CPUKind Kind, bool IsRV64) {
- if (Kind == CK_INVALID)
- return false;
- return RISCVCPUInfo[static_cast<unsigned>(Kind)].is64Bit() == IsRV64;
-}
-
+bool checkTuneCPUKind(CPUKind Kind, bool IsRV64) {
+ if (Kind == CK_INVALID)
+ return false;
+ return RISCVCPUInfo[static_cast<unsigned>(Kind)].is64Bit() == IsRV64;
+}
+
CPUKind parseCPUKind(StringRef CPU) {
return llvm::StringSwitch<CPUKind>(CPU)
#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) .Case(NAME, CK_##ENUM)
@@ -270,22 +270,22 @@ CPUKind parseCPUKind(StringRef CPU) {
.Default(CK_INVALID);
}
-StringRef resolveTuneCPUAlias(StringRef TuneCPU, bool IsRV64) {
- return llvm::StringSwitch<StringRef>(TuneCPU)
-#define PROC_ALIAS(NAME, RV32, RV64) .Case(NAME, IsRV64 ? StringRef(RV64) : StringRef(RV32))
-#include "llvm/Support/RISCVTargetParser.def"
- .Default(TuneCPU);
-}
-
-CPUKind parseTuneCPUKind(StringRef TuneCPU, bool IsRV64) {
- TuneCPU = resolveTuneCPUAlias(TuneCPU, IsRV64);
-
- return llvm::StringSwitch<CPUKind>(TuneCPU)
-#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) .Case(NAME, CK_##ENUM)
-#include "llvm/Support/RISCVTargetParser.def"
- .Default(CK_INVALID);
-}
-
+StringRef resolveTuneCPUAlias(StringRef TuneCPU, bool IsRV64) {
+ return llvm::StringSwitch<StringRef>(TuneCPU)
+#define PROC_ALIAS(NAME, RV32, RV64) .Case(NAME, IsRV64 ? StringRef(RV64) : StringRef(RV32))
+#include "llvm/Support/RISCVTargetParser.def"
+ .Default(TuneCPU);
+}
+
+CPUKind parseTuneCPUKind(StringRef TuneCPU, bool IsRV64) {
+ TuneCPU = resolveTuneCPUAlias(TuneCPU, IsRV64);
+
+ return llvm::StringSwitch<CPUKind>(TuneCPU)
+#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) .Case(NAME, CK_##ENUM)
+#include "llvm/Support/RISCVTargetParser.def"
+ .Default(CK_INVALID);
+}
+
StringRef getMArchFromMcpu(StringRef CPU) {
CPUKind Kind = parseCPUKind(CPU);
return RISCVCPUInfo[static_cast<unsigned>(Kind)].DefaultMarch;
@@ -298,15 +298,15 @@ void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) {
}
}
-void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) {
- for (const auto &C : RISCVCPUInfo) {
- if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit())
- Values.emplace_back(C.Name);
- }
-#define PROC_ALIAS(NAME, RV32, RV64) Values.emplace_back(StringRef(NAME));
-#include "llvm/Support/RISCVTargetParser.def"
-}
-
+void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) {
+ for (const auto &C : RISCVCPUInfo) {
+ if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit())
+ Values.emplace_back(C.Name);
+ }
+#define PROC_ALIAS(NAME, RV32, RV64) Values.emplace_back(StringRef(NAME));
+#include "llvm/Support/RISCVTargetParser.def"
+}
+
// Get all features except standard extension feature
bool getCPUFeaturesExceptStdExt(CPUKind Kind,
std::vector<StringRef> &Features) {
diff --git a/contrib/libs/llvm12/lib/Support/Timer.cpp b/contrib/libs/llvm12/lib/Support/Timer.cpp
index b2cfb4a4aa..f5a512f9a2 100644
--- a/contrib/libs/llvm12/lib/Support/Timer.cpp
+++ b/contrib/libs/llvm12/lib/Support/Timer.cpp
@@ -53,11 +53,11 @@ namespace {
InfoOutputFilename("info-output-file", cl::value_desc("filename"),
cl::desc("File to append -stats and -timer output to"),
cl::Hidden, cl::location(getLibSupportInfoOutputFilename()));
-
- static cl::opt<bool>
- SortTimers("sort-timers", cl::desc("In the report, sort the timers in each group "
- "in wall clock time order"),
- cl::init(true), cl::Hidden);
+
+ static cl::opt<bool>
+ SortTimers("sort-timers", cl::desc("In the report, sort the timers in each group "
+ "in wall clock time order"),
+ cl::init(true), cl::Hidden);
}
std::unique_ptr<raw_fd_ostream> llvm::CreateInfoOutputFile() {
@@ -143,7 +143,7 @@ TimeRecord TimeRecord::getCurrentTime(bool Start) {
void Timer::startTimer() {
assert(!Running && "Cannot start a running timer");
Running = Triggered = true;
- Signposts->startInterval(this, getName());
+ Signposts->startInterval(this, getName());
StartTime = TimeRecord::getCurrentTime(true);
}
@@ -152,7 +152,7 @@ void Timer::stopTimer() {
Running = false;
Time += TimeRecord::getCurrentTime(false);
Time -= StartTime;
- Signposts->endInterval(this, getName());
+ Signposts->endInterval(this, getName());
}
void Timer::clear() {
@@ -306,9 +306,9 @@ void TimerGroup::addTimer(Timer &T) {
}
void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
- // Perhaps sort the timers in descending order by amount of time taken.
- if (SortTimers)
- llvm::sort(TimersToPrint);
+ // Perhaps sort the timers in descending order by amount of time taken.
+ if (SortTimers)
+ llvm::sort(TimersToPrint);
TimeRecord Total;
for (const PrintRecord &Record : TimersToPrint)
diff --git a/contrib/libs/llvm12/lib/Support/TrigramIndex.cpp b/contrib/libs/llvm12/lib/Support/TrigramIndex.cpp
index accc001dd7..4370adc9c3 100644
--- a/contrib/libs/llvm12/lib/Support/TrigramIndex.cpp
+++ b/contrib/libs/llvm12/lib/Support/TrigramIndex.cpp
@@ -25,7 +25,7 @@ static bool isAdvancedMetachar(unsigned Char) {
return strchr(RegexAdvancedMetachars, Char) != nullptr;
}
-void TrigramIndex::insert(const std::string &Regex) {
+void TrigramIndex::insert(const std::string &Regex) {
if (Defeated) return;
std::set<unsigned> Was;
unsigned Cnt = 0;
diff --git a/contrib/libs/llvm12/lib/Support/Triple.cpp b/contrib/libs/llvm12/lib/Support/Triple.cpp
index e764c79aa6..4f483c9652 100644
--- a/contrib/libs/llvm12/lib/Support/Triple.cpp
+++ b/contrib/libs/llvm12/lib/Support/Triple.cpp
@@ -36,7 +36,7 @@ StringRef Triple::getArchTypeName(ArchType Kind) {
case avr: return "avr";
case bpfeb: return "bpfeb";
case bpfel: return "bpfel";
- case csky: return "csky";
+ case csky: return "csky";
case hexagon: return "hexagon";
case hsail64: return "hsail64";
case hsail: return "hsail";
@@ -54,7 +54,7 @@ StringRef Triple::getArchTypeName(ArchType Kind) {
case ppc64: return "powerpc64";
case ppc64le: return "powerpc64le";
case ppc: return "powerpc";
- case ppcle: return "powerpcle";
+ case ppcle: return "powerpcle";
case r600: return "r600";
case renderscript32: return "renderscript32";
case renderscript64: return "renderscript64";
@@ -102,8 +102,8 @@ StringRef Triple::getArchTypePrefix(ArchType Kind) {
case ppc64:
case ppc64le:
- case ppc:
- case ppcle: return "ppc";
+ case ppc:
+ case ppcle: return "ppc";
case mips:
case mipsel:
@@ -154,7 +154,7 @@ StringRef Triple::getArchTypePrefix(ArchType Kind) {
case riscv64: return "riscv";
case ve: return "ve";
- case csky: return "csky";
+ case csky: return "csky";
}
}
@@ -219,7 +219,7 @@ StringRef Triple::getOSTypeName(OSType Kind) {
case WASI: return "wasi";
case WatchOS: return "watchos";
case Win32: return "windows";
- case ZOS: return "zos";
+ case ZOS: return "zos";
}
llvm_unreachable("Invalid OSType");
@@ -240,7 +240,7 @@ StringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) {
case GNUEABI: return "gnueabi";
case GNUEABIHF: return "gnueabihf";
case GNUX32: return "gnux32";
- case GNUILP32: return "gnu_ilp32";
+ case GNUILP32: return "gnu_ilp32";
case Itanium: return "itanium";
case MSVC: return "msvc";
case MacABI: return "macabi";
@@ -289,8 +289,8 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
.Case("ppc64", ppc64)
.Case("ppc32", ppc)
.Case("ppc", ppc)
- .Case("ppc32le", ppcle)
- .Case("ppcle", ppcle)
+ .Case("ppc32le", ppcle)
+ .Case("ppcle", ppcle)
.Case("ppc64le", ppc64le)
.Case("r600", r600)
.Case("amdgcn", amdgcn)
@@ -326,7 +326,7 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
.Case("renderscript32", renderscript32)
.Case("renderscript64", renderscript64)
.Case("ve", ve)
- .Case("csky", csky)
+ .Case("csky", csky)
.Default(UnknownArch);
}
@@ -402,7 +402,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Cases("i786", "i886", "i986", Triple::x86)
.Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
.Cases("powerpc", "powerpcspe", "ppc", "ppc32", Triple::ppc)
- .Cases("powerpcle", "ppcle", "ppc32le", Triple::ppcle)
+ .Cases("powerpcle", "ppcle", "ppc32le", Triple::ppcle)
.Cases("powerpc64", "ppu", "ppc64", Triple::ppc64)
.Cases("powerpc64le", "ppc64le", Triple::ppc64le)
.Case("xscale", Triple::arm)
@@ -413,7 +413,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Case("arc", Triple::arc)
.Case("arm64", Triple::aarch64)
.Case("arm64_32", Triple::aarch64_32)
- .Case("arm64e", Triple::aarch64)
+ .Case("arm64e", Triple::aarch64)
.Case("arm", Triple::arm)
.Case("armeb", Triple::armeb)
.Case("thumb", Triple::thumb)
@@ -458,7 +458,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Case("ve", Triple::ve)
.Case("wasm32", Triple::wasm32)
.Case("wasm64", Triple::wasm64)
- .Case("csky", Triple::csky)
+ .Case("csky", Triple::csky)
.Default(Triple::UnknownArch);
// Some architectures require special parsing logic just to compute the
@@ -511,7 +511,7 @@ static Triple::OSType parseOS(StringRef OSName) {
.StartsWith("solaris", Triple::Solaris)
.StartsWith("win32", Triple::Win32)
.StartsWith("windows", Triple::Win32)
- .StartsWith("zos", Triple::ZOS)
+ .StartsWith("zos", Triple::ZOS)
.StartsWith("haiku", Triple::Haiku)
.StartsWith("minix", Triple::Minix)
.StartsWith("rtems", Triple::RTEMS)
@@ -536,27 +536,27 @@ static Triple::OSType parseOS(StringRef OSName) {
static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
- .StartsWith("eabihf", Triple::EABIHF)
- .StartsWith("eabi", Triple::EABI)
- .StartsWith("gnuabin32", Triple::GNUABIN32)
- .StartsWith("gnuabi64", Triple::GNUABI64)
- .StartsWith("gnueabihf", Triple::GNUEABIHF)
- .StartsWith("gnueabi", Triple::GNUEABI)
- .StartsWith("gnux32", Triple::GNUX32)
- .StartsWith("gnu_ilp32", Triple::GNUILP32)
- .StartsWith("code16", Triple::CODE16)
- .StartsWith("gnu", Triple::GNU)
- .StartsWith("android", Triple::Android)
- .StartsWith("musleabihf", Triple::MuslEABIHF)
- .StartsWith("musleabi", Triple::MuslEABI)
- .StartsWith("musl", Triple::Musl)
- .StartsWith("msvc", Triple::MSVC)
- .StartsWith("itanium", Triple::Itanium)
- .StartsWith("cygnus", Triple::Cygnus)
- .StartsWith("coreclr", Triple::CoreCLR)
- .StartsWith("simulator", Triple::Simulator)
- .StartsWith("macabi", Triple::MacABI)
- .Default(Triple::UnknownEnvironment);
+ .StartsWith("eabihf", Triple::EABIHF)
+ .StartsWith("eabi", Triple::EABI)
+ .StartsWith("gnuabin32", Triple::GNUABIN32)
+ .StartsWith("gnuabi64", Triple::GNUABI64)
+ .StartsWith("gnueabihf", Triple::GNUEABIHF)
+ .StartsWith("gnueabi", Triple::GNUEABI)
+ .StartsWith("gnux32", Triple::GNUX32)
+ .StartsWith("gnu_ilp32", Triple::GNUILP32)
+ .StartsWith("code16", Triple::CODE16)
+ .StartsWith("gnu", Triple::GNU)
+ .StartsWith("android", Triple::Android)
+ .StartsWith("musleabihf", Triple::MuslEABIHF)
+ .StartsWith("musleabi", Triple::MuslEABI)
+ .StartsWith("musl", Triple::Musl)
+ .StartsWith("msvc", Triple::MSVC)
+ .StartsWith("itanium", Triple::Itanium)
+ .StartsWith("cygnus", Triple::Cygnus)
+ .StartsWith("coreclr", Triple::CoreCLR)
+ .StartsWith("simulator", Triple::Simulator)
+ .StartsWith("macabi", Triple::MacABI)
+ .Default(Triple::UnknownEnvironment);
}
static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
@@ -566,7 +566,7 @@ static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
.EndsWith("xcoff", Triple::XCOFF)
.EndsWith("coff", Triple::COFF)
.EndsWith("elf", Triple::ELF)
- .EndsWith("goff", Triple::GOFF)
+ .EndsWith("goff", Triple::GOFF)
.EndsWith("macho", Triple::MachO)
.EndsWith("wasm", Triple::Wasm)
.Default(Triple::UnknownObjectFormat);
@@ -580,9 +580,9 @@ static Triple::SubArchType parseSubArch(StringRef SubArchName) {
if (SubArchName == "powerpcspe")
return Triple::PPCSubArch_spe;
- if (SubArchName == "arm64e")
- return Triple::AArch64SubArch_arm64e;
-
+ if (SubArchName == "arm64e")
+ return Triple::AArch64SubArch_arm64e;
+
StringRef ARMSubArch = ARM::getCanonicalArchName(SubArchName);
// For now, this is the small part. Early return.
@@ -643,8 +643,8 @@ static Triple::SubArchType parseSubArch(StringRef SubArchName) {
return Triple::ARMSubArch_v8_5a;
case ARM::ArchKind::ARMV8_6A:
return Triple::ARMSubArch_v8_6a;
- case ARM::ArchKind::ARMV8_7A:
- return Triple::ARMSubArch_v8_7a;
+ case ARM::ArchKind::ARMV8_7A:
+ return Triple::ARMSubArch_v8_7a;
case ARM::ArchKind::ARMV8R:
return Triple::ARMSubArch_v8r;
case ARM::ArchKind::ARMV8MBaseline:
@@ -663,7 +663,7 @@ static StringRef getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
case Triple::UnknownObjectFormat: return "";
case Triple::COFF: return "coff";
case Triple::ELF: return "elf";
- case Triple::GOFF: return "goff";
+ case Triple::GOFF: return "goff";
case Triple::MachO: return "macho";
case Triple::Wasm: return "wasm";
case Triple::XCOFF: return "xcoff";
@@ -695,7 +695,7 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::avr:
case Triple::bpfeb:
case Triple::bpfel:
- case Triple::csky:
+ case Triple::csky:
case Triple::hexagon:
case Triple::hsail64:
case Triple::hsail:
@@ -711,7 +711,7 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::nvptx64:
case Triple::nvptx:
case Triple::ppc64le:
- case Triple::ppcle:
+ case Triple::ppcle:
case Triple::r600:
case Triple::renderscript32:
case Triple::renderscript64:
@@ -736,11 +736,11 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
return Triple::XCOFF;
return Triple::ELF;
- case Triple::systemz:
- if (T.isOSzOS())
- return Triple::GOFF;
- return Triple::ELF;
-
+ case Triple::systemz:
+ if (T.isOSzOS())
+ return Triple::GOFF;
+ return Triple::ELF;
+
case Triple::wasm32:
case Triple::wasm64:
return Triple::Wasm;
@@ -1038,7 +1038,7 @@ StringRef Triple::getOSAndEnvironmentName() const {
}
static unsigned EatNumber(StringRef &Str) {
- assert(!Str.empty() && isDigit(Str[0]) && "Not a number");
+ assert(!Str.empty() && isDigit(Str[0]) && "Not a number");
unsigned Result = 0;
do {
@@ -1047,7 +1047,7 @@ static unsigned EatNumber(StringRef &Str) {
// Eat the digit.
Str = Str.substr(1);
- } while (!Str.empty() && isDigit(Str[0]));
+ } while (!Str.empty() && isDigit(Str[0]));
return Result;
}
@@ -1270,7 +1270,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::arc:
case llvm::Triple::arm:
case llvm::Triple::armeb:
- case llvm::Triple::csky:
+ case llvm::Triple::csky:
case llvm::Triple::hexagon:
case llvm::Triple::hsail:
case llvm::Triple::kalimba:
@@ -1280,7 +1280,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::mipsel:
case llvm::Triple::nvptx:
case llvm::Triple::ppc:
- case llvm::Triple::ppcle:
+ case llvm::Triple::ppcle:
case llvm::Triple::r600:
case llvm::Triple::renderscript32:
case llvm::Triple::riscv32:
@@ -1354,7 +1354,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::arc:
case Triple::arm:
case Triple::armeb:
- case Triple::csky:
+ case Triple::csky:
case Triple::hexagon:
case Triple::hsail:
case Triple::kalimba:
@@ -1364,7 +1364,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::mipsel:
case Triple::nvptx:
case Triple::ppc:
- case Triple::ppcle:
+ case Triple::ppcle:
case Triple::r600:
case Triple::renderscript32:
case Triple::riscv32:
@@ -1391,7 +1391,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::mips64el: T.setArch(Triple::mipsel); break;
case Triple::nvptx64: T.setArch(Triple::nvptx); break;
case Triple::ppc64: T.setArch(Triple::ppc); break;
- case Triple::ppc64le: T.setArch(Triple::ppcle); break;
+ case Triple::ppc64le: T.setArch(Triple::ppcle); break;
case Triple::renderscript64: T.setArch(Triple::renderscript32); break;
case Triple::riscv64: T.setArch(Triple::riscv32); break;
case Triple::sparcv9: T.setArch(Triple::sparc); break;
@@ -1408,7 +1408,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::UnknownArch:
case Triple::arc:
case Triple::avr:
- case Triple::csky:
+ case Triple::csky:
case Triple::hexagon:
case Triple::kalimba:
case Triple::lanai:
@@ -1456,7 +1456,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::mipsel: T.setArch(Triple::mips64el); break;
case Triple::nvptx: T.setArch(Triple::nvptx64); break;
case Triple::ppc: T.setArch(Triple::ppc64); break;
- case Triple::ppcle: T.setArch(Triple::ppc64le); break;
+ case Triple::ppcle: T.setArch(Triple::ppc64le); break;
case Triple::renderscript32: T.setArch(Triple::renderscript64); break;
case Triple::riscv32: T.setArch(Triple::riscv64); break;
case Triple::sparc: T.setArch(Triple::sparcv9); break;
@@ -1503,7 +1503,7 @@ Triple Triple::getBigEndianArchVariant() const {
case Triple::x86_64:
case Triple::xcore:
case Triple::ve:
- case Triple::csky:
+ case Triple::csky:
// ARM is intentionally unsupported here, changing the architecture would
// drop any arch suffixes.
@@ -1516,7 +1516,7 @@ Triple Triple::getBigEndianArchVariant() const {
case Triple::bpfel: T.setArch(Triple::bpfeb); break;
case Triple::mips64el:T.setArch(Triple::mips64); break;
case Triple::mipsel: T.setArch(Triple::mips); break;
- case Triple::ppcle: T.setArch(Triple::ppc); break;
+ case Triple::ppcle: T.setArch(Triple::ppc); break;
case Triple::ppc64le: T.setArch(Triple::ppc64); break;
case Triple::sparcel: T.setArch(Triple::sparc); break;
case Triple::tcele: T.setArch(Triple::tce); break;
@@ -1548,7 +1548,7 @@ Triple Triple::getLittleEndianArchVariant() const {
case Triple::bpfeb: T.setArch(Triple::bpfel); break;
case Triple::mips64: T.setArch(Triple::mips64el); break;
case Triple::mips: T.setArch(Triple::mipsel); break;
- case Triple::ppc: T.setArch(Triple::ppcle); break;
+ case Triple::ppc: T.setArch(Triple::ppcle); break;
case Triple::ppc64: T.setArch(Triple::ppc64le); break;
case Triple::sparc: T.setArch(Triple::sparcel); break;
case Triple::tce: T.setArch(Triple::tcele); break;
@@ -1568,7 +1568,7 @@ bool Triple::isLittleEndian() const {
case Triple::arm:
case Triple::avr:
case Triple::bpfel:
- case Triple::csky:
+ case Triple::csky:
case Triple::hexagon:
case Triple::hsail64:
case Triple::hsail:
@@ -1580,7 +1580,7 @@ bool Triple::isLittleEndian() const {
case Triple::msp430:
case Triple::nvptx64:
case Triple::nvptx:
- case Triple::ppcle:
+ case Triple::ppcle:
case Triple::ppc64le:
case Triple::r600:
case Triple::renderscript32:
@@ -1667,9 +1667,9 @@ VersionTuple Triple::getMinimumSupportedOSVersion() const {
// ARM64 simulators are supported for iOS 14+.
if (isMacCatalystEnvironment() || isSimulatorEnvironment())
return VersionTuple(14, 0, 0);
- // ARM64e slice is supported starting from iOS 14.
- if (isArm64e())
- return VersionTuple(14, 0, 0);
+ // ARM64e slice is supported starting from iOS 14.
+ if (isArm64e())
+ return VersionTuple(14, 0, 0);
break;
case Triple::TvOS:
// ARM64 simulators are supported for tvOS 14+.
diff --git a/contrib/libs/llvm12/lib/Support/Unicode.cpp b/contrib/libs/llvm12/lib/Support/Unicode.cpp
index cdfc3042c5..bb6e75555b 100644
--- a/contrib/libs/llvm12/lib/Support/Unicode.cpp
+++ b/contrib/libs/llvm12/lib/Support/Unicode.cpp
@@ -339,22 +339,22 @@ static inline int charWidth(int UCS)
return 1;
}
-static bool isprintableascii(char c) { return c > 31 && c < 127; }
-
+static bool isprintableascii(char c) { return c > 31 && c < 127; }
+
int columnWidthUTF8(StringRef Text) {
unsigned ColumnWidth = 0;
unsigned Length;
for (size_t i = 0, e = Text.size(); i < e; i += Length) {
Length = getNumBytesForUTF8(Text[i]);
-
- // fast path for ASCII characters
- if (Length == 1) {
- if (!isprintableascii(Text[i]))
- return ErrorNonPrintableCharacter;
- ColumnWidth += 1;
- continue;
- }
-
+
+ // fast path for ASCII characters
+ if (Length == 1) {
+ if (!isprintableascii(Text[i]))
+ return ErrorNonPrintableCharacter;
+ ColumnWidth += 1;
+ continue;
+ }
+
if (Length <= 0 || i + Length > Text.size())
return ErrorInvalidUTF8;
UTF32 buf[1];
diff --git a/contrib/libs/llvm12/lib/Support/Unix/Path.inc b/contrib/libs/llvm12/lib/Support/Unix/Path.inc
index 1c2fc15fc5..996b8aebf6 100644
--- a/contrib/libs/llvm12/lib/Support/Unix/Path.inc
+++ b/contrib/libs/llvm12/lib/Support/Unix/Path.inc
@@ -33,7 +33,7 @@
#include <dirent.h>
#include <pwd.h>
-#include <sys/file.h>
+#include <sys/file.h>
#ifdef __APPLE__
#include <mach-o/dyld.h>
@@ -147,9 +147,9 @@ test_dir(char ret[PATH_MAX], const char *dir, const char *bin)
static char *
getprogpath(char ret[PATH_MAX], const char *bin)
{
- if (bin == nullptr)
- return nullptr;
-
+ if (bin == nullptr)
+ return nullptr;
+
/* First approach: absolute path. */
if (bin[0] == '/') {
if (test_dir(ret, "/", bin) == 0)
@@ -793,16 +793,16 @@ std::error_code setLastAccessAndModificationTime(int FD, TimePoint<> AccessTime,
if (::futimes(FD, Times))
return std::error_code(errno, std::generic_category());
return std::error_code();
-#elif defined(__MVS__)
- attrib_t Attr;
- memset(&Attr, 0, sizeof(Attr));
- Attr.att_atimechg = 1;
- Attr.att_atime = sys::toTimeT(AccessTime);
- Attr.att_mtimechg = 1;
- Attr.att_mtime = sys::toTimeT(ModificationTime);
- if (::__fchattr(FD, &Attr, sizeof(Attr)) != 0)
- return std::error_code(errno, std::generic_category());
- return std::error_code();
+#elif defined(__MVS__)
+ attrib_t Attr;
+ memset(&Attr, 0, sizeof(Attr));
+ Attr.att_atimechg = 1;
+ Attr.att_atime = sys::toTimeT(AccessTime);
+ Attr.att_mtimechg = 1;
+ Attr.att_mtime = sys::toTimeT(ModificationTime);
+ if (::__fchattr(FD, &Attr, sizeof(Attr)) != 0)
+ return std::error_code(errno, std::generic_category());
+ return std::error_code();
#else
#warning Missing futimes() and futimens()
return make_error_code(errc::function_not_supported);
@@ -1067,13 +1067,13 @@ file_t getStdoutHandle() { return 1; }
file_t getStderrHandle() { return 2; }
Expected<size_t> readNativeFile(file_t FD, MutableArrayRef<char> Buf) {
-#if defined(__APPLE__)
- size_t Size = std::min<size_t>(Buf.size(), INT32_MAX);
-#else
- size_t Size = Buf.size();
-#endif
+#if defined(__APPLE__)
+ size_t Size = std::min<size_t>(Buf.size(), INT32_MAX);
+#else
+ size_t Size = Buf.size();
+#endif
ssize_t NumRead =
- sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Size);
+ sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Size);
if (ssize_t(NumRead) == -1)
return errorCodeToError(std::error_code(errno, std::generic_category()));
return NumRead;
@@ -1081,69 +1081,69 @@ Expected<size_t> readNativeFile(file_t FD, MutableArrayRef<char> Buf) {
Expected<size_t> readNativeFileSlice(file_t FD, MutableArrayRef<char> Buf,
uint64_t Offset) {
-#if defined(__APPLE__)
- size_t Size = std::min<size_t>(Buf.size(), INT32_MAX);
-#else
- size_t Size = Buf.size();
-#endif
+#if defined(__APPLE__)
+ size_t Size = std::min<size_t>(Buf.size(), INT32_MAX);
+#else
+ size_t Size = Buf.size();
+#endif
#ifdef HAVE_PREAD
ssize_t NumRead =
- sys::RetryAfterSignal(-1, ::pread, FD, Buf.data(), Size, Offset);
+ sys::RetryAfterSignal(-1, ::pread, FD, Buf.data(), Size, Offset);
#else
if (lseek(FD, Offset, SEEK_SET) == -1)
return errorCodeToError(std::error_code(errno, std::generic_category()));
ssize_t NumRead =
- sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Size);
+ sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Size);
#endif
if (NumRead == -1)
return errorCodeToError(std::error_code(errno, std::generic_category()));
return NumRead;
}
-std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout) {
- auto Start = std::chrono::steady_clock::now();
- auto End = Start + Timeout;
- do {
- struct flock Lock;
- memset(&Lock, 0, sizeof(Lock));
- Lock.l_type = F_WRLCK;
- Lock.l_whence = SEEK_SET;
- Lock.l_start = 0;
- Lock.l_len = 0;
- if (::fcntl(FD, F_SETLK, &Lock) != -1)
- return std::error_code();
- int Error = errno;
- if (Error != EACCES && Error != EAGAIN)
- return std::error_code(Error, std::generic_category());
- usleep(1000);
- } while (std::chrono::steady_clock::now() < End);
- return make_error_code(errc::no_lock_available);
-}
-
-std::error_code lockFile(int FD) {
- struct flock Lock;
- memset(&Lock, 0, sizeof(Lock));
- Lock.l_type = F_WRLCK;
- Lock.l_whence = SEEK_SET;
- Lock.l_start = 0;
- Lock.l_len = 0;
- if (::fcntl(FD, F_SETLKW, &Lock) != -1)
- return std::error_code();
- int Error = errno;
- return std::error_code(Error, std::generic_category());
-}
-
-std::error_code unlockFile(int FD) {
- struct flock Lock;
- Lock.l_type = F_UNLCK;
- Lock.l_whence = SEEK_SET;
- Lock.l_start = 0;
- Lock.l_len = 0;
- if (::fcntl(FD, F_SETLK, &Lock) != -1)
- return std::error_code();
- return std::error_code(errno, std::generic_category());
-}
-
+std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout) {
+ auto Start = std::chrono::steady_clock::now();
+ auto End = Start + Timeout;
+ do {
+ struct flock Lock;
+ memset(&Lock, 0, sizeof(Lock));
+ Lock.l_type = F_WRLCK;
+ Lock.l_whence = SEEK_SET;
+ Lock.l_start = 0;
+ Lock.l_len = 0;
+ if (::fcntl(FD, F_SETLK, &Lock) != -1)
+ return std::error_code();
+ int Error = errno;
+ if (Error != EACCES && Error != EAGAIN)
+ return std::error_code(Error, std::generic_category());
+ usleep(1000);
+ } while (std::chrono::steady_clock::now() < End);
+ return make_error_code(errc::no_lock_available);
+}
+
+std::error_code lockFile(int FD) {
+ struct flock Lock;
+ memset(&Lock, 0, sizeof(Lock));
+ Lock.l_type = F_WRLCK;
+ Lock.l_whence = SEEK_SET;
+ Lock.l_start = 0;
+ Lock.l_len = 0;
+ if (::fcntl(FD, F_SETLKW, &Lock) != -1)
+ return std::error_code();
+ int Error = errno;
+ return std::error_code(Error, std::generic_category());
+}
+
+std::error_code unlockFile(int FD) {
+ struct flock Lock;
+ Lock.l_type = F_UNLCK;
+ Lock.l_whence = SEEK_SET;
+ Lock.l_start = 0;
+ Lock.l_len = 0;
+ if (::fcntl(FD, F_SETLK, &Lock) != -1)
+ return std::error_code();
+ return std::error_code(errno, std::generic_category());
+}
+
std::error_code closeFile(file_t &F) {
file_t TmpF = F;
F = kInvalidFile;
diff --git a/contrib/libs/llvm12/lib/Support/Unix/Process.inc b/contrib/libs/llvm12/lib/Support/Unix/Process.inc
index 8058a3b7ce..7425d084da 100644
--- a/contrib/libs/llvm12/lib/Support/Unix/Process.inc
+++ b/contrib/libs/llvm12/lib/Support/Unix/Process.inc
@@ -313,7 +313,7 @@ unsigned Process::StandardErrColumns() {
return getColumns();
}
-#ifdef LLVM_ENABLE_TERMINFO
+#ifdef LLVM_ENABLE_TERMINFO
// We manually declare these extern functions because finding the correct
// headers from various terminfo, curses, or other sources is harder than
// writing their specs down.
@@ -323,12 +323,12 @@ extern "C" int del_curterm(struct term *termp);
extern "C" int tigetnum(char *capname);
#endif
-#ifdef LLVM_ENABLE_TERMINFO
+#ifdef LLVM_ENABLE_TERMINFO
static ManagedStatic<std::mutex> TermColorMutex;
#endif
static bool terminalHasColors(int fd) {
-#ifdef LLVM_ENABLE_TERMINFO
+#ifdef LLVM_ENABLE_TERMINFO
// First, acquire a global lock because these C routines are thread hostile.
std::lock_guard<std::mutex> G(*TermColorMutex);
diff --git a/contrib/libs/llvm12/lib/Support/Unix/Program.inc b/contrib/libs/llvm12/lib/Support/Unix/Program.inc
index a018bc06d1..fb56fa4b0d 100644
--- a/contrib/libs/llvm12/lib/Support/Unix/Program.inc
+++ b/contrib/libs/llvm12/lib/Support/Unix/Program.inc
@@ -174,8 +174,8 @@ toNullTerminatedCStringArray(ArrayRef<StringRef> Strings, StringSaver &Saver) {
static bool Execute(ProcessInfo &PI, StringRef Program,
ArrayRef<StringRef> Args, Optional<ArrayRef<StringRef>> Env,
ArrayRef<Optional<StringRef>> Redirects,
- unsigned MemoryLimit, std::string *ErrMsg,
- BitVector *AffinityMask) {
+ unsigned MemoryLimit, std::string *ErrMsg,
+ BitVector *AffinityMask) {
if (!llvm::sys::fs::exists(Program)) {
if (ErrMsg)
*ErrMsg = std::string("Executable \"") + Program.str() +
@@ -183,9 +183,9 @@ static bool Execute(ProcessInfo &PI, StringRef Program,
return false;
}
- assert(!AffinityMask && "Starting a process with an affinity mask is "
- "currently not supported on Unix!");
-
+ assert(!AffinityMask && "Starting a process with an affinity mask is "
+ "currently not supported on Unix!");
+
BumpPtrAllocator Allocator;
StringSaver Saver(Allocator);
std::vector<const char *> ArgVector, EnvVector;
diff --git a/contrib/libs/llvm12/lib/Support/Unix/Signals.inc b/contrib/libs/llvm12/lib/Support/Unix/Signals.inc
index 8906d28ddd..3d7b5d2fe5 100644
--- a/contrib/libs/llvm12/lib/Support/Unix/Signals.inc
+++ b/contrib/libs/llvm12/lib/Support/Unix/Signals.inc
@@ -36,7 +36,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Config/config.h"
#include "llvm/Demangle/Demangle.h"
-#include "llvm/Support/ExitCodes.h"
+#include "llvm/Support/ExitCodes.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/Format.h"
@@ -331,7 +331,7 @@ static void RegisterHandlers() { // Not signal-safe.
registerHandler(S, SignalKind::IsInfo);
}
-void sys::unregisterHandlers() {
+void sys::unregisterHandlers() {
// Restore all of the signal handlers to how they were before we showed up.
for (unsigned i = 0, e = NumRegisteredSignals.load(); i != e; ++i) {
sigaction(RegisteredSignalInfo[i].SigNo,
@@ -367,7 +367,7 @@ static RETSIGTYPE SignalHandler(int Sig) {
// crashes when we return and the signal reissues. This also ensures that if
// we crash in our signal handler that the program will terminate immediately
// instead of recursing in the signal handler.
- sys::unregisterHandlers();
+ sys::unregisterHandlers();
// Unmask all potentially blocked kill signals.
sigset_t SigMask;
@@ -382,15 +382,15 @@ static RETSIGTYPE SignalHandler(int Sig) {
OneShotPipeSignalFunction.exchange(nullptr))
return OldOneShotPipeFunction();
- bool IsIntSig = llvm::is_contained(IntSigs, Sig);
- if (IsIntSig)
+ bool IsIntSig = llvm::is_contained(IntSigs, Sig);
+ if (IsIntSig)
if (auto OldInterruptFunction = InterruptFunction.exchange(nullptr))
return OldInterruptFunction();
- if (Sig == SIGPIPE || IsIntSig) {
- raise(Sig); // Execute the default handler.
+ if (Sig == SIGPIPE || IsIntSig) {
+ raise(Sig); // Execute the default handler.
return;
- }
+ }
}
// Otherwise if it is a fault (like SEGV) run any handler.
@@ -555,7 +555,7 @@ static int unwindBacktrace(void **StackTrace, int MaxEntries) {
//
// On glibc systems we have the 'backtrace' function, which works nicely, but
// doesn't demangle symbols.
-void llvm::sys::PrintStackTrace(raw_ostream &OS, int Depth) {
+void llvm::sys::PrintStackTrace(raw_ostream &OS, int Depth) {
#if ENABLE_BACKTRACES
static void *StackTrace[256];
int depth = 0;
@@ -572,15 +572,15 @@ void llvm::sys::PrintStackTrace(raw_ostream &OS, int Depth) {
#endif
if (!depth)
return;
- // If "Depth" is not provided by the caller, use the return value of
- // backtrace() for printing a symbolized stack trace.
- if (!Depth)
- Depth = depth;
- if (printSymbolizedStackTrace(Argv0, StackTrace, Depth, OS))
+ // If "Depth" is not provided by the caller, use the return value of
+ // backtrace() for printing a symbolized stack trace.
+ if (!Depth)
+ Depth = depth;
+ if (printSymbolizedStackTrace(Argv0, StackTrace, Depth, OS))
return;
- OS << "Stack dump without symbol names (ensure you have llvm-symbolizer in "
- "your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point "
- "to it):\n";
+ OS << "Stack dump without symbol names (ensure you have llvm-symbolizer in "
+ "your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point "
+ "to it):\n";
#if HAVE_DLFCN_H && HAVE_DLADDR
int width = 0;
for (int i = 0; i < depth; ++i) {
@@ -622,7 +622,7 @@ void llvm::sys::PrintStackTrace(raw_ostream &OS, int Depth) {
OS << '\n';
}
#elif defined(HAVE_BACKTRACE)
- backtrace_symbols_fd(StackTrace, Depth, STDERR_FILENO);
+ backtrace_symbols_fd(StackTrace, Depth, STDERR_FILENO);
#endif
#endif
}
diff --git a/contrib/libs/llvm12/lib/Support/Unix/Threading.inc b/contrib/libs/llvm12/lib/Support/Unix/Threading.inc
index 4e8c82dbac..a745495d6e 100644
--- a/contrib/libs/llvm12/lib/Support/Unix/Threading.inc
+++ b/contrib/libs/llvm12/lib/Support/Unix/Threading.inc
@@ -28,7 +28,7 @@
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <errno.h>
-#include <sys/cpuset.h>
+#include <sys/cpuset.h>
#include <sys/sysctl.h>
#include <sys/user.h>
#include <unistd.h>
@@ -283,13 +283,13 @@ SetThreadPriorityResult llvm::set_thread_priority(ThreadPriority Priority) {
#include <thread>
int computeHostNumHardwareThreads() {
-#if defined(__FreeBSD__)
- cpuset_t mask;
- CPU_ZERO(&mask);
- if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(mask),
- &mask) == 0)
- return CPU_COUNT(&mask);
-#elif defined(__linux__)
+#if defined(__FreeBSD__)
+ cpuset_t mask;
+ CPU_ZERO(&mask);
+ if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(mask),
+ &mask) == 0)
+ return CPU_COUNT(&mask);
+#elif defined(__linux__)
cpu_set_t Set;
if (sched_getaffinity(0, sizeof(Set), &Set) == 0)
return CPU_COUNT(&Set);
diff --git a/contrib/libs/llvm12/lib/Support/VirtualFileSystem.cpp b/contrib/libs/llvm12/lib/Support/VirtualFileSystem.cpp
index e725a868c7..c0ccadfce0 100644
--- a/contrib/libs/llvm12/lib/Support/VirtualFileSystem.cpp
+++ b/contrib/libs/llvm12/lib/Support/VirtualFileSystem.cpp
@@ -897,12 +897,12 @@ bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime,
}
bool InMemoryFileSystem::addFileNoOwn(const Twine &P, time_t ModificationTime,
- const llvm::MemoryBufferRef &Buffer,
+ const llvm::MemoryBufferRef &Buffer,
Optional<uint32_t> User,
Optional<uint32_t> Group,
Optional<llvm::sys::fs::file_type> Type,
Optional<llvm::sys::fs::perms> Perms) {
- return addFile(P, ModificationTime, llvm::MemoryBuffer::getMemBuffer(Buffer),
+ return addFile(P, ModificationTime, llvm::MemoryBuffer::getMemBuffer(Buffer),
std::move(User), std::move(Group), std::move(Type),
std::move(Perms));
}
@@ -1187,14 +1187,14 @@ RedirectingFileSystem::setCurrentWorkingDirectory(const Twine &Path) {
return {};
}
-std::error_code RedirectingFileSystem::isLocal(const Twine &Path_,
+std::error_code RedirectingFileSystem::isLocal(const Twine &Path_,
bool &Result) {
- SmallString<256> Path;
- Path_.toVector(Path);
-
- if (std::error_code EC = makeCanonical(Path))
- return {};
-
+ SmallString<256> Path;
+ Path_.toVector(Path);
+
+ if (std::error_code EC = makeCanonical(Path))
+ return {};
+
return ExternalFS->isLocal(Path, Result);
}
@@ -1229,21 +1229,21 @@ std::error_code RedirectingFileSystem::makeAbsolute(SmallVectorImpl<char> &Path)
directory_iterator RedirectingFileSystem::dir_begin(const Twine &Dir,
std::error_code &EC) {
- SmallString<256> Path;
- Dir.toVector(Path);
-
- EC = makeCanonical(Path);
- if (EC)
- return {};
-
- ErrorOr<RedirectingFileSystem::Entry *> E = lookupPath(Path);
+ SmallString<256> Path;
+ Dir.toVector(Path);
+
+ EC = makeCanonical(Path);
+ if (EC)
+ return {};
+
+ ErrorOr<RedirectingFileSystem::Entry *> E = lookupPath(Path);
if (!E) {
EC = E.getError();
if (shouldUseExternalFS() && EC == errc::no_such_file_or_directory)
- return ExternalFS->dir_begin(Path, EC);
+ return ExternalFS->dir_begin(Path, EC);
return {};
}
- ErrorOr<Status> S = status(Path, *E);
+ ErrorOr<Status> S = status(Path, *E);
if (!S) {
EC = S.getError();
return {};
@@ -1256,7 +1256,7 @@ directory_iterator RedirectingFileSystem::dir_begin(const Twine &Dir,
auto *D = cast<RedirectingFileSystem::RedirectingDirectoryEntry>(*E);
return directory_iterator(std::make_shared<VFSFromYamlDirIterImpl>(
- Path, D->contents_begin(), D->contents_end(),
+ Path, D->contents_begin(), D->contents_end(),
/*IterateExternalFS=*/shouldUseExternalFS(), *ExternalFS, EC));
}
@@ -1268,17 +1268,17 @@ StringRef RedirectingFileSystem::getExternalContentsPrefixDir() const {
return ExternalContentsPrefixDir;
}
-void RedirectingFileSystem::setFallthrough(bool Fallthrough) {
- IsFallthrough = Fallthrough;
-}
-
-std::vector<StringRef> RedirectingFileSystem::getRoots() const {
- std::vector<StringRef> R;
- for (const auto &Root : Roots)
- R.push_back(Root->getName());
- return R;
-}
-
+void RedirectingFileSystem::setFallthrough(bool Fallthrough) {
+ IsFallthrough = Fallthrough;
+}
+
+std::vector<StringRef> RedirectingFileSystem::getRoots() const {
+ std::vector<StringRef> R;
+ for (const auto &Root : Roots)
+ R.push_back(Root->getName());
+ return R;
+}
+
void RedirectingFileSystem::dump(raw_ostream &OS) const {
for (const auto &Root : Roots)
dumpEntry(OS, Root.get());
@@ -1383,8 +1383,8 @@ class llvm::vfs::RedirectingFileSystemParser {
return true;
}
-public:
- static RedirectingFileSystem::Entry *
+public:
+ static RedirectingFileSystem::Entry *
lookupOrCreateEntry(RedirectingFileSystem *FS, StringRef Name,
RedirectingFileSystem::Entry *ParentEntry = nullptr) {
if (!ParentEntry) { // Look for a existent root
@@ -1426,7 +1426,7 @@ public:
return DE->getLastContent();
}
-private:
+private:
void uniqueOverlayTree(RedirectingFileSystem *FS,
RedirectingFileSystem::Entry *SrcE,
RedirectingFileSystem::Entry *NewParentE = nullptr) {
@@ -1752,7 +1752,7 @@ public:
}
};
-std::unique_ptr<RedirectingFileSystem>
+std::unique_ptr<RedirectingFileSystem>
RedirectingFileSystem::create(std::unique_ptr<MemoryBuffer> Buffer,
SourceMgr::DiagHandlerTy DiagHandler,
StringRef YAMLFilePath, void *DiagContext,
@@ -1792,80 +1792,80 @@ RedirectingFileSystem::create(std::unique_ptr<MemoryBuffer> Buffer,
if (!P.parse(Root, FS.get()))
return nullptr;
- return FS;
-}
-
-std::unique_ptr<RedirectingFileSystem> RedirectingFileSystem::create(
- ArrayRef<std::pair<std::string, std::string>> RemappedFiles,
- bool UseExternalNames, FileSystem &ExternalFS) {
- std::unique_ptr<RedirectingFileSystem> FS(
- new RedirectingFileSystem(&ExternalFS));
- FS->UseExternalNames = UseExternalNames;
-
- StringMap<RedirectingFileSystem::Entry *> Entries;
-
- for (auto &Mapping : llvm::reverse(RemappedFiles)) {
- SmallString<128> From = StringRef(Mapping.first);
- SmallString<128> To = StringRef(Mapping.second);
- {
- auto EC = ExternalFS.makeAbsolute(From);
- (void)EC;
- assert(!EC && "Could not make absolute path");
- }
-
- // Check if we've already mapped this file. The first one we see (in the
- // reverse iteration) wins.
- RedirectingFileSystem::Entry *&ToEntry = Entries[From];
- if (ToEntry)
- continue;
-
- // Add parent directories.
- RedirectingFileSystem::Entry *Parent = nullptr;
- StringRef FromDirectory = llvm::sys::path::parent_path(From);
- for (auto I = llvm::sys::path::begin(FromDirectory),
- E = llvm::sys::path::end(FromDirectory);
- I != E; ++I) {
- Parent = RedirectingFileSystemParser::lookupOrCreateEntry(FS.get(), *I,
- Parent);
- }
- assert(Parent && "File without a directory?");
- {
- auto EC = ExternalFS.makeAbsolute(To);
- (void)EC;
- assert(!EC && "Could not make absolute path");
- }
-
- // Add the file.
- auto NewFile =
- std::make_unique<RedirectingFileSystem::RedirectingFileEntry>(
- llvm::sys::path::filename(From), To,
- UseExternalNames
- ? RedirectingFileSystem::RedirectingFileEntry::NK_External
- : RedirectingFileSystem::RedirectingFileEntry::NK_Virtual);
- ToEntry = NewFile.get();
- cast<RedirectingFileSystem::RedirectingDirectoryEntry>(Parent)->addContent(
- std::move(NewFile));
- }
-
- return FS;
-}
-
-std::error_code
-RedirectingFileSystem::makeCanonical(SmallVectorImpl<char> &Path) const {
+ return FS;
+}
+
+std::unique_ptr<RedirectingFileSystem> RedirectingFileSystem::create(
+ ArrayRef<std::pair<std::string, std::string>> RemappedFiles,
+ bool UseExternalNames, FileSystem &ExternalFS) {
+ std::unique_ptr<RedirectingFileSystem> FS(
+ new RedirectingFileSystem(&ExternalFS));
+ FS->UseExternalNames = UseExternalNames;
+
+ StringMap<RedirectingFileSystem::Entry *> Entries;
+
+ for (auto &Mapping : llvm::reverse(RemappedFiles)) {
+ SmallString<128> From = StringRef(Mapping.first);
+ SmallString<128> To = StringRef(Mapping.second);
+ {
+ auto EC = ExternalFS.makeAbsolute(From);
+ (void)EC;
+ assert(!EC && "Could not make absolute path");
+ }
+
+ // Check if we've already mapped this file. The first one we see (in the
+ // reverse iteration) wins.
+ RedirectingFileSystem::Entry *&ToEntry = Entries[From];
+ if (ToEntry)
+ continue;
+
+ // Add parent directories.
+ RedirectingFileSystem::Entry *Parent = nullptr;
+ StringRef FromDirectory = llvm::sys::path::parent_path(From);
+ for (auto I = llvm::sys::path::begin(FromDirectory),
+ E = llvm::sys::path::end(FromDirectory);
+ I != E; ++I) {
+ Parent = RedirectingFileSystemParser::lookupOrCreateEntry(FS.get(), *I,
+ Parent);
+ }
+ assert(Parent && "File without a directory?");
+ {
+ auto EC = ExternalFS.makeAbsolute(To);
+ (void)EC;
+ assert(!EC && "Could not make absolute path");
+ }
+
+ // Add the file.
+ auto NewFile =
+ std::make_unique<RedirectingFileSystem::RedirectingFileEntry>(
+ llvm::sys::path::filename(From), To,
+ UseExternalNames
+ ? RedirectingFileSystem::RedirectingFileEntry::NK_External
+ : RedirectingFileSystem::RedirectingFileEntry::NK_Virtual);
+ ToEntry = NewFile.get();
+ cast<RedirectingFileSystem::RedirectingDirectoryEntry>(Parent)->addContent(
+ std::move(NewFile));
+ }
+
+ return FS;
+}
+
+std::error_code
+RedirectingFileSystem::makeCanonical(SmallVectorImpl<char> &Path) const {
if (std::error_code EC = makeAbsolute(Path))
return EC;
- llvm::SmallString<256> CanonicalPath =
- canonicalize(StringRef(Path.data(), Path.size()));
- if (CanonicalPath.empty())
+ llvm::SmallString<256> CanonicalPath =
+ canonicalize(StringRef(Path.data(), Path.size()));
+ if (CanonicalPath.empty())
return make_error_code(llvm::errc::invalid_argument);
- Path.assign(CanonicalPath.begin(), CanonicalPath.end());
- return {};
-}
-
-ErrorOr<RedirectingFileSystem::Entry *>
-RedirectingFileSystem::lookupPath(StringRef Path) const {
+ Path.assign(CanonicalPath.begin(), CanonicalPath.end());
+ return {};
+}
+
+ErrorOr<RedirectingFileSystem::Entry *>
+RedirectingFileSystem::lookupPath(StringRef Path) const {
sys::path::const_iterator Start = sys::path::begin(Path);
sys::path::const_iterator End = sys::path::end(Path);
for (const auto &Root : Roots) {
@@ -1940,13 +1940,13 @@ ErrorOr<Status> RedirectingFileSystem::status(const Twine &Path,
}
}
-ErrorOr<Status> RedirectingFileSystem::status(const Twine &Path_) {
- SmallString<256> Path;
- Path_.toVector(Path);
-
- if (std::error_code EC = makeCanonical(Path))
- return EC;
-
+ErrorOr<Status> RedirectingFileSystem::status(const Twine &Path_) {
+ SmallString<256> Path;
+ Path_.toVector(Path);
+
+ if (std::error_code EC = makeCanonical(Path))
+ return EC;
+
ErrorOr<RedirectingFileSystem::Entry *> Result = lookupPath(Path);
if (!Result) {
if (shouldUseExternalFS() &&
@@ -1984,13 +1984,13 @@ public:
} // namespace
ErrorOr<std::unique_ptr<File>>
-RedirectingFileSystem::openFileForRead(const Twine &Path_) {
- SmallString<256> Path;
- Path_.toVector(Path);
-
- if (std::error_code EC = makeCanonical(Path))
- return EC;
-
+RedirectingFileSystem::openFileForRead(const Twine &Path_) {
+ SmallString<256> Path;
+ Path_.toVector(Path);
+
+ if (std::error_code EC = makeCanonical(Path))
+ return EC;
+
ErrorOr<RedirectingFileSystem::Entry *> E = lookupPath(Path);
if (!E) {
if (shouldUseExternalFS() &&
@@ -2020,14 +2020,14 @@ RedirectingFileSystem::openFileForRead(const Twine &Path_) {
}
std::error_code
-RedirectingFileSystem::getRealPath(const Twine &Path_,
+RedirectingFileSystem::getRealPath(const Twine &Path_,
SmallVectorImpl<char> &Output) const {
- SmallString<256> Path;
- Path_.toVector(Path);
-
- if (std::error_code EC = makeCanonical(Path))
- return EC;
-
+ SmallString<256> Path;
+ Path_.toVector(Path);
+
+ if (std::error_code EC = makeCanonical(Path))
+ return EC;
+
ErrorOr<RedirectingFileSystem::Entry *> Result = lookupPath(Path);
if (!Result) {
if (shouldUseExternalFS() &&
@@ -2047,7 +2047,7 @@ RedirectingFileSystem::getRealPath(const Twine &Path_,
: llvm::errc::invalid_argument;
}
-std::unique_ptr<FileSystem>
+std::unique_ptr<FileSystem>
vfs::getVFSFromYAML(std::unique_ptr<MemoryBuffer> Buffer,
SourceMgr::DiagHandlerTy DiagHandler,
StringRef YAMLFilePath, void *DiagContext,
@@ -2088,7 +2088,7 @@ void vfs::collectVFSFromYAML(std::unique_ptr<MemoryBuffer> Buffer,
SmallVectorImpl<YAMLVFSEntry> &CollectedEntries,
void *DiagContext,
IntrusiveRefCntPtr<FileSystem> ExternalFS) {
- std::unique_ptr<RedirectingFileSystem> VFS = RedirectingFileSystem::create(
+ std::unique_ptr<RedirectingFileSystem> VFS = RedirectingFileSystem::create(
std::move(Buffer), DiagHandler, YAMLFilePath, DiagContext,
std::move(ExternalFS));
ErrorOr<RedirectingFileSystem::Entry *> RootE = VFS->lookupPath("/");
diff --git a/contrib/libs/llvm12/lib/Support/Windows/Path.inc b/contrib/libs/llvm12/lib/Support/Windows/Path.inc
index 8155050d47..adcbd1b5f8 100644
--- a/contrib/libs/llvm12/lib/Support/Windows/Path.inc
+++ b/contrib/libs/llvm12/lib/Support/Windows/Path.inc
@@ -402,22 +402,22 @@ std::error_code is_local(int FD, bool &Result) {
}
static std::error_code setDeleteDisposition(HANDLE Handle, bool Delete) {
- // Clear the FILE_DISPOSITION_INFO flag first, before checking if it's a
- // network file. On Windows 7 the function realPathFromHandle() below fails
- // if the FILE_DISPOSITION_INFO flag was already set to 'DeleteFile = true' by
- // a prior call.
- FILE_DISPOSITION_INFO Disposition;
- Disposition.DeleteFile = false;
- if (!SetFileInformationByHandle(Handle, FileDispositionInfo, &Disposition,
- sizeof(Disposition)))
- return mapWindowsError(::GetLastError());
- if (!Delete)
- return std::error_code();
-
- // Check if the file is on a network (non-local) drive. If so, don't
- // continue when DeleteFile is true, since it prevents opening the file for
- // writes. Note -- this will leak temporary files on disk, but only when the
- // target file is on a network drive.
+ // Clear the FILE_DISPOSITION_INFO flag first, before checking if it's a
+ // network file. On Windows 7 the function realPathFromHandle() below fails
+ // if the FILE_DISPOSITION_INFO flag was already set to 'DeleteFile = true' by
+ // a prior call.
+ FILE_DISPOSITION_INFO Disposition;
+ Disposition.DeleteFile = false;
+ if (!SetFileInformationByHandle(Handle, FileDispositionInfo, &Disposition,
+ sizeof(Disposition)))
+ return mapWindowsError(::GetLastError());
+ if (!Delete)
+ return std::error_code();
+
+ // Check if the file is on a network (non-local) drive. If so, don't
+ // continue when DeleteFile is true, since it prevents opening the file for
+ // writes. Note -- this will leak temporary files on disk, but only when the
+ // target file is on a network drive.
SmallVector<wchar_t, 128> FinalPath;
if (std::error_code EC = realPathFromHandle(Handle, FinalPath))
return EC;
@@ -429,9 +429,9 @@ static std::error_code setDeleteDisposition(HANDLE Handle, bool Delete) {
if (!IsLocal)
return std::error_code();
- // The file is on a local drive, we can safely set FILE_DISPOSITION_INFO's
- // flag.
- Disposition.DeleteFile = true;
+ // The file is on a local drive, we can safely set FILE_DISPOSITION_INFO's
+ // flag.
+ Disposition.DeleteFile = true;
if (!SetFileInformationByHandle(Handle, FileDispositionInfo, &Disposition,
sizeof(Disposition)))
return mapWindowsError(::GetLastError());
@@ -1287,43 +1287,43 @@ Expected<size_t> readNativeFileSlice(file_t FileHandle,
return readNativeFileImpl(FileHandle, Buf, &Overlapped);
}
-std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout) {
- DWORD Flags = LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY;
- OVERLAPPED OV = {};
- file_t File = convertFDToNativeFile(FD);
- auto Start = std::chrono::steady_clock::now();
- auto End = Start + Timeout;
- do {
- if (::LockFileEx(File, Flags, 0, MAXDWORD, MAXDWORD, &OV))
- return std::error_code();
- DWORD Error = ::GetLastError();
- if (Error == ERROR_LOCK_VIOLATION) {
- ::Sleep(1);
- continue;
- }
- return mapWindowsError(Error);
- } while (std::chrono::steady_clock::now() < End);
- return mapWindowsError(ERROR_LOCK_VIOLATION);
-}
-
-std::error_code lockFile(int FD) {
- DWORD Flags = LOCKFILE_EXCLUSIVE_LOCK;
- OVERLAPPED OV = {};
- file_t File = convertFDToNativeFile(FD);
- if (::LockFileEx(File, Flags, 0, MAXDWORD, MAXDWORD, &OV))
- return std::error_code();
- DWORD Error = ::GetLastError();
- return mapWindowsError(Error);
-}
-
-std::error_code unlockFile(int FD) {
- OVERLAPPED OV = {};
- file_t File = convertFDToNativeFile(FD);
- if (::UnlockFileEx(File, 0, MAXDWORD, MAXDWORD, &OV))
- return std::error_code();
- return mapWindowsError(::GetLastError());
-}
-
+std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout) {
+ DWORD Flags = LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY;
+ OVERLAPPED OV = {};
+ file_t File = convertFDToNativeFile(FD);
+ auto Start = std::chrono::steady_clock::now();
+ auto End = Start + Timeout;
+ do {
+ if (::LockFileEx(File, Flags, 0, MAXDWORD, MAXDWORD, &OV))
+ return std::error_code();
+ DWORD Error = ::GetLastError();
+ if (Error == ERROR_LOCK_VIOLATION) {
+ ::Sleep(1);
+ continue;
+ }
+ return mapWindowsError(Error);
+ } while (std::chrono::steady_clock::now() < End);
+ return mapWindowsError(ERROR_LOCK_VIOLATION);
+}
+
+std::error_code lockFile(int FD) {
+ DWORD Flags = LOCKFILE_EXCLUSIVE_LOCK;
+ OVERLAPPED OV = {};
+ file_t File = convertFDToNativeFile(FD);
+ if (::LockFileEx(File, Flags, 0, MAXDWORD, MAXDWORD, &OV))
+ return std::error_code();
+ DWORD Error = ::GetLastError();
+ return mapWindowsError(Error);
+}
+
+std::error_code unlockFile(int FD) {
+ OVERLAPPED OV = {};
+ file_t File = convertFDToNativeFile(FD);
+ if (::UnlockFileEx(File, 0, MAXDWORD, MAXDWORD, &OV))
+ return std::error_code();
+ return mapWindowsError(::GetLastError());
+}
+
std::error_code closeFile(file_t &F) {
file_t TmpF = F;
F = kInvalidFile;
diff --git a/contrib/libs/llvm12/lib/Support/Windows/Process.inc b/contrib/libs/llvm12/lib/Support/Windows/Process.inc
index 38ba20bd91..910d2395d2 100644
--- a/contrib/libs/llvm12/lib/Support/Windows/Process.inc
+++ b/contrib/libs/llvm12/lib/Support/Windows/Process.inc
@@ -228,8 +228,8 @@ static std::error_code GetExecutableName(SmallVectorImpl<char> &Filename) {
if (EC)
return EC;
- // Make a copy of the filename since assign makes the StringRef invalid.
- std::string Base = sys::path::filename(Filename.data()).str();
+ // Make a copy of the filename since assign makes the StringRef invalid.
+ std::string Base = sys::path::filename(Filename.data()).str();
Filename.assign(Base.begin(), Base.end());
return std::error_code();
}
diff --git a/contrib/libs/llvm12/lib/Support/Windows/Program.inc b/contrib/libs/llvm12/lib/Support/Windows/Program.inc
index e3c07e9da9..f1d612cf3c 100644
--- a/contrib/libs/llvm12/lib/Support/Windows/Program.inc
+++ b/contrib/libs/llvm12/lib/Support/Windows/Program.inc
@@ -171,8 +171,8 @@ static HANDLE RedirectIO(Optional<StringRef> Path, int fd,
static bool Execute(ProcessInfo &PI, StringRef Program,
ArrayRef<StringRef> Args, Optional<ArrayRef<StringRef>> Env,
ArrayRef<Optional<StringRef>> Redirects,
- unsigned MemoryLimit, std::string *ErrMsg,
- BitVector *AffinityMask) {
+ unsigned MemoryLimit, std::string *ErrMsg,
+ BitVector *AffinityMask) {
if (!sys::fs::can_execute(Program)) {
if (ErrMsg)
*ErrMsg = "program not executable";
@@ -190,13 +190,13 @@ static bool Execute(ProcessInfo &PI, StringRef Program,
// Windows wants a command line, not an array of args, to pass to the new
// process. We have to concatenate them all, while quoting the args that
// have embedded spaces (or are empty).
- auto Result = flattenWindowsCommandLine(Args);
- if (std::error_code ec = Result.getError()) {
- SetLastError(ec.value());
- MakeErrMsg(ErrMsg, std::string("Unable to convert command-line to UTF-16"));
- return false;
- }
- std::wstring Command = *Result;
+ auto Result = flattenWindowsCommandLine(Args);
+ if (std::error_code ec = Result.getError()) {
+ SetLastError(ec.value());
+ MakeErrMsg(ErrMsg, std::string("Unable to convert command-line to UTF-16"));
+ return false;
+ }
+ std::wstring Command = *Result;
// The pointer to the environment block for the new process.
std::vector<wchar_t> EnvBlock;
@@ -213,7 +213,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program,
return false;
}
- llvm::append_range(EnvBlock, EnvString);
+ llvm::append_range(EnvBlock, EnvString);
EnvBlock.push_back(0);
}
EnvBlock.push_back(0);
@@ -278,15 +278,15 @@ static bool Execute(ProcessInfo &PI, StringRef Program,
return false;
}
- unsigned CreateFlags = CREATE_UNICODE_ENVIRONMENT;
- if (AffinityMask)
- CreateFlags |= CREATE_SUSPENDED;
+ unsigned CreateFlags = CREATE_UNICODE_ENVIRONMENT;
+ if (AffinityMask)
+ CreateFlags |= CREATE_SUSPENDED;
- std::vector<wchar_t> CommandUtf16(Command.size() + 1, 0);
- std::copy(Command.begin(), Command.end(), CommandUtf16.begin());
- BOOL rc = CreateProcessW(ProgramUtf16.data(), CommandUtf16.data(), 0, 0, TRUE,
- CreateFlags, EnvBlock.empty() ? 0 : EnvBlock.data(),
- 0, &si, &pi);
+ std::vector<wchar_t> CommandUtf16(Command.size() + 1, 0);
+ std::copy(Command.begin(), Command.end(), CommandUtf16.begin());
+ BOOL rc = CreateProcessW(ProgramUtf16.data(), CommandUtf16.data(), 0, 0, TRUE,
+ CreateFlags, EnvBlock.empty() ? 0 : EnvBlock.data(),
+ 0, &si, &pi);
DWORD err = GetLastError();
// Regardless of whether the process got created or not, we are done with
@@ -334,13 +334,13 @@ static bool Execute(ProcessInfo &PI, StringRef Program,
}
}
- // Set the affinity mask
- if (AffinityMask) {
- ::SetProcessAffinityMask(pi.hProcess,
- (DWORD_PTR)AffinityMask->getData().front());
- ::ResumeThread(pi.hThread);
- }
-
+ // Set the affinity mask
+ if (AffinityMask) {
+ ::SetProcessAffinityMask(pi.hProcess,
+ (DWORD_PTR)AffinityMask->getData().front());
+ ::ResumeThread(pi.hThread);
+ }
+
return true;
}
@@ -387,7 +387,7 @@ static std::string quoteSingleArg(StringRef Arg) {
}
namespace llvm {
-ErrorOr<std::wstring> sys::flattenWindowsCommandLine(ArrayRef<StringRef> Args) {
+ErrorOr<std::wstring> sys::flattenWindowsCommandLine(ArrayRef<StringRef> Args) {
std::string Command;
for (StringRef Arg : Args) {
if (argNeedsQuotes(Arg))
@@ -398,11 +398,11 @@ ErrorOr<std::wstring> sys::flattenWindowsCommandLine(ArrayRef<StringRef> Args) {
Command.push_back(' ');
}
- SmallVector<wchar_t, MAX_PATH> CommandUtf16;
- if (std::error_code ec = windows::UTF8ToUTF16(Command, CommandUtf16))
- return ec;
-
- return std::wstring(CommandUtf16.begin(), CommandUtf16.end());
+ SmallVector<wchar_t, MAX_PATH> CommandUtf16;
+ if (std::error_code ec = windows::UTF8ToUTF16(Command, CommandUtf16))
+ return ec;
+
+ return std::wstring(CommandUtf16.begin(), CommandUtf16.end());
}
ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
@@ -547,16 +547,16 @@ llvm::sys::writeFileWithEncoding(StringRef FileName, StringRef Contents,
bool llvm::sys::commandLineFitsWithinSystemLimits(StringRef Program,
ArrayRef<StringRef> Args) {
- // The documentation on CreateProcessW states that the size of the argument
- // lpCommandLine must not be greater than 32767 characters, including the
- // Unicode terminating null character. We use smaller value to reduce risk
- // of getting invalid command line due to unaccounted factors.
- static const size_t MaxCommandStringLength = 32000;
+ // The documentation on CreateProcessW states that the size of the argument
+ // lpCommandLine must not be greater than 32767 characters, including the
+ // Unicode terminating null character. We use smaller value to reduce risk
+ // of getting invalid command line due to unaccounted factors.
+ static const size_t MaxCommandStringLength = 32000;
SmallVector<StringRef, 8> FullArgs;
FullArgs.push_back(Program);
FullArgs.append(Args.begin(), Args.end());
- auto Result = flattenWindowsCommandLine(FullArgs);
- assert(!Result.getError());
- return (Result->size() + 1) <= MaxCommandStringLength;
+ auto Result = flattenWindowsCommandLine(FullArgs);
+ assert(!Result.getError());
+ return (Result->size() + 1) <= MaxCommandStringLength;
}
}
diff --git a/contrib/libs/llvm12/lib/Support/Windows/Signals.inc b/contrib/libs/llvm12/lib/Support/Windows/Signals.inc
index f97e42a6df..3758582b35 100644
--- a/contrib/libs/llvm12/lib/Support/Windows/Signals.inc
+++ b/contrib/libs/llvm12/lib/Support/Windows/Signals.inc
@@ -552,8 +552,8 @@ static void LocalPrintStackTrace(raw_ostream &OS, PCONTEXT C) {
StackFrame, C);
}
-void llvm::sys::PrintStackTrace(raw_ostream &OS, int Depth) {
- // FIXME: Handle "Depth" parameter to print stack trace upto specified Depth
+void llvm::sys::PrintStackTrace(raw_ostream &OS, int Depth) {
+ // FIXME: Handle "Depth" parameter to print stack trace upto specified Depth
LocalPrintStackTrace(OS, nullptr);
}
@@ -869,5 +869,5 @@ static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType) {
#pragma GCC diagnostic warning "-Wformat"
#pragma GCC diagnostic warning "-Wformat-extra-args"
#endif
-
-void sys::unregisterHandlers() {}
+
+void sys::unregisterHandlers() {}
diff --git a/contrib/libs/llvm12/lib/Support/Windows/Threading.inc b/contrib/libs/llvm12/lib/Support/Windows/Threading.inc
index d96f3ded72..6448bb478d 100644
--- a/contrib/libs/llvm12/lib/Support/Windows/Threading.inc
+++ b/contrib/libs/llvm12/lib/Support/Windows/Threading.inc
@@ -195,25 +195,25 @@ static ArrayRef<ProcessorGroup> getProcessorGroups() {
if (!IterateProcInfo(RelationProcessorCore, HandleProc))
return std::vector<ProcessorGroup>();
- // If there's an affinity mask set, assume the user wants to constrain the
- // current process to only a single CPU group. On Windows, it is not
- // possible for affinity masks to cross CPU group boundaries.
- DWORD_PTR ProcessAffinityMask = 0, SystemAffinityMask = 0;
- if (::GetProcessAffinityMask(GetCurrentProcess(), &ProcessAffinityMask,
- &SystemAffinityMask) &&
- ProcessAffinityMask != SystemAffinityMask) {
- // We don't expect more that 4 CPU groups on Windows (256 processors).
- USHORT GroupCount = 4;
- USHORT GroupArray[4]{};
- if (::GetProcessGroupAffinity(GetCurrentProcess(), &GroupCount,
- GroupArray)) {
- assert(GroupCount == 1 &&
- "On startup, a program is expected to be assigned only to "
- "one processor group!");
- unsigned CurrentGroupID = GroupArray[0];
- ProcessorGroup NewG{Groups[CurrentGroupID]};
- NewG.Affinity = ProcessAffinityMask;
- NewG.UsableThreads = countPopulation(ProcessAffinityMask);
+ // If there's an affinity mask set, assume the user wants to constrain the
+ // current process to only a single CPU group. On Windows, it is not
+ // possible for affinity masks to cross CPU group boundaries.
+ DWORD_PTR ProcessAffinityMask = 0, SystemAffinityMask = 0;
+ if (::GetProcessAffinityMask(GetCurrentProcess(), &ProcessAffinityMask,
+ &SystemAffinityMask) &&
+ ProcessAffinityMask != SystemAffinityMask) {
+ // We don't expect more that 4 CPU groups on Windows (256 processors).
+ USHORT GroupCount = 4;
+ USHORT GroupArray[4]{};
+ if (::GetProcessGroupAffinity(GetCurrentProcess(), &GroupCount,
+ GroupArray)) {
+ assert(GroupCount == 1 &&
+ "On startup, a program is expected to be assigned only to "
+ "one processor group!");
+ unsigned CurrentGroupID = GroupArray[0];
+ ProcessorGroup NewG{Groups[CurrentGroupID]};
+ NewG.Affinity = ProcessAffinityMask;
+ NewG.UsableThreads = countPopulation(ProcessAffinityMask);
Groups.clear();
Groups.push_back(NewG);
}
diff --git a/contrib/libs/llvm12/lib/Support/X86TargetParser.cpp b/contrib/libs/llvm12/lib/Support/X86TargetParser.cpp
index b4772bb7a4..d738511465 100644
--- a/contrib/libs/llvm12/lib/Support/X86TargetParser.cpp
+++ b/contrib/libs/llvm12/lib/Support/X86TargetParser.cpp
@@ -116,160 +116,160 @@ struct FeatureInfo {
} // end anonymous namespace
#define X86_FEATURE(ENUM, STRING) \
- constexpr FeatureBitset Feature##ENUM = {X86::FEATURE_##ENUM};
+ constexpr FeatureBitset Feature##ENUM = {X86::FEATURE_##ENUM};
#include "llvm/Support/X86TargetParser.def"
// Pentium with MMX.
-constexpr FeatureBitset FeaturesPentiumMMX =
+constexpr FeatureBitset FeaturesPentiumMMX =
FeatureX87 | FeatureCMPXCHG8B | FeatureMMX;
// Pentium 2 and 3.
-constexpr FeatureBitset FeaturesPentium2 =
+constexpr FeatureBitset FeaturesPentium2 =
FeatureX87 | FeatureCMPXCHG8B | FeatureMMX | FeatureFXSR;
-constexpr FeatureBitset FeaturesPentium3 = FeaturesPentium2 | FeatureSSE;
+constexpr FeatureBitset FeaturesPentium3 = FeaturesPentium2 | FeatureSSE;
// Pentium 4 CPUs
-constexpr FeatureBitset FeaturesPentium4 = FeaturesPentium3 | FeatureSSE2;
-constexpr FeatureBitset FeaturesPrescott = FeaturesPentium4 | FeatureSSE3;
-constexpr FeatureBitset FeaturesNocona =
+constexpr FeatureBitset FeaturesPentium4 = FeaturesPentium3 | FeatureSSE2;
+constexpr FeatureBitset FeaturesPrescott = FeaturesPentium4 | FeatureSSE3;
+constexpr FeatureBitset FeaturesNocona =
FeaturesPrescott | Feature64BIT | FeatureCMPXCHG16B;
// Basic 64-bit capable CPU.
-constexpr FeatureBitset FeaturesX86_64 = FeaturesPentium4 | Feature64BIT;
-constexpr FeatureBitset FeaturesX86_64_V2 = FeaturesX86_64 | FeatureSAHF |
- FeaturePOPCNT | FeatureSSE4_2 |
- FeatureCMPXCHG16B;
-constexpr FeatureBitset FeaturesX86_64_V3 =
- FeaturesX86_64_V2 | FeatureAVX2 | FeatureBMI | FeatureBMI2 | FeatureF16C |
- FeatureFMA | FeatureLZCNT | FeatureMOVBE | FeatureXSAVE;
-constexpr FeatureBitset FeaturesX86_64_V4 = FeaturesX86_64_V3 |
- FeatureAVX512BW | FeatureAVX512CD |
- FeatureAVX512DQ | FeatureAVX512VL;
+constexpr FeatureBitset FeaturesX86_64 = FeaturesPentium4 | Feature64BIT;
+constexpr FeatureBitset FeaturesX86_64_V2 = FeaturesX86_64 | FeatureSAHF |
+ FeaturePOPCNT | FeatureSSE4_2 |
+ FeatureCMPXCHG16B;
+constexpr FeatureBitset FeaturesX86_64_V3 =
+ FeaturesX86_64_V2 | FeatureAVX2 | FeatureBMI | FeatureBMI2 | FeatureF16C |
+ FeatureFMA | FeatureLZCNT | FeatureMOVBE | FeatureXSAVE;
+constexpr FeatureBitset FeaturesX86_64_V4 = FeaturesX86_64_V3 |
+ FeatureAVX512BW | FeatureAVX512CD |
+ FeatureAVX512DQ | FeatureAVX512VL;
// Intel Core CPUs
-constexpr FeatureBitset FeaturesCore2 =
+constexpr FeatureBitset FeaturesCore2 =
FeaturesNocona | FeatureSAHF | FeatureSSSE3;
-constexpr FeatureBitset FeaturesPenryn = FeaturesCore2 | FeatureSSE4_1;
-constexpr FeatureBitset FeaturesNehalem =
+constexpr FeatureBitset FeaturesPenryn = FeaturesCore2 | FeatureSSE4_1;
+constexpr FeatureBitset FeaturesNehalem =
FeaturesPenryn | FeaturePOPCNT | FeatureSSE4_2;
-constexpr FeatureBitset FeaturesWestmere = FeaturesNehalem | FeaturePCLMUL;
-constexpr FeatureBitset FeaturesSandyBridge =
+constexpr FeatureBitset FeaturesWestmere = FeaturesNehalem | FeaturePCLMUL;
+constexpr FeatureBitset FeaturesSandyBridge =
FeaturesWestmere | FeatureAVX | FeatureXSAVE | FeatureXSAVEOPT;
-constexpr FeatureBitset FeaturesIvyBridge =
+constexpr FeatureBitset FeaturesIvyBridge =
FeaturesSandyBridge | FeatureF16C | FeatureFSGSBASE | FeatureRDRND;
-constexpr FeatureBitset FeaturesHaswell =
+constexpr FeatureBitset FeaturesHaswell =
FeaturesIvyBridge | FeatureAVX2 | FeatureBMI | FeatureBMI2 | FeatureFMA |
FeatureINVPCID | FeatureLZCNT | FeatureMOVBE;
-constexpr FeatureBitset FeaturesBroadwell =
+constexpr FeatureBitset FeaturesBroadwell =
FeaturesHaswell | FeatureADX | FeaturePRFCHW | FeatureRDSEED;
// Intel Knights Landing and Knights Mill
// Knights Landing has feature parity with Broadwell.
-constexpr FeatureBitset FeaturesKNL =
+constexpr FeatureBitset FeaturesKNL =
FeaturesBroadwell | FeatureAES | FeatureAVX512F | FeatureAVX512CD |
FeatureAVX512ER | FeatureAVX512PF | FeaturePREFETCHWT1;
-constexpr FeatureBitset FeaturesKNM = FeaturesKNL | FeatureAVX512VPOPCNTDQ;
+constexpr FeatureBitset FeaturesKNM = FeaturesKNL | FeatureAVX512VPOPCNTDQ;
// Intel Skylake processors.
-constexpr FeatureBitset FeaturesSkylakeClient =
+constexpr FeatureBitset FeaturesSkylakeClient =
FeaturesBroadwell | FeatureAES | FeatureCLFLUSHOPT | FeatureXSAVEC |
FeatureXSAVES | FeatureSGX;
// SkylakeServer inherits all SkylakeClient features except SGX.
// FIXME: That doesn't match gcc.
-constexpr FeatureBitset FeaturesSkylakeServer =
+constexpr FeatureBitset FeaturesSkylakeServer =
(FeaturesSkylakeClient & ~FeatureSGX) | FeatureAVX512F | FeatureAVX512CD |
FeatureAVX512DQ | FeatureAVX512BW | FeatureAVX512VL | FeatureCLWB |
FeaturePKU;
-constexpr FeatureBitset FeaturesCascadeLake =
+constexpr FeatureBitset FeaturesCascadeLake =
FeaturesSkylakeServer | FeatureAVX512VNNI;
-constexpr FeatureBitset FeaturesCooperLake =
+constexpr FeatureBitset FeaturesCooperLake =
FeaturesCascadeLake | FeatureAVX512BF16;
// Intel 10nm processors.
-constexpr FeatureBitset FeaturesCannonlake =
+constexpr FeatureBitset FeaturesCannonlake =
FeaturesSkylakeClient | FeatureAVX512F | FeatureAVX512CD | FeatureAVX512DQ |
FeatureAVX512BW | FeatureAVX512VL | FeatureAVX512IFMA | FeatureAVX512VBMI |
FeaturePKU | FeatureSHA;
-constexpr FeatureBitset FeaturesICLClient =
+constexpr FeatureBitset FeaturesICLClient =
FeaturesCannonlake | FeatureAVX512BITALG | FeatureAVX512VBMI2 |
FeatureAVX512VNNI | FeatureAVX512VPOPCNTDQ | FeatureCLWB | FeatureGFNI |
FeatureRDPID | FeatureVAES | FeatureVPCLMULQDQ;
-constexpr FeatureBitset FeaturesICLServer =
+constexpr FeatureBitset FeaturesICLServer =
FeaturesICLClient | FeaturePCONFIG | FeatureWBNOINVD;
-constexpr FeatureBitset FeaturesTigerlake =
+constexpr FeatureBitset FeaturesTigerlake =
FeaturesICLClient | FeatureAVX512VP2INTERSECT | FeatureMOVDIR64B |
- FeatureMOVDIRI | FeatureSHSTK | FeatureKL | FeatureWIDEKL;
-constexpr FeatureBitset FeaturesSapphireRapids =
- FeaturesICLServer | FeatureAMX_TILE | FeatureAMX_INT8 | FeatureAMX_BF16 |
- FeatureAVX512BF16 | FeatureAVX512VP2INTERSECT | FeatureCLDEMOTE |
- FeatureENQCMD | FeatureMOVDIR64B | FeatureMOVDIRI | FeaturePTWRITE |
- FeatureSERIALIZE | FeatureSHSTK | FeatureTSXLDTRK | FeatureUINTR |
- FeatureWAITPKG | FeatureAVXVNNI;
-constexpr FeatureBitset FeaturesAlderlake =
- FeaturesSkylakeClient | FeatureCLDEMOTE | FeatureHRESET | FeaturePTWRITE |
- FeatureSERIALIZE | FeatureWAITPKG | FeatureAVXVNNI;
+ FeatureMOVDIRI | FeatureSHSTK | FeatureKL | FeatureWIDEKL;
+constexpr FeatureBitset FeaturesSapphireRapids =
+ FeaturesICLServer | FeatureAMX_TILE | FeatureAMX_INT8 | FeatureAMX_BF16 |
+ FeatureAVX512BF16 | FeatureAVX512VP2INTERSECT | FeatureCLDEMOTE |
+ FeatureENQCMD | FeatureMOVDIR64B | FeatureMOVDIRI | FeaturePTWRITE |
+ FeatureSERIALIZE | FeatureSHSTK | FeatureTSXLDTRK | FeatureUINTR |
+ FeatureWAITPKG | FeatureAVXVNNI;
+constexpr FeatureBitset FeaturesAlderlake =
+ FeaturesSkylakeClient | FeatureCLDEMOTE | FeatureHRESET | FeaturePTWRITE |
+ FeatureSERIALIZE | FeatureWAITPKG | FeatureAVXVNNI;
// Intel Atom processors.
// Bonnell has feature parity with Core2 and adds MOVBE.
-constexpr FeatureBitset FeaturesBonnell = FeaturesCore2 | FeatureMOVBE;
+constexpr FeatureBitset FeaturesBonnell = FeaturesCore2 | FeatureMOVBE;
// Silvermont has parity with Westmere and Bonnell plus PRFCHW and RDRND.
-constexpr FeatureBitset FeaturesSilvermont =
+constexpr FeatureBitset FeaturesSilvermont =
FeaturesBonnell | FeaturesWestmere | FeaturePRFCHW | FeatureRDRND;
-constexpr FeatureBitset FeaturesGoldmont =
+constexpr FeatureBitset FeaturesGoldmont =
FeaturesSilvermont | FeatureAES | FeatureCLFLUSHOPT | FeatureFSGSBASE |
FeatureRDSEED | FeatureSHA | FeatureXSAVE | FeatureXSAVEC |
FeatureXSAVEOPT | FeatureXSAVES;
-constexpr FeatureBitset FeaturesGoldmontPlus =
+constexpr FeatureBitset FeaturesGoldmontPlus =
FeaturesGoldmont | FeaturePTWRITE | FeatureRDPID | FeatureSGX;
-constexpr FeatureBitset FeaturesTremont =
+constexpr FeatureBitset FeaturesTremont =
FeaturesGoldmontPlus | FeatureCLWB | FeatureGFNI;
// Geode Processor.
-constexpr FeatureBitset FeaturesGeode =
+constexpr FeatureBitset FeaturesGeode =
FeatureX87 | FeatureCMPXCHG8B | FeatureMMX | Feature3DNOW | Feature3DNOWA;
// K6 processor.
-constexpr FeatureBitset FeaturesK6 = FeatureX87 | FeatureCMPXCHG8B | FeatureMMX;
+constexpr FeatureBitset FeaturesK6 = FeatureX87 | FeatureCMPXCHG8B | FeatureMMX;
// K7 and K8 architecture processors.
-constexpr FeatureBitset FeaturesAthlon =
+constexpr FeatureBitset FeaturesAthlon =
FeatureX87 | FeatureCMPXCHG8B | FeatureMMX | Feature3DNOW | Feature3DNOWA;
-constexpr FeatureBitset FeaturesAthlonXP =
+constexpr FeatureBitset FeaturesAthlonXP =
FeaturesAthlon | FeatureFXSR | FeatureSSE;
-constexpr FeatureBitset FeaturesK8 =
+constexpr FeatureBitset FeaturesK8 =
FeaturesAthlonXP | FeatureSSE2 | Feature64BIT;
-constexpr FeatureBitset FeaturesK8SSE3 = FeaturesK8 | FeatureSSE3;
-constexpr FeatureBitset FeaturesAMDFAM10 =
+constexpr FeatureBitset FeaturesK8SSE3 = FeaturesK8 | FeatureSSE3;
+constexpr FeatureBitset FeaturesAMDFAM10 =
FeaturesK8SSE3 | FeatureCMPXCHG16B | FeatureLZCNT | FeaturePOPCNT |
FeaturePRFCHW | FeatureSAHF | FeatureSSE4_A;
// Bobcat architecture processors.
-constexpr FeatureBitset FeaturesBTVER1 =
+constexpr FeatureBitset FeaturesBTVER1 =
FeatureX87 | FeatureCMPXCHG8B | FeatureCMPXCHG16B | Feature64BIT |
FeatureFXSR | FeatureLZCNT | FeatureMMX | FeaturePOPCNT | FeaturePRFCHW |
FeatureSSE | FeatureSSE2 | FeatureSSE3 | FeatureSSSE3 | FeatureSSE4_A |
FeatureSAHF;
-constexpr FeatureBitset FeaturesBTVER2 =
+constexpr FeatureBitset FeaturesBTVER2 =
FeaturesBTVER1 | FeatureAES | FeatureAVX | FeatureBMI | FeatureF16C |
FeatureMOVBE | FeaturePCLMUL | FeatureXSAVE | FeatureXSAVEOPT;
// AMD Bulldozer architecture processors.
-constexpr FeatureBitset FeaturesBDVER1 =
+constexpr FeatureBitset FeaturesBDVER1 =
FeatureX87 | FeatureAES | FeatureAVX | FeatureCMPXCHG8B |
FeatureCMPXCHG16B | Feature64BIT | FeatureFMA4 | FeatureFXSR | FeatureLWP |
FeatureLZCNT | FeatureMMX | FeaturePCLMUL | FeaturePOPCNT | FeaturePRFCHW |
FeatureSAHF | FeatureSSE | FeatureSSE2 | FeatureSSE3 | FeatureSSSE3 |
FeatureSSE4_1 | FeatureSSE4_2 | FeatureSSE4_A | FeatureXOP | FeatureXSAVE;
-constexpr FeatureBitset FeaturesBDVER2 =
+constexpr FeatureBitset FeaturesBDVER2 =
FeaturesBDVER1 | FeatureBMI | FeatureFMA | FeatureF16C | FeatureTBM;
-constexpr FeatureBitset FeaturesBDVER3 =
+constexpr FeatureBitset FeaturesBDVER3 =
FeaturesBDVER2 | FeatureFSGSBASE | FeatureXSAVEOPT;
-constexpr FeatureBitset FeaturesBDVER4 = FeaturesBDVER3 | FeatureAVX2 |
- FeatureBMI2 | FeatureMOVBE |
- FeatureMWAITX | FeatureRDRND;
+constexpr FeatureBitset FeaturesBDVER4 = FeaturesBDVER3 | FeatureAVX2 |
+ FeatureBMI2 | FeatureMOVBE |
+ FeatureMWAITX | FeatureRDRND;
// AMD Zen architecture processors.
-constexpr FeatureBitset FeaturesZNVER1 =
+constexpr FeatureBitset FeaturesZNVER1 =
FeatureX87 | FeatureADX | FeatureAES | FeatureAVX | FeatureAVX2 |
FeatureBMI | FeatureBMI2 | FeatureCLFLUSHOPT | FeatureCLZERO |
FeatureCMPXCHG8B | FeatureCMPXCHG16B | Feature64BIT | FeatureF16C |
@@ -279,13 +279,13 @@ constexpr FeatureBitset FeaturesZNVER1 =
FeatureSSE | FeatureSSE2 | FeatureSSE3 | FeatureSSSE3 | FeatureSSE4_1 |
FeatureSSE4_2 | FeatureSSE4_A | FeatureXSAVE | FeatureXSAVEC |
FeatureXSAVEOPT | FeatureXSAVES;
-constexpr FeatureBitset FeaturesZNVER2 =
+constexpr FeatureBitset FeaturesZNVER2 =
FeaturesZNVER1 | FeatureCLWB | FeatureRDPID | FeatureWBNOINVD;
-static constexpr FeatureBitset FeaturesZNVER3 = FeaturesZNVER2 |
- FeatureINVPCID | FeaturePKU |
- FeatureVAES | FeatureVPCLMULQDQ;
+static constexpr FeatureBitset FeaturesZNVER3 = FeaturesZNVER2 |
+ FeatureINVPCID | FeaturePKU |
+ FeatureVAES | FeatureVPCLMULQDQ;
-constexpr ProcInfo Processors[] = {
+constexpr ProcInfo Processors[] = {
// Empty processor. Include X87 and CMPXCHG8 for backwards compatibility.
{ {""}, CK_None, ~0U, FeatureX87 | FeatureCMPXCHG8B },
// i386-generation processors.
@@ -357,10 +357,10 @@ constexpr ProcInfo Processors[] = {
{ {"icelake-server"}, CK_IcelakeServer, FEATURE_AVX512VBMI2, FeaturesICLServer },
// Tigerlake microarchitecture based processors.
{ {"tigerlake"}, CK_Tigerlake, FEATURE_AVX512VP2INTERSECT, FeaturesTigerlake },
- // Sapphire Rapids microarchitecture based processors.
- { {"sapphirerapids"}, CK_SapphireRapids, FEATURE_AVX512VP2INTERSECT, FeaturesSapphireRapids },
- // Alderlake microarchitecture based processors.
- { {"alderlake"}, CK_Alderlake, FEATURE_AVX2, FeaturesAlderlake },
+ // Sapphire Rapids microarchitecture based processors.
+ { {"sapphirerapids"}, CK_SapphireRapids, FEATURE_AVX512VP2INTERSECT, FeaturesSapphireRapids },
+ // Alderlake microarchitecture based processors.
+ { {"alderlake"}, CK_Alderlake, FEATURE_AVX2, FeaturesAlderlake },
// Knights Landing processor.
{ {"knl"}, CK_KNL, FEATURE_AVX512F, FeaturesKNL },
// Knights Mill processor.
@@ -398,18 +398,18 @@ constexpr ProcInfo Processors[] = {
// Zen architecture processors.
{ {"znver1"}, CK_ZNVER1, FEATURE_AVX2, FeaturesZNVER1 },
{ {"znver2"}, CK_ZNVER2, FEATURE_AVX2, FeaturesZNVER2 },
- { {"znver3"}, CK_ZNVER3, FEATURE_AVX2, FeaturesZNVER3 },
+ { {"znver3"}, CK_ZNVER3, FEATURE_AVX2, FeaturesZNVER3 },
// Generic 64-bit processor.
{ {"x86-64"}, CK_x86_64, ~0U, FeaturesX86_64 },
- { {"x86-64-v2"}, CK_x86_64_v2, ~0U, FeaturesX86_64_V2 },
- { {"x86-64-v3"}, CK_x86_64_v3, ~0U, FeaturesX86_64_V3 },
- { {"x86-64-v4"}, CK_x86_64_v4, ~0U, FeaturesX86_64_V4 },
+ { {"x86-64-v2"}, CK_x86_64_v2, ~0U, FeaturesX86_64_V2 },
+ { {"x86-64-v3"}, CK_x86_64_v3, ~0U, FeaturesX86_64_V3 },
+ { {"x86-64-v4"}, CK_x86_64_v4, ~0U, FeaturesX86_64_V4 },
// Geode processors.
{ {"geode"}, CK_Geode, ~0U, FeaturesGeode },
};
-constexpr const char *NoTuneList[] = {"x86-64-v2", "x86-64-v3", "x86-64-v4"};
-
+constexpr const char *NoTuneList[] = {"x86-64-v2", "x86-64-v3", "x86-64-v4"};
+
X86::CPUKind llvm::X86::parseArchX86(StringRef CPU, bool Only64Bit) {
for (const auto &P : Processors)
if (P.Name == CPU && (P.Features[FEATURE_64BIT] || !Only64Bit))
@@ -418,12 +418,12 @@ X86::CPUKind llvm::X86::parseArchX86(StringRef CPU, bool Only64Bit) {
return CK_None;
}
-X86::CPUKind llvm::X86::parseTuneCPU(StringRef CPU, bool Only64Bit) {
- if (llvm::is_contained(NoTuneList, CPU))
- return CK_None;
- return parseArchX86(CPU, Only64Bit);
-}
-
+X86::CPUKind llvm::X86::parseTuneCPU(StringRef CPU, bool Only64Bit) {
+ if (llvm::is_contained(NoTuneList, CPU))
+ return CK_None;
+ return parseArchX86(CPU, Only64Bit);
+}
+
void llvm::X86::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values,
bool Only64Bit) {
for (const auto &P : Processors)
@@ -431,14 +431,14 @@ void llvm::X86::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values,
Values.emplace_back(P.Name);
}
-void llvm::X86::fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values,
- bool Only64Bit) {
- for (const ProcInfo &P : Processors)
- if (!P.Name.empty() && (P.Features[FEATURE_64BIT] || !Only64Bit) &&
- !llvm::is_contained(NoTuneList, P.Name))
- Values.emplace_back(P.Name);
-}
-
+void llvm::X86::fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values,
+ bool Only64Bit) {
+ for (const ProcInfo &P : Processors)
+ if (!P.Name.empty() && (P.Features[FEATURE_64BIT] || !Only64Bit) &&
+ !llvm::is_contained(NoTuneList, P.Name))
+ Values.emplace_back(P.Name);
+}
+
ProcessorFeatures llvm::X86::getKeyFeature(X86::CPUKind Kind) {
// FIXME: Can we avoid a linear search here? The table might be sorted by
// CPUKind so we could binary search?
@@ -453,131 +453,131 @@ ProcessorFeatures llvm::X86::getKeyFeature(X86::CPUKind Kind) {
}
// Features with no dependencies.
-constexpr FeatureBitset ImpliedFeatures64BIT = {};
-constexpr FeatureBitset ImpliedFeaturesADX = {};
-constexpr FeatureBitset ImpliedFeaturesBMI = {};
-constexpr FeatureBitset ImpliedFeaturesBMI2 = {};
-constexpr FeatureBitset ImpliedFeaturesCLDEMOTE = {};
-constexpr FeatureBitset ImpliedFeaturesCLFLUSHOPT = {};
-constexpr FeatureBitset ImpliedFeaturesCLWB = {};
-constexpr FeatureBitset ImpliedFeaturesCLZERO = {};
-constexpr FeatureBitset ImpliedFeaturesCMOV = {};
-constexpr FeatureBitset ImpliedFeaturesCMPXCHG16B = {};
-constexpr FeatureBitset ImpliedFeaturesCMPXCHG8B = {};
-constexpr FeatureBitset ImpliedFeaturesENQCMD = {};
-constexpr FeatureBitset ImpliedFeaturesFSGSBASE = {};
-constexpr FeatureBitset ImpliedFeaturesFXSR = {};
-constexpr FeatureBitset ImpliedFeaturesINVPCID = {};
-constexpr FeatureBitset ImpliedFeaturesLWP = {};
-constexpr FeatureBitset ImpliedFeaturesLZCNT = {};
-constexpr FeatureBitset ImpliedFeaturesMWAITX = {};
-constexpr FeatureBitset ImpliedFeaturesMOVBE = {};
-constexpr FeatureBitset ImpliedFeaturesMOVDIR64B = {};
-constexpr FeatureBitset ImpliedFeaturesMOVDIRI = {};
-constexpr FeatureBitset ImpliedFeaturesPCONFIG = {};
-constexpr FeatureBitset ImpliedFeaturesPOPCNT = {};
-constexpr FeatureBitset ImpliedFeaturesPKU = {};
-constexpr FeatureBitset ImpliedFeaturesPREFETCHWT1 = {};
-constexpr FeatureBitset ImpliedFeaturesPRFCHW = {};
-constexpr FeatureBitset ImpliedFeaturesPTWRITE = {};
-constexpr FeatureBitset ImpliedFeaturesRDPID = {};
-constexpr FeatureBitset ImpliedFeaturesRDRND = {};
-constexpr FeatureBitset ImpliedFeaturesRDSEED = {};
-constexpr FeatureBitset ImpliedFeaturesRTM = {};
-constexpr FeatureBitset ImpliedFeaturesSAHF = {};
-constexpr FeatureBitset ImpliedFeaturesSERIALIZE = {};
-constexpr FeatureBitset ImpliedFeaturesSGX = {};
-constexpr FeatureBitset ImpliedFeaturesSHSTK = {};
-constexpr FeatureBitset ImpliedFeaturesTBM = {};
-constexpr FeatureBitset ImpliedFeaturesTSXLDTRK = {};
-constexpr FeatureBitset ImpliedFeaturesUINTR = {};
-constexpr FeatureBitset ImpliedFeaturesWAITPKG = {};
-constexpr FeatureBitset ImpliedFeaturesWBNOINVD = {};
-constexpr FeatureBitset ImpliedFeaturesVZEROUPPER = {};
-constexpr FeatureBitset ImpliedFeaturesX87 = {};
-constexpr FeatureBitset ImpliedFeaturesXSAVE = {};
+constexpr FeatureBitset ImpliedFeatures64BIT = {};
+constexpr FeatureBitset ImpliedFeaturesADX = {};
+constexpr FeatureBitset ImpliedFeaturesBMI = {};
+constexpr FeatureBitset ImpliedFeaturesBMI2 = {};
+constexpr FeatureBitset ImpliedFeaturesCLDEMOTE = {};
+constexpr FeatureBitset ImpliedFeaturesCLFLUSHOPT = {};
+constexpr FeatureBitset ImpliedFeaturesCLWB = {};
+constexpr FeatureBitset ImpliedFeaturesCLZERO = {};
+constexpr FeatureBitset ImpliedFeaturesCMOV = {};
+constexpr FeatureBitset ImpliedFeaturesCMPXCHG16B = {};
+constexpr FeatureBitset ImpliedFeaturesCMPXCHG8B = {};
+constexpr FeatureBitset ImpliedFeaturesENQCMD = {};
+constexpr FeatureBitset ImpliedFeaturesFSGSBASE = {};
+constexpr FeatureBitset ImpliedFeaturesFXSR = {};
+constexpr FeatureBitset ImpliedFeaturesINVPCID = {};
+constexpr FeatureBitset ImpliedFeaturesLWP = {};
+constexpr FeatureBitset ImpliedFeaturesLZCNT = {};
+constexpr FeatureBitset ImpliedFeaturesMWAITX = {};
+constexpr FeatureBitset ImpliedFeaturesMOVBE = {};
+constexpr FeatureBitset ImpliedFeaturesMOVDIR64B = {};
+constexpr FeatureBitset ImpliedFeaturesMOVDIRI = {};
+constexpr FeatureBitset ImpliedFeaturesPCONFIG = {};
+constexpr FeatureBitset ImpliedFeaturesPOPCNT = {};
+constexpr FeatureBitset ImpliedFeaturesPKU = {};
+constexpr FeatureBitset ImpliedFeaturesPREFETCHWT1 = {};
+constexpr FeatureBitset ImpliedFeaturesPRFCHW = {};
+constexpr FeatureBitset ImpliedFeaturesPTWRITE = {};
+constexpr FeatureBitset ImpliedFeaturesRDPID = {};
+constexpr FeatureBitset ImpliedFeaturesRDRND = {};
+constexpr FeatureBitset ImpliedFeaturesRDSEED = {};
+constexpr FeatureBitset ImpliedFeaturesRTM = {};
+constexpr FeatureBitset ImpliedFeaturesSAHF = {};
+constexpr FeatureBitset ImpliedFeaturesSERIALIZE = {};
+constexpr FeatureBitset ImpliedFeaturesSGX = {};
+constexpr FeatureBitset ImpliedFeaturesSHSTK = {};
+constexpr FeatureBitset ImpliedFeaturesTBM = {};
+constexpr FeatureBitset ImpliedFeaturesTSXLDTRK = {};
+constexpr FeatureBitset ImpliedFeaturesUINTR = {};
+constexpr FeatureBitset ImpliedFeaturesWAITPKG = {};
+constexpr FeatureBitset ImpliedFeaturesWBNOINVD = {};
+constexpr FeatureBitset ImpliedFeaturesVZEROUPPER = {};
+constexpr FeatureBitset ImpliedFeaturesX87 = {};
+constexpr FeatureBitset ImpliedFeaturesXSAVE = {};
// Not really CPU features, but need to be in the table because clang uses
// target features to communicate them to the backend.
-constexpr FeatureBitset ImpliedFeaturesRETPOLINE_EXTERNAL_THUNK = {};
-constexpr FeatureBitset ImpliedFeaturesRETPOLINE_INDIRECT_BRANCHES = {};
-constexpr FeatureBitset ImpliedFeaturesRETPOLINE_INDIRECT_CALLS = {};
-constexpr FeatureBitset ImpliedFeaturesLVI_CFI = {};
-constexpr FeatureBitset ImpliedFeaturesLVI_LOAD_HARDENING = {};
+constexpr FeatureBitset ImpliedFeaturesRETPOLINE_EXTERNAL_THUNK = {};
+constexpr FeatureBitset ImpliedFeaturesRETPOLINE_INDIRECT_BRANCHES = {};
+constexpr FeatureBitset ImpliedFeaturesRETPOLINE_INDIRECT_CALLS = {};
+constexpr FeatureBitset ImpliedFeaturesLVI_CFI = {};
+constexpr FeatureBitset ImpliedFeaturesLVI_LOAD_HARDENING = {};
// XSAVE features are dependent on basic XSAVE.
-constexpr FeatureBitset ImpliedFeaturesXSAVEC = FeatureXSAVE;
-constexpr FeatureBitset ImpliedFeaturesXSAVEOPT = FeatureXSAVE;
-constexpr FeatureBitset ImpliedFeaturesXSAVES = FeatureXSAVE;
+constexpr FeatureBitset ImpliedFeaturesXSAVEC = FeatureXSAVE;
+constexpr FeatureBitset ImpliedFeaturesXSAVEOPT = FeatureXSAVE;
+constexpr FeatureBitset ImpliedFeaturesXSAVES = FeatureXSAVE;
// MMX->3DNOW->3DNOWA chain.
-constexpr FeatureBitset ImpliedFeaturesMMX = {};
-constexpr FeatureBitset ImpliedFeatures3DNOW = FeatureMMX;
-constexpr FeatureBitset ImpliedFeatures3DNOWA = Feature3DNOW;
+constexpr FeatureBitset ImpliedFeaturesMMX = {};
+constexpr FeatureBitset ImpliedFeatures3DNOW = FeatureMMX;
+constexpr FeatureBitset ImpliedFeatures3DNOWA = Feature3DNOW;
// SSE/AVX/AVX512F chain.
-constexpr FeatureBitset ImpliedFeaturesSSE = {};
-constexpr FeatureBitset ImpliedFeaturesSSE2 = FeatureSSE;
-constexpr FeatureBitset ImpliedFeaturesSSE3 = FeatureSSE2;
-constexpr FeatureBitset ImpliedFeaturesSSSE3 = FeatureSSE3;
-constexpr FeatureBitset ImpliedFeaturesSSE4_1 = FeatureSSSE3;
-constexpr FeatureBitset ImpliedFeaturesSSE4_2 = FeatureSSE4_1;
-constexpr FeatureBitset ImpliedFeaturesAVX = FeatureSSE4_2;
-constexpr FeatureBitset ImpliedFeaturesAVX2 = FeatureAVX;
-constexpr FeatureBitset ImpliedFeaturesAVX512F =
+constexpr FeatureBitset ImpliedFeaturesSSE = {};
+constexpr FeatureBitset ImpliedFeaturesSSE2 = FeatureSSE;
+constexpr FeatureBitset ImpliedFeaturesSSE3 = FeatureSSE2;
+constexpr FeatureBitset ImpliedFeaturesSSSE3 = FeatureSSE3;
+constexpr FeatureBitset ImpliedFeaturesSSE4_1 = FeatureSSSE3;
+constexpr FeatureBitset ImpliedFeaturesSSE4_2 = FeatureSSE4_1;
+constexpr FeatureBitset ImpliedFeaturesAVX = FeatureSSE4_2;
+constexpr FeatureBitset ImpliedFeaturesAVX2 = FeatureAVX;
+constexpr FeatureBitset ImpliedFeaturesAVX512F =
FeatureAVX2 | FeatureF16C | FeatureFMA;
// Vector extensions that build on SSE or AVX.
-constexpr FeatureBitset ImpliedFeaturesAES = FeatureSSE2;
-constexpr FeatureBitset ImpliedFeaturesF16C = FeatureAVX;
-constexpr FeatureBitset ImpliedFeaturesFMA = FeatureAVX;
-constexpr FeatureBitset ImpliedFeaturesGFNI = FeatureSSE2;
-constexpr FeatureBitset ImpliedFeaturesPCLMUL = FeatureSSE2;
-constexpr FeatureBitset ImpliedFeaturesSHA = FeatureSSE2;
-constexpr FeatureBitset ImpliedFeaturesVAES = FeatureAES | FeatureAVX;
-constexpr FeatureBitset ImpliedFeaturesVPCLMULQDQ = FeatureAVX | FeaturePCLMUL;
+constexpr FeatureBitset ImpliedFeaturesAES = FeatureSSE2;
+constexpr FeatureBitset ImpliedFeaturesF16C = FeatureAVX;
+constexpr FeatureBitset ImpliedFeaturesFMA = FeatureAVX;
+constexpr FeatureBitset ImpliedFeaturesGFNI = FeatureSSE2;
+constexpr FeatureBitset ImpliedFeaturesPCLMUL = FeatureSSE2;
+constexpr FeatureBitset ImpliedFeaturesSHA = FeatureSSE2;
+constexpr FeatureBitset ImpliedFeaturesVAES = FeatureAES | FeatureAVX;
+constexpr FeatureBitset ImpliedFeaturesVPCLMULQDQ = FeatureAVX | FeaturePCLMUL;
// AVX512 features.
-constexpr FeatureBitset ImpliedFeaturesAVX512CD = FeatureAVX512F;
-constexpr FeatureBitset ImpliedFeaturesAVX512BW = FeatureAVX512F;
-constexpr FeatureBitset ImpliedFeaturesAVX512DQ = FeatureAVX512F;
-constexpr FeatureBitset ImpliedFeaturesAVX512ER = FeatureAVX512F;
-constexpr FeatureBitset ImpliedFeaturesAVX512PF = FeatureAVX512F;
-constexpr FeatureBitset ImpliedFeaturesAVX512VL = FeatureAVX512F;
-
-constexpr FeatureBitset ImpliedFeaturesAVX512BF16 = FeatureAVX512BW;
-constexpr FeatureBitset ImpliedFeaturesAVX512BITALG = FeatureAVX512BW;
-constexpr FeatureBitset ImpliedFeaturesAVX512IFMA = FeatureAVX512F;
-constexpr FeatureBitset ImpliedFeaturesAVX512VNNI = FeatureAVX512F;
-constexpr FeatureBitset ImpliedFeaturesAVX512VPOPCNTDQ = FeatureAVX512F;
-constexpr FeatureBitset ImpliedFeaturesAVX512VBMI = FeatureAVX512BW;
-constexpr FeatureBitset ImpliedFeaturesAVX512VBMI2 = FeatureAVX512BW;
-constexpr FeatureBitset ImpliedFeaturesAVX512VP2INTERSECT = FeatureAVX512F;
+constexpr FeatureBitset ImpliedFeaturesAVX512CD = FeatureAVX512F;
+constexpr FeatureBitset ImpliedFeaturesAVX512BW = FeatureAVX512F;
+constexpr FeatureBitset ImpliedFeaturesAVX512DQ = FeatureAVX512F;
+constexpr FeatureBitset ImpliedFeaturesAVX512ER = FeatureAVX512F;
+constexpr FeatureBitset ImpliedFeaturesAVX512PF = FeatureAVX512F;
+constexpr FeatureBitset ImpliedFeaturesAVX512VL = FeatureAVX512F;
+
+constexpr FeatureBitset ImpliedFeaturesAVX512BF16 = FeatureAVX512BW;
+constexpr FeatureBitset ImpliedFeaturesAVX512BITALG = FeatureAVX512BW;
+constexpr FeatureBitset ImpliedFeaturesAVX512IFMA = FeatureAVX512F;
+constexpr FeatureBitset ImpliedFeaturesAVX512VNNI = FeatureAVX512F;
+constexpr FeatureBitset ImpliedFeaturesAVX512VPOPCNTDQ = FeatureAVX512F;
+constexpr FeatureBitset ImpliedFeaturesAVX512VBMI = FeatureAVX512BW;
+constexpr FeatureBitset ImpliedFeaturesAVX512VBMI2 = FeatureAVX512BW;
+constexpr FeatureBitset ImpliedFeaturesAVX512VP2INTERSECT = FeatureAVX512F;
// FIXME: These two aren't really implemented and just exist in the feature
// list for __builtin_cpu_supports. So omit their dependencies.
-constexpr FeatureBitset ImpliedFeaturesAVX5124FMAPS = {};
-constexpr FeatureBitset ImpliedFeaturesAVX5124VNNIW = {};
+constexpr FeatureBitset ImpliedFeaturesAVX5124FMAPS = {};
+constexpr FeatureBitset ImpliedFeaturesAVX5124VNNIW = {};
// SSE4_A->FMA4->XOP chain.
-constexpr FeatureBitset ImpliedFeaturesSSE4_A = FeatureSSE3;
-constexpr FeatureBitset ImpliedFeaturesFMA4 = FeatureAVX | FeatureSSE4_A;
-constexpr FeatureBitset ImpliedFeaturesXOP = FeatureFMA4;
+constexpr FeatureBitset ImpliedFeaturesSSE4_A = FeatureSSE3;
+constexpr FeatureBitset ImpliedFeaturesFMA4 = FeatureAVX | FeatureSSE4_A;
+constexpr FeatureBitset ImpliedFeaturesXOP = FeatureFMA4;
// AMX Features
-constexpr FeatureBitset ImpliedFeaturesAMX_TILE = {};
-constexpr FeatureBitset ImpliedFeaturesAMX_BF16 = FeatureAMX_TILE;
-constexpr FeatureBitset ImpliedFeaturesAMX_INT8 = FeatureAMX_TILE;
-constexpr FeatureBitset ImpliedFeaturesHRESET = {};
-
-// Key Locker Features
-constexpr FeatureBitset ImpliedFeaturesKL = FeatureSSE2;
-constexpr FeatureBitset ImpliedFeaturesWIDEKL = FeatureKL;
-
-// AVXVNNI Features
-constexpr FeatureBitset ImpliedFeaturesAVXVNNI = FeatureAVX2;
-
-constexpr FeatureInfo FeatureInfos[X86::CPU_FEATURE_MAX] = {
+constexpr FeatureBitset ImpliedFeaturesAMX_TILE = {};
+constexpr FeatureBitset ImpliedFeaturesAMX_BF16 = FeatureAMX_TILE;
+constexpr FeatureBitset ImpliedFeaturesAMX_INT8 = FeatureAMX_TILE;
+constexpr FeatureBitset ImpliedFeaturesHRESET = {};
+
+// Key Locker Features
+constexpr FeatureBitset ImpliedFeaturesKL = FeatureSSE2;
+constexpr FeatureBitset ImpliedFeaturesWIDEKL = FeatureKL;
+
+// AVXVNNI Features
+constexpr FeatureBitset ImpliedFeaturesAVXVNNI = FeatureAVX2;
+
+constexpr FeatureInfo FeatureInfos[X86::CPU_FEATURE_MAX] = {
#define X86_FEATURE(ENUM, STR) {{STR}, ImpliedFeatures##ENUM},
#include "llvm/Support/X86TargetParser.def"
};
@@ -595,9 +595,9 @@ void llvm::X86::getFeaturesForCPU(StringRef CPU,
Bits &= ~Feature64BIT;
// Add the string version of all set bits.
- for (unsigned i = 0; i != CPU_FEATURE_MAX; ++i)
- if (Bits[i] && !FeatureInfos[i].Name.empty())
- EnabledFeatures.push_back(FeatureInfos[i].Name);
+ for (unsigned i = 0; i != CPU_FEATURE_MAX; ++i)
+ if (Bits[i] && !FeatureInfos[i].Name.empty())
+ EnabledFeatures.push_back(FeatureInfos[i].Name);
}
// For each feature that is (transitively) implied by this feature, set it.
@@ -631,9 +631,9 @@ static void getImpliedDisabledFeatures(FeatureBitset &Bits, unsigned Value) {
} while (Prev != Bits);
}
-void llvm::X86::updateImpliedFeatures(
+void llvm::X86::updateImpliedFeatures(
StringRef Feature, bool Enabled,
- StringMap<bool> &Features) {
+ StringMap<bool> &Features) {
auto I = llvm::find_if(
FeatureInfos, [&](const FeatureInfo &FI) { return FI.Name == Feature; });
if (I == std::end(FeatureInfos)) {
@@ -649,8 +649,8 @@ void llvm::X86::updateImpliedFeatures(
getImpliedDisabledFeatures(ImpliedBits,
std::distance(std::begin(FeatureInfos), I));
- // Update the map entry for all implied features.
- for (unsigned i = 0; i != CPU_FEATURE_MAX; ++i)
- if (ImpliedBits[i] && !FeatureInfos[i].Name.empty())
- Features[FeatureInfos[i].Name] = Enabled;
+ // Update the map entry for all implied features.
+ for (unsigned i = 0; i != CPU_FEATURE_MAX; ++i)
+ if (ImpliedBits[i] && !FeatureInfos[i].Name.empty())
+ Features[FeatureInfos[i].Name] = Enabled;
}
diff --git a/contrib/libs/llvm12/lib/Support/YAMLParser.cpp b/contrib/libs/llvm12/lib/Support/YAMLParser.cpp
index cddc30daf6..f68ba0d065 100644
--- a/contrib/libs/llvm12/lib/Support/YAMLParser.cpp
+++ b/contrib/libs/llvm12/lib/Support/YAMLParser.cpp
@@ -200,12 +200,12 @@ static UTF8Decoded decodeUTF8(StringRef Range) {
StringRef::iterator End = Range.end();
// 1 byte: [0x00, 0x7f]
// Bit pattern: 0xxxxxxx
- if (Position < End && (*Position & 0x80) == 0) {
- return std::make_pair(*Position, 1);
+ if (Position < End && (*Position & 0x80) == 0) {
+ return std::make_pair(*Position, 1);
}
// 2 bytes: [0x80, 0x7ff]
// Bit pattern: 110xxxxx 10xxxxxx
- if (Position + 1 < End && ((*Position & 0xE0) == 0xC0) &&
+ if (Position + 1 < End && ((*Position & 0xE0) == 0xC0) &&
((*(Position + 1) & 0xC0) == 0x80)) {
uint32_t codepoint = ((*Position & 0x1F) << 6) |
(*(Position + 1) & 0x3F);
@@ -214,7 +214,7 @@ static UTF8Decoded decodeUTF8(StringRef Range) {
}
// 3 bytes: [0x8000, 0xffff]
// Bit pattern: 1110xxxx 10xxxxxx 10xxxxxx
- if (Position + 2 < End && ((*Position & 0xF0) == 0xE0) &&
+ if (Position + 2 < End && ((*Position & 0xF0) == 0xE0) &&
((*(Position + 1) & 0xC0) == 0x80) &&
((*(Position + 2) & 0xC0) == 0x80)) {
uint32_t codepoint = ((*Position & 0x0F) << 12) |
@@ -228,7 +228,7 @@ static UTF8Decoded decodeUTF8(StringRef Range) {
}
// 4 bytes: [0x10000, 0x10FFFF]
// Bit pattern: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
- if (Position + 3 < End && ((*Position & 0xF8) == 0xF0) &&
+ if (Position + 3 < End && ((*Position & 0xF8) == 0xF0) &&
((*(Position + 1) & 0xC0) == 0x80) &&
((*(Position + 2) & 0xC0) == 0x80) &&
((*(Position + 3) & 0xC0) == 0x80)) {
@@ -715,7 +715,7 @@ std::string yaml::escape(StringRef Input, bool EscapePrintable) {
// Found invalid char.
SmallString<4> Val;
encodeUTF8(0xFFFD, Val);
- llvm::append_range(EscapedInput, Val);
+ llvm::append_range(EscapedInput, Val);
// FIXME: Error reporting.
return EscapedInput;
}
@@ -746,92 +746,92 @@ std::string yaml::escape(StringRef Input, bool EscapePrintable) {
return EscapedInput;
}
-llvm::Optional<bool> yaml::parseBool(StringRef S) {
- switch (S.size()) {
- case 1:
- switch (S.front()) {
- case 'y':
- case 'Y':
- return true;
- case 'n':
- case 'N':
- return false;
- default:
- return None;
- }
- case 2:
- switch (S.front()) {
- case 'O':
- if (S[1] == 'N') // ON
- return true;
- LLVM_FALLTHROUGH;
- case 'o':
- if (S[1] == 'n') //[Oo]n
- return true;
- return None;
- case 'N':
- if (S[1] == 'O') // NO
- return false;
- LLVM_FALLTHROUGH;
- case 'n':
- if (S[1] == 'o') //[Nn]o
- return false;
- return None;
- default:
- return None;
- }
- case 3:
- switch (S.front()) {
- case 'O':
- if (S.drop_front() == "FF") // OFF
- return false;
- LLVM_FALLTHROUGH;
- case 'o':
- if (S.drop_front() == "ff") //[Oo]ff
- return false;
- return None;
- case 'Y':
- if (S.drop_front() == "ES") // YES
- return true;
- LLVM_FALLTHROUGH;
- case 'y':
- if (S.drop_front() == "es") //[Yy]es
- return true;
- return None;
- default:
- return None;
- }
- case 4:
- switch (S.front()) {
- case 'T':
- if (S.drop_front() == "RUE") // TRUE
- return true;
- LLVM_FALLTHROUGH;
- case 't':
- if (S.drop_front() == "rue") //[Tt]rue
- return true;
- return None;
- default:
- return None;
- }
- case 5:
- switch (S.front()) {
- case 'F':
- if (S.drop_front() == "ALSE") // FALSE
- return false;
- LLVM_FALLTHROUGH;
- case 'f':
- if (S.drop_front() == "alse") //[Ff]alse
- return false;
- return None;
- default:
- return None;
- }
- default:
- return None;
- }
-}
-
+llvm::Optional<bool> yaml::parseBool(StringRef S) {
+ switch (S.size()) {
+ case 1:
+ switch (S.front()) {
+ case 'y':
+ case 'Y':
+ return true;
+ case 'n':
+ case 'N':
+ return false;
+ default:
+ return None;
+ }
+ case 2:
+ switch (S.front()) {
+ case 'O':
+ if (S[1] == 'N') // ON
+ return true;
+ LLVM_FALLTHROUGH;
+ case 'o':
+ if (S[1] == 'n') //[Oo]n
+ return true;
+ return None;
+ case 'N':
+ if (S[1] == 'O') // NO
+ return false;
+ LLVM_FALLTHROUGH;
+ case 'n':
+ if (S[1] == 'o') //[Nn]o
+ return false;
+ return None;
+ default:
+ return None;
+ }
+ case 3:
+ switch (S.front()) {
+ case 'O':
+ if (S.drop_front() == "FF") // OFF
+ return false;
+ LLVM_FALLTHROUGH;
+ case 'o':
+ if (S.drop_front() == "ff") //[Oo]ff
+ return false;
+ return None;
+ case 'Y':
+ if (S.drop_front() == "ES") // YES
+ return true;
+ LLVM_FALLTHROUGH;
+ case 'y':
+ if (S.drop_front() == "es") //[Yy]es
+ return true;
+ return None;
+ default:
+ return None;
+ }
+ case 4:
+ switch (S.front()) {
+ case 'T':
+ if (S.drop_front() == "RUE") // TRUE
+ return true;
+ LLVM_FALLTHROUGH;
+ case 't':
+ if (S.drop_front() == "rue") //[Tt]rue
+ return true;
+ return None;
+ default:
+ return None;
+ }
+ case 5:
+ switch (S.front()) {
+ case 'F':
+ if (S.drop_front() == "ALSE") // FALSE
+ return false;
+ LLVM_FALLTHROUGH;
+ case 'f':
+ if (S.drop_front() == "alse") //[Ff]alse
+ return false;
+ return None;
+ default:
+ return None;
+ }
+ default:
+ return None;
+ }
+}
+
Scanner::Scanner(StringRef Input, SourceMgr &sm, bool ShowColors,
std::error_code *EC)
: SM(sm), ShowColors(ShowColors), EC(EC) {
@@ -856,7 +856,7 @@ void Scanner::init(MemoryBufferRef Buffer) {
IsSimpleKeyAllowed = true;
Failed = false;
std::unique_ptr<MemoryBuffer> InputBufferOwner =
- MemoryBuffer::getMemBuffer(Buffer, /*RequiresNullTerminator=*/false);
+ MemoryBuffer::getMemBuffer(Buffer, /*RequiresNullTerminator=*/false);
SM.AddNewSourceBuffer(std::move(InputBufferOwner), SMLoc());
}
@@ -981,9 +981,9 @@ void Scanner::advanceWhile(SkipWhileFunc Func) {
Current = Final;
}
-static bool is_ns_hex_digit(const char C) { return isAlnum(C); }
+static bool is_ns_hex_digit(const char C) { return isAlnum(C); }
-static bool is_ns_word_char(const char C) { return C == '-' || isAlpha(C); }
+static bool is_ns_word_char(const char C) { return C == '-' || isAlpha(C); }
void Scanner::scan_ns_uri_char() {
while (true) {
@@ -1111,7 +1111,7 @@ bool Scanner::rollIndent( int ToColumn
}
void Scanner::skipComment() {
- if (Current == End || *Current != '#')
+ if (Current == End || *Current != '#')
return;
while (true) {
// This may skip more than one byte, thus Column is only incremented
@@ -1126,7 +1126,7 @@ void Scanner::skipComment() {
void Scanner::scanToNextToken() {
while (true) {
- while (Current != End && (*Current == ' ' || *Current == '\t')) {
+ while (Current != End && (*Current == ' ' || *Current == '\t')) {
skip(1);
}
@@ -1361,7 +1361,7 @@ bool Scanner::scanFlowScalar(bool IsDoubleQuoted) {
&& wasEscaped(Start + 1, Current));
} else {
skip(1);
- while (Current != End) {
+ while (Current != End) {
// Skip a ' followed by another '.
if (Current + 1 < End && *Current == '\'' && *(Current + 1) == '\'') {
skip(2);
@@ -1409,14 +1409,14 @@ bool Scanner::scanPlainScalar() {
unsigned LeadingBlanks = 0;
assert(Indent >= -1 && "Indent must be >= -1 !");
unsigned indent = static_cast<unsigned>(Indent + 1);
- while (Current != End) {
+ while (Current != End) {
if (*Current == '#')
break;
- while (Current != End && !isBlankOrBreak(Current)) {
- if (FlowLevel && *Current == ':' &&
- (Current + 1 == End ||
- !(isBlankOrBreak(Current + 1) || *(Current + 1) == ','))) {
+ while (Current != End && !isBlankOrBreak(Current)) {
+ if (FlowLevel && *Current == ':' &&
+ (Current + 1 == End ||
+ !(isBlankOrBreak(Current + 1) || *(Current + 1) == ','))) {
setError("Found unexpected ':' while scanning a plain scalar", Current);
return false;
}
@@ -1486,7 +1486,7 @@ bool Scanner::scanAliasOrAnchor(bool IsAlias) {
StringRef::iterator Start = Current;
unsigned ColStart = Column;
skip(1);
- while (Current != End) {
+ while (Current != End) {
if ( *Current == '[' || *Current == ']'
|| *Current == '{' || *Current == '}'
|| *Current == ','
@@ -1499,7 +1499,7 @@ bool Scanner::scanAliasOrAnchor(bool IsAlias) {
++Column;
}
- if (Start + 1 == Current) {
+ if (Start + 1 == Current) {
setError("Got empty alias or anchor", Start);
return false;
}
@@ -1851,15 +1851,15 @@ Stream::~Stream() = default;
bool Stream::failed() { return scanner->failed(); }
-void Stream::printError(Node *N, const Twine &Msg, SourceMgr::DiagKind Kind) {
- printError(N ? N->getSourceRange() : SMRange(), Msg, Kind);
+void Stream::printError(Node *N, const Twine &Msg, SourceMgr::DiagKind Kind) {
+ printError(N ? N->getSourceRange() : SMRange(), Msg, Kind);
+}
+
+void Stream::printError(const SMRange &Range, const Twine &Msg,
+ SourceMgr::DiagKind Kind) {
+ scanner->printError(Range.Start, Kind, Msg, Range);
}
-void Stream::printError(const SMRange &Range, const Twine &Msg,
- SourceMgr::DiagKind Kind) {
- scanner->printError(Range.Start, Kind, Msg, Range);
-}
-
document_iterator Stream::begin() {
if (CurrentDoc)
report_fatal_error("Can only iterate over the stream once");
@@ -1976,11 +1976,11 @@ StringRef ScalarNode::getValue(SmallVectorImpl<char> &Storage) const {
Storage.reserve(UnquotedValue.size());
for (; i != StringRef::npos; i = UnquotedValue.find('\'')) {
StringRef Valid(UnquotedValue.begin(), i);
- llvm::append_range(Storage, Valid);
+ llvm::append_range(Storage, Valid);
Storage.push_back('\'');
UnquotedValue = UnquotedValue.substr(i + 2);
}
- llvm::append_range(Storage, UnquotedValue);
+ llvm::append_range(Storage, UnquotedValue);
return StringRef(Storage.begin(), Storage.size());
}
return UnquotedValue;
@@ -1999,7 +1999,7 @@ StringRef ScalarNode::unescapeDoubleQuoted( StringRef UnquotedValue
for (; i != StringRef::npos; i = UnquotedValue.find_first_of("\\\r\n")) {
// Insert all previous chars into Storage.
StringRef Valid(UnquotedValue.begin(), i);
- llvm::append_range(Storage, Valid);
+ llvm::append_range(Storage, Valid);
// Chop off inserted chars.
UnquotedValue = UnquotedValue.substr(i);
@@ -2131,7 +2131,7 @@ StringRef ScalarNode::unescapeDoubleQuoted( StringRef UnquotedValue
UnquotedValue = UnquotedValue.substr(1);
}
}
- llvm::append_range(Storage, UnquotedValue);
+ llvm::append_range(Storage, UnquotedValue);
return StringRef(Storage.begin(), Storage.size());
}
diff --git a/contrib/libs/llvm12/lib/Support/YAMLTraits.cpp b/contrib/libs/llvm12/lib/Support/YAMLTraits.cpp
index a84e4f57d1..aa6163a761 100644
--- a/contrib/libs/llvm12/lib/Support/YAMLTraits.cpp
+++ b/contrib/libs/llvm12/lib/Support/YAMLTraits.cpp
@@ -48,10 +48,10 @@ void IO::setContext(void *Context) {
Ctxt = Context;
}
-void IO::setAllowUnknownKeys(bool Allow) {
- llvm_unreachable("Only supported for Input");
-}
-
+void IO::setAllowUnknownKeys(bool Allow) {
+ llvm_unreachable("Only supported for Input");
+}
+
//===----------------------------------------------------------------------===//
// Input
//===----------------------------------------------------------------------===//
@@ -175,7 +175,7 @@ bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
return false;
}
MN->ValidKeys.push_back(Key);
- HNode *Value = MN->Mapping[Key].first.get();
+ HNode *Value = MN->Mapping[Key].first.get();
if (!Value) {
if (Required)
setError(CurrentNode, Twine("missing required key '") + Key + "'");
@@ -201,12 +201,12 @@ void Input::endMapping() {
return;
for (const auto &NN : MN->Mapping) {
if (!is_contained(MN->ValidKeys, NN.first())) {
- const SMRange &ReportLoc = NN.second.second;
- if (!AllowUnknownKeys) {
- setError(ReportLoc, Twine("unknown key '") + NN.first() + "'");
- break;
- } else
- reportWarning(ReportLoc, Twine("unknown key '") + NN.first() + "'");
+ const SMRange &ReportLoc = NN.second.second;
+ if (!AllowUnknownKeys) {
+ setError(ReportLoc, Twine("unknown key '") + NN.first() + "'");
+ break;
+ } else
+ reportWarning(ReportLoc, Twine("unknown key '") + NN.first() + "'");
}
}
}
@@ -378,24 +378,24 @@ void Input::setError(Node *node, const Twine &message) {
EC = make_error_code(errc::invalid_argument);
}
-void Input::setError(const SMRange &range, const Twine &message) {
- Strm->printError(range, message);
- EC = make_error_code(errc::invalid_argument);
-}
-
-void Input::reportWarning(HNode *hnode, const Twine &message) {
- assert(hnode && "HNode must not be NULL");
- Strm->printError(hnode->_node, message, SourceMgr::DK_Warning);
-}
-
-void Input::reportWarning(Node *node, const Twine &message) {
- Strm->printError(node, message, SourceMgr::DK_Warning);
-}
-
-void Input::reportWarning(const SMRange &range, const Twine &message) {
- Strm->printError(range, message, SourceMgr::DK_Warning);
-}
-
+void Input::setError(const SMRange &range, const Twine &message) {
+ Strm->printError(range, message);
+ EC = make_error_code(errc::invalid_argument);
+}
+
+void Input::reportWarning(HNode *hnode, const Twine &message) {
+ assert(hnode && "HNode must not be NULL");
+ Strm->printError(hnode->_node, message, SourceMgr::DK_Warning);
+}
+
+void Input::reportWarning(Node *node, const Twine &message) {
+ Strm->printError(node, message, SourceMgr::DK_Warning);
+}
+
+void Input::reportWarning(const SMRange &range, const Twine &message) {
+ Strm->printError(range, message, SourceMgr::DK_Warning);
+}
+
std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
SmallString<128> StringStorage;
if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
@@ -439,8 +439,8 @@ std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
auto ValueHNode = createHNodes(Value);
if (EC)
break;
- mapHNode->Mapping[KeyStr] =
- std::make_pair(std::move(ValueHNode), KeyNode->getSourceRange());
+ mapHNode->Mapping[KeyStr] =
+ std::make_pair(std::move(ValueHNode), KeyNode->getSourceRange());
}
return std::move(mapHNode);
} else if (isa<NullNode>(N)) {
@@ -455,8 +455,8 @@ void Input::setError(const Twine &Message) {
setError(CurrentNode, Message);
}
-void Input::setAllowUnknownKeys(bool Allow) { AllowUnknownKeys = Allow; }
-
+void Input::setAllowUnknownKeys(bool Allow) { AllowUnknownKeys = Allow; }
+
bool Input::canElideEmptySequence() {
return false;
}
@@ -592,7 +592,7 @@ void Output::endSequence() {
// If we did not emit anything, we should explicitly emit an empty sequence
if (StateStack.back() == inSeqFirstElement) {
Padding = PaddingBeforeContainer;
- newLineCheck(/*EmptySequence=*/true);
+ newLineCheck(/*EmptySequence=*/true);
output("[]");
Padding = "\n";
}
@@ -798,7 +798,7 @@ void Output::outputNewLine() {
// if seq in middle, use "- " if firstKey, else use " "
//
-void Output::newLineCheck(bool EmptySequence) {
+void Output::newLineCheck(bool EmptySequence) {
if (Padding != "\n") {
output(Padding);
Padding = {};
@@ -807,7 +807,7 @@ void Output::newLineCheck(bool EmptySequence) {
outputNewLine();
Padding = {};
- if (StateStack.size() == 0 || EmptySequence)
+ if (StateStack.size() == 0 || EmptySequence)
return;
unsigned Indent = StateStack.size() - 1;
@@ -884,8 +884,8 @@ void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
}
StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
- if (llvm::Optional<bool> Parsed = parseBool(Scalar)) {
- Val = *Parsed;
+ if (llvm::Optional<bool> Parsed = parseBool(Scalar)) {
+ Val = *Parsed;
return StringRef();
}
return "invalid boolean";
@@ -1056,7 +1056,7 @@ StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
}
void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
- Out << format("0x%" PRIX8, (uint8_t)Val);
+ Out << format("0x%" PRIX8, (uint8_t)Val);
}
StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
@@ -1070,7 +1070,7 @@ StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
}
void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
- Out << format("0x%" PRIX16, (uint16_t)Val);
+ Out << format("0x%" PRIX16, (uint16_t)Val);
}
StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
@@ -1084,7 +1084,7 @@ StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
}
void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
- Out << format("0x%" PRIX32, (uint32_t)Val);
+ Out << format("0x%" PRIX32, (uint32_t)Val);
}
StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
@@ -1098,7 +1098,7 @@ StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
}
void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
- Out << format("0x%" PRIX64, (uint64_t)Val);
+ Out << format("0x%" PRIX64, (uint64_t)Val);
}
StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
@@ -1108,15 +1108,15 @@ StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
Val = Num;
return StringRef();
}
-
-void ScalarTraits<VersionTuple>::output(const VersionTuple &Val, void *,
- llvm::raw_ostream &Out) {
- Out << Val.getAsString();
-}
-
-StringRef ScalarTraits<VersionTuple>::input(StringRef Scalar, void *,
- VersionTuple &Val) {
- if (Val.tryParse(Scalar))
- return "invalid version format";
- return StringRef();
-}
+
+void ScalarTraits<VersionTuple>::output(const VersionTuple &Val, void *,
+ llvm::raw_ostream &Out) {
+ Out << Val.getAsString();
+}
+
+StringRef ScalarTraits<VersionTuple>::input(StringRef Scalar, void *,
+ VersionTuple &Val) {
+ if (Val.tryParse(Scalar))
+ return "invalid version format";
+ return StringRef();
+}
diff --git a/contrib/libs/llvm12/lib/Support/raw_ostream.cpp b/contrib/libs/llvm12/lib/Support/raw_ostream.cpp
index 343806afb5..8f10d136bc 100644
--- a/contrib/libs/llvm12/lib/Support/raw_ostream.cpp
+++ b/contrib/libs/llvm12/lib/Support/raw_ostream.cpp
@@ -618,9 +618,9 @@ raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
/// FD is the file descriptor that this writes to. If ShouldClose is true, this
/// closes the file when the stream is destroyed.
-raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered,
- OStreamKind K)
- : raw_pwrite_stream(unbuffered, K), FD(fd), ShouldClose(shouldClose) {
+raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered,
+ OStreamKind K)
+ : raw_pwrite_stream(unbuffered, K), FD(fd), ShouldClose(shouldClose) {
if (FD < 0 ) {
ShouldClose = false;
return;
@@ -857,26 +857,26 @@ bool raw_fd_ostream::is_displayed() const {
}
bool raw_fd_ostream::has_colors() const {
- if (!HasColors)
- HasColors = sys::Process::FileDescriptorHasColors(FD);
- return *HasColors;
-}
-
-Expected<sys::fs::FileLocker> raw_fd_ostream::lock() {
- std::error_code EC = sys::fs::lockFile(FD);
- if (!EC)
- return sys::fs::FileLocker(FD);
- return errorCodeToError(EC);
-}
-
-Expected<sys::fs::FileLocker>
-raw_fd_ostream::tryLockFor(std::chrono::milliseconds Timeout) {
- std::error_code EC = sys::fs::tryLockFile(FD, Timeout);
- if (!EC)
- return sys::fs::FileLocker(FD);
- return errorCodeToError(EC);
-}
-
+ if (!HasColors)
+ HasColors = sys::Process::FileDescriptorHasColors(FD);
+ return *HasColors;
+}
+
+Expected<sys::fs::FileLocker> raw_fd_ostream::lock() {
+ std::error_code EC = sys::fs::lockFile(FD);
+ if (!EC)
+ return sys::fs::FileLocker(FD);
+ return errorCodeToError(EC);
+}
+
+Expected<sys::fs::FileLocker>
+raw_fd_ostream::tryLockFor(std::chrono::milliseconds Timeout) {
+ std::error_code EC = sys::fs::tryLockFile(FD, Timeout);
+ if (!EC)
+ return sys::fs::FileLocker(FD);
+ return errorCodeToError(EC);
+}
+
void raw_fd_ostream::anchor() {}
//===----------------------------------------------------------------------===//
@@ -904,37 +904,37 @@ raw_ostream &llvm::nulls() {
}
//===----------------------------------------------------------------------===//
-// File Streams
-//===----------------------------------------------------------------------===//
-
-raw_fd_stream::raw_fd_stream(StringRef Filename, std::error_code &EC)
- : raw_fd_ostream(getFD(Filename, EC, sys::fs::CD_CreateAlways,
- sys::fs::FA_Write | sys::fs::FA_Read,
- sys::fs::OF_None),
- true, false, OStreamKind::OK_FDStream) {
- if (EC)
- return;
-
- // Do not support non-seekable files.
- if (!supportsSeeking())
- EC = std::make_error_code(std::errc::invalid_argument);
-}
-
-ssize_t raw_fd_stream::read(char *Ptr, size_t Size) {
- assert(get_fd() >= 0 && "File already closed.");
- ssize_t Ret = ::read(get_fd(), (void *)Ptr, Size);
- if (Ret >= 0)
- inc_pos(Ret);
- else
- error_detected(std::error_code(errno, std::generic_category()));
- return Ret;
-}
-
-bool raw_fd_stream::classof(const raw_ostream *OS) {
- return OS->get_kind() == OStreamKind::OK_FDStream;
-}
-
-//===----------------------------------------------------------------------===//
+// File Streams
+//===----------------------------------------------------------------------===//
+
+raw_fd_stream::raw_fd_stream(StringRef Filename, std::error_code &EC)
+ : raw_fd_ostream(getFD(Filename, EC, sys::fs::CD_CreateAlways,
+ sys::fs::FA_Write | sys::fs::FA_Read,
+ sys::fs::OF_None),
+ true, false, OStreamKind::OK_FDStream) {
+ if (EC)
+ return;
+
+ // Do not support non-seekable files.
+ if (!supportsSeeking())
+ EC = std::make_error_code(std::errc::invalid_argument);
+}
+
+ssize_t raw_fd_stream::read(char *Ptr, size_t Size) {
+ assert(get_fd() >= 0 && "File already closed.");
+ ssize_t Ret = ::read(get_fd(), (void *)Ptr, Size);
+ if (Ret >= 0)
+ inc_pos(Ret);
+ else
+ error_detected(std::error_code(errno, std::generic_category()));
+ return Ret;
+}
+
+bool raw_fd_stream::classof(const raw_ostream *OS) {
+ return OS->get_kind() == OStreamKind::OK_FDStream;
+}
+
+//===----------------------------------------------------------------------===//
// raw_string_ostream
//===----------------------------------------------------------------------===//
@@ -987,5 +987,5 @@ void raw_null_ostream::pwrite_impl(const char *Ptr, size_t Size,
void raw_pwrite_stream::anchor() {}
void buffer_ostream::anchor() {}
-
-void buffer_unique_ostream::anchor() {}
+
+void buffer_unique_ostream::anchor() {}
diff --git a/contrib/libs/llvm12/lib/Support/ya.make b/contrib/libs/llvm12/lib/Support/ya.make
index 0a01d9dadd..b3f49d0f2a 100644
--- a/contrib/libs/llvm12/lib/Support/ya.make
+++ b/contrib/libs/llvm12/lib/Support/ya.make
@@ -21,8 +21,8 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/Demangle
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/Demangle
contrib/libs/zlib
)
@@ -38,7 +38,7 @@ SRCS(
AArch64TargetParser.cpp
ABIBreak.cpp
AMDGPUMetadata.cpp
- APFixedPoint.cpp
+ APFixedPoint.cpp
APFloat.cpp
APInt.cpp
APSInt.cpp
@@ -89,7 +89,7 @@ SRCS(
Hashing.cpp
Host.cpp
InitLLVM.cpp
- InstructionCost.cpp
+ InstructionCost.cpp
IntEqClasses.cpp
IntervalMap.cpp
ItaniumManglingCanonicalizer.cpp
@@ -106,7 +106,7 @@ SRCS(
MemAlloc.cpp
Memory.cpp
MemoryBuffer.cpp
- MemoryBufferRef.cpp
+ MemoryBufferRef.cpp
NativeFormatting.cpp
OptimizedStructLayout.cpp
Optional.cpp
diff --git a/contrib/libs/llvm12/lib/TableGen/DetailedRecordsBackend.cpp b/contrib/libs/llvm12/lib/TableGen/DetailedRecordsBackend.cpp
index c49fd43f44..2c3c3358b3 100644
--- a/contrib/libs/llvm12/lib/TableGen/DetailedRecordsBackend.cpp
+++ b/contrib/libs/llvm12/lib/TableGen/DetailedRecordsBackend.cpp
@@ -1,203 +1,203 @@
-//===- DetailedRecordBackend.cpp - Detailed Records Report -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This Tablegen backend prints a report that includes all the global
-// variables, classes, and records in complete detail. It includes more
-// detail than the default TableGen printer backend.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/FormatVariadic.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/TableGen/Error.h"
-#include "llvm/TableGen/Record.h"
-#include "llvm/TableGen/TableGenBackend.h"
-#include <algorithm>
-#include <set>
-#include <string>
-#include <vector>
-
-#define DEBUG_TYPE "detailed-records-backend"
-
-#define NL "\n"
-
-using namespace llvm;
-
-namespace {
-
-class DetailedRecordsEmitter {
-private:
- RecordKeeper &Records;
-
-public:
- DetailedRecordsEmitter(RecordKeeper &RK) : Records(RK) {}
-
- void run(raw_ostream &OS);
- void printReportHeading(raw_ostream &OS);
- void printVariables(raw_ostream &OS);
- void printClasses(raw_ostream &OS);
- void printRecords(raw_ostream &OS);
- void printSectionHeading(std::string Title, int Count, raw_ostream &OS);
- void printDefms(Record *Rec, raw_ostream &OS);
- void printTemplateArgs(Record *Rec, raw_ostream &OS);
- void printSuperclasses(Record *Rec, raw_ostream &OS);
- void printFields(Record *Rec, raw_ostream &OS);
-}; // emitter class
-
-} // anonymous namespace
-
-// Print the report.
-void DetailedRecordsEmitter::run(raw_ostream &OS) {
- printReportHeading(OS);
- printVariables(OS);
- printClasses(OS);
- printRecords(OS);
-}
-
-// Print the report heading, including the source file name.
-void DetailedRecordsEmitter::printReportHeading(raw_ostream &OS) {
- OS << formatv("DETAILED RECORDS for file {0}\n", Records.getInputFilename());
-}
-
-// Print the global variables.
-void DetailedRecordsEmitter::printVariables(raw_ostream &OS) {
- const auto GlobalList = Records.getGlobals();
- printSectionHeading("Global Variables", GlobalList.size(), OS);
-
- OS << NL;
- for (const auto &Var : GlobalList) {
- OS << Var.first << " = " << Var.second->getAsString() << NL;
- }
-}
-
-// Print the classes, including the template arguments, superclasses,
-// and fields.
-void DetailedRecordsEmitter::printClasses(raw_ostream &OS) {
- const auto &ClassList = Records.getClasses();
- printSectionHeading("Classes", ClassList.size(), OS);
-
- for (const auto &ClassPair : ClassList) {
- auto *const Class = ClassPair.second.get();
- OS << formatv("\n{0} |{1}|\n", Class->getNameInitAsString(),
- SrcMgr.getFormattedLocationNoOffset(Class->getLoc().front()));
- printTemplateArgs(Class, OS);
- printSuperclasses(Class, OS);
- printFields(Class, OS);
- }
-}
-
-// Print the records, including the defm sequences, supercasses,
-// and fields.
-void DetailedRecordsEmitter::printRecords(raw_ostream &OS) {
- const auto &RecordList = Records.getDefs();
- printSectionHeading("Records", RecordList.size(), OS);
-
- for (const auto &RecPair : RecordList) {
- auto *const Rec = RecPair.second.get();
- OS << formatv("\n{0} |{1}|\n", Rec->getNameInitAsString(),
- SrcMgr.getFormattedLocationNoOffset(Rec->getLoc().front()));
- printDefms(Rec, OS);
- printSuperclasses(Rec, OS);
- printFields(Rec, OS);
- }
-}
-
-// Print a section heading with the name of the section and
-// the item count.
-void DetailedRecordsEmitter::printSectionHeading(std::string Title, int Count,
- raw_ostream &OS) {
- OS << formatv("\n{0} {1} ({2}) {0}\n", "--------------------", Title, Count);
-}
-
-// Print the record's defm source locations, if any. Note that they
-// are stored in the reverse order of their invocation.
-void DetailedRecordsEmitter::printDefms(Record *Rec, raw_ostream &OS) {
- const auto &LocList = Rec->getLoc();
- if (LocList.size() < 2)
- return;
-
- OS << " Defm sequence:";
- for (unsigned I = LocList.size() - 1; I >= 1; --I) {
- OS << formatv(" |{0}|", SrcMgr.getFormattedLocationNoOffset(LocList[I]));
- }
- OS << NL;
-}
-
-// Print the template arguments of a class.
-void DetailedRecordsEmitter::printTemplateArgs(Record *Rec,
- raw_ostream &OS) {
- ArrayRef<Init *> Args = Rec->getTemplateArgs();
- if (Args.empty()) {
- OS << " Template args: (none)\n";
- return;
- }
-
- OS << " Template args:\n";
- for (const Init *ArgName : Args) {
- const RecordVal *Value = Rec->getValue(ArgName);
- assert(Value && "Template argument value not found.");
- OS << " ";
- Value->print(OS, false);
- OS << formatv(" |{0}|", SrcMgr.getFormattedLocationNoOffset(Value->getLoc()));
- OS << NL;
- }
-}
-
-// Print the superclasses of a class or record. Indirect superclasses
-// are enclosed in parentheses.
-void DetailedRecordsEmitter::printSuperclasses(Record *Rec, raw_ostream &OS) {
- ArrayRef<std::pair<Record *, SMRange>> Superclasses = Rec->getSuperClasses();
- if (Superclasses.empty()) {
- OS << " Superclasses: (none)\n";
- return;
- }
-
- OS << " Superclasses:";
- for (const auto &SuperclassPair : Superclasses) {
- auto *ClassRec = SuperclassPair.first;
- if (Rec->hasDirectSuperClass(ClassRec))
- OS << formatv(" {0}", ClassRec->getNameInitAsString());
- else
- OS << formatv(" ({0})", ClassRec->getNameInitAsString());
- }
- OS << NL;
-}
-
-// Print the fields of a class or record, including their source locations.
-void DetailedRecordsEmitter::printFields(Record *Rec, raw_ostream &OS) {
- const auto &ValueList = Rec->getValues();
- if (ValueList.empty()) {
- OS << " Fields: (none)\n";
- return;
- }
-
- OS << " Fields:\n";
- for (const RecordVal &Value : ValueList)
- if (!Rec->isTemplateArg(Value.getNameInit())) {
- OS << " ";
- Value.print(OS, false);
- OS << formatv(" |{0}|\n",
- SrcMgr.getFormattedLocationNoOffset(Value.getLoc()));
- }
-}
-
-namespace llvm {
-
-// This function is called by TableGen after parsing the files.
-
-void EmitDetailedRecords(RecordKeeper &RK, raw_ostream &OS) {
- // Instantiate the emitter class and invoke run().
- DetailedRecordsEmitter(RK).run(OS);
-}
-
-} // namespace llvm
+//===- DetailedRecordBackend.cpp - Detailed Records Report -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This Tablegen backend prints a report that includes all the global
+// variables, classes, and records in complete detail. It includes more
+// detail than the default TableGen printer backend.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
+#include <algorithm>
+#include <set>
+#include <string>
+#include <vector>
+
+#define DEBUG_TYPE "detailed-records-backend"
+
+#define NL "\n"
+
+using namespace llvm;
+
+namespace {
+
+class DetailedRecordsEmitter {
+private:
+ RecordKeeper &Records;
+
+public:
+ DetailedRecordsEmitter(RecordKeeper &RK) : Records(RK) {}
+
+ void run(raw_ostream &OS);
+ void printReportHeading(raw_ostream &OS);
+ void printVariables(raw_ostream &OS);
+ void printClasses(raw_ostream &OS);
+ void printRecords(raw_ostream &OS);
+ void printSectionHeading(std::string Title, int Count, raw_ostream &OS);
+ void printDefms(Record *Rec, raw_ostream &OS);
+ void printTemplateArgs(Record *Rec, raw_ostream &OS);
+ void printSuperclasses(Record *Rec, raw_ostream &OS);
+ void printFields(Record *Rec, raw_ostream &OS);
+}; // emitter class
+
+} // anonymous namespace
+
+// Print the report.
+void DetailedRecordsEmitter::run(raw_ostream &OS) {
+ printReportHeading(OS);
+ printVariables(OS);
+ printClasses(OS);
+ printRecords(OS);
+}
+
+// Print the report heading, including the source file name.
+void DetailedRecordsEmitter::printReportHeading(raw_ostream &OS) {
+ OS << formatv("DETAILED RECORDS for file {0}\n", Records.getInputFilename());
+}
+
+// Print the global variables.
+void DetailedRecordsEmitter::printVariables(raw_ostream &OS) {
+ const auto GlobalList = Records.getGlobals();
+ printSectionHeading("Global Variables", GlobalList.size(), OS);
+
+ OS << NL;
+ for (const auto &Var : GlobalList) {
+ OS << Var.first << " = " << Var.second->getAsString() << NL;
+ }
+}
+
+// Print the classes, including the template arguments, superclasses,
+// and fields.
+void DetailedRecordsEmitter::printClasses(raw_ostream &OS) {
+ const auto &ClassList = Records.getClasses();
+ printSectionHeading("Classes", ClassList.size(), OS);
+
+ for (const auto &ClassPair : ClassList) {
+ auto *const Class = ClassPair.second.get();
+ OS << formatv("\n{0} |{1}|\n", Class->getNameInitAsString(),
+ SrcMgr.getFormattedLocationNoOffset(Class->getLoc().front()));
+ printTemplateArgs(Class, OS);
+ printSuperclasses(Class, OS);
+ printFields(Class, OS);
+ }
+}
+
+// Print the records, including the defm sequences, supercasses,
+// and fields.
+void DetailedRecordsEmitter::printRecords(raw_ostream &OS) {
+ const auto &RecordList = Records.getDefs();
+ printSectionHeading("Records", RecordList.size(), OS);
+
+ for (const auto &RecPair : RecordList) {
+ auto *const Rec = RecPair.second.get();
+ OS << formatv("\n{0} |{1}|\n", Rec->getNameInitAsString(),
+ SrcMgr.getFormattedLocationNoOffset(Rec->getLoc().front()));
+ printDefms(Rec, OS);
+ printSuperclasses(Rec, OS);
+ printFields(Rec, OS);
+ }
+}
+
+// Print a section heading with the name of the section and
+// the item count.
+void DetailedRecordsEmitter::printSectionHeading(std::string Title, int Count,
+ raw_ostream &OS) {
+ OS << formatv("\n{0} {1} ({2}) {0}\n", "--------------------", Title, Count);
+}
+
+// Print the record's defm source locations, if any. Note that they
+// are stored in the reverse order of their invocation.
+void DetailedRecordsEmitter::printDefms(Record *Rec, raw_ostream &OS) {
+ const auto &LocList = Rec->getLoc();
+ if (LocList.size() < 2)
+ return;
+
+ OS << " Defm sequence:";
+ for (unsigned I = LocList.size() - 1; I >= 1; --I) {
+ OS << formatv(" |{0}|", SrcMgr.getFormattedLocationNoOffset(LocList[I]));
+ }
+ OS << NL;
+}
+
+// Print the template arguments of a class.
+void DetailedRecordsEmitter::printTemplateArgs(Record *Rec,
+ raw_ostream &OS) {
+ ArrayRef<Init *> Args = Rec->getTemplateArgs();
+ if (Args.empty()) {
+ OS << " Template args: (none)\n";
+ return;
+ }
+
+ OS << " Template args:\n";
+ for (const Init *ArgName : Args) {
+ const RecordVal *Value = Rec->getValue(ArgName);
+ assert(Value && "Template argument value not found.");
+ OS << " ";
+ Value->print(OS, false);
+ OS << formatv(" |{0}|", SrcMgr.getFormattedLocationNoOffset(Value->getLoc()));
+ OS << NL;
+ }
+}
+
+// Print the superclasses of a class or record. Indirect superclasses
+// are enclosed in parentheses.
+void DetailedRecordsEmitter::printSuperclasses(Record *Rec, raw_ostream &OS) {
+ ArrayRef<std::pair<Record *, SMRange>> Superclasses = Rec->getSuperClasses();
+ if (Superclasses.empty()) {
+ OS << " Superclasses: (none)\n";
+ return;
+ }
+
+ OS << " Superclasses:";
+ for (const auto &SuperclassPair : Superclasses) {
+ auto *ClassRec = SuperclassPair.first;
+ if (Rec->hasDirectSuperClass(ClassRec))
+ OS << formatv(" {0}", ClassRec->getNameInitAsString());
+ else
+ OS << formatv(" ({0})", ClassRec->getNameInitAsString());
+ }
+ OS << NL;
+}
+
+// Print the fields of a class or record, including their source locations.
+void DetailedRecordsEmitter::printFields(Record *Rec, raw_ostream &OS) {
+ const auto &ValueList = Rec->getValues();
+ if (ValueList.empty()) {
+ OS << " Fields: (none)\n";
+ return;
+ }
+
+ OS << " Fields:\n";
+ for (const RecordVal &Value : ValueList)
+ if (!Rec->isTemplateArg(Value.getNameInit())) {
+ OS << " ";
+ Value.print(OS, false);
+ OS << formatv(" |{0}|\n",
+ SrcMgr.getFormattedLocationNoOffset(Value.getLoc()));
+ }
+}
+
+namespace llvm {
+
+// This function is called by TableGen after parsing the files.
+
+void EmitDetailedRecords(RecordKeeper &RK, raw_ostream &OS) {
+ // Instantiate the emitter class and invoke run().
+ DetailedRecordsEmitter(RK).run(OS);
+}
+
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/TableGen/Error.cpp b/contrib/libs/llvm12/lib/TableGen/Error.cpp
index a80302097e..eed4de6794 100644
--- a/contrib/libs/llvm12/lib/TableGen/Error.cpp
+++ b/contrib/libs/llvm12/lib/TableGen/Error.cpp
@@ -12,11 +12,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/Twine.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/WithColor.h"
-#include "llvm/TableGen/Error.h"
-#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
#include <cstdlib>
namespace llvm {
@@ -40,54 +40,54 @@ static void PrintMessage(ArrayRef<SMLoc> Loc, SourceMgr::DiagKind Kind,
"instantiated from multiclass");
}
-// Functions to print notes.
+// Functions to print notes.
+
+void PrintNote(const Twine &Msg) {
+ WithColor::note() << Msg << "\n";
+}
-void PrintNote(const Twine &Msg) {
- WithColor::note() << Msg << "\n";
-}
-
void PrintNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg) {
PrintMessage(NoteLoc, SourceMgr::DK_Note, Msg);
}
-// Functions to print fatal notes.
-
-void PrintFatalNote(const Twine &Msg) {
- PrintNote(Msg);
- // The following call runs the file cleanup handlers.
- sys::RunInterruptHandlers();
- std::exit(1);
-}
-
-void PrintFatalNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg) {
- PrintNote(NoteLoc, Msg);
- // The following call runs the file cleanup handlers.
- sys::RunInterruptHandlers();
- std::exit(1);
-}
-
-// This method takes a Record and uses the source location
-// stored in it.
-void PrintFatalNote(const Record *Rec, const Twine &Msg) {
- PrintNote(Rec->getLoc(), Msg);
- // The following call runs the file cleanup handlers.
- sys::RunInterruptHandlers();
- std::exit(1);
-}
-
-// This method takes a RecordVal and uses the source location
-// stored in it.
-void PrintFatalNote(const RecordVal *RecVal, const Twine &Msg) {
- PrintNote(RecVal->getLoc(), Msg);
- // The following call runs the file cleanup handlers.
- sys::RunInterruptHandlers();
- std::exit(1);
-}
-
-// Functions to print warnings.
-
-void PrintWarning(const Twine &Msg) { WithColor::warning() << Msg << "\n"; }
-
+// Functions to print fatal notes.
+
+void PrintFatalNote(const Twine &Msg) {
+ PrintNote(Msg);
+ // The following call runs the file cleanup handlers.
+ sys::RunInterruptHandlers();
+ std::exit(1);
+}
+
+void PrintFatalNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg) {
+ PrintNote(NoteLoc, Msg);
+ // The following call runs the file cleanup handlers.
+ sys::RunInterruptHandlers();
+ std::exit(1);
+}
+
+// This method takes a Record and uses the source location
+// stored in it.
+void PrintFatalNote(const Record *Rec, const Twine &Msg) {
+ PrintNote(Rec->getLoc(), Msg);
+ // The following call runs the file cleanup handlers.
+ sys::RunInterruptHandlers();
+ std::exit(1);
+}
+
+// This method takes a RecordVal and uses the source location
+// stored in it.
+void PrintFatalNote(const RecordVal *RecVal, const Twine &Msg) {
+ PrintNote(RecVal->getLoc(), Msg);
+ // The following call runs the file cleanup handlers.
+ sys::RunInterruptHandlers();
+ std::exit(1);
+}
+
+// Functions to print warnings.
+
+void PrintWarning(const Twine &Msg) { WithColor::warning() << Msg << "\n"; }
+
void PrintWarning(ArrayRef<SMLoc> WarningLoc, const Twine &Msg) {
PrintMessage(WarningLoc, SourceMgr::DK_Warning, Msg);
}
@@ -96,10 +96,10 @@ void PrintWarning(const char *Loc, const Twine &Msg) {
SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Warning, Msg);
}
-// Functions to print errors.
+// Functions to print errors.
+
+void PrintError(const Twine &Msg) { WithColor::error() << Msg << "\n"; }
-void PrintError(const Twine &Msg) { WithColor::error() << Msg << "\n"; }
-
void PrintError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg) {
PrintMessage(ErrorLoc, SourceMgr::DK_Error, Msg);
}
@@ -108,20 +108,20 @@ void PrintError(const char *Loc, const Twine &Msg) {
SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Error, Msg);
}
-// This method takes a Record and uses the source location
-// stored in it.
-void PrintError(const Record *Rec, const Twine &Msg) {
- PrintMessage(Rec->getLoc(), SourceMgr::DK_Error, Msg);
-}
-
-// This method takes a RecordVal and uses the source location
-// stored in it.
-void PrintError(const RecordVal *RecVal, const Twine &Msg) {
- PrintMessage(RecVal->getLoc(), SourceMgr::DK_Error, Msg);
-}
-
-// Functions to print fatal errors.
-
+// This method takes a Record and uses the source location
+// stored in it.
+void PrintError(const Record *Rec, const Twine &Msg) {
+ PrintMessage(Rec->getLoc(), SourceMgr::DK_Error, Msg);
+}
+
+// This method takes a RecordVal and uses the source location
+// stored in it.
+void PrintError(const RecordVal *RecVal, const Twine &Msg) {
+ PrintMessage(RecVal->getLoc(), SourceMgr::DK_Error, Msg);
+}
+
+// Functions to print fatal errors.
+
void PrintFatalError(const Twine &Msg) {
PrintError(Msg);
// The following call runs the file cleanup handlers.
@@ -136,22 +136,22 @@ void PrintFatalError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg) {
std::exit(1);
}
-// This method takes a Record and uses the source location
-// stored in it.
-void PrintFatalError(const Record *Rec, const Twine &Msg) {
- PrintError(Rec->getLoc(), Msg);
- // The following call runs the file cleanup handlers.
- sys::RunInterruptHandlers();
- std::exit(1);
-}
-
-// This method takes a RecordVal and uses the source location
-// stored in it.
-void PrintFatalError(const RecordVal *RecVal, const Twine &Msg) {
- PrintError(RecVal->getLoc(), Msg);
- // The following call runs the file cleanup handlers.
- sys::RunInterruptHandlers();
- std::exit(1);
-}
-
+// This method takes a Record and uses the source location
+// stored in it.
+void PrintFatalError(const Record *Rec, const Twine &Msg) {
+ PrintError(Rec->getLoc(), Msg);
+ // The following call runs the file cleanup handlers.
+ sys::RunInterruptHandlers();
+ std::exit(1);
+}
+
+// This method takes a RecordVal and uses the source location
+// stored in it.
+void PrintFatalError(const RecordVal *RecVal, const Twine &Msg) {
+ PrintError(RecVal->getLoc(), Msg);
+ // The following call runs the file cleanup handlers.
+ sys::RunInterruptHandlers();
+ std::exit(1);
+}
+
} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/TableGen/JSONBackend.cpp b/contrib/libs/llvm12/lib/TableGen/JSONBackend.cpp
index f34ae8174d..8ddfd9f045 100644
--- a/contrib/libs/llvm12/lib/TableGen/JSONBackend.cpp
+++ b/contrib/libs/llvm12/lib/TableGen/JSONBackend.cpp
@@ -144,7 +144,7 @@ void JSONEmitter::run(raw_ostream &OS) {
for (const RecordVal &RV : Def.getValues()) {
if (!Def.isTemplateArg(RV.getNameInit())) {
auto Name = RV.getNameInitAsString();
- if (RV.isNonconcreteOK())
+ if (RV.isNonconcreteOK())
fields.push_back(Name);
obj[Name] = translateInit(*RV.getValue());
}
diff --git a/contrib/libs/llvm12/lib/TableGen/Main.cpp b/contrib/libs/llvm12/lib/TableGen/Main.cpp
index b20c794f4c..0ace5363dd 100644
--- a/contrib/libs/llvm12/lib/TableGen/Main.cpp
+++ b/contrib/libs/llvm12/lib/TableGen/Main.cpp
@@ -52,9 +52,9 @@ MacroNames("D", cl::desc("Name of the macro to be defined"),
static cl::opt<bool>
WriteIfChanged("write-if-changed", cl::desc("Only write output if it changed"));
-static cl::opt<bool>
-TimePhases("time-phases", cl::desc("Time phases of parser and backend"));
-
+static cl::opt<bool>
+TimePhases("time-phases", cl::desc("Time phases of parser and backend"));
+
static int reportError(const char *ProgName, Twine Msg) {
errs() << ProgName << ": " << Msg;
errs().flush();
@@ -86,20 +86,20 @@ static int createDependencyFile(const TGParser &Parser, const char *argv0) {
int llvm::TableGenMain(const char *argv0, TableGenMainFn *MainFn) {
RecordKeeper Records;
- if (TimePhases)
- Records.startPhaseTiming();
-
+ if (TimePhases)
+ Records.startPhaseTiming();
+
// Parse the input file.
-
- Records.startTimer("Parse, build records");
+
+ Records.startTimer("Parse, build records");
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
MemoryBuffer::getFileOrSTDIN(InputFilename);
if (std::error_code EC = FileOrErr.getError())
return reportError(argv0, "Could not open input file '" + InputFilename +
"': " + EC.message() + "\n");
- Records.saveInputFilename(InputFilename);
-
+ Records.saveInputFilename(InputFilename);
+
// Tell SrcMgr about this buffer, which is what TGParser will pick up.
SrcMgr.AddNewSourceBuffer(std::move(*FileOrErr), SMLoc());
@@ -111,15 +111,15 @@ int llvm::TableGenMain(const char *argv0, TableGenMainFn *MainFn) {
if (Parser.ParseFile())
return 1;
- Records.stopTimer();
+ Records.stopTimer();
// Write output to memory.
- Records.startBackendTimer("Backend overall");
+ Records.startBackendTimer("Backend overall");
std::string OutString;
raw_string_ostream Out(OutString);
- unsigned status = MainFn(Out, Records);
- Records.stopBackendTimer();
- if (status)
+ unsigned status = MainFn(Out, Records);
+ Records.stopBackendTimer();
+ if (status)
return 1;
// Always write the depfile, even if the main output hasn't changed.
@@ -131,29 +131,29 @@ int llvm::TableGenMain(const char *argv0, TableGenMainFn *MainFn) {
return Ret;
}
- Records.startTimer("Write output");
- bool WriteFile = true;
+ Records.startTimer("Write output");
+ bool WriteFile = true;
if (WriteIfChanged) {
// Only updates the real output file if there are any differences.
// This prevents recompilation of all the files depending on it if there
// aren't any.
if (auto ExistingOrErr = MemoryBuffer::getFile(OutputFilename))
if (std::move(ExistingOrErr.get())->getBuffer() == Out.str())
- WriteFile = false;
+ WriteFile = false;
+ }
+ if (WriteFile) {
+ std::error_code EC;
+ ToolOutputFile OutFile(OutputFilename, EC, sys::fs::OF_None);
+ if (EC)
+ return reportError(argv0, "error opening " + OutputFilename + ": " +
+ EC.message() + "\n");
+ OutFile.os() << Out.str();
+ if (ErrorsPrinted == 0)
+ OutFile.keep();
}
- if (WriteFile) {
- std::error_code EC;
- ToolOutputFile OutFile(OutputFilename, EC, sys::fs::OF_None);
- if (EC)
- return reportError(argv0, "error opening " + OutputFilename + ": " +
- EC.message() + "\n");
- OutFile.os() << Out.str();
- if (ErrorsPrinted == 0)
- OutFile.keep();
- }
-
- Records.stopTimer();
- Records.stopPhaseTiming();
+
+ Records.stopTimer();
+ Records.stopPhaseTiming();
if (ErrorsPrinted > 0)
return reportError(argv0, Twine(ErrorsPrinted) + " errors.\n");
diff --git a/contrib/libs/llvm12/lib/TableGen/Record.cpp b/contrib/libs/llvm12/lib/TableGen/Record.cpp
index 5caaecf70d..b6c6b8f031 100644
--- a/contrib/libs/llvm12/lib/TableGen/Record.cpp
+++ b/contrib/libs/llvm12/lib/TableGen/Record.cpp
@@ -115,16 +115,16 @@ std::string StringRecTy::getAsString() const {
bool StringRecTy::typeIsConvertibleTo(const RecTy *RHS) const {
RecTyKind Kind = RHS->getRecTyKind();
- return Kind == StringRecTyKind;
+ return Kind == StringRecTyKind;
}
std::string ListRecTy::getAsString() const {
- return "list<" + ElementTy->getAsString() + ">";
+ return "list<" + ElementTy->getAsString() + ">";
}
bool ListRecTy::typeIsConvertibleTo(const RecTy *RHS) const {
if (const auto *ListTy = dyn_cast<ListRecTy>(RHS))
- return ElementTy->typeIsConvertibleTo(ListTy->getElementType());
+ return ElementTy->typeIsConvertibleTo(ListTy->getElementType());
return false;
}
@@ -232,10 +232,10 @@ bool RecordRecTy::typeIsA(const RecTy *RHS) const {
static RecordRecTy *resolveRecordTypes(RecordRecTy *T1, RecordRecTy *T2) {
SmallVector<Record *, 4> CommonSuperClasses;
- SmallVector<Record *, 4> Stack(T1->classes_begin(), T1->classes_end());
+ SmallVector<Record *, 4> Stack(T1->classes_begin(), T1->classes_end());
while (!Stack.empty()) {
- Record *R = Stack.pop_back_val();
+ Record *R = Stack.pop_back_val();
if (T2->isSubClassOf(R)) {
CommonSuperClasses.push_back(R);
@@ -502,21 +502,21 @@ IntInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
return BitsInit::get(NewBits);
}
-StringInit *StringInit::get(StringRef V, StringFormat Fmt) {
- static StringMap<StringInit*, BumpPtrAllocator &> StringPool(Allocator);
- static StringMap<StringInit*, BumpPtrAllocator &> CodePool(Allocator);
+StringInit *StringInit::get(StringRef V, StringFormat Fmt) {
+ static StringMap<StringInit*, BumpPtrAllocator &> StringPool(Allocator);
+ static StringMap<StringInit*, BumpPtrAllocator &> CodePool(Allocator);
- if (Fmt == SF_String) {
- auto &Entry = *StringPool.insert(std::make_pair(V, nullptr)).first;
- if (!Entry.second)
- Entry.second = new (Allocator) StringInit(Entry.getKey(), Fmt);
- return Entry.second;
- } else {
- auto &Entry = *CodePool.insert(std::make_pair(V, nullptr)).first;
- if (!Entry.second)
- Entry.second = new (Allocator) StringInit(Entry.getKey(), Fmt);
- return Entry.second;
- }
+ if (Fmt == SF_String) {
+ auto &Entry = *StringPool.insert(std::make_pair(V, nullptr)).first;
+ if (!Entry.second)
+ Entry.second = new (Allocator) StringInit(Entry.getKey(), Fmt);
+ return Entry.second;
+ } else {
+ auto &Entry = *CodePool.insert(std::make_pair(V, nullptr)).first;
+ if (!Entry.second)
+ Entry.second = new (Allocator) StringInit(Entry.getKey(), Fmt);
+ return Entry.second;
+ }
}
Init *StringInit::convertInitializerTo(RecTy *Ty) const {
@@ -688,10 +688,10 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
if (DefInit *LHSd = dyn_cast<DefInit>(LHS))
return StringInit::get(LHSd->getAsString());
- if (IntInit *LHSi =
- dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get())))
+ if (IntInit *LHSi =
+ dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get())))
return StringInit::get(LHSi->getAsString());
-
+
} else if (isa<RecordRecTy>(getType())) {
if (StringInit *Name = dyn_cast<StringInit>(LHS)) {
if (!CurRec && !IsFinal)
@@ -732,12 +732,12 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
return NewInit;
break;
- case NOT:
- if (IntInit *LHSi =
- dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get())))
- return IntInit::get(LHSi->getValue() ? 0 : 1);
- break;
-
+ case NOT:
+ if (IntInit *LHSi =
+ dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get())))
+ return IntInit::get(LHSi->getValue() ? 0 : 1);
+ break;
+
case HEAD:
if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
assert(!LHSl->empty() && "Empty list in head");
@@ -757,22 +757,22 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
case SIZE:
if (ListInit *LHSl = dyn_cast<ListInit>(LHS))
return IntInit::get(LHSl->size());
- if (DagInit *LHSd = dyn_cast<DagInit>(LHS))
- return IntInit::get(LHSd->arg_size());
- if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
- return IntInit::get(LHSs->getValue().size());
+ if (DagInit *LHSd = dyn_cast<DagInit>(LHS))
+ return IntInit::get(LHSd->arg_size());
+ if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
+ return IntInit::get(LHSs->getValue().size());
break;
case EMPTY:
if (ListInit *LHSl = dyn_cast<ListInit>(LHS))
return IntInit::get(LHSl->empty());
- if (DagInit *LHSd = dyn_cast<DagInit>(LHS))
- return IntInit::get(LHSd->arg_empty());
+ if (DagInit *LHSd = dyn_cast<DagInit>(LHS))
+ return IntInit::get(LHSd->arg_empty());
if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
return IntInit::get(LHSs->getValue().empty());
break;
- case GETDAGOP:
+ case GETDAGOP:
if (DagInit *Dag = dyn_cast<DagInit>(LHS)) {
DefInit *DI = DefInit::get(Dag->getOperatorAsDef({}));
if (!DI->getType()->typeIsA(getType())) {
@@ -803,12 +803,12 @@ std::string UnOpInit::getAsString() const {
std::string Result;
switch (getOpcode()) {
case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break;
- case NOT: Result = "!not"; break;
+ case NOT: Result = "!not"; break;
case HEAD: Result = "!head"; break;
case TAIL: Result = "!tail"; break;
case SIZE: Result = "!size"; break;
case EMPTY: Result = "!empty"; break;
- case GETDAGOP: Result = "!getdagop"; break;
+ case GETDAGOP: Result = "!getdagop"; break;
}
return Result + "(" + LHS->getAsString() + ")";
}
@@ -846,55 +846,55 @@ static StringInit *ConcatStringInits(const StringInit *I0,
const StringInit *I1) {
SmallString<80> Concat(I0->getValue());
Concat.append(I1->getValue());
- return StringInit::get(Concat,
- StringInit::determineFormat(I0->getFormat(),
- I1->getFormat()));
-}
-
-static StringInit *interleaveStringList(const ListInit *List,
- const StringInit *Delim) {
- if (List->size() == 0)
- return StringInit::get("");
- StringInit *Element = dyn_cast<StringInit>(List->getElement(0));
- if (!Element)
- return nullptr;
- SmallString<80> Result(Element->getValue());
- StringInit::StringFormat Fmt = StringInit::SF_String;
-
- for (unsigned I = 1, E = List->size(); I < E; ++I) {
- Result.append(Delim->getValue());
- StringInit *Element = dyn_cast<StringInit>(List->getElement(I));
- if (!Element)
- return nullptr;
- Result.append(Element->getValue());
- Fmt = StringInit::determineFormat(Fmt, Element->getFormat());
- }
- return StringInit::get(Result, Fmt);
-}
-
-static StringInit *interleaveIntList(const ListInit *List,
- const StringInit *Delim) {
- if (List->size() == 0)
- return StringInit::get("");
- IntInit *Element =
- dyn_cast_or_null<IntInit>(List->getElement(0)
- ->convertInitializerTo(IntRecTy::get()));
- if (!Element)
- return nullptr;
- SmallString<80> Result(Element->getAsString());
-
- for (unsigned I = 1, E = List->size(); I < E; ++I) {
- Result.append(Delim->getValue());
- IntInit *Element =
- dyn_cast_or_null<IntInit>(List->getElement(I)
- ->convertInitializerTo(IntRecTy::get()));
- if (!Element)
- return nullptr;
- Result.append(Element->getAsString());
- }
- return StringInit::get(Result);
-}
-
+ return StringInit::get(Concat,
+ StringInit::determineFormat(I0->getFormat(),
+ I1->getFormat()));
+}
+
+static StringInit *interleaveStringList(const ListInit *List,
+ const StringInit *Delim) {
+ if (List->size() == 0)
+ return StringInit::get("");
+ StringInit *Element = dyn_cast<StringInit>(List->getElement(0));
+ if (!Element)
+ return nullptr;
+ SmallString<80> Result(Element->getValue());
+ StringInit::StringFormat Fmt = StringInit::SF_String;
+
+ for (unsigned I = 1, E = List->size(); I < E; ++I) {
+ Result.append(Delim->getValue());
+ StringInit *Element = dyn_cast<StringInit>(List->getElement(I));
+ if (!Element)
+ return nullptr;
+ Result.append(Element->getValue());
+ Fmt = StringInit::determineFormat(Fmt, Element->getFormat());
+ }
+ return StringInit::get(Result, Fmt);
+}
+
+static StringInit *interleaveIntList(const ListInit *List,
+ const StringInit *Delim) {
+ if (List->size() == 0)
+ return StringInit::get("");
+ IntInit *Element =
+ dyn_cast_or_null<IntInit>(List->getElement(0)
+ ->convertInitializerTo(IntRecTy::get()));
+ if (!Element)
+ return nullptr;
+ SmallString<80> Result(Element->getAsString());
+
+ for (unsigned I = 1, E = List->size(); I < E; ++I) {
+ Result.append(Delim->getValue());
+ IntInit *Element =
+ dyn_cast_or_null<IntInit>(List->getElement(I)
+ ->convertInitializerTo(IntRecTy::get()));
+ if (!Element)
+ return nullptr;
+ Result.append(Element->getAsString());
+ }
+ return StringInit::get(Result);
+}
+
Init *BinOpInit::getStrConcat(Init *I0, Init *I1) {
// Shortcut for the common case of concatenating two strings.
if (const StringInit *I0s = dyn_cast<StringInit>(I0))
@@ -906,8 +906,8 @@ Init *BinOpInit::getStrConcat(Init *I0, Init *I1) {
static ListInit *ConcatListInits(const ListInit *LHS,
const ListInit *RHS) {
SmallVector<Init *, 8> Args;
- llvm::append_range(Args, *LHS);
- llvm::append_range(Args, *RHS);
+ llvm::append_range(Args, *LHS);
+ llvm::append_range(Args, *RHS);
return ListInit::get(Args, LHS->getElementType());
}
@@ -960,8 +960,8 @@ Init *BinOpInit::Fold(Record *CurRec) const {
ListInit *RHSs = dyn_cast<ListInit>(RHS);
if (LHSs && RHSs) {
SmallVector<Init *, 8> Args;
- llvm::append_range(Args, *LHSs);
- llvm::append_range(Args, *RHSs);
+ llvm::append_range(Args, *LHSs);
+ llvm::append_range(Args, *RHSs);
return ListInit::get(Args, LHSs->getElementType());
}
break;
@@ -982,76 +982,76 @@ Init *BinOpInit::Fold(Record *CurRec) const {
return ConcatStringInits(LHSs, RHSs);
break;
}
- case INTERLEAVE: {
- ListInit *List = dyn_cast<ListInit>(LHS);
- StringInit *Delim = dyn_cast<StringInit>(RHS);
- if (List && Delim) {
- StringInit *Result;
- if (isa<StringRecTy>(List->getElementType()))
- Result = interleaveStringList(List, Delim);
- else
- Result = interleaveIntList(List, Delim);
- if (Result)
- return Result;
- }
- break;
- }
+ case INTERLEAVE: {
+ ListInit *List = dyn_cast<ListInit>(LHS);
+ StringInit *Delim = dyn_cast<StringInit>(RHS);
+ if (List && Delim) {
+ StringInit *Result;
+ if (isa<StringRecTy>(List->getElementType()))
+ Result = interleaveStringList(List, Delim);
+ else
+ Result = interleaveIntList(List, Delim);
+ if (Result)
+ return Result;
+ }
+ break;
+ }
case EQ:
case NE:
case LE:
case LT:
case GE:
case GT: {
- // First see if we have two bit, bits, or int.
- IntInit *LHSi =
+ // First see if we have two bit, bits, or int.
+ IntInit *LHSi =
dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get()));
- IntInit *RHSi =
+ IntInit *RHSi =
dyn_cast_or_null<IntInit>(RHS->convertInitializerTo(IntRecTy::get()));
- if (LHSi && RHSi) {
+ if (LHSi && RHSi) {
bool Result;
switch (getOpcode()) {
- case EQ: Result = LHSi->getValue() == RHSi->getValue(); break;
- case NE: Result = LHSi->getValue() != RHSi->getValue(); break;
- case LE: Result = LHSi->getValue() <= RHSi->getValue(); break;
- case LT: Result = LHSi->getValue() < RHSi->getValue(); break;
- case GE: Result = LHSi->getValue() >= RHSi->getValue(); break;
- case GT: Result = LHSi->getValue() > RHSi->getValue(); break;
+ case EQ: Result = LHSi->getValue() == RHSi->getValue(); break;
+ case NE: Result = LHSi->getValue() != RHSi->getValue(); break;
+ case LE: Result = LHSi->getValue() <= RHSi->getValue(); break;
+ case LT: Result = LHSi->getValue() < RHSi->getValue(); break;
+ case GE: Result = LHSi->getValue() >= RHSi->getValue(); break;
+ case GT: Result = LHSi->getValue() > RHSi->getValue(); break;
default: llvm_unreachable("unhandled comparison");
}
return BitInit::get(Result);
}
- // Next try strings.
- StringInit *LHSs = dyn_cast<StringInit>(LHS);
- StringInit *RHSs = dyn_cast<StringInit>(RHS);
-
- if (LHSs && RHSs) {
- bool Result;
- switch (getOpcode()) {
- case EQ: Result = LHSs->getValue() == RHSs->getValue(); break;
- case NE: Result = LHSs->getValue() != RHSs->getValue(); break;
- case LE: Result = LHSs->getValue() <= RHSs->getValue(); break;
- case LT: Result = LHSs->getValue() < RHSs->getValue(); break;
- case GE: Result = LHSs->getValue() >= RHSs->getValue(); break;
- case GT: Result = LHSs->getValue() > RHSs->getValue(); break;
- default: llvm_unreachable("unhandled comparison");
+ // Next try strings.
+ StringInit *LHSs = dyn_cast<StringInit>(LHS);
+ StringInit *RHSs = dyn_cast<StringInit>(RHS);
+
+ if (LHSs && RHSs) {
+ bool Result;
+ switch (getOpcode()) {
+ case EQ: Result = LHSs->getValue() == RHSs->getValue(); break;
+ case NE: Result = LHSs->getValue() != RHSs->getValue(); break;
+ case LE: Result = LHSs->getValue() <= RHSs->getValue(); break;
+ case LT: Result = LHSs->getValue() < RHSs->getValue(); break;
+ case GE: Result = LHSs->getValue() >= RHSs->getValue(); break;
+ case GT: Result = LHSs->getValue() > RHSs->getValue(); break;
+ default: llvm_unreachable("unhandled comparison");
}
- return BitInit::get(Result);
+ return BitInit::get(Result);
+ }
+
+ // Finally, !eq and !ne can be used with records.
+ if (getOpcode() == EQ || getOpcode() == NE) {
+ DefInit *LHSd = dyn_cast<DefInit>(LHS);
+ DefInit *RHSd = dyn_cast<DefInit>(RHS);
+ if (LHSd && RHSd)
+ return BitInit::get((getOpcode() == EQ) ? LHSd == RHSd
+ : LHSd != RHSd);
}
- // Finally, !eq and !ne can be used with records.
- if (getOpcode() == EQ || getOpcode() == NE) {
- DefInit *LHSd = dyn_cast<DefInit>(LHS);
- DefInit *RHSd = dyn_cast<DefInit>(RHS);
- if (LHSd && RHSd)
- return BitInit::get((getOpcode() == EQ) ? LHSd == RHSd
- : LHSd != RHSd);
- }
-
break;
}
- case SETDAGOP: {
+ case SETDAGOP: {
DagInit *Dag = dyn_cast<DagInit>(LHS);
DefInit *Op = dyn_cast<DefInit>(RHS);
if (Dag && Op) {
@@ -1066,11 +1066,11 @@ Init *BinOpInit::Fold(Record *CurRec) const {
break;
}
case ADD:
- case SUB:
+ case SUB:
case MUL:
case AND:
case OR:
- case XOR:
+ case XOR:
case SHL:
case SRA:
case SRL: {
@@ -1083,12 +1083,12 @@ Init *BinOpInit::Fold(Record *CurRec) const {
int64_t Result;
switch (getOpcode()) {
default: llvm_unreachable("Bad opcode!");
- case ADD: Result = LHSv + RHSv; break;
- case SUB: Result = LHSv - RHSv; break;
- case MUL: Result = LHSv * RHSv; break;
- case AND: Result = LHSv & RHSv; break;
- case OR: Result = LHSv | RHSv; break;
- case XOR: Result = LHSv ^ RHSv; break;
+ case ADD: Result = LHSv + RHSv; break;
+ case SUB: Result = LHSv - RHSv; break;
+ case MUL: Result = LHSv * RHSv; break;
+ case AND: Result = LHSv & RHSv; break;
+ case OR: Result = LHSv | RHSv; break;
+ case XOR: Result = LHSv ^ RHSv; break;
case SHL: Result = (uint64_t)LHSv << (uint64_t)RHSv; break;
case SRA: Result = LHSv >> RHSv; break;
case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break;
@@ -1116,11 +1116,11 @@ std::string BinOpInit::getAsString() const {
switch (getOpcode()) {
case CONCAT: Result = "!con"; break;
case ADD: Result = "!add"; break;
- case SUB: Result = "!sub"; break;
+ case SUB: Result = "!sub"; break;
case MUL: Result = "!mul"; break;
case AND: Result = "!and"; break;
case OR: Result = "!or"; break;
- case XOR: Result = "!xor"; break;
+ case XOR: Result = "!xor"; break;
case SHL: Result = "!shl"; break;
case SRA: Result = "!sra"; break;
case SRL: Result = "!srl"; break;
@@ -1133,8 +1133,8 @@ std::string BinOpInit::getAsString() const {
case LISTCONCAT: Result = "!listconcat"; break;
case LISTSPLAT: Result = "!listsplat"; break;
case STRCONCAT: Result = "!strconcat"; break;
- case INTERLEAVE: Result = "!interleave"; break;
- case SETDAGOP: Result = "!setdagop"; break;
+ case INTERLEAVE: Result = "!interleave"; break;
+ case SETDAGOP: Result = "!setdagop"; break;
}
return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
}
@@ -1169,7 +1169,7 @@ void TernOpInit::Profile(FoldingSetNodeID &ID) const {
ProfileTernOpInit(ID, getOpcode(), getLHS(), getMHS(), getRHS(), getType());
}
-static Init *ItemApply(Init *LHS, Init *MHSe, Init *RHS, Record *CurRec) {
+static Init *ItemApply(Init *LHS, Init *MHSe, Init *RHS, Record *CurRec) {
MapResolver R(CurRec);
R.set(LHS, MHSe);
return RHS->resolveReferences(R);
@@ -1178,7 +1178,7 @@ static Init *ItemApply(Init *LHS, Init *MHSe, Init *RHS, Record *CurRec) {
static Init *ForeachDagApply(Init *LHS, DagInit *MHSd, Init *RHS,
Record *CurRec) {
bool Change = false;
- Init *Val = ItemApply(LHS, MHSd->getOperator(), RHS, CurRec);
+ Init *Val = ItemApply(LHS, MHSd->getOperator(), RHS, CurRec);
if (Val != MHSd->getOperator())
Change = true;
@@ -1191,7 +1191,7 @@ static Init *ForeachDagApply(Init *LHS, DagInit *MHSd, Init *RHS,
if (DagInit *Argd = dyn_cast<DagInit>(Arg))
NewArg = ForeachDagApply(LHS, Argd, RHS, CurRec);
else
- NewArg = ItemApply(LHS, Arg, RHS, CurRec);
+ NewArg = ItemApply(LHS, Arg, RHS, CurRec);
NewArgs.push_back(std::make_pair(NewArg, ArgName));
if (Arg != NewArg)
@@ -1213,7 +1213,7 @@ static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
SmallVector<Init *, 8> NewList(MHSl->begin(), MHSl->end());
for (Init *&Item : NewList) {
- Init *NewItem = ItemApply(LHS, Item, RHS, CurRec);
+ Init *NewItem = ItemApply(LHS, Item, RHS, CurRec);
if (NewItem != Item)
Item = NewItem;
}
@@ -1223,31 +1223,31 @@ static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
return nullptr;
}
-// Evaluates RHS for all elements of MHS, using LHS as a temp variable.
-// Creates a new list with the elements that evaluated to true.
-static Init *FilterHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
- Record *CurRec) {
- if (ListInit *MHSl = dyn_cast<ListInit>(MHS)) {
- SmallVector<Init *, 8> NewList;
-
- for (Init *Item : MHSl->getValues()) {
- Init *Include = ItemApply(LHS, Item, RHS, CurRec);
- if (!Include)
- return nullptr;
- if (IntInit *IncludeInt = dyn_cast_or_null<IntInit>(
- Include->convertInitializerTo(IntRecTy::get()))) {
- if (IncludeInt->getValue())
- NewList.push_back(Item);
- } else {
- return nullptr;
- }
- }
- return ListInit::get(NewList, cast<ListRecTy>(Type)->getElementType());
- }
-
- return nullptr;
-}
-
+// Evaluates RHS for all elements of MHS, using LHS as a temp variable.
+// Creates a new list with the elements that evaluated to true.
+static Init *FilterHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
+ Record *CurRec) {
+ if (ListInit *MHSl = dyn_cast<ListInit>(MHS)) {
+ SmallVector<Init *, 8> NewList;
+
+ for (Init *Item : MHSl->getValues()) {
+ Init *Include = ItemApply(LHS, Item, RHS, CurRec);
+ if (!Include)
+ return nullptr;
+ if (IntInit *IncludeInt = dyn_cast_or_null<IntInit>(
+ Include->convertInitializerTo(IntRecTy::get()))) {
+ if (IncludeInt->getValue())
+ NewList.push_back(Item);
+ } else {
+ return nullptr;
+ }
+ }
+ return ListInit::get(NewList, cast<ListRecTy>(Type)->getElementType());
+ }
+
+ return nullptr;
+}
+
Init *TernOpInit::Fold(Record *CurRec) const {
switch (getOpcode()) {
case SUBST: {
@@ -1300,12 +1300,12 @@ Init *TernOpInit::Fold(Record *CurRec) const {
break;
}
- case FILTER: {
- if (Init *Result = FilterHelper(LHS, MHS, RHS, getType(), CurRec))
- return Result;
- break;
- }
-
+ case FILTER: {
+ if (Init *Result = FilterHelper(LHS, MHS, RHS, getType(), CurRec))
+ return Result;
+ break;
+ }
+
case IF: {
if (IntInit *LHSi = dyn_cast_or_null<IntInit>(
LHS->convertInitializerTo(IntRecTy::get()))) {
@@ -1339,28 +1339,28 @@ Init *TernOpInit::Fold(Record *CurRec) const {
}
break;
}
-
- case SUBSTR: {
- StringInit *LHSs = dyn_cast<StringInit>(LHS);
- IntInit *MHSi = dyn_cast<IntInit>(MHS);
- IntInit *RHSi = dyn_cast<IntInit>(RHS);
- if (LHSs && MHSi && RHSi) {
- int64_t StringSize = LHSs->getValue().size();
- int64_t Start = MHSi->getValue();
- int64_t Length = RHSi->getValue();
- if (Start < 0 || Start > StringSize)
- PrintError(CurRec->getLoc(),
- Twine("!substr start position is out of range 0...") +
- std::to_string(StringSize) + ": " +
- std::to_string(Start));
- if (Length < 0)
- PrintError(CurRec->getLoc(), "!substr length must be nonnegative");
- return StringInit::get(LHSs->getValue().substr(Start, Length),
- LHSs->getFormat());
- }
- break;
- }
- }
+
+ case SUBSTR: {
+ StringInit *LHSs = dyn_cast<StringInit>(LHS);
+ IntInit *MHSi = dyn_cast<IntInit>(MHS);
+ IntInit *RHSi = dyn_cast<IntInit>(RHS);
+ if (LHSs && MHSi && RHSi) {
+ int64_t StringSize = LHSs->getValue().size();
+ int64_t Start = MHSi->getValue();
+ int64_t Length = RHSi->getValue();
+ if (Start < 0 || Start > StringSize)
+ PrintError(CurRec->getLoc(),
+ Twine("!substr start position is out of range 0...") +
+ std::to_string(StringSize) + ": " +
+ std::to_string(Start));
+ if (Length < 0)
+ PrintError(CurRec->getLoc(), "!substr length must be nonnegative");
+ return StringInit::get(LHSs->getValue().substr(Start, Length),
+ LHSs->getFormat());
+ }
+ break;
+ }
+ }
return const_cast<TernOpInit *>(this);
}
@@ -1381,7 +1381,7 @@ Init *TernOpInit::resolveReferences(Resolver &R) const {
Init *mhs = MHS->resolveReferences(R);
Init *rhs;
- if (getOpcode() == FOREACH || getOpcode() == FILTER) {
+ if (getOpcode() == FOREACH || getOpcode() == FILTER) {
ShadowResolver SR(R);
SR.addShadow(lhs);
rhs = RHS->resolveReferences(SR);
@@ -1399,12 +1399,12 @@ std::string TernOpInit::getAsString() const {
std::string Result;
bool UnquotedLHS = false;
switch (getOpcode()) {
- case DAG: Result = "!dag"; break;
- case FILTER: Result = "!filter"; UnquotedLHS = true; break;
+ case DAG: Result = "!dag"; break;
+ case FILTER: Result = "!filter"; UnquotedLHS = true; break;
case FOREACH: Result = "!foreach"; UnquotedLHS = true; break;
case IF: Result = "!if"; break;
- case SUBST: Result = "!subst"; break;
- case SUBSTR: Result = "!substr"; break;
+ case SUBST: Result = "!subst"; break;
+ case SUBSTR: Result = "!substr"; break;
}
return (Result + "(" +
(UnquotedLHS ? LHS->getAsUnquotedString() : LHS->getAsString()) +
@@ -2142,39 +2142,39 @@ std::string DagInit::getAsString() const {
// Other implementations
//===----------------------------------------------------------------------===//
-RecordVal::RecordVal(Init *N, RecTy *T, FieldKind K)
- : Name(N), TyAndKind(T, K) {
+RecordVal::RecordVal(Init *N, RecTy *T, FieldKind K)
+ : Name(N), TyAndKind(T, K) {
+ setValue(UnsetInit::get());
+ assert(Value && "Cannot create unset value for current type!");
+}
+
+// This constructor accepts the same arguments as the above, but also
+// a source location.
+RecordVal::RecordVal(Init *N, SMLoc Loc, RecTy *T, FieldKind K)
+ : Name(N), Loc(Loc), TyAndKind(T, K) {
setValue(UnsetInit::get());
assert(Value && "Cannot create unset value for current type!");
}
-// This constructor accepts the same arguments as the above, but also
-// a source location.
-RecordVal::RecordVal(Init *N, SMLoc Loc, RecTy *T, FieldKind K)
- : Name(N), Loc(Loc), TyAndKind(T, K) {
- setValue(UnsetInit::get());
- assert(Value && "Cannot create unset value for current type!");
-}
-
StringRef RecordVal::getName() const {
return cast<StringInit>(getNameInit())->getValue();
}
-std::string RecordVal::getPrintType() const {
- if (getType() == StringRecTy::get()) {
- if (auto *StrInit = dyn_cast<StringInit>(Value)) {
- if (StrInit->hasCodeFormat())
- return "code";
- else
- return "string";
- } else {
- return "string";
- }
- } else {
- return TyAndKind.getPointer()->getAsString();
- }
-}
-
+std::string RecordVal::getPrintType() const {
+ if (getType() == StringRecTy::get()) {
+ if (auto *StrInit = dyn_cast<StringInit>(Value)) {
+ if (StrInit->hasCodeFormat())
+ return "code";
+ else
+ return "string";
+ } else {
+ return "string";
+ }
+ } else {
+ return TyAndKind.getPointer()->getAsString();
+ }
+}
+
bool RecordVal::setValue(Init *V) {
if (V) {
Value = V->getCastTo(getType());
@@ -2185,8 +2185,33 @@ bool RecordVal::setValue(Init *V) {
if (!isa<BitsInit>(Value)) {
SmallVector<Init *, 64> Bits;
Bits.reserve(BTy->getNumBits());
- for (unsigned I = 0, E = BTy->getNumBits(); I < E; ++I)
- Bits.push_back(Value->getBit(I));
+ for (unsigned I = 0, E = BTy->getNumBits(); I < E; ++I)
+ Bits.push_back(Value->getBit(I));
+ Value = BitsInit::get(Bits);
+ }
+ }
+ }
+ return Value == nullptr;
+ }
+ Value = nullptr;
+ return false;
+}
+
+// This version of setValue takes a source location and resets the
+// location in the RecordVal.
+bool RecordVal::setValue(Init *V, SMLoc NewLoc) {
+ Loc = NewLoc;
+ if (V) {
+ Value = V->getCastTo(getType());
+ if (Value) {
+ assert(!isa<TypedInit>(Value) ||
+ cast<TypedInit>(Value)->getType()->typeIsA(getType()));
+ if (BitsRecTy *BTy = dyn_cast<BitsRecTy>(getType())) {
+ if (!isa<BitsInit>(Value)) {
+ SmallVector<Init *, 64> Bits;
+ Bits.reserve(BTy->getNumBits());
+ for (unsigned I = 0, E = BTy->getNumBits(); I < E; ++I)
+ Bits.push_back(Value->getBit(I));
Value = BitsInit::get(Bits);
}
}
@@ -2197,39 +2222,14 @@ bool RecordVal::setValue(Init *V) {
return false;
}
-// This version of setValue takes a source location and resets the
-// location in the RecordVal.
-bool RecordVal::setValue(Init *V, SMLoc NewLoc) {
- Loc = NewLoc;
- if (V) {
- Value = V->getCastTo(getType());
- if (Value) {
- assert(!isa<TypedInit>(Value) ||
- cast<TypedInit>(Value)->getType()->typeIsA(getType()));
- if (BitsRecTy *BTy = dyn_cast<BitsRecTy>(getType())) {
- if (!isa<BitsInit>(Value)) {
- SmallVector<Init *, 64> Bits;
- Bits.reserve(BTy->getNumBits());
- for (unsigned I = 0, E = BTy->getNumBits(); I < E; ++I)
- Bits.push_back(Value->getBit(I));
- Value = BitsInit::get(Bits);
- }
- }
- }
- return Value == nullptr;
- }
- Value = nullptr;
- return false;
-}
-
-#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/Record.h"
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void RecordVal::dump() const { errs() << *this; }
#endif
void RecordVal::print(raw_ostream &OS, bool PrintSem) const {
- if (isNonconcreteOK()) OS << "field ";
- OS << getPrintType() << " " << getNameInitAsString();
+ if (isNonconcreteOK()) OS << "field ";
+ OS << getPrintType() << " " << getNameInitAsString();
if (getValue())
OS << " = " << *getValue();
@@ -2254,9 +2254,9 @@ RecordRecTy *Record::getType() {
}
DefInit *Record::getDefInit() {
- if (!CorrespondingDefInit)
- CorrespondingDefInit = new (Allocator) DefInit(this);
- return CorrespondingDefInit;
+ if (!CorrespondingDefInit)
+ CorrespondingDefInit = new (Allocator) DefInit(this);
+ return CorrespondingDefInit;
}
void Record::setName(Init *NewName) {
@@ -2275,27 +2275,27 @@ void Record::setName(Init *NewName) {
// this. See TGParser::ParseDef and TGParser::ParseDefm.
}
-// NOTE for the next two functions:
-// Superclasses are in post-order, so the final one is a direct
-// superclass. All of its transitive superclases immediately precede it,
-// so we can step through the direct superclasses in reverse order.
-
-bool Record::hasDirectSuperClass(const Record *Superclass) const {
- ArrayRef<std::pair<Record *, SMRange>> SCs = getSuperClasses();
-
- for (int I = SCs.size() - 1; I >= 0; --I) {
- const Record *SC = SCs[I].first;
- if (SC == Superclass)
- return true;
- I -= SC->getSuperClasses().size();
- }
-
- return false;
-}
-
+// NOTE for the next two functions:
+// Superclasses are in post-order, so the final one is a direct
+// superclass. All of its transitive superclases immediately precede it,
+// so we can step through the direct superclasses in reverse order.
+
+bool Record::hasDirectSuperClass(const Record *Superclass) const {
+ ArrayRef<std::pair<Record *, SMRange>> SCs = getSuperClasses();
+
+ for (int I = SCs.size() - 1; I >= 0; --I) {
+ const Record *SC = SCs[I].first;
+ if (SC == Superclass)
+ return true;
+ I -= SC->getSuperClasses().size();
+ }
+
+ return false;
+}
+
void Record::getDirectSuperClasses(SmallVectorImpl<Record *> &Classes) const {
ArrayRef<std::pair<Record *, SMRange>> SCs = getSuperClasses();
-
+
while (!SCs.empty()) {
Record *SC = SCs.back().first;
SCs = SCs.drop_back(1 + SC->getSuperClasses().size());
@@ -2369,23 +2369,23 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) {
OS << "\n";
for (const RecordVal &Val : R.getValues())
- if (Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
+ if (Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
OS << Val;
for (const RecordVal &Val : R.getValues())
- if (!Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
+ if (!Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
OS << Val;
return OS << "}\n";
}
-SMLoc Record::getFieldLoc(StringRef FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (!R)
- PrintFatalError(getLoc(), "Record `" + getName() +
- "' does not have a field named `" + FieldName + "'!\n");
- return R->getLoc();
-}
-
+SMLoc Record::getFieldLoc(StringRef FieldName) const {
+ const RecordVal *R = getValue(FieldName);
+ if (!R)
+ PrintFatalError(getLoc(), "Record `" + getName() +
+ "' does not have a field named `" + FieldName + "'!\n");
+ return R->getLoc();
+}
+
Init *Record::getValueInit(StringRef FieldName) const {
const RecordVal *R = getValue(FieldName);
if (!R || !R->getValue())
@@ -2395,27 +2395,27 @@ Init *Record::getValueInit(StringRef FieldName) const {
}
StringRef Record::getValueAsString(StringRef FieldName) const {
- llvm::Optional<StringRef> S = getValueAsOptionalString(FieldName);
- if (!S.hasValue())
+ llvm::Optional<StringRef> S = getValueAsOptionalString(FieldName);
+ if (!S.hasValue())
PrintFatalError(getLoc(), "Record `" + getName() +
"' does not have a field named `" + FieldName + "'!\n");
- return S.getValue();
-}
-
-llvm::Optional<StringRef>
-Record::getValueAsOptionalString(StringRef FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (!R || !R->getValue())
- return llvm::Optional<StringRef>();
- if (isa<UnsetInit>(R->getValue()))
- return llvm::Optional<StringRef>();
-
+ return S.getValue();
+}
+
+llvm::Optional<StringRef>
+Record::getValueAsOptionalString(StringRef FieldName) const {
+ const RecordVal *R = getValue(FieldName);
+ if (!R || !R->getValue())
+ return llvm::Optional<StringRef>();
+ if (isa<UnsetInit>(R->getValue()))
+ return llvm::Optional<StringRef>();
+
if (StringInit *SI = dyn_cast<StringInit>(R->getValue()))
return SI->getValue();
- PrintFatalError(getLoc(),
- "Record `" + getName() + "', ` field `" + FieldName +
- "' exists but does not have a string initializer!");
+ PrintFatalError(getLoc(),
+ "Record `" + getName() + "', ` field `" + FieldName +
+ "' exists but does not have a string initializer!");
}
BitsInit *Record::getValueAsBitsInit(StringRef FieldName) const {
@@ -2426,8 +2426,8 @@ BitsInit *Record::getValueAsBitsInit(StringRef FieldName) const {
if (BitsInit *BI = dyn_cast<BitsInit>(R->getValue()))
return BI;
- PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + FieldName +
- "' exists but does not have a bits value");
+ PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + FieldName +
+ "' exists but does not have a bits value");
}
ListInit *Record::getValueAsListInit(StringRef FieldName) const {
@@ -2438,8 +2438,8 @@ ListInit *Record::getValueAsListInit(StringRef FieldName) const {
if (ListInit *LI = dyn_cast<ListInit>(R->getValue()))
return LI;
- PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + FieldName +
- "' exists but does not have a list value");
+ PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + FieldName +
+ "' exists but does not have a list value");
}
std::vector<Record*>
@@ -2466,7 +2466,7 @@ int64_t Record::getValueAsInt(StringRef FieldName) const {
return II->getValue();
PrintFatalError(getLoc(), Twine("Record `") + getName() + "', field `" +
FieldName +
- "' exists but does not have an int value: " +
+ "' exists but does not have an int value: " +
R->getValue()->getAsString());
}
@@ -2480,7 +2480,7 @@ Record::getValueAsListOfInts(StringRef FieldName) const {
else
PrintFatalError(getLoc(),
Twine("Record `") + getName() + "', field `" + FieldName +
- "' exists but does not have a list of ints value: " +
+ "' exists but does not have a list of ints value: " +
I->getAsString());
}
return Ints;
@@ -2496,7 +2496,7 @@ Record::getValueAsListOfStrings(StringRef FieldName) const {
else
PrintFatalError(getLoc(),
Twine("Record `") + getName() + "', field `" + FieldName +
- "' exists but does not have a list of strings value: " +
+ "' exists but does not have a list of strings value: " +
I->getAsString());
}
return Strings;
@@ -2591,79 +2591,79 @@ Init *RecordKeeper::getNewAnonymousName() {
return StringInit::get("anonymous_" + utostr(AnonCounter++));
}
-// These functions implement the phase timing facility. Starting a timer
-// when one is already running stops the running one.
-
-void RecordKeeper::startTimer(StringRef Name) {
- if (TimingGroup) {
- if (LastTimer && LastTimer->isRunning()) {
- LastTimer->stopTimer();
- if (BackendTimer) {
- LastTimer->clear();
- BackendTimer = false;
- }
- }
-
- LastTimer = new Timer("", Name, *TimingGroup);
- LastTimer->startTimer();
- }
-}
-
-void RecordKeeper::stopTimer() {
- if (TimingGroup) {
- assert(LastTimer && "No phase timer was started");
- LastTimer->stopTimer();
- }
-}
-
-void RecordKeeper::startBackendTimer(StringRef Name) {
- if (TimingGroup) {
- startTimer(Name);
- BackendTimer = true;
- }
-}
-
-void RecordKeeper::stopBackendTimer() {
- if (TimingGroup) {
- if (BackendTimer) {
- stopTimer();
- BackendTimer = false;
- }
- }
-}
-
-// We cache the record vectors for single classes. Many backends request
-// the same vectors multiple times.
-std::vector<Record *> RecordKeeper::getAllDerivedDefinitions(
- StringRef ClassName) const {
-
- auto Pair = ClassRecordsMap.try_emplace(ClassName);
- if (Pair.second)
- Pair.first->second = getAllDerivedDefinitions(makeArrayRef(ClassName));
-
- return Pair.first->second;
-}
-
-std::vector<Record *> RecordKeeper::getAllDerivedDefinitions(
- ArrayRef<StringRef> ClassNames) const {
- SmallVector<Record *, 2> ClassRecs;
- std::vector<Record *> Defs;
-
- assert(ClassNames.size() > 0 && "At least one class must be passed.");
- for (const auto &ClassName : ClassNames) {
- Record *Class = getClass(ClassName);
- if (!Class)
- PrintFatalError("The class '" + ClassName + "' is not defined\n");
- ClassRecs.push_back(Class);
- }
-
- for (const auto &OneDef : getDefs()) {
- if (all_of(ClassRecs, [&OneDef](const Record *Class) {
- return OneDef.second->isSubClassOf(Class);
- }))
- Defs.push_back(OneDef.second.get());
- }
-
+// These functions implement the phase timing facility. Starting a timer
+// when one is already running stops the running one.
+
+void RecordKeeper::startTimer(StringRef Name) {
+ if (TimingGroup) {
+ if (LastTimer && LastTimer->isRunning()) {
+ LastTimer->stopTimer();
+ if (BackendTimer) {
+ LastTimer->clear();
+ BackendTimer = false;
+ }
+ }
+
+ LastTimer = new Timer("", Name, *TimingGroup);
+ LastTimer->startTimer();
+ }
+}
+
+void RecordKeeper::stopTimer() {
+ if (TimingGroup) {
+ assert(LastTimer && "No phase timer was started");
+ LastTimer->stopTimer();
+ }
+}
+
+void RecordKeeper::startBackendTimer(StringRef Name) {
+ if (TimingGroup) {
+ startTimer(Name);
+ BackendTimer = true;
+ }
+}
+
+void RecordKeeper::stopBackendTimer() {
+ if (TimingGroup) {
+ if (BackendTimer) {
+ stopTimer();
+ BackendTimer = false;
+ }
+ }
+}
+
+// We cache the record vectors for single classes. Many backends request
+// the same vectors multiple times.
+std::vector<Record *> RecordKeeper::getAllDerivedDefinitions(
+ StringRef ClassName) const {
+
+ auto Pair = ClassRecordsMap.try_emplace(ClassName);
+ if (Pair.second)
+ Pair.first->second = getAllDerivedDefinitions(makeArrayRef(ClassName));
+
+ return Pair.first->second;
+}
+
+std::vector<Record *> RecordKeeper::getAllDerivedDefinitions(
+ ArrayRef<StringRef> ClassNames) const {
+ SmallVector<Record *, 2> ClassRecs;
+ std::vector<Record *> Defs;
+
+ assert(ClassNames.size() > 0 && "At least one class must be passed.");
+ for (const auto &ClassName : ClassNames) {
+ Record *Class = getClass(ClassName);
+ if (!Class)
+ PrintFatalError("The class '" + ClassName + "' is not defined\n");
+ ClassRecs.push_back(Class);
+ }
+
+ for (const auto &OneDef : getDefs()) {
+ if (all_of(ClassRecs, [&OneDef](const Record *Class) {
+ return OneDef.second->isSubClassOf(Class);
+ }))
+ Defs.push_back(OneDef.second.get());
+ }
+
return Defs;
}
diff --git a/contrib/libs/llvm12/lib/TableGen/TGLexer.cpp b/contrib/libs/llvm12/lib/TableGen/TGLexer.cpp
index fd0f9ff7af..94c79102c7 100644
--- a/contrib/libs/llvm12/lib/TableGen/TGLexer.cpp
+++ b/contrib/libs/llvm12/lib/TableGen/TGLexer.cpp
@@ -150,7 +150,7 @@ tgtok::TokKind TGLexer::LexToken(bool FileOrLineStart) {
case EOF:
// Lex next token, if we just left an include file.
// Note that leaving an include file means that the next
- // symbol is located at the end of the 'include "..."'
+ // symbol is located at the end of the 'include "..."'
// construct, so LexToken() is called with default
// false parameter.
if (processEOF())
@@ -180,19 +180,19 @@ tgtok::TokKind TGLexer::LexToken(bool FileOrLineStart) {
return tgtok::paste;
- // The period is a separate case so we can recognize the "..."
- // range punctuator.
- case '.':
- if (peekNextChar(0) == '.') {
- ++CurPtr; // Eat second dot.
- if (peekNextChar(0) == '.') {
- ++CurPtr; // Eat third dot.
- return tgtok::dotdotdot;
- }
- return ReturnError(TokStart, "Invalid '..' punctuation");
- }
- return tgtok::dot;
-
+ // The period is a separate case so we can recognize the "..."
+ // range punctuator.
+ case '.':
+ if (peekNextChar(0) == '.') {
+ ++CurPtr; // Eat second dot.
+ if (peekNextChar(0) == '.') {
+ ++CurPtr; // Eat third dot.
+ return tgtok::dotdotdot;
+ }
+ return ReturnError(TokStart, "Invalid '..' punctuation");
+ }
+ return tgtok::dot;
+
case '\r':
PrintFatalError("getNextChar() must never return '\r'");
return tgtok::Error;
@@ -338,7 +338,7 @@ tgtok::TokKind TGLexer::LexIdentifier() {
while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_')
++CurPtr;
- // Check to see if this identifier is a reserved keyword.
+ // Check to see if this identifier is a reserved keyword.
StringRef Str(IdentStart, CurPtr-IdentStart);
tgtok::TokKind Kind = StringSwitch<tgtok::TokKind>(Str)
@@ -351,8 +351,8 @@ tgtok::TokKind TGLexer::LexIdentifier() {
.Case("dag", tgtok::Dag)
.Case("class", tgtok::Class)
.Case("def", tgtok::Def)
- .Case("true", tgtok::TrueVal)
- .Case("false", tgtok::FalseVal)
+ .Case("true", tgtok::TrueVal)
+ .Case("false", tgtok::FalseVal)
.Case("foreach", tgtok::Foreach)
.Case("defm", tgtok::Defm)
.Case("defset", tgtok::Defset)
@@ -361,25 +361,25 @@ tgtok::TokKind TGLexer::LexIdentifier() {
.Case("let", tgtok::Let)
.Case("in", tgtok::In)
.Case("defvar", tgtok::Defvar)
- .Case("include", tgtok::Include)
+ .Case("include", tgtok::Include)
.Case("if", tgtok::If)
.Case("then", tgtok::Then)
.Case("else", tgtok::ElseKW)
- .Case("assert", tgtok::Assert)
+ .Case("assert", tgtok::Assert)
.Default(tgtok::Id);
- // A couple of tokens require special processing.
- switch (Kind) {
- case tgtok::Include:
- if (LexInclude()) return tgtok::Error;
- return Lex();
- case tgtok::Id:
- CurStrVal.assign(Str.begin(), Str.end());
- break;
- default:
- break;
- }
-
+ // A couple of tokens require special processing.
+ switch (Kind) {
+ case tgtok::Include:
+ if (LexInclude()) return tgtok::Error;
+ return Lex();
+ case tgtok::Id:
+ CurStrVal.assign(Str.begin(), Str.end());
+ break;
+ default:
+ break;
+ }
+
return Kind;
}
@@ -541,7 +541,7 @@ tgtok::TokKind TGLexer::LexBracket() {
}
}
- return ReturnError(CodeStart - 2, "Unterminated code block");
+ return ReturnError(CodeStart - 2, "Unterminated code block");
}
/// LexExclaim - Lex '!' and '![a-zA-Z]+'.
@@ -571,12 +571,12 @@ tgtok::TokKind TGLexer::LexExclaim() {
.Case("con", tgtok::XConcat)
.Case("dag", tgtok::XDag)
.Case("add", tgtok::XADD)
- .Case("sub", tgtok::XSUB)
+ .Case("sub", tgtok::XSUB)
.Case("mul", tgtok::XMUL)
- .Case("not", tgtok::XNOT)
+ .Case("not", tgtok::XNOT)
.Case("and", tgtok::XAND)
.Case("or", tgtok::XOR)
- .Case("xor", tgtok::XXOR)
+ .Case("xor", tgtok::XXOR)
.Case("shl", tgtok::XSHL)
.Case("sra", tgtok::XSRA)
.Case("srl", tgtok::XSRL)
@@ -585,14 +585,14 @@ tgtok::TokKind TGLexer::LexExclaim() {
.Case("subst", tgtok::XSubst)
.Case("foldl", tgtok::XFoldl)
.Case("foreach", tgtok::XForEach)
- .Case("filter", tgtok::XFilter)
+ .Case("filter", tgtok::XFilter)
.Case("listconcat", tgtok::XListConcat)
.Case("listsplat", tgtok::XListSplat)
.Case("strconcat", tgtok::XStrConcat)
- .Case("interleave", tgtok::XInterleave)
- .Case("substr", tgtok::XSubstr)
- .Cases("setdagop", "setop", tgtok::XSetDagOp) // !setop is deprecated.
- .Cases("getdagop", "getop", tgtok::XGetDagOp) // !getop is deprecated.
+ .Case("interleave", tgtok::XInterleave)
+ .Case("substr", tgtok::XSubstr)
+ .Cases("setdagop", "setop", tgtok::XSetDagOp) // !setop is deprecated.
+ .Cases("getdagop", "getop", tgtok::XGetDagOp) // !getop is deprecated.
.Default(tgtok::Error);
return Kind != tgtok::Error ? Kind : ReturnError(Start-1, "Unknown operator");
diff --git a/contrib/libs/llvm12/lib/TableGen/TGLexer.h b/contrib/libs/llvm12/lib/TableGen/TGLexer.h
index 442decc8ff..2f322f705e 100644
--- a/contrib/libs/llvm12/lib/TableGen/TGLexer.h
+++ b/contrib/libs/llvm12/lib/TableGen/TGLexer.h
@@ -40,26 +40,26 @@ namespace tgtok {
l_paren, r_paren, // ( )
less, greater, // < >
colon, semi, // : ;
- comma, dot, // , .
+ comma, dot, // , .
equal, question, // = ?
paste, // #
- dotdotdot, // ...
-
- // Reserved keywords. ('ElseKW' is named to distinguish it from the
- // existing 'Else' that means the preprocessor #else.)
- Assert, Bit, Bits, Class, Code, Dag, Def, Defm, Defset, Defvar, ElseKW,
- FalseKW, Field, Foreach, If, In, Include, Int, Let, List, MultiClass,
- String, Then, TrueKW,
-
- // Bang operators.
- XConcat, XADD, XSUB, XMUL, XNOT, XAND, XOR, XXOR, XSRA, XSRL, XSHL,
- XListConcat, XListSplat, XStrConcat, XInterleave, XSubstr, XCast,
- XSubst, XForEach, XFilter, XFoldl, XHead, XTail, XSize, XEmpty, XIf,
- XCond, XEq, XIsA, XDag, XNe, XLe, XLt, XGe, XGt, XSetDagOp, XGetDagOp,
-
- // Boolean literals.
- TrueVal, FalseVal,
-
+ dotdotdot, // ...
+
+ // Reserved keywords. ('ElseKW' is named to distinguish it from the
+ // existing 'Else' that means the preprocessor #else.)
+ Assert, Bit, Bits, Class, Code, Dag, Def, Defm, Defset, Defvar, ElseKW,
+ FalseKW, Field, Foreach, If, In, Include, Int, Let, List, MultiClass,
+ String, Then, TrueKW,
+
+ // Bang operators.
+ XConcat, XADD, XSUB, XMUL, XNOT, XAND, XOR, XXOR, XSRA, XSRL, XSHL,
+ XListConcat, XListSplat, XStrConcat, XInterleave, XSubstr, XCast,
+ XSubst, XForEach, XFilter, XFoldl, XHead, XTail, XSize, XEmpty, XIf,
+ XCond, XEq, XIsA, XDag, XNe, XLe, XLt, XGe, XGt, XSetDagOp, XGetDagOp,
+
+ // Boolean literals.
+ TrueVal, FalseVal,
+
// Integer value.
IntVal,
@@ -86,8 +86,8 @@ class TGLexer {
// Information about the current token.
const char *TokStart = nullptr;
tgtok::TokKind CurCode = tgtok::TokKind::Eof;
- std::string CurStrVal; // This is valid for Id, StrVal, VarName, CodeFragment
- int64_t CurIntVal = 0; // This is valid for IntVal.
+ std::string CurStrVal; // This is valid for Id, StrVal, VarName, CodeFragment
+ int64_t CurIntVal = 0; // This is valid for IntVal.
/// CurBuffer - This is the current buffer index we're lexing from as managed
/// by the SourceMgr object.
diff --git a/contrib/libs/llvm12/lib/TableGen/TGParser.cpp b/contrib/libs/llvm12/lib/TableGen/TGParser.cpp
index f88ab0c7f9..24949f0b2b 100644
--- a/contrib/libs/llvm12/lib/TableGen/TGParser.cpp
+++ b/contrib/libs/llvm12/lib/TableGen/TGParser.cpp
@@ -25,7 +25,7 @@
#include <algorithm>
#include <cassert>
#include <cstdint>
-#include <limits>
+#include <limits>
using namespace llvm;
@@ -95,7 +95,7 @@ static void checkConcrete(Record &R) {
// done merely because existing targets have legitimate cases of
// non-concrete variables in helper defs. Ideally, we'd introduce a
// 'maybe' or 'optional' modifier instead of this.
- if (RV.isNonconcreteOK())
+ if (RV.isNonconcreteOK())
continue;
if (Init *V = RV.getValue()) {
@@ -210,16 +210,16 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName,
V = BitsInit::get(NewBits);
}
- if (RV->setValue(V, Loc)) {
+ if (RV->setValue(V, Loc)) {
std::string InitType;
if (BitsInit *BI = dyn_cast<BitsInit>(V))
InitType = (Twine("' of type bit initializer with length ") +
Twine(BI->getNumBits())).str();
else if (TypedInit *TI = dyn_cast<TypedInit>(V))
InitType = (Twine("' of type '") + TI->getType()->getAsString()).str();
- return Error(Loc, "Field '" + ValName->getAsUnquotedString() +
+ return Error(Loc, "Field '" + ValName->getAsUnquotedString() +
"' of type '" + RV->getType()->getAsString() +
- "' is incompatible with value '" +
+ "' is incompatible with value '" +
V->getAsString() + InitType + "'");
}
return false;
@@ -452,8 +452,8 @@ bool TGParser::addDefOne(std::unique_ptr<Record> Rec) {
Rec->resolveReferences();
checkConcrete(*Rec);
- CheckRecordAsserts(*Rec);
-
+ CheckRecordAsserts(*Rec);
+
if (!isa<StringInit>(Rec->getNameInit())) {
PrintError(Rec->getLoc(), Twine("record name '") +
Rec->getNameInit()->getAsString() +
@@ -484,12 +484,12 @@ bool TGParser::addDefOne(std::unique_ptr<Record> Rec) {
// Parser Code
//===----------------------------------------------------------------------===//
-/// isObjectStart - Return true if this is a valid first token for a statement.
+/// isObjectStart - Return true if this is a valid first token for a statement.
static bool isObjectStart(tgtok::TokKind K) {
- return K == tgtok::Assert || K == tgtok::Class || K == tgtok::Def ||
- K == tgtok::Defm || K == tgtok::Defset || K == tgtok::Defvar ||
- K == tgtok::Foreach || K == tgtok::If || K == tgtok::Let ||
- K == tgtok::MultiClass;
+ return K == tgtok::Assert || K == tgtok::Class || K == tgtok::Def ||
+ K == tgtok::Defm || K == tgtok::Defset || K == tgtok::Defvar ||
+ K == tgtok::Foreach || K == tgtok::If || K == tgtok::Let ||
+ K == tgtok::MultiClass;
}
bool TGParser::consume(tgtok::TokKind K) {
@@ -675,10 +675,10 @@ ParseSubMultiClassReference(MultiClass *CurMC) {
/// ParseRangePiece - Parse a bit/value range.
/// RangePiece ::= INTVAL
-/// RangePiece ::= INTVAL '...' INTVAL
+/// RangePiece ::= INTVAL '...' INTVAL
/// RangePiece ::= INTVAL '-' INTVAL
-/// RangePiece ::= INTVAL INTVAL
-// The last two forms are deprecated.
+/// RangePiece ::= INTVAL INTVAL
+// The last two forms are deprecated.
bool TGParser::ParseRangePiece(SmallVectorImpl<unsigned> &Ranges,
TypedInit *FirstItem) {
Init *CurVal = FirstItem;
@@ -699,8 +699,8 @@ bool TGParser::ParseRangePiece(SmallVectorImpl<unsigned> &Ranges,
default:
Ranges.push_back(Start);
return false;
-
- case tgtok::dotdotdot:
+
+ case tgtok::dotdotdot:
case tgtok::minus: {
Lex.Lex(); // eat
@@ -803,8 +803,8 @@ bool TGParser::ParseOptionalBitList(SmallVectorImpl<unsigned> &Ranges) {
RecTy *TGParser::ParseType() {
switch (Lex.getCode()) {
default: TokError("Unknown token when expecting a type"); return nullptr;
- case tgtok::String:
- case tgtok::Code: Lex.Lex(); return StringRecTy::get();
+ case tgtok::String:
+ case tgtok::Code: Lex.Lex(); return StringRecTy::get();
case tgtok::Bit: Lex.Lex(); return BitRecTy::get();
case tgtok::Int: Lex.Lex(); return IntRecTy::get();
case tgtok::Dag: Lex.Lex(); return DagRecTy::get();
@@ -817,12 +817,12 @@ RecTy *TGParser::ParseType() {
TokError("expected '<' after bits type");
return nullptr;
}
- if (Lex.Lex() != tgtok::IntVal) { // Eat '<'
+ if (Lex.Lex() != tgtok::IntVal) { // Eat '<'
TokError("expected integer in bits<n> type");
return nullptr;
}
uint64_t Val = Lex.getCurIntVal();
- if (Lex.Lex() != tgtok::greater) { // Eat count.
+ if (Lex.Lex() != tgtok::greater) { // Eat count.
TokError("expected '>' at end of bits<n> type");
return nullptr;
}
@@ -847,7 +847,7 @@ RecTy *TGParser::ParseType() {
}
}
-/// ParseIDValue
+/// ParseIDValue
Init *TGParser::ParseIDValue(Record *CurRec, StringInit *Name, SMLoc NameLoc,
IDParseMode Mode) {
if (CurRec) {
@@ -909,15 +909,15 @@ Init *TGParser::ParseIDValue(Record *CurRec, StringInit *Name, SMLoc NameLoc,
Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
switch (Lex.getCode()) {
default:
- TokError("unknown bang operator");
+ TokError("unknown bang operator");
return nullptr;
- case tgtok::XNOT:
+ case tgtok::XNOT:
case tgtok::XHead:
case tgtok::XTail:
case tgtok::XSize:
case tgtok::XEmpty:
case tgtok::XCast:
- case tgtok::XGetDagOp: { // Value ::= !unop '(' Value ')'
+ case tgtok::XGetDagOp: { // Value ::= !unop '(' Value ')'
UnOpInit::UnaryOp Code;
RecTy *Type = nullptr;
@@ -935,11 +935,11 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
}
break;
- case tgtok::XNOT:
- Lex.Lex(); // eat the operation
- Code = UnOpInit::NOT;
- Type = IntRecTy::get();
- break;
+ case tgtok::XNOT:
+ Lex.Lex(); // eat the operation
+ Code = UnOpInit::NOT;
+ Type = IntRecTy::get();
+ break;
case tgtok::XHead:
Lex.Lex(); // eat the operation
Code = UnOpInit::HEAD;
@@ -958,12 +958,12 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
Code = UnOpInit::EMPTY;
Type = IntRecTy::get();
break;
- case tgtok::XGetDagOp:
+ case tgtok::XGetDagOp:
Lex.Lex(); // eat the operation
if (Lex.getCode() == tgtok::less) {
// Parse an optional type suffix, so that you can say
- // !getdagop<BaseClass>(someDag) as a shorthand for
- // !cast<BaseClass>(!getdagop(someDag)).
+ // !getdagop<BaseClass>(someDag) as a shorthand for
+ // !cast<BaseClass>(!getdagop(someDag)).
Type = ParseOperatorType();
if (!Type) {
@@ -972,13 +972,13 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
}
if (!isa<RecordRecTy>(Type)) {
- TokError("type for !getdagop must be a record type");
+ TokError("type for !getdagop must be a record type");
// but keep parsing, to consume the operand
}
} else {
Type = RecordRecTy::get({});
}
- Code = UnOpInit::GETDAGOP;
+ Code = UnOpInit::GETDAGOP;
break;
}
if (!consume(tgtok::l_paren)) {
@@ -989,58 +989,58 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
Init *LHS = ParseValue(CurRec);
if (!LHS) return nullptr;
- if (Code == UnOpInit::EMPTY || Code == UnOpInit::SIZE) {
+ if (Code == UnOpInit::EMPTY || Code == UnOpInit::SIZE) {
ListInit *LHSl = dyn_cast<ListInit>(LHS);
StringInit *LHSs = dyn_cast<StringInit>(LHS);
- DagInit *LHSd = dyn_cast<DagInit>(LHS);
+ DagInit *LHSd = dyn_cast<DagInit>(LHS);
TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
- if (!LHSl && !LHSs && !LHSd && !LHSt) {
- TokError("expected string, list, or dag type argument in unary operator");
+ if (!LHSl && !LHSs && !LHSd && !LHSt) {
+ TokError("expected string, list, or dag type argument in unary operator");
return nullptr;
}
if (LHSt) {
ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType());
StringRecTy *SType = dyn_cast<StringRecTy>(LHSt->getType());
- DagRecTy *DType = dyn_cast<DagRecTy>(LHSt->getType());
- if (!LType && !SType && !DType) {
- TokError("expected string, list, or dag type argument in unary operator");
+ DagRecTy *DType = dyn_cast<DagRecTy>(LHSt->getType());
+ if (!LType && !SType && !DType) {
+ TokError("expected string, list, or dag type argument in unary operator");
return nullptr;
}
}
- }
-
- if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL) {
- ListInit *LHSl = dyn_cast<ListInit>(LHS);
- TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
- if (!LHSl && !LHSt) {
- TokError("expected list type argument in unary operator");
- return nullptr;
- }
- if (LHSt) {
- ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType());
- if (!LType) {
+ }
+
+ if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL) {
+ ListInit *LHSl = dyn_cast<ListInit>(LHS);
+ TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
+ if (!LHSl && !LHSt) {
+ TokError("expected list type argument in unary operator");
+ return nullptr;
+ }
+ if (LHSt) {
+ ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType());
+ if (!LType) {
TokError("expected list type argument in unary operator");
return nullptr;
}
}
- if (LHSl && LHSl->empty()) {
- TokError("empty list argument in unary operator");
- return nullptr;
- }
- if (LHSl) {
- Init *Item = LHSl->getElement(0);
- TypedInit *Itemt = dyn_cast<TypedInit>(Item);
- if (!Itemt) {
- TokError("untyped list element in unary operator");
+ if (LHSl && LHSl->empty()) {
+ TokError("empty list argument in unary operator");
+ return nullptr;
+ }
+ if (LHSl) {
+ Init *Item = LHSl->getElement(0);
+ TypedInit *Itemt = dyn_cast<TypedInit>(Item);
+ if (!Itemt) {
+ TokError("untyped list element in unary operator");
return nullptr;
}
- Type = (Code == UnOpInit::HEAD) ? Itemt->getType()
- : ListRecTy::get(Itemt->getType());
- } else {
- assert(LHSt && "expected list type argument in unary operator");
- ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType());
- Type = (Code == UnOpInit::HEAD) ? LType->getElementType() : LType;
+ Type = (Code == UnOpInit::HEAD) ? Itemt->getType()
+ : ListRecTy::get(Itemt->getType());
+ } else {
+ assert(LHSt && "expected list type argument in unary operator");
+ ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType());
+ Type = (Code == UnOpInit::HEAD) ? LType->getElementType() : LType;
}
}
@@ -1078,11 +1078,11 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
case tgtok::XConcat:
case tgtok::XADD:
- case tgtok::XSUB:
+ case tgtok::XSUB:
case tgtok::XMUL:
case tgtok::XAND:
case tgtok::XOR:
- case tgtok::XXOR:
+ case tgtok::XXOR:
case tgtok::XSRA:
case tgtok::XSRL:
case tgtok::XSHL:
@@ -1095,8 +1095,8 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
case tgtok::XListConcat:
case tgtok::XListSplat:
case tgtok::XStrConcat:
- case tgtok::XInterleave:
- case tgtok::XSetDagOp: { // Value ::= !binop '(' Value ',' Value ')'
+ case tgtok::XInterleave:
+ case tgtok::XSetDagOp: { // Value ::= !binop '(' Value ',' Value ')'
tgtok::TokKind OpTok = Lex.getCode();
SMLoc OpLoc = Lex.getLoc();
Lex.Lex(); // eat the operation
@@ -1106,11 +1106,11 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
default: llvm_unreachable("Unhandled code!");
case tgtok::XConcat: Code = BinOpInit::CONCAT; break;
case tgtok::XADD: Code = BinOpInit::ADD; break;
- case tgtok::XSUB: Code = BinOpInit::SUB; break;
+ case tgtok::XSUB: Code = BinOpInit::SUB; break;
case tgtok::XMUL: Code = BinOpInit::MUL; break;
case tgtok::XAND: Code = BinOpInit::AND; break;
case tgtok::XOR: Code = BinOpInit::OR; break;
- case tgtok::XXOR: Code = BinOpInit::XOR; break;
+ case tgtok::XXOR: Code = BinOpInit::XOR; break;
case tgtok::XSRA: Code = BinOpInit::SRA; break;
case tgtok::XSRL: Code = BinOpInit::SRL; break;
case tgtok::XSHL: Code = BinOpInit::SHL; break;
@@ -1121,10 +1121,10 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
case tgtok::XGe: Code = BinOpInit::GE; break;
case tgtok::XGt: Code = BinOpInit::GT; break;
case tgtok::XListConcat: Code = BinOpInit::LISTCONCAT; break;
- case tgtok::XListSplat: Code = BinOpInit::LISTSPLAT; break;
- case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break;
- case tgtok::XInterleave: Code = BinOpInit::INTERLEAVE; break;
- case tgtok::XSetDagOp: Code = BinOpInit::SETDAGOP; break;
+ case tgtok::XListSplat: Code = BinOpInit::LISTSPLAT; break;
+ case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break;
+ case tgtok::XInterleave: Code = BinOpInit::INTERLEAVE; break;
+ case tgtok::XSetDagOp: Code = BinOpInit::SETDAGOP; break;
}
RecTy *Type = nullptr;
@@ -1133,18 +1133,18 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
default:
llvm_unreachable("Unhandled code!");
case tgtok::XConcat:
- case tgtok::XSetDagOp:
+ case tgtok::XSetDagOp:
Type = DagRecTy::get();
ArgType = DagRecTy::get();
break;
case tgtok::XAND:
case tgtok::XOR:
- case tgtok::XXOR:
+ case tgtok::XXOR:
case tgtok::XSRA:
case tgtok::XSRL:
case tgtok::XSHL:
case tgtok::XADD:
- case tgtok::XSUB:
+ case tgtok::XSUB:
case tgtok::XMUL:
Type = IntRecTy::get();
ArgType = IntRecTy::get();
@@ -1156,7 +1156,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
case tgtok::XGe:
case tgtok::XGt:
Type = BitRecTy::get();
- // ArgType for the comparison operators is not yet known.
+ // ArgType for the comparison operators is not yet known.
break;
case tgtok::XListConcat:
// We don't know the list type until we parse the first argument
@@ -1169,9 +1169,9 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
Type = StringRecTy::get();
ArgType = StringRecTy::get();
break;
- case tgtok::XInterleave:
- Type = StringRecTy::get();
- // The first argument type is not yet known.
+ case tgtok::XInterleave:
+ Type = StringRecTy::get();
+ // The first argument type is not yet known.
}
if (Type && ItemType && !Type->typeIsConvertibleTo(ItemType)) {
@@ -1188,8 +1188,8 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
SmallVector<Init*, 2> InitList;
- // Note that this loop consumes an arbitrary number of arguments.
- // The actual count is checked later.
+ // Note that this loop consumes an arbitrary number of arguments.
+ // The actual count is checked later.
for (;;) {
SMLoc InitLoc = Lex.getLoc();
InitList.push_back(ParseValue(CurRec, ArgType));
@@ -1202,9 +1202,9 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
return nullptr;
}
RecTy *ListType = InitListBack->getType();
-
+
if (!ArgType) {
- // Argument type must be determined from the argument itself.
+ // Argument type must be determined from the argument itself.
ArgType = ListType;
switch (Code) {
@@ -1245,54 +1245,54 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
case BinOpInit::EQ:
case BinOpInit::NE:
if (!ArgType->typeIsConvertibleTo(IntRecTy::get()) &&
- !ArgType->typeIsConvertibleTo(StringRecTy::get()) &&
- !ArgType->typeIsConvertibleTo(RecordRecTy::get({}))) {
- Error(InitLoc, Twine("expected bit, bits, int, string, or record; "
- "got value of type '") + ArgType->getAsString() +
- "'");
- return nullptr;
- }
- break;
- case BinOpInit::LE:
- case BinOpInit::LT:
- case BinOpInit::GE:
- case BinOpInit::GT:
- if (!ArgType->typeIsConvertibleTo(IntRecTy::get()) &&
+ !ArgType->typeIsConvertibleTo(StringRecTy::get()) &&
+ !ArgType->typeIsConvertibleTo(RecordRecTy::get({}))) {
+ Error(InitLoc, Twine("expected bit, bits, int, string, or record; "
+ "got value of type '") + ArgType->getAsString() +
+ "'");
+ return nullptr;
+ }
+ break;
+ case BinOpInit::LE:
+ case BinOpInit::LT:
+ case BinOpInit::GE:
+ case BinOpInit::GT:
+ if (!ArgType->typeIsConvertibleTo(IntRecTy::get()) &&
!ArgType->typeIsConvertibleTo(StringRecTy::get())) {
- Error(InitLoc, Twine("expected bit, bits, int, or string; "
- "got value of type '") + ArgType->getAsString() +
- "'");
+ Error(InitLoc, Twine("expected bit, bits, int, or string; "
+ "got value of type '") + ArgType->getAsString() +
+ "'");
return nullptr;
}
break;
- case BinOpInit::INTERLEAVE:
- switch (InitList.size()) {
- case 1: // First argument must be a list of strings or integers.
- if (ArgType != StringRecTy::get()->getListTy() &&
- !ArgType->typeIsConvertibleTo(IntRecTy::get()->getListTy())) {
- Error(InitLoc, Twine("expected list of string, int, bits, or bit; "
- "got value of type '") +
- ArgType->getAsString() + "'");
- return nullptr;
- }
- break;
- case 2: // Second argument must be a string.
- if (!isa<StringRecTy>(ArgType)) {
- Error(InitLoc, Twine("expected second argument to be a string, "
- "got value of type '") +
- ArgType->getAsString() + "'");
- return nullptr;
- }
- break;
- default: ;
- }
- ArgType = nullptr; // Broken invariant: types not identical.
- break;
+ case BinOpInit::INTERLEAVE:
+ switch (InitList.size()) {
+ case 1: // First argument must be a list of strings or integers.
+ if (ArgType != StringRecTy::get()->getListTy() &&
+ !ArgType->typeIsConvertibleTo(IntRecTy::get()->getListTy())) {
+ Error(InitLoc, Twine("expected list of string, int, bits, or bit; "
+ "got value of type '") +
+ ArgType->getAsString() + "'");
+ return nullptr;
+ }
+ break;
+ case 2: // Second argument must be a string.
+ if (!isa<StringRecTy>(ArgType)) {
+ Error(InitLoc, Twine("expected second argument to be a string, "
+ "got value of type '") +
+ ArgType->getAsString() + "'");
+ return nullptr;
+ }
+ break;
+ default: ;
+ }
+ ArgType = nullptr; // Broken invariant: types not identical.
+ break;
default: llvm_unreachable("other ops have fixed argument types");
}
-
+
} else {
- // Desired argument type is a known and in ArgType.
+ // Desired argument type is a known and in ArgType.
RecTy *Resolved = resolveTypes(ArgType, ListType);
if (!Resolved) {
Error(InitLoc, Twine("expected value of type '") +
@@ -1300,9 +1300,9 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
ListType->getAsString() + "'");
return nullptr;
}
- if (Code != BinOpInit::ADD && Code != BinOpInit::SUB &&
- Code != BinOpInit::AND && Code != BinOpInit::OR &&
- Code != BinOpInit::XOR && Code != BinOpInit::SRA &&
+ if (Code != BinOpInit::ADD && Code != BinOpInit::SUB &&
+ Code != BinOpInit::AND && Code != BinOpInit::OR &&
+ Code != BinOpInit::XOR && Code != BinOpInit::SRA &&
Code != BinOpInit::SRL && Code != BinOpInit::SHL &&
Code != BinOpInit::MUL)
ArgType = Resolved;
@@ -1311,7 +1311,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
// Deal with BinOps whose arguments have different types, by
// rewriting ArgType in between them.
switch (Code) {
- case BinOpInit::SETDAGOP:
+ case BinOpInit::SETDAGOP:
// After parsing the first dag argument, switch to expecting
// a record, with no restriction on its superclasses.
ArgType = RecordRecTy::get({});
@@ -1341,7 +1341,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
if (Code == BinOpInit::STRCONCAT || Code == BinOpInit::LISTCONCAT ||
Code == BinOpInit::CONCAT || Code == BinOpInit::ADD ||
Code == BinOpInit::AND || Code == BinOpInit::OR ||
- Code == BinOpInit::XOR || Code == BinOpInit::MUL) {
+ Code == BinOpInit::XOR || Code == BinOpInit::MUL) {
while (InitList.size() > 2) {
Init *RHS = InitList.pop_back_val();
RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type))->Fold(CurRec);
@@ -1357,14 +1357,14 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
return nullptr;
}
- case tgtok::XForEach:
- case tgtok::XFilter: {
- return ParseOperationForEachFilter(CurRec, ItemType);
+ case tgtok::XForEach:
+ case tgtok::XFilter: {
+ return ParseOperationForEachFilter(CurRec, ItemType);
}
case tgtok::XDag:
case tgtok::XIf:
- case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
+ case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
TernOpInit::TernaryOp Code;
RecTy *Type = nullptr;
@@ -1499,14 +1499,14 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec);
}
- case tgtok::XSubstr:
- return ParseOperationSubstr(CurRec, ItemType);
-
+ case tgtok::XSubstr:
+ return ParseOperationSubstr(CurRec, ItemType);
+
case tgtok::XCond:
return ParseOperationCond(CurRec, ItemType);
case tgtok::XFoldl: {
- // Value ::= !foldl '(' Value ',' Value ',' Id ',' Id ',' Expr ')'
+ // Value ::= !foldl '(' Value ',' Value ',' Id ',' Id ',' Expr ')'
Lex.Lex(); // eat the operation
if (!consume(tgtok::l_paren)) {
TokError("expected '(' after !foldl");
@@ -1589,8 +1589,8 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
}
Lex.Lex(); // eat the ','
- // We need to create a temporary record to provide a scope for the
- // two variables.
+ // We need to create a temporary record to provide a scope for the
+ // two variables.
std::unique_ptr<Record> ParseRecTmp;
Record *ParseRec = CurRec;
if (!ParseRec) {
@@ -1598,9 +1598,9 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
ParseRec = ParseRecTmp.get();
}
- ParseRec->addValue(RecordVal(A, Start->getType(), RecordVal::FK_Normal));
- ParseRec->addValue(RecordVal(B, ListType->getElementType(),
- RecordVal::FK_Normal));
+ ParseRec->addValue(RecordVal(A, Start->getType(), RecordVal::FK_Normal));
+ ParseRec->addValue(RecordVal(B, ListType->getElementType(),
+ RecordVal::FK_Normal));
Init *ExprUntyped = ParseValue(ParseRec);
ParseRec->removeValue(A);
ParseRec->removeValue(B);
@@ -1644,9 +1644,9 @@ RecTy *TGParser::ParseOperatorType() {
return nullptr;
}
- if (Lex.getCode() == tgtok::Code)
- TokError("the 'code' type is not allowed in bang operators; use 'string'");
-
+ if (Lex.getCode() == tgtok::Code)
+ TokError("the 'code' type is not allowed in bang operators; use 'string'");
+
Type = ParseType();
if (!Type) {
@@ -1662,221 +1662,221 @@ RecTy *TGParser::ParseOperatorType() {
return Type;
}
-/// Parse the !substr operation. Return null on error.
-///
-/// Substr ::= !substr(string, start-int [, length-int]) => string
-Init *TGParser::ParseOperationSubstr(Record *CurRec, RecTy *ItemType) {
- TernOpInit::TernaryOp Code = TernOpInit::SUBSTR;
- RecTy *Type = StringRecTy::get();
-
- Lex.Lex(); // eat the operation
-
- if (!consume(tgtok::l_paren)) {
- TokError("expected '(' after !substr operator");
- return nullptr;
- }
-
- Init *LHS = ParseValue(CurRec);
- if (!LHS)
- return nullptr;
-
- if (!consume(tgtok::comma)) {
- TokError("expected ',' in !substr operator");
- return nullptr;
- }
-
- SMLoc MHSLoc = Lex.getLoc();
- Init *MHS = ParseValue(CurRec);
- if (!MHS)
- return nullptr;
-
- SMLoc RHSLoc = Lex.getLoc();
- Init *RHS;
- if (consume(tgtok::comma)) {
- RHSLoc = Lex.getLoc();
- RHS = ParseValue(CurRec);
- if (!RHS)
- return nullptr;
- } else {
- RHS = IntInit::get(std::numeric_limits<int64_t>::max());
- }
-
- if (!consume(tgtok::r_paren)) {
- TokError("expected ')' in !substr operator");
- return nullptr;
- }
-
- if (ItemType && !Type->typeIsConvertibleTo(ItemType)) {
- Error(RHSLoc, Twine("expected value of type '") +
- ItemType->getAsString() + "', got '" +
- Type->getAsString() + "'");
- }
-
- TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
- if (!LHSt && !isa<UnsetInit>(LHS)) {
- TokError("could not determine type of the string in !substr");
- return nullptr;
- }
- if (LHSt && !isa<StringRecTy>(LHSt->getType())) {
- TokError(Twine("expected string, got type '") +
- LHSt->getType()->getAsString() + "'");
- return nullptr;
- }
-
- TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
- if (!MHSt && !isa<UnsetInit>(MHS)) {
- TokError("could not determine type of the start position in !substr");
- return nullptr;
- }
- if (MHSt && !isa<IntRecTy>(MHSt->getType())) {
- Error(MHSLoc, Twine("expected int, got type '") +
- MHSt->getType()->getAsString() + "'");
- return nullptr;
- }
-
- if (RHS) {
- TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
- if (!RHSt && !isa<UnsetInit>(RHS)) {
- TokError("could not determine type of the length in !substr");
- return nullptr;
- }
- if (RHSt && !isa<IntRecTy>(RHSt->getType())) {
- TokError(Twine("expected int, got type '") +
- RHSt->getType()->getAsString() + "'");
- return nullptr;
- }
- }
-
- return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec);
-}
-
-/// Parse the !foreach and !filter operations. Return null on error.
-///
-/// ForEach ::= !foreach(ID, list-or-dag, expr) => list<expr type>
-/// Filter ::= !foreach(ID, list, predicate) ==> list<list type>
-Init *TGParser::ParseOperationForEachFilter(Record *CurRec, RecTy *ItemType) {
- SMLoc OpLoc = Lex.getLoc();
- tgtok::TokKind Operation = Lex.getCode();
- Lex.Lex(); // eat the operation
- if (Lex.getCode() != tgtok::l_paren) {
- TokError("expected '(' after !foreach/!filter");
- return nullptr;
- }
-
- if (Lex.Lex() != tgtok::Id) { // eat the '('
- TokError("first argument of !foreach/!filter must be an identifier");
- return nullptr;
- }
-
- Init *LHS = StringInit::get(Lex.getCurStrVal());
- Lex.Lex(); // eat the ID.
-
- if (CurRec && CurRec->getValue(LHS)) {
- TokError((Twine("iteration variable '") + LHS->getAsString() +
- "' is already defined")
- .str());
- return nullptr;
- }
-
- if (!consume(tgtok::comma)) {
- TokError("expected ',' in !foreach/!filter");
- return nullptr;
- }
-
- Init *MHS = ParseValue(CurRec);
- if (!MHS)
- return nullptr;
-
- if (!consume(tgtok::comma)) {
- TokError("expected ',' in !foreach/!filter");
- return nullptr;
- }
-
- TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
- if (!MHSt) {
- TokError("could not get type of !foreach/!filter list or dag");
- return nullptr;
- }
-
- RecTy *InEltType = nullptr;
- RecTy *ExprEltType = nullptr;
- bool IsDAG = false;
-
- if (ListRecTy *InListTy = dyn_cast<ListRecTy>(MHSt->getType())) {
- InEltType = InListTy->getElementType();
- if (ItemType) {
- if (ListRecTy *OutListTy = dyn_cast<ListRecTy>(ItemType)) {
- ExprEltType = (Operation == tgtok::XForEach)
- ? OutListTy->getElementType()
- : IntRecTy::get();
- } else {
- Error(OpLoc,
- "expected value of type '" +
- Twine(ItemType->getAsString()) +
- "', but got list type");
- return nullptr;
- }
- }
- } else if (DagRecTy *InDagTy = dyn_cast<DagRecTy>(MHSt->getType())) {
- if (Operation == tgtok::XFilter) {
- TokError("!filter must have a list argument");
- return nullptr;
- }
- InEltType = InDagTy;
- if (ItemType && !isa<DagRecTy>(ItemType)) {
- Error(OpLoc,
- "expected value of type '" + Twine(ItemType->getAsString()) +
- "', but got dag type");
- return nullptr;
- }
- IsDAG = true;
- } else {
- if (Operation == tgtok::XForEach)
- TokError("!foreach must have a list or dag argument");
- else
- TokError("!filter must have a list argument");
- return nullptr;
- }
-
- // We need to create a temporary record to provide a scope for the
- // iteration variable.
- std::unique_ptr<Record> ParseRecTmp;
- Record *ParseRec = CurRec;
- if (!ParseRec) {
- ParseRecTmp =
- std::make_unique<Record>(".parse", ArrayRef<SMLoc>{}, Records);
- ParseRec = ParseRecTmp.get();
- }
-
- ParseRec->addValue(RecordVal(LHS, InEltType, RecordVal::FK_Normal));
- Init *RHS = ParseValue(ParseRec, ExprEltType);
- ParseRec->removeValue(LHS);
- if (!RHS)
- return nullptr;
-
- if (!consume(tgtok::r_paren)) {
- TokError("expected ')' in !foreach/!filter");
- return nullptr;
- }
-
- RecTy *OutType = InEltType;
- if (Operation == tgtok::XForEach && !IsDAG) {
- TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
- if (!RHSt) {
- TokError("could not get type of !foreach result expression");
- return nullptr;
- }
- OutType = RHSt->getType()->getListTy();
- } else if (Operation == tgtok::XFilter) {
- OutType = InEltType->getListTy();
- }
-
- return (TernOpInit::get((Operation == tgtok::XForEach) ? TernOpInit::FOREACH
- : TernOpInit::FILTER,
- LHS, MHS, RHS, OutType))
- ->Fold(CurRec);
-}
-
+/// Parse the !substr operation. Return null on error.
+///
+/// Substr ::= !substr(string, start-int [, length-int]) => string
+Init *TGParser::ParseOperationSubstr(Record *CurRec, RecTy *ItemType) {
+ TernOpInit::TernaryOp Code = TernOpInit::SUBSTR;
+ RecTy *Type = StringRecTy::get();
+
+ Lex.Lex(); // eat the operation
+
+ if (!consume(tgtok::l_paren)) {
+ TokError("expected '(' after !substr operator");
+ return nullptr;
+ }
+
+ Init *LHS = ParseValue(CurRec);
+ if (!LHS)
+ return nullptr;
+
+ if (!consume(tgtok::comma)) {
+ TokError("expected ',' in !substr operator");
+ return nullptr;
+ }
+
+ SMLoc MHSLoc = Lex.getLoc();
+ Init *MHS = ParseValue(CurRec);
+ if (!MHS)
+ return nullptr;
+
+ SMLoc RHSLoc = Lex.getLoc();
+ Init *RHS;
+ if (consume(tgtok::comma)) {
+ RHSLoc = Lex.getLoc();
+ RHS = ParseValue(CurRec);
+ if (!RHS)
+ return nullptr;
+ } else {
+ RHS = IntInit::get(std::numeric_limits<int64_t>::max());
+ }
+
+ if (!consume(tgtok::r_paren)) {
+ TokError("expected ')' in !substr operator");
+ return nullptr;
+ }
+
+ if (ItemType && !Type->typeIsConvertibleTo(ItemType)) {
+ Error(RHSLoc, Twine("expected value of type '") +
+ ItemType->getAsString() + "', got '" +
+ Type->getAsString() + "'");
+ }
+
+ TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
+ if (!LHSt && !isa<UnsetInit>(LHS)) {
+ TokError("could not determine type of the string in !substr");
+ return nullptr;
+ }
+ if (LHSt && !isa<StringRecTy>(LHSt->getType())) {
+ TokError(Twine("expected string, got type '") +
+ LHSt->getType()->getAsString() + "'");
+ return nullptr;
+ }
+
+ TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
+ if (!MHSt && !isa<UnsetInit>(MHS)) {
+ TokError("could not determine type of the start position in !substr");
+ return nullptr;
+ }
+ if (MHSt && !isa<IntRecTy>(MHSt->getType())) {
+ Error(MHSLoc, Twine("expected int, got type '") +
+ MHSt->getType()->getAsString() + "'");
+ return nullptr;
+ }
+
+ if (RHS) {
+ TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
+ if (!RHSt && !isa<UnsetInit>(RHS)) {
+ TokError("could not determine type of the length in !substr");
+ return nullptr;
+ }
+ if (RHSt && !isa<IntRecTy>(RHSt->getType())) {
+ TokError(Twine("expected int, got type '") +
+ RHSt->getType()->getAsString() + "'");
+ return nullptr;
+ }
+ }
+
+ return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec);
+}
+
+/// Parse the !foreach and !filter operations. Return null on error.
+///
+/// ForEach ::= !foreach(ID, list-or-dag, expr) => list<expr type>
+/// Filter ::= !foreach(ID, list, predicate) ==> list<list type>
+Init *TGParser::ParseOperationForEachFilter(Record *CurRec, RecTy *ItemType) {
+ SMLoc OpLoc = Lex.getLoc();
+ tgtok::TokKind Operation = Lex.getCode();
+ Lex.Lex(); // eat the operation
+ if (Lex.getCode() != tgtok::l_paren) {
+ TokError("expected '(' after !foreach/!filter");
+ return nullptr;
+ }
+
+ if (Lex.Lex() != tgtok::Id) { // eat the '('
+ TokError("first argument of !foreach/!filter must be an identifier");
+ return nullptr;
+ }
+
+ Init *LHS = StringInit::get(Lex.getCurStrVal());
+ Lex.Lex(); // eat the ID.
+
+ if (CurRec && CurRec->getValue(LHS)) {
+ TokError((Twine("iteration variable '") + LHS->getAsString() +
+ "' is already defined")
+ .str());
+ return nullptr;
+ }
+
+ if (!consume(tgtok::comma)) {
+ TokError("expected ',' in !foreach/!filter");
+ return nullptr;
+ }
+
+ Init *MHS = ParseValue(CurRec);
+ if (!MHS)
+ return nullptr;
+
+ if (!consume(tgtok::comma)) {
+ TokError("expected ',' in !foreach/!filter");
+ return nullptr;
+ }
+
+ TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
+ if (!MHSt) {
+ TokError("could not get type of !foreach/!filter list or dag");
+ return nullptr;
+ }
+
+ RecTy *InEltType = nullptr;
+ RecTy *ExprEltType = nullptr;
+ bool IsDAG = false;
+
+ if (ListRecTy *InListTy = dyn_cast<ListRecTy>(MHSt->getType())) {
+ InEltType = InListTy->getElementType();
+ if (ItemType) {
+ if (ListRecTy *OutListTy = dyn_cast<ListRecTy>(ItemType)) {
+ ExprEltType = (Operation == tgtok::XForEach)
+ ? OutListTy->getElementType()
+ : IntRecTy::get();
+ } else {
+ Error(OpLoc,
+ "expected value of type '" +
+ Twine(ItemType->getAsString()) +
+ "', but got list type");
+ return nullptr;
+ }
+ }
+ } else if (DagRecTy *InDagTy = dyn_cast<DagRecTy>(MHSt->getType())) {
+ if (Operation == tgtok::XFilter) {
+ TokError("!filter must have a list argument");
+ return nullptr;
+ }
+ InEltType = InDagTy;
+ if (ItemType && !isa<DagRecTy>(ItemType)) {
+ Error(OpLoc,
+ "expected value of type '" + Twine(ItemType->getAsString()) +
+ "', but got dag type");
+ return nullptr;
+ }
+ IsDAG = true;
+ } else {
+ if (Operation == tgtok::XForEach)
+ TokError("!foreach must have a list or dag argument");
+ else
+ TokError("!filter must have a list argument");
+ return nullptr;
+ }
+
+ // We need to create a temporary record to provide a scope for the
+ // iteration variable.
+ std::unique_ptr<Record> ParseRecTmp;
+ Record *ParseRec = CurRec;
+ if (!ParseRec) {
+ ParseRecTmp =
+ std::make_unique<Record>(".parse", ArrayRef<SMLoc>{}, Records);
+ ParseRec = ParseRecTmp.get();
+ }
+
+ ParseRec->addValue(RecordVal(LHS, InEltType, RecordVal::FK_Normal));
+ Init *RHS = ParseValue(ParseRec, ExprEltType);
+ ParseRec->removeValue(LHS);
+ if (!RHS)
+ return nullptr;
+
+ if (!consume(tgtok::r_paren)) {
+ TokError("expected ')' in !foreach/!filter");
+ return nullptr;
+ }
+
+ RecTy *OutType = InEltType;
+ if (Operation == tgtok::XForEach && !IsDAG) {
+ TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
+ if (!RHSt) {
+ TokError("could not get type of !foreach result expression");
+ return nullptr;
+ }
+ OutType = RHSt->getType()->getListTy();
+ } else if (Operation == tgtok::XFilter) {
+ OutType = InEltType->getListTy();
+ }
+
+ return (TernOpInit::get((Operation == tgtok::XForEach) ? TernOpInit::FOREACH
+ : TernOpInit::FILTER,
+ LHS, MHS, RHS, OutType))
+ ->Fold(CurRec);
+}
+
Init *TGParser::ParseOperationCond(Record *CurRec, RecTy *ItemType) {
Lex.Lex(); // eat the operation 'cond'
@@ -1968,7 +1968,7 @@ Init *TGParser::ParseOperationCond(Record *CurRec, RecTy *ItemType) {
/// SimpleValue ::= '(' IDValue DagArgList ')'
/// SimpleValue ::= CONCATTOK '(' Value ',' Value ')'
/// SimpleValue ::= ADDTOK '(' Value ',' Value ')'
-/// SimpleValue ::= SUBTOK '(' Value ',' Value ')'
+/// SimpleValue ::= SUBTOK '(' Value ',' Value ')'
/// SimpleValue ::= SHLTOK '(' Value ',' Value ')'
/// SimpleValue ::= SRATOK '(' Value ',' Value ')'
/// SimpleValue ::= SRLTOK '(' Value ',' Value ')'
@@ -1981,20 +1981,20 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
IDParseMode Mode) {
Init *R = nullptr;
switch (Lex.getCode()) {
- default: TokError("Unknown or reserved token when parsing a value"); break;
-
- case tgtok::TrueVal:
- R = IntInit::get(1);
- Lex.Lex();
- break;
- case tgtok::FalseVal:
- R = IntInit::get(0);
- Lex.Lex();
- break;
- case tgtok::IntVal:
- R = IntInit::get(Lex.getCurIntVal());
- Lex.Lex();
- break;
+ default: TokError("Unknown or reserved token when parsing a value"); break;
+
+ case tgtok::TrueVal:
+ R = IntInit::get(1);
+ Lex.Lex();
+ break;
+ case tgtok::FalseVal:
+ R = IntInit::get(0);
+ Lex.Lex();
+ break;
+ case tgtok::IntVal:
+ R = IntInit::get(Lex.getCurIntVal());
+ Lex.Lex();
+ break;
case tgtok::BinaryIntVal: {
auto BinaryVal = Lex.getCurBinaryIntVal();
SmallVector<Init*, 16> Bits(BinaryVal.second);
@@ -2018,7 +2018,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
break;
}
case tgtok::CodeFragment:
- R = StringInit::get(Lex.getCurStrVal(), StringInit::SF_Code);
+ R = StringInit::get(Lex.getCurStrVal(), StringInit::SF_Code);
Lex.Lex();
break;
case tgtok::question:
@@ -2149,7 +2149,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
if (ItemType) {
ListRecTy *ListType = dyn_cast<ListRecTy>(ItemType);
if (!ListType) {
- TokError(Twine("Encountered a list when expecting a ") +
+ TokError(Twine("Encountered a list when expecting a ") +
ItemType->getAsString());
return nullptr;
}
@@ -2233,7 +2233,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')'
Lex.Lex(); // eat the '('
if (Lex.getCode() != tgtok::Id && Lex.getCode() != tgtok::XCast &&
- Lex.getCode() != tgtok::question && Lex.getCode() != tgtok::XGetDagOp) {
+ Lex.getCode() != tgtok::question && Lex.getCode() != tgtok::XGetDagOp) {
TokError("expected identifier in dag init");
return nullptr;
}
@@ -2271,17 +2271,17 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
case tgtok::XSize:
case tgtok::XEmpty:
case tgtok::XCast:
- case tgtok::XGetDagOp: // Value ::= !unop '(' Value ')'
+ case tgtok::XGetDagOp: // Value ::= !unop '(' Value ')'
case tgtok::XIsA:
case tgtok::XConcat:
case tgtok::XDag:
case tgtok::XADD:
- case tgtok::XSUB:
+ case tgtok::XSUB:
case tgtok::XMUL:
- case tgtok::XNOT:
+ case tgtok::XNOT:
case tgtok::XAND:
case tgtok::XOR:
- case tgtok::XXOR:
+ case tgtok::XXOR:
case tgtok::XSRA:
case tgtok::XSRL:
case tgtok::XSHL:
@@ -2294,15 +2294,15 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
case tgtok::XListConcat:
case tgtok::XListSplat:
case tgtok::XStrConcat:
- case tgtok::XInterleave:
- case tgtok::XSetDagOp: // Value ::= !binop '(' Value ',' Value ')'
+ case tgtok::XInterleave:
+ case tgtok::XSetDagOp: // Value ::= !binop '(' Value ',' Value ')'
case tgtok::XIf:
case tgtok::XCond:
case tgtok::XFoldl:
case tgtok::XForEach:
- case tgtok::XFilter:
- case tgtok::XSubst:
- case tgtok::XSubstr: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
+ case tgtok::XFilter:
+ case tgtok::XSubst:
+ case tgtok::XSubstr: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
return ParseOperation(CurRec, ItemType);
}
}
@@ -2310,7 +2310,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
return R;
}
-/// ParseValue - Parse a TableGen value. This returns null on error.
+/// ParseValue - Parse a TableGen value. This returns null on error.
///
/// Value ::= SimpleValue ValueSuffix*
/// ValueSuffix ::= '{' BitList '}'
@@ -2371,8 +2371,8 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
}
break;
}
- case tgtok::dot: {
- if (Lex.Lex() != tgtok::Id) { // eat the .
+ case tgtok::dot: {
+ if (Lex.Lex() != tgtok::Id) { // eat the .
TokError("expected field identifier after '.'");
return nullptr;
}
@@ -2399,8 +2399,8 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
if (isa<ListRecTy>(LHS->getType())) {
Lex.Lex(); // Eat the '#'.
- assert(Mode == ParseValueMode && "encountered paste of lists in name");
-
+ assert(Mode == ParseValueMode && "encountered paste of lists in name");
+
switch (Lex.getCode()) {
case tgtok::colon:
case tgtok::semi:
@@ -2408,11 +2408,11 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
Result = LHS; // trailing paste, ignore.
break;
default:
- Init *RHSResult = ParseValue(CurRec, ItemType, ParseValueMode);
- if (!RHSResult)
- return nullptr;
+ Init *RHSResult = ParseValue(CurRec, ItemType, ParseValueMode);
+ if (!RHSResult)
+ return nullptr;
Result = BinOpInit::getListConcat(LHS, RHSResult);
- break;
+ break;
}
break;
}
@@ -2448,8 +2448,8 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
default:
Init *RHSResult = ParseValue(CurRec, nullptr, ParseNameMode);
- if (!RHSResult)
- return nullptr;
+ if (!RHSResult)
+ return nullptr;
RHS = dyn_cast<TypedInit>(RHSResult);
if (!RHS) {
Error(PasteLoc, "RHS of paste is not typed!");
@@ -2621,10 +2621,10 @@ Init *TGParser::ParseDeclaration(Record *CurRec,
"::");
}
- // Add the field to the record.
- if (AddValue(CurRec, IdLoc, RecordVal(DeclName, IdLoc, Type,
- HasField ? RecordVal::FK_NonconcreteOK
- : RecordVal::FK_Normal)))
+ // Add the field to the record.
+ if (AddValue(CurRec, IdLoc, RecordVal(DeclName, IdLoc, Type,
+ HasField ? RecordVal::FK_NonconcreteOK
+ : RecordVal::FK_Normal)))
return nullptr;
// If a value is present, parse it.
@@ -2765,16 +2765,16 @@ bool TGParser::ParseTemplateArgList(Record *CurRec) {
return false;
}
-/// ParseBodyItem - Parse a single item within the body of a def or class.
+/// ParseBodyItem - Parse a single item within the body of a def or class.
///
/// BodyItem ::= Declaration ';'
/// BodyItem ::= LET ID OptionalBitList '=' Value ';'
/// BodyItem ::= Defvar
-/// BodyItem ::= Assert
+/// BodyItem ::= Assert
bool TGParser::ParseBodyItem(Record *CurRec) {
- if (Lex.getCode() == tgtok::Assert)
- return ParseAssert(nullptr, CurRec);
-
+ if (Lex.getCode() == tgtok::Assert)
+ return ParseAssert(nullptr, CurRec);
+
if (Lex.getCode() == tgtok::Defvar)
return ParseDefvar();
@@ -2836,7 +2836,7 @@ bool TGParser::ParseBody(Record *CurRec) {
return false;
if (!consume(tgtok::l_brace))
- return TokError("Expected '{' to start body or ';' for declaration only");
+ return TokError("Expected '{' to start body or ';' for declaration only");
// An object body introduces a new scope for local variables.
TGLocalVarScope *BodyScope = PushLocalScope();
@@ -2849,14 +2849,14 @@ bool TGParser::ParseBody(Record *CurRec) {
// Eat the '}'.
Lex.Lex();
-
- // If we have a semicolon, print a gentle error.
- SMLoc SemiLoc = Lex.getLoc();
- if (consume(tgtok::semi)) {
- PrintError(SemiLoc, "A class or def body should not end with a semicolon");
- PrintNote("Semicolon ignored; remove to eliminate this error");
- }
-
+
+ // If we have a semicolon, print a gentle error.
+ SMLoc SemiLoc = Lex.getLoc();
+ if (consume(tgtok::semi)) {
+ PrintError(SemiLoc, "A class or def body should not end with a semicolon");
+ PrintNote("Semicolon ignored; remove to eliminate this error");
+ }
+
return false;
}
@@ -3188,41 +3188,41 @@ bool TGParser::ParseIfBody(MultiClass *CurMultiClass, StringRef Kind) {
return false;
}
-/// ParseAssert - Parse an assert statement.
-///
-/// Assert ::= ASSERT condition , message ;
-bool TGParser::ParseAssert(MultiClass *CurMultiClass, Record *CurRec) {
- assert(Lex.getCode() == tgtok::Assert && "Unknown tok");
- Lex.Lex(); // Eat the 'assert' token.
-
- SMLoc ConditionLoc = Lex.getLoc();
- Init *Condition = ParseValue(CurRec);
- if (!Condition)
- return true;
-
- if (!consume(tgtok::comma)) {
- TokError("expected ',' in assert statement");
- return true;
- }
-
- Init *Message = ParseValue(CurRec);
- if (!Message)
- return true;
-
- if (!consume(tgtok::semi))
- return TokError("expected ';'");
-
- if (CurMultiClass) {
- assert(false && "assert in multiclass not yet supported");
- } else if (CurRec) {
- CurRec->addAssertion(ConditionLoc, Condition, Message);
- } else { // at top level
- CheckAssert(ConditionLoc, Condition, Message);
- }
-
- return false;
-}
+/// ParseAssert - Parse an assert statement.
+///
+/// Assert ::= ASSERT condition , message ;
+bool TGParser::ParseAssert(MultiClass *CurMultiClass, Record *CurRec) {
+ assert(Lex.getCode() == tgtok::Assert && "Unknown tok");
+ Lex.Lex(); // Eat the 'assert' token.
+
+ SMLoc ConditionLoc = Lex.getLoc();
+ Init *Condition = ParseValue(CurRec);
+ if (!Condition)
+ return true;
+
+ if (!consume(tgtok::comma)) {
+ TokError("expected ',' in assert statement");
+ return true;
+ }
+
+ Init *Message = ParseValue(CurRec);
+ if (!Message)
+ return true;
+
+ if (!consume(tgtok::semi))
+ return TokError("expected ';'");
+
+ if (CurMultiClass) {
+ assert(false && "assert in multiclass not yet supported");
+ } else if (CurRec) {
+ CurRec->addAssertion(ConditionLoc, Condition, Message);
+ } else { // at top level
+ CheckAssert(ConditionLoc, Condition, Message);
+ }
+ return false;
+}
+
/// ParseClass - Parse a tblgen class definition.
///
/// ClassInst ::= CLASS ID TemplateArgList? ObjectBody
@@ -3422,17 +3422,17 @@ bool TGParser::ParseMultiClass() {
while (Lex.getCode() != tgtok::r_brace) {
switch (Lex.getCode()) {
default:
- return TokError("expected 'assert', 'def', 'defm', 'defvar', "
- "'foreach', 'if', or 'let' in multiclass body");
- case tgtok::Assert:
- return TokError("an assert statement in a multiclass is not yet supported");
-
+ return TokError("expected 'assert', 'def', 'defm', 'defvar', "
+ "'foreach', 'if', or 'let' in multiclass body");
+ case tgtok::Assert:
+ return TokError("an assert statement in a multiclass is not yet supported");
+
case tgtok::Def:
case tgtok::Defm:
case tgtok::Defvar:
case tgtok::Foreach:
case tgtok::If:
- case tgtok::Let:
+ case tgtok::Let:
if (ParseObject(CurMultiClass))
return true;
break;
@@ -3440,13 +3440,13 @@ bool TGParser::ParseMultiClass() {
}
Lex.Lex(); // eat the '}'.
- // If we have a semicolon, print a gentle error.
- SMLoc SemiLoc = Lex.getLoc();
- if (consume(tgtok::semi)) {
- PrintError(SemiLoc, "A multiclass body should not end with a semicolon");
- PrintNote("Semicolon ignored; remove to eliminate this error");
- }
-
+ // If we have a semicolon, print a gentle error.
+ SMLoc SemiLoc = Lex.getLoc();
+ if (consume(tgtok::semi)) {
+ PrintError(SemiLoc, "A multiclass body should not end with a semicolon");
+ PrintNote("Semicolon ignored; remove to eliminate this error");
+ }
+
PopLocalScope(MulticlassScope);
}
@@ -3590,19 +3590,19 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
/// Object ::= LETCommand Object
/// Object ::= Defset
/// Object ::= Defvar
-/// Object ::= Assert
+/// Object ::= Assert
bool TGParser::ParseObject(MultiClass *MC) {
switch (Lex.getCode()) {
default:
- return TokError(
- "Expected assert, class, def, defm, defset, foreach, if, or let");
- case tgtok::Assert: return ParseAssert(MC, nullptr);
- case tgtok::Def: return ParseDef(MC);
- case tgtok::Defm: return ParseDefm(MC);
- case tgtok::Defvar: return ParseDefvar();
- case tgtok::Foreach: return ParseForeach(MC);
- case tgtok::If: return ParseIf(MC);
- case tgtok::Let: return ParseTopLevelLet(MC);
+ return TokError(
+ "Expected assert, class, def, defm, defset, foreach, if, or let");
+ case tgtok::Assert: return ParseAssert(MC, nullptr);
+ case tgtok::Def: return ParseDef(MC);
+ case tgtok::Defm: return ParseDefm(MC);
+ case tgtok::Defvar: return ParseDefvar();
+ case tgtok::Foreach: return ParseForeach(MC);
+ case tgtok::If: return ParseIf(MC);
+ case tgtok::Let: return ParseTopLevelLet(MC);
case tgtok::Defset:
if (MC)
return TokError("defset is not allowed inside multiclass");
@@ -3638,40 +3638,40 @@ bool TGParser::ParseFile() {
if (Lex.getCode() == tgtok::Eof)
return false;
- return TokError("Unexpected token at top level");
-}
-
-// Check an assertion: Obtain the condition value and be sure it is true.
-// If not, print a nonfatal error along with the message.
-void TGParser::CheckAssert(SMLoc Loc, Init *Condition, Init *Message) {
- auto *CondValue = dyn_cast_or_null<IntInit>(
- Condition->convertInitializerTo(IntRecTy::get()));
- if (CondValue) {
- if (!CondValue->getValue()) {
- PrintError(Loc, "assertion failed");
- if (auto *MessageInit = dyn_cast<StringInit>(Message))
- PrintNote(MessageInit->getValue());
- else
- PrintNote("(assert message is not a string)");
- }
- } else {
- PrintError(Loc, "assert condition must of type bit, bits, or int.");
- }
-}
-
-// Check all record assertions: For each one, resolve the condition
-// and message, then call CheckAssert().
-void TGParser::CheckRecordAsserts(Record &Rec) {
- RecordResolver R(Rec);
- R.setFinal(true);
-
- for (auto Assertion : Rec.getAssertions()) {
- Init *Condition = std::get<1>(Assertion)->resolveReferences(R);
- Init *Message = std::get<2>(Assertion)->resolveReferences(R);
- CheckAssert(std::get<0>(Assertion), Condition, Message);
- }
-}
-
+ return TokError("Unexpected token at top level");
+}
+
+// Check an assertion: Obtain the condition value and be sure it is true.
+// If not, print a nonfatal error along with the message.
+void TGParser::CheckAssert(SMLoc Loc, Init *Condition, Init *Message) {
+ auto *CondValue = dyn_cast_or_null<IntInit>(
+ Condition->convertInitializerTo(IntRecTy::get()));
+ if (CondValue) {
+ if (!CondValue->getValue()) {
+ PrintError(Loc, "assertion failed");
+ if (auto *MessageInit = dyn_cast<StringInit>(Message))
+ PrintNote(MessageInit->getValue());
+ else
+ PrintNote("(assert message is not a string)");
+ }
+ } else {
+ PrintError(Loc, "assert condition must of type bit, bits, or int.");
+ }
+}
+
+// Check all record assertions: For each one, resolve the condition
+// and message, then call CheckAssert().
+void TGParser::CheckRecordAsserts(Record &Rec) {
+ RecordResolver R(Rec);
+ R.setFinal(true);
+
+ for (auto Assertion : Rec.getAssertions()) {
+ Init *Condition = std::get<1>(Assertion)->resolveReferences(R);
+ Init *Message = std::get<2>(Assertion)->resolveReferences(R);
+ CheckAssert(std::get<0>(Assertion), Condition, Message);
+ }
+}
+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void RecordsEntry::dump() const {
if (Loop)
diff --git a/contrib/libs/llvm12/lib/TableGen/TGParser.h b/contrib/libs/llvm12/lib/TableGen/TGParser.h
index 3f1f5d7089..578a56c9d0 100644
--- a/contrib/libs/llvm12/lib/TableGen/TGParser.h
+++ b/contrib/libs/llvm12/lib/TableGen/TGParser.h
@@ -222,7 +222,7 @@ private: // Parser methods.
bool ParseForeach(MultiClass *CurMultiClass);
bool ParseIf(MultiClass *CurMultiClass);
bool ParseIfBody(MultiClass *CurMultiClass, StringRef Kind);
- bool ParseAssert(MultiClass *CurMultiClass, Record *CurRec);
+ bool ParseAssert(MultiClass *CurMultiClass, Record *CurRec);
bool ParseTopLevelLet(MultiClass *CurMultiClass);
void ParseLetList(SmallVectorImpl<LetRecord> &Result);
@@ -255,8 +255,8 @@ private: // Parser methods.
TypedInit *FirstItem = nullptr);
RecTy *ParseType();
Init *ParseOperation(Record *CurRec, RecTy *ItemType);
- Init *ParseOperationSubstr(Record *CurRec, RecTy *ItemType);
- Init *ParseOperationForEachFilter(Record *CurRec, RecTy *ItemType);
+ Init *ParseOperationSubstr(Record *CurRec, RecTy *ItemType);
+ Init *ParseOperationForEachFilter(Record *CurRec, RecTy *ItemType);
Init *ParseOperationCond(Record *CurRec, RecTy *ItemType);
RecTy *ParseOperatorType();
Init *ParseObjectName(MultiClass *CurMultiClass);
@@ -264,8 +264,8 @@ private: // Parser methods.
MultiClass *ParseMultiClassID();
bool ApplyLetStack(Record *CurRec);
bool ApplyLetStack(RecordsEntry &Entry);
- void CheckAssert(SMLoc Loc, Init *Condition, Init *Message);
- void CheckRecordAsserts(Record &Rec);
+ void CheckAssert(SMLoc Loc, Init *Condition, Init *Message);
+ void CheckRecordAsserts(Record &Rec);
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/TableGen/TableGenBackendSkeleton.cpp b/contrib/libs/llvm12/lib/TableGen/TableGenBackendSkeleton.cpp
index c375d3cc3a..4ce88e003e 100644
--- a/contrib/libs/llvm12/lib/TableGen/TableGenBackendSkeleton.cpp
+++ b/contrib/libs/llvm12/lib/TableGen/TableGenBackendSkeleton.cpp
@@ -1,64 +1,64 @@
-//===- SkeletonEmitter.cpp - Skeleton TableGen backend -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This Tablegen backend emits ...
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/TableGen/Error.h"
-#include "llvm/TableGen/Record.h"
-#include "llvm/TableGen/TableGenBackend.h"
-#include <algorithm>
-#include <set>
-#include <string>
-#include <vector>
-
-#define DEBUG_TYPE "skeleton-emitter"
-
-using namespace llvm;
-
-namespace {
-
-// Any helper data structures can be defined here. Some backends use
-// structs to collect information from the records.
-
-class SkeletonEmitter {
-private:
- RecordKeeper &Records;
-
-public:
- SkeletonEmitter(RecordKeeper &RK) : Records(RK) {}
-
- void run(raw_ostream &OS);
-}; // emitter class
-
-} // anonymous namespace
-
-void SkeletonEmitter::run(raw_ostream &OS) {
- emitSourceFileHeader("Skeleton data structures", OS);
-
- (void)Records; // To suppress unused variable warning; remove on use.
-}
-
-namespace llvm {
-
-// The only thing that should be in the llvm namespace is the
-// emitter entry point function.
-
-void EmitSkeleton(RecordKeeper &RK, raw_ostream &OS) {
- // Instantiate the emitter class and invoke run().
- SkeletonEmitter(RK).run(OS);
-}
-
-} // namespace llvm
+//===- SkeletonEmitter.cpp - Skeleton TableGen backend -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This Tablegen backend emits ...
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
+#include <algorithm>
+#include <set>
+#include <string>
+#include <vector>
+
+#define DEBUG_TYPE "skeleton-emitter"
+
+using namespace llvm;
+
+namespace {
+
+// Any helper data structures can be defined here. Some backends use
+// structs to collect information from the records.
+
+class SkeletonEmitter {
+private:
+ RecordKeeper &Records;
+
+public:
+ SkeletonEmitter(RecordKeeper &RK) : Records(RK) {}
+
+ void run(raw_ostream &OS);
+}; // emitter class
+
+} // anonymous namespace
+
+void SkeletonEmitter::run(raw_ostream &OS) {
+ emitSourceFileHeader("Skeleton data structures", OS);
+
+ (void)Records; // To suppress unused variable warning; remove on use.
+}
+
+namespace llvm {
+
+// The only thing that should be in the llvm namespace is the
+// emitter entry point function.
+
+void EmitSkeleton(RecordKeeper &RK, raw_ostream &OS) {
+ // Instantiate the emitter class and invoke run().
+ SkeletonEmitter(RK).run(OS);
+}
+
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/TableGen/ya.make b/contrib/libs/llvm12/lib/TableGen/ya.make
index 0ffe53763d..a5ef0f22ef 100644
--- a/contrib/libs/llvm12/lib/TableGen/ya.make
+++ b/contrib/libs/llvm12/lib/TableGen/ya.make
@@ -12,8 +12,8 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
@@ -25,7 +25,7 @@ NO_COMPILER_WARNINGS()
NO_UTIL()
SRCS(
- DetailedRecordsBackend.cpp
+ DetailedRecordsBackend.cpp
Error.cpp
JSONBackend.cpp
Main.cpp
@@ -35,7 +35,7 @@ SRCS(
TGLexer.cpp
TGParser.cpp
TableGenBackend.cpp
- TableGenBackendSkeleton.cpp
+ TableGenBackendSkeleton.cpp
)
END()
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64.h b/contrib/libs/llvm12/lib/Target/AArch64/AArch64.h
index 88d25e474e..d2170a99e0 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64.h
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64.h
@@ -58,10 +58,10 @@ ModulePass *createSVEIntrinsicOptsPass();
InstructionSelector *
createAArch64InstructionSelector(const AArch64TargetMachine &,
AArch64Subtarget &, AArch64RegisterBankInfo &);
-FunctionPass *createAArch64PreLegalizerCombiner(bool IsOptNone);
-FunctionPass *createAArch64PostLegalizerCombiner(bool IsOptNone);
-FunctionPass *createAArch64PostLegalizerLowering();
-FunctionPass *createAArch64PostSelectOptimize();
+FunctionPass *createAArch64PreLegalizerCombiner(bool IsOptNone);
+FunctionPass *createAArch64PostLegalizerCombiner(bool IsOptNone);
+FunctionPass *createAArch64PostLegalizerLowering();
+FunctionPass *createAArch64PostSelectOptimize();
FunctionPass *createAArch64StackTaggingPass(bool IsOptNone);
FunctionPass *createAArch64StackTaggingPreRAPass();
@@ -82,8 +82,8 @@ void initializeAArch64LoadStoreOptPass(PassRegistry&);
void initializeAArch64SIMDInstrOptPass(PassRegistry&);
void initializeAArch64PreLegalizerCombinerPass(PassRegistry&);
void initializeAArch64PostLegalizerCombinerPass(PassRegistry &);
-void initializeAArch64PostLegalizerLoweringPass(PassRegistry &);
-void initializeAArch64PostSelectOptimizePass(PassRegistry &);
+void initializeAArch64PostLegalizerLoweringPass(PassRegistry &);
+void initializeAArch64PostSelectOptimizePass(PassRegistry &);
void initializeAArch64PromoteConstantPass(PassRegistry&);
void initializeAArch64RedundantCopyEliminationPass(PassRegistry&);
void initializeAArch64StorePairSuppressPass(PassRegistry&);
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64.td b/contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
index 385216a208..762855207d 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64.td
@@ -61,9 +61,9 @@ def FeatureRAS : SubtargetFeature<"ras", "HasRAS", "true",
def FeatureLSE : SubtargetFeature<"lse", "HasLSE", "true",
"Enable ARMv8.1 Large System Extension (LSE) atomic instructions">;
-def FeatureOutlineAtomics : SubtargetFeature<"outline-atomics", "OutlineAtomics", "true",
- "Enable out of line atomics to support LSE instructions">;
-
+def FeatureOutlineAtomics : SubtargetFeature<"outline-atomics", "OutlineAtomics", "true",
+ "Enable out of line atomics to support LSE instructions">;
+
def FeatureRDM : SubtargetFeature<"rdm", "HasRDM", "true",
"Enable ARMv8.1 Rounding Double Multiply Add/Subtract instructions">;
@@ -75,12 +75,12 @@ def FeatureLOR : SubtargetFeature<
"lor", "HasLOR", "true",
"Enables ARM v8.1 Limited Ordering Regions extension">;
-def FeatureCONTEXTIDREL2 : SubtargetFeature<"CONTEXTIDREL2", "HasCONTEXTIDREL2",
- "true", "Enable RW operand CONTEXTIDR_EL2" >;
+def FeatureCONTEXTIDREL2 : SubtargetFeature<"CONTEXTIDREL2", "HasCONTEXTIDREL2",
+ "true", "Enable RW operand CONTEXTIDR_EL2" >;
+
+def FeatureVH : SubtargetFeature<"vh", "HasVH", "true",
+ "Enables ARM v8.1 Virtual Host extension", [FeatureCONTEXTIDREL2] >;
-def FeatureVH : SubtargetFeature<"vh", "HasVH", "true",
- "Enables ARM v8.1 Virtual Host extension", [FeatureCONTEXTIDREL2] >;
-
def FeaturePerfMon : SubtargetFeature<"perfmon", "HasPerfMon", "true",
"Enable ARMv8 PMUv3 Performance Monitors extension">;
@@ -218,10 +218,10 @@ def FeatureArithmeticCbzFusion : SubtargetFeature<
"arith-cbz-fusion", "HasArithmeticCbzFusion", "true",
"CPU fuses arithmetic + cbz/cbnz operations">;
-def FeatureCmpBccFusion : SubtargetFeature<
- "cmp-bcc-fusion", "HasCmpBccFusion", "true",
- "CPU fuses cmp+bcc operations">;
-
+def FeatureCmpBccFusion : SubtargetFeature<
+ "cmp-bcc-fusion", "HasCmpBccFusion", "true",
+ "CPU fuses cmp+bcc operations">;
+
def FeatureFuseAddress : SubtargetFeature<
"fuse-address", "HasFuseAddress", "true",
"CPU fuses address generation and memory operations">;
@@ -265,8 +265,8 @@ def FeatureDotProd : SubtargetFeature<
"dotprod", "HasDotProd", "true",
"Enable dot product support">;
-def FeaturePAuth : SubtargetFeature<
- "pauth", "HasPAuth", "true",
+def FeaturePAuth : SubtargetFeature<
+ "pauth", "HasPAuth", "true",
"Enable v8.3-A Pointer Authentication extension">;
def FeatureJS : SubtargetFeature<
@@ -320,8 +320,8 @@ def FeatureTLB_RMI : SubtargetFeature<
"tlb-rmi", "HasTLB_RMI", "true",
"Enable v8.4-A TLB Range and Maintenance Instructions">;
-def FeatureFlagM : SubtargetFeature<
- "flagm", "HasFlagM", "true",
+def FeatureFlagM : SubtargetFeature<
+ "flagm", "HasFlagM", "true",
"Enable v8.4-A Flag Manipulation Instructions">;
// 8.4 RCPC enchancements: LDAPR & STLR instructions with Immediate Offset
@@ -404,24 +404,24 @@ def FeatureMatMulFP32 : SubtargetFeature<"f32mm", "HasMatMulFP32",
def FeatureMatMulFP64 : SubtargetFeature<"f64mm", "HasMatMulFP64",
"true", "Enable Matrix Multiply FP64 Extension", [FeatureSVE]>;
-def FeatureXS : SubtargetFeature<"xs", "HasXS",
- "true", "Enable Armv8.7-A limited-TLB-maintenance instruction">;
-
-def FeatureWFxT : SubtargetFeature<"wfxt", "HasWFxT",
- "true", "Enable Armv8.7-A WFET and WFIT instruction">;
-
-def FeatureHCX : SubtargetFeature<
- "hcx", "HasHCX", "true", "Enable Armv8.7-A HCRX_EL2 system register">;
-
-def FeatureLS64 : SubtargetFeature<"ls64", "HasLS64",
- "true", "Enable Armv8.7-A LD64B/ST64B Accelerator Extension">;
-
-def FeatureBRBE : SubtargetFeature<"brbe", "HasBRBE",
- "true", "Enable Branch Record Buffer Extension">;
-
-def FeatureSPE_EEF : SubtargetFeature<"spe-eef", "HasSPE_EEF",
- "true", "Enable extra register in the Statistical Profiling Extension">;
-
+def FeatureXS : SubtargetFeature<"xs", "HasXS",
+ "true", "Enable Armv8.7-A limited-TLB-maintenance instruction">;
+
+def FeatureWFxT : SubtargetFeature<"wfxt", "HasWFxT",
+ "true", "Enable Armv8.7-A WFET and WFIT instruction">;
+
+def FeatureHCX : SubtargetFeature<
+ "hcx", "HasHCX", "true", "Enable Armv8.7-A HCRX_EL2 system register">;
+
+def FeatureLS64 : SubtargetFeature<"ls64", "HasLS64",
+ "true", "Enable Armv8.7-A LD64B/ST64B Accelerator Extension">;
+
+def FeatureBRBE : SubtargetFeature<"brbe", "HasBRBE",
+ "true", "Enable Branch Record Buffer Extension">;
+
+def FeatureSPE_EEF : SubtargetFeature<"spe-eef", "HasSPE_EEF",
+ "true", "Enable extra register in the Statistical Profiling Extension">;
+
def FeatureFineGrainedTraps : SubtargetFeature<"fgt", "HasFineGrainedTraps",
"true", "Enable fine grained virtualization traps extension">;
@@ -442,14 +442,14 @@ def HasV8_2aOps : SubtargetFeature<"v8.2a", "HasV8_2aOps", "true",
FeaturePAN_RWV, FeatureRAS, FeatureCCPP]>;
def HasV8_3aOps : SubtargetFeature<"v8.3a", "HasV8_3aOps", "true",
- "Support ARM v8.3a instructions", [HasV8_2aOps, FeatureRCPC, FeaturePAuth,
+ "Support ARM v8.3a instructions", [HasV8_2aOps, FeatureRCPC, FeaturePAuth,
FeatureJS, FeatureCCIDX, FeatureComplxNum]>;
def HasV8_4aOps : SubtargetFeature<"v8.4a", "HasV8_4aOps", "true",
"Support ARM v8.4a instructions", [HasV8_3aOps, FeatureDotProd,
- FeatureNV, FeatureMPAM, FeatureDIT,
+ FeatureNV, FeatureMPAM, FeatureDIT,
FeatureTRACEV8_4, FeatureAM, FeatureSEL2, FeaturePMU, FeatureTLB_RMI,
- FeatureFlagM, FeatureRCPC_IMMO]>;
+ FeatureFlagM, FeatureRCPC_IMMO]>;
def HasV8_5aOps : SubtargetFeature<
"v8.5a", "HasV8_5aOps", "true", "Support ARM v8.5a instructions",
@@ -462,26 +462,26 @@ def HasV8_6aOps : SubtargetFeature<
[HasV8_5aOps, FeatureAMVS, FeatureBF16, FeatureFineGrainedTraps,
FeatureEnhancedCounterVirtualization, FeatureMatMulInt8]>;
-def HasV8_7aOps : SubtargetFeature<
- "v8.7a", "HasV8_7aOps", "true", "Support ARM v8.7a instructions",
- [HasV8_6aOps, FeatureXS, FeatureWFxT, FeatureHCX]>;
-
-def HasV8_0rOps : SubtargetFeature<
- "v8r", "HasV8_0rOps", "true", "Support ARM v8r instructions",
- [//v8.1
- FeatureCRC, FeaturePAN, FeatureRDM, FeatureLSE, FeatureCONTEXTIDREL2,
- //v8.2
- FeaturePerfMon, FeatureRAS, FeaturePsUAO, FeatureSM4,
- FeatureSHA3, FeatureCCPP, FeatureFullFP16, FeaturePAN_RWV,
- //v8.3
- FeatureComplxNum, FeatureCCIDX, FeatureJS,
- FeaturePAuth, FeatureRCPC,
- //v8.4
- FeatureDotProd, FeatureFP16FML, FeatureTRACEV8_4,
- FeatureTLB_RMI, FeatureFlagM, FeatureDIT, FeatureSEL2, FeatureRCPC_IMMO,
- //v8.5
- FeatureSSBS, FeaturePredRes, FeatureSB, FeatureSpecRestrict]>;
-
+def HasV8_7aOps : SubtargetFeature<
+ "v8.7a", "HasV8_7aOps", "true", "Support ARM v8.7a instructions",
+ [HasV8_6aOps, FeatureXS, FeatureWFxT, FeatureHCX]>;
+
+def HasV8_0rOps : SubtargetFeature<
+ "v8r", "HasV8_0rOps", "true", "Support ARM v8r instructions",
+ [//v8.1
+ FeatureCRC, FeaturePAN, FeatureRDM, FeatureLSE, FeatureCONTEXTIDREL2,
+ //v8.2
+ FeaturePerfMon, FeatureRAS, FeaturePsUAO, FeatureSM4,
+ FeatureSHA3, FeatureCCPP, FeatureFullFP16, FeaturePAN_RWV,
+ //v8.3
+ FeatureComplxNum, FeatureCCIDX, FeatureJS,
+ FeaturePAuth, FeatureRCPC,
+ //v8.4
+ FeatureDotProd, FeatureFP16FML, FeatureTRACEV8_4,
+ FeatureTLB_RMI, FeatureFlagM, FeatureDIT, FeatureSEL2, FeatureRCPC_IMMO,
+ //v8.5
+ FeatureSSBS, FeaturePredRes, FeatureSB, FeatureSpecRestrict]>;
+
//===----------------------------------------------------------------------===//
// Register File Description
//===----------------------------------------------------------------------===//
@@ -543,11 +543,11 @@ def SVEUnsupported : AArch64Unsupported {
}
def PAUnsupported : AArch64Unsupported {
- let F = [HasPAuth];
+ let F = [HasPAuth];
}
include "AArch64SchedA53.td"
-include "AArch64SchedA55.td"
+include "AArch64SchedA55.td"
include "AArch64SchedA57.td"
include "AArch64SchedCyclone.td"
include "AArch64SchedFalkor.td"
@@ -557,9 +557,9 @@ include "AArch64SchedExynosM4.td"
include "AArch64SchedExynosM5.td"
include "AArch64SchedThunderX.td"
include "AArch64SchedThunderX2T99.td"
-include "AArch64SchedA64FX.td"
+include "AArch64SchedA64FX.td"
include "AArch64SchedThunderX3T110.td"
-include "AArch64SchedTSV110.td"
+include "AArch64SchedTSV110.td"
def ProcA35 : SubtargetFeature<"a35", "ARMProcFamily", "CortexA35",
"Cortex-A35 ARM processors", [
@@ -619,9 +619,9 @@ def ProcA65 : SubtargetFeature<"a65", "ARMProcFamily", "CortexA65",
FeatureDotProd,
FeatureFPARMv8,
FeatureFullFP16,
- FeatureFuseAddress,
- FeatureFuseAES,
- FeatureFuseLiterals,
+ FeatureFuseAddress,
+ FeatureFuseAES,
+ FeatureFuseLiterals,
FeatureNEON,
FeatureRAS,
FeatureRCPC,
@@ -634,7 +634,7 @@ def ProcA72 : SubtargetFeature<"a72", "ARMProcFamily", "CortexA72",
FeatureCrypto,
FeatureFPARMv8,
FeatureFuseAES,
- FeatureFuseLiterals,
+ FeatureFuseLiterals,
FeatureNEON,
FeaturePerfMon
]>;
@@ -666,7 +666,7 @@ def ProcA76 : SubtargetFeature<"a76", "ARMProcFamily", "CortexA76",
"Cortex-A76 ARM processors", [
HasV8_2aOps,
FeatureFPARMv8,
- FeatureFuseAES,
+ FeatureFuseAES,
FeatureNEON,
FeatureRCPC,
FeatureCrypto,
@@ -678,9 +678,9 @@ def ProcA76 : SubtargetFeature<"a76", "ARMProcFamily", "CortexA76",
def ProcA77 : SubtargetFeature<"a77", "ARMProcFamily", "CortexA77",
"Cortex-A77 ARM processors", [
HasV8_2aOps,
- FeatureCmpBccFusion,
+ FeatureCmpBccFusion,
FeatureFPARMv8,
- FeatureFuseAES,
+ FeatureFuseAES,
FeatureNEON, FeatureRCPC,
FeatureCrypto,
FeatureFullFP16,
@@ -691,7 +691,7 @@ def ProcA78 : SubtargetFeature<"cortex-a78", "ARMProcFamily",
"CortexA78",
"Cortex-A78 ARM processors", [
HasV8_2aOps,
- FeatureCmpBccFusion,
+ FeatureCmpBccFusion,
FeatureCrypto,
FeatureFPARMv8,
FeatureFuseAES,
@@ -704,39 +704,39 @@ def ProcA78 : SubtargetFeature<"cortex-a78", "ARMProcFamily",
FeatureSSBS,
FeatureDotProd]>;
-def ProcA78C : SubtargetFeature<"cortex-a78c", "ARMProcFamily",
- "CortexA78C",
- "Cortex-A78C ARM processors", [
- HasV8_2aOps,
- FeatureCmpBccFusion,
- FeatureCrypto,
- FeatureDotProd,
- FeatureFlagM,
- FeatureFP16FML,
- FeatureFPARMv8,
- FeatureFullFP16,
- FeatureFuseAES,
- FeatureNEON,
- FeaturePAuth,
- FeaturePerfMon,
- FeaturePostRAScheduler,
- FeatureRCPC,
- FeatureSPE,
- FeatureSSBS]>;
-
-def ProcR82 : SubtargetFeature<"cortex-r82", "ARMProcFamily",
- "CortexR82",
- "Cortex-R82 ARM Processors", [
- FeaturePostRAScheduler,
- // TODO: crypto and FuseAES
- // All other features are implied by v8_0r ops:
- HasV8_0rOps,
- ]>;
-
+def ProcA78C : SubtargetFeature<"cortex-a78c", "ARMProcFamily",
+ "CortexA78C",
+ "Cortex-A78C ARM processors", [
+ HasV8_2aOps,
+ FeatureCmpBccFusion,
+ FeatureCrypto,
+ FeatureDotProd,
+ FeatureFlagM,
+ FeatureFP16FML,
+ FeatureFPARMv8,
+ FeatureFullFP16,
+ FeatureFuseAES,
+ FeatureNEON,
+ FeaturePAuth,
+ FeaturePerfMon,
+ FeaturePostRAScheduler,
+ FeatureRCPC,
+ FeatureSPE,
+ FeatureSSBS]>;
+
+def ProcR82 : SubtargetFeature<"cortex-r82", "ARMProcFamily",
+ "CortexR82",
+ "Cortex-R82 ARM Processors", [
+ FeaturePostRAScheduler,
+ // TODO: crypto and FuseAES
+ // All other features are implied by v8_0r ops:
+ HasV8_0rOps,
+ ]>;
+
def ProcX1 : SubtargetFeature<"cortex-x1", "ARMProcFamily", "CortexX1",
"Cortex-X1 ARM processors", [
HasV8_2aOps,
- FeatureCmpBccFusion,
+ FeatureCmpBccFusion,
FeatureCrypto,
FeatureFPARMv8,
FeatureFuseAES,
@@ -758,10 +758,10 @@ def ProcA64FX : SubtargetFeature<"a64fx", "ARMProcFamily", "A64FX",
FeatureFullFP16,
FeatureSVE,
FeaturePostRAScheduler,
- FeatureComplxNum,
- FeatureAggressiveFMA,
- FeatureArithmeticBccFusion,
- FeaturePredictableSelectIsExpensive
+ FeatureComplxNum,
+ FeatureAggressiveFMA,
+ FeatureArithmeticBccFusion,
+ FeaturePredictableSelectIsExpensive
]>;
def ProcCarmel : SubtargetFeature<"carmel", "ARMProcFamily", "Carmel",
@@ -868,38 +868,38 @@ def ProcAppleA13 : SubtargetFeature<"apple-a13", "ARMProcFamily", "AppleA13",
HasV8_4aOps
]>;
-def ProcAppleA14 : SubtargetFeature<"apple-a14", "ARMProcFamily", "AppleA14",
- "Apple A14", [
- FeatureAggressiveFMA,
- FeatureAlternateSExtLoadCVTF32Pattern,
- FeatureAltFPCmp,
- FeatureArithmeticBccFusion,
- FeatureArithmeticCbzFusion,
- FeatureCrypto,
- FeatureDisableLatencySchedHeuristic,
- FeatureFPARMv8,
- FeatureFRInt3264,
- FeatureFuseAddress,
- FeatureFuseAES,
- FeatureFuseArithmeticLogic,
- FeatureFuseCCSelect,
- FeatureFuseCryptoEOR,
- FeatureFuseLiterals,
- FeatureNEON,
- FeaturePerfMon,
- FeatureSpecRestrict,
- FeatureSSBS,
- FeatureSB,
- FeaturePredRes,
- FeatureCacheDeepPersist,
- FeatureZCRegMove,
- FeatureZCZeroing,
- FeatureFullFP16,
- FeatureFP16FML,
- FeatureSHA3,
- HasV8_4aOps
- ]>;
-
+def ProcAppleA14 : SubtargetFeature<"apple-a14", "ARMProcFamily", "AppleA14",
+ "Apple A14", [
+ FeatureAggressiveFMA,
+ FeatureAlternateSExtLoadCVTF32Pattern,
+ FeatureAltFPCmp,
+ FeatureArithmeticBccFusion,
+ FeatureArithmeticCbzFusion,
+ FeatureCrypto,
+ FeatureDisableLatencySchedHeuristic,
+ FeatureFPARMv8,
+ FeatureFRInt3264,
+ FeatureFuseAddress,
+ FeatureFuseAES,
+ FeatureFuseArithmeticLogic,
+ FeatureFuseCCSelect,
+ FeatureFuseCryptoEOR,
+ FeatureFuseLiterals,
+ FeatureNEON,
+ FeaturePerfMon,
+ FeatureSpecRestrict,
+ FeatureSSBS,
+ FeatureSB,
+ FeaturePredRes,
+ FeatureCacheDeepPersist,
+ FeatureZCRegMove,
+ FeatureZCZeroing,
+ FeatureFullFP16,
+ FeatureFP16FML,
+ FeatureSHA3,
+ HasV8_4aOps
+ ]>;
+
def ProcExynosM3 : SubtargetFeature<"exynosm3", "ARMProcFamily", "ExynosM3",
"Samsung Exynos-M3 processors",
[FeatureCRC,
@@ -993,38 +993,38 @@ def ProcNeoverseN1 : SubtargetFeature<"neoversen1", "ARMProcFamily",
FeatureSSBS,
]>;
-def ProcNeoverseN2 : SubtargetFeature<"neoversen2", "ARMProcFamily",
- "NeoverseN2",
- "Neoverse N2 ARM processors", [
- HasV8_5aOps,
- FeatureBF16,
- FeatureETE,
- FeatureMatMulInt8,
- FeatureMTE,
- FeatureSVE2,
- FeatureSVE2BitPerm,
- FeatureTRBE]>;
-
-def ProcNeoverseV1 : SubtargetFeature<"neoversev1", "ARMProcFamily",
- "NeoverseV1",
- "Neoverse V1 ARM processors", [
- HasV8_4aOps,
- FeatureBF16,
- FeatureCacheDeepPersist,
- FeatureCrypto,
- FeatureFPARMv8,
- FeatureFP16FML,
- FeatureFullFP16,
- FeatureFuseAES,
- FeatureMatMulInt8,
- FeatureNEON,
- FeaturePerfMon,
- FeaturePostRAScheduler,
- FeatureRandGen,
- FeatureSPE,
- FeatureSSBS,
- FeatureSVE]>;
-
+def ProcNeoverseN2 : SubtargetFeature<"neoversen2", "ARMProcFamily",
+ "NeoverseN2",
+ "Neoverse N2 ARM processors", [
+ HasV8_5aOps,
+ FeatureBF16,
+ FeatureETE,
+ FeatureMatMulInt8,
+ FeatureMTE,
+ FeatureSVE2,
+ FeatureSVE2BitPerm,
+ FeatureTRBE]>;
+
+def ProcNeoverseV1 : SubtargetFeature<"neoversev1", "ARMProcFamily",
+ "NeoverseV1",
+ "Neoverse V1 ARM processors", [
+ HasV8_4aOps,
+ FeatureBF16,
+ FeatureCacheDeepPersist,
+ FeatureCrypto,
+ FeatureFPARMv8,
+ FeatureFP16FML,
+ FeatureFullFP16,
+ FeatureFuseAES,
+ FeatureMatMulInt8,
+ FeatureNEON,
+ FeaturePerfMon,
+ FeaturePostRAScheduler,
+ FeatureRandGen,
+ FeatureSPE,
+ FeatureSSBS,
+ FeatureSVE]>;
+
def ProcSaphira : SubtargetFeature<"saphira", "ARMProcFamily", "Saphira",
"Qualcomm Saphira processors", [
FeatureCrypto,
@@ -1065,7 +1065,7 @@ def ProcThunderX3T110 : SubtargetFeature<"thunderx3t110", "ARMProcFamily",
FeaturePostRAScheduler,
FeaturePredictableSelectIsExpensive,
FeatureLSE,
- FeaturePAuth,
+ FeaturePAuth,
FeatureUseAA,
FeatureBalanceFPOps,
FeaturePerfMon,
@@ -1147,7 +1147,7 @@ def : ProcessorModel<"generic", NoSchedModel, [
def : ProcessorModel<"cortex-a35", CortexA53Model, [ProcA35]>;
def : ProcessorModel<"cortex-a34", CortexA53Model, [ProcA35]>;
def : ProcessorModel<"cortex-a53", CortexA53Model, [ProcA53]>;
-def : ProcessorModel<"cortex-a55", CortexA55Model, [ProcA55]>;
+def : ProcessorModel<"cortex-a55", CortexA55Model, [ProcA55]>;
def : ProcessorModel<"cortex-a57", CortexA57Model, [ProcA57]>;
def : ProcessorModel<"cortex-a65", CortexA53Model, [ProcA65]>;
def : ProcessorModel<"cortex-a65ae", CortexA53Model, [ProcA65]>;
@@ -1158,13 +1158,13 @@ def : ProcessorModel<"cortex-a76", CortexA57Model, [ProcA76]>;
def : ProcessorModel<"cortex-a76ae", CortexA57Model, [ProcA76]>;
def : ProcessorModel<"cortex-a77", CortexA57Model, [ProcA77]>;
def : ProcessorModel<"cortex-a78", CortexA57Model, [ProcA78]>;
-def : ProcessorModel<"cortex-a78c", CortexA57Model, [ProcA78C]>;
-def : ProcessorModel<"cortex-r82", CortexA55Model, [ProcR82]>;
+def : ProcessorModel<"cortex-a78c", CortexA57Model, [ProcA78C]>;
+def : ProcessorModel<"cortex-r82", CortexA55Model, [ProcR82]>;
def : ProcessorModel<"cortex-x1", CortexA57Model, [ProcX1]>;
def : ProcessorModel<"neoverse-e1", CortexA53Model, [ProcNeoverseE1]>;
def : ProcessorModel<"neoverse-n1", CortexA57Model, [ProcNeoverseN1]>;
-def : ProcessorModel<"neoverse-n2", CortexA57Model, [ProcNeoverseN2]>;
-def : ProcessorModel<"neoverse-v1", CortexA57Model, [ProcNeoverseV1]>;
+def : ProcessorModel<"neoverse-n2", CortexA57Model, [ProcNeoverseN2]>;
+def : ProcessorModel<"neoverse-v1", CortexA57Model, [ProcNeoverseV1]>;
def : ProcessorModel<"exynos-m3", ExynosM3Model, [ProcExynosM3]>;
def : ProcessorModel<"exynos-m4", ExynosM4Model, [ProcExynosM4]>;
def : ProcessorModel<"exynos-m5", ExynosM5Model, [ProcExynosM4]>;
@@ -1180,7 +1180,7 @@ def : ProcessorModel<"thunderxt83", ThunderXT8XModel, [ProcThunderXT83]>;
def : ProcessorModel<"thunderx2t99", ThunderX2T99Model, [ProcThunderX2T99]>;
// Marvell ThunderX3T110 Processors.
def : ProcessorModel<"thunderx3t110", ThunderX3T110Model, [ProcThunderX3T110]>;
-def : ProcessorModel<"tsv110", TSV110Model, [ProcTSV110]>;
+def : ProcessorModel<"tsv110", TSV110Model, [ProcTSV110]>;
// Support cyclone as an alias for apple-a7 so we can still LTO old bitcode.
def : ProcessorModel<"cyclone", CycloneModel, [ProcAppleA7]>;
@@ -1193,7 +1193,7 @@ def : ProcessorModel<"apple-a10", CycloneModel, [ProcAppleA10]>;
def : ProcessorModel<"apple-a11", CycloneModel, [ProcAppleA11]>;
def : ProcessorModel<"apple-a12", CycloneModel, [ProcAppleA12]>;
def : ProcessorModel<"apple-a13", CycloneModel, [ProcAppleA13]>;
-def : ProcessorModel<"apple-a14", CycloneModel, [ProcAppleA14]>;
+def : ProcessorModel<"apple-a14", CycloneModel, [ProcAppleA14]>;
// watch CPUs.
def : ProcessorModel<"apple-s4", CycloneModel, [ProcAppleA12]>;
@@ -1203,7 +1203,7 @@ def : ProcessorModel<"apple-s5", CycloneModel, [ProcAppleA12]>;
def : ProcessorModel<"apple-latest", CycloneModel, [ProcAppleA13]>;
// Fujitsu A64FX
-def : ProcessorModel<"a64fx", A64FXModel, [ProcA64FX]>;
+def : ProcessorModel<"a64fx", A64FXModel, [ProcA64FX]>;
// Nvidia Carmel
def : ProcessorModel<"carmel", NoSchedModel, [ProcCarmel]>;
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64AdvSIMDScalarPass.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64AdvSIMDScalarPass.cpp
index 74fd2411f4..c996d2df8c 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64AdvSIMDScalarPass.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64AdvSIMDScalarPass.cpp
@@ -123,7 +123,7 @@ static bool isFPR64(unsigned Reg, unsigned SubReg,
}
// getSrcFromCopy - Get the original source register for a GPR64 <--> FPR64
-// copy instruction. Return nullptr if the instruction is not a copy.
+// copy instruction. Return nullptr if the instruction is not a copy.
static MachineOperand *getSrcFromCopy(MachineInstr *MI,
const MachineRegisterInfo *MRI,
unsigned &SubReg) {
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64AsmPrinter.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64AsmPrinter.cpp
index 419af6785c..a0c5498ee6 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -32,7 +32,7 @@
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/FaultMaps.h"
+#include "llvm/CodeGen/FaultMaps.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
@@ -55,7 +55,7 @@
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
+#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
@@ -71,13 +71,13 @@ namespace {
class AArch64AsmPrinter : public AsmPrinter {
AArch64MCInstLower MCInstLowering;
StackMaps SM;
- FaultMaps FM;
+ FaultMaps FM;
const AArch64Subtarget *STI;
public:
AArch64AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
: AsmPrinter(TM, std::move(Streamer)), MCInstLowering(OutContext, *this),
- SM(*this), FM(*this) {}
+ SM(*this), FM(*this) {}
StringRef getPassName() const override { return "AArch64 Assembly Printer"; }
@@ -92,15 +92,15 @@ public:
void emitFunctionEntryLabel() override;
- void LowerJumpTableDest(MCStreamer &OutStreamer, const MachineInstr &MI);
+ void LowerJumpTableDest(MCStreamer &OutStreamer, const MachineInstr &MI);
void LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
const MachineInstr &MI);
void LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
const MachineInstr &MI);
- void LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
- const MachineInstr &MI);
- void LowerFAULTING_OP(const MachineInstr &MI);
+ void LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
+ const MachineInstr &MI);
+ void LowerFAULTING_OP(const MachineInstr &MI);
void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI);
void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI);
@@ -195,24 +195,24 @@ void AArch64AsmPrinter::emitStartOfAsmFile(Module &M) {
return;
// Assemble feature flags that may require creation of a note section.
- unsigned Flags = 0;
- if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
- M.getModuleFlag("branch-target-enforcement")))
- if (BTE->getZExtValue())
- Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
+ unsigned Flags = 0;
+ if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
+ M.getModuleFlag("branch-target-enforcement")))
+ if (BTE->getZExtValue())
+ Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
- if (const auto *Sign = mdconst::extract_or_null<ConstantInt>(
- M.getModuleFlag("sign-return-address")))
- if (Sign->getZExtValue())
- Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
+ if (const auto *Sign = mdconst::extract_or_null<ConstantInt>(
+ M.getModuleFlag("sign-return-address")))
+ if (Sign->getZExtValue())
+ Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
if (Flags == 0)
return;
// Emit a .note.gnu.property section with the flags.
- if (auto *TS = static_cast<AArch64TargetStreamer *>(
- OutStreamer->getTargetStreamer()))
- TS->emitNoteSection(Flags);
+ if (auto *TS = static_cast<AArch64TargetStreamer *>(
+ OutStreamer->getTargetStreamer()))
+ TS->emitNoteSection(Flags);
}
void AArch64AsmPrinter::emitFunctionHeaderComment() {
@@ -303,7 +303,7 @@ void AArch64AsmPrinter::LowerHWASAN_CHECK_MEMACCESS(const MachineInstr &MI) {
std::string SymName = "__hwasan_check_x" + utostr(Reg - AArch64::X0) + "_" +
utostr(AccessInfo);
if (IsShort)
- SymName += "_short_v2";
+ SymName += "_short_v2";
Sym = OutContext.getOrCreateSymbol(SymName);
}
@@ -320,7 +320,7 @@ void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) {
assert(TT.isOSBinFormatELF());
std::unique_ptr<MCSubtargetInfo> STI(
TM.getTarget().createMCSubtargetInfo(TT.str(), "", ""));
- assert(STI && "Unable to create subtarget info");
+ assert(STI && "Unable to create subtarget info");
MCSymbol *HwasanTagMismatchV1Sym =
OutContext.getOrCreateSymbol("__hwasan_tag_mismatch");
@@ -340,15 +340,15 @@ void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) {
IsShort ? HwasanTagMismatchV2Ref : HwasanTagMismatchV1Ref;
MCSymbol *Sym = P.second;
- bool HasMatchAllTag =
- (AccessInfo >> HWASanAccessInfo::HasMatchAllShift) & 1;
- uint8_t MatchAllTag =
- (AccessInfo >> HWASanAccessInfo::MatchAllShift) & 0xff;
- unsigned Size =
- 1 << ((AccessInfo >> HWASanAccessInfo::AccessSizeShift) & 0xf);
- bool CompileKernel =
- (AccessInfo >> HWASanAccessInfo::CompileKernelShift) & 1;
-
+ bool HasMatchAllTag =
+ (AccessInfo >> HWASanAccessInfo::HasMatchAllShift) & 1;
+ uint8_t MatchAllTag =
+ (AccessInfo >> HWASanAccessInfo::MatchAllShift) & 0xff;
+ unsigned Size =
+ 1 << ((AccessInfo >> HWASanAccessInfo::AccessSizeShift) & 0xf);
+ bool CompileKernel =
+ (AccessInfo >> HWASanAccessInfo::CompileKernelShift) & 1;
+
OutStreamer->SwitchSection(OutContext.getELFSection(
".text.hot", ELF::SHT_PROGBITS,
ELF::SHF_EXECINSTR | ELF::SHF_ALLOC | ELF::SHF_GROUP, 0,
@@ -359,21 +359,21 @@ void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) {
OutStreamer->emitSymbolAttribute(Sym, MCSA_Hidden);
OutStreamer->emitLabel(Sym);
- OutStreamer->emitInstruction(MCInstBuilder(AArch64::SBFMXri)
+ OutStreamer->emitInstruction(MCInstBuilder(AArch64::SBFMXri)
.addReg(AArch64::X16)
.addReg(Reg)
.addImm(4)
.addImm(55),
*STI);
OutStreamer->emitInstruction(
- MCInstBuilder(AArch64::LDRBBroX)
- .addReg(AArch64::W16)
- .addReg(IsShort ? AArch64::X20 : AArch64::X9)
- .addReg(AArch64::X16)
- .addImm(0)
- .addImm(0),
- *STI);
- OutStreamer->emitInstruction(
+ MCInstBuilder(AArch64::LDRBBroX)
+ .addReg(AArch64::W16)
+ .addReg(IsShort ? AArch64::X20 : AArch64::X9)
+ .addReg(AArch64::X16)
+ .addImm(0)
+ .addImm(0),
+ *STI);
+ OutStreamer->emitInstruction(
MCInstBuilder(AArch64::SUBSXrs)
.addReg(AArch64::XZR)
.addReg(AArch64::X16)
@@ -393,26 +393,26 @@ void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) {
MCInstBuilder(AArch64::RET).addReg(AArch64::LR), *STI);
OutStreamer->emitLabel(HandleMismatchOrPartialSym);
- if (HasMatchAllTag) {
- OutStreamer->emitInstruction(MCInstBuilder(AArch64::UBFMXri)
- .addReg(AArch64::X16)
- .addReg(Reg)
- .addImm(56)
- .addImm(63),
- *STI);
- OutStreamer->emitInstruction(MCInstBuilder(AArch64::SUBSXri)
- .addReg(AArch64::XZR)
- .addReg(AArch64::X16)
- .addImm(MatchAllTag)
- .addImm(0),
- *STI);
- OutStreamer->emitInstruction(
- MCInstBuilder(AArch64::Bcc)
- .addImm(AArch64CC::EQ)
- .addExpr(MCSymbolRefExpr::create(ReturnSym, OutContext)),
- *STI);
- }
-
+ if (HasMatchAllTag) {
+ OutStreamer->emitInstruction(MCInstBuilder(AArch64::UBFMXri)
+ .addReg(AArch64::X16)
+ .addReg(Reg)
+ .addImm(56)
+ .addImm(63),
+ *STI);
+ OutStreamer->emitInstruction(MCInstBuilder(AArch64::SUBSXri)
+ .addReg(AArch64::XZR)
+ .addReg(AArch64::X16)
+ .addImm(MatchAllTag)
+ .addImm(0),
+ *STI);
+ OutStreamer->emitInstruction(
+ MCInstBuilder(AArch64::Bcc)
+ .addImm(AArch64CC::EQ)
+ .addExpr(MCSymbolRefExpr::create(ReturnSym, OutContext)),
+ *STI);
+ }
+
if (IsShort) {
OutStreamer->emitInstruction(MCInstBuilder(AArch64::SUBSWri)
.addReg(AArch64::WZR)
@@ -501,40 +501,40 @@ void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) {
.addImm(0),
*STI);
OutStreamer->emitInstruction(
- MCInstBuilder(AArch64::MOVZXi)
- .addReg(AArch64::X1)
- .addImm(AccessInfo & HWASanAccessInfo::RuntimeMask)
- .addImm(0),
+ MCInstBuilder(AArch64::MOVZXi)
+ .addReg(AArch64::X1)
+ .addImm(AccessInfo & HWASanAccessInfo::RuntimeMask)
+ .addImm(0),
*STI);
-
- if (CompileKernel) {
- // The Linux kernel's dynamic loader doesn't support GOT relative
- // relocations, but it doesn't support late binding either, so just call
- // the function directly.
- OutStreamer->emitInstruction(
- MCInstBuilder(AArch64::B).addExpr(HwasanTagMismatchRef), *STI);
- } else {
- // Intentionally load the GOT entry and branch to it, rather than possibly
- // late binding the function, which may clobber the registers before we
- // have a chance to save them.
- OutStreamer->emitInstruction(
- MCInstBuilder(AArch64::ADRP)
- .addReg(AArch64::X16)
- .addExpr(AArch64MCExpr::create(
- HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_PAGE,
- OutContext)),
- *STI);
- OutStreamer->emitInstruction(
- MCInstBuilder(AArch64::LDRXui)
- .addReg(AArch64::X16)
- .addReg(AArch64::X16)
- .addExpr(AArch64MCExpr::create(
- HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_LO12,
- OutContext)),
- *STI);
- OutStreamer->emitInstruction(
- MCInstBuilder(AArch64::BR).addReg(AArch64::X16), *STI);
- }
+
+ if (CompileKernel) {
+ // The Linux kernel's dynamic loader doesn't support GOT relative
+ // relocations, but it doesn't support late binding either, so just call
+ // the function directly.
+ OutStreamer->emitInstruction(
+ MCInstBuilder(AArch64::B).addExpr(HwasanTagMismatchRef), *STI);
+ } else {
+ // Intentionally load the GOT entry and branch to it, rather than possibly
+ // late binding the function, which may clobber the registers before we
+ // have a chance to save them.
+ OutStreamer->emitInstruction(
+ MCInstBuilder(AArch64::ADRP)
+ .addReg(AArch64::X16)
+ .addExpr(AArch64MCExpr::create(
+ HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_PAGE,
+ OutContext)),
+ *STI);
+ OutStreamer->emitInstruction(
+ MCInstBuilder(AArch64::LDRXui)
+ .addReg(AArch64::X16)
+ .addReg(AArch64::X16)
+ .addExpr(AArch64MCExpr::create(
+ HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_LO12,
+ OutContext)),
+ *STI);
+ OutStreamer->emitInstruction(
+ MCInstBuilder(AArch64::BR).addReg(AArch64::X16), *STI);
+ }
}
}
@@ -550,11 +550,11 @@ void AArch64AsmPrinter::emitEndOfAsmFile(Module &M) {
// generates code that does this, it is always safe to set.
OutStreamer->emitAssemblerFlag(MCAF_SubsectionsViaSymbols);
}
-
- // Emit stack and fault map information.
+
+ // Emit stack and fault map information.
emitStackMaps(SM);
- FM.serializeToFaultMapSection();
-
+ FM.serializeToFaultMapSection();
+
}
void AArch64AsmPrinter::EmitLOHs() {
@@ -647,8 +647,8 @@ bool AArch64AsmPrinter::printAsmRegInClass(const MachineOperand &MO,
const TargetRegisterInfo *RI = STI->getRegisterInfo();
Register Reg = MO.getReg();
unsigned RegToPrint = RC->getRegister(RI->getEncodingValue(Reg));
- if (!RI->regsOverlap(RegToPrint, Reg))
- return true;
+ if (!RI->regsOverlap(RegToPrint, Reg))
+ return true;
O << AArch64InstPrinter::getRegisterName(RegToPrint, AltName);
return false;
}
@@ -809,24 +809,24 @@ void AArch64AsmPrinter::emitJumpTableInfo() {
emitAlignment(Align(Size));
OutStreamer->emitLabel(GetJTISymbol(JTI));
- const MCSymbol *BaseSym = AArch64FI->getJumpTableEntryPCRelSymbol(JTI);
- const MCExpr *Base = MCSymbolRefExpr::create(BaseSym, OutContext);
-
- for (auto *JTBB : JTBBs) {
- const MCExpr *Value =
- MCSymbolRefExpr::create(JTBB->getSymbol(), OutContext);
-
- // Each entry is:
- // .byte/.hword (LBB - Lbase)>>2
- // or plain:
- // .word LBB - Lbase
- Value = MCBinaryExpr::createSub(Value, Base, OutContext);
- if (Size != 4)
- Value = MCBinaryExpr::createLShr(
- Value, MCConstantExpr::create(2, OutContext), OutContext);
-
- OutStreamer->emitValue(Value, Size);
- }
+ const MCSymbol *BaseSym = AArch64FI->getJumpTableEntryPCRelSymbol(JTI);
+ const MCExpr *Base = MCSymbolRefExpr::create(BaseSym, OutContext);
+
+ for (auto *JTBB : JTBBs) {
+ const MCExpr *Value =
+ MCSymbolRefExpr::create(JTBB->getSymbol(), OutContext);
+
+ // Each entry is:
+ // .byte/.hword (LBB - Lbase)>>2
+ // or plain:
+ // .word LBB - Lbase
+ Value = MCBinaryExpr::createSub(Value, Base, OutContext);
+ if (Size != 4)
+ Value = MCBinaryExpr::createLShr(
+ Value, MCConstantExpr::create(2, OutContext), OutContext);
+
+ OutStreamer->emitValue(Value, Size);
+ }
}
}
@@ -851,9 +851,9 @@ void AArch64AsmPrinter::emitFunctionEntryLabel() {
///
/// adr xDest, .LBB0_0
/// ldrb wScratch, [xTable, xEntry] (with "lsl #1" for ldrh).
-/// add xDest, xDest, xScratch (with "lsl #2" for smaller entries)
-void AArch64AsmPrinter::LowerJumpTableDest(llvm::MCStreamer &OutStreamer,
- const llvm::MachineInstr &MI) {
+/// add xDest, xDest, xScratch (with "lsl #2" for smaller entries)
+void AArch64AsmPrinter::LowerJumpTableDest(llvm::MCStreamer &OutStreamer,
+ const llvm::MachineInstr &MI) {
Register DestReg = MI.getOperand(0).getReg();
Register ScratchReg = MI.getOperand(1).getReg();
Register ScratchRegW =
@@ -861,50 +861,50 @@ void AArch64AsmPrinter::LowerJumpTableDest(llvm::MCStreamer &OutStreamer,
Register TableReg = MI.getOperand(2).getReg();
Register EntryReg = MI.getOperand(3).getReg();
int JTIdx = MI.getOperand(4).getIndex();
- int Size = AArch64FI->getJumpTableEntrySize(JTIdx);
+ int Size = AArch64FI->getJumpTableEntrySize(JTIdx);
// This has to be first because the compression pass based its reachability
// calculations on the start of the JumpTableDest instruction.
auto Label =
MF->getInfo<AArch64FunctionInfo>()->getJumpTableEntryPCRelSymbol(JTIdx);
-
- // If we don't already have a symbol to use as the base, use the ADR
- // instruction itself.
- if (!Label) {
- Label = MF->getContext().createTempSymbol();
- AArch64FI->setJumpTableEntryInfo(JTIdx, Size, Label);
- OutStreamer.emitLabel(Label);
- }
-
- auto LabelExpr = MCSymbolRefExpr::create(Label, MF->getContext());
+
+ // If we don't already have a symbol to use as the base, use the ADR
+ // instruction itself.
+ if (!Label) {
+ Label = MF->getContext().createTempSymbol();
+ AArch64FI->setJumpTableEntryInfo(JTIdx, Size, Label);
+ OutStreamer.emitLabel(Label);
+ }
+
+ auto LabelExpr = MCSymbolRefExpr::create(Label, MF->getContext());
EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::ADR)
.addReg(DestReg)
- .addExpr(LabelExpr));
+ .addExpr(LabelExpr));
// Load the number of instruction-steps to offset from the label.
- unsigned LdrOpcode;
- switch (Size) {
- case 1: LdrOpcode = AArch64::LDRBBroX; break;
- case 2: LdrOpcode = AArch64::LDRHHroX; break;
- case 4: LdrOpcode = AArch64::LDRSWroX; break;
- default:
- llvm_unreachable("Unknown jump table size");
- }
-
+ unsigned LdrOpcode;
+ switch (Size) {
+ case 1: LdrOpcode = AArch64::LDRBBroX; break;
+ case 2: LdrOpcode = AArch64::LDRHHroX; break;
+ case 4: LdrOpcode = AArch64::LDRSWroX; break;
+ default:
+ llvm_unreachable("Unknown jump table size");
+ }
+
EmitToStreamer(OutStreamer, MCInstBuilder(LdrOpcode)
- .addReg(Size == 4 ? ScratchReg : ScratchRegW)
+ .addReg(Size == 4 ? ScratchReg : ScratchRegW)
.addReg(TableReg)
.addReg(EntryReg)
.addImm(0)
- .addImm(Size == 1 ? 0 : 1));
+ .addImm(Size == 1 ? 0 : 1));
- // Add to the already materialized base label address, multiplying by 4 if
- // compressed.
+ // Add to the already materialized base label address, multiplying by 4 if
+ // compressed.
EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::ADDXrs)
.addReg(DestReg)
.addReg(DestReg)
.addReg(ScratchReg)
- .addImm(Size == 4 ? 0 : 2));
+ .addImm(Size == 4 ? 0 : 2));
}
void AArch64AsmPrinter::LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
@@ -982,83 +982,83 @@ void AArch64AsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0));
}
-void AArch64AsmPrinter::LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
- const MachineInstr &MI) {
- StatepointOpers SOpers(&MI);
- if (unsigned PatchBytes = SOpers.getNumPatchBytes()) {
- assert(PatchBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
- for (unsigned i = 0; i < PatchBytes; i += 4)
- EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0));
- } else {
- // Lower call target and choose correct opcode
- const MachineOperand &CallTarget = SOpers.getCallTarget();
- MCOperand CallTargetMCOp;
- unsigned CallOpcode;
- switch (CallTarget.getType()) {
- case MachineOperand::MO_GlobalAddress:
- case MachineOperand::MO_ExternalSymbol:
- MCInstLowering.lowerOperand(CallTarget, CallTargetMCOp);
- CallOpcode = AArch64::BL;
- break;
- case MachineOperand::MO_Immediate:
- CallTargetMCOp = MCOperand::createImm(CallTarget.getImm());
- CallOpcode = AArch64::BL;
- break;
- case MachineOperand::MO_Register:
- CallTargetMCOp = MCOperand::createReg(CallTarget.getReg());
- CallOpcode = AArch64::BLR;
- break;
- default:
- llvm_unreachable("Unsupported operand type in statepoint call target");
- break;
- }
-
- EmitToStreamer(OutStreamer,
- MCInstBuilder(CallOpcode).addOperand(CallTargetMCOp));
- }
-
- auto &Ctx = OutStreamer.getContext();
- MCSymbol *MILabel = Ctx.createTempSymbol();
- OutStreamer.emitLabel(MILabel);
- SM.recordStatepoint(*MILabel, MI);
-}
-
-void AArch64AsmPrinter::LowerFAULTING_OP(const MachineInstr &FaultingMI) {
- // FAULTING_LOAD_OP <def>, <faltinf type>, <MBB handler>,
- // <opcode>, <operands>
-
- Register DefRegister = FaultingMI.getOperand(0).getReg();
- FaultMaps::FaultKind FK =
- static_cast<FaultMaps::FaultKind>(FaultingMI.getOperand(1).getImm());
- MCSymbol *HandlerLabel = FaultingMI.getOperand(2).getMBB()->getSymbol();
- unsigned Opcode = FaultingMI.getOperand(3).getImm();
- unsigned OperandsBeginIdx = 4;
-
- auto &Ctx = OutStreamer->getContext();
- MCSymbol *FaultingLabel = Ctx.createTempSymbol();
- OutStreamer->emitLabel(FaultingLabel);
-
- assert(FK < FaultMaps::FaultKindMax && "Invalid Faulting Kind!");
- FM.recordFaultingOp(FK, FaultingLabel, HandlerLabel);
-
- MCInst MI;
- MI.setOpcode(Opcode);
-
- if (DefRegister != (Register)0)
- MI.addOperand(MCOperand::createReg(DefRegister));
-
- for (auto I = FaultingMI.operands_begin() + OperandsBeginIdx,
- E = FaultingMI.operands_end();
- I != E; ++I) {
- MCOperand Dest;
- lowerOperand(*I, Dest);
- MI.addOperand(Dest);
- }
-
- OutStreamer->AddComment("on-fault: " + HandlerLabel->getName());
- OutStreamer->emitInstruction(MI, getSubtargetInfo());
-}
-
+void AArch64AsmPrinter::LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
+ const MachineInstr &MI) {
+ StatepointOpers SOpers(&MI);
+ if (unsigned PatchBytes = SOpers.getNumPatchBytes()) {
+ assert(PatchBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
+ for (unsigned i = 0; i < PatchBytes; i += 4)
+ EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0));
+ } else {
+ // Lower call target and choose correct opcode
+ const MachineOperand &CallTarget = SOpers.getCallTarget();
+ MCOperand CallTargetMCOp;
+ unsigned CallOpcode;
+ switch (CallTarget.getType()) {
+ case MachineOperand::MO_GlobalAddress:
+ case MachineOperand::MO_ExternalSymbol:
+ MCInstLowering.lowerOperand(CallTarget, CallTargetMCOp);
+ CallOpcode = AArch64::BL;
+ break;
+ case MachineOperand::MO_Immediate:
+ CallTargetMCOp = MCOperand::createImm(CallTarget.getImm());
+ CallOpcode = AArch64::BL;
+ break;
+ case MachineOperand::MO_Register:
+ CallTargetMCOp = MCOperand::createReg(CallTarget.getReg());
+ CallOpcode = AArch64::BLR;
+ break;
+ default:
+ llvm_unreachable("Unsupported operand type in statepoint call target");
+ break;
+ }
+
+ EmitToStreamer(OutStreamer,
+ MCInstBuilder(CallOpcode).addOperand(CallTargetMCOp));
+ }
+
+ auto &Ctx = OutStreamer.getContext();
+ MCSymbol *MILabel = Ctx.createTempSymbol();
+ OutStreamer.emitLabel(MILabel);
+ SM.recordStatepoint(*MILabel, MI);
+}
+
+void AArch64AsmPrinter::LowerFAULTING_OP(const MachineInstr &FaultingMI) {
+ // FAULTING_LOAD_OP <def>, <faltinf type>, <MBB handler>,
+ // <opcode>, <operands>
+
+ Register DefRegister = FaultingMI.getOperand(0).getReg();
+ FaultMaps::FaultKind FK =
+ static_cast<FaultMaps::FaultKind>(FaultingMI.getOperand(1).getImm());
+ MCSymbol *HandlerLabel = FaultingMI.getOperand(2).getMBB()->getSymbol();
+ unsigned Opcode = FaultingMI.getOperand(3).getImm();
+ unsigned OperandsBeginIdx = 4;
+
+ auto &Ctx = OutStreamer->getContext();
+ MCSymbol *FaultingLabel = Ctx.createTempSymbol();
+ OutStreamer->emitLabel(FaultingLabel);
+
+ assert(FK < FaultMaps::FaultKindMax && "Invalid Faulting Kind!");
+ FM.recordFaultingOp(FK, FaultingLabel, HandlerLabel);
+
+ MCInst MI;
+ MI.setOpcode(Opcode);
+
+ if (DefRegister != (Register)0)
+ MI.addOperand(MCOperand::createReg(DefRegister));
+
+ for (auto I = FaultingMI.operands_begin() + OperandsBeginIdx,
+ E = FaultingMI.operands_end();
+ I != E; ++I) {
+ MCOperand Dest;
+ lowerOperand(*I, Dest);
+ MI.addOperand(Dest);
+ }
+
+ OutStreamer->AddComment("on-fault: " + HandlerLabel->getName());
+ OutStreamer->emitInstruction(MI, getSubtargetInfo());
+}
+
void AArch64AsmPrinter::EmitFMov0(const MachineInstr &MI) {
Register DestReg = MI.getOperand(0).getReg();
if (STI->hasZeroCycleZeroingFP() && !STI->hasZeroCycleZeroingFPWorkaround()) {
@@ -1272,28 +1272,28 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
EmitToStreamer(*OutStreamer, Adrp);
MCInst Ldr;
- if (STI->isTargetILP32()) {
- Ldr.setOpcode(AArch64::LDRWui);
- Ldr.addOperand(MCOperand::createReg(AArch64::W1));
- } else {
- Ldr.setOpcode(AArch64::LDRXui);
- Ldr.addOperand(MCOperand::createReg(AArch64::X1));
- }
+ if (STI->isTargetILP32()) {
+ Ldr.setOpcode(AArch64::LDRWui);
+ Ldr.addOperand(MCOperand::createReg(AArch64::W1));
+ } else {
+ Ldr.setOpcode(AArch64::LDRXui);
+ Ldr.addOperand(MCOperand::createReg(AArch64::X1));
+ }
Ldr.addOperand(MCOperand::createReg(AArch64::X0));
Ldr.addOperand(SymTLSDescLo12);
Ldr.addOperand(MCOperand::createImm(0));
EmitToStreamer(*OutStreamer, Ldr);
MCInst Add;
- if (STI->isTargetILP32()) {
- Add.setOpcode(AArch64::ADDWri);
- Add.addOperand(MCOperand::createReg(AArch64::W0));
- Add.addOperand(MCOperand::createReg(AArch64::W0));
- } else {
- Add.setOpcode(AArch64::ADDXri);
- Add.addOperand(MCOperand::createReg(AArch64::X0));
- Add.addOperand(MCOperand::createReg(AArch64::X0));
- }
+ if (STI->isTargetILP32()) {
+ Add.setOpcode(AArch64::ADDWri);
+ Add.addOperand(MCOperand::createReg(AArch64::W0));
+ Add.addOperand(MCOperand::createReg(AArch64::W0));
+ } else {
+ Add.setOpcode(AArch64::ADDXri);
+ Add.addOperand(MCOperand::createReg(AArch64::X0));
+ Add.addOperand(MCOperand::createReg(AArch64::X0));
+ }
Add.addOperand(SymTLSDescLo12);
Add.addOperand(MCOperand::createImm(AArch64_AM::getShiftValue(0)));
EmitToStreamer(*OutStreamer, Add);
@@ -1313,10 +1313,10 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
return;
}
- case AArch64::JumpTableDest32:
+ case AArch64::JumpTableDest32:
case AArch64::JumpTableDest16:
case AArch64::JumpTableDest8:
- LowerJumpTableDest(*OutStreamer, *MI);
+ LowerJumpTableDest(*OutStreamer, *MI);
return;
case AArch64::FMOVH0:
@@ -1331,12 +1331,12 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
case TargetOpcode::PATCHPOINT:
return LowerPATCHPOINT(*OutStreamer, SM, *MI);
- case TargetOpcode::STATEPOINT:
- return LowerSTATEPOINT(*OutStreamer, SM, *MI);
-
- case TargetOpcode::FAULTING_OP:
- return LowerFAULTING_OP(*MI);
-
+ case TargetOpcode::STATEPOINT:
+ return LowerSTATEPOINT(*OutStreamer, SM, *MI);
+
+ case TargetOpcode::FAULTING_OP:
+ return LowerFAULTING_OP(*MI);
+
case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
LowerPATCHABLE_FUNCTION_ENTER(*MI);
return;
@@ -1381,14 +1381,14 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
return;
case AArch64::SEH_SaveRegP:
- if (MI->getOperand(1).getImm() == 30 && MI->getOperand(0).getImm() >= 19 &&
- MI->getOperand(0).getImm() <= 28) {
- assert((MI->getOperand(0).getImm() - 19) % 2 == 0 &&
- "Register paired with LR must be odd");
- TS->EmitARM64WinCFISaveLRPair(MI->getOperand(0).getImm(),
- MI->getOperand(2).getImm());
- return;
- }
+ if (MI->getOperand(1).getImm() == 30 && MI->getOperand(0).getImm() >= 19 &&
+ MI->getOperand(0).getImm() <= 28) {
+ assert((MI->getOperand(0).getImm() - 19) % 2 == 0 &&
+ "Register paired with LR must be odd");
+ TS->EmitARM64WinCFISaveLRPair(MI->getOperand(0).getImm(),
+ MI->getOperand(2).getImm());
+ return;
+ }
assert((MI->getOperand(1).getImm() - MI->getOperand(0).getImm() == 1) &&
"Non-consecutive registers not allowed for save_regp");
TS->EmitARM64WinCFISaveRegP(MI->getOperand(0).getImm(),
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64BranchTargets.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64BranchTargets.cpp
index 12a4c8ce9d..d3b5166585 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64BranchTargets.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64BranchTargets.cpp
@@ -16,7 +16,7 @@
//
//===----------------------------------------------------------------------===//
-#include "AArch64MachineFunctionInfo.h"
+#include "AArch64MachineFunctionInfo.h"
#include "AArch64Subtarget.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -58,13 +58,13 @@ FunctionPass *llvm::createAArch64BranchTargetsPass() {
}
bool AArch64BranchTargets::runOnMachineFunction(MachineFunction &MF) {
- if (!MF.getInfo<AArch64FunctionInfo>()->branchTargetEnforcement())
+ if (!MF.getInfo<AArch64FunctionInfo>()->branchTargetEnforcement())
return false;
LLVM_DEBUG(
dbgs() << "********** AArch64 Branch Targets **********\n"
<< "********** Function: " << MF.getName() << '\n');
- const Function &F = MF.getFunction();
+ const Function &F = MF.getFunction();
// LLVM does not consider basic blocks which are the targets of jump tables
// to be address-taken (the address can't escape anywhere else), but they are
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.cpp
index ab1a31e1e7..c51dd48cab 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64CallingConvention.cpp
@@ -42,51 +42,51 @@ static const MCPhysReg ZRegList[] = {AArch64::Z0, AArch64::Z1, AArch64::Z2,
static bool finishStackBlock(SmallVectorImpl<CCValAssign> &PendingMembers,
MVT LocVT, ISD::ArgFlagsTy &ArgFlags,
CCState &State, Align SlotAlign) {
- if (LocVT.isScalableVector()) {
- const AArch64Subtarget &Subtarget = static_cast<const AArch64Subtarget &>(
- State.getMachineFunction().getSubtarget());
- const AArch64TargetLowering *TLI = Subtarget.getTargetLowering();
-
- // We are about to reinvoke the CCAssignFn auto-generated handler. If we
- // don't unset these flags we will get stuck in an infinite loop forever
- // invoking the custom handler.
- ArgFlags.setInConsecutiveRegs(false);
- ArgFlags.setInConsecutiveRegsLast(false);
-
- // The calling convention for passing SVE tuples states that in the event
- // we cannot allocate enough registers for the tuple we should still leave
- // any remaining registers unallocated. However, when we call the
- // CCAssignFn again we want it to behave as if all remaining registers are
- // allocated. This will force the code to pass the tuple indirectly in
- // accordance with the PCS.
- bool RegsAllocated[8];
- for (int I = 0; I < 8; I++) {
- RegsAllocated[I] = State.isAllocated(ZRegList[I]);
- State.AllocateReg(ZRegList[I]);
- }
-
- auto &It = PendingMembers[0];
- CCAssignFn *AssignFn =
- TLI->CCAssignFnForCall(State.getCallingConv(), /*IsVarArg=*/false);
- if (AssignFn(It.getValNo(), It.getValVT(), It.getValVT(), CCValAssign::Full,
- ArgFlags, State))
- llvm_unreachable("Call operand has unhandled type");
-
- // Return the flags to how they were before.
- ArgFlags.setInConsecutiveRegs(true);
- ArgFlags.setInConsecutiveRegsLast(true);
-
- // Return the register state back to how it was before, leaving any
- // unallocated registers available for other smaller types.
- for (int I = 0; I < 8; I++)
- if (!RegsAllocated[I])
- State.DeallocateReg(ZRegList[I]);
-
- // All pending members have now been allocated
- PendingMembers.clear();
- return true;
- }
-
+ if (LocVT.isScalableVector()) {
+ const AArch64Subtarget &Subtarget = static_cast<const AArch64Subtarget &>(
+ State.getMachineFunction().getSubtarget());
+ const AArch64TargetLowering *TLI = Subtarget.getTargetLowering();
+
+ // We are about to reinvoke the CCAssignFn auto-generated handler. If we
+ // don't unset these flags we will get stuck in an infinite loop forever
+ // invoking the custom handler.
+ ArgFlags.setInConsecutiveRegs(false);
+ ArgFlags.setInConsecutiveRegsLast(false);
+
+ // The calling convention for passing SVE tuples states that in the event
+ // we cannot allocate enough registers for the tuple we should still leave
+ // any remaining registers unallocated. However, when we call the
+ // CCAssignFn again we want it to behave as if all remaining registers are
+ // allocated. This will force the code to pass the tuple indirectly in
+ // accordance with the PCS.
+ bool RegsAllocated[8];
+ for (int I = 0; I < 8; I++) {
+ RegsAllocated[I] = State.isAllocated(ZRegList[I]);
+ State.AllocateReg(ZRegList[I]);
+ }
+
+ auto &It = PendingMembers[0];
+ CCAssignFn *AssignFn =
+ TLI->CCAssignFnForCall(State.getCallingConv(), /*IsVarArg=*/false);
+ if (AssignFn(It.getValNo(), It.getValVT(), It.getValVT(), CCValAssign::Full,
+ ArgFlags, State))
+ llvm_unreachable("Call operand has unhandled type");
+
+ // Return the flags to how they were before.
+ ArgFlags.setInConsecutiveRegs(true);
+ ArgFlags.setInConsecutiveRegsLast(true);
+
+ // Return the register state back to how it was before, leaving any
+ // unallocated registers available for other smaller types.
+ for (int I = 0; I < 8; I++)
+ if (!RegsAllocated[I])
+ State.DeallocateReg(ZRegList[I]);
+
+ // All pending members have now been allocated
+ PendingMembers.clear();
+ return true;
+ }
+
unsigned Size = LocVT.getSizeInBits() / 8;
const Align StackAlign =
State.getMachineFunction().getDataLayout().getStackAlignment();
@@ -191,11 +191,11 @@ static bool CC_AArch64_Custom_Block(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
return true;
}
- if (!LocVT.isScalableVector()) {
- // Mark all regs in the class as unavailable
- for (auto Reg : RegList)
- State.AllocateReg(Reg);
- }
+ if (!LocVT.isScalableVector()) {
+ // Mark all regs in the class as unavailable
+ for (auto Reg : RegList)
+ State.AllocateReg(Reg);
+ }
const Align SlotAlign = Subtarget.isTargetDarwin() ? Align(1) : Align(8);
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td b/contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
index 03d92b8d50..b1e714653f 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64Combine.td
@@ -75,68 +75,68 @@ def ext: GICombineRule <
// instruction.
def shuffle_vector_pseudos : GICombineGroup<[dup, rev, ext, zip, uzp, trn]>;
-def vashr_vlshr_imm_matchdata : GIDefMatchData<"int64_t">;
-def vashr_vlshr_imm : GICombineRule<
- (defs root:$root, vashr_vlshr_imm_matchdata:$matchinfo),
- (match (wip_match_opcode G_ASHR, G_LSHR):$root,
- [{ return matchVAshrLshrImm(*${root}, MRI, ${matchinfo}); }]),
- (apply [{ applyVAshrLshrImm(*${root}, MRI, ${matchinfo}); }])
->;
-
-def form_duplane_matchdata :
- GIDefMatchData<"std::pair<unsigned, int>">;
-def form_duplane : GICombineRule <
- (defs root:$root, form_duplane_matchdata:$matchinfo),
- (match (wip_match_opcode G_SHUFFLE_VECTOR):$root,
- [{ return matchDupLane(*${root}, MRI, ${matchinfo}); }]),
- (apply [{ applyDupLane(*${root}, MRI, B, ${matchinfo}); }])
->;
-
-def adjust_icmp_imm_matchdata :
- GIDefMatchData<"std::pair<uint64_t, CmpInst::Predicate>">;
-def adjust_icmp_imm : GICombineRule <
- (defs root:$root, adjust_icmp_imm_matchdata:$matchinfo),
- (match (wip_match_opcode G_ICMP):$root,
- [{ return matchAdjustICmpImmAndPred(*${root}, MRI, ${matchinfo}); }]),
- (apply [{ applyAdjustICmpImmAndPred(*${root}, ${matchinfo}, B, Observer); }])
->;
-
-def icmp_lowering : GICombineGroup<[adjust_icmp_imm]>;
-
-def extractvecelt_pairwise_add_matchdata : GIDefMatchData<"std::tuple<unsigned, LLT, Register>">;
-def extractvecelt_pairwise_add : GICombineRule<
- (defs root:$root, extractvecelt_pairwise_add_matchdata:$matchinfo),
- (match (wip_match_opcode G_EXTRACT_VECTOR_ELT):$root,
- [{ return matchExtractVecEltPairwiseAdd(*${root}, MRI, ${matchinfo}); }]),
- (apply [{ applyExtractVecEltPairwiseAdd(*${root}, MRI, B, ${matchinfo}); }])
->;
-
-def mul_const_matchdata : GIDefMatchData<"std::function<void(MachineIRBuilder&, Register)>">;
-def mul_const : GICombineRule<
- (defs root:$root, mul_const_matchdata:$matchinfo),
- (match (wip_match_opcode G_MUL):$root,
- [{ return matchAArch64MulConstCombine(*${root}, MRI, ${matchinfo}); }]),
- (apply [{ applyAArch64MulConstCombine(*${root}, MRI, B, ${matchinfo}); }])
->;
-
-// Post-legalization combines which should happen at all optimization levels.
-// (E.g. ones that facilitate matching for the selector) For example, matching
-// pseudos.
-def AArch64PostLegalizerLoweringHelper
- : GICombinerHelper<"AArch64GenPostLegalizerLoweringHelper",
- [shuffle_vector_pseudos, vashr_vlshr_imm,
- icmp_lowering, form_duplane]> {
- let DisableRuleOption = "aarch64postlegalizerlowering-disable-rule";
-}
-
-// Post-legalization combines which are primarily optimizations.
+def vashr_vlshr_imm_matchdata : GIDefMatchData<"int64_t">;
+def vashr_vlshr_imm : GICombineRule<
+ (defs root:$root, vashr_vlshr_imm_matchdata:$matchinfo),
+ (match (wip_match_opcode G_ASHR, G_LSHR):$root,
+ [{ return matchVAshrLshrImm(*${root}, MRI, ${matchinfo}); }]),
+ (apply [{ applyVAshrLshrImm(*${root}, MRI, ${matchinfo}); }])
+>;
+
+def form_duplane_matchdata :
+ GIDefMatchData<"std::pair<unsigned, int>">;
+def form_duplane : GICombineRule <
+ (defs root:$root, form_duplane_matchdata:$matchinfo),
+ (match (wip_match_opcode G_SHUFFLE_VECTOR):$root,
+ [{ return matchDupLane(*${root}, MRI, ${matchinfo}); }]),
+ (apply [{ applyDupLane(*${root}, MRI, B, ${matchinfo}); }])
+>;
+
+def adjust_icmp_imm_matchdata :
+ GIDefMatchData<"std::pair<uint64_t, CmpInst::Predicate>">;
+def adjust_icmp_imm : GICombineRule <
+ (defs root:$root, adjust_icmp_imm_matchdata:$matchinfo),
+ (match (wip_match_opcode G_ICMP):$root,
+ [{ return matchAdjustICmpImmAndPred(*${root}, MRI, ${matchinfo}); }]),
+ (apply [{ applyAdjustICmpImmAndPred(*${root}, ${matchinfo}, B, Observer); }])
+>;
+
+def icmp_lowering : GICombineGroup<[adjust_icmp_imm]>;
+
+def extractvecelt_pairwise_add_matchdata : GIDefMatchData<"std::tuple<unsigned, LLT, Register>">;
+def extractvecelt_pairwise_add : GICombineRule<
+ (defs root:$root, extractvecelt_pairwise_add_matchdata:$matchinfo),
+ (match (wip_match_opcode G_EXTRACT_VECTOR_ELT):$root,
+ [{ return matchExtractVecEltPairwiseAdd(*${root}, MRI, ${matchinfo}); }]),
+ (apply [{ applyExtractVecEltPairwiseAdd(*${root}, MRI, B, ${matchinfo}); }])
+>;
+
+def mul_const_matchdata : GIDefMatchData<"std::function<void(MachineIRBuilder&, Register)>">;
+def mul_const : GICombineRule<
+ (defs root:$root, mul_const_matchdata:$matchinfo),
+ (match (wip_match_opcode G_MUL):$root,
+ [{ return matchAArch64MulConstCombine(*${root}, MRI, ${matchinfo}); }]),
+ (apply [{ applyAArch64MulConstCombine(*${root}, MRI, B, ${matchinfo}); }])
+>;
+
+// Post-legalization combines which should happen at all optimization levels.
+// (E.g. ones that facilitate matching for the selector) For example, matching
+// pseudos.
+def AArch64PostLegalizerLoweringHelper
+ : GICombinerHelper<"AArch64GenPostLegalizerLoweringHelper",
+ [shuffle_vector_pseudos, vashr_vlshr_imm,
+ icmp_lowering, form_duplane]> {
+ let DisableRuleOption = "aarch64postlegalizerlowering-disable-rule";
+}
+
+// Post-legalization combines which are primarily optimizations.
def AArch64PostLegalizerCombinerHelper
: GICombinerHelper<"AArch64GenPostLegalizerCombinerHelper",
- [copy_prop, erase_undef_store, combines_for_extload,
- sext_trunc_sextload,
- hoist_logic_op_with_same_opcode_hands,
- redundant_and, xor_of_and_with_same_reg,
- extractvecelt_pairwise_add, redundant_or,
- mul_const]> {
+ [copy_prop, erase_undef_store, combines_for_extload,
+ sext_trunc_sextload,
+ hoist_logic_op_with_same_opcode_hands,
+ redundant_and, xor_of_and_with_same_reg,
+ extractvecelt_pairwise_add, redundant_or,
+ mul_const]> {
let DisableRuleOption = "aarch64postlegalizercombiner-disable-rule";
}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64CompressJumpTables.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64CompressJumpTables.cpp
index d419598aaa..2328a8b4de 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64CompressJumpTables.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64CompressJumpTables.cpp
@@ -37,14 +37,14 @@ class AArch64CompressJumpTables : public MachineFunctionPass {
MachineFunction *MF;
SmallVector<int, 8> BlockInfo;
- /// Returns the size in instructions of the block \p MBB, or None if we
- /// couldn't get a safe upper bound.
- Optional<int> computeBlockSize(MachineBasicBlock &MBB);
-
- /// Gather information about the function, returns false if we can't perform
- /// this optimization for some reason.
- bool scanFunction();
-
+ /// Returns the size in instructions of the block \p MBB, or None if we
+ /// couldn't get a safe upper bound.
+ Optional<int> computeBlockSize(MachineBasicBlock &MBB);
+
+ /// Gather information about the function, returns false if we can't perform
+ /// this optimization for some reason.
+ bool scanFunction();
+
bool compressJumpTable(MachineInstr &MI, int Offset);
public:
@@ -64,27 +64,27 @@ public:
}
};
char AArch64CompressJumpTables::ID = 0;
-} // namespace
+} // namespace
INITIALIZE_PASS(AArch64CompressJumpTables, DEBUG_TYPE,
"AArch64 compress jump tables pass", false, false)
-Optional<int>
-AArch64CompressJumpTables::computeBlockSize(MachineBasicBlock &MBB) {
+Optional<int>
+AArch64CompressJumpTables::computeBlockSize(MachineBasicBlock &MBB) {
int Size = 0;
- for (const MachineInstr &MI : MBB) {
- // Inline asm may contain some directives like .bytes which we don't
- // currently have the ability to parse accurately. To be safe, just avoid
- // computing a size and bail out.
- if (MI.getOpcode() == AArch64::INLINEASM ||
- MI.getOpcode() == AArch64::INLINEASM_BR)
- return None;
+ for (const MachineInstr &MI : MBB) {
+ // Inline asm may contain some directives like .bytes which we don't
+ // currently have the ability to parse accurately. To be safe, just avoid
+ // computing a size and bail out.
+ if (MI.getOpcode() == AArch64::INLINEASM ||
+ MI.getOpcode() == AArch64::INLINEASM_BR)
+ return None;
Size += TII->getInstSizeInBytes(MI);
- }
+ }
return Size;
}
-bool AArch64CompressJumpTables::scanFunction() {
+bool AArch64CompressJumpTables::scanFunction() {
BlockInfo.clear();
BlockInfo.resize(MF->getNumBlockIDs());
@@ -97,12 +97,12 @@ bool AArch64CompressJumpTables::scanFunction() {
else
AlignedOffset = alignTo(Offset, Alignment);
BlockInfo[MBB.getNumber()] = AlignedOffset;
- auto BlockSize = computeBlockSize(MBB);
- if (!BlockSize)
- return false;
- Offset = AlignedOffset + *BlockSize;
+ auto BlockSize = computeBlockSize(MBB);
+ if (!BlockSize)
+ return false;
+ Offset = AlignedOffset + *BlockSize;
}
- return true;
+ return true;
}
bool AArch64CompressJumpTables::compressJumpTable(MachineInstr &MI,
@@ -121,7 +121,7 @@ bool AArch64CompressJumpTables::compressJumpTable(MachineInstr &MI,
int MaxOffset = std::numeric_limits<int>::min(),
MinOffset = std::numeric_limits<int>::max();
MachineBasicBlock *MinBlock = nullptr;
- for (auto *Block : JT.MBBs) {
+ for (auto *Block : JT.MBBs) {
int BlockOffset = BlockInfo[Block->getNumber()];
assert(BlockOffset % 4 == 0 && "misaligned basic block");
@@ -141,14 +141,14 @@ bool AArch64CompressJumpTables::compressJumpTable(MachineInstr &MI,
}
int Span = MaxOffset - MinOffset;
- auto *AFI = MF->getInfo<AArch64FunctionInfo>();
+ auto *AFI = MF->getInfo<AArch64FunctionInfo>();
if (isUInt<8>(Span / 4)) {
AFI->setJumpTableEntryInfo(JTIdx, 1, MinBlock->getSymbol());
MI.setDesc(TII->get(AArch64::JumpTableDest8));
++NumJT8;
return true;
- }
- if (isUInt<16>(Span / 4)) {
+ }
+ if (isUInt<16>(Span / 4)) {
AFI->setJumpTableEntryInfo(JTIdx, 2, MinBlock->getSymbol());
MI.setDesc(TII->get(AArch64::JumpTableDest16));
++NumJT16;
@@ -169,8 +169,8 @@ bool AArch64CompressJumpTables::runOnMachineFunction(MachineFunction &MFIn) {
if (ST.force32BitJumpTables() && !MF->getFunction().hasMinSize())
return false;
- if (!scanFunction())
- return false;
+ if (!scanFunction())
+ return false;
for (MachineBasicBlock &MBB : *MF) {
int Offset = BlockInfo[MBB.getNumber()];
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
index 1a8731883f..e57650ae60 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
@@ -83,8 +83,8 @@ private:
bool expandSVESpillFill(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI, unsigned Opc,
unsigned N);
- bool expandCALL_RVMARKER(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MBBI);
+ bool expandCALL_RVMARKER(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI);
};
} // end anonymous namespace
@@ -629,46 +629,46 @@ bool AArch64ExpandPseudo::expandSVESpillFill(MachineBasicBlock &MBB,
return true;
}
-bool AArch64ExpandPseudo::expandCALL_RVMARKER(
- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) {
- // Expand CALL_RVMARKER pseudo to a branch, followed by the special `mov x29,
- // x29` marker. Mark the sequence as bundle, to avoid passes moving other code
- // in between.
- MachineInstr &MI = *MBBI;
-
- MachineInstr *OriginalCall;
- MachineOperand &CallTarget = MI.getOperand(0);
- assert((CallTarget.isGlobal() || CallTarget.isReg()) &&
- "invalid operand for regular call");
- unsigned Opc = CallTarget.isGlobal() ? AArch64::BL : AArch64::BLR;
- OriginalCall = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc)).getInstr();
- OriginalCall->addOperand(CallTarget);
-
- unsigned RegMaskStartIdx = 1;
- // Skip register arguments. Those are added during ISel, but are not
- // needed for the concrete branch.
- while (!MI.getOperand(RegMaskStartIdx).isRegMask()) {
- assert(MI.getOperand(RegMaskStartIdx).isReg() &&
- "should only skip register operands");
- RegMaskStartIdx++;
- }
- for (; RegMaskStartIdx < MI.getNumOperands(); ++RegMaskStartIdx)
- OriginalCall->addOperand(MI.getOperand(RegMaskStartIdx));
-
- auto *Marker = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ORRXrs))
- .addReg(AArch64::FP, RegState::Define)
- .addReg(AArch64::XZR)
- .addReg(AArch64::FP)
- .addImm(0)
- .getInstr();
- if (MI.shouldUpdateCallSiteInfo())
- MBB.getParent()->moveCallSiteInfo(&MI, Marker);
- MI.eraseFromParent();
- finalizeBundle(MBB, OriginalCall->getIterator(),
- std::next(Marker->getIterator()));
- return true;
-}
-
+bool AArch64ExpandPseudo::expandCALL_RVMARKER(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) {
+ // Expand CALL_RVMARKER pseudo to a branch, followed by the special `mov x29,
+ // x29` marker. Mark the sequence as bundle, to avoid passes moving other code
+ // in between.
+ MachineInstr &MI = *MBBI;
+
+ MachineInstr *OriginalCall;
+ MachineOperand &CallTarget = MI.getOperand(0);
+ assert((CallTarget.isGlobal() || CallTarget.isReg()) &&
+ "invalid operand for regular call");
+ unsigned Opc = CallTarget.isGlobal() ? AArch64::BL : AArch64::BLR;
+ OriginalCall = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc)).getInstr();
+ OriginalCall->addOperand(CallTarget);
+
+ unsigned RegMaskStartIdx = 1;
+ // Skip register arguments. Those are added during ISel, but are not
+ // needed for the concrete branch.
+ while (!MI.getOperand(RegMaskStartIdx).isRegMask()) {
+ assert(MI.getOperand(RegMaskStartIdx).isReg() &&
+ "should only skip register operands");
+ RegMaskStartIdx++;
+ }
+ for (; RegMaskStartIdx < MI.getNumOperands(); ++RegMaskStartIdx)
+ OriginalCall->addOperand(MI.getOperand(RegMaskStartIdx));
+
+ auto *Marker = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ORRXrs))
+ .addReg(AArch64::FP, RegState::Define)
+ .addReg(AArch64::XZR)
+ .addReg(AArch64::FP)
+ .addImm(0)
+ .getInstr();
+ if (MI.shouldUpdateCallSiteInfo())
+ MBB.getParent()->moveCallSiteInfo(&MI, Marker);
+ MI.eraseFromParent();
+ finalizeBundle(MBB, OriginalCall->getIterator(),
+ std::next(Marker->getIterator()));
+ return true;
+}
+
/// If MBBI references a pseudo instruction that should be expanded here,
/// do the expansion and return true. Otherwise return false.
bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &MBB,
@@ -1056,8 +1056,8 @@ bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &MBB,
return expandSVESpillFill(MBB, MBBI, AArch64::LDR_ZXI, 3);
case AArch64::LDR_ZZXI:
return expandSVESpillFill(MBB, MBBI, AArch64::LDR_ZXI, 2);
- case AArch64::BLR_RVMARKER:
- return expandCALL_RVMARKER(MBB, MBBI);
+ case AArch64::BLR_RVMARKER:
+ return expandCALL_RVMARKER(MBB, MBBI);
}
return false;
}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64FalkorHWPFFix.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64FalkorHWPFFix.cpp
index afd8765f45..209f9f7255 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64FalkorHWPFFix.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64FalkorHWPFFix.cpp
@@ -54,7 +54,7 @@
using namespace llvm;
-#define DEBUG_TYPE "aarch64-falkor-hwpf-fix"
+#define DEBUG_TYPE "aarch64-falkor-hwpf-fix"
STATISTIC(NumStridedLoadsMarked, "Number of strided loads marked");
STATISTIC(NumCollisionsAvoided,
@@ -146,7 +146,7 @@ bool FalkorMarkStridedAccesses::run() {
bool FalkorMarkStridedAccesses::runOnLoop(Loop &L) {
// Only mark strided loads in the inner-most loop
- if (!L.isInnermost())
+ if (!L.isInnermost())
return false;
bool MadeChange = false;
@@ -224,10 +224,10 @@ struct LoadInfo {
char FalkorHWPFFix::ID = 0;
-INITIALIZE_PASS_BEGIN(FalkorHWPFFix, "aarch64-falkor-hwpf-fix-late",
+INITIALIZE_PASS_BEGIN(FalkorHWPFFix, "aarch64-falkor-hwpf-fix-late",
"Falkor HW Prefetch Fix Late Phase", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
-INITIALIZE_PASS_END(FalkorHWPFFix, "aarch64-falkor-hwpf-fix-late",
+INITIALIZE_PASS_END(FalkorHWPFFix, "aarch64-falkor-hwpf-fix-late",
"Falkor HW Prefetch Fix Late Phase", false, false)
static unsigned makeTag(unsigned Dest, unsigned Base, unsigned Offset) {
@@ -830,7 +830,7 @@ bool FalkorHWPFFix::runOnMachineFunction(MachineFunction &Fn) {
for (MachineLoop *I : LI)
for (auto L = df_begin(I), LE = df_end(I); L != LE; ++L)
// Only process inner-loops
- if (L->isInnermost())
+ if (L->isInnermost())
runOnLoop(**L, Fn);
return Modified;
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64FastISel.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64FastISel.cpp
index b4e4233448..9801036653 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64FastISel.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64FastISel.cpp
@@ -3409,7 +3409,7 @@ bool AArch64FastISel::foldXALUIntrinsic(AArch64CC::CondCode &CC,
const Value *RHS = II->getArgOperand(1);
// Canonicalize immediate to the RHS.
- if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS) && II->isCommutative())
+ if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS) && II->isCommutative())
std::swap(LHS, RHS);
// Simplify multiplies.
@@ -3651,10 +3651,10 @@ bool AArch64FastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) {
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::BRK))
.addImm(1);
return true;
- case Intrinsic::debugtrap:
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::BRK))
- .addImm(0xF000);
- return true;
+ case Intrinsic::debugtrap:
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::BRK))
+ .addImm(0xF000);
+ return true;
case Intrinsic::sqrt: {
Type *RetTy = II->getCalledFunction()->getReturnType();
@@ -3696,7 +3696,7 @@ bool AArch64FastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) {
const Value *LHS = II->getArgOperand(0);
const Value *RHS = II->getArgOperand(1);
// Canonicalize immediate to the RHS.
- if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS) && II->isCommutative())
+ if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS) && II->isCommutative())
std::swap(LHS, RHS);
// Simplify multiplies.
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64FrameLowering.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64FrameLowering.cpp
index 9aa8f7a804..65ee501604 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -175,10 +175,10 @@ static cl::opt<bool> StackTaggingMergeSetTag(
cl::desc("merge settag instruction in function epilog"), cl::init(true),
cl::Hidden);
-static cl::opt<bool> OrderFrameObjects("aarch64-order-frame-objects",
- cl::desc("sort stack allocations"),
- cl::init(true), cl::Hidden);
-
+static cl::opt<bool> OrderFrameObjects("aarch64-order-frame-objects",
+ cl::desc("sort stack allocations"),
+ cl::init(true), cl::Hidden);
+
STATISTIC(NumRedZoneFunctions, "Number of functions using red zone");
/// Returns the argument pop size.
@@ -249,7 +249,7 @@ static unsigned estimateRSStackSizeLimit(MachineFunction &MF) {
TargetStackID::Value
AArch64FrameLowering::getStackIDForScalableVectors() const {
- return TargetStackID::ScalableVector;
+ return TargetStackID::ScalableVector;
}
/// Returns the size of the fixed object area (allocated next to sp on entry)
@@ -273,7 +273,7 @@ static unsigned getFixedObjectSize(const MachineFunction &MF,
/// Returns the size of the entire SVE stackframe (calleesaves + spills).
static StackOffset getSVEStackSize(const MachineFunction &MF) {
const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
- return StackOffset::getScalable((int64_t)AFI->getStackSizeSVE());
+ return StackOffset::getScalable((int64_t)AFI->getStackSizeSVE());
}
bool AArch64FrameLowering::canUseRedZone(const MachineFunction &MF) const {
@@ -365,15 +365,15 @@ MachineBasicBlock::iterator AArch64FrameLowering::eliminateCallFramePseudoInstr(
// Most call frames will be allocated at the start of a function so
// this is OK, but it is a limitation that needs dealing with.
assert(Amount > -0xffffff && Amount < 0xffffff && "call frame too large");
- emitFrameOffset(MBB, I, DL, AArch64::SP, AArch64::SP,
- StackOffset::getFixed(Amount), TII);
+ emitFrameOffset(MBB, I, DL, AArch64::SP, AArch64::SP,
+ StackOffset::getFixed(Amount), TII);
}
} else if (CalleePopAmount != 0) {
// If the calling convention demands that the callee pops arguments from the
// stack, we want to add it back if we have a reserved call frame.
assert(CalleePopAmount < 0xffffff && "call frame too large");
emitFrameOffset(MBB, I, DL, AArch64::SP, AArch64::SP,
- StackOffset::getFixed(-(int64_t)CalleePopAmount), TII);
+ StackOffset::getFixed(-(int64_t)CalleePopAmount), TII);
}
return MBB.erase(I);
}
@@ -413,8 +413,8 @@ static void appendVGScaledOffsetExpr(SmallVectorImpl<char> &Expr,
MCCFIInstruction AArch64FrameLowering::createDefCFAExpressionFromSP(
const TargetRegisterInfo &TRI, const StackOffset &OffsetFromSP) const {
int64_t NumBytes, NumVGScaledBytes;
- AArch64InstrInfo::decomposeStackOffsetForDwarfOffsets(OffsetFromSP, NumBytes,
- NumVGScaledBytes);
+ AArch64InstrInfo::decomposeStackOffsetForDwarfOffsets(OffsetFromSP, NumBytes,
+ NumVGScaledBytes);
std::string CommentBuffer = "sp";
llvm::raw_string_ostream Comment(CommentBuffer);
@@ -441,8 +441,8 @@ MCCFIInstruction AArch64FrameLowering::createCfaOffset(
const TargetRegisterInfo &TRI, unsigned Reg,
const StackOffset &OffsetFromDefCFA) const {
int64_t NumBytes, NumVGScaledBytes;
- AArch64InstrInfo::decomposeStackOffsetForDwarfOffsets(
- OffsetFromDefCFA, NumBytes, NumVGScaledBytes);
+ AArch64InstrInfo::decomposeStackOffsetForDwarfOffsets(
+ OffsetFromDefCFA, NumBytes, NumVGScaledBytes);
unsigned DwarfReg = TRI.getDwarfRegNum(Reg, true);
@@ -496,14 +496,14 @@ void AArch64FrameLowering::emitCalleeSavedFrameMoves(
continue;
StackOffset Offset;
- if (MFI.getStackID(Info.getFrameIdx()) == TargetStackID::ScalableVector) {
+ if (MFI.getStackID(Info.getFrameIdx()) == TargetStackID::ScalableVector) {
AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
- Offset =
- StackOffset::getScalable(MFI.getObjectOffset(Info.getFrameIdx())) -
- StackOffset::getFixed(AFI->getCalleeSavedStackSize(MFI));
+ Offset =
+ StackOffset::getScalable(MFI.getObjectOffset(Info.getFrameIdx())) -
+ StackOffset::getFixed(AFI->getCalleeSavedStackSize(MFI));
} else {
- Offset = StackOffset::getFixed(MFI.getObjectOffset(Info.getFrameIdx()) -
- getOffsetOfLocalArea());
+ Offset = StackOffset::getFixed(MFI.getObjectOffset(Info.getFrameIdx()) -
+ getOffsetOfLocalArea());
}
unsigned CFIIndex = MF.addFrameInst(createCfaOffset(*TRI, Reg, Offset));
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
@@ -584,12 +584,12 @@ static bool windowsRequiresStackProbe(MachineFunction &MF,
!F.hasFnAttribute("no-stack-arg-probe");
}
-static bool needsWinCFI(const MachineFunction &MF) {
- const Function &F = MF.getFunction();
- return MF.getTarget().getMCAsmInfo()->usesWindowsCFI() &&
- F.needsUnwindTableEntry();
-}
-
+static bool needsWinCFI(const MachineFunction &MF) {
+ const Function &F = MF.getFunction();
+ return MF.getTarget().getMCAsmInfo()->usesWindowsCFI() &&
+ F.needsUnwindTableEntry();
+}
+
bool AArch64FrameLowering::shouldCombineCSRLocalStackBump(
MachineFunction &MF, uint64_t StackBumpBytes) const {
AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
@@ -600,18 +600,18 @@ bool AArch64FrameLowering::shouldCombineCSRLocalStackBump(
if (AFI->getLocalStackSize() == 0)
return false;
- // For WinCFI, if optimizing for size, prefer to not combine the stack bump
- // (to force a stp with predecrement) to match the packed unwind format,
- // provided that there actually are any callee saved registers to merge the
- // decrement with.
- // This is potentially marginally slower, but allows using the packed
- // unwind format for functions that both have a local area and callee saved
- // registers. Using the packed unwind format notably reduces the size of
- // the unwind info.
- if (needsWinCFI(MF) && AFI->getCalleeSavedStackSize() > 0 &&
- MF.getFunction().hasOptSize())
- return false;
-
+ // For WinCFI, if optimizing for size, prefer to not combine the stack bump
+ // (to force a stp with predecrement) to match the packed unwind format,
+ // provided that there actually are any callee saved registers to merge the
+ // decrement with.
+ // This is potentially marginally slower, but allows using the packed
+ // unwind format for functions that both have a local area and callee saved
+ // registers. Using the packed unwind format notably reduces the size of
+ // the unwind info.
+ if (needsWinCFI(MF) && AFI->getCalleeSavedStackSize() > 0 &&
+ MF.getFunction().hasOptSize())
+ return false;
+
// 512 is the maximum immediate for stp/ldp that will be used for
// callee-save save/restores
if (StackBumpBytes >= 512 || windowsRequiresStackProbe(MF, StackBumpBytes))
@@ -1051,16 +1051,16 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
// to determine the end of the prologue.
DebugLoc DL;
- const auto &MFnI = *MF.getInfo<AArch64FunctionInfo>();
- if (MFnI.shouldSignReturnAddress()) {
- if (MFnI.shouldSignWithBKey()) {
+ const auto &MFnI = *MF.getInfo<AArch64FunctionInfo>();
+ if (MFnI.shouldSignReturnAddress()) {
+ if (MFnI.shouldSignWithBKey()) {
BuildMI(MBB, MBBI, DL, TII->get(AArch64::EMITBKEY))
.setMIFlag(MachineInstr::FrameSetup);
BuildMI(MBB, MBBI, DL, TII->get(AArch64::PACIBSP))
.setMIFlag(MachineInstr::FrameSetup);
- } else {
- BuildMI(MBB, MBBI, DL, TII->get(AArch64::PACIASP))
- .setMIFlag(MachineInstr::FrameSetup);
+ } else {
+ BuildMI(MBB, MBBI, DL, TII->get(AArch64::PACIASP))
+ .setMIFlag(MachineInstr::FrameSetup);
}
unsigned CFIIndex =
@@ -1075,13 +1075,13 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
if (MF.getFunction().getCallingConv() == CallingConv::GHC)
return;
- // Set tagged base pointer to the requested stack slot.
+ // Set tagged base pointer to the requested stack slot.
// Ideally it should match SP value after prologue.
- Optional<int> TBPI = AFI->getTaggedBasePointerIndex();
- if (TBPI)
- AFI->setTaggedBasePointerOffset(-MFI.getObjectOffset(*TBPI));
- else
- AFI->setTaggedBasePointerOffset(MFI.getStackSize());
+ Optional<int> TBPI = AFI->getTaggedBasePointerIndex();
+ if (TBPI)
+ AFI->setTaggedBasePointerOffset(-MFI.getObjectOffset(*TBPI));
+ else
+ AFI->setTaggedBasePointerOffset(MFI.getStackSize());
const StackOffset &SVEStackSize = getSVEStackSize(MF);
@@ -1108,8 +1108,8 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
++NumRedZoneFunctions;
} else {
emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP,
- StackOffset::getFixed(-NumBytes), TII,
- MachineInstr::FrameSetup, false, NeedsWinCFI, &HasWinCFI);
+ StackOffset::getFixed(-NumBytes), TII,
+ MachineInstr::FrameSetup, false, NeedsWinCFI, &HasWinCFI);
if (!NeedsWinCFI && needsFrameMoves) {
// Label used to tie together the PROLOG_LABEL and the MachineMoves.
MCSymbol *FrameLabel = MMI.getContext().createTempSymbol();
@@ -1142,8 +1142,8 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
if (CombineSPBump) {
assert(!SVEStackSize && "Cannot combine SP bump with SVE");
emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP,
- StackOffset::getFixed(-NumBytes), TII,
- MachineInstr::FrameSetup, false, NeedsWinCFI, &HasWinCFI);
+ StackOffset::getFixed(-NumBytes), TII,
+ MachineInstr::FrameSetup, false, NeedsWinCFI, &HasWinCFI);
NumBytes = 0;
} else if (PrologueSaveSize != 0) {
MBBI = convertCalleeSaveRestoreToSPPrePostIncDec(
@@ -1167,7 +1167,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
// For funclets the FP belongs to the containing function.
if (!IsFunclet && HasFP) {
// Only set up FP if we actually need to.
- int64_t FPOffset = AFI->getCalleeSaveBaseToFrameRecordOffset();
+ int64_t FPOffset = AFI->getCalleeSaveBaseToFrameRecordOffset();
if (CombineSPBump)
FPOffset += AFI->getLocalStackSize();
@@ -1177,8 +1177,8 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
// Note: All stores of callee-saved registers are marked as "FrameSetup".
// This code marks the instruction(s) that set the FP also.
emitFrameOffset(MBB, MBBI, DL, AArch64::FP, AArch64::SP,
- StackOffset::getFixed(FPOffset), TII,
- MachineInstr::FrameSetup, false, NeedsWinCFI, &HasWinCFI);
+ StackOffset::getFixed(FPOffset), TII,
+ MachineInstr::FrameSetup, false, NeedsWinCFI, &HasWinCFI);
}
if (windowsRequiresStackProbe(MF, NumBytes)) {
@@ -1288,7 +1288,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
++MBBI;
CalleeSavesEnd = MBBI;
- AllocateBefore = StackOffset::getScalable(CalleeSavedSize);
+ AllocateBefore = StackOffset::getScalable(CalleeSavedSize);
AllocateAfter = SVEStackSize - AllocateBefore;
}
@@ -1320,8 +1320,8 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
// the correct value here, as NumBytes also includes padding bytes,
// which shouldn't be counted here.
emitFrameOffset(MBB, MBBI, DL, scratchSPReg, AArch64::SP,
- StackOffset::getFixed(-NumBytes), TII,
- MachineInstr::FrameSetup, false, NeedsWinCFI, &HasWinCFI);
+ StackOffset::getFixed(-NumBytes), TII,
+ MachineInstr::FrameSetup, false, NeedsWinCFI, &HasWinCFI);
if (NeedsRealignment) {
const unsigned NrBitsToZero = Log2(MFI.getMaxAlign());
@@ -1458,15 +1458,15 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
// .cfi_offset w28, -32
if (HasFP) {
- const int OffsetToFirstCalleeSaveFromFP =
- AFI->getCalleeSaveBaseToFrameRecordOffset() -
- AFI->getCalleeSavedStackSize();
- Register FramePtr = RegInfo->getFrameRegister(MF);
-
+ const int OffsetToFirstCalleeSaveFromFP =
+ AFI->getCalleeSaveBaseToFrameRecordOffset() -
+ AFI->getCalleeSavedStackSize();
+ Register FramePtr = RegInfo->getFrameRegister(MF);
+
// Define the current CFA rule to use the provided FP.
unsigned Reg = RegInfo->getDwarfRegNum(FramePtr, true);
unsigned CFIIndex = MF.addFrameInst(
- MCCFIInstruction::cfiDefCfa(nullptr, Reg, FixedObject - OffsetToFirstCalleeSaveFromFP));
+ MCCFIInstruction::cfiDefCfa(nullptr, Reg, FixedObject - OffsetToFirstCalleeSaveFromFP));
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
.addCFIIndex(CFIIndex)
.setMIFlags(MachineInstr::FrameSetup);
@@ -1476,7 +1476,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
const TargetSubtargetInfo &STI = MF.getSubtarget();
const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
StackOffset TotalSize =
- SVEStackSize + StackOffset::getFixed((int64_t)MFI.getStackSize());
+ SVEStackSize + StackOffset::getFixed((int64_t)MFI.getStackSize());
CFIIndex = MF.addFrameInst(createDefCFAExpressionFromSP(TRI, TotalSize));
} else {
// Encode the stack size of the leaf function.
@@ -1496,8 +1496,8 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
static void InsertReturnAddressAuth(MachineFunction &MF,
MachineBasicBlock &MBB) {
- const auto &MFI = *MF.getInfo<AArch64FunctionInfo>();
- if (!MFI.shouldSignReturnAddress())
+ const auto &MFI = *MF.getInfo<AArch64FunctionInfo>();
+ if (!MFI.shouldSignReturnAddress())
return;
const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
@@ -1511,16 +1511,16 @@ static void InsertReturnAddressAuth(MachineFunction &MF,
// this instruction can safely used for any v8a architecture.
// From v8.3a onwards there are optimised authenticate LR and return
// instructions, namely RETA{A,B}, that can be used instead.
- if (Subtarget.hasPAuth() && MBBI != MBB.end() &&
+ if (Subtarget.hasPAuth() && MBBI != MBB.end() &&
MBBI->getOpcode() == AArch64::RET_ReallyLR) {
BuildMI(MBB, MBBI, DL,
- TII->get(MFI.shouldSignWithBKey() ? AArch64::RETAB : AArch64::RETAA))
+ TII->get(MFI.shouldSignWithBKey() ? AArch64::RETAB : AArch64::RETAA))
.copyImplicitOps(*MBBI);
MBB.erase(MBBI);
} else {
BuildMI(
MBB, MBBI, DL,
- TII->get(MFI.shouldSignWithBKey() ? AArch64::AUTIBSP : AArch64::AUTIASP))
+ TII->get(MFI.shouldSignWithBKey() ? AArch64::AUTIBSP : AArch64::AUTIASP))
.setMIFlag(MachineInstr::FrameDestroy);
}
}
@@ -1545,7 +1545,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
bool NeedsWinCFI = needsWinCFI(MF);
bool HasWinCFI = false;
bool IsFunclet = false;
- auto WinCFI = make_scope_exit([&]() { assert(HasWinCFI == MF.hasWinCFI()); });
+ auto WinCFI = make_scope_exit([&]() { assert(HasWinCFI == MF.hasWinCFI()); });
if (MBB.end() != MBBI) {
DL = MBBI->getDebugLoc();
@@ -1645,13 +1645,13 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
NeedsWinCFI, &HasWinCFI);
}
- if (MF.hasWinCFI()) {
- // If the prologue didn't contain any SEH opcodes and didn't set the
- // MF.hasWinCFI() flag, assume the epilogue won't either, and skip the
- // EpilogStart - to avoid generating CFI for functions that don't need it.
- // (And as we didn't generate any prologue at all, it would be asymmetrical
- // to the epilogue.) By the end of the function, we assert that
- // HasWinCFI is equal to MF.hasWinCFI(), to verify this assumption.
+ if (MF.hasWinCFI()) {
+ // If the prologue didn't contain any SEH opcodes and didn't set the
+ // MF.hasWinCFI() flag, assume the epilogue won't either, and skip the
+ // EpilogStart - to avoid generating CFI for functions that don't need it.
+ // (And as we didn't generate any prologue at all, it would be asymmetrical
+ // to the epilogue.) By the end of the function, we assert that
+ // HasWinCFI is equal to MF.hasWinCFI(), to verify this assumption.
HasWinCFI = true;
BuildMI(MBB, LastPopI, DL, TII->get(AArch64::SEH_EpilogStart))
.setMIFlag(MachineInstr::FrameDestroy);
@@ -1663,10 +1663,10 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
if (CombineSPBump) {
assert(!SVEStackSize && "Cannot combine SP bump with SVE");
emitFrameOffset(MBB, MBB.getFirstTerminator(), DL, AArch64::SP, AArch64::SP,
- StackOffset::getFixed(NumBytes + (int64_t)AfterCSRPopSize),
- TII, MachineInstr::FrameDestroy, false, NeedsWinCFI,
- &HasWinCFI);
- if (HasWinCFI)
+ StackOffset::getFixed(NumBytes + (int64_t)AfterCSRPopSize),
+ TII, MachineInstr::FrameDestroy, false, NeedsWinCFI,
+ &HasWinCFI);
+ if (HasWinCFI)
BuildMI(MBB, MBB.getFirstTerminator(), DL,
TII->get(AArch64::SEH_EpilogEnd))
.setMIFlag(MachineInstr::FrameDestroy);
@@ -1689,8 +1689,8 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
assert(IsSVECalleeSave(RestoreBegin) &&
IsSVECalleeSave(std::prev(RestoreEnd)) && "Unexpected instruction");
- StackOffset CalleeSavedSizeAsOffset =
- StackOffset::getScalable(CalleeSavedSize);
+ StackOffset CalleeSavedSizeAsOffset =
+ StackOffset::getScalable(CalleeSavedSize);
DeallocateBefore = SVEStackSize - CalleeSavedSizeAsOffset;
DeallocateAfter = CalleeSavedSizeAsOffset;
}
@@ -1703,15 +1703,15 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
// be reloaded. The code below will deallocate the stack space
// space by moving FP -> SP.
emitFrameOffset(MBB, RestoreBegin, DL, AArch64::SP, AArch64::FP,
- StackOffset::getScalable(-CalleeSavedSize), TII,
+ StackOffset::getScalable(-CalleeSavedSize), TII,
MachineInstr::FrameDestroy);
} else {
if (AFI->getSVECalleeSavedStackSize()) {
// Deallocate the non-SVE locals first before we can deallocate (and
// restore callee saves) from the SVE area.
emitFrameOffset(MBB, RestoreBegin, DL, AArch64::SP, AArch64::SP,
- StackOffset::getFixed(NumBytes), TII,
- MachineInstr::FrameDestroy);
+ StackOffset::getFixed(NumBytes), TII,
+ MachineInstr::FrameDestroy);
NumBytes = 0;
}
@@ -1744,10 +1744,10 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
adaptForLdStOpt(MBB, MBB.getFirstTerminator(), LastPopI);
emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::SP,
- StackOffset::getFixed(StackRestoreBytes), TII,
+ StackOffset::getFixed(StackRestoreBytes), TII,
MachineInstr::FrameDestroy, false, NeedsWinCFI, &HasWinCFI);
if (Done) {
- if (HasWinCFI) {
+ if (HasWinCFI) {
BuildMI(MBB, MBB.getFirstTerminator(), DL,
TII->get(AArch64::SEH_EpilogEnd))
.setMIFlag(MachineInstr::FrameDestroy);
@@ -1763,14 +1763,14 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
// non-post-indexed loads for the restores if we aren't actually going to
// be able to save any instructions.
if (!IsFunclet && (MFI.hasVarSizedObjects() || AFI->isStackRealigned())) {
- emitFrameOffset(
- MBB, LastPopI, DL, AArch64::SP, AArch64::FP,
- StackOffset::getFixed(-AFI->getCalleeSaveBaseToFrameRecordOffset()),
- TII, MachineInstr::FrameDestroy, false, NeedsWinCFI);
+ emitFrameOffset(
+ MBB, LastPopI, DL, AArch64::SP, AArch64::FP,
+ StackOffset::getFixed(-AFI->getCalleeSaveBaseToFrameRecordOffset()),
+ TII, MachineInstr::FrameDestroy, false, NeedsWinCFI);
} else if (NumBytes)
emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::SP,
- StackOffset::getFixed(NumBytes), TII,
- MachineInstr::FrameDestroy, false, NeedsWinCFI);
+ StackOffset::getFixed(NumBytes), TII,
+ MachineInstr::FrameDestroy, false, NeedsWinCFI);
// This must be placed after the callee-save restore code because that code
// assumes the SP is at the same location as it was after the callee-save save
@@ -1791,10 +1791,10 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
adaptForLdStOpt(MBB, FirstSPPopI, LastPopI);
emitFrameOffset(MBB, FirstSPPopI, DL, AArch64::SP, AArch64::SP,
- StackOffset::getFixed((int64_t)AfterCSRPopSize), TII,
+ StackOffset::getFixed((int64_t)AfterCSRPopSize), TII,
MachineInstr::FrameDestroy, false, NeedsWinCFI, &HasWinCFI);
}
- if (HasWinCFI)
+ if (HasWinCFI)
BuildMI(MBB, MBB.getFirstTerminator(), DL, TII->get(AArch64::SEH_EpilogEnd))
.setMIFlag(MachineInstr::FrameDestroy);
}
@@ -1803,51 +1803,51 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
/// debug info. It's the same as what we use for resolving the code-gen
/// references for now. FIXME: This can go wrong when references are
/// SP-relative and simple call frames aren't used.
-StackOffset
-AArch64FrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
- Register &FrameReg) const {
+StackOffset
+AArch64FrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
+ Register &FrameReg) const {
return resolveFrameIndexReference(
- MF, FI, FrameReg,
- /*PreferFP=*/
- MF.getFunction().hasFnAttribute(Attribute::SanitizeHWAddress),
- /*ForSimm=*/false);
+ MF, FI, FrameReg,
+ /*PreferFP=*/
+ MF.getFunction().hasFnAttribute(Attribute::SanitizeHWAddress),
+ /*ForSimm=*/false);
}
-StackOffset
-AArch64FrameLowering::getNonLocalFrameIndexReference(const MachineFunction &MF,
- int FI) const {
- return StackOffset::getFixed(getSEHFrameIndexOffset(MF, FI));
+StackOffset
+AArch64FrameLowering::getNonLocalFrameIndexReference(const MachineFunction &MF,
+ int FI) const {
+ return StackOffset::getFixed(getSEHFrameIndexOffset(MF, FI));
}
-static StackOffset getFPOffset(const MachineFunction &MF,
- int64_t ObjectOffset) {
+static StackOffset getFPOffset(const MachineFunction &MF,
+ int64_t ObjectOffset) {
const auto *AFI = MF.getInfo<AArch64FunctionInfo>();
const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
bool IsWin64 =
Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv());
unsigned FixedObject =
getFixedObjectSize(MF, AFI, IsWin64, /*IsFunclet=*/false);
- int64_t CalleeSaveSize = AFI->getCalleeSavedStackSize(MF.getFrameInfo());
- int64_t FPAdjust =
- CalleeSaveSize - AFI->getCalleeSaveBaseToFrameRecordOffset();
- return StackOffset::getFixed(ObjectOffset + FixedObject + FPAdjust);
+ int64_t CalleeSaveSize = AFI->getCalleeSavedStackSize(MF.getFrameInfo());
+ int64_t FPAdjust =
+ CalleeSaveSize - AFI->getCalleeSaveBaseToFrameRecordOffset();
+ return StackOffset::getFixed(ObjectOffset + FixedObject + FPAdjust);
}
-static StackOffset getStackOffset(const MachineFunction &MF,
- int64_t ObjectOffset) {
+static StackOffset getStackOffset(const MachineFunction &MF,
+ int64_t ObjectOffset) {
const auto &MFI = MF.getFrameInfo();
- return StackOffset::getFixed(ObjectOffset + (int64_t)MFI.getStackSize());
+ return StackOffset::getFixed(ObjectOffset + (int64_t)MFI.getStackSize());
}
- // TODO: This function currently does not work for scalable vectors.
+ // TODO: This function currently does not work for scalable vectors.
int AArch64FrameLowering::getSEHFrameIndexOffset(const MachineFunction &MF,
int FI) const {
const auto *RegInfo = static_cast<const AArch64RegisterInfo *>(
MF.getSubtarget().getRegisterInfo());
int ObjectOffset = MF.getFrameInfo().getObjectOffset(FI);
return RegInfo->getLocalAddressRegister(MF) == AArch64::FP
- ? getFPOffset(MF, ObjectOffset).getFixed()
- : getStackOffset(MF, ObjectOffset).getFixed();
+ ? getFPOffset(MF, ObjectOffset).getFixed()
+ : getStackOffset(MF, ObjectOffset).getFixed();
}
StackOffset AArch64FrameLowering::resolveFrameIndexReference(
@@ -1856,7 +1856,7 @@ StackOffset AArch64FrameLowering::resolveFrameIndexReference(
const auto &MFI = MF.getFrameInfo();
int64_t ObjectOffset = MFI.getObjectOffset(FI);
bool isFixed = MFI.isFixedObjectIndex(FI);
- bool isSVE = MFI.getStackID(FI) == TargetStackID::ScalableVector;
+ bool isSVE = MFI.getStackID(FI) == TargetStackID::ScalableVector;
return resolveFrameOffsetReference(MF, ObjectOffset, isFixed, isSVE, FrameReg,
PreferFP, ForSimm);
}
@@ -1870,8 +1870,8 @@ StackOffset AArch64FrameLowering::resolveFrameOffsetReference(
const auto *AFI = MF.getInfo<AArch64FunctionInfo>();
const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
- int64_t FPOffset = getFPOffset(MF, ObjectOffset).getFixed();
- int64_t Offset = getStackOffset(MF, ObjectOffset).getFixed();
+ int64_t FPOffset = getFPOffset(MF, ObjectOffset).getFixed();
+ int64_t Offset = getStackOffset(MF, ObjectOffset).getFixed();
bool isCSR =
!isFixed && ObjectOffset >= -((int)AFI->getCalleeSavedStackSize(MFI));
@@ -1946,16 +1946,16 @@ StackOffset AArch64FrameLowering::resolveFrameOffsetReference(
"non-argument/CSR objects cannot be accessed through the frame pointer");
if (isSVE) {
- StackOffset FPOffset =
- StackOffset::get(-AFI->getCalleeSaveBaseToFrameRecordOffset(), ObjectOffset);
- StackOffset SPOffset =
- SVEStackSize +
- StackOffset::get(MFI.getStackSize() - AFI->getCalleeSavedStackSize(),
- ObjectOffset);
+ StackOffset FPOffset =
+ StackOffset::get(-AFI->getCalleeSaveBaseToFrameRecordOffset(), ObjectOffset);
+ StackOffset SPOffset =
+ SVEStackSize +
+ StackOffset::get(MFI.getStackSize() - AFI->getCalleeSavedStackSize(),
+ ObjectOffset);
// Always use the FP for SVE spills if available and beneficial.
if (hasFP(MF) &&
- (SPOffset.getFixed() ||
- FPOffset.getScalable() < SPOffset.getScalable() ||
+ (SPOffset.getFixed() ||
+ FPOffset.getScalable() < SPOffset.getScalable() ||
RegInfo->needsStackRealignment(MF))) {
FrameReg = RegInfo->getFrameRegister(MF);
return FPOffset;
@@ -1974,7 +1974,7 @@ StackOffset AArch64FrameLowering::resolveFrameOffsetReference(
if (UseFP) {
FrameReg = RegInfo->getFrameRegister(MF);
- return StackOffset::getFixed(FPOffset) + ScalableOffset;
+ return StackOffset::getFixed(FPOffset) + ScalableOffset;
}
// Use the base pointer if we have one.
@@ -1991,7 +1991,7 @@ StackOffset AArch64FrameLowering::resolveFrameOffsetReference(
Offset -= AFI->getLocalStackSize();
}
- return StackOffset::getFixed(Offset) + ScalableOffset;
+ return StackOffset::getFixed(Offset) + ScalableOffset;
}
static unsigned getPrologueDeath(MachineFunction &MF, unsigned Reg) {
@@ -2013,12 +2013,12 @@ static bool produceCompactUnwindFrame(MachineFunction &MF) {
}
static bool invalidateWindowsRegisterPairing(unsigned Reg1, unsigned Reg2,
- bool NeedsWinCFI, bool IsFirst) {
+ bool NeedsWinCFI, bool IsFirst) {
// If we are generating register pairs for a Windows function that requires
// EH support, then pair consecutive registers only. There are no unwind
// opcodes for saves/restores of non-consectuve register pairs.
- // The unwind opcodes are save_regp, save_regp_x, save_fregp, save_frepg_x,
- // save_lrpair.
+ // The unwind opcodes are save_regp, save_regp_x, save_fregp, save_frepg_x,
+ // save_lrpair.
// https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
if (Reg2 == AArch64::FP)
@@ -2027,14 +2027,14 @@ static bool invalidateWindowsRegisterPairing(unsigned Reg1, unsigned Reg2,
return false;
if (Reg2 == Reg1 + 1)
return false;
- // If pairing a GPR with LR, the pair can be described by the save_lrpair
- // opcode. If this is the first register pair, it would end up with a
- // predecrement, but there's no save_lrpair_x opcode, so we can only do this
- // if LR is paired with something else than the first register.
- // The save_lrpair opcode requires the first register to be an odd one.
- if (Reg1 >= AArch64::X19 && Reg1 <= AArch64::X27 &&
- (Reg1 - AArch64::X19) % 2 == 0 && Reg2 == AArch64::LR && !IsFirst)
- return false;
+ // If pairing a GPR with LR, the pair can be described by the save_lrpair
+ // opcode. If this is the first register pair, it would end up with a
+ // predecrement, but there's no save_lrpair_x opcode, so we can only do this
+ // if LR is paired with something else than the first register.
+ // The save_lrpair opcode requires the first register to be an odd one.
+ if (Reg1 >= AArch64::X19 && Reg1 <= AArch64::X27 &&
+ (Reg1 - AArch64::X19) % 2 == 0 && Reg2 == AArch64::LR && !IsFirst)
+ return false;
return true;
}
@@ -2043,10 +2043,10 @@ static bool invalidateWindowsRegisterPairing(unsigned Reg1, unsigned Reg2,
/// LR and FP need to be allocated together when the frame needs to save
/// the frame-record. This means any other register pairing with LR is invalid.
static bool invalidateRegisterPairing(unsigned Reg1, unsigned Reg2,
- bool UsesWinAAPCS, bool NeedsWinCFI,
- bool NeedsFrameRecord, bool IsFirst) {
+ bool UsesWinAAPCS, bool NeedsWinCFI,
+ bool NeedsFrameRecord, bool IsFirst) {
if (UsesWinAAPCS)
- return invalidateWindowsRegisterPairing(Reg1, Reg2, NeedsWinCFI, IsFirst);
+ return invalidateWindowsRegisterPairing(Reg1, Reg2, NeedsWinCFI, IsFirst);
// If we need to store the frame record, don't pair any register
// with LR other than FP.
@@ -2110,22 +2110,22 @@ static void computeCalleeSaveRegisterPairs(
(Count & 1) == 0) &&
"Odd number of callee-saved regs to spill!");
int ByteOffset = AFI->getCalleeSavedStackSize();
- int StackFillDir = -1;
- int RegInc = 1;
- unsigned FirstReg = 0;
- if (NeedsWinCFI) {
- // For WinCFI, fill the stack from the bottom up.
- ByteOffset = 0;
- StackFillDir = 1;
- // As the CSI array is reversed to match PrologEpilogInserter, iterate
- // backwards, to pair up registers starting from lower numbered registers.
- RegInc = -1;
- FirstReg = Count - 1;
- }
+ int StackFillDir = -1;
+ int RegInc = 1;
+ unsigned FirstReg = 0;
+ if (NeedsWinCFI) {
+ // For WinCFI, fill the stack from the bottom up.
+ ByteOffset = 0;
+ StackFillDir = 1;
+ // As the CSI array is reversed to match PrologEpilogInserter, iterate
+ // backwards, to pair up registers starting from lower numbered registers.
+ RegInc = -1;
+ FirstReg = Count - 1;
+ }
int ScalableByteOffset = AFI->getSVECalleeSavedStackSize();
- // When iterating backwards, the loop condition relies on unsigned wraparound.
- for (unsigned i = FirstReg; i < Count; i += RegInc) {
+ // When iterating backwards, the loop condition relies on unsigned wraparound.
+ for (unsigned i = FirstReg; i < Count; i += RegInc) {
RegPairInfo RPI;
RPI.Reg1 = CSI[i].getReg();
@@ -2143,20 +2143,20 @@ static void computeCalleeSaveRegisterPairs(
llvm_unreachable("Unsupported register class.");
// Add the next reg to the pair if it is in the same register class.
- if (unsigned(i + RegInc) < Count) {
- unsigned NextReg = CSI[i + RegInc].getReg();
- bool IsFirst = i == FirstReg;
+ if (unsigned(i + RegInc) < Count) {
+ unsigned NextReg = CSI[i + RegInc].getReg();
+ bool IsFirst = i == FirstReg;
switch (RPI.Type) {
case RegPairInfo::GPR:
if (AArch64::GPR64RegClass.contains(NextReg) &&
- !invalidateRegisterPairing(RPI.Reg1, NextReg, IsWindows,
- NeedsWinCFI, NeedsFrameRecord, IsFirst))
+ !invalidateRegisterPairing(RPI.Reg1, NextReg, IsWindows,
+ NeedsWinCFI, NeedsFrameRecord, IsFirst))
RPI.Reg2 = NextReg;
break;
case RegPairInfo::FPR64:
if (AArch64::FPR64RegClass.contains(NextReg) &&
- !invalidateWindowsRegisterPairing(RPI.Reg1, NextReg, NeedsWinCFI,
- IsFirst))
+ !invalidateWindowsRegisterPairing(RPI.Reg1, NextReg, NeedsWinCFI,
+ IsFirst))
RPI.Reg2 = NextReg;
break;
case RegPairInfo::FPR128:
@@ -2185,7 +2185,7 @@ static void computeCalleeSaveRegisterPairs(
// The order of the registers in the list is controlled by
// getCalleeSavedRegs(), so they will always be in-order, as well.
assert((!RPI.isPaired() ||
- (CSI[i].getFrameIdx() + RegInc == CSI[i + RegInc].getFrameIdx())) &&
+ (CSI[i].getFrameIdx() + RegInc == CSI[i + RegInc].getFrameIdx())) &&
"Out of order callee saved regs!");
assert((!RPI.isPaired() || !NeedsFrameRecord || RPI.Reg2 != AArch64::FP ||
@@ -2207,73 +2207,73 @@ static void computeCalleeSaveRegisterPairs(
"Callee-save registers not saved as adjacent register pair!");
RPI.FrameIdx = CSI[i].getFrameIdx();
- if (NeedsWinCFI &&
- RPI.isPaired()) // RPI.FrameIdx must be the lower index of the pair
- RPI.FrameIdx = CSI[i + RegInc].getFrameIdx();
+ if (NeedsWinCFI &&
+ RPI.isPaired()) // RPI.FrameIdx must be the lower index of the pair
+ RPI.FrameIdx = CSI[i + RegInc].getFrameIdx();
int Scale = RPI.getScale();
-
- int OffsetPre = RPI.isScalable() ? ScalableByteOffset : ByteOffset;
- assert(OffsetPre % Scale == 0);
-
+
+ int OffsetPre = RPI.isScalable() ? ScalableByteOffset : ByteOffset;
+ assert(OffsetPre % Scale == 0);
+
if (RPI.isScalable())
- ScalableByteOffset += StackFillDir * Scale;
+ ScalableByteOffset += StackFillDir * Scale;
else
- ByteOffset += StackFillDir * (RPI.isPaired() ? 2 * Scale : Scale);
+ ByteOffset += StackFillDir * (RPI.isPaired() ? 2 * Scale : Scale);
assert(!(RPI.isScalable() && RPI.isPaired()) &&
"Paired spill/fill instructions don't exist for SVE vectors");
// Round up size of non-pair to pair size if we need to pad the
// callee-save area to ensure 16-byte alignment.
- if (AFI->hasCalleeSaveStackFreeSpace() && !NeedsWinCFI &&
+ if (AFI->hasCalleeSaveStackFreeSpace() && !NeedsWinCFI &&
!RPI.isScalable() && RPI.Type != RegPairInfo::FPR128 &&
!RPI.isPaired()) {
- ByteOffset += 8 * StackFillDir;
+ ByteOffset += 8 * StackFillDir;
assert(ByteOffset % 16 == 0);
assert(MFI.getObjectAlign(RPI.FrameIdx) <= Align(16));
- // A stack frame with a gap looks like this, bottom up:
- // d9, d8. x21, gap, x20, x19.
- // Set extra alignment on the x21 object (the only unpaired register)
- // to create the gap above it.
+ // A stack frame with a gap looks like this, bottom up:
+ // d9, d8. x21, gap, x20, x19.
+ // Set extra alignment on the x21 object (the only unpaired register)
+ // to create the gap above it.
MFI.setObjectAlignment(RPI.FrameIdx, Align(16));
}
- int OffsetPost = RPI.isScalable() ? ScalableByteOffset : ByteOffset;
- assert(OffsetPost % Scale == 0);
- // If filling top down (default), we want the offset after incrementing it.
- // If fillibg bootom up (WinCFI) we need the original offset.
- int Offset = NeedsWinCFI ? OffsetPre : OffsetPost;
+ int OffsetPost = RPI.isScalable() ? ScalableByteOffset : ByteOffset;
+ assert(OffsetPost % Scale == 0);
+ // If filling top down (default), we want the offset after incrementing it.
+ // If fillibg bootom up (WinCFI) we need the original offset.
+ int Offset = NeedsWinCFI ? OffsetPre : OffsetPost;
RPI.Offset = Offset / Scale;
assert(((!RPI.isScalable() && RPI.Offset >= -64 && RPI.Offset <= 63) ||
(RPI.isScalable() && RPI.Offset >= -256 && RPI.Offset <= 255)) &&
"Offset out of bounds for LDP/STP immediate");
- // Save the offset to frame record so that the FP register can point to the
- // innermost frame record (spilled FP and LR registers).
- if (NeedsFrameRecord && ((!IsWindows && RPI.Reg1 == AArch64::LR &&
- RPI.Reg2 == AArch64::FP) ||
- (IsWindows && RPI.Reg1 == AArch64::FP &&
- RPI.Reg2 == AArch64::LR)))
- AFI->setCalleeSaveBaseToFrameRecordOffset(Offset);
-
+ // Save the offset to frame record so that the FP register can point to the
+ // innermost frame record (spilled FP and LR registers).
+ if (NeedsFrameRecord && ((!IsWindows && RPI.Reg1 == AArch64::LR &&
+ RPI.Reg2 == AArch64::FP) ||
+ (IsWindows && RPI.Reg1 == AArch64::FP &&
+ RPI.Reg2 == AArch64::LR)))
+ AFI->setCalleeSaveBaseToFrameRecordOffset(Offset);
+
RegPairs.push_back(RPI);
if (RPI.isPaired())
- i += RegInc;
- }
- if (NeedsWinCFI) {
- // If we need an alignment gap in the stack, align the topmost stack
- // object. A stack frame with a gap looks like this, bottom up:
- // x19, d8. d9, gap.
- // Set extra alignment on the topmost stack object (the first element in
- // CSI, which goes top down), to create the gap above it.
- if (AFI->hasCalleeSaveStackFreeSpace())
- MFI.setObjectAlignment(CSI[0].getFrameIdx(), Align(16));
- // We iterated bottom up over the registers; flip RegPairs back to top
- // down order.
- std::reverse(RegPairs.begin(), RegPairs.end());
- }
+ i += RegInc;
+ }
+ if (NeedsWinCFI) {
+ // If we need an alignment gap in the stack, align the topmost stack
+ // object. A stack frame with a gap looks like this, bottom up:
+ // x19, d8. d9, gap.
+ // Set extra alignment on the topmost stack object (the first element in
+ // CSI, which goes top down), to create the gap above it.
+ if (AFI->hasCalleeSaveStackFreeSpace())
+ MFI.setObjectAlignment(CSI[0].getFrameIdx(), Align(16));
+ // We iterated bottom up over the registers; flip RegPairs back to top
+ // down order.
+ std::reverse(RegPairs.begin(), RegPairs.end());
+ }
}
bool AArch64FrameLowering::spillCalleeSavedRegisters(
@@ -2412,7 +2412,7 @@ bool AArch64FrameLowering::spillCalleeSavedRegisters(
// Update the StackIDs of the SVE stack slots.
MachineFrameInfo &MFI = MF.getFrameInfo();
if (RPI.Type == RegPairInfo::ZPR || RPI.Type == RegPairInfo::PPR)
- MFI.setStackID(RPI.FrameIdx, TargetStackID::ScalableVector);
+ MFI.setStackID(RPI.FrameIdx, TargetStackID::ScalableVector);
}
return true;
@@ -2704,21 +2704,21 @@ void AArch64FrameLowering::determineCalleeSaves(MachineFunction &MF,
AFI->setSVECalleeSavedStackSize(alignTo(SVECSStackSize, 16));
}
-bool AArch64FrameLowering::assignCalleeSavedSpillSlots(
- MachineFunction &MF, const TargetRegisterInfo *TRI,
- std::vector<CalleeSavedInfo> &CSI) const {
- bool NeedsWinCFI = needsWinCFI(MF);
- // To match the canonical windows frame layout, reverse the list of
- // callee saved registers to get them laid out by PrologEpilogInserter
- // in the right order. (PrologEpilogInserter allocates stack objects top
- // down. Windows canonical prologs store higher numbered registers at
- // the top, thus have the CSI array start from the highest registers.)
- if (NeedsWinCFI)
- std::reverse(CSI.begin(), CSI.end());
- // Let the generic code do the rest of the setup.
- return false;
-}
-
+bool AArch64FrameLowering::assignCalleeSavedSpillSlots(
+ MachineFunction &MF, const TargetRegisterInfo *TRI,
+ std::vector<CalleeSavedInfo> &CSI) const {
+ bool NeedsWinCFI = needsWinCFI(MF);
+ // To match the canonical windows frame layout, reverse the list of
+ // callee saved registers to get them laid out by PrologEpilogInserter
+ // in the right order. (PrologEpilogInserter allocates stack objects top
+ // down. Windows canonical prologs store higher numbered registers at
+ // the top, thus have the CSI array start from the highest registers.)
+ if (NeedsWinCFI)
+ std::reverse(CSI.begin(), CSI.end());
+ // Let the generic code do the rest of the setup.
+ return false;
+}
+
bool AArch64FrameLowering::enableStackSlotScavenging(
const MachineFunction &MF) const {
const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
@@ -2761,7 +2761,7 @@ static int64_t determineSVEStackObjectOffsets(MachineFrameInfo &MFI,
#ifndef NDEBUG
// First process all fixed stack objects.
for (int I = MFI.getObjectIndexBegin(); I != 0; ++I)
- assert(MFI.getStackID(I) != TargetStackID::ScalableVector &&
+ assert(MFI.getStackID(I) != TargetStackID::ScalableVector &&
"SVE vectors should never be passed on the stack by value, only by "
"reference.");
#endif
@@ -2791,7 +2791,7 @@ static int64_t determineSVEStackObjectOffsets(MachineFrameInfo &MFI,
SmallVector<int, 8> ObjectsToAllocate;
for (int I = 0, E = MFI.getObjectIndexEnd(); I != E; ++I) {
unsigned StackID = MFI.getStackID(I);
- if (StackID != TargetStackID::ScalableVector)
+ if (StackID != TargetStackID::ScalableVector)
continue;
if (MaxCSFrameIndex >= I && I >= MinCSFrameIndex)
continue;
@@ -2945,12 +2945,12 @@ void TagStoreEdit::emitUnrolled(MachineBasicBlock::iterator InsertI) {
const int64_t kMaxOffset = 255 * 16;
Register BaseReg = FrameReg;
- int64_t BaseRegOffsetBytes = FrameRegOffset.getFixed();
+ int64_t BaseRegOffsetBytes = FrameRegOffset.getFixed();
if (BaseRegOffsetBytes < kMinOffset ||
BaseRegOffsetBytes + (Size - Size % 32) > kMaxOffset) {
Register ScratchReg = MRI->createVirtualRegister(&AArch64::GPR64RegClass);
emitFrameOffset(*MBB, InsertI, DL, ScratchReg, BaseReg,
- StackOffset::getFixed(BaseRegOffsetBytes), TII);
+ StackOffset::getFixed(BaseRegOffsetBytes), TII);
BaseReg = ScratchReg;
BaseRegOffsetBytes = 0;
}
@@ -3007,7 +3007,7 @@ void TagStoreEdit::emitLoop(MachineBasicBlock::iterator InsertI) {
LoopI->setFlags(FrameRegUpdateFlags);
int64_t ExtraBaseRegUpdate =
- FrameRegUpdate ? (*FrameRegUpdate - FrameRegOffset.getFixed() - Size) : 0;
+ FrameRegUpdate ? (*FrameRegUpdate - FrameRegOffset.getFixed() - Size) : 0;
if (LoopSize < Size) {
assert(FrameRegUpdate);
assert(Size - LoopSize == 16);
@@ -3111,7 +3111,7 @@ void TagStoreEdit::emitCode(MachineBasicBlock::iterator &InsertI,
// realistically happens in function epilogue. Also, STGloop is expanded
// before that pass.
if (InsertI != MBB->end() &&
- canMergeRegUpdate(InsertI, FrameReg, FrameRegOffset.getFixed() + Size,
+ canMergeRegUpdate(InsertI, FrameReg, FrameRegOffset.getFixed() + Size,
&TotalOffset)) {
UpdateInstr = &*InsertI++;
LLVM_DEBUG(dbgs() << "Folding SP update into loop:\n "
@@ -3274,7 +3274,7 @@ void AArch64FrameLowering::processFunctionBeforeFrameIndicesReplaced(
/// For Win64 AArch64 EH, the offset to the Unwind object is from the SP
/// before the update. This is easily retrieved as it is exactly the offset
/// that is set in processFunctionBeforeFrameFinalized.
-StackOffset AArch64FrameLowering::getFrameIndexReferencePreferSP(
+StackOffset AArch64FrameLowering::getFrameIndexReferencePreferSP(
const MachineFunction &MF, int FI, Register &FrameReg,
bool IgnoreSPUpdates) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
@@ -3282,7 +3282,7 @@ StackOffset AArch64FrameLowering::getFrameIndexReferencePreferSP(
LLVM_DEBUG(dbgs() << "Offset from the SP for " << FI << " is "
<< MFI.getObjectOffset(FI) << "\n");
FrameReg = AArch64::SP;
- return StackOffset::getFixed(MFI.getObjectOffset(FI));
+ return StackOffset::getFixed(MFI.getObjectOffset(FI));
}
return getFrameIndexReference(MF, FI, FrameReg);
@@ -3306,162 +3306,162 @@ unsigned AArch64FrameLowering::getWinEHFuncletFrameSize(
return alignTo(CSSize + MF.getFrameInfo().getMaxCallFrameSize(),
getStackAlign());
}
-
-namespace {
-struct FrameObject {
- bool IsValid = false;
- // Index of the object in MFI.
- int ObjectIndex = 0;
- // Group ID this object belongs to.
- int GroupIndex = -1;
- // This object should be placed first (closest to SP).
- bool ObjectFirst = false;
- // This object's group (which always contains the object with
- // ObjectFirst==true) should be placed first.
- bool GroupFirst = false;
-};
-
-class GroupBuilder {
- SmallVector<int, 8> CurrentMembers;
- int NextGroupIndex = 0;
- std::vector<FrameObject> &Objects;
-
-public:
- GroupBuilder(std::vector<FrameObject> &Objects) : Objects(Objects) {}
- void AddMember(int Index) { CurrentMembers.push_back(Index); }
- void EndCurrentGroup() {
- if (CurrentMembers.size() > 1) {
- // Create a new group with the current member list. This might remove them
- // from their pre-existing groups. That's OK, dealing with overlapping
- // groups is too hard and unlikely to make a difference.
- LLVM_DEBUG(dbgs() << "group:");
- for (int Index : CurrentMembers) {
- Objects[Index].GroupIndex = NextGroupIndex;
- LLVM_DEBUG(dbgs() << " " << Index);
- }
- LLVM_DEBUG(dbgs() << "\n");
- NextGroupIndex++;
- }
- CurrentMembers.clear();
- }
-};
-
-bool FrameObjectCompare(const FrameObject &A, const FrameObject &B) {
- // Objects at a lower index are closer to FP; objects at a higher index are
- // closer to SP.
- //
- // For consistency in our comparison, all invalid objects are placed
- // at the end. This also allows us to stop walking when we hit the
- // first invalid item after it's all sorted.
- //
- // The "first" object goes first (closest to SP), followed by the members of
- // the "first" group.
- //
- // The rest are sorted by the group index to keep the groups together.
- // Higher numbered groups are more likely to be around longer (i.e. untagged
- // in the function epilogue and not at some earlier point). Place them closer
- // to SP.
- //
- // If all else equal, sort by the object index to keep the objects in the
- // original order.
- return std::make_tuple(!A.IsValid, A.ObjectFirst, A.GroupFirst, A.GroupIndex,
- A.ObjectIndex) <
- std::make_tuple(!B.IsValid, B.ObjectFirst, B.GroupFirst, B.GroupIndex,
- B.ObjectIndex);
-}
-} // namespace
-
-void AArch64FrameLowering::orderFrameObjects(
- const MachineFunction &MF, SmallVectorImpl<int> &ObjectsToAllocate) const {
- if (!OrderFrameObjects || ObjectsToAllocate.empty())
- return;
-
- const MachineFrameInfo &MFI = MF.getFrameInfo();
- std::vector<FrameObject> FrameObjects(MFI.getObjectIndexEnd());
- for (auto &Obj : ObjectsToAllocate) {
- FrameObjects[Obj].IsValid = true;
- FrameObjects[Obj].ObjectIndex = Obj;
- }
-
- // Identify stack slots that are tagged at the same time.
- GroupBuilder GB(FrameObjects);
- for (auto &MBB : MF) {
- for (auto &MI : MBB) {
- if (MI.isDebugInstr())
- continue;
- int OpIndex;
- switch (MI.getOpcode()) {
- case AArch64::STGloop:
- case AArch64::STZGloop:
- OpIndex = 3;
- break;
- case AArch64::STGOffset:
- case AArch64::STZGOffset:
- case AArch64::ST2GOffset:
- case AArch64::STZ2GOffset:
- OpIndex = 1;
- break;
- default:
- OpIndex = -1;
- }
-
- int TaggedFI = -1;
- if (OpIndex >= 0) {
- const MachineOperand &MO = MI.getOperand(OpIndex);
- if (MO.isFI()) {
- int FI = MO.getIndex();
- if (FI >= 0 && FI < MFI.getObjectIndexEnd() &&
- FrameObjects[FI].IsValid)
- TaggedFI = FI;
- }
- }
-
- // If this is a stack tagging instruction for a slot that is not part of a
- // group yet, either start a new group or add it to the current one.
- if (TaggedFI >= 0)
- GB.AddMember(TaggedFI);
- else
- GB.EndCurrentGroup();
- }
- // Groups should never span multiple basic blocks.
- GB.EndCurrentGroup();
- }
-
- // If the function's tagged base pointer is pinned to a stack slot, we want to
- // put that slot first when possible. This will likely place it at SP + 0,
- // and save one instruction when generating the base pointer because IRG does
- // not allow an immediate offset.
- const AArch64FunctionInfo &AFI = *MF.getInfo<AArch64FunctionInfo>();
- Optional<int> TBPI = AFI.getTaggedBasePointerIndex();
- if (TBPI) {
- FrameObjects[*TBPI].ObjectFirst = true;
- FrameObjects[*TBPI].GroupFirst = true;
- int FirstGroupIndex = FrameObjects[*TBPI].GroupIndex;
- if (FirstGroupIndex >= 0)
- for (FrameObject &Object : FrameObjects)
- if (Object.GroupIndex == FirstGroupIndex)
- Object.GroupFirst = true;
- }
-
- llvm::stable_sort(FrameObjects, FrameObjectCompare);
-
- int i = 0;
- for (auto &Obj : FrameObjects) {
- // All invalid items are sorted at the end, so it's safe to stop.
- if (!Obj.IsValid)
- break;
- ObjectsToAllocate[i++] = Obj.ObjectIndex;
- }
-
- LLVM_DEBUG(dbgs() << "Final frame order:\n"; for (auto &Obj
- : FrameObjects) {
- if (!Obj.IsValid)
- break;
- dbgs() << " " << Obj.ObjectIndex << ": group " << Obj.GroupIndex;
- if (Obj.ObjectFirst)
- dbgs() << ", first";
- if (Obj.GroupFirst)
- dbgs() << ", group-first";
- dbgs() << "\n";
- });
-}
+
+namespace {
+struct FrameObject {
+ bool IsValid = false;
+ // Index of the object in MFI.
+ int ObjectIndex = 0;
+ // Group ID this object belongs to.
+ int GroupIndex = -1;
+ // This object should be placed first (closest to SP).
+ bool ObjectFirst = false;
+ // This object's group (which always contains the object with
+ // ObjectFirst==true) should be placed first.
+ bool GroupFirst = false;
+};
+
+class GroupBuilder {
+ SmallVector<int, 8> CurrentMembers;
+ int NextGroupIndex = 0;
+ std::vector<FrameObject> &Objects;
+
+public:
+ GroupBuilder(std::vector<FrameObject> &Objects) : Objects(Objects) {}
+ void AddMember(int Index) { CurrentMembers.push_back(Index); }
+ void EndCurrentGroup() {
+ if (CurrentMembers.size() > 1) {
+ // Create a new group with the current member list. This might remove them
+ // from their pre-existing groups. That's OK, dealing with overlapping
+ // groups is too hard and unlikely to make a difference.
+ LLVM_DEBUG(dbgs() << "group:");
+ for (int Index : CurrentMembers) {
+ Objects[Index].GroupIndex = NextGroupIndex;
+ LLVM_DEBUG(dbgs() << " " << Index);
+ }
+ LLVM_DEBUG(dbgs() << "\n");
+ NextGroupIndex++;
+ }
+ CurrentMembers.clear();
+ }
+};
+
+bool FrameObjectCompare(const FrameObject &A, const FrameObject &B) {
+ // Objects at a lower index are closer to FP; objects at a higher index are
+ // closer to SP.
+ //
+ // For consistency in our comparison, all invalid objects are placed
+ // at the end. This also allows us to stop walking when we hit the
+ // first invalid item after it's all sorted.
+ //
+ // The "first" object goes first (closest to SP), followed by the members of
+ // the "first" group.
+ //
+ // The rest are sorted by the group index to keep the groups together.
+ // Higher numbered groups are more likely to be around longer (i.e. untagged
+ // in the function epilogue and not at some earlier point). Place them closer
+ // to SP.
+ //
+ // If all else equal, sort by the object index to keep the objects in the
+ // original order.
+ return std::make_tuple(!A.IsValid, A.ObjectFirst, A.GroupFirst, A.GroupIndex,
+ A.ObjectIndex) <
+ std::make_tuple(!B.IsValid, B.ObjectFirst, B.GroupFirst, B.GroupIndex,
+ B.ObjectIndex);
+}
+} // namespace
+
+void AArch64FrameLowering::orderFrameObjects(
+ const MachineFunction &MF, SmallVectorImpl<int> &ObjectsToAllocate) const {
+ if (!OrderFrameObjects || ObjectsToAllocate.empty())
+ return;
+
+ const MachineFrameInfo &MFI = MF.getFrameInfo();
+ std::vector<FrameObject> FrameObjects(MFI.getObjectIndexEnd());
+ for (auto &Obj : ObjectsToAllocate) {
+ FrameObjects[Obj].IsValid = true;
+ FrameObjects[Obj].ObjectIndex = Obj;
+ }
+
+ // Identify stack slots that are tagged at the same time.
+ GroupBuilder GB(FrameObjects);
+ for (auto &MBB : MF) {
+ for (auto &MI : MBB) {
+ if (MI.isDebugInstr())
+ continue;
+ int OpIndex;
+ switch (MI.getOpcode()) {
+ case AArch64::STGloop:
+ case AArch64::STZGloop:
+ OpIndex = 3;
+ break;
+ case AArch64::STGOffset:
+ case AArch64::STZGOffset:
+ case AArch64::ST2GOffset:
+ case AArch64::STZ2GOffset:
+ OpIndex = 1;
+ break;
+ default:
+ OpIndex = -1;
+ }
+
+ int TaggedFI = -1;
+ if (OpIndex >= 0) {
+ const MachineOperand &MO = MI.getOperand(OpIndex);
+ if (MO.isFI()) {
+ int FI = MO.getIndex();
+ if (FI >= 0 && FI < MFI.getObjectIndexEnd() &&
+ FrameObjects[FI].IsValid)
+ TaggedFI = FI;
+ }
+ }
+
+ // If this is a stack tagging instruction for a slot that is not part of a
+ // group yet, either start a new group or add it to the current one.
+ if (TaggedFI >= 0)
+ GB.AddMember(TaggedFI);
+ else
+ GB.EndCurrentGroup();
+ }
+ // Groups should never span multiple basic blocks.
+ GB.EndCurrentGroup();
+ }
+
+ // If the function's tagged base pointer is pinned to a stack slot, we want to
+ // put that slot first when possible. This will likely place it at SP + 0,
+ // and save one instruction when generating the base pointer because IRG does
+ // not allow an immediate offset.
+ const AArch64FunctionInfo &AFI = *MF.getInfo<AArch64FunctionInfo>();
+ Optional<int> TBPI = AFI.getTaggedBasePointerIndex();
+ if (TBPI) {
+ FrameObjects[*TBPI].ObjectFirst = true;
+ FrameObjects[*TBPI].GroupFirst = true;
+ int FirstGroupIndex = FrameObjects[*TBPI].GroupIndex;
+ if (FirstGroupIndex >= 0)
+ for (FrameObject &Object : FrameObjects)
+ if (Object.GroupIndex == FirstGroupIndex)
+ Object.GroupFirst = true;
+ }
+
+ llvm::stable_sort(FrameObjects, FrameObjectCompare);
+
+ int i = 0;
+ for (auto &Obj : FrameObjects) {
+ // All invalid items are sorted at the end, so it's safe to stop.
+ if (!Obj.IsValid)
+ break;
+ ObjectsToAllocate[i++] = Obj.ObjectIndex;
+ }
+
+ LLVM_DEBUG(dbgs() << "Final frame order:\n"; for (auto &Obj
+ : FrameObjects) {
+ if (!Obj.IsValid)
+ break;
+ dbgs() << " " << Obj.ObjectIndex << ": group " << Obj.GroupIndex;
+ if (Obj.ObjectFirst)
+ dbgs() << ", first";
+ if (Obj.GroupFirst)
+ dbgs() << ", group-first";
+ dbgs() << "\n";
+ });
+}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64FrameLowering.h b/contrib/libs/llvm12/lib/Target/AArch64/AArch64FrameLowering.h
index b3a402de03..80079a9d98 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64FrameLowering.h
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64FrameLowering.h
@@ -13,7 +13,7 @@
#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64FRAMELOWERING_H
#define LLVM_LIB_TARGET_AARCH64_AARCH64FRAMELOWERING_H
-#include "llvm/Support/TypeSize.h"
+#include "llvm/Support/TypeSize.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
namespace llvm {
@@ -41,8 +41,8 @@ public:
bool canUseAsPrologue(const MachineBasicBlock &MBB) const override;
- StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
- Register &FrameReg) const override;
+ StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
+ Register &FrameReg) const override;
StackOffset resolveFrameIndexReference(const MachineFunction &MF, int FI,
Register &FrameReg, bool PreferFP,
bool ForSimm) const;
@@ -67,11 +67,11 @@ public:
bool hasFP(const MachineFunction &MF) const override;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
- bool
- assignCalleeSavedSpillSlots(MachineFunction &MF,
- const TargetRegisterInfo *TRI,
- std::vector<CalleeSavedInfo> &CSI) const override;
-
+ bool
+ assignCalleeSavedSpillSlots(MachineFunction &MF,
+ const TargetRegisterInfo *TRI,
+ std::vector<CalleeSavedInfo> &CSI) const override;
+
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
RegScavenger *RS) const override;
@@ -94,12 +94,12 @@ public:
unsigned getWinEHFuncletFrameSize(const MachineFunction &MF) const;
- StackOffset
- getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI,
- Register &FrameReg,
- bool IgnoreSPUpdates) const override;
- StackOffset getNonLocalFrameIndexReference(const MachineFunction &MF,
- int FI) const override;
+ StackOffset
+ getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI,
+ Register &FrameReg,
+ bool IgnoreSPUpdates) const override;
+ StackOffset getNonLocalFrameIndexReference(const MachineFunction &MF,
+ int FI) const override;
int getSEHFrameIndexOffset(const MachineFunction &MF, int FI) const;
bool isSupportedStackID(TargetStackID::Value ID) const override {
@@ -107,7 +107,7 @@ public:
default:
return false;
case TargetStackID::Default:
- case TargetStackID::ScalableVector:
+ case TargetStackID::ScalableVector:
case TargetStackID::NoAlloc:
return true;
}
@@ -116,13 +116,13 @@ public:
bool isStackIdSafeForLocalArea(unsigned StackId) const override {
// We don't support putting SVE objects into the pre-allocated local
// frame block at the moment.
- return StackId != TargetStackID::ScalableVector;
+ return StackId != TargetStackID::ScalableVector;
}
- void
- orderFrameObjects(const MachineFunction &MF,
- SmallVectorImpl<int> &ObjectsToAllocate) const override;
-
+ void
+ orderFrameObjects(const MachineFunction &MF,
+ SmallVectorImpl<int> &ObjectsToAllocate) const override;
+
private:
bool shouldCombineCSRLocalStackBump(MachineFunction &MF,
uint64_t StackBumpBytes) const;
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
index a570f2d3b0..94b5d7718d 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//
-#include "AArch64MachineFunctionInfo.h"
+#include "AArch64MachineFunctionInfo.h"
#include "AArch64TargetMachine.h"
#include "MCTargetDesc/AArch64AddressingModes.h"
#include "llvm/ADT/APSInt.h"
@@ -191,16 +191,16 @@ public:
return SelectSVELogicalImm(N, VT, Imm);
}
- template <MVT::SimpleValueType VT>
- bool SelectSVEArithImm(SDValue N, SDValue &Imm) {
- return SelectSVEArithImm(N, VT, Imm);
+ template <MVT::SimpleValueType VT>
+ bool SelectSVEArithImm(SDValue N, SDValue &Imm) {
+ return SelectSVEArithImm(N, VT, Imm);
+ }
+
+ template <unsigned Low, unsigned High, bool AllowSaturation = false>
+ bool SelectSVEShiftImm(SDValue N, SDValue &Imm) {
+ return SelectSVEShiftImm(N, Low, High, AllowSaturation, Imm);
}
- template <unsigned Low, unsigned High, bool AllowSaturation = false>
- bool SelectSVEShiftImm(SDValue N, SDValue &Imm) {
- return SelectSVEShiftImm(N, Low, High, AllowSaturation, Imm);
- }
-
// Returns a suitable CNT/INC/DEC/RDVL multiplier to calculate VSCALE*N.
template<signed Min, signed Max, signed Scale, bool Shift>
bool SelectCntImm(SDValue N, SDValue &Imm) {
@@ -329,10 +329,10 @@ private:
bool SelectSVELogicalImm(SDValue N, MVT VT, SDValue &Imm);
bool SelectSVESignedArithImm(SDValue N, SDValue &Imm);
- bool SelectSVEShiftImm(SDValue N, uint64_t Low, uint64_t High,
- bool AllowSaturation, SDValue &Imm);
+ bool SelectSVEShiftImm(SDValue N, uint64_t Low, uint64_t High,
+ bool AllowSaturation, SDValue &Imm);
- bool SelectSVEArithImm(SDValue N, MVT VT, SDValue &Imm);
+ bool SelectSVEArithImm(SDValue N, MVT VT, SDValue &Imm);
bool SelectSVERegRegAddrMode(SDValue N, unsigned Scale, SDValue &Base,
SDValue &Offset);
};
@@ -1377,12 +1377,12 @@ void AArch64DAGToDAGISel::SelectLoad(SDNode *N, unsigned NumVecs, unsigned Opc,
ReplaceUses(SDValue(N, NumVecs), SDValue(Ld, 1));
- // Transfer memoperands. In the case of AArch64::LD64B, there won't be one,
- // because it's too simple to have needed special treatment during lowering.
- if (auto *MemIntr = dyn_cast<MemIntrinsicSDNode>(N)) {
- MachineMemOperand *MemOp = MemIntr->getMemOperand();
- CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {MemOp});
- }
+ // Transfer memoperands. In the case of AArch64::LD64B, there won't be one,
+ // because it's too simple to have needed special treatment during lowering.
+ if (auto *MemIntr = dyn_cast<MemIntrinsicSDNode>(N)) {
+ MachineMemOperand *MemOp = MemIntr->getMemOperand();
+ CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {MemOp});
+ }
CurDAG->RemoveDeadNode(N);
}
@@ -3136,28 +3136,28 @@ bool AArch64DAGToDAGISel::SelectSVESignedArithImm(SDValue N, SDValue &Imm) {
return false;
}
-bool AArch64DAGToDAGISel::SelectSVEArithImm(SDValue N, MVT VT, SDValue &Imm) {
+bool AArch64DAGToDAGISel::SelectSVEArithImm(SDValue N, MVT VT, SDValue &Imm) {
if (auto CNode = dyn_cast<ConstantSDNode>(N)) {
- uint64_t ImmVal = CNode->getZExtValue();
-
- switch (VT.SimpleTy) {
- case MVT::i8:
- ImmVal &= 0xFF;
- break;
- case MVT::i16:
- ImmVal &= 0xFFFF;
- break;
- case MVT::i32:
- ImmVal &= 0xFFFFFFFF;
- break;
- case MVT::i64:
- break;
- default:
- llvm_unreachable("Unexpected type");
- }
-
+ uint64_t ImmVal = CNode->getZExtValue();
+
+ switch (VT.SimpleTy) {
+ case MVT::i8:
+ ImmVal &= 0xFF;
+ break;
+ case MVT::i16:
+ ImmVal &= 0xFFFF;
+ break;
+ case MVT::i32:
+ ImmVal &= 0xFFFFFFFF;
+ break;
+ case MVT::i64:
+ break;
+ default:
+ llvm_unreachable("Unexpected type");
+ }
+
if (ImmVal < 256) {
- Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(N), MVT::i32);
+ Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(N), MVT::i32);
return true;
}
}
@@ -3201,30 +3201,30 @@ bool AArch64DAGToDAGISel::SelectSVELogicalImm(SDValue N, MVT VT, SDValue &Imm) {
return false;
}
-// SVE shift intrinsics allow shift amounts larger than the element's bitwidth.
-// Rather than attempt to normalise everything we can sometimes saturate the
-// shift amount during selection. This function also allows for consistent
-// isel patterns by ensuring the resulting "Imm" node is of the i32 type
-// required by the instructions.
-bool AArch64DAGToDAGISel::SelectSVEShiftImm(SDValue N, uint64_t Low,
- uint64_t High, bool AllowSaturation,
- SDValue &Imm) {
+// SVE shift intrinsics allow shift amounts larger than the element's bitwidth.
+// Rather than attempt to normalise everything we can sometimes saturate the
+// shift amount during selection. This function also allows for consistent
+// isel patterns by ensuring the resulting "Imm" node is of the i32 type
+// required by the instructions.
+bool AArch64DAGToDAGISel::SelectSVEShiftImm(SDValue N, uint64_t Low,
+ uint64_t High, bool AllowSaturation,
+ SDValue &Imm) {
if (auto *CN = dyn_cast<ConstantSDNode>(N)) {
uint64_t ImmVal = CN->getZExtValue();
- // Reject shift amounts that are too small.
- if (ImmVal < Low)
- return false;
-
- // Reject or saturate shift amounts that are too big.
- if (ImmVal > High) {
- if (!AllowSaturation)
- return false;
- ImmVal = High;
+ // Reject shift amounts that are too small.
+ if (ImmVal < Low)
+ return false;
+
+ // Reject or saturate shift amounts that are too big.
+ if (ImmVal > High) {
+ if (!AllowSaturation)
+ return false;
+ ImmVal = High;
}
-
- Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(N), MVT::i32);
- return true;
+
+ Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(N), MVT::i32);
+ return true;
}
return false;
@@ -3833,9 +3833,9 @@ void AArch64DAGToDAGISel::Select(SDNode *Node) {
return;
}
break;
- case Intrinsic::aarch64_ld64b:
- SelectLoad(Node, 8, AArch64::LD64B, AArch64::x8sub_0);
- return;
+ case Intrinsic::aarch64_ld64b:
+ SelectLoad(Node, 8, AArch64::LD64B, AArch64::x8sub_0);
+ return;
}
} break;
case ISD::INTRINSIC_WO_CHAIN: {
@@ -4854,8 +4854,8 @@ static EVT getPackedVectorTypeFromPredicateType(LLVMContext &Ctx, EVT PredVT,
return EVT();
ElementCount EC = PredVT.getVectorElementCount();
- EVT ScalarVT =
- EVT::getIntegerVT(Ctx, AArch64::SVEBitsPerBlock / EC.getKnownMinValue());
+ EVT ScalarVT =
+ EVT::getIntegerVT(Ctx, AArch64::SVEBitsPerBlock / EC.getKnownMinValue());
EVT MemVT = EVT::getVectorVT(Ctx, ScalarVT, EC * NumVec);
return MemVT;
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64ISelLowering.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64ISelLowering.cpp
index 513c8932b3..c522ee7662 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -112,76 +112,76 @@ EnableOptimizeLogicalImm("aarch64-enable-logical-imm", cl::Hidden,
"optimization"),
cl::init(true));
-// Temporary option added for the purpose of testing functionality added
-// to DAGCombiner.cpp in D92230. It is expected that this can be removed
-// in future when both implementations will be based off MGATHER rather
-// than the GLD1 nodes added for the SVE gather load intrinsics.
-static cl::opt<bool>
-EnableCombineMGatherIntrinsics("aarch64-enable-mgather-combine", cl::Hidden,
- cl::desc("Combine extends of AArch64 masked "
- "gather intrinsics"),
- cl::init(true));
-
+// Temporary option added for the purpose of testing functionality added
+// to DAGCombiner.cpp in D92230. It is expected that this can be removed
+// in future when both implementations will be based off MGATHER rather
+// than the GLD1 nodes added for the SVE gather load intrinsics.
+static cl::opt<bool>
+EnableCombineMGatherIntrinsics("aarch64-enable-mgather-combine", cl::Hidden,
+ cl::desc("Combine extends of AArch64 masked "
+ "gather intrinsics"),
+ cl::init(true));
+
/// Value type used for condition codes.
static const MVT MVT_CC = MVT::i32;
-static inline EVT getPackedSVEVectorVT(EVT VT) {
- switch (VT.getSimpleVT().SimpleTy) {
- default:
- llvm_unreachable("unexpected element type for vector");
- case MVT::i8:
- return MVT::nxv16i8;
- case MVT::i16:
- return MVT::nxv8i16;
- case MVT::i32:
- return MVT::nxv4i32;
- case MVT::i64:
- return MVT::nxv2i64;
- case MVT::f16:
- return MVT::nxv8f16;
- case MVT::f32:
- return MVT::nxv4f32;
- case MVT::f64:
- return MVT::nxv2f64;
- case MVT::bf16:
- return MVT::nxv8bf16;
- }
-}
-
-// NOTE: Currently there's only a need to return integer vector types. If this
-// changes then just add an extra "type" parameter.
-static inline EVT getPackedSVEVectorVT(ElementCount EC) {
- switch (EC.getKnownMinValue()) {
- default:
- llvm_unreachable("unexpected element count for vector");
- case 16:
- return MVT::nxv16i8;
- case 8:
- return MVT::nxv8i16;
- case 4:
- return MVT::nxv4i32;
- case 2:
- return MVT::nxv2i64;
- }
-}
-
-static inline EVT getPromotedVTForPredicate(EVT VT) {
- assert(VT.isScalableVector() && (VT.getVectorElementType() == MVT::i1) &&
- "Expected scalable predicate vector type!");
- switch (VT.getVectorMinNumElements()) {
- default:
- llvm_unreachable("unexpected element count for vector");
- case 2:
- return MVT::nxv2i64;
- case 4:
- return MVT::nxv4i32;
- case 8:
- return MVT::nxv8i16;
- case 16:
- return MVT::nxv16i8;
- }
-}
-
+static inline EVT getPackedSVEVectorVT(EVT VT) {
+ switch (VT.getSimpleVT().SimpleTy) {
+ default:
+ llvm_unreachable("unexpected element type for vector");
+ case MVT::i8:
+ return MVT::nxv16i8;
+ case MVT::i16:
+ return MVT::nxv8i16;
+ case MVT::i32:
+ return MVT::nxv4i32;
+ case MVT::i64:
+ return MVT::nxv2i64;
+ case MVT::f16:
+ return MVT::nxv8f16;
+ case MVT::f32:
+ return MVT::nxv4f32;
+ case MVT::f64:
+ return MVT::nxv2f64;
+ case MVT::bf16:
+ return MVT::nxv8bf16;
+ }
+}
+
+// NOTE: Currently there's only a need to return integer vector types. If this
+// changes then just add an extra "type" parameter.
+static inline EVT getPackedSVEVectorVT(ElementCount EC) {
+ switch (EC.getKnownMinValue()) {
+ default:
+ llvm_unreachable("unexpected element count for vector");
+ case 16:
+ return MVT::nxv16i8;
+ case 8:
+ return MVT::nxv8i16;
+ case 4:
+ return MVT::nxv4i32;
+ case 2:
+ return MVT::nxv2i64;
+ }
+}
+
+static inline EVT getPromotedVTForPredicate(EVT VT) {
+ assert(VT.isScalableVector() && (VT.getVectorElementType() == MVT::i1) &&
+ "Expected scalable predicate vector type!");
+ switch (VT.getVectorMinNumElements()) {
+ default:
+ llvm_unreachable("unexpected element count for vector");
+ case 2:
+ return MVT::nxv2i64;
+ case 4:
+ return MVT::nxv4i32;
+ case 8:
+ return MVT::nxv8i16;
+ case 16:
+ return MVT::nxv16i8;
+ }
+}
+
/// Returns true if VT's elements occupy the lowest bit positions of its
/// associated register class without any intervening space.
///
@@ -194,42 +194,42 @@ static inline bool isPackedVectorType(EVT VT, SelectionDAG &DAG) {
VT.getSizeInBits().getKnownMinSize() == AArch64::SVEBitsPerBlock;
}
-// Returns true for ####_MERGE_PASSTHRU opcodes, whose operands have a leading
-// predicate and end with a passthru value matching the result type.
-static bool isMergePassthruOpcode(unsigned Opc) {
- switch (Opc) {
- default:
- return false;
- case AArch64ISD::BITREVERSE_MERGE_PASSTHRU:
- case AArch64ISD::BSWAP_MERGE_PASSTHRU:
- case AArch64ISD::CTLZ_MERGE_PASSTHRU:
- case AArch64ISD::CTPOP_MERGE_PASSTHRU:
- case AArch64ISD::DUP_MERGE_PASSTHRU:
- case AArch64ISD::ABS_MERGE_PASSTHRU:
- case AArch64ISD::NEG_MERGE_PASSTHRU:
- case AArch64ISD::FNEG_MERGE_PASSTHRU:
- case AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU:
- case AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU:
- case AArch64ISD::FCEIL_MERGE_PASSTHRU:
- case AArch64ISD::FFLOOR_MERGE_PASSTHRU:
- case AArch64ISD::FNEARBYINT_MERGE_PASSTHRU:
- case AArch64ISD::FRINT_MERGE_PASSTHRU:
- case AArch64ISD::FROUND_MERGE_PASSTHRU:
- case AArch64ISD::FROUNDEVEN_MERGE_PASSTHRU:
- case AArch64ISD::FTRUNC_MERGE_PASSTHRU:
- case AArch64ISD::FP_ROUND_MERGE_PASSTHRU:
- case AArch64ISD::FP_EXTEND_MERGE_PASSTHRU:
- case AArch64ISD::SINT_TO_FP_MERGE_PASSTHRU:
- case AArch64ISD::UINT_TO_FP_MERGE_PASSTHRU:
- case AArch64ISD::FCVTZU_MERGE_PASSTHRU:
- case AArch64ISD::FCVTZS_MERGE_PASSTHRU:
- case AArch64ISD::FSQRT_MERGE_PASSTHRU:
- case AArch64ISD::FRECPX_MERGE_PASSTHRU:
- case AArch64ISD::FABS_MERGE_PASSTHRU:
- return true;
- }
-}
-
+// Returns true for ####_MERGE_PASSTHRU opcodes, whose operands have a leading
+// predicate and end with a passthru value matching the result type.
+static bool isMergePassthruOpcode(unsigned Opc) {
+ switch (Opc) {
+ default:
+ return false;
+ case AArch64ISD::BITREVERSE_MERGE_PASSTHRU:
+ case AArch64ISD::BSWAP_MERGE_PASSTHRU:
+ case AArch64ISD::CTLZ_MERGE_PASSTHRU:
+ case AArch64ISD::CTPOP_MERGE_PASSTHRU:
+ case AArch64ISD::DUP_MERGE_PASSTHRU:
+ case AArch64ISD::ABS_MERGE_PASSTHRU:
+ case AArch64ISD::NEG_MERGE_PASSTHRU:
+ case AArch64ISD::FNEG_MERGE_PASSTHRU:
+ case AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU:
+ case AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU:
+ case AArch64ISD::FCEIL_MERGE_PASSTHRU:
+ case AArch64ISD::FFLOOR_MERGE_PASSTHRU:
+ case AArch64ISD::FNEARBYINT_MERGE_PASSTHRU:
+ case AArch64ISD::FRINT_MERGE_PASSTHRU:
+ case AArch64ISD::FROUND_MERGE_PASSTHRU:
+ case AArch64ISD::FROUNDEVEN_MERGE_PASSTHRU:
+ case AArch64ISD::FTRUNC_MERGE_PASSTHRU:
+ case AArch64ISD::FP_ROUND_MERGE_PASSTHRU:
+ case AArch64ISD::FP_EXTEND_MERGE_PASSTHRU:
+ case AArch64ISD::SINT_TO_FP_MERGE_PASSTHRU:
+ case AArch64ISD::UINT_TO_FP_MERGE_PASSTHRU:
+ case AArch64ISD::FCVTZU_MERGE_PASSTHRU:
+ case AArch64ISD::FCVTZS_MERGE_PASSTHRU:
+ case AArch64ISD::FSQRT_MERGE_PASSTHRU:
+ case AArch64ISD::FRECPX_MERGE_PASSTHRU:
+ case AArch64ISD::FABS_MERGE_PASSTHRU:
+ return true;
+ }
+}
+
AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
const AArch64Subtarget &STI)
: TargetLowering(TM), Subtarget(&STI) {
@@ -263,8 +263,8 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
addDRTypeForNEON(MVT::v1i64);
addDRTypeForNEON(MVT::v1f64);
addDRTypeForNEON(MVT::v4f16);
- if (Subtarget->hasBF16())
- addDRTypeForNEON(MVT::v4bf16);
+ if (Subtarget->hasBF16())
+ addDRTypeForNEON(MVT::v4bf16);
addQRTypeForNEON(MVT::v4f32);
addQRTypeForNEON(MVT::v2f64);
@@ -273,8 +273,8 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
addQRTypeForNEON(MVT::v4i32);
addQRTypeForNEON(MVT::v2i64);
addQRTypeForNEON(MVT::v8f16);
- if (Subtarget->hasBF16())
- addQRTypeForNEON(MVT::v8bf16);
+ if (Subtarget->hasBF16())
+ addQRTypeForNEON(MVT::v8bf16);
}
if (Subtarget->hasSVE()) {
@@ -303,7 +303,7 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
addRegisterClass(MVT::nxv8bf16, &AArch64::ZPRRegClass);
}
- if (Subtarget->useSVEForFixedLengthVectors()) {
+ if (Subtarget->useSVEForFixedLengthVectors()) {
for (MVT VT : MVT::integer_fixedlen_vector_valuetypes())
if (useSVEForFixedLengthVectorVT(VT))
addRegisterClass(VT, &AArch64::ZPRRegClass);
@@ -334,9 +334,9 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
MVT::nxv2f64 }) {
setCondCodeAction(ISD::SETO, VT, Expand);
setCondCodeAction(ISD::SETOLT, VT, Expand);
- setCondCodeAction(ISD::SETLT, VT, Expand);
+ setCondCodeAction(ISD::SETLT, VT, Expand);
setCondCodeAction(ISD::SETOLE, VT, Expand);
- setCondCodeAction(ISD::SETLE, VT, Expand);
+ setCondCodeAction(ISD::SETLE, VT, Expand);
setCondCodeAction(ISD::SETULT, VT, Expand);
setCondCodeAction(ISD::SETULE, VT, Expand);
setCondCodeAction(ISD::SETUGE, VT, Expand);
@@ -402,12 +402,12 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
// Virtually no operation on f128 is legal, but LLVM can't expand them when
// there's a valid register class, so we need custom operations in most cases.
setOperationAction(ISD::FABS, MVT::f128, Expand);
- setOperationAction(ISD::FADD, MVT::f128, LibCall);
+ setOperationAction(ISD::FADD, MVT::f128, LibCall);
setOperationAction(ISD::FCOPYSIGN, MVT::f128, Expand);
setOperationAction(ISD::FCOS, MVT::f128, Expand);
- setOperationAction(ISD::FDIV, MVT::f128, LibCall);
+ setOperationAction(ISD::FDIV, MVT::f128, LibCall);
setOperationAction(ISD::FMA, MVT::f128, Expand);
- setOperationAction(ISD::FMUL, MVT::f128, LibCall);
+ setOperationAction(ISD::FMUL, MVT::f128, LibCall);
setOperationAction(ISD::FNEG, MVT::f128, Expand);
setOperationAction(ISD::FPOW, MVT::f128, Expand);
setOperationAction(ISD::FREM, MVT::f128, Expand);
@@ -415,7 +415,7 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
setOperationAction(ISD::FSIN, MVT::f128, Expand);
setOperationAction(ISD::FSINCOS, MVT::f128, Expand);
setOperationAction(ISD::FSQRT, MVT::f128, Expand);
- setOperationAction(ISD::FSUB, MVT::f128, LibCall);
+ setOperationAction(ISD::FSUB, MVT::f128, LibCall);
setOperationAction(ISD::FTRUNC, MVT::f128, Expand);
setOperationAction(ISD::SETCC, MVT::f128, Custom);
setOperationAction(ISD::STRICT_FSETCC, MVT::f128, Custom);
@@ -451,10 +451,10 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i32, Custom);
setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i64, Custom);
setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i128, Custom);
- setOperationAction(ISD::FP_ROUND, MVT::f16, Custom);
+ setOperationAction(ISD::FP_ROUND, MVT::f16, Custom);
setOperationAction(ISD::FP_ROUND, MVT::f32, Custom);
setOperationAction(ISD::FP_ROUND, MVT::f64, Custom);
- setOperationAction(ISD::STRICT_FP_ROUND, MVT::f16, Custom);
+ setOperationAction(ISD::STRICT_FP_ROUND, MVT::f16, Custom);
setOperationAction(ISD::STRICT_FP_ROUND, MVT::f32, Custom);
setOperationAction(ISD::STRICT_FP_ROUND, MVT::f64, Custom);
@@ -509,9 +509,9 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
setOperationAction(ISD::CTPOP, MVT::i64, Custom);
setOperationAction(ISD::CTPOP, MVT::i128, Custom);
- setOperationAction(ISD::ABS, MVT::i32, Custom);
- setOperationAction(ISD::ABS, MVT::i64, Custom);
-
+ setOperationAction(ISD::ABS, MVT::i32, Custom);
+ setOperationAction(ISD::ABS, MVT::i64, Custom);
+
setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
setOperationAction(ISD::SDIVREM, MVT::i64, Expand);
for (MVT VT : MVT::fixedlen_vector_valuetypes()) {
@@ -699,57 +699,57 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
setOperationAction(ISD::ATOMIC_LOAD_AND, MVT::i32, Custom);
setOperationAction(ISD::ATOMIC_LOAD_AND, MVT::i64, Custom);
- // Generate outline atomics library calls only if LSE was not specified for
- // subtarget
- if (Subtarget->outlineAtomics() && !Subtarget->hasLSE()) {
- setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i8, LibCall);
- setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i16, LibCall);
- setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, LibCall);
- setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i64, LibCall);
- setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i128, LibCall);
- setOperationAction(ISD::ATOMIC_SWAP, MVT::i8, LibCall);
- setOperationAction(ISD::ATOMIC_SWAP, MVT::i16, LibCall);
- setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, LibCall);
- setOperationAction(ISD::ATOMIC_SWAP, MVT::i64, LibCall);
- setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i8, LibCall);
- setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i16, LibCall);
- setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i32, LibCall);
- setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i64, LibCall);
- setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i8, LibCall);
- setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i16, LibCall);
- setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i32, LibCall);
- setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i64, LibCall);
- setOperationAction(ISD::ATOMIC_LOAD_CLR, MVT::i8, LibCall);
- setOperationAction(ISD::ATOMIC_LOAD_CLR, MVT::i16, LibCall);
- setOperationAction(ISD::ATOMIC_LOAD_CLR, MVT::i32, LibCall);
- setOperationAction(ISD::ATOMIC_LOAD_CLR, MVT::i64, LibCall);
- setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i8, LibCall);
- setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i16, LibCall);
- setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i32, LibCall);
- setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i64, LibCall);
-#define LCALLNAMES(A, B, N) \
- setLibcallName(A##N##_RELAX, #B #N "_relax"); \
- setLibcallName(A##N##_ACQ, #B #N "_acq"); \
- setLibcallName(A##N##_REL, #B #N "_rel"); \
- setLibcallName(A##N##_ACQ_REL, #B #N "_acq_rel");
-#define LCALLNAME4(A, B) \
- LCALLNAMES(A, B, 1) \
- LCALLNAMES(A, B, 2) LCALLNAMES(A, B, 4) LCALLNAMES(A, B, 8)
-#define LCALLNAME5(A, B) \
- LCALLNAMES(A, B, 1) \
- LCALLNAMES(A, B, 2) \
- LCALLNAMES(A, B, 4) LCALLNAMES(A, B, 8) LCALLNAMES(A, B, 16)
- LCALLNAME5(RTLIB::OUTLINE_ATOMIC_CAS, __aarch64_cas)
- LCALLNAME4(RTLIB::OUTLINE_ATOMIC_SWP, __aarch64_swp)
- LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDADD, __aarch64_ldadd)
- LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDSET, __aarch64_ldset)
- LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDCLR, __aarch64_ldclr)
- LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDEOR, __aarch64_ldeor)
-#undef LCALLNAMES
-#undef LCALLNAME4
-#undef LCALLNAME5
- }
-
+ // Generate outline atomics library calls only if LSE was not specified for
+ // subtarget
+ if (Subtarget->outlineAtomics() && !Subtarget->hasLSE()) {
+ setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i8, LibCall);
+ setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i16, LibCall);
+ setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, LibCall);
+ setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i64, LibCall);
+ setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i128, LibCall);
+ setOperationAction(ISD::ATOMIC_SWAP, MVT::i8, LibCall);
+ setOperationAction(ISD::ATOMIC_SWAP, MVT::i16, LibCall);
+ setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, LibCall);
+ setOperationAction(ISD::ATOMIC_SWAP, MVT::i64, LibCall);
+ setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i8, LibCall);
+ setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i16, LibCall);
+ setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i32, LibCall);
+ setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i64, LibCall);
+ setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i8, LibCall);
+ setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i16, LibCall);
+ setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i32, LibCall);
+ setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i64, LibCall);
+ setOperationAction(ISD::ATOMIC_LOAD_CLR, MVT::i8, LibCall);
+ setOperationAction(ISD::ATOMIC_LOAD_CLR, MVT::i16, LibCall);
+ setOperationAction(ISD::ATOMIC_LOAD_CLR, MVT::i32, LibCall);
+ setOperationAction(ISD::ATOMIC_LOAD_CLR, MVT::i64, LibCall);
+ setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i8, LibCall);
+ setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i16, LibCall);
+ setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i32, LibCall);
+ setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i64, LibCall);
+#define LCALLNAMES(A, B, N) \
+ setLibcallName(A##N##_RELAX, #B #N "_relax"); \
+ setLibcallName(A##N##_ACQ, #B #N "_acq"); \
+ setLibcallName(A##N##_REL, #B #N "_rel"); \
+ setLibcallName(A##N##_ACQ_REL, #B #N "_acq_rel");
+#define LCALLNAME4(A, B) \
+ LCALLNAMES(A, B, 1) \
+ LCALLNAMES(A, B, 2) LCALLNAMES(A, B, 4) LCALLNAMES(A, B, 8)
+#define LCALLNAME5(A, B) \
+ LCALLNAMES(A, B, 1) \
+ LCALLNAMES(A, B, 2) \
+ LCALLNAMES(A, B, 4) LCALLNAMES(A, B, 8) LCALLNAMES(A, B, 16)
+ LCALLNAME5(RTLIB::OUTLINE_ATOMIC_CAS, __aarch64_cas)
+ LCALLNAME4(RTLIB::OUTLINE_ATOMIC_SWP, __aarch64_swp)
+ LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDADD, __aarch64_ldadd)
+ LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDSET, __aarch64_ldset)
+ LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDCLR, __aarch64_ldclr)
+ LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDEOR, __aarch64_ldeor)
+#undef LCALLNAMES
+#undef LCALLNAME4
+#undef LCALLNAME5
+ }
+
// 128-bit loads and stores can be done without expanding
setOperationAction(ISD::LOAD, MVT::i128, Custom);
setOperationAction(ISD::STORE, MVT::i128, Custom);
@@ -839,8 +839,8 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
// Trap.
setOperationAction(ISD::TRAP, MVT::Other, Legal);
- setOperationAction(ISD::DEBUGTRAP, MVT::Other, Legal);
- setOperationAction(ISD::UBSANTRAP, MVT::Other, Legal);
+ setOperationAction(ISD::DEBUGTRAP, MVT::Other, Legal);
+ setOperationAction(ISD::UBSANTRAP, MVT::Other, Legal);
// We combine OR nodes for bitfield operations.
setTargetDAGCombine(ISD::OR);
@@ -850,7 +850,7 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
// Vector add and sub nodes may conceal a high-half opportunity.
// Also, try to fold ADD into CSINC/CSINV..
setTargetDAGCombine(ISD::ADD);
- setTargetDAGCombine(ISD::ABS);
+ setTargetDAGCombine(ISD::ABS);
setTargetDAGCombine(ISD::SUB);
setTargetDAGCombine(ISD::SRL);
setTargetDAGCombine(ISD::XOR);
@@ -867,15 +867,15 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
setTargetDAGCombine(ISD::ZERO_EXTEND);
setTargetDAGCombine(ISD::SIGN_EXTEND);
setTargetDAGCombine(ISD::SIGN_EXTEND_INREG);
- setTargetDAGCombine(ISD::TRUNCATE);
+ setTargetDAGCombine(ISD::TRUNCATE);
setTargetDAGCombine(ISD::CONCAT_VECTORS);
setTargetDAGCombine(ISD::STORE);
if (Subtarget->supportsAddressTopByteIgnored())
setTargetDAGCombine(ISD::LOAD);
- setTargetDAGCombine(ISD::MGATHER);
- setTargetDAGCombine(ISD::MSCATTER);
-
+ setTargetDAGCombine(ISD::MGATHER);
+ setTargetDAGCombine(ISD::MSCATTER);
+
setTargetDAGCombine(ISD::MUL);
setTargetDAGCombine(ISD::SELECT);
@@ -884,8 +884,8 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
setTargetDAGCombine(ISD::INTRINSIC_VOID);
setTargetDAGCombine(ISD::INTRINSIC_W_CHAIN);
setTargetDAGCombine(ISD::INSERT_VECTOR_ELT);
- setTargetDAGCombine(ISD::EXTRACT_VECTOR_ELT);
- setTargetDAGCombine(ISD::VECREDUCE_ADD);
+ setTargetDAGCombine(ISD::EXTRACT_VECTOR_ELT);
+ setTargetDAGCombine(ISD::VECREDUCE_ADD);
setTargetDAGCombine(ISD::GlobalAddress);
@@ -1005,34 +1005,34 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
setOperationAction(ISD::MUL, MVT::v4i32, Custom);
setOperationAction(ISD::MUL, MVT::v2i64, Custom);
- // Saturates
+ // Saturates
for (MVT VT : { MVT::v8i8, MVT::v4i16, MVT::v2i32,
MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64 }) {
setOperationAction(ISD::SADDSAT, VT, Legal);
setOperationAction(ISD::UADDSAT, VT, Legal);
setOperationAction(ISD::SSUBSAT, VT, Legal);
setOperationAction(ISD::USUBSAT, VT, Legal);
- }
+ }
- // Vector reductions
+ // Vector reductions
for (MVT VT : { MVT::v4f16, MVT::v2f32,
MVT::v8f16, MVT::v4f32, MVT::v2f64 }) {
- if (VT.getVectorElementType() != MVT::f16 || Subtarget->hasFullFP16()) {
- setOperationAction(ISD::VECREDUCE_FMAX, VT, Custom);
- setOperationAction(ISD::VECREDUCE_FMIN, VT, Custom);
-
- setOperationAction(ISD::VECREDUCE_FADD, VT, Legal);
- }
+ if (VT.getVectorElementType() != MVT::f16 || Subtarget->hasFullFP16()) {
+ setOperationAction(ISD::VECREDUCE_FMAX, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_FMIN, VT, Custom);
+
+ setOperationAction(ISD::VECREDUCE_FADD, VT, Legal);
+ }
+ }
+ for (MVT VT : { MVT::v8i8, MVT::v4i16, MVT::v2i32,
+ MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
+ setOperationAction(ISD::VECREDUCE_ADD, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_SMAX, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_SMIN, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_UMAX, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_UMIN, VT, Custom);
}
- for (MVT VT : { MVT::v8i8, MVT::v4i16, MVT::v2i32,
- MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
- setOperationAction(ISD::VECREDUCE_ADD, VT, Custom);
- setOperationAction(ISD::VECREDUCE_SMAX, VT, Custom);
- setOperationAction(ISD::VECREDUCE_SMIN, VT, Custom);
- setOperationAction(ISD::VECREDUCE_UMAX, VT, Custom);
- setOperationAction(ISD::VECREDUCE_UMIN, VT, Custom);
- }
- setOperationAction(ISD::VECREDUCE_ADD, MVT::v2i64, Custom);
+ setOperationAction(ISD::VECREDUCE_ADD, MVT::v2i64, Custom);
setOperationAction(ISD::ANY_EXTEND, MVT::v4i32, Legal);
setTruncStoreAction(MVT::v2i32, MVT::v2i16, Expand);
@@ -1093,112 +1093,112 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
// FIXME: Add custom lowering of MLOAD to handle different passthrus (not a
// splat of 0 or undef) once vector selects supported in SVE codegen. See
// D68877 for more details.
- for (auto VT : {MVT::nxv16i8, MVT::nxv8i16, MVT::nxv4i32, MVT::nxv2i64}) {
- setOperationAction(ISD::BITREVERSE, VT, Custom);
- setOperationAction(ISD::BSWAP, VT, Custom);
- setOperationAction(ISD::CTLZ, VT, Custom);
- setOperationAction(ISD::CTPOP, VT, Custom);
- setOperationAction(ISD::CTTZ, VT, Custom);
- setOperationAction(ISD::INSERT_SUBVECTOR, VT, Custom);
- setOperationAction(ISD::UINT_TO_FP, VT, Custom);
- setOperationAction(ISD::SINT_TO_FP, VT, Custom);
- setOperationAction(ISD::FP_TO_UINT, VT, Custom);
- setOperationAction(ISD::FP_TO_SINT, VT, Custom);
- setOperationAction(ISD::MGATHER, VT, Custom);
- setOperationAction(ISD::MSCATTER, VT, Custom);
- setOperationAction(ISD::MUL, VT, Custom);
- setOperationAction(ISD::SPLAT_VECTOR, VT, Custom);
- setOperationAction(ISD::SELECT, VT, Custom);
- setOperationAction(ISD::SDIV, VT, Custom);
- setOperationAction(ISD::UDIV, VT, Custom);
- setOperationAction(ISD::SMIN, VT, Custom);
- setOperationAction(ISD::UMIN, VT, Custom);
- setOperationAction(ISD::SMAX, VT, Custom);
- setOperationAction(ISD::UMAX, VT, Custom);
- setOperationAction(ISD::SHL, VT, Custom);
- setOperationAction(ISD::SRL, VT, Custom);
- setOperationAction(ISD::SRA, VT, Custom);
- setOperationAction(ISD::ABS, VT, Custom);
- setOperationAction(ISD::VECREDUCE_ADD, VT, Custom);
- setOperationAction(ISD::VECREDUCE_AND, VT, Custom);
- setOperationAction(ISD::VECREDUCE_OR, VT, Custom);
- setOperationAction(ISD::VECREDUCE_XOR, VT, Custom);
- setOperationAction(ISD::VECREDUCE_UMIN, VT, Custom);
- setOperationAction(ISD::VECREDUCE_UMAX, VT, Custom);
- setOperationAction(ISD::VECREDUCE_SMIN, VT, Custom);
- setOperationAction(ISD::VECREDUCE_SMAX, VT, Custom);
+ for (auto VT : {MVT::nxv16i8, MVT::nxv8i16, MVT::nxv4i32, MVT::nxv2i64}) {
+ setOperationAction(ISD::BITREVERSE, VT, Custom);
+ setOperationAction(ISD::BSWAP, VT, Custom);
+ setOperationAction(ISD::CTLZ, VT, Custom);
+ setOperationAction(ISD::CTPOP, VT, Custom);
+ setOperationAction(ISD::CTTZ, VT, Custom);
+ setOperationAction(ISD::INSERT_SUBVECTOR, VT, Custom);
+ setOperationAction(ISD::UINT_TO_FP, VT, Custom);
+ setOperationAction(ISD::SINT_TO_FP, VT, Custom);
+ setOperationAction(ISD::FP_TO_UINT, VT, Custom);
+ setOperationAction(ISD::FP_TO_SINT, VT, Custom);
+ setOperationAction(ISD::MGATHER, VT, Custom);
+ setOperationAction(ISD::MSCATTER, VT, Custom);
+ setOperationAction(ISD::MUL, VT, Custom);
+ setOperationAction(ISD::SPLAT_VECTOR, VT, Custom);
+ setOperationAction(ISD::SELECT, VT, Custom);
+ setOperationAction(ISD::SDIV, VT, Custom);
+ setOperationAction(ISD::UDIV, VT, Custom);
+ setOperationAction(ISD::SMIN, VT, Custom);
+ setOperationAction(ISD::UMIN, VT, Custom);
+ setOperationAction(ISD::SMAX, VT, Custom);
+ setOperationAction(ISD::UMAX, VT, Custom);
+ setOperationAction(ISD::SHL, VT, Custom);
+ setOperationAction(ISD::SRL, VT, Custom);
+ setOperationAction(ISD::SRA, VT, Custom);
+ setOperationAction(ISD::ABS, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_ADD, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_AND, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_OR, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_XOR, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_UMIN, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_UMAX, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_SMIN, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_SMAX, VT, Custom);
}
- // Illegal unpacked integer vector types.
- for (auto VT : {MVT::nxv8i8, MVT::nxv4i16, MVT::nxv2i32}) {
+ // Illegal unpacked integer vector types.
+ for (auto VT : {MVT::nxv8i8, MVT::nxv4i16, MVT::nxv2i32}) {
setOperationAction(ISD::EXTRACT_SUBVECTOR, VT, Custom);
- setOperationAction(ISD::INSERT_SUBVECTOR, VT, Custom);
- }
-
- for (auto VT : {MVT::nxv16i1, MVT::nxv8i1, MVT::nxv4i1, MVT::nxv2i1}) {
- setOperationAction(ISD::CONCAT_VECTORS, VT, Custom);
- setOperationAction(ISD::SELECT, VT, Custom);
- setOperationAction(ISD::SETCC, VT, Custom);
- setOperationAction(ISD::SPLAT_VECTOR, VT, Custom);
- setOperationAction(ISD::TRUNCATE, VT, Custom);
- setOperationAction(ISD::VECREDUCE_AND, VT, Custom);
- setOperationAction(ISD::VECREDUCE_OR, VT, Custom);
- setOperationAction(ISD::VECREDUCE_XOR, VT, Custom);
-
- // There are no legal MVT::nxv16f## based types.
- if (VT != MVT::nxv16i1) {
- setOperationAction(ISD::SINT_TO_FP, VT, Custom);
- setOperationAction(ISD::UINT_TO_FP, VT, Custom);
+ setOperationAction(ISD::INSERT_SUBVECTOR, VT, Custom);
+ }
+
+ for (auto VT : {MVT::nxv16i1, MVT::nxv8i1, MVT::nxv4i1, MVT::nxv2i1}) {
+ setOperationAction(ISD::CONCAT_VECTORS, VT, Custom);
+ setOperationAction(ISD::SELECT, VT, Custom);
+ setOperationAction(ISD::SETCC, VT, Custom);
+ setOperationAction(ISD::SPLAT_VECTOR, VT, Custom);
+ setOperationAction(ISD::TRUNCATE, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_AND, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_OR, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_XOR, VT, Custom);
+
+ // There are no legal MVT::nxv16f## based types.
+ if (VT != MVT::nxv16i1) {
+ setOperationAction(ISD::SINT_TO_FP, VT, Custom);
+ setOperationAction(ISD::UINT_TO_FP, VT, Custom);
}
}
- for (auto VT : {MVT::nxv2f16, MVT::nxv4f16, MVT::nxv8f16, MVT::nxv2f32,
- MVT::nxv4f32, MVT::nxv2f64}) {
- setOperationAction(ISD::CONCAT_VECTORS, VT, Custom);
- setOperationAction(ISD::INSERT_SUBVECTOR, VT, Custom);
- setOperationAction(ISD::MGATHER, VT, Custom);
- setOperationAction(ISD::MSCATTER, VT, Custom);
- setOperationAction(ISD::SPLAT_VECTOR, VT, Custom);
- setOperationAction(ISD::SELECT, VT, Custom);
- setOperationAction(ISD::FADD, VT, Custom);
- setOperationAction(ISD::FDIV, VT, Custom);
- setOperationAction(ISD::FMA, VT, Custom);
- setOperationAction(ISD::FMAXNUM, VT, Custom);
- setOperationAction(ISD::FMINNUM, VT, Custom);
- setOperationAction(ISD::FMUL, VT, Custom);
- setOperationAction(ISD::FNEG, VT, Custom);
- setOperationAction(ISD::FSUB, VT, Custom);
- setOperationAction(ISD::FCEIL, VT, Custom);
- setOperationAction(ISD::FFLOOR, VT, Custom);
- setOperationAction(ISD::FNEARBYINT, VT, Custom);
- setOperationAction(ISD::FRINT, VT, Custom);
- setOperationAction(ISD::FROUND, VT, Custom);
- setOperationAction(ISD::FROUNDEVEN, VT, Custom);
- setOperationAction(ISD::FTRUNC, VT, Custom);
- setOperationAction(ISD::FSQRT, VT, Custom);
- setOperationAction(ISD::FABS, VT, Custom);
- setOperationAction(ISD::FP_EXTEND, VT, Custom);
- setOperationAction(ISD::FP_ROUND, VT, Custom);
- setOperationAction(ISD::VECREDUCE_FADD, VT, Custom);
- setOperationAction(ISD::VECREDUCE_FMAX, VT, Custom);
- setOperationAction(ISD::VECREDUCE_FMIN, VT, Custom);
- setOperationAction(ISD::VECREDUCE_SEQ_FADD, VT, Custom);
- }
-
- for (auto VT : {MVT::nxv2bf16, MVT::nxv4bf16, MVT::nxv8bf16}) {
- setOperationAction(ISD::CONCAT_VECTORS, VT, Custom);
- setOperationAction(ISD::MGATHER, VT, Custom);
- setOperationAction(ISD::MSCATTER, VT, Custom);
- }
-
- setOperationAction(ISD::SPLAT_VECTOR, MVT::nxv8bf16, Custom);
-
- setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i8, Custom);
- setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i16, Custom);
-
+ for (auto VT : {MVT::nxv2f16, MVT::nxv4f16, MVT::nxv8f16, MVT::nxv2f32,
+ MVT::nxv4f32, MVT::nxv2f64}) {
+ setOperationAction(ISD::CONCAT_VECTORS, VT, Custom);
+ setOperationAction(ISD::INSERT_SUBVECTOR, VT, Custom);
+ setOperationAction(ISD::MGATHER, VT, Custom);
+ setOperationAction(ISD::MSCATTER, VT, Custom);
+ setOperationAction(ISD::SPLAT_VECTOR, VT, Custom);
+ setOperationAction(ISD::SELECT, VT, Custom);
+ setOperationAction(ISD::FADD, VT, Custom);
+ setOperationAction(ISD::FDIV, VT, Custom);
+ setOperationAction(ISD::FMA, VT, Custom);
+ setOperationAction(ISD::FMAXNUM, VT, Custom);
+ setOperationAction(ISD::FMINNUM, VT, Custom);
+ setOperationAction(ISD::FMUL, VT, Custom);
+ setOperationAction(ISD::FNEG, VT, Custom);
+ setOperationAction(ISD::FSUB, VT, Custom);
+ setOperationAction(ISD::FCEIL, VT, Custom);
+ setOperationAction(ISD::FFLOOR, VT, Custom);
+ setOperationAction(ISD::FNEARBYINT, VT, Custom);
+ setOperationAction(ISD::FRINT, VT, Custom);
+ setOperationAction(ISD::FROUND, VT, Custom);
+ setOperationAction(ISD::FROUNDEVEN, VT, Custom);
+ setOperationAction(ISD::FTRUNC, VT, Custom);
+ setOperationAction(ISD::FSQRT, VT, Custom);
+ setOperationAction(ISD::FABS, VT, Custom);
+ setOperationAction(ISD::FP_EXTEND, VT, Custom);
+ setOperationAction(ISD::FP_ROUND, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_FADD, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_FMAX, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_FMIN, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_SEQ_FADD, VT, Custom);
+ }
+
+ for (auto VT : {MVT::nxv2bf16, MVT::nxv4bf16, MVT::nxv8bf16}) {
+ setOperationAction(ISD::CONCAT_VECTORS, VT, Custom);
+ setOperationAction(ISD::MGATHER, VT, Custom);
+ setOperationAction(ISD::MSCATTER, VT, Custom);
+ }
+
+ setOperationAction(ISD::SPLAT_VECTOR, MVT::nxv8bf16, Custom);
+
+ setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i8, Custom);
+ setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i16, Custom);
+
// NOTE: Currently this has to happen after computeRegisterProperties rather
// than the preferred option of combining it with the addRegisterClass call.
- if (Subtarget->useSVEForFixedLengthVectors()) {
+ if (Subtarget->useSVEForFixedLengthVectors()) {
for (MVT VT : MVT::integer_fixedlen_vector_valuetypes())
if (useSVEForFixedLengthVectorVT(VT))
addTypeForFixedLengthSVE(VT);
@@ -1216,61 +1216,61 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
setOperationAction(ISD::TRUNCATE, VT, Custom);
for (auto VT : {MVT::v8f16, MVT::v4f32})
setOperationAction(ISD::FP_ROUND, VT, Expand);
-
- // These operations are not supported on NEON but SVE can do them.
- setOperationAction(ISD::BITREVERSE, MVT::v1i64, Custom);
- setOperationAction(ISD::CTLZ, MVT::v1i64, Custom);
- setOperationAction(ISD::CTLZ, MVT::v2i64, Custom);
- setOperationAction(ISD::CTTZ, MVT::v1i64, Custom);
- setOperationAction(ISD::MUL, MVT::v1i64, Custom);
- setOperationAction(ISD::MUL, MVT::v2i64, Custom);
- setOperationAction(ISD::SDIV, MVT::v8i8, Custom);
- setOperationAction(ISD::SDIV, MVT::v16i8, Custom);
- setOperationAction(ISD::SDIV, MVT::v4i16, Custom);
- setOperationAction(ISD::SDIV, MVT::v8i16, Custom);
- setOperationAction(ISD::SDIV, MVT::v2i32, Custom);
- setOperationAction(ISD::SDIV, MVT::v4i32, Custom);
- setOperationAction(ISD::SDIV, MVT::v1i64, Custom);
- setOperationAction(ISD::SDIV, MVT::v2i64, Custom);
- setOperationAction(ISD::SMAX, MVT::v1i64, Custom);
- setOperationAction(ISD::SMAX, MVT::v2i64, Custom);
- setOperationAction(ISD::SMIN, MVT::v1i64, Custom);
- setOperationAction(ISD::SMIN, MVT::v2i64, Custom);
- setOperationAction(ISD::UDIV, MVT::v8i8, Custom);
- setOperationAction(ISD::UDIV, MVT::v16i8, Custom);
- setOperationAction(ISD::UDIV, MVT::v4i16, Custom);
- setOperationAction(ISD::UDIV, MVT::v8i16, Custom);
- setOperationAction(ISD::UDIV, MVT::v2i32, Custom);
- setOperationAction(ISD::UDIV, MVT::v4i32, Custom);
- setOperationAction(ISD::UDIV, MVT::v1i64, Custom);
- setOperationAction(ISD::UDIV, MVT::v2i64, Custom);
- setOperationAction(ISD::UMAX, MVT::v1i64, Custom);
- setOperationAction(ISD::UMAX, MVT::v2i64, Custom);
- setOperationAction(ISD::UMIN, MVT::v1i64, Custom);
- setOperationAction(ISD::UMIN, MVT::v2i64, Custom);
- setOperationAction(ISD::VECREDUCE_SMAX, MVT::v2i64, Custom);
- setOperationAction(ISD::VECREDUCE_SMIN, MVT::v2i64, Custom);
- setOperationAction(ISD::VECREDUCE_UMAX, MVT::v2i64, Custom);
- setOperationAction(ISD::VECREDUCE_UMIN, MVT::v2i64, Custom);
-
- // Int operations with no NEON support.
- for (auto VT : {MVT::v8i8, MVT::v16i8, MVT::v4i16, MVT::v8i16,
- MVT::v2i32, MVT::v4i32, MVT::v2i64}) {
- setOperationAction(ISD::BITREVERSE, VT, Custom);
- setOperationAction(ISD::CTTZ, VT, Custom);
- setOperationAction(ISD::VECREDUCE_AND, VT, Custom);
- setOperationAction(ISD::VECREDUCE_OR, VT, Custom);
- setOperationAction(ISD::VECREDUCE_XOR, VT, Custom);
- }
-
- // FP operations with no NEON support.
- for (auto VT : {MVT::v4f16, MVT::v8f16, MVT::v2f32, MVT::v4f32,
- MVT::v1f64, MVT::v2f64})
- setOperationAction(ISD::VECREDUCE_SEQ_FADD, VT, Custom);
-
- // Use SVE for vectors with more than 2 elements.
- for (auto VT : {MVT::v4f16, MVT::v8f16, MVT::v4f32})
- setOperationAction(ISD::VECREDUCE_FADD, VT, Custom);
+
+ // These operations are not supported on NEON but SVE can do them.
+ setOperationAction(ISD::BITREVERSE, MVT::v1i64, Custom);
+ setOperationAction(ISD::CTLZ, MVT::v1i64, Custom);
+ setOperationAction(ISD::CTLZ, MVT::v2i64, Custom);
+ setOperationAction(ISD::CTTZ, MVT::v1i64, Custom);
+ setOperationAction(ISD::MUL, MVT::v1i64, Custom);
+ setOperationAction(ISD::MUL, MVT::v2i64, Custom);
+ setOperationAction(ISD::SDIV, MVT::v8i8, Custom);
+ setOperationAction(ISD::SDIV, MVT::v16i8, Custom);
+ setOperationAction(ISD::SDIV, MVT::v4i16, Custom);
+ setOperationAction(ISD::SDIV, MVT::v8i16, Custom);
+ setOperationAction(ISD::SDIV, MVT::v2i32, Custom);
+ setOperationAction(ISD::SDIV, MVT::v4i32, Custom);
+ setOperationAction(ISD::SDIV, MVT::v1i64, Custom);
+ setOperationAction(ISD::SDIV, MVT::v2i64, Custom);
+ setOperationAction(ISD::SMAX, MVT::v1i64, Custom);
+ setOperationAction(ISD::SMAX, MVT::v2i64, Custom);
+ setOperationAction(ISD::SMIN, MVT::v1i64, Custom);
+ setOperationAction(ISD::SMIN, MVT::v2i64, Custom);
+ setOperationAction(ISD::UDIV, MVT::v8i8, Custom);
+ setOperationAction(ISD::UDIV, MVT::v16i8, Custom);
+ setOperationAction(ISD::UDIV, MVT::v4i16, Custom);
+ setOperationAction(ISD::UDIV, MVT::v8i16, Custom);
+ setOperationAction(ISD::UDIV, MVT::v2i32, Custom);
+ setOperationAction(ISD::UDIV, MVT::v4i32, Custom);
+ setOperationAction(ISD::UDIV, MVT::v1i64, Custom);
+ setOperationAction(ISD::UDIV, MVT::v2i64, Custom);
+ setOperationAction(ISD::UMAX, MVT::v1i64, Custom);
+ setOperationAction(ISD::UMAX, MVT::v2i64, Custom);
+ setOperationAction(ISD::UMIN, MVT::v1i64, Custom);
+ setOperationAction(ISD::UMIN, MVT::v2i64, Custom);
+ setOperationAction(ISD::VECREDUCE_SMAX, MVT::v2i64, Custom);
+ setOperationAction(ISD::VECREDUCE_SMIN, MVT::v2i64, Custom);
+ setOperationAction(ISD::VECREDUCE_UMAX, MVT::v2i64, Custom);
+ setOperationAction(ISD::VECREDUCE_UMIN, MVT::v2i64, Custom);
+
+ // Int operations with no NEON support.
+ for (auto VT : {MVT::v8i8, MVT::v16i8, MVT::v4i16, MVT::v8i16,
+ MVT::v2i32, MVT::v4i32, MVT::v2i64}) {
+ setOperationAction(ISD::BITREVERSE, VT, Custom);
+ setOperationAction(ISD::CTTZ, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_AND, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_OR, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_XOR, VT, Custom);
+ }
+
+ // FP operations with no NEON support.
+ for (auto VT : {MVT::v4f16, MVT::v8f16, MVT::v2f32, MVT::v4f32,
+ MVT::v1f64, MVT::v2f64})
+ setOperationAction(ISD::VECREDUCE_SEQ_FADD, VT, Custom);
+
+ // Use SVE for vectors with more than 2 elements.
+ for (auto VT : {MVT::v4f16, MVT::v8f16, MVT::v4f32})
+ setOperationAction(ISD::VECREDUCE_FADD, VT, Custom);
}
}
@@ -1342,7 +1342,7 @@ void AArch64TargetLowering::addTypeForNEON(MVT VT, MVT PromotedBitwiseVT) {
// F[MIN|MAX][NUM|NAN] are available for all FP NEON types.
if (VT.isFloatingPoint() &&
- VT.getVectorElementType() != MVT::bf16 &&
+ VT.getVectorElementType() != MVT::bf16 &&
(VT.getVectorElementType() != MVT::f16 || Subtarget->hasFullFP16()))
for (unsigned Opcode :
{ISD::FMINIMUM, ISD::FMAXIMUM, ISD::FMINNUM, ISD::FMAXNUM})
@@ -1368,64 +1368,64 @@ void AArch64TargetLowering::addTypeForFixedLengthSVE(MVT VT) {
setOperationAction(ISD::EXTRACT_SUBVECTOR, VT, Custom);
// Lower fixed length vector operations to scalable equivalents.
- setOperationAction(ISD::ABS, VT, Custom);
+ setOperationAction(ISD::ABS, VT, Custom);
setOperationAction(ISD::ADD, VT, Custom);
- setOperationAction(ISD::AND, VT, Custom);
- setOperationAction(ISD::ANY_EXTEND, VT, Custom);
- setOperationAction(ISD::BITREVERSE, VT, Custom);
- setOperationAction(ISD::BSWAP, VT, Custom);
- setOperationAction(ISD::CTLZ, VT, Custom);
- setOperationAction(ISD::CTPOP, VT, Custom);
- setOperationAction(ISD::CTTZ, VT, Custom);
+ setOperationAction(ISD::AND, VT, Custom);
+ setOperationAction(ISD::ANY_EXTEND, VT, Custom);
+ setOperationAction(ISD::BITREVERSE, VT, Custom);
+ setOperationAction(ISD::BSWAP, VT, Custom);
+ setOperationAction(ISD::CTLZ, VT, Custom);
+ setOperationAction(ISD::CTPOP, VT, Custom);
+ setOperationAction(ISD::CTTZ, VT, Custom);
setOperationAction(ISD::FADD, VT, Custom);
- setOperationAction(ISD::FCEIL, VT, Custom);
- setOperationAction(ISD::FDIV, VT, Custom);
- setOperationAction(ISD::FFLOOR, VT, Custom);
- setOperationAction(ISD::FMA, VT, Custom);
- setOperationAction(ISD::FMAXNUM, VT, Custom);
- setOperationAction(ISD::FMINNUM, VT, Custom);
- setOperationAction(ISD::FMUL, VT, Custom);
- setOperationAction(ISD::FNEARBYINT, VT, Custom);
- setOperationAction(ISD::FNEG, VT, Custom);
- setOperationAction(ISD::FRINT, VT, Custom);
- setOperationAction(ISD::FROUND, VT, Custom);
- setOperationAction(ISD::FSQRT, VT, Custom);
- setOperationAction(ISD::FSUB, VT, Custom);
- setOperationAction(ISD::FTRUNC, VT, Custom);
+ setOperationAction(ISD::FCEIL, VT, Custom);
+ setOperationAction(ISD::FDIV, VT, Custom);
+ setOperationAction(ISD::FFLOOR, VT, Custom);
+ setOperationAction(ISD::FMA, VT, Custom);
+ setOperationAction(ISD::FMAXNUM, VT, Custom);
+ setOperationAction(ISD::FMINNUM, VT, Custom);
+ setOperationAction(ISD::FMUL, VT, Custom);
+ setOperationAction(ISD::FNEARBYINT, VT, Custom);
+ setOperationAction(ISD::FNEG, VT, Custom);
+ setOperationAction(ISD::FRINT, VT, Custom);
+ setOperationAction(ISD::FROUND, VT, Custom);
+ setOperationAction(ISD::FSQRT, VT, Custom);
+ setOperationAction(ISD::FSUB, VT, Custom);
+ setOperationAction(ISD::FTRUNC, VT, Custom);
setOperationAction(ISD::LOAD, VT, Custom);
- setOperationAction(ISD::MUL, VT, Custom);
- setOperationAction(ISD::OR, VT, Custom);
- setOperationAction(ISD::SDIV, VT, Custom);
- setOperationAction(ISD::SETCC, VT, Custom);
- setOperationAction(ISD::SHL, VT, Custom);
- setOperationAction(ISD::SIGN_EXTEND, VT, Custom);
- setOperationAction(ISD::SIGN_EXTEND_INREG, VT, Custom);
- setOperationAction(ISD::SMAX, VT, Custom);
- setOperationAction(ISD::SMIN, VT, Custom);
- setOperationAction(ISD::SPLAT_VECTOR, VT, Custom);
- setOperationAction(ISD::SRA, VT, Custom);
- setOperationAction(ISD::SRL, VT, Custom);
+ setOperationAction(ISD::MUL, VT, Custom);
+ setOperationAction(ISD::OR, VT, Custom);
+ setOperationAction(ISD::SDIV, VT, Custom);
+ setOperationAction(ISD::SETCC, VT, Custom);
+ setOperationAction(ISD::SHL, VT, Custom);
+ setOperationAction(ISD::SIGN_EXTEND, VT, Custom);
+ setOperationAction(ISD::SIGN_EXTEND_INREG, VT, Custom);
+ setOperationAction(ISD::SMAX, VT, Custom);
+ setOperationAction(ISD::SMIN, VT, Custom);
+ setOperationAction(ISD::SPLAT_VECTOR, VT, Custom);
+ setOperationAction(ISD::SRA, VT, Custom);
+ setOperationAction(ISD::SRL, VT, Custom);
setOperationAction(ISD::STORE, VT, Custom);
- setOperationAction(ISD::SUB, VT, Custom);
+ setOperationAction(ISD::SUB, VT, Custom);
setOperationAction(ISD::TRUNCATE, VT, Custom);
- setOperationAction(ISD::UDIV, VT, Custom);
- setOperationAction(ISD::UMAX, VT, Custom);
- setOperationAction(ISD::UMIN, VT, Custom);
- setOperationAction(ISD::VECREDUCE_ADD, VT, Custom);
- setOperationAction(ISD::VECREDUCE_AND, VT, Custom);
- setOperationAction(ISD::VECREDUCE_FADD, VT, Custom);
- setOperationAction(ISD::VECREDUCE_SEQ_FADD, VT, Custom);
- setOperationAction(ISD::VECREDUCE_FMAX, VT, Custom);
- setOperationAction(ISD::VECREDUCE_FMIN, VT, Custom);
- setOperationAction(ISD::VECREDUCE_OR, VT, Custom);
- setOperationAction(ISD::VECREDUCE_SMAX, VT, Custom);
- setOperationAction(ISD::VECREDUCE_SMIN, VT, Custom);
- setOperationAction(ISD::VECREDUCE_UMAX, VT, Custom);
- setOperationAction(ISD::VECREDUCE_UMIN, VT, Custom);
- setOperationAction(ISD::VECREDUCE_XOR, VT, Custom);
- setOperationAction(ISD::VSELECT, VT, Custom);
- setOperationAction(ISD::XOR, VT, Custom);
- setOperationAction(ISD::ZERO_EXTEND, VT, Custom);
+ setOperationAction(ISD::UDIV, VT, Custom);
+ setOperationAction(ISD::UMAX, VT, Custom);
+ setOperationAction(ISD::UMIN, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_ADD, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_AND, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_FADD, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_SEQ_FADD, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_FMAX, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_FMIN, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_OR, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_SMAX, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_SMIN, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_UMAX, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_UMIN, VT, Custom);
+ setOperationAction(ISD::VECREDUCE_XOR, VT, Custom);
+ setOperationAction(ISD::VSELECT, VT, Custom);
+ setOperationAction(ISD::XOR, VT, Custom);
+ setOperationAction(ISD::ZERO_EXTEND, VT, Custom);
}
void AArch64TargetLowering::addDRTypeForNEON(MVT VT) {
@@ -1597,7 +1597,7 @@ void AArch64TargetLowering::computeKnownBitsForTargetNode(
KnownBits Known2;
Known = DAG.computeKnownBits(Op->getOperand(0), Depth + 1);
Known2 = DAG.computeKnownBits(Op->getOperand(1), Depth + 1);
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
break;
}
case AArch64ISD::LOADgot:
@@ -1737,38 +1737,38 @@ const char *AArch64TargetLowering::getTargetNodeName(unsigned Opcode) const {
MAKE_CASE(AArch64ISD::THREAD_POINTER)
MAKE_CASE(AArch64ISD::TLSDESC_CALLSEQ)
MAKE_CASE(AArch64ISD::ADD_PRED)
- MAKE_CASE(AArch64ISD::MUL_PRED)
+ MAKE_CASE(AArch64ISD::MUL_PRED)
MAKE_CASE(AArch64ISD::SDIV_PRED)
- MAKE_CASE(AArch64ISD::SHL_PRED)
- MAKE_CASE(AArch64ISD::SMAX_PRED)
- MAKE_CASE(AArch64ISD::SMIN_PRED)
- MAKE_CASE(AArch64ISD::SRA_PRED)
- MAKE_CASE(AArch64ISD::SRL_PRED)
- MAKE_CASE(AArch64ISD::SUB_PRED)
+ MAKE_CASE(AArch64ISD::SHL_PRED)
+ MAKE_CASE(AArch64ISD::SMAX_PRED)
+ MAKE_CASE(AArch64ISD::SMIN_PRED)
+ MAKE_CASE(AArch64ISD::SRA_PRED)
+ MAKE_CASE(AArch64ISD::SRL_PRED)
+ MAKE_CASE(AArch64ISD::SUB_PRED)
MAKE_CASE(AArch64ISD::UDIV_PRED)
- MAKE_CASE(AArch64ISD::UMAX_PRED)
- MAKE_CASE(AArch64ISD::UMIN_PRED)
- MAKE_CASE(AArch64ISD::FNEG_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::FCEIL_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::FFLOOR_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::FNEARBYINT_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::FRINT_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::FROUND_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::FROUNDEVEN_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::FTRUNC_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::FP_ROUND_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::FP_EXTEND_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::SINT_TO_FP_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::UINT_TO_FP_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::FCVTZU_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::FCVTZS_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::FSQRT_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::FRECPX_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::FABS_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::ABS_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::NEG_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::UMAX_PRED)
+ MAKE_CASE(AArch64ISD::UMIN_PRED)
+ MAKE_CASE(AArch64ISD::FNEG_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::FCEIL_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::FFLOOR_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::FNEARBYINT_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::FRINT_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::FROUND_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::FROUNDEVEN_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::FTRUNC_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::FP_ROUND_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::FP_EXTEND_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::SINT_TO_FP_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::UINT_TO_FP_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::FCVTZU_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::FCVTZS_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::FSQRT_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::FRECPX_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::FABS_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::ABS_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::NEG_MERGE_PASSTHRU)
MAKE_CASE(AArch64ISD::SETCC_MERGE_ZERO)
MAKE_CASE(AArch64ISD::ADC)
MAKE_CASE(AArch64ISD::SBC)
@@ -1837,14 +1837,14 @@ const char *AArch64TargetLowering::getTargetNodeName(unsigned Opcode) const {
MAKE_CASE(AArch64ISD::UADDV)
MAKE_CASE(AArch64ISD::SRHADD)
MAKE_CASE(AArch64ISD::URHADD)
- MAKE_CASE(AArch64ISD::SHADD)
- MAKE_CASE(AArch64ISD::UHADD)
+ MAKE_CASE(AArch64ISD::SHADD)
+ MAKE_CASE(AArch64ISD::UHADD)
MAKE_CASE(AArch64ISD::SMINV)
MAKE_CASE(AArch64ISD::UMINV)
MAKE_CASE(AArch64ISD::SMAXV)
MAKE_CASE(AArch64ISD::UMAXV)
- MAKE_CASE(AArch64ISD::SADDV_PRED)
- MAKE_CASE(AArch64ISD::UADDV_PRED)
+ MAKE_CASE(AArch64ISD::SADDV_PRED)
+ MAKE_CASE(AArch64ISD::UADDV_PRED)
MAKE_CASE(AArch64ISD::SMAXV_PRED)
MAKE_CASE(AArch64ISD::UMAXV_PRED)
MAKE_CASE(AArch64ISD::SMINV_PRED)
@@ -1862,16 +1862,16 @@ const char *AArch64TargetLowering::getTargetNodeName(unsigned Opcode) const {
MAKE_CASE(AArch64ISD::FADD_PRED)
MAKE_CASE(AArch64ISD::FADDA_PRED)
MAKE_CASE(AArch64ISD::FADDV_PRED)
- MAKE_CASE(AArch64ISD::FDIV_PRED)
+ MAKE_CASE(AArch64ISD::FDIV_PRED)
MAKE_CASE(AArch64ISD::FMA_PRED)
MAKE_CASE(AArch64ISD::FMAXV_PRED)
- MAKE_CASE(AArch64ISD::FMAXNM_PRED)
+ MAKE_CASE(AArch64ISD::FMAXNM_PRED)
MAKE_CASE(AArch64ISD::FMAXNMV_PRED)
MAKE_CASE(AArch64ISD::FMINV_PRED)
- MAKE_CASE(AArch64ISD::FMINNM_PRED)
+ MAKE_CASE(AArch64ISD::FMINNM_PRED)
MAKE_CASE(AArch64ISD::FMINNMV_PRED)
- MAKE_CASE(AArch64ISD::FMUL_PRED)
- MAKE_CASE(AArch64ISD::FSUB_PRED)
+ MAKE_CASE(AArch64ISD::FMUL_PRED)
+ MAKE_CASE(AArch64ISD::FSUB_PRED)
MAKE_CASE(AArch64ISD::BIT)
MAKE_CASE(AArch64ISD::CBZ)
MAKE_CASE(AArch64ISD::CBNZ)
@@ -1983,15 +1983,15 @@ const char *AArch64TargetLowering::getTargetNodeName(unsigned Opcode) const {
MAKE_CASE(AArch64ISD::LDP)
MAKE_CASE(AArch64ISD::STP)
MAKE_CASE(AArch64ISD::STNP)
- MAKE_CASE(AArch64ISD::BITREVERSE_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::BSWAP_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::CTLZ_MERGE_PASSTHRU)
- MAKE_CASE(AArch64ISD::CTPOP_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::BITREVERSE_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::BSWAP_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::CTLZ_MERGE_PASSTHRU)
+ MAKE_CASE(AArch64ISD::CTPOP_MERGE_PASSTHRU)
MAKE_CASE(AArch64ISD::DUP_MERGE_PASSTHRU)
MAKE_CASE(AArch64ISD::INDEX_VECTOR)
- MAKE_CASE(AArch64ISD::UABD)
- MAKE_CASE(AArch64ISD::SABD)
- MAKE_CASE(AArch64ISD::CALL_RVMARKER)
+ MAKE_CASE(AArch64ISD::UABD)
+ MAKE_CASE(AArch64ISD::SABD)
+ MAKE_CASE(AArch64ISD::CALL_RVMARKER)
}
#undef MAKE_CASE
return nullptr;
@@ -2079,7 +2079,7 @@ MachineBasicBlock *AArch64TargetLowering::EmitInstrWithCustomInserter(
case TargetOpcode::STACKMAP:
case TargetOpcode::PATCHPOINT:
- case TargetOpcode::STATEPOINT:
+ case TargetOpcode::STATEPOINT:
return emitPatchPoint(MI, BB);
case AArch64::CATCHRET:
@@ -2905,9 +2905,9 @@ getAArch64XALUOOp(AArch64CC::CondCode &CC, SDValue Op, SelectionDAG &DAG) {
return std::make_pair(Value, Overflow);
}
-SDValue AArch64TargetLowering::LowerXOR(SDValue Op, SelectionDAG &DAG) const {
- if (useSVEForFixedLengthVectorVT(Op.getValueType()))
- return LowerToScalableOp(Op, DAG);
+SDValue AArch64TargetLowering::LowerXOR(SDValue Op, SelectionDAG &DAG) const {
+ if (useSVEForFixedLengthVectorVT(Op.getValueType()))
+ return LowerToScalableOp(Op, DAG);
SDValue Sel = Op.getOperand(0);
SDValue Other = Op.getOperand(1);
@@ -3083,18 +3083,18 @@ static SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG) {
SDValue AArch64TargetLowering::LowerFP_EXTEND(SDValue Op,
SelectionDAG &DAG) const {
- if (Op.getValueType().isScalableVector())
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::FP_EXTEND_MERGE_PASSTHRU);
-
+ if (Op.getValueType().isScalableVector())
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FP_EXTEND_MERGE_PASSTHRU);
+
assert(Op.getValueType() == MVT::f128 && "Unexpected lowering");
- return SDValue();
+ return SDValue();
}
SDValue AArch64TargetLowering::LowerFP_ROUND(SDValue Op,
SelectionDAG &DAG) const {
- if (Op.getValueType().isScalableVector())
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::FP_ROUND_MERGE_PASSTHRU);
-
+ if (Op.getValueType().isScalableVector())
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FP_ROUND_MERGE_PASSTHRU);
+
bool IsStrict = Op->isStrictFPOpcode();
SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
EVT SrcVT = SrcVal.getValueType();
@@ -3108,7 +3108,7 @@ SDValue AArch64TargetLowering::LowerFP_ROUND(SDValue Op,
return Op;
}
- return SDValue();
+ return SDValue();
}
SDValue AArch64TargetLowering::LowerVectorFP_TO_INT(SDValue Op,
@@ -3118,14 +3118,14 @@ SDValue AArch64TargetLowering::LowerVectorFP_TO_INT(SDValue Op,
// in the cost tables.
EVT InVT = Op.getOperand(0).getValueType();
EVT VT = Op.getValueType();
-
- if (VT.isScalableVector()) {
- unsigned Opcode = Op.getOpcode() == ISD::FP_TO_UINT
- ? AArch64ISD::FCVTZU_MERGE_PASSTHRU
- : AArch64ISD::FCVTZS_MERGE_PASSTHRU;
- return LowerToPredicatedOp(Op, DAG, Opcode);
- }
-
+
+ if (VT.isScalableVector()) {
+ unsigned Opcode = Op.getOpcode() == ISD::FP_TO_UINT
+ ? AArch64ISD::FCVTZU_MERGE_PASSTHRU
+ : AArch64ISD::FCVTZS_MERGE_PASSTHRU;
+ return LowerToPredicatedOp(Op, DAG, Opcode);
+ }
+
unsigned NumElts = InVT.getVectorNumElements();
// f16 conversions are promoted to f32 when full fp16 is not supported.
@@ -3138,9 +3138,9 @@ SDValue AArch64TargetLowering::LowerVectorFP_TO_INT(SDValue Op,
DAG.getNode(ISD::FP_EXTEND, dl, NewVT, Op.getOperand(0)));
}
- uint64_t VTSize = VT.getFixedSizeInBits();
- uint64_t InVTSize = InVT.getFixedSizeInBits();
- if (VTSize < InVTSize) {
+ uint64_t VTSize = VT.getFixedSizeInBits();
+ uint64_t InVTSize = InVT.getFixedSizeInBits();
+ if (VTSize < InVTSize) {
SDLoc dl(Op);
SDValue Cv =
DAG.getNode(Op.getOpcode(), dl, InVT.changeVectorElementTypeToInteger(),
@@ -3148,7 +3148,7 @@ SDValue AArch64TargetLowering::LowerVectorFP_TO_INT(SDValue Op,
return DAG.getNode(ISD::TRUNCATE, dl, VT, Cv);
}
- if (VTSize > InVTSize) {
+ if (VTSize > InVTSize) {
SDLoc dl(Op);
MVT ExtVT =
MVT::getVectorVT(MVT::getFloatingPointVT(VT.getScalarSizeInBits()),
@@ -3183,11 +3183,11 @@ SDValue AArch64TargetLowering::LowerFP_TO_INT(SDValue Op,
return Op;
}
- return SDValue();
+ return SDValue();
}
-SDValue AArch64TargetLowering::LowerVectorINT_TO_FP(SDValue Op,
- SelectionDAG &DAG) const {
+SDValue AArch64TargetLowering::LowerVectorINT_TO_FP(SDValue Op,
+ SelectionDAG &DAG) const {
// Warning: We maintain cost tables in AArch64TargetTransformInfo.cpp.
// Any additional optimization in this function should be recorded
// in the cost tables.
@@ -3195,38 +3195,38 @@ SDValue AArch64TargetLowering::LowerVectorINT_TO_FP(SDValue Op,
SDLoc dl(Op);
SDValue In = Op.getOperand(0);
EVT InVT = In.getValueType();
- unsigned Opc = Op.getOpcode();
- bool IsSigned = Opc == ISD::SINT_TO_FP || Opc == ISD::STRICT_SINT_TO_FP;
-
- if (VT.isScalableVector()) {
- if (InVT.getVectorElementType() == MVT::i1) {
- // We can't directly extend an SVE predicate; extend it first.
- unsigned CastOpc = IsSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
- EVT CastVT = getPromotedVTForPredicate(InVT);
- In = DAG.getNode(CastOpc, dl, CastVT, In);
- return DAG.getNode(Opc, dl, VT, In);
- }
-
- unsigned Opcode = IsSigned ? AArch64ISD::SINT_TO_FP_MERGE_PASSTHRU
- : AArch64ISD::UINT_TO_FP_MERGE_PASSTHRU;
- return LowerToPredicatedOp(Op, DAG, Opcode);
- }
-
- uint64_t VTSize = VT.getFixedSizeInBits();
- uint64_t InVTSize = InVT.getFixedSizeInBits();
- if (VTSize < InVTSize) {
+ unsigned Opc = Op.getOpcode();
+ bool IsSigned = Opc == ISD::SINT_TO_FP || Opc == ISD::STRICT_SINT_TO_FP;
+
+ if (VT.isScalableVector()) {
+ if (InVT.getVectorElementType() == MVT::i1) {
+ // We can't directly extend an SVE predicate; extend it first.
+ unsigned CastOpc = IsSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
+ EVT CastVT = getPromotedVTForPredicate(InVT);
+ In = DAG.getNode(CastOpc, dl, CastVT, In);
+ return DAG.getNode(Opc, dl, VT, In);
+ }
+
+ unsigned Opcode = IsSigned ? AArch64ISD::SINT_TO_FP_MERGE_PASSTHRU
+ : AArch64ISD::UINT_TO_FP_MERGE_PASSTHRU;
+ return LowerToPredicatedOp(Op, DAG, Opcode);
+ }
+
+ uint64_t VTSize = VT.getFixedSizeInBits();
+ uint64_t InVTSize = InVT.getFixedSizeInBits();
+ if (VTSize < InVTSize) {
MVT CastVT =
MVT::getVectorVT(MVT::getFloatingPointVT(InVT.getScalarSizeInBits()),
InVT.getVectorNumElements());
- In = DAG.getNode(Opc, dl, CastVT, In);
+ In = DAG.getNode(Opc, dl, CastVT, In);
return DAG.getNode(ISD::FP_ROUND, dl, VT, In, DAG.getIntPtrConstant(0, dl));
}
- if (VTSize > InVTSize) {
- unsigned CastOpc = IsSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
+ if (VTSize > InVTSize) {
+ unsigned CastOpc = IsSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
EVT CastVT = VT.changeVectorElementTypeToInteger();
In = DAG.getNode(CastOpc, dl, CastVT, In);
- return DAG.getNode(Opc, dl, VT, In);
+ return DAG.getNode(Opc, dl, VT, In);
}
return Op;
@@ -3259,7 +3259,7 @@ SDValue AArch64TargetLowering::LowerINT_TO_FP(SDValue Op,
// fp128.
if (Op.getValueType() != MVT::f128)
return Op;
- return SDValue();
+ return SDValue();
}
SDValue AArch64TargetLowering::LowerFSINCOS(SDValue Op,
@@ -3373,8 +3373,8 @@ static bool isExtendedBUILD_VECTOR(SDNode *N, SelectionDAG &DAG,
}
static SDValue skipExtensionForVectorMULL(SDNode *N, SelectionDAG &DAG) {
- if (N->getOpcode() == ISD::SIGN_EXTEND ||
- N->getOpcode() == ISD::ZERO_EXTEND || N->getOpcode() == ISD::ANY_EXTEND)
+ if (N->getOpcode() == ISD::SIGN_EXTEND ||
+ N->getOpcode() == ISD::ZERO_EXTEND || N->getOpcode() == ISD::ANY_EXTEND)
return addRequiredExtensionForVectorMULL(N->getOperand(0), DAG,
N->getOperand(0)->getValueType(0),
N->getValueType(0),
@@ -3399,13 +3399,13 @@ static SDValue skipExtensionForVectorMULL(SDNode *N, SelectionDAG &DAG) {
static bool isSignExtended(SDNode *N, SelectionDAG &DAG) {
return N->getOpcode() == ISD::SIGN_EXTEND ||
- N->getOpcode() == ISD::ANY_EXTEND ||
+ N->getOpcode() == ISD::ANY_EXTEND ||
isExtendedBUILD_VECTOR(N, DAG, true);
}
static bool isZeroExtended(SDNode *N, SelectionDAG &DAG) {
return N->getOpcode() == ISD::ZERO_EXTEND ||
- N->getOpcode() == ISD::ANY_EXTEND ||
+ N->getOpcode() == ISD::ANY_EXTEND ||
isExtendedBUILD_VECTOR(N, DAG, false);
}
@@ -3454,15 +3454,15 @@ SDValue AArch64TargetLowering::LowerFLT_ROUNDS_(SDValue Op,
return DAG.getMergeValues({AND, Chain}, dl);
}
-SDValue AArch64TargetLowering::LowerMUL(SDValue Op, SelectionDAG &DAG) const {
- EVT VT = Op.getValueType();
-
- // If SVE is available then i64 vector multiplications can also be made legal.
- bool OverrideNEON = VT == MVT::v2i64 || VT == MVT::v1i64;
-
- if (VT.isScalableVector() || useSVEForFixedLengthVectorVT(VT, OverrideNEON))
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::MUL_PRED, OverrideNEON);
-
+SDValue AArch64TargetLowering::LowerMUL(SDValue Op, SelectionDAG &DAG) const {
+ EVT VT = Op.getValueType();
+
+ // If SVE is available then i64 vector multiplications can also be made legal.
+ bool OverrideNEON = VT == MVT::v2i64 || VT == MVT::v1i64;
+
+ if (VT.isScalableVector() || useSVEForFixedLengthVectorVT(VT, OverrideNEON))
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::MUL_PRED, OverrideNEON);
+
// Multiplications are only custom-lowered for 128-bit vectors so that
// VMULL can be detected. Otherwise v2i64 multiplications are not legal.
assert(VT.is128BitVector() && VT.isInteger() &&
@@ -3623,77 +3623,77 @@ SDValue AArch64TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
case Intrinsic::aarch64_sve_ptrue:
return DAG.getNode(AArch64ISD::PTRUE, dl, Op.getValueType(),
Op.getOperand(1));
- case Intrinsic::aarch64_sve_clz:
- return DAG.getNode(AArch64ISD::CTLZ_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
- case Intrinsic::aarch64_sve_cnt: {
- SDValue Data = Op.getOperand(3);
- // CTPOP only supports integer operands.
- if (Data.getValueType().isFloatingPoint())
- Data = DAG.getNode(ISD::BITCAST, dl, Op.getValueType(), Data);
- return DAG.getNode(AArch64ISD::CTPOP_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Data, Op.getOperand(1));
- }
+ case Intrinsic::aarch64_sve_clz:
+ return DAG.getNode(AArch64ISD::CTLZ_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
+ case Intrinsic::aarch64_sve_cnt: {
+ SDValue Data = Op.getOperand(3);
+ // CTPOP only supports integer operands.
+ if (Data.getValueType().isFloatingPoint())
+ Data = DAG.getNode(ISD::BITCAST, dl, Op.getValueType(), Data);
+ return DAG.getNode(AArch64ISD::CTPOP_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Data, Op.getOperand(1));
+ }
case Intrinsic::aarch64_sve_dupq_lane:
return LowerDUPQLane(Op, DAG);
case Intrinsic::aarch64_sve_convert_from_svbool:
return DAG.getNode(AArch64ISD::REINTERPRET_CAST, dl, Op.getValueType(),
Op.getOperand(1));
- case Intrinsic::aarch64_sve_fneg:
- return DAG.getNode(AArch64ISD::FNEG_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
- case Intrinsic::aarch64_sve_frintp:
- return DAG.getNode(AArch64ISD::FCEIL_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
- case Intrinsic::aarch64_sve_frintm:
- return DAG.getNode(AArch64ISD::FFLOOR_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
- case Intrinsic::aarch64_sve_frinti:
- return DAG.getNode(AArch64ISD::FNEARBYINT_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
- case Intrinsic::aarch64_sve_frintx:
- return DAG.getNode(AArch64ISD::FRINT_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
- case Intrinsic::aarch64_sve_frinta:
- return DAG.getNode(AArch64ISD::FROUND_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
- case Intrinsic::aarch64_sve_frintn:
- return DAG.getNode(AArch64ISD::FROUNDEVEN_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
- case Intrinsic::aarch64_sve_frintz:
- return DAG.getNode(AArch64ISD::FTRUNC_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
- case Intrinsic::aarch64_sve_ucvtf:
- return DAG.getNode(AArch64ISD::UINT_TO_FP_MERGE_PASSTHRU, dl,
- Op.getValueType(), Op.getOperand(2), Op.getOperand(3),
- Op.getOperand(1));
- case Intrinsic::aarch64_sve_scvtf:
- return DAG.getNode(AArch64ISD::SINT_TO_FP_MERGE_PASSTHRU, dl,
- Op.getValueType(), Op.getOperand(2), Op.getOperand(3),
- Op.getOperand(1));
- case Intrinsic::aarch64_sve_fcvtzu:
- return DAG.getNode(AArch64ISD::FCVTZU_MERGE_PASSTHRU, dl,
- Op.getValueType(), Op.getOperand(2), Op.getOperand(3),
- Op.getOperand(1));
- case Intrinsic::aarch64_sve_fcvtzs:
- return DAG.getNode(AArch64ISD::FCVTZS_MERGE_PASSTHRU, dl,
- Op.getValueType(), Op.getOperand(2), Op.getOperand(3),
- Op.getOperand(1));
- case Intrinsic::aarch64_sve_fsqrt:
- return DAG.getNode(AArch64ISD::FSQRT_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
- case Intrinsic::aarch64_sve_frecpx:
- return DAG.getNode(AArch64ISD::FRECPX_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
- case Intrinsic::aarch64_sve_fabs:
- return DAG.getNode(AArch64ISD::FABS_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
- case Intrinsic::aarch64_sve_abs:
- return DAG.getNode(AArch64ISD::ABS_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
- case Intrinsic::aarch64_sve_neg:
- return DAG.getNode(AArch64ISD::NEG_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
+ case Intrinsic::aarch64_sve_fneg:
+ return DAG.getNode(AArch64ISD::FNEG_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
+ case Intrinsic::aarch64_sve_frintp:
+ return DAG.getNode(AArch64ISD::FCEIL_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
+ case Intrinsic::aarch64_sve_frintm:
+ return DAG.getNode(AArch64ISD::FFLOOR_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
+ case Intrinsic::aarch64_sve_frinti:
+ return DAG.getNode(AArch64ISD::FNEARBYINT_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
+ case Intrinsic::aarch64_sve_frintx:
+ return DAG.getNode(AArch64ISD::FRINT_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
+ case Intrinsic::aarch64_sve_frinta:
+ return DAG.getNode(AArch64ISD::FROUND_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
+ case Intrinsic::aarch64_sve_frintn:
+ return DAG.getNode(AArch64ISD::FROUNDEVEN_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
+ case Intrinsic::aarch64_sve_frintz:
+ return DAG.getNode(AArch64ISD::FTRUNC_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
+ case Intrinsic::aarch64_sve_ucvtf:
+ return DAG.getNode(AArch64ISD::UINT_TO_FP_MERGE_PASSTHRU, dl,
+ Op.getValueType(), Op.getOperand(2), Op.getOperand(3),
+ Op.getOperand(1));
+ case Intrinsic::aarch64_sve_scvtf:
+ return DAG.getNode(AArch64ISD::SINT_TO_FP_MERGE_PASSTHRU, dl,
+ Op.getValueType(), Op.getOperand(2), Op.getOperand(3),
+ Op.getOperand(1));
+ case Intrinsic::aarch64_sve_fcvtzu:
+ return DAG.getNode(AArch64ISD::FCVTZU_MERGE_PASSTHRU, dl,
+ Op.getValueType(), Op.getOperand(2), Op.getOperand(3),
+ Op.getOperand(1));
+ case Intrinsic::aarch64_sve_fcvtzs:
+ return DAG.getNode(AArch64ISD::FCVTZS_MERGE_PASSTHRU, dl,
+ Op.getValueType(), Op.getOperand(2), Op.getOperand(3),
+ Op.getOperand(1));
+ case Intrinsic::aarch64_sve_fsqrt:
+ return DAG.getNode(AArch64ISD::FSQRT_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
+ case Intrinsic::aarch64_sve_frecpx:
+ return DAG.getNode(AArch64ISD::FRECPX_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
+ case Intrinsic::aarch64_sve_fabs:
+ return DAG.getNode(AArch64ISD::FABS_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
+ case Intrinsic::aarch64_sve_abs:
+ return DAG.getNode(AArch64ISD::ABS_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
+ case Intrinsic::aarch64_sve_neg:
+ return DAG.getNode(AArch64ISD::NEG_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
case Intrinsic::aarch64_sve_convert_to_svbool: {
EVT OutVT = Op.getValueType();
EVT InVT = Op.getOperand(1).getValueType();
@@ -3719,49 +3719,49 @@ SDValue AArch64TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
return DAG.getNode(AArch64ISD::INSR, dl, Op.getValueType(),
Op.getOperand(1), Scalar);
}
- case Intrinsic::aarch64_sve_rbit:
- return DAG.getNode(AArch64ISD::BITREVERSE_MERGE_PASSTHRU, dl,
- Op.getValueType(), Op.getOperand(2), Op.getOperand(3),
- Op.getOperand(1));
- case Intrinsic::aarch64_sve_revb:
- return DAG.getNode(AArch64ISD::BSWAP_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
- case Intrinsic::aarch64_sve_sxtb:
- return DAG.getNode(
- AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3),
- DAG.getValueType(Op.getValueType().changeVectorElementType(MVT::i8)),
- Op.getOperand(1));
- case Intrinsic::aarch64_sve_sxth:
- return DAG.getNode(
- AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3),
- DAG.getValueType(Op.getValueType().changeVectorElementType(MVT::i16)),
- Op.getOperand(1));
- case Intrinsic::aarch64_sve_sxtw:
- return DAG.getNode(
- AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3),
- DAG.getValueType(Op.getValueType().changeVectorElementType(MVT::i32)),
- Op.getOperand(1));
- case Intrinsic::aarch64_sve_uxtb:
- return DAG.getNode(
- AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3),
- DAG.getValueType(Op.getValueType().changeVectorElementType(MVT::i8)),
- Op.getOperand(1));
- case Intrinsic::aarch64_sve_uxth:
- return DAG.getNode(
- AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3),
- DAG.getValueType(Op.getValueType().changeVectorElementType(MVT::i16)),
- Op.getOperand(1));
- case Intrinsic::aarch64_sve_uxtw:
- return DAG.getNode(
- AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU, dl, Op.getValueType(),
- Op.getOperand(2), Op.getOperand(3),
- DAG.getValueType(Op.getValueType().changeVectorElementType(MVT::i32)),
- Op.getOperand(1));
+ case Intrinsic::aarch64_sve_rbit:
+ return DAG.getNode(AArch64ISD::BITREVERSE_MERGE_PASSTHRU, dl,
+ Op.getValueType(), Op.getOperand(2), Op.getOperand(3),
+ Op.getOperand(1));
+ case Intrinsic::aarch64_sve_revb:
+ return DAG.getNode(AArch64ISD::BSWAP_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
+ case Intrinsic::aarch64_sve_sxtb:
+ return DAG.getNode(
+ AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3),
+ DAG.getValueType(Op.getValueType().changeVectorElementType(MVT::i8)),
+ Op.getOperand(1));
+ case Intrinsic::aarch64_sve_sxth:
+ return DAG.getNode(
+ AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3),
+ DAG.getValueType(Op.getValueType().changeVectorElementType(MVT::i16)),
+ Op.getOperand(1));
+ case Intrinsic::aarch64_sve_sxtw:
+ return DAG.getNode(
+ AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3),
+ DAG.getValueType(Op.getValueType().changeVectorElementType(MVT::i32)),
+ Op.getOperand(1));
+ case Intrinsic::aarch64_sve_uxtb:
+ return DAG.getNode(
+ AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3),
+ DAG.getValueType(Op.getValueType().changeVectorElementType(MVT::i8)),
+ Op.getOperand(1));
+ case Intrinsic::aarch64_sve_uxth:
+ return DAG.getNode(
+ AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3),
+ DAG.getValueType(Op.getValueType().changeVectorElementType(MVT::i16)),
+ Op.getOperand(1));
+ case Intrinsic::aarch64_sve_uxtw:
+ return DAG.getNode(
+ AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU, dl, Op.getValueType(),
+ Op.getOperand(2), Op.getOperand(3),
+ DAG.getValueType(Op.getValueType().changeVectorElementType(MVT::i32)),
+ Op.getOperand(1));
case Intrinsic::localaddress: {
const auto &MF = DAG.getMachineFunction();
@@ -3801,291 +3801,291 @@ SDValue AArch64TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
}
case Intrinsic::aarch64_neon_srhadd:
- case Intrinsic::aarch64_neon_urhadd:
- case Intrinsic::aarch64_neon_shadd:
- case Intrinsic::aarch64_neon_uhadd: {
- bool IsSignedAdd = (IntNo == Intrinsic::aarch64_neon_srhadd ||
- IntNo == Intrinsic::aarch64_neon_shadd);
- bool IsRoundingAdd = (IntNo == Intrinsic::aarch64_neon_srhadd ||
- IntNo == Intrinsic::aarch64_neon_urhadd);
- unsigned Opcode =
- IsSignedAdd ? (IsRoundingAdd ? AArch64ISD::SRHADD : AArch64ISD::SHADD)
- : (IsRoundingAdd ? AArch64ISD::URHADD : AArch64ISD::UHADD);
+ case Intrinsic::aarch64_neon_urhadd:
+ case Intrinsic::aarch64_neon_shadd:
+ case Intrinsic::aarch64_neon_uhadd: {
+ bool IsSignedAdd = (IntNo == Intrinsic::aarch64_neon_srhadd ||
+ IntNo == Intrinsic::aarch64_neon_shadd);
+ bool IsRoundingAdd = (IntNo == Intrinsic::aarch64_neon_srhadd ||
+ IntNo == Intrinsic::aarch64_neon_urhadd);
+ unsigned Opcode =
+ IsSignedAdd ? (IsRoundingAdd ? AArch64ISD::SRHADD : AArch64ISD::SHADD)
+ : (IsRoundingAdd ? AArch64ISD::URHADD : AArch64ISD::UHADD);
return DAG.getNode(Opcode, dl, Op.getValueType(), Op.getOperand(1),
Op.getOperand(2));
}
-
- case Intrinsic::aarch64_neon_uabd: {
- return DAG.getNode(AArch64ISD::UABD, dl, Op.getValueType(),
- Op.getOperand(1), Op.getOperand(2));
- }
- case Intrinsic::aarch64_neon_sabd: {
- return DAG.getNode(AArch64ISD::SABD, dl, Op.getValueType(),
- Op.getOperand(1), Op.getOperand(2));
- }
- }
-}
-
-bool AArch64TargetLowering::shouldRemoveExtendFromGSIndex(EVT VT) const {
- if (VT.getVectorElementType() == MVT::i32 &&
- VT.getVectorElementCount().getKnownMinValue() >= 4)
- return true;
-
- return false;
-}
-
+
+ case Intrinsic::aarch64_neon_uabd: {
+ return DAG.getNode(AArch64ISD::UABD, dl, Op.getValueType(),
+ Op.getOperand(1), Op.getOperand(2));
+ }
+ case Intrinsic::aarch64_neon_sabd: {
+ return DAG.getNode(AArch64ISD::SABD, dl, Op.getValueType(),
+ Op.getOperand(1), Op.getOperand(2));
+ }
+ }
+}
+
+bool AArch64TargetLowering::shouldRemoveExtendFromGSIndex(EVT VT) const {
+ if (VT.getVectorElementType() == MVT::i32 &&
+ VT.getVectorElementCount().getKnownMinValue() >= 4)
+ return true;
+
+ return false;
+}
+
bool AArch64TargetLowering::isVectorLoadExtDesirable(SDValue ExtVal) const {
return ExtVal.getValueType().isScalableVector();
}
-unsigned getGatherVecOpcode(bool IsScaled, bool IsSigned, bool NeedsExtend) {
- std::map<std::tuple<bool, bool, bool>, unsigned> AddrModes = {
- {std::make_tuple(/*Scaled*/ false, /*Signed*/ false, /*Extend*/ false),
- AArch64ISD::GLD1_MERGE_ZERO},
- {std::make_tuple(/*Scaled*/ false, /*Signed*/ false, /*Extend*/ true),
- AArch64ISD::GLD1_UXTW_MERGE_ZERO},
- {std::make_tuple(/*Scaled*/ false, /*Signed*/ true, /*Extend*/ false),
- AArch64ISD::GLD1_MERGE_ZERO},
- {std::make_tuple(/*Scaled*/ false, /*Signed*/ true, /*Extend*/ true),
- AArch64ISD::GLD1_SXTW_MERGE_ZERO},
- {std::make_tuple(/*Scaled*/ true, /*Signed*/ false, /*Extend*/ false),
- AArch64ISD::GLD1_SCALED_MERGE_ZERO},
- {std::make_tuple(/*Scaled*/ true, /*Signed*/ false, /*Extend*/ true),
- AArch64ISD::GLD1_UXTW_SCALED_MERGE_ZERO},
- {std::make_tuple(/*Scaled*/ true, /*Signed*/ true, /*Extend*/ false),
- AArch64ISD::GLD1_SCALED_MERGE_ZERO},
- {std::make_tuple(/*Scaled*/ true, /*Signed*/ true, /*Extend*/ true),
- AArch64ISD::GLD1_SXTW_SCALED_MERGE_ZERO},
- };
- auto Key = std::make_tuple(IsScaled, IsSigned, NeedsExtend);
- return AddrModes.find(Key)->second;
-}
-
-unsigned getScatterVecOpcode(bool IsScaled, bool IsSigned, bool NeedsExtend) {
- std::map<std::tuple<bool, bool, bool>, unsigned> AddrModes = {
- {std::make_tuple(/*Scaled*/ false, /*Signed*/ false, /*Extend*/ false),
- AArch64ISD::SST1_PRED},
- {std::make_tuple(/*Scaled*/ false, /*Signed*/ false, /*Extend*/ true),
- AArch64ISD::SST1_UXTW_PRED},
- {std::make_tuple(/*Scaled*/ false, /*Signed*/ true, /*Extend*/ false),
- AArch64ISD::SST1_PRED},
- {std::make_tuple(/*Scaled*/ false, /*Signed*/ true, /*Extend*/ true),
- AArch64ISD::SST1_SXTW_PRED},
- {std::make_tuple(/*Scaled*/ true, /*Signed*/ false, /*Extend*/ false),
- AArch64ISD::SST1_SCALED_PRED},
- {std::make_tuple(/*Scaled*/ true, /*Signed*/ false, /*Extend*/ true),
- AArch64ISD::SST1_UXTW_SCALED_PRED},
- {std::make_tuple(/*Scaled*/ true, /*Signed*/ true, /*Extend*/ false),
- AArch64ISD::SST1_SCALED_PRED},
- {std::make_tuple(/*Scaled*/ true, /*Signed*/ true, /*Extend*/ true),
- AArch64ISD::SST1_SXTW_SCALED_PRED},
- };
- auto Key = std::make_tuple(IsScaled, IsSigned, NeedsExtend);
- return AddrModes.find(Key)->second;
-}
-
-unsigned getSignExtendedGatherOpcode(unsigned Opcode) {
- switch (Opcode) {
- default:
- llvm_unreachable("unimplemented opcode");
- return Opcode;
- case AArch64ISD::GLD1_MERGE_ZERO:
- return AArch64ISD::GLD1S_MERGE_ZERO;
- case AArch64ISD::GLD1_IMM_MERGE_ZERO:
- return AArch64ISD::GLD1S_IMM_MERGE_ZERO;
- case AArch64ISD::GLD1_UXTW_MERGE_ZERO:
- return AArch64ISD::GLD1S_UXTW_MERGE_ZERO;
- case AArch64ISD::GLD1_SXTW_MERGE_ZERO:
- return AArch64ISD::GLD1S_SXTW_MERGE_ZERO;
- case AArch64ISD::GLD1_SCALED_MERGE_ZERO:
- return AArch64ISD::GLD1S_SCALED_MERGE_ZERO;
- case AArch64ISD::GLD1_UXTW_SCALED_MERGE_ZERO:
- return AArch64ISD::GLD1S_UXTW_SCALED_MERGE_ZERO;
- case AArch64ISD::GLD1_SXTW_SCALED_MERGE_ZERO:
- return AArch64ISD::GLD1S_SXTW_SCALED_MERGE_ZERO;
- }
-}
-
-bool getGatherScatterIndexIsExtended(SDValue Index) {
- unsigned Opcode = Index.getOpcode();
- if (Opcode == ISD::SIGN_EXTEND_INREG)
- return true;
-
- if (Opcode == ISD::AND) {
- SDValue Splat = Index.getOperand(1);
- if (Splat.getOpcode() != ISD::SPLAT_VECTOR)
- return false;
- ConstantSDNode *Mask = dyn_cast<ConstantSDNode>(Splat.getOperand(0));
- if (!Mask || Mask->getZExtValue() != 0xFFFFFFFF)
- return false;
- return true;
- }
-
- return false;
-}
-
-// If the base pointer of a masked gather or scatter is null, we
-// may be able to swap BasePtr & Index and use the vector + register
-// or vector + immediate addressing mode, e.g.
-// VECTOR + REGISTER:
-// getelementptr nullptr, <vscale x N x T> (splat(%offset)) + %indices)
-// -> getelementptr %offset, <vscale x N x T> %indices
-// VECTOR + IMMEDIATE:
-// getelementptr nullptr, <vscale x N x T> (splat(#x)) + %indices)
-// -> getelementptr #x, <vscale x N x T> %indices
-void selectGatherScatterAddrMode(SDValue &BasePtr, SDValue &Index, EVT MemVT,
- unsigned &Opcode, bool IsGather,
- SelectionDAG &DAG) {
- if (!isNullConstant(BasePtr))
- return;
-
- ConstantSDNode *Offset = nullptr;
- if (Index.getOpcode() == ISD::ADD)
- if (auto SplatVal = DAG.getSplatValue(Index.getOperand(1))) {
- if (isa<ConstantSDNode>(SplatVal))
- Offset = cast<ConstantSDNode>(SplatVal);
- else {
- BasePtr = SplatVal;
- Index = Index->getOperand(0);
- return;
- }
- }
-
- unsigned NewOp =
- IsGather ? AArch64ISD::GLD1_IMM_MERGE_ZERO : AArch64ISD::SST1_IMM_PRED;
-
- if (!Offset) {
- std::swap(BasePtr, Index);
- Opcode = NewOp;
- return;
- }
-
- uint64_t OffsetVal = Offset->getZExtValue();
- unsigned ScalarSizeInBytes = MemVT.getScalarSizeInBits() / 8;
- auto ConstOffset = DAG.getConstant(OffsetVal, SDLoc(Index), MVT::i64);
-
- if (OffsetVal % ScalarSizeInBytes || OffsetVal / ScalarSizeInBytes > 31) {
- // Index is out of range for the immediate addressing mode
- BasePtr = ConstOffset;
- Index = Index->getOperand(0);
- return;
- }
-
- // Immediate is in range
- Opcode = NewOp;
- BasePtr = Index->getOperand(0);
- Index = ConstOffset;
-}
-
-SDValue AArch64TargetLowering::LowerMGATHER(SDValue Op,
- SelectionDAG &DAG) const {
- SDLoc DL(Op);
- MaskedGatherSDNode *MGT = cast<MaskedGatherSDNode>(Op);
- assert(MGT && "Can only custom lower gather load nodes");
-
- SDValue Index = MGT->getIndex();
- SDValue Chain = MGT->getChain();
- SDValue PassThru = MGT->getPassThru();
- SDValue Mask = MGT->getMask();
- SDValue BasePtr = MGT->getBasePtr();
- ISD::LoadExtType ExtTy = MGT->getExtensionType();
-
- ISD::MemIndexType IndexType = MGT->getIndexType();
- bool IsScaled =
- IndexType == ISD::SIGNED_SCALED || IndexType == ISD::UNSIGNED_SCALED;
- bool IsSigned =
- IndexType == ISD::SIGNED_SCALED || IndexType == ISD::SIGNED_UNSCALED;
- bool IdxNeedsExtend =
- getGatherScatterIndexIsExtended(Index) ||
- Index.getSimpleValueType().getVectorElementType() == MVT::i32;
- bool ResNeedsSignExtend = ExtTy == ISD::EXTLOAD || ExtTy == ISD::SEXTLOAD;
-
- EVT VT = PassThru.getSimpleValueType();
- EVT MemVT = MGT->getMemoryVT();
- SDValue InputVT = DAG.getValueType(MemVT);
-
- if (VT.getVectorElementType() == MVT::bf16 &&
- !static_cast<const AArch64Subtarget &>(DAG.getSubtarget()).hasBF16())
- return SDValue();
-
- // Handle FP data by using an integer gather and casting the result.
- if (VT.isFloatingPoint()) {
- EVT PassThruVT = getPackedSVEVectorVT(VT.getVectorElementCount());
- PassThru = getSVESafeBitCast(PassThruVT, PassThru, DAG);
- InputVT = DAG.getValueType(MemVT.changeVectorElementTypeToInteger());
- }
-
- SDVTList VTs = DAG.getVTList(PassThru.getSimpleValueType(), MVT::Other);
-
- if (getGatherScatterIndexIsExtended(Index))
- Index = Index.getOperand(0);
-
- unsigned Opcode = getGatherVecOpcode(IsScaled, IsSigned, IdxNeedsExtend);
- selectGatherScatterAddrMode(BasePtr, Index, MemVT, Opcode,
- /*isGather=*/true, DAG);
-
- if (ResNeedsSignExtend)
- Opcode = getSignExtendedGatherOpcode(Opcode);
-
- SDValue Ops[] = {Chain, Mask, BasePtr, Index, InputVT, PassThru};
- SDValue Gather = DAG.getNode(Opcode, DL, VTs, Ops);
-
- if (VT.isFloatingPoint()) {
- SDValue Cast = getSVESafeBitCast(VT, Gather, DAG);
- return DAG.getMergeValues({Cast, Gather}, DL);
- }
-
- return Gather;
-}
-
-SDValue AArch64TargetLowering::LowerMSCATTER(SDValue Op,
- SelectionDAG &DAG) const {
- SDLoc DL(Op);
- MaskedScatterSDNode *MSC = cast<MaskedScatterSDNode>(Op);
- assert(MSC && "Can only custom lower scatter store nodes");
-
- SDValue Index = MSC->getIndex();
- SDValue Chain = MSC->getChain();
- SDValue StoreVal = MSC->getValue();
- SDValue Mask = MSC->getMask();
- SDValue BasePtr = MSC->getBasePtr();
-
- ISD::MemIndexType IndexType = MSC->getIndexType();
- bool IsScaled =
- IndexType == ISD::SIGNED_SCALED || IndexType == ISD::UNSIGNED_SCALED;
- bool IsSigned =
- IndexType == ISD::SIGNED_SCALED || IndexType == ISD::SIGNED_UNSCALED;
- bool NeedsExtend =
- getGatherScatterIndexIsExtended(Index) ||
- Index.getSimpleValueType().getVectorElementType() == MVT::i32;
-
- EVT VT = StoreVal.getSimpleValueType();
- SDVTList VTs = DAG.getVTList(MVT::Other);
- EVT MemVT = MSC->getMemoryVT();
- SDValue InputVT = DAG.getValueType(MemVT);
-
- if (VT.getVectorElementType() == MVT::bf16 &&
- !static_cast<const AArch64Subtarget &>(DAG.getSubtarget()).hasBF16())
- return SDValue();
-
- // Handle FP data by casting the data so an integer scatter can be used.
- if (VT.isFloatingPoint()) {
- EVT StoreValVT = getPackedSVEVectorVT(VT.getVectorElementCount());
- StoreVal = getSVESafeBitCast(StoreValVT, StoreVal, DAG);
- InputVT = DAG.getValueType(MemVT.changeVectorElementTypeToInteger());
- }
-
- if (getGatherScatterIndexIsExtended(Index))
- Index = Index.getOperand(0);
-
- unsigned Opcode = getScatterVecOpcode(IsScaled, IsSigned, NeedsExtend);
- selectGatherScatterAddrMode(BasePtr, Index, MemVT, Opcode,
- /*isGather=*/false, DAG);
-
- SDValue Ops[] = {Chain, StoreVal, Mask, BasePtr, Index, InputVT};
- return DAG.getNode(Opcode, DL, VTs, Ops);
-}
-
+unsigned getGatherVecOpcode(bool IsScaled, bool IsSigned, bool NeedsExtend) {
+ std::map<std::tuple<bool, bool, bool>, unsigned> AddrModes = {
+ {std::make_tuple(/*Scaled*/ false, /*Signed*/ false, /*Extend*/ false),
+ AArch64ISD::GLD1_MERGE_ZERO},
+ {std::make_tuple(/*Scaled*/ false, /*Signed*/ false, /*Extend*/ true),
+ AArch64ISD::GLD1_UXTW_MERGE_ZERO},
+ {std::make_tuple(/*Scaled*/ false, /*Signed*/ true, /*Extend*/ false),
+ AArch64ISD::GLD1_MERGE_ZERO},
+ {std::make_tuple(/*Scaled*/ false, /*Signed*/ true, /*Extend*/ true),
+ AArch64ISD::GLD1_SXTW_MERGE_ZERO},
+ {std::make_tuple(/*Scaled*/ true, /*Signed*/ false, /*Extend*/ false),
+ AArch64ISD::GLD1_SCALED_MERGE_ZERO},
+ {std::make_tuple(/*Scaled*/ true, /*Signed*/ false, /*Extend*/ true),
+ AArch64ISD::GLD1_UXTW_SCALED_MERGE_ZERO},
+ {std::make_tuple(/*Scaled*/ true, /*Signed*/ true, /*Extend*/ false),
+ AArch64ISD::GLD1_SCALED_MERGE_ZERO},
+ {std::make_tuple(/*Scaled*/ true, /*Signed*/ true, /*Extend*/ true),
+ AArch64ISD::GLD1_SXTW_SCALED_MERGE_ZERO},
+ };
+ auto Key = std::make_tuple(IsScaled, IsSigned, NeedsExtend);
+ return AddrModes.find(Key)->second;
+}
+
+unsigned getScatterVecOpcode(bool IsScaled, bool IsSigned, bool NeedsExtend) {
+ std::map<std::tuple<bool, bool, bool>, unsigned> AddrModes = {
+ {std::make_tuple(/*Scaled*/ false, /*Signed*/ false, /*Extend*/ false),
+ AArch64ISD::SST1_PRED},
+ {std::make_tuple(/*Scaled*/ false, /*Signed*/ false, /*Extend*/ true),
+ AArch64ISD::SST1_UXTW_PRED},
+ {std::make_tuple(/*Scaled*/ false, /*Signed*/ true, /*Extend*/ false),
+ AArch64ISD::SST1_PRED},
+ {std::make_tuple(/*Scaled*/ false, /*Signed*/ true, /*Extend*/ true),
+ AArch64ISD::SST1_SXTW_PRED},
+ {std::make_tuple(/*Scaled*/ true, /*Signed*/ false, /*Extend*/ false),
+ AArch64ISD::SST1_SCALED_PRED},
+ {std::make_tuple(/*Scaled*/ true, /*Signed*/ false, /*Extend*/ true),
+ AArch64ISD::SST1_UXTW_SCALED_PRED},
+ {std::make_tuple(/*Scaled*/ true, /*Signed*/ true, /*Extend*/ false),
+ AArch64ISD::SST1_SCALED_PRED},
+ {std::make_tuple(/*Scaled*/ true, /*Signed*/ true, /*Extend*/ true),
+ AArch64ISD::SST1_SXTW_SCALED_PRED},
+ };
+ auto Key = std::make_tuple(IsScaled, IsSigned, NeedsExtend);
+ return AddrModes.find(Key)->second;
+}
+
+unsigned getSignExtendedGatherOpcode(unsigned Opcode) {
+ switch (Opcode) {
+ default:
+ llvm_unreachable("unimplemented opcode");
+ return Opcode;
+ case AArch64ISD::GLD1_MERGE_ZERO:
+ return AArch64ISD::GLD1S_MERGE_ZERO;
+ case AArch64ISD::GLD1_IMM_MERGE_ZERO:
+ return AArch64ISD::GLD1S_IMM_MERGE_ZERO;
+ case AArch64ISD::GLD1_UXTW_MERGE_ZERO:
+ return AArch64ISD::GLD1S_UXTW_MERGE_ZERO;
+ case AArch64ISD::GLD1_SXTW_MERGE_ZERO:
+ return AArch64ISD::GLD1S_SXTW_MERGE_ZERO;
+ case AArch64ISD::GLD1_SCALED_MERGE_ZERO:
+ return AArch64ISD::GLD1S_SCALED_MERGE_ZERO;
+ case AArch64ISD::GLD1_UXTW_SCALED_MERGE_ZERO:
+ return AArch64ISD::GLD1S_UXTW_SCALED_MERGE_ZERO;
+ case AArch64ISD::GLD1_SXTW_SCALED_MERGE_ZERO:
+ return AArch64ISD::GLD1S_SXTW_SCALED_MERGE_ZERO;
+ }
+}
+
+bool getGatherScatterIndexIsExtended(SDValue Index) {
+ unsigned Opcode = Index.getOpcode();
+ if (Opcode == ISD::SIGN_EXTEND_INREG)
+ return true;
+
+ if (Opcode == ISD::AND) {
+ SDValue Splat = Index.getOperand(1);
+ if (Splat.getOpcode() != ISD::SPLAT_VECTOR)
+ return false;
+ ConstantSDNode *Mask = dyn_cast<ConstantSDNode>(Splat.getOperand(0));
+ if (!Mask || Mask->getZExtValue() != 0xFFFFFFFF)
+ return false;
+ return true;
+ }
+
+ return false;
+}
+
+// If the base pointer of a masked gather or scatter is null, we
+// may be able to swap BasePtr & Index and use the vector + register
+// or vector + immediate addressing mode, e.g.
+// VECTOR + REGISTER:
+// getelementptr nullptr, <vscale x N x T> (splat(%offset)) + %indices)
+// -> getelementptr %offset, <vscale x N x T> %indices
+// VECTOR + IMMEDIATE:
+// getelementptr nullptr, <vscale x N x T> (splat(#x)) + %indices)
+// -> getelementptr #x, <vscale x N x T> %indices
+void selectGatherScatterAddrMode(SDValue &BasePtr, SDValue &Index, EVT MemVT,
+ unsigned &Opcode, bool IsGather,
+ SelectionDAG &DAG) {
+ if (!isNullConstant(BasePtr))
+ return;
+
+ ConstantSDNode *Offset = nullptr;
+ if (Index.getOpcode() == ISD::ADD)
+ if (auto SplatVal = DAG.getSplatValue(Index.getOperand(1))) {
+ if (isa<ConstantSDNode>(SplatVal))
+ Offset = cast<ConstantSDNode>(SplatVal);
+ else {
+ BasePtr = SplatVal;
+ Index = Index->getOperand(0);
+ return;
+ }
+ }
+
+ unsigned NewOp =
+ IsGather ? AArch64ISD::GLD1_IMM_MERGE_ZERO : AArch64ISD::SST1_IMM_PRED;
+
+ if (!Offset) {
+ std::swap(BasePtr, Index);
+ Opcode = NewOp;
+ return;
+ }
+
+ uint64_t OffsetVal = Offset->getZExtValue();
+ unsigned ScalarSizeInBytes = MemVT.getScalarSizeInBits() / 8;
+ auto ConstOffset = DAG.getConstant(OffsetVal, SDLoc(Index), MVT::i64);
+
+ if (OffsetVal % ScalarSizeInBytes || OffsetVal / ScalarSizeInBytes > 31) {
+ // Index is out of range for the immediate addressing mode
+ BasePtr = ConstOffset;
+ Index = Index->getOperand(0);
+ return;
+ }
+
+ // Immediate is in range
+ Opcode = NewOp;
+ BasePtr = Index->getOperand(0);
+ Index = ConstOffset;
+}
+
+SDValue AArch64TargetLowering::LowerMGATHER(SDValue Op,
+ SelectionDAG &DAG) const {
+ SDLoc DL(Op);
+ MaskedGatherSDNode *MGT = cast<MaskedGatherSDNode>(Op);
+ assert(MGT && "Can only custom lower gather load nodes");
+
+ SDValue Index = MGT->getIndex();
+ SDValue Chain = MGT->getChain();
+ SDValue PassThru = MGT->getPassThru();
+ SDValue Mask = MGT->getMask();
+ SDValue BasePtr = MGT->getBasePtr();
+ ISD::LoadExtType ExtTy = MGT->getExtensionType();
+
+ ISD::MemIndexType IndexType = MGT->getIndexType();
+ bool IsScaled =
+ IndexType == ISD::SIGNED_SCALED || IndexType == ISD::UNSIGNED_SCALED;
+ bool IsSigned =
+ IndexType == ISD::SIGNED_SCALED || IndexType == ISD::SIGNED_UNSCALED;
+ bool IdxNeedsExtend =
+ getGatherScatterIndexIsExtended(Index) ||
+ Index.getSimpleValueType().getVectorElementType() == MVT::i32;
+ bool ResNeedsSignExtend = ExtTy == ISD::EXTLOAD || ExtTy == ISD::SEXTLOAD;
+
+ EVT VT = PassThru.getSimpleValueType();
+ EVT MemVT = MGT->getMemoryVT();
+ SDValue InputVT = DAG.getValueType(MemVT);
+
+ if (VT.getVectorElementType() == MVT::bf16 &&
+ !static_cast<const AArch64Subtarget &>(DAG.getSubtarget()).hasBF16())
+ return SDValue();
+
+ // Handle FP data by using an integer gather and casting the result.
+ if (VT.isFloatingPoint()) {
+ EVT PassThruVT = getPackedSVEVectorVT(VT.getVectorElementCount());
+ PassThru = getSVESafeBitCast(PassThruVT, PassThru, DAG);
+ InputVT = DAG.getValueType(MemVT.changeVectorElementTypeToInteger());
+ }
+
+ SDVTList VTs = DAG.getVTList(PassThru.getSimpleValueType(), MVT::Other);
+
+ if (getGatherScatterIndexIsExtended(Index))
+ Index = Index.getOperand(0);
+
+ unsigned Opcode = getGatherVecOpcode(IsScaled, IsSigned, IdxNeedsExtend);
+ selectGatherScatterAddrMode(BasePtr, Index, MemVT, Opcode,
+ /*isGather=*/true, DAG);
+
+ if (ResNeedsSignExtend)
+ Opcode = getSignExtendedGatherOpcode(Opcode);
+
+ SDValue Ops[] = {Chain, Mask, BasePtr, Index, InputVT, PassThru};
+ SDValue Gather = DAG.getNode(Opcode, DL, VTs, Ops);
+
+ if (VT.isFloatingPoint()) {
+ SDValue Cast = getSVESafeBitCast(VT, Gather, DAG);
+ return DAG.getMergeValues({Cast, Gather}, DL);
+ }
+
+ return Gather;
+}
+
+SDValue AArch64TargetLowering::LowerMSCATTER(SDValue Op,
+ SelectionDAG &DAG) const {
+ SDLoc DL(Op);
+ MaskedScatterSDNode *MSC = cast<MaskedScatterSDNode>(Op);
+ assert(MSC && "Can only custom lower scatter store nodes");
+
+ SDValue Index = MSC->getIndex();
+ SDValue Chain = MSC->getChain();
+ SDValue StoreVal = MSC->getValue();
+ SDValue Mask = MSC->getMask();
+ SDValue BasePtr = MSC->getBasePtr();
+
+ ISD::MemIndexType IndexType = MSC->getIndexType();
+ bool IsScaled =
+ IndexType == ISD::SIGNED_SCALED || IndexType == ISD::UNSIGNED_SCALED;
+ bool IsSigned =
+ IndexType == ISD::SIGNED_SCALED || IndexType == ISD::SIGNED_UNSCALED;
+ bool NeedsExtend =
+ getGatherScatterIndexIsExtended(Index) ||
+ Index.getSimpleValueType().getVectorElementType() == MVT::i32;
+
+ EVT VT = StoreVal.getSimpleValueType();
+ SDVTList VTs = DAG.getVTList(MVT::Other);
+ EVT MemVT = MSC->getMemoryVT();
+ SDValue InputVT = DAG.getValueType(MemVT);
+
+ if (VT.getVectorElementType() == MVT::bf16 &&
+ !static_cast<const AArch64Subtarget &>(DAG.getSubtarget()).hasBF16())
+ return SDValue();
+
+ // Handle FP data by casting the data so an integer scatter can be used.
+ if (VT.isFloatingPoint()) {
+ EVT StoreValVT = getPackedSVEVectorVT(VT.getVectorElementCount());
+ StoreVal = getSVESafeBitCast(StoreValVT, StoreVal, DAG);
+ InputVT = DAG.getValueType(MemVT.changeVectorElementTypeToInteger());
+ }
+
+ if (getGatherScatterIndexIsExtended(Index))
+ Index = Index.getOperand(0);
+
+ unsigned Opcode = getScatterVecOpcode(IsScaled, IsSigned, NeedsExtend);
+ selectGatherScatterAddrMode(BasePtr, Index, MemVT, Opcode,
+ /*isGather=*/false, DAG);
+
+ SDValue Ops[] = {Chain, StoreVal, Mask, BasePtr, Index, InputVT};
+ return DAG.getNode(Opcode, DL, VTs, Ops);
+}
+
// Custom lower trunc store for v4i8 vectors, since it is promoted to v4i16.
static SDValue LowerTruncateVectorStore(SDLoc DL, StoreSDNode *ST,
EVT VT, EVT MemVT,
@@ -4151,9 +4151,9 @@ SDValue AArch64TargetLowering::LowerSTORE(SDValue Op,
// 256 bit non-temporal stores can be lowered to STNP. Do this as part of
// the custom lowering, as there are no un-paired non-temporal stores and
// legalization will break up 256 bit inputs.
- ElementCount EC = MemVT.getVectorElementCount();
+ ElementCount EC = MemVT.getVectorElementCount();
if (StoreNode->isNonTemporal() && MemVT.getSizeInBits() == 256u &&
- EC.isKnownEven() &&
+ EC.isKnownEven() &&
((MemVT.getScalarSizeInBits() == 8u ||
MemVT.getScalarSizeInBits() == 16u ||
MemVT.getScalarSizeInBits() == 32u ||
@@ -4162,11 +4162,11 @@ SDValue AArch64TargetLowering::LowerSTORE(SDValue Op,
DAG.getNode(ISD::EXTRACT_SUBVECTOR, Dl,
MemVT.getHalfNumVectorElementsVT(*DAG.getContext()),
StoreNode->getValue(), DAG.getConstant(0, Dl, MVT::i64));
- SDValue Hi =
- DAG.getNode(ISD::EXTRACT_SUBVECTOR, Dl,
- MemVT.getHalfNumVectorElementsVT(*DAG.getContext()),
- StoreNode->getValue(),
- DAG.getConstant(EC.getKnownMinValue() / 2, Dl, MVT::i64));
+ SDValue Hi =
+ DAG.getNode(ISD::EXTRACT_SUBVECTOR, Dl,
+ MemVT.getHalfNumVectorElementsVT(*DAG.getContext()),
+ StoreNode->getValue(),
+ DAG.getConstant(EC.getKnownMinValue() / 2, Dl, MVT::i64));
SDValue Result = DAG.getMemIntrinsicNode(
AArch64ISD::STNP, Dl, DAG.getVTList(MVT::Other),
{StoreNode->getChain(), Lo, Hi, StoreNode->getBasePtr()},
@@ -4191,25 +4191,25 @@ SDValue AArch64TargetLowering::LowerSTORE(SDValue Op,
return SDValue();
}
-// Generate SUBS and CSEL for integer abs.
-SDValue AArch64TargetLowering::LowerABS(SDValue Op, SelectionDAG &DAG) const {
- MVT VT = Op.getSimpleValueType();
-
- if (VT.isVector())
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::ABS_MERGE_PASSTHRU);
-
- SDLoc DL(Op);
- SDValue Neg = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT),
- Op.getOperand(0));
- // Generate SUBS & CSEL.
- SDValue Cmp =
- DAG.getNode(AArch64ISD::SUBS, DL, DAG.getVTList(VT, MVT::i32),
- Op.getOperand(0), DAG.getConstant(0, DL, VT));
- return DAG.getNode(AArch64ISD::CSEL, DL, VT, Op.getOperand(0), Neg,
- DAG.getConstant(AArch64CC::PL, DL, MVT::i32),
- Cmp.getValue(1));
-}
-
+// Generate SUBS and CSEL for integer abs.
+SDValue AArch64TargetLowering::LowerABS(SDValue Op, SelectionDAG &DAG) const {
+ MVT VT = Op.getSimpleValueType();
+
+ if (VT.isVector())
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::ABS_MERGE_PASSTHRU);
+
+ SDLoc DL(Op);
+ SDValue Neg = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT),
+ Op.getOperand(0));
+ // Generate SUBS & CSEL.
+ SDValue Cmp =
+ DAG.getNode(AArch64ISD::SUBS, DL, DAG.getVTList(VT, MVT::i32),
+ Op.getOperand(0), DAG.getConstant(0, DL, VT));
+ return DAG.getNode(AArch64ISD::CSEL, DL, VT, Op.getOperand(0), Neg,
+ DAG.getConstant(AArch64CC::PL, DL, MVT::i32),
+ Cmp.getValue(1));
+}
+
SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
SelectionDAG &DAG) const {
LLVM_DEBUG(dbgs() << "Custom lowering: ");
@@ -4262,35 +4262,35 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
case ISD::UMULO:
return LowerXALUO(Op, DAG);
case ISD::FADD:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::FADD_PRED);
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FADD_PRED);
case ISD::FSUB:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::FSUB_PRED);
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FSUB_PRED);
case ISD::FMUL:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::FMUL_PRED);
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FMUL_PRED);
case ISD::FMA:
return LowerToPredicatedOp(Op, DAG, AArch64ISD::FMA_PRED);
case ISD::FDIV:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::FDIV_PRED);
- case ISD::FNEG:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::FNEG_MERGE_PASSTHRU);
- case ISD::FCEIL:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::FCEIL_MERGE_PASSTHRU);
- case ISD::FFLOOR:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::FFLOOR_MERGE_PASSTHRU);
- case ISD::FNEARBYINT:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::FNEARBYINT_MERGE_PASSTHRU);
- case ISD::FRINT:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::FRINT_MERGE_PASSTHRU);
- case ISD::FROUND:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::FROUND_MERGE_PASSTHRU);
- case ISD::FROUNDEVEN:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::FROUNDEVEN_MERGE_PASSTHRU);
- case ISD::FTRUNC:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::FTRUNC_MERGE_PASSTHRU);
- case ISD::FSQRT:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::FSQRT_MERGE_PASSTHRU);
- case ISD::FABS:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::FABS_MERGE_PASSTHRU);
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FDIV_PRED);
+ case ISD::FNEG:
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FNEG_MERGE_PASSTHRU);
+ case ISD::FCEIL:
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FCEIL_MERGE_PASSTHRU);
+ case ISD::FFLOOR:
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FFLOOR_MERGE_PASSTHRU);
+ case ISD::FNEARBYINT:
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FNEARBYINT_MERGE_PASSTHRU);
+ case ISD::FRINT:
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FRINT_MERGE_PASSTHRU);
+ case ISD::FROUND:
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FROUND_MERGE_PASSTHRU);
+ case ISD::FROUNDEVEN:
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FROUNDEVEN_MERGE_PASSTHRU);
+ case ISD::FTRUNC:
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FTRUNC_MERGE_PASSTHRU);
+ case ISD::FSQRT:
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FSQRT_MERGE_PASSTHRU);
+ case ISD::FABS:
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FABS_MERGE_PASSTHRU);
case ISD::FP_ROUND:
case ISD::STRICT_FP_ROUND:
return LowerFP_ROUND(Op, DAG);
@@ -4304,8 +4304,8 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
return LowerRETURNADDR(Op, DAG);
case ISD::ADDROFRETURNADDR:
return LowerADDROFRETURNADDR(Op, DAG);
- case ISD::CONCAT_VECTORS:
- return LowerCONCAT_VECTORS(Op, DAG);
+ case ISD::CONCAT_VECTORS:
+ return LowerCONCAT_VECTORS(Op, DAG);
case ISD::INSERT_VECTOR_ELT:
return LowerINSERT_VECTOR_ELT(Op, DAG);
case ISD::EXTRACT_VECTOR_ELT:
@@ -4322,19 +4322,19 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
return LowerINSERT_SUBVECTOR(Op, DAG);
case ISD::SDIV:
case ISD::UDIV:
- return LowerDIV(Op, DAG);
+ return LowerDIV(Op, DAG);
case ISD::SMIN:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::SMIN_PRED,
- /*OverrideNEON=*/true);
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::SMIN_PRED,
+ /*OverrideNEON=*/true);
case ISD::UMIN:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::UMIN_PRED,
- /*OverrideNEON=*/true);
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::UMIN_PRED,
+ /*OverrideNEON=*/true);
case ISD::SMAX:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::SMAX_PRED,
- /*OverrideNEON=*/true);
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::SMAX_PRED,
+ /*OverrideNEON=*/true);
case ISD::UMAX:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::UMAX_PRED,
- /*OverrideNEON=*/true);
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::UMAX_PRED,
+ /*OverrideNEON=*/true);
case ISD::SRA:
case ISD::SRL:
case ISD::SHL:
@@ -4374,21 +4374,21 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
return LowerINTRINSIC_WO_CHAIN(Op, DAG);
case ISD::STORE:
return LowerSTORE(Op, DAG);
- case ISD::MGATHER:
- return LowerMGATHER(Op, DAG);
- case ISD::MSCATTER:
- return LowerMSCATTER(Op, DAG);
- case ISD::VECREDUCE_SEQ_FADD:
- return LowerVECREDUCE_SEQ_FADD(Op, DAG);
+ case ISD::MGATHER:
+ return LowerMGATHER(Op, DAG);
+ case ISD::MSCATTER:
+ return LowerMSCATTER(Op, DAG);
+ case ISD::VECREDUCE_SEQ_FADD:
+ return LowerVECREDUCE_SEQ_FADD(Op, DAG);
case ISD::VECREDUCE_ADD:
- case ISD::VECREDUCE_AND:
- case ISD::VECREDUCE_OR:
- case ISD::VECREDUCE_XOR:
+ case ISD::VECREDUCE_AND:
+ case ISD::VECREDUCE_OR:
+ case ISD::VECREDUCE_XOR:
case ISD::VECREDUCE_SMAX:
case ISD::VECREDUCE_SMIN:
case ISD::VECREDUCE_UMAX:
case ISD::VECREDUCE_UMIN:
- case ISD::VECREDUCE_FADD:
+ case ISD::VECREDUCE_FADD:
case ISD::VECREDUCE_FMAX:
case ISD::VECREDUCE_FMIN:
return LowerVECREDUCE(Op, DAG);
@@ -4400,21 +4400,21 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
return LowerDYNAMIC_STACKALLOC(Op, DAG);
case ISD::VSCALE:
return LowerVSCALE(Op, DAG);
- case ISD::ANY_EXTEND:
- case ISD::SIGN_EXTEND:
- case ISD::ZERO_EXTEND:
- return LowerFixedLengthVectorIntExtendToSVE(Op, DAG);
- case ISD::SIGN_EXTEND_INREG: {
- // Only custom lower when ExtraVT has a legal byte based element type.
- EVT ExtraVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
- EVT ExtraEltVT = ExtraVT.getVectorElementType();
- if ((ExtraEltVT != MVT::i8) && (ExtraEltVT != MVT::i16) &&
- (ExtraEltVT != MVT::i32) && (ExtraEltVT != MVT::i64))
- return SDValue();
-
- return LowerToPredicatedOp(Op, DAG,
- AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU);
- }
+ case ISD::ANY_EXTEND:
+ case ISD::SIGN_EXTEND:
+ case ISD::ZERO_EXTEND:
+ return LowerFixedLengthVectorIntExtendToSVE(Op, DAG);
+ case ISD::SIGN_EXTEND_INREG: {
+ // Only custom lower when ExtraVT has a legal byte based element type.
+ EVT ExtraVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
+ EVT ExtraEltVT = ExtraVT.getVectorElementType();
+ if ((ExtraEltVT != MVT::i8) && (ExtraEltVT != MVT::i16) &&
+ (ExtraEltVT != MVT::i32) && (ExtraEltVT != MVT::i64))
+ return SDValue();
+
+ return LowerToPredicatedOp(Op, DAG,
+ AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU);
+ }
case ISD::TRUNCATE:
return LowerTRUNCATE(Op, DAG);
case ISD::LOAD:
@@ -4422,49 +4422,49 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
return LowerFixedLengthVectorLoadToSVE(Op, DAG);
llvm_unreachable("Unexpected request to lower ISD::LOAD");
case ISD::ADD:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::ADD_PRED);
- case ISD::AND:
- return LowerToScalableOp(Op, DAG);
- case ISD::SUB:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::SUB_PRED);
- case ISD::FMAXNUM:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::FMAXNM_PRED);
- case ISD::FMINNUM:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::FMINNM_PRED);
- case ISD::VSELECT:
- return LowerFixedLengthVectorSelectToSVE(Op, DAG);
- case ISD::ABS:
- return LowerABS(Op, DAG);
- case ISD::BITREVERSE:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::BITREVERSE_MERGE_PASSTHRU,
- /*OverrideNEON=*/true);
- case ISD::BSWAP:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::BSWAP_MERGE_PASSTHRU);
- case ISD::CTLZ:
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::CTLZ_MERGE_PASSTHRU,
- /*OverrideNEON=*/true);
- case ISD::CTTZ:
- return LowerCTTZ(Op, DAG);
- }
-}
-
-bool AArch64TargetLowering::mergeStoresAfterLegalization(EVT VT) const {
- return !Subtarget->useSVEForFixedLengthVectors();
-}
-
-bool AArch64TargetLowering::useSVEForFixedLengthVectorVT(
- EVT VT, bool OverrideNEON) const {
- if (!Subtarget->useSVEForFixedLengthVectors())
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::ADD_PRED);
+ case ISD::AND:
+ return LowerToScalableOp(Op, DAG);
+ case ISD::SUB:
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::SUB_PRED);
+ case ISD::FMAXNUM:
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FMAXNM_PRED);
+ case ISD::FMINNUM:
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FMINNM_PRED);
+ case ISD::VSELECT:
+ return LowerFixedLengthVectorSelectToSVE(Op, DAG);
+ case ISD::ABS:
+ return LowerABS(Op, DAG);
+ case ISD::BITREVERSE:
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::BITREVERSE_MERGE_PASSTHRU,
+ /*OverrideNEON=*/true);
+ case ISD::BSWAP:
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::BSWAP_MERGE_PASSTHRU);
+ case ISD::CTLZ:
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::CTLZ_MERGE_PASSTHRU,
+ /*OverrideNEON=*/true);
+ case ISD::CTTZ:
+ return LowerCTTZ(Op, DAG);
+ }
+}
+
+bool AArch64TargetLowering::mergeStoresAfterLegalization(EVT VT) const {
+ return !Subtarget->useSVEForFixedLengthVectors();
+}
+
+bool AArch64TargetLowering::useSVEForFixedLengthVectorVT(
+ EVT VT, bool OverrideNEON) const {
+ if (!Subtarget->useSVEForFixedLengthVectors())
return false;
if (!VT.isFixedLengthVector())
return false;
- // Don't use SVE for vectors we cannot scalarize if required.
- switch (VT.getVectorElementType().getSimpleVT().SimpleTy) {
+ // Don't use SVE for vectors we cannot scalarize if required.
+ switch (VT.getVectorElementType().getSimpleVT().SimpleTy) {
// Fixed length predicates should be promoted to i8.
// NOTE: This is consistent with how NEON (and thus 64/128bit vectors) work.
- case MVT::i1:
+ case MVT::i1:
default:
return false;
case MVT::i8:
@@ -4477,16 +4477,16 @@ bool AArch64TargetLowering::useSVEForFixedLengthVectorVT(
break;
}
- // All SVE implementations support NEON sized vectors.
- if (OverrideNEON && (VT.is128BitVector() || VT.is64BitVector()))
- return true;
-
+ // All SVE implementations support NEON sized vectors.
+ if (OverrideNEON && (VT.is128BitVector() || VT.is64BitVector()))
+ return true;
+
// Ensure NEON MVTs only belong to a single register class.
- if (VT.getFixedSizeInBits() <= 128)
+ if (VT.getFixedSizeInBits() <= 128)
return false;
// Don't use SVE for types that don't fit.
- if (VT.getFixedSizeInBits() > Subtarget->getMinSVEVectorSizeInBits())
+ if (VT.getFixedSizeInBits() > Subtarget->getMinSVEVectorSizeInBits())
return false;
// TODO: Perhaps an artificial restriction, but worth having whilst getting
@@ -4586,9 +4586,9 @@ SDValue AArch64TargetLowering::LowerFormalArguments(
(void)Res;
}
SmallVector<SDValue, 16> ArgValues;
- unsigned ExtraArgLocs = 0;
- for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
- CCValAssign &VA = ArgLocs[i - ExtraArgLocs];
+ unsigned ExtraArgLocs = 0;
+ for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
+ CCValAssign &VA = ArgLocs[i - ExtraArgLocs];
if (Ins[i].Flags.isByVal()) {
// Byval is used for HFAs in the PCS, but the system should work in a
@@ -4716,44 +4716,44 @@ SDValue AArch64TargetLowering::LowerFormalArguments(
if (VA.getLocInfo() == CCValAssign::Indirect) {
assert(VA.getValVT().isScalableVector() &&
"Only scalable vectors can be passed indirectly");
-
- uint64_t PartSize = VA.getValVT().getStoreSize().getKnownMinSize();
- unsigned NumParts = 1;
- if (Ins[i].Flags.isInConsecutiveRegs()) {
- assert(!Ins[i].Flags.isInConsecutiveRegsLast());
- while (!Ins[i + NumParts - 1].Flags.isInConsecutiveRegsLast())
- ++NumParts;
- }
-
- MVT PartLoad = VA.getValVT();
- SDValue Ptr = ArgValue;
-
- // Ensure we generate all loads for each tuple part, whilst updating the
- // pointer after each load correctly using vscale.
- while (NumParts > 0) {
- ArgValue = DAG.getLoad(PartLoad, DL, Chain, Ptr, MachinePointerInfo());
- InVals.push_back(ArgValue);
- NumParts--;
- if (NumParts > 0) {
- SDValue BytesIncrement = DAG.getVScale(
- DL, Ptr.getValueType(),
- APInt(Ptr.getValueSizeInBits().getFixedSize(), PartSize));
- SDNodeFlags Flags;
- Flags.setNoUnsignedWrap(true);
- Ptr = DAG.getNode(ISD::ADD, DL, Ptr.getValueType(), Ptr,
- BytesIncrement, Flags);
- ExtraArgLocs++;
- i++;
- }
- }
- } else {
- if (Subtarget->isTargetILP32() && Ins[i].Flags.isPointer())
- ArgValue = DAG.getNode(ISD::AssertZext, DL, ArgValue.getValueType(),
- ArgValue, DAG.getValueType(MVT::i32));
- InVals.push_back(ArgValue);
+
+ uint64_t PartSize = VA.getValVT().getStoreSize().getKnownMinSize();
+ unsigned NumParts = 1;
+ if (Ins[i].Flags.isInConsecutiveRegs()) {
+ assert(!Ins[i].Flags.isInConsecutiveRegsLast());
+ while (!Ins[i + NumParts - 1].Flags.isInConsecutiveRegsLast())
+ ++NumParts;
+ }
+
+ MVT PartLoad = VA.getValVT();
+ SDValue Ptr = ArgValue;
+
+ // Ensure we generate all loads for each tuple part, whilst updating the
+ // pointer after each load correctly using vscale.
+ while (NumParts > 0) {
+ ArgValue = DAG.getLoad(PartLoad, DL, Chain, Ptr, MachinePointerInfo());
+ InVals.push_back(ArgValue);
+ NumParts--;
+ if (NumParts > 0) {
+ SDValue BytesIncrement = DAG.getVScale(
+ DL, Ptr.getValueType(),
+ APInt(Ptr.getValueSizeInBits().getFixedSize(), PartSize));
+ SDNodeFlags Flags;
+ Flags.setNoUnsignedWrap(true);
+ Ptr = DAG.getNode(ISD::ADD, DL, Ptr.getValueType(), Ptr,
+ BytesIncrement, Flags);
+ ExtraArgLocs++;
+ i++;
+ }
+ }
+ } else {
+ if (Subtarget->isTargetILP32() && Ins[i].Flags.isPointer())
+ ArgValue = DAG.getNode(ISD::AssertZext, DL, ArgValue.getValueType(),
+ ArgValue, DAG.getValueType(MVT::i32));
+ InVals.push_back(ArgValue);
}
}
- assert((ArgLocs.size() + ExtraArgLocs) == Ins.size());
+ assert((ArgLocs.size() + ExtraArgLocs) == Ins.size());
// varargs
AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
@@ -4928,7 +4928,7 @@ SDValue AArch64TargetLowering::LowerCallResult(
const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, bool isThisReturn,
SDValue ThisVal) const {
- CCAssignFn *RetCC = CCAssignFnForReturn(CallConv);
+ CCAssignFn *RetCC = CCAssignFnForReturn(CallConv);
// Assign locations to each value returned by this call.
SmallVector<CCValAssign, 16> RVLocs;
DenseMap<unsigned, SDValue> CopiedRegs;
@@ -5351,9 +5351,9 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
}
// Walk the register/memloc assignments, inserting copies/loads.
- unsigned ExtraArgLocs = 0;
- for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
- CCValAssign &VA = ArgLocs[i - ExtraArgLocs];
+ unsigned ExtraArgLocs = 0;
+ for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
+ CCValAssign &VA = ArgLocs[i - ExtraArgLocs];
SDValue Arg = OutVals[i];
ISD::ArgFlagsTy Flags = Outs[i].Flags;
@@ -5395,49 +5395,49 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
case CCValAssign::Indirect:
assert(VA.getValVT().isScalableVector() &&
"Only scalable vectors can be passed indirectly");
-
- uint64_t StoreSize = VA.getValVT().getStoreSize().getKnownMinSize();
- uint64_t PartSize = StoreSize;
- unsigned NumParts = 1;
- if (Outs[i].Flags.isInConsecutiveRegs()) {
- assert(!Outs[i].Flags.isInConsecutiveRegsLast());
- while (!Outs[i + NumParts - 1].Flags.isInConsecutiveRegsLast())
- ++NumParts;
- StoreSize *= NumParts;
- }
-
+
+ uint64_t StoreSize = VA.getValVT().getStoreSize().getKnownMinSize();
+ uint64_t PartSize = StoreSize;
+ unsigned NumParts = 1;
+ if (Outs[i].Flags.isInConsecutiveRegs()) {
+ assert(!Outs[i].Flags.isInConsecutiveRegsLast());
+ while (!Outs[i + NumParts - 1].Flags.isInConsecutiveRegsLast())
+ ++NumParts;
+ StoreSize *= NumParts;
+ }
+
MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
Type *Ty = EVT(VA.getValVT()).getTypeForEVT(*DAG.getContext());
Align Alignment = DAG.getDataLayout().getPrefTypeAlign(Ty);
- int FI = MFI.CreateStackObject(StoreSize, Alignment, false);
- MFI.setStackID(FI, TargetStackID::ScalableVector);
+ int FI = MFI.CreateStackObject(StoreSize, Alignment, false);
+ MFI.setStackID(FI, TargetStackID::ScalableVector);
- MachinePointerInfo MPI =
- MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI);
- SDValue Ptr = DAG.getFrameIndex(
+ MachinePointerInfo MPI =
+ MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI);
+ SDValue Ptr = DAG.getFrameIndex(
FI, DAG.getTargetLoweringInfo().getFrameIndexTy(DAG.getDataLayout()));
- SDValue SpillSlot = Ptr;
-
- // Ensure we generate all stores for each tuple part, whilst updating the
- // pointer after each store correctly using vscale.
- while (NumParts) {
- Chain = DAG.getStore(Chain, DL, OutVals[i], Ptr, MPI);
- NumParts--;
- if (NumParts > 0) {
- SDValue BytesIncrement = DAG.getVScale(
- DL, Ptr.getValueType(),
- APInt(Ptr.getValueSizeInBits().getFixedSize(), PartSize));
- SDNodeFlags Flags;
- Flags.setNoUnsignedWrap(true);
-
- MPI = MachinePointerInfo(MPI.getAddrSpace());
- Ptr = DAG.getNode(ISD::ADD, DL, Ptr.getValueType(), Ptr,
- BytesIncrement, Flags);
- ExtraArgLocs++;
- i++;
- }
- }
-
+ SDValue SpillSlot = Ptr;
+
+ // Ensure we generate all stores for each tuple part, whilst updating the
+ // pointer after each store correctly using vscale.
+ while (NumParts) {
+ Chain = DAG.getStore(Chain, DL, OutVals[i], Ptr, MPI);
+ NumParts--;
+ if (NumParts > 0) {
+ SDValue BytesIncrement = DAG.getVScale(
+ DL, Ptr.getValueType(),
+ APInt(Ptr.getValueSizeInBits().getFixedSize(), PartSize));
+ SDNodeFlags Flags;
+ Flags.setNoUnsignedWrap(true);
+
+ MPI = MachinePointerInfo(MPI.getAddrSpace());
+ Ptr = DAG.getNode(ISD::ADD, DL, Ptr.getValueType(), Ptr,
+ BytesIncrement, Flags);
+ ExtraArgLocs++;
+ i++;
+ }
+ }
+
Arg = SpillSlot;
break;
}
@@ -5457,18 +5457,18 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
// take care of putting the two halves in the right place but we have to
// combine them.
SDValue &Bits =
- llvm::find_if(RegsToPass,
- [=](const std::pair<unsigned, SDValue> &Elt) {
- return Elt.first == VA.getLocReg();
- })
+ llvm::find_if(RegsToPass,
+ [=](const std::pair<unsigned, SDValue> &Elt) {
+ return Elt.first == VA.getLocReg();
+ })
->second;
Bits = DAG.getNode(ISD::OR, DL, Bits.getValueType(), Bits, Arg);
// Call site info is used for function's parameter entry value
// tracking. For now we track only simple cases when parameter
// is transferred through whole register.
- llvm::erase_if(CSInfo, [&VA](MachineFunction::ArgRegPair ArgReg) {
- return ArgReg.Reg == VA.getLocReg();
- });
+ llvm::erase_if(CSInfo, [&VA](MachineFunction::ArgRegPair ArgReg) {
+ return ArgReg.Reg == VA.getLocReg();
+ });
} else {
RegsToPass.emplace_back(VA.getLocReg(), Arg);
RegsUsed.insert(VA.getLocReg());
@@ -5487,7 +5487,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
uint32_t BEAlign = 0;
unsigned OpSize;
if (VA.getLocInfo() == CCValAssign::Indirect)
- OpSize = VA.getLocVT().getFixedSizeInBits();
+ OpSize = VA.getLocVT().getFixedSizeInBits();
else
OpSize = Flags.isByVal() ? Flags.getByValSize() * 8
: VA.getValVT().getSizeInBits();
@@ -5647,17 +5647,17 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
return Ret;
}
- unsigned CallOpc = AArch64ISD::CALL;
- // Calls marked with "rv_marker" are special. They should be expanded to the
- // call, directly followed by a special marker sequence. Use the CALL_RVMARKER
- // to do that.
- if (CLI.CB && CLI.CB->hasRetAttr("rv_marker")) {
- assert(!IsTailCall && "tail calls cannot be marked with rv_marker");
- CallOpc = AArch64ISD::CALL_RVMARKER;
- }
-
+ unsigned CallOpc = AArch64ISD::CALL;
+ // Calls marked with "rv_marker" are special. They should be expanded to the
+ // call, directly followed by a special marker sequence. Use the CALL_RVMARKER
+ // to do that.
+ if (CLI.CB && CLI.CB->hasRetAttr("rv_marker")) {
+ assert(!IsTailCall && "tail calls cannot be marked with rv_marker");
+ CallOpc = AArch64ISD::CALL_RVMARKER;
+ }
+
// Returns a chain and a flag for retval copy to use.
- Chain = DAG.getNode(CallOpc, DL, NodeTys, Ops);
+ Chain = DAG.getNode(CallOpc, DL, NodeTys, Ops);
DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
InFlag = Chain.getValue(1);
DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
@@ -5681,7 +5681,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
bool AArch64TargetLowering::CanLowerReturn(
CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
- CCAssignFn *RetCC = CCAssignFnForReturn(CallConv);
+ CCAssignFn *RetCC = CCAssignFnForReturn(CallConv);
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
return CCInfo.CheckReturn(Outs, RetCC);
@@ -5696,7 +5696,7 @@ AArch64TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
auto &MF = DAG.getMachineFunction();
auto *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
- CCAssignFn *RetCC = CCAssignFnForReturn(CallConv);
+ CCAssignFn *RetCC = CCAssignFnForReturn(CallConv);
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
*DAG.getContext());
@@ -5741,9 +5741,9 @@ AArch64TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
if (RegsUsed.count(VA.getLocReg())) {
SDValue &Bits =
- llvm::find_if(RetVals, [=](const std::pair<unsigned, SDValue> &Elt) {
- return Elt.first == VA.getLocReg();
- })->second;
+ llvm::find_if(RetVals, [=](const std::pair<unsigned, SDValue> &Elt) {
+ return Elt.first == VA.getLocReg();
+ })->second;
Bits = DAG.getNode(ISD::OR, DL, Bits.getValueType(), Bits, Arg);
} else {
RetVals.emplace_back(VA.getLocReg(), Arg);
@@ -5963,7 +5963,7 @@ AArch64TargetLowering::LowerDarwinGlobalTLSAddress(SDValue Op,
SDValue FuncTLVGet = DAG.getLoad(
PtrMemVT, DL, Chain, DescAddr,
MachinePointerInfo::getGOT(DAG.getMachineFunction()),
- Align(PtrMemVT.getSizeInBits() / 8),
+ Align(PtrMemVT.getSizeInBits() / 8),
MachineMemOperand::MOInvariant | MachineMemOperand::MODereferenceable);
Chain = FuncTLVGet.getValue(1);
@@ -6278,22 +6278,22 @@ SDValue AArch64TargetLowering::LowerGlobalTLSAddress(SDValue Op,
llvm_unreachable("Unexpected platform trying to use TLS");
}
-// Looks through \param Val to determine the bit that can be used to
-// check the sign of the value. It returns the unextended value and
-// the sign bit position.
-std::pair<SDValue, uint64_t> lookThroughSignExtension(SDValue Val) {
- if (Val.getOpcode() == ISD::SIGN_EXTEND_INREG)
- return {Val.getOperand(0),
- cast<VTSDNode>(Val.getOperand(1))->getVT().getFixedSizeInBits() -
- 1};
-
- if (Val.getOpcode() == ISD::SIGN_EXTEND)
- return {Val.getOperand(0),
- Val.getOperand(0)->getValueType(0).getFixedSizeInBits() - 1};
-
- return {Val, Val.getValueSizeInBits() - 1};
-}
-
+// Looks through \param Val to determine the bit that can be used to
+// check the sign of the value. It returns the unextended value and
+// the sign bit position.
+std::pair<SDValue, uint64_t> lookThroughSignExtension(SDValue Val) {
+ if (Val.getOpcode() == ISD::SIGN_EXTEND_INREG)
+ return {Val.getOperand(0),
+ cast<VTSDNode>(Val.getOperand(1))->getVT().getFixedSizeInBits() -
+ 1};
+
+ if (Val.getOpcode() == ISD::SIGN_EXTEND)
+ return {Val.getOperand(0),
+ Val.getOperand(0)->getValueType(0).getFixedSizeInBits() - 1};
+
+ return {Val, Val.getValueSizeInBits() - 1};
+}
+
SDValue AArch64TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
SDValue Chain = Op.getOperand(0);
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
@@ -6388,10 +6388,10 @@ SDValue AArch64TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
// Don't combine AND since emitComparison converts the AND to an ANDS
// (a.k.a. TST) and the test in the test bit and branch instruction
// becomes redundant. This would also increase register pressure.
- uint64_t SignBitPos;
- std::tie(LHS, SignBitPos) = lookThroughSignExtension(LHS);
+ uint64_t SignBitPos;
+ std::tie(LHS, SignBitPos) = lookThroughSignExtension(LHS);
return DAG.getNode(AArch64ISD::TBNZ, dl, MVT::Other, Chain, LHS,
- DAG.getConstant(SignBitPos, dl, MVT::i64), Dest);
+ DAG.getConstant(SignBitPos, dl, MVT::i64), Dest);
}
}
if (RHSC && RHSC->getSExtValue() == -1 && CC == ISD::SETGT &&
@@ -6399,10 +6399,10 @@ SDValue AArch64TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
// Don't combine AND since emitComparison converts the AND to an ANDS
// (a.k.a. TST) and the test in the test bit and branch instruction
// becomes redundant. This would also increase register pressure.
- uint64_t SignBitPos;
- std::tie(LHS, SignBitPos) = lookThroughSignExtension(LHS);
+ uint64_t SignBitPos;
+ std::tie(LHS, SignBitPos) = lookThroughSignExtension(LHS);
return DAG.getNode(AArch64ISD::TBZ, dl, MVT::Other, Chain, LHS,
- DAG.getConstant(SignBitPos, dl, MVT::i64), Dest);
+ DAG.getConstant(SignBitPos, dl, MVT::i64), Dest);
}
SDValue CCVal;
@@ -6549,9 +6549,9 @@ SDValue AArch64TargetLowering::LowerCTPOP(SDValue Op, SelectionDAG &DAG) const {
return DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i128, UaddLV);
}
- if (VT.isScalableVector() || useSVEForFixedLengthVectorVT(VT))
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::CTPOP_MERGE_PASSTHRU);
-
+ if (VT.isScalableVector() || useSVEForFixedLengthVectorVT(VT))
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::CTPOP_MERGE_PASSTHRU);
+
assert((VT == MVT::v1i64 || VT == MVT::v2i64 || VT == MVT::v2i32 ||
VT == MVT::v4i32 || VT == MVT::v4i16 || VT == MVT::v8i16) &&
"Unexpected type for custom ctpop lowering");
@@ -6575,16 +6575,16 @@ SDValue AArch64TargetLowering::LowerCTPOP(SDValue Op, SelectionDAG &DAG) const {
return Val;
}
-SDValue AArch64TargetLowering::LowerCTTZ(SDValue Op, SelectionDAG &DAG) const {
- EVT VT = Op.getValueType();
- assert(VT.isScalableVector() ||
- useSVEForFixedLengthVectorVT(VT, /*OverrideNEON=*/true));
-
- SDLoc DL(Op);
- SDValue RBIT = DAG.getNode(ISD::BITREVERSE, DL, VT, Op.getOperand(0));
- return DAG.getNode(ISD::CTLZ, DL, VT, RBIT);
-}
-
+SDValue AArch64TargetLowering::LowerCTTZ(SDValue Op, SelectionDAG &DAG) const {
+ EVT VT = Op.getValueType();
+ assert(VT.isScalableVector() ||
+ useSVEForFixedLengthVectorVT(VT, /*OverrideNEON=*/true));
+
+ SDLoc DL(Op);
+ SDValue RBIT = DAG.getNode(ISD::BITREVERSE, DL, VT, Op.getOperand(0));
+ return DAG.getNode(ISD::CTLZ, DL, VT, RBIT);
+}
+
SDValue AArch64TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
if (Op.getValueType().isVector())
@@ -6742,8 +6742,8 @@ SDValue AArch64TargetLowering::LowerSELECT_CC(ISD::CondCode CC, SDValue LHS,
// instead of a CSEL in that case.
if (TrueVal == ~FalseVal) {
Opcode = AArch64ISD::CSINV;
- } else if (FalseVal > std::numeric_limits<int64_t>::min() &&
- TrueVal == -FalseVal) {
+ } else if (FalseVal > std::numeric_limits<int64_t>::min() &&
+ TrueVal == -FalseVal) {
Opcode = AArch64ISD::CSNEG;
} else if (TVal.getValueType() == MVT::i32) {
// If our operands are only 32-bit wide, make sure we use 32-bit
@@ -6943,9 +6943,9 @@ SDValue AArch64TargetLowering::LowerBR_JT(SDValue Op,
SDValue Entry = Op.getOperand(2);
int JTI = cast<JumpTableSDNode>(JT.getNode())->getIndex();
- auto *AFI = DAG.getMachineFunction().getInfo<AArch64FunctionInfo>();
- AFI->setJumpTableEntryInfo(JTI, 4, nullptr);
-
+ auto *AFI = DAG.getMachineFunction().getInfo<AArch64FunctionInfo>();
+ AFI->setJumpTableEntryInfo(JTI, 4, nullptr);
+
SDNode *Dest =
DAG.getMachineNode(AArch64::JumpTableDest32, DL, MVT::i64, MVT::i64, JT,
Entry, DAG.getTargetJumpTable(JTI, MVT::i32));
@@ -7012,13 +7012,13 @@ SDValue AArch64TargetLowering::LowerWin64_VASTART(SDValue Op,
}
SDValue AArch64TargetLowering::LowerAAPCS_VASTART(SDValue Op,
- SelectionDAG &DAG) const {
+ SelectionDAG &DAG) const {
// The layout of the va_list struct is specified in the AArch64 Procedure Call
// Standard, section B.3.
MachineFunction &MF = DAG.getMachineFunction();
AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
- unsigned PtrSize = Subtarget->isTargetILP32() ? 4 : 8;
- auto PtrMemVT = getPointerMemTy(DAG.getDataLayout());
+ unsigned PtrSize = Subtarget->isTargetILP32() ? 4 : 8;
+ auto PtrMemVT = getPointerMemTy(DAG.getDataLayout());
auto PtrVT = getPointerTy(DAG.getDataLayout());
SDLoc DL(Op);
@@ -7028,64 +7028,64 @@ SDValue AArch64TargetLowering::LowerAAPCS_VASTART(SDValue Op,
SmallVector<SDValue, 4> MemOps;
// void *__stack at offset 0
- unsigned Offset = 0;
+ unsigned Offset = 0;
SDValue Stack = DAG.getFrameIndex(FuncInfo->getVarArgsStackIndex(), PtrVT);
- Stack = DAG.getZExtOrTrunc(Stack, DL, PtrMemVT);
+ Stack = DAG.getZExtOrTrunc(Stack, DL, PtrMemVT);
MemOps.push_back(DAG.getStore(Chain, DL, Stack, VAList,
- MachinePointerInfo(SV), Align(PtrSize)));
+ MachinePointerInfo(SV), Align(PtrSize)));
- // void *__gr_top at offset 8 (4 on ILP32)
- Offset += PtrSize;
+ // void *__gr_top at offset 8 (4 on ILP32)
+ Offset += PtrSize;
int GPRSize = FuncInfo->getVarArgsGPRSize();
if (GPRSize > 0) {
SDValue GRTop, GRTopAddr;
- GRTopAddr = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,
- DAG.getConstant(Offset, DL, PtrVT));
+ GRTopAddr = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,
+ DAG.getConstant(Offset, DL, PtrVT));
GRTop = DAG.getFrameIndex(FuncInfo->getVarArgsGPRIndex(), PtrVT);
GRTop = DAG.getNode(ISD::ADD, DL, PtrVT, GRTop,
DAG.getConstant(GPRSize, DL, PtrVT));
- GRTop = DAG.getZExtOrTrunc(GRTop, DL, PtrMemVT);
+ GRTop = DAG.getZExtOrTrunc(GRTop, DL, PtrMemVT);
MemOps.push_back(DAG.getStore(Chain, DL, GRTop, GRTopAddr,
- MachinePointerInfo(SV, Offset),
- Align(PtrSize)));
+ MachinePointerInfo(SV, Offset),
+ Align(PtrSize)));
}
- // void *__vr_top at offset 16 (8 on ILP32)
- Offset += PtrSize;
+ // void *__vr_top at offset 16 (8 on ILP32)
+ Offset += PtrSize;
int FPRSize = FuncInfo->getVarArgsFPRSize();
if (FPRSize > 0) {
SDValue VRTop, VRTopAddr;
VRTopAddr = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,
- DAG.getConstant(Offset, DL, PtrVT));
+ DAG.getConstant(Offset, DL, PtrVT));
VRTop = DAG.getFrameIndex(FuncInfo->getVarArgsFPRIndex(), PtrVT);
VRTop = DAG.getNode(ISD::ADD, DL, PtrVT, VRTop,
DAG.getConstant(FPRSize, DL, PtrVT));
- VRTop = DAG.getZExtOrTrunc(VRTop, DL, PtrMemVT);
+ VRTop = DAG.getZExtOrTrunc(VRTop, DL, PtrMemVT);
MemOps.push_back(DAG.getStore(Chain, DL, VRTop, VRTopAddr,
- MachinePointerInfo(SV, Offset),
- Align(PtrSize)));
- }
-
- // int __gr_offs at offset 24 (12 on ILP32)
- Offset += PtrSize;
- SDValue GROffsAddr = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,
- DAG.getConstant(Offset, DL, PtrVT));
- MemOps.push_back(
- DAG.getStore(Chain, DL, DAG.getConstant(-GPRSize, DL, MVT::i32),
- GROffsAddr, MachinePointerInfo(SV, Offset), Align(4)));
-
- // int __vr_offs at offset 28 (16 on ILP32)
- Offset += 4;
- SDValue VROffsAddr = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,
- DAG.getConstant(Offset, DL, PtrVT));
- MemOps.push_back(
- DAG.getStore(Chain, DL, DAG.getConstant(-FPRSize, DL, MVT::i32),
- VROffsAddr, MachinePointerInfo(SV, Offset), Align(4)));
+ MachinePointerInfo(SV, Offset),
+ Align(PtrSize)));
+ }
+
+ // int __gr_offs at offset 24 (12 on ILP32)
+ Offset += PtrSize;
+ SDValue GROffsAddr = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,
+ DAG.getConstant(Offset, DL, PtrVT));
+ MemOps.push_back(
+ DAG.getStore(Chain, DL, DAG.getConstant(-GPRSize, DL, MVT::i32),
+ GROffsAddr, MachinePointerInfo(SV, Offset), Align(4)));
+
+ // int __vr_offs at offset 28 (16 on ILP32)
+ Offset += 4;
+ SDValue VROffsAddr = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,
+ DAG.getConstant(Offset, DL, PtrVT));
+ MemOps.push_back(
+ DAG.getStore(Chain, DL, DAG.getConstant(-FPRSize, DL, MVT::i32),
+ VROffsAddr, MachinePointerInfo(SV, Offset), Align(4)));
return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOps);
}
@@ -7108,10 +7108,10 @@ SDValue AArch64TargetLowering::LowerVACOPY(SDValue Op,
// pointer.
SDLoc DL(Op);
unsigned PtrSize = Subtarget->isTargetILP32() ? 4 : 8;
- unsigned VaListSize =
- (Subtarget->isTargetDarwin() || Subtarget->isTargetWindows())
- ? PtrSize
- : Subtarget->isTargetILP32() ? 20 : 32;
+ unsigned VaListSize =
+ (Subtarget->isTargetDarwin() || Subtarget->isTargetWindows())
+ ? PtrSize
+ : Subtarget->isTargetILP32() ? 20 : 32;
const Value *DestSV = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();
const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
@@ -7264,34 +7264,34 @@ SDValue AArch64TargetLowering::LowerRETURNADDR(SDValue Op,
EVT VT = Op.getValueType();
SDLoc DL(Op);
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
- SDValue ReturnAddress;
+ SDValue ReturnAddress;
if (Depth) {
SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
SDValue Offset = DAG.getConstant(8, DL, getPointerTy(DAG.getDataLayout()));
- ReturnAddress = DAG.getLoad(
- VT, DL, DAG.getEntryNode(),
- DAG.getNode(ISD::ADD, DL, VT, FrameAddr, Offset), MachinePointerInfo());
- } else {
- // Return LR, which contains the return address. Mark it an implicit
- // live-in.
- unsigned Reg = MF.addLiveIn(AArch64::LR, &AArch64::GPR64RegClass);
- ReturnAddress = DAG.getCopyFromReg(DAG.getEntryNode(), DL, Reg, VT);
- }
-
- // The XPACLRI instruction assembles to a hint-space instruction before
- // Armv8.3-A therefore this instruction can be safely used for any pre
- // Armv8.3-A architectures. On Armv8.3-A and onwards XPACI is available so use
- // that instead.
- SDNode *St;
- if (Subtarget->hasPAuth()) {
- St = DAG.getMachineNode(AArch64::XPACI, DL, VT, ReturnAddress);
- } else {
- // XPACLRI operates on LR therefore we must move the operand accordingly.
- SDValue Chain =
- DAG.getCopyToReg(DAG.getEntryNode(), DL, AArch64::LR, ReturnAddress);
- St = DAG.getMachineNode(AArch64::XPACLRI, DL, VT, Chain);
- }
- return SDValue(St, 0);
+ ReturnAddress = DAG.getLoad(
+ VT, DL, DAG.getEntryNode(),
+ DAG.getNode(ISD::ADD, DL, VT, FrameAddr, Offset), MachinePointerInfo());
+ } else {
+ // Return LR, which contains the return address. Mark it an implicit
+ // live-in.
+ unsigned Reg = MF.addLiveIn(AArch64::LR, &AArch64::GPR64RegClass);
+ ReturnAddress = DAG.getCopyFromReg(DAG.getEntryNode(), DL, Reg, VT);
+ }
+
+ // The XPACLRI instruction assembles to a hint-space instruction before
+ // Armv8.3-A therefore this instruction can be safely used for any pre
+ // Armv8.3-A architectures. On Armv8.3-A and onwards XPACI is available so use
+ // that instead.
+ SDNode *St;
+ if (Subtarget->hasPAuth()) {
+ St = DAG.getMachineNode(AArch64::XPACI, DL, VT, ReturnAddress);
+ } else {
+ // XPACLRI operates on LR therefore we must move the operand accordingly.
+ SDValue Chain =
+ DAG.getCopyToReg(DAG.getEntryNode(), DL, AArch64::LR, ReturnAddress);
+ St = DAG.getMachineNode(AArch64::XPACLRI, DL, VT, Chain);
+ }
+ return SDValue(St, 0);
}
/// LowerShiftRightParts - Lower SRA_PARTS, which returns two
@@ -7472,22 +7472,22 @@ static SDValue getEstimate(const AArch64Subtarget *ST, unsigned Opcode,
return SDValue();
}
-SDValue
-AArch64TargetLowering::getSqrtInputTest(SDValue Op, SelectionDAG &DAG,
- const DenormalMode &Mode) const {
- SDLoc DL(Op);
- EVT VT = Op.getValueType();
- EVT CCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
- SDValue FPZero = DAG.getConstantFP(0.0, DL, VT);
- return DAG.getSetCC(DL, CCVT, Op, FPZero, ISD::SETEQ);
-}
-
-SDValue
-AArch64TargetLowering::getSqrtResultForDenormInput(SDValue Op,
- SelectionDAG &DAG) const {
- return Op;
-}
-
+SDValue
+AArch64TargetLowering::getSqrtInputTest(SDValue Op, SelectionDAG &DAG,
+ const DenormalMode &Mode) const {
+ SDLoc DL(Op);
+ EVT VT = Op.getValueType();
+ EVT CCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
+ SDValue FPZero = DAG.getConstantFP(0.0, DL, VT);
+ return DAG.getSetCC(DL, CCVT, Op, FPZero, ISD::SETEQ);
+}
+
+SDValue
+AArch64TargetLowering::getSqrtResultForDenormInput(SDValue Op,
+ SelectionDAG &DAG) const {
+ return Op;
+}
+
SDValue AArch64TargetLowering::getSqrtEstimate(SDValue Operand,
SelectionDAG &DAG, int Enabled,
int &ExtraSteps,
@@ -7511,7 +7511,7 @@ SDValue AArch64TargetLowering::getSqrtEstimate(SDValue Operand,
Step = DAG.getNode(AArch64ISD::FRSQRTS, DL, VT, Operand, Step, Flags);
Estimate = DAG.getNode(ISD::FMUL, DL, VT, Estimate, Step, Flags);
}
- if (!Reciprocal)
+ if (!Reciprocal)
Estimate = DAG.getNode(ISD::FMUL, DL, VT, Operand, Estimate, Flags);
ExtraSteps = 0;
@@ -7688,30 +7688,30 @@ AArch64TargetLowering::getRegForInlineAsmConstraint(
if (Constraint.size() == 1) {
switch (Constraint[0]) {
case 'r':
- if (VT.isScalableVector())
- return std::make_pair(0U, nullptr);
- if (VT.getFixedSizeInBits() == 64)
+ if (VT.isScalableVector())
+ return std::make_pair(0U, nullptr);
+ if (VT.getFixedSizeInBits() == 64)
return std::make_pair(0U, &AArch64::GPR64commonRegClass);
return std::make_pair(0U, &AArch64::GPR32commonRegClass);
- case 'w': {
+ case 'w': {
if (!Subtarget->hasFPARMv8())
break;
- if (VT.isScalableVector()) {
- if (VT.getVectorElementType() != MVT::i1)
- return std::make_pair(0U, &AArch64::ZPRRegClass);
- return std::make_pair(0U, nullptr);
- }
- uint64_t VTSize = VT.getFixedSizeInBits();
- if (VTSize == 16)
+ if (VT.isScalableVector()) {
+ if (VT.getVectorElementType() != MVT::i1)
+ return std::make_pair(0U, &AArch64::ZPRRegClass);
+ return std::make_pair(0U, nullptr);
+ }
+ uint64_t VTSize = VT.getFixedSizeInBits();
+ if (VTSize == 16)
return std::make_pair(0U, &AArch64::FPR16RegClass);
- if (VTSize == 32)
+ if (VTSize == 32)
return std::make_pair(0U, &AArch64::FPR32RegClass);
- if (VTSize == 64)
+ if (VTSize == 64)
return std::make_pair(0U, &AArch64::FPR64RegClass);
- if (VTSize == 128)
+ if (VTSize == 128)
return std::make_pair(0U, &AArch64::FPR128RegClass);
break;
- }
+ }
// The instructions that this constraint is designed for can
// only take 128-bit registers so just use that regclass.
case 'x':
@@ -7732,11 +7732,11 @@ AArch64TargetLowering::getRegForInlineAsmConstraint(
} else {
PredicateConstraint PC = parsePredicateConstraint(Constraint);
if (PC != PredicateConstraint::Invalid) {
- if (!VT.isScalableVector() || VT.getVectorElementType() != MVT::i1)
- return std::make_pair(0U, nullptr);
+ if (!VT.isScalableVector() || VT.getVectorElementType() != MVT::i1)
+ return std::make_pair(0U, nullptr);
bool restricted = (PC == PredicateConstraint::Upl);
return restricted ? std::make_pair(0U, &AArch64::PPR_3bRegClass)
- : std::make_pair(0U, &AArch64::PPRRegClass);
+ : std::make_pair(0U, &AArch64::PPRRegClass);
}
}
if (StringRef("{cc}").equals_lower(Constraint))
@@ -7975,8 +7975,8 @@ SDValue AArch64TargetLowering::ReconstructShuffle(SDValue Op,
LLVM_DEBUG(dbgs() << "AArch64TargetLowering::ReconstructShuffle\n");
SDLoc dl(Op);
EVT VT = Op.getValueType();
- assert(!VT.isScalableVector() &&
- "Scalable vectors cannot be used with ISD::BUILD_VECTOR");
+ assert(!VT.isScalableVector() &&
+ "Scalable vectors cannot be used with ISD::BUILD_VECTOR");
unsigned NumElts = VT.getVectorNumElements();
struct ShuffleSourceInfo {
@@ -8047,9 +8047,9 @@ SDValue AArch64TargetLowering::ReconstructShuffle(SDValue Op,
}
}
unsigned ResMultiplier =
- VT.getScalarSizeInBits() / SmallestEltTy.getFixedSizeInBits();
- uint64_t VTSize = VT.getFixedSizeInBits();
- NumElts = VTSize / SmallestEltTy.getFixedSizeInBits();
+ VT.getScalarSizeInBits() / SmallestEltTy.getFixedSizeInBits();
+ uint64_t VTSize = VT.getFixedSizeInBits();
+ NumElts = VTSize / SmallestEltTy.getFixedSizeInBits();
EVT ShuffleVT = EVT::getVectorVT(*DAG.getContext(), SmallestEltTy, NumElts);
// If the source vector is too wide or too narrow, we may nevertheless be able
@@ -8058,18 +8058,18 @@ SDValue AArch64TargetLowering::ReconstructShuffle(SDValue Op,
for (auto &Src : Sources) {
EVT SrcVT = Src.ShuffleVec.getValueType();
- uint64_t SrcVTSize = SrcVT.getFixedSizeInBits();
- if (SrcVTSize == VTSize)
+ uint64_t SrcVTSize = SrcVT.getFixedSizeInBits();
+ if (SrcVTSize == VTSize)
continue;
// This stage of the search produces a source with the same element type as
// the original, but with a total width matching the BUILD_VECTOR output.
EVT EltVT = SrcVT.getVectorElementType();
- unsigned NumSrcElts = VTSize / EltVT.getFixedSizeInBits();
+ unsigned NumSrcElts = VTSize / EltVT.getFixedSizeInBits();
EVT DestVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumSrcElts);
- if (SrcVTSize < VTSize) {
- assert(2 * SrcVTSize == VTSize);
+ if (SrcVTSize < VTSize) {
+ assert(2 * SrcVTSize == VTSize);
// We can pad out the smaller vector for free, so if it's part of a
// shuffle...
Src.ShuffleVec =
@@ -8078,11 +8078,11 @@ SDValue AArch64TargetLowering::ReconstructShuffle(SDValue Op,
continue;
}
- if (SrcVTSize != 2 * VTSize) {
- LLVM_DEBUG(
- dbgs() << "Reshuffle failed: result vector too small to extract\n");
- return SDValue();
- }
+ if (SrcVTSize != 2 * VTSize) {
+ LLVM_DEBUG(
+ dbgs() << "Reshuffle failed: result vector too small to extract\n");
+ return SDValue();
+ }
if (Src.MaxElt - Src.MinElt >= NumSrcElts) {
LLVM_DEBUG(
@@ -8111,13 +8111,13 @@ SDValue AArch64TargetLowering::ReconstructShuffle(SDValue Op,
DAG.getConstant(NumSrcElts, dl, MVT::i64));
unsigned Imm = Src.MinElt * getExtFactor(VEXTSrc1);
- if (!SrcVT.is64BitVector()) {
- LLVM_DEBUG(
- dbgs() << "Reshuffle failed: don't know how to lower AArch64ISD::EXT "
- "for SVE vectors.");
- return SDValue();
- }
-
+ if (!SrcVT.is64BitVector()) {
+ LLVM_DEBUG(
+ dbgs() << "Reshuffle failed: don't know how to lower AArch64ISD::EXT "
+ "for SVE vectors.");
+ return SDValue();
+ }
+
Src.ShuffleVec = DAG.getNode(AArch64ISD::EXT, dl, DestVT, VEXTSrc1,
VEXTSrc2,
DAG.getConstant(Imm, dl, MVT::i32));
@@ -8134,8 +8134,8 @@ SDValue AArch64TargetLowering::ReconstructShuffle(SDValue Op,
continue;
assert(ShuffleVT.getVectorElementType() == SmallestEltTy);
Src.ShuffleVec = DAG.getNode(ISD::BITCAST, dl, ShuffleVT, Src.ShuffleVec);
- Src.WindowScale =
- SrcEltTy.getFixedSizeInBits() / SmallestEltTy.getFixedSizeInBits();
+ Src.WindowScale =
+ SrcEltTy.getFixedSizeInBits() / SmallestEltTy.getFixedSizeInBits();
Src.WindowBase *= Src.WindowScale;
}
@@ -8159,8 +8159,8 @@ SDValue AArch64TargetLowering::ReconstructShuffle(SDValue Op,
// trunc. So only std::min(SrcBits, DestBits) actually get defined in this
// segment.
EVT OrigEltTy = Entry.getOperand(0).getValueType().getVectorElementType();
- int BitsDefined = std::min(OrigEltTy.getScalarSizeInBits(),
- VT.getScalarSizeInBits());
+ int BitsDefined = std::min(OrigEltTy.getScalarSizeInBits(),
+ VT.getScalarSizeInBits());
int LanesDefined = BitsDefined / BitsPerShuffleLane;
// This source is expected to fill ResMultiplier lanes of the final shuffle,
@@ -8224,81 +8224,81 @@ static bool isSingletonEXTMask(ArrayRef<int> M, EVT VT, unsigned &Imm) {
return true;
}
-/// Check if a vector shuffle corresponds to a DUP instructions with a larger
-/// element width than the vector lane type. If that is the case the function
-/// returns true and writes the value of the DUP instruction lane operand into
-/// DupLaneOp
-static bool isWideDUPMask(ArrayRef<int> M, EVT VT, unsigned BlockSize,
- unsigned &DupLaneOp) {
- assert((BlockSize == 16 || BlockSize == 32 || BlockSize == 64) &&
- "Only possible block sizes for wide DUP are: 16, 32, 64");
-
- if (BlockSize <= VT.getScalarSizeInBits())
- return false;
- if (BlockSize % VT.getScalarSizeInBits() != 0)
- return false;
- if (VT.getSizeInBits() % BlockSize != 0)
- return false;
-
- size_t SingleVecNumElements = VT.getVectorNumElements();
- size_t NumEltsPerBlock = BlockSize / VT.getScalarSizeInBits();
- size_t NumBlocks = VT.getSizeInBits() / BlockSize;
-
- // We are looking for masks like
- // [0, 1, 0, 1] or [2, 3, 2, 3] or [4, 5, 6, 7, 4, 5, 6, 7] where any element
- // might be replaced by 'undefined'. BlockIndices will eventually contain
- // lane indices of the duplicated block (i.e. [0, 1], [2, 3] and [4, 5, 6, 7]
- // for the above examples)
- SmallVector<int, 8> BlockElts(NumEltsPerBlock, -1);
- for (size_t BlockIndex = 0; BlockIndex < NumBlocks; BlockIndex++)
- for (size_t I = 0; I < NumEltsPerBlock; I++) {
- int Elt = M[BlockIndex * NumEltsPerBlock + I];
- if (Elt < 0)
- continue;
- // For now we don't support shuffles that use the second operand
- if ((unsigned)Elt >= SingleVecNumElements)
- return false;
- if (BlockElts[I] < 0)
- BlockElts[I] = Elt;
- else if (BlockElts[I] != Elt)
- return false;
- }
-
- // We found a candidate block (possibly with some undefs). It must be a
- // sequence of consecutive integers starting with a value divisible by
- // NumEltsPerBlock with some values possibly replaced by undef-s.
-
- // Find first non-undef element
- auto FirstRealEltIter = find_if(BlockElts, [](int Elt) { return Elt >= 0; });
- assert(FirstRealEltIter != BlockElts.end() &&
- "Shuffle with all-undefs must have been caught by previous cases, "
- "e.g. isSplat()");
- if (FirstRealEltIter == BlockElts.end()) {
- DupLaneOp = 0;
- return true;
- }
-
- // Index of FirstRealElt in BlockElts
- size_t FirstRealIndex = FirstRealEltIter - BlockElts.begin();
-
- if ((unsigned)*FirstRealEltIter < FirstRealIndex)
- return false;
- // BlockElts[0] must have the following value if it isn't undef:
- size_t Elt0 = *FirstRealEltIter - FirstRealIndex;
-
- // Check the first element
- if (Elt0 % NumEltsPerBlock != 0)
- return false;
- // Check that the sequence indeed consists of consecutive integers (modulo
- // undefs)
- for (size_t I = 0; I < NumEltsPerBlock; I++)
- if (BlockElts[I] >= 0 && (unsigned)BlockElts[I] != Elt0 + I)
- return false;
-
- DupLaneOp = Elt0 / NumEltsPerBlock;
- return true;
-}
-
+/// Check if a vector shuffle corresponds to a DUP instructions with a larger
+/// element width than the vector lane type. If that is the case the function
+/// returns true and writes the value of the DUP instruction lane operand into
+/// DupLaneOp
+static bool isWideDUPMask(ArrayRef<int> M, EVT VT, unsigned BlockSize,
+ unsigned &DupLaneOp) {
+ assert((BlockSize == 16 || BlockSize == 32 || BlockSize == 64) &&
+ "Only possible block sizes for wide DUP are: 16, 32, 64");
+
+ if (BlockSize <= VT.getScalarSizeInBits())
+ return false;
+ if (BlockSize % VT.getScalarSizeInBits() != 0)
+ return false;
+ if (VT.getSizeInBits() % BlockSize != 0)
+ return false;
+
+ size_t SingleVecNumElements = VT.getVectorNumElements();
+ size_t NumEltsPerBlock = BlockSize / VT.getScalarSizeInBits();
+ size_t NumBlocks = VT.getSizeInBits() / BlockSize;
+
+ // We are looking for masks like
+ // [0, 1, 0, 1] or [2, 3, 2, 3] or [4, 5, 6, 7, 4, 5, 6, 7] where any element
+ // might be replaced by 'undefined'. BlockIndices will eventually contain
+ // lane indices of the duplicated block (i.e. [0, 1], [2, 3] and [4, 5, 6, 7]
+ // for the above examples)
+ SmallVector<int, 8> BlockElts(NumEltsPerBlock, -1);
+ for (size_t BlockIndex = 0; BlockIndex < NumBlocks; BlockIndex++)
+ for (size_t I = 0; I < NumEltsPerBlock; I++) {
+ int Elt = M[BlockIndex * NumEltsPerBlock + I];
+ if (Elt < 0)
+ continue;
+ // For now we don't support shuffles that use the second operand
+ if ((unsigned)Elt >= SingleVecNumElements)
+ return false;
+ if (BlockElts[I] < 0)
+ BlockElts[I] = Elt;
+ else if (BlockElts[I] != Elt)
+ return false;
+ }
+
+ // We found a candidate block (possibly with some undefs). It must be a
+ // sequence of consecutive integers starting with a value divisible by
+ // NumEltsPerBlock with some values possibly replaced by undef-s.
+
+ // Find first non-undef element
+ auto FirstRealEltIter = find_if(BlockElts, [](int Elt) { return Elt >= 0; });
+ assert(FirstRealEltIter != BlockElts.end() &&
+ "Shuffle with all-undefs must have been caught by previous cases, "
+ "e.g. isSplat()");
+ if (FirstRealEltIter == BlockElts.end()) {
+ DupLaneOp = 0;
+ return true;
+ }
+
+ // Index of FirstRealElt in BlockElts
+ size_t FirstRealIndex = FirstRealEltIter - BlockElts.begin();
+
+ if ((unsigned)*FirstRealEltIter < FirstRealIndex)
+ return false;
+ // BlockElts[0] must have the following value if it isn't undef:
+ size_t Elt0 = *FirstRealEltIter - FirstRealIndex;
+
+ // Check the first element
+ if (Elt0 % NumEltsPerBlock != 0)
+ return false;
+ // Check that the sequence indeed consists of consecutive integers (modulo
+ // undefs)
+ for (size_t I = 0; I < NumEltsPerBlock; I++)
+ if (BlockElts[I] >= 0 && (unsigned)BlockElts[I] != Elt0 + I)
+ return false;
+
+ DupLaneOp = Elt0 / NumEltsPerBlock;
+ return true;
+}
+
// check if an EXT instruction can handle the shuffle mask when the
// vector sources of the shuffle are different.
static bool isEXTMask(ArrayRef<int> M, EVT VT, bool &ReverseEXT,
@@ -8732,60 +8732,60 @@ static unsigned getDUPLANEOp(EVT EltType) {
llvm_unreachable("Invalid vector element type?");
}
-static SDValue constructDup(SDValue V, int Lane, SDLoc dl, EVT VT,
- unsigned Opcode, SelectionDAG &DAG) {
- // Try to eliminate a bitcasted extract subvector before a DUPLANE.
- auto getScaledOffsetDup = [](SDValue BitCast, int &LaneC, MVT &CastVT) {
- // Match: dup (bitcast (extract_subv X, C)), LaneC
- if (BitCast.getOpcode() != ISD::BITCAST ||
- BitCast.getOperand(0).getOpcode() != ISD::EXTRACT_SUBVECTOR)
- return false;
-
- // The extract index must align in the destination type. That may not
- // happen if the bitcast is from narrow to wide type.
- SDValue Extract = BitCast.getOperand(0);
- unsigned ExtIdx = Extract.getConstantOperandVal(1);
- unsigned SrcEltBitWidth = Extract.getScalarValueSizeInBits();
- unsigned ExtIdxInBits = ExtIdx * SrcEltBitWidth;
- unsigned CastedEltBitWidth = BitCast.getScalarValueSizeInBits();
- if (ExtIdxInBits % CastedEltBitWidth != 0)
- return false;
-
- // Update the lane value by offsetting with the scaled extract index.
- LaneC += ExtIdxInBits / CastedEltBitWidth;
-
- // Determine the casted vector type of the wide vector input.
- // dup (bitcast (extract_subv X, C)), LaneC --> dup (bitcast X), LaneC'
- // Examples:
- // dup (bitcast (extract_subv v2f64 X, 1) to v2f32), 1 --> dup v4f32 X, 3
- // dup (bitcast (extract_subv v16i8 X, 8) to v4i16), 1 --> dup v8i16 X, 5
- unsigned SrcVecNumElts =
- Extract.getOperand(0).getValueSizeInBits() / CastedEltBitWidth;
- CastVT = MVT::getVectorVT(BitCast.getSimpleValueType().getScalarType(),
- SrcVecNumElts);
- return true;
- };
- MVT CastVT;
- if (getScaledOffsetDup(V, Lane, CastVT)) {
- V = DAG.getBitcast(CastVT, V.getOperand(0).getOperand(0));
- } else if (V.getOpcode() == ISD::EXTRACT_SUBVECTOR) {
- // The lane is incremented by the index of the extract.
- // Example: dup v2f32 (extract v4f32 X, 2), 1 --> dup v4f32 X, 3
- Lane += V.getConstantOperandVal(1);
- V = V.getOperand(0);
- } else if (V.getOpcode() == ISD::CONCAT_VECTORS) {
- // The lane is decremented if we are splatting from the 2nd operand.
- // Example: dup v4i32 (concat v2i32 X, v2i32 Y), 3 --> dup v4i32 Y, 1
- unsigned Idx = Lane >= (int)VT.getVectorNumElements() / 2;
- Lane -= Idx * VT.getVectorNumElements() / 2;
- V = WidenVector(V.getOperand(Idx), DAG);
- } else if (VT.getSizeInBits() == 64) {
- // Widen the operand to 128-bit register with undef.
- V = WidenVector(V, DAG);
- }
- return DAG.getNode(Opcode, dl, VT, V, DAG.getConstant(Lane, dl, MVT::i64));
-}
-
+static SDValue constructDup(SDValue V, int Lane, SDLoc dl, EVT VT,
+ unsigned Opcode, SelectionDAG &DAG) {
+ // Try to eliminate a bitcasted extract subvector before a DUPLANE.
+ auto getScaledOffsetDup = [](SDValue BitCast, int &LaneC, MVT &CastVT) {
+ // Match: dup (bitcast (extract_subv X, C)), LaneC
+ if (BitCast.getOpcode() != ISD::BITCAST ||
+ BitCast.getOperand(0).getOpcode() != ISD::EXTRACT_SUBVECTOR)
+ return false;
+
+ // The extract index must align in the destination type. That may not
+ // happen if the bitcast is from narrow to wide type.
+ SDValue Extract = BitCast.getOperand(0);
+ unsigned ExtIdx = Extract.getConstantOperandVal(1);
+ unsigned SrcEltBitWidth = Extract.getScalarValueSizeInBits();
+ unsigned ExtIdxInBits = ExtIdx * SrcEltBitWidth;
+ unsigned CastedEltBitWidth = BitCast.getScalarValueSizeInBits();
+ if (ExtIdxInBits % CastedEltBitWidth != 0)
+ return false;
+
+ // Update the lane value by offsetting with the scaled extract index.
+ LaneC += ExtIdxInBits / CastedEltBitWidth;
+
+ // Determine the casted vector type of the wide vector input.
+ // dup (bitcast (extract_subv X, C)), LaneC --> dup (bitcast X), LaneC'
+ // Examples:
+ // dup (bitcast (extract_subv v2f64 X, 1) to v2f32), 1 --> dup v4f32 X, 3
+ // dup (bitcast (extract_subv v16i8 X, 8) to v4i16), 1 --> dup v8i16 X, 5
+ unsigned SrcVecNumElts =
+ Extract.getOperand(0).getValueSizeInBits() / CastedEltBitWidth;
+ CastVT = MVT::getVectorVT(BitCast.getSimpleValueType().getScalarType(),
+ SrcVecNumElts);
+ return true;
+ };
+ MVT CastVT;
+ if (getScaledOffsetDup(V, Lane, CastVT)) {
+ V = DAG.getBitcast(CastVT, V.getOperand(0).getOperand(0));
+ } else if (V.getOpcode() == ISD::EXTRACT_SUBVECTOR) {
+ // The lane is incremented by the index of the extract.
+ // Example: dup v2f32 (extract v4f32 X, 2), 1 --> dup v4f32 X, 3
+ Lane += V.getConstantOperandVal(1);
+ V = V.getOperand(0);
+ } else if (V.getOpcode() == ISD::CONCAT_VECTORS) {
+ // The lane is decremented if we are splatting from the 2nd operand.
+ // Example: dup v4i32 (concat v2i32 X, v2i32 Y), 3 --> dup v4i32 Y, 1
+ unsigned Idx = Lane >= (int)VT.getVectorNumElements() / 2;
+ Lane -= Idx * VT.getVectorNumElements() / 2;
+ V = WidenVector(V.getOperand(Idx), DAG);
+ } else if (VT.getSizeInBits() == 64) {
+ // Widen the operand to 128-bit register with undef.
+ V = WidenVector(V, DAG);
+ }
+ return DAG.getNode(Opcode, dl, VT, V, DAG.getConstant(Lane, dl, MVT::i64));
+}
+
SDValue AArch64TargetLowering::LowerVECTOR_SHUFFLE(SDValue Op,
SelectionDAG &DAG) const {
SDLoc dl(Op);
@@ -8819,25 +8819,25 @@ SDValue AArch64TargetLowering::LowerVECTOR_SHUFFLE(SDValue Op,
// Otherwise, duplicate from the lane of the input vector.
unsigned Opcode = getDUPLANEOp(V1.getValueType().getVectorElementType());
- return constructDup(V1, Lane, dl, VT, Opcode, DAG);
- }
-
- // Check if the mask matches a DUP for a wider element
- for (unsigned LaneSize : {64U, 32U, 16U}) {
- unsigned Lane = 0;
- if (isWideDUPMask(ShuffleMask, VT, LaneSize, Lane)) {
- unsigned Opcode = LaneSize == 64 ? AArch64ISD::DUPLANE64
- : LaneSize == 32 ? AArch64ISD::DUPLANE32
- : AArch64ISD::DUPLANE16;
- // Cast V1 to an integer vector with required lane size
- MVT NewEltTy = MVT::getIntegerVT(LaneSize);
- unsigned NewEltCount = VT.getSizeInBits() / LaneSize;
- MVT NewVecTy = MVT::getVectorVT(NewEltTy, NewEltCount);
- V1 = DAG.getBitcast(NewVecTy, V1);
- // Constuct the DUP instruction
- V1 = constructDup(V1, Lane, dl, NewVecTy, Opcode, DAG);
- // Cast back to the original type
- return DAG.getBitcast(VT, V1);
+ return constructDup(V1, Lane, dl, VT, Opcode, DAG);
+ }
+
+ // Check if the mask matches a DUP for a wider element
+ for (unsigned LaneSize : {64U, 32U, 16U}) {
+ unsigned Lane = 0;
+ if (isWideDUPMask(ShuffleMask, VT, LaneSize, Lane)) {
+ unsigned Opcode = LaneSize == 64 ? AArch64ISD::DUPLANE64
+ : LaneSize == 32 ? AArch64ISD::DUPLANE32
+ : AArch64ISD::DUPLANE16;
+ // Cast V1 to an integer vector with required lane size
+ MVT NewEltTy = MVT::getIntegerVT(LaneSize);
+ unsigned NewEltCount = VT.getSizeInBits() / LaneSize;
+ MVT NewVecTy = MVT::getVectorVT(NewEltTy, NewEltCount);
+ V1 = DAG.getBitcast(NewVecTy, V1);
+ // Constuct the DUP instruction
+ V1 = constructDup(V1, Lane, dl, NewVecTy, Opcode, DAG);
+ // Cast back to the original type
+ return DAG.getBitcast(VT, V1);
}
}
@@ -8909,7 +8909,7 @@ SDValue AArch64TargetLowering::LowerVECTOR_SHUFFLE(SDValue Op,
EVT ScalarVT = VT.getVectorElementType();
- if (ScalarVT.getFixedSizeInBits() < 32 && ScalarVT.isInteger())
+ if (ScalarVT.getFixedSizeInBits() < 32 && ScalarVT.isInteger())
ScalarVT = MVT::i32;
return DAG.getNode(
@@ -8950,9 +8950,9 @@ SDValue AArch64TargetLowering::LowerSPLAT_VECTOR(SDValue Op,
EVT ElemVT = VT.getScalarType();
SDValue SplatVal = Op.getOperand(0);
- if (useSVEForFixedLengthVectorVT(VT))
- return LowerToScalableOp(Op, DAG);
-
+ if (useSVEForFixedLengthVectorVT(VT))
+ return LowerToScalableOp(Op, DAG);
+
// Extend input splat value where needed to fit into a GPR (32b or 64b only)
// FPRs don't have this restriction.
switch (ElemVT.getSimpleVT().SimpleTy) {
@@ -9382,9 +9382,9 @@ static SDValue tryLowerToSLI(SDNode *N, SelectionDAG &DAG) {
SDValue AArch64TargetLowering::LowerVectorOR(SDValue Op,
SelectionDAG &DAG) const {
- if (useSVEForFixedLengthVectorVT(Op.getValueType()))
- return LowerToScalableOp(Op, DAG);
-
+ if (useSVEForFixedLengthVectorVT(Op.getValueType()))
+ return LowerToScalableOp(Op, DAG);
+
// Attempt to form a vector S[LR]I from (or (and X, C1), (lsl Y, C2))
if (SDValue Res = tryLowerToSLI(Op.getNode(), DAG))
return Res;
@@ -9543,18 +9543,18 @@ SDValue AArch64TargetLowering::LowerBUILD_VECTOR(SDValue Op,
bool isConstant = true;
bool AllLanesExtractElt = true;
unsigned NumConstantLanes = 0;
- unsigned NumDifferentLanes = 0;
- unsigned NumUndefLanes = 0;
+ unsigned NumDifferentLanes = 0;
+ unsigned NumUndefLanes = 0;
SDValue Value;
SDValue ConstantValue;
for (unsigned i = 0; i < NumElts; ++i) {
SDValue V = Op.getOperand(i);
if (V.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
AllLanesExtractElt = false;
- if (V.isUndef()) {
- ++NumUndefLanes;
+ if (V.isUndef()) {
+ ++NumUndefLanes;
continue;
- }
+ }
if (i > 0)
isOnlyLowElement = false;
if (!isa<ConstantFPSDNode>(V) && !isa<ConstantSDNode>(V))
@@ -9570,10 +9570,10 @@ SDValue AArch64TargetLowering::LowerBUILD_VECTOR(SDValue Op,
if (!Value.getNode())
Value = V;
- else if (V != Value) {
+ else if (V != Value) {
usesOnlyOneValue = false;
- ++NumDifferentLanes;
- }
+ ++NumDifferentLanes;
+ }
}
if (!Value.getNode()) {
@@ -9699,20 +9699,20 @@ SDValue AArch64TargetLowering::LowerBUILD_VECTOR(SDValue Op,
}
}
- // If we need to insert a small number of different non-constant elements and
- // the vector width is sufficiently large, prefer using DUP with the common
- // value and INSERT_VECTOR_ELT for the different lanes. If DUP is preferred,
- // skip the constant lane handling below.
- bool PreferDUPAndInsert =
- !isConstant && NumDifferentLanes >= 1 &&
- NumDifferentLanes < ((NumElts - NumUndefLanes) / 2) &&
- NumDifferentLanes >= NumConstantLanes;
-
+ // If we need to insert a small number of different non-constant elements and
+ // the vector width is sufficiently large, prefer using DUP with the common
+ // value and INSERT_VECTOR_ELT for the different lanes. If DUP is preferred,
+ // skip the constant lane handling below.
+ bool PreferDUPAndInsert =
+ !isConstant && NumDifferentLanes >= 1 &&
+ NumDifferentLanes < ((NumElts - NumUndefLanes) / 2) &&
+ NumDifferentLanes >= NumConstantLanes;
+
// If there was only one constant value used and for more than one lane,
// start by splatting that value, then replace the non-constant lanes. This
// is better than the default, which will perform a separate initialization
// for each lane.
- if (!PreferDUPAndInsert && NumConstantLanes > 0 && usesOnlyOneConstantValue) {
+ if (!PreferDUPAndInsert && NumConstantLanes > 0 && usesOnlyOneConstantValue) {
// Firstly, try to materialize the splat constant.
SDValue Vec = DAG.getSplatBuildVector(VT, dl, ConstantValue),
Val = ConstantBuildVector(Vec, DAG);
@@ -9748,22 +9748,22 @@ SDValue AArch64TargetLowering::LowerBUILD_VECTOR(SDValue Op,
return shuffle;
}
- if (PreferDUPAndInsert) {
- // First, build a constant vector with the common element.
- SmallVector<SDValue, 8> Ops;
- for (unsigned I = 0; I < NumElts; ++I)
- Ops.push_back(Value);
- SDValue NewVector = LowerBUILD_VECTOR(DAG.getBuildVector(VT, dl, Ops), DAG);
- // Next, insert the elements that do not match the common value.
- for (unsigned I = 0; I < NumElts; ++I)
- if (Op.getOperand(I) != Value)
- NewVector =
- DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, NewVector,
- Op.getOperand(I), DAG.getConstant(I, dl, MVT::i64));
-
- return NewVector;
- }
-
+ if (PreferDUPAndInsert) {
+ // First, build a constant vector with the common element.
+ SmallVector<SDValue, 8> Ops;
+ for (unsigned I = 0; I < NumElts; ++I)
+ Ops.push_back(Value);
+ SDValue NewVector = LowerBUILD_VECTOR(DAG.getBuildVector(VT, dl, Ops), DAG);
+ // Next, insert the elements that do not match the common value.
+ for (unsigned I = 0; I < NumElts; ++I)
+ if (Op.getOperand(I) != Value)
+ NewVector =
+ DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, NewVector,
+ Op.getOperand(I), DAG.getConstant(I, dl, MVT::i64));
+
+ return NewVector;
+ }
+
// If all else fails, just use a sequence of INSERT_VECTOR_ELT when we
// know the default expansion would otherwise fall back on something even
// worse. For a vector with one or two non-undef values, that's
@@ -9812,18 +9812,18 @@ SDValue AArch64TargetLowering::LowerBUILD_VECTOR(SDValue Op,
return SDValue();
}
-SDValue AArch64TargetLowering::LowerCONCAT_VECTORS(SDValue Op,
- SelectionDAG &DAG) const {
- assert(Op.getValueType().isScalableVector() &&
- isTypeLegal(Op.getValueType()) &&
- "Expected legal scalable vector type!");
-
- if (isTypeLegal(Op.getOperand(0).getValueType()) && Op.getNumOperands() == 2)
- return Op;
-
- return SDValue();
-}
-
+SDValue AArch64TargetLowering::LowerCONCAT_VECTORS(SDValue Op,
+ SelectionDAG &DAG) const {
+ assert(Op.getValueType().isScalableVector() &&
+ isTypeLegal(Op.getValueType()) &&
+ "Expected legal scalable vector type!");
+
+ if (isTypeLegal(Op.getOperand(0).getValueType()) && Op.getNumOperands() == 2)
+ return Op;
+
+ return SDValue();
+}
+
SDValue AArch64TargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op,
SelectionDAG &DAG) const {
assert(Op.getOpcode() == ISD::INSERT_VECTOR_ELT && "Unknown opcode!");
@@ -9919,8 +9919,8 @@ SDValue AArch64TargetLowering::LowerEXTRACT_SUBVECTOR(SDValue Op,
// If this is extracting the upper 64-bits of a 128-bit vector, we match
// that directly.
- if (Size == 64 && Idx * InVT.getScalarSizeInBits() == 64 &&
- InVT.getSizeInBits() == 128)
+ if (Size == 64 && Idx * InVT.getScalarSizeInBits() == 64 &&
+ InVT.getSizeInBits() == 128)
return Op;
return SDValue();
@@ -9934,34 +9934,34 @@ SDValue AArch64TargetLowering::LowerINSERT_SUBVECTOR(SDValue Op,
EVT InVT = Op.getOperand(1).getValueType();
unsigned Idx = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue();
- if (InVT.isScalableVector()) {
- SDLoc DL(Op);
- EVT VT = Op.getValueType();
-
- if (!isTypeLegal(VT) || !VT.isInteger())
- return SDValue();
-
- SDValue Vec0 = Op.getOperand(0);
- SDValue Vec1 = Op.getOperand(1);
-
- // Ensure the subvector is half the size of the main vector.
- if (VT.getVectorElementCount() != (InVT.getVectorElementCount() * 2))
- return SDValue();
-
- // Extend elements of smaller vector...
- EVT WideVT = InVT.widenIntegerVectorElementType(*(DAG.getContext()));
- SDValue ExtVec = DAG.getNode(ISD::ANY_EXTEND, DL, WideVT, Vec1);
-
- if (Idx == 0) {
- SDValue HiVec0 = DAG.getNode(AArch64ISD::UUNPKHI, DL, WideVT, Vec0);
- return DAG.getNode(AArch64ISD::UZP1, DL, VT, ExtVec, HiVec0);
- } else if (Idx == InVT.getVectorMinNumElements()) {
- SDValue LoVec0 = DAG.getNode(AArch64ISD::UUNPKLO, DL, WideVT, Vec0);
- return DAG.getNode(AArch64ISD::UZP1, DL, VT, LoVec0, ExtVec);
- }
-
+ if (InVT.isScalableVector()) {
+ SDLoc DL(Op);
+ EVT VT = Op.getValueType();
+
+ if (!isTypeLegal(VT) || !VT.isInteger())
+ return SDValue();
+
+ SDValue Vec0 = Op.getOperand(0);
+ SDValue Vec1 = Op.getOperand(1);
+
+ // Ensure the subvector is half the size of the main vector.
+ if (VT.getVectorElementCount() != (InVT.getVectorElementCount() * 2))
+ return SDValue();
+
+ // Extend elements of smaller vector...
+ EVT WideVT = InVT.widenIntegerVectorElementType(*(DAG.getContext()));
+ SDValue ExtVec = DAG.getNode(ISD::ANY_EXTEND, DL, WideVT, Vec1);
+
+ if (Idx == 0) {
+ SDValue HiVec0 = DAG.getNode(AArch64ISD::UUNPKHI, DL, WideVT, Vec0);
+ return DAG.getNode(AArch64ISD::UZP1, DL, VT, ExtVec, HiVec0);
+ } else if (Idx == InVT.getVectorMinNumElements()) {
+ SDValue LoVec0 = DAG.getNode(AArch64ISD::UUNPKLO, DL, WideVT, Vec0);
+ return DAG.getNode(AArch64ISD::UZP1, DL, VT, LoVec0, ExtVec);
+ }
+
return SDValue();
- }
+ }
// This will be matched by custom code during ISelDAGToDAG.
if (Idx == 0 && isPackedVectorType(InVT, DAG) && Op.getOperand(0).isUndef())
@@ -9970,42 +9970,42 @@ SDValue AArch64TargetLowering::LowerINSERT_SUBVECTOR(SDValue Op,
return SDValue();
}
-SDValue AArch64TargetLowering::LowerDIV(SDValue Op, SelectionDAG &DAG) const {
- EVT VT = Op.getValueType();
-
- if (useSVEForFixedLengthVectorVT(VT, /*OverrideNEON=*/true))
- return LowerFixedLengthVectorIntDivideToSVE(Op, DAG);
-
- assert(VT.isScalableVector() && "Expected a scalable vector.");
-
- bool Signed = Op.getOpcode() == ISD::SDIV;
- unsigned PredOpcode = Signed ? AArch64ISD::SDIV_PRED : AArch64ISD::UDIV_PRED;
-
- if (VT == MVT::nxv4i32 || VT == MVT::nxv2i64)
- return LowerToPredicatedOp(Op, DAG, PredOpcode);
-
- // SVE doesn't have i8 and i16 DIV operations; widen them to 32-bit
- // operations, and truncate the result.
- EVT WidenedVT;
- if (VT == MVT::nxv16i8)
- WidenedVT = MVT::nxv8i16;
- else if (VT == MVT::nxv8i16)
- WidenedVT = MVT::nxv4i32;
- else
- llvm_unreachable("Unexpected Custom DIV operation");
-
- SDLoc dl(Op);
- unsigned UnpkLo = Signed ? AArch64ISD::SUNPKLO : AArch64ISD::UUNPKLO;
- unsigned UnpkHi = Signed ? AArch64ISD::SUNPKHI : AArch64ISD::UUNPKHI;
- SDValue Op0Lo = DAG.getNode(UnpkLo, dl, WidenedVT, Op.getOperand(0));
- SDValue Op1Lo = DAG.getNode(UnpkLo, dl, WidenedVT, Op.getOperand(1));
- SDValue Op0Hi = DAG.getNode(UnpkHi, dl, WidenedVT, Op.getOperand(0));
- SDValue Op1Hi = DAG.getNode(UnpkHi, dl, WidenedVT, Op.getOperand(1));
- SDValue ResultLo = DAG.getNode(Op.getOpcode(), dl, WidenedVT, Op0Lo, Op1Lo);
- SDValue ResultHi = DAG.getNode(Op.getOpcode(), dl, WidenedVT, Op0Hi, Op1Hi);
- return DAG.getNode(AArch64ISD::UZP1, dl, VT, ResultLo, ResultHi);
-}
-
+SDValue AArch64TargetLowering::LowerDIV(SDValue Op, SelectionDAG &DAG) const {
+ EVT VT = Op.getValueType();
+
+ if (useSVEForFixedLengthVectorVT(VT, /*OverrideNEON=*/true))
+ return LowerFixedLengthVectorIntDivideToSVE(Op, DAG);
+
+ assert(VT.isScalableVector() && "Expected a scalable vector.");
+
+ bool Signed = Op.getOpcode() == ISD::SDIV;
+ unsigned PredOpcode = Signed ? AArch64ISD::SDIV_PRED : AArch64ISD::UDIV_PRED;
+
+ if (VT == MVT::nxv4i32 || VT == MVT::nxv2i64)
+ return LowerToPredicatedOp(Op, DAG, PredOpcode);
+
+ // SVE doesn't have i8 and i16 DIV operations; widen them to 32-bit
+ // operations, and truncate the result.
+ EVT WidenedVT;
+ if (VT == MVT::nxv16i8)
+ WidenedVT = MVT::nxv8i16;
+ else if (VT == MVT::nxv8i16)
+ WidenedVT = MVT::nxv4i32;
+ else
+ llvm_unreachable("Unexpected Custom DIV operation");
+
+ SDLoc dl(Op);
+ unsigned UnpkLo = Signed ? AArch64ISD::SUNPKLO : AArch64ISD::UUNPKLO;
+ unsigned UnpkHi = Signed ? AArch64ISD::SUNPKHI : AArch64ISD::UUNPKHI;
+ SDValue Op0Lo = DAG.getNode(UnpkLo, dl, WidenedVT, Op.getOperand(0));
+ SDValue Op1Lo = DAG.getNode(UnpkLo, dl, WidenedVT, Op.getOperand(1));
+ SDValue Op0Hi = DAG.getNode(UnpkHi, dl, WidenedVT, Op.getOperand(0));
+ SDValue Op1Hi = DAG.getNode(UnpkHi, dl, WidenedVT, Op.getOperand(1));
+ SDValue ResultLo = DAG.getNode(Op.getOpcode(), dl, WidenedVT, Op0Lo, Op1Lo);
+ SDValue ResultHi = DAG.getNode(Op.getOpcode(), dl, WidenedVT, Op0Hi, Op1Hi);
+ return DAG.getNode(AArch64ISD::UZP1, dl, VT, ResultLo, ResultHi);
+}
+
bool AArch64TargetLowering::isShuffleMaskLegal(ArrayRef<int> M, EVT VT) const {
// Currently no fixed length shuffles that require SVE are legal.
if (useSVEForFixedLengthVectorVT(VT))
@@ -10105,12 +10105,12 @@ SDValue AArch64TargetLowering::LowerTRUNCATE(SDValue Op,
}
if (!VT.isVector() || VT.isScalableVector())
- return SDValue();
+ return SDValue();
if (useSVEForFixedLengthVectorVT(Op.getOperand(0).getValueType()))
return LowerFixedLengthVectorTruncateToSVE(Op, DAG);
- return SDValue();
+ return SDValue();
}
SDValue AArch64TargetLowering::LowerVectorSRA_SRL_SHL(SDValue Op,
@@ -10128,8 +10128,8 @@ SDValue AArch64TargetLowering::LowerVectorSRA_SRL_SHL(SDValue Op,
llvm_unreachable("unexpected shift opcode");
case ISD::SHL:
- if (VT.isScalableVector() || useSVEForFixedLengthVectorVT(VT))
- return LowerToPredicatedOp(Op, DAG, AArch64ISD::SHL_PRED);
+ if (VT.isScalableVector() || useSVEForFixedLengthVectorVT(VT))
+ return LowerToPredicatedOp(Op, DAG, AArch64ISD::SHL_PRED);
if (isVShiftLImm(Op.getOperand(1), VT, false, Cnt) && Cnt < EltSize)
return DAG.getNode(AArch64ISD::VSHL, DL, VT, Op.getOperand(0),
@@ -10140,9 +10140,9 @@ SDValue AArch64TargetLowering::LowerVectorSRA_SRL_SHL(SDValue Op,
Op.getOperand(0), Op.getOperand(1));
case ISD::SRA:
case ISD::SRL:
- if (VT.isScalableVector() || useSVEForFixedLengthVectorVT(VT)) {
- unsigned Opc = Op.getOpcode() == ISD::SRA ? AArch64ISD::SRA_PRED
- : AArch64ISD::SRL_PRED;
+ if (VT.isScalableVector() || useSVEForFixedLengthVectorVT(VT)) {
+ unsigned Opc = Op.getOpcode() == ISD::SRA ? AArch64ISD::SRA_PRED
+ : AArch64ISD::SRL_PRED;
return LowerToPredicatedOp(Op, DAG, Opc);
}
@@ -10194,7 +10194,7 @@ static SDValue EmitVectorComparison(SDValue LHS, SDValue RHS,
Fcmeq = DAG.getNode(AArch64ISD::FCMEQz, dl, VT, LHS);
else
Fcmeq = DAG.getNode(AArch64ISD::FCMEQ, dl, VT, LHS, RHS);
- return DAG.getNOT(dl, Fcmeq, VT);
+ return DAG.getNOT(dl, Fcmeq, VT);
}
case AArch64CC::EQ:
if (IsZero)
@@ -10233,7 +10233,7 @@ static SDValue EmitVectorComparison(SDValue LHS, SDValue RHS,
Cmeq = DAG.getNode(AArch64ISD::CMEQz, dl, VT, LHS);
else
Cmeq = DAG.getNode(AArch64ISD::CMEQ, dl, VT, LHS, RHS);
- return DAG.getNOT(dl, Cmeq, VT);
+ return DAG.getNOT(dl, Cmeq, VT);
}
case AArch64CC::EQ:
if (IsZero)
@@ -10274,9 +10274,9 @@ SDValue AArch64TargetLowering::LowerVSETCC(SDValue Op,
return LowerToPredicatedOp(Op, DAG, AArch64ISD::SETCC_MERGE_ZERO);
}
- if (useSVEForFixedLengthVectorVT(Op.getOperand(0).getValueType()))
- return LowerFixedLengthVectorSetccToSVE(Op, DAG);
-
+ if (useSVEForFixedLengthVectorVT(Op.getOperand(0).getValueType()))
+ return LowerFixedLengthVectorSetccToSVE(Op, DAG);
+
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
SDValue LHS = Op.getOperand(0);
SDValue RHS = Op.getOperand(1);
@@ -10349,51 +10349,51 @@ static SDValue getReductionSDNode(unsigned Op, SDLoc DL, SDValue ScalarOp,
SDValue AArch64TargetLowering::LowerVECREDUCE(SDValue Op,
SelectionDAG &DAG) const {
- SDValue Src = Op.getOperand(0);
-
- // Try to lower fixed length reductions to SVE.
- EVT SrcVT = Src.getValueType();
- bool OverrideNEON = Op.getOpcode() == ISD::VECREDUCE_AND ||
- Op.getOpcode() == ISD::VECREDUCE_OR ||
- Op.getOpcode() == ISD::VECREDUCE_XOR ||
- Op.getOpcode() == ISD::VECREDUCE_FADD ||
- (Op.getOpcode() != ISD::VECREDUCE_ADD &&
- SrcVT.getVectorElementType() == MVT::i64);
- if (SrcVT.isScalableVector() ||
- useSVEForFixedLengthVectorVT(SrcVT, OverrideNEON)) {
-
- if (SrcVT.getVectorElementType() == MVT::i1)
- return LowerPredReductionToSVE(Op, DAG);
-
- switch (Op.getOpcode()) {
- case ISD::VECREDUCE_ADD:
- return LowerReductionToSVE(AArch64ISD::UADDV_PRED, Op, DAG);
- case ISD::VECREDUCE_AND:
- return LowerReductionToSVE(AArch64ISD::ANDV_PRED, Op, DAG);
- case ISD::VECREDUCE_OR:
- return LowerReductionToSVE(AArch64ISD::ORV_PRED, Op, DAG);
- case ISD::VECREDUCE_SMAX:
- return LowerReductionToSVE(AArch64ISD::SMAXV_PRED, Op, DAG);
- case ISD::VECREDUCE_SMIN:
- return LowerReductionToSVE(AArch64ISD::SMINV_PRED, Op, DAG);
- case ISD::VECREDUCE_UMAX:
- return LowerReductionToSVE(AArch64ISD::UMAXV_PRED, Op, DAG);
- case ISD::VECREDUCE_UMIN:
- return LowerReductionToSVE(AArch64ISD::UMINV_PRED, Op, DAG);
- case ISD::VECREDUCE_XOR:
- return LowerReductionToSVE(AArch64ISD::EORV_PRED, Op, DAG);
- case ISD::VECREDUCE_FADD:
- return LowerReductionToSVE(AArch64ISD::FADDV_PRED, Op, DAG);
- case ISD::VECREDUCE_FMAX:
- return LowerReductionToSVE(AArch64ISD::FMAXNMV_PRED, Op, DAG);
- case ISD::VECREDUCE_FMIN:
- return LowerReductionToSVE(AArch64ISD::FMINNMV_PRED, Op, DAG);
- default:
- llvm_unreachable("Unhandled fixed length reduction");
- }
- }
-
- // Lower NEON reductions.
+ SDValue Src = Op.getOperand(0);
+
+ // Try to lower fixed length reductions to SVE.
+ EVT SrcVT = Src.getValueType();
+ bool OverrideNEON = Op.getOpcode() == ISD::VECREDUCE_AND ||
+ Op.getOpcode() == ISD::VECREDUCE_OR ||
+ Op.getOpcode() == ISD::VECREDUCE_XOR ||
+ Op.getOpcode() == ISD::VECREDUCE_FADD ||
+ (Op.getOpcode() != ISD::VECREDUCE_ADD &&
+ SrcVT.getVectorElementType() == MVT::i64);
+ if (SrcVT.isScalableVector() ||
+ useSVEForFixedLengthVectorVT(SrcVT, OverrideNEON)) {
+
+ if (SrcVT.getVectorElementType() == MVT::i1)
+ return LowerPredReductionToSVE(Op, DAG);
+
+ switch (Op.getOpcode()) {
+ case ISD::VECREDUCE_ADD:
+ return LowerReductionToSVE(AArch64ISD::UADDV_PRED, Op, DAG);
+ case ISD::VECREDUCE_AND:
+ return LowerReductionToSVE(AArch64ISD::ANDV_PRED, Op, DAG);
+ case ISD::VECREDUCE_OR:
+ return LowerReductionToSVE(AArch64ISD::ORV_PRED, Op, DAG);
+ case ISD::VECREDUCE_SMAX:
+ return LowerReductionToSVE(AArch64ISD::SMAXV_PRED, Op, DAG);
+ case ISD::VECREDUCE_SMIN:
+ return LowerReductionToSVE(AArch64ISD::SMINV_PRED, Op, DAG);
+ case ISD::VECREDUCE_UMAX:
+ return LowerReductionToSVE(AArch64ISD::UMAXV_PRED, Op, DAG);
+ case ISD::VECREDUCE_UMIN:
+ return LowerReductionToSVE(AArch64ISD::UMINV_PRED, Op, DAG);
+ case ISD::VECREDUCE_XOR:
+ return LowerReductionToSVE(AArch64ISD::EORV_PRED, Op, DAG);
+ case ISD::VECREDUCE_FADD:
+ return LowerReductionToSVE(AArch64ISD::FADDV_PRED, Op, DAG);
+ case ISD::VECREDUCE_FMAX:
+ return LowerReductionToSVE(AArch64ISD::FMAXNMV_PRED, Op, DAG);
+ case ISD::VECREDUCE_FMIN:
+ return LowerReductionToSVE(AArch64ISD::FMINNMV_PRED, Op, DAG);
+ default:
+ llvm_unreachable("Unhandled fixed length reduction");
+ }
+ }
+
+ // Lower NEON reductions.
SDLoc dl(Op);
switch (Op.getOpcode()) {
case ISD::VECREDUCE_ADD:
@@ -10410,13 +10410,13 @@ SDValue AArch64TargetLowering::LowerVECREDUCE(SDValue Op,
return DAG.getNode(
ISD::INTRINSIC_WO_CHAIN, dl, Op.getValueType(),
DAG.getConstant(Intrinsic::aarch64_neon_fmaxnmv, dl, MVT::i32),
- Src);
+ Src);
}
case ISD::VECREDUCE_FMIN: {
return DAG.getNode(
ISD::INTRINSIC_WO_CHAIN, dl, Op.getValueType(),
DAG.getConstant(Intrinsic::aarch64_neon_fminnmv, dl, MVT::i32),
- Src);
+ Src);
}
default:
llvm_unreachable("Unhandled reduction");
@@ -10426,7 +10426,7 @@ SDValue AArch64TargetLowering::LowerVECREDUCE(SDValue Op,
SDValue AArch64TargetLowering::LowerATOMIC_LOAD_SUB(SDValue Op,
SelectionDAG &DAG) const {
auto &Subtarget = static_cast<const AArch64Subtarget &>(DAG.getSubtarget());
- if (!Subtarget.hasLSE() && !Subtarget.outlineAtomics())
+ if (!Subtarget.hasLSE() && !Subtarget.outlineAtomics())
return SDValue();
// LSE has an atomic load-add instruction, but not a load-sub.
@@ -10443,7 +10443,7 @@ SDValue AArch64TargetLowering::LowerATOMIC_LOAD_SUB(SDValue Op,
SDValue AArch64TargetLowering::LowerATOMIC_LOAD_AND(SDValue Op,
SelectionDAG &DAG) const {
auto &Subtarget = static_cast<const AArch64Subtarget &>(DAG.getSubtarget());
- if (!Subtarget.hasLSE() && !Subtarget.outlineAtomics())
+ if (!Subtarget.hasLSE() && !Subtarget.outlineAtomics())
return SDValue();
// LSE has an atomic load-clear instruction, but not a load-and.
@@ -10544,17 +10544,17 @@ SDValue AArch64TargetLowering::LowerVSCALE(SDValue Op,
/// Set the IntrinsicInfo for the `aarch64_sve_st<N>` intrinsics.
template <unsigned NumVecs>
-static bool
-setInfoSVEStN(const AArch64TargetLowering &TLI, const DataLayout &DL,
- AArch64TargetLowering::IntrinsicInfo &Info, const CallInst &CI) {
+static bool
+setInfoSVEStN(const AArch64TargetLowering &TLI, const DataLayout &DL,
+ AArch64TargetLowering::IntrinsicInfo &Info, const CallInst &CI) {
Info.opc = ISD::INTRINSIC_VOID;
// Retrieve EC from first vector argument.
- const EVT VT = TLI.getMemValueType(DL, CI.getArgOperand(0)->getType());
+ const EVT VT = TLI.getMemValueType(DL, CI.getArgOperand(0)->getType());
ElementCount EC = VT.getVectorElementCount();
#ifndef NDEBUG
// Check the assumption that all input vectors are the same type.
for (unsigned I = 0; I < NumVecs; ++I)
- assert(VT == TLI.getMemValueType(DL, CI.getArgOperand(I)->getType()) &&
+ assert(VT == TLI.getMemValueType(DL, CI.getArgOperand(I)->getType()) &&
"Invalid type.");
#endif
// memVT is `NumVecs * VT`.
@@ -10577,11 +10577,11 @@ bool AArch64TargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
auto &DL = I.getModule()->getDataLayout();
switch (Intrinsic) {
case Intrinsic::aarch64_sve_st2:
- return setInfoSVEStN<2>(*this, DL, Info, I);
+ return setInfoSVEStN<2>(*this, DL, Info, I);
case Intrinsic::aarch64_sve_st3:
- return setInfoSVEStN<3>(*this, DL, Info, I);
+ return setInfoSVEStN<3>(*this, DL, Info, I);
case Intrinsic::aarch64_sve_st4:
- return setInfoSVEStN<4>(*this, DL, Info, I);
+ return setInfoSVEStN<4>(*this, DL, Info, I);
case Intrinsic::aarch64_neon_ld2:
case Intrinsic::aarch64_neon_ld3:
case Intrinsic::aarch64_neon_ld4:
@@ -10737,15 +10737,15 @@ bool AArch64TargetLowering::shouldReduceLoadWidth(SDNode *Load,
bool AArch64TargetLowering::isTruncateFree(Type *Ty1, Type *Ty2) const {
if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
return false;
- uint64_t NumBits1 = Ty1->getPrimitiveSizeInBits().getFixedSize();
- uint64_t NumBits2 = Ty2->getPrimitiveSizeInBits().getFixedSize();
+ uint64_t NumBits1 = Ty1->getPrimitiveSizeInBits().getFixedSize();
+ uint64_t NumBits2 = Ty2->getPrimitiveSizeInBits().getFixedSize();
return NumBits1 > NumBits2;
}
bool AArch64TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
if (VT1.isVector() || VT2.isVector() || !VT1.isInteger() || !VT2.isInteger())
return false;
- uint64_t NumBits1 = VT1.getFixedSizeInBits();
- uint64_t NumBits2 = VT2.getFixedSizeInBits();
+ uint64_t NumBits1 = VT1.getFixedSizeInBits();
+ uint64_t NumBits2 = VT2.getFixedSizeInBits();
return NumBits1 > NumBits2;
}
@@ -10987,43 +10987,43 @@ bool AArch64TargetLowering::shouldSinkOperands(
return true;
}
- case Instruction::Mul: {
- bool IsProfitable = false;
- for (auto &Op : I->operands()) {
- // Make sure we are not already sinking this operand
- if (any_of(Ops, [&](Use *U) { return U->get() == Op; }))
- continue;
-
- ShuffleVectorInst *Shuffle = dyn_cast<ShuffleVectorInst>(Op);
- if (!Shuffle || !Shuffle->isZeroEltSplat())
- continue;
-
- Value *ShuffleOperand = Shuffle->getOperand(0);
- InsertElementInst *Insert = dyn_cast<InsertElementInst>(ShuffleOperand);
- if (!Insert)
- continue;
-
- Instruction *OperandInstr = dyn_cast<Instruction>(Insert->getOperand(1));
- if (!OperandInstr)
- continue;
-
- ConstantInt *ElementConstant =
- dyn_cast<ConstantInt>(Insert->getOperand(2));
- // Check that the insertelement is inserting into element 0
- if (!ElementConstant || ElementConstant->getZExtValue() != 0)
- continue;
-
- unsigned Opcode = OperandInstr->getOpcode();
- if (Opcode != Instruction::SExt && Opcode != Instruction::ZExt)
- continue;
-
- Ops.push_back(&Shuffle->getOperandUse(0));
- Ops.push_back(&Op);
- IsProfitable = true;
- }
-
- return IsProfitable;
- }
+ case Instruction::Mul: {
+ bool IsProfitable = false;
+ for (auto &Op : I->operands()) {
+ // Make sure we are not already sinking this operand
+ if (any_of(Ops, [&](Use *U) { return U->get() == Op; }))
+ continue;
+
+ ShuffleVectorInst *Shuffle = dyn_cast<ShuffleVectorInst>(Op);
+ if (!Shuffle || !Shuffle->isZeroEltSplat())
+ continue;
+
+ Value *ShuffleOperand = Shuffle->getOperand(0);
+ InsertElementInst *Insert = dyn_cast<InsertElementInst>(ShuffleOperand);
+ if (!Insert)
+ continue;
+
+ Instruction *OperandInstr = dyn_cast<Instruction>(Insert->getOperand(1));
+ if (!OperandInstr)
+ continue;
+
+ ConstantInt *ElementConstant =
+ dyn_cast<ConstantInt>(Insert->getOperand(2));
+ // Check that the insertelement is inserting into element 0
+ if (!ElementConstant || ElementConstant->getZExtValue() != 0)
+ continue;
+
+ unsigned Opcode = OperandInstr->getOpcode();
+ if (Opcode != Instruction::SExt && Opcode != Instruction::ZExt)
+ continue;
+
+ Ops.push_back(&Shuffle->getOperandUse(0));
+ Ops.push_back(&Op);
+ IsProfitable = true;
+ }
+
+ return IsProfitable;
+ }
default:
return false;
}
@@ -11359,12 +11359,12 @@ SDValue AArch64TargetLowering::LowerSVEStructLoad(unsigned Intrinsic,
{Intrinsic::aarch64_sve_ld4, {4, AArch64ISD::SVE_LD4_MERGE_ZERO}}};
std::tie(N, Opcode) = IntrinsicMap[Intrinsic];
- assert(VT.getVectorElementCount().getKnownMinValue() % N == 0 &&
+ assert(VT.getVectorElementCount().getKnownMinValue() % N == 0 &&
"invalid tuple vector type!");
- EVT SplitVT =
- EVT::getVectorVT(*DAG.getContext(), VT.getVectorElementType(),
- VT.getVectorElementCount().divideCoefficientBy(N));
+ EVT SplitVT =
+ EVT::getVectorVT(*DAG.getContext(), VT.getVectorElementType(),
+ VT.getVectorElementCount().divideCoefficientBy(N));
assert(isTypeLegal(SplitVT));
SmallVector<EVT, 5> VTs(N, SplitVT);
@@ -11655,86 +11655,86 @@ static SDValue foldVectorXorShiftIntoCmp(SDNode *N, SelectionDAG &DAG,
return DAG.getNode(AArch64ISD::CMGEz, SDLoc(N), VT, Shift.getOperand(0));
}
-// VECREDUCE_ADD( EXTEND(v16i8_type) ) to
-// VECREDUCE_ADD( DOTv16i8(v16i8_type) )
-static SDValue performVecReduceAddCombine(SDNode *N, SelectionDAG &DAG,
- const AArch64Subtarget *ST) {
- SDValue Op0 = N->getOperand(0);
- if (!ST->hasDotProd() || N->getValueType(0) != MVT::i32)
- return SDValue();
-
- if (Op0.getValueType().getVectorElementType() != MVT::i32)
- return SDValue();
-
- unsigned ExtOpcode = Op0.getOpcode();
- if (ExtOpcode != ISD::ZERO_EXTEND && ExtOpcode != ISD::SIGN_EXTEND)
- return SDValue();
-
- EVT Op0VT = Op0.getOperand(0).getValueType();
- if (Op0VT != MVT::v16i8)
- return SDValue();
-
- SDLoc DL(Op0);
- SDValue Ones = DAG.getConstant(1, DL, Op0VT);
- SDValue Zeros = DAG.getConstant(0, DL, MVT::v4i32);
- auto DotIntrisic = (ExtOpcode == ISD::ZERO_EXTEND)
- ? Intrinsic::aarch64_neon_udot
- : Intrinsic::aarch64_neon_sdot;
- SDValue Dot = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, Zeros.getValueType(),
- DAG.getConstant(DotIntrisic, DL, MVT::i32), Zeros,
- Ones, Op0.getOperand(0));
- return DAG.getNode(ISD::VECREDUCE_ADD, DL, N->getValueType(0), Dot);
-}
-
-// Given a ABS node, detect the following pattern:
-// (ABS (SUB (EXTEND a), (EXTEND b))).
-// Generates UABD/SABD instruction.
-static SDValue performABSCombine(SDNode *N, SelectionDAG &DAG,
- TargetLowering::DAGCombinerInfo &DCI,
- const AArch64Subtarget *Subtarget) {
- SDValue AbsOp1 = N->getOperand(0);
- SDValue Op0, Op1;
-
- if (AbsOp1.getOpcode() != ISD::SUB)
- return SDValue();
-
- Op0 = AbsOp1.getOperand(0);
- Op1 = AbsOp1.getOperand(1);
-
- unsigned Opc0 = Op0.getOpcode();
- // Check if the operands of the sub are (zero|sign)-extended.
- if (Opc0 != Op1.getOpcode() ||
- (Opc0 != ISD::ZERO_EXTEND && Opc0 != ISD::SIGN_EXTEND))
- return SDValue();
-
- EVT VectorT1 = Op0.getOperand(0).getValueType();
- EVT VectorT2 = Op1.getOperand(0).getValueType();
- // Check if vectors are of same type and valid size.
- uint64_t Size = VectorT1.getFixedSizeInBits();
- if (VectorT1 != VectorT2 || (Size != 64 && Size != 128))
- return SDValue();
-
- // Check if vector element types are valid.
- EVT VT1 = VectorT1.getVectorElementType();
- if (VT1 != MVT::i8 && VT1 != MVT::i16 && VT1 != MVT::i32)
- return SDValue();
-
- Op0 = Op0.getOperand(0);
- Op1 = Op1.getOperand(0);
- unsigned ABDOpcode =
- (Opc0 == ISD::SIGN_EXTEND) ? AArch64ISD::SABD : AArch64ISD::UABD;
- SDValue ABD =
- DAG.getNode(ABDOpcode, SDLoc(N), Op0->getValueType(0), Op0, Op1);
- return DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), N->getValueType(0), ABD);
-}
-
+// VECREDUCE_ADD( EXTEND(v16i8_type) ) to
+// VECREDUCE_ADD( DOTv16i8(v16i8_type) )
+static SDValue performVecReduceAddCombine(SDNode *N, SelectionDAG &DAG,
+ const AArch64Subtarget *ST) {
+ SDValue Op0 = N->getOperand(0);
+ if (!ST->hasDotProd() || N->getValueType(0) != MVT::i32)
+ return SDValue();
+
+ if (Op0.getValueType().getVectorElementType() != MVT::i32)
+ return SDValue();
+
+ unsigned ExtOpcode = Op0.getOpcode();
+ if (ExtOpcode != ISD::ZERO_EXTEND && ExtOpcode != ISD::SIGN_EXTEND)
+ return SDValue();
+
+ EVT Op0VT = Op0.getOperand(0).getValueType();
+ if (Op0VT != MVT::v16i8)
+ return SDValue();
+
+ SDLoc DL(Op0);
+ SDValue Ones = DAG.getConstant(1, DL, Op0VT);
+ SDValue Zeros = DAG.getConstant(0, DL, MVT::v4i32);
+ auto DotIntrisic = (ExtOpcode == ISD::ZERO_EXTEND)
+ ? Intrinsic::aarch64_neon_udot
+ : Intrinsic::aarch64_neon_sdot;
+ SDValue Dot = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, Zeros.getValueType(),
+ DAG.getConstant(DotIntrisic, DL, MVT::i32), Zeros,
+ Ones, Op0.getOperand(0));
+ return DAG.getNode(ISD::VECREDUCE_ADD, DL, N->getValueType(0), Dot);
+}
+
+// Given a ABS node, detect the following pattern:
+// (ABS (SUB (EXTEND a), (EXTEND b))).
+// Generates UABD/SABD instruction.
+static SDValue performABSCombine(SDNode *N, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI,
+ const AArch64Subtarget *Subtarget) {
+ SDValue AbsOp1 = N->getOperand(0);
+ SDValue Op0, Op1;
+
+ if (AbsOp1.getOpcode() != ISD::SUB)
+ return SDValue();
+
+ Op0 = AbsOp1.getOperand(0);
+ Op1 = AbsOp1.getOperand(1);
+
+ unsigned Opc0 = Op0.getOpcode();
+ // Check if the operands of the sub are (zero|sign)-extended.
+ if (Opc0 != Op1.getOpcode() ||
+ (Opc0 != ISD::ZERO_EXTEND && Opc0 != ISD::SIGN_EXTEND))
+ return SDValue();
+
+ EVT VectorT1 = Op0.getOperand(0).getValueType();
+ EVT VectorT2 = Op1.getOperand(0).getValueType();
+ // Check if vectors are of same type and valid size.
+ uint64_t Size = VectorT1.getFixedSizeInBits();
+ if (VectorT1 != VectorT2 || (Size != 64 && Size != 128))
+ return SDValue();
+
+ // Check if vector element types are valid.
+ EVT VT1 = VectorT1.getVectorElementType();
+ if (VT1 != MVT::i8 && VT1 != MVT::i16 && VT1 != MVT::i32)
+ return SDValue();
+
+ Op0 = Op0.getOperand(0);
+ Op1 = Op1.getOperand(0);
+ unsigned ABDOpcode =
+ (Opc0 == ISD::SIGN_EXTEND) ? AArch64ISD::SABD : AArch64ISD::UABD;
+ SDValue ABD =
+ DAG.getNode(ABDOpcode, SDLoc(N), Op0->getValueType(0), Op0, Op1);
+ return DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), N->getValueType(0), ABD);
+}
+
static SDValue performXorCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const AArch64Subtarget *Subtarget) {
if (DCI.isBeforeLegalizeOps())
return SDValue();
- return foldVectorXorShiftIntoCmp(N, DAG, Subtarget);
+ return foldVectorXorShiftIntoCmp(N, DAG, Subtarget);
}
SDValue
@@ -11793,157 +11793,157 @@ static bool IsSVECntIntrinsic(SDValue S) {
return false;
}
-/// Calculates what the pre-extend type is, based on the extension
-/// operation node provided by \p Extend.
-///
-/// In the case that \p Extend is a SIGN_EXTEND or a ZERO_EXTEND, the
-/// pre-extend type is pulled directly from the operand, while other extend
-/// operations need a bit more inspection to get this information.
-///
-/// \param Extend The SDNode from the DAG that represents the extend operation
-/// \param DAG The SelectionDAG hosting the \p Extend node
-///
-/// \returns The type representing the \p Extend source type, or \p MVT::Other
-/// if no valid type can be determined
-static EVT calculatePreExtendType(SDValue Extend, SelectionDAG &DAG) {
- switch (Extend.getOpcode()) {
- case ISD::SIGN_EXTEND:
- case ISD::ZERO_EXTEND:
- return Extend.getOperand(0).getValueType();
- case ISD::AssertSext:
- case ISD::AssertZext:
- case ISD::SIGN_EXTEND_INREG: {
- VTSDNode *TypeNode = dyn_cast<VTSDNode>(Extend.getOperand(1));
- if (!TypeNode)
- return MVT::Other;
- return TypeNode->getVT();
- }
- case ISD::AND: {
- ConstantSDNode *Constant =
- dyn_cast<ConstantSDNode>(Extend.getOperand(1).getNode());
- if (!Constant)
- return MVT::Other;
-
- uint32_t Mask = Constant->getZExtValue();
-
- if (Mask == UCHAR_MAX)
- return MVT::i8;
- else if (Mask == USHRT_MAX)
- return MVT::i16;
- else if (Mask == UINT_MAX)
- return MVT::i32;
-
- return MVT::Other;
- }
- default:
- return MVT::Other;
- }
-
- llvm_unreachable("Code path unhandled in calculatePreExtendType!");
-}
-
-/// Combines a dup(sext/zext) node pattern into sext/zext(dup)
-/// making use of the vector SExt/ZExt rather than the scalar SExt/ZExt
-static SDValue performCommonVectorExtendCombine(SDValue VectorShuffle,
- SelectionDAG &DAG) {
-
- ShuffleVectorSDNode *ShuffleNode =
- dyn_cast<ShuffleVectorSDNode>(VectorShuffle.getNode());
- if (!ShuffleNode)
- return SDValue();
-
- // Ensuring the mask is zero before continuing
- if (!ShuffleNode->isSplat() || ShuffleNode->getSplatIndex() != 0)
- return SDValue();
-
- SDValue InsertVectorElt = VectorShuffle.getOperand(0);
-
- if (InsertVectorElt.getOpcode() != ISD::INSERT_VECTOR_ELT)
- return SDValue();
-
- SDValue InsertLane = InsertVectorElt.getOperand(2);
- ConstantSDNode *Constant = dyn_cast<ConstantSDNode>(InsertLane.getNode());
- // Ensures the insert is inserting into lane 0
- if (!Constant || Constant->getZExtValue() != 0)
- return SDValue();
-
- SDValue Extend = InsertVectorElt.getOperand(1);
- unsigned ExtendOpcode = Extend.getOpcode();
-
- bool IsSExt = ExtendOpcode == ISD::SIGN_EXTEND ||
- ExtendOpcode == ISD::SIGN_EXTEND_INREG ||
- ExtendOpcode == ISD::AssertSext;
- if (!IsSExt && ExtendOpcode != ISD::ZERO_EXTEND &&
- ExtendOpcode != ISD::AssertZext && ExtendOpcode != ISD::AND)
- return SDValue();
-
- EVT TargetType = VectorShuffle.getValueType();
- EVT PreExtendType = calculatePreExtendType(Extend, DAG);
-
- if ((TargetType != MVT::v8i16 && TargetType != MVT::v4i32 &&
- TargetType != MVT::v2i64) ||
- (PreExtendType == MVT::Other))
- return SDValue();
-
- // Restrict valid pre-extend data type
- if (PreExtendType != MVT::i8 && PreExtendType != MVT::i16 &&
- PreExtendType != MVT::i32)
- return SDValue();
-
- EVT PreExtendVT = TargetType.changeVectorElementType(PreExtendType);
-
- if (PreExtendVT.getVectorElementCount() != TargetType.getVectorElementCount())
- return SDValue();
-
- if (TargetType.getScalarSizeInBits() != PreExtendVT.getScalarSizeInBits() * 2)
- return SDValue();
-
- SDLoc DL(VectorShuffle);
-
- SDValue InsertVectorNode = DAG.getNode(
- InsertVectorElt.getOpcode(), DL, PreExtendVT, DAG.getUNDEF(PreExtendVT),
- DAG.getAnyExtOrTrunc(Extend.getOperand(0), DL, PreExtendType),
- DAG.getConstant(0, DL, MVT::i64));
-
- std::vector<int> ShuffleMask(TargetType.getVectorElementCount().getValue());
-
- SDValue VectorShuffleNode =
- DAG.getVectorShuffle(PreExtendVT, DL, InsertVectorNode,
- DAG.getUNDEF(PreExtendVT), ShuffleMask);
-
- SDValue ExtendNode = DAG.getNode(IsSExt ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
- DL, TargetType, VectorShuffleNode);
-
- return ExtendNode;
-}
-
-/// Combines a mul(dup(sext/zext)) node pattern into mul(sext/zext(dup))
-/// making use of the vector SExt/ZExt rather than the scalar SExt/ZExt
-static SDValue performMulVectorExtendCombine(SDNode *Mul, SelectionDAG &DAG) {
- // If the value type isn't a vector, none of the operands are going to be dups
- if (!Mul->getValueType(0).isVector())
- return SDValue();
-
- SDValue Op0 = performCommonVectorExtendCombine(Mul->getOperand(0), DAG);
- SDValue Op1 = performCommonVectorExtendCombine(Mul->getOperand(1), DAG);
-
- // Neither operands have been changed, don't make any further changes
- if (!Op0 && !Op1)
- return SDValue();
-
- SDLoc DL(Mul);
- return DAG.getNode(Mul->getOpcode(), DL, Mul->getValueType(0),
- Op0 ? Op0 : Mul->getOperand(0),
- Op1 ? Op1 : Mul->getOperand(1));
-}
-
+/// Calculates what the pre-extend type is, based on the extension
+/// operation node provided by \p Extend.
+///
+/// In the case that \p Extend is a SIGN_EXTEND or a ZERO_EXTEND, the
+/// pre-extend type is pulled directly from the operand, while other extend
+/// operations need a bit more inspection to get this information.
+///
+/// \param Extend The SDNode from the DAG that represents the extend operation
+/// \param DAG The SelectionDAG hosting the \p Extend node
+///
+/// \returns The type representing the \p Extend source type, or \p MVT::Other
+/// if no valid type can be determined
+static EVT calculatePreExtendType(SDValue Extend, SelectionDAG &DAG) {
+ switch (Extend.getOpcode()) {
+ case ISD::SIGN_EXTEND:
+ case ISD::ZERO_EXTEND:
+ return Extend.getOperand(0).getValueType();
+ case ISD::AssertSext:
+ case ISD::AssertZext:
+ case ISD::SIGN_EXTEND_INREG: {
+ VTSDNode *TypeNode = dyn_cast<VTSDNode>(Extend.getOperand(1));
+ if (!TypeNode)
+ return MVT::Other;
+ return TypeNode->getVT();
+ }
+ case ISD::AND: {
+ ConstantSDNode *Constant =
+ dyn_cast<ConstantSDNode>(Extend.getOperand(1).getNode());
+ if (!Constant)
+ return MVT::Other;
+
+ uint32_t Mask = Constant->getZExtValue();
+
+ if (Mask == UCHAR_MAX)
+ return MVT::i8;
+ else if (Mask == USHRT_MAX)
+ return MVT::i16;
+ else if (Mask == UINT_MAX)
+ return MVT::i32;
+
+ return MVT::Other;
+ }
+ default:
+ return MVT::Other;
+ }
+
+ llvm_unreachable("Code path unhandled in calculatePreExtendType!");
+}
+
+/// Combines a dup(sext/zext) node pattern into sext/zext(dup)
+/// making use of the vector SExt/ZExt rather than the scalar SExt/ZExt
+static SDValue performCommonVectorExtendCombine(SDValue VectorShuffle,
+ SelectionDAG &DAG) {
+
+ ShuffleVectorSDNode *ShuffleNode =
+ dyn_cast<ShuffleVectorSDNode>(VectorShuffle.getNode());
+ if (!ShuffleNode)
+ return SDValue();
+
+ // Ensuring the mask is zero before continuing
+ if (!ShuffleNode->isSplat() || ShuffleNode->getSplatIndex() != 0)
+ return SDValue();
+
+ SDValue InsertVectorElt = VectorShuffle.getOperand(0);
+
+ if (InsertVectorElt.getOpcode() != ISD::INSERT_VECTOR_ELT)
+ return SDValue();
+
+ SDValue InsertLane = InsertVectorElt.getOperand(2);
+ ConstantSDNode *Constant = dyn_cast<ConstantSDNode>(InsertLane.getNode());
+ // Ensures the insert is inserting into lane 0
+ if (!Constant || Constant->getZExtValue() != 0)
+ return SDValue();
+
+ SDValue Extend = InsertVectorElt.getOperand(1);
+ unsigned ExtendOpcode = Extend.getOpcode();
+
+ bool IsSExt = ExtendOpcode == ISD::SIGN_EXTEND ||
+ ExtendOpcode == ISD::SIGN_EXTEND_INREG ||
+ ExtendOpcode == ISD::AssertSext;
+ if (!IsSExt && ExtendOpcode != ISD::ZERO_EXTEND &&
+ ExtendOpcode != ISD::AssertZext && ExtendOpcode != ISD::AND)
+ return SDValue();
+
+ EVT TargetType = VectorShuffle.getValueType();
+ EVT PreExtendType = calculatePreExtendType(Extend, DAG);
+
+ if ((TargetType != MVT::v8i16 && TargetType != MVT::v4i32 &&
+ TargetType != MVT::v2i64) ||
+ (PreExtendType == MVT::Other))
+ return SDValue();
+
+ // Restrict valid pre-extend data type
+ if (PreExtendType != MVT::i8 && PreExtendType != MVT::i16 &&
+ PreExtendType != MVT::i32)
+ return SDValue();
+
+ EVT PreExtendVT = TargetType.changeVectorElementType(PreExtendType);
+
+ if (PreExtendVT.getVectorElementCount() != TargetType.getVectorElementCount())
+ return SDValue();
+
+ if (TargetType.getScalarSizeInBits() != PreExtendVT.getScalarSizeInBits() * 2)
+ return SDValue();
+
+ SDLoc DL(VectorShuffle);
+
+ SDValue InsertVectorNode = DAG.getNode(
+ InsertVectorElt.getOpcode(), DL, PreExtendVT, DAG.getUNDEF(PreExtendVT),
+ DAG.getAnyExtOrTrunc(Extend.getOperand(0), DL, PreExtendType),
+ DAG.getConstant(0, DL, MVT::i64));
+
+ std::vector<int> ShuffleMask(TargetType.getVectorElementCount().getValue());
+
+ SDValue VectorShuffleNode =
+ DAG.getVectorShuffle(PreExtendVT, DL, InsertVectorNode,
+ DAG.getUNDEF(PreExtendVT), ShuffleMask);
+
+ SDValue ExtendNode = DAG.getNode(IsSExt ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
+ DL, TargetType, VectorShuffleNode);
+
+ return ExtendNode;
+}
+
+/// Combines a mul(dup(sext/zext)) node pattern into mul(sext/zext(dup))
+/// making use of the vector SExt/ZExt rather than the scalar SExt/ZExt
+static SDValue performMulVectorExtendCombine(SDNode *Mul, SelectionDAG &DAG) {
+ // If the value type isn't a vector, none of the operands are going to be dups
+ if (!Mul->getValueType(0).isVector())
+ return SDValue();
+
+ SDValue Op0 = performCommonVectorExtendCombine(Mul->getOperand(0), DAG);
+ SDValue Op1 = performCommonVectorExtendCombine(Mul->getOperand(1), DAG);
+
+ // Neither operands have been changed, don't make any further changes
+ if (!Op0 && !Op1)
+ return SDValue();
+
+ SDLoc DL(Mul);
+ return DAG.getNode(Mul->getOpcode(), DL, Mul->getValueType(0),
+ Op0 ? Op0 : Mul->getOperand(0),
+ Op1 ? Op1 : Mul->getOperand(1));
+}
+
static SDValue performMulCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const AArch64Subtarget *Subtarget) {
-
- if (SDValue Ext = performMulVectorExtendCombine(N, DAG))
- return Ext;
-
+
+ if (SDValue Ext = performMulVectorExtendCombine(N, DAG))
+ return Ext;
+
if (DCI.isBeforeLegalizeOps())
return SDValue();
@@ -12478,9 +12478,9 @@ static SDValue performSVEAndCombine(SDNode *N,
return DAG.getNode(Opc, DL, N->getValueType(0), And);
}
- if (!EnableCombineMGatherIntrinsics)
- return SDValue();
-
+ if (!EnableCombineMGatherIntrinsics)
+ return SDValue();
+
SDValue Mask = N->getOperand(1);
if (!Src.hasOneUse())
@@ -12534,11 +12534,11 @@ static SDValue performANDCombine(SDNode *N,
if (VT.isScalableVector())
return performSVEAndCombine(N, DCI);
- // The combining code below works only for NEON vectors. In particular, it
- // does not work for SVE when dealing with vectors wider than 128 bits.
- if (!(VT.is64BitVector() || VT.is128BitVector()))
- return SDValue();
-
+ // The combining code below works only for NEON vectors. In particular, it
+ // does not work for SVE when dealing with vectors wider than 128 bits.
+ if (!(VT.is64BitVector() || VT.is128BitVector()))
+ return SDValue();
+
BuildVectorSDNode *BVN =
dyn_cast<BuildVectorSDNode>(N->getOperand(1).getNode());
if (!BVN)
@@ -12599,143 +12599,143 @@ static SDValue performSRLCombine(SDNode *N,
return SDValue();
}
-// Attempt to form urhadd(OpA, OpB) from
-// truncate(vlshr(sub(zext(OpB), xor(zext(OpA), Ones(ElemSizeInBits))), 1))
-// or uhadd(OpA, OpB) from truncate(vlshr(add(zext(OpA), zext(OpB)), 1)).
-// The original form of the first expression is
-// truncate(srl(add(zext(OpB), add(zext(OpA), 1)), 1)) and the
-// (OpA + OpB + 1) subexpression will have been changed to (OpB - (~OpA)).
-// Before this function is called the srl will have been lowered to
-// AArch64ISD::VLSHR.
-// This pass can also recognize signed variants of the patterns that use sign
-// extension instead of zero extension and form a srhadd(OpA, OpB) or a
-// shadd(OpA, OpB) from them.
-static SDValue
-performVectorTruncateCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
- SelectionDAG &DAG) {
- EVT VT = N->getValueType(0);
-
- // Since we are looking for a right shift by a constant value of 1 and we are
- // operating on types at least 16 bits in length (sign/zero extended OpA and
- // OpB, which are at least 8 bits), it follows that the truncate will always
- // discard the shifted-in bit and therefore the right shift will be logical
- // regardless of the signedness of OpA and OpB.
- SDValue Shift = N->getOperand(0);
- if (Shift.getOpcode() != AArch64ISD::VLSHR)
- return SDValue();
-
- // Is the right shift using an immediate value of 1?
- uint64_t ShiftAmount = Shift.getConstantOperandVal(1);
- if (ShiftAmount != 1)
- return SDValue();
-
- SDValue ExtendOpA, ExtendOpB;
- SDValue ShiftOp0 = Shift.getOperand(0);
- unsigned ShiftOp0Opc = ShiftOp0.getOpcode();
- if (ShiftOp0Opc == ISD::SUB) {
-
- SDValue Xor = ShiftOp0.getOperand(1);
- if (Xor.getOpcode() != ISD::XOR)
- return SDValue();
-
- // Is the XOR using a constant amount of all ones in the right hand side?
- uint64_t C;
- if (!isAllConstantBuildVector(Xor.getOperand(1), C))
- return SDValue();
-
- unsigned ElemSizeInBits = VT.getScalarSizeInBits();
- APInt CAsAPInt(ElemSizeInBits, C);
- if (CAsAPInt != APInt::getAllOnesValue(ElemSizeInBits))
- return SDValue();
-
- ExtendOpA = Xor.getOperand(0);
- ExtendOpB = ShiftOp0.getOperand(0);
- } else if (ShiftOp0Opc == ISD::ADD) {
- ExtendOpA = ShiftOp0.getOperand(0);
- ExtendOpB = ShiftOp0.getOperand(1);
- } else
- return SDValue();
-
- unsigned ExtendOpAOpc = ExtendOpA.getOpcode();
- unsigned ExtendOpBOpc = ExtendOpB.getOpcode();
- if (!(ExtendOpAOpc == ExtendOpBOpc &&
- (ExtendOpAOpc == ISD::ZERO_EXTEND || ExtendOpAOpc == ISD::SIGN_EXTEND)))
- return SDValue();
-
- // Is the result of the right shift being truncated to the same value type as
- // the original operands, OpA and OpB?
- SDValue OpA = ExtendOpA.getOperand(0);
- SDValue OpB = ExtendOpB.getOperand(0);
- EVT OpAVT = OpA.getValueType();
- assert(ExtendOpA.getValueType() == ExtendOpB.getValueType());
- if (!(VT == OpAVT && OpAVT == OpB.getValueType()))
- return SDValue();
-
- SDLoc DL(N);
- bool IsSignExtend = ExtendOpAOpc == ISD::SIGN_EXTEND;
- bool IsRHADD = ShiftOp0Opc == ISD::SUB;
- unsigned HADDOpc = IsSignExtend
- ? (IsRHADD ? AArch64ISD::SRHADD : AArch64ISD::SHADD)
- : (IsRHADD ? AArch64ISD::URHADD : AArch64ISD::UHADD);
- SDValue ResultHADD = DAG.getNode(HADDOpc, DL, VT, OpA, OpB);
-
- return ResultHADD;
-}
-
-static bool hasPairwiseAdd(unsigned Opcode, EVT VT, bool FullFP16) {
- switch (Opcode) {
- case ISD::FADD:
- return (FullFP16 && VT == MVT::f16) || VT == MVT::f32 || VT == MVT::f64;
- case ISD::ADD:
- return VT == MVT::i64;
- default:
- return false;
- }
-}
-
-static SDValue performExtractVectorEltCombine(SDNode *N, SelectionDAG &DAG) {
- SDValue N0 = N->getOperand(0), N1 = N->getOperand(1);
- ConstantSDNode *ConstantN1 = dyn_cast<ConstantSDNode>(N1);
-
- EVT VT = N->getValueType(0);
- const bool FullFP16 =
- static_cast<const AArch64Subtarget &>(DAG.getSubtarget()).hasFullFP16();
-
- // Rewrite for pairwise fadd pattern
- // (f32 (extract_vector_elt
- // (fadd (vXf32 Other)
- // (vector_shuffle (vXf32 Other) undef <1,X,...> )) 0))
- // ->
- // (f32 (fadd (extract_vector_elt (vXf32 Other) 0)
- // (extract_vector_elt (vXf32 Other) 1))
- if (ConstantN1 && ConstantN1->getZExtValue() == 0 &&
- hasPairwiseAdd(N0->getOpcode(), VT, FullFP16)) {
- SDLoc DL(N0);
- SDValue N00 = N0->getOperand(0);
- SDValue N01 = N0->getOperand(1);
-
- ShuffleVectorSDNode *Shuffle = dyn_cast<ShuffleVectorSDNode>(N01);
- SDValue Other = N00;
-
- // And handle the commutative case.
- if (!Shuffle) {
- Shuffle = dyn_cast<ShuffleVectorSDNode>(N00);
- Other = N01;
- }
-
- if (Shuffle && Shuffle->getMaskElt(0) == 1 &&
- Other == Shuffle->getOperand(0)) {
- return DAG.getNode(N0->getOpcode(), DL, VT,
- DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Other,
- DAG.getConstant(0, DL, MVT::i64)),
- DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Other,
- DAG.getConstant(1, DL, MVT::i64)));
- }
- }
-
- return SDValue();
-}
-
+// Attempt to form urhadd(OpA, OpB) from
+// truncate(vlshr(sub(zext(OpB), xor(zext(OpA), Ones(ElemSizeInBits))), 1))
+// or uhadd(OpA, OpB) from truncate(vlshr(add(zext(OpA), zext(OpB)), 1)).
+// The original form of the first expression is
+// truncate(srl(add(zext(OpB), add(zext(OpA), 1)), 1)) and the
+// (OpA + OpB + 1) subexpression will have been changed to (OpB - (~OpA)).
+// Before this function is called the srl will have been lowered to
+// AArch64ISD::VLSHR.
+// This pass can also recognize signed variants of the patterns that use sign
+// extension instead of zero extension and form a srhadd(OpA, OpB) or a
+// shadd(OpA, OpB) from them.
+static SDValue
+performVectorTruncateCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
+ SelectionDAG &DAG) {
+ EVT VT = N->getValueType(0);
+
+ // Since we are looking for a right shift by a constant value of 1 and we are
+ // operating on types at least 16 bits in length (sign/zero extended OpA and
+ // OpB, which are at least 8 bits), it follows that the truncate will always
+ // discard the shifted-in bit and therefore the right shift will be logical
+ // regardless of the signedness of OpA and OpB.
+ SDValue Shift = N->getOperand(0);
+ if (Shift.getOpcode() != AArch64ISD::VLSHR)
+ return SDValue();
+
+ // Is the right shift using an immediate value of 1?
+ uint64_t ShiftAmount = Shift.getConstantOperandVal(1);
+ if (ShiftAmount != 1)
+ return SDValue();
+
+ SDValue ExtendOpA, ExtendOpB;
+ SDValue ShiftOp0 = Shift.getOperand(0);
+ unsigned ShiftOp0Opc = ShiftOp0.getOpcode();
+ if (ShiftOp0Opc == ISD::SUB) {
+
+ SDValue Xor = ShiftOp0.getOperand(1);
+ if (Xor.getOpcode() != ISD::XOR)
+ return SDValue();
+
+ // Is the XOR using a constant amount of all ones in the right hand side?
+ uint64_t C;
+ if (!isAllConstantBuildVector(Xor.getOperand(1), C))
+ return SDValue();
+
+ unsigned ElemSizeInBits = VT.getScalarSizeInBits();
+ APInt CAsAPInt(ElemSizeInBits, C);
+ if (CAsAPInt != APInt::getAllOnesValue(ElemSizeInBits))
+ return SDValue();
+
+ ExtendOpA = Xor.getOperand(0);
+ ExtendOpB = ShiftOp0.getOperand(0);
+ } else if (ShiftOp0Opc == ISD::ADD) {
+ ExtendOpA = ShiftOp0.getOperand(0);
+ ExtendOpB = ShiftOp0.getOperand(1);
+ } else
+ return SDValue();
+
+ unsigned ExtendOpAOpc = ExtendOpA.getOpcode();
+ unsigned ExtendOpBOpc = ExtendOpB.getOpcode();
+ if (!(ExtendOpAOpc == ExtendOpBOpc &&
+ (ExtendOpAOpc == ISD::ZERO_EXTEND || ExtendOpAOpc == ISD::SIGN_EXTEND)))
+ return SDValue();
+
+ // Is the result of the right shift being truncated to the same value type as
+ // the original operands, OpA and OpB?
+ SDValue OpA = ExtendOpA.getOperand(0);
+ SDValue OpB = ExtendOpB.getOperand(0);
+ EVT OpAVT = OpA.getValueType();
+ assert(ExtendOpA.getValueType() == ExtendOpB.getValueType());
+ if (!(VT == OpAVT && OpAVT == OpB.getValueType()))
+ return SDValue();
+
+ SDLoc DL(N);
+ bool IsSignExtend = ExtendOpAOpc == ISD::SIGN_EXTEND;
+ bool IsRHADD = ShiftOp0Opc == ISD::SUB;
+ unsigned HADDOpc = IsSignExtend
+ ? (IsRHADD ? AArch64ISD::SRHADD : AArch64ISD::SHADD)
+ : (IsRHADD ? AArch64ISD::URHADD : AArch64ISD::UHADD);
+ SDValue ResultHADD = DAG.getNode(HADDOpc, DL, VT, OpA, OpB);
+
+ return ResultHADD;
+}
+
+static bool hasPairwiseAdd(unsigned Opcode, EVT VT, bool FullFP16) {
+ switch (Opcode) {
+ case ISD::FADD:
+ return (FullFP16 && VT == MVT::f16) || VT == MVT::f32 || VT == MVT::f64;
+ case ISD::ADD:
+ return VT == MVT::i64;
+ default:
+ return false;
+ }
+}
+
+static SDValue performExtractVectorEltCombine(SDNode *N, SelectionDAG &DAG) {
+ SDValue N0 = N->getOperand(0), N1 = N->getOperand(1);
+ ConstantSDNode *ConstantN1 = dyn_cast<ConstantSDNode>(N1);
+
+ EVT VT = N->getValueType(0);
+ const bool FullFP16 =
+ static_cast<const AArch64Subtarget &>(DAG.getSubtarget()).hasFullFP16();
+
+ // Rewrite for pairwise fadd pattern
+ // (f32 (extract_vector_elt
+ // (fadd (vXf32 Other)
+ // (vector_shuffle (vXf32 Other) undef <1,X,...> )) 0))
+ // ->
+ // (f32 (fadd (extract_vector_elt (vXf32 Other) 0)
+ // (extract_vector_elt (vXf32 Other) 1))
+ if (ConstantN1 && ConstantN1->getZExtValue() == 0 &&
+ hasPairwiseAdd(N0->getOpcode(), VT, FullFP16)) {
+ SDLoc DL(N0);
+ SDValue N00 = N0->getOperand(0);
+ SDValue N01 = N0->getOperand(1);
+
+ ShuffleVectorSDNode *Shuffle = dyn_cast<ShuffleVectorSDNode>(N01);
+ SDValue Other = N00;
+
+ // And handle the commutative case.
+ if (!Shuffle) {
+ Shuffle = dyn_cast<ShuffleVectorSDNode>(N00);
+ Other = N01;
+ }
+
+ if (Shuffle && Shuffle->getMaskElt(0) == 1 &&
+ Other == Shuffle->getOperand(0)) {
+ return DAG.getNode(N0->getOpcode(), DL, VT,
+ DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Other,
+ DAG.getConstant(0, DL, MVT::i64)),
+ DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Other,
+ DAG.getConstant(1, DL, MVT::i64)));
+ }
+ }
+
+ return SDValue();
+}
+
static SDValue performConcatVectorsCombine(SDNode *N,
TargetLowering::DAGCombinerInfo &DCI,
SelectionDAG &DAG) {
@@ -12781,9 +12781,9 @@ static SDValue performConcatVectorsCombine(SDNode *N,
if (DCI.isBeforeLegalizeOps())
return SDValue();
- // Optimise concat_vectors of two [us]rhadds or [us]hadds that use extracted
- // subvectors from the same original vectors. Combine these into a single
- // [us]rhadd or [us]hadd that operates on the two original vectors. Example:
+ // Optimise concat_vectors of two [us]rhadds or [us]hadds that use extracted
+ // subvectors from the same original vectors. Combine these into a single
+ // [us]rhadd or [us]hadd that operates on the two original vectors. Example:
// (v16i8 (concat_vectors (v8i8 (urhadd (extract_subvector (v16i8 OpA, <0>),
// extract_subvector (v16i8 OpB,
// <0>))),
@@ -12793,8 +12793,8 @@ static SDValue performConcatVectorsCombine(SDNode *N,
// ->
// (v16i8(urhadd(v16i8 OpA, v16i8 OpB)))
if (N->getNumOperands() == 2 && N0Opc == N1Opc &&
- (N0Opc == AArch64ISD::URHADD || N0Opc == AArch64ISD::SRHADD ||
- N0Opc == AArch64ISD::UHADD || N0Opc == AArch64ISD::SHADD)) {
+ (N0Opc == AArch64ISD::URHADD || N0Opc == AArch64ISD::SRHADD ||
+ N0Opc == AArch64ISD::UHADD || N0Opc == AArch64ISD::SHADD)) {
SDValue N00 = N0->getOperand(0);
SDValue N01 = N0->getOperand(1);
SDValue N10 = N1->getOperand(0);
@@ -13099,43 +13099,43 @@ static SDValue performSetccAddFolding(SDNode *Op, SelectionDAG &DAG) {
return DAG.getNode(AArch64ISD::CSEL, dl, VT, RHS, LHS, CCVal, Cmp);
}
-// ADD(UADDV a, UADDV b) --> UADDV(ADD a, b)
-static SDValue performUADDVCombine(SDNode *N, SelectionDAG &DAG) {
- EVT VT = N->getValueType(0);
- // Only scalar integer and vector types.
- if (N->getOpcode() != ISD::ADD || !VT.isScalarInteger())
- return SDValue();
-
- SDValue LHS = N->getOperand(0);
- SDValue RHS = N->getOperand(1);
- if (LHS.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
- RHS.getOpcode() != ISD::EXTRACT_VECTOR_ELT || LHS.getValueType() != VT)
- return SDValue();
-
- auto *LHSN1 = dyn_cast<ConstantSDNode>(LHS->getOperand(1));
- auto *RHSN1 = dyn_cast<ConstantSDNode>(RHS->getOperand(1));
- if (!LHSN1 || LHSN1 != RHSN1 || !RHSN1->isNullValue())
- return SDValue();
-
- SDValue Op1 = LHS->getOperand(0);
- SDValue Op2 = RHS->getOperand(0);
- EVT OpVT1 = Op1.getValueType();
- EVT OpVT2 = Op2.getValueType();
- if (Op1.getOpcode() != AArch64ISD::UADDV || OpVT1 != OpVT2 ||
- Op2.getOpcode() != AArch64ISD::UADDV ||
- OpVT1.getVectorElementType() != VT)
- return SDValue();
-
- SDValue Val1 = Op1.getOperand(0);
- SDValue Val2 = Op2.getOperand(0);
- EVT ValVT = Val1->getValueType(0);
- SDLoc DL(N);
- SDValue AddVal = DAG.getNode(ISD::ADD, DL, ValVT, Val1, Val2);
- return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT,
- DAG.getNode(AArch64ISD::UADDV, DL, ValVT, AddVal),
- DAG.getConstant(0, DL, MVT::i64));
-}
-
+// ADD(UADDV a, UADDV b) --> UADDV(ADD a, b)
+static SDValue performUADDVCombine(SDNode *N, SelectionDAG &DAG) {
+ EVT VT = N->getValueType(0);
+ // Only scalar integer and vector types.
+ if (N->getOpcode() != ISD::ADD || !VT.isScalarInteger())
+ return SDValue();
+
+ SDValue LHS = N->getOperand(0);
+ SDValue RHS = N->getOperand(1);
+ if (LHS.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
+ RHS.getOpcode() != ISD::EXTRACT_VECTOR_ELT || LHS.getValueType() != VT)
+ return SDValue();
+
+ auto *LHSN1 = dyn_cast<ConstantSDNode>(LHS->getOperand(1));
+ auto *RHSN1 = dyn_cast<ConstantSDNode>(RHS->getOperand(1));
+ if (!LHSN1 || LHSN1 != RHSN1 || !RHSN1->isNullValue())
+ return SDValue();
+
+ SDValue Op1 = LHS->getOperand(0);
+ SDValue Op2 = RHS->getOperand(0);
+ EVT OpVT1 = Op1.getValueType();
+ EVT OpVT2 = Op2.getValueType();
+ if (Op1.getOpcode() != AArch64ISD::UADDV || OpVT1 != OpVT2 ||
+ Op2.getOpcode() != AArch64ISD::UADDV ||
+ OpVT1.getVectorElementType() != VT)
+ return SDValue();
+
+ SDValue Val1 = Op1.getOperand(0);
+ SDValue Val2 = Op2.getOperand(0);
+ EVT ValVT = Val1->getValueType(0);
+ SDLoc DL(N);
+ SDValue AddVal = DAG.getNode(ISD::ADD, DL, ValVT, Val1, Val2);
+ return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT,
+ DAG.getNode(AArch64ISD::UADDV, DL, ValVT, AddVal),
+ DAG.getConstant(0, DL, MVT::i64));
+}
+
// The basic add/sub long vector instructions have variants with "2" on the end
// which act on the high-half of their inputs. They are normally matched by
// patterns like:
@@ -13189,16 +13189,16 @@ static SDValue performAddSubLongCombine(SDNode *N,
return DAG.getNode(N->getOpcode(), SDLoc(N), VT, LHS, RHS);
}
-static SDValue performAddSubCombine(SDNode *N,
- TargetLowering::DAGCombinerInfo &DCI,
- SelectionDAG &DAG) {
- // Try to change sum of two reductions.
- if (SDValue Val = performUADDVCombine(N, DAG))
- return Val;
-
- return performAddSubLongCombine(N, DCI, DAG);
-}
-
+static SDValue performAddSubCombine(SDNode *N,
+ TargetLowering::DAGCombinerInfo &DCI,
+ SelectionDAG &DAG) {
+ // Try to change sum of two reductions.
+ if (SDValue Val = performUADDVCombine(N, DAG))
+ return Val;
+
+ return performAddSubLongCombine(N, DCI, DAG);
+}
+
// Massage DAGs which we can use the high-half "long" operations on into
// something isel will recognize better. E.g.
//
@@ -13212,8 +13212,8 @@ static SDValue tryCombineLongOpWithDup(unsigned IID, SDNode *N,
if (DCI.isBeforeLegalizeOps())
return SDValue();
- SDValue LHS = N->getOperand((IID == Intrinsic::not_intrinsic) ? 0 : 1);
- SDValue RHS = N->getOperand((IID == Intrinsic::not_intrinsic) ? 1 : 2);
+ SDValue LHS = N->getOperand((IID == Intrinsic::not_intrinsic) ? 0 : 1);
+ SDValue RHS = N->getOperand((IID == Intrinsic::not_intrinsic) ? 1 : 2);
assert(LHS.getValueType().is64BitVector() &&
RHS.getValueType().is64BitVector() &&
"unexpected shape for long operation");
@@ -13231,9 +13231,9 @@ static SDValue tryCombineLongOpWithDup(unsigned IID, SDNode *N,
return SDValue();
}
- if (IID == Intrinsic::not_intrinsic)
- return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0), LHS, RHS);
-
+ if (IID == Intrinsic::not_intrinsic)
+ return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0), LHS, RHS);
+
return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, SDLoc(N), N->getValueType(0),
N->getOperand(0), LHS, RHS);
}
@@ -13374,8 +13374,8 @@ static SDValue LowerSVEIntrinsicEXT(SDNode *N, SelectionDAG &DAG) {
unsigned ElemSize = VT.getVectorElementType().getSizeInBits() / 8;
unsigned ByteSize = VT.getSizeInBits().getKnownMinSize() / 8;
- EVT ByteVT =
- EVT::getVectorVT(Ctx, MVT::i8, ElementCount::getScalable(ByteSize));
+ EVT ByteVT =
+ EVT::getVectorVT(Ctx, MVT::i8, ElementCount::getScalable(ByteSize));
// Convert everything to the domain of EXT (i.e bytes).
SDValue Op0 = DAG.getNode(ISD::BITCAST, dl, ByteVT, N->getOperand(1));
@@ -13475,25 +13475,25 @@ static SDValue getPTest(SelectionDAG &DAG, EVT VT, SDValue Pg, SDValue Op,
return DAG.getZExtOrTrunc(Res, DL, VT);
}
-static SDValue combineSVEReductionInt(SDNode *N, unsigned Opc,
- SelectionDAG &DAG) {
- SDLoc DL(N);
-
- SDValue Pred = N->getOperand(1);
- SDValue VecToReduce = N->getOperand(2);
-
- // NOTE: The integer reduction's result type is not always linked to the
- // operand's element type so we construct it from the intrinsic's result type.
- EVT ReduceVT = getPackedSVEVectorVT(N->getValueType(0));
- SDValue Reduce = DAG.getNode(Opc, DL, ReduceVT, Pred, VecToReduce);
-
- // SVE reductions set the whole vector register with the first element
- // containing the reduction result, which we'll now extract.
- SDValue Zero = DAG.getConstant(0, DL, MVT::i64);
- return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, N->getValueType(0), Reduce,
- Zero);
-}
-
+static SDValue combineSVEReductionInt(SDNode *N, unsigned Opc,
+ SelectionDAG &DAG) {
+ SDLoc DL(N);
+
+ SDValue Pred = N->getOperand(1);
+ SDValue VecToReduce = N->getOperand(2);
+
+ // NOTE: The integer reduction's result type is not always linked to the
+ // operand's element type so we construct it from the intrinsic's result type.
+ EVT ReduceVT = getPackedSVEVectorVT(N->getValueType(0));
+ SDValue Reduce = DAG.getNode(Opc, DL, ReduceVT, Pred, VecToReduce);
+
+ // SVE reductions set the whole vector register with the first element
+ // containing the reduction result, which we'll now extract.
+ SDValue Zero = DAG.getConstant(0, DL, MVT::i64);
+ return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, N->getValueType(0), Reduce,
+ Zero);
+}
+
static SDValue combineSVEReductionFP(SDNode *N, unsigned Opc,
SelectionDAG &DAG) {
SDLoc DL(N);
@@ -13534,25 +13534,25 @@ static SDValue combineSVEReductionOrderedFP(SDNode *N, unsigned Opc,
Zero);
}
-// If a merged operation has no inactive lanes we can relax it to a predicated
-// or unpredicated operation, which potentially allows better isel (perhaps
-// using immediate forms) or relaxing register reuse requirements.
-static SDValue convertMergedOpToPredOp(SDNode *N, unsigned PredOpc,
- SelectionDAG &DAG) {
- assert(N->getOpcode() == ISD::INTRINSIC_WO_CHAIN && "Expected intrinsic!");
- assert(N->getNumOperands() == 4 && "Expected 3 operand intrinsic!");
- SDValue Pg = N->getOperand(1);
-
- // ISD way to specify an all active predicate.
- if ((Pg.getOpcode() == AArch64ISD::PTRUE) &&
- (Pg.getConstantOperandVal(0) == AArch64SVEPredPattern::all))
- return DAG.getNode(PredOpc, SDLoc(N), N->getValueType(0), Pg,
- N->getOperand(2), N->getOperand(3));
-
- // FUTURE: SplatVector(true)
- return SDValue();
-}
-
+// If a merged operation has no inactive lanes we can relax it to a predicated
+// or unpredicated operation, which potentially allows better isel (perhaps
+// using immediate forms) or relaxing register reuse requirements.
+static SDValue convertMergedOpToPredOp(SDNode *N, unsigned PredOpc,
+ SelectionDAG &DAG) {
+ assert(N->getOpcode() == ISD::INTRINSIC_WO_CHAIN && "Expected intrinsic!");
+ assert(N->getNumOperands() == 4 && "Expected 3 operand intrinsic!");
+ SDValue Pg = N->getOperand(1);
+
+ // ISD way to specify an all active predicate.
+ if ((Pg.getOpcode() == AArch64ISD::PTRUE) &&
+ (Pg.getConstantOperandVal(0) == AArch64SVEPredPattern::all))
+ return DAG.getNode(PredOpc, SDLoc(N), N->getValueType(0), Pg,
+ N->getOperand(2), N->getOperand(3));
+
+ // FUTURE: SplatVector(true)
+ return SDValue();
+}
+
static SDValue performIntrinsicCombine(SDNode *N,
TargetLowering::DAGCombinerInfo &DCI,
const AArch64Subtarget *Subtarget) {
@@ -13607,28 +13607,28 @@ static SDValue performIntrinsicCombine(SDNode *N,
case Intrinsic::aarch64_crc32h:
case Intrinsic::aarch64_crc32ch:
return tryCombineCRC32(0xffff, N, DAG);
- case Intrinsic::aarch64_sve_saddv:
- // There is no i64 version of SADDV because the sign is irrelevant.
- if (N->getOperand(2)->getValueType(0).getVectorElementType() == MVT::i64)
- return combineSVEReductionInt(N, AArch64ISD::UADDV_PRED, DAG);
- else
- return combineSVEReductionInt(N, AArch64ISD::SADDV_PRED, DAG);
- case Intrinsic::aarch64_sve_uaddv:
- return combineSVEReductionInt(N, AArch64ISD::UADDV_PRED, DAG);
+ case Intrinsic::aarch64_sve_saddv:
+ // There is no i64 version of SADDV because the sign is irrelevant.
+ if (N->getOperand(2)->getValueType(0).getVectorElementType() == MVT::i64)
+ return combineSVEReductionInt(N, AArch64ISD::UADDV_PRED, DAG);
+ else
+ return combineSVEReductionInt(N, AArch64ISD::SADDV_PRED, DAG);
+ case Intrinsic::aarch64_sve_uaddv:
+ return combineSVEReductionInt(N, AArch64ISD::UADDV_PRED, DAG);
case Intrinsic::aarch64_sve_smaxv:
- return combineSVEReductionInt(N, AArch64ISD::SMAXV_PRED, DAG);
+ return combineSVEReductionInt(N, AArch64ISD::SMAXV_PRED, DAG);
case Intrinsic::aarch64_sve_umaxv:
- return combineSVEReductionInt(N, AArch64ISD::UMAXV_PRED, DAG);
+ return combineSVEReductionInt(N, AArch64ISD::UMAXV_PRED, DAG);
case Intrinsic::aarch64_sve_sminv:
- return combineSVEReductionInt(N, AArch64ISD::SMINV_PRED, DAG);
+ return combineSVEReductionInt(N, AArch64ISD::SMINV_PRED, DAG);
case Intrinsic::aarch64_sve_uminv:
- return combineSVEReductionInt(N, AArch64ISD::UMINV_PRED, DAG);
+ return combineSVEReductionInt(N, AArch64ISD::UMINV_PRED, DAG);
case Intrinsic::aarch64_sve_orv:
- return combineSVEReductionInt(N, AArch64ISD::ORV_PRED, DAG);
+ return combineSVEReductionInt(N, AArch64ISD::ORV_PRED, DAG);
case Intrinsic::aarch64_sve_eorv:
- return combineSVEReductionInt(N, AArch64ISD::EORV_PRED, DAG);
+ return combineSVEReductionInt(N, AArch64ISD::EORV_PRED, DAG);
case Intrinsic::aarch64_sve_andv:
- return combineSVEReductionInt(N, AArch64ISD::ANDV_PRED, DAG);
+ return combineSVEReductionInt(N, AArch64ISD::ANDV_PRED, DAG);
case Intrinsic::aarch64_sve_index:
return LowerSVEIntrinsicIndex(N, DAG);
case Intrinsic::aarch64_sve_dup:
@@ -13639,19 +13639,19 @@ static SDValue performIntrinsicCombine(SDNode *N,
case Intrinsic::aarch64_sve_ext:
return LowerSVEIntrinsicEXT(N, DAG);
case Intrinsic::aarch64_sve_smin:
- return convertMergedOpToPredOp(N, AArch64ISD::SMIN_PRED, DAG);
+ return convertMergedOpToPredOp(N, AArch64ISD::SMIN_PRED, DAG);
case Intrinsic::aarch64_sve_umin:
- return convertMergedOpToPredOp(N, AArch64ISD::UMIN_PRED, DAG);
+ return convertMergedOpToPredOp(N, AArch64ISD::UMIN_PRED, DAG);
case Intrinsic::aarch64_sve_smax:
- return convertMergedOpToPredOp(N, AArch64ISD::SMAX_PRED, DAG);
+ return convertMergedOpToPredOp(N, AArch64ISD::SMAX_PRED, DAG);
case Intrinsic::aarch64_sve_umax:
- return convertMergedOpToPredOp(N, AArch64ISD::UMAX_PRED, DAG);
+ return convertMergedOpToPredOp(N, AArch64ISD::UMAX_PRED, DAG);
case Intrinsic::aarch64_sve_lsl:
- return convertMergedOpToPredOp(N, AArch64ISD::SHL_PRED, DAG);
+ return convertMergedOpToPredOp(N, AArch64ISD::SHL_PRED, DAG);
case Intrinsic::aarch64_sve_lsr:
- return convertMergedOpToPredOp(N, AArch64ISD::SRL_PRED, DAG);
+ return convertMergedOpToPredOp(N, AArch64ISD::SRL_PRED, DAG);
case Intrinsic::aarch64_sve_asr:
- return convertMergedOpToPredOp(N, AArch64ISD::SRA_PRED, DAG);
+ return convertMergedOpToPredOp(N, AArch64ISD::SRA_PRED, DAG);
case Intrinsic::aarch64_sve_cmphs:
if (!N->getOperand(2).getValueType().isFloatingPoint())
return DAG.getNode(AArch64ISD::SETCC_MERGE_ZERO, SDLoc(N),
@@ -13744,15 +13744,15 @@ static SDValue performExtendCombine(SDNode *N,
// helps the backend to decide that an sabdl2 would be useful, saving a real
// extract_high operation.
if (!DCI.isBeforeLegalizeOps() && N->getOpcode() == ISD::ZERO_EXTEND &&
- (N->getOperand(0).getOpcode() == AArch64ISD::UABD ||
- N->getOperand(0).getOpcode() == AArch64ISD::SABD)) {
+ (N->getOperand(0).getOpcode() == AArch64ISD::UABD ||
+ N->getOperand(0).getOpcode() == AArch64ISD::SABD)) {
SDNode *ABDNode = N->getOperand(0).getNode();
- SDValue NewABD =
- tryCombineLongOpWithDup(Intrinsic::not_intrinsic, ABDNode, DCI, DAG);
- if (!NewABD.getNode())
- return SDValue();
+ SDValue NewABD =
+ tryCombineLongOpWithDup(Intrinsic::not_intrinsic, ABDNode, DCI, DAG);
+ if (!NewABD.getNode())
+ return SDValue();
- return DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), N->getValueType(0), NewABD);
+ return DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), N->getValueType(0), NewABD);
}
// This is effectively a custom type legalization for AArch64.
@@ -14235,31 +14235,31 @@ static SDValue splitStores(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
S->getMemOperand()->getFlags());
}
-static SDValue performUzpCombine(SDNode *N, SelectionDAG &DAG) {
- SDLoc DL(N);
- SDValue Op0 = N->getOperand(0);
- SDValue Op1 = N->getOperand(1);
- EVT ResVT = N->getValueType(0);
-
- // uzp1(unpklo(uzp1(x, y)), z) => uzp1(x, z)
- if (Op0.getOpcode() == AArch64ISD::UUNPKLO) {
- if (Op0.getOperand(0).getOpcode() == AArch64ISD::UZP1) {
- SDValue X = Op0.getOperand(0).getOperand(0);
- return DAG.getNode(AArch64ISD::UZP1, DL, ResVT, X, Op1);
- }
- }
-
- // uzp1(x, unpkhi(uzp1(y, z))) => uzp1(x, z)
- if (Op1.getOpcode() == AArch64ISD::UUNPKHI) {
- if (Op1.getOperand(0).getOpcode() == AArch64ISD::UZP1) {
- SDValue Z = Op1.getOperand(0).getOperand(1);
- return DAG.getNode(AArch64ISD::UZP1, DL, ResVT, Op0, Z);
- }
- }
-
- return SDValue();
-}
-
+static SDValue performUzpCombine(SDNode *N, SelectionDAG &DAG) {
+ SDLoc DL(N);
+ SDValue Op0 = N->getOperand(0);
+ SDValue Op1 = N->getOperand(1);
+ EVT ResVT = N->getValueType(0);
+
+ // uzp1(unpklo(uzp1(x, y)), z) => uzp1(x, z)
+ if (Op0.getOpcode() == AArch64ISD::UUNPKLO) {
+ if (Op0.getOperand(0).getOpcode() == AArch64ISD::UZP1) {
+ SDValue X = Op0.getOperand(0).getOperand(0);
+ return DAG.getNode(AArch64ISD::UZP1, DL, ResVT, X, Op1);
+ }
+ }
+
+ // uzp1(x, unpkhi(uzp1(y, z))) => uzp1(x, z)
+ if (Op1.getOpcode() == AArch64ISD::UUNPKHI) {
+ if (Op1.getOperand(0).getOpcode() == AArch64ISD::UZP1) {
+ SDValue Z = Op1.getOperand(0).getOperand(1);
+ return DAG.getNode(AArch64ISD::UZP1, DL, ResVT, Op0, Z);
+ }
+ }
+
+ return SDValue();
+}
+
/// Target-specific DAG combine function for post-increment LD1 (lane) and
/// post-increment LD1R.
static SDValue performPostLD1Combine(SDNode *N,
@@ -14398,55 +14398,55 @@ static SDValue performSTORECombine(SDNode *N,
return SDValue();
}
-static SDValue performMaskedGatherScatterCombine(SDNode *N,
- TargetLowering::DAGCombinerInfo &DCI,
- SelectionDAG &DAG) {
- MaskedGatherScatterSDNode *MGS = cast<MaskedGatherScatterSDNode>(N);
- assert(MGS && "Can only combine gather load or scatter store nodes");
-
- SDLoc DL(MGS);
- SDValue Chain = MGS->getChain();
- SDValue Scale = MGS->getScale();
- SDValue Index = MGS->getIndex();
- SDValue Mask = MGS->getMask();
- SDValue BasePtr = MGS->getBasePtr();
- ISD::MemIndexType IndexType = MGS->getIndexType();
-
- EVT IdxVT = Index.getValueType();
-
- if (DCI.isBeforeLegalize()) {
- // SVE gather/scatter requires indices of i32/i64. Promote anything smaller
- // prior to legalisation so the result can be split if required.
- if ((IdxVT.getVectorElementType() == MVT::i8) ||
- (IdxVT.getVectorElementType() == MVT::i16)) {
- EVT NewIdxVT = IdxVT.changeVectorElementType(MVT::i32);
- if (MGS->isIndexSigned())
- Index = DAG.getNode(ISD::SIGN_EXTEND, DL, NewIdxVT, Index);
- else
- Index = DAG.getNode(ISD::ZERO_EXTEND, DL, NewIdxVT, Index);
-
- if (auto *MGT = dyn_cast<MaskedGatherSDNode>(MGS)) {
- SDValue PassThru = MGT->getPassThru();
- SDValue Ops[] = { Chain, PassThru, Mask, BasePtr, Index, Scale };
- return DAG.getMaskedGather(DAG.getVTList(N->getValueType(0), MVT::Other),
- PassThru.getValueType(), DL, Ops,
- MGT->getMemOperand(),
- MGT->getIndexType(), MGT->getExtensionType());
- } else {
- auto *MSC = cast<MaskedScatterSDNode>(MGS);
- SDValue Data = MSC->getValue();
- SDValue Ops[] = { Chain, Data, Mask, BasePtr, Index, Scale };
- return DAG.getMaskedScatter(DAG.getVTList(MVT::Other),
- MSC->getMemoryVT(), DL, Ops,
- MSC->getMemOperand(), IndexType,
- MSC->isTruncatingStore());
- }
- }
- }
-
- return SDValue();
-}
-
+static SDValue performMaskedGatherScatterCombine(SDNode *N,
+ TargetLowering::DAGCombinerInfo &DCI,
+ SelectionDAG &DAG) {
+ MaskedGatherScatterSDNode *MGS = cast<MaskedGatherScatterSDNode>(N);
+ assert(MGS && "Can only combine gather load or scatter store nodes");
+
+ SDLoc DL(MGS);
+ SDValue Chain = MGS->getChain();
+ SDValue Scale = MGS->getScale();
+ SDValue Index = MGS->getIndex();
+ SDValue Mask = MGS->getMask();
+ SDValue BasePtr = MGS->getBasePtr();
+ ISD::MemIndexType IndexType = MGS->getIndexType();
+
+ EVT IdxVT = Index.getValueType();
+
+ if (DCI.isBeforeLegalize()) {
+ // SVE gather/scatter requires indices of i32/i64. Promote anything smaller
+ // prior to legalisation so the result can be split if required.
+ if ((IdxVT.getVectorElementType() == MVT::i8) ||
+ (IdxVT.getVectorElementType() == MVT::i16)) {
+ EVT NewIdxVT = IdxVT.changeVectorElementType(MVT::i32);
+ if (MGS->isIndexSigned())
+ Index = DAG.getNode(ISD::SIGN_EXTEND, DL, NewIdxVT, Index);
+ else
+ Index = DAG.getNode(ISD::ZERO_EXTEND, DL, NewIdxVT, Index);
+
+ if (auto *MGT = dyn_cast<MaskedGatherSDNode>(MGS)) {
+ SDValue PassThru = MGT->getPassThru();
+ SDValue Ops[] = { Chain, PassThru, Mask, BasePtr, Index, Scale };
+ return DAG.getMaskedGather(DAG.getVTList(N->getValueType(0), MVT::Other),
+ PassThru.getValueType(), DL, Ops,
+ MGT->getMemOperand(),
+ MGT->getIndexType(), MGT->getExtensionType());
+ } else {
+ auto *MSC = cast<MaskedScatterSDNode>(MGS);
+ SDValue Data = MSC->getValue();
+ SDValue Ops[] = { Chain, Data, Mask, BasePtr, Index, Scale };
+ return DAG.getMaskedScatter(DAG.getVTList(MVT::Other),
+ MSC->getMemoryVT(), DL, Ops,
+ MSC->getMemOperand(), IndexType,
+ MSC->isTruncatingStore());
+ }
+ }
+ }
+
+ return SDValue();
+}
+
/// Target-specific DAG combine function for NEON load/store intrinsics
/// to merge base address updates.
static SDValue performNEONPostLDSTCombine(SDNode *N,
@@ -15443,7 +15443,7 @@ performSignExtendInRegCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
assert((EltTy == MVT::i8 || EltTy == MVT::i16 || EltTy == MVT::i32) &&
"Sign extending from an invalid type");
- EVT ExtVT = VT.getDoubleNumVectorElementsVT(*DAG.getContext());
+ EVT ExtVT = VT.getDoubleNumVectorElementsVT(*DAG.getContext());
SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, ExtOp.getValueType(),
ExtOp, DAG.getValueType(ExtVT));
@@ -15451,12 +15451,12 @@ performSignExtendInRegCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
return DAG.getNode(SOpc, DL, N->getValueType(0), Ext);
}
- if (DCI.isBeforeLegalizeOps())
- return SDValue();
-
- if (!EnableCombineMGatherIntrinsics)
- return SDValue();
-
+ if (DCI.isBeforeLegalizeOps())
+ return SDValue();
+
+ if (!EnableCombineMGatherIntrinsics)
+ return SDValue();
+
// SVE load nodes (e.g. AArch64ISD::GLD1) are straightforward candidates
// for DAG Combine with SIGN_EXTEND_INREG. Bail out for all other nodes.
unsigned NewOpc;
@@ -15596,11 +15596,11 @@ SDValue AArch64TargetLowering::PerformDAGCombine(SDNode *N,
default:
LLVM_DEBUG(dbgs() << "Custom combining: skipping\n");
break;
- case ISD::ABS:
- return performABSCombine(N, DAG, DCI, Subtarget);
+ case ISD::ABS:
+ return performABSCombine(N, DAG, DCI, Subtarget);
case ISD::ADD:
case ISD::SUB:
- return performAddSubCombine(N, DCI, DAG);
+ return performAddSubCombine(N, DCI, DAG);
case ISD::XOR:
return performXorCombine(N, DAG, DCI, Subtarget);
case ISD::MUL:
@@ -15627,8 +15627,8 @@ SDValue AArch64TargetLowering::PerformDAGCombine(SDNode *N,
return performExtendCombine(N, DCI, DAG);
case ISD::SIGN_EXTEND_INREG:
return performSignExtendInRegCombine(N, DCI, DAG);
- case ISD::TRUNCATE:
- return performVectorTruncateCombine(N, DCI, DAG);
+ case ISD::TRUNCATE:
+ return performVectorTruncateCombine(N, DCI, DAG);
case ISD::CONCAT_VECTORS:
return performConcatVectorsCombine(N, DCI, DAG);
case ISD::SELECT:
@@ -15641,9 +15641,9 @@ SDValue AArch64TargetLowering::PerformDAGCombine(SDNode *N,
break;
case ISD::STORE:
return performSTORECombine(N, DCI, DAG, Subtarget);
- case ISD::MGATHER:
- case ISD::MSCATTER:
- return performMaskedGatherScatterCombine(N, DCI, DAG);
+ case ISD::MGATHER:
+ case ISD::MSCATTER:
+ return performMaskedGatherScatterCombine(N, DCI, DAG);
case AArch64ISD::BRCOND:
return performBRCONDCombine(N, DCI, DAG);
case AArch64ISD::TBNZ:
@@ -15655,14 +15655,14 @@ SDValue AArch64TargetLowering::PerformDAGCombine(SDNode *N,
return performPostLD1Combine(N, DCI, false);
case AArch64ISD::NVCAST:
return performNVCASTCombine(N);
- case AArch64ISD::UZP1:
- return performUzpCombine(N, DAG);
+ case AArch64ISD::UZP1:
+ return performUzpCombine(N, DAG);
case ISD::INSERT_VECTOR_ELT:
return performPostLD1Combine(N, DCI, true);
- case ISD::EXTRACT_VECTOR_ELT:
- return performExtractVectorEltCombine(N, DAG);
- case ISD::VECREDUCE_ADD:
- return performVecReduceAddCombine(N, DCI.DAG, Subtarget);
+ case ISD::EXTRACT_VECTOR_ELT:
+ return performExtractVectorEltCombine(N, DAG);
+ case ISD::VECREDUCE_ADD:
+ return performVecReduceAddCombine(N, DCI.DAG, Subtarget);
case ISD::INTRINSIC_VOID:
case ISD::INTRINSIC_W_CHAIN:
switch (cast<ConstantSDNode>(N->getOperand(1))->getZExtValue()) {
@@ -15811,10 +15811,10 @@ SDValue AArch64TargetLowering::PerformDAGCombine(SDNode *N,
uint64_t IdxConst = cast<ConstantSDNode>(Idx)->getZExtValue();
EVT ResVT = N->getValueType(0);
- uint64_t NumLanes = ResVT.getVectorElementCount().getKnownMinValue();
- SDValue ExtIdx = DAG.getVectorIdxConstant(IdxConst * NumLanes, DL);
+ uint64_t NumLanes = ResVT.getVectorElementCount().getKnownMinValue();
+ SDValue ExtIdx = DAG.getVectorIdxConstant(IdxConst * NumLanes, DL);
SDValue Val =
- DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, ResVT, Src1, ExtIdx);
+ DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, ResVT, Src1, ExtIdx);
return DAG.getMergeValues({Val, Chain}, DL);
}
case Intrinsic::aarch64_sve_tuple_set: {
@@ -15825,11 +15825,11 @@ SDValue AArch64TargetLowering::PerformDAGCombine(SDNode *N,
SDValue Vec = N->getOperand(4);
EVT TupleVT = Tuple.getValueType();
- uint64_t TupleLanes = TupleVT.getVectorElementCount().getKnownMinValue();
+ uint64_t TupleLanes = TupleVT.getVectorElementCount().getKnownMinValue();
uint64_t IdxConst = cast<ConstantSDNode>(Idx)->getZExtValue();
- uint64_t NumLanes =
- Vec.getValueType().getVectorElementCount().getKnownMinValue();
+ uint64_t NumLanes =
+ Vec.getValueType().getVectorElementCount().getKnownMinValue();
if ((TupleLanes % NumLanes) != 0)
report_fatal_error("invalid tuple vector!");
@@ -15841,9 +15841,9 @@ SDValue AArch64TargetLowering::PerformDAGCombine(SDNode *N,
if (I == IdxConst)
Opnds.push_back(Vec);
else {
- SDValue ExtIdx = DAG.getVectorIdxConstant(I * NumLanes, DL);
- Opnds.push_back(DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL,
- Vec.getValueType(), Tuple, ExtIdx));
+ SDValue ExtIdx = DAG.getVectorIdxConstant(I * NumLanes, DL);
+ Opnds.push_back(DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL,
+ Vec.getValueType(), Tuple, ExtIdx));
}
}
SDValue Concat =
@@ -16065,7 +16065,7 @@ void AArch64TargetLowering::ReplaceExtractSubVectorResults(
ElementCount ResEC = VT.getVectorElementCount();
- if (InVT.getVectorElementCount() != (ResEC * 2))
+ if (InVT.getVectorElementCount() != (ResEC * 2))
return;
auto *CIndex = dyn_cast<ConstantSDNode>(N->getOperand(1));
@@ -16073,7 +16073,7 @@ void AArch64TargetLowering::ReplaceExtractSubVectorResults(
return;
unsigned Index = CIndex->getZExtValue();
- if ((Index != 0) && (Index != ResEC.getKnownMinValue()))
+ if ((Index != 0) && (Index != ResEC.getKnownMinValue()))
return;
unsigned Opcode = (Index == 0) ? AArch64ISD::UUNPKLO : AArch64ISD::UUNPKHI;
@@ -16108,7 +16108,7 @@ static void ReplaceCMP_SWAP_128Results(SDNode *N,
assert(N->getValueType(0) == MVT::i128 &&
"AtomicCmpSwap on types less than 128 should be legal");
- if (Subtarget->hasLSE() || Subtarget->outlineAtomics()) {
+ if (Subtarget->hasLSE() || Subtarget->outlineAtomics()) {
// LSE has a 128-bit compare and swap (CASP), but i128 is not a legal type,
// so lower it here, wrapped in REG_SEQUENCE and EXTRACT_SUBREG.
SDValue Ops[] = {
@@ -16189,8 +16189,8 @@ void AArch64TargetLowering::ReplaceNodeResults(
return;
case ISD::CTPOP:
- if (SDValue Result = LowerCTPOP(SDValue(N, 0), DAG))
- Results.push_back(Result);
+ if (SDValue Result = LowerCTPOP(SDValue(N, 0), DAG))
+ Results.push_back(Result);
return;
case AArch64ISD::SADDV:
ReplaceReductionResults(N, Results, DAG, ISD::ADD, AArch64ISD::SADDV);
@@ -16335,44 +16335,44 @@ AArch64TargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
unsigned Size = AI->getType()->getPrimitiveSizeInBits();
if (Size > 128) return AtomicExpansionKind::None;
-
- // Nand is not supported in LSE.
- // Leave 128 bits to LLSC or CmpXChg.
- if (AI->getOperation() != AtomicRMWInst::Nand && Size < 128) {
- if (Subtarget->hasLSE())
- return AtomicExpansionKind::None;
- if (Subtarget->outlineAtomics()) {
- // [U]Min/[U]Max RWM atomics are used in __sync_fetch_ libcalls so far.
- // Don't outline them unless
- // (1) high level <atomic> support approved:
- // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p0493r1.pdf
- // (2) low level libgcc and compiler-rt support implemented by:
- // min/max outline atomics helpers
- if (AI->getOperation() != AtomicRMWInst::Min &&
- AI->getOperation() != AtomicRMWInst::Max &&
- AI->getOperation() != AtomicRMWInst::UMin &&
- AI->getOperation() != AtomicRMWInst::UMax) {
- return AtomicExpansionKind::None;
- }
- }
- }
-
- // At -O0, fast-regalloc cannot cope with the live vregs necessary to
- // implement atomicrmw without spilling. If the target address is also on the
- // stack and close enough to the spill slot, this can lead to a situation
- // where the monitor always gets cleared and the atomic operation can never
- // succeed. So at -O0 lower this operation to a CAS loop.
- if (getTargetMachine().getOptLevel() == CodeGenOpt::None)
- return AtomicExpansionKind::CmpXChg;
-
- return AtomicExpansionKind::LLSC;
+
+ // Nand is not supported in LSE.
+ // Leave 128 bits to LLSC or CmpXChg.
+ if (AI->getOperation() != AtomicRMWInst::Nand && Size < 128) {
+ if (Subtarget->hasLSE())
+ return AtomicExpansionKind::None;
+ if (Subtarget->outlineAtomics()) {
+ // [U]Min/[U]Max RWM atomics are used in __sync_fetch_ libcalls so far.
+ // Don't outline them unless
+ // (1) high level <atomic> support approved:
+ // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p0493r1.pdf
+ // (2) low level libgcc and compiler-rt support implemented by:
+ // min/max outline atomics helpers
+ if (AI->getOperation() != AtomicRMWInst::Min &&
+ AI->getOperation() != AtomicRMWInst::Max &&
+ AI->getOperation() != AtomicRMWInst::UMin &&
+ AI->getOperation() != AtomicRMWInst::UMax) {
+ return AtomicExpansionKind::None;
+ }
+ }
+ }
+
+ // At -O0, fast-regalloc cannot cope with the live vregs necessary to
+ // implement atomicrmw without spilling. If the target address is also on the
+ // stack and close enough to the spill slot, this can lead to a situation
+ // where the monitor always gets cleared and the atomic operation can never
+ // succeed. So at -O0 lower this operation to a CAS loop.
+ if (getTargetMachine().getOptLevel() == CodeGenOpt::None)
+ return AtomicExpansionKind::CmpXChg;
+
+ return AtomicExpansionKind::LLSC;
}
TargetLowering::AtomicExpansionKind
AArch64TargetLowering::shouldExpandAtomicCmpXchgInIR(
AtomicCmpXchgInst *AI) const {
// If subtarget has LSE, leave cmpxchg intact for codegen.
- if (Subtarget->hasLSE() || Subtarget->outlineAtomics())
+ if (Subtarget->hasLSE() || Subtarget->outlineAtomics())
return AtomicExpansionKind::None;
// At -O0, fast-regalloc cannot cope with the live vregs necessary to
// implement cmpxchg without spilling. If the address being exchanged is also
@@ -16883,92 +16883,92 @@ SDValue AArch64TargetLowering::LowerFixedLengthVectorStoreToSVE(
Store->isTruncatingStore());
}
-SDValue AArch64TargetLowering::LowerFixedLengthVectorIntDivideToSVE(
- SDValue Op, SelectionDAG &DAG) const {
- SDLoc dl(Op);
- EVT VT = Op.getValueType();
- EVT EltVT = VT.getVectorElementType();
-
- bool Signed = Op.getOpcode() == ISD::SDIV;
- unsigned PredOpcode = Signed ? AArch64ISD::SDIV_PRED : AArch64ISD::UDIV_PRED;
-
- // Scalable vector i32/i64 DIV is supported.
- if (EltVT == MVT::i32 || EltVT == MVT::i64)
- return LowerToPredicatedOp(Op, DAG, PredOpcode, /*OverrideNEON=*/true);
-
- // Scalable vector i8/i16 DIV is not supported. Promote it to i32.
- EVT ContainerVT = getContainerForFixedLengthVector(DAG, VT);
- EVT HalfVT = VT.getHalfNumVectorElementsVT(*DAG.getContext());
- EVT FixedWidenedVT = HalfVT.widenIntegerVectorElementType(*DAG.getContext());
- EVT ScalableWidenedVT = getContainerForFixedLengthVector(DAG, FixedWidenedVT);
-
- // Convert the operands to scalable vectors.
- SDValue Op0 = convertToScalableVector(DAG, ContainerVT, Op.getOperand(0));
- SDValue Op1 = convertToScalableVector(DAG, ContainerVT, Op.getOperand(1));
-
- // Extend the scalable operands.
- unsigned UnpkLo = Signed ? AArch64ISD::SUNPKLO : AArch64ISD::UUNPKLO;
- unsigned UnpkHi = Signed ? AArch64ISD::SUNPKHI : AArch64ISD::UUNPKHI;
- SDValue Op0Lo = DAG.getNode(UnpkLo, dl, ScalableWidenedVT, Op0);
- SDValue Op1Lo = DAG.getNode(UnpkLo, dl, ScalableWidenedVT, Op1);
- SDValue Op0Hi = DAG.getNode(UnpkHi, dl, ScalableWidenedVT, Op0);
- SDValue Op1Hi = DAG.getNode(UnpkHi, dl, ScalableWidenedVT, Op1);
-
- // Convert back to fixed vectors so the DIV can be further lowered.
- Op0Lo = convertFromScalableVector(DAG, FixedWidenedVT, Op0Lo);
- Op1Lo = convertFromScalableVector(DAG, FixedWidenedVT, Op1Lo);
- Op0Hi = convertFromScalableVector(DAG, FixedWidenedVT, Op0Hi);
- Op1Hi = convertFromScalableVector(DAG, FixedWidenedVT, Op1Hi);
- SDValue ResultLo = DAG.getNode(Op.getOpcode(), dl, FixedWidenedVT,
- Op0Lo, Op1Lo);
- SDValue ResultHi = DAG.getNode(Op.getOpcode(), dl, FixedWidenedVT,
- Op0Hi, Op1Hi);
-
- // Convert again to scalable vectors to truncate.
- ResultLo = convertToScalableVector(DAG, ScalableWidenedVT, ResultLo);
- ResultHi = convertToScalableVector(DAG, ScalableWidenedVT, ResultHi);
- SDValue ScalableResult = DAG.getNode(AArch64ISD::UZP1, dl, ContainerVT,
- ResultLo, ResultHi);
-
- return convertFromScalableVector(DAG, VT, ScalableResult);
-}
-
-SDValue AArch64TargetLowering::LowerFixedLengthVectorIntExtendToSVE(
- SDValue Op, SelectionDAG &DAG) const {
- EVT VT = Op.getValueType();
- assert(VT.isFixedLengthVector() && "Expected fixed length vector type!");
-
- SDLoc DL(Op);
- SDValue Val = Op.getOperand(0);
- EVT ContainerVT = getContainerForFixedLengthVector(DAG, Val.getValueType());
- Val = convertToScalableVector(DAG, ContainerVT, Val);
-
- bool Signed = Op.getOpcode() == ISD::SIGN_EXTEND;
- unsigned ExtendOpc = Signed ? AArch64ISD::SUNPKLO : AArch64ISD::UUNPKLO;
-
- // Repeatedly unpack Val until the result is of the desired element type.
- switch (ContainerVT.getSimpleVT().SimpleTy) {
- default:
- llvm_unreachable("unimplemented container type");
- case MVT::nxv16i8:
- Val = DAG.getNode(ExtendOpc, DL, MVT::nxv8i16, Val);
- if (VT.getVectorElementType() == MVT::i16)
- break;
- LLVM_FALLTHROUGH;
- case MVT::nxv8i16:
- Val = DAG.getNode(ExtendOpc, DL, MVT::nxv4i32, Val);
- if (VT.getVectorElementType() == MVT::i32)
- break;
- LLVM_FALLTHROUGH;
- case MVT::nxv4i32:
- Val = DAG.getNode(ExtendOpc, DL, MVT::nxv2i64, Val);
- assert(VT.getVectorElementType() == MVT::i64 && "Unexpected element type!");
- break;
- }
-
- return convertFromScalableVector(DAG, VT, Val);
-}
-
+SDValue AArch64TargetLowering::LowerFixedLengthVectorIntDivideToSVE(
+ SDValue Op, SelectionDAG &DAG) const {
+ SDLoc dl(Op);
+ EVT VT = Op.getValueType();
+ EVT EltVT = VT.getVectorElementType();
+
+ bool Signed = Op.getOpcode() == ISD::SDIV;
+ unsigned PredOpcode = Signed ? AArch64ISD::SDIV_PRED : AArch64ISD::UDIV_PRED;
+
+ // Scalable vector i32/i64 DIV is supported.
+ if (EltVT == MVT::i32 || EltVT == MVT::i64)
+ return LowerToPredicatedOp(Op, DAG, PredOpcode, /*OverrideNEON=*/true);
+
+ // Scalable vector i8/i16 DIV is not supported. Promote it to i32.
+ EVT ContainerVT = getContainerForFixedLengthVector(DAG, VT);
+ EVT HalfVT = VT.getHalfNumVectorElementsVT(*DAG.getContext());
+ EVT FixedWidenedVT = HalfVT.widenIntegerVectorElementType(*DAG.getContext());
+ EVT ScalableWidenedVT = getContainerForFixedLengthVector(DAG, FixedWidenedVT);
+
+ // Convert the operands to scalable vectors.
+ SDValue Op0 = convertToScalableVector(DAG, ContainerVT, Op.getOperand(0));
+ SDValue Op1 = convertToScalableVector(DAG, ContainerVT, Op.getOperand(1));
+
+ // Extend the scalable operands.
+ unsigned UnpkLo = Signed ? AArch64ISD::SUNPKLO : AArch64ISD::UUNPKLO;
+ unsigned UnpkHi = Signed ? AArch64ISD::SUNPKHI : AArch64ISD::UUNPKHI;
+ SDValue Op0Lo = DAG.getNode(UnpkLo, dl, ScalableWidenedVT, Op0);
+ SDValue Op1Lo = DAG.getNode(UnpkLo, dl, ScalableWidenedVT, Op1);
+ SDValue Op0Hi = DAG.getNode(UnpkHi, dl, ScalableWidenedVT, Op0);
+ SDValue Op1Hi = DAG.getNode(UnpkHi, dl, ScalableWidenedVT, Op1);
+
+ // Convert back to fixed vectors so the DIV can be further lowered.
+ Op0Lo = convertFromScalableVector(DAG, FixedWidenedVT, Op0Lo);
+ Op1Lo = convertFromScalableVector(DAG, FixedWidenedVT, Op1Lo);
+ Op0Hi = convertFromScalableVector(DAG, FixedWidenedVT, Op0Hi);
+ Op1Hi = convertFromScalableVector(DAG, FixedWidenedVT, Op1Hi);
+ SDValue ResultLo = DAG.getNode(Op.getOpcode(), dl, FixedWidenedVT,
+ Op0Lo, Op1Lo);
+ SDValue ResultHi = DAG.getNode(Op.getOpcode(), dl, FixedWidenedVT,
+ Op0Hi, Op1Hi);
+
+ // Convert again to scalable vectors to truncate.
+ ResultLo = convertToScalableVector(DAG, ScalableWidenedVT, ResultLo);
+ ResultHi = convertToScalableVector(DAG, ScalableWidenedVT, ResultHi);
+ SDValue ScalableResult = DAG.getNode(AArch64ISD::UZP1, dl, ContainerVT,
+ ResultLo, ResultHi);
+
+ return convertFromScalableVector(DAG, VT, ScalableResult);
+}
+
+SDValue AArch64TargetLowering::LowerFixedLengthVectorIntExtendToSVE(
+ SDValue Op, SelectionDAG &DAG) const {
+ EVT VT = Op.getValueType();
+ assert(VT.isFixedLengthVector() && "Expected fixed length vector type!");
+
+ SDLoc DL(Op);
+ SDValue Val = Op.getOperand(0);
+ EVT ContainerVT = getContainerForFixedLengthVector(DAG, Val.getValueType());
+ Val = convertToScalableVector(DAG, ContainerVT, Val);
+
+ bool Signed = Op.getOpcode() == ISD::SIGN_EXTEND;
+ unsigned ExtendOpc = Signed ? AArch64ISD::SUNPKLO : AArch64ISD::UUNPKLO;
+
+ // Repeatedly unpack Val until the result is of the desired element type.
+ switch (ContainerVT.getSimpleVT().SimpleTy) {
+ default:
+ llvm_unreachable("unimplemented container type");
+ case MVT::nxv16i8:
+ Val = DAG.getNode(ExtendOpc, DL, MVT::nxv8i16, Val);
+ if (VT.getVectorElementType() == MVT::i16)
+ break;
+ LLVM_FALLTHROUGH;
+ case MVT::nxv8i16:
+ Val = DAG.getNode(ExtendOpc, DL, MVT::nxv4i32, Val);
+ if (VT.getVectorElementType() == MVT::i32)
+ break;
+ LLVM_FALLTHROUGH;
+ case MVT::nxv4i32:
+ Val = DAG.getNode(ExtendOpc, DL, MVT::nxv2i64, Val);
+ assert(VT.getVectorElementType() == MVT::i64 && "Unexpected element type!");
+ break;
+ }
+
+ return convertFromScalableVector(DAG, VT, Val);
+}
+
SDValue AArch64TargetLowering::LowerFixedLengthVectorTruncateToSVE(
SDValue Op, SelectionDAG &DAG) const {
EVT VT = Op.getValueType();
@@ -17005,21 +17005,21 @@ SDValue AArch64TargetLowering::LowerFixedLengthVectorTruncateToSVE(
return convertFromScalableVector(DAG, VT, Val);
}
-// Convert vector operation 'Op' to an equivalent predicated operation whereby
-// the original operation's type is used to construct a suitable predicate.
-// NOTE: The results for inactive lanes are undefined.
+// Convert vector operation 'Op' to an equivalent predicated operation whereby
+// the original operation's type is used to construct a suitable predicate.
+// NOTE: The results for inactive lanes are undefined.
SDValue AArch64TargetLowering::LowerToPredicatedOp(SDValue Op,
SelectionDAG &DAG,
- unsigned NewOp,
- bool OverrideNEON) const {
+ unsigned NewOp,
+ bool OverrideNEON) const {
EVT VT = Op.getValueType();
SDLoc DL(Op);
auto Pg = getPredicateForVector(DAG, DL, VT);
- if (useSVEForFixedLengthVectorVT(VT, OverrideNEON)) {
+ if (useSVEForFixedLengthVectorVT(VT, OverrideNEON)) {
EVT ContainerVT = getContainerForFixedLengthVector(DAG, VT);
- // Create list of operands by converting existing ones to scalable types.
+ // Create list of operands by converting existing ones to scalable types.
SmallVector<SDValue, 4> Operands = {Pg};
for (const SDValue &V : Op->op_values()) {
if (isa<CondCodeSDNode>(V)) {
@@ -17027,21 +17027,21 @@ SDValue AArch64TargetLowering::LowerToPredicatedOp(SDValue Op,
continue;
}
- if (const VTSDNode *VTNode = dyn_cast<VTSDNode>(V)) {
- EVT VTArg = VTNode->getVT().getVectorElementType();
- EVT NewVTArg = ContainerVT.changeVectorElementType(VTArg);
- Operands.push_back(DAG.getValueType(NewVTArg));
- continue;
- }
-
- assert(useSVEForFixedLengthVectorVT(V.getValueType(), OverrideNEON) &&
+ if (const VTSDNode *VTNode = dyn_cast<VTSDNode>(V)) {
+ EVT VTArg = VTNode->getVT().getVectorElementType();
+ EVT NewVTArg = ContainerVT.changeVectorElementType(VTArg);
+ Operands.push_back(DAG.getValueType(NewVTArg));
+ continue;
+ }
+
+ assert(useSVEForFixedLengthVectorVT(V.getValueType(), OverrideNEON) &&
"Only fixed length vectors are supported!");
Operands.push_back(convertToScalableVector(DAG, ContainerVT, V));
}
- if (isMergePassthruOpcode(NewOp))
- Operands.push_back(DAG.getUNDEF(ContainerVT));
-
+ if (isMergePassthruOpcode(NewOp))
+ Operands.push_back(DAG.getUNDEF(ContainerVT));
+
auto ScalableRes = DAG.getNode(NewOp, DL, ContainerVT, Operands);
return convertFromScalableVector(DAG, VT, ScalableRes);
}
@@ -17050,228 +17050,228 @@ SDValue AArch64TargetLowering::LowerToPredicatedOp(SDValue Op,
SmallVector<SDValue, 4> Operands = {Pg};
for (const SDValue &V : Op->op_values()) {
- assert((!V.getValueType().isVector() ||
- V.getValueType().isScalableVector()) &&
+ assert((!V.getValueType().isVector() ||
+ V.getValueType().isScalableVector()) &&
"Only scalable vectors are supported!");
Operands.push_back(V);
}
- if (isMergePassthruOpcode(NewOp))
- Operands.push_back(DAG.getUNDEF(VT));
-
+ if (isMergePassthruOpcode(NewOp))
+ Operands.push_back(DAG.getUNDEF(VT));
+
return DAG.getNode(NewOp, DL, VT, Operands);
}
-
-// If a fixed length vector operation has no side effects when applied to
-// undefined elements, we can safely use scalable vectors to perform the same
-// operation without needing to worry about predication.
-SDValue AArch64TargetLowering::LowerToScalableOp(SDValue Op,
- SelectionDAG &DAG) const {
- EVT VT = Op.getValueType();
- assert(useSVEForFixedLengthVectorVT(VT) &&
- "Only expected to lower fixed length vector operation!");
- EVT ContainerVT = getContainerForFixedLengthVector(DAG, VT);
-
- // Create list of operands by converting existing ones to scalable types.
- SmallVector<SDValue, 4> Ops;
- for (const SDValue &V : Op->op_values()) {
- assert(!isa<VTSDNode>(V) && "Unexpected VTSDNode node!");
-
- // Pass through non-vector operands.
- if (!V.getValueType().isVector()) {
- Ops.push_back(V);
- continue;
- }
-
- // "cast" fixed length vector to a scalable vector.
- assert(useSVEForFixedLengthVectorVT(V.getValueType()) &&
- "Only fixed length vectors are supported!");
- Ops.push_back(convertToScalableVector(DAG, ContainerVT, V));
- }
-
- auto ScalableRes = DAG.getNode(Op.getOpcode(), SDLoc(Op), ContainerVT, Ops);
- return convertFromScalableVector(DAG, VT, ScalableRes);
-}
-
-SDValue AArch64TargetLowering::LowerVECREDUCE_SEQ_FADD(SDValue ScalarOp,
- SelectionDAG &DAG) const {
- SDLoc DL(ScalarOp);
- SDValue AccOp = ScalarOp.getOperand(0);
- SDValue VecOp = ScalarOp.getOperand(1);
- EVT SrcVT = VecOp.getValueType();
- EVT ResVT = SrcVT.getVectorElementType();
-
- EVT ContainerVT = SrcVT;
- if (SrcVT.isFixedLengthVector()) {
- ContainerVT = getContainerForFixedLengthVector(DAG, SrcVT);
- VecOp = convertToScalableVector(DAG, ContainerVT, VecOp);
- }
-
- SDValue Pg = getPredicateForVector(DAG, DL, SrcVT);
- SDValue Zero = DAG.getConstant(0, DL, MVT::i64);
-
- // Convert operands to Scalable.
- AccOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, ContainerVT,
- DAG.getUNDEF(ContainerVT), AccOp, Zero);
-
- // Perform reduction.
- SDValue Rdx = DAG.getNode(AArch64ISD::FADDA_PRED, DL, ContainerVT,
- Pg, AccOp, VecOp);
-
- return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ResVT, Rdx, Zero);
-}
-
-SDValue AArch64TargetLowering::LowerPredReductionToSVE(SDValue ReduceOp,
- SelectionDAG &DAG) const {
- SDLoc DL(ReduceOp);
- SDValue Op = ReduceOp.getOperand(0);
- EVT OpVT = Op.getValueType();
- EVT VT = ReduceOp.getValueType();
-
- if (!OpVT.isScalableVector() || OpVT.getVectorElementType() != MVT::i1)
- return SDValue();
-
- SDValue Pg = getPredicateForVector(DAG, DL, OpVT);
-
- switch (ReduceOp.getOpcode()) {
- default:
- return SDValue();
- case ISD::VECREDUCE_OR:
- return getPTest(DAG, VT, Pg, Op, AArch64CC::ANY_ACTIVE);
- case ISD::VECREDUCE_AND: {
- Op = DAG.getNode(ISD::XOR, DL, OpVT, Op, Pg);
- return getPTest(DAG, VT, Pg, Op, AArch64CC::NONE_ACTIVE);
- }
- case ISD::VECREDUCE_XOR: {
- SDValue ID =
- DAG.getTargetConstant(Intrinsic::aarch64_sve_cntp, DL, MVT::i64);
- SDValue Cntp =
- DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::i64, ID, Pg, Op);
- return DAG.getAnyExtOrTrunc(Cntp, DL, VT);
- }
- }
-
- return SDValue();
-}
-
-SDValue AArch64TargetLowering::LowerReductionToSVE(unsigned Opcode,
- SDValue ScalarOp,
- SelectionDAG &DAG) const {
- SDLoc DL(ScalarOp);
- SDValue VecOp = ScalarOp.getOperand(0);
- EVT SrcVT = VecOp.getValueType();
-
- if (useSVEForFixedLengthVectorVT(SrcVT, true)) {
- EVT ContainerVT = getContainerForFixedLengthVector(DAG, SrcVT);
- VecOp = convertToScalableVector(DAG, ContainerVT, VecOp);
- }
-
- // UADDV always returns an i64 result.
- EVT ResVT = (Opcode == AArch64ISD::UADDV_PRED) ? MVT::i64 :
- SrcVT.getVectorElementType();
- EVT RdxVT = SrcVT;
- if (SrcVT.isFixedLengthVector() || Opcode == AArch64ISD::UADDV_PRED)
- RdxVT = getPackedSVEVectorVT(ResVT);
-
- SDValue Pg = getPredicateForVector(DAG, DL, SrcVT);
- SDValue Rdx = DAG.getNode(Opcode, DL, RdxVT, Pg, VecOp);
- SDValue Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ResVT,
- Rdx, DAG.getConstant(0, DL, MVT::i64));
-
- // The VEC_REDUCE nodes expect an element size result.
- if (ResVT != ScalarOp.getValueType())
- Res = DAG.getAnyExtOrTrunc(Res, DL, ScalarOp.getValueType());
-
- return Res;
-}
-
-SDValue
-AArch64TargetLowering::LowerFixedLengthVectorSelectToSVE(SDValue Op,
- SelectionDAG &DAG) const {
- EVT VT = Op.getValueType();
- SDLoc DL(Op);
-
- EVT InVT = Op.getOperand(1).getValueType();
- EVT ContainerVT = getContainerForFixedLengthVector(DAG, InVT);
- SDValue Op1 = convertToScalableVector(DAG, ContainerVT, Op->getOperand(1));
- SDValue Op2 = convertToScalableVector(DAG, ContainerVT, Op->getOperand(2));
-
- // Convert the mask to a predicated (NOTE: We don't need to worry about
- // inactive lanes since VSELECT is safe when given undefined elements).
- EVT MaskVT = Op.getOperand(0).getValueType();
- EVT MaskContainerVT = getContainerForFixedLengthVector(DAG, MaskVT);
- auto Mask = convertToScalableVector(DAG, MaskContainerVT, Op.getOperand(0));
- Mask = DAG.getNode(ISD::TRUNCATE, DL,
- MaskContainerVT.changeVectorElementType(MVT::i1), Mask);
-
- auto ScalableRes = DAG.getNode(ISD::VSELECT, DL, ContainerVT,
- Mask, Op1, Op2);
-
- return convertFromScalableVector(DAG, VT, ScalableRes);
-}
-
-SDValue AArch64TargetLowering::LowerFixedLengthVectorSetccToSVE(
- SDValue Op, SelectionDAG &DAG) const {
- SDLoc DL(Op);
- EVT InVT = Op.getOperand(0).getValueType();
- EVT ContainerVT = getContainerForFixedLengthVector(DAG, InVT);
-
- assert(useSVEForFixedLengthVectorVT(InVT) &&
- "Only expected to lower fixed length vector operation!");
- assert(Op.getValueType() == InVT.changeTypeToInteger() &&
- "Expected integer result of the same bit length as the inputs!");
-
- // Expand floating point vector comparisons.
- if (InVT.isFloatingPoint())
- return SDValue();
-
- auto Op1 = convertToScalableVector(DAG, ContainerVT, Op.getOperand(0));
- auto Op2 = convertToScalableVector(DAG, ContainerVT, Op.getOperand(1));
- auto Pg = getPredicateForFixedLengthVector(DAG, DL, InVT);
-
- EVT CmpVT = Pg.getValueType();
- auto Cmp = DAG.getNode(AArch64ISD::SETCC_MERGE_ZERO, DL, CmpVT,
- {Pg, Op1, Op2, Op.getOperand(2)});
-
- EVT PromoteVT = ContainerVT.changeTypeToInteger();
- auto Promote = DAG.getBoolExtOrTrunc(Cmp, DL, PromoteVT, InVT);
- return convertFromScalableVector(DAG, Op.getValueType(), Promote);
-}
-
-SDValue AArch64TargetLowering::getSVESafeBitCast(EVT VT, SDValue Op,
- SelectionDAG &DAG) const {
- SDLoc DL(Op);
- EVT InVT = Op.getValueType();
- const TargetLowering &TLI = DAG.getTargetLoweringInfo();
- (void)TLI;
-
- assert(VT.isScalableVector() && TLI.isTypeLegal(VT) &&
- InVT.isScalableVector() && TLI.isTypeLegal(InVT) &&
- "Only expect to cast between legal scalable vector types!");
- assert((VT.getVectorElementType() == MVT::i1) ==
- (InVT.getVectorElementType() == MVT::i1) &&
- "Cannot cast between data and predicate scalable vector types!");
-
- if (InVT == VT)
- return Op;
-
- if (VT.getVectorElementType() == MVT::i1)
- return DAG.getNode(AArch64ISD::REINTERPRET_CAST, DL, VT, Op);
-
- EVT PackedVT = getPackedSVEVectorVT(VT.getVectorElementType());
- EVT PackedInVT = getPackedSVEVectorVT(InVT.getVectorElementType());
- assert((VT == PackedVT || InVT == PackedInVT) &&
- "Cannot cast between unpacked scalable vector types!");
-
- // Pack input if required.
- if (InVT != PackedInVT)
- Op = DAG.getNode(AArch64ISD::REINTERPRET_CAST, DL, PackedInVT, Op);
-
- Op = DAG.getNode(ISD::BITCAST, DL, PackedVT, Op);
-
- // Unpack result if required.
- if (VT != PackedVT)
- Op = DAG.getNode(AArch64ISD::REINTERPRET_CAST, DL, VT, Op);
-
- return Op;
-}
+
+// If a fixed length vector operation has no side effects when applied to
+// undefined elements, we can safely use scalable vectors to perform the same
+// operation without needing to worry about predication.
+SDValue AArch64TargetLowering::LowerToScalableOp(SDValue Op,
+ SelectionDAG &DAG) const {
+ EVT VT = Op.getValueType();
+ assert(useSVEForFixedLengthVectorVT(VT) &&
+ "Only expected to lower fixed length vector operation!");
+ EVT ContainerVT = getContainerForFixedLengthVector(DAG, VT);
+
+ // Create list of operands by converting existing ones to scalable types.
+ SmallVector<SDValue, 4> Ops;
+ for (const SDValue &V : Op->op_values()) {
+ assert(!isa<VTSDNode>(V) && "Unexpected VTSDNode node!");
+
+ // Pass through non-vector operands.
+ if (!V.getValueType().isVector()) {
+ Ops.push_back(V);
+ continue;
+ }
+
+ // "cast" fixed length vector to a scalable vector.
+ assert(useSVEForFixedLengthVectorVT(V.getValueType()) &&
+ "Only fixed length vectors are supported!");
+ Ops.push_back(convertToScalableVector(DAG, ContainerVT, V));
+ }
+
+ auto ScalableRes = DAG.getNode(Op.getOpcode(), SDLoc(Op), ContainerVT, Ops);
+ return convertFromScalableVector(DAG, VT, ScalableRes);
+}
+
+SDValue AArch64TargetLowering::LowerVECREDUCE_SEQ_FADD(SDValue ScalarOp,
+ SelectionDAG &DAG) const {
+ SDLoc DL(ScalarOp);
+ SDValue AccOp = ScalarOp.getOperand(0);
+ SDValue VecOp = ScalarOp.getOperand(1);
+ EVT SrcVT = VecOp.getValueType();
+ EVT ResVT = SrcVT.getVectorElementType();
+
+ EVT ContainerVT = SrcVT;
+ if (SrcVT.isFixedLengthVector()) {
+ ContainerVT = getContainerForFixedLengthVector(DAG, SrcVT);
+ VecOp = convertToScalableVector(DAG, ContainerVT, VecOp);
+ }
+
+ SDValue Pg = getPredicateForVector(DAG, DL, SrcVT);
+ SDValue Zero = DAG.getConstant(0, DL, MVT::i64);
+
+ // Convert operands to Scalable.
+ AccOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, ContainerVT,
+ DAG.getUNDEF(ContainerVT), AccOp, Zero);
+
+ // Perform reduction.
+ SDValue Rdx = DAG.getNode(AArch64ISD::FADDA_PRED, DL, ContainerVT,
+ Pg, AccOp, VecOp);
+
+ return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ResVT, Rdx, Zero);
+}
+
+SDValue AArch64TargetLowering::LowerPredReductionToSVE(SDValue ReduceOp,
+ SelectionDAG &DAG) const {
+ SDLoc DL(ReduceOp);
+ SDValue Op = ReduceOp.getOperand(0);
+ EVT OpVT = Op.getValueType();
+ EVT VT = ReduceOp.getValueType();
+
+ if (!OpVT.isScalableVector() || OpVT.getVectorElementType() != MVT::i1)
+ return SDValue();
+
+ SDValue Pg = getPredicateForVector(DAG, DL, OpVT);
+
+ switch (ReduceOp.getOpcode()) {
+ default:
+ return SDValue();
+ case ISD::VECREDUCE_OR:
+ return getPTest(DAG, VT, Pg, Op, AArch64CC::ANY_ACTIVE);
+ case ISD::VECREDUCE_AND: {
+ Op = DAG.getNode(ISD::XOR, DL, OpVT, Op, Pg);
+ return getPTest(DAG, VT, Pg, Op, AArch64CC::NONE_ACTIVE);
+ }
+ case ISD::VECREDUCE_XOR: {
+ SDValue ID =
+ DAG.getTargetConstant(Intrinsic::aarch64_sve_cntp, DL, MVT::i64);
+ SDValue Cntp =
+ DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::i64, ID, Pg, Op);
+ return DAG.getAnyExtOrTrunc(Cntp, DL, VT);
+ }
+ }
+
+ return SDValue();
+}
+
+SDValue AArch64TargetLowering::LowerReductionToSVE(unsigned Opcode,
+ SDValue ScalarOp,
+ SelectionDAG &DAG) const {
+ SDLoc DL(ScalarOp);
+ SDValue VecOp = ScalarOp.getOperand(0);
+ EVT SrcVT = VecOp.getValueType();
+
+ if (useSVEForFixedLengthVectorVT(SrcVT, true)) {
+ EVT ContainerVT = getContainerForFixedLengthVector(DAG, SrcVT);
+ VecOp = convertToScalableVector(DAG, ContainerVT, VecOp);
+ }
+
+ // UADDV always returns an i64 result.
+ EVT ResVT = (Opcode == AArch64ISD::UADDV_PRED) ? MVT::i64 :
+ SrcVT.getVectorElementType();
+ EVT RdxVT = SrcVT;
+ if (SrcVT.isFixedLengthVector() || Opcode == AArch64ISD::UADDV_PRED)
+ RdxVT = getPackedSVEVectorVT(ResVT);
+
+ SDValue Pg = getPredicateForVector(DAG, DL, SrcVT);
+ SDValue Rdx = DAG.getNode(Opcode, DL, RdxVT, Pg, VecOp);
+ SDValue Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ResVT,
+ Rdx, DAG.getConstant(0, DL, MVT::i64));
+
+ // The VEC_REDUCE nodes expect an element size result.
+ if (ResVT != ScalarOp.getValueType())
+ Res = DAG.getAnyExtOrTrunc(Res, DL, ScalarOp.getValueType());
+
+ return Res;
+}
+
+SDValue
+AArch64TargetLowering::LowerFixedLengthVectorSelectToSVE(SDValue Op,
+ SelectionDAG &DAG) const {
+ EVT VT = Op.getValueType();
+ SDLoc DL(Op);
+
+ EVT InVT = Op.getOperand(1).getValueType();
+ EVT ContainerVT = getContainerForFixedLengthVector(DAG, InVT);
+ SDValue Op1 = convertToScalableVector(DAG, ContainerVT, Op->getOperand(1));
+ SDValue Op2 = convertToScalableVector(DAG, ContainerVT, Op->getOperand(2));
+
+ // Convert the mask to a predicated (NOTE: We don't need to worry about
+ // inactive lanes since VSELECT is safe when given undefined elements).
+ EVT MaskVT = Op.getOperand(0).getValueType();
+ EVT MaskContainerVT = getContainerForFixedLengthVector(DAG, MaskVT);
+ auto Mask = convertToScalableVector(DAG, MaskContainerVT, Op.getOperand(0));
+ Mask = DAG.getNode(ISD::TRUNCATE, DL,
+ MaskContainerVT.changeVectorElementType(MVT::i1), Mask);
+
+ auto ScalableRes = DAG.getNode(ISD::VSELECT, DL, ContainerVT,
+ Mask, Op1, Op2);
+
+ return convertFromScalableVector(DAG, VT, ScalableRes);
+}
+
+SDValue AArch64TargetLowering::LowerFixedLengthVectorSetccToSVE(
+ SDValue Op, SelectionDAG &DAG) const {
+ SDLoc DL(Op);
+ EVT InVT = Op.getOperand(0).getValueType();
+ EVT ContainerVT = getContainerForFixedLengthVector(DAG, InVT);
+
+ assert(useSVEForFixedLengthVectorVT(InVT) &&
+ "Only expected to lower fixed length vector operation!");
+ assert(Op.getValueType() == InVT.changeTypeToInteger() &&
+ "Expected integer result of the same bit length as the inputs!");
+
+ // Expand floating point vector comparisons.
+ if (InVT.isFloatingPoint())
+ return SDValue();
+
+ auto Op1 = convertToScalableVector(DAG, ContainerVT, Op.getOperand(0));
+ auto Op2 = convertToScalableVector(DAG, ContainerVT, Op.getOperand(1));
+ auto Pg = getPredicateForFixedLengthVector(DAG, DL, InVT);
+
+ EVT CmpVT = Pg.getValueType();
+ auto Cmp = DAG.getNode(AArch64ISD::SETCC_MERGE_ZERO, DL, CmpVT,
+ {Pg, Op1, Op2, Op.getOperand(2)});
+
+ EVT PromoteVT = ContainerVT.changeTypeToInteger();
+ auto Promote = DAG.getBoolExtOrTrunc(Cmp, DL, PromoteVT, InVT);
+ return convertFromScalableVector(DAG, Op.getValueType(), Promote);
+}
+
+SDValue AArch64TargetLowering::getSVESafeBitCast(EVT VT, SDValue Op,
+ SelectionDAG &DAG) const {
+ SDLoc DL(Op);
+ EVT InVT = Op.getValueType();
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ (void)TLI;
+
+ assert(VT.isScalableVector() && TLI.isTypeLegal(VT) &&
+ InVT.isScalableVector() && TLI.isTypeLegal(InVT) &&
+ "Only expect to cast between legal scalable vector types!");
+ assert((VT.getVectorElementType() == MVT::i1) ==
+ (InVT.getVectorElementType() == MVT::i1) &&
+ "Cannot cast between data and predicate scalable vector types!");
+
+ if (InVT == VT)
+ return Op;
+
+ if (VT.getVectorElementType() == MVT::i1)
+ return DAG.getNode(AArch64ISD::REINTERPRET_CAST, DL, VT, Op);
+
+ EVT PackedVT = getPackedSVEVectorVT(VT.getVectorElementType());
+ EVT PackedInVT = getPackedSVEVectorVT(InVT.getVectorElementType());
+ assert((VT == PackedVT || InVT == PackedInVT) &&
+ "Cannot cast between unpacked scalable vector types!");
+
+ // Pack input if required.
+ if (InVT != PackedInVT)
+ Op = DAG.getNode(AArch64ISD::REINTERPRET_CAST, DL, PackedInVT, Op);
+
+ Op = DAG.getNode(ISD::BITCAST, DL, PackedVT, Op);
+
+ // Unpack result if required.
+ if (VT != PackedVT)
+ Op = DAG.getNode(AArch64ISD::REINTERPRET_CAST, DL, VT, Op);
+
+ return Op;
+}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64ISelLowering.h b/contrib/libs/llvm12/lib/Target/AArch64/AArch64ISelLowering.h
index 535aa519f7..9550197159 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64ISelLowering.h
@@ -72,51 +72,51 @@ enum NodeType : unsigned {
ADC,
SBC, // adc, sbc instructions
- // Predicated instructions where inactive lanes produce undefined results.
+ // Predicated instructions where inactive lanes produce undefined results.
ADD_PRED,
FADD_PRED,
- FDIV_PRED,
- FMA_PRED,
- FMAXNM_PRED,
- FMINNM_PRED,
- FMUL_PRED,
- FSUB_PRED,
- MUL_PRED,
+ FDIV_PRED,
+ FMA_PRED,
+ FMAXNM_PRED,
+ FMINNM_PRED,
+ FMUL_PRED,
+ FSUB_PRED,
+ MUL_PRED,
SDIV_PRED,
- SHL_PRED,
- SMAX_PRED,
- SMIN_PRED,
- SRA_PRED,
- SRL_PRED,
- SUB_PRED,
+ SHL_PRED,
+ SMAX_PRED,
+ SMIN_PRED,
+ SRA_PRED,
+ SRL_PRED,
+ SUB_PRED,
UDIV_PRED,
- UMAX_PRED,
- UMIN_PRED,
-
- // Predicated instructions with the result of inactive lanes provided by the
- // last operand.
- FABS_MERGE_PASSTHRU,
- FCEIL_MERGE_PASSTHRU,
- FFLOOR_MERGE_PASSTHRU,
- FNEARBYINT_MERGE_PASSTHRU,
- FNEG_MERGE_PASSTHRU,
- FRECPX_MERGE_PASSTHRU,
- FRINT_MERGE_PASSTHRU,
- FROUND_MERGE_PASSTHRU,
- FROUNDEVEN_MERGE_PASSTHRU,
- FSQRT_MERGE_PASSTHRU,
- FTRUNC_MERGE_PASSTHRU,
- FP_ROUND_MERGE_PASSTHRU,
- FP_EXTEND_MERGE_PASSTHRU,
- UINT_TO_FP_MERGE_PASSTHRU,
- SINT_TO_FP_MERGE_PASSTHRU,
- FCVTZU_MERGE_PASSTHRU,
- FCVTZS_MERGE_PASSTHRU,
- SIGN_EXTEND_INREG_MERGE_PASSTHRU,
- ZERO_EXTEND_INREG_MERGE_PASSTHRU,
- ABS_MERGE_PASSTHRU,
- NEG_MERGE_PASSTHRU,
-
+ UMAX_PRED,
+ UMIN_PRED,
+
+ // Predicated instructions with the result of inactive lanes provided by the
+ // last operand.
+ FABS_MERGE_PASSTHRU,
+ FCEIL_MERGE_PASSTHRU,
+ FFLOOR_MERGE_PASSTHRU,
+ FNEARBYINT_MERGE_PASSTHRU,
+ FNEG_MERGE_PASSTHRU,
+ FRECPX_MERGE_PASSTHRU,
+ FRINT_MERGE_PASSTHRU,
+ FROUND_MERGE_PASSTHRU,
+ FROUNDEVEN_MERGE_PASSTHRU,
+ FSQRT_MERGE_PASSTHRU,
+ FTRUNC_MERGE_PASSTHRU,
+ FP_ROUND_MERGE_PASSTHRU,
+ FP_EXTEND_MERGE_PASSTHRU,
+ UINT_TO_FP_MERGE_PASSTHRU,
+ SINT_TO_FP_MERGE_PASSTHRU,
+ FCVTZU_MERGE_PASSTHRU,
+ FCVTZS_MERGE_PASSTHRU,
+ SIGN_EXTEND_INREG_MERGE_PASSTHRU,
+ ZERO_EXTEND_INREG_MERGE_PASSTHRU,
+ ABS_MERGE_PASSTHRU,
+ NEG_MERGE_PASSTHRU,
+
SETCC_MERGE_ZERO,
// Arithmetic instructions which write flags.
@@ -219,18 +219,18 @@ enum NodeType : unsigned {
SADDV,
UADDV,
- // Vector halving addition
- SHADD,
- UHADD,
-
+ // Vector halving addition
+ SHADD,
+ UHADD,
+
// Vector rounding halving addition
SRHADD,
URHADD,
- // Absolute difference
- UABD,
- SABD,
-
+ // Absolute difference
+ UABD,
+ SABD,
+
// Vector across-lanes min/max
// Only the lower result lane is defined.
SMINV,
@@ -238,8 +238,8 @@ enum NodeType : unsigned {
SMAXV,
UMAXV,
- SADDV_PRED,
- UADDV_PRED,
+ SADDV_PRED,
+ UADDV_PRED,
SMAXV_PRED,
UMAXV_PRED,
SMINV_PRED,
@@ -307,14 +307,14 @@ enum NodeType : unsigned {
PTEST,
PTRUE,
- BITREVERSE_MERGE_PASSTHRU,
- BSWAP_MERGE_PASSTHRU,
- CTLZ_MERGE_PASSTHRU,
- CTPOP_MERGE_PASSTHRU,
+ BITREVERSE_MERGE_PASSTHRU,
+ BSWAP_MERGE_PASSTHRU,
+ CTLZ_MERGE_PASSTHRU,
+ CTPOP_MERGE_PASSTHRU,
DUP_MERGE_PASSTHRU,
INDEX_VECTOR,
- // Cast between vectors of the same element type but differ in length.
+ // Cast between vectors of the same element type but differ in length.
REINTERPRET_CAST,
LD1_MERGE_ZERO,
@@ -424,11 +424,11 @@ enum NodeType : unsigned {
LDP,
STP,
- STNP,
-
- // Pseudo for a OBJC call that gets emitted together with a special `mov
- // x29, x29` marker instruction.
- CALL_RVMARKER
+ STNP,
+
+ // Pseudo for a OBJC call that gets emitted together with a special `mov
+ // x29, x29` marker instruction.
+ CALL_RVMARKER
};
} // end namespace AArch64ISD
@@ -438,14 +438,14 @@ namespace {
// Any instruction that defines a 32-bit result zeros out the high half of the
// register. Truncate can be lowered to EXTRACT_SUBREG. CopyFromReg may
// be copying from a truncate. But any other 32-bit operation will zero-extend
-// up to 64 bits. AssertSext/AssertZext aren't saying anything about the upper
-// 32 bits, they're probably just qualifying a CopyFromReg.
+// up to 64 bits. AssertSext/AssertZext aren't saying anything about the upper
+// 32 bits, they're probably just qualifying a CopyFromReg.
// FIXME: X86 also checks for CMOV here. Do we need something similar?
static inline bool isDef32(const SDNode &N) {
unsigned Opc = N.getOpcode();
return Opc != ISD::TRUNCATE && Opc != TargetOpcode::EXTRACT_SUBREG &&
- Opc != ISD::CopyFromReg && Opc != ISD::AssertSext &&
- Opc != ISD::AssertZext;
+ Opc != ISD::CopyFromReg && Opc != ISD::AssertSext &&
+ Opc != ISD::AssertZext;
}
} // end anonymous namespace
@@ -784,7 +784,7 @@ public:
/// illegal as the original, thus leading to an infinite legalisation loop.
/// NOTE: Once BUILD_VECTOR is legal or can be custom lowered for all legal
/// vector types this override can be removed.
- bool mergeStoresAfterLegalization(EVT VT) const override;
+ bool mergeStoresAfterLegalization(EVT VT) const override;
private:
/// Keep a pointer to the AArch64Subtarget around so that we can
@@ -815,11 +815,11 @@ private:
SDValue ThisVal) const;
SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerABS(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerABS(SDValue Op, SelectionDAG &DAG) const;
+
+ SDValue LowerMGATHER(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerMSCATTER(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerMGATHER(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerMSCATTER(SDValue Op, SelectionDAG &DAG) const;
-
SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
bool isEligibleForTailCallOptimization(
@@ -903,28 +903,28 @@ private:
SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSPLAT_VECTOR(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerDUPQLane(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerToPredicatedOp(SDValue Op, SelectionDAG &DAG, unsigned NewOp,
- bool OverrideNEON = false) const;
- SDValue LowerToScalableOp(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerToPredicatedOp(SDValue Op, SelectionDAG &DAG, unsigned NewOp,
+ bool OverrideNEON = false) const;
+ SDValue LowerToScalableOp(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerINSERT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerDIV(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerDIV(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVectorSRA_SRL_SHL(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVSETCC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerCTTZ(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerCTTZ(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVectorFP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerVectorINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerVectorINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVectorOR(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerXOR(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerXOR(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFSINCOS(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVSCALE(SDValue Op, SelectionDAG &DAG) const;
@@ -939,17 +939,17 @@ private:
SDValue LowerSVEStructLoad(unsigned Intrinsic, ArrayRef<SDValue> LoadOps,
EVT VT, SelectionDAG &DAG, const SDLoc &DL) const;
- SDValue LowerFixedLengthVectorIntDivideToSVE(SDValue Op,
- SelectionDAG &DAG) const;
- SDValue LowerFixedLengthVectorIntExtendToSVE(SDValue Op,
- SelectionDAG &DAG) const;
+ SDValue LowerFixedLengthVectorIntDivideToSVE(SDValue Op,
+ SelectionDAG &DAG) const;
+ SDValue LowerFixedLengthVectorIntExtendToSVE(SDValue Op,
+ SelectionDAG &DAG) const;
SDValue LowerFixedLengthVectorLoadToSVE(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerVECREDUCE_SEQ_FADD(SDValue ScalarOp, SelectionDAG &DAG) const;
- SDValue LowerPredReductionToSVE(SDValue ScalarOp, SelectionDAG &DAG) const;
- SDValue LowerReductionToSVE(unsigned Opcode, SDValue ScalarOp,
- SelectionDAG &DAG) const;
- SDValue LowerFixedLengthVectorSelectToSVE(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerFixedLengthVectorSetccToSVE(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerVECREDUCE_SEQ_FADD(SDValue ScalarOp, SelectionDAG &DAG) const;
+ SDValue LowerPredReductionToSVE(SDValue ScalarOp, SelectionDAG &DAG) const;
+ SDValue LowerReductionToSVE(unsigned Opcode, SDValue ScalarOp,
+ SelectionDAG &DAG) const;
+ SDValue LowerFixedLengthVectorSelectToSVE(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerFixedLengthVectorSetccToSVE(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFixedLengthVectorStoreToSVE(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFixedLengthVectorTruncateToSVE(SDValue Op,
SelectionDAG &DAG) const;
@@ -961,10 +961,10 @@ private:
bool Reciprocal) const override;
SDValue getRecipEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled,
int &ExtraSteps) const override;
- SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG,
- const DenormalMode &Mode) const override;
- SDValue getSqrtResultForDenormInput(SDValue Operand,
- SelectionDAG &DAG) const override;
+ SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG,
+ const DenormalMode &Mode) const override;
+ SDValue getSqrtResultForDenormInput(SDValue Operand,
+ SelectionDAG &DAG) const override;
unsigned combineRepeatedFPDivisors() const override;
ConstraintType getConstraintType(StringRef Constraint) const override;
@@ -996,7 +996,7 @@ private:
return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
}
- bool shouldRemoveExtendFromGSIndex(EVT VT) const override;
+ bool shouldRemoveExtendFromGSIndex(EVT VT) const override;
bool isVectorLoadExtDesirable(SDValue ExtVal) const override;
bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override;
bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
@@ -1023,21 +1023,21 @@ private:
bool shouldLocalize(const MachineInstr &MI,
const TargetTransformInfo *TTI) const override;
- // Normally SVE is only used for byte size vectors that do not fit within a
- // NEON vector. This changes when OverrideNEON is true, allowing SVE to be
- // used for 64bit and 128bit vectors as well.
- bool useSVEForFixedLengthVectorVT(EVT VT, bool OverrideNEON = false) const;
-
- // With the exception of data-predicate transitions, no instructions are
- // required to cast between legal scalable vector types. However:
- // 1. Packed and unpacked types have different bit lengths, meaning BITCAST
- // is not universally useable.
- // 2. Most unpacked integer types are not legal and thus integer extends
- // cannot be used to convert between unpacked and packed types.
- // These can make "bitcasting" a multiphase process. REINTERPRET_CAST is used
- // to transition between unpacked and packed types of the same element type,
- // with BITCAST used otherwise.
- SDValue getSVESafeBitCast(EVT VT, SDValue Op, SelectionDAG &DAG) const;
+ // Normally SVE is only used for byte size vectors that do not fit within a
+ // NEON vector. This changes when OverrideNEON is true, allowing SVE to be
+ // used for 64bit and 128bit vectors as well.
+ bool useSVEForFixedLengthVectorVT(EVT VT, bool OverrideNEON = false) const;
+
+ // With the exception of data-predicate transitions, no instructions are
+ // required to cast between legal scalable vector types. However:
+ // 1. Packed and unpacked types have different bit lengths, meaning BITCAST
+ // is not universally useable.
+ // 2. Most unpacked integer types are not legal and thus integer extends
+ // cannot be used to convert between unpacked and packed types.
+ // These can make "bitcasting" a multiphase process. REINTERPRET_CAST is used
+ // to transition between unpacked and packed types of the same element type,
+ // with BITCAST used otherwise.
+ SDValue getSVESafeBitCast(EVT VT, SDValue Op, SelectionDAG &DAG) const;
};
namespace AArch64 {
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrFormats.td b/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrFormats.td
index eb03fce945..cf08f56e5b 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrFormats.td
@@ -60,14 +60,14 @@ class AArch64Inst<Format f, string cstr> : Instruction {
bits<2> Form = F.Value;
// Defaults
- bit isWhile = 0;
- bit isPTestLike = 0;
+ bit isWhile = 0;
+ bit isPTestLike = 0;
FalseLanesEnum FalseLanes = FalseLanesNone;
DestructiveInstTypeEnum DestructiveInstType = NotDestructive;
ElementSizeEnum ElementSize = ElementSizeNone;
- let TSFlags{10} = isPTestLike;
- let TSFlags{9} = isWhile;
+ let TSFlags{10} = isPTestLike;
+ let TSFlags{9} = isWhile;
let TSFlags{8-7} = FalseLanes.Value;
let TSFlags{6-3} = DestructiveInstType.Value;
let TSFlags{2-0} = ElementSize.Value;
@@ -267,7 +267,7 @@ def adrplabel : Operand<i64> {
let EncoderMethod = "getAdrLabelOpValue";
let PrintMethod = "printAdrpLabel";
let ParserMatchClass = AdrpOperand;
- let OperandType = "OPERAND_PCREL";
+ let OperandType = "OPERAND_PCREL";
}
def AdrOperand : AsmOperandClass {
@@ -330,7 +330,7 @@ def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
}
def SImm8Operand : SImmOperand<8>;
-def simm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 128; }]> {
+def simm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 128; }]> {
let ParserMatchClass = SImm8Operand;
let DecoderMethod = "DecodeSImm<8>";
}
@@ -919,13 +919,13 @@ def imm0_1 : Operand<i64>, ImmLeaf<i64, [{
let ParserMatchClass = Imm0_1Operand;
}
-// timm0_1 - as above, but use TargetConstant (TImmLeaf)
-def timm0_1 : Operand<i64>, TImmLeaf<i64, [{
- return ((uint64_t)Imm) < 2;
-}]> {
- let ParserMatchClass = Imm0_1Operand;
-}
-
+// timm0_1 - as above, but use TargetConstant (TImmLeaf)
+def timm0_1 : Operand<i64>, TImmLeaf<i64, [{
+ return ((uint64_t)Imm) < 2;
+}]> {
+ let ParserMatchClass = Imm0_1Operand;
+}
+
// imm0_15 predicate - True if the immediate is in the range [0,15]
def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
return ((uint64_t)Imm) < 16;
@@ -1301,9 +1301,9 @@ class SimpleSystemI<bit L, dag iops, string asm, string operands,
}
// System instructions which have an Rt register.
-class RtSystemI<bit L, dag oops, dag iops, string asm, string operands,
- list<dag> pattern = []>
- : BaseSystemI<L, oops, iops, asm, operands, pattern>,
+class RtSystemI<bit L, dag oops, dag iops, string asm, string operands,
+ list<dag> pattern = []>
+ : BaseSystemI<L, oops, iops, asm, operands, pattern>,
Sched<[WriteSys]> {
bits<5> Rt;
let Inst{4-0} = Rt;
@@ -1331,16 +1331,16 @@ class TMSystemI<bits<4> CRm, string asm, list<dag> pattern>
let Inst{4-0} = Rt;
}
-// System instructions that pass a register argument
-// This class assumes the register is for input rather than output.
-class RegInputSystemI<bits<4> CRm, bits<3> Op2, string asm,
- list<dag> pattern = []>
- : RtSystemI<0, (outs), (ins GPR64:$Rt), asm, "\t$Rt", pattern> {
- let Inst{20-12} = 0b000110001;
- let Inst{11-8} = CRm;
- let Inst{7-5} = Op2;
-}
-
+// System instructions that pass a register argument
+// This class assumes the register is for input rather than output.
+class RegInputSystemI<bits<4> CRm, bits<3> Op2, string asm,
+ list<dag> pattern = []>
+ : RtSystemI<0, (outs), (ins GPR64:$Rt), asm, "\t$Rt", pattern> {
+ let Inst{20-12} = 0b000110001;
+ let Inst{11-8} = CRm;
+ let Inst{7-5} = Op2;
+}
+
// System instructions for transactional memory - no operand
class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern>
: TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> {
@@ -1381,14 +1381,14 @@ def barrier_op : Operand<i32> {
let PrintMethod = "printBarrierOption";
let ParserMatchClass = BarrierAsmOperand;
}
-def BarriernXSAsmOperand : AsmOperandClass {
- let Name = "BarriernXS";
- let ParserMethod = "tryParseBarriernXSOperand";
-}
-def barrier_nxs_op : Operand<i32> {
- let PrintMethod = "printBarriernXSOption";
- let ParserMatchClass = BarriernXSAsmOperand;
-}
+def BarriernXSAsmOperand : AsmOperandClass {
+ let Name = "BarriernXS";
+ let ParserMethod = "tryParseBarriernXSOperand";
+}
+def barrier_nxs_op : Operand<i32> {
+ let PrintMethod = "printBarriernXSOption";
+ let ParserMatchClass = BarriernXSAsmOperand;
+}
class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
list<dag> pattern = []>
: SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
@@ -1470,7 +1470,7 @@ class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
"mrs", "\t$Rt, $systemreg"> {
bits<16> systemreg;
let Inst{20-5} = systemreg;
- let DecoderNamespace = "Fallback";
+ let DecoderNamespace = "Fallback";
}
// FIXME: Some of these def NZCV, others don't. Best way to model that?
@@ -1480,7 +1480,7 @@ class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
"msr", "\t$systemreg, $Rt"> {
bits<16> systemreg;
let Inst{20-5} = systemreg;
- let DecoderNamespace = "Fallback";
+ let DecoderNamespace = "Fallback";
}
def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
@@ -1970,21 +1970,21 @@ class SignAuthTwoOperand<bits<4> opc, string asm,
let Inst{4-0} = Rd;
}
-class ClearAuth<bits<1> data, string asm>
- : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> {
- bits<5> Rd;
- let Inst{31-11} = 0b110110101100000101000;
- let Inst{10} = data;
- let Inst{9-5} = 0b11111;
- let Inst{4-0} = Rd;
-}
-
+class ClearAuth<bits<1> data, string asm>
+ : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> {
+ bits<5> Rd;
+ let Inst{31-11} = 0b110110101100000101000;
+ let Inst{10} = data;
+ let Inst{9-5} = 0b11111;
+ let Inst{4-0} = Rd;
+}
+
// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions
class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops>
: I<(outs), iops, asm, ops, "", []>,
Sched<[WriteI, ReadI, ReadI]> {
let Uses = [NZCV];
- let Defs = [NZCV];
+ let Defs = [NZCV];
bits<5> Rn;
let Inst{31} = sf;
let Inst{30-15} = 0b0111010000000000;
@@ -3972,7 +3972,7 @@ class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
(outs GPR64sp:$wback, regtype:$Rt),
(ins GPR64sp:$Rn, simm9:$offset), asm,
"$Rn = $wback,@earlyclobber $wback", []>,
- Sched<[WriteAdr, WriteLD]>;
+ Sched<[WriteAdr, WriteLD]>;
let mayStore = 1, mayLoad = 0 in
class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
@@ -4018,7 +4018,7 @@ class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
(outs GPR64sp:$wback, regtype:$Rt),
(ins GPR64sp:$Rn, simm9:$offset),
asm, "$Rn = $wback,@earlyclobber $wback", []>,
- Sched<[WriteAdr, WriteLD]>;
+ Sched<[WriteAdr, WriteLD]>;
let mayStore = 1, mayLoad = 0 in
class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
@@ -4115,7 +4115,7 @@ class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype,
: BaseLoadStorePairPreIdx<opc, V, 1,
(outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
(ins GPR64sp:$Rn, indextype:$offset), asm>,
- Sched<[WriteAdr, WriteLD, WriteLDHi]>;
+ Sched<[WriteAdr, WriteLD, WriteLDHi]>;
let mayStore = 1, mayLoad = 0 in
class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype,
@@ -4156,7 +4156,7 @@ class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype,
: BaseLoadStorePairPostIdx<opc, V, 1,
(outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
(ins GPR64sp:$Rn, idxtype:$offset), asm>,
- Sched<[WriteAdr, WriteLD, WriteLDHi]>;
+ Sched<[WriteAdr, WriteLD, WriteLDHi]>;
let mayStore = 1, mayLoad = 0 in
class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype,
@@ -7874,9 +7874,9 @@ class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1,
multiclass SIMDThreeSameVectorBFDot<bit U, string asm> {
def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64,
- v2f32, v4bf16>;
+ v2f32, v4bf16>;
def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128,
- v4f32, v8bf16>;
+ v4f32, v8bf16>;
}
class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm,
@@ -7894,7 +7894,7 @@ class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm,
(InputType RegType:$Rn),
(InputType (bitconvert (AccumType
(AArch64duplane32 (v4f32 V128:$Rm),
- VectorIndexS:$idx)))))))]> {
+ VectorIndexS:$idx)))))))]> {
bits<2> idx;
let Inst{21} = idx{0}; // L
@@ -7904,16 +7904,16 @@ class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm,
multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> {
def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h",
- ".2h", V64, v2f32, v4bf16>;
+ ".2h", V64, v2f32, v4bf16>;
def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h",
- ".2h", V128, v4f32, v8bf16>;
+ ".2h", V128, v4f32, v8bf16>;
}
class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode>
: BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s",
[(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
- (v8bf16 V128:$Rn),
- (v8bf16 V128:$Rm)))]> {
+ (v8bf16 V128:$Rn),
+ (v8bf16 V128:$Rm)))]> {
let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}");
}
@@ -7923,10 +7923,10 @@ class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode>
"{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst",
[(set (v4f32 V128:$dst),
(v4f32 (OpNode (v4f32 V128:$Rd),
- (v8bf16 V128:$Rn),
- (v8bf16
+ (v8bf16 V128:$Rn),
+ (v8bf16
(AArch64duplane16 (v8bf16 V128_lo:$Rm),
- VectorIndexH:$idx)))))]>,
+ VectorIndexH:$idx)))))]>,
Sched<[WriteV]> {
bits<5> Rd;
bits<5> Rn;
@@ -7950,8 +7950,8 @@ class SIMDThreeSameVectorBF16MatrixMul<string asm>
V128, asm, ".4s",
[(set (v4f32 V128:$dst),
(int_aarch64_neon_bfmmla (v4f32 V128:$Rd),
- (v8bf16 V128:$Rn),
- (v8bf16 V128:$Rm)))]> {
+ (v8bf16 V128:$Rn),
+ (v8bf16 V128:$Rm)))]> {
let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h",
", $Rm", ".8h", "}");
}
@@ -10629,14 +10629,14 @@ multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype,
[(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
(v4f16 V64:$Rn),
(v4f16 V64:$Rm),
- (i32 rottype:$rot)))]>;
+ (i32 rottype:$rot)))]>;
def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype,
asm, ".8h",
[(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
(v8f16 V128:$Rn),
(v8f16 V128:$Rm),
- (i32 rottype:$rot)))]>;
+ (i32 rottype:$rot)))]>;
}
let Predicates = [HasComplxNum, HasNEON] in {
@@ -10645,21 +10645,21 @@ multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype,
[(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
(v2f32 V64:$Rn),
(v2f32 V64:$Rm),
- (i32 rottype:$rot)))]>;
+ (i32 rottype:$rot)))]>;
def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype,
asm, ".4s",
[(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
(v4f32 V128:$Rn),
(v4f32 V128:$Rm),
- (i32 rottype:$rot)))]>;
+ (i32 rottype:$rot)))]>;
def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype,
asm, ".2d",
[(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
(v2f64 V128:$Rn),
(v2f64 V128:$Rm),
- (i32 rottype:$rot)))]>;
+ (i32 rottype:$rot)))]>;
}
}
@@ -10701,14 +10701,14 @@ multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode,
[(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
(v4f16 V64:$Rn),
(v4f16 V64:$Rm),
- (i32 rottype:$rot)))]>;
+ (i32 rottype:$rot)))]>;
def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128,
rottype, asm, ".8h",
[(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
(v8f16 V128:$Rn),
(v8f16 V128:$Rm),
- (i32 rottype:$rot)))]>;
+ (i32 rottype:$rot)))]>;
}
let Predicates = [HasComplxNum, HasNEON] in {
@@ -10717,21 +10717,21 @@ multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode,
[(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
(v2f32 V64:$Rn),
(v2f32 V64:$Rm),
- (i32 rottype:$rot)))]>;
+ (i32 rottype:$rot)))]>;
def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128,
rottype, asm, ".4s",
[(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
(v4f32 V128:$Rn),
(v4f32 V128:$Rm),
- (i32 rottype:$rot)))]>;
+ (i32 rottype:$rot)))]>;
def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128,
rottype, asm, ".2d",
[(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
(v2f64 V128:$Rn),
(v2f64 V128:$Rm),
- (i32 rottype:$rot)))]>;
+ (i32 rottype:$rot)))]>;
}
}
@@ -11259,35 +11259,35 @@ multiclass STOPregister<string asm, string instr> {
!cast<Instruction>(instr # "X")>;
}
-class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops,
- dag iops, dag oops, list<dag> pat>
- : I<oops, iops, asm_inst, asm_ops, "", pat>,
- Sched<[]> /* FIXME: fill in scheduling details once known */ {
- bits<5> Rt;
- bits<5> Rn;
- let Inst{31-21} = 0b11111000001;
- let Inst{15} = 1;
- let Inst{14-12} = opc;
- let Inst{11-10} = 0b00;
- let Inst{9-5} = Rn;
- let Inst{4-0} = Rt;
-
- let Predicates = [HasV8_7a];
-}
-
-class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops,
- list<dag> pat = []>
- : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> {
- let Inst{20-16} = 0b11111;
-}
-
-class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []>
- : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]",
- (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> {
- bits<5> Rs;
- let Inst{20-16} = Rs;
-}
-
+class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops,
+ dag iops, dag oops, list<dag> pat>
+ : I<oops, iops, asm_inst, asm_ops, "", pat>,
+ Sched<[]> /* FIXME: fill in scheduling details once known */ {
+ bits<5> Rt;
+ bits<5> Rn;
+ let Inst{31-21} = 0b11111000001;
+ let Inst{15} = 1;
+ let Inst{14-12} = opc;
+ let Inst{11-10} = 0b00;
+ let Inst{9-5} = Rn;
+ let Inst{4-0} = Rt;
+
+ let Predicates = [HasV8_7a];
+}
+
+class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops,
+ list<dag> pat = []>
+ : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> {
+ let Inst{20-16} = 0b11111;
+}
+
+class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []>
+ : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]",
+ (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> {
+ bits<5> Rs;
+ let Inst{20-16} = Rs;
+}
+
//----------------------------------------------------------------------------
// Allow the size specifier tokens to be upper case, not just lower.
def : TokenAlias<".4B", ".4b">; // Add dot product
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrGISel.td b/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrGISel.td
index b7d5014166..25656fac1d 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrGISel.td
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrGISel.td
@@ -88,29 +88,29 @@ def G_DUP: AArch64GenericInstruction {
let InOperandList = (ins type1:$lane);
let hasSideEffects = 0;
}
-
-// Represents a lane duplicate operation.
-def G_DUPLANE8 : AArch64GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src, type1:$lane);
- let hasSideEffects = 0;
-}
-def G_DUPLANE16 : AArch64GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src, type1:$lane);
- let hasSideEffects = 0;
-}
-def G_DUPLANE32 : AArch64GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src, type1:$lane);
- let hasSideEffects = 0;
-}
-def G_DUPLANE64 : AArch64GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src, type1:$lane);
- let hasSideEffects = 0;
-}
-
+
+// Represents a lane duplicate operation.
+def G_DUPLANE8 : AArch64GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src, type1:$lane);
+ let hasSideEffects = 0;
+}
+def G_DUPLANE16 : AArch64GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src, type1:$lane);
+ let hasSideEffects = 0;
+}
+def G_DUPLANE32 : AArch64GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src, type1:$lane);
+ let hasSideEffects = 0;
+}
+def G_DUPLANE64 : AArch64GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src, type1:$lane);
+ let hasSideEffects = 0;
+}
+
// Represents a trn1 instruction. Produced post-legalization from
// G_SHUFFLE_VECTORs with appropriate masks.
def G_TRN1 : AArch64GenericInstruction {
@@ -134,28 +134,28 @@ def G_EXT: AArch64GenericInstruction {
let InOperandList = (ins type0:$v1, type0:$v2, untyped_imm_0:$imm);
}
-// Represents a vector G_ASHR with an immediate.
-def G_VASHR : AArch64GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, untyped_imm_0:$imm);
-}
-
-// Represents a vector G_LSHR with an immediate.
-def G_VLSHR : AArch64GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, untyped_imm_0:$imm);
-}
-
-// Represents an integer to FP conversion on the FPR bank.
-def G_SITOF : AArch64GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src);
-}
-def G_UITOF : AArch64GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src);
-}
-
+// Represents a vector G_ASHR with an immediate.
+def G_VASHR : AArch64GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, untyped_imm_0:$imm);
+}
+
+// Represents a vector G_LSHR with an immediate.
+def G_VLSHR : AArch64GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, untyped_imm_0:$imm);
+}
+
+// Represents an integer to FP conversion on the FPR bank.
+def G_SITOF : AArch64GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src);
+}
+def G_UITOF : AArch64GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src);
+}
+
def : GINodeEquiv<G_REV16, AArch64rev16>;
def : GINodeEquiv<G_REV32, AArch64rev32>;
def : GINodeEquiv<G_REV64, AArch64rev64>;
@@ -164,21 +164,21 @@ def : GINodeEquiv<G_UZP2, AArch64uzp2>;
def : GINodeEquiv<G_ZIP1, AArch64zip1>;
def : GINodeEquiv<G_ZIP2, AArch64zip2>;
def : GINodeEquiv<G_DUP, AArch64dup>;
-def : GINodeEquiv<G_DUPLANE8, AArch64duplane8>;
-def : GINodeEquiv<G_DUPLANE16, AArch64duplane16>;
-def : GINodeEquiv<G_DUPLANE32, AArch64duplane32>;
-def : GINodeEquiv<G_DUPLANE64, AArch64duplane64>;
+def : GINodeEquiv<G_DUPLANE8, AArch64duplane8>;
+def : GINodeEquiv<G_DUPLANE16, AArch64duplane16>;
+def : GINodeEquiv<G_DUPLANE32, AArch64duplane32>;
+def : GINodeEquiv<G_DUPLANE64, AArch64duplane64>;
def : GINodeEquiv<G_TRN1, AArch64trn1>;
def : GINodeEquiv<G_TRN2, AArch64trn2>;
def : GINodeEquiv<G_EXT, AArch64ext>;
-def : GINodeEquiv<G_VASHR, AArch64vashr>;
-def : GINodeEquiv<G_VLSHR, AArch64vlshr>;
-def : GINodeEquiv<G_SITOF, AArch64sitof>;
-def : GINodeEquiv<G_UITOF, AArch64uitof>;
-
-def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, vector_extract>;
-
-// These are patterns that we only use for GlobalISel via the importer.
-def : Pat<(f32 (fadd (vector_extract (v2f32 FPR64:$Rn), (i64 0)),
- (vector_extract (v2f32 FPR64:$Rn), (i64 1)))),
- (f32 (FADDPv2i32p (v2f32 FPR64:$Rn)))>;
+def : GINodeEquiv<G_VASHR, AArch64vashr>;
+def : GINodeEquiv<G_VLSHR, AArch64vlshr>;
+def : GINodeEquiv<G_SITOF, AArch64sitof>;
+def : GINodeEquiv<G_UITOF, AArch64uitof>;
+
+def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, vector_extract>;
+
+// These are patterns that we only use for GlobalISel via the importer.
+def : Pat<(f32 (fadd (vector_extract (v2f32 FPR64:$Rn), (i64 0)),
+ (vector_extract (v2f32 FPR64:$Rn), (i64 1)))),
+ (f32 (FADDPv2i32p (v2f32 FPR64:$Rn)))>;
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrInfo.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrInfo.cpp
index fc3e238182..6b38e216a8 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -107,13 +107,13 @@ unsigned AArch64InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
NumBytes = PatchPointOpers(&MI).getNumPatchBytes();
assert(NumBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
break;
- case TargetOpcode::STATEPOINT:
- NumBytes = StatepointOpers(&MI).getNumPatchBytes();
- assert(NumBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
- // No patch bytes means a normal call inst is emitted
- if (NumBytes == 0)
- NumBytes = 4;
- break;
+ case TargetOpcode::STATEPOINT:
+ NumBytes = StatepointOpers(&MI).getNumPatchBytes();
+ assert(NumBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
+ // No patch bytes means a normal call inst is emitted
+ if (NumBytes == 0)
+ NumBytes = 4;
+ break;
case AArch64::TLSDESC_CALLSEQ:
// This gets lowered to an instruction sequence which takes 16 bytes
NumBytes = 16;
@@ -294,31 +294,31 @@ bool AArch64InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
}
}
- // If we're allowed to modify and the block ends in a unconditional branch
- // which could simply fallthrough, remove the branch. (Note: This case only
- // matters when we can't understand the whole sequence, otherwise it's also
- // handled by BranchFolding.cpp.)
- if (AllowModify && isUncondBranchOpcode(LastOpc) &&
- MBB.isLayoutSuccessor(getBranchDestBlock(*LastInst))) {
- LastInst->eraseFromParent();
- LastInst = SecondLastInst;
- LastOpc = LastInst->getOpcode();
- if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
- assert(!isUncondBranchOpcode(LastOpc) &&
- "unreachable unconditional branches removed above");
-
- if (isCondBranchOpcode(LastOpc)) {
- // Block ends with fall-through condbranch.
- parseCondBranch(LastInst, TBB, Cond);
- return false;
- }
- return true; // Can't handle indirect branch.
- } else {
- SecondLastInst = &*I;
- SecondLastOpc = SecondLastInst->getOpcode();
- }
- }
-
+ // If we're allowed to modify and the block ends in a unconditional branch
+ // which could simply fallthrough, remove the branch. (Note: This case only
+ // matters when we can't understand the whole sequence, otherwise it's also
+ // handled by BranchFolding.cpp.)
+ if (AllowModify && isUncondBranchOpcode(LastOpc) &&
+ MBB.isLayoutSuccessor(getBranchDestBlock(*LastInst))) {
+ LastInst->eraseFromParent();
+ LastInst = SecondLastInst;
+ LastOpc = LastInst->getOpcode();
+ if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
+ assert(!isUncondBranchOpcode(LastOpc) &&
+ "unreachable unconditional branches removed above");
+
+ if (isCondBranchOpcode(LastOpc)) {
+ // Block ends with fall-through condbranch.
+ parseCondBranch(LastInst, TBB, Cond);
+ return false;
+ }
+ return true; // Can't handle indirect branch.
+ } else {
+ SecondLastInst = &*I;
+ SecondLastOpc = SecondLastInst->getOpcode();
+ }
+ }
+
// If there are three terminators, we don't know what sort of block this is.
if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I))
return true;
@@ -353,56 +353,56 @@ bool AArch64InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
return true;
}
-bool AArch64InstrInfo::analyzeBranchPredicate(MachineBasicBlock &MBB,
- MachineBranchPredicate &MBP,
- bool AllowModify) const {
- // For the moment, handle only a block which ends with a cb(n)zx followed by
- // a fallthrough. Why this? Because it is a common form.
- // TODO: Should we handle b.cc?
-
- MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
- if (I == MBB.end())
- return true;
-
- // Skip over SpeculationBarrierEndBB terminators
- if (I->getOpcode() == AArch64::SpeculationBarrierISBDSBEndBB ||
- I->getOpcode() == AArch64::SpeculationBarrierSBEndBB) {
- --I;
- }
-
- if (!isUnpredicatedTerminator(*I))
- return true;
-
- // Get the last instruction in the block.
- MachineInstr *LastInst = &*I;
- unsigned LastOpc = LastInst->getOpcode();
- if (!isCondBranchOpcode(LastOpc))
- return true;
-
- switch (LastOpc) {
- default:
- return true;
- case AArch64::CBZW:
- case AArch64::CBZX:
- case AArch64::CBNZW:
- case AArch64::CBNZX:
- break;
- };
-
- MBP.TrueDest = LastInst->getOperand(1).getMBB();
- assert(MBP.TrueDest && "expected!");
- MBP.FalseDest = MBB.getNextNode();
-
- MBP.ConditionDef = nullptr;
- MBP.SingleUseCondition = false;
-
- MBP.LHS = LastInst->getOperand(0);
- MBP.RHS = MachineOperand::CreateImm(0);
- MBP.Predicate = LastOpc == AArch64::CBNZX ? MachineBranchPredicate::PRED_NE
- : MachineBranchPredicate::PRED_EQ;
- return false;
-}
-
+bool AArch64InstrInfo::analyzeBranchPredicate(MachineBasicBlock &MBB,
+ MachineBranchPredicate &MBP,
+ bool AllowModify) const {
+ // For the moment, handle only a block which ends with a cb(n)zx followed by
+ // a fallthrough. Why this? Because it is a common form.
+ // TODO: Should we handle b.cc?
+
+ MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
+ if (I == MBB.end())
+ return true;
+
+ // Skip over SpeculationBarrierEndBB terminators
+ if (I->getOpcode() == AArch64::SpeculationBarrierISBDSBEndBB ||
+ I->getOpcode() == AArch64::SpeculationBarrierSBEndBB) {
+ --I;
+ }
+
+ if (!isUnpredicatedTerminator(*I))
+ return true;
+
+ // Get the last instruction in the block.
+ MachineInstr *LastInst = &*I;
+ unsigned LastOpc = LastInst->getOpcode();
+ if (!isCondBranchOpcode(LastOpc))
+ return true;
+
+ switch (LastOpc) {
+ default:
+ return true;
+ case AArch64::CBZW:
+ case AArch64::CBZX:
+ case AArch64::CBNZW:
+ case AArch64::CBNZX:
+ break;
+ };
+
+ MBP.TrueDest = LastInst->getOperand(1).getMBB();
+ assert(MBP.TrueDest && "expected!");
+ MBP.FalseDest = MBB.getNextNode();
+
+ MBP.ConditionDef = nullptr;
+ MBP.SingleUseCondition = false;
+
+ MBP.LHS = LastInst->getOperand(0);
+ MBP.RHS = MachineOperand::CreateImm(0);
+ MBP.Predicate = LastOpc == AArch64::CBNZX ? MachineBranchPredicate::PRED_NE
+ : MachineBranchPredicate::PRED_EQ;
+ return false;
+}
+
bool AArch64InstrInfo::reverseBranchCondition(
SmallVectorImpl<MachineOperand> &Cond) const {
if (Cond[0].getImm() != -1) {
@@ -1119,13 +1119,13 @@ bool AArch64InstrInfo::analyzeCompare(const MachineInstr &MI, Register &SrcReg,
switch (MI.getOpcode()) {
default:
break;
- case AArch64::PTEST_PP:
- SrcReg = MI.getOperand(0).getReg();
- SrcReg2 = MI.getOperand(1).getReg();
- // Not sure about the mask and value for now...
- CmpMask = ~0;
- CmpValue = 0;
- return true;
+ case AArch64::PTEST_PP:
+ SrcReg = MI.getOperand(0).getReg();
+ SrcReg2 = MI.getOperand(1).getReg();
+ // Not sure about the mask and value for now...
+ CmpMask = ~0;
+ CmpValue = 0;
+ return true;
case AArch64::SUBSWrr:
case AArch64::SUBSWrs:
case AArch64::SUBSWrx:
@@ -1281,9 +1281,9 @@ static bool areCFlagsAccessedBetweenInstrs(
return true;
// From must be above To.
- assert(std::any_of(
- ++To.getReverse(), To->getParent()->rend(),
- [From](MachineInstr &MI) { return MI.getIterator() == From; }));
+ assert(std::any_of(
+ ++To.getReverse(), To->getParent()->rend(),
+ [From](MachineInstr &MI) { return MI.getIterator() == From; }));
// We iterate backward starting at \p To until we hit \p From.
for (const MachineInstr &Instr :
@@ -1296,127 +1296,127 @@ static bool areCFlagsAccessedBetweenInstrs(
return false;
}
-/// optimizePTestInstr - Attempt to remove a ptest of a predicate-generating
-/// operation which could set the flags in an identical manner
-bool AArch64InstrInfo::optimizePTestInstr(
- MachineInstr *PTest, unsigned MaskReg, unsigned PredReg,
- const MachineRegisterInfo *MRI) const {
- auto *Mask = MRI->getUniqueVRegDef(MaskReg);
- auto *Pred = MRI->getUniqueVRegDef(PredReg);
- auto NewOp = Pred->getOpcode();
- bool OpChanged = false;
-
- unsigned MaskOpcode = Mask->getOpcode();
- unsigned PredOpcode = Pred->getOpcode();
- bool PredIsPTestLike = isPTestLikeOpcode(PredOpcode);
- bool PredIsWhileLike = isWhileOpcode(PredOpcode);
-
- if (isPTrueOpcode(MaskOpcode) && (PredIsPTestLike || PredIsWhileLike)) {
- // For PTEST(PTRUE, OTHER_INST), PTEST is redundant when PTRUE doesn't
- // deactivate any lanes OTHER_INST might set.
- uint64_t MaskElementSize = getElementSizeForOpcode(MaskOpcode);
- uint64_t PredElementSize = getElementSizeForOpcode(PredOpcode);
-
- // Must be an all active predicate of matching element size.
- if ((PredElementSize != MaskElementSize) ||
- (Mask->getOperand(1).getImm() != 31))
- return false;
-
- // Fallthough to simply remove the PTEST.
- } else if ((Mask == Pred) && (PredIsPTestLike || PredIsWhileLike)) {
- // For PTEST(PG, PG), PTEST is redundant when PG is the result of an
- // instruction that sets the flags as PTEST would.
-
- // Fallthough to simply remove the PTEST.
- } else if (PredIsPTestLike) {
- // For PTEST(PG_1, PTEST_LIKE(PG2, ...)), PTEST is redundant when both
- // instructions use the same predicate.
- auto PTestLikeMask = MRI->getUniqueVRegDef(Pred->getOperand(1).getReg());
- if (Mask != PTestLikeMask)
- return false;
-
- // Fallthough to simply remove the PTEST.
- } else {
- switch (Pred->getOpcode()) {
- case AArch64::BRKB_PPzP:
- case AArch64::BRKPB_PPzPP: {
- // Op 0 is chain, 1 is the mask, 2 the previous predicate to
- // propagate, 3 the new predicate.
-
- // Check to see if our mask is the same as the brkpb's. If
- // not the resulting flag bits may be different and we
- // can't remove the ptest.
- auto *PredMask = MRI->getUniqueVRegDef(Pred->getOperand(1).getReg());
- if (Mask != PredMask)
- return false;
-
- // Switch to the new opcode
- NewOp = Pred->getOpcode() == AArch64::BRKB_PPzP ? AArch64::BRKBS_PPzP
- : AArch64::BRKPBS_PPzPP;
- OpChanged = true;
- break;
- }
- case AArch64::BRKN_PPzP: {
- auto *PredMask = MRI->getUniqueVRegDef(Pred->getOperand(1).getReg());
- if (Mask != PredMask)
- return false;
-
- NewOp = AArch64::BRKNS_PPzP;
- OpChanged = true;
- break;
- }
- default:
- // Bail out if we don't recognize the input
- return false;
- }
- }
-
- const TargetRegisterInfo *TRI = &getRegisterInfo();
-
- // If the predicate is in a different block (possibly because its been
- // hoisted out), then assume the flags are set in between statements.
- if (Pred->getParent() != PTest->getParent())
- return false;
-
- // If another instruction between the propagation and test sets the
- // flags, don't remove the ptest.
- MachineBasicBlock::iterator I = Pred, E = PTest;
- ++I; // Skip past the predicate op itself.
- for (; I != E; ++I) {
- const MachineInstr &Inst = *I;
-
- // TODO: If the ptest flags are unused, we could still remove it.
- if (Inst.modifiesRegister(AArch64::NZCV, TRI))
- return false;
- }
-
- // If we pass all the checks, it's safe to remove the PTEST and use the flags
- // as they are prior to PTEST. Sometimes this requires the tested PTEST
- // operand to be replaced with an equivalent instruction that also sets the
- // flags.
- Pred->setDesc(get(NewOp));
- PTest->eraseFromParent();
- if (OpChanged) {
- bool succeeded = UpdateOperandRegClass(*Pred);
- (void)succeeded;
- assert(succeeded && "Operands have incompatible register classes!");
- Pred->addRegisterDefined(AArch64::NZCV, TRI);
- }
-
- // Ensure that the flags def is live.
- if (Pred->registerDefIsDead(AArch64::NZCV, TRI)) {
- unsigned i = 0, e = Pred->getNumOperands();
- for (; i != e; ++i) {
- MachineOperand &MO = Pred->getOperand(i);
- if (MO.isReg() && MO.isDef() && MO.getReg() == AArch64::NZCV) {
- MO.setIsDead(false);
- break;
- }
- }
- }
- return true;
-}
-
+/// optimizePTestInstr - Attempt to remove a ptest of a predicate-generating
+/// operation which could set the flags in an identical manner
+bool AArch64InstrInfo::optimizePTestInstr(
+ MachineInstr *PTest, unsigned MaskReg, unsigned PredReg,
+ const MachineRegisterInfo *MRI) const {
+ auto *Mask = MRI->getUniqueVRegDef(MaskReg);
+ auto *Pred = MRI->getUniqueVRegDef(PredReg);
+ auto NewOp = Pred->getOpcode();
+ bool OpChanged = false;
+
+ unsigned MaskOpcode = Mask->getOpcode();
+ unsigned PredOpcode = Pred->getOpcode();
+ bool PredIsPTestLike = isPTestLikeOpcode(PredOpcode);
+ bool PredIsWhileLike = isWhileOpcode(PredOpcode);
+
+ if (isPTrueOpcode(MaskOpcode) && (PredIsPTestLike || PredIsWhileLike)) {
+ // For PTEST(PTRUE, OTHER_INST), PTEST is redundant when PTRUE doesn't
+ // deactivate any lanes OTHER_INST might set.
+ uint64_t MaskElementSize = getElementSizeForOpcode(MaskOpcode);
+ uint64_t PredElementSize = getElementSizeForOpcode(PredOpcode);
+
+ // Must be an all active predicate of matching element size.
+ if ((PredElementSize != MaskElementSize) ||
+ (Mask->getOperand(1).getImm() != 31))
+ return false;
+
+ // Fallthough to simply remove the PTEST.
+ } else if ((Mask == Pred) && (PredIsPTestLike || PredIsWhileLike)) {
+ // For PTEST(PG, PG), PTEST is redundant when PG is the result of an
+ // instruction that sets the flags as PTEST would.
+
+ // Fallthough to simply remove the PTEST.
+ } else if (PredIsPTestLike) {
+ // For PTEST(PG_1, PTEST_LIKE(PG2, ...)), PTEST is redundant when both
+ // instructions use the same predicate.
+ auto PTestLikeMask = MRI->getUniqueVRegDef(Pred->getOperand(1).getReg());
+ if (Mask != PTestLikeMask)
+ return false;
+
+ // Fallthough to simply remove the PTEST.
+ } else {
+ switch (Pred->getOpcode()) {
+ case AArch64::BRKB_PPzP:
+ case AArch64::BRKPB_PPzPP: {
+ // Op 0 is chain, 1 is the mask, 2 the previous predicate to
+ // propagate, 3 the new predicate.
+
+ // Check to see if our mask is the same as the brkpb's. If
+ // not the resulting flag bits may be different and we
+ // can't remove the ptest.
+ auto *PredMask = MRI->getUniqueVRegDef(Pred->getOperand(1).getReg());
+ if (Mask != PredMask)
+ return false;
+
+ // Switch to the new opcode
+ NewOp = Pred->getOpcode() == AArch64::BRKB_PPzP ? AArch64::BRKBS_PPzP
+ : AArch64::BRKPBS_PPzPP;
+ OpChanged = true;
+ break;
+ }
+ case AArch64::BRKN_PPzP: {
+ auto *PredMask = MRI->getUniqueVRegDef(Pred->getOperand(1).getReg());
+ if (Mask != PredMask)
+ return false;
+
+ NewOp = AArch64::BRKNS_PPzP;
+ OpChanged = true;
+ break;
+ }
+ default:
+ // Bail out if we don't recognize the input
+ return false;
+ }
+ }
+
+ const TargetRegisterInfo *TRI = &getRegisterInfo();
+
+ // If the predicate is in a different block (possibly because its been
+ // hoisted out), then assume the flags are set in between statements.
+ if (Pred->getParent() != PTest->getParent())
+ return false;
+
+ // If another instruction between the propagation and test sets the
+ // flags, don't remove the ptest.
+ MachineBasicBlock::iterator I = Pred, E = PTest;
+ ++I; // Skip past the predicate op itself.
+ for (; I != E; ++I) {
+ const MachineInstr &Inst = *I;
+
+ // TODO: If the ptest flags are unused, we could still remove it.
+ if (Inst.modifiesRegister(AArch64::NZCV, TRI))
+ return false;
+ }
+
+ // If we pass all the checks, it's safe to remove the PTEST and use the flags
+ // as they are prior to PTEST. Sometimes this requires the tested PTEST
+ // operand to be replaced with an equivalent instruction that also sets the
+ // flags.
+ Pred->setDesc(get(NewOp));
+ PTest->eraseFromParent();
+ if (OpChanged) {
+ bool succeeded = UpdateOperandRegClass(*Pred);
+ (void)succeeded;
+ assert(succeeded && "Operands have incompatible register classes!");
+ Pred->addRegisterDefined(AArch64::NZCV, TRI);
+ }
+
+ // Ensure that the flags def is live.
+ if (Pred->registerDefIsDead(AArch64::NZCV, TRI)) {
+ unsigned i = 0, e = Pred->getNumOperands();
+ for (; i != e; ++i) {
+ MachineOperand &MO = Pred->getOperand(i);
+ if (MO.isReg() && MO.isDef() && MO.getReg() == AArch64::NZCV) {
+ MO.setIsDead(false);
+ break;
+ }
+ }
+ }
+ return true;
+}
+
/// Try to optimize a compare instruction. A compare instruction is an
/// instruction which produces AArch64::NZCV. It can be truly compare
/// instruction
@@ -1455,9 +1455,9 @@ bool AArch64InstrInfo::optimizeCompareInstr(
return true;
}
- if (CmpInstr.getOpcode() == AArch64::PTEST_PP)
- return optimizePTestInstr(&CmpInstr, SrcReg, SrcReg2, MRI);
-
+ if (CmpInstr.getOpcode() == AArch64::PTEST_PP)
+ return optimizePTestInstr(&CmpInstr, SrcReg, SrcReg2, MRI);
+
// Continue only if we have a "ri" where immediate is zero.
// FIXME:CmpValue has already been converted to 0 or 1 in analyzeCompare
// function.
@@ -2274,24 +2274,24 @@ bool AArch64InstrInfo::getMemOperandsWithOffsetWidth(
return true;
}
-Optional<ExtAddrMode>
-AArch64InstrInfo::getAddrModeFromMemoryOp(const MachineInstr &MemI,
- const TargetRegisterInfo *TRI) const {
- const MachineOperand *Base; // Filled with the base operand of MI.
- int64_t Offset; // Filled with the offset of MI.
- bool OffsetIsScalable;
- if (!getMemOperandWithOffset(MemI, Base, Offset, OffsetIsScalable, TRI))
- return None;
-
- if (!Base->isReg())
- return None;
- ExtAddrMode AM;
- AM.BaseReg = Base->getReg();
- AM.Displacement = Offset;
- AM.ScaledReg = 0;
- return AM;
-}
-
+Optional<ExtAddrMode>
+AArch64InstrInfo::getAddrModeFromMemoryOp(const MachineInstr &MemI,
+ const TargetRegisterInfo *TRI) const {
+ const MachineOperand *Base; // Filled with the base operand of MI.
+ int64_t Offset; // Filled with the offset of MI.
+ bool OffsetIsScalable;
+ if (!getMemOperandWithOffset(MemI, Base, Offset, OffsetIsScalable, TRI))
+ return None;
+
+ if (!Base->isReg())
+ return None;
+ ExtAddrMode AM;
+ AM.BaseReg = Base->getReg();
+ AM.Displacement = Offset;
+ AM.ScaledReg = 0;
+ return AM;
+}
+
bool AArch64InstrInfo::getMemOperandWithOffsetWidth(
const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset,
bool &OffsetIsScalable, unsigned &Width,
@@ -3290,7 +3290,7 @@ void AArch64InstrInfo::storeRegToStackSlot(
else if (AArch64::PPRRegClass.hasSubClassEq(RC)) {
assert(Subtarget.hasSVE() && "Unexpected register store without SVE");
Opc = AArch64::STR_PXI;
- StackID = TargetStackID::ScalableVector;
+ StackID = TargetStackID::ScalableVector;
}
break;
case 4:
@@ -3334,7 +3334,7 @@ void AArch64InstrInfo::storeRegToStackSlot(
} else if (AArch64::ZPRRegClass.hasSubClassEq(RC)) {
assert(Subtarget.hasSVE() && "Unexpected register store without SVE");
Opc = AArch64::STR_ZXI;
- StackID = TargetStackID::ScalableVector;
+ StackID = TargetStackID::ScalableVector;
}
break;
case 24:
@@ -3356,7 +3356,7 @@ void AArch64InstrInfo::storeRegToStackSlot(
} else if (AArch64::ZPR2RegClass.hasSubClassEq(RC)) {
assert(Subtarget.hasSVE() && "Unexpected register store without SVE");
Opc = AArch64::STR_ZZXI;
- StackID = TargetStackID::ScalableVector;
+ StackID = TargetStackID::ScalableVector;
}
break;
case 48:
@@ -3367,7 +3367,7 @@ void AArch64InstrInfo::storeRegToStackSlot(
} else if (AArch64::ZPR3RegClass.hasSubClassEq(RC)) {
assert(Subtarget.hasSVE() && "Unexpected register store without SVE");
Opc = AArch64::STR_ZZZXI;
- StackID = TargetStackID::ScalableVector;
+ StackID = TargetStackID::ScalableVector;
}
break;
case 64:
@@ -3378,7 +3378,7 @@ void AArch64InstrInfo::storeRegToStackSlot(
} else if (AArch64::ZPR4RegClass.hasSubClassEq(RC)) {
assert(Subtarget.hasSVE() && "Unexpected register store without SVE");
Opc = AArch64::STR_ZZZZXI;
- StackID = TargetStackID::ScalableVector;
+ StackID = TargetStackID::ScalableVector;
}
break;
}
@@ -3444,7 +3444,7 @@ void AArch64InstrInfo::loadRegFromStackSlot(
else if (AArch64::PPRRegClass.hasSubClassEq(RC)) {
assert(Subtarget.hasSVE() && "Unexpected register load without SVE");
Opc = AArch64::LDR_PXI;
- StackID = TargetStackID::ScalableVector;
+ StackID = TargetStackID::ScalableVector;
}
break;
case 4:
@@ -3488,7 +3488,7 @@ void AArch64InstrInfo::loadRegFromStackSlot(
} else if (AArch64::ZPRRegClass.hasSubClassEq(RC)) {
assert(Subtarget.hasSVE() && "Unexpected register load without SVE");
Opc = AArch64::LDR_ZXI;
- StackID = TargetStackID::ScalableVector;
+ StackID = TargetStackID::ScalableVector;
}
break;
case 24:
@@ -3510,7 +3510,7 @@ void AArch64InstrInfo::loadRegFromStackSlot(
} else if (AArch64::ZPR2RegClass.hasSubClassEq(RC)) {
assert(Subtarget.hasSVE() && "Unexpected register load without SVE");
Opc = AArch64::LDR_ZZXI;
- StackID = TargetStackID::ScalableVector;
+ StackID = TargetStackID::ScalableVector;
}
break;
case 48:
@@ -3521,7 +3521,7 @@ void AArch64InstrInfo::loadRegFromStackSlot(
} else if (AArch64::ZPR3RegClass.hasSubClassEq(RC)) {
assert(Subtarget.hasSVE() && "Unexpected register load without SVE");
Opc = AArch64::LDR_ZZZXI;
- StackID = TargetStackID::ScalableVector;
+ StackID = TargetStackID::ScalableVector;
}
break;
case 64:
@@ -3532,7 +3532,7 @@ void AArch64InstrInfo::loadRegFromStackSlot(
} else if (AArch64::ZPR4RegClass.hasSubClassEq(RC)) {
assert(Subtarget.hasSVE() && "Unexpected register load without SVE");
Opc = AArch64::LDR_ZZZZXI;
- StackID = TargetStackID::ScalableVector;
+ StackID = TargetStackID::ScalableVector;
}
break;
}
@@ -3559,47 +3559,47 @@ bool llvm::isNZCVTouchedInInstructionRange(const MachineInstr &DefMI,
});
}
-void AArch64InstrInfo::decomposeStackOffsetForDwarfOffsets(
- const StackOffset &Offset, int64_t &ByteSized, int64_t &VGSized) {
- // The smallest scalable element supported by scaled SVE addressing
- // modes are predicates, which are 2 scalable bytes in size. So the scalable
- // byte offset must always be a multiple of 2.
- assert(Offset.getScalable() % 2 == 0 && "Invalid frame offset");
-
- // VGSized offsets are divided by '2', because the VG register is the
- // the number of 64bit granules as opposed to 128bit vector chunks,
- // which is how the 'n' in e.g. MVT::nxv1i8 is modelled.
- // So, for a stack offset of 16 MVT::nxv1i8's, the size is n x 16 bytes.
- // VG = n * 2 and the dwarf offset must be VG * 8 bytes.
- ByteSized = Offset.getFixed();
- VGSized = Offset.getScalable() / 2;
-}
-
-/// Returns the offset in parts to which this frame offset can be
-/// decomposed for the purpose of describing a frame offset.
-/// For non-scalable offsets this is simply its byte size.
-void AArch64InstrInfo::decomposeStackOffsetForFrameOffsets(
- const StackOffset &Offset, int64_t &NumBytes, int64_t &NumPredicateVectors,
- int64_t &NumDataVectors) {
- // The smallest scalable element supported by scaled SVE addressing
- // modes are predicates, which are 2 scalable bytes in size. So the scalable
- // byte offset must always be a multiple of 2.
- assert(Offset.getScalable() % 2 == 0 && "Invalid frame offset");
-
- NumBytes = Offset.getFixed();
- NumDataVectors = 0;
- NumPredicateVectors = Offset.getScalable() / 2;
- // This method is used to get the offsets to adjust the frame offset.
- // If the function requires ADDPL to be used and needs more than two ADDPL
- // instructions, part of the offset is folded into NumDataVectors so that it
- // uses ADDVL for part of it, reducing the number of ADDPL instructions.
- if (NumPredicateVectors % 8 == 0 || NumPredicateVectors < -64 ||
- NumPredicateVectors > 62) {
- NumDataVectors = NumPredicateVectors / 8;
- NumPredicateVectors -= NumDataVectors * 8;
- }
-}
-
+void AArch64InstrInfo::decomposeStackOffsetForDwarfOffsets(
+ const StackOffset &Offset, int64_t &ByteSized, int64_t &VGSized) {
+ // The smallest scalable element supported by scaled SVE addressing
+ // modes are predicates, which are 2 scalable bytes in size. So the scalable
+ // byte offset must always be a multiple of 2.
+ assert(Offset.getScalable() % 2 == 0 && "Invalid frame offset");
+
+ // VGSized offsets are divided by '2', because the VG register is the
+ // the number of 64bit granules as opposed to 128bit vector chunks,
+ // which is how the 'n' in e.g. MVT::nxv1i8 is modelled.
+ // So, for a stack offset of 16 MVT::nxv1i8's, the size is n x 16 bytes.
+ // VG = n * 2 and the dwarf offset must be VG * 8 bytes.
+ ByteSized = Offset.getFixed();
+ VGSized = Offset.getScalable() / 2;
+}
+
+/// Returns the offset in parts to which this frame offset can be
+/// decomposed for the purpose of describing a frame offset.
+/// For non-scalable offsets this is simply its byte size.
+void AArch64InstrInfo::decomposeStackOffsetForFrameOffsets(
+ const StackOffset &Offset, int64_t &NumBytes, int64_t &NumPredicateVectors,
+ int64_t &NumDataVectors) {
+ // The smallest scalable element supported by scaled SVE addressing
+ // modes are predicates, which are 2 scalable bytes in size. So the scalable
+ // byte offset must always be a multiple of 2.
+ assert(Offset.getScalable() % 2 == 0 && "Invalid frame offset");
+
+ NumBytes = Offset.getFixed();
+ NumDataVectors = 0;
+ NumPredicateVectors = Offset.getScalable() / 2;
+ // This method is used to get the offsets to adjust the frame offset.
+ // If the function requires ADDPL to be used and needs more than two ADDPL
+ // instructions, part of the offset is folded into NumDataVectors so that it
+ // uses ADDVL for part of it, reducing the number of ADDPL instructions.
+ if (NumPredicateVectors % 8 == 0 || NumPredicateVectors < -64 ||
+ NumPredicateVectors > 62) {
+ NumDataVectors = NumPredicateVectors / 8;
+ NumPredicateVectors -= NumDataVectors * 8;
+ }
+}
+
// Helper function to emit a frame offset adjustment from a given
// pointer (SrcReg), stored into DestReg. This function is explicit
// in that it requires the opcode.
@@ -3709,13 +3709,13 @@ void llvm::emitFrameOffset(MachineBasicBlock &MBB,
MachineInstr::MIFlag Flag, bool SetNZCV,
bool NeedsWinCFI, bool *HasWinCFI) {
int64_t Bytes, NumPredicateVectors, NumDataVectors;
- AArch64InstrInfo::decomposeStackOffsetForFrameOffsets(
- Offset, Bytes, NumPredicateVectors, NumDataVectors);
+ AArch64InstrInfo::decomposeStackOffsetForFrameOffsets(
+ Offset, Bytes, NumPredicateVectors, NumDataVectors);
// First emit non-scalable frame offsets, or a simple 'mov'.
if (Bytes || (!Offset && SrcReg != DestReg)) {
- assert((DestReg != AArch64::SP || Bytes % 8 == 0) &&
- "SP increment/decrement not 8-byte aligned");
+ assert((DestReg != AArch64::SP || Bytes % 8 == 0) &&
+ "SP increment/decrement not 8-byte aligned");
unsigned Opc = SetNZCV ? AArch64::ADDSXri : AArch64::ADDXri;
if (Bytes < 0) {
Bytes = -Bytes;
@@ -3970,7 +3970,7 @@ int llvm::isAArch64FrameOffsetLegal(const MachineInstr &MI,
// Construct the complete offset.
bool IsMulVL = ScaleValue.isScalable();
unsigned Scale = ScaleValue.getKnownMinSize();
- int64_t Offset = IsMulVL ? SOffset.getScalable() : SOffset.getFixed();
+ int64_t Offset = IsMulVL ? SOffset.getScalable() : SOffset.getFixed();
const MachineOperand &ImmOpnd =
MI.getOperand(AArch64InstrInfo::getLoadStoreImmIdx(MI.getOpcode()));
@@ -4012,9 +4012,9 @@ int llvm::isAArch64FrameOffsetLegal(const MachineInstr &MI,
*OutUnscaledOp = *UnscaledOp;
if (IsMulVL)
- SOffset = StackOffset::get(SOffset.getFixed(), Offset);
+ SOffset = StackOffset::get(SOffset.getFixed(), Offset);
else
- SOffset = StackOffset::get(Offset, SOffset.getScalable());
+ SOffset = StackOffset::get(Offset, SOffset.getScalable());
return AArch64FrameOffsetCanUpdate |
(SOffset ? 0 : AArch64FrameOffsetIsLegal);
}
@@ -4026,7 +4026,7 @@ bool llvm::rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
unsigned ImmIdx = FrameRegIdx + 1;
if (Opcode == AArch64::ADDSXri || Opcode == AArch64::ADDXri) {
- Offset += StackOffset::getFixed(MI.getOperand(ImmIdx).getImm());
+ Offset += StackOffset::getFixed(MI.getOperand(ImmIdx).getImm());
emitFrameOffset(*MI.getParent(), MI, MI.getDebugLoc(),
MI.getOperand(0).getReg(), FrameReg, Offset, TII,
MachineInstr::NoFlags, (Opcode == AArch64::ADDSXri));
@@ -4131,7 +4131,7 @@ static bool isCombineInstrCandidate64(unsigned Opc) {
return false;
}
-// FP Opcodes that can be combined with a FMUL.
+// FP Opcodes that can be combined with a FMUL.
static bool isCombineInstrCandidateFP(const MachineInstr &Inst) {
switch (Inst.getOpcode()) {
default:
@@ -4153,12 +4153,12 @@ static bool isCombineInstrCandidateFP(const MachineInstr &Inst) {
case AArch64::FSUBv2f64:
case AArch64::FSUBv4f32:
TargetOptions Options = Inst.getParent()->getParent()->getTarget().Options;
- // We can fuse FADD/FSUB with FMUL, if fusion is either allowed globally by
- // the target options or if FADD/FSUB has the contract fast-math flag.
- return Options.UnsafeFPMath ||
- Options.AllowFPOpFusion == FPOpFusion::Fast ||
- Inst.getFlag(MachineInstr::FmContract);
- return true;
+ // We can fuse FADD/FSUB with FMUL, if fusion is either allowed globally by
+ // the target options or if FADD/FSUB has the contract fast-math flag.
+ return Options.UnsafeFPMath ||
+ Options.AllowFPOpFusion == FPOpFusion::Fast ||
+ Inst.getFlag(MachineInstr::FmContract);
+ return true;
}
return false;
}
@@ -4638,8 +4638,8 @@ bool AArch64InstrInfo::isThroughputPattern(
/// pattern evaluator stops checking as soon as it finds a faster sequence.
bool AArch64InstrInfo::getMachineCombinerPatterns(
- MachineInstr &Root, SmallVectorImpl<MachineCombinerPattern> &Patterns,
- bool DoRegPressureReduce) const {
+ MachineInstr &Root, SmallVectorImpl<MachineCombinerPattern> &Patterns,
+ bool DoRegPressureReduce) const {
// Integer patterns
if (getMaddPatterns(Root, Patterns))
return true;
@@ -4647,8 +4647,8 @@ bool AArch64InstrInfo::getMachineCombinerPatterns(
if (getFMAPatterns(Root, Patterns))
return true;
- return TargetInstrInfo::getMachineCombinerPatterns(Root, Patterns,
- DoRegPressureReduce);
+ return TargetInstrInfo::getMachineCombinerPatterns(Root, Patterns,
+ DoRegPressureReduce);
}
enum class FMAInstKind { Default, Indexed, Accumulator };
@@ -4871,7 +4871,7 @@ void AArch64InstrInfo::genAlternativeCodeSequence(
MachineFunction &MF = *MBB.getParent();
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
- MachineInstr *MUL = nullptr;
+ MachineInstr *MUL = nullptr;
const TargetRegisterClass *RC;
unsigned Opc;
switch (Pattern) {
@@ -5692,9 +5692,9 @@ void AArch64InstrInfo::genAlternativeCodeSequence(
}
} // end switch (Pattern)
// Record MUL and ADD/SUB for deletion
- // FIXME: This assertion fails in CodeGen/AArch64/tailmerging_in_mbp.ll and
- // CodeGen/AArch64/urem-seteq-nonzero.ll.
- // assert(MUL && "MUL was never set");
+ // FIXME: This assertion fails in CodeGen/AArch64/tailmerging_in_mbp.ll and
+ // CodeGen/AArch64/urem-seteq-nonzero.ll.
+ // assert(MUL && "MUL was never set");
DelInstrs.push_back(MUL);
DelInstrs.push_back(&Root);
}
@@ -6034,20 +6034,20 @@ AArch64InstrInfo::findRegisterToSaveLRTo(const outliner::Candidate &C) const {
static bool
outliningCandidatesSigningScopeConsensus(const outliner::Candidate &a,
const outliner::Candidate &b) {
- const auto &MFIa = a.getMF()->getInfo<AArch64FunctionInfo>();
- const auto &MFIb = b.getMF()->getInfo<AArch64FunctionInfo>();
+ const auto &MFIa = a.getMF()->getInfo<AArch64FunctionInfo>();
+ const auto &MFIb = b.getMF()->getInfo<AArch64FunctionInfo>();
- return MFIa->shouldSignReturnAddress(false) == MFIb->shouldSignReturnAddress(false) &&
- MFIa->shouldSignReturnAddress(true) == MFIb->shouldSignReturnAddress(true);
+ return MFIa->shouldSignReturnAddress(false) == MFIb->shouldSignReturnAddress(false) &&
+ MFIa->shouldSignReturnAddress(true) == MFIb->shouldSignReturnAddress(true);
}
static bool
outliningCandidatesSigningKeyConsensus(const outliner::Candidate &a,
const outliner::Candidate &b) {
- const auto &MFIa = a.getMF()->getInfo<AArch64FunctionInfo>();
- const auto &MFIb = b.getMF()->getInfo<AArch64FunctionInfo>();
+ const auto &MFIa = a.getMF()->getInfo<AArch64FunctionInfo>();
+ const auto &MFIb = b.getMF()->getInfo<AArch64FunctionInfo>();
- return MFIa->shouldSignWithBKey() == MFIb->shouldSignWithBKey();
+ return MFIa->shouldSignWithBKey() == MFIb->shouldSignWithBKey();
}
static bool outliningCandidatesV8_3OpsConsensus(const outliner::Candidate &a,
@@ -6104,9 +6104,9 @@ outliner::OutlinedFunction AArch64InstrInfo::getOutliningCandidateInfo(
// necessary. However, at this point we don't know if the outlined function
// will have a RET instruction so we assume the worst.
const TargetRegisterInfo &TRI = getRegisterInfo();
- if (FirstCand.getMF()
- ->getInfo<AArch64FunctionInfo>()
- ->shouldSignReturnAddress(true)) {
+ if (FirstCand.getMF()
+ ->getInfo<AArch64FunctionInfo>()
+ ->shouldSignReturnAddress(true)) {
// One PAC and one AUT instructions
NumBytesToCreateFrame += 8;
@@ -6163,7 +6163,7 @@ outliner::OutlinedFunction AArch64InstrInfo::getOutliningCandidateInfo(
return false;
};
// Remove candidates with illegal stack modifying instructions
- llvm::erase_if(RepeatedSequenceLocs, hasIllegalSPModification);
+ llvm::erase_if(RepeatedSequenceLocs, hasIllegalSPModification);
// If the sequence doesn't have enough candidates left, then we're done.
if (RepeatedSequenceLocs.size() < 2)
@@ -6206,7 +6206,7 @@ outliner::OutlinedFunction AArch64InstrInfo::getOutliningCandidateInfo(
// Erase every candidate that violates the restrictions above. (It could be
// true that we have viable candidates, so it's not worth bailing out in
// the case that, say, 1 out of 20 candidates violate the restructions.)
- llvm::erase_if(RepeatedSequenceLocs, CantGuaranteeValueAcrossCall);
+ llvm::erase_if(RepeatedSequenceLocs, CantGuaranteeValueAcrossCall);
// If the sequence doesn't have enough candidates left, then we're done.
if (RepeatedSequenceLocs.size() < 2)
@@ -6229,7 +6229,7 @@ outliner::OutlinedFunction AArch64InstrInfo::getOutliningCandidateInfo(
NumBytesToCreateFrame += 4;
bool HasBTI = any_of(RepeatedSequenceLocs, [](outliner::Candidate &C) {
- return C.getMF()->getInfo<AArch64FunctionInfo>()->branchTargetEnforcement();
+ return C.getMF()->getInfo<AArch64FunctionInfo>()->branchTargetEnforcement();
});
// We check to see if CFI Instructions are present, and if they are
@@ -6398,60 +6398,60 @@ outliner::OutlinedFunction AArch64InstrInfo::getOutliningCandidateInfo(
FrameID = MachineOutlinerNoLRSave;
} else {
SetCandidateCallInfo(MachineOutlinerDefault, 12);
-
- // Bugzilla ID: 46767
- // TODO: Check if fixing up the stack more than once is safe so we can
- // outline these.
- //
- // An outline resulting in a caller that requires stack fixups at the
- // callsite to a callee that also requires stack fixups can happen when
- // there are no available registers at the candidate callsite for a
- // candidate that itself also has calls.
- //
- // In other words if function_containing_sequence in the following pseudo
- // assembly requires that we save LR at the point of the call, but there
- // are no available registers: in this case we save using SP and as a
- // result the SP offsets requires stack fixups by multiples of 16.
- //
- // function_containing_sequence:
- // ...
- // save LR to SP <- Requires stack instr fixups in OUTLINED_FUNCTION_N
- // call OUTLINED_FUNCTION_N
- // restore LR from SP
- // ...
- //
- // OUTLINED_FUNCTION_N:
- // save LR to SP <- Requires stack instr fixups in OUTLINED_FUNCTION_N
- // ...
- // bl foo
- // restore LR from SP
- // ret
- //
- // Because the code to handle more than one stack fixup does not
- // currently have the proper checks for legality, these cases will assert
- // in the AArch64 MachineOutliner. This is because the code to do this
- // needs more hardening, testing, better checks that generated code is
- // legal, etc and because it is only verified to handle a single pass of
- // stack fixup.
- //
- // The assert happens in AArch64InstrInfo::buildOutlinedFrame to catch
- // these cases until they are known to be handled. Bugzilla 46767 is
- // referenced in comments at the assert site.
- //
- // To avoid asserting (or generating non-legal code on noassert builds)
- // we remove all candidates which would need more than one stack fixup by
- // pruning the cases where the candidate has calls while also having no
- // available LR and having no available general purpose registers to copy
- // LR to (ie one extra stack save/restore).
- //
- if (FlagsSetInAll & MachineOutlinerMBBFlags::HasCalls) {
- erase_if(RepeatedSequenceLocs, [this](outliner::Candidate &C) {
- return (std::any_of(
- C.front(), std::next(C.back()),
- [](const MachineInstr &MI) { return MI.isCall(); })) &&
- (!C.LRU.available(AArch64::LR) || !findRegisterToSaveLRTo(C));
- });
- }
+
+ // Bugzilla ID: 46767
+ // TODO: Check if fixing up the stack more than once is safe so we can
+ // outline these.
+ //
+ // An outline resulting in a caller that requires stack fixups at the
+ // callsite to a callee that also requires stack fixups can happen when
+ // there are no available registers at the candidate callsite for a
+ // candidate that itself also has calls.
+ //
+ // In other words if function_containing_sequence in the following pseudo
+ // assembly requires that we save LR at the point of the call, but there
+ // are no available registers: in this case we save using SP and as a
+ // result the SP offsets requires stack fixups by multiples of 16.
+ //
+ // function_containing_sequence:
+ // ...
+ // save LR to SP <- Requires stack instr fixups in OUTLINED_FUNCTION_N
+ // call OUTLINED_FUNCTION_N
+ // restore LR from SP
+ // ...
+ //
+ // OUTLINED_FUNCTION_N:
+ // save LR to SP <- Requires stack instr fixups in OUTLINED_FUNCTION_N
+ // ...
+ // bl foo
+ // restore LR from SP
+ // ret
+ //
+ // Because the code to handle more than one stack fixup does not
+ // currently have the proper checks for legality, these cases will assert
+ // in the AArch64 MachineOutliner. This is because the code to do this
+ // needs more hardening, testing, better checks that generated code is
+ // legal, etc and because it is only verified to handle a single pass of
+ // stack fixup.
+ //
+ // The assert happens in AArch64InstrInfo::buildOutlinedFrame to catch
+ // these cases until they are known to be handled. Bugzilla 46767 is
+ // referenced in comments at the assert site.
+ //
+ // To avoid asserting (or generating non-legal code on noassert builds)
+ // we remove all candidates which would need more than one stack fixup by
+ // pruning the cases where the candidate has calls while also having no
+ // available LR and having no available general purpose registers to copy
+ // LR to (ie one extra stack save/restore).
+ //
+ if (FlagsSetInAll & MachineOutlinerMBBFlags::HasCalls) {
+ erase_if(RepeatedSequenceLocs, [this](outliner::Candidate &C) {
+ return (std::any_of(
+ C.front(), std::next(C.back()),
+ [](const MachineInstr &MI) { return MI.isCall(); })) &&
+ (!C.LRU.available(AArch64::LR) || !findRegisterToSaveLRTo(C));
+ });
+ }
}
// If we dropped all of the candidates, bail out here.
@@ -6820,7 +6820,7 @@ static void signOutlinedFunction(MachineFunction &MF, MachineBasicBlock &MBB,
// If v8.3a features are available we can replace a RET instruction by
// RETAA or RETAB and omit the AUT instructions
- if (Subtarget.hasPAuth() && MBBAUT != MBB.end() &&
+ if (Subtarget.hasPAuth() && MBBAUT != MBB.end() &&
MBBAUT->getOpcode() == AArch64::RET) {
BuildMI(MBB, MBBAUT, DL,
TII->get(ShouldSignReturnAddrWithAKey ? AArch64::RETAA
@@ -6872,12 +6872,12 @@ void AArch64InstrInfo::buildOutlinedFrame(
return MI.isCall() && !MI.isReturn();
};
- if (llvm::any_of(MBB.instrs(), IsNonTailCall)) {
+ if (llvm::any_of(MBB.instrs(), IsNonTailCall)) {
// Fix up the instructions in the range, since we're going to modify the
// stack.
-
- // Bugzilla ID: 46767
- // TODO: Check if fixing up twice is safe so we can outline these.
+
+ // Bugzilla ID: 46767
+ // TODO: Check if fixing up twice is safe so we can outline these.
assert(OF.FrameConstructionID != MachineOutlinerDefault &&
"Can only fix up stack references once");
fixupPostOutline(MBB);
@@ -6934,11 +6934,11 @@ void AArch64InstrInfo::buildOutlinedFrame(
// If a bunch of candidates reach this point they must agree on their return
// address signing. It is therefore enough to just consider the signing
// behaviour of one of them
- const auto &MFI = *OF.Candidates.front().getMF()->getInfo<AArch64FunctionInfo>();
- bool ShouldSignReturnAddr = MFI.shouldSignReturnAddress(!IsLeafFunction);
+ const auto &MFI = *OF.Candidates.front().getMF()->getInfo<AArch64FunctionInfo>();
+ bool ShouldSignReturnAddr = MFI.shouldSignReturnAddress(!IsLeafFunction);
// a_key is the default
- bool ShouldSignReturnAddrWithAKey = !MFI.shouldSignWithBKey();
+ bool ShouldSignReturnAddrWithAKey = !MFI.shouldSignWithBKey();
// If this is a tail call outlined function, then there's already a return.
if (OF.FrameConstructionID == MachineOutlinerTailCall ||
@@ -7099,7 +7099,7 @@ Optional<RegImmPair> AArch64InstrInfo::isAddImmediate(const MachineInstr &MI,
return None;
int Shift = MI.getOperand(3).getImm();
assert((Shift == 0 || Shift == 12) && "Shift can be either 0 or 12");
- Offset = Sign * (MI.getOperand(2).getImm() << Shift);
+ Offset = Sign * (MI.getOperand(2).getImm() << Shift);
}
}
return RegImmPair{MI.getOperand(1).getReg(), Offset};
@@ -7175,14 +7175,14 @@ uint64_t AArch64InstrInfo::getElementSizeForOpcode(unsigned Opc) const {
return get(Opc).TSFlags & AArch64::ElementSizeMask;
}
-bool AArch64InstrInfo::isPTestLikeOpcode(unsigned Opc) const {
- return get(Opc).TSFlags & AArch64::InstrFlagIsPTestLike;
-}
-
-bool AArch64InstrInfo::isWhileOpcode(unsigned Opc) const {
- return get(Opc).TSFlags & AArch64::InstrFlagIsWhile;
-}
-
+bool AArch64InstrInfo::isPTestLikeOpcode(unsigned Opc) const {
+ return get(Opc).TSFlags & AArch64::InstrFlagIsPTestLike;
+}
+
+bool AArch64InstrInfo::isWhileOpcode(unsigned Opc) const {
+ return get(Opc).TSFlags & AArch64::InstrFlagIsWhile;
+}
+
unsigned llvm::getBLRCallOpcode(const MachineFunction &MF) {
if (MF.getSubtarget<AArch64Subtarget>().hardenSlsBlr())
return AArch64::BLRNoIP;
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrInfo.h b/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrInfo.h
index 9b924a8440..7434987e06 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrInfo.h
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrInfo.h
@@ -112,10 +112,10 @@ public:
/// Hint that pairing the given load or store is unprofitable.
static void suppressLdStPair(MachineInstr &MI);
- Optional<ExtAddrMode>
- getAddrModeFromMemoryOp(const MachineInstr &MemI,
- const TargetRegisterInfo *TRI) const override;
-
+ Optional<ExtAddrMode>
+ getAddrModeFromMemoryOp(const MachineInstr &MemI,
+ const TargetRegisterInfo *TRI) const override;
+
bool getMemOperandsWithOffsetWidth(
const MachineInstr &MI, SmallVectorImpl<const MachineOperand *> &BaseOps,
int64_t &Offset, bool &OffsetIsScalable, unsigned &Width,
@@ -191,9 +191,9 @@ public:
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify = false) const override;
- bool analyzeBranchPredicate(MachineBasicBlock &MBB,
- MachineBranchPredicate &MBP,
- bool AllowModify) const override;
+ bool analyzeBranchPredicate(MachineBasicBlock &MBB,
+ MachineBranchPredicate &MBP,
+ bool AllowModify) const override;
unsigned removeBranch(MachineBasicBlock &MBB,
int *BytesRemoved = nullptr) const override;
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
@@ -235,10 +235,10 @@ public:
/// Return true when there is potentially a faster code sequence
/// for an instruction chain ending in ``Root``. All potential patterns are
/// listed in the ``Patterns`` array.
- bool
- getMachineCombinerPatterns(MachineInstr &Root,
- SmallVectorImpl<MachineCombinerPattern> &Patterns,
- bool DoRegPressureReduce) const override;
+ bool
+ getMachineCombinerPatterns(MachineInstr &Root,
+ SmallVectorImpl<MachineCombinerPattern> &Patterns,
+ bool DoRegPressureReduce) const override;
/// Return true when Inst is associative and commutative so that it can be
/// reassociated.
bool isAssociativeAndCommutative(const MachineInstr &Inst) const override;
@@ -280,12 +280,12 @@ public:
bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override;
/// Returns the vector element size (B, H, S or D) of an SVE opcode.
uint64_t getElementSizeForOpcode(unsigned Opc) const;
- /// Returns true if the opcode is for an SVE instruction that sets the
- /// condition codes as if it's results had been fed to a PTEST instruction
- /// along with the same general predicate.
- bool isPTestLikeOpcode(unsigned Opc) const;
- /// Returns true if the opcode is for an SVE WHILE## instruction.
- bool isWhileOpcode(unsigned Opc) const;
+ /// Returns true if the opcode is for an SVE instruction that sets the
+ /// condition codes as if it's results had been fed to a PTEST instruction
+ /// along with the same general predicate.
+ bool isPTestLikeOpcode(unsigned Opc) const;
+ /// Returns true if the opcode is for an SVE WHILE## instruction.
+ bool isWhileOpcode(unsigned Opc) const;
/// Returns true if the instruction has a shift by immediate that can be
/// executed in one cycle less.
static bool isFalkorShiftExtFast(const MachineInstr &MI);
@@ -299,13 +299,13 @@ public:
Optional<ParamLoadedValue> describeLoadedValue(const MachineInstr &MI,
Register Reg) const override;
- static void decomposeStackOffsetForFrameOffsets(const StackOffset &Offset,
- int64_t &NumBytes,
- int64_t &NumPredicateVectors,
- int64_t &NumDataVectors);
- static void decomposeStackOffsetForDwarfOffsets(const StackOffset &Offset,
- int64_t &ByteSized,
- int64_t &VGSized);
+ static void decomposeStackOffsetForFrameOffsets(const StackOffset &Offset,
+ int64_t &NumBytes,
+ int64_t &NumPredicateVectors,
+ int64_t &NumDataVectors);
+ static void decomposeStackOffsetForDwarfOffsets(const StackOffset &Offset,
+ int64_t &ByteSized,
+ int64_t &VGSized);
#define GET_INSTRINFO_HELPER_DECLS
#include "AArch64GenInstrInfo.inc"
@@ -334,12 +334,12 @@ private:
/// Returns an unused general-purpose register which can be used for
/// constructing an outlined call if one exists. Returns 0 otherwise.
unsigned findRegisterToSaveLRTo(const outliner::Candidate &C) const;
-
- /// Remove a ptest of a predicate-generating operation that already sets, or
- /// can be made to set, the condition codes in an identical manner
- bool optimizePTestInstr(MachineInstr *PTest, unsigned MaskReg,
- unsigned PredReg,
- const MachineRegisterInfo *MRI) const;
+
+ /// Remove a ptest of a predicate-generating operation that already sets, or
+ /// can be made to set, the condition codes in an identical manner
+ bool optimizePTestInstr(MachineInstr *PTest, unsigned MaskReg,
+ unsigned PredReg,
+ const MachineRegisterInfo *MRI) const;
};
/// Return true if there is an instruction /after/ \p DefMI and before \p UseMI
@@ -423,18 +423,18 @@ static inline bool isIndirectBranchOpcode(int Opc) {
return false;
}
-static inline bool isPTrueOpcode(unsigned Opc) {
- switch (Opc) {
- case AArch64::PTRUE_B:
- case AArch64::PTRUE_H:
- case AArch64::PTRUE_S:
- case AArch64::PTRUE_D:
- return true;
- default:
- return false;
- }
-}
-
+static inline bool isPTrueOpcode(unsigned Opc) {
+ switch (Opc) {
+ case AArch64::PTRUE_B:
+ case AArch64::PTRUE_H:
+ case AArch64::PTRUE_S:
+ case AArch64::PTRUE_D:
+ return true;
+ default:
+ return false;
+ }
+}
+
/// Return opcode to be used for indirect calls.
unsigned getBLRCallOpcode(const MachineFunction &MF);
@@ -442,7 +442,7 @@ unsigned getBLRCallOpcode(const MachineFunction &MF);
#define TSFLAG_ELEMENT_SIZE_TYPE(X) (X) // 3-bits
#define TSFLAG_DESTRUCTIVE_INST_TYPE(X) ((X) << 3) // 4-bit
#define TSFLAG_FALSE_LANE_TYPE(X) ((X) << 7) // 2-bits
-#define TSFLAG_INSTR_FLAGS(X) ((X) << 9) // 2-bits
+#define TSFLAG_INSTR_FLAGS(X) ((X) << 9) // 2-bits
// }
namespace AArch64 {
@@ -475,14 +475,14 @@ enum FalseLaneType {
FalseLanesUndef = TSFLAG_FALSE_LANE_TYPE(0x2),
};
-// NOTE: This is a bit field.
-static const uint64_t InstrFlagIsWhile = TSFLAG_INSTR_FLAGS(0x1);
-static const uint64_t InstrFlagIsPTestLike = TSFLAG_INSTR_FLAGS(0x2);
-
+// NOTE: This is a bit field.
+static const uint64_t InstrFlagIsWhile = TSFLAG_INSTR_FLAGS(0x1);
+static const uint64_t InstrFlagIsPTestLike = TSFLAG_INSTR_FLAGS(0x2);
+
#undef TSFLAG_ELEMENT_SIZE_TYPE
#undef TSFLAG_DESTRUCTIVE_INST_TYPE
#undef TSFLAG_FALSE_LANE_TYPE
-#undef TSFLAG_INSTR_FLAGS
+#undef TSFLAG_INSTR_FLAGS
int getSVEPseudoMap(uint16_t Opcode);
int getSVERevInstr(uint16_t Opcode);
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrInfo.td b/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrInfo.td
index 8051a6a937..171d3dbaa8 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64InstrInfo.td
@@ -25,16 +25,16 @@ def HasV8_5a : Predicate<"Subtarget->hasV8_5aOps()">,
AssemblerPredicate<(all_of HasV8_5aOps), "armv8.5a">;
def HasV8_6a : Predicate<"Subtarget->hasV8_6aOps()">,
AssemblerPredicate<(all_of HasV8_6aOps), "armv8.6a">;
-def HasV8_7a : Predicate<"Subtarget->hasV8_7aOps()">,
- AssemblerPredicate<(all_of HasV8_7aOps), "armv8.7a">;
+def HasV8_7a : Predicate<"Subtarget->hasV8_7aOps()">,
+ AssemblerPredicate<(all_of HasV8_7aOps), "armv8.7a">;
def HasVH : Predicate<"Subtarget->hasVH()">,
AssemblerPredicate<(all_of FeatureVH), "vh">;
def HasLOR : Predicate<"Subtarget->hasLOR()">,
AssemblerPredicate<(all_of FeatureLOR), "lor">;
-def HasPAuth : Predicate<"Subtarget->hasPAuth()">,
- AssemblerPredicate<(all_of FeaturePAuth), "pauth">;
+def HasPAuth : Predicate<"Subtarget->hasPAuth()">,
+ AssemblerPredicate<(all_of FeaturePAuth), "pauth">;
def HasJS : Predicate<"Subtarget->hasJS()">,
AssemblerPredicate<(all_of FeatureJS), "jsconv">;
@@ -69,8 +69,8 @@ def HasPMU : Predicate<"Subtarget->hasPMU()">,
def HasTLB_RMI : Predicate<"Subtarget->hasTLB_RMI()">,
AssemblerPredicate<(all_of FeatureTLB_RMI), "tlb-rmi">;
-def HasFlagM : Predicate<"Subtarget->hasFlagM()">,
- AssemblerPredicate<(all_of FeatureFlagM), "flagm">;
+def HasFlagM : Predicate<"Subtarget->hasFlagM()">,
+ AssemblerPredicate<(all_of FeatureFlagM), "flagm">;
def HasRCPC_IMMO : Predicate<"Subtarget->hasRCPCImm()">,
AssemblerPredicate<(all_of FeatureRCPC_IMMO), "rcpc-immo">;
@@ -151,16 +151,16 @@ def HasMatMulFP32 : Predicate<"Subtarget->hasMatMulFP32()">,
AssemblerPredicate<(all_of FeatureMatMulFP32), "f32mm">;
def HasMatMulFP64 : Predicate<"Subtarget->hasMatMulFP64()">,
AssemblerPredicate<(all_of FeatureMatMulFP64), "f64mm">;
-def HasXS : Predicate<"Subtarget->hasXS()">,
- AssemblerPredicate<(all_of FeatureXS), "xs">;
-def HasWFxT : Predicate<"Subtarget->hasWFxT()">,
- AssemblerPredicate<(all_of FeatureWFxT), "wfxt">;
-def HasLS64 : Predicate<"Subtarget->hasLS64()">,
- AssemblerPredicate<(all_of FeatureLS64), "ls64">;
-def HasBRBE : Predicate<"Subtarget->hasBRBE()">,
- AssemblerPredicate<(all_of FeatureBRBE), "brbe">;
-def HasSPE_EEF : Predicate<"Subtarget->hasSPE_EEF()">,
- AssemblerPredicate<(all_of FeatureSPE_EEF), "spe-eef">;
+def HasXS : Predicate<"Subtarget->hasXS()">,
+ AssemblerPredicate<(all_of FeatureXS), "xs">;
+def HasWFxT : Predicate<"Subtarget->hasWFxT()">,
+ AssemblerPredicate<(all_of FeatureWFxT), "wfxt">;
+def HasLS64 : Predicate<"Subtarget->hasLS64()">,
+ AssemblerPredicate<(all_of FeatureLS64), "ls64">;
+def HasBRBE : Predicate<"Subtarget->hasBRBE()">,
+ AssemblerPredicate<(all_of FeatureBRBE), "brbe">;
+def HasSPE_EEF : Predicate<"Subtarget->hasSPE_EEF()">,
+ AssemblerPredicate<(all_of FeatureSPE_EEF), "spe-eef">;
def IsLE : Predicate<"Subtarget->isLittleEndian()">;
def IsBE : Predicate<"!Subtarget->isLittleEndian()">;
def IsWindows : Predicate<"Subtarget->isTargetWindows()">;
@@ -411,12 +411,12 @@ def AArch64call : SDNode<"AArch64ISD::CALL",
SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
SDNPVariadic]>;
-
-def AArch64call_rvmarker: SDNode<"AArch64ISD::CALL_RVMARKER",
- SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>,
- [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
- SDNPVariadic]>;
-
+
+def AArch64call_rvmarker: SDNode<"AArch64ISD::CALL_RVMARKER",
+ SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>,
+ [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
+ SDNPVariadic]>;
+
def AArch64brcond : SDNode<"AArch64ISD::BRCOND", SDT_AArch64Brcond,
[SDNPHasChain]>;
def AArch64cbz : SDNode<"AArch64ISD::CBZ", SDT_AArch64cbz,
@@ -518,7 +518,7 @@ def AArch64cmgtz: SDNode<"AArch64ISD::CMGTz", SDT_AArch64unvec>;
def AArch64cmlez: SDNode<"AArch64ISD::CMLEz", SDT_AArch64unvec>;
def AArch64cmltz: SDNode<"AArch64ISD::CMLTz", SDT_AArch64unvec>;
def AArch64cmtst : PatFrag<(ops node:$LHS, node:$RHS),
- (vnot (AArch64cmeqz (and node:$LHS, node:$RHS)))>;
+ (vnot (AArch64cmeqz (and node:$LHS, node:$RHS)))>;
def AArch64fcmeqz: SDNode<"AArch64ISD::FCMEQz", SDT_AArch64fcmpz>;
def AArch64fcmgez: SDNode<"AArch64ISD::FCMGEz", SDT_AArch64fcmpz>;
@@ -570,19 +570,19 @@ def AArch64umaxv : SDNode<"AArch64ISD::UMAXV", SDT_AArch64UnaryVec>;
def AArch64srhadd : SDNode<"AArch64ISD::SRHADD", SDT_AArch64binvec>;
def AArch64urhadd : SDNode<"AArch64ISD::URHADD", SDT_AArch64binvec>;
-def AArch64shadd : SDNode<"AArch64ISD::SHADD", SDT_AArch64binvec>;
-def AArch64uhadd : SDNode<"AArch64ISD::UHADD", SDT_AArch64binvec>;
-
-def AArch64uabd_n : SDNode<"AArch64ISD::UABD", SDT_AArch64binvec>;
-def AArch64sabd_n : SDNode<"AArch64ISD::SABD", SDT_AArch64binvec>;
-
-def AArch64uabd : PatFrags<(ops node:$lhs, node:$rhs),
- [(AArch64uabd_n node:$lhs, node:$rhs),
- (int_aarch64_neon_uabd node:$lhs, node:$rhs)]>;
-def AArch64sabd : PatFrags<(ops node:$lhs, node:$rhs),
- [(AArch64sabd_n node:$lhs, node:$rhs),
- (int_aarch64_neon_sabd node:$lhs, node:$rhs)]>;
-
+def AArch64shadd : SDNode<"AArch64ISD::SHADD", SDT_AArch64binvec>;
+def AArch64uhadd : SDNode<"AArch64ISD::UHADD", SDT_AArch64binvec>;
+
+def AArch64uabd_n : SDNode<"AArch64ISD::UABD", SDT_AArch64binvec>;
+def AArch64sabd_n : SDNode<"AArch64ISD::SABD", SDT_AArch64binvec>;
+
+def AArch64uabd : PatFrags<(ops node:$lhs, node:$rhs),
+ [(AArch64uabd_n node:$lhs, node:$rhs),
+ (int_aarch64_neon_uabd node:$lhs, node:$rhs)]>;
+def AArch64sabd : PatFrags<(ops node:$lhs, node:$rhs),
+ [(AArch64sabd_n node:$lhs, node:$rhs),
+ (int_aarch64_neon_sabd node:$lhs, node:$rhs)]>;
+
def SDT_AArch64SETTAG : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisPtrTy<1>]>;
def AArch64stg : SDNode<"AArch64ISD::STG", SDT_AArch64SETTAG, [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
def AArch64stzg : SDNode<"AArch64ISD::STZG", SDT_AArch64SETTAG, [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
@@ -617,8 +617,8 @@ let RecomputePerFunction = 1 in {
// Avoid generating STRQro if it is slow, unless we're optimizing for code size.
def UseSTRQro : Predicate<"!Subtarget->isSTRQroSlow() || shouldOptForSize(MF)">;
- def UseBTI : Predicate<[{ MF->getInfo<AArch64FunctionInfo>()->branchTargetEnforcement() }]>;
- def NotUseBTI : Predicate<[{ !MF->getInfo<AArch64FunctionInfo>()->branchTargetEnforcement() }]>;
+ def UseBTI : Predicate<[{ MF->getInfo<AArch64FunctionInfo>()->branchTargetEnforcement() }]>;
+ def NotUseBTI : Predicate<[{ !MF->getInfo<AArch64FunctionInfo>()->branchTargetEnforcement() }]>;
def SLSBLRMitigation : Predicate<[{ MF->getSubtarget<AArch64Subtarget>().hardenSlsBlr() }]>;
def NoSLSBLRMitigation : Predicate<[{ !MF->getSubtarget<AArch64Subtarget>().hardenSlsBlr() }]>;
@@ -716,8 +716,8 @@ def : Pat<(AArch64LOADgot tconstpool:$addr),
// 32-bit jump table destination is actually only 2 instructions since we can
// use the table itself as a PC-relative base. But optimization occurs after
// branch relaxation so be pessimistic.
-let Size = 12, Constraints = "@earlyclobber $dst,@earlyclobber $scratch",
- isNotDuplicable = 1 in {
+let Size = 12, Constraints = "@earlyclobber $dst,@earlyclobber $scratch",
+ isNotDuplicable = 1 in {
def JumpTableDest32 : Pseudo<(outs GPR64:$dst, GPR64sp:$scratch),
(ins GPR64:$table, GPR64:$entry, i32imm:$jti), []>,
Sched<[]>;
@@ -801,34 +801,34 @@ def TSB : CRmSystemI<barrier_op, 0b010, "tsb", []> {
let Inst{12} = 0;
let Predicates = [HasTRACEV8_4];
}
-
-def DSBnXS : CRmSystemI<barrier_nxs_op, 0b001, "dsb"> {
- let CRm{1-0} = 0b11;
- let Inst{9-8} = 0b10;
- let Predicates = [HasXS];
-}
-
-let Predicates = [HasWFxT] in {
-def WFET : RegInputSystemI<0b0000, 0b000, "wfet">;
-def WFIT : RegInputSystemI<0b0000, 0b001, "wfit">;
-}
-
-// Branch Record Buffer two-word mnemonic instructions
-class BRBEI<bits<3> op2, string keyword>
- : SimpleSystemI<0, (ins), "brb", keyword>, Sched<[WriteSys]> {
- let Inst{31-8} = 0b110101010000100101110010;
- let Inst{7-5} = op2;
- let Predicates = [HasBRBE];
-}
-def BRB_IALL: BRBEI<0b100, "\tiall">;
-def BRB_INJ: BRBEI<0b101, "\tinj">;
-
-}
-
-// Allow uppercase and lowercase keyword arguments for BRB IALL and BRB INJ
-def : TokenAlias<"INJ", "inj">;
-def : TokenAlias<"IALL", "iall">;
-
+
+def DSBnXS : CRmSystemI<barrier_nxs_op, 0b001, "dsb"> {
+ let CRm{1-0} = 0b11;
+ let Inst{9-8} = 0b10;
+ let Predicates = [HasXS];
+}
+
+let Predicates = [HasWFxT] in {
+def WFET : RegInputSystemI<0b0000, 0b000, "wfet">;
+def WFIT : RegInputSystemI<0b0000, 0b001, "wfit">;
+}
+
+// Branch Record Buffer two-word mnemonic instructions
+class BRBEI<bits<3> op2, string keyword>
+ : SimpleSystemI<0, (ins), "brb", keyword>, Sched<[WriteSys]> {
+ let Inst{31-8} = 0b110101010000100101110010;
+ let Inst{7-5} = op2;
+ let Predicates = [HasBRBE];
+}
+def BRB_IALL: BRBEI<0b100, "\tiall">;
+def BRB_INJ: BRBEI<0b101, "\tinj">;
+
+}
+
+// Allow uppercase and lowercase keyword arguments for BRB IALL and BRB INJ
+def : TokenAlias<"INJ", "inj">;
+def : TokenAlias<"IALL", "iall">;
+
// ARMv8.2-A Dot Product
let Predicates = [HasDotProd] in {
defm SDOT : SIMDThreeSameVectorDot<0, 0, "sdot", int_aarch64_neon_sdot>;
@@ -849,23 +849,23 @@ def BFMLALTIdx : SIMDBF16MLALIndex<1, "bfmlalt", int_aarch64_neon_bfmlalt>;
def BFCVTN : SIMD_BFCVTN;
def BFCVTN2 : SIMD_BFCVTN2;
def BFCVT : BF16ToSinglePrecision<"bfcvt">;
-
-// Vector-scalar BFDOT:
-// The second source operand of the 64-bit variant of BF16DOTlane is a 128-bit
-// register (the instruction uses a single 32-bit lane from it), so the pattern
-// is a bit tricky.
-def : Pat<(v2f32 (int_aarch64_neon_bfdot
- (v2f32 V64:$Rd), (v4bf16 V64:$Rn),
- (v4bf16 (bitconvert
- (v2i32 (AArch64duplane32
- (v4i32 (bitconvert
- (v8bf16 (insert_subvector undef,
- (v4bf16 V64:$Rm),
- (i64 0))))),
- VectorIndexS:$idx)))))),
- (BF16DOTlanev4bf16 (v2f32 V64:$Rd), (v4bf16 V64:$Rn),
- (SUBREG_TO_REG (i32 0), V64:$Rm, dsub),
- VectorIndexS:$idx)>;
+
+// Vector-scalar BFDOT:
+// The second source operand of the 64-bit variant of BF16DOTlane is a 128-bit
+// register (the instruction uses a single 32-bit lane from it), so the pattern
+// is a bit tricky.
+def : Pat<(v2f32 (int_aarch64_neon_bfdot
+ (v2f32 V64:$Rd), (v4bf16 V64:$Rn),
+ (v4bf16 (bitconvert
+ (v2i32 (AArch64duplane32
+ (v4i32 (bitconvert
+ (v8bf16 (insert_subvector undef,
+ (v4bf16 V64:$Rm),
+ (i64 0))))),
+ VectorIndexS:$idx)))))),
+ (BF16DOTlanev4bf16 (v2f32 V64:$Rd), (v4bf16 V64:$Rn),
+ (SUBREG_TO_REG (i32 0), V64:$Rm, dsub),
+ VectorIndexS:$idx)>;
}
// ARMv8.6A AArch64 matrix multiplication
@@ -965,7 +965,7 @@ let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
def : Pat<(v8f16 (int_aarch64_neon_vcadd_rot270 (v8f16 V128:$Rn), (v8f16 V128:$Rm))),
(FCADDv8f16 (v8f16 V128:$Rn), (v8f16 V128:$Rm), (i32 1))>;
}
-
+
let Predicates = [HasComplxNum, HasNEON] in {
def : Pat<(v2f32 (int_aarch64_neon_vcadd_rot90 (v2f32 V64:$Rn), (v2f32 V64:$Rm))),
(FCADDv2f32 (v2f32 V64:$Rn), (v2f32 V64:$Rm), (i32 0))>;
@@ -979,47 +979,47 @@ let Predicates = [HasComplxNum, HasNEON] in {
}
}
-multiclass FCMLA_PATS<ValueType ty, RegisterClass Reg> {
- def : Pat<(ty (int_aarch64_neon_vcmla_rot0 (ty Reg:$Rd), (ty Reg:$Rn), (ty Reg:$Rm))),
- (!cast<Instruction>("FCMLA" # ty) $Rd, $Rn, $Rm, 0)>;
- def : Pat<(ty (int_aarch64_neon_vcmla_rot90 (ty Reg:$Rd), (ty Reg:$Rn), (ty Reg:$Rm))),
- (!cast<Instruction>("FCMLA" # ty) $Rd, $Rn, $Rm, 1)>;
- def : Pat<(ty (int_aarch64_neon_vcmla_rot180 (ty Reg:$Rd), (ty Reg:$Rn), (ty Reg:$Rm))),
- (!cast<Instruction>("FCMLA" # ty) $Rd, $Rn, $Rm, 2)>;
- def : Pat<(ty (int_aarch64_neon_vcmla_rot270 (ty Reg:$Rd), (ty Reg:$Rn), (ty Reg:$Rm))),
- (!cast<Instruction>("FCMLA" # ty) $Rd, $Rn, $Rm, 3)>;
-}
-
-multiclass FCMLA_LANE_PATS<ValueType ty, RegisterClass Reg, dag RHSDup> {
- def : Pat<(ty (int_aarch64_neon_vcmla_rot0 (ty Reg:$Rd), (ty Reg:$Rn), RHSDup)),
- (!cast<Instruction>("FCMLA" # ty # "_indexed") $Rd, $Rn, $Rm, VectorIndexS:$idx, 0)>;
- def : Pat<(ty (int_aarch64_neon_vcmla_rot90 (ty Reg:$Rd), (ty Reg:$Rn), RHSDup)),
- (!cast<Instruction>("FCMLA" # ty # "_indexed") $Rd, $Rn, $Rm, VectorIndexS:$idx, 1)>;
- def : Pat<(ty (int_aarch64_neon_vcmla_rot180 (ty Reg:$Rd), (ty Reg:$Rn), RHSDup)),
- (!cast<Instruction>("FCMLA" # ty # "_indexed") $Rd, $Rn, $Rm, VectorIndexS:$idx, 2)>;
- def : Pat<(ty (int_aarch64_neon_vcmla_rot270 (ty Reg:$Rd), (ty Reg:$Rn), RHSDup)),
- (!cast<Instruction>("FCMLA" # ty # "_indexed") $Rd, $Rn, $Rm, VectorIndexS:$idx, 3)>;
-}
-
-
-let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
- defm : FCMLA_PATS<v4f16, V64>;
- defm : FCMLA_PATS<v8f16, V128>;
-
- defm : FCMLA_LANE_PATS<v4f16, V64,
- (v4f16 (bitconvert (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexD:$idx))))>;
- defm : FCMLA_LANE_PATS<v8f16, V128,
- (v8f16 (bitconvert (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))>;
-}
-let Predicates = [HasComplxNum, HasNEON] in {
- defm : FCMLA_PATS<v2f32, V64>;
- defm : FCMLA_PATS<v4f32, V128>;
- defm : FCMLA_PATS<v2f64, V128>;
-
- defm : FCMLA_LANE_PATS<v4f32, V128,
- (v4f32 (bitconvert (v2i64 (AArch64duplane64 (v2i64 V128:$Rm), VectorIndexD:$idx))))>;
-}
-
+multiclass FCMLA_PATS<ValueType ty, RegisterClass Reg> {
+ def : Pat<(ty (int_aarch64_neon_vcmla_rot0 (ty Reg:$Rd), (ty Reg:$Rn), (ty Reg:$Rm))),
+ (!cast<Instruction>("FCMLA" # ty) $Rd, $Rn, $Rm, 0)>;
+ def : Pat<(ty (int_aarch64_neon_vcmla_rot90 (ty Reg:$Rd), (ty Reg:$Rn), (ty Reg:$Rm))),
+ (!cast<Instruction>("FCMLA" # ty) $Rd, $Rn, $Rm, 1)>;
+ def : Pat<(ty (int_aarch64_neon_vcmla_rot180 (ty Reg:$Rd), (ty Reg:$Rn), (ty Reg:$Rm))),
+ (!cast<Instruction>("FCMLA" # ty) $Rd, $Rn, $Rm, 2)>;
+ def : Pat<(ty (int_aarch64_neon_vcmla_rot270 (ty Reg:$Rd), (ty Reg:$Rn), (ty Reg:$Rm))),
+ (!cast<Instruction>("FCMLA" # ty) $Rd, $Rn, $Rm, 3)>;
+}
+
+multiclass FCMLA_LANE_PATS<ValueType ty, RegisterClass Reg, dag RHSDup> {
+ def : Pat<(ty (int_aarch64_neon_vcmla_rot0 (ty Reg:$Rd), (ty Reg:$Rn), RHSDup)),
+ (!cast<Instruction>("FCMLA" # ty # "_indexed") $Rd, $Rn, $Rm, VectorIndexS:$idx, 0)>;
+ def : Pat<(ty (int_aarch64_neon_vcmla_rot90 (ty Reg:$Rd), (ty Reg:$Rn), RHSDup)),
+ (!cast<Instruction>("FCMLA" # ty # "_indexed") $Rd, $Rn, $Rm, VectorIndexS:$idx, 1)>;
+ def : Pat<(ty (int_aarch64_neon_vcmla_rot180 (ty Reg:$Rd), (ty Reg:$Rn), RHSDup)),
+ (!cast<Instruction>("FCMLA" # ty # "_indexed") $Rd, $Rn, $Rm, VectorIndexS:$idx, 2)>;
+ def : Pat<(ty (int_aarch64_neon_vcmla_rot270 (ty Reg:$Rd), (ty Reg:$Rn), RHSDup)),
+ (!cast<Instruction>("FCMLA" # ty # "_indexed") $Rd, $Rn, $Rm, VectorIndexS:$idx, 3)>;
+}
+
+
+let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {
+ defm : FCMLA_PATS<v4f16, V64>;
+ defm : FCMLA_PATS<v8f16, V128>;
+
+ defm : FCMLA_LANE_PATS<v4f16, V64,
+ (v4f16 (bitconvert (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexD:$idx))))>;
+ defm : FCMLA_LANE_PATS<v8f16, V128,
+ (v8f16 (bitconvert (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))>;
+}
+let Predicates = [HasComplxNum, HasNEON] in {
+ defm : FCMLA_PATS<v2f32, V64>;
+ defm : FCMLA_PATS<v4f32, V128>;
+ defm : FCMLA_PATS<v2f64, V128>;
+
+ defm : FCMLA_LANE_PATS<v4f32, V128,
+ (v4f32 (bitconvert (v2i64 (AArch64duplane64 (v2i64 V128:$Rm), VectorIndexD:$idx))))>;
+}
+
// v8.3a Pointer Authentication
// These instructions inhabit part of the hint space and so can be used for
// armv8 targets. Keeping the old HINT mnemonic when compiling without PA is
@@ -1073,7 +1073,7 @@ def : InstAlias<"autib1716", (AUTIB1716), 0>;
def : InstAlias<"xpaclri", (XPACLRI), 0>;
// These pointer authentication instructions require armv8.3a
-let Predicates = [HasPAuth] in {
+let Predicates = [HasPAuth] in {
// When PA is enabled, a better mnemonic should be emitted.
def : InstAlias<"paciaz", (PACIAZ), 1>;
@@ -1104,8 +1104,8 @@ let Predicates = [HasPAuth] in {
defm PAC : SignAuth<0b000, 0b010, "pac">;
defm AUT : SignAuth<0b001, 0b011, "aut">;
- def XPACI : ClearAuth<0, "xpaci">;
- def XPACD : ClearAuth<1, "xpacd">;
+ def XPACI : ClearAuth<0, "xpaci">;
+ def XPACD : ClearAuth<1, "xpacd">;
def PACGA : SignAuthTwoOperand<0b1100, "pacga", null_frag>;
// Combined Instructions
@@ -1140,7 +1140,7 @@ let Predicates = [HasPAuth] in {
}
// v8.3a floating point conversion for javascript
-let Predicates = [HasJS, HasFPARMv8], Defs = [NZCV] in
+let Predicates = [HasJS, HasFPARMv8], Defs = [NZCV] in
def FJCVTZS : BaseFPToIntegerUnscaled<0b01, 0b11, 0b110, FPR64, GPR32,
"fjcvtzs",
[(set GPR32:$Rd,
@@ -1149,7 +1149,7 @@ def FJCVTZS : BaseFPToIntegerUnscaled<0b01, 0b11, 0b110, FPR64, GPR32,
} // HasJS, HasFPARMv8
// v8.4 Flag manipulation instructions
-let Predicates = [HasFlagM], Defs = [NZCV], Uses = [NZCV] in {
+let Predicates = [HasFlagM], Defs = [NZCV], Uses = [NZCV] in {
def CFINV : SimpleSystemI<0, (ins), "cfinv", "">, Sched<[WriteSys]> {
let Inst{20-5} = 0b0000001000000000;
}
@@ -1157,7 +1157,7 @@ def SETF8 : BaseFlagManipulation<0, 0, (ins GPR32:$Rn), "setf8", "{\t$Rn}">;
def SETF16 : BaseFlagManipulation<0, 1, (ins GPR32:$Rn), "setf16", "{\t$Rn}">;
def RMIF : FlagRotate<(ins GPR64:$Rn, uimm6:$imm, imm0_15:$mask), "rmif",
"{\t$Rn, $imm, $mask}">;
-} // HasFlagM
+} // HasFlagM
// v8.5 flag manipulation instructions
let Predicates = [HasAltNZCV], Uses = [NZCV], Defs = [NZCV] in {
@@ -1206,12 +1206,12 @@ def HWASAN_CHECK_MEMACCESS : Pseudo<
(outs), (ins GPR64noip:$ptr, i32imm:$accessinfo),
[(int_hwasan_check_memaccess X9, GPR64noip:$ptr, (i32 timm:$accessinfo))]>,
Sched<[]>;
-}
-
-let Uses = [ X20 ], Defs = [ X16, X17, LR, NZCV ] in {
+}
+
+let Uses = [ X20 ], Defs = [ X16, X17, LR, NZCV ] in {
def HWASAN_CHECK_MEMACCESS_SHORTGRANULES : Pseudo<
(outs), (ins GPR64noip:$ptr, i32imm:$accessinfo),
- [(int_hwasan_check_memaccess_shortgranules X20, GPR64noip:$ptr, (i32 timm:$accessinfo))]>,
+ [(int_hwasan_check_memaccess_shortgranules X20, GPR64noip:$ptr, (i32 timm:$accessinfo))]>,
Sched<[]>;
}
@@ -1558,16 +1558,16 @@ def SMSUBLrrr : WideMulAccum<1, 0b001, "smsubl", sub, sext>;
def UMADDLrrr : WideMulAccum<0, 0b101, "umaddl", add, zext>;
def UMSUBLrrr : WideMulAccum<1, 0b101, "umsubl", sub, zext>;
-def : Pat<(i64 (mul (sext_inreg GPR64:$Rn, i32), (sext_inreg GPR64:$Rm, i32))),
- (SMADDLrrr (EXTRACT_SUBREG $Rn, sub_32), (EXTRACT_SUBREG $Rm, sub_32), XZR)>;
-def : Pat<(i64 (mul (sext_inreg GPR64:$Rn, i32), (sext GPR32:$Rm))),
- (SMADDLrrr (EXTRACT_SUBREG $Rn, sub_32), $Rm, XZR)>;
+def : Pat<(i64 (mul (sext_inreg GPR64:$Rn, i32), (sext_inreg GPR64:$Rm, i32))),
+ (SMADDLrrr (EXTRACT_SUBREG $Rn, sub_32), (EXTRACT_SUBREG $Rm, sub_32), XZR)>;
+def : Pat<(i64 (mul (sext_inreg GPR64:$Rn, i32), (sext GPR32:$Rm))),
+ (SMADDLrrr (EXTRACT_SUBREG $Rn, sub_32), $Rm, XZR)>;
def : Pat<(i64 (mul (sext GPR32:$Rn), (sext GPR32:$Rm))),
(SMADDLrrr GPR32:$Rn, GPR32:$Rm, XZR)>;
-def : Pat<(i64 (mul (and GPR64:$Rn, 0xFFFFFFFF), (and GPR64:$Rm, 0xFFFFFFFF))),
- (UMADDLrrr (EXTRACT_SUBREG $Rn, sub_32), (EXTRACT_SUBREG $Rm, sub_32), XZR)>;
-def : Pat<(i64 (mul (and GPR64:$Rn, 0xFFFFFFFF), (zext GPR32:$Rm))),
- (UMADDLrrr (EXTRACT_SUBREG $Rn, sub_32), $Rm, XZR)>;
+def : Pat<(i64 (mul (and GPR64:$Rn, 0xFFFFFFFF), (and GPR64:$Rm, 0xFFFFFFFF))),
+ (UMADDLrrr (EXTRACT_SUBREG $Rn, sub_32), (EXTRACT_SUBREG $Rm, sub_32), XZR)>;
+def : Pat<(i64 (mul (and GPR64:$Rn, 0xFFFFFFFF), (zext GPR32:$Rm))),
+ (UMADDLrrr (EXTRACT_SUBREG $Rn, sub_32), $Rm, XZR)>;
def : Pat<(i64 (mul (zext GPR32:$Rn), (zext GPR32:$Rm))),
(UMADDLrrr GPR32:$Rn, GPR32:$Rm, XZR)>;
@@ -2154,8 +2154,8 @@ let isCall = 1, Defs = [LR], Uses = [SP] in {
def BLRNoIP : Pseudo<(outs), (ins GPR64noip:$Rn), []>,
Sched<[WriteBrReg]>,
PseudoInstExpansion<(BLR GPR64:$Rn)>;
- def BLR_RVMARKER : Pseudo<(outs), (ins variable_ops), []>,
- Sched<[WriteBrReg]>;
+ def BLR_RVMARKER : Pseudo<(outs), (ins variable_ops), []>,
+ Sched<[WriteBrReg]>;
} // isCall
def : Pat<(AArch64call GPR64:$Rn),
@@ -2165,10 +2165,10 @@ def : Pat<(AArch64call GPR64noip:$Rn),
(BLRNoIP GPR64noip:$Rn)>,
Requires<[SLSBLRMitigation]>;
-def : Pat<(AArch64call_rvmarker GPR64:$Rn),
- (BLR_RVMARKER GPR64:$Rn)>,
- Requires<[NoSLSBLRMitigation]>;
-
+def : Pat<(AArch64call_rvmarker GPR64:$Rn),
+ (BLR_RVMARKER GPR64:$Rn)>,
+ Requires<[NoSLSBLRMitigation]>;
+
let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
def BR : BranchReg<0b0000, "br", [(brind GPR64:$Rn)]>;
} // isBranch, isTerminator, isBarrier, isIndirectBranch
@@ -3900,7 +3900,7 @@ let isTerminator = 1, hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1,
// Floating point immediate move.
//===----------------------------------------------------------------------===//
-let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
+let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
defm FMOV : FPMoveImmediate<"fmov">;
}
@@ -3909,7 +3909,7 @@ defm FMOV : FPMoveImmediate<"fmov">;
//===----------------------------------------------------------------------===//
defm UABDL : SIMDLongThreeVectorBHSabdl<1, 0b0111, "uabdl",
- AArch64uabd>;
+ AArch64uabd>;
// Match UABDL in log2-shuffle patterns.
def : Pat<(abs (v8i16 (sub (zext (v8i8 V64:$opA)),
(zext (v8i8 V64:$opB))))),
@@ -4041,7 +4041,7 @@ def : Pat<(vnot (v4i16 V64:$Rn)), (NOTv8i8 V64:$Rn)>;
def : Pat<(vnot (v8i16 V128:$Rn)), (NOTv16i8 V128:$Rn)>;
def : Pat<(vnot (v2i32 V64:$Rn)), (NOTv8i8 V64:$Rn)>;
def : Pat<(vnot (v4i32 V128:$Rn)), (NOTv16i8 V128:$Rn)>;
-def : Pat<(vnot (v1i64 V64:$Rn)), (NOTv8i8 V64:$Rn)>;
+def : Pat<(vnot (v1i64 V64:$Rn)), (NOTv8i8 V64:$Rn)>;
def : Pat<(vnot (v2i64 V128:$Rn)), (NOTv16i8 V128:$Rn)>;
defm RBIT : SIMDTwoVectorB<1, 0b01, 0b00101, "rbit", int_aarch64_neon_rbit>;
@@ -4160,9 +4160,9 @@ defm MLS : SIMDThreeSameVectorBHSTied<1, 0b10010, "mls", null_frag>;
defm MUL : SIMDThreeSameVectorBHS<0, 0b10011, "mul", mul>;
defm PMUL : SIMDThreeSameVectorB<1, 0b10011, "pmul", int_aarch64_neon_pmul>;
defm SABA : SIMDThreeSameVectorBHSTied<0, 0b01111, "saba",
- TriOpFrag<(add node:$LHS, (AArch64sabd node:$MHS, node:$RHS))> >;
-defm SABD : SIMDThreeSameVectorBHS<0,0b01110,"sabd", AArch64sabd>;
-defm SHADD : SIMDThreeSameVectorBHS<0,0b00000,"shadd", AArch64shadd>;
+ TriOpFrag<(add node:$LHS, (AArch64sabd node:$MHS, node:$RHS))> >;
+defm SABD : SIMDThreeSameVectorBHS<0,0b01110,"sabd", AArch64sabd>;
+defm SHADD : SIMDThreeSameVectorBHS<0,0b00000,"shadd", AArch64shadd>;
defm SHSUB : SIMDThreeSameVectorBHS<0,0b00100,"shsub", int_aarch64_neon_shsub>;
defm SMAXP : SIMDThreeSameVectorBHS<0,0b10100,"smaxp", int_aarch64_neon_smaxp>;
defm SMAX : SIMDThreeSameVectorBHS<0,0b01100,"smax", smax>;
@@ -4179,9 +4179,9 @@ defm SRSHL : SIMDThreeSameVector<0,0b01010,"srshl", int_aarch64_neon_srshl>;
defm SSHL : SIMDThreeSameVector<0,0b01000,"sshl", int_aarch64_neon_sshl>;
defm SUB : SIMDThreeSameVector<1,0b10000,"sub", sub>;
defm UABA : SIMDThreeSameVectorBHSTied<1, 0b01111, "uaba",
- TriOpFrag<(add node:$LHS, (AArch64uabd node:$MHS, node:$RHS))> >;
-defm UABD : SIMDThreeSameVectorBHS<1,0b01110,"uabd", AArch64uabd>;
-defm UHADD : SIMDThreeSameVectorBHS<1,0b00000,"uhadd", AArch64uhadd>;
+ TriOpFrag<(add node:$LHS, (AArch64uabd node:$MHS, node:$RHS))> >;
+defm UABD : SIMDThreeSameVectorBHS<1,0b01110,"uabd", AArch64uabd>;
+defm UHADD : SIMDThreeSameVectorBHS<1,0b00000,"uhadd", AArch64uhadd>;
defm UHSUB : SIMDThreeSameVectorBHS<1,0b00100,"uhsub", int_aarch64_neon_uhsub>;
defm UMAXP : SIMDThreeSameVectorBHS<1,0b10100,"umaxp", int_aarch64_neon_umaxp>;
defm UMAX : SIMDThreeSameVectorBHS<1,0b01100,"umax", umax>;
@@ -4579,10 +4579,10 @@ def : Pat<(v1i64 (int_aarch64_neon_fcvtps (v1f64 FPR64:$Rn))),
(FCVTPSv1i64 FPR64:$Rn)>;
def : Pat<(v1i64 (int_aarch64_neon_fcvtpu (v1f64 FPR64:$Rn))),
(FCVTPUv1i64 FPR64:$Rn)>;
-def : Pat<(v1i64 (int_aarch64_neon_fcvtzs (v1f64 FPR64:$Rn))),
- (FCVTZSv1i64 FPR64:$Rn)>;
-def : Pat<(v1i64 (int_aarch64_neon_fcvtzu (v1f64 FPR64:$Rn))),
- (FCVTZUv1i64 FPR64:$Rn)>;
+def : Pat<(v1i64 (int_aarch64_neon_fcvtzs (v1f64 FPR64:$Rn))),
+ (FCVTZSv1i64 FPR64:$Rn)>;
+def : Pat<(v1i64 (int_aarch64_neon_fcvtzu (v1f64 FPR64:$Rn))),
+ (FCVTZUv1i64 FPR64:$Rn)>;
def : Pat<(f16 (int_aarch64_neon_frecpe (f16 FPR16:$Rn))),
(FRECPEv1f16 FPR16:$Rn)>;
@@ -4754,9 +4754,9 @@ defm RADDHN : SIMDNarrowThreeVectorBHS<1,0b0100,"raddhn",int_aarch64_neon_raddhn
defm RSUBHN : SIMDNarrowThreeVectorBHS<1,0b0110,"rsubhn",int_aarch64_neon_rsubhn>;
defm PMULL : SIMDDifferentThreeVectorBD<0,0b1110,"pmull",int_aarch64_neon_pmull>;
defm SABAL : SIMDLongThreeVectorTiedBHSabal<0,0b0101,"sabal",
- AArch64sabd>;
+ AArch64sabd>;
defm SABDL : SIMDLongThreeVectorBHSabdl<0, 0b0111, "sabdl",
- AArch64sabd>;
+ AArch64sabd>;
defm SADDL : SIMDLongThreeVectorBHS< 0, 0b0000, "saddl",
BinOpFrag<(add (sext node:$LHS), (sext node:$RHS))>>;
defm SADDW : SIMDWideThreeVectorBHS< 0, 0b0001, "saddw",
@@ -4777,59 +4777,59 @@ defm SSUBL : SIMDLongThreeVectorBHS<0, 0b0010, "ssubl",
defm SSUBW : SIMDWideThreeVectorBHS<0, 0b0011, "ssubw",
BinOpFrag<(sub node:$LHS, (sext node:$RHS))>>;
defm UABAL : SIMDLongThreeVectorTiedBHSabal<1, 0b0101, "uabal",
- AArch64uabd>;
+ AArch64uabd>;
defm UADDL : SIMDLongThreeVectorBHS<1, 0b0000, "uaddl",
- BinOpFrag<(add (zanyext node:$LHS), (zanyext node:$RHS))>>;
+ BinOpFrag<(add (zanyext node:$LHS), (zanyext node:$RHS))>>;
defm UADDW : SIMDWideThreeVectorBHS<1, 0b0001, "uaddw",
- BinOpFrag<(add node:$LHS, (zanyext node:$RHS))>>;
+ BinOpFrag<(add node:$LHS, (zanyext node:$RHS))>>;
defm UMLAL : SIMDLongThreeVectorTiedBHS<1, 0b1000, "umlal",
TriOpFrag<(add node:$LHS, (int_aarch64_neon_umull node:$MHS, node:$RHS))>>;
defm UMLSL : SIMDLongThreeVectorTiedBHS<1, 0b1010, "umlsl",
TriOpFrag<(sub node:$LHS, (int_aarch64_neon_umull node:$MHS, node:$RHS))>>;
defm UMULL : SIMDLongThreeVectorBHS<1, 0b1100, "umull", int_aarch64_neon_umull>;
defm USUBL : SIMDLongThreeVectorBHS<1, 0b0010, "usubl",
- BinOpFrag<(sub (zanyext node:$LHS), (zanyext node:$RHS))>>;
+ BinOpFrag<(sub (zanyext node:$LHS), (zanyext node:$RHS))>>;
defm USUBW : SIMDWideThreeVectorBHS< 1, 0b0011, "usubw",
- BinOpFrag<(sub node:$LHS, (zanyext node:$RHS))>>;
-
-// Additional patterns for [SU]ML[AS]L
-multiclass Neon_mul_acc_widen_patterns<SDPatternOperator opnode, SDPatternOperator vecopnode,
- Instruction INST8B, Instruction INST4H, Instruction INST2S> {
- def : Pat<(v4i16 (opnode
- V64:$Ra,
- (v4i16 (extract_subvector
- (vecopnode (v8i8 V64:$Rn),(v8i8 V64:$Rm)),
- (i64 0))))),
- (EXTRACT_SUBREG (v8i16 (INST8B
- (INSERT_SUBREG (v8i16 (IMPLICIT_DEF)), V64:$Ra, dsub),
- V64:$Rn, V64:$Rm)), dsub)>;
- def : Pat<(v2i32 (opnode
- V64:$Ra,
- (v2i32 (extract_subvector
- (vecopnode (v4i16 V64:$Rn),(v4i16 V64:$Rm)),
- (i64 0))))),
- (EXTRACT_SUBREG (v4i32 (INST4H
- (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), V64:$Ra, dsub),
- V64:$Rn, V64:$Rm)), dsub)>;
- def : Pat<(v1i64 (opnode
- V64:$Ra,
- (v1i64 (extract_subvector
- (vecopnode (v2i32 V64:$Rn),(v2i32 V64:$Rm)),
- (i64 0))))),
- (EXTRACT_SUBREG (v2i64 (INST2S
- (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)), V64:$Ra, dsub),
- V64:$Rn, V64:$Rm)), dsub)>;
-}
-
-defm : Neon_mul_acc_widen_patterns<add, int_aarch64_neon_umull,
- UMLALv8i8_v8i16, UMLALv4i16_v4i32, UMLALv2i32_v2i64>;
-defm : Neon_mul_acc_widen_patterns<add, int_aarch64_neon_smull,
- SMLALv8i8_v8i16, SMLALv4i16_v4i32, SMLALv2i32_v2i64>;
-defm : Neon_mul_acc_widen_patterns<sub, int_aarch64_neon_umull,
- UMLSLv8i8_v8i16, UMLSLv4i16_v4i32, UMLSLv2i32_v2i64>;
-defm : Neon_mul_acc_widen_patterns<sub, int_aarch64_neon_smull,
- SMLSLv8i8_v8i16, SMLSLv4i16_v4i32, SMLSLv2i32_v2i64>;
-
+ BinOpFrag<(sub node:$LHS, (zanyext node:$RHS))>>;
+
+// Additional patterns for [SU]ML[AS]L
+multiclass Neon_mul_acc_widen_patterns<SDPatternOperator opnode, SDPatternOperator vecopnode,
+ Instruction INST8B, Instruction INST4H, Instruction INST2S> {
+ def : Pat<(v4i16 (opnode
+ V64:$Ra,
+ (v4i16 (extract_subvector
+ (vecopnode (v8i8 V64:$Rn),(v8i8 V64:$Rm)),
+ (i64 0))))),
+ (EXTRACT_SUBREG (v8i16 (INST8B
+ (INSERT_SUBREG (v8i16 (IMPLICIT_DEF)), V64:$Ra, dsub),
+ V64:$Rn, V64:$Rm)), dsub)>;
+ def : Pat<(v2i32 (opnode
+ V64:$Ra,
+ (v2i32 (extract_subvector
+ (vecopnode (v4i16 V64:$Rn),(v4i16 V64:$Rm)),
+ (i64 0))))),
+ (EXTRACT_SUBREG (v4i32 (INST4H
+ (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), V64:$Ra, dsub),
+ V64:$Rn, V64:$Rm)), dsub)>;
+ def : Pat<(v1i64 (opnode
+ V64:$Ra,
+ (v1i64 (extract_subvector
+ (vecopnode (v2i32 V64:$Rn),(v2i32 V64:$Rm)),
+ (i64 0))))),
+ (EXTRACT_SUBREG (v2i64 (INST2S
+ (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)), V64:$Ra, dsub),
+ V64:$Rn, V64:$Rm)), dsub)>;
+}
+
+defm : Neon_mul_acc_widen_patterns<add, int_aarch64_neon_umull,
+ UMLALv8i8_v8i16, UMLALv4i16_v4i32, UMLALv2i32_v2i64>;
+defm : Neon_mul_acc_widen_patterns<add, int_aarch64_neon_smull,
+ SMLALv8i8_v8i16, SMLALv4i16_v4i32, SMLALv2i32_v2i64>;
+defm : Neon_mul_acc_widen_patterns<sub, int_aarch64_neon_umull,
+ UMLSLv8i8_v8i16, UMLSLv4i16_v4i32, UMLSLv2i32_v2i64>;
+defm : Neon_mul_acc_widen_patterns<sub, int_aarch64_neon_smull,
+ SMLSLv8i8_v8i16, SMLSLv4i16_v4i32, SMLSLv2i32_v2i64>;
+
// Additional patterns for SMULL and UMULL
multiclass Neon_mul_widen_patterns<SDPatternOperator opnode,
Instruction INST8B, Instruction INST4H, Instruction INST2S> {
@@ -5041,26 +5041,26 @@ defm FMAXNMP : SIMDFPPairwiseScalar<0, 0b01100, "fmaxnmp">;
defm FMAXP : SIMDFPPairwiseScalar<0, 0b01111, "fmaxp">;
defm FMINNMP : SIMDFPPairwiseScalar<1, 0b01100, "fminnmp">;
defm FMINP : SIMDFPPairwiseScalar<1, 0b01111, "fminp">;
-
-let Predicates = [HasFullFP16] in {
-def : Pat<(f16 (vecreduce_fadd (v8f16 V128:$Rn))),
- (FADDPv2i16p
- (EXTRACT_SUBREG
- (FADDPv8f16 (FADDPv8f16 V128:$Rn, (v8f16 (IMPLICIT_DEF))), (v8f16 (IMPLICIT_DEF))),
- dsub))>;
-def : Pat<(f16 (vecreduce_fadd (v4f16 V64:$Rn))),
- (FADDPv2i16p (FADDPv4f16 V64:$Rn, (v4f16 (IMPLICIT_DEF))))>;
-}
-def : Pat<(f32 (vecreduce_fadd (v4f32 V128:$Rn))),
- (FADDPv2i32p
- (EXTRACT_SUBREG
- (FADDPv4f32 V128:$Rn, (v4f32 (IMPLICIT_DEF))),
- dsub))>;
-def : Pat<(f32 (vecreduce_fadd (v2f32 V64:$Rn))),
- (FADDPv2i32p V64:$Rn)>;
-def : Pat<(f64 (vecreduce_fadd (v2f64 V128:$Rn))),
- (FADDPv2i64p V128:$Rn)>;
-
+
+let Predicates = [HasFullFP16] in {
+def : Pat<(f16 (vecreduce_fadd (v8f16 V128:$Rn))),
+ (FADDPv2i16p
+ (EXTRACT_SUBREG
+ (FADDPv8f16 (FADDPv8f16 V128:$Rn, (v8f16 (IMPLICIT_DEF))), (v8f16 (IMPLICIT_DEF))),
+ dsub))>;
+def : Pat<(f16 (vecreduce_fadd (v4f16 V64:$Rn))),
+ (FADDPv2i16p (FADDPv4f16 V64:$Rn, (v4f16 (IMPLICIT_DEF))))>;
+}
+def : Pat<(f32 (vecreduce_fadd (v4f32 V128:$Rn))),
+ (FADDPv2i32p
+ (EXTRACT_SUBREG
+ (FADDPv4f32 V128:$Rn, (v4f32 (IMPLICIT_DEF))),
+ dsub))>;
+def : Pat<(f32 (vecreduce_fadd (v2f32 V64:$Rn))),
+ (FADDPv2i32p V64:$Rn)>;
+def : Pat<(f64 (vecreduce_fadd (v2f64 V128:$Rn))),
+ (FADDPv2i64p V128:$Rn)>;
+
def : Pat<(v2i64 (AArch64saddv V128:$Rn)),
(INSERT_SUBREG (v2i64 (IMPLICIT_DEF)), (ADDPv2i64p V128:$Rn), dsub)>;
def : Pat<(v2i64 (AArch64uaddv V128:$Rn)),
@@ -5312,16 +5312,16 @@ def : Pat<(v4f16 (vector_insert (v4f16 V64:$Rn),
(i64 0)),
dsub)>;
-def : Pat<(vector_insert (v8f16 v8f16:$Rn), (f16 fpimm0),
- (i64 VectorIndexH:$imm)),
- (INSvi16gpr V128:$Rn, VectorIndexH:$imm, WZR)>;
-def : Pat<(vector_insert v4f32:$Rn, (f32 fpimm0),
- (i64 VectorIndexS:$imm)),
- (INSvi32gpr V128:$Rn, VectorIndexS:$imm, WZR)>;
-def : Pat<(vector_insert v2f64:$Rn, (f64 fpimm0),
- (i64 VectorIndexD:$imm)),
- (INSvi64gpr V128:$Rn, VectorIndexS:$imm, XZR)>;
-
+def : Pat<(vector_insert (v8f16 v8f16:$Rn), (f16 fpimm0),
+ (i64 VectorIndexH:$imm)),
+ (INSvi16gpr V128:$Rn, VectorIndexH:$imm, WZR)>;
+def : Pat<(vector_insert v4f32:$Rn, (f32 fpimm0),
+ (i64 VectorIndexS:$imm)),
+ (INSvi32gpr V128:$Rn, VectorIndexS:$imm, WZR)>;
+def : Pat<(vector_insert v2f64:$Rn, (f64 fpimm0),
+ (i64 VectorIndexD:$imm)),
+ (INSvi64gpr V128:$Rn, VectorIndexS:$imm, XZR)>;
+
def : Pat<(v8f16 (vector_insert (v8f16 V128:$Rn),
(f16 FPR16:$Rm), (i64 VectorIndexH:$imm))),
(INSvi16lane
@@ -6833,18 +6833,18 @@ def : Pat<(i32 (trunc GPR64sp:$src)),
// __builtin_trap() uses the BRK instruction on AArch64.
def : Pat<(trap), (BRK 1)>;
-def : Pat<(debugtrap), (BRK 0xF000)>;
-
-def ubsan_trap_xform : SDNodeXForm<timm, [{
- return CurDAG->getTargetConstant(N->getZExtValue() | ('U' << 8), SDLoc(N), MVT::i32);
-}]>;
-
-def ubsan_trap_imm : TImmLeaf<i32, [{
- return isUInt<8>(Imm);
-}], ubsan_trap_xform>;
-
-def : Pat<(ubsantrap ubsan_trap_imm:$kind), (BRK ubsan_trap_imm:$kind)>;
-
+def : Pat<(debugtrap), (BRK 0xF000)>;
+
+def ubsan_trap_xform : SDNodeXForm<timm, [{
+ return CurDAG->getTargetConstant(N->getZExtValue() | ('U' << 8), SDLoc(N), MVT::i32);
+}]>;
+
+def ubsan_trap_imm : TImmLeaf<i32, [{
+ return isUInt<8>(Imm);
+}], ubsan_trap_xform>;
+
+def : Pat<(ubsantrap ubsan_trap_imm:$kind), (BRK ubsan_trap_imm:$kind)>;
+
// Multiply high patterns which multiply the lower subvector using smull/umull
// and the upper subvector with smull2/umull2. Then shuffle the high the high
// part of both results together.
@@ -7639,9 +7639,9 @@ def : Pat<(f64 (fadd (vector_extract (v2f64 FPR128:$Rn), (i64 0)),
def : Pat<(fadd (vector_extract (v4f32 FPR128:$Rn), (i64 0)),
(vector_extract (v4f32 FPR128:$Rn), (i64 1))),
(f32 (FADDPv2i32p (EXTRACT_SUBREG FPR128:$Rn, dsub)))>;
-def : Pat<(fadd (vector_extract (v8f16 FPR128:$Rn), (i64 0)),
- (vector_extract (v8f16 FPR128:$Rn), (i64 1))),
- (f16 (FADDPv2i16p (EXTRACT_SUBREG FPR128:$Rn, dsub)))>;
+def : Pat<(fadd (vector_extract (v8f16 FPR128:$Rn), (i64 0)),
+ (vector_extract (v8f16 FPR128:$Rn), (i64 1))),
+ (f16 (FADDPv2i16p (EXTRACT_SUBREG FPR128:$Rn, dsub)))>;
// Scalar 64-bit shifts in FPR64 registers.
def : Pat<(i64 (int_aarch64_neon_sshl (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
@@ -7844,23 +7844,23 @@ let AddedComplexity = 10 in {
// FIXME: add SVE dot-product patterns.
}
-let Predicates = [HasLS64] in {
- def LD64B: LoadStore64B<0b101, "ld64b", (ins GPR64sp:$Rn),
- (outs GPR64x8:$Rt)>;
- def ST64B: LoadStore64B<0b001, "st64b", (ins GPR64x8:$Rt, GPR64sp:$Rn),
- (outs)>;
- def ST64BV: Store64BV<0b011, "st64bv">;
- def ST64BV0: Store64BV<0b010, "st64bv0">;
-
- class ST64BPattern<Intrinsic intrinsic, Instruction instruction>
- : Pat<(intrinsic GPR64sp:$addr, GPR64:$x0, GPR64:$x1, GPR64:$x2, GPR64:$x3, GPR64:$x4, GPR64:$x5, GPR64:$x6, GPR64:$x7),
- (instruction (REG_SEQUENCE GPR64x8Class, $x0, x8sub_0, $x1, x8sub_1, $x2, x8sub_2, $x3, x8sub_3, $x4, x8sub_4, $x5, x8sub_5, $x6, x8sub_6, $x7, x8sub_7), $addr)>;
-
- def : ST64BPattern<int_aarch64_st64b, ST64B>;
- def : ST64BPattern<int_aarch64_st64bv, ST64BV>;
- def : ST64BPattern<int_aarch64_st64bv0, ST64BV0>;
-}
-
+let Predicates = [HasLS64] in {
+ def LD64B: LoadStore64B<0b101, "ld64b", (ins GPR64sp:$Rn),
+ (outs GPR64x8:$Rt)>;
+ def ST64B: LoadStore64B<0b001, "st64b", (ins GPR64x8:$Rt, GPR64sp:$Rn),
+ (outs)>;
+ def ST64BV: Store64BV<0b011, "st64bv">;
+ def ST64BV0: Store64BV<0b010, "st64bv0">;
+
+ class ST64BPattern<Intrinsic intrinsic, Instruction instruction>
+ : Pat<(intrinsic GPR64sp:$addr, GPR64:$x0, GPR64:$x1, GPR64:$x2, GPR64:$x3, GPR64:$x4, GPR64:$x5, GPR64:$x6, GPR64:$x7),
+ (instruction (REG_SEQUENCE GPR64x8Class, $x0, x8sub_0, $x1, x8sub_1, $x2, x8sub_2, $x3, x8sub_3, $x4, x8sub_4, $x5, x8sub_5, $x6, x8sub_6, $x7, x8sub_7), $addr)>;
+
+ def : ST64BPattern<int_aarch64_st64b, ST64B>;
+ def : ST64BPattern<int_aarch64_st64bv, ST64BV>;
+ def : ST64BPattern<int_aarch64_st64bv0, ST64BV0>;
+}
+
include "AArch64InstrAtomics.td"
include "AArch64SVEInstrInfo.td"
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
index f87385ccd4..ad180cb293 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
@@ -1186,10 +1186,10 @@ bool AArch64LoadStoreOpt::findMatchingStore(
// store instruction writes and the stored value is not modified, we can
// promote the load. Since we do not handle stores with pre-/post-index,
// it's unnecessary to check if BaseReg is modified by the store itself.
- // Also we can't handle stores without an immediate offset operand,
- // while the operand might be the address for a global variable.
+ // Also we can't handle stores without an immediate offset operand,
+ // while the operand might be the address for a global variable.
if (MI.mayStore() && isMatchingStore(LoadMI, MI) &&
- BaseReg == getLdStBaseOp(MI).getReg() && getLdStOffsetOp(MI).isImm() &&
+ BaseReg == getLdStBaseOp(MI).getReg() && getLdStOffsetOp(MI).isImm() &&
isLdOffsetInRangeOfSt(LoadMI, MI, TII) &&
ModifiedRegUnits.available(getLdStRegOp(MI).getReg())) {
StoreI = MBBI;
@@ -1552,27 +1552,27 @@ AArch64LoadStoreOpt::findMatchingInsn(MachineBasicBlock::iterator I,
continue;
}
}
- // If the destination register of one load is the same register or a
- // sub/super register of the other load, bail and keep looking. A
- // load-pair instruction with both destination registers the same is
- // UNPREDICTABLE and will result in an exception.
- if (MayLoad &&
- TRI->isSuperOrSubRegisterEq(Reg, getLdStRegOp(MI).getReg())) {
+ // If the destination register of one load is the same register or a
+ // sub/super register of the other load, bail and keep looking. A
+ // load-pair instruction with both destination registers the same is
+ // UNPREDICTABLE and will result in an exception.
+ if (MayLoad &&
+ TRI->isSuperOrSubRegisterEq(Reg, getLdStRegOp(MI).getReg())) {
LiveRegUnits::accumulateUsedDefed(MI, ModifiedRegUnits, UsedRegUnits,
TRI);
MemInsns.push_back(&MI);
continue;
}
- // If the BaseReg has been modified, then we cannot do the optimization.
- // For example, in the following pattern
- // ldr x1 [x2]
- // ldr x2 [x3]
- // ldr x4 [x2, #8],
- // the first and third ldr cannot be converted to ldp x1, x4, [x2]
- if (!ModifiedRegUnits.available(BaseReg))
- return E;
-
+ // If the BaseReg has been modified, then we cannot do the optimization.
+ // For example, in the following pattern
+ // ldr x1 [x2]
+ // ldr x2 [x3]
+ // ldr x4 [x2, #8],
+ // the first and third ldr cannot be converted to ldp x1, x4, [x2]
+ if (!ModifiedRegUnits.available(BaseReg))
+ return E;
+
// If the Rt of the second instruction was not modified or used between
// the two instructions and none of the instructions between the second
// and first alias with the second, we can combine the second into the
@@ -1763,11 +1763,11 @@ bool AArch64LoadStoreOpt::isMatchingUpdateInsn(MachineInstr &MemMI,
return false;
}
-static bool needsWinCFI(const MachineFunction *MF) {
- return MF->getTarget().getMCAsmInfo()->usesWindowsCFI() &&
- MF->getFunction().needsUnwindTableEntry();
-}
-
+static bool needsWinCFI(const MachineFunction *MF) {
+ return MF->getTarget().getMCAsmInfo()->usesWindowsCFI() &&
+ MF->getFunction().needsUnwindTableEntry();
+}
+
MachineBasicBlock::iterator AArch64LoadStoreOpt::findMatchingUpdateInsnForward(
MachineBasicBlock::iterator I, int UnscaledOffset, unsigned Limit) {
MachineBasicBlock::iterator E = I->getParent()->end();
@@ -1808,11 +1808,11 @@ MachineBasicBlock::iterator AArch64LoadStoreOpt::findMatchingUpdateInsnForward(
// the memory access (I) and the increment (MBBI) can access the memory
// region defined by [SP, MBBI].
const bool BaseRegSP = BaseReg == AArch64::SP;
- if (BaseRegSP && needsWinCFI(I->getMF())) {
+ if (BaseRegSP && needsWinCFI(I->getMF())) {
// FIXME: For now, we always block the optimization over SP in windows
// targets as it requires to adjust the unwind/debug info, messing up
// the unwind info can actually cause a miscompile.
- return E;
+ return E;
}
for (unsigned Count = 0; MBBI != E && Count < Limit;
@@ -1868,14 +1868,14 @@ MachineBasicBlock::iterator AArch64LoadStoreOpt::findMatchingUpdateInsnBackward(
}
}
- const bool BaseRegSP = BaseReg == AArch64::SP;
- if (BaseRegSP && needsWinCFI(I->getMF())) {
- // FIXME: For now, we always block the optimization over SP in windows
- // targets as it requires to adjust the unwind/debug info, messing up
- // the unwind info can actually cause a miscompile.
- return E;
- }
-
+ const bool BaseRegSP = BaseReg == AArch64::SP;
+ if (BaseRegSP && needsWinCFI(I->getMF())) {
+ // FIXME: For now, we always block the optimization over SP in windows
+ // targets as it requires to adjust the unwind/debug info, messing up
+ // the unwind info can actually cause a miscompile.
+ return E;
+ }
+
// Track which register units have been modified and used between the first
// insn (inclusive) and the second insn.
ModifiedRegUnits.clear();
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64MCInstLower.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64MCInstLower.cpp
index c923f53281..10e191ff44 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64MCInstLower.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64MCInstLower.cpp
@@ -203,12 +203,12 @@ MCOperand AArch64MCInstLower::lowerSymbolOperandCOFF(const MachineOperand &MO,
RefFlags |= AArch64MCExpr::VK_SABS;
} else {
RefFlags |= AArch64MCExpr::VK_ABS;
-
- if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
- RefFlags |= AArch64MCExpr::VK_PAGE;
- else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
- AArch64II::MO_PAGEOFF)
- RefFlags |= AArch64MCExpr::VK_PAGEOFF | AArch64MCExpr::VK_NC;
+
+ if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
+ RefFlags |= AArch64MCExpr::VK_PAGE;
+ else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
+ AArch64II::MO_PAGEOFF)
+ RefFlags |= AArch64MCExpr::VK_PAGEOFF | AArch64MCExpr::VK_NC;
}
if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G3)
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
index ebb501b779..41343ba970 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
@@ -14,9 +14,9 @@
//===----------------------------------------------------------------------===//
#include "AArch64MachineFunctionInfo.h"
-#include "AArch64InstrInfo.h"
-#include <llvm/IR/Metadata.h>
-#include <llvm/IR/Module.h>
+#include "AArch64InstrInfo.h"
+#include <llvm/IR/Metadata.h>
+#include <llvm/IR/Module.h>
using namespace llvm;
@@ -33,82 +33,82 @@ void AArch64FunctionInfo::initializeBaseYamlFields(
if (YamlMFI.HasRedZone.hasValue())
HasRedZone = YamlMFI.HasRedZone;
}
-
-static std::pair<bool, bool> GetSignReturnAddress(const Function &F) {
- // The function should be signed in the following situations:
- // - sign-return-address=all
- // - sign-return-address=non-leaf and the functions spills the LR
- if (!F.hasFnAttribute("sign-return-address")) {
- const Module &M = *F.getParent();
- if (const auto *Sign = mdconst::extract_or_null<ConstantInt>(
- M.getModuleFlag("sign-return-address"))) {
- if (Sign->getZExtValue()) {
- if (const auto *All = mdconst::extract_or_null<ConstantInt>(
- M.getModuleFlag("sign-return-address-all")))
- return {true, All->getZExtValue()};
- return {true, false};
- }
- }
- return {false, false};
- }
-
- StringRef Scope = F.getFnAttribute("sign-return-address").getValueAsString();
- if (Scope.equals("none"))
- return {false, false};
-
- if (Scope.equals("all"))
- return {true, true};
-
- assert(Scope.equals("non-leaf"));
- return {true, false};
-}
-
-static bool ShouldSignWithBKey(const Function &F) {
- if (!F.hasFnAttribute("sign-return-address-key")) {
- if (const auto *BKey = mdconst::extract_or_null<ConstantInt>(
- F.getParent()->getModuleFlag("sign-return-address-with-bkey")))
- return BKey->getZExtValue();
- return false;
- }
-
- const StringRef Key =
- F.getFnAttribute("sign-return-address-key").getValueAsString();
- assert(Key.equals_lower("a_key") || Key.equals_lower("b_key"));
- return Key.equals_lower("b_key");
-}
-
-AArch64FunctionInfo::AArch64FunctionInfo(MachineFunction &MF) : MF(MF) {
- // If we already know that the function doesn't have a redzone, set
- // HasRedZone here.
- if (MF.getFunction().hasFnAttribute(Attribute::NoRedZone))
- HasRedZone = false;
-
- const Function &F = MF.getFunction();
- std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F);
- SignWithBKey = ShouldSignWithBKey(F);
-
- if (!F.hasFnAttribute("branch-target-enforcement")) {
- if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
- F.getParent()->getModuleFlag("branch-target-enforcement")))
- BranchTargetEnforcement = BTE->getZExtValue();
- return;
- }
-
- const StringRef BTIEnable = F.getFnAttribute("branch-target-enforcement").getValueAsString();
- assert(BTIEnable.equals_lower("true") || BTIEnable.equals_lower("false"));
- BranchTargetEnforcement = BTIEnable.equals_lower("true");
-}
-
-bool AArch64FunctionInfo::shouldSignReturnAddress(bool SpillsLR) const {
- if (!SignReturnAddress)
- return false;
- if (SignReturnAddressAll)
- return true;
- return SpillsLR;
-}
-
-bool AArch64FunctionInfo::shouldSignReturnAddress() const {
- return shouldSignReturnAddress(llvm::any_of(
- MF.getFrameInfo().getCalleeSavedInfo(),
- [](const auto &Info) { return Info.getReg() == AArch64::LR; }));
-}
+
+static std::pair<bool, bool> GetSignReturnAddress(const Function &F) {
+ // The function should be signed in the following situations:
+ // - sign-return-address=all
+ // - sign-return-address=non-leaf and the functions spills the LR
+ if (!F.hasFnAttribute("sign-return-address")) {
+ const Module &M = *F.getParent();
+ if (const auto *Sign = mdconst::extract_or_null<ConstantInt>(
+ M.getModuleFlag("sign-return-address"))) {
+ if (Sign->getZExtValue()) {
+ if (const auto *All = mdconst::extract_or_null<ConstantInt>(
+ M.getModuleFlag("sign-return-address-all")))
+ return {true, All->getZExtValue()};
+ return {true, false};
+ }
+ }
+ return {false, false};
+ }
+
+ StringRef Scope = F.getFnAttribute("sign-return-address").getValueAsString();
+ if (Scope.equals("none"))
+ return {false, false};
+
+ if (Scope.equals("all"))
+ return {true, true};
+
+ assert(Scope.equals("non-leaf"));
+ return {true, false};
+}
+
+static bool ShouldSignWithBKey(const Function &F) {
+ if (!F.hasFnAttribute("sign-return-address-key")) {
+ if (const auto *BKey = mdconst::extract_or_null<ConstantInt>(
+ F.getParent()->getModuleFlag("sign-return-address-with-bkey")))
+ return BKey->getZExtValue();
+ return false;
+ }
+
+ const StringRef Key =
+ F.getFnAttribute("sign-return-address-key").getValueAsString();
+ assert(Key.equals_lower("a_key") || Key.equals_lower("b_key"));
+ return Key.equals_lower("b_key");
+}
+
+AArch64FunctionInfo::AArch64FunctionInfo(MachineFunction &MF) : MF(MF) {
+ // If we already know that the function doesn't have a redzone, set
+ // HasRedZone here.
+ if (MF.getFunction().hasFnAttribute(Attribute::NoRedZone))
+ HasRedZone = false;
+
+ const Function &F = MF.getFunction();
+ std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F);
+ SignWithBKey = ShouldSignWithBKey(F);
+
+ if (!F.hasFnAttribute("branch-target-enforcement")) {
+ if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
+ F.getParent()->getModuleFlag("branch-target-enforcement")))
+ BranchTargetEnforcement = BTE->getZExtValue();
+ return;
+ }
+
+ const StringRef BTIEnable = F.getFnAttribute("branch-target-enforcement").getValueAsString();
+ assert(BTIEnable.equals_lower("true") || BTIEnable.equals_lower("false"));
+ BranchTargetEnforcement = BTIEnable.equals_lower("true");
+}
+
+bool AArch64FunctionInfo::shouldSignReturnAddress(bool SpillsLR) const {
+ if (!SignReturnAddress)
+ return false;
+ if (SignReturnAddressAll)
+ return true;
+ return SpillsLR;
+}
+
+bool AArch64FunctionInfo::shouldSignReturnAddress() const {
+ return shouldSignReturnAddress(llvm::any_of(
+ MF.getFrameInfo().getCalleeSavedInfo(),
+ [](const auto &Info) { return Info.getReg() == AArch64::LR; }));
+}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64MachineFunctionInfo.h b/contrib/libs/llvm12/lib/Target/AArch64/AArch64MachineFunctionInfo.h
index b3f35a46c7..f60e2b6c31 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64MachineFunctionInfo.h
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64MachineFunctionInfo.h
@@ -35,9 +35,9 @@ class MachineInstr;
/// AArch64FunctionInfo - This class is derived from MachineFunctionInfo and
/// contains private AArch64-specific information for each MachineFunction.
class AArch64FunctionInfo final : public MachineFunctionInfo {
- /// Backreference to the machine function.
- MachineFunction &MF;
-
+ /// Backreference to the machine function.
+ MachineFunction &MF;
+
/// Number of bytes of arguments this function has on the stack. If the callee
/// is expected to restore the argument stack this should be a multiple of 16,
/// all usable during a tail call.
@@ -128,39 +128,39 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
/// that must be forwarded to every musttail call.
SmallVector<ForwardedRegister, 1> ForwardedMustTailRegParms;
- /// FrameIndex for the tagged base pointer.
- Optional<int> TaggedBasePointerIndex;
+ /// FrameIndex for the tagged base pointer.
+ Optional<int> TaggedBasePointerIndex;
+
+ /// Offset from SP-at-entry to the tagged base pointer.
+ /// Tagged base pointer is set up to point to the first (lowest address)
+ /// tagged stack slot.
+ unsigned TaggedBasePointerOffset;
- /// Offset from SP-at-entry to the tagged base pointer.
- /// Tagged base pointer is set up to point to the first (lowest address)
- /// tagged stack slot.
- unsigned TaggedBasePointerOffset;
-
/// OutliningStyle denotes, if a function was outined, how it was outlined,
/// e.g. Tail Call, Thunk, or Function if none apply.
Optional<std::string> OutliningStyle;
- // Offset from SP-after-callee-saved-spills (i.e. SP-at-entry minus
- // CalleeSavedStackSize) to the address of the frame record.
- int CalleeSaveBaseToFrameRecordOffset = 0;
-
- /// SignReturnAddress is true if PAC-RET is enabled for the function with
- /// defaults being sign non-leaf functions only, with the B key.
- bool SignReturnAddress = false;
-
- /// SignReturnAddressAll modifies the default PAC-RET mode to signing leaf
- /// functions as well.
- bool SignReturnAddressAll = false;
-
- /// SignWithBKey modifies the default PAC-RET mode to signing with the B key.
- bool SignWithBKey = false;
-
- /// BranchTargetEnforcement enables placing BTI instructions at potential
- /// indirect branch destinations.
- bool BranchTargetEnforcement = false;
-
+ // Offset from SP-after-callee-saved-spills (i.e. SP-at-entry minus
+ // CalleeSavedStackSize) to the address of the frame record.
+ int CalleeSaveBaseToFrameRecordOffset = 0;
+
+ /// SignReturnAddress is true if PAC-RET is enabled for the function with
+ /// defaults being sign non-leaf functions only, with the B key.
+ bool SignReturnAddress = false;
+
+ /// SignReturnAddressAll modifies the default PAC-RET mode to signing leaf
+ /// functions as well.
+ bool SignReturnAddressAll = false;
+
+ /// SignWithBKey modifies the default PAC-RET mode to signing with the B key.
+ bool SignWithBKey = false;
+
+ /// BranchTargetEnforcement enables placing BTI instructions at potential
+ /// indirect branch destinations.
+ bool BranchTargetEnforcement = false;
+
public:
- explicit AArch64FunctionInfo(MachineFunction &MF);
+ explicit AArch64FunctionInfo(MachineFunction &MF);
void initializeBaseYamlFields(const yaml::AArch64FunctionInfo &YamlMFI);
@@ -297,14 +297,14 @@ public:
void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
unsigned getJumpTableEntrySize(int Idx) const {
- return JumpTableEntryInfo[Idx].first;
+ return JumpTableEntryInfo[Idx].first;
}
MCSymbol *getJumpTableEntryPCRelSymbol(int Idx) const {
- return JumpTableEntryInfo[Idx].second;
+ return JumpTableEntryInfo[Idx].second;
}
void setJumpTableEntryInfo(int Idx, unsigned Size, MCSymbol *PCRelSym) {
- if ((unsigned)Idx >= JumpTableEntryInfo.size())
- JumpTableEntryInfo.resize(Idx+1);
+ if ((unsigned)Idx >= JumpTableEntryInfo.size())
+ JumpTableEntryInfo.resize(Idx+1);
JumpTableEntryInfo[Idx] = std::make_pair(Size, PCRelSym);
}
@@ -346,11 +346,11 @@ public:
return ForwardedMustTailRegParms;
}
- Optional<int> getTaggedBasePointerIndex() const {
- return TaggedBasePointerIndex;
- }
- void setTaggedBasePointerIndex(int Index) { TaggedBasePointerIndex = Index; }
-
+ Optional<int> getTaggedBasePointerIndex() const {
+ return TaggedBasePointerIndex;
+ }
+ void setTaggedBasePointerIndex(int Index) { TaggedBasePointerIndex = Index; }
+
unsigned getTaggedBasePointerOffset() const {
return TaggedBasePointerOffset;
}
@@ -358,26 +358,26 @@ public:
TaggedBasePointerOffset = Offset;
}
- int getCalleeSaveBaseToFrameRecordOffset() const {
- return CalleeSaveBaseToFrameRecordOffset;
- }
- void setCalleeSaveBaseToFrameRecordOffset(int Offset) {
- CalleeSaveBaseToFrameRecordOffset = Offset;
- }
-
- bool shouldSignReturnAddress() const;
- bool shouldSignReturnAddress(bool SpillsLR) const;
-
- bool shouldSignWithBKey() const { return SignWithBKey; }
-
- bool branchTargetEnforcement() const { return BranchTargetEnforcement; }
-
+ int getCalleeSaveBaseToFrameRecordOffset() const {
+ return CalleeSaveBaseToFrameRecordOffset;
+ }
+ void setCalleeSaveBaseToFrameRecordOffset(int Offset) {
+ CalleeSaveBaseToFrameRecordOffset = Offset;
+ }
+
+ bool shouldSignReturnAddress() const;
+ bool shouldSignReturnAddress(bool SpillsLR) const;
+
+ bool shouldSignWithBKey() const { return SignWithBKey; }
+
+ bool branchTargetEnforcement() const { return BranchTargetEnforcement; }
+
private:
// Hold the lists of LOHs.
MILOHContainer LOHContainerSet;
SetOfInstructions LOHRelated;
- SmallVector<std::pair<unsigned, MCSymbol *>, 2> JumpTableEntryInfo;
+ SmallVector<std::pair<unsigned, MCSymbol *>, 2> JumpTableEntryInfo;
};
namespace yaml {
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64MacroFusion.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64MacroFusion.cpp
index 0e9cb143f2..f3b8ef16d6 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64MacroFusion.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64MacroFusion.cpp
@@ -21,7 +21,7 @@ namespace {
/// CMN, CMP, TST followed by Bcc
static bool isArithmeticBccPair(const MachineInstr *FirstMI,
- const MachineInstr &SecondMI, bool CmpOnly) {
+ const MachineInstr &SecondMI, bool CmpOnly) {
if (SecondMI.getOpcode() != AArch64::Bcc)
return false;
@@ -29,13 +29,13 @@ static bool isArithmeticBccPair(const MachineInstr *FirstMI,
if (FirstMI == nullptr)
return true;
- // If we're in CmpOnly mode, we only fuse arithmetic instructions that
- // discard their result.
- if (CmpOnly && !(FirstMI->getOperand(0).getReg() == AArch64::XZR ||
- FirstMI->getOperand(0).getReg() == AArch64::WZR)) {
- return false;
- }
-
+ // If we're in CmpOnly mode, we only fuse arithmetic instructions that
+ // discard their result.
+ if (CmpOnly && !(FirstMI->getOperand(0).getReg() == AArch64::XZR ||
+ FirstMI->getOperand(0).getReg() == AArch64::WZR)) {
+ return false;
+ }
+
switch (FirstMI->getOpcode()) {
case AArch64::ADDSWri:
case AArch64::ADDSWrr:
@@ -387,11 +387,11 @@ static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
// All checking functions assume that the 1st instr is a wildcard if it is
// unspecified.
- if (ST.hasCmpBccFusion() || ST.hasArithmeticBccFusion()) {
- bool CmpOnly = !ST.hasArithmeticBccFusion();
- if (isArithmeticBccPair(FirstMI, SecondMI, CmpOnly))
- return true;
- }
+ if (ST.hasCmpBccFusion() || ST.hasArithmeticBccFusion()) {
+ bool CmpOnly = !ST.hasArithmeticBccFusion();
+ if (isArithmeticBccPair(FirstMI, SecondMI, CmpOnly))
+ return true;
+ }
if (ST.hasArithmeticCbzFusion() && isArithmeticCbzPair(FirstMI, SecondMI))
return true;
if (ST.hasFuseAES() && isAESPair(FirstMI, SecondMI))
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp
index 82b610f995..019220e3a5 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp
@@ -408,11 +408,11 @@ bool AArch64RedundantCopyElimination::optimizeBlock(MachineBasicBlock *MBB) {
O.getReg() != CmpReg;
}))
continue;
-
- // Don't remove a move immediate that implicitly defines the upper
- // bits as different.
- if (TRI->isSuperRegister(DefReg, KnownReg.Reg) && KnownReg.Imm < 0)
- continue;
+
+ // Don't remove a move immediate that implicitly defines the upper
+ // bits as different.
+ if (TRI->isSuperRegister(DefReg, KnownReg.Reg) && KnownReg.Imm < 0)
+ continue;
}
if (IsCopy)
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64RegisterInfo.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64RegisterInfo.cpp
index 2aeea84ae2..f90856d14b 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64RegisterInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64RegisterInfo.cpp
@@ -24,7 +24,7 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
-#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
@@ -240,14 +240,14 @@ AArch64RegisterInfo::getCallPreservedMask(const MachineFunction &MF,
return SCS ? CSR_AArch64_AAPCS_SCS_RegMask : CSR_AArch64_AAPCS_RegMask;
}
-const uint32_t *AArch64RegisterInfo::getCustomEHPadPreservedMask(
- const MachineFunction &MF) const {
- if (MF.getSubtarget<AArch64Subtarget>().isTargetLinux())
- return CSR_AArch64_AAPCS_RegMask;
-
- return nullptr;
-}
-
+const uint32_t *AArch64RegisterInfo::getCustomEHPadPreservedMask(
+ const MachineFunction &MF) const {
+ if (MF.getSubtarget<AArch64Subtarget>().isTargetLinux())
+ return CSR_AArch64_AAPCS_RegMask;
+
+ return nullptr;
+}
+
const uint32_t *AArch64RegisterInfo::getTLSCallPreservedMask() const {
if (TT.isOSDarwin())
return CSR_Darwin_AArch64_TLS_RegMask;
@@ -334,16 +334,16 @@ bool AArch64RegisterInfo::isReservedReg(const MachineFunction &MF,
}
bool AArch64RegisterInfo::isAnyArgRegReserved(const MachineFunction &MF) const {
- return llvm::any_of(*AArch64::GPR64argRegClass.MC, [this, &MF](MCPhysReg r) {
- return isReservedReg(MF, r);
- });
+ return llvm::any_of(*AArch64::GPR64argRegClass.MC, [this, &MF](MCPhysReg r) {
+ return isReservedReg(MF, r);
+ });
}
void AArch64RegisterInfo::emitReservedArgRegCallError(
const MachineFunction &MF) const {
const Function &F = MF.getFunction();
- F.getContext().diagnose(DiagnosticInfoUnsupported{F, ("AArch64 doesn't support"
- " function calls if any of the argument registers is reserved.")});
+ F.getContext().diagnose(DiagnosticInfoUnsupported{F, ("AArch64 doesn't support"
+ " function calls if any of the argument registers is reserved.")});
}
bool AArch64RegisterInfo::isAsmClobberable(const MachineFunction &MF,
@@ -525,16 +525,16 @@ bool AArch64RegisterInfo::isFrameOffsetLegal(const MachineInstr *MI,
Register BaseReg,
int64_t Offset) const {
assert(MI && "Unable to get the legal offset for nil instruction.");
- StackOffset SaveOffset = StackOffset::getFixed(Offset);
+ StackOffset SaveOffset = StackOffset::getFixed(Offset);
return isAArch64FrameOffsetLegal(*MI, SaveOffset) & AArch64FrameOffsetIsLegal;
}
/// Insert defining instruction(s) for BaseReg to be a pointer to FrameIdx
/// at the beginning of the basic block.
-Register
-AArch64RegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,
- int FrameIdx,
- int64_t Offset) const {
+Register
+AArch64RegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,
+ int FrameIdx,
+ int64_t Offset) const {
MachineBasicBlock::iterator Ins = MBB->begin();
DebugLoc DL; // Defaults to "unknown"
if (Ins != MBB->end())
@@ -544,7 +544,7 @@ AArch64RegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,
MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
const MCInstrDesc &MCID = TII->get(AArch64::ADDXri);
MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
- Register BaseReg = MRI.createVirtualRegister(&AArch64::GPR64spRegClass);
+ Register BaseReg = MRI.createVirtualRegister(&AArch64::GPR64spRegClass);
MRI.constrainRegClass(BaseReg, TII->getRegClass(MCID, 0, this, MF));
unsigned Shifter = AArch64_AM::getShifterImm(AArch64_AM::LSL, 0);
@@ -552,21 +552,21 @@ AArch64RegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,
.addFrameIndex(FrameIdx)
.addImm(Offset)
.addImm(Shifter);
-
- return BaseReg;
+
+ return BaseReg;
}
void AArch64RegisterInfo::resolveFrameIndex(MachineInstr &MI, Register BaseReg,
int64_t Offset) const {
// ARM doesn't need the general 64-bit offsets
- StackOffset Off = StackOffset::getFixed(Offset);
+ StackOffset Off = StackOffset::getFixed(Offset);
unsigned i = 0;
while (!MI.getOperand(i).isFI()) {
++i;
assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
}
-
+
const MachineFunction *MF = MI.getParent()->getParent();
const AArch64InstrInfo *TII =
MF->getSubtarget<AArch64Subtarget>().getInstrInfo();
@@ -596,33 +596,33 @@ createScratchRegisterForInstruction(MachineInstr &MI,
}
}
-void AArch64RegisterInfo::getOffsetOpcodes(
- const StackOffset &Offset, SmallVectorImpl<uint64_t> &Ops) const {
- // The smallest scalable element supported by scaled SVE addressing
- // modes are predicates, which are 2 scalable bytes in size. So the scalable
- // byte offset must always be a multiple of 2.
- assert(Offset.getScalable() % 2 == 0 && "Invalid frame offset");
-
- // Add fixed-sized offset using existing DIExpression interface.
- DIExpression::appendOffset(Ops, Offset.getFixed());
-
- unsigned VG = getDwarfRegNum(AArch64::VG, true);
- int64_t VGSized = Offset.getScalable() / 2;
- if (VGSized > 0) {
- Ops.push_back(dwarf::DW_OP_constu);
- Ops.push_back(VGSized);
- Ops.append({dwarf::DW_OP_bregx, VG, 0ULL});
- Ops.push_back(dwarf::DW_OP_mul);
- Ops.push_back(dwarf::DW_OP_plus);
- } else if (VGSized < 0) {
- Ops.push_back(dwarf::DW_OP_constu);
- Ops.push_back(-VGSized);
- Ops.append({dwarf::DW_OP_bregx, VG, 0ULL});
- Ops.push_back(dwarf::DW_OP_mul);
- Ops.push_back(dwarf::DW_OP_minus);
- }
-}
-
+void AArch64RegisterInfo::getOffsetOpcodes(
+ const StackOffset &Offset, SmallVectorImpl<uint64_t> &Ops) const {
+ // The smallest scalable element supported by scaled SVE addressing
+ // modes are predicates, which are 2 scalable bytes in size. So the scalable
+ // byte offset must always be a multiple of 2.
+ assert(Offset.getScalable() % 2 == 0 && "Invalid frame offset");
+
+ // Add fixed-sized offset using existing DIExpression interface.
+ DIExpression::appendOffset(Ops, Offset.getFixed());
+
+ unsigned VG = getDwarfRegNum(AArch64::VG, true);
+ int64_t VGSized = Offset.getScalable() / 2;
+ if (VGSized > 0) {
+ Ops.push_back(dwarf::DW_OP_constu);
+ Ops.push_back(VGSized);
+ Ops.append({dwarf::DW_OP_bregx, VG, 0ULL});
+ Ops.push_back(dwarf::DW_OP_mul);
+ Ops.push_back(dwarf::DW_OP_plus);
+ } else if (VGSized < 0) {
+ Ops.push_back(dwarf::DW_OP_constu);
+ Ops.push_back(-VGSized);
+ Ops.append({dwarf::DW_OP_bregx, VG, 0ULL});
+ Ops.push_back(dwarf::DW_OP_mul);
+ Ops.push_back(dwarf::DW_OP_minus);
+ }
+}
+
void AArch64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS) const {
@@ -640,26 +640,26 @@ void AArch64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
MI.getOperand(FIOperandNum).getTargetFlags() & AArch64II::MO_TAGGED;
Register FrameReg;
- // Special handling of dbg_value, stackmap patchpoint statepoint instructions.
- if (MI.getOpcode() == TargetOpcode::STACKMAP ||
- MI.getOpcode() == TargetOpcode::PATCHPOINT ||
- MI.getOpcode() == TargetOpcode::STATEPOINT) {
+ // Special handling of dbg_value, stackmap patchpoint statepoint instructions.
+ if (MI.getOpcode() == TargetOpcode::STACKMAP ||
+ MI.getOpcode() == TargetOpcode::PATCHPOINT ||
+ MI.getOpcode() == TargetOpcode::STATEPOINT) {
StackOffset Offset =
TFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg,
/*PreferFP=*/true,
/*ForSimm=*/false);
- Offset += StackOffset::getFixed(MI.getOperand(FIOperandNum + 1).getImm());
+ Offset += StackOffset::getFixed(MI.getOperand(FIOperandNum + 1).getImm());
MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/);
- MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset.getFixed());
+ MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset.getFixed());
return;
}
if (MI.getOpcode() == TargetOpcode::LOCAL_ESCAPE) {
MachineOperand &FI = MI.getOperand(FIOperandNum);
- StackOffset Offset = TFI->getNonLocalFrameIndexReference(MF, FrameIndex);
- assert(!Offset.getScalable() &&
- "Frame offsets with a scalable component are not supported");
- FI.ChangeToImmediate(Offset.getFixed());
+ StackOffset Offset = TFI->getNonLocalFrameIndexReference(MF, FrameIndex);
+ assert(!Offset.getScalable() &&
+ "Frame offsets with a scalable component are not supported");
+ FI.ChangeToImmediate(Offset.getFixed());
return;
}
@@ -668,11 +668,11 @@ void AArch64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
// TAGPstack must use the virtual frame register in its 3rd operand.
const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
FrameReg = MI.getOperand(3).getReg();
- Offset = StackOffset::getFixed(MFI.getObjectOffset(FrameIndex) +
- AFI->getTaggedBasePointerOffset());
+ Offset = StackOffset::getFixed(MFI.getObjectOffset(FrameIndex) +
+ AFI->getTaggedBasePointerOffset());
} else if (Tagged) {
- StackOffset SPOffset = StackOffset::getFixed(
- MFI.getObjectOffset(FrameIndex) + (int64_t)MFI.getStackSize());
+ StackOffset SPOffset = StackOffset::getFixed(
+ MFI.getObjectOffset(FrameIndex) + (int64_t)MFI.getStackSize());
if (MFI.hasVarSizedObjects() ||
isAArch64FrameOffsetLegal(MI, SPOffset, nullptr, nullptr, nullptr) !=
(AArch64FrameOffsetCanUpdate | AArch64FrameOffsetIsLegal)) {
@@ -693,8 +693,8 @@ void AArch64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
return;
}
FrameReg = AArch64::SP;
- Offset = StackOffset::getFixed(MFI.getObjectOffset(FrameIndex) +
- (int64_t)MFI.getStackSize());
+ Offset = StackOffset::getFixed(MFI.getObjectOffset(FrameIndex) +
+ (int64_t)MFI.getStackSize());
} else {
Offset = TFI->resolveFrameIndexReference(
MF, FrameIndex, FrameReg, /*PreferFP=*/false, /*ForSimm=*/true);
@@ -765,19 +765,19 @@ unsigned AArch64RegisterInfo::getLocalAddressRegister(
return getBaseRegister();
return getFrameRegister(MF);
}
-
-/// SrcRC and DstRC will be morphed into NewRC if this returns true
-bool AArch64RegisterInfo::shouldCoalesce(
- MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg,
- const TargetRegisterClass *DstRC, unsigned DstSubReg,
- const TargetRegisterClass *NewRC, LiveIntervals &LIS) const {
- if (MI->isCopy() &&
- ((DstRC->getID() == AArch64::GPR64RegClassID) ||
- (DstRC->getID() == AArch64::GPR64commonRegClassID)) &&
- MI->getOperand(0).getSubReg() && MI->getOperand(1).getSubReg())
- // Do not coalesce in the case of a 32-bit subregister copy
- // which implements a 32 to 64 bit zero extension
- // which relies on the upper 32 bits being zeroed.
- return false;
- return true;
-}
+
+/// SrcRC and DstRC will be morphed into NewRC if this returns true
+bool AArch64RegisterInfo::shouldCoalesce(
+ MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg,
+ const TargetRegisterClass *DstRC, unsigned DstSubReg,
+ const TargetRegisterClass *NewRC, LiveIntervals &LIS) const {
+ if (MI->isCopy() &&
+ ((DstRC->getID() == AArch64::GPR64RegClassID) ||
+ (DstRC->getID() == AArch64::GPR64commonRegClassID)) &&
+ MI->getOperand(0).getSubReg() && MI->getOperand(1).getSubReg())
+ // Do not coalesce in the case of a 32-bit subregister copy
+ // which implements a 32 to 64 bit zero extension
+ // which relies on the upper 32 bits being zeroed.
+ return false;
+ return true;
+}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64RegisterInfo.h b/contrib/libs/llvm12/lib/Target/AArch64/AArch64RegisterInfo.h
index b9a4e6ac16..0c871ac089 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64RegisterInfo.h
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64RegisterInfo.h
@@ -72,10 +72,10 @@ public:
// Funclets on ARM64 Windows don't preserve any registers.
const uint32_t *getNoPreservedMask() const override;
- // Unwinders may not preserve all Neon and SVE registers.
- const uint32_t *
- getCustomEHPadPreservedMask(const MachineFunction &MF) const override;
-
+ // Unwinders may not preserve all Neon and SVE registers.
+ const uint32_t *
+ getCustomEHPadPreservedMask(const MachineFunction &MF) const override;
+
/// getThisReturnPreservedMask - Returns a call preserved mask specific to the
/// case that 'returned' is on an i64 first argument if the calling convention
/// is one that can (partially) model this attribute with a preserved mask
@@ -107,8 +107,8 @@ public:
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg,
int64_t Offset) const override;
- Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx,
- int64_t Offset) const override;
+ Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx,
+ int64_t Offset) const override;
void resolveFrameIndex(MachineInstr &MI, Register BaseReg,
int64_t Offset) const override;
void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
@@ -128,15 +128,15 @@ public:
unsigned getLocalAddressRegister(const MachineFunction &MF) const;
bool regNeedsCFI(unsigned Reg, unsigned &RegToUseForCFI) const;
-
- /// SrcRC and DstRC will be morphed into NewRC if this returns true
- bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC,
- unsigned SubReg, const TargetRegisterClass *DstRC,
- unsigned DstSubReg, const TargetRegisterClass *NewRC,
- LiveIntervals &LIS) const override;
-
- void getOffsetOpcodes(const StackOffset &Offset,
- SmallVectorImpl<uint64_t> &Ops) const override;
+
+ /// SrcRC and DstRC will be morphed into NewRC if this returns true
+ bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC,
+ unsigned SubReg, const TargetRegisterClass *DstRC,
+ unsigned DstSubReg, const TargetRegisterClass *NewRC,
+ LiveIntervals &LIS) const override;
+
+ void getOffsetOpcodes(const StackOffset &Offset,
+ SmallVectorImpl<uint64_t> &Ops) const override;
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64RegisterInfo.td b/contrib/libs/llvm12/lib/Target/AArch64/AArch64RegisterInfo.td
index 17ad5b997c..28d1988b8a 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64RegisterInfo.td
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64RegisterInfo.td
@@ -711,32 +711,32 @@ def XSeqPairClassOperand :
//===----- END: v8.1a atomic CASP register operands -----------------------===//
-//===----------------------------------------------------------------------===//
-// Armv8.7a accelerator extension register operands: 8 consecutive GPRs
-// starting with an even one
-
-let Namespace = "AArch64" in {
- foreach i = 0-7 in
- def "x8sub_"#i : SubRegIndex<64, !mul(64, i)>;
-}
-
-def Tuples8X : RegisterTuples<
- !foreach(i, [0,1,2,3,4,5,6,7], !cast<SubRegIndex>("x8sub_"#i)),
- !foreach(i, [0,1,2,3,4,5,6,7], (trunc (decimate (rotl GPR64, i), 2), 12))>;
-
-def GPR64x8Class : RegisterClass<"AArch64", [i64], 64, (trunc Tuples8X, 12)>;
-def GPR64x8AsmOp : AsmOperandClass {
- let Name = "GPR64x8";
- let ParserMethod = "tryParseGPR64x8";
- let RenderMethod = "addRegOperands";
-}
-def GPR64x8 : RegisterOperand<GPR64x8Class, "printGPR64x8"> {
- let ParserMatchClass = GPR64x8AsmOp;
- let PrintMethod = "printGPR64x8";
-}
-
-//===----- END: v8.7a accelerator extension register operands -------------===//
-
+//===----------------------------------------------------------------------===//
+// Armv8.7a accelerator extension register operands: 8 consecutive GPRs
+// starting with an even one
+
+let Namespace = "AArch64" in {
+ foreach i = 0-7 in
+ def "x8sub_"#i : SubRegIndex<64, !mul(64, i)>;
+}
+
+def Tuples8X : RegisterTuples<
+ !foreach(i, [0,1,2,3,4,5,6,7], !cast<SubRegIndex>("x8sub_"#i)),
+ !foreach(i, [0,1,2,3,4,5,6,7], (trunc (decimate (rotl GPR64, i), 2), 12))>;
+
+def GPR64x8Class : RegisterClass<"AArch64", [i64], 64, (trunc Tuples8X, 12)>;
+def GPR64x8AsmOp : AsmOperandClass {
+ let Name = "GPR64x8";
+ let ParserMethod = "tryParseGPR64x8";
+ let RenderMethod = "addRegOperands";
+}
+def GPR64x8 : RegisterOperand<GPR64x8Class, "printGPR64x8"> {
+ let ParserMatchClass = GPR64x8AsmOp;
+ let PrintMethod = "printGPR64x8";
+}
+
+//===----- END: v8.7a accelerator extension register operands -------------===//
+
// SVE predicate registers
def P0 : AArch64Reg<0, "p0">, DwarfRegNum<[48]>;
def P1 : AArch64Reg<1, "p1">, DwarfRegNum<[49]>;
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64SIMDInstrOpt.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64SIMDInstrOpt.cpp
index 84e6327550..03b32967a2 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64SIMDInstrOpt.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64SIMDInstrOpt.cpp
@@ -221,9 +221,9 @@ shouldReplaceInst(MachineFunction *MF, const MCInstrDesc *InstDesc,
// if so, return it.
std::string Subtarget = std::string(SchedModel.getSubtargetInfo()->getCPU());
auto InstID = std::make_pair(InstDesc->getOpcode(), Subtarget);
- auto It = SIMDInstrTable.find(InstID);
- if (It != SIMDInstrTable.end())
- return It->second;
+ auto It = SIMDInstrTable.find(InstID);
+ if (It != SIMDInstrTable.end())
+ return It->second;
unsigned SCIdx = InstDesc->getSchedClass();
const MCSchedClassDesc *SCDesc =
@@ -291,9 +291,9 @@ bool AArch64SIMDInstrOpt::shouldExitEarly(MachineFunction *MF, Subpass SP) {
case Interleave:
std::string Subtarget =
std::string(SchedModel.getSubtargetInfo()->getCPU());
- auto It = InterlEarlyExit.find(Subtarget);
- if (It != InterlEarlyExit.end())
- return It->second;
+ auto It = InterlEarlyExit.find(Subtarget);
+ if (It != InterlEarlyExit.end())
+ return It->second;
for (auto &I : IRT) {
OriginalMCID = &TII->get(I.OrigOpc);
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64SVEInstrInfo.td b/contrib/libs/llvm12/lib/Target/AArch64/AArch64SVEInstrInfo.td
index 19a71f606b..e09b8401c0 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -152,8 +152,8 @@ def AArch64fmaxv_p : SDNode<"AArch64ISD::FMAXV_PRED", SDT_AArch64Reduce>;
def AArch64fmaxnmv_p : SDNode<"AArch64ISD::FMAXNMV_PRED", SDT_AArch64Reduce>;
def AArch64fminv_p : SDNode<"AArch64ISD::FMINV_PRED", SDT_AArch64Reduce>;
def AArch64fminnmv_p : SDNode<"AArch64ISD::FMINNMV_PRED", SDT_AArch64Reduce>;
-def AArch64saddv_p : SDNode<"AArch64ISD::SADDV_PRED", SDT_AArch64Reduce>;
-def AArch64uaddv_p : SDNode<"AArch64ISD::UADDV_PRED", SDT_AArch64Reduce>;
+def AArch64saddv_p : SDNode<"AArch64ISD::SADDV_PRED", SDT_AArch64Reduce>;
+def AArch64uaddv_p : SDNode<"AArch64ISD::UADDV_PRED", SDT_AArch64Reduce>;
def AArch64smaxv_p : SDNode<"AArch64ISD::SMAXV_PRED", SDT_AArch64Reduce>;
def AArch64umaxv_p : SDNode<"AArch64ISD::UMAXV_PRED", SDT_AArch64Reduce>;
def AArch64sminv_p : SDNode<"AArch64ISD::SMINV_PRED", SDT_AArch64Reduce>;
@@ -166,84 +166,84 @@ def AArch64lastb : SDNode<"AArch64ISD::LASTB", SDT_AArch64Reduce>;
def SDT_AArch64Arith : SDTypeProfile<1, 3, [
SDTCisVec<0>, SDTCisVec<1>, SDTCisVec<2>, SDTCisVec<3>,
- SDTCVecEltisVT<1,i1>, SDTCisSameAs<0,2>, SDTCisSameAs<2,3>
+ SDTCVecEltisVT<1,i1>, SDTCisSameAs<0,2>, SDTCisSameAs<2,3>
]>;
def SDT_AArch64FMA : SDTypeProfile<1, 4, [
SDTCisVec<0>, SDTCisVec<1>, SDTCisVec<2>, SDTCisVec<3>, SDTCisVec<4>,
- SDTCVecEltisVT<1,i1>, SDTCisSameAs<0,2>, SDTCisSameAs<2,3>, SDTCisSameAs<3,4>
+ SDTCVecEltisVT<1,i1>, SDTCisSameAs<0,2>, SDTCisSameAs<2,3>, SDTCisSameAs<3,4>
]>;
// Predicated operations with the result of inactive lanes being unspecified.
def AArch64add_p : SDNode<"AArch64ISD::ADD_PRED", SDT_AArch64Arith>;
-def AArch64asr_p : SDNode<"AArch64ISD::SRA_PRED", SDT_AArch64Arith>;
+def AArch64asr_p : SDNode<"AArch64ISD::SRA_PRED", SDT_AArch64Arith>;
def AArch64fadd_p : SDNode<"AArch64ISD::FADD_PRED", SDT_AArch64Arith>;
-def AArch64fdiv_p : SDNode<"AArch64ISD::FDIV_PRED", SDT_AArch64Arith>;
+def AArch64fdiv_p : SDNode<"AArch64ISD::FDIV_PRED", SDT_AArch64Arith>;
def AArch64fma_p : SDNode<"AArch64ISD::FMA_PRED", SDT_AArch64FMA>;
-def AArch64fmaxnm_p : SDNode<"AArch64ISD::FMAXNM_PRED", SDT_AArch64Arith>;
-def AArch64fminnm_p : SDNode<"AArch64ISD::FMINNM_PRED", SDT_AArch64Arith>;
-def AArch64fmul_p : SDNode<"AArch64ISD::FMUL_PRED", SDT_AArch64Arith>;
-def AArch64fsub_p : SDNode<"AArch64ISD::FSUB_PRED", SDT_AArch64Arith>;
-def AArch64lsl_p : SDNode<"AArch64ISD::SHL_PRED", SDT_AArch64Arith>;
-def AArch64lsr_p : SDNode<"AArch64ISD::SRL_PRED", SDT_AArch64Arith>;
-def AArch64mul_p : SDNode<"AArch64ISD::MUL_PRED", SDT_AArch64Arith>;
+def AArch64fmaxnm_p : SDNode<"AArch64ISD::FMAXNM_PRED", SDT_AArch64Arith>;
+def AArch64fminnm_p : SDNode<"AArch64ISD::FMINNM_PRED", SDT_AArch64Arith>;
+def AArch64fmul_p : SDNode<"AArch64ISD::FMUL_PRED", SDT_AArch64Arith>;
+def AArch64fsub_p : SDNode<"AArch64ISD::FSUB_PRED", SDT_AArch64Arith>;
+def AArch64lsl_p : SDNode<"AArch64ISD::SHL_PRED", SDT_AArch64Arith>;
+def AArch64lsr_p : SDNode<"AArch64ISD::SRL_PRED", SDT_AArch64Arith>;
+def AArch64mul_p : SDNode<"AArch64ISD::MUL_PRED", SDT_AArch64Arith>;
def AArch64sdiv_p : SDNode<"AArch64ISD::SDIV_PRED", SDT_AArch64Arith>;
-def AArch64smax_p : SDNode<"AArch64ISD::SMAX_PRED", SDT_AArch64Arith>;
-def AArch64smin_p : SDNode<"AArch64ISD::SMIN_PRED", SDT_AArch64Arith>;
-def AArch64sub_p : SDNode<"AArch64ISD::SUB_PRED", SDT_AArch64Arith>;
+def AArch64smax_p : SDNode<"AArch64ISD::SMAX_PRED", SDT_AArch64Arith>;
+def AArch64smin_p : SDNode<"AArch64ISD::SMIN_PRED", SDT_AArch64Arith>;
+def AArch64sub_p : SDNode<"AArch64ISD::SUB_PRED", SDT_AArch64Arith>;
def AArch64udiv_p : SDNode<"AArch64ISD::UDIV_PRED", SDT_AArch64Arith>;
-def AArch64umax_p : SDNode<"AArch64ISD::UMAX_PRED", SDT_AArch64Arith>;
-def AArch64umin_p : SDNode<"AArch64ISD::UMIN_PRED", SDT_AArch64Arith>;
-
-def SDT_AArch64IntExtend : SDTypeProfile<1, 4, [
- SDTCisVec<0>, SDTCisVec<1>, SDTCisVec<2>, SDTCisVT<3, OtherVT>, SDTCisVec<4>,
- SDTCVecEltisVT<1,i1>, SDTCisSameAs<0,2>, SDTCisVTSmallerThanOp<3, 2>, SDTCisSameAs<0,4>
-]>;
-
-// Predicated operations with the result of inactive lanes provided by the last operand.
-def AArch64clz_mt : SDNode<"AArch64ISD::CTLZ_MERGE_PASSTHRU", SDT_AArch64Arith>;
-def AArch64cnt_mt : SDNode<"AArch64ISD::CTPOP_MERGE_PASSTHRU", SDT_AArch64Arith>;
-def AArch64fneg_mt : SDNode<"AArch64ISD::FNEG_MERGE_PASSTHRU", SDT_AArch64Arith>;
-def AArch64fabs_mt : SDNode<"AArch64ISD::FABS_MERGE_PASSTHRU", SDT_AArch64Arith>;
-def AArch64abs_mt : SDNode<"AArch64ISD::ABS_MERGE_PASSTHRU", SDT_AArch64Arith>;
-def AArch64neg_mt : SDNode<"AArch64ISD::NEG_MERGE_PASSTHRU", SDT_AArch64Arith>;
-def AArch64sxt_mt : SDNode<"AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU", SDT_AArch64IntExtend>;
-def AArch64uxt_mt : SDNode<"AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU", SDT_AArch64IntExtend>;
-def AArch64frintp_mt : SDNode<"AArch64ISD::FCEIL_MERGE_PASSTHRU", SDT_AArch64Arith>;
-def AArch64frintm_mt : SDNode<"AArch64ISD::FFLOOR_MERGE_PASSTHRU", SDT_AArch64Arith>;
-def AArch64frinti_mt : SDNode<"AArch64ISD::FNEARBYINT_MERGE_PASSTHRU", SDT_AArch64Arith>;
-def AArch64frintx_mt : SDNode<"AArch64ISD::FRINT_MERGE_PASSTHRU", SDT_AArch64Arith>;
-def AArch64frinta_mt : SDNode<"AArch64ISD::FROUND_MERGE_PASSTHRU", SDT_AArch64Arith>;
-def AArch64frintn_mt : SDNode<"AArch64ISD::FROUNDEVEN_MERGE_PASSTHRU", SDT_AArch64Arith>;
-def AArch64frintz_mt : SDNode<"AArch64ISD::FTRUNC_MERGE_PASSTHRU", SDT_AArch64Arith>;
-def AArch64fsqrt_mt : SDNode<"AArch64ISD::FSQRT_MERGE_PASSTHRU", SDT_AArch64Arith>;
-def AArch64frecpx_mt : SDNode<"AArch64ISD::FRECPX_MERGE_PASSTHRU", SDT_AArch64Arith>;
-def AArch64rbit_mt : SDNode<"AArch64ISD::BITREVERSE_MERGE_PASSTHRU", SDT_AArch64Arith>;
-def AArch64revb_mt : SDNode<"AArch64ISD::BSWAP_MERGE_PASSTHRU", SDT_AArch64Arith>;
-
-// These are like the above but we don't yet have need for ISD nodes. They allow
-// a single pattern to match intrinsic and ISD operand layouts.
-def AArch64cls_mt : PatFrags<(ops node:$pg, node:$op, node:$pt), [(int_aarch64_sve_cls node:$pt, node:$pg, node:$op)]>;
-def AArch64cnot_mt : PatFrags<(ops node:$pg, node:$op, node:$pt), [(int_aarch64_sve_cnot node:$pt, node:$pg, node:$op)]>;
-def AArch64not_mt : PatFrags<(ops node:$pg, node:$op, node:$pt), [(int_aarch64_sve_not node:$pt, node:$pg, node:$op)]>;
-
-def SDT_AArch64FCVT : SDTypeProfile<1, 3, [
- SDTCisVec<0>, SDTCisVec<1>, SDTCisVec<2>, SDTCisVec<3>,
- SDTCVecEltisVT<1,i1>
-]>;
-
-def SDT_AArch64FCVTR : SDTypeProfile<1, 4, [
- SDTCisVec<0>, SDTCisVec<1>, SDTCisVec<2>, SDTCisInt<3>, SDTCisVec<4>,
- SDTCVecEltisVT<1,i1>
-]>;
-
-def AArch64fcvtr_mt : SDNode<"AArch64ISD::FP_ROUND_MERGE_PASSTHRU", SDT_AArch64FCVTR>;
-def AArch64fcvte_mt : SDNode<"AArch64ISD::FP_EXTEND_MERGE_PASSTHRU", SDT_AArch64FCVT>;
-def AArch64ucvtf_mt : SDNode<"AArch64ISD::UINT_TO_FP_MERGE_PASSTHRU", SDT_AArch64FCVT>;
-def AArch64scvtf_mt : SDNode<"AArch64ISD::SINT_TO_FP_MERGE_PASSTHRU", SDT_AArch64FCVT>;
-def AArch64fcvtzu_mt : SDNode<"AArch64ISD::FCVTZU_MERGE_PASSTHRU", SDT_AArch64FCVT>;
-def AArch64fcvtzs_mt : SDNode<"AArch64ISD::FCVTZS_MERGE_PASSTHRU", SDT_AArch64FCVT>;
-
+def AArch64umax_p : SDNode<"AArch64ISD::UMAX_PRED", SDT_AArch64Arith>;
+def AArch64umin_p : SDNode<"AArch64ISD::UMIN_PRED", SDT_AArch64Arith>;
+
+def SDT_AArch64IntExtend : SDTypeProfile<1, 4, [
+ SDTCisVec<0>, SDTCisVec<1>, SDTCisVec<2>, SDTCisVT<3, OtherVT>, SDTCisVec<4>,
+ SDTCVecEltisVT<1,i1>, SDTCisSameAs<0,2>, SDTCisVTSmallerThanOp<3, 2>, SDTCisSameAs<0,4>
+]>;
+
+// Predicated operations with the result of inactive lanes provided by the last operand.
+def AArch64clz_mt : SDNode<"AArch64ISD::CTLZ_MERGE_PASSTHRU", SDT_AArch64Arith>;
+def AArch64cnt_mt : SDNode<"AArch64ISD::CTPOP_MERGE_PASSTHRU", SDT_AArch64Arith>;
+def AArch64fneg_mt : SDNode<"AArch64ISD::FNEG_MERGE_PASSTHRU", SDT_AArch64Arith>;
+def AArch64fabs_mt : SDNode<"AArch64ISD::FABS_MERGE_PASSTHRU", SDT_AArch64Arith>;
+def AArch64abs_mt : SDNode<"AArch64ISD::ABS_MERGE_PASSTHRU", SDT_AArch64Arith>;
+def AArch64neg_mt : SDNode<"AArch64ISD::NEG_MERGE_PASSTHRU", SDT_AArch64Arith>;
+def AArch64sxt_mt : SDNode<"AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU", SDT_AArch64IntExtend>;
+def AArch64uxt_mt : SDNode<"AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU", SDT_AArch64IntExtend>;
+def AArch64frintp_mt : SDNode<"AArch64ISD::FCEIL_MERGE_PASSTHRU", SDT_AArch64Arith>;
+def AArch64frintm_mt : SDNode<"AArch64ISD::FFLOOR_MERGE_PASSTHRU", SDT_AArch64Arith>;
+def AArch64frinti_mt : SDNode<"AArch64ISD::FNEARBYINT_MERGE_PASSTHRU", SDT_AArch64Arith>;
+def AArch64frintx_mt : SDNode<"AArch64ISD::FRINT_MERGE_PASSTHRU", SDT_AArch64Arith>;
+def AArch64frinta_mt : SDNode<"AArch64ISD::FROUND_MERGE_PASSTHRU", SDT_AArch64Arith>;
+def AArch64frintn_mt : SDNode<"AArch64ISD::FROUNDEVEN_MERGE_PASSTHRU", SDT_AArch64Arith>;
+def AArch64frintz_mt : SDNode<"AArch64ISD::FTRUNC_MERGE_PASSTHRU", SDT_AArch64Arith>;
+def AArch64fsqrt_mt : SDNode<"AArch64ISD::FSQRT_MERGE_PASSTHRU", SDT_AArch64Arith>;
+def AArch64frecpx_mt : SDNode<"AArch64ISD::FRECPX_MERGE_PASSTHRU", SDT_AArch64Arith>;
+def AArch64rbit_mt : SDNode<"AArch64ISD::BITREVERSE_MERGE_PASSTHRU", SDT_AArch64Arith>;
+def AArch64revb_mt : SDNode<"AArch64ISD::BSWAP_MERGE_PASSTHRU", SDT_AArch64Arith>;
+
+// These are like the above but we don't yet have need for ISD nodes. They allow
+// a single pattern to match intrinsic and ISD operand layouts.
+def AArch64cls_mt : PatFrags<(ops node:$pg, node:$op, node:$pt), [(int_aarch64_sve_cls node:$pt, node:$pg, node:$op)]>;
+def AArch64cnot_mt : PatFrags<(ops node:$pg, node:$op, node:$pt), [(int_aarch64_sve_cnot node:$pt, node:$pg, node:$op)]>;
+def AArch64not_mt : PatFrags<(ops node:$pg, node:$op, node:$pt), [(int_aarch64_sve_not node:$pt, node:$pg, node:$op)]>;
+
+def SDT_AArch64FCVT : SDTypeProfile<1, 3, [
+ SDTCisVec<0>, SDTCisVec<1>, SDTCisVec<2>, SDTCisVec<3>,
+ SDTCVecEltisVT<1,i1>
+]>;
+
+def SDT_AArch64FCVTR : SDTypeProfile<1, 4, [
+ SDTCisVec<0>, SDTCisVec<1>, SDTCisVec<2>, SDTCisInt<3>, SDTCisVec<4>,
+ SDTCVecEltisVT<1,i1>
+]>;
+
+def AArch64fcvtr_mt : SDNode<"AArch64ISD::FP_ROUND_MERGE_PASSTHRU", SDT_AArch64FCVTR>;
+def AArch64fcvte_mt : SDNode<"AArch64ISD::FP_EXTEND_MERGE_PASSTHRU", SDT_AArch64FCVT>;
+def AArch64ucvtf_mt : SDNode<"AArch64ISD::UINT_TO_FP_MERGE_PASSTHRU", SDT_AArch64FCVT>;
+def AArch64scvtf_mt : SDNode<"AArch64ISD::SINT_TO_FP_MERGE_PASSTHRU", SDT_AArch64FCVT>;
+def AArch64fcvtzu_mt : SDNode<"AArch64ISD::FCVTZU_MERGE_PASSTHRU", SDT_AArch64FCVT>;
+def AArch64fcvtzs_mt : SDNode<"AArch64ISD::FCVTZS_MERGE_PASSTHRU", SDT_AArch64FCVT>;
+
def SDT_AArch64ReduceWithInit : SDTypeProfile<1, 3, [SDTCisVec<1>, SDTCisVec<3>]>;
def AArch64clasta_n : SDNode<"AArch64ISD::CLASTA_N", SDT_AArch64ReduceWithInit>;
def AArch64clastb_n : SDNode<"AArch64ISD::CLASTB_N", SDT_AArch64ReduceWithInit>;
@@ -263,24 +263,24 @@ def index_vector : SDNode<"AArch64ISD::INDEX_VECTOR", SDT_IndexVector, []>;
def reinterpret_cast : SDNode<"AArch64ISD::REINTERPRET_CAST", SDTUnaryOp>;
-def setoge_or_setge : PatFrags<(ops node:$lhs, node:$rhs),
- [(setoge node:$lhs, node:$rhs),
- (setge node:$lhs, node:$rhs)]>;
-def setogt_or_setgt : PatFrags<(ops node:$lhs, node:$rhs),
- [(setogt node:$lhs, node:$rhs),
- (setgt node:$lhs, node:$rhs)]>;
-def setoeq_or_seteq : PatFrags<(ops node:$lhs, node:$rhs),
- [(setoeq node:$lhs, node:$rhs),
- (seteq node:$lhs, node:$rhs)]>;
-def setone_or_setne : PatFrags<(ops node:$lhs, node:$rhs),
- [(setone node:$lhs, node:$rhs),
- (setne node:$lhs, node:$rhs)]>;
-def AArch64mul_p_oneuse : PatFrag<(ops node:$pred, node:$src1, node:$src2),
- (AArch64mul_p node:$pred, node:$src1, node:$src2), [{
- return N->hasOneUse();
-}]>;
-
-
+def setoge_or_setge : PatFrags<(ops node:$lhs, node:$rhs),
+ [(setoge node:$lhs, node:$rhs),
+ (setge node:$lhs, node:$rhs)]>;
+def setogt_or_setgt : PatFrags<(ops node:$lhs, node:$rhs),
+ [(setogt node:$lhs, node:$rhs),
+ (setgt node:$lhs, node:$rhs)]>;
+def setoeq_or_seteq : PatFrags<(ops node:$lhs, node:$rhs),
+ [(setoeq node:$lhs, node:$rhs),
+ (seteq node:$lhs, node:$rhs)]>;
+def setone_or_setne : PatFrags<(ops node:$lhs, node:$rhs),
+ [(setone node:$lhs, node:$rhs),
+ (setne node:$lhs, node:$rhs)]>;
+def AArch64mul_p_oneuse : PatFrag<(ops node:$pred, node:$src1, node:$src2),
+ (AArch64mul_p node:$pred, node:$src1, node:$src2), [{
+ return N->hasOneUse();
+}]>;
+
+
let Predicates = [HasSVE] in {
defm RDFFR_PPz : sve_int_rdffr_pred<0b0, "rdffr", int_aarch64_sve_rdffr_z>;
def RDFFRS_PPz : sve_int_rdffr_pred<0b1, "rdffrs">;
@@ -305,7 +305,7 @@ let Predicates = [HasSVE] in {
defm SUBR_ZPmZ : sve_int_bin_pred_arit_0<0b011, "subr", "SUBR_ZPZZ", int_aarch64_sve_subr, DestructiveBinaryCommWithRev, "SUB_ZPmZ", /*isReverseInstr*/ 1>;
defm ADD_ZPZZ : sve_int_bin_pred_bhsd<AArch64add_p>;
- defm SUB_ZPZZ : sve_int_bin_pred_bhsd<AArch64sub_p>;
+ defm SUB_ZPZZ : sve_int_bin_pred_bhsd<AArch64sub_p>;
let Predicates = [HasSVE, UseExperimentalZeroingPseudos] in {
defm ADD_ZPZZ : sve_int_bin_pred_zeroing_bhsd<int_aarch64_sve_add>;
@@ -328,12 +328,12 @@ let Predicates = [HasSVE] in {
defm MAD_ZPmZZ : sve_int_mladdsub_vvv_pred<0b0, "mad", int_aarch64_sve_mad>;
defm MSB_ZPmZZ : sve_int_mladdsub_vvv_pred<0b1, "msb", int_aarch64_sve_msb>;
- defm MLA_ZPmZZ : sve_int_mlas_vvv_pred<0b0, "mla", int_aarch64_sve_mla, add, AArch64mul_p_oneuse>;
- defm MLS_ZPmZZ : sve_int_mlas_vvv_pred<0b1, "mls", int_aarch64_sve_mls, sub, AArch64mul_p_oneuse>;
+ defm MLA_ZPmZZ : sve_int_mlas_vvv_pred<0b0, "mla", int_aarch64_sve_mla, add, AArch64mul_p_oneuse>;
+ defm MLS_ZPmZZ : sve_int_mlas_vvv_pred<0b1, "mls", int_aarch64_sve_mls, sub, AArch64mul_p_oneuse>;
// SVE predicated integer reductions.
- defm SADDV_VPZ : sve_int_reduce_0_saddv<0b000, "saddv", AArch64saddv_p>;
- defm UADDV_VPZ : sve_int_reduce_0_uaddv<0b001, "uaddv", AArch64uaddv_p>;
+ defm SADDV_VPZ : sve_int_reduce_0_saddv<0b000, "saddv", AArch64saddv_p>;
+ defm UADDV_VPZ : sve_int_reduce_0_uaddv<0b001, "uaddv", AArch64uaddv_p>;
defm SMAXV_VPZ : sve_int_reduce_1<0b000, "smaxv", AArch64smaxv_p>;
defm UMAXV_VPZ : sve_int_reduce_1<0b001, "umaxv", AArch64umaxv_p>;
defm SMINV_VPZ : sve_int_reduce_1<0b010, "sminv", AArch64sminv_p>;
@@ -346,17 +346,17 @@ let Predicates = [HasSVE] in {
defm EOR_ZI : sve_int_log_imm<0b01, "eor", "eon", xor>;
defm AND_ZI : sve_int_log_imm<0b10, "and", "bic", and>;
- defm SMAX_ZI : sve_int_arith_imm1<0b00, "smax", AArch64smax_p>;
- defm SMIN_ZI : sve_int_arith_imm1<0b10, "smin", AArch64smin_p>;
- defm UMAX_ZI : sve_int_arith_imm1_unsigned<0b01, "umax", AArch64umax_p>;
- defm UMIN_ZI : sve_int_arith_imm1_unsigned<0b11, "umin", AArch64umin_p>;
+ defm SMAX_ZI : sve_int_arith_imm1<0b00, "smax", AArch64smax_p>;
+ defm SMIN_ZI : sve_int_arith_imm1<0b10, "smin", AArch64smin_p>;
+ defm UMAX_ZI : sve_int_arith_imm1_unsigned<0b01, "umax", AArch64umax_p>;
+ defm UMIN_ZI : sve_int_arith_imm1_unsigned<0b11, "umin", AArch64umin_p>;
- defm MUL_ZI : sve_int_arith_imm2<"mul", AArch64mul_p>;
- defm MUL_ZPmZ : sve_int_bin_pred_arit_2<0b000, "mul", "MUL_ZPZZ", int_aarch64_sve_mul, DestructiveBinaryComm>;
- defm SMULH_ZPmZ : sve_int_bin_pred_arit_2<0b010, "smulh", "SMULH_ZPZZ", int_aarch64_sve_smulh, DestructiveBinaryComm>;
- defm UMULH_ZPmZ : sve_int_bin_pred_arit_2<0b011, "umulh", "UMULH_ZPZZ", int_aarch64_sve_umulh, DestructiveBinaryComm>;
+ defm MUL_ZI : sve_int_arith_imm2<"mul", AArch64mul_p>;
+ defm MUL_ZPmZ : sve_int_bin_pred_arit_2<0b000, "mul", "MUL_ZPZZ", int_aarch64_sve_mul, DestructiveBinaryComm>;
+ defm SMULH_ZPmZ : sve_int_bin_pred_arit_2<0b010, "smulh", "SMULH_ZPZZ", int_aarch64_sve_smulh, DestructiveBinaryComm>;
+ defm UMULH_ZPmZ : sve_int_bin_pred_arit_2<0b011, "umulh", "UMULH_ZPZZ", int_aarch64_sve_umulh, DestructiveBinaryComm>;
- defm MUL_ZPZZ : sve_int_bin_pred_bhsd<AArch64mul_p>;
+ defm MUL_ZPZZ : sve_int_bin_pred_bhsd<AArch64mul_p>;
defm SDIV_ZPmZ : sve_int_bin_pred_arit_2_div<0b100, "sdiv", "SDIV_ZPZZ", int_aarch64_sve_sdiv, DestructiveBinaryCommWithRev, "SDIVR_ZPmZ">;
defm UDIV_ZPmZ : sve_int_bin_pred_arit_2_div<0b101, "udiv", "UDIV_ZPZZ", int_aarch64_sve_udiv, DestructiveBinaryCommWithRev, "UDIVR_ZPmZ">;
@@ -372,34 +372,34 @@ let Predicates = [HasSVE] in {
defm SDOT_ZZZI : sve_intx_dot_by_indexed_elem<0b0, "sdot", int_aarch64_sve_sdot_lane>;
defm UDOT_ZZZI : sve_intx_dot_by_indexed_elem<0b1, "udot", int_aarch64_sve_udot_lane>;
- defm SXTB_ZPmZ : sve_int_un_pred_arit_0_h<0b000, "sxtb", AArch64sxt_mt>;
- defm UXTB_ZPmZ : sve_int_un_pred_arit_0_h<0b001, "uxtb", AArch64uxt_mt>;
- defm SXTH_ZPmZ : sve_int_un_pred_arit_0_w<0b010, "sxth", AArch64sxt_mt>;
- defm UXTH_ZPmZ : sve_int_un_pred_arit_0_w<0b011, "uxth", AArch64uxt_mt>;
- defm SXTW_ZPmZ : sve_int_un_pred_arit_0_d<0b100, "sxtw", AArch64sxt_mt>;
- defm UXTW_ZPmZ : sve_int_un_pred_arit_0_d<0b101, "uxtw", AArch64uxt_mt>;
- defm ABS_ZPmZ : sve_int_un_pred_arit_0< 0b110, "abs", AArch64abs_mt>;
- defm NEG_ZPmZ : sve_int_un_pred_arit_0< 0b111, "neg", AArch64neg_mt>;
-
- defm CLS_ZPmZ : sve_int_un_pred_arit_1< 0b000, "cls", AArch64cls_mt>;
- defm CLZ_ZPmZ : sve_int_un_pred_arit_1< 0b001, "clz", AArch64clz_mt>;
- defm CNT_ZPmZ : sve_int_un_pred_arit_1< 0b010, "cnt", AArch64cnt_mt>;
- defm CNOT_ZPmZ : sve_int_un_pred_arit_1< 0b011, "cnot", AArch64cnot_mt>;
- defm NOT_ZPmZ : sve_int_un_pred_arit_1< 0b110, "not", AArch64not_mt>;
- defm FABS_ZPmZ : sve_int_un_pred_arit_1_fp<0b100, "fabs", AArch64fabs_mt>;
- defm FNEG_ZPmZ : sve_int_un_pred_arit_1_fp<0b101, "fneg", AArch64fneg_mt>;
-
- defm SMAX_ZPmZ : sve_int_bin_pred_arit_1<0b000, "smax", "SMAX_ZPZZ", int_aarch64_sve_smax, DestructiveBinaryComm>;
- defm UMAX_ZPmZ : sve_int_bin_pred_arit_1<0b001, "umax", "UMAX_ZPZZ", int_aarch64_sve_umax, DestructiveBinaryComm>;
- defm SMIN_ZPmZ : sve_int_bin_pred_arit_1<0b010, "smin", "SMIN_ZPZZ", int_aarch64_sve_smin, DestructiveBinaryComm>;
- defm UMIN_ZPmZ : sve_int_bin_pred_arit_1<0b011, "umin", "UMIN_ZPZZ", int_aarch64_sve_umin, DestructiveBinaryComm>;
- defm SABD_ZPmZ : sve_int_bin_pred_arit_1<0b100, "sabd", "SABD_ZPZZ", int_aarch64_sve_sabd, DestructiveBinaryComm>;
- defm UABD_ZPmZ : sve_int_bin_pred_arit_1<0b101, "uabd", "UABD_ZPZZ", int_aarch64_sve_uabd, DestructiveBinaryComm>;
-
- defm SMAX_ZPZZ : sve_int_bin_pred_bhsd<AArch64smax_p>;
- defm UMAX_ZPZZ : sve_int_bin_pred_bhsd<AArch64umax_p>;
- defm SMIN_ZPZZ : sve_int_bin_pred_bhsd<AArch64smin_p>;
- defm UMIN_ZPZZ : sve_int_bin_pred_bhsd<AArch64umin_p>;
+ defm SXTB_ZPmZ : sve_int_un_pred_arit_0_h<0b000, "sxtb", AArch64sxt_mt>;
+ defm UXTB_ZPmZ : sve_int_un_pred_arit_0_h<0b001, "uxtb", AArch64uxt_mt>;
+ defm SXTH_ZPmZ : sve_int_un_pred_arit_0_w<0b010, "sxth", AArch64sxt_mt>;
+ defm UXTH_ZPmZ : sve_int_un_pred_arit_0_w<0b011, "uxth", AArch64uxt_mt>;
+ defm SXTW_ZPmZ : sve_int_un_pred_arit_0_d<0b100, "sxtw", AArch64sxt_mt>;
+ defm UXTW_ZPmZ : sve_int_un_pred_arit_0_d<0b101, "uxtw", AArch64uxt_mt>;
+ defm ABS_ZPmZ : sve_int_un_pred_arit_0< 0b110, "abs", AArch64abs_mt>;
+ defm NEG_ZPmZ : sve_int_un_pred_arit_0< 0b111, "neg", AArch64neg_mt>;
+
+ defm CLS_ZPmZ : sve_int_un_pred_arit_1< 0b000, "cls", AArch64cls_mt>;
+ defm CLZ_ZPmZ : sve_int_un_pred_arit_1< 0b001, "clz", AArch64clz_mt>;
+ defm CNT_ZPmZ : sve_int_un_pred_arit_1< 0b010, "cnt", AArch64cnt_mt>;
+ defm CNOT_ZPmZ : sve_int_un_pred_arit_1< 0b011, "cnot", AArch64cnot_mt>;
+ defm NOT_ZPmZ : sve_int_un_pred_arit_1< 0b110, "not", AArch64not_mt>;
+ defm FABS_ZPmZ : sve_int_un_pred_arit_1_fp<0b100, "fabs", AArch64fabs_mt>;
+ defm FNEG_ZPmZ : sve_int_un_pred_arit_1_fp<0b101, "fneg", AArch64fneg_mt>;
+
+ defm SMAX_ZPmZ : sve_int_bin_pred_arit_1<0b000, "smax", "SMAX_ZPZZ", int_aarch64_sve_smax, DestructiveBinaryComm>;
+ defm UMAX_ZPmZ : sve_int_bin_pred_arit_1<0b001, "umax", "UMAX_ZPZZ", int_aarch64_sve_umax, DestructiveBinaryComm>;
+ defm SMIN_ZPmZ : sve_int_bin_pred_arit_1<0b010, "smin", "SMIN_ZPZZ", int_aarch64_sve_smin, DestructiveBinaryComm>;
+ defm UMIN_ZPmZ : sve_int_bin_pred_arit_1<0b011, "umin", "UMIN_ZPZZ", int_aarch64_sve_umin, DestructiveBinaryComm>;
+ defm SABD_ZPmZ : sve_int_bin_pred_arit_1<0b100, "sabd", "SABD_ZPZZ", int_aarch64_sve_sabd, DestructiveBinaryComm>;
+ defm UABD_ZPmZ : sve_int_bin_pred_arit_1<0b101, "uabd", "UABD_ZPZZ", int_aarch64_sve_uabd, DestructiveBinaryComm>;
+
+ defm SMAX_ZPZZ : sve_int_bin_pred_bhsd<AArch64smax_p>;
+ defm UMAX_ZPZZ : sve_int_bin_pred_bhsd<AArch64umax_p>;
+ defm SMIN_ZPZZ : sve_int_bin_pred_bhsd<AArch64smin_p>;
+ defm UMIN_ZPZZ : sve_int_bin_pred_bhsd<AArch64umin_p>;
defm FRECPE_ZZ : sve_fp_2op_u_zd<0b110, "frecpe", int_aarch64_sve_frecpe_x>;
defm FRSQRTE_ZZ : sve_fp_2op_u_zd<0b111, "frsqrte", int_aarch64_sve_frsqrte_x>;
@@ -428,11 +428,11 @@ let Predicates = [HasSVE] in {
defm FDIV_ZPmZ : sve_fp_2op_p_zds<0b1101, "fdiv", "FDIV_ZPZZ", int_aarch64_sve_fdiv, DestructiveBinaryCommWithRev, "FDIVR_ZPmZ">;
defm FADD_ZPZZ : sve_fp_bin_pred_hfd<AArch64fadd_p>;
- defm FSUB_ZPZZ : sve_fp_bin_pred_hfd<AArch64fsub_p>;
- defm FMUL_ZPZZ : sve_fp_bin_pred_hfd<AArch64fmul_p>;
- defm FMAXNM_ZPZZ : sve_fp_bin_pred_hfd<AArch64fmaxnm_p>;
- defm FMINNM_ZPZZ : sve_fp_bin_pred_hfd<AArch64fminnm_p>;
- defm FDIV_ZPZZ : sve_fp_bin_pred_hfd<AArch64fdiv_p>;
+ defm FSUB_ZPZZ : sve_fp_bin_pred_hfd<AArch64fsub_p>;
+ defm FMUL_ZPZZ : sve_fp_bin_pred_hfd<AArch64fmul_p>;
+ defm FMAXNM_ZPZZ : sve_fp_bin_pred_hfd<AArch64fmaxnm_p>;
+ defm FMINNM_ZPZZ : sve_fp_bin_pred_hfd<AArch64fminnm_p>;
+ defm FDIV_ZPZZ : sve_fp_bin_pred_hfd<AArch64fdiv_p>;
let Predicates = [HasSVE, UseExperimentalZeroingPseudos] in {
defm FADD_ZPZZ : sve_fp_2op_p_zds_zeroing_hsd<int_aarch64_sve_fadd>;
@@ -449,10 +449,10 @@ let Predicates = [HasSVE] in {
defm FDIV_ZPZZ : sve_fp_2op_p_zds_zeroing_hsd<int_aarch64_sve_fdiv>;
}
- defm FADD_ZZZ : sve_fp_3op_u_zd<0b000, "fadd", fadd, AArch64fadd_p>;
- defm FSUB_ZZZ : sve_fp_3op_u_zd<0b001, "fsub", fsub, AArch64fsub_p>;
- defm FMUL_ZZZ : sve_fp_3op_u_zd<0b010, "fmul", fmul, AArch64fmul_p>;
- defm FTSMUL_ZZZ : sve_fp_3op_u_zd_ftsmul<0b011, "ftsmul", int_aarch64_sve_ftsmul_x>;
+ defm FADD_ZZZ : sve_fp_3op_u_zd<0b000, "fadd", fadd, AArch64fadd_p>;
+ defm FSUB_ZZZ : sve_fp_3op_u_zd<0b001, "fsub", fsub, AArch64fsub_p>;
+ defm FMUL_ZZZ : sve_fp_3op_u_zd<0b010, "fmul", fmul, AArch64fmul_p>;
+ defm FTSMUL_ZZZ : sve_fp_3op_u_zd_ftsmul<0b011, "ftsmul", int_aarch64_sve_ftsmul_x>;
defm FRECPS_ZZZ : sve_fp_3op_u_zd<0b110, "frecps", int_aarch64_sve_frecps_x>;
defm FRSQRTS_ZZZ : sve_fp_3op_u_zd<0b111, "frsqrts", int_aarch64_sve_frsqrts_x>;
@@ -476,14 +476,14 @@ let Predicates = [HasSVE] in {
// regalloc.
def : Pat<(nxv8f16 (AArch64fma_p nxv8i1:$P, nxv8f16:$Op1, nxv8f16:$Op2, nxv8f16:$Op3)),
(FMLA_ZPmZZ_H $P, $Op3, $Op1, $Op2)>;
- def : Pat<(nxv4f16 (AArch64fma_p nxv4i1:$P, nxv4f16:$Op1, nxv4f16:$Op2, nxv4f16:$Op3)),
- (FMLA_ZPmZZ_H $P, $Op3, $Op1, $Op2)>;
- def : Pat<(nxv2f16 (AArch64fma_p nxv2i1:$P, nxv2f16:$Op1, nxv2f16:$Op2, nxv2f16:$Op3)),
- (FMLA_ZPmZZ_H $P, $Op3, $Op1, $Op2)>;
+ def : Pat<(nxv4f16 (AArch64fma_p nxv4i1:$P, nxv4f16:$Op1, nxv4f16:$Op2, nxv4f16:$Op3)),
+ (FMLA_ZPmZZ_H $P, $Op3, $Op1, $Op2)>;
+ def : Pat<(nxv2f16 (AArch64fma_p nxv2i1:$P, nxv2f16:$Op1, nxv2f16:$Op2, nxv2f16:$Op3)),
+ (FMLA_ZPmZZ_H $P, $Op3, $Op1, $Op2)>;
def : Pat<(nxv4f32 (AArch64fma_p nxv4i1:$P, nxv4f32:$Op1, nxv4f32:$Op2, nxv4f32:$Op3)),
(FMLA_ZPmZZ_S $P, $Op3, $Op1, $Op2)>;
- def : Pat<(nxv2f32 (AArch64fma_p nxv2i1:$P, nxv2f32:$Op1, nxv2f32:$Op2, nxv2f32:$Op3)),
- (FMLA_ZPmZZ_S $P, $Op3, $Op1, $Op2)>;
+ def : Pat<(nxv2f32 (AArch64fma_p nxv2i1:$P, nxv2f32:$Op1, nxv2f32:$Op2, nxv2f32:$Op3)),
+ (FMLA_ZPmZZ_S $P, $Op3, $Op1, $Op2)>;
def : Pat<(nxv2f64 (AArch64fma_p nxv2i1:$P, nxv2f64:$Op1, nxv2f64:$Op2, nxv2f64:$Op3)),
(FMLA_ZPmZZ_D $P, $Op3, $Op1, $Op2)>;
@@ -534,8 +534,8 @@ let Predicates = [HasSVE] in {
(DUP_ZZI_S (INSERT_SUBREG (IMPLICIT_DEF), FPR32:$src, ssub), 0)>;
def : Pat<(nxv2f64 (AArch64dup (f64 FPR64:$src))),
(DUP_ZZI_D (INSERT_SUBREG (IMPLICIT_DEF), FPR64:$src, dsub), 0)>;
- def : Pat<(nxv8bf16 (AArch64dup (bf16 FPR16:$src))),
- (DUP_ZZI_H (INSERT_SUBREG (IMPLICIT_DEF), FPR16:$src, hsub), 0)>;
+ def : Pat<(nxv8bf16 (AArch64dup (bf16 FPR16:$src))),
+ (DUP_ZZI_H (INSERT_SUBREG (IMPLICIT_DEF), FPR16:$src, hsub), 0)>;
// Duplicate +0.0 into all vector elements
def : Pat<(nxv8f16 (AArch64dup (f16 fpimm0))), (DUP_ZI_H 0, 0)>;
@@ -544,7 +544,7 @@ let Predicates = [HasSVE] in {
def : Pat<(nxv4f32 (AArch64dup (f32 fpimm0))), (DUP_ZI_S 0, 0)>;
def : Pat<(nxv2f32 (AArch64dup (f32 fpimm0))), (DUP_ZI_S 0, 0)>;
def : Pat<(nxv2f64 (AArch64dup (f64 fpimm0))), (DUP_ZI_D 0, 0)>;
- def : Pat<(nxv8bf16 (AArch64dup (bf16 fpimm0))), (DUP_ZI_H 0, 0)>;
+ def : Pat<(nxv8bf16 (AArch64dup (bf16 fpimm0))), (DUP_ZI_H 0, 0)>;
// Duplicate Int immediate into all vector elements
def : Pat<(nxv16i8 (AArch64dup (i32 (SVE8BitLslImm i32:$a, i32:$b)))),
@@ -573,7 +573,7 @@ let Predicates = [HasSVE] in {
}
// Select elements from either vector (predicated)
- defm SEL_ZPZZ : sve_int_sel_vvv<"sel", vselect>;
+ defm SEL_ZPZZ : sve_int_sel_vvv<"sel", vselect>;
defm SPLICE_ZPZ : sve_int_perm_splice<"splice", int_aarch64_sve_splice>;
@@ -582,8 +582,8 @@ let Predicates = [HasSVE] in {
defm INSR_ZV : sve_int_perm_insrv<"insr", AArch64insr>;
defm EXT_ZZI : sve_int_perm_extract_i<"ext", AArch64ext>;
- defm RBIT_ZPmZ : sve_int_perm_rev_rbit<"rbit", AArch64rbit_mt>;
- defm REVB_ZPmZ : sve_int_perm_rev_revb<"revb", AArch64revb_mt>;
+ defm RBIT_ZPmZ : sve_int_perm_rev_rbit<"rbit", AArch64rbit_mt>;
+ defm REVB_ZPmZ : sve_int_perm_rev_revb<"revb", AArch64revb_mt>;
defm REVH_ZPmZ : sve_int_perm_rev_revh<"revh", int_aarch64_sve_revh>;
defm REVW_ZPmZ : sve_int_perm_rev_revw<"revw", int_aarch64_sve_revw>;
@@ -1035,7 +1035,7 @@ let Predicates = [HasSVE] in {
def PRFS_PRR : sve_mem_prfm_ss<0b101, "prfw", GPR64NoXZRshifted32>;
def PRFD_PRR : sve_mem_prfm_ss<0b111, "prfd", GPR64NoXZRshifted64>;
- multiclass sve_prefetch<SDPatternOperator prefetch, ValueType PredTy, Instruction RegImmInst, Instruction RegRegInst, int scale, ComplexPattern AddrCP> {
+ multiclass sve_prefetch<SDPatternOperator prefetch, ValueType PredTy, Instruction RegImmInst, Instruction RegRegInst, int scale, ComplexPattern AddrCP> {
// reg + imm
let AddedComplexity = 2 in {
def _reg_imm : Pat<(prefetch (PredTy PPR_3b:$gp), (am_sve_indexed_s6 GPR64sp:$base, simm6s1:$offset), (i32 sve_prfop:$prfop)),
@@ -1145,29 +1145,29 @@ let Predicates = [HasSVE] in {
def : Pat<(nxv8i1 (extract_subvector (nxv16i1 PPR:$Ps), (i64 8))),
(ZIP2_PPP_B PPR:$Ps, (PFALSE))>;
- // Extract subvectors from FP SVE vectors
- def : Pat<(nxv2f16 (extract_subvector (nxv4f16 ZPR:$Zs), (i64 0))),
- (UUNPKLO_ZZ_D ZPR:$Zs)>;
- def : Pat<(nxv2f16 (extract_subvector (nxv4f16 ZPR:$Zs), (i64 2))),
- (UUNPKHI_ZZ_D ZPR:$Zs)>;
- def : Pat<(nxv4f16 (extract_subvector (nxv8f16 ZPR:$Zs), (i64 0))),
- (UUNPKLO_ZZ_S ZPR:$Zs)>;
- def : Pat<(nxv4f16 (extract_subvector (nxv8f16 ZPR:$Zs), (i64 4))),
- (UUNPKHI_ZZ_S ZPR:$Zs)>;
- def : Pat<(nxv2f32 (extract_subvector (nxv4f32 ZPR:$Zs), (i64 0))),
- (UUNPKLO_ZZ_D ZPR:$Zs)>;
- def : Pat<(nxv2f32 (extract_subvector (nxv4f32 ZPR:$Zs), (i64 2))),
- (UUNPKHI_ZZ_D ZPR:$Zs)>;
-
- def : Pat<(nxv2bf16 (extract_subvector (nxv4bf16 ZPR:$Zs), (i64 0))),
- (UUNPKLO_ZZ_D ZPR:$Zs)>;
- def : Pat<(nxv2bf16 (extract_subvector (nxv4bf16 ZPR:$Zs), (i64 2))),
- (UUNPKHI_ZZ_D ZPR:$Zs)>;
- def : Pat<(nxv4bf16 (extract_subvector (nxv8bf16 ZPR:$Zs), (i64 0))),
- (UUNPKLO_ZZ_S ZPR:$Zs)>;
- def : Pat<(nxv4bf16 (extract_subvector (nxv8bf16 ZPR:$Zs), (i64 4))),
- (UUNPKHI_ZZ_S ZPR:$Zs)>;
-
+ // Extract subvectors from FP SVE vectors
+ def : Pat<(nxv2f16 (extract_subvector (nxv4f16 ZPR:$Zs), (i64 0))),
+ (UUNPKLO_ZZ_D ZPR:$Zs)>;
+ def : Pat<(nxv2f16 (extract_subvector (nxv4f16 ZPR:$Zs), (i64 2))),
+ (UUNPKHI_ZZ_D ZPR:$Zs)>;
+ def : Pat<(nxv4f16 (extract_subvector (nxv8f16 ZPR:$Zs), (i64 0))),
+ (UUNPKLO_ZZ_S ZPR:$Zs)>;
+ def : Pat<(nxv4f16 (extract_subvector (nxv8f16 ZPR:$Zs), (i64 4))),
+ (UUNPKHI_ZZ_S ZPR:$Zs)>;
+ def : Pat<(nxv2f32 (extract_subvector (nxv4f32 ZPR:$Zs), (i64 0))),
+ (UUNPKLO_ZZ_D ZPR:$Zs)>;
+ def : Pat<(nxv2f32 (extract_subvector (nxv4f32 ZPR:$Zs), (i64 2))),
+ (UUNPKHI_ZZ_D ZPR:$Zs)>;
+
+ def : Pat<(nxv2bf16 (extract_subvector (nxv4bf16 ZPR:$Zs), (i64 0))),
+ (UUNPKLO_ZZ_D ZPR:$Zs)>;
+ def : Pat<(nxv2bf16 (extract_subvector (nxv4bf16 ZPR:$Zs), (i64 2))),
+ (UUNPKHI_ZZ_D ZPR:$Zs)>;
+ def : Pat<(nxv4bf16 (extract_subvector (nxv8bf16 ZPR:$Zs), (i64 0))),
+ (UUNPKLO_ZZ_S ZPR:$Zs)>;
+ def : Pat<(nxv4bf16 (extract_subvector (nxv8bf16 ZPR:$Zs), (i64 4))),
+ (UUNPKHI_ZZ_S ZPR:$Zs)>;
+
// Concatenate two predicates.
def : Pat<(nxv4i1 (concat_vectors nxv2i1:$p1, nxv2i1:$p2)),
(UZP1_PPP_S $p1, $p2)>;
@@ -1176,18 +1176,18 @@ let Predicates = [HasSVE] in {
def : Pat<(nxv16i1 (concat_vectors nxv8i1:$p1, nxv8i1:$p2)),
(UZP1_PPP_B $p1, $p2)>;
- // Concatenate two floating point vectors.
- def : Pat<(nxv4f16 (concat_vectors nxv2f16:$v1, nxv2f16:$v2)),
- (UZP1_ZZZ_S $v1, $v2)>;
- def : Pat<(nxv8f16 (concat_vectors nxv4f16:$v1, nxv4f16:$v2)),
- (UZP1_ZZZ_H $v1, $v2)>;
- def : Pat<(nxv4f32 (concat_vectors nxv2f32:$v1, nxv2f32:$v2)),
- (UZP1_ZZZ_S $v1, $v2)>;
- def : Pat<(nxv4bf16 (concat_vectors nxv2bf16:$v1, nxv2bf16:$v2)),
- (UZP1_ZZZ_S $v1, $v2)>;
- def : Pat<(nxv8bf16 (concat_vectors nxv4bf16:$v1, nxv4bf16:$v2)),
- (UZP1_ZZZ_H $v1, $v2)>;
-
+ // Concatenate two floating point vectors.
+ def : Pat<(nxv4f16 (concat_vectors nxv2f16:$v1, nxv2f16:$v2)),
+ (UZP1_ZZZ_S $v1, $v2)>;
+ def : Pat<(nxv8f16 (concat_vectors nxv4f16:$v1, nxv4f16:$v2)),
+ (UZP1_ZZZ_H $v1, $v2)>;
+ def : Pat<(nxv4f32 (concat_vectors nxv2f32:$v1, nxv2f32:$v2)),
+ (UZP1_ZZZ_S $v1, $v2)>;
+ def : Pat<(nxv4bf16 (concat_vectors nxv2bf16:$v1, nxv2bf16:$v2)),
+ (UZP1_ZZZ_S $v1, $v2)>;
+ def : Pat<(nxv8bf16 (concat_vectors nxv4bf16:$v1, nxv4bf16:$v2)),
+ (UZP1_ZZZ_H $v1, $v2)>;
+
defm CMPHS_PPzZZ : sve_int_cmp_0<0b000, "cmphs", SETUGE, SETULE>;
defm CMPHI_PPzZZ : sve_int_cmp_0<0b001, "cmphi", SETUGT, SETULT>;
defm CMPGE_PPzZZ : sve_int_cmp_0<0b100, "cmpge", SETGE, SETLE>;
@@ -1217,10 +1217,10 @@ let Predicates = [HasSVE] in {
defm CMPLO_PPzZI : sve_int_ucmp_vi<0b10, "cmplo", SETULT, SETUGT>;
defm CMPLS_PPzZI : sve_int_ucmp_vi<0b11, "cmpls", SETULE, SETUGE>;
- defm FCMGE_PPzZZ : sve_fp_3op_p_pd_cc<0b000, "fcmge", int_aarch64_sve_fcmpge, setoge_or_setge>;
- defm FCMGT_PPzZZ : sve_fp_3op_p_pd_cc<0b001, "fcmgt", int_aarch64_sve_fcmpgt, setogt_or_setgt>;
- defm FCMEQ_PPzZZ : sve_fp_3op_p_pd_cc<0b010, "fcmeq", int_aarch64_sve_fcmpeq, setoeq_or_seteq>;
- defm FCMNE_PPzZZ : sve_fp_3op_p_pd_cc<0b011, "fcmne", int_aarch64_sve_fcmpne, setone_or_setne>;
+ defm FCMGE_PPzZZ : sve_fp_3op_p_pd_cc<0b000, "fcmge", int_aarch64_sve_fcmpge, setoge_or_setge>;
+ defm FCMGT_PPzZZ : sve_fp_3op_p_pd_cc<0b001, "fcmgt", int_aarch64_sve_fcmpgt, setogt_or_setgt>;
+ defm FCMEQ_PPzZZ : sve_fp_3op_p_pd_cc<0b010, "fcmeq", int_aarch64_sve_fcmpeq, setoeq_or_seteq>;
+ defm FCMNE_PPzZZ : sve_fp_3op_p_pd_cc<0b011, "fcmne", int_aarch64_sve_fcmpne, setone_or_setne>;
defm FCMUO_PPzZZ : sve_fp_3op_p_pd_cc<0b100, "fcmuo", int_aarch64_sve_fcmpuo, setuo>;
defm FACGE_PPzZZ : sve_fp_3op_p_pd<0b101, "facge", int_aarch64_sve_facge>;
defm FACGT_PPzZZ : sve_fp_3op_p_pd<0b111, "facgt", int_aarch64_sve_facgt>;
@@ -1345,146 +1345,146 @@ let Predicates = [HasSVE] in {
defm INDEX_II : sve_int_index_ii<"index", index_vector>;
// Unpredicated shifts
- defm ASR_ZZI : sve_int_bin_cons_shift_imm_right<0b00, "asr", AArch64asr_p>;
- defm LSR_ZZI : sve_int_bin_cons_shift_imm_right<0b01, "lsr", AArch64lsr_p>;
- defm LSL_ZZI : sve_int_bin_cons_shift_imm_left< 0b11, "lsl", AArch64lsl_p>;
+ defm ASR_ZZI : sve_int_bin_cons_shift_imm_right<0b00, "asr", AArch64asr_p>;
+ defm LSR_ZZI : sve_int_bin_cons_shift_imm_right<0b01, "lsr", AArch64lsr_p>;
+ defm LSL_ZZI : sve_int_bin_cons_shift_imm_left< 0b11, "lsl", AArch64lsl_p>;
defm ASR_WIDE_ZZZ : sve_int_bin_cons_shift_wide<0b00, "asr">;
defm LSR_WIDE_ZZZ : sve_int_bin_cons_shift_wide<0b01, "lsr">;
defm LSL_WIDE_ZZZ : sve_int_bin_cons_shift_wide<0b11, "lsl">;
// Predicated shifts
- defm ASR_ZPmI : sve_int_bin_pred_shift_imm_right_dup<0b0000, "asr", "ASR_ZPZI", int_aarch64_sve_asr>;
- defm LSR_ZPmI : sve_int_bin_pred_shift_imm_right_dup<0b0001, "lsr", "LSR_ZPZI", int_aarch64_sve_lsr>;
- defm LSL_ZPmI : sve_int_bin_pred_shift_imm_left_dup< 0b0011, "lsl", "LSL_ZPZI", int_aarch64_sve_lsl>;
- defm ASRD_ZPmI : sve_int_bin_pred_shift_imm_right< 0b0100, "asrd", "ASRD_ZPZI", int_aarch64_sve_asrd>;
-
- defm ASR_ZPZI : sve_int_shift_pred_bhsd<AArch64asr_p, SVEShiftImmR8, SVEShiftImmR16, SVEShiftImmR32, SVEShiftImmR64>;
- defm LSR_ZPZI : sve_int_shift_pred_bhsd<AArch64lsr_p, SVEShiftImmR8, SVEShiftImmR16, SVEShiftImmR32, SVEShiftImmR64>;
- defm LSL_ZPZI : sve_int_shift_pred_bhsd<AArch64lsl_p, SVEShiftImmL8, SVEShiftImmL16, SVEShiftImmL32, SVEShiftImmL64>;
-
+ defm ASR_ZPmI : sve_int_bin_pred_shift_imm_right_dup<0b0000, "asr", "ASR_ZPZI", int_aarch64_sve_asr>;
+ defm LSR_ZPmI : sve_int_bin_pred_shift_imm_right_dup<0b0001, "lsr", "LSR_ZPZI", int_aarch64_sve_lsr>;
+ defm LSL_ZPmI : sve_int_bin_pred_shift_imm_left_dup< 0b0011, "lsl", "LSL_ZPZI", int_aarch64_sve_lsl>;
+ defm ASRD_ZPmI : sve_int_bin_pred_shift_imm_right< 0b0100, "asrd", "ASRD_ZPZI", int_aarch64_sve_asrd>;
+
+ defm ASR_ZPZI : sve_int_shift_pred_bhsd<AArch64asr_p, SVEShiftImmR8, SVEShiftImmR16, SVEShiftImmR32, SVEShiftImmR64>;
+ defm LSR_ZPZI : sve_int_shift_pred_bhsd<AArch64lsr_p, SVEShiftImmR8, SVEShiftImmR16, SVEShiftImmR32, SVEShiftImmR64>;
+ defm LSL_ZPZI : sve_int_shift_pred_bhsd<AArch64lsl_p, SVEShiftImmL8, SVEShiftImmL16, SVEShiftImmL32, SVEShiftImmL64>;
+
let Predicates = [HasSVE, UseExperimentalZeroingPseudos] in {
- defm ASR_ZPZZ : sve_int_bin_pred_zeroing_bhsd<int_aarch64_sve_asr>;
- defm LSR_ZPZZ : sve_int_bin_pred_zeroing_bhsd<int_aarch64_sve_lsr>;
- defm LSL_ZPZZ : sve_int_bin_pred_zeroing_bhsd<int_aarch64_sve_lsl>;
+ defm ASR_ZPZZ : sve_int_bin_pred_zeroing_bhsd<int_aarch64_sve_asr>;
+ defm LSR_ZPZZ : sve_int_bin_pred_zeroing_bhsd<int_aarch64_sve_lsr>;
+ defm LSL_ZPZZ : sve_int_bin_pred_zeroing_bhsd<int_aarch64_sve_lsl>;
defm ASRD_ZPZI : sve_int_bin_pred_shift_imm_right_zeroing_bhsd<int_aarch64_sve_asrd>;
}
- defm ASR_ZPmZ : sve_int_bin_pred_shift<0b000, "asr", "ASR_ZPZZ", int_aarch64_sve_asr, "ASRR_ZPmZ">;
- defm LSR_ZPmZ : sve_int_bin_pred_shift<0b001, "lsr", "LSR_ZPZZ", int_aarch64_sve_lsr, "LSRR_ZPmZ">;
- defm LSL_ZPmZ : sve_int_bin_pred_shift<0b011, "lsl", "LSL_ZPZZ", int_aarch64_sve_lsl, "LSLR_ZPmZ">;
+ defm ASR_ZPmZ : sve_int_bin_pred_shift<0b000, "asr", "ASR_ZPZZ", int_aarch64_sve_asr, "ASRR_ZPmZ">;
+ defm LSR_ZPmZ : sve_int_bin_pred_shift<0b001, "lsr", "LSR_ZPZZ", int_aarch64_sve_lsr, "LSRR_ZPmZ">;
+ defm LSL_ZPmZ : sve_int_bin_pred_shift<0b011, "lsl", "LSL_ZPZZ", int_aarch64_sve_lsl, "LSLR_ZPmZ">;
defm ASRR_ZPmZ : sve_int_bin_pred_shift<0b100, "asrr", "ASRR_ZPZZ", null_frag, "ASR_ZPmZ", /*isReverseInstr*/ 1>;
defm LSRR_ZPmZ : sve_int_bin_pred_shift<0b101, "lsrr", "LSRR_ZPZZ", null_frag, "LSR_ZPmZ", /*isReverseInstr*/ 1>;
defm LSLR_ZPmZ : sve_int_bin_pred_shift<0b111, "lslr", "LSLR_ZPZZ", null_frag, "LSL_ZPmZ", /*isReverseInstr*/ 1>;
- defm ASR_ZPZZ : sve_int_bin_pred_bhsd<AArch64asr_p>;
- defm LSR_ZPZZ : sve_int_bin_pred_bhsd<AArch64lsr_p>;
- defm LSL_ZPZZ : sve_int_bin_pred_bhsd<AArch64lsl_p>;
-
+ defm ASR_ZPZZ : sve_int_bin_pred_bhsd<AArch64asr_p>;
+ defm LSR_ZPZZ : sve_int_bin_pred_bhsd<AArch64lsr_p>;
+ defm LSL_ZPZZ : sve_int_bin_pred_bhsd<AArch64lsl_p>;
+
defm ASR_WIDE_ZPmZ : sve_int_bin_pred_shift_wide<0b000, "asr", int_aarch64_sve_asr_wide>;
defm LSR_WIDE_ZPmZ : sve_int_bin_pred_shift_wide<0b001, "lsr", int_aarch64_sve_lsr_wide>;
defm LSL_WIDE_ZPmZ : sve_int_bin_pred_shift_wide<0b011, "lsl", int_aarch64_sve_lsl_wide>;
- defm FCVT_ZPmZ_StoH : sve_fp_2op_p_zdr<0b1001000, "fcvt", ZPR32, ZPR16, int_aarch64_sve_fcvt_f16f32, AArch64fcvtr_mt, nxv4f16, nxv4i1, nxv4f32, ElementSizeS>;
- defm FCVT_ZPmZ_HtoS : sve_fp_2op_p_zd< 0b1001001, "fcvt", ZPR16, ZPR32, int_aarch64_sve_fcvt_f32f16, AArch64fcvte_mt, nxv4f32, nxv4i1, nxv4f16, ElementSizeS>;
- defm SCVTF_ZPmZ_HtoH : sve_fp_2op_p_zd< 0b0110010, "scvtf", ZPR16, ZPR16, null_frag, AArch64scvtf_mt, nxv8f16, nxv8i1, nxv8i16, ElementSizeH>;
- defm SCVTF_ZPmZ_StoS : sve_fp_2op_p_zd< 0b1010100, "scvtf", ZPR32, ZPR32, null_frag, AArch64scvtf_mt, nxv4f32, nxv4i1, nxv4i32, ElementSizeS>;
- defm UCVTF_ZPmZ_StoS : sve_fp_2op_p_zd< 0b1010101, "ucvtf", ZPR32, ZPR32, null_frag, AArch64ucvtf_mt, nxv4f32, nxv4i1, nxv4i32, ElementSizeS>;
- defm UCVTF_ZPmZ_HtoH : sve_fp_2op_p_zd< 0b0110011, "ucvtf", ZPR16, ZPR16, null_frag, AArch64ucvtf_mt, nxv8f16, nxv8i1, nxv8i16, ElementSizeH>;
- defm FCVTZS_ZPmZ_HtoH : sve_fp_2op_p_zd< 0b0111010, "fcvtzs", ZPR16, ZPR16, null_frag, AArch64fcvtzs_mt, nxv8i16, nxv8i1, nxv8f16, ElementSizeH>;
- defm FCVTZS_ZPmZ_StoS : sve_fp_2op_p_zd< 0b1011100, "fcvtzs", ZPR32, ZPR32, null_frag, AArch64fcvtzs_mt, nxv4i32, nxv4i1, nxv4f32, ElementSizeS>;
- defm FCVTZU_ZPmZ_HtoH : sve_fp_2op_p_zd< 0b0111011, "fcvtzu", ZPR16, ZPR16, null_frag, AArch64fcvtzu_mt, nxv8i16, nxv8i1, nxv8f16, ElementSizeH>;
- defm FCVTZU_ZPmZ_StoS : sve_fp_2op_p_zd< 0b1011101, "fcvtzu", ZPR32, ZPR32, null_frag, AArch64fcvtzu_mt, nxv4i32, nxv4i1, nxv4f32, ElementSizeS>;
- defm FCVT_ZPmZ_DtoH : sve_fp_2op_p_zdr<0b1101000, "fcvt", ZPR64, ZPR16, int_aarch64_sve_fcvt_f16f64, AArch64fcvtr_mt, nxv2f16, nxv2i1, nxv2f64, ElementSizeD>;
- defm FCVT_ZPmZ_HtoD : sve_fp_2op_p_zd< 0b1101001, "fcvt", ZPR16, ZPR64, int_aarch64_sve_fcvt_f64f16, AArch64fcvte_mt, nxv2f64, nxv2i1, nxv2f16, ElementSizeD>;
- defm FCVT_ZPmZ_DtoS : sve_fp_2op_p_zdr<0b1101010, "fcvt", ZPR64, ZPR32, int_aarch64_sve_fcvt_f32f64, AArch64fcvtr_mt, nxv2f32, nxv2i1, nxv2f64, ElementSizeD>;
- defm FCVT_ZPmZ_StoD : sve_fp_2op_p_zd< 0b1101011, "fcvt", ZPR32, ZPR64, int_aarch64_sve_fcvt_f64f32, AArch64fcvte_mt, nxv2f64, nxv2i1, nxv2f32, ElementSizeD>;
- defm SCVTF_ZPmZ_StoD : sve_fp_2op_p_zd< 0b1110000, "scvtf", ZPR32, ZPR64, int_aarch64_sve_scvtf_f64i32, AArch64scvtf_mt, nxv2f64, nxv2i1, nxv4i32, ElementSizeD>;
- defm UCVTF_ZPmZ_StoD : sve_fp_2op_p_zd< 0b1110001, "ucvtf", ZPR32, ZPR64, int_aarch64_sve_ucvtf_f64i32, AArch64ucvtf_mt, nxv2f64, nxv2i1, nxv4i32, ElementSizeD>;
- defm UCVTF_ZPmZ_StoH : sve_fp_2op_p_zd< 0b0110101, "ucvtf", ZPR32, ZPR16, int_aarch64_sve_ucvtf_f16i32, AArch64ucvtf_mt, nxv4f16, nxv4i1, nxv4i32, ElementSizeS>;
- defm SCVTF_ZPmZ_DtoS : sve_fp_2op_p_zd< 0b1110100, "scvtf", ZPR64, ZPR32, int_aarch64_sve_scvtf_f32i64, AArch64scvtf_mt, nxv2f32, nxv2i1, nxv2i64, ElementSizeD>;
- defm SCVTF_ZPmZ_StoH : sve_fp_2op_p_zd< 0b0110100, "scvtf", ZPR32, ZPR16, int_aarch64_sve_scvtf_f16i32, AArch64scvtf_mt, nxv4f16, nxv4i1, nxv4i32, ElementSizeS>;
- defm SCVTF_ZPmZ_DtoH : sve_fp_2op_p_zd< 0b0110110, "scvtf", ZPR64, ZPR16, int_aarch64_sve_scvtf_f16i64, AArch64scvtf_mt, nxv2f16, nxv2i1, nxv2i64, ElementSizeD>;
- defm UCVTF_ZPmZ_DtoS : sve_fp_2op_p_zd< 0b1110101, "ucvtf", ZPR64, ZPR32, int_aarch64_sve_ucvtf_f32i64, AArch64ucvtf_mt, nxv2f32, nxv2i1, nxv2i64, ElementSizeD>;
- defm UCVTF_ZPmZ_DtoH : sve_fp_2op_p_zd< 0b0110111, "ucvtf", ZPR64, ZPR16, int_aarch64_sve_ucvtf_f16i64, AArch64ucvtf_mt, nxv2f16, nxv2i1, nxv2i64, ElementSizeD>;
- defm SCVTF_ZPmZ_DtoD : sve_fp_2op_p_zd< 0b1110110, "scvtf", ZPR64, ZPR64, null_frag, AArch64scvtf_mt, nxv2f64, nxv2i1, nxv2i64, ElementSizeD>;
- defm UCVTF_ZPmZ_DtoD : sve_fp_2op_p_zd< 0b1110111, "ucvtf", ZPR64, ZPR64, null_frag, AArch64ucvtf_mt, nxv2f64, nxv2i1, nxv2i64, ElementSizeD>;
- defm FCVTZS_ZPmZ_DtoS : sve_fp_2op_p_zd< 0b1111000, "fcvtzs", ZPR64, ZPR32, int_aarch64_sve_fcvtzs_i32f64, null_frag, nxv4i32, nxv2i1, nxv2f64, ElementSizeD>;
- defm FCVTZU_ZPmZ_DtoS : sve_fp_2op_p_zd< 0b1111001, "fcvtzu", ZPR64, ZPR32, int_aarch64_sve_fcvtzu_i32f64, null_frag, nxv4i32, nxv2i1, nxv2f64, ElementSizeD>;
- defm FCVTZS_ZPmZ_StoD : sve_fp_2op_p_zd< 0b1111100, "fcvtzs", ZPR32, ZPR64, int_aarch64_sve_fcvtzs_i64f32, AArch64fcvtzs_mt, nxv2i64, nxv2i1, nxv2f32, ElementSizeD>;
- defm FCVTZS_ZPmZ_HtoS : sve_fp_2op_p_zd< 0b0111100, "fcvtzs", ZPR16, ZPR32, int_aarch64_sve_fcvtzs_i32f16, AArch64fcvtzs_mt, nxv4i32, nxv4i1, nxv4f16, ElementSizeS>;
- defm FCVTZS_ZPmZ_HtoD : sve_fp_2op_p_zd< 0b0111110, "fcvtzs", ZPR16, ZPR64, int_aarch64_sve_fcvtzs_i64f16, AArch64fcvtzs_mt, nxv2i64, nxv2i1, nxv2f16, ElementSizeD>;
- defm FCVTZU_ZPmZ_HtoS : sve_fp_2op_p_zd< 0b0111101, "fcvtzu", ZPR16, ZPR32, int_aarch64_sve_fcvtzu_i32f16, AArch64fcvtzu_mt, nxv4i32, nxv4i1, nxv4f16, ElementSizeS>;
- defm FCVTZU_ZPmZ_HtoD : sve_fp_2op_p_zd< 0b0111111, "fcvtzu", ZPR16, ZPR64, int_aarch64_sve_fcvtzu_i64f16, AArch64fcvtzu_mt, nxv2i64, nxv2i1, nxv2f16, ElementSizeD>;
- defm FCVTZU_ZPmZ_StoD : sve_fp_2op_p_zd< 0b1111101, "fcvtzu", ZPR32, ZPR64, int_aarch64_sve_fcvtzu_i64f32, AArch64fcvtzu_mt, nxv2i64, nxv2i1, nxv2f32, ElementSizeD>;
- defm FCVTZS_ZPmZ_DtoD : sve_fp_2op_p_zd< 0b1111110, "fcvtzs", ZPR64, ZPR64, null_frag, AArch64fcvtzs_mt, nxv2i64, nxv2i1, nxv2f64, ElementSizeD>;
- defm FCVTZU_ZPmZ_DtoD : sve_fp_2op_p_zd< 0b1111111, "fcvtzu", ZPR64, ZPR64, null_frag, AArch64fcvtzu_mt, nxv2i64, nxv2i1, nxv2f64, ElementSizeD>;
-
- def : Pat<(nxv2f32 (AArch64fcvte_mt (nxv2i1 PPR:$Pg), (nxv2f16 ZPR:$Zs), (nxv2f32 ZPR:$Zd))),
- (FCVT_ZPmZ_HtoS ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
-
- // FP_ROUND has an additional 'precise' flag which indicates the type of rounding.
- // This is ignored by the pattern below where it is matched by (i64 timm0_1)
- def : Pat<(nxv2f16 (AArch64fcvtr_mt (nxv2i1 PPR:$Pg), (nxv2f32 ZPR:$Zs), (i64 timm0_1), (nxv2f16 ZPR:$Zd))),
- (FCVT_ZPmZ_StoH ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
-
- // Floating-point -> signed integer
- def : Pat<(nxv2f16 (AArch64scvtf_mt (nxv2i1 PPR:$Pg),
- (sext_inreg (nxv2i64 ZPR:$Zs), nxv2i16), (nxv2f16 ZPR:$Zd))),
- (SCVTF_ZPmZ_HtoH ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
-
- def : Pat<(nxv4f16 (AArch64scvtf_mt (nxv4i1 PPR:$Pg),
- (sext_inreg (nxv4i32 ZPR:$Zs), nxv4i16), (nxv4f16 ZPR:$Zd))),
- (SCVTF_ZPmZ_HtoH ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
-
- def : Pat<(nxv2f16 (AArch64scvtf_mt (nxv2i1 PPR:$Pg),
- (sext_inreg (nxv2i64 ZPR:$Zs), nxv2i32), (nxv2f16 ZPR:$Zd))),
- (SCVTF_ZPmZ_StoH ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
-
- def : Pat<(nxv2f32 (AArch64scvtf_mt (nxv2i1 PPR:$Pg),
- (sext_inreg (nxv2i64 ZPR:$Zs), nxv2i32), (nxv2f32 ZPR:$Zd))),
- (SCVTF_ZPmZ_StoS ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
-
- def : Pat<(nxv2f64 (AArch64scvtf_mt (nxv2i1 PPR:$Pg),
- (sext_inreg (nxv2i64 ZPR:$Zs), nxv2i32), (nxv2f64 ZPR:$Zd))),
- (SCVTF_ZPmZ_StoD ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
-
- // Floating-point -> unsigned integer
- def : Pat<(nxv2f16 (AArch64ucvtf_mt (nxv2i1 PPR:$Pg),
- (and (nxv2i64 ZPR:$Zs),
- (nxv2i64 (AArch64dup (i64 0xFFFF)))), (nxv2f16 ZPR:$Zd))),
- (UCVTF_ZPmZ_HtoH ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
-
- def : Pat<(nxv2f16 (AArch64ucvtf_mt (nxv2i1 PPR:$Pg),
- (and (nxv2i64 ZPR:$Zs),
- (nxv2i64 (AArch64dup (i64 0xFFFFFFFF)))), (nxv2f16 ZPR:$Zd))),
- (UCVTF_ZPmZ_StoH ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
-
- def : Pat<(nxv4f16 (AArch64ucvtf_mt (nxv4i1 PPR:$Pg),
- (and (nxv4i32 ZPR:$Zs),
- (nxv4i32 (AArch64dup (i32 0xFFFF)))), (nxv4f16 ZPR:$Zd))),
- (UCVTF_ZPmZ_HtoH ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
-
- def : Pat<(nxv2f32 (AArch64ucvtf_mt (nxv2i1 PPR:$Pg),
- (and (nxv2i64 ZPR:$Zs),
- (nxv2i64 (AArch64dup (i64 0xFFFFFFFF)))), (nxv2f32 ZPR:$Zd))),
- (UCVTF_ZPmZ_StoS ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
-
- def : Pat<(nxv2f64 (AArch64ucvtf_mt (nxv2i1 PPR:$Pg),
- (and (nxv2i64 ZPR:$Zs),
- (nxv2i64 (AArch64dup (i64 0xFFFFFFFF)))), (nxv2f64 ZPR:$Zd))),
- (UCVTF_ZPmZ_StoD ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
-
- defm FRINTN_ZPmZ : sve_fp_2op_p_zd_HSD<0b00000, "frintn", AArch64frintn_mt>;
- defm FRINTP_ZPmZ : sve_fp_2op_p_zd_HSD<0b00001, "frintp", AArch64frintp_mt>;
- defm FRINTM_ZPmZ : sve_fp_2op_p_zd_HSD<0b00010, "frintm", AArch64frintm_mt>;
- defm FRINTZ_ZPmZ : sve_fp_2op_p_zd_HSD<0b00011, "frintz", AArch64frintz_mt>;
- defm FRINTA_ZPmZ : sve_fp_2op_p_zd_HSD<0b00100, "frinta", AArch64frinta_mt>;
- defm FRINTX_ZPmZ : sve_fp_2op_p_zd_HSD<0b00110, "frintx", AArch64frintx_mt>;
- defm FRINTI_ZPmZ : sve_fp_2op_p_zd_HSD<0b00111, "frinti", AArch64frinti_mt>;
- defm FRECPX_ZPmZ : sve_fp_2op_p_zd_HSD<0b01100, "frecpx", AArch64frecpx_mt>;
- defm FSQRT_ZPmZ : sve_fp_2op_p_zd_HSD<0b01101, "fsqrt", AArch64fsqrt_mt>;
-
+ defm FCVT_ZPmZ_StoH : sve_fp_2op_p_zdr<0b1001000, "fcvt", ZPR32, ZPR16, int_aarch64_sve_fcvt_f16f32, AArch64fcvtr_mt, nxv4f16, nxv4i1, nxv4f32, ElementSizeS>;
+ defm FCVT_ZPmZ_HtoS : sve_fp_2op_p_zd< 0b1001001, "fcvt", ZPR16, ZPR32, int_aarch64_sve_fcvt_f32f16, AArch64fcvte_mt, nxv4f32, nxv4i1, nxv4f16, ElementSizeS>;
+ defm SCVTF_ZPmZ_HtoH : sve_fp_2op_p_zd< 0b0110010, "scvtf", ZPR16, ZPR16, null_frag, AArch64scvtf_mt, nxv8f16, nxv8i1, nxv8i16, ElementSizeH>;
+ defm SCVTF_ZPmZ_StoS : sve_fp_2op_p_zd< 0b1010100, "scvtf", ZPR32, ZPR32, null_frag, AArch64scvtf_mt, nxv4f32, nxv4i1, nxv4i32, ElementSizeS>;
+ defm UCVTF_ZPmZ_StoS : sve_fp_2op_p_zd< 0b1010101, "ucvtf", ZPR32, ZPR32, null_frag, AArch64ucvtf_mt, nxv4f32, nxv4i1, nxv4i32, ElementSizeS>;
+ defm UCVTF_ZPmZ_HtoH : sve_fp_2op_p_zd< 0b0110011, "ucvtf", ZPR16, ZPR16, null_frag, AArch64ucvtf_mt, nxv8f16, nxv8i1, nxv8i16, ElementSizeH>;
+ defm FCVTZS_ZPmZ_HtoH : sve_fp_2op_p_zd< 0b0111010, "fcvtzs", ZPR16, ZPR16, null_frag, AArch64fcvtzs_mt, nxv8i16, nxv8i1, nxv8f16, ElementSizeH>;
+ defm FCVTZS_ZPmZ_StoS : sve_fp_2op_p_zd< 0b1011100, "fcvtzs", ZPR32, ZPR32, null_frag, AArch64fcvtzs_mt, nxv4i32, nxv4i1, nxv4f32, ElementSizeS>;
+ defm FCVTZU_ZPmZ_HtoH : sve_fp_2op_p_zd< 0b0111011, "fcvtzu", ZPR16, ZPR16, null_frag, AArch64fcvtzu_mt, nxv8i16, nxv8i1, nxv8f16, ElementSizeH>;
+ defm FCVTZU_ZPmZ_StoS : sve_fp_2op_p_zd< 0b1011101, "fcvtzu", ZPR32, ZPR32, null_frag, AArch64fcvtzu_mt, nxv4i32, nxv4i1, nxv4f32, ElementSizeS>;
+ defm FCVT_ZPmZ_DtoH : sve_fp_2op_p_zdr<0b1101000, "fcvt", ZPR64, ZPR16, int_aarch64_sve_fcvt_f16f64, AArch64fcvtr_mt, nxv2f16, nxv2i1, nxv2f64, ElementSizeD>;
+ defm FCVT_ZPmZ_HtoD : sve_fp_2op_p_zd< 0b1101001, "fcvt", ZPR16, ZPR64, int_aarch64_sve_fcvt_f64f16, AArch64fcvte_mt, nxv2f64, nxv2i1, nxv2f16, ElementSizeD>;
+ defm FCVT_ZPmZ_DtoS : sve_fp_2op_p_zdr<0b1101010, "fcvt", ZPR64, ZPR32, int_aarch64_sve_fcvt_f32f64, AArch64fcvtr_mt, nxv2f32, nxv2i1, nxv2f64, ElementSizeD>;
+ defm FCVT_ZPmZ_StoD : sve_fp_2op_p_zd< 0b1101011, "fcvt", ZPR32, ZPR64, int_aarch64_sve_fcvt_f64f32, AArch64fcvte_mt, nxv2f64, nxv2i1, nxv2f32, ElementSizeD>;
+ defm SCVTF_ZPmZ_StoD : sve_fp_2op_p_zd< 0b1110000, "scvtf", ZPR32, ZPR64, int_aarch64_sve_scvtf_f64i32, AArch64scvtf_mt, nxv2f64, nxv2i1, nxv4i32, ElementSizeD>;
+ defm UCVTF_ZPmZ_StoD : sve_fp_2op_p_zd< 0b1110001, "ucvtf", ZPR32, ZPR64, int_aarch64_sve_ucvtf_f64i32, AArch64ucvtf_mt, nxv2f64, nxv2i1, nxv4i32, ElementSizeD>;
+ defm UCVTF_ZPmZ_StoH : sve_fp_2op_p_zd< 0b0110101, "ucvtf", ZPR32, ZPR16, int_aarch64_sve_ucvtf_f16i32, AArch64ucvtf_mt, nxv4f16, nxv4i1, nxv4i32, ElementSizeS>;
+ defm SCVTF_ZPmZ_DtoS : sve_fp_2op_p_zd< 0b1110100, "scvtf", ZPR64, ZPR32, int_aarch64_sve_scvtf_f32i64, AArch64scvtf_mt, nxv2f32, nxv2i1, nxv2i64, ElementSizeD>;
+ defm SCVTF_ZPmZ_StoH : sve_fp_2op_p_zd< 0b0110100, "scvtf", ZPR32, ZPR16, int_aarch64_sve_scvtf_f16i32, AArch64scvtf_mt, nxv4f16, nxv4i1, nxv4i32, ElementSizeS>;
+ defm SCVTF_ZPmZ_DtoH : sve_fp_2op_p_zd< 0b0110110, "scvtf", ZPR64, ZPR16, int_aarch64_sve_scvtf_f16i64, AArch64scvtf_mt, nxv2f16, nxv2i1, nxv2i64, ElementSizeD>;
+ defm UCVTF_ZPmZ_DtoS : sve_fp_2op_p_zd< 0b1110101, "ucvtf", ZPR64, ZPR32, int_aarch64_sve_ucvtf_f32i64, AArch64ucvtf_mt, nxv2f32, nxv2i1, nxv2i64, ElementSizeD>;
+ defm UCVTF_ZPmZ_DtoH : sve_fp_2op_p_zd< 0b0110111, "ucvtf", ZPR64, ZPR16, int_aarch64_sve_ucvtf_f16i64, AArch64ucvtf_mt, nxv2f16, nxv2i1, nxv2i64, ElementSizeD>;
+ defm SCVTF_ZPmZ_DtoD : sve_fp_2op_p_zd< 0b1110110, "scvtf", ZPR64, ZPR64, null_frag, AArch64scvtf_mt, nxv2f64, nxv2i1, nxv2i64, ElementSizeD>;
+ defm UCVTF_ZPmZ_DtoD : sve_fp_2op_p_zd< 0b1110111, "ucvtf", ZPR64, ZPR64, null_frag, AArch64ucvtf_mt, nxv2f64, nxv2i1, nxv2i64, ElementSizeD>;
+ defm FCVTZS_ZPmZ_DtoS : sve_fp_2op_p_zd< 0b1111000, "fcvtzs", ZPR64, ZPR32, int_aarch64_sve_fcvtzs_i32f64, null_frag, nxv4i32, nxv2i1, nxv2f64, ElementSizeD>;
+ defm FCVTZU_ZPmZ_DtoS : sve_fp_2op_p_zd< 0b1111001, "fcvtzu", ZPR64, ZPR32, int_aarch64_sve_fcvtzu_i32f64, null_frag, nxv4i32, nxv2i1, nxv2f64, ElementSizeD>;
+ defm FCVTZS_ZPmZ_StoD : sve_fp_2op_p_zd< 0b1111100, "fcvtzs", ZPR32, ZPR64, int_aarch64_sve_fcvtzs_i64f32, AArch64fcvtzs_mt, nxv2i64, nxv2i1, nxv2f32, ElementSizeD>;
+ defm FCVTZS_ZPmZ_HtoS : sve_fp_2op_p_zd< 0b0111100, "fcvtzs", ZPR16, ZPR32, int_aarch64_sve_fcvtzs_i32f16, AArch64fcvtzs_mt, nxv4i32, nxv4i1, nxv4f16, ElementSizeS>;
+ defm FCVTZS_ZPmZ_HtoD : sve_fp_2op_p_zd< 0b0111110, "fcvtzs", ZPR16, ZPR64, int_aarch64_sve_fcvtzs_i64f16, AArch64fcvtzs_mt, nxv2i64, nxv2i1, nxv2f16, ElementSizeD>;
+ defm FCVTZU_ZPmZ_HtoS : sve_fp_2op_p_zd< 0b0111101, "fcvtzu", ZPR16, ZPR32, int_aarch64_sve_fcvtzu_i32f16, AArch64fcvtzu_mt, nxv4i32, nxv4i1, nxv4f16, ElementSizeS>;
+ defm FCVTZU_ZPmZ_HtoD : sve_fp_2op_p_zd< 0b0111111, "fcvtzu", ZPR16, ZPR64, int_aarch64_sve_fcvtzu_i64f16, AArch64fcvtzu_mt, nxv2i64, nxv2i1, nxv2f16, ElementSizeD>;
+ defm FCVTZU_ZPmZ_StoD : sve_fp_2op_p_zd< 0b1111101, "fcvtzu", ZPR32, ZPR64, int_aarch64_sve_fcvtzu_i64f32, AArch64fcvtzu_mt, nxv2i64, nxv2i1, nxv2f32, ElementSizeD>;
+ defm FCVTZS_ZPmZ_DtoD : sve_fp_2op_p_zd< 0b1111110, "fcvtzs", ZPR64, ZPR64, null_frag, AArch64fcvtzs_mt, nxv2i64, nxv2i1, nxv2f64, ElementSizeD>;
+ defm FCVTZU_ZPmZ_DtoD : sve_fp_2op_p_zd< 0b1111111, "fcvtzu", ZPR64, ZPR64, null_frag, AArch64fcvtzu_mt, nxv2i64, nxv2i1, nxv2f64, ElementSizeD>;
+
+ def : Pat<(nxv2f32 (AArch64fcvte_mt (nxv2i1 PPR:$Pg), (nxv2f16 ZPR:$Zs), (nxv2f32 ZPR:$Zd))),
+ (FCVT_ZPmZ_HtoS ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
+
+ // FP_ROUND has an additional 'precise' flag which indicates the type of rounding.
+ // This is ignored by the pattern below where it is matched by (i64 timm0_1)
+ def : Pat<(nxv2f16 (AArch64fcvtr_mt (nxv2i1 PPR:$Pg), (nxv2f32 ZPR:$Zs), (i64 timm0_1), (nxv2f16 ZPR:$Zd))),
+ (FCVT_ZPmZ_StoH ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
+
+ // Floating-point -> signed integer
+ def : Pat<(nxv2f16 (AArch64scvtf_mt (nxv2i1 PPR:$Pg),
+ (sext_inreg (nxv2i64 ZPR:$Zs), nxv2i16), (nxv2f16 ZPR:$Zd))),
+ (SCVTF_ZPmZ_HtoH ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
+
+ def : Pat<(nxv4f16 (AArch64scvtf_mt (nxv4i1 PPR:$Pg),
+ (sext_inreg (nxv4i32 ZPR:$Zs), nxv4i16), (nxv4f16 ZPR:$Zd))),
+ (SCVTF_ZPmZ_HtoH ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
+
+ def : Pat<(nxv2f16 (AArch64scvtf_mt (nxv2i1 PPR:$Pg),
+ (sext_inreg (nxv2i64 ZPR:$Zs), nxv2i32), (nxv2f16 ZPR:$Zd))),
+ (SCVTF_ZPmZ_StoH ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
+
+ def : Pat<(nxv2f32 (AArch64scvtf_mt (nxv2i1 PPR:$Pg),
+ (sext_inreg (nxv2i64 ZPR:$Zs), nxv2i32), (nxv2f32 ZPR:$Zd))),
+ (SCVTF_ZPmZ_StoS ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
+
+ def : Pat<(nxv2f64 (AArch64scvtf_mt (nxv2i1 PPR:$Pg),
+ (sext_inreg (nxv2i64 ZPR:$Zs), nxv2i32), (nxv2f64 ZPR:$Zd))),
+ (SCVTF_ZPmZ_StoD ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
+
+ // Floating-point -> unsigned integer
+ def : Pat<(nxv2f16 (AArch64ucvtf_mt (nxv2i1 PPR:$Pg),
+ (and (nxv2i64 ZPR:$Zs),
+ (nxv2i64 (AArch64dup (i64 0xFFFF)))), (nxv2f16 ZPR:$Zd))),
+ (UCVTF_ZPmZ_HtoH ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
+
+ def : Pat<(nxv2f16 (AArch64ucvtf_mt (nxv2i1 PPR:$Pg),
+ (and (nxv2i64 ZPR:$Zs),
+ (nxv2i64 (AArch64dup (i64 0xFFFFFFFF)))), (nxv2f16 ZPR:$Zd))),
+ (UCVTF_ZPmZ_StoH ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
+
+ def : Pat<(nxv4f16 (AArch64ucvtf_mt (nxv4i1 PPR:$Pg),
+ (and (nxv4i32 ZPR:$Zs),
+ (nxv4i32 (AArch64dup (i32 0xFFFF)))), (nxv4f16 ZPR:$Zd))),
+ (UCVTF_ZPmZ_HtoH ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
+
+ def : Pat<(nxv2f32 (AArch64ucvtf_mt (nxv2i1 PPR:$Pg),
+ (and (nxv2i64 ZPR:$Zs),
+ (nxv2i64 (AArch64dup (i64 0xFFFFFFFF)))), (nxv2f32 ZPR:$Zd))),
+ (UCVTF_ZPmZ_StoS ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
+
+ def : Pat<(nxv2f64 (AArch64ucvtf_mt (nxv2i1 PPR:$Pg),
+ (and (nxv2i64 ZPR:$Zs),
+ (nxv2i64 (AArch64dup (i64 0xFFFFFFFF)))), (nxv2f64 ZPR:$Zd))),
+ (UCVTF_ZPmZ_StoD ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>;
+
+ defm FRINTN_ZPmZ : sve_fp_2op_p_zd_HSD<0b00000, "frintn", AArch64frintn_mt>;
+ defm FRINTP_ZPmZ : sve_fp_2op_p_zd_HSD<0b00001, "frintp", AArch64frintp_mt>;
+ defm FRINTM_ZPmZ : sve_fp_2op_p_zd_HSD<0b00010, "frintm", AArch64frintm_mt>;
+ defm FRINTZ_ZPmZ : sve_fp_2op_p_zd_HSD<0b00011, "frintz", AArch64frintz_mt>;
+ defm FRINTA_ZPmZ : sve_fp_2op_p_zd_HSD<0b00100, "frinta", AArch64frinta_mt>;
+ defm FRINTX_ZPmZ : sve_fp_2op_p_zd_HSD<0b00110, "frintx", AArch64frintx_mt>;
+ defm FRINTI_ZPmZ : sve_fp_2op_p_zd_HSD<0b00111, "frinti", AArch64frinti_mt>;
+ defm FRECPX_ZPmZ : sve_fp_2op_p_zd_HSD<0b01100, "frecpx", AArch64frecpx_mt>;
+ defm FSQRT_ZPmZ : sve_fp_2op_p_zd_HSD<0b01101, "fsqrt", AArch64fsqrt_mt>;
+
let Predicates = [HasBF16, HasSVE] in {
defm BFDOT_ZZZ : sve_bfloat_dot<"bfdot", int_aarch64_sve_bfdot>;
defm BFDOT_ZZI : sve_bfloat_dot_indexed<"bfdot", int_aarch64_sve_bfdot_lane>;
@@ -1648,9 +1648,9 @@ let Predicates = [HasSVE] in {
def : Pat<(vscale (sve_cntd_imm_neg i32:$imm)), (SUBXrs XZR, (CNTD_XPiI 31, $imm), 0)>;
}
- def : Pat<(add GPR64:$op, (vscale (sve_rdvl_imm i32:$imm))),
- (ADDVL_XXI GPR64:$op, $imm)>;
-
+ def : Pat<(add GPR64:$op, (vscale (sve_rdvl_imm i32:$imm))),
+ (ADDVL_XXI GPR64:$op, $imm)>;
+
// FIXME: BigEndian requires an additional REV instruction to satisfy the
// constraint that none of the bits change when stored to memory as one
// type, and and reloaded as another type.
@@ -1721,7 +1721,7 @@ let Predicates = [HasSVE] in {
def : Pat<(nxv2f64 (bitconvert (nxv8bf16 ZPR:$src))), (nxv2f64 ZPR:$src)>;
}
- // These allow casting from/to unpacked predicate types.
+ // These allow casting from/to unpacked predicate types.
def : Pat<(nxv16i1 (reinterpret_cast (nxv16i1 PPR:$src))), (COPY_TO_REGCLASS PPR:$src, PPR)>;
def : Pat<(nxv16i1 (reinterpret_cast (nxv8i1 PPR:$src))), (COPY_TO_REGCLASS PPR:$src, PPR)>;
def : Pat<(nxv16i1 (reinterpret_cast (nxv4i1 PPR:$src))), (COPY_TO_REGCLASS PPR:$src, PPR)>;
@@ -1736,18 +1736,18 @@ let Predicates = [HasSVE] in {
def : Pat<(nxv2i1 (reinterpret_cast (nxv8i1 PPR:$src))), (COPY_TO_REGCLASS PPR:$src, PPR)>;
def : Pat<(nxv2i1 (reinterpret_cast (nxv4i1 PPR:$src))), (COPY_TO_REGCLASS PPR:$src, PPR)>;
- // These allow casting from/to unpacked floating-point types.
- def : Pat<(nxv2f16 (reinterpret_cast (nxv8f16 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
- def : Pat<(nxv8f16 (reinterpret_cast (nxv2f16 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
- def : Pat<(nxv4f16 (reinterpret_cast (nxv8f16 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
- def : Pat<(nxv8f16 (reinterpret_cast (nxv4f16 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
- def : Pat<(nxv2f32 (reinterpret_cast (nxv4f32 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
- def : Pat<(nxv4f32 (reinterpret_cast (nxv2f32 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
- def : Pat<(nxv2bf16 (reinterpret_cast (nxv8bf16 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
- def : Pat<(nxv8bf16 (reinterpret_cast (nxv2bf16 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
- def : Pat<(nxv4bf16 (reinterpret_cast (nxv8bf16 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
- def : Pat<(nxv8bf16 (reinterpret_cast (nxv4bf16 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
-
+ // These allow casting from/to unpacked floating-point types.
+ def : Pat<(nxv2f16 (reinterpret_cast (nxv8f16 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
+ def : Pat<(nxv8f16 (reinterpret_cast (nxv2f16 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
+ def : Pat<(nxv4f16 (reinterpret_cast (nxv8f16 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
+ def : Pat<(nxv8f16 (reinterpret_cast (nxv4f16 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
+ def : Pat<(nxv2f32 (reinterpret_cast (nxv4f32 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
+ def : Pat<(nxv4f32 (reinterpret_cast (nxv2f32 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
+ def : Pat<(nxv2bf16 (reinterpret_cast (nxv8bf16 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
+ def : Pat<(nxv8bf16 (reinterpret_cast (nxv2bf16 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
+ def : Pat<(nxv4bf16 (reinterpret_cast (nxv8bf16 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
+ def : Pat<(nxv8bf16 (reinterpret_cast (nxv4bf16 ZPR:$src))), (COPY_TO_REGCLASS ZPR:$src, ZPR)>;
+
def : Pat<(nxv16i1 (and PPR:$Ps1, PPR:$Ps2)),
(AND_PPzPP (PTRUE_B 31), PPR:$Ps1, PPR:$Ps2)>;
def : Pat<(nxv8i1 (and PPR:$Ps1, PPR:$Ps2)),
@@ -1800,7 +1800,7 @@ let Predicates = [HasSVE] in {
defm : pred_load<nxv8i16, nxv8i1, asext_masked_load_i8, LD1SB_H, LD1SB_H_IMM, am_sve_regreg_lsl0>;
defm : pred_load<nxv8i16, nxv8i1, nonext_masked_load, LD1H, LD1H_IMM, am_sve_regreg_lsl1>;
defm : pred_load<nxv8f16, nxv8i1, nonext_masked_load, LD1H, LD1H_IMM, am_sve_regreg_lsl1>;
- defm : pred_load<nxv8bf16, nxv8i1, nonext_masked_load, LD1H, LD1H_IMM, am_sve_regreg_lsl1>;
+ defm : pred_load<nxv8bf16, nxv8i1, nonext_masked_load, LD1H, LD1H_IMM, am_sve_regreg_lsl1>;
// 16-element contiguous loads
defm : pred_load<nxv16i8, nxv16i1, nonext_masked_load, LD1B, LD1B_IMM, am_sve_regreg_lsl0>;
@@ -1838,10 +1838,10 @@ let Predicates = [HasSVE] in {
defm : pred_store<nxv4f32, nxv4i1, nontrunc_masked_store, ST1W, ST1W_IMM, am_sve_regreg_lsl2>;
// 8-element contiguous stores
- defm : pred_store<nxv8i16, nxv8i1, trunc_masked_store_i8, ST1B_H, ST1B_H_IMM, am_sve_regreg_lsl0>;
- defm : pred_store<nxv8i16, nxv8i1, nontrunc_masked_store, ST1H, ST1H_IMM, am_sve_regreg_lsl1>;
- defm : pred_store<nxv8f16, nxv8i1, nontrunc_masked_store, ST1H, ST1H_IMM, am_sve_regreg_lsl1>;
- defm : pred_store<nxv8bf16, nxv8i1, nontrunc_masked_store, ST1H, ST1H_IMM, am_sve_regreg_lsl1>;
+ defm : pred_store<nxv8i16, nxv8i1, trunc_masked_store_i8, ST1B_H, ST1B_H_IMM, am_sve_regreg_lsl0>;
+ defm : pred_store<nxv8i16, nxv8i1, nontrunc_masked_store, ST1H, ST1H_IMM, am_sve_regreg_lsl1>;
+ defm : pred_store<nxv8f16, nxv8i1, nontrunc_masked_store, ST1H, ST1H_IMM, am_sve_regreg_lsl1>;
+ defm : pred_store<nxv8bf16, nxv8i1, nontrunc_masked_store, ST1H, ST1H_IMM, am_sve_regreg_lsl1>;
// 16-element contiguous stores
defm : pred_store<nxv16i8, nxv16i1, nontrunc_masked_store, ST1B, ST1B_IMM, am_sve_regreg_lsl0>;
@@ -2003,7 +2003,7 @@ let Predicates = [HasSVE] in {
defm : ld1<LD1SB_H, LD1SB_H_IMM, nxv8i16, AArch64ld1s_z, nxv8i1, nxv8i8, am_sve_regreg_lsl0>;
defm : ld1<LD1H, LD1H_IMM, nxv8i16, AArch64ld1_z, nxv8i1, nxv8i16, am_sve_regreg_lsl1>;
defm : ld1<LD1H, LD1H_IMM, nxv8f16, AArch64ld1_z, nxv8i1, nxv8f16, am_sve_regreg_lsl1>;
- defm : ld1<LD1H, LD1H_IMM, nxv8bf16, AArch64ld1_z, nxv8i1, nxv8bf16, am_sve_regreg_lsl1>;
+ defm : ld1<LD1H, LD1H_IMM, nxv8bf16, AArch64ld1_z, nxv8i1, nxv8bf16, am_sve_regreg_lsl1>;
// 16-element contiguous loads
defm : ld1<LD1B, LD1B_IMM, nxv16i8, AArch64ld1_z, nxv16i1, nxv16i8, am_sve_regreg_lsl0>;
@@ -2043,7 +2043,7 @@ let Predicates = [HasSVE] in {
defm : ldnf1<LDNF1SB_H_IMM, nxv8i16, AArch64ldnf1s_z, nxv8i1, nxv8i8>;
defm : ldnf1<LDNF1H_IMM, nxv8i16, AArch64ldnf1_z, nxv8i1, nxv8i16>;
defm : ldnf1<LDNF1H_IMM, nxv8f16, AArch64ldnf1_z, nxv8i1, nxv8f16>;
- defm : ldnf1<LDNF1H_IMM, nxv8bf16, AArch64ldnf1_z, nxv8i1, nxv8bf16>;
+ defm : ldnf1<LDNF1H_IMM, nxv8bf16, AArch64ldnf1_z, nxv8i1, nxv8bf16>;
// 16-element contiguous non-faulting loads
defm : ldnf1<LDNF1B_IMM, nxv16i8, AArch64ldnf1_z, nxv16i1, nxv16i8>;
@@ -2084,7 +2084,7 @@ let Predicates = [HasSVE] in {
defm : ldff1<LDFF1SB_H, nxv8i16, AArch64ldff1s_z, nxv8i1, nxv8i8, am_sve_regreg_lsl0>;
defm : ldff1<LDFF1H, nxv8i16, AArch64ldff1_z, nxv8i1, nxv8i16, am_sve_regreg_lsl1>;
defm : ldff1<LDFF1H, nxv8f16, AArch64ldff1_z, nxv8i1, nxv8f16, am_sve_regreg_lsl1>;
- defm : ldff1<LDFF1H, nxv8bf16, AArch64ldff1_z, nxv8i1, nxv8bf16, am_sve_regreg_lsl1>;
+ defm : ldff1<LDFF1H, nxv8bf16, AArch64ldff1_z, nxv8i1, nxv8bf16, am_sve_regreg_lsl1>;
// 16-element contiguous first faulting loads
defm : ldff1<LDFF1B, nxv16i8, AArch64ldff1_z, nxv16i1, nxv16i8, am_sve_regreg_lsl0>;
@@ -2135,19 +2135,19 @@ let Predicates = [HasSVE] in {
def : Pat<(nxv2i64 (vector_insert (nxv2i64 (undef)), (i64 FPR64:$src), 0)),
(INSERT_SUBREG (nxv2i64 (IMPLICIT_DEF)), FPR64:$src, dsub)>;
- def : Pat<(nxv8f16 (vector_insert (nxv8f16 (undef)), (f16 FPR16:$src), 0)),
- (INSERT_SUBREG (nxv8f16 (IMPLICIT_DEF)), FPR16:$src, hsub)>;
- def : Pat<(nxv4f16 (vector_insert (nxv4f16 (undef)), (f16 FPR16:$src), 0)),
- (INSERT_SUBREG (nxv4f16 (IMPLICIT_DEF)), FPR16:$src, hsub)>;
- def : Pat<(nxv2f16 (vector_insert (nxv2f16 (undef)), (f16 FPR16:$src), 0)),
- (INSERT_SUBREG (nxv2f16 (IMPLICIT_DEF)), FPR16:$src, hsub)>;
- def : Pat<(nxv4f32 (vector_insert (nxv4f32 (undef)), (f32 FPR32:$src), 0)),
- (INSERT_SUBREG (nxv4f32 (IMPLICIT_DEF)), FPR32:$src, ssub)>;
- def : Pat<(nxv2f32 (vector_insert (nxv2f32 (undef)), (f32 FPR32:$src), 0)),
- (INSERT_SUBREG (nxv2f32 (IMPLICIT_DEF)), FPR32:$src, ssub)>;
- def : Pat<(nxv2f64 (vector_insert (nxv2f64 (undef)), (f64 FPR64:$src), 0)),
- (INSERT_SUBREG (nxv2f64 (IMPLICIT_DEF)), FPR64:$src, dsub)>;
-
+ def : Pat<(nxv8f16 (vector_insert (nxv8f16 (undef)), (f16 FPR16:$src), 0)),
+ (INSERT_SUBREG (nxv8f16 (IMPLICIT_DEF)), FPR16:$src, hsub)>;
+ def : Pat<(nxv4f16 (vector_insert (nxv4f16 (undef)), (f16 FPR16:$src), 0)),
+ (INSERT_SUBREG (nxv4f16 (IMPLICIT_DEF)), FPR16:$src, hsub)>;
+ def : Pat<(nxv2f16 (vector_insert (nxv2f16 (undef)), (f16 FPR16:$src), 0)),
+ (INSERT_SUBREG (nxv2f16 (IMPLICIT_DEF)), FPR16:$src, hsub)>;
+ def : Pat<(nxv4f32 (vector_insert (nxv4f32 (undef)), (f32 FPR32:$src), 0)),
+ (INSERT_SUBREG (nxv4f32 (IMPLICIT_DEF)), FPR32:$src, ssub)>;
+ def : Pat<(nxv2f32 (vector_insert (nxv2f32 (undef)), (f32 FPR32:$src), 0)),
+ (INSERT_SUBREG (nxv2f32 (IMPLICIT_DEF)), FPR32:$src, ssub)>;
+ def : Pat<(nxv2f64 (vector_insert (nxv2f64 (undef)), (f64 FPR64:$src), 0)),
+ (INSERT_SUBREG (nxv2f64 (IMPLICIT_DEF)), FPR64:$src, dsub)>;
+
// Insert scalar into vector[0]
def : Pat<(nxv16i8 (vector_insert (nxv16i8 ZPR:$vec), (i32 GPR32:$src), 0)),
(CPY_ZPmR_B ZPR:$vec, (PTRUE_B 1), GPR32:$src)>;
@@ -2211,28 +2211,28 @@ let Predicates = [HasSVE] in {
(DUP_ZR_D $index)),
$src)>;
- // Extract element from vector with scalar index
- def : Pat<(i32 (vector_extract (nxv16i8 ZPR:$vec), GPR64:$index)),
- (LASTB_RPZ_B (WHILELS_PXX_B XZR, GPR64:$index), ZPR:$vec)>;
- def : Pat<(i32 (vector_extract (nxv8i16 ZPR:$vec), GPR64:$index)),
- (LASTB_RPZ_H (WHILELS_PXX_H XZR, GPR64:$index), ZPR:$vec)>;
- def : Pat<(i32 (vector_extract (nxv4i32 ZPR:$vec), GPR64:$index)),
- (LASTB_RPZ_S (WHILELS_PXX_S XZR, GPR64:$index), ZPR:$vec)>;
- def : Pat<(i64 (vector_extract (nxv2i64 ZPR:$vec), GPR64:$index)),
- (LASTB_RPZ_D (WHILELS_PXX_D XZR, GPR64:$index), ZPR:$vec)>;
- def : Pat<(f16 (vector_extract (nxv8f16 ZPR:$vec), GPR64:$index)),
- (LASTB_VPZ_H (WHILELS_PXX_H XZR, GPR64:$index), ZPR:$vec)>;
- def : Pat<(f16 (vector_extract (nxv4f16 ZPR:$vec), GPR64:$index)),
- (LASTB_VPZ_H (WHILELS_PXX_S XZR, GPR64:$index), ZPR:$vec)>;
- def : Pat<(f16 (vector_extract (nxv2f16 ZPR:$vec), GPR64:$index)),
- (LASTB_VPZ_H (WHILELS_PXX_D XZR, GPR64:$index), ZPR:$vec)>;
- def : Pat<(f32 (vector_extract (nxv4f32 ZPR:$vec), GPR64:$index)),
- (LASTB_VPZ_S (WHILELS_PXX_S XZR, GPR64:$index), ZPR:$vec)>;
- def : Pat<(f32 (vector_extract (nxv2f32 ZPR:$vec), GPR64:$index)),
- (LASTB_VPZ_S (WHILELS_PXX_D XZR, GPR64:$index), ZPR:$vec)>;
- def : Pat<(f64 (vector_extract (nxv2f64 ZPR:$vec), GPR64:$index)),
- (LASTB_VPZ_D (WHILELS_PXX_D XZR, GPR64:$index), ZPR:$vec)>;
-
+ // Extract element from vector with scalar index
+ def : Pat<(i32 (vector_extract (nxv16i8 ZPR:$vec), GPR64:$index)),
+ (LASTB_RPZ_B (WHILELS_PXX_B XZR, GPR64:$index), ZPR:$vec)>;
+ def : Pat<(i32 (vector_extract (nxv8i16 ZPR:$vec), GPR64:$index)),
+ (LASTB_RPZ_H (WHILELS_PXX_H XZR, GPR64:$index), ZPR:$vec)>;
+ def : Pat<(i32 (vector_extract (nxv4i32 ZPR:$vec), GPR64:$index)),
+ (LASTB_RPZ_S (WHILELS_PXX_S XZR, GPR64:$index), ZPR:$vec)>;
+ def : Pat<(i64 (vector_extract (nxv2i64 ZPR:$vec), GPR64:$index)),
+ (LASTB_RPZ_D (WHILELS_PXX_D XZR, GPR64:$index), ZPR:$vec)>;
+ def : Pat<(f16 (vector_extract (nxv8f16 ZPR:$vec), GPR64:$index)),
+ (LASTB_VPZ_H (WHILELS_PXX_H XZR, GPR64:$index), ZPR:$vec)>;
+ def : Pat<(f16 (vector_extract (nxv4f16 ZPR:$vec), GPR64:$index)),
+ (LASTB_VPZ_H (WHILELS_PXX_S XZR, GPR64:$index), ZPR:$vec)>;
+ def : Pat<(f16 (vector_extract (nxv2f16 ZPR:$vec), GPR64:$index)),
+ (LASTB_VPZ_H (WHILELS_PXX_D XZR, GPR64:$index), ZPR:$vec)>;
+ def : Pat<(f32 (vector_extract (nxv4f32 ZPR:$vec), GPR64:$index)),
+ (LASTB_VPZ_S (WHILELS_PXX_S XZR, GPR64:$index), ZPR:$vec)>;
+ def : Pat<(f32 (vector_extract (nxv2f32 ZPR:$vec), GPR64:$index)),
+ (LASTB_VPZ_S (WHILELS_PXX_D XZR, GPR64:$index), ZPR:$vec)>;
+ def : Pat<(f64 (vector_extract (nxv2f64 ZPR:$vec), GPR64:$index)),
+ (LASTB_VPZ_D (WHILELS_PXX_D XZR, GPR64:$index), ZPR:$vec)>;
+
// Extract element from vector with immediate index
def : Pat<(i32 (vector_extract (nxv16i8 ZPR:$vec), sve_elm_idx_extdup_b:$index)),
(EXTRACT_SUBREG (DUP_ZZI_B ZPR:$vec, sve_elm_idx_extdup_b:$index), ssub)>;
@@ -2244,54 +2244,54 @@ let Predicates = [HasSVE] in {
(EXTRACT_SUBREG (DUP_ZZI_D ZPR:$vec, sve_elm_idx_extdup_d:$index), dsub)>;
def : Pat<(f16 (vector_extract (nxv8f16 ZPR:$vec), sve_elm_idx_extdup_h:$index)),
(EXTRACT_SUBREG (DUP_ZZI_H ZPR:$vec, sve_elm_idx_extdup_h:$index), hsub)>;
- def : Pat<(f16 (vector_extract (nxv8f16 ZPR:$vec), sve_elm_idx_extdup_h:$index)),
- (EXTRACT_SUBREG (DUP_ZZI_H ZPR:$vec, sve_elm_idx_extdup_h:$index), hsub)>;
- def : Pat<(f16 (vector_extract (nxv4f16 ZPR:$vec), sve_elm_idx_extdup_s:$index)),
- (EXTRACT_SUBREG (DUP_ZZI_S ZPR:$vec, sve_elm_idx_extdup_s:$index), hsub)>;
- def : Pat<(f16 (vector_extract (nxv2f16 ZPR:$vec), sve_elm_idx_extdup_d:$index)),
- (EXTRACT_SUBREG (DUP_ZZI_D ZPR:$vec, sve_elm_idx_extdup_d:$index), hsub)>;
+ def : Pat<(f16 (vector_extract (nxv8f16 ZPR:$vec), sve_elm_idx_extdup_h:$index)),
+ (EXTRACT_SUBREG (DUP_ZZI_H ZPR:$vec, sve_elm_idx_extdup_h:$index), hsub)>;
+ def : Pat<(f16 (vector_extract (nxv4f16 ZPR:$vec), sve_elm_idx_extdup_s:$index)),
+ (EXTRACT_SUBREG (DUP_ZZI_S ZPR:$vec, sve_elm_idx_extdup_s:$index), hsub)>;
+ def : Pat<(f16 (vector_extract (nxv2f16 ZPR:$vec), sve_elm_idx_extdup_d:$index)),
+ (EXTRACT_SUBREG (DUP_ZZI_D ZPR:$vec, sve_elm_idx_extdup_d:$index), hsub)>;
def : Pat<(f32 (vector_extract (nxv4f32 ZPR:$vec), sve_elm_idx_extdup_s:$index)),
(EXTRACT_SUBREG (DUP_ZZI_S ZPR:$vec, sve_elm_idx_extdup_s:$index), ssub)>;
- def : Pat<(f32 (vector_extract (nxv2f32 ZPR:$vec), sve_elm_idx_extdup_d:$index)),
- (EXTRACT_SUBREG (DUP_ZZI_D ZPR:$vec, sve_elm_idx_extdup_d:$index), ssub)>;
+ def : Pat<(f32 (vector_extract (nxv2f32 ZPR:$vec), sve_elm_idx_extdup_d:$index)),
+ (EXTRACT_SUBREG (DUP_ZZI_D ZPR:$vec, sve_elm_idx_extdup_d:$index), ssub)>;
def : Pat<(f64 (vector_extract (nxv2f64 ZPR:$vec), sve_elm_idx_extdup_d:$index)),
(EXTRACT_SUBREG (DUP_ZZI_D ZPR:$vec, sve_elm_idx_extdup_d:$index), dsub)>;
- // Extract element from vector with immediate index that's within the bottom 128-bits.
- let AddedComplexity = 1 in {
- def : Pat<(i32 (vector_extract (nxv16i8 ZPR:$vec), VectorIndexB:$index)),
- (i32 (UMOVvi8 (v16i8 (EXTRACT_SUBREG ZPR:$vec, zsub)), VectorIndexB:$index))>;
- def : Pat<(i32 (vector_extract (nxv8i16 ZPR:$vec), VectorIndexH:$index)),
- (i32 (UMOVvi16 (v8i16 (EXTRACT_SUBREG ZPR:$vec, zsub)), VectorIndexH:$index))>;
- def : Pat<(i32 (vector_extract (nxv4i32 ZPR:$vec), VectorIndexS:$index)),
- (i32 (UMOVvi32 (v4i32 (EXTRACT_SUBREG ZPR:$vec, zsub)), VectorIndexS:$index))>;
- def : Pat<(i64 (vector_extract (nxv2i64 ZPR:$vec), VectorIndexD:$index)),
- (i64 (UMOVvi64 (v2i64 (EXTRACT_SUBREG ZPR:$vec, zsub)), VectorIndexD:$index))>;
- }
-
- // Extract first element from vector.
- let AddedComplexity = 2 in {
- def : Pat<(vector_extract (nxv16i8 ZPR:$Zs), (i64 0)),
- (i32 (EXTRACT_SUBREG ZPR:$Zs, ssub))>;
- def : Pat<(vector_extract (nxv8i16 ZPR:$Zs), (i64 0)),
- (i32 (EXTRACT_SUBREG ZPR:$Zs, ssub))>;
- def : Pat<(vector_extract (nxv4i32 ZPR:$Zs), (i64 0)),
- (i32 (EXTRACT_SUBREG ZPR:$Zs, ssub))>;
- def : Pat<(vector_extract (nxv2i64 ZPR:$Zs), (i64 0)),
- (i64 (EXTRACT_SUBREG ZPR:$Zs, dsub))>;
- def : Pat<(vector_extract (nxv8f16 ZPR:$Zs), (i64 0)),
- (f16 (EXTRACT_SUBREG ZPR:$Zs, hsub))>;
- def : Pat<(vector_extract (nxv4f16 ZPR:$Zs), (i64 0)),
- (f16 (EXTRACT_SUBREG ZPR:$Zs, hsub))>;
- def : Pat<(vector_extract (nxv2f16 ZPR:$Zs), (i64 0)),
- (f16 (EXTRACT_SUBREG ZPR:$Zs, hsub))>;
- def : Pat<(vector_extract (nxv4f32 ZPR:$Zs), (i64 0)),
- (f32 (EXTRACT_SUBREG ZPR:$Zs, ssub))>;
- def : Pat<(vector_extract (nxv2f32 ZPR:$Zs), (i64 0)),
- (f32 (EXTRACT_SUBREG ZPR:$Zs, ssub))>;
- def : Pat<(vector_extract (nxv2f64 ZPR:$Zs), (i64 0)),
- (f64 (EXTRACT_SUBREG ZPR:$Zs, dsub))>;
- }
+ // Extract element from vector with immediate index that's within the bottom 128-bits.
+ let AddedComplexity = 1 in {
+ def : Pat<(i32 (vector_extract (nxv16i8 ZPR:$vec), VectorIndexB:$index)),
+ (i32 (UMOVvi8 (v16i8 (EXTRACT_SUBREG ZPR:$vec, zsub)), VectorIndexB:$index))>;
+ def : Pat<(i32 (vector_extract (nxv8i16 ZPR:$vec), VectorIndexH:$index)),
+ (i32 (UMOVvi16 (v8i16 (EXTRACT_SUBREG ZPR:$vec, zsub)), VectorIndexH:$index))>;
+ def : Pat<(i32 (vector_extract (nxv4i32 ZPR:$vec), VectorIndexS:$index)),
+ (i32 (UMOVvi32 (v4i32 (EXTRACT_SUBREG ZPR:$vec, zsub)), VectorIndexS:$index))>;
+ def : Pat<(i64 (vector_extract (nxv2i64 ZPR:$vec), VectorIndexD:$index)),
+ (i64 (UMOVvi64 (v2i64 (EXTRACT_SUBREG ZPR:$vec, zsub)), VectorIndexD:$index))>;
+ }
+
+ // Extract first element from vector.
+ let AddedComplexity = 2 in {
+ def : Pat<(vector_extract (nxv16i8 ZPR:$Zs), (i64 0)),
+ (i32 (EXTRACT_SUBREG ZPR:$Zs, ssub))>;
+ def : Pat<(vector_extract (nxv8i16 ZPR:$Zs), (i64 0)),
+ (i32 (EXTRACT_SUBREG ZPR:$Zs, ssub))>;
+ def : Pat<(vector_extract (nxv4i32 ZPR:$Zs), (i64 0)),
+ (i32 (EXTRACT_SUBREG ZPR:$Zs, ssub))>;
+ def : Pat<(vector_extract (nxv2i64 ZPR:$Zs), (i64 0)),
+ (i64 (EXTRACT_SUBREG ZPR:$Zs, dsub))>;
+ def : Pat<(vector_extract (nxv8f16 ZPR:$Zs), (i64 0)),
+ (f16 (EXTRACT_SUBREG ZPR:$Zs, hsub))>;
+ def : Pat<(vector_extract (nxv4f16 ZPR:$Zs), (i64 0)),
+ (f16 (EXTRACT_SUBREG ZPR:$Zs, hsub))>;
+ def : Pat<(vector_extract (nxv2f16 ZPR:$Zs), (i64 0)),
+ (f16 (EXTRACT_SUBREG ZPR:$Zs, hsub))>;
+ def : Pat<(vector_extract (nxv4f32 ZPR:$Zs), (i64 0)),
+ (f32 (EXTRACT_SUBREG ZPR:$Zs, ssub))>;
+ def : Pat<(vector_extract (nxv2f32 ZPR:$Zs), (i64 0)),
+ (f32 (EXTRACT_SUBREG ZPR:$Zs, ssub))>;
+ def : Pat<(vector_extract (nxv2f64 ZPR:$Zs), (i64 0)),
+ (f64 (EXTRACT_SUBREG ZPR:$Zs, dsub))>;
+ }
}
let Predicates = [HasSVE, HasMatMulInt8] in {
@@ -2350,10 +2350,10 @@ let Predicates = [HasSVE2] in {
defm SQRDMULH_ZZZ : sve2_int_mul<0b101, "sqrdmulh", int_aarch64_sve_sqrdmulh>;
// SVE2 integer multiply vectors (unpredicated)
- defm MUL_ZZZ : sve2_int_mul<0b000, "mul", null_frag, AArch64mul_p>;
+ defm MUL_ZZZ : sve2_int_mul<0b000, "mul", null_frag, AArch64mul_p>;
defm SMULH_ZZZ : sve2_int_mul<0b010, "smulh", null_frag>;
defm UMULH_ZZZ : sve2_int_mul<0b011, "umulh", null_frag>;
- defm PMUL_ZZZ : sve2_int_mul_single<0b001, "pmul", int_aarch64_sve_pmul>;
+ defm PMUL_ZZZ : sve2_int_mul_single<0b001, "pmul", int_aarch64_sve_pmul>;
// Add patterns for unpredicated version of smulh and umulh.
def : Pat<(nxv16i8 (int_aarch64_sve_smulh (nxv16i1 (AArch64ptrue 31)), nxv16i8:$Op1, nxv16i8:$Op2)),
@@ -2372,7 +2372,7 @@ let Predicates = [HasSVE2] in {
(UMULH_ZZZ_S $Op1, $Op2)>;
def : Pat<(nxv2i64 (int_aarch64_sve_umulh (nxv2i1 (AArch64ptrue 31)), nxv2i64:$Op1, nxv2i64:$Op2)),
(UMULH_ZZZ_D $Op1, $Op2)>;
-
+
// SVE2 complex integer dot product (indexed)
defm CDOT_ZZZI : sve2_cintx_dot_by_indexed_elem<"cdot", int_aarch64_sve_cdot_lane>;
@@ -2494,11 +2494,11 @@ let Predicates = [HasSVE2] in {
}
// SVE2 predicated shifts
- defm SQSHL_ZPmI : sve_int_bin_pred_shift_imm_left< 0b0110, "sqshl", "SQSHL_ZPZI">;
- defm UQSHL_ZPmI : sve_int_bin_pred_shift_imm_left< 0b0111, "uqshl", "UQSHL_ZPZI">;
- defm SRSHR_ZPmI : sve_int_bin_pred_shift_imm_right<0b1100, "srshr", "SRSHR_ZPZI", int_aarch64_sve_srshr>;
- defm URSHR_ZPmI : sve_int_bin_pred_shift_imm_right<0b1101, "urshr", "URSHR_ZPZI", int_aarch64_sve_urshr>;
- defm SQSHLU_ZPmI : sve_int_bin_pred_shift_imm_left< 0b1111, "sqshlu", "SQSHLU_ZPZI", int_aarch64_sve_sqshlu>;
+ defm SQSHL_ZPmI : sve_int_bin_pred_shift_imm_left< 0b0110, "sqshl", "SQSHL_ZPZI">;
+ defm UQSHL_ZPmI : sve_int_bin_pred_shift_imm_left< 0b0111, "uqshl", "UQSHL_ZPZI">;
+ defm SRSHR_ZPmI : sve_int_bin_pred_shift_imm_right<0b1100, "srshr", "SRSHR_ZPZI", int_aarch64_sve_srshr>;
+ defm URSHR_ZPmI : sve_int_bin_pred_shift_imm_right<0b1101, "urshr", "URSHR_ZPZI", int_aarch64_sve_urshr>;
+ defm SQSHLU_ZPmI : sve_int_bin_pred_shift_imm_left< 0b1111, "sqshlu", "SQSHLU_ZPZI", int_aarch64_sve_sqshlu>;
// SVE2 integer add/subtract long
defm SADDLB_ZZZ : sve2_wide_int_arith_long<0b00000, "saddlb", int_aarch64_sve_saddlb>;
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA55.td b/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA55.td
index 0b45a3ba09..50911fd22b 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA55.td
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA55.td
@@ -1,339 +1,339 @@
-//==- AArch64SchedCortexA55.td - ARM Cortex-A55 Scheduling Definitions -*- tablegen -*-=//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the machine model for the ARM Cortex-A55 processors.
-//
-//===----------------------------------------------------------------------===//
-
-// ===---------------------------------------------------------------------===//
-// The following definitions describe the per-operand machine model.
-// This works with MachineScheduler. See MCSchedModel.h for details.
-
-// Cortex-A55 machine model for scheduling and other instruction cost heuristics.
-def CortexA55Model : SchedMachineModel {
- let MicroOpBufferSize = 0; // The Cortex-A55 is an in-order processor
- let IssueWidth = 2; // It dual-issues under most circumstances
- let LoadLatency = 4; // Cycles for loads to access the cache. The
- // optimisation guide shows that most loads have
- // a latency of 3, but some have a latency of 4
- // or 5. Setting it 4 looked to be good trade-off.
- let MispredictPenalty = 8; // A branch direction mispredict.
- let PostRAScheduler = 1; // Enable PostRA scheduler pass.
- let CompleteModel = 0; // Covers instructions applicable to Cortex-A55.
-
- list<Predicate> UnsupportedFeatures = [HasSVE];
-
- // FIXME: Remove when all errors have been fixed.
- let FullInstRWOverlapCheck = 0;
-}
-
-//===----------------------------------------------------------------------===//
-// Define each kind of processor resource and number available.
-
-// Modeling each pipeline as a ProcResource using the BufferSize = 0 since the
-// Cortex-A55 is in-order.
-
-def CortexA55UnitALU : ProcResource<2> { let BufferSize = 0; } // Int ALU
-def CortexA55UnitMAC : ProcResource<1> { let BufferSize = 0; } // Int MAC, 64-bi wide
-def CortexA55UnitDiv : ProcResource<1> { let BufferSize = 0; } // Int Division, not pipelined
-def CortexA55UnitLd : ProcResource<1> { let BufferSize = 0; } // Load pipe
-def CortexA55UnitSt : ProcResource<1> { let BufferSize = 0; } // Store pipe
-def CortexA55UnitB : ProcResource<1> { let BufferSize = 0; } // Branch
-
-// The FP DIV/SQRT instructions execute totally differently from the FP ALU
-// instructions, which can mostly be dual-issued; that's why for now we model
-// them with 2 resources.
-def CortexA55UnitFPALU : ProcResource<2> { let BufferSize = 0; } // FP ALU
-def CortexA55UnitFPMAC : ProcResource<2> { let BufferSize = 0; } // FP MAC
-def CortexA55UnitFPDIV : ProcResource<1> { let BufferSize = 0; } // FP Div/SQRT, 64/128
-
-//===----------------------------------------------------------------------===//
-// Subtarget-specific SchedWrite types
-
-let SchedModel = CortexA55Model in {
-
-// These latencies are modeled without taking into account forwarding paths
-// (the software optimisation guide lists latencies taking into account
-// typical forwarding paths).
-def : WriteRes<WriteImm, [CortexA55UnitALU]> { let Latency = 3; } // MOVN, MOVZ
-def : WriteRes<WriteI, [CortexA55UnitALU]> { let Latency = 3; } // ALU
-def : WriteRes<WriteISReg, [CortexA55UnitALU]> { let Latency = 3; } // ALU of Shifted-Reg
-def : WriteRes<WriteIEReg, [CortexA55UnitALU]> { let Latency = 3; } // ALU of Extended-Reg
-def : WriteRes<WriteExtr, [CortexA55UnitALU]> { let Latency = 3; } // EXTR from a reg pair
-def : WriteRes<WriteIS, [CortexA55UnitALU]> { let Latency = 3; } // Shift/Scale
-
-// MAC
-def : WriteRes<WriteIM32, [CortexA55UnitMAC]> { let Latency = 4; } // 32-bit Multiply
-def : WriteRes<WriteIM64, [CortexA55UnitMAC]> { let Latency = 4; } // 64-bit Multiply
-
-// Div
-def : WriteRes<WriteID32, [CortexA55UnitDiv]> {
- let Latency = 8; let ResourceCycles = [8];
-}
-def : WriteRes<WriteID64, [CortexA55UnitDiv]> {
- let Latency = 8; let ResourceCycles = [8];
-}
-
-// Load
-def : WriteRes<WriteLD, [CortexA55UnitLd]> { let Latency = 3; }
-def : WriteRes<WriteLDIdx, [CortexA55UnitLd]> { let Latency = 4; }
-def : WriteRes<WriteLDHi, [CortexA55UnitLd]> { let Latency = 5; }
-
-// Vector Load - Vector loads take 1-5 cycles to issue. For the WriteVecLd
-// below, choosing the median of 3 which makes the latency 6.
-// An extra cycle is needed to get the swizzling right.
-def : WriteRes<WriteVLD, [CortexA55UnitLd]> { let Latency = 6;
- let ResourceCycles = [3]; }
-def CortexA55WriteVLD1 : SchedWriteRes<[CortexA55UnitLd]> { let Latency = 4; }
-def CortexA55WriteVLD2 : SchedWriteRes<[CortexA55UnitLd]> { let Latency = 5;
- let ResourceCycles = [2]; }
-def CortexA55WriteVLD3 : SchedWriteRes<[CortexA55UnitLd]> { let Latency = 6;
- let ResourceCycles = [3]; }
-def CortexA55WriteVLD4 : SchedWriteRes<[CortexA55UnitLd]> { let Latency = 7;
- let ResourceCycles = [4]; }
-def CortexA55WriteVLD5 : SchedWriteRes<[CortexA55UnitLd]> { let Latency = 8;
- let ResourceCycles = [5]; }
-def CortexA55WriteVLD6 : SchedWriteRes<[CortexA55UnitLd]> { let Latency = 9;
- let ResourceCycles = [6]; }
-def CortexA55WriteVLD7 : SchedWriteRes<[CortexA55UnitLd]> { let Latency = 10;
- let ResourceCycles = [7]; }
-def CortexA55WriteVLD8 : SchedWriteRes<[CortexA55UnitLd]> { let Latency = 11;
- let ResourceCycles = [8]; }
-
-// Pre/Post Indexing - Performed as part of address generation
-def : WriteRes<WriteAdr, []> { let Latency = 0; }
-
-// Store
-def : WriteRes<WriteST, [CortexA55UnitSt]> { let Latency = 4; }
-def : WriteRes<WriteSTP, [CortexA55UnitSt]> { let Latency = 4; }
-def : WriteRes<WriteSTIdx, [CortexA55UnitSt]> { let Latency = 4; }
-def : WriteRes<WriteSTX, [CortexA55UnitSt]> { let Latency = 4; }
-
-// Vector Store - Similar to vector loads, can take 1-3 cycles to issue.
-def : WriteRes<WriteVST, [CortexA55UnitSt]> { let Latency = 5;
- let ResourceCycles = [2];}
-def CortexA55WriteVST1 : SchedWriteRes<[CortexA55UnitSt]> { let Latency = 4; }
-def CortexA55WriteVST2 : SchedWriteRes<[CortexA55UnitSt]> { let Latency = 5;
- let ResourceCycles = [2]; }
-def CortexA55WriteVST3 : SchedWriteRes<[CortexA55UnitSt]> { let Latency = 6;
- let ResourceCycles = [3]; }
-def CortexA55WriteVST4 : SchedWriteRes<[CortexA55UnitSt]> { let Latency = 5;
- let ResourceCycles = [4]; }
-
-def : WriteRes<WriteAtomic, []> { let Unsupported = 1; }
-
-// Branch
-def : WriteRes<WriteBr, [CortexA55UnitB]>;
-def : WriteRes<WriteBrReg, [CortexA55UnitB]>;
-def : WriteRes<WriteSys, [CortexA55UnitB]>;
-def : WriteRes<WriteBarrier, [CortexA55UnitB]>;
-def : WriteRes<WriteHint, [CortexA55UnitB]>;
-
-// FP ALU
-// As WriteF result is produced in F5 and it can be mostly forwarded
-// to consumer at F1, the effectively latency is set as 4.
-def : WriteRes<WriteF, [CortexA55UnitFPALU]> { let Latency = 4; }
-def : WriteRes<WriteFCmp, [CortexA55UnitFPALU]> { let Latency = 3; }
-def : WriteRes<WriteFCvt, [CortexA55UnitFPALU]> { let Latency = 4; }
-def : WriteRes<WriteFCopy, [CortexA55UnitFPALU]> { let Latency = 3; }
-def : WriteRes<WriteFImm, [CortexA55UnitFPALU]> { let Latency = 3; }
-def : WriteRes<WriteV, [CortexA55UnitFPALU]> { let Latency = 4; }
-
-// FP ALU specific new schedwrite definitions
-def CortexA55WriteFPALU_F3 : SchedWriteRes<[CortexA55UnitFPALU]> { let Latency = 3;}
-def CortexA55WriteFPALU_F4 : SchedWriteRes<[CortexA55UnitFPALU]> { let Latency = 4;}
-def CortexA55WriteFPALU_F5 : SchedWriteRes<[CortexA55UnitFPALU]> { let Latency = 5;}
-
-// FP Mul, Div, Sqrt. Div/Sqrt are not pipelined
-def : WriteRes<WriteFMul, [CortexA55UnitFPMAC]> { let Latency = 4; }
-def : WriteRes<WriteFDiv, [CortexA55UnitFPDIV]> { let Latency = 22;
- let ResourceCycles = [29]; }
-def CortexA55WriteFMAC : SchedWriteRes<[CortexA55UnitFPMAC]> { let Latency = 4; }
-def CortexA55WriteFDivHP : SchedWriteRes<[CortexA55UnitFPDIV]> { let Latency = 8;
- let ResourceCycles = [5]; }
-def CortexA55WriteFDivSP : SchedWriteRes<[CortexA55UnitFPDIV]> { let Latency = 13;
- let ResourceCycles = [10]; }
-def CortexA55WriteFDivDP : SchedWriteRes<[CortexA55UnitFPDIV]> { let Latency = 22;
- let ResourceCycles = [19]; }
-def CortexA55WriteFSqrtHP : SchedWriteRes<[CortexA55UnitFPDIV]> { let Latency = 8;
- let ResourceCycles = [5]; }
-def CortexA55WriteFSqrtSP : SchedWriteRes<[CortexA55UnitFPDIV]> { let Latency = 12;
- let ResourceCycles = [9]; }
-def CortexA55WriteFSqrtDP : SchedWriteRes<[CortexA55UnitFPDIV]> { let Latency = 22;
- let ResourceCycles = [19]; }
-
-//===----------------------------------------------------------------------===//
-// Subtarget-specific SchedRead types.
-
-def : ReadAdvance<ReadVLD, 0>;
-def : ReadAdvance<ReadExtrHi, 1>;
-def : ReadAdvance<ReadAdrBase, 1>;
-
-// ALU - ALU input operands are generally needed in EX1. An operand produced in
-// in say EX2 can be forwarded for consumption to ALU in EX1, thereby
-// allowing back-to-back ALU operations such as add. If an operand requires
-// a shift, it will, however, be required in ISS stage.
-def : ReadAdvance<ReadI, 2, [WriteImm,WriteI,
- WriteISReg, WriteIEReg,WriteIS,
- WriteID32,WriteID64,
- WriteIM32,WriteIM64]>;
-// Shifted operand
-def CortexA55ReadShifted : SchedReadAdvance<1, [WriteImm,WriteI,
- WriteISReg, WriteIEReg,WriteIS,
- WriteID32,WriteID64,
- WriteIM32,WriteIM64]>;
-def CortexA55ReadNotShifted : SchedReadAdvance<2, [WriteImm,WriteI,
- WriteISReg, WriteIEReg,WriteIS,
- WriteID32,WriteID64,
- WriteIM32,WriteIM64]>;
-def CortexA55ReadISReg : SchedReadVariant<[
- SchedVar<RegShiftedPred, [CortexA55ReadShifted]>,
- SchedVar<NoSchedPred, [CortexA55ReadNotShifted]>]>;
-def : SchedAlias<ReadISReg, CortexA55ReadISReg>;
-
-def CortexA55ReadIEReg : SchedReadVariant<[
- SchedVar<RegExtendedPred, [CortexA55ReadShifted]>,
- SchedVar<NoSchedPred, [CortexA55ReadNotShifted]>]>;
-def : SchedAlias<ReadIEReg, CortexA55ReadIEReg>;
-
-// MUL
-def : ReadAdvance<ReadIM, 1, [WriteImm,WriteI,
- WriteISReg, WriteIEReg,WriteIS,
- WriteID32,WriteID64,
- WriteIM32,WriteIM64]>;
-def : ReadAdvance<ReadIMA, 2, [WriteImm,WriteI,
- WriteISReg, WriteIEReg,WriteIS,
- WriteID32,WriteID64,
- WriteIM32,WriteIM64]>;
-
-// Div
-def : ReadAdvance<ReadID, 1, [WriteImm,WriteI,
- WriteISReg, WriteIEReg,WriteIS,
- WriteID32,WriteID64,
- WriteIM32,WriteIM64]>;
-
-//===----------------------------------------------------------------------===//
-// Subtarget-specific InstRWs.
-
-//---
-// Miscellaneous
-//---
-def : InstRW<[CortexA55WriteVLD2,CortexA55WriteVLD1], (instregex "LDP.*")>;
-def : InstRW<[WriteI], (instrs COPY)>;
-//---
-// Vector Loads - 64-bit per cycle
-//---
-// 1-element structures
-def : InstRW<[CortexA55WriteVLD1], (instregex "LD1i(8|16|32|64)$")>; // single element
-def : InstRW<[CortexA55WriteVLD1], (instregex "LD1Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>; // replicate
-def : InstRW<[CortexA55WriteVLD1], (instregex "LD1Onev(8b|4h|2s|1d)$")>;
-def : InstRW<[CortexA55WriteVLD2], (instregex "LD1Onev(16b|8h|4s|2d)$")>;
-def : InstRW<[CortexA55WriteVLD2], (instregex "LD1Twov(8b|4h|2s|1d)$")>; // multiple structures
-def : InstRW<[CortexA55WriteVLD4], (instregex "LD1Twov(16b|8h|4s|2d)$")>;
-def : InstRW<[CortexA55WriteVLD3], (instregex "LD1Threev(8b|4h|2s|1d)$")>;
-def : InstRW<[CortexA55WriteVLD6], (instregex "LD1Threev(16b|8h|4s|2d)$")>;
-def : InstRW<[CortexA55WriteVLD4], (instregex "LD1Fourv(8b|4h|2s|1d)$")>;
-def : InstRW<[CortexA55WriteVLD8], (instregex "LD1Fourv(16b|8h|4s|2d)$")>;
-
-def : InstRW<[CortexA55WriteVLD1, WriteAdr], (instregex "LD1i(8|16|32|64)_POST$")>;
-def : InstRW<[CortexA55WriteVLD1, WriteAdr], (instregex "LD1Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-def : InstRW<[CortexA55WriteVLD1, WriteAdr], (instregex "LD1Onev(8b|4h|2s|1d)_POST$")>;
-def : InstRW<[CortexA55WriteVLD2, WriteAdr], (instregex "LD1Onev(16b|8h|4s|2d)_POST$")>;
-def : InstRW<[CortexA55WriteVLD2, WriteAdr], (instregex "LD1Twov(8b|4h|2s|1d)_POST$")>;
-def : InstRW<[CortexA55WriteVLD4, WriteAdr], (instregex "LD1Twov(16b|8h|4s|2d)_POST$")>;
-def : InstRW<[CortexA55WriteVLD3, WriteAdr], (instregex "LD1Threev(8b|4h|2s|1d)_POST$")>;
-def : InstRW<[CortexA55WriteVLD6, WriteAdr], (instregex "LD1Threev(16b|8h|4s|2d)_POST$")>;
-def : InstRW<[CortexA55WriteVLD4, WriteAdr], (instregex "LD1Fourv(8b|4h|2s|1d)_POST$")>;
-def : InstRW<[CortexA55WriteVLD8, WriteAdr], (instregex "LD1Fourv(16b|8h|4s|2d)_POST$")>;
-
-// 2-element structures
-def : InstRW<[CortexA55WriteVLD2], (instregex "LD2i(8|16|32|64)$")>;
-def : InstRW<[CortexA55WriteVLD2], (instregex "LD2Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[CortexA55WriteVLD2], (instregex "LD2Twov(8b|4h|2s)$")>;
-def : InstRW<[CortexA55WriteVLD4], (instregex "LD2Twov(16b|8h|4s|2d)$")>;
-
-def : InstRW<[CortexA55WriteVLD2, WriteAdr], (instregex "LD2i(8|16|32|64)(_POST)?$")>;
-def : InstRW<[CortexA55WriteVLD2, WriteAdr], (instregex "LD2Rv(8b|4h|2s|1d|16b|8h|4s|2d)(_POST)?$")>;
-def : InstRW<[CortexA55WriteVLD2, WriteAdr], (instregex "LD2Twov(8b|4h|2s)(_POST)?$")>;
-def : InstRW<[CortexA55WriteVLD4, WriteAdr], (instregex "LD2Twov(16b|8h|4s|2d)(_POST)?$")>;
-
-// 3-element structures
-def : InstRW<[CortexA55WriteVLD2], (instregex "LD3i(8|16|32|64)$")>;
-def : InstRW<[CortexA55WriteVLD2], (instregex "LD3Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[CortexA55WriteVLD3], (instregex "LD3Threev(8b|4h|2s|1d)$")>;
-def : InstRW<[CortexA55WriteVLD6], (instregex "LD3Threev(16b|8h|4s|2d)$")>;
-
-def : InstRW<[CortexA55WriteVLD2, WriteAdr], (instregex "LD3i(8|16|32|64)_POST$")>;
-def : InstRW<[CortexA55WriteVLD2, WriteAdr], (instregex "LD3Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-def : InstRW<[CortexA55WriteVLD3, WriteAdr], (instregex "LD3Threev(8b|4h|2s|1d)_POST$")>;
-def : InstRW<[CortexA55WriteVLD6, WriteAdr], (instregex "LD3Threev(16b|8h|4s|2d)_POST$")>;
-
-// 4-element structures
-def : InstRW<[CortexA55WriteVLD2], (instregex "LD4i(8|16|32|64)$")>; // load single 4-el structure to one lane of 4 regs.
-def : InstRW<[CortexA55WriteVLD2], (instregex "LD4Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>; // load single 4-el structure, replicate to all lanes of 4 regs.
-def : InstRW<[CortexA55WriteVLD4], (instregex "LD4Fourv(8b|4h|2s|1d)$")>; // load multiple 4-el structures to 4 regs.
-def : InstRW<[CortexA55WriteVLD8], (instregex "LD4Fourv(16b|8h|4s|2d)$")>;
-
-def : InstRW<[CortexA55WriteVLD2, WriteAdr], (instregex "LD4i(8|16|32|64)_POST$")>;
-def : InstRW<[CortexA55WriteVLD2, WriteAdr], (instregex "LD4Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-def : InstRW<[CortexA55WriteVLD4, WriteAdr], (instregex "LD4Fourv(8b|4h|2s|1d)_POST$")>;
-def : InstRW<[CortexA55WriteVLD8, WriteAdr], (instregex "LD4Fourv(16b|8h|4s|2d)_POST$")>;
-
-//---
-// Vector Stores
-//---
-def : InstRW<[CortexA55WriteVST1], (instregex "ST1i(8|16|32|64)$")>;
-def : InstRW<[CortexA55WriteVST1], (instregex "ST1Onev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[CortexA55WriteVST1], (instregex "ST1Twov(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[CortexA55WriteVST2], (instregex "ST1Threev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[CortexA55WriteVST4], (instregex "ST1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[CortexA55WriteVST1, WriteAdr], (instregex "ST1i(8|16|32|64)_POST$")>;
-def : InstRW<[CortexA55WriteVST1, WriteAdr], (instregex "ST1Onev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-def : InstRW<[CortexA55WriteVST1, WriteAdr], (instregex "ST1Twov(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-def : InstRW<[CortexA55WriteVST2, WriteAdr], (instregex "ST1Threev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-def : InstRW<[CortexA55WriteVST4, WriteAdr], (instregex "ST1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-def : InstRW<[CortexA55WriteVST2], (instregex "ST2i(8|16|32|64)$")>;
-def : InstRW<[CortexA55WriteVST2], (instregex "ST2Twov(8b|4h|2s)$")>;
-def : InstRW<[CortexA55WriteVST4], (instregex "ST2Twov(16b|8h|4s|2d)$")>;
-def : InstRW<[CortexA55WriteVST2, WriteAdr], (instregex "ST2i(8|16|32|64)_POST$")>;
-def : InstRW<[CortexA55WriteVST2, WriteAdr], (instregex "ST2Twov(8b|4h|2s)_POST$")>;
-def : InstRW<[CortexA55WriteVST4, WriteAdr], (instregex "ST2Twov(16b|8h|4s|2d)_POST$")>;
-
-def : InstRW<[CortexA55WriteVST2], (instregex "ST3i(8|16|32|64)$")>;
-def : InstRW<[CortexA55WriteVST4], (instregex "ST3Threev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[CortexA55WriteVST2, WriteAdr], (instregex "ST3i(8|16|32|64)_POST$")>;
-def : InstRW<[CortexA55WriteVST4, WriteAdr], (instregex "ST3Threev(8b|4h|2s|1d|2d|16b|8h|4s|4d)_POST$")>;
-
-def : InstRW<[CortexA55WriteVST2], (instregex "ST4i(8|16|32|64)$")>;
-def : InstRW<[CortexA55WriteVST4], (instregex "ST4Fourv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[CortexA55WriteVST2, WriteAdr], (instregex "ST4i(8|16|32|64)_POST$")>;
-def : InstRW<[CortexA55WriteVST4, WriteAdr], (instregex "ST4Fourv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-//---
-// Floating Point Conversions, MAC, DIV, SQRT
-//---
-def : InstRW<[CortexA55WriteFPALU_F3], (instregex "^FCVT[ALMNPZ][SU](S|U)?(W|X)")>;
-def : InstRW<[CortexA55WriteFPALU_F4], (instregex "^FCVT(X)?[ALMNPXZ](S|U|N)?v")>;
-
-def : InstRW<[CortexA55WriteFPALU_F4], (instregex "^(S|U)CVTF(S|U)(W|X)(H|S|D)")>;
-def : InstRW<[CortexA55WriteFPALU_F4], (instregex "^(S|U)CVTF(h|s|d)")>;
-def : InstRW<[CortexA55WriteFPALU_F4], (instregex "^(S|U)CVTFv")>;
-
-def : InstRW<[CortexA55WriteFMAC], (instregex "^FN?M(ADD|SUB).*")>;
-def : InstRW<[CortexA55WriteFMAC], (instregex "^FML(A|S).*")>;
-def : InstRW<[CortexA55WriteFDivHP], (instrs FDIVHrr)>;
-def : InstRW<[CortexA55WriteFDivSP], (instrs FDIVSrr)>;
-def : InstRW<[CortexA55WriteFDivDP], (instrs FDIVDrr)>;
-def : InstRW<[CortexA55WriteFDivHP], (instregex "^FDIVv.*16$")>;
-def : InstRW<[CortexA55WriteFDivSP], (instregex "^FDIVv.*32$")>;
-def : InstRW<[CortexA55WriteFDivDP], (instregex "^FDIVv.*64$")>;
-def : InstRW<[CortexA55WriteFSqrtHP], (instregex "^.*SQRT.*16$")>;
-def : InstRW<[CortexA55WriteFSqrtSP], (instregex "^.*SQRT.*32$")>;
-def : InstRW<[CortexA55WriteFSqrtDP], (instregex "^.*SQRT.*64$")>;
-}
+//==- AArch64SchedCortexA55.td - ARM Cortex-A55 Scheduling Definitions -*- tablegen -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the machine model for the ARM Cortex-A55 processors.
+//
+//===----------------------------------------------------------------------===//
+
+// ===---------------------------------------------------------------------===//
+// The following definitions describe the per-operand machine model.
+// This works with MachineScheduler. See MCSchedModel.h for details.
+
+// Cortex-A55 machine model for scheduling and other instruction cost heuristics.
+def CortexA55Model : SchedMachineModel {
+ let MicroOpBufferSize = 0; // The Cortex-A55 is an in-order processor
+ let IssueWidth = 2; // It dual-issues under most circumstances
+ let LoadLatency = 4; // Cycles for loads to access the cache. The
+ // optimisation guide shows that most loads have
+ // a latency of 3, but some have a latency of 4
+ // or 5. Setting it 4 looked to be good trade-off.
+ let MispredictPenalty = 8; // A branch direction mispredict.
+ let PostRAScheduler = 1; // Enable PostRA scheduler pass.
+ let CompleteModel = 0; // Covers instructions applicable to Cortex-A55.
+
+ list<Predicate> UnsupportedFeatures = [HasSVE];
+
+ // FIXME: Remove when all errors have been fixed.
+ let FullInstRWOverlapCheck = 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Define each kind of processor resource and number available.
+
+// Modeling each pipeline as a ProcResource using the BufferSize = 0 since the
+// Cortex-A55 is in-order.
+
+def CortexA55UnitALU : ProcResource<2> { let BufferSize = 0; } // Int ALU
+def CortexA55UnitMAC : ProcResource<1> { let BufferSize = 0; } // Int MAC, 64-bi wide
+def CortexA55UnitDiv : ProcResource<1> { let BufferSize = 0; } // Int Division, not pipelined
+def CortexA55UnitLd : ProcResource<1> { let BufferSize = 0; } // Load pipe
+def CortexA55UnitSt : ProcResource<1> { let BufferSize = 0; } // Store pipe
+def CortexA55UnitB : ProcResource<1> { let BufferSize = 0; } // Branch
+
+// The FP DIV/SQRT instructions execute totally differently from the FP ALU
+// instructions, which can mostly be dual-issued; that's why for now we model
+// them with 2 resources.
+def CortexA55UnitFPALU : ProcResource<2> { let BufferSize = 0; } // FP ALU
+def CortexA55UnitFPMAC : ProcResource<2> { let BufferSize = 0; } // FP MAC
+def CortexA55UnitFPDIV : ProcResource<1> { let BufferSize = 0; } // FP Div/SQRT, 64/128
+
+//===----------------------------------------------------------------------===//
+// Subtarget-specific SchedWrite types
+
+let SchedModel = CortexA55Model in {
+
+// These latencies are modeled without taking into account forwarding paths
+// (the software optimisation guide lists latencies taking into account
+// typical forwarding paths).
+def : WriteRes<WriteImm, [CortexA55UnitALU]> { let Latency = 3; } // MOVN, MOVZ
+def : WriteRes<WriteI, [CortexA55UnitALU]> { let Latency = 3; } // ALU
+def : WriteRes<WriteISReg, [CortexA55UnitALU]> { let Latency = 3; } // ALU of Shifted-Reg
+def : WriteRes<WriteIEReg, [CortexA55UnitALU]> { let Latency = 3; } // ALU of Extended-Reg
+def : WriteRes<WriteExtr, [CortexA55UnitALU]> { let Latency = 3; } // EXTR from a reg pair
+def : WriteRes<WriteIS, [CortexA55UnitALU]> { let Latency = 3; } // Shift/Scale
+
+// MAC
+def : WriteRes<WriteIM32, [CortexA55UnitMAC]> { let Latency = 4; } // 32-bit Multiply
+def : WriteRes<WriteIM64, [CortexA55UnitMAC]> { let Latency = 4; } // 64-bit Multiply
+
+// Div
+def : WriteRes<WriteID32, [CortexA55UnitDiv]> {
+ let Latency = 8; let ResourceCycles = [8];
+}
+def : WriteRes<WriteID64, [CortexA55UnitDiv]> {
+ let Latency = 8; let ResourceCycles = [8];
+}
+
+// Load
+def : WriteRes<WriteLD, [CortexA55UnitLd]> { let Latency = 3; }
+def : WriteRes<WriteLDIdx, [CortexA55UnitLd]> { let Latency = 4; }
+def : WriteRes<WriteLDHi, [CortexA55UnitLd]> { let Latency = 5; }
+
+// Vector Load - Vector loads take 1-5 cycles to issue. For the WriteVecLd
+// below, choosing the median of 3 which makes the latency 6.
+// An extra cycle is needed to get the swizzling right.
+def : WriteRes<WriteVLD, [CortexA55UnitLd]> { let Latency = 6;
+ let ResourceCycles = [3]; }
+def CortexA55WriteVLD1 : SchedWriteRes<[CortexA55UnitLd]> { let Latency = 4; }
+def CortexA55WriteVLD2 : SchedWriteRes<[CortexA55UnitLd]> { let Latency = 5;
+ let ResourceCycles = [2]; }
+def CortexA55WriteVLD3 : SchedWriteRes<[CortexA55UnitLd]> { let Latency = 6;
+ let ResourceCycles = [3]; }
+def CortexA55WriteVLD4 : SchedWriteRes<[CortexA55UnitLd]> { let Latency = 7;
+ let ResourceCycles = [4]; }
+def CortexA55WriteVLD5 : SchedWriteRes<[CortexA55UnitLd]> { let Latency = 8;
+ let ResourceCycles = [5]; }
+def CortexA55WriteVLD6 : SchedWriteRes<[CortexA55UnitLd]> { let Latency = 9;
+ let ResourceCycles = [6]; }
+def CortexA55WriteVLD7 : SchedWriteRes<[CortexA55UnitLd]> { let Latency = 10;
+ let ResourceCycles = [7]; }
+def CortexA55WriteVLD8 : SchedWriteRes<[CortexA55UnitLd]> { let Latency = 11;
+ let ResourceCycles = [8]; }
+
+// Pre/Post Indexing - Performed as part of address generation
+def : WriteRes<WriteAdr, []> { let Latency = 0; }
+
+// Store
+def : WriteRes<WriteST, [CortexA55UnitSt]> { let Latency = 4; }
+def : WriteRes<WriteSTP, [CortexA55UnitSt]> { let Latency = 4; }
+def : WriteRes<WriteSTIdx, [CortexA55UnitSt]> { let Latency = 4; }
+def : WriteRes<WriteSTX, [CortexA55UnitSt]> { let Latency = 4; }
+
+// Vector Store - Similar to vector loads, can take 1-3 cycles to issue.
+def : WriteRes<WriteVST, [CortexA55UnitSt]> { let Latency = 5;
+ let ResourceCycles = [2];}
+def CortexA55WriteVST1 : SchedWriteRes<[CortexA55UnitSt]> { let Latency = 4; }
+def CortexA55WriteVST2 : SchedWriteRes<[CortexA55UnitSt]> { let Latency = 5;
+ let ResourceCycles = [2]; }
+def CortexA55WriteVST3 : SchedWriteRes<[CortexA55UnitSt]> { let Latency = 6;
+ let ResourceCycles = [3]; }
+def CortexA55WriteVST4 : SchedWriteRes<[CortexA55UnitSt]> { let Latency = 5;
+ let ResourceCycles = [4]; }
+
+def : WriteRes<WriteAtomic, []> { let Unsupported = 1; }
+
+// Branch
+def : WriteRes<WriteBr, [CortexA55UnitB]>;
+def : WriteRes<WriteBrReg, [CortexA55UnitB]>;
+def : WriteRes<WriteSys, [CortexA55UnitB]>;
+def : WriteRes<WriteBarrier, [CortexA55UnitB]>;
+def : WriteRes<WriteHint, [CortexA55UnitB]>;
+
+// FP ALU
+// As WriteF result is produced in F5 and it can be mostly forwarded
+// to consumer at F1, the effectively latency is set as 4.
+def : WriteRes<WriteF, [CortexA55UnitFPALU]> { let Latency = 4; }
+def : WriteRes<WriteFCmp, [CortexA55UnitFPALU]> { let Latency = 3; }
+def : WriteRes<WriteFCvt, [CortexA55UnitFPALU]> { let Latency = 4; }
+def : WriteRes<WriteFCopy, [CortexA55UnitFPALU]> { let Latency = 3; }
+def : WriteRes<WriteFImm, [CortexA55UnitFPALU]> { let Latency = 3; }
+def : WriteRes<WriteV, [CortexA55UnitFPALU]> { let Latency = 4; }
+
+// FP ALU specific new schedwrite definitions
+def CortexA55WriteFPALU_F3 : SchedWriteRes<[CortexA55UnitFPALU]> { let Latency = 3;}
+def CortexA55WriteFPALU_F4 : SchedWriteRes<[CortexA55UnitFPALU]> { let Latency = 4;}
+def CortexA55WriteFPALU_F5 : SchedWriteRes<[CortexA55UnitFPALU]> { let Latency = 5;}
+
+// FP Mul, Div, Sqrt. Div/Sqrt are not pipelined
+def : WriteRes<WriteFMul, [CortexA55UnitFPMAC]> { let Latency = 4; }
+def : WriteRes<WriteFDiv, [CortexA55UnitFPDIV]> { let Latency = 22;
+ let ResourceCycles = [29]; }
+def CortexA55WriteFMAC : SchedWriteRes<[CortexA55UnitFPMAC]> { let Latency = 4; }
+def CortexA55WriteFDivHP : SchedWriteRes<[CortexA55UnitFPDIV]> { let Latency = 8;
+ let ResourceCycles = [5]; }
+def CortexA55WriteFDivSP : SchedWriteRes<[CortexA55UnitFPDIV]> { let Latency = 13;
+ let ResourceCycles = [10]; }
+def CortexA55WriteFDivDP : SchedWriteRes<[CortexA55UnitFPDIV]> { let Latency = 22;
+ let ResourceCycles = [19]; }
+def CortexA55WriteFSqrtHP : SchedWriteRes<[CortexA55UnitFPDIV]> { let Latency = 8;
+ let ResourceCycles = [5]; }
+def CortexA55WriteFSqrtSP : SchedWriteRes<[CortexA55UnitFPDIV]> { let Latency = 12;
+ let ResourceCycles = [9]; }
+def CortexA55WriteFSqrtDP : SchedWriteRes<[CortexA55UnitFPDIV]> { let Latency = 22;
+ let ResourceCycles = [19]; }
+
+//===----------------------------------------------------------------------===//
+// Subtarget-specific SchedRead types.
+
+def : ReadAdvance<ReadVLD, 0>;
+def : ReadAdvance<ReadExtrHi, 1>;
+def : ReadAdvance<ReadAdrBase, 1>;
+
+// ALU - ALU input operands are generally needed in EX1. An operand produced in
+// in say EX2 can be forwarded for consumption to ALU in EX1, thereby
+// allowing back-to-back ALU operations such as add. If an operand requires
+// a shift, it will, however, be required in ISS stage.
+def : ReadAdvance<ReadI, 2, [WriteImm,WriteI,
+ WriteISReg, WriteIEReg,WriteIS,
+ WriteID32,WriteID64,
+ WriteIM32,WriteIM64]>;
+// Shifted operand
+def CortexA55ReadShifted : SchedReadAdvance<1, [WriteImm,WriteI,
+ WriteISReg, WriteIEReg,WriteIS,
+ WriteID32,WriteID64,
+ WriteIM32,WriteIM64]>;
+def CortexA55ReadNotShifted : SchedReadAdvance<2, [WriteImm,WriteI,
+ WriteISReg, WriteIEReg,WriteIS,
+ WriteID32,WriteID64,
+ WriteIM32,WriteIM64]>;
+def CortexA55ReadISReg : SchedReadVariant<[
+ SchedVar<RegShiftedPred, [CortexA55ReadShifted]>,
+ SchedVar<NoSchedPred, [CortexA55ReadNotShifted]>]>;
+def : SchedAlias<ReadISReg, CortexA55ReadISReg>;
+
+def CortexA55ReadIEReg : SchedReadVariant<[
+ SchedVar<RegExtendedPred, [CortexA55ReadShifted]>,
+ SchedVar<NoSchedPred, [CortexA55ReadNotShifted]>]>;
+def : SchedAlias<ReadIEReg, CortexA55ReadIEReg>;
+
+// MUL
+def : ReadAdvance<ReadIM, 1, [WriteImm,WriteI,
+ WriteISReg, WriteIEReg,WriteIS,
+ WriteID32,WriteID64,
+ WriteIM32,WriteIM64]>;
+def : ReadAdvance<ReadIMA, 2, [WriteImm,WriteI,
+ WriteISReg, WriteIEReg,WriteIS,
+ WriteID32,WriteID64,
+ WriteIM32,WriteIM64]>;
+
+// Div
+def : ReadAdvance<ReadID, 1, [WriteImm,WriteI,
+ WriteISReg, WriteIEReg,WriteIS,
+ WriteID32,WriteID64,
+ WriteIM32,WriteIM64]>;
+
+//===----------------------------------------------------------------------===//
+// Subtarget-specific InstRWs.
+
+//---
+// Miscellaneous
+//---
+def : InstRW<[CortexA55WriteVLD2,CortexA55WriteVLD1], (instregex "LDP.*")>;
+def : InstRW<[WriteI], (instrs COPY)>;
+//---
+// Vector Loads - 64-bit per cycle
+//---
+// 1-element structures
+def : InstRW<[CortexA55WriteVLD1], (instregex "LD1i(8|16|32|64)$")>; // single element
+def : InstRW<[CortexA55WriteVLD1], (instregex "LD1Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>; // replicate
+def : InstRW<[CortexA55WriteVLD1], (instregex "LD1Onev(8b|4h|2s|1d)$")>;
+def : InstRW<[CortexA55WriteVLD2], (instregex "LD1Onev(16b|8h|4s|2d)$")>;
+def : InstRW<[CortexA55WriteVLD2], (instregex "LD1Twov(8b|4h|2s|1d)$")>; // multiple structures
+def : InstRW<[CortexA55WriteVLD4], (instregex "LD1Twov(16b|8h|4s|2d)$")>;
+def : InstRW<[CortexA55WriteVLD3], (instregex "LD1Threev(8b|4h|2s|1d)$")>;
+def : InstRW<[CortexA55WriteVLD6], (instregex "LD1Threev(16b|8h|4s|2d)$")>;
+def : InstRW<[CortexA55WriteVLD4], (instregex "LD1Fourv(8b|4h|2s|1d)$")>;
+def : InstRW<[CortexA55WriteVLD8], (instregex "LD1Fourv(16b|8h|4s|2d)$")>;
+
+def : InstRW<[CortexA55WriteVLD1, WriteAdr], (instregex "LD1i(8|16|32|64)_POST$")>;
+def : InstRW<[CortexA55WriteVLD1, WriteAdr], (instregex "LD1Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+def : InstRW<[CortexA55WriteVLD1, WriteAdr], (instregex "LD1Onev(8b|4h|2s|1d)_POST$")>;
+def : InstRW<[CortexA55WriteVLD2, WriteAdr], (instregex "LD1Onev(16b|8h|4s|2d)_POST$")>;
+def : InstRW<[CortexA55WriteVLD2, WriteAdr], (instregex "LD1Twov(8b|4h|2s|1d)_POST$")>;
+def : InstRW<[CortexA55WriteVLD4, WriteAdr], (instregex "LD1Twov(16b|8h|4s|2d)_POST$")>;
+def : InstRW<[CortexA55WriteVLD3, WriteAdr], (instregex "LD1Threev(8b|4h|2s|1d)_POST$")>;
+def : InstRW<[CortexA55WriteVLD6, WriteAdr], (instregex "LD1Threev(16b|8h|4s|2d)_POST$")>;
+def : InstRW<[CortexA55WriteVLD4, WriteAdr], (instregex "LD1Fourv(8b|4h|2s|1d)_POST$")>;
+def : InstRW<[CortexA55WriteVLD8, WriteAdr], (instregex "LD1Fourv(16b|8h|4s|2d)_POST$")>;
+
+// 2-element structures
+def : InstRW<[CortexA55WriteVLD2], (instregex "LD2i(8|16|32|64)$")>;
+def : InstRW<[CortexA55WriteVLD2], (instregex "LD2Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[CortexA55WriteVLD2], (instregex "LD2Twov(8b|4h|2s)$")>;
+def : InstRW<[CortexA55WriteVLD4], (instregex "LD2Twov(16b|8h|4s|2d)$")>;
+
+def : InstRW<[CortexA55WriteVLD2, WriteAdr], (instregex "LD2i(8|16|32|64)(_POST)?$")>;
+def : InstRW<[CortexA55WriteVLD2, WriteAdr], (instregex "LD2Rv(8b|4h|2s|1d|16b|8h|4s|2d)(_POST)?$")>;
+def : InstRW<[CortexA55WriteVLD2, WriteAdr], (instregex "LD2Twov(8b|4h|2s)(_POST)?$")>;
+def : InstRW<[CortexA55WriteVLD4, WriteAdr], (instregex "LD2Twov(16b|8h|4s|2d)(_POST)?$")>;
+
+// 3-element structures
+def : InstRW<[CortexA55WriteVLD2], (instregex "LD3i(8|16|32|64)$")>;
+def : InstRW<[CortexA55WriteVLD2], (instregex "LD3Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[CortexA55WriteVLD3], (instregex "LD3Threev(8b|4h|2s|1d)$")>;
+def : InstRW<[CortexA55WriteVLD6], (instregex "LD3Threev(16b|8h|4s|2d)$")>;
+
+def : InstRW<[CortexA55WriteVLD2, WriteAdr], (instregex "LD3i(8|16|32|64)_POST$")>;
+def : InstRW<[CortexA55WriteVLD2, WriteAdr], (instregex "LD3Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+def : InstRW<[CortexA55WriteVLD3, WriteAdr], (instregex "LD3Threev(8b|4h|2s|1d)_POST$")>;
+def : InstRW<[CortexA55WriteVLD6, WriteAdr], (instregex "LD3Threev(16b|8h|4s|2d)_POST$")>;
+
+// 4-element structures
+def : InstRW<[CortexA55WriteVLD2], (instregex "LD4i(8|16|32|64)$")>; // load single 4-el structure to one lane of 4 regs.
+def : InstRW<[CortexA55WriteVLD2], (instregex "LD4Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>; // load single 4-el structure, replicate to all lanes of 4 regs.
+def : InstRW<[CortexA55WriteVLD4], (instregex "LD4Fourv(8b|4h|2s|1d)$")>; // load multiple 4-el structures to 4 regs.
+def : InstRW<[CortexA55WriteVLD8], (instregex "LD4Fourv(16b|8h|4s|2d)$")>;
+
+def : InstRW<[CortexA55WriteVLD2, WriteAdr], (instregex "LD4i(8|16|32|64)_POST$")>;
+def : InstRW<[CortexA55WriteVLD2, WriteAdr], (instregex "LD4Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+def : InstRW<[CortexA55WriteVLD4, WriteAdr], (instregex "LD4Fourv(8b|4h|2s|1d)_POST$")>;
+def : InstRW<[CortexA55WriteVLD8, WriteAdr], (instregex "LD4Fourv(16b|8h|4s|2d)_POST$")>;
+
+//---
+// Vector Stores
+//---
+def : InstRW<[CortexA55WriteVST1], (instregex "ST1i(8|16|32|64)$")>;
+def : InstRW<[CortexA55WriteVST1], (instregex "ST1Onev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[CortexA55WriteVST1], (instregex "ST1Twov(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[CortexA55WriteVST2], (instregex "ST1Threev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[CortexA55WriteVST4], (instregex "ST1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[CortexA55WriteVST1, WriteAdr], (instregex "ST1i(8|16|32|64)_POST$")>;
+def : InstRW<[CortexA55WriteVST1, WriteAdr], (instregex "ST1Onev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+def : InstRW<[CortexA55WriteVST1, WriteAdr], (instregex "ST1Twov(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+def : InstRW<[CortexA55WriteVST2, WriteAdr], (instregex "ST1Threev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+def : InstRW<[CortexA55WriteVST4, WriteAdr], (instregex "ST1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+def : InstRW<[CortexA55WriteVST2], (instregex "ST2i(8|16|32|64)$")>;
+def : InstRW<[CortexA55WriteVST2], (instregex "ST2Twov(8b|4h|2s)$")>;
+def : InstRW<[CortexA55WriteVST4], (instregex "ST2Twov(16b|8h|4s|2d)$")>;
+def : InstRW<[CortexA55WriteVST2, WriteAdr], (instregex "ST2i(8|16|32|64)_POST$")>;
+def : InstRW<[CortexA55WriteVST2, WriteAdr], (instregex "ST2Twov(8b|4h|2s)_POST$")>;
+def : InstRW<[CortexA55WriteVST4, WriteAdr], (instregex "ST2Twov(16b|8h|4s|2d)_POST$")>;
+
+def : InstRW<[CortexA55WriteVST2], (instregex "ST3i(8|16|32|64)$")>;
+def : InstRW<[CortexA55WriteVST4], (instregex "ST3Threev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[CortexA55WriteVST2, WriteAdr], (instregex "ST3i(8|16|32|64)_POST$")>;
+def : InstRW<[CortexA55WriteVST4, WriteAdr], (instregex "ST3Threev(8b|4h|2s|1d|2d|16b|8h|4s|4d)_POST$")>;
+
+def : InstRW<[CortexA55WriteVST2], (instregex "ST4i(8|16|32|64)$")>;
+def : InstRW<[CortexA55WriteVST4], (instregex "ST4Fourv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[CortexA55WriteVST2, WriteAdr], (instregex "ST4i(8|16|32|64)_POST$")>;
+def : InstRW<[CortexA55WriteVST4, WriteAdr], (instregex "ST4Fourv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+//---
+// Floating Point Conversions, MAC, DIV, SQRT
+//---
+def : InstRW<[CortexA55WriteFPALU_F3], (instregex "^FCVT[ALMNPZ][SU](S|U)?(W|X)")>;
+def : InstRW<[CortexA55WriteFPALU_F4], (instregex "^FCVT(X)?[ALMNPXZ](S|U|N)?v")>;
+
+def : InstRW<[CortexA55WriteFPALU_F4], (instregex "^(S|U)CVTF(S|U)(W|X)(H|S|D)")>;
+def : InstRW<[CortexA55WriteFPALU_F4], (instregex "^(S|U)CVTF(h|s|d)")>;
+def : InstRW<[CortexA55WriteFPALU_F4], (instregex "^(S|U)CVTFv")>;
+
+def : InstRW<[CortexA55WriteFMAC], (instregex "^FN?M(ADD|SUB).*")>;
+def : InstRW<[CortexA55WriteFMAC], (instregex "^FML(A|S).*")>;
+def : InstRW<[CortexA55WriteFDivHP], (instrs FDIVHrr)>;
+def : InstRW<[CortexA55WriteFDivSP], (instrs FDIVSrr)>;
+def : InstRW<[CortexA55WriteFDivDP], (instrs FDIVDrr)>;
+def : InstRW<[CortexA55WriteFDivHP], (instregex "^FDIVv.*16$")>;
+def : InstRW<[CortexA55WriteFDivSP], (instregex "^FDIVv.*32$")>;
+def : InstRW<[CortexA55WriteFDivDP], (instregex "^FDIVv.*64$")>;
+def : InstRW<[CortexA55WriteFSqrtHP], (instregex "^.*SQRT.*16$")>;
+def : InstRW<[CortexA55WriteFSqrtSP], (instregex "^.*SQRT.*32$")>;
+def : InstRW<[CortexA55WriteFSqrtDP], (instregex "^.*SQRT.*64$")>;
+}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA57.td b/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA57.td
index 0ee50541c0..aa5bec8088 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA57.td
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA57.td
@@ -93,7 +93,7 @@ def : SchedAlias<WriteFCmp, A57Write_3cyc_1V>;
def : SchedAlias<WriteFCvt, A57Write_5cyc_1V>;
def : SchedAlias<WriteFCopy, A57Write_5cyc_1L>;
def : SchedAlias<WriteFImm, A57Write_3cyc_1V>;
-def : WriteRes<WriteFMul, [A57UnitV]> { let Latency = 5;}
+def : WriteRes<WriteFMul, [A57UnitV]> { let Latency = 5;}
def : SchedAlias<WriteFDiv, A57Write_17cyc_1W>;
def : SchedAlias<WriteV, A57Write_3cyc_1V>;
def : SchedAlias<WriteVLD, A57Write_5cyc_1L>;
@@ -350,16 +350,16 @@ def : InstRW<[A57Write_8cyc_8S, WriteAdr], (instregex "ST4Fourv(2d)_POST$")
// D form - v8i8_v8i16, v4i16_v4i32, v2i32_v2i64
// Q form - v16i8_v8i16, v8i16_v4i32, v4i32_v2i64
-// Cortex A57 Software Optimization Guide Sec 3.14
-// Advance for absolute diff accum, pairwise add and accumulate, shift accumulate
-def A57ReadIVA3 : SchedReadAdvance<3, [A57Write_4cyc_1X_NonMul_Forward, A57Write_5cyc_2X_NonMul_Forward]>;
-
+// Cortex A57 Software Optimization Guide Sec 3.14
+// Advance for absolute diff accum, pairwise add and accumulate, shift accumulate
+def A57ReadIVA3 : SchedReadAdvance<3, [A57Write_4cyc_1X_NonMul_Forward, A57Write_5cyc_2X_NonMul_Forward]>;
+
// ASIMD absolute diff accum, D-form
-def : InstRW<[A57Write_4cyc_1X_NonMul_Forward, A57ReadIVA3], (instregex "^[SU]ABA(v8i8|v4i16|v2i32)$")>;
+def : InstRW<[A57Write_4cyc_1X_NonMul_Forward, A57ReadIVA3], (instregex "^[SU]ABA(v8i8|v4i16|v2i32)$")>;
// ASIMD absolute diff accum, Q-form
-def : InstRW<[A57Write_5cyc_2X_NonMul_Forward, A57ReadIVA3], (instregex "^[SU]ABA(v16i8|v8i16|v4i32)$")>;
+def : InstRW<[A57Write_5cyc_2X_NonMul_Forward, A57ReadIVA3], (instregex "^[SU]ABA(v16i8|v8i16|v4i32)$")>;
// ASIMD absolute diff accum long
-def : InstRW<[A57Write_4cyc_1X_NonMul_Forward, A57ReadIVA3], (instregex "^[SU]ABAL")>;
+def : InstRW<[A57Write_4cyc_1X_NonMul_Forward, A57ReadIVA3], (instregex "^[SU]ABAL")>;
// ASIMD arith, reduce, 4H/4S
def : InstRW<[A57Write_4cyc_1X], (instregex "^[SU]?ADDL?V(v8i8|v4i16|v2i32)v$")>;
@@ -376,41 +376,41 @@ def : InstRW<[A57Write_7cyc_1V_1X], (instregex "^[SU](MIN|MAX)V(v8i8|v8i16)v$")>
def : InstRW<[A57Write_8cyc_2X], (instregex "^[SU](MIN|MAX)Vv16i8v$")>;
// ASIMD multiply, D-form
-// MUL
-def : InstRW<[A57Write_5cyc_1W_Mul_Forward], (instregex "^MUL(v8i8|v4i16|v2i32|v1i8|v1i16|v1i32|v1i64)(_indexed)?$")>;
-// PMUL, SQDMULH, SQRDMULH
-def : InstRW<[A57Write_5cyc_1W], (instregex "^(PMUL|SQR?DMULH)(v8i8|v4i16|v2i32|v1i8|v1i16|v1i32|v1i64)(_indexed)?$")>;
-
+// MUL
+def : InstRW<[A57Write_5cyc_1W_Mul_Forward], (instregex "^MUL(v8i8|v4i16|v2i32|v1i8|v1i16|v1i32|v1i64)(_indexed)?$")>;
+// PMUL, SQDMULH, SQRDMULH
+def : InstRW<[A57Write_5cyc_1W], (instregex "^(PMUL|SQR?DMULH)(v8i8|v4i16|v2i32|v1i8|v1i16|v1i32|v1i64)(_indexed)?$")>;
+
// ASIMD multiply, Q-form
-// MUL
-def : InstRW<[A57Write_6cyc_2W_Mul_Forward], (instregex "^MUL(v16i8|v8i16|v4i32)(_indexed)?$")>;
-// PMUL, SQDMULH, SQRDMULH
-def : InstRW<[A57Write_6cyc_2W], (instregex "^(PMUL|SQR?DMULH)(v16i8|v8i16|v4i32)(_indexed)?$")>;
-
-// Cortex A57 Software Optimization Guide Sec 3.14
-def A57ReadIVMA4 : SchedReadAdvance<4 , [A57Write_5cyc_1W_Mul_Forward, A57Write_6cyc_2W_Mul_Forward]>;
-def A57ReadIVMA3 : SchedReadAdvance<3 , [A57Write_5cyc_1W_Mul_Forward, A57Write_6cyc_2W_Mul_Forward]>;
-
+// MUL
+def : InstRW<[A57Write_6cyc_2W_Mul_Forward], (instregex "^MUL(v16i8|v8i16|v4i32)(_indexed)?$")>;
+// PMUL, SQDMULH, SQRDMULH
+def : InstRW<[A57Write_6cyc_2W], (instregex "^(PMUL|SQR?DMULH)(v16i8|v8i16|v4i32)(_indexed)?$")>;
+
+// Cortex A57 Software Optimization Guide Sec 3.14
+def A57ReadIVMA4 : SchedReadAdvance<4 , [A57Write_5cyc_1W_Mul_Forward, A57Write_6cyc_2W_Mul_Forward]>;
+def A57ReadIVMA3 : SchedReadAdvance<3 , [A57Write_5cyc_1W_Mul_Forward, A57Write_6cyc_2W_Mul_Forward]>;
+
// ASIMD multiply accumulate, D-form
-def : InstRW<[A57Write_5cyc_1W_Mul_Forward, A57ReadIVMA4], (instregex "^ML[AS](v8i8|v4i16|v2i32)(_indexed)?$")>;
+def : InstRW<[A57Write_5cyc_1W_Mul_Forward, A57ReadIVMA4], (instregex "^ML[AS](v8i8|v4i16|v2i32)(_indexed)?$")>;
// ASIMD multiply accumulate, Q-form
-def : InstRW<[A57Write_6cyc_2W_Mul_Forward, A57ReadIVMA4], (instregex "^ML[AS](v16i8|v8i16|v4i32)(_indexed)?$")>;
+def : InstRW<[A57Write_6cyc_2W_Mul_Forward, A57ReadIVMA4], (instregex "^ML[AS](v16i8|v8i16|v4i32)(_indexed)?$")>;
// ASIMD multiply accumulate long
// ASIMD multiply accumulate saturating long
-def : InstRW<[A57Write_5cyc_1W_Mul_Forward, A57ReadIVMA4], (instregex "^(S|U)ML[AS]L")>;
-def : InstRW<[A57Write_5cyc_1W_Mul_Forward, A57ReadIVMA3], (instregex "^SQDML[AS]L")>;
+def : InstRW<[A57Write_5cyc_1W_Mul_Forward, A57ReadIVMA4], (instregex "^(S|U)ML[AS]L")>;
+def : InstRW<[A57Write_5cyc_1W_Mul_Forward, A57ReadIVMA3], (instregex "^SQDML[AS]L")>;
// ASIMD multiply long
-def : InstRW<[A57Write_5cyc_1W_Mul_Forward], (instregex "^(S|U)MULL")>;
-def : InstRW<[A57Write_5cyc_1W], (instregex "^SQDMULL")>;
+def : InstRW<[A57Write_5cyc_1W_Mul_Forward], (instregex "^(S|U)MULL")>;
+def : InstRW<[A57Write_5cyc_1W], (instregex "^SQDMULL")>;
def : InstRW<[A57Write_5cyc_1W], (instregex "^PMULL(v8i8|v16i8)")>;
def : InstRW<[A57Write_3cyc_1W], (instregex "^PMULL(v1i64|v2i64)")>;
// ASIMD pairwise add and accumulate
// ASIMD shift accumulate
-def : InstRW<[A57Write_4cyc_1X_NonMul_Forward, A57ReadIVA3], (instregex "^[SU]ADALP")>;
-def : InstRW<[A57Write_4cyc_1X_NonMul_Forward, A57ReadIVA3], (instregex "^(S|SR|U|UR)SRA")>;
+def : InstRW<[A57Write_4cyc_1X_NonMul_Forward, A57ReadIVA3], (instregex "^[SU]ADALP")>;
+def : InstRW<[A57Write_4cyc_1X_NonMul_Forward, A57ReadIVA3], (instregex "^(S|SR|U|UR)SRA")>;
// ASIMD shift by immed, complex
def : InstRW<[A57Write_4cyc_1X], (instregex "^[SU]?(Q|R){1,2}SHR")>;
@@ -487,22 +487,22 @@ def : InstRW<[A57Write_9cyc_3V], (instregex "^(FMAX|FMIN)(NM)?P(v4f32|v2f64|v2i6
def : InstRW<[A57Write_10cyc_3V], (instregex "^(FMAX|FMIN)(NM)?Vv")>;
// ASIMD FP multiply, D-form, FZ
-def : InstRW<[A57Write_5cyc_1V_FP_Forward], (instregex "^FMULX?(v2f32|v1i32|v2i32|v1i64|32|64)")>;
+def : InstRW<[A57Write_5cyc_1V_FP_Forward], (instregex "^FMULX?(v2f32|v1i32|v2i32|v1i64|32|64)")>;
// ASIMD FP multiply, Q-form, FZ
-def : InstRW<[A57Write_5cyc_2V_FP_Forward], (instregex "^FMULX?(v4f32|v2f64|v4i32|v2i64)")>;
+def : InstRW<[A57Write_5cyc_2V_FP_Forward], (instregex "^FMULX?(v4f32|v2f64|v4i32|v2i64)")>;
// ASIMD FP multiply accumulate, D-form, FZ
// ASIMD FP multiply accumulate, Q-form, FZ
def A57WriteFPVMAD : SchedWriteRes<[A57UnitV]> { let Latency = 9; }
def A57WriteFPVMAQ : SchedWriteRes<[A57UnitV, A57UnitV]> { let Latency = 10; }
-
-// Cortex A57 Software Optimization Guide Sec 3.15
-// Advances from FP mul and mul-accum to mul-accum
-def A57ReadFPVMA5 : SchedReadAdvance<5, [A57WriteFPVMAD, A57WriteFPVMAQ, A57Write_5cyc_1V_FP_Forward, A57Write_5cyc_2V_FP_Forward]>;
-def A57ReadFPVMA6 : SchedReadAdvance<6, [A57WriteFPVMAD, A57WriteFPVMAQ, A57Write_5cyc_1V_FP_Forward, A57Write_5cyc_2V_FP_Forward]>;
-
+
+// Cortex A57 Software Optimization Guide Sec 3.15
+// Advances from FP mul and mul-accum to mul-accum
+def A57ReadFPVMA5 : SchedReadAdvance<5, [A57WriteFPVMAD, A57WriteFPVMAQ, A57Write_5cyc_1V_FP_Forward, A57Write_5cyc_2V_FP_Forward]>;
+def A57ReadFPVMA6 : SchedReadAdvance<6, [A57WriteFPVMAD, A57WriteFPVMAQ, A57Write_5cyc_1V_FP_Forward, A57Write_5cyc_2V_FP_Forward]>;
+
def : InstRW<[A57WriteFPVMAD, A57ReadFPVMA5], (instregex "^FML[AS](v2f32|v1i32|v2i32|v1i64)")>;
-def : InstRW<[A57WriteFPVMAQ, A57ReadFPVMA6], (instregex "^FML[AS](v4f32|v2f64|v4i32|v2i64)")>;
+def : InstRW<[A57WriteFPVMAQ, A57ReadFPVMA6], (instregex "^FML[AS](v4f32|v2f64|v4i32|v2i64)")>;
// ASIMD FP round, D-form
def : InstRW<[A57Write_5cyc_1V], (instregex "^FRINT[AIMNPXZ](v2f32)")>;
@@ -565,9 +565,9 @@ def : InstRW<[A57Write_6cyc_3V], (instregex "^(UZP|ZIP)(1|2)(v16i8|v8i16|v4i32|v
def : InstRW<[A57Write_5cyc_1V], (instregex "^F(ADD|SUB)[DS]rr")>;
-// Cortex A57 Software Optimization Guide Sec 3.10
+// Cortex A57 Software Optimization Guide Sec 3.10
def A57WriteFPMA : SchedWriteRes<[A57UnitV]> { let Latency = 9; }
-def A57ReadFPMA5 : SchedReadAdvance<5, [A57WriteFPMA, WriteFMul]>;
+def A57ReadFPMA5 : SchedReadAdvance<5, [A57WriteFPMA, WriteFMul]>;
def A57ReadFPM : SchedReadAdvance<0>;
def : InstRW<[A57WriteFPMA, A57ReadFPM, A57ReadFPM, A57ReadFPMA5], (instregex "^FN?M(ADD|SUB)[DS]rrr")>;
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA57WriteRes.td b/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA57WriteRes.td
index 2ec3233887..a4c090d439 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA57WriteRes.td
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA57WriteRes.td
@@ -13,11 +13,11 @@
// Prefix: A57Write
// Latency: #cyc
// MicroOp Count/Types: #(B|I|M|L|S|X|W|V)
-// Postfix (optional): (XYZ)_Forward
+// Postfix (optional): (XYZ)_Forward
+//
+// The postfix is added to differentiate SchedWriteRes that are used in
+// subsequent SchedReadAdvances.
//
-// The postfix is added to differentiate SchedWriteRes that are used in
-// subsequent SchedReadAdvances.
-//
// e.g. A57Write_6cyc_1I_6S_4V means the total latency is 6 and there are
// 11 micro-ops to be issued down one I pipe, six S pipes and four V pipes.
//
@@ -29,9 +29,9 @@
def A57Write_5cyc_1L : SchedWriteRes<[A57UnitL]> { let Latency = 5; }
def A57Write_5cyc_1M : SchedWriteRes<[A57UnitM]> { let Latency = 5; }
def A57Write_5cyc_1V : SchedWriteRes<[A57UnitV]> { let Latency = 5; }
-def A57Write_5cyc_1V_FP_Forward : SchedWriteRes<[A57UnitV]> { let Latency = 5; }
+def A57Write_5cyc_1V_FP_Forward : SchedWriteRes<[A57UnitV]> { let Latency = 5; }
def A57Write_5cyc_1W : SchedWriteRes<[A57UnitW]> { let Latency = 5; }
-def A57Write_5cyc_1W_Mul_Forward : SchedWriteRes<[A57UnitW]> { let Latency = 5; }
+def A57Write_5cyc_1W_Mul_Forward : SchedWriteRes<[A57UnitW]> { let Latency = 5; }
def A57Write_10cyc_1V : SchedWriteRes<[A57UnitV]> { let Latency = 10; }
def A57Write_17cyc_1W : SchedWriteRes<[A57UnitW]> { let Latency = 17;
let ResourceCycles = [17]; }
@@ -51,7 +51,7 @@ def A57Write_3cyc_1W : SchedWriteRes<[A57UnitW]> { let Latency = 3; }
def A57Write_3cyc_1X : SchedWriteRes<[A57UnitX]> { let Latency = 3; }
def A57Write_4cyc_1L : SchedWriteRes<[A57UnitL]> { let Latency = 4; }
def A57Write_4cyc_1X : SchedWriteRes<[A57UnitX]> { let Latency = 4; }
-def A57Write_4cyc_1X_NonMul_Forward : SchedWriteRes<[A57UnitX]> { let Latency = 4; }
+def A57Write_4cyc_1X_NonMul_Forward : SchedWriteRes<[A57UnitX]> { let Latency = 4; }
def A57Write_9cyc_1V : SchedWriteRes<[A57UnitV]> { let Latency = 9; }
def A57Write_6cyc_1M : SchedWriteRes<[A57UnitM]> { let Latency = 6; }
def A57Write_6cyc_1V : SchedWriteRes<[A57UnitV]> { let Latency = 6; }
@@ -100,10 +100,10 @@ def A57Write_6cyc_2W : SchedWriteRes<[A57UnitW, A57UnitW]> {
let Latency = 6;
let NumMicroOps = 2;
}
-def A57Write_6cyc_2W_Mul_Forward : SchedWriteRes<[A57UnitW, A57UnitW]> {
- let Latency = 6;
- let NumMicroOps = 2;
-}
+def A57Write_6cyc_2W_Mul_Forward : SchedWriteRes<[A57UnitW, A57UnitW]> {
+ let Latency = 6;
+ let NumMicroOps = 2;
+}
def A57Write_5cyc_1I_1L : SchedWriteRes<[A57UnitI,
A57UnitL]> {
let Latency = 5;
@@ -113,18 +113,18 @@ def A57Write_5cyc_2V : SchedWriteRes<[A57UnitV, A57UnitV]> {
let Latency = 5;
let NumMicroOps = 2;
}
-def A57Write_5cyc_2V_FP_Forward : SchedWriteRes<[A57UnitV, A57UnitV]> {
- let Latency = 5;
- let NumMicroOps = 2;
-}
+def A57Write_5cyc_2V_FP_Forward : SchedWriteRes<[A57UnitV, A57UnitV]> {
+ let Latency = 5;
+ let NumMicroOps = 2;
+}
def A57Write_5cyc_2X : SchedWriteRes<[A57UnitX, A57UnitX]> {
let Latency = 5;
let NumMicroOps = 2;
}
-def A57Write_5cyc_2X_NonMul_Forward : SchedWriteRes<[A57UnitX, A57UnitX]> {
- let Latency = 5;
- let NumMicroOps = 2;
-}
+def A57Write_5cyc_2X_NonMul_Forward : SchedWriteRes<[A57UnitX, A57UnitX]> {
+ let Latency = 5;
+ let NumMicroOps = 2;
+}
def A57Write_10cyc_1L_1V : SchedWriteRes<[A57UnitL,
A57UnitV]> {
let Latency = 10;
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA64FX.td b/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA64FX.td
index 3c5a8d033d..b6741d418e 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA64FX.td
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedA64FX.td
@@ -1,3890 +1,3890 @@
-//=- AArch64SchedA64FX.td - Fujitsu A64FX Scheduling Defs -*- tablegen -*-=//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the scheduling model for the Fujitsu A64FX processors.
-//
-//===----------------------------------------------------------------------===//
-
-def A64FXModel : SchedMachineModel {
- let IssueWidth = 6; // 6 micro-ops dispatched at a time.
- let MicroOpBufferSize = 180; // 180 entries in micro-op re-order buffer.
- let LoadLatency = 5; // Optimistic load latency.
- let MispredictPenalty = 12; // Extra cycles for mispredicted branch.
- // Determined via a mix of micro-arch details and experimentation.
- let LoopMicroOpBufferSize = 128;
- let PostRAScheduler = 1; // Using PostRA sched.
- let CompleteModel = 1;
-
- list<Predicate> UnsupportedFeatures =
- [HasSVE2, HasSVE2AES, HasSVE2SM4, HasSVE2SHA3, HasSVE2BitPerm, HasPAuth];
-
- let FullInstRWOverlapCheck = 0;
-}
-
-let SchedModel = A64FXModel in {
-
-// Define the issue ports.
-
-// A64FXIP*
-
-// Port 0
-def A64FXIPFLA : ProcResource<1>;
-
-// Port 1
-def A64FXIPPR : ProcResource<1>;
-
-// Port 2
-def A64FXIPEXA : ProcResource<1>;
-
-// Port 3
-def A64FXIPFLB : ProcResource<1>;
-
-// Port 4
-def A64FXIPEXB : ProcResource<1>;
-
-// Port 5
-def A64FXIPEAGA : ProcResource<1>;
-
-// Port 6
-def A64FXIPEAGB : ProcResource<1>;
-
-// Port 7
-def A64FXIPBR : ProcResource<1>;
-
-// Define groups for the functional units on each issue port. Each group
-// created will be used by a WriteRes later on.
-
-def A64FXGI7 : ProcResGroup<[A64FXIPBR]>;
-
-def A64FXGI0 : ProcResGroup<[A64FXIPFLA]>;
-
-def A64FXGI1 : ProcResGroup<[A64FXIPPR]>;
-
-def A64FXGI2 : ProcResGroup<[A64FXIPEXA]>;
-
-def A64FXGI3 : ProcResGroup<[A64FXIPFLB]>;
-
-def A64FXGI4 : ProcResGroup<[A64FXIPEXB]>;
-
-def A64FXGI5 : ProcResGroup<[A64FXIPEAGA]>;
-
-def A64FXGI6 : ProcResGroup<[A64FXIPEAGB]>;
-
-def A64FXGI03 : ProcResGroup<[A64FXIPFLA, A64FXIPFLB]>;
-
-def A64FXGI01 : ProcResGroup<[A64FXIPFLA, A64FXIPPR]>;
-
-def A64FXGI02 : ProcResGroup<[A64FXIPFLA, A64FXIPEXA]>;
-
-def A64FXGI12 : ProcResGroup<[A64FXIPEXA, A64FXIPPR]>;
-
-def A64FXGI15 : ProcResGroup<[A64FXIPEAGA, A64FXIPPR]>;
-
-def A64FXGI05 : ProcResGroup<[A64FXIPFLA, A64FXIPEAGA]>;
-
-def A64FXGI24 : ProcResGroup<[A64FXIPEXA, A64FXIPEXB]>;
-
-def A64FXGI124 : ProcResGroup<[A64FXIPEXA, A64FXIPEXB, A64FXIPPR]>;
-
-def A64FXGI056 : ProcResGroup<[A64FXIPFLA, A64FXIPEAGA, A64FXIPEAGB]>;
-
-def A64FXGI0256 : ProcResGroup<[A64FXIPFLA, A64FXIPEXA, A64FXIPEAGA, A64FXIPEAGB]>;
-
-def A64FXGI56 : ProcResGroup<[A64FXIPEAGA, A64FXIPEAGB]>;
-
-def A64FXGI2456 : ProcResGroup<[A64FXIPEXA, A64FXIPEXB, A64FXIPEAGA, A64FXIPEAGB]>;
-
-def A64FXAny : ProcResGroup<[A64FXIPFLA, A64FXIPPR, A64FXIPEXA, A64FXIPFLB,
- A64FXIPEXB, A64FXIPEAGA, A64FXIPEAGB, A64FXIPBR]> {
- let BufferSize = 60;
-}
-
-def A64FXWrite_6Cyc : SchedWriteRes<[]> {
- let Latency = 6;
-}
-
-def A64FXWrite_1Cyc_GI7 : SchedWriteRes<[A64FXGI7]> {
- let Latency = 1;
-}
-
-def A64FXWrite_2Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
- let Latency = 2;
-}
-
-def A64FXWrite_4Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
- let Latency = 4;
-}
-
-def A64FXWrite_5Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
- let Latency = 5;
-}
-
-def A64FXWrite_6Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
- let Latency = 6;
-}
-
-def A64FXWrite_8Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
- let Latency = 8;
-}
-
-def A64FXWrite_9Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
- let Latency = 9;
-}
-
-def A64FXWrite_13Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
- let Latency = 13;
-}
-
-def A64FXWrite_37Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
- let Latency = 37;
-}
-
-def A64FXWrite_98Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
- let Latency = 98;
-}
-
-def A64FXWrite_134Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
- let Latency = 134;
-}
-
-def A64FXWrite_154Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
- let Latency = 154;
-}
-
-def A64FXWrite_4Cyc_GI01 : SchedWriteRes<[A64FXGI01]> {
- let Latency = 4;
-}
-
-def A64FXWrite_6Cyc_GI01 : SchedWriteRes<[A64FXGI01]> {
- let Latency = 6;
-}
-
-def A64FXWrite_8Cyc_GI01 : SchedWriteRes<[A64FXGI01]> {
- let Latency = 8;
-}
-
-def A64FXWrite_12Cyc_GI01 : SchedWriteRes<[A64FXGI01]> {
- let Latency = 12;
-}
-
-def A64FXWrite_10Cyc_GI02 : SchedWriteRes<[A64FXGI02]> {
- let Latency = 10;
-}
-
-def A64FXWrite_17Cyc_GI02 : SchedWriteRes<[A64FXGI02]> {
- let Latency = 17;
-}
-
-def A64FXWrite_21Cyc_GI02 : SchedWriteRes<[A64FXGI02]> {
- let Latency = 21;
-}
-
-def A64FXWrite_3Cyc_GI1 : SchedWriteRes<[A64FXGI1]> {
- let Latency = 3;
-}
-
-def A64FXWrite_6Cyc_NGI1 : SchedWriteRes<[A64FXGI1]> {
- let Latency = 3;
- let NumMicroOps = 2;
-}
-
-def A64FXWrite_4Cyc_GI12 : SchedWriteRes<[A64FXGI12]> {
- let Latency = 4;
-}
-
-def A64FXWrite_3Cyc_GI2 : SchedWriteRes<[A64FXGI2]> {
- let Latency = 3;
-}
-
-def A64FXWrite_5Cyc_GI2 : SchedWriteRes<[A64FXGI2]> {
- let Latency = 5;
-}
-
-def A64FXWrite_6Cyc_GI2 : SchedWriteRes<[A64FXGI2]> {
- let Latency = 6;
-}
-
-def A64FXWrite_4Cyc_GI3 : SchedWriteRes<[A64FXGI3]> {
- let Latency = 4;
-}
-
-def A64FXWrite_6Cyc_GI3 : SchedWriteRes<[A64FXGI3]> {
- let Latency = 6;
-}
-
-def A64FXWrite_6Cyc_GI15 : SchedWriteRes<[A64FXGI15]> {
- let Latency = 6;
-}
-
-def A64FXWrite_3Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 3;
-}
-
-def A64FXWrite_4Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 4;
-}
-
-def A64FXWrite_6Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 6;
-}
-
-def A64FXWrite_8Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 8;
-}
-
-def A64FXWrite_9Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 9;
-}
-
-def A64FXWrite_10Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 10;
-}
-
-def A64FXWrite_12Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 12;
-}
-
-def A64FXWrite_14Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 14;
-}
-
-def A64FXWrite_15Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 15;
-}
-
-def A64FXWrite_15Cyc_NGI03 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 15;
- let NumMicroOps = 2;
-}
-
-def A64FXWrite_18Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 18;
-}
-
-def A64FXWrite_45Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 45;
-}
-
-def A64FXWrite_60Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 60;
-}
-
-def A64FXWrite_75Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 75;
-}
-
-def A64FXWrite_6Cyc_GI05 : SchedWriteRes<[A64FXGI05]> {
- let Latency = 6;
-}
-
-def A64FXWrite_10Cyc_GI4 : SchedWriteRes<[A64FXGI4]> {
- let Latency = 10;
-}
-
-def A64FXWrite_12Cyc_GI4 : SchedWriteRes<[A64FXGI4]> {
- let Latency = 12;
-}
-
-def A64FXWrite_20Cyc_GI4 : SchedWriteRes<[A64FXGI4]> {
- let Latency = 20;
-}
-
-def A64FXWrite_5Cyc_GI5 : SchedWriteRes<[A64FXGI5]> {
- let Latency = 5;
-}
-
-def A64FXWrite_11Cyc_GI5 : SchedWriteRes<[A64FXGI5]> {
- let Latency = 11;
-}
-
-def A64FXWrite_5Cyc_GI6 : SchedWriteRes<[A64FXGI6]> {
- let Latency = 5;
-}
-
-def A64FXWrite_1Cyc_GI24 : SchedWriteRes<[A64FXGI24]> {
- let Latency = 1;
-}
-
-def A64FXWrite_2Cyc_GI24 : SchedWriteRes<[A64FXGI24]> {
- let Latency = 2;
-}
-
-def A64FXWrite_4Cyc_NGI24 : SchedWriteRes<[A64FXGI24]> {
- let Latency = 4;
- let NumMicroOps = 4;
-}
-
-def A64FXWrite_6Cyc_GI124: SchedWriteRes<[A64FXGI124]> {
- let Latency = 6;
-}
-
-def A64FXWrite_8Cyc_GI124 : SchedWriteRes<[A64FXGI124]> {
- let Latency = 8;
- let NumMicroOps = 2;
-}
-
-def A64FXWrite_6Cyc_GI56 : SchedWriteRes<[A64FXGI56]> {
- let Latency = 0;
-}
-
-def A64FXWrite_1Cyc_GI56 : SchedWriteRes<[A64FXGI56]> {
- let Latency = 1;
-}
-
-def A64FXWrite_5Cyc_GI56 : SchedWriteRes<[A64FXGI56]> {
- let Latency = 5;
-}
-
-def A64FXWrite_8Cyc_GI56 : SchedWriteRes<[A64FXGI56]> {
- let Latency = 8;
-}
-
-def A64FXWrite_11Cyc_GI56 : SchedWriteRes<[A64FXGI56]> {
- let Latency = 11;
-}
-
-def A64FXWrite_44Cyc_GI56 : SchedWriteRes<[A64FXGI56]> {
- let Latency = 44;
-}
-
-def A64FXWrite_10Cyc_GI056 : SchedWriteRes<[A64FXGI056]> {
- let Latency = 10;
-}
-
-def A64FXWrite_15Cyc_GI056 : SchedWriteRes<[A64FXGI056]> {
- let Latency = 15;
-}
-
-def A64FXWrite_19Cyc_GI056 : SchedWriteRes<[A64FXGI056]> {
- let Latency = 19;
-}
-
-def A64FXWrite_25Cyc_GI056 : SchedWriteRes<[A64FXGI056]> {
- let Latency = 25;
-}
-
-def A64FXWrite_14Cyc_GI0256 : SchedWriteRes<[A64FXGI0256]> {
- let Latency = 14;
-}
-
-def A64FXWrite_19Cyc_GI0256 : SchedWriteRes<[A64FXGI0256]> {
- let Latency = 19;
-}
-
-def A64FXWrite_29Cyc_GI0256 : SchedWriteRes<[A64FXGI0256]> {
- let Latency = 29;
-}
-
-def A64FXWrite_LDNP: SchedWriteRes<[A64FXGI56]> {
- let Latency = 5;
- let NumMicroOps = 2;
-}
-
-def A64FXWrite_LDP01: SchedWriteRes<[A64FXGI2456]> {
- let Latency = 5;
- let NumMicroOps = 3;
-}
-
-def A64FXWrite_LDR01: SchedWriteRes<[A64FXGI2456]> {
- let Latency = 5;
- let NumMicroOps = 2;
-}
-
-def A64FXWrite_LD102: SchedWriteRes<[A64FXGI56]> {
- let Latency = 8;
- let NumMicroOps = 2;
-}
-
-def A64FXWrite_LD103: SchedWriteRes<[A64FXGI56]> {
- let Latency = 11;
- let NumMicroOps = 2;
-
-}
-
-def A64FXWrite_LD104: SchedWriteRes<[A64FXGI56]> {
- let Latency = 8;
- let NumMicroOps = 3;
-}
-
-def A64FXWrite_LD105: SchedWriteRes<[A64FXGI56]> {
- let Latency = 11;
- let NumMicroOps = 3;
-}
-
-def A64FXWrite_LD106: SchedWriteRes<[A64FXGI56]> {
- let Latency = 8;
- let NumMicroOps = 4;
-}
-
-def A64FXWrite_LD107: SchedWriteRes<[A64FXGI56]> {
- let Latency = 11;
- let NumMicroOps = 4;
-}
-
-def A64FXWrite_LD108: SchedWriteRes<[A64FXGI56]> {
- let Latency = 8;
- let NumMicroOps = 2;
-}
-
-def A64FXWrite_LD109: SchedWriteRes<[A64FXGI56]> {
- let Latency = 11;
- let NumMicroOps = 2;
-}
-
-def A64FXWrite_LD110: SchedWriteRes<[A64FXGI56]> {
- let Latency = 8;
- let NumMicroOps = 3;
-}
-
-def A64FXWrite_LD111: SchedWriteRes<[A64FXGI56]> {
- let Latency = 11;
- let NumMicroOps = 3;
-}
-
-def A64FXWrite_LD112: SchedWriteRes<[A64FXGI56]> {
- let Latency = 8;
- let NumMicroOps = 4;
-}
-
-def A64FXWrite_LD113: SchedWriteRes<[A64FXGI56]> {
- let Latency = 11;
- let NumMicroOps = 4;
-}
-
-def A64FXWrite_LD114: SchedWriteRes<[A64FXGI56]> {
- let Latency = 8;
- let NumMicroOps = 5;
-}
-
-def A64FXWrite_LD115: SchedWriteRes<[A64FXGI56]> {
- let Latency = 11;
- let NumMicroOps = 5;
-}
-
-def A64FXWrite_LD1I0: SchedWriteRes<[A64FXGI056]> {
- let Latency = 8;
- let NumMicroOps = 2;
-}
-
-def A64FXWrite_LD1I1: SchedWriteRes<[A64FXGI056]> {
- let Latency = 8;
- let NumMicroOps = 3;
-}
-
-def A64FXWrite_LD2I0: SchedWriteRes<[A64FXGI056]> {
- let Latency = 8;
- let NumMicroOps = 4;
-}
-
-def A64FXWrite_LD2I1: SchedWriteRes<[A64FXGI056]> {
- let Latency = 8;
- let NumMicroOps = 5;
-}
-
-def A64FXWrite_LD3I0: SchedWriteRes<[A64FXGI056]> {
- let Latency = 8;
- let NumMicroOps = 6;
-}
-
-def A64FXWrite_LD3I1: SchedWriteRes<[A64FXGI056]> {
- let Latency = 8;
- let NumMicroOps = 7;
-}
-
-def A64FXWrite_LD4I0: SchedWriteRes<[A64FXGI056]> {
- let Latency = 8;
- let NumMicroOps = 8;
-}
-
-def A64FXWrite_LD4I1: SchedWriteRes<[A64FXGI056]> {
- let Latency = 8;
- let NumMicroOps = 9;
-}
-
-def A64FXWrite_1Cyc_GI2456 : SchedWriteRes<[A64FXGI2456]> {
- let Latency = 1;
-}
-
-def A64FXWrite_FMOV_GV : SchedWriteRes<[A64FXGI03]> {
- let Latency = 10;
-}
-
-def A64FXWrite_FMOV_VG14 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 14;
-}
-
-def A64FXWrite_FMOV_VG : SchedWriteRes<[A64FXGI03]> {
- let Latency = 25;
-}
-
-def A64FXWrite_ADDLV : SchedWriteRes<[A64FXGI03]> {
- let Latency = 12;
-}
-
-def A64FXWrite_MULLE : SchedWriteRes<[A64FXGI03]> {
- let Latency = 14;
-}
-
-def A64FXWrite_MULLV : SchedWriteRes<[A64FXGI03]> {
- let Latency = 14;
-}
-
-def A64FXWrite_MADDL : SchedWriteRes<[A64FXGI03]> {
- let Latency = 6;
-}
-
-def A64FXWrite_ABA : SchedWriteRes<[A64FXGI03]> {
- let Latency = 8;
-}
-
-def A64FXWrite_ABAL : SchedWriteRes<[A64FXGI03]> {
- let Latency = 10;
-}
-
-def A64FXWrite_ADDLV1 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 12;
- let NumMicroOps = 6;
-}
-
-def A64FXWrite_MINMAXV : SchedWriteRes<[A64FXGI03]> {
- let Latency = 14;
- let NumMicroOps = 6;
-}
-
-def A64FXWrite_SQRDMULH : SchedWriteRes<[A64FXGI03]> {
- let Latency = 9;
-}
-
-def A64FXWrite_PMUL : SchedWriteRes<[A64FXGI03]> {
- let Latency = 8;
-}
-
-
-def A64FXWrite_SRSRAV : SchedWriteRes<[A64FXGI03]> {
- let Latency = 8;
- let NumMicroOps = 3;
-}
-
-def A64FXWrite_SSRAV : SchedWriteRes<[A64FXGI03]> {
- let Latency = 8;
- let NumMicroOps = 2;
-}
-
-def A64FXWrite_RSHRN : SchedWriteRes<[A64FXGI03]> {
- let Latency = 10;
- let NumMicroOps = 3;
-}
-
-def A64FXWrite_SHRN : SchedWriteRes<[A64FXGI03]> {
- let Latency = 10;
- let NumMicroOps = 2;
-}
-
-
-def A64FXWrite_ADDP : SchedWriteRes<[A64FXGI03]> {
- let Latency = 10;
- let NumMicroOps = 3;
-}
-
-def A64FXWrite_FMULXE : SchedWriteRes<[A64FXGI03]> {
- let Latency = 15;
- let NumMicroOps = 2;
-}
-
-def A64FXWrite_FADDPV : SchedWriteRes<[A64FXGI03]> {
- let Latency = 15;
- let NumMicroOps = 3;
-}
-
-def A64FXWrite_SADALP : SchedWriteRes<[A64FXGI03]> {
- let Latency = 10;
- let NumMicroOps = 3;
-}
-
-def A64FXWrite_SADDLP : SchedWriteRes<[A64FXGI03]> {
- let Latency = 10;
- let NumMicroOps = 2;
-}
-
-def A64FXWrite_FCVTXNV : SchedWriteRes<[A64FXGI03]> {
- let Latency = 15;
- let NumMicroOps = 2;
-}
-
-def A64FXWrite_FMAXVVH : SchedWriteRes<[A64FXGI03]> {
- let Latency = 14;
- let NumMicroOps = 7;
-}
-
-def A64FXWrite_FMAXVVS : SchedWriteRes<[A64FXGI03]> {
- let Latency = 14;
-}
-
-def A64FXWrite_BIF : SchedWriteRes<[A64FXGI03]> {
- let Latency = 5;
-}
-
-def A64FXWrite_DUPGENERAL : SchedWriteRes<[A64FXGI03]> {
- let Latency = 10;
-}
-
-def A64FXWrite_SHA00 : SchedWriteRes<[A64FXGI0]> {
- let Latency = 9;
-}
-
-def A64FXWrite_SHA01 : SchedWriteRes<[A64FXGI0]> {
- let Latency = 12;
-}
-
-def A64FXWrite_SMOV : SchedWriteRes<[A64FXGI03]> {
- let Latency = 25;
-}
-
-def A64FXWrite_TBX1 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 10;
- let NumMicroOps = 3;
-}
-
-def A64FXWrite_TBX2 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 10;
- let NumMicroOps = 5;
-}
-
-def A64FXWrite_TBX3 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 10;
- let NumMicroOps = 7;
-}
-
-def A64FXWrite_TBX4 : SchedWriteRes<[A64FXGI03]> {
- let Latency = 10;
- let NumMicroOps = 9;
-}
-
-def A64FXWrite_PREF0: SchedWriteRes<[A64FXGI56]> {
- let Latency = 0;
-}
-
-def A64FXWrite_PREF1: SchedWriteRes<[A64FXGI56]> {
- let Latency = 0;
-}
-
-def A64FXWrite_SWP: SchedWriteRes<[A64FXGI56]> {
- let Latency = 0;
-}
-
-def A64FXWrite_STUR: SchedWriteRes<[A64FXGI56]> {
- let Latency = 0;
-}
-
-def A64FXWrite_STNP: SchedWriteRes<[A64FXGI56]> {
- let Latency = 0;
-}
-
-def A64FXWrite_STP01: SchedWriteRes<[A64FXGI56]> {
- let Latency = 0;
-}
-
-def A64FXWrite_ST10: SchedWriteRes<[A64FXGI56]> {
- let Latency = 0;
-}
-
-def A64FXWrite_ST11: SchedWriteRes<[A64FXGI56]> {
- let Latency = 0;
-}
-
-def A64FXWrite_ST12: SchedWriteRes<[A64FXGI56]> {
- let Latency = 0;
-}
-
-def A64FXWrite_ST13: SchedWriteRes<[A64FXGI56]> {
- let Latency = 0;
-}
-
-def A64FXWrite_ST14: SchedWriteRes<[A64FXGI56]> {
- let Latency = 1;
-}
-
-def A64FXWrite_ST15: SchedWriteRes<[A64FXGI56]> {
- let Latency = 1;
-}
-
-def A64FXWrite_ST16: SchedWriteRes<[A64FXGI56]> {
- let Latency = 1;
-}
-
-def A64FXWrite_ST17: SchedWriteRes<[A64FXGI56]> {
- let Latency = 1;
-}
-
-def A64FXWrite_ST1W_6: SchedWriteRes<[A64FXGI056]> {
- let Latency = 6;
-}
-
-def A64FXWrite_ST2W_7: SchedWriteRes<[A64FXGI056]> {
- let Latency = 7;
-}
-
-def A64FXWrite_ST3W_8: SchedWriteRes<[A64FXGI056]> {
- let Latency = 8;
-}
-
-def A64FXWrite_ST4W_9: SchedWriteRes<[A64FXGI056]> {
- let Latency = 9;
-}
-
-def A64FXWrite_ST1W_15: SchedWriteRes<[A64FXGI056]> {
- let Latency = 15;
-}
-
-def A64FXWrite_ST1W_19: SchedWriteRes<[A64FXGI056]> {
- let Latency = 19;
-}
-
-def A64FXWrite_CAS: SchedWriteRes<[A64FXGI56]> {
- let Latency = 7;
-}
-
-// Define commonly used read types.
-
-// No forwarding is provided for these types.
-def : ReadAdvance<ReadI, 0>;
-def : ReadAdvance<ReadISReg, 0>;
-def : ReadAdvance<ReadIEReg, 0>;
-def : ReadAdvance<ReadIM, 0>;
-def : ReadAdvance<ReadIMA, 0>;
-def : ReadAdvance<ReadID, 0>;
-def : ReadAdvance<ReadExtrHi, 0>;
-def : ReadAdvance<ReadAdrBase, 0>;
-def : ReadAdvance<ReadVLD, 0>;
-
-//===----------------------------------------------------------------------===//
-// 3. Instruction Tables.
-
-//---
-// 3.1 Branch Instructions
-//---
-
-// Branch, immed
-// Branch and link, immed
-// Compare and branch
-def : WriteRes<WriteBr, [A64FXGI7]> {
- let Latency = 1;
-}
-
-// Branch, register
-// Branch and link, register != LR
-// Branch and link, register = LR
-def : WriteRes<WriteBrReg, [A64FXGI7]> {
- let Latency = 1;
-}
-
-def : WriteRes<WriteSys, []> { let Latency = 1; }
-def : WriteRes<WriteBarrier, []> { let Latency = 1; }
-def : WriteRes<WriteHint, []> { let Latency = 1; }
-
-def : WriteRes<WriteAtomic, []> {
- let Latency = 4;
-}
-
-//---
-// Branch
-//---
-def : InstRW<[A64FXWrite_1Cyc_GI7], (instrs B, BL, BR, BLR)>;
-def : InstRW<[A64FXWrite_1Cyc_GI7], (instrs RET)>;
-def : InstRW<[A64FXWrite_1Cyc_GI7], (instregex "^B..$")>;
-def : InstRW<[A64FXWrite_1Cyc_GI7],
- (instregex "^CBZ", "^CBNZ", "^TBZ", "^TBNZ")>;
-
-//---
-// 3.2 Arithmetic and Logical Instructions
-// 3.3 Move and Shift Instructions
-//---
-
-// ALU, basic
-// Conditional compare
-// Conditional select
-// Address generation
-def : WriteRes<WriteI, [A64FXGI2456]> {
- let Latency = 1;
- let ResourceCycles = [1];
-}
-
-def : InstRW<[WriteI],
- (instregex "ADD?(W|X)r(i|r|s|x)", "ADDS?(W|X)r(i|r|s|x)(64)?",
- "AND?(W|X)r(i|r|s|x)", "ANDS?(W|X)r(i|r|s|x)",
- "ADC(W|X)r",
- "BIC?(W|X)r(i|r|s|x)", "BICS?(W|X)r(i|r|s|x)",
- "EON?(W|X)r(i|r|s|x)", "ORN?(W|X)r(i|r|s|x)",
- "ORR?(W|X)r(i|r|s|x)", "SUB?(W|X)r(i|r|s|x)",
- "SUBS?(W|X)r(i|r|s|x)", "SBC(W|X)r",
- "SBCS(W|X)r", "CCMN(W|X)(i|r)",
- "CCMP(W|X)(i|r)", "CSEL(W|X)r",
- "CSINC(W|X)r", "CSINV(W|X)r",
- "CSNEG(W|X)r")>;
-
-def : InstRW<[WriteI], (instrs COPY)>;
-
-// ALU, extend and/or shift
-def : WriteRes<WriteISReg, [A64FXGI2456]> {
- let Latency = 2;
- let ResourceCycles = [1];
-}
-
-def : InstRW<[WriteISReg],
- (instregex "ADD?(W|X)r(i|r|s|x)", "ADDS?(W|X)r(i|r|s|x)(64)?",
- "AND?(W|X)r(i|r|s|x)", "ANDS?(W|X)r(i|r|s|x)",
- "ADC(W|X)r",
- "BIC?(W|X)r(i|r|s|x)", "BICS?(W|X)r(i|r|s|x)",
- "EON?(W|X)r(i|r|s|x)", "ORN?(W|X)r(i|r|s|x)",
- "ORR?(W|X)r(i|r|s|x)", "SUB?(W|X)r(i|r|s|x)",
- "SUBS?(W|X)r(i|r|s|x)", "SBC(W|X)r",
- "SBCS(W|X)r", "CCMN(W|X)(i|r)",
- "CCMP(W|X)(i|r)", "CSEL(W|X)r",
- "CSINC(W|X)r", "CSINV(W|X)r",
- "CSNEG(W|X)r")>;
-
-def : WriteRes<WriteIEReg, [A64FXGI2456]> {
- let Latency = 1;
- let ResourceCycles = [1];
-}
-
-def : InstRW<[WriteIEReg],
- (instregex "ADD?(W|X)r(i|r|s|x)", "ADDS?(W|X)r(i|r|s|x)(64)?",
- "AND?(W|X)r(i|r|s|x)", "ANDS?(W|X)r(i|r|s|x)",
- "ADC(W|X)r",
- "BIC?(W|X)r(i|r|s|x)", "BICS?(W|X)r(i|r|s|x)",
- "EON?(W|X)r(i|r|s|x)", "ORN?(W|X)r(i|r|s|x)",
- "ORR?(W|X)r(i|r|s|x)", "SUB?(W|X)r(i|r|s|x)",
- "SUBS?(W|X)r(i|r|s|x)", "SBC(W|X)r",
- "SBCS(W|X)r", "CCMN(W|X)(i|r)",
- "CCMP(W|X)(i|r)", "CSEL(W|X)r",
- "CSINC(W|X)r", "CSINV(W|X)r",
- "CSNEG(W|X)r")>;
-
-// Move immed
-def : WriteRes<WriteImm, [A64FXGI2456]> {
- let Latency = 1;
- let ResourceCycles = [1];
-}
-
-def : InstRW<[A64FXWrite_1Cyc_GI2456],
- (instrs MOVKWi, MOVKXi, MOVNWi, MOVNXi, MOVZWi, MOVZXi)>;
-
-def : InstRW<[A64FXWrite_2Cyc_GI24],
- (instrs ASRVWr, ASRVXr, LSLVWr, LSLVXr, RORVWr, RORVXr)>;
-
-// Variable shift
-def : WriteRes<WriteIS, [A64FXGI2456]> {
- let Latency = 1;
- let ResourceCycles = [1];
-}
-
-//---
-// 3.4 Divide and Multiply Instructions
-//---
-
-// Divide, W-form
-def : WriteRes<WriteID32, [A64FXGI4]> {
- let Latency = 39;
- let ResourceCycles = [39];
-}
-
-// Divide, X-form
-def : WriteRes<WriteID64, [A64FXGI4]> {
- let Latency = 23;
- let ResourceCycles = [23];
-}
-
-// Multiply accumulate, W-form
-def : WriteRes<WriteIM32, [A64FXGI2456]> {
- let Latency = 5;
- let ResourceCycles = [1];
-}
-
-// Multiply accumulate, X-form
-def : WriteRes<WriteIM64, [A64FXGI2456]> {
- let Latency = 5;
- let ResourceCycles = [1];
-}
-
-def : InstRW<[WriteIM32], (instrs MADDWrrr, MSUBWrrr)>;
-def : InstRW<[WriteIM32], (instrs MADDXrrr, MSUBXrrr)>;
-def : InstRW<[A64FXWrite_MADDL],
- (instregex "(S|U)(MADDL|MSUBL)rrr")>;
-
-def : InstRW<[WriteID32], (instrs SDIVWr, UDIVWr)>;
-def : InstRW<[WriteID64], (instrs SDIVXr, UDIVXr)>;
-
-// Bitfield extract, two reg
-def : WriteRes<WriteExtr, [A64FXGI2456]> {
- let Latency = 1;
- let ResourceCycles = [1];
-}
-
-// Multiply high
-def : InstRW<[A64FXWrite_5Cyc_GI2], (instrs SMULHrr, UMULHrr)>;
-
-// Miscellaneous Data-Processing Instructions
-// Bitfield extract
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs EXTRWrri, EXTRXrri)>;
-
-// Bitifield move - basic
-def : InstRW<[A64FXWrite_1Cyc_GI24],
- (instrs SBFMWri, SBFMXri, UBFMWri, UBFMXri)>;
-
-// Bitfield move, insert
-def : InstRW<[A64FXWrite_4Cyc_NGI24], (instregex "^BFM")>;
-def : InstRW<[A64FXWrite_1Cyc_GI24], (instregex "(S|U)?BFM.*")>;
-
-// Count leading
-def : InstRW<[A64FXWrite_2Cyc_GI0], (instregex "^CLS(W|X)r$",
- "^CLZ(W|X)r$")>;
-
-// Reverse bits
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs RBITWr, RBITXr)>;
-
-// Cryptography Extensions
-def : InstRW<[A64FXWrite_8Cyc_GI0], (instregex "^AES[DE]")>;
-def : InstRW<[A64FXWrite_8Cyc_GI0], (instregex "^AESI?MC")>;
-def : InstRW<[A64FXWrite_8Cyc_GI0], (instregex "^PMULL")>;
-def : InstRW<[A64FXWrite_SHA00], (instregex "^SHA1SU0")>;
-def : InstRW<[A64FXWrite_8Cyc_GI0], (instregex "^SHA1(H|SU1)")>;
-def : InstRW<[A64FXWrite_SHA01], (instregex "^SHA1[CMP]")>;
-def : InstRW<[A64FXWrite_8Cyc_GI0], (instregex "^SHA256SU0")>;
-def : InstRW<[A64FXWrite_8Cyc_GI0], (instregex "^SHA256SU1")>;
-def : InstRW<[A64FXWrite_SHA01], (instregex "^SHA256(H|H2)")>;
-
-// CRC Instructions
-def : InstRW<[A64FXWrite_10Cyc_GI4], (instrs CRC32Brr, CRC32Hrr)>;
-def : InstRW<[A64FXWrite_12Cyc_GI4], (instrs CRC32Wrr)>;
-def : InstRW<[A64FXWrite_20Cyc_GI4], (instrs CRC32Xrr)>;
-
-def : InstRW<[A64FXWrite_10Cyc_GI4], (instrs CRC32CBrr, CRC32CHrr)>;
-def : InstRW<[A64FXWrite_12Cyc_GI4], (instrs CRC32CWrr)>;
-def : InstRW<[A64FXWrite_20Cyc_GI4], (instrs CRC32CXrr)>;
-
-// Reverse bits/bytes
-// NOTE: Handled by WriteI.
-
-//---
-// 3.6 Load Instructions
-// 3.10 FP Load Instructions
-//---
-
-// Load register, literal
-// Load register, unscaled immed
-// Load register, immed unprivileged
-// Load register, unsigned immed
-def : WriteRes<WriteLD, [A64FXGI56]> {
- let Latency = 4;
- let ResourceCycles = [3];
-}
-
-// Load register, immed post-index
-// NOTE: Handled by WriteLD, WriteI.
-// Load register, immed pre-index
-// NOTE: Handled by WriteLD, WriteAdr.
-def : WriteRes<WriteAdr, [A64FXGI2456]> {
- let Latency = 1;
- let ResourceCycles = [1];
-}
-
-// Load pair, immed offset, normal
-// Load pair, immed offset, signed words, base != SP
-// Load pair, immed offset signed words, base = SP
-// LDP only breaks into *one* LS micro-op. Thus
-// the resources are handled by WriteLD.
-def : WriteRes<WriteLDHi, []> {
- let Latency = 5;
-}
-
-// Load register offset, basic
-// Load register, register offset, scale by 4/8
-// Load register, register offset, scale by 2
-// Load register offset, extend
-// Load register, register offset, extend, scale by 4/8
-// Load register, register offset, extend, scale by 2
-def A64FXWriteLDIdx : SchedWriteVariant<[
- SchedVar<ScaledIdxPred, [A64FXWrite_1Cyc_GI56]>,
- SchedVar<NoSchedPred, [A64FXWrite_1Cyc_GI56]>]>;
-def : SchedAlias<WriteLDIdx, A64FXWriteLDIdx>;
-
-def A64FXReadAdrBase : SchedReadVariant<[
- SchedVar<ScaledIdxPred, [ReadDefault]>,
- SchedVar<NoSchedPred, [ReadDefault]>]>;
-def : SchedAlias<ReadAdrBase, A64FXReadAdrBase>;
-
-// Load pair, immed pre-index, normal
-// Load pair, immed pre-index, signed words
-// Load pair, immed post-index, normal
-// Load pair, immed post-index, signed words
-// NOTE: Handled by WriteLD, WriteLDHi, WriteAdr.
-
-def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDNPDi)>;
-def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDNPQi)>;
-def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDNPSi)>;
-def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDNPWi)>;
-def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDNPXi)>;
-
-def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDPDi)>;
-def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDPQi)>;
-def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDPSi)>;
-def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDPSWi)>;
-def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDPWi)>;
-def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDPXi)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDRBui)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDRDui)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDRHui)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDRQui)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDRSui)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI6], (instrs LDRDl)>;
-def : InstRW<[A64FXWrite_5Cyc_GI6], (instrs LDRQl)>;
-def : InstRW<[A64FXWrite_5Cyc_GI6], (instrs LDRWl)>;
-def : InstRW<[A64FXWrite_5Cyc_GI6], (instrs LDRXl)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDTRBi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDTRHi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDTRWi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDTRXi)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDTRSBWi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDTRSBXi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDTRSHWi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDTRSHXi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDTRSWi)>;
-
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPDpre)>;
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPQpre)>;
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPSpre)>;
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPWpre)>;
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPWpre)>;
-
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRBpre)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRDpre)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRHpre)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRQpre)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSpre)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRWpre)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRXpre)>;
-
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSBWpre)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSBXpre)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSBWpost)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSBXpost)>;
-
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSHWpre)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSHXpre)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSHWpost)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSHXpost)>;
-
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRBBpre)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRBBpost)>;
-
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRHHpre)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRHHpost)>;
-
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPDpost)>;
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPQpost)>;
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPSpost)>;
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPWpost)>;
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPXpost)>;
-
-def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRBpost)>;
-def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRDpost)>;
-def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRHpost)>;
-def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRQpost)>;
-def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRSpost)>;
-def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRWpost)>;
-def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRXpost)>;
-
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPDpre)>;
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPQpre)>;
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPSpre)>;
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPWpre)>;
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPXpre)>;
-
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRBpre)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRDpre)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRHpre)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRQpre)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSpre)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRWpre)>;
-def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRXpre)>;
-
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPDpost)>;
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPQpost)>;
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPSpost)>;
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPWpost)>;
-def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
- (instrs LDPXpost)>;
-
-def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRBpost)>;
-def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRDpost)>;
-def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRHpost)>;
-def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRQpost)>;
-def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRSpost)>;
-def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRWpost)>;
-def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRXpost)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRBroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRDroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRHroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRHHroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRQroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRSroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRSHWroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRSHXroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRWroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRXroW)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRBroX)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRDroX)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRHHroX)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRHroX)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRQroX)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRSroX)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRSHWroX)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRSHXroX)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRWroX)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRXroX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRBroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRBroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRDroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRHroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRHHroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRQroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRSroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRSHWroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRSHXroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRWroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRXroW)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRBroX)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRDroX)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRHroX)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRHHroX)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRQroX)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRSroX)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRSHWroX)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRSHXroX)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRWroX)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
- (instrs LDRXroX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURBi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURBBi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURDi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURHi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURHHi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURQi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURSi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURXi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURSBWi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURSBXi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURSHWi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURSHXi)>;
-def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURSWi)>;
-
-//---
-// Prefetch
-//---
-def : InstRW<[A64FXWrite_PREF0], (instrs PRFMl)>;
-def : InstRW<[A64FXWrite_PREF1], (instrs PRFUMi)>;
-def : InstRW<[A64FXWrite_PREF1], (instrs PRFMui)>;
-def : InstRW<[A64FXWrite_PREF1], (instrs PRFMroW)>;
-def : InstRW<[A64FXWrite_PREF1], (instrs PRFMroX)>;
-
-//--
-// 3.7 Store Instructions
-// 3.11 FP Store Instructions
-//--
-
-// Store register, unscaled immed
-// Store register, immed unprivileged
-// Store register, unsigned immed
-def : WriteRes<WriteST, [A64FXGI56]> {
- let Latency = 1;
-}
-
-// Store register, immed post-index
-// NOTE: Handled by WriteAdr, WriteST, ReadAdrBase
-
-// Store register, immed pre-index
-// NOTE: Handled by WriteAdr, WriteST
-
-// Store register, register offset, basic
-// Store register, register offset, scaled by 4/8
-// Store register, register offset, scaled by 2
-// Store register, register offset, extend
-// Store register, register offset, extend, scale by 4/8
-// Store register, register offset, extend, scale by 1
-def : WriteRes<WriteSTIdx, [A64FXGI56, A64FXGI2456]> {
- let Latency = 1;
-}
-
-// Store pair, immed offset, W-form
-// Store pair, immed offset, X-form
-def : WriteRes<WriteSTP, [A64FXGI56]> {
- let Latency = 1;
-}
-
-// Store pair, immed post-index, W-form
-// Store pair, immed post-index, X-form
-// Store pair, immed pre-index, W-form
-// Store pair, immed pre-index, X-form
-// NOTE: Handled by WriteAdr, WriteSTP.
-
-def : InstRW<[A64FXWrite_STUR], (instrs STURBi)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STURBBi)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STURDi)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STURHi)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STURHHi)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STURQi)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STURSi)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STURWi)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STURXi)>;
-
-def : InstRW<[WriteAdr, A64FXWrite_STUR], (instrs STTRBi)>;
-def : InstRW<[WriteAdr, A64FXWrite_STUR], (instrs STTRHi)>;
-def : InstRW<[WriteAdr, A64FXWrite_STUR], (instrs STTRWi)>;
-def : InstRW<[WriteAdr, A64FXWrite_STUR], (instrs STTRXi)>;
-
-def : InstRW<[A64FXWrite_STNP], (instrs STNPDi)>;
-def : InstRW<[A64FXWrite_STNP], (instrs STNPQi)>;
-def : InstRW<[A64FXWrite_STNP], (instrs STNPXi)>;
-def : InstRW<[A64FXWrite_STNP], (instrs STNPWi)>;
-
-def : InstRW<[A64FXWrite_STNP], (instrs STPDi)>;
-def : InstRW<[A64FXWrite_STNP], (instrs STPQi)>;
-def : InstRW<[A64FXWrite_STNP], (instrs STPXi)>;
-def : InstRW<[A64FXWrite_STNP], (instrs STPWi)>;
-
-def : InstRW<[A64FXWrite_STUR], (instrs STRBui)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STRBui)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STRDui)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STRDui)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STRHui)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STRHui)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STRQui)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STRQui)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STRXui)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STRXui)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STRWui)>;
-def : InstRW<[A64FXWrite_STUR], (instrs STRWui)>;
-
-def : InstRW<[A64FXWrite_STP01],
- (instrs STPDpre, STPDpost)>;
-def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
- (instrs STPDpre, STPDpost)>;
-def : InstRW<[A64FXWrite_STP01],
- (instrs STPDpre, STPDpost)>;
-def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
- (instrs STPDpre, STPDpost)>;
-def : InstRW<[A64FXWrite_STP01],
- (instrs STPQpre, STPQpost)>;
-def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
- (instrs STPQpre, STPQpost)>;
-def : InstRW<[A64FXWrite_STP01],
- (instrs STPQpre, STPQpost)>;
-def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
- (instrs STPQpre, STPQpost)>;
-def : InstRW<[A64FXWrite_STP01],
- (instrs STPSpre, STPSpost)>;
-def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
- (instrs STPSpre, STPSpost)>;
-def : InstRW<[A64FXWrite_STP01],
- (instrs STPSpre, STPSpost)>;
-def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
- (instrs STPSpre, STPSpost)>;
-def : InstRW<[A64FXWrite_STP01],
- (instrs STPWpre, STPWpost)>;
-def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
- (instrs STPWpre, STPWpost)>;
-def : InstRW<[A64FXWrite_STP01],
- (instrs STPWpre, STPWpost)>;
-def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
- (instrs STPWpre, STPWpost)>;
-def : InstRW<[A64FXWrite_STP01],
- (instrs STPXpre, STPXpost)>;
-def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
- (instrs STPXpre, STPXpost)>;
-def : InstRW<[A64FXWrite_STP01],
- (instrs STPXpre, STPXpost)>;
-def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
- (instrs STPXpre, STPXpost)>;
-
-def : InstRW<[WriteAdr, A64FXWrite_STP01],
- (instrs STRBpre, STRBpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
- (instrs STRBpre, STRBpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01],
- (instrs STRBpre, STRBpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
- (instrs STRBpre, STRBpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01],
- (instrs STRBBpre, STRBBpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
- (instrs STRBBpre, STRBBpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01],
- (instrs STRBBpre, STRBBpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
- (instrs STRBBpre, STRBBpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01],
- (instrs STRDpre, STRDpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
- (instrs STRDpre, STRDpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01],
- (instrs STRDpre, STRDpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
- (instrs STRDpre, STRDpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01],
- (instrs STRHpre, STRHpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
- (instrs STRHpre, STRHpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01],
- (instrs STRHpre, STRHpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
- (instrs STRHpre, STRHpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01],
- (instrs STRHHpre, STRHHpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
- (instrs STRHHpre, STRHHpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01],
- (instrs STRHHpre, STRHHpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
- (instrs STRHHpre, STRHHpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01],
- (instrs STRQpre, STRQpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
- (instrs STRQpre, STRQpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01],
- (instrs STRQpre, STRQpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
- (instrs STRQpre, STRQpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01],
- (instrs STRSpre, STRSpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
- (instrs STRSpre, STRSpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01],
- (instrs STRSpre, STRSpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
- (instrs STRSpre, STRSpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01],
- (instrs STRWpre, STRWpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
- (instrs STRWpre, STRWpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01],
- (instrs STRWpre, STRWpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
- (instrs STRWpre, STRWpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01],
- (instrs STRXpre, STRXpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
- (instrs STRXpre, STRXpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01],
- (instrs STRXpre, STRXpost)>;
-def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
- (instrs STRXpre, STRXpost)>;
-
-def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
- (instrs STRBroW, STRBroX)>;
-def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
- (instrs STRBroW, STRBroX)>;
-def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
- (instrs STRBBroW, STRBBroX)>;
-def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
- (instrs STRBBroW, STRBBroX)>;
-def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
- (instrs STRDroW, STRDroX)>;
-def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
- (instrs STRDroW, STRDroX)>;
-def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
- (instrs STRHroW, STRHroX)>;
-def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
- (instrs STRHroW, STRHroX)>;
-def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
- (instrs STRHHroW, STRHHroX)>;
-def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
- (instrs STRHHroW, STRHHroX)>;
-def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
- (instrs STRQroW, STRQroX)>;
-def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
- (instrs STRQroW, STRQroX)>;
-def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
- (instrs STRSroW, STRSroX)>;
-def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
- (instrs STRSroW, STRSroX)>;
-def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
- (instrs STRWroW, STRWroX)>;
-def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
- (instrs STRWroW, STRWroX)>;
-def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
- (instrs STRXroW, STRXroX)>;
-def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
- (instrs STRXroW, STRXroX)>;
-
-//---
-// 3.8 FP Data Processing Instructions
-//---
-
-// FP absolute value
-// FP min/max
-// FP negate
-def : WriteRes<WriteF, [A64FXGI03]> {
- let Latency = 4;
- let ResourceCycles = [2];
-}
-
-// FP arithmetic
-
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FADDDrr, FADDHrr)>;
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FSUBDrr, FSUBHrr)>;
-
-// FP compare
-def : WriteRes<WriteFCmp, [A64FXGI03]> {
- let Latency = 4;
- let ResourceCycles = [2];
-}
-
-// FP Div, Sqrt
-def : WriteRes<WriteFDiv, [A64FXGI0]> {
- let Latency = 43;
-}
-
-def A64FXXWriteFDiv : SchedWriteRes<[A64FXGI0]> {
- let Latency = 38;
-}
-
-def A64FXXWriteFDivSP : SchedWriteRes<[A64FXGI0]> {
- let Latency = 29;
-}
-
-def A64FXXWriteFDivDP : SchedWriteRes<[A64FXGI0]> {
- let Latency = 43;
-}
-
-def A64FXXWriteFSqrtSP : SchedWriteRes<[A64FXGI0]> {
- let Latency = 29;
-}
-
-def A64FXXWriteFSqrtDP : SchedWriteRes<[A64FXGI0]> {
- let Latency = 43;
-}
-
-// FP divide, S-form
-// FP square root, S-form
-def : InstRW<[A64FXXWriteFDivSP], (instrs FDIVSrr)>;
-def : InstRW<[A64FXXWriteFSqrtSP], (instrs FSQRTSr)>;
-def : InstRW<[A64FXXWriteFDivSP], (instregex "^FDIVv.*32$")>;
-def : InstRW<[A64FXXWriteFSqrtSP], (instregex "^.*SQRT.*32$")>;
-def : InstRW<[A64FXXWriteFDivSP], (instregex "^FDIVSrr")>;
-def : InstRW<[A64FXXWriteFSqrtSP], (instregex "^FSQRTSr")>;
-
-// FP divide, D-form
-// FP square root, D-form
-def : InstRW<[A64FXXWriteFDivDP], (instrs FDIVDrr)>;
-def : InstRW<[A64FXXWriteFSqrtDP], (instrs FSQRTDr)>;
-def : InstRW<[A64FXXWriteFDivDP], (instregex "^FDIVv.*64$")>;
-def : InstRW<[A64FXXWriteFSqrtDP], (instregex "^.*SQRT.*64$")>;
-def : InstRW<[A64FXXWriteFDivDP], (instregex "^FDIVDrr")>;
-def : InstRW<[A64FXXWriteFSqrtDP], (instregex "^FSQRTDr")>;
-
-// FP multiply
-// FP multiply accumulate
-def : WriteRes<WriteFMul, [A64FXGI03]> {
- let Latency = 9;
- let ResourceCycles = [2];
-}
-
-def A64FXXWriteFMul : SchedWriteRes<[A64FXGI03]> {
- let Latency = 9;
- let ResourceCycles = [2];
-}
-
-def A64FXXWriteFMulAcc : SchedWriteRes<[A64FXGI03]> {
- let Latency = 9;
- let ResourceCycles = [2];
-}
-
-def : InstRW<[A64FXXWriteFMul], (instregex "^FMUL", "^FNMUL")>;
-def : InstRW<[A64FXXWriteFMulAcc],
- (instregex "^FMADD", "^FMSUB", "^FNMADD", "^FNMSUB")>;
-
-// FP round to integral
-def : InstRW<[A64FXWrite_9Cyc_GI03],
- (instregex "^FRINT(A|I|M|N|P|X|Z)(Sr|Dr)")>;
-
-// FP select
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instregex "^FCSEL")>;
-
-//---
-// 3.9 FP Miscellaneous Instructions
-//---
-
-// FP convert, from vec to vec reg
-// FP convert, from gen to vec reg
-// FP convert, from vec to gen reg
-def : WriteRes<WriteFCvt, [A64FXGI03]> {
- let Latency = 9;
- let ResourceCycles = [2];
-}
-
-// FP move, immed
-// FP move, register
-def : WriteRes<WriteFImm, [A64FXGI0]> {
- let Latency = 4;
- let ResourceCycles = [2];
-}
-
-// FP transfer, from gen to vec reg
-// FP transfer, from vec to gen reg
-def : WriteRes<WriteFCopy, [A64FXGI0]> {
- let Latency = 4;
- let ResourceCycles = [2];
-}
-
-def : InstRW<[A64FXWrite_FMOV_GV], (instrs FMOVXDHighr)>;
-def : InstRW<[A64FXWrite_FMOV_VG14], (instrs FMOVDXHighr)>;
-
-//---
-// 3.12 ASIMD Integer Instructions
-//---
-
-// ASIMD absolute diff, D-form
-// ASIMD absolute diff, Q-form
-// ASIMD absolute diff accum, D-form
-// ASIMD absolute diff accum, Q-form
-// ASIMD absolute diff accum long
-// ASIMD absolute diff long
-// ASIMD arith, basic
-// ASIMD arith, complex
-// ASIMD compare
-// ASIMD logical (AND, BIC, EOR)
-// ASIMD max/min, basic
-// ASIMD max/min, reduce, 4H/4S
-// ASIMD max/min, reduce, 8B/8H
-// ASIMD max/min, reduce, 16B
-// ASIMD multiply, D-form
-// ASIMD multiply, Q-form
-// ASIMD multiply accumulate long
-// ASIMD multiply accumulate saturating long
-// ASIMD multiply long
-// ASIMD pairwise add and accumulate
-// ASIMD shift accumulate
-// ASIMD shift by immed, basic
-// ASIMD shift by immed and insert, basic, D-form
-// ASIMD shift by immed and insert, basic, Q-form
-// ASIMD shift by immed, complex
-// ASIMD shift by register, basic, D-form
-// ASIMD shift by register, basic, Q-form
-// ASIMD shift by register, complex, D-form
-// ASIMD shift by register, complex, Q-form
-def : WriteRes<WriteV, [A64FXGI03]> {
- let Latency = 4;
- let ResourceCycles = [1];
-}
-
-// ASIMD arith, reduce, 4H/4S
-// ASIMD arith, reduce, 8B/8H
-// ASIMD arith, reduce, 16B
-
-// ASIMD logical (MVN (alias for NOT), ORN, ORR)
-def : InstRW<[A64FXWrite_4Cyc_GI03],
- (instregex "^ANDv", "^BICv", "^EORv", "^ORRv", "^ORNv", "^NOTv")>;
-
-// ASIMD arith, reduce
-def : InstRW<[A64FXWrite_ADDLV],
- (instregex "^ADDVv", "^SADDLVv", "^UADDLVv")>;
-
-// ASIMD polynomial (8x8) multiply long
-def : InstRW<[A64FXWrite_MULLE], (instregex "^(S|U|SQD)MULL")>;
-def : InstRW<[A64FXWrite_MULLV],
- (instregex "(S|U|SQD)(MLAL|MLSL|MULL)v.*")>;
-def : InstRW<[A64FXWrite_8Cyc_GI03], (instregex "^PMULL(v8i8|v16i8)")>;
-def : InstRW<[A64FXWrite_8Cyc_GI03], (instregex "^PMULL(v1i64|v2i64)")>;
-
-// ASIMD absolute diff accum, D-form
-def : InstRW<[A64FXWrite_ABA],
- (instregex "^[SU]ABA(v8i8|v4i16|v2i32)$")>;
-// ASIMD absolute diff accum, Q-form
-def : InstRW<[A64FXWrite_ABA],
- (instregex "^[SU]ABA(v16i8|v8i16|v4i32)$")>;
-// ASIMD absolute diff accum long
-def : InstRW<[A64FXWrite_ABAL],
- (instregex "^[SU]ABAL")>;
-// ASIMD arith, reduce, 4H/4S
-def : InstRW<[A64FXWrite_ADDLV1],
- (instregex "^[SU]?ADDL?V(v8i8|v4i16|v2i32)v$")>;
-// ASIMD arith, reduce, 8B
-def : InstRW<[A64FXWrite_ADDLV1],
- (instregex "^[SU]?ADDL?V(v8i16|v4i32)v$")>;
-// ASIMD arith, reduce, 16B/16H
-def : InstRW<[A64FXWrite_ADDLV1],
- (instregex "^[SU]?ADDL?Vv16i8v$")>;
-// ASIMD max/min, reduce, 4H/4S
-def : InstRW<[A64FXWrite_MINMAXV],
- (instregex "^[SU](MIN|MAX)V(v4i16|v4i32)v$")>;
-// ASIMD max/min, reduce, 8B/8H
-def : InstRW<[A64FXWrite_MINMAXV],
- (instregex "^[SU](MIN|MAX)V(v8i8|v8i16)v$")>;
-// ASIMD max/min, reduce, 16B/16H
-def : InstRW<[A64FXWrite_MINMAXV],
- (instregex "^[SU](MIN|MAX)Vv16i8v$")>;
-// ASIMD multiply, D-form
-def : InstRW<[A64FXWrite_PMUL],
- (instregex "^(P?MUL|SQR?DMUL)" #
- "(v8i8|v4i16|v2i32|v1i8|v1i16|v1i32|v1i64)" #
- "(_indexed)?$")>;
-
-// ASIMD multiply, Q-form
-def : InstRW<[A64FXWrite_PMUL],
- (instregex "^(P?MUL)(v16i8|v8i16|v4i32)(_indexed)?$")>;
-
-// ASIMD multiply, Q-form
-def : InstRW<[A64FXWrite_SQRDMULH],
- (instregex "^(SQR?DMULH)(v16i8|v8i16|v4i32)(_indexed)?$")>;
-
-// ASIMD multiply accumulate, D-form
-def : InstRW<[A64FXWrite_9Cyc_GI03],
- (instregex "^ML[AS](v8i8|v4i16|v2i32)(_indexed)?$")>;
-// ASIMD multiply accumulate, Q-form
-def : InstRW<[A64FXWrite_9Cyc_GI03],
- (instregex "^ML[AS](v16i8|v8i16|v4i32)(_indexed)?$")>;
-// ASIMD shift accumulate
-def : InstRW<[A64FXWrite_SRSRAV],
- (instregex "SRSRAv", "URSRAv")>;
-def : InstRW<[A64FXWrite_SSRAV],
- (instregex "SSRAv", "USRAv")>;
-
-// ASIMD shift by immed, basic
-def : InstRW<[A64FXWrite_RSHRN],
- (instregex "RSHRNv", "SQRSHRNv", "SQRSHRUNv", "UQRSHRNv")>;
-def : InstRW<[A64FXWrite_SHRN],
- (instregex "SHRNv", "SQSHRNv", "SQSHRUNv", "UQSHRNv")>;
-
-def : InstRW<[A64FXWrite_6Cyc_GI3],
- (instregex "SQXTNv", "SQXTUNv", "UQXTNv")>;
-
-// ASIMD shift by immed, complex
-def : InstRW<[A64FXWrite_ABA], (instregex "^[SU]?(Q|R){1,2}SHR")>;
-def : InstRW<[A64FXWrite_6Cyc_GI3], (instregex "^SQSHLU")>;
-// ASIMD shift by register, basic, Q-form
-def : InstRW<[A64FXWrite_6Cyc_GI3],
- (instregex "^[SU]SHL(v16i8|v8i16|v4i32|v2i64)")>;
-// ASIMD shift by register, complex, D-form
-def : InstRW<[A64FXWrite_6Cyc_GI3],
- (instregex "^[SU][QR]{1,2}SHL" #
- "(v1i8|v1i16|v1i32|v1i64|v8i8|v4i16|v2i32|b|d|h|s)")>;
-// ASIMD shift by register, complex, Q-form
-def : InstRW<[A64FXWrite_6Cyc_GI3],
- (instregex "^[SU][QR]{1,2}SHL(v16i8|v8i16|v4i32|v2i64)")>;
-
-// ASIMD Arithmetic
-def : InstRW<[A64FXWrite_4Cyc_GI03],
- (instregex "(ADD|SUB)(v8i8|v4i16|v2i32|v1i64)")>;
-def : InstRW<[A64FXWrite_4Cyc_GI03],
- (instregex "(ADD|SUB)(v16i8|v8i16|v4i32|v2i64)")>;
-def : InstRW<[A64FXWrite_SHRN], (instregex "(ADD|SUB)HNv.*")>;
-def : InstRW<[A64FXWrite_RSHRN], (instregex "(RADD|RSUB)HNv.*")>;
-def : InstRW<[A64FXWrite_4Cyc_GI03],
- (instregex "^SQADD", "^SQNEG", "^SQSUB", "^SRHADD",
- "^SUQADD", "^UQADD", "^UQSUB", "^URHADD", "^USQADD")>;
-def : InstRW<[A64FXWrite_ADDP],
- (instregex "ADDP(v16i8|v8i16|v4i32|v2i64)")>;
-def : InstRW<[A64FXWrite_4Cyc_GI03],
- (instregex "((AND|ORN|EOR|EON)S?(Xr[rsi]|v16i8|v8i16|v4i32)|" #
- "(ORR|BIC)S?(Xr[rs]|v16i8|v8i16|v4i32))")>;
-def : InstRW<[A64FXWrite_4Cyc_GI0],
- (instregex "(CLS|CLZ|CNT)(v4i32|v8i16|v16i8)")>;
-def : InstRW<[A64FXWrite_SADALP], (instregex "^SADALP", "^UADALP")>;
-def : InstRW<[A64FXWrite_SADDLP], (instregex "^SADDLPv", "^UADDLPv")>;
-def : InstRW<[A64FXWrite_ADDLV1], (instregex "^SADDLV", "^UADDLV")>;
-def : InstRW<[A64FXWrite_MINMAXV],
- (instregex "^ADDVv", "^SMAXVv", "^UMAXVv", "^SMINVv", "^UMINVv")>;
-def : InstRW<[A64FXWrite_ABA],
- (instregex "^SABAv", "^UABAv", "^SABALv", "^UABALv")>;
-def : InstRW<[A64FXWrite_4Cyc_GI03],
- (instregex "^SQADDv", "^SQSUBv", "^UQADDv", "^UQSUBv")>;
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instregex "^SUQADDv", "^USQADDv")>;
-def : InstRW<[A64FXWrite_SHRN],
- (instregex "^ADDHNv", "^SUBHNv")>;
-def : InstRW<[A64FXWrite_RSHRN],
- (instregex "^RADDHNv", "^RSUBHNv")>;
-def : InstRW<[A64FXWrite_4Cyc_GI03],
- (instregex "^SQABS", "^SQADD", "^SQNEG", "^SQSUB",
- "^SRHADD", "^SUQADD", "^UQADD", "^UQSUB",
- "^URHADD", "^USQADD")>;
-
-def : InstRW<[A64FXWrite_4Cyc_GI03],
- (instregex "^CMEQv", "^CMGEv", "^CMGTv",
- "^CMLEv", "^CMLTv", "^CMHIv", "^CMHSv")>;
-def : InstRW<[A64FXWrite_MINMAXV],
- (instregex "^SMAXv", "^SMINv", "^UMAXv", "^UMINv")>;
-def : InstRW<[A64FXWrite_ADDP],
- (instregex "^SMAXPv", "^SMINPv", "^UMAXPv", "^UMINPv")>;
-def : InstRW<[A64FXWrite_4Cyc_GI03],
- (instregex "^SABDv", "^UABDv")>;
-def : InstRW<[A64FXWrite_TBX1],
- (instregex "^SABDLv", "^UABDLv")>;
-
-//---
-// 3.13 ASIMD Floating-point Instructions
-//---
-
-// ASIMD FP absolute value
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instregex "^FABSv")>;
-
-// ASIMD FP arith, normal, D-form
-// ASIMD FP arith, normal, Q-form
-def : InstRW<[A64FXWrite_9Cyc_GI03],
- (instregex "^FABDv", "^FADDv", "^FSUBv")>;
-
-// ASIMD FP arith, pairwise, D-form
-// ASIMD FP arith, pairwise, Q-form
-def : InstRW<[A64FXWrite_FADDPV], (instregex "^FADDPv")>;
-
-// ASIMD FP compare, D-form
-// ASIMD FP compare, Q-form
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instregex "^FACGEv", "^FACGTv")>;
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instregex "^FCMEQv", "^FCMGEv",
- "^FCMGTv", "^FCMLEv",
- "^FCMLTv")>;
-// ASIMD FP round, D-form
-def : InstRW<[A64FXWrite_9Cyc_GI03],
- (instregex "^FRINT[AIMNPXZ](v2f32)")>;
-// ASIMD FP round, Q-form
-def : InstRW<[A64FXWrite_9Cyc_GI03],
- (instregex "^FRINT[AIMNPXZ](v4f32|v2f64)")>;
-
-// ASIMD FP convert, long
-// ASIMD FP convert, narrow
-// ASIMD FP convert, other, D-form
-// ASIMD FP convert, other, Q-form
-
-// ASIMD FP convert, long and narrow
-def : InstRW<[A64FXWrite_FCVTXNV], (instregex "^FCVT(L|N|XN)v")>;
-// ASIMD FP convert, other, D-form
-def : InstRW<[A64FXWrite_FCVTXNV],
- (instregex "^[FVSU]CVT([AMNPZ][SU])?(_Int)?(v2f32|v1i32|v2i32|v1i64)")>;
-// ASIMD FP convert, other, Q-form
-def : InstRW<[A64FXWrite_FCVTXNV],
- (instregex "^[FVSU]CVT([AMNPZ][SU])?(_Int)?(v4f32|v2f64|v4i32|v2i64)")>;
-
-// ASIMD FP divide, D-form, F32
-def : InstRW<[A64FXXWriteFDivSP], (instrs FDIVv2f32)>;
-def : InstRW<[A64FXXWriteFDivSP], (instregex "FDIVv2f32")>;
-
-// ASIMD FP divide, Q-form, F32
-def : InstRW<[A64FXXWriteFDiv], (instrs FDIVv4f32)>;
-def : InstRW<[A64FXXWriteFDiv], (instregex "FDIVv4f32")>;
-
-// ASIMD FP divide, Q-form, F64
-def : InstRW<[A64FXXWriteFDivDP], (instrs FDIVv2f64)>;
-def : InstRW<[A64FXXWriteFDivDP], (instregex "FDIVv2f64")>;
-
-// ASIMD FP max/min, normal, D-form
-// ASIMD FP max/min, normal, Q-form
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instregex "^FMAXv", "^FMAXNMv",
- "^FMINv", "^FMINNMv")>;
-
-// ASIMD FP max/min, pairwise, D-form
-// ASIMD FP max/min, pairwise, Q-form
-def : InstRW<[A64FXWrite_ADDP], (instregex "^FMAXPv", "^FMAXNMPv",
- "^FMINPv", "^FMINNMPv")>;
-
-// ASIMD FP max/min, reduce
-def : InstRW<[A64FXWrite_FMAXVVH], (instregex "^FMAXVv", "^FMAXNMVv",
- "^FMINVv", "^FMINNMVv")>;
-
-// ASIMD FP multiply, D-form, FZ
-// ASIMD FP multiply, D-form, no FZ
-// ASIMD FP multiply, Q-form, FZ
-// ASIMD FP multiply, Q-form, no FZ
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instregex "^FMULv", "^FMULXv")>;
-def : InstRW<[A64FXWrite_FMULXE],
- (instregex "^FMULX?(v2f32|v1i32|v2i32|v1i64|32|64)")>;
-def : InstRW<[A64FXWrite_FMULXE],
- (instregex "^FMULX?(v4f32|v2f64|v4i32|v2i64)")>;
-
-// ASIMD FP multiply accumulate, Dform, FZ
-// ASIMD FP multiply accumulate, Dform, no FZ
-// ASIMD FP multiply accumulate, Qform, FZ
-// ASIMD FP multiply accumulate, Qform, no FZ
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instregex "^FMLAv", "^FMLSv")>;
-def : InstRW<[A64FXWrite_FMULXE],
- (instregex "^FML[AS](v2f32|v1i32|v2i32|v1i64)")>;
-def : InstRW<[A64FXWrite_FMULXE],
- (instregex "^FML[AS](v4f32|v2f64|v4i32|v2i64)")>;
-
-// ASIMD FP negate
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instregex "^FNEGv")>;
-
-//--
-// 3.14 ASIMD Miscellaneous Instructions
-//--
-
-// ASIMD bit reverse
-def : InstRW<[A64FXWrite_1Cyc_GI2456], (instregex "^RBITv")>;
-
-// ASIMD bitwise insert, D-form
-// ASIMD bitwise insert, Q-form
-def : InstRW<[A64FXWrite_BIF],
- (instregex "^BIFv", "^BITv", "^BSLv")>;
-
-// ASIMD count, D-form
-// ASIMD count, Q-form
-def : InstRW<[A64FXWrite_4Cyc_GI0],
- (instregex "^CLSv", "^CLZv", "^CNTv")>;
-
-// ASIMD duplicate, gen reg
-// ASIMD duplicate, element
-def : InstRW<[A64FXWrite_DUPGENERAL], (instregex "^DUPv")>;
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^CPY")>;
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^DUPv.+gpr")>;
-
-// ASIMD extract
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^EXTv")>;
-
-// ASIMD extract narrow
-def : InstRW<[A64FXWrite_6Cyc_GI3], (instregex "^XTNv")>;
-
-// ASIMD extract narrow, saturating
-def : InstRW<[A64FXWrite_6Cyc_GI3],
- (instregex "^SQXTNv", "^SQXTUNv", "^UQXTNv")>;
-
-// ASIMD insert, element to element
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^INSv")>;
-
-// ASIMD transfer, element to gen reg
-def : InstRW<[A64FXWrite_SMOV], (instregex "^[SU]MOVv")>;
-
-// ASIMD move, integer immed
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instregex "^MOVIv")>;
-
-// ASIMD move, FP immed
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instregex "^FMOVv")>;
-
-// ASIMD table lookup, D-form
-def : InstRW<[A64FXWrite_6Cyc_GI3], (instregex "^TBLv8i8One")>;
-def : InstRW<[A64FXWrite_TBX1], (instregex "^TBLv8i8Two")>;
-def : InstRW<[A64FXWrite_TBX2], (instregex "^TBLv8i8Three")>;
-def : InstRW<[A64FXWrite_TBX3], (instregex "^TBLv8i8Four")>;
-def : InstRW<[A64FXWrite_TBX1], (instregex "^TBXv8i8One")>;
-def : InstRW<[A64FXWrite_TBX2], (instregex "^TBXv8i8Two")>;
-def : InstRW<[A64FXWrite_TBX3], (instregex "^TBXv8i8Three")>;
-def : InstRW<[A64FXWrite_TBX4], (instregex "^TBXv8i8Four")>;
-
-// ASIMD table lookup, Q-form
-def : InstRW<[A64FXWrite_6Cyc_GI3], (instregex "^TBLv16i8One")>;
-def : InstRW<[A64FXWrite_TBX1], (instregex "^TBLv16i8Two")>;
-def : InstRW<[A64FXWrite_TBX2], (instregex "^TBLv16i8Three")>;
-def : InstRW<[A64FXWrite_TBX3], (instregex "^TBLv16i8Four")>;
-def : InstRW<[A64FXWrite_TBX1], (instregex "^TBXv16i8One")>;
-def : InstRW<[A64FXWrite_TBX2], (instregex "^TBXv16i8Two")>;
-def : InstRW<[A64FXWrite_TBX3], (instregex "^TBXv16i8Three")>;
-def : InstRW<[A64FXWrite_TBX4], (instregex "^TBXv16i8Four")>;
-
-// ASIMD transpose
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^TRN1", "^TRN2")>;
-
-// ASIMD unzip/zip
-def : InstRW<[A64FXWrite_6Cyc_GI0],
- (instregex "^UZP1", "^UZP2", "^ZIP1", "^ZIP2")>;
-
-// ASIMD reciprocal estimate, D-form
-// ASIMD reciprocal estimate, Q-form
-def : InstRW<[A64FXWrite_4Cyc_GI03],
- (instregex "^FRECPEv", "^FRECPXv", "^URECPEv",
- "^FRSQRTEv", "^URSQRTEv")>;
-
-// ASIMD reciprocal step, D-form, FZ
-// ASIMD reciprocal step, D-form, no FZ
-// ASIMD reciprocal step, Q-form, FZ
-// ASIMD reciprocal step, Q-form, no FZ
-def : InstRW<[A64FXWrite_9Cyc_GI0], (instregex "^FRECPSv", "^FRSQRTSv")>;
-
-// ASIMD reverse
-def : InstRW<[A64FXWrite_4Cyc_GI03],
- (instregex "^REV16v", "^REV32v", "^REV64v")>;
-
-// ASIMD table lookup, D-form
-// ASIMD table lookup, Q-form
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^TBLv", "^TBXv")>;
-
-// ASIMD transfer, element to word or word
-def : InstRW<[A64FXWrite_SMOV], (instregex "^[SU]MOVv")>;
-
-// ASIMD transfer, element to gen reg
-def : InstRW<[A64FXWrite_SMOV], (instregex "(S|U)MOVv.*")>;
-
-// ASIMD transfer gen reg to element
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^INSv")>;
-
-// ASIMD transpose
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^TRN1v", "^TRN2v",
- "^UZP1v", "^UZP2v")>;
-
-// ASIMD unzip/zip
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^ZIP1v", "^ZIP2v")>;
-
-//--
-// 3.15 ASIMD Load Instructions
-//--
-
-// ASIMD load, 1 element, multiple, 1 reg, D-form
-// ASIMD load, 1 element, multiple, 1 reg, Q-form
-def : InstRW<[A64FXWrite_8Cyc_GI56],
- (instregex "^LD1Onev(8b|4h|2s|1d|2d)$")>;
-def : InstRW<[A64FXWrite_11Cyc_GI56],
- (instregex "^LD1Onev(16b|8h|4s)$")>;
-def : InstRW<[A64FXWrite_LD108, WriteAdr],
- (instregex "^LD1Onev(8b|4h|2s|1d|2d)_POST$")>;
-def : InstRW<[A64FXWrite_LD109, WriteAdr],
- (instregex "^LD1Onev(16b|8h|4s)_POST$")>;
-
-// ASIMD load, 1 element, multiple, 2 reg, D-form
-// ASIMD load, 1 element, multiple, 2 reg, Q-form
-def : InstRW<[A64FXWrite_LD102],
- (instregex "^LD1Twov(8b|4h|2s|1d|2d)$")>;
-def : InstRW<[A64FXWrite_LD103],
- (instregex "^LD1Twov(16b|8h|4s)$")>;
-def : InstRW<[A64FXWrite_LD110, WriteAdr],
- (instregex "^LD1Twov(8b|4h|2s|1d|2d)_POST$")>;
-def : InstRW<[A64FXWrite_LD111, WriteAdr],
- (instregex "^LD1Twov(16b|8h|4s)_POST$")>;
-
-// ASIMD load, 1 element, multiple, 3 reg, D-form
-// ASIMD load, 1 element, multiple, 3 reg, Q-form
-def : InstRW<[A64FXWrite_LD104],
- (instregex "^LD1Threev(8b|4h|2s|1d|2d)$")>;
-def : InstRW<[A64FXWrite_LD105],
- (instregex "^LD1Threev(16b|8h|4s)$")>;
-def : InstRW<[A64FXWrite_LD112, WriteAdr],
- (instregex "^LD1Threev(8b|4h|2s|1d|2d)_POST$")>;
-def : InstRW<[A64FXWrite_LD113, WriteAdr],
- (instregex "^LD1Threev(16b|8h|4s)_POST$")>;
-
-// ASIMD load, 1 element, multiple, 4 reg, D-form
-// ASIMD load, 1 element, multiple, 4 reg, Q-form
-def : InstRW<[A64FXWrite_LD106],
- (instregex "^LD1Fourv(8b|4h|2s|1d|2d)$")>;
-def : InstRW<[A64FXWrite_LD107],
- (instregex "^LD1Fourv(16b|8h|4s)$")>;
-def : InstRW<[A64FXWrite_LD114, WriteAdr],
- (instregex "^LD1Fourv(8b|4h|2s|1d|2d)_POST$")>;
-def : InstRW<[A64FXWrite_LD115, WriteAdr],
- (instregex "^LD1Fourv(16b|8h|4s)_POST$")>;
-
-// ASIMD load, 1 element, one lane, B/H/S
-// ASIMD load, 1 element, one lane, D
-def : InstRW<[A64FXWrite_LD1I0], (instregex "^LD1i(8|16|32|64)$")>;
-def : InstRW<[A64FXWrite_LD1I1, WriteAdr],
- (instregex "^LD1i(8|16|32|64)_POST$")>;
-
-// ASIMD load, 1 element, all lanes, D-form, B/H/S
-// ASIMD load, 1 element, all lanes, D-form, D
-// ASIMD load, 1 element, all lanes, Q-form
-def : InstRW<[A64FXWrite_8Cyc_GI03],
- (instregex "^LD1Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[A64FXWrite_LD108, WriteAdr],
- (instregex "^LD1Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-// ASIMD load, 2 element, multiple, D-form, B/H/S
-// ASIMD load, 2 element, multiple, Q-form, D
-def : InstRW<[A64FXWrite_LD103],
- (instregex "^LD2Twov(8b|4h|2s|16b|8h|4s|2d)$")>;
-def : InstRW<[A64FXWrite_LD111, WriteAdr],
- (instregex "^LD2Twov(8b|4h|2s|16b|8h|4s|2d)_POST$")>;
-
-// ASIMD load, 2 element, one lane, B/H
-// ASIMD load, 2 element, one lane, S
-// ASIMD load, 2 element, one lane, D
-def : InstRW<[A64FXWrite_LD2I0], (instregex "^LD2i(8|16|32|64)$")>;
-def : InstRW<[A64FXWrite_LD2I1, WriteAdr],
- (instregex "^LD2i(8|16|32|64)_POST$")>;
-
-// ASIMD load, 2 element, all lanes, D-form, B/H/S
-// ASIMD load, 2 element, all lanes, D-form, D
-// ASIMD load, 2 element, all lanes, Q-form
-def : InstRW<[A64FXWrite_LD102],
- (instregex "^LD2Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[A64FXWrite_LD110, WriteAdr],
- (instregex "^LD2Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-// ASIMD load, 3 element, multiple, D-form, B/H/S
-// ASIMD load, 3 element, multiple, Q-form, B/H/S
-// ASIMD load, 3 element, multiple, Q-form, D
-def : InstRW<[A64FXWrite_LD105],
- (instregex "^LD3Threev(8b|4h|2s|16b|8h|4s|2d)$")>;
-def : InstRW<[A64FXWrite_LD113, WriteAdr],
- (instregex "^LD3Threev(8b|4h|2s|16b|8h|4s|2d)_POST$")>;
-
-// ASIMD load, 3 element, one lone, B/H
-// ASIMD load, 3 element, one lane, S
-// ASIMD load, 3 element, one lane, D
-def : InstRW<[A64FXWrite_LD3I0], (instregex "^LD3i(8|16|32|64)$")>;
-def : InstRW<[A64FXWrite_LD3I1, WriteAdr],
- (instregex "^LD3i(8|16|32|64)_POST$")>;
-
-// ASIMD load, 3 element, all lanes, D-form, B/H/S
-// ASIMD load, 3 element, all lanes, D-form, D
-// ASIMD load, 3 element, all lanes, Q-form, B/H/S
-// ASIMD load, 3 element, all lanes, Q-form, D
-def : InstRW<[A64FXWrite_LD104],
- (instregex "^LD3Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[A64FXWrite_LD112, WriteAdr],
- (instregex "^LD3Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-// ASIMD load, 4 element, multiple, D-form, B/H/S
-// ASIMD load, 4 element, multiple, Q-form, B/H/S
-// ASIMD load, 4 element, multiple, Q-form, D
-def : InstRW<[A64FXWrite_LD107],
- (instregex "^LD4Fourv(8b|4h|2s|16b|8h|4s|2d)$")>;
-def : InstRW<[A64FXWrite_LD115, WriteAdr],
- (instregex "^LD4Fourv(8b|4h|2s|16b|8h|4s|2d)_POST$")>;
-
-// ASIMD load, 4 element, one lane, B/H
-// ASIMD load, 4 element, one lane, S
-// ASIMD load, 4 element, one lane, D
-def : InstRW<[A64FXWrite_LD4I0], (instregex "^LD4i(8|16|32|64)$")>;
-def : InstRW<[A64FXWrite_LD4I1, WriteAdr],
- (instregex "^LD4i(8|16|32|64)_POST$")>;
-
-// ASIMD load, 4 element, all lanes, D-form, B/H/S
-// ASIMD load, 4 element, all lanes, D-form, D
-// ASIMD load, 4 element, all lanes, Q-form, B/H/S
-// ASIMD load, 4 element, all lanes, Q-form, D
-def : InstRW<[A64FXWrite_LD106],
- (instregex "^LD4Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[A64FXWrite_LD114, WriteAdr],
- (instregex "^LD4Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-//--
-// 3.16 ASIMD Store Instructions
-//--
-
-// ASIMD store, 1 element, multiple, 1 reg, D-form
-// ASIMD store, 1 element, multiple, 1 reg, Q-form
-def : InstRW<[A64FXWrite_ST10],
- (instregex "^ST1Onev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[A64FXWrite_ST14, WriteAdr],
- (instregex "^ST1Onev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-// ASIMD store, 1 element, multiple, 2 reg, D-form
-// ASIMD store, 1 element, multiple, 2 reg, Q-form
-def : InstRW<[A64FXWrite_ST11],
- (instregex "^ST1Twov(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[A64FXWrite_ST15, WriteAdr],
- (instregex "^ST1Twov(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-// ASIMD store, 1 element, multiple, 3 reg, D-form
-// ASIMD store, 1 element, multiple, 3 reg, Q-form
-def : InstRW<[A64FXWrite_ST12],
- (instregex "^ST1Threev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[A64FXWrite_ST16, WriteAdr],
- (instregex "^ST1Threev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-// ASIMD store, 1 element, multiple, 4 reg, D-form
-// ASIMD store, 1 element, multiple, 4 reg, Q-form
-def : InstRW<[A64FXWrite_ST13],
- (instregex "^ST1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[A64FXWrite_ST17, WriteAdr],
- (instregex "^ST1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-// ASIMD store, 1 element, one lane, B/H/S
-// ASIMD store, 1 element, one lane, D
-def : InstRW<[A64FXWrite_ST10],
- (instregex "^ST1i(8|16|32|64)$")>;
-def : InstRW<[A64FXWrite_ST14, WriteAdr],
- (instregex "^ST1i(8|16|32|64)_POST$")>;
-
-// ASIMD store, 2 element, multiple, D-form, B/H/S
-// ASIMD store, 2 element, multiple, Q-form, B/H/S
-// ASIMD store, 2 element, multiple, Q-form, D
-def : InstRW<[A64FXWrite_ST11],
- (instregex "^ST2Twov(8b|4h|2s|16b|8h|4s|2d)$")>;
-def : InstRW<[A64FXWrite_ST15, WriteAdr],
- (instregex "^ST2Twov(8b|4h|2s|16b|8h|4s|2d)_POST$")>;
-
-// ASIMD store, 2 element, one lane, B/H/S
-// ASIMD store, 2 element, one lane, D
-def : InstRW<[A64FXWrite_ST11],
- (instregex "^ST2i(8|16|32|64)$")>;
-def : InstRW<[A64FXWrite_ST15, WriteAdr],
- (instregex "^ST2i(8|16|32|64)_POST$")>;
-
-// ASIMD store, 3 element, multiple, D-form, B/H/S
-// ASIMD store, 3 element, multiple, Q-form, B/H/S
-// ASIMD store, 3 element, multiple, Q-form, D
-def : InstRW<[A64FXWrite_ST12],
- (instregex "^ST3Threev(8b|4h|2s|16b|8h|4s|2d)$")>;
-def : InstRW<[A64FXWrite_ST16, WriteAdr],
- (instregex "^ST3Threev(8b|4h|2s|16b|8h|4s|2d)_POST$")>;
-
-// ASIMD store, 3 element, one lane, B/H
-// ASIMD store, 3 element, one lane, S
-// ASIMD store, 3 element, one lane, D
-def : InstRW<[A64FXWrite_ST12], (instregex "^ST3i(8|16|32|64)$")>;
-def : InstRW<[A64FXWrite_ST16, WriteAdr],
- (instregex "^ST3i(8|16|32|64)_POST$")>;
-
-// ASIMD store, 4 element, multiple, D-form, B/H/S
-// ASIMD store, 4 element, multiple, Q-form, B/H/S
-// ASIMD store, 4 element, multiple, Q-form, D
-def : InstRW<[A64FXWrite_ST13],
- (instregex "^ST4Fourv(8b|4h|2s|16b|8h|4s|2d)$")>;
-def : InstRW<[A64FXWrite_ST17, WriteAdr],
- (instregex "^ST4Fourv(8b|4h|2s|16b|8h|4s|2d)_POST$")>;
-
-// ASIMD store, 4 element, one lane, B/H
-// ASIMD store, 4 element, one lane, S
-// ASIMD store, 4 element, one lane, D
-def : InstRW<[A64FXWrite_ST13], (instregex "^ST4i(8|16|32|64)$")>;
-def : InstRW<[A64FXWrite_ST17, WriteAdr],
- (instregex "^ST4i(8|16|32|64)_POST$")>;
-
-// V8.1a Atomics (LSE)
-def : InstRW<[A64FXWrite_CAS, WriteAtomic],
- (instrs CASB, CASH, CASW, CASX)>;
-
-def : InstRW<[A64FXWrite_CAS, WriteAtomic],
- (instrs CASAB, CASAH, CASAW, CASAX)>;
-
-def : InstRW<[A64FXWrite_CAS, WriteAtomic],
- (instrs CASLB, CASLH, CASLW, CASLX)>;
-
-def : InstRW<[A64FXWrite_CAS, WriteAtomic],
- (instrs CASALB, CASALH, CASALW, CASALX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDLARB, LDLARH, LDLARW, LDLARX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDADDB, LDADDH, LDADDW, LDADDX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDADDAB, LDADDAH, LDADDAW, LDADDAX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDADDLB, LDADDLH, LDADDLW, LDADDLX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDADDALB, LDADDALH, LDADDALW, LDADDALX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDCLRB, LDCLRH, LDCLRW, LDCLRX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDCLRAB, LDCLRAH, LDCLRAW, LDCLRAX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDCLRLB, LDCLRLH, LDCLRLW, LDCLRLX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDCLRALB, LDCLRALH, LDCLRALW, LDCLRALX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDEORB, LDEORH, LDEORW, LDEORX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDEORAB, LDEORAH, LDEORAW, LDEORAX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDEORLB, LDEORLH, LDEORLW, LDEORLX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDEORALB, LDEORALH, LDEORALW, LDEORALX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDSETB, LDSETH, LDSETW, LDSETX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDSETAB, LDSETAH, LDSETAW, LDSETAX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDSETLB, LDSETLH, LDSETLW, LDSETLX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDSETALB, LDSETALH, LDSETALW, LDSETALX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDSMAXB, LDSMAXH, LDSMAXW, LDSMAXX,
- LDSMAXAB, LDSMAXAH, LDSMAXAW, LDSMAXAX,
- LDSMAXLB, LDSMAXLH, LDSMAXLW, LDSMAXLX,
- LDSMAXALB, LDSMAXALH, LDSMAXALW, LDSMAXALX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDSMINB, LDSMINH, LDSMINW, LDSMINX,
- LDSMINAB, LDSMINAH, LDSMINAW, LDSMINAX,
- LDSMINLB, LDSMINLH, LDSMINLW, LDSMINLX,
- LDSMINALB, LDSMINALH, LDSMINALW, LDSMINALX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDUMAXB, LDUMAXH, LDUMAXW, LDUMAXX,
- LDUMAXAB, LDUMAXAH, LDUMAXAW, LDUMAXAX,
- LDUMAXLB, LDUMAXLH, LDUMAXLW, LDUMAXLX,
- LDUMAXALB, LDUMAXALH, LDUMAXALW, LDUMAXALX)>;
-
-def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
- (instrs LDUMINB, LDUMINH, LDUMINW, LDUMINX,
- LDUMINAB, LDUMINAH, LDUMINAW, LDUMINAX,
- LDUMINLB, LDUMINLH, LDUMINLW, LDUMINLX,
- LDUMINALB, LDUMINALH, LDUMINALW, LDUMINALX)>;
-
-def : InstRW<[A64FXWrite_SWP, WriteAtomic],
- (instrs SWPB, SWPH, SWPW, SWPX)>;
-
-def : InstRW<[A64FXWrite_SWP, WriteAtomic],
- (instrs SWPAB, SWPAH, SWPAW, SWPAX)>;
-
-def : InstRW<[A64FXWrite_SWP, WriteAtomic],
- (instrs SWPLB, SWPLH, SWPLW, SWPLX)>;
-
-def : InstRW<[A64FXWrite_SWP, WriteAtomic],
- (instrs SWPALB, SWPALH, SWPALW, SWPALX)>;
-
-def : InstRW<[A64FXWrite_STUR, WriteAtomic],
- (instrs STLLRB, STLLRH, STLLRW, STLLRX)>;
-
-// [ 1] "abs $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ABS_ZPmZ_B, ABS_ZPmZ_D, ABS_ZPmZ_H, ABS_ZPmZ_S)>;
-
-// [ 2] "add $Zd, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ADD_ZZZ_B, ADD_ZZZ_D, ADD_ZZZ_H, ADD_ZZZ_S)>;
-
-// [ 3] "add $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ADD_ZPmZ_B, ADD_ZPmZ_D, ADD_ZPmZ_H, ADD_ZPmZ_S)>;
-
-// [ 4] "add $Zdn, $_Zdn, $imm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ADD_ZI_B, ADD_ZI_D, ADD_ZI_H, ADD_ZI_S)>;
-
-// [ 5] "addpl $Rd, $Rn, $imm6";
-def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs ADDPL_XXI)>;
-
-// [ 6] "addvl $Rd, $Rn, $imm6";
-def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs ADDVL_XXI)>;
-
-// [ 7] "adr $Zd, [$Zn, $Zm]";
-def : InstRW<[A64FXWrite_5Cyc_GI0], (instrs ADR_LSL_ZZZ_D_0, ADR_LSL_ZZZ_D_1, ADR_LSL_ZZZ_D_2, ADR_LSL_ZZZ_D_3, ADR_LSL_ZZZ_S_0, ADR_LSL_ZZZ_S_1, ADR_LSL_ZZZ_S_2, ADR_LSL_ZZZ_S_3, ADR_SXTW_ZZZ_D_0, ADR_SXTW_ZZZ_D_1, ADR_SXTW_ZZZ_D_2, ADR_SXTW_ZZZ_D_3, ADR_UXTW_ZZZ_D_0, ADR_UXTW_ZZZ_D_1, ADR_UXTW_ZZZ_D_2, ADR_UXTW_ZZZ_D_3)>;
-
-// [ 8] "and $Pd, $Pg/z, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs AND_PPzPP)>;
-
-// [ 9] "and $Zd, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs AND_ZZZ)>;
-
-// [10] "and $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs AND_ZPmZ_B, AND_ZPmZ_D, AND_ZPmZ_H, AND_ZPmZ_S)>;
-
-// [11] "and $Zdn, $_Zdn, $imms13";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs AND_ZI)>;
-
-// [12] "ands $Pd, $Pg/z, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs ANDS_PPzPP)>;
-
-// [13] "andv $Vd, $Pg, $Zn";
-def : InstRW<[A64FXWrite_14Cyc_GI03], (instrs ANDV_VPZ_B, ANDV_VPZ_D, ANDV_VPZ_H, ANDV_VPZ_S)>;
-
-// [14] "asr $Zd, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ASR_WIDE_ZZZ_B, ASR_WIDE_ZZZ_H, ASR_WIDE_ZZZ_S)>;
-
-// [15] "asr $Zd, $Zn, $imm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ASR_ZZI_B, ASR_ZZI_D, ASR_ZZI_H, ASR_ZZI_S)>;
-
-// [16] "asr $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ASR_WIDE_ZPmZ_B, ASR_WIDE_ZPmZ_H, ASR_WIDE_ZPmZ_S, ASR_ZPmZ_B, ASR_ZPmZ_D, ASR_ZPmZ_H, ASR_ZPmZ_S)>;
-
-// [17] "asr $Zdn, $Pg/m, $_Zdn, $imm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ASR_ZPmI_B, ASR_ZPmI_D, ASR_ZPmI_H, ASR_ZPmI_S)>;
-
-// [18] "asrd $Zdn, $Pg/m, $_Zdn, $imm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ASRD_ZPmI_B, ASRD_ZPmI_D, ASRD_ZPmI_H, ASRD_ZPmI_S)>;
-
-// [19] "asrr $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ASRR_ZPmZ_B, ASRR_ZPmZ_D, ASRR_ZPmZ_H, ASRR_ZPmZ_S)>;
-
-// [20] "bic $Pd, $Pg/z, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BIC_PPzPP)>;
-
-// [21] "bic $Zd, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs BIC_ZZZ)>;
-
-// [22] "bic $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs BIC_ZPmZ_B, BIC_ZPmZ_D, BIC_ZPmZ_H, BIC_ZPmZ_S)>;
-
-// [23] "bics $Pd, $Pg/z, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BICS_PPzPP)>;
-
-// [24] "brka $Pd, $Pg/m, $Pn";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKA_PPmP)>;
-
-// [25] "brka $Pd, $Pg/z, $Pn";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKA_PPzP)>;
-
-// [26] "brkas $Pd, $Pg/z, $Pn";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKAS_PPzP)>;
-
-// [27] "brkb $Pd, $Pg/m, $Pn";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKB_PPmP)>;
-
-// [28] "brkb $Pd, $Pg/z, $Pn";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKB_PPzP)>;
-
-// [29] "brkbs $Pd, $Pg/z, $Pn";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKBS_PPzP)>;
-
-// [30] "brkn $Pdm, $Pg/z, $Pn, $_Pdm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKN_PPzP)>;
-
-// [31] "brkns $Pdm, $Pg/z, $Pn, $_Pdm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKNS_PPzP)>;
-
-// [32] "brkpa $Pd, $Pg/z, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKPA_PPzPP)>;
-
-// [33] "brkpas $Pd, $Pg/z, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKPAS_PPzPP)>;
-
-// [34] "brkpb $Pd, $Pg/z, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKPB_PPzPP)>;
-
-// [35] "brkpbs $Pd, $Pg/z, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKPBS_PPzPP)>;
-
-// [36] "clasta $Rdn, $Pg, $_Rdn, $Zm";
-def : InstRW<[A64FXWrite_29Cyc_GI0256], (instrs CLASTA_RPZ_B, CLASTA_RPZ_D, CLASTA_RPZ_H, CLASTA_RPZ_S)>;
-
-// [37] "clasta $Vdn, $Pg, $_Vdn, $Zm";
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs CLASTA_VPZ_B, CLASTA_VPZ_D, CLASTA_VPZ_H, CLASTA_VPZ_S)>;
-
-// [38] "clasta $Zdn, $Pg, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs CLASTA_ZPZ_B, CLASTA_ZPZ_D, CLASTA_ZPZ_H, CLASTA_ZPZ_S)>;
-
-// [39] "clastb $Rdn, $Pg, $_Rdn, $Zm";
-def : InstRW<[A64FXWrite_29Cyc_GI0256], (instrs CLASTB_RPZ_B, CLASTB_RPZ_D, CLASTB_RPZ_H, CLASTB_RPZ_S)>;
-
-// [40] "clastb $Vdn, $Pg, $_Vdn, $Zm";
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs CLASTB_VPZ_B, CLASTB_VPZ_D, CLASTB_VPZ_H, CLASTB_VPZ_S)>;
-
-// [41] "clastb $Zdn, $Pg, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs CLASTB_ZPZ_B, CLASTB_ZPZ_D, CLASTB_ZPZ_H, CLASTB_ZPZ_S)>;
-
-// [42] "cls $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs CLS_ZPmZ_B, CLS_ZPmZ_D, CLS_ZPmZ_H, CLS_ZPmZ_S)>;
-
-// [43] "clz $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs CLZ_ZPmZ_B, CLZ_ZPmZ_D, CLZ_ZPmZ_H, CLZ_ZPmZ_S)>;
-
-// [44] "cmpeq $Pd, $Pg/z, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPEQ_PPzZZ_B, CMPEQ_PPzZZ_D, CMPEQ_PPzZZ_H, CMPEQ_PPzZZ_S, CMPEQ_WIDE_PPzZZ_B, CMPEQ_WIDE_PPzZZ_H, CMPEQ_WIDE_PPzZZ_S)>;
-
-// [45] "cmpeq $Pd, $Pg/z, $Zn, $imm5";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPEQ_PPzZI_B, CMPEQ_PPzZI_D, CMPEQ_PPzZI_H, CMPEQ_PPzZI_S)>;
-
-// [46] "cmpge $Pd, $Pg/z, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPGE_PPzZZ_B, CMPGE_PPzZZ_D, CMPGE_PPzZZ_H, CMPGE_PPzZZ_S, CMPGE_WIDE_PPzZZ_B, CMPGE_WIDE_PPzZZ_H, CMPGE_WIDE_PPzZZ_S)>;
-
-// [47] "cmpge $Pd, $Pg/z, $Zn, $imm5";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPGE_PPzZI_B, CMPGE_PPzZI_D, CMPGE_PPzZI_H, CMPGE_PPzZI_S)>;
-
-// [48] "cmpgt $Pd, $Pg/z, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPGT_PPzZZ_B, CMPGT_PPzZZ_D, CMPGT_PPzZZ_H, CMPGT_PPzZZ_S, CMPGT_WIDE_PPzZZ_B, CMPGT_WIDE_PPzZZ_H, CMPGT_WIDE_PPzZZ_S)>;
-
-// [49] "cmpgt $Pd, $Pg/z, $Zn, $imm5";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPGT_PPzZI_B, CMPGT_PPzZI_D, CMPGT_PPzZI_H, CMPGT_PPzZI_S)>;
-
-// [50] "cmphi $Pd, $Pg/z, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPHI_PPzZZ_B, CMPHI_PPzZZ_D, CMPHI_PPzZZ_H, CMPHI_PPzZZ_S, CMPHI_WIDE_PPzZZ_B, CMPHI_WIDE_PPzZZ_H, CMPHI_WIDE_PPzZZ_S)>;
-
-// [51] "cmphi $Pd, $Pg/z, $Zn, $imm7";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPHI_PPzZI_B, CMPHI_PPzZI_D, CMPHI_PPzZI_H, CMPHI_PPzZI_S)>;
-
-// [52] "cmphs $Pd, $Pg/z, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPHS_PPzZZ_B, CMPHS_PPzZZ_D, CMPHS_PPzZZ_H, CMPHS_PPzZZ_S, CMPHS_WIDE_PPzZZ_B, CMPHS_WIDE_PPzZZ_H, CMPHS_WIDE_PPzZZ_S)>;
-
-// [53] "cmphs $Pd, $Pg/z, $Zn, $imm7";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPHS_PPzZI_B, CMPHS_PPzZI_D, CMPHS_PPzZI_H, CMPHS_PPzZI_S)>;
-
-// [54] "cmple $Pd, $Pg/z, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPLE_WIDE_PPzZZ_B, CMPLE_WIDE_PPzZZ_H, CMPLE_WIDE_PPzZZ_S)>;
-
-// [55] "cmple $Pd, $Pg/z, $Zn, $imm5";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPLE_PPzZI_B, CMPLE_PPzZI_D, CMPLE_PPzZI_H, CMPLE_PPzZI_S)>;
-
-// [56] "cmplo $Pd, $Pg/z, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPLO_WIDE_PPzZZ_B, CMPLO_WIDE_PPzZZ_H, CMPLO_WIDE_PPzZZ_S)>;
-
-// [57] "cmplo $Pd, $Pg/z, $Zn, $imm7";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPLO_PPzZI_B, CMPLO_PPzZI_D, CMPLO_PPzZI_H, CMPLO_PPzZI_S)>;
-
-// [58] "cmpls $Pd, $Pg/z, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPLS_WIDE_PPzZZ_B, CMPLS_WIDE_PPzZZ_H, CMPLS_WIDE_PPzZZ_S)>;
-
-// [59] "cmpls $Pd, $Pg/z, $Zn, $imm7";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPLS_PPzZI_B, CMPLS_PPzZI_D, CMPLS_PPzZI_H, CMPLS_PPzZI_S)>;
-
-// [60] "cmplt $Pd, $Pg/z, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPLT_WIDE_PPzZZ_B, CMPLT_WIDE_PPzZZ_H, CMPLT_WIDE_PPzZZ_S)>;
-
-// [61] "cmplt $Pd, $Pg/z, $Zn, $imm5";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPLT_PPzZI_B, CMPLT_PPzZI_D, CMPLT_PPzZI_H, CMPLT_PPzZI_S)>;
-
-// [62] "cmpne $Pd, $Pg/z, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPNE_PPzZZ_B, CMPNE_PPzZZ_D, CMPNE_PPzZZ_H, CMPNE_PPzZZ_S, CMPNE_WIDE_PPzZZ_B, CMPNE_WIDE_PPzZZ_H, CMPNE_WIDE_PPzZZ_S)>;
-
-// [63] "cmpne $Pd, $Pg/z, $Zn, $imm5";
-def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPNE_PPzZI_B, CMPNE_PPzZI_D, CMPNE_PPzZI_H, CMPNE_PPzZI_S)>;
-
-// [64] "cnot $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs CNOT_ZPmZ_B, CNOT_ZPmZ_D, CNOT_ZPmZ_H, CNOT_ZPmZ_S)>;
-
-// [65] "cnt $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI3], (instrs CNT_ZPmZ_B, CNT_ZPmZ_D, CNT_ZPmZ_H, CNT_ZPmZ_S)>;
-
-// [66] "cntb $Rd, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs CNTB_XPiI)>;
-
-// [67] "cntd $Rd, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs CNTD_XPiI)>;
-
-// [68] "cnth $Rd, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs CNTH_XPiI)>;
-
-// [69] "cntp $Rd, $Pg, $Pn";
-def : InstRW<[A64FXWrite_6Cyc_GI01], (instrs CNTP_XPP_B, CNTP_XPP_D, CNTP_XPP_H, CNTP_XPP_S)>;
-
-// [70] "cntw $Rd, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs CNTW_XPiI)>;
-
-// [71] "compact $Zd, $Pg, $Zn";
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs COMPACT_ZPZ_D, COMPACT_ZPZ_S)>;
-
-// [72] "cpy $Zd, $Pg/m, $Rn";
-//@@@ def : InstRW<[XXXXXX], (instrs CPY_ZPmR_B, CPY_ZPmR_D, CPY_ZPmR_H, CPY_ZPmR_S)>;
-
-// [73] "cpy $Zd, $Pg/m, $Vn";
-//@@@ def : InstRW<[XXXXXX], (instrs CPY_ZPmV_B, CPY_ZPmV_D, CPY_ZPmV_H, CPY_ZPmV_S)>;
-
-// [74] "cpy $Zd, $Pg/m, $imm";
-//@@@ def : InstRW<[XXXXXX], (instrs CPY_ZPmI_B, CPY_ZPmI_D, CPY_ZPmI_H, CPY_ZPmI_S)>;
-
-// [75] "cpy $Zd, $Pg/z, $imm";
-//@@@ def : InstRW<[XXXXXX], (instrs CPY_ZPzI_B, CPY_ZPzI_D, CPY_ZPzI_H, CPY_ZPzI_S)>;
-
-// [76] "ctermeq $Rn, $Rm";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs CTERMEQ_WW, CTERMEQ_XX)>;
-
-// [77] "ctermne $Rn, $Rm";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs CTERMNE_WW, CTERMNE_XX)>;
-
-// [78] "decb $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs DECB_XPiI)>;
-
-// [79] "decd $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs DECD_XPiI)>;
-
-// [80] "decd $Zdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs DECD_ZPiI)>;
-
-// [81] "dech $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs DECH_XPiI)>;
-
-// [82] "dech $Zdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs DECH_ZPiI)>;
-
-// [83] "decp $Rdn, $Pg";
-def : InstRW<[A64FXWrite_6Cyc_GI124], (instrs DECP_XP_B, DECP_XP_D, DECP_XP_H, DECP_XP_S)>;
-
-// [84] "decp $Zdn, $Pg";
-def : InstRW<[A64FXWrite_12Cyc_GI01], (instrs DECP_ZP_D, DECP_ZP_H, DECP_ZP_S)>;
-
-// [85] "decw $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs DECW_XPiI)>;
-
-// [86] "decw $Zdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs DECW_ZPiI)>;
-
-// [87] "dup $Zd, $Rn";
-def : InstRW<[A64FXWrite_8Cyc_GI01], (instrs DUP_ZR_B, DUP_ZR_D, DUP_ZR_H, DUP_ZR_S)>;
-
-// [88] "dup $Zd, $Zn$idx";
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs DUP_ZZI_B, DUP_ZZI_D, DUP_ZZI_H, DUP_ZZI_Q, DUP_ZZI_S)>;
-
-// [89] "dup $Zd, $imm";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs DUP_ZI_B, DUP_ZI_D, DUP_ZI_H, DUP_ZI_S)>;
-
-// [90] "dupm $Zd, $imms";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs DUPM_ZI)>;
-
-// [91] "eor $Pd, $Pg/z, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs EOR_PPzPP)>;
-
-// [92] "eor $Zd, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs EOR_ZZZ)>;
-
-// [93] "eor $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs EOR_ZPmZ_B, EOR_ZPmZ_D, EOR_ZPmZ_H, EOR_ZPmZ_S)>;
-
-// [94] "eor $Zdn, $_Zdn, $imms13";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs EOR_ZI)>;
-
-// [95] "eors $Pd, $Pg/z, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs EORS_PPzPP)>;
-
-// [96] "eorv $Vd, $Pg, $Zn";
-def : InstRW<[A64FXWrite_14Cyc_GI03], (instrs EORV_VPZ_B, EORV_VPZ_D, EORV_VPZ_H, EORV_VPZ_S)>;
-
-// [97] "ext $Zdn, $_Zdn, $Zm, $imm8";
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs EXT_ZZI)>;
-
-// [99] "fabd $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FABD_ZPmZ_D, FABD_ZPmZ_H, FABD_ZPmZ_S)>;
-
-// [100] "fabs $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FABS_ZPmZ_D, FABS_ZPmZ_H, FABS_ZPmZ_S)>;
-
-// [101] "facge $Pd, $Pg/z, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FACGE_PPzZZ_D, FACGE_PPzZZ_H, FACGE_PPzZZ_S)>;
-
-// [102] "facgt $Pd, $Pg/z, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FACGT_PPzZZ_D, FACGT_PPzZZ_H, FACGT_PPzZZ_S)>;
-
-// [103] "fadd $Zd, $Zn, $Zm"; def is line 1638
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FADD_ZZZ_D, FADD_ZZZ_H, FADD_ZZZ_S)>;
-
-// [104] "fadd $Zdn, $Pg/m, $_Zdn, $Zm"; def is line 1638
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FADD_ZPmZ_D, FADD_ZPmZ_H, FADD_ZPmZ_S)>;
-
-// [105] "fadd $Zdn, $Pg/m, $_Zdn, $i1"; def is line 1638
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FADD_ZPmI_D, FADD_ZPmI_H, FADD_ZPmI_S)>;
-
-// [106] "fadda $Vdn, $Pg, $_Vdn, $Zm";
-def : InstRW<[A64FXWrite_18Cyc_GI03], (instrs FADDA_VPZ_D, FADDA_VPZ_H, FADDA_VPZ_S)>;
-
-// [107] "faddv $Vd, $Pg, $Zn";
-// H : 4 / 6 / ([1,2]9 / [1]6) x 4 / [1,2]9 = 75 cycle
-// S : 4 / 6 / ([1,2]9 / [1]6) x 3 / [1,2]9 = 60 cycle
-// D : 4 / 6 / ([1,2]9 / [1]6) x 2 / [1,2]9 = 45 cycle
-def : InstRW<[A64FXWrite_75Cyc_GI03], (instrs FADDV_VPZ_H)>;
-def : InstRW<[A64FXWrite_60Cyc_GI03], (instrs FADDV_VPZ_S)>;
-def : InstRW<[A64FXWrite_45Cyc_GI03], (instrs FADDV_VPZ_D)>;
-
-// [108] "fcadd $Zdn, $Pg/m, $_Zdn, $Zm, $imm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FCADD_ZPmZ_D, FCADD_ZPmZ_H, FCADD_ZPmZ_S)>;
-
-// [109] "fcmeq $Pd, $Pg/z, $Zn, #0.0";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMEQ_PPzZ0_D, FCMEQ_PPzZ0_H, FCMEQ_PPzZ0_S)>;
-
-// [110] "fcmeq $Pd, $Pg/z, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMEQ_PPzZZ_D, FCMEQ_PPzZZ_H, FCMEQ_PPzZZ_S)>;
-
-// [111] "fcmge $Pd, $Pg/z, $Zn, #0.0";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMGE_PPzZ0_D, FCMGE_PPzZ0_H, FCMGE_PPzZ0_S)>;
-
-// [112] "fcmge $Pd, $Pg/z, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMGE_PPzZZ_D, FCMGE_PPzZZ_H, FCMGE_PPzZZ_S)>;
-
-// [113] "fcmgt $Pd, $Pg/z, $Zn, #0.0";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMGT_PPzZ0_D, FCMGT_PPzZ0_H, FCMGT_PPzZ0_S)>;
-
-// [114] "fcmgt $Pd, $Pg/z, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMGT_PPzZZ_D, FCMGT_PPzZZ_H, FCMGT_PPzZZ_S)>;
-
-// [115] "fcmla $Zda, $Pg/m, $Zn, $Zm, $imm";
-def : InstRW<[A64FXWrite_15Cyc_GI03], (instrs FCMLA_ZPmZZ_D, FCMLA_ZPmZZ_H, FCMLA_ZPmZZ_S)>;
-
-// [116] "fcmla $Zda, $Zn, $Zm$iop, $imm";
-def : InstRW<[A64FXWrite_15Cyc_GI03], (instrs FCMLA_ZZZI_H, FCMLA_ZZZI_S)>;
-
-// [117] "fcmle $Pd, $Pg/z, $Zn, #0.0";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMLE_PPzZ0_D, FCMLE_PPzZ0_H, FCMLE_PPzZ0_S)>;
-
-// [118] "fcmlt $Pd, $Pg/z, $Zn, #0.0";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMLT_PPzZ0_D, FCMLT_PPzZ0_H, FCMLT_PPzZ0_S)>;
-
-// [119] "fcmne $Pd, $Pg/z, $Zn, #0.0";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMNE_PPzZ0_D, FCMNE_PPzZ0_H, FCMNE_PPzZ0_S)>;
-
-// [120] "fcmne $Pd, $Pg/z, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMNE_PPzZZ_D, FCMNE_PPzZZ_H, FCMNE_PPzZZ_S)>;
-
-// [121] "fcmuo $Pd, $Pg/z, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMUO_PPzZZ_D, FCMUO_PPzZZ_H, FCMUO_PPzZZ_S)>;
-
-// [122] "fcpy $Zd, $Pg/m, $imm8";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCPY_ZPmI_D, FCPY_ZPmI_H, FCPY_ZPmI_S)>;
-
-// [123] "fcvt $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FCVT_ZPmZ_DtoH, FCVT_ZPmZ_DtoS, FCVT_ZPmZ_HtoD, FCVT_ZPmZ_HtoS, FCVT_ZPmZ_StoD, FCVT_ZPmZ_StoH)>;
-
-// [124] "fcvtzs $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FCVTZS_ZPmZ_DtoD, FCVTZS_ZPmZ_DtoS, FCVTZS_ZPmZ_HtoD, FCVTZS_ZPmZ_HtoH, FCVTZS_ZPmZ_HtoS, FCVTZS_ZPmZ_StoD, FCVTZS_ZPmZ_StoS)>;
-
-// [125] "fcvtzu $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FCVTZU_ZPmZ_DtoD, FCVTZU_ZPmZ_DtoS, FCVTZU_ZPmZ_HtoD, FCVTZU_ZPmZ_HtoH, FCVTZU_ZPmZ_HtoS, FCVTZU_ZPmZ_StoD, FCVTZU_ZPmZ_StoS)>;
-
-// [126] "fdiv $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_154Cyc_GI0], (instrs FDIV_ZPmZ_D)>;
-def : InstRW<[A64FXWrite_134Cyc_GI0], (instrs FDIV_ZPmZ_H)>;
-def : InstRW<[A64FXWrite_98Cyc_GI0], (instrs FDIV_ZPmZ_S)>;
-
-// [127] "fdivr $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_154Cyc_GI0], (instrs FDIVR_ZPmZ_D)>;
-def : InstRW<[A64FXWrite_134Cyc_GI0], (instrs FDIVR_ZPmZ_H)>;
-def : InstRW<[A64FXWrite_98Cyc_GI0], (instrs FDIVR_ZPmZ_S)>;
-
-// [128] "fdup $Zd, $imm8";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FDUP_ZI_D, FDUP_ZI_H, FDUP_ZI_S)>;
-
-// [129] "fexpa $Zd, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FEXPA_ZZ_D, FEXPA_ZZ_H, FEXPA_ZZ_S)>;
-
-// [130] "fmad $Zdn, $Pg/m, $Zm, $Za";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FMAD_ZPmZZ_D, FMAD_ZPmZZ_H, FMAD_ZPmZZ_S)>;
-
-// [131] "fmax $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FMAX_ZPmZ_D, FMAX_ZPmZ_H, FMAX_ZPmZ_S)>;
-
-// [132] "fmax $Zdn, $Pg/m, $_Zdn, $i1";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FMAX_ZPmI_D, FMAX_ZPmI_H, FMAX_ZPmI_S)>;
-
-// [133] "fmaxnm $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FMAXNM_ZPmZ_D, FMAXNM_ZPmZ_H, FMAXNM_ZPmZ_S)>;
-
-// [134] "fmaxnm $Zdn, $Pg/m, $_Zdn, $i1";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FMAXNM_ZPmI_D, FMAXNM_ZPmI_H, FMAXNM_ZPmI_S)>;
-
-// [135] "fmaxnmv $Vd, $Pg, $Zn";
-def : InstRW<[A64FXWrite_10Cyc_GI03], (instrs FMAXNMV_VPZ_D, FMAXNMV_VPZ_H, FMAXNMV_VPZ_S)>;
-
-// [136] "fmaxv $Vd, $Pg, $Zn";
-def : InstRW<[A64FXWrite_10Cyc_GI03], (instrs FMAXV_VPZ_D, FMAXV_VPZ_H, FMAXV_VPZ_S)>;
-
-// [137] "fmin $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FMIN_ZPmZ_D, FMIN_ZPmZ_H, FMIN_ZPmZ_S)>;
-
-// [138] "fmin $Zdn, $Pg/m, $_Zdn, $i1";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FMIN_ZPmI_D, FMIN_ZPmI_H, FMIN_ZPmI_S)>;
-
-// [139] "fminnm $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FMINNM_ZPmZ_D, FMINNM_ZPmZ_H, FMINNM_ZPmZ_S)>;
-
-// [140] "fminnm $Zdn, $Pg/m, $_Zdn, $i1";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FMINNM_ZPmI_D, FMINNM_ZPmI_H, FMINNM_ZPmI_S)>;
-
-// [141] "fminnmv $Vd, $Pg, $Zn";
-def : InstRW<[A64FXWrite_10Cyc_GI03], (instrs FMINNMV_VPZ_D, FMINNMV_VPZ_H, FMINNMV_VPZ_S)>;
-
-// [142] "fminv $Vd, $Pg, $Zn";
-def : InstRW<[A64FXWrite_10Cyc_GI03], (instrs FMINV_VPZ_D, FMINV_VPZ_H, FMINV_VPZ_S)>;
-
-// [143] "fmla $Zda, $Pg/m, $Zn, $Zm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FMLA_ZPmZZ_D, FMLA_ZPmZZ_H, FMLA_ZPmZZ_S)>;
-
-// [144] "fmla $Zda, $Zn, $Zm$iop";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FMLA_ZZZI_D, FMLA_ZZZI_H, FMLA_ZZZI_S)>;
-
-// [145] "fmls $Zda, $Pg/m, $Zn, $Zm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FMLS_ZPmZZ_D, FMLS_ZPmZZ_H, FMLS_ZPmZZ_S)>;
-
-// [146] "fmls $Zda, $Zn, $Zm$iop";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FMLS_ZZZI_D, FMLS_ZZZI_H, FMLS_ZZZI_S)>;
-
-// [147] "fmsb $Zdn, $Pg/m, $Zm, $Za";
-
-// [148] "fmul $Zd, $Zn, $Zm";
-
-// [149] "fmul $Zd, $Zn, $Zm$iop";
-
-// [150] "fmul $Zdn, $Pg/m, $_Zdn, $Zm";
-
-// [151] "fmul $Zdn, $Pg/m, $_Zdn, $i1";
-
-// [152] "fmulx $Zdn, $Pg/m, $_Zdn, $Zm";
-
-// [153] "fneg $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FNEG_ZPmZ_D, FNEG_ZPmZ_H, FNEG_ZPmZ_S)>;
-
-// [154] "fnmad $Zdn, $Pg/m, $Zm, $Za";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FNMAD_ZPmZZ_D, FNMAD_ZPmZZ_H, FNMAD_ZPmZZ_S)>;
-
-// [155] "fnmla $Zda, $Pg/m, $Zn, $Zm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FNMLA_ZPmZZ_D, FNMLA_ZPmZZ_H, FNMLA_ZPmZZ_S)>;
-
-// [156] "fnmls $Zda, $Pg/m, $Zn, $Zm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FNMLS_ZPmZZ_D, FNMLS_ZPmZZ_H, FNMLS_ZPmZZ_S)>;
-
-// [157] "fnmsb $Zdn, $Pg/m, $Zm, $Za";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FNMSB_ZPmZZ_D, FNMSB_ZPmZZ_H, FNMSB_ZPmZZ_S)>;
-
-// [158] "frecpe $Zd, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FRECPE_ZZ_D, FRECPE_ZZ_H, FRECPE_ZZ_S)>;
-
-// [159] "frecps $Zd, $Zn, $Zm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FRECPS_ZZZ_D, FRECPS_ZZZ_H, FRECPS_ZZZ_S)>;
-
-// [160] "frecpx $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FRECPX_ZPmZ_D, FRECPX_ZPmZ_H, FRECPX_ZPmZ_S)>;
-
-// [161] "frinta $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FRINTA_ZPmZ_D, FRINTA_ZPmZ_H, FRINTA_ZPmZ_S)>;
-
-// [162] "frinti $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FRINTI_ZPmZ_D, FRINTI_ZPmZ_H, FRINTI_ZPmZ_S)>;
-
-// [163] "frintm $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FRINTM_ZPmZ_D, FRINTM_ZPmZ_H, FRINTM_ZPmZ_S)>;
-
-// [164] "frintn $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FRINTN_ZPmZ_D, FRINTN_ZPmZ_H, FRINTN_ZPmZ_S)>;
-
-// [165] "frintp $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FRINTP_ZPmZ_D, FRINTP_ZPmZ_H, FRINTP_ZPmZ_S)>;
-
-// [166] "frintx $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FRINTX_ZPmZ_D, FRINTX_ZPmZ_H, FRINTX_ZPmZ_S)>;
-
-// [167] "frintz $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FRINTZ_ZPmZ_D, FRINTZ_ZPmZ_H, FRINTZ_ZPmZ_S)>;
-
-// [168] "frsqrte $Zd, $Zn";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FRSQRTE_ZZ_D, FRSQRTE_ZZ_H, FRSQRTE_ZZ_S)>;
-
-// [169] "frsqrts $Zd, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FRSQRTS_ZZZ_D, FRSQRTS_ZZZ_H, FRSQRTS_ZZZ_S)>;
-
-// [170] "fscale $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FSCALE_ZPmZ_D, FSCALE_ZPmZ_H, FSCALE_ZPmZ_S)>;
-
-// [171] "fsqrt $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_154Cyc_GI0], (instrs FSQRT_ZPmZ_D)>;
-def : InstRW<[A64FXWrite_134Cyc_GI0], (instrs FSQRT_ZPmZ_H)>;
-def : InstRW<[A64FXWrite_98Cyc_GI0], (instrs FSQRT_ZPmZ_S)>;
-
-// [172] "fsub $Zd, $Zn, $Zm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FSUB_ZZZ_D, FSUB_ZZZ_H, FSUB_ZZZ_S)>;
-
-// [173] "fsub $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FSUB_ZPmZ_D, FSUB_ZPmZ_H, FSUB_ZPmZ_S)>;
-
-// [174] "fsub $Zdn, $Pg/m, $_Zdn, $i1";
-def : InstRW<[A64FXWrite_9Cyc_GI0], (instrs FSUB_ZPmI_D, FSUB_ZPmI_H, FSUB_ZPmI_S)>;
-
-// [175] "fsubr $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FSUBR_ZPmZ_D, FSUBR_ZPmZ_H, FSUBR_ZPmZ_S)>;
-
-// [176] "fsubr $Zdn, $Pg/m, $_Zdn, $i1";
-def : InstRW<[A64FXWrite_9Cyc_GI0], (instrs FSUBR_ZPmI_D, FSUBR_ZPmI_H, FSUBR_ZPmI_S)>;
-
-// [177] "ftmad $Zdn, $_Zdn, $Zm, $imm3";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FTMAD_ZZI_D, FTMAD_ZZI_H, FTMAD_ZZI_S)>;
-
-// [178] "ftsmul $Zd, $Zn, $Zm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FTSMUL_ZZZ_D, FTSMUL_ZZZ_H, FTSMUL_ZZZ_S)>;
-
-// [180] "incb $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs INCB_XPiI)>;
-
-// [181] "incd $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs INCD_XPiI)>;
-
-// [182] "incd $Zdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs INCD_ZPiI)>;
-
-// [183] "inch $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs INCH_XPiI)>;
-
-// [184] "inch $Zdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs INCH_ZPiI)>;
-
-// [185] "incp $Rdn, $Pg";
-def : InstRW<[A64FXWrite_6Cyc_GI124], (instrs INCP_XP_B, INCP_XP_D, INCP_XP_H, INCP_XP_S)>;
-
-// [186] "incp $Zdn, $Pg";
-def : InstRW<[A64FXWrite_12Cyc_GI01], (instrs INCP_ZP_D, INCP_ZP_H, INCP_ZP_S)>;
-
-// [187] "incw $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs INCW_XPiI)>;
-
-// [188] "incw $Zdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs INCW_ZPiI)>;
-
-// [189] "index $Zd, $Rn, $Rm";
-def : InstRW<[A64FXWrite_17Cyc_GI02], (instrs INDEX_RR_B, INDEX_RR_D, INDEX_RR_H, INDEX_RR_S)>;
-
-// [190] "index $Zd, $Rn, $imm5";
-def : InstRW<[A64FXWrite_21Cyc_GI02], (instrs INDEX_RI_B, INDEX_RI_D, INDEX_RI_H, INDEX_RI_S)>;
-
-// [191] "index $Zd, $imm5, $Rm";
-def : InstRW<[A64FXWrite_21Cyc_GI02], (instrs INDEX_IR_B, INDEX_IR_D, INDEX_IR_H, INDEX_IR_S)>;
-
-// [192] "index $Zd, $imm5, $imm5b";
-def : InstRW<[A64FXWrite_13Cyc_GI0], (instrs INDEX_II_B, INDEX_II_D, INDEX_II_H, INDEX_II_S)>;
-
-// [193] "insr $Zdn, $Rm";
-def : InstRW<[A64FXWrite_10Cyc_GI02], (instrs INSR_ZR_B, INSR_ZR_D, INSR_ZR_H, INSR_ZR_S)>;
-
-// [194] "insr $Zdn, $Vm";
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs INSR_ZV_B, INSR_ZV_D, INSR_ZV_H, INSR_ZV_S)>;
-
-// [195] "lasta $Rd, $Pg, $Zn";
-def : InstRW<[A64FXWrite_25Cyc_GI056], (instrs LASTA_RPZ_B, LASTA_RPZ_D, LASTA_RPZ_H, LASTA_RPZ_S)>;
-
-// [196] "lasta $Vd, $Pg, $Zn";
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs LASTA_VPZ_B, LASTA_VPZ_D, LASTA_VPZ_H, LASTA_VPZ_S)>;
-
-// [197] "lastb $Rd, $Pg, $Zn";
-def : InstRW<[A64FXWrite_25Cyc_GI056], (instrs LASTB_RPZ_B, LASTB_RPZ_D, LASTB_RPZ_H, LASTB_RPZ_S)>;
-
-// [198] "lastb $Vd, $Pg, $Zn";
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs LASTB_VPZ_B, LASTB_VPZ_D, LASTB_VPZ_H, LASTB_VPZ_S)>;
-
-// [199] "ld1b $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1B, LD1B_D, LD1B_H, LD1B_S)>;
-
-// [200] "ld1b $Zt, $Pg/z, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLD1B_D_REAL, GLD1B_D_SXTW_REAL, GLD1B_D_UXTW_REAL, GLD1B_S_SXTW_REAL, GLD1B_S_UXTW_REAL)>;
-
-// [201] "ld1b $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1B_D_IMM_REAL, LD1B_H_IMM_REAL, LD1B_IMM_REAL, LD1B_S_IMM_REAL)>;
-
-// [202] "ld1b $Zt, $Pg/z, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLD1B_D_IMM_REAL, GLD1B_S_IMM_REAL)>;
-
-// [203] "ld1d $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1D)>;
-
-// [204] "ld1d $Zt, $Pg/z, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLD1D_REAL, GLD1D_SCALED_REAL, GLD1D_SXTW_REAL, GLD1D_SXTW_SCALED_REAL, GLD1D_UXTW_REAL, GLD1D_UXTW_SCALED_REAL)>;
-
-// [205] "ld1d $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1D_IMM_REAL)>;
-
-// [206] "ld1d $Zt, $Pg/z, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLD1D_IMM_REAL)>;
-
-// [207] "ld1h $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1H, LD1H_D, LD1H_S)>;
-
-// [208] "ld1h $Zt, $Pg/z, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLD1H_D_REAL, GLD1H_D_SCALED_REAL, GLD1H_D_SXTW_REAL, GLD1H_D_SXTW_SCALED_REAL, GLD1H_D_UXTW_REAL, GLD1H_D_UXTW_SCALED_REAL, GLD1H_S_SXTW_REAL, GLD1H_S_SXTW_SCALED_REAL, GLD1H_S_UXTW_REAL, GLD1H_S_UXTW_SCALED_REAL)>;
-
-// [209] "ld1h $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1H_D_IMM_REAL, LD1H_IMM_REAL, LD1H_S_IMM_REAL)>;
-
-// [210] "ld1h $Zt, $Pg/z, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLD1H_D_IMM_REAL, GLD1H_S_IMM_REAL)>;
-
-// [211] "ld1rb $Zt, $Pg/z, [$Rn, $imm6]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RB_D_IMM, LD1RB_H_IMM, LD1RB_IMM, LD1RB_S_IMM)>;
-
-// [212] "ld1rd $Zt, $Pg/z, [$Rn, $imm6]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RD_IMM)>;
-
-// [213] "ld1rh $Zt, $Pg/z, [$Rn, $imm6]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RH_D_IMM, LD1RH_IMM, LD1RH_S_IMM)>;
-
-// [214] "ld1rqb $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RQ_B)>;
-
-// [215] "ld1rqb $Zt, $Pg/z, [$Rn, $imm4]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RQ_B_IMM)>;
-
-// [216] "ld1rqd $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RQ_D)>;
-
-// [217] "ld1rqd $Zt, $Pg/z, [$Rn, $imm4]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RQ_D_IMM)>;
-
-// [218] "ld1rqh $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RQ_H)>;
-
-// [219] "ld1rqh $Zt, $Pg/z, [$Rn, $imm4]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RQ_H_IMM)>;
-
-// [220] "ld1rqw $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RQ_W)>;
-
-// [221] "ld1rqw $Zt, $Pg/z, [$Rn, $imm4]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RQ_W_IMM)>;
-
-// [222] "ld1rsb $Zt, $Pg/z, [$Rn, $imm6]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RSB_D_IMM, LD1RSB_H_IMM, LD1RSB_S_IMM)>;
-
-// [223] "ld1rsh $Zt, $Pg/z, [$Rn, $imm6]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RSH_D_IMM, LD1RSH_S_IMM)>;
-
-// [224] "ld1rsw $Zt, $Pg/z, [$Rn, $imm6]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RSW_IMM)>;
-
-// [225] "ld1rw $Zt, $Pg/z, [$Rn, $imm6]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RW_D_IMM, LD1RW_IMM)>;
-
-// [226] "ld1sb $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1SB_D, LD1SB_H, LD1SB_S)>;
-
-// [227] "ld1sb $Zt, $Pg/z, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLD1SB_D_REAL, GLD1SB_D_SXTW_REAL, GLD1SB_D_UXTW_REAL, GLD1SB_S_SXTW_REAL, GLD1SB_S_UXTW_REAL)>;
-
-// [228] "ld1sb $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1SB_D_IMM_REAL, LD1SB_H_IMM_REAL, LD1SB_S_IMM_REAL)>;
-
-// [229] "ld1sb $Zt, $Pg/z, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLD1SB_D_IMM_REAL, GLD1SB_S_IMM_REAL)>;
-
-// [230] "ld1sh $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1SH_D, LD1SH_S)>;
-
-// [231] "ld1sh $Zt, $Pg/z, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLD1SH_D_REAL, GLD1SH_D_SCALED_REAL, GLD1SH_D_SXTW_REAL, GLD1SH_D_SXTW_SCALED_REAL, GLD1SH_D_UXTW_REAL, GLD1SH_D_UXTW_SCALED_REAL, GLD1SH_S_SXTW_REAL, GLD1SH_S_SXTW_SCALED_REAL, GLD1SH_S_UXTW_REAL, GLD1SH_S_UXTW_SCALED_REAL)>;
-
-// [232] "ld1sh $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1SH_D_IMM_REAL, LD1SH_S_IMM_REAL)>;
-
-// [233] "ld1sh $Zt, $Pg/z, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLD1SH_D_IMM_REAL, GLD1SH_S_IMM_REAL)>;
-
-// [234] "ld1sw $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1SW_D)>;
-
-// [235] "ld1sw $Zt, $Pg/z, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLD1SW_D_REAL, GLD1SW_D_SCALED_REAL, GLD1SW_D_SXTW_REAL, GLD1SW_D_SXTW_SCALED_REAL, GLD1SW_D_UXTW_REAL, GLD1SW_D_UXTW_SCALED_REAL)>;
-
-// [236] "ld1sw $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1SW_D_IMM_REAL)>;
-
-// [237] "ld1sw $Zt, $Pg/z, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLD1SW_D_IMM_REAL)>;
-
-// [238] "ld1w $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1W, LD1W_D)>;
-
-// [239] "ld1w $Zt, $Pg/z, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLD1W_D_REAL, GLD1W_D_SCALED_REAL, GLD1W_D_SXTW_REAL, GLD1W_D_SXTW_SCALED_REAL, GLD1W_D_UXTW_REAL, GLD1W_D_UXTW_SCALED_REAL, GLD1W_SXTW_REAL, GLD1W_SXTW_SCALED_REAL, GLD1W_UXTW_REAL, GLD1W_UXTW_SCALED_REAL)>;
-
-// [240] "ld1w $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1W_D_IMM_REAL, LD1W_IMM_REAL)>;
-
-// [241] "ld1w $Zt, $Pg/z, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLD1W_D_IMM_REAL, GLD1W_IMM_REAL)>;
-
-// [242] "ld2b $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD2B)>;
-
-// [243] "ld2b $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD2B_IMM)>;
-
-// [244] "ld2d $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD2D)>;
-
-// [245] "ld2d $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD2D_IMM)>;
-
-// [246] "ld2h $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD2H)>;
-
-// [247] "ld2h $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD2H_IMM)>;
-
-// [248] "ld2w $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD2W)>;
-
-// [249] "ld2w $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD2W_IMM)>;
-
-// [250] "ld3b $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD3B)>;
-
-// [251] "ld3b $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD3B_IMM)>;
-
-// [252] "ld3d $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD3D)>;
-
-// [253] "ld3d $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD3D_IMM)>;
-
-// [254] "ld3h $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD3H)>;
-
-// [255] "ld3h $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD3H_IMM)>;
-
-// [256] "ld3w $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD3W)>;
-
-// [257] "ld3w $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD3W_IMM)>;
-
-// [258] "ld4b $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD4B)>;
-
-// [259] "ld4b $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD4B_IMM)>;
-
-// [260] "ld4d $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD4D)>;
-
-// [261] "ld4d $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD4D_IMM)>;
-
-// [262] "ld4h $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD4H)>;
-
-// [263] "ld4h $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD4H_IMM)>;
-
-// [264] "ld4w $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD4W)>;
-
-// [265] "ld4w $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD4W_IMM)>;
-
-// [266] "ldff1b $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDFF1B_D_REAL, LDFF1B_H_REAL, LDFF1B_REAL, LDFF1B_S_REAL)>;
-
-// [267] "ldff1b $Zt, $Pg/z, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLDFF1B_D_REAL, GLDFF1B_D_SXTW_REAL, GLDFF1B_D_UXTW_REAL, GLDFF1B_S_SXTW_REAL, GLDFF1B_S_UXTW_REAL)>;
-
-// [268] "ldff1b $Zt, $Pg/z, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLDFF1B_D_IMM_REAL, GLDFF1B_S_IMM_REAL)>;
-
-// [269] "ldff1d $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDFF1D_REAL)>;
-
-// [270] "ldff1d $Zt, $Pg/z, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLDFF1D_REAL, GLDFF1D_SCALED_REAL, GLDFF1D_SXTW_REAL, GLDFF1D_SXTW_SCALED_REAL, GLDFF1D_UXTW_REAL, GLDFF1D_UXTW_SCALED_REAL)>;
-
-// [271] "ldff1d $Zt, $Pg/z, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLDFF1D_IMM_REAL)>;
-
-// [272] "ldff1h $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDFF1H_D_REAL, LDFF1H_REAL, LDFF1H_S_REAL)>;
-
-// [273] "ldff1h $Zt, $Pg/z, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLDFF1H_D_REAL, GLDFF1H_D_SCALED_REAL, GLDFF1H_D_SXTW_REAL, GLDFF1H_D_SXTW_SCALED_REAL, GLDFF1H_D_UXTW_REAL, GLDFF1H_D_UXTW_SCALED_REAL, GLDFF1H_S_SXTW_REAL, GLDFF1H_S_SXTW_SCALED_REAL, GLDFF1H_S_UXTW_REAL, GLDFF1H_S_UXTW_SCALED_REAL)>;
-
-// [274] "ldff1h $Zt, $Pg/z, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLDFF1H_D_IMM_REAL, GLDFF1H_S_IMM_REAL)>;
-
-// [275] "ldff1sb $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDFF1SB_D_REAL, LDFF1SB_H_REAL, LDFF1SB_S_REAL)>;
-
-// [276] "ldff1sb $Zt, $Pg/z, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLDFF1SB_D_REAL, GLDFF1SB_D_SXTW_REAL, GLDFF1SB_D_UXTW_REAL, GLDFF1SB_S_SXTW_REAL, GLDFF1SB_S_UXTW_REAL)>;
-
-// [277] "ldff1sb $Zt, $Pg/z, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLDFF1SB_D_IMM_REAL, GLDFF1SB_S_IMM_REAL)>;
-
-// [278] "ldff1sh $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDFF1SH_D_REAL, LDFF1SH_S_REAL)>;
-
-// [279] "ldff1sh $Zt, $Pg/z, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLDFF1SH_D_REAL, GLDFF1SH_D_SCALED_REAL, GLDFF1SH_D_SXTW_REAL, GLDFF1SH_D_SXTW_SCALED_REAL, GLDFF1SH_D_UXTW_REAL, GLDFF1SH_D_UXTW_SCALED_REAL, GLDFF1SH_S_SXTW_REAL, GLDFF1SH_S_SXTW_SCALED_REAL, GLDFF1SH_S_UXTW_REAL, GLDFF1SH_S_UXTW_SCALED_REAL)>;
-
-// [280] "ldff1sh $Zt, $Pg/z, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLDFF1SH_D_IMM_REAL, GLDFF1SH_S_IMM_REAL)>;
-
-// [281] "ldff1sw $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDFF1SW_D_REAL)>;
-
-// [282] "ldff1sw $Zt, $Pg/z, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLDFF1SW_D_REAL, GLDFF1SW_D_SCALED_REAL, GLDFF1SW_D_SXTW_REAL, GLDFF1SW_D_SXTW_SCALED_REAL, GLDFF1SW_D_UXTW_REAL, GLDFF1SW_D_UXTW_SCALED_REAL)>;
-
-// [283] "ldff1sw $Zt, $Pg/z, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLDFF1SW_D_IMM_REAL)>;
-
-// [284] "ldff1w $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDFF1W_D_REAL, LDFF1W_REAL)>;
-
-// [285] "ldff1w $Zt, $Pg/z, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLDFF1W_D_REAL, GLDFF1W_D_SCALED_REAL, GLDFF1W_D_SXTW_REAL, GLDFF1W_D_SXTW_SCALED_REAL, GLDFF1W_D_UXTW_REAL, GLDFF1W_D_UXTW_SCALED_REAL, GLDFF1W_SXTW_REAL, GLDFF1W_SXTW_SCALED_REAL, GLDFF1W_UXTW_REAL, GLDFF1W_UXTW_SCALED_REAL)>;
-
-// [286] "ldff1w $Zt, $Pg/z, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLDFF1W_D_IMM_REAL, GLDFF1W_IMM_REAL)>;
-
-// [287] "ldnf1b $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNF1B_D_IMM_REAL, LDNF1B_H_IMM_REAL, LDNF1B_IMM_REAL, LDNF1B_S_IMM_REAL)>;
-
-// [288] "ldnf1d $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNF1D_IMM_REAL)>;
-
-// [289] "ldnf1h $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNF1H_D_IMM_REAL, LDNF1H_IMM_REAL, LDNF1H_S_IMM_REAL)>;
-
-// [290] "ldnf1sb $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNF1SB_D_IMM_REAL, LDNF1SB_H_IMM_REAL, LDNF1SB_S_IMM_REAL)>;
-
-// [291] "ldnf1sh $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNF1SH_D_IMM_REAL, LDNF1SH_S_IMM_REAL)>;
-
-// [292] "ldnf1sw $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNF1SW_D_IMM_REAL)>;
-
-// [293] "ldnf1w $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNF1W_D_IMM_REAL, LDNF1W_IMM_REAL)>;
-
-// [294] "ldnt1b $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNT1B_ZRR)>;
-
-// [295] "ldnt1b $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNT1B_ZRI)>;
-
-// [296] "ldnt1d $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNT1D_ZRR)>;
-
-// [297] "ldnt1d $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNT1D_ZRI)>;
-
-// [298] "ldnt1h $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNT1H_ZRR)>;
-
-// [299] "ldnt1h $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNT1H_ZRI)>;
-
-// [300] "ldnt1w $Zt, $Pg/z, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNT1W_ZRR)>;
-
-// [301] "ldnt1w $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNT1W_ZRI)>;
-
-// [302] "ldr $Pt, [$Rn, $imm9, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI5], (instrs LDR_PXI)>;
-
-// [303] "ldr $Zt, [$Rn, $imm9, mul vl]";
-def : InstRW<[A64FXWrite_11Cyc_GI5], (instrs LDR_ZXI)>;
-
-// [304] "lsl $Zd, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSL_WIDE_ZZZ_B, LSL_WIDE_ZZZ_H, LSL_WIDE_ZZZ_S)>;
-
-// [305] "lsl $Zd, $Zn, $imm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSL_ZZI_B, LSL_ZZI_D, LSL_ZZI_H, LSL_ZZI_S)>;
-
-// [306] "lsl $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSL_WIDE_ZPmZ_B, LSL_WIDE_ZPmZ_H, LSL_WIDE_ZPmZ_S, LSL_ZPmZ_B, LSL_ZPmZ_D, LSL_ZPmZ_H, LSL_ZPmZ_S)>;
-
-// [307] "lsl $Zdn, $Pg/m, $_Zdn, $imm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSL_ZPmI_B, LSL_ZPmI_D, LSL_ZPmI_H, LSL_ZPmI_S)>;
-
-// [308] "lslr $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSLR_ZPmZ_B, LSLR_ZPmZ_D, LSLR_ZPmZ_H, LSLR_ZPmZ_S)>;
-
-// [309] "lsr $Zd, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSR_WIDE_ZZZ_B, LSR_WIDE_ZZZ_H, LSR_WIDE_ZZZ_S)>;
-
-// [310] "lsr $Zd, $Zn, $imm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSR_ZZI_B, LSR_ZZI_D, LSR_ZZI_H, LSR_ZZI_S)>;
-
-// [311] "lsr $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSR_WIDE_ZPmZ_B, LSR_WIDE_ZPmZ_H, LSR_WIDE_ZPmZ_S, LSR_ZPmZ_B, LSR_ZPmZ_D, LSR_ZPmZ_H, LSR_ZPmZ_S)>;
-
-// [312] "lsr $Zdn, $Pg/m, $_Zdn, $imm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSR_ZPmI_B, LSR_ZPmI_D, LSR_ZPmI_H, LSR_ZPmI_S)>;
-
-// [313] "lsrr $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSRR_ZPmZ_B, LSRR_ZPmZ_D, LSRR_ZPmZ_H, LSRR_ZPmZ_S)>;
-
-// [314] "mad $Zdn, $Pg/m, $Zm, $Za";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs MAD_ZPmZZ_B, MAD_ZPmZZ_D, MAD_ZPmZZ_H, MAD_ZPmZZ_S)>;
-
-// [315] "mla $Zda, $Pg/m, $Zn, $Zm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs MLA_ZPmZZ_B, MLA_ZPmZZ_D, MLA_ZPmZZ_H, MLA_ZPmZZ_S)>;
-
-// [316] "mls $Zda, $Pg/m, $Zn, $Zm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs MLS_ZPmZZ_B, MLS_ZPmZZ_D, MLS_ZPmZZ_H, MLS_ZPmZZ_S)>;
-
-// [317] "movprfx $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs MOVPRFX_ZPmZ_B, MOVPRFX_ZPmZ_D, MOVPRFX_ZPmZ_H, MOVPRFX_ZPmZ_S)>;
-
-// [318] "movprfx $Zd, $Pg/z, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs MOVPRFX_ZPzZ_B, MOVPRFX_ZPzZ_D, MOVPRFX_ZPzZ_H, MOVPRFX_ZPzZ_S)>;
-
-// [319] "movprfx $Zd, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs MOVPRFX_ZZ)>;
-
-// [320] "msb $Zdn, $Pg/m, $Zm, $Za";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs MSB_ZPmZZ_B, MSB_ZPmZZ_D, MSB_ZPmZZ_H, MSB_ZPmZZ_S)>;
-
-// [321] "mul $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs MUL_ZPmZ_B, MUL_ZPmZ_D, MUL_ZPmZ_H, MUL_ZPmZ_S)>;
-
-// [322] "mul $Zdn, $_Zdn, $imm";
-def : InstRW<[A64FXWrite_9Cyc_GI0], (instrs MUL_ZI_B, MUL_ZI_D, MUL_ZI_H, MUL_ZI_S)>;
-
-// [323] "nand $Pd, $Pg/z, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs NAND_PPzPP)>;
-
-// [324] "nands $Pd, $Pg/z, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs NANDS_PPzPP)>;
-
-// [325] "neg $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs NEG_ZPmZ_B, NEG_ZPmZ_D, NEG_ZPmZ_H, NEG_ZPmZ_S)>;
-
-// [326] "nor $Pd, $Pg/z, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs NOR_PPzPP)>;
-
-// [327] "nors $Pd, $Pg/z, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs NORS_PPzPP)>;
-
-// [328] "not $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs NOT_ZPmZ_B, NOT_ZPmZ_D, NOT_ZPmZ_H, NOT_ZPmZ_S)>;
-
-// [329] "orn $Pd, $Pg/z, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs ORN_PPzPP)>;
-
-// [330] "orns $Pd, $Pg/z, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs ORNS_PPzPP)>;
-
-// [331] "orr $Pd, $Pg/z, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs ORR_PPzPP)>;
-
-// [332] "orr $Zd, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ORR_ZZZ)>;
-
-// [333] "orr $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ORR_ZPmZ_B, ORR_ZPmZ_D, ORR_ZPmZ_H, ORR_ZPmZ_S)>;
-
-// [334] "orr $Zdn, $_Zdn, $imms13";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs ORR_ZI)>;
-
-// [335] "orrs $Pd, $Pg/z, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs ORRS_PPzPP)>;
-
-// [336] "orv $Vd, $Pg, $Zn";
-def : InstRW<[A64FXWrite_14Cyc_GI03], (instrs ORV_VPZ_B, ORV_VPZ_D, ORV_VPZ_H, ORV_VPZ_S)>;
-
-// [337] "pfalse $Pd";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs PFALSE)>;
-
-// [338] "pnext $Pdn, $Pg, $_Pdn";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs PNEXT_B, PNEXT_D, PNEXT_H, PNEXT_S)>;
-
-// [339] "prfb $prfop, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_6Cyc_GI56], (instrs PRFB_PRR)>;
-
-// [340] "prfb $prfop, $Pg, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_14Cyc_GI0256], (instrs PRFB_D_SCALED, PRFB_D_SXTW_SCALED, PRFB_D_UXTW_SCALED, PRFB_S_SXTW_SCALED, PRFB_S_UXTW_SCALED)>;
-
-// [341] "prfb $prfop, $Pg, [$Rn, $imm6, mul vl]";
-def : InstRW<[A64FXWrite_6Cyc_GI56], (instrs PRFB_PRI)>;
-
-// [342] "prfb $prfop, $Pg, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_10Cyc_GI056], (instrs PRFB_D_PZI, PRFB_S_PZI)>;
-
-// [343] "prfd $prfop, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_6Cyc_GI56], (instrs PRFD_PRR)>;
-
-// [344] "prfd $prfop, $Pg, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_14Cyc_GI0256], (instrs PRFD_D_SCALED, PRFD_D_SXTW_SCALED, PRFD_D_UXTW_SCALED, PRFD_S_SXTW_SCALED, PRFD_S_UXTW_SCALED)>;
-
-// [345] "prfd $prfop, $Pg, [$Rn, $imm6, mul vl]";
-def : InstRW<[A64FXWrite_6Cyc_GI56], (instrs PRFD_PRI)>;
-
-// [346] "prfd $prfop, $Pg, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_10Cyc_GI056], (instrs PRFD_D_PZI, PRFD_S_PZI)>;
-
-// [347] "prfh $prfop, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_6Cyc_GI56], (instrs PRFH_PRR)>;
-
-// [348] "prfh $prfop, $Pg, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_14Cyc_GI0256], (instrs PRFH_D_SCALED, PRFH_D_SXTW_SCALED, PRFH_D_UXTW_SCALED, PRFH_S_SXTW_SCALED, PRFH_S_UXTW_SCALED)>;
-
-// [349] "prfh $prfop, $Pg, [$Rn, $imm6, mul vl]";
-def : InstRW<[A64FXWrite_6Cyc_GI56], (instrs PRFH_PRI)>;
-
-// [350] "prfh $prfop, $Pg, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_10Cyc_GI056], (instrs PRFH_D_PZI, PRFH_S_PZI)>;
-
-// [351] "prfw $prfop, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_6Cyc_GI56], (instrs PRFS_PRR)>;
-
-// [352] "prfw $prfop, $Pg, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_14Cyc_GI0256], (instrs PRFW_D_SCALED, PRFW_D_SXTW_SCALED, PRFW_D_UXTW_SCALED, PRFW_S_SXTW_SCALED, PRFW_S_UXTW_SCALED)>;
-
-// [353] "prfw $prfop, $Pg, [$Rn, $imm6, mul vl]";
-def : InstRW<[A64FXWrite_6Cyc_GI56], (instrs PRFW_PRI)>;
-
-// [354] "prfw $prfop, $Pg, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_10Cyc_GI056], (instrs PRFW_D_PZI, PRFW_S_PZI)>;
-
-// [355] "ptest $Pg, $Pn";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs PTEST_PP)>;
-
-// [356] "ptrue $Pd, $pattern";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs PTRUE_B, PTRUE_D, PTRUE_H, PTRUE_S)>;
-
-// [357] "ptrues $Pd, $pattern";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs PTRUES_B, PTRUES_D, PTRUES_H, PTRUES_S)>;
-
-// [358] "punpkhi $Pd, $Pn";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs PUNPKHI_PP)>;
-
-// [359] "punpklo $Pd, $Pn";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs PUNPKLO_PP)>;
-
-// [360] "rbit $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs RBIT_ZPmZ_B, RBIT_ZPmZ_D, RBIT_ZPmZ_H, RBIT_ZPmZ_S)>;
-
-// [361] "rdffr $Pd";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs RDFFR_P)>;
-
-// [362] "rdffr $Pd, $Pg/z";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs RDFFR_PPz)>;
-
-// [363] "rdffrs $Pd, $Pg/z";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs RDFFRS_PPz)>;
-
-// [364] "rdvl $Rd, $imm6";
-def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs RDVLI_XI)>;
-
-// [365] "rev $Pd, $Pn";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs REV_PP_B, REV_PP_D, REV_PP_H, REV_PP_S)>;
-
-// [366] "rev $Zd, $Zn";
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs REV_ZZ_B, REV_ZZ_D, REV_ZZ_H, REV_ZZ_S)>;
-
-// [367] "revb $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs REVB_ZPmZ_D, REVB_ZPmZ_H, REVB_ZPmZ_S)>;
-
-// [368] "revh $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs REVH_ZPmZ_D, REVH_ZPmZ_S)>;
-
-// [369] "revw $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs REVW_ZPmZ_D)>;
-
-// [370] "sabd $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SABD_ZPmZ_B, SABD_ZPmZ_D, SABD_ZPmZ_H, SABD_ZPmZ_S)>;
-
-// [371] "saddv $Vd, $Pg, $Zn";
-def : InstRW<[A64FXWrite_12Cyc_GI03], (instrs SADDV_VPZ_B, SADDV_VPZ_H, SADDV_VPZ_S)>;
-
-// [372] "scvtf $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs SCVTF_ZPmZ_DtoD, SCVTF_ZPmZ_DtoH, SCVTF_ZPmZ_DtoS, SCVTF_ZPmZ_HtoH, SCVTF_ZPmZ_StoD, SCVTF_ZPmZ_StoH, SCVTF_ZPmZ_StoS)>;
-
-// [373] "sdiv $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_37Cyc_GI0], (instrs SDIV_ZPmZ_D, SDIV_ZPmZ_S)>;
-
-// [374] "sdivr $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_37Cyc_GI0], (instrs SDIVR_ZPmZ_D, SDIVR_ZPmZ_S)>;
-
-// [375] "sdot $Zda, $Zn, $Zm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs SDOT_ZZZ_D, SDOT_ZZZ_S)>;
-
-// [376] "sdot $Zda, $Zn, $Zm$iop";
-def : InstRW<[A64FXWrite_15Cyc_NGI03], (instrs SDOT_ZZZI_D, SDOT_ZZZI_S)>;
-
-// [377] "sel $Pd, $Pg, $Pn, $Pm";
-def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs SEL_PPPP)>;
-
-// [378] "sel $Zd, $Pg, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SEL_ZPZZ_B, SEL_ZPZZ_D, SEL_ZPZZ_H, SEL_ZPZZ_S)>;
-
-// [379] "setffr";
-def : InstRW<[A64FXWrite_6Cyc], (instrs SETFFR)>;
-
-// [380] "smax $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SMAX_ZPmZ_B, SMAX_ZPmZ_D, SMAX_ZPmZ_H, SMAX_ZPmZ_S)>;
-
-// [381] "smax $Zdn, $_Zdn, $imm";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs SMAX_ZI_B, SMAX_ZI_D, SMAX_ZI_H, SMAX_ZI_S)>;
-
-// [382] "smaxv $Vd, $Pg, $Zn";
-def : InstRW<[A64FXWrite_14Cyc_GI03], (instrs SMAXV_VPZ_B, SMAXV_VPZ_D, SMAXV_VPZ_H, SMAXV_VPZ_S)>;
-
-// [383] "smin $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SMIN_ZPmZ_B, SMIN_ZPmZ_D, SMIN_ZPmZ_H, SMIN_ZPmZ_S)>;
-
-// [384] "smin $Zdn, $_Zdn, $imm";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs SMIN_ZI_B, SMIN_ZI_D, SMIN_ZI_H, SMIN_ZI_S)>;
-
-// [385] "sminv $Vd, $Pg, $Zn";
-def : InstRW<[A64FXWrite_14Cyc_GI03], (instrs SMINV_VPZ_B, SMINV_VPZ_D, SMINV_VPZ_H, SMINV_VPZ_S)>;
-
-// [386] "smulh $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs SMULH_ZPmZ_B, SMULH_ZPmZ_D, SMULH_ZPmZ_H, SMULH_ZPmZ_S)>;
-
-// [387] "splice $Zdn, $Pg, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs SPLICE_ZPZ_B, SPLICE_ZPZ_D, SPLICE_ZPZ_H, SPLICE_ZPZ_S)>;
-
-// [388] "sqadd $Zd, $Zn, $Zm";
-
-// [389] "sqadd $Zdn, $_Zdn, $imm";
-
-// [390] "sqdecb $Rdn, $_Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQDECB_XPiWdI)>;
-
-// [391] "sqdecb $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQDECB_XPiI)>;
-
-// [392] "sqdecd $Rdn, $_Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQDECD_XPiWdI)>;
-
-// [393] "sqdecd $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQDECD_XPiI)>;
-
-// [394] "sqdecd $Zdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SQDECD_ZPiI)>;
-
-// [395] "sqdech $Rdn, $_Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQDECH_XPiWdI)>;
-
-// [396] "sqdech $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQDECH_XPiI)>;
-
-// [397] "sqdech $Zdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SQDECH_ZPiI)>;
-
-// [398] "sqdecp $Rdn, $Pg";
-def : InstRW<[A64FXWrite_8Cyc_GI124], (instrs SQDECP_XP_B, SQDECP_XP_D, SQDECP_XP_H, SQDECP_XP_S)>;
-
-// [399] "sqdecp $Rdn, $Pg, $_Rdn";
-def : InstRW<[A64FXWrite_8Cyc_GI124], (instrs SQDECP_XPWd_B, SQDECP_XPWd_D, SQDECP_XPWd_H, SQDECP_XPWd_S)>;
-
-// [400] "sqdecp $Zdn, $Pg";
-def : InstRW<[A64FXWrite_12Cyc_GI01], (instrs SQDECP_ZP_D, SQDECP_ZP_H, SQDECP_ZP_S)>;
-
-// [401] "sqdecw $Rdn, $_Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQDECW_XPiWdI)>;
-
-// [402] "sqdecw $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQDECW_XPiI)>;
-
-// [403] "sqdecw $Zdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SQDECW_ZPiI)>;
-
-// [404] "sqincb $Rdn, $_Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQINCB_XPiWdI)>;
-
-// [405] "sqincb $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQINCB_XPiI)>;
-
-// [406] "sqincd $Rdn, $_Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQINCD_XPiWdI)>;
-
-// [407] "sqincd $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQINCD_XPiI)>;
-
-// [408] "sqincd $Zdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SQINCD_ZPiI)>;
-
-// [409] "sqinch $Rdn, $_Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQINCH_XPiWdI)>;
-
-// [410] "sqinch $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQINCH_XPiI)>;
-
-// [411] "sqinch $Zdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SQINCH_ZPiI)>;
-
-// [412] "sqincp $Rdn, $Pg";
-def : InstRW<[A64FXWrite_8Cyc_GI124], (instrs SQINCP_XP_B, SQINCP_XP_D, SQINCP_XP_H, SQINCP_XP_S)>;
-
-// [413] "sqincp $Rdn, $Pg, $_Rdn";
-def : InstRW<[A64FXWrite_8Cyc_GI124], (instrs SQINCP_XPWd_B, SQINCP_XPWd_D, SQINCP_XPWd_H, SQINCP_XPWd_S)>;
-
-// [414] "sqincp $Zdn, $Pg";
-def : InstRW<[A64FXWrite_12Cyc_GI01], (instrs SQINCP_ZP_D, SQINCP_ZP_H, SQINCP_ZP_S)>;
-
-// [415] "sqincw $Rdn, $_Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQINCW_XPiWdI)>;
-
-// [416] "sqincw $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQINCW_XPiI)>;
-
-// [417] "sqincw $Zdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SQINCW_ZPiI)>;
-
-// [418] "sqsub $Zd, $Zn, $Zm";
-
-// [419] "sqsub $Zdn, $_Zdn, $imm";
-
-// [420] "st1b $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST1W_6], (instrs ST1B, ST1B_D, ST1B_H, ST1B_S)>;
-
-// [421] "st1b $Zt, $Pg, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_ST1W_19], (instrs SST1B_D_REAL, SST1B_D_SXTW, SST1B_D_UXTW, SST1B_S_SXTW, SST1B_S_UXTW)>;
-
-// [422] "st1b $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST1W_6], (instrs ST1B_D_IMM, ST1B_H_IMM, ST1B_IMM, ST1B_S_IMM)>;
-
-// [423] "st1b $Zt, $Pg, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_ST1W_15], (instrs SST1B_D_IMM, SST1B_S_IMM)>;
-
-// [424] "st1d $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST1W_6], (instrs ST1D)>;
-
-// [425] "st1d $Zt, $Pg, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_ST1W_19], (instrs SST1D_REAL, SST1D_SCALED_SCALED_REAL, SST1D_SXTW, SST1D_SXTW_SCALED, SST1D_UXTW, SST1D_UXTW_SCALED)>;
-
-// [426] "st1d $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST1W_6], (instrs ST1D_IMM)>;
-
-// [427] "st1d $Zt, $Pg, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_ST1W_15], (instrs SST1D_IMM)>;
-
-// [428] "st1h $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST1W_6], (instrs ST1H, ST1H_D, ST1H_S)>;
-
-// [429] "st1h $Zt, $Pg, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_ST1W_19], (instrs SST1H_D_REAL, SST1H_D_SCALED_SCALED_REAL, SST1H_D_SXTW, SST1H_D_SXTW_SCALED, SST1H_D_UXTW, SST1H_D_UXTW_SCALED, SST1H_S_SXTW, SST1H_S_SXTW_SCALED, SST1H_S_UXTW, SST1H_S_UXTW_SCALED)>;
-
-// [430] "st1h $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST1W_6], (instrs ST1H_D_IMM, ST1H_IMM, ST1H_S_IMM)>;
-
-// [431] "st1h $Zt, $Pg, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_ST1W_15], (instrs SST1H_D_IMM, SST1H_S_IMM)>;
-
-// [432] "st1w $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST1W_6], (instrs ST1W, ST1W_D)>;
-
-// [433] "st1w $Zt, $Pg, [$Rn, $Zm]";
-def : InstRW<[A64FXWrite_ST1W_19], (instrs SST1W_D_REAL, SST1W_D_SCALED_SCALED_REAL, SST1W_D_SXTW, SST1W_D_SXTW_SCALED, SST1W_D_UXTW, SST1W_D_UXTW_SCALED, SST1W_SXTW, SST1W_SXTW_SCALED, SST1W_UXTW, SST1W_UXTW_SCALED)>;
-
-// [434] "st1w $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST1W_6], (instrs ST1W_D_IMM, ST1W_IMM)>;
-
-// [435] "st1w $Zt, $Pg, [$Zn, $imm5]";
-def : InstRW<[A64FXWrite_ST1W_15], (instrs SST1W_D_IMM, SST1W_IMM)>;
-
-// [436] "st2b $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST2W_7], (instrs ST2B)>;
-
-// [437] "st2b $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST2W_7], (instrs ST2B_IMM)>;
-
-// [438] "st2d $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST2W_7], (instrs ST2D)>;
-
-// [439] "st2d $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST2W_7], (instrs ST2D_IMM)>;
-
-// [440] "st2h $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST2W_7], (instrs ST2H)>;
-
-// [441] "st2h $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST2W_7], (instrs ST2H_IMM)>;
-
-// [442] "st2w $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST2W_7], (instrs ST2W)>;
-
-// [443] "st2w $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST2W_7], (instrs ST2W_IMM)>;
-
-// [444] "st3b $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST3W_8], (instrs ST3B)>;
-
-// [445] "st3b $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST3W_8], (instrs ST3B_IMM)>;
-
-// [446] "st3d $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST3W_8], (instrs ST3D)>;
-
-// [447] "st3d $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST3W_8], (instrs ST3D_IMM)>;
-
-// [448] "st3h $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST3W_8], (instrs ST3H)>;
-
-// [449] "st3h $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST3W_8], (instrs ST3H_IMM)>;
-
-// [450] "st3w $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST3W_8], (instrs ST3W)>;
-
-// [451] "st3w $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST3W_8], (instrs ST3W_IMM)>;
-
-// [452] "st4b $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST4W_9], (instrs ST4B)>;
-
-// [453] "st4b $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST4W_9], (instrs ST4B_IMM)>;
-
-// [454] "st4d $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST4W_9], (instrs ST4D)>;
-
-// [455] "st4d $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST4W_9], (instrs ST4D_IMM)>;
-
-// [456] "st4h $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST4W_9], (instrs ST4H)>;
-
-// [457] "st4h $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST4W_9], (instrs ST4H_IMM)>;
-
-// [458] "st4w $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST4W_9], (instrs ST4W)>;
-
-// [459] "st4w $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST4W_9], (instrs ST4W_IMM)>;
-
-// [460] "stnt1b $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST1W_6], (instrs STNT1B_ZRR)>;
-
-// [461] "stnt1b $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST1W_6], (instrs STNT1B_ZRI)>;
-
-// [462] "stnt1d $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST1W_6], (instrs STNT1D_ZRR)>;
-
-// [463] "stnt1d $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST1W_6], (instrs STNT1D_ZRI)>;
-
-// [464] "stnt1h $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST1W_6], (instrs STNT1H_ZRR)>;
-
-// [465] "stnt1h $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST1W_6], (instrs STNT1H_ZRI)>;
-
-// [466] "stnt1w $Zt, $Pg, [$Rn, $Rm]";
-def : InstRW<[A64FXWrite_ST1W_6], (instrs STNT1W_ZRR)>;
-
-// [467] "stnt1w $Zt, $Pg, [$Rn, $imm4, mul vl]";
-def : InstRW<[A64FXWrite_ST1W_6], (instrs STNT1W_ZRI)>;
-
-// [468] "str $Pt, [$Rn, $imm9, mul vl]";
-def : InstRW<[A64FXWrite_6Cyc_GI15], (instrs STR_PXI)>;
-
-// [469] "str $Zt, [$Rn, $imm9, mul vl]";
-def : InstRW<[A64FXWrite_6Cyc_GI05], (instrs STR_ZXI)>;
-
-// [470] "sub $Zd, $Zn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SUB_ZZZ_B, SUB_ZZZ_D, SUB_ZZZ_H, SUB_ZZZ_S)>;
-
-// [471] "sub $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SUB_ZPmZ_B, SUB_ZPmZ_D, SUB_ZPmZ_H, SUB_ZPmZ_S)>;
-
-// [472] "sub $Zdn, $_Zdn, $imm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SUB_ZI_B, SUB_ZI_D, SUB_ZI_H, SUB_ZI_S)>;
-
-// [473] "subr $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SUBR_ZPmZ_B, SUBR_ZPmZ_D, SUBR_ZPmZ_H, SUBR_ZPmZ_S)>;
-
-// [474] "subr $Zdn, $_Zdn, $imm";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs SUBR_ZI_B, SUBR_ZI_D, SUBR_ZI_H, SUBR_ZI_S)>;
-
-// [475] "sunpkhi $Zd, $Zn";
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs SUNPKHI_ZZ_D, SUNPKHI_ZZ_H, SUNPKHI_ZZ_S)>;
-
-// [476] "sunpklo $Zd, $Zn";
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs SUNPKLO_ZZ_D, SUNPKLO_ZZ_H, SUNPKLO_ZZ_S)>;
-
-// [477] "sxtb $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SXTB_ZPmZ_D, SXTB_ZPmZ_H, SXTB_ZPmZ_S)>;
-
-// [478] "sxth $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SXTH_ZPmZ_D, SXTH_ZPmZ_S)>;
-
-// [479] "sxtw $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SXTW_ZPmZ_D)>;
-
-// [480] "tbl $Zd, $Zn, $Zm";
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs TBL_ZZZ_B, TBL_ZZZ_D, TBL_ZZZ_H, TBL_ZZZ_S)>;
-
-// [481] "trn1 $Pd, $Pn, $Pm";
-
-// [482] "trn1 $Zd, $Zn, $Zm";
-
-// [483] "trn2 $Pd, $Pn, $Pm";
-
-// [484] "trn2 $Zd, $Zn, $Zm";
-
-// [486] "uabd $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UABD_ZPmZ_B, UABD_ZPmZ_D, UABD_ZPmZ_H, UABD_ZPmZ_S)>;
-
-// [487] "uaddv $Vd, $Pg, $Zn";
-def : InstRW<[A64FXWrite_12Cyc_GI03], (instrs UADDV_VPZ_B, UADDV_VPZ_D, UADDV_VPZ_H, UADDV_VPZ_S)>;
-
-// [488] "ucvtf $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs UCVTF_ZPmZ_DtoD, UCVTF_ZPmZ_DtoH, UCVTF_ZPmZ_DtoS, UCVTF_ZPmZ_HtoH, UCVTF_ZPmZ_StoD, UCVTF_ZPmZ_StoH, UCVTF_ZPmZ_StoS)>;
-
-// [489] "udiv $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_37Cyc_GI0], (instrs UDIV_ZPmZ_D, UDIV_ZPmZ_S)>;
-
-// [490] "udivr $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_37Cyc_GI0], (instrs UDIVR_ZPmZ_D, UDIVR_ZPmZ_S)>;
-
-// [491] "udot $Zda, $Zn, $Zm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs UDOT_ZZZ_D, UDOT_ZZZ_S)>;
-
-// [492] "udot $Zda, $Zn, $Zm$iop";
-def : InstRW<[A64FXWrite_15Cyc_NGI03], (instrs UDOT_ZZZI_D, UDOT_ZZZI_S)>;
-
-// [493] "umax $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UMAX_ZPmZ_B, UMAX_ZPmZ_D, UMAX_ZPmZ_H, UMAX_ZPmZ_S)>;
-
-// [494] "umax $Zdn, $_Zdn, $imm";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs UMAX_ZI_B, UMAX_ZI_D, UMAX_ZI_H, UMAX_ZI_S)>;
-
-// [495] "umaxv $Vd, $Pg, $Zn";
-def : InstRW<[A64FXWrite_14Cyc_GI03], (instrs UMAXV_VPZ_B, UMAXV_VPZ_D, UMAXV_VPZ_H, UMAXV_VPZ_S)>;
-
-// [496] "umin $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UMIN_ZPmZ_B, UMIN_ZPmZ_D, UMIN_ZPmZ_H, UMIN_ZPmZ_S)>;
-
-// [497] "umin $Zdn, $_Zdn, $imm";
-def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs UMIN_ZI_B, UMIN_ZI_D, UMIN_ZI_H, UMIN_ZI_S)>;
-
-// [498] "uminv $Vd, $Pg, $Zn";
-def : InstRW<[A64FXWrite_14Cyc_GI03], (instrs UMINV_VPZ_B, UMINV_VPZ_D, UMINV_VPZ_H, UMINV_VPZ_S)>;
-
-// [499] "umulh $Zdn, $Pg/m, $_Zdn, $Zm";
-def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs UMULH_ZPmZ_B, UMULH_ZPmZ_D, UMULH_ZPmZ_H, UMULH_ZPmZ_S)>;
-
-// [500] "uqadd $Zd, $Zn, $Zm";
-
-// [501] "uqadd $Zdn, $_Zdn, $imm";
-
-// [502] "uqdecb $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs UQDECB_WPiI, UQDECB_XPiI)>;
-
-// [503] "uqdecd $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs UQDECD_WPiI, UQDECD_XPiI)>;
-
-// [504] "uqdecd $Zdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UQDECD_ZPiI)>;
-
-// [505] "uqdech $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs UQDECH_WPiI, UQDECH_XPiI)>;
-
-// [506] "uqdech $Zdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UQDECH_ZPiI)>;
-
-// [507] "uqdecp $Rdn, $Pg";
-def : InstRW<[A64FXWrite_8Cyc_GI124], (instrs UQDECP_WP_B, UQDECP_WP_D, UQDECP_WP_H, UQDECP_WP_S, UQDECP_XP_B, UQDECP_XP_D, UQDECP_XP_H, UQDECP_XP_S)>;
-
-// [508] "uqdecp $Zdn, $Pg";
-def : InstRW<[A64FXWrite_12Cyc_GI01], (instrs UQDECP_ZP_D, UQDECP_ZP_H, UQDECP_ZP_S)>;
-
-// [509] "uqdecw $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs UQDECW_WPiI, UQDECW_XPiI)>;
-
-// [510] "uqdecw $Zdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UQDECW_ZPiI)>;
-
-// [511] "uqincb $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs UQINCB_WPiI, UQINCB_XPiI)>;
-
-// [512] "uqincd $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs UQINCD_WPiI, UQINCD_XPiI)>;
-
-// [513] "uqincd $Zdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UQINCD_ZPiI)>;
-
-// [514] "uqinch $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs UQINCH_WPiI, UQINCH_XPiI)>;
-
-// [515] "uqinch $Zdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UQINCH_ZPiI)>;
-
-// [516] "uqincp $Rdn, $Pg";
-def : InstRW<[A64FXWrite_8Cyc_GI124], (instrs UQINCP_WP_B, UQINCP_WP_D, UQINCP_WP_H, UQINCP_WP_S, UQINCP_XP_B, UQINCP_XP_D, UQINCP_XP_H, UQINCP_XP_S)>;
-
-// [517] "uqincp $Zdn, $Pg";
-def : InstRW<[A64FXWrite_12Cyc_GI01], (instrs UQINCP_ZP_D, UQINCP_ZP_H, UQINCP_ZP_S)>;
-
-// [518] "uqincw $Rdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs UQINCW_WPiI, UQINCW_XPiI)>;
-
-// [519] "uqincw $Zdn, $pattern, mul $imm4";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UQINCW_ZPiI)>;
-
-// [520] "uqsub $Zd, $Zn, $Zm";
-//@@@ def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UQSUB_ZZZ_B, UQSUB_ZZZ_D, UQSUB_ZZZ_H, UQSUB_ZZZ_S)>;
-
-// [521] "uqsub $Zdn, $_Zdn, $imm";
-//@@@ def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UQSUB_ZI_B, UQSUB_ZI_D, UQSUB_ZI_H, UQSUB_ZI_S)>;
-
-// [522] "uunpkhi $Zd, $Zn";
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs UUNPKHI_ZZ_D, UUNPKHI_ZZ_H, UUNPKHI_ZZ_S)>;
-
-// [523] "uunpklo $Zd, $Zn";
-def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs UUNPKLO_ZZ_D, UUNPKLO_ZZ_H, UUNPKLO_ZZ_S)>;
-
-// [524] "uxtb $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UXTB_ZPmZ_D, UXTB_ZPmZ_H, UXTB_ZPmZ_S)>;
-
-// [525] "uxth $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UXTH_ZPmZ_D, UXTH_ZPmZ_S)>;
-
-// [526] "uxtw $Zd, $Pg/m, $Zn";
-def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UXTW_ZPmZ_D)>;
-
-// [527] "uzp1 $Pd, $Pn, $Pm";
-
-// [528] "uzp1 $Zd, $Zn, $Zm";
-
-// [529] "uzp2 $Pd, $Pn, $Pm";
-
-// [530] "uzp2 $Zd, $Zn, $Zm";
-
-// [531] "whilele $Pd, $Rn, $Rm";
-def : InstRW<[A64FXWrite_4Cyc_GI12], (instrs WHILELE_PWW_B, WHILELE_PWW_D, WHILELE_PWW_H, WHILELE_PWW_S, WHILELE_PXX_B, WHILELE_PXX_D, WHILELE_PXX_H, WHILELE_PXX_S)>;
-
-// [532] "whilelo $Pd, $Rn, $Rm";
-def : InstRW<[A64FXWrite_4Cyc_GI12], (instrs WHILELO_PWW_B, WHILELO_PWW_D, WHILELO_PWW_H, WHILELO_PWW_S, WHILELO_PXX_B, WHILELO_PXX_D, WHILELO_PXX_H, WHILELO_PXX_S)>;
-
-// [533] "whilels $Pd, $Rn, $Rm";
-def : InstRW<[A64FXWrite_4Cyc_GI12], (instrs WHILELS_PWW_B, WHILELS_PWW_D, WHILELS_PWW_H, WHILELS_PWW_S, WHILELS_PXX_B, WHILELS_PXX_D, WHILELS_PXX_H, WHILELS_PXX_S)>;
-
-// [534] "whilelt $Pd, $Rn, $Rm";
-def : InstRW<[A64FXWrite_4Cyc_GI12], (instrs WHILELT_PWW_B, WHILELT_PWW_D, WHILELT_PWW_H, WHILELT_PWW_S, WHILELT_PXX_B, WHILELT_PXX_D, WHILELT_PXX_H, WHILELT_PXX_S)>;
-
-// [535] "wrffr $Pn";
-def : InstRW<[A64FXWrite_6Cyc_NGI1], (instrs WRFFR)>;
-
-// [536] "zip1 $Pd, $Pn, $Pm";
-
-// [537] "zip1 $Zd, $Zn, $Zm";
-
-// [538] "zip2 $Pd, $Pn, $Pm";
-
-// [539] "zip2 $Zd, $Zn, $Zm";
-
-} // SchedModel = A64FXModel
+//=- AArch64SchedA64FX.td - Fujitsu A64FX Scheduling Defs -*- tablegen -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the scheduling model for the Fujitsu A64FX processors.
+//
+//===----------------------------------------------------------------------===//
+
+def A64FXModel : SchedMachineModel {
+ let IssueWidth = 6; // 6 micro-ops dispatched at a time.
+ let MicroOpBufferSize = 180; // 180 entries in micro-op re-order buffer.
+ let LoadLatency = 5; // Optimistic load latency.
+ let MispredictPenalty = 12; // Extra cycles for mispredicted branch.
+ // Determined via a mix of micro-arch details and experimentation.
+ let LoopMicroOpBufferSize = 128;
+ let PostRAScheduler = 1; // Using PostRA sched.
+ let CompleteModel = 1;
+
+ list<Predicate> UnsupportedFeatures =
+ [HasSVE2, HasSVE2AES, HasSVE2SM4, HasSVE2SHA3, HasSVE2BitPerm, HasPAuth];
+
+ let FullInstRWOverlapCheck = 0;
+}
+
+let SchedModel = A64FXModel in {
+
+// Define the issue ports.
+
+// A64FXIP*
+
+// Port 0
+def A64FXIPFLA : ProcResource<1>;
+
+// Port 1
+def A64FXIPPR : ProcResource<1>;
+
+// Port 2
+def A64FXIPEXA : ProcResource<1>;
+
+// Port 3
+def A64FXIPFLB : ProcResource<1>;
+
+// Port 4
+def A64FXIPEXB : ProcResource<1>;
+
+// Port 5
+def A64FXIPEAGA : ProcResource<1>;
+
+// Port 6
+def A64FXIPEAGB : ProcResource<1>;
+
+// Port 7
+def A64FXIPBR : ProcResource<1>;
+
+// Define groups for the functional units on each issue port. Each group
+// created will be used by a WriteRes later on.
+
+def A64FXGI7 : ProcResGroup<[A64FXIPBR]>;
+
+def A64FXGI0 : ProcResGroup<[A64FXIPFLA]>;
+
+def A64FXGI1 : ProcResGroup<[A64FXIPPR]>;
+
+def A64FXGI2 : ProcResGroup<[A64FXIPEXA]>;
+
+def A64FXGI3 : ProcResGroup<[A64FXIPFLB]>;
+
+def A64FXGI4 : ProcResGroup<[A64FXIPEXB]>;
+
+def A64FXGI5 : ProcResGroup<[A64FXIPEAGA]>;
+
+def A64FXGI6 : ProcResGroup<[A64FXIPEAGB]>;
+
+def A64FXGI03 : ProcResGroup<[A64FXIPFLA, A64FXIPFLB]>;
+
+def A64FXGI01 : ProcResGroup<[A64FXIPFLA, A64FXIPPR]>;
+
+def A64FXGI02 : ProcResGroup<[A64FXIPFLA, A64FXIPEXA]>;
+
+def A64FXGI12 : ProcResGroup<[A64FXIPEXA, A64FXIPPR]>;
+
+def A64FXGI15 : ProcResGroup<[A64FXIPEAGA, A64FXIPPR]>;
+
+def A64FXGI05 : ProcResGroup<[A64FXIPFLA, A64FXIPEAGA]>;
+
+def A64FXGI24 : ProcResGroup<[A64FXIPEXA, A64FXIPEXB]>;
+
+def A64FXGI124 : ProcResGroup<[A64FXIPEXA, A64FXIPEXB, A64FXIPPR]>;
+
+def A64FXGI056 : ProcResGroup<[A64FXIPFLA, A64FXIPEAGA, A64FXIPEAGB]>;
+
+def A64FXGI0256 : ProcResGroup<[A64FXIPFLA, A64FXIPEXA, A64FXIPEAGA, A64FXIPEAGB]>;
+
+def A64FXGI56 : ProcResGroup<[A64FXIPEAGA, A64FXIPEAGB]>;
+
+def A64FXGI2456 : ProcResGroup<[A64FXIPEXA, A64FXIPEXB, A64FXIPEAGA, A64FXIPEAGB]>;
+
+def A64FXAny : ProcResGroup<[A64FXIPFLA, A64FXIPPR, A64FXIPEXA, A64FXIPFLB,
+ A64FXIPEXB, A64FXIPEAGA, A64FXIPEAGB, A64FXIPBR]> {
+ let BufferSize = 60;
+}
+
+def A64FXWrite_6Cyc : SchedWriteRes<[]> {
+ let Latency = 6;
+}
+
+def A64FXWrite_1Cyc_GI7 : SchedWriteRes<[A64FXGI7]> {
+ let Latency = 1;
+}
+
+def A64FXWrite_2Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
+ let Latency = 2;
+}
+
+def A64FXWrite_4Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
+ let Latency = 4;
+}
+
+def A64FXWrite_5Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
+ let Latency = 5;
+}
+
+def A64FXWrite_6Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
+ let Latency = 6;
+}
+
+def A64FXWrite_8Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
+ let Latency = 8;
+}
+
+def A64FXWrite_9Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
+ let Latency = 9;
+}
+
+def A64FXWrite_13Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
+ let Latency = 13;
+}
+
+def A64FXWrite_37Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
+ let Latency = 37;
+}
+
+def A64FXWrite_98Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
+ let Latency = 98;
+}
+
+def A64FXWrite_134Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
+ let Latency = 134;
+}
+
+def A64FXWrite_154Cyc_GI0 : SchedWriteRes<[A64FXGI0]> {
+ let Latency = 154;
+}
+
+def A64FXWrite_4Cyc_GI01 : SchedWriteRes<[A64FXGI01]> {
+ let Latency = 4;
+}
+
+def A64FXWrite_6Cyc_GI01 : SchedWriteRes<[A64FXGI01]> {
+ let Latency = 6;
+}
+
+def A64FXWrite_8Cyc_GI01 : SchedWriteRes<[A64FXGI01]> {
+ let Latency = 8;
+}
+
+def A64FXWrite_12Cyc_GI01 : SchedWriteRes<[A64FXGI01]> {
+ let Latency = 12;
+}
+
+def A64FXWrite_10Cyc_GI02 : SchedWriteRes<[A64FXGI02]> {
+ let Latency = 10;
+}
+
+def A64FXWrite_17Cyc_GI02 : SchedWriteRes<[A64FXGI02]> {
+ let Latency = 17;
+}
+
+def A64FXWrite_21Cyc_GI02 : SchedWriteRes<[A64FXGI02]> {
+ let Latency = 21;
+}
+
+def A64FXWrite_3Cyc_GI1 : SchedWriteRes<[A64FXGI1]> {
+ let Latency = 3;
+}
+
+def A64FXWrite_6Cyc_NGI1 : SchedWriteRes<[A64FXGI1]> {
+ let Latency = 3;
+ let NumMicroOps = 2;
+}
+
+def A64FXWrite_4Cyc_GI12 : SchedWriteRes<[A64FXGI12]> {
+ let Latency = 4;
+}
+
+def A64FXWrite_3Cyc_GI2 : SchedWriteRes<[A64FXGI2]> {
+ let Latency = 3;
+}
+
+def A64FXWrite_5Cyc_GI2 : SchedWriteRes<[A64FXGI2]> {
+ let Latency = 5;
+}
+
+def A64FXWrite_6Cyc_GI2 : SchedWriteRes<[A64FXGI2]> {
+ let Latency = 6;
+}
+
+def A64FXWrite_4Cyc_GI3 : SchedWriteRes<[A64FXGI3]> {
+ let Latency = 4;
+}
+
+def A64FXWrite_6Cyc_GI3 : SchedWriteRes<[A64FXGI3]> {
+ let Latency = 6;
+}
+
+def A64FXWrite_6Cyc_GI15 : SchedWriteRes<[A64FXGI15]> {
+ let Latency = 6;
+}
+
+def A64FXWrite_3Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 3;
+}
+
+def A64FXWrite_4Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 4;
+}
+
+def A64FXWrite_6Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 6;
+}
+
+def A64FXWrite_8Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 8;
+}
+
+def A64FXWrite_9Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 9;
+}
+
+def A64FXWrite_10Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 10;
+}
+
+def A64FXWrite_12Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 12;
+}
+
+def A64FXWrite_14Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 14;
+}
+
+def A64FXWrite_15Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 15;
+}
+
+def A64FXWrite_15Cyc_NGI03 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 15;
+ let NumMicroOps = 2;
+}
+
+def A64FXWrite_18Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 18;
+}
+
+def A64FXWrite_45Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 45;
+}
+
+def A64FXWrite_60Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 60;
+}
+
+def A64FXWrite_75Cyc_GI03 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 75;
+}
+
+def A64FXWrite_6Cyc_GI05 : SchedWriteRes<[A64FXGI05]> {
+ let Latency = 6;
+}
+
+def A64FXWrite_10Cyc_GI4 : SchedWriteRes<[A64FXGI4]> {
+ let Latency = 10;
+}
+
+def A64FXWrite_12Cyc_GI4 : SchedWriteRes<[A64FXGI4]> {
+ let Latency = 12;
+}
+
+def A64FXWrite_20Cyc_GI4 : SchedWriteRes<[A64FXGI4]> {
+ let Latency = 20;
+}
+
+def A64FXWrite_5Cyc_GI5 : SchedWriteRes<[A64FXGI5]> {
+ let Latency = 5;
+}
+
+def A64FXWrite_11Cyc_GI5 : SchedWriteRes<[A64FXGI5]> {
+ let Latency = 11;
+}
+
+def A64FXWrite_5Cyc_GI6 : SchedWriteRes<[A64FXGI6]> {
+ let Latency = 5;
+}
+
+def A64FXWrite_1Cyc_GI24 : SchedWriteRes<[A64FXGI24]> {
+ let Latency = 1;
+}
+
+def A64FXWrite_2Cyc_GI24 : SchedWriteRes<[A64FXGI24]> {
+ let Latency = 2;
+}
+
+def A64FXWrite_4Cyc_NGI24 : SchedWriteRes<[A64FXGI24]> {
+ let Latency = 4;
+ let NumMicroOps = 4;
+}
+
+def A64FXWrite_6Cyc_GI124: SchedWriteRes<[A64FXGI124]> {
+ let Latency = 6;
+}
+
+def A64FXWrite_8Cyc_GI124 : SchedWriteRes<[A64FXGI124]> {
+ let Latency = 8;
+ let NumMicroOps = 2;
+}
+
+def A64FXWrite_6Cyc_GI56 : SchedWriteRes<[A64FXGI56]> {
+ let Latency = 0;
+}
+
+def A64FXWrite_1Cyc_GI56 : SchedWriteRes<[A64FXGI56]> {
+ let Latency = 1;
+}
+
+def A64FXWrite_5Cyc_GI56 : SchedWriteRes<[A64FXGI56]> {
+ let Latency = 5;
+}
+
+def A64FXWrite_8Cyc_GI56 : SchedWriteRes<[A64FXGI56]> {
+ let Latency = 8;
+}
+
+def A64FXWrite_11Cyc_GI56 : SchedWriteRes<[A64FXGI56]> {
+ let Latency = 11;
+}
+
+def A64FXWrite_44Cyc_GI56 : SchedWriteRes<[A64FXGI56]> {
+ let Latency = 44;
+}
+
+def A64FXWrite_10Cyc_GI056 : SchedWriteRes<[A64FXGI056]> {
+ let Latency = 10;
+}
+
+def A64FXWrite_15Cyc_GI056 : SchedWriteRes<[A64FXGI056]> {
+ let Latency = 15;
+}
+
+def A64FXWrite_19Cyc_GI056 : SchedWriteRes<[A64FXGI056]> {
+ let Latency = 19;
+}
+
+def A64FXWrite_25Cyc_GI056 : SchedWriteRes<[A64FXGI056]> {
+ let Latency = 25;
+}
+
+def A64FXWrite_14Cyc_GI0256 : SchedWriteRes<[A64FXGI0256]> {
+ let Latency = 14;
+}
+
+def A64FXWrite_19Cyc_GI0256 : SchedWriteRes<[A64FXGI0256]> {
+ let Latency = 19;
+}
+
+def A64FXWrite_29Cyc_GI0256 : SchedWriteRes<[A64FXGI0256]> {
+ let Latency = 29;
+}
+
+def A64FXWrite_LDNP: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 5;
+ let NumMicroOps = 2;
+}
+
+def A64FXWrite_LDP01: SchedWriteRes<[A64FXGI2456]> {
+ let Latency = 5;
+ let NumMicroOps = 3;
+}
+
+def A64FXWrite_LDR01: SchedWriteRes<[A64FXGI2456]> {
+ let Latency = 5;
+ let NumMicroOps = 2;
+}
+
+def A64FXWrite_LD102: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 8;
+ let NumMicroOps = 2;
+}
+
+def A64FXWrite_LD103: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 11;
+ let NumMicroOps = 2;
+
+}
+
+def A64FXWrite_LD104: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 8;
+ let NumMicroOps = 3;
+}
+
+def A64FXWrite_LD105: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 11;
+ let NumMicroOps = 3;
+}
+
+def A64FXWrite_LD106: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 8;
+ let NumMicroOps = 4;
+}
+
+def A64FXWrite_LD107: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 11;
+ let NumMicroOps = 4;
+}
+
+def A64FXWrite_LD108: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 8;
+ let NumMicroOps = 2;
+}
+
+def A64FXWrite_LD109: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 11;
+ let NumMicroOps = 2;
+}
+
+def A64FXWrite_LD110: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 8;
+ let NumMicroOps = 3;
+}
+
+def A64FXWrite_LD111: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 11;
+ let NumMicroOps = 3;
+}
+
+def A64FXWrite_LD112: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 8;
+ let NumMicroOps = 4;
+}
+
+def A64FXWrite_LD113: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 11;
+ let NumMicroOps = 4;
+}
+
+def A64FXWrite_LD114: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 8;
+ let NumMicroOps = 5;
+}
+
+def A64FXWrite_LD115: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 11;
+ let NumMicroOps = 5;
+}
+
+def A64FXWrite_LD1I0: SchedWriteRes<[A64FXGI056]> {
+ let Latency = 8;
+ let NumMicroOps = 2;
+}
+
+def A64FXWrite_LD1I1: SchedWriteRes<[A64FXGI056]> {
+ let Latency = 8;
+ let NumMicroOps = 3;
+}
+
+def A64FXWrite_LD2I0: SchedWriteRes<[A64FXGI056]> {
+ let Latency = 8;
+ let NumMicroOps = 4;
+}
+
+def A64FXWrite_LD2I1: SchedWriteRes<[A64FXGI056]> {
+ let Latency = 8;
+ let NumMicroOps = 5;
+}
+
+def A64FXWrite_LD3I0: SchedWriteRes<[A64FXGI056]> {
+ let Latency = 8;
+ let NumMicroOps = 6;
+}
+
+def A64FXWrite_LD3I1: SchedWriteRes<[A64FXGI056]> {
+ let Latency = 8;
+ let NumMicroOps = 7;
+}
+
+def A64FXWrite_LD4I0: SchedWriteRes<[A64FXGI056]> {
+ let Latency = 8;
+ let NumMicroOps = 8;
+}
+
+def A64FXWrite_LD4I1: SchedWriteRes<[A64FXGI056]> {
+ let Latency = 8;
+ let NumMicroOps = 9;
+}
+
+def A64FXWrite_1Cyc_GI2456 : SchedWriteRes<[A64FXGI2456]> {
+ let Latency = 1;
+}
+
+def A64FXWrite_FMOV_GV : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 10;
+}
+
+def A64FXWrite_FMOV_VG14 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 14;
+}
+
+def A64FXWrite_FMOV_VG : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 25;
+}
+
+def A64FXWrite_ADDLV : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 12;
+}
+
+def A64FXWrite_MULLE : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 14;
+}
+
+def A64FXWrite_MULLV : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 14;
+}
+
+def A64FXWrite_MADDL : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 6;
+}
+
+def A64FXWrite_ABA : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 8;
+}
+
+def A64FXWrite_ABAL : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 10;
+}
+
+def A64FXWrite_ADDLV1 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 12;
+ let NumMicroOps = 6;
+}
+
+def A64FXWrite_MINMAXV : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 14;
+ let NumMicroOps = 6;
+}
+
+def A64FXWrite_SQRDMULH : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 9;
+}
+
+def A64FXWrite_PMUL : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 8;
+}
+
+
+def A64FXWrite_SRSRAV : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 8;
+ let NumMicroOps = 3;
+}
+
+def A64FXWrite_SSRAV : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 8;
+ let NumMicroOps = 2;
+}
+
+def A64FXWrite_RSHRN : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 10;
+ let NumMicroOps = 3;
+}
+
+def A64FXWrite_SHRN : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 10;
+ let NumMicroOps = 2;
+}
+
+
+def A64FXWrite_ADDP : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 10;
+ let NumMicroOps = 3;
+}
+
+def A64FXWrite_FMULXE : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 15;
+ let NumMicroOps = 2;
+}
+
+def A64FXWrite_FADDPV : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 15;
+ let NumMicroOps = 3;
+}
+
+def A64FXWrite_SADALP : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 10;
+ let NumMicroOps = 3;
+}
+
+def A64FXWrite_SADDLP : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 10;
+ let NumMicroOps = 2;
+}
+
+def A64FXWrite_FCVTXNV : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 15;
+ let NumMicroOps = 2;
+}
+
+def A64FXWrite_FMAXVVH : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 14;
+ let NumMicroOps = 7;
+}
+
+def A64FXWrite_FMAXVVS : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 14;
+}
+
+def A64FXWrite_BIF : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 5;
+}
+
+def A64FXWrite_DUPGENERAL : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 10;
+}
+
+def A64FXWrite_SHA00 : SchedWriteRes<[A64FXGI0]> {
+ let Latency = 9;
+}
+
+def A64FXWrite_SHA01 : SchedWriteRes<[A64FXGI0]> {
+ let Latency = 12;
+}
+
+def A64FXWrite_SMOV : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 25;
+}
+
+def A64FXWrite_TBX1 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 10;
+ let NumMicroOps = 3;
+}
+
+def A64FXWrite_TBX2 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 10;
+ let NumMicroOps = 5;
+}
+
+def A64FXWrite_TBX3 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 10;
+ let NumMicroOps = 7;
+}
+
+def A64FXWrite_TBX4 : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 10;
+ let NumMicroOps = 9;
+}
+
+def A64FXWrite_PREF0: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 0;
+}
+
+def A64FXWrite_PREF1: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 0;
+}
+
+def A64FXWrite_SWP: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 0;
+}
+
+def A64FXWrite_STUR: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 0;
+}
+
+def A64FXWrite_STNP: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 0;
+}
+
+def A64FXWrite_STP01: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 0;
+}
+
+def A64FXWrite_ST10: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 0;
+}
+
+def A64FXWrite_ST11: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 0;
+}
+
+def A64FXWrite_ST12: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 0;
+}
+
+def A64FXWrite_ST13: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 0;
+}
+
+def A64FXWrite_ST14: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 1;
+}
+
+def A64FXWrite_ST15: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 1;
+}
+
+def A64FXWrite_ST16: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 1;
+}
+
+def A64FXWrite_ST17: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 1;
+}
+
+def A64FXWrite_ST1W_6: SchedWriteRes<[A64FXGI056]> {
+ let Latency = 6;
+}
+
+def A64FXWrite_ST2W_7: SchedWriteRes<[A64FXGI056]> {
+ let Latency = 7;
+}
+
+def A64FXWrite_ST3W_8: SchedWriteRes<[A64FXGI056]> {
+ let Latency = 8;
+}
+
+def A64FXWrite_ST4W_9: SchedWriteRes<[A64FXGI056]> {
+ let Latency = 9;
+}
+
+def A64FXWrite_ST1W_15: SchedWriteRes<[A64FXGI056]> {
+ let Latency = 15;
+}
+
+def A64FXWrite_ST1W_19: SchedWriteRes<[A64FXGI056]> {
+ let Latency = 19;
+}
+
+def A64FXWrite_CAS: SchedWriteRes<[A64FXGI56]> {
+ let Latency = 7;
+}
+
+// Define commonly used read types.
+
+// No forwarding is provided for these types.
+def : ReadAdvance<ReadI, 0>;
+def : ReadAdvance<ReadISReg, 0>;
+def : ReadAdvance<ReadIEReg, 0>;
+def : ReadAdvance<ReadIM, 0>;
+def : ReadAdvance<ReadIMA, 0>;
+def : ReadAdvance<ReadID, 0>;
+def : ReadAdvance<ReadExtrHi, 0>;
+def : ReadAdvance<ReadAdrBase, 0>;
+def : ReadAdvance<ReadVLD, 0>;
+
+//===----------------------------------------------------------------------===//
+// 3. Instruction Tables.
+
+//---
+// 3.1 Branch Instructions
+//---
+
+// Branch, immed
+// Branch and link, immed
+// Compare and branch
+def : WriteRes<WriteBr, [A64FXGI7]> {
+ let Latency = 1;
+}
+
+// Branch, register
+// Branch and link, register != LR
+// Branch and link, register = LR
+def : WriteRes<WriteBrReg, [A64FXGI7]> {
+ let Latency = 1;
+}
+
+def : WriteRes<WriteSys, []> { let Latency = 1; }
+def : WriteRes<WriteBarrier, []> { let Latency = 1; }
+def : WriteRes<WriteHint, []> { let Latency = 1; }
+
+def : WriteRes<WriteAtomic, []> {
+ let Latency = 4;
+}
+
+//---
+// Branch
+//---
+def : InstRW<[A64FXWrite_1Cyc_GI7], (instrs B, BL, BR, BLR)>;
+def : InstRW<[A64FXWrite_1Cyc_GI7], (instrs RET)>;
+def : InstRW<[A64FXWrite_1Cyc_GI7], (instregex "^B..$")>;
+def : InstRW<[A64FXWrite_1Cyc_GI7],
+ (instregex "^CBZ", "^CBNZ", "^TBZ", "^TBNZ")>;
+
+//---
+// 3.2 Arithmetic and Logical Instructions
+// 3.3 Move and Shift Instructions
+//---
+
+// ALU, basic
+// Conditional compare
+// Conditional select
+// Address generation
+def : WriteRes<WriteI, [A64FXGI2456]> {
+ let Latency = 1;
+ let ResourceCycles = [1];
+}
+
+def : InstRW<[WriteI],
+ (instregex "ADD?(W|X)r(i|r|s|x)", "ADDS?(W|X)r(i|r|s|x)(64)?",
+ "AND?(W|X)r(i|r|s|x)", "ANDS?(W|X)r(i|r|s|x)",
+ "ADC(W|X)r",
+ "BIC?(W|X)r(i|r|s|x)", "BICS?(W|X)r(i|r|s|x)",
+ "EON?(W|X)r(i|r|s|x)", "ORN?(W|X)r(i|r|s|x)",
+ "ORR?(W|X)r(i|r|s|x)", "SUB?(W|X)r(i|r|s|x)",
+ "SUBS?(W|X)r(i|r|s|x)", "SBC(W|X)r",
+ "SBCS(W|X)r", "CCMN(W|X)(i|r)",
+ "CCMP(W|X)(i|r)", "CSEL(W|X)r",
+ "CSINC(W|X)r", "CSINV(W|X)r",
+ "CSNEG(W|X)r")>;
+
+def : InstRW<[WriteI], (instrs COPY)>;
+
+// ALU, extend and/or shift
+def : WriteRes<WriteISReg, [A64FXGI2456]> {
+ let Latency = 2;
+ let ResourceCycles = [1];
+}
+
+def : InstRW<[WriteISReg],
+ (instregex "ADD?(W|X)r(i|r|s|x)", "ADDS?(W|X)r(i|r|s|x)(64)?",
+ "AND?(W|X)r(i|r|s|x)", "ANDS?(W|X)r(i|r|s|x)",
+ "ADC(W|X)r",
+ "BIC?(W|X)r(i|r|s|x)", "BICS?(W|X)r(i|r|s|x)",
+ "EON?(W|X)r(i|r|s|x)", "ORN?(W|X)r(i|r|s|x)",
+ "ORR?(W|X)r(i|r|s|x)", "SUB?(W|X)r(i|r|s|x)",
+ "SUBS?(W|X)r(i|r|s|x)", "SBC(W|X)r",
+ "SBCS(W|X)r", "CCMN(W|X)(i|r)",
+ "CCMP(W|X)(i|r)", "CSEL(W|X)r",
+ "CSINC(W|X)r", "CSINV(W|X)r",
+ "CSNEG(W|X)r")>;
+
+def : WriteRes<WriteIEReg, [A64FXGI2456]> {
+ let Latency = 1;
+ let ResourceCycles = [1];
+}
+
+def : InstRW<[WriteIEReg],
+ (instregex "ADD?(W|X)r(i|r|s|x)", "ADDS?(W|X)r(i|r|s|x)(64)?",
+ "AND?(W|X)r(i|r|s|x)", "ANDS?(W|X)r(i|r|s|x)",
+ "ADC(W|X)r",
+ "BIC?(W|X)r(i|r|s|x)", "BICS?(W|X)r(i|r|s|x)",
+ "EON?(W|X)r(i|r|s|x)", "ORN?(W|X)r(i|r|s|x)",
+ "ORR?(W|X)r(i|r|s|x)", "SUB?(W|X)r(i|r|s|x)",
+ "SUBS?(W|X)r(i|r|s|x)", "SBC(W|X)r",
+ "SBCS(W|X)r", "CCMN(W|X)(i|r)",
+ "CCMP(W|X)(i|r)", "CSEL(W|X)r",
+ "CSINC(W|X)r", "CSINV(W|X)r",
+ "CSNEG(W|X)r")>;
+
+// Move immed
+def : WriteRes<WriteImm, [A64FXGI2456]> {
+ let Latency = 1;
+ let ResourceCycles = [1];
+}
+
+def : InstRW<[A64FXWrite_1Cyc_GI2456],
+ (instrs MOVKWi, MOVKXi, MOVNWi, MOVNXi, MOVZWi, MOVZXi)>;
+
+def : InstRW<[A64FXWrite_2Cyc_GI24],
+ (instrs ASRVWr, ASRVXr, LSLVWr, LSLVXr, RORVWr, RORVXr)>;
+
+// Variable shift
+def : WriteRes<WriteIS, [A64FXGI2456]> {
+ let Latency = 1;
+ let ResourceCycles = [1];
+}
+
+//---
+// 3.4 Divide and Multiply Instructions
+//---
+
+// Divide, W-form
+def : WriteRes<WriteID32, [A64FXGI4]> {
+ let Latency = 39;
+ let ResourceCycles = [39];
+}
+
+// Divide, X-form
+def : WriteRes<WriteID64, [A64FXGI4]> {
+ let Latency = 23;
+ let ResourceCycles = [23];
+}
+
+// Multiply accumulate, W-form
+def : WriteRes<WriteIM32, [A64FXGI2456]> {
+ let Latency = 5;
+ let ResourceCycles = [1];
+}
+
+// Multiply accumulate, X-form
+def : WriteRes<WriteIM64, [A64FXGI2456]> {
+ let Latency = 5;
+ let ResourceCycles = [1];
+}
+
+def : InstRW<[WriteIM32], (instrs MADDWrrr, MSUBWrrr)>;
+def : InstRW<[WriteIM32], (instrs MADDXrrr, MSUBXrrr)>;
+def : InstRW<[A64FXWrite_MADDL],
+ (instregex "(S|U)(MADDL|MSUBL)rrr")>;
+
+def : InstRW<[WriteID32], (instrs SDIVWr, UDIVWr)>;
+def : InstRW<[WriteID64], (instrs SDIVXr, UDIVXr)>;
+
+// Bitfield extract, two reg
+def : WriteRes<WriteExtr, [A64FXGI2456]> {
+ let Latency = 1;
+ let ResourceCycles = [1];
+}
+
+// Multiply high
+def : InstRW<[A64FXWrite_5Cyc_GI2], (instrs SMULHrr, UMULHrr)>;
+
+// Miscellaneous Data-Processing Instructions
+// Bitfield extract
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs EXTRWrri, EXTRXrri)>;
+
+// Bitifield move - basic
+def : InstRW<[A64FXWrite_1Cyc_GI24],
+ (instrs SBFMWri, SBFMXri, UBFMWri, UBFMXri)>;
+
+// Bitfield move, insert
+def : InstRW<[A64FXWrite_4Cyc_NGI24], (instregex "^BFM")>;
+def : InstRW<[A64FXWrite_1Cyc_GI24], (instregex "(S|U)?BFM.*")>;
+
+// Count leading
+def : InstRW<[A64FXWrite_2Cyc_GI0], (instregex "^CLS(W|X)r$",
+ "^CLZ(W|X)r$")>;
+
+// Reverse bits
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs RBITWr, RBITXr)>;
+
+// Cryptography Extensions
+def : InstRW<[A64FXWrite_8Cyc_GI0], (instregex "^AES[DE]")>;
+def : InstRW<[A64FXWrite_8Cyc_GI0], (instregex "^AESI?MC")>;
+def : InstRW<[A64FXWrite_8Cyc_GI0], (instregex "^PMULL")>;
+def : InstRW<[A64FXWrite_SHA00], (instregex "^SHA1SU0")>;
+def : InstRW<[A64FXWrite_8Cyc_GI0], (instregex "^SHA1(H|SU1)")>;
+def : InstRW<[A64FXWrite_SHA01], (instregex "^SHA1[CMP]")>;
+def : InstRW<[A64FXWrite_8Cyc_GI0], (instregex "^SHA256SU0")>;
+def : InstRW<[A64FXWrite_8Cyc_GI0], (instregex "^SHA256SU1")>;
+def : InstRW<[A64FXWrite_SHA01], (instregex "^SHA256(H|H2)")>;
+
+// CRC Instructions
+def : InstRW<[A64FXWrite_10Cyc_GI4], (instrs CRC32Brr, CRC32Hrr)>;
+def : InstRW<[A64FXWrite_12Cyc_GI4], (instrs CRC32Wrr)>;
+def : InstRW<[A64FXWrite_20Cyc_GI4], (instrs CRC32Xrr)>;
+
+def : InstRW<[A64FXWrite_10Cyc_GI4], (instrs CRC32CBrr, CRC32CHrr)>;
+def : InstRW<[A64FXWrite_12Cyc_GI4], (instrs CRC32CWrr)>;
+def : InstRW<[A64FXWrite_20Cyc_GI4], (instrs CRC32CXrr)>;
+
+// Reverse bits/bytes
+// NOTE: Handled by WriteI.
+
+//---
+// 3.6 Load Instructions
+// 3.10 FP Load Instructions
+//---
+
+// Load register, literal
+// Load register, unscaled immed
+// Load register, immed unprivileged
+// Load register, unsigned immed
+def : WriteRes<WriteLD, [A64FXGI56]> {
+ let Latency = 4;
+ let ResourceCycles = [3];
+}
+
+// Load register, immed post-index
+// NOTE: Handled by WriteLD, WriteI.
+// Load register, immed pre-index
+// NOTE: Handled by WriteLD, WriteAdr.
+def : WriteRes<WriteAdr, [A64FXGI2456]> {
+ let Latency = 1;
+ let ResourceCycles = [1];
+}
+
+// Load pair, immed offset, normal
+// Load pair, immed offset, signed words, base != SP
+// Load pair, immed offset signed words, base = SP
+// LDP only breaks into *one* LS micro-op. Thus
+// the resources are handled by WriteLD.
+def : WriteRes<WriteLDHi, []> {
+ let Latency = 5;
+}
+
+// Load register offset, basic
+// Load register, register offset, scale by 4/8
+// Load register, register offset, scale by 2
+// Load register offset, extend
+// Load register, register offset, extend, scale by 4/8
+// Load register, register offset, extend, scale by 2
+def A64FXWriteLDIdx : SchedWriteVariant<[
+ SchedVar<ScaledIdxPred, [A64FXWrite_1Cyc_GI56]>,
+ SchedVar<NoSchedPred, [A64FXWrite_1Cyc_GI56]>]>;
+def : SchedAlias<WriteLDIdx, A64FXWriteLDIdx>;
+
+def A64FXReadAdrBase : SchedReadVariant<[
+ SchedVar<ScaledIdxPred, [ReadDefault]>,
+ SchedVar<NoSchedPred, [ReadDefault]>]>;
+def : SchedAlias<ReadAdrBase, A64FXReadAdrBase>;
+
+// Load pair, immed pre-index, normal
+// Load pair, immed pre-index, signed words
+// Load pair, immed post-index, normal
+// Load pair, immed post-index, signed words
+// NOTE: Handled by WriteLD, WriteLDHi, WriteAdr.
+
+def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDNPDi)>;
+def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDNPQi)>;
+def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDNPSi)>;
+def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDNPWi)>;
+def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDNPXi)>;
+
+def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDPDi)>;
+def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDPQi)>;
+def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDPSi)>;
+def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDPSWi)>;
+def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDPWi)>;
+def : InstRW<[A64FXWrite_LDNP, WriteLDHi], (instrs LDPXi)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDRBui)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDRDui)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDRHui)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDRQui)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDRSui)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI6], (instrs LDRDl)>;
+def : InstRW<[A64FXWrite_5Cyc_GI6], (instrs LDRQl)>;
+def : InstRW<[A64FXWrite_5Cyc_GI6], (instrs LDRWl)>;
+def : InstRW<[A64FXWrite_5Cyc_GI6], (instrs LDRXl)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDTRBi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDTRHi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDTRWi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDTRXi)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDTRSBWi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDTRSBXi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDTRSHWi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDTRSHXi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDTRSWi)>;
+
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPDpre)>;
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPQpre)>;
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPSpre)>;
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPWpre)>;
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPWpre)>;
+
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRBpre)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRDpre)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRHpre)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRQpre)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSpre)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRWpre)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRXpre)>;
+
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSBWpre)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSBXpre)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSBWpost)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSBXpost)>;
+
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSHWpre)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSHXpre)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSHWpost)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSHXpost)>;
+
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRBBpre)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRBBpost)>;
+
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRHHpre)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRHHpost)>;
+
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPDpost)>;
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPQpost)>;
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPSpost)>;
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPWpost)>;
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPXpost)>;
+
+def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRBpost)>;
+def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRDpost)>;
+def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRHpost)>;
+def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRQpost)>;
+def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRSpost)>;
+def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRWpost)>;
+def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRXpost)>;
+
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPDpre)>;
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPQpre)>;
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPSpre)>;
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPWpre)>;
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPXpre)>;
+
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRBpre)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRDpre)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRHpre)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRQpre)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRSpre)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRWpre)>;
+def : InstRW<[A64FXWrite_LDR01, WriteAdr], (instrs LDRXpre)>;
+
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPDpost)>;
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPQpost)>;
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPSpost)>;
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPWpost)>;
+def : InstRW<[A64FXWrite_LDP01, WriteLDHi, WriteAdr],
+ (instrs LDPXpost)>;
+
+def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRBpost)>;
+def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRDpost)>;
+def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRHpost)>;
+def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRQpost)>;
+def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRSpost)>;
+def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRWpost)>;
+def : InstRW<[A64FXWrite_LDR01, WriteI], (instrs LDRXpost)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRBroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRDroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRHroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRHHroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRQroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRSroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRSHWroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRSHXroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRWroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRXroW)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRBroX)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRDroX)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRHHroX)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRHroX)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRQroX)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRSroX)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRSHWroX)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRSHXroX)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRWroX)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase], (instrs LDRXroX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRBroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRBroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRDroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRHroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRHHroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRQroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRSroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRSHWroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRSHXroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRWroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRXroW)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRBroX)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRDroX)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRHroX)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRHHroX)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRQroX)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRSroX)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRSHWroX)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRSHXroX)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRWroX)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56, ReadAdrBase],
+ (instrs LDRXroX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURBi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURBBi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURDi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURHi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURHHi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURQi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURSi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURXi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURSBWi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURSBXi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURSHWi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURSHXi)>;
+def : InstRW<[A64FXWrite_5Cyc_GI56], (instrs LDURSWi)>;
+
+//---
+// Prefetch
+//---
+def : InstRW<[A64FXWrite_PREF0], (instrs PRFMl)>;
+def : InstRW<[A64FXWrite_PREF1], (instrs PRFUMi)>;
+def : InstRW<[A64FXWrite_PREF1], (instrs PRFMui)>;
+def : InstRW<[A64FXWrite_PREF1], (instrs PRFMroW)>;
+def : InstRW<[A64FXWrite_PREF1], (instrs PRFMroX)>;
+
+//--
+// 3.7 Store Instructions
+// 3.11 FP Store Instructions
+//--
+
+// Store register, unscaled immed
+// Store register, immed unprivileged
+// Store register, unsigned immed
+def : WriteRes<WriteST, [A64FXGI56]> {
+ let Latency = 1;
+}
+
+// Store register, immed post-index
+// NOTE: Handled by WriteAdr, WriteST, ReadAdrBase
+
+// Store register, immed pre-index
+// NOTE: Handled by WriteAdr, WriteST
+
+// Store register, register offset, basic
+// Store register, register offset, scaled by 4/8
+// Store register, register offset, scaled by 2
+// Store register, register offset, extend
+// Store register, register offset, extend, scale by 4/8
+// Store register, register offset, extend, scale by 1
+def : WriteRes<WriteSTIdx, [A64FXGI56, A64FXGI2456]> {
+ let Latency = 1;
+}
+
+// Store pair, immed offset, W-form
+// Store pair, immed offset, X-form
+def : WriteRes<WriteSTP, [A64FXGI56]> {
+ let Latency = 1;
+}
+
+// Store pair, immed post-index, W-form
+// Store pair, immed post-index, X-form
+// Store pair, immed pre-index, W-form
+// Store pair, immed pre-index, X-form
+// NOTE: Handled by WriteAdr, WriteSTP.
+
+def : InstRW<[A64FXWrite_STUR], (instrs STURBi)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STURBBi)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STURDi)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STURHi)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STURHHi)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STURQi)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STURSi)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STURWi)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STURXi)>;
+
+def : InstRW<[WriteAdr, A64FXWrite_STUR], (instrs STTRBi)>;
+def : InstRW<[WriteAdr, A64FXWrite_STUR], (instrs STTRHi)>;
+def : InstRW<[WriteAdr, A64FXWrite_STUR], (instrs STTRWi)>;
+def : InstRW<[WriteAdr, A64FXWrite_STUR], (instrs STTRXi)>;
+
+def : InstRW<[A64FXWrite_STNP], (instrs STNPDi)>;
+def : InstRW<[A64FXWrite_STNP], (instrs STNPQi)>;
+def : InstRW<[A64FXWrite_STNP], (instrs STNPXi)>;
+def : InstRW<[A64FXWrite_STNP], (instrs STNPWi)>;
+
+def : InstRW<[A64FXWrite_STNP], (instrs STPDi)>;
+def : InstRW<[A64FXWrite_STNP], (instrs STPQi)>;
+def : InstRW<[A64FXWrite_STNP], (instrs STPXi)>;
+def : InstRW<[A64FXWrite_STNP], (instrs STPWi)>;
+
+def : InstRW<[A64FXWrite_STUR], (instrs STRBui)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STRBui)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STRDui)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STRDui)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STRHui)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STRHui)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STRQui)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STRQui)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STRXui)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STRXui)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STRWui)>;
+def : InstRW<[A64FXWrite_STUR], (instrs STRWui)>;
+
+def : InstRW<[A64FXWrite_STP01],
+ (instrs STPDpre, STPDpost)>;
+def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
+ (instrs STPDpre, STPDpost)>;
+def : InstRW<[A64FXWrite_STP01],
+ (instrs STPDpre, STPDpost)>;
+def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
+ (instrs STPDpre, STPDpost)>;
+def : InstRW<[A64FXWrite_STP01],
+ (instrs STPQpre, STPQpost)>;
+def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
+ (instrs STPQpre, STPQpost)>;
+def : InstRW<[A64FXWrite_STP01],
+ (instrs STPQpre, STPQpost)>;
+def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
+ (instrs STPQpre, STPQpost)>;
+def : InstRW<[A64FXWrite_STP01],
+ (instrs STPSpre, STPSpost)>;
+def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
+ (instrs STPSpre, STPSpost)>;
+def : InstRW<[A64FXWrite_STP01],
+ (instrs STPSpre, STPSpost)>;
+def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
+ (instrs STPSpre, STPSpost)>;
+def : InstRW<[A64FXWrite_STP01],
+ (instrs STPWpre, STPWpost)>;
+def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
+ (instrs STPWpre, STPWpost)>;
+def : InstRW<[A64FXWrite_STP01],
+ (instrs STPWpre, STPWpost)>;
+def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
+ (instrs STPWpre, STPWpost)>;
+def : InstRW<[A64FXWrite_STP01],
+ (instrs STPXpre, STPXpost)>;
+def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
+ (instrs STPXpre, STPXpost)>;
+def : InstRW<[A64FXWrite_STP01],
+ (instrs STPXpre, STPXpost)>;
+def : InstRW<[A64FXWrite_STP01, ReadAdrBase],
+ (instrs STPXpre, STPXpost)>;
+
+def : InstRW<[WriteAdr, A64FXWrite_STP01],
+ (instrs STRBpre, STRBpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
+ (instrs STRBpre, STRBpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01],
+ (instrs STRBpre, STRBpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
+ (instrs STRBpre, STRBpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01],
+ (instrs STRBBpre, STRBBpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
+ (instrs STRBBpre, STRBBpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01],
+ (instrs STRBBpre, STRBBpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
+ (instrs STRBBpre, STRBBpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01],
+ (instrs STRDpre, STRDpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
+ (instrs STRDpre, STRDpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01],
+ (instrs STRDpre, STRDpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
+ (instrs STRDpre, STRDpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01],
+ (instrs STRHpre, STRHpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
+ (instrs STRHpre, STRHpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01],
+ (instrs STRHpre, STRHpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
+ (instrs STRHpre, STRHpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01],
+ (instrs STRHHpre, STRHHpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
+ (instrs STRHHpre, STRHHpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01],
+ (instrs STRHHpre, STRHHpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
+ (instrs STRHHpre, STRHHpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01],
+ (instrs STRQpre, STRQpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
+ (instrs STRQpre, STRQpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01],
+ (instrs STRQpre, STRQpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
+ (instrs STRQpre, STRQpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01],
+ (instrs STRSpre, STRSpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
+ (instrs STRSpre, STRSpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01],
+ (instrs STRSpre, STRSpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
+ (instrs STRSpre, STRSpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01],
+ (instrs STRWpre, STRWpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
+ (instrs STRWpre, STRWpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01],
+ (instrs STRWpre, STRWpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
+ (instrs STRWpre, STRWpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01],
+ (instrs STRXpre, STRXpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
+ (instrs STRXpre, STRXpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01],
+ (instrs STRXpre, STRXpost)>;
+def : InstRW<[WriteAdr, A64FXWrite_STP01, ReadAdrBase],
+ (instrs STRXpre, STRXpost)>;
+
+def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
+ (instrs STRBroW, STRBroX)>;
+def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
+ (instrs STRBroW, STRBroX)>;
+def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
+ (instrs STRBBroW, STRBBroX)>;
+def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
+ (instrs STRBBroW, STRBBroX)>;
+def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
+ (instrs STRDroW, STRDroX)>;
+def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
+ (instrs STRDroW, STRDroX)>;
+def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
+ (instrs STRHroW, STRHroX)>;
+def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
+ (instrs STRHroW, STRHroX)>;
+def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
+ (instrs STRHHroW, STRHHroX)>;
+def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
+ (instrs STRHHroW, STRHHroX)>;
+def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
+ (instrs STRQroW, STRQroX)>;
+def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
+ (instrs STRQroW, STRQroX)>;
+def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
+ (instrs STRSroW, STRSroX)>;
+def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
+ (instrs STRSroW, STRSroX)>;
+def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
+ (instrs STRWroW, STRWroX)>;
+def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
+ (instrs STRWroW, STRWroX)>;
+def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
+ (instrs STRXroW, STRXroX)>;
+def : InstRW<[A64FXWrite_STUR, ReadAdrBase],
+ (instrs STRXroW, STRXroX)>;
+
+//---
+// 3.8 FP Data Processing Instructions
+//---
+
+// FP absolute value
+// FP min/max
+// FP negate
+def : WriteRes<WriteF, [A64FXGI03]> {
+ let Latency = 4;
+ let ResourceCycles = [2];
+}
+
+// FP arithmetic
+
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FADDDrr, FADDHrr)>;
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FSUBDrr, FSUBHrr)>;
+
+// FP compare
+def : WriteRes<WriteFCmp, [A64FXGI03]> {
+ let Latency = 4;
+ let ResourceCycles = [2];
+}
+
+// FP Div, Sqrt
+def : WriteRes<WriteFDiv, [A64FXGI0]> {
+ let Latency = 43;
+}
+
+def A64FXXWriteFDiv : SchedWriteRes<[A64FXGI0]> {
+ let Latency = 38;
+}
+
+def A64FXXWriteFDivSP : SchedWriteRes<[A64FXGI0]> {
+ let Latency = 29;
+}
+
+def A64FXXWriteFDivDP : SchedWriteRes<[A64FXGI0]> {
+ let Latency = 43;
+}
+
+def A64FXXWriteFSqrtSP : SchedWriteRes<[A64FXGI0]> {
+ let Latency = 29;
+}
+
+def A64FXXWriteFSqrtDP : SchedWriteRes<[A64FXGI0]> {
+ let Latency = 43;
+}
+
+// FP divide, S-form
+// FP square root, S-form
+def : InstRW<[A64FXXWriteFDivSP], (instrs FDIVSrr)>;
+def : InstRW<[A64FXXWriteFSqrtSP], (instrs FSQRTSr)>;
+def : InstRW<[A64FXXWriteFDivSP], (instregex "^FDIVv.*32$")>;
+def : InstRW<[A64FXXWriteFSqrtSP], (instregex "^.*SQRT.*32$")>;
+def : InstRW<[A64FXXWriteFDivSP], (instregex "^FDIVSrr")>;
+def : InstRW<[A64FXXWriteFSqrtSP], (instregex "^FSQRTSr")>;
+
+// FP divide, D-form
+// FP square root, D-form
+def : InstRW<[A64FXXWriteFDivDP], (instrs FDIVDrr)>;
+def : InstRW<[A64FXXWriteFSqrtDP], (instrs FSQRTDr)>;
+def : InstRW<[A64FXXWriteFDivDP], (instregex "^FDIVv.*64$")>;
+def : InstRW<[A64FXXWriteFSqrtDP], (instregex "^.*SQRT.*64$")>;
+def : InstRW<[A64FXXWriteFDivDP], (instregex "^FDIVDrr")>;
+def : InstRW<[A64FXXWriteFSqrtDP], (instregex "^FSQRTDr")>;
+
+// FP multiply
+// FP multiply accumulate
+def : WriteRes<WriteFMul, [A64FXGI03]> {
+ let Latency = 9;
+ let ResourceCycles = [2];
+}
+
+def A64FXXWriteFMul : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 9;
+ let ResourceCycles = [2];
+}
+
+def A64FXXWriteFMulAcc : SchedWriteRes<[A64FXGI03]> {
+ let Latency = 9;
+ let ResourceCycles = [2];
+}
+
+def : InstRW<[A64FXXWriteFMul], (instregex "^FMUL", "^FNMUL")>;
+def : InstRW<[A64FXXWriteFMulAcc],
+ (instregex "^FMADD", "^FMSUB", "^FNMADD", "^FNMSUB")>;
+
+// FP round to integral
+def : InstRW<[A64FXWrite_9Cyc_GI03],
+ (instregex "^FRINT(A|I|M|N|P|X|Z)(Sr|Dr)")>;
+
+// FP select
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instregex "^FCSEL")>;
+
+//---
+// 3.9 FP Miscellaneous Instructions
+//---
+
+// FP convert, from vec to vec reg
+// FP convert, from gen to vec reg
+// FP convert, from vec to gen reg
+def : WriteRes<WriteFCvt, [A64FXGI03]> {
+ let Latency = 9;
+ let ResourceCycles = [2];
+}
+
+// FP move, immed
+// FP move, register
+def : WriteRes<WriteFImm, [A64FXGI0]> {
+ let Latency = 4;
+ let ResourceCycles = [2];
+}
+
+// FP transfer, from gen to vec reg
+// FP transfer, from vec to gen reg
+def : WriteRes<WriteFCopy, [A64FXGI0]> {
+ let Latency = 4;
+ let ResourceCycles = [2];
+}
+
+def : InstRW<[A64FXWrite_FMOV_GV], (instrs FMOVXDHighr)>;
+def : InstRW<[A64FXWrite_FMOV_VG14], (instrs FMOVDXHighr)>;
+
+//---
+// 3.12 ASIMD Integer Instructions
+//---
+
+// ASIMD absolute diff, D-form
+// ASIMD absolute diff, Q-form
+// ASIMD absolute diff accum, D-form
+// ASIMD absolute diff accum, Q-form
+// ASIMD absolute diff accum long
+// ASIMD absolute diff long
+// ASIMD arith, basic
+// ASIMD arith, complex
+// ASIMD compare
+// ASIMD logical (AND, BIC, EOR)
+// ASIMD max/min, basic
+// ASIMD max/min, reduce, 4H/4S
+// ASIMD max/min, reduce, 8B/8H
+// ASIMD max/min, reduce, 16B
+// ASIMD multiply, D-form
+// ASIMD multiply, Q-form
+// ASIMD multiply accumulate long
+// ASIMD multiply accumulate saturating long
+// ASIMD multiply long
+// ASIMD pairwise add and accumulate
+// ASIMD shift accumulate
+// ASIMD shift by immed, basic
+// ASIMD shift by immed and insert, basic, D-form
+// ASIMD shift by immed and insert, basic, Q-form
+// ASIMD shift by immed, complex
+// ASIMD shift by register, basic, D-form
+// ASIMD shift by register, basic, Q-form
+// ASIMD shift by register, complex, D-form
+// ASIMD shift by register, complex, Q-form
+def : WriteRes<WriteV, [A64FXGI03]> {
+ let Latency = 4;
+ let ResourceCycles = [1];
+}
+
+// ASIMD arith, reduce, 4H/4S
+// ASIMD arith, reduce, 8B/8H
+// ASIMD arith, reduce, 16B
+
+// ASIMD logical (MVN (alias for NOT), ORN, ORR)
+def : InstRW<[A64FXWrite_4Cyc_GI03],
+ (instregex "^ANDv", "^BICv", "^EORv", "^ORRv", "^ORNv", "^NOTv")>;
+
+// ASIMD arith, reduce
+def : InstRW<[A64FXWrite_ADDLV],
+ (instregex "^ADDVv", "^SADDLVv", "^UADDLVv")>;
+
+// ASIMD polynomial (8x8) multiply long
+def : InstRW<[A64FXWrite_MULLE], (instregex "^(S|U|SQD)MULL")>;
+def : InstRW<[A64FXWrite_MULLV],
+ (instregex "(S|U|SQD)(MLAL|MLSL|MULL)v.*")>;
+def : InstRW<[A64FXWrite_8Cyc_GI03], (instregex "^PMULL(v8i8|v16i8)")>;
+def : InstRW<[A64FXWrite_8Cyc_GI03], (instregex "^PMULL(v1i64|v2i64)")>;
+
+// ASIMD absolute diff accum, D-form
+def : InstRW<[A64FXWrite_ABA],
+ (instregex "^[SU]ABA(v8i8|v4i16|v2i32)$")>;
+// ASIMD absolute diff accum, Q-form
+def : InstRW<[A64FXWrite_ABA],
+ (instregex "^[SU]ABA(v16i8|v8i16|v4i32)$")>;
+// ASIMD absolute diff accum long
+def : InstRW<[A64FXWrite_ABAL],
+ (instregex "^[SU]ABAL")>;
+// ASIMD arith, reduce, 4H/4S
+def : InstRW<[A64FXWrite_ADDLV1],
+ (instregex "^[SU]?ADDL?V(v8i8|v4i16|v2i32)v$")>;
+// ASIMD arith, reduce, 8B
+def : InstRW<[A64FXWrite_ADDLV1],
+ (instregex "^[SU]?ADDL?V(v8i16|v4i32)v$")>;
+// ASIMD arith, reduce, 16B/16H
+def : InstRW<[A64FXWrite_ADDLV1],
+ (instregex "^[SU]?ADDL?Vv16i8v$")>;
+// ASIMD max/min, reduce, 4H/4S
+def : InstRW<[A64FXWrite_MINMAXV],
+ (instregex "^[SU](MIN|MAX)V(v4i16|v4i32)v$")>;
+// ASIMD max/min, reduce, 8B/8H
+def : InstRW<[A64FXWrite_MINMAXV],
+ (instregex "^[SU](MIN|MAX)V(v8i8|v8i16)v$")>;
+// ASIMD max/min, reduce, 16B/16H
+def : InstRW<[A64FXWrite_MINMAXV],
+ (instregex "^[SU](MIN|MAX)Vv16i8v$")>;
+// ASIMD multiply, D-form
+def : InstRW<[A64FXWrite_PMUL],
+ (instregex "^(P?MUL|SQR?DMUL)" #
+ "(v8i8|v4i16|v2i32|v1i8|v1i16|v1i32|v1i64)" #
+ "(_indexed)?$")>;
+
+// ASIMD multiply, Q-form
+def : InstRW<[A64FXWrite_PMUL],
+ (instregex "^(P?MUL)(v16i8|v8i16|v4i32)(_indexed)?$")>;
+
+// ASIMD multiply, Q-form
+def : InstRW<[A64FXWrite_SQRDMULH],
+ (instregex "^(SQR?DMULH)(v16i8|v8i16|v4i32)(_indexed)?$")>;
+
+// ASIMD multiply accumulate, D-form
+def : InstRW<[A64FXWrite_9Cyc_GI03],
+ (instregex "^ML[AS](v8i8|v4i16|v2i32)(_indexed)?$")>;
+// ASIMD multiply accumulate, Q-form
+def : InstRW<[A64FXWrite_9Cyc_GI03],
+ (instregex "^ML[AS](v16i8|v8i16|v4i32)(_indexed)?$")>;
+// ASIMD shift accumulate
+def : InstRW<[A64FXWrite_SRSRAV],
+ (instregex "SRSRAv", "URSRAv")>;
+def : InstRW<[A64FXWrite_SSRAV],
+ (instregex "SSRAv", "USRAv")>;
+
+// ASIMD shift by immed, basic
+def : InstRW<[A64FXWrite_RSHRN],
+ (instregex "RSHRNv", "SQRSHRNv", "SQRSHRUNv", "UQRSHRNv")>;
+def : InstRW<[A64FXWrite_SHRN],
+ (instregex "SHRNv", "SQSHRNv", "SQSHRUNv", "UQSHRNv")>;
+
+def : InstRW<[A64FXWrite_6Cyc_GI3],
+ (instregex "SQXTNv", "SQXTUNv", "UQXTNv")>;
+
+// ASIMD shift by immed, complex
+def : InstRW<[A64FXWrite_ABA], (instregex "^[SU]?(Q|R){1,2}SHR")>;
+def : InstRW<[A64FXWrite_6Cyc_GI3], (instregex "^SQSHLU")>;
+// ASIMD shift by register, basic, Q-form
+def : InstRW<[A64FXWrite_6Cyc_GI3],
+ (instregex "^[SU]SHL(v16i8|v8i16|v4i32|v2i64)")>;
+// ASIMD shift by register, complex, D-form
+def : InstRW<[A64FXWrite_6Cyc_GI3],
+ (instregex "^[SU][QR]{1,2}SHL" #
+ "(v1i8|v1i16|v1i32|v1i64|v8i8|v4i16|v2i32|b|d|h|s)")>;
+// ASIMD shift by register, complex, Q-form
+def : InstRW<[A64FXWrite_6Cyc_GI3],
+ (instregex "^[SU][QR]{1,2}SHL(v16i8|v8i16|v4i32|v2i64)")>;
+
+// ASIMD Arithmetic
+def : InstRW<[A64FXWrite_4Cyc_GI03],
+ (instregex "(ADD|SUB)(v8i8|v4i16|v2i32|v1i64)")>;
+def : InstRW<[A64FXWrite_4Cyc_GI03],
+ (instregex "(ADD|SUB)(v16i8|v8i16|v4i32|v2i64)")>;
+def : InstRW<[A64FXWrite_SHRN], (instregex "(ADD|SUB)HNv.*")>;
+def : InstRW<[A64FXWrite_RSHRN], (instregex "(RADD|RSUB)HNv.*")>;
+def : InstRW<[A64FXWrite_4Cyc_GI03],
+ (instregex "^SQADD", "^SQNEG", "^SQSUB", "^SRHADD",
+ "^SUQADD", "^UQADD", "^UQSUB", "^URHADD", "^USQADD")>;
+def : InstRW<[A64FXWrite_ADDP],
+ (instregex "ADDP(v16i8|v8i16|v4i32|v2i64)")>;
+def : InstRW<[A64FXWrite_4Cyc_GI03],
+ (instregex "((AND|ORN|EOR|EON)S?(Xr[rsi]|v16i8|v8i16|v4i32)|" #
+ "(ORR|BIC)S?(Xr[rs]|v16i8|v8i16|v4i32))")>;
+def : InstRW<[A64FXWrite_4Cyc_GI0],
+ (instregex "(CLS|CLZ|CNT)(v4i32|v8i16|v16i8)")>;
+def : InstRW<[A64FXWrite_SADALP], (instregex "^SADALP", "^UADALP")>;
+def : InstRW<[A64FXWrite_SADDLP], (instregex "^SADDLPv", "^UADDLPv")>;
+def : InstRW<[A64FXWrite_ADDLV1], (instregex "^SADDLV", "^UADDLV")>;
+def : InstRW<[A64FXWrite_MINMAXV],
+ (instregex "^ADDVv", "^SMAXVv", "^UMAXVv", "^SMINVv", "^UMINVv")>;
+def : InstRW<[A64FXWrite_ABA],
+ (instregex "^SABAv", "^UABAv", "^SABALv", "^UABALv")>;
+def : InstRW<[A64FXWrite_4Cyc_GI03],
+ (instregex "^SQADDv", "^SQSUBv", "^UQADDv", "^UQSUBv")>;
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instregex "^SUQADDv", "^USQADDv")>;
+def : InstRW<[A64FXWrite_SHRN],
+ (instregex "^ADDHNv", "^SUBHNv")>;
+def : InstRW<[A64FXWrite_RSHRN],
+ (instregex "^RADDHNv", "^RSUBHNv")>;
+def : InstRW<[A64FXWrite_4Cyc_GI03],
+ (instregex "^SQABS", "^SQADD", "^SQNEG", "^SQSUB",
+ "^SRHADD", "^SUQADD", "^UQADD", "^UQSUB",
+ "^URHADD", "^USQADD")>;
+
+def : InstRW<[A64FXWrite_4Cyc_GI03],
+ (instregex "^CMEQv", "^CMGEv", "^CMGTv",
+ "^CMLEv", "^CMLTv", "^CMHIv", "^CMHSv")>;
+def : InstRW<[A64FXWrite_MINMAXV],
+ (instregex "^SMAXv", "^SMINv", "^UMAXv", "^UMINv")>;
+def : InstRW<[A64FXWrite_ADDP],
+ (instregex "^SMAXPv", "^SMINPv", "^UMAXPv", "^UMINPv")>;
+def : InstRW<[A64FXWrite_4Cyc_GI03],
+ (instregex "^SABDv", "^UABDv")>;
+def : InstRW<[A64FXWrite_TBX1],
+ (instregex "^SABDLv", "^UABDLv")>;
+
+//---
+// 3.13 ASIMD Floating-point Instructions
+//---
+
+// ASIMD FP absolute value
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instregex "^FABSv")>;
+
+// ASIMD FP arith, normal, D-form
+// ASIMD FP arith, normal, Q-form
+def : InstRW<[A64FXWrite_9Cyc_GI03],
+ (instregex "^FABDv", "^FADDv", "^FSUBv")>;
+
+// ASIMD FP arith, pairwise, D-form
+// ASIMD FP arith, pairwise, Q-form
+def : InstRW<[A64FXWrite_FADDPV], (instregex "^FADDPv")>;
+
+// ASIMD FP compare, D-form
+// ASIMD FP compare, Q-form
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instregex "^FACGEv", "^FACGTv")>;
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instregex "^FCMEQv", "^FCMGEv",
+ "^FCMGTv", "^FCMLEv",
+ "^FCMLTv")>;
+// ASIMD FP round, D-form
+def : InstRW<[A64FXWrite_9Cyc_GI03],
+ (instregex "^FRINT[AIMNPXZ](v2f32)")>;
+// ASIMD FP round, Q-form
+def : InstRW<[A64FXWrite_9Cyc_GI03],
+ (instregex "^FRINT[AIMNPXZ](v4f32|v2f64)")>;
+
+// ASIMD FP convert, long
+// ASIMD FP convert, narrow
+// ASIMD FP convert, other, D-form
+// ASIMD FP convert, other, Q-form
+
+// ASIMD FP convert, long and narrow
+def : InstRW<[A64FXWrite_FCVTXNV], (instregex "^FCVT(L|N|XN)v")>;
+// ASIMD FP convert, other, D-form
+def : InstRW<[A64FXWrite_FCVTXNV],
+ (instregex "^[FVSU]CVT([AMNPZ][SU])?(_Int)?(v2f32|v1i32|v2i32|v1i64)")>;
+// ASIMD FP convert, other, Q-form
+def : InstRW<[A64FXWrite_FCVTXNV],
+ (instregex "^[FVSU]CVT([AMNPZ][SU])?(_Int)?(v4f32|v2f64|v4i32|v2i64)")>;
+
+// ASIMD FP divide, D-form, F32
+def : InstRW<[A64FXXWriteFDivSP], (instrs FDIVv2f32)>;
+def : InstRW<[A64FXXWriteFDivSP], (instregex "FDIVv2f32")>;
+
+// ASIMD FP divide, Q-form, F32
+def : InstRW<[A64FXXWriteFDiv], (instrs FDIVv4f32)>;
+def : InstRW<[A64FXXWriteFDiv], (instregex "FDIVv4f32")>;
+
+// ASIMD FP divide, Q-form, F64
+def : InstRW<[A64FXXWriteFDivDP], (instrs FDIVv2f64)>;
+def : InstRW<[A64FXXWriteFDivDP], (instregex "FDIVv2f64")>;
+
+// ASIMD FP max/min, normal, D-form
+// ASIMD FP max/min, normal, Q-form
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instregex "^FMAXv", "^FMAXNMv",
+ "^FMINv", "^FMINNMv")>;
+
+// ASIMD FP max/min, pairwise, D-form
+// ASIMD FP max/min, pairwise, Q-form
+def : InstRW<[A64FXWrite_ADDP], (instregex "^FMAXPv", "^FMAXNMPv",
+ "^FMINPv", "^FMINNMPv")>;
+
+// ASIMD FP max/min, reduce
+def : InstRW<[A64FXWrite_FMAXVVH], (instregex "^FMAXVv", "^FMAXNMVv",
+ "^FMINVv", "^FMINNMVv")>;
+
+// ASIMD FP multiply, D-form, FZ
+// ASIMD FP multiply, D-form, no FZ
+// ASIMD FP multiply, Q-form, FZ
+// ASIMD FP multiply, Q-form, no FZ
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instregex "^FMULv", "^FMULXv")>;
+def : InstRW<[A64FXWrite_FMULXE],
+ (instregex "^FMULX?(v2f32|v1i32|v2i32|v1i64|32|64)")>;
+def : InstRW<[A64FXWrite_FMULXE],
+ (instregex "^FMULX?(v4f32|v2f64|v4i32|v2i64)")>;
+
+// ASIMD FP multiply accumulate, Dform, FZ
+// ASIMD FP multiply accumulate, Dform, no FZ
+// ASIMD FP multiply accumulate, Qform, FZ
+// ASIMD FP multiply accumulate, Qform, no FZ
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instregex "^FMLAv", "^FMLSv")>;
+def : InstRW<[A64FXWrite_FMULXE],
+ (instregex "^FML[AS](v2f32|v1i32|v2i32|v1i64)")>;
+def : InstRW<[A64FXWrite_FMULXE],
+ (instregex "^FML[AS](v4f32|v2f64|v4i32|v2i64)")>;
+
+// ASIMD FP negate
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instregex "^FNEGv")>;
+
+//--
+// 3.14 ASIMD Miscellaneous Instructions
+//--
+
+// ASIMD bit reverse
+def : InstRW<[A64FXWrite_1Cyc_GI2456], (instregex "^RBITv")>;
+
+// ASIMD bitwise insert, D-form
+// ASIMD bitwise insert, Q-form
+def : InstRW<[A64FXWrite_BIF],
+ (instregex "^BIFv", "^BITv", "^BSLv")>;
+
+// ASIMD count, D-form
+// ASIMD count, Q-form
+def : InstRW<[A64FXWrite_4Cyc_GI0],
+ (instregex "^CLSv", "^CLZv", "^CNTv")>;
+
+// ASIMD duplicate, gen reg
+// ASIMD duplicate, element
+def : InstRW<[A64FXWrite_DUPGENERAL], (instregex "^DUPv")>;
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^CPY")>;
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^DUPv.+gpr")>;
+
+// ASIMD extract
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^EXTv")>;
+
+// ASIMD extract narrow
+def : InstRW<[A64FXWrite_6Cyc_GI3], (instregex "^XTNv")>;
+
+// ASIMD extract narrow, saturating
+def : InstRW<[A64FXWrite_6Cyc_GI3],
+ (instregex "^SQXTNv", "^SQXTUNv", "^UQXTNv")>;
+
+// ASIMD insert, element to element
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^INSv")>;
+
+// ASIMD transfer, element to gen reg
+def : InstRW<[A64FXWrite_SMOV], (instregex "^[SU]MOVv")>;
+
+// ASIMD move, integer immed
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instregex "^MOVIv")>;
+
+// ASIMD move, FP immed
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instregex "^FMOVv")>;
+
+// ASIMD table lookup, D-form
+def : InstRW<[A64FXWrite_6Cyc_GI3], (instregex "^TBLv8i8One")>;
+def : InstRW<[A64FXWrite_TBX1], (instregex "^TBLv8i8Two")>;
+def : InstRW<[A64FXWrite_TBX2], (instregex "^TBLv8i8Three")>;
+def : InstRW<[A64FXWrite_TBX3], (instregex "^TBLv8i8Four")>;
+def : InstRW<[A64FXWrite_TBX1], (instregex "^TBXv8i8One")>;
+def : InstRW<[A64FXWrite_TBX2], (instregex "^TBXv8i8Two")>;
+def : InstRW<[A64FXWrite_TBX3], (instregex "^TBXv8i8Three")>;
+def : InstRW<[A64FXWrite_TBX4], (instregex "^TBXv8i8Four")>;
+
+// ASIMD table lookup, Q-form
+def : InstRW<[A64FXWrite_6Cyc_GI3], (instregex "^TBLv16i8One")>;
+def : InstRW<[A64FXWrite_TBX1], (instregex "^TBLv16i8Two")>;
+def : InstRW<[A64FXWrite_TBX2], (instregex "^TBLv16i8Three")>;
+def : InstRW<[A64FXWrite_TBX3], (instregex "^TBLv16i8Four")>;
+def : InstRW<[A64FXWrite_TBX1], (instregex "^TBXv16i8One")>;
+def : InstRW<[A64FXWrite_TBX2], (instregex "^TBXv16i8Two")>;
+def : InstRW<[A64FXWrite_TBX3], (instregex "^TBXv16i8Three")>;
+def : InstRW<[A64FXWrite_TBX4], (instregex "^TBXv16i8Four")>;
+
+// ASIMD transpose
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^TRN1", "^TRN2")>;
+
+// ASIMD unzip/zip
+def : InstRW<[A64FXWrite_6Cyc_GI0],
+ (instregex "^UZP1", "^UZP2", "^ZIP1", "^ZIP2")>;
+
+// ASIMD reciprocal estimate, D-form
+// ASIMD reciprocal estimate, Q-form
+def : InstRW<[A64FXWrite_4Cyc_GI03],
+ (instregex "^FRECPEv", "^FRECPXv", "^URECPEv",
+ "^FRSQRTEv", "^URSQRTEv")>;
+
+// ASIMD reciprocal step, D-form, FZ
+// ASIMD reciprocal step, D-form, no FZ
+// ASIMD reciprocal step, Q-form, FZ
+// ASIMD reciprocal step, Q-form, no FZ
+def : InstRW<[A64FXWrite_9Cyc_GI0], (instregex "^FRECPSv", "^FRSQRTSv")>;
+
+// ASIMD reverse
+def : InstRW<[A64FXWrite_4Cyc_GI03],
+ (instregex "^REV16v", "^REV32v", "^REV64v")>;
+
+// ASIMD table lookup, D-form
+// ASIMD table lookup, Q-form
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^TBLv", "^TBXv")>;
+
+// ASIMD transfer, element to word or word
+def : InstRW<[A64FXWrite_SMOV], (instregex "^[SU]MOVv")>;
+
+// ASIMD transfer, element to gen reg
+def : InstRW<[A64FXWrite_SMOV], (instregex "(S|U)MOVv.*")>;
+
+// ASIMD transfer gen reg to element
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^INSv")>;
+
+// ASIMD transpose
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^TRN1v", "^TRN2v",
+ "^UZP1v", "^UZP2v")>;
+
+// ASIMD unzip/zip
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^ZIP1v", "^ZIP2v")>;
+
+//--
+// 3.15 ASIMD Load Instructions
+//--
+
+// ASIMD load, 1 element, multiple, 1 reg, D-form
+// ASIMD load, 1 element, multiple, 1 reg, Q-form
+def : InstRW<[A64FXWrite_8Cyc_GI56],
+ (instregex "^LD1Onev(8b|4h|2s|1d|2d)$")>;
+def : InstRW<[A64FXWrite_11Cyc_GI56],
+ (instregex "^LD1Onev(16b|8h|4s)$")>;
+def : InstRW<[A64FXWrite_LD108, WriteAdr],
+ (instregex "^LD1Onev(8b|4h|2s|1d|2d)_POST$")>;
+def : InstRW<[A64FXWrite_LD109, WriteAdr],
+ (instregex "^LD1Onev(16b|8h|4s)_POST$")>;
+
+// ASIMD load, 1 element, multiple, 2 reg, D-form
+// ASIMD load, 1 element, multiple, 2 reg, Q-form
+def : InstRW<[A64FXWrite_LD102],
+ (instregex "^LD1Twov(8b|4h|2s|1d|2d)$")>;
+def : InstRW<[A64FXWrite_LD103],
+ (instregex "^LD1Twov(16b|8h|4s)$")>;
+def : InstRW<[A64FXWrite_LD110, WriteAdr],
+ (instregex "^LD1Twov(8b|4h|2s|1d|2d)_POST$")>;
+def : InstRW<[A64FXWrite_LD111, WriteAdr],
+ (instregex "^LD1Twov(16b|8h|4s)_POST$")>;
+
+// ASIMD load, 1 element, multiple, 3 reg, D-form
+// ASIMD load, 1 element, multiple, 3 reg, Q-form
+def : InstRW<[A64FXWrite_LD104],
+ (instregex "^LD1Threev(8b|4h|2s|1d|2d)$")>;
+def : InstRW<[A64FXWrite_LD105],
+ (instregex "^LD1Threev(16b|8h|4s)$")>;
+def : InstRW<[A64FXWrite_LD112, WriteAdr],
+ (instregex "^LD1Threev(8b|4h|2s|1d|2d)_POST$")>;
+def : InstRW<[A64FXWrite_LD113, WriteAdr],
+ (instregex "^LD1Threev(16b|8h|4s)_POST$")>;
+
+// ASIMD load, 1 element, multiple, 4 reg, D-form
+// ASIMD load, 1 element, multiple, 4 reg, Q-form
+def : InstRW<[A64FXWrite_LD106],
+ (instregex "^LD1Fourv(8b|4h|2s|1d|2d)$")>;
+def : InstRW<[A64FXWrite_LD107],
+ (instregex "^LD1Fourv(16b|8h|4s)$")>;
+def : InstRW<[A64FXWrite_LD114, WriteAdr],
+ (instregex "^LD1Fourv(8b|4h|2s|1d|2d)_POST$")>;
+def : InstRW<[A64FXWrite_LD115, WriteAdr],
+ (instregex "^LD1Fourv(16b|8h|4s)_POST$")>;
+
+// ASIMD load, 1 element, one lane, B/H/S
+// ASIMD load, 1 element, one lane, D
+def : InstRW<[A64FXWrite_LD1I0], (instregex "^LD1i(8|16|32|64)$")>;
+def : InstRW<[A64FXWrite_LD1I1, WriteAdr],
+ (instregex "^LD1i(8|16|32|64)_POST$")>;
+
+// ASIMD load, 1 element, all lanes, D-form, B/H/S
+// ASIMD load, 1 element, all lanes, D-form, D
+// ASIMD load, 1 element, all lanes, Q-form
+def : InstRW<[A64FXWrite_8Cyc_GI03],
+ (instregex "^LD1Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[A64FXWrite_LD108, WriteAdr],
+ (instregex "^LD1Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+// ASIMD load, 2 element, multiple, D-form, B/H/S
+// ASIMD load, 2 element, multiple, Q-form, D
+def : InstRW<[A64FXWrite_LD103],
+ (instregex "^LD2Twov(8b|4h|2s|16b|8h|4s|2d)$")>;
+def : InstRW<[A64FXWrite_LD111, WriteAdr],
+ (instregex "^LD2Twov(8b|4h|2s|16b|8h|4s|2d)_POST$")>;
+
+// ASIMD load, 2 element, one lane, B/H
+// ASIMD load, 2 element, one lane, S
+// ASIMD load, 2 element, one lane, D
+def : InstRW<[A64FXWrite_LD2I0], (instregex "^LD2i(8|16|32|64)$")>;
+def : InstRW<[A64FXWrite_LD2I1, WriteAdr],
+ (instregex "^LD2i(8|16|32|64)_POST$")>;
+
+// ASIMD load, 2 element, all lanes, D-form, B/H/S
+// ASIMD load, 2 element, all lanes, D-form, D
+// ASIMD load, 2 element, all lanes, Q-form
+def : InstRW<[A64FXWrite_LD102],
+ (instregex "^LD2Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[A64FXWrite_LD110, WriteAdr],
+ (instregex "^LD2Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+// ASIMD load, 3 element, multiple, D-form, B/H/S
+// ASIMD load, 3 element, multiple, Q-form, B/H/S
+// ASIMD load, 3 element, multiple, Q-form, D
+def : InstRW<[A64FXWrite_LD105],
+ (instregex "^LD3Threev(8b|4h|2s|16b|8h|4s|2d)$")>;
+def : InstRW<[A64FXWrite_LD113, WriteAdr],
+ (instregex "^LD3Threev(8b|4h|2s|16b|8h|4s|2d)_POST$")>;
+
+// ASIMD load, 3 element, one lone, B/H
+// ASIMD load, 3 element, one lane, S
+// ASIMD load, 3 element, one lane, D
+def : InstRW<[A64FXWrite_LD3I0], (instregex "^LD3i(8|16|32|64)$")>;
+def : InstRW<[A64FXWrite_LD3I1, WriteAdr],
+ (instregex "^LD3i(8|16|32|64)_POST$")>;
+
+// ASIMD load, 3 element, all lanes, D-form, B/H/S
+// ASIMD load, 3 element, all lanes, D-form, D
+// ASIMD load, 3 element, all lanes, Q-form, B/H/S
+// ASIMD load, 3 element, all lanes, Q-form, D
+def : InstRW<[A64FXWrite_LD104],
+ (instregex "^LD3Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[A64FXWrite_LD112, WriteAdr],
+ (instregex "^LD3Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+// ASIMD load, 4 element, multiple, D-form, B/H/S
+// ASIMD load, 4 element, multiple, Q-form, B/H/S
+// ASIMD load, 4 element, multiple, Q-form, D
+def : InstRW<[A64FXWrite_LD107],
+ (instregex "^LD4Fourv(8b|4h|2s|16b|8h|4s|2d)$")>;
+def : InstRW<[A64FXWrite_LD115, WriteAdr],
+ (instregex "^LD4Fourv(8b|4h|2s|16b|8h|4s|2d)_POST$")>;
+
+// ASIMD load, 4 element, one lane, B/H
+// ASIMD load, 4 element, one lane, S
+// ASIMD load, 4 element, one lane, D
+def : InstRW<[A64FXWrite_LD4I0], (instregex "^LD4i(8|16|32|64)$")>;
+def : InstRW<[A64FXWrite_LD4I1, WriteAdr],
+ (instregex "^LD4i(8|16|32|64)_POST$")>;
+
+// ASIMD load, 4 element, all lanes, D-form, B/H/S
+// ASIMD load, 4 element, all lanes, D-form, D
+// ASIMD load, 4 element, all lanes, Q-form, B/H/S
+// ASIMD load, 4 element, all lanes, Q-form, D
+def : InstRW<[A64FXWrite_LD106],
+ (instregex "^LD4Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[A64FXWrite_LD114, WriteAdr],
+ (instregex "^LD4Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+//--
+// 3.16 ASIMD Store Instructions
+//--
+
+// ASIMD store, 1 element, multiple, 1 reg, D-form
+// ASIMD store, 1 element, multiple, 1 reg, Q-form
+def : InstRW<[A64FXWrite_ST10],
+ (instregex "^ST1Onev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[A64FXWrite_ST14, WriteAdr],
+ (instregex "^ST1Onev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+// ASIMD store, 1 element, multiple, 2 reg, D-form
+// ASIMD store, 1 element, multiple, 2 reg, Q-form
+def : InstRW<[A64FXWrite_ST11],
+ (instregex "^ST1Twov(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[A64FXWrite_ST15, WriteAdr],
+ (instregex "^ST1Twov(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+// ASIMD store, 1 element, multiple, 3 reg, D-form
+// ASIMD store, 1 element, multiple, 3 reg, Q-form
+def : InstRW<[A64FXWrite_ST12],
+ (instregex "^ST1Threev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[A64FXWrite_ST16, WriteAdr],
+ (instregex "^ST1Threev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+// ASIMD store, 1 element, multiple, 4 reg, D-form
+// ASIMD store, 1 element, multiple, 4 reg, Q-form
+def : InstRW<[A64FXWrite_ST13],
+ (instregex "^ST1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[A64FXWrite_ST17, WriteAdr],
+ (instregex "^ST1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+// ASIMD store, 1 element, one lane, B/H/S
+// ASIMD store, 1 element, one lane, D
+def : InstRW<[A64FXWrite_ST10],
+ (instregex "^ST1i(8|16|32|64)$")>;
+def : InstRW<[A64FXWrite_ST14, WriteAdr],
+ (instregex "^ST1i(8|16|32|64)_POST$")>;
+
+// ASIMD store, 2 element, multiple, D-form, B/H/S
+// ASIMD store, 2 element, multiple, Q-form, B/H/S
+// ASIMD store, 2 element, multiple, Q-form, D
+def : InstRW<[A64FXWrite_ST11],
+ (instregex "^ST2Twov(8b|4h|2s|16b|8h|4s|2d)$")>;
+def : InstRW<[A64FXWrite_ST15, WriteAdr],
+ (instregex "^ST2Twov(8b|4h|2s|16b|8h|4s|2d)_POST$")>;
+
+// ASIMD store, 2 element, one lane, B/H/S
+// ASIMD store, 2 element, one lane, D
+def : InstRW<[A64FXWrite_ST11],
+ (instregex "^ST2i(8|16|32|64)$")>;
+def : InstRW<[A64FXWrite_ST15, WriteAdr],
+ (instregex "^ST2i(8|16|32|64)_POST$")>;
+
+// ASIMD store, 3 element, multiple, D-form, B/H/S
+// ASIMD store, 3 element, multiple, Q-form, B/H/S
+// ASIMD store, 3 element, multiple, Q-form, D
+def : InstRW<[A64FXWrite_ST12],
+ (instregex "^ST3Threev(8b|4h|2s|16b|8h|4s|2d)$")>;
+def : InstRW<[A64FXWrite_ST16, WriteAdr],
+ (instregex "^ST3Threev(8b|4h|2s|16b|8h|4s|2d)_POST$")>;
+
+// ASIMD store, 3 element, one lane, B/H
+// ASIMD store, 3 element, one lane, S
+// ASIMD store, 3 element, one lane, D
+def : InstRW<[A64FXWrite_ST12], (instregex "^ST3i(8|16|32|64)$")>;
+def : InstRW<[A64FXWrite_ST16, WriteAdr],
+ (instregex "^ST3i(8|16|32|64)_POST$")>;
+
+// ASIMD store, 4 element, multiple, D-form, B/H/S
+// ASIMD store, 4 element, multiple, Q-form, B/H/S
+// ASIMD store, 4 element, multiple, Q-form, D
+def : InstRW<[A64FXWrite_ST13],
+ (instregex "^ST4Fourv(8b|4h|2s|16b|8h|4s|2d)$")>;
+def : InstRW<[A64FXWrite_ST17, WriteAdr],
+ (instregex "^ST4Fourv(8b|4h|2s|16b|8h|4s|2d)_POST$")>;
+
+// ASIMD store, 4 element, one lane, B/H
+// ASIMD store, 4 element, one lane, S
+// ASIMD store, 4 element, one lane, D
+def : InstRW<[A64FXWrite_ST13], (instregex "^ST4i(8|16|32|64)$")>;
+def : InstRW<[A64FXWrite_ST17, WriteAdr],
+ (instregex "^ST4i(8|16|32|64)_POST$")>;
+
+// V8.1a Atomics (LSE)
+def : InstRW<[A64FXWrite_CAS, WriteAtomic],
+ (instrs CASB, CASH, CASW, CASX)>;
+
+def : InstRW<[A64FXWrite_CAS, WriteAtomic],
+ (instrs CASAB, CASAH, CASAW, CASAX)>;
+
+def : InstRW<[A64FXWrite_CAS, WriteAtomic],
+ (instrs CASLB, CASLH, CASLW, CASLX)>;
+
+def : InstRW<[A64FXWrite_CAS, WriteAtomic],
+ (instrs CASALB, CASALH, CASALW, CASALX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDLARB, LDLARH, LDLARW, LDLARX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDADDB, LDADDH, LDADDW, LDADDX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDADDAB, LDADDAH, LDADDAW, LDADDAX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDADDLB, LDADDLH, LDADDLW, LDADDLX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDADDALB, LDADDALH, LDADDALW, LDADDALX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDCLRB, LDCLRH, LDCLRW, LDCLRX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDCLRAB, LDCLRAH, LDCLRAW, LDCLRAX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDCLRLB, LDCLRLH, LDCLRLW, LDCLRLX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDCLRALB, LDCLRALH, LDCLRALW, LDCLRALX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDEORB, LDEORH, LDEORW, LDEORX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDEORAB, LDEORAH, LDEORAW, LDEORAX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDEORLB, LDEORLH, LDEORLW, LDEORLX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDEORALB, LDEORALH, LDEORALW, LDEORALX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDSETB, LDSETH, LDSETW, LDSETX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDSETAB, LDSETAH, LDSETAW, LDSETAX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDSETLB, LDSETLH, LDSETLW, LDSETLX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDSETALB, LDSETALH, LDSETALW, LDSETALX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDSMAXB, LDSMAXH, LDSMAXW, LDSMAXX,
+ LDSMAXAB, LDSMAXAH, LDSMAXAW, LDSMAXAX,
+ LDSMAXLB, LDSMAXLH, LDSMAXLW, LDSMAXLX,
+ LDSMAXALB, LDSMAXALH, LDSMAXALW, LDSMAXALX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDSMINB, LDSMINH, LDSMINW, LDSMINX,
+ LDSMINAB, LDSMINAH, LDSMINAW, LDSMINAX,
+ LDSMINLB, LDSMINLH, LDSMINLW, LDSMINLX,
+ LDSMINALB, LDSMINALH, LDSMINALW, LDSMINALX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDUMAXB, LDUMAXH, LDUMAXW, LDUMAXX,
+ LDUMAXAB, LDUMAXAH, LDUMAXAW, LDUMAXAX,
+ LDUMAXLB, LDUMAXLH, LDUMAXLW, LDUMAXLX,
+ LDUMAXALB, LDUMAXALH, LDUMAXALW, LDUMAXALX)>;
+
+def : InstRW<[A64FXWrite_5Cyc_GI5, WriteAtomic],
+ (instrs LDUMINB, LDUMINH, LDUMINW, LDUMINX,
+ LDUMINAB, LDUMINAH, LDUMINAW, LDUMINAX,
+ LDUMINLB, LDUMINLH, LDUMINLW, LDUMINLX,
+ LDUMINALB, LDUMINALH, LDUMINALW, LDUMINALX)>;
+
+def : InstRW<[A64FXWrite_SWP, WriteAtomic],
+ (instrs SWPB, SWPH, SWPW, SWPX)>;
+
+def : InstRW<[A64FXWrite_SWP, WriteAtomic],
+ (instrs SWPAB, SWPAH, SWPAW, SWPAX)>;
+
+def : InstRW<[A64FXWrite_SWP, WriteAtomic],
+ (instrs SWPLB, SWPLH, SWPLW, SWPLX)>;
+
+def : InstRW<[A64FXWrite_SWP, WriteAtomic],
+ (instrs SWPALB, SWPALH, SWPALW, SWPALX)>;
+
+def : InstRW<[A64FXWrite_STUR, WriteAtomic],
+ (instrs STLLRB, STLLRH, STLLRW, STLLRX)>;
+
+// [ 1] "abs $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ABS_ZPmZ_B, ABS_ZPmZ_D, ABS_ZPmZ_H, ABS_ZPmZ_S)>;
+
+// [ 2] "add $Zd, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ADD_ZZZ_B, ADD_ZZZ_D, ADD_ZZZ_H, ADD_ZZZ_S)>;
+
+// [ 3] "add $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ADD_ZPmZ_B, ADD_ZPmZ_D, ADD_ZPmZ_H, ADD_ZPmZ_S)>;
+
+// [ 4] "add $Zdn, $_Zdn, $imm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ADD_ZI_B, ADD_ZI_D, ADD_ZI_H, ADD_ZI_S)>;
+
+// [ 5] "addpl $Rd, $Rn, $imm6";
+def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs ADDPL_XXI)>;
+
+// [ 6] "addvl $Rd, $Rn, $imm6";
+def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs ADDVL_XXI)>;
+
+// [ 7] "adr $Zd, [$Zn, $Zm]";
+def : InstRW<[A64FXWrite_5Cyc_GI0], (instrs ADR_LSL_ZZZ_D_0, ADR_LSL_ZZZ_D_1, ADR_LSL_ZZZ_D_2, ADR_LSL_ZZZ_D_3, ADR_LSL_ZZZ_S_0, ADR_LSL_ZZZ_S_1, ADR_LSL_ZZZ_S_2, ADR_LSL_ZZZ_S_3, ADR_SXTW_ZZZ_D_0, ADR_SXTW_ZZZ_D_1, ADR_SXTW_ZZZ_D_2, ADR_SXTW_ZZZ_D_3, ADR_UXTW_ZZZ_D_0, ADR_UXTW_ZZZ_D_1, ADR_UXTW_ZZZ_D_2, ADR_UXTW_ZZZ_D_3)>;
+
+// [ 8] "and $Pd, $Pg/z, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs AND_PPzPP)>;
+
+// [ 9] "and $Zd, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs AND_ZZZ)>;
+
+// [10] "and $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs AND_ZPmZ_B, AND_ZPmZ_D, AND_ZPmZ_H, AND_ZPmZ_S)>;
+
+// [11] "and $Zdn, $_Zdn, $imms13";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs AND_ZI)>;
+
+// [12] "ands $Pd, $Pg/z, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs ANDS_PPzPP)>;
+
+// [13] "andv $Vd, $Pg, $Zn";
+def : InstRW<[A64FXWrite_14Cyc_GI03], (instrs ANDV_VPZ_B, ANDV_VPZ_D, ANDV_VPZ_H, ANDV_VPZ_S)>;
+
+// [14] "asr $Zd, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ASR_WIDE_ZZZ_B, ASR_WIDE_ZZZ_H, ASR_WIDE_ZZZ_S)>;
+
+// [15] "asr $Zd, $Zn, $imm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ASR_ZZI_B, ASR_ZZI_D, ASR_ZZI_H, ASR_ZZI_S)>;
+
+// [16] "asr $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ASR_WIDE_ZPmZ_B, ASR_WIDE_ZPmZ_H, ASR_WIDE_ZPmZ_S, ASR_ZPmZ_B, ASR_ZPmZ_D, ASR_ZPmZ_H, ASR_ZPmZ_S)>;
+
+// [17] "asr $Zdn, $Pg/m, $_Zdn, $imm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ASR_ZPmI_B, ASR_ZPmI_D, ASR_ZPmI_H, ASR_ZPmI_S)>;
+
+// [18] "asrd $Zdn, $Pg/m, $_Zdn, $imm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ASRD_ZPmI_B, ASRD_ZPmI_D, ASRD_ZPmI_H, ASRD_ZPmI_S)>;
+
+// [19] "asrr $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ASRR_ZPmZ_B, ASRR_ZPmZ_D, ASRR_ZPmZ_H, ASRR_ZPmZ_S)>;
+
+// [20] "bic $Pd, $Pg/z, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BIC_PPzPP)>;
+
+// [21] "bic $Zd, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs BIC_ZZZ)>;
+
+// [22] "bic $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs BIC_ZPmZ_B, BIC_ZPmZ_D, BIC_ZPmZ_H, BIC_ZPmZ_S)>;
+
+// [23] "bics $Pd, $Pg/z, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BICS_PPzPP)>;
+
+// [24] "brka $Pd, $Pg/m, $Pn";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKA_PPmP)>;
+
+// [25] "brka $Pd, $Pg/z, $Pn";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKA_PPzP)>;
+
+// [26] "brkas $Pd, $Pg/z, $Pn";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKAS_PPzP)>;
+
+// [27] "brkb $Pd, $Pg/m, $Pn";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKB_PPmP)>;
+
+// [28] "brkb $Pd, $Pg/z, $Pn";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKB_PPzP)>;
+
+// [29] "brkbs $Pd, $Pg/z, $Pn";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKBS_PPzP)>;
+
+// [30] "brkn $Pdm, $Pg/z, $Pn, $_Pdm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKN_PPzP)>;
+
+// [31] "brkns $Pdm, $Pg/z, $Pn, $_Pdm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKNS_PPzP)>;
+
+// [32] "brkpa $Pd, $Pg/z, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKPA_PPzPP)>;
+
+// [33] "brkpas $Pd, $Pg/z, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKPAS_PPzPP)>;
+
+// [34] "brkpb $Pd, $Pg/z, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKPB_PPzPP)>;
+
+// [35] "brkpbs $Pd, $Pg/z, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs BRKPBS_PPzPP)>;
+
+// [36] "clasta $Rdn, $Pg, $_Rdn, $Zm";
+def : InstRW<[A64FXWrite_29Cyc_GI0256], (instrs CLASTA_RPZ_B, CLASTA_RPZ_D, CLASTA_RPZ_H, CLASTA_RPZ_S)>;
+
+// [37] "clasta $Vdn, $Pg, $_Vdn, $Zm";
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs CLASTA_VPZ_B, CLASTA_VPZ_D, CLASTA_VPZ_H, CLASTA_VPZ_S)>;
+
+// [38] "clasta $Zdn, $Pg, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs CLASTA_ZPZ_B, CLASTA_ZPZ_D, CLASTA_ZPZ_H, CLASTA_ZPZ_S)>;
+
+// [39] "clastb $Rdn, $Pg, $_Rdn, $Zm";
+def : InstRW<[A64FXWrite_29Cyc_GI0256], (instrs CLASTB_RPZ_B, CLASTB_RPZ_D, CLASTB_RPZ_H, CLASTB_RPZ_S)>;
+
+// [40] "clastb $Vdn, $Pg, $_Vdn, $Zm";
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs CLASTB_VPZ_B, CLASTB_VPZ_D, CLASTB_VPZ_H, CLASTB_VPZ_S)>;
+
+// [41] "clastb $Zdn, $Pg, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs CLASTB_ZPZ_B, CLASTB_ZPZ_D, CLASTB_ZPZ_H, CLASTB_ZPZ_S)>;
+
+// [42] "cls $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs CLS_ZPmZ_B, CLS_ZPmZ_D, CLS_ZPmZ_H, CLS_ZPmZ_S)>;
+
+// [43] "clz $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs CLZ_ZPmZ_B, CLZ_ZPmZ_D, CLZ_ZPmZ_H, CLZ_ZPmZ_S)>;
+
+// [44] "cmpeq $Pd, $Pg/z, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPEQ_PPzZZ_B, CMPEQ_PPzZZ_D, CMPEQ_PPzZZ_H, CMPEQ_PPzZZ_S, CMPEQ_WIDE_PPzZZ_B, CMPEQ_WIDE_PPzZZ_H, CMPEQ_WIDE_PPzZZ_S)>;
+
+// [45] "cmpeq $Pd, $Pg/z, $Zn, $imm5";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPEQ_PPzZI_B, CMPEQ_PPzZI_D, CMPEQ_PPzZI_H, CMPEQ_PPzZI_S)>;
+
+// [46] "cmpge $Pd, $Pg/z, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPGE_PPzZZ_B, CMPGE_PPzZZ_D, CMPGE_PPzZZ_H, CMPGE_PPzZZ_S, CMPGE_WIDE_PPzZZ_B, CMPGE_WIDE_PPzZZ_H, CMPGE_WIDE_PPzZZ_S)>;
+
+// [47] "cmpge $Pd, $Pg/z, $Zn, $imm5";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPGE_PPzZI_B, CMPGE_PPzZI_D, CMPGE_PPzZI_H, CMPGE_PPzZI_S)>;
+
+// [48] "cmpgt $Pd, $Pg/z, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPGT_PPzZZ_B, CMPGT_PPzZZ_D, CMPGT_PPzZZ_H, CMPGT_PPzZZ_S, CMPGT_WIDE_PPzZZ_B, CMPGT_WIDE_PPzZZ_H, CMPGT_WIDE_PPzZZ_S)>;
+
+// [49] "cmpgt $Pd, $Pg/z, $Zn, $imm5";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPGT_PPzZI_B, CMPGT_PPzZI_D, CMPGT_PPzZI_H, CMPGT_PPzZI_S)>;
+
+// [50] "cmphi $Pd, $Pg/z, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPHI_PPzZZ_B, CMPHI_PPzZZ_D, CMPHI_PPzZZ_H, CMPHI_PPzZZ_S, CMPHI_WIDE_PPzZZ_B, CMPHI_WIDE_PPzZZ_H, CMPHI_WIDE_PPzZZ_S)>;
+
+// [51] "cmphi $Pd, $Pg/z, $Zn, $imm7";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPHI_PPzZI_B, CMPHI_PPzZI_D, CMPHI_PPzZI_H, CMPHI_PPzZI_S)>;
+
+// [52] "cmphs $Pd, $Pg/z, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPHS_PPzZZ_B, CMPHS_PPzZZ_D, CMPHS_PPzZZ_H, CMPHS_PPzZZ_S, CMPHS_WIDE_PPzZZ_B, CMPHS_WIDE_PPzZZ_H, CMPHS_WIDE_PPzZZ_S)>;
+
+// [53] "cmphs $Pd, $Pg/z, $Zn, $imm7";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPHS_PPzZI_B, CMPHS_PPzZI_D, CMPHS_PPzZI_H, CMPHS_PPzZI_S)>;
+
+// [54] "cmple $Pd, $Pg/z, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPLE_WIDE_PPzZZ_B, CMPLE_WIDE_PPzZZ_H, CMPLE_WIDE_PPzZZ_S)>;
+
+// [55] "cmple $Pd, $Pg/z, $Zn, $imm5";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPLE_PPzZI_B, CMPLE_PPzZI_D, CMPLE_PPzZI_H, CMPLE_PPzZI_S)>;
+
+// [56] "cmplo $Pd, $Pg/z, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPLO_WIDE_PPzZZ_B, CMPLO_WIDE_PPzZZ_H, CMPLO_WIDE_PPzZZ_S)>;
+
+// [57] "cmplo $Pd, $Pg/z, $Zn, $imm7";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPLO_PPzZI_B, CMPLO_PPzZI_D, CMPLO_PPzZI_H, CMPLO_PPzZI_S)>;
+
+// [58] "cmpls $Pd, $Pg/z, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPLS_WIDE_PPzZZ_B, CMPLS_WIDE_PPzZZ_H, CMPLS_WIDE_PPzZZ_S)>;
+
+// [59] "cmpls $Pd, $Pg/z, $Zn, $imm7";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPLS_PPzZI_B, CMPLS_PPzZI_D, CMPLS_PPzZI_H, CMPLS_PPzZI_S)>;
+
+// [60] "cmplt $Pd, $Pg/z, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPLT_WIDE_PPzZZ_B, CMPLT_WIDE_PPzZZ_H, CMPLT_WIDE_PPzZZ_S)>;
+
+// [61] "cmplt $Pd, $Pg/z, $Zn, $imm5";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPLT_PPzZI_B, CMPLT_PPzZI_D, CMPLT_PPzZI_H, CMPLT_PPzZI_S)>;
+
+// [62] "cmpne $Pd, $Pg/z, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPNE_PPzZZ_B, CMPNE_PPzZZ_D, CMPNE_PPzZZ_H, CMPNE_PPzZZ_S, CMPNE_WIDE_PPzZZ_B, CMPNE_WIDE_PPzZZ_H, CMPNE_WIDE_PPzZZ_S)>;
+
+// [63] "cmpne $Pd, $Pg/z, $Zn, $imm5";
+def : InstRW<[A64FXWrite_4Cyc_GI01], (instrs CMPNE_PPzZI_B, CMPNE_PPzZI_D, CMPNE_PPzZI_H, CMPNE_PPzZI_S)>;
+
+// [64] "cnot $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs CNOT_ZPmZ_B, CNOT_ZPmZ_D, CNOT_ZPmZ_H, CNOT_ZPmZ_S)>;
+
+// [65] "cnt $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI3], (instrs CNT_ZPmZ_B, CNT_ZPmZ_D, CNT_ZPmZ_H, CNT_ZPmZ_S)>;
+
+// [66] "cntb $Rd, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs CNTB_XPiI)>;
+
+// [67] "cntd $Rd, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs CNTD_XPiI)>;
+
+// [68] "cnth $Rd, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs CNTH_XPiI)>;
+
+// [69] "cntp $Rd, $Pg, $Pn";
+def : InstRW<[A64FXWrite_6Cyc_GI01], (instrs CNTP_XPP_B, CNTP_XPP_D, CNTP_XPP_H, CNTP_XPP_S)>;
+
+// [70] "cntw $Rd, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs CNTW_XPiI)>;
+
+// [71] "compact $Zd, $Pg, $Zn";
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs COMPACT_ZPZ_D, COMPACT_ZPZ_S)>;
+
+// [72] "cpy $Zd, $Pg/m, $Rn";
+//@@@ def : InstRW<[XXXXXX], (instrs CPY_ZPmR_B, CPY_ZPmR_D, CPY_ZPmR_H, CPY_ZPmR_S)>;
+
+// [73] "cpy $Zd, $Pg/m, $Vn";
+//@@@ def : InstRW<[XXXXXX], (instrs CPY_ZPmV_B, CPY_ZPmV_D, CPY_ZPmV_H, CPY_ZPmV_S)>;
+
+// [74] "cpy $Zd, $Pg/m, $imm";
+//@@@ def : InstRW<[XXXXXX], (instrs CPY_ZPmI_B, CPY_ZPmI_D, CPY_ZPmI_H, CPY_ZPmI_S)>;
+
+// [75] "cpy $Zd, $Pg/z, $imm";
+//@@@ def : InstRW<[XXXXXX], (instrs CPY_ZPzI_B, CPY_ZPzI_D, CPY_ZPzI_H, CPY_ZPzI_S)>;
+
+// [76] "ctermeq $Rn, $Rm";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs CTERMEQ_WW, CTERMEQ_XX)>;
+
+// [77] "ctermne $Rn, $Rm";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs CTERMNE_WW, CTERMNE_XX)>;
+
+// [78] "decb $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs DECB_XPiI)>;
+
+// [79] "decd $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs DECD_XPiI)>;
+
+// [80] "decd $Zdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs DECD_ZPiI)>;
+
+// [81] "dech $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs DECH_XPiI)>;
+
+// [82] "dech $Zdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs DECH_ZPiI)>;
+
+// [83] "decp $Rdn, $Pg";
+def : InstRW<[A64FXWrite_6Cyc_GI124], (instrs DECP_XP_B, DECP_XP_D, DECP_XP_H, DECP_XP_S)>;
+
+// [84] "decp $Zdn, $Pg";
+def : InstRW<[A64FXWrite_12Cyc_GI01], (instrs DECP_ZP_D, DECP_ZP_H, DECP_ZP_S)>;
+
+// [85] "decw $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs DECW_XPiI)>;
+
+// [86] "decw $Zdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs DECW_ZPiI)>;
+
+// [87] "dup $Zd, $Rn";
+def : InstRW<[A64FXWrite_8Cyc_GI01], (instrs DUP_ZR_B, DUP_ZR_D, DUP_ZR_H, DUP_ZR_S)>;
+
+// [88] "dup $Zd, $Zn$idx";
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs DUP_ZZI_B, DUP_ZZI_D, DUP_ZZI_H, DUP_ZZI_Q, DUP_ZZI_S)>;
+
+// [89] "dup $Zd, $imm";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs DUP_ZI_B, DUP_ZI_D, DUP_ZI_H, DUP_ZI_S)>;
+
+// [90] "dupm $Zd, $imms";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs DUPM_ZI)>;
+
+// [91] "eor $Pd, $Pg/z, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs EOR_PPzPP)>;
+
+// [92] "eor $Zd, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs EOR_ZZZ)>;
+
+// [93] "eor $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs EOR_ZPmZ_B, EOR_ZPmZ_D, EOR_ZPmZ_H, EOR_ZPmZ_S)>;
+
+// [94] "eor $Zdn, $_Zdn, $imms13";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs EOR_ZI)>;
+
+// [95] "eors $Pd, $Pg/z, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs EORS_PPzPP)>;
+
+// [96] "eorv $Vd, $Pg, $Zn";
+def : InstRW<[A64FXWrite_14Cyc_GI03], (instrs EORV_VPZ_B, EORV_VPZ_D, EORV_VPZ_H, EORV_VPZ_S)>;
+
+// [97] "ext $Zdn, $_Zdn, $Zm, $imm8";
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs EXT_ZZI)>;
+
+// [99] "fabd $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FABD_ZPmZ_D, FABD_ZPmZ_H, FABD_ZPmZ_S)>;
+
+// [100] "fabs $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FABS_ZPmZ_D, FABS_ZPmZ_H, FABS_ZPmZ_S)>;
+
+// [101] "facge $Pd, $Pg/z, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FACGE_PPzZZ_D, FACGE_PPzZZ_H, FACGE_PPzZZ_S)>;
+
+// [102] "facgt $Pd, $Pg/z, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FACGT_PPzZZ_D, FACGT_PPzZZ_H, FACGT_PPzZZ_S)>;
+
+// [103] "fadd $Zd, $Zn, $Zm"; def is line 1638
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FADD_ZZZ_D, FADD_ZZZ_H, FADD_ZZZ_S)>;
+
+// [104] "fadd $Zdn, $Pg/m, $_Zdn, $Zm"; def is line 1638
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FADD_ZPmZ_D, FADD_ZPmZ_H, FADD_ZPmZ_S)>;
+
+// [105] "fadd $Zdn, $Pg/m, $_Zdn, $i1"; def is line 1638
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FADD_ZPmI_D, FADD_ZPmI_H, FADD_ZPmI_S)>;
+
+// [106] "fadda $Vdn, $Pg, $_Vdn, $Zm";
+def : InstRW<[A64FXWrite_18Cyc_GI03], (instrs FADDA_VPZ_D, FADDA_VPZ_H, FADDA_VPZ_S)>;
+
+// [107] "faddv $Vd, $Pg, $Zn";
+// H : 4 / 6 / ([1,2]9 / [1]6) x 4 / [1,2]9 = 75 cycle
+// S : 4 / 6 / ([1,2]9 / [1]6) x 3 / [1,2]9 = 60 cycle
+// D : 4 / 6 / ([1,2]9 / [1]6) x 2 / [1,2]9 = 45 cycle
+def : InstRW<[A64FXWrite_75Cyc_GI03], (instrs FADDV_VPZ_H)>;
+def : InstRW<[A64FXWrite_60Cyc_GI03], (instrs FADDV_VPZ_S)>;
+def : InstRW<[A64FXWrite_45Cyc_GI03], (instrs FADDV_VPZ_D)>;
+
+// [108] "fcadd $Zdn, $Pg/m, $_Zdn, $Zm, $imm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FCADD_ZPmZ_D, FCADD_ZPmZ_H, FCADD_ZPmZ_S)>;
+
+// [109] "fcmeq $Pd, $Pg/z, $Zn, #0.0";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMEQ_PPzZ0_D, FCMEQ_PPzZ0_H, FCMEQ_PPzZ0_S)>;
+
+// [110] "fcmeq $Pd, $Pg/z, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMEQ_PPzZZ_D, FCMEQ_PPzZZ_H, FCMEQ_PPzZZ_S)>;
+
+// [111] "fcmge $Pd, $Pg/z, $Zn, #0.0";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMGE_PPzZ0_D, FCMGE_PPzZ0_H, FCMGE_PPzZ0_S)>;
+
+// [112] "fcmge $Pd, $Pg/z, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMGE_PPzZZ_D, FCMGE_PPzZZ_H, FCMGE_PPzZZ_S)>;
+
+// [113] "fcmgt $Pd, $Pg/z, $Zn, #0.0";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMGT_PPzZ0_D, FCMGT_PPzZ0_H, FCMGT_PPzZ0_S)>;
+
+// [114] "fcmgt $Pd, $Pg/z, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMGT_PPzZZ_D, FCMGT_PPzZZ_H, FCMGT_PPzZZ_S)>;
+
+// [115] "fcmla $Zda, $Pg/m, $Zn, $Zm, $imm";
+def : InstRW<[A64FXWrite_15Cyc_GI03], (instrs FCMLA_ZPmZZ_D, FCMLA_ZPmZZ_H, FCMLA_ZPmZZ_S)>;
+
+// [116] "fcmla $Zda, $Zn, $Zm$iop, $imm";
+def : InstRW<[A64FXWrite_15Cyc_GI03], (instrs FCMLA_ZZZI_H, FCMLA_ZZZI_S)>;
+
+// [117] "fcmle $Pd, $Pg/z, $Zn, #0.0";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMLE_PPzZ0_D, FCMLE_PPzZ0_H, FCMLE_PPzZ0_S)>;
+
+// [118] "fcmlt $Pd, $Pg/z, $Zn, #0.0";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMLT_PPzZ0_D, FCMLT_PPzZ0_H, FCMLT_PPzZ0_S)>;
+
+// [119] "fcmne $Pd, $Pg/z, $Zn, #0.0";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMNE_PPzZ0_D, FCMNE_PPzZ0_H, FCMNE_PPzZ0_S)>;
+
+// [120] "fcmne $Pd, $Pg/z, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMNE_PPzZZ_D, FCMNE_PPzZZ_H, FCMNE_PPzZZ_S)>;
+
+// [121] "fcmuo $Pd, $Pg/z, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCMUO_PPzZZ_D, FCMUO_PPzZZ_H, FCMUO_PPzZZ_S)>;
+
+// [122] "fcpy $Zd, $Pg/m, $imm8";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FCPY_ZPmI_D, FCPY_ZPmI_H, FCPY_ZPmI_S)>;
+
+// [123] "fcvt $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FCVT_ZPmZ_DtoH, FCVT_ZPmZ_DtoS, FCVT_ZPmZ_HtoD, FCVT_ZPmZ_HtoS, FCVT_ZPmZ_StoD, FCVT_ZPmZ_StoH)>;
+
+// [124] "fcvtzs $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FCVTZS_ZPmZ_DtoD, FCVTZS_ZPmZ_DtoS, FCVTZS_ZPmZ_HtoD, FCVTZS_ZPmZ_HtoH, FCVTZS_ZPmZ_HtoS, FCVTZS_ZPmZ_StoD, FCVTZS_ZPmZ_StoS)>;
+
+// [125] "fcvtzu $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FCVTZU_ZPmZ_DtoD, FCVTZU_ZPmZ_DtoS, FCVTZU_ZPmZ_HtoD, FCVTZU_ZPmZ_HtoH, FCVTZU_ZPmZ_HtoS, FCVTZU_ZPmZ_StoD, FCVTZU_ZPmZ_StoS)>;
+
+// [126] "fdiv $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_154Cyc_GI0], (instrs FDIV_ZPmZ_D)>;
+def : InstRW<[A64FXWrite_134Cyc_GI0], (instrs FDIV_ZPmZ_H)>;
+def : InstRW<[A64FXWrite_98Cyc_GI0], (instrs FDIV_ZPmZ_S)>;
+
+// [127] "fdivr $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_154Cyc_GI0], (instrs FDIVR_ZPmZ_D)>;
+def : InstRW<[A64FXWrite_134Cyc_GI0], (instrs FDIVR_ZPmZ_H)>;
+def : InstRW<[A64FXWrite_98Cyc_GI0], (instrs FDIVR_ZPmZ_S)>;
+
+// [128] "fdup $Zd, $imm8";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FDUP_ZI_D, FDUP_ZI_H, FDUP_ZI_S)>;
+
+// [129] "fexpa $Zd, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FEXPA_ZZ_D, FEXPA_ZZ_H, FEXPA_ZZ_S)>;
+
+// [130] "fmad $Zdn, $Pg/m, $Zm, $Za";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FMAD_ZPmZZ_D, FMAD_ZPmZZ_H, FMAD_ZPmZZ_S)>;
+
+// [131] "fmax $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FMAX_ZPmZ_D, FMAX_ZPmZ_H, FMAX_ZPmZ_S)>;
+
+// [132] "fmax $Zdn, $Pg/m, $_Zdn, $i1";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FMAX_ZPmI_D, FMAX_ZPmI_H, FMAX_ZPmI_S)>;
+
+// [133] "fmaxnm $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FMAXNM_ZPmZ_D, FMAXNM_ZPmZ_H, FMAXNM_ZPmZ_S)>;
+
+// [134] "fmaxnm $Zdn, $Pg/m, $_Zdn, $i1";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FMAXNM_ZPmI_D, FMAXNM_ZPmI_H, FMAXNM_ZPmI_S)>;
+
+// [135] "fmaxnmv $Vd, $Pg, $Zn";
+def : InstRW<[A64FXWrite_10Cyc_GI03], (instrs FMAXNMV_VPZ_D, FMAXNMV_VPZ_H, FMAXNMV_VPZ_S)>;
+
+// [136] "fmaxv $Vd, $Pg, $Zn";
+def : InstRW<[A64FXWrite_10Cyc_GI03], (instrs FMAXV_VPZ_D, FMAXV_VPZ_H, FMAXV_VPZ_S)>;
+
+// [137] "fmin $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FMIN_ZPmZ_D, FMIN_ZPmZ_H, FMIN_ZPmZ_S)>;
+
+// [138] "fmin $Zdn, $Pg/m, $_Zdn, $i1";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FMIN_ZPmI_D, FMIN_ZPmI_H, FMIN_ZPmI_S)>;
+
+// [139] "fminnm $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FMINNM_ZPmZ_D, FMINNM_ZPmZ_H, FMINNM_ZPmZ_S)>;
+
+// [140] "fminnm $Zdn, $Pg/m, $_Zdn, $i1";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs FMINNM_ZPmI_D, FMINNM_ZPmI_H, FMINNM_ZPmI_S)>;
+
+// [141] "fminnmv $Vd, $Pg, $Zn";
+def : InstRW<[A64FXWrite_10Cyc_GI03], (instrs FMINNMV_VPZ_D, FMINNMV_VPZ_H, FMINNMV_VPZ_S)>;
+
+// [142] "fminv $Vd, $Pg, $Zn";
+def : InstRW<[A64FXWrite_10Cyc_GI03], (instrs FMINV_VPZ_D, FMINV_VPZ_H, FMINV_VPZ_S)>;
+
+// [143] "fmla $Zda, $Pg/m, $Zn, $Zm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FMLA_ZPmZZ_D, FMLA_ZPmZZ_H, FMLA_ZPmZZ_S)>;
+
+// [144] "fmla $Zda, $Zn, $Zm$iop";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FMLA_ZZZI_D, FMLA_ZZZI_H, FMLA_ZZZI_S)>;
+
+// [145] "fmls $Zda, $Pg/m, $Zn, $Zm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FMLS_ZPmZZ_D, FMLS_ZPmZZ_H, FMLS_ZPmZZ_S)>;
+
+// [146] "fmls $Zda, $Zn, $Zm$iop";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FMLS_ZZZI_D, FMLS_ZZZI_H, FMLS_ZZZI_S)>;
+
+// [147] "fmsb $Zdn, $Pg/m, $Zm, $Za";
+
+// [148] "fmul $Zd, $Zn, $Zm";
+
+// [149] "fmul $Zd, $Zn, $Zm$iop";
+
+// [150] "fmul $Zdn, $Pg/m, $_Zdn, $Zm";
+
+// [151] "fmul $Zdn, $Pg/m, $_Zdn, $i1";
+
+// [152] "fmulx $Zdn, $Pg/m, $_Zdn, $Zm";
+
+// [153] "fneg $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FNEG_ZPmZ_D, FNEG_ZPmZ_H, FNEG_ZPmZ_S)>;
+
+// [154] "fnmad $Zdn, $Pg/m, $Zm, $Za";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FNMAD_ZPmZZ_D, FNMAD_ZPmZZ_H, FNMAD_ZPmZZ_S)>;
+
+// [155] "fnmla $Zda, $Pg/m, $Zn, $Zm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FNMLA_ZPmZZ_D, FNMLA_ZPmZZ_H, FNMLA_ZPmZZ_S)>;
+
+// [156] "fnmls $Zda, $Pg/m, $Zn, $Zm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FNMLS_ZPmZZ_D, FNMLS_ZPmZZ_H, FNMLS_ZPmZZ_S)>;
+
+// [157] "fnmsb $Zdn, $Pg/m, $Zm, $Za";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FNMSB_ZPmZZ_D, FNMSB_ZPmZZ_H, FNMSB_ZPmZZ_S)>;
+
+// [158] "frecpe $Zd, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FRECPE_ZZ_D, FRECPE_ZZ_H, FRECPE_ZZ_S)>;
+
+// [159] "frecps $Zd, $Zn, $Zm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FRECPS_ZZZ_D, FRECPS_ZZZ_H, FRECPS_ZZZ_S)>;
+
+// [160] "frecpx $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FRECPX_ZPmZ_D, FRECPX_ZPmZ_H, FRECPX_ZPmZ_S)>;
+
+// [161] "frinta $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FRINTA_ZPmZ_D, FRINTA_ZPmZ_H, FRINTA_ZPmZ_S)>;
+
+// [162] "frinti $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FRINTI_ZPmZ_D, FRINTI_ZPmZ_H, FRINTI_ZPmZ_S)>;
+
+// [163] "frintm $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FRINTM_ZPmZ_D, FRINTM_ZPmZ_H, FRINTM_ZPmZ_S)>;
+
+// [164] "frintn $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FRINTN_ZPmZ_D, FRINTN_ZPmZ_H, FRINTN_ZPmZ_S)>;
+
+// [165] "frintp $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FRINTP_ZPmZ_D, FRINTP_ZPmZ_H, FRINTP_ZPmZ_S)>;
+
+// [166] "frintx $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FRINTX_ZPmZ_D, FRINTX_ZPmZ_H, FRINTX_ZPmZ_S)>;
+
+// [167] "frintz $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FRINTZ_ZPmZ_D, FRINTZ_ZPmZ_H, FRINTZ_ZPmZ_S)>;
+
+// [168] "frsqrte $Zd, $Zn";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FRSQRTE_ZZ_D, FRSQRTE_ZZ_H, FRSQRTE_ZZ_S)>;
+
+// [169] "frsqrts $Zd, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs FRSQRTS_ZZZ_D, FRSQRTS_ZZZ_H, FRSQRTS_ZZZ_S)>;
+
+// [170] "fscale $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FSCALE_ZPmZ_D, FSCALE_ZPmZ_H, FSCALE_ZPmZ_S)>;
+
+// [171] "fsqrt $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_154Cyc_GI0], (instrs FSQRT_ZPmZ_D)>;
+def : InstRW<[A64FXWrite_134Cyc_GI0], (instrs FSQRT_ZPmZ_H)>;
+def : InstRW<[A64FXWrite_98Cyc_GI0], (instrs FSQRT_ZPmZ_S)>;
+
+// [172] "fsub $Zd, $Zn, $Zm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FSUB_ZZZ_D, FSUB_ZZZ_H, FSUB_ZZZ_S)>;
+
+// [173] "fsub $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FSUB_ZPmZ_D, FSUB_ZPmZ_H, FSUB_ZPmZ_S)>;
+
+// [174] "fsub $Zdn, $Pg/m, $_Zdn, $i1";
+def : InstRW<[A64FXWrite_9Cyc_GI0], (instrs FSUB_ZPmI_D, FSUB_ZPmI_H, FSUB_ZPmI_S)>;
+
+// [175] "fsubr $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FSUBR_ZPmZ_D, FSUBR_ZPmZ_H, FSUBR_ZPmZ_S)>;
+
+// [176] "fsubr $Zdn, $Pg/m, $_Zdn, $i1";
+def : InstRW<[A64FXWrite_9Cyc_GI0], (instrs FSUBR_ZPmI_D, FSUBR_ZPmI_H, FSUBR_ZPmI_S)>;
+
+// [177] "ftmad $Zdn, $_Zdn, $Zm, $imm3";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FTMAD_ZZI_D, FTMAD_ZZI_H, FTMAD_ZZI_S)>;
+
+// [178] "ftsmul $Zd, $Zn, $Zm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs FTSMUL_ZZZ_D, FTSMUL_ZZZ_H, FTSMUL_ZZZ_S)>;
+
+// [180] "incb $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs INCB_XPiI)>;
+
+// [181] "incd $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs INCD_XPiI)>;
+
+// [182] "incd $Zdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs INCD_ZPiI)>;
+
+// [183] "inch $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs INCH_XPiI)>;
+
+// [184] "inch $Zdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs INCH_ZPiI)>;
+
+// [185] "incp $Rdn, $Pg";
+def : InstRW<[A64FXWrite_6Cyc_GI124], (instrs INCP_XP_B, INCP_XP_D, INCP_XP_H, INCP_XP_S)>;
+
+// [186] "incp $Zdn, $Pg";
+def : InstRW<[A64FXWrite_12Cyc_GI01], (instrs INCP_ZP_D, INCP_ZP_H, INCP_ZP_S)>;
+
+// [187] "incw $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs INCW_XPiI)>;
+
+// [188] "incw $Zdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs INCW_ZPiI)>;
+
+// [189] "index $Zd, $Rn, $Rm";
+def : InstRW<[A64FXWrite_17Cyc_GI02], (instrs INDEX_RR_B, INDEX_RR_D, INDEX_RR_H, INDEX_RR_S)>;
+
+// [190] "index $Zd, $Rn, $imm5";
+def : InstRW<[A64FXWrite_21Cyc_GI02], (instrs INDEX_RI_B, INDEX_RI_D, INDEX_RI_H, INDEX_RI_S)>;
+
+// [191] "index $Zd, $imm5, $Rm";
+def : InstRW<[A64FXWrite_21Cyc_GI02], (instrs INDEX_IR_B, INDEX_IR_D, INDEX_IR_H, INDEX_IR_S)>;
+
+// [192] "index $Zd, $imm5, $imm5b";
+def : InstRW<[A64FXWrite_13Cyc_GI0], (instrs INDEX_II_B, INDEX_II_D, INDEX_II_H, INDEX_II_S)>;
+
+// [193] "insr $Zdn, $Rm";
+def : InstRW<[A64FXWrite_10Cyc_GI02], (instrs INSR_ZR_B, INSR_ZR_D, INSR_ZR_H, INSR_ZR_S)>;
+
+// [194] "insr $Zdn, $Vm";
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs INSR_ZV_B, INSR_ZV_D, INSR_ZV_H, INSR_ZV_S)>;
+
+// [195] "lasta $Rd, $Pg, $Zn";
+def : InstRW<[A64FXWrite_25Cyc_GI056], (instrs LASTA_RPZ_B, LASTA_RPZ_D, LASTA_RPZ_H, LASTA_RPZ_S)>;
+
+// [196] "lasta $Vd, $Pg, $Zn";
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs LASTA_VPZ_B, LASTA_VPZ_D, LASTA_VPZ_H, LASTA_VPZ_S)>;
+
+// [197] "lastb $Rd, $Pg, $Zn";
+def : InstRW<[A64FXWrite_25Cyc_GI056], (instrs LASTB_RPZ_B, LASTB_RPZ_D, LASTB_RPZ_H, LASTB_RPZ_S)>;
+
+// [198] "lastb $Vd, $Pg, $Zn";
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs LASTB_VPZ_B, LASTB_VPZ_D, LASTB_VPZ_H, LASTB_VPZ_S)>;
+
+// [199] "ld1b $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1B, LD1B_D, LD1B_H, LD1B_S)>;
+
+// [200] "ld1b $Zt, $Pg/z, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLD1B_D_REAL, GLD1B_D_SXTW_REAL, GLD1B_D_UXTW_REAL, GLD1B_S_SXTW_REAL, GLD1B_S_UXTW_REAL)>;
+
+// [201] "ld1b $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1B_D_IMM_REAL, LD1B_H_IMM_REAL, LD1B_IMM_REAL, LD1B_S_IMM_REAL)>;
+
+// [202] "ld1b $Zt, $Pg/z, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLD1B_D_IMM_REAL, GLD1B_S_IMM_REAL)>;
+
+// [203] "ld1d $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1D)>;
+
+// [204] "ld1d $Zt, $Pg/z, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLD1D_REAL, GLD1D_SCALED_REAL, GLD1D_SXTW_REAL, GLD1D_SXTW_SCALED_REAL, GLD1D_UXTW_REAL, GLD1D_UXTW_SCALED_REAL)>;
+
+// [205] "ld1d $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1D_IMM_REAL)>;
+
+// [206] "ld1d $Zt, $Pg/z, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLD1D_IMM_REAL)>;
+
+// [207] "ld1h $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1H, LD1H_D, LD1H_S)>;
+
+// [208] "ld1h $Zt, $Pg/z, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLD1H_D_REAL, GLD1H_D_SCALED_REAL, GLD1H_D_SXTW_REAL, GLD1H_D_SXTW_SCALED_REAL, GLD1H_D_UXTW_REAL, GLD1H_D_UXTW_SCALED_REAL, GLD1H_S_SXTW_REAL, GLD1H_S_SXTW_SCALED_REAL, GLD1H_S_UXTW_REAL, GLD1H_S_UXTW_SCALED_REAL)>;
+
+// [209] "ld1h $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1H_D_IMM_REAL, LD1H_IMM_REAL, LD1H_S_IMM_REAL)>;
+
+// [210] "ld1h $Zt, $Pg/z, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLD1H_D_IMM_REAL, GLD1H_S_IMM_REAL)>;
+
+// [211] "ld1rb $Zt, $Pg/z, [$Rn, $imm6]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RB_D_IMM, LD1RB_H_IMM, LD1RB_IMM, LD1RB_S_IMM)>;
+
+// [212] "ld1rd $Zt, $Pg/z, [$Rn, $imm6]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RD_IMM)>;
+
+// [213] "ld1rh $Zt, $Pg/z, [$Rn, $imm6]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RH_D_IMM, LD1RH_IMM, LD1RH_S_IMM)>;
+
+// [214] "ld1rqb $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RQ_B)>;
+
+// [215] "ld1rqb $Zt, $Pg/z, [$Rn, $imm4]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RQ_B_IMM)>;
+
+// [216] "ld1rqd $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RQ_D)>;
+
+// [217] "ld1rqd $Zt, $Pg/z, [$Rn, $imm4]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RQ_D_IMM)>;
+
+// [218] "ld1rqh $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RQ_H)>;
+
+// [219] "ld1rqh $Zt, $Pg/z, [$Rn, $imm4]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RQ_H_IMM)>;
+
+// [220] "ld1rqw $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RQ_W)>;
+
+// [221] "ld1rqw $Zt, $Pg/z, [$Rn, $imm4]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RQ_W_IMM)>;
+
+// [222] "ld1rsb $Zt, $Pg/z, [$Rn, $imm6]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RSB_D_IMM, LD1RSB_H_IMM, LD1RSB_S_IMM)>;
+
+// [223] "ld1rsh $Zt, $Pg/z, [$Rn, $imm6]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RSH_D_IMM, LD1RSH_S_IMM)>;
+
+// [224] "ld1rsw $Zt, $Pg/z, [$Rn, $imm6]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RSW_IMM)>;
+
+// [225] "ld1rw $Zt, $Pg/z, [$Rn, $imm6]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1RW_D_IMM, LD1RW_IMM)>;
+
+// [226] "ld1sb $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1SB_D, LD1SB_H, LD1SB_S)>;
+
+// [227] "ld1sb $Zt, $Pg/z, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLD1SB_D_REAL, GLD1SB_D_SXTW_REAL, GLD1SB_D_UXTW_REAL, GLD1SB_S_SXTW_REAL, GLD1SB_S_UXTW_REAL)>;
+
+// [228] "ld1sb $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1SB_D_IMM_REAL, LD1SB_H_IMM_REAL, LD1SB_S_IMM_REAL)>;
+
+// [229] "ld1sb $Zt, $Pg/z, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLD1SB_D_IMM_REAL, GLD1SB_S_IMM_REAL)>;
+
+// [230] "ld1sh $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1SH_D, LD1SH_S)>;
+
+// [231] "ld1sh $Zt, $Pg/z, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLD1SH_D_REAL, GLD1SH_D_SCALED_REAL, GLD1SH_D_SXTW_REAL, GLD1SH_D_SXTW_SCALED_REAL, GLD1SH_D_UXTW_REAL, GLD1SH_D_UXTW_SCALED_REAL, GLD1SH_S_SXTW_REAL, GLD1SH_S_SXTW_SCALED_REAL, GLD1SH_S_UXTW_REAL, GLD1SH_S_UXTW_SCALED_REAL)>;
+
+// [232] "ld1sh $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1SH_D_IMM_REAL, LD1SH_S_IMM_REAL)>;
+
+// [233] "ld1sh $Zt, $Pg/z, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLD1SH_D_IMM_REAL, GLD1SH_S_IMM_REAL)>;
+
+// [234] "ld1sw $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1SW_D)>;
+
+// [235] "ld1sw $Zt, $Pg/z, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLD1SW_D_REAL, GLD1SW_D_SCALED_REAL, GLD1SW_D_SXTW_REAL, GLD1SW_D_SXTW_SCALED_REAL, GLD1SW_D_UXTW_REAL, GLD1SW_D_UXTW_SCALED_REAL)>;
+
+// [236] "ld1sw $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1SW_D_IMM_REAL)>;
+
+// [237] "ld1sw $Zt, $Pg/z, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLD1SW_D_IMM_REAL)>;
+
+// [238] "ld1w $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1W, LD1W_D)>;
+
+// [239] "ld1w $Zt, $Pg/z, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLD1W_D_REAL, GLD1W_D_SCALED_REAL, GLD1W_D_SXTW_REAL, GLD1W_D_SXTW_SCALED_REAL, GLD1W_D_UXTW_REAL, GLD1W_D_UXTW_SCALED_REAL, GLD1W_SXTW_REAL, GLD1W_SXTW_SCALED_REAL, GLD1W_UXTW_REAL, GLD1W_UXTW_SCALED_REAL)>;
+
+// [240] "ld1w $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD1W_D_IMM_REAL, LD1W_IMM_REAL)>;
+
+// [241] "ld1w $Zt, $Pg/z, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLD1W_D_IMM_REAL, GLD1W_IMM_REAL)>;
+
+// [242] "ld2b $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD2B)>;
+
+// [243] "ld2b $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD2B_IMM)>;
+
+// [244] "ld2d $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD2D)>;
+
+// [245] "ld2d $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD2D_IMM)>;
+
+// [246] "ld2h $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD2H)>;
+
+// [247] "ld2h $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD2H_IMM)>;
+
+// [248] "ld2w $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD2W)>;
+
+// [249] "ld2w $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD2W_IMM)>;
+
+// [250] "ld3b $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD3B)>;
+
+// [251] "ld3b $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD3B_IMM)>;
+
+// [252] "ld3d $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD3D)>;
+
+// [253] "ld3d $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD3D_IMM)>;
+
+// [254] "ld3h $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD3H)>;
+
+// [255] "ld3h $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD3H_IMM)>;
+
+// [256] "ld3w $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD3W)>;
+
+// [257] "ld3w $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD3W_IMM)>;
+
+// [258] "ld4b $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD4B)>;
+
+// [259] "ld4b $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_44Cyc_GI56], (instrs LD4B_IMM)>;
+
+// [260] "ld4d $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD4D)>;
+
+// [261] "ld4d $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD4D_IMM)>;
+
+// [262] "ld4h $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD4H)>;
+
+// [263] "ld4h $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD4H_IMM)>;
+
+// [264] "ld4w $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD4W)>;
+
+// [265] "ld4w $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LD4W_IMM)>;
+
+// [266] "ldff1b $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDFF1B_D_REAL, LDFF1B_H_REAL, LDFF1B_REAL, LDFF1B_S_REAL)>;
+
+// [267] "ldff1b $Zt, $Pg/z, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLDFF1B_D_REAL, GLDFF1B_D_SXTW_REAL, GLDFF1B_D_UXTW_REAL, GLDFF1B_S_SXTW_REAL, GLDFF1B_S_UXTW_REAL)>;
+
+// [268] "ldff1b $Zt, $Pg/z, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLDFF1B_D_IMM_REAL, GLDFF1B_S_IMM_REAL)>;
+
+// [269] "ldff1d $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDFF1D_REAL)>;
+
+// [270] "ldff1d $Zt, $Pg/z, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLDFF1D_REAL, GLDFF1D_SCALED_REAL, GLDFF1D_SXTW_REAL, GLDFF1D_SXTW_SCALED_REAL, GLDFF1D_UXTW_REAL, GLDFF1D_UXTW_SCALED_REAL)>;
+
+// [271] "ldff1d $Zt, $Pg/z, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLDFF1D_IMM_REAL)>;
+
+// [272] "ldff1h $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDFF1H_D_REAL, LDFF1H_REAL, LDFF1H_S_REAL)>;
+
+// [273] "ldff1h $Zt, $Pg/z, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLDFF1H_D_REAL, GLDFF1H_D_SCALED_REAL, GLDFF1H_D_SXTW_REAL, GLDFF1H_D_SXTW_SCALED_REAL, GLDFF1H_D_UXTW_REAL, GLDFF1H_D_UXTW_SCALED_REAL, GLDFF1H_S_SXTW_REAL, GLDFF1H_S_SXTW_SCALED_REAL, GLDFF1H_S_UXTW_REAL, GLDFF1H_S_UXTW_SCALED_REAL)>;
+
+// [274] "ldff1h $Zt, $Pg/z, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLDFF1H_D_IMM_REAL, GLDFF1H_S_IMM_REAL)>;
+
+// [275] "ldff1sb $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDFF1SB_D_REAL, LDFF1SB_H_REAL, LDFF1SB_S_REAL)>;
+
+// [276] "ldff1sb $Zt, $Pg/z, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLDFF1SB_D_REAL, GLDFF1SB_D_SXTW_REAL, GLDFF1SB_D_UXTW_REAL, GLDFF1SB_S_SXTW_REAL, GLDFF1SB_S_UXTW_REAL)>;
+
+// [277] "ldff1sb $Zt, $Pg/z, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLDFF1SB_D_IMM_REAL, GLDFF1SB_S_IMM_REAL)>;
+
+// [278] "ldff1sh $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDFF1SH_D_REAL, LDFF1SH_S_REAL)>;
+
+// [279] "ldff1sh $Zt, $Pg/z, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLDFF1SH_D_REAL, GLDFF1SH_D_SCALED_REAL, GLDFF1SH_D_SXTW_REAL, GLDFF1SH_D_SXTW_SCALED_REAL, GLDFF1SH_D_UXTW_REAL, GLDFF1SH_D_UXTW_SCALED_REAL, GLDFF1SH_S_SXTW_REAL, GLDFF1SH_S_SXTW_SCALED_REAL, GLDFF1SH_S_UXTW_REAL, GLDFF1SH_S_UXTW_SCALED_REAL)>;
+
+// [280] "ldff1sh $Zt, $Pg/z, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLDFF1SH_D_IMM_REAL, GLDFF1SH_S_IMM_REAL)>;
+
+// [281] "ldff1sw $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDFF1SW_D_REAL)>;
+
+// [282] "ldff1sw $Zt, $Pg/z, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLDFF1SW_D_REAL, GLDFF1SW_D_SCALED_REAL, GLDFF1SW_D_SXTW_REAL, GLDFF1SW_D_SXTW_SCALED_REAL, GLDFF1SW_D_UXTW_REAL, GLDFF1SW_D_UXTW_SCALED_REAL)>;
+
+// [283] "ldff1sw $Zt, $Pg/z, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLDFF1SW_D_IMM_REAL)>;
+
+// [284] "ldff1w $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDFF1W_D_REAL, LDFF1W_REAL)>;
+
+// [285] "ldff1w $Zt, $Pg/z, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_19Cyc_GI0256], (instrs GLDFF1W_D_REAL, GLDFF1W_D_SCALED_REAL, GLDFF1W_D_SXTW_REAL, GLDFF1W_D_SXTW_SCALED_REAL, GLDFF1W_D_UXTW_REAL, GLDFF1W_D_UXTW_SCALED_REAL, GLDFF1W_SXTW_REAL, GLDFF1W_SXTW_SCALED_REAL, GLDFF1W_UXTW_REAL, GLDFF1W_UXTW_SCALED_REAL)>;
+
+// [286] "ldff1w $Zt, $Pg/z, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_15Cyc_GI056], (instrs GLDFF1W_D_IMM_REAL, GLDFF1W_IMM_REAL)>;
+
+// [287] "ldnf1b $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNF1B_D_IMM_REAL, LDNF1B_H_IMM_REAL, LDNF1B_IMM_REAL, LDNF1B_S_IMM_REAL)>;
+
+// [288] "ldnf1d $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNF1D_IMM_REAL)>;
+
+// [289] "ldnf1h $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNF1H_D_IMM_REAL, LDNF1H_IMM_REAL, LDNF1H_S_IMM_REAL)>;
+
+// [290] "ldnf1sb $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNF1SB_D_IMM_REAL, LDNF1SB_H_IMM_REAL, LDNF1SB_S_IMM_REAL)>;
+
+// [291] "ldnf1sh $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNF1SH_D_IMM_REAL, LDNF1SH_S_IMM_REAL)>;
+
+// [292] "ldnf1sw $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNF1SW_D_IMM_REAL)>;
+
+// [293] "ldnf1w $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNF1W_D_IMM_REAL, LDNF1W_IMM_REAL)>;
+
+// [294] "ldnt1b $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNT1B_ZRR)>;
+
+// [295] "ldnt1b $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNT1B_ZRI)>;
+
+// [296] "ldnt1d $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNT1D_ZRR)>;
+
+// [297] "ldnt1d $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNT1D_ZRI)>;
+
+// [298] "ldnt1h $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNT1H_ZRR)>;
+
+// [299] "ldnt1h $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNT1H_ZRI)>;
+
+// [300] "ldnt1w $Zt, $Pg/z, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNT1W_ZRR)>;
+
+// [301] "ldnt1w $Zt, $Pg/z, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI56], (instrs LDNT1W_ZRI)>;
+
+// [302] "ldr $Pt, [$Rn, $imm9, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI5], (instrs LDR_PXI)>;
+
+// [303] "ldr $Zt, [$Rn, $imm9, mul vl]";
+def : InstRW<[A64FXWrite_11Cyc_GI5], (instrs LDR_ZXI)>;
+
+// [304] "lsl $Zd, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSL_WIDE_ZZZ_B, LSL_WIDE_ZZZ_H, LSL_WIDE_ZZZ_S)>;
+
+// [305] "lsl $Zd, $Zn, $imm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSL_ZZI_B, LSL_ZZI_D, LSL_ZZI_H, LSL_ZZI_S)>;
+
+// [306] "lsl $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSL_WIDE_ZPmZ_B, LSL_WIDE_ZPmZ_H, LSL_WIDE_ZPmZ_S, LSL_ZPmZ_B, LSL_ZPmZ_D, LSL_ZPmZ_H, LSL_ZPmZ_S)>;
+
+// [307] "lsl $Zdn, $Pg/m, $_Zdn, $imm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSL_ZPmI_B, LSL_ZPmI_D, LSL_ZPmI_H, LSL_ZPmI_S)>;
+
+// [308] "lslr $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSLR_ZPmZ_B, LSLR_ZPmZ_D, LSLR_ZPmZ_H, LSLR_ZPmZ_S)>;
+
+// [309] "lsr $Zd, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSR_WIDE_ZZZ_B, LSR_WIDE_ZZZ_H, LSR_WIDE_ZZZ_S)>;
+
+// [310] "lsr $Zd, $Zn, $imm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSR_ZZI_B, LSR_ZZI_D, LSR_ZZI_H, LSR_ZZI_S)>;
+
+// [311] "lsr $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSR_WIDE_ZPmZ_B, LSR_WIDE_ZPmZ_H, LSR_WIDE_ZPmZ_S, LSR_ZPmZ_B, LSR_ZPmZ_D, LSR_ZPmZ_H, LSR_ZPmZ_S)>;
+
+// [312] "lsr $Zdn, $Pg/m, $_Zdn, $imm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSR_ZPmI_B, LSR_ZPmI_D, LSR_ZPmI_H, LSR_ZPmI_S)>;
+
+// [313] "lsrr $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs LSRR_ZPmZ_B, LSRR_ZPmZ_D, LSRR_ZPmZ_H, LSRR_ZPmZ_S)>;
+
+// [314] "mad $Zdn, $Pg/m, $Zm, $Za";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs MAD_ZPmZZ_B, MAD_ZPmZZ_D, MAD_ZPmZZ_H, MAD_ZPmZZ_S)>;
+
+// [315] "mla $Zda, $Pg/m, $Zn, $Zm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs MLA_ZPmZZ_B, MLA_ZPmZZ_D, MLA_ZPmZZ_H, MLA_ZPmZZ_S)>;
+
+// [316] "mls $Zda, $Pg/m, $Zn, $Zm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs MLS_ZPmZZ_B, MLS_ZPmZZ_D, MLS_ZPmZZ_H, MLS_ZPmZZ_S)>;
+
+// [317] "movprfx $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs MOVPRFX_ZPmZ_B, MOVPRFX_ZPmZ_D, MOVPRFX_ZPmZ_H, MOVPRFX_ZPmZ_S)>;
+
+// [318] "movprfx $Zd, $Pg/z, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs MOVPRFX_ZPzZ_B, MOVPRFX_ZPzZ_D, MOVPRFX_ZPzZ_H, MOVPRFX_ZPzZ_S)>;
+
+// [319] "movprfx $Zd, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs MOVPRFX_ZZ)>;
+
+// [320] "msb $Zdn, $Pg/m, $Zm, $Za";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs MSB_ZPmZZ_B, MSB_ZPmZZ_D, MSB_ZPmZZ_H, MSB_ZPmZZ_S)>;
+
+// [321] "mul $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs MUL_ZPmZ_B, MUL_ZPmZ_D, MUL_ZPmZ_H, MUL_ZPmZ_S)>;
+
+// [322] "mul $Zdn, $_Zdn, $imm";
+def : InstRW<[A64FXWrite_9Cyc_GI0], (instrs MUL_ZI_B, MUL_ZI_D, MUL_ZI_H, MUL_ZI_S)>;
+
+// [323] "nand $Pd, $Pg/z, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs NAND_PPzPP)>;
+
+// [324] "nands $Pd, $Pg/z, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs NANDS_PPzPP)>;
+
+// [325] "neg $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs NEG_ZPmZ_B, NEG_ZPmZ_D, NEG_ZPmZ_H, NEG_ZPmZ_S)>;
+
+// [326] "nor $Pd, $Pg/z, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs NOR_PPzPP)>;
+
+// [327] "nors $Pd, $Pg/z, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs NORS_PPzPP)>;
+
+// [328] "not $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs NOT_ZPmZ_B, NOT_ZPmZ_D, NOT_ZPmZ_H, NOT_ZPmZ_S)>;
+
+// [329] "orn $Pd, $Pg/z, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs ORN_PPzPP)>;
+
+// [330] "orns $Pd, $Pg/z, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs ORNS_PPzPP)>;
+
+// [331] "orr $Pd, $Pg/z, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs ORR_PPzPP)>;
+
+// [332] "orr $Zd, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ORR_ZZZ)>;
+
+// [333] "orr $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs ORR_ZPmZ_B, ORR_ZPmZ_D, ORR_ZPmZ_H, ORR_ZPmZ_S)>;
+
+// [334] "orr $Zdn, $_Zdn, $imms13";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs ORR_ZI)>;
+
+// [335] "orrs $Pd, $Pg/z, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs ORRS_PPzPP)>;
+
+// [336] "orv $Vd, $Pg, $Zn";
+def : InstRW<[A64FXWrite_14Cyc_GI03], (instrs ORV_VPZ_B, ORV_VPZ_D, ORV_VPZ_H, ORV_VPZ_S)>;
+
+// [337] "pfalse $Pd";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs PFALSE)>;
+
+// [338] "pnext $Pdn, $Pg, $_Pdn";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs PNEXT_B, PNEXT_D, PNEXT_H, PNEXT_S)>;
+
+// [339] "prfb $prfop, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_6Cyc_GI56], (instrs PRFB_PRR)>;
+
+// [340] "prfb $prfop, $Pg, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_14Cyc_GI0256], (instrs PRFB_D_SCALED, PRFB_D_SXTW_SCALED, PRFB_D_UXTW_SCALED, PRFB_S_SXTW_SCALED, PRFB_S_UXTW_SCALED)>;
+
+// [341] "prfb $prfop, $Pg, [$Rn, $imm6, mul vl]";
+def : InstRW<[A64FXWrite_6Cyc_GI56], (instrs PRFB_PRI)>;
+
+// [342] "prfb $prfop, $Pg, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_10Cyc_GI056], (instrs PRFB_D_PZI, PRFB_S_PZI)>;
+
+// [343] "prfd $prfop, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_6Cyc_GI56], (instrs PRFD_PRR)>;
+
+// [344] "prfd $prfop, $Pg, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_14Cyc_GI0256], (instrs PRFD_D_SCALED, PRFD_D_SXTW_SCALED, PRFD_D_UXTW_SCALED, PRFD_S_SXTW_SCALED, PRFD_S_UXTW_SCALED)>;
+
+// [345] "prfd $prfop, $Pg, [$Rn, $imm6, mul vl]";
+def : InstRW<[A64FXWrite_6Cyc_GI56], (instrs PRFD_PRI)>;
+
+// [346] "prfd $prfop, $Pg, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_10Cyc_GI056], (instrs PRFD_D_PZI, PRFD_S_PZI)>;
+
+// [347] "prfh $prfop, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_6Cyc_GI56], (instrs PRFH_PRR)>;
+
+// [348] "prfh $prfop, $Pg, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_14Cyc_GI0256], (instrs PRFH_D_SCALED, PRFH_D_SXTW_SCALED, PRFH_D_UXTW_SCALED, PRFH_S_SXTW_SCALED, PRFH_S_UXTW_SCALED)>;
+
+// [349] "prfh $prfop, $Pg, [$Rn, $imm6, mul vl]";
+def : InstRW<[A64FXWrite_6Cyc_GI56], (instrs PRFH_PRI)>;
+
+// [350] "prfh $prfop, $Pg, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_10Cyc_GI056], (instrs PRFH_D_PZI, PRFH_S_PZI)>;
+
+// [351] "prfw $prfop, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_6Cyc_GI56], (instrs PRFS_PRR)>;
+
+// [352] "prfw $prfop, $Pg, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_14Cyc_GI0256], (instrs PRFW_D_SCALED, PRFW_D_SXTW_SCALED, PRFW_D_UXTW_SCALED, PRFW_S_SXTW_SCALED, PRFW_S_UXTW_SCALED)>;
+
+// [353] "prfw $prfop, $Pg, [$Rn, $imm6, mul vl]";
+def : InstRW<[A64FXWrite_6Cyc_GI56], (instrs PRFW_PRI)>;
+
+// [354] "prfw $prfop, $Pg, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_10Cyc_GI056], (instrs PRFW_D_PZI, PRFW_S_PZI)>;
+
+// [355] "ptest $Pg, $Pn";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs PTEST_PP)>;
+
+// [356] "ptrue $Pd, $pattern";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs PTRUE_B, PTRUE_D, PTRUE_H, PTRUE_S)>;
+
+// [357] "ptrues $Pd, $pattern";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs PTRUES_B, PTRUES_D, PTRUES_H, PTRUES_S)>;
+
+// [358] "punpkhi $Pd, $Pn";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs PUNPKHI_PP)>;
+
+// [359] "punpklo $Pd, $Pn";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs PUNPKLO_PP)>;
+
+// [360] "rbit $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs RBIT_ZPmZ_B, RBIT_ZPmZ_D, RBIT_ZPmZ_H, RBIT_ZPmZ_S)>;
+
+// [361] "rdffr $Pd";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs RDFFR_P)>;
+
+// [362] "rdffr $Pd, $Pg/z";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs RDFFR_PPz)>;
+
+// [363] "rdffrs $Pd, $Pg/z";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs RDFFRS_PPz)>;
+
+// [364] "rdvl $Rd, $imm6";
+def : InstRW<[A64FXWrite_1Cyc_GI24], (instrs RDVLI_XI)>;
+
+// [365] "rev $Pd, $Pn";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs REV_PP_B, REV_PP_D, REV_PP_H, REV_PP_S)>;
+
+// [366] "rev $Zd, $Zn";
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs REV_ZZ_B, REV_ZZ_D, REV_ZZ_H, REV_ZZ_S)>;
+
+// [367] "revb $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs REVB_ZPmZ_D, REVB_ZPmZ_H, REVB_ZPmZ_S)>;
+
+// [368] "revh $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs REVH_ZPmZ_D, REVH_ZPmZ_S)>;
+
+// [369] "revw $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs REVW_ZPmZ_D)>;
+
+// [370] "sabd $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SABD_ZPmZ_B, SABD_ZPmZ_D, SABD_ZPmZ_H, SABD_ZPmZ_S)>;
+
+// [371] "saddv $Vd, $Pg, $Zn";
+def : InstRW<[A64FXWrite_12Cyc_GI03], (instrs SADDV_VPZ_B, SADDV_VPZ_H, SADDV_VPZ_S)>;
+
+// [372] "scvtf $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs SCVTF_ZPmZ_DtoD, SCVTF_ZPmZ_DtoH, SCVTF_ZPmZ_DtoS, SCVTF_ZPmZ_HtoH, SCVTF_ZPmZ_StoD, SCVTF_ZPmZ_StoH, SCVTF_ZPmZ_StoS)>;
+
+// [373] "sdiv $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_37Cyc_GI0], (instrs SDIV_ZPmZ_D, SDIV_ZPmZ_S)>;
+
+// [374] "sdivr $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_37Cyc_GI0], (instrs SDIVR_ZPmZ_D, SDIVR_ZPmZ_S)>;
+
+// [375] "sdot $Zda, $Zn, $Zm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs SDOT_ZZZ_D, SDOT_ZZZ_S)>;
+
+// [376] "sdot $Zda, $Zn, $Zm$iop";
+def : InstRW<[A64FXWrite_15Cyc_NGI03], (instrs SDOT_ZZZI_D, SDOT_ZZZI_S)>;
+
+// [377] "sel $Pd, $Pg, $Pn, $Pm";
+def : InstRW<[A64FXWrite_3Cyc_GI1], (instrs SEL_PPPP)>;
+
+// [378] "sel $Zd, $Pg, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SEL_ZPZZ_B, SEL_ZPZZ_D, SEL_ZPZZ_H, SEL_ZPZZ_S)>;
+
+// [379] "setffr";
+def : InstRW<[A64FXWrite_6Cyc], (instrs SETFFR)>;
+
+// [380] "smax $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SMAX_ZPmZ_B, SMAX_ZPmZ_D, SMAX_ZPmZ_H, SMAX_ZPmZ_S)>;
+
+// [381] "smax $Zdn, $_Zdn, $imm";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs SMAX_ZI_B, SMAX_ZI_D, SMAX_ZI_H, SMAX_ZI_S)>;
+
+// [382] "smaxv $Vd, $Pg, $Zn";
+def : InstRW<[A64FXWrite_14Cyc_GI03], (instrs SMAXV_VPZ_B, SMAXV_VPZ_D, SMAXV_VPZ_H, SMAXV_VPZ_S)>;
+
+// [383] "smin $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SMIN_ZPmZ_B, SMIN_ZPmZ_D, SMIN_ZPmZ_H, SMIN_ZPmZ_S)>;
+
+// [384] "smin $Zdn, $_Zdn, $imm";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs SMIN_ZI_B, SMIN_ZI_D, SMIN_ZI_H, SMIN_ZI_S)>;
+
+// [385] "sminv $Vd, $Pg, $Zn";
+def : InstRW<[A64FXWrite_14Cyc_GI03], (instrs SMINV_VPZ_B, SMINV_VPZ_D, SMINV_VPZ_H, SMINV_VPZ_S)>;
+
+// [386] "smulh $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs SMULH_ZPmZ_B, SMULH_ZPmZ_D, SMULH_ZPmZ_H, SMULH_ZPmZ_S)>;
+
+// [387] "splice $Zdn, $Pg, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs SPLICE_ZPZ_B, SPLICE_ZPZ_D, SPLICE_ZPZ_H, SPLICE_ZPZ_S)>;
+
+// [388] "sqadd $Zd, $Zn, $Zm";
+
+// [389] "sqadd $Zdn, $_Zdn, $imm";
+
+// [390] "sqdecb $Rdn, $_Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQDECB_XPiWdI)>;
+
+// [391] "sqdecb $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQDECB_XPiI)>;
+
+// [392] "sqdecd $Rdn, $_Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQDECD_XPiWdI)>;
+
+// [393] "sqdecd $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQDECD_XPiI)>;
+
+// [394] "sqdecd $Zdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SQDECD_ZPiI)>;
+
+// [395] "sqdech $Rdn, $_Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQDECH_XPiWdI)>;
+
+// [396] "sqdech $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQDECH_XPiI)>;
+
+// [397] "sqdech $Zdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SQDECH_ZPiI)>;
+
+// [398] "sqdecp $Rdn, $Pg";
+def : InstRW<[A64FXWrite_8Cyc_GI124], (instrs SQDECP_XP_B, SQDECP_XP_D, SQDECP_XP_H, SQDECP_XP_S)>;
+
+// [399] "sqdecp $Rdn, $Pg, $_Rdn";
+def : InstRW<[A64FXWrite_8Cyc_GI124], (instrs SQDECP_XPWd_B, SQDECP_XPWd_D, SQDECP_XPWd_H, SQDECP_XPWd_S)>;
+
+// [400] "sqdecp $Zdn, $Pg";
+def : InstRW<[A64FXWrite_12Cyc_GI01], (instrs SQDECP_ZP_D, SQDECP_ZP_H, SQDECP_ZP_S)>;
+
+// [401] "sqdecw $Rdn, $_Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQDECW_XPiWdI)>;
+
+// [402] "sqdecw $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQDECW_XPiI)>;
+
+// [403] "sqdecw $Zdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SQDECW_ZPiI)>;
+
+// [404] "sqincb $Rdn, $_Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQINCB_XPiWdI)>;
+
+// [405] "sqincb $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQINCB_XPiI)>;
+
+// [406] "sqincd $Rdn, $_Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQINCD_XPiWdI)>;
+
+// [407] "sqincd $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQINCD_XPiI)>;
+
+// [408] "sqincd $Zdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SQINCD_ZPiI)>;
+
+// [409] "sqinch $Rdn, $_Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQINCH_XPiWdI)>;
+
+// [410] "sqinch $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQINCH_XPiI)>;
+
+// [411] "sqinch $Zdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SQINCH_ZPiI)>;
+
+// [412] "sqincp $Rdn, $Pg";
+def : InstRW<[A64FXWrite_8Cyc_GI124], (instrs SQINCP_XP_B, SQINCP_XP_D, SQINCP_XP_H, SQINCP_XP_S)>;
+
+// [413] "sqincp $Rdn, $Pg, $_Rdn";
+def : InstRW<[A64FXWrite_8Cyc_GI124], (instrs SQINCP_XPWd_B, SQINCP_XPWd_D, SQINCP_XPWd_H, SQINCP_XPWd_S)>;
+
+// [414] "sqincp $Zdn, $Pg";
+def : InstRW<[A64FXWrite_12Cyc_GI01], (instrs SQINCP_ZP_D, SQINCP_ZP_H, SQINCP_ZP_S)>;
+
+// [415] "sqincw $Rdn, $_Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQINCW_XPiWdI)>;
+
+// [416] "sqincw $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs SQINCW_XPiI)>;
+
+// [417] "sqincw $Zdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SQINCW_ZPiI)>;
+
+// [418] "sqsub $Zd, $Zn, $Zm";
+
+// [419] "sqsub $Zdn, $_Zdn, $imm";
+
+// [420] "st1b $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST1W_6], (instrs ST1B, ST1B_D, ST1B_H, ST1B_S)>;
+
+// [421] "st1b $Zt, $Pg, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_ST1W_19], (instrs SST1B_D_REAL, SST1B_D_SXTW, SST1B_D_UXTW, SST1B_S_SXTW, SST1B_S_UXTW)>;
+
+// [422] "st1b $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST1W_6], (instrs ST1B_D_IMM, ST1B_H_IMM, ST1B_IMM, ST1B_S_IMM)>;
+
+// [423] "st1b $Zt, $Pg, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_ST1W_15], (instrs SST1B_D_IMM, SST1B_S_IMM)>;
+
+// [424] "st1d $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST1W_6], (instrs ST1D)>;
+
+// [425] "st1d $Zt, $Pg, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_ST1W_19], (instrs SST1D_REAL, SST1D_SCALED_SCALED_REAL, SST1D_SXTW, SST1D_SXTW_SCALED, SST1D_UXTW, SST1D_UXTW_SCALED)>;
+
+// [426] "st1d $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST1W_6], (instrs ST1D_IMM)>;
+
+// [427] "st1d $Zt, $Pg, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_ST1W_15], (instrs SST1D_IMM)>;
+
+// [428] "st1h $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST1W_6], (instrs ST1H, ST1H_D, ST1H_S)>;
+
+// [429] "st1h $Zt, $Pg, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_ST1W_19], (instrs SST1H_D_REAL, SST1H_D_SCALED_SCALED_REAL, SST1H_D_SXTW, SST1H_D_SXTW_SCALED, SST1H_D_UXTW, SST1H_D_UXTW_SCALED, SST1H_S_SXTW, SST1H_S_SXTW_SCALED, SST1H_S_UXTW, SST1H_S_UXTW_SCALED)>;
+
+// [430] "st1h $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST1W_6], (instrs ST1H_D_IMM, ST1H_IMM, ST1H_S_IMM)>;
+
+// [431] "st1h $Zt, $Pg, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_ST1W_15], (instrs SST1H_D_IMM, SST1H_S_IMM)>;
+
+// [432] "st1w $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST1W_6], (instrs ST1W, ST1W_D)>;
+
+// [433] "st1w $Zt, $Pg, [$Rn, $Zm]";
+def : InstRW<[A64FXWrite_ST1W_19], (instrs SST1W_D_REAL, SST1W_D_SCALED_SCALED_REAL, SST1W_D_SXTW, SST1W_D_SXTW_SCALED, SST1W_D_UXTW, SST1W_D_UXTW_SCALED, SST1W_SXTW, SST1W_SXTW_SCALED, SST1W_UXTW, SST1W_UXTW_SCALED)>;
+
+// [434] "st1w $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST1W_6], (instrs ST1W_D_IMM, ST1W_IMM)>;
+
+// [435] "st1w $Zt, $Pg, [$Zn, $imm5]";
+def : InstRW<[A64FXWrite_ST1W_15], (instrs SST1W_D_IMM, SST1W_IMM)>;
+
+// [436] "st2b $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST2W_7], (instrs ST2B)>;
+
+// [437] "st2b $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST2W_7], (instrs ST2B_IMM)>;
+
+// [438] "st2d $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST2W_7], (instrs ST2D)>;
+
+// [439] "st2d $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST2W_7], (instrs ST2D_IMM)>;
+
+// [440] "st2h $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST2W_7], (instrs ST2H)>;
+
+// [441] "st2h $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST2W_7], (instrs ST2H_IMM)>;
+
+// [442] "st2w $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST2W_7], (instrs ST2W)>;
+
+// [443] "st2w $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST2W_7], (instrs ST2W_IMM)>;
+
+// [444] "st3b $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST3W_8], (instrs ST3B)>;
+
+// [445] "st3b $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST3W_8], (instrs ST3B_IMM)>;
+
+// [446] "st3d $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST3W_8], (instrs ST3D)>;
+
+// [447] "st3d $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST3W_8], (instrs ST3D_IMM)>;
+
+// [448] "st3h $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST3W_8], (instrs ST3H)>;
+
+// [449] "st3h $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST3W_8], (instrs ST3H_IMM)>;
+
+// [450] "st3w $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST3W_8], (instrs ST3W)>;
+
+// [451] "st3w $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST3W_8], (instrs ST3W_IMM)>;
+
+// [452] "st4b $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST4W_9], (instrs ST4B)>;
+
+// [453] "st4b $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST4W_9], (instrs ST4B_IMM)>;
+
+// [454] "st4d $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST4W_9], (instrs ST4D)>;
+
+// [455] "st4d $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST4W_9], (instrs ST4D_IMM)>;
+
+// [456] "st4h $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST4W_9], (instrs ST4H)>;
+
+// [457] "st4h $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST4W_9], (instrs ST4H_IMM)>;
+
+// [458] "st4w $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST4W_9], (instrs ST4W)>;
+
+// [459] "st4w $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST4W_9], (instrs ST4W_IMM)>;
+
+// [460] "stnt1b $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST1W_6], (instrs STNT1B_ZRR)>;
+
+// [461] "stnt1b $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST1W_6], (instrs STNT1B_ZRI)>;
+
+// [462] "stnt1d $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST1W_6], (instrs STNT1D_ZRR)>;
+
+// [463] "stnt1d $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST1W_6], (instrs STNT1D_ZRI)>;
+
+// [464] "stnt1h $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST1W_6], (instrs STNT1H_ZRR)>;
+
+// [465] "stnt1h $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST1W_6], (instrs STNT1H_ZRI)>;
+
+// [466] "stnt1w $Zt, $Pg, [$Rn, $Rm]";
+def : InstRW<[A64FXWrite_ST1W_6], (instrs STNT1W_ZRR)>;
+
+// [467] "stnt1w $Zt, $Pg, [$Rn, $imm4, mul vl]";
+def : InstRW<[A64FXWrite_ST1W_6], (instrs STNT1W_ZRI)>;
+
+// [468] "str $Pt, [$Rn, $imm9, mul vl]";
+def : InstRW<[A64FXWrite_6Cyc_GI15], (instrs STR_PXI)>;
+
+// [469] "str $Zt, [$Rn, $imm9, mul vl]";
+def : InstRW<[A64FXWrite_6Cyc_GI05], (instrs STR_ZXI)>;
+
+// [470] "sub $Zd, $Zn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SUB_ZZZ_B, SUB_ZZZ_D, SUB_ZZZ_H, SUB_ZZZ_S)>;
+
+// [471] "sub $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SUB_ZPmZ_B, SUB_ZPmZ_D, SUB_ZPmZ_H, SUB_ZPmZ_S)>;
+
+// [472] "sub $Zdn, $_Zdn, $imm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SUB_ZI_B, SUB_ZI_D, SUB_ZI_H, SUB_ZI_S)>;
+
+// [473] "subr $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SUBR_ZPmZ_B, SUBR_ZPmZ_D, SUBR_ZPmZ_H, SUBR_ZPmZ_S)>;
+
+// [474] "subr $Zdn, $_Zdn, $imm";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs SUBR_ZI_B, SUBR_ZI_D, SUBR_ZI_H, SUBR_ZI_S)>;
+
+// [475] "sunpkhi $Zd, $Zn";
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs SUNPKHI_ZZ_D, SUNPKHI_ZZ_H, SUNPKHI_ZZ_S)>;
+
+// [476] "sunpklo $Zd, $Zn";
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs SUNPKLO_ZZ_D, SUNPKLO_ZZ_H, SUNPKLO_ZZ_S)>;
+
+// [477] "sxtb $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SXTB_ZPmZ_D, SXTB_ZPmZ_H, SXTB_ZPmZ_S)>;
+
+// [478] "sxth $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SXTH_ZPmZ_D, SXTH_ZPmZ_S)>;
+
+// [479] "sxtw $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs SXTW_ZPmZ_D)>;
+
+// [480] "tbl $Zd, $Zn, $Zm";
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs TBL_ZZZ_B, TBL_ZZZ_D, TBL_ZZZ_H, TBL_ZZZ_S)>;
+
+// [481] "trn1 $Pd, $Pn, $Pm";
+
+// [482] "trn1 $Zd, $Zn, $Zm";
+
+// [483] "trn2 $Pd, $Pn, $Pm";
+
+// [484] "trn2 $Zd, $Zn, $Zm";
+
+// [486] "uabd $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UABD_ZPmZ_B, UABD_ZPmZ_D, UABD_ZPmZ_H, UABD_ZPmZ_S)>;
+
+// [487] "uaddv $Vd, $Pg, $Zn";
+def : InstRW<[A64FXWrite_12Cyc_GI03], (instrs UADDV_VPZ_B, UADDV_VPZ_D, UADDV_VPZ_H, UADDV_VPZ_S)>;
+
+// [488] "ucvtf $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs UCVTF_ZPmZ_DtoD, UCVTF_ZPmZ_DtoH, UCVTF_ZPmZ_DtoS, UCVTF_ZPmZ_HtoH, UCVTF_ZPmZ_StoD, UCVTF_ZPmZ_StoH, UCVTF_ZPmZ_StoS)>;
+
+// [489] "udiv $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_37Cyc_GI0], (instrs UDIV_ZPmZ_D, UDIV_ZPmZ_S)>;
+
+// [490] "udivr $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_37Cyc_GI0], (instrs UDIVR_ZPmZ_D, UDIVR_ZPmZ_S)>;
+
+// [491] "udot $Zda, $Zn, $Zm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs UDOT_ZZZ_D, UDOT_ZZZ_S)>;
+
+// [492] "udot $Zda, $Zn, $Zm$iop";
+def : InstRW<[A64FXWrite_15Cyc_NGI03], (instrs UDOT_ZZZI_D, UDOT_ZZZI_S)>;
+
+// [493] "umax $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UMAX_ZPmZ_B, UMAX_ZPmZ_D, UMAX_ZPmZ_H, UMAX_ZPmZ_S)>;
+
+// [494] "umax $Zdn, $_Zdn, $imm";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs UMAX_ZI_B, UMAX_ZI_D, UMAX_ZI_H, UMAX_ZI_S)>;
+
+// [495] "umaxv $Vd, $Pg, $Zn";
+def : InstRW<[A64FXWrite_14Cyc_GI03], (instrs UMAXV_VPZ_B, UMAXV_VPZ_D, UMAXV_VPZ_H, UMAXV_VPZ_S)>;
+
+// [496] "umin $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UMIN_ZPmZ_B, UMIN_ZPmZ_D, UMIN_ZPmZ_H, UMIN_ZPmZ_S)>;
+
+// [497] "umin $Zdn, $_Zdn, $imm";
+def : InstRW<[A64FXWrite_4Cyc_GI0], (instrs UMIN_ZI_B, UMIN_ZI_D, UMIN_ZI_H, UMIN_ZI_S)>;
+
+// [498] "uminv $Vd, $Pg, $Zn";
+def : InstRW<[A64FXWrite_14Cyc_GI03], (instrs UMINV_VPZ_B, UMINV_VPZ_D, UMINV_VPZ_H, UMINV_VPZ_S)>;
+
+// [499] "umulh $Zdn, $Pg/m, $_Zdn, $Zm";
+def : InstRW<[A64FXWrite_9Cyc_GI03], (instrs UMULH_ZPmZ_B, UMULH_ZPmZ_D, UMULH_ZPmZ_H, UMULH_ZPmZ_S)>;
+
+// [500] "uqadd $Zd, $Zn, $Zm";
+
+// [501] "uqadd $Zdn, $_Zdn, $imm";
+
+// [502] "uqdecb $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs UQDECB_WPiI, UQDECB_XPiI)>;
+
+// [503] "uqdecd $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs UQDECD_WPiI, UQDECD_XPiI)>;
+
+// [504] "uqdecd $Zdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UQDECD_ZPiI)>;
+
+// [505] "uqdech $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs UQDECH_WPiI, UQDECH_XPiI)>;
+
+// [506] "uqdech $Zdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UQDECH_ZPiI)>;
+
+// [507] "uqdecp $Rdn, $Pg";
+def : InstRW<[A64FXWrite_8Cyc_GI124], (instrs UQDECP_WP_B, UQDECP_WP_D, UQDECP_WP_H, UQDECP_WP_S, UQDECP_XP_B, UQDECP_XP_D, UQDECP_XP_H, UQDECP_XP_S)>;
+
+// [508] "uqdecp $Zdn, $Pg";
+def : InstRW<[A64FXWrite_12Cyc_GI01], (instrs UQDECP_ZP_D, UQDECP_ZP_H, UQDECP_ZP_S)>;
+
+// [509] "uqdecw $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs UQDECW_WPiI, UQDECW_XPiI)>;
+
+// [510] "uqdecw $Zdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UQDECW_ZPiI)>;
+
+// [511] "uqincb $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs UQINCB_WPiI, UQINCB_XPiI)>;
+
+// [512] "uqincd $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs UQINCD_WPiI, UQINCD_XPiI)>;
+
+// [513] "uqincd $Zdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UQINCD_ZPiI)>;
+
+// [514] "uqinch $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs UQINCH_WPiI, UQINCH_XPiI)>;
+
+// [515] "uqinch $Zdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UQINCH_ZPiI)>;
+
+// [516] "uqincp $Rdn, $Pg";
+def : InstRW<[A64FXWrite_8Cyc_GI124], (instrs UQINCP_WP_B, UQINCP_WP_D, UQINCP_WP_H, UQINCP_WP_S, UQINCP_XP_B, UQINCP_XP_D, UQINCP_XP_H, UQINCP_XP_S)>;
+
+// [517] "uqincp $Zdn, $Pg";
+def : InstRW<[A64FXWrite_12Cyc_GI01], (instrs UQINCP_ZP_D, UQINCP_ZP_H, UQINCP_ZP_S)>;
+
+// [518] "uqincw $Rdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_2Cyc_GI24], (instrs UQINCW_WPiI, UQINCW_XPiI)>;
+
+// [519] "uqincw $Zdn, $pattern, mul $imm4";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UQINCW_ZPiI)>;
+
+// [520] "uqsub $Zd, $Zn, $Zm";
+//@@@ def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UQSUB_ZZZ_B, UQSUB_ZZZ_D, UQSUB_ZZZ_H, UQSUB_ZZZ_S)>;
+
+// [521] "uqsub $Zdn, $_Zdn, $imm";
+//@@@ def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UQSUB_ZI_B, UQSUB_ZI_D, UQSUB_ZI_H, UQSUB_ZI_S)>;
+
+// [522] "uunpkhi $Zd, $Zn";
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs UUNPKHI_ZZ_D, UUNPKHI_ZZ_H, UUNPKHI_ZZ_S)>;
+
+// [523] "uunpklo $Zd, $Zn";
+def : InstRW<[A64FXWrite_6Cyc_GI0], (instrs UUNPKLO_ZZ_D, UUNPKLO_ZZ_H, UUNPKLO_ZZ_S)>;
+
+// [524] "uxtb $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UXTB_ZPmZ_D, UXTB_ZPmZ_H, UXTB_ZPmZ_S)>;
+
+// [525] "uxth $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UXTH_ZPmZ_D, UXTH_ZPmZ_S)>;
+
+// [526] "uxtw $Zd, $Pg/m, $Zn";
+def : InstRW<[A64FXWrite_4Cyc_GI03], (instrs UXTW_ZPmZ_D)>;
+
+// [527] "uzp1 $Pd, $Pn, $Pm";
+
+// [528] "uzp1 $Zd, $Zn, $Zm";
+
+// [529] "uzp2 $Pd, $Pn, $Pm";
+
+// [530] "uzp2 $Zd, $Zn, $Zm";
+
+// [531] "whilele $Pd, $Rn, $Rm";
+def : InstRW<[A64FXWrite_4Cyc_GI12], (instrs WHILELE_PWW_B, WHILELE_PWW_D, WHILELE_PWW_H, WHILELE_PWW_S, WHILELE_PXX_B, WHILELE_PXX_D, WHILELE_PXX_H, WHILELE_PXX_S)>;
+
+// [532] "whilelo $Pd, $Rn, $Rm";
+def : InstRW<[A64FXWrite_4Cyc_GI12], (instrs WHILELO_PWW_B, WHILELO_PWW_D, WHILELO_PWW_H, WHILELO_PWW_S, WHILELO_PXX_B, WHILELO_PXX_D, WHILELO_PXX_H, WHILELO_PXX_S)>;
+
+// [533] "whilels $Pd, $Rn, $Rm";
+def : InstRW<[A64FXWrite_4Cyc_GI12], (instrs WHILELS_PWW_B, WHILELS_PWW_D, WHILELS_PWW_H, WHILELS_PWW_S, WHILELS_PXX_B, WHILELS_PXX_D, WHILELS_PXX_H, WHILELS_PXX_S)>;
+
+// [534] "whilelt $Pd, $Rn, $Rm";
+def : InstRW<[A64FXWrite_4Cyc_GI12], (instrs WHILELT_PWW_B, WHILELT_PWW_D, WHILELT_PWW_H, WHILELT_PWW_S, WHILELT_PXX_B, WHILELT_PXX_D, WHILELT_PXX_H, WHILELT_PXX_S)>;
+
+// [535] "wrffr $Pn";
+def : InstRW<[A64FXWrite_6Cyc_NGI1], (instrs WRFFR)>;
+
+// [536] "zip1 $Pd, $Pn, $Pm";
+
+// [537] "zip1 $Zd, $Zn, $Zm";
+
+// [538] "zip2 $Pd, $Pn, $Pm";
+
+// [539] "zip2 $Zd, $Zn, $Zm";
+
+} // SchedModel = A64FXModel
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedTSV110.td b/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedTSV110.td
index 0828d8a8c9..438371c1b6 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedTSV110.td
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64SchedTSV110.td
@@ -1,745 +1,745 @@
-//==- AArch64SchedTSV110.td - Huawei TSV110 Scheduling Definitions -*- tablegen -*-=//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the machine model for Huawei TSV110 to support
-// instruction scheduling and other instruction cost heuristics.
-//
-//===----------------------------------------------------------------------===//
-
-// ===---------------------------------------------------------------------===//
-// The following definitions describe the simpler per-operand machine model.
-// This works with MachineScheduler. See llvm/MC/MCSchedule.h for details.
-
-// Huawei TSV110 scheduling machine model.
-def TSV110Model : SchedMachineModel {
- let IssueWidth = 4; // 4 micro-ops dispatched per cycle.
- let MicroOpBufferSize = 128; // 128 micro-op re-order buffer
- let LoopMicroOpBufferSize = 16;
- let LoadLatency = 4; // Optimistic load latency.
- let MispredictPenalty = 14; // Fetch + Decode/Rename/Dispatch + Branch
- let CompleteModel = 1;
-
- list<Predicate> UnsupportedFeatures = !listconcat(SVEUnsupported.F,
- PAUnsupported.F);
-}
-
-// Define each kind of processor resource and number available on the TSV110,
-// which has 8 pipelines, each with its own queue where micro-ops wait for
-// their operands and issue out-of-order to one of eight execution pipelines.
-let SchedModel = TSV110Model in {
- def TSV110UnitALU : ProcResource<1>; // Int ALU
- def TSV110UnitAB : ProcResource<2>; // Int ALU/BRU
- def TSV110UnitMDU : ProcResource<1>; // Multi-Cycle
- def TSV110UnitFSU1 : ProcResource<1>; // FP/ASIMD
- def TSV110UnitFSU2 : ProcResource<1>; // FP/ASIMD
- def TSV110UnitLdSt : ProcResource<2>; // Load/Store
-
- def TSV110UnitF : ProcResGroup<[TSV110UnitFSU1, TSV110UnitFSU2]>;
- def TSV110UnitALUAB : ProcResGroup<[TSV110UnitALU, TSV110UnitAB]>;
- def TSV110UnitFLdSt : ProcResGroup<[TSV110UnitFSU1, TSV110UnitFSU2, TSV110UnitLdSt]>;
-}
-
-let SchedModel = TSV110Model in {
-
-//===----------------------------------------------------------------------===//
-// Map the target-defined scheduler read/write resources and latency for
-// TSV110
-
-// Integer ALU
-def : WriteRes<WriteImm, [TSV110UnitALUAB]> { let Latency = 1; }
-def : WriteRes<WriteI, [TSV110UnitALUAB]> { let Latency = 1; }
-def : WriteRes<WriteISReg, [TSV110UnitMDU]> { let Latency = 2; }
-def : WriteRes<WriteIEReg, [TSV110UnitMDU]> { let Latency = 2; }
-def : WriteRes<WriteExtr, [TSV110UnitALUAB]> { let Latency = 1; }
-def : WriteRes<WriteIS, [TSV110UnitALUAB]> { let Latency = 1; }
-
-// Integer Mul/MAC/Div
-def : WriteRes<WriteID32, [TSV110UnitMDU]> { let Latency = 12;
- let ResourceCycles = [12]; }
-def : WriteRes<WriteID64, [TSV110UnitMDU]> { let Latency = 20;
- let ResourceCycles = [20]; }
-def : WriteRes<WriteIM32, [TSV110UnitMDU]> { let Latency = 3; }
-def : WriteRes<WriteIM64, [TSV110UnitMDU]> { let Latency = 4; }
-
-// Load
-def : WriteRes<WriteLD, [TSV110UnitLdSt]> { let Latency = 4; }
-def : WriteRes<WriteLDIdx, [TSV110UnitLdSt]> { let Latency = 4; }
-def : WriteRes<WriteLDHi, []> { let Latency = 4; }
-
-// Pre/Post Indexing
-def : WriteRes<WriteAdr, [TSV110UnitALUAB]> { let Latency = 1; }
-
-// Store
-def : WriteRes<WriteST, [TSV110UnitLdSt]> { let Latency = 1; }
-def : WriteRes<WriteSTP, [TSV110UnitLdSt]> { let Latency = 1; }
-def : WriteRes<WriteSTIdx, [TSV110UnitLdSt]> { let Latency = 1; }
-
-// FP
-def : WriteRes<WriteF, [TSV110UnitF]> { let Latency = 2; }
-def : WriteRes<WriteFCmp, [TSV110UnitF]> { let Latency = 3; }
-def : WriteRes<WriteFCvt, [TSV110UnitF]> { let Latency = 3; }
-def : WriteRes<WriteFCopy, [TSV110UnitF]> { let Latency = 2; }
-def : WriteRes<WriteFImm, [TSV110UnitF]> { let Latency = 2; }
-def : WriteRes<WriteFMul, [TSV110UnitF]> { let Latency = 5; }
-
-// FP Div, Sqrt
-def : WriteRes<WriteFDiv, [TSV110UnitFSU1]> { let Latency = 18; }
-
-def : WriteRes<WriteV, [TSV110UnitF]> { let Latency = 4; }
-def : WriteRes<WriteVLD, [TSV110UnitFLdSt]> { let Latency = 5; }
-def : WriteRes<WriteVST, [TSV110UnitF]> { let Latency = 1; }
-
-// Branch
-def : WriteRes<WriteBr, [TSV110UnitAB]> { let Latency = 1; }
-def : WriteRes<WriteBrReg, [TSV110UnitAB]> { let Latency = 1; }
-def : WriteRes<WriteSys, []> { let Latency = 1; }
-def : WriteRes<WriteBarrier, []> { let Latency = 1; }
-def : WriteRes<WriteHint, []> { let Latency = 1; }
-
-def : WriteRes<WriteAtomic, []> { let Unsupported = 1; }
-
-// Forwarding logic is modeled only for multiply and accumulate.
-def : ReadAdvance<ReadI, 0>;
-def : ReadAdvance<ReadISReg, 0>;
-def : ReadAdvance<ReadIEReg, 0>;
-def : ReadAdvance<ReadIM, 0>;
-def : ReadAdvance<ReadIMA, 2, [WriteIM32, WriteIM64]>;
-def : ReadAdvance<ReadID, 0>;
-def : ReadAdvance<ReadExtrHi, 0>;
-def : ReadAdvance<ReadAdrBase, 0>;
-def : ReadAdvance<ReadVLD, 0>;
-
-def : InstRW<[WriteI], (instrs COPY)>;
-
-// Detailed Refinements
-//===----------------------------------------------------------------------===//
-
-// Contains all of the TSV110 specific SchedWriteRes types. The approach
-// below is to define a generic SchedWriteRes for every combination of
-// latency and microOps. The naming conventions is to use a prefix, one field
-// for latency, and one or more microOp count/type designators.
-// Prefix: TSV110Wr
-// Latency: #cyc
-// MicroOp Count/Types: #(ALU|AB|MDU|FSU1|FSU2|LdSt|ALUAB|F|FLdSt)
-//
-// e.g. TSV110Wr_6cyc_1ALU_6MDU_4LdSt means the total latency is 6 and there are
-// 1 micro-ops to be issued down one ALU pipe, six MDU pipes and four LdSt pipes.
-//
-
-//===----------------------------------------------------------------------===//
-// Define Generic 1 micro-op types
-
-def TSV110Wr_1cyc_1AB : SchedWriteRes<[TSV110UnitAB]> { let Latency = 1; }
-def TSV110Wr_1cyc_1ALU : SchedWriteRes<[TSV110UnitALU]> { let Latency = 1; }
-def TSV110Wr_1cyc_1ALUAB : SchedWriteRes<[TSV110UnitALUAB]> { let Latency = 1; }
-def TSV110Wr_1cyc_1LdSt : SchedWriteRes<[TSV110UnitLdSt]> { let Latency = 1; }
-
-def TSV110Wr_2cyc_1AB : SchedWriteRes<[TSV110UnitAB]> { let Latency = 2; }
-def TSV110Wr_2cyc_1ALU : SchedWriteRes<[TSV110UnitALU]> { let Latency = 2; }
-def TSV110Wr_2cyc_1LdSt : SchedWriteRes<[TSV110UnitLdSt]> { let Latency = 2; }
-def TSV110Wr_2cyc_1MDU : SchedWriteRes<[TSV110UnitMDU]> { let Latency = 2; }
-def TSV110Wr_2cyc_1FSU1 : SchedWriteRes<[TSV110UnitFSU1]> { let Latency = 2; }
-def TSV110Wr_2cyc_1F : SchedWriteRes<[TSV110UnitF]> { let Latency = 2; }
-
-def TSV110Wr_3cyc_1F : SchedWriteRes<[TSV110UnitF]> { let Latency = 3; }
-def TSV110Wr_3cyc_1FSU1 : SchedWriteRes<[TSV110UnitFSU1]> { let Latency = 3; }
-def TSV110Wr_3cyc_1MDU : SchedWriteRes<[TSV110UnitMDU]> { let Latency = 3; }
-
-def TSV110Wr_4cyc_1FSU1 : SchedWriteRes<[TSV110UnitFSU1]> { let Latency = 4; }
-def TSV110Wr_4cyc_1F : SchedWriteRes<[TSV110UnitF]> { let Latency = 4; }
-def TSV110Wr_4cyc_1LdSt : SchedWriteRes<[TSV110UnitLdSt]> { let Latency = 4; }
-def TSV110Wr_4cyc_1MDU : SchedWriteRes<[TSV110UnitMDU]> { let Latency = 4; }
-
-def TSV110Wr_5cyc_1F : SchedWriteRes<[TSV110UnitF]> { let Latency = 5; }
-def TSV110Wr_5cyc_1FSU1 : SchedWriteRes<[TSV110UnitFSU1]> { let Latency = 5; }
-def TSV110Wr_5cyc_1FSU2 : SchedWriteRes<[TSV110UnitFSU2]> { let Latency = 5; }
-def TSV110Wr_5cyc_1LdSt : SchedWriteRes<[TSV110UnitLdSt]> { let Latency = 5; }
-
-def TSV110Wr_6cyc_1F : SchedWriteRes<[TSV110UnitF]> { let Latency = 6; }
-
-def TSV110Wr_7cyc_1F : SchedWriteRes<[TSV110UnitF]> { let Latency = 7; }
-
-def TSV110Wr_8cyc_1F : SchedWriteRes<[TSV110UnitF]> { let Latency = 8; }
-
-def TSV110Wr_11cyc_1FSU1 : SchedWriteRes<[TSV110UnitFSU1]> { let Latency = 11; }
-
-def TSV110Wr_12cyc_1MDU : SchedWriteRes<[TSV110UnitMDU]> { let Latency = 12; }
-
-def TSV110Wr_17cyc_1FSU2 : SchedWriteRes<[TSV110UnitFSU2]> { let Latency = 17; }
-
-def TSV110Wr_18cyc_1FSU1 : SchedWriteRes<[TSV110UnitFSU1]> { let Latency = 18; }
-
-def TSV110Wr_20cyc_1MDU : SchedWriteRes<[TSV110UnitMDU]> { let Latency = 20; }
-
-def TSV110Wr_24cyc_1FSU1 : SchedWriteRes<[TSV110UnitFSU1]> { let Latency = 24; }
-
-def TSV110Wr_31cyc_1FSU2 : SchedWriteRes<[TSV110UnitFSU2]> { let Latency = 31; }
-
-def TSV110Wr_36cyc_1FSU2 : SchedWriteRes<[TSV110UnitFSU2]> { let Latency = 36; }
-
-def TSV110Wr_38cyc_1FSU1 : SchedWriteRes<[TSV110UnitFSU1]> { let Latency = 38; }
-
-def TSV110Wr_64cyc_1FSU2 : SchedWriteRes<[TSV110UnitFSU2]> { let Latency = 64; }
-
-//===----------------------------------------------------------------------===//
-// Define Generic 2 micro-op types
-
-def TSV110Wr_1cyc_1LdSt_1ALUAB : SchedWriteRes<[TSV110UnitLdSt,
- TSV110UnitALUAB]> {
- let Latency = 1;
- let NumMicroOps = 2;
-}
-
-def TSV110Wr_2cyc_1LdSt_1ALUAB : SchedWriteRes<[TSV110UnitLdSt,
- TSV110UnitALUAB]> {
- let Latency = 2;
- let NumMicroOps = 2;
-}
-
-def TSV110Wr_2cyc_2LdSt : SchedWriteRes<[TSV110UnitLdSt,
- TSV110UnitLdSt]> {
- let Latency = 2;
- let NumMicroOps = 2;
-}
-
-def TSV110Wr_2cyc_2F : SchedWriteRes<[TSV110UnitF,
- TSV110UnitF]> {
- let Latency = 2;
- let NumMicroOps = 2;
-}
-
-def TSV110Wr_2cyc_1FSU1_1FSU2 : SchedWriteRes<[TSV110UnitFSU1,
- TSV110UnitFSU2]> {
- let Latency = 2;
- let NumMicroOps = 2;
-}
-
-def TSV110Wr_4cyc_2F : SchedWriteRes<[TSV110UnitF,
- TSV110UnitF]> {
- let Latency = 4;
- let NumMicroOps = 2;
-}
-
-def TSV110Wr_4cyc_1FSU1_1FSU2 : SchedWriteRes<[TSV110UnitFSU1,
- TSV110UnitFSU2]> {
- let Latency = 4;
- let NumMicroOps = 2;
-}
-
-def TSV110Wr_4cyc_1LdSt_1ALUAB : SchedWriteRes<[TSV110UnitLdSt,
- TSV110UnitALUAB]> {
- let Latency = 4;
- let NumMicroOps = 2;
-}
-
-def TSV110Wr_5cyc_1ALU_1F : SchedWriteRes<[TSV110UnitALU,
- TSV110UnitF]> {
- let Latency = 5;
- let NumMicroOps = 2;
-}
-
-def TSV110Wr_6cyc_2LdSt : SchedWriteRes<[TSV110UnitLdSt,
- TSV110UnitLdSt]> {
- let Latency = 6;
- let NumMicroOps = 2;
-}
-
-def TSV110Wr_6cyc_1LdSt_1ALUAB : SchedWriteRes<[TSV110UnitLdSt,
- TSV110UnitALUAB]> {
- let Latency = 6;
- let NumMicroOps = 2;
-}
-
-def TSV110Wr_7cyc_1F_1LdSt : SchedWriteRes<[TSV110UnitF,
- TSV110UnitLdSt]> {
- let Latency = 7;
- let NumMicroOps = 2;
-}
-
-def TSV110Wr_8cyc_2FSU1 : SchedWriteRes<[TSV110UnitFSU1,
- TSV110UnitFSU1]> {
- let Latency = 8;
- let NumMicroOps = 2;
-}
-
-
-def TSV110Wr_8cyc_1FSU1_1FSU2 : SchedWriteRes<[TSV110UnitFSU1,
- TSV110UnitFSU2]> {
- let Latency = 8;
- let NumMicroOps = 2;
-}
-
-//===----------------------------------------------------------------------===//
-// Define Generic 3 micro-op types
-
-def TSV110Wr_6cyc_3F : SchedWriteRes<[TSV110UnitF, TSV110UnitF,
- TSV110UnitF]> {
- let Latency = 6;
- let NumMicroOps = 3;
-}
-
-def TSV110Wr_6cyc_3LdSt : SchedWriteRes<[TSV110UnitLdSt, TSV110UnitLdSt,
- TSV110UnitLdSt]> {
- let Latency = 6;
- let NumMicroOps = 3;
-}
-
-def TSV110Wr_7cyc_2F_1LdSt : SchedWriteRes<[TSV110UnitF, TSV110UnitF,
- TSV110UnitLdSt]> {
- let Latency = 7;
- let NumMicroOps = 3;
-}
-
-//===----------------------------------------------------------------------===//
-// Define Generic 4 micro-op types
-
-def TSV110Wr_8cyc_4F : SchedWriteRes<[TSV110UnitF, TSV110UnitF,
- TSV110UnitF, TSV110UnitF]> {
- let Latency = 8;
- let NumMicroOps = 4;
-}
-
-def TSV110Wr_8cyc_3F_1LdSt : SchedWriteRes<[TSV110UnitF, TSV110UnitF,
- TSV110UnitF, TSV110UnitLdSt]> {
- let Latency = 8;
- let NumMicroOps = 4;
-}
-
-//===----------------------------------------------------------------------===//
-// Define Generic 5 micro-op types
-
-def TSV110Wr_8cyc_3F_2LdSt : SchedWriteRes<[TSV110UnitF, TSV110UnitF, TSV110UnitF,
- TSV110UnitLdSt, TSV110UnitLdSt]> {
- let Latency = 8;
- let NumMicroOps = 5;
-}
-
-//===----------------------------------------------------------------------===//
-// Define Generic 8 micro-op types
-
-def TSV110Wr_10cyc_4F_4LdSt : SchedWriteRes<[TSV110UnitF, TSV110UnitF,
- TSV110UnitF, TSV110UnitF,
- TSV110UnitLdSt, TSV110UnitLdSt,
- TSV110UnitLdSt, TSV110UnitLdSt]> {
- let Latency = 10;
- let NumMicroOps = 8;
-}
-
-
-// Branch Instructions
-// -----------------------------------------------------------------------------
-
-def : InstRW<[TSV110Wr_1cyc_1AB], (instrs B)>;
-def : InstRW<[TSV110Wr_1cyc_1AB], (instrs BL)>;
-def : InstRW<[TSV110Wr_1cyc_1AB], (instrs BLR)>;
-def : InstRW<[TSV110Wr_1cyc_1AB], (instregex "^(BR|RET|(CBZ|CBNZ|TBZ|TBNZ))$")>;
-
-
-// Cryptography Extensions
-// -----------------------------------------------------------------------------
-
-def : InstRW<[TSV110Wr_3cyc_1FSU1], (instregex "^AES[DE]")>;
-def : InstRW<[TSV110Wr_3cyc_1FSU1], (instregex "^AESI?MC")>;
-def : InstRW<[TSV110Wr_2cyc_1FSU1], (instregex "^SHA1SU1")>;
-def : InstRW<[TSV110Wr_2cyc_2F], (instregex "^SHA1(H|SU0)")>;
-def : InstRW<[TSV110Wr_5cyc_1FSU1], (instregex "^SHA1[CMP]")>;
-def : InstRW<[TSV110Wr_2cyc_1FSU1], (instregex "^SHA256SU0")>;
-def : InstRW<[TSV110Wr_3cyc_1FSU1], (instregex "^SHA256SU1")>;
-def : InstRW<[TSV110Wr_5cyc_1FSU1], (instregex "^SHA256(H|H2)")>;
-def TSV110ReadCRC: SchedReadAdvance<1, [TSV110Wr_2cyc_1MDU]>;
-def : InstRW<[TSV110Wr_2cyc_1MDU, TSV110ReadCRC], (instregex "^CRC32.*$")>;
-
-
-// Arithmetic and Logical Instructions
-// -----------------------------------------------------------------------------
-
-def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instregex "(BIC|EON|ORN)[WX]rr")>;
-def : InstRW<[TSV110Wr_1cyc_1AB], (instregex "(BIC)S[WX]rr")>;
-
-def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instregex "(ADD|AND|EOR|ORR|SUB)[WX]r(r|i)")>;
-def : InstRW<[TSV110Wr_1cyc_1AB], (instregex "(ADD|AND|EOR|ORR|SUB)S[WX]r(r|i)")>;
-
-def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instregex "^(ADC|SBC|BIC)[WX]r$")>;
-def : InstRW<[TSV110Wr_1cyc_1AB], (instregex "^(ADC|SBC)S[WX]r$")>;
-
-def : InstRW<[TSV110Wr_2cyc_1MDU], (instregex "^(AND|BIC|EON|EOR|ORN|ORR)[WX]rs$")>;
-def : InstRW<[TSV110Wr_2cyc_1AB], (instregex "^(AND|BIC|EON|EOR|ORN|ORR)S[WX]rs$")>;
-def : InstRW<[TSV110Wr_2cyc_1MDU], (instregex "^(ADD|SUB)[WX]r(s|x|x64)$")>;
-def : InstRW<[TSV110Wr_2cyc_1AB], (instregex "^(ADD|SUB)S[WX]r(s|x|x64)$")>;
-
-def : InstRW<[TSV110Wr_1cyc_1AB], (instregex "^(CCMN|CCMP)(W|X)(r|i)$")>;
-def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instregex "^(CSEL|CSINC|CSINV|CSNEG)(W|X)r$")>;
-
-
-// Move and Shift Instructions
-// -----------------------------------------------------------------------------
-
-def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instrs ADR, ADRP)>;
-def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instregex "^MOV[NZK][WX]i")>;
-def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instregex "(LSLV|LSRV|ASRV|RORV)(W|X)r")>;
-
-
-// Divide and Multiply Instructions
-// -----------------------------------------------------------------------------
-
-def : InstRW<[TSV110Wr_12cyc_1MDU], (instregex "^(S|U)DIVWr$")>;
-def : InstRW<[TSV110Wr_20cyc_1MDU], (instregex "^(S|U)DIVXr$")>;
-
-def TSV110ReadMAW : SchedReadAdvance<2, [TSV110Wr_3cyc_1MDU]>;
-def : InstRW<[TSV110Wr_3cyc_1MDU, TSV110ReadMAW], (instrs MADDWrrr, MSUBWrrr)>;
-def TSV110ReadMAQ : SchedReadAdvance<3, [TSV110Wr_4cyc_1MDU]>;
-def : InstRW<[TSV110Wr_4cyc_1MDU, TSV110ReadMAQ], (instrs MADDXrrr, MSUBXrrr)>;
-def : InstRW<[TSV110Wr_3cyc_1MDU, TSV110ReadMAW], (instregex "(S|U)(MADDL|MSUBL)rrr")>;
-def : InstRW<[TSV110Wr_4cyc_1MDU], (instregex "^(S|U)MULHrr$")>;
-
-
-// Miscellaneous Data-Processing Instructions
-// -----------------------------------------------------------------------------
-
-def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instregex "^EXTR(W|X)rri$")>;
-def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instregex "^(S|U)?BFM(W|X)ri$")>;
-def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instregex "^(CLS|CLZ|RBIT|REV(16|32)?)(W|X)r$")>;
-
-
-// Load Instructions
-// -----------------------------------------------------------------------------
-
-def : InstRW<[TSV110Wr_4cyc_1LdSt], (instregex "^LDR(W|X)l$")>;
-def : InstRW<[TSV110Wr_4cyc_1LdSt], (instrs LDRSWl)>;
-
-def : InstRW<[TSV110Wr_4cyc_1LdSt], (instregex "^LDR(BB|HH|W|X)ui$")>;
-def : InstRW<[TSV110Wr_4cyc_1LdSt], (instregex "^LDRS(BW|BX|HW|HX|W)ui$")>;
-
-def : InstRW<[TSV110Wr_4cyc_1LdSt, WriteAdr], (instregex "^LDR(BB|HH|W|X)(post|pre)$")>;
-def : InstRW<[TSV110Wr_4cyc_1LdSt, WriteAdr], (instregex "^LDRS(BW|BX|HW|HX|W)(post|pre)$")>;
-
-def : InstRW<[TSV110Wr_4cyc_1LdSt], (instregex "^LDTR(B|H|W|X)i$")>;
-def : InstRW<[TSV110Wr_4cyc_1LdSt], (instregex "^LDUR(BB|HH|W|X)i$")>;
-def : InstRW<[TSV110Wr_4cyc_1LdSt], (instregex "^LDTRS(BW|BX|HW|HX|W)i$")>;
-def : InstRW<[TSV110Wr_4cyc_1LdSt], (instregex "^LDURS(BW|BX|HW|HX|W)i$")>;
-
-def : InstRW<[TSV110Wr_4cyc_1LdSt, WriteLDHi], (instregex "^LDNP(W|X)i$")>;
-def : InstRW<[TSV110Wr_4cyc_1LdSt, WriteLDHi], (instregex "^LDP(W|X)i$")>;
-def : InstRW<[TSV110Wr_4cyc_1LdSt_1ALUAB, WriteLDHi, WriteAdr],(instregex "^LDP(W|X)(post|pre)$")>;
-
-def : InstRW<[TSV110Wr_4cyc_1LdSt, WriteLDHi], (instrs LDPSWi)>;
-def : InstRW<[TSV110Wr_4cyc_1LdSt, WriteLDHi, WriteAdr], (instrs LDPSWpost)>;
-def : InstRW<[TSV110Wr_4cyc_1LdSt, WriteLDHi, WriteAdr], (instrs LDPSWpre)>;
-
-def : InstRW<[TSV110Wr_4cyc_1LdSt], (instrs PRFMl)>;
-def : InstRW<[TSV110Wr_4cyc_1LdSt], (instrs PRFUMi)>;
-def : InstRW<[TSV110Wr_4cyc_1LdSt], (instregex "^PRFMui$")>;
-def : InstRW<[TSV110Wr_4cyc_1LdSt], (instregex "^PRFMro(W|X)$")>;
-
-
-// Store Instructions
-// -----------------------------------------------------------------------------
-
-def : InstRW<[TSV110Wr_1cyc_1LdSt], (instregex "^STN?P(W|X)i$")>;
-def : InstRW<[TSV110Wr_1cyc_1LdSt, WriteAdr], (instregex "^STP(W|X)(post|pre)$")>;
-def : InstRW<[TSV110Wr_1cyc_1LdSt], (instregex "^STUR(BB|HH|W|X)i$")>;
-def : InstRW<[TSV110Wr_1cyc_1LdSt], (instregex "^STTR(B|H|W|X)i$")>;
-def : InstRW<[TSV110Wr_1cyc_1LdSt], (instregex "^STR(BB|HH|W|X)ui$")>;
-
-def : InstRW<[TSV110Wr_1cyc_1LdSt, WriteAdr], (instregex "^STR(BB|HH|W|X)(post|pre)$")>;
-def : InstRW<[TSV110Wr_1cyc_1LdSt, WriteAdr], (instregex "^STR(BB|HH|W|X)ro(W|X)$")>;
-
-
-// FP Data Processing Instructions
-// -----------------------------------------------------------------------------
-
-def : InstRW<[TSV110Wr_2cyc_1F], (instregex "F(ABS|NEG)(D|S)r")>;
-def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^FCCMP(E)?(S|D)rr$")>;
-def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^FCMP(E)?(S|D)r(r|i)$")>;
-def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^FCSEL(S|D)rrr$")>;
-
-def : InstRW<[TSV110Wr_11cyc_1FSU1], (instrs FDIVSrr)>;
-def : InstRW<[TSV110Wr_18cyc_1FSU1], (instrs FDIVDrr)>;
-def : InstRW<[TSV110Wr_17cyc_1FSU2], (instrs FSQRTSr)>;
-def : InstRW<[TSV110Wr_31cyc_1FSU2], (instrs FSQRTDr)>;
-
-def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^F(MAX|MIN).+rr")>;
-
-def : InstRW<[TSV110Wr_4cyc_1F], (instregex "^FN?M(ADD|SUB)Hrrr")>;
-def : InstRW<[TSV110Wr_5cyc_1F], (instregex "^FN?M(ADD|SUB)Srrr")>;
-def : InstRW<[TSV110Wr_7cyc_1F], (instregex "^FN?M(ADD|SUB)Drrr")>;
-
-def : InstRW<[TSV110Wr_4cyc_1F], (instregex "^F(ADD|SUB)Hrr")>;
-def : InstRW<[TSV110Wr_5cyc_1F], (instregex "^F(ADD|SUB)Srr")>;
-def : InstRW<[TSV110Wr_4cyc_1F], (instregex "^F(ADD|SUB)Drr")>;
-
-def : InstRW<[TSV110Wr_4cyc_1F], (instregex "^F(N)?MULHrr$")>;
-def : InstRW<[TSV110Wr_5cyc_1F], (instregex "^F(N)?MULSrr$")>;
-def : InstRW<[TSV110Wr_5cyc_1F], (instregex "^F(N)?MULDrr$")>;
-
-def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^FRINT.+r")>;
-
-
-// FP Miscellaneous Instructions
-// -----------------------------------------------------------------------------
-
-def : InstRW<[TSV110Wr_5cyc_1ALU_1F], (instregex "^[SU]CVTF[SU][WX][SD]ri")>;
-def : InstRW<[TSV110Wr_4cyc_1FSU1], (instregex "^FCVT(A|M|N|P|Z)(S|U)U(W|X)(S|D)r$")>;
-def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^FCVT[HSD][HSD]r")>;
-
-def : InstRW<[TSV110Wr_2cyc_1FSU1], (instregex "^FMOV(DX|WS|XD|SW|DXHigh|XDHigh)r$")>;
-def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^FMOV[SD][ir]$")>;
-
-
-// FP Load Instructions
-// -----------------------------------------------------------------------------
-
-def : InstRW<[TSV110Wr_5cyc_1LdSt], (instregex "^LDR[DSQ]l")>;
-def : InstRW<[TSV110Wr_5cyc_1LdSt], (instregex "^LDUR[BDHSQ]i")>;
-def : InstRW<[TSV110Wr_5cyc_1LdSt, WriteAdr], (instregex "^LDR[BDHSQ](post|pre)")>;
-def : InstRW<[TSV110Wr_5cyc_1LdSt], (instregex "^LDR[BDHSQ]ui")>;
-def : InstRW<[TSV110Wr_6cyc_1LdSt_1ALUAB, ReadAdrBase], (instregex "^LDR(Q|D|H|S|B)ro(W|X)$")>;
-def : InstRW<[TSV110Wr_5cyc_1LdSt, WriteLDHi], (instregex "^LDN?P[DQS]i")>;
-def : InstRW<[TSV110Wr_5cyc_1LdSt, WriteLDHi, WriteAdr], (instregex "^LDP[DQS](post|pre)")>;
-
-
-// FP Store Instructions
-// -----------------------------------------------------------------------------
-
-def : InstRW<[TSV110Wr_1cyc_1LdSt], (instregex "^STUR[BHSDQ]i")>;
-def : InstRW<[TSV110Wr_1cyc_1LdSt_1ALUAB, ReadAdrBase], (instregex "^STR[BHSDQ](post|pre)")>;
-def : InstRW<[TSV110Wr_1cyc_1LdSt], (instregex "^STR[BHSDQ]ui")>;
-def : InstRW<[TSV110Wr_2cyc_1LdSt_1ALUAB, ReadAdrBase], (instregex "^STR[BHSDQ]ro[WX]")>;
-def : InstRW<[TSV110Wr_2cyc_2LdSt], (instregex "^STN?P[SDQ]i")>;
-def : InstRW<[TSV110Wr_2cyc_2LdSt, WriteAdr], (instregex "^STP[SDQ](post|pre)")>;
-
-
-// ASIMD Integer Instructions
-// -----------------------------------------------------------------------------
-
-// Reference for forms in this group
-// D form - v8i8, v4i16, v2i32
-// Q form - v16i8, v8i16, v4i32
-// D form - v1i8, v1i16, v1i32, v1i64
-// Q form - v16i8, v8i16, v4i32, v2i64
-// D form - v8i8_v8i16, v4i16_v4i32, v2i32_v2i64
-// Q form - v16i8_v8i16, v8i16_v4i32, v4i32_v2i64
-
-// ASIMD simple arithmetic
-def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^(ABS|ADD(P)?|NEG|SUB)v")>;
-def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^[SU](ADD(L|LP|W)|SUB(L|W))v")>;
-
-// ASIMD complex arithmetic
-def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^[SU]H(ADD|SUB)v")>;
-def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^R?(ADD|SUB)HN2?v")>;
-def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^[SU]Q(ADD|SUB)v")>;
-def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^(SU|US)QADDv")>;
-def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^[SU]RHADDv")>;
-def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^[SU]ABAL?v")>;
-def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^[SU]ABDL?v")>;
-def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^[SU]ADALPv")>;
-def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^((SQ)(ABS|NEG))v")>;
-
-// ASIMD compare
-def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^CM(EQ|GE|GT|HI|HS|LE|LT|TST)v")>;
-
-// ASIMD max/min
-def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^[SU](MIN|MAX)P?v")>;
-
-// ASIMD logical
-def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^(AND|BIC|BIF|BIT|BSL|EOR|MVN|NOT|ORN|ORR)v")>;
-
-// ASIMD multiply accumulate, D-form
-def : InstRW<[TSV110Wr_4cyc_1FSU1], (instregex "^(MUL|ML[AS]|SQR?D(MULH))(v8i8|v4i16|v2i32|v1i8|v1i16|v1i32|v1i64)")>;
-// ASIMD multiply accumulate, Q-form
-def : InstRW<[TSV110Wr_8cyc_2FSU1], (instregex "^(MUL|ML[AS]|SQR?D(MULH))(v16i8|v8i16|v4i32)")>;
-
-// ASIMD multiply accumulate long
-def : InstRW<[TSV110Wr_4cyc_1FSU1], (instregex "(S|U|SQD)(MLAL|MLSL|MULL)v.*")>;
-def : InstRW<[TSV110Wr_2cyc_1FSU1], (instregex "^PMULL(v8i8|v16i8)")>;
-def : InstRW<[TSV110Wr_2cyc_1FSU1], (instregex "^PMULL(v1i64|v2i64)")>;
-
-// ASIMD shift
-// ASIMD shift accumulate
-def : InstRW<[TSV110Wr_4cyc_1FSU1], (instregex "^(S|SR|U|UR)SRA")>;
-// ASIMD shift by immed, basic
-def : InstRW<[TSV110Wr_4cyc_1FSU1],
- (instregex "SHLv","SLIv","SRIv","SHRNv","SQXTNv","SQXTUNv","UQXTNv")>;
-// ASIMD shift by immed, complex
-def : InstRW<[TSV110Wr_4cyc_1FSU1], (instregex "^[SU]?(Q|R){1,2}SHR")>;
-def : InstRW<[TSV110Wr_4cyc_1FSU1], (instregex "^SQSHLU")>;
-// ASIMD shift by register, basic, Q-form
-def : InstRW<[TSV110Wr_4cyc_1FSU1], (instregex "^[SU]SHL(v16i8|v8i16|v4i32|v2i64)")>;
-// ASIMD shift by register, complex, D-form
-def : InstRW<[TSV110Wr_4cyc_1FSU1], (instregex "^[SU][QR]{1,2}SHL(v1i8|v1i16|v1i32|v1i64|v8i8|v4i16|v2i32|b|d|h|s)")>;
-// ASIMD shift by register, complex, Q-form
-def : InstRW<[TSV110Wr_4cyc_1FSU1], (instregex "^[SU][QR]{1,2}SHL(v16i8|v8i16|v4i32|v2i64)")>;
-
-// ASIMD reduction
-// ASIMD arith, reduce, 4H/4S
-def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^[SU]?ADDL?V(v8i8|v4i16|v2i32)v$")>;
-// ASIMD arith, reduce, 8B/8H
-def : InstRW<[TSV110Wr_8cyc_1FSU1_1FSU2], (instregex "^[SU]?ADDL?V(v8i16|v4i32)v$")>;
-// ASIMD arith, reduce, 16B
-def : InstRW<[TSV110Wr_8cyc_1FSU1_1FSU2], (instregex "^[SU]?ADDL?Vv16i8v$")>;
-
-// ASIMD max/min, reduce, 4H/4S
-def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^[SU](MIN|MAX)V(v4i16|v4i32)v$")>;
-// ASIMD max/min, reduce, 8B/8H
-def : InstRW<[TSV110Wr_8cyc_1FSU1_1FSU2], (instregex "^[SU](MIN|MAX)V(v8i8|v8i16)v$")>;
-// ASIMD max/min, reduce, 16B
-def : InstRW<[TSV110Wr_8cyc_1FSU1_1FSU2], (instregex "^[SU](MIN|MAX)Vv16i8v$")>;
-
-
-// Vector - Floating Point
-// -----------------------------------------------------------------------------
-
-// Reference for forms in this group
-// D form - v2f32
-// Q form - v4f32, v2f64
-// D form - 32, 64
-// D form - v1i32, v1i64
-// D form - v2i32
-// Q form - v4i32, v2i64
-
-// ASIMD FP sign manipulation
-def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^FABSv")>;
-def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^FNEGv")>;
-
-// ASIMD FP compare
-def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^F(AC|CM)(EQ|GE|GT|LE|LT)v")>;
-
-// ASIMD FP convert
-def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^FCVT[AMNPZ][SU]v")>;
-def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^FCVT(L)v")>;
-def : InstRW<[TSV110Wr_5cyc_1F], (instregex "^FCVT(N|XN)v")>;
-
-// ASIMD FP divide, D-form, F32
-def : InstRW<[TSV110Wr_11cyc_1FSU1], (instregex "FDIVv2f32")>;
-// ASIMD FP divide, Q-form, F32
-def : InstRW<[TSV110Wr_24cyc_1FSU1], (instregex "FDIVv4f32")>;
-// ASIMD FP divide, Q-form, F64
-def : InstRW<[TSV110Wr_38cyc_1FSU1], (instregex "FDIVv2f64")>;
-
-// ASIMD FP SQRT
-def : InstRW<[TSV110Wr_17cyc_1FSU2], (instrs FSQRTv2f32)>;
-def : InstRW<[TSV110Wr_36cyc_1FSU2], (instrs FSQRTv4f32)>;
-def : InstRW<[TSV110Wr_64cyc_1FSU2], (instrs FSQRTv2f64)>;
-
-// ASIMD FP max,min
-def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^F(MAX|MIN)(NM)?v")>;
-def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^F(MAX|MIN)(NM)?Pv")>;
-def : InstRW<[TSV110Wr_4cyc_1F], (instregex "^F(MAX|MIN)(NM)?Vv")>;
-
-// ASIMD FP add
-def : InstRW<[TSV110Wr_5cyc_1F], (instregex "^F(ADD|ADDP|SUB)v")>;
-
-// ASIMD FP multiply
-def : InstRW<[TSV110Wr_5cyc_1F], (instregex "^FMULX?v")>;
-
-
-// ASIMD Miscellaneous Instructions
-// -----------------------------------------------------------------------------
-
-def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^(CLS|CLZ|CNT)v")>;
-def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^(DUP|INS)v.+lane")>;
-def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^REV(16|32|64)v")>;
-def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^(UZP|ZIP)[12]v")>;
-
-def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^EXTv")>;
-def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^XTNv")>;
-def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^RBITv")>;
-
-def : InstRW<[TSV110Wr_4cyc_1F], (instregex "^(INS|DUP)v.+gpr")>;
-
-def : InstRW<[TSV110Wr_3cyc_1FSU1], (instregex "^[SU]MOVv")>;
-
-// ASIMD table lookup, D-form
-def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^TB[LX]v8i8One")>;
-def : InstRW<[TSV110Wr_4cyc_2F], (instregex "^TB[LX]v8i8Two")>;
-def : InstRW<[TSV110Wr_6cyc_3F], (instregex "^TB[LX]v8i8Three")>;
-def : InstRW<[TSV110Wr_8cyc_4F], (instregex "^TB[LX]v8i8Four")>;
-// ASIMD table lookup, Q-form
-def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^TB[LX]v16i8One")>;
-def : InstRW<[TSV110Wr_4cyc_2F], (instregex "^TB[LX]v16i8Two")>;
-def : InstRW<[TSV110Wr_6cyc_3F], (instregex "^TB[LX]v16i8Three")>;
-def : InstRW<[TSV110Wr_8cyc_4F], (instregex "^TB[LX]v16i8Four")>;
-
-def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^FMOVv")>;
-
-def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^FRINT[AIMNPXZ]v")>;
-def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^[SU]CVTFv")>;
-def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^[FU](RECP|RSQRT)(E|X)v")>;
-
-
-// ASIMD Load Instructions
-// -----------------------------------------------------------------------------
-
-def : InstRW<[TSV110Wr_7cyc_1F_1LdSt], (instregex "^LD1Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[TSV110Wr_7cyc_1F_1LdSt, WriteAdr], (instregex "^LD1Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-def : InstRW<[TSV110Wr_7cyc_2F_1LdSt], (instregex "^LD2Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[TSV110Wr_7cyc_2F_1LdSt, WriteAdr], (instregex "^LD2Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-def : InstRW<[TSV110Wr_8cyc_3F_1LdSt], (instregex "^LD3Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[TSV110Wr_8cyc_3F_1LdSt, WriteAdr], (instregex "^LD3Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-def : InstRW<[TSV110Wr_8cyc_3F_2LdSt], (instregex "^LD4Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[TSV110Wr_8cyc_3F_2LdSt, WriteAdr], (instregex "^LD4Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-def : InstRW<[TSV110Wr_7cyc_1F_1LdSt], (instregex "LD1i(8|16|32|64)$")>;
-def : InstRW<[TSV110Wr_7cyc_1F_1LdSt, WriteAdr], (instregex "LD1i(8|16|32|64)_POST$")>;
-def : InstRW<[TSV110Wr_7cyc_2F_1LdSt], (instregex "LD2i(8|16|32|64)$")>;
-def : InstRW<[TSV110Wr_7cyc_2F_1LdSt, WriteAdr], (instregex "LD2i(8|16|32|64)_POST$")>;
-def : InstRW<[TSV110Wr_8cyc_3F_1LdSt], (instregex "LD3i(8|16|32|64)$")>;
-def : InstRW<[TSV110Wr_8cyc_3F_1LdSt, WriteAdr], (instregex "LD3i(8|16|32|64)_POST$")>;
-def : InstRW<[TSV110Wr_8cyc_3F_2LdSt], (instregex "LD4i(8|16|32|64)$")>;
-def : InstRW<[TSV110Wr_8cyc_3F_2LdSt, WriteAdr], (instregex "LD4i(8|16|32|64)_POST$")>;
-
-def : InstRW<[TSV110Wr_5cyc_1LdSt], (instregex "^LD1Onev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[TSV110Wr_5cyc_1LdSt, WriteAdr], (instregex "^LD1Onev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-def : InstRW<[TSV110Wr_5cyc_1LdSt], (instregex "^LD1Twov(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[TSV110Wr_5cyc_1LdSt, WriteAdr], (instregex "^LD1Twov(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-def : InstRW<[TSV110Wr_6cyc_3LdSt], (instregex "^LD1Threev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[TSV110Wr_6cyc_3LdSt, WriteAdr], (instregex "^LD1Threev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-def : InstRW<[TSV110Wr_6cyc_2LdSt], (instregex "^LD1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[TSV110Wr_6cyc_2LdSt, WriteAdr], (instregex "^LD1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-def : InstRW<[TSV110Wr_7cyc_2F_1LdSt], (instregex "^LD2Twov(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[TSV110Wr_7cyc_2F_1LdSt, WriteAdr], (instregex "^LD2Twov(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-def : InstRW<[TSV110Wr_8cyc_3F_1LdSt], (instregex "^LD3Threev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[TSV110Wr_8cyc_3F_1LdSt, WriteAdr], (instregex "^LD3Threev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-def : InstRW<[TSV110Wr_10cyc_4F_4LdSt], (instregex "^LD4Fourv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[TSV110Wr_10cyc_4F_4LdSt, WriteAdr], (instregex "^LD4Fourv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-
-// ASIMD Store Instructions
-// -----------------------------------------------------------------------------
-
-def : InstRW<[TSV110Wr_3cyc_1F], (instregex "ST1i(8|16|32|64)$")>;
-def : InstRW<[TSV110Wr_3cyc_1F, WriteAdr], (instregex "ST1i(8|16|32|64)_POST$")>;
-def : InstRW<[TSV110Wr_4cyc_1F], (instregex "ST2i(8|16|32|64)$")>;
-def : InstRW<[TSV110Wr_4cyc_1F, WriteAdr], (instregex "ST2i(8|16|32|64)_POST$")>;
-def : InstRW<[TSV110Wr_5cyc_1F], (instregex "ST3i(8|16|32|64)$")>;
-def : InstRW<[TSV110Wr_5cyc_1F, WriteAdr], (instregex "ST3i(8|16|32|64)_POST$")>;
-def : InstRW<[TSV110Wr_6cyc_1F], (instregex "ST4i(8|16|32|64)$")>;
-def : InstRW<[TSV110Wr_6cyc_1F, WriteAdr], (instregex "ST4i(8|16|32|64)_POST$")>;
-
-def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^ST1Onev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[TSV110Wr_3cyc_1F, WriteAdr], (instregex "^ST1Onev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-def : InstRW<[TSV110Wr_4cyc_1F], (instregex "^ST1Twov(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[TSV110Wr_4cyc_1F, WriteAdr], (instregex "^ST1Twov(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-def : InstRW<[TSV110Wr_5cyc_1F], (instregex "^ST1Threev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[TSV110Wr_5cyc_1F, WriteAdr], (instregex "^ST1Threev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-def : InstRW<[TSV110Wr_6cyc_1F], (instregex "^ST1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[TSV110Wr_6cyc_1F, WriteAdr], (instregex "^ST1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-def : InstRW<[TSV110Wr_4cyc_1F], (instregex "^ST2Twov(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[TSV110Wr_4cyc_1F, WriteAdr], (instregex "^ST2Twov(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-def : InstRW<[TSV110Wr_5cyc_1F], (instregex "^ST3Threev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[TSV110Wr_5cyc_1F, WriteAdr], (instregex "^ST3Threev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-def : InstRW<[TSV110Wr_8cyc_1F], (instregex "^ST4Fourv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
-def : InstRW<[TSV110Wr_8cyc_1F, WriteAdr], (instregex "^ST4Fourv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
-
-} // SchedModel = TSV110Model
+//==- AArch64SchedTSV110.td - Huawei TSV110 Scheduling Definitions -*- tablegen -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the machine model for Huawei TSV110 to support
+// instruction scheduling and other instruction cost heuristics.
+//
+//===----------------------------------------------------------------------===//
+
+// ===---------------------------------------------------------------------===//
+// The following definitions describe the simpler per-operand machine model.
+// This works with MachineScheduler. See llvm/MC/MCSchedule.h for details.
+
+// Huawei TSV110 scheduling machine model.
+def TSV110Model : SchedMachineModel {
+ let IssueWidth = 4; // 4 micro-ops dispatched per cycle.
+ let MicroOpBufferSize = 128; // 128 micro-op re-order buffer
+ let LoopMicroOpBufferSize = 16;
+ let LoadLatency = 4; // Optimistic load latency.
+ let MispredictPenalty = 14; // Fetch + Decode/Rename/Dispatch + Branch
+ let CompleteModel = 1;
+
+ list<Predicate> UnsupportedFeatures = !listconcat(SVEUnsupported.F,
+ PAUnsupported.F);
+}
+
+// Define each kind of processor resource and number available on the TSV110,
+// which has 8 pipelines, each with its own queue where micro-ops wait for
+// their operands and issue out-of-order to one of eight execution pipelines.
+let SchedModel = TSV110Model in {
+ def TSV110UnitALU : ProcResource<1>; // Int ALU
+ def TSV110UnitAB : ProcResource<2>; // Int ALU/BRU
+ def TSV110UnitMDU : ProcResource<1>; // Multi-Cycle
+ def TSV110UnitFSU1 : ProcResource<1>; // FP/ASIMD
+ def TSV110UnitFSU2 : ProcResource<1>; // FP/ASIMD
+ def TSV110UnitLdSt : ProcResource<2>; // Load/Store
+
+ def TSV110UnitF : ProcResGroup<[TSV110UnitFSU1, TSV110UnitFSU2]>;
+ def TSV110UnitALUAB : ProcResGroup<[TSV110UnitALU, TSV110UnitAB]>;
+ def TSV110UnitFLdSt : ProcResGroup<[TSV110UnitFSU1, TSV110UnitFSU2, TSV110UnitLdSt]>;
+}
+
+let SchedModel = TSV110Model in {
+
+//===----------------------------------------------------------------------===//
+// Map the target-defined scheduler read/write resources and latency for
+// TSV110
+
+// Integer ALU
+def : WriteRes<WriteImm, [TSV110UnitALUAB]> { let Latency = 1; }
+def : WriteRes<WriteI, [TSV110UnitALUAB]> { let Latency = 1; }
+def : WriteRes<WriteISReg, [TSV110UnitMDU]> { let Latency = 2; }
+def : WriteRes<WriteIEReg, [TSV110UnitMDU]> { let Latency = 2; }
+def : WriteRes<WriteExtr, [TSV110UnitALUAB]> { let Latency = 1; }
+def : WriteRes<WriteIS, [TSV110UnitALUAB]> { let Latency = 1; }
+
+// Integer Mul/MAC/Div
+def : WriteRes<WriteID32, [TSV110UnitMDU]> { let Latency = 12;
+ let ResourceCycles = [12]; }
+def : WriteRes<WriteID64, [TSV110UnitMDU]> { let Latency = 20;
+ let ResourceCycles = [20]; }
+def : WriteRes<WriteIM32, [TSV110UnitMDU]> { let Latency = 3; }
+def : WriteRes<WriteIM64, [TSV110UnitMDU]> { let Latency = 4; }
+
+// Load
+def : WriteRes<WriteLD, [TSV110UnitLdSt]> { let Latency = 4; }
+def : WriteRes<WriteLDIdx, [TSV110UnitLdSt]> { let Latency = 4; }
+def : WriteRes<WriteLDHi, []> { let Latency = 4; }
+
+// Pre/Post Indexing
+def : WriteRes<WriteAdr, [TSV110UnitALUAB]> { let Latency = 1; }
+
+// Store
+def : WriteRes<WriteST, [TSV110UnitLdSt]> { let Latency = 1; }
+def : WriteRes<WriteSTP, [TSV110UnitLdSt]> { let Latency = 1; }
+def : WriteRes<WriteSTIdx, [TSV110UnitLdSt]> { let Latency = 1; }
+
+// FP
+def : WriteRes<WriteF, [TSV110UnitF]> { let Latency = 2; }
+def : WriteRes<WriteFCmp, [TSV110UnitF]> { let Latency = 3; }
+def : WriteRes<WriteFCvt, [TSV110UnitF]> { let Latency = 3; }
+def : WriteRes<WriteFCopy, [TSV110UnitF]> { let Latency = 2; }
+def : WriteRes<WriteFImm, [TSV110UnitF]> { let Latency = 2; }
+def : WriteRes<WriteFMul, [TSV110UnitF]> { let Latency = 5; }
+
+// FP Div, Sqrt
+def : WriteRes<WriteFDiv, [TSV110UnitFSU1]> { let Latency = 18; }
+
+def : WriteRes<WriteV, [TSV110UnitF]> { let Latency = 4; }
+def : WriteRes<WriteVLD, [TSV110UnitFLdSt]> { let Latency = 5; }
+def : WriteRes<WriteVST, [TSV110UnitF]> { let Latency = 1; }
+
+// Branch
+def : WriteRes<WriteBr, [TSV110UnitAB]> { let Latency = 1; }
+def : WriteRes<WriteBrReg, [TSV110UnitAB]> { let Latency = 1; }
+def : WriteRes<WriteSys, []> { let Latency = 1; }
+def : WriteRes<WriteBarrier, []> { let Latency = 1; }
+def : WriteRes<WriteHint, []> { let Latency = 1; }
+
+def : WriteRes<WriteAtomic, []> { let Unsupported = 1; }
+
+// Forwarding logic is modeled only for multiply and accumulate.
+def : ReadAdvance<ReadI, 0>;
+def : ReadAdvance<ReadISReg, 0>;
+def : ReadAdvance<ReadIEReg, 0>;
+def : ReadAdvance<ReadIM, 0>;
+def : ReadAdvance<ReadIMA, 2, [WriteIM32, WriteIM64]>;
+def : ReadAdvance<ReadID, 0>;
+def : ReadAdvance<ReadExtrHi, 0>;
+def : ReadAdvance<ReadAdrBase, 0>;
+def : ReadAdvance<ReadVLD, 0>;
+
+def : InstRW<[WriteI], (instrs COPY)>;
+
+// Detailed Refinements
+//===----------------------------------------------------------------------===//
+
+// Contains all of the TSV110 specific SchedWriteRes types. The approach
+// below is to define a generic SchedWriteRes for every combination of
+// latency and microOps. The naming conventions is to use a prefix, one field
+// for latency, and one or more microOp count/type designators.
+// Prefix: TSV110Wr
+// Latency: #cyc
+// MicroOp Count/Types: #(ALU|AB|MDU|FSU1|FSU2|LdSt|ALUAB|F|FLdSt)
+//
+// e.g. TSV110Wr_6cyc_1ALU_6MDU_4LdSt means the total latency is 6 and there are
+// 1 micro-ops to be issued down one ALU pipe, six MDU pipes and four LdSt pipes.
+//
+
+//===----------------------------------------------------------------------===//
+// Define Generic 1 micro-op types
+
+def TSV110Wr_1cyc_1AB : SchedWriteRes<[TSV110UnitAB]> { let Latency = 1; }
+def TSV110Wr_1cyc_1ALU : SchedWriteRes<[TSV110UnitALU]> { let Latency = 1; }
+def TSV110Wr_1cyc_1ALUAB : SchedWriteRes<[TSV110UnitALUAB]> { let Latency = 1; }
+def TSV110Wr_1cyc_1LdSt : SchedWriteRes<[TSV110UnitLdSt]> { let Latency = 1; }
+
+def TSV110Wr_2cyc_1AB : SchedWriteRes<[TSV110UnitAB]> { let Latency = 2; }
+def TSV110Wr_2cyc_1ALU : SchedWriteRes<[TSV110UnitALU]> { let Latency = 2; }
+def TSV110Wr_2cyc_1LdSt : SchedWriteRes<[TSV110UnitLdSt]> { let Latency = 2; }
+def TSV110Wr_2cyc_1MDU : SchedWriteRes<[TSV110UnitMDU]> { let Latency = 2; }
+def TSV110Wr_2cyc_1FSU1 : SchedWriteRes<[TSV110UnitFSU1]> { let Latency = 2; }
+def TSV110Wr_2cyc_1F : SchedWriteRes<[TSV110UnitF]> { let Latency = 2; }
+
+def TSV110Wr_3cyc_1F : SchedWriteRes<[TSV110UnitF]> { let Latency = 3; }
+def TSV110Wr_3cyc_1FSU1 : SchedWriteRes<[TSV110UnitFSU1]> { let Latency = 3; }
+def TSV110Wr_3cyc_1MDU : SchedWriteRes<[TSV110UnitMDU]> { let Latency = 3; }
+
+def TSV110Wr_4cyc_1FSU1 : SchedWriteRes<[TSV110UnitFSU1]> { let Latency = 4; }
+def TSV110Wr_4cyc_1F : SchedWriteRes<[TSV110UnitF]> { let Latency = 4; }
+def TSV110Wr_4cyc_1LdSt : SchedWriteRes<[TSV110UnitLdSt]> { let Latency = 4; }
+def TSV110Wr_4cyc_1MDU : SchedWriteRes<[TSV110UnitMDU]> { let Latency = 4; }
+
+def TSV110Wr_5cyc_1F : SchedWriteRes<[TSV110UnitF]> { let Latency = 5; }
+def TSV110Wr_5cyc_1FSU1 : SchedWriteRes<[TSV110UnitFSU1]> { let Latency = 5; }
+def TSV110Wr_5cyc_1FSU2 : SchedWriteRes<[TSV110UnitFSU2]> { let Latency = 5; }
+def TSV110Wr_5cyc_1LdSt : SchedWriteRes<[TSV110UnitLdSt]> { let Latency = 5; }
+
+def TSV110Wr_6cyc_1F : SchedWriteRes<[TSV110UnitF]> { let Latency = 6; }
+
+def TSV110Wr_7cyc_1F : SchedWriteRes<[TSV110UnitF]> { let Latency = 7; }
+
+def TSV110Wr_8cyc_1F : SchedWriteRes<[TSV110UnitF]> { let Latency = 8; }
+
+def TSV110Wr_11cyc_1FSU1 : SchedWriteRes<[TSV110UnitFSU1]> { let Latency = 11; }
+
+def TSV110Wr_12cyc_1MDU : SchedWriteRes<[TSV110UnitMDU]> { let Latency = 12; }
+
+def TSV110Wr_17cyc_1FSU2 : SchedWriteRes<[TSV110UnitFSU2]> { let Latency = 17; }
+
+def TSV110Wr_18cyc_1FSU1 : SchedWriteRes<[TSV110UnitFSU1]> { let Latency = 18; }
+
+def TSV110Wr_20cyc_1MDU : SchedWriteRes<[TSV110UnitMDU]> { let Latency = 20; }
+
+def TSV110Wr_24cyc_1FSU1 : SchedWriteRes<[TSV110UnitFSU1]> { let Latency = 24; }
+
+def TSV110Wr_31cyc_1FSU2 : SchedWriteRes<[TSV110UnitFSU2]> { let Latency = 31; }
+
+def TSV110Wr_36cyc_1FSU2 : SchedWriteRes<[TSV110UnitFSU2]> { let Latency = 36; }
+
+def TSV110Wr_38cyc_1FSU1 : SchedWriteRes<[TSV110UnitFSU1]> { let Latency = 38; }
+
+def TSV110Wr_64cyc_1FSU2 : SchedWriteRes<[TSV110UnitFSU2]> { let Latency = 64; }
+
+//===----------------------------------------------------------------------===//
+// Define Generic 2 micro-op types
+
+def TSV110Wr_1cyc_1LdSt_1ALUAB : SchedWriteRes<[TSV110UnitLdSt,
+ TSV110UnitALUAB]> {
+ let Latency = 1;
+ let NumMicroOps = 2;
+}
+
+def TSV110Wr_2cyc_1LdSt_1ALUAB : SchedWriteRes<[TSV110UnitLdSt,
+ TSV110UnitALUAB]> {
+ let Latency = 2;
+ let NumMicroOps = 2;
+}
+
+def TSV110Wr_2cyc_2LdSt : SchedWriteRes<[TSV110UnitLdSt,
+ TSV110UnitLdSt]> {
+ let Latency = 2;
+ let NumMicroOps = 2;
+}
+
+def TSV110Wr_2cyc_2F : SchedWriteRes<[TSV110UnitF,
+ TSV110UnitF]> {
+ let Latency = 2;
+ let NumMicroOps = 2;
+}
+
+def TSV110Wr_2cyc_1FSU1_1FSU2 : SchedWriteRes<[TSV110UnitFSU1,
+ TSV110UnitFSU2]> {
+ let Latency = 2;
+ let NumMicroOps = 2;
+}
+
+def TSV110Wr_4cyc_2F : SchedWriteRes<[TSV110UnitF,
+ TSV110UnitF]> {
+ let Latency = 4;
+ let NumMicroOps = 2;
+}
+
+def TSV110Wr_4cyc_1FSU1_1FSU2 : SchedWriteRes<[TSV110UnitFSU1,
+ TSV110UnitFSU2]> {
+ let Latency = 4;
+ let NumMicroOps = 2;
+}
+
+def TSV110Wr_4cyc_1LdSt_1ALUAB : SchedWriteRes<[TSV110UnitLdSt,
+ TSV110UnitALUAB]> {
+ let Latency = 4;
+ let NumMicroOps = 2;
+}
+
+def TSV110Wr_5cyc_1ALU_1F : SchedWriteRes<[TSV110UnitALU,
+ TSV110UnitF]> {
+ let Latency = 5;
+ let NumMicroOps = 2;
+}
+
+def TSV110Wr_6cyc_2LdSt : SchedWriteRes<[TSV110UnitLdSt,
+ TSV110UnitLdSt]> {
+ let Latency = 6;
+ let NumMicroOps = 2;
+}
+
+def TSV110Wr_6cyc_1LdSt_1ALUAB : SchedWriteRes<[TSV110UnitLdSt,
+ TSV110UnitALUAB]> {
+ let Latency = 6;
+ let NumMicroOps = 2;
+}
+
+def TSV110Wr_7cyc_1F_1LdSt : SchedWriteRes<[TSV110UnitF,
+ TSV110UnitLdSt]> {
+ let Latency = 7;
+ let NumMicroOps = 2;
+}
+
+def TSV110Wr_8cyc_2FSU1 : SchedWriteRes<[TSV110UnitFSU1,
+ TSV110UnitFSU1]> {
+ let Latency = 8;
+ let NumMicroOps = 2;
+}
+
+
+def TSV110Wr_8cyc_1FSU1_1FSU2 : SchedWriteRes<[TSV110UnitFSU1,
+ TSV110UnitFSU2]> {
+ let Latency = 8;
+ let NumMicroOps = 2;
+}
+
+//===----------------------------------------------------------------------===//
+// Define Generic 3 micro-op types
+
+def TSV110Wr_6cyc_3F : SchedWriteRes<[TSV110UnitF, TSV110UnitF,
+ TSV110UnitF]> {
+ let Latency = 6;
+ let NumMicroOps = 3;
+}
+
+def TSV110Wr_6cyc_3LdSt : SchedWriteRes<[TSV110UnitLdSt, TSV110UnitLdSt,
+ TSV110UnitLdSt]> {
+ let Latency = 6;
+ let NumMicroOps = 3;
+}
+
+def TSV110Wr_7cyc_2F_1LdSt : SchedWriteRes<[TSV110UnitF, TSV110UnitF,
+ TSV110UnitLdSt]> {
+ let Latency = 7;
+ let NumMicroOps = 3;
+}
+
+//===----------------------------------------------------------------------===//
+// Define Generic 4 micro-op types
+
+def TSV110Wr_8cyc_4F : SchedWriteRes<[TSV110UnitF, TSV110UnitF,
+ TSV110UnitF, TSV110UnitF]> {
+ let Latency = 8;
+ let NumMicroOps = 4;
+}
+
+def TSV110Wr_8cyc_3F_1LdSt : SchedWriteRes<[TSV110UnitF, TSV110UnitF,
+ TSV110UnitF, TSV110UnitLdSt]> {
+ let Latency = 8;
+ let NumMicroOps = 4;
+}
+
+//===----------------------------------------------------------------------===//
+// Define Generic 5 micro-op types
+
+def TSV110Wr_8cyc_3F_2LdSt : SchedWriteRes<[TSV110UnitF, TSV110UnitF, TSV110UnitF,
+ TSV110UnitLdSt, TSV110UnitLdSt]> {
+ let Latency = 8;
+ let NumMicroOps = 5;
+}
+
+//===----------------------------------------------------------------------===//
+// Define Generic 8 micro-op types
+
+def TSV110Wr_10cyc_4F_4LdSt : SchedWriteRes<[TSV110UnitF, TSV110UnitF,
+ TSV110UnitF, TSV110UnitF,
+ TSV110UnitLdSt, TSV110UnitLdSt,
+ TSV110UnitLdSt, TSV110UnitLdSt]> {
+ let Latency = 10;
+ let NumMicroOps = 8;
+}
+
+
+// Branch Instructions
+// -----------------------------------------------------------------------------
+
+def : InstRW<[TSV110Wr_1cyc_1AB], (instrs B)>;
+def : InstRW<[TSV110Wr_1cyc_1AB], (instrs BL)>;
+def : InstRW<[TSV110Wr_1cyc_1AB], (instrs BLR)>;
+def : InstRW<[TSV110Wr_1cyc_1AB], (instregex "^(BR|RET|(CBZ|CBNZ|TBZ|TBNZ))$")>;
+
+
+// Cryptography Extensions
+// -----------------------------------------------------------------------------
+
+def : InstRW<[TSV110Wr_3cyc_1FSU1], (instregex "^AES[DE]")>;
+def : InstRW<[TSV110Wr_3cyc_1FSU1], (instregex "^AESI?MC")>;
+def : InstRW<[TSV110Wr_2cyc_1FSU1], (instregex "^SHA1SU1")>;
+def : InstRW<[TSV110Wr_2cyc_2F], (instregex "^SHA1(H|SU0)")>;
+def : InstRW<[TSV110Wr_5cyc_1FSU1], (instregex "^SHA1[CMP]")>;
+def : InstRW<[TSV110Wr_2cyc_1FSU1], (instregex "^SHA256SU0")>;
+def : InstRW<[TSV110Wr_3cyc_1FSU1], (instregex "^SHA256SU1")>;
+def : InstRW<[TSV110Wr_5cyc_1FSU1], (instregex "^SHA256(H|H2)")>;
+def TSV110ReadCRC: SchedReadAdvance<1, [TSV110Wr_2cyc_1MDU]>;
+def : InstRW<[TSV110Wr_2cyc_1MDU, TSV110ReadCRC], (instregex "^CRC32.*$")>;
+
+
+// Arithmetic and Logical Instructions
+// -----------------------------------------------------------------------------
+
+def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instregex "(BIC|EON|ORN)[WX]rr")>;
+def : InstRW<[TSV110Wr_1cyc_1AB], (instregex "(BIC)S[WX]rr")>;
+
+def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instregex "(ADD|AND|EOR|ORR|SUB)[WX]r(r|i)")>;
+def : InstRW<[TSV110Wr_1cyc_1AB], (instregex "(ADD|AND|EOR|ORR|SUB)S[WX]r(r|i)")>;
+
+def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instregex "^(ADC|SBC|BIC)[WX]r$")>;
+def : InstRW<[TSV110Wr_1cyc_1AB], (instregex "^(ADC|SBC)S[WX]r$")>;
+
+def : InstRW<[TSV110Wr_2cyc_1MDU], (instregex "^(AND|BIC|EON|EOR|ORN|ORR)[WX]rs$")>;
+def : InstRW<[TSV110Wr_2cyc_1AB], (instregex "^(AND|BIC|EON|EOR|ORN|ORR)S[WX]rs$")>;
+def : InstRW<[TSV110Wr_2cyc_1MDU], (instregex "^(ADD|SUB)[WX]r(s|x|x64)$")>;
+def : InstRW<[TSV110Wr_2cyc_1AB], (instregex "^(ADD|SUB)S[WX]r(s|x|x64)$")>;
+
+def : InstRW<[TSV110Wr_1cyc_1AB], (instregex "^(CCMN|CCMP)(W|X)(r|i)$")>;
+def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instregex "^(CSEL|CSINC|CSINV|CSNEG)(W|X)r$")>;
+
+
+// Move and Shift Instructions
+// -----------------------------------------------------------------------------
+
+def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instrs ADR, ADRP)>;
+def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instregex "^MOV[NZK][WX]i")>;
+def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instregex "(LSLV|LSRV|ASRV|RORV)(W|X)r")>;
+
+
+// Divide and Multiply Instructions
+// -----------------------------------------------------------------------------
+
+def : InstRW<[TSV110Wr_12cyc_1MDU], (instregex "^(S|U)DIVWr$")>;
+def : InstRW<[TSV110Wr_20cyc_1MDU], (instregex "^(S|U)DIVXr$")>;
+
+def TSV110ReadMAW : SchedReadAdvance<2, [TSV110Wr_3cyc_1MDU]>;
+def : InstRW<[TSV110Wr_3cyc_1MDU, TSV110ReadMAW], (instrs MADDWrrr, MSUBWrrr)>;
+def TSV110ReadMAQ : SchedReadAdvance<3, [TSV110Wr_4cyc_1MDU]>;
+def : InstRW<[TSV110Wr_4cyc_1MDU, TSV110ReadMAQ], (instrs MADDXrrr, MSUBXrrr)>;
+def : InstRW<[TSV110Wr_3cyc_1MDU, TSV110ReadMAW], (instregex "(S|U)(MADDL|MSUBL)rrr")>;
+def : InstRW<[TSV110Wr_4cyc_1MDU], (instregex "^(S|U)MULHrr$")>;
+
+
+// Miscellaneous Data-Processing Instructions
+// -----------------------------------------------------------------------------
+
+def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instregex "^EXTR(W|X)rri$")>;
+def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instregex "^(S|U)?BFM(W|X)ri$")>;
+def : InstRW<[TSV110Wr_1cyc_1ALUAB], (instregex "^(CLS|CLZ|RBIT|REV(16|32)?)(W|X)r$")>;
+
+
+// Load Instructions
+// -----------------------------------------------------------------------------
+
+def : InstRW<[TSV110Wr_4cyc_1LdSt], (instregex "^LDR(W|X)l$")>;
+def : InstRW<[TSV110Wr_4cyc_1LdSt], (instrs LDRSWl)>;
+
+def : InstRW<[TSV110Wr_4cyc_1LdSt], (instregex "^LDR(BB|HH|W|X)ui$")>;
+def : InstRW<[TSV110Wr_4cyc_1LdSt], (instregex "^LDRS(BW|BX|HW|HX|W)ui$")>;
+
+def : InstRW<[TSV110Wr_4cyc_1LdSt, WriteAdr], (instregex "^LDR(BB|HH|W|X)(post|pre)$")>;
+def : InstRW<[TSV110Wr_4cyc_1LdSt, WriteAdr], (instregex "^LDRS(BW|BX|HW|HX|W)(post|pre)$")>;
+
+def : InstRW<[TSV110Wr_4cyc_1LdSt], (instregex "^LDTR(B|H|W|X)i$")>;
+def : InstRW<[TSV110Wr_4cyc_1LdSt], (instregex "^LDUR(BB|HH|W|X)i$")>;
+def : InstRW<[TSV110Wr_4cyc_1LdSt], (instregex "^LDTRS(BW|BX|HW|HX|W)i$")>;
+def : InstRW<[TSV110Wr_4cyc_1LdSt], (instregex "^LDURS(BW|BX|HW|HX|W)i$")>;
+
+def : InstRW<[TSV110Wr_4cyc_1LdSt, WriteLDHi], (instregex "^LDNP(W|X)i$")>;
+def : InstRW<[TSV110Wr_4cyc_1LdSt, WriteLDHi], (instregex "^LDP(W|X)i$")>;
+def : InstRW<[TSV110Wr_4cyc_1LdSt_1ALUAB, WriteLDHi, WriteAdr],(instregex "^LDP(W|X)(post|pre)$")>;
+
+def : InstRW<[TSV110Wr_4cyc_1LdSt, WriteLDHi], (instrs LDPSWi)>;
+def : InstRW<[TSV110Wr_4cyc_1LdSt, WriteLDHi, WriteAdr], (instrs LDPSWpost)>;
+def : InstRW<[TSV110Wr_4cyc_1LdSt, WriteLDHi, WriteAdr], (instrs LDPSWpre)>;
+
+def : InstRW<[TSV110Wr_4cyc_1LdSt], (instrs PRFMl)>;
+def : InstRW<[TSV110Wr_4cyc_1LdSt], (instrs PRFUMi)>;
+def : InstRW<[TSV110Wr_4cyc_1LdSt], (instregex "^PRFMui$")>;
+def : InstRW<[TSV110Wr_4cyc_1LdSt], (instregex "^PRFMro(W|X)$")>;
+
+
+// Store Instructions
+// -----------------------------------------------------------------------------
+
+def : InstRW<[TSV110Wr_1cyc_1LdSt], (instregex "^STN?P(W|X)i$")>;
+def : InstRW<[TSV110Wr_1cyc_1LdSt, WriteAdr], (instregex "^STP(W|X)(post|pre)$")>;
+def : InstRW<[TSV110Wr_1cyc_1LdSt], (instregex "^STUR(BB|HH|W|X)i$")>;
+def : InstRW<[TSV110Wr_1cyc_1LdSt], (instregex "^STTR(B|H|W|X)i$")>;
+def : InstRW<[TSV110Wr_1cyc_1LdSt], (instregex "^STR(BB|HH|W|X)ui$")>;
+
+def : InstRW<[TSV110Wr_1cyc_1LdSt, WriteAdr], (instregex "^STR(BB|HH|W|X)(post|pre)$")>;
+def : InstRW<[TSV110Wr_1cyc_1LdSt, WriteAdr], (instregex "^STR(BB|HH|W|X)ro(W|X)$")>;
+
+
+// FP Data Processing Instructions
+// -----------------------------------------------------------------------------
+
+def : InstRW<[TSV110Wr_2cyc_1F], (instregex "F(ABS|NEG)(D|S)r")>;
+def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^FCCMP(E)?(S|D)rr$")>;
+def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^FCMP(E)?(S|D)r(r|i)$")>;
+def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^FCSEL(S|D)rrr$")>;
+
+def : InstRW<[TSV110Wr_11cyc_1FSU1], (instrs FDIVSrr)>;
+def : InstRW<[TSV110Wr_18cyc_1FSU1], (instrs FDIVDrr)>;
+def : InstRW<[TSV110Wr_17cyc_1FSU2], (instrs FSQRTSr)>;
+def : InstRW<[TSV110Wr_31cyc_1FSU2], (instrs FSQRTDr)>;
+
+def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^F(MAX|MIN).+rr")>;
+
+def : InstRW<[TSV110Wr_4cyc_1F], (instregex "^FN?M(ADD|SUB)Hrrr")>;
+def : InstRW<[TSV110Wr_5cyc_1F], (instregex "^FN?M(ADD|SUB)Srrr")>;
+def : InstRW<[TSV110Wr_7cyc_1F], (instregex "^FN?M(ADD|SUB)Drrr")>;
+
+def : InstRW<[TSV110Wr_4cyc_1F], (instregex "^F(ADD|SUB)Hrr")>;
+def : InstRW<[TSV110Wr_5cyc_1F], (instregex "^F(ADD|SUB)Srr")>;
+def : InstRW<[TSV110Wr_4cyc_1F], (instregex "^F(ADD|SUB)Drr")>;
+
+def : InstRW<[TSV110Wr_4cyc_1F], (instregex "^F(N)?MULHrr$")>;
+def : InstRW<[TSV110Wr_5cyc_1F], (instregex "^F(N)?MULSrr$")>;
+def : InstRW<[TSV110Wr_5cyc_1F], (instregex "^F(N)?MULDrr$")>;
+
+def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^FRINT.+r")>;
+
+
+// FP Miscellaneous Instructions
+// -----------------------------------------------------------------------------
+
+def : InstRW<[TSV110Wr_5cyc_1ALU_1F], (instregex "^[SU]CVTF[SU][WX][SD]ri")>;
+def : InstRW<[TSV110Wr_4cyc_1FSU1], (instregex "^FCVT(A|M|N|P|Z)(S|U)U(W|X)(S|D)r$")>;
+def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^FCVT[HSD][HSD]r")>;
+
+def : InstRW<[TSV110Wr_2cyc_1FSU1], (instregex "^FMOV(DX|WS|XD|SW|DXHigh|XDHigh)r$")>;
+def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^FMOV[SD][ir]$")>;
+
+
+// FP Load Instructions
+// -----------------------------------------------------------------------------
+
+def : InstRW<[TSV110Wr_5cyc_1LdSt], (instregex "^LDR[DSQ]l")>;
+def : InstRW<[TSV110Wr_5cyc_1LdSt], (instregex "^LDUR[BDHSQ]i")>;
+def : InstRW<[TSV110Wr_5cyc_1LdSt, WriteAdr], (instregex "^LDR[BDHSQ](post|pre)")>;
+def : InstRW<[TSV110Wr_5cyc_1LdSt], (instregex "^LDR[BDHSQ]ui")>;
+def : InstRW<[TSV110Wr_6cyc_1LdSt_1ALUAB, ReadAdrBase], (instregex "^LDR(Q|D|H|S|B)ro(W|X)$")>;
+def : InstRW<[TSV110Wr_5cyc_1LdSt, WriteLDHi], (instregex "^LDN?P[DQS]i")>;
+def : InstRW<[TSV110Wr_5cyc_1LdSt, WriteLDHi, WriteAdr], (instregex "^LDP[DQS](post|pre)")>;
+
+
+// FP Store Instructions
+// -----------------------------------------------------------------------------
+
+def : InstRW<[TSV110Wr_1cyc_1LdSt], (instregex "^STUR[BHSDQ]i")>;
+def : InstRW<[TSV110Wr_1cyc_1LdSt_1ALUAB, ReadAdrBase], (instregex "^STR[BHSDQ](post|pre)")>;
+def : InstRW<[TSV110Wr_1cyc_1LdSt], (instregex "^STR[BHSDQ]ui")>;
+def : InstRW<[TSV110Wr_2cyc_1LdSt_1ALUAB, ReadAdrBase], (instregex "^STR[BHSDQ]ro[WX]")>;
+def : InstRW<[TSV110Wr_2cyc_2LdSt], (instregex "^STN?P[SDQ]i")>;
+def : InstRW<[TSV110Wr_2cyc_2LdSt, WriteAdr], (instregex "^STP[SDQ](post|pre)")>;
+
+
+// ASIMD Integer Instructions
+// -----------------------------------------------------------------------------
+
+// Reference for forms in this group
+// D form - v8i8, v4i16, v2i32
+// Q form - v16i8, v8i16, v4i32
+// D form - v1i8, v1i16, v1i32, v1i64
+// Q form - v16i8, v8i16, v4i32, v2i64
+// D form - v8i8_v8i16, v4i16_v4i32, v2i32_v2i64
+// Q form - v16i8_v8i16, v8i16_v4i32, v4i32_v2i64
+
+// ASIMD simple arithmetic
+def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^(ABS|ADD(P)?|NEG|SUB)v")>;
+def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^[SU](ADD(L|LP|W)|SUB(L|W))v")>;
+
+// ASIMD complex arithmetic
+def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^[SU]H(ADD|SUB)v")>;
+def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^R?(ADD|SUB)HN2?v")>;
+def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^[SU]Q(ADD|SUB)v")>;
+def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^(SU|US)QADDv")>;
+def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^[SU]RHADDv")>;
+def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^[SU]ABAL?v")>;
+def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^[SU]ABDL?v")>;
+def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^[SU]ADALPv")>;
+def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^((SQ)(ABS|NEG))v")>;
+
+// ASIMD compare
+def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^CM(EQ|GE|GT|HI|HS|LE|LT|TST)v")>;
+
+// ASIMD max/min
+def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^[SU](MIN|MAX)P?v")>;
+
+// ASIMD logical
+def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^(AND|BIC|BIF|BIT|BSL|EOR|MVN|NOT|ORN|ORR)v")>;
+
+// ASIMD multiply accumulate, D-form
+def : InstRW<[TSV110Wr_4cyc_1FSU1], (instregex "^(MUL|ML[AS]|SQR?D(MULH))(v8i8|v4i16|v2i32|v1i8|v1i16|v1i32|v1i64)")>;
+// ASIMD multiply accumulate, Q-form
+def : InstRW<[TSV110Wr_8cyc_2FSU1], (instregex "^(MUL|ML[AS]|SQR?D(MULH))(v16i8|v8i16|v4i32)")>;
+
+// ASIMD multiply accumulate long
+def : InstRW<[TSV110Wr_4cyc_1FSU1], (instregex "(S|U|SQD)(MLAL|MLSL|MULL)v.*")>;
+def : InstRW<[TSV110Wr_2cyc_1FSU1], (instregex "^PMULL(v8i8|v16i8)")>;
+def : InstRW<[TSV110Wr_2cyc_1FSU1], (instregex "^PMULL(v1i64|v2i64)")>;
+
+// ASIMD shift
+// ASIMD shift accumulate
+def : InstRW<[TSV110Wr_4cyc_1FSU1], (instregex "^(S|SR|U|UR)SRA")>;
+// ASIMD shift by immed, basic
+def : InstRW<[TSV110Wr_4cyc_1FSU1],
+ (instregex "SHLv","SLIv","SRIv","SHRNv","SQXTNv","SQXTUNv","UQXTNv")>;
+// ASIMD shift by immed, complex
+def : InstRW<[TSV110Wr_4cyc_1FSU1], (instregex "^[SU]?(Q|R){1,2}SHR")>;
+def : InstRW<[TSV110Wr_4cyc_1FSU1], (instregex "^SQSHLU")>;
+// ASIMD shift by register, basic, Q-form
+def : InstRW<[TSV110Wr_4cyc_1FSU1], (instregex "^[SU]SHL(v16i8|v8i16|v4i32|v2i64)")>;
+// ASIMD shift by register, complex, D-form
+def : InstRW<[TSV110Wr_4cyc_1FSU1], (instregex "^[SU][QR]{1,2}SHL(v1i8|v1i16|v1i32|v1i64|v8i8|v4i16|v2i32|b|d|h|s)")>;
+// ASIMD shift by register, complex, Q-form
+def : InstRW<[TSV110Wr_4cyc_1FSU1], (instregex "^[SU][QR]{1,2}SHL(v16i8|v8i16|v4i32|v2i64)")>;
+
+// ASIMD reduction
+// ASIMD arith, reduce, 4H/4S
+def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^[SU]?ADDL?V(v8i8|v4i16|v2i32)v$")>;
+// ASIMD arith, reduce, 8B/8H
+def : InstRW<[TSV110Wr_8cyc_1FSU1_1FSU2], (instregex "^[SU]?ADDL?V(v8i16|v4i32)v$")>;
+// ASIMD arith, reduce, 16B
+def : InstRW<[TSV110Wr_8cyc_1FSU1_1FSU2], (instregex "^[SU]?ADDL?Vv16i8v$")>;
+
+// ASIMD max/min, reduce, 4H/4S
+def : InstRW<[TSV110Wr_4cyc_1FSU1_1FSU2], (instregex "^[SU](MIN|MAX)V(v4i16|v4i32)v$")>;
+// ASIMD max/min, reduce, 8B/8H
+def : InstRW<[TSV110Wr_8cyc_1FSU1_1FSU2], (instregex "^[SU](MIN|MAX)V(v8i8|v8i16)v$")>;
+// ASIMD max/min, reduce, 16B
+def : InstRW<[TSV110Wr_8cyc_1FSU1_1FSU2], (instregex "^[SU](MIN|MAX)Vv16i8v$")>;
+
+
+// Vector - Floating Point
+// -----------------------------------------------------------------------------
+
+// Reference for forms in this group
+// D form - v2f32
+// Q form - v4f32, v2f64
+// D form - 32, 64
+// D form - v1i32, v1i64
+// D form - v2i32
+// Q form - v4i32, v2i64
+
+// ASIMD FP sign manipulation
+def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^FABSv")>;
+def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^FNEGv")>;
+
+// ASIMD FP compare
+def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^F(AC|CM)(EQ|GE|GT|LE|LT)v")>;
+
+// ASIMD FP convert
+def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^FCVT[AMNPZ][SU]v")>;
+def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^FCVT(L)v")>;
+def : InstRW<[TSV110Wr_5cyc_1F], (instregex "^FCVT(N|XN)v")>;
+
+// ASIMD FP divide, D-form, F32
+def : InstRW<[TSV110Wr_11cyc_1FSU1], (instregex "FDIVv2f32")>;
+// ASIMD FP divide, Q-form, F32
+def : InstRW<[TSV110Wr_24cyc_1FSU1], (instregex "FDIVv4f32")>;
+// ASIMD FP divide, Q-form, F64
+def : InstRW<[TSV110Wr_38cyc_1FSU1], (instregex "FDIVv2f64")>;
+
+// ASIMD FP SQRT
+def : InstRW<[TSV110Wr_17cyc_1FSU2], (instrs FSQRTv2f32)>;
+def : InstRW<[TSV110Wr_36cyc_1FSU2], (instrs FSQRTv4f32)>;
+def : InstRW<[TSV110Wr_64cyc_1FSU2], (instrs FSQRTv2f64)>;
+
+// ASIMD FP max,min
+def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^F(MAX|MIN)(NM)?v")>;
+def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^F(MAX|MIN)(NM)?Pv")>;
+def : InstRW<[TSV110Wr_4cyc_1F], (instregex "^F(MAX|MIN)(NM)?Vv")>;
+
+// ASIMD FP add
+def : InstRW<[TSV110Wr_5cyc_1F], (instregex "^F(ADD|ADDP|SUB)v")>;
+
+// ASIMD FP multiply
+def : InstRW<[TSV110Wr_5cyc_1F], (instregex "^FMULX?v")>;
+
+
+// ASIMD Miscellaneous Instructions
+// -----------------------------------------------------------------------------
+
+def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^(CLS|CLZ|CNT)v")>;
+def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^(DUP|INS)v.+lane")>;
+def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^REV(16|32|64)v")>;
+def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^(UZP|ZIP)[12]v")>;
+
+def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^EXTv")>;
+def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^XTNv")>;
+def : InstRW<[TSV110Wr_2cyc_1FSU1_1FSU2], (instregex "^RBITv")>;
+
+def : InstRW<[TSV110Wr_4cyc_1F], (instregex "^(INS|DUP)v.+gpr")>;
+
+def : InstRW<[TSV110Wr_3cyc_1FSU1], (instregex "^[SU]MOVv")>;
+
+// ASIMD table lookup, D-form
+def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^TB[LX]v8i8One")>;
+def : InstRW<[TSV110Wr_4cyc_2F], (instregex "^TB[LX]v8i8Two")>;
+def : InstRW<[TSV110Wr_6cyc_3F], (instregex "^TB[LX]v8i8Three")>;
+def : InstRW<[TSV110Wr_8cyc_4F], (instregex "^TB[LX]v8i8Four")>;
+// ASIMD table lookup, Q-form
+def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^TB[LX]v16i8One")>;
+def : InstRW<[TSV110Wr_4cyc_2F], (instregex "^TB[LX]v16i8Two")>;
+def : InstRW<[TSV110Wr_6cyc_3F], (instregex "^TB[LX]v16i8Three")>;
+def : InstRW<[TSV110Wr_8cyc_4F], (instregex "^TB[LX]v16i8Four")>;
+
+def : InstRW<[TSV110Wr_2cyc_1F], (instregex "^FMOVv")>;
+
+def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^FRINT[AIMNPXZ]v")>;
+def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^[SU]CVTFv")>;
+def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^[FU](RECP|RSQRT)(E|X)v")>;
+
+
+// ASIMD Load Instructions
+// -----------------------------------------------------------------------------
+
+def : InstRW<[TSV110Wr_7cyc_1F_1LdSt], (instregex "^LD1Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[TSV110Wr_7cyc_1F_1LdSt, WriteAdr], (instregex "^LD1Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+def : InstRW<[TSV110Wr_7cyc_2F_1LdSt], (instregex "^LD2Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[TSV110Wr_7cyc_2F_1LdSt, WriteAdr], (instregex "^LD2Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+def : InstRW<[TSV110Wr_8cyc_3F_1LdSt], (instregex "^LD3Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[TSV110Wr_8cyc_3F_1LdSt, WriteAdr], (instregex "^LD3Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+def : InstRW<[TSV110Wr_8cyc_3F_2LdSt], (instregex "^LD4Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[TSV110Wr_8cyc_3F_2LdSt, WriteAdr], (instregex "^LD4Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+def : InstRW<[TSV110Wr_7cyc_1F_1LdSt], (instregex "LD1i(8|16|32|64)$")>;
+def : InstRW<[TSV110Wr_7cyc_1F_1LdSt, WriteAdr], (instregex "LD1i(8|16|32|64)_POST$")>;
+def : InstRW<[TSV110Wr_7cyc_2F_1LdSt], (instregex "LD2i(8|16|32|64)$")>;
+def : InstRW<[TSV110Wr_7cyc_2F_1LdSt, WriteAdr], (instregex "LD2i(8|16|32|64)_POST$")>;
+def : InstRW<[TSV110Wr_8cyc_3F_1LdSt], (instregex "LD3i(8|16|32|64)$")>;
+def : InstRW<[TSV110Wr_8cyc_3F_1LdSt, WriteAdr], (instregex "LD3i(8|16|32|64)_POST$")>;
+def : InstRW<[TSV110Wr_8cyc_3F_2LdSt], (instregex "LD4i(8|16|32|64)$")>;
+def : InstRW<[TSV110Wr_8cyc_3F_2LdSt, WriteAdr], (instregex "LD4i(8|16|32|64)_POST$")>;
+
+def : InstRW<[TSV110Wr_5cyc_1LdSt], (instregex "^LD1Onev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[TSV110Wr_5cyc_1LdSt, WriteAdr], (instregex "^LD1Onev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+def : InstRW<[TSV110Wr_5cyc_1LdSt], (instregex "^LD1Twov(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[TSV110Wr_5cyc_1LdSt, WriteAdr], (instregex "^LD1Twov(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+def : InstRW<[TSV110Wr_6cyc_3LdSt], (instregex "^LD1Threev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[TSV110Wr_6cyc_3LdSt, WriteAdr], (instregex "^LD1Threev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+def : InstRW<[TSV110Wr_6cyc_2LdSt], (instregex "^LD1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[TSV110Wr_6cyc_2LdSt, WriteAdr], (instregex "^LD1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+def : InstRW<[TSV110Wr_7cyc_2F_1LdSt], (instregex "^LD2Twov(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[TSV110Wr_7cyc_2F_1LdSt, WriteAdr], (instregex "^LD2Twov(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+def : InstRW<[TSV110Wr_8cyc_3F_1LdSt], (instregex "^LD3Threev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[TSV110Wr_8cyc_3F_1LdSt, WriteAdr], (instregex "^LD3Threev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+def : InstRW<[TSV110Wr_10cyc_4F_4LdSt], (instregex "^LD4Fourv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[TSV110Wr_10cyc_4F_4LdSt, WriteAdr], (instregex "^LD4Fourv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+
+// ASIMD Store Instructions
+// -----------------------------------------------------------------------------
+
+def : InstRW<[TSV110Wr_3cyc_1F], (instregex "ST1i(8|16|32|64)$")>;
+def : InstRW<[TSV110Wr_3cyc_1F, WriteAdr], (instregex "ST1i(8|16|32|64)_POST$")>;
+def : InstRW<[TSV110Wr_4cyc_1F], (instregex "ST2i(8|16|32|64)$")>;
+def : InstRW<[TSV110Wr_4cyc_1F, WriteAdr], (instregex "ST2i(8|16|32|64)_POST$")>;
+def : InstRW<[TSV110Wr_5cyc_1F], (instregex "ST3i(8|16|32|64)$")>;
+def : InstRW<[TSV110Wr_5cyc_1F, WriteAdr], (instregex "ST3i(8|16|32|64)_POST$")>;
+def : InstRW<[TSV110Wr_6cyc_1F], (instregex "ST4i(8|16|32|64)$")>;
+def : InstRW<[TSV110Wr_6cyc_1F, WriteAdr], (instregex "ST4i(8|16|32|64)_POST$")>;
+
+def : InstRW<[TSV110Wr_3cyc_1F], (instregex "^ST1Onev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[TSV110Wr_3cyc_1F, WriteAdr], (instregex "^ST1Onev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+def : InstRW<[TSV110Wr_4cyc_1F], (instregex "^ST1Twov(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[TSV110Wr_4cyc_1F, WriteAdr], (instregex "^ST1Twov(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+def : InstRW<[TSV110Wr_5cyc_1F], (instregex "^ST1Threev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[TSV110Wr_5cyc_1F, WriteAdr], (instregex "^ST1Threev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+def : InstRW<[TSV110Wr_6cyc_1F], (instregex "^ST1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[TSV110Wr_6cyc_1F, WriteAdr], (instregex "^ST1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+def : InstRW<[TSV110Wr_4cyc_1F], (instregex "^ST2Twov(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[TSV110Wr_4cyc_1F, WriteAdr], (instregex "^ST2Twov(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+def : InstRW<[TSV110Wr_5cyc_1F], (instregex "^ST3Threev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[TSV110Wr_5cyc_1F, WriteAdr], (instregex "^ST3Threev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+def : InstRW<[TSV110Wr_8cyc_1F], (instregex "^ST4Fourv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
+def : InstRW<[TSV110Wr_8cyc_1F, WriteAdr], (instregex "^ST4Fourv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
+
+} // SchedModel = TSV110Model
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
index 38ab512c56..a5bc3668ed 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
@@ -82,8 +82,8 @@ static SDValue EmitUnrolledSetTag(SelectionDAG &DAG, const SDLoc &dl,
unsigned OffsetScaled = 0;
while (OffsetScaled < ObjSizeScaled) {
if (ObjSizeScaled - OffsetScaled >= 2) {
- SDValue AddrNode =
- DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(OffsetScaled * 16), dl);
+ SDValue AddrNode =
+ DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(OffsetScaled * 16), dl);
SDValue St = DAG.getMemIntrinsicNode(
OpCode2, dl, DAG.getVTList(MVT::Other),
{Chain, TagSrc, AddrNode},
@@ -95,8 +95,8 @@ static SDValue EmitUnrolledSetTag(SelectionDAG &DAG, const SDLoc &dl,
}
if (ObjSizeScaled - OffsetScaled > 0) {
- SDValue AddrNode =
- DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(OffsetScaled * 16), dl);
+ SDValue AddrNode =
+ DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(OffsetScaled * 16), dl);
SDValue St = DAG.getMemIntrinsicNode(
OpCode1, dl, DAG.getVTList(MVT::Other),
{Chain, TagSrc, AddrNode},
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64StackTagging.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64StackTagging.cpp
index 93dfda439d..ab49e0c3f9 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64StackTagging.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64StackTagging.cpp
@@ -59,7 +59,7 @@
using namespace llvm;
-#define DEBUG_TYPE "aarch64-stack-tagging"
+#define DEBUG_TYPE "aarch64-stack-tagging"
static cl::opt<bool> ClMergeInit(
"stack-tagging-merge-init", cl::Hidden, cl::init(true), cl::ZeroOrMore,
@@ -73,10 +73,10 @@ static cl::opt<bool>
static cl::opt<unsigned> ClScanLimit("stack-tagging-merge-init-scan-limit",
cl::init(40), cl::Hidden);
-static cl::opt<unsigned>
- ClMergeInitSizeLimit("stack-tagging-merge-init-size-limit", cl::init(272),
- cl::Hidden);
-
+static cl::opt<unsigned>
+ ClMergeInitSizeLimit("stack-tagging-merge-init-size-limit", cl::init(272),
+ cl::Hidden);
+
static const Align kTagGranuleSize = Align(16);
namespace {
@@ -107,10 +107,10 @@ public:
SetTagZeroFn(SetTagZeroFn), StgpFn(StgpFn) {}
bool addRange(uint64_t Start, uint64_t End, Instruction *Inst) {
- auto I =
- llvm::lower_bound(Ranges, Start, [](const Range &LHS, uint64_t RHS) {
- return LHS.End <= RHS;
- });
+ auto I =
+ llvm::lower_bound(Ranges, Start, [](const Range &LHS, uint64_t RHS) {
+ return LHS.End <= RHS;
+ });
if (I != Ranges.end() && End > I->Start) {
// Overlap - bail.
return false;
@@ -439,8 +439,8 @@ void AArch64StackTagging::tagAlloca(AllocaInst *AI, Instruction *InsertBefore,
bool LittleEndian =
Triple(AI->getModule()->getTargetTriple()).isLittleEndian();
// Current implementation of initializer merging assumes little endianness.
- if (MergeInit && !F->hasOptNone() && LittleEndian &&
- Size < ClMergeInitSizeLimit) {
+ if (MergeInit && !F->hasOptNone() && LittleEndian &&
+ Size < ClMergeInitSizeLimit) {
LLVM_DEBUG(dbgs() << "collecting initializers for " << *AI
<< ", size = " << Size << "\n");
InsertBefore = collectInitializers(InsertBefore, Ptr, Size, IB);
@@ -571,7 +571,7 @@ bool AArch64StackTagging::runOnFunction(Function &Fn) {
auto *II = dyn_cast<IntrinsicInst>(I);
if (II && (II->getIntrinsicID() == Intrinsic::lifetime_start ||
II->getIntrinsicID() == Intrinsic::lifetime_end)) {
- AllocaInst *AI = findAllocaForValue(II->getArgOperand(1));
+ AllocaInst *AI = findAllocaForValue(II->getArgOperand(1));
if (!AI) {
UnrecognizedLifetimes.push_back(I);
continue;
@@ -659,7 +659,7 @@ bool AArch64StackTagging::runOnFunction(Function &Fn) {
IntrinsicInst *Start = Info.LifetimeStart[0];
IntrinsicInst *End = Info.LifetimeEnd[0];
uint64_t Size =
- cast<ConstantInt>(Start->getArgOperand(0))->getZExtValue();
+ cast<ConstantInt>(Start->getArgOperand(0))->getZExtValue();
Size = alignTo(Size, kTagGranuleSize);
tagAlloca(AI, Start->getNextNode(), Start->getArgOperand(1), Size);
// We need to ensure that if we tag some object, we certainly untag it
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64StackTaggingPreRA.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64StackTaggingPreRA.cpp
index 4e64b6116e..41096a9613 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64StackTaggingPreRA.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64StackTaggingPreRA.cpp
@@ -49,12 +49,12 @@ cl::opt<UncheckedLdStMode> ClUncheckedLdSt(
"apply unchecked-ld-st when the target is definitely within range"),
clEnumValN(UncheckedAlways, "always", "always apply unchecked-ld-st")));
-static cl::opt<bool>
- ClFirstSlot("stack-tagging-first-slot-opt", cl::Hidden, cl::init(true),
- cl::ZeroOrMore,
- cl::desc("Apply first slot optimization for stack tagging "
- "(eliminate ADDG Rt, Rn, 0, 0)."));
-
+static cl::opt<bool>
+ ClFirstSlot("stack-tagging-first-slot-opt", cl::Hidden, cl::init(true),
+ cl::ZeroOrMore,
+ cl::desc("Apply first slot optimization for stack tagging "
+ "(eliminate ADDG Rt, Rn, 0, 0)."));
+
namespace {
class AArch64StackTaggingPreRA : public MachineFunctionPass {
@@ -76,7 +76,7 @@ public:
bool mayUseUncheckedLoadStore();
void uncheckUsesOf(unsigned TaggedReg, int FI);
void uncheckLoadsAndStores();
- Optional<int> findFirstSlotCandidate();
+ Optional<int> findFirstSlotCandidate();
bool runOnMachineFunction(MachineFunction &Func) override;
StringRef getPassName() const override {
@@ -203,141 +203,141 @@ void AArch64StackTaggingPreRA::uncheckLoadsAndStores() {
}
}
-struct SlotWithTag {
- int FI;
- int Tag;
- SlotWithTag(int FI, int Tag) : FI(FI), Tag(Tag) {}
- explicit SlotWithTag(const MachineInstr &MI)
- : FI(MI.getOperand(1).getIndex()), Tag(MI.getOperand(4).getImm()) {}
- bool operator==(const SlotWithTag &Other) const {
- return FI == Other.FI && Tag == Other.Tag;
- }
-};
-
-namespace llvm {
-template <> struct DenseMapInfo<SlotWithTag> {
- static inline SlotWithTag getEmptyKey() { return {-2, -2}; }
- static inline SlotWithTag getTombstoneKey() { return {-3, -3}; }
- static unsigned getHashValue(const SlotWithTag &V) {
- return hash_combine(DenseMapInfo<int>::getHashValue(V.FI),
- DenseMapInfo<int>::getHashValue(V.Tag));
- }
- static bool isEqual(const SlotWithTag &A, const SlotWithTag &B) {
- return A == B;
- }
-};
-} // namespace llvm
-
-static bool isSlotPreAllocated(MachineFrameInfo *MFI, int FI) {
- return MFI->getUseLocalStackAllocationBlock() &&
- MFI->isObjectPreAllocated(FI);
-}
-
-// Pin one of the tagged slots to offset 0 from the tagged base pointer.
-// This would make its address available in a virtual register (IRG's def), as
-// opposed to requiring an ADDG instruction to materialize. This effectively
-// eliminates a vreg (by replacing it with direct uses of IRG, which is usually
-// live almost everywhere anyway), and therefore needs to happen before
-// regalloc.
-Optional<int> AArch64StackTaggingPreRA::findFirstSlotCandidate() {
- // Find the best (FI, Tag) pair to pin to offset 0.
- // Looking at the possible uses of a tagged address, the advantage of pinning
- // is:
- // - COPY to physical register.
- // Does not matter, this would trade a MOV instruction for an ADDG.
- // - ST*G matter, but those mostly appear near the function prologue where all
- // the tagged addresses need to be materialized anyway; also, counting ST*G
- // uses would overweight large allocas that require more than one ST*G
- // instruction.
- // - Load/Store instructions in the address operand do not require a tagged
- // pointer, so they also do not benefit. These operands have already been
- // eliminated (see uncheckLoadsAndStores) so all remaining load/store
- // instructions count.
- // - Any other instruction may benefit from being pinned to offset 0.
- LLVM_DEBUG(dbgs() << "AArch64StackTaggingPreRA::findFirstSlotCandidate\n");
- if (!ClFirstSlot)
- return None;
-
- DenseMap<SlotWithTag, int> RetagScore;
- SlotWithTag MaxScoreST{-1, -1};
- int MaxScore = -1;
- for (auto *I : ReTags) {
- SlotWithTag ST{*I};
- if (isSlotPreAllocated(MFI, ST.FI))
- continue;
-
- Register RetagReg = I->getOperand(0).getReg();
- if (!Register::isVirtualRegister(RetagReg))
- continue;
-
- int Score = 0;
- SmallVector<Register, 8> WorkList;
- WorkList.push_back(RetagReg);
-
- while (!WorkList.empty()) {
- Register UseReg = WorkList.back();
- WorkList.pop_back();
- for (auto &UseI : MRI->use_instructions(UseReg)) {
- unsigned Opcode = UseI.getOpcode();
- if (Opcode == AArch64::STGOffset || Opcode == AArch64::ST2GOffset ||
- Opcode == AArch64::STZGOffset || Opcode == AArch64::STZ2GOffset ||
- Opcode == AArch64::STGPi || Opcode == AArch64::STGloop ||
- Opcode == AArch64::STZGloop || Opcode == AArch64::STGloop_wback ||
- Opcode == AArch64::STZGloop_wback)
- continue;
- if (UseI.isCopy()) {
- Register DstReg = UseI.getOperand(0).getReg();
- if (Register::isVirtualRegister(DstReg))
- WorkList.push_back(DstReg);
- continue;
- }
- LLVM_DEBUG(dbgs() << "[" << ST.FI << ":" << ST.Tag << "] use of %"
- << Register::virtReg2Index(UseReg) << " in " << UseI
- << "\n");
- Score++;
- }
- }
-
- int TotalScore = RetagScore[ST] += Score;
- if (TotalScore > MaxScore ||
- (TotalScore == MaxScore && ST.FI > MaxScoreST.FI)) {
- MaxScore = TotalScore;
- MaxScoreST = ST;
- }
- }
-
- if (MaxScoreST.FI < 0)
- return None;
-
- // If FI's tag is already 0, we are done.
- if (MaxScoreST.Tag == 0)
- return MaxScoreST.FI;
-
- // Otherwise, find a random victim pair (FI, Tag) where Tag == 0.
- SlotWithTag SwapST{-1, -1};
- for (auto *I : ReTags) {
- SlotWithTag ST{*I};
- if (ST.Tag == 0) {
- SwapST = ST;
- break;
- }
- }
-
- // Swap tags between the victim and the highest scoring pair.
- // If SwapWith is still (-1, -1), that's fine, too - we'll simply take tag for
- // the highest score slot without changing anything else.
- for (auto *&I : ReTags) {
- SlotWithTag ST{*I};
- MachineOperand &TagOp = I->getOperand(4);
- if (ST == MaxScoreST) {
- TagOp.setImm(0);
- } else if (ST == SwapST) {
- TagOp.setImm(MaxScoreST.Tag);
- }
- }
- return MaxScoreST.FI;
-}
-
+struct SlotWithTag {
+ int FI;
+ int Tag;
+ SlotWithTag(int FI, int Tag) : FI(FI), Tag(Tag) {}
+ explicit SlotWithTag(const MachineInstr &MI)
+ : FI(MI.getOperand(1).getIndex()), Tag(MI.getOperand(4).getImm()) {}
+ bool operator==(const SlotWithTag &Other) const {
+ return FI == Other.FI && Tag == Other.Tag;
+ }
+};
+
+namespace llvm {
+template <> struct DenseMapInfo<SlotWithTag> {
+ static inline SlotWithTag getEmptyKey() { return {-2, -2}; }
+ static inline SlotWithTag getTombstoneKey() { return {-3, -3}; }
+ static unsigned getHashValue(const SlotWithTag &V) {
+ return hash_combine(DenseMapInfo<int>::getHashValue(V.FI),
+ DenseMapInfo<int>::getHashValue(V.Tag));
+ }
+ static bool isEqual(const SlotWithTag &A, const SlotWithTag &B) {
+ return A == B;
+ }
+};
+} // namespace llvm
+
+static bool isSlotPreAllocated(MachineFrameInfo *MFI, int FI) {
+ return MFI->getUseLocalStackAllocationBlock() &&
+ MFI->isObjectPreAllocated(FI);
+}
+
+// Pin one of the tagged slots to offset 0 from the tagged base pointer.
+// This would make its address available in a virtual register (IRG's def), as
+// opposed to requiring an ADDG instruction to materialize. This effectively
+// eliminates a vreg (by replacing it with direct uses of IRG, which is usually
+// live almost everywhere anyway), and therefore needs to happen before
+// regalloc.
+Optional<int> AArch64StackTaggingPreRA::findFirstSlotCandidate() {
+ // Find the best (FI, Tag) pair to pin to offset 0.
+ // Looking at the possible uses of a tagged address, the advantage of pinning
+ // is:
+ // - COPY to physical register.
+ // Does not matter, this would trade a MOV instruction for an ADDG.
+ // - ST*G matter, but those mostly appear near the function prologue where all
+ // the tagged addresses need to be materialized anyway; also, counting ST*G
+ // uses would overweight large allocas that require more than one ST*G
+ // instruction.
+ // - Load/Store instructions in the address operand do not require a tagged
+ // pointer, so they also do not benefit. These operands have already been
+ // eliminated (see uncheckLoadsAndStores) so all remaining load/store
+ // instructions count.
+ // - Any other instruction may benefit from being pinned to offset 0.
+ LLVM_DEBUG(dbgs() << "AArch64StackTaggingPreRA::findFirstSlotCandidate\n");
+ if (!ClFirstSlot)
+ return None;
+
+ DenseMap<SlotWithTag, int> RetagScore;
+ SlotWithTag MaxScoreST{-1, -1};
+ int MaxScore = -1;
+ for (auto *I : ReTags) {
+ SlotWithTag ST{*I};
+ if (isSlotPreAllocated(MFI, ST.FI))
+ continue;
+
+ Register RetagReg = I->getOperand(0).getReg();
+ if (!Register::isVirtualRegister(RetagReg))
+ continue;
+
+ int Score = 0;
+ SmallVector<Register, 8> WorkList;
+ WorkList.push_back(RetagReg);
+
+ while (!WorkList.empty()) {
+ Register UseReg = WorkList.back();
+ WorkList.pop_back();
+ for (auto &UseI : MRI->use_instructions(UseReg)) {
+ unsigned Opcode = UseI.getOpcode();
+ if (Opcode == AArch64::STGOffset || Opcode == AArch64::ST2GOffset ||
+ Opcode == AArch64::STZGOffset || Opcode == AArch64::STZ2GOffset ||
+ Opcode == AArch64::STGPi || Opcode == AArch64::STGloop ||
+ Opcode == AArch64::STZGloop || Opcode == AArch64::STGloop_wback ||
+ Opcode == AArch64::STZGloop_wback)
+ continue;
+ if (UseI.isCopy()) {
+ Register DstReg = UseI.getOperand(0).getReg();
+ if (Register::isVirtualRegister(DstReg))
+ WorkList.push_back(DstReg);
+ continue;
+ }
+ LLVM_DEBUG(dbgs() << "[" << ST.FI << ":" << ST.Tag << "] use of %"
+ << Register::virtReg2Index(UseReg) << " in " << UseI
+ << "\n");
+ Score++;
+ }
+ }
+
+ int TotalScore = RetagScore[ST] += Score;
+ if (TotalScore > MaxScore ||
+ (TotalScore == MaxScore && ST.FI > MaxScoreST.FI)) {
+ MaxScore = TotalScore;
+ MaxScoreST = ST;
+ }
+ }
+
+ if (MaxScoreST.FI < 0)
+ return None;
+
+ // If FI's tag is already 0, we are done.
+ if (MaxScoreST.Tag == 0)
+ return MaxScoreST.FI;
+
+ // Otherwise, find a random victim pair (FI, Tag) where Tag == 0.
+ SlotWithTag SwapST{-1, -1};
+ for (auto *I : ReTags) {
+ SlotWithTag ST{*I};
+ if (ST.Tag == 0) {
+ SwapST = ST;
+ break;
+ }
+ }
+
+ // Swap tags between the victim and the highest scoring pair.
+ // If SwapWith is still (-1, -1), that's fine, too - we'll simply take tag for
+ // the highest score slot without changing anything else.
+ for (auto *&I : ReTags) {
+ SlotWithTag ST{*I};
+ MachineOperand &TagOp = I->getOperand(4);
+ if (ST == MaxScoreST) {
+ TagOp.setImm(0);
+ } else if (ST == SwapST) {
+ TagOp.setImm(MaxScoreST.Tag);
+ }
+ }
+ return MaxScoreST.FI;
+}
+
bool AArch64StackTaggingPreRA::runOnMachineFunction(MachineFunction &Func) {
MF = &Func;
MRI = &MF->getRegInfo();
@@ -366,35 +366,35 @@ bool AArch64StackTaggingPreRA::runOnMachineFunction(MachineFunction &Func) {
}
}
- // Take over from SSP. It does nothing for tagged slots, and should not really
- // have been enabled in the first place.
- for (int FI : TaggedSlots)
- MFI->setObjectSSPLayout(FI, MachineFrameInfo::SSPLK_None);
-
+ // Take over from SSP. It does nothing for tagged slots, and should not really
+ // have been enabled in the first place.
+ for (int FI : TaggedSlots)
+ MFI->setObjectSSPLayout(FI, MachineFrameInfo::SSPLK_None);
+
if (ReTags.empty())
return false;
if (mayUseUncheckedLoadStore())
uncheckLoadsAndStores();
- // Find a slot that is used with zero tag offset, like ADDG #fi, 0.
- // If the base tagged pointer is set up to the address of this slot,
- // the ADDG instruction can be eliminated.
- Optional<int> BaseSlot = findFirstSlotCandidate();
- if (BaseSlot)
- AFI->setTaggedBasePointerIndex(*BaseSlot);
-
- for (auto *I : ReTags) {
- int FI = I->getOperand(1).getIndex();
- int Tag = I->getOperand(4).getImm();
- Register Base = I->getOperand(3).getReg();
- if (Tag == 0 && FI == BaseSlot) {
- BuildMI(*I->getParent(), I, {}, TII->get(AArch64::COPY),
- I->getOperand(0).getReg())
- .addReg(Base);
- I->eraseFromParent();
- }
- }
-
+ // Find a slot that is used with zero tag offset, like ADDG #fi, 0.
+ // If the base tagged pointer is set up to the address of this slot,
+ // the ADDG instruction can be eliminated.
+ Optional<int> BaseSlot = findFirstSlotCandidate();
+ if (BaseSlot)
+ AFI->setTaggedBasePointerIndex(*BaseSlot);
+
+ for (auto *I : ReTags) {
+ int FI = I->getOperand(1).getIndex();
+ int Tag = I->getOperand(4).getImm();
+ Register Base = I->getOperand(3).getReg();
+ if (Tag == 0 && FI == BaseSlot) {
+ BuildMI(*I->getParent(), I, {}, TII->get(AArch64::COPY),
+ I->getOperand(0).getReg())
+ .addReg(Base);
+ I->eraseFromParent();
+ }
+ }
+
return true;
}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64Subtarget.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64Subtarget.cpp
index f78643d8e7..71b2bb1964 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64Subtarget.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64Subtarget.cpp
@@ -67,7 +67,7 @@ AArch64Subtarget::initializeSubtargetDependencies(StringRef FS,
if (CPUString.empty())
CPUString = "generic";
- ParseSubtargetFeatures(CPUString, /*TuneCPU*/ CPUString, FS);
+ ParseSubtargetFeatures(CPUString, /*TuneCPU*/ CPUString, FS);
initializeProperties();
return *this;
@@ -103,26 +103,26 @@ void AArch64Subtarget::initializeProperties() {
case CortexA76:
case CortexA77:
case CortexA78:
- case CortexA78C:
- case CortexR82:
+ case CortexA78C:
+ case CortexR82:
case CortexX1:
PrefFunctionLogAlignment = 4;
break;
case A64FX:
CacheLineSize = 256;
- PrefFunctionLogAlignment = 3;
- PrefLoopLogAlignment = 2;
- MaxInterleaveFactor = 4;
- PrefetchDistance = 128;
- MinPrefetchStride = 1024;
- MaxPrefetchIterationsAhead = 4;
+ PrefFunctionLogAlignment = 3;
+ PrefLoopLogAlignment = 2;
+ MaxInterleaveFactor = 4;
+ PrefetchDistance = 128;
+ MinPrefetchStride = 1024;
+ MaxPrefetchIterationsAhead = 4;
break;
case AppleA7:
case AppleA10:
case AppleA11:
case AppleA12:
case AppleA13:
- case AppleA14:
+ case AppleA14:
CacheLineSize = 64;
PrefetchDistance = 280;
MinPrefetchStride = 2048;
@@ -157,8 +157,8 @@ void AArch64Subtarget::initializeProperties() {
PrefFunctionLogAlignment = 3;
break;
case NeoverseN1:
- case NeoverseN2:
- case NeoverseV1:
+ case NeoverseN2:
+ case NeoverseV1:
PrefFunctionLogAlignment = 4;
break;
case Saphira:
@@ -209,7 +209,7 @@ void AArch64Subtarget::initializeProperties() {
AArch64Subtarget::AArch64Subtarget(const Triple &TT, const std::string &CPU,
const std::string &FS,
const TargetMachine &TM, bool LittleEndian)
- : AArch64GenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS),
+ : AArch64GenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS),
ReserveXRegister(AArch64::GPR64commonRegClass.getNumRegs()),
CustomCallSavedXRegs(AArch64::GPR64commonRegClass.getNumRegs()),
IsLittle(LittleEndian),
@@ -375,8 +375,8 @@ unsigned AArch64Subtarget::getMinSVEVectorSizeInBits() const {
return (SVEVectorBitsMin / 128) * 128;
return (std::min(SVEVectorBitsMin, SVEVectorBitsMax) / 128) * 128;
}
-
-bool AArch64Subtarget::useSVEForFixedLengthVectors() const {
- // Prefer NEON unless larger SVE registers are available.
- return hasSVE() && getMinSVEVectorSizeInBits() >= 256;
-}
+
+bool AArch64Subtarget::useSVEForFixedLengthVectors() const {
+ // Prefer NEON unless larger SVE registers are available.
+ return hasSVE() && getMinSVEVectorSizeInBits() >= 256;
+}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64Subtarget.h b/contrib/libs/llvm12/lib/Target/AArch64/AArch64Subtarget.h
index ce401f4986..8fe2f12598 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64Subtarget.h
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64Subtarget.h
@@ -45,7 +45,7 @@ public:
AppleA11,
AppleA12,
AppleA13,
- AppleA14,
+ AppleA14,
Carmel,
CortexA35,
CortexA53,
@@ -58,24 +58,24 @@ public:
CortexA76,
CortexA77,
CortexA78,
- CortexA78C,
- CortexR82,
+ CortexA78C,
+ CortexR82,
CortexX1,
ExynosM3,
Falkor,
Kryo,
NeoverseE1,
NeoverseN1,
- NeoverseN2,
- NeoverseV1,
+ NeoverseN2,
+ NeoverseV1,
Saphira,
ThunderX2T99,
ThunderX,
ThunderXT81,
ThunderXT83,
ThunderXT88,
- ThunderX3T110,
- TSV110
+ ThunderX3T110,
+ TSV110
};
protected:
@@ -88,11 +88,11 @@ protected:
bool HasV8_4aOps = false;
bool HasV8_5aOps = false;
bool HasV8_6aOps = false;
- bool HasV8_7aOps = false;
+ bool HasV8_7aOps = false;
+
+ bool HasV8_0rOps = false;
+ bool HasCONTEXTIDREL2 = false;
- bool HasV8_0rOps = false;
- bool HasCONTEXTIDREL2 = false;
-
bool HasFPARMv8 = false;
bool HasNEON = false;
bool HasCrypto = false;
@@ -127,7 +127,7 @@ protected:
bool HasAES = false;
// ARMv8.3 extensions
- bool HasPAuth = false;
+ bool HasPAuth = false;
bool HasJS = false;
bool HasCCIDX = false;
bool HasComplxNum = false;
@@ -141,7 +141,7 @@ protected:
bool HasSEL2 = false;
bool HasPMU = false;
bool HasTLB_RMI = false;
- bool HasFlagM = false;
+ bool HasFlagM = false;
bool HasRCPC_IMMO = false;
bool HasLSLFast = false;
@@ -170,12 +170,12 @@ protected:
bool HasFineGrainedTraps = false;
bool HasEnhancedCounterVirtualization = false;
- // Armv8.7-A Extensions
- bool HasXS = false;
- bool HasWFxT = false;
- bool HasHCX = false;
- bool HasLS64 = false;
-
+ // Armv8.7-A Extensions
+ bool HasXS = false;
+ bool HasWFxT = false;
+ bool HasHCX = false;
+ bool HasLS64 = false;
+
// Arm SVE2 extensions
bool HasSVE2 = false;
bool HasSVE2AES = false;
@@ -186,9 +186,9 @@ protected:
// Future architecture extensions.
bool HasETE = false;
bool HasTRBE = false;
- bool HasBRBE = false;
- bool HasPAUTH = false;
- bool HasSPE_EEF = false;
+ bool HasBRBE = false;
+ bool HasPAUTH = false;
+ bool HasSPE_EEF = false;
// HasZeroCycleRegMove - Has zero-cycle register mov instructions.
bool HasZeroCycleRegMove = false;
@@ -208,7 +208,7 @@ protected:
// Enable 64-bit vectorization in SLP.
unsigned MinVectorRegisterBitWidth = 64;
- bool OutlineAtomics = false;
+ bool OutlineAtomics = false;
bool UseAA = false;
bool PredictableSelectIsExpensive = false;
bool BalanceFPOps = false;
@@ -221,7 +221,7 @@ protected:
bool UseAlternateSExtLoadCVTF32Pattern = false;
bool HasArithmeticBccFusion = false;
bool HasArithmeticCbzFusion = false;
- bool HasCmpBccFusion = false;
+ bool HasCmpBccFusion = false;
bool HasFuseAddress = false;
bool HasFuseAES = false;
bool HasFuseArithmeticLogic = false;
@@ -325,7 +325,7 @@ public:
bool hasV8_3aOps() const { return HasV8_3aOps; }
bool hasV8_4aOps() const { return HasV8_4aOps; }
bool hasV8_5aOps() const { return HasV8_5aOps; }
- bool hasV8_0rOps() const { return HasV8_0rOps; }
+ bool hasV8_0rOps() const { return HasV8_0rOps; }
bool hasZeroCycleRegMove() const { return HasZeroCycleRegMove; }
@@ -363,7 +363,7 @@ public:
bool hasSHA3() const { return HasSHA3; }
bool hasSHA2() const { return HasSHA2; }
bool hasAES() const { return HasAES; }
- bool hasCONTEXTIDREL2() const { return HasCONTEXTIDREL2; }
+ bool hasCONTEXTIDREL2() const { return HasCONTEXTIDREL2; }
bool balanceFPOps() const { return BalanceFPOps; }
bool predictableSelectIsExpensive() const {
return PredictableSelectIsExpensive;
@@ -378,7 +378,7 @@ public:
}
bool hasArithmeticBccFusion() const { return HasArithmeticBccFusion; }
bool hasArithmeticCbzFusion() const { return HasArithmeticCbzFusion; }
- bool hasCmpBccFusion() const { return HasCmpBccFusion; }
+ bool hasCmpBccFusion() const { return HasCmpBccFusion; }
bool hasFuseAddress() const { return HasFuseAddress; }
bool hasFuseAES() const { return HasFuseAES; }
bool hasFuseArithmeticLogic() const { return HasFuseArithmeticLogic; }
@@ -454,7 +454,7 @@ public:
bool hasRandGen() const { return HasRandGen; }
bool hasMTE() const { return HasMTE; }
bool hasTME() const { return HasTME; }
- bool hasPAUTH() const { return HasPAUTH; }
+ bool hasPAUTH() const { return HasPAUTH; }
// Arm SVE2 extensions
bool hasSVE2AES() const { return HasSVE2AES; }
bool hasSVE2SM4() const { return HasSVE2SM4; }
@@ -484,15 +484,15 @@ public:
bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
- bool isTargetILP32() const {
- return TargetTriple.isArch32Bit() ||
- TargetTriple.getEnvironment() == Triple::GNUILP32;
- }
+ bool isTargetILP32() const {
+ return TargetTriple.isArch32Bit() ||
+ TargetTriple.getEnvironment() == Triple::GNUILP32;
+ }
bool useAA() const override { return UseAA; }
- bool outlineAtomics() const { return OutlineAtomics; }
-
+ bool outlineAtomics() const { return OutlineAtomics; }
+
bool hasVH() const { return HasVH; }
bool hasPAN() const { return HasPAN; }
bool hasLOR() const { return HasLOR; }
@@ -501,7 +501,7 @@ public:
bool hasPAN_RWV() const { return HasPAN_RWV; }
bool hasCCPP() const { return HasCCPP; }
- bool hasPAuth() const { return HasPAuth; }
+ bool hasPAuth() const { return HasPAuth; }
bool hasJS() const { return HasJS; }
bool hasCCIDX() const { return HasCCIDX; }
bool hasComplxNum() const { return HasComplxNum; }
@@ -512,14 +512,14 @@ public:
bool hasTRACEV8_4() const { return HasTRACEV8_4; }
bool hasAM() const { return HasAM; }
bool hasAMVS() const { return HasAMVS; }
- bool hasXS() const { return HasXS; }
- bool hasWFxT() const { return HasWFxT; }
- bool hasHCX() const { return HasHCX; }
- bool hasLS64() const { return HasLS64; }
+ bool hasXS() const { return HasXS; }
+ bool hasWFxT() const { return HasWFxT; }
+ bool hasHCX() const { return HasHCX; }
+ bool hasLS64() const { return HasLS64; }
bool hasSEL2() const { return HasSEL2; }
bool hasPMU() const { return HasPMU; }
bool hasTLB_RMI() const { return HasTLB_RMI; }
- bool hasFlagM() const { return HasFlagM; }
+ bool hasFlagM() const { return HasFlagM; }
bool hasRCPC_IMMO() const { return HasRCPC_IMMO; }
bool addrSinkUsingGEPs() const override {
@@ -542,7 +542,7 @@ public:
/// ParseSubtargetFeatures - Parses features string setting specified
/// subtarget options. Definition of function is auto generated by tblgen.
- void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
+ void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
/// ClassifyGlobalReference - Find the target operand flags that describe
/// how a global value should be referenced for the current subtarget.
@@ -581,7 +581,7 @@ public:
// implied by the architecture.
unsigned getMaxSVEVectorSizeInBits() const;
unsigned getMinSVEVectorSizeInBits() const;
- bool useSVEForFixedLengthVectors() const;
+ bool useSVEForFixedLengthVectors() const;
};
} // End llvm namespace
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64SystemOperands.td b/contrib/libs/llvm12/lib/Target/AArch64/AArch64SystemOperands.td
index 0b9c53a72f..01ac52bd87 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64SystemOperands.td
@@ -32,11 +32,11 @@ def HasPAN_RWV : Predicate<"Subtarget->hasPAN_RWV()">,
AssemblerPredicate<(all_of FeaturePAN_RWV),
"ARM v8.2 PAN AT S1E1R and AT S1E1W Variation">;
-def HasCONTEXTIDREL2
- : Predicate<"Subtarget->hasCONTEXTIDREL2()">,
- AssemblerPredicate<(all_of FeatureCONTEXTIDREL2),
- "Target contains CONTEXTIDR_EL2 RW operand">;
-
+def HasCONTEXTIDREL2
+ : Predicate<"Subtarget->hasCONTEXTIDREL2()">,
+ AssemblerPredicate<(all_of FeatureCONTEXTIDREL2),
+ "Target contains CONTEXTIDR_EL2 RW operand">;
+
//===----------------------------------------------------------------------===//
// AT (address translate) instruction options.
//===----------------------------------------------------------------------===//
@@ -98,21 +98,21 @@ def : DB<"ld", 0xd>;
def : DB<"st", 0xe>;
def : DB<"sy", 0xf>;
-class DBnXS<string name, bits<4> encoding, bits<5> immValue> : SearchableTable {
- let SearchableFields = ["Name", "Encoding", "ImmValue"];
- let EnumValueField = "Encoding";
-
- string Name = name;
- bits<4> Encoding = encoding;
- bits<5> ImmValue = immValue;
- code Requires = [{ {AArch64::FeatureXS} }];
-}
-
-def : DBnXS<"oshnxs", 0x3, 0x10>;
-def : DBnXS<"nshnxs", 0x7, 0x14>;
-def : DBnXS<"ishnxs", 0xb, 0x18>;
-def : DBnXS<"synxs", 0xf, 0x1c>;
-
+class DBnXS<string name, bits<4> encoding, bits<5> immValue> : SearchableTable {
+ let SearchableFields = ["Name", "Encoding", "ImmValue"];
+ let EnumValueField = "Encoding";
+
+ string Name = name;
+ bits<4> Encoding = encoding;
+ bits<5> ImmValue = immValue;
+ code Requires = [{ {AArch64::FeatureXS} }];
+}
+
+def : DBnXS<"oshnxs", 0x3, 0x10>;
+def : DBnXS<"nshnxs", 0x7, 0x14>;
+def : DBnXS<"ishnxs", 0xb, 0x18>;
+def : DBnXS<"synxs", 0xf, 0x1c>;
+
//===----------------------------------------------------------------------===//
// DC (data cache maintenance) instruction options.
//===----------------------------------------------------------------------===//
@@ -404,8 +404,8 @@ def : BTI<"jc", 0b11>;
// TLBI (translation lookaside buffer invalidate) instruction options.
//===----------------------------------------------------------------------===//
-class TLBIEntry<string name, bits<3> op1, bits<4> crn, bits<4> crm,
- bits<3> op2, bit needsreg> {
+class TLBIEntry<string name, bits<3> op1, bits<4> crn, bits<4> crm,
+ bits<3> op2, bit needsreg> {
string Name = name;
bits<14> Encoding;
let Encoding{13-11} = op1;
@@ -413,122 +413,122 @@ class TLBIEntry<string name, bits<3> op1, bits<4> crn, bits<4> crm,
let Encoding{6-3} = crm;
let Encoding{2-0} = op2;
bit NeedsReg = needsreg;
- list<string> Requires = [];
- list<string> ExtraRequires = [];
- code RequiresStr = [{ { }] # !interleave(Requires # ExtraRequires, [{, }]) # [{ } }];
+ list<string> Requires = [];
+ list<string> ExtraRequires = [];
+ code RequiresStr = [{ { }] # !interleave(Requires # ExtraRequires, [{, }]) # [{ } }];
+}
+
+def TLBITable : GenericTable {
+ let FilterClass = "TLBIEntry";
+ let CppTypeName = "TLBI";
+ let Fields = ["Name", "Encoding", "NeedsReg", "RequiresStr"];
+}
+
+def lookupTLBIByName : SearchIndex {
+ let Table = TLBITable;
+ let Key = ["Name"];
}
-def TLBITable : GenericTable {
- let FilterClass = "TLBIEntry";
- let CppTypeName = "TLBI";
- let Fields = ["Name", "Encoding", "NeedsReg", "RequiresStr"];
-}
-
-def lookupTLBIByName : SearchIndex {
- let Table = TLBITable;
- let Key = ["Name"];
-}
-
-def lookupTLBIByEncoding : SearchIndex {
- let Table = TLBITable;
- let Key = ["Encoding"];
-}
-
-multiclass TLBI<string name, bits<3> op1, bits<4> crn, bits<4> crm,
- bits<3> op2, bit needsreg = 1> {
- def : TLBIEntry<name, op1, crn, crm, op2, needsreg>;
- def : TLBIEntry<!strconcat(name, "nXS"), op1, crn, crm, op2, needsreg> {
- let Encoding{7} = 1;
- let ExtraRequires = ["AArch64::FeatureXS"];
- }
-}
-
-defm : TLBI<"IPAS2E1IS", 0b100, 0b1000, 0b0000, 0b001>;
-defm : TLBI<"IPAS2LE1IS", 0b100, 0b1000, 0b0000, 0b101>;
-defm : TLBI<"VMALLE1IS", 0b000, 0b1000, 0b0011, 0b000, 0>;
-defm : TLBI<"ALLE2IS", 0b100, 0b1000, 0b0011, 0b000, 0>;
-defm : TLBI<"ALLE3IS", 0b110, 0b1000, 0b0011, 0b000, 0>;
-defm : TLBI<"VAE1IS", 0b000, 0b1000, 0b0011, 0b001>;
-defm : TLBI<"VAE2IS", 0b100, 0b1000, 0b0011, 0b001>;
-defm : TLBI<"VAE3IS", 0b110, 0b1000, 0b0011, 0b001>;
-defm : TLBI<"ASIDE1IS", 0b000, 0b1000, 0b0011, 0b010>;
-defm : TLBI<"VAAE1IS", 0b000, 0b1000, 0b0011, 0b011>;
-defm : TLBI<"ALLE1IS", 0b100, 0b1000, 0b0011, 0b100, 0>;
-defm : TLBI<"VALE1IS", 0b000, 0b1000, 0b0011, 0b101>;
-defm : TLBI<"VALE2IS", 0b100, 0b1000, 0b0011, 0b101>;
-defm : TLBI<"VALE3IS", 0b110, 0b1000, 0b0011, 0b101>;
-defm : TLBI<"VMALLS12E1IS", 0b100, 0b1000, 0b0011, 0b110, 0>;
-defm : TLBI<"VAALE1IS", 0b000, 0b1000, 0b0011, 0b111>;
-defm : TLBI<"IPAS2E1", 0b100, 0b1000, 0b0100, 0b001>;
-defm : TLBI<"IPAS2LE1", 0b100, 0b1000, 0b0100, 0b101>;
-defm : TLBI<"VMALLE1", 0b000, 0b1000, 0b0111, 0b000, 0>;
-defm : TLBI<"ALLE2", 0b100, 0b1000, 0b0111, 0b000, 0>;
-defm : TLBI<"ALLE3", 0b110, 0b1000, 0b0111, 0b000, 0>;
-defm : TLBI<"VAE1", 0b000, 0b1000, 0b0111, 0b001>;
-defm : TLBI<"VAE2", 0b100, 0b1000, 0b0111, 0b001>;
-defm : TLBI<"VAE3", 0b110, 0b1000, 0b0111, 0b001>;
-defm : TLBI<"ASIDE1", 0b000, 0b1000, 0b0111, 0b010>;
-defm : TLBI<"VAAE1", 0b000, 0b1000, 0b0111, 0b011>;
-defm : TLBI<"ALLE1", 0b100, 0b1000, 0b0111, 0b100, 0>;
-defm : TLBI<"VALE1", 0b000, 0b1000, 0b0111, 0b101>;
-defm : TLBI<"VALE2", 0b100, 0b1000, 0b0111, 0b101>;
-defm : TLBI<"VALE3", 0b110, 0b1000, 0b0111, 0b101>;
-defm : TLBI<"VMALLS12E1", 0b100, 0b1000, 0b0111, 0b110, 0>;
-defm : TLBI<"VAALE1", 0b000, 0b1000, 0b0111, 0b111>;
-
+def lookupTLBIByEncoding : SearchIndex {
+ let Table = TLBITable;
+ let Key = ["Encoding"];
+}
+
+multiclass TLBI<string name, bits<3> op1, bits<4> crn, bits<4> crm,
+ bits<3> op2, bit needsreg = 1> {
+ def : TLBIEntry<name, op1, crn, crm, op2, needsreg>;
+ def : TLBIEntry<!strconcat(name, "nXS"), op1, crn, crm, op2, needsreg> {
+ let Encoding{7} = 1;
+ let ExtraRequires = ["AArch64::FeatureXS"];
+ }
+}
+
+defm : TLBI<"IPAS2E1IS", 0b100, 0b1000, 0b0000, 0b001>;
+defm : TLBI<"IPAS2LE1IS", 0b100, 0b1000, 0b0000, 0b101>;
+defm : TLBI<"VMALLE1IS", 0b000, 0b1000, 0b0011, 0b000, 0>;
+defm : TLBI<"ALLE2IS", 0b100, 0b1000, 0b0011, 0b000, 0>;
+defm : TLBI<"ALLE3IS", 0b110, 0b1000, 0b0011, 0b000, 0>;
+defm : TLBI<"VAE1IS", 0b000, 0b1000, 0b0011, 0b001>;
+defm : TLBI<"VAE2IS", 0b100, 0b1000, 0b0011, 0b001>;
+defm : TLBI<"VAE3IS", 0b110, 0b1000, 0b0011, 0b001>;
+defm : TLBI<"ASIDE1IS", 0b000, 0b1000, 0b0011, 0b010>;
+defm : TLBI<"VAAE1IS", 0b000, 0b1000, 0b0011, 0b011>;
+defm : TLBI<"ALLE1IS", 0b100, 0b1000, 0b0011, 0b100, 0>;
+defm : TLBI<"VALE1IS", 0b000, 0b1000, 0b0011, 0b101>;
+defm : TLBI<"VALE2IS", 0b100, 0b1000, 0b0011, 0b101>;
+defm : TLBI<"VALE3IS", 0b110, 0b1000, 0b0011, 0b101>;
+defm : TLBI<"VMALLS12E1IS", 0b100, 0b1000, 0b0011, 0b110, 0>;
+defm : TLBI<"VAALE1IS", 0b000, 0b1000, 0b0011, 0b111>;
+defm : TLBI<"IPAS2E1", 0b100, 0b1000, 0b0100, 0b001>;
+defm : TLBI<"IPAS2LE1", 0b100, 0b1000, 0b0100, 0b101>;
+defm : TLBI<"VMALLE1", 0b000, 0b1000, 0b0111, 0b000, 0>;
+defm : TLBI<"ALLE2", 0b100, 0b1000, 0b0111, 0b000, 0>;
+defm : TLBI<"ALLE3", 0b110, 0b1000, 0b0111, 0b000, 0>;
+defm : TLBI<"VAE1", 0b000, 0b1000, 0b0111, 0b001>;
+defm : TLBI<"VAE2", 0b100, 0b1000, 0b0111, 0b001>;
+defm : TLBI<"VAE3", 0b110, 0b1000, 0b0111, 0b001>;
+defm : TLBI<"ASIDE1", 0b000, 0b1000, 0b0111, 0b010>;
+defm : TLBI<"VAAE1", 0b000, 0b1000, 0b0111, 0b011>;
+defm : TLBI<"ALLE1", 0b100, 0b1000, 0b0111, 0b100, 0>;
+defm : TLBI<"VALE1", 0b000, 0b1000, 0b0111, 0b101>;
+defm : TLBI<"VALE2", 0b100, 0b1000, 0b0111, 0b101>;
+defm : TLBI<"VALE3", 0b110, 0b1000, 0b0111, 0b101>;
+defm : TLBI<"VMALLS12E1", 0b100, 0b1000, 0b0111, 0b110, 0>;
+defm : TLBI<"VAALE1", 0b000, 0b1000, 0b0111, 0b111>;
+
// Armv8.4-A Translation Lookaside Buffer Instructions (TLBI)
-let Requires = ["AArch64::FeatureTLB_RMI"] in {
+let Requires = ["AArch64::FeatureTLB_RMI"] in {
// Armv8.4-A Outer Sharable TLB Maintenance instructions:
// op1 CRn CRm op2
-defm : TLBI<"VMALLE1OS", 0b000, 0b1000, 0b0001, 0b000, 0>;
-defm : TLBI<"VAE1OS", 0b000, 0b1000, 0b0001, 0b001>;
-defm : TLBI<"ASIDE1OS", 0b000, 0b1000, 0b0001, 0b010>;
-defm : TLBI<"VAAE1OS", 0b000, 0b1000, 0b0001, 0b011>;
-defm : TLBI<"VALE1OS", 0b000, 0b1000, 0b0001, 0b101>;
-defm : TLBI<"VAALE1OS", 0b000, 0b1000, 0b0001, 0b111>;
-defm : TLBI<"IPAS2E1OS", 0b100, 0b1000, 0b0100, 0b000>;
-defm : TLBI<"IPAS2LE1OS", 0b100, 0b1000, 0b0100, 0b100>;
-defm : TLBI<"VAE2OS", 0b100, 0b1000, 0b0001, 0b001>;
-defm : TLBI<"VALE2OS", 0b100, 0b1000, 0b0001, 0b101>;
-defm : TLBI<"VMALLS12E1OS", 0b100, 0b1000, 0b0001, 0b110, 0>;
-defm : TLBI<"VAE3OS", 0b110, 0b1000, 0b0001, 0b001>;
-defm : TLBI<"VALE3OS", 0b110, 0b1000, 0b0001, 0b101>;
-defm : TLBI<"ALLE2OS", 0b100, 0b1000, 0b0001, 0b000, 0>;
-defm : TLBI<"ALLE1OS", 0b100, 0b1000, 0b0001, 0b100, 0>;
-defm : TLBI<"ALLE3OS", 0b110, 0b1000, 0b0001, 0b000, 0>;
+defm : TLBI<"VMALLE1OS", 0b000, 0b1000, 0b0001, 0b000, 0>;
+defm : TLBI<"VAE1OS", 0b000, 0b1000, 0b0001, 0b001>;
+defm : TLBI<"ASIDE1OS", 0b000, 0b1000, 0b0001, 0b010>;
+defm : TLBI<"VAAE1OS", 0b000, 0b1000, 0b0001, 0b011>;
+defm : TLBI<"VALE1OS", 0b000, 0b1000, 0b0001, 0b101>;
+defm : TLBI<"VAALE1OS", 0b000, 0b1000, 0b0001, 0b111>;
+defm : TLBI<"IPAS2E1OS", 0b100, 0b1000, 0b0100, 0b000>;
+defm : TLBI<"IPAS2LE1OS", 0b100, 0b1000, 0b0100, 0b100>;
+defm : TLBI<"VAE2OS", 0b100, 0b1000, 0b0001, 0b001>;
+defm : TLBI<"VALE2OS", 0b100, 0b1000, 0b0001, 0b101>;
+defm : TLBI<"VMALLS12E1OS", 0b100, 0b1000, 0b0001, 0b110, 0>;
+defm : TLBI<"VAE3OS", 0b110, 0b1000, 0b0001, 0b001>;
+defm : TLBI<"VALE3OS", 0b110, 0b1000, 0b0001, 0b101>;
+defm : TLBI<"ALLE2OS", 0b100, 0b1000, 0b0001, 0b000, 0>;
+defm : TLBI<"ALLE1OS", 0b100, 0b1000, 0b0001, 0b100, 0>;
+defm : TLBI<"ALLE3OS", 0b110, 0b1000, 0b0001, 0b000, 0>;
// Armv8.4-A TLB Range Maintenance instructions:
// op1 CRn CRm op2
-defm : TLBI<"RVAE1", 0b000, 0b1000, 0b0110, 0b001>;
-defm : TLBI<"RVAAE1", 0b000, 0b1000, 0b0110, 0b011>;
-defm : TLBI<"RVALE1", 0b000, 0b1000, 0b0110, 0b101>;
-defm : TLBI<"RVAALE1", 0b000, 0b1000, 0b0110, 0b111>;
-defm : TLBI<"RVAE1IS", 0b000, 0b1000, 0b0010, 0b001>;
-defm : TLBI<"RVAAE1IS", 0b000, 0b1000, 0b0010, 0b011>;
-defm : TLBI<"RVALE1IS", 0b000, 0b1000, 0b0010, 0b101>;
-defm : TLBI<"RVAALE1IS", 0b000, 0b1000, 0b0010, 0b111>;
-defm : TLBI<"RVAE1OS", 0b000, 0b1000, 0b0101, 0b001>;
-defm : TLBI<"RVAAE1OS", 0b000, 0b1000, 0b0101, 0b011>;
-defm : TLBI<"RVALE1OS", 0b000, 0b1000, 0b0101, 0b101>;
-defm : TLBI<"RVAALE1OS", 0b000, 0b1000, 0b0101, 0b111>;
-defm : TLBI<"RIPAS2E1IS", 0b100, 0b1000, 0b0000, 0b010>;
-defm : TLBI<"RIPAS2LE1IS", 0b100, 0b1000, 0b0000, 0b110>;
-defm : TLBI<"RIPAS2E1", 0b100, 0b1000, 0b0100, 0b010>;
-defm : TLBI<"RIPAS2LE1", 0b100, 0b1000, 0b0100, 0b110>;
-defm : TLBI<"RIPAS2E1OS", 0b100, 0b1000, 0b0100, 0b011>;
-defm : TLBI<"RIPAS2LE1OS", 0b100, 0b1000, 0b0100, 0b111>;
-defm : TLBI<"RVAE2", 0b100, 0b1000, 0b0110, 0b001>;
-defm : TLBI<"RVALE2", 0b100, 0b1000, 0b0110, 0b101>;
-defm : TLBI<"RVAE2IS", 0b100, 0b1000, 0b0010, 0b001>;
-defm : TLBI<"RVALE2IS", 0b100, 0b1000, 0b0010, 0b101>;
-defm : TLBI<"RVAE2OS", 0b100, 0b1000, 0b0101, 0b001>;
-defm : TLBI<"RVALE2OS", 0b100, 0b1000, 0b0101, 0b101>;
-defm : TLBI<"RVAE3", 0b110, 0b1000, 0b0110, 0b001>;
-defm : TLBI<"RVALE3", 0b110, 0b1000, 0b0110, 0b101>;
-defm : TLBI<"RVAE3IS", 0b110, 0b1000, 0b0010, 0b001>;
-defm : TLBI<"RVALE3IS", 0b110, 0b1000, 0b0010, 0b101>;
-defm : TLBI<"RVAE3OS", 0b110, 0b1000, 0b0101, 0b001>;
-defm : TLBI<"RVALE3OS", 0b110, 0b1000, 0b0101, 0b101>;
+defm : TLBI<"RVAE1", 0b000, 0b1000, 0b0110, 0b001>;
+defm : TLBI<"RVAAE1", 0b000, 0b1000, 0b0110, 0b011>;
+defm : TLBI<"RVALE1", 0b000, 0b1000, 0b0110, 0b101>;
+defm : TLBI<"RVAALE1", 0b000, 0b1000, 0b0110, 0b111>;
+defm : TLBI<"RVAE1IS", 0b000, 0b1000, 0b0010, 0b001>;
+defm : TLBI<"RVAAE1IS", 0b000, 0b1000, 0b0010, 0b011>;
+defm : TLBI<"RVALE1IS", 0b000, 0b1000, 0b0010, 0b101>;
+defm : TLBI<"RVAALE1IS", 0b000, 0b1000, 0b0010, 0b111>;
+defm : TLBI<"RVAE1OS", 0b000, 0b1000, 0b0101, 0b001>;
+defm : TLBI<"RVAAE1OS", 0b000, 0b1000, 0b0101, 0b011>;
+defm : TLBI<"RVALE1OS", 0b000, 0b1000, 0b0101, 0b101>;
+defm : TLBI<"RVAALE1OS", 0b000, 0b1000, 0b0101, 0b111>;
+defm : TLBI<"RIPAS2E1IS", 0b100, 0b1000, 0b0000, 0b010>;
+defm : TLBI<"RIPAS2LE1IS", 0b100, 0b1000, 0b0000, 0b110>;
+defm : TLBI<"RIPAS2E1", 0b100, 0b1000, 0b0100, 0b010>;
+defm : TLBI<"RIPAS2LE1", 0b100, 0b1000, 0b0100, 0b110>;
+defm : TLBI<"RIPAS2E1OS", 0b100, 0b1000, 0b0100, 0b011>;
+defm : TLBI<"RIPAS2LE1OS", 0b100, 0b1000, 0b0100, 0b111>;
+defm : TLBI<"RVAE2", 0b100, 0b1000, 0b0110, 0b001>;
+defm : TLBI<"RVALE2", 0b100, 0b1000, 0b0110, 0b101>;
+defm : TLBI<"RVAE2IS", 0b100, 0b1000, 0b0010, 0b001>;
+defm : TLBI<"RVALE2IS", 0b100, 0b1000, 0b0010, 0b101>;
+defm : TLBI<"RVAE2OS", 0b100, 0b1000, 0b0101, 0b001>;
+defm : TLBI<"RVALE2OS", 0b100, 0b1000, 0b0101, 0b101>;
+defm : TLBI<"RVAE3", 0b110, 0b1000, 0b0110, 0b001>;
+defm : TLBI<"RVALE3", 0b110, 0b1000, 0b0110, 0b101>;
+defm : TLBI<"RVAE3IS", 0b110, 0b1000, 0b0010, 0b001>;
+defm : TLBI<"RVALE3IS", 0b110, 0b1000, 0b0010, 0b101>;
+defm : TLBI<"RVAE3OS", 0b110, 0b1000, 0b0101, 0b001>;
+defm : TLBI<"RVALE3OS", 0b110, 0b1000, 0b0101, 0b101>;
} //FeatureTLB_RMI
// Armv8.5-A Prediction Restriction by Context instruction options:
@@ -643,7 +643,7 @@ def : ROSysReg<"ID_AA64AFR0_EL1", 0b11, 0b000, 0b0000, 0b0101, 0b100>;
def : ROSysReg<"ID_AA64AFR1_EL1", 0b11, 0b000, 0b0000, 0b0101, 0b101>;
def : ROSysReg<"ID_AA64ISAR0_EL1", 0b11, 0b000, 0b0000, 0b0110, 0b000>;
def : ROSysReg<"ID_AA64ISAR1_EL1", 0b11, 0b000, 0b0000, 0b0110, 0b001>;
-def : ROSysReg<"ID_AA64ISAR2_EL1", 0b11, 0b000, 0b0000, 0b0110, 0b010>;
+def : ROSysReg<"ID_AA64ISAR2_EL1", 0b11, 0b000, 0b0000, 0b0110, 0b010>;
def : ROSysReg<"ID_AA64MMFR0_EL1", 0b11, 0b000, 0b0000, 0b0111, 0b000>;
def : ROSysReg<"ID_AA64MMFR1_EL1", 0b11, 0b000, 0b0000, 0b0111, 0b001>;
def : ROSysReg<"ID_AA64MMFR2_EL1", 0b11, 0b000, 0b0000, 0b0111, 0b010>;
@@ -859,9 +859,9 @@ def : RWSysReg<"ACTLR_EL1", 0b11, 0b000, 0b0001, 0b0000, 0b001>;
def : RWSysReg<"ACTLR_EL2", 0b11, 0b100, 0b0001, 0b0000, 0b001>;
def : RWSysReg<"ACTLR_EL3", 0b11, 0b110, 0b0001, 0b0000, 0b001>;
def : RWSysReg<"HCR_EL2", 0b11, 0b100, 0b0001, 0b0001, 0b000>;
-def : RWSysReg<"HCRX_EL2", 0b11, 0b100, 0b0001, 0b0010, 0b010> {
- let Requires = [{ {AArch64::FeatureHCX} }];
-}
+def : RWSysReg<"HCRX_EL2", 0b11, 0b100, 0b0001, 0b0010, 0b010> {
+ let Requires = [{ {AArch64::FeatureHCX} }];
+}
def : RWSysReg<"SCR_EL3", 0b11, 0b110, 0b0001, 0b0001, 0b000>;
def : RWSysReg<"MDCR_EL2", 0b11, 0b100, 0b0001, 0b0001, 0b001>;
def : RWSysReg<"SDER32_EL3", 0b11, 0b110, 0b0001, 0b0001, 0b001>;
@@ -1293,10 +1293,10 @@ def : RWSysReg<"CNTV_CTL_EL02", 0b11, 0b101, 0b1110, 0b0011, 0b001>;
def : RWSysReg<"CNTV_CVAL_EL02", 0b11, 0b101, 0b1110, 0b0011, 0b010>;
def : RWSysReg<"SPSR_EL12", 0b11, 0b101, 0b0100, 0b0000, 0b000>;
def : RWSysReg<"ELR_EL12", 0b11, 0b101, 0b0100, 0b0000, 0b001>;
-let Requires = [{ {AArch64::FeatureCONTEXTIDREL2} }] in {
- def : RWSysReg<"CONTEXTIDR_EL2", 0b11, 0b100, 0b1101, 0b0000, 0b001>;
+let Requires = [{ {AArch64::FeatureCONTEXTIDREL2} }] in {
+ def : RWSysReg<"CONTEXTIDR_EL2", 0b11, 0b100, 0b1101, 0b0000, 0b001>;
+}
}
-}
// v8.2a registers
// Op0 Op1 CRn CRm Op2
let Requires = [{ {AArch64::FeaturePsUAO} }] in
@@ -1336,7 +1336,7 @@ def : RWSysReg<"VSESR_EL2", 0b11, 0b100, 0b0101, 0b0010, 0b011>;
// v8.3a "Pointer authentication extension" registers
// Op0 Op1 CRn CRm Op2
-let Requires = [{ {AArch64::FeaturePAuth} }] in {
+let Requires = [{ {AArch64::FeaturePAuth} }] in {
def : RWSysReg<"APIAKeyLo_EL1", 0b11, 0b000, 0b0010, 0b0001, 0b000>;
def : RWSysReg<"APIAKeyHi_EL1", 0b11, 0b000, 0b0010, 0b0001, 0b001>;
def : RWSysReg<"APIBKeyLo_EL1", 0b11, 0b000, 0b0010, 0b0001, 0b010>;
@@ -1570,33 +1570,33 @@ def : RWSysReg<"CNTPCTSS_EL0", 0b11, 0b011, 0b1110, 0b0000, 0b101>;
def : RWSysReg<"CNTVCTSS_EL0", 0b11, 0b011, 0b1110, 0b0000, 0b110>;
}
-// v8.7a LD64B/ST64B Accelerator Extension system register
-let Requires = [{ {AArch64::FeatureLS64} }] in
-def : RWSysReg<"ACCDATA_EL1", 0b11, 0b000, 0b1101, 0b0000, 0b101>;
-
-// Branch Record Buffer system registers
-let Requires = [{ {AArch64::FeatureBRBE} }] in {
-def : RWSysReg<"BRBCR_EL1", 0b10, 0b001, 0b1001, 0b0000, 0b000>;
-def : RWSysReg<"BRBCR_EL12", 0b10, 0b101, 0b1001, 0b0000, 0b000>;
-def : RWSysReg<"BRBCR_EL2", 0b10, 0b100, 0b1001, 0b0000, 0b000>;
-def : RWSysReg<"BRBFCR_EL1", 0b10, 0b001, 0b1001, 0b0000, 0b001>;
-def : ROSysReg<"BRBIDR0_EL1", 0b10, 0b001, 0b1001, 0b0010, 0b000>;
-def : RWSysReg<"BRBINFINJ_EL1", 0b10, 0b001, 0b1001, 0b0001, 0b000>;
-def : RWSysReg<"BRBSRCINJ_EL1", 0b10, 0b001, 0b1001, 0b0001, 0b001>;
-def : RWSysReg<"BRBTGTINJ_EL1", 0b10, 0b001, 0b1001, 0b0001, 0b010>;
-def : RWSysReg<"BRBTS_EL1", 0b10, 0b001, 0b1001, 0b0000, 0b010>;
-foreach n = 0-31 in {
- defvar nb = !cast<bits<5>>(n);
- def : ROSysReg<"BRBINF"#n#"_EL1", 0b10, 0b001, 0b1000, nb{3-0}, {nb{4},0b00}>;
- def : ROSysReg<"BRBSRC"#n#"_EL1", 0b10, 0b001, 0b1000, nb{3-0}, {nb{4},0b01}>;
- def : ROSysReg<"BRBTGT"#n#"_EL1", 0b10, 0b001, 0b1000, nb{3-0}, {nb{4},0b10}>;
-}
-}
-
-// Statistical Profiling Extension system register
-let Requires = [{ {AArch64::FeatureSPE_EEF} }] in
-def : RWSysReg<"PMSNEVFR_EL1", 0b11, 0b000, 0b1001, 0b1001, 0b001>;
-
+// v8.7a LD64B/ST64B Accelerator Extension system register
+let Requires = [{ {AArch64::FeatureLS64} }] in
+def : RWSysReg<"ACCDATA_EL1", 0b11, 0b000, 0b1101, 0b0000, 0b101>;
+
+// Branch Record Buffer system registers
+let Requires = [{ {AArch64::FeatureBRBE} }] in {
+def : RWSysReg<"BRBCR_EL1", 0b10, 0b001, 0b1001, 0b0000, 0b000>;
+def : RWSysReg<"BRBCR_EL12", 0b10, 0b101, 0b1001, 0b0000, 0b000>;
+def : RWSysReg<"BRBCR_EL2", 0b10, 0b100, 0b1001, 0b0000, 0b000>;
+def : RWSysReg<"BRBFCR_EL1", 0b10, 0b001, 0b1001, 0b0000, 0b001>;
+def : ROSysReg<"BRBIDR0_EL1", 0b10, 0b001, 0b1001, 0b0010, 0b000>;
+def : RWSysReg<"BRBINFINJ_EL1", 0b10, 0b001, 0b1001, 0b0001, 0b000>;
+def : RWSysReg<"BRBSRCINJ_EL1", 0b10, 0b001, 0b1001, 0b0001, 0b001>;
+def : RWSysReg<"BRBTGTINJ_EL1", 0b10, 0b001, 0b1001, 0b0001, 0b010>;
+def : RWSysReg<"BRBTS_EL1", 0b10, 0b001, 0b1001, 0b0000, 0b010>;
+foreach n = 0-31 in {
+ defvar nb = !cast<bits<5>>(n);
+ def : ROSysReg<"BRBINF"#n#"_EL1", 0b10, 0b001, 0b1000, nb{3-0}, {nb{4},0b00}>;
+ def : ROSysReg<"BRBSRC"#n#"_EL1", 0b10, 0b001, 0b1000, nb{3-0}, {nb{4},0b01}>;
+ def : ROSysReg<"BRBTGT"#n#"_EL1", 0b10, 0b001, 0b1000, nb{3-0}, {nb{4},0b10}>;
+}
+}
+
+// Statistical Profiling Extension system register
+let Requires = [{ {AArch64::FeatureSPE_EEF} }] in
+def : RWSysReg<"PMSNEVFR_EL1", 0b11, 0b000, 0b1001, 0b1001, 0b001>;
+
// Cyclone specific system registers
// Op0 Op1 CRn CRm Op2
let Requires = [{ {AArch64::ProcAppleA7} }] in
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetMachine.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetMachine.cpp
index 5635b07fd6..bec1758a93 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -148,10 +148,10 @@ static cl::opt<int> EnableGlobalISelAtO(
cl::desc("Enable GlobalISel at or below an opt level (-1 to disable)"),
cl::init(0));
-static cl::opt<bool>
- EnableSVEIntrinsicOpts("aarch64-enable-sve-intrinsic-opts", cl::Hidden,
- cl::desc("Enable SVE intrinsic opts"),
- cl::init(true));
+static cl::opt<bool>
+ EnableSVEIntrinsicOpts("aarch64-enable-sve-intrinsic-opts", cl::Hidden,
+ cl::desc("Enable SVE intrinsic opts"),
+ cl::init(true));
static cl::opt<bool> EnableFalkorHWPFFix("aarch64-enable-falkor-hwpf-fix",
cl::init(true), cl::Hidden);
@@ -184,8 +184,8 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64Target() {
initializeAArch64SIMDInstrOptPass(*PR);
initializeAArch64PreLegalizerCombinerPass(*PR);
initializeAArch64PostLegalizerCombinerPass(*PR);
- initializeAArch64PostLegalizerLoweringPass(*PR);
- initializeAArch64PostSelectOptimizePass(*PR);
+ initializeAArch64PostLegalizerLoweringPass(*PR);
+ initializeAArch64PostSelectOptimizePass(*PR);
initializeAArch64PromoteConstantPass(*PR);
initializeAArch64RedundantCopyEliminationPass(*PR);
initializeAArch64StorePairSuppressPass(*PR);
@@ -222,18 +222,18 @@ static std::string computeDataLayout(const Triple &TT,
}
if (TT.isOSBinFormatCOFF())
return "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128";
- std::string Endian = LittleEndian ? "e" : "E";
- std::string Ptr32 = TT.getEnvironment() == Triple::GNUILP32 ? "-p:32:32" : "";
- return Endian + "-m:e" + Ptr32 +
- "-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128";
+ std::string Endian = LittleEndian ? "e" : "E";
+ std::string Ptr32 = TT.getEnvironment() == Triple::GNUILP32 ? "-p:32:32" : "";
+ return Endian + "-m:e" + Ptr32 +
+ "-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128";
+}
+
+static StringRef computeDefaultCPU(const Triple &TT, StringRef CPU) {
+ if (CPU.empty() && TT.isArm64e())
+ return "apple-a12";
+ return CPU;
}
-static StringRef computeDefaultCPU(const Triple &TT, StringRef CPU) {
- if (CPU.empty() && TT.isArm64e())
- return "apple-a12";
- return CPU;
-}
-
static Reloc::Model getEffectiveRelocModel(const Triple &TT,
Optional<Reloc::Model> RM) {
// AArch64 Darwin and Windows are always PIC.
@@ -281,8 +281,8 @@ AArch64TargetMachine::AArch64TargetMachine(const Target &T, const Triple &TT,
bool LittleEndian)
: LLVMTargetMachine(T,
computeDataLayout(TT, Options.MCOptions, LittleEndian),
- TT, computeDefaultCPU(TT, CPU), FS, Options,
- getEffectiveRelocModel(TT, RM),
+ TT, computeDefaultCPU(TT, CPU), FS, Options,
+ getEffectiveRelocModel(TT, RM),
getEffectiveAArch64CodeModel(TT, CM, JIT), OL),
TLOF(createTLOF(getTargetTriple())), isLittle(LittleEndian) {
initAsmInfo();
@@ -317,7 +317,7 @@ AArch64TargetMachine::AArch64TargetMachine(const Target &T, const Triple &TT,
// MachO/CodeModel::Large, which GlobalISel does not support.
if (getOptLevel() <= EnableGlobalISelAtO &&
TT.getArch() != Triple::aarch64_32 &&
- TT.getEnvironment() != Triple::GNUILP32 &&
+ TT.getEnvironment() != Triple::GNUILP32 &&
!(getCodeModel() == CodeModel::Large && TT.isOSBinFormatMachO())) {
setGlobalISel(true);
setGlobalISelAbort(GlobalISelAbortMode::Disable);
@@ -340,10 +340,10 @@ AArch64TargetMachine::getSubtargetImpl(const Function &F) const {
Attribute CPUAttr = F.getFnAttribute("target-cpu");
Attribute FSAttr = F.getFnAttribute("target-features");
- std::string CPU =
- CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
- std::string FS =
- FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
+ std::string CPU =
+ CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
+ std::string FS =
+ FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
auto &I = SubtargetMap[CPU + FS];
if (!I) {
@@ -460,12 +460,12 @@ void AArch64PassConfig::addIRPasses() {
// determine whether it succeeded. We can exploit existing control-flow in
// ldrex/strex loops to simplify this, but it needs tidying up.
if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy)
- addPass(createCFGSimplificationPass(SimplifyCFGOptions()
- .forwardSwitchCondToPhi(true)
- .convertSwitchToLookupTable(true)
- .needCanonicalLoops(false)
- .hoistCommonInsts(true)
- .sinkCommonInsts(true)));
+ addPass(createCFGSimplificationPass(SimplifyCFGOptions()
+ .forwardSwitchCondToPhi(true)
+ .convertSwitchToLookupTable(true)
+ .needCanonicalLoops(false)
+ .hoistCommonInsts(true)
+ .sinkCommonInsts(true)));
// Run LoopDataPrefetch
//
@@ -553,13 +553,13 @@ bool AArch64PassConfig::addInstSelector() {
}
bool AArch64PassConfig::addIRTranslator() {
- addPass(new IRTranslator(getOptLevel()));
+ addPass(new IRTranslator(getOptLevel()));
return false;
}
void AArch64PassConfig::addPreLegalizeMachineIR() {
bool IsOptNone = getOptLevel() == CodeGenOpt::None;
- addPass(createAArch64PreLegalizerCombiner(IsOptNone));
+ addPass(createAArch64PreLegalizerCombiner(IsOptNone));
}
bool AArch64PassConfig::addLegalizeMachineIR() {
@@ -570,8 +570,8 @@ bool AArch64PassConfig::addLegalizeMachineIR() {
void AArch64PassConfig::addPreRegBankSelect() {
bool IsOptNone = getOptLevel() == CodeGenOpt::None;
if (!IsOptNone)
- addPass(createAArch64PostLegalizerCombiner(IsOptNone));
- addPass(createAArch64PostLegalizerLowering());
+ addPass(createAArch64PostLegalizerCombiner(IsOptNone));
+ addPass(createAArch64PostLegalizerLowering());
}
bool AArch64PassConfig::addRegBankSelect() {
@@ -585,8 +585,8 @@ void AArch64PassConfig::addPreGlobalInstructionSelect() {
bool AArch64PassConfig::addGlobalInstructionSelect() {
addPass(new InstructionSelect());
- if (getOptLevel() != CodeGenOpt::None)
- addPass(createAArch64PostSelectOptimize());
+ if (getOptLevel() != CodeGenOpt::None)
+ addPass(createAArch64PostSelectOptimize());
return false;
}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetMachine.h b/contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetMachine.h
index 2420658743..25e6261343 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetMachine.h
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetMachine.h
@@ -57,12 +57,12 @@ public:
SMDiagnostic &Error,
SMRange &SourceRange) const override;
- /// Returns true if a cast between SrcAS and DestAS is a noop.
- bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override {
- // Addrspacecasts are always noops.
- return true;
- }
-
+ /// Returns true if a cast between SrcAS and DestAS is a noop.
+ bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override {
+ // Addrspacecasts are always noops.
+ return true;
+ }
+
private:
bool isLittle;
};
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index d9f700a966..7fda6b8fb6 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "AArch64TargetTransformInfo.h"
+#include "AArch64TargetTransformInfo.h"
#include "AArch64ExpandImm.h"
#include "MCTargetDesc/AArch64AddressingModes.h"
#include "llvm/Analysis/LoopInfo.h"
@@ -16,11 +16,11 @@
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/IntrinsicsAArch64.h"
-#include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/PatternMatch.h"
#include "llvm/Support/Debug.h"
#include <algorithm>
using namespace llvm;
-using namespace llvm::PatternMatch;
+using namespace llvm::PatternMatch;
#define DEBUG_TYPE "aarch64tti"
@@ -86,8 +86,8 @@ int AArch64TTIImpl::getIntImmCost(const APInt &Imm, Type *Ty,
int AArch64TTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx,
const APInt &Imm, Type *Ty,
- TTI::TargetCostKind CostKind,
- Instruction *Inst) {
+ TTI::TargetCostKind CostKind,
+ Instruction *Inst) {
assert(Ty->isIntegerTy());
unsigned BitSize = Ty->getPrimitiveSizeInBits();
@@ -195,10 +195,10 @@ int AArch64TTIImpl::getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
if ((Idx < 4) || (Imm.getBitWidth() <= 64 && isInt<64>(Imm.getSExtValue())))
return TTI::TCC_Free;
break;
- case Intrinsic::experimental_gc_statepoint:
- if ((Idx < 5) || (Imm.getBitWidth() <= 64 && isInt<64>(Imm.getSExtValue())))
- return TTI::TCC_Free;
- break;
+ case Intrinsic::experimental_gc_statepoint:
+ if ((Idx < 5) || (Imm.getBitWidth() <= 64 && isInt<64>(Imm.getSExtValue())))
+ return TTI::TCC_Free;
+ break;
}
return AArch64TTIImpl::getIntImmCost(Imm, Ty, CostKind);
}
@@ -212,43 +212,43 @@ AArch64TTIImpl::getPopcntSupport(unsigned TyWidth) {
return TTI::PSK_Software;
}
-unsigned
-AArch64TTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
- TTI::TargetCostKind CostKind) {
- auto *RetTy = ICA.getReturnType();
- switch (ICA.getID()) {
- case Intrinsic::umin:
- case Intrinsic::umax: {
- auto LT = TLI->getTypeLegalizationCost(DL, RetTy);
- // umin(x,y) -> sub(x,usubsat(x,y))
- // umax(x,y) -> add(x,usubsat(y,x))
- if (LT.second == MVT::v2i64)
- return LT.first * 2;
- LLVM_FALLTHROUGH;
- }
- case Intrinsic::smin:
- case Intrinsic::smax: {
- static const auto ValidMinMaxTys = {MVT::v8i8, MVT::v16i8, MVT::v4i16,
- MVT::v8i16, MVT::v2i32, MVT::v4i32};
- auto LT = TLI->getTypeLegalizationCost(DL, RetTy);
- if (any_of(ValidMinMaxTys, [&LT](MVT M) { return M == LT.second; }))
- return LT.first;
- break;
- }
- default:
- break;
- }
- return BaseT::getIntrinsicInstrCost(ICA, CostKind);
-}
-
+unsigned
+AArch64TTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
+ TTI::TargetCostKind CostKind) {
+ auto *RetTy = ICA.getReturnType();
+ switch (ICA.getID()) {
+ case Intrinsic::umin:
+ case Intrinsic::umax: {
+ auto LT = TLI->getTypeLegalizationCost(DL, RetTy);
+ // umin(x,y) -> sub(x,usubsat(x,y))
+ // umax(x,y) -> add(x,usubsat(y,x))
+ if (LT.second == MVT::v2i64)
+ return LT.first * 2;
+ LLVM_FALLTHROUGH;
+ }
+ case Intrinsic::smin:
+ case Intrinsic::smax: {
+ static const auto ValidMinMaxTys = {MVT::v8i8, MVT::v16i8, MVT::v4i16,
+ MVT::v8i16, MVT::v2i32, MVT::v4i32};
+ auto LT = TLI->getTypeLegalizationCost(DL, RetTy);
+ if (any_of(ValidMinMaxTys, [&LT](MVT M) { return M == LT.second; }))
+ return LT.first;
+ break;
+ }
+ default:
+ break;
+ }
+ return BaseT::getIntrinsicInstrCost(ICA, CostKind);
+}
+
bool AArch64TTIImpl::isWideningInstruction(Type *DstTy, unsigned Opcode,
ArrayRef<const Value *> Args) {
// A helper that returns a vector type from the given type. The number of
// elements in type Ty determine the vector width.
auto toVectorTy = [&](Type *ArgTy) {
- return VectorType::get(ArgTy->getScalarType(),
- cast<VectorType>(DstTy)->getElementCount());
+ return VectorType::get(ArgTy->getScalarType(),
+ cast<VectorType>(DstTy)->getElementCount());
};
// Exit early if DstTy is not a vector type whose elements are at least
@@ -297,8 +297,8 @@ bool AArch64TTIImpl::isWideningInstruction(Type *DstTy, unsigned Opcode,
return false;
// Get the total number of vector elements in the legalized types.
- unsigned NumDstEls = DstTyL.first * DstTyL.second.getVectorMinNumElements();
- unsigned NumSrcEls = SrcTyL.first * SrcTyL.second.getVectorMinNumElements();
+ unsigned NumDstEls = DstTyL.first * DstTyL.second.getVectorMinNumElements();
+ unsigned NumSrcEls = SrcTyL.first * SrcTyL.second.getVectorMinNumElements();
// Return true if the legalized types have the same number of vector elements
// and the destination element type size is twice that of the source type.
@@ -306,7 +306,7 @@ bool AArch64TTIImpl::isWideningInstruction(Type *DstTy, unsigned Opcode,
}
int AArch64TTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
- TTI::CastContextHint CCH,
+ TTI::CastContextHint CCH,
TTI::TargetCostKind CostKind,
const Instruction *I) {
int ISD = TLI->InstructionOpcodeToISD(Opcode);
@@ -343,8 +343,8 @@ int AArch64TTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
EVT DstTy = TLI->getValueType(DL, Dst);
if (!SrcTy.isSimple() || !DstTy.isSimple())
- return AdjustCost(
- BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I));
+ return AdjustCost(
+ BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I));
static const TypeConversionCostTblEntry
ConversionTbl[] = {
@@ -448,8 +448,8 @@ int AArch64TTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
SrcTy.getSimpleVT()))
return AdjustCost(Entry->Cost);
- return AdjustCost(
- BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I));
+ return AdjustCost(
+ BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I));
}
int AArch64TTIImpl::getExtractWithExtendCost(unsigned Opcode, Type *Dst,
@@ -481,14 +481,14 @@ int AArch64TTIImpl::getExtractWithExtendCost(unsigned Opcode, Type *Dst,
// we may get the extension for free. If not, get the default cost for the
// extend.
if (!VecLT.second.isVector() || !TLI->isTypeLegal(DstVT))
- return Cost + getCastInstrCost(Opcode, Dst, Src, TTI::CastContextHint::None,
- CostKind);
+ return Cost + getCastInstrCost(Opcode, Dst, Src, TTI::CastContextHint::None,
+ CostKind);
// The destination type should be larger than the element type. If not, get
// the default cost for the extend.
- if (DstVT.getFixedSizeInBits() < SrcVT.getFixedSizeInBits())
- return Cost + getCastInstrCost(Opcode, Dst, Src, TTI::CastContextHint::None,
- CostKind);
+ if (DstVT.getFixedSizeInBits() < SrcVT.getFixedSizeInBits())
+ return Cost + getCastInstrCost(Opcode, Dst, Src, TTI::CastContextHint::None,
+ CostKind);
switch (Opcode) {
default:
@@ -507,8 +507,8 @@ int AArch64TTIImpl::getExtractWithExtendCost(unsigned Opcode, Type *Dst,
}
// If we are unable to perform the extend for free, get the default cost.
- return Cost + getCastInstrCost(Opcode, Dst, Src, TTI::CastContextHint::None,
- CostKind);
+ return Cost + getCastInstrCost(Opcode, Dst, Src, TTI::CastContextHint::None,
+ CostKind);
}
unsigned AArch64TTIImpl::getCFInstrCost(unsigned Opcode,
@@ -644,19 +644,19 @@ int AArch64TTIImpl::getArithmeticInstrCost(
}
return Cost;
- case ISD::MUL:
- if (LT.second != MVT::v2i64)
- return (Cost + 1) * LT.first;
- // Since we do not have a MUL.2d instruction, a mul <2 x i64> is expensive
- // as elements are extracted from the vectors and the muls scalarized.
- // As getScalarizationOverhead is a bit too pessimistic, we estimate the
- // cost for a i64 vector directly here, which is:
- // - four i64 extracts,
- // - two i64 inserts, and
- // - two muls.
- // So, for a v2i64 with LT.First = 1 the cost is 8, and for a v4i64 with
- // LT.first = 2 the cost is 16.
- return LT.first * 8;
+ case ISD::MUL:
+ if (LT.second != MVT::v2i64)
+ return (Cost + 1) * LT.first;
+ // Since we do not have a MUL.2d instruction, a mul <2 x i64> is expensive
+ // as elements are extracted from the vectors and the muls scalarized.
+ // As getScalarizationOverhead is a bit too pessimistic, we estimate the
+ // cost for a i64 vector directly here, which is:
+ // - four i64 extracts,
+ // - two i64 inserts, and
+ // - two muls.
+ // So, for a v2i64 with LT.First = 1 the cost is 8, and for a v4i64 with
+ // LT.first = 2 the cost is 16.
+ return LT.first * 8;
case ISD::ADD:
case ISD::XOR:
case ISD::OR:
@@ -696,40 +696,40 @@ int AArch64TTIImpl::getAddressComputationCost(Type *Ty, ScalarEvolution *SE,
}
int AArch64TTIImpl::getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
- Type *CondTy, CmpInst::Predicate VecPred,
+ Type *CondTy, CmpInst::Predicate VecPred,
TTI::TargetCostKind CostKind,
const Instruction *I) {
// TODO: Handle other cost kinds.
if (CostKind != TTI::TCK_RecipThroughput)
- return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
- I);
+ return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
+ I);
int ISD = TLI->InstructionOpcodeToISD(Opcode);
// We don't lower some vector selects well that are wider than the register
// width.
- if (isa<FixedVectorType>(ValTy) && ISD == ISD::SELECT) {
+ if (isa<FixedVectorType>(ValTy) && ISD == ISD::SELECT) {
// We would need this many instructions to hide the scalarization happening.
const int AmortizationCost = 20;
-
- // If VecPred is not set, check if we can get a predicate from the context
- // instruction, if its type matches the requested ValTy.
- if (VecPred == CmpInst::BAD_ICMP_PREDICATE && I && I->getType() == ValTy) {
- CmpInst::Predicate CurrentPred;
- if (match(I, m_Select(m_Cmp(CurrentPred, m_Value(), m_Value()), m_Value(),
- m_Value())))
- VecPred = CurrentPred;
- }
- // Check if we have a compare/select chain that can be lowered using CMxx &
- // BFI pair.
- if (CmpInst::isIntPredicate(VecPred)) {
- static const auto ValidMinMaxTys = {MVT::v8i8, MVT::v16i8, MVT::v4i16,
- MVT::v8i16, MVT::v2i32, MVT::v4i32,
- MVT::v2i64};
- auto LT = TLI->getTypeLegalizationCost(DL, ValTy);
- if (any_of(ValidMinMaxTys, [&LT](MVT M) { return M == LT.second; }))
- return LT.first;
- }
-
+
+ // If VecPred is not set, check if we can get a predicate from the context
+ // instruction, if its type matches the requested ValTy.
+ if (VecPred == CmpInst::BAD_ICMP_PREDICATE && I && I->getType() == ValTy) {
+ CmpInst::Predicate CurrentPred;
+ if (match(I, m_Select(m_Cmp(CurrentPred, m_Value(), m_Value()), m_Value(),
+ m_Value())))
+ VecPred = CurrentPred;
+ }
+ // Check if we have a compare/select chain that can be lowered using CMxx &
+ // BFI pair.
+ if (CmpInst::isIntPredicate(VecPred)) {
+ static const auto ValidMinMaxTys = {MVT::v8i8, MVT::v16i8, MVT::v4i16,
+ MVT::v8i16, MVT::v2i32, MVT::v4i32,
+ MVT::v2i64};
+ auto LT = TLI->getTypeLegalizationCost(DL, ValTy);
+ if (any_of(ValidMinMaxTys, [&LT](MVT M) { return M == LT.second; }))
+ return LT.first;
+ }
+
static const TypeConversionCostTblEntry
VectorSelectTbl[] = {
{ ISD::SELECT, MVT::v16i1, MVT::v16i16, 16 },
@@ -749,9 +749,9 @@ int AArch64TTIImpl::getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
return Entry->Cost;
}
}
- // The base case handles scalable vectors fine for now, since it treats the
- // cost as 1 * legalization cost.
- return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind, I);
+ // The base case handles scalable vectors fine for now, since it treats the
+ // cost as 1 * legalization cost.
+ return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind, I);
}
AArch64TTIImpl::TTI::MemCmpExpansionOptions
@@ -772,30 +772,30 @@ AArch64TTIImpl::enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const {
return Options;
}
-unsigned AArch64TTIImpl::getGatherScatterOpCost(
- unsigned Opcode, Type *DataTy, const Value *Ptr, bool VariableMask,
- Align Alignment, TTI::TargetCostKind CostKind, const Instruction *I) {
-
- if (!isa<ScalableVectorType>(DataTy))
- return BaseT::getGatherScatterOpCost(Opcode, DataTy, Ptr, VariableMask,
- Alignment, CostKind, I);
- auto *VT = cast<VectorType>(DataTy);
- auto LT = TLI->getTypeLegalizationCost(DL, DataTy);
- ElementCount LegalVF = LT.second.getVectorElementCount();
- Optional<unsigned> MaxNumVScale = getMaxVScale();
- assert(MaxNumVScale && "Expected valid max vscale value");
-
- unsigned MemOpCost =
- getMemoryOpCost(Opcode, VT->getElementType(), Alignment, 0, CostKind, I);
- unsigned MaxNumElementsPerGather =
- MaxNumVScale.getValue() * LegalVF.getKnownMinValue();
- return LT.first * MaxNumElementsPerGather * MemOpCost;
-}
-
-bool AArch64TTIImpl::useNeonVector(const Type *Ty) const {
- return isa<FixedVectorType>(Ty) && !ST->useSVEForFixedLengthVectors();
-}
-
+unsigned AArch64TTIImpl::getGatherScatterOpCost(
+ unsigned Opcode, Type *DataTy, const Value *Ptr, bool VariableMask,
+ Align Alignment, TTI::TargetCostKind CostKind, const Instruction *I) {
+
+ if (!isa<ScalableVectorType>(DataTy))
+ return BaseT::getGatherScatterOpCost(Opcode, DataTy, Ptr, VariableMask,
+ Alignment, CostKind, I);
+ auto *VT = cast<VectorType>(DataTy);
+ auto LT = TLI->getTypeLegalizationCost(DL, DataTy);
+ ElementCount LegalVF = LT.second.getVectorElementCount();
+ Optional<unsigned> MaxNumVScale = getMaxVScale();
+ assert(MaxNumVScale && "Expected valid max vscale value");
+
+ unsigned MemOpCost =
+ getMemoryOpCost(Opcode, VT->getElementType(), Alignment, 0, CostKind, I);
+ unsigned MaxNumElementsPerGather =
+ MaxNumVScale.getValue() * LegalVF.getKnownMinValue();
+ return LT.first * MaxNumElementsPerGather * MemOpCost;
+}
+
+bool AArch64TTIImpl::useNeonVector(const Type *Ty) const {
+ return isa<FixedVectorType>(Ty) && !ST->useSVEForFixedLengthVectors();
+}
+
int AArch64TTIImpl::getMemoryOpCost(unsigned Opcode, Type *Ty,
MaybeAlign Alignment, unsigned AddressSpace,
TTI::TargetCostKind CostKind,
@@ -823,7 +823,7 @@ int AArch64TTIImpl::getMemoryOpCost(unsigned Opcode, Type *Ty,
return LT.first * 2 * AmortizationCost;
}
- if (useNeonVector(Ty) &&
+ if (useNeonVector(Ty) &&
cast<VectorType>(Ty)->getElementType()->isIntegerTy(8)) {
unsigned ProfitableNumElements;
if (Opcode == Instruction::Store)
@@ -1098,70 +1098,70 @@ bool AArch64TTIImpl::useReductionIntrinsic(unsigned Opcode, Type *Ty,
return false;
}
-int AArch64TTIImpl::getMinMaxReductionCost(VectorType *Ty, VectorType *CondTy,
- bool IsPairwise, bool IsUnsigned,
- TTI::TargetCostKind CostKind) {
- if (!isa<ScalableVectorType>(Ty))
- return BaseT::getMinMaxReductionCost(Ty, CondTy, IsPairwise, IsUnsigned,
- CostKind);
- assert((isa<ScalableVectorType>(Ty) && isa<ScalableVectorType>(CondTy)) &&
- "Both vector needs to be scalable");
-
- std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, Ty);
- int LegalizationCost = 0;
- if (LT.first > 1) {
- Type *LegalVTy = EVT(LT.second).getTypeForEVT(Ty->getContext());
- unsigned CmpOpcode =
- Ty->isFPOrFPVectorTy() ? Instruction::FCmp : Instruction::ICmp;
- LegalizationCost =
- getCmpSelInstrCost(CmpOpcode, LegalVTy, LegalVTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind) +
- getCmpSelInstrCost(Instruction::Select, LegalVTy, LegalVTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
- LegalizationCost *= LT.first - 1;
- }
-
- return LegalizationCost + /*Cost of horizontal reduction*/ 2;
-}
-
-int AArch64TTIImpl::getArithmeticReductionCostSVE(
- unsigned Opcode, VectorType *ValTy, bool IsPairwise,
- TTI::TargetCostKind CostKind) {
- assert(!IsPairwise && "Cannot be pair wise to continue");
-
- std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, ValTy);
- int LegalizationCost = 0;
- if (LT.first > 1) {
- Type *LegalVTy = EVT(LT.second).getTypeForEVT(ValTy->getContext());
- LegalizationCost = getArithmeticInstrCost(Opcode, LegalVTy, CostKind);
- LegalizationCost *= LT.first - 1;
- }
-
- int ISD = TLI->InstructionOpcodeToISD(Opcode);
- assert(ISD && "Invalid opcode");
- // Add the final reduction cost for the legal horizontal reduction
- switch (ISD) {
- case ISD::ADD:
- case ISD::AND:
- case ISD::OR:
- case ISD::XOR:
- case ISD::FADD:
- return LegalizationCost + 2;
- default:
- // TODO: Replace for invalid when InstructionCost is used
- // cases not supported by SVE
- return 16;
- }
-}
-
+int AArch64TTIImpl::getMinMaxReductionCost(VectorType *Ty, VectorType *CondTy,
+ bool IsPairwise, bool IsUnsigned,
+ TTI::TargetCostKind CostKind) {
+ if (!isa<ScalableVectorType>(Ty))
+ return BaseT::getMinMaxReductionCost(Ty, CondTy, IsPairwise, IsUnsigned,
+ CostKind);
+ assert((isa<ScalableVectorType>(Ty) && isa<ScalableVectorType>(CondTy)) &&
+ "Both vector needs to be scalable");
+
+ std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, Ty);
+ int LegalizationCost = 0;
+ if (LT.first > 1) {
+ Type *LegalVTy = EVT(LT.second).getTypeForEVT(Ty->getContext());
+ unsigned CmpOpcode =
+ Ty->isFPOrFPVectorTy() ? Instruction::FCmp : Instruction::ICmp;
+ LegalizationCost =
+ getCmpSelInstrCost(CmpOpcode, LegalVTy, LegalVTy,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind) +
+ getCmpSelInstrCost(Instruction::Select, LegalVTy, LegalVTy,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ LegalizationCost *= LT.first - 1;
+ }
+
+ return LegalizationCost + /*Cost of horizontal reduction*/ 2;
+}
+
+int AArch64TTIImpl::getArithmeticReductionCostSVE(
+ unsigned Opcode, VectorType *ValTy, bool IsPairwise,
+ TTI::TargetCostKind CostKind) {
+ assert(!IsPairwise && "Cannot be pair wise to continue");
+
+ std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, ValTy);
+ int LegalizationCost = 0;
+ if (LT.first > 1) {
+ Type *LegalVTy = EVT(LT.second).getTypeForEVT(ValTy->getContext());
+ LegalizationCost = getArithmeticInstrCost(Opcode, LegalVTy, CostKind);
+ LegalizationCost *= LT.first - 1;
+ }
+
+ int ISD = TLI->InstructionOpcodeToISD(Opcode);
+ assert(ISD && "Invalid opcode");
+ // Add the final reduction cost for the legal horizontal reduction
+ switch (ISD) {
+ case ISD::ADD:
+ case ISD::AND:
+ case ISD::OR:
+ case ISD::XOR:
+ case ISD::FADD:
+ return LegalizationCost + 2;
+ default:
+ // TODO: Replace for invalid when InstructionCost is used
+ // cases not supported by SVE
+ return 16;
+ }
+}
+
int AArch64TTIImpl::getArithmeticReductionCost(unsigned Opcode,
VectorType *ValTy,
bool IsPairwiseForm,
TTI::TargetCostKind CostKind) {
- if (isa<ScalableVectorType>(ValTy))
- return getArithmeticReductionCostSVE(Opcode, ValTy, IsPairwiseForm,
- CostKind);
+ if (isa<ScalableVectorType>(ValTy))
+ return getArithmeticReductionCostSVE(Opcode, ValTy, IsPairwiseForm,
+ CostKind);
if (IsPairwiseForm)
return BaseT::getArithmeticReductionCost(Opcode, ValTy, IsPairwiseForm,
CostKind);
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetTransformInfo.h b/contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetTransformInfo.h
index f669e3f595..7c9360ada9 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetTransformInfo.h
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AArch64TargetTransformInfo.h
@@ -74,8 +74,8 @@ public:
int getIntImmCost(int64_t Val);
int getIntImmCost(const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind);
int getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm,
- Type *Ty, TTI::TargetCostKind CostKind,
- Instruction *Inst = nullptr);
+ Type *Ty, TTI::TargetCostKind CostKind,
+ Instruction *Inst = nullptr);
int getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
Type *Ty, TTI::TargetCostKind CostKind);
TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth);
@@ -97,9 +97,9 @@ public:
return 31;
}
- unsigned getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
- TTI::TargetCostKind CostKind);
-
+ unsigned getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
+ TTI::TargetCostKind CostKind);
+
unsigned getRegisterBitWidth(bool Vector) const {
if (Vector) {
if (ST->hasSVE())
@@ -115,21 +115,21 @@ public:
return ST->getMinVectorRegisterBitWidth();
}
- Optional<unsigned> getMaxVScale() const {
- if (ST->hasSVE())
- return AArch64::SVEMaxBitsPerVector / AArch64::SVEBitsPerBlock;
- return BaseT::getMaxVScale();
- }
-
+ Optional<unsigned> getMaxVScale() const {
+ if (ST->hasSVE())
+ return AArch64::SVEMaxBitsPerVector / AArch64::SVEBitsPerBlock;
+ return BaseT::getMaxVScale();
+ }
+
unsigned getMaxInterleaveFactor(unsigned VF);
- unsigned getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
- const Value *Ptr, bool VariableMask,
- Align Alignment, TTI::TargetCostKind CostKind,
- const Instruction *I = nullptr);
-
+ unsigned getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
+ const Value *Ptr, bool VariableMask,
+ Align Alignment, TTI::TargetCostKind CostKind,
+ const Instruction *I = nullptr);
+
int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
- TTI::CastContextHint CCH, TTI::TargetCostKind CostKind,
+ TTI::CastContextHint CCH, TTI::TargetCostKind CostKind,
const Instruction *I = nullptr);
int getExtractWithExtendCost(unsigned Opcode, Type *Dst, VectorType *VecTy,
@@ -139,14 +139,14 @@ public:
int getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index);
- int getMinMaxReductionCost(VectorType *Ty, VectorType *CondTy,
- bool IsPairwise, bool IsUnsigned,
- TTI::TargetCostKind CostKind);
-
- int getArithmeticReductionCostSVE(unsigned Opcode, VectorType *ValTy,
- bool IsPairwiseForm,
- TTI::TargetCostKind CostKind);
-
+ int getMinMaxReductionCost(VectorType *Ty, VectorType *CondTy,
+ bool IsPairwise, bool IsUnsigned,
+ TTI::TargetCostKind CostKind);
+
+ int getArithmeticReductionCostSVE(unsigned Opcode, VectorType *ValTy,
+ bool IsPairwiseForm,
+ TTI::TargetCostKind CostKind);
+
int getArithmeticInstrCost(
unsigned Opcode, Type *Ty,
TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput,
@@ -160,13 +160,13 @@ public:
int getAddressComputationCost(Type *Ty, ScalarEvolution *SE, const SCEV *Ptr);
int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
- CmpInst::Predicate VecPred,
+ CmpInst::Predicate VecPred,
TTI::TargetCostKind CostKind,
const Instruction *I = nullptr);
TTI::MemCmpExpansionOptions enableMemCmpExpansion(bool OptSize,
bool IsZeroCmp) const;
- bool useNeonVector(const Type *Ty) const;
+ bool useNeonVector(const Type *Ty) const;
int getMemoryOpCost(unsigned Opcode, Type *Src, MaybeAlign Alignment,
unsigned AddressSpace,
@@ -191,9 +191,9 @@ public:
return false;
Type *Ty = cast<ScalableVectorType>(DataType)->getElementType();
- if (Ty->isPointerTy())
- return true;
-
+ if (Ty->isPointerTy())
+ return true;
+
if (Ty->isBFloatTy() || Ty->isHalfTy() ||
Ty->isFloatTy() || Ty->isDoubleTy())
return true;
@@ -241,14 +241,14 @@ public:
shouldConsiderAddressTypePromotion(const Instruction &I,
bool &AllowPromotionWithoutCommonHeader);
- bool shouldExpandReduction(const IntrinsicInst *II) const { return false; }
+ bool shouldExpandReduction(const IntrinsicInst *II) const { return false; }
unsigned getGISelRematGlobalCost() const {
return 2;
}
- bool supportsScalableVectors() const { return ST->hasSVE(); }
-
+ bool supportsScalableVectors() const { return ST->hasSVE(); }
+
bool useReductionIntrinsic(unsigned Opcode, Type *Ty,
TTI::ReductionFlags Flags) const;
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/contrib/libs/llvm12/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index d69e2b127c..96c50ff3f8 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "MCTargetDesc/AArch64AddressingModes.h"
-#include "MCTargetDesc/AArch64InstPrinter.h"
+#include "MCTargetDesc/AArch64InstPrinter.h"
#include "MCTargetDesc/AArch64MCExpr.h"
#include "MCTargetDesc/AArch64MCTargetDesc.h"
#include "MCTargetDesc/AArch64TargetStreamer.h"
@@ -159,13 +159,13 @@ private:
bool parseSymbolicImmVal(const MCExpr *&ImmVal);
bool parseNeonVectorList(OperandVector &Operands);
bool parseOptionalMulOperand(OperandVector &Operands);
- bool parseKeywordOperand(OperandVector &Operands);
+ bool parseKeywordOperand(OperandVector &Operands);
bool parseOperand(OperandVector &Operands, bool isCondCode,
bool invertCondCode);
- bool parseImmExpr(int64_t &Out);
- bool parseComma();
- bool parseRegisterInRange(unsigned &Out, unsigned Base, unsigned First,
- unsigned Last);
+ bool parseImmExpr(int64_t &Out);
+ bool parseComma();
+ bool parseRegisterInRange(unsigned &Out, unsigned Base, unsigned First,
+ unsigned Last);
bool showMatchError(SMLoc Loc, unsigned ErrCode, uint64_t ErrorInfo,
OperandVector &Operands);
@@ -187,31 +187,31 @@ private:
bool parseDirectiveVariantPCS(SMLoc L);
- bool parseDirectiveSEHAllocStack(SMLoc L);
- bool parseDirectiveSEHPrologEnd(SMLoc L);
- bool parseDirectiveSEHSaveR19R20X(SMLoc L);
- bool parseDirectiveSEHSaveFPLR(SMLoc L);
- bool parseDirectiveSEHSaveFPLRX(SMLoc L);
- bool parseDirectiveSEHSaveReg(SMLoc L);
- bool parseDirectiveSEHSaveRegX(SMLoc L);
- bool parseDirectiveSEHSaveRegP(SMLoc L);
- bool parseDirectiveSEHSaveRegPX(SMLoc L);
- bool parseDirectiveSEHSaveLRPair(SMLoc L);
- bool parseDirectiveSEHSaveFReg(SMLoc L);
- bool parseDirectiveSEHSaveFRegX(SMLoc L);
- bool parseDirectiveSEHSaveFRegP(SMLoc L);
- bool parseDirectiveSEHSaveFRegPX(SMLoc L);
- bool parseDirectiveSEHSetFP(SMLoc L);
- bool parseDirectiveSEHAddFP(SMLoc L);
- bool parseDirectiveSEHNop(SMLoc L);
- bool parseDirectiveSEHSaveNext(SMLoc L);
- bool parseDirectiveSEHEpilogStart(SMLoc L);
- bool parseDirectiveSEHEpilogEnd(SMLoc L);
- bool parseDirectiveSEHTrapFrame(SMLoc L);
- bool parseDirectiveSEHMachineFrame(SMLoc L);
- bool parseDirectiveSEHContext(SMLoc L);
- bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
-
+ bool parseDirectiveSEHAllocStack(SMLoc L);
+ bool parseDirectiveSEHPrologEnd(SMLoc L);
+ bool parseDirectiveSEHSaveR19R20X(SMLoc L);
+ bool parseDirectiveSEHSaveFPLR(SMLoc L);
+ bool parseDirectiveSEHSaveFPLRX(SMLoc L);
+ bool parseDirectiveSEHSaveReg(SMLoc L);
+ bool parseDirectiveSEHSaveRegX(SMLoc L);
+ bool parseDirectiveSEHSaveRegP(SMLoc L);
+ bool parseDirectiveSEHSaveRegPX(SMLoc L);
+ bool parseDirectiveSEHSaveLRPair(SMLoc L);
+ bool parseDirectiveSEHSaveFReg(SMLoc L);
+ bool parseDirectiveSEHSaveFRegX(SMLoc L);
+ bool parseDirectiveSEHSaveFRegP(SMLoc L);
+ bool parseDirectiveSEHSaveFRegPX(SMLoc L);
+ bool parseDirectiveSEHSetFP(SMLoc L);
+ bool parseDirectiveSEHAddFP(SMLoc L);
+ bool parseDirectiveSEHNop(SMLoc L);
+ bool parseDirectiveSEHSaveNext(SMLoc L);
+ bool parseDirectiveSEHEpilogStart(SMLoc L);
+ bool parseDirectiveSEHEpilogEnd(SMLoc L);
+ bool parseDirectiveSEHTrapFrame(SMLoc L);
+ bool parseDirectiveSEHMachineFrame(SMLoc L);
+ bool parseDirectiveSEHContext(SMLoc L);
+ bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
+
bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
SmallVectorImpl<SMLoc> &Loc);
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
@@ -231,7 +231,7 @@ private:
RegKind MatchKind);
OperandMatchResultTy tryParseOptionalShiftExtend(OperandVector &Operands);
OperandMatchResultTy tryParseBarrierOperand(OperandVector &Operands);
- OperandMatchResultTy tryParseBarriernXSOperand(OperandVector &Operands);
+ OperandMatchResultTy tryParseBarriernXSOperand(OperandVector &Operands);
OperandMatchResultTy tryParseMRSSystemRegister(OperandVector &Operands);
OperandMatchResultTy tryParseSysReg(OperandVector &Operands);
OperandMatchResultTy tryParseSysCROperand(OperandVector &Operands);
@@ -258,7 +258,7 @@ private:
OperandMatchResultTy tryParseVectorList(OperandVector &Operands,
bool ExpectMatch = false);
OperandMatchResultTy tryParseSVEPattern(OperandVector &Operands);
- OperandMatchResultTy tryParseGPR64x8(OperandVector &Operands);
+ OperandMatchResultTy tryParseGPR64x8(OperandVector &Operands);
public:
enum AArch64MatchResultTy {
@@ -271,7 +271,7 @@ public:
AArch64AsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
const MCInstrInfo &MII, const MCTargetOptions &Options)
: MCTargetAsmParser(Options, STI, MII) {
- IsILP32 = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32;
+ IsILP32 = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32;
MCAsmParserExtension::Initialize(Parser);
MCStreamer &S = getParser().getStreamer();
if (S.getTargetStreamer() == nullptr)
@@ -404,7 +404,7 @@ private:
const char *Data;
unsigned Length;
unsigned Val; // Not the enum since not all values have names.
- bool HasnXSModifier;
+ bool HasnXSModifier;
};
struct SysRegOp {
@@ -574,11 +574,11 @@ public:
return StringRef(Barrier.Data, Barrier.Length);
}
- bool getBarriernXSModifier() const {
- assert(Kind == k_Barrier && "Invalid access!");
- return Barrier.HasnXSModifier;
- }
-
+ bool getBarriernXSModifier() const {
+ assert(Kind == k_Barrier && "Invalid access!");
+ return Barrier.HasnXSModifier;
+ }
+
unsigned getReg() const override {
assert(Kind == k_Register && "Invalid access!");
return Reg.RegNum;
@@ -750,8 +750,8 @@ public:
ELFRefKind == AArch64MCExpr::VK_GOTTPREL_LO12_NC ||
ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 ||
ELFRefKind == AArch64MCExpr::VK_SECREL_LO12 ||
- ELFRefKind == AArch64MCExpr::VK_SECREL_HI12 ||
- ELFRefKind == AArch64MCExpr::VK_GOT_PAGE_LO15) {
+ ELFRefKind == AArch64MCExpr::VK_SECREL_HI12 ||
+ ELFRefKind == AArch64MCExpr::VK_GOT_PAGE_LO15) {
// Note that we don't range-check the addend. It's adjusted modulo page
// size when converted, so there is no "out of range" condition when using
// @pageoff.
@@ -897,8 +897,8 @@ public:
if (!isShiftedImm() && (!isImm() || !isa<MCConstantExpr>(getImm())))
return DiagnosticPredicateTy::NoMatch;
- bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
- std::is_same<int8_t, T>::value;
+ bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
+ std::is_same<int8_t, T>::value;
if (auto ShiftedImm = getShiftedVal<8>())
if (!(IsByte && ShiftedImm->second) &&
AArch64_AM::isSVECpyImm<T>(uint64_t(ShiftedImm->first)
@@ -915,8 +915,8 @@ public:
if (!isShiftedImm() && (!isImm() || !isa<MCConstantExpr>(getImm())))
return DiagnosticPredicateTy::NoMatch;
- bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
- std::is_same<int8_t, T>::value;
+ bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
+ std::is_same<int8_t, T>::value;
if (auto ShiftedImm = getShiftedVal<8>())
if (!(IsByte && ShiftedImm->second) &&
AArch64_AM::isSVEAddSubImm<T>(ShiftedImm->first
@@ -1041,12 +1041,12 @@ public:
AArch64_AM::getFP64Imm(getFPImm().bitcastToAPInt()) != -1;
}
- bool isBarrier() const {
- return Kind == k_Barrier && !getBarriernXSModifier();
- }
- bool isBarriernXS() const {
- return Kind == k_Barrier && getBarriernXSModifier();
- }
+ bool isBarrier() const {
+ return Kind == k_Barrier && !getBarriernXSModifier();
+ }
+ bool isBarriernXS() const {
+ return Kind == k_Barrier && getBarriernXSModifier();
+ }
bool isSysReg() const { return Kind == k_SysReg; }
bool isMRSSystemRegister() const {
@@ -1173,12 +1173,12 @@ public:
AArch64MCRegisterClasses[AArch64::GPR32RegClassID].contains(Reg.RegNum);
}
- bool isGPR64x8() const {
- return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
- AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].contains(
- Reg.RegNum);
- }
-
+ bool isGPR64x8() const {
+ return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
+ AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].contains(
+ Reg.RegNum);
+ }
+
bool isWSeqPair() const {
return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains(
@@ -1742,11 +1742,11 @@ public:
Inst.addOperand(MCOperand::createImm(getBarrier()));
}
- void addBarriernXSOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createImm(getBarrier()));
- }
-
+ void addBarriernXSOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::createImm(getBarrier()));
+ }
+
void addMRSSystemRegisterOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
@@ -1982,13 +1982,13 @@ public:
static std::unique_ptr<AArch64Operand> CreateBarrier(unsigned Val,
StringRef Str,
SMLoc S,
- MCContext &Ctx,
- bool HasnXSModifier) {
+ MCContext &Ctx,
+ bool HasnXSModifier) {
auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
Op->Barrier.Val = Val;
Op->Barrier.Data = Str.data();
Op->Barrier.Length = Str.size();
- Op->Barrier.HasnXSModifier = HasnXSModifier;
+ Op->Barrier.HasnXSModifier = HasnXSModifier;
Op->StartLoc = S;
Op->EndLoc = S;
return Op;
@@ -2133,9 +2133,9 @@ void AArch64Operand::print(raw_ostream &OS) const {
case k_PSBHint:
OS << getPSBHintName();
break;
- case k_BTIHint:
- OS << getBTIHintName();
- break;
+ case k_BTIHint:
+ OS << getBTIHintName();
+ break;
case k_Register:
OS << "<register " << getReg() << ">";
if (!getShiftExtendAmount() && !hasShiftExtendAmount())
@@ -2570,7 +2570,7 @@ AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE &&
ELFRefKind != AArch64MCExpr::VK_ABS_PAGE_NC &&
ELFRefKind != AArch64MCExpr::VK_GOT_PAGE &&
- ELFRefKind != AArch64MCExpr::VK_GOT_PAGE_LO15 &&
+ ELFRefKind != AArch64MCExpr::VK_GOT_PAGE_LO15 &&
ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE &&
ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) {
// The operand must be an @page or @gotpage qualified symbolref.
@@ -2904,7 +2904,7 @@ static const struct Extension {
{"predres", {AArch64::FeaturePredRes}},
{"ccdp", {AArch64::FeatureCacheDeepPersist}},
{"mte", {AArch64::FeatureMTE}},
- {"memtag", {AArch64::FeatureMTE}},
+ {"memtag", {AArch64::FeatureMTE}},
{"tlb-rmi", {AArch64::FeatureTLB_RMI}},
{"pan-rwv", {AArch64::FeaturePAN_RWV}},
{"ccpp", {AArch64::FeatureCCPP}},
@@ -2915,10 +2915,10 @@ static const struct Extension {
{"sve2-sm4", {AArch64::FeatureSVE2SM4}},
{"sve2-sha3", {AArch64::FeatureSVE2SHA3}},
{"sve2-bitperm", {AArch64::FeatureSVE2BitPerm}},
- {"ls64", {AArch64::FeatureLS64}},
- {"xs", {AArch64::FeatureXS}},
- {"pauth", {AArch64::FeaturePAuth}},
- {"flagm", {AArch64::FeatureFlagM}},
+ {"ls64", {AArch64::FeatureLS64}},
+ {"xs", {AArch64::FeatureXS}},
+ {"pauth", {AArch64::FeaturePAuth}},
+ {"flagm", {AArch64::FeatureFlagM}},
// FIXME: Unsupported extensions
{"pan", {}},
{"lor", {}},
@@ -2939,16 +2939,16 @@ static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) {
Str += "ARMv8.5a";
else if (FBS[AArch64::HasV8_6aOps])
Str += "ARMv8.6a";
- else if (FBS[AArch64::HasV8_7aOps])
- Str += "ARMv8.7a";
+ else if (FBS[AArch64::HasV8_7aOps])
+ Str += "ARMv8.7a";
else {
- SmallVector<std::string, 2> ExtMatches;
- for (const auto& Ext : ExtensionMap) {
+ SmallVector<std::string, 2> ExtMatches;
+ for (const auto& Ext : ExtensionMap) {
// Use & in case multiple features are enabled
- if ((FBS & Ext.Features) != FeatureBitset())
- ExtMatches.push_back(Ext.Name);
- }
- Str += !ExtMatches.empty() ? llvm::join(ExtMatches, ", ") : "(unknown)";
+ if ((FBS & Ext.Features) != FeatureBitset())
+ ExtMatches.push_back(Ext.Name);
+ }
+ Str += !ExtMatches.empty() ? llvm::join(ExtMatches, ", ") : "(unknown)";
}
}
@@ -2993,7 +2993,7 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
if (!IC)
return TokError("invalid operand for IC instruction");
else if (!IC->haveFeatures(getSTI().getFeatureBits())) {
- std::string Str("IC " + std::string(IC->Name) + " requires: ");
+ std::string Str("IC " + std::string(IC->Name) + " requires: ");
setRequiredFeatureString(IC->getRequiredFeatures(), Str);
return TokError(Str.c_str());
}
@@ -3003,7 +3003,7 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
if (!DC)
return TokError("invalid operand for DC instruction");
else if (!DC->haveFeatures(getSTI().getFeatureBits())) {
- std::string Str("DC " + std::string(DC->Name) + " requires: ");
+ std::string Str("DC " + std::string(DC->Name) + " requires: ");
setRequiredFeatureString(DC->getRequiredFeatures(), Str);
return TokError(Str.c_str());
}
@@ -3013,7 +3013,7 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
if (!AT)
return TokError("invalid operand for AT instruction");
else if (!AT->haveFeatures(getSTI().getFeatureBits())) {
- std::string Str("AT " + std::string(AT->Name) + " requires: ");
+ std::string Str("AT " + std::string(AT->Name) + " requires: ");
setRequiredFeatureString(AT->getRequiredFeatures(), Str);
return TokError(Str.c_str());
}
@@ -3023,7 +3023,7 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
if (!TLBI)
return TokError("invalid operand for TLBI instruction");
else if (!TLBI->haveFeatures(getSTI().getFeatureBits())) {
- std::string Str("TLBI " + std::string(TLBI->Name) + " requires: ");
+ std::string Str("TLBI " + std::string(TLBI->Name) + " requires: ");
setRequiredFeatureString(TLBI->getRequiredFeatures(), Str);
return TokError(Str.c_str());
}
@@ -3034,7 +3034,7 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
return TokError("invalid operand for prediction restriction instruction");
else if (!PRCTX->haveFeatures(getSTI().getFeatureBits())) {
std::string Str(
- Mnemonic.upper() + std::string(PRCTX->Name) + " requires: ");
+ Mnemonic.upper() + std::string(PRCTX->Name) + " requires: ");
setRequiredFeatureString(PRCTX->getRequiredFeatures(), Str);
return TokError(Str.c_str());
}
@@ -3082,7 +3082,7 @@ AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
// Immediate operand.
const MCExpr *ImmVal;
SMLoc ExprLoc = getLoc();
- AsmToken IntTok = Tok;
+ AsmToken IntTok = Tok;
if (getParser().parseExpression(ImmVal))
return MatchOperand_ParseFail;
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
@@ -3090,22 +3090,22 @@ AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
Error(ExprLoc, "immediate value expected for barrier operand");
return MatchOperand_ParseFail;
}
- int64_t Value = MCE->getValue();
- if (Mnemonic == "dsb" && Value > 15) {
- // This case is a no match here, but it might be matched by the nXS
- // variant. Deliberately not unlex the optional '#' as it is not necessary
- // to characterize an integer immediate.
- Parser.getLexer().UnLex(IntTok);
- return MatchOperand_NoMatch;
- }
- if (Value < 0 || Value > 15) {
+ int64_t Value = MCE->getValue();
+ if (Mnemonic == "dsb" && Value > 15) {
+ // This case is a no match here, but it might be matched by the nXS
+ // variant. Deliberately not unlex the optional '#' as it is not necessary
+ // to characterize an integer immediate.
+ Parser.getLexer().UnLex(IntTok);
+ return MatchOperand_NoMatch;
+ }
+ if (Value < 0 || Value > 15) {
Error(ExprLoc, "barrier operand out of range");
return MatchOperand_ParseFail;
}
- auto DB = AArch64DB::lookupDBByEncoding(Value);
- Operands.push_back(AArch64Operand::CreateBarrier(Value, DB ? DB->Name : "",
- ExprLoc, getContext(),
- false /*hasnXSModifier*/));
+ auto DB = AArch64DB::lookupDBByEncoding(Value);
+ Operands.push_back(AArch64Operand::CreateBarrier(Value, DB ? DB->Name : "",
+ ExprLoc, getContext(),
+ false /*hasnXSModifier*/));
return MatchOperand_Success;
}
@@ -3114,9 +3114,9 @@ AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
return MatchOperand_ParseFail;
}
- StringRef Operand = Tok.getString();
- auto TSB = AArch64TSB::lookupTSBByName(Operand);
- auto DB = AArch64DB::lookupDBByName(Operand);
+ StringRef Operand = Tok.getString();
+ auto TSB = AArch64TSB::lookupTSBByName(Operand);
+ auto DB = AArch64DB::lookupDBByName(Operand);
// The only valid named option for ISB is 'sy'
if (Mnemonic == "isb" && (!DB || DB->Encoding != AArch64DB::sy)) {
TokError("'sy' or #imm operand expected");
@@ -3126,79 +3126,79 @@ AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
TokError("'csync' operand expected");
return MatchOperand_ParseFail;
} else if (!DB && !TSB) {
- if (Mnemonic == "dsb") {
- // This case is a no match here, but it might be matched by the nXS
- // variant.
- return MatchOperand_NoMatch;
- }
+ if (Mnemonic == "dsb") {
+ // This case is a no match here, but it might be matched by the nXS
+ // variant.
+ return MatchOperand_NoMatch;
+ }
TokError("invalid barrier option name");
return MatchOperand_ParseFail;
}
Operands.push_back(AArch64Operand::CreateBarrier(
- DB ? DB->Encoding : TSB->Encoding, Tok.getString(), getLoc(),
- getContext(), false /*hasnXSModifier*/));
+ DB ? DB->Encoding : TSB->Encoding, Tok.getString(), getLoc(),
+ getContext(), false /*hasnXSModifier*/));
+ Parser.Lex(); // Consume the option
+
+ return MatchOperand_Success;
+}
+
+OperandMatchResultTy
+AArch64AsmParser::tryParseBarriernXSOperand(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
+ const AsmToken &Tok = Parser.getTok();
+
+ assert(Mnemonic == "dsb" && "Instruction does not accept nXS operands");
+ if (Mnemonic != "dsb")
+ return MatchOperand_ParseFail;
+
+ if (parseOptionalToken(AsmToken::Hash) || Tok.is(AsmToken::Integer)) {
+ // Immediate operand.
+ const MCExpr *ImmVal;
+ SMLoc ExprLoc = getLoc();
+ if (getParser().parseExpression(ImmVal))
+ return MatchOperand_ParseFail;
+ const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
+ if (!MCE) {
+ Error(ExprLoc, "immediate value expected for barrier operand");
+ return MatchOperand_ParseFail;
+ }
+ int64_t Value = MCE->getValue();
+ // v8.7-A DSB in the nXS variant accepts only the following immediate
+ // values: 16, 20, 24, 28.
+ if (Value != 16 && Value != 20 && Value != 24 && Value != 28) {
+ Error(ExprLoc, "barrier operand out of range");
+ return MatchOperand_ParseFail;
+ }
+ auto DB = AArch64DBnXS::lookupDBnXSByImmValue(Value);
+ Operands.push_back(AArch64Operand::CreateBarrier(DB->Encoding, DB->Name,
+ ExprLoc, getContext(),
+ true /*hasnXSModifier*/));
+ return MatchOperand_Success;
+ }
+
+ if (Tok.isNot(AsmToken::Identifier)) {
+ TokError("invalid operand for instruction");
+ return MatchOperand_ParseFail;
+ }
+
+ StringRef Operand = Tok.getString();
+ auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
+
+ if (!DB) {
+ TokError("invalid barrier option name");
+ return MatchOperand_ParseFail;
+ }
+
+ Operands.push_back(
+ AArch64Operand::CreateBarrier(DB->Encoding, Tok.getString(), getLoc(),
+ getContext(), true /*hasnXSModifier*/));
Parser.Lex(); // Consume the option
return MatchOperand_Success;
}
OperandMatchResultTy
-AArch64AsmParser::tryParseBarriernXSOperand(OperandVector &Operands) {
- MCAsmParser &Parser = getParser();
- const AsmToken &Tok = Parser.getTok();
-
- assert(Mnemonic == "dsb" && "Instruction does not accept nXS operands");
- if (Mnemonic != "dsb")
- return MatchOperand_ParseFail;
-
- if (parseOptionalToken(AsmToken::Hash) || Tok.is(AsmToken::Integer)) {
- // Immediate operand.
- const MCExpr *ImmVal;
- SMLoc ExprLoc = getLoc();
- if (getParser().parseExpression(ImmVal))
- return MatchOperand_ParseFail;
- const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
- if (!MCE) {
- Error(ExprLoc, "immediate value expected for barrier operand");
- return MatchOperand_ParseFail;
- }
- int64_t Value = MCE->getValue();
- // v8.7-A DSB in the nXS variant accepts only the following immediate
- // values: 16, 20, 24, 28.
- if (Value != 16 && Value != 20 && Value != 24 && Value != 28) {
- Error(ExprLoc, "barrier operand out of range");
- return MatchOperand_ParseFail;
- }
- auto DB = AArch64DBnXS::lookupDBnXSByImmValue(Value);
- Operands.push_back(AArch64Operand::CreateBarrier(DB->Encoding, DB->Name,
- ExprLoc, getContext(),
- true /*hasnXSModifier*/));
- return MatchOperand_Success;
- }
-
- if (Tok.isNot(AsmToken::Identifier)) {
- TokError("invalid operand for instruction");
- return MatchOperand_ParseFail;
- }
-
- StringRef Operand = Tok.getString();
- auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
-
- if (!DB) {
- TokError("invalid barrier option name");
- return MatchOperand_ParseFail;
- }
-
- Operands.push_back(
- AArch64Operand::CreateBarrier(DB->Encoding, Tok.getString(), getLoc(),
- getContext(), true /*hasnXSModifier*/));
- Parser.Lex(); // Consume the option
-
- return MatchOperand_Success;
-}
-
-OperandMatchResultTy
AArch64AsmParser::tryParseSysReg(OperandVector &Operands) {
MCAsmParser &Parser = getParser();
const AsmToken &Tok = Parser.getTok();
@@ -3438,7 +3438,7 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
.Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC)
.Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12)
.Case("got", AArch64MCExpr::VK_GOT_PAGE)
- .Case("gotpage_lo15", AArch64MCExpr::VK_GOT_PAGE_LO15)
+ .Case("gotpage_lo15", AArch64MCExpr::VK_GOT_PAGE_LO15)
.Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
.Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
.Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
@@ -3707,17 +3707,17 @@ bool AArch64AsmParser::parseOptionalMulOperand(OperandVector &Operands) {
return Error(getLoc(), "expected 'vl' or '#<imm>'");
}
-bool AArch64AsmParser::parseKeywordOperand(OperandVector &Operands) {
- MCAsmParser &Parser = getParser();
- auto Tok = Parser.getTok();
- if (Tok.isNot(AsmToken::Identifier))
- return true;
- Operands.push_back(AArch64Operand::CreateToken(Tok.getString(), false,
- Tok.getLoc(), getContext()));
- Parser.Lex();
- return false;
-}
-
+bool AArch64AsmParser::parseKeywordOperand(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
+ auto Tok = Parser.getTok();
+ if (Tok.isNot(AsmToken::Identifier))
+ return true;
+ Operands.push_back(AArch64Operand::CreateToken(Tok.getString(), false,
+ Tok.getLoc(), getContext()));
+ Parser.Lex();
+ return false;
+}
+
/// parseOperand - Parse a arm instruction operand. For now this parses the
/// operand regardless of the mnemonic.
bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
@@ -3782,11 +3782,11 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
if (GotShift != MatchOperand_NoMatch)
return GotShift;
- // If this is a two-word mnemonic, parse its special keyword
- // operand as an identifier.
- if (Mnemonic == "brb")
- return parseKeywordOperand(Operands);
-
+ // If this is a two-word mnemonic, parse its special keyword
+ // operand as an identifier.
+ if (Mnemonic == "brb")
+ return parseKeywordOperand(Operands);
+
// This was not a register so parse other operands that start with an
// identifier (like labels) as expressions and create them as immediates.
const MCExpr *IdVal;
@@ -3895,66 +3895,66 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
}
}
-bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
- const MCExpr *Expr = nullptr;
- SMLoc L = getLoc();
- if (check(getParser().parseExpression(Expr), L, "expected expression"))
- return true;
- const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
- if (check(!Value, L, "expected constant expression"))
- return true;
- Out = Value->getValue();
- return false;
-}
-
-bool AArch64AsmParser::parseComma() {
- if (check(getParser().getTok().isNot(AsmToken::Comma), getLoc(),
- "expected comma"))
- return true;
- // Eat the comma
- getParser().Lex();
- return false;
-}
-
-bool AArch64AsmParser::parseRegisterInRange(unsigned &Out, unsigned Base,
- unsigned First, unsigned Last) {
- unsigned Reg;
- SMLoc Start, End;
- if (check(ParseRegister(Reg, Start, End), getLoc(), "expected register"))
- return true;
-
- // Special handling for FP and LR; they aren't linearly after x28 in
- // the registers enum.
- unsigned RangeEnd = Last;
- if (Base == AArch64::X0) {
- if (Last == AArch64::FP) {
- RangeEnd = AArch64::X28;
- if (Reg == AArch64::FP) {
- Out = 29;
- return false;
- }
- }
- if (Last == AArch64::LR) {
- RangeEnd = AArch64::X28;
- if (Reg == AArch64::FP) {
- Out = 29;
- return false;
- } else if (Reg == AArch64::LR) {
- Out = 30;
- return false;
- }
- }
- }
-
- if (check(Reg < First || Reg > RangeEnd, Start,
- Twine("expected register in range ") +
- AArch64InstPrinter::getRegisterName(First) + " to " +
- AArch64InstPrinter::getRegisterName(Last)))
- return true;
- Out = Reg - Base;
- return false;
-}
-
+bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
+ const MCExpr *Expr = nullptr;
+ SMLoc L = getLoc();
+ if (check(getParser().parseExpression(Expr), L, "expected expression"))
+ return true;
+ const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
+ if (check(!Value, L, "expected constant expression"))
+ return true;
+ Out = Value->getValue();
+ return false;
+}
+
+bool AArch64AsmParser::parseComma() {
+ if (check(getParser().getTok().isNot(AsmToken::Comma), getLoc(),
+ "expected comma"))
+ return true;
+ // Eat the comma
+ getParser().Lex();
+ return false;
+}
+
+bool AArch64AsmParser::parseRegisterInRange(unsigned &Out, unsigned Base,
+ unsigned First, unsigned Last) {
+ unsigned Reg;
+ SMLoc Start, End;
+ if (check(ParseRegister(Reg, Start, End), getLoc(), "expected register"))
+ return true;
+
+ // Special handling for FP and LR; they aren't linearly after x28 in
+ // the registers enum.
+ unsigned RangeEnd = Last;
+ if (Base == AArch64::X0) {
+ if (Last == AArch64::FP) {
+ RangeEnd = AArch64::X28;
+ if (Reg == AArch64::FP) {
+ Out = 29;
+ return false;
+ }
+ }
+ if (Last == AArch64::LR) {
+ RangeEnd = AArch64::X28;
+ if (Reg == AArch64::FP) {
+ Out = 29;
+ return false;
+ } else if (Reg == AArch64::LR) {
+ Out = 30;
+ return false;
+ }
+ }
+ }
+
+ if (check(Reg < First || Reg > RangeEnd, Start,
+ Twine("expected register in range ") +
+ AArch64InstPrinter::getRegisterName(First) + " to " +
+ AArch64InstPrinter::getRegisterName(Last)))
+ return true;
+ Out = Reg - Base;
+ return false;
+}
+
bool AArch64AsmParser::regsEqual(const MCParsedAsmOperand &Op1,
const MCParsedAsmOperand &Op2) const {
auto &AOp1 = static_cast<const AArch64Operand&>(Op1);
@@ -5273,7 +5273,7 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
const MCObjectFileInfo::Environment Format =
getContext().getObjectFileInfo()->getObjectFileType();
bool IsMachO = Format == MCObjectFileInfo::IsMachO;
- bool IsCOFF = Format == MCObjectFileInfo::IsCOFF;
+ bool IsCOFF = Format == MCObjectFileInfo::IsCOFF;
auto IDVal = DirectiveID.getIdentifier().lower();
SMLoc Loc = DirectiveID.getLoc();
@@ -5302,57 +5302,57 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
parseDirectiveLOH(IDVal, Loc);
else
return true;
- } else if (IsCOFF) {
- if (IDVal == ".seh_stackalloc")
- parseDirectiveSEHAllocStack(Loc);
- else if (IDVal == ".seh_endprologue")
- parseDirectiveSEHPrologEnd(Loc);
- else if (IDVal == ".seh_save_r19r20_x")
- parseDirectiveSEHSaveR19R20X(Loc);
- else if (IDVal == ".seh_save_fplr")
- parseDirectiveSEHSaveFPLR(Loc);
- else if (IDVal == ".seh_save_fplr_x")
- parseDirectiveSEHSaveFPLRX(Loc);
- else if (IDVal == ".seh_save_reg")
- parseDirectiveSEHSaveReg(Loc);
- else if (IDVal == ".seh_save_reg_x")
- parseDirectiveSEHSaveRegX(Loc);
- else if (IDVal == ".seh_save_regp")
- parseDirectiveSEHSaveRegP(Loc);
- else if (IDVal == ".seh_save_regp_x")
- parseDirectiveSEHSaveRegPX(Loc);
- else if (IDVal == ".seh_save_lrpair")
- parseDirectiveSEHSaveLRPair(Loc);
- else if (IDVal == ".seh_save_freg")
- parseDirectiveSEHSaveFReg(Loc);
- else if (IDVal == ".seh_save_freg_x")
- parseDirectiveSEHSaveFRegX(Loc);
- else if (IDVal == ".seh_save_fregp")
- parseDirectiveSEHSaveFRegP(Loc);
- else if (IDVal == ".seh_save_fregp_x")
- parseDirectiveSEHSaveFRegPX(Loc);
- else if (IDVal == ".seh_set_fp")
- parseDirectiveSEHSetFP(Loc);
- else if (IDVal == ".seh_add_fp")
- parseDirectiveSEHAddFP(Loc);
- else if (IDVal == ".seh_nop")
- parseDirectiveSEHNop(Loc);
- else if (IDVal == ".seh_save_next")
- parseDirectiveSEHSaveNext(Loc);
- else if (IDVal == ".seh_startepilogue")
- parseDirectiveSEHEpilogStart(Loc);
- else if (IDVal == ".seh_endepilogue")
- parseDirectiveSEHEpilogEnd(Loc);
- else if (IDVal == ".seh_trap_frame")
- parseDirectiveSEHTrapFrame(Loc);
- else if (IDVal == ".seh_pushframe")
- parseDirectiveSEHMachineFrame(Loc);
- else if (IDVal == ".seh_context")
- parseDirectiveSEHContext(Loc);
- else if (IDVal == ".seh_clear_unwound_to_call")
- parseDirectiveSEHClearUnwoundToCall(Loc);
- else
- return true;
+ } else if (IsCOFF) {
+ if (IDVal == ".seh_stackalloc")
+ parseDirectiveSEHAllocStack(Loc);
+ else if (IDVal == ".seh_endprologue")
+ parseDirectiveSEHPrologEnd(Loc);
+ else if (IDVal == ".seh_save_r19r20_x")
+ parseDirectiveSEHSaveR19R20X(Loc);
+ else if (IDVal == ".seh_save_fplr")
+ parseDirectiveSEHSaveFPLR(Loc);
+ else if (IDVal == ".seh_save_fplr_x")
+ parseDirectiveSEHSaveFPLRX(Loc);
+ else if (IDVal == ".seh_save_reg")
+ parseDirectiveSEHSaveReg(Loc);
+ else if (IDVal == ".seh_save_reg_x")
+ parseDirectiveSEHSaveRegX(Loc);
+ else if (IDVal == ".seh_save_regp")
+ parseDirectiveSEHSaveRegP(Loc);
+ else if (IDVal == ".seh_save_regp_x")
+ parseDirectiveSEHSaveRegPX(Loc);
+ else if (IDVal == ".seh_save_lrpair")
+ parseDirectiveSEHSaveLRPair(Loc);
+ else if (IDVal == ".seh_save_freg")
+ parseDirectiveSEHSaveFReg(Loc);
+ else if (IDVal == ".seh_save_freg_x")
+ parseDirectiveSEHSaveFRegX(Loc);
+ else if (IDVal == ".seh_save_fregp")
+ parseDirectiveSEHSaveFRegP(Loc);
+ else if (IDVal == ".seh_save_fregp_x")
+ parseDirectiveSEHSaveFRegPX(Loc);
+ else if (IDVal == ".seh_set_fp")
+ parseDirectiveSEHSetFP(Loc);
+ else if (IDVal == ".seh_add_fp")
+ parseDirectiveSEHAddFP(Loc);
+ else if (IDVal == ".seh_nop")
+ parseDirectiveSEHNop(Loc);
+ else if (IDVal == ".seh_save_next")
+ parseDirectiveSEHSaveNext(Loc);
+ else if (IDVal == ".seh_startepilogue")
+ parseDirectiveSEHEpilogStart(Loc);
+ else if (IDVal == ".seh_endepilogue")
+ parseDirectiveSEHEpilogEnd(Loc);
+ else if (IDVal == ".seh_trap_frame")
+ parseDirectiveSEHTrapFrame(Loc);
+ else if (IDVal == ".seh_pushframe")
+ parseDirectiveSEHMachineFrame(Loc);
+ else if (IDVal == ".seh_context")
+ parseDirectiveSEHContext(Loc);
+ else if (IDVal == ".seh_clear_unwound_to_call")
+ parseDirectiveSEHClearUnwoundToCall(Loc);
+ else
+ return true;
} else
return true;
return false;
@@ -5360,8 +5360,8 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
static void ExpandCryptoAEK(AArch64::ArchKind ArchKind,
SmallVector<StringRef, 4> &RequestedExtensions) {
- const bool NoCrypto = llvm::is_contained(RequestedExtensions, "nocrypto");
- const bool Crypto = llvm::is_contained(RequestedExtensions, "crypto");
+ const bool NoCrypto = llvm::is_contained(RequestedExtensions, "nocrypto");
+ const bool Crypto = llvm::is_contained(RequestedExtensions, "crypto");
if (!NoCrypto && Crypto) {
switch (ArchKind) {
@@ -5377,8 +5377,8 @@ static void ExpandCryptoAEK(AArch64::ArchKind ArchKind,
case AArch64::ArchKind::ARMV8_4A:
case AArch64::ArchKind::ARMV8_5A:
case AArch64::ArchKind::ARMV8_6A:
- case AArch64::ArchKind::ARMV8_7A:
- case AArch64::ArchKind::ARMV8R:
+ case AArch64::ArchKind::ARMV8_7A:
+ case AArch64::ArchKind::ARMV8R:
RequestedExtensions.push_back("sm4");
RequestedExtensions.push_back("sha3");
RequestedExtensions.push_back("sha2");
@@ -5399,7 +5399,7 @@ static void ExpandCryptoAEK(AArch64::ArchKind ArchKind,
case AArch64::ArchKind::ARMV8_4A:
case AArch64::ArchKind::ARMV8_5A:
case AArch64::ArchKind::ARMV8_6A:
- case AArch64::ArchKind::ARMV8_7A:
+ case AArch64::ArchKind::ARMV8_7A:
RequestedExtensions.push_back("nosm4");
RequestedExtensions.push_back("nosha3");
RequestedExtensions.push_back("nosha2");
@@ -5433,8 +5433,8 @@ bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
MCSubtargetInfo &STI = copySTI();
std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
- STI.setDefaultFeatures("generic", /*TuneCPU*/ "generic",
- join(ArchFeatures.begin(), ArchFeatures.end(), ","));
+ STI.setDefaultFeatures("generic", /*TuneCPU*/ "generic",
+ join(ArchFeatures.begin(), ArchFeatures.end(), ","));
SmallVector<StringRef, 4> RequestedExtensions;
if (!ExtensionString.empty())
@@ -5536,7 +5536,7 @@ bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
}
MCSubtargetInfo &STI = copySTI();
- STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, "");
+ STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, "");
CurLoc = incrementLoc(CurLoc, CPU.size());
ExpandCryptoAEK(llvm::AArch64::getCPUArchKind(CPU), RequestedExtensions);
@@ -5804,238 +5804,238 @@ bool AArch64AsmParser::parseDirectiveVariantPCS(SMLoc L) {
return false;
}
-/// parseDirectiveSEHAllocStack
-/// ::= .seh_stackalloc
-bool AArch64AsmParser::parseDirectiveSEHAllocStack(SMLoc L) {
- int64_t Size;
- if (parseImmExpr(Size))
- return true;
- getTargetStreamer().EmitARM64WinCFIAllocStack(Size);
- return false;
-}
-
-/// parseDirectiveSEHPrologEnd
-/// ::= .seh_endprologue
-bool AArch64AsmParser::parseDirectiveSEHPrologEnd(SMLoc L) {
- getTargetStreamer().EmitARM64WinCFIPrologEnd();
- return false;
-}
-
-/// parseDirectiveSEHSaveR19R20X
-/// ::= .seh_save_r19r20_x
-bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(SMLoc L) {
- int64_t Offset;
- if (parseImmExpr(Offset))
- return true;
- getTargetStreamer().EmitARM64WinCFISaveR19R20X(Offset);
- return false;
-}
-
-/// parseDirectiveSEHSaveFPLR
-/// ::= .seh_save_fplr
-bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(SMLoc L) {
- int64_t Offset;
- if (parseImmExpr(Offset))
- return true;
- getTargetStreamer().EmitARM64WinCFISaveFPLR(Offset);
- return false;
-}
-
-/// parseDirectiveSEHSaveFPLRX
-/// ::= .seh_save_fplr_x
-bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(SMLoc L) {
- int64_t Offset;
- if (parseImmExpr(Offset))
- return true;
- getTargetStreamer().EmitARM64WinCFISaveFPLRX(Offset);
- return false;
-}
-
-/// parseDirectiveSEHSaveReg
-/// ::= .seh_save_reg
-bool AArch64AsmParser::parseDirectiveSEHSaveReg(SMLoc L) {
- unsigned Reg;
- int64_t Offset;
- if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
- parseComma() || parseImmExpr(Offset))
- return true;
- getTargetStreamer().EmitARM64WinCFISaveReg(Reg, Offset);
- return false;
-}
-
-/// parseDirectiveSEHSaveRegX
-/// ::= .seh_save_reg_x
-bool AArch64AsmParser::parseDirectiveSEHSaveRegX(SMLoc L) {
- unsigned Reg;
- int64_t Offset;
- if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
- parseComma() || parseImmExpr(Offset))
- return true;
- getTargetStreamer().EmitARM64WinCFISaveRegX(Reg, Offset);
- return false;
-}
-
-/// parseDirectiveSEHSaveRegP
-/// ::= .seh_save_regp
-bool AArch64AsmParser::parseDirectiveSEHSaveRegP(SMLoc L) {
- unsigned Reg;
- int64_t Offset;
- if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
- parseComma() || parseImmExpr(Offset))
- return true;
- getTargetStreamer().EmitARM64WinCFISaveRegP(Reg, Offset);
- return false;
-}
-
-/// parseDirectiveSEHSaveRegPX
-/// ::= .seh_save_regp_x
-bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(SMLoc L) {
- unsigned Reg;
- int64_t Offset;
- if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
- parseComma() || parseImmExpr(Offset))
- return true;
- getTargetStreamer().EmitARM64WinCFISaveRegPX(Reg, Offset);
- return false;
-}
-
-/// parseDirectiveSEHSaveLRPair
-/// ::= .seh_save_lrpair
-bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(SMLoc L) {
- unsigned Reg;
- int64_t Offset;
- L = getLoc();
- if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
- parseComma() || parseImmExpr(Offset))
- return true;
- if (check(((Reg - 19) % 2 != 0), L,
- "expected register with even offset from x19"))
- return true;
- getTargetStreamer().EmitARM64WinCFISaveLRPair(Reg, Offset);
- return false;
-}
-
-/// parseDirectiveSEHSaveFReg
-/// ::= .seh_save_freg
-bool AArch64AsmParser::parseDirectiveSEHSaveFReg(SMLoc L) {
- unsigned Reg;
- int64_t Offset;
- if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
- parseComma() || parseImmExpr(Offset))
- return true;
- getTargetStreamer().EmitARM64WinCFISaveFReg(Reg, Offset);
- return false;
-}
-
-/// parseDirectiveSEHSaveFRegX
-/// ::= .seh_save_freg_x
-bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(SMLoc L) {
- unsigned Reg;
- int64_t Offset;
- if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
- parseComma() || parseImmExpr(Offset))
- return true;
- getTargetStreamer().EmitARM64WinCFISaveFRegX(Reg, Offset);
- return false;
-}
-
-/// parseDirectiveSEHSaveFRegP
-/// ::= .seh_save_fregp
-bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(SMLoc L) {
- unsigned Reg;
- int64_t Offset;
- if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
- parseComma() || parseImmExpr(Offset))
- return true;
- getTargetStreamer().EmitARM64WinCFISaveFRegP(Reg, Offset);
- return false;
-}
-
-/// parseDirectiveSEHSaveFRegPX
-/// ::= .seh_save_fregp_x
-bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(SMLoc L) {
- unsigned Reg;
- int64_t Offset;
- if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
- parseComma() || parseImmExpr(Offset))
- return true;
- getTargetStreamer().EmitARM64WinCFISaveFRegPX(Reg, Offset);
- return false;
-}
-
-/// parseDirectiveSEHSetFP
-/// ::= .seh_set_fp
-bool AArch64AsmParser::parseDirectiveSEHSetFP(SMLoc L) {
- getTargetStreamer().EmitARM64WinCFISetFP();
- return false;
-}
-
-/// parseDirectiveSEHAddFP
-/// ::= .seh_add_fp
-bool AArch64AsmParser::parseDirectiveSEHAddFP(SMLoc L) {
- int64_t Size;
- if (parseImmExpr(Size))
- return true;
- getTargetStreamer().EmitARM64WinCFIAddFP(Size);
- return false;
-}
-
-/// parseDirectiveSEHNop
-/// ::= .seh_nop
-bool AArch64AsmParser::parseDirectiveSEHNop(SMLoc L) {
- getTargetStreamer().EmitARM64WinCFINop();
- return false;
-}
-
-/// parseDirectiveSEHSaveNext
-/// ::= .seh_save_next
-bool AArch64AsmParser::parseDirectiveSEHSaveNext(SMLoc L) {
- getTargetStreamer().EmitARM64WinCFISaveNext();
- return false;
-}
-
-/// parseDirectiveSEHEpilogStart
-/// ::= .seh_startepilogue
-bool AArch64AsmParser::parseDirectiveSEHEpilogStart(SMLoc L) {
- getTargetStreamer().EmitARM64WinCFIEpilogStart();
- return false;
-}
-
-/// parseDirectiveSEHEpilogEnd
-/// ::= .seh_endepilogue
-bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
- getTargetStreamer().EmitARM64WinCFIEpilogEnd();
- return false;
-}
-
-/// parseDirectiveSEHTrapFrame
-/// ::= .seh_trap_frame
-bool AArch64AsmParser::parseDirectiveSEHTrapFrame(SMLoc L) {
- getTargetStreamer().EmitARM64WinCFITrapFrame();
- return false;
-}
-
-/// parseDirectiveSEHMachineFrame
-/// ::= .seh_pushframe
-bool AArch64AsmParser::parseDirectiveSEHMachineFrame(SMLoc L) {
- getTargetStreamer().EmitARM64WinCFIMachineFrame();
- return false;
-}
-
-/// parseDirectiveSEHContext
-/// ::= .seh_context
-bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
- getTargetStreamer().EmitARM64WinCFIContext();
- return false;
-}
-
-/// parseDirectiveSEHClearUnwoundToCall
-/// ::= .seh_clear_unwound_to_call
-bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
- getTargetStreamer().EmitARM64WinCFIClearUnwoundToCall();
- return false;
-}
-
+/// parseDirectiveSEHAllocStack
+/// ::= .seh_stackalloc
+bool AArch64AsmParser::parseDirectiveSEHAllocStack(SMLoc L) {
+ int64_t Size;
+ if (parseImmExpr(Size))
+ return true;
+ getTargetStreamer().EmitARM64WinCFIAllocStack(Size);
+ return false;
+}
+
+/// parseDirectiveSEHPrologEnd
+/// ::= .seh_endprologue
+bool AArch64AsmParser::parseDirectiveSEHPrologEnd(SMLoc L) {
+ getTargetStreamer().EmitARM64WinCFIPrologEnd();
+ return false;
+}
+
+/// parseDirectiveSEHSaveR19R20X
+/// ::= .seh_save_r19r20_x
+bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(SMLoc L) {
+ int64_t Offset;
+ if (parseImmExpr(Offset))
+ return true;
+ getTargetStreamer().EmitARM64WinCFISaveR19R20X(Offset);
+ return false;
+}
+
+/// parseDirectiveSEHSaveFPLR
+/// ::= .seh_save_fplr
+bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(SMLoc L) {
+ int64_t Offset;
+ if (parseImmExpr(Offset))
+ return true;
+ getTargetStreamer().EmitARM64WinCFISaveFPLR(Offset);
+ return false;
+}
+
+/// parseDirectiveSEHSaveFPLRX
+/// ::= .seh_save_fplr_x
+bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(SMLoc L) {
+ int64_t Offset;
+ if (parseImmExpr(Offset))
+ return true;
+ getTargetStreamer().EmitARM64WinCFISaveFPLRX(Offset);
+ return false;
+}
+
+/// parseDirectiveSEHSaveReg
+/// ::= .seh_save_reg
+bool AArch64AsmParser::parseDirectiveSEHSaveReg(SMLoc L) {
+ unsigned Reg;
+ int64_t Offset;
+ if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
+ parseComma() || parseImmExpr(Offset))
+ return true;
+ getTargetStreamer().EmitARM64WinCFISaveReg(Reg, Offset);
+ return false;
+}
+
+/// parseDirectiveSEHSaveRegX
+/// ::= .seh_save_reg_x
+bool AArch64AsmParser::parseDirectiveSEHSaveRegX(SMLoc L) {
+ unsigned Reg;
+ int64_t Offset;
+ if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
+ parseComma() || parseImmExpr(Offset))
+ return true;
+ getTargetStreamer().EmitARM64WinCFISaveRegX(Reg, Offset);
+ return false;
+}
+
+/// parseDirectiveSEHSaveRegP
+/// ::= .seh_save_regp
+bool AArch64AsmParser::parseDirectiveSEHSaveRegP(SMLoc L) {
+ unsigned Reg;
+ int64_t Offset;
+ if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
+ parseComma() || parseImmExpr(Offset))
+ return true;
+ getTargetStreamer().EmitARM64WinCFISaveRegP(Reg, Offset);
+ return false;
+}
+
+/// parseDirectiveSEHSaveRegPX
+/// ::= .seh_save_regp_x
+bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(SMLoc L) {
+ unsigned Reg;
+ int64_t Offset;
+ if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
+ parseComma() || parseImmExpr(Offset))
+ return true;
+ getTargetStreamer().EmitARM64WinCFISaveRegPX(Reg, Offset);
+ return false;
+}
+
+/// parseDirectiveSEHSaveLRPair
+/// ::= .seh_save_lrpair
+bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(SMLoc L) {
+ unsigned Reg;
+ int64_t Offset;
+ L = getLoc();
+ if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
+ parseComma() || parseImmExpr(Offset))
+ return true;
+ if (check(((Reg - 19) % 2 != 0), L,
+ "expected register with even offset from x19"))
+ return true;
+ getTargetStreamer().EmitARM64WinCFISaveLRPair(Reg, Offset);
+ return false;
+}
+
+/// parseDirectiveSEHSaveFReg
+/// ::= .seh_save_freg
+bool AArch64AsmParser::parseDirectiveSEHSaveFReg(SMLoc L) {
+ unsigned Reg;
+ int64_t Offset;
+ if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
+ parseComma() || parseImmExpr(Offset))
+ return true;
+ getTargetStreamer().EmitARM64WinCFISaveFReg(Reg, Offset);
+ return false;
+}
+
+/// parseDirectiveSEHSaveFRegX
+/// ::= .seh_save_freg_x
+bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(SMLoc L) {
+ unsigned Reg;
+ int64_t Offset;
+ if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
+ parseComma() || parseImmExpr(Offset))
+ return true;
+ getTargetStreamer().EmitARM64WinCFISaveFRegX(Reg, Offset);
+ return false;
+}
+
+/// parseDirectiveSEHSaveFRegP
+/// ::= .seh_save_fregp
+bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(SMLoc L) {
+ unsigned Reg;
+ int64_t Offset;
+ if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
+ parseComma() || parseImmExpr(Offset))
+ return true;
+ getTargetStreamer().EmitARM64WinCFISaveFRegP(Reg, Offset);
+ return false;
+}
+
+/// parseDirectiveSEHSaveFRegPX
+/// ::= .seh_save_fregp_x
+bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(SMLoc L) {
+ unsigned Reg;
+ int64_t Offset;
+ if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
+ parseComma() || parseImmExpr(Offset))
+ return true;
+ getTargetStreamer().EmitARM64WinCFISaveFRegPX(Reg, Offset);
+ return false;
+}
+
+/// parseDirectiveSEHSetFP
+/// ::= .seh_set_fp
+bool AArch64AsmParser::parseDirectiveSEHSetFP(SMLoc L) {
+ getTargetStreamer().EmitARM64WinCFISetFP();
+ return false;
+}
+
+/// parseDirectiveSEHAddFP
+/// ::= .seh_add_fp
+bool AArch64AsmParser::parseDirectiveSEHAddFP(SMLoc L) {
+ int64_t Size;
+ if (parseImmExpr(Size))
+ return true;
+ getTargetStreamer().EmitARM64WinCFIAddFP(Size);
+ return false;
+}
+
+/// parseDirectiveSEHNop
+/// ::= .seh_nop
+bool AArch64AsmParser::parseDirectiveSEHNop(SMLoc L) {
+ getTargetStreamer().EmitARM64WinCFINop();
+ return false;
+}
+
+/// parseDirectiveSEHSaveNext
+/// ::= .seh_save_next
+bool AArch64AsmParser::parseDirectiveSEHSaveNext(SMLoc L) {
+ getTargetStreamer().EmitARM64WinCFISaveNext();
+ return false;
+}
+
+/// parseDirectiveSEHEpilogStart
+/// ::= .seh_startepilogue
+bool AArch64AsmParser::parseDirectiveSEHEpilogStart(SMLoc L) {
+ getTargetStreamer().EmitARM64WinCFIEpilogStart();
+ return false;
+}
+
+/// parseDirectiveSEHEpilogEnd
+/// ::= .seh_endepilogue
+bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
+ getTargetStreamer().EmitARM64WinCFIEpilogEnd();
+ return false;
+}
+
+/// parseDirectiveSEHTrapFrame
+/// ::= .seh_trap_frame
+bool AArch64AsmParser::parseDirectiveSEHTrapFrame(SMLoc L) {
+ getTargetStreamer().EmitARM64WinCFITrapFrame();
+ return false;
+}
+
+/// parseDirectiveSEHMachineFrame
+/// ::= .seh_pushframe
+bool AArch64AsmParser::parseDirectiveSEHMachineFrame(SMLoc L) {
+ getTargetStreamer().EmitARM64WinCFIMachineFrame();
+ return false;
+}
+
+/// parseDirectiveSEHContext
+/// ::= .seh_context
+bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
+ getTargetStreamer().EmitARM64WinCFIContext();
+ return false;
+}
+
+/// parseDirectiveSEHClearUnwoundToCall
+/// ::= .seh_clear_unwound_to_call
+bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
+ getTargetStreamer().EmitARM64WinCFIClearUnwoundToCall();
+ return false;
+}
+
bool
AArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
AArch64MCExpr::VariantKind &ELFRefKind,
@@ -6323,26 +6323,26 @@ AArch64AsmParser::tryParseSVEPattern(OperandVector &Operands) {
return MatchOperand_Success;
}
-
-OperandMatchResultTy
-AArch64AsmParser::tryParseGPR64x8(OperandVector &Operands) {
- SMLoc SS = getLoc();
-
- unsigned XReg;
- if (tryParseScalarRegister(XReg) != MatchOperand_Success)
- return MatchOperand_NoMatch;
-
- MCContext &ctx = getContext();
- const MCRegisterInfo *RI = ctx.getRegisterInfo();
- int X8Reg = RI->getMatchingSuperReg(
- XReg, AArch64::x8sub_0,
- &AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID]);
- if (!X8Reg) {
- Error(SS, "expected an even-numbered x-register in the range [x0,x22]");
- return MatchOperand_ParseFail;
- }
-
- Operands.push_back(
- AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
- return MatchOperand_Success;
-}
+
+OperandMatchResultTy
+AArch64AsmParser::tryParseGPR64x8(OperandVector &Operands) {
+ SMLoc SS = getLoc();
+
+ unsigned XReg;
+ if (tryParseScalarRegister(XReg) != MatchOperand_Success)
+ return MatchOperand_NoMatch;
+
+ MCContext &ctx = getContext();
+ const MCRegisterInfo *RI = ctx.getRegisterInfo();
+ int X8Reg = RI->getMatchingSuperReg(
+ XReg, AArch64::x8sub_0,
+ &AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID]);
+ if (!X8Reg) {
+ Error(SS, "expected an even-numbered x-register in the range [x0,x22]");
+ return MatchOperand_ParseFail;
+ }
+
+ Operands.push_back(
+ AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
+ return MatchOperand_Success;
+}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/AsmParser/ya.make b/contrib/libs/llvm12/lib/Target/AArch64/AsmParser/ya.make
index c9421c4c06..512f510d85 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/AsmParser/ya.make
+++ b/contrib/libs/llvm12/lib/Target/AArch64/AsmParser/ya.make
@@ -12,20 +12,20 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/MC/MCParser
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc
- contrib/libs/llvm12/lib/Target/AArch64/TargetInfo
- contrib/libs/llvm12/lib/Target/AArch64/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/MC/MCParser
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/AArch64/TargetInfo
+ contrib/libs/llvm12/lib/Target/AArch64/Utils
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64
- contrib/libs/llvm12/lib/Target/AArch64
- contrib/libs/llvm12/lib/Target/AArch64/AsmParser
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64
+ contrib/libs/llvm12/lib/Target/AArch64
+ contrib/libs/llvm12/lib/Target/AArch64/AsmParser
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/contrib/libs/llvm12/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
index 72f9968681..dca76f8457 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
@@ -62,10 +62,10 @@ static DecodeStatus DecodeGPR64commonRegisterClass(MCInst &Inst, unsigned RegNo,
static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
-static DecodeStatus DecodeGPR64x8ClassRegisterClass(MCInst &Inst,
- unsigned RegNo,
- uint64_t Address,
- const void *Decoder);
+static DecodeStatus DecodeGPR64x8ClassRegisterClass(MCInst &Inst,
+ unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder);
static DecodeStatus DecodeGPR64spRegisterClass(MCInst &Inst,
unsigned RegNo, uint64_t Address,
const void *Decoder);
@@ -271,16 +271,16 @@ DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
uint32_t Insn =
(Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
- const uint8_t *Tables[] = {DecoderTable32, DecoderTableFallback32};
-
- for (auto Table : Tables) {
- DecodeStatus Result =
- decodeInstruction(Table, MI, Insn, Address, this, STI);
- if (Result != MCDisassembler::Fail)
- return Result;
- }
-
- return MCDisassembler::Fail;
+ const uint8_t *Tables[] = {DecoderTable32, DecoderTableFallback32};
+
+ for (auto Table : Tables) {
+ DecodeStatus Result =
+ decodeInstruction(Table, MI, Insn, Address, this, STI);
+ if (Result != MCDisassembler::Fail)
+ return Result;
+ }
+
+ return MCDisassembler::Fail;
}
static MCSymbolizer *
@@ -461,35 +461,35 @@ static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
return Success;
}
-static const unsigned GPR64x8DecoderTable[] = {
- AArch64::X0_X1_X2_X3_X4_X5_X6_X7,
- AArch64::X2_X3_X4_X5_X6_X7_X8_X9,
- AArch64::X4_X5_X6_X7_X8_X9_X10_X11,
- AArch64::X6_X7_X8_X9_X10_X11_X12_X13,
- AArch64::X8_X9_X10_X11_X12_X13_X14_X15,
- AArch64::X10_X11_X12_X13_X14_X15_X16_X17,
- AArch64::X12_X13_X14_X15_X16_X17_X18_X19,
- AArch64::X14_X15_X16_X17_X18_X19_X20_X21,
- AArch64::X16_X17_X18_X19_X20_X21_X22_X23,
- AArch64::X18_X19_X20_X21_X22_X23_X24_X25,
- AArch64::X20_X21_X22_X23_X24_X25_X26_X27,
- AArch64::X22_X23_X24_X25_X26_X27_X28_FP,
-};
-
-static DecodeStatus DecodeGPR64x8ClassRegisterClass(MCInst &Inst,
- unsigned RegNo,
- uint64_t Address,
- const void *Decoder) {
- if (RegNo > 22)
- return Fail;
- if (RegNo & 1)
- return Fail;
-
- unsigned Register = GPR64x8DecoderTable[RegNo >> 1];
- Inst.addOperand(MCOperand::createReg(Register));
- return Success;
-}
-
+static const unsigned GPR64x8DecoderTable[] = {
+ AArch64::X0_X1_X2_X3_X4_X5_X6_X7,
+ AArch64::X2_X3_X4_X5_X6_X7_X8_X9,
+ AArch64::X4_X5_X6_X7_X8_X9_X10_X11,
+ AArch64::X6_X7_X8_X9_X10_X11_X12_X13,
+ AArch64::X8_X9_X10_X11_X12_X13_X14_X15,
+ AArch64::X10_X11_X12_X13_X14_X15_X16_X17,
+ AArch64::X12_X13_X14_X15_X16_X17_X18_X19,
+ AArch64::X14_X15_X16_X17_X18_X19_X20_X21,
+ AArch64::X16_X17_X18_X19_X20_X21_X22_X23,
+ AArch64::X18_X19_X20_X21_X22_X23_X24_X25,
+ AArch64::X20_X21_X22_X23_X24_X25_X26_X27,
+ AArch64::X22_X23_X24_X25_X26_X27_X28_FP,
+};
+
+static DecodeStatus DecodeGPR64x8ClassRegisterClass(MCInst &Inst,
+ unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder) {
+ if (RegNo > 22)
+ return Fail;
+ if (RegNo & 1)
+ return Fail;
+
+ unsigned Register = GPR64x8DecoderTable[RegNo >> 1];
+ Inst.addOperand(MCOperand::createReg(Register));
+ return Success;
+}
+
static DecodeStatus DecodeGPR64spRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Addr,
const void *Decoder) {
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/Disassembler/ya.make b/contrib/libs/llvm12/lib/Target/AArch64/Disassembler/ya.make
index e4da353a77..096b55cd68 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/Disassembler/ya.make
+++ b/contrib/libs/llvm12/lib/Target/AArch64/Disassembler/ya.make
@@ -12,20 +12,20 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/MC/MCDisassembler
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc
- contrib/libs/llvm12/lib/Target/AArch64/TargetInfo
- contrib/libs/llvm12/lib/Target/AArch64/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/MC/MCDisassembler
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/AArch64/TargetInfo
+ contrib/libs/llvm12/lib/Target/AArch64/Utils
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64
- contrib/libs/llvm12/lib/Target/AArch64
- contrib/libs/llvm12/lib/Target/AArch64/Disassembler
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64
+ contrib/libs/llvm12/lib/Target/AArch64
+ contrib/libs/llvm12/lib/Target/AArch64/Disassembler
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64CallLowering.cpp b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
index 7b05f70a73..0f8b1d6584 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
@@ -52,10 +52,10 @@ AArch64CallLowering::AArch64CallLowering(const AArch64TargetLowering &TLI)
: CallLowering(&TLI) {}
namespace {
-struct IncomingArgHandler : public CallLowering::IncomingValueHandler {
+struct IncomingArgHandler : public CallLowering::IncomingValueHandler {
IncomingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
CCAssignFn *AssignFn)
- : IncomingValueHandler(MIRBuilder, MRI, AssignFn), StackUsed(0) {}
+ : IncomingValueHandler(MIRBuilder, MRI, AssignFn), StackUsed(0) {}
Register getStackAddress(uint64_t Size, int64_t Offset,
MachinePointerInfo &MPO) override {
@@ -101,7 +101,7 @@ struct IncomingArgHandler : public CallLowering::IncomingValueHandler {
/// How the physical register gets marked varies between formal
/// parameters (it's a basic-block live-in), and a call instruction
/// (it's an implicit-def of the BL).
- virtual void markPhysRegUsed(MCRegister PhysReg) = 0;
+ virtual void markPhysRegUsed(MCRegister PhysReg) = 0;
uint64_t StackUsed;
};
@@ -111,7 +111,7 @@ struct FormalArgHandler : public IncomingArgHandler {
CCAssignFn *AssignFn)
: IncomingArgHandler(MIRBuilder, MRI, AssignFn) {}
- void markPhysRegUsed(MCRegister PhysReg) override {
+ void markPhysRegUsed(MCRegister PhysReg) override {
MIRBuilder.getMRI()->addLiveIn(PhysReg);
MIRBuilder.getMBB().addLiveIn(PhysReg);
}
@@ -122,19 +122,19 @@ struct CallReturnHandler : public IncomingArgHandler {
MachineInstrBuilder MIB, CCAssignFn *AssignFn)
: IncomingArgHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
- void markPhysRegUsed(MCRegister PhysReg) override {
+ void markPhysRegUsed(MCRegister PhysReg) override {
MIB.addDef(PhysReg, RegState::Implicit);
}
MachineInstrBuilder MIB;
};
-struct OutgoingArgHandler : public CallLowering::OutgoingValueHandler {
+struct OutgoingArgHandler : public CallLowering::OutgoingValueHandler {
OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
MachineInstrBuilder MIB, CCAssignFn *AssignFn,
CCAssignFn *AssignFnVarArg, bool IsTailCall = false,
int FPDiff = 0)
- : OutgoingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB),
+ : OutgoingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB),
AssignFnVarArg(AssignFnVarArg), IsTailCall(IsTailCall), FPDiff(FPDiff),
StackSize(0), SPReg(0) {}
@@ -187,8 +187,8 @@ struct OutgoingArgHandler : public CallLowering::OutgoingValueHandler {
if (!Arg.IsFixed)
MaxSize = 0;
- assert(Arg.Regs.size() == 1);
-
+ assert(Arg.Regs.size() == 1);
+
Register ValVReg = VA.getLocInfo() != CCValAssign::LocInfo::FPExt
? extendRegister(Arg.Regs[0], VA, MaxSize)
: Arg.Regs[0];
@@ -274,7 +274,7 @@ void AArch64CallLowering::splitToValueTypes(
bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
const Value *Val,
ArrayRef<Register> VRegs,
- FunctionLoweringInfo &FLI,
+ FunctionLoweringInfo &FLI,
Register SwiftErrorVReg) const {
auto MIB = MIRBuilder.buildInstrNoInsert(AArch64::RET_ReallyLR);
assert(((Val && !VRegs.empty()) || (!Val && VRegs.empty())) &&
@@ -420,7 +420,7 @@ static void handleMustTailForwardedRegisters(MachineIRBuilder &MIRBuilder,
// Conservatively forward X8, since it might be used for an aggregate
// return.
if (!CCInfo.isAllocated(AArch64::X8)) {
- Register X8VReg = MF.addLiveIn(AArch64::X8, &AArch64::GPR64RegClass);
+ Register X8VReg = MF.addLiveIn(AArch64::X8, &AArch64::GPR64RegClass);
Forwards.push_back(ForwardedRegister(X8VReg, AArch64::X8, MVT::i64));
}
@@ -441,7 +441,7 @@ bool AArch64CallLowering::fallBackToDAGISel(const Function &F) const {
bool AArch64CallLowering::lowerFormalArguments(
MachineIRBuilder &MIRBuilder, const Function &F,
- ArrayRef<ArrayRef<Register>> VRegs, FunctionLoweringInfo &FLI) const {
+ ArrayRef<ArrayRef<Register>> VRegs, FunctionLoweringInfo &FLI) const {
MachineFunction &MF = MIRBuilder.getMF();
MachineBasicBlock &MBB = MIRBuilder.getMBB();
MachineRegisterInfo &MRI = MF.getRegInfo();
@@ -623,25 +623,25 @@ bool AArch64CallLowering::areCalleeOutgoingArgsTailCallable(
const uint32_t *CallerPreservedMask = TRI->getCallPreservedMask(MF, CallerCC);
MachineRegisterInfo &MRI = MF.getRegInfo();
- if (Info.IsVarArg) {
- // Be conservative and disallow variadic memory operands to match SDAG's
- // behaviour.
- // FIXME: If the caller's calling convention is C, then we can
- // potentially use its argument area. However, for cases like fastcc,
- // we can't do anything.
- for (unsigned i = 0; i < OutLocs.size(); ++i) {
- auto &ArgLoc = OutLocs[i];
- if (ArgLoc.isRegLoc())
- continue;
+ if (Info.IsVarArg) {
+ // Be conservative and disallow variadic memory operands to match SDAG's
+ // behaviour.
+ // FIXME: If the caller's calling convention is C, then we can
+ // potentially use its argument area. However, for cases like fastcc,
+ // we can't do anything.
+ for (unsigned i = 0; i < OutLocs.size(); ++i) {
+ auto &ArgLoc = OutLocs[i];
+ if (ArgLoc.isRegLoc())
+ continue;
LLVM_DEBUG(
dbgs()
- << "... Cannot tail call vararg function with stack arguments\n");
+ << "... Cannot tail call vararg function with stack arguments\n");
return false;
}
}
- return parametersInCSRMatch(MRI, CallerPreservedMask, OutLocs, OutArgs);
+ return parametersInCSRMatch(MRI, CallerPreservedMask, OutLocs, OutArgs);
}
bool AArch64CallLowering::isEligibleForTailCallOptimization(
@@ -756,7 +756,7 @@ static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect,
// When BTI is enabled, we need to use TCRETURNriBTI to make sure that we use
// x16 or x17.
- if (CallerF.getInfo<AArch64FunctionInfo>()->branchTargetEnforcement())
+ if (CallerF.getInfo<AArch64FunctionInfo>()->branchTargetEnforcement())
return AArch64::TCRETURNriBTI;
return AArch64::TCRETURNri;
@@ -776,7 +776,7 @@ bool AArch64CallLowering::lowerTailCall(
// TODO: Right now, regbankselect doesn't know how to handle the rtcGPR64
// register class. Until we can do that, we should fall back here.
- if (MF.getInfo<AArch64FunctionInfo>()->branchTargetEnforcement()) {
+ if (MF.getInfo<AArch64FunctionInfo>()->branchTargetEnforcement()) {
LLVM_DEBUG(
dbgs() << "Cannot lower indirect tail calls with BTI enabled yet.\n");
return false;
@@ -894,9 +894,9 @@ bool AArch64CallLowering::lowerTailCall(
// If Callee is a reg, since it is used by a target specific instruction,
// it must have a register class matching the constraint of that instruction.
if (Info.Callee.isReg())
- constrainOperandRegClass(MF, *TRI, MRI, *MF.getSubtarget().getInstrInfo(),
- *MF.getSubtarget().getRegBankInfo(), *MIB,
- MIB->getDesc(), Info.Callee, 0);
+ constrainOperandRegClass(MF, *TRI, MRI, *MF.getSubtarget().getInstrInfo(),
+ *MF.getSubtarget().getRegBankInfo(), *MIB,
+ MIB->getDesc(), Info.Callee, 0);
MF.getFrameInfo().setHasTailCall();
Info.LoweredTailCall = true;
@@ -978,9 +978,9 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
// instruction, it must have a register class matching the
// constraint of that instruction.
if (Info.Callee.isReg())
- constrainOperandRegClass(MF, *TRI, MRI, *MF.getSubtarget().getInstrInfo(),
- *MF.getSubtarget().getRegBankInfo(), *MIB,
- MIB->getDesc(), Info.Callee, 0);
+ constrainOperandRegClass(MF, *TRI, MRI, *MF.getSubtarget().getInstrInfo(),
+ *MF.getSubtarget().getRegBankInfo(), *MIB,
+ MIB->getDesc(), Info.Callee, 0);
// Finally we can copy the returned value back into its virtual-register. In
// symmetry with the arguments, the physical register must be an
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64CallLowering.h b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64CallLowering.h
index 8054cf6b99..1f45c9ebc0 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64CallLowering.h
+++ b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64CallLowering.h
@@ -34,14 +34,14 @@ public:
AArch64CallLowering(const AArch64TargetLowering &TLI);
bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
- ArrayRef<Register> VRegs, FunctionLoweringInfo &FLI,
+ ArrayRef<Register> VRegs, FunctionLoweringInfo &FLI,
Register SwiftErrorVReg) const override;
bool fallBackToDAGISel(const Function &F) const override;
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F,
- ArrayRef<ArrayRef<Register>> VRegs,
- FunctionLoweringInfo &FLI) const override;
+ ArrayRef<ArrayRef<Register>> VRegs,
+ FunctionLoweringInfo &FLI) const override;
bool lowerCall(MachineIRBuilder &MIRBuilder,
CallLoweringInfo &Info) const override;
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.h b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.h
index 9536f0a596..bed1136c7a 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.h
+++ b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.h
@@ -1,29 +1,29 @@
-//===- AArch64GlobalISelUtils.h ----------------------------------*- C++ -*-==//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-/// \file APIs for AArch64-specific helper functions used in the GlobalISel
-/// pipeline.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_TARGET_AARCH64_GISEL_AARCH64GLOBALISELUTILS_H
-#define LLVM_LIB_TARGET_AARCH64_GISEL_AARCH64GLOBALISELUTILS_H
-
-#include <cstdint>
-
-namespace llvm {
-namespace AArch64GISelUtils {
-
-/// \returns true if \p C is a legal immediate operand for an arithmetic
-/// instruction.
-constexpr bool isLegalArithImmed(const uint64_t C) {
- return (C >> 12 == 0) || ((C & 0xFFFULL) == 0 && C >> 24 == 0);
-}
-
-} // namespace AArch64GISelUtils
-} // namespace llvm
-
-#endif
+//===- AArch64GlobalISelUtils.h ----------------------------------*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file APIs for AArch64-specific helper functions used in the GlobalISel
+/// pipeline.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_AARCH64_GISEL_AARCH64GLOBALISELUTILS_H
+#define LLVM_LIB_TARGET_AARCH64_GISEL_AARCH64GLOBALISELUTILS_H
+
+#include <cstdint>
+
+namespace llvm {
+namespace AArch64GISelUtils {
+
+/// \returns true if \p C is a legal immediate operand for an arithmetic
+/// instruction.
+constexpr bool isLegalArithImmed(const uint64_t C) {
+ return (C >> 12 == 0) || ((C & 0xFFFULL) == 0 && C >> 24 == 0);
+}
+
+} // namespace AArch64GISelUtils
+} // namespace llvm
+
+#endif
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 72f92065f3..fc5ef02e84 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -18,7 +18,7 @@
#include "AArch64Subtarget.h"
#include "AArch64TargetMachine.h"
#include "MCTargetDesc/AArch64AddressingModes.h"
-#include "MCTargetDesc/AArch64MCTargetDesc.h"
+#include "MCTargetDesc/AArch64MCTargetDesc.h"
#include "llvm/ADT/Optional.h"
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
@@ -34,18 +34,18 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/IR/Constants.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/IntrinsicsAArch64.h"
-#include "llvm/Pass.h"
+#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#define DEBUG_TYPE "aarch64-isel"
using namespace llvm;
-using namespace MIPatternMatch;
+using namespace MIPatternMatch;
namespace {
@@ -103,23 +103,23 @@ private:
bool selectVaStartDarwin(MachineInstr &I, MachineFunction &MF,
MachineRegisterInfo &MRI) const;
- ///@{
- /// Helper functions for selectCompareBranch.
- bool selectCompareBranchFedByFCmp(MachineInstr &I, MachineInstr &FCmp,
- MachineIRBuilder &MIB) const;
- bool selectCompareBranchFedByICmp(MachineInstr &I, MachineInstr &ICmp,
- MachineIRBuilder &MIB) const;
- bool tryOptCompareBranchFedByICmp(MachineInstr &I, MachineInstr &ICmp,
- MachineIRBuilder &MIB) const;
- bool tryOptAndIntoCompareBranch(MachineInstr &AndInst, bool Invert,
+ ///@{
+ /// Helper functions for selectCompareBranch.
+ bool selectCompareBranchFedByFCmp(MachineInstr &I, MachineInstr &FCmp,
+ MachineIRBuilder &MIB) const;
+ bool selectCompareBranchFedByICmp(MachineInstr &I, MachineInstr &ICmp,
+ MachineIRBuilder &MIB) const;
+ bool tryOptCompareBranchFedByICmp(MachineInstr &I, MachineInstr &ICmp,
+ MachineIRBuilder &MIB) const;
+ bool tryOptAndIntoCompareBranch(MachineInstr &AndInst, bool Invert,
MachineBasicBlock *DstMBB,
MachineIRBuilder &MIB) const;
- ///@}
-
+ ///@}
+
bool selectCompareBranch(MachineInstr &I, MachineFunction &MF,
MachineRegisterInfo &MRI) const;
- bool selectVectorAshrLshr(MachineInstr &I, MachineRegisterInfo &MRI) const;
+ bool selectVectorAshrLshr(MachineInstr &I, MachineRegisterInfo &MRI) const;
bool selectVectorSHL(MachineInstr &I, MachineRegisterInfo &MRI) const;
// Helper to generate an equivalent of scalar_to_vector into a new register,
@@ -160,7 +160,7 @@ private:
bool selectJumpTable(MachineInstr &I, MachineRegisterInfo &MRI) const;
bool selectBrJT(MachineInstr &I, MachineRegisterInfo &MRI) const;
bool selectTLSGlobalValue(MachineInstr &I, MachineRegisterInfo &MRI) const;
- bool selectReduction(MachineInstr &I, MachineRegisterInfo &MRI) const;
+ bool selectReduction(MachineInstr &I, MachineRegisterInfo &MRI) const;
unsigned emitConstantPoolEntry(const Constant *CPVal,
MachineFunction &MF) const;
@@ -173,72 +173,72 @@ private:
MachineIRBuilder &MIRBuilder) const;
// Emit an integer compare between LHS and RHS, which checks for Predicate.
- MachineInstr *emitIntegerCompare(MachineOperand &LHS, MachineOperand &RHS,
- MachineOperand &Predicate,
- MachineIRBuilder &MIRBuilder) const;
-
- /// Emit a floating point comparison between \p LHS and \p RHS.
- /// \p Pred if given is the intended predicate to use.
- MachineInstr *emitFPCompare(Register LHS, Register RHS,
- MachineIRBuilder &MIRBuilder,
- Optional<CmpInst::Predicate> = None) const;
-
- MachineInstr *emitInstr(unsigned Opcode,
- std::initializer_list<llvm::DstOp> DstOps,
- std::initializer_list<llvm::SrcOp> SrcOps,
- MachineIRBuilder &MIRBuilder,
- const ComplexRendererFns &RenderFns = None) const;
- /// Helper function to emit an add or sub instruction.
- ///
- /// \p AddrModeAndSizeToOpcode must contain each of the opcode variants above
- /// in a specific order.
- ///
- /// Below is an example of the expected input to \p AddrModeAndSizeToOpcode.
- ///
- /// \code
- /// const std::array<std::array<unsigned, 2>, 4> Table {
- /// {{AArch64::ADDXri, AArch64::ADDWri},
- /// {AArch64::ADDXrs, AArch64::ADDWrs},
- /// {AArch64::ADDXrr, AArch64::ADDWrr},
- /// {AArch64::SUBXri, AArch64::SUBWri},
- /// {AArch64::ADDXrx, AArch64::ADDWrx}}};
- /// \endcode
- ///
- /// Each row in the table corresponds to a different addressing mode. Each
- /// column corresponds to a different register size.
- ///
- /// \attention Rows must be structured as follows:
- /// - Row 0: The ri opcode variants
- /// - Row 1: The rs opcode variants
- /// - Row 2: The rr opcode variants
- /// - Row 3: The ri opcode variants for negative immediates
- /// - Row 4: The rx opcode variants
- ///
- /// \attention Columns must be structured as follows:
- /// - Column 0: The 64-bit opcode variants
- /// - Column 1: The 32-bit opcode variants
- ///
- /// \p Dst is the destination register of the binop to emit.
- /// \p LHS is the left-hand operand of the binop to emit.
- /// \p RHS is the right-hand operand of the binop to emit.
- MachineInstr *emitAddSub(
- const std::array<std::array<unsigned, 2>, 5> &AddrModeAndSizeToOpcode,
- Register Dst, MachineOperand &LHS, MachineOperand &RHS,
- MachineIRBuilder &MIRBuilder) const;
- MachineInstr *emitADD(Register DefReg, MachineOperand &LHS,
- MachineOperand &RHS,
+ MachineInstr *emitIntegerCompare(MachineOperand &LHS, MachineOperand &RHS,
+ MachineOperand &Predicate,
+ MachineIRBuilder &MIRBuilder) const;
+
+ /// Emit a floating point comparison between \p LHS and \p RHS.
+ /// \p Pred if given is the intended predicate to use.
+ MachineInstr *emitFPCompare(Register LHS, Register RHS,
+ MachineIRBuilder &MIRBuilder,
+ Optional<CmpInst::Predicate> = None) const;
+
+ MachineInstr *emitInstr(unsigned Opcode,
+ std::initializer_list<llvm::DstOp> DstOps,
+ std::initializer_list<llvm::SrcOp> SrcOps,
+ MachineIRBuilder &MIRBuilder,
+ const ComplexRendererFns &RenderFns = None) const;
+ /// Helper function to emit an add or sub instruction.
+ ///
+ /// \p AddrModeAndSizeToOpcode must contain each of the opcode variants above
+ /// in a specific order.
+ ///
+ /// Below is an example of the expected input to \p AddrModeAndSizeToOpcode.
+ ///
+ /// \code
+ /// const std::array<std::array<unsigned, 2>, 4> Table {
+ /// {{AArch64::ADDXri, AArch64::ADDWri},
+ /// {AArch64::ADDXrs, AArch64::ADDWrs},
+ /// {AArch64::ADDXrr, AArch64::ADDWrr},
+ /// {AArch64::SUBXri, AArch64::SUBWri},
+ /// {AArch64::ADDXrx, AArch64::ADDWrx}}};
+ /// \endcode
+ ///
+ /// Each row in the table corresponds to a different addressing mode. Each
+ /// column corresponds to a different register size.
+ ///
+ /// \attention Rows must be structured as follows:
+ /// - Row 0: The ri opcode variants
+ /// - Row 1: The rs opcode variants
+ /// - Row 2: The rr opcode variants
+ /// - Row 3: The ri opcode variants for negative immediates
+ /// - Row 4: The rx opcode variants
+ ///
+ /// \attention Columns must be structured as follows:
+ /// - Column 0: The 64-bit opcode variants
+ /// - Column 1: The 32-bit opcode variants
+ ///
+ /// \p Dst is the destination register of the binop to emit.
+ /// \p LHS is the left-hand operand of the binop to emit.
+ /// \p RHS is the right-hand operand of the binop to emit.
+ MachineInstr *emitAddSub(
+ const std::array<std::array<unsigned, 2>, 5> &AddrModeAndSizeToOpcode,
+ Register Dst, MachineOperand &LHS, MachineOperand &RHS,
+ MachineIRBuilder &MIRBuilder) const;
+ MachineInstr *emitADD(Register DefReg, MachineOperand &LHS,
+ MachineOperand &RHS,
MachineIRBuilder &MIRBuilder) const;
- MachineInstr *emitADDS(Register Dst, MachineOperand &LHS, MachineOperand &RHS,
- MachineIRBuilder &MIRBuilder) const;
- MachineInstr *emitSUBS(Register Dst, MachineOperand &LHS, MachineOperand &RHS,
- MachineIRBuilder &MIRBuilder) const;
+ MachineInstr *emitADDS(Register Dst, MachineOperand &LHS, MachineOperand &RHS,
+ MachineIRBuilder &MIRBuilder) const;
+ MachineInstr *emitSUBS(Register Dst, MachineOperand &LHS, MachineOperand &RHS,
+ MachineIRBuilder &MIRBuilder) const;
MachineInstr *emitCMN(MachineOperand &LHS, MachineOperand &RHS,
MachineIRBuilder &MIRBuilder) const;
- MachineInstr *emitTST(MachineOperand &LHS, MachineOperand &RHS,
+ MachineInstr *emitTST(MachineOperand &LHS, MachineOperand &RHS,
MachineIRBuilder &MIRBuilder) const;
- MachineInstr *emitSelect(Register Dst, Register LHS, Register RHS,
- AArch64CC::CondCode CC,
- MachineIRBuilder &MIRBuilder) const;
+ MachineInstr *emitSelect(Register Dst, Register LHS, Register RHS,
+ AArch64CC::CondCode CC,
+ MachineIRBuilder &MIRBuilder) const;
MachineInstr *emitExtractVectorElt(Optional<Register> DstReg,
const RegisterBank &DstRB, LLT ScalarTy,
Register VecReg, unsigned LaneIdx,
@@ -250,25 +250,25 @@ private:
MachineInstr *emitFMovForFConstant(MachineInstr &MI,
MachineRegisterInfo &MRI) const;
- /// Emit a CSet for an integer compare.
- ///
- /// \p DefReg is expected to be a 32-bit scalar register.
+ /// Emit a CSet for an integer compare.
+ ///
+ /// \p DefReg is expected to be a 32-bit scalar register.
MachineInstr *emitCSetForICMP(Register DefReg, unsigned Pred,
MachineIRBuilder &MIRBuilder) const;
- /// Emit a CSet for a FP compare.
- ///
- /// \p Dst is expected to be a 32-bit scalar register.
- MachineInstr *emitCSetForFCmp(Register Dst, CmpInst::Predicate Pred,
- MachineIRBuilder &MIRBuilder) const;
-
- /// Emit the overflow op for \p Opcode.
- ///
- /// \p Opcode is expected to be an overflow op's opcode, e.g. G_UADDO,
- /// G_USUBO, etc.
- std::pair<MachineInstr *, AArch64CC::CondCode>
- emitOverflowOp(unsigned Opcode, Register Dst, MachineOperand &LHS,
- MachineOperand &RHS, MachineIRBuilder &MIRBuilder) const;
-
+ /// Emit a CSet for a FP compare.
+ ///
+ /// \p Dst is expected to be a 32-bit scalar register.
+ MachineInstr *emitCSetForFCmp(Register Dst, CmpInst::Predicate Pred,
+ MachineIRBuilder &MIRBuilder) const;
+
+ /// Emit the overflow op for \p Opcode.
+ ///
+ /// \p Opcode is expected to be an overflow op's opcode, e.g. G_UADDO,
+ /// G_USUBO, etc.
+ std::pair<MachineInstr *, AArch64CC::CondCode>
+ emitOverflowOp(unsigned Opcode, Register Dst, MachineOperand &LHS,
+ MachineOperand &RHS, MachineIRBuilder &MIRBuilder) const;
+
/// Emit a TB(N)Z instruction which tests \p Bit in \p TestReg.
/// \p IsNegative is true if the test should be "not zero".
/// This will also optimize the test bit instruction when possible.
@@ -276,11 +276,11 @@ private:
MachineBasicBlock *DstMBB,
MachineIRBuilder &MIB) const;
- /// Emit a CB(N)Z instruction which branches to \p DestMBB.
- MachineInstr *emitCBZ(Register CompareReg, bool IsNegative,
- MachineBasicBlock *DestMBB,
- MachineIRBuilder &MIB) const;
-
+ /// Emit a CB(N)Z instruction which branches to \p DestMBB.
+ MachineInstr *emitCBZ(Register CompareReg, bool IsNegative,
+ MachineBasicBlock *DestMBB,
+ MachineIRBuilder &MIB) const;
+
// Equivalent to the i32shift_a and friends from AArch64InstrInfo.td.
// We use these manually instead of using the importer since it doesn't
// support SDNodeXForm.
@@ -577,7 +577,7 @@ static Optional<uint64_t> getImmedFromMO(const MachineOperand &Root) {
getConstantVRegValWithLookThrough(Root.getReg(), MRI, true);
if (!ValAndVReg)
return None;
- Immed = ValAndVReg->Value.getSExtValue();
+ Immed = ValAndVReg->Value.getSExtValue();
} else
return None;
return Immed;
@@ -865,7 +865,7 @@ static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
#ifndef NDEBUG
ValidCopy = KnownValid || isValidCopy(I, DstRegBank, MRI, TRI, RBI);
assert(ValidCopy && "Invalid copy.");
- (void)KnownValid;
+ (void)KnownValid;
#endif
return ValidCopy;
};
@@ -1012,173 +1012,173 @@ static unsigned selectFPConvOpc(unsigned GenericOpc, LLT DstTy, LLT SrcTy) {
return GenericOpc;
}
-MachineInstr *
-AArch64InstructionSelector::emitSelect(Register Dst, Register True,
- Register False, AArch64CC::CondCode CC,
- MachineIRBuilder &MIB) const {
- MachineRegisterInfo &MRI = *MIB.getMRI();
- assert(RBI.getRegBank(False, MRI, TRI)->getID() ==
- RBI.getRegBank(True, MRI, TRI)->getID() &&
- "Expected both select operands to have the same regbank?");
- LLT Ty = MRI.getType(True);
- if (Ty.isVector())
- return nullptr;
- const unsigned Size = Ty.getSizeInBits();
- assert((Size == 32 || Size == 64) &&
- "Expected 32 bit or 64 bit select only?");
- const bool Is32Bit = Size == 32;
- if (RBI.getRegBank(True, MRI, TRI)->getID() != AArch64::GPRRegBankID) {
- unsigned Opc = Is32Bit ? AArch64::FCSELSrrr : AArch64::FCSELDrrr;
- auto FCSel = MIB.buildInstr(Opc, {Dst}, {True, False}).addImm(CC);
- constrainSelectedInstRegOperands(*FCSel, TII, TRI, RBI);
- return &*FCSel;
- }
-
- // By default, we'll try and emit a CSEL.
- unsigned Opc = Is32Bit ? AArch64::CSELWr : AArch64::CSELXr;
- bool Optimized = false;
- auto TryFoldBinOpIntoSelect = [&Opc, Is32Bit, &CC, &MRI,
- &Optimized](Register &Reg, Register &OtherReg,
- bool Invert) {
- if (Optimized)
- return false;
-
- // Attempt to fold:
- //
- // %sub = G_SUB 0, %x
- // %select = G_SELECT cc, %reg, %sub
- //
- // Into:
- // %select = CSNEG %reg, %x, cc
- Register MatchReg;
- if (mi_match(Reg, MRI, m_Neg(m_Reg(MatchReg)))) {
- Opc = Is32Bit ? AArch64::CSNEGWr : AArch64::CSNEGXr;
- Reg = MatchReg;
- if (Invert) {
- CC = AArch64CC::getInvertedCondCode(CC);
- std::swap(Reg, OtherReg);
- }
- return true;
- }
-
- // Attempt to fold:
- //
- // %xor = G_XOR %x, -1
- // %select = G_SELECT cc, %reg, %xor
- //
- // Into:
- // %select = CSINV %reg, %x, cc
- if (mi_match(Reg, MRI, m_Not(m_Reg(MatchReg)))) {
- Opc = Is32Bit ? AArch64::CSINVWr : AArch64::CSINVXr;
- Reg = MatchReg;
- if (Invert) {
- CC = AArch64CC::getInvertedCondCode(CC);
- std::swap(Reg, OtherReg);
- }
- return true;
- }
-
- // Attempt to fold:
- //
- // %add = G_ADD %x, 1
- // %select = G_SELECT cc, %reg, %add
- //
- // Into:
- // %select = CSINC %reg, %x, cc
- if (mi_match(Reg, MRI, m_GAdd(m_Reg(MatchReg), m_SpecificICst(1)))) {
- Opc = Is32Bit ? AArch64::CSINCWr : AArch64::CSINCXr;
- Reg = MatchReg;
- if (Invert) {
- CC = AArch64CC::getInvertedCondCode(CC);
- std::swap(Reg, OtherReg);
- }
- return true;
- }
-
+MachineInstr *
+AArch64InstructionSelector::emitSelect(Register Dst, Register True,
+ Register False, AArch64CC::CondCode CC,
+ MachineIRBuilder &MIB) const {
+ MachineRegisterInfo &MRI = *MIB.getMRI();
+ assert(RBI.getRegBank(False, MRI, TRI)->getID() ==
+ RBI.getRegBank(True, MRI, TRI)->getID() &&
+ "Expected both select operands to have the same regbank?");
+ LLT Ty = MRI.getType(True);
+ if (Ty.isVector())
+ return nullptr;
+ const unsigned Size = Ty.getSizeInBits();
+ assert((Size == 32 || Size == 64) &&
+ "Expected 32 bit or 64 bit select only?");
+ const bool Is32Bit = Size == 32;
+ if (RBI.getRegBank(True, MRI, TRI)->getID() != AArch64::GPRRegBankID) {
+ unsigned Opc = Is32Bit ? AArch64::FCSELSrrr : AArch64::FCSELDrrr;
+ auto FCSel = MIB.buildInstr(Opc, {Dst}, {True, False}).addImm(CC);
+ constrainSelectedInstRegOperands(*FCSel, TII, TRI, RBI);
+ return &*FCSel;
+ }
+
+ // By default, we'll try and emit a CSEL.
+ unsigned Opc = Is32Bit ? AArch64::CSELWr : AArch64::CSELXr;
+ bool Optimized = false;
+ auto TryFoldBinOpIntoSelect = [&Opc, Is32Bit, &CC, &MRI,
+ &Optimized](Register &Reg, Register &OtherReg,
+ bool Invert) {
+ if (Optimized)
+ return false;
+
+ // Attempt to fold:
+ //
+ // %sub = G_SUB 0, %x
+ // %select = G_SELECT cc, %reg, %sub
+ //
+ // Into:
+ // %select = CSNEG %reg, %x, cc
+ Register MatchReg;
+ if (mi_match(Reg, MRI, m_Neg(m_Reg(MatchReg)))) {
+ Opc = Is32Bit ? AArch64::CSNEGWr : AArch64::CSNEGXr;
+ Reg = MatchReg;
+ if (Invert) {
+ CC = AArch64CC::getInvertedCondCode(CC);
+ std::swap(Reg, OtherReg);
+ }
+ return true;
+ }
+
+ // Attempt to fold:
+ //
+ // %xor = G_XOR %x, -1
+ // %select = G_SELECT cc, %reg, %xor
+ //
+ // Into:
+ // %select = CSINV %reg, %x, cc
+ if (mi_match(Reg, MRI, m_Not(m_Reg(MatchReg)))) {
+ Opc = Is32Bit ? AArch64::CSINVWr : AArch64::CSINVXr;
+ Reg = MatchReg;
+ if (Invert) {
+ CC = AArch64CC::getInvertedCondCode(CC);
+ std::swap(Reg, OtherReg);
+ }
+ return true;
+ }
+
+ // Attempt to fold:
+ //
+ // %add = G_ADD %x, 1
+ // %select = G_SELECT cc, %reg, %add
+ //
+ // Into:
+ // %select = CSINC %reg, %x, cc
+ if (mi_match(Reg, MRI, m_GAdd(m_Reg(MatchReg), m_SpecificICst(1)))) {
+ Opc = Is32Bit ? AArch64::CSINCWr : AArch64::CSINCXr;
+ Reg = MatchReg;
+ if (Invert) {
+ CC = AArch64CC::getInvertedCondCode(CC);
+ std::swap(Reg, OtherReg);
+ }
+ return true;
+ }
+
return false;
- };
-
- // Helper lambda which tries to use CSINC/CSINV for the instruction when its
- // true/false values are constants.
- // FIXME: All of these patterns already exist in tablegen. We should be
- // able to import these.
- auto TryOptSelectCst = [&Opc, &True, &False, &CC, Is32Bit, &MRI,
- &Optimized]() {
- if (Optimized)
- return false;
- auto TrueCst = getConstantVRegValWithLookThrough(True, MRI);
- auto FalseCst = getConstantVRegValWithLookThrough(False, MRI);
- if (!TrueCst && !FalseCst)
- return false;
-
- Register ZReg = Is32Bit ? AArch64::WZR : AArch64::XZR;
- if (TrueCst && FalseCst) {
- int64_t T = TrueCst->Value.getSExtValue();
- int64_t F = FalseCst->Value.getSExtValue();
-
- if (T == 0 && F == 1) {
- // G_SELECT cc, 0, 1 -> CSINC zreg, zreg, cc
- Opc = Is32Bit ? AArch64::CSINCWr : AArch64::CSINCXr;
- True = ZReg;
- False = ZReg;
- return true;
- }
-
- if (T == 0 && F == -1) {
- // G_SELECT cc 0, -1 -> CSINV zreg, zreg cc
- Opc = Is32Bit ? AArch64::CSINVWr : AArch64::CSINVXr;
- True = ZReg;
- False = ZReg;
- return true;
- }
- }
-
- if (TrueCst) {
- int64_t T = TrueCst->Value.getSExtValue();
- if (T == 1) {
- // G_SELECT cc, 1, f -> CSINC f, zreg, inv_cc
- Opc = Is32Bit ? AArch64::CSINCWr : AArch64::CSINCXr;
- True = False;
- False = ZReg;
- CC = AArch64CC::getInvertedCondCode(CC);
- return true;
- }
-
- if (T == -1) {
- // G_SELECT cc, -1, f -> CSINV f, zreg, inv_cc
- Opc = Is32Bit ? AArch64::CSINVWr : AArch64::CSINVXr;
- True = False;
- False = ZReg;
- CC = AArch64CC::getInvertedCondCode(CC);
- return true;
- }
- }
-
- if (FalseCst) {
- int64_t F = FalseCst->Value.getSExtValue();
- if (F == 1) {
- // G_SELECT cc, t, 1 -> CSINC t, zreg, cc
- Opc = Is32Bit ? AArch64::CSINCWr : AArch64::CSINCXr;
- False = ZReg;
- return true;
- }
-
- if (F == -1) {
- // G_SELECT cc, t, -1 -> CSINC t, zreg, cc
- Opc = Is32Bit ? AArch64::CSINVWr : AArch64::CSINVXr;
- False = ZReg;
- return true;
- }
- }
- return false;
- };
-
- Optimized |= TryFoldBinOpIntoSelect(False, True, /*Invert = */ false);
- Optimized |= TryFoldBinOpIntoSelect(True, False, /*Invert = */ true);
- Optimized |= TryOptSelectCst();
- auto SelectInst = MIB.buildInstr(Opc, {Dst}, {True, False}).addImm(CC);
- constrainSelectedInstRegOperands(*SelectInst, TII, TRI, RBI);
- return &*SelectInst;
+ };
+
+ // Helper lambda which tries to use CSINC/CSINV for the instruction when its
+ // true/false values are constants.
+ // FIXME: All of these patterns already exist in tablegen. We should be
+ // able to import these.
+ auto TryOptSelectCst = [&Opc, &True, &False, &CC, Is32Bit, &MRI,
+ &Optimized]() {
+ if (Optimized)
+ return false;
+ auto TrueCst = getConstantVRegValWithLookThrough(True, MRI);
+ auto FalseCst = getConstantVRegValWithLookThrough(False, MRI);
+ if (!TrueCst && !FalseCst)
+ return false;
+
+ Register ZReg = Is32Bit ? AArch64::WZR : AArch64::XZR;
+ if (TrueCst && FalseCst) {
+ int64_t T = TrueCst->Value.getSExtValue();
+ int64_t F = FalseCst->Value.getSExtValue();
+
+ if (T == 0 && F == 1) {
+ // G_SELECT cc, 0, 1 -> CSINC zreg, zreg, cc
+ Opc = Is32Bit ? AArch64::CSINCWr : AArch64::CSINCXr;
+ True = ZReg;
+ False = ZReg;
+ return true;
+ }
+
+ if (T == 0 && F == -1) {
+ // G_SELECT cc 0, -1 -> CSINV zreg, zreg cc
+ Opc = Is32Bit ? AArch64::CSINVWr : AArch64::CSINVXr;
+ True = ZReg;
+ False = ZReg;
+ return true;
+ }
+ }
+
+ if (TrueCst) {
+ int64_t T = TrueCst->Value.getSExtValue();
+ if (T == 1) {
+ // G_SELECT cc, 1, f -> CSINC f, zreg, inv_cc
+ Opc = Is32Bit ? AArch64::CSINCWr : AArch64::CSINCXr;
+ True = False;
+ False = ZReg;
+ CC = AArch64CC::getInvertedCondCode(CC);
+ return true;
+ }
+
+ if (T == -1) {
+ // G_SELECT cc, -1, f -> CSINV f, zreg, inv_cc
+ Opc = Is32Bit ? AArch64::CSINVWr : AArch64::CSINVXr;
+ True = False;
+ False = ZReg;
+ CC = AArch64CC::getInvertedCondCode(CC);
+ return true;
+ }
+ }
+
+ if (FalseCst) {
+ int64_t F = FalseCst->Value.getSExtValue();
+ if (F == 1) {
+ // G_SELECT cc, t, 1 -> CSINC t, zreg, cc
+ Opc = Is32Bit ? AArch64::CSINCWr : AArch64::CSINCXr;
+ False = ZReg;
+ return true;
+ }
+
+ if (F == -1) {
+ // G_SELECT cc, t, -1 -> CSINC t, zreg, cc
+ Opc = Is32Bit ? AArch64::CSINVWr : AArch64::CSINVXr;
+ False = ZReg;
+ return true;
+ }
+ }
+ return false;
+ };
+
+ Optimized |= TryFoldBinOpIntoSelect(False, True, /*Invert = */ false);
+ Optimized |= TryFoldBinOpIntoSelect(True, False, /*Invert = */ true);
+ Optimized |= TryOptSelectCst();
+ auto SelectInst = MIB.buildInstr(Opc, {Dst}, {True, False}).addImm(CC);
+ constrainSelectedInstRegOperands(*SelectInst, TII, TRI, RBI);
+ return &*SelectInst;
}
static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P) {
@@ -1308,7 +1308,7 @@ static Register getTestBitReg(Register Reg, uint64_t &Bit, bool &Invert,
VRegAndVal = getConstantVRegValWithLookThrough(ConstantReg, MRI);
}
if (VRegAndVal)
- C = VRegAndVal->Value.getSExtValue();
+ C = VRegAndVal->Value.getSExtValue();
break;
}
case TargetOpcode::G_ASHR:
@@ -1318,7 +1318,7 @@ static Register getTestBitReg(Register Reg, uint64_t &Bit, bool &Invert,
auto VRegAndVal =
getConstantVRegValWithLookThrough(MI->getOperand(2).getReg(), MRI);
if (VRegAndVal)
- C = VRegAndVal->Value.getSExtValue();
+ C = VRegAndVal->Value.getSExtValue();
break;
}
}
@@ -1420,9 +1420,9 @@ MachineInstr *AArch64InstructionSelector::emitTestBit(
}
bool AArch64InstructionSelector::tryOptAndIntoCompareBranch(
- MachineInstr &AndInst, bool Invert, MachineBasicBlock *DstMBB,
- MachineIRBuilder &MIB) const {
- assert(AndInst.getOpcode() == TargetOpcode::G_AND && "Expected G_AND only?");
+ MachineInstr &AndInst, bool Invert, MachineBasicBlock *DstMBB,
+ MachineIRBuilder &MIB) const {
+ assert(AndInst.getOpcode() == TargetOpcode::G_AND && "Expected G_AND only?");
// Given something like this:
//
// %x = ...Something...
@@ -1444,92 +1444,92 @@ bool AArch64InstructionSelector::tryOptAndIntoCompareBranch(
// Check if the AND has a constant on its RHS which we can use as a mask.
// If it's a power of 2, then it's the same as checking a specific bit.
// (e.g, ANDing with 8 == ANDing with 000...100 == testing if bit 3 is set)
- auto MaybeBit = getConstantVRegValWithLookThrough(
- AndInst.getOperand(2).getReg(), *MIB.getMRI());
- if (!MaybeBit)
+ auto MaybeBit = getConstantVRegValWithLookThrough(
+ AndInst.getOperand(2).getReg(), *MIB.getMRI());
+ if (!MaybeBit)
return false;
- int32_t Bit = MaybeBit->Value.exactLogBase2();
- if (Bit < 0)
- return false;
+ int32_t Bit = MaybeBit->Value.exactLogBase2();
+ if (Bit < 0)
+ return false;
+
+ Register TestReg = AndInst.getOperand(1).getReg();
- Register TestReg = AndInst.getOperand(1).getReg();
-
// Emit a TB(N)Z.
emitTestBit(TestReg, Bit, Invert, DstMBB, MIB);
return true;
}
-MachineInstr *AArch64InstructionSelector::emitCBZ(Register CompareReg,
- bool IsNegative,
- MachineBasicBlock *DestMBB,
- MachineIRBuilder &MIB) const {
- assert(ProduceNonFlagSettingCondBr && "CBZ does not set flags!");
- MachineRegisterInfo &MRI = *MIB.getMRI();
- assert(RBI.getRegBank(CompareReg, MRI, TRI)->getID() ==
- AArch64::GPRRegBankID &&
- "Expected GPRs only?");
- auto Ty = MRI.getType(CompareReg);
- unsigned Width = Ty.getSizeInBits();
- assert(!Ty.isVector() && "Expected scalar only?");
- assert(Width <= 64 && "Expected width to be at most 64?");
- static const unsigned OpcTable[2][2] = {{AArch64::CBZW, AArch64::CBZX},
- {AArch64::CBNZW, AArch64::CBNZX}};
- unsigned Opc = OpcTable[IsNegative][Width == 64];
- auto BranchMI = MIB.buildInstr(Opc, {}, {CompareReg}).addMBB(DestMBB);
- constrainSelectedInstRegOperands(*BranchMI, TII, TRI, RBI);
- return &*BranchMI;
-}
-
-bool AArch64InstructionSelector::selectCompareBranchFedByFCmp(
- MachineInstr &I, MachineInstr &FCmp, MachineIRBuilder &MIB) const {
- assert(FCmp.getOpcode() == TargetOpcode::G_FCMP);
- assert(I.getOpcode() == TargetOpcode::G_BRCOND);
- // Unfortunately, the mapping of LLVM FP CC's onto AArch64 CC's isn't
- // totally clean. Some of them require two branches to implement.
- auto Pred = (CmpInst::Predicate)FCmp.getOperand(1).getPredicate();
- emitFPCompare(FCmp.getOperand(2).getReg(), FCmp.getOperand(3).getReg(), MIB,
- Pred);
- AArch64CC::CondCode CC1, CC2;
- changeFCMPPredToAArch64CC(static_cast<CmpInst::Predicate>(Pred), CC1, CC2);
+MachineInstr *AArch64InstructionSelector::emitCBZ(Register CompareReg,
+ bool IsNegative,
+ MachineBasicBlock *DestMBB,
+ MachineIRBuilder &MIB) const {
+ assert(ProduceNonFlagSettingCondBr && "CBZ does not set flags!");
+ MachineRegisterInfo &MRI = *MIB.getMRI();
+ assert(RBI.getRegBank(CompareReg, MRI, TRI)->getID() ==
+ AArch64::GPRRegBankID &&
+ "Expected GPRs only?");
+ auto Ty = MRI.getType(CompareReg);
+ unsigned Width = Ty.getSizeInBits();
+ assert(!Ty.isVector() && "Expected scalar only?");
+ assert(Width <= 64 && "Expected width to be at most 64?");
+ static const unsigned OpcTable[2][2] = {{AArch64::CBZW, AArch64::CBZX},
+ {AArch64::CBNZW, AArch64::CBNZX}};
+ unsigned Opc = OpcTable[IsNegative][Width == 64];
+ auto BranchMI = MIB.buildInstr(Opc, {}, {CompareReg}).addMBB(DestMBB);
+ constrainSelectedInstRegOperands(*BranchMI, TII, TRI, RBI);
+ return &*BranchMI;
+}
+
+bool AArch64InstructionSelector::selectCompareBranchFedByFCmp(
+ MachineInstr &I, MachineInstr &FCmp, MachineIRBuilder &MIB) const {
+ assert(FCmp.getOpcode() == TargetOpcode::G_FCMP);
+ assert(I.getOpcode() == TargetOpcode::G_BRCOND);
+ // Unfortunately, the mapping of LLVM FP CC's onto AArch64 CC's isn't
+ // totally clean. Some of them require two branches to implement.
+ auto Pred = (CmpInst::Predicate)FCmp.getOperand(1).getPredicate();
+ emitFPCompare(FCmp.getOperand(2).getReg(), FCmp.getOperand(3).getReg(), MIB,
+ Pred);
+ AArch64CC::CondCode CC1, CC2;
+ changeFCMPPredToAArch64CC(static_cast<CmpInst::Predicate>(Pred), CC1, CC2);
MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
- MIB.buildInstr(AArch64::Bcc, {}, {}).addImm(CC1).addMBB(DestMBB);
- if (CC2 != AArch64CC::AL)
- MIB.buildInstr(AArch64::Bcc, {}, {}).addImm(CC2).addMBB(DestMBB);
- I.eraseFromParent();
- return true;
-}
-
-bool AArch64InstructionSelector::tryOptCompareBranchFedByICmp(
- MachineInstr &I, MachineInstr &ICmp, MachineIRBuilder &MIB) const {
- assert(ICmp.getOpcode() == TargetOpcode::G_ICMP);
- assert(I.getOpcode() == TargetOpcode::G_BRCOND);
- // Attempt to optimize the G_BRCOND + G_ICMP into a TB(N)Z/CB(N)Z.
- //
- // Speculation tracking/SLH assumes that optimized TB(N)Z/CB(N)Z
- // instructions will not be produced, as they are conditional branch
- // instructions that do not set flags.
- if (!ProduceNonFlagSettingCondBr)
+ MIB.buildInstr(AArch64::Bcc, {}, {}).addImm(CC1).addMBB(DestMBB);
+ if (CC2 != AArch64CC::AL)
+ MIB.buildInstr(AArch64::Bcc, {}, {}).addImm(CC2).addMBB(DestMBB);
+ I.eraseFromParent();
+ return true;
+}
+
+bool AArch64InstructionSelector::tryOptCompareBranchFedByICmp(
+ MachineInstr &I, MachineInstr &ICmp, MachineIRBuilder &MIB) const {
+ assert(ICmp.getOpcode() == TargetOpcode::G_ICMP);
+ assert(I.getOpcode() == TargetOpcode::G_BRCOND);
+ // Attempt to optimize the G_BRCOND + G_ICMP into a TB(N)Z/CB(N)Z.
+ //
+ // Speculation tracking/SLH assumes that optimized TB(N)Z/CB(N)Z
+ // instructions will not be produced, as they are conditional branch
+ // instructions that do not set flags.
+ if (!ProduceNonFlagSettingCondBr)
return false;
- MachineRegisterInfo &MRI = *MIB.getMRI();
- MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
- auto Pred =
- static_cast<CmpInst::Predicate>(ICmp.getOperand(1).getPredicate());
- Register LHS = ICmp.getOperand(2).getReg();
- Register RHS = ICmp.getOperand(3).getReg();
-
- // We're allowed to emit a TB(N)Z/CB(N)Z. Try to do that.
+ MachineRegisterInfo &MRI = *MIB.getMRI();
+ MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
+ auto Pred =
+ static_cast<CmpInst::Predicate>(ICmp.getOperand(1).getPredicate());
+ Register LHS = ICmp.getOperand(2).getReg();
+ Register RHS = ICmp.getOperand(3).getReg();
+
+ // We're allowed to emit a TB(N)Z/CB(N)Z. Try to do that.
auto VRegAndVal = getConstantVRegValWithLookThrough(RHS, MRI);
- MachineInstr *AndInst = getOpcodeDef(TargetOpcode::G_AND, LHS, MRI);
+ MachineInstr *AndInst = getOpcodeDef(TargetOpcode::G_AND, LHS, MRI);
// When we can emit a TB(N)Z, prefer that.
//
// Handle non-commutative condition codes first.
// Note that we don't want to do this when we have a G_AND because it can
// become a tst. The tst will make the test bit in the TB(N)Z redundant.
- if (VRegAndVal && !AndInst) {
- int64_t C = VRegAndVal->Value.getSExtValue();
+ if (VRegAndVal && !AndInst) {
+ int64_t C = VRegAndVal->Value.getSExtValue();
// When we have a greater-than comparison, we can just test if the msb is
// zero.
@@ -1550,97 +1550,97 @@ bool AArch64InstructionSelector::tryOptCompareBranchFedByICmp(
}
}
- // Attempt to handle commutative condition codes. Right now, that's only
- // eq/ne.
- if (ICmpInst::isEquality(Pred)) {
- if (!VRegAndVal) {
- std::swap(RHS, LHS);
- VRegAndVal = getConstantVRegValWithLookThrough(RHS, MRI);
- AndInst = getOpcodeDef(TargetOpcode::G_AND, LHS, MRI);
- }
-
- if (VRegAndVal && VRegAndVal->Value == 0) {
- // If there's a G_AND feeding into this branch, try to fold it away by
- // emitting a TB(N)Z instead.
- //
- // Note: If we have LT, then it *is* possible to fold, but it wouldn't be
- // beneficial. When we have an AND and LT, we need a TST/ANDS, so folding
- // would be redundant.
- if (AndInst &&
- tryOptAndIntoCompareBranch(
- *AndInst, /*Invert = */ Pred == CmpInst::ICMP_NE, DestMBB, MIB)) {
- I.eraseFromParent();
- return true;
- }
-
- // Otherwise, try to emit a CB(N)Z instead.
- auto LHSTy = MRI.getType(LHS);
- if (!LHSTy.isVector() && LHSTy.getSizeInBits() <= 64) {
- emitCBZ(LHS, /*IsNegative = */ Pred == CmpInst::ICMP_NE, DestMBB, MIB);
- I.eraseFromParent();
- return true;
- }
- }
- }
-
- return false;
-}
-
-bool AArch64InstructionSelector::selectCompareBranchFedByICmp(
- MachineInstr &I, MachineInstr &ICmp, MachineIRBuilder &MIB) const {
- assert(ICmp.getOpcode() == TargetOpcode::G_ICMP);
- assert(I.getOpcode() == TargetOpcode::G_BRCOND);
- if (tryOptCompareBranchFedByICmp(I, ICmp, MIB))
+ // Attempt to handle commutative condition codes. Right now, that's only
+ // eq/ne.
+ if (ICmpInst::isEquality(Pred)) {
+ if (!VRegAndVal) {
+ std::swap(RHS, LHS);
+ VRegAndVal = getConstantVRegValWithLookThrough(RHS, MRI);
+ AndInst = getOpcodeDef(TargetOpcode::G_AND, LHS, MRI);
+ }
+
+ if (VRegAndVal && VRegAndVal->Value == 0) {
+ // If there's a G_AND feeding into this branch, try to fold it away by
+ // emitting a TB(N)Z instead.
+ //
+ // Note: If we have LT, then it *is* possible to fold, but it wouldn't be
+ // beneficial. When we have an AND and LT, we need a TST/ANDS, so folding
+ // would be redundant.
+ if (AndInst &&
+ tryOptAndIntoCompareBranch(
+ *AndInst, /*Invert = */ Pred == CmpInst::ICMP_NE, DestMBB, MIB)) {
+ I.eraseFromParent();
+ return true;
+ }
+
+ // Otherwise, try to emit a CB(N)Z instead.
+ auto LHSTy = MRI.getType(LHS);
+ if (!LHSTy.isVector() && LHSTy.getSizeInBits() <= 64) {
+ emitCBZ(LHS, /*IsNegative = */ Pred == CmpInst::ICMP_NE, DestMBB, MIB);
+ I.eraseFromParent();
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool AArch64InstructionSelector::selectCompareBranchFedByICmp(
+ MachineInstr &I, MachineInstr &ICmp, MachineIRBuilder &MIB) const {
+ assert(ICmp.getOpcode() == TargetOpcode::G_ICMP);
+ assert(I.getOpcode() == TargetOpcode::G_BRCOND);
+ if (tryOptCompareBranchFedByICmp(I, ICmp, MIB))
return true;
-
- // Couldn't optimize. Emit a compare + a Bcc.
- MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
- auto PredOp = ICmp.getOperand(1);
- emitIntegerCompare(ICmp.getOperand(2), ICmp.getOperand(3), PredOp, MIB);
- const AArch64CC::CondCode CC = changeICMPPredToAArch64CC(
- static_cast<CmpInst::Predicate>(PredOp.getPredicate()));
- MIB.buildInstr(AArch64::Bcc, {}, {}).addImm(CC).addMBB(DestMBB);
- I.eraseFromParent();
- return true;
-}
-
-bool AArch64InstructionSelector::selectCompareBranch(
- MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
- Register CondReg = I.getOperand(0).getReg();
- MachineInstr *CCMI = MRI.getVRegDef(CondReg);
- if (CCMI->getOpcode() == TargetOpcode::G_TRUNC) {
- CondReg = CCMI->getOperand(1).getReg();
- CCMI = MRI.getVRegDef(CondReg);
- }
-
- // Try to select the G_BRCOND using whatever is feeding the condition if
- // possible.
- MachineIRBuilder MIB(I);
- unsigned CCMIOpc = CCMI->getOpcode();
- if (CCMIOpc == TargetOpcode::G_FCMP)
- return selectCompareBranchFedByFCmp(I, *CCMI, MIB);
- if (CCMIOpc == TargetOpcode::G_ICMP)
- return selectCompareBranchFedByICmp(I, *CCMI, MIB);
-
- // Speculation tracking/SLH assumes that optimized TB(N)Z/CB(N)Z
- // instructions will not be produced, as they are conditional branch
- // instructions that do not set flags.
- if (ProduceNonFlagSettingCondBr) {
- emitTestBit(CondReg, /*Bit = */ 0, /*IsNegative = */ true,
- I.getOperand(1).getMBB(), MIB);
+
+ // Couldn't optimize. Emit a compare + a Bcc.
+ MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
+ auto PredOp = ICmp.getOperand(1);
+ emitIntegerCompare(ICmp.getOperand(2), ICmp.getOperand(3), PredOp, MIB);
+ const AArch64CC::CondCode CC = changeICMPPredToAArch64CC(
+ static_cast<CmpInst::Predicate>(PredOp.getPredicate()));
+ MIB.buildInstr(AArch64::Bcc, {}, {}).addImm(CC).addMBB(DestMBB);
+ I.eraseFromParent();
+ return true;
+}
+
+bool AArch64InstructionSelector::selectCompareBranch(
+ MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
+ Register CondReg = I.getOperand(0).getReg();
+ MachineInstr *CCMI = MRI.getVRegDef(CondReg);
+ if (CCMI->getOpcode() == TargetOpcode::G_TRUNC) {
+ CondReg = CCMI->getOperand(1).getReg();
+ CCMI = MRI.getVRegDef(CondReg);
+ }
+
+ // Try to select the G_BRCOND using whatever is feeding the condition if
+ // possible.
+ MachineIRBuilder MIB(I);
+ unsigned CCMIOpc = CCMI->getOpcode();
+ if (CCMIOpc == TargetOpcode::G_FCMP)
+ return selectCompareBranchFedByFCmp(I, *CCMI, MIB);
+ if (CCMIOpc == TargetOpcode::G_ICMP)
+ return selectCompareBranchFedByICmp(I, *CCMI, MIB);
+
+ // Speculation tracking/SLH assumes that optimized TB(N)Z/CB(N)Z
+ // instructions will not be produced, as they are conditional branch
+ // instructions that do not set flags.
+ if (ProduceNonFlagSettingCondBr) {
+ emitTestBit(CondReg, /*Bit = */ 0, /*IsNegative = */ true,
+ I.getOperand(1).getMBB(), MIB);
I.eraseFromParent();
return true;
}
- // Can't emit TB(N)Z/CB(N)Z. Emit a tst + bcc instead.
- auto TstMI =
- MIB.buildInstr(AArch64::ANDSWri, {LLT::scalar(32)}, {CondReg}).addImm(1);
- constrainSelectedInstRegOperands(*TstMI, TII, TRI, RBI);
- auto Bcc = MIB.buildInstr(AArch64::Bcc)
- .addImm(AArch64CC::EQ)
- .addMBB(I.getOperand(1).getMBB());
+ // Can't emit TB(N)Z/CB(N)Z. Emit a tst + bcc instead.
+ auto TstMI =
+ MIB.buildInstr(AArch64::ANDSWri, {LLT::scalar(32)}, {CondReg}).addImm(1);
+ constrainSelectedInstRegOperands(*TstMI, TII, TRI, RBI);
+ auto Bcc = MIB.buildInstr(AArch64::Bcc)
+ .addImm(AArch64CC::EQ)
+ .addMBB(I.getOperand(1).getMBB());
I.eraseFromParent();
- return constrainSelectedInstRegOperands(*Bcc, TII, TRI, RBI);
+ return constrainSelectedInstRegOperands(*Bcc, TII, TRI, RBI);
}
/// Returns the element immediate value of a vector shift operand if found.
@@ -1661,8 +1661,8 @@ static Optional<int64_t> getVectorShiftImm(Register Reg,
return None;
if (Idx == 1)
- ImmVal = VRegAndVal->Value.getSExtValue();
- if (ImmVal != VRegAndVal->Value.getSExtValue())
+ ImmVal = VRegAndVal->Value.getSExtValue();
+ if (ImmVal != VRegAndVal->Value.getSExtValue())
return None;
}
@@ -1725,14 +1725,14 @@ bool AArch64InstructionSelector::selectVectorSHL(
Opc = ImmVal ? AArch64::SHLv4i32_shift : AArch64::USHLv4i32;
} else if (Ty == LLT::vector(2, 32)) {
Opc = ImmVal ? AArch64::SHLv2i32_shift : AArch64::USHLv2i32;
- } else if (Ty == LLT::vector(4, 16)) {
- Opc = ImmVal ? AArch64::SHLv4i16_shift : AArch64::USHLv4i16;
- } else if (Ty == LLT::vector(8, 16)) {
- Opc = ImmVal ? AArch64::SHLv8i16_shift : AArch64::USHLv8i16;
- } else if (Ty == LLT::vector(16, 8)) {
- Opc = ImmVal ? AArch64::SHLv16i8_shift : AArch64::USHLv16i8;
- } else if (Ty == LLT::vector(8, 8)) {
- Opc = ImmVal ? AArch64::SHLv8i8_shift : AArch64::USHLv8i8;
+ } else if (Ty == LLT::vector(4, 16)) {
+ Opc = ImmVal ? AArch64::SHLv4i16_shift : AArch64::USHLv4i16;
+ } else if (Ty == LLT::vector(8, 16)) {
+ Opc = ImmVal ? AArch64::SHLv8i16_shift : AArch64::USHLv8i16;
+ } else if (Ty == LLT::vector(16, 8)) {
+ Opc = ImmVal ? AArch64::SHLv16i8_shift : AArch64::USHLv16i8;
+ } else if (Ty == LLT::vector(8, 8)) {
+ Opc = ImmVal ? AArch64::SHLv8i8_shift : AArch64::USHLv8i8;
} else {
LLVM_DEBUG(dbgs() << "Unhandled G_SHL type");
return false;
@@ -1749,10 +1749,10 @@ bool AArch64InstructionSelector::selectVectorSHL(
return true;
}
-bool AArch64InstructionSelector::selectVectorAshrLshr(
+bool AArch64InstructionSelector::selectVectorAshrLshr(
MachineInstr &I, MachineRegisterInfo &MRI) const {
- assert(I.getOpcode() == TargetOpcode::G_ASHR ||
- I.getOpcode() == TargetOpcode::G_LSHR);
+ assert(I.getOpcode() == TargetOpcode::G_ASHR ||
+ I.getOpcode() == TargetOpcode::G_LSHR);
Register DstReg = I.getOperand(0).getReg();
const LLT Ty = MRI.getType(DstReg);
Register Src1Reg = I.getOperand(1).getReg();
@@ -1761,40 +1761,40 @@ bool AArch64InstructionSelector::selectVectorAshrLshr(
if (!Ty.isVector())
return false;
- bool IsASHR = I.getOpcode() == TargetOpcode::G_ASHR;
-
- // We expect the immediate case to be lowered in the PostLegalCombiner to
- // AArch64ISD::VASHR or AArch64ISD::VLSHR equivalents.
-
+ bool IsASHR = I.getOpcode() == TargetOpcode::G_ASHR;
+
+ // We expect the immediate case to be lowered in the PostLegalCombiner to
+ // AArch64ISD::VASHR or AArch64ISD::VLSHR equivalents.
+
// There is not a shift right register instruction, but the shift left
// register instruction takes a signed value, where negative numbers specify a
// right shift.
unsigned Opc = 0;
unsigned NegOpc = 0;
- const TargetRegisterClass *RC =
- getRegClassForTypeOnBank(Ty, RBI.getRegBank(AArch64::FPRRegBankID), RBI);
+ const TargetRegisterClass *RC =
+ getRegClassForTypeOnBank(Ty, RBI.getRegBank(AArch64::FPRRegBankID), RBI);
if (Ty == LLT::vector(2, 64)) {
- Opc = IsASHR ? AArch64::SSHLv2i64 : AArch64::USHLv2i64;
+ Opc = IsASHR ? AArch64::SSHLv2i64 : AArch64::USHLv2i64;
NegOpc = AArch64::NEGv2i64;
} else if (Ty == LLT::vector(4, 32)) {
- Opc = IsASHR ? AArch64::SSHLv4i32 : AArch64::USHLv4i32;
+ Opc = IsASHR ? AArch64::SSHLv4i32 : AArch64::USHLv4i32;
NegOpc = AArch64::NEGv4i32;
} else if (Ty == LLT::vector(2, 32)) {
- Opc = IsASHR ? AArch64::SSHLv2i32 : AArch64::USHLv2i32;
+ Opc = IsASHR ? AArch64::SSHLv2i32 : AArch64::USHLv2i32;
NegOpc = AArch64::NEGv2i32;
- } else if (Ty == LLT::vector(4, 16)) {
- Opc = IsASHR ? AArch64::SSHLv4i16 : AArch64::USHLv4i16;
- NegOpc = AArch64::NEGv4i16;
- } else if (Ty == LLT::vector(8, 16)) {
- Opc = IsASHR ? AArch64::SSHLv8i16 : AArch64::USHLv8i16;
- NegOpc = AArch64::NEGv8i16;
- } else if (Ty == LLT::vector(16, 8)) {
- Opc = IsASHR ? AArch64::SSHLv16i8 : AArch64::USHLv16i8;
- NegOpc = AArch64::NEGv16i8;
- } else if (Ty == LLT::vector(8, 8)) {
- Opc = IsASHR ? AArch64::SSHLv8i8 : AArch64::USHLv8i8;
- NegOpc = AArch64::NEGv8i8;
+ } else if (Ty == LLT::vector(4, 16)) {
+ Opc = IsASHR ? AArch64::SSHLv4i16 : AArch64::USHLv4i16;
+ NegOpc = AArch64::NEGv4i16;
+ } else if (Ty == LLT::vector(8, 16)) {
+ Opc = IsASHR ? AArch64::SSHLv8i16 : AArch64::USHLv8i16;
+ NegOpc = AArch64::NEGv8i16;
+ } else if (Ty == LLT::vector(16, 8)) {
+ Opc = IsASHR ? AArch64::SSHLv16i8 : AArch64::USHLv16i8;
+ NegOpc = AArch64::NEGv16i8;
+ } else if (Ty == LLT::vector(8, 8)) {
+ Opc = IsASHR ? AArch64::SSHLv8i8 : AArch64::USHLv8i8;
+ NegOpc = AArch64::NEGv8i8;
} else {
LLVM_DEBUG(dbgs() << "Unhandled G_ASHR type");
return false;
@@ -1931,40 +1931,40 @@ bool AArch64InstructionSelector::preISelLower(MachineInstr &I) {
MRI.setType(DstReg, LLT::scalar(64));
return true;
}
- case AArch64::G_DUP: {
- // Convert the type from p0 to s64 to help selection.
- LLT DstTy = MRI.getType(I.getOperand(0).getReg());
- if (!DstTy.getElementType().isPointer())
- return false;
- MachineIRBuilder MIB(I);
- auto NewSrc = MIB.buildCopy(LLT::scalar(64), I.getOperand(1).getReg());
- MRI.setType(I.getOperand(0).getReg(),
- DstTy.changeElementType(LLT::scalar(64)));
- MRI.setRegBank(NewSrc.getReg(0), RBI.getRegBank(AArch64::GPRRegBankID));
- I.getOperand(1).setReg(NewSrc.getReg(0));
- return true;
- }
- case TargetOpcode::G_UITOFP:
- case TargetOpcode::G_SITOFP: {
- // If both source and destination regbanks are FPR, then convert the opcode
- // to G_SITOF so that the importer can select it to an fpr variant.
- // Otherwise, it ends up matching an fpr/gpr variant and adding a cross-bank
- // copy.
- Register SrcReg = I.getOperand(1).getReg();
- LLT SrcTy = MRI.getType(SrcReg);
- LLT DstTy = MRI.getType(I.getOperand(0).getReg());
- if (SrcTy.isVector() || SrcTy.getSizeInBits() != DstTy.getSizeInBits())
- return false;
-
- if (RBI.getRegBank(SrcReg, MRI, TRI)->getID() == AArch64::FPRRegBankID) {
- if (I.getOpcode() == TargetOpcode::G_SITOFP)
- I.setDesc(TII.get(AArch64::G_SITOF));
- else
- I.setDesc(TII.get(AArch64::G_UITOF));
- return true;
- }
- return false;
- }
+ case AArch64::G_DUP: {
+ // Convert the type from p0 to s64 to help selection.
+ LLT DstTy = MRI.getType(I.getOperand(0).getReg());
+ if (!DstTy.getElementType().isPointer())
+ return false;
+ MachineIRBuilder MIB(I);
+ auto NewSrc = MIB.buildCopy(LLT::scalar(64), I.getOperand(1).getReg());
+ MRI.setType(I.getOperand(0).getReg(),
+ DstTy.changeElementType(LLT::scalar(64)));
+ MRI.setRegBank(NewSrc.getReg(0), RBI.getRegBank(AArch64::GPRRegBankID));
+ I.getOperand(1).setReg(NewSrc.getReg(0));
+ return true;
+ }
+ case TargetOpcode::G_UITOFP:
+ case TargetOpcode::G_SITOFP: {
+ // If both source and destination regbanks are FPR, then convert the opcode
+ // to G_SITOF so that the importer can select it to an fpr variant.
+ // Otherwise, it ends up matching an fpr/gpr variant and adding a cross-bank
+ // copy.
+ Register SrcReg = I.getOperand(1).getReg();
+ LLT SrcTy = MRI.getType(SrcReg);
+ LLT DstTy = MRI.getType(I.getOperand(0).getReg());
+ if (SrcTy.isVector() || SrcTy.getSizeInBits() != DstTy.getSizeInBits())
+ return false;
+
+ if (RBI.getRegBank(SrcReg, MRI, TRI)->getID() == AArch64::FPRRegBankID) {
+ if (I.getOpcode() == TargetOpcode::G_SITOFP)
+ I.setDesc(TII.get(AArch64::G_SITOF));
+ else
+ I.setDesc(TII.get(AArch64::G_UITOF));
+ return true;
+ }
+ return false;
+ }
default:
return false;
}
@@ -2005,14 +2005,14 @@ bool AArch64InstructionSelector::convertPtrAddToAdd(
LLVM_DEBUG(dbgs() << "Failed to select G_PTRTOINT in convertPtrAddToAdd");
return false;
}
-
- // Also take the opportunity here to try to do some optimization.
- // Try to convert this into a G_SUB if the offset is a 0-x negate idiom.
- Register NegatedReg;
- if (!mi_match(I.getOperand(2).getReg(), MRI, m_Neg(m_Reg(NegatedReg))))
- return true;
- I.getOperand(2).setReg(NegatedReg);
- I.setDesc(TII.get(TargetOpcode::G_SUB));
+
+ // Also take the opportunity here to try to do some optimization.
+ // Try to convert this into a G_SUB if the offset is a 0-x negate idiom.
+ Register NegatedReg;
+ if (!mi_match(I.getOperand(2).getReg(), MRI, m_Neg(m_Reg(NegatedReg))))
+ return true;
+ I.getOperand(2).setReg(NegatedReg);
+ I.setDesc(TII.get(TargetOpcode::G_SUB));
return true;
}
@@ -2102,17 +2102,17 @@ bool AArch64InstructionSelector::earlySelect(MachineInstr &I) const {
MachineRegisterInfo &MRI = MF.getRegInfo();
switch (I.getOpcode()) {
- case TargetOpcode::G_BR: {
- // If the branch jumps to the fallthrough block, don't bother emitting it.
- // Only do this for -O0 for a good code size improvement, because when
- // optimizations are enabled we want to leave this choice to
- // MachineBlockPlacement.
- bool EnableOpt = MF.getTarget().getOptLevel() != CodeGenOpt::None;
- if (EnableOpt || !MBB.isLayoutSuccessor(I.getOperand(0).getMBB()))
- return false;
- I.eraseFromParent();
- return true;
- }
+ case TargetOpcode::G_BR: {
+ // If the branch jumps to the fallthrough block, don't bother emitting it.
+ // Only do this for -O0 for a good code size improvement, because when
+ // optimizations are enabled we want to leave this choice to
+ // MachineBlockPlacement.
+ bool EnableOpt = MF.getTarget().getOptLevel() != CodeGenOpt::None;
+ if (EnableOpt || !MBB.isLayoutSuccessor(I.getOperand(0).getMBB()))
+ return false;
+ I.eraseFromParent();
+ return true;
+ }
case TargetOpcode::G_SHL:
return earlySelectSHL(I, MRI);
case TargetOpcode::G_CONSTANT: {
@@ -2232,8 +2232,8 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
MachineIRBuilder MIB(I);
switch (Opcode) {
- case TargetOpcode::G_BRCOND:
- return selectCompareBranch(I, MF, MRI);
+ case TargetOpcode::G_BRCOND:
+ return selectCompareBranch(I, MF, MRI);
case TargetOpcode::G_BRINDIRECT: {
I.setDesc(TII.get(AArch64::BR));
@@ -2313,7 +2313,7 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
const LLT s16 = LLT::scalar(16);
const LLT s32 = LLT::scalar(32);
const LLT s64 = LLT::scalar(64);
- const LLT s128 = LLT::scalar(128);
+ const LLT s128 = LLT::scalar(128);
const LLT p0 = LLT::pointer(0, 64);
const Register DefReg = I.getOperand(0).getReg();
@@ -2323,10 +2323,10 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
// FIXME: Redundant check, but even less readable when factored out.
if (isFP) {
- if (Ty != s32 && Ty != s64 && Ty != s128) {
+ if (Ty != s32 && Ty != s64 && Ty != s128) {
LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
<< " constant, expected: " << s32 << " or " << s64
- << " or " << s128 << '\n');
+ << " or " << s128 << '\n');
return false;
}
@@ -2339,9 +2339,9 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
// The case when we have 0.0 is covered by tablegen. Reject it here so we
// can be sure tablegen works correctly and isn't rescued by this code.
- // 0.0 is not covered by tablegen for FP128. So we will handle this
- // scenario in the code here.
- if (DefSize != 128 && I.getOperand(1).getFPImm()->isExactlyValue(0.0))
+ // 0.0 is not covered by tablegen for FP128. So we will handle this
+ // scenario in the code here.
+ if (DefSize != 128 && I.getOperand(1).getFPImm()->isExactlyValue(0.0))
return false;
} else {
// s32 and s64 are covered by tablegen.
@@ -2368,17 +2368,17 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
// Either emit a FMOV, or emit a copy to emit a normal mov.
const TargetRegisterClass &GPRRC =
DefSize == 32 ? AArch64::GPR32RegClass : AArch64::GPR64RegClass;
- const TargetRegisterClass &FPRRC =
- DefSize == 32 ? AArch64::FPR32RegClass
- : (DefSize == 64 ? AArch64::FPR64RegClass
- : AArch64::FPR128RegClass);
+ const TargetRegisterClass &FPRRC =
+ DefSize == 32 ? AArch64::FPR32RegClass
+ : (DefSize == 64 ? AArch64::FPR64RegClass
+ : AArch64::FPR128RegClass);
// Can we use a FMOV instruction to represent the immediate?
if (emitFMovForFConstant(I, MRI))
return true;
// For 64b values, emit a constant pool load instead.
- if (DefSize == 64 || DefSize == 128) {
+ if (DefSize == 64 || DefSize == 128) {
auto *FPImm = I.getOperand(1).getFPImm();
MachineIRBuilder MIB(I);
auto *LoadMI = emitLoadFromConstantPool(FPImm, MIB);
@@ -2571,21 +2571,21 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
}
auto &MemOp = **I.memoperands_begin();
- uint64_t MemSizeInBytes = MemOp.getSize();
+ uint64_t MemSizeInBytes = MemOp.getSize();
if (MemOp.isAtomic()) {
// For now we just support s8 acquire loads to be able to compile stack
// protector code.
if (MemOp.getOrdering() == AtomicOrdering::Acquire &&
- MemSizeInBytes == 1) {
+ MemSizeInBytes == 1) {
I.setDesc(TII.get(AArch64::LDARB));
return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
}
LLVM_DEBUG(dbgs() << "Atomic load/store not fully supported yet\n");
return false;
}
- unsigned MemSizeInBits = MemSizeInBytes * 8;
+ unsigned MemSizeInBits = MemSizeInBytes * 8;
-#ifndef NDEBUG
+#ifndef NDEBUG
const Register PtrReg = I.getOperand(1).getReg();
const RegisterBank &PtrRB = *RBI.getRegBank(PtrReg, MRI, TRI);
// Sanity-check the pointer register.
@@ -2598,78 +2598,78 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
const Register ValReg = I.getOperand(0).getReg();
const RegisterBank &RB = *RBI.getRegBank(ValReg, MRI, TRI);
- // Helper lambda for partially selecting I. Either returns the original
- // instruction with an updated opcode, or a new instruction.
- auto SelectLoadStoreAddressingMode = [&]() -> MachineInstr * {
- bool IsStore = I.getOpcode() == TargetOpcode::G_STORE;
- const unsigned NewOpc =
- selectLoadStoreUIOp(I.getOpcode(), RB.getID(), MemSizeInBits);
- if (NewOpc == I.getOpcode())
- return nullptr;
- // Check if we can fold anything into the addressing mode.
- auto AddrModeFns =
- selectAddrModeIndexed(I.getOperand(1), MemSizeInBytes);
- if (!AddrModeFns) {
- // Can't fold anything. Use the original instruction.
- I.setDesc(TII.get(NewOpc));
- I.addOperand(MachineOperand::CreateImm(0));
- return &I;
+ // Helper lambda for partially selecting I. Either returns the original
+ // instruction with an updated opcode, or a new instruction.
+ auto SelectLoadStoreAddressingMode = [&]() -> MachineInstr * {
+ bool IsStore = I.getOpcode() == TargetOpcode::G_STORE;
+ const unsigned NewOpc =
+ selectLoadStoreUIOp(I.getOpcode(), RB.getID(), MemSizeInBits);
+ if (NewOpc == I.getOpcode())
+ return nullptr;
+ // Check if we can fold anything into the addressing mode.
+ auto AddrModeFns =
+ selectAddrModeIndexed(I.getOperand(1), MemSizeInBytes);
+ if (!AddrModeFns) {
+ // Can't fold anything. Use the original instruction.
+ I.setDesc(TII.get(NewOpc));
+ I.addOperand(MachineOperand::CreateImm(0));
+ return &I;
}
- // Folded something. Create a new instruction and return it.
- auto NewInst = MIB.buildInstr(NewOpc, {}, {}, I.getFlags());
- IsStore ? NewInst.addUse(ValReg) : NewInst.addDef(ValReg);
- NewInst.cloneMemRefs(I);
- for (auto &Fn : *AddrModeFns)
- Fn(NewInst);
- I.eraseFromParent();
- return &*NewInst;
- };
+ // Folded something. Create a new instruction and return it.
+ auto NewInst = MIB.buildInstr(NewOpc, {}, {}, I.getFlags());
+ IsStore ? NewInst.addUse(ValReg) : NewInst.addDef(ValReg);
+ NewInst.cloneMemRefs(I);
+ for (auto &Fn : *AddrModeFns)
+ Fn(NewInst);
+ I.eraseFromParent();
+ return &*NewInst;
+ };
- MachineInstr *LoadStore = SelectLoadStoreAddressingMode();
- if (!LoadStore)
- return false;
+ MachineInstr *LoadStore = SelectLoadStoreAddressingMode();
+ if (!LoadStore)
+ return false;
// If we're storing a 0, use WZR/XZR.
- if (Opcode == TargetOpcode::G_STORE) {
- auto CVal = getConstantVRegValWithLookThrough(
- LoadStore->getOperand(0).getReg(), MRI, /*LookThroughInstrs = */ true,
- /*HandleFConstants = */ false);
- if (CVal && CVal->Value == 0) {
- switch (LoadStore->getOpcode()) {
- case AArch64::STRWui:
- case AArch64::STRHHui:
- case AArch64::STRBBui:
- LoadStore->getOperand(0).setReg(AArch64::WZR);
- break;
- case AArch64::STRXui:
- LoadStore->getOperand(0).setReg(AArch64::XZR);
- break;
- }
+ if (Opcode == TargetOpcode::G_STORE) {
+ auto CVal = getConstantVRegValWithLookThrough(
+ LoadStore->getOperand(0).getReg(), MRI, /*LookThroughInstrs = */ true,
+ /*HandleFConstants = */ false);
+ if (CVal && CVal->Value == 0) {
+ switch (LoadStore->getOpcode()) {
+ case AArch64::STRWui:
+ case AArch64::STRHHui:
+ case AArch64::STRBBui:
+ LoadStore->getOperand(0).setReg(AArch64::WZR);
+ break;
+ case AArch64::STRXui:
+ LoadStore->getOperand(0).setReg(AArch64::XZR);
+ break;
+ }
}
}
if (IsZExtLoad) {
- // The zextload from a smaller type to i32 should be handled by the
- // importer.
- if (MRI.getType(LoadStore->getOperand(0).getReg()).getSizeInBits() != 64)
+ // The zextload from a smaller type to i32 should be handled by the
+ // importer.
+ if (MRI.getType(LoadStore->getOperand(0).getReg()).getSizeInBits() != 64)
return false;
// If we have a ZEXTLOAD then change the load's type to be a narrower reg
- // and zero_extend with SUBREG_TO_REG.
+ // and zero_extend with SUBREG_TO_REG.
Register LdReg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
- Register DstReg = LoadStore->getOperand(0).getReg();
- LoadStore->getOperand(0).setReg(LdReg);
+ Register DstReg = LoadStore->getOperand(0).getReg();
+ LoadStore->getOperand(0).setReg(LdReg);
- MIB.setInsertPt(MIB.getMBB(), std::next(LoadStore->getIterator()));
+ MIB.setInsertPt(MIB.getMBB(), std::next(LoadStore->getIterator()));
MIB.buildInstr(AArch64::SUBREG_TO_REG, {DstReg}, {})
.addImm(0)
.addUse(LdReg)
.addImm(AArch64::sub_32);
- constrainSelectedInstRegOperands(*LoadStore, TII, TRI, RBI);
+ constrainSelectedInstRegOperands(*LoadStore, TII, TRI, RBI);
return RBI.constrainGenericRegister(DstReg, AArch64::GPR64allRegClass,
MRI);
}
- return constrainSelectedInstRegOperands(*LoadStore, TII, TRI, RBI);
+ return constrainSelectedInstRegOperands(*LoadStore, TII, TRI, RBI);
}
case TargetOpcode::G_SMULH:
@@ -2700,21 +2700,21 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
// operands to use appropriate classes.
return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
}
- case TargetOpcode::G_LSHR:
+ case TargetOpcode::G_LSHR:
case TargetOpcode::G_ASHR:
if (MRI.getType(I.getOperand(0).getReg()).isVector())
- return selectVectorAshrLshr(I, MRI);
+ return selectVectorAshrLshr(I, MRI);
LLVM_FALLTHROUGH;
case TargetOpcode::G_SHL:
if (Opcode == TargetOpcode::G_SHL &&
MRI.getType(I.getOperand(0).getReg()).isVector())
return selectVectorSHL(I, MRI);
LLVM_FALLTHROUGH;
- case TargetOpcode::G_FADD:
- case TargetOpcode::G_FSUB:
- case TargetOpcode::G_FMUL:
- case TargetOpcode::G_FDIV:
- case TargetOpcode::G_OR: {
+ case TargetOpcode::G_FADD:
+ case TargetOpcode::G_FSUB:
+ case TargetOpcode::G_FMUL:
+ case TargetOpcode::G_FDIV:
+ case TargetOpcode::G_OR: {
// Reject the various things we don't support yet.
if (unsupportedBinOp(I, RBI, MRI, TRI))
return false;
@@ -2743,24 +2743,24 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
I.eraseFromParent();
return true;
}
- case TargetOpcode::G_SADDO:
- case TargetOpcode::G_UADDO:
- case TargetOpcode::G_SSUBO:
- case TargetOpcode::G_USUBO: {
- // Emit the operation and get the correct condition code.
+ case TargetOpcode::G_SADDO:
+ case TargetOpcode::G_UADDO:
+ case TargetOpcode::G_SSUBO:
+ case TargetOpcode::G_USUBO: {
+ // Emit the operation and get the correct condition code.
MachineIRBuilder MIRBuilder(I);
- auto OpAndCC = emitOverflowOp(Opcode, I.getOperand(0).getReg(),
- I.getOperand(2), I.getOperand(3), MIRBuilder);
+ auto OpAndCC = emitOverflowOp(Opcode, I.getOperand(0).getReg(),
+ I.getOperand(2), I.getOperand(3), MIRBuilder);
// Now, put the overflow result in the register given by the first operand
- // to the overflow op. CSINC increments the result when the predicate is
- // false, so to get the increment when it's true, we need to use the
- // inverse. In this case, we want to increment when carry is set.
- Register ZReg = AArch64::WZR;
+ // to the overflow op. CSINC increments the result when the predicate is
+ // false, so to get the increment when it's true, we need to use the
+ // inverse. In this case, we want to increment when carry is set.
+ Register ZReg = AArch64::WZR;
auto CsetMI = MIRBuilder
.buildInstr(AArch64::CSINCWr, {I.getOperand(1).getReg()},
- {ZReg, ZReg})
- .addImm(getInvertedCondCode(OpAndCC.second));
+ {ZReg, ZReg})
+ .addImm(getInvertedCondCode(OpAndCC.second));
constrainSelectedInstRegOperands(*CsetMI, TII, TRI, RBI);
I.eraseFromParent();
return true;
@@ -2768,7 +2768,7 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
case TargetOpcode::G_PTRMASK: {
Register MaskReg = I.getOperand(2).getReg();
- Optional<int64_t> MaskVal = getConstantVRegSExtVal(MaskReg, MRI);
+ Optional<int64_t> MaskVal = getConstantVRegSExtVal(MaskReg, MRI);
// TODO: Implement arbitrary cases
if (!MaskVal || !isShiftedMask_64(*MaskVal))
return false;
@@ -3059,15 +3059,15 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
if (tryOptSelect(I))
return true;
- // Make sure to use an unused vreg instead of wzr, so that the peephole
- // optimizations will be able to optimize these.
- MachineIRBuilder MIB(I);
- Register DeadVReg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
- auto TstMI = MIB.buildInstr(AArch64::ANDSWri, {DeadVReg}, {CondReg})
- .addImm(AArch64_AM::encodeLogicalImmediate(1, 32));
- constrainSelectedInstRegOperands(*TstMI, TII, TRI, RBI);
- if (!emitSelect(I.getOperand(0).getReg(), TReg, FReg, AArch64CC::NE, MIB))
- return false;
+ // Make sure to use an unused vreg instead of wzr, so that the peephole
+ // optimizations will be able to optimize these.
+ MachineIRBuilder MIB(I);
+ Register DeadVReg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
+ auto TstMI = MIB.buildInstr(AArch64::ANDSWri, {DeadVReg}, {CondReg})
+ .addImm(AArch64_AM::encodeLogicalImmediate(1, 32));
+ constrainSelectedInstRegOperands(*TstMI, TII, TRI, RBI);
+ if (!emitSelect(I.getOperand(0).getReg(), TReg, FReg, AArch64CC::NE, MIB))
+ return false;
I.eraseFromParent();
return true;
}
@@ -3082,21 +3082,21 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
}
MachineIRBuilder MIRBuilder(I);
- auto Pred = static_cast<CmpInst::Predicate>(I.getOperand(1).getPredicate());
- emitIntegerCompare(I.getOperand(2), I.getOperand(3), I.getOperand(1),
- MIRBuilder);
+ auto Pred = static_cast<CmpInst::Predicate>(I.getOperand(1).getPredicate());
+ emitIntegerCompare(I.getOperand(2), I.getOperand(3), I.getOperand(1),
+ MIRBuilder);
emitCSetForICMP(I.getOperand(0).getReg(), Pred, MIRBuilder);
I.eraseFromParent();
return true;
}
case TargetOpcode::G_FCMP: {
- MachineIRBuilder MIRBuilder(I);
- CmpInst::Predicate Pred =
- static_cast<CmpInst::Predicate>(I.getOperand(1).getPredicate());
- if (!emitFPCompare(I.getOperand(2).getReg(), I.getOperand(3).getReg(),
- MIRBuilder, Pred) ||
- !emitCSetForFCmp(I.getOperand(0).getReg(), Pred, MIRBuilder))
+ MachineIRBuilder MIRBuilder(I);
+ CmpInst::Predicate Pred =
+ static_cast<CmpInst::Predicate>(I.getOperand(1).getPredicate());
+ if (!emitFPCompare(I.getOperand(2).getReg(), I.getOperand(3).getReg(),
+ MIRBuilder, Pred) ||
+ !emitCSetForFCmp(I.getOperand(0).getReg(), Pred, MIRBuilder))
return false;
I.eraseFromParent();
return true;
@@ -3136,24 +3136,24 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
return constrainSelectedInstRegOperands(*MovMI, TII, TRI, RBI);
}
}
- case AArch64::G_DUP: {
- // When the scalar of G_DUP is an s8/s16 gpr, they can't be selected by
- // imported patterns. Do it manually here. Avoiding generating s16 gpr is
- // difficult because at RBS we may end up pessimizing the fpr case if we
- // decided to add an anyextend to fix this. Manual selection is the most
- // robust solution for now.
- Register SrcReg = I.getOperand(1).getReg();
- if (RBI.getRegBank(SrcReg, MRI, TRI)->getID() != AArch64::GPRRegBankID)
- return false; // We expect the fpr regbank case to be imported.
- LLT SrcTy = MRI.getType(SrcReg);
- if (SrcTy.getSizeInBits() == 16)
- I.setDesc(TII.get(AArch64::DUPv8i16gpr));
- else if (SrcTy.getSizeInBits() == 8)
- I.setDesc(TII.get(AArch64::DUPv16i8gpr));
- else
- return false;
- return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
- }
+ case AArch64::G_DUP: {
+ // When the scalar of G_DUP is an s8/s16 gpr, they can't be selected by
+ // imported patterns. Do it manually here. Avoiding generating s16 gpr is
+ // difficult because at RBS we may end up pessimizing the fpr case if we
+ // decided to add an anyextend to fix this. Manual selection is the most
+ // robust solution for now.
+ Register SrcReg = I.getOperand(1).getReg();
+ if (RBI.getRegBank(SrcReg, MRI, TRI)->getID() != AArch64::GPRRegBankID)
+ return false; // We expect the fpr regbank case to be imported.
+ LLT SrcTy = MRI.getType(SrcReg);
+ if (SrcTy.getSizeInBits() == 16)
+ I.setDesc(TII.get(AArch64::DUPv8i16gpr));
+ else if (SrcTy.getSizeInBits() == 8)
+ I.setDesc(TII.get(AArch64::DUPv16i8gpr));
+ else
+ return false;
+ return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
+ }
case TargetOpcode::G_INTRINSIC_TRUNC:
return selectIntrinsicTrunc(I, MRI);
case TargetOpcode::G_INTRINSIC_ROUND:
@@ -3174,52 +3174,52 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
return selectConcatVectors(I, MRI);
case TargetOpcode::G_JUMP_TABLE:
return selectJumpTable(I, MRI);
- case TargetOpcode::G_VECREDUCE_FADD:
- case TargetOpcode::G_VECREDUCE_ADD:
- return selectReduction(I, MRI);
+ case TargetOpcode::G_VECREDUCE_FADD:
+ case TargetOpcode::G_VECREDUCE_ADD:
+ return selectReduction(I, MRI);
+ }
+
+ return false;
+}
+
+bool AArch64InstructionSelector::selectReduction(
+ MachineInstr &I, MachineRegisterInfo &MRI) const {
+ Register VecReg = I.getOperand(1).getReg();
+ LLT VecTy = MRI.getType(VecReg);
+ if (I.getOpcode() == TargetOpcode::G_VECREDUCE_ADD) {
+ unsigned Opc = 0;
+ if (VecTy == LLT::vector(16, 8))
+ Opc = AArch64::ADDVv16i8v;
+ else if (VecTy == LLT::vector(8, 16))
+ Opc = AArch64::ADDVv8i16v;
+ else if (VecTy == LLT::vector(4, 32))
+ Opc = AArch64::ADDVv4i32v;
+ else if (VecTy == LLT::vector(2, 64))
+ Opc = AArch64::ADDPv2i64p;
+ else {
+ LLVM_DEBUG(dbgs() << "Unhandled type for add reduction");
+ return false;
+ }
+ I.setDesc(TII.get(Opc));
+ return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
}
+ if (I.getOpcode() == TargetOpcode::G_VECREDUCE_FADD) {
+ unsigned Opc = 0;
+ if (VecTy == LLT::vector(2, 32))
+ Opc = AArch64::FADDPv2i32p;
+ else if (VecTy == LLT::vector(2, 64))
+ Opc = AArch64::FADDPv2i64p;
+ else {
+ LLVM_DEBUG(dbgs() << "Unhandled type for fadd reduction");
+ return false;
+ }
+ I.setDesc(TII.get(Opc));
+ return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
+ }
return false;
}
-bool AArch64InstructionSelector::selectReduction(
- MachineInstr &I, MachineRegisterInfo &MRI) const {
- Register VecReg = I.getOperand(1).getReg();
- LLT VecTy = MRI.getType(VecReg);
- if (I.getOpcode() == TargetOpcode::G_VECREDUCE_ADD) {
- unsigned Opc = 0;
- if (VecTy == LLT::vector(16, 8))
- Opc = AArch64::ADDVv16i8v;
- else if (VecTy == LLT::vector(8, 16))
- Opc = AArch64::ADDVv8i16v;
- else if (VecTy == LLT::vector(4, 32))
- Opc = AArch64::ADDVv4i32v;
- else if (VecTy == LLT::vector(2, 64))
- Opc = AArch64::ADDPv2i64p;
- else {
- LLVM_DEBUG(dbgs() << "Unhandled type for add reduction");
- return false;
- }
- I.setDesc(TII.get(Opc));
- return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
- }
-
- if (I.getOpcode() == TargetOpcode::G_VECREDUCE_FADD) {
- unsigned Opc = 0;
- if (VecTy == LLT::vector(2, 32))
- Opc = AArch64::FADDPv2i32p;
- else if (VecTy == LLT::vector(2, 64))
- Opc = AArch64::FADDPv2i64p;
- else {
- LLVM_DEBUG(dbgs() << "Unhandled type for fadd reduction");
- return false;
- }
- I.setDesc(TII.get(Opc));
- return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
- }
- return false;
-}
-
bool AArch64InstructionSelector::selectBrJT(MachineInstr &I,
MachineRegisterInfo &MRI) const {
assert(I.getOpcode() == TargetOpcode::G_BRJT && "Expected G_BRJT");
@@ -3230,8 +3230,8 @@ bool AArch64InstructionSelector::selectBrJT(MachineInstr &I,
Register TargetReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
Register ScratchReg = MRI.createVirtualRegister(&AArch64::GPR64spRegClass);
-
- MF->getInfo<AArch64FunctionInfo>()->setJumpTableEntryInfo(JTI, 4, nullptr);
+
+ MF->getInfo<AArch64FunctionInfo>()->setJumpTableEntryInfo(JTI, 4, nullptr);
auto JumpTableInst = MIB.buildInstr(AArch64::JumpTableDest32,
{TargetReg, ScratchReg}, {JTAddr, Index})
.addJumpTableIndex(JTI);
@@ -3268,20 +3268,20 @@ bool AArch64InstructionSelector::selectTLSGlobalValue(
const GlobalValue &GV = *I.getOperand(1).getGlobal();
MachineIRBuilder MIB(I);
- auto LoadGOT =
- MIB.buildInstr(AArch64::LOADgot, {&AArch64::GPR64commonRegClass}, {})
- .addGlobalAddress(&GV, 0, AArch64II::MO_TLS);
+ auto LoadGOT =
+ MIB.buildInstr(AArch64::LOADgot, {&AArch64::GPR64commonRegClass}, {})
+ .addGlobalAddress(&GV, 0, AArch64II::MO_TLS);
auto Load = MIB.buildInstr(AArch64::LDRXui, {&AArch64::GPR64commonRegClass},
- {LoadGOT.getReg(0)})
+ {LoadGOT.getReg(0)})
.addImm(0);
- MIB.buildCopy(Register(AArch64::X0), LoadGOT.getReg(0));
+ MIB.buildCopy(Register(AArch64::X0), LoadGOT.getReg(0));
// TLS calls preserve all registers except those that absolutely must be
// trashed: X0 (it takes an argument), LR (it's a call) and NZCV (let's not be
// silly).
MIB.buildInstr(getBLRCallOpcode(MF), {}, {Load})
- .addUse(AArch64::X0, RegState::Implicit)
+ .addUse(AArch64::X0, RegState::Implicit)
.addDef(AArch64::X0, RegState::Implicit)
.addRegMask(TRI.getTLSCallPreservedMask());
@@ -3767,7 +3767,7 @@ bool AArch64InstructionSelector::selectExtractElt(
(void)WideTy;
assert(WideTy.getSizeInBits() >= NarrowTy.getSizeInBits() &&
"source register size too small!");
- assert(!NarrowTy.isVector() && "cannot extract vector into vector!");
+ assert(!NarrowTy.isVector() && "cannot extract vector into vector!");
// Need the lane index to determine the correct copy opcode.
MachineOperand &LaneIdxOp = I.getOperand(2);
@@ -3782,7 +3782,7 @@ bool AArch64InstructionSelector::selectExtractElt(
auto VRegAndVal = getConstantVRegValWithLookThrough(LaneIdxOp.getReg(), MRI);
if (!VRegAndVal)
return false;
- unsigned LaneIdx = VRegAndVal->Value.getSExtValue();
+ unsigned LaneIdx = VRegAndVal->Value.getSExtValue();
MachineIRBuilder MIRBuilder(I);
@@ -4005,10 +4005,10 @@ static std::pair<unsigned, unsigned>
getInsertVecEltOpInfo(const RegisterBank &RB, unsigned EltSize) {
unsigned Opc, SubregIdx;
if (RB.getID() == AArch64::GPRRegBankID) {
- if (EltSize == 16) {
- Opc = AArch64::INSvi16gpr;
- SubregIdx = AArch64::ssub;
- } else if (EltSize == 32) {
+ if (EltSize == 16) {
+ Opc = AArch64::INSvi16gpr;
+ SubregIdx = AArch64::ssub;
+ } else if (EltSize == 32) {
Opc = AArch64::INSvi32gpr;
SubregIdx = AArch64::ssub;
} else if (EltSize == 64) {
@@ -4037,93 +4037,93 @@ getInsertVecEltOpInfo(const RegisterBank &RB, unsigned EltSize) {
return std::make_pair(Opc, SubregIdx);
}
-MachineInstr *AArch64InstructionSelector::emitInstr(
- unsigned Opcode, std::initializer_list<llvm::DstOp> DstOps,
- std::initializer_list<llvm::SrcOp> SrcOps, MachineIRBuilder &MIRBuilder,
- const ComplexRendererFns &RenderFns) const {
- assert(Opcode && "Expected an opcode?");
- assert(!isPreISelGenericOpcode(Opcode) &&
- "Function should only be used to produce selected instructions!");
- auto MI = MIRBuilder.buildInstr(Opcode, DstOps, SrcOps);
- if (RenderFns)
- for (auto &Fn : *RenderFns)
- Fn(MI);
- constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
- return &*MI;
-}
-
-MachineInstr *AArch64InstructionSelector::emitAddSub(
- const std::array<std::array<unsigned, 2>, 5> &AddrModeAndSizeToOpcode,
- Register Dst, MachineOperand &LHS, MachineOperand &RHS,
- MachineIRBuilder &MIRBuilder) const {
- MachineRegisterInfo &MRI = MIRBuilder.getMF().getRegInfo();
- assert(LHS.isReg() && RHS.isReg() && "Expected register operands?");
- auto Ty = MRI.getType(LHS.getReg());
- assert(!Ty.isVector() && "Expected a scalar or pointer?");
- unsigned Size = Ty.getSizeInBits();
- assert((Size == 32 || Size == 64) && "Expected a 32-bit or 64-bit type only");
- bool Is32Bit = Size == 32;
-
- // INSTRri form with positive arithmetic immediate.
- if (auto Fns = selectArithImmed(RHS))
- return emitInstr(AddrModeAndSizeToOpcode[0][Is32Bit], {Dst}, {LHS},
- MIRBuilder, Fns);
-
- // INSTRri form with negative arithmetic immediate.
- if (auto Fns = selectNegArithImmed(RHS))
- return emitInstr(AddrModeAndSizeToOpcode[3][Is32Bit], {Dst}, {LHS},
- MIRBuilder, Fns);
-
- // INSTRrx form.
- if (auto Fns = selectArithExtendedRegister(RHS))
- return emitInstr(AddrModeAndSizeToOpcode[4][Is32Bit], {Dst}, {LHS},
- MIRBuilder, Fns);
-
- // INSTRrs form.
- if (auto Fns = selectShiftedRegister(RHS))
- return emitInstr(AddrModeAndSizeToOpcode[1][Is32Bit], {Dst}, {LHS},
- MIRBuilder, Fns);
- return emitInstr(AddrModeAndSizeToOpcode[2][Is32Bit], {Dst}, {LHS, RHS},
- MIRBuilder);
-}
-
+MachineInstr *AArch64InstructionSelector::emitInstr(
+ unsigned Opcode, std::initializer_list<llvm::DstOp> DstOps,
+ std::initializer_list<llvm::SrcOp> SrcOps, MachineIRBuilder &MIRBuilder,
+ const ComplexRendererFns &RenderFns) const {
+ assert(Opcode && "Expected an opcode?");
+ assert(!isPreISelGenericOpcode(Opcode) &&
+ "Function should only be used to produce selected instructions!");
+ auto MI = MIRBuilder.buildInstr(Opcode, DstOps, SrcOps);
+ if (RenderFns)
+ for (auto &Fn : *RenderFns)
+ Fn(MI);
+ constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
+ return &*MI;
+}
+
+MachineInstr *AArch64InstructionSelector::emitAddSub(
+ const std::array<std::array<unsigned, 2>, 5> &AddrModeAndSizeToOpcode,
+ Register Dst, MachineOperand &LHS, MachineOperand &RHS,
+ MachineIRBuilder &MIRBuilder) const {
+ MachineRegisterInfo &MRI = MIRBuilder.getMF().getRegInfo();
+ assert(LHS.isReg() && RHS.isReg() && "Expected register operands?");
+ auto Ty = MRI.getType(LHS.getReg());
+ assert(!Ty.isVector() && "Expected a scalar or pointer?");
+ unsigned Size = Ty.getSizeInBits();
+ assert((Size == 32 || Size == 64) && "Expected a 32-bit or 64-bit type only");
+ bool Is32Bit = Size == 32;
+
+ // INSTRri form with positive arithmetic immediate.
+ if (auto Fns = selectArithImmed(RHS))
+ return emitInstr(AddrModeAndSizeToOpcode[0][Is32Bit], {Dst}, {LHS},
+ MIRBuilder, Fns);
+
+ // INSTRri form with negative arithmetic immediate.
+ if (auto Fns = selectNegArithImmed(RHS))
+ return emitInstr(AddrModeAndSizeToOpcode[3][Is32Bit], {Dst}, {LHS},
+ MIRBuilder, Fns);
+
+ // INSTRrx form.
+ if (auto Fns = selectArithExtendedRegister(RHS))
+ return emitInstr(AddrModeAndSizeToOpcode[4][Is32Bit], {Dst}, {LHS},
+ MIRBuilder, Fns);
+
+ // INSTRrs form.
+ if (auto Fns = selectShiftedRegister(RHS))
+ return emitInstr(AddrModeAndSizeToOpcode[1][Is32Bit], {Dst}, {LHS},
+ MIRBuilder, Fns);
+ return emitInstr(AddrModeAndSizeToOpcode[2][Is32Bit], {Dst}, {LHS, RHS},
+ MIRBuilder);
+}
+
MachineInstr *
AArch64InstructionSelector::emitADD(Register DefReg, MachineOperand &LHS,
MachineOperand &RHS,
MachineIRBuilder &MIRBuilder) const {
- const std::array<std::array<unsigned, 2>, 5> OpcTable{
- {{AArch64::ADDXri, AArch64::ADDWri},
- {AArch64::ADDXrs, AArch64::ADDWrs},
- {AArch64::ADDXrr, AArch64::ADDWrr},
- {AArch64::SUBXri, AArch64::SUBWri},
- {AArch64::ADDXrx, AArch64::ADDWrx}}};
- return emitAddSub(OpcTable, DefReg, LHS, RHS, MIRBuilder);
-}
-
-MachineInstr *
-AArch64InstructionSelector::emitADDS(Register Dst, MachineOperand &LHS,
- MachineOperand &RHS,
- MachineIRBuilder &MIRBuilder) const {
- const std::array<std::array<unsigned, 2>, 5> OpcTable{
- {{AArch64::ADDSXri, AArch64::ADDSWri},
- {AArch64::ADDSXrs, AArch64::ADDSWrs},
- {AArch64::ADDSXrr, AArch64::ADDSWrr},
- {AArch64::SUBSXri, AArch64::SUBSWri},
- {AArch64::ADDSXrx, AArch64::ADDSWrx}}};
- return emitAddSub(OpcTable, Dst, LHS, RHS, MIRBuilder);
-}
-
-MachineInstr *
-AArch64InstructionSelector::emitSUBS(Register Dst, MachineOperand &LHS,
- MachineOperand &RHS,
- MachineIRBuilder &MIRBuilder) const {
- const std::array<std::array<unsigned, 2>, 5> OpcTable{
- {{AArch64::SUBSXri, AArch64::SUBSWri},
- {AArch64::SUBSXrs, AArch64::SUBSWrs},
- {AArch64::SUBSXrr, AArch64::SUBSWrr},
- {AArch64::ADDSXri, AArch64::ADDSWri},
- {AArch64::SUBSXrx, AArch64::SUBSWrx}}};
- return emitAddSub(OpcTable, Dst, LHS, RHS, MIRBuilder);
+ const std::array<std::array<unsigned, 2>, 5> OpcTable{
+ {{AArch64::ADDXri, AArch64::ADDWri},
+ {AArch64::ADDXrs, AArch64::ADDWrs},
+ {AArch64::ADDXrr, AArch64::ADDWrr},
+ {AArch64::SUBXri, AArch64::SUBWri},
+ {AArch64::ADDXrx, AArch64::ADDWrx}}};
+ return emitAddSub(OpcTable, DefReg, LHS, RHS, MIRBuilder);
+}
+
+MachineInstr *
+AArch64InstructionSelector::emitADDS(Register Dst, MachineOperand &LHS,
+ MachineOperand &RHS,
+ MachineIRBuilder &MIRBuilder) const {
+ const std::array<std::array<unsigned, 2>, 5> OpcTable{
+ {{AArch64::ADDSXri, AArch64::ADDSWri},
+ {AArch64::ADDSXrs, AArch64::ADDSWrs},
+ {AArch64::ADDSXrr, AArch64::ADDSWrr},
+ {AArch64::SUBSXri, AArch64::SUBSWri},
+ {AArch64::ADDSXrx, AArch64::ADDSWrx}}};
+ return emitAddSub(OpcTable, Dst, LHS, RHS, MIRBuilder);
+}
+
+MachineInstr *
+AArch64InstructionSelector::emitSUBS(Register Dst, MachineOperand &LHS,
+ MachineOperand &RHS,
+ MachineIRBuilder &MIRBuilder) const {
+ const std::array<std::array<unsigned, 2>, 5> OpcTable{
+ {{AArch64::SUBSXri, AArch64::SUBSWri},
+ {AArch64::SUBSXrs, AArch64::SUBSWrs},
+ {AArch64::SUBSXrr, AArch64::SUBSWrr},
+ {AArch64::ADDSXri, AArch64::ADDSWri},
+ {AArch64::SUBSXrx, AArch64::SUBSWrx}}};
+ return emitAddSub(OpcTable, Dst, LHS, RHS, MIRBuilder);
}
MachineInstr *
@@ -4131,129 +4131,129 @@ AArch64InstructionSelector::emitCMN(MachineOperand &LHS, MachineOperand &RHS,
MachineIRBuilder &MIRBuilder) const {
MachineRegisterInfo &MRI = MIRBuilder.getMF().getRegInfo();
bool Is32Bit = (MRI.getType(LHS.getReg()).getSizeInBits() == 32);
- auto RC = Is32Bit ? &AArch64::GPR32RegClass : &AArch64::GPR64RegClass;
- return emitADDS(MRI.createVirtualRegister(RC), LHS, RHS, MIRBuilder);
+ auto RC = Is32Bit ? &AArch64::GPR32RegClass : &AArch64::GPR64RegClass;
+ return emitADDS(MRI.createVirtualRegister(RC), LHS, RHS, MIRBuilder);
}
MachineInstr *
-AArch64InstructionSelector::emitTST(MachineOperand &LHS, MachineOperand &RHS,
+AArch64InstructionSelector::emitTST(MachineOperand &LHS, MachineOperand &RHS,
MachineIRBuilder &MIRBuilder) const {
- assert(LHS.isReg() && RHS.isReg() && "Expected register operands?");
+ assert(LHS.isReg() && RHS.isReg() && "Expected register operands?");
MachineRegisterInfo &MRI = MIRBuilder.getMF().getRegInfo();
- LLT Ty = MRI.getType(LHS.getReg());
- unsigned RegSize = Ty.getSizeInBits();
+ LLT Ty = MRI.getType(LHS.getReg());
+ unsigned RegSize = Ty.getSizeInBits();
bool Is32Bit = (RegSize == 32);
- const unsigned OpcTable[3][2] = {{AArch64::ANDSXri, AArch64::ANDSWri},
- {AArch64::ANDSXrs, AArch64::ANDSWrs},
- {AArch64::ANDSXrr, AArch64::ANDSWrr}};
- // ANDS needs a logical immediate for its immediate form. Check if we can
- // fold one in.
- if (auto ValAndVReg = getConstantVRegValWithLookThrough(RHS.getReg(), MRI)) {
- int64_t Imm = ValAndVReg->Value.getSExtValue();
-
- if (AArch64_AM::isLogicalImmediate(Imm, RegSize)) {
- auto TstMI = MIRBuilder.buildInstr(OpcTable[0][Is32Bit], {Ty}, {LHS});
- TstMI.addImm(AArch64_AM::encodeLogicalImmediate(Imm, RegSize));
- constrainSelectedInstRegOperands(*TstMI, TII, TRI, RBI);
- return &*TstMI;
- }
- }
-
- if (auto Fns = selectLogicalShiftedRegister(RHS))
- return emitInstr(OpcTable[1][Is32Bit], {Ty}, {LHS}, MIRBuilder, Fns);
- return emitInstr(OpcTable[2][Is32Bit], {Ty}, {LHS, RHS}, MIRBuilder);
+ const unsigned OpcTable[3][2] = {{AArch64::ANDSXri, AArch64::ANDSWri},
+ {AArch64::ANDSXrs, AArch64::ANDSWrs},
+ {AArch64::ANDSXrr, AArch64::ANDSWrr}};
+ // ANDS needs a logical immediate for its immediate form. Check if we can
+ // fold one in.
+ if (auto ValAndVReg = getConstantVRegValWithLookThrough(RHS.getReg(), MRI)) {
+ int64_t Imm = ValAndVReg->Value.getSExtValue();
+
+ if (AArch64_AM::isLogicalImmediate(Imm, RegSize)) {
+ auto TstMI = MIRBuilder.buildInstr(OpcTable[0][Is32Bit], {Ty}, {LHS});
+ TstMI.addImm(AArch64_AM::encodeLogicalImmediate(Imm, RegSize));
+ constrainSelectedInstRegOperands(*TstMI, TII, TRI, RBI);
+ return &*TstMI;
+ }
+ }
+
+ if (auto Fns = selectLogicalShiftedRegister(RHS))
+ return emitInstr(OpcTable[1][Is32Bit], {Ty}, {LHS}, MIRBuilder, Fns);
+ return emitInstr(OpcTable[2][Is32Bit], {Ty}, {LHS, RHS}, MIRBuilder);
}
-MachineInstr *AArch64InstructionSelector::emitIntegerCompare(
+MachineInstr *AArch64InstructionSelector::emitIntegerCompare(
MachineOperand &LHS, MachineOperand &RHS, MachineOperand &Predicate,
MachineIRBuilder &MIRBuilder) const {
assert(LHS.isReg() && RHS.isReg() && "Expected LHS and RHS to be registers!");
assert(Predicate.isPredicate() && "Expected predicate?");
MachineRegisterInfo &MRI = MIRBuilder.getMF().getRegInfo();
- LLT CmpTy = MRI.getType(LHS.getReg());
- assert(!CmpTy.isVector() && "Expected scalar or pointer");
- unsigned Size = CmpTy.getSizeInBits();
- (void)Size;
- assert((Size == 32 || Size == 64) && "Expected a 32-bit or 64-bit LHS/RHS?");
- // Fold the compare into a cmn or tst if possible.
- if (auto FoldCmp = tryFoldIntegerCompare(LHS, RHS, Predicate, MIRBuilder))
- return FoldCmp;
- auto Dst = MRI.cloneVirtualRegister(LHS.getReg());
- return emitSUBS(Dst, LHS, RHS, MIRBuilder);
-}
-
-MachineInstr *AArch64InstructionSelector::emitCSetForFCmp(
- Register Dst, CmpInst::Predicate Pred, MachineIRBuilder &MIRBuilder) const {
- MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
-#ifndef NDEBUG
- LLT Ty = MRI.getType(Dst);
- assert(!Ty.isVector() && Ty.getSizeInBits() == 32 &&
- "Expected a 32-bit scalar register?");
-#endif
- const Register ZeroReg = AArch64::WZR;
- auto EmitCSet = [&](Register CsetDst, AArch64CC::CondCode CC) {
- auto CSet =
- MIRBuilder.buildInstr(AArch64::CSINCWr, {CsetDst}, {ZeroReg, ZeroReg})
- .addImm(getInvertedCondCode(CC));
- constrainSelectedInstRegOperands(*CSet, TII, TRI, RBI);
- return &*CSet;
- };
-
- AArch64CC::CondCode CC1, CC2;
- changeFCMPPredToAArch64CC(Pred, CC1, CC2);
- if (CC2 == AArch64CC::AL)
- return EmitCSet(Dst, CC1);
-
- const TargetRegisterClass *RC = &AArch64::GPR32RegClass;
- Register Def1Reg = MRI.createVirtualRegister(RC);
- Register Def2Reg = MRI.createVirtualRegister(RC);
- EmitCSet(Def1Reg, CC1);
- EmitCSet(Def2Reg, CC2);
- auto OrMI = MIRBuilder.buildInstr(AArch64::ORRWrr, {Dst}, {Def1Reg, Def2Reg});
- constrainSelectedInstRegOperands(*OrMI, TII, TRI, RBI);
- return &*OrMI;
-}
-
-MachineInstr *
-AArch64InstructionSelector::emitFPCompare(Register LHS, Register RHS,
- MachineIRBuilder &MIRBuilder,
- Optional<CmpInst::Predicate> Pred) const {
- MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
- LLT Ty = MRI.getType(LHS);
- if (Ty.isVector())
- return nullptr;
- unsigned OpSize = Ty.getSizeInBits();
- if (OpSize != 32 && OpSize != 64)
- return nullptr;
-
- // If this is a compare against +0.0, then we don't have
- // to explicitly materialize a constant.
- const ConstantFP *FPImm = getConstantFPVRegVal(RHS, MRI);
- bool ShouldUseImm = FPImm && (FPImm->isZero() && !FPImm->isNegative());
-
- auto IsEqualityPred = [](CmpInst::Predicate P) {
- return P == CmpInst::FCMP_OEQ || P == CmpInst::FCMP_ONE ||
- P == CmpInst::FCMP_UEQ || P == CmpInst::FCMP_UNE;
- };
- if (!ShouldUseImm && Pred && IsEqualityPred(*Pred)) {
- // Try commutating the operands.
- const ConstantFP *LHSImm = getConstantFPVRegVal(LHS, MRI);
- if (LHSImm && (LHSImm->isZero() && !LHSImm->isNegative())) {
- ShouldUseImm = true;
- std::swap(LHS, RHS);
- }
- }
- unsigned CmpOpcTbl[2][2] = {{AArch64::FCMPSrr, AArch64::FCMPDrr},
- {AArch64::FCMPSri, AArch64::FCMPDri}};
- unsigned CmpOpc = CmpOpcTbl[ShouldUseImm][OpSize == 64];
-
- // Partially build the compare. Decide if we need to add a use for the
- // third operand based off whether or not we're comparing against 0.0.
- auto CmpMI = MIRBuilder.buildInstr(CmpOpc).addUse(LHS);
- if (!ShouldUseImm)
- CmpMI.addUse(RHS);
+ LLT CmpTy = MRI.getType(LHS.getReg());
+ assert(!CmpTy.isVector() && "Expected scalar or pointer");
+ unsigned Size = CmpTy.getSizeInBits();
+ (void)Size;
+ assert((Size == 32 || Size == 64) && "Expected a 32-bit or 64-bit LHS/RHS?");
+ // Fold the compare into a cmn or tst if possible.
+ if (auto FoldCmp = tryFoldIntegerCompare(LHS, RHS, Predicate, MIRBuilder))
+ return FoldCmp;
+ auto Dst = MRI.cloneVirtualRegister(LHS.getReg());
+ return emitSUBS(Dst, LHS, RHS, MIRBuilder);
+}
+
+MachineInstr *AArch64InstructionSelector::emitCSetForFCmp(
+ Register Dst, CmpInst::Predicate Pred, MachineIRBuilder &MIRBuilder) const {
+ MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
+#ifndef NDEBUG
+ LLT Ty = MRI.getType(Dst);
+ assert(!Ty.isVector() && Ty.getSizeInBits() == 32 &&
+ "Expected a 32-bit scalar register?");
+#endif
+ const Register ZeroReg = AArch64::WZR;
+ auto EmitCSet = [&](Register CsetDst, AArch64CC::CondCode CC) {
+ auto CSet =
+ MIRBuilder.buildInstr(AArch64::CSINCWr, {CsetDst}, {ZeroReg, ZeroReg})
+ .addImm(getInvertedCondCode(CC));
+ constrainSelectedInstRegOperands(*CSet, TII, TRI, RBI);
+ return &*CSet;
+ };
+
+ AArch64CC::CondCode CC1, CC2;
+ changeFCMPPredToAArch64CC(Pred, CC1, CC2);
+ if (CC2 == AArch64CC::AL)
+ return EmitCSet(Dst, CC1);
+
+ const TargetRegisterClass *RC = &AArch64::GPR32RegClass;
+ Register Def1Reg = MRI.createVirtualRegister(RC);
+ Register Def2Reg = MRI.createVirtualRegister(RC);
+ EmitCSet(Def1Reg, CC1);
+ EmitCSet(Def2Reg, CC2);
+ auto OrMI = MIRBuilder.buildInstr(AArch64::ORRWrr, {Dst}, {Def1Reg, Def2Reg});
+ constrainSelectedInstRegOperands(*OrMI, TII, TRI, RBI);
+ return &*OrMI;
+}
+
+MachineInstr *
+AArch64InstructionSelector::emitFPCompare(Register LHS, Register RHS,
+ MachineIRBuilder &MIRBuilder,
+ Optional<CmpInst::Predicate> Pred) const {
+ MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
+ LLT Ty = MRI.getType(LHS);
+ if (Ty.isVector())
+ return nullptr;
+ unsigned OpSize = Ty.getSizeInBits();
+ if (OpSize != 32 && OpSize != 64)
+ return nullptr;
+
+ // If this is a compare against +0.0, then we don't have
+ // to explicitly materialize a constant.
+ const ConstantFP *FPImm = getConstantFPVRegVal(RHS, MRI);
+ bool ShouldUseImm = FPImm && (FPImm->isZero() && !FPImm->isNegative());
+
+ auto IsEqualityPred = [](CmpInst::Predicate P) {
+ return P == CmpInst::FCMP_OEQ || P == CmpInst::FCMP_ONE ||
+ P == CmpInst::FCMP_UEQ || P == CmpInst::FCMP_UNE;
+ };
+ if (!ShouldUseImm && Pred && IsEqualityPred(*Pred)) {
+ // Try commutating the operands.
+ const ConstantFP *LHSImm = getConstantFPVRegVal(LHS, MRI);
+ if (LHSImm && (LHSImm->isZero() && !LHSImm->isNegative())) {
+ ShouldUseImm = true;
+ std::swap(LHS, RHS);
+ }
+ }
+ unsigned CmpOpcTbl[2][2] = {{AArch64::FCMPSrr, AArch64::FCMPDrr},
+ {AArch64::FCMPSri, AArch64::FCMPDri}};
+ unsigned CmpOpc = CmpOpcTbl[ShouldUseImm][OpSize == 64];
+
+ // Partially build the compare. Decide if we need to add a use for the
+ // third operand based off whether or not we're comparing against 0.0.
+ auto CmpMI = MIRBuilder.buildInstr(CmpOpc).addUse(LHS);
+ if (!ShouldUseImm)
+ CmpMI.addUse(RHS);
constrainSelectedInstRegOperands(*CmpMI, TII, TRI, RBI);
- return &*CmpMI;
+ return &*CmpMI;
}
MachineInstr *AArch64InstructionSelector::emitVectorConcat(
@@ -4363,25 +4363,25 @@ AArch64InstructionSelector::emitCSetForICMP(Register DefReg, unsigned Pred,
return &*I;
}
-std::pair<MachineInstr *, AArch64CC::CondCode>
-AArch64InstructionSelector::emitOverflowOp(unsigned Opcode, Register Dst,
- MachineOperand &LHS,
- MachineOperand &RHS,
- MachineIRBuilder &MIRBuilder) const {
- switch (Opcode) {
- default:
- llvm_unreachable("Unexpected opcode!");
- case TargetOpcode::G_SADDO:
- return std::make_pair(emitADDS(Dst, LHS, RHS, MIRBuilder), AArch64CC::VS);
- case TargetOpcode::G_UADDO:
- return std::make_pair(emitADDS(Dst, LHS, RHS, MIRBuilder), AArch64CC::HS);
- case TargetOpcode::G_SSUBO:
- return std::make_pair(emitSUBS(Dst, LHS, RHS, MIRBuilder), AArch64CC::VS);
- case TargetOpcode::G_USUBO:
- return std::make_pair(emitSUBS(Dst, LHS, RHS, MIRBuilder), AArch64CC::LO);
- }
-}
-
+std::pair<MachineInstr *, AArch64CC::CondCode>
+AArch64InstructionSelector::emitOverflowOp(unsigned Opcode, Register Dst,
+ MachineOperand &LHS,
+ MachineOperand &RHS,
+ MachineIRBuilder &MIRBuilder) const {
+ switch (Opcode) {
+ default:
+ llvm_unreachable("Unexpected opcode!");
+ case TargetOpcode::G_SADDO:
+ return std::make_pair(emitADDS(Dst, LHS, RHS, MIRBuilder), AArch64CC::VS);
+ case TargetOpcode::G_UADDO:
+ return std::make_pair(emitADDS(Dst, LHS, RHS, MIRBuilder), AArch64CC::HS);
+ case TargetOpcode::G_SSUBO:
+ return std::make_pair(emitSUBS(Dst, LHS, RHS, MIRBuilder), AArch64CC::VS);
+ case TargetOpcode::G_USUBO:
+ return std::make_pair(emitSUBS(Dst, LHS, RHS, MIRBuilder), AArch64CC::LO);
+ }
+}
+
bool AArch64InstructionSelector::tryOptSelect(MachineInstr &I) const {
MachineIRBuilder MIB(I);
MachineRegisterInfo &MRI = *MIB.getMRI();
@@ -4441,17 +4441,17 @@ bool AArch64InstructionSelector::tryOptSelect(MachineInstr &I) const {
AArch64CC::CondCode CondCode;
if (CondOpc == TargetOpcode::G_ICMP) {
- auto Pred =
- static_cast<CmpInst::Predicate>(CondDef->getOperand(1).getPredicate());
+ auto Pred =
+ static_cast<CmpInst::Predicate>(CondDef->getOperand(1).getPredicate());
CondCode = changeICMPPredToAArch64CC(Pred);
- emitIntegerCompare(CondDef->getOperand(2), CondDef->getOperand(3),
- CondDef->getOperand(1), MIB);
+ emitIntegerCompare(CondDef->getOperand(2), CondDef->getOperand(3),
+ CondDef->getOperand(1), MIB);
} else {
// Get the condition code for the select.
- auto Pred =
- static_cast<CmpInst::Predicate>(CondDef->getOperand(1).getPredicate());
+ auto Pred =
+ static_cast<CmpInst::Predicate>(CondDef->getOperand(1).getPredicate());
AArch64CC::CondCode CondCode2;
- changeFCMPPredToAArch64CC(Pred, CondCode, CondCode2);
+ changeFCMPPredToAArch64CC(Pred, CondCode, CondCode2);
// changeFCMPPredToAArch64CC sets CondCode2 to AL when we require two
// instructions to emit the comparison.
@@ -4460,16 +4460,16 @@ bool AArch64InstructionSelector::tryOptSelect(MachineInstr &I) const {
if (CondCode2 != AArch64CC::AL)
return false;
- if (!emitFPCompare(CondDef->getOperand(2).getReg(),
- CondDef->getOperand(3).getReg(), MIB)) {
- LLVM_DEBUG(dbgs() << "Couldn't emit compare for select!\n");
+ if (!emitFPCompare(CondDef->getOperand(2).getReg(),
+ CondDef->getOperand(3).getReg(), MIB)) {
+ LLVM_DEBUG(dbgs() << "Couldn't emit compare for select!\n");
return false;
- }
+ }
}
// Emit the select.
- emitSelect(I.getOperand(0).getReg(), I.getOperand(2).getReg(),
- I.getOperand(3).getReg(), CondCode, MIB);
+ emitSelect(I.getOperand(0).getReg(), I.getOperand(2).getReg(),
+ I.getOperand(3).getReg(), CondCode, MIB);
I.eraseFromParent();
return true;
}
@@ -4552,15 +4552,15 @@ MachineInstr *AArch64InstructionSelector::tryFoldIntegerCompare(
// Produce this if the compare is signed:
//
// tst x, y
- if (!CmpInst::isUnsigned(P) && LHSDef &&
+ if (!CmpInst::isUnsigned(P) && LHSDef &&
LHSDef->getOpcode() == TargetOpcode::G_AND) {
// Make sure that the RHS is 0.
auto ValAndVReg = getConstantVRegValWithLookThrough(RHS.getReg(), MRI);
if (!ValAndVReg || ValAndVReg->Value != 0)
return nullptr;
- return emitTST(LHSDef->getOperand(1),
- LHSDef->getOperand(2), MIRBuilder);
+ return emitTST(LHSDef->getOperand(1),
+ LHSDef->getOperand(2), MIRBuilder);
}
return nullptr;
@@ -4708,7 +4708,7 @@ bool AArch64InstructionSelector::selectInsertElt(
auto VRegAndVal = getConstantVRegValWithLookThrough(IdxReg, MRI);
if (!VRegAndVal)
return false;
- unsigned LaneIdx = VRegAndVal->Value.getSExtValue();
+ unsigned LaneIdx = VRegAndVal->Value.getSExtValue();
// Perform the lane insert.
Register SrcReg = I.getOperand(1).getReg();
@@ -4765,9 +4765,9 @@ bool AArch64InstructionSelector::selectInsertElt(
bool AArch64InstructionSelector::tryOptConstantBuildVec(
MachineInstr &I, LLT DstTy, MachineRegisterInfo &MRI) const {
assert(I.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
- unsigned DstSize = DstTy.getSizeInBits();
- assert(DstSize <= 128 && "Unexpected build_vec type!");
- if (DstSize < 32)
+ unsigned DstSize = DstTy.getSizeInBits();
+ assert(DstSize <= 128 && "Unexpected build_vec type!");
+ if (DstSize < 32)
return false;
// Check if we're building a constant vector, in which case we want to
// generate a constant pool load instead of a vector insert sequence.
@@ -4788,24 +4788,24 @@ bool AArch64InstructionSelector::tryOptConstantBuildVec(
}
Constant *CV = ConstantVector::get(Csts);
MachineIRBuilder MIB(I);
- if (CV->isNullValue()) {
- // Until the importer can support immAllZerosV in pattern leaf nodes,
- // select a zero move manually here.
- Register DstReg = I.getOperand(0).getReg();
- if (DstSize == 128) {
- auto Mov = MIB.buildInstr(AArch64::MOVIv2d_ns, {DstReg}, {}).addImm(0);
- I.eraseFromParent();
- return constrainSelectedInstRegOperands(*Mov, TII, TRI, RBI);
- } else if (DstSize == 64) {
- auto Mov =
- MIB.buildInstr(AArch64::MOVIv2d_ns, {&AArch64::FPR128RegClass}, {})
- .addImm(0);
- MIB.buildInstr(TargetOpcode::COPY, {DstReg}, {})
- .addReg(Mov.getReg(0), 0, AArch64::dsub);
- I.eraseFromParent();
- return RBI.constrainGenericRegister(DstReg, AArch64::FPR64RegClass, MRI);
- }
- }
+ if (CV->isNullValue()) {
+ // Until the importer can support immAllZerosV in pattern leaf nodes,
+ // select a zero move manually here.
+ Register DstReg = I.getOperand(0).getReg();
+ if (DstSize == 128) {
+ auto Mov = MIB.buildInstr(AArch64::MOVIv2d_ns, {DstReg}, {}).addImm(0);
+ I.eraseFromParent();
+ return constrainSelectedInstRegOperands(*Mov, TII, TRI, RBI);
+ } else if (DstSize == 64) {
+ auto Mov =
+ MIB.buildInstr(AArch64::MOVIv2d_ns, {&AArch64::FPR128RegClass}, {})
+ .addImm(0);
+ MIB.buildInstr(TargetOpcode::COPY, {DstReg}, {})
+ .addReg(Mov.getReg(0), 0, AArch64::dsub);
+ I.eraseFromParent();
+ return RBI.constrainGenericRegister(DstReg, AArch64::FPR64RegClass, MRI);
+ }
+ }
auto *CPLoad = emitLoadFromConstantPool(CV, MIB);
if (!CPLoad) {
LLVM_DEBUG(dbgs() << "Could not generate cp load for build_vector");
@@ -4927,10 +4927,10 @@ bool AArch64InstructionSelector::selectIntrinsicWithSideEffects(
case Intrinsic::debugtrap:
MIRBuilder.buildInstr(AArch64::BRK, {}, {}).addImm(0xF000);
break;
- case Intrinsic::ubsantrap:
- MIRBuilder.buildInstr(AArch64::BRK, {}, {})
- .addImm(I.getOperand(1).getImm() | ('U' << 8));
- break;
+ case Intrinsic::ubsantrap:
+ MIRBuilder.buildInstr(AArch64::BRK, {}, {})
+ .addImm(I.getOperand(1).getImm() | ('U' << 8));
+ break;
}
I.eraseFromParent();
@@ -4996,22 +4996,22 @@ bool AArch64InstructionSelector::selectIntrinsic(MachineInstr &I,
RBI.constrainGenericRegister(DstReg, AArch64::GPR64RegClass, MRI);
if (Depth == 0 && IntrinID == Intrinsic::returnaddress) {
- if (!MFReturnAddr) {
- // Insert the copy from LR/X30 into the entry block, before it can be
- // clobbered by anything.
- MFI.setReturnAddressIsTaken(true);
- MFReturnAddr = getFunctionLiveInPhysReg(MF, TII, AArch64::LR,
- AArch64::GPR64RegClass);
+ if (!MFReturnAddr) {
+ // Insert the copy from LR/X30 into the entry block, before it can be
+ // clobbered by anything.
+ MFI.setReturnAddressIsTaken(true);
+ MFReturnAddr = getFunctionLiveInPhysReg(MF, TII, AArch64::LR,
+ AArch64::GPR64RegClass);
+ }
+
+ if (STI.hasPAuth()) {
+ MIRBuilder.buildInstr(AArch64::XPACI, {DstReg}, {MFReturnAddr});
+ } else {
+ MIRBuilder.buildCopy({Register(AArch64::LR)}, {MFReturnAddr});
+ MIRBuilder.buildInstr(AArch64::XPACLRI);
+ MIRBuilder.buildCopy({DstReg}, {Register(AArch64::LR)});
}
-
- if (STI.hasPAuth()) {
- MIRBuilder.buildInstr(AArch64::XPACI, {DstReg}, {MFReturnAddr});
- } else {
- MIRBuilder.buildCopy({Register(AArch64::LR)}, {MFReturnAddr});
- MIRBuilder.buildInstr(AArch64::XPACLRI);
- MIRBuilder.buildCopy({DstReg}, {Register(AArch64::LR)});
- }
-
+
I.eraseFromParent();
return true;
}
@@ -5031,16 +5031,16 @@ bool AArch64InstructionSelector::selectIntrinsic(MachineInstr &I,
MIRBuilder.buildCopy({DstReg}, {FrameAddr});
else {
MFI.setReturnAddressIsTaken(true);
-
- if (STI.hasPAuth()) {
- Register TmpReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
- MIRBuilder.buildInstr(AArch64::LDRXui, {TmpReg}, {FrameAddr}).addImm(1);
- MIRBuilder.buildInstr(AArch64::XPACI, {DstReg}, {TmpReg});
- } else {
- MIRBuilder.buildInstr(AArch64::LDRXui, {Register(AArch64::LR)}, {FrameAddr}).addImm(1);
- MIRBuilder.buildInstr(AArch64::XPACLRI);
- MIRBuilder.buildCopy({DstReg}, {Register(AArch64::LR)});
- }
+
+ if (STI.hasPAuth()) {
+ Register TmpReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
+ MIRBuilder.buildInstr(AArch64::LDRXui, {TmpReg}, {FrameAddr}).addImm(1);
+ MIRBuilder.buildInstr(AArch64::XPACI, {DstReg}, {TmpReg});
+ } else {
+ MIRBuilder.buildInstr(AArch64::LDRXui, {Register(AArch64::LR)}, {FrameAddr}).addImm(1);
+ MIRBuilder.buildInstr(AArch64::XPACLRI);
+ MIRBuilder.buildCopy({DstReg}, {Register(AArch64::LR)});
+ }
}
I.eraseFromParent();
@@ -5248,7 +5248,7 @@ AArch64InstructionSelector::selectExtendedSHL(
// The value must fit into 3 bits, and must be positive. Make sure that is
// true.
- int64_t ImmVal = ValAndVReg->Value.getSExtValue();
+ int64_t ImmVal = ValAndVReg->Value.getSExtValue();
// Since we're going to pull this into a shift, the constant value must be
// a power of 2. If we got a multiply, then we need to check this.
@@ -5388,60 +5388,60 @@ InstructionSelector::ComplexRendererFns
AArch64InstructionSelector::selectAddrModeXRO(MachineOperand &Root,
unsigned SizeInBytes) const {
MachineRegisterInfo &MRI = Root.getParent()->getMF()->getRegInfo();
- if (!Root.isReg())
+ if (!Root.isReg())
+ return None;
+ MachineInstr *PtrAdd =
+ getOpcodeDef(TargetOpcode::G_PTR_ADD, Root.getReg(), MRI);
+ if (!PtrAdd)
return None;
- MachineInstr *PtrAdd =
- getOpcodeDef(TargetOpcode::G_PTR_ADD, Root.getReg(), MRI);
- if (!PtrAdd)
- return None;
-
- // Check for an immediates which cannot be encoded in the [base + imm]
- // addressing mode, and can't be encoded in an add/sub. If this happens, we'll
- // end up with code like:
- //
- // mov x0, wide
- // add x1 base, x0
- // ldr x2, [x1, x0]
- //
- // In this situation, we can use the [base, xreg] addressing mode to save an
- // add/sub:
- //
- // mov x0, wide
- // ldr x2, [base, x0]
- auto ValAndVReg =
- getConstantVRegValWithLookThrough(PtrAdd->getOperand(2).getReg(), MRI);
- if (ValAndVReg) {
- unsigned Scale = Log2_32(SizeInBytes);
- int64_t ImmOff = ValAndVReg->Value.getSExtValue();
-
- // Skip immediates that can be selected in the load/store addresing
- // mode.
- if (ImmOff % SizeInBytes == 0 && ImmOff >= 0 &&
- ImmOff < (0x1000 << Scale))
- return None;
-
- // Helper lambda to decide whether or not it is preferable to emit an add.
- auto isPreferredADD = [](int64_t ImmOff) {
- // Constants in [0x0, 0xfff] can be encoded in an add.
- if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
- return true;
-
- // Can it be encoded in an add lsl #12?
- if ((ImmOff & 0xffffffffff000fffLL) != 0x0LL)
- return false;
-
- // It can be encoded in an add lsl #12, but we may not want to. If it is
- // possible to select this as a single movz, then prefer that. A single
- // movz is faster than an add with a shift.
- return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
- (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
- };
-
- // If the immediate can be encoded in a single add/sub, then bail out.
- if (isPreferredADD(ImmOff) || isPreferredADD(-ImmOff))
- return None;
- }
-
+
+ // Check for an immediates which cannot be encoded in the [base + imm]
+ // addressing mode, and can't be encoded in an add/sub. If this happens, we'll
+ // end up with code like:
+ //
+ // mov x0, wide
+ // add x1 base, x0
+ // ldr x2, [x1, x0]
+ //
+ // In this situation, we can use the [base, xreg] addressing mode to save an
+ // add/sub:
+ //
+ // mov x0, wide
+ // ldr x2, [base, x0]
+ auto ValAndVReg =
+ getConstantVRegValWithLookThrough(PtrAdd->getOperand(2).getReg(), MRI);
+ if (ValAndVReg) {
+ unsigned Scale = Log2_32(SizeInBytes);
+ int64_t ImmOff = ValAndVReg->Value.getSExtValue();
+
+ // Skip immediates that can be selected in the load/store addresing
+ // mode.
+ if (ImmOff % SizeInBytes == 0 && ImmOff >= 0 &&
+ ImmOff < (0x1000 << Scale))
+ return None;
+
+ // Helper lambda to decide whether or not it is preferable to emit an add.
+ auto isPreferredADD = [](int64_t ImmOff) {
+ // Constants in [0x0, 0xfff] can be encoded in an add.
+ if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
+ return true;
+
+ // Can it be encoded in an add lsl #12?
+ if ((ImmOff & 0xffffffffff000fffLL) != 0x0LL)
+ return false;
+
+ // It can be encoded in an add lsl #12, but we may not want to. If it is
+ // possible to select this as a single movz, then prefer that. A single
+ // movz is faster than an add with a shift.
+ return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
+ (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
+ };
+
+ // If the immediate can be encoded in a single add/sub, then bail out.
+ if (isPreferredADD(ImmOff) || isPreferredADD(-ImmOff))
+ return None;
+ }
+
// Try to fold shifts into the addressing mode.
auto AddrModeFns = selectAddrModeShiftedExtendXReg(Root, SizeInBytes);
if (AddrModeFns)
@@ -5871,8 +5871,8 @@ void AArch64InstructionSelector::renderTruncImm(MachineInstrBuilder &MIB,
const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
"Expected G_CONSTANT");
- Optional<int64_t> CstVal =
- getConstantVRegSExtVal(MI.getOperand(0).getReg(), MRI);
+ Optional<int64_t> CstVal =
+ getConstantVRegSExtVal(MI.getOperand(0).getReg(), MRI);
assert(CstVal && "Expected constant value");
MIB.addImm(CstVal.getValue());
}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index af24267bf2..5a6c904e3f 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -14,7 +14,7 @@
#include "AArch64LegalizerInfo.h"
#include "AArch64Subtarget.h"
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
-#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
+#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/GlobalISel/Utils.h"
#include "llvm/CodeGen/MachineInstr.h"
@@ -23,8 +23,8 @@
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Type.h"
-#include <initializer_list>
-#include "llvm/Support/MathExtras.h"
+#include <initializer_list>
+#include "llvm/Support/MathExtras.h"
#define DEBUG_TYPE "aarch64-legalinfo"
@@ -56,13 +56,13 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
const LLT v2s64 = LLT::vector(2, 64);
const LLT v2p0 = LLT::vector(2, p0);
- std::initializer_list<LLT> PackedVectorAllTypeList = {/* Begin 128bit types */
- v16s8, v8s16, v4s32,
- v2s64, v2p0,
- /* End 128bit types */
- /* Begin 64bit types */
- v8s8, v4s16, v2s32};
-
+ std::initializer_list<LLT> PackedVectorAllTypeList = {/* Begin 128bit types */
+ v16s8, v8s16, v4s32,
+ v2s64, v2p0,
+ /* End 128bit types */
+ /* Begin 64bit types */
+ v8s8, v4s16, v2s32};
+
const TargetMachine &TM = ST.getTargetLowering()->getTargetMachine();
// FIXME: support subtargets which have neon/fp-armv8 disabled.
@@ -71,31 +71,31 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
return;
}
- // Some instructions only support s16 if the subtarget has full 16-bit FP
- // support.
- const bool HasFP16 = ST.hasFullFP16();
- const LLT &MinFPScalar = HasFP16 ? s16 : s32;
-
+ // Some instructions only support s16 if the subtarget has full 16-bit FP
+ // support.
+ const bool HasFP16 = ST.hasFullFP16();
+ const LLT &MinFPScalar = HasFP16 ? s16 : s32;
+
getActionDefinitionsBuilder({G_IMPLICIT_DEF, G_FREEZE})
- .legalFor({p0, s1, s8, s16, s32, s64})
- .legalFor(PackedVectorAllTypeList)
- .clampScalar(0, s1, s64)
- .widenScalarToNextPow2(0, 8)
- .fewerElementsIf(
- [=](const LegalityQuery &Query) {
- return Query.Types[0].isVector() &&
- (Query.Types[0].getElementType() != s64 ||
- Query.Types[0].getNumElements() != 2);
- },
- [=](const LegalityQuery &Query) {
- LLT EltTy = Query.Types[0].getElementType();
- if (EltTy == s64)
- return std::make_pair(0, LLT::vector(2, 64));
- return std::make_pair(0, EltTy);
- });
-
- getActionDefinitionsBuilder(G_PHI).legalFor({p0, s16, s32, s64})
- .legalFor(PackedVectorAllTypeList)
+ .legalFor({p0, s1, s8, s16, s32, s64})
+ .legalFor(PackedVectorAllTypeList)
+ .clampScalar(0, s1, s64)
+ .widenScalarToNextPow2(0, 8)
+ .fewerElementsIf(
+ [=](const LegalityQuery &Query) {
+ return Query.Types[0].isVector() &&
+ (Query.Types[0].getElementType() != s64 ||
+ Query.Types[0].getNumElements() != 2);
+ },
+ [=](const LegalityQuery &Query) {
+ LLT EltTy = Query.Types[0].getElementType();
+ if (EltTy == s64)
+ return std::make_pair(0, LLT::vector(2, 64));
+ return std::make_pair(0, EltTy);
+ });
+
+ getActionDefinitionsBuilder(G_PHI).legalFor({p0, s16, s32, s64})
+ .legalFor(PackedVectorAllTypeList)
.clampScalar(0, s16, s64)
.widenScalarToNextPow2(0);
@@ -105,38 +105,38 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
.widenScalarToNextPow2(0);
getActionDefinitionsBuilder({G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR})
- .legalFor({s32, s64, v2s32, v4s32, v4s16, v8s16, v16s8, v8s8})
- .scalarizeIf(
- [=](const LegalityQuery &Query) {
- return Query.Opcode == G_MUL && Query.Types[0] == v2s64;
- },
- 0)
- .legalFor({v2s64})
+ .legalFor({s32, s64, v2s32, v4s32, v4s16, v8s16, v16s8, v8s8})
+ .scalarizeIf(
+ [=](const LegalityQuery &Query) {
+ return Query.Opcode == G_MUL && Query.Types[0] == v2s64;
+ },
+ 0)
+ .legalFor({v2s64})
.clampScalar(0, s32, s64)
.widenScalarToNextPow2(0)
.clampNumElements(0, v2s32, v4s32)
.clampNumElements(0, v2s64, v2s64)
.moreElementsToNextPow2(0);
- getActionDefinitionsBuilder({G_SHL, G_ASHR, G_LSHR})
+ getActionDefinitionsBuilder({G_SHL, G_ASHR, G_LSHR})
.customIf([=](const LegalityQuery &Query) {
const auto &SrcTy = Query.Types[0];
const auto &AmtTy = Query.Types[1];
return !SrcTy.isVector() && SrcTy.getSizeInBits() == 32 &&
AmtTy.getSizeInBits() == 32;
})
- .legalFor({
- {s32, s32},
- {s32, s64},
- {s64, s64},
- {v8s8, v8s8},
- {v16s8, v16s8},
- {v4s16, v4s16},
- {v8s16, v8s16},
- {v2s32, v2s32},
- {v4s32, v4s32},
- {v2s64, v2s64},
- })
+ .legalFor({
+ {s32, s32},
+ {s32, s64},
+ {s64, s64},
+ {v8s8, v8s8},
+ {v16s8, v16s8},
+ {v4s16, v4s16},
+ {v8s16, v8s16},
+ {v2s32, v2s32},
+ {v4s32, v4s32},
+ {v2s64, v2s64},
+ })
.clampScalar(1, s32, s64)
.clampScalar(0, s32, s64)
.widenScalarToNextPow2(0)
@@ -161,25 +161,25 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
getActionDefinitionsBuilder({G_SREM, G_UREM})
.lowerFor({s1, s8, s16, s32, s64});
- getActionDefinitionsBuilder({G_SMULO, G_UMULO}).lowerFor({{s64, s1}});
+ getActionDefinitionsBuilder({G_SMULO, G_UMULO}).lowerFor({{s64, s1}});
getActionDefinitionsBuilder({G_SMULH, G_UMULH}).legalFor({s32, s64});
- getActionDefinitionsBuilder(
- {G_UADDE, G_USUBE, G_SADDO, G_SSUBO, G_UADDO, G_USUBO})
+ getActionDefinitionsBuilder(
+ {G_UADDE, G_USUBE, G_SADDO, G_SSUBO, G_UADDO, G_USUBO})
.legalFor({{s32, s1}, {s64, s1}})
.minScalar(0, s32);
getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FNEG})
- .legalFor({s32, s64, v2s64, v4s32, v2s32})
- .clampNumElements(0, v2s32, v4s32)
- .clampNumElements(0, v2s64, v2s64);
+ .legalFor({s32, s64, v2s64, v4s32, v2s32})
+ .clampNumElements(0, v2s32, v4s32)
+ .clampNumElements(0, v2s64, v2s64);
getActionDefinitionsBuilder(G_FREM).libcallFor({s32, s64});
getActionDefinitionsBuilder({G_FCEIL, G_FABS, G_FSQRT, G_FFLOOR, G_FRINT,
G_FMA, G_INTRINSIC_TRUNC, G_INTRINSIC_ROUND,
- G_FNEARBYINT, G_INTRINSIC_LRINT})
+ G_FNEARBYINT, G_INTRINSIC_LRINT})
// If we don't have full FP16 support, then scalarize the elements of
// vectors containing fp16 types.
.fewerElementsIf(
@@ -285,7 +285,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
{v4s32, p0, 128, 8},
{v2s64, p0, 128, 8}})
// These extends are also legal
- .legalForTypesWithMemDesc({{s32, p0, 8, 8}, {s32, p0, 16, 8}})
+ .legalForTypesWithMemDesc({{s32, p0, 8, 8}, {s32, p0, 16, 8}})
.clampScalar(0, s8, s64)
.lowerIfMemSizeNotPow2()
// Lower any any-extending loads left into G_ANYEXT and G_LOAD
@@ -307,7 +307,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
{p0, p0, 64, 8},
{s128, p0, 128, 8},
{v16s8, p0, 128, 8},
- {v8s8, p0, 64, 8},
+ {v8s8, p0, 64, 8},
{v4s16, p0, 64, 8},
{v8s16, p0, 128, 8},
{v2s32, p0, 64, 8},
@@ -325,19 +325,19 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
// Constants
getActionDefinitionsBuilder(G_CONSTANT)
- .legalFor({p0, s8, s16, s32, s64})
+ .legalFor({p0, s8, s16, s32, s64})
.clampScalar(0, s8, s64)
.widenScalarToNextPow2(0);
getActionDefinitionsBuilder(G_FCONSTANT)
- .legalIf([=](const LegalityQuery &Query) {
- const auto &Ty = Query.Types[0];
- if (HasFP16 && Ty == s16)
- return true;
- return Ty == s32 || Ty == s64 || Ty == s128;
- })
- .clampScalar(0, MinFPScalar, s128);
-
- getActionDefinitionsBuilder({G_ICMP, G_FCMP})
+ .legalIf([=](const LegalityQuery &Query) {
+ const auto &Ty = Query.Types[0];
+ if (HasFP16 && Ty == s16)
+ return true;
+ return Ty == s32 || Ty == s64 || Ty == s128;
+ })
+ .clampScalar(0, MinFPScalar, s128);
+
+ getActionDefinitionsBuilder({G_ICMP, G_FCMP})
.legalFor({{s32, s32},
{s32, s64},
{s32, p0},
@@ -365,8 +365,8 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
.minScalarOrEltIf(
[=](const LegalityQuery &Query) { return Query.Types[1] == v2p0; }, 0,
s64)
- .widenScalarOrEltToNextPow2(1)
- .clampNumElements(0, v2s32, v4s32);
+ .widenScalarOrEltToNextPow2(1)
+ .clampNumElements(0, v2s32, v4s32);
// Extensions
auto ExtLegalFunc = [=](const LegalityQuery &Query) {
@@ -374,7 +374,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
if (DstSize == 128 && !Query.Types[0].isVector())
return false; // Extending to a scalar s128 needs narrowing.
-
+
// Make sure that we have something that will fit in a register, and
// make sure it's a power of 2.
if (DstSize < 8 || DstSize > 128 || !isPowerOf2_32(DstSize))
@@ -399,28 +399,28 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
.legalIf(ExtLegalFunc)
.clampScalar(0, s64, s64); // Just for s128, others are handled above.
- getActionDefinitionsBuilder(G_TRUNC)
- .minScalarOrEltIf(
- [=](const LegalityQuery &Query) { return Query.Types[0].isVector(); },
- 0, s8)
- .customIf([=](const LegalityQuery &Query) {
- LLT DstTy = Query.Types[0];
- LLT SrcTy = Query.Types[1];
- return DstTy == v8s8 && SrcTy.getSizeInBits() > 128;
- })
- .alwaysLegal();
+ getActionDefinitionsBuilder(G_TRUNC)
+ .minScalarOrEltIf(
+ [=](const LegalityQuery &Query) { return Query.Types[0].isVector(); },
+ 0, s8)
+ .customIf([=](const LegalityQuery &Query) {
+ LLT DstTy = Query.Types[0];
+ LLT SrcTy = Query.Types[1];
+ return DstTy == v8s8 && SrcTy.getSizeInBits() > 128;
+ })
+ .alwaysLegal();
- getActionDefinitionsBuilder(G_SEXT_INREG).legalFor({s32, s64}).lower();
+ getActionDefinitionsBuilder(G_SEXT_INREG).legalFor({s32, s64}).lower();
// FP conversions
- getActionDefinitionsBuilder(G_FPTRUNC)
- .legalFor(
- {{s16, s32}, {s16, s64}, {s32, s64}, {v4s16, v4s32}, {v2s32, v2s64}})
- .clampMaxNumElements(0, s32, 2);
- getActionDefinitionsBuilder(G_FPEXT)
- .legalFor(
- {{s32, s16}, {s64, s16}, {s64, s32}, {v4s32, v4s16}, {v2s64, v2s32}})
- .clampMaxNumElements(0, s64, 2);
+ getActionDefinitionsBuilder(G_FPTRUNC)
+ .legalFor(
+ {{s16, s32}, {s16, s64}, {s32, s64}, {v4s16, v4s32}, {v2s32, v2s64}})
+ .clampMaxNumElements(0, s32, 2);
+ getActionDefinitionsBuilder(G_FPEXT)
+ .legalFor(
+ {{s32, s16}, {s64, s16}, {s64, s32}, {v4s32, v4s16}, {v2s64, v2s32}})
+ .clampMaxNumElements(0, s64, 2);
// Conversions
getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
@@ -433,7 +433,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
.legalForCartesianProduct({s32, s64, v2s64, v4s32, v2s32})
.clampScalar(1, s32, s64)
- .minScalarSameAs(1, 0)
+ .minScalarSameAs(1, 0)
.clampScalar(0, s32, s64)
.widenScalarToNextPow2(0);
@@ -445,8 +445,8 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
.legalFor({{s32, s1}, {s64, s1}, {p0, s1}})
.clampScalar(0, s32, s64)
.widenScalarToNextPow2(0)
- .minScalarEltSameAsIf(all(isVector(0), isVector(1)), 1, 0)
- .lowerIf(isVector(0));
+ .minScalarEltSameAsIf(all(isVector(0), isVector(1)), 1, 0)
+ .lowerIf(isVector(0));
// Pointer-handling
getActionDefinitionsBuilder(G_FRAME_INDEX).legalFor({p0});
@@ -576,8 +576,8 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
return BigTy.getSizeInBits() % LitTy.getSizeInBits() == 0;
})
// Any vectors left are the wrong size. Scalarize them.
- .scalarize(0)
- .scalarize(1);
+ .scalarize(0)
+ .scalarize(1);
}
getActionDefinitionsBuilder(G_EXTRACT_VECTOR_ELT)
@@ -589,40 +589,40 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
.legalIf([=](const LegalityQuery &Query) {
const LLT &VecTy = Query.Types[1];
return VecTy == v2s16 || VecTy == v4s16 || VecTy == v8s16 ||
- VecTy == v4s32 || VecTy == v2s64 || VecTy == v2s32 ||
- VecTy == v16s8 || VecTy == v2s32 || VecTy == v2p0;
- })
- .minScalarOrEltIf(
- [=](const LegalityQuery &Query) {
- // We want to promote to <M x s1> to <M x s64> if that wouldn't
- // cause the total vec size to be > 128b.
- return Query.Types[1].getNumElements() <= 2;
- },
- 0, s64)
- .minScalarOrEltIf(
- [=](const LegalityQuery &Query) {
- return Query.Types[1].getNumElements() <= 4;
- },
- 0, s32)
- .minScalarOrEltIf(
- [=](const LegalityQuery &Query) {
- return Query.Types[1].getNumElements() <= 8;
- },
- 0, s16)
- .minScalarOrEltIf(
- [=](const LegalityQuery &Query) {
- return Query.Types[1].getNumElements() <= 16;
- },
- 0, s8)
- .minScalarOrElt(0, s8); // Worst case, we need at least s8.
+ VecTy == v4s32 || VecTy == v2s64 || VecTy == v2s32 ||
+ VecTy == v16s8 || VecTy == v2s32 || VecTy == v2p0;
+ })
+ .minScalarOrEltIf(
+ [=](const LegalityQuery &Query) {
+ // We want to promote to <M x s1> to <M x s64> if that wouldn't
+ // cause the total vec size to be > 128b.
+ return Query.Types[1].getNumElements() <= 2;
+ },
+ 0, s64)
+ .minScalarOrEltIf(
+ [=](const LegalityQuery &Query) {
+ return Query.Types[1].getNumElements() <= 4;
+ },
+ 0, s32)
+ .minScalarOrEltIf(
+ [=](const LegalityQuery &Query) {
+ return Query.Types[1].getNumElements() <= 8;
+ },
+ 0, s16)
+ .minScalarOrEltIf(
+ [=](const LegalityQuery &Query) {
+ return Query.Types[1].getNumElements() <= 16;
+ },
+ 0, s8)
+ .minScalarOrElt(0, s8); // Worst case, we need at least s8.
getActionDefinitionsBuilder(G_INSERT_VECTOR_ELT)
- .legalIf(typeInSet(0, {v8s16, v2s32, v4s32, v2s64}));
+ .legalIf(typeInSet(0, {v8s16, v2s32, v4s32, v2s64}));
getActionDefinitionsBuilder(G_BUILD_VECTOR)
- .legalFor({{v8s8, s8},
- {v16s8, s8},
- {v4s16, s16},
+ .legalFor({{v8s8, s8},
+ {v16s8, s8},
+ {v4s16, s16},
{v8s16, s16},
{v2s32, s32},
{v4s32, s32},
@@ -638,9 +638,9 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
})
.minScalarSameAs(1, 0);
- getActionDefinitionsBuilder(G_CTLZ)
- .legalForCartesianProduct(
- {s32, s64, v8s8, v16s8, v4s16, v8s16, v2s32, v4s32})
+ getActionDefinitionsBuilder(G_CTLZ)
+ .legalForCartesianProduct(
+ {s32, s64, v8s8, v16s8, v4s16, v8s16, v2s32, v4s32})
.scalarize(1);
getActionDefinitionsBuilder(G_SHUFFLE_VECTOR)
@@ -651,7 +651,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
// to be the same size as the dest.
if (DstTy != SrcTy)
return false;
- for (auto &Ty : {v2s32, v4s32, v2s64, v2p0, v16s8, v8s16}) {
+ for (auto &Ty : {v2s32, v4s32, v2s64, v2p0, v16s8, v8s16}) {
if (DstTy == Ty)
return true;
}
@@ -668,7 +668,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
getActionDefinitionsBuilder(G_CONCAT_VECTORS)
.legalFor({{v4s32, v2s32}, {v8s16, v4s16}});
- getActionDefinitionsBuilder(G_JUMP_TABLE).legalFor({{p0}, {s64}});
+ getActionDefinitionsBuilder(G_JUMP_TABLE).legalFor({{p0}, {s64}});
getActionDefinitionsBuilder(G_BRJT).legalIf([=](const LegalityQuery &Query) {
return Query.Types[0] == p0 && Query.Types[1] == s64;
@@ -676,20 +676,20 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
getActionDefinitionsBuilder(G_DYN_STACKALLOC).lower();
- getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE, G_MEMSET}).libcall();
-
- getActionDefinitionsBuilder(G_ABS).lowerIf(
- [=](const LegalityQuery &Query) { return Query.Types[0].isScalar(); });
-
- getActionDefinitionsBuilder(G_VECREDUCE_FADD)
- // We only have FADDP to do reduction-like operations. Lower the rest.
- .legalFor({{s32, v2s32}, {s64, v2s64}})
- .lower();
-
- getActionDefinitionsBuilder(G_VECREDUCE_ADD)
- .legalFor({{s8, v16s8}, {s16, v8s16}, {s32, v4s32}, {s64, v2s64}})
- .lower();
-
+ getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE, G_MEMSET}).libcall();
+
+ getActionDefinitionsBuilder(G_ABS).lowerIf(
+ [=](const LegalityQuery &Query) { return Query.Types[0].isScalar(); });
+
+ getActionDefinitionsBuilder(G_VECREDUCE_FADD)
+ // We only have FADDP to do reduction-like operations. Lower the rest.
+ .legalFor({{s32, v2s32}, {s64, v2s64}})
+ .lower();
+
+ getActionDefinitionsBuilder(G_VECREDUCE_ADD)
+ .legalFor({{s8, v16s8}, {s16, v8s16}, {s32, v4s32}, {s64, v2s64}})
+ .lower();
+
computeTables();
verify(*ST.getInstrInfo());
}
@@ -714,63 +714,63 @@ bool AArch64LegalizerInfo::legalizeCustom(LegalizerHelper &Helper,
return legalizeShlAshrLshr(MI, MRI, MIRBuilder, Observer);
case TargetOpcode::G_GLOBAL_VALUE:
return legalizeSmallCMGlobalValue(MI, MRI, MIRBuilder, Observer);
- case TargetOpcode::G_TRUNC:
- return legalizeVectorTrunc(MI, Helper);
+ case TargetOpcode::G_TRUNC:
+ return legalizeVectorTrunc(MI, Helper);
}
llvm_unreachable("expected switch to return");
}
-static void extractParts(Register Reg, MachineRegisterInfo &MRI,
- MachineIRBuilder &MIRBuilder, LLT Ty, int NumParts,
- SmallVectorImpl<Register> &VRegs) {
- for (int I = 0; I < NumParts; ++I)
- VRegs.push_back(MRI.createGenericVirtualRegister(Ty));
- MIRBuilder.buildUnmerge(VRegs, Reg);
-}
-
-bool AArch64LegalizerInfo::legalizeVectorTrunc(
- MachineInstr &MI, LegalizerHelper &Helper) const {
- MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
- MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
- // Similar to how operand splitting is done in SelectiondDAG, we can handle
- // %res(v8s8) = G_TRUNC %in(v8s32) by generating:
- // %inlo(<4x s32>), %inhi(<4 x s32>) = G_UNMERGE %in(<8 x s32>)
- // %lo16(<4 x s16>) = G_TRUNC %inlo
- // %hi16(<4 x s16>) = G_TRUNC %inhi
- // %in16(<8 x s16>) = G_CONCAT_VECTORS %lo16, %hi16
- // %res(<8 x s8>) = G_TRUNC %in16
-
- Register DstReg = MI.getOperand(0).getReg();
- Register SrcReg = MI.getOperand(1).getReg();
- LLT DstTy = MRI.getType(DstReg);
- LLT SrcTy = MRI.getType(SrcReg);
- assert(isPowerOf2_32(DstTy.getSizeInBits()) &&
- isPowerOf2_32(SrcTy.getSizeInBits()));
-
- // Split input type.
- LLT SplitSrcTy = SrcTy.changeNumElements(SrcTy.getNumElements() / 2);
- // First, split the source into two smaller vectors.
- SmallVector<Register, 2> SplitSrcs;
- extractParts(SrcReg, MRI, MIRBuilder, SplitSrcTy, 2, SplitSrcs);
-
- // Truncate the splits into intermediate narrower elements.
- LLT InterTy = SplitSrcTy.changeElementSize(DstTy.getScalarSizeInBits() * 2);
- for (unsigned I = 0; I < SplitSrcs.size(); ++I)
- SplitSrcs[I] = MIRBuilder.buildTrunc(InterTy, SplitSrcs[I]).getReg(0);
-
- auto Concat = MIRBuilder.buildConcatVectors(
- DstTy.changeElementSize(DstTy.getScalarSizeInBits() * 2), SplitSrcs);
-
- Helper.Observer.changingInstr(MI);
- MI.getOperand(1).setReg(Concat.getReg(0));
- Helper.Observer.changedInstr(MI);
- return true;
-}
-
-bool AArch64LegalizerInfo::legalizeSmallCMGlobalValue(
- MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &MIRBuilder,
- GISelChangeObserver &Observer) const {
+static void extractParts(Register Reg, MachineRegisterInfo &MRI,
+ MachineIRBuilder &MIRBuilder, LLT Ty, int NumParts,
+ SmallVectorImpl<Register> &VRegs) {
+ for (int I = 0; I < NumParts; ++I)
+ VRegs.push_back(MRI.createGenericVirtualRegister(Ty));
+ MIRBuilder.buildUnmerge(VRegs, Reg);
+}
+
+bool AArch64LegalizerInfo::legalizeVectorTrunc(
+ MachineInstr &MI, LegalizerHelper &Helper) const {
+ MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
+ MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
+ // Similar to how operand splitting is done in SelectiondDAG, we can handle
+ // %res(v8s8) = G_TRUNC %in(v8s32) by generating:
+ // %inlo(<4x s32>), %inhi(<4 x s32>) = G_UNMERGE %in(<8 x s32>)
+ // %lo16(<4 x s16>) = G_TRUNC %inlo
+ // %hi16(<4 x s16>) = G_TRUNC %inhi
+ // %in16(<8 x s16>) = G_CONCAT_VECTORS %lo16, %hi16
+ // %res(<8 x s8>) = G_TRUNC %in16
+
+ Register DstReg = MI.getOperand(0).getReg();
+ Register SrcReg = MI.getOperand(1).getReg();
+ LLT DstTy = MRI.getType(DstReg);
+ LLT SrcTy = MRI.getType(SrcReg);
+ assert(isPowerOf2_32(DstTy.getSizeInBits()) &&
+ isPowerOf2_32(SrcTy.getSizeInBits()));
+
+ // Split input type.
+ LLT SplitSrcTy = SrcTy.changeNumElements(SrcTy.getNumElements() / 2);
+ // First, split the source into two smaller vectors.
+ SmallVector<Register, 2> SplitSrcs;
+ extractParts(SrcReg, MRI, MIRBuilder, SplitSrcTy, 2, SplitSrcs);
+
+ // Truncate the splits into intermediate narrower elements.
+ LLT InterTy = SplitSrcTy.changeElementSize(DstTy.getScalarSizeInBits() * 2);
+ for (unsigned I = 0; I < SplitSrcs.size(); ++I)
+ SplitSrcs[I] = MIRBuilder.buildTrunc(InterTy, SplitSrcs[I]).getReg(0);
+
+ auto Concat = MIRBuilder.buildConcatVectors(
+ DstTy.changeElementSize(DstTy.getScalarSizeInBits() * 2), SplitSrcs);
+
+ Helper.Observer.changingInstr(MI);
+ MI.getOperand(1).setReg(Concat.getReg(0));
+ Helper.Observer.changedInstr(MI);
+ return true;
+}
+
+bool AArch64LegalizerInfo::legalizeSmallCMGlobalValue(
+ MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &MIRBuilder,
+ GISelChangeObserver &Observer) const {
assert(MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE);
// We do this custom legalization to convert G_GLOBAL_VALUE into target ADRP +
// G_ADD_LOW instructions.
@@ -792,27 +792,27 @@ bool AArch64LegalizerInfo::legalizeSmallCMGlobalValue(
// Set the regclass on the dest reg too.
MRI.setRegClass(ADRP.getReg(0), &AArch64::GPR64RegClass);
- // MO_TAGGED on the page indicates a tagged address. Set the tag now. We do so
- // by creating a MOVK that sets bits 48-63 of the register to (global address
- // + 0x100000000 - PC) >> 48. The additional 0x100000000 offset here is to
- // prevent an incorrect tag being generated during relocation when the the
- // global appears before the code section. Without the offset, a global at
- // `0x0f00'0000'0000'1000` (i.e. at `0x1000` with tag `0xf`) that's referenced
- // by code at `0x2000` would result in `0x0f00'0000'0000'1000 - 0x2000 =
- // 0x0eff'ffff'ffff'f000`, meaning the tag would be incorrectly set to `0xe`
- // instead of `0xf`.
- // This assumes that we're in the small code model so we can assume a binary
- // size of <= 4GB, which makes the untagged PC relative offset positive. The
- // binary must also be loaded into address range [0, 2^48). Both of these
- // properties need to be ensured at runtime when using tagged addresses.
- if (OpFlags & AArch64II::MO_TAGGED) {
- ADRP = MIRBuilder.buildInstr(AArch64::MOVKXi, {LLT::pointer(0, 64)}, {ADRP})
- .addGlobalAddress(GV, 0x100000000,
- AArch64II::MO_PREL | AArch64II::MO_G3)
- .addImm(48);
- MRI.setRegClass(ADRP.getReg(0), &AArch64::GPR64RegClass);
- }
-
+ // MO_TAGGED on the page indicates a tagged address. Set the tag now. We do so
+ // by creating a MOVK that sets bits 48-63 of the register to (global address
+ // + 0x100000000 - PC) >> 48. The additional 0x100000000 offset here is to
+ // prevent an incorrect tag being generated during relocation when the the
+ // global appears before the code section. Without the offset, a global at
+ // `0x0f00'0000'0000'1000` (i.e. at `0x1000` with tag `0xf`) that's referenced
+ // by code at `0x2000` would result in `0x0f00'0000'0000'1000 - 0x2000 =
+ // 0x0eff'ffff'ffff'f000`, meaning the tag would be incorrectly set to `0xe`
+ // instead of `0xf`.
+ // This assumes that we're in the small code model so we can assume a binary
+ // size of <= 4GB, which makes the untagged PC relative offset positive. The
+ // binary must also be loaded into address range [0, 2^48). Both of these
+ // properties need to be ensured at runtime when using tagged addresses.
+ if (OpFlags & AArch64II::MO_TAGGED) {
+ ADRP = MIRBuilder.buildInstr(AArch64::MOVKXi, {LLT::pointer(0, 64)}, {ADRP})
+ .addGlobalAddress(GV, 0x100000000,
+ AArch64II::MO_PREL | AArch64II::MO_G3)
+ .addImm(48);
+ MRI.setRegClass(ADRP.getReg(0), &AArch64::GPR64RegClass);
+ }
+
MIRBuilder.buildInstr(AArch64::G_ADD_LOW, {DstReg}, {ADRP})
.addGlobalAddress(GV, 0,
OpFlags | AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
@@ -820,8 +820,8 @@ bool AArch64LegalizerInfo::legalizeSmallCMGlobalValue(
return true;
}
-bool AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
- MachineInstr &MI) const {
+bool AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
+ MachineInstr &MI) const {
return true;
}
@@ -838,13 +838,13 @@ bool AArch64LegalizerInfo::legalizeShlAshrLshr(
if (!VRegAndVal)
return true;
// Check the shift amount is in range for an immediate form.
- int64_t Amount = VRegAndVal->Value.getSExtValue();
+ int64_t Amount = VRegAndVal->Value.getSExtValue();
if (Amount > 31)
return true; // This will have to remain a register variant.
auto ExtCst = MIRBuilder.buildConstant(LLT::scalar(64), Amount);
- Observer.changingInstr(MI);
+ Observer.changingInstr(MI);
MI.getOperand(2).setReg(ExtCst.getReg(0));
- Observer.changedInstr(MI);
+ Observer.changedInstr(MI);
return true;
}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h
index c22cb26608..8217e37c85 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h
+++ b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h
@@ -15,7 +15,7 @@
#define LLVM_LIB_TARGET_AARCH64_AARCH64MACHINELEGALIZER_H
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
-#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
+#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
namespace llvm {
@@ -46,7 +46,7 @@ private:
bool legalizeSmallCMGlobalValue(MachineInstr &MI, MachineRegisterInfo &MRI,
MachineIRBuilder &MIRBuilder,
GISelChangeObserver &Observer) const;
- bool legalizeVectorTrunc(MachineInstr &MI, LegalizerHelper &Helper) const;
+ bool legalizeVectorTrunc(MachineInstr &MI, LegalizerHelper &Helper) const;
const AArch64Subtarget *ST;
};
} // End llvm namespace.
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp
index bf3190ce93..fdd04cb77f 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp
@@ -1,22 +1,22 @@
-//=== AArch64PostLegalizerCombiner.cpp --------------------------*- C++ -*-===//
+//=== AArch64PostLegalizerCombiner.cpp --------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-///
-/// \file
-/// Post-legalization combines on generic MachineInstrs.
-///
-/// The combines here must preserve instruction legality.
-///
-/// Lowering combines (e.g. pseudo matching) should be handled by
-/// AArch64PostLegalizerLowering.
-///
-/// Combines which don't rely on instruction legality should go in the
-/// AArch64PreLegalizerCombiner.
-///
+///
+/// \file
+/// Post-legalization combines on generic MachineInstrs.
+///
+/// The combines here must preserve instruction legality.
+///
+/// Lowering combines (e.g. pseudo matching) should be handled by
+/// AArch64PostLegalizerLowering.
+///
+/// Combines which don't rely on instruction legality should go in the
+/// AArch64PreLegalizerCombiner.
+///
//===----------------------------------------------------------------------===//
#include "AArch64TargetMachine.h"
@@ -24,12 +24,12 @@
#include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
#include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
-#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
-#include "llvm/CodeGen/GlobalISel/Utils.h"
+#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+#include "llvm/CodeGen/GlobalISel/Utils.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/TargetOpcodes.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/Support/Debug.h"
@@ -37,202 +37,202 @@
using namespace llvm;
-/// This combine tries do what performExtractVectorEltCombine does in SDAG.
-/// Rewrite for pairwise fadd pattern
-/// (s32 (g_extract_vector_elt
-/// (g_fadd (vXs32 Other)
-/// (g_vector_shuffle (vXs32 Other) undef <1,X,...> )) 0))
-/// ->
-/// (s32 (g_fadd (g_extract_vector_elt (vXs32 Other) 0)
-/// (g_extract_vector_elt (vXs32 Other) 1))
-bool matchExtractVecEltPairwiseAdd(
- MachineInstr &MI, MachineRegisterInfo &MRI,
- std::tuple<unsigned, LLT, Register> &MatchInfo) {
- Register Src1 = MI.getOperand(1).getReg();
- Register Src2 = MI.getOperand(2).getReg();
- LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
-
- auto Cst = getConstantVRegValWithLookThrough(Src2, MRI);
- if (!Cst || Cst->Value != 0)
+/// This combine tries do what performExtractVectorEltCombine does in SDAG.
+/// Rewrite for pairwise fadd pattern
+/// (s32 (g_extract_vector_elt
+/// (g_fadd (vXs32 Other)
+/// (g_vector_shuffle (vXs32 Other) undef <1,X,...> )) 0))
+/// ->
+/// (s32 (g_fadd (g_extract_vector_elt (vXs32 Other) 0)
+/// (g_extract_vector_elt (vXs32 Other) 1))
+bool matchExtractVecEltPairwiseAdd(
+ MachineInstr &MI, MachineRegisterInfo &MRI,
+ std::tuple<unsigned, LLT, Register> &MatchInfo) {
+ Register Src1 = MI.getOperand(1).getReg();
+ Register Src2 = MI.getOperand(2).getReg();
+ LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
+
+ auto Cst = getConstantVRegValWithLookThrough(Src2, MRI);
+ if (!Cst || Cst->Value != 0)
return false;
- // SDAG also checks for FullFP16, but this looks to be beneficial anyway.
+ // SDAG also checks for FullFP16, but this looks to be beneficial anyway.
- // Now check for an fadd operation. TODO: expand this for integer add?
- auto *FAddMI = getOpcodeDef(TargetOpcode::G_FADD, Src1, MRI);
- if (!FAddMI)
+ // Now check for an fadd operation. TODO: expand this for integer add?
+ auto *FAddMI = getOpcodeDef(TargetOpcode::G_FADD, Src1, MRI);
+ if (!FAddMI)
return false;
- // If we add support for integer add, must restrict these types to just s64.
- unsigned DstSize = DstTy.getSizeInBits();
- if (DstSize != 16 && DstSize != 32 && DstSize != 64)
+ // If we add support for integer add, must restrict these types to just s64.
+ unsigned DstSize = DstTy.getSizeInBits();
+ if (DstSize != 16 && DstSize != 32 && DstSize != 64)
return false;
- Register Src1Op1 = FAddMI->getOperand(1).getReg();
- Register Src1Op2 = FAddMI->getOperand(2).getReg();
- MachineInstr *Shuffle =
- getOpcodeDef(TargetOpcode::G_SHUFFLE_VECTOR, Src1Op2, MRI);
- MachineInstr *Other = MRI.getVRegDef(Src1Op1);
- if (!Shuffle) {
- Shuffle = getOpcodeDef(TargetOpcode::G_SHUFFLE_VECTOR, Src1Op1, MRI);
- Other = MRI.getVRegDef(Src1Op2);
+ Register Src1Op1 = FAddMI->getOperand(1).getReg();
+ Register Src1Op2 = FAddMI->getOperand(2).getReg();
+ MachineInstr *Shuffle =
+ getOpcodeDef(TargetOpcode::G_SHUFFLE_VECTOR, Src1Op2, MRI);
+ MachineInstr *Other = MRI.getVRegDef(Src1Op1);
+ if (!Shuffle) {
+ Shuffle = getOpcodeDef(TargetOpcode::G_SHUFFLE_VECTOR, Src1Op1, MRI);
+ Other = MRI.getVRegDef(Src1Op2);
}
- // We're looking for a shuffle that moves the second element to index 0.
- if (Shuffle && Shuffle->getOperand(3).getShuffleMask()[0] == 1 &&
- Other == MRI.getVRegDef(Shuffle->getOperand(1).getReg())) {
- std::get<0>(MatchInfo) = TargetOpcode::G_FADD;
- std::get<1>(MatchInfo) = DstTy;
- std::get<2>(MatchInfo) = Other->getOperand(0).getReg();
+ // We're looking for a shuffle that moves the second element to index 0.
+ if (Shuffle && Shuffle->getOperand(3).getShuffleMask()[0] == 1 &&
+ Other == MRI.getVRegDef(Shuffle->getOperand(1).getReg())) {
+ std::get<0>(MatchInfo) = TargetOpcode::G_FADD;
+ std::get<1>(MatchInfo) = DstTy;
+ std::get<2>(MatchInfo) = Other->getOperand(0).getReg();
return true;
}
return false;
}
-bool applyExtractVecEltPairwiseAdd(
- MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B,
- std::tuple<unsigned, LLT, Register> &MatchInfo) {
- unsigned Opc = std::get<0>(MatchInfo);
- assert(Opc == TargetOpcode::G_FADD && "Unexpected opcode!");
- // We want to generate two extracts of elements 0 and 1, and add them.
- LLT Ty = std::get<1>(MatchInfo);
- Register Src = std::get<2>(MatchInfo);
- LLT s64 = LLT::scalar(64);
- B.setInstrAndDebugLoc(MI);
- auto Elt0 = B.buildExtractVectorElement(Ty, Src, B.buildConstant(s64, 0));
- auto Elt1 = B.buildExtractVectorElement(Ty, Src, B.buildConstant(s64, 1));
- B.buildInstr(Opc, {MI.getOperand(0).getReg()}, {Elt0, Elt1});
- MI.eraseFromParent();
+bool applyExtractVecEltPairwiseAdd(
+ MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B,
+ std::tuple<unsigned, LLT, Register> &MatchInfo) {
+ unsigned Opc = std::get<0>(MatchInfo);
+ assert(Opc == TargetOpcode::G_FADD && "Unexpected opcode!");
+ // We want to generate two extracts of elements 0 and 1, and add them.
+ LLT Ty = std::get<1>(MatchInfo);
+ Register Src = std::get<2>(MatchInfo);
+ LLT s64 = LLT::scalar(64);
+ B.setInstrAndDebugLoc(MI);
+ auto Elt0 = B.buildExtractVectorElement(Ty, Src, B.buildConstant(s64, 0));
+ auto Elt1 = B.buildExtractVectorElement(Ty, Src, B.buildConstant(s64, 1));
+ B.buildInstr(Opc, {MI.getOperand(0).getReg()}, {Elt0, Elt1});
+ MI.eraseFromParent();
return true;
}
-static bool isSignExtended(Register R, MachineRegisterInfo &MRI) {
- // TODO: check if extended build vector as well.
- unsigned Opc = MRI.getVRegDef(R)->getOpcode();
- return Opc == TargetOpcode::G_SEXT || Opc == TargetOpcode::G_SEXT_INREG;
+static bool isSignExtended(Register R, MachineRegisterInfo &MRI) {
+ // TODO: check if extended build vector as well.
+ unsigned Opc = MRI.getVRegDef(R)->getOpcode();
+ return Opc == TargetOpcode::G_SEXT || Opc == TargetOpcode::G_SEXT_INREG;
}
-static bool isZeroExtended(Register R, MachineRegisterInfo &MRI) {
- // TODO: check if extended build vector as well.
- return MRI.getVRegDef(R)->getOpcode() == TargetOpcode::G_ZEXT;
+static bool isZeroExtended(Register R, MachineRegisterInfo &MRI) {
+ // TODO: check if extended build vector as well.
+ return MRI.getVRegDef(R)->getOpcode() == TargetOpcode::G_ZEXT;
}
-bool matchAArch64MulConstCombine(
- MachineInstr &MI, MachineRegisterInfo &MRI,
- std::function<void(MachineIRBuilder &B, Register DstReg)> &ApplyFn) {
- assert(MI.getOpcode() == TargetOpcode::G_MUL);
- Register LHS = MI.getOperand(1).getReg();
- Register RHS = MI.getOperand(2).getReg();
- Register Dst = MI.getOperand(0).getReg();
- const LLT Ty = MRI.getType(LHS);
-
- // The below optimizations require a constant RHS.
- auto Const = getConstantVRegValWithLookThrough(RHS, MRI);
- if (!Const)
+bool matchAArch64MulConstCombine(
+ MachineInstr &MI, MachineRegisterInfo &MRI,
+ std::function<void(MachineIRBuilder &B, Register DstReg)> &ApplyFn) {
+ assert(MI.getOpcode() == TargetOpcode::G_MUL);
+ Register LHS = MI.getOperand(1).getReg();
+ Register RHS = MI.getOperand(2).getReg();
+ Register Dst = MI.getOperand(0).getReg();
+ const LLT Ty = MRI.getType(LHS);
+
+ // The below optimizations require a constant RHS.
+ auto Const = getConstantVRegValWithLookThrough(RHS, MRI);
+ if (!Const)
return false;
- const APInt ConstValue = Const->Value.sextOrSelf(Ty.getSizeInBits());
- // The following code is ported from AArch64ISelLowering.
- // Multiplication of a power of two plus/minus one can be done more
- // cheaply as as shift+add/sub. For now, this is true unilaterally. If
- // future CPUs have a cheaper MADD instruction, this may need to be
- // gated on a subtarget feature. For Cyclone, 32-bit MADD is 4 cycles and
- // 64-bit is 5 cycles, so this is always a win.
- // More aggressively, some multiplications N0 * C can be lowered to
- // shift+add+shift if the constant C = A * B where A = 2^N + 1 and B = 2^M,
- // e.g. 6=3*2=(2+1)*2.
- // TODO: consider lowering more cases, e.g. C = 14, -6, -14 or even 45
- // which equals to (1+2)*16-(1+2).
- // TrailingZeroes is used to test if the mul can be lowered to
- // shift+add+shift.
- unsigned TrailingZeroes = ConstValue.countTrailingZeros();
- if (TrailingZeroes) {
- // Conservatively do not lower to shift+add+shift if the mul might be
- // folded into smul or umul.
- if (MRI.hasOneNonDBGUse(LHS) &&
- (isSignExtended(LHS, MRI) || isZeroExtended(LHS, MRI)))
- return false;
- // Conservatively do not lower to shift+add+shift if the mul might be
- // folded into madd or msub.
- if (MRI.hasOneNonDBGUse(Dst)) {
- MachineInstr &UseMI = *MRI.use_instr_begin(Dst);
- if (UseMI.getOpcode() == TargetOpcode::G_ADD ||
- UseMI.getOpcode() == TargetOpcode::G_SUB)
- return false;
- }
- }
- // Use ShiftedConstValue instead of ConstValue to support both shift+add/sub
- // and shift+add+shift.
- APInt ShiftedConstValue = ConstValue.ashr(TrailingZeroes);
-
- unsigned ShiftAmt, AddSubOpc;
- // Is the shifted value the LHS operand of the add/sub?
- bool ShiftValUseIsLHS = true;
- // Do we need to negate the result?
- bool NegateResult = false;
-
- if (ConstValue.isNonNegative()) {
- // (mul x, 2^N + 1) => (add (shl x, N), x)
- // (mul x, 2^N - 1) => (sub (shl x, N), x)
- // (mul x, (2^N + 1) * 2^M) => (shl (add (shl x, N), x), M)
- APInt SCVMinus1 = ShiftedConstValue - 1;
- APInt CVPlus1 = ConstValue + 1;
- if (SCVMinus1.isPowerOf2()) {
- ShiftAmt = SCVMinus1.logBase2();
- AddSubOpc = TargetOpcode::G_ADD;
- } else if (CVPlus1.isPowerOf2()) {
- ShiftAmt = CVPlus1.logBase2();
- AddSubOpc = TargetOpcode::G_SUB;
- } else
- return false;
- } else {
- // (mul x, -(2^N - 1)) => (sub x, (shl x, N))
- // (mul x, -(2^N + 1)) => - (add (shl x, N), x)
- APInt CVNegPlus1 = -ConstValue + 1;
- APInt CVNegMinus1 = -ConstValue - 1;
- if (CVNegPlus1.isPowerOf2()) {
- ShiftAmt = CVNegPlus1.logBase2();
- AddSubOpc = TargetOpcode::G_SUB;
- ShiftValUseIsLHS = false;
- } else if (CVNegMinus1.isPowerOf2()) {
- ShiftAmt = CVNegMinus1.logBase2();
- AddSubOpc = TargetOpcode::G_ADD;
- NegateResult = true;
- } else
- return false;
- }
-
- if (NegateResult && TrailingZeroes)
+ const APInt ConstValue = Const->Value.sextOrSelf(Ty.getSizeInBits());
+ // The following code is ported from AArch64ISelLowering.
+ // Multiplication of a power of two plus/minus one can be done more
+ // cheaply as as shift+add/sub. For now, this is true unilaterally. If
+ // future CPUs have a cheaper MADD instruction, this may need to be
+ // gated on a subtarget feature. For Cyclone, 32-bit MADD is 4 cycles and
+ // 64-bit is 5 cycles, so this is always a win.
+ // More aggressively, some multiplications N0 * C can be lowered to
+ // shift+add+shift if the constant C = A * B where A = 2^N + 1 and B = 2^M,
+ // e.g. 6=3*2=(2+1)*2.
+ // TODO: consider lowering more cases, e.g. C = 14, -6, -14 or even 45
+ // which equals to (1+2)*16-(1+2).
+ // TrailingZeroes is used to test if the mul can be lowered to
+ // shift+add+shift.
+ unsigned TrailingZeroes = ConstValue.countTrailingZeros();
+ if (TrailingZeroes) {
+ // Conservatively do not lower to shift+add+shift if the mul might be
+ // folded into smul or umul.
+ if (MRI.hasOneNonDBGUse(LHS) &&
+ (isSignExtended(LHS, MRI) || isZeroExtended(LHS, MRI)))
+ return false;
+ // Conservatively do not lower to shift+add+shift if the mul might be
+ // folded into madd or msub.
+ if (MRI.hasOneNonDBGUse(Dst)) {
+ MachineInstr &UseMI = *MRI.use_instr_begin(Dst);
+ if (UseMI.getOpcode() == TargetOpcode::G_ADD ||
+ UseMI.getOpcode() == TargetOpcode::G_SUB)
+ return false;
+ }
+ }
+ // Use ShiftedConstValue instead of ConstValue to support both shift+add/sub
+ // and shift+add+shift.
+ APInt ShiftedConstValue = ConstValue.ashr(TrailingZeroes);
+
+ unsigned ShiftAmt, AddSubOpc;
+ // Is the shifted value the LHS operand of the add/sub?
+ bool ShiftValUseIsLHS = true;
+ // Do we need to negate the result?
+ bool NegateResult = false;
+
+ if (ConstValue.isNonNegative()) {
+ // (mul x, 2^N + 1) => (add (shl x, N), x)
+ // (mul x, 2^N - 1) => (sub (shl x, N), x)
+ // (mul x, (2^N + 1) * 2^M) => (shl (add (shl x, N), x), M)
+ APInt SCVMinus1 = ShiftedConstValue - 1;
+ APInt CVPlus1 = ConstValue + 1;
+ if (SCVMinus1.isPowerOf2()) {
+ ShiftAmt = SCVMinus1.logBase2();
+ AddSubOpc = TargetOpcode::G_ADD;
+ } else if (CVPlus1.isPowerOf2()) {
+ ShiftAmt = CVPlus1.logBase2();
+ AddSubOpc = TargetOpcode::G_SUB;
+ } else
+ return false;
+ } else {
+ // (mul x, -(2^N - 1)) => (sub x, (shl x, N))
+ // (mul x, -(2^N + 1)) => - (add (shl x, N), x)
+ APInt CVNegPlus1 = -ConstValue + 1;
+ APInt CVNegMinus1 = -ConstValue - 1;
+ if (CVNegPlus1.isPowerOf2()) {
+ ShiftAmt = CVNegPlus1.logBase2();
+ AddSubOpc = TargetOpcode::G_SUB;
+ ShiftValUseIsLHS = false;
+ } else if (CVNegMinus1.isPowerOf2()) {
+ ShiftAmt = CVNegMinus1.logBase2();
+ AddSubOpc = TargetOpcode::G_ADD;
+ NegateResult = true;
+ } else
+ return false;
+ }
+
+ if (NegateResult && TrailingZeroes)
return false;
- ApplyFn = [=](MachineIRBuilder &B, Register DstReg) {
- auto Shift = B.buildConstant(LLT::scalar(64), ShiftAmt);
- auto ShiftedVal = B.buildShl(Ty, LHS, Shift);
-
- Register AddSubLHS = ShiftValUseIsLHS ? ShiftedVal.getReg(0) : LHS;
- Register AddSubRHS = ShiftValUseIsLHS ? LHS : ShiftedVal.getReg(0);
- auto Res = B.buildInstr(AddSubOpc, {Ty}, {AddSubLHS, AddSubRHS});
- assert(!(NegateResult && TrailingZeroes) &&
- "NegateResult and TrailingZeroes cannot both be true for now.");
- // Negate the result.
- if (NegateResult) {
- B.buildSub(DstReg, B.buildConstant(Ty, 0), Res);
- return;
- }
- // Shift the result.
- if (TrailingZeroes) {
- B.buildShl(DstReg, Res, B.buildConstant(LLT::scalar(64), TrailingZeroes));
- return;
- }
- B.buildCopy(DstReg, Res.getReg(0));
- };
+ ApplyFn = [=](MachineIRBuilder &B, Register DstReg) {
+ auto Shift = B.buildConstant(LLT::scalar(64), ShiftAmt);
+ auto ShiftedVal = B.buildShl(Ty, LHS, Shift);
+
+ Register AddSubLHS = ShiftValUseIsLHS ? ShiftedVal.getReg(0) : LHS;
+ Register AddSubRHS = ShiftValUseIsLHS ? LHS : ShiftedVal.getReg(0);
+ auto Res = B.buildInstr(AddSubOpc, {Ty}, {AddSubLHS, AddSubRHS});
+ assert(!(NegateResult && TrailingZeroes) &&
+ "NegateResult and TrailingZeroes cannot both be true for now.");
+ // Negate the result.
+ if (NegateResult) {
+ B.buildSub(DstReg, B.buildConstant(Ty, 0), Res);
+ return;
+ }
+ // Shift the result.
+ if (TrailingZeroes) {
+ B.buildShl(DstReg, Res, B.buildConstant(LLT::scalar(64), TrailingZeroes));
+ return;
+ }
+ B.buildCopy(DstReg, Res.getReg(0));
+ };
return true;
}
-bool applyAArch64MulConstCombine(
- MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B,
- std::function<void(MachineIRBuilder &B, Register DstReg)> &ApplyFn) {
- B.setInstrAndDebugLoc(MI);
- ApplyFn(B, MI.getOperand(0).getReg());
+bool applyAArch64MulConstCombine(
+ MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B,
+ std::function<void(MachineIRBuilder &B, Register DstReg)> &ApplyFn) {
+ B.setInstrAndDebugLoc(MI);
+ ApplyFn(B, MI.getOperand(0).getReg());
MI.eraseFromParent();
return true;
}
@@ -348,7 +348,7 @@ INITIALIZE_PASS_END(AArch64PostLegalizerCombiner, DEBUG_TYPE,
false)
namespace llvm {
-FunctionPass *createAArch64PostLegalizerCombiner(bool IsOptNone) {
+FunctionPass *createAArch64PostLegalizerCombiner(bool IsOptNone) {
return new AArch64PostLegalizerCombiner(IsOptNone);
}
} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
index 0447c3e8a0..a06ff4b541 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
@@ -1,704 +1,704 @@
-//=== AArch64PostLegalizerLowering.cpp --------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// Post-legalization lowering for instructions.
-///
-/// This is used to offload pattern matching from the selector.
-///
-/// For example, this combiner will notice that a G_SHUFFLE_VECTOR is actually
-/// a G_ZIP, G_UZP, etc.
-///
-/// General optimization combines should be handled by either the
-/// AArch64PostLegalizerCombiner or the AArch64PreLegalizerCombiner.
-///
-//===----------------------------------------------------------------------===//
-
-#include "AArch64TargetMachine.h"
-#include "AArch64GlobalISelUtils.h"
-#include "MCTargetDesc/AArch64MCTargetDesc.h"
-#include "llvm/CodeGen/GlobalISel/Combiner.h"
-#include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
-#include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
-#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
-#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
-#include "llvm/CodeGen/GlobalISel/Utils.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/TargetOpcodes.h"
-#include "llvm/CodeGen/TargetPassConfig.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Support/Debug.h"
-
-#define DEBUG_TYPE "aarch64-postlegalizer-lowering"
-
-using namespace llvm;
-using namespace MIPatternMatch;
-using namespace AArch64GISelUtils;
-
-/// Represents a pseudo instruction which replaces a G_SHUFFLE_VECTOR.
-///
-/// Used for matching target-supported shuffles before codegen.
-struct ShuffleVectorPseudo {
- unsigned Opc; ///< Opcode for the instruction. (E.g. G_ZIP1)
- Register Dst; ///< Destination register.
- SmallVector<SrcOp, 2> SrcOps; ///< Source registers.
- ShuffleVectorPseudo(unsigned Opc, Register Dst,
- std::initializer_list<SrcOp> SrcOps)
- : Opc(Opc), Dst(Dst), SrcOps(SrcOps){};
- ShuffleVectorPseudo() {}
-};
-
-/// Check if a vector shuffle corresponds to a REV instruction with the
-/// specified blocksize.
-static bool isREVMask(ArrayRef<int> M, unsigned EltSize, unsigned NumElts,
- unsigned BlockSize) {
- assert((BlockSize == 16 || BlockSize == 32 || BlockSize == 64) &&
- "Only possible block sizes for REV are: 16, 32, 64");
- assert(EltSize != 64 && "EltSize cannot be 64 for REV mask.");
-
- unsigned BlockElts = M[0] + 1;
-
- // If the first shuffle index is UNDEF, be optimistic.
- if (M[0] < 0)
- BlockElts = BlockSize / EltSize;
-
- if (BlockSize <= EltSize || BlockSize != BlockElts * EltSize)
- return false;
-
- for (unsigned i = 0; i < NumElts; ++i) {
- // Ignore undef indices.
- if (M[i] < 0)
- continue;
- if (static_cast<unsigned>(M[i]) !=
- (i - i % BlockElts) + (BlockElts - 1 - i % BlockElts))
- return false;
- }
-
- return true;
-}
-
-/// Determines if \p M is a shuffle vector mask for a TRN of \p NumElts.
-/// Whether or not G_TRN1 or G_TRN2 should be used is stored in \p WhichResult.
-static bool isTRNMask(ArrayRef<int> M, unsigned NumElts,
- unsigned &WhichResult) {
- if (NumElts % 2 != 0)
- return false;
- WhichResult = (M[0] == 0 ? 0 : 1);
- for (unsigned i = 0; i < NumElts; i += 2) {
- if ((M[i] >= 0 && static_cast<unsigned>(M[i]) != i + WhichResult) ||
- (M[i + 1] >= 0 &&
- static_cast<unsigned>(M[i + 1]) != i + NumElts + WhichResult))
- return false;
- }
- return true;
-}
-
-/// Check if a G_EXT instruction can handle a shuffle mask \p M when the vector
-/// sources of the shuffle are different.
-static Optional<std::pair<bool, uint64_t>> getExtMask(ArrayRef<int> M,
- unsigned NumElts) {
- // Look for the first non-undef element.
- auto FirstRealElt = find_if(M, [](int Elt) { return Elt >= 0; });
- if (FirstRealElt == M.end())
- return None;
-
- // Use APInt to handle overflow when calculating expected element.
- unsigned MaskBits = APInt(32, NumElts * 2).logBase2();
- APInt ExpectedElt = APInt(MaskBits, *FirstRealElt + 1);
-
- // The following shuffle indices must be the successive elements after the
- // first real element.
- if (any_of(
- make_range(std::next(FirstRealElt), M.end()),
- [&ExpectedElt](int Elt) { return Elt != ExpectedElt++ && Elt >= 0; }))
- return None;
-
- // The index of an EXT is the first element if it is not UNDEF.
- // Watch out for the beginning UNDEFs. The EXT index should be the expected
- // value of the first element. E.g.
- // <-1, -1, 3, ...> is treated as <1, 2, 3, ...>.
- // <-1, -1, 0, 1, ...> is treated as <2*NumElts-2, 2*NumElts-1, 0, 1, ...>.
- // ExpectedElt is the last mask index plus 1.
- uint64_t Imm = ExpectedElt.getZExtValue();
- bool ReverseExt = false;
-
- // There are two difference cases requiring to reverse input vectors.
- // For example, for vector <4 x i32> we have the following cases,
- // Case 1: shufflevector(<4 x i32>,<4 x i32>,<-1, -1, -1, 0>)
- // Case 2: shufflevector(<4 x i32>,<4 x i32>,<-1, -1, 7, 0>)
- // For both cases, we finally use mask <5, 6, 7, 0>, which requires
- // to reverse two input vectors.
- if (Imm < NumElts)
- ReverseExt = true;
- else
- Imm -= NumElts;
- return std::make_pair(ReverseExt, Imm);
-}
-
-/// Determines if \p M is a shuffle vector mask for a UZP of \p NumElts.
-/// Whether or not G_UZP1 or G_UZP2 should be used is stored in \p WhichResult.
-static bool isUZPMask(ArrayRef<int> M, unsigned NumElts,
- unsigned &WhichResult) {
- WhichResult = (M[0] == 0 ? 0 : 1);
- for (unsigned i = 0; i != NumElts; ++i) {
- // Skip undef indices.
- if (M[i] < 0)
- continue;
- if (static_cast<unsigned>(M[i]) != 2 * i + WhichResult)
- return false;
- }
- return true;
-}
-
-/// \return true if \p M is a zip mask for a shuffle vector of \p NumElts.
-/// Whether or not G_ZIP1 or G_ZIP2 should be used is stored in \p WhichResult.
-static bool isZipMask(ArrayRef<int> M, unsigned NumElts,
- unsigned &WhichResult) {
- if (NumElts % 2 != 0)
- return false;
-
- // 0 means use ZIP1, 1 means use ZIP2.
- WhichResult = (M[0] == 0 ? 0 : 1);
- unsigned Idx = WhichResult * NumElts / 2;
- for (unsigned i = 0; i != NumElts; i += 2) {
- if ((M[i] >= 0 && static_cast<unsigned>(M[i]) != Idx) ||
- (M[i + 1] >= 0 && static_cast<unsigned>(M[i + 1]) != Idx + NumElts))
- return false;
- Idx += 1;
- }
- return true;
-}
-
-/// \return true if a G_SHUFFLE_VECTOR instruction \p MI can be replaced with a
-/// G_REV instruction. Returns the appropriate G_REV opcode in \p Opc.
-static bool matchREV(MachineInstr &MI, MachineRegisterInfo &MRI,
- ShuffleVectorPseudo &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
- ArrayRef<int> ShuffleMask = MI.getOperand(3).getShuffleMask();
- Register Dst = MI.getOperand(0).getReg();
- Register Src = MI.getOperand(1).getReg();
- LLT Ty = MRI.getType(Dst);
- unsigned EltSize = Ty.getScalarSizeInBits();
-
- // Element size for a rev cannot be 64.
- if (EltSize == 64)
- return false;
-
- unsigned NumElts = Ty.getNumElements();
-
- // Try to produce G_REV64
- if (isREVMask(ShuffleMask, EltSize, NumElts, 64)) {
- MatchInfo = ShuffleVectorPseudo(AArch64::G_REV64, Dst, {Src});
- return true;
- }
-
- // TODO: Produce G_REV32 and G_REV16 once we have proper legalization support.
- // This should be identical to above, but with a constant 32 and constant
- // 16.
- return false;
-}
-
-/// \return true if a G_SHUFFLE_VECTOR instruction \p MI can be replaced with
-/// a G_TRN1 or G_TRN2 instruction.
-static bool matchTRN(MachineInstr &MI, MachineRegisterInfo &MRI,
- ShuffleVectorPseudo &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
- unsigned WhichResult;
- ArrayRef<int> ShuffleMask = MI.getOperand(3).getShuffleMask();
- Register Dst = MI.getOperand(0).getReg();
- unsigned NumElts = MRI.getType(Dst).getNumElements();
- if (!isTRNMask(ShuffleMask, NumElts, WhichResult))
- return false;
- unsigned Opc = (WhichResult == 0) ? AArch64::G_TRN1 : AArch64::G_TRN2;
- Register V1 = MI.getOperand(1).getReg();
- Register V2 = MI.getOperand(2).getReg();
- MatchInfo = ShuffleVectorPseudo(Opc, Dst, {V1, V2});
- return true;
-}
-
-/// \return true if a G_SHUFFLE_VECTOR instruction \p MI can be replaced with
-/// a G_UZP1 or G_UZP2 instruction.
-///
-/// \param [in] MI - The shuffle vector instruction.
-/// \param [out] MatchInfo - Either G_UZP1 or G_UZP2 on success.
-static bool matchUZP(MachineInstr &MI, MachineRegisterInfo &MRI,
- ShuffleVectorPseudo &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
- unsigned WhichResult;
- ArrayRef<int> ShuffleMask = MI.getOperand(3).getShuffleMask();
- Register Dst = MI.getOperand(0).getReg();
- unsigned NumElts = MRI.getType(Dst).getNumElements();
- if (!isUZPMask(ShuffleMask, NumElts, WhichResult))
- return false;
- unsigned Opc = (WhichResult == 0) ? AArch64::G_UZP1 : AArch64::G_UZP2;
- Register V1 = MI.getOperand(1).getReg();
- Register V2 = MI.getOperand(2).getReg();
- MatchInfo = ShuffleVectorPseudo(Opc, Dst, {V1, V2});
- return true;
-}
-
-static bool matchZip(MachineInstr &MI, MachineRegisterInfo &MRI,
- ShuffleVectorPseudo &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
- unsigned WhichResult;
- ArrayRef<int> ShuffleMask = MI.getOperand(3).getShuffleMask();
- Register Dst = MI.getOperand(0).getReg();
- unsigned NumElts = MRI.getType(Dst).getNumElements();
- if (!isZipMask(ShuffleMask, NumElts, WhichResult))
- return false;
- unsigned Opc = (WhichResult == 0) ? AArch64::G_ZIP1 : AArch64::G_ZIP2;
- Register V1 = MI.getOperand(1).getReg();
- Register V2 = MI.getOperand(2).getReg();
- MatchInfo = ShuffleVectorPseudo(Opc, Dst, {V1, V2});
- return true;
-}
-
-/// Helper function for matchDup.
-static bool matchDupFromInsertVectorElt(int Lane, MachineInstr &MI,
- MachineRegisterInfo &MRI,
- ShuffleVectorPseudo &MatchInfo) {
- if (Lane != 0)
- return false;
-
- // Try to match a vector splat operation into a dup instruction.
- // We're looking for this pattern:
- //
- // %scalar:gpr(s64) = COPY $x0
- // %undef:fpr(<2 x s64>) = G_IMPLICIT_DEF
- // %cst0:gpr(s32) = G_CONSTANT i32 0
- // %zerovec:fpr(<2 x s32>) = G_BUILD_VECTOR %cst0(s32), %cst0(s32)
- // %ins:fpr(<2 x s64>) = G_INSERT_VECTOR_ELT %undef, %scalar(s64), %cst0(s32)
- // %splat:fpr(<2 x s64>) = G_SHUFFLE_VECTOR %ins(<2 x s64>), %undef, %zerovec(<2 x s32>)
- //
- // ...into:
- // %splat = G_DUP %scalar
-
- // Begin matching the insert.
- auto *InsMI = getOpcodeDef(TargetOpcode::G_INSERT_VECTOR_ELT,
- MI.getOperand(1).getReg(), MRI);
- if (!InsMI)
- return false;
- // Match the undef vector operand.
- if (!getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, InsMI->getOperand(1).getReg(),
- MRI))
- return false;
-
- // Match the index constant 0.
- if (!mi_match(InsMI->getOperand(3).getReg(), MRI, m_ZeroInt()))
- return false;
-
- MatchInfo = ShuffleVectorPseudo(AArch64::G_DUP, MI.getOperand(0).getReg(),
- {InsMI->getOperand(2).getReg()});
- return true;
-}
-
-/// Helper function for matchDup.
-static bool matchDupFromBuildVector(int Lane, MachineInstr &MI,
- MachineRegisterInfo &MRI,
- ShuffleVectorPseudo &MatchInfo) {
- assert(Lane >= 0 && "Expected positive lane?");
- // Test if the LHS is a BUILD_VECTOR. If it is, then we can just reference the
- // lane's definition directly.
- auto *BuildVecMI = getOpcodeDef(TargetOpcode::G_BUILD_VECTOR,
- MI.getOperand(1).getReg(), MRI);
- if (!BuildVecMI)
- return false;
- Register Reg = BuildVecMI->getOperand(Lane + 1).getReg();
- MatchInfo =
- ShuffleVectorPseudo(AArch64::G_DUP, MI.getOperand(0).getReg(), {Reg});
- return true;
-}
-
-static bool matchDup(MachineInstr &MI, MachineRegisterInfo &MRI,
- ShuffleVectorPseudo &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
- auto MaybeLane = getSplatIndex(MI);
- if (!MaybeLane)
- return false;
- int Lane = *MaybeLane;
- // If this is undef splat, generate it via "just" vdup, if possible.
- if (Lane < 0)
- Lane = 0;
- if (matchDupFromInsertVectorElt(Lane, MI, MRI, MatchInfo))
- return true;
- if (matchDupFromBuildVector(Lane, MI, MRI, MatchInfo))
- return true;
- return false;
-}
-
-static bool matchEXT(MachineInstr &MI, MachineRegisterInfo &MRI,
- ShuffleVectorPseudo &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
- Register Dst = MI.getOperand(0).getReg();
- auto ExtInfo = getExtMask(MI.getOperand(3).getShuffleMask(),
- MRI.getType(Dst).getNumElements());
- if (!ExtInfo)
- return false;
- bool ReverseExt;
- uint64_t Imm;
- std::tie(ReverseExt, Imm) = *ExtInfo;
- Register V1 = MI.getOperand(1).getReg();
- Register V2 = MI.getOperand(2).getReg();
- if (ReverseExt)
- std::swap(V1, V2);
- uint64_t ExtFactor = MRI.getType(V1).getScalarSizeInBits() / 8;
- Imm *= ExtFactor;
- MatchInfo = ShuffleVectorPseudo(AArch64::G_EXT, Dst, {V1, V2, Imm});
- return true;
-}
-
-/// Replace a G_SHUFFLE_VECTOR instruction with a pseudo.
-/// \p Opc is the opcode to use. \p MI is the G_SHUFFLE_VECTOR.
-static bool applyShuffleVectorPseudo(MachineInstr &MI,
- ShuffleVectorPseudo &MatchInfo) {
- MachineIRBuilder MIRBuilder(MI);
- MIRBuilder.buildInstr(MatchInfo.Opc, {MatchInfo.Dst}, MatchInfo.SrcOps);
- MI.eraseFromParent();
- return true;
-}
-
-/// Replace a G_SHUFFLE_VECTOR instruction with G_EXT.
-/// Special-cased because the constant operand must be emitted as a G_CONSTANT
-/// for the imported tablegen patterns to work.
-static bool applyEXT(MachineInstr &MI, ShuffleVectorPseudo &MatchInfo) {
- MachineIRBuilder MIRBuilder(MI);
- // Tablegen patterns expect an i32 G_CONSTANT as the final op.
- auto Cst =
- MIRBuilder.buildConstant(LLT::scalar(32), MatchInfo.SrcOps[2].getImm());
- MIRBuilder.buildInstr(MatchInfo.Opc, {MatchInfo.Dst},
- {MatchInfo.SrcOps[0], MatchInfo.SrcOps[1], Cst});
- MI.eraseFromParent();
- return true;
-}
-
-/// isVShiftRImm - Check if this is a valid vector for the immediate
-/// operand of a vector shift right operation. The value must be in the range:
-/// 1 <= Value <= ElementBits for a right shift.
-static bool isVShiftRImm(Register Reg, MachineRegisterInfo &MRI, LLT Ty,
- int64_t &Cnt) {
- assert(Ty.isVector() && "vector shift count is not a vector type");
- MachineInstr *MI = MRI.getVRegDef(Reg);
- auto Cst = getBuildVectorConstantSplat(*MI, MRI);
- if (!Cst)
- return false;
- Cnt = *Cst;
- int64_t ElementBits = Ty.getScalarSizeInBits();
- return Cnt >= 1 && Cnt <= ElementBits;
-}
-
-/// Match a vector G_ASHR or G_LSHR with a valid immediate shift.
-static bool matchVAshrLshrImm(MachineInstr &MI, MachineRegisterInfo &MRI,
- int64_t &Imm) {
- assert(MI.getOpcode() == TargetOpcode::G_ASHR ||
- MI.getOpcode() == TargetOpcode::G_LSHR);
- LLT Ty = MRI.getType(MI.getOperand(1).getReg());
- if (!Ty.isVector())
- return false;
- return isVShiftRImm(MI.getOperand(2).getReg(), MRI, Ty, Imm);
-}
-
-static bool applyVAshrLshrImm(MachineInstr &MI, MachineRegisterInfo &MRI,
- int64_t &Imm) {
- unsigned Opc = MI.getOpcode();
- assert(Opc == TargetOpcode::G_ASHR || Opc == TargetOpcode::G_LSHR);
- unsigned NewOpc =
- Opc == TargetOpcode::G_ASHR ? AArch64::G_VASHR : AArch64::G_VLSHR;
- MachineIRBuilder MIB(MI);
- auto ImmDef = MIB.buildConstant(LLT::scalar(32), Imm);
- MIB.buildInstr(NewOpc, {MI.getOperand(0)}, {MI.getOperand(1), ImmDef});
- MI.eraseFromParent();
- return true;
-}
-
-/// Determine if it is possible to modify the \p RHS and predicate \p P of a
-/// G_ICMP instruction such that the right-hand side is an arithmetic immediate.
-///
-/// \returns A pair containing the updated immediate and predicate which may
-/// be used to optimize the instruction.
-///
-/// \note This assumes that the comparison has been legalized.
-Optional<std::pair<uint64_t, CmpInst::Predicate>>
-tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
- const MachineRegisterInfo &MRI) {
- const auto &Ty = MRI.getType(RHS);
- if (Ty.isVector())
- return None;
- unsigned Size = Ty.getSizeInBits();
- assert((Size == 32 || Size == 64) && "Expected 32 or 64 bit compare only?");
-
- // If the RHS is not a constant, or the RHS is already a valid arithmetic
- // immediate, then there is nothing to change.
- auto ValAndVReg = getConstantVRegValWithLookThrough(RHS, MRI);
- if (!ValAndVReg)
- return None;
- uint64_t C = ValAndVReg->Value.getZExtValue();
- if (isLegalArithImmed(C))
- return None;
-
- // We have a non-arithmetic immediate. Check if adjusting the immediate and
- // adjusting the predicate will result in a legal arithmetic immediate.
- switch (P) {
- default:
- return None;
- case CmpInst::ICMP_SLT:
- case CmpInst::ICMP_SGE:
- // Check for
- //
- // x slt c => x sle c - 1
- // x sge c => x sgt c - 1
- //
- // When c is not the smallest possible negative number.
- if ((Size == 64 && static_cast<int64_t>(C) == INT64_MIN) ||
- (Size == 32 && static_cast<int32_t>(C) == INT32_MIN))
- return None;
- P = (P == CmpInst::ICMP_SLT) ? CmpInst::ICMP_SLE : CmpInst::ICMP_SGT;
- C -= 1;
- break;
- case CmpInst::ICMP_ULT:
- case CmpInst::ICMP_UGE:
- // Check for
- //
- // x ult c => x ule c - 1
- // x uge c => x ugt c - 1
- //
- // When c is not zero.
- if (C == 0)
- return None;
- P = (P == CmpInst::ICMP_ULT) ? CmpInst::ICMP_ULE : CmpInst::ICMP_UGT;
- C -= 1;
- break;
- case CmpInst::ICMP_SLE:
- case CmpInst::ICMP_SGT:
- // Check for
- //
- // x sle c => x slt c + 1
- // x sgt c => s sge c + 1
- //
- // When c is not the largest possible signed integer.
- if ((Size == 32 && static_cast<int32_t>(C) == INT32_MAX) ||
- (Size == 64 && static_cast<int64_t>(C) == INT64_MAX))
- return None;
- P = (P == CmpInst::ICMP_SLE) ? CmpInst::ICMP_SLT : CmpInst::ICMP_SGE;
- C += 1;
- break;
- case CmpInst::ICMP_ULE:
- case CmpInst::ICMP_UGT:
- // Check for
- //
- // x ule c => x ult c + 1
- // x ugt c => s uge c + 1
- //
- // When c is not the largest possible unsigned integer.
- if ((Size == 32 && static_cast<uint32_t>(C) == UINT32_MAX) ||
- (Size == 64 && C == UINT64_MAX))
- return None;
- P = (P == CmpInst::ICMP_ULE) ? CmpInst::ICMP_ULT : CmpInst::ICMP_UGE;
- C += 1;
- break;
- }
-
- // Check if the new constant is valid, and return the updated constant and
- // predicate if it is.
- if (Size == 32)
- C = static_cast<uint32_t>(C);
- if (!isLegalArithImmed(C))
- return None;
- return {{C, P}};
-}
-
-/// Determine whether or not it is possible to update the RHS and predicate of
-/// a G_ICMP instruction such that the RHS will be selected as an arithmetic
-/// immediate.
-///
-/// \p MI - The G_ICMP instruction
-/// \p MatchInfo - The new RHS immediate and predicate on success
-///
-/// See tryAdjustICmpImmAndPred for valid transformations.
-bool matchAdjustICmpImmAndPred(
- MachineInstr &MI, const MachineRegisterInfo &MRI,
- std::pair<uint64_t, CmpInst::Predicate> &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_ICMP);
- Register RHS = MI.getOperand(3).getReg();
- auto Pred = static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
- if (auto MaybeNewImmAndPred = tryAdjustICmpImmAndPred(RHS, Pred, MRI)) {
- MatchInfo = *MaybeNewImmAndPred;
- return true;
- }
- return false;
-}
-
-bool applyAdjustICmpImmAndPred(
- MachineInstr &MI, std::pair<uint64_t, CmpInst::Predicate> &MatchInfo,
- MachineIRBuilder &MIB, GISelChangeObserver &Observer) {
- MIB.setInstrAndDebugLoc(MI);
- MachineOperand &RHS = MI.getOperand(3);
- MachineRegisterInfo &MRI = *MIB.getMRI();
- auto Cst = MIB.buildConstant(MRI.cloneVirtualRegister(RHS.getReg()),
- MatchInfo.first);
- Observer.changingInstr(MI);
- RHS.setReg(Cst->getOperand(0).getReg());
- MI.getOperand(1).setPredicate(MatchInfo.second);
- Observer.changedInstr(MI);
- return true;
-}
-
-bool matchDupLane(MachineInstr &MI, MachineRegisterInfo &MRI,
- std::pair<unsigned, int> &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
- Register Src1Reg = MI.getOperand(1).getReg();
- const LLT SrcTy = MRI.getType(Src1Reg);
- const LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
-
- auto LaneIdx = getSplatIndex(MI);
- if (!LaneIdx)
- return false;
-
- // The lane idx should be within the first source vector.
- if (*LaneIdx >= SrcTy.getNumElements())
- return false;
-
- if (DstTy != SrcTy)
- return false;
-
- LLT ScalarTy = SrcTy.getElementType();
- unsigned ScalarSize = ScalarTy.getSizeInBits();
-
- unsigned Opc = 0;
- switch (SrcTy.getNumElements()) {
- case 2:
- if (ScalarSize == 64)
- Opc = AArch64::G_DUPLANE64;
- break;
- case 4:
- if (ScalarSize == 32)
- Opc = AArch64::G_DUPLANE32;
- break;
- case 8:
- if (ScalarSize == 16)
- Opc = AArch64::G_DUPLANE16;
- break;
- case 16:
- if (ScalarSize == 8)
- Opc = AArch64::G_DUPLANE8;
- break;
- default:
- break;
- }
- if (!Opc)
- return false;
-
- MatchInfo.first = Opc;
- MatchInfo.second = *LaneIdx;
- return true;
-}
-
-bool applyDupLane(MachineInstr &MI, MachineRegisterInfo &MRI,
- MachineIRBuilder &B, std::pair<unsigned, int> &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
- B.setInstrAndDebugLoc(MI);
- auto Lane = B.buildConstant(LLT::scalar(64), MatchInfo.second);
- B.buildInstr(MatchInfo.first, {MI.getOperand(0).getReg()},
- {MI.getOperand(1).getReg(), Lane});
- MI.eraseFromParent();
- return true;
-}
-
-#define AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_DEPS
-#include "AArch64GenPostLegalizeGILowering.inc"
-#undef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_DEPS
-
-namespace {
-#define AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_H
-#include "AArch64GenPostLegalizeGILowering.inc"
-#undef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_H
-
-class AArch64PostLegalizerLoweringInfo : public CombinerInfo {
-public:
- AArch64GenPostLegalizerLoweringHelperRuleConfig GeneratedRuleCfg;
-
- AArch64PostLegalizerLoweringInfo(bool OptSize, bool MinSize)
- : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
- /*LegalizerInfo*/ nullptr, /*OptEnabled = */ true, OptSize,
- MinSize) {
- if (!GeneratedRuleCfg.parseCommandLineOption())
- report_fatal_error("Invalid rule identifier");
- }
-
- virtual bool combine(GISelChangeObserver &Observer, MachineInstr &MI,
- MachineIRBuilder &B) const override;
-};
-
-bool AArch64PostLegalizerLoweringInfo::combine(GISelChangeObserver &Observer,
- MachineInstr &MI,
- MachineIRBuilder &B) const {
- CombinerHelper Helper(Observer, B);
- AArch64GenPostLegalizerLoweringHelper Generated(GeneratedRuleCfg);
- return Generated.tryCombineAll(Observer, MI, B, Helper);
-}
-
-#define AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_CPP
-#include "AArch64GenPostLegalizeGILowering.inc"
-#undef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_CPP
-
-class AArch64PostLegalizerLowering : public MachineFunctionPass {
-public:
- static char ID;
-
- AArch64PostLegalizerLowering();
-
- StringRef getPassName() const override {
- return "AArch64PostLegalizerLowering";
- }
-
- bool runOnMachineFunction(MachineFunction &MF) override;
- void getAnalysisUsage(AnalysisUsage &AU) const override;
-};
-} // end anonymous namespace
-
-void AArch64PostLegalizerLowering::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<TargetPassConfig>();
- AU.setPreservesCFG();
- getSelectionDAGFallbackAnalysisUsage(AU);
- MachineFunctionPass::getAnalysisUsage(AU);
-}
-
-AArch64PostLegalizerLowering::AArch64PostLegalizerLowering()
- : MachineFunctionPass(ID) {
- initializeAArch64PostLegalizerLoweringPass(*PassRegistry::getPassRegistry());
-}
-
-bool AArch64PostLegalizerLowering::runOnMachineFunction(MachineFunction &MF) {
- if (MF.getProperties().hasProperty(
- MachineFunctionProperties::Property::FailedISel))
- return false;
- assert(MF.getProperties().hasProperty(
- MachineFunctionProperties::Property::Legalized) &&
- "Expected a legalized function?");
- auto *TPC = &getAnalysis<TargetPassConfig>();
- const Function &F = MF.getFunction();
- AArch64PostLegalizerLoweringInfo PCInfo(F.hasOptSize(), F.hasMinSize());
- Combiner C(PCInfo, TPC);
- return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr);
-}
-
-char AArch64PostLegalizerLowering::ID = 0;
-INITIALIZE_PASS_BEGIN(AArch64PostLegalizerLowering, DEBUG_TYPE,
- "Lower AArch64 MachineInstrs after legalization", false,
- false)
-INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
-INITIALIZE_PASS_END(AArch64PostLegalizerLowering, DEBUG_TYPE,
- "Lower AArch64 MachineInstrs after legalization", false,
- false)
-
-namespace llvm {
-FunctionPass *createAArch64PostLegalizerLowering() {
- return new AArch64PostLegalizerLowering();
-}
-} // end namespace llvm
+//=== AArch64PostLegalizerLowering.cpp --------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Post-legalization lowering for instructions.
+///
+/// This is used to offload pattern matching from the selector.
+///
+/// For example, this combiner will notice that a G_SHUFFLE_VECTOR is actually
+/// a G_ZIP, G_UZP, etc.
+///
+/// General optimization combines should be handled by either the
+/// AArch64PostLegalizerCombiner or the AArch64PreLegalizerCombiner.
+///
+//===----------------------------------------------------------------------===//
+
+#include "AArch64TargetMachine.h"
+#include "AArch64GlobalISelUtils.h"
+#include "MCTargetDesc/AArch64MCTargetDesc.h"
+#include "llvm/CodeGen/GlobalISel/Combiner.h"
+#include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
+#include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
+#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
+#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+#include "llvm/CodeGen/GlobalISel/Utils.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/TargetOpcodes.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "aarch64-postlegalizer-lowering"
+
+using namespace llvm;
+using namespace MIPatternMatch;
+using namespace AArch64GISelUtils;
+
+/// Represents a pseudo instruction which replaces a G_SHUFFLE_VECTOR.
+///
+/// Used for matching target-supported shuffles before codegen.
+struct ShuffleVectorPseudo {
+ unsigned Opc; ///< Opcode for the instruction. (E.g. G_ZIP1)
+ Register Dst; ///< Destination register.
+ SmallVector<SrcOp, 2> SrcOps; ///< Source registers.
+ ShuffleVectorPseudo(unsigned Opc, Register Dst,
+ std::initializer_list<SrcOp> SrcOps)
+ : Opc(Opc), Dst(Dst), SrcOps(SrcOps){};
+ ShuffleVectorPseudo() {}
+};
+
+/// Check if a vector shuffle corresponds to a REV instruction with the
+/// specified blocksize.
+static bool isREVMask(ArrayRef<int> M, unsigned EltSize, unsigned NumElts,
+ unsigned BlockSize) {
+ assert((BlockSize == 16 || BlockSize == 32 || BlockSize == 64) &&
+ "Only possible block sizes for REV are: 16, 32, 64");
+ assert(EltSize != 64 && "EltSize cannot be 64 for REV mask.");
+
+ unsigned BlockElts = M[0] + 1;
+
+ // If the first shuffle index is UNDEF, be optimistic.
+ if (M[0] < 0)
+ BlockElts = BlockSize / EltSize;
+
+ if (BlockSize <= EltSize || BlockSize != BlockElts * EltSize)
+ return false;
+
+ for (unsigned i = 0; i < NumElts; ++i) {
+ // Ignore undef indices.
+ if (M[i] < 0)
+ continue;
+ if (static_cast<unsigned>(M[i]) !=
+ (i - i % BlockElts) + (BlockElts - 1 - i % BlockElts))
+ return false;
+ }
+
+ return true;
+}
+
+/// Determines if \p M is a shuffle vector mask for a TRN of \p NumElts.
+/// Whether or not G_TRN1 or G_TRN2 should be used is stored in \p WhichResult.
+static bool isTRNMask(ArrayRef<int> M, unsigned NumElts,
+ unsigned &WhichResult) {
+ if (NumElts % 2 != 0)
+ return false;
+ WhichResult = (M[0] == 0 ? 0 : 1);
+ for (unsigned i = 0; i < NumElts; i += 2) {
+ if ((M[i] >= 0 && static_cast<unsigned>(M[i]) != i + WhichResult) ||
+ (M[i + 1] >= 0 &&
+ static_cast<unsigned>(M[i + 1]) != i + NumElts + WhichResult))
+ return false;
+ }
+ return true;
+}
+
+/// Check if a G_EXT instruction can handle a shuffle mask \p M when the vector
+/// sources of the shuffle are different.
+static Optional<std::pair<bool, uint64_t>> getExtMask(ArrayRef<int> M,
+ unsigned NumElts) {
+ // Look for the first non-undef element.
+ auto FirstRealElt = find_if(M, [](int Elt) { return Elt >= 0; });
+ if (FirstRealElt == M.end())
+ return None;
+
+ // Use APInt to handle overflow when calculating expected element.
+ unsigned MaskBits = APInt(32, NumElts * 2).logBase2();
+ APInt ExpectedElt = APInt(MaskBits, *FirstRealElt + 1);
+
+ // The following shuffle indices must be the successive elements after the
+ // first real element.
+ if (any_of(
+ make_range(std::next(FirstRealElt), M.end()),
+ [&ExpectedElt](int Elt) { return Elt != ExpectedElt++ && Elt >= 0; }))
+ return None;
+
+ // The index of an EXT is the first element if it is not UNDEF.
+ // Watch out for the beginning UNDEFs. The EXT index should be the expected
+ // value of the first element. E.g.
+ // <-1, -1, 3, ...> is treated as <1, 2, 3, ...>.
+ // <-1, -1, 0, 1, ...> is treated as <2*NumElts-2, 2*NumElts-1, 0, 1, ...>.
+ // ExpectedElt is the last mask index plus 1.
+ uint64_t Imm = ExpectedElt.getZExtValue();
+ bool ReverseExt = false;
+
+ // There are two difference cases requiring to reverse input vectors.
+ // For example, for vector <4 x i32> we have the following cases,
+ // Case 1: shufflevector(<4 x i32>,<4 x i32>,<-1, -1, -1, 0>)
+ // Case 2: shufflevector(<4 x i32>,<4 x i32>,<-1, -1, 7, 0>)
+ // For both cases, we finally use mask <5, 6, 7, 0>, which requires
+ // to reverse two input vectors.
+ if (Imm < NumElts)
+ ReverseExt = true;
+ else
+ Imm -= NumElts;
+ return std::make_pair(ReverseExt, Imm);
+}
+
+/// Determines if \p M is a shuffle vector mask for a UZP of \p NumElts.
+/// Whether or not G_UZP1 or G_UZP2 should be used is stored in \p WhichResult.
+static bool isUZPMask(ArrayRef<int> M, unsigned NumElts,
+ unsigned &WhichResult) {
+ WhichResult = (M[0] == 0 ? 0 : 1);
+ for (unsigned i = 0; i != NumElts; ++i) {
+ // Skip undef indices.
+ if (M[i] < 0)
+ continue;
+ if (static_cast<unsigned>(M[i]) != 2 * i + WhichResult)
+ return false;
+ }
+ return true;
+}
+
+/// \return true if \p M is a zip mask for a shuffle vector of \p NumElts.
+/// Whether or not G_ZIP1 or G_ZIP2 should be used is stored in \p WhichResult.
+static bool isZipMask(ArrayRef<int> M, unsigned NumElts,
+ unsigned &WhichResult) {
+ if (NumElts % 2 != 0)
+ return false;
+
+ // 0 means use ZIP1, 1 means use ZIP2.
+ WhichResult = (M[0] == 0 ? 0 : 1);
+ unsigned Idx = WhichResult * NumElts / 2;
+ for (unsigned i = 0; i != NumElts; i += 2) {
+ if ((M[i] >= 0 && static_cast<unsigned>(M[i]) != Idx) ||
+ (M[i + 1] >= 0 && static_cast<unsigned>(M[i + 1]) != Idx + NumElts))
+ return false;
+ Idx += 1;
+ }
+ return true;
+}
+
+/// \return true if a G_SHUFFLE_VECTOR instruction \p MI can be replaced with a
+/// G_REV instruction. Returns the appropriate G_REV opcode in \p Opc.
+static bool matchREV(MachineInstr &MI, MachineRegisterInfo &MRI,
+ ShuffleVectorPseudo &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
+ ArrayRef<int> ShuffleMask = MI.getOperand(3).getShuffleMask();
+ Register Dst = MI.getOperand(0).getReg();
+ Register Src = MI.getOperand(1).getReg();
+ LLT Ty = MRI.getType(Dst);
+ unsigned EltSize = Ty.getScalarSizeInBits();
+
+ // Element size for a rev cannot be 64.
+ if (EltSize == 64)
+ return false;
+
+ unsigned NumElts = Ty.getNumElements();
+
+ // Try to produce G_REV64
+ if (isREVMask(ShuffleMask, EltSize, NumElts, 64)) {
+ MatchInfo = ShuffleVectorPseudo(AArch64::G_REV64, Dst, {Src});
+ return true;
+ }
+
+ // TODO: Produce G_REV32 and G_REV16 once we have proper legalization support.
+ // This should be identical to above, but with a constant 32 and constant
+ // 16.
+ return false;
+}
+
+/// \return true if a G_SHUFFLE_VECTOR instruction \p MI can be replaced with
+/// a G_TRN1 or G_TRN2 instruction.
+static bool matchTRN(MachineInstr &MI, MachineRegisterInfo &MRI,
+ ShuffleVectorPseudo &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
+ unsigned WhichResult;
+ ArrayRef<int> ShuffleMask = MI.getOperand(3).getShuffleMask();
+ Register Dst = MI.getOperand(0).getReg();
+ unsigned NumElts = MRI.getType(Dst).getNumElements();
+ if (!isTRNMask(ShuffleMask, NumElts, WhichResult))
+ return false;
+ unsigned Opc = (WhichResult == 0) ? AArch64::G_TRN1 : AArch64::G_TRN2;
+ Register V1 = MI.getOperand(1).getReg();
+ Register V2 = MI.getOperand(2).getReg();
+ MatchInfo = ShuffleVectorPseudo(Opc, Dst, {V1, V2});
+ return true;
+}
+
+/// \return true if a G_SHUFFLE_VECTOR instruction \p MI can be replaced with
+/// a G_UZP1 or G_UZP2 instruction.
+///
+/// \param [in] MI - The shuffle vector instruction.
+/// \param [out] MatchInfo - Either G_UZP1 or G_UZP2 on success.
+static bool matchUZP(MachineInstr &MI, MachineRegisterInfo &MRI,
+ ShuffleVectorPseudo &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
+ unsigned WhichResult;
+ ArrayRef<int> ShuffleMask = MI.getOperand(3).getShuffleMask();
+ Register Dst = MI.getOperand(0).getReg();
+ unsigned NumElts = MRI.getType(Dst).getNumElements();
+ if (!isUZPMask(ShuffleMask, NumElts, WhichResult))
+ return false;
+ unsigned Opc = (WhichResult == 0) ? AArch64::G_UZP1 : AArch64::G_UZP2;
+ Register V1 = MI.getOperand(1).getReg();
+ Register V2 = MI.getOperand(2).getReg();
+ MatchInfo = ShuffleVectorPseudo(Opc, Dst, {V1, V2});
+ return true;
+}
+
+static bool matchZip(MachineInstr &MI, MachineRegisterInfo &MRI,
+ ShuffleVectorPseudo &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
+ unsigned WhichResult;
+ ArrayRef<int> ShuffleMask = MI.getOperand(3).getShuffleMask();
+ Register Dst = MI.getOperand(0).getReg();
+ unsigned NumElts = MRI.getType(Dst).getNumElements();
+ if (!isZipMask(ShuffleMask, NumElts, WhichResult))
+ return false;
+ unsigned Opc = (WhichResult == 0) ? AArch64::G_ZIP1 : AArch64::G_ZIP2;
+ Register V1 = MI.getOperand(1).getReg();
+ Register V2 = MI.getOperand(2).getReg();
+ MatchInfo = ShuffleVectorPseudo(Opc, Dst, {V1, V2});
+ return true;
+}
+
+/// Helper function for matchDup.
+static bool matchDupFromInsertVectorElt(int Lane, MachineInstr &MI,
+ MachineRegisterInfo &MRI,
+ ShuffleVectorPseudo &MatchInfo) {
+ if (Lane != 0)
+ return false;
+
+ // Try to match a vector splat operation into a dup instruction.
+ // We're looking for this pattern:
+ //
+ // %scalar:gpr(s64) = COPY $x0
+ // %undef:fpr(<2 x s64>) = G_IMPLICIT_DEF
+ // %cst0:gpr(s32) = G_CONSTANT i32 0
+ // %zerovec:fpr(<2 x s32>) = G_BUILD_VECTOR %cst0(s32), %cst0(s32)
+ // %ins:fpr(<2 x s64>) = G_INSERT_VECTOR_ELT %undef, %scalar(s64), %cst0(s32)
+ // %splat:fpr(<2 x s64>) = G_SHUFFLE_VECTOR %ins(<2 x s64>), %undef, %zerovec(<2 x s32>)
+ //
+ // ...into:
+ // %splat = G_DUP %scalar
+
+ // Begin matching the insert.
+ auto *InsMI = getOpcodeDef(TargetOpcode::G_INSERT_VECTOR_ELT,
+ MI.getOperand(1).getReg(), MRI);
+ if (!InsMI)
+ return false;
+ // Match the undef vector operand.
+ if (!getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, InsMI->getOperand(1).getReg(),
+ MRI))
+ return false;
+
+ // Match the index constant 0.
+ if (!mi_match(InsMI->getOperand(3).getReg(), MRI, m_ZeroInt()))
+ return false;
+
+ MatchInfo = ShuffleVectorPseudo(AArch64::G_DUP, MI.getOperand(0).getReg(),
+ {InsMI->getOperand(2).getReg()});
+ return true;
+}
+
+/// Helper function for matchDup.
+static bool matchDupFromBuildVector(int Lane, MachineInstr &MI,
+ MachineRegisterInfo &MRI,
+ ShuffleVectorPseudo &MatchInfo) {
+ assert(Lane >= 0 && "Expected positive lane?");
+ // Test if the LHS is a BUILD_VECTOR. If it is, then we can just reference the
+ // lane's definition directly.
+ auto *BuildVecMI = getOpcodeDef(TargetOpcode::G_BUILD_VECTOR,
+ MI.getOperand(1).getReg(), MRI);
+ if (!BuildVecMI)
+ return false;
+ Register Reg = BuildVecMI->getOperand(Lane + 1).getReg();
+ MatchInfo =
+ ShuffleVectorPseudo(AArch64::G_DUP, MI.getOperand(0).getReg(), {Reg});
+ return true;
+}
+
+static bool matchDup(MachineInstr &MI, MachineRegisterInfo &MRI,
+ ShuffleVectorPseudo &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
+ auto MaybeLane = getSplatIndex(MI);
+ if (!MaybeLane)
+ return false;
+ int Lane = *MaybeLane;
+ // If this is undef splat, generate it via "just" vdup, if possible.
+ if (Lane < 0)
+ Lane = 0;
+ if (matchDupFromInsertVectorElt(Lane, MI, MRI, MatchInfo))
+ return true;
+ if (matchDupFromBuildVector(Lane, MI, MRI, MatchInfo))
+ return true;
+ return false;
+}
+
+static bool matchEXT(MachineInstr &MI, MachineRegisterInfo &MRI,
+ ShuffleVectorPseudo &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
+ Register Dst = MI.getOperand(0).getReg();
+ auto ExtInfo = getExtMask(MI.getOperand(3).getShuffleMask(),
+ MRI.getType(Dst).getNumElements());
+ if (!ExtInfo)
+ return false;
+ bool ReverseExt;
+ uint64_t Imm;
+ std::tie(ReverseExt, Imm) = *ExtInfo;
+ Register V1 = MI.getOperand(1).getReg();
+ Register V2 = MI.getOperand(2).getReg();
+ if (ReverseExt)
+ std::swap(V1, V2);
+ uint64_t ExtFactor = MRI.getType(V1).getScalarSizeInBits() / 8;
+ Imm *= ExtFactor;
+ MatchInfo = ShuffleVectorPseudo(AArch64::G_EXT, Dst, {V1, V2, Imm});
+ return true;
+}
+
+/// Replace a G_SHUFFLE_VECTOR instruction with a pseudo.
+/// \p Opc is the opcode to use. \p MI is the G_SHUFFLE_VECTOR.
+static bool applyShuffleVectorPseudo(MachineInstr &MI,
+ ShuffleVectorPseudo &MatchInfo) {
+ MachineIRBuilder MIRBuilder(MI);
+ MIRBuilder.buildInstr(MatchInfo.Opc, {MatchInfo.Dst}, MatchInfo.SrcOps);
+ MI.eraseFromParent();
+ return true;
+}
+
+/// Replace a G_SHUFFLE_VECTOR instruction with G_EXT.
+/// Special-cased because the constant operand must be emitted as a G_CONSTANT
+/// for the imported tablegen patterns to work.
+static bool applyEXT(MachineInstr &MI, ShuffleVectorPseudo &MatchInfo) {
+ MachineIRBuilder MIRBuilder(MI);
+ // Tablegen patterns expect an i32 G_CONSTANT as the final op.
+ auto Cst =
+ MIRBuilder.buildConstant(LLT::scalar(32), MatchInfo.SrcOps[2].getImm());
+ MIRBuilder.buildInstr(MatchInfo.Opc, {MatchInfo.Dst},
+ {MatchInfo.SrcOps[0], MatchInfo.SrcOps[1], Cst});
+ MI.eraseFromParent();
+ return true;
+}
+
+/// isVShiftRImm - Check if this is a valid vector for the immediate
+/// operand of a vector shift right operation. The value must be in the range:
+/// 1 <= Value <= ElementBits for a right shift.
+static bool isVShiftRImm(Register Reg, MachineRegisterInfo &MRI, LLT Ty,
+ int64_t &Cnt) {
+ assert(Ty.isVector() && "vector shift count is not a vector type");
+ MachineInstr *MI = MRI.getVRegDef(Reg);
+ auto Cst = getBuildVectorConstantSplat(*MI, MRI);
+ if (!Cst)
+ return false;
+ Cnt = *Cst;
+ int64_t ElementBits = Ty.getScalarSizeInBits();
+ return Cnt >= 1 && Cnt <= ElementBits;
+}
+
+/// Match a vector G_ASHR or G_LSHR with a valid immediate shift.
+static bool matchVAshrLshrImm(MachineInstr &MI, MachineRegisterInfo &MRI,
+ int64_t &Imm) {
+ assert(MI.getOpcode() == TargetOpcode::G_ASHR ||
+ MI.getOpcode() == TargetOpcode::G_LSHR);
+ LLT Ty = MRI.getType(MI.getOperand(1).getReg());
+ if (!Ty.isVector())
+ return false;
+ return isVShiftRImm(MI.getOperand(2).getReg(), MRI, Ty, Imm);
+}
+
+static bool applyVAshrLshrImm(MachineInstr &MI, MachineRegisterInfo &MRI,
+ int64_t &Imm) {
+ unsigned Opc = MI.getOpcode();
+ assert(Opc == TargetOpcode::G_ASHR || Opc == TargetOpcode::G_LSHR);
+ unsigned NewOpc =
+ Opc == TargetOpcode::G_ASHR ? AArch64::G_VASHR : AArch64::G_VLSHR;
+ MachineIRBuilder MIB(MI);
+ auto ImmDef = MIB.buildConstant(LLT::scalar(32), Imm);
+ MIB.buildInstr(NewOpc, {MI.getOperand(0)}, {MI.getOperand(1), ImmDef});
+ MI.eraseFromParent();
+ return true;
+}
+
+/// Determine if it is possible to modify the \p RHS and predicate \p P of a
+/// G_ICMP instruction such that the right-hand side is an arithmetic immediate.
+///
+/// \returns A pair containing the updated immediate and predicate which may
+/// be used to optimize the instruction.
+///
+/// \note This assumes that the comparison has been legalized.
+Optional<std::pair<uint64_t, CmpInst::Predicate>>
+tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
+ const MachineRegisterInfo &MRI) {
+ const auto &Ty = MRI.getType(RHS);
+ if (Ty.isVector())
+ return None;
+ unsigned Size = Ty.getSizeInBits();
+ assert((Size == 32 || Size == 64) && "Expected 32 or 64 bit compare only?");
+
+ // If the RHS is not a constant, or the RHS is already a valid arithmetic
+ // immediate, then there is nothing to change.
+ auto ValAndVReg = getConstantVRegValWithLookThrough(RHS, MRI);
+ if (!ValAndVReg)
+ return None;
+ uint64_t C = ValAndVReg->Value.getZExtValue();
+ if (isLegalArithImmed(C))
+ return None;
+
+ // We have a non-arithmetic immediate. Check if adjusting the immediate and
+ // adjusting the predicate will result in a legal arithmetic immediate.
+ switch (P) {
+ default:
+ return None;
+ case CmpInst::ICMP_SLT:
+ case CmpInst::ICMP_SGE:
+ // Check for
+ //
+ // x slt c => x sle c - 1
+ // x sge c => x sgt c - 1
+ //
+ // When c is not the smallest possible negative number.
+ if ((Size == 64 && static_cast<int64_t>(C) == INT64_MIN) ||
+ (Size == 32 && static_cast<int32_t>(C) == INT32_MIN))
+ return None;
+ P = (P == CmpInst::ICMP_SLT) ? CmpInst::ICMP_SLE : CmpInst::ICMP_SGT;
+ C -= 1;
+ break;
+ case CmpInst::ICMP_ULT:
+ case CmpInst::ICMP_UGE:
+ // Check for
+ //
+ // x ult c => x ule c - 1
+ // x uge c => x ugt c - 1
+ //
+ // When c is not zero.
+ if (C == 0)
+ return None;
+ P = (P == CmpInst::ICMP_ULT) ? CmpInst::ICMP_ULE : CmpInst::ICMP_UGT;
+ C -= 1;
+ break;
+ case CmpInst::ICMP_SLE:
+ case CmpInst::ICMP_SGT:
+ // Check for
+ //
+ // x sle c => x slt c + 1
+ // x sgt c => s sge c + 1
+ //
+ // When c is not the largest possible signed integer.
+ if ((Size == 32 && static_cast<int32_t>(C) == INT32_MAX) ||
+ (Size == 64 && static_cast<int64_t>(C) == INT64_MAX))
+ return None;
+ P = (P == CmpInst::ICMP_SLE) ? CmpInst::ICMP_SLT : CmpInst::ICMP_SGE;
+ C += 1;
+ break;
+ case CmpInst::ICMP_ULE:
+ case CmpInst::ICMP_UGT:
+ // Check for
+ //
+ // x ule c => x ult c + 1
+ // x ugt c => s uge c + 1
+ //
+ // When c is not the largest possible unsigned integer.
+ if ((Size == 32 && static_cast<uint32_t>(C) == UINT32_MAX) ||
+ (Size == 64 && C == UINT64_MAX))
+ return None;
+ P = (P == CmpInst::ICMP_ULE) ? CmpInst::ICMP_ULT : CmpInst::ICMP_UGE;
+ C += 1;
+ break;
+ }
+
+ // Check if the new constant is valid, and return the updated constant and
+ // predicate if it is.
+ if (Size == 32)
+ C = static_cast<uint32_t>(C);
+ if (!isLegalArithImmed(C))
+ return None;
+ return {{C, P}};
+}
+
+/// Determine whether or not it is possible to update the RHS and predicate of
+/// a G_ICMP instruction such that the RHS will be selected as an arithmetic
+/// immediate.
+///
+/// \p MI - The G_ICMP instruction
+/// \p MatchInfo - The new RHS immediate and predicate on success
+///
+/// See tryAdjustICmpImmAndPred for valid transformations.
+bool matchAdjustICmpImmAndPred(
+ MachineInstr &MI, const MachineRegisterInfo &MRI,
+ std::pair<uint64_t, CmpInst::Predicate> &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_ICMP);
+ Register RHS = MI.getOperand(3).getReg();
+ auto Pred = static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
+ if (auto MaybeNewImmAndPred = tryAdjustICmpImmAndPred(RHS, Pred, MRI)) {
+ MatchInfo = *MaybeNewImmAndPred;
+ return true;
+ }
+ return false;
+}
+
+bool applyAdjustICmpImmAndPred(
+ MachineInstr &MI, std::pair<uint64_t, CmpInst::Predicate> &MatchInfo,
+ MachineIRBuilder &MIB, GISelChangeObserver &Observer) {
+ MIB.setInstrAndDebugLoc(MI);
+ MachineOperand &RHS = MI.getOperand(3);
+ MachineRegisterInfo &MRI = *MIB.getMRI();
+ auto Cst = MIB.buildConstant(MRI.cloneVirtualRegister(RHS.getReg()),
+ MatchInfo.first);
+ Observer.changingInstr(MI);
+ RHS.setReg(Cst->getOperand(0).getReg());
+ MI.getOperand(1).setPredicate(MatchInfo.second);
+ Observer.changedInstr(MI);
+ return true;
+}
+
+bool matchDupLane(MachineInstr &MI, MachineRegisterInfo &MRI,
+ std::pair<unsigned, int> &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
+ Register Src1Reg = MI.getOperand(1).getReg();
+ const LLT SrcTy = MRI.getType(Src1Reg);
+ const LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
+
+ auto LaneIdx = getSplatIndex(MI);
+ if (!LaneIdx)
+ return false;
+
+ // The lane idx should be within the first source vector.
+ if (*LaneIdx >= SrcTy.getNumElements())
+ return false;
+
+ if (DstTy != SrcTy)
+ return false;
+
+ LLT ScalarTy = SrcTy.getElementType();
+ unsigned ScalarSize = ScalarTy.getSizeInBits();
+
+ unsigned Opc = 0;
+ switch (SrcTy.getNumElements()) {
+ case 2:
+ if (ScalarSize == 64)
+ Opc = AArch64::G_DUPLANE64;
+ break;
+ case 4:
+ if (ScalarSize == 32)
+ Opc = AArch64::G_DUPLANE32;
+ break;
+ case 8:
+ if (ScalarSize == 16)
+ Opc = AArch64::G_DUPLANE16;
+ break;
+ case 16:
+ if (ScalarSize == 8)
+ Opc = AArch64::G_DUPLANE8;
+ break;
+ default:
+ break;
+ }
+ if (!Opc)
+ return false;
+
+ MatchInfo.first = Opc;
+ MatchInfo.second = *LaneIdx;
+ return true;
+}
+
+bool applyDupLane(MachineInstr &MI, MachineRegisterInfo &MRI,
+ MachineIRBuilder &B, std::pair<unsigned, int> &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
+ B.setInstrAndDebugLoc(MI);
+ auto Lane = B.buildConstant(LLT::scalar(64), MatchInfo.second);
+ B.buildInstr(MatchInfo.first, {MI.getOperand(0).getReg()},
+ {MI.getOperand(1).getReg(), Lane});
+ MI.eraseFromParent();
+ return true;
+}
+
+#define AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_DEPS
+#include "AArch64GenPostLegalizeGILowering.inc"
+#undef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_DEPS
+
+namespace {
+#define AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_H
+#include "AArch64GenPostLegalizeGILowering.inc"
+#undef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_H
+
+class AArch64PostLegalizerLoweringInfo : public CombinerInfo {
+public:
+ AArch64GenPostLegalizerLoweringHelperRuleConfig GeneratedRuleCfg;
+
+ AArch64PostLegalizerLoweringInfo(bool OptSize, bool MinSize)
+ : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
+ /*LegalizerInfo*/ nullptr, /*OptEnabled = */ true, OptSize,
+ MinSize) {
+ if (!GeneratedRuleCfg.parseCommandLineOption())
+ report_fatal_error("Invalid rule identifier");
+ }
+
+ virtual bool combine(GISelChangeObserver &Observer, MachineInstr &MI,
+ MachineIRBuilder &B) const override;
+};
+
+bool AArch64PostLegalizerLoweringInfo::combine(GISelChangeObserver &Observer,
+ MachineInstr &MI,
+ MachineIRBuilder &B) const {
+ CombinerHelper Helper(Observer, B);
+ AArch64GenPostLegalizerLoweringHelper Generated(GeneratedRuleCfg);
+ return Generated.tryCombineAll(Observer, MI, B, Helper);
+}
+
+#define AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_CPP
+#include "AArch64GenPostLegalizeGILowering.inc"
+#undef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_CPP
+
+class AArch64PostLegalizerLowering : public MachineFunctionPass {
+public:
+ static char ID;
+
+ AArch64PostLegalizerLowering();
+
+ StringRef getPassName() const override {
+ return "AArch64PostLegalizerLowering";
+ }
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+};
+} // end anonymous namespace
+
+void AArch64PostLegalizerLowering::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<TargetPassConfig>();
+ AU.setPreservesCFG();
+ getSelectionDAGFallbackAnalysisUsage(AU);
+ MachineFunctionPass::getAnalysisUsage(AU);
+}
+
+AArch64PostLegalizerLowering::AArch64PostLegalizerLowering()
+ : MachineFunctionPass(ID) {
+ initializeAArch64PostLegalizerLoweringPass(*PassRegistry::getPassRegistry());
+}
+
+bool AArch64PostLegalizerLowering::runOnMachineFunction(MachineFunction &MF) {
+ if (MF.getProperties().hasProperty(
+ MachineFunctionProperties::Property::FailedISel))
+ return false;
+ assert(MF.getProperties().hasProperty(
+ MachineFunctionProperties::Property::Legalized) &&
+ "Expected a legalized function?");
+ auto *TPC = &getAnalysis<TargetPassConfig>();
+ const Function &F = MF.getFunction();
+ AArch64PostLegalizerLoweringInfo PCInfo(F.hasOptSize(), F.hasMinSize());
+ Combiner C(PCInfo, TPC);
+ return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr);
+}
+
+char AArch64PostLegalizerLowering::ID = 0;
+INITIALIZE_PASS_BEGIN(AArch64PostLegalizerLowering, DEBUG_TYPE,
+ "Lower AArch64 MachineInstrs after legalization", false,
+ false)
+INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
+INITIALIZE_PASS_END(AArch64PostLegalizerLowering, DEBUG_TYPE,
+ "Lower AArch64 MachineInstrs after legalization", false,
+ false)
+
+namespace llvm {
+FunctionPass *createAArch64PostLegalizerLowering() {
+ return new AArch64PostLegalizerLowering();
+}
+} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PostSelectOptimize.cpp b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PostSelectOptimize.cpp
index 00436b5924..2f882ecb1f 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PostSelectOptimize.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PostSelectOptimize.cpp
@@ -1,187 +1,187 @@
-//=== AArch64PostSelectOptimize.cpp ---------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass does post-instruction-selection optimizations in the GlobalISel
-// pipeline, before the rest of codegen runs.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AArch64.h"
-#include "AArch64TargetMachine.h"
-#include "MCTargetDesc/AArch64MCTargetDesc.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineOperand.h"
-#include "llvm/CodeGen/TargetPassConfig.h"
-#include "llvm/Support/Debug.h"
-
-#define DEBUG_TYPE "aarch64-post-select-optimize"
-
-using namespace llvm;
-
-namespace {
-class AArch64PostSelectOptimize : public MachineFunctionPass {
-public:
- static char ID;
-
- AArch64PostSelectOptimize();
-
- StringRef getPassName() const override {
- return "AArch64 Post Select Optimizer";
- }
-
- bool runOnMachineFunction(MachineFunction &MF) override;
-
- void getAnalysisUsage(AnalysisUsage &AU) const override;
-
-private:
- bool optimizeNZCVDefs(MachineBasicBlock &MBB);
-};
-} // end anonymous namespace
-
-void AArch64PostSelectOptimize::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<TargetPassConfig>();
- AU.setPreservesCFG();
- getSelectionDAGFallbackAnalysisUsage(AU);
- MachineFunctionPass::getAnalysisUsage(AU);
-}
-
-AArch64PostSelectOptimize::AArch64PostSelectOptimize()
- : MachineFunctionPass(ID) {
- initializeAArch64PostSelectOptimizePass(*PassRegistry::getPassRegistry());
-}
-
-unsigned getNonFlagSettingVariant(unsigned Opc) {
- switch (Opc) {
- default:
- return 0;
- case AArch64::SUBSXrr:
- return AArch64::SUBXrr;
- case AArch64::SUBSWrr:
- return AArch64::SUBWrr;
- case AArch64::SUBSXrs:
- return AArch64::SUBXrs;
- case AArch64::SUBSXri:
- return AArch64::SUBXri;
- case AArch64::SUBSWri:
- return AArch64::SUBWri;
- }
-}
-
-bool AArch64PostSelectOptimize::optimizeNZCVDefs(MachineBasicBlock &MBB) {
- // Consider the following code:
- // FCMPSrr %0, %1, implicit-def $nzcv
- // %sel1:gpr32 = CSELWr %_, %_, 12, implicit $nzcv
- // %sub:gpr32 = SUBSWrr %_, %_, implicit-def $nzcv
- // FCMPSrr %0, %1, implicit-def $nzcv
- // %sel2:gpr32 = CSELWr %_, %_, 12, implicit $nzcv
- // This kind of code where we have 2 FCMPs each feeding a CSEL can happen
- // when we have a single IR fcmp being used by two selects. During selection,
- // to ensure that there can be no clobbering of nzcv between the fcmp and the
- // csel, we have to generate an fcmp immediately before each csel is
- // selected.
- // However, often we can essentially CSE these together later in MachineCSE.
- // This doesn't work though if there are unrelated flag-setting instructions
- // in between the two FCMPs. In this case, the SUBS defines NZCV
- // but it doesn't have any users, being overwritten by the second FCMP.
- //
- // Our solution here is to try to convert flag setting operations between
- // a interval of identical FCMPs, so that CSE will be able to eliminate one.
- bool Changed = false;
- const auto *TII = MBB.getParent()->getSubtarget().getInstrInfo();
-
- // The first step is to find the first and last FCMPs. If we have found
- // at least two, then set the limit of the bottom-up walk to the first FCMP
- // found since we're only interested in dealing with instructions between
- // them.
- MachineInstr *FirstCmp = nullptr, *LastCmp = nullptr;
- for (auto &MI : instructionsWithoutDebug(MBB.begin(), MBB.end())) {
- if (MI.getOpcode() == AArch64::FCMPSrr ||
- MI.getOpcode() == AArch64::FCMPDrr) {
- if (!FirstCmp)
- FirstCmp = &MI;
- else
- LastCmp = &MI;
- }
- }
-
- // In addition to converting flag-setting ops in fcmp ranges into non-flag
- // setting ops, across the whole basic block we also detect when nzcv
- // implicit-defs are dead, and mark them as dead. Peephole optimizations need
- // this information later.
-
- LiveRegUnits LRU(*MBB.getParent()->getSubtarget().getRegisterInfo());
- LRU.addLiveOuts(MBB);
- bool NZCVDead = LRU.available(AArch64::NZCV);
- bool InsideCmpRange = false;
- for (auto &II : instructionsWithoutDebug(MBB.rbegin(), MBB.rend())) {
- LRU.stepBackward(II);
-
- if (LastCmp) { // There's a range present in this block.
- // If we're inside an fcmp range, look for begin instruction.
- if (InsideCmpRange && &II == FirstCmp)
- InsideCmpRange = false;
- else if (&II == LastCmp)
- InsideCmpRange = true;
- }
-
- // Did this instruction define NZCV?
- bool NZCVDeadAtCurrInstr = LRU.available(AArch64::NZCV);
- if (NZCVDead && NZCVDeadAtCurrInstr && II.definesRegister(AArch64::NZCV)) {
- // If we have a def and NZCV is dead, then we may convert this op.
- unsigned NewOpc = getNonFlagSettingVariant(II.getOpcode());
- int DeadNZCVIdx = II.findRegisterDefOperandIdx(AArch64::NZCV);
- if (DeadNZCVIdx != -1) {
- // If we're inside an fcmp range, then convert flag setting ops.
- if (InsideCmpRange && NewOpc) {
- LLVM_DEBUG(dbgs() << "Post-select optimizer: converting flag-setting "
- "op in fcmp range: "
- << II);
- II.setDesc(TII->get(NewOpc));
- II.RemoveOperand(DeadNZCVIdx);
- Changed |= true;
- } else {
- // Otherwise, we just set the nzcv imp-def operand to be dead, so the
- // peephole optimizations can optimize them further.
- II.getOperand(DeadNZCVIdx).setIsDead();
- }
- }
- }
-
- NZCVDead = NZCVDeadAtCurrInstr;
- }
- return Changed;
-}
-
-bool AArch64PostSelectOptimize::runOnMachineFunction(MachineFunction &MF) {
- if (MF.getProperties().hasProperty(
- MachineFunctionProperties::Property::FailedISel))
- return false;
- assert(MF.getProperties().hasProperty(
- MachineFunctionProperties::Property::Selected) &&
- "Expected a selected MF");
-
- bool Changed = false;
- for (auto &BB : MF)
- Changed |= optimizeNZCVDefs(BB);
- return true;
-}
-
-char AArch64PostSelectOptimize::ID = 0;
-INITIALIZE_PASS_BEGIN(AArch64PostSelectOptimize, DEBUG_TYPE,
- "Optimize AArch64 selected instructions",
- false, false)
-INITIALIZE_PASS_END(AArch64PostSelectOptimize, DEBUG_TYPE,
- "Optimize AArch64 selected instructions", false,
- false)
-
-namespace llvm {
-FunctionPass *createAArch64PostSelectOptimize() {
- return new AArch64PostSelectOptimize();
-}
-} // end namespace llvm
+//=== AArch64PostSelectOptimize.cpp ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass does post-instruction-selection optimizations in the GlobalISel
+// pipeline, before the rest of codegen runs.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AArch64.h"
+#include "AArch64TargetMachine.h"
+#include "MCTargetDesc/AArch64MCTargetDesc.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "aarch64-post-select-optimize"
+
+using namespace llvm;
+
+namespace {
+class AArch64PostSelectOptimize : public MachineFunctionPass {
+public:
+ static char ID;
+
+ AArch64PostSelectOptimize();
+
+ StringRef getPassName() const override {
+ return "AArch64 Post Select Optimizer";
+ }
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+private:
+ bool optimizeNZCVDefs(MachineBasicBlock &MBB);
+};
+} // end anonymous namespace
+
+void AArch64PostSelectOptimize::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<TargetPassConfig>();
+ AU.setPreservesCFG();
+ getSelectionDAGFallbackAnalysisUsage(AU);
+ MachineFunctionPass::getAnalysisUsage(AU);
+}
+
+AArch64PostSelectOptimize::AArch64PostSelectOptimize()
+ : MachineFunctionPass(ID) {
+ initializeAArch64PostSelectOptimizePass(*PassRegistry::getPassRegistry());
+}
+
+unsigned getNonFlagSettingVariant(unsigned Opc) {
+ switch (Opc) {
+ default:
+ return 0;
+ case AArch64::SUBSXrr:
+ return AArch64::SUBXrr;
+ case AArch64::SUBSWrr:
+ return AArch64::SUBWrr;
+ case AArch64::SUBSXrs:
+ return AArch64::SUBXrs;
+ case AArch64::SUBSXri:
+ return AArch64::SUBXri;
+ case AArch64::SUBSWri:
+ return AArch64::SUBWri;
+ }
+}
+
+bool AArch64PostSelectOptimize::optimizeNZCVDefs(MachineBasicBlock &MBB) {
+ // Consider the following code:
+ // FCMPSrr %0, %1, implicit-def $nzcv
+ // %sel1:gpr32 = CSELWr %_, %_, 12, implicit $nzcv
+ // %sub:gpr32 = SUBSWrr %_, %_, implicit-def $nzcv
+ // FCMPSrr %0, %1, implicit-def $nzcv
+ // %sel2:gpr32 = CSELWr %_, %_, 12, implicit $nzcv
+ // This kind of code where we have 2 FCMPs each feeding a CSEL can happen
+ // when we have a single IR fcmp being used by two selects. During selection,
+ // to ensure that there can be no clobbering of nzcv between the fcmp and the
+ // csel, we have to generate an fcmp immediately before each csel is
+ // selected.
+ // However, often we can essentially CSE these together later in MachineCSE.
+ // This doesn't work though if there are unrelated flag-setting instructions
+ // in between the two FCMPs. In this case, the SUBS defines NZCV
+ // but it doesn't have any users, being overwritten by the second FCMP.
+ //
+ // Our solution here is to try to convert flag setting operations between
+ // a interval of identical FCMPs, so that CSE will be able to eliminate one.
+ bool Changed = false;
+ const auto *TII = MBB.getParent()->getSubtarget().getInstrInfo();
+
+ // The first step is to find the first and last FCMPs. If we have found
+ // at least two, then set the limit of the bottom-up walk to the first FCMP
+ // found since we're only interested in dealing with instructions between
+ // them.
+ MachineInstr *FirstCmp = nullptr, *LastCmp = nullptr;
+ for (auto &MI : instructionsWithoutDebug(MBB.begin(), MBB.end())) {
+ if (MI.getOpcode() == AArch64::FCMPSrr ||
+ MI.getOpcode() == AArch64::FCMPDrr) {
+ if (!FirstCmp)
+ FirstCmp = &MI;
+ else
+ LastCmp = &MI;
+ }
+ }
+
+ // In addition to converting flag-setting ops in fcmp ranges into non-flag
+ // setting ops, across the whole basic block we also detect when nzcv
+ // implicit-defs are dead, and mark them as dead. Peephole optimizations need
+ // this information later.
+
+ LiveRegUnits LRU(*MBB.getParent()->getSubtarget().getRegisterInfo());
+ LRU.addLiveOuts(MBB);
+ bool NZCVDead = LRU.available(AArch64::NZCV);
+ bool InsideCmpRange = false;
+ for (auto &II : instructionsWithoutDebug(MBB.rbegin(), MBB.rend())) {
+ LRU.stepBackward(II);
+
+ if (LastCmp) { // There's a range present in this block.
+ // If we're inside an fcmp range, look for begin instruction.
+ if (InsideCmpRange && &II == FirstCmp)
+ InsideCmpRange = false;
+ else if (&II == LastCmp)
+ InsideCmpRange = true;
+ }
+
+ // Did this instruction define NZCV?
+ bool NZCVDeadAtCurrInstr = LRU.available(AArch64::NZCV);
+ if (NZCVDead && NZCVDeadAtCurrInstr && II.definesRegister(AArch64::NZCV)) {
+ // If we have a def and NZCV is dead, then we may convert this op.
+ unsigned NewOpc = getNonFlagSettingVariant(II.getOpcode());
+ int DeadNZCVIdx = II.findRegisterDefOperandIdx(AArch64::NZCV);
+ if (DeadNZCVIdx != -1) {
+ // If we're inside an fcmp range, then convert flag setting ops.
+ if (InsideCmpRange && NewOpc) {
+ LLVM_DEBUG(dbgs() << "Post-select optimizer: converting flag-setting "
+ "op in fcmp range: "
+ << II);
+ II.setDesc(TII->get(NewOpc));
+ II.RemoveOperand(DeadNZCVIdx);
+ Changed |= true;
+ } else {
+ // Otherwise, we just set the nzcv imp-def operand to be dead, so the
+ // peephole optimizations can optimize them further.
+ II.getOperand(DeadNZCVIdx).setIsDead();
+ }
+ }
+ }
+
+ NZCVDead = NZCVDeadAtCurrInstr;
+ }
+ return Changed;
+}
+
+bool AArch64PostSelectOptimize::runOnMachineFunction(MachineFunction &MF) {
+ if (MF.getProperties().hasProperty(
+ MachineFunctionProperties::Property::FailedISel))
+ return false;
+ assert(MF.getProperties().hasProperty(
+ MachineFunctionProperties::Property::Selected) &&
+ "Expected a selected MF");
+
+ bool Changed = false;
+ for (auto &BB : MF)
+ Changed |= optimizeNZCVDefs(BB);
+ return true;
+}
+
+char AArch64PostSelectOptimize::ID = 0;
+INITIALIZE_PASS_BEGIN(AArch64PostSelectOptimize, DEBUG_TYPE,
+ "Optimize AArch64 selected instructions",
+ false, false)
+INITIALIZE_PASS_END(AArch64PostSelectOptimize, DEBUG_TYPE,
+ "Optimize AArch64 selected instructions", false,
+ false)
+
+namespace llvm {
+FunctionPass *createAArch64PostSelectOptimize() {
+ return new AArch64PostSelectOptimize();
+}
+} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp
index 2686f6dc46..5f9b64e274 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp
@@ -104,16 +104,16 @@ bool AArch64PreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer,
return Helper.tryCombineConcatVectors(MI);
case TargetOpcode::G_SHUFFLE_VECTOR:
return Helper.tryCombineShuffleVector(MI);
- case TargetOpcode::G_MEMCPY:
- case TargetOpcode::G_MEMMOVE:
- case TargetOpcode::G_MEMSET: {
- // If we're at -O0 set a maxlen of 32 to inline, otherwise let the other
- // heuristics decide.
- unsigned MaxLen = EnableOpt ? 0 : 32;
- // Try to inline memcpy type calls if optimizations are enabled.
- return !EnableMinSize ? Helper.tryCombineMemCpyFamily(MI, MaxLen) : false;
+ case TargetOpcode::G_MEMCPY:
+ case TargetOpcode::G_MEMMOVE:
+ case TargetOpcode::G_MEMSET: {
+ // If we're at -O0 set a maxlen of 32 to inline, otherwise let the other
+ // heuristics decide.
+ unsigned MaxLen = EnableOpt ? 0 : 32;
+ // Try to inline memcpy type calls if optimizations are enabled.
+ return !EnableMinSize ? Helper.tryCombineMemCpyFamily(MI, MaxLen) : false;
+ }
}
- }
return false;
}
@@ -188,7 +188,7 @@ INITIALIZE_PASS_END(AArch64PreLegalizerCombiner, DEBUG_TYPE,
namespace llvm {
-FunctionPass *createAArch64PreLegalizerCombiner(bool IsOptNone) {
+FunctionPass *createAArch64PreLegalizerCombiner(bool IsOptNone) {
return new AArch64PreLegalizerCombiner(IsOptNone);
}
} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index e26fe60d93..c76c43389b 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -13,7 +13,7 @@
#include "AArch64RegisterBankInfo.h"
#include "AArch64InstrInfo.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
@@ -466,10 +466,10 @@ AArch64RegisterBankInfo::getSameKindOfOperandsMapping(
getValueMapping(RBIdx, Size), NumOperands);
}
-bool AArch64RegisterBankInfo::hasFPConstraints(const MachineInstr &MI,
- const MachineRegisterInfo &MRI,
- const TargetRegisterInfo &TRI,
- unsigned Depth) const {
+bool AArch64RegisterBankInfo::hasFPConstraints(const MachineInstr &MI,
+ const MachineRegisterInfo &MRI,
+ const TargetRegisterInfo &TRI,
+ unsigned Depth) const {
unsigned Op = MI.getOpcode();
// Do we have an explicit floating point instruction?
@@ -481,30 +481,30 @@ bool AArch64RegisterBankInfo::hasFPConstraints(const MachineInstr &MI,
if (Op != TargetOpcode::COPY && !MI.isPHI())
return false;
- // Check if we already know the register bank.
- auto *RB = getRegBank(MI.getOperand(0).getReg(), MRI, TRI);
- if (RB == &AArch64::FPRRegBank)
- return true;
- if (RB == &AArch64::GPRRegBank)
- return false;
-
- // We don't know anything.
- //
- // If we have a phi, we may be able to infer that it will be assigned a FPR
- // based off of its inputs.
- if (!MI.isPHI() || Depth > MaxFPRSearchDepth)
- return false;
-
- return any_of(MI.explicit_uses(), [&](const MachineOperand &Op) {
- return Op.isReg() &&
- onlyDefinesFP(*MRI.getVRegDef(Op.getReg()), MRI, TRI, Depth + 1);
- });
+ // Check if we already know the register bank.
+ auto *RB = getRegBank(MI.getOperand(0).getReg(), MRI, TRI);
+ if (RB == &AArch64::FPRRegBank)
+ return true;
+ if (RB == &AArch64::GPRRegBank)
+ return false;
+
+ // We don't know anything.
+ //
+ // If we have a phi, we may be able to infer that it will be assigned a FPR
+ // based off of its inputs.
+ if (!MI.isPHI() || Depth > MaxFPRSearchDepth)
+ return false;
+
+ return any_of(MI.explicit_uses(), [&](const MachineOperand &Op) {
+ return Op.isReg() &&
+ onlyDefinesFP(*MRI.getVRegDef(Op.getReg()), MRI, TRI, Depth + 1);
+ });
}
bool AArch64RegisterBankInfo::onlyUsesFP(const MachineInstr &MI,
const MachineRegisterInfo &MRI,
- const TargetRegisterInfo &TRI,
- unsigned Depth) const {
+ const TargetRegisterInfo &TRI,
+ unsigned Depth) const {
switch (MI.getOpcode()) {
case TargetOpcode::G_FPTOSI:
case TargetOpcode::G_FPTOUI:
@@ -513,13 +513,13 @@ bool AArch64RegisterBankInfo::onlyUsesFP(const MachineInstr &MI,
default:
break;
}
- return hasFPConstraints(MI, MRI, TRI, Depth);
+ return hasFPConstraints(MI, MRI, TRI, Depth);
}
-bool AArch64RegisterBankInfo::onlyDefinesFP(const MachineInstr &MI,
- const MachineRegisterInfo &MRI,
- const TargetRegisterInfo &TRI,
- unsigned Depth) const {
+bool AArch64RegisterBankInfo::onlyDefinesFP(const MachineInstr &MI,
+ const MachineRegisterInfo &MRI,
+ const TargetRegisterInfo &TRI,
+ unsigned Depth) const {
switch (MI.getOpcode()) {
case AArch64::G_DUP:
case TargetOpcode::G_SITOFP:
@@ -530,7 +530,7 @@ bool AArch64RegisterBankInfo::onlyDefinesFP(const MachineInstr &MI,
default:
break;
}
- return hasFPConstraints(MI, MRI, TRI, Depth);
+ return hasFPConstraints(MI, MRI, TRI, Depth);
}
const RegisterBankInfo::InstructionMapping &
@@ -680,18 +680,18 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
break;
}
case TargetOpcode::G_SITOFP:
- case TargetOpcode::G_UITOFP: {
+ case TargetOpcode::G_UITOFP: {
if (MRI.getType(MI.getOperand(0).getReg()).isVector())
break;
- // Integer to FP conversions don't necessarily happen between GPR -> FPR
- // regbanks. They can also be done within an FPR register.
- Register SrcReg = MI.getOperand(1).getReg();
- if (getRegBank(SrcReg, MRI, TRI) == &AArch64::FPRRegBank)
- OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR};
- else
- OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR};
+ // Integer to FP conversions don't necessarily happen between GPR -> FPR
+ // regbanks. They can also be done within an FPR register.
+ Register SrcReg = MI.getOperand(1).getReg();
+ if (getRegBank(SrcReg, MRI, TRI) == &AArch64::FPRRegBank)
+ OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR};
+ else
+ OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR};
break;
- }
+ }
case TargetOpcode::G_FPTOSI:
case TargetOpcode::G_FPTOUI:
if (MRI.getType(MI.getOperand(0).getReg()).isVector())
@@ -729,8 +729,8 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
// assume this was a floating point load in the IR.
// If it was not, we would have had a bitcast before
// reaching that instruction.
- // Int->FP conversion operations are also captured in onlyDefinesFP().
- if (onlyUsesFP(UseMI, MRI, TRI) || onlyDefinesFP(UseMI, MRI, TRI)) {
+ // Int->FP conversion operations are also captured in onlyDefinesFP().
+ if (onlyUsesFP(UseMI, MRI, TRI) || onlyDefinesFP(UseMI, MRI, TRI)) {
OpRegBankIdx[0] = PMI_FirstFPR;
break;
}
@@ -853,7 +853,7 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
}
break;
}
- case TargetOpcode::G_BUILD_VECTOR: {
+ case TargetOpcode::G_BUILD_VECTOR: {
// If the first source operand belongs to a FPR register bank, then make
// sure that we preserve that.
if (OpRegBankIdx[1] != PMI_FirstGPR)
@@ -864,17 +864,17 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
// Get the instruction that defined the source operand reg, and check if
// it's a floating point operation. Or, if it's a type like s16 which
- // doesn't have a exact size gpr register class. The exception is if the
- // build_vector has all constant operands, which may be better to leave as
- // gpr without copies, so it can be matched in imported patterns.
+ // doesn't have a exact size gpr register class. The exception is if the
+ // build_vector has all constant operands, which may be better to leave as
+ // gpr without copies, so it can be matched in imported patterns.
MachineInstr *DefMI = MRI.getVRegDef(VReg);
unsigned DefOpc = DefMI->getOpcode();
const LLT SrcTy = MRI.getType(VReg);
- if (all_of(MI.operands(), [&](const MachineOperand &Op) {
- return Op.isDef() || MRI.getVRegDef(Op.getReg())->getOpcode() ==
- TargetOpcode::G_CONSTANT;
- }))
- break;
+ if (all_of(MI.operands(), [&](const MachineOperand &Op) {
+ return Op.isDef() || MRI.getVRegDef(Op.getReg())->getOpcode() ==
+ TargetOpcode::G_CONSTANT;
+ }))
+ break;
if (isPreISelGenericFloatingPointOpcode(DefOpc) ||
SrcTy.getSizeInBits() < 32) {
// Have a floating point op.
@@ -885,30 +885,30 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
}
break;
}
- case TargetOpcode::G_VECREDUCE_FADD:
- case TargetOpcode::G_VECREDUCE_FMUL:
- case TargetOpcode::G_VECREDUCE_FMAX:
- case TargetOpcode::G_VECREDUCE_FMIN:
- case TargetOpcode::G_VECREDUCE_ADD:
- case TargetOpcode::G_VECREDUCE_MUL:
- case TargetOpcode::G_VECREDUCE_AND:
- case TargetOpcode::G_VECREDUCE_OR:
- case TargetOpcode::G_VECREDUCE_XOR:
- case TargetOpcode::G_VECREDUCE_SMAX:
- case TargetOpcode::G_VECREDUCE_SMIN:
- case TargetOpcode::G_VECREDUCE_UMAX:
- case TargetOpcode::G_VECREDUCE_UMIN:
- // Reductions produce a scalar value from a vector, the scalar should be on
- // FPR bank.
- OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR};
- break;
- case TargetOpcode::G_VECREDUCE_SEQ_FADD:
- case TargetOpcode::G_VECREDUCE_SEQ_FMUL:
- // These reductions also take a scalar accumulator input.
- // Assign them FPR for now.
- OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR, PMI_FirstFPR};
- break;
- }
+ case TargetOpcode::G_VECREDUCE_FADD:
+ case TargetOpcode::G_VECREDUCE_FMUL:
+ case TargetOpcode::G_VECREDUCE_FMAX:
+ case TargetOpcode::G_VECREDUCE_FMIN:
+ case TargetOpcode::G_VECREDUCE_ADD:
+ case TargetOpcode::G_VECREDUCE_MUL:
+ case TargetOpcode::G_VECREDUCE_AND:
+ case TargetOpcode::G_VECREDUCE_OR:
+ case TargetOpcode::G_VECREDUCE_XOR:
+ case TargetOpcode::G_VECREDUCE_SMAX:
+ case TargetOpcode::G_VECREDUCE_SMIN:
+ case TargetOpcode::G_VECREDUCE_UMAX:
+ case TargetOpcode::G_VECREDUCE_UMIN:
+ // Reductions produce a scalar value from a vector, the scalar should be on
+ // FPR bank.
+ OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR};
+ break;
+ case TargetOpcode::G_VECREDUCE_SEQ_FADD:
+ case TargetOpcode::G_VECREDUCE_SEQ_FMUL:
+ // These reductions also take a scalar accumulator input.
+ // Assign them FPR for now.
+ OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR, PMI_FirstFPR};
+ break;
+ }
// Finally construct the computed mapping.
SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.h b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.h
index c8cfe53299..019017bc3e 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.h
+++ b/contrib/libs/llvm12/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.h
@@ -114,20 +114,20 @@ class AArch64RegisterBankInfo final : public AArch64GenRegisterBankInfo {
const InstructionMapping &
getSameKindOfOperandsMapping(const MachineInstr &MI) const;
- /// Maximum recursion depth for hasFPConstraints.
- const unsigned MaxFPRSearchDepth = 2;
-
- /// \returns true if \p MI only uses and defines FPRs.
+ /// Maximum recursion depth for hasFPConstraints.
+ const unsigned MaxFPRSearchDepth = 2;
+
+ /// \returns true if \p MI only uses and defines FPRs.
bool hasFPConstraints(const MachineInstr &MI, const MachineRegisterInfo &MRI,
- const TargetRegisterInfo &TRI, unsigned Depth = 0) const;
+ const TargetRegisterInfo &TRI, unsigned Depth = 0) const;
- /// \returns true if \p MI only uses FPRs.
+ /// \returns true if \p MI only uses FPRs.
bool onlyUsesFP(const MachineInstr &MI, const MachineRegisterInfo &MRI,
- const TargetRegisterInfo &TRI, unsigned Depth = 0) const;
+ const TargetRegisterInfo &TRI, unsigned Depth = 0) const;
- /// \returns true if \p MI only defines FPRs.
+ /// \returns true if \p MI only defines FPRs.
bool onlyDefinesFP(const MachineInstr &MI, const MachineRegisterInfo &MRI,
- const TargetRegisterInfo &TRI, unsigned Depth = 0) const;
+ const TargetRegisterInfo &TRI, unsigned Depth = 0) const;
public:
AArch64RegisterBankInfo(const TargetRegisterInfo &TRI);
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h
index 77b7c09946..2cbe8315bc 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h
+++ b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h
@@ -763,8 +763,8 @@ static inline bool isSVECpyImm(int64_t Imm) {
bool IsImm8 = int8_t(Imm) == Imm;
bool IsImm16 = int16_t(Imm & ~0xff) == Imm;
- if (std::is_same<int8_t, std::make_signed_t<T>>::value ||
- std::is_same<int8_t, T>::value)
+ if (std::is_same<int8_t, std::make_signed_t<T>>::value ||
+ std::is_same<int8_t, T>::value)
return IsImm8 || uint8_t(Imm) == Imm;
if (std::is_same<int16_t, std::make_signed_t<T>>::value)
@@ -776,8 +776,8 @@ static inline bool isSVECpyImm(int64_t Imm) {
/// Returns true if Imm is valid for ADD/SUB.
template <typename T>
static inline bool isSVEAddSubImm(int64_t Imm) {
- bool IsInt8t = std::is_same<int8_t, std::make_signed_t<T>>::value ||
- std::is_same<int8_t, T>::value;
+ bool IsInt8t = std::is_same<int8_t, std::make_signed_t<T>>::value ||
+ std::is_same<int8_t, T>::value;
return uint8_t(Imm) == Imm || (!IsInt8t && uint16_t(Imm & ~0xff) == Imm);
}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
index 33448cef46..75a9f2f5c8 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
@@ -758,7 +758,7 @@ MCAsmBackend *llvm::createAArch64leAsmBackend(const Target &T,
assert(TheTriple.isOSBinFormatELF() && "Invalid target");
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
- bool IsILP32 = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32;
+ bool IsILP32 = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32;
return new ELFAArch64AsmBackend(T, TheTriple, OSABI, /*IsLittleEndian=*/true,
IsILP32);
}
@@ -771,7 +771,7 @@ MCAsmBackend *llvm::createAArch64beAsmBackend(const Target &T,
assert(TheTriple.isOSBinFormatELF() &&
"Big endian is only supported for ELF targets!");
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
- bool IsILP32 = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32;
+ bool IsILP32 = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32;
return new ELFAArch64AsmBackend(T, TheTriple, OSABI, /*IsLittleEndian=*/false,
IsILP32);
}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index 6c98ac4737..fcf67bd2f7 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -43,7 +43,7 @@ protected:
} // end anonymous namespace
AArch64ELFObjectWriter::AArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32)
- : MCELFObjectTargetWriter(/*Is64Bit*/ !IsILP32, OSABI, ELF::EM_AARCH64,
+ : MCELFObjectTargetWriter(/*Is64Bit*/ !IsILP32, OSABI, ELF::EM_AARCH64,
/*HasRelocationAddend*/ true),
IsILP32(IsILP32) {}
@@ -322,11 +322,11 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
return R_CLS(LDST64_ABS_LO12_NC);
if (SymLoc == AArch64MCExpr::VK_GOT && IsNC) {
- AArch64MCExpr::VariantKind AddressLoc =
- AArch64MCExpr::getAddressFrag(RefKind);
+ AArch64MCExpr::VariantKind AddressLoc =
+ AArch64MCExpr::getAddressFrag(RefKind);
if (!IsILP32) {
- if (AddressLoc == AArch64MCExpr::VK_LO15)
- return ELF::R_AARCH64_LD64_GOTPAGE_LO15;
+ if (AddressLoc == AArch64MCExpr::VK_LO15)
+ return ELF::R_AARCH64_LD64_GOTPAGE_LO15;
return ELF::R_AARCH64_LD64_GOT_LO12_NC;
} else {
Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store "
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
index 2135cf605b..ec97e1c8b7 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
@@ -51,61 +51,61 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer {
OS << "\t.variant_pcs " << Symbol->getName() << "\n";
}
- void EmitARM64WinCFIAllocStack(unsigned Size) override {
- OS << "\t.seh_stackalloc " << Size << "\n";
- }
- void EmitARM64WinCFISaveR19R20X(int Offset) override {
- OS << "\t.seh_save_r19r20_x " << Offset << "\n";
- }
- void EmitARM64WinCFISaveFPLR(int Offset) override {
- OS << "\t.seh_save_fplr " << Offset << "\n";
- }
- void EmitARM64WinCFISaveFPLRX(int Offset) override {
- OS << "\t.seh_save_fplr_x " << Offset << "\n";
- }
- void EmitARM64WinCFISaveReg(unsigned Reg, int Offset) override {
- OS << "\t.seh_save_reg x" << Reg << ", " << Offset << "\n";
- }
- void EmitARM64WinCFISaveRegX(unsigned Reg, int Offset) override {
- OS << "\t.seh_save_reg_x x" << Reg << ", " << Offset << "\n";
- }
- void EmitARM64WinCFISaveRegP(unsigned Reg, int Offset) override {
- OS << "\t.seh_save_regp x" << Reg << ", " << Offset << "\n";
- }
- void EmitARM64WinCFISaveRegPX(unsigned Reg, int Offset) override {
- OS << "\t.seh_save_regp_x x" << Reg << ", " << Offset << "\n";
- }
- void EmitARM64WinCFISaveLRPair(unsigned Reg, int Offset) override {
- OS << "\t.seh_save_lrpair x" << Reg << ", " << Offset << "\n";
- }
- void EmitARM64WinCFISaveFReg(unsigned Reg, int Offset) override {
- OS << "\t.seh_save_freg d" << Reg << ", " << Offset << "\n";
- }
- void EmitARM64WinCFISaveFRegX(unsigned Reg, int Offset) override {
- OS << "\t.seh_save_freg_x d" << Reg << ", " << Offset << "\n";
- }
- void EmitARM64WinCFISaveFRegP(unsigned Reg, int Offset) override {
- OS << "\t.seh_save_fregp d" << Reg << ", " << Offset << "\n";
- }
- void EmitARM64WinCFISaveFRegPX(unsigned Reg, int Offset) override {
- OS << "\t.seh_save_fregp_x d" << Reg << ", " << Offset << "\n";
- }
- void EmitARM64WinCFISetFP() override { OS << "\t.seh_set_fp\n"; }
- void EmitARM64WinCFIAddFP(unsigned Size) override {
- OS << "\t.seh_add_fp " << Size << "\n";
- }
- void EmitARM64WinCFINop() override { OS << "\t.seh_nop\n"; }
- void EmitARM64WinCFISaveNext() override { OS << "\t.seh_save_next\n"; }
- void EmitARM64WinCFIPrologEnd() override { OS << "\t.seh_endprologue\n"; }
- void EmitARM64WinCFIEpilogStart() override { OS << "\t.seh_startepilogue\n"; }
- void EmitARM64WinCFIEpilogEnd() override { OS << "\t.seh_endepilogue\n"; }
- void EmitARM64WinCFITrapFrame() override { OS << "\t.seh_trap_frame\n"; }
- void EmitARM64WinCFIMachineFrame() override { OS << "\t.seh_pushframe\n"; }
- void EmitARM64WinCFIContext() override { OS << "\t.seh_context\n"; }
- void EmitARM64WinCFIClearUnwoundToCall() override {
- OS << "\t.seh_clear_unwound_to_call\n";
- }
-
+ void EmitARM64WinCFIAllocStack(unsigned Size) override {
+ OS << "\t.seh_stackalloc " << Size << "\n";
+ }
+ void EmitARM64WinCFISaveR19R20X(int Offset) override {
+ OS << "\t.seh_save_r19r20_x " << Offset << "\n";
+ }
+ void EmitARM64WinCFISaveFPLR(int Offset) override {
+ OS << "\t.seh_save_fplr " << Offset << "\n";
+ }
+ void EmitARM64WinCFISaveFPLRX(int Offset) override {
+ OS << "\t.seh_save_fplr_x " << Offset << "\n";
+ }
+ void EmitARM64WinCFISaveReg(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_reg x" << Reg << ", " << Offset << "\n";
+ }
+ void EmitARM64WinCFISaveRegX(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_reg_x x" << Reg << ", " << Offset << "\n";
+ }
+ void EmitARM64WinCFISaveRegP(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_regp x" << Reg << ", " << Offset << "\n";
+ }
+ void EmitARM64WinCFISaveRegPX(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_regp_x x" << Reg << ", " << Offset << "\n";
+ }
+ void EmitARM64WinCFISaveLRPair(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_lrpair x" << Reg << ", " << Offset << "\n";
+ }
+ void EmitARM64WinCFISaveFReg(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_freg d" << Reg << ", " << Offset << "\n";
+ }
+ void EmitARM64WinCFISaveFRegX(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_freg_x d" << Reg << ", " << Offset << "\n";
+ }
+ void EmitARM64WinCFISaveFRegP(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_fregp d" << Reg << ", " << Offset << "\n";
+ }
+ void EmitARM64WinCFISaveFRegPX(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_fregp_x d" << Reg << ", " << Offset << "\n";
+ }
+ void EmitARM64WinCFISetFP() override { OS << "\t.seh_set_fp\n"; }
+ void EmitARM64WinCFIAddFP(unsigned Size) override {
+ OS << "\t.seh_add_fp " << Size << "\n";
+ }
+ void EmitARM64WinCFINop() override { OS << "\t.seh_nop\n"; }
+ void EmitARM64WinCFISaveNext() override { OS << "\t.seh_save_next\n"; }
+ void EmitARM64WinCFIPrologEnd() override { OS << "\t.seh_endprologue\n"; }
+ void EmitARM64WinCFIEpilogStart() override { OS << "\t.seh_startepilogue\n"; }
+ void EmitARM64WinCFIEpilogEnd() override { OS << "\t.seh_endepilogue\n"; }
+ void EmitARM64WinCFITrapFrame() override { OS << "\t.seh_trap_frame\n"; }
+ void EmitARM64WinCFIMachineFrame() override { OS << "\t.seh_pushframe\n"; }
+ void EmitARM64WinCFIContext() override { OS << "\t.seh_context\n"; }
+ void EmitARM64WinCFIClearUnwoundToCall() override {
+ OS << "\t.seh_clear_unwound_to_call\n";
+ }
+
public:
AArch64TargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS);
};
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
index 4aeb45ac21..340120d2b9 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
@@ -849,7 +849,7 @@ bool AArch64InstPrinter::printSysAlias(const MCInst *MI,
}
break;
}
- } else if (CnVal == 8 || CnVal == 9) {
+ } else if (CnVal == 8 || CnVal == 9) {
// TLBI aliases
const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByEncoding(Encoding);
if (!TLBI || !TLBI->haveFeatures(STI.getFeatureBits()))
@@ -1377,8 +1377,8 @@ void AArch64InstPrinter::printAlignedLabel(const MCInst *MI, uint64_t Address,
}
}
-void AArch64InstPrinter::printAdrpLabel(const MCInst *MI, uint64_t Address,
- unsigned OpNum,
+void AArch64InstPrinter::printAdrpLabel(const MCInst *MI, uint64_t Address,
+ unsigned OpNum,
const MCSubtargetInfo &STI,
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNum);
@@ -1386,11 +1386,11 @@ void AArch64InstPrinter::printAdrpLabel(const MCInst *MI, uint64_t Address,
// If the label has already been resolved to an immediate offset (say, when
// we're running the disassembler), just print the immediate.
if (Op.isImm()) {
- const int64_t Offset = Op.getImm() * 4096;
- if (PrintBranchImmAsAddress)
- O << formatHex((Address & -4096) + Offset);
- else
- O << "#" << Offset;
+ const int64_t Offset = Op.getImm() * 4096;
+ if (PrintBranchImmAsAddress)
+ O << formatHex((Address & -4096) + Offset);
+ else
+ O << "#" << Offset;
return;
}
@@ -1421,22 +1421,22 @@ void AArch64InstPrinter::printBarrierOption(const MCInst *MI, unsigned OpNo,
O << "#" << Val;
}
-void AArch64InstPrinter::printBarriernXSOption(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
- raw_ostream &O) {
- unsigned Val = MI->getOperand(OpNo).getImm();
- assert(MI->getOpcode() == AArch64::DSBnXS);
-
- StringRef Name;
- auto DB = AArch64DBnXS::lookupDBnXSByEncoding(Val);
- Name = DB ? DB->Name : "";
-
- if (!Name.empty())
- O << Name;
- else
- O << "#" << Val;
-}
-
+void AArch64InstPrinter::printBarriernXSOption(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
+ unsigned Val = MI->getOperand(OpNo).getImm();
+ assert(MI->getOpcode() == AArch64::DSBnXS);
+
+ StringRef Name;
+ auto DB = AArch64DBnXS::lookupDBnXSByEncoding(Val);
+ Name = DB ? DB->Name : "";
+
+ if (!Name.empty())
+ O << Name;
+ else
+ O << "#" << Val;
+}
+
void AArch64InstPrinter::printMRSSystemRegister(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
@@ -1644,10 +1644,10 @@ void AArch64InstPrinter::printGPR64as32(const MCInst *MI, unsigned OpNum,
unsigned Reg = MI->getOperand(OpNum).getReg();
O << getRegisterName(getWRegFromXReg(Reg));
}
-
-void AArch64InstPrinter::printGPR64x8(const MCInst *MI, unsigned OpNum,
- const MCSubtargetInfo &STI,
- raw_ostream &O) {
- unsigned Reg = MI->getOperand(OpNum).getReg();
- O << getRegisterName(MRI.getSubReg(Reg, AArch64::x8sub_0));
-}
+
+void AArch64InstPrinter::printGPR64x8(const MCInst *MI, unsigned OpNum,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
+ unsigned Reg = MI->getOperand(OpNum).getReg();
+ O << getRegisterName(MRI.getSubReg(Reg, AArch64::x8sub_0));
+}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
index b1952ebd27..4be885e667 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
+++ b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
@@ -30,7 +30,7 @@ public:
void printRegName(raw_ostream &OS, unsigned RegNo) const override;
// Autogenerated by tblgen.
- std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
+ std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
virtual void printInstruction(const MCInst *MI, uint64_t Address,
const MCSubtargetInfo &STI, raw_ostream &O);
virtual bool printAliasInstr(const MCInst *MI, uint64_t Address,
@@ -156,12 +156,12 @@ protected:
void printVectorIndex(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);
- void printAdrpLabel(const MCInst *MI, uint64_t Address, unsigned OpNum,
+ void printAdrpLabel(const MCInst *MI, uint64_t Address, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);
void printBarrierOption(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);
- void printBarriernXSOption(const MCInst *MI, unsigned OpNum,
- const MCSubtargetInfo &STI, raw_ostream &O);
+ void printBarriernXSOption(const MCInst *MI, unsigned OpNum,
+ const MCSubtargetInfo &STI, raw_ostream &O);
void printMSRSystemRegister(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);
void printMRSSystemRegister(const MCInst *MI, unsigned OpNum,
@@ -190,8 +190,8 @@ protected:
const MCSubtargetInfo &STI, raw_ostream &O);
void printGPR64as32(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);
- void printGPR64x8(const MCInst *MI, unsigned OpNum,
- const MCSubtargetInfo &STI, raw_ostream &O);
+ void printGPR64x8(const MCInst *MI, unsigned OpNum,
+ const MCSubtargetInfo &STI, raw_ostream &O);
template <int Width>
void printZPRasFPR(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);
@@ -208,7 +208,7 @@ public:
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
const MCSubtargetInfo &STI, raw_ostream &O) override;
- std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
+ std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
void printInstruction(const MCInst *MI, uint64_t Address,
const MCSubtargetInfo &STI, raw_ostream &O) override;
bool printAliasInstr(const MCInst *MI, uint64_t Address,
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
index 257ecd33d2..68c721cb0d 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
@@ -73,7 +73,7 @@ AArch64MCAsmInfoELF::AArch64MCAsmInfoELF(const Triple &T) {
// targeting ELF.
AssemblerDialect = AsmWriterVariant == Default ? Generic : AsmWriterVariant;
- CodePointerSize = T.getEnvironment() == Triple::GNUILP32 ? 4 : 8;
+ CodePointerSize = T.getEnvironment() == Triple::GNUILP32 ? 4 : 8;
// ".comm align is in bytes but .align is pow-2."
AlignmentIsInBytes = false;
@@ -111,7 +111,7 @@ AArch64MCAsmInfoMicrosoftCOFF::AArch64MCAsmInfoMicrosoftCOFF() {
SupportsDebugInformation = true;
CodePointerSize = 8;
- CommentString = "//";
+ CommentString = "//";
ExceptionsType = ExceptionHandling::WinEH;
WinEHEncodingType = WinEH::EncodingType::Itanium;
}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp
index dd975cd363..844bd6bbad 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp
@@ -70,7 +70,7 @@ StringRef AArch64MCExpr::getVariantKindName() const {
case VK_ABS_PAGE_NC: return ":pg_hi21_nc:";
case VK_GOT: return ":got:";
case VK_GOT_PAGE: return ":got:";
- case VK_GOT_PAGE_LO15: return ":gotpage_lo15:";
+ case VK_GOT_PAGE_LO15: return ":gotpage_lo15:";
case VK_GOT_LO12: return ":got_lo12:";
case VK_GOTTPREL: return ":gottprel:";
case VK_GOTTPREL_PAGE: return ":gottprel:";
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
index 6e191cd455..d3e834a140 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
+++ b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
@@ -46,7 +46,7 @@ public:
VK_G1 = 0x050,
VK_G2 = 0x060,
VK_G3 = 0x070,
- VK_LO15 = 0x080,
+ VK_LO15 = 0x080,
VK_AddressFragBits = 0x0f0,
// Whether the final relocation is a checked one (where a linker should
@@ -83,7 +83,7 @@ public:
VK_PREL_G0_NC = VK_PREL | VK_G0 | VK_NC,
VK_GOT_LO12 = VK_GOT | VK_PAGEOFF | VK_NC,
VK_GOT_PAGE = VK_GOT | VK_PAGE,
- VK_GOT_PAGE_LO15 = VK_GOT | VK_LO15 | VK_NC,
+ VK_GOT_PAGE_LO15 = VK_GOT | VK_LO15 | VK_NC,
VK_DTPREL_G2 = VK_DTPREL | VK_G2,
VK_DTPREL_G1 = VK_DTPREL | VK_G1,
VK_DTPREL_G1_NC = VK_DTPREL | VK_G1 | VK_NC,
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp
index 98dcd9a96a..3c2df1621e 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp
@@ -50,14 +50,14 @@ static MCInstrInfo *createAArch64MCInstrInfo() {
static MCSubtargetInfo *
createAArch64MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
- if (CPU.empty()) {
+ if (CPU.empty()) {
CPU = "generic";
- if (TT.isArm64e())
- CPU = "apple-a12";
- }
-
- return createAArch64MCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
+ if (TT.isArm64e())
+ CPU = "apple-a12";
+ }
+
+ return createAArch64MCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
}
void AArch64_MC::initLLVMToCVRegMapping(MCRegisterInfo *MRI) {
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp
index f2384aa588..012661edbb 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp
@@ -373,11 +373,11 @@ void AArch64MachObjectWriter::recordRelocation(
Type == MachO::ARM64_RELOC_PAGE21 ||
Type == MachO::ARM64_RELOC_PAGEOFF12) &&
Value) {
- if (!isInt<24>(Value)) {
- Asm.getContext().reportError(Fixup.getLoc(),
- "addend too big for relocation");
- return;
- }
+ if (!isInt<24>(Value)) {
+ Asm.getContext().reportError(Fixup.getLoc(),
+ "addend too big for relocation");
+ return;
+ }
MachO::any_relocation_info MRE;
MRE.r_word0 = FixupOffset;
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
index 8f3e876061..f32a8f15b8 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
@@ -11,23 +11,23 @@
//===----------------------------------------------------------------------===//
#include "AArch64TargetStreamer.h"
-#include "AArch64MCAsmInfo.h"
-#include "AArch64Subtarget.h"
-#include "llvm/BinaryFormat/ELF.h"
+#include "AArch64MCAsmInfo.h"
+#include "AArch64Subtarget.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/ConstantPools.h"
-#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSection.h"
-#include "llvm/MC/MCSectionELF.h"
+#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/CommandLine.h"
using namespace llvm;
-static cl::opt<bool> MarkBTIProperty(
- "aarch64-mark-bti-property", cl::Hidden,
- cl::desc("Add .note.gnu.property with BTI to assembly files"),
- cl::init(false));
-
+static cl::opt<bool> MarkBTIProperty(
+ "aarch64-mark-bti-property", cl::Hidden,
+ cl::desc("Add .note.gnu.property with BTI to assembly files"),
+ cl::init(false));
+
//
// AArch64TargetStreamer Implemenation
//
@@ -48,51 +48,51 @@ void AArch64TargetStreamer::emitCurrentConstantPool() {
ConstantPools->emitForCurrentSection(Streamer);
}
-// finish() - write out any non-empty assembler constant pools and
-// write out note.gnu.properties if need.
-void AArch64TargetStreamer::finish() {
- ConstantPools->emitAll(Streamer);
-
- if (MarkBTIProperty)
- emitNoteSection(ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI);
-}
-
-void AArch64TargetStreamer::emitNoteSection(unsigned Flags) {
- if (Flags == 0)
- return;
-
- MCStreamer &OutStreamer = getStreamer();
- MCContext &Context = OutStreamer.getContext();
- // Emit a .note.gnu.property section with the flags.
- MCSectionELF *Nt = Context.getELFSection(".note.gnu.property", ELF::SHT_NOTE,
- ELF::SHF_ALLOC);
- if (Nt->isRegistered()) {
- SMLoc Loc;
- Context.reportWarning(
- Loc,
- "The .note.gnu.property is not emitted because it is already present.");
- return;
- }
- MCSection *Cur = OutStreamer.getCurrentSectionOnly();
- OutStreamer.SwitchSection(Nt);
-
- // Emit the note header.
- OutStreamer.emitValueToAlignment(Align(8).value());
- OutStreamer.emitIntValue(4, 4); // data size for "GNU\0"
- OutStreamer.emitIntValue(4 * 4, 4); // Elf_Prop size
- OutStreamer.emitIntValue(ELF::NT_GNU_PROPERTY_TYPE_0, 4);
- OutStreamer.emitBytes(StringRef("GNU", 4)); // note name
-
- // Emit the PAC/BTI properties.
- OutStreamer.emitIntValue(ELF::GNU_PROPERTY_AARCH64_FEATURE_1_AND, 4);
- OutStreamer.emitIntValue(4, 4); // data size
- OutStreamer.emitIntValue(Flags, 4); // data
- OutStreamer.emitIntValue(0, 4); // pad
-
- OutStreamer.endSection(Nt);
- OutStreamer.SwitchSection(Cur);
-}
-
+// finish() - write out any non-empty assembler constant pools and
+// write out note.gnu.properties if need.
+void AArch64TargetStreamer::finish() {
+ ConstantPools->emitAll(Streamer);
+
+ if (MarkBTIProperty)
+ emitNoteSection(ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI);
+}
+
+void AArch64TargetStreamer::emitNoteSection(unsigned Flags) {
+ if (Flags == 0)
+ return;
+
+ MCStreamer &OutStreamer = getStreamer();
+ MCContext &Context = OutStreamer.getContext();
+ // Emit a .note.gnu.property section with the flags.
+ MCSectionELF *Nt = Context.getELFSection(".note.gnu.property", ELF::SHT_NOTE,
+ ELF::SHF_ALLOC);
+ if (Nt->isRegistered()) {
+ SMLoc Loc;
+ Context.reportWarning(
+ Loc,
+ "The .note.gnu.property is not emitted because it is already present.");
+ return;
+ }
+ MCSection *Cur = OutStreamer.getCurrentSectionOnly();
+ OutStreamer.SwitchSection(Nt);
+
+ // Emit the note header.
+ OutStreamer.emitValueToAlignment(Align(8).value());
+ OutStreamer.emitIntValue(4, 4); // data size for "GNU\0"
+ OutStreamer.emitIntValue(4 * 4, 4); // Elf_Prop size
+ OutStreamer.emitIntValue(ELF::NT_GNU_PROPERTY_TYPE_0, 4);
+ OutStreamer.emitBytes(StringRef("GNU", 4)); // note name
+
+ // Emit the PAC/BTI properties.
+ OutStreamer.emitIntValue(ELF::GNU_PROPERTY_AARCH64_FEATURE_1_AND, 4);
+ OutStreamer.emitIntValue(4, 4); // data size
+ OutStreamer.emitIntValue(Flags, 4); // data
+ OutStreamer.emitIntValue(0, 4); // pad
+
+ OutStreamer.endSection(Nt);
+ OutStreamer.SwitchSection(Cur);
+}
+
void AArch64TargetStreamer::emitInst(uint32_t Inst) {
char Buffer[4];
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
index 5212d70a57..73dc1e5d4d 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
+++ b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
@@ -33,9 +33,9 @@ public:
/// Emit contents of constant pool for the current section.
void emitCurrentConstantPool();
- /// Callback used to implement the .note.gnu.property section.
- void emitNoteSection(unsigned Flags);
-
+ /// Callback used to implement the .note.gnu.property section.
+ void emitNoteSection(unsigned Flags);
+
/// Callback used to implement the .inst directive.
virtual void emitInst(uint32_t Inst);
@@ -43,14 +43,14 @@ public:
virtual void emitDirectiveVariantPCS(MCSymbol *Symbol) {};
virtual void EmitARM64WinCFIAllocStack(unsigned Size) {}
- virtual void EmitARM64WinCFISaveR19R20X(int Offset) {}
+ virtual void EmitARM64WinCFISaveR19R20X(int Offset) {}
virtual void EmitARM64WinCFISaveFPLR(int Offset) {}
virtual void EmitARM64WinCFISaveFPLRX(int Offset) {}
virtual void EmitARM64WinCFISaveReg(unsigned Reg, int Offset) {}
virtual void EmitARM64WinCFISaveRegX(unsigned Reg, int Offset) {}
virtual void EmitARM64WinCFISaveRegP(unsigned Reg, int Offset) {}
virtual void EmitARM64WinCFISaveRegPX(unsigned Reg, int Offset) {}
- virtual void EmitARM64WinCFISaveLRPair(unsigned Reg, int Offset) {}
+ virtual void EmitARM64WinCFISaveLRPair(unsigned Reg, int Offset) {}
virtual void EmitARM64WinCFISaveFReg(unsigned Reg, int Offset) {}
virtual void EmitARM64WinCFISaveFRegX(unsigned Reg, int Offset) {}
virtual void EmitARM64WinCFISaveFRegP(unsigned Reg, int Offset) {}
@@ -58,14 +58,14 @@ public:
virtual void EmitARM64WinCFISetFP() {}
virtual void EmitARM64WinCFIAddFP(unsigned Size) {}
virtual void EmitARM64WinCFINop() {}
- virtual void EmitARM64WinCFISaveNext() {}
+ virtual void EmitARM64WinCFISaveNext() {}
virtual void EmitARM64WinCFIPrologEnd() {}
virtual void EmitARM64WinCFIEpilogStart() {}
virtual void EmitARM64WinCFIEpilogEnd() {}
- virtual void EmitARM64WinCFITrapFrame() {}
- virtual void EmitARM64WinCFIMachineFrame() {}
- virtual void EmitARM64WinCFIContext() {}
- virtual void EmitARM64WinCFIClearUnwoundToCall() {}
+ virtual void EmitARM64WinCFITrapFrame() {}
+ virtual void EmitARM64WinCFIMachineFrame() {}
+ virtual void EmitARM64WinCFIContext() {}
+ virtual void EmitARM64WinCFIClearUnwoundToCall() {}
private:
std::unique_ptr<AssemblerConstantPools> ConstantPools;
@@ -96,14 +96,14 @@ public:
// The unwind codes on ARM64 Windows are documented at
// https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
void EmitARM64WinCFIAllocStack(unsigned Size) override;
- void EmitARM64WinCFISaveR19R20X(int Offset) override;
+ void EmitARM64WinCFISaveR19R20X(int Offset) override;
void EmitARM64WinCFISaveFPLR(int Offset) override;
void EmitARM64WinCFISaveFPLRX(int Offset) override;
void EmitARM64WinCFISaveReg(unsigned Reg, int Offset) override;
void EmitARM64WinCFISaveRegX(unsigned Reg, int Offset) override;
void EmitARM64WinCFISaveRegP(unsigned Reg, int Offset) override;
void EmitARM64WinCFISaveRegPX(unsigned Reg, int Offset) override;
- void EmitARM64WinCFISaveLRPair(unsigned Reg, int Offset) override;
+ void EmitARM64WinCFISaveLRPair(unsigned Reg, int Offset) override;
void EmitARM64WinCFISaveFReg(unsigned Reg, int Offset) override;
void EmitARM64WinCFISaveFRegX(unsigned Reg, int Offset) override;
void EmitARM64WinCFISaveFRegP(unsigned Reg, int Offset) override;
@@ -111,15 +111,15 @@ public:
void EmitARM64WinCFISetFP() override;
void EmitARM64WinCFIAddFP(unsigned Size) override;
void EmitARM64WinCFINop() override;
- void EmitARM64WinCFISaveNext() override;
+ void EmitARM64WinCFISaveNext() override;
void EmitARM64WinCFIPrologEnd() override;
void EmitARM64WinCFIEpilogStart() override;
void EmitARM64WinCFIEpilogEnd() override;
- void EmitARM64WinCFITrapFrame() override;
- void EmitARM64WinCFIMachineFrame() override;
- void EmitARM64WinCFIContext() override;
- void EmitARM64WinCFIClearUnwoundToCall() override;
-
+ void EmitARM64WinCFITrapFrame() override;
+ void EmitARM64WinCFIMachineFrame() override;
+ void EmitARM64WinCFIContext() override;
+ void EmitARM64WinCFIClearUnwoundToCall() override;
+
private:
void EmitARM64WinUnwindCode(unsigned UnwindCode, int Reg, int Offset);
};
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp
index 603446f40d..1c50706a26 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp
@@ -28,7 +28,7 @@ public:
void EmitWinEHHandlerData(SMLoc Loc) override;
void EmitWindowsUnwindTables() override;
- void EmitWindowsUnwindTables(WinEH::FrameInfo *Frame) override;
+ void EmitWindowsUnwindTables(WinEH::FrameInfo *Frame) override;
void finishImpl() override;
};
@@ -37,14 +37,14 @@ void AArch64WinCOFFStreamer::EmitWinEHHandlerData(SMLoc Loc) {
// We have to emit the unwind info now, because this directive
// actually switches to the .xdata section!
- EHStreamer.EmitUnwindInfo(*this, getCurrentWinFrameInfo(),
- /* HandlerData = */ true);
+ EHStreamer.EmitUnwindInfo(*this, getCurrentWinFrameInfo(),
+ /* HandlerData = */ true);
+}
+
+void AArch64WinCOFFStreamer::EmitWindowsUnwindTables(WinEH::FrameInfo *Frame) {
+ EHStreamer.EmitUnwindInfo(*this, Frame, /* HandlerData = */ false);
}
-void AArch64WinCOFFStreamer::EmitWindowsUnwindTables(WinEH::FrameInfo *Frame) {
- EHStreamer.EmitUnwindInfo(*this, Frame, /* HandlerData = */ false);
-}
-
void AArch64WinCOFFStreamer::EmitWindowsUnwindTables() {
if (!getNumWinFrameInfos())
return;
@@ -91,10 +91,10 @@ void AArch64TargetWinCOFFStreamer::EmitARM64WinCFIAllocStack(unsigned Size) {
EmitARM64WinUnwindCode(Op, -1, Size);
}
-void AArch64TargetWinCOFFStreamer::EmitARM64WinCFISaveR19R20X(int Offset) {
- EmitARM64WinUnwindCode(Win64EH::UOP_SaveR19R20X, -1, Offset);
-}
-
+void AArch64TargetWinCOFFStreamer::EmitARM64WinCFISaveR19R20X(int Offset) {
+ EmitARM64WinUnwindCode(Win64EH::UOP_SaveR19R20X, -1, Offset);
+}
+
void AArch64TargetWinCOFFStreamer::EmitARM64WinCFISaveFPLR(int Offset) {
EmitARM64WinUnwindCode(Win64EH::UOP_SaveFPLR, -1, Offset);
}
@@ -125,11 +125,11 @@ void AArch64TargetWinCOFFStreamer::EmitARM64WinCFISaveRegPX(unsigned Reg,
EmitARM64WinUnwindCode(Win64EH::UOP_SaveRegPX, Reg, Offset);
}
-void AArch64TargetWinCOFFStreamer::EmitARM64WinCFISaveLRPair(unsigned Reg,
- int Offset) {
- EmitARM64WinUnwindCode(Win64EH::UOP_SaveLRPair, Reg, Offset);
-}
-
+void AArch64TargetWinCOFFStreamer::EmitARM64WinCFISaveLRPair(unsigned Reg,
+ int Offset) {
+ EmitARM64WinUnwindCode(Win64EH::UOP_SaveLRPair, Reg, Offset);
+}
+
void AArch64TargetWinCOFFStreamer::EmitARM64WinCFISaveFReg(unsigned Reg,
int Offset) {
assert(Offset >= 0 && Offset <= 504 &&
@@ -165,10 +165,10 @@ void AArch64TargetWinCOFFStreamer::EmitARM64WinCFINop() {
EmitARM64WinUnwindCode(Win64EH::UOP_Nop, -1, 0);
}
-void AArch64TargetWinCOFFStreamer::EmitARM64WinCFISaveNext() {
- EmitARM64WinUnwindCode(Win64EH::UOP_SaveNext, -1, 0);
-}
-
+void AArch64TargetWinCOFFStreamer::EmitARM64WinCFISaveNext() {
+ EmitARM64WinUnwindCode(Win64EH::UOP_SaveNext, -1, 0);
+}
+
// The functions below handle opcodes that can end up in either a prolog or
// an epilog, but not both.
void AArch64TargetWinCOFFStreamer::EmitARM64WinCFIPrologEnd() {
@@ -207,22 +207,22 @@ void AArch64TargetWinCOFFStreamer::EmitARM64WinCFIEpilogEnd() {
CurrentEpilog = nullptr;
}
-void AArch64TargetWinCOFFStreamer::EmitARM64WinCFITrapFrame() {
- EmitARM64WinUnwindCode(Win64EH::UOP_TrapFrame, -1, 0);
-}
-
-void AArch64TargetWinCOFFStreamer::EmitARM64WinCFIMachineFrame() {
- EmitARM64WinUnwindCode(Win64EH::UOP_PushMachFrame, -1, 0);
-}
-
-void AArch64TargetWinCOFFStreamer::EmitARM64WinCFIContext() {
- EmitARM64WinUnwindCode(Win64EH::UOP_Context, -1, 0);
-}
-
-void AArch64TargetWinCOFFStreamer::EmitARM64WinCFIClearUnwoundToCall() {
- EmitARM64WinUnwindCode(Win64EH::UOP_ClearUnwoundToCall, -1, 0);
-}
-
+void AArch64TargetWinCOFFStreamer::EmitARM64WinCFITrapFrame() {
+ EmitARM64WinUnwindCode(Win64EH::UOP_TrapFrame, -1, 0);
+}
+
+void AArch64TargetWinCOFFStreamer::EmitARM64WinCFIMachineFrame() {
+ EmitARM64WinUnwindCode(Win64EH::UOP_PushMachFrame, -1, 0);
+}
+
+void AArch64TargetWinCOFFStreamer::EmitARM64WinCFIContext() {
+ EmitARM64WinUnwindCode(Win64EH::UOP_Context, -1, 0);
+}
+
+void AArch64TargetWinCOFFStreamer::EmitARM64WinCFIClearUnwoundToCall() {
+ EmitARM64WinUnwindCode(Win64EH::UOP_ClearUnwoundToCall, -1, 0);
+}
+
MCWinCOFFStreamer *createAArch64WinCOFFStreamer(
MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter,
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/ya.make b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/ya.make
index 9a6f23a3c8..18b5c7460f 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/ya.make
+++ b/contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc/ya.make
@@ -12,19 +12,19 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target/AArch64/TargetInfo
- contrib/libs/llvm12/lib/Target/AArch64/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target/AArch64/TargetInfo
+ contrib/libs/llvm12/lib/Target/AArch64/Utils
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64
- contrib/libs/llvm12/lib/Target/AArch64
- contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64
+ contrib/libs/llvm12/lib/Target/AArch64
+ contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/SVEInstrFormats.td b/contrib/libs/llvm12/lib/Target/AArch64/SVEInstrFormats.td
index 0c31ac1f9a..4eecf72862 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/SVEInstrFormats.td
+++ b/contrib/libs/llvm12/lib/Target/AArch64/SVEInstrFormats.td
@@ -206,20 +206,20 @@ def SVELogicalImm64Pat : ComplexPattern<i64, 1, "SelectSVELogicalImm<MVT::i64>",
def SVE8BitLslImm : ComplexPattern<i32, 2, "SelectSVE8BitLslImm", [imm]>;
-def SVEArithUImm8Pat : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i8>", []>;
-def SVEArithUImm16Pat : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i16>", []>;
-def SVEArithUImm32Pat : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i32>", []>;
-def SVEArithUImm64Pat : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i64>", []>;
+def SVEArithUImm8Pat : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i8>", []>;
+def SVEArithUImm16Pat : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i16>", []>;
+def SVEArithUImm32Pat : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i32>", []>;
+def SVEArithUImm64Pat : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i64>", []>;
def SVEArithSImmPat : ComplexPattern<i32, 1, "SelectSVESignedArithImm", []>;
-def SVEShiftImmL8 : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 7>", []>;
-def SVEShiftImmL16 : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 15>", []>;
-def SVEShiftImmL32 : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 31>", []>;
-def SVEShiftImmL64 : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 63>", []>;
-def SVEShiftImmR8 : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 8, true>", []>;
-def SVEShiftImmR16 : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 16, true>", []>;
-def SVEShiftImmR32 : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 32, true>", []>;
-def SVEShiftImmR64 : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 64, true>", []>;
+def SVEShiftImmL8 : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 7>", []>;
+def SVEShiftImmL16 : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 15>", []>;
+def SVEShiftImmL32 : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 31>", []>;
+def SVEShiftImmL64 : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 63>", []>;
+def SVEShiftImmR8 : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 8, true>", []>;
+def SVEShiftImmR16 : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 16, true>", []>;
+def SVEShiftImmR32 : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 32, true>", []>;
+def SVEShiftImmR64 : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 64, true>", []>;
class SVEExactFPImm<string Suffix, string ValA, string ValB> : AsmOperandClass {
let Name = "SVEExactFPImmOperand" # Suffix;
@@ -280,8 +280,8 @@ class sve_int_ptrue<bits<2> sz8_64, bits<3> opc, string asm, PPRRegOp pprty,
let Inst{3-0} = Pd;
let Defs = !if(!eq (opc{0}, 1), [NZCV], []);
- let ElementSize = pprty.ElementSize;
- let isReMaterializable = 1;
+ let ElementSize = pprty.ElementSize;
+ let isReMaterializable = 1;
}
multiclass sve_int_ptrue<bits<3> opc, string asm, SDPatternOperator op> {
@@ -317,18 +317,18 @@ class SVE_1_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
: Pat<(vtd (op vt1:$Op1)),
(inst $Op1)>;
-class SVE_1_Op_Passthru_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
- ValueType vts, Instruction inst>
-: Pat<(vtd (op pg:$Op1, vts:$Op2, vtd:$Op3)),
- (inst $Op3, $Op1, $Op2)>;
-
-// Used to match FP_ROUND_MERGE_PASSTHRU, which has an additional flag for the
-// type of rounding. This is matched by timm0_1 in pattern below and ignored.
-class SVE_1_Op_Passthru_Round_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
- ValueType vts, Instruction inst>
-: Pat<(vtd (op pg:$Op1, vts:$Op2, (i64 timm0_1), vtd:$Op3)),
- (inst $Op3, $Op1, $Op2)>;
-
+class SVE_1_Op_Passthru_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
+ ValueType vts, Instruction inst>
+: Pat<(vtd (op pg:$Op1, vts:$Op2, vtd:$Op3)),
+ (inst $Op3, $Op1, $Op2)>;
+
+// Used to match FP_ROUND_MERGE_PASSTHRU, which has an additional flag for the
+// type of rounding. This is matched by timm0_1 in pattern below and ignored.
+class SVE_1_Op_Passthru_Round_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
+ ValueType vts, Instruction inst>
+: Pat<(vtd (op pg:$Op1, vts:$Op2, (i64 timm0_1), vtd:$Op3)),
+ (inst $Op3, $Op1, $Op2)>;
+
class SVE_1_Op_Imm_OptLsl_Reverse_Pat<ValueType vt, SDPatternOperator op, ZPRRegOp zprty,
ValueType it, ComplexPattern cpx, Instruction inst>
: Pat<(vt (op (vt (AArch64dup (it (cpx i32:$imm, i32:$shift)))), (vt zprty:$Op1))),
@@ -354,11 +354,11 @@ class SVE_2_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
: Pat<(vtd (op vt1:$Op1, vt2:$Op2)),
(inst $Op1, $Op2)>;
-class SVE_2_Op_Pred_All_Active<ValueType vtd, SDPatternOperator op,
- ValueType pt, ValueType vt1, ValueType vt2,
- Instruction inst>
-: Pat<(vtd (op (pt (AArch64ptrue 31)), vt1:$Op1, vt2:$Op2)),
- (inst $Op1, $Op2)>;
+class SVE_2_Op_Pred_All_Active<ValueType vtd, SDPatternOperator op,
+ ValueType pt, ValueType vt1, ValueType vt2,
+ Instruction inst>
+: Pat<(vtd (op (pt (AArch64ptrue 31)), vt1:$Op1, vt2:$Op2)),
+ (inst $Op1, $Op2)>;
class SVE_3_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
ValueType vt2, ValueType vt3, Instruction inst>
@@ -418,23 +418,23 @@ class SVE_2_Op_AllActive_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
: Pat<(vtd (op vt1:$Op1, vt2:$Op2)),
(inst (ptrue 31), $Op1, $Op2)>;
-class SVE_InReg_Extend<ValueType vt, SDPatternOperator op, ValueType pt,
- ValueType inreg_vt, Instruction inst>
-: Pat<(vt (op pt:$Pg, vt:$Src, inreg_vt, vt:$PassThru)),
- (inst $PassThru, $Pg, $Src)>;
-
-class SVE_Shift_DupImm_Pred_Pat<ValueType vt, SDPatternOperator op,
- ValueType pt, ValueType it,
- ComplexPattern cast, Instruction inst>
-: Pat<(vt (op pt:$Pg, vt:$Rn, (vt (AArch64dup (it (cast i32:$imm)))))),
- (inst $Pg, $Rn, i32:$imm)>;
-
-class SVE_Shift_DupImm_All_Active_Pat<ValueType vt, SDPatternOperator op,
- ValueType pt, ValueType it,
- ComplexPattern cast, Instruction inst>
-: Pat<(vt (op (pt (AArch64ptrue 31)), vt:$Rn, (vt (AArch64dup (it (cast i32:$imm)))))),
- (inst $Rn, i32:$imm)>;
-
+class SVE_InReg_Extend<ValueType vt, SDPatternOperator op, ValueType pt,
+ ValueType inreg_vt, Instruction inst>
+: Pat<(vt (op pt:$Pg, vt:$Src, inreg_vt, vt:$PassThru)),
+ (inst $PassThru, $Pg, $Src)>;
+
+class SVE_Shift_DupImm_Pred_Pat<ValueType vt, SDPatternOperator op,
+ ValueType pt, ValueType it,
+ ComplexPattern cast, Instruction inst>
+: Pat<(vt (op pt:$Pg, vt:$Rn, (vt (AArch64dup (it (cast i32:$imm)))))),
+ (inst $Pg, $Rn, i32:$imm)>;
+
+class SVE_Shift_DupImm_All_Active_Pat<ValueType vt, SDPatternOperator op,
+ ValueType pt, ValueType it,
+ ComplexPattern cast, Instruction inst>
+: Pat<(vt (op (pt (AArch64ptrue 31)), vt:$Rn, (vt (AArch64dup (it (cast i32:$imm)))))),
+ (inst $Rn, i32:$imm)>;
+
//
// Pseudo -> Instruction mappings
//
@@ -511,8 +511,8 @@ class sve_int_pfalse<bits<6> opc, string asm>
let Inst{9} = opc{0};
let Inst{8-4} = 0b00000;
let Inst{3-0} = Pd;
-
- let isReMaterializable = 1;
+
+ let isReMaterializable = 1;
}
class sve_int_ptest<bits<6> opc, string asm>
@@ -533,7 +533,7 @@ class sve_int_ptest<bits<6> opc, string asm>
let Inst{4-0} = 0b00000;
let Defs = [NZCV];
- let isCompare = 1;
+ let isCompare = 1;
}
class sve_int_pfirst_next<bits<2> sz8_64, bits<5> opc, string asm,
@@ -1014,8 +1014,8 @@ multiclass sve_int_perm_dup_i<string asm> {
(!cast<Instruction>(NAME # _Q) ZPR128:$Zd, FPR128asZPR:$Qn, 0), 2>;
}
-class sve_int_perm_tbl<bits<2> sz8_64, bits<2> opc, string asm, ZPRRegOp zprty,
- RegisterOperand VecList>
+class sve_int_perm_tbl<bits<2> sz8_64, bits<2> opc, string asm, ZPRRegOp zprty,
+ RegisterOperand VecList>
: I<(outs zprty:$Zd), (ins VecList:$Zn, zprty:$Zm),
asm, "\t$Zd, $Zn, $Zm",
"",
@@ -1057,8 +1057,8 @@ multiclass sve_int_perm_tbl<string asm, SDPatternOperator op> {
def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
-
- def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8i16, !cast<Instruction>(NAME # _H)>;
+
+ def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8i16, !cast<Instruction>(NAME # _H)>;
}
multiclass sve2_int_perm_tbl<string asm, SDPatternOperator op> {
@@ -1101,11 +1101,11 @@ multiclass sve2_int_perm_tbl<string asm, SDPatternOperator op> {
(nxv2f64 (!cast<Instruction>(NAME # _D) (REG_SEQUENCE ZPR2, nxv2f64:$Op1, zsub0,
nxv2f64:$Op2, zsub1),
nxv2i64:$Op3))>;
-
- def : Pat<(nxv8bf16 (op nxv8bf16:$Op1, nxv8bf16:$Op2, nxv8i16:$Op3)),
- (nxv8bf16 (!cast<Instruction>(NAME # _H) (REG_SEQUENCE ZPR2, nxv8bf16:$Op1, zsub0,
- nxv8bf16:$Op2, zsub1),
- nxv8i16:$Op3))>;
+
+ def : Pat<(nxv8bf16 (op nxv8bf16:$Op1, nxv8bf16:$Op2, nxv8i16:$Op3)),
+ (nxv8bf16 (!cast<Instruction>(NAME # _H) (REG_SEQUENCE ZPR2, nxv8bf16:$Op1, zsub0,
+ nxv8bf16:$Op2, zsub1),
+ nxv8i16:$Op3))>;
}
class sve2_int_perm_tbx<bits<2> sz8_64, string asm, ZPRRegOp zprty>
@@ -1141,8 +1141,8 @@ multiclass sve2_int_perm_tbx<string asm, SDPatternOperator op> {
def : SVE_3_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
def : SVE_3_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
-
- def : SVE_3_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, nxv8i16, !cast<Instruction>(NAME # _H)>;
+
+ def : SVE_3_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, nxv8i16, !cast<Instruction>(NAME # _H)>;
}
class sve_int_perm_reverse_z<bits<2> sz8_64, string asm, ZPRRegOp zprty>
@@ -1173,8 +1173,8 @@ multiclass sve_int_perm_reverse_z<string asm, SDPatternOperator op> {
def : SVE_1_Op_Pat<nxv8f16, op, nxv8f16, !cast<Instruction>(NAME # _H)>;
def : SVE_1_Op_Pat<nxv4f32, op, nxv4f32, !cast<Instruction>(NAME # _S)>;
def : SVE_1_Op_Pat<nxv2f64, op, nxv2f64, !cast<Instruction>(NAME # _D)>;
-
- def : SVE_1_Op_Pat<nxv8bf16, op, nxv8bf16, !cast<Instruction>(NAME # _H)>;
+
+ def : SVE_1_Op_Pat<nxv8bf16, op, nxv8bf16, !cast<Instruction>(NAME # _H)>;
}
class sve_int_perm_reverse_p<bits<2> sz8_64, string asm, PPRRegOp pprty>
@@ -1287,8 +1287,8 @@ multiclass sve_int_perm_insrv<string asm, SDPatternOperator op> {
def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, f16, !cast<Instruction>(NAME # _H)>;
def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, f32, !cast<Instruction>(NAME # _S)>;
def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, f64, !cast<Instruction>(NAME # _D)>;
-
- def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, bf16, !cast<Instruction>(NAME # _H)>;
+
+ def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, bf16, !cast<Instruction>(NAME # _H)>;
}
//===----------------------------------------------------------------------===//
@@ -1375,8 +1375,8 @@ multiclass sve_int_sel_vvv<string asm, SDPatternOperator op> {
def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _D)>;
def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
- def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
-
+ def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
+
def : InstAlias<"mov $Zd, $Pg/m, $Zn",
(!cast<Instruction>(NAME # _B) ZPR8:$Zd, PPRAny:$Pg, ZPR8:$Zn, ZPR8:$Zd), 1>;
def : InstAlias<"mov $Zd, $Pg/m, $Zn",
@@ -1713,8 +1713,8 @@ class sve_fp_3op_u_zd<bits<2> sz, bits<3> opc, string asm, ZPRRegOp zprty>
let Inst{4-0} = Zd;
}
-multiclass sve_fp_3op_u_zd<bits<3> opc, string asm, SDPatternOperator op,
- SDPatternOperator predicated_op = null_frag> {
+multiclass sve_fp_3op_u_zd<bits<3> opc, string asm, SDPatternOperator op,
+ SDPatternOperator predicated_op = null_frag> {
def _H : sve_fp_3op_u_zd<0b01, opc, asm, ZPR16>;
def _S : sve_fp_3op_u_zd<0b10, opc, asm, ZPR32>;
def _D : sve_fp_3op_u_zd<0b11, opc, asm, ZPR64>;
@@ -1723,9 +1723,9 @@ multiclass sve_fp_3op_u_zd<bits<3> opc, string asm, SDPatternOperator op,
def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
- def : SVE_2_Op_Pred_All_Active<nxv8f16, predicated_op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
- def : SVE_2_Op_Pred_All_Active<nxv4f32, predicated_op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
- def : SVE_2_Op_Pred_All_Active<nxv2f64, predicated_op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
+ def : SVE_2_Op_Pred_All_Active<nxv8f16, predicated_op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_2_Op_Pred_All_Active<nxv4f32, predicated_op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_2_Op_Pred_All_Active<nxv2f64, predicated_op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
}
multiclass sve_fp_3op_u_zd_ftsmul<bits<3> opc, string asm, SDPatternOperator op> {
@@ -2117,8 +2117,8 @@ class sve2_fp_pairwise_pred<bits<2> sz, bits<3> opc, string asm,
let ElementSize = zprty.ElementSize;
}
-multiclass sve2_fp_pairwise_pred<bits<3> opc, string asm,
- SDPatternOperator op> {
+multiclass sve2_fp_pairwise_pred<bits<3> opc, string asm,
+ SDPatternOperator op> {
def _H : sve2_fp_pairwise_pred<0b01, opc, asm, ZPR16>;
def _S : sve2_fp_pairwise_pred<0b10, opc, asm, ZPR32>;
def _D : sve2_fp_pairwise_pred<0b11, opc, asm, ZPR64>;
@@ -2270,11 +2270,11 @@ multiclass sve_int_perm_bin_perm_zz<bits<3> opc, string asm,
def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
def : SVE_2_Op_Pat<nxv4f16, op, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _S)>;
def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
- def : SVE_2_Op_Pat<nxv2f16, op, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _D)>;
- def : SVE_2_Op_Pat<nxv2f32, op, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _D)>;
+ def : SVE_2_Op_Pat<nxv2f16, op, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _D)>;
+ def : SVE_2_Op_Pat<nxv2f32, op, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _D)>;
def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
-
- def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
+
+ def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
}
//===----------------------------------------------------------------------===//
@@ -2282,7 +2282,7 @@ multiclass sve_int_perm_bin_perm_zz<bits<3> opc, string asm,
//===----------------------------------------------------------------------===//
class sve_fp_2op_p_zd<bits<7> opc, string asm, RegisterOperand i_zprtype,
- RegisterOperand o_zprtype, ElementSizeEnum Sz>
+ RegisterOperand o_zprtype, ElementSizeEnum Sz>
: I<(outs o_zprtype:$Zd), (ins i_zprtype:$_Zd, PPR3bAny:$Pg, i_zprtype:$Zn),
asm, "\t$Zd, $Pg/m, $Zn",
"",
@@ -2301,64 +2301,64 @@ class sve_fp_2op_p_zd<bits<7> opc, string asm, RegisterOperand i_zprtype,
let Constraints = "$Zd = $_Zd";
let DestructiveInstType = DestructiveOther;
- let ElementSize = Sz;
+ let ElementSize = Sz;
}
multiclass sve_fp_2op_p_zd<bits<7> opc, string asm,
RegisterOperand i_zprtype,
RegisterOperand o_zprtype,
- SDPatternOperator int_op,
- SDPatternOperator ir_op, ValueType vt1,
+ SDPatternOperator int_op,
+ SDPatternOperator ir_op, ValueType vt1,
ValueType vt2, ValueType vt3, ElementSizeEnum Sz> {
def NAME : sve_fp_2op_p_zd<opc, asm, i_zprtype, o_zprtype, Sz>;
- // convert vt1 to a packed type for the intrinsic patterns
- defvar packedvt1 = !cond(!eq(!cast<string>(vt1), "nxv2f16"): nxv8f16,
- !eq(!cast<string>(vt1), "nxv4f16"): nxv8f16,
- !eq(!cast<string>(vt1), "nxv2f32"): nxv4f32,
- 1 : vt1);
-
- // convert vt3 to a packed type for the intrinsic patterns
- defvar packedvt3 = !cond(!eq(!cast<string>(vt3), "nxv2f16"): nxv8f16,
- !eq(!cast<string>(vt3), "nxv4f16"): nxv8f16,
- !eq(!cast<string>(vt3), "nxv2f32"): nxv4f32,
- 1 : vt3);
-
- def : SVE_3_Op_Pat<packedvt1, int_op, packedvt1, vt2, packedvt3, !cast<Instruction>(NAME)>;
-
- def : SVE_1_Op_Passthru_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME)>;
-}
-
-multiclass sve_fp_2op_p_zdr<bits<7> opc, string asm,
- RegisterOperand i_zprtype,
- RegisterOperand o_zprtype,
- SDPatternOperator int_op,
- SDPatternOperator ir_op, ValueType vt1,
- ValueType vt2, ValueType vt3, ElementSizeEnum Sz> {
- def NAME : sve_fp_2op_p_zd<opc, asm, i_zprtype, o_zprtype, Sz>;
-
- // convert vt1 to a packed type for the intrinsic patterns
- defvar packedvt1 = !cond(!eq(!cast<string>(vt1), "nxv2f16"): nxv8f16,
- !eq(!cast<string>(vt1), "nxv4f16"): nxv8f16,
- !eq(!cast<string>(vt1), "nxv2f32"): nxv4f32,
- 1 : vt1);
-
- def : SVE_3_Op_Pat<packedvt1, int_op, packedvt1, vt2, vt3, !cast<Instruction>(NAME)>;
-
- def : SVE_1_Op_Passthru_Round_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME)>;
-}
-
+ // convert vt1 to a packed type for the intrinsic patterns
+ defvar packedvt1 = !cond(!eq(!cast<string>(vt1), "nxv2f16"): nxv8f16,
+ !eq(!cast<string>(vt1), "nxv4f16"): nxv8f16,
+ !eq(!cast<string>(vt1), "nxv2f32"): nxv4f32,
+ 1 : vt1);
+
+ // convert vt3 to a packed type for the intrinsic patterns
+ defvar packedvt3 = !cond(!eq(!cast<string>(vt3), "nxv2f16"): nxv8f16,
+ !eq(!cast<string>(vt3), "nxv4f16"): nxv8f16,
+ !eq(!cast<string>(vt3), "nxv2f32"): nxv4f32,
+ 1 : vt3);
+
+ def : SVE_3_Op_Pat<packedvt1, int_op, packedvt1, vt2, packedvt3, !cast<Instruction>(NAME)>;
+
+ def : SVE_1_Op_Passthru_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME)>;
+}
+
+multiclass sve_fp_2op_p_zdr<bits<7> opc, string asm,
+ RegisterOperand i_zprtype,
+ RegisterOperand o_zprtype,
+ SDPatternOperator int_op,
+ SDPatternOperator ir_op, ValueType vt1,
+ ValueType vt2, ValueType vt3, ElementSizeEnum Sz> {
+ def NAME : sve_fp_2op_p_zd<opc, asm, i_zprtype, o_zprtype, Sz>;
+
+ // convert vt1 to a packed type for the intrinsic patterns
+ defvar packedvt1 = !cond(!eq(!cast<string>(vt1), "nxv2f16"): nxv8f16,
+ !eq(!cast<string>(vt1), "nxv4f16"): nxv8f16,
+ !eq(!cast<string>(vt1), "nxv2f32"): nxv4f32,
+ 1 : vt1);
+
+ def : SVE_3_Op_Pat<packedvt1, int_op, packedvt1, vt2, vt3, !cast<Instruction>(NAME)>;
+
+ def : SVE_1_Op_Passthru_Round_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME)>;
+}
+
multiclass sve_fp_2op_p_zd_HSD<bits<5> opc, string asm, SDPatternOperator op> {
def _H : sve_fp_2op_p_zd<{ 0b01, opc }, asm, ZPR16, ZPR16, ElementSizeH>;
def _S : sve_fp_2op_p_zd<{ 0b10, opc }, asm, ZPR32, ZPR32, ElementSizeS>;
def _D : sve_fp_2op_p_zd<{ 0b11, opc }, asm, ZPR64, ZPR64, ElementSizeD>;
- def : SVE_1_Op_Passthru_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
- def : SVE_1_Op_Passthru_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
- def : SVE_1_Op_Passthru_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
- def : SVE_1_Op_Passthru_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
- def : SVE_1_Op_Passthru_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
- def : SVE_1_Op_Passthru_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
+ def : SVE_1_Op_Passthru_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_1_Op_Passthru_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_1_Op_Passthru_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_1_Op_Passthru_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_1_Op_Passthru_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_1_Op_Passthru_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
}
multiclass sve2_fp_flogb<string asm, SDPatternOperator op> {
@@ -2466,19 +2466,19 @@ multiclass sve_int_bin_pred_arit_0<bits<3> opc, string asm, string Ps,
def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
}
-multiclass sve_int_bin_pred_arit_1<bits<3> opc, string asm, string Ps,
- SDPatternOperator op,
- DestructiveInstTypeEnum flags> {
- let DestructiveInstType = flags in {
- def _B : sve_int_bin_pred_arit_log<0b00, 0b01, opc, asm, ZPR8>,
- SVEPseudo2Instr<Ps # _B, 1>;
- def _H : sve_int_bin_pred_arit_log<0b01, 0b01, opc, asm, ZPR16>,
- SVEPseudo2Instr<Ps # _H, 1>;
- def _S : sve_int_bin_pred_arit_log<0b10, 0b01, opc, asm, ZPR32>,
- SVEPseudo2Instr<Ps # _S, 1>;
- def _D : sve_int_bin_pred_arit_log<0b11, 0b01, opc, asm, ZPR64>,
- SVEPseudo2Instr<Ps # _D, 1>;
- }
+multiclass sve_int_bin_pred_arit_1<bits<3> opc, string asm, string Ps,
+ SDPatternOperator op,
+ DestructiveInstTypeEnum flags> {
+ let DestructiveInstType = flags in {
+ def _B : sve_int_bin_pred_arit_log<0b00, 0b01, opc, asm, ZPR8>,
+ SVEPseudo2Instr<Ps # _B, 1>;
+ def _H : sve_int_bin_pred_arit_log<0b01, 0b01, opc, asm, ZPR16>,
+ SVEPseudo2Instr<Ps # _H, 1>;
+ def _S : sve_int_bin_pred_arit_log<0b10, 0b01, opc, asm, ZPR32>,
+ SVEPseudo2Instr<Ps # _S, 1>;
+ def _D : sve_int_bin_pred_arit_log<0b11, 0b01, opc, asm, ZPR64>,
+ SVEPseudo2Instr<Ps # _D, 1>;
+ }
def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
@@ -2486,19 +2486,19 @@ multiclass sve_int_bin_pred_arit_1<bits<3> opc, string asm, string Ps,
def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
}
-multiclass sve_int_bin_pred_arit_2<bits<3> opc, string asm, string Ps,
- SDPatternOperator op,
- DestructiveInstTypeEnum flags> {
- let DestructiveInstType = flags in {
- def _B : sve_int_bin_pred_arit_log<0b00, 0b10, opc, asm, ZPR8>,
- SVEPseudo2Instr<Ps # _B, 1>;
- def _H : sve_int_bin_pred_arit_log<0b01, 0b10, opc, asm, ZPR16>,
- SVEPseudo2Instr<Ps # _H, 1>;
- def _S : sve_int_bin_pred_arit_log<0b10, 0b10, opc, asm, ZPR32>,
- SVEPseudo2Instr<Ps # _S, 1>;
- def _D : sve_int_bin_pred_arit_log<0b11, 0b10, opc, asm, ZPR64>,
- SVEPseudo2Instr<Ps # _D, 1>;
- }
+multiclass sve_int_bin_pred_arit_2<bits<3> opc, string asm, string Ps,
+ SDPatternOperator op,
+ DestructiveInstTypeEnum flags> {
+ let DestructiveInstType = flags in {
+ def _B : sve_int_bin_pred_arit_log<0b00, 0b10, opc, asm, ZPR8>,
+ SVEPseudo2Instr<Ps # _B, 1>;
+ def _H : sve_int_bin_pred_arit_log<0b01, 0b10, opc, asm, ZPR16>,
+ SVEPseudo2Instr<Ps # _H, 1>;
+ def _S : sve_int_bin_pred_arit_log<0b10, 0b10, opc, asm, ZPR32>,
+ SVEPseudo2Instr<Ps # _S, 1>;
+ def _D : sve_int_bin_pred_arit_log<0b11, 0b10, opc, asm, ZPR64>,
+ SVEPseudo2Instr<Ps # _D, 1>;
+ }
def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
@@ -2588,8 +2588,8 @@ class sve_int_mlas_vvv_pred<bits<2> sz8_64, bits<1> opc, string asm,
let ElementSize = zprty.ElementSize;
}
-multiclass sve_int_mlas_vvv_pred<bits<1> opc, string asm, SDPatternOperator op,
- SDPatternOperator outerop, SDPatternOperator mulop> {
+multiclass sve_int_mlas_vvv_pred<bits<1> opc, string asm, SDPatternOperator op,
+ SDPatternOperator outerop, SDPatternOperator mulop> {
def _B : sve_int_mlas_vvv_pred<0b00, opc, asm, ZPR8>;
def _H : sve_int_mlas_vvv_pred<0b01, opc, asm, ZPR16>;
def _S : sve_int_mlas_vvv_pred<0b10, opc, asm, ZPR32>;
@@ -2599,15 +2599,15 @@ multiclass sve_int_mlas_vvv_pred<bits<1> opc, string asm, SDPatternOperator op,
def : SVE_4_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
def : SVE_4_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
def : SVE_4_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
-
- def : Pat<(outerop nxv16i8:$Op1, (mulop nxv16i1:$pred, nxv16i8:$Op2, nxv16i8:$Op3)),
- (!cast<Instruction>(NAME # _B) $pred, $Op1, $Op2, $Op3)>;
- def : Pat<(outerop nxv8i16:$Op1, (mulop nxv8i1:$pred, nxv8i16:$Op2, nxv8i16:$Op3)),
- (!cast<Instruction>(NAME # _H) $pred, $Op1, $Op2, $Op3)>;
- def : Pat<(outerop nxv4i32:$Op1, (mulop nxv4i1:$pred, nxv4i32:$Op2, nxv4i32:$Op3)),
- (!cast<Instruction>(NAME # _S) $pred, $Op1, $Op2, $Op3)>;
- def : Pat<(outerop nxv2i64:$Op1, (mulop nxv2i1:$pred, nxv2i64:$Op2, nxv2i64:$Op3)),
- (!cast<Instruction>(NAME # _D) $pred, $Op1, $Op2, $Op3)>;
+
+ def : Pat<(outerop nxv16i8:$Op1, (mulop nxv16i1:$pred, nxv16i8:$Op2, nxv16i8:$Op3)),
+ (!cast<Instruction>(NAME # _B) $pred, $Op1, $Op2, $Op3)>;
+ def : Pat<(outerop nxv8i16:$Op1, (mulop nxv8i1:$pred, nxv8i16:$Op2, nxv8i16:$Op3)),
+ (!cast<Instruction>(NAME # _H) $pred, $Op1, $Op2, $Op3)>;
+ def : Pat<(outerop nxv4i32:$Op1, (mulop nxv4i1:$pred, nxv4i32:$Op2, nxv4i32:$Op3)),
+ (!cast<Instruction>(NAME # _S) $pred, $Op1, $Op2, $Op3)>;
+ def : Pat<(outerop nxv2i64:$Op1, (mulop nxv2i1:$pred, nxv2i64:$Op2, nxv2i64:$Op3)),
+ (!cast<Instruction>(NAME # _D) $pred, $Op1, $Op2, $Op3)>;
}
//===----------------------------------------------------------------------===//
@@ -2711,8 +2711,8 @@ multiclass sve2_int_mla_by_indexed_elem<bits<2> opc, bit S, string asm,
// SVE2 Integer Multiply-Add Long - Indexed Group
//===----------------------------------------------------------------------===//
-multiclass sve2_int_mla_long_by_indexed_elem<bits<4> opc, string asm,
- SDPatternOperator op> {
+multiclass sve2_int_mla_long_by_indexed_elem<bits<4> opc, string asm,
+ SDPatternOperator op> {
def _S : sve2_int_mla_by_indexed_elem<0b10, { opc{3}, 0b0, opc{2-1}, ?, opc{0} },
asm, ZPR32, ZPR16, ZPR3b16, VectorIndexH32b> {
bits<3> Zm;
@@ -2962,8 +2962,8 @@ class sve2_int_mul<bits<2> sz, bits<3> opc, string asm, ZPRRegOp zprty>
let Inst{4-0} = Zd;
}
-multiclass sve2_int_mul<bits<3> opc, string asm, SDPatternOperator op,
- SDPatternOperator op_pred = null_frag> {
+multiclass sve2_int_mul<bits<3> opc, string asm, SDPatternOperator op,
+ SDPatternOperator op_pred = null_frag> {
def _B : sve2_int_mul<0b00, opc, asm, ZPR8>;
def _H : sve2_int_mul<0b01, opc, asm, ZPR16>;
def _S : sve2_int_mul<0b10, opc, asm, ZPR32>;
@@ -2973,11 +2973,11 @@ multiclass sve2_int_mul<bits<3> opc, string asm, SDPatternOperator op,
def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
-
- def : SVE_2_Op_Pred_All_Active<nxv16i8, op_pred, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
- def : SVE_2_Op_Pred_All_Active<nxv8i16, op_pred, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
- def : SVE_2_Op_Pred_All_Active<nxv4i32, op_pred, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
- def : SVE_2_Op_Pred_All_Active<nxv2i64, op_pred, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
+
+ def : SVE_2_Op_Pred_All_Active<nxv16i8, op_pred, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
+ def : SVE_2_Op_Pred_All_Active<nxv8i16, op_pred, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_2_Op_Pred_All_Active<nxv4i32, op_pred, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_2_Op_Pred_All_Active<nxv2i64, op_pred, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
}
multiclass sve2_int_mul_single<bits<3> opc, string asm, SDPatternOperator op> {
@@ -3531,8 +3531,8 @@ multiclass sve2_int_absdiff_accum_long<bits<2> opc, string asm,
def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
}
-multiclass sve2_int_addsub_long_carry<bits<2> opc, string asm,
- SDPatternOperator op> {
+multiclass sve2_int_addsub_long_carry<bits<2> opc, string asm,
+ SDPatternOperator op> {
def _S : sve2_int_absdiff_accum<{ opc{1}, 0b0 }, { 0b010, opc{0} }, asm,
ZPR32, ZPR32>;
def _D : sve2_int_absdiff_accum<{ opc{1}, 0b1 }, { 0b010, opc{0} }, asm,
@@ -3576,7 +3576,7 @@ multiclass sve2_int_bin_shift_imm_right_narrow_bottom<bits<3> opc, string asm,
let Inst{19} = imm{3};
}
def _S : sve2_int_bin_shift_imm_narrow_bottom<{1,?,?}, opc, asm, ZPR32, ZPR64,
- tvecshiftR32> {
+ tvecshiftR32> {
let Inst{20-19} = imm{4-3};
}
def : SVE_2_Op_Imm_Pat<nxv16i8, op, nxv8i16, i32, tvecshiftR8, !cast<Instruction>(NAME # _B)>;
@@ -3616,7 +3616,7 @@ multiclass sve2_int_bin_shift_imm_right_narrow_top<bits<3> opc, string asm,
let Inst{19} = imm{3};
}
def _S : sve2_int_bin_shift_imm_narrow_top<{1,?,?}, opc, asm, ZPR32, ZPR64,
- tvecshiftR32> {
+ tvecshiftR32> {
let Inst{20-19} = imm{4-3};
}
def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv8i16, i32, tvecshiftR8, !cast<Instruction>(NAME # _B)>;
@@ -3777,10 +3777,10 @@ multiclass sve_int_un_pred_arit_0<bits<3> opc, string asm,
def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>;
def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>;
- def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
- def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
- def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
- def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
+ def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
+ def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
}
multiclass sve_int_un_pred_arit_0_h<bits<3> opc, string asm,
@@ -3789,9 +3789,9 @@ multiclass sve_int_un_pred_arit_0_h<bits<3> opc, string asm,
def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>;
def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>;
- def : SVE_InReg_Extend<nxv8i16, op, nxv8i1, nxv8i8, !cast<Instruction>(NAME # _H)>;
- def : SVE_InReg_Extend<nxv4i32, op, nxv4i1, nxv4i8, !cast<Instruction>(NAME # _S)>;
- def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i8, !cast<Instruction>(NAME # _D)>;
+ def : SVE_InReg_Extend<nxv8i16, op, nxv8i1, nxv8i8, !cast<Instruction>(NAME # _H)>;
+ def : SVE_InReg_Extend<nxv4i32, op, nxv4i1, nxv4i8, !cast<Instruction>(NAME # _S)>;
+ def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i8, !cast<Instruction>(NAME # _D)>;
}
multiclass sve_int_un_pred_arit_0_w<bits<3> opc, string asm,
@@ -3799,15 +3799,15 @@ multiclass sve_int_un_pred_arit_0_w<bits<3> opc, string asm,
def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>;
def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>;
- def : SVE_InReg_Extend<nxv4i32, op, nxv4i1, nxv4i16, !cast<Instruction>(NAME # _S)>;
- def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i16, !cast<Instruction>(NAME # _D)>;
+ def : SVE_InReg_Extend<nxv4i32, op, nxv4i1, nxv4i16, !cast<Instruction>(NAME # _S)>;
+ def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i16, !cast<Instruction>(NAME # _D)>;
}
multiclass sve_int_un_pred_arit_0_d<bits<3> opc, string asm,
SDPatternOperator op> {
def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>;
- def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i32, !cast<Instruction>(NAME # _D)>;
+ def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i32, !cast<Instruction>(NAME # _D)>;
}
multiclass sve_int_un_pred_arit_1<bits<3> opc, string asm,
@@ -3817,23 +3817,23 @@ multiclass sve_int_un_pred_arit_1<bits<3> opc, string asm,
def _S : sve_int_un_pred_arit<0b10, { opc, 0b1 }, asm, ZPR32>;
def _D : sve_int_un_pred_arit<0b11, { opc, 0b1 }, asm, ZPR64>;
- def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
- def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
- def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
- def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
+ def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
+ def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
}
-multiclass sve_int_un_pred_arit_1_fp<bits<3> opc, string asm, SDPatternOperator op> {
+multiclass sve_int_un_pred_arit_1_fp<bits<3> opc, string asm, SDPatternOperator op> {
def _H : sve_int_un_pred_arit<0b01, { opc, 0b1 }, asm, ZPR16>;
def _S : sve_int_un_pred_arit<0b10, { opc, 0b1 }, asm, ZPR32>;
def _D : sve_int_un_pred_arit<0b11, { opc, 0b1 }, asm, ZPR64>;
- def : SVE_1_Op_Passthru_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
- def : SVE_1_Op_Passthru_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
- def : SVE_1_Op_Passthru_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
- def : SVE_1_Op_Passthru_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
- def : SVE_1_Op_Passthru_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
- def : SVE_1_Op_Passthru_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
+ def : SVE_1_Op_Passthru_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_1_Op_Passthru_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_1_Op_Passthru_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_1_Op_Passthru_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_1_Op_Passthru_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_1_Op_Passthru_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
}
//===----------------------------------------------------------------------===//
@@ -4002,10 +4002,10 @@ multiclass sve_int_arith_imm1_unsigned<bits<2> opc, string asm, SDPatternOperato
def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, imm0_255>;
def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, imm0_255>;
- def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithUImm8Pat, !cast<Instruction>(NAME # _B)>;
- def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithUImm16Pat, !cast<Instruction>(NAME # _H)>;
- def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithUImm32Pat, !cast<Instruction>(NAME # _S)>;
- def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithUImm64Pat, !cast<Instruction>(NAME # _D)>;
+ def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithUImm8Pat, !cast<Instruction>(NAME # _B)>;
+ def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithUImm16Pat, !cast<Instruction>(NAME # _H)>;
+ def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithUImm32Pat, !cast<Instruction>(NAME # _S)>;
+ def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithUImm64Pat, !cast<Instruction>(NAME # _D)>;
}
multiclass sve_int_arith_imm2<string asm, SDPatternOperator op> {
@@ -4014,10 +4014,10 @@ multiclass sve_int_arith_imm2<string asm, SDPatternOperator op> {
def _S : sve_int_arith_imm<0b10, 0b110000, asm, ZPR32, simm8>;
def _D : sve_int_arith_imm<0b11, 0b110000, asm, ZPR64, simm8>;
- def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat, !cast<Instruction>(NAME # _B)>;
- def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithSImmPat, !cast<Instruction>(NAME # _H)>;
- def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithSImmPat, !cast<Instruction>(NAME # _S)>;
- def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithSImmPat, !cast<Instruction>(NAME # _D)>;
+ def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat, !cast<Instruction>(NAME # _B)>;
+ def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithSImmPat, !cast<Instruction>(NAME # _H)>;
+ def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithSImmPat, !cast<Instruction>(NAME # _S)>;
+ def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithSImmPat, !cast<Instruction>(NAME # _D)>;
}
//===----------------------------------------------------------------------===//
@@ -4130,7 +4130,7 @@ multiclass sve2_int_rotate_right_imm<string asm, SDPatternOperator op> {
let Inst{22} = imm{5};
let Inst{20-19} = imm{4-3};
}
-
+
def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8, !cast<Instruction>(NAME # _B)>;
def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
@@ -4289,8 +4289,8 @@ class sve_int_cmp<bit cmp_1, bits<2> sz8_64, bits<3> opc, string asm,
let Inst{3-0} = Pd;
let Defs = [NZCV];
- let ElementSize = pprty.ElementSize;
- let isPTestLike = 1;
+ let ElementSize = pprty.ElementSize;
+ let isPTestLike = 1;
}
multiclass SVE_SETCC_Pat<CondCode cc, CondCode invcc, ValueType predvt,
@@ -4363,7 +4363,7 @@ class sve_int_scmp_vi<bits<2> sz8_64, bits<3> opc, string asm, PPRRegOp pprty,
let Defs = [NZCV];
let ElementSize = pprty.ElementSize;
- let isPTestLike = 1;
+ let isPTestLike = 1;
}
multiclass SVE_SETCC_Imm_Pat<CondCode cc, CondCode commuted_cc,
@@ -4423,8 +4423,8 @@ class sve_int_ucmp_vi<bits<2> sz8_64, bits<2> opc, string asm, PPRRegOp pprty,
let Inst{3-0} = Pd;
let Defs = [NZCV];
- let ElementSize = pprty.ElementSize;
- let isPTestLike = 1;
+ let ElementSize = pprty.ElementSize;
+ let isPTestLike = 1;
}
multiclass sve_int_ucmp_vi<bits<2> opc, string asm, CondCode cc,
@@ -4469,7 +4469,7 @@ class sve_int_cterm<bit sz, bit opc, string asm, RegisterClass rt>
}
class sve_int_while_rr<bits<2> sz8_64, bits<4> opc, string asm,
- RegisterClass gprty, PPRRegOp pprty>
+ RegisterClass gprty, PPRRegOp pprty>
: I<(outs pprty:$Pd), (ins gprty:$Rn, gprty:$Rm),
asm, "\t$Pd, $Rn, $Rm",
"", []>, Sched<[]> {
@@ -4487,32 +4487,32 @@ class sve_int_while_rr<bits<2> sz8_64, bits<4> opc, string asm,
let Inst{3-0} = Pd;
let Defs = [NZCV];
- let ElementSize = pprty.ElementSize;
- let isWhile = 1;
+ let ElementSize = pprty.ElementSize;
+ let isWhile = 1;
}
multiclass sve_int_while4_rr<bits<3> opc, string asm, SDPatternOperator op> {
- def _B : sve_int_while_rr<0b00, { 0, opc }, asm, GPR32, PPR8>;
- def _H : sve_int_while_rr<0b01, { 0, opc }, asm, GPR32, PPR16>;
- def _S : sve_int_while_rr<0b10, { 0, opc }, asm, GPR32, PPR32>;
- def _D : sve_int_while_rr<0b11, { 0, opc }, asm, GPR32, PPR64>;
+ def _B : sve_int_while_rr<0b00, { 0, opc }, asm, GPR32, PPR8>;
+ def _H : sve_int_while_rr<0b01, { 0, opc }, asm, GPR32, PPR16>;
+ def _S : sve_int_while_rr<0b10, { 0, opc }, asm, GPR32, PPR32>;
+ def _D : sve_int_while_rr<0b11, { 0, opc }, asm, GPR32, PPR64>;
def : SVE_2_Op_Pat<nxv16i1, op, i32, i32, !cast<Instruction>(NAME # _B)>;
- def : SVE_2_Op_Pat<nxv8i1, op, i32, i32, !cast<Instruction>(NAME # _H)>;
- def : SVE_2_Op_Pat<nxv4i1, op, i32, i32, !cast<Instruction>(NAME # _S)>;
- def : SVE_2_Op_Pat<nxv2i1, op, i32, i32, !cast<Instruction>(NAME # _D)>;
+ def : SVE_2_Op_Pat<nxv8i1, op, i32, i32, !cast<Instruction>(NAME # _H)>;
+ def : SVE_2_Op_Pat<nxv4i1, op, i32, i32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_2_Op_Pat<nxv2i1, op, i32, i32, !cast<Instruction>(NAME # _D)>;
}
multiclass sve_int_while8_rr<bits<3> opc, string asm, SDPatternOperator op> {
- def _B : sve_int_while_rr<0b00, { 1, opc }, asm, GPR64, PPR8>;
- def _H : sve_int_while_rr<0b01, { 1, opc }, asm, GPR64, PPR16>;
- def _S : sve_int_while_rr<0b10, { 1, opc }, asm, GPR64, PPR32>;
- def _D : sve_int_while_rr<0b11, { 1, opc }, asm, GPR64, PPR64>;
+ def _B : sve_int_while_rr<0b00, { 1, opc }, asm, GPR64, PPR8>;
+ def _H : sve_int_while_rr<0b01, { 1, opc }, asm, GPR64, PPR16>;
+ def _S : sve_int_while_rr<0b10, { 1, opc }, asm, GPR64, PPR32>;
+ def _D : sve_int_while_rr<0b11, { 1, opc }, asm, GPR64, PPR64>;
def : SVE_2_Op_Pat<nxv16i1, op, i64, i64, !cast<Instruction>(NAME # _B)>;
- def : SVE_2_Op_Pat<nxv8i1, op, i64, i64, !cast<Instruction>(NAME # _H)>;
- def : SVE_2_Op_Pat<nxv4i1, op, i64, i64, !cast<Instruction>(NAME # _S)>;
- def : SVE_2_Op_Pat<nxv2i1, op, i64, i64, !cast<Instruction>(NAME # _D)>;
+ def : SVE_2_Op_Pat<nxv8i1, op, i64, i64, !cast<Instruction>(NAME # _H)>;
+ def : SVE_2_Op_Pat<nxv4i1, op, i64, i64, !cast<Instruction>(NAME # _S)>;
+ def : SVE_2_Op_Pat<nxv2i1, op, i64, i64, !cast<Instruction>(NAME # _D)>;
}
class sve2_int_while_rr<bits<2> sz8_64, bits<1> rw, string asm,
@@ -4533,8 +4533,8 @@ class sve2_int_while_rr<bits<2> sz8_64, bits<1> rw, string asm,
let Inst{3-0} = Pd;
let Defs = [NZCV];
- let ElementSize = pprty.ElementSize;
- let isWhile = 1;
+ let ElementSize = pprty.ElementSize;
+ let isWhile = 1;
}
multiclass sve2_int_while_rr<bits<1> rw, string asm, string op> {
@@ -4577,10 +4577,10 @@ multiclass sve_fp_fast_red<bits<3> opc, string asm, SDPatternOperator op> {
def _S : sve_fp_fast_red<0b10, opc, asm, ZPR32, FPR32asZPR>;
def _D : sve_fp_fast_red<0b11, opc, asm, ZPR64, FPR64asZPR>;
- def : SVE_2_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
- def : SVE_2_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_2_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_2_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
def : SVE_2_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
- def : SVE_2_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_2_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
def : SVE_2_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
def : SVE_2_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
}
@@ -4616,10 +4616,10 @@ multiclass sve_fp_2op_p_vd<bits<3> opc, string asm, SDPatternOperator op> {
def _S : sve_fp_2op_p_vd<0b10, opc, asm, ZPR32, FPR32asZPR>;
def _D : sve_fp_2op_p_vd<0b11, opc, asm, ZPR64, FPR64asZPR>;
- def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H)>;
- def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H)>;
def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
- def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S)>;
def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
}
@@ -4840,11 +4840,11 @@ multiclass sve_int_index_rr<string asm, SDPatternOperator op> {
def : SVE_2_Op_Pat<nxv4i32, op, i32, i32, !cast<Instruction>(NAME # _S)>;
def : SVE_2_Op_Pat<nxv2i64, op, i64, i64, !cast<Instruction>(NAME # _D)>;
}
-
+
//===----------------------------------------------------------------------===//
// SVE Bitwise Shift - Predicated Group
//===----------------------------------------------------------------------===//
-
+
class sve_int_bin_pred_shift_imm<bits<4> tsz8_64, bits<4> opc, string asm,
ZPRRegOp zprty, Operand immtype>
: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, immtype:$imm),
@@ -4869,19 +4869,19 @@ class sve_int_bin_pred_shift_imm<bits<4> tsz8_64, bits<4> opc, string asm,
let ElementSize = zprty.ElementSize;
}
-multiclass sve_int_bin_pred_shift_imm_left<bits<4> opc, string asm, string Ps,
- SDPatternOperator op = null_frag> {
- def _B : SVEPseudo2Instr<Ps # _B, 1>,
+multiclass sve_int_bin_pred_shift_imm_left<bits<4> opc, string asm, string Ps,
+ SDPatternOperator op = null_frag> {
+ def _B : SVEPseudo2Instr<Ps # _B, 1>,
sve_int_bin_pred_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
- def _H : SVEPseudo2Instr<Ps # _H, 1>,
+ def _H : SVEPseudo2Instr<Ps # _H, 1>,
sve_int_bin_pred_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
let Inst{8} = imm{3};
}
- def _S : SVEPseudo2Instr<Ps # _S, 1>,
+ def _S : SVEPseudo2Instr<Ps # _S, 1>,
sve_int_bin_pred_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
let Inst{9-8} = imm{4-3};
}
- def _D : SVEPseudo2Instr<Ps # _D, 1>,
+ def _D : SVEPseudo2Instr<Ps # _D, 1>,
sve_int_bin_pred_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
let Inst{22} = imm{5};
let Inst{9-8} = imm{4-3};
@@ -4893,16 +4893,16 @@ multiclass sve_int_bin_pred_shift_imm_left<bits<4> opc, string asm, string Ps,
def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i1, nxv2i64, i32, tvecshiftL64, !cast<Instruction>(NAME # _D)>;
}
-// As above but shift amount takes the form of a "vector immediate".
-multiclass sve_int_bin_pred_shift_imm_left_dup<bits<4> opc, string asm,
- string Ps, SDPatternOperator op>
-: sve_int_bin_pred_shift_imm_left<opc, asm, Ps, null_frag> {
- def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmL8, !cast<Instruction>(NAME # _B)>;
- def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1, i32, SVEShiftImmL16, !cast<Instruction>(NAME # _H)>;
- def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1, i32, SVEShiftImmL32, !cast<Instruction>(NAME # _S)>;
- def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1, i64, SVEShiftImmL64, !cast<Instruction>(NAME # _D)>;
-}
-
+// As above but shift amount takes the form of a "vector immediate".
+multiclass sve_int_bin_pred_shift_imm_left_dup<bits<4> opc, string asm,
+ string Ps, SDPatternOperator op>
+: sve_int_bin_pred_shift_imm_left<opc, asm, Ps, null_frag> {
+ def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmL8, !cast<Instruction>(NAME # _B)>;
+ def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1, i32, SVEShiftImmL16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1, i32, SVEShiftImmL32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1, i64, SVEShiftImmL64, !cast<Instruction>(NAME # _D)>;
+}
+
multiclass sve_int_bin_pred_shift_imm_left_zeroing_bhsd<SDPatternOperator op> {
def _ZERO_B : PredTwoOpImmPseudo<NAME # _B, ZPR8, tvecshiftL8, FalseLanesZero>;
def _ZERO_H : PredTwoOpImmPseudo<NAME # _H, ZPR16, tvecshiftL16, FalseLanesZero>;
@@ -4939,16 +4939,16 @@ multiclass sve_int_bin_pred_shift_imm_right<bits<4> opc, string asm, string Ps,
def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i1, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
}
-// As above but shift amount takes the form of a "vector immediate".
-multiclass sve_int_bin_pred_shift_imm_right_dup<bits<4> opc, string asm,
- string Ps, SDPatternOperator op>
-: sve_int_bin_pred_shift_imm_right<opc, asm, Ps, null_frag> {
- def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmR8, !cast<Instruction>(NAME # _B)>;
- def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1, i32, SVEShiftImmR16, !cast<Instruction>(NAME # _H)>;
- def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1, i32, SVEShiftImmR32, !cast<Instruction>(NAME # _S)>;
- def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1, i64, SVEShiftImmR64, !cast<Instruction>(NAME # _D)>;
-}
-
+// As above but shift amount takes the form of a "vector immediate".
+multiclass sve_int_bin_pred_shift_imm_right_dup<bits<4> opc, string asm,
+ string Ps, SDPatternOperator op>
+: sve_int_bin_pred_shift_imm_right<opc, asm, Ps, null_frag> {
+ def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmR8, !cast<Instruction>(NAME # _B)>;
+ def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1, i32, SVEShiftImmR16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1, i32, SVEShiftImmR32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1, i64, SVEShiftImmR64, !cast<Instruction>(NAME # _D)>;
+}
+
multiclass sve_int_bin_pred_shift_imm_right_zeroing_bhsd<SDPatternOperator op = null_frag> {
def _ZERO_B : PredTwoOpImmPseudo<NAME # _B, ZPR8, vecshiftR8, FalseLanesZero>;
def _ZERO_H : PredTwoOpImmPseudo<NAME # _H, ZPR16, vecshiftR16, FalseLanesZero>;
@@ -5089,10 +5089,10 @@ multiclass sve_int_bin_cons_shift_imm_left<bits<2> opc, string asm,
let Inst{20-19} = imm{4-3};
}
- def : SVE_Shift_DupImm_All_Active_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmL8, !cast<Instruction>(NAME # _B)>;
- def : SVE_Shift_DupImm_All_Active_Pat<nxv8i16, op, nxv8i1, i32, SVEShiftImmL16, !cast<Instruction>(NAME # _H)>;
- def : SVE_Shift_DupImm_All_Active_Pat<nxv4i32, op, nxv4i1, i32, SVEShiftImmL32, !cast<Instruction>(NAME # _S)>;
- def : SVE_Shift_DupImm_All_Active_Pat<nxv2i64, op, nxv2i1, i64, SVEShiftImmL64, !cast<Instruction>(NAME # _D)>;
+ def : SVE_Shift_DupImm_All_Active_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmL8, !cast<Instruction>(NAME # _B)>;
+ def : SVE_Shift_DupImm_All_Active_Pat<nxv8i16, op, nxv8i1, i32, SVEShiftImmL16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_Shift_DupImm_All_Active_Pat<nxv4i32, op, nxv4i1, i32, SVEShiftImmL32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_Shift_DupImm_All_Active_Pat<nxv2i64, op, nxv2i1, i64, SVEShiftImmL64, !cast<Instruction>(NAME # _D)>;
}
multiclass sve_int_bin_cons_shift_imm_right<bits<2> opc, string asm,
@@ -5109,12 +5109,12 @@ multiclass sve_int_bin_cons_shift_imm_right<bits<2> opc, string asm,
let Inst{20-19} = imm{4-3};
}
- def : SVE_Shift_DupImm_All_Active_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmR8, !cast<Instruction>(NAME # _B)>;
- def : SVE_Shift_DupImm_All_Active_Pat<nxv8i16, op, nxv8i1, i32, SVEShiftImmR16, !cast<Instruction>(NAME # _H)>;
- def : SVE_Shift_DupImm_All_Active_Pat<nxv4i32, op, nxv4i1, i32, SVEShiftImmR32, !cast<Instruction>(NAME # _S)>;
- def : SVE_Shift_DupImm_All_Active_Pat<nxv2i64, op, nxv2i1, i64, SVEShiftImmR64, !cast<Instruction>(NAME # _D)>;
+ def : SVE_Shift_DupImm_All_Active_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmR8, !cast<Instruction>(NAME # _B)>;
+ def : SVE_Shift_DupImm_All_Active_Pat<nxv8i16, op, nxv8i1, i32, SVEShiftImmR16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_Shift_DupImm_All_Active_Pat<nxv4i32, op, nxv4i1, i32, SVEShiftImmR32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_Shift_DupImm_All_Active_Pat<nxv2i64, op, nxv2i1, i64, SVEShiftImmR64, !cast<Instruction>(NAME # _D)>;
}
-
+
//===----------------------------------------------------------------------===//
// SVE Memory - Store Group
//===----------------------------------------------------------------------===//
@@ -5623,7 +5623,7 @@ class sve_int_perm_bin_perm_pp<bits<3> opc, bits<2> sz8_64, string asm,
PPRRegOp pprty>
: I<(outs pprty:$Pd), (ins pprty:$Pn, pprty:$Pm),
asm, "\t$Pd, $Pn, $Pm",
- "", []>, Sched<[]> {
+ "", []>, Sched<[]> {
bits<4> Pd;
bits<4> Pm;
bits<4> Pn;
@@ -5689,7 +5689,7 @@ class sve_int_rdffr_pred<bit s, string asm>
let Inst{4} = 0;
let Inst{3-0} = Pd;
- let Defs = !if(s, [NZCV], []);
+ let Defs = !if(s, [NZCV], []);
let Uses = [FFR];
}
@@ -5816,11 +5816,11 @@ multiclass sve_int_perm_clast_vz<bit ab, string asm, SDPatternOperator op> {
def _S : sve_int_perm_clast_vz<0b10, ab, asm, ZPR32, FPR32>;
def _D : sve_int_perm_clast_vz<0b11, ab, asm, ZPR64, FPR64>;
- def : SVE_3_Op_Pat<f16, op, nxv8i1, f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
- def : SVE_3_Op_Pat<f32, op, nxv4i1, f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
- def : SVE_3_Op_Pat<f64, op, nxv2i1, f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
-
- def : SVE_3_Op_Pat<bf16, op, nxv8i1, bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_3_Op_Pat<f16, op, nxv8i1, f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_3_Op_Pat<f32, op, nxv4i1, f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_3_Op_Pat<f64, op, nxv2i1, f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
+
+ def : SVE_3_Op_Pat<bf16, op, nxv8i1, bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
}
class sve_int_perm_clast_zz<bits<2> sz8_64, bit ab, string asm,
@@ -5860,8 +5860,8 @@ multiclass sve_int_perm_clast_zz<bit ab, string asm, SDPatternOperator op> {
def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
-
- def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
+
+ def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
}
class sve_int_perm_last_r<bits<2> sz8_64, bit ab, string asm,
@@ -5924,8 +5924,8 @@ multiclass sve_int_perm_last_v<bit ab, string asm, SDPatternOperator op> {
def : SVE_2_Op_Pat<f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
def : SVE_2_Op_Pat<f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
def : SVE_2_Op_Pat<f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
-
- def : SVE_2_Op_Pat<bf16, op, nxv8i1, nxv8bf16, !cast<Instruction>(NAME # _H)>;
+
+ def : SVE_2_Op_Pat<bf16, op, nxv8i1, nxv8bf16, !cast<Instruction>(NAME # _H)>;
}
class sve_int_perm_splice<bits<2> sz8_64, string asm, ZPRRegOp zprty>
@@ -5962,8 +5962,8 @@ multiclass sve_int_perm_splice<string asm, SDPatternOperator op> {
def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
-
- def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
+
+ def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
}
class sve2_int_perm_splice_cons<bits<2> sz8_64, string asm,
@@ -6019,20 +6019,20 @@ multiclass sve_int_perm_rev_rbit<string asm, SDPatternOperator op> {
def _S : sve_int_perm_rev<0b10, 0b11, asm, ZPR32>;
def _D : sve_int_perm_rev<0b11, 0b11, asm, ZPR64>;
- def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
- def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
- def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
- def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
+ def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
+ def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
}
-multiclass sve_int_perm_rev_revb<string asm, SDPatternOperator op> {
+multiclass sve_int_perm_rev_revb<string asm, SDPatternOperator op> {
def _H : sve_int_perm_rev<0b01, 0b00, asm, ZPR16>;
def _S : sve_int_perm_rev<0b10, 0b00, asm, ZPR32>;
def _D : sve_int_perm_rev<0b11, 0b00, asm, ZPR64>;
- def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
- def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
- def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
+ def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
}
multiclass sve_int_perm_rev_revh<string asm, SDPatternOperator op> {
@@ -6139,9 +6139,9 @@ multiclass sve_int_perm_cpy_v<string asm, SDPatternOperator op> {
(!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
def : Pat<(nxv2f64 (op nxv2i1:$pg, f64:$splat, nxv2f64:$passthru)),
(!cast<Instruction>(NAME # _D) $passthru, $pg, $splat)>;
-
- def : Pat<(nxv8bf16 (op nxv8i1:$pg, bf16:$splat, nxv8bf16:$passthru)),
- (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
+
+ def : Pat<(nxv8bf16 (op nxv8i1:$pg, bf16:$splat, nxv8bf16:$passthru)),
+ (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
}
class sve_int_perm_compact<bit sz, string asm, ZPRRegOp zprty>
@@ -6194,8 +6194,8 @@ class sve_mem_cld_si_base<bits<4> dtype, bit nf, string asm,
let Inst{4-0} = Zt;
let mayLoad = 1;
- let Uses = !if(nf, [FFR], []);
- let Defs = !if(nf, [FFR], []);
+ let Uses = !if(nf, [FFR], []);
+ let Defs = !if(nf, [FFR], []);
}
multiclass sve_mem_cld_si_base<bits<4> dtype, bit nf, string asm,
@@ -6397,8 +6397,8 @@ class sve_mem_cld_ss_base<bits<4> dtype, bit ff, dag iops, string asm,
let Inst{4-0} = Zt;
let mayLoad = 1;
- let Uses = !if(ff, [FFR], []);
- let Defs = !if(ff, [FFR], []);
+ let Uses = !if(ff, [FFR], []);
+ let Defs = !if(ff, [FFR], []);
}
multiclass sve_mem_cld_ss<bits<4> dtype, string asm, RegisterOperand listty,
@@ -7227,8 +7227,8 @@ multiclass sve_int_bin_cons_misc_0_c_fexpa<string asm, SDPatternOperator op> {
//===----------------------------------------------------------------------===//
class sve_int_reduce<bits<2> sz8_32, bits<2> fmt, bits<3> opc, string asm,
- ZPRRegOp zprty, FPRasZPROperand dstOpType>
-: I<(outs dstOpType:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
+ ZPRRegOp zprty, FPRasZPROperand dstOpType>
+: I<(outs dstOpType:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
asm, "\t$Vd, $Pg, $Zn",
"",
[]>, Sched<[]> {
@@ -7246,54 +7246,54 @@ class sve_int_reduce<bits<2> sz8_32, bits<2> fmt, bits<3> opc, string asm,
let Inst{4-0} = Vd;
}
-multiclass sve_int_reduce_0_saddv<bits<3> opc, string asm,
- SDPatternOperator op> {
- def _B : sve_int_reduce<0b00, 0b00, opc, asm, ZPR8, FPR64asZPR>;
- def _H : sve_int_reduce<0b01, 0b00, opc, asm, ZPR16, FPR64asZPR>;
- def _S : sve_int_reduce<0b10, 0b00, opc, asm, ZPR32, FPR64asZPR>;
+multiclass sve_int_reduce_0_saddv<bits<3> opc, string asm,
+ SDPatternOperator op> {
+ def _B : sve_int_reduce<0b00, 0b00, opc, asm, ZPR8, FPR64asZPR>;
+ def _H : sve_int_reduce<0b01, 0b00, opc, asm, ZPR16, FPR64asZPR>;
+ def _S : sve_int_reduce<0b10, 0b00, opc, asm, ZPR32, FPR64asZPR>;
- def : SVE_2_Op_Pat<nxv2i64, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
- def : SVE_2_Op_Pat<nxv2i64, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
- def : SVE_2_Op_Pat<nxv2i64, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_2_Op_Pat<nxv2i64, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
+ def : SVE_2_Op_Pat<nxv2i64, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_2_Op_Pat<nxv2i64, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
}
-multiclass sve_int_reduce_0_uaddv<bits<3> opc, string asm,
- SDPatternOperator op> {
- def _B : sve_int_reduce<0b00, 0b00, opc, asm, ZPR8, FPR64asZPR>;
- def _H : sve_int_reduce<0b01, 0b00, opc, asm, ZPR16, FPR64asZPR>;
- def _S : sve_int_reduce<0b10, 0b00, opc, asm, ZPR32, FPR64asZPR>;
- def _D : sve_int_reduce<0b11, 0b00, opc, asm, ZPR64, FPR64asZPR>;
+multiclass sve_int_reduce_0_uaddv<bits<3> opc, string asm,
+ SDPatternOperator op> {
+ def _B : sve_int_reduce<0b00, 0b00, opc, asm, ZPR8, FPR64asZPR>;
+ def _H : sve_int_reduce<0b01, 0b00, opc, asm, ZPR16, FPR64asZPR>;
+ def _S : sve_int_reduce<0b10, 0b00, opc, asm, ZPR32, FPR64asZPR>;
+ def _D : sve_int_reduce<0b11, 0b00, opc, asm, ZPR64, FPR64asZPR>;
- def : SVE_2_Op_Pat<nxv2i64, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
- def : SVE_2_Op_Pat<nxv2i64, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
- def : SVE_2_Op_Pat<nxv2i64, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
- def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
+ def : SVE_2_Op_Pat<nxv2i64, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
+ def : SVE_2_Op_Pat<nxv2i64, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_2_Op_Pat<nxv2i64, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
}
-multiclass sve_int_reduce_1<bits<3> opc, string asm,
- SDPatternOperator op> {
- def _B : sve_int_reduce<0b00, 0b01, opc, asm, ZPR8, FPR8asZPR>;
- def _H : sve_int_reduce<0b01, 0b01, opc, asm, ZPR16, FPR16asZPR>;
- def _S : sve_int_reduce<0b10, 0b01, opc, asm, ZPR32, FPR32asZPR>;
- def _D : sve_int_reduce<0b11, 0b01, opc, asm, ZPR64, FPR64asZPR>;
+multiclass sve_int_reduce_1<bits<3> opc, string asm,
+ SDPatternOperator op> {
+ def _B : sve_int_reduce<0b00, 0b01, opc, asm, ZPR8, FPR8asZPR>;
+ def _H : sve_int_reduce<0b01, 0b01, opc, asm, ZPR16, FPR16asZPR>;
+ def _S : sve_int_reduce<0b10, 0b01, opc, asm, ZPR32, FPR32asZPR>;
+ def _D : sve_int_reduce<0b11, 0b01, opc, asm, ZPR64, FPR64asZPR>;
- def : SVE_2_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
- def : SVE_2_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
- def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
- def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
+ def : SVE_2_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
+ def : SVE_2_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
}
-multiclass sve_int_reduce_2<bits<3> opc, string asm,
- SDPatternOperator op> {
- def _B : sve_int_reduce<0b00, 0b11, opc, asm, ZPR8, FPR8asZPR>;
- def _H : sve_int_reduce<0b01, 0b11, opc, asm, ZPR16, FPR16asZPR>;
- def _S : sve_int_reduce<0b10, 0b11, opc, asm, ZPR32, FPR32asZPR>;
- def _D : sve_int_reduce<0b11, 0b11, opc, asm, ZPR64, FPR64asZPR>;
+multiclass sve_int_reduce_2<bits<3> opc, string asm,
+ SDPatternOperator op> {
+ def _B : sve_int_reduce<0b00, 0b11, opc, asm, ZPR8, FPR8asZPR>;
+ def _H : sve_int_reduce<0b01, 0b11, opc, asm, ZPR16, FPR16asZPR>;
+ def _S : sve_int_reduce<0b10, 0b11, opc, asm, ZPR32, FPR32asZPR>;
+ def _D : sve_int_reduce<0b11, 0b11, opc, asm, ZPR64, FPR64asZPR>;
- def : SVE_2_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
- def : SVE_2_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
- def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
- def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
+ def : SVE_2_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
+ def : SVE_2_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
+ def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
+ def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
}
class sve_int_movprfx_pred<bits<2> sz8_32, bits<3> opc, string asm,
@@ -7398,7 +7398,7 @@ class sve_int_brkn<bit S, string asm>
let Inst{3-0} = Pdm;
let Constraints = "$Pdm = $_Pdm";
- let Defs = !if(S, [NZCV], []);
+ let Defs = !if(S, [NZCV], []);
}
multiclass sve_int_brkn<bits<1> opc, string asm, SDPatternOperator op> {
@@ -7900,8 +7900,8 @@ multiclass sve_mem_ldor_ss<bits<2> sz, string asm, RegisterOperand listty,
def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
(!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
- def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$gp), (AddrCP GPR64sp:$base, gprty:$offset))),
- (!cast<Instruction>(NAME) PPR3bAny:$gp, GPR64sp:$base, gprty:$offset)>;
+ def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$gp), (AddrCP GPR64sp:$base, gprty:$offset))),
+ (!cast<Instruction>(NAME) PPR3bAny:$gp, GPR64sp:$base, gprty:$offset)>;
}
//===----------------------------------------------------------------------===//
@@ -7935,7 +7935,7 @@ multiclass sve_int_perm_bin_perm_128_zz<bits<2> opc, bit P, string asm, SDPatter
def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, !cast<Instruction>(NAME)>;
def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, !cast<Instruction>(NAME)>;
- def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
+ def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
}
/// Addressing modes
@@ -7954,10 +7954,10 @@ multiclass sve_fp_bin_pred_hfd<SDPatternOperator op> {
def _UNDEF_D : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Pseudo>(NAME # _UNDEF_H)>;
- def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, !cast<Pseudo>(NAME # _UNDEF_H)>;
- def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, !cast<Pseudo>(NAME # _UNDEF_H)>;
+ def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, !cast<Pseudo>(NAME # _UNDEF_H)>;
+ def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, !cast<Pseudo>(NAME # _UNDEF_H)>;
def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Pseudo>(NAME # _UNDEF_S)>;
- def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, !cast<Pseudo>(NAME # _UNDEF_S)>;
+ def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, !cast<Pseudo>(NAME # _UNDEF_S)>;
def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Pseudo>(NAME # _UNDEF_D)>;
}
@@ -7982,19 +7982,19 @@ multiclass sve_int_bin_pred_sd<SDPatternOperator op> {
def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _UNDEF_S)>;
def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _UNDEF_D)>;
}
-
-// Predicated pseudo integer two operand instructions. Second operand is an
-// immediate specified by imm_[bhsd].
-multiclass sve_int_shift_pred_bhsd<SDPatternOperator op,
- ComplexPattern imm_b, ComplexPattern imm_h,
- ComplexPattern imm_s, ComplexPattern imm_d> {
- def _UNDEF_B : PredTwoOpImmPseudo<NAME # _B, ZPR8, Operand<i32>, FalseLanesUndef>;
- def _UNDEF_H : PredTwoOpImmPseudo<NAME # _H, ZPR16, Operand<i32>, FalseLanesUndef>;
- def _UNDEF_S : PredTwoOpImmPseudo<NAME # _S, ZPR32, Operand<i32>, FalseLanesUndef>;
- def _UNDEF_D : PredTwoOpImmPseudo<NAME # _D, ZPR64, Operand<i32>, FalseLanesUndef>;
-
- def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, imm_b, !cast<Instruction>(NAME # _UNDEF_B)>;
- def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1, i32, imm_h, !cast<Instruction>(NAME # _UNDEF_H)>;
- def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1, i32, imm_s, !cast<Instruction>(NAME # _UNDEF_S)>;
- def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1, i64, imm_d, !cast<Instruction>(NAME # _UNDEF_D)>;
-}
+
+// Predicated pseudo integer two operand instructions. Second operand is an
+// immediate specified by imm_[bhsd].
+multiclass sve_int_shift_pred_bhsd<SDPatternOperator op,
+ ComplexPattern imm_b, ComplexPattern imm_h,
+ ComplexPattern imm_s, ComplexPattern imm_d> {
+ def _UNDEF_B : PredTwoOpImmPseudo<NAME # _B, ZPR8, Operand<i32>, FalseLanesUndef>;
+ def _UNDEF_H : PredTwoOpImmPseudo<NAME # _H, ZPR16, Operand<i32>, FalseLanesUndef>;
+ def _UNDEF_S : PredTwoOpImmPseudo<NAME # _S, ZPR32, Operand<i32>, FalseLanesUndef>;
+ def _UNDEF_D : PredTwoOpImmPseudo<NAME # _D, ZPR64, Operand<i32>, FalseLanesUndef>;
+
+ def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, imm_b, !cast<Instruction>(NAME # _UNDEF_B)>;
+ def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1, i32, imm_h, !cast<Instruction>(NAME # _UNDEF_H)>;
+ def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1, i32, imm_s, !cast<Instruction>(NAME # _UNDEF_S)>;
+ def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1, i64, imm_d, !cast<Instruction>(NAME # _UNDEF_D)>;
+}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/SVEIntrinsicOpts.cpp b/contrib/libs/llvm12/lib/Target/AArch64/SVEIntrinsicOpts.cpp
index e312d9d28b..9911f33371 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/SVEIntrinsicOpts.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/SVEIntrinsicOpts.cpp
@@ -37,7 +37,7 @@
using namespace llvm;
using namespace llvm::PatternMatch;
-#define DEBUG_TYPE "aarch64-sve-intrinsic-opts"
+#define DEBUG_TYPE "aarch64-sve-intrinsic-opts"
namespace llvm {
void initializeSVEIntrinsicOptsPass(PassRegistry &);
@@ -177,50 +177,50 @@ bool SVEIntrinsicOpts::optimizeConvertFromSVBool(IntrinsicInst *I) {
if (isa<PHINode>(I->getArgOperand(0)))
return processPhiNode(I);
- SmallVector<Instruction *, 32> CandidatesForRemoval;
- Value *Cursor = I->getOperand(0), *EarliestReplacement = nullptr;
-
- const auto *IVTy = cast<VectorType>(I->getType());
-
- // Walk the chain of conversions.
- while (Cursor) {
- // If the type of the cursor has fewer lanes than the final result, zeroing
- // must take place, which breaks the equivalence chain.
- const auto *CursorVTy = cast<VectorType>(Cursor->getType());
- if (CursorVTy->getElementCount().getKnownMinValue() <
- IVTy->getElementCount().getKnownMinValue())
- break;
-
- // If the cursor has the same type as I, it is a viable replacement.
- if (Cursor->getType() == IVTy)
- EarliestReplacement = Cursor;
-
- auto *IntrinsicCursor = dyn_cast<IntrinsicInst>(Cursor);
-
- // If this is not an SVE conversion intrinsic, this is the end of the chain.
- if (!IntrinsicCursor || !(IntrinsicCursor->getIntrinsicID() ==
- Intrinsic::aarch64_sve_convert_to_svbool ||
- IntrinsicCursor->getIntrinsicID() ==
- Intrinsic::aarch64_sve_convert_from_svbool))
- break;
-
- CandidatesForRemoval.insert(CandidatesForRemoval.begin(), IntrinsicCursor);
- Cursor = IntrinsicCursor->getOperand(0);
- }
-
- // If no viable replacement in the conversion chain was found, there is
- // nothing to do.
- if (!EarliestReplacement)
+ SmallVector<Instruction *, 32> CandidatesForRemoval;
+ Value *Cursor = I->getOperand(0), *EarliestReplacement = nullptr;
+
+ const auto *IVTy = cast<VectorType>(I->getType());
+
+ // Walk the chain of conversions.
+ while (Cursor) {
+ // If the type of the cursor has fewer lanes than the final result, zeroing
+ // must take place, which breaks the equivalence chain.
+ const auto *CursorVTy = cast<VectorType>(Cursor->getType());
+ if (CursorVTy->getElementCount().getKnownMinValue() <
+ IVTy->getElementCount().getKnownMinValue())
+ break;
+
+ // If the cursor has the same type as I, it is a viable replacement.
+ if (Cursor->getType() == IVTy)
+ EarliestReplacement = Cursor;
+
+ auto *IntrinsicCursor = dyn_cast<IntrinsicInst>(Cursor);
+
+ // If this is not an SVE conversion intrinsic, this is the end of the chain.
+ if (!IntrinsicCursor || !(IntrinsicCursor->getIntrinsicID() ==
+ Intrinsic::aarch64_sve_convert_to_svbool ||
+ IntrinsicCursor->getIntrinsicID() ==
+ Intrinsic::aarch64_sve_convert_from_svbool))
+ break;
+
+ CandidatesForRemoval.insert(CandidatesForRemoval.begin(), IntrinsicCursor);
+ Cursor = IntrinsicCursor->getOperand(0);
+ }
+
+ // If no viable replacement in the conversion chain was found, there is
+ // nothing to do.
+ if (!EarliestReplacement)
return false;
- I->replaceAllUsesWith(EarliestReplacement);
+ I->replaceAllUsesWith(EarliestReplacement);
I->eraseFromParent();
- while (!CandidatesForRemoval.empty()) {
- Instruction *Candidate = CandidatesForRemoval.pop_back_val();
- if (Candidate->use_empty())
- Candidate->eraseFromParent();
- }
+ while (!CandidatesForRemoval.empty()) {
+ Instruction *Candidate = CandidatesForRemoval.pop_back_val();
+ if (Candidate->use_empty())
+ Candidate->eraseFromParent();
+ }
return true;
}
@@ -276,8 +276,8 @@ bool SVEIntrinsicOpts::runOnModule(Module &M) {
case Intrinsic::aarch64_sve_ptest_any:
case Intrinsic::aarch64_sve_ptest_first:
case Intrinsic::aarch64_sve_ptest_last:
- for (User *U : F.users())
- Functions.insert(cast<Instruction>(U)->getFunction());
+ for (User *U : F.users())
+ Functions.insert(cast<Instruction>(U)->getFunction());
break;
default:
break;
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/TargetInfo/ya.make b/contrib/libs/llvm12/lib/Target/AArch64/TargetInfo/ya.make
index cf2f9565d1..bb7d4a2c89 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/TargetInfo/ya.make
+++ b/contrib/libs/llvm12/lib/Target/AArch64/TargetInfo/ya.make
@@ -12,13 +12,13 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
- contrib/libs/llvm12/lib/Target/AArch64
- contrib/libs/llvm12/lib/Target/AArch64/TargetInfo
+ contrib/libs/llvm12/lib/Target/AArch64
+ contrib/libs/llvm12/lib/Target/AArch64/TargetInfo
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp b/contrib/libs/llvm12/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
index 8a90a74841..ac59d73fd9 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
@@ -26,13 +26,13 @@ namespace llvm {
namespace llvm {
- namespace AArch64DBnXS {
-#define GET_DBNXS_IMPL
-#include "AArch64GenSystemOperands.inc"
- }
-}
-
-namespace llvm {
+ namespace AArch64DBnXS {
+#define GET_DBNXS_IMPL
+#include "AArch64GenSystemOperands.inc"
+ }
+}
+
+namespace llvm {
namespace AArch64DB {
#define GET_DB_IMPL
#include "AArch64GenSystemOperands.inc"
@@ -165,7 +165,7 @@ std::string AArch64SysReg::genericRegisterString(uint32_t Bits) {
namespace llvm {
namespace AArch64TLBI {
-#define GET_TLBITable_IMPL
+#define GET_TLBITable_IMPL
#include "AArch64GenSystemOperands.inc"
}
}
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/contrib/libs/llvm12/lib/Target/AArch64/Utils/AArch64BaseInfo.h
index 6d737ac8e1..1b13c94389 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/Utils/AArch64BaseInfo.h
+++ b/contrib/libs/llvm12/lib/Target/AArch64/Utils/AArch64BaseInfo.h
@@ -338,14 +338,14 @@ struct SysAliasReg : SysAlias {
: SysAlias(N, E, F), NeedsReg(R) {}
};
-struct SysAliasImm : SysAlias {
- uint16_t ImmValue;
- constexpr SysAliasImm(const char *N, uint16_t E, uint16_t I)
- : SysAlias(N, E), ImmValue(I) {}
- constexpr SysAliasImm(const char *N, uint16_t E, uint16_t I, FeatureBitset F)
- : SysAlias(N, E, F), ImmValue(I) {}
-};
-
+struct SysAliasImm : SysAlias {
+ uint16_t ImmValue;
+ constexpr SysAliasImm(const char *N, uint16_t E, uint16_t I)
+ : SysAlias(N, E), ImmValue(I) {}
+ constexpr SysAliasImm(const char *N, uint16_t E, uint16_t I, FeatureBitset F)
+ : SysAlias(N, E, F), ImmValue(I) {}
+};
+
namespace AArch64AT{
struct AT : SysAlias {
using SysAlias::SysAlias;
@@ -362,14 +362,14 @@ namespace AArch64DB {
#include "AArch64GenSystemOperands.inc"
}
-namespace AArch64DBnXS {
- struct DBnXS : SysAliasImm {
- using SysAliasImm::SysAliasImm;
- };
- #define GET_DBNXS_DECL
- #include "AArch64GenSystemOperands.inc"
-}
-
+namespace AArch64DBnXS {
+ struct DBnXS : SysAliasImm {
+ using SysAliasImm::SysAliasImm;
+ };
+ #define GET_DBNXS_DECL
+ #include "AArch64GenSystemOperands.inc"
+}
+
namespace AArch64DC {
struct DC : SysAlias {
using SysAlias::SysAlias;
@@ -568,7 +568,7 @@ namespace AArch64TLBI {
struct TLBI : SysAliasReg {
using SysAliasReg::SysAliasReg;
};
- #define GET_TLBITable_DECL
+ #define GET_TLBITable_DECL
#include "AArch64GenSystemOperands.inc"
}
@@ -622,7 +622,7 @@ namespace AArch64II {
MO_HI12 = 7,
/// MO_COFFSTUB - On a symbol operand "FOO", this indicates that the
- /// reference is actually to the ".refptr.FOO" symbol. This is used for
+ /// reference is actually to the ".refptr.FOO" symbol. This is used for
/// stub symbols on windows.
MO_COFFSTUB = 0x8,
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/Utils/ya.make b/contrib/libs/llvm12/lib/Target/AArch64/Utils/ya.make
index 37d19feb17..3668c2a650 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/Utils/ya.make
+++ b/contrib/libs/llvm12/lib/Target/AArch64/Utils/ya.make
@@ -12,15 +12,15 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64
- contrib/libs/llvm12/lib/Target/AArch64
- contrib/libs/llvm12/lib/Target/AArch64/Utils
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64
+ contrib/libs/llvm12/lib/Target/AArch64
+ contrib/libs/llvm12/lib/Target/AArch64/Utils
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/AArch64/ya.make b/contrib/libs/llvm12/lib/Target/AArch64/ya.make
index 0c05f2840f..244cbc7f34 100644
--- a/contrib/libs/llvm12/lib/Target/AArch64/ya.make
+++ b/contrib/libs/llvm12/lib/Target/AArch64/ya.make
@@ -15,28 +15,28 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/CodeGen
- contrib/libs/llvm12/lib/CodeGen/AsmPrinter
- contrib/libs/llvm12/lib/CodeGen/GlobalISel
- contrib/libs/llvm12/lib/CodeGen/SelectionDAG
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target
- contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc
- contrib/libs/llvm12/lib/Target/AArch64/TargetInfo
- contrib/libs/llvm12/lib/Target/AArch64/Utils
- contrib/libs/llvm12/lib/Transforms/CFGuard
- contrib/libs/llvm12/lib/Transforms/Scalar
- contrib/libs/llvm12/lib/Transforms/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/CodeGen
+ contrib/libs/llvm12/lib/CodeGen/AsmPrinter
+ contrib/libs/llvm12/lib/CodeGen/GlobalISel
+ contrib/libs/llvm12/lib/CodeGen/SelectionDAG
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target
+ contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/AArch64/TargetInfo
+ contrib/libs/llvm12/lib/Target/AArch64/Utils
+ contrib/libs/llvm12/lib/Transforms/CFGuard
+ contrib/libs/llvm12/lib/Transforms/Scalar
+ contrib/libs/llvm12/lib/Transforms/Utils
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64
- contrib/libs/llvm12/lib/Target/AArch64
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/AArch64
+ contrib/libs/llvm12/lib/Target/AArch64
)
NO_COMPILER_WARNINGS()
@@ -88,8 +88,8 @@ SRCS(
GISel/AArch64InstructionSelector.cpp
GISel/AArch64LegalizerInfo.cpp
GISel/AArch64PostLegalizerCombiner.cpp
- GISel/AArch64PostLegalizerLowering.cpp
- GISel/AArch64PostSelectOptimize.cpp
+ GISel/AArch64PostLegalizerLowering.cpp
+ GISel/AArch64PostSelectOptimize.cpp
GISel/AArch64PreLegalizerCombiner.cpp
GISel/AArch64RegisterBankInfo.cpp
SVEIntrinsicOpts.cpp
diff --git a/contrib/libs/llvm12/lib/Target/ARM/A15SDOptimizer.cpp b/contrib/libs/llvm12/lib/Target/ARM/A15SDOptimizer.cpp
index 6c6f49ff6d..bb81233cf8 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/A15SDOptimizer.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/A15SDOptimizer.cpp
@@ -359,7 +359,7 @@ void A15SDOptimizer::elideCopiesAndPHIs(MachineInstr *MI,
SmallVector<MachineInstr *, 8> Front;
Front.push_back(MI);
while (Front.size() != 0) {
- MI = Front.pop_back_val();
+ MI = Front.pop_back_val();
// If we have already explored this MachineInstr, ignore it.
if (Reached.find(MI) != Reached.end())
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARM.h b/contrib/libs/llvm12/lib/Target/ARM/ARM.h
index 2fbfabe828..f4fdc98037 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARM.h
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARM.h
@@ -37,7 +37,7 @@ class PassRegistry;
Pass *createMVETailPredicationPass();
FunctionPass *createARMLowOverheadLoopsPass();
-FunctionPass *createARMBlockPlacementPass();
+FunctionPass *createARMBlockPlacementPass();
Pass *createARMParallelDSPPass();
FunctionPass *createARMISelDag(ARMBaseTargetMachine &TM,
CodeGenOpt::Level OptLevel);
@@ -56,8 +56,8 @@ InstructionSelector *
createARMInstructionSelector(const ARMBaseTargetMachine &TM, const ARMSubtarget &STI,
const ARMRegisterBankInfo &RBI);
Pass *createMVEGatherScatterLoweringPass();
-FunctionPass *createARMSLSHardeningPass();
-FunctionPass *createARMIndirectThunks();
+FunctionPass *createARMSLSHardeningPass();
+FunctionPass *createARMIndirectThunks();
void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
ARMAsmPrinter &AP);
@@ -72,10 +72,10 @@ void initializeThumb2ITBlockPass(PassRegistry &);
void initializeMVEVPTBlockPass(PassRegistry &);
void initializeMVEVPTOptimisationsPass(PassRegistry &);
void initializeARMLowOverheadLoopsPass(PassRegistry &);
-void initializeARMBlockPlacementPass(PassRegistry &);
+void initializeARMBlockPlacementPass(PassRegistry &);
void initializeMVETailPredicationPass(PassRegistry &);
void initializeMVEGatherScatterLoweringPass(PassRegistry &);
-void initializeARMSLSHardeningPass(PassRegistry &);
+void initializeARMSLSHardeningPass(PassRegistry &);
} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARM.td b/contrib/libs/llvm12/lib/Target/ARM/ARM.td
index 9540784c7f..3d0a0bf7f8 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARM.td
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARM.td
@@ -535,10 +535,10 @@ def HasV8_6aOps : SubtargetFeature<"v8.6a", "HasV8_6aOps", "true",
[HasV8_5aOps, FeatureBF16,
FeatureMatMulInt8]>;
-def HasV8_7aOps : SubtargetFeature<"v8.7a", "HasV8_7aOps", "true",
- "Support ARM v8.7a instructions",
- [HasV8_6aOps]>;
-
+def HasV8_7aOps : SubtargetFeature<"v8.7a", "HasV8_7aOps", "true",
+ "Support ARM v8.7a instructions",
+ [HasV8_6aOps]>;
+
def HasV8_1MMainlineOps : SubtargetFeature<
"v8.1m.main", "HasV8_1MMainlineOps", "true",
"Support ARM v8-1M Mainline instructions",
@@ -563,20 +563,20 @@ foreach i = {0-7} in
[HasCDEOps]>;
//===----------------------------------------------------------------------===//
-// Control codegen mitigation against Straight Line Speculation vulnerability.
-//===----------------------------------------------------------------------===//
-
-def FeatureHardenSlsRetBr : SubtargetFeature<"harden-sls-retbr",
- "HardenSlsRetBr", "true",
- "Harden against straight line speculation across RETurn and BranchRegister "
- "instructions">;
-def FeatureHardenSlsBlr : SubtargetFeature<"harden-sls-blr",
- "HardenSlsBlr", "true",
- "Harden against straight line speculation across indirect calls">;
-
-
-
-//===----------------------------------------------------------------------===//
+// Control codegen mitigation against Straight Line Speculation vulnerability.
+//===----------------------------------------------------------------------===//
+
+def FeatureHardenSlsRetBr : SubtargetFeature<"harden-sls-retbr",
+ "HardenSlsRetBr", "true",
+ "Harden against straight line speculation across RETurn and BranchRegister "
+ "instructions">;
+def FeatureHardenSlsBlr : SubtargetFeature<"harden-sls-blr",
+ "HardenSlsBlr", "true",
+ "Harden against straight line speculation across indirect calls">;
+
+
+
+//===----------------------------------------------------------------------===//
// ARM Processor subtarget features.
//
@@ -616,14 +616,14 @@ def ProcA77 : SubtargetFeature<"a77", "ARMProcFamily", "CortexA77",
"Cortex-A77 ARM processors", []>;
def ProcA78 : SubtargetFeature<"cortex-a78", "ARMProcFamily", "CortexA78",
"Cortex-A78 ARM processors", []>;
-def ProcA78C : SubtargetFeature<"a78c", "ARMProcFamily", "CortexA78C",
- "Cortex-A78C ARM processors", []>;
+def ProcA78C : SubtargetFeature<"a78c", "ARMProcFamily", "CortexA78C",
+ "Cortex-A78C ARM processors", []>;
def ProcX1 : SubtargetFeature<"cortex-x1", "ARMProcFamily", "CortexX1",
"Cortex-X1 ARM processors", []>;
-def ProcV1 : SubtargetFeature<"neoverse-v1", "ARMProcFamily",
- "NeoverseV1", "Neoverse-V1 ARM processors", []>;
-
+def ProcV1 : SubtargetFeature<"neoverse-v1", "ARMProcFamily",
+ "NeoverseV1", "Neoverse-V1 ARM processors", []>;
+
def ProcKrait : SubtargetFeature<"krait", "ARMProcFamily", "Krait",
"Qualcomm Krait processors", []>;
def ProcKryo : SubtargetFeature<"kryo", "ARMProcFamily", "Kryo",
@@ -662,8 +662,8 @@ def ProcR52 : SubtargetFeature<"r52", "ARMProcFamily", "CortexR52",
def ProcM3 : SubtargetFeature<"m3", "ARMProcFamily", "CortexM3",
"Cortex-M3 ARM processors", []>;
-def ProcM7 : SubtargetFeature<"m7", "ARMProcFamily", "CortexM7",
- "Cortex-M7 ARM processors", []>;
+def ProcM7 : SubtargetFeature<"m7", "ARMProcFamily", "CortexM7",
+ "Cortex-M7 ARM processors", []>;
//===----------------------------------------------------------------------===//
// ARM Helper classes.
@@ -852,19 +852,19 @@ def ARMv86a : Architecture<"armv8.6-a", "ARMv86a", [HasV8_6aOps,
FeatureCRC,
FeatureRAS,
FeatureDotProd]>;
-def ARMv87a : Architecture<"armv8.7-a", "ARMv86a", [HasV8_7aOps,
- FeatureAClass,
- FeatureDB,
- FeatureFPARMv8,
- FeatureNEON,
- FeatureDSP,
- FeatureTrustZone,
- FeatureMP,
- FeatureVirtualization,
- FeatureCrypto,
- FeatureCRC,
- FeatureRAS,
- FeatureDotProd]>;
+def ARMv87a : Architecture<"armv8.7-a", "ARMv86a", [HasV8_7aOps,
+ FeatureAClass,
+ FeatureDB,
+ FeatureFPARMv8,
+ FeatureNEON,
+ FeatureDSP,
+ FeatureTrustZone,
+ FeatureMP,
+ FeatureVirtualization,
+ FeatureCrypto,
+ FeatureCRC,
+ FeatureRAS,
+ FeatureDotProd]>;
def ARMv8r : Architecture<"armv8-r", "ARMv8r", [HasV8Ops,
FeatureRClass,
@@ -919,14 +919,14 @@ def ARMv6j : Architecture<"armv6j", "ARMv7a", [ARMv6]>;
def ARMv7k : Architecture<"armv7k", "ARMv7a", [ARMv7a]>;
def ARMv7s : Architecture<"armv7s", "ARMv7a", [ARMv7a]>;
-//===----------------------------------------------------------------------===//
-// Register File Description
-//===----------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
+// Register File Description
+//===----------------------------------------------------------------------===//
+
+include "ARMRegisterInfo.td"
+include "ARMRegisterBanks.td"
+include "ARMCallingConv.td"
-include "ARMRegisterInfo.td"
-include "ARMRegisterBanks.td"
-include "ARMCallingConv.td"
-
//===----------------------------------------------------------------------===//
// ARM schedules.
//===----------------------------------------------------------------------===//
@@ -935,25 +935,25 @@ include "ARMPredicates.td"
include "ARMSchedule.td"
//===----------------------------------------------------------------------===//
-// Instruction Descriptions
-//===----------------------------------------------------------------------===//
-
-include "ARMInstrInfo.td"
-def ARMInstrInfo : InstrInfo;
-
-//===----------------------------------------------------------------------===//
-// ARM schedules
-//
-include "ARMScheduleV6.td"
-include "ARMScheduleA8.td"
-include "ARMScheduleA9.td"
-include "ARMScheduleSwift.td"
-include "ARMScheduleR52.td"
-include "ARMScheduleA57.td"
-include "ARMScheduleM4.td"
-include "ARMScheduleM7.td"
-
-//===----------------------------------------------------------------------===//
+// Instruction Descriptions
+//===----------------------------------------------------------------------===//
+
+include "ARMInstrInfo.td"
+def ARMInstrInfo : InstrInfo;
+
+//===----------------------------------------------------------------------===//
+// ARM schedules
+//
+include "ARMScheduleV6.td"
+include "ARMScheduleA8.td"
+include "ARMScheduleA9.td"
+include "ARMScheduleSwift.td"
+include "ARMScheduleR52.td"
+include "ARMScheduleA57.td"
+include "ARMScheduleM4.td"
+include "ARMScheduleM7.td"
+
+//===----------------------------------------------------------------------===//
// ARM processors
//
// Dummy CPU, used to target architectures
@@ -1193,10 +1193,10 @@ def : ProcessorModel<"cortex-m4", CortexM4Model, [ARMv7em,
FeatureUseMISched,
FeatureHasNoBranchPredictor]>;
-def : ProcessorModel<"cortex-m7", CortexM7Model, [ARMv7em,
- ProcM7,
- FeatureFPARMv8_D16,
- FeatureUseMISched]>;
+def : ProcessorModel<"cortex-m7", CortexM7Model, [ARMv7em,
+ ProcM7,
+ FeatureFPARMv8_D16,
+ FeatureUseMISched]>;
def : ProcNoItin<"cortex-m23", [ARMv8mBaseline,
FeatureNoMovt]>;
@@ -1310,14 +1310,14 @@ def : ProcNoItin<"cortex-a78", [ARMv82a, ProcA78,
FeatureFullFP16,
FeatureDotProd]>;
-def : ProcNoItin<"cortex-a78c", [ARMv82a, ProcA78C,
- FeatureHWDivThumb,
- FeatureHWDivARM,
- FeatureCrypto,
- FeatureCRC,
- FeatureDotProd,
- FeatureFullFP16]>;
-
+def : ProcNoItin<"cortex-a78c", [ARMv82a, ProcA78C,
+ FeatureHWDivThumb,
+ FeatureHWDivARM,
+ FeatureCrypto,
+ FeatureCRC,
+ FeatureDotProd,
+ FeatureFullFP16]>;
+
def : ProcNoItin<"cortex-x1", [ARMv82a, ProcX1,
FeatureHWDivThumb,
FeatureHWDivARM,
@@ -1326,15 +1326,15 @@ def : ProcNoItin<"cortex-x1", [ARMv82a, ProcX1,
FeatureFullFP16,
FeatureDotProd]>;
-def : ProcNoItin<"neoverse-v1", [ARMv84a,
- FeatureHWDivThumb,
- FeatureHWDivARM,
- FeatureCrypto,
- FeatureCRC,
- FeatureFullFP16,
- FeatureBF16,
- FeatureMatMulInt8]>;
-
+def : ProcNoItin<"neoverse-v1", [ARMv84a,
+ FeatureHWDivThumb,
+ FeatureHWDivARM,
+ FeatureCrypto,
+ FeatureCRC,
+ FeatureFullFP16,
+ FeatureBF16,
+ FeatureMatMulInt8]>;
+
def : ProcNoItin<"neoverse-n1", [ARMv82a,
FeatureHWDivThumb,
FeatureHWDivARM,
@@ -1342,11 +1342,11 @@ def : ProcNoItin<"neoverse-n1", [ARMv82a,
FeatureCRC,
FeatureDotProd]>;
-def : ProcNoItin<"neoverse-n2", [ARMv85a,
- FeatureBF16,
- FeatureMatMulInt8,
- FeaturePerfMon]>;
-
+def : ProcNoItin<"neoverse-n2", [ARMv85a,
+ FeatureBF16,
+ FeatureMatMulInt8,
+ FeaturePerfMon]>;
+
def : ProcessorModel<"cyclone", SwiftModel, [ARMv8a, ProcSwift,
FeatureHasRetAddrStack,
FeatureNEONForFP,
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMAsmPrinter.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMAsmPrinter.cpp
index 31059e5910..04e21867d5 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -285,7 +285,7 @@ bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
return false;
case 'y': // Print a VFP single precision register as indexed double.
if (MI->getOperand(OpNum).isReg()) {
- MCRegister Reg = MI->getOperand(OpNum).getReg().asMCReg();
+ MCRegister Reg = MI->getOperand(OpNum).getReg().asMCReg();
const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
// Find the 'd' register that has this 's' register as a sub-register,
// and determine the lane number.
@@ -903,7 +903,7 @@ void ARMAsmPrinter::emitMachineConstantPoolValue(
MCSymbol *MCSym;
if (ACPV->isLSDA()) {
- MCSym = getMBBExceptionSym(MF->front());
+ MCSym = getMBBExceptionSym(MF->front());
} else if (ACPV->isBlockAddress()) {
const BlockAddress *BA =
cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress();
@@ -1897,7 +1897,7 @@ void ARMAsmPrinter::emitInstruction(const MachineInstr *MI) {
// LSJLJEH:
Register SrcReg = MI->getOperand(0).getReg();
Register ValReg = MI->getOperand(1).getReg();
- MCSymbol *Label = OutContext.createTempSymbol("SJLJEH");
+ MCSymbol *Label = OutContext.createTempSymbol("SJLJEH");
OutStreamer->AddComment("eh_setjmp begin");
EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tMOVr)
.addReg(ValReg)
@@ -2180,49 +2180,49 @@ void ARMAsmPrinter::emitInstruction(const MachineInstr *MI) {
case ARM::PATCHABLE_TAIL_CALL:
LowerPATCHABLE_TAIL_CALL(*MI);
return;
- case ARM::SpeculationBarrierISBDSBEndBB: {
- // Print DSB SYS + ISB
- MCInst TmpInstDSB;
- TmpInstDSB.setOpcode(ARM::DSB);
- TmpInstDSB.addOperand(MCOperand::createImm(0xf));
- EmitToStreamer(*OutStreamer, TmpInstDSB);
- MCInst TmpInstISB;
- TmpInstISB.setOpcode(ARM::ISB);
- TmpInstISB.addOperand(MCOperand::createImm(0xf));
- EmitToStreamer(*OutStreamer, TmpInstISB);
- return;
- }
- case ARM::t2SpeculationBarrierISBDSBEndBB: {
- // Print DSB SYS + ISB
- MCInst TmpInstDSB;
- TmpInstDSB.setOpcode(ARM::t2DSB);
- TmpInstDSB.addOperand(MCOperand::createImm(0xf));
- TmpInstDSB.addOperand(MCOperand::createImm(ARMCC::AL));
- TmpInstDSB.addOperand(MCOperand::createReg(0));
- EmitToStreamer(*OutStreamer, TmpInstDSB);
- MCInst TmpInstISB;
- TmpInstISB.setOpcode(ARM::t2ISB);
- TmpInstISB.addOperand(MCOperand::createImm(0xf));
- TmpInstISB.addOperand(MCOperand::createImm(ARMCC::AL));
- TmpInstISB.addOperand(MCOperand::createReg(0));
- EmitToStreamer(*OutStreamer, TmpInstISB);
- return;
- }
- case ARM::SpeculationBarrierSBEndBB: {
- // Print SB
- MCInst TmpInstSB;
- TmpInstSB.setOpcode(ARM::SB);
- EmitToStreamer(*OutStreamer, TmpInstSB);
- return;
- }
- case ARM::t2SpeculationBarrierSBEndBB: {
- // Print SB
- MCInst TmpInstSB;
- TmpInstSB.setOpcode(ARM::t2SB);
- EmitToStreamer(*OutStreamer, TmpInstSB);
- return;
- }
- }
+ case ARM::SpeculationBarrierISBDSBEndBB: {
+ // Print DSB SYS + ISB
+ MCInst TmpInstDSB;
+ TmpInstDSB.setOpcode(ARM::DSB);
+ TmpInstDSB.addOperand(MCOperand::createImm(0xf));
+ EmitToStreamer(*OutStreamer, TmpInstDSB);
+ MCInst TmpInstISB;
+ TmpInstISB.setOpcode(ARM::ISB);
+ TmpInstISB.addOperand(MCOperand::createImm(0xf));
+ EmitToStreamer(*OutStreamer, TmpInstISB);
+ return;
+ }
+ case ARM::t2SpeculationBarrierISBDSBEndBB: {
+ // Print DSB SYS + ISB
+ MCInst TmpInstDSB;
+ TmpInstDSB.setOpcode(ARM::t2DSB);
+ TmpInstDSB.addOperand(MCOperand::createImm(0xf));
+ TmpInstDSB.addOperand(MCOperand::createImm(ARMCC::AL));
+ TmpInstDSB.addOperand(MCOperand::createReg(0));
+ EmitToStreamer(*OutStreamer, TmpInstDSB);
+ MCInst TmpInstISB;
+ TmpInstISB.setOpcode(ARM::t2ISB);
+ TmpInstISB.addOperand(MCOperand::createImm(0xf));
+ TmpInstISB.addOperand(MCOperand::createImm(ARMCC::AL));
+ TmpInstISB.addOperand(MCOperand::createReg(0));
+ EmitToStreamer(*OutStreamer, TmpInstISB);
+ return;
+ }
+ case ARM::SpeculationBarrierSBEndBB: {
+ // Print SB
+ MCInst TmpInstSB;
+ TmpInstSB.setOpcode(ARM::SB);
+ EmitToStreamer(*OutStreamer, TmpInstSB);
+ return;
+ }
+ case ARM::t2SpeculationBarrierSBEndBB: {
+ // Print SB
+ MCInst TmpInstSB;
+ TmpInstSB.setOpcode(ARM::t2SB);
+ EmitToStreamer(*OutStreamer, TmpInstSB);
+ return;
+ }
+ }
MCInst TmpInst;
LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMBaseInstrInfo.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMBaseInstrInfo.cpp
index d3047e1ae7..e418d53b56 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -19,7 +19,7 @@
#include "ARMSubtarget.h"
#include "MCTargetDesc/ARMAddressingModes.h"
#include "MCTargetDesc/ARMBaseInfo.h"
-#include "MVETailPredUtils.h"
+#include "MVETailPredUtils.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
@@ -36,8 +36,8 @@
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/MachineScheduler.h"
-#include "llvm/CodeGen/MultiHazardRecognizer.h"
+#include "llvm/CodeGen/MachineScheduler.h"
+#include "llvm/CodeGen/MultiHazardRecognizer.h"
#include "llvm/CodeGen/ScoreboardHazardRecognizer.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
@@ -134,43 +134,43 @@ ARMBaseInstrInfo::CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI,
return TargetInstrInfo::CreateTargetHazardRecognizer(STI, DAG);
}
-// Called during:
-// - pre-RA scheduling
-// - post-RA scheduling when FeatureUseMISched is set
-ScheduleHazardRecognizer *ARMBaseInstrInfo::CreateTargetMIHazardRecognizer(
- const InstrItineraryData *II, const ScheduleDAGMI *DAG) const {
- MultiHazardRecognizer *MHR = new MultiHazardRecognizer();
-
- // We would like to restrict this hazard recognizer to only
- // post-RA scheduling; we can tell that we're post-RA because we don't
- // track VRegLiveness.
- // Cortex-M7: TRM indicates that there is a single ITCM bank and two DTCM
- // banks banked on bit 2. Assume that TCMs are in use.
- if (Subtarget.isCortexM7() && !DAG->hasVRegLiveness())
- MHR->AddHazardRecognizer(
- std::make_unique<ARMBankConflictHazardRecognizer>(DAG, 0x4, true));
-
- // Not inserting ARMHazardRecognizerFPMLx because that would change
- // legacy behavior
-
- auto BHR = TargetInstrInfo::CreateTargetMIHazardRecognizer(II, DAG);
- MHR->AddHazardRecognizer(std::unique_ptr<ScheduleHazardRecognizer>(BHR));
- return MHR;
-}
-
-// Called during post-RA scheduling when FeatureUseMISched is not set
+// Called during:
+// - pre-RA scheduling
+// - post-RA scheduling when FeatureUseMISched is set
+ScheduleHazardRecognizer *ARMBaseInstrInfo::CreateTargetMIHazardRecognizer(
+ const InstrItineraryData *II, const ScheduleDAGMI *DAG) const {
+ MultiHazardRecognizer *MHR = new MultiHazardRecognizer();
+
+ // We would like to restrict this hazard recognizer to only
+ // post-RA scheduling; we can tell that we're post-RA because we don't
+ // track VRegLiveness.
+ // Cortex-M7: TRM indicates that there is a single ITCM bank and two DTCM
+ // banks banked on bit 2. Assume that TCMs are in use.
+ if (Subtarget.isCortexM7() && !DAG->hasVRegLiveness())
+ MHR->AddHazardRecognizer(
+ std::make_unique<ARMBankConflictHazardRecognizer>(DAG, 0x4, true));
+
+ // Not inserting ARMHazardRecognizerFPMLx because that would change
+ // legacy behavior
+
+ auto BHR = TargetInstrInfo::CreateTargetMIHazardRecognizer(II, DAG);
+ MHR->AddHazardRecognizer(std::unique_ptr<ScheduleHazardRecognizer>(BHR));
+ return MHR;
+}
+
+// Called during post-RA scheduling when FeatureUseMISched is not set
ScheduleHazardRecognizer *ARMBaseInstrInfo::
CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
const ScheduleDAG *DAG) const {
- MultiHazardRecognizer *MHR = new MultiHazardRecognizer();
-
+ MultiHazardRecognizer *MHR = new MultiHazardRecognizer();
+
if (Subtarget.isThumb2() || Subtarget.hasVFP2Base())
- MHR->AddHazardRecognizer(std::make_unique<ARMHazardRecognizerFPMLx>());
-
- auto BHR = TargetInstrInfo::CreateTargetPostRAHazardRecognizer(II, DAG);
- if (BHR)
- MHR->AddHazardRecognizer(std::unique_ptr<ScheduleHazardRecognizer>(BHR));
- return MHR;
+ MHR->AddHazardRecognizer(std::make_unique<ARMHazardRecognizerFPMLx>());
+
+ auto BHR = TargetInstrInfo::CreateTargetPostRAHazardRecognizer(II, DAG);
+ if (BHR)
+ MHR->AddHazardRecognizer(std::unique_ptr<ScheduleHazardRecognizer>(BHR));
+ return MHR;
}
MachineInstr *ARMBaseInstrInfo::convertToThreeAddress(
@@ -351,8 +351,8 @@ bool ARMBaseInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
TBB = nullptr;
FBB = nullptr;
- MachineBasicBlock::instr_iterator I = MBB.instr_end();
- if (I == MBB.instr_begin())
+ MachineBasicBlock::instr_iterator I = MBB.instr_end();
+ if (I == MBB.instr_begin())
return false; // Empty blocks are easy.
--I;
@@ -364,12 +364,12 @@ bool ARMBaseInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
// out.
bool CantAnalyze = false;
- // Skip over DEBUG values, predicated nonterminators and speculation
- // barrier terminators.
- while (I->isDebugInstr() || !I->isTerminator() ||
- isSpeculationBarrierEndBBOpcode(I->getOpcode()) ||
- I->getOpcode() == ARM::t2DoLoopStartTP){
- if (I == MBB.instr_begin())
+ // Skip over DEBUG values, predicated nonterminators and speculation
+ // barrier terminators.
+ while (I->isDebugInstr() || !I->isTerminator() ||
+ isSpeculationBarrierEndBBOpcode(I->getOpcode()) ||
+ I->getOpcode() == ARM::t2DoLoopStartTP){
+ if (I == MBB.instr_begin())
return false;
--I;
}
@@ -393,7 +393,7 @@ bool ARMBaseInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
Cond.push_back(I->getOperand(2));
} else if (I->isReturn()) {
// Returns can't be analyzed, but we should run cleanup.
- CantAnalyze = true;
+ CantAnalyze = true;
} else {
// We encountered other unrecognized terminator. Bail out immediately.
return true;
@@ -414,30 +414,30 @@ bool ARMBaseInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
// unconditional branch.
if (AllowModify) {
MachineBasicBlock::iterator DI = std::next(I);
- while (DI != MBB.instr_end()) {
+ while (DI != MBB.instr_end()) {
MachineInstr &InstToDelete = *DI;
++DI;
- // Speculation barriers must not be deleted.
- if (isSpeculationBarrierEndBBOpcode(InstToDelete.getOpcode()))
- continue;
+ // Speculation barriers must not be deleted.
+ if (isSpeculationBarrierEndBBOpcode(InstToDelete.getOpcode()))
+ continue;
InstToDelete.eraseFromParent();
}
}
}
- if (CantAnalyze) {
- // We may not be able to analyze the block, but we could still have
- // an unconditional branch as the last instruction in the block, which
- // just branches to layout successor. If this is the case, then just
- // remove it if we're allowed to make modifications.
- if (AllowModify && !isPredicated(MBB.back()) &&
- isUncondBranchOpcode(MBB.back().getOpcode()) &&
- TBB && MBB.isLayoutSuccessor(TBB))
- removeBranch(MBB);
+ if (CantAnalyze) {
+ // We may not be able to analyze the block, but we could still have
+ // an unconditional branch as the last instruction in the block, which
+ // just branches to layout successor. If this is the case, then just
+ // remove it if we're allowed to make modifications.
+ if (AllowModify && !isPredicated(MBB.back()) &&
+ isUncondBranchOpcode(MBB.back().getOpcode()) &&
+ TBB && MBB.isLayoutSuccessor(TBB))
+ removeBranch(MBB);
return true;
- }
+ }
- if (I == MBB.instr_begin())
+ if (I == MBB.instr_begin())
return false;
--I;
@@ -586,18 +586,18 @@ bool ARMBaseInstrInfo::PredicateInstruction(
MachineOperand &PMO = MI.getOperand(PIdx);
PMO.setImm(Pred[0].getImm());
MI.getOperand(PIdx+1).setReg(Pred[1].getReg());
-
- // Thumb 1 arithmetic instructions do not set CPSR when executed inside an
- // IT block. This affects how they are printed.
- const MCInstrDesc &MCID = MI.getDesc();
- if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
- assert(MCID.OpInfo[1].isOptionalDef() && "CPSR def isn't expected operand");
- assert((MI.getOperand(1).isDead() ||
- MI.getOperand(1).getReg() != ARM::CPSR) &&
- "if conversion tried to stop defining used CPSR");
- MI.getOperand(1).setReg(ARM::NoRegister);
- }
-
+
+ // Thumb 1 arithmetic instructions do not set CPSR when executed inside an
+ // IT block. This affects how they are printed.
+ const MCInstrDesc &MCID = MI.getDesc();
+ if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
+ assert(MCID.OpInfo[1].isOptionalDef() && "CPSR def isn't expected operand");
+ assert((MI.getOperand(1).isDead() ||
+ MI.getOperand(1).getReg() != ARM::CPSR) &&
+ "if conversion tried to stop defining used CPSR");
+ MI.getOperand(1).setReg(ARM::NoRegister);
+ }
+
return true;
}
return false;
@@ -629,23 +629,23 @@ bool ARMBaseInstrInfo::SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
}
}
-bool ARMBaseInstrInfo::ClobbersPredicate(MachineInstr &MI,
- std::vector<MachineOperand> &Pred,
- bool SkipDead) const {
+bool ARMBaseInstrInfo::ClobbersPredicate(MachineInstr &MI,
+ std::vector<MachineOperand> &Pred,
+ bool SkipDead) const {
bool Found = false;
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI.getOperand(i);
- bool ClobbersCPSR = MO.isRegMask() && MO.clobbersPhysReg(ARM::CPSR);
- bool IsCPSR = MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR;
- if (ClobbersCPSR || IsCPSR) {
-
- // Filter out T1 instructions that have a dead CPSR,
- // allowing IT blocks to be generated containing T1 instructions
- const MCInstrDesc &MCID = MI.getDesc();
- if (MCID.TSFlags & ARMII::ThumbArithFlagSetting && MO.isDead() &&
- SkipDead)
- continue;
-
+ bool ClobbersCPSR = MO.isRegMask() && MO.clobbersPhysReg(ARM::CPSR);
+ bool IsCPSR = MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR;
+ if (ClobbersCPSR || IsCPSR) {
+
+ // Filter out T1 instructions that have a dead CPSR,
+ // allowing IT blocks to be generated containing T1 instructions
+ const MCInstrDesc &MCID = MI.getDesc();
+ if (MCID.TSFlags & ARMII::ThumbArithFlagSetting && MO.isDead() &&
+ SkipDead)
+ continue;
+
Pred.push_back(MO);
Found = true;
}
@@ -703,23 +703,23 @@ bool ARMBaseInstrInfo::isPredicable(const MachineInstr &MI) const {
if (!isEligibleForITBlock(&MI))
return false;
- const MachineFunction *MF = MI.getParent()->getParent();
+ const MachineFunction *MF = MI.getParent()->getParent();
const ARMFunctionInfo *AFI =
- MF->getInfo<ARMFunctionInfo>();
+ MF->getInfo<ARMFunctionInfo>();
// Neon instructions in Thumb2 IT blocks are deprecated, see ARMARM.
// In their ARM encoding, they can't be encoded in a conditional form.
if ((MI.getDesc().TSFlags & ARMII::DomainMask) == ARMII::DomainNEON)
return false;
- // Make indirect control flow changes unpredicable when SLS mitigation is
- // enabled.
- const ARMSubtarget &ST = MF->getSubtarget<ARMSubtarget>();
- if (ST.hardenSlsRetBr() && isIndirectControlFlowNotComingBack(MI))
- return false;
- if (ST.hardenSlsBlr() && isIndirectCall(MI))
- return false;
-
+ // Make indirect control flow changes unpredicable when SLS mitigation is
+ // enabled.
+ const ARMSubtarget &ST = MF->getSubtarget<ARMSubtarget>();
+ if (ST.hardenSlsRetBr() && isIndirectControlFlowNotComingBack(MI))
+ return false;
+ if (ST.hardenSlsBlr() && isIndirectCall(MI))
+ return false;
+
if (AFI->isThumb2Function()) {
if (getSubtarget().restrictIT())
return isV8EligibleForIT(&MI);
@@ -802,14 +802,14 @@ unsigned ARMBaseInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
Size = alignTo(Size, 4);
return Size;
}
- case ARM::SpeculationBarrierISBDSBEndBB:
- case ARM::t2SpeculationBarrierISBDSBEndBB:
- // This gets lowered to 2 4-byte instructions.
- return 8;
- case ARM::SpeculationBarrierSBEndBB:
- case ARM::t2SpeculationBarrierSBEndBB:
- // This gets lowered to 1 4-byte instructions.
- return 4;
+ case ARM::SpeculationBarrierISBDSBEndBB:
+ case ARM::t2SpeculationBarrierISBDSBEndBB:
+ // This gets lowered to 2 4-byte instructions.
+ return 8;
+ case ARM::SpeculationBarrierSBEndBB:
+ case ARM::t2SpeculationBarrierSBEndBB:
+ // This gets lowered to 1 4-byte instructions.
+ return 4;
}
}
@@ -2175,12 +2175,12 @@ ARMBaseInstrInfo::extraSizeToPredicateInstructions(const MachineFunction &MF,
// Thumb2 needs a 2-byte IT instruction to predicate up to 4 instructions.
// ARM has a condition code field in every predicable instruction, using it
// doesn't change code size.
- if (!Subtarget.isThumb2())
- return 0;
-
- // It's possible that the size of the IT is restricted to a single block.
- unsigned MaxInsts = Subtarget.restrictIT() ? 1 : 4;
- return divideCeil(NumInsts, MaxInsts) * 2;
+ if (!Subtarget.isThumb2())
+ return 0;
+
+ // It's possible that the size of the IT is restricted to a single block.
+ unsigned MaxInsts = Subtarget.restrictIT() ? 1 : 4;
+ return divideCeil(NumInsts, MaxInsts) * 2;
}
unsigned
@@ -3417,7 +3417,7 @@ bool ARMBaseInstrInfo::FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
case ARM::t2SUBspImm:
case ARM::t2ADDri:
case ARM::t2SUBri:
- MRI->constrainRegClass(UseMI.getOperand(0).getReg(), TRC);
+ MRI->constrainRegClass(UseMI.getOperand(0).getReg(), TRC);
}
return true;
}
@@ -4838,14 +4838,14 @@ bool ARMBaseInstrInfo::verifyInstruction(const MachineInstr &MI,
}
}
}
- if (MI.getOpcode() == ARM::MVE_VMOV_q_rr) {
- assert(MI.getOperand(4).isImm() && MI.getOperand(5).isImm());
- if ((MI.getOperand(4).getImm() != 2 && MI.getOperand(4).getImm() != 3) ||
- MI.getOperand(4).getImm() != MI.getOperand(5).getImm() + 2) {
- ErrInfo = "Incorrect array index for MVE_VMOV_q_rr";
- return false;
- }
- }
+ if (MI.getOpcode() == ARM::MVE_VMOV_q_rr) {
+ assert(MI.getOperand(4).isImm() && MI.getOperand(5).isImm());
+ if ((MI.getOperand(4).getImm() != 2 && MI.getOperand(4).getImm() != 3) ||
+ MI.getOperand(4).getImm() != MI.getOperand(5).getImm() + 2) {
+ ErrInfo = "Incorrect array index for MVE_VMOV_q_rr";
+ return false;
+ }
+ }
return true;
}
@@ -5531,8 +5531,8 @@ unsigned llvm::ConstantMaterializationCost(unsigned Val,
return ForCodesize ? 4 : 1;
if (ARM_AM::isSOImmTwoPartVal(Val)) // two instrs
return ForCodesize ? 8 : 2;
- if (ARM_AM::isSOImmTwoPartValNeg(Val)) // two instrs
- return ForCodesize ? 8 : 2;
+ if (ARM_AM::isSOImmTwoPartValNeg(Val)) // two instrs
+ return ForCodesize ? 8 : 2;
}
if (Subtarget->useMovt()) // MOVW + MOVT
return ForCodesize ? 8 : 2;
@@ -5637,32 +5637,32 @@ bool llvm::HasLowerConstantMaterializationCost(unsigned Val1, unsigned Val2,
/// | Frame overhead in Bytes | 2 | 4 |
/// | Stack fixup required | No | No |
/// +-------------------------+--------+-----+
-///
-/// \p MachineOutlinerDefault implies that the function should be called with
-/// a save and restore of LR to the stack.
-///
-/// That is,
-///
-/// I1 Save LR OUTLINED_FUNCTION:
-/// I2 --> BL OUTLINED_FUNCTION I1
-/// I3 Restore LR I2
-/// I3
-/// BX LR
-///
-/// +-------------------------+--------+-----+
-/// | | Thumb2 | ARM |
-/// +-------------------------+--------+-----+
-/// | Call overhead in Bytes | 8 | 12 |
-/// | Frame overhead in Bytes | 2 | 4 |
-/// | Stack fixup required | Yes | Yes |
-/// +-------------------------+--------+-----+
+///
+/// \p MachineOutlinerDefault implies that the function should be called with
+/// a save and restore of LR to the stack.
+///
+/// That is,
+///
+/// I1 Save LR OUTLINED_FUNCTION:
+/// I2 --> BL OUTLINED_FUNCTION I1
+/// I3 Restore LR I2
+/// I3
+/// BX LR
+///
+/// +-------------------------+--------+-----+
+/// | | Thumb2 | ARM |
+/// +-------------------------+--------+-----+
+/// | Call overhead in Bytes | 8 | 12 |
+/// | Frame overhead in Bytes | 2 | 4 |
+/// | Stack fixup required | Yes | Yes |
+/// +-------------------------+--------+-----+
enum MachineOutlinerClass {
MachineOutlinerTailCall,
MachineOutlinerThunk,
MachineOutlinerNoLRSave,
- MachineOutlinerRegSave,
- MachineOutlinerDefault
+ MachineOutlinerRegSave,
+ MachineOutlinerDefault
};
enum MachineOutlinerMBBFlags {
@@ -5680,9 +5680,9 @@ struct OutlinerCosts {
const int FrameNoLRSave;
const int CallRegSave;
const int FrameRegSave;
- const int CallDefault;
- const int FrameDefault;
- const int SaveRestoreLROnStack;
+ const int CallDefault;
+ const int FrameDefault;
+ const int SaveRestoreLROnStack;
OutlinerCosts(const ARMSubtarget &target)
: CallTailCall(target.isThumb() ? 4 : 4),
@@ -5692,10 +5692,10 @@ struct OutlinerCosts {
CallNoLRSave(target.isThumb() ? 4 : 4),
FrameNoLRSave(target.isThumb() ? 4 : 4),
CallRegSave(target.isThumb() ? 8 : 12),
- FrameRegSave(target.isThumb() ? 2 : 4),
- CallDefault(target.isThumb() ? 8 : 12),
- FrameDefault(target.isThumb() ? 2 : 4),
- SaveRestoreLROnStack(target.isThumb() ? 8 : 8) {}
+ FrameRegSave(target.isThumb() ? 2 : 4),
+ CallDefault(target.isThumb() ? 8 : 12),
+ FrameDefault(target.isThumb() ? 2 : 4),
+ SaveRestoreLROnStack(target.isThumb() ? 8 : 8) {}
};
unsigned
@@ -5720,37 +5720,37 @@ ARMBaseInstrInfo::findRegisterToSaveLRTo(const outliner::Candidate &C) const {
return 0u;
}
-// Compute liveness of LR at the point after the interval [I, E), which
-// denotes a *backward* iteration through instructions. Used only for return
-// basic blocks, which do not end with a tail call.
-static bool isLRAvailable(const TargetRegisterInfo &TRI,
- MachineBasicBlock::reverse_iterator I,
- MachineBasicBlock::reverse_iterator E) {
- // At the end of the function LR dead.
- bool Live = false;
- for (; I != E; ++I) {
- const MachineInstr &MI = *I;
-
- // Check defs of LR.
- if (MI.modifiesRegister(ARM::LR, &TRI))
- Live = false;
-
- // Check uses of LR.
- unsigned Opcode = MI.getOpcode();
- if (Opcode == ARM::BX_RET || Opcode == ARM::MOVPCLR ||
- Opcode == ARM::SUBS_PC_LR || Opcode == ARM::tBX_RET ||
- Opcode == ARM::tBXNS_RET) {
- // These instructions use LR, but it's not an (explicit or implicit)
- // operand.
- Live = true;
- continue;
- }
- if (MI.readsRegister(ARM::LR, &TRI))
- Live = true;
- }
- return !Live;
-}
-
+// Compute liveness of LR at the point after the interval [I, E), which
+// denotes a *backward* iteration through instructions. Used only for return
+// basic blocks, which do not end with a tail call.
+static bool isLRAvailable(const TargetRegisterInfo &TRI,
+ MachineBasicBlock::reverse_iterator I,
+ MachineBasicBlock::reverse_iterator E) {
+ // At the end of the function LR dead.
+ bool Live = false;
+ for (; I != E; ++I) {
+ const MachineInstr &MI = *I;
+
+ // Check defs of LR.
+ if (MI.modifiesRegister(ARM::LR, &TRI))
+ Live = false;
+
+ // Check uses of LR.
+ unsigned Opcode = MI.getOpcode();
+ if (Opcode == ARM::BX_RET || Opcode == ARM::MOVPCLR ||
+ Opcode == ARM::SUBS_PC_LR || Opcode == ARM::tBX_RET ||
+ Opcode == ARM::tBXNS_RET) {
+ // These instructions use LR, but it's not an (explicit or implicit)
+ // operand.
+ Live = true;
+ continue;
+ }
+ if (MI.readsRegister(ARM::LR, &TRI))
+ Live = true;
+ }
+ return !Live;
+}
+
outliner::OutlinedFunction ARMBaseInstrInfo::getOutliningCandidateInfo(
std::vector<outliner::Candidate> &RepeatedSequenceLocs) const {
outliner::Candidate &FirstCand = RepeatedSequenceLocs[0];
@@ -5796,7 +5796,7 @@ outliner::OutlinedFunction ARMBaseInstrInfo::getOutliningCandidateInfo(
// Erase every candidate that violates the restrictions above. (It could be
// true that we have viable candidates, so it's not worth bailing out in
// the case that, say, 1 out of 20 candidates violate the restructions.)
- llvm::erase_if(RepeatedSequenceLocs, CantGuaranteeValueAcrossCall);
+ llvm::erase_if(RepeatedSequenceLocs, CantGuaranteeValueAcrossCall);
// If the sequence doesn't have enough candidates left, then we're done.
if (RepeatedSequenceLocs.size() < 2)
@@ -5816,8 +5816,8 @@ outliner::OutlinedFunction ARMBaseInstrInfo::getOutliningCandidateInfo(
};
OutlinerCosts Costs(Subtarget);
- unsigned FrameID = MachineOutlinerDefault;
- unsigned NumBytesToCreateFrame = Costs.FrameDefault;
+ unsigned FrameID = MachineOutlinerDefault;
+ unsigned NumBytesToCreateFrame = Costs.FrameDefault;
// If the last instruction in any candidate is a terminator, then we should
// tail call all of the candidates.
@@ -5826,31 +5826,31 @@ outliner::OutlinedFunction ARMBaseInstrInfo::getOutliningCandidateInfo(
NumBytesToCreateFrame = Costs.FrameTailCall;
SetCandidateCallInfo(MachineOutlinerTailCall, Costs.CallTailCall);
} else if (LastInstrOpcode == ARM::BL || LastInstrOpcode == ARM::BLX ||
- LastInstrOpcode == ARM::BLX_noip || LastInstrOpcode == ARM::tBL ||
- LastInstrOpcode == ARM::tBLXr ||
- LastInstrOpcode == ARM::tBLXr_noip ||
+ LastInstrOpcode == ARM::BLX_noip || LastInstrOpcode == ARM::tBL ||
+ LastInstrOpcode == ARM::tBLXr ||
+ LastInstrOpcode == ARM::tBLXr_noip ||
LastInstrOpcode == ARM::tBLXi) {
FrameID = MachineOutlinerThunk;
NumBytesToCreateFrame = Costs.FrameThunk;
SetCandidateCallInfo(MachineOutlinerThunk, Costs.CallThunk);
} else {
// We need to decide how to emit calls + frames. We can always emit the same
- // frame if we don't need to save to the stack. If we have to save to the
- // stack, then we need a different frame.
+ // frame if we don't need to save to the stack. If we have to save to the
+ // stack, then we need a different frame.
unsigned NumBytesNoStackCalls = 0;
std::vector<outliner::Candidate> CandidatesWithoutStackFixups;
for (outliner::Candidate &C : RepeatedSequenceLocs) {
C.initLRU(TRI);
- // LR liveness is overestimated in return blocks, unless they end with a
- // tail call.
- const auto Last = C.getMBB()->rbegin();
- const bool LRIsAvailable =
- C.getMBB()->isReturnBlock() && !Last->isCall()
- ? isLRAvailable(TRI, Last,
- (MachineBasicBlock::reverse_iterator)C.front())
- : C.LRU.available(ARM::LR);
- if (LRIsAvailable) {
+ // LR liveness is overestimated in return blocks, unless they end with a
+ // tail call.
+ const auto Last = C.getMBB()->rbegin();
+ const bool LRIsAvailable =
+ C.getMBB()->isReturnBlock() && !Last->isCall()
+ ? isLRAvailable(TRI, Last,
+ (MachineBasicBlock::reverse_iterator)C.front())
+ : C.LRU.available(ARM::LR);
+ if (LRIsAvailable) {
FrameID = MachineOutlinerNoLRSave;
NumBytesNoStackCalls += Costs.CallNoLRSave;
C.setCallInfo(MachineOutlinerNoLRSave, Costs.CallNoLRSave);
@@ -5865,157 +5865,157 @@ outliner::OutlinedFunction ARMBaseInstrInfo::getOutliningCandidateInfo(
C.setCallInfo(MachineOutlinerRegSave, Costs.CallRegSave);
CandidatesWithoutStackFixups.push_back(C);
}
-
- // Is SP used in the sequence at all? If not, we don't have to modify
- // the stack, so we are guaranteed to get the same frame.
- else if (C.UsedInSequence.available(ARM::SP)) {
- NumBytesNoStackCalls += Costs.CallDefault;
- C.setCallInfo(MachineOutlinerDefault, Costs.CallDefault);
- CandidatesWithoutStackFixups.push_back(C);
- }
-
- // If we outline this, we need to modify the stack. Pretend we don't
- // outline this by saving all of its bytes.
- else
- NumBytesNoStackCalls += SequenceSize;
+
+ // Is SP used in the sequence at all? If not, we don't have to modify
+ // the stack, so we are guaranteed to get the same frame.
+ else if (C.UsedInSequence.available(ARM::SP)) {
+ NumBytesNoStackCalls += Costs.CallDefault;
+ C.setCallInfo(MachineOutlinerDefault, Costs.CallDefault);
+ CandidatesWithoutStackFixups.push_back(C);
+ }
+
+ // If we outline this, we need to modify the stack. Pretend we don't
+ // outline this by saving all of its bytes.
+ else
+ NumBytesNoStackCalls += SequenceSize;
}
- // If there are no places where we have to save LR, then note that we don't
- // have to update the stack. Otherwise, give every candidate the default
- // call type
- if (NumBytesNoStackCalls <=
- RepeatedSequenceLocs.size() * Costs.CallDefault) {
+ // If there are no places where we have to save LR, then note that we don't
+ // have to update the stack. Otherwise, give every candidate the default
+ // call type
+ if (NumBytesNoStackCalls <=
+ RepeatedSequenceLocs.size() * Costs.CallDefault) {
RepeatedSequenceLocs = CandidatesWithoutStackFixups;
- FrameID = MachineOutlinerNoLRSave;
+ FrameID = MachineOutlinerNoLRSave;
} else
- SetCandidateCallInfo(MachineOutlinerDefault, Costs.CallDefault);
- }
-
- // Does every candidate's MBB contain a call? If so, then we might have a
- // call in the range.
- if (FlagsSetInAll & MachineOutlinerMBBFlags::HasCalls) {
- // check if the range contains a call. These require a save + restore of
- // the link register.
- if (std::any_of(FirstCand.front(), FirstCand.back(),
- [](const MachineInstr &MI) { return MI.isCall(); }))
- NumBytesToCreateFrame += Costs.SaveRestoreLROnStack;
-
- // Handle the last instruction separately. If it is tail call, then the
- // last instruction is a call, we don't want to save + restore in this
- // case. However, it could be possible that the last instruction is a
- // call without it being valid to tail call this sequence. We should
- // consider this as well.
- else if (FrameID != MachineOutlinerThunk &&
- FrameID != MachineOutlinerTailCall && FirstCand.back()->isCall())
- NumBytesToCreateFrame += Costs.SaveRestoreLROnStack;
- }
-
+ SetCandidateCallInfo(MachineOutlinerDefault, Costs.CallDefault);
+ }
+
+ // Does every candidate's MBB contain a call? If so, then we might have a
+ // call in the range.
+ if (FlagsSetInAll & MachineOutlinerMBBFlags::HasCalls) {
+ // check if the range contains a call. These require a save + restore of
+ // the link register.
+ if (std::any_of(FirstCand.front(), FirstCand.back(),
+ [](const MachineInstr &MI) { return MI.isCall(); }))
+ NumBytesToCreateFrame += Costs.SaveRestoreLROnStack;
+
+ // Handle the last instruction separately. If it is tail call, then the
+ // last instruction is a call, we don't want to save + restore in this
+ // case. However, it could be possible that the last instruction is a
+ // call without it being valid to tail call this sequence. We should
+ // consider this as well.
+ else if (FrameID != MachineOutlinerThunk &&
+ FrameID != MachineOutlinerTailCall && FirstCand.back()->isCall())
+ NumBytesToCreateFrame += Costs.SaveRestoreLROnStack;
+ }
+
return outliner::OutlinedFunction(RepeatedSequenceLocs, SequenceSize,
NumBytesToCreateFrame, FrameID);
}
-bool ARMBaseInstrInfo::checkAndUpdateStackOffset(MachineInstr *MI,
- int64_t Fixup,
- bool Updt) const {
- int SPIdx = MI->findRegisterUseOperandIdx(ARM::SP);
- unsigned AddrMode = (MI->getDesc().TSFlags & ARMII::AddrModeMask);
- if (SPIdx < 0)
- // No SP operand
- return true;
- else if (SPIdx != 1 && (AddrMode != ARMII::AddrModeT2_i8s4 || SPIdx != 2))
- // If SP is not the base register we can't do much
- return false;
-
- // Stack might be involved but addressing mode doesn't handle any offset.
- // Rq: AddrModeT1_[1|2|4] don't operate on SP
- if (AddrMode == ARMII::AddrMode1 // Arithmetic instructions
- || AddrMode == ARMII::AddrMode4 // Load/Store Multiple
- || AddrMode == ARMII::AddrMode6 // Neon Load/Store Multiple
- || AddrMode == ARMII::AddrModeT2_so // SP can't be used as based register
- || AddrMode == ARMII::AddrModeT2_pc // PCrel access
- || AddrMode == ARMII::AddrMode2 // Used by PRE and POST indexed LD/ST
- || AddrMode == ARMII::AddrModeT2_i7 // v8.1-M MVE
- || AddrMode == ARMII::AddrModeT2_i7s2 // v8.1-M MVE
- || AddrMode == ARMII::AddrModeT2_i7s4 // v8.1-M sys regs VLDR/VSTR
- || AddrMode == ARMII::AddrModeNone)
- return false;
-
- unsigned NumOps = MI->getDesc().getNumOperands();
- unsigned ImmIdx = NumOps - 3;
-
- const MachineOperand &Offset = MI->getOperand(ImmIdx);
- assert(Offset.isImm() && "Is not an immediate");
- int64_t OffVal = Offset.getImm();
-
- if (OffVal < 0)
- // Don't override data if the are below SP.
- return false;
-
- unsigned NumBits = 0;
- unsigned Scale = 1;
-
- switch (AddrMode) {
- case ARMII::AddrMode3:
- if (ARM_AM::getAM3Op(OffVal) == ARM_AM::sub)
- return false;
- OffVal = ARM_AM::getAM3Offset(OffVal);
- NumBits = 8;
- break;
- case ARMII::AddrMode5:
- if (ARM_AM::getAM5Op(OffVal) == ARM_AM::sub)
- return false;
- OffVal = ARM_AM::getAM5Offset(OffVal);
- NumBits = 8;
- Scale = 4;
- break;
- case ARMII::AddrMode5FP16:
- if (ARM_AM::getAM5FP16Op(OffVal) == ARM_AM::sub)
- return false;
- OffVal = ARM_AM::getAM5FP16Offset(OffVal);
- NumBits = 8;
- Scale = 2;
- break;
- case ARMII::AddrModeT2_i8:
- NumBits = 8;
- break;
- case ARMII::AddrModeT2_i8s4:
- // FIXME: Values are already scaled in this addressing mode.
- assert((Fixup & 3) == 0 && "Can't encode this offset!");
- NumBits = 10;
- break;
- case ARMII::AddrModeT2_ldrex:
- NumBits = 8;
- Scale = 4;
- break;
- case ARMII::AddrModeT2_i12:
- case ARMII::AddrMode_i12:
- NumBits = 12;
- break;
- case ARMII::AddrModeT1_s: // SP-relative LD/ST
- NumBits = 8;
- Scale = 4;
- break;
- default:
- llvm_unreachable("Unsupported addressing mode!");
- }
- // Make sure the offset is encodable for instructions that scale the
- // immediate.
- assert(((OffVal * Scale + Fixup) & (Scale - 1)) == 0 &&
- "Can't encode this offset!");
- OffVal += Fixup / Scale;
-
- unsigned Mask = (1 << NumBits) - 1;
-
- if (OffVal <= Mask) {
- if (Updt)
- MI->getOperand(ImmIdx).setImm(OffVal);
- return true;
- }
-
- return false;
-
-}
-
+bool ARMBaseInstrInfo::checkAndUpdateStackOffset(MachineInstr *MI,
+ int64_t Fixup,
+ bool Updt) const {
+ int SPIdx = MI->findRegisterUseOperandIdx(ARM::SP);
+ unsigned AddrMode = (MI->getDesc().TSFlags & ARMII::AddrModeMask);
+ if (SPIdx < 0)
+ // No SP operand
+ return true;
+ else if (SPIdx != 1 && (AddrMode != ARMII::AddrModeT2_i8s4 || SPIdx != 2))
+ // If SP is not the base register we can't do much
+ return false;
+
+ // Stack might be involved but addressing mode doesn't handle any offset.
+ // Rq: AddrModeT1_[1|2|4] don't operate on SP
+ if (AddrMode == ARMII::AddrMode1 // Arithmetic instructions
+ || AddrMode == ARMII::AddrMode4 // Load/Store Multiple
+ || AddrMode == ARMII::AddrMode6 // Neon Load/Store Multiple
+ || AddrMode == ARMII::AddrModeT2_so // SP can't be used as based register
+ || AddrMode == ARMII::AddrModeT2_pc // PCrel access
+ || AddrMode == ARMII::AddrMode2 // Used by PRE and POST indexed LD/ST
+ || AddrMode == ARMII::AddrModeT2_i7 // v8.1-M MVE
+ || AddrMode == ARMII::AddrModeT2_i7s2 // v8.1-M MVE
+ || AddrMode == ARMII::AddrModeT2_i7s4 // v8.1-M sys regs VLDR/VSTR
+ || AddrMode == ARMII::AddrModeNone)
+ return false;
+
+ unsigned NumOps = MI->getDesc().getNumOperands();
+ unsigned ImmIdx = NumOps - 3;
+
+ const MachineOperand &Offset = MI->getOperand(ImmIdx);
+ assert(Offset.isImm() && "Is not an immediate");
+ int64_t OffVal = Offset.getImm();
+
+ if (OffVal < 0)
+ // Don't override data if the are below SP.
+ return false;
+
+ unsigned NumBits = 0;
+ unsigned Scale = 1;
+
+ switch (AddrMode) {
+ case ARMII::AddrMode3:
+ if (ARM_AM::getAM3Op(OffVal) == ARM_AM::sub)
+ return false;
+ OffVal = ARM_AM::getAM3Offset(OffVal);
+ NumBits = 8;
+ break;
+ case ARMII::AddrMode5:
+ if (ARM_AM::getAM5Op(OffVal) == ARM_AM::sub)
+ return false;
+ OffVal = ARM_AM::getAM5Offset(OffVal);
+ NumBits = 8;
+ Scale = 4;
+ break;
+ case ARMII::AddrMode5FP16:
+ if (ARM_AM::getAM5FP16Op(OffVal) == ARM_AM::sub)
+ return false;
+ OffVal = ARM_AM::getAM5FP16Offset(OffVal);
+ NumBits = 8;
+ Scale = 2;
+ break;
+ case ARMII::AddrModeT2_i8:
+ NumBits = 8;
+ break;
+ case ARMII::AddrModeT2_i8s4:
+ // FIXME: Values are already scaled in this addressing mode.
+ assert((Fixup & 3) == 0 && "Can't encode this offset!");
+ NumBits = 10;
+ break;
+ case ARMII::AddrModeT2_ldrex:
+ NumBits = 8;
+ Scale = 4;
+ break;
+ case ARMII::AddrModeT2_i12:
+ case ARMII::AddrMode_i12:
+ NumBits = 12;
+ break;
+ case ARMII::AddrModeT1_s: // SP-relative LD/ST
+ NumBits = 8;
+ Scale = 4;
+ break;
+ default:
+ llvm_unreachable("Unsupported addressing mode!");
+ }
+ // Make sure the offset is encodable for instructions that scale the
+ // immediate.
+ assert(((OffVal * Scale + Fixup) & (Scale - 1)) == 0 &&
+ "Can't encode this offset!");
+ OffVal += Fixup / Scale;
+
+ unsigned Mask = (1 << NumBits) - 1;
+
+ if (OffVal <= Mask) {
+ if (Updt)
+ MI->getOperand(ImmIdx).setImm(OffVal);
+ return true;
+ }
+
+ return false;
+
+}
+
bool ARMBaseInstrInfo::isFunctionSafeToOutlineFrom(
MachineFunction &MF, bool OutlineFromLinkOnceODRs) const {
const Function &F = MF.getFunction();
@@ -6075,13 +6075,13 @@ bool ARMBaseInstrInfo::isMBBSafeToOutlineFrom(MachineBasicBlock &MBB,
if (any_of(MBB, [](MachineInstr &MI) { return MI.isCall(); }))
Flags |= MachineOutlinerMBBFlags::HasCalls;
- // LR liveness is overestimated in return blocks.
-
- bool LRIsAvailable =
- MBB.isReturnBlock() && !MBB.back().isCall()
- ? isLRAvailable(getRegisterInfo(), MBB.rbegin(), MBB.rend())
- : LRU.available(ARM::LR);
- if (!LRIsAvailable)
+ // LR liveness is overestimated in return blocks.
+
+ bool LRIsAvailable =
+ MBB.isReturnBlock() && !MBB.back().isCall()
+ ? isLRAvailable(getRegisterInfo(), MBB.rbegin(), MBB.rend())
+ : LRU.available(ARM::LR);
+ if (!LRIsAvailable)
Flags |= MachineOutlinerMBBFlags::LRUnavailableSomewhere;
return true;
@@ -6119,9 +6119,9 @@ ARMBaseInstrInfo::getOutliningType(MachineBasicBlock::iterator &MIT,
// Be conservative with ARMv8.1 MVE instructions.
if (Opc == ARM::t2BF_LabelPseudo || Opc == ARM::t2DoLoopStart ||
- Opc == ARM::t2DoLoopStartTP || Opc == ARM::t2WhileLoopStart ||
- Opc == ARM::t2LoopDec || Opc == ARM::t2LoopEnd ||
- Opc == ARM::t2LoopEndDec)
+ Opc == ARM::t2DoLoopStartTP || Opc == ARM::t2WhileLoopStart ||
+ Opc == ARM::t2LoopDec || Opc == ARM::t2LoopEnd ||
+ Opc == ARM::t2LoopEndDec)
return outliner::InstrType::Illegal;
const MCInstrDesc &MCID = MI.getDesc();
@@ -6155,56 +6155,56 @@ ARMBaseInstrInfo::getOutliningType(MachineBasicBlock::iterator &MIT,
return outliner::InstrType::Illegal;
if (MI.isCall()) {
- // Get the function associated with the call. Look at each operand and find
- // the one that represents the calle and get its name.
- const Function *Callee = nullptr;
- for (const MachineOperand &MOP : MI.operands()) {
- if (MOP.isGlobal()) {
- Callee = dyn_cast<Function>(MOP.getGlobal());
- break;
- }
- }
-
- // Dont't outline calls to "mcount" like functions, in particular Linux
- // kernel function tracing relies on it.
- if (Callee &&
- (Callee->getName() == "\01__gnu_mcount_nc" ||
- Callee->getName() == "\01mcount" || Callee->getName() == "__mcount"))
- return outliner::InstrType::Illegal;
-
+ // Get the function associated with the call. Look at each operand and find
+ // the one that represents the calle and get its name.
+ const Function *Callee = nullptr;
+ for (const MachineOperand &MOP : MI.operands()) {
+ if (MOP.isGlobal()) {
+ Callee = dyn_cast<Function>(MOP.getGlobal());
+ break;
+ }
+ }
+
+ // Dont't outline calls to "mcount" like functions, in particular Linux
+ // kernel function tracing relies on it.
+ if (Callee &&
+ (Callee->getName() == "\01__gnu_mcount_nc" ||
+ Callee->getName() == "\01mcount" || Callee->getName() == "__mcount"))
+ return outliner::InstrType::Illegal;
+
// If we don't know anything about the callee, assume it depends on the
// stack layout of the caller. In that case, it's only legal to outline
// as a tail-call. Explicitly list the call instructions we know about so
// we don't get unexpected results with call pseudo-instructions.
auto UnknownCallOutlineType = outliner::InstrType::Illegal;
if (Opc == ARM::BL || Opc == ARM::tBL || Opc == ARM::BLX ||
- Opc == ARM::BLX_noip || Opc == ARM::tBLXr || Opc == ARM::tBLXr_noip ||
- Opc == ARM::tBLXi)
+ Opc == ARM::BLX_noip || Opc == ARM::tBLXr || Opc == ARM::tBLXr_noip ||
+ Opc == ARM::tBLXi)
UnknownCallOutlineType = outliner::InstrType::LegalTerminator;
- if (!Callee)
- return UnknownCallOutlineType;
-
- // We have a function we have information about. Check if it's something we
- // can safely outline.
- MachineFunction *MF = MI.getParent()->getParent();
- MachineFunction *CalleeMF = MF->getMMI().getMachineFunction(*Callee);
-
- // We don't know what's going on with the callee at all. Don't touch it.
- if (!CalleeMF)
- return UnknownCallOutlineType;
-
- // Check if we know anything about the callee saves on the function. If we
- // don't, then don't touch it, since that implies that we haven't computed
- // anything about its stack frame yet.
- MachineFrameInfo &MFI = CalleeMF->getFrameInfo();
- if (!MFI.isCalleeSavedInfoValid() || MFI.getStackSize() > 0 ||
- MFI.getNumObjects() > 0)
- return UnknownCallOutlineType;
-
- // At this point, we can say that CalleeMF ought to not pass anything on the
- // stack. Therefore, we can outline it.
- return outliner::InstrType::Legal;
+ if (!Callee)
+ return UnknownCallOutlineType;
+
+ // We have a function we have information about. Check if it's something we
+ // can safely outline.
+ MachineFunction *MF = MI.getParent()->getParent();
+ MachineFunction *CalleeMF = MF->getMMI().getMachineFunction(*Callee);
+
+ // We don't know what's going on with the callee at all. Don't touch it.
+ if (!CalleeMF)
+ return UnknownCallOutlineType;
+
+ // Check if we know anything about the callee saves on the function. If we
+ // don't, then don't touch it, since that implies that we haven't computed
+ // anything about its stack frame yet.
+ MachineFrameInfo &MFI = CalleeMF->getFrameInfo();
+ if (!MFI.isCalleeSavedInfoValid() || MFI.getStackSize() > 0 ||
+ MFI.getNumObjects() > 0)
+ return UnknownCallOutlineType;
+
+ // At this point, we can say that CalleeMF ought to not pass anything on the
+ // stack. Therefore, we can outline it.
+ return outliner::InstrType::Legal;
}
// Since calls are handled, don't touch LR or PC
@@ -6227,19 +6227,19 @@ ARMBaseInstrInfo::getOutliningType(MachineBasicBlock::iterator &MIT,
if (!MightNeedStackFixUp)
return outliner::InstrType::Legal;
- // Any modification of SP will break our code to save/restore LR.
- // FIXME: We could handle some instructions which add a constant offset to
- // SP, with a bit more work.
- if (MI.modifiesRegister(ARM::SP, TRI))
- return outliner::InstrType::Illegal;
-
- // At this point, we have a stack instruction that we might need to fix up.
- // up. We'll handle it if it's a load or store.
- if (checkAndUpdateStackOffset(&MI, Subtarget.getStackAlignment().value(),
- false))
- return outliner::InstrType::Legal;
-
- // We can't fix it up, so don't outline it.
+ // Any modification of SP will break our code to save/restore LR.
+ // FIXME: We could handle some instructions which add a constant offset to
+ // SP, with a bit more work.
+ if (MI.modifiesRegister(ARM::SP, TRI))
+ return outliner::InstrType::Illegal;
+
+ // At this point, we have a stack instruction that we might need to fix up.
+ // up. We'll handle it if it's a load or store.
+ if (checkAndUpdateStackOffset(&MI, Subtarget.getStackAlignment().value(),
+ false))
+ return outliner::InstrType::Legal;
+
+ // We can't fix it up, so don't outline it.
return outliner::InstrType::Illegal;
}
@@ -6255,104 +6255,104 @@ ARMBaseInstrInfo::getOutliningType(MachineBasicBlock::iterator &MIT,
return outliner::InstrType::Legal;
}
-void ARMBaseInstrInfo::fixupPostOutline(MachineBasicBlock &MBB) const {
- for (MachineInstr &MI : MBB) {
- checkAndUpdateStackOffset(&MI, Subtarget.getStackAlignment().value(), true);
- }
-}
-
-void ARMBaseInstrInfo::saveLROnStack(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator It) const {
- unsigned Opc = Subtarget.isThumb() ? ARM::t2STR_PRE : ARM::STR_PRE_IMM;
- int Align = -Subtarget.getStackAlignment().value();
- BuildMI(MBB, It, DebugLoc(), get(Opc), ARM::SP)
- .addReg(ARM::LR, RegState::Kill)
- .addReg(ARM::SP)
- .addImm(Align)
- .add(predOps(ARMCC::AL));
-}
-
-void ARMBaseInstrInfo::emitCFIForLRSaveOnStack(
- MachineBasicBlock &MBB, MachineBasicBlock::iterator It) const {
- MachineFunction &MF = *MBB.getParent();
- const MCRegisterInfo *MRI = Subtarget.getRegisterInfo();
- unsigned DwarfLR = MRI->getDwarfRegNum(ARM::LR, true);
- int Align = Subtarget.getStackAlignment().value();
- // Add a CFI saying the stack was moved down.
- int64_t StackPosEntry =
- MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, Align));
- BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
- .addCFIIndex(StackPosEntry)
- .setMIFlags(MachineInstr::FrameSetup);
-
- // Add a CFI saying that the LR that we want to find is now higher than
- // before.
- int64_t LRPosEntry =
- MF.addFrameInst(MCCFIInstruction::createOffset(nullptr, DwarfLR, -Align));
- BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
- .addCFIIndex(LRPosEntry)
- .setMIFlags(MachineInstr::FrameSetup);
-}
-
-void ARMBaseInstrInfo::emitCFIForLRSaveToReg(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator It,
- Register Reg) const {
- MachineFunction &MF = *MBB.getParent();
- const MCRegisterInfo *MRI = Subtarget.getRegisterInfo();
- unsigned DwarfLR = MRI->getDwarfRegNum(ARM::LR, true);
- unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
-
- int64_t LRPosEntry = MF.addFrameInst(
- MCCFIInstruction::createRegister(nullptr, DwarfLR, DwarfReg));
- BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
- .addCFIIndex(LRPosEntry)
- .setMIFlags(MachineInstr::FrameSetup);
-}
-
-void ARMBaseInstrInfo::restoreLRFromStack(
- MachineBasicBlock &MBB, MachineBasicBlock::iterator It) const {
- unsigned Opc = Subtarget.isThumb() ? ARM::t2LDR_POST : ARM::LDR_POST_IMM;
- MachineInstrBuilder MIB = BuildMI(MBB, It, DebugLoc(), get(Opc), ARM::LR)
- .addReg(ARM::SP, RegState::Define)
- .addReg(ARM::SP);
- if (!Subtarget.isThumb())
- MIB.addReg(0);
- MIB.addImm(Subtarget.getStackAlignment().value()).add(predOps(ARMCC::AL));
-}
-
-void ARMBaseInstrInfo::emitCFIForLRRestoreFromStack(
- MachineBasicBlock &MBB, MachineBasicBlock::iterator It) const {
- // Now stack has moved back up...
- MachineFunction &MF = *MBB.getParent();
- const MCRegisterInfo *MRI = Subtarget.getRegisterInfo();
- unsigned DwarfLR = MRI->getDwarfRegNum(ARM::LR, true);
- int64_t StackPosEntry =
- MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, 0));
- BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
- .addCFIIndex(StackPosEntry)
- .setMIFlags(MachineInstr::FrameDestroy);
-
- // ... and we have restored LR.
- int64_t LRPosEntry =
- MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, DwarfLR));
- BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
- .addCFIIndex(LRPosEntry)
- .setMIFlags(MachineInstr::FrameDestroy);
-}
-
-void ARMBaseInstrInfo::emitCFIForLRRestoreFromReg(
- MachineBasicBlock &MBB, MachineBasicBlock::iterator It) const {
- MachineFunction &MF = *MBB.getParent();
- const MCRegisterInfo *MRI = Subtarget.getRegisterInfo();
- unsigned DwarfLR = MRI->getDwarfRegNum(ARM::LR, true);
-
- int64_t LRPosEntry =
- MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, DwarfLR));
- BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
- .addCFIIndex(LRPosEntry)
- .setMIFlags(MachineInstr::FrameDestroy);
-}
-
+void ARMBaseInstrInfo::fixupPostOutline(MachineBasicBlock &MBB) const {
+ for (MachineInstr &MI : MBB) {
+ checkAndUpdateStackOffset(&MI, Subtarget.getStackAlignment().value(), true);
+ }
+}
+
+void ARMBaseInstrInfo::saveLROnStack(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator It) const {
+ unsigned Opc = Subtarget.isThumb() ? ARM::t2STR_PRE : ARM::STR_PRE_IMM;
+ int Align = -Subtarget.getStackAlignment().value();
+ BuildMI(MBB, It, DebugLoc(), get(Opc), ARM::SP)
+ .addReg(ARM::LR, RegState::Kill)
+ .addReg(ARM::SP)
+ .addImm(Align)
+ .add(predOps(ARMCC::AL));
+}
+
+void ARMBaseInstrInfo::emitCFIForLRSaveOnStack(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator It) const {
+ MachineFunction &MF = *MBB.getParent();
+ const MCRegisterInfo *MRI = Subtarget.getRegisterInfo();
+ unsigned DwarfLR = MRI->getDwarfRegNum(ARM::LR, true);
+ int Align = Subtarget.getStackAlignment().value();
+ // Add a CFI saying the stack was moved down.
+ int64_t StackPosEntry =
+ MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, Align));
+ BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
+ .addCFIIndex(StackPosEntry)
+ .setMIFlags(MachineInstr::FrameSetup);
+
+ // Add a CFI saying that the LR that we want to find is now higher than
+ // before.
+ int64_t LRPosEntry =
+ MF.addFrameInst(MCCFIInstruction::createOffset(nullptr, DwarfLR, -Align));
+ BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
+ .addCFIIndex(LRPosEntry)
+ .setMIFlags(MachineInstr::FrameSetup);
+}
+
+void ARMBaseInstrInfo::emitCFIForLRSaveToReg(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator It,
+ Register Reg) const {
+ MachineFunction &MF = *MBB.getParent();
+ const MCRegisterInfo *MRI = Subtarget.getRegisterInfo();
+ unsigned DwarfLR = MRI->getDwarfRegNum(ARM::LR, true);
+ unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
+
+ int64_t LRPosEntry = MF.addFrameInst(
+ MCCFIInstruction::createRegister(nullptr, DwarfLR, DwarfReg));
+ BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
+ .addCFIIndex(LRPosEntry)
+ .setMIFlags(MachineInstr::FrameSetup);
+}
+
+void ARMBaseInstrInfo::restoreLRFromStack(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator It) const {
+ unsigned Opc = Subtarget.isThumb() ? ARM::t2LDR_POST : ARM::LDR_POST_IMM;
+ MachineInstrBuilder MIB = BuildMI(MBB, It, DebugLoc(), get(Opc), ARM::LR)
+ .addReg(ARM::SP, RegState::Define)
+ .addReg(ARM::SP);
+ if (!Subtarget.isThumb())
+ MIB.addReg(0);
+ MIB.addImm(Subtarget.getStackAlignment().value()).add(predOps(ARMCC::AL));
+}
+
+void ARMBaseInstrInfo::emitCFIForLRRestoreFromStack(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator It) const {
+ // Now stack has moved back up...
+ MachineFunction &MF = *MBB.getParent();
+ const MCRegisterInfo *MRI = Subtarget.getRegisterInfo();
+ unsigned DwarfLR = MRI->getDwarfRegNum(ARM::LR, true);
+ int64_t StackPosEntry =
+ MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, 0));
+ BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
+ .addCFIIndex(StackPosEntry)
+ .setMIFlags(MachineInstr::FrameDestroy);
+
+ // ... and we have restored LR.
+ int64_t LRPosEntry =
+ MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, DwarfLR));
+ BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
+ .addCFIIndex(LRPosEntry)
+ .setMIFlags(MachineInstr::FrameDestroy);
+}
+
+void ARMBaseInstrInfo::emitCFIForLRRestoreFromReg(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator It) const {
+ MachineFunction &MF = *MBB.getParent();
+ const MCRegisterInfo *MRI = Subtarget.getRegisterInfo();
+ unsigned DwarfLR = MRI->getDwarfRegNum(ARM::LR, true);
+
+ int64_t LRPosEntry =
+ MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, DwarfLR));
+ BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
+ .addCFIIndex(LRPosEntry)
+ .setMIFlags(MachineInstr::FrameDestroy);
+}
+
void ARMBaseInstrInfo::buildOutlinedFrame(
MachineBasicBlock &MBB, MachineFunction &MF,
const outliner::OutlinedFunction &OF) const {
@@ -6374,57 +6374,57 @@ void ARMBaseInstrInfo::buildOutlinedFrame(
Call->eraseFromParent();
}
- // Is there a call in the outlined range?
- auto IsNonTailCall = [](MachineInstr &MI) {
- return MI.isCall() && !MI.isReturn();
- };
- if (llvm::any_of(MBB.instrs(), IsNonTailCall)) {
- MachineBasicBlock::iterator It = MBB.begin();
- MachineBasicBlock::iterator Et = MBB.end();
-
- if (OF.FrameConstructionID == MachineOutlinerTailCall ||
- OF.FrameConstructionID == MachineOutlinerThunk)
- Et = std::prev(MBB.end());
-
- // We have to save and restore LR, we need to add it to the liveins if it
- // is not already part of the set. This is suffient since outlined
- // functions only have one block.
- if (!MBB.isLiveIn(ARM::LR))
- MBB.addLiveIn(ARM::LR);
-
- // Insert a save before the outlined region
- saveLROnStack(MBB, It);
- emitCFIForLRSaveOnStack(MBB, It);
-
- // Fix up the instructions in the range, since we're going to modify the
- // stack.
- assert(OF.FrameConstructionID != MachineOutlinerDefault &&
- "Can only fix up stack references once");
- fixupPostOutline(MBB);
-
- // Insert a restore before the terminator for the function. Restore LR.
- restoreLRFromStack(MBB, Et);
- emitCFIForLRRestoreFromStack(MBB, Et);
- }
-
- // If this is a tail call outlined function, then there's already a return.
- if (OF.FrameConstructionID == MachineOutlinerTailCall ||
- OF.FrameConstructionID == MachineOutlinerThunk)
- return;
-
+ // Is there a call in the outlined range?
+ auto IsNonTailCall = [](MachineInstr &MI) {
+ return MI.isCall() && !MI.isReturn();
+ };
+ if (llvm::any_of(MBB.instrs(), IsNonTailCall)) {
+ MachineBasicBlock::iterator It = MBB.begin();
+ MachineBasicBlock::iterator Et = MBB.end();
+
+ if (OF.FrameConstructionID == MachineOutlinerTailCall ||
+ OF.FrameConstructionID == MachineOutlinerThunk)
+ Et = std::prev(MBB.end());
+
+ // We have to save and restore LR, we need to add it to the liveins if it
+ // is not already part of the set. This is suffient since outlined
+ // functions only have one block.
+ if (!MBB.isLiveIn(ARM::LR))
+ MBB.addLiveIn(ARM::LR);
+
+ // Insert a save before the outlined region
+ saveLROnStack(MBB, It);
+ emitCFIForLRSaveOnStack(MBB, It);
+
+ // Fix up the instructions in the range, since we're going to modify the
+ // stack.
+ assert(OF.FrameConstructionID != MachineOutlinerDefault &&
+ "Can only fix up stack references once");
+ fixupPostOutline(MBB);
+
+ // Insert a restore before the terminator for the function. Restore LR.
+ restoreLRFromStack(MBB, Et);
+ emitCFIForLRRestoreFromStack(MBB, Et);
+ }
+
+ // If this is a tail call outlined function, then there's already a return.
+ if (OF.FrameConstructionID == MachineOutlinerTailCall ||
+ OF.FrameConstructionID == MachineOutlinerThunk)
+ return;
+
// Here we have to insert the return ourselves. Get the correct opcode from
// current feature set.
BuildMI(MBB, MBB.end(), DebugLoc(), get(Subtarget.getReturnOpcode()))
.add(predOps(ARMCC::AL));
-
- // Did we have to modify the stack by saving the link register?
- if (OF.FrameConstructionID != MachineOutlinerDefault &&
- OF.Candidates[0].CallConstructionID != MachineOutlinerDefault)
- return;
-
- // We modified the stack.
- // Walk over the basic block and fix up all the stack accesses.
- fixupPostOutline(MBB);
+
+ // Did we have to modify the stack by saving the link register?
+ if (OF.FrameConstructionID != MachineOutlinerDefault &&
+ OF.Candidates[0].CallConstructionID != MachineOutlinerDefault)
+ return;
+
+ // We modified the stack.
+ // Walk over the basic block and fix up all the stack accesses.
+ fixupPostOutline(MBB);
}
MachineBasicBlock::iterator ARMBaseInstrInfo::insertOutlinedCall(
@@ -6456,14 +6456,14 @@ MachineBasicBlock::iterator ARMBaseInstrInfo::insertOutlinedCall(
CallMIB.add(predOps(ARMCC::AL));
CallMIB.addGlobalAddress(M.getNamedValue(MF.getName()));
- if (C.CallConstructionID == MachineOutlinerNoLRSave ||
- C.CallConstructionID == MachineOutlinerThunk) {
- // No, so just insert the call.
- It = MBB.insert(It, CallMIB);
- return It;
- }
-
- const ARMFunctionInfo &AFI = *C.getMF()->getInfo<ARMFunctionInfo>();
+ if (C.CallConstructionID == MachineOutlinerNoLRSave ||
+ C.CallConstructionID == MachineOutlinerThunk) {
+ // No, so just insert the call.
+ It = MBB.insert(It, CallMIB);
+ return It;
+ }
+
+ const ARMFunctionInfo &AFI = *C.getMF()->getInfo<ARMFunctionInfo>();
// Can we save to a register?
if (C.CallConstructionID == MachineOutlinerRegSave) {
unsigned Reg = findRegisterToSaveLRTo(C);
@@ -6471,55 +6471,55 @@ MachineBasicBlock::iterator ARMBaseInstrInfo::insertOutlinedCall(
// Save and restore LR from that register.
copyPhysReg(MBB, It, DebugLoc(), Reg, ARM::LR, true);
- if (!AFI.isLRSpilled())
- emitCFIForLRSaveToReg(MBB, It, Reg);
+ if (!AFI.isLRSpilled())
+ emitCFIForLRSaveToReg(MBB, It, Reg);
CallPt = MBB.insert(It, CallMIB);
copyPhysReg(MBB, It, DebugLoc(), ARM::LR, Reg, true);
- if (!AFI.isLRSpilled())
- emitCFIForLRRestoreFromReg(MBB, It);
+ if (!AFI.isLRSpilled())
+ emitCFIForLRRestoreFromReg(MBB, It);
It--;
return CallPt;
}
- // We have the default case. Save and restore from SP.
- if (!MBB.isLiveIn(ARM::LR))
- MBB.addLiveIn(ARM::LR);
- saveLROnStack(MBB, It);
- if (!AFI.isLRSpilled())
- emitCFIForLRSaveOnStack(MBB, It);
- CallPt = MBB.insert(It, CallMIB);
- restoreLRFromStack(MBB, It);
- if (!AFI.isLRSpilled())
- emitCFIForLRRestoreFromStack(MBB, It);
- It--;
- return CallPt;
-}
-
-bool ARMBaseInstrInfo::shouldOutlineFromFunctionByDefault(
- MachineFunction &MF) const {
- return Subtarget.isMClass() && MF.getFunction().hasMinSize();
-}
-
-bool ARMBaseInstrInfo::isReallyTriviallyReMaterializable(const MachineInstr &MI,
- AAResults *AA) const {
- // Try hard to rematerialize any VCTPs because if we spill P0, it will block
- // the tail predication conversion. This means that the element count
- // register has to be live for longer, but that has to be better than
- // spill/restore and VPT predication.
- return isVCTP(&MI) && !isPredicated(MI);
-}
-
-unsigned llvm::getBLXOpcode(const MachineFunction &MF) {
- return (MF.getSubtarget<ARMSubtarget>().hardenSlsBlr()) ? ARM::BLX_noip
- : ARM::BLX;
-}
-
-unsigned llvm::gettBLXrOpcode(const MachineFunction &MF) {
- return (MF.getSubtarget<ARMSubtarget>().hardenSlsBlr()) ? ARM::tBLXr_noip
- : ARM::tBLXr;
-}
-
-unsigned llvm::getBLXpredOpcode(const MachineFunction &MF) {
- return (MF.getSubtarget<ARMSubtarget>().hardenSlsBlr()) ? ARM::BLX_pred_noip
- : ARM::BLX_pred;
-}
-
+ // We have the default case. Save and restore from SP.
+ if (!MBB.isLiveIn(ARM::LR))
+ MBB.addLiveIn(ARM::LR);
+ saveLROnStack(MBB, It);
+ if (!AFI.isLRSpilled())
+ emitCFIForLRSaveOnStack(MBB, It);
+ CallPt = MBB.insert(It, CallMIB);
+ restoreLRFromStack(MBB, It);
+ if (!AFI.isLRSpilled())
+ emitCFIForLRRestoreFromStack(MBB, It);
+ It--;
+ return CallPt;
+}
+
+bool ARMBaseInstrInfo::shouldOutlineFromFunctionByDefault(
+ MachineFunction &MF) const {
+ return Subtarget.isMClass() && MF.getFunction().hasMinSize();
+}
+
+bool ARMBaseInstrInfo::isReallyTriviallyReMaterializable(const MachineInstr &MI,
+ AAResults *AA) const {
+ // Try hard to rematerialize any VCTPs because if we spill P0, it will block
+ // the tail predication conversion. This means that the element count
+ // register has to be live for longer, but that has to be better than
+ // spill/restore and VPT predication.
+ return isVCTP(&MI) && !isPredicated(MI);
+}
+
+unsigned llvm::getBLXOpcode(const MachineFunction &MF) {
+ return (MF.getSubtarget<ARMSubtarget>().hardenSlsBlr()) ? ARM::BLX_noip
+ : ARM::BLX;
+}
+
+unsigned llvm::gettBLXrOpcode(const MachineFunction &MF) {
+ return (MF.getSubtarget<ARMSubtarget>().hardenSlsBlr()) ? ARM::tBLXr_noip
+ : ARM::tBLXr;
+}
+
+unsigned llvm::getBLXpredOpcode(const MachineFunction &MF) {
+ return (MF.getSubtarget<ARMSubtarget>().hardenSlsBlr()) ? ARM::BLX_pred_noip
+ : ARM::BLX_pred;
+}
+
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMBaseInstrInfo.h b/contrib/libs/llvm12/lib/Target/ARM/ARMBaseInstrInfo.h
index e61d557c1d..1b843c4281 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMBaseInstrInfo.h
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMBaseInstrInfo.h
@@ -132,10 +132,10 @@ public:
const ScheduleDAG *DAG) const override;
ScheduleHazardRecognizer *
- CreateTargetMIHazardRecognizer(const InstrItineraryData *II,
- const ScheduleDAGMI *DAG) const override;
-
- ScheduleHazardRecognizer *
+ CreateTargetMIHazardRecognizer(const InstrItineraryData *II,
+ const ScheduleDAGMI *DAG) const override;
+
+ ScheduleHazardRecognizer *
CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
const ScheduleDAG *DAG) const override;
@@ -175,8 +175,8 @@ public:
bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
ArrayRef<MachineOperand> Pred2) const override;
- bool ClobbersPredicate(MachineInstr &MI, std::vector<MachineOperand> &Pred,
- bool SkipDead) const override;
+ bool ClobbersPredicate(MachineInstr &MI, std::vector<MachineOperand> &Pred,
+ bool SkipDead) const override;
bool isPredicable(const MachineInstr &MI) const override;
@@ -361,60 +361,60 @@ public:
MachineBasicBlock::iterator &It, MachineFunction &MF,
const outliner::Candidate &C) const override;
- /// Enable outlining by default at -Oz.
- bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override;
-
- bool isUnspillableTerminatorImpl(const MachineInstr *MI) const override {
- return MI->getOpcode() == ARM::t2LoopEndDec ||
- MI->getOpcode() == ARM::t2DoLoopStartTP;
- }
-
+ /// Enable outlining by default at -Oz.
+ bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override;
+
+ bool isUnspillableTerminatorImpl(const MachineInstr *MI) const override {
+ return MI->getOpcode() == ARM::t2LoopEndDec ||
+ MI->getOpcode() == ARM::t2DoLoopStartTP;
+ }
+
private:
/// Returns an unused general-purpose register which can be used for
/// constructing an outlined call if one exists. Returns 0 otherwise.
unsigned findRegisterToSaveLRTo(const outliner::Candidate &C) const;
- // Adds an instruction which saves the link register on top of the stack into
- /// the MachineBasicBlock \p MBB at position \p It.
- void saveLROnStack(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator It) const;
-
- /// Adds an instruction which restores the link register from the top the
- /// stack into the MachineBasicBlock \p MBB at position \p It.
- void restoreLRFromStack(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator It) const;
-
- /// Emit CFI instructions into the MachineBasicBlock \p MBB at position \p It,
- /// for the case when the LR is saved on the stack.
- void emitCFIForLRSaveOnStack(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator It) const;
-
- /// Emit CFI instructions into the MachineBasicBlock \p MBB at position \p It,
- /// for the case when the LR is saved in the register \p Reg.
- void emitCFIForLRSaveToReg(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator It,
- Register Reg) const;
-
- /// Emit CFI instructions into the MachineBasicBlock \p MBB at position \p It,
- /// after the LR is was restored from the stack.
- void emitCFIForLRRestoreFromStack(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator It) const;
-
- /// Emit CFI instructions into the MachineBasicBlock \p MBB at position \p It,
- /// after the LR is was restored from a register.
- void emitCFIForLRRestoreFromReg(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator It) const;
- /// \brief Sets the offsets on outlined instructions in \p MBB which use SP
- /// so that they will be valid post-outlining.
- ///
- /// \param MBB A \p MachineBasicBlock in an outlined function.
- void fixupPostOutline(MachineBasicBlock &MBB) const;
-
- /// Returns true if the machine instruction offset can handle the stack fixup
- /// and updates it if requested.
- bool checkAndUpdateStackOffset(MachineInstr *MI, int64_t Fixup,
- bool Updt) const;
-
+ // Adds an instruction which saves the link register on top of the stack into
+ /// the MachineBasicBlock \p MBB at position \p It.
+ void saveLROnStack(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator It) const;
+
+ /// Adds an instruction which restores the link register from the top the
+ /// stack into the MachineBasicBlock \p MBB at position \p It.
+ void restoreLRFromStack(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator It) const;
+
+ /// Emit CFI instructions into the MachineBasicBlock \p MBB at position \p It,
+ /// for the case when the LR is saved on the stack.
+ void emitCFIForLRSaveOnStack(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator It) const;
+
+ /// Emit CFI instructions into the MachineBasicBlock \p MBB at position \p It,
+ /// for the case when the LR is saved in the register \p Reg.
+ void emitCFIForLRSaveToReg(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator It,
+ Register Reg) const;
+
+ /// Emit CFI instructions into the MachineBasicBlock \p MBB at position \p It,
+ /// after the LR is was restored from the stack.
+ void emitCFIForLRRestoreFromStack(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator It) const;
+
+ /// Emit CFI instructions into the MachineBasicBlock \p MBB at position \p It,
+ /// after the LR is was restored from a register.
+ void emitCFIForLRRestoreFromReg(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator It) const;
+ /// \brief Sets the offsets on outlined instructions in \p MBB which use SP
+ /// so that they will be valid post-outlining.
+ ///
+ /// \param MBB A \p MachineBasicBlock in an outlined function.
+ void fixupPostOutline(MachineBasicBlock &MBB) const;
+
+ /// Returns true if the machine instruction offset can handle the stack fixup
+ /// and updates it if requested.
+ bool checkAndUpdateStackOffset(MachineInstr *MI, int64_t Fixup,
+ bool Updt) const;
+
unsigned getInstBundleLength(const MachineInstr &MI) const;
int getVLDMDefCycle(const InstrItineraryData *ItinData,
@@ -477,9 +477,9 @@ private:
MachineInstr *canFoldIntoMOVCC(Register Reg, const MachineRegisterInfo &MRI,
const TargetInstrInfo *TII) const;
- bool isReallyTriviallyReMaterializable(const MachineInstr &MI,
- AAResults *AA) const override;
-
+ bool isReallyTriviallyReMaterializable(const MachineInstr &MI,
+ AAResults *AA) const override;
+
private:
/// Modeling special VFP / NEON fp MLA / MLS hazards.
@@ -644,77 +644,77 @@ static inline bool isJumpTableBranchOpcode(int Opc) {
Opc == ARM::t2BR_JT;
}
-static inline bool isLowOverheadTerminatorOpcode(int Opc) {
- return Opc == ARM::t2DoLoopStartTP || Opc == ARM::t2WhileLoopStart ||
- Opc == ARM::t2LoopEnd || Opc == ARM::t2LoopEndDec;
-}
-
+static inline bool isLowOverheadTerminatorOpcode(int Opc) {
+ return Opc == ARM::t2DoLoopStartTP || Opc == ARM::t2WhileLoopStart ||
+ Opc == ARM::t2LoopEnd || Opc == ARM::t2LoopEndDec;
+}
+
static inline
bool isIndirectBranchOpcode(int Opc) {
return Opc == ARM::BX || Opc == ARM::MOVPCRX || Opc == ARM::tBRIND;
}
-static inline bool isIndirectCall(const MachineInstr &MI) {
- int Opc = MI.getOpcode();
- switch (Opc) {
- // indirect calls:
- case ARM::BLX:
- case ARM::BLX_noip:
- case ARM::BLX_pred:
- case ARM::BLX_pred_noip:
- case ARM::BX_CALL:
- case ARM::BMOVPCRX_CALL:
- case ARM::TCRETURNri:
- case ARM::TAILJMPr:
- case ARM::TAILJMPr4:
- case ARM::tBLXr:
- case ARM::tBLXr_noip:
- case ARM::tBLXNSr:
- case ARM::tBLXNS_CALL:
- case ARM::tBX_CALL:
- case ARM::tTAILJMPr:
- assert(MI.isCall(MachineInstr::IgnoreBundle));
- return true;
- // direct calls:
- case ARM::BL:
- case ARM::BL_pred:
- case ARM::BMOVPCB_CALL:
- case ARM::BL_PUSHLR:
- case ARM::BLXi:
- case ARM::TCRETURNdi:
- case ARM::TAILJMPd:
- case ARM::SVC:
- case ARM::HVC:
- case ARM::TPsoft:
- case ARM::tTAILJMPd:
- case ARM::t2SMC:
- case ARM::t2HVC:
- case ARM::tBL:
- case ARM::tBLXi:
- case ARM::tBL_PUSHLR:
- case ARM::tTAILJMPdND:
- case ARM::tSVC:
- case ARM::tTPsoft:
- assert(MI.isCall(MachineInstr::IgnoreBundle));
- return false;
- }
- assert(!MI.isCall(MachineInstr::IgnoreBundle));
- return false;
-}
-
-static inline bool isIndirectControlFlowNotComingBack(const MachineInstr &MI) {
- int opc = MI.getOpcode();
- return MI.isReturn() || isIndirectBranchOpcode(MI.getOpcode()) ||
- isJumpTableBranchOpcode(opc);
-}
-
-static inline bool isSpeculationBarrierEndBBOpcode(int Opc) {
- return Opc == ARM::SpeculationBarrierISBDSBEndBB ||
- Opc == ARM::SpeculationBarrierSBEndBB ||
- Opc == ARM::t2SpeculationBarrierISBDSBEndBB ||
- Opc == ARM::t2SpeculationBarrierSBEndBB;
-}
-
+static inline bool isIndirectCall(const MachineInstr &MI) {
+ int Opc = MI.getOpcode();
+ switch (Opc) {
+ // indirect calls:
+ case ARM::BLX:
+ case ARM::BLX_noip:
+ case ARM::BLX_pred:
+ case ARM::BLX_pred_noip:
+ case ARM::BX_CALL:
+ case ARM::BMOVPCRX_CALL:
+ case ARM::TCRETURNri:
+ case ARM::TAILJMPr:
+ case ARM::TAILJMPr4:
+ case ARM::tBLXr:
+ case ARM::tBLXr_noip:
+ case ARM::tBLXNSr:
+ case ARM::tBLXNS_CALL:
+ case ARM::tBX_CALL:
+ case ARM::tTAILJMPr:
+ assert(MI.isCall(MachineInstr::IgnoreBundle));
+ return true;
+ // direct calls:
+ case ARM::BL:
+ case ARM::BL_pred:
+ case ARM::BMOVPCB_CALL:
+ case ARM::BL_PUSHLR:
+ case ARM::BLXi:
+ case ARM::TCRETURNdi:
+ case ARM::TAILJMPd:
+ case ARM::SVC:
+ case ARM::HVC:
+ case ARM::TPsoft:
+ case ARM::tTAILJMPd:
+ case ARM::t2SMC:
+ case ARM::t2HVC:
+ case ARM::tBL:
+ case ARM::tBLXi:
+ case ARM::tBL_PUSHLR:
+ case ARM::tTAILJMPdND:
+ case ARM::tSVC:
+ case ARM::tTPsoft:
+ assert(MI.isCall(MachineInstr::IgnoreBundle));
+ return false;
+ }
+ assert(!MI.isCall(MachineInstr::IgnoreBundle));
+ return false;
+}
+
+static inline bool isIndirectControlFlowNotComingBack(const MachineInstr &MI) {
+ int opc = MI.getOpcode();
+ return MI.isReturn() || isIndirectBranchOpcode(MI.getOpcode()) ||
+ isJumpTableBranchOpcode(opc);
+}
+
+static inline bool isSpeculationBarrierEndBBOpcode(int Opc) {
+ return Opc == ARM::SpeculationBarrierISBDSBEndBB ||
+ Opc == ARM::SpeculationBarrierSBEndBB ||
+ Opc == ARM::t2SpeculationBarrierISBDSBEndBB ||
+ Opc == ARM::t2SpeculationBarrierSBEndBB;
+}
+
static inline bool isPopOpcode(int Opc) {
return Opc == ARM::tPOP_RET || Opc == ARM::LDMIA_RET ||
Opc == ARM::t2LDMIA_RET || Opc == ARM::tPOP || Opc == ARM::LDMIA_UPD ||
@@ -886,17 +886,17 @@ inline bool isLegalAddressImm(unsigned Opcode, int Imm,
return std::abs(Imm) < (((1 << 7) * 2) - 1) && Imm % 2 == 0;
case ARMII::AddrModeT2_i7s4:
return std::abs(Imm) < (((1 << 7) * 4) - 1) && Imm % 4 == 0;
- case ARMII::AddrModeT2_i8:
- return std::abs(Imm) < (((1 << 8) * 1) - 1);
- case ARMII::AddrModeT2_i12:
- return Imm >= 0 && Imm < (((1 << 12) * 1) - 1);
+ case ARMII::AddrModeT2_i8:
+ return std::abs(Imm) < (((1 << 8) * 1) - 1);
+ case ARMII::AddrModeT2_i12:
+ return Imm >= 0 && Imm < (((1 << 12) * 1) - 1);
default:
llvm_unreachable("Unhandled Addressing mode");
}
}
-// Return true if the given intrinsic is a gather
-inline bool isGather(IntrinsicInst *IntInst) {
+// Return true if the given intrinsic is a gather
+inline bool isGather(IntrinsicInst *IntInst) {
if (IntInst == nullptr)
return false;
unsigned IntrinsicID = IntInst->getIntrinsicID();
@@ -906,15 +906,15 @@ inline bool isGather(IntrinsicInst *IntInst) {
IntrinsicID == Intrinsic::arm_mve_vldr_gather_base_wb ||
IntrinsicID == Intrinsic::arm_mve_vldr_gather_base_wb_predicated ||
IntrinsicID == Intrinsic::arm_mve_vldr_gather_offset ||
- IntrinsicID == Intrinsic::arm_mve_vldr_gather_offset_predicated);
-}
-
-// Return true if the given intrinsic is a scatter
-inline bool isScatter(IntrinsicInst *IntInst) {
- if (IntInst == nullptr)
- return false;
- unsigned IntrinsicID = IntInst->getIntrinsicID();
- return (IntrinsicID == Intrinsic::masked_scatter ||
+ IntrinsicID == Intrinsic::arm_mve_vldr_gather_offset_predicated);
+}
+
+// Return true if the given intrinsic is a scatter
+inline bool isScatter(IntrinsicInst *IntInst) {
+ if (IntInst == nullptr)
+ return false;
+ unsigned IntrinsicID = IntInst->getIntrinsicID();
+ return (IntrinsicID == Intrinsic::masked_scatter ||
IntrinsicID == Intrinsic::arm_mve_vstr_scatter_base ||
IntrinsicID == Intrinsic::arm_mve_vstr_scatter_base_predicated ||
IntrinsicID == Intrinsic::arm_mve_vstr_scatter_base_wb ||
@@ -923,17 +923,17 @@ inline bool isScatter(IntrinsicInst *IntInst) {
IntrinsicID == Intrinsic::arm_mve_vstr_scatter_offset_predicated);
}
-// Return true if the given intrinsic is a gather or scatter
-inline bool isGatherScatter(IntrinsicInst *IntInst) {
- if (IntInst == nullptr)
- return false;
- return isGather(IntInst) || isScatter(IntInst);
-}
-
-unsigned getBLXOpcode(const MachineFunction &MF);
-unsigned gettBLXrOpcode(const MachineFunction &MF);
-unsigned getBLXpredOpcode(const MachineFunction &MF);
-
+// Return true if the given intrinsic is a gather or scatter
+inline bool isGatherScatter(IntrinsicInst *IntInst) {
+ if (IntInst == nullptr)
+ return false;
+ return isGather(IntInst) || isScatter(IntInst);
+}
+
+unsigned getBLXOpcode(const MachineFunction &MF);
+unsigned gettBLXrOpcode(const MachineFunction &MF);
+unsigned getBLXpredOpcode(const MachineFunction &MF);
+
} // end namespace llvm
#endif // LLVM_LIB_TARGET_ARM_ARMBASEINSTRINFO_H
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index 138431e36d..1a264dabee 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -55,9 +55,9 @@
using namespace llvm;
ARMBaseRegisterInfo::ARMBaseRegisterInfo()
- : ARMGenRegisterInfo(ARM::LR, 0, 0, ARM::PC) {
- ARM_MC::initLLVMToCVRegMapping(this);
-}
+ : ARMGenRegisterInfo(ARM::LR, 0, 0, ARM::PC) {
+ ARM_MC::initLLVMToCVRegMapping(this);
+}
static unsigned getFramePointerReg(const ARMSubtarget &STI) {
return STI.useR7AsFramePointer() ? ARM::R7 : ARM::R11;
@@ -330,13 +330,13 @@ bool ARMBaseRegisterInfo::getRegAllocationHints(
case ARMRI::RegPairOdd:
Odd = 1;
break;
- case ARMRI::RegLR:
+ case ARMRI::RegLR:
TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF, VRM);
- if (MRI.getRegClass(VirtReg)->contains(ARM::LR))
- Hints.push_back(ARM::LR);
+ if (MRI.getRegClass(VirtReg)->contains(ARM::LR))
+ Hints.push_back(ARM::LR);
return false;
- default:
- return TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF, VRM);
+ default:
+ return TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF, VRM);
}
// This register should preferably be even (Odd == 0) or odd (Odd == 1).
@@ -640,10 +640,10 @@ needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const {
/// materializeFrameBaseRegister - Insert defining instruction(s) for BaseReg to
/// be a pointer to FrameIdx at the beginning of the basic block.
-Register
-ARMBaseRegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,
- int FrameIdx,
- int64_t Offset) const {
+Register
+ARMBaseRegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,
+ int FrameIdx,
+ int64_t Offset) const {
ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>();
unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri :
(AFI->isThumb1OnlyFunction() ? ARM::tADDframe : ARM::t2ADDri);
@@ -657,7 +657,7 @@ ARMBaseRegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,
MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
const MCInstrDesc &MCID = TII.get(ADDriOpc);
- Register BaseReg = MRI.createVirtualRegister(&ARM::GPRRegClass);
+ Register BaseReg = MRI.createVirtualRegister(&ARM::GPRRegClass);
MRI.constrainRegClass(BaseReg, TII.getRegClass(MCID, 0, this, MF));
MachineInstrBuilder MIB = BuildMI(*MBB, Ins, DL, MCID, BaseReg)
@@ -665,8 +665,8 @@ ARMBaseRegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,
if (!AFI->isThumb1OnlyFunction())
MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
-
- return BaseReg;
+
+ return BaseReg;
}
void ARMBaseRegisterInfo::resolveFrameIndex(MachineInstr &MI, Register BaseReg,
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMBaseRegisterInfo.h b/contrib/libs/llvm12/lib/Target/ARM/ARMBaseRegisterInfo.h
index 53e8aa657c..5afb6c6aa0 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMBaseRegisterInfo.h
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMBaseRegisterInfo.h
@@ -32,11 +32,11 @@ class LiveIntervals;
namespace ARMRI {
enum {
- // Used for LDRD register pairs
+ // Used for LDRD register pairs
RegPairOdd = 1,
- RegPairEven = 2,
- // Used to hint for lr in t2DoLoopStart
- RegLR = 3
+ RegPairEven = 2,
+ // Used to hint for lr in t2DoLoopStart
+ RegLR = 3
};
} // end namespace ARMRI
@@ -168,8 +168,8 @@ public:
int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
int Idx) const override;
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
- Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx,
- int64_t Offset) const override;
+ Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx,
+ int64_t Offset) const override;
void resolveFrameIndex(MachineInstr &MI, Register BaseReg,
int64_t Offset) const override;
bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg,
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMBlockPlacement.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMBlockPlacement.cpp
index 2cc6a5b4c1..9ba16003a9 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMBlockPlacement.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMBlockPlacement.cpp
@@ -1,228 +1,228 @@
-//===-- ARMBlockPlacement.cpp - ARM block placement pass ------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass re-arranges machine basic blocks to suit target requirements.
-// Currently it only moves blocks to fix backwards WLS branches.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ARM.h"
-#include "ARMBaseInstrInfo.h"
-#include "ARMBasicBlockInfo.h"
-#include "ARMSubtarget.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineLoopInfo.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "arm-block-placement"
-#define DEBUG_PREFIX "ARM Block Placement: "
-
-namespace llvm {
-class ARMBlockPlacement : public MachineFunctionPass {
-private:
- const ARMBaseInstrInfo *TII;
- std::unique_ptr<ARMBasicBlockUtils> BBUtils = nullptr;
- MachineLoopInfo *MLI = nullptr;
-
-public:
- static char ID;
- ARMBlockPlacement() : MachineFunctionPass(ID) {}
-
- bool runOnMachineFunction(MachineFunction &MF) override;
- void moveBasicBlock(MachineBasicBlock *BB, MachineBasicBlock *After);
- bool blockIsBefore(MachineBasicBlock *BB, MachineBasicBlock *Other);
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesCFG();
- AU.addRequired<MachineLoopInfo>();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
-};
-
-} // namespace llvm
-
-FunctionPass *llvm::createARMBlockPlacementPass() {
- return new ARMBlockPlacement();
-}
-
-char ARMBlockPlacement::ID = 0;
-
-INITIALIZE_PASS(ARMBlockPlacement, DEBUG_TYPE, "ARM block placement", false,
- false)
-
-bool ARMBlockPlacement::runOnMachineFunction(MachineFunction &MF) {
- if (skipFunction(MF.getFunction()))
- return false;
- const ARMSubtarget &ST = static_cast<const ARMSubtarget &>(MF.getSubtarget());
- if (!ST.hasLOB())
- return false;
- LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "Running on " << MF.getName() << "\n");
- MLI = &getAnalysis<MachineLoopInfo>();
- TII = static_cast<const ARMBaseInstrInfo *>(ST.getInstrInfo());
- BBUtils = std::unique_ptr<ARMBasicBlockUtils>(new ARMBasicBlockUtils(MF));
- MF.RenumberBlocks();
- BBUtils->computeAllBlockSizes();
- BBUtils->adjustBBOffsetsAfter(&MF.front());
- bool Changed = false;
-
- // Find loops with a backwards branching WLS.
- // This requires looping over the loops in the function, checking each
- // preheader for a WLS and if its target is before the preheader. If moving
- // the target block wouldn't produce another backwards WLS or a new forwards
- // LE branch then move the target block after the preheader.
- for (auto *ML : *MLI) {
- MachineBasicBlock *Preheader = ML->getLoopPredecessor();
- if (!Preheader)
- continue;
-
- for (auto &Terminator : Preheader->terminators()) {
- if (Terminator.getOpcode() != ARM::t2WhileLoopStart)
- continue;
- MachineBasicBlock *LoopExit = Terminator.getOperand(1).getMBB();
- // We don't want to move the function's entry block.
- if (!LoopExit->getPrevNode())
- continue;
- if (blockIsBefore(Preheader, LoopExit))
- continue;
- LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "Found a backwards WLS from "
- << Preheader->getFullName() << " to "
- << LoopExit->getFullName() << "\n");
-
- // Make sure that moving the target block doesn't cause any of its WLSs
- // that were previously not backwards to become backwards
- bool CanMove = true;
- for (auto &LoopExitTerminator : LoopExit->terminators()) {
- if (LoopExitTerminator.getOpcode() != ARM::t2WhileLoopStart)
- continue;
- // An example loop structure where the LoopExit can't be moved, since
- // bb1's WLS will become backwards once it's moved after bb3 bb1: -
- // LoopExit
- // WLS bb2 - LoopExit2
- // bb2:
- // ...
- // bb3: - Preheader
- // WLS bb1
- // bb4: - Header
- MachineBasicBlock *LoopExit2 =
- LoopExitTerminator.getOperand(1).getMBB();
- // If the WLS from LoopExit to LoopExit2 is already backwards then
- // moving LoopExit won't affect it, so it can be moved. If LoopExit2 is
- // after the Preheader then moving will keep it as a forward branch, so
- // it can be moved. If LoopExit2 is between the Preheader and LoopExit
- // then moving LoopExit will make it a backwards branch, so it can't be
- // moved since we'd fix one and introduce one backwards branch.
- // TODO: Analyse the blocks to make a decision if it would be worth
- // moving LoopExit even if LoopExit2 is between the Preheader and
- // LoopExit.
- if (!blockIsBefore(LoopExit2, LoopExit) &&
- (LoopExit2 == Preheader || blockIsBefore(LoopExit2, Preheader))) {
- LLVM_DEBUG(dbgs() << DEBUG_PREFIX
- << "Can't move the target block as it would "
- "introduce a new backwards WLS branch\n");
- CanMove = false;
- break;
- }
- }
-
- if (CanMove) {
- // Make sure no LEs become forwards.
- // An example loop structure where the LoopExit can't be moved, since
- // bb2's LE will become forwards once bb1 is moved after bb3.
- // bb1: - LoopExit
- // bb2:
- // LE bb1 - Terminator
- // bb3: - Preheader
- // WLS bb1
- // bb4: - Header
- for (auto It = LoopExit->getIterator(); It != Preheader->getIterator();
- It++) {
- MachineBasicBlock *MBB = &*It;
- for (auto &Terminator : MBB->terminators()) {
- if (Terminator.getOpcode() != ARM::t2LoopEndDec)
- continue;
- MachineBasicBlock *LETarget = Terminator.getOperand(2).getMBB();
- // The LE will become forwards branching if it branches to LoopExit
- // which isn't allowed by the architecture, so we should avoid
- // introducing these.
- // TODO: Analyse the blocks to make a decision if it would be worth
- // moving LoopExit even if we'd introduce a forwards LE
- if (LETarget == LoopExit) {
- LLVM_DEBUG(dbgs() << DEBUG_PREFIX
- << "Can't move the target block as it would "
- "introduce a new forwards LE branch\n");
- CanMove = false;
- break;
- }
- }
- }
-
- if (!CanMove)
- break;
- }
-
- if (CanMove) {
- moveBasicBlock(LoopExit, Preheader);
- Changed = true;
- break;
- }
- }
- }
-
- return Changed;
-}
-
-bool ARMBlockPlacement::blockIsBefore(MachineBasicBlock *BB,
- MachineBasicBlock *Other) {
- return BBUtils->getOffsetOf(Other) > BBUtils->getOffsetOf(BB);
-}
-
-void ARMBlockPlacement::moveBasicBlock(MachineBasicBlock *BB,
- MachineBasicBlock *After) {
- LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "Moving " << BB->getName() << " after "
- << After->getName() << "\n");
- MachineBasicBlock *BBPrevious = BB->getPrevNode();
- assert(BBPrevious && "Cannot move the function entry basic block");
- MachineBasicBlock *AfterNext = After->getNextNode();
- MachineBasicBlock *BBNext = BB->getNextNode();
-
- BB->moveAfter(After);
-
- auto FixFallthrough = [&](MachineBasicBlock *From, MachineBasicBlock *To) {
- LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "Checking for fallthrough from "
- << From->getName() << " to " << To->getName() << "\n");
- assert(From->isSuccessor(To) &&
- "'To' is expected to be a successor of 'From'");
- MachineInstr &Terminator = *(--From->terminators().end());
- if (!Terminator.isUnconditionalBranch()) {
- // The BB doesn't have an unconditional branch so it relied on
- // fall-through. Fix by adding an unconditional branch to the moved BB.
- MachineInstrBuilder MIB =
- BuildMI(From, Terminator.getDebugLoc(), TII->get(ARM::t2B));
- MIB.addMBB(To);
- MIB.addImm(ARMCC::CondCodes::AL);
- MIB.addReg(ARM::NoRegister);
- LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "Adding unconditional branch from "
- << From->getName() << " to " << To->getName() << ": "
- << *MIB.getInstr());
- }
- };
-
- // Fix fall-through to the moved BB from the one that used to be before it.
- if (BBPrevious->isSuccessor(BB))
- FixFallthrough(BBPrevious, BB);
- // Fix fall through from the destination BB to the one that used to follow.
- if (AfterNext && After->isSuccessor(AfterNext))
- FixFallthrough(After, AfterNext);
- // Fix fall through from the moved BB to the one that used to follow.
- if (BBNext && BB->isSuccessor(BBNext))
- FixFallthrough(BB, BBNext);
-
- BBUtils->adjustBBOffsetsAfter(After);
-}
+//===-- ARMBlockPlacement.cpp - ARM block placement pass ------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass re-arranges machine basic blocks to suit target requirements.
+// Currently it only moves blocks to fix backwards WLS branches.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ARM.h"
+#include "ARMBaseInstrInfo.h"
+#include "ARMBasicBlockInfo.h"
+#include "ARMSubtarget.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineLoopInfo.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "arm-block-placement"
+#define DEBUG_PREFIX "ARM Block Placement: "
+
+namespace llvm {
+class ARMBlockPlacement : public MachineFunctionPass {
+private:
+ const ARMBaseInstrInfo *TII;
+ std::unique_ptr<ARMBasicBlockUtils> BBUtils = nullptr;
+ MachineLoopInfo *MLI = nullptr;
+
+public:
+ static char ID;
+ ARMBlockPlacement() : MachineFunctionPass(ID) {}
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+ void moveBasicBlock(MachineBasicBlock *BB, MachineBasicBlock *After);
+ bool blockIsBefore(MachineBasicBlock *BB, MachineBasicBlock *Other);
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesCFG();
+ AU.addRequired<MachineLoopInfo>();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+};
+
+} // namespace llvm
+
+FunctionPass *llvm::createARMBlockPlacementPass() {
+ return new ARMBlockPlacement();
+}
+
+char ARMBlockPlacement::ID = 0;
+
+INITIALIZE_PASS(ARMBlockPlacement, DEBUG_TYPE, "ARM block placement", false,
+ false)
+
+bool ARMBlockPlacement::runOnMachineFunction(MachineFunction &MF) {
+ if (skipFunction(MF.getFunction()))
+ return false;
+ const ARMSubtarget &ST = static_cast<const ARMSubtarget &>(MF.getSubtarget());
+ if (!ST.hasLOB())
+ return false;
+ LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "Running on " << MF.getName() << "\n");
+ MLI = &getAnalysis<MachineLoopInfo>();
+ TII = static_cast<const ARMBaseInstrInfo *>(ST.getInstrInfo());
+ BBUtils = std::unique_ptr<ARMBasicBlockUtils>(new ARMBasicBlockUtils(MF));
+ MF.RenumberBlocks();
+ BBUtils->computeAllBlockSizes();
+ BBUtils->adjustBBOffsetsAfter(&MF.front());
+ bool Changed = false;
+
+ // Find loops with a backwards branching WLS.
+ // This requires looping over the loops in the function, checking each
+ // preheader for a WLS and if its target is before the preheader. If moving
+ // the target block wouldn't produce another backwards WLS or a new forwards
+ // LE branch then move the target block after the preheader.
+ for (auto *ML : *MLI) {
+ MachineBasicBlock *Preheader = ML->getLoopPredecessor();
+ if (!Preheader)
+ continue;
+
+ for (auto &Terminator : Preheader->terminators()) {
+ if (Terminator.getOpcode() != ARM::t2WhileLoopStart)
+ continue;
+ MachineBasicBlock *LoopExit = Terminator.getOperand(1).getMBB();
+ // We don't want to move the function's entry block.
+ if (!LoopExit->getPrevNode())
+ continue;
+ if (blockIsBefore(Preheader, LoopExit))
+ continue;
+ LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "Found a backwards WLS from "
+ << Preheader->getFullName() << " to "
+ << LoopExit->getFullName() << "\n");
+
+ // Make sure that moving the target block doesn't cause any of its WLSs
+ // that were previously not backwards to become backwards
+ bool CanMove = true;
+ for (auto &LoopExitTerminator : LoopExit->terminators()) {
+ if (LoopExitTerminator.getOpcode() != ARM::t2WhileLoopStart)
+ continue;
+ // An example loop structure where the LoopExit can't be moved, since
+ // bb1's WLS will become backwards once it's moved after bb3 bb1: -
+ // LoopExit
+ // WLS bb2 - LoopExit2
+ // bb2:
+ // ...
+ // bb3: - Preheader
+ // WLS bb1
+ // bb4: - Header
+ MachineBasicBlock *LoopExit2 =
+ LoopExitTerminator.getOperand(1).getMBB();
+ // If the WLS from LoopExit to LoopExit2 is already backwards then
+ // moving LoopExit won't affect it, so it can be moved. If LoopExit2 is
+ // after the Preheader then moving will keep it as a forward branch, so
+ // it can be moved. If LoopExit2 is between the Preheader and LoopExit
+ // then moving LoopExit will make it a backwards branch, so it can't be
+ // moved since we'd fix one and introduce one backwards branch.
+ // TODO: Analyse the blocks to make a decision if it would be worth
+ // moving LoopExit even if LoopExit2 is between the Preheader and
+ // LoopExit.
+ if (!blockIsBefore(LoopExit2, LoopExit) &&
+ (LoopExit2 == Preheader || blockIsBefore(LoopExit2, Preheader))) {
+ LLVM_DEBUG(dbgs() << DEBUG_PREFIX
+ << "Can't move the target block as it would "
+ "introduce a new backwards WLS branch\n");
+ CanMove = false;
+ break;
+ }
+ }
+
+ if (CanMove) {
+ // Make sure no LEs become forwards.
+ // An example loop structure where the LoopExit can't be moved, since
+ // bb2's LE will become forwards once bb1 is moved after bb3.
+ // bb1: - LoopExit
+ // bb2:
+ // LE bb1 - Terminator
+ // bb3: - Preheader
+ // WLS bb1
+ // bb4: - Header
+ for (auto It = LoopExit->getIterator(); It != Preheader->getIterator();
+ It++) {
+ MachineBasicBlock *MBB = &*It;
+ for (auto &Terminator : MBB->terminators()) {
+ if (Terminator.getOpcode() != ARM::t2LoopEndDec)
+ continue;
+ MachineBasicBlock *LETarget = Terminator.getOperand(2).getMBB();
+ // The LE will become forwards branching if it branches to LoopExit
+ // which isn't allowed by the architecture, so we should avoid
+ // introducing these.
+ // TODO: Analyse the blocks to make a decision if it would be worth
+ // moving LoopExit even if we'd introduce a forwards LE
+ if (LETarget == LoopExit) {
+ LLVM_DEBUG(dbgs() << DEBUG_PREFIX
+ << "Can't move the target block as it would "
+ "introduce a new forwards LE branch\n");
+ CanMove = false;
+ break;
+ }
+ }
+ }
+
+ if (!CanMove)
+ break;
+ }
+
+ if (CanMove) {
+ moveBasicBlock(LoopExit, Preheader);
+ Changed = true;
+ break;
+ }
+ }
+ }
+
+ return Changed;
+}
+
+bool ARMBlockPlacement::blockIsBefore(MachineBasicBlock *BB,
+ MachineBasicBlock *Other) {
+ return BBUtils->getOffsetOf(Other) > BBUtils->getOffsetOf(BB);
+}
+
+void ARMBlockPlacement::moveBasicBlock(MachineBasicBlock *BB,
+ MachineBasicBlock *After) {
+ LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "Moving " << BB->getName() << " after "
+ << After->getName() << "\n");
+ MachineBasicBlock *BBPrevious = BB->getPrevNode();
+ assert(BBPrevious && "Cannot move the function entry basic block");
+ MachineBasicBlock *AfterNext = After->getNextNode();
+ MachineBasicBlock *BBNext = BB->getNextNode();
+
+ BB->moveAfter(After);
+
+ auto FixFallthrough = [&](MachineBasicBlock *From, MachineBasicBlock *To) {
+ LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "Checking for fallthrough from "
+ << From->getName() << " to " << To->getName() << "\n");
+ assert(From->isSuccessor(To) &&
+ "'To' is expected to be a successor of 'From'");
+ MachineInstr &Terminator = *(--From->terminators().end());
+ if (!Terminator.isUnconditionalBranch()) {
+ // The BB doesn't have an unconditional branch so it relied on
+ // fall-through. Fix by adding an unconditional branch to the moved BB.
+ MachineInstrBuilder MIB =
+ BuildMI(From, Terminator.getDebugLoc(), TII->get(ARM::t2B));
+ MIB.addMBB(To);
+ MIB.addImm(ARMCC::CondCodes::AL);
+ MIB.addReg(ARM::NoRegister);
+ LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "Adding unconditional branch from "
+ << From->getName() << " to " << To->getName() << ": "
+ << *MIB.getInstr());
+ }
+ };
+
+ // Fix fall-through to the moved BB from the one that used to be before it.
+ if (BBPrevious->isSuccessor(BB))
+ FixFallthrough(BBPrevious, BB);
+ // Fix fall through from the destination BB to the one that used to follow.
+ if (AfterNext && After->isSuccessor(AfterNext))
+ FixFallthrough(After, AfterNext);
+ // Fix fall through from the moved BB to the one that used to follow.
+ if (BBNext && BB->isSuccessor(BBNext))
+ FixFallthrough(BB, BBNext);
+
+ BBUtils->adjustBBOffsetsAfter(After);
+}
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMCallLowering.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMCallLowering.cpp
index 471474788e..6feed82596 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMCallLowering.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMCallLowering.cpp
@@ -85,11 +85,11 @@ namespace {
/// Helper class for values going out through an ABI boundary (used for handling
/// function return values and call parameters).
-struct ARMOutgoingValueHandler : public CallLowering::OutgoingValueHandler {
- ARMOutgoingValueHandler(MachineIRBuilder &MIRBuilder,
- MachineRegisterInfo &MRI, MachineInstrBuilder &MIB,
- CCAssignFn *AssignFn)
- : OutgoingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
+struct ARMOutgoingValueHandler : public CallLowering::OutgoingValueHandler {
+ ARMOutgoingValueHandler(MachineIRBuilder &MIRBuilder,
+ MachineRegisterInfo &MRI, MachineInstrBuilder &MIB,
+ CCAssignFn *AssignFn)
+ : OutgoingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
Register getStackAddress(uint64_t Size, int64_t Offset,
MachinePointerInfo &MPO) override {
@@ -257,14 +257,14 @@ bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
CCAssignFn *AssignFn =
TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
- ARMOutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret,
- AssignFn);
+ ARMOutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret,
+ AssignFn);
return handleAssignments(MIRBuilder, SplitRetInfos, RetHandler);
}
bool ARMCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
- const Value *Val, ArrayRef<Register> VRegs,
- FunctionLoweringInfo &FLI) const {
+ const Value *Val, ArrayRef<Register> VRegs,
+ FunctionLoweringInfo &FLI) const {
assert(!Val == VRegs.empty() && "Return value without a vreg");
auto const &ST = MIRBuilder.getMF().getSubtarget<ARMSubtarget>();
@@ -282,10 +282,10 @@ namespace {
/// Helper class for values coming in through an ABI boundary (used for handling
/// formal arguments and call return values).
-struct ARMIncomingValueHandler : public CallLowering::IncomingValueHandler {
- ARMIncomingValueHandler(MachineIRBuilder &MIRBuilder,
- MachineRegisterInfo &MRI, CCAssignFn AssignFn)
- : IncomingValueHandler(MIRBuilder, MRI, AssignFn) {}
+struct ARMIncomingValueHandler : public CallLowering::IncomingValueHandler {
+ ARMIncomingValueHandler(MachineIRBuilder &MIRBuilder,
+ MachineRegisterInfo &MRI, CCAssignFn AssignFn)
+ : IncomingValueHandler(MIRBuilder, MRI, AssignFn) {}
Register getStackAddress(uint64_t Size, int64_t Offset,
MachinePointerInfo &MPO) override {
@@ -335,8 +335,8 @@ struct ARMIncomingValueHandler : public CallLowering::IncomingValueHandler {
assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
- uint64_t ValSize = VA.getValVT().getFixedSizeInBits();
- uint64_t LocSize = VA.getLocVT().getFixedSizeInBits();
+ uint64_t ValSize = VA.getValVT().getFixedSizeInBits();
+ uint64_t LocSize = VA.getLocVT().getFixedSizeInBits();
assert(ValSize <= 64 && "Unsupported value size");
assert(LocSize <= 64 && "Unsupported location size");
@@ -397,10 +397,10 @@ struct ARMIncomingValueHandler : public CallLowering::IncomingValueHandler {
virtual void markPhysRegUsed(unsigned PhysReg) = 0;
};
-struct FormalArgHandler : public ARMIncomingValueHandler {
+struct FormalArgHandler : public ARMIncomingValueHandler {
FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
CCAssignFn AssignFn)
- : ARMIncomingValueHandler(MIRBuilder, MRI, AssignFn) {}
+ : ARMIncomingValueHandler(MIRBuilder, MRI, AssignFn) {}
void markPhysRegUsed(unsigned PhysReg) override {
MIRBuilder.getMRI()->addLiveIn(PhysReg);
@@ -410,10 +410,10 @@ struct FormalArgHandler : public ARMIncomingValueHandler {
} // end anonymous namespace
-bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
- const Function &F,
- ArrayRef<ArrayRef<Register>> VRegs,
- FunctionLoweringInfo &FLI) const {
+bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
+ const Function &F,
+ ArrayRef<ArrayRef<Register>> VRegs,
+ FunctionLoweringInfo &FLI) const {
auto &TLI = *getTLI<ARMTargetLowering>();
auto Subtarget = TLI.getSubtarget();
@@ -434,7 +434,7 @@ bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
for (auto &Arg : F.args()) {
if (!isSupportedType(DL, TLI, Arg.getType()))
return false;
- if (Arg.hasPassPointeeByValueCopyAttr())
+ if (Arg.hasPassPointeeByValueCopyAttr())
return false;
}
@@ -468,10 +468,10 @@ bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
namespace {
-struct CallReturnHandler : public ARMIncomingValueHandler {
+struct CallReturnHandler : public ARMIncomingValueHandler {
CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
MachineInstrBuilder MIB, CCAssignFn *AssignFn)
- : ARMIncomingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
+ : ARMIncomingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
void markPhysRegUsed(unsigned PhysReg) override {
MIB.addDef(PhysReg, RegState::Implicit);
@@ -481,16 +481,16 @@ struct CallReturnHandler : public ARMIncomingValueHandler {
};
// FIXME: This should move to the ARMSubtarget when it supports all the opcodes.
-unsigned getCallOpcode(const MachineFunction &MF, const ARMSubtarget &STI,
- bool isDirect) {
+unsigned getCallOpcode(const MachineFunction &MF, const ARMSubtarget &STI,
+ bool isDirect) {
if (isDirect)
return STI.isThumb() ? ARM::tBL : ARM::BL;
if (STI.isThumb())
- return gettBLXrOpcode(MF);
+ return gettBLXrOpcode(MF);
if (STI.hasV5TOps())
- return getBLXOpcode(MF);
+ return getBLXOpcode(MF);
if (STI.hasV4TOps())
return ARM::BX_CALL;
@@ -518,7 +518,7 @@ bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &
// Create the call instruction so we can add the implicit uses of arg
// registers, but don't insert it yet.
bool IsDirect = !Info.Callee.isReg();
- auto CallOpcode = getCallOpcode(MF, STI, IsDirect);
+ auto CallOpcode = getCallOpcode(MF, STI, IsDirect);
auto MIB = MIRBuilder.buildInstrNoInsert(CallOpcode);
bool IsThumb = STI.isThumb();
@@ -549,8 +549,8 @@ bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &
splitToValueTypes(Arg, ArgInfos, MF);
}
- auto ArgAssignFn = TLI.CCAssignFnForCall(Info.CallConv, Info.IsVarArg);
- ARMOutgoingValueHandler ArgHandler(MIRBuilder, MRI, MIB, ArgAssignFn);
+ auto ArgAssignFn = TLI.CCAssignFnForCall(Info.CallConv, Info.IsVarArg);
+ ARMOutgoingValueHandler ArgHandler(MIRBuilder, MRI, MIB, ArgAssignFn);
if (!handleAssignments(MIRBuilder, ArgInfos, ArgHandler))
return false;
@@ -563,7 +563,7 @@ bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &
ArgInfos.clear();
splitToValueTypes(Info.OrigRet, ArgInfos, MF);
- auto RetAssignFn = TLI.CCAssignFnForReturn(Info.CallConv, Info.IsVarArg);
+ auto RetAssignFn = TLI.CCAssignFnForReturn(Info.CallConv, Info.IsVarArg);
CallReturnHandler RetHandler(MIRBuilder, MRI, MIB, RetAssignFn);
if (!handleAssignments(MIRBuilder, ArgInfos, RetHandler))
return false;
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMCallLowering.h b/contrib/libs/llvm12/lib/Target/ARM/ARMCallLowering.h
index 9bff3564c5..3be73d497d 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMCallLowering.h
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMCallLowering.h
@@ -33,12 +33,12 @@ public:
ARMCallLowering(const ARMTargetLowering &TLI);
bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
- ArrayRef<Register> VRegs,
- FunctionLoweringInfo &FLI) const override;
+ ArrayRef<Register> VRegs,
+ FunctionLoweringInfo &FLI) const override;
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F,
- ArrayRef<ArrayRef<Register>> VRegs,
- FunctionLoweringInfo &FLI) const override;
+ ArrayRef<ArrayRef<Register>> VRegs,
+ FunctionLoweringInfo &FLI) const override;
bool lowerCall(MachineIRBuilder &MIRBuilder,
CallLoweringInfo &Info) const override;
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMConstantIslandPass.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMConstantIslandPass.cpp
index 86faf511c9..630490f6f9 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMConstantIslandPass.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMConstantIslandPass.cpp
@@ -338,32 +338,32 @@ LLVM_DUMP_METHOD void ARMConstantIslands::dumpBBs() {
}
#endif
-// Align blocks where the previous block does not fall through. This may add
-// extra NOP's but they will not be executed. It uses the PrefLoopAlignment as a
-// measure of how much to align, and only runs at CodeGenOpt::Aggressive.
-static bool AlignBlocks(MachineFunction *MF) {
- if (MF->getTarget().getOptLevel() != CodeGenOpt::Aggressive ||
- MF->getFunction().hasOptSize())
- return false;
-
- auto *TLI = MF->getSubtarget().getTargetLowering();
- const Align Alignment = TLI->getPrefLoopAlignment();
- if (Alignment < 4)
- return false;
-
- bool Changed = false;
- bool PrevCanFallthough = true;
- for (auto &MBB : *MF) {
- if (!PrevCanFallthough) {
- Changed = true;
- MBB.setAlignment(Alignment);
- }
- PrevCanFallthough = MBB.canFallThrough();
- }
-
- return Changed;
-}
-
+// Align blocks where the previous block does not fall through. This may add
+// extra NOP's but they will not be executed. It uses the PrefLoopAlignment as a
+// measure of how much to align, and only runs at CodeGenOpt::Aggressive.
+static bool AlignBlocks(MachineFunction *MF) {
+ if (MF->getTarget().getOptLevel() != CodeGenOpt::Aggressive ||
+ MF->getFunction().hasOptSize())
+ return false;
+
+ auto *TLI = MF->getSubtarget().getTargetLowering();
+ const Align Alignment = TLI->getPrefLoopAlignment();
+ if (Alignment < 4)
+ return false;
+
+ bool Changed = false;
+ bool PrevCanFallthough = true;
+ for (auto &MBB : *MF) {
+ if (!PrevCanFallthough) {
+ Changed = true;
+ MBB.setAlignment(Alignment);
+ }
+ PrevCanFallthough = MBB.canFallThrough();
+ }
+
+ return Changed;
+}
+
bool ARMConstantIslands::runOnMachineFunction(MachineFunction &mf) {
MF = &mf;
MCP = mf.getConstantPool();
@@ -385,10 +385,10 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &mf) {
isThumb2 = AFI->isThumb2Function();
bool GenerateTBB = isThumb2 || (isThumb1 && SynthesizeThumb1TBB);
- // TBB generation code in this constant island pass has not been adapted to
- // deal with speculation barriers.
- if (STI->hardenSlsRetBr())
- GenerateTBB = false;
+ // TBB generation code in this constant island pass has not been adapted to
+ // deal with speculation barriers.
+ if (STI->hardenSlsRetBr())
+ GenerateTBB = false;
// Renumber all of the machine basic blocks in the function, guaranteeing that
// the numbers agree with the position of the block in the function.
@@ -406,9 +406,9 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &mf) {
MF->RenumberBlocks();
}
- // Align any non-fallthrough blocks
- MadeChange |= AlignBlocks(MF);
-
+ // Align any non-fallthrough blocks
+ MadeChange |= AlignBlocks(MF);
+
// Perform the initial placement of the constant pool entries. To start with,
// we put them all at the end of the function.
std::vector<MachineInstr*> CPEMIs;
@@ -524,11 +524,11 @@ ARMConstantIslands::doInitialConstPlacement(std::vector<MachineInstr*> &CPEMIs)
// The function needs to be as aligned as the basic blocks. The linker may
// move functions around based on their alignment.
- // Special case: halfword literals still need word alignment on the function.
- Align FuncAlign = MaxAlign;
- if (MaxAlign == 2)
- FuncAlign = Align(4);
- MF->ensureAlignment(FuncAlign);
+ // Special case: halfword literals still need word alignment on the function.
+ Align FuncAlign = MaxAlign;
+ if (MaxAlign == 2)
+ FuncAlign = Align(4);
+ MF->ensureAlignment(FuncAlign);
// Order the entries in BB by descending alignment. That ensures correct
// alignment of all entries as long as BB is sufficiently aligned. Keep
@@ -543,7 +543,7 @@ ARMConstantIslands::doInitialConstPlacement(std::vector<MachineInstr*> &CPEMIs)
const DataLayout &TD = MF->getDataLayout();
for (unsigned i = 0, e = CPs.size(); i != e; ++i) {
- unsigned Size = CPs[i].getSizeInBytes(TD);
+ unsigned Size = CPs[i].getSizeInBytes(TD);
Align Alignment = CPs[i].getAlign();
// Verify that all constant pool entries are a multiple of their alignment.
// If not, we would have to pad them out so that instructions stay aligned.
@@ -586,12 +586,12 @@ void ARMConstantIslands::doInitialJumpTablePlacement(
MachineBasicBlock *LastCorrectlyNumberedBB = nullptr;
for (MachineBasicBlock &MBB : *MF) {
auto MI = MBB.getLastNonDebugInstr();
- // Look past potential SpeculationBarriers at end of BB.
- while (MI != MBB.end() &&
- (isSpeculationBarrierEndBBOpcode(MI->getOpcode()) ||
- MI->isDebugInstr()))
- --MI;
-
+ // Look past potential SpeculationBarriers at end of BB.
+ while (MI != MBB.end() &&
+ (isSpeculationBarrierEndBBOpcode(MI->getOpcode()) ||
+ MI->isDebugInstr()))
+ --MI;
+
if (MI == MBB.end())
continue;
@@ -814,26 +814,26 @@ initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {
// Taking the address of a CP entry.
case ARM::LEApcrel:
- case ARM::LEApcrelJT: {
- // This takes a SoImm, which is 8 bit immediate rotated. We'll
- // pretend the maximum offset is 255 * 4. Since each instruction
- // 4 byte wide, this is always correct. We'll check for other
- // displacements that fits in a SoImm as well.
- Bits = 8;
- NegOk = true;
- IsSoImm = true;
- unsigned CPI = I.getOperand(op).getIndex();
- assert(CPI < CPEMIs.size());
- MachineInstr *CPEMI = CPEMIs[CPI];
- const Align CPEAlign = getCPEAlign(CPEMI);
- const unsigned LogCPEAlign = Log2(CPEAlign);
- if (LogCPEAlign >= 2)
- Scale = 4;
- else
- // For constants with less than 4-byte alignment,
- // we'll pretend the maximum offset is 255 * 1.
- Scale = 1;
- }
+ case ARM::LEApcrelJT: {
+ // This takes a SoImm, which is 8 bit immediate rotated. We'll
+ // pretend the maximum offset is 255 * 4. Since each instruction
+ // 4 byte wide, this is always correct. We'll check for other
+ // displacements that fits in a SoImm as well.
+ Bits = 8;
+ NegOk = true;
+ IsSoImm = true;
+ unsigned CPI = I.getOperand(op).getIndex();
+ assert(CPI < CPEMIs.size());
+ MachineInstr *CPEMI = CPEMIs[CPI];
+ const Align CPEAlign = getCPEAlign(CPEMI);
+ const unsigned LogCPEAlign = Log2(CPEAlign);
+ if (LogCPEAlign >= 2)
+ Scale = 4;
+ else
+ // For constants with less than 4-byte alignment,
+ // we'll pretend the maximum offset is 255 * 1.
+ Scale = 1;
+ }
break;
case ARM::t2LEApcrel:
case ARM::t2LEApcrelJT:
@@ -2124,7 +2124,7 @@ static bool jumpTableFollowsTB(MachineInstr *JTMI, MachineInstr *CPEMI) {
MachineFunction *MF = MBB->getParent();
++MBB;
- return MBB != MF->end() && !MBB->empty() && &*MBB->begin() == CPEMI;
+ return MBB != MF->end() && !MBB->empty() && &*MBB->begin() == CPEMI;
}
static void RemoveDeadAddBetweenLEAAndJT(MachineInstr *LEAMI,
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMExpandPseudoInsts.cpp
index a38327ffe6..a7f1765a93 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMExpandPseudoInsts.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMExpandPseudoInsts.cpp
@@ -875,25 +875,25 @@ void ARMExpandPseudo::ExpandMOV32BitImm(MachineBasicBlock &MBB,
assert (MO.isImm() && "MOVi32imm w/ non-immediate source operand!");
unsigned ImmVal = (unsigned)MO.getImm();
- unsigned SOImmValV1 = 0, SOImmValV2 = 0;
-
- if (ARM_AM::isSOImmTwoPartVal(ImmVal)) { // Expand into a movi + orr.
- LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVi), DstReg);
- HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::ORRri))
- .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
- .addReg(DstReg);
- SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal);
- SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal);
- } else { // Expand into a mvn + sub.
- LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MVNi), DstReg);
- HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::SUBri))
- .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
- .addReg(DstReg);
- SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(-ImmVal);
- SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(-ImmVal);
- SOImmValV1 = ~(-SOImmValV1);
- }
-
+ unsigned SOImmValV1 = 0, SOImmValV2 = 0;
+
+ if (ARM_AM::isSOImmTwoPartVal(ImmVal)) { // Expand into a movi + orr.
+ LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVi), DstReg);
+ HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::ORRri))
+ .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
+ .addReg(DstReg);
+ SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal);
+ SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal);
+ } else { // Expand into a mvn + sub.
+ LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MVNi), DstReg);
+ HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::SUBri))
+ .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
+ .addReg(DstReg);
+ SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(-ImmVal);
+ SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(-ImmVal);
+ SOImmValV1 = ~(-SOImmValV1);
+ }
+
unsigned MIFlags = MI.getFlags();
LO16 = LO16.addImm(SOImmValV1);
HI16 = HI16.addImm(SOImmValV2);
@@ -1871,66 +1871,66 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
default:
return false;
- case ARM::VBSPd:
- case ARM::VBSPq: {
- Register DstReg = MI.getOperand(0).getReg();
- if (DstReg == MI.getOperand(3).getReg()) {
- // Expand to VBIT
- unsigned NewOpc = Opcode == ARM::VBSPd ? ARM::VBITd : ARM::VBITq;
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc))
- .add(MI.getOperand(0))
- .add(MI.getOperand(3))
- .add(MI.getOperand(2))
- .add(MI.getOperand(1))
- .addImm(MI.getOperand(4).getImm())
- .add(MI.getOperand(5));
- } else if (DstReg == MI.getOperand(2).getReg()) {
- // Expand to VBIF
- unsigned NewOpc = Opcode == ARM::VBSPd ? ARM::VBIFd : ARM::VBIFq;
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc))
- .add(MI.getOperand(0))
- .add(MI.getOperand(2))
- .add(MI.getOperand(3))
- .add(MI.getOperand(1))
- .addImm(MI.getOperand(4).getImm())
- .add(MI.getOperand(5));
- } else {
- // Expand to VBSL
- unsigned NewOpc = Opcode == ARM::VBSPd ? ARM::VBSLd : ARM::VBSLq;
- if (DstReg == MI.getOperand(1).getReg()) {
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc))
- .add(MI.getOperand(0))
- .add(MI.getOperand(1))
- .add(MI.getOperand(2))
- .add(MI.getOperand(3))
- .addImm(MI.getOperand(4).getImm())
- .add(MI.getOperand(5));
- } else {
- // Use move to satisfy constraints
- unsigned MoveOpc = Opcode == ARM::VBSPd ? ARM::VORRd : ARM::VORRq;
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(MoveOpc))
- .addReg(DstReg,
- RegState::Define |
- getRenamableRegState(MI.getOperand(0).isRenamable()))
- .add(MI.getOperand(1))
- .add(MI.getOperand(1))
- .addImm(MI.getOperand(4).getImm())
- .add(MI.getOperand(5));
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc))
- .add(MI.getOperand(0))
- .addReg(DstReg,
- RegState::Kill |
- getRenamableRegState(MI.getOperand(0).isRenamable()))
- .add(MI.getOperand(2))
- .add(MI.getOperand(3))
- .addImm(MI.getOperand(4).getImm())
- .add(MI.getOperand(5));
- }
- }
- MI.eraseFromParent();
- return true;
- }
-
+ case ARM::VBSPd:
+ case ARM::VBSPq: {
+ Register DstReg = MI.getOperand(0).getReg();
+ if (DstReg == MI.getOperand(3).getReg()) {
+ // Expand to VBIT
+ unsigned NewOpc = Opcode == ARM::VBSPd ? ARM::VBITd : ARM::VBITq;
+ BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc))
+ .add(MI.getOperand(0))
+ .add(MI.getOperand(3))
+ .add(MI.getOperand(2))
+ .add(MI.getOperand(1))
+ .addImm(MI.getOperand(4).getImm())
+ .add(MI.getOperand(5));
+ } else if (DstReg == MI.getOperand(2).getReg()) {
+ // Expand to VBIF
+ unsigned NewOpc = Opcode == ARM::VBSPd ? ARM::VBIFd : ARM::VBIFq;
+ BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc))
+ .add(MI.getOperand(0))
+ .add(MI.getOperand(2))
+ .add(MI.getOperand(3))
+ .add(MI.getOperand(1))
+ .addImm(MI.getOperand(4).getImm())
+ .add(MI.getOperand(5));
+ } else {
+ // Expand to VBSL
+ unsigned NewOpc = Opcode == ARM::VBSPd ? ARM::VBSLd : ARM::VBSLq;
+ if (DstReg == MI.getOperand(1).getReg()) {
+ BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc))
+ .add(MI.getOperand(0))
+ .add(MI.getOperand(1))
+ .add(MI.getOperand(2))
+ .add(MI.getOperand(3))
+ .addImm(MI.getOperand(4).getImm())
+ .add(MI.getOperand(5));
+ } else {
+ // Use move to satisfy constraints
+ unsigned MoveOpc = Opcode == ARM::VBSPd ? ARM::VORRd : ARM::VORRq;
+ BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(MoveOpc))
+ .addReg(DstReg,
+ RegState::Define |
+ getRenamableRegState(MI.getOperand(0).isRenamable()))
+ .add(MI.getOperand(1))
+ .add(MI.getOperand(1))
+ .addImm(MI.getOperand(4).getImm())
+ .add(MI.getOperand(5));
+ BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc))
+ .add(MI.getOperand(0))
+ .addReg(DstReg,
+ RegState::Kill |
+ getRenamableRegState(MI.getOperand(0).isRenamable()))
+ .add(MI.getOperand(2))
+ .add(MI.getOperand(3))
+ .addImm(MI.getOperand(4).getImm())
+ .add(MI.getOperand(5));
+ }
+ }
+ MI.eraseFromParent();
+ return true;
+ }
+
case ARM::TCRETURNdi:
case ARM::TCRETURNri: {
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
@@ -2304,9 +2304,9 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
MIB.addImm(0);
MIB.add(predOps(ARMCC::AL));
- MIB =
- BuildMI(MBB, MBBI, MI.getDebugLoc(),
- TII->get(Thumb ? gettBLXrOpcode(*MF) : getBLXOpcode(*MF)));
+ MIB =
+ BuildMI(MBB, MBBI, MI.getDebugLoc(),
+ TII->get(Thumb ? gettBLXrOpcode(*MF) : getBLXOpcode(*MF)));
if (Thumb)
MIB.add(predOps(ARMCC::AL));
MIB.addReg(Reg, RegState::Kill);
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMFastISel.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMFastISel.cpp
index 483aeb4d72..da1d9af8d5 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMFastISel.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMFastISel.cpp
@@ -606,9 +606,9 @@ unsigned ARMFastISel::ARMMaterializeGV(const GlobalValue *GV, MVT VT) {
}
}
- if ((Subtarget->isTargetELF() && Subtarget->isGVInGOT(GV)) ||
- (Subtarget->isTargetMachO() && IsIndirect) ||
- Subtarget->genLongCalls()) {
+ if ((Subtarget->isTargetELF() && Subtarget->isGVInGOT(GV)) ||
+ (Subtarget->isTargetMachO() && IsIndirect) ||
+ Subtarget->genLongCalls()) {
MachineInstrBuilder MIB;
unsigned NewDestReg = createResultReg(TLI.getRegClassFor(VT));
if (isThumb2)
@@ -2175,7 +2175,7 @@ bool ARMFastISel::SelectRet(const Instruction *I) {
unsigned ARMFastISel::ARMSelectCallOp(bool UseReg) {
if (UseReg)
- return isThumb2 ? gettBLXrOpcode(*MF) : getBLXOpcode(*MF);
+ return isThumb2 ? gettBLXrOpcode(*MF) : getBLXOpcode(*MF);
else
return isThumb2 ? ARM::tBL : ARM::BL;
}
@@ -2266,11 +2266,11 @@ bool ARMFastISel::ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call) {
// BL / BLX don't take a predicate, but tBL / tBLX do.
if (isThumb2)
MIB.add(predOps(ARMCC::AL));
- if (Subtarget->genLongCalls()) {
- CalleeReg =
- constrainOperandRegClass(TII.get(CallOpc), CalleeReg, isThumb2 ? 2 : 0);
+ if (Subtarget->genLongCalls()) {
+ CalleeReg =
+ constrainOperandRegClass(TII.get(CallOpc), CalleeReg, isThumb2 ? 2 : 0);
MIB.addReg(CalleeReg);
- } else
+ } else
MIB.addExternalSymbol(TLI.getLibcallName(Call));
// Add implicit physical register uses to the call.
@@ -2408,11 +2408,11 @@ bool ARMFastISel::SelectCall(const Instruction *I,
// ARM calls don't take a predicate, but tBL / tBLX do.
if(isThumb2)
MIB.add(predOps(ARMCC::AL));
- if (UseReg) {
- CalleeReg =
- constrainOperandRegClass(TII.get(CallOpc), CalleeReg, isThumb2 ? 2 : 0);
+ if (UseReg) {
+ CalleeReg =
+ constrainOperandRegClass(TII.get(CallOpc), CalleeReg, isThumb2 ? 2 : 0);
MIB.addReg(CalleeReg);
- } else if (!IntrMemName)
+ } else if (!IntrMemName)
MIB.addGlobalAddress(GV, 0, 0);
else
MIB.addExternalSymbol(IntrMemName, 0);
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMFeatures.h b/contrib/libs/llvm12/lib/Target/ARM/ARMFeatures.h
index 6d8e75a2ec..99e0ef05b5 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMFeatures.h
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMFeatures.h
@@ -75,7 +75,7 @@ inline bool isV8EligibleForIT(const InstrType *Instr) {
// there are some "conditionally deprecated" opcodes
case ARM::tADDspr:
case ARM::tBLXr:
- case ARM::tBLXr_noip:
+ case ARM::tBLXr_noip:
return Instr->getOperand(2).getReg() != ARM::PC;
// ADD PC, SP and BLX PC were always unpredictable,
// now on top of it they're deprecated
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMFrameLowering.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMFrameLowering.cpp
index e0a657b505..9eeb7f20dc 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMFrameLowering.cpp
@@ -883,10 +883,10 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
/// debug info. It's the same as what we use for resolving the code-gen
/// references for now. FIXME: This can go wrong when references are
/// SP-relative and simple call frames aren't used.
-StackOffset ARMFrameLowering::getFrameIndexReference(const MachineFunction &MF,
- int FI,
- Register &FrameReg) const {
- return StackOffset::getFixed(ResolveFrameIndexReference(MF, FI, FrameReg, 0));
+StackOffset ARMFrameLowering::getFrameIndexReference(const MachineFunction &MF,
+ int FI,
+ Register &FrameReg) const {
+ return StackOffset::getFixed(ResolveFrameIndexReference(MF, FI, FrameReg, 0));
}
int ARMFrameLowering::ResolveFrameIndexReference(const MachineFunction &MF,
@@ -2114,7 +2114,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
unsigned NumExtras = TargetAlign.value() / 4;
SmallVector<unsigned, 2> Extras;
while (NumExtras && !UnspilledCS1GPRs.empty()) {
- unsigned Reg = UnspilledCS1GPRs.pop_back_val();
+ unsigned Reg = UnspilledCS1GPRs.pop_back_val();
if (!MRI.isReserved(Reg) &&
(!AFI->isThumb1OnlyFunction() || isARMLowRegister(Reg))) {
Extras.push_back(Reg);
@@ -2124,7 +2124,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
// For non-Thumb1 functions, also check for hi-reg CS registers
if (!AFI->isThumb1OnlyFunction()) {
while (NumExtras && !UnspilledCS2GPRs.empty()) {
- unsigned Reg = UnspilledCS2GPRs.pop_back_val();
+ unsigned Reg = UnspilledCS2GPRs.pop_back_val();
if (!MRI.isReserved(Reg)) {
Extras.push_back(Reg);
NumExtras--;
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMFrameLowering.h b/contrib/libs/llvm12/lib/Target/ARM/ARMFrameLowering.h
index c609c07043..9822e2321b 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMFrameLowering.h
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMFrameLowering.h
@@ -10,7 +10,7 @@
#define LLVM_LIB_TARGET_ARM_ARMFRAMELOWERING_H
#include "llvm/CodeGen/TargetFrameLowering.h"
-#include "llvm/Support/TypeSize.h"
+#include "llvm/Support/TypeSize.h"
namespace llvm {
@@ -48,8 +48,8 @@ public:
bool hasFP(const MachineFunction &MF) const override;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override;
- StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
- Register &FrameReg) const override;
+ StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
+ Register &FrameReg) const override;
int ResolveFrameIndexReference(const MachineFunction &MF, int FI,
Register &FrameReg, int SPAdj) const;
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMHazardRecognizer.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMHazardRecognizer.cpp
index 48df96b5e6..f083fa6662 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMHazardRecognizer.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMHazardRecognizer.cpp
@@ -10,19 +10,19 @@
#include "ARMBaseInstrInfo.h"
#include "ARMBaseRegisterInfo.h"
#include "ARMSubtarget.h"
-#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/Analysis/ValueTracking.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
-#include "llvm/Support/CommandLine.h"
-
+#include "llvm/Support/CommandLine.h"
+
using namespace llvm;
-static cl::opt<int> DataBankMask("arm-data-bank-mask", cl::init(-1),
- cl::Hidden);
-static cl::opt<bool> AssumeITCMConflict("arm-assume-itcm-bankconflict",
- cl::init(false), cl::Hidden);
-
+static cl::opt<int> DataBankMask("arm-data-bank-mask", cl::init(-1),
+ cl::Hidden);
+static cl::opt<bool> AssumeITCMConflict("arm-assume-itcm-bankconflict",
+ cl::init(false), cl::Hidden);
+
static bool hasRAWHazard(MachineInstr *DefMI, MachineInstr *MI,
const TargetRegisterInfo &TRI) {
// FIXME: Detect integer instructions properly.
@@ -39,7 +39,7 @@ static bool hasRAWHazard(MachineInstr *DefMI, MachineInstr *MI,
}
ScheduleHazardRecognizer::HazardType
-ARMHazardRecognizerFPMLx::getHazardType(SUnit *SU, int Stalls) {
+ARMHazardRecognizerFPMLx::getHazardType(SUnit *SU, int Stalls) {
assert(Stalls == 0 && "ARM hazards don't support scoreboard lookahead");
MachineInstr *MI = SU->getInstr();
@@ -76,15 +76,15 @@ ARMHazardRecognizerFPMLx::getHazardType(SUnit *SU, int Stalls) {
}
}
}
- return NoHazard;
+ return NoHazard;
}
-void ARMHazardRecognizerFPMLx::Reset() {
+void ARMHazardRecognizerFPMLx::Reset() {
LastMI = nullptr;
FpMLxStalls = 0;
}
-void ARMHazardRecognizerFPMLx::EmitInstruction(SUnit *SU) {
+void ARMHazardRecognizerFPMLx::EmitInstruction(SUnit *SU) {
MachineInstr *MI = SU->getInstr();
if (!MI->isDebugInstr()) {
LastMI = MI;
@@ -92,177 +92,177 @@ void ARMHazardRecognizerFPMLx::EmitInstruction(SUnit *SU) {
}
}
-void ARMHazardRecognizerFPMLx::AdvanceCycle() {
+void ARMHazardRecognizerFPMLx::AdvanceCycle() {
if (FpMLxStalls && --FpMLxStalls == 0)
// Stalled for 4 cycles but still can't schedule any other instructions.
LastMI = nullptr;
}
-void ARMHazardRecognizerFPMLx::RecedeCycle() {
+void ARMHazardRecognizerFPMLx::RecedeCycle() {
llvm_unreachable("reverse ARM hazard checking unsupported");
}
-
-///////// Bank conflicts handled as hazards //////////////
-
-static bool getBaseOffset(const MachineInstr &MI, const MachineOperand *&BaseOp,
- int64_t &Offset) {
-
- uint64_t TSFlags = MI.getDesc().TSFlags;
- unsigned AddrMode = (TSFlags & ARMII::AddrModeMask);
- unsigned IndexMode =
- (TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
-
- // Address mode tells us what we want to know about operands for T2
- // instructions (but not size). It tells us size (but not about operands)
- // for T1 instructions.
- switch (AddrMode) {
- default:
- return false;
- case ARMII::AddrModeT2_i8:
- // t2LDRBT, t2LDRB_POST, t2LDRB_PRE, t2LDRBi8,
- // t2LDRHT, t2LDRH_POST, t2LDRH_PRE, t2LDRHi8,
- // t2LDRSBT, t2LDRSB_POST, t2LDRSB_PRE, t2LDRSBi8,
- // t2LDRSHT, t2LDRSH_POST, t2LDRSH_PRE, t2LDRSHi8,
- // t2LDRT, t2LDR_POST, t2LDR_PRE, t2LDRi8
- BaseOp = &MI.getOperand(1);
- Offset = (IndexMode == ARMII::IndexModePost)
- ? 0
- : (IndexMode == ARMII::IndexModePre ||
- IndexMode == ARMII::IndexModeUpd)
- ? MI.getOperand(3).getImm()
- : MI.getOperand(2).getImm();
- return true;
- case ARMII::AddrModeT2_i12:
- // t2LDRBi12, t2LDRHi12
- // t2LDRSBi12, t2LDRSHi12
- // t2LDRi12
- BaseOp = &MI.getOperand(1);
- Offset = MI.getOperand(2).getImm();
- return true;
- case ARMII::AddrModeT2_i8s4:
- // t2LDRD_POST, t2LDRD_PRE, t2LDRDi8
- BaseOp = &MI.getOperand(2);
- Offset = (IndexMode == ARMII::IndexModePost)
- ? 0
- : (IndexMode == ARMII::IndexModePre ||
- IndexMode == ARMII::IndexModeUpd)
- ? MI.getOperand(4).getImm()
- : MI.getOperand(3).getImm();
- return true;
- case ARMII::AddrModeT1_1:
- // tLDRBi, tLDRBr (watch out!), TLDRSB
- case ARMII::AddrModeT1_2:
- // tLDRHi, tLDRHr (watch out!), TLDRSH
- case ARMII::AddrModeT1_4:
- // tLDRi, tLDRr (watch out!)
- BaseOp = &MI.getOperand(1);
- Offset = MI.getOperand(2).isImm() ? MI.getOperand(2).getImm() : 0;
- return MI.getOperand(2).isImm();
- }
- return false;
-}
-
-ARMBankConflictHazardRecognizer::ARMBankConflictHazardRecognizer(
- const ScheduleDAG *DAG, int64_t CPUBankMask, bool CPUAssumeITCMConflict)
- : ScheduleHazardRecognizer(), MF(DAG->MF), DL(DAG->MF.getDataLayout()),
- DataMask(DataBankMask.getNumOccurrences() ? int64_t(DataBankMask)
- : CPUBankMask),
- AssumeITCMBankConflict(AssumeITCMConflict.getNumOccurrences()
- ? AssumeITCMConflict
- : CPUAssumeITCMConflict) {
- MaxLookAhead = 1;
-}
-
-ScheduleHazardRecognizer::HazardType
-ARMBankConflictHazardRecognizer::CheckOffsets(unsigned O0, unsigned O1) {
- return (((O0 ^ O1) & DataMask) != 0) ? NoHazard : Hazard;
-}
-
-ScheduleHazardRecognizer::HazardType
-ARMBankConflictHazardRecognizer::getHazardType(SUnit *SU, int Stalls) {
- MachineInstr &L0 = *SU->getInstr();
- if (!L0.mayLoad() || L0.mayStore() || L0.getNumMemOperands() != 1)
- return NoHazard;
-
- auto MO0 = *L0.memoperands().begin();
- auto BaseVal0 = MO0->getValue();
- auto BasePseudoVal0 = MO0->getPseudoValue();
- int64_t Offset0 = 0;
-
- if (MO0->getSize() > 4)
- return NoHazard;
-
- bool SPvalid = false;
- const MachineOperand *SP = nullptr;
- int64_t SPOffset0 = 0;
-
- for (auto L1 : Accesses) {
- auto MO1 = *L1->memoperands().begin();
- auto BaseVal1 = MO1->getValue();
- auto BasePseudoVal1 = MO1->getPseudoValue();
- int64_t Offset1 = 0;
-
- // Pointers to the same object
- if (BaseVal0 && BaseVal1) {
- const Value *Ptr0, *Ptr1;
- Ptr0 = GetPointerBaseWithConstantOffset(BaseVal0, Offset0, DL, true);
- Ptr1 = GetPointerBaseWithConstantOffset(BaseVal1, Offset1, DL, true);
- if (Ptr0 == Ptr1 && Ptr0)
- return CheckOffsets(Offset0, Offset1);
- }
-
- if (BasePseudoVal0 && BasePseudoVal1 &&
- BasePseudoVal0->kind() == BasePseudoVal1->kind() &&
- BasePseudoVal0->kind() == PseudoSourceValue::FixedStack) {
- // Spills/fills
- auto FS0 = cast<FixedStackPseudoSourceValue>(BasePseudoVal0);
- auto FS1 = cast<FixedStackPseudoSourceValue>(BasePseudoVal1);
- Offset0 = MF.getFrameInfo().getObjectOffset(FS0->getFrameIndex());
- Offset1 = MF.getFrameInfo().getObjectOffset(FS1->getFrameIndex());
- return CheckOffsets(Offset0, Offset1);
- }
-
- // Constant pools (likely in ITCM)
- if (BasePseudoVal0 && BasePseudoVal1 &&
- BasePseudoVal0->kind() == BasePseudoVal1->kind() &&
- BasePseudoVal0->isConstantPool() && AssumeITCMBankConflict)
- return Hazard;
-
- // Is this a stack pointer-relative access? We could in general try to
- // use "is this the same register and is it unchanged?", but the
- // memory operand tracking is highly likely to have already found that.
- // What we're after here is bank conflicts between different objects in
- // the stack frame.
- if (!SPvalid) { // set up SP
- if (!getBaseOffset(L0, SP, SPOffset0) || SP->getReg().id() != ARM::SP)
- SP = nullptr;
- SPvalid = true;
- }
- if (SP) {
- int64_t SPOffset1;
- const MachineOperand *SP1;
- if (getBaseOffset(*L1, SP1, SPOffset1) && SP1->getReg().id() == ARM::SP)
- return CheckOffsets(SPOffset0, SPOffset1);
- }
- }
-
- return NoHazard;
-}
-
-void ARMBankConflictHazardRecognizer::Reset() { Accesses.clear(); }
-
-void ARMBankConflictHazardRecognizer::EmitInstruction(SUnit *SU) {
- MachineInstr &MI = *SU->getInstr();
- if (!MI.mayLoad() || MI.mayStore() || MI.getNumMemOperands() != 1)
- return;
-
- auto MO = *MI.memoperands().begin();
- uint64_t Size1 = MO->getSize();
- if (Size1 > 4)
- return;
- Accesses.push_back(&MI);
-}
-
-void ARMBankConflictHazardRecognizer::AdvanceCycle() { Accesses.clear(); }
-
-void ARMBankConflictHazardRecognizer::RecedeCycle() { Accesses.clear(); }
+
+///////// Bank conflicts handled as hazards //////////////
+
+static bool getBaseOffset(const MachineInstr &MI, const MachineOperand *&BaseOp,
+ int64_t &Offset) {
+
+ uint64_t TSFlags = MI.getDesc().TSFlags;
+ unsigned AddrMode = (TSFlags & ARMII::AddrModeMask);
+ unsigned IndexMode =
+ (TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
+
+ // Address mode tells us what we want to know about operands for T2
+ // instructions (but not size). It tells us size (but not about operands)
+ // for T1 instructions.
+ switch (AddrMode) {
+ default:
+ return false;
+ case ARMII::AddrModeT2_i8:
+ // t2LDRBT, t2LDRB_POST, t2LDRB_PRE, t2LDRBi8,
+ // t2LDRHT, t2LDRH_POST, t2LDRH_PRE, t2LDRHi8,
+ // t2LDRSBT, t2LDRSB_POST, t2LDRSB_PRE, t2LDRSBi8,
+ // t2LDRSHT, t2LDRSH_POST, t2LDRSH_PRE, t2LDRSHi8,
+ // t2LDRT, t2LDR_POST, t2LDR_PRE, t2LDRi8
+ BaseOp = &MI.getOperand(1);
+ Offset = (IndexMode == ARMII::IndexModePost)
+ ? 0
+ : (IndexMode == ARMII::IndexModePre ||
+ IndexMode == ARMII::IndexModeUpd)
+ ? MI.getOperand(3).getImm()
+ : MI.getOperand(2).getImm();
+ return true;
+ case ARMII::AddrModeT2_i12:
+ // t2LDRBi12, t2LDRHi12
+ // t2LDRSBi12, t2LDRSHi12
+ // t2LDRi12
+ BaseOp = &MI.getOperand(1);
+ Offset = MI.getOperand(2).getImm();
+ return true;
+ case ARMII::AddrModeT2_i8s4:
+ // t2LDRD_POST, t2LDRD_PRE, t2LDRDi8
+ BaseOp = &MI.getOperand(2);
+ Offset = (IndexMode == ARMII::IndexModePost)
+ ? 0
+ : (IndexMode == ARMII::IndexModePre ||
+ IndexMode == ARMII::IndexModeUpd)
+ ? MI.getOperand(4).getImm()
+ : MI.getOperand(3).getImm();
+ return true;
+ case ARMII::AddrModeT1_1:
+ // tLDRBi, tLDRBr (watch out!), TLDRSB
+ case ARMII::AddrModeT1_2:
+ // tLDRHi, tLDRHr (watch out!), TLDRSH
+ case ARMII::AddrModeT1_4:
+ // tLDRi, tLDRr (watch out!)
+ BaseOp = &MI.getOperand(1);
+ Offset = MI.getOperand(2).isImm() ? MI.getOperand(2).getImm() : 0;
+ return MI.getOperand(2).isImm();
+ }
+ return false;
+}
+
+ARMBankConflictHazardRecognizer::ARMBankConflictHazardRecognizer(
+ const ScheduleDAG *DAG, int64_t CPUBankMask, bool CPUAssumeITCMConflict)
+ : ScheduleHazardRecognizer(), MF(DAG->MF), DL(DAG->MF.getDataLayout()),
+ DataMask(DataBankMask.getNumOccurrences() ? int64_t(DataBankMask)
+ : CPUBankMask),
+ AssumeITCMBankConflict(AssumeITCMConflict.getNumOccurrences()
+ ? AssumeITCMConflict
+ : CPUAssumeITCMConflict) {
+ MaxLookAhead = 1;
+}
+
+ScheduleHazardRecognizer::HazardType
+ARMBankConflictHazardRecognizer::CheckOffsets(unsigned O0, unsigned O1) {
+ return (((O0 ^ O1) & DataMask) != 0) ? NoHazard : Hazard;
+}
+
+ScheduleHazardRecognizer::HazardType
+ARMBankConflictHazardRecognizer::getHazardType(SUnit *SU, int Stalls) {
+ MachineInstr &L0 = *SU->getInstr();
+ if (!L0.mayLoad() || L0.mayStore() || L0.getNumMemOperands() != 1)
+ return NoHazard;
+
+ auto MO0 = *L0.memoperands().begin();
+ auto BaseVal0 = MO0->getValue();
+ auto BasePseudoVal0 = MO0->getPseudoValue();
+ int64_t Offset0 = 0;
+
+ if (MO0->getSize() > 4)
+ return NoHazard;
+
+ bool SPvalid = false;
+ const MachineOperand *SP = nullptr;
+ int64_t SPOffset0 = 0;
+
+ for (auto L1 : Accesses) {
+ auto MO1 = *L1->memoperands().begin();
+ auto BaseVal1 = MO1->getValue();
+ auto BasePseudoVal1 = MO1->getPseudoValue();
+ int64_t Offset1 = 0;
+
+ // Pointers to the same object
+ if (BaseVal0 && BaseVal1) {
+ const Value *Ptr0, *Ptr1;
+ Ptr0 = GetPointerBaseWithConstantOffset(BaseVal0, Offset0, DL, true);
+ Ptr1 = GetPointerBaseWithConstantOffset(BaseVal1, Offset1, DL, true);
+ if (Ptr0 == Ptr1 && Ptr0)
+ return CheckOffsets(Offset0, Offset1);
+ }
+
+ if (BasePseudoVal0 && BasePseudoVal1 &&
+ BasePseudoVal0->kind() == BasePseudoVal1->kind() &&
+ BasePseudoVal0->kind() == PseudoSourceValue::FixedStack) {
+ // Spills/fills
+ auto FS0 = cast<FixedStackPseudoSourceValue>(BasePseudoVal0);
+ auto FS1 = cast<FixedStackPseudoSourceValue>(BasePseudoVal1);
+ Offset0 = MF.getFrameInfo().getObjectOffset(FS0->getFrameIndex());
+ Offset1 = MF.getFrameInfo().getObjectOffset(FS1->getFrameIndex());
+ return CheckOffsets(Offset0, Offset1);
+ }
+
+ // Constant pools (likely in ITCM)
+ if (BasePseudoVal0 && BasePseudoVal1 &&
+ BasePseudoVal0->kind() == BasePseudoVal1->kind() &&
+ BasePseudoVal0->isConstantPool() && AssumeITCMBankConflict)
+ return Hazard;
+
+ // Is this a stack pointer-relative access? We could in general try to
+ // use "is this the same register and is it unchanged?", but the
+ // memory operand tracking is highly likely to have already found that.
+ // What we're after here is bank conflicts between different objects in
+ // the stack frame.
+ if (!SPvalid) { // set up SP
+ if (!getBaseOffset(L0, SP, SPOffset0) || SP->getReg().id() != ARM::SP)
+ SP = nullptr;
+ SPvalid = true;
+ }
+ if (SP) {
+ int64_t SPOffset1;
+ const MachineOperand *SP1;
+ if (getBaseOffset(*L1, SP1, SPOffset1) && SP1->getReg().id() == ARM::SP)
+ return CheckOffsets(SPOffset0, SPOffset1);
+ }
+ }
+
+ return NoHazard;
+}
+
+void ARMBankConflictHazardRecognizer::Reset() { Accesses.clear(); }
+
+void ARMBankConflictHazardRecognizer::EmitInstruction(SUnit *SU) {
+ MachineInstr &MI = *SU->getInstr();
+ if (!MI.mayLoad() || MI.mayStore() || MI.getNumMemOperands() != 1)
+ return;
+
+ auto MO = *MI.memoperands().begin();
+ uint64_t Size1 = MO->getSize();
+ if (Size1 > 4)
+ return;
+ Accesses.push_back(&MI);
+}
+
+void ARMBankConflictHazardRecognizer::AdvanceCycle() { Accesses.clear(); }
+
+void ARMBankConflictHazardRecognizer::RecedeCycle() { Accesses.clear(); }
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMHazardRecognizer.h b/contrib/libs/llvm12/lib/Target/ARM/ARMHazardRecognizer.h
index e6b5304488..c1f1bcd0a6 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMHazardRecognizer.h
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMHazardRecognizer.h
@@ -13,28 +13,28 @@
#ifndef LLVM_LIB_TARGET_ARM_ARMHAZARDRECOGNIZER_H
#define LLVM_LIB_TARGET_ARM_ARMHAZARDRECOGNIZER_H
-#include "ARMBaseInstrInfo.h"
-#include "llvm/ADT/BitmaskEnum.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
-#include "llvm/Support/DataTypes.h"
-#include <array>
-#include <initializer_list>
+#include "ARMBaseInstrInfo.h"
+#include "llvm/ADT/BitmaskEnum.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
+#include "llvm/Support/DataTypes.h"
+#include <array>
+#include <initializer_list>
namespace llvm {
-class DataLayout;
-class MachineFunction;
+class DataLayout;
+class MachineFunction;
class MachineInstr;
-class ScheduleDAG;
+class ScheduleDAG;
-// Hazards related to FP MLx instructions
-class ARMHazardRecognizerFPMLx : public ScheduleHazardRecognizer {
+// Hazards related to FP MLx instructions
+class ARMHazardRecognizerFPMLx : public ScheduleHazardRecognizer {
MachineInstr *LastMI = nullptr;
unsigned FpMLxStalls = 0;
public:
- ARMHazardRecognizerFPMLx() : ScheduleHazardRecognizer() { MaxLookAhead = 1; }
+ ARMHazardRecognizerFPMLx() : ScheduleHazardRecognizer() { MaxLookAhead = 1; }
HazardType getHazardType(SUnit *SU, int Stalls) override;
void Reset() override;
@@ -43,27 +43,27 @@ public:
void RecedeCycle() override;
};
-// Hazards related to bank conflicts
-class ARMBankConflictHazardRecognizer : public ScheduleHazardRecognizer {
- SmallVector<MachineInstr *, 8> Accesses;
- const MachineFunction &MF;
- const DataLayout &DL;
- int64_t DataMask;
- bool AssumeITCMBankConflict;
-
-public:
- ARMBankConflictHazardRecognizer(const ScheduleDAG *DAG, int64_t DDM,
- bool ABC);
- HazardType getHazardType(SUnit *SU, int Stalls) override;
- void Reset() override;
- void EmitInstruction(SUnit *SU) override;
- void AdvanceCycle() override;
- void RecedeCycle() override;
-
-private:
- inline HazardType CheckOffsets(unsigned O0, unsigned O1);
-};
-
+// Hazards related to bank conflicts
+class ARMBankConflictHazardRecognizer : public ScheduleHazardRecognizer {
+ SmallVector<MachineInstr *, 8> Accesses;
+ const MachineFunction &MF;
+ const DataLayout &DL;
+ int64_t DataMask;
+ bool AssumeITCMBankConflict;
+
+public:
+ ARMBankConflictHazardRecognizer(const ScheduleDAG *DAG, int64_t DDM,
+ bool ABC);
+ HazardType getHazardType(SUnit *SU, int Stalls) override;
+ void Reset() override;
+ void EmitInstruction(SUnit *SU) override;
+ void AdvanceCycle() override;
+ void RecedeCycle() override;
+
+private:
+ inline HazardType CheckOffsets(unsigned O0, unsigned O1);
+};
+
} // end namespace llvm
#endif
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMISelLowering.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMISelLowering.cpp
index 2daf77fb5e..598062672a 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMISelLowering.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMISelLowering.cpp
@@ -143,7 +143,7 @@ static cl::opt<unsigned> ConstpoolPromotionMaxTotal(
cl::desc("Maximum size of ALL constants to promote into a constant pool"),
cl::init(128));
-cl::opt<unsigned>
+cl::opt<unsigned>
MVEMaxSupportedInterleaveFactor("mve-max-interleave-factor", cl::Hidden,
cl::desc("Maximum interleave factor for MVE VLDn to generate."),
cl::init(2));
@@ -289,8 +289,8 @@ void ARMTargetLowering::addMVEVectorTypes(bool HasMVEFP) {
setOperationAction(ISD::UDIVREM, VT, Expand);
setOperationAction(ISD::SDIVREM, VT, Expand);
setOperationAction(ISD::CTPOP, VT, Expand);
- setOperationAction(ISD::SELECT, VT, Expand);
- setOperationAction(ISD::SELECT_CC, VT, Expand);
+ setOperationAction(ISD::SELECT, VT, Expand);
+ setOperationAction(ISD::SELECT_CC, VT, Expand);
// Vector reductions
setOperationAction(ISD::VECREDUCE_ADD, VT, Legal);
@@ -337,8 +337,8 @@ void ARMTargetLowering::addMVEVectorTypes(bool HasMVEFP) {
setOperationAction(ISD::SETCC, VT, Custom);
setOperationAction(ISD::MLOAD, VT, Custom);
setOperationAction(ISD::MSTORE, VT, Legal);
- setOperationAction(ISD::SELECT, VT, Expand);
- setOperationAction(ISD::SELECT_CC, VT, Expand);
+ setOperationAction(ISD::SELECT, VT, Expand);
+ setOperationAction(ISD::SELECT_CC, VT, Expand);
// Pre and Post inc are supported on loads and stores
for (unsigned im = (unsigned)ISD::PRE_INC;
@@ -443,9 +443,9 @@ void ARMTargetLowering::addMVEVectorTypes(bool HasMVEFP) {
setOperationAction(ISD::SCALAR_TO_VECTOR, VT, Expand);
setOperationAction(ISD::LOAD, VT, Custom);
setOperationAction(ISD::STORE, VT, Custom);
- setOperationAction(ISD::TRUNCATE, VT, Custom);
- setOperationAction(ISD::VSELECT, VT, Expand);
- setOperationAction(ISD::SELECT, VT, Expand);
+ setOperationAction(ISD::TRUNCATE, VT, Custom);
+ setOperationAction(ISD::VSELECT, VT, Expand);
+ setOperationAction(ISD::SELECT, VT, Expand);
}
}
@@ -994,8 +994,8 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
setTargetDAGCombine(ISD::SMAX);
setTargetDAGCombine(ISD::UMAX);
setTargetDAGCombine(ISD::FP_EXTEND);
- setTargetDAGCombine(ISD::SELECT);
- setTargetDAGCombine(ISD::SELECT_CC);
+ setTargetDAGCombine(ISD::SELECT);
+ setTargetDAGCombine(ISD::SELECT_CC);
}
if (!Subtarget->hasFP64()) {
@@ -1725,11 +1725,11 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
case ARMISD::VCVTL: return "ARMISD::VCVTL";
case ARMISD::VMULLs: return "ARMISD::VMULLs";
case ARMISD::VMULLu: return "ARMISD::VMULLu";
- case ARMISD::VQDMULH: return "ARMISD::VQDMULH";
+ case ARMISD::VQDMULH: return "ARMISD::VQDMULH";
case ARMISD::VADDVs: return "ARMISD::VADDVs";
case ARMISD::VADDVu: return "ARMISD::VADDVu";
- case ARMISD::VADDVps: return "ARMISD::VADDVps";
- case ARMISD::VADDVpu: return "ARMISD::VADDVpu";
+ case ARMISD::VADDVps: return "ARMISD::VADDVps";
+ case ARMISD::VADDVpu: return "ARMISD::VADDVpu";
case ARMISD::VADDLVs: return "ARMISD::VADDLVs";
case ARMISD::VADDLVu: return "ARMISD::VADDLVu";
case ARMISD::VADDLVAs: return "ARMISD::VADDLVAs";
@@ -1740,20 +1740,20 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
case ARMISD::VADDLVApu: return "ARMISD::VADDLVApu";
case ARMISD::VMLAVs: return "ARMISD::VMLAVs";
case ARMISD::VMLAVu: return "ARMISD::VMLAVu";
- case ARMISD::VMLAVps: return "ARMISD::VMLAVps";
- case ARMISD::VMLAVpu: return "ARMISD::VMLAVpu";
+ case ARMISD::VMLAVps: return "ARMISD::VMLAVps";
+ case ARMISD::VMLAVpu: return "ARMISD::VMLAVpu";
case ARMISD::VMLALVs: return "ARMISD::VMLALVs";
case ARMISD::VMLALVu: return "ARMISD::VMLALVu";
- case ARMISD::VMLALVps: return "ARMISD::VMLALVps";
- case ARMISD::VMLALVpu: return "ARMISD::VMLALVpu";
+ case ARMISD::VMLALVps: return "ARMISD::VMLALVps";
+ case ARMISD::VMLALVpu: return "ARMISD::VMLALVpu";
case ARMISD::VMLALVAs: return "ARMISD::VMLALVAs";
case ARMISD::VMLALVAu: return "ARMISD::VMLALVAu";
- case ARMISD::VMLALVAps: return "ARMISD::VMLALVAps";
- case ARMISD::VMLALVApu: return "ARMISD::VMLALVApu";
- case ARMISD::VMINVu: return "ARMISD::VMINVu";
- case ARMISD::VMINVs: return "ARMISD::VMINVs";
- case ARMISD::VMAXVu: return "ARMISD::VMAXVu";
- case ARMISD::VMAXVs: return "ARMISD::VMAXVs";
+ case ARMISD::VMLALVAps: return "ARMISD::VMLALVAps";
+ case ARMISD::VMLALVApu: return "ARMISD::VMLALVApu";
+ case ARMISD::VMINVu: return "ARMISD::VMINVu";
+ case ARMISD::VMINVs: return "ARMISD::VMINVs";
+ case ARMISD::VMAXVu: return "ARMISD::VMAXVu";
+ case ARMISD::VMAXVs: return "ARMISD::VMAXVs";
case ARMISD::UMAAL: return "ARMISD::UMAAL";
case ARMISD::UMLAL: return "ARMISD::UMLAL";
case ARMISD::SMLAL: return "ARMISD::SMLAL";
@@ -1777,7 +1777,7 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
case ARMISD::BFI: return "ARMISD::BFI";
case ARMISD::VORRIMM: return "ARMISD::VORRIMM";
case ARMISD::VBICIMM: return "ARMISD::VBICIMM";
- case ARMISD::VBSP: return "ARMISD::VBSP";
+ case ARMISD::VBSP: return "ARMISD::VBSP";
case ARMISD::MEMCPY: return "ARMISD::MEMCPY";
case ARMISD::VLD1DUP: return "ARMISD::VLD1DUP";
case ARMISD::VLD2DUP: return "ARMISD::VLD2DUP";
@@ -2531,9 +2531,9 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
DAG.getTargetGlobalAddress(GV, dl, PtrVt, 0, ARMII::MO_NONLAZY));
Callee = DAG.getLoad(
PtrVt, dl, DAG.getEntryNode(), Callee,
- MachinePointerInfo::getGOT(DAG.getMachineFunction()), MaybeAlign(),
- MachineMemOperand::MODereferenceable |
- MachineMemOperand::MOInvariant);
+ MachinePointerInfo::getGOT(DAG.getMachineFunction()), MaybeAlign(),
+ MachineMemOperand::MODereferenceable |
+ MachineMemOperand::MOInvariant);
} else if (Subtarget->isTargetCOFF()) {
assert(Subtarget->isTargetWindows() &&
"Windows is the only supported COFF target");
@@ -3342,7 +3342,7 @@ ARMTargetLowering::LowerGlobalTLSAddressDarwin(SDValue Op,
SDValue Chain = DAG.getEntryNode();
SDValue FuncTLVGet = DAG.getLoad(
MVT::i32, DL, Chain, DescAddr,
- MachinePointerInfo::getGOT(DAG.getMachineFunction()), Align(4),
+ MachinePointerInfo::getGOT(DAG.getMachineFunction()), Align(4),
MachineMemOperand::MONonTemporal | MachineMemOperand::MODereferenceable |
MachineMemOperand::MOInvariant);
Chain = FuncTLVGet.getValue(1);
@@ -3556,7 +3556,7 @@ static bool allUsersAreInFunction(const Value *V, const Function *F) {
while (!Worklist.empty()) {
auto *U = Worklist.pop_back_val();
if (isa<ConstantExpr>(U)) {
- append_range(Worklist, U->users());
+ append_range(Worklist, U->users());
continue;
}
@@ -4443,26 +4443,26 @@ SDValue ARMTargetLowering::LowerFormalArguments(
}
// varargs
- if (isVarArg && MFI.hasVAStart()) {
- VarArgStyleRegisters(CCInfo, DAG, dl, Chain, CCInfo.getNextStackOffset(),
+ if (isVarArg && MFI.hasVAStart()) {
+ VarArgStyleRegisters(CCInfo, DAG, dl, Chain, CCInfo.getNextStackOffset(),
TotalArgRegsSaveSize);
- if (AFI->isCmseNSEntryFunction()) {
- DiagnosticInfoUnsupported Diag(
- DAG.getMachineFunction().getFunction(),
- "secure entry function must not be variadic", dl.getDebugLoc());
- DAG.getContext()->diagnose(Diag);
- }
- }
+ if (AFI->isCmseNSEntryFunction()) {
+ DiagnosticInfoUnsupported Diag(
+ DAG.getMachineFunction().getFunction(),
+ "secure entry function must not be variadic", dl.getDebugLoc());
+ DAG.getContext()->diagnose(Diag);
+ }
+ }
AFI->setArgumentStackSize(CCInfo.getNextStackOffset());
- if (CCInfo.getNextStackOffset() > 0 && AFI->isCmseNSEntryFunction()) {
- DiagnosticInfoUnsupported Diag(
- DAG.getMachineFunction().getFunction(),
- "secure entry function requires arguments on stack", dl.getDebugLoc());
- DAG.getContext()->diagnose(Diag);
- }
-
+ if (CCInfo.getNextStackOffset() > 0 && AFI->isCmseNSEntryFunction()) {
+ DiagnosticInfoUnsupported Diag(
+ DAG.getMachineFunction().getFunction(),
+ "secure entry function requires arguments on stack", dl.getDebugLoc());
+ DAG.getContext()->diagnose(Diag);
+ }
+
return Chain;
}
@@ -5034,68 +5034,68 @@ static bool isLowerSaturate(const SDValue LHS, const SDValue RHS,
// x < k ? (x < -k ? -k : x) : k
// etc.
//
-// LLVM canonicalizes these to either a min(max()) or a max(min())
-// pattern. This function tries to match one of these and will return a SSAT
-// node if successful.
+// LLVM canonicalizes these to either a min(max()) or a max(min())
+// pattern. This function tries to match one of these and will return a SSAT
+// node if successful.
//
-// USAT works similarily to SSAT but bounds on the interval [0, k] where k + 1
-// is a power of 2.
-static SDValue LowerSaturatingConditional(SDValue Op, SelectionDAG &DAG) {
- EVT VT = Op.getValueType();
- SDValue V1 = Op.getOperand(0);
- SDValue K1 = Op.getOperand(1);
+// USAT works similarily to SSAT but bounds on the interval [0, k] where k + 1
+// is a power of 2.
+static SDValue LowerSaturatingConditional(SDValue Op, SelectionDAG &DAG) {
+ EVT VT = Op.getValueType();
+ SDValue V1 = Op.getOperand(0);
+ SDValue K1 = Op.getOperand(1);
SDValue TrueVal1 = Op.getOperand(2);
SDValue FalseVal1 = Op.getOperand(3);
ISD::CondCode CC1 = cast<CondCodeSDNode>(Op.getOperand(4))->get();
const SDValue Op2 = isa<ConstantSDNode>(TrueVal1) ? FalseVal1 : TrueVal1;
if (Op2.getOpcode() != ISD::SELECT_CC)
- return SDValue();
+ return SDValue();
- SDValue V2 = Op2.getOperand(0);
- SDValue K2 = Op2.getOperand(1);
+ SDValue V2 = Op2.getOperand(0);
+ SDValue K2 = Op2.getOperand(1);
SDValue TrueVal2 = Op2.getOperand(2);
SDValue FalseVal2 = Op2.getOperand(3);
ISD::CondCode CC2 = cast<CondCodeSDNode>(Op2.getOperand(4))->get();
- SDValue V1Tmp = V1;
- SDValue V2Tmp = V2;
+ SDValue V1Tmp = V1;
+ SDValue V2Tmp = V2;
- // Check that the registers and the constants match a max(min()) or min(max())
- // pattern
- if (V1Tmp != TrueVal1 || V2Tmp != TrueVal2 || K1 != FalseVal1 ||
- K2 != FalseVal2 ||
- !((isGTorGE(CC1) && isLTorLE(CC2)) || (isLTorLE(CC1) && isGTorGE(CC2))))
- return SDValue();
+ // Check that the registers and the constants match a max(min()) or min(max())
+ // pattern
+ if (V1Tmp != TrueVal1 || V2Tmp != TrueVal2 || K1 != FalseVal1 ||
+ K2 != FalseVal2 ||
+ !((isGTorGE(CC1) && isLTorLE(CC2)) || (isLTorLE(CC1) && isGTorGE(CC2))))
+ return SDValue();
// Check that the constant in the lower-bound check is
// the opposite of the constant in the upper-bound check
// in 1's complement.
- if (!isa<ConstantSDNode>(K1) || !isa<ConstantSDNode>(K2))
- return SDValue();
-
- int64_t Val1 = cast<ConstantSDNode>(K1)->getSExtValue();
- int64_t Val2 = cast<ConstantSDNode>(K2)->getSExtValue();
+ if (!isa<ConstantSDNode>(K1) || !isa<ConstantSDNode>(K2))
+ return SDValue();
+
+ int64_t Val1 = cast<ConstantSDNode>(K1)->getSExtValue();
+ int64_t Val2 = cast<ConstantSDNode>(K2)->getSExtValue();
int64_t PosVal = std::max(Val1, Val2);
int64_t NegVal = std::min(Val1, Val2);
- if (!((Val1 > Val2 && isLTorLE(CC1)) || (Val1 < Val2 && isLTorLE(CC2))) ||
- !isPowerOf2_64(PosVal + 1))
- return SDValue();
+ if (!((Val1 > Val2 && isLTorLE(CC1)) || (Val1 < Val2 && isLTorLE(CC2))) ||
+ !isPowerOf2_64(PosVal + 1))
+ return SDValue();
- // Handle the difference between USAT (unsigned) and SSAT (signed)
- // saturation
- // At this point, PosVal is guaranteed to be positive
- uint64_t K = PosVal;
- SDLoc dl(Op);
- if (Val1 == ~Val2)
- return DAG.getNode(ARMISD::SSAT, dl, VT, V2Tmp,
- DAG.getConstant(countTrailingOnes(K), dl, VT));
- if (NegVal == 0)
- return DAG.getNode(ARMISD::USAT, dl, VT, V2Tmp,
- DAG.getConstant(countTrailingOnes(K), dl, VT));
+ // Handle the difference between USAT (unsigned) and SSAT (signed)
+ // saturation
+ // At this point, PosVal is guaranteed to be positive
+ uint64_t K = PosVal;
+ SDLoc dl(Op);
+ if (Val1 == ~Val2)
+ return DAG.getNode(ARMISD::SSAT, dl, VT, V2Tmp,
+ DAG.getConstant(countTrailingOnes(K), dl, VT));
+ if (NegVal == 0)
+ return DAG.getNode(ARMISD::USAT, dl, VT, V2Tmp,
+ DAG.getConstant(countTrailingOnes(K), dl, VT));
- return SDValue();
+ return SDValue();
}
// Check if a condition of the type x < k ? k : x can be converted into a
@@ -5155,9 +5155,9 @@ SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
SDLoc dl(Op);
// Try to convert two saturating conditional selects into a single SSAT
- if ((!Subtarget->isThumb() && Subtarget->hasV6Ops()) || Subtarget->isThumb2())
- if (SDValue SatValue = LowerSaturatingConditional(Op, DAG))
- return SatValue;
+ if ((!Subtarget->isThumb() && Subtarget->hasV6Ops()) || Subtarget->isThumb2())
+ if (SDValue SatValue = LowerSaturatingConditional(Op, DAG))
+ return SatValue;
// Try to convert expressions of the form x < k ? k : x (and similar forms)
// into more efficient bit operations, which is possible when k is 0 or -1
@@ -5166,7 +5166,7 @@ SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
// instructions.
// Only allow this transformation on full-width (32-bit) operations
SDValue LowerSatConstant;
- SDValue SatValue;
+ SDValue SatValue;
if (VT == MVT::i32 &&
isLowerSaturatingConditional(Op, SatValue, LowerSatConstant)) {
SDValue ShiftV = DAG.getNode(ISD::SRA, dl, VT, SatValue,
@@ -7750,19 +7750,19 @@ SDValue ARMTargetLowering::ReconstructShuffle(SDValue Op,
for (auto &Src : Sources) {
EVT SrcVT = Src.ShuffleVec.getValueType();
- uint64_t SrcVTSize = SrcVT.getFixedSizeInBits();
- uint64_t VTSize = VT.getFixedSizeInBits();
- if (SrcVTSize == VTSize)
+ uint64_t SrcVTSize = SrcVT.getFixedSizeInBits();
+ uint64_t VTSize = VT.getFixedSizeInBits();
+ if (SrcVTSize == VTSize)
continue;
// This stage of the search produces a source with the same element type as
// the original, but with a total width matching the BUILD_VECTOR output.
EVT EltVT = SrcVT.getVectorElementType();
- unsigned NumSrcElts = VTSize / EltVT.getFixedSizeInBits();
+ unsigned NumSrcElts = VTSize / EltVT.getFixedSizeInBits();
EVT DestVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumSrcElts);
- if (SrcVTSize < VTSize) {
- if (2 * SrcVTSize != VTSize)
+ if (SrcVTSize < VTSize) {
+ if (2 * SrcVTSize != VTSize)
return SDValue();
// We can pad out the smaller vector for free, so if it's part of a
// shuffle...
@@ -7772,7 +7772,7 @@ SDValue ARMTargetLowering::ReconstructShuffle(SDValue Op,
continue;
}
- if (SrcVTSize != 2 * VTSize)
+ if (SrcVTSize != 2 * VTSize)
return SDValue();
if (Src.MaxElt - Src.MinElt >= NumSrcElts) {
@@ -7840,7 +7840,7 @@ SDValue ARMTargetLowering::ReconstructShuffle(SDValue Op,
// trunc. So only std::min(SrcBits, DestBits) actually get defined in this
// segment.
EVT OrigEltTy = Entry.getOperand(0).getValueType().getVectorElementType();
- int BitsDefined = std::min(OrigEltTy.getScalarSizeInBits(),
+ int BitsDefined = std::min(OrigEltTy.getScalarSizeInBits(),
VT.getScalarSizeInBits());
int LanesDefined = BitsDefined / BitsPerShuffleLane;
@@ -8642,23 +8642,23 @@ static SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG,
DAG.getConstant(ARMCC::NE, dl, MVT::i32));
}
-// Turn a truncate into a predicate (an i1 vector) into icmp(and(x, 1), 0).
-static SDValue LowerTruncatei1(SDValue N, SelectionDAG &DAG,
- const ARMSubtarget *ST) {
- assert(ST->hasMVEIntegerOps() && "Expected MVE!");
- EVT VT = N.getValueType();
- assert((VT == MVT::v16i1 || VT == MVT::v8i1 || VT == MVT::v4i1) &&
- "Expected a vector i1 type!");
- SDValue Op = N.getOperand(0);
- EVT FromVT = Op.getValueType();
- SDLoc DL(N);
-
- SDValue And =
- DAG.getNode(ISD::AND, DL, FromVT, Op, DAG.getConstant(1, DL, FromVT));
- return DAG.getNode(ISD::SETCC, DL, VT, And, DAG.getConstant(0, DL, FromVT),
- DAG.getCondCode(ISD::SETNE));
-}
-
+// Turn a truncate into a predicate (an i1 vector) into icmp(and(x, 1), 0).
+static SDValue LowerTruncatei1(SDValue N, SelectionDAG &DAG,
+ const ARMSubtarget *ST) {
+ assert(ST->hasMVEIntegerOps() && "Expected MVE!");
+ EVT VT = N.getValueType();
+ assert((VT == MVT::v16i1 || VT == MVT::v8i1 || VT == MVT::v4i1) &&
+ "Expected a vector i1 type!");
+ SDValue Op = N.getOperand(0);
+ EVT FromVT = Op.getValueType();
+ SDLoc DL(N);
+
+ SDValue And =
+ DAG.getNode(ISD::AND, DL, FromVT, Op, DAG.getConstant(1, DL, FromVT));
+ return DAG.getNode(ISD::SETCC, DL, VT, And, DAG.getConstant(0, DL, FromVT),
+ DAG.getCondCode(ISD::SETNE));
+}
+
/// isExtendedBUILD_VECTOR - Check if N is a constant BUILD_VECTOR where each
/// element has been zero/sign-extended, depending on the isSigned parameter,
/// from an integer type half its size.
@@ -8723,11 +8723,11 @@ static bool isSignExtended(SDNode *N, SelectionDAG &DAG) {
return false;
}
-/// isZeroExtended - Check if a node is a vector value that is zero-extended (or
-/// any-extended) or a constant BUILD_VECTOR with zero-extended elements.
+/// isZeroExtended - Check if a node is a vector value that is zero-extended (or
+/// any-extended) or a constant BUILD_VECTOR with zero-extended elements.
static bool isZeroExtended(SDNode *N, SelectionDAG &DAG) {
- if (N->getOpcode() == ISD::ZERO_EXTEND || N->getOpcode() == ISD::ANY_EXTEND ||
- ISD::isZEXTLoad(N))
+ if (N->getOpcode() == ISD::ZERO_EXTEND || N->getOpcode() == ISD::ANY_EXTEND ||
+ ISD::isZEXTLoad(N))
return true;
if (isExtendedBUILD_VECTOR(N, DAG, false))
return true;
@@ -8795,14 +8795,14 @@ static SDValue SkipLoadExtensionForVMULL(LoadSDNode *LD, SelectionDAG& DAG) {
}
/// SkipExtensionForVMULL - For a node that is a SIGN_EXTEND, ZERO_EXTEND,
-/// ANY_EXTEND, extending load, or BUILD_VECTOR with extended elements, return
-/// the unextended value. The unextended vector should be 64 bits so that it can
+/// ANY_EXTEND, extending load, or BUILD_VECTOR with extended elements, return
+/// the unextended value. The unextended vector should be 64 bits so that it can
/// be used as an operand to a VMULL instruction. If the original vector size
/// before extension is less than 64 bits we add a an extension to resize
/// the vector to 64 bits.
static SDValue SkipExtensionForVMULL(SDNode *N, SelectionDAG &DAG) {
- if (N->getOpcode() == ISD::SIGN_EXTEND ||
- N->getOpcode() == ISD::ZERO_EXTEND || N->getOpcode() == ISD::ANY_EXTEND)
+ if (N->getOpcode() == ISD::SIGN_EXTEND ||
+ N->getOpcode() == ISD::ZERO_EXTEND || N->getOpcode() == ISD::ANY_EXTEND)
return AddRequiredExtensionForVMULL(N->getOperand(0), DAG,
N->getOperand(0)->getValueType(0),
N->getValueType(0),
@@ -9770,7 +9770,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::INSERT_VECTOR_ELT: return LowerINSERT_VECTOR_ELT(Op, DAG);
case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG, Subtarget);
case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG, Subtarget);
- case ISD::TRUNCATE: return LowerTruncatei1(Op, DAG, Subtarget);
+ case ISD::TRUNCATE: return LowerTruncatei1(Op, DAG, Subtarget);
case ISD::FLT_ROUNDS_: return LowerFLT_ROUNDS_(Op, DAG);
case ISD::MUL: return LowerMUL(Op, DAG);
case ISD::SDIV:
@@ -10403,7 +10403,7 @@ void ARMTargetLowering::EmitSjLjDispatchBlock(MachineInstr &MI,
// Remove the landing pad successor from the invoke block and replace it
// with the new dispatch block.
- SmallVector<MachineBasicBlock*, 4> Successors(BB->successors());
+ SmallVector<MachineBasicBlock*, 4> Successors(BB->successors());
while (!Successors.empty()) {
MachineBasicBlock *SMBB = Successors.pop_back_val();
if (SMBB->isEHPad()) {
@@ -10887,7 +10887,7 @@ ARMTargetLowering::EmitLowered__chkstk(MachineInstr &MI,
BuildMI(*MBB, MI, DL, TII.get(ARM::t2MOVi32imm), Reg)
.addExternalSymbol("__chkstk");
- BuildMI(*MBB, MI, DL, TII.get(gettBLXrOpcode(*MBB->getParent())))
+ BuildMI(*MBB, MI, DL, TII.get(gettBLXrOpcode(*MBB->getParent())))
.add(predOps(ARMCC::AL))
.addReg(Reg, RegState::Kill)
.addReg(ARM::R4, RegState::Implicit | RegState::Kill)
@@ -11266,14 +11266,14 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
return EmitLowered__chkstk(MI, BB);
case ARM::WIN__DBZCHK:
return EmitLowered__dbzchk(MI, BB);
- case ARM::t2DoLoopStart:
- // We are just here to set a register allocation hint, prefering lr for the
- // input register to make it more likely to be movable and removable, later
- // in the pipeline.
- Register R = MI.getOperand(1).getReg();
- MachineFunction *MF = MI.getParent()->getParent();
- MF->getRegInfo().setRegAllocationHint(R, ARMRI::RegLR, 0);
- return BB;
+ case ARM::t2DoLoopStart:
+ // We are just here to set a register allocation hint, prefering lr for the
+ // input register to make it more likely to be movable and removable, later
+ // in the pipeline.
+ Register R = MI.getOperand(1).getReg();
+ MachineFunction *MF = MI.getParent()->getParent();
+ MF->getRegInfo().setRegAllocationHint(R, ARMRI::RegLR, 0);
+ return BB;
}
}
@@ -12115,198 +12115,198 @@ static SDValue PerformAddeSubeCombine(SDNode *N,
return SDValue();
}
-static SDValue PerformSELECTCombine(SDNode *N,
- TargetLowering::DAGCombinerInfo &DCI,
- const ARMSubtarget *Subtarget) {
- if (!Subtarget->hasMVEIntegerOps())
- return SDValue();
-
- SDLoc dl(N);
- SDValue SetCC;
- SDValue LHS;
- SDValue RHS;
- ISD::CondCode CC;
- SDValue TrueVal;
- SDValue FalseVal;
-
- if (N->getOpcode() == ISD::SELECT &&
- N->getOperand(0)->getOpcode() == ISD::SETCC) {
- SetCC = N->getOperand(0);
- LHS = SetCC->getOperand(0);
- RHS = SetCC->getOperand(1);
- CC = cast<CondCodeSDNode>(SetCC->getOperand(2))->get();
- TrueVal = N->getOperand(1);
- FalseVal = N->getOperand(2);
- } else if (N->getOpcode() == ISD::SELECT_CC) {
- LHS = N->getOperand(0);
- RHS = N->getOperand(1);
- CC = cast<CondCodeSDNode>(N->getOperand(4))->get();
- TrueVal = N->getOperand(2);
- FalseVal = N->getOperand(3);
- } else {
- return SDValue();
- }
-
- unsigned int Opcode = 0;
- if ((TrueVal->getOpcode() == ISD::VECREDUCE_UMIN ||
- FalseVal->getOpcode() == ISD::VECREDUCE_UMIN) &&
- (CC == ISD::SETULT || CC == ISD::SETUGT)) {
- Opcode = ARMISD::VMINVu;
- if (CC == ISD::SETUGT)
- std::swap(TrueVal, FalseVal);
- } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_SMIN ||
- FalseVal->getOpcode() == ISD::VECREDUCE_SMIN) &&
- (CC == ISD::SETLT || CC == ISD::SETGT)) {
- Opcode = ARMISD::VMINVs;
- if (CC == ISD::SETGT)
- std::swap(TrueVal, FalseVal);
- } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_UMAX ||
- FalseVal->getOpcode() == ISD::VECREDUCE_UMAX) &&
- (CC == ISD::SETUGT || CC == ISD::SETULT)) {
- Opcode = ARMISD::VMAXVu;
- if (CC == ISD::SETULT)
- std::swap(TrueVal, FalseVal);
- } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_SMAX ||
- FalseVal->getOpcode() == ISD::VECREDUCE_SMAX) &&
- (CC == ISD::SETGT || CC == ISD::SETLT)) {
- Opcode = ARMISD::VMAXVs;
- if (CC == ISD::SETLT)
- std::swap(TrueVal, FalseVal);
- } else
- return SDValue();
-
- // Normalise to the right hand side being the vector reduction
- switch (TrueVal->getOpcode()) {
- case ISD::VECREDUCE_UMIN:
- case ISD::VECREDUCE_SMIN:
- case ISD::VECREDUCE_UMAX:
- case ISD::VECREDUCE_SMAX:
- std::swap(LHS, RHS);
- std::swap(TrueVal, FalseVal);
- break;
- }
-
- EVT VectorType = FalseVal->getOperand(0).getValueType();
-
- if (VectorType != MVT::v16i8 && VectorType != MVT::v8i16 &&
- VectorType != MVT::v4i32)
- return SDValue();
-
- EVT VectorScalarType = VectorType.getVectorElementType();
-
- // The values being selected must also be the ones being compared
- if (TrueVal != LHS || FalseVal != RHS)
- return SDValue();
-
- EVT LeftType = LHS->getValueType(0);
- EVT RightType = RHS->getValueType(0);
-
- // The types must match the reduced type too
- if (LeftType != VectorScalarType || RightType != VectorScalarType)
- return SDValue();
-
- // Legalise the scalar to an i32
- if (VectorScalarType != MVT::i32)
- LHS = DCI.DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, LHS);
-
- // Generate the reduction as an i32 for legalisation purposes
- auto Reduction =
- DCI.DAG.getNode(Opcode, dl, MVT::i32, LHS, RHS->getOperand(0));
-
- // The result isn't actually an i32 so truncate it back to its original type
- if (VectorScalarType != MVT::i32)
- Reduction = DCI.DAG.getNode(ISD::TRUNCATE, dl, VectorScalarType, Reduction);
-
- return Reduction;
-}
-
-// A special combine for the vqdmulh family of instructions. This is one of the
-// potential set of patterns that could patch this instruction. The base pattern
-// you would expect to be min(max(ashr(mul(mul(sext(x), 2), sext(y)), 16))).
-// This matches the different min(max(ashr(mul(mul(sext(x), sext(y)), 2), 16))),
-// which llvm will have optimized to min(ashr(mul(sext(x), sext(y)), 15))) as
-// the max is unnecessary.
-static SDValue PerformVQDMULHCombine(SDNode *N, SelectionDAG &DAG) {
- EVT VT = N->getValueType(0);
- SDValue Shft;
- ConstantSDNode *Clamp;
-
- if (N->getOpcode() == ISD::SMIN) {
- Shft = N->getOperand(0);
- Clamp = isConstOrConstSplat(N->getOperand(1));
- } else if (N->getOpcode() == ISD::VSELECT) {
- // Detect a SMIN, which for an i64 node will be a vselect/setcc, not a smin.
- SDValue Cmp = N->getOperand(0);
- if (Cmp.getOpcode() != ISD::SETCC ||
- cast<CondCodeSDNode>(Cmp.getOperand(2))->get() != ISD::SETLT ||
- Cmp.getOperand(0) != N->getOperand(1) ||
- Cmp.getOperand(1) != N->getOperand(2))
- return SDValue();
- Shft = N->getOperand(1);
- Clamp = isConstOrConstSplat(N->getOperand(2));
- } else
- return SDValue();
-
- if (!Clamp)
- return SDValue();
-
- MVT ScalarType;
- int ShftAmt = 0;
- switch (Clamp->getSExtValue()) {
- case (1 << 7) - 1:
- ScalarType = MVT::i8;
- ShftAmt = 7;
- break;
- case (1 << 15) - 1:
- ScalarType = MVT::i16;
- ShftAmt = 15;
- break;
- case (1ULL << 31) - 1:
- ScalarType = MVT::i32;
- ShftAmt = 31;
- break;
- default:
- return SDValue();
- }
-
- if (Shft.getOpcode() != ISD::SRA)
- return SDValue();
- ConstantSDNode *N1 = isConstOrConstSplat(Shft.getOperand(1));
- if (!N1 || N1->getSExtValue() != ShftAmt)
- return SDValue();
-
- SDValue Mul = Shft.getOperand(0);
- if (Mul.getOpcode() != ISD::MUL)
- return SDValue();
-
- SDValue Ext0 = Mul.getOperand(0);
- SDValue Ext1 = Mul.getOperand(1);
- if (Ext0.getOpcode() != ISD::SIGN_EXTEND ||
- Ext1.getOpcode() != ISD::SIGN_EXTEND)
- return SDValue();
- EVT VecVT = Ext0.getOperand(0).getValueType();
- if (VecVT != MVT::v4i32 && VecVT != MVT::v8i16 && VecVT != MVT::v16i8)
- return SDValue();
- if (Ext1.getOperand(0).getValueType() != VecVT ||
- VecVT.getScalarType() != ScalarType ||
- VT.getScalarSizeInBits() < ScalarType.getScalarSizeInBits() * 2)
- return SDValue();
-
- SDLoc DL(Mul);
- SDValue VQDMULH = DAG.getNode(ARMISD::VQDMULH, DL, VecVT, Ext0.getOperand(0),
- Ext1.getOperand(0));
- return DAG.getNode(ISD::SIGN_EXTEND, DL, VT, VQDMULH);
-}
-
+static SDValue PerformSELECTCombine(SDNode *N,
+ TargetLowering::DAGCombinerInfo &DCI,
+ const ARMSubtarget *Subtarget) {
+ if (!Subtarget->hasMVEIntegerOps())
+ return SDValue();
+
+ SDLoc dl(N);
+ SDValue SetCC;
+ SDValue LHS;
+ SDValue RHS;
+ ISD::CondCode CC;
+ SDValue TrueVal;
+ SDValue FalseVal;
+
+ if (N->getOpcode() == ISD::SELECT &&
+ N->getOperand(0)->getOpcode() == ISD::SETCC) {
+ SetCC = N->getOperand(0);
+ LHS = SetCC->getOperand(0);
+ RHS = SetCC->getOperand(1);
+ CC = cast<CondCodeSDNode>(SetCC->getOperand(2))->get();
+ TrueVal = N->getOperand(1);
+ FalseVal = N->getOperand(2);
+ } else if (N->getOpcode() == ISD::SELECT_CC) {
+ LHS = N->getOperand(0);
+ RHS = N->getOperand(1);
+ CC = cast<CondCodeSDNode>(N->getOperand(4))->get();
+ TrueVal = N->getOperand(2);
+ FalseVal = N->getOperand(3);
+ } else {
+ return SDValue();
+ }
+
+ unsigned int Opcode = 0;
+ if ((TrueVal->getOpcode() == ISD::VECREDUCE_UMIN ||
+ FalseVal->getOpcode() == ISD::VECREDUCE_UMIN) &&
+ (CC == ISD::SETULT || CC == ISD::SETUGT)) {
+ Opcode = ARMISD::VMINVu;
+ if (CC == ISD::SETUGT)
+ std::swap(TrueVal, FalseVal);
+ } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_SMIN ||
+ FalseVal->getOpcode() == ISD::VECREDUCE_SMIN) &&
+ (CC == ISD::SETLT || CC == ISD::SETGT)) {
+ Opcode = ARMISD::VMINVs;
+ if (CC == ISD::SETGT)
+ std::swap(TrueVal, FalseVal);
+ } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_UMAX ||
+ FalseVal->getOpcode() == ISD::VECREDUCE_UMAX) &&
+ (CC == ISD::SETUGT || CC == ISD::SETULT)) {
+ Opcode = ARMISD::VMAXVu;
+ if (CC == ISD::SETULT)
+ std::swap(TrueVal, FalseVal);
+ } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_SMAX ||
+ FalseVal->getOpcode() == ISD::VECREDUCE_SMAX) &&
+ (CC == ISD::SETGT || CC == ISD::SETLT)) {
+ Opcode = ARMISD::VMAXVs;
+ if (CC == ISD::SETLT)
+ std::swap(TrueVal, FalseVal);
+ } else
+ return SDValue();
+
+ // Normalise to the right hand side being the vector reduction
+ switch (TrueVal->getOpcode()) {
+ case ISD::VECREDUCE_UMIN:
+ case ISD::VECREDUCE_SMIN:
+ case ISD::VECREDUCE_UMAX:
+ case ISD::VECREDUCE_SMAX:
+ std::swap(LHS, RHS);
+ std::swap(TrueVal, FalseVal);
+ break;
+ }
+
+ EVT VectorType = FalseVal->getOperand(0).getValueType();
+
+ if (VectorType != MVT::v16i8 && VectorType != MVT::v8i16 &&
+ VectorType != MVT::v4i32)
+ return SDValue();
+
+ EVT VectorScalarType = VectorType.getVectorElementType();
+
+ // The values being selected must also be the ones being compared
+ if (TrueVal != LHS || FalseVal != RHS)
+ return SDValue();
+
+ EVT LeftType = LHS->getValueType(0);
+ EVT RightType = RHS->getValueType(0);
+
+ // The types must match the reduced type too
+ if (LeftType != VectorScalarType || RightType != VectorScalarType)
+ return SDValue();
+
+ // Legalise the scalar to an i32
+ if (VectorScalarType != MVT::i32)
+ LHS = DCI.DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, LHS);
+
+ // Generate the reduction as an i32 for legalisation purposes
+ auto Reduction =
+ DCI.DAG.getNode(Opcode, dl, MVT::i32, LHS, RHS->getOperand(0));
+
+ // The result isn't actually an i32 so truncate it back to its original type
+ if (VectorScalarType != MVT::i32)
+ Reduction = DCI.DAG.getNode(ISD::TRUNCATE, dl, VectorScalarType, Reduction);
+
+ return Reduction;
+}
+
+// A special combine for the vqdmulh family of instructions. This is one of the
+// potential set of patterns that could patch this instruction. The base pattern
+// you would expect to be min(max(ashr(mul(mul(sext(x), 2), sext(y)), 16))).
+// This matches the different min(max(ashr(mul(mul(sext(x), sext(y)), 2), 16))),
+// which llvm will have optimized to min(ashr(mul(sext(x), sext(y)), 15))) as
+// the max is unnecessary.
+static SDValue PerformVQDMULHCombine(SDNode *N, SelectionDAG &DAG) {
+ EVT VT = N->getValueType(0);
+ SDValue Shft;
+ ConstantSDNode *Clamp;
+
+ if (N->getOpcode() == ISD::SMIN) {
+ Shft = N->getOperand(0);
+ Clamp = isConstOrConstSplat(N->getOperand(1));
+ } else if (N->getOpcode() == ISD::VSELECT) {
+ // Detect a SMIN, which for an i64 node will be a vselect/setcc, not a smin.
+ SDValue Cmp = N->getOperand(0);
+ if (Cmp.getOpcode() != ISD::SETCC ||
+ cast<CondCodeSDNode>(Cmp.getOperand(2))->get() != ISD::SETLT ||
+ Cmp.getOperand(0) != N->getOperand(1) ||
+ Cmp.getOperand(1) != N->getOperand(2))
+ return SDValue();
+ Shft = N->getOperand(1);
+ Clamp = isConstOrConstSplat(N->getOperand(2));
+ } else
+ return SDValue();
+
+ if (!Clamp)
+ return SDValue();
+
+ MVT ScalarType;
+ int ShftAmt = 0;
+ switch (Clamp->getSExtValue()) {
+ case (1 << 7) - 1:
+ ScalarType = MVT::i8;
+ ShftAmt = 7;
+ break;
+ case (1 << 15) - 1:
+ ScalarType = MVT::i16;
+ ShftAmt = 15;
+ break;
+ case (1ULL << 31) - 1:
+ ScalarType = MVT::i32;
+ ShftAmt = 31;
+ break;
+ default:
+ return SDValue();
+ }
+
+ if (Shft.getOpcode() != ISD::SRA)
+ return SDValue();
+ ConstantSDNode *N1 = isConstOrConstSplat(Shft.getOperand(1));
+ if (!N1 || N1->getSExtValue() != ShftAmt)
+ return SDValue();
+
+ SDValue Mul = Shft.getOperand(0);
+ if (Mul.getOpcode() != ISD::MUL)
+ return SDValue();
+
+ SDValue Ext0 = Mul.getOperand(0);
+ SDValue Ext1 = Mul.getOperand(1);
+ if (Ext0.getOpcode() != ISD::SIGN_EXTEND ||
+ Ext1.getOpcode() != ISD::SIGN_EXTEND)
+ return SDValue();
+ EVT VecVT = Ext0.getOperand(0).getValueType();
+ if (VecVT != MVT::v4i32 && VecVT != MVT::v8i16 && VecVT != MVT::v16i8)
+ return SDValue();
+ if (Ext1.getOperand(0).getValueType() != VecVT ||
+ VecVT.getScalarType() != ScalarType ||
+ VT.getScalarSizeInBits() < ScalarType.getScalarSizeInBits() * 2)
+ return SDValue();
+
+ SDLoc DL(Mul);
+ SDValue VQDMULH = DAG.getNode(ARMISD::VQDMULH, DL, VecVT, Ext0.getOperand(0),
+ Ext1.getOperand(0));
+ return DAG.getNode(ISD::SIGN_EXTEND, DL, VT, VQDMULH);
+}
+
static SDValue PerformVSELECTCombine(SDNode *N,
TargetLowering::DAGCombinerInfo &DCI,
const ARMSubtarget *Subtarget) {
- if (!Subtarget->hasMVEIntegerOps())
- return SDValue();
-
- if (SDValue V = PerformVQDMULHCombine(N, DCI.DAG))
- return V;
-
+ if (!Subtarget->hasMVEIntegerOps())
+ return SDValue();
+
+ if (SDValue V = PerformVQDMULHCombine(N, DCI.DAG))
+ return V;
+
// Transforms vselect(not(cond), lhs, rhs) into vselect(cond, rhs, lhs).
//
// We need to re-implement this optimization here as the implementation in the
@@ -12456,14 +12456,14 @@ static SDValue PerformADDVecReduce(SDNode *N,
return M;
if (SDValue M = MakeVecReduce(ARMISD::VMLALVu, ARMISD::VMLALVAu, N1, N0))
return M;
- if (SDValue M = MakeVecReduce(ARMISD::VMLALVps, ARMISD::VMLALVAps, N0, N1))
- return M;
- if (SDValue M = MakeVecReduce(ARMISD::VMLALVpu, ARMISD::VMLALVApu, N0, N1))
- return M;
- if (SDValue M = MakeVecReduce(ARMISD::VMLALVps, ARMISD::VMLALVAps, N1, N0))
- return M;
- if (SDValue M = MakeVecReduce(ARMISD::VMLALVpu, ARMISD::VMLALVApu, N1, N0))
- return M;
+ if (SDValue M = MakeVecReduce(ARMISD::VMLALVps, ARMISD::VMLALVAps, N0, N1))
+ return M;
+ if (SDValue M = MakeVecReduce(ARMISD::VMLALVpu, ARMISD::VMLALVApu, N0, N1))
+ return M;
+ if (SDValue M = MakeVecReduce(ARMISD::VMLALVps, ARMISD::VMLALVAps, N1, N0))
+ return M;
+ if (SDValue M = MakeVecReduce(ARMISD::VMLALVpu, ARMISD::VMLALVApu, N1, N0))
+ return M;
return SDValue();
}
@@ -13358,7 +13358,7 @@ static SDValue PerformORCombine(SDNode *N,
// Canonicalize the vector type to make instruction selection
// simpler.
EVT CanonicalVT = VT.is128BitVector() ? MVT::v4i32 : MVT::v2i32;
- SDValue Result = DAG.getNode(ARMISD::VBSP, dl, CanonicalVT,
+ SDValue Result = DAG.getNode(ARMISD::VBSP, dl, CanonicalVT,
N0->getOperand(1),
N0->getOperand(0),
N1->getOperand(0));
@@ -13669,12 +13669,12 @@ static SDValue PerformVMOVrhCombine(SDNode *N,
SDValue N0 = N->getOperand(0);
EVT VT = N->getValueType(0);
- // fold (VMOVrh (fpconst x)) -> const x
- if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(N0)) {
- APFloat V = C->getValueAPF();
- return DCI.DAG.getConstant(V.bitcastToAPInt().getZExtValue(), SDLoc(N), VT);
- }
-
+ // fold (VMOVrh (fpconst x)) -> const x
+ if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(N0)) {
+ APFloat V = C->getValueAPF();
+ return DCI.DAG.getConstant(V.bitcastToAPInt().getZExtValue(), SDLoc(N), VT);
+ }
+
// fold (VMOVrh (load x)) -> (zextload (i16*)x)
if (ISD::isNormalLoad(N0.getNode()) && N0.hasOneUse()) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
@@ -13849,23 +13849,23 @@ PerformPREDICATE_CASTCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI) {
return DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT, Op->getOperand(0));
}
- // Turn pred_cast(xor x, -1) into xor(pred_cast x, -1), in order to produce
- // more VPNOT which might get folded as else predicates.
- if (Op.getValueType() == MVT::i32 && isBitwiseNot(Op)) {
- SDValue X =
- DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT, Op->getOperand(0));
- SDValue C = DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT,
- DCI.DAG.getConstant(65535, dl, MVT::i32));
- return DCI.DAG.getNode(ISD::XOR, dl, VT, X, C);
- }
-
- // Only the bottom 16 bits of the source register are used.
- if (Op.getValueType() == MVT::i32) {
- APInt DemandedMask = APInt::getLowBitsSet(32, 16);
- const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
- if (TLI.SimplifyDemandedBits(Op, DemandedMask, DCI))
- return SDValue(N, 0);
- }
+ // Turn pred_cast(xor x, -1) into xor(pred_cast x, -1), in order to produce
+ // more VPNOT which might get folded as else predicates.
+ if (Op.getValueType() == MVT::i32 && isBitwiseNot(Op)) {
+ SDValue X =
+ DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT, Op->getOperand(0));
+ SDValue C = DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT,
+ DCI.DAG.getConstant(65535, dl, MVT::i32));
+ return DCI.DAG.getNode(ISD::XOR, dl, VT, X, C);
+ }
+
+ // Only the bottom 16 bits of the source register are used.
+ if (Op.getValueType() == MVT::i32) {
+ APInt DemandedMask = APInt::getLowBitsSet(32, 16);
+ const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
+ if (TLI.SimplifyDemandedBits(Op, DemandedMask, DCI))
+ return SDValue(N, 0);
+ }
return SDValue();
}
@@ -14078,13 +14078,13 @@ static SDValue CombineBaseUpdate(SDNode *N,
NumVecs = 3; break;
case Intrinsic::arm_neon_vld4: NewOpc = ARMISD::VLD4_UPD;
NumVecs = 4; break;
- case Intrinsic::arm_neon_vld1x2:
- case Intrinsic::arm_neon_vld1x3:
- case Intrinsic::arm_neon_vld1x4:
+ case Intrinsic::arm_neon_vld1x2:
+ case Intrinsic::arm_neon_vld1x3:
+ case Intrinsic::arm_neon_vld1x4:
case Intrinsic::arm_neon_vld2dup:
case Intrinsic::arm_neon_vld3dup:
case Intrinsic::arm_neon_vld4dup:
- // TODO: Support updating VLD1x and VLDxDUP nodes. For now, we just skip
+ // TODO: Support updating VLD1x and VLDxDUP nodes. For now, we just skip
// combining base updates for such intrinsics.
continue;
case Intrinsic::arm_neon_vld2lane: NewOpc = ARMISD::VLD2LN_UPD;
@@ -14676,39 +14676,39 @@ static SDValue PerformSplittingToNarrowingStores(StoreSDNode *St,
// use the VMOVN over splitting the store. We are looking for patterns of:
// !rev: 0 N 1 N+1 2 N+2 ...
// rev: N 0 N+1 1 N+2 2 ...
- // The shuffle may either be a single source (in which case N = NumElts/2) or
- // two inputs extended with concat to the same size (in which case N =
- // NumElts).
- auto isVMOVNShuffle = [&](ShuffleVectorSDNode *SVN, bool Rev) {
- ArrayRef<int> M = SVN->getMask();
+ // The shuffle may either be a single source (in which case N = NumElts/2) or
+ // two inputs extended with concat to the same size (in which case N =
+ // NumElts).
+ auto isVMOVNShuffle = [&](ShuffleVectorSDNode *SVN, bool Rev) {
+ ArrayRef<int> M = SVN->getMask();
unsigned NumElts = ToVT.getVectorNumElements();
- if (SVN->getOperand(1).isUndef())
- NumElts /= 2;
+ if (SVN->getOperand(1).isUndef())
+ NumElts /= 2;
- unsigned Off0 = Rev ? NumElts : 0;
- unsigned Off1 = Rev ? 0 : NumElts;
+ unsigned Off0 = Rev ? NumElts : 0;
+ unsigned Off1 = Rev ? 0 : NumElts;
- for (unsigned I = 0; I < NumElts; I += 2) {
- if (M[I] >= 0 && M[I] != (int)(Off0 + I / 2))
+ for (unsigned I = 0; I < NumElts; I += 2) {
+ if (M[I] >= 0 && M[I] != (int)(Off0 + I / 2))
return false;
- if (M[I + 1] >= 0 && M[I + 1] != (int)(Off1 + I / 2))
+ if (M[I + 1] >= 0 && M[I + 1] != (int)(Off1 + I / 2))
return false;
}
return true;
};
- // It may be preferable to keep the store unsplit as the trunc may end up
- // being removed. Check that here.
- if (Trunc.getOperand(0).getOpcode() == ISD::SMIN) {
- if (SDValue U = PerformVQDMULHCombine(Trunc.getOperand(0).getNode(), DAG)) {
- DAG.ReplaceAllUsesWith(Trunc.getOperand(0), U);
+ // It may be preferable to keep the store unsplit as the trunc may end up
+ // being removed. Check that here.
+ if (Trunc.getOperand(0).getOpcode() == ISD::SMIN) {
+ if (SDValue U = PerformVQDMULHCombine(Trunc.getOperand(0).getNode(), DAG)) {
+ DAG.ReplaceAllUsesWith(Trunc.getOperand(0), U);
+ return SDValue();
+ }
+ }
+ if (auto *Shuffle = dyn_cast<ShuffleVectorSDNode>(Trunc.getOperand(0)))
+ if (isVMOVNShuffle(Shuffle, false) || isVMOVNShuffle(Shuffle, true))
return SDValue();
- }
- }
- if (auto *Shuffle = dyn_cast<ShuffleVectorSDNode>(Trunc.getOperand(0)))
- if (isVMOVNShuffle(Shuffle, false) || isVMOVNShuffle(Shuffle, true))
- return SDValue();
LLVMContext &C = *DAG.getContext();
SDLoc DL(St);
@@ -14728,8 +14728,8 @@ static SDValue PerformSplittingToNarrowingStores(StoreSDNode *St,
SmallVector<SDValue, 4> Stores;
for (unsigned i = 0; i < FromVT.getVectorNumElements() / NumElements; i++) {
unsigned NewOffset = i * NumElements * ToEltVT.getSizeInBits() / 8;
- SDValue NewPtr =
- DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::Fixed(NewOffset));
+ SDValue NewPtr =
+ DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::Fixed(NewOffset));
SDValue Extract =
DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, NewFromVT, Trunc.getOperand(0),
@@ -14782,15 +14782,15 @@ static SDValue PerformSTORECombine(SDNode *N,
SDValue BasePtr = St->getBasePtr();
SDValue NewST1 = DAG.getStore(
St->getChain(), DL, StVal.getNode()->getOperand(isBigEndian ? 1 : 0),
- BasePtr, St->getPointerInfo(), St->getOriginalAlign(),
+ BasePtr, St->getPointerInfo(), St->getOriginalAlign(),
St->getMemOperand()->getFlags());
SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr,
DAG.getConstant(4, DL, MVT::i32));
return DAG.getStore(NewST1.getValue(0), DL,
StVal.getNode()->getOperand(isBigEndian ? 0 : 1),
- OffsetPtr, St->getPointerInfo().getWithOffset(4),
- St->getOriginalAlign(),
+ OffsetPtr, St->getPointerInfo().getWithOffset(4),
+ St->getOriginalAlign(),
St->getMemOperand()->getFlags());
}
@@ -14964,107 +14964,107 @@ static SDValue PerformVECREDUCE_ADDCombine(SDNode *N, SelectionDAG &DAG,
// VADDLV u/s 32
// VMLALV u/s 16/32
- // If the input vector is smaller than legal (v4i8/v4i16 for example) we can
- // extend it and use v4i32 instead.
- auto ExtendIfNeeded = [&](SDValue A, unsigned ExtendCode) {
- EVT AVT = A.getValueType();
- if (!AVT.is128BitVector())
- A = DAG.getNode(ExtendCode, dl,
- AVT.changeVectorElementType(MVT::getIntegerVT(
- 128 / AVT.getVectorMinNumElements())),
- A);
- return A;
- };
+ // If the input vector is smaller than legal (v4i8/v4i16 for example) we can
+ // extend it and use v4i32 instead.
+ auto ExtendIfNeeded = [&](SDValue A, unsigned ExtendCode) {
+ EVT AVT = A.getValueType();
+ if (!AVT.is128BitVector())
+ A = DAG.getNode(ExtendCode, dl,
+ AVT.changeVectorElementType(MVT::getIntegerVT(
+ 128 / AVT.getVectorMinNumElements())),
+ A);
+ return A;
+ };
auto IsVADDV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes) {
if (ResVT != RetTy || N0->getOpcode() != ExtendCode)
return SDValue();
SDValue A = N0->getOperand(0);
if (llvm::any_of(ExtTypes, [&A](MVT Ty) { return A.getValueType() == Ty; }))
- return ExtendIfNeeded(A, ExtendCode);
+ return ExtendIfNeeded(A, ExtendCode);
+ return SDValue();
+ };
+ auto IsPredVADDV = [&](MVT RetTy, unsigned ExtendCode,
+ ArrayRef<MVT> ExtTypes, SDValue &Mask) {
+ if (ResVT != RetTy || N0->getOpcode() != ISD::VSELECT ||
+ !ISD::isBuildVectorAllZeros(N0->getOperand(2).getNode()))
+ return SDValue();
+ Mask = N0->getOperand(0);
+ SDValue Ext = N0->getOperand(1);
+ if (Ext->getOpcode() != ExtendCode)
+ return SDValue();
+ SDValue A = Ext->getOperand(0);
+ if (llvm::any_of(ExtTypes, [&A](MVT Ty) { return A.getValueType() == Ty; }))
+ return ExtendIfNeeded(A, ExtendCode);
return SDValue();
};
- auto IsPredVADDV = [&](MVT RetTy, unsigned ExtendCode,
- ArrayRef<MVT> ExtTypes, SDValue &Mask) {
- if (ResVT != RetTy || N0->getOpcode() != ISD::VSELECT ||
- !ISD::isBuildVectorAllZeros(N0->getOperand(2).getNode()))
- return SDValue();
- Mask = N0->getOperand(0);
- SDValue Ext = N0->getOperand(1);
- if (Ext->getOpcode() != ExtendCode)
- return SDValue();
- SDValue A = Ext->getOperand(0);
- if (llvm::any_of(ExtTypes, [&A](MVT Ty) { return A.getValueType() == Ty; }))
- return ExtendIfNeeded(A, ExtendCode);
- return SDValue();
- };
auto IsVMLAV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes,
SDValue &A, SDValue &B) {
- // For a vmla we are trying to match a larger pattern:
- // ExtA = sext/zext A
- // ExtB = sext/zext B
- // Mul = mul ExtA, ExtB
- // vecreduce.add Mul
- // There might also be en extra extend between the mul and the addreduce, so
- // long as the bitwidth is high enough to make them equivalent (for example
- // original v8i16 might be mul at v8i32 and the reduce happens at v8i64).
- if (ResVT != RetTy)
+ // For a vmla we are trying to match a larger pattern:
+ // ExtA = sext/zext A
+ // ExtB = sext/zext B
+ // Mul = mul ExtA, ExtB
+ // vecreduce.add Mul
+ // There might also be en extra extend between the mul and the addreduce, so
+ // long as the bitwidth is high enough to make them equivalent (for example
+ // original v8i16 might be mul at v8i32 and the reduce happens at v8i64).
+ if (ResVT != RetTy)
return false;
- SDValue Mul = N0;
- if (Mul->getOpcode() == ExtendCode &&
- Mul->getOperand(0).getScalarValueSizeInBits() * 2 >=
- ResVT.getScalarSizeInBits())
- Mul = Mul->getOperand(0);
- if (Mul->getOpcode() != ISD::MUL)
- return false;
- SDValue ExtA = Mul->getOperand(0);
- SDValue ExtB = Mul->getOperand(1);
+ SDValue Mul = N0;
+ if (Mul->getOpcode() == ExtendCode &&
+ Mul->getOperand(0).getScalarValueSizeInBits() * 2 >=
+ ResVT.getScalarSizeInBits())
+ Mul = Mul->getOperand(0);
+ if (Mul->getOpcode() != ISD::MUL)
+ return false;
+ SDValue ExtA = Mul->getOperand(0);
+ SDValue ExtB = Mul->getOperand(1);
if (ExtA->getOpcode() != ExtendCode && ExtB->getOpcode() != ExtendCode)
return false;
A = ExtA->getOperand(0);
B = ExtB->getOperand(0);
if (A.getValueType() == B.getValueType() &&
- llvm::any_of(ExtTypes,
- [&A](MVT Ty) { return A.getValueType() == Ty; })) {
- A = ExtendIfNeeded(A, ExtendCode);
- B = ExtendIfNeeded(B, ExtendCode);
+ llvm::any_of(ExtTypes,
+ [&A](MVT Ty) { return A.getValueType() == Ty; })) {
+ A = ExtendIfNeeded(A, ExtendCode);
+ B = ExtendIfNeeded(B, ExtendCode);
return true;
- }
+ }
+ return false;
+ };
+ auto IsPredVMLAV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes,
+ SDValue &A, SDValue &B, SDValue &Mask) {
+ // Same as the pattern above with a select for the zero predicated lanes
+ // ExtA = sext/zext A
+ // ExtB = sext/zext B
+ // Mul = mul ExtA, ExtB
+ // N0 = select Mask, Mul, 0
+ // vecreduce.add N0
+ if (ResVT != RetTy || N0->getOpcode() != ISD::VSELECT ||
+ !ISD::isBuildVectorAllZeros(N0->getOperand(2).getNode()))
+ return false;
+ Mask = N0->getOperand(0);
+ SDValue Mul = N0->getOperand(1);
+ if (Mul->getOpcode() == ExtendCode &&
+ Mul->getOperand(0).getScalarValueSizeInBits() * 2 >=
+ ResVT.getScalarSizeInBits())
+ Mul = Mul->getOperand(0);
+ if (Mul->getOpcode() != ISD::MUL)
+ return false;
+ SDValue ExtA = Mul->getOperand(0);
+ SDValue ExtB = Mul->getOperand(1);
+ if (ExtA->getOpcode() != ExtendCode && ExtB->getOpcode() != ExtendCode)
+ return false;
+ A = ExtA->getOperand(0);
+ B = ExtB->getOperand(0);
+ if (A.getValueType() == B.getValueType() &&
+ llvm::any_of(ExtTypes,
+ [&A](MVT Ty) { return A.getValueType() == Ty; })) {
+ A = ExtendIfNeeded(A, ExtendCode);
+ B = ExtendIfNeeded(B, ExtendCode);
+ return true;
+ }
return false;
};
- auto IsPredVMLAV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes,
- SDValue &A, SDValue &B, SDValue &Mask) {
- // Same as the pattern above with a select for the zero predicated lanes
- // ExtA = sext/zext A
- // ExtB = sext/zext B
- // Mul = mul ExtA, ExtB
- // N0 = select Mask, Mul, 0
- // vecreduce.add N0
- if (ResVT != RetTy || N0->getOpcode() != ISD::VSELECT ||
- !ISD::isBuildVectorAllZeros(N0->getOperand(2).getNode()))
- return false;
- Mask = N0->getOperand(0);
- SDValue Mul = N0->getOperand(1);
- if (Mul->getOpcode() == ExtendCode &&
- Mul->getOperand(0).getScalarValueSizeInBits() * 2 >=
- ResVT.getScalarSizeInBits())
- Mul = Mul->getOperand(0);
- if (Mul->getOpcode() != ISD::MUL)
- return false;
- SDValue ExtA = Mul->getOperand(0);
- SDValue ExtB = Mul->getOperand(1);
- if (ExtA->getOpcode() != ExtendCode && ExtB->getOpcode() != ExtendCode)
- return false;
- A = ExtA->getOperand(0);
- B = ExtB->getOperand(0);
- if (A.getValueType() == B.getValueType() &&
- llvm::any_of(ExtTypes,
- [&A](MVT Ty) { return A.getValueType() == Ty; })) {
- A = ExtendIfNeeded(A, ExtendCode);
- B = ExtendIfNeeded(B, ExtendCode);
- return true;
- }
- return false;
- };
auto Create64bitNode = [&](unsigned Opcode, ArrayRef<SDValue> Ops) {
SDValue Node = DAG.getNode(Opcode, dl, {MVT::i32, MVT::i32}, Ops);
return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Node,
@@ -15075,93 +15075,93 @@ static SDValue PerformVECREDUCE_ADDCombine(SDNode *N, SelectionDAG &DAG,
return DAG.getNode(ARMISD::VADDVs, dl, ResVT, A);
if (SDValue A = IsVADDV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}))
return DAG.getNode(ARMISD::VADDVu, dl, ResVT, A);
- if (SDValue A = IsVADDV(MVT::i64, ISD::SIGN_EXTEND,
- {MVT::v4i8, MVT::v4i16, MVT::v4i32}))
+ if (SDValue A = IsVADDV(MVT::i64, ISD::SIGN_EXTEND,
+ {MVT::v4i8, MVT::v4i16, MVT::v4i32}))
return Create64bitNode(ARMISD::VADDLVs, {A});
- if (SDValue A = IsVADDV(MVT::i64, ISD::ZERO_EXTEND,
- {MVT::v4i8, MVT::v4i16, MVT::v4i32}))
+ if (SDValue A = IsVADDV(MVT::i64, ISD::ZERO_EXTEND,
+ {MVT::v4i8, MVT::v4i16, MVT::v4i32}))
return Create64bitNode(ARMISD::VADDLVu, {A});
- if (SDValue A = IsVADDV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}))
- return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
- DAG.getNode(ARMISD::VADDVs, dl, MVT::i32, A));
- if (SDValue A = IsVADDV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}))
- return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
- DAG.getNode(ARMISD::VADDVu, dl, MVT::i32, A));
-
- SDValue Mask;
- if (SDValue A = IsPredVADDV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, Mask))
- return DAG.getNode(ARMISD::VADDVps, dl, ResVT, A, Mask);
- if (SDValue A = IsPredVADDV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, Mask))
- return DAG.getNode(ARMISD::VADDVpu, dl, ResVT, A, Mask);
- if (SDValue A = IsPredVADDV(MVT::i64, ISD::SIGN_EXTEND,
- {MVT::v4i8, MVT::v4i16, MVT::v4i32}, Mask))
- return Create64bitNode(ARMISD::VADDLVps, {A, Mask});
- if (SDValue A = IsPredVADDV(MVT::i64, ISD::ZERO_EXTEND,
- {MVT::v4i8, MVT::v4i16, MVT::v4i32}, Mask))
- return Create64bitNode(ARMISD::VADDLVpu, {A, Mask});
- if (SDValue A = IsPredVADDV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, Mask))
- return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
- DAG.getNode(ARMISD::VADDVps, dl, MVT::i32, A, Mask));
- if (SDValue A = IsPredVADDV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, Mask))
- return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
- DAG.getNode(ARMISD::VADDVpu, dl, MVT::i32, A, Mask));
-
+ if (SDValue A = IsVADDV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}))
+ return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
+ DAG.getNode(ARMISD::VADDVs, dl, MVT::i32, A));
+ if (SDValue A = IsVADDV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}))
+ return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
+ DAG.getNode(ARMISD::VADDVu, dl, MVT::i32, A));
+
+ SDValue Mask;
+ if (SDValue A = IsPredVADDV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, Mask))
+ return DAG.getNode(ARMISD::VADDVps, dl, ResVT, A, Mask);
+ if (SDValue A = IsPredVADDV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, Mask))
+ return DAG.getNode(ARMISD::VADDVpu, dl, ResVT, A, Mask);
+ if (SDValue A = IsPredVADDV(MVT::i64, ISD::SIGN_EXTEND,
+ {MVT::v4i8, MVT::v4i16, MVT::v4i32}, Mask))
+ return Create64bitNode(ARMISD::VADDLVps, {A, Mask});
+ if (SDValue A = IsPredVADDV(MVT::i64, ISD::ZERO_EXTEND,
+ {MVT::v4i8, MVT::v4i16, MVT::v4i32}, Mask))
+ return Create64bitNode(ARMISD::VADDLVpu, {A, Mask});
+ if (SDValue A = IsPredVADDV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, Mask))
+ return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
+ DAG.getNode(ARMISD::VADDVps, dl, MVT::i32, A, Mask));
+ if (SDValue A = IsPredVADDV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, Mask))
+ return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
+ DAG.getNode(ARMISD::VADDVpu, dl, MVT::i32, A, Mask));
+
SDValue A, B;
if (IsVMLAV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B))
return DAG.getNode(ARMISD::VMLAVs, dl, ResVT, A, B);
if (IsVMLAV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B))
return DAG.getNode(ARMISD::VMLAVu, dl, ResVT, A, B);
- if (IsVMLAV(MVT::i64, ISD::SIGN_EXTEND,
- {MVT::v8i8, MVT::v8i16, MVT::v4i8, MVT::v4i16, MVT::v4i32}, A, B))
+ if (IsVMLAV(MVT::i64, ISD::SIGN_EXTEND,
+ {MVT::v8i8, MVT::v8i16, MVT::v4i8, MVT::v4i16, MVT::v4i32}, A, B))
return Create64bitNode(ARMISD::VMLALVs, {A, B});
- if (IsVMLAV(MVT::i64, ISD::ZERO_EXTEND,
- {MVT::v8i8, MVT::v8i16, MVT::v4i8, MVT::v4i16, MVT::v4i32}, A, B))
+ if (IsVMLAV(MVT::i64, ISD::ZERO_EXTEND,
+ {MVT::v8i8, MVT::v8i16, MVT::v4i8, MVT::v4i16, MVT::v4i32}, A, B))
return Create64bitNode(ARMISD::VMLALVu, {A, B});
- if (IsVMLAV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, A, B))
- return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
- DAG.getNode(ARMISD::VMLAVs, dl, MVT::i32, A, B));
- if (IsVMLAV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, A, B))
- return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
- DAG.getNode(ARMISD::VMLAVu, dl, MVT::i32, A, B));
-
- if (IsPredVMLAV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B, Mask))
- return DAG.getNode(ARMISD::VMLAVps, dl, ResVT, A, B, Mask);
- if (IsPredVMLAV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B, Mask))
- return DAG.getNode(ARMISD::VMLAVpu, dl, ResVT, A, B, Mask);
- if (IsPredVMLAV(MVT::i64, ISD::SIGN_EXTEND,
- {MVT::v8i8, MVT::v8i16, MVT::v4i8, MVT::v4i16, MVT::v4i32}, A,
- B, Mask))
- return Create64bitNode(ARMISD::VMLALVps, {A, B, Mask});
- if (IsPredVMLAV(MVT::i64, ISD::ZERO_EXTEND,
- {MVT::v8i8, MVT::v8i16, MVT::v4i8, MVT::v4i16, MVT::v4i32}, A,
- B, Mask))
- return Create64bitNode(ARMISD::VMLALVpu, {A, B, Mask});
- if (IsPredVMLAV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, A, B, Mask))
- return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
- DAG.getNode(ARMISD::VMLAVps, dl, MVT::i32, A, B, Mask));
- if (IsPredVMLAV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, A, B, Mask))
- return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
- DAG.getNode(ARMISD::VMLAVpu, dl, MVT::i32, A, B, Mask));
-
- // Some complications. We can get a case where the two inputs of the mul are
- // the same, then the output sext will have been helpfully converted to a
- // zext. Turn it back.
- SDValue Op = N0;
- if (Op->getOpcode() == ISD::VSELECT)
- Op = Op->getOperand(1);
- if (Op->getOpcode() == ISD::ZERO_EXTEND &&
- Op->getOperand(0)->getOpcode() == ISD::MUL) {
- SDValue Mul = Op->getOperand(0);
- if (Mul->getOperand(0) == Mul->getOperand(1) &&
- Mul->getOperand(0)->getOpcode() == ISD::SIGN_EXTEND) {
- SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND, dl, N0->getValueType(0), Mul);
- if (Op != N0)
- Ext = DAG.getNode(ISD::VSELECT, dl, N0->getValueType(0),
- N0->getOperand(0), Ext, N0->getOperand(2));
- return DAG.getNode(ISD::VECREDUCE_ADD, dl, ResVT, Ext);
- }
- }
-
+ if (IsVMLAV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, A, B))
+ return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
+ DAG.getNode(ARMISD::VMLAVs, dl, MVT::i32, A, B));
+ if (IsVMLAV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, A, B))
+ return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
+ DAG.getNode(ARMISD::VMLAVu, dl, MVT::i32, A, B));
+
+ if (IsPredVMLAV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B, Mask))
+ return DAG.getNode(ARMISD::VMLAVps, dl, ResVT, A, B, Mask);
+ if (IsPredVMLAV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B, Mask))
+ return DAG.getNode(ARMISD::VMLAVpu, dl, ResVT, A, B, Mask);
+ if (IsPredVMLAV(MVT::i64, ISD::SIGN_EXTEND,
+ {MVT::v8i8, MVT::v8i16, MVT::v4i8, MVT::v4i16, MVT::v4i32}, A,
+ B, Mask))
+ return Create64bitNode(ARMISD::VMLALVps, {A, B, Mask});
+ if (IsPredVMLAV(MVT::i64, ISD::ZERO_EXTEND,
+ {MVT::v8i8, MVT::v8i16, MVT::v4i8, MVT::v4i16, MVT::v4i32}, A,
+ B, Mask))
+ return Create64bitNode(ARMISD::VMLALVpu, {A, B, Mask});
+ if (IsPredVMLAV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, A, B, Mask))
+ return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
+ DAG.getNode(ARMISD::VMLAVps, dl, MVT::i32, A, B, Mask));
+ if (IsPredVMLAV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, A, B, Mask))
+ return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
+ DAG.getNode(ARMISD::VMLAVpu, dl, MVT::i32, A, B, Mask));
+
+ // Some complications. We can get a case where the two inputs of the mul are
+ // the same, then the output sext will have been helpfully converted to a
+ // zext. Turn it back.
+ SDValue Op = N0;
+ if (Op->getOpcode() == ISD::VSELECT)
+ Op = Op->getOperand(1);
+ if (Op->getOpcode() == ISD::ZERO_EXTEND &&
+ Op->getOperand(0)->getOpcode() == ISD::MUL) {
+ SDValue Mul = Op->getOperand(0);
+ if (Mul->getOperand(0) == Mul->getOperand(1) &&
+ Mul->getOperand(0)->getOpcode() == ISD::SIGN_EXTEND) {
+ SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND, dl, N0->getValueType(0), Mul);
+ if (Op != N0)
+ Ext = DAG.getNode(ISD::VSELECT, dl, N0->getValueType(0),
+ N0->getOperand(0), Ext, N0->getOperand(2));
+ return DAG.getNode(ISD::VECREDUCE_ADD, dl, ResVT, Ext);
+ }
+ }
+
return SDValue();
}
@@ -15613,13 +15613,13 @@ static SDValue PerformSplittingToWideningLoad(SDNode *N, SelectionDAG &DAG) {
SmallVector<SDValue, 4> Chains;
for (unsigned i = 0; i < FromVT.getVectorNumElements() / NumElements; i++) {
unsigned NewOffset = (i * NewFromVT.getSizeInBits()) / 8;
- SDValue NewPtr =
- DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::Fixed(NewOffset));
+ SDValue NewPtr =
+ DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::Fixed(NewOffset));
SDValue NewLoad =
DAG.getLoad(ISD::UNINDEXED, NewExtType, NewToVT, DL, Ch, NewPtr, Offset,
LD->getPointerInfo().getWithOffset(NewOffset), NewFromVT,
- Alignment, MMOFlags, AAInfo);
+ Alignment, MMOFlags, AAInfo);
Loads.push_back(NewLoad);
Chains.push_back(SDValue(NewLoad.getNode(), 1));
}
@@ -15707,9 +15707,9 @@ static SDValue PerformMinMaxCombine(SDNode *N, SelectionDAG &DAG,
if (!ST->hasMVEIntegerOps())
return SDValue();
- if (SDValue V = PerformVQDMULHCombine(N, DAG))
- return V;
-
+ if (SDValue V = PerformVQDMULHCombine(N, DAG))
+ return V;
+
if (VT != MVT::v4i32 && VT != MVT::v8i16)
return SDValue();
@@ -16317,8 +16317,8 @@ SDValue ARMTargetLowering::PerformDAGCombine(SDNode *N,
DAGCombinerInfo &DCI) const {
switch (N->getOpcode()) {
default: break;
- case ISD::SELECT_CC:
- case ISD::SELECT: return PerformSELECTCombine(N, DCI, Subtarget);
+ case ISD::SELECT_CC:
+ case ISD::SELECT: return PerformSELECTCombine(N, DCI, Subtarget);
case ISD::VSELECT: return PerformVSELECTCombine(N, DCI, Subtarget);
case ISD::ABS: return PerformABSCombine(N, DCI, Subtarget);
case ARMISD::ADDE: return PerformADDECombine(N, DCI, Subtarget);
@@ -16735,19 +16735,19 @@ bool ARMTargetLowering::shouldSinkOperands(Instruction *I,
switch (II->getIntrinsicID()) {
case Intrinsic::fma:
return !IsFMS(I);
- case Intrinsic::arm_mve_add_predicated:
- case Intrinsic::arm_mve_mul_predicated:
- case Intrinsic::arm_mve_qadd_predicated:
- case Intrinsic::arm_mve_hadd_predicated:
- case Intrinsic::arm_mve_vqdmull_predicated:
- case Intrinsic::arm_mve_qdmulh_predicated:
- case Intrinsic::arm_mve_qrdmulh_predicated:
- case Intrinsic::arm_mve_fma_predicated:
- return true;
- case Intrinsic::arm_mve_sub_predicated:
- case Intrinsic::arm_mve_qsub_predicated:
- case Intrinsic::arm_mve_hsub_predicated:
- return Operand == 1;
+ case Intrinsic::arm_mve_add_predicated:
+ case Intrinsic::arm_mve_mul_predicated:
+ case Intrinsic::arm_mve_qadd_predicated:
+ case Intrinsic::arm_mve_hadd_predicated:
+ case Intrinsic::arm_mve_vqdmull_predicated:
+ case Intrinsic::arm_mve_qdmulh_predicated:
+ case Intrinsic::arm_mve_qrdmulh_predicated:
+ case Intrinsic::arm_mve_fma_predicated:
+ return true;
+ case Intrinsic::arm_mve_sub_predicated:
+ case Intrinsic::arm_mve_qsub_predicated:
+ case Intrinsic::arm_mve_hsub_predicated:
+ return Operand == 1;
default:
return false;
}
@@ -17476,7 +17476,7 @@ void ARMTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
return;
KnownBits KnownRHS = DAG.computeKnownBits(Op.getOperand(1), Depth+1);
- Known = KnownBits::commonBits(Known, KnownRHS);
+ Known = KnownBits::commonBits(Known, KnownRHS);
return;
}
case ISD::INTRINSIC_W_CHAIN: {
@@ -18349,9 +18349,9 @@ bool ARMTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
return false;
if (VT == MVT::f16 && Subtarget->hasFullFP16())
return ARM_AM::getFP16Imm(Imm) != -1;
- if (VT == MVT::f32 && Subtarget->hasFullFP16() &&
- ARM_AM::getFP32FP16Imm(Imm) != -1)
- return true;
+ if (VT == MVT::f32 && Subtarget->hasFullFP16() &&
+ ARM_AM::getFP32FP16Imm(Imm) != -1)
+ return true;
if (VT == MVT::f32)
return ARM_AM::getFP32Imm(Imm) != -1;
if (VT == MVT::f64 && Subtarget->hasFP64())
@@ -18661,8 +18661,8 @@ ARMTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
: AtomicExpansionKind::None;
}
-// Similar to shouldExpandAtomicRMWInIR, ldrex/strex can be used up to 32
-// bits, and up to 64 bits on the non-M profiles.
+// Similar to shouldExpandAtomicRMWInIR, ldrex/strex can be used up to 32
+// bits, and up to 64 bits on the non-M profiles.
TargetLowering::AtomicExpansionKind
ARMTargetLowering::shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const {
// At -O0, fast-regalloc cannot cope with the live vregs necessary to
@@ -18670,11 +18670,11 @@ ARMTargetLowering::shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const {
// on the stack and close enough to the spill slot, this can lead to a
// situation where the monitor always gets cleared and the atomic operation
// can never succeed. So at -O0 we need a late-expanded pseudo-inst instead.
- unsigned Size = AI->getOperand(1)->getType()->getPrimitiveSizeInBits();
+ unsigned Size = AI->getOperand(1)->getType()->getPrimitiveSizeInBits();
bool HasAtomicCmpXchg =
!Subtarget->isThumb() || Subtarget->hasV8MBaselineOps();
- if (getTargetMachine().getOptLevel() != 0 && HasAtomicCmpXchg &&
- Size <= (Subtarget->isMClass() ? 32U : 64U))
+ if (getTargetMachine().getOptLevel() != 0 && HasAtomicCmpXchg &&
+ Size <= (Subtarget->isMClass() ? 32U : 64U))
return AtomicExpansionKind::LLSC;
return AtomicExpansionKind::None;
}
@@ -19129,7 +19129,7 @@ bool ARMTargetLowering::lowerInterleavedStore(StoreInst *SI,
SmallVector<Value *, 6> Ops;
Ops.push_back(Builder.CreateBitCast(BaseAddr, Int8Ptr));
- append_range(Ops, Shuffles);
+ append_range(Ops, Shuffles);
Ops.push_back(Builder.getInt32(SI->getAlignment()));
Builder.CreateCall(VstNFunc, Ops);
} else {
@@ -19145,7 +19145,7 @@ bool ARMTargetLowering::lowerInterleavedStore(StoreInst *SI,
SmallVector<Value *, 6> Ops;
Ops.push_back(Builder.CreateBitCast(BaseAddr, EltPtrTy));
- append_range(Ops, Shuffles);
+ append_range(Ops, Shuffles);
for (unsigned F = 0; F < Factor; F++) {
Ops.push_back(Builder.getInt32(F));
Builder.CreateCall(VstNFunc, Ops);
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMISelLowering.h b/contrib/libs/llvm12/lib/Target/ARM/ARMISelLowering.h
index 5b04ba8c6d..61a127af07 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMISelLowering.h
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMISelLowering.h
@@ -216,37 +216,37 @@ class VectorType;
VMULLs, // ...signed
VMULLu, // ...unsigned
- VQDMULH, // MVE vqdmulh instruction
-
+ VQDMULH, // MVE vqdmulh instruction
+
// MVE reductions
VADDVs, // sign- or zero-extend the elements of a vector to i32,
VADDVu, // add them all together, and return an i32 of their sum
- VADDVps, // Same as VADDV[su] but with a v4i1 predicate mask
- VADDVpu,
+ VADDVps, // Same as VADDV[su] but with a v4i1 predicate mask
+ VADDVpu,
VADDLVs, // sign- or zero-extend elements to i64 and sum, returning
VADDLVu, // the low and high 32-bit halves of the sum
- VADDLVAs, // Same as VADDLV[su] but also add an input accumulator
+ VADDLVAs, // Same as VADDLV[su] but also add an input accumulator
VADDLVAu, // provided as low and high halves
- VADDLVps, // Same as VADDLV[su] but with a v4i1 predicate mask
- VADDLVpu,
- VADDLVAps, // Same as VADDLVp[su] but with a v4i1 predicate mask
- VADDLVApu,
- VMLAVs, // sign- or zero-extend the elements of two vectors to i32, multiply them
- VMLAVu, // and add the results together, returning an i32 of their sum
- VMLAVps, // Same as VMLAV[su] with a v4i1 predicate mask
- VMLAVpu,
- VMLALVs, // Same as VMLAV but with i64, returning the low and
- VMLALVu, // high 32-bit halves of the sum
- VMLALVps, // Same as VMLALV[su] with a v4i1 predicate mask
- VMLALVpu,
- VMLALVAs, // Same as VMLALV but also add an input accumulator
- VMLALVAu, // provided as low and high halves
- VMLALVAps, // Same as VMLALVA[su] with a v4i1 predicate mask
- VMLALVApu,
- VMINVu, // Find minimum unsigned value of a vector and register
- VMINVs, // Find minimum signed value of a vector and register
- VMAXVu, // Find maximum unsigned value of a vector and register
- VMAXVs, // Find maximum signed value of a vector and register
+ VADDLVps, // Same as VADDLV[su] but with a v4i1 predicate mask
+ VADDLVpu,
+ VADDLVAps, // Same as VADDLVp[su] but with a v4i1 predicate mask
+ VADDLVApu,
+ VMLAVs, // sign- or zero-extend the elements of two vectors to i32, multiply them
+ VMLAVu, // and add the results together, returning an i32 of their sum
+ VMLAVps, // Same as VMLAV[su] with a v4i1 predicate mask
+ VMLAVpu,
+ VMLALVs, // Same as VMLAV but with i64, returning the low and
+ VMLALVu, // high 32-bit halves of the sum
+ VMLALVps, // Same as VMLALV[su] with a v4i1 predicate mask
+ VMLALVpu,
+ VMLALVAs, // Same as VMLALV but also add an input accumulator
+ VMLALVAu, // provided as low and high halves
+ VMLALVAps, // Same as VMLALVA[su] with a v4i1 predicate mask
+ VMLALVApu,
+ VMINVu, // Find minimum unsigned value of a vector and register
+ VMINVs, // Find minimum signed value of a vector and register
+ VMAXVu, // Find maximum unsigned value of a vector and register
+ VMAXVs, // Find maximum signed value of a vector and register
SMULWB, // Signed multiply word by half word, bottom
SMULWT, // Signed multiply word by half word, top
@@ -285,8 +285,8 @@ class VectorType;
// Vector AND with NOT of immediate
VBICIMM,
- // Pseudo vector bitwise select
- VBSP,
+ // Pseudo vector bitwise select
+ VBSP,
// Pseudo-instruction representing a memory copy using ldm/stm
// instructions.
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td b/contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td
index 7937353678..85da7c5a53 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMInstrFormats.td
@@ -403,9 +403,9 @@ class InstTemplate<AddrMode am, int sz, IndexMode im,
bit isUnaryDataProc = 0;
bit canXformTo16Bit = 0;
// The instruction is a 16-bit flag setting Thumb instruction. Used
- // by the parser and if-converter to determine whether to require the 'S'
- // suffix on the mnemonic (when not in an IT block) or preclude it (when
- // in an IT block).
+ // by the parser and if-converter to determine whether to require the 'S'
+ // suffix on the mnemonic (when not in an IT block) or preclude it (when
+ // in an IT block).
bit thumbArithFlagSetting = 0;
bit validForTailPredication = 0;
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMInstrInfo.td b/contrib/libs/llvm12/lib/Target/ARM/ARMInstrInfo.td
index 2fe8cbc613..8dcb319923 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMInstrInfo.td
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMInstrInfo.td
@@ -162,9 +162,9 @@ def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
[SDNPInGlue]>;
def ARMsubs : SDNode<"ARMISD::SUBS", SDTIntBinOp, [SDNPOutGlue]>;
-def ARMssat : SDNode<"ARMISD::SSAT", SDTIntSatNoShOp, []>;
+def ARMssat : SDNode<"ARMISD::SSAT", SDTIntSatNoShOp, []>;
-def ARMusat : SDNode<"ARMISD::USAT", SDTIntSatNoShOp, []>;
+def ARMusat : SDNode<"ARMISD::USAT", SDTIntSatNoShOp, []>;
def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
[SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
@@ -371,11 +371,11 @@ def imm_not_XFORM : SDNodeXForm<imm, [{
return CurDAG->getTargetConstant(~(int)N->getZExtValue(), SDLoc(N), MVT::i32);
}]>;
-// asr_imm_XFORM - Returns a shift immediate with bit {5} set to 1
-def asr_imm_XFORM : SDNodeXForm<imm, [{
- return CurDAG->getTargetConstant(0x20 | N->getZExtValue(), SDLoc(N), MVT:: i32);
-}]>;
-
+// asr_imm_XFORM - Returns a shift immediate with bit {5} set to 1
+def asr_imm_XFORM : SDNodeXForm<imm, [{
+ return CurDAG->getTargetConstant(0x20 | N->getZExtValue(), SDLoc(N), MVT:: i32);
+}]>;
+
/// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
def imm16_31 : ImmLeaf<i32, [{
return (int32_t)Imm >= 16 && (int32_t)Imm < 32;
@@ -442,8 +442,8 @@ def fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{
def imm_even : ImmLeaf<i32, [{ return (Imm & 1) == 0; }]>;
def imm_odd : ImmLeaf<i32, [{ return (Imm & 1) == 1; }]>;
-def asr_imm : ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }], asr_imm_XFORM>;
-
+def asr_imm : ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }], asr_imm_XFORM>;
+
//===----------------------------------------------------------------------===//
// NEON/MVE pattern fragments
//
@@ -496,19 +496,19 @@ def SubReg_i32_lane : SDNodeXForm<imm, [{
}]>;
-def ARMimmAllZerosV: PatLeaf<(bitconvert (v4i32 (ARMvmovImm (i32 0))))>;
-def ARMimmAllZerosD: PatLeaf<(bitconvert (v2i32 (ARMvmovImm (i32 0))))>;
-def ARMimmAllOnesV: PatLeaf<(bitconvert (v16i8 (ARMvmovImm (i32 0xEFF))))>;
-def ARMimmAllOnesD: PatLeaf<(bitconvert (v8i8 (ARMvmovImm (i32 0xEFF))))>;
+def ARMimmAllZerosV: PatLeaf<(bitconvert (v4i32 (ARMvmovImm (i32 0))))>;
+def ARMimmAllZerosD: PatLeaf<(bitconvert (v2i32 (ARMvmovImm (i32 0))))>;
+def ARMimmAllOnesV: PatLeaf<(bitconvert (v16i8 (ARMvmovImm (i32 0xEFF))))>;
+def ARMimmAllOnesD: PatLeaf<(bitconvert (v8i8 (ARMvmovImm (i32 0xEFF))))>;
+
+def ARMimmOneV: PatLeaf<(ARMvmovImm (i32 timm)), [{
+ ConstantSDNode *ConstVal = cast<ConstantSDNode>(N->getOperand(0));
+ unsigned EltBits = 0;
+ uint64_t EltVal = ARM_AM::decodeVMOVModImm(ConstVal->getZExtValue(), EltBits);
+ return (EltBits == N->getValueType(0).getScalarSizeInBits() && EltVal == 0x01);
+}]>;
+
-def ARMimmOneV: PatLeaf<(ARMvmovImm (i32 timm)), [{
- ConstantSDNode *ConstVal = cast<ConstantSDNode>(N->getOperand(0));
- unsigned EltBits = 0;
- uint64_t EltVal = ARM_AM::decodeVMOVModImm(ConstVal->getZExtValue(), EltBits);
- return (EltBits == N->getValueType(0).getScalarSizeInBits() && EltVal == 0x01);
-}]>;
-
-
//===----------------------------------------------------------------------===//
// Operand Definitions.
//
@@ -822,9 +822,9 @@ def mod_imm_neg : Operand<i32>, PatLeaf<(imm), [{
def arm_i32imm : IntImmLeaf<i32, [{
if (Subtarget->useMovt())
return true;
- if (ARM_AM::isSOImmTwoPartVal(Imm.getZExtValue()))
- return true;
- return ARM_AM::isSOImmTwoPartValNeg(Imm.getZExtValue());
+ if (ARM_AM::isSOImmTwoPartVal(Imm.getZExtValue()))
+ return true;
+ return ARM_AM::isSOImmTwoPartValNeg(Imm.getZExtValue());
}]>;
/// imm0_1 predicate - Immediate in the range [0,1].
@@ -2492,30 +2492,30 @@ let isCall = 1,
}
// ARMv5T and above
- def BLX : AXI<(outs), (ins GPR:$func), BrMiscFrm, IIC_Br, "blx\t$func", []>,
+ def BLX : AXI<(outs), (ins GPR:$func), BrMiscFrm, IIC_Br, "blx\t$func", []>,
Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]> {
bits<4> func;
let Inst{31-4} = 0b1110000100101111111111110011;
let Inst{3-0} = func;
}
- def BLX_noip : ARMPseudoExpand<(outs), (ins GPRnoip:$func),
- 4, IIC_Br, [], (BLX GPR:$func)>,
- Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]>;
+ def BLX_noip : ARMPseudoExpand<(outs), (ins GPRnoip:$func),
+ 4, IIC_Br, [], (BLX GPR:$func)>,
+ Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]>;
+
-
def BLX_pred : AI<(outs), (ins GPR:$func), BrMiscFrm,
- IIC_Br, "blx", "\t$func", []>,
+ IIC_Br, "blx", "\t$func", []>,
Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]> {
bits<4> func;
let Inst{27-4} = 0b000100101111111111110011;
let Inst{3-0} = func;
}
- def BLX_pred_noip : ARMPseudoExpand<(outs), (ins GPRnoip:$func),
- 4, IIC_Br, [],
- (BLX_pred GPR:$func, (ops 14, zero_reg))>,
- Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]>;
+ def BLX_pred_noip : ARMPseudoExpand<(outs), (ins GPRnoip:$func),
+ 4, IIC_Br, [],
+ (BLX_pred GPR:$func, (ops 14, zero_reg))>,
+ Requires<[IsARM, HasV5T]>, Sched<[WriteBrL]>;
+
-
// ARMv4T
// Note: Restrict $func to the tGPR regclass to prevent it being in LR.
def BX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func),
@@ -2540,16 +2540,16 @@ let isCall = 1,
Requires<[IsARM]>, Sched<[WriteBr]>;
}
-def : ARMPat<(ARMcall GPR:$func), (BLX $func)>,
- Requires<[IsARM, HasV5T, NoSLSBLRMitigation]>;
-def : ARMPat<(ARMcall GPRnoip:$func), (BLX_noip $func)>,
- Requires<[IsARM, HasV5T, SLSBLRMitigation]>;
-def : ARMPat<(ARMcall_pred GPR:$func), (BLX_pred $func)>,
- Requires<[IsARM, HasV5T, NoSLSBLRMitigation]>;
-def : ARMPat<(ARMcall_pred GPRnoip:$func), (BLX_pred_noip $func)>,
- Requires<[IsARM, HasV5T, SLSBLRMitigation]>;
-
-
+def : ARMPat<(ARMcall GPR:$func), (BLX $func)>,
+ Requires<[IsARM, HasV5T, NoSLSBLRMitigation]>;
+def : ARMPat<(ARMcall GPRnoip:$func), (BLX_noip $func)>,
+ Requires<[IsARM, HasV5T, SLSBLRMitigation]>;
+def : ARMPat<(ARMcall_pred GPR:$func), (BLX_pred $func)>,
+ Requires<[IsARM, HasV5T, NoSLSBLRMitigation]>;
+def : ARMPat<(ARMcall_pred GPRnoip:$func), (BLX_pred_noip $func)>,
+ Requires<[IsARM, HasV5T, SLSBLRMitigation]>;
+
+
let isBranch = 1, isTerminator = 1 in {
// FIXME: should be able to write a pattern for ARMBrcond, but can't use
// a two-value operand where a dag node expects two operands. :(
@@ -4089,32 +4089,32 @@ def : ARMV6Pat<(int_arm_ssat GPRnopc:$a, imm1_32:$pos),
(SSAT imm1_32:$pos, GPRnopc:$a, 0)>;
def : ARMV6Pat<(int_arm_usat GPRnopc:$a, imm0_31:$pos),
(USAT imm0_31:$pos, GPRnopc:$a, 0)>;
-def : ARMPat<(ARMssat GPRnopc:$Rn, imm0_31:$imm),
+def : ARMPat<(ARMssat GPRnopc:$Rn, imm0_31:$imm),
(SSAT imm0_31:$imm, GPRnopc:$Rn, 0)>;
-def : ARMPat<(ARMusat GPRnopc:$Rn, imm0_31:$imm),
+def : ARMPat<(ARMusat GPRnopc:$Rn, imm0_31:$imm),
(USAT imm0_31:$imm, GPRnopc:$Rn, 0)>;
def : ARMV6Pat<(int_arm_ssat16 GPRnopc:$a, imm1_16:$pos),
(SSAT16 imm1_16:$pos, GPRnopc:$a)>;
def : ARMV6Pat<(int_arm_usat16 GPRnopc:$a, imm0_15:$pos),
(USAT16 imm0_15:$pos, GPRnopc:$a)>;
-def : ARMV6Pat<(int_arm_ssat (shl GPRnopc:$a, imm0_31:$shft), imm1_32:$pos),
- (SSAT imm1_32:$pos, GPRnopc:$a, imm0_31:$shft)>;
-def : ARMV6Pat<(int_arm_ssat (sra GPRnopc:$a, asr_imm:$shft), imm1_32:$pos),
- (SSAT imm1_32:$pos, GPRnopc:$a, asr_imm:$shft)>;
-def : ARMV6Pat<(int_arm_usat (shl GPRnopc:$a, imm0_31:$shft), imm0_31:$pos),
- (USAT imm0_31:$pos, GPRnopc:$a, imm0_31:$shft)>;
-def : ARMV6Pat<(int_arm_usat (sra GPRnopc:$a, asr_imm:$shft), imm0_31:$pos),
- (USAT imm0_31:$pos, GPRnopc:$a, asr_imm:$shft)>;
-def : ARMPat<(ARMssat (shl GPRnopc:$Rn, imm0_31:$shft), imm0_31:$pos),
- (SSAT imm0_31:$pos, GPRnopc:$Rn, imm0_31:$shft)>;
-def : ARMPat<(ARMssat (sra GPRnopc:$Rn, asr_imm:$shft), imm0_31:$pos),
- (SSAT imm0_31:$pos, GPRnopc:$Rn, asr_imm:$shft)>;
-def : ARMPat<(ARMusat (shl GPRnopc:$Rn, imm0_31:$shft), imm0_31:$pos),
- (USAT imm0_31:$pos, GPRnopc:$Rn, imm0_31:$shft)>;
-def : ARMPat<(ARMusat (sra GPRnopc:$Rn, asr_imm:$shft), imm0_31:$pos),
- (USAT imm0_31:$pos, GPRnopc:$Rn, asr_imm:$shft)>;
-
-
+def : ARMV6Pat<(int_arm_ssat (shl GPRnopc:$a, imm0_31:$shft), imm1_32:$pos),
+ (SSAT imm1_32:$pos, GPRnopc:$a, imm0_31:$shft)>;
+def : ARMV6Pat<(int_arm_ssat (sra GPRnopc:$a, asr_imm:$shft), imm1_32:$pos),
+ (SSAT imm1_32:$pos, GPRnopc:$a, asr_imm:$shft)>;
+def : ARMV6Pat<(int_arm_usat (shl GPRnopc:$a, imm0_31:$shft), imm0_31:$pos),
+ (USAT imm0_31:$pos, GPRnopc:$a, imm0_31:$shft)>;
+def : ARMV6Pat<(int_arm_usat (sra GPRnopc:$a, asr_imm:$shft), imm0_31:$pos),
+ (USAT imm0_31:$pos, GPRnopc:$a, asr_imm:$shft)>;
+def : ARMPat<(ARMssat (shl GPRnopc:$Rn, imm0_31:$shft), imm0_31:$pos),
+ (SSAT imm0_31:$pos, GPRnopc:$Rn, imm0_31:$shft)>;
+def : ARMPat<(ARMssat (sra GPRnopc:$Rn, asr_imm:$shft), imm0_31:$pos),
+ (SSAT imm0_31:$pos, GPRnopc:$Rn, asr_imm:$shft)>;
+def : ARMPat<(ARMusat (shl GPRnopc:$Rn, imm0_31:$shft), imm0_31:$pos),
+ (USAT imm0_31:$pos, GPRnopc:$Rn, imm0_31:$shft)>;
+def : ARMPat<(ARMusat (sra GPRnopc:$Rn, asr_imm:$shft), imm0_31:$pos),
+ (USAT imm0_31:$pos, GPRnopc:$Rn, asr_imm:$shft)>;
+
+
//===----------------------------------------------------------------------===//
// Bitwise Instructions.
//
@@ -6381,15 +6381,15 @@ def SPACE : PseudoInst<(outs GPR:$Rd), (ins i32imm:$size, GPR:$Rn),
NoItinerary,
[(set GPR:$Rd, (int_arm_space timm:$size, GPR:$Rn))]>;
-// SpeculationBarrierEndBB must only be used after an unconditional control
-// flow, i.e. after a terminator for which isBarrier is True.
-let hasSideEffects = 1, isCodeGenOnly = 1, isTerminator = 1, isBarrier = 1 in {
- def SpeculationBarrierISBDSBEndBB
- : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
- def SpeculationBarrierSBEndBB
- : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
-}
-
+// SpeculationBarrierEndBB must only be used after an unconditional control
+// flow, i.e. after a terminator for which isBarrier is True.
+let hasSideEffects = 1, isCodeGenOnly = 1, isTerminator = 1, isBarrier = 1 in {
+ def SpeculationBarrierISBDSBEndBB
+ : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
+ def SpeculationBarrierSBEndBB
+ : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
+}
+
//===----------------------------------
// Atomic cmpxchg for -O0
//===----------------------------------
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMInstrMVE.td b/contrib/libs/llvm12/lib/Target/ARM/ARMInstrMVE.td
index 64cef5d967..0dfea68887 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMInstrMVE.td
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMInstrMVE.td
@@ -318,78 +318,78 @@ def MVE_v2f64 : MVEVectorVTInfo<v2f64, ?, v4i1, ?, 0b11, "f", ?>;
def MVE_v16p8 : MVEVectorVTInfo<v16i8, v8i16, v16i1, v8i1, 0b11, "p", 0b0>;
def MVE_v8p16 : MVEVectorVTInfo<v8i16, v4i32, v8i1, v4i1, 0b11, "p", 0b1>;
-multiclass MVE_TwoOpPattern<MVEVectorVTInfo VTI, PatFrag Op, Intrinsic PredInt,
- dag PredOperands, Instruction Inst,
- SDPatternOperator IdentityVec = null_frag> {
- // Unpredicated
- def : Pat<(VTI.Vec (Op (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn))),
- (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn)))>;
-
- // Predicated with select
- if !ne(VTI.Size, 0b11) then {
- def : Pat<(VTI.Vec (vselect (VTI.Pred VCCR:$mask),
- (VTI.Vec (Op (VTI.Vec MQPR:$Qm),
- (VTI.Vec MQPR:$Qn))),
- (VTI.Vec MQPR:$inactive))),
- (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn),
- ARMVCCThen, (VTI.Pred VCCR:$mask),
- (VTI.Vec MQPR:$inactive)))>;
-
- // Optionally with the select folded through the op
- def : Pat<(VTI.Vec (Op (VTI.Vec MQPR:$Qm),
- (VTI.Vec (vselect (VTI.Pred VCCR:$mask),
- (VTI.Vec MQPR:$Qn),
- (VTI.Vec IdentityVec))))),
- (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn),
- ARMVCCThen, (VTI.Pred VCCR:$mask),
- (VTI.Vec MQPR:$Qm)))>;
- }
-
- // Predicated with intrinsic
- def : Pat<(VTI.Vec !con((PredInt (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn)),
- PredOperands,
- (? (VTI.Pred VCCR:$mask), (VTI.Vec MQPR:$inactive)))),
- (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn),
- ARMVCCThen, (VTI.Pred VCCR:$mask),
- (VTI.Vec MQPR:$inactive)))>;
-}
-
-multiclass MVE_TwoOpPatternDup<MVEVectorVTInfo VTI, PatFrag Op, Intrinsic PredInt,
- dag PredOperands, Instruction Inst,
- SDPatternOperator IdentityVec = null_frag> {
- // Unpredicated
- def : Pat<(VTI.Vec (Op (VTI.Vec MQPR:$Qm), (VTI.Vec (ARMvdup rGPR:$Rn)))),
- (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), rGPR:$Rn))>;
-
- // Predicated with select
- if !ne(VTI.Size, 0b11) then {
- def : Pat<(VTI.Vec (vselect (VTI.Pred VCCR:$mask),
- (VTI.Vec (Op (VTI.Vec MQPR:$Qm),
- (VTI.Vec (ARMvdup rGPR:$Rn)))),
- (VTI.Vec MQPR:$inactive))),
- (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), rGPR:$Rn,
- ARMVCCThen, (VTI.Pred VCCR:$mask),
- (VTI.Vec MQPR:$inactive)))>;
-
- // Optionally with the select folded through the op
- def : Pat<(VTI.Vec (Op (VTI.Vec MQPR:$Qm),
- (VTI.Vec (vselect (VTI.Pred VCCR:$mask),
- (ARMvdup rGPR:$Rn),
- (VTI.Vec IdentityVec))))),
- (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), rGPR:$Rn,
- ARMVCCThen, (VTI.Pred VCCR:$mask),
- (VTI.Vec MQPR:$Qm)))>;
- }
-
- // Predicated with intrinsic
- def : Pat<(VTI.Vec !con((PredInt (VTI.Vec MQPR:$Qm), (VTI.Vec (ARMvdup rGPR:$Rn))),
- PredOperands,
- (? (VTI.Pred VCCR:$mask), (VTI.Vec MQPR:$inactive)))),
- (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), rGPR:$Rn,
- ARMVCCThen, (VTI.Pred VCCR:$mask),
- (VTI.Vec MQPR:$inactive)))>;
-}
-
+multiclass MVE_TwoOpPattern<MVEVectorVTInfo VTI, PatFrag Op, Intrinsic PredInt,
+ dag PredOperands, Instruction Inst,
+ SDPatternOperator IdentityVec = null_frag> {
+ // Unpredicated
+ def : Pat<(VTI.Vec (Op (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn))),
+ (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn)))>;
+
+ // Predicated with select
+ if !ne(VTI.Size, 0b11) then {
+ def : Pat<(VTI.Vec (vselect (VTI.Pred VCCR:$mask),
+ (VTI.Vec (Op (VTI.Vec MQPR:$Qm),
+ (VTI.Vec MQPR:$Qn))),
+ (VTI.Vec MQPR:$inactive))),
+ (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn),
+ ARMVCCThen, (VTI.Pred VCCR:$mask),
+ (VTI.Vec MQPR:$inactive)))>;
+
+ // Optionally with the select folded through the op
+ def : Pat<(VTI.Vec (Op (VTI.Vec MQPR:$Qm),
+ (VTI.Vec (vselect (VTI.Pred VCCR:$mask),
+ (VTI.Vec MQPR:$Qn),
+ (VTI.Vec IdentityVec))))),
+ (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn),
+ ARMVCCThen, (VTI.Pred VCCR:$mask),
+ (VTI.Vec MQPR:$Qm)))>;
+ }
+
+ // Predicated with intrinsic
+ def : Pat<(VTI.Vec !con((PredInt (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn)),
+ PredOperands,
+ (? (VTI.Pred VCCR:$mask), (VTI.Vec MQPR:$inactive)))),
+ (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn),
+ ARMVCCThen, (VTI.Pred VCCR:$mask),
+ (VTI.Vec MQPR:$inactive)))>;
+}
+
+multiclass MVE_TwoOpPatternDup<MVEVectorVTInfo VTI, PatFrag Op, Intrinsic PredInt,
+ dag PredOperands, Instruction Inst,
+ SDPatternOperator IdentityVec = null_frag> {
+ // Unpredicated
+ def : Pat<(VTI.Vec (Op (VTI.Vec MQPR:$Qm), (VTI.Vec (ARMvdup rGPR:$Rn)))),
+ (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), rGPR:$Rn))>;
+
+ // Predicated with select
+ if !ne(VTI.Size, 0b11) then {
+ def : Pat<(VTI.Vec (vselect (VTI.Pred VCCR:$mask),
+ (VTI.Vec (Op (VTI.Vec MQPR:$Qm),
+ (VTI.Vec (ARMvdup rGPR:$Rn)))),
+ (VTI.Vec MQPR:$inactive))),
+ (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), rGPR:$Rn,
+ ARMVCCThen, (VTI.Pred VCCR:$mask),
+ (VTI.Vec MQPR:$inactive)))>;
+
+ // Optionally with the select folded through the op
+ def : Pat<(VTI.Vec (Op (VTI.Vec MQPR:$Qm),
+ (VTI.Vec (vselect (VTI.Pred VCCR:$mask),
+ (ARMvdup rGPR:$Rn),
+ (VTI.Vec IdentityVec))))),
+ (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), rGPR:$Rn,
+ ARMVCCThen, (VTI.Pred VCCR:$mask),
+ (VTI.Vec MQPR:$Qm)))>;
+ }
+
+ // Predicated with intrinsic
+ def : Pat<(VTI.Vec !con((PredInt (VTI.Vec MQPR:$Qm), (VTI.Vec (ARMvdup rGPR:$Rn))),
+ PredOperands,
+ (? (VTI.Pred VCCR:$mask), (VTI.Vec MQPR:$inactive)))),
+ (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), rGPR:$Rn,
+ ARMVCCThen, (VTI.Pred VCCR:$mask),
+ (VTI.Vec MQPR:$inactive)))>;
+}
+
// --------- Start of base classes for the instructions themselves
class MVE_MI<dag oops, dag iops, InstrItinClass itin, string asm,
@@ -450,7 +450,7 @@ class MVE_ScalarShift<string iname, dag oops, dag iops, string asm, string cstr,
: MVE_MI_with_pred<oops, iops, NoItinerary, iname, asm, cstr, pattern> {
let Inst{31-20} = 0b111010100101;
let Inst{8} = 0b1;
- let validForTailPredication=1;
+ let validForTailPredication=1;
}
class MVE_ScalarShiftSingleReg<string iname, dag iops, string asm, string cstr,
@@ -684,13 +684,13 @@ class MVE_VADDV<string iname, string suffix, dag iops, string cstr,
let validForTailPredication = 1;
}
-def SDTVecReduceP : SDTypeProfile<1, 2, [ // VADDLVp
- SDTCisInt<0>, SDTCisVec<1>, SDTCisVec<2>
-]>;
+def SDTVecReduceP : SDTypeProfile<1, 2, [ // VADDLVp
+ SDTCisInt<0>, SDTCisVec<1>, SDTCisVec<2>
+]>;
def ARMVADDVs : SDNode<"ARMISD::VADDVs", SDTVecReduce>;
def ARMVADDVu : SDNode<"ARMISD::VADDVu", SDTVecReduce>;
-def ARMVADDVps : SDNode<"ARMISD::VADDVps", SDTVecReduceP>;
-def ARMVADDVpu : SDNode<"ARMISD::VADDVpu", SDTVecReduceP>;
+def ARMVADDVps : SDNode<"ARMISD::VADDVps", SDTVecReduceP>;
+def ARMVADDVpu : SDNode<"ARMISD::VADDVpu", SDTVecReduceP>;
multiclass MVE_VADDV_A<MVEVectorVTInfo VTI> {
def acc : MVE_VADDV<"vaddva", VTI.Suffix,
@@ -707,39 +707,39 @@ multiclass MVE_VADDV_A<MVEVectorVTInfo VTI> {
if VTI.Unsigned then {
def : Pat<(i32 (vecreduce_add (VTI.Vec MQPR:$vec))),
(i32 (InstN $vec))>;
- def : Pat<(i32 (vecreduce_add (VTI.Vec (vselect (VTI.Pred VCCR:$pred),
- (VTI.Vec MQPR:$vec),
- (VTI.Vec ARMimmAllZerosV))))),
- (i32 (InstN $vec, ARMVCCThen, $pred))>;
+ def : Pat<(i32 (vecreduce_add (VTI.Vec (vselect (VTI.Pred VCCR:$pred),
+ (VTI.Vec MQPR:$vec),
+ (VTI.Vec ARMimmAllZerosV))))),
+ (i32 (InstN $vec, ARMVCCThen, $pred))>;
def : Pat<(i32 (ARMVADDVu (VTI.Vec MQPR:$vec))),
(i32 (InstN $vec))>;
- def : Pat<(i32 (ARMVADDVpu (VTI.Vec MQPR:$vec), (VTI.Pred VCCR:$pred))),
- (i32 (InstN $vec, ARMVCCThen, $pred))>;
+ def : Pat<(i32 (ARMVADDVpu (VTI.Vec MQPR:$vec), (VTI.Pred VCCR:$pred))),
+ (i32 (InstN $vec, ARMVCCThen, $pred))>;
def : Pat<(i32 (add (i32 (vecreduce_add (VTI.Vec MQPR:$vec))),
(i32 tGPREven:$acc))),
(i32 (InstA $acc, $vec))>;
- def : Pat<(i32 (add (i32 (vecreduce_add (VTI.Vec (vselect (VTI.Pred VCCR:$pred),
- (VTI.Vec MQPR:$vec),
- (VTI.Vec ARMimmAllZerosV))))),
- (i32 tGPREven:$acc))),
- (i32 (InstA $acc, $vec, ARMVCCThen, $pred))>;
+ def : Pat<(i32 (add (i32 (vecreduce_add (VTI.Vec (vselect (VTI.Pred VCCR:$pred),
+ (VTI.Vec MQPR:$vec),
+ (VTI.Vec ARMimmAllZerosV))))),
+ (i32 tGPREven:$acc))),
+ (i32 (InstA $acc, $vec, ARMVCCThen, $pred))>;
def : Pat<(i32 (add (i32 (ARMVADDVu (VTI.Vec MQPR:$vec))),
(i32 tGPREven:$acc))),
(i32 (InstA $acc, $vec))>;
- def : Pat<(i32 (add (i32 (ARMVADDVpu (VTI.Vec MQPR:$vec), (VTI.Pred VCCR:$pred))),
- (i32 tGPREven:$acc))),
- (i32 (InstA $acc, $vec, ARMVCCThen, $pred))>;
+ def : Pat<(i32 (add (i32 (ARMVADDVpu (VTI.Vec MQPR:$vec), (VTI.Pred VCCR:$pred))),
+ (i32 tGPREven:$acc))),
+ (i32 (InstA $acc, $vec, ARMVCCThen, $pred))>;
} else {
def : Pat<(i32 (ARMVADDVs (VTI.Vec MQPR:$vec))),
(i32 (InstN $vec))>;
def : Pat<(i32 (add (i32 (ARMVADDVs (VTI.Vec MQPR:$vec))),
(i32 tGPREven:$acc))),
(i32 (InstA $acc, $vec))>;
- def : Pat<(i32 (ARMVADDVps (VTI.Vec MQPR:$vec), (VTI.Pred VCCR:$pred))),
- (i32 (InstN $vec, ARMVCCThen, $pred))>;
- def : Pat<(i32 (add (i32 (ARMVADDVps (VTI.Vec MQPR:$vec), (VTI.Pred VCCR:$pred))),
- (i32 tGPREven:$acc))),
- (i32 (InstA $acc, $vec, ARMVCCThen, $pred))>;
+ def : Pat<(i32 (ARMVADDVps (VTI.Vec MQPR:$vec), (VTI.Pred VCCR:$pred))),
+ (i32 (InstN $vec, ARMVCCThen, $pred))>;
+ def : Pat<(i32 (add (i32 (ARMVADDVps (VTI.Vec MQPR:$vec), (VTI.Pred VCCR:$pred))),
+ (i32 tGPREven:$acc))),
+ (i32 (InstA $acc, $vec, ARMVCCThen, $pred))>;
}
def : Pat<(i32 (int_arm_mve_addv_predicated (VTI.Vec MQPR:$vec),
@@ -944,14 +944,14 @@ multiclass MVE_VMINMAXV_ty<string iname, bit isMin, string intrBaseName> {
defm u32: MVE_VMINMAXV_p<iname, 1, isMin, MVE_v4u32, intrBaseName>;
}
-def SDTVecReduceR : SDTypeProfile<1, 2, [ // Reduction of an integer and vector into an integer
- SDTCisInt<0>, SDTCisInt<1>, SDTCisVec<2>
-]>;
-def ARMVMINVu : SDNode<"ARMISD::VMINVu", SDTVecReduceR>;
-def ARMVMINVs : SDNode<"ARMISD::VMINVs", SDTVecReduceR>;
-def ARMVMAXVu : SDNode<"ARMISD::VMAXVu", SDTVecReduceR>;
-def ARMVMAXVs : SDNode<"ARMISD::VMAXVs", SDTVecReduceR>;
-
+def SDTVecReduceR : SDTypeProfile<1, 2, [ // Reduction of an integer and vector into an integer
+ SDTCisInt<0>, SDTCisInt<1>, SDTCisVec<2>
+]>;
+def ARMVMINVu : SDNode<"ARMISD::VMINVu", SDTVecReduceR>;
+def ARMVMINVs : SDNode<"ARMISD::VMINVs", SDTVecReduceR>;
+def ARMVMAXVu : SDNode<"ARMISD::VMAXVu", SDTVecReduceR>;
+def ARMVMAXVs : SDNode<"ARMISD::VMAXVs", SDTVecReduceR>;
+
defm MVE_VMINV : MVE_VMINMAXV_ty<"vminv", 1, "int_arm_mve_minv">;
defm MVE_VMAXV : MVE_VMINMAXV_ty<"vmaxv", 0, "int_arm_mve_maxv">;
@@ -982,32 +982,32 @@ let Predicates = [HasMVEInt] in {
def : Pat<(i32 (vecreduce_umin (v4i32 MQPR:$src))),
(i32 (MVE_VMINVu32 (t2MOVi (i32 4294967295)), $src))>;
- def : Pat<(i32 (ARMVMINVu (i32 rGPR:$x), (v16i8 MQPR:$src))),
- (i32 (MVE_VMINVu8 $x, $src))>;
- def : Pat<(i32 (ARMVMINVu (i32 rGPR:$x), (v8i16 MQPR:$src))),
- (i32 (MVE_VMINVu16 $x, $src))>;
- def : Pat<(i32 (ARMVMINVu (i32 rGPR:$x), (v4i32 MQPR:$src))),
- (i32 (MVE_VMINVu32 $x, $src))>;
- def : Pat<(i32 (ARMVMINVs (i32 rGPR:$x), (v16i8 MQPR:$src))),
- (i32 (MVE_VMINVs8 $x, $src))>;
- def : Pat<(i32 (ARMVMINVs (i32 rGPR:$x), (v8i16 MQPR:$src))),
- (i32 (MVE_VMINVs16 $x, $src))>;
- def : Pat<(i32 (ARMVMINVs (i32 rGPR:$x), (v4i32 MQPR:$src))),
- (i32 (MVE_VMINVs32 $x, $src))>;
-
- def : Pat<(i32 (ARMVMAXVu (i32 rGPR:$x), (v16i8 MQPR:$src))),
- (i32 (MVE_VMAXVu8 $x, $src))>;
- def : Pat<(i32 (ARMVMAXVu (i32 rGPR:$x), (v8i16 MQPR:$src))),
- (i32 (MVE_VMAXVu16 $x, $src))>;
- def : Pat<(i32 (ARMVMAXVu (i32 rGPR:$x), (v4i32 MQPR:$src))),
- (i32 (MVE_VMAXVu32 $x, $src))>;
- def : Pat<(i32 (ARMVMAXVs (i32 rGPR:$x), (v16i8 MQPR:$src))),
- (i32 (MVE_VMAXVs8 $x, $src))>;
- def : Pat<(i32 (ARMVMAXVs (i32 rGPR:$x), (v8i16 MQPR:$src))),
- (i32 (MVE_VMAXVs16 $x, $src))>;
- def : Pat<(i32 (ARMVMAXVs (i32 rGPR:$x), (v4i32 MQPR:$src))),
- (i32 (MVE_VMAXVs32 $x, $src))>;
-
+ def : Pat<(i32 (ARMVMINVu (i32 rGPR:$x), (v16i8 MQPR:$src))),
+ (i32 (MVE_VMINVu8 $x, $src))>;
+ def : Pat<(i32 (ARMVMINVu (i32 rGPR:$x), (v8i16 MQPR:$src))),
+ (i32 (MVE_VMINVu16 $x, $src))>;
+ def : Pat<(i32 (ARMVMINVu (i32 rGPR:$x), (v4i32 MQPR:$src))),
+ (i32 (MVE_VMINVu32 $x, $src))>;
+ def : Pat<(i32 (ARMVMINVs (i32 rGPR:$x), (v16i8 MQPR:$src))),
+ (i32 (MVE_VMINVs8 $x, $src))>;
+ def : Pat<(i32 (ARMVMINVs (i32 rGPR:$x), (v8i16 MQPR:$src))),
+ (i32 (MVE_VMINVs16 $x, $src))>;
+ def : Pat<(i32 (ARMVMINVs (i32 rGPR:$x), (v4i32 MQPR:$src))),
+ (i32 (MVE_VMINVs32 $x, $src))>;
+
+ def : Pat<(i32 (ARMVMAXVu (i32 rGPR:$x), (v16i8 MQPR:$src))),
+ (i32 (MVE_VMAXVu8 $x, $src))>;
+ def : Pat<(i32 (ARMVMAXVu (i32 rGPR:$x), (v8i16 MQPR:$src))),
+ (i32 (MVE_VMAXVu16 $x, $src))>;
+ def : Pat<(i32 (ARMVMAXVu (i32 rGPR:$x), (v4i32 MQPR:$src))),
+ (i32 (MVE_VMAXVu32 $x, $src))>;
+ def : Pat<(i32 (ARMVMAXVs (i32 rGPR:$x), (v16i8 MQPR:$src))),
+ (i32 (MVE_VMAXVs8 $x, $src))>;
+ def : Pat<(i32 (ARMVMAXVs (i32 rGPR:$x), (v8i16 MQPR:$src))),
+ (i32 (MVE_VMAXVs16 $x, $src))>;
+ def : Pat<(i32 (ARMVMAXVs (i32 rGPR:$x), (v4i32 MQPR:$src))),
+ (i32 (MVE_VMAXVs32 $x, $src))>;
+
}
multiclass MVE_VMINMAXAV_ty<string iname, bit isMin, string intrBaseName> {
@@ -1139,28 +1139,28 @@ def SDTVecReduce2LA : SDTypeProfile<2, 4, [ // VMLALVA
SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>, SDTCisInt<3>,
SDTCisVec<4>, SDTCisVec<5>
]>;
-def SDTVecReduce2P : SDTypeProfile<1, 3, [ // VMLAV
- SDTCisInt<0>, SDTCisVec<1>, SDTCisVec<2>, SDTCisVec<3>
-]>;
-def SDTVecReduce2LP : SDTypeProfile<2, 3, [ // VMLALV
- SDTCisInt<0>, SDTCisInt<1>, SDTCisVec<2>, SDTCisVec<3>, SDTCisVec<4>
-]>;
-def SDTVecReduce2LAP : SDTypeProfile<2, 5, [ // VMLALVA
- SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>, SDTCisInt<3>,
- SDTCisVec<4>, SDTCisVec<5>, SDTCisVec<6>
-]>;
+def SDTVecReduce2P : SDTypeProfile<1, 3, [ // VMLAV
+ SDTCisInt<0>, SDTCisVec<1>, SDTCisVec<2>, SDTCisVec<3>
+]>;
+def SDTVecReduce2LP : SDTypeProfile<2, 3, [ // VMLALV
+ SDTCisInt<0>, SDTCisInt<1>, SDTCisVec<2>, SDTCisVec<3>, SDTCisVec<4>
+]>;
+def SDTVecReduce2LAP : SDTypeProfile<2, 5, [ // VMLALVA
+ SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>, SDTCisInt<3>,
+ SDTCisVec<4>, SDTCisVec<5>, SDTCisVec<6>
+]>;
def ARMVMLAVs : SDNode<"ARMISD::VMLAVs", SDTVecReduce2>;
def ARMVMLAVu : SDNode<"ARMISD::VMLAVu", SDTVecReduce2>;
def ARMVMLALVs : SDNode<"ARMISD::VMLALVs", SDTVecReduce2L>;
def ARMVMLALVu : SDNode<"ARMISD::VMLALVu", SDTVecReduce2L>;
-def ARMVMLALVAs : SDNode<"ARMISD::VMLALVAs", SDTVecReduce2LA>;
-def ARMVMLALVAu : SDNode<"ARMISD::VMLALVAu", SDTVecReduce2LA>;
-def ARMVMLAVps : SDNode<"ARMISD::VMLAVps", SDTVecReduce2P>;
-def ARMVMLAVpu : SDNode<"ARMISD::VMLAVpu", SDTVecReduce2P>;
-def ARMVMLALVps : SDNode<"ARMISD::VMLALVps", SDTVecReduce2LP>;
-def ARMVMLALVpu : SDNode<"ARMISD::VMLALVpu", SDTVecReduce2LP>;
-def ARMVMLALVAps : SDNode<"ARMISD::VMLALVAps", SDTVecReduce2LAP>;
-def ARMVMLALVApu : SDNode<"ARMISD::VMLALVApu", SDTVecReduce2LAP>;
+def ARMVMLALVAs : SDNode<"ARMISD::VMLALVAs", SDTVecReduce2LA>;
+def ARMVMLALVAu : SDNode<"ARMISD::VMLALVAu", SDTVecReduce2LA>;
+def ARMVMLAVps : SDNode<"ARMISD::VMLAVps", SDTVecReduce2P>;
+def ARMVMLAVpu : SDNode<"ARMISD::VMLAVpu", SDTVecReduce2P>;
+def ARMVMLALVps : SDNode<"ARMISD::VMLALVps", SDTVecReduce2LP>;
+def ARMVMLALVpu : SDNode<"ARMISD::VMLALVpu", SDTVecReduce2LP>;
+def ARMVMLALVAps : SDNode<"ARMISD::VMLALVAps", SDTVecReduce2LAP>;
+def ARMVMLALVApu : SDNode<"ARMISD::VMLALVApu", SDTVecReduce2LAP>;
let Predicates = [HasMVEInt] in {
def : Pat<(i32 (vecreduce_add (mul (v4i32 MQPR:$src1), (v4i32 MQPR:$src2)))),
@@ -1179,68 +1179,68 @@ let Predicates = [HasMVEInt] in {
(i32 (MVE_VMLADAVu8 (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
def : Pat<(i32 (add (i32 (vecreduce_add (mul (v4i32 MQPR:$src1), (v4i32 MQPR:$src2)))),
- (i32 tGPREven:$src3))),
+ (i32 tGPREven:$src3))),
(i32 (MVE_VMLADAVau32 $src3, $src1, $src2))>;
def : Pat<(i32 (add (i32 (vecreduce_add (mul (v8i16 MQPR:$src1), (v8i16 MQPR:$src2)))),
- (i32 tGPREven:$src3))),
+ (i32 tGPREven:$src3))),
(i32 (MVE_VMLADAVau16 $src3, $src1, $src2))>;
def : Pat<(i32 (add (ARMVMLAVs (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)), tGPREven:$Rd)),
(i32 (MVE_VMLADAVas16 tGPREven:$Rd, (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)))>;
def : Pat<(i32 (add (ARMVMLAVu (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)), tGPREven:$Rd)),
(i32 (MVE_VMLADAVau16 tGPREven:$Rd, (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)))>;
def : Pat<(i32 (add (i32 (vecreduce_add (mul (v16i8 MQPR:$src1), (v16i8 MQPR:$src2)))),
- (i32 tGPREven:$src3))),
+ (i32 tGPREven:$src3))),
(i32 (MVE_VMLADAVau8 $src3, $src1, $src2))>;
def : Pat<(i32 (add (ARMVMLAVs (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)), tGPREven:$Rd)),
(i32 (MVE_VMLADAVas8 tGPREven:$Rd, (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
def : Pat<(i32 (add (ARMVMLAVu (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)), tGPREven:$Rd)),
(i32 (MVE_VMLADAVau8 tGPREven:$Rd, (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
-
- // Predicated
- def : Pat<(i32 (vecreduce_add (vselect (v4i1 VCCR:$pred),
- (mul (v4i32 MQPR:$src1), (v4i32 MQPR:$src2)),
- (v4i32 ARMimmAllZerosV)))),
- (i32 (MVE_VMLADAVu32 $src1, $src2, ARMVCCThen, $pred))>;
- def : Pat<(i32 (vecreduce_add (vselect (v8i1 VCCR:$pred),
- (mul (v8i16 MQPR:$src1), (v8i16 MQPR:$src2)),
- (v8i16 ARMimmAllZerosV)))),
- (i32 (MVE_VMLADAVu16 $src1, $src2, ARMVCCThen, $pred))>;
- def : Pat<(i32 (ARMVMLAVps (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), (v8i1 VCCR:$pred))),
- (i32 (MVE_VMLADAVs16 (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), ARMVCCThen, $pred))>;
- def : Pat<(i32 (ARMVMLAVpu (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), (v8i1 VCCR:$pred))),
- (i32 (MVE_VMLADAVu16 (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), ARMVCCThen, $pred))>;
- def : Pat<(i32 (vecreduce_add (vselect (v16i1 VCCR:$pred),
- (mul (v16i8 MQPR:$src1), (v16i8 MQPR:$src2)),
- (v16i8 ARMimmAllZerosV)))),
- (i32 (MVE_VMLADAVu8 $src1, $src2, ARMVCCThen, $pred))>;
- def : Pat<(i32 (ARMVMLAVps (v16i8 MQPR:$val1), (v16i8 MQPR:$val2), (v16i1 VCCR:$pred))),
- (i32 (MVE_VMLADAVs8 (v16i8 MQPR:$val1), (v16i8 MQPR:$val2), ARMVCCThen, $pred))>;
- def : Pat<(i32 (ARMVMLAVpu (v16i8 MQPR:$val1), (v16i8 MQPR:$val2), (v16i1 VCCR:$pred))),
- (i32 (MVE_VMLADAVu8 (v16i8 MQPR:$val1), (v16i8 MQPR:$val2), ARMVCCThen, $pred))>;
-
- def : Pat<(i32 (add (i32 (vecreduce_add (vselect (v4i1 VCCR:$pred),
- (mul (v4i32 MQPR:$src1), (v4i32 MQPR:$src2)),
- (v4i32 ARMimmAllZerosV)))),
- (i32 tGPREven:$src3))),
- (i32 (MVE_VMLADAVau32 $src3, $src1, $src2, ARMVCCThen, $pred))>;
- def : Pat<(i32 (add (i32 (vecreduce_add (vselect (v8i1 VCCR:$pred),
- (mul (v8i16 MQPR:$src1), (v8i16 MQPR:$src2)),
- (v8i16 ARMimmAllZerosV)))),
- (i32 tGPREven:$src3))),
- (i32 (MVE_VMLADAVau16 $src3, $src1, $src2, ARMVCCThen, $pred))>;
- def : Pat<(i32 (add (ARMVMLAVps (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), (v8i1 VCCR:$pred)), tGPREven:$Rd)),
- (i32 (MVE_VMLADAVas16 tGPREven:$Rd, (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), ARMVCCThen, $pred))>;
- def : Pat<(i32 (add (ARMVMLAVpu (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), (v8i1 VCCR:$pred)), tGPREven:$Rd)),
- (i32 (MVE_VMLADAVau16 tGPREven:$Rd, (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), ARMVCCThen, $pred))>;
- def : Pat<(i32 (add (i32 (vecreduce_add (vselect (v16i1 VCCR:$pred),
- (mul (v16i8 MQPR:$src1), (v16i8 MQPR:$src2)),
- (v16i8 ARMimmAllZerosV)))),
- (i32 tGPREven:$src3))),
- (i32 (MVE_VMLADAVau8 $src3, $src1, $src2, ARMVCCThen, $pred))>;
- def : Pat<(i32 (add (ARMVMLAVps (v16i8 MQPR:$val1), (v16i8 MQPR:$val2), (v16i1 VCCR:$pred)), tGPREven:$Rd)),
- (i32 (MVE_VMLADAVas8 tGPREven:$Rd, (v16i8 MQPR:$val1), (v16i8 MQPR:$val2), ARMVCCThen, $pred))>;
- def : Pat<(i32 (add (ARMVMLAVpu (v16i8 MQPR:$val1), (v16i8 MQPR:$val2), (v16i1 VCCR:$pred)), tGPREven:$Rd)),
- (i32 (MVE_VMLADAVau8 tGPREven:$Rd, (v16i8 MQPR:$val1), (v16i8 MQPR:$val2), ARMVCCThen, $pred))>;
+
+ // Predicated
+ def : Pat<(i32 (vecreduce_add (vselect (v4i1 VCCR:$pred),
+ (mul (v4i32 MQPR:$src1), (v4i32 MQPR:$src2)),
+ (v4i32 ARMimmAllZerosV)))),
+ (i32 (MVE_VMLADAVu32 $src1, $src2, ARMVCCThen, $pred))>;
+ def : Pat<(i32 (vecreduce_add (vselect (v8i1 VCCR:$pred),
+ (mul (v8i16 MQPR:$src1), (v8i16 MQPR:$src2)),
+ (v8i16 ARMimmAllZerosV)))),
+ (i32 (MVE_VMLADAVu16 $src1, $src2, ARMVCCThen, $pred))>;
+ def : Pat<(i32 (ARMVMLAVps (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), (v8i1 VCCR:$pred))),
+ (i32 (MVE_VMLADAVs16 (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), ARMVCCThen, $pred))>;
+ def : Pat<(i32 (ARMVMLAVpu (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), (v8i1 VCCR:$pred))),
+ (i32 (MVE_VMLADAVu16 (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), ARMVCCThen, $pred))>;
+ def : Pat<(i32 (vecreduce_add (vselect (v16i1 VCCR:$pred),
+ (mul (v16i8 MQPR:$src1), (v16i8 MQPR:$src2)),
+ (v16i8 ARMimmAllZerosV)))),
+ (i32 (MVE_VMLADAVu8 $src1, $src2, ARMVCCThen, $pred))>;
+ def : Pat<(i32 (ARMVMLAVps (v16i8 MQPR:$val1), (v16i8 MQPR:$val2), (v16i1 VCCR:$pred))),
+ (i32 (MVE_VMLADAVs8 (v16i8 MQPR:$val1), (v16i8 MQPR:$val2), ARMVCCThen, $pred))>;
+ def : Pat<(i32 (ARMVMLAVpu (v16i8 MQPR:$val1), (v16i8 MQPR:$val2), (v16i1 VCCR:$pred))),
+ (i32 (MVE_VMLADAVu8 (v16i8 MQPR:$val1), (v16i8 MQPR:$val2), ARMVCCThen, $pred))>;
+
+ def : Pat<(i32 (add (i32 (vecreduce_add (vselect (v4i1 VCCR:$pred),
+ (mul (v4i32 MQPR:$src1), (v4i32 MQPR:$src2)),
+ (v4i32 ARMimmAllZerosV)))),
+ (i32 tGPREven:$src3))),
+ (i32 (MVE_VMLADAVau32 $src3, $src1, $src2, ARMVCCThen, $pred))>;
+ def : Pat<(i32 (add (i32 (vecreduce_add (vselect (v8i1 VCCR:$pred),
+ (mul (v8i16 MQPR:$src1), (v8i16 MQPR:$src2)),
+ (v8i16 ARMimmAllZerosV)))),
+ (i32 tGPREven:$src3))),
+ (i32 (MVE_VMLADAVau16 $src3, $src1, $src2, ARMVCCThen, $pred))>;
+ def : Pat<(i32 (add (ARMVMLAVps (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), (v8i1 VCCR:$pred)), tGPREven:$Rd)),
+ (i32 (MVE_VMLADAVas16 tGPREven:$Rd, (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), ARMVCCThen, $pred))>;
+ def : Pat<(i32 (add (ARMVMLAVpu (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), (v8i1 VCCR:$pred)), tGPREven:$Rd)),
+ (i32 (MVE_VMLADAVau16 tGPREven:$Rd, (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), ARMVCCThen, $pred))>;
+ def : Pat<(i32 (add (i32 (vecreduce_add (vselect (v16i1 VCCR:$pred),
+ (mul (v16i8 MQPR:$src1), (v16i8 MQPR:$src2)),
+ (v16i8 ARMimmAllZerosV)))),
+ (i32 tGPREven:$src3))),
+ (i32 (MVE_VMLADAVau8 $src3, $src1, $src2, ARMVCCThen, $pred))>;
+ def : Pat<(i32 (add (ARMVMLAVps (v16i8 MQPR:$val1), (v16i8 MQPR:$val2), (v16i1 VCCR:$pred)), tGPREven:$Rd)),
+ (i32 (MVE_VMLADAVas8 tGPREven:$Rd, (v16i8 MQPR:$val1), (v16i8 MQPR:$val2), ARMVCCThen, $pred))>;
+ def : Pat<(i32 (add (ARMVMLAVpu (v16i8 MQPR:$val1), (v16i8 MQPR:$val2), (v16i1 VCCR:$pred)), tGPREven:$Rd)),
+ (i32 (MVE_VMLADAVau8 tGPREven:$Rd, (v16i8 MQPR:$val1), (v16i8 MQPR:$val2), ARMVCCThen, $pred))>;
}
// vmlav aliases vmladav
@@ -1360,25 +1360,25 @@ let Predicates = [HasMVEInt] in {
(MVE_VMLALDAVas16 tGPREven:$Rda, tGPROdd:$Rdb, (v8i16 MQPR:$val1), (v8i16 MQPR:$val2))>;
def : Pat<(ARMVMLALVAu tGPREven:$Rda, tGPROdd:$Rdb, (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)),
(MVE_VMLALDAVau16 tGPREven:$Rda, tGPROdd:$Rdb, (v8i16 MQPR:$val1), (v8i16 MQPR:$val2))>;
-
- // Predicated
- def : Pat<(ARMVMLALVps (v4i32 MQPR:$val1), (v4i32 MQPR:$val2), (v4i1 VCCR:$pred)),
- (MVE_VMLALDAVs32 (v4i32 MQPR:$val1), (v4i32 MQPR:$val2), ARMVCCThen, $pred)>;
- def : Pat<(ARMVMLALVpu (v4i32 MQPR:$val1), (v4i32 MQPR:$val2), (v4i1 VCCR:$pred)),
- (MVE_VMLALDAVu32 (v4i32 MQPR:$val1), (v4i32 MQPR:$val2), ARMVCCThen, $pred)>;
- def : Pat<(ARMVMLALVps (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), (v8i1 VCCR:$pred)),
- (MVE_VMLALDAVs16 (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), ARMVCCThen, $pred)>;
- def : Pat<(ARMVMLALVpu (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), (v8i1 VCCR:$pred)),
- (MVE_VMLALDAVu16 (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), ARMVCCThen, $pred)>;
-
- def : Pat<(ARMVMLALVAps tGPREven:$Rda, tGPROdd:$Rdb, (v4i32 MQPR:$val1), (v4i32 MQPR:$val2), (v4i1 VCCR:$pred)),
- (MVE_VMLALDAVas32 tGPREven:$Rda, tGPROdd:$Rdb, (v4i32 MQPR:$val1), (v4i32 MQPR:$val2), ARMVCCThen, $pred)>;
- def : Pat<(ARMVMLALVApu tGPREven:$Rda, tGPROdd:$Rdb, (v4i32 MQPR:$val1), (v4i32 MQPR:$val2), (v4i1 VCCR:$pred)),
- (MVE_VMLALDAVau32 tGPREven:$Rda, tGPROdd:$Rdb, (v4i32 MQPR:$val1), (v4i32 MQPR:$val2), ARMVCCThen, $pred)>;
- def : Pat<(ARMVMLALVAps tGPREven:$Rda, tGPROdd:$Rdb, (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), (v8i1 VCCR:$pred)),
- (MVE_VMLALDAVas16 tGPREven:$Rda, tGPROdd:$Rdb, (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), ARMVCCThen, $pred)>;
- def : Pat<(ARMVMLALVApu tGPREven:$Rda, tGPROdd:$Rdb, (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), (v8i1 VCCR:$pred)),
- (MVE_VMLALDAVau16 tGPREven:$Rda, tGPROdd:$Rdb, (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), ARMVCCThen, $pred)>;
+
+ // Predicated
+ def : Pat<(ARMVMLALVps (v4i32 MQPR:$val1), (v4i32 MQPR:$val2), (v4i1 VCCR:$pred)),
+ (MVE_VMLALDAVs32 (v4i32 MQPR:$val1), (v4i32 MQPR:$val2), ARMVCCThen, $pred)>;
+ def : Pat<(ARMVMLALVpu (v4i32 MQPR:$val1), (v4i32 MQPR:$val2), (v4i1 VCCR:$pred)),
+ (MVE_VMLALDAVu32 (v4i32 MQPR:$val1), (v4i32 MQPR:$val2), ARMVCCThen, $pred)>;
+ def : Pat<(ARMVMLALVps (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), (v8i1 VCCR:$pred)),
+ (MVE_VMLALDAVs16 (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), ARMVCCThen, $pred)>;
+ def : Pat<(ARMVMLALVpu (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), (v8i1 VCCR:$pred)),
+ (MVE_VMLALDAVu16 (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), ARMVCCThen, $pred)>;
+
+ def : Pat<(ARMVMLALVAps tGPREven:$Rda, tGPROdd:$Rdb, (v4i32 MQPR:$val1), (v4i32 MQPR:$val2), (v4i1 VCCR:$pred)),
+ (MVE_VMLALDAVas32 tGPREven:$Rda, tGPROdd:$Rdb, (v4i32 MQPR:$val1), (v4i32 MQPR:$val2), ARMVCCThen, $pred)>;
+ def : Pat<(ARMVMLALVApu tGPREven:$Rda, tGPROdd:$Rdb, (v4i32 MQPR:$val1), (v4i32 MQPR:$val2), (v4i1 VCCR:$pred)),
+ (MVE_VMLALDAVau32 tGPREven:$Rda, tGPROdd:$Rdb, (v4i32 MQPR:$val1), (v4i32 MQPR:$val2), ARMVCCThen, $pred)>;
+ def : Pat<(ARMVMLALVAps tGPREven:$Rda, tGPROdd:$Rdb, (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), (v8i1 VCCR:$pred)),
+ (MVE_VMLALDAVas16 tGPREven:$Rda, tGPROdd:$Rdb, (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), ARMVCCThen, $pred)>;
+ def : Pat<(ARMVMLALVApu tGPREven:$Rda, tGPROdd:$Rdb, (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), (v8i1 VCCR:$pred)),
+ (MVE_VMLALDAVau16 tGPREven:$Rda, tGPROdd:$Rdb, (v8i16 MQPR:$val1), (v8i16 MQPR:$val2), ARMVCCThen, $pred)>;
}
// vmlalv aliases vmlaldav
@@ -1426,7 +1426,7 @@ class MVE_comp<InstrItinClass itin, string iname, string suffix,
}
class MVE_VMINMAXNM<string iname, string suffix, bit sz, bit bit_21,
- list<dag> pattern=[]>
+ list<dag> pattern=[]>
: MVE_comp<NoItinerary, iname, suffix, "", pattern> {
let Inst{28} = 0b1;
@@ -1442,18 +1442,18 @@ class MVE_VMINMAXNM<string iname, string suffix, bit sz, bit bit_21,
let Predicates = [HasMVEFloat];
}
-multiclass MVE_VMINMAXNM_m<string iname, bit bit_4, MVEVectorVTInfo VTI, SDNode Op, Intrinsic PredInt> {
- def "" : MVE_VMINMAXNM<iname, VTI.Suffix, VTI.Size{0}, bit_4>;
+multiclass MVE_VMINMAXNM_m<string iname, bit bit_4, MVEVectorVTInfo VTI, SDNode Op, Intrinsic PredInt> {
+ def "" : MVE_VMINMAXNM<iname, VTI.Suffix, VTI.Size{0}, bit_4>;
- let Predicates = [HasMVEFloat] in {
- defm : MVE_TwoOpPattern<VTI, Op, PredInt, (? (i32 0)), !cast<Instruction>(NAME)>;
- }
+ let Predicates = [HasMVEFloat] in {
+ defm : MVE_TwoOpPattern<VTI, Op, PredInt, (? (i32 0)), !cast<Instruction>(NAME)>;
+ }
}
-defm MVE_VMAXNMf32 : MVE_VMINMAXNM_m<"vmaxnm", 0b0, MVE_v4f32, fmaxnum, int_arm_mve_max_predicated>;
-defm MVE_VMAXNMf16 : MVE_VMINMAXNM_m<"vmaxnm", 0b0, MVE_v8f16, fmaxnum, int_arm_mve_max_predicated>;
-defm MVE_VMINNMf32 : MVE_VMINMAXNM_m<"vminnm", 0b1, MVE_v4f32, fminnum, int_arm_mve_min_predicated>;
-defm MVE_VMINNMf16 : MVE_VMINMAXNM_m<"vminnm", 0b1, MVE_v8f16, fminnum, int_arm_mve_min_predicated>;
+defm MVE_VMAXNMf32 : MVE_VMINMAXNM_m<"vmaxnm", 0b0, MVE_v4f32, fmaxnum, int_arm_mve_max_predicated>;
+defm MVE_VMAXNMf16 : MVE_VMINMAXNM_m<"vmaxnm", 0b0, MVE_v8f16, fmaxnum, int_arm_mve_max_predicated>;
+defm MVE_VMINNMf32 : MVE_VMINMAXNM_m<"vminnm", 0b1, MVE_v4f32, fminnum, int_arm_mve_min_predicated>;
+defm MVE_VMINNMf16 : MVE_VMINMAXNM_m<"vminnm", 0b1, MVE_v8f16, fminnum, int_arm_mve_min_predicated>;
class MVE_VMINMAX<string iname, string suffix, bit U, bits<2> size,
@@ -1472,11 +1472,11 @@ class MVE_VMINMAX<string iname, string suffix, bit U, bits<2> size,
}
multiclass MVE_VMINMAX_m<string iname, bit bit_4, MVEVectorVTInfo VTI,
- SDNode Op, Intrinsic PredInt> {
+ SDNode Op, Intrinsic PredInt> {
def "" : MVE_VMINMAX<iname, VTI.Suffix, VTI.Unsigned, VTI.Size, bit_4>;
let Predicates = [HasMVEInt] in {
- defm : MVE_TwoOpPattern<VTI, Op, PredInt, (? (i32 VTI.Unsigned)), !cast<Instruction>(NAME)>;
+ defm : MVE_TwoOpPattern<VTI, Op, PredInt, (? (i32 VTI.Unsigned)), !cast<Instruction>(NAME)>;
}
}
@@ -1649,39 +1649,39 @@ foreach s=["s8", "s16", "s32", "u8", "u16", "u32", "i8", "i16", "i32", "f16", "f
(MVE_VAND MQPR:$QdSrc, MQPR:$QnSrc, MQPR:$QmSrc, vpred_r:$vp)>;
}
-let Predicates = [HasMVEInt] in {
- defm : MVE_TwoOpPattern<MVE_v16i8, and, int_arm_mve_and_predicated, (? ), MVE_VAND, ARMimmAllOnesV>;
- defm : MVE_TwoOpPattern<MVE_v8i16, and, int_arm_mve_and_predicated, (? ), MVE_VAND, ARMimmAllOnesV>;
- defm : MVE_TwoOpPattern<MVE_v4i32, and, int_arm_mve_and_predicated, (? ), MVE_VAND, ARMimmAllOnesV>;
- defm : MVE_TwoOpPattern<MVE_v2i64, and, int_arm_mve_and_predicated, (? ), MVE_VAND, ARMimmAllOnesV>;
-
- defm : MVE_TwoOpPattern<MVE_v16i8, or, int_arm_mve_orr_predicated, (? ), MVE_VORR, ARMimmAllZerosV>;
- defm : MVE_TwoOpPattern<MVE_v8i16, or, int_arm_mve_orr_predicated, (? ), MVE_VORR, ARMimmAllZerosV>;
- defm : MVE_TwoOpPattern<MVE_v4i32, or, int_arm_mve_orr_predicated, (? ), MVE_VORR, ARMimmAllZerosV>;
- defm : MVE_TwoOpPattern<MVE_v2i64, or, int_arm_mve_orr_predicated, (? ), MVE_VORR, ARMimmAllZerosV>;
-
- defm : MVE_TwoOpPattern<MVE_v16i8, xor, int_arm_mve_eor_predicated, (? ), MVE_VEOR, ARMimmAllZerosV>;
- defm : MVE_TwoOpPattern<MVE_v8i16, xor, int_arm_mve_eor_predicated, (? ), MVE_VEOR, ARMimmAllZerosV>;
- defm : MVE_TwoOpPattern<MVE_v4i32, xor, int_arm_mve_eor_predicated, (? ), MVE_VEOR, ARMimmAllZerosV>;
- defm : MVE_TwoOpPattern<MVE_v2i64, xor, int_arm_mve_eor_predicated, (? ), MVE_VEOR, ARMimmAllZerosV>;
-
- defm : MVE_TwoOpPattern<MVE_v16i8, BinOpFrag<(and node:$LHS, (vnotq node:$RHS))>,
- int_arm_mve_bic_predicated, (? ), MVE_VBIC>;
- defm : MVE_TwoOpPattern<MVE_v8i16, BinOpFrag<(and node:$LHS, (vnotq node:$RHS))>,
- int_arm_mve_bic_predicated, (? ), MVE_VBIC>;
- defm : MVE_TwoOpPattern<MVE_v4i32, BinOpFrag<(and node:$LHS, (vnotq node:$RHS))>,
- int_arm_mve_bic_predicated, (? ), MVE_VBIC>;
- defm : MVE_TwoOpPattern<MVE_v2i64, BinOpFrag<(and node:$LHS, (vnotq node:$RHS))>,
- int_arm_mve_bic_predicated, (? ), MVE_VBIC>;
-
- defm : MVE_TwoOpPattern<MVE_v16i8, BinOpFrag<(or node:$LHS, (vnotq node:$RHS))>,
- int_arm_mve_orn_predicated, (? ), MVE_VORN>;
- defm : MVE_TwoOpPattern<MVE_v8i16, BinOpFrag<(or node:$LHS, (vnotq node:$RHS))>,
- int_arm_mve_orn_predicated, (? ), MVE_VORN>;
- defm : MVE_TwoOpPattern<MVE_v4i32, BinOpFrag<(or node:$LHS, (vnotq node:$RHS))>,
- int_arm_mve_orn_predicated, (? ), MVE_VORN>;
- defm : MVE_TwoOpPattern<MVE_v2i64, BinOpFrag<(or node:$LHS, (vnotq node:$RHS))>,
- int_arm_mve_orn_predicated, (? ), MVE_VORN>;
+let Predicates = [HasMVEInt] in {
+ defm : MVE_TwoOpPattern<MVE_v16i8, and, int_arm_mve_and_predicated, (? ), MVE_VAND, ARMimmAllOnesV>;
+ defm : MVE_TwoOpPattern<MVE_v8i16, and, int_arm_mve_and_predicated, (? ), MVE_VAND, ARMimmAllOnesV>;
+ defm : MVE_TwoOpPattern<MVE_v4i32, and, int_arm_mve_and_predicated, (? ), MVE_VAND, ARMimmAllOnesV>;
+ defm : MVE_TwoOpPattern<MVE_v2i64, and, int_arm_mve_and_predicated, (? ), MVE_VAND, ARMimmAllOnesV>;
+
+ defm : MVE_TwoOpPattern<MVE_v16i8, or, int_arm_mve_orr_predicated, (? ), MVE_VORR, ARMimmAllZerosV>;
+ defm : MVE_TwoOpPattern<MVE_v8i16, or, int_arm_mve_orr_predicated, (? ), MVE_VORR, ARMimmAllZerosV>;
+ defm : MVE_TwoOpPattern<MVE_v4i32, or, int_arm_mve_orr_predicated, (? ), MVE_VORR, ARMimmAllZerosV>;
+ defm : MVE_TwoOpPattern<MVE_v2i64, or, int_arm_mve_orr_predicated, (? ), MVE_VORR, ARMimmAllZerosV>;
+
+ defm : MVE_TwoOpPattern<MVE_v16i8, xor, int_arm_mve_eor_predicated, (? ), MVE_VEOR, ARMimmAllZerosV>;
+ defm : MVE_TwoOpPattern<MVE_v8i16, xor, int_arm_mve_eor_predicated, (? ), MVE_VEOR, ARMimmAllZerosV>;
+ defm : MVE_TwoOpPattern<MVE_v4i32, xor, int_arm_mve_eor_predicated, (? ), MVE_VEOR, ARMimmAllZerosV>;
+ defm : MVE_TwoOpPattern<MVE_v2i64, xor, int_arm_mve_eor_predicated, (? ), MVE_VEOR, ARMimmAllZerosV>;
+
+ defm : MVE_TwoOpPattern<MVE_v16i8, BinOpFrag<(and node:$LHS, (vnotq node:$RHS))>,
+ int_arm_mve_bic_predicated, (? ), MVE_VBIC>;
+ defm : MVE_TwoOpPattern<MVE_v8i16, BinOpFrag<(and node:$LHS, (vnotq node:$RHS))>,
+ int_arm_mve_bic_predicated, (? ), MVE_VBIC>;
+ defm : MVE_TwoOpPattern<MVE_v4i32, BinOpFrag<(and node:$LHS, (vnotq node:$RHS))>,
+ int_arm_mve_bic_predicated, (? ), MVE_VBIC>;
+ defm : MVE_TwoOpPattern<MVE_v2i64, BinOpFrag<(and node:$LHS, (vnotq node:$RHS))>,
+ int_arm_mve_bic_predicated, (? ), MVE_VBIC>;
+
+ defm : MVE_TwoOpPattern<MVE_v16i8, BinOpFrag<(or node:$LHS, (vnotq node:$RHS))>,
+ int_arm_mve_orn_predicated, (? ), MVE_VORN>;
+ defm : MVE_TwoOpPattern<MVE_v8i16, BinOpFrag<(or node:$LHS, (vnotq node:$RHS))>,
+ int_arm_mve_orn_predicated, (? ), MVE_VORN>;
+ defm : MVE_TwoOpPattern<MVE_v4i32, BinOpFrag<(or node:$LHS, (vnotq node:$RHS))>,
+ int_arm_mve_orn_predicated, (? ), MVE_VORN>;
+ defm : MVE_TwoOpPattern<MVE_v2i64, BinOpFrag<(or node:$LHS, (vnotq node:$RHS))>,
+ int_arm_mve_orn_predicated, (? ), MVE_VORN>;
}
class MVE_bit_cmode<string iname, string suffix, bit halfword, dag inOps>
@@ -1718,8 +1718,8 @@ multiclass MVE_bit_cmode_p<string iname, bit opcode,
defvar UnpredPat = (VTI.Vec (op (VTI.Vec MQPR:$src), timm:$simm));
let Predicates = [HasMVEInt] in {
- def : Pat<UnpredPat,
- (VTI.Vec (Inst (VTI.Vec MQPR:$src), imm_type:$simm))>;
+ def : Pat<UnpredPat,
+ (VTI.Vec (Inst (VTI.Vec MQPR:$src), imm_type:$simm))>;
def : Pat<(VTI.Vec (vselect (VTI.Pred VCCR:$pred),
UnpredPat, (VTI.Vec MQPR:$src))),
(VTI.Vec (Inst (VTI.Vec MQPR:$src), imm_type:$simm,
@@ -1929,18 +1929,18 @@ class MVE_VMULt1<string iname, string suffix, bits<2> size,
let validForTailPredication = 1;
}
-multiclass MVE_VMUL_m<MVEVectorVTInfo VTI> {
- def "" : MVE_VMULt1<"vmul", VTI.Suffix, VTI.Size>;
+multiclass MVE_VMUL_m<MVEVectorVTInfo VTI> {
+ def "" : MVE_VMULt1<"vmul", VTI.Suffix, VTI.Size>;
let Predicates = [HasMVEInt] in {
- defm : MVE_TwoOpPattern<VTI, mul, int_arm_mve_mul_predicated, (? ),
- !cast<Instruction>(NAME), ARMimmOneV>;
+ defm : MVE_TwoOpPattern<VTI, mul, int_arm_mve_mul_predicated, (? ),
+ !cast<Instruction>(NAME), ARMimmOneV>;
}
}
-defm MVE_VMULi8 : MVE_VMUL_m<MVE_v16i8>;
-defm MVE_VMULi16 : MVE_VMUL_m<MVE_v8i16>;
-defm MVE_VMULi32 : MVE_VMUL_m<MVE_v4i32>;
+defm MVE_VMULi8 : MVE_VMUL_m<MVE_v16i8>;
+defm MVE_VMULi16 : MVE_VMUL_m<MVE_v8i16>;
+defm MVE_VMULi32 : MVE_VMUL_m<MVE_v4i32>;
class MVE_VQxDMULH_Base<string iname, string suffix, bits<2> size, bit rounding,
list<dag> pattern=[]>
@@ -1952,30 +1952,30 @@ class MVE_VQxDMULH_Base<string iname, string suffix, bits<2> size, bit rounding,
let Inst{12-8} = 0b01011;
let Inst{4} = 0b0;
let Inst{0} = 0b0;
- let validForTailPredication = 1;
+ let validForTailPredication = 1;
}
-def MVEvqdmulh : SDNode<"ARMISD::VQDMULH", SDTIntBinOp>;
-
+def MVEvqdmulh : SDNode<"ARMISD::VQDMULH", SDTIntBinOp>;
+
multiclass MVE_VQxDMULH_m<string iname, MVEVectorVTInfo VTI,
- SDNode Op, Intrinsic unpred_int, Intrinsic pred_int,
+ SDNode Op, Intrinsic unpred_int, Intrinsic pred_int,
bit rounding> {
def "" : MVE_VQxDMULH_Base<iname, VTI.Suffix, VTI.Size, rounding>;
defvar Inst = !cast<Instruction>(NAME);
let Predicates = [HasMVEInt] in {
- defm : MVE_TwoOpPattern<VTI, Op, pred_int, (? ), Inst>;
-
- // Extra unpredicated multiply intrinsic patterns
- def : Pat<(VTI.Vec (unpred_int (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn))),
+ defm : MVE_TwoOpPattern<VTI, Op, pred_int, (? ), Inst>;
+
+ // Extra unpredicated multiply intrinsic patterns
+ def : Pat<(VTI.Vec (unpred_int (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn))),
(VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn)))>;
}
}
multiclass MVE_VQxDMULH<string iname, MVEVectorVTInfo VTI, bit rounding>
- : MVE_VQxDMULH_m<iname, VTI, !if(rounding, null_frag,
- MVEvqdmulh),
- !if(rounding, int_arm_mve_vqrdmulh,
+ : MVE_VQxDMULH_m<iname, VTI, !if(rounding, null_frag,
+ MVEvqdmulh),
+ !if(rounding, int_arm_mve_vqrdmulh,
int_arm_mve_vqdmulh),
!if(rounding, int_arm_mve_qrdmulh_predicated,
int_arm_mve_qdmulh_predicated),
@@ -2003,12 +2003,12 @@ class MVE_VADDSUB<string iname, string suffix, bits<2> size, bit subtract,
}
multiclass MVE_VADDSUB_m<string iname, MVEVectorVTInfo VTI, bit subtract,
- SDNode Op, Intrinsic PredInt> {
+ SDNode Op, Intrinsic PredInt> {
def "" : MVE_VADDSUB<iname, VTI.Suffix, VTI.Size, subtract>;
defvar Inst = !cast<Instruction>(NAME);
let Predicates = [HasMVEInt] in {
- defm : MVE_TwoOpPattern<VTI, Op, PredInt, (? ), !cast<Instruction>(NAME), ARMimmAllZerosV>;
+ defm : MVE_TwoOpPattern<VTI, Op, PredInt, (? ), !cast<Instruction>(NAME), ARMimmAllZerosV>;
}
}
@@ -2046,13 +2046,13 @@ class MVE_VQSUB_<string suffix, bit U, bits<2> size>
: MVE_VQADDSUB<"vqsub", suffix, U, 0b1, size>;
multiclass MVE_VQADD_m<MVEVectorVTInfo VTI,
- SDNode Op, Intrinsic PredInt> {
+ SDNode Op, Intrinsic PredInt> {
def "" : MVE_VQADD_<VTI.Suffix, VTI.Unsigned, VTI.Size>;
defvar Inst = !cast<Instruction>(NAME);
let Predicates = [HasMVEInt] in {
- defm : MVE_TwoOpPattern<VTI, Op, PredInt, (? (i32 VTI.Unsigned)),
- !cast<Instruction>(NAME)>;
+ defm : MVE_TwoOpPattern<VTI, Op, PredInt, (? (i32 VTI.Unsigned)),
+ !cast<Instruction>(NAME)>;
}
}
@@ -2067,13 +2067,13 @@ defm MVE_VQADDu16 : MVE_VQADD<MVE_v8u16, uaddsat>;
defm MVE_VQADDu32 : MVE_VQADD<MVE_v4u32, uaddsat>;
multiclass MVE_VQSUB_m<MVEVectorVTInfo VTI,
- SDNode Op, Intrinsic PredInt> {
+ SDNode Op, Intrinsic PredInt> {
def "" : MVE_VQSUB_<VTI.Suffix, VTI.Unsigned, VTI.Size>;
defvar Inst = !cast<Instruction>(NAME);
let Predicates = [HasMVEInt] in {
- defm : MVE_TwoOpPattern<VTI, Op, PredInt, (? (i32 VTI.Unsigned)),
- !cast<Instruction>(NAME)>;
+ defm : MVE_TwoOpPattern<VTI, Op, PredInt, (? (i32 VTI.Unsigned)),
+ !cast<Instruction>(NAME)>;
}
}
@@ -2199,32 +2199,32 @@ defm MVE_VRHADDu32 : MVE_VRHADD<MVE_v4u32>;
// modelling that here with these patterns, but we're using no wrap forms of
// add to ensure that the extra bit of information is not needed for the
// arithmetic or the rounding.
-let Predicates = [HasMVEInt] in {
- def : Pat<(v16i8 (ARMvshrsImm (addnsw (addnsw (v16i8 MQPR:$Qm), (v16i8 MQPR:$Qn)),
- (v16i8 (ARMvmovImm (i32 3585)))),
- (i32 1))),
- (MVE_VRHADDs8 MQPR:$Qm, MQPR:$Qn)>;
- def : Pat<(v8i16 (ARMvshrsImm (addnsw (addnsw (v8i16 MQPR:$Qm), (v8i16 MQPR:$Qn)),
- (v8i16 (ARMvmovImm (i32 2049)))),
- (i32 1))),
- (MVE_VRHADDs16 MQPR:$Qm, MQPR:$Qn)>;
- def : Pat<(v4i32 (ARMvshrsImm (addnsw (addnsw (v4i32 MQPR:$Qm), (v4i32 MQPR:$Qn)),
- (v4i32 (ARMvmovImm (i32 1)))),
- (i32 1))),
- (MVE_VRHADDs32 MQPR:$Qm, MQPR:$Qn)>;
- def : Pat<(v16i8 (ARMvshruImm (addnuw (addnuw (v16i8 MQPR:$Qm), (v16i8 MQPR:$Qn)),
- (v16i8 (ARMvmovImm (i32 3585)))),
- (i32 1))),
- (MVE_VRHADDu8 MQPR:$Qm, MQPR:$Qn)>;
- def : Pat<(v8i16 (ARMvshruImm (addnuw (addnuw (v8i16 MQPR:$Qm), (v8i16 MQPR:$Qn)),
- (v8i16 (ARMvmovImm (i32 2049)))),
- (i32 1))),
- (MVE_VRHADDu16 MQPR:$Qm, MQPR:$Qn)>;
- def : Pat<(v4i32 (ARMvshruImm (addnuw (addnuw (v4i32 MQPR:$Qm), (v4i32 MQPR:$Qn)),
- (v4i32 (ARMvmovImm (i32 1)))),
- (i32 1))),
- (MVE_VRHADDu32 MQPR:$Qm, MQPR:$Qn)>;
-}
+let Predicates = [HasMVEInt] in {
+ def : Pat<(v16i8 (ARMvshrsImm (addnsw (addnsw (v16i8 MQPR:$Qm), (v16i8 MQPR:$Qn)),
+ (v16i8 (ARMvmovImm (i32 3585)))),
+ (i32 1))),
+ (MVE_VRHADDs8 MQPR:$Qm, MQPR:$Qn)>;
+ def : Pat<(v8i16 (ARMvshrsImm (addnsw (addnsw (v8i16 MQPR:$Qm), (v8i16 MQPR:$Qn)),
+ (v8i16 (ARMvmovImm (i32 2049)))),
+ (i32 1))),
+ (MVE_VRHADDs16 MQPR:$Qm, MQPR:$Qn)>;
+ def : Pat<(v4i32 (ARMvshrsImm (addnsw (addnsw (v4i32 MQPR:$Qm), (v4i32 MQPR:$Qn)),
+ (v4i32 (ARMvmovImm (i32 1)))),
+ (i32 1))),
+ (MVE_VRHADDs32 MQPR:$Qm, MQPR:$Qn)>;
+ def : Pat<(v16i8 (ARMvshruImm (addnuw (addnuw (v16i8 MQPR:$Qm), (v16i8 MQPR:$Qn)),
+ (v16i8 (ARMvmovImm (i32 3585)))),
+ (i32 1))),
+ (MVE_VRHADDu8 MQPR:$Qm, MQPR:$Qn)>;
+ def : Pat<(v8i16 (ARMvshruImm (addnuw (addnuw (v8i16 MQPR:$Qm), (v8i16 MQPR:$Qn)),
+ (v8i16 (ARMvmovImm (i32 2049)))),
+ (i32 1))),
+ (MVE_VRHADDu16 MQPR:$Qm, MQPR:$Qn)>;
+ def : Pat<(v4i32 (ARMvshruImm (addnuw (addnuw (v4i32 MQPR:$Qm), (v4i32 MQPR:$Qn)),
+ (v4i32 (ARMvmovImm (i32 1)))),
+ (i32 1))),
+ (MVE_VRHADDu32 MQPR:$Qm, MQPR:$Qn)>;
+}
class MVE_VHADDSUB<string iname, string suffix, bit U, bit subtract,
@@ -2473,9 +2473,9 @@ multiclass MVE_VABSNEG_int_m<string iname, bit negate, bit saturate,
let Predicates = [HasMVEInt] in {
// VQABS and VQNEG have more difficult isel patterns defined elsewhere
- if !not(saturate) then {
- def : Pat<(VTI.Vec (unpred_op (VTI.Vec MQPR:$v))),
- (VTI.Vec (Inst $v))>;
+ if !not(saturate) then {
+ def : Pat<(VTI.Vec (unpred_op (VTI.Vec MQPR:$v))),
+ (VTI.Vec (Inst $v))>;
}
def : Pat<(VTI.Vec (pred_int (VTI.Vec MQPR:$v), (VTI.Pred VCCR:$mask),
@@ -3032,7 +3032,7 @@ multiclass MVE_VSHRN_patterns<MVE_shift_imm_partial inst,
defvar outparams = (inst (OutVTI.Vec MQPR:$QdSrc), (InVTI.Vec MQPR:$Qm),
(imm:$imm));
- def : Pat<(OutVTI.Vec !setdagop(inparams, int_arm_mve_vshrn)),
+ def : Pat<(OutVTI.Vec !setdagop(inparams, int_arm_mve_vshrn)),
(OutVTI.Vec outparams)>;
def : Pat<(OutVTI.Vec !con(inparams, (int_arm_mve_vshrn_predicated
(InVTI.Pred VCCR:$pred)))),
@@ -3234,7 +3234,7 @@ multiclass MVE_VSxI_patterns<MVE_VSxI_imm inst, string name,
defvar unpred_int = !cast<Intrinsic>("int_arm_mve_" # name);
defvar pred_int = !cast<Intrinsic>("int_arm_mve_" # name # "_predicated");
- def : Pat<(VTI.Vec !setdagop(inparams, unpred_int)),
+ def : Pat<(VTI.Vec !setdagop(inparams, unpred_int)),
(VTI.Vec outparams)>;
def : Pat<(VTI.Vec !con(inparams, (pred_int (VTI.Pred VCCR:$pred)))),
(VTI.Vec !con(outparams, (? ARMVCCThen, VCCR:$pred)))>;
@@ -3586,12 +3586,12 @@ class MVE_VMUL_fp<string iname, string suffix, bit size, list<dag> pattern=[]>
}
multiclass MVE_VMULT_fp_m<string iname, bit bit_21, MVEVectorVTInfo VTI,
- SDNode Op, Intrinsic PredInt> {
+ SDNode Op, Intrinsic PredInt> {
def "" : MVE_VMUL_fp<iname, VTI.Suffix, VTI.Size{0}>;
defvar Inst = !cast<Instruction>(NAME);
let Predicates = [HasMVEFloat] in {
- defm : MVE_TwoOpPattern<VTI, Op, PredInt, (? ), !cast<Instruction>(NAME)>;
+ defm : MVE_TwoOpPattern<VTI, Op, PredInt, (? ), !cast<Instruction>(NAME)>;
}
}
@@ -3682,23 +3682,23 @@ multiclass MVE_VFMA_fp_multi<string iname, bit fms, MVEVectorVTInfo VTI> {
let Predicates = [HasMVEFloat] in {
if fms then {
- def : Pat<(VTI.Vec (fma (fneg m1), m2, add)),
- (Inst $add, $m1, $m2)>;
- def : Pat<(VTI.Vec (vselect (VTI.Pred VCCR:$pred),
- (VTI.Vec (fma (fneg m1), m2, add)),
- add)),
- (Inst $add, $m1, $m2, ARMVCCThen, $pred)>;
+ def : Pat<(VTI.Vec (fma (fneg m1), m2, add)),
+ (Inst $add, $m1, $m2)>;
+ def : Pat<(VTI.Vec (vselect (VTI.Pred VCCR:$pred),
+ (VTI.Vec (fma (fneg m1), m2, add)),
+ add)),
+ (Inst $add, $m1, $m2, ARMVCCThen, $pred)>;
def : Pat<(VTI.Vec (pred_int (fneg m1), m2, add, pred)),
(Inst $add, $m1, $m2, ARMVCCThen, $pred)>;
def : Pat<(VTI.Vec (pred_int m1, (fneg m2), add, pred)),
(Inst $add, $m1, $m2, ARMVCCThen, $pred)>;
} else {
- def : Pat<(VTI.Vec (fma m1, m2, add)),
- (Inst $add, $m1, $m2)>;
- def : Pat<(VTI.Vec (vselect (VTI.Pred VCCR:$pred),
- (VTI.Vec (fma m1, m2, add)),
- add)),
- (Inst $add, $m1, $m2, ARMVCCThen, $pred)>;
+ def : Pat<(VTI.Vec (fma m1, m2, add)),
+ (Inst $add, $m1, $m2)>;
+ def : Pat<(VTI.Vec (vselect (VTI.Pred VCCR:$pred),
+ (VTI.Vec (fma m1, m2, add)),
+ add)),
+ (Inst $add, $m1, $m2, ARMVCCThen, $pred)>;
def : Pat<(VTI.Vec (pred_int m1, m2, add, pred)),
(Inst $add, $m1, $m2, ARMVCCThen, $pred)>;
}
@@ -3711,14 +3711,14 @@ defm MVE_VFMSf32 : MVE_VFMA_fp_multi<"vfms", 1, MVE_v4f32>;
defm MVE_VFMSf16 : MVE_VFMA_fp_multi<"vfms", 1, MVE_v8f16>;
multiclass MVE_VADDSUB_fp_m<string iname, bit bit_21, MVEVectorVTInfo VTI,
- SDNode Op, Intrinsic PredInt> {
+ SDNode Op, Intrinsic PredInt> {
def "" : MVE_VADDSUBFMA_fp<iname, VTI.Suffix, VTI.Size{0}, 0, 1, bit_21> {
let validForTailPredication = 1;
}
defvar Inst = !cast<Instruction>(NAME);
let Predicates = [HasMVEFloat] in {
- defm : MVE_TwoOpPattern<VTI, Op, PredInt, (? ), !cast<Instruction>(NAME)>;
+ defm : MVE_TwoOpPattern<VTI, Op, PredInt, (? ), !cast<Instruction>(NAME)>;
}
}
@@ -3820,15 +3820,15 @@ multiclass MVE_VABD_fp_m<MVEVectorVTInfo VTI>
: MVE_VABDT_fp_m<VTI, int_arm_mve_vabd, int_arm_mve_abd_predicated>;
defm MVE_VABDf32 : MVE_VABD_fp_m<MVE_v4f32>;
-defm MVE_VABDf16 : MVE_VABD_fp_m<MVE_v8f16>;
-
-let Predicates = [HasMVEFloat] in {
- def : Pat<(v8f16 (fabs (fsub (v8f16 MQPR:$Qm), (v8f16 MQPR:$Qn)))),
- (MVE_VABDf16 MQPR:$Qm, MQPR:$Qn)>;
- def : Pat<(v4f32 (fabs (fsub (v4f32 MQPR:$Qm), (v4f32 MQPR:$Qn)))),
- (MVE_VABDf32 MQPR:$Qm, MQPR:$Qn)>;
-}
-
+defm MVE_VABDf16 : MVE_VABD_fp_m<MVE_v8f16>;
+
+let Predicates = [HasMVEFloat] in {
+ def : Pat<(v8f16 (fabs (fsub (v8f16 MQPR:$Qm), (v8f16 MQPR:$Qn)))),
+ (MVE_VABDf16 MQPR:$Qm, MQPR:$Qn)>;
+ def : Pat<(v4f32 (fabs (fsub (v4f32 MQPR:$Qm), (v4f32 MQPR:$Qn)))),
+ (MVE_VABDf32 MQPR:$Qm, MQPR:$Qn)>;
+}
+
class MVE_VCVT_fix<string suffix, bit fsi, bit U, bit op,
Operand imm_operand_type>
: MVE_float<"vcvt", suffix,
@@ -4047,8 +4047,8 @@ multiclass MVE_VABSNEG_fp_m<string iname, SDNode unpred_op, Intrinsic pred_int,
defvar Inst = !cast<Instruction>(NAME);
let Predicates = [HasMVEInt] in {
- def : Pat<(VTI.Vec (unpred_op (VTI.Vec MQPR:$v))),
- (VTI.Vec (Inst $v))>;
+ def : Pat<(VTI.Vec (unpred_op (VTI.Vec MQPR:$v))),
+ (VTI.Vec (Inst $v))>;
def : Pat<(VTI.Vec (pred_int (VTI.Vec MQPR:$v), (VTI.Pred VCCR:$mask),
(VTI.Vec MQPR:$inactive))),
(VTI.Vec (Inst $v, ARMVCCThen, $mask, $inactive))>;
@@ -4083,8 +4083,8 @@ class MVE_VMAXMINNMA<string iname, string suffix, bit size, bit bit_12,
let Inst{4} = 0b0;
let Inst{3-1} = Qm{2-0};
let Inst{0} = 0b1;
-
- let isCommutable = 1;
+
+ let isCommutable = 1;
}
multiclass MVE_VMAXMINNMA_m<string iname, MVEVectorVTInfo VTI,
@@ -4410,10 +4410,10 @@ let Predicates = [HasMVEInt] in {
// vector types (v4i1<>v8i1, etc.) also as part of lowering vector shuffles.
def predicate_cast : SDNode<"ARMISD::PREDICATE_CAST", SDTUnaryOp>;
-def load_align4 : PatFrag<(ops node:$ptr), (load node:$ptr), [{
- return cast<LoadSDNode>(N)->getAlignment() >= 4;
-}]>;
-
+def load_align4 : PatFrag<(ops node:$ptr), (load node:$ptr), [{
+ return cast<LoadSDNode>(N)->getAlignment() >= 4;
+}]>;
+
let Predicates = [HasMVEInt] in {
foreach VT = [ v4i1, v8i1, v16i1 ] in {
def : Pat<(i32 (predicate_cast (VT VCCR:$src))),
@@ -4426,13 +4426,13 @@ let Predicates = [HasMVEInt] in {
(VT (COPY_TO_REGCLASS (VT2 VCCR:$src), VCCR))>;
}
- // If we happen to be casting from a load we can convert that straight
- // into a predicate load, so long as the load is of the correct type.
- foreach VT = [ v4i1, v8i1, v16i1 ] in {
- def : Pat<(VT (predicate_cast (i32 (load_align4 taddrmode_imm7<2>:$addr)))),
- (VT (VLDR_P0_off taddrmode_imm7<2>:$addr))>;
- }
-
+ // If we happen to be casting from a load we can convert that straight
+ // into a predicate load, so long as the load is of the correct type.
+ foreach VT = [ v4i1, v8i1, v16i1 ] in {
+ def : Pat<(VT (predicate_cast (i32 (load_align4 taddrmode_imm7<2>:$addr)))),
+ (VT (VLDR_P0_off taddrmode_imm7<2>:$addr))>;
+ }
+
// Here we match the specific SDNode type 'ARMVectorRegCastImpl'
// rather than the more general 'ARMVectorRegCast' which would also
// match some bitconverts. If we use the latter in cases where the
@@ -4441,8 +4441,8 @@ let Predicates = [HasMVEInt] in {
foreach VT = [ v16i8, v8i16, v8f16, v4i32, v4f32, v2i64, v2f64 ] in
foreach VT2 = [ v16i8, v8i16, v8f16, v4i32, v4f32, v2i64, v2f64 ] in
- def : Pat<(VT (ARMVectorRegCastImpl (VT2 MQPR:$src))),
- (VT MQPR:$src)>;
+ def : Pat<(VT (ARMVectorRegCastImpl (VT2 MQPR:$src))),
+ (VT MQPR:$src)>;
}
// end of MVE compares
@@ -4770,7 +4770,7 @@ class MVE_VxMOVxN<string iname, string suffix, bit bit_28, bit bit_17,
let Inst{16} = 0b1;
let Inst{12} = T;
let Inst{8} = 0b0;
- let Inst{7} = !not(bit_17);
+ let Inst{7} = !not(bit_17);
let Inst{0} = 0b1;
let validForTailPredication = 1;
let retainsPreviousHalfElement = 1;
@@ -4801,7 +4801,7 @@ multiclass MVE_VMOVN_p<Instruction Inst, bit top,
(VTI.Vec MQPR:$Qm), (i32 top))),
(VTI.Vec (Inst (VTI.Vec MQPR:$Qd_src), (VTI.Vec MQPR:$Qm)))>;
- if !not(top) then {
+ if !not(top) then {
// If we see MVEvmovn(a,ARMvrev(b),1), that wants to overwrite the odd
// lanes of a with the odd lanes of b. In other words, the lanes we're
// _keeping_ from a are the even ones. So we can flip it round and say that
@@ -5173,11 +5173,11 @@ class MVE_VADDSUB_qr<string iname, string suffix, bits<2> size,
// Vector-scalar add/sub
multiclass MVE_VADDSUB_qr_m<string iname, MVEVectorVTInfo VTI, bit subtract,
- SDNode Op, Intrinsic PredInt> {
+ SDNode Op, Intrinsic PredInt> {
def "" : MVE_VADDSUB_qr<iname, VTI.Suffix, VTI.Size, 0b0, subtract, 0b1, 0b0>;
- let Predicates = [HasMVEInt] in {
- defm : MVE_TwoOpPatternDup<VTI, Op, PredInt, (? ), !cast<Instruction>(NAME), ARMimmAllZerosV>;
- }
+ let Predicates = [HasMVEInt] in {
+ defm : MVE_TwoOpPatternDup<VTI, Op, PredInt, (? ), !cast<Instruction>(NAME), ARMimmAllZerosV>;
+ }
}
multiclass MVE_VADD_qr_m<MVEVectorVTInfo VTI>
@@ -5196,35 +5196,35 @@ defm MVE_VSUB_qr_i32 : MVE_VSUB_qr_m<MVE_v4i32>;
// Vector-scalar saturating add/sub
multiclass MVE_VQADDSUB_qr_m<string iname, MVEVectorVTInfo VTI, bit subtract,
- SDNode Op, Intrinsic PredInt> {
+ SDNode Op, Intrinsic PredInt> {
def "" : MVE_VADDSUB_qr<iname, VTI.Suffix, VTI.Size, 0b1, subtract,
0b0, VTI.Unsigned>;
-
- let Predicates = [HasMVEInt] in {
- defm : MVE_TwoOpPatternDup<VTI, Op, PredInt, (? (i32 VTI.Unsigned)),
- !cast<Instruction>(NAME)>;
- }
+
+ let Predicates = [HasMVEInt] in {
+ defm : MVE_TwoOpPatternDup<VTI, Op, PredInt, (? (i32 VTI.Unsigned)),
+ !cast<Instruction>(NAME)>;
+ }
}
-multiclass MVE_VQADD_qr_m<MVEVectorVTInfo VTI, SDNode Op>
- : MVE_VQADDSUB_qr_m<"vqadd", VTI, 0b0, Op, int_arm_mve_qadd_predicated>;
+multiclass MVE_VQADD_qr_m<MVEVectorVTInfo VTI, SDNode Op>
+ : MVE_VQADDSUB_qr_m<"vqadd", VTI, 0b0, Op, int_arm_mve_qadd_predicated>;
-multiclass MVE_VQSUB_qr_m<MVEVectorVTInfo VTI, SDNode Op>
- : MVE_VQADDSUB_qr_m<"vqsub", VTI, 0b1, Op, int_arm_mve_qsub_predicated>;
+multiclass MVE_VQSUB_qr_m<MVEVectorVTInfo VTI, SDNode Op>
+ : MVE_VQADDSUB_qr_m<"vqsub", VTI, 0b1, Op, int_arm_mve_qsub_predicated>;
-defm MVE_VQADD_qr_s8 : MVE_VQADD_qr_m<MVE_v16s8, saddsat>;
-defm MVE_VQADD_qr_s16 : MVE_VQADD_qr_m<MVE_v8s16, saddsat>;
-defm MVE_VQADD_qr_s32 : MVE_VQADD_qr_m<MVE_v4s32, saddsat>;
-defm MVE_VQADD_qr_u8 : MVE_VQADD_qr_m<MVE_v16u8, uaddsat>;
-defm MVE_VQADD_qr_u16 : MVE_VQADD_qr_m<MVE_v8u16, uaddsat>;
-defm MVE_VQADD_qr_u32 : MVE_VQADD_qr_m<MVE_v4u32, uaddsat>;
+defm MVE_VQADD_qr_s8 : MVE_VQADD_qr_m<MVE_v16s8, saddsat>;
+defm MVE_VQADD_qr_s16 : MVE_VQADD_qr_m<MVE_v8s16, saddsat>;
+defm MVE_VQADD_qr_s32 : MVE_VQADD_qr_m<MVE_v4s32, saddsat>;
+defm MVE_VQADD_qr_u8 : MVE_VQADD_qr_m<MVE_v16u8, uaddsat>;
+defm MVE_VQADD_qr_u16 : MVE_VQADD_qr_m<MVE_v8u16, uaddsat>;
+defm MVE_VQADD_qr_u32 : MVE_VQADD_qr_m<MVE_v4u32, uaddsat>;
-defm MVE_VQSUB_qr_s8 : MVE_VQSUB_qr_m<MVE_v16s8, ssubsat>;
-defm MVE_VQSUB_qr_s16 : MVE_VQSUB_qr_m<MVE_v8s16, ssubsat>;
-defm MVE_VQSUB_qr_s32 : MVE_VQSUB_qr_m<MVE_v4s32, ssubsat>;
-defm MVE_VQSUB_qr_u8 : MVE_VQSUB_qr_m<MVE_v16u8, usubsat>;
-defm MVE_VQSUB_qr_u16 : MVE_VQSUB_qr_m<MVE_v8u16, usubsat>;
-defm MVE_VQSUB_qr_u32 : MVE_VQSUB_qr_m<MVE_v4u32, usubsat>;
+defm MVE_VQSUB_qr_s8 : MVE_VQSUB_qr_m<MVE_v16s8, ssubsat>;
+defm MVE_VQSUB_qr_s16 : MVE_VQSUB_qr_m<MVE_v8s16, ssubsat>;
+defm MVE_VQSUB_qr_s32 : MVE_VQSUB_qr_m<MVE_v4s32, ssubsat>;
+defm MVE_VQSUB_qr_u8 : MVE_VQSUB_qr_m<MVE_v16u8, usubsat>;
+defm MVE_VQSUB_qr_u16 : MVE_VQSUB_qr_m<MVE_v8u16, usubsat>;
+defm MVE_VQSUB_qr_u32 : MVE_VQSUB_qr_m<MVE_v4u32, usubsat>;
class MVE_VQDMULL_qr<string iname, string suffix, bit size,
bit T, string cstr="", list<dag> pattern=[]>
@@ -5315,23 +5315,23 @@ defm MVE_VHSUB_qr_u8 : MVE_VHSUB_qr_m<MVE_v16u8>;
defm MVE_VHSUB_qr_u16 : MVE_VHSUB_qr_m<MVE_v8u16>;
defm MVE_VHSUB_qr_u32 : MVE_VHSUB_qr_m<MVE_v4u32>;
-multiclass MVE_VADDSUB_qr_f<string iname, MVEVectorVTInfo VTI, bit subtract,
- SDNode Op, Intrinsic PredInt> {
- def "" : MVE_VxADDSUB_qr<iname, VTI.Suffix, VTI.Size{0}, 0b11, subtract>;
- defm : MVE_TwoOpPatternDup<VTI, Op, PredInt, (? ),
- !cast<Instruction>(NAME)>;
-}
-
+multiclass MVE_VADDSUB_qr_f<string iname, MVEVectorVTInfo VTI, bit subtract,
+ SDNode Op, Intrinsic PredInt> {
+ def "" : MVE_VxADDSUB_qr<iname, VTI.Suffix, VTI.Size{0}, 0b11, subtract>;
+ defm : MVE_TwoOpPatternDup<VTI, Op, PredInt, (? ),
+ !cast<Instruction>(NAME)>;
+}
+
let Predicates = [HasMVEFloat] in {
- defm MVE_VADD_qr_f32 : MVE_VADDSUB_qr_f<"vadd", MVE_v4f32, 0b0, fadd,
- int_arm_mve_add_predicated>;
- defm MVE_VADD_qr_f16 : MVE_VADDSUB_qr_f<"vadd", MVE_v8f16, 0b0, fadd,
- int_arm_mve_add_predicated>;
+ defm MVE_VADD_qr_f32 : MVE_VADDSUB_qr_f<"vadd", MVE_v4f32, 0b0, fadd,
+ int_arm_mve_add_predicated>;
+ defm MVE_VADD_qr_f16 : MVE_VADDSUB_qr_f<"vadd", MVE_v8f16, 0b0, fadd,
+ int_arm_mve_add_predicated>;
- defm MVE_VSUB_qr_f32 : MVE_VADDSUB_qr_f<"vsub", MVE_v4f32, 0b1, fsub,
- int_arm_mve_sub_predicated>;
- defm MVE_VSUB_qr_f16 : MVE_VADDSUB_qr_f<"vsub", MVE_v8f16, 0b1, fsub,
- int_arm_mve_sub_predicated>;
+ defm MVE_VSUB_qr_f32 : MVE_VADDSUB_qr_f<"vsub", MVE_v4f32, 0b1, fsub,
+ int_arm_mve_sub_predicated>;
+ defm MVE_VSUB_qr_f16 : MVE_VADDSUB_qr_f<"vsub", MVE_v8f16, 0b1, fsub,
+ int_arm_mve_sub_predicated>;
}
class MVE_VxSHL_qr<string iname, string suffix, bit U, bits<2> size,
@@ -5461,10 +5461,10 @@ class MVE_VMUL_qr_int<string iname, string suffix, bits<2> size>
multiclass MVE_VMUL_qr_int_m<MVEVectorVTInfo VTI> {
def "" : MVE_VMUL_qr_int<"vmul", VTI.Suffix, VTI.Size>;
- let Predicates = [HasMVEInt] in {
- defm : MVE_TwoOpPatternDup<VTI, mul, int_arm_mve_mul_predicated, (? ),
- !cast<Instruction>(NAME), ARMimmOneV>;
- }
+ let Predicates = [HasMVEInt] in {
+ defm : MVE_TwoOpPatternDup<VTI, mul, int_arm_mve_mul_predicated, (? ),
+ !cast<Instruction>(NAME), ARMimmOneV>;
+ }
}
defm MVE_VMUL_qr_i8 : MVE_VMUL_qr_int_m<MVE_v16i8>;
@@ -5481,25 +5481,25 @@ class MVE_VxxMUL_qr<string iname, string suffix,
let Inst{12} = 0b0;
let Inst{8} = 0b0;
let Inst{5} = 0b1;
- let validForTailPredication = 1;
+ let validForTailPredication = 1;
}
multiclass MVE_VxxMUL_qr_m<string iname, MVEVectorVTInfo VTI, bit bit_28,
- PatFrag Op, Intrinsic int_unpred, Intrinsic int_pred> {
+ PatFrag Op, Intrinsic int_unpred, Intrinsic int_pred> {
def "" : MVE_VxxMUL_qr<iname, VTI.Suffix, bit_28, VTI.Size>;
-
- let Predicates = [HasMVEInt] in {
- defm : MVE_TwoOpPatternDup<VTI, Op, int_pred, (? ), !cast<Instruction>(NAME)>;
- }
- defm : MVE_vec_scalar_int_pat_m<!cast<Instruction>(NAME), VTI, int_unpred, int_pred>;
+
+ let Predicates = [HasMVEInt] in {
+ defm : MVE_TwoOpPatternDup<VTI, Op, int_pred, (? ), !cast<Instruction>(NAME)>;
+ }
+ defm : MVE_vec_scalar_int_pat_m<!cast<Instruction>(NAME), VTI, int_unpred, int_pred>;
}
multiclass MVE_VQDMULH_qr_m<MVEVectorVTInfo VTI> :
- MVE_VxxMUL_qr_m<"vqdmulh", VTI, 0b0, MVEvqdmulh,
+ MVE_VxxMUL_qr_m<"vqdmulh", VTI, 0b0, MVEvqdmulh,
int_arm_mve_vqdmulh, int_arm_mve_qdmulh_predicated>;
multiclass MVE_VQRDMULH_qr_m<MVEVectorVTInfo VTI> :
- MVE_VxxMUL_qr_m<"vqrdmulh", VTI, 0b1, null_frag,
+ MVE_VxxMUL_qr_m<"vqrdmulh", VTI, 0b1, null_frag,
int_arm_mve_vqrdmulh, int_arm_mve_qrdmulh_predicated>;
defm MVE_VQDMULH_qr_s8 : MVE_VQDMULH_qr_m<MVE_v16s8>;
@@ -5510,17 +5510,17 @@ defm MVE_VQRDMULH_qr_s8 : MVE_VQRDMULH_qr_m<MVE_v16s8>;
defm MVE_VQRDMULH_qr_s16 : MVE_VQRDMULH_qr_m<MVE_v8s16>;
defm MVE_VQRDMULH_qr_s32 : MVE_VQRDMULH_qr_m<MVE_v4s32>;
-multiclass MVE_VxxMUL_qr_f_m<MVEVectorVTInfo VTI> {
- let validForTailPredication = 1 in
- def "" : MVE_VxxMUL_qr<"vmul", VTI.Suffix, VTI.Size{0}, 0b11>;
- defm : MVE_TwoOpPatternDup<VTI, fmul, int_arm_mve_mul_predicated, (? ),
- !cast<Instruction>(NAME)>;
+multiclass MVE_VxxMUL_qr_f_m<MVEVectorVTInfo VTI> {
+ let validForTailPredication = 1 in
+ def "" : MVE_VxxMUL_qr<"vmul", VTI.Suffix, VTI.Size{0}, 0b11>;
+ defm : MVE_TwoOpPatternDup<VTI, fmul, int_arm_mve_mul_predicated, (? ),
+ !cast<Instruction>(NAME)>;
}
-let Predicates = [HasMVEFloat] in {
- defm MVE_VMUL_qr_f16 : MVE_VxxMUL_qr_f_m<MVE_v8f16>;
- defm MVE_VMUL_qr_f32 : MVE_VxxMUL_qr_f_m<MVE_v4f32>;
-}
+let Predicates = [HasMVEFloat] in {
+ defm MVE_VMUL_qr_f16 : MVE_VxxMUL_qr_f_m<MVE_v8f16>;
+ defm MVE_VMUL_qr_f32 : MVE_VxxMUL_qr_f_m<MVE_v4f32>;
+}
class MVE_VFMAMLA_qr<string iname, string suffix,
bit bit_28, bits<2> bits_21_20, bit S,
@@ -5595,10 +5595,10 @@ multiclass MVE_VFMA_qr_multi<string iname, MVEVectorVTInfo VTI,
if scalar_addend then {
def : Pat<(VTI.Vec (fma v1, v2, vs)),
(VTI.Vec (Inst v1, v2, is))>;
- def : Pat<(VTI.Vec (vselect (VTI.Pred VCCR:$pred),
- (VTI.Vec (fma v1, v2, vs)),
- v1)),
- (VTI.Vec (Inst v1, v2, is, ARMVCCThen, $pred))>;
+ def : Pat<(VTI.Vec (vselect (VTI.Pred VCCR:$pred),
+ (VTI.Vec (fma v1, v2, vs)),
+ v1)),
+ (VTI.Vec (Inst v1, v2, is, ARMVCCThen, $pred))>;
def : Pat<(VTI.Vec (pred_int v1, v2, vs, pred)),
(VTI.Vec (Inst v1, v2, is, ARMVCCThen, pred))>;
} else {
@@ -5606,14 +5606,14 @@ multiclass MVE_VFMA_qr_multi<string iname, MVEVectorVTInfo VTI,
(VTI.Vec (Inst v2, v1, is))>;
def : Pat<(VTI.Vec (fma vs, v1, v2)),
(VTI.Vec (Inst v2, v1, is))>;
- def : Pat<(VTI.Vec (vselect (VTI.Pred VCCR:$pred),
- (VTI.Vec (fma vs, v2, v1)),
- v1)),
- (VTI.Vec (Inst v1, v2, is, ARMVCCThen, $pred))>;
- def : Pat<(VTI.Vec (vselect (VTI.Pred VCCR:$pred),
- (VTI.Vec (fma v2, vs, v1)),
- v1)),
- (VTI.Vec (Inst v1, v2, is, ARMVCCThen, $pred))>;
+ def : Pat<(VTI.Vec (vselect (VTI.Pred VCCR:$pred),
+ (VTI.Vec (fma vs, v2, v1)),
+ v1)),
+ (VTI.Vec (Inst v1, v2, is, ARMVCCThen, $pred))>;
+ def : Pat<(VTI.Vec (vselect (VTI.Pred VCCR:$pred),
+ (VTI.Vec (fma v2, vs, v1)),
+ v1)),
+ (VTI.Vec (Inst v1, v2, is, ARMVCCThen, $pred))>;
def : Pat<(VTI.Vec (pred_int v1, vs, v2, pred)),
(VTI.Vec (Inst v2, v1, is, ARMVCCThen, pred))>;
def : Pat<(VTI.Vec (pred_int vs, v1, v2, pred)),
@@ -5742,7 +5742,7 @@ def MVE_VDWDUPu8 : MVE_VxWDUP<"vdwdup", "u8", 0b00, 0b1>;
def MVE_VDWDUPu16 : MVE_VxWDUP<"vdwdup", "u16", 0b01, 0b1>;
def MVE_VDWDUPu32 : MVE_VxWDUP<"vdwdup", "u32", 0b10, 0b1>;
-let isReMaterializable = 1 in
+let isReMaterializable = 1 in
class MVE_VCTPInst<string suffix, bits<2> size, list<dag> pattern=[]>
: MVE_p<(outs VCCR:$P0), (ins rGPR:$Rn), NoItinerary, "vctp", suffix,
"$Rn", vpred_n, "", pattern> {
@@ -5766,8 +5766,8 @@ multiclass MVE_VCTP<MVEVectorVTInfo VTI, Intrinsic intr> {
defvar Inst = !cast<Instruction>(NAME);
let Predicates = [HasMVEInt] in {
- def : Pat<(intr rGPR:$Rn),
- (VTI.Pred (Inst rGPR:$Rn))>;
+ def : Pat<(intr rGPR:$Rn),
+ (VTI.Pred (Inst rGPR:$Rn))>;
def : Pat<(and (intr rGPR:$Rn), (VTI.Pred VCCR:$mask)),
(VTI.Pred (Inst rGPR:$Rn, ARMVCCThen, VCCR:$mask))>;
}
@@ -5845,41 +5845,41 @@ def MVE_VMOV_rr_q : MVE_VMOV_64bit<(outs rGPR:$Rt, rGPR:$Rt2), (ins MQPR:$Qd),
let AsmMatchConverter = "cvtMVEVMOVQtoDReg";
}
-let Predicates = [HasMVEInt] in {
- // Double lane moves. There are a number of patterns here. We know that the
- // insertelt's will be in descending order by index, and need to match the 5
- // patterns that might contain 2-0 or 3-1 pairs. These are:
- // 3 2 1 0 -> vmovqrr 31; vmovqrr 20
- // 3 2 1 -> vmovqrr 31; vmov 2
- // 3 1 -> vmovqrr 31
- // 2 1 0 -> vmovqrr 20; vmov 1
- // 2 0 -> vmovqrr 20
- // The other potential patterns will be handled by single lane inserts.
- def : Pat<(insertelt (insertelt (insertelt (insertelt (v4i32 MQPR:$src1),
- rGPR:$srcA, (i32 0)),
- rGPR:$srcB, (i32 1)),
- rGPR:$srcC, (i32 2)),
- rGPR:$srcD, (i32 3)),
- (MVE_VMOV_q_rr (MVE_VMOV_q_rr MQPR:$src1, rGPR:$srcA, rGPR:$srcC, (i32 2), (i32 0)),
- rGPR:$srcB, rGPR:$srcD, (i32 3), (i32 1))>;
- def : Pat<(insertelt (insertelt (insertelt (v4i32 MQPR:$src1),
- rGPR:$srcB, (i32 1)),
- rGPR:$srcC, (i32 2)),
- rGPR:$srcD, (i32 3)),
- (MVE_VMOV_q_rr (MVE_VMOV_to_lane_32 MQPR:$src1, rGPR:$srcC, (i32 2)),
- rGPR:$srcB, rGPR:$srcD, (i32 3), (i32 1))>;
- def : Pat<(insertelt (insertelt (v4i32 MQPR:$src1), rGPR:$srcA, (i32 1)), rGPR:$srcB, (i32 3)),
- (MVE_VMOV_q_rr MQPR:$src1, rGPR:$srcA, rGPR:$srcB, (i32 3), (i32 1))>;
- def : Pat<(insertelt (insertelt (insertelt (v4i32 MQPR:$src1),
- rGPR:$srcB, (i32 0)),
- rGPR:$srcC, (i32 1)),
- rGPR:$srcD, (i32 2)),
- (MVE_VMOV_q_rr (MVE_VMOV_to_lane_32 MQPR:$src1, rGPR:$srcC, (i32 1)),
- rGPR:$srcB, rGPR:$srcD, (i32 2), (i32 0))>;
- def : Pat<(insertelt (insertelt (v4i32 MQPR:$src1), rGPR:$srcA, (i32 0)), rGPR:$srcB, (i32 2)),
- (MVE_VMOV_q_rr MQPR:$src1, rGPR:$srcA, rGPR:$srcB, (i32 2), (i32 0))>;
-}
-
+let Predicates = [HasMVEInt] in {
+ // Double lane moves. There are a number of patterns here. We know that the
+ // insertelt's will be in descending order by index, and need to match the 5
+ // patterns that might contain 2-0 or 3-1 pairs. These are:
+ // 3 2 1 0 -> vmovqrr 31; vmovqrr 20
+ // 3 2 1 -> vmovqrr 31; vmov 2
+ // 3 1 -> vmovqrr 31
+ // 2 1 0 -> vmovqrr 20; vmov 1
+ // 2 0 -> vmovqrr 20
+ // The other potential patterns will be handled by single lane inserts.
+ def : Pat<(insertelt (insertelt (insertelt (insertelt (v4i32 MQPR:$src1),
+ rGPR:$srcA, (i32 0)),
+ rGPR:$srcB, (i32 1)),
+ rGPR:$srcC, (i32 2)),
+ rGPR:$srcD, (i32 3)),
+ (MVE_VMOV_q_rr (MVE_VMOV_q_rr MQPR:$src1, rGPR:$srcA, rGPR:$srcC, (i32 2), (i32 0)),
+ rGPR:$srcB, rGPR:$srcD, (i32 3), (i32 1))>;
+ def : Pat<(insertelt (insertelt (insertelt (v4i32 MQPR:$src1),
+ rGPR:$srcB, (i32 1)),
+ rGPR:$srcC, (i32 2)),
+ rGPR:$srcD, (i32 3)),
+ (MVE_VMOV_q_rr (MVE_VMOV_to_lane_32 MQPR:$src1, rGPR:$srcC, (i32 2)),
+ rGPR:$srcB, rGPR:$srcD, (i32 3), (i32 1))>;
+ def : Pat<(insertelt (insertelt (v4i32 MQPR:$src1), rGPR:$srcA, (i32 1)), rGPR:$srcB, (i32 3)),
+ (MVE_VMOV_q_rr MQPR:$src1, rGPR:$srcA, rGPR:$srcB, (i32 3), (i32 1))>;
+ def : Pat<(insertelt (insertelt (insertelt (v4i32 MQPR:$src1),
+ rGPR:$srcB, (i32 0)),
+ rGPR:$srcC, (i32 1)),
+ rGPR:$srcD, (i32 2)),
+ (MVE_VMOV_q_rr (MVE_VMOV_to_lane_32 MQPR:$src1, rGPR:$srcC, (i32 1)),
+ rGPR:$srcB, rGPR:$srcD, (i32 2), (i32 0))>;
+ def : Pat<(insertelt (insertelt (v4i32 MQPR:$src1), rGPR:$srcA, (i32 0)), rGPR:$srcB, (i32 2)),
+ (MVE_VMOV_q_rr MQPR:$src1, rGPR:$srcA, rGPR:$srcB, (i32 2), (i32 0))>;
+}
+
// end of coproc mov
// start of MVE interleaving load/store
@@ -5908,7 +5908,7 @@ class MVE_vldst24_base<bit writeback, bit fourregs, bits<2> stage, bits<2> size,
let mayLoad = load;
let mayStore = !eq(load,0);
let hasSideEffects = 0;
- let validForTailPredication = load;
+ let validForTailPredication = load;
}
// A parameter class used to encapsulate all the ways the writeback
@@ -6518,7 +6518,7 @@ class MVE_VPT<string suffix, bits<2> size, dag iops, string asm, list<dag> patte
let Inst{4} = 0b0;
let Defs = [VPR];
- let validForTailPredication=1;
+ let validForTailPredication=1;
}
class MVE_VPTt1<string suffix, bits<2> size, dag iops>
@@ -6631,7 +6631,7 @@ class MVE_VPTf<string suffix, bit size, dag iops, string asm, list<dag> pattern=
let Defs = [VPR];
let Predicates = [HasMVEFloat];
- let validForTailPredication=1;
+ let validForTailPredication=1;
}
class MVE_VPTft1<string suffix, bit size>
@@ -7107,7 +7107,7 @@ class MVE_vector_load_typed<ValueType Ty, Instruction RegImmInst,
class MVE_vector_maskedload_typed<ValueType Ty, Instruction RegImmInst,
PatFrag LoadKind, int shift>
- : Pat<(Ty (LoadKind t2addrmode_imm7<shift>:$addr, VCCR:$pred, (Ty (ARMvmovImm (i32 0))))),
+ : Pat<(Ty (LoadKind t2addrmode_imm7<shift>:$addr, VCCR:$pred, (Ty (ARMvmovImm (i32 0))))),
(Ty (RegImmInst t2addrmode_imm7<shift>:$addr, ARMVCCThen, VCCR:$pred))>;
multiclass MVE_vector_load<Instruction RegImmInst, PatFrag LoadKind,
@@ -7274,11 +7274,11 @@ multiclass MVEExtLoadStore<Instruction LoadSInst, Instruction LoadUInst, string
(VT (LoadUInst taddrmode_imm7<Shift>:$addr))>;
// Masked ext loads
- def : Pat<(VT (!cast<PatFrag>("aligned_extmaskedload"#Amble) taddrmode_imm7<Shift>:$addr, VCCR:$pred, (VT (ARMvmovImm (i32 0))))),
+ def : Pat<(VT (!cast<PatFrag>("aligned_extmaskedload"#Amble) taddrmode_imm7<Shift>:$addr, VCCR:$pred, (VT (ARMvmovImm (i32 0))))),
(VT (LoadUInst taddrmode_imm7<Shift>:$addr, ARMVCCThen, VCCR:$pred))>;
- def : Pat<(VT (!cast<PatFrag>("aligned_sextmaskedload"#Amble) taddrmode_imm7<Shift>:$addr, VCCR:$pred, (VT (ARMvmovImm (i32 0))))),
+ def : Pat<(VT (!cast<PatFrag>("aligned_sextmaskedload"#Amble) taddrmode_imm7<Shift>:$addr, VCCR:$pred, (VT (ARMvmovImm (i32 0))))),
(VT (LoadSInst taddrmode_imm7<Shift>:$addr, ARMVCCThen, VCCR:$pred))>;
- def : Pat<(VT (!cast<PatFrag>("aligned_zextmaskedload"#Amble) taddrmode_imm7<Shift>:$addr, VCCR:$pred, (VT (ARMvmovImm (i32 0))))),
+ def : Pat<(VT (!cast<PatFrag>("aligned_zextmaskedload"#Amble) taddrmode_imm7<Shift>:$addr, VCCR:$pred, (VT (ARMvmovImm (i32 0))))),
(VT (LoadUInst taddrmode_imm7<Shift>:$addr, ARMVCCThen, VCCR:$pred))>;
}
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMInstrNEON.td b/contrib/libs/llvm12/lib/Target/ARM/ARMInstrNEON.td
index 0f5d53b57d..a8c0d05d91 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMInstrNEON.td
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMInstrNEON.td
@@ -509,7 +509,7 @@ def NEONvqrshrnsuImm : SDNode<"ARMISD::VQRSHRNsuIMM", SDTARMVSHXIMM>;
def NEONvsliImm : SDNode<"ARMISD::VSLIIMM", SDTARMVSHINSIMM>;
def NEONvsriImm : SDNode<"ARMISD::VSRIIMM", SDTARMVSHINSIMM>;
-def NEONvbsp : SDNode<"ARMISD::VBSP",
+def NEONvbsp : SDNode<"ARMISD::VBSP",
SDTypeProfile<1, 3, [SDTCisVec<0>,
SDTCisSameAs<0, 1>,
SDTCisSameAs<0, 2>,
@@ -4197,10 +4197,10 @@ def VADDhq : N3VQ<0, 0, 0b01, 0b1101, 0, IIC_VBINQ, "vadd", "f16",
defm VADDLs : N3VLExt_QHS<0,1,0b0000,0, IIC_VSHLiD, IIC_VSHLiD,
"vaddl", "s", add, sext, 1>;
defm VADDLu : N3VLExt_QHS<1,1,0b0000,0, IIC_VSHLiD, IIC_VSHLiD,
- "vaddl", "u", add, zanyext, 1>;
+ "vaddl", "u", add, zanyext, 1>;
// VADDW : Vector Add Wide (Q = Q + D)
defm VADDWs : N3VW_QHS<0,1,0b0001,0, "vaddw", "s", add, sext, 0>;
-defm VADDWu : N3VW_QHS<1,1,0b0001,0, "vaddw", "u", add, zanyext, 0>;
+defm VADDWu : N3VW_QHS<1,1,0b0001,0, "vaddw", "u", add, zanyext, 0>;
// VHADD : Vector Halving Add
defm VHADDs : N3VInt_QHS<0, 0, 0b0000, 0, N3RegFrm,
IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q,
@@ -4512,9 +4512,9 @@ let Predicates = [HasNEON, HasV8_1a] in {
(SubReg_i16_lane imm:$lane)))>;
def : Pat<(v4i32 (saddsat
(v4i32 QPR:$src1),
- (v4i32 (int_arm_neon_vqrdmulh
+ (v4i32 (int_arm_neon_vqrdmulh
(v4i32 QPR:$src2),
- (v4i32 (ARMvduplane (v4i32 QPR:$src3),
+ (v4i32 (ARMvduplane (v4i32 QPR:$src3),
imm:$lane)))))),
(v4i32 (VQRDMLAHslv4i32 (v4i32 QPR:$src1),
(v4i32 QPR:$src2),
@@ -4565,17 +4565,17 @@ let Predicates = [HasNEON, HasV8_1a] in {
(v2i32 DPR:$Vn),
(v2i32 (ARMvduplane (v2i32 DPR_VFP2:$Vm),
imm:$lane)))))),
- (v2i32 (VQRDMLSHslv2i32 DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm,
+ (v2i32 (VQRDMLSHslv2i32 DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm,
imm:$lane))>;
def : Pat<(v8i16 (ssubsat
(v8i16 QPR:$src1),
(v8i16 (int_arm_neon_vqrdmulh
(v8i16 QPR:$src2),
- (v8i16 (ARMvduplane (v8i16 QPR:$src3),
+ (v8i16 (ARMvduplane (v8i16 QPR:$src3),
imm:$lane)))))),
(v8i16 (VQRDMLSHslv8i16 (v8i16 QPR:$src1),
(v8i16 QPR:$src2),
- (v4i16 (EXTRACT_SUBREG
+ (v4i16 (EXTRACT_SUBREG
QPR:$src3,
(DSubReg_i16_reg imm:$lane))),
(SubReg_i16_lane imm:$lane)))>;
@@ -4587,7 +4587,7 @@ let Predicates = [HasNEON, HasV8_1a] in {
imm:$lane)))))),
(v4i32 (VQRDMLSHslv4i32 (v4i32 QPR:$src1),
(v4i32 QPR:$src2),
- (v2i32 (EXTRACT_SUBREG
+ (v2i32 (EXTRACT_SUBREG
QPR:$src3,
(DSubReg_i32_reg imm:$lane))),
(SubReg_i32_lane imm:$lane)))>;
@@ -5045,10 +5045,10 @@ def VSUBhq : N3VQ<0, 0, 0b11, 0b1101, 0, IIC_VBINQ, "vsub", "f16",
defm VSUBLs : N3VLExt_QHS<0,1,0b0010,0, IIC_VSHLiD, IIC_VSHLiD,
"vsubl", "s", sub, sext, 0>;
defm VSUBLu : N3VLExt_QHS<1,1,0b0010,0, IIC_VSHLiD, IIC_VSHLiD,
- "vsubl", "u", sub, zanyext, 0>;
+ "vsubl", "u", sub, zanyext, 0>;
// VSUBW : Vector Subtract Wide (Q = Q - D)
defm VSUBWs : N3VW_QHS<0,1,0b0011,0, "vsubw", "s", sub, sext, 0>;
-defm VSUBWu : N3VW_QHS<1,1,0b0011,0, "vsubw", "u", sub, zanyext, 0>;
+defm VSUBWu : N3VW_QHS<1,1,0b0011,0, "vsubw", "u", sub, zanyext, 0>;
// VHSUB : Vector Halving Subtract
defm VHSUBs : N3VInt_QHS<0, 0, 0b0010, 0, N3RegFrm,
IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
@@ -5259,9 +5259,9 @@ def: NEONInstAlias<"vacle${p}.f16 $Vd, $Vm",
// Vector Bitwise Operations.
def vnotd : PatFrag<(ops node:$in),
- (xor node:$in, ARMimmAllOnesD)>;
+ (xor node:$in, ARMimmAllOnesD)>;
def vnotq : PatFrag<(ops node:$in),
- (xor node:$in, ARMimmAllOnesV)>;
+ (xor node:$in, ARMimmAllOnesV)>;
// VAND : Vector Bitwise AND
@@ -5428,84 +5428,84 @@ def : Pat<(v2i32 (vnotd DPR:$src)), (VMVNd DPR:$src)>;
def : Pat<(v4i32 (vnotq QPR:$src)), (VMVNq QPR:$src)>;
}
-// The TwoAddress pass will not go looking for equivalent operations
-// with different register constraints; it just inserts copies.
-// That is why pseudo VBSP implemented. Is is expanded later into
-// VBIT/VBIF/VBSL taking into account register constraints to avoid copies.
-def VBSPd
- : PseudoNeonI<(outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm),
- IIC_VBINiD, "",
- [(set DPR:$Vd,
- (v2i32 (NEONvbsp DPR:$src1, DPR:$Vn, DPR:$Vm)))]>;
+// The TwoAddress pass will not go looking for equivalent operations
+// with different register constraints; it just inserts copies.
+// That is why pseudo VBSP implemented. Is is expanded later into
+// VBIT/VBIF/VBSL taking into account register constraints to avoid copies.
+def VBSPd
+ : PseudoNeonI<(outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm),
+ IIC_VBINiD, "",
+ [(set DPR:$Vd,
+ (v2i32 (NEONvbsp DPR:$src1, DPR:$Vn, DPR:$Vm)))]>;
let Predicates = [HasNEON] in {
def : Pat<(v8i8 (int_arm_neon_vbsl (v8i8 DPR:$src1),
(v8i8 DPR:$Vn), (v8i8 DPR:$Vm))),
- (VBSPd DPR:$src1, DPR:$Vn, DPR:$Vm)>;
+ (VBSPd DPR:$src1, DPR:$Vn, DPR:$Vm)>;
def : Pat<(v4i16 (int_arm_neon_vbsl (v4i16 DPR:$src1),
(v4i16 DPR:$Vn), (v4i16 DPR:$Vm))),
- (VBSPd DPR:$src1, DPR:$Vn, DPR:$Vm)>;
+ (VBSPd DPR:$src1, DPR:$Vn, DPR:$Vm)>;
def : Pat<(v2i32 (int_arm_neon_vbsl (v2i32 DPR:$src1),
(v2i32 DPR:$Vn), (v2i32 DPR:$Vm))),
- (VBSPd DPR:$src1, DPR:$Vn, DPR:$Vm)>;
+ (VBSPd DPR:$src1, DPR:$Vn, DPR:$Vm)>;
def : Pat<(v2f32 (int_arm_neon_vbsl (v2f32 DPR:$src1),
(v2f32 DPR:$Vn), (v2f32 DPR:$Vm))),
- (VBSPd DPR:$src1, DPR:$Vn, DPR:$Vm)>;
+ (VBSPd DPR:$src1, DPR:$Vn, DPR:$Vm)>;
def : Pat<(v1i64 (int_arm_neon_vbsl (v1i64 DPR:$src1),
(v1i64 DPR:$Vn), (v1i64 DPR:$Vm))),
- (VBSPd DPR:$src1, DPR:$Vn, DPR:$Vm)>;
+ (VBSPd DPR:$src1, DPR:$Vn, DPR:$Vm)>;
def : Pat<(v2i32 (or (and DPR:$Vn, DPR:$Vd),
(and DPR:$Vm, (vnotd DPR:$Vd)))),
- (VBSPd DPR:$Vd, DPR:$Vn, DPR:$Vm)>;
+ (VBSPd DPR:$Vd, DPR:$Vn, DPR:$Vm)>;
def : Pat<(v1i64 (or (and DPR:$Vn, DPR:$Vd),
(and DPR:$Vm, (vnotd DPR:$Vd)))),
- (VBSPd DPR:$Vd, DPR:$Vn, DPR:$Vm)>;
+ (VBSPd DPR:$Vd, DPR:$Vn, DPR:$Vm)>;
}
-def VBSPq
- : PseudoNeonI<(outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm),
- IIC_VBINiQ, "",
- [(set QPR:$Vd,
- (v4i32 (NEONvbsp QPR:$src1, QPR:$Vn, QPR:$Vm)))]>;
+def VBSPq
+ : PseudoNeonI<(outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm),
+ IIC_VBINiQ, "",
+ [(set QPR:$Vd,
+ (v4i32 (NEONvbsp QPR:$src1, QPR:$Vn, QPR:$Vm)))]>;
let Predicates = [HasNEON] in {
def : Pat<(v16i8 (int_arm_neon_vbsl (v16i8 QPR:$src1),
(v16i8 QPR:$Vn), (v16i8 QPR:$Vm))),
- (VBSPq QPR:$src1, QPR:$Vn, QPR:$Vm)>;
+ (VBSPq QPR:$src1, QPR:$Vn, QPR:$Vm)>;
def : Pat<(v8i16 (int_arm_neon_vbsl (v8i16 QPR:$src1),
(v8i16 QPR:$Vn), (v8i16 QPR:$Vm))),
- (VBSPq QPR:$src1, QPR:$Vn, QPR:$Vm)>;
+ (VBSPq QPR:$src1, QPR:$Vn, QPR:$Vm)>;
def : Pat<(v4i32 (int_arm_neon_vbsl (v4i32 QPR:$src1),
(v4i32 QPR:$Vn), (v4i32 QPR:$Vm))),
- (VBSPq QPR:$src1, QPR:$Vn, QPR:$Vm)>;
+ (VBSPq QPR:$src1, QPR:$Vn, QPR:$Vm)>;
def : Pat<(v4f32 (int_arm_neon_vbsl (v4f32 QPR:$src1),
(v4f32 QPR:$Vn), (v4f32 QPR:$Vm))),
- (VBSPq QPR:$src1, QPR:$Vn, QPR:$Vm)>;
+ (VBSPq QPR:$src1, QPR:$Vn, QPR:$Vm)>;
def : Pat<(v2i64 (int_arm_neon_vbsl (v2i64 QPR:$src1),
(v2i64 QPR:$Vn), (v2i64 QPR:$Vm))),
- (VBSPq QPR:$src1, QPR:$Vn, QPR:$Vm)>;
+ (VBSPq QPR:$src1, QPR:$Vn, QPR:$Vm)>;
def : Pat<(v4i32 (or (and QPR:$Vn, QPR:$Vd),
(and QPR:$Vm, (vnotq QPR:$Vd)))),
- (VBSPq QPR:$Vd, QPR:$Vn, QPR:$Vm)>;
+ (VBSPq QPR:$Vd, QPR:$Vn, QPR:$Vm)>;
def : Pat<(v2i64 (or (and QPR:$Vn, QPR:$Vd),
(and QPR:$Vm, (vnotq QPR:$Vd)))),
- (VBSPq QPR:$Vd, QPR:$Vn, QPR:$Vm)>;
-}
-
-// VBSL : Vector Bitwise Select
-def VBSLd : N3VX<1, 0, 0b01, 0b0001, 0, 1, (outs DPR:$Vd),
- (ins DPR:$src1, DPR:$Vn, DPR:$Vm),
- N3RegFrm, IIC_VBINiD,
- "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd",
- []>;
-
-def VBSLq : N3VX<1, 0, 0b01, 0b0001, 1, 1, (outs QPR:$Vd),
- (ins QPR:$src1, QPR:$Vn, QPR:$Vm),
- N3RegFrm, IIC_VBINiQ,
- "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd",
- []>;
-
+ (VBSPq QPR:$Vd, QPR:$Vn, QPR:$Vm)>;
+}
+
+// VBSL : Vector Bitwise Select
+def VBSLd : N3VX<1, 0, 0b01, 0b0001, 0, 1, (outs DPR:$Vd),
+ (ins DPR:$src1, DPR:$Vn, DPR:$Vm),
+ N3RegFrm, IIC_VBINiD,
+ "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd",
+ []>;
+
+def VBSLq : N3VX<1, 0, 0b01, 0b0001, 1, 1, (outs QPR:$Vd),
+ (ins QPR:$src1, QPR:$Vn, QPR:$Vm),
+ N3RegFrm, IIC_VBINiQ,
+ "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd",
+ []>;
+
// VBIF : Vector Bitwise Insert if False
// like VBSL but with: "vbif $dst, $src3, $src1", "$src2 = $dst",
def VBIFd : N3VX<1, 0, 0b11, 0b0001, 0, 1,
@@ -6040,9 +6040,9 @@ defm VQABS : N2VInt_QHS<0b11, 0b11, 0b00, 0b01110, 0,
// Vector Negate.
def vnegd : PatFrag<(ops node:$in),
- (sub ARMimmAllZerosD, node:$in)>;
+ (sub ARMimmAllZerosD, node:$in)>;
def vnegq : PatFrag<(ops node:$in),
- (sub ARMimmAllZerosV, node:$in)>;
+ (sub ARMimmAllZerosV, node:$in)>;
class VNEGD<bits<2> size, string OpcodeStr, string Dt, ValueType Ty>
: N2V<0b11, 0b11, size, 0b01, 0b00111, 0, 0, (outs DPR:$Vd), (ins DPR:$Vm),
@@ -6256,11 +6256,11 @@ defm : NEONImmReplicateInstAlias<i32, VMOVv2i32, VMOVv4i32,
let AddedComplexity = 50, isAsCheapAsAMove = 1, isReMaterializable = 1 in {
def VMOVD0 : ARMPseudoExpand<(outs DPR:$Vd), (ins), 4, IIC_VMOVImm,
- [(set DPR:$Vd, (v2i32 ARMimmAllZerosD))],
+ [(set DPR:$Vd, (v2i32 ARMimmAllZerosD))],
(VMOVv2i32 DPR:$Vd, 0, (ops 14, zero_reg))>,
Requires<[HasZCZ]>;
def VMOVQ0 : ARMPseudoExpand<(outs QPR:$Vd), (ins), 4, IIC_VMOVImm,
- [(set QPR:$Vd, (v4i32 ARMimmAllZerosV))],
+ [(set QPR:$Vd, (v4i32 ARMimmAllZerosV))],
(VMOVv4i32 QPR:$Vd, 0, (ops 14, zero_reg))>,
Requires<[HasZCZ]>;
}
@@ -7946,7 +7946,7 @@ let Predicates = [HasNEON,IsLE] in {
(VLD1LNd16 addrmode6:$addr,
(f64 (IMPLICIT_DEF)), (i32 0))), dsub_0)), dsub_0))>;
}
-// The following patterns are basically a copy of the patterns above,
+// The following patterns are basically a copy of the patterns above,
// however with an additional VREV16d instruction to convert data
// loaded by VLD1LN into proper vector format in big endian mode.
let Predicates = [HasNEON,IsBE] in {
@@ -9079,11 +9079,11 @@ multiclass BF16VDOTI<bit Q, RegisterClass RegTy, string opc, ValueType AccumTy,
(!cast<Instruction>(NAME) RegTy:$Vd, RegTy:$Vn, RHS, VectorIndex32:$lane)>;
}
-def BF16VDOTS_VDOTD : BF16VDOTS<0, DPR, "vdot", v2f32, v4bf16>;
-def BF16VDOTS_VDOTQ : BF16VDOTS<1, QPR, "vdot", v4f32, v8bf16>;
+def BF16VDOTS_VDOTD : BF16VDOTS<0, DPR, "vdot", v2f32, v4bf16>;
+def BF16VDOTS_VDOTQ : BF16VDOTS<1, QPR, "vdot", v4f32, v8bf16>;
-defm BF16VDOTI_VDOTD : BF16VDOTI<0, DPR, "vdot", v2f32, v4bf16, (v2f32 DPR_VFP2:$Vm)>;
-defm BF16VDOTI_VDOTQ : BF16VDOTI<1, QPR, "vdot", v4f32, v8bf16, (EXTRACT_SUBREG QPR:$Vm, dsub_0)>;
+defm BF16VDOTI_VDOTD : BF16VDOTI<0, DPR, "vdot", v2f32, v4bf16, (v2f32 DPR_VFP2:$Vm)>;
+defm BF16VDOTI_VDOTQ : BF16VDOTI<1, QPR, "vdot", v4f32, v8bf16, (EXTRACT_SUBREG QPR:$Vm, dsub_0)>;
class BF16MM<bit Q, RegisterClass RegTy,
string opc>
@@ -9091,8 +9091,8 @@ class BF16MM<bit Q, RegisterClass RegTy,
(outs RegTy:$dst), (ins RegTy:$Vd, RegTy:$Vn, RegTy:$Vm),
N3RegFrm, IIC_VDOTPROD, "", "",
[(set (v4f32 QPR:$dst), (int_arm_neon_bfmmla (v4f32 QPR:$Vd),
- (v8bf16 QPR:$Vn),
- (v8bf16 QPR:$Vm)))]> {
+ (v8bf16 QPR:$Vn),
+ (v8bf16 QPR:$Vm)))]> {
let Constraints = "$dst = $Vd";
let AsmString = !strconcat(opc, ".bf16", "\t$Vd, $Vn, $Vm");
let DecoderNamespace = "VFPV8";
@@ -9106,8 +9106,8 @@ class VBF16MALQ<bit T, string suffix, SDPatternOperator OpNode>
NoItinerary, "vfma" # suffix, "bf16", "$Vd, $Vn, $Vm", "",
[(set (v4f32 QPR:$dst),
(OpNode (v4f32 QPR:$Vd),
- (v8bf16 QPR:$Vn),
- (v8bf16 QPR:$Vm)))]> {
+ (v8bf16 QPR:$Vn),
+ (v8bf16 QPR:$Vm)))]> {
let Constraints = "$dst = $Vd";
let DecoderNamespace = "VFPV8";
}
@@ -9128,9 +9128,9 @@ multiclass VBF16MALQI<bit T, string suffix, SDPatternOperator OpNode> {
def : Pat<
(v4f32 (OpNode (v4f32 QPR:$Vd),
- (v8bf16 QPR:$Vn),
- (v8bf16 (ARMvduplane (v8bf16 QPR:$Vm),
- VectorIndex16:$lane)))),
+ (v8bf16 QPR:$Vn),
+ (v8bf16 (ARMvduplane (v8bf16 QPR:$Vm),
+ VectorIndex16:$lane)))),
(!cast<Instruction>(NAME) QPR:$Vd,
QPR:$Vn,
(EXTRACT_SUBREG QPR:$Vm,
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMInstrThumb.td b/contrib/libs/llvm12/lib/Target/ARM/ARMInstrThumb.td
index 0b0c510102..3a33dfeecd 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMInstrThumb.td
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMInstrThumb.td
@@ -548,19 +548,19 @@ let isCall = 1,
// Also used for Thumb2
def tBLXr : TI<(outs), (ins pred:$p, GPR:$func), IIC_Br,
- "blx${p}\t$func", []>,
+ "blx${p}\t$func", []>,
Requires<[IsThumb, HasV5T]>,
T1Special<{1,1,1,?}>, Sched<[WriteBrL]> { // A6.2.3 & A8.6.24;
bits<4> func;
let Inst{6-3} = func;
let Inst{2-0} = 0b000;
}
- def tBLXr_noip : ARMPseudoExpand<(outs), (ins pred:$p, GPRnoip:$func),
- 2, IIC_Br, [], (tBLXr pred:$p, GPR:$func)>,
- Requires<[IsThumb, HasV5T]>,
- Sched<[WriteBrL]>;
+ def tBLXr_noip : ARMPseudoExpand<(outs), (ins pred:$p, GPRnoip:$func),
+ 2, IIC_Br, [], (tBLXr pred:$p, GPR:$func)>,
+ Requires<[IsThumb, HasV5T]>,
+ Sched<[WriteBrL]>;
+
-
// ARMv8-M Security Extensions
def tBLXNSr : TI<(outs), (ins pred:$p, GPRnopc:$func), IIC_Br,
"blxns${p}\t$func", []>,
@@ -590,11 +590,11 @@ let isCall = 1,
Requires<[IsThumb]>, Sched<[WriteBr]>;
}
-def : ARMPat<(ARMcall GPR:$func), (tBLXr $func)>,
- Requires<[IsThumb, HasV5T, NoSLSBLRMitigation]>;
-def : ARMPat<(ARMcall GPRnoip:$func), (tBLXr_noip $func)>,
- Requires<[IsThumb, HasV5T, SLSBLRMitigation]>;
-
+def : ARMPat<(ARMcall GPR:$func), (tBLXr $func)>,
+ Requires<[IsThumb, HasV5T, NoSLSBLRMitigation]>;
+def : ARMPat<(ARMcall GPRnoip:$func), (tBLXr_noip $func)>,
+ Requires<[IsThumb, HasV5T, SLSBLRMitigation]>;
+
let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
let isPredicable = 1 in
def tB : T1pI<(outs), (ins t_brtarget:$target), IIC_Br,
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMInstrThumb2.td b/contrib/libs/llvm12/lib/Target/ARM/ARMInstrThumb2.td
index b79212a48b..5642cab32e 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMInstrThumb2.td
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMInstrThumb2.td
@@ -1724,7 +1724,7 @@ def t2STRH_preidx: t2PseudoInst<(outs GPRnopc:$Rn_wb),
// only.
// Ref: A8.6.193 STR (immediate, Thumb) Encoding T4
class T2IstT<bits<2> type, string opc, InstrItinClass ii>
- : T2Ii8<(outs), (ins rGPR:$Rt, t2addrmode_imm8:$addr), ii, opc,
+ : T2Ii8<(outs), (ins rGPR:$Rt, t2addrmode_imm8:$addr), ii, opc,
"\t$Rt, $addr", []>, Sched<[WriteST]> {
let Inst{31-27} = 0b11111;
let Inst{26-25} = 0b00;
@@ -2623,9 +2623,9 @@ def t2USAT16: T2SatI<(ins imm0_15:$sat_imm, rGPR:$Rn),
let Inst{4} = 0;
}
-def : T2Pat<(ARMssat GPRnopc:$Rn, imm0_31:$imm),
+def : T2Pat<(ARMssat GPRnopc:$Rn, imm0_31:$imm),
(t2SSAT imm0_31:$imm, GPRnopc:$Rn, 0)>;
-def : T2Pat<(ARMusat GPRnopc:$Rn, imm0_31:$imm),
+def : T2Pat<(ARMusat GPRnopc:$Rn, imm0_31:$imm),
(t2USAT imm0_31:$imm, GPRnopc:$Rn, 0)>;
def : T2Pat<(int_arm_ssat GPR:$a, imm1_32:$pos),
(t2SSAT imm1_32:$pos, GPR:$a, 0)>;
@@ -2635,24 +2635,24 @@ def : T2Pat<(int_arm_ssat16 GPR:$a, imm1_16:$pos),
(t2SSAT16 imm1_16:$pos, GPR:$a)>;
def : T2Pat<(int_arm_usat16 GPR:$a, imm0_15:$pos),
(t2USAT16 imm0_15:$pos, GPR:$a)>;
-def : T2Pat<(int_arm_ssat (shl GPRnopc:$a, imm0_31:$shft), imm1_32:$pos),
- (t2SSAT imm1_32:$pos, GPRnopc:$a, imm0_31:$shft)>;
-def : T2Pat<(int_arm_ssat (sra GPRnopc:$a, asr_imm:$shft), imm1_32:$pos),
- (t2SSAT imm1_32:$pos, GPRnopc:$a, asr_imm:$shft)>;
-def : T2Pat<(int_arm_usat (shl GPRnopc:$a, imm0_31:$shft), imm0_31:$pos),
- (t2USAT imm0_31:$pos, GPRnopc:$a, imm0_31:$shft)>;
-def : T2Pat<(int_arm_usat (sra GPRnopc:$a, asr_imm:$shft), imm0_31:$pos),
- (t2USAT imm0_31:$pos, GPRnopc:$a, asr_imm:$shft)>;
-def : T2Pat<(ARMssat (shl GPRnopc:$a, imm0_31:$shft), imm0_31:$pos),
- (t2SSAT imm0_31:$pos, GPRnopc:$a, imm0_31:$shft)>;
-def : T2Pat<(ARMssat (sra GPRnopc:$Rn, asr_imm:$shft), imm0_31:$pos),
- (t2SSAT imm0_31:$pos, GPRnopc:$Rn, asr_imm:$shft)>;
-def : T2Pat<(ARMusat (shl GPRnopc:$a, imm0_31:$shft), imm0_31:$pos),
- (t2USAT imm0_31:$pos, GPRnopc:$a, imm0_31:$shft)>;
-def : T2Pat<(ARMusat (sra GPRnopc:$Rn, asr_imm:$shft), imm0_31:$pos),
- (t2USAT imm0_31:$pos, GPRnopc:$Rn, asr_imm:$shft)>;
-
-
+def : T2Pat<(int_arm_ssat (shl GPRnopc:$a, imm0_31:$shft), imm1_32:$pos),
+ (t2SSAT imm1_32:$pos, GPRnopc:$a, imm0_31:$shft)>;
+def : T2Pat<(int_arm_ssat (sra GPRnopc:$a, asr_imm:$shft), imm1_32:$pos),
+ (t2SSAT imm1_32:$pos, GPRnopc:$a, asr_imm:$shft)>;
+def : T2Pat<(int_arm_usat (shl GPRnopc:$a, imm0_31:$shft), imm0_31:$pos),
+ (t2USAT imm0_31:$pos, GPRnopc:$a, imm0_31:$shft)>;
+def : T2Pat<(int_arm_usat (sra GPRnopc:$a, asr_imm:$shft), imm0_31:$pos),
+ (t2USAT imm0_31:$pos, GPRnopc:$a, asr_imm:$shft)>;
+def : T2Pat<(ARMssat (shl GPRnopc:$a, imm0_31:$shft), imm0_31:$pos),
+ (t2SSAT imm0_31:$pos, GPRnopc:$a, imm0_31:$shft)>;
+def : T2Pat<(ARMssat (sra GPRnopc:$Rn, asr_imm:$shft), imm0_31:$pos),
+ (t2SSAT imm0_31:$pos, GPRnopc:$Rn, asr_imm:$shft)>;
+def : T2Pat<(ARMusat (shl GPRnopc:$a, imm0_31:$shft), imm0_31:$pos),
+ (t2USAT imm0_31:$pos, GPRnopc:$a, imm0_31:$shft)>;
+def : T2Pat<(ARMusat (sra GPRnopc:$Rn, asr_imm:$shft), imm0_31:$pos),
+ (t2USAT imm0_31:$pos, GPRnopc:$Rn, asr_imm:$shft)>;
+
+
//===----------------------------------------------------------------------===//
// Shift and rotate Instructions.
//
@@ -4935,15 +4935,15 @@ def : InstAlias<"pssbb", (t2DSB 0x4, 14, 0), 1>, Requires<[HasDB, IsThumb2]>;
// Armv8-R 'Data Full Barrier'
def : InstAlias<"dfb${p}", (t2DSB 0xc, pred:$p), 1>, Requires<[HasDFB]>;
-// SpeculationBarrierEndBB must only be used after an unconditional control
-// flow, i.e. after a terminator for which isBarrier is True.
-let hasSideEffects = 1, isCodeGenOnly = 1, isTerminator = 1, isBarrier = 1 in {
- def t2SpeculationBarrierISBDSBEndBB
- : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
- def t2SpeculationBarrierSBEndBB
- : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
-}
-
+// SpeculationBarrierEndBB must only be used after an unconditional control
+// flow, i.e. after a terminator for which isBarrier is True.
+let hasSideEffects = 1, isCodeGenOnly = 1, isTerminator = 1, isBarrier = 1 in {
+ def t2SpeculationBarrierISBDSBEndBB
+ : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
+ def t2SpeculationBarrierSBEndBB
+ : PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
+}
+
// Alias for LDR, LDRB, LDRH, LDRSB, and LDRSH without the ".w" optional
// width specifier.
def : t2InstAlias<"ldr${p} $Rt, $addr",
@@ -5429,17 +5429,17 @@ def t2LE : t2LOL<(outs ), (ins lelabel_u11:$label), "le", "$label"> {
let isTerminator = 1;
}
-let Predicates = [IsThumb2, HasV8_1MMainline, HasLOB] in {
-
-let usesCustomInserter = 1 in
+let Predicates = [IsThumb2, HasV8_1MMainline, HasLOB] in {
+
+let usesCustomInserter = 1 in
def t2DoLoopStart :
- t2PseudoInst<(outs GPRlr:$X), (ins rGPR:$elts), 4, IIC_Br,
- [(set GPRlr:$X, (int_start_loop_iterations rGPR:$elts))]>;
+ t2PseudoInst<(outs GPRlr:$X), (ins rGPR:$elts), 4, IIC_Br,
+ [(set GPRlr:$X, (int_start_loop_iterations rGPR:$elts))]>;
+
+let isTerminator = 1, hasSideEffects = 1 in
+def t2DoLoopStartTP :
+ t2PseudoInst<(outs GPRlr:$X), (ins rGPR:$elts, rGPR:$count), 4, IIC_Br, []>;
-let isTerminator = 1, hasSideEffects = 1 in
-def t2DoLoopStartTP :
- t2PseudoInst<(outs GPRlr:$X), (ins rGPR:$elts, rGPR:$count), 4, IIC_Br, []>;
-
let hasSideEffects = 0 in
def t2LoopDec :
t2PseudoInst<(outs GPRlr:$Rm), (ins GPRlr:$Rn, imm0_7:$size),
@@ -5458,14 +5458,14 @@ def t2LoopEnd :
t2PseudoInst<(outs), (ins GPRlr:$elts, brtarget:$target),
8, IIC_Br, []>, Sched<[WriteBr]>;
-def t2LoopEndDec :
- t2PseudoInst<(outs GPRlr:$Rm), (ins GPRlr:$elts, brtarget:$target),
- 8, IIC_Br, []>, Sched<[WriteBr]>;
-
+def t2LoopEndDec :
+ t2PseudoInst<(outs GPRlr:$Rm), (ins GPRlr:$elts, brtarget:$target),
+ 8, IIC_Br, []>, Sched<[WriteBr]>;
+
} // end isBranch, isTerminator, hasSideEffects
-}
-
+}
+
} // end isNotDuplicable
class CS<string iname, bits<4> opcode, list<dag> pattern=[]>
@@ -5484,7 +5484,7 @@ class CS<string iname, bits<4> opcode, list<dag> pattern=[]>
let Inst{3-0} = Rm{3-0};
let Uses = [CPSR];
- let hasSideEffects = 0;
+ let hasSideEffects = 0;
}
def t2CSEL : CS<"csel", 0b1000>;
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMInstrVFP.td b/contrib/libs/llvm12/lib/Target/ARM/ARMInstrVFP.td
index 9034b35ded..2be58d7a0e 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMInstrVFP.td
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMInstrVFP.td
@@ -54,16 +54,16 @@ def vfp_f16imm : Operand<f16>,
let ParserMatchClass = FPImmOperand;
}
-def vfp_f32f16imm_xform : SDNodeXForm<fpimm, [{
- APFloat InVal = N->getValueAPF();
- uint32_t enc = ARM_AM::getFP32FP16Imm(InVal);
- return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
- }]>;
-
-def vfp_f32f16imm : PatLeaf<(f32 fpimm), [{
- return ARM_AM::getFP32FP16Imm(N->getValueAPF()) != -1;
- }], vfp_f32f16imm_xform>;
-
+def vfp_f32f16imm_xform : SDNodeXForm<fpimm, [{
+ APFloat InVal = N->getValueAPF();
+ uint32_t enc = ARM_AM::getFP32FP16Imm(InVal);
+ return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
+ }]>;
+
+def vfp_f32f16imm : PatLeaf<(f32 fpimm), [{
+ return ARM_AM::getFP32FP16Imm(N->getValueAPF()) != -1;
+ }], vfp_f32f16imm_xform>;
+
def vfp_f32imm_xform : SDNodeXForm<fpimm, [{
APFloat InVal = N->getValueAPF();
uint32_t enc = ARM_AM::getFP32Imm(InVal);
@@ -1561,8 +1561,8 @@ class AVConv1InsS_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
let Inst{5} = Sm{0};
let Inst{15-12} = Sd{4-1};
let Inst{22} = Sd{0};
-
- let hasSideEffects = 0;
+
+ let hasSideEffects = 0;
}
class AVConv1IsH_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
@@ -2626,11 +2626,11 @@ def FCONSTH : VFPAI<(outs HPR:$Sd), (ins vfp_f16imm:$imm),
}
}
-def : Pat<(f32 (vfp_f32f16imm:$imm)),
- (f32 (COPY_TO_REGCLASS (f16 (FCONSTH (vfp_f32f16imm_xform (f32 $imm)))), SPR))> {
- let Predicates = [HasFullFP16];
-}
-
+def : Pat<(f32 (vfp_f32f16imm:$imm)),
+ (f32 (COPY_TO_REGCLASS (f16 (FCONSTH (vfp_f32f16imm_xform (f32 $imm)))), SPR))> {
+ let Predicates = [HasFullFP16];
+}
+
//===----------------------------------------------------------------------===//
// Assembler aliases.
//
@@ -2846,12 +2846,12 @@ let Predicates = [HasV8_1MMainline, HasMVEInt] in {
}
defm VSTR_P0 : vfp_vstrldr_sysreg<0b0,0b1101, "p0",
(outs), (ins VCCR:$P0)>;
-
- let Defs = [VPR] in {
- defm VLDR_VPR : vfp_vstrldr_sysreg<0b1,0b1100, "vpr">;
- }
- defm VLDR_P0 : vfp_vstrldr_sysreg<0b1,0b1101, "p0",
- (outs VCCR:$P0), (ins)>;
+
+ let Defs = [VPR] in {
+ defm VLDR_VPR : vfp_vstrldr_sysreg<0b1,0b1100, "vpr">;
+ }
+ defm VLDR_P0 : vfp_vstrldr_sysreg<0b1,0b1101, "p0",
+ (outs VCCR:$P0), (ins)>;
}
let Uses = [FPSCR] in {
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMLegalizerInfo.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMLegalizerInfo.cpp
index 92b7dd5047..d9b60f4c4e 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMLegalizerInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMLegalizerInfo.cpp
@@ -88,7 +88,7 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
getActionDefinitionsBuilder({G_MUL, G_AND, G_OR, G_XOR})
.legalFor({s32})
- .clampScalar(0, s32, s32);
+ .clampScalar(0, s32, s32);
if (ST.hasNEON())
getActionDefinitionsBuilder({G_ADD, G_SUB})
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
index e264726f91..aa1fe4e4ff 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -1268,7 +1268,7 @@ findIncDecAfter(MachineBasicBlock::iterator MBBI, Register Reg,
bool ARMLoadStoreOpt::MergeBaseUpdateLSMultiple(MachineInstr *MI) {
// Thumb1 is already using updating loads/stores.
if (isThumb1) return false;
- LLVM_DEBUG(dbgs() << "Attempting to merge update of: " << *MI);
+ LLVM_DEBUG(dbgs() << "Attempting to merge update of: " << *MI);
const MachineOperand &BaseOP = MI->getOperand(0);
Register Base = BaseOP.getReg();
@@ -1320,10 +1320,10 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLSMultiple(MachineInstr *MI) {
return false;
}
}
- if (MergeInstr != MBB.end()) {
- LLVM_DEBUG(dbgs() << " Erasing old increment: " << *MergeInstr);
+ if (MergeInstr != MBB.end()) {
+ LLVM_DEBUG(dbgs() << " Erasing old increment: " << *MergeInstr);
MBB.erase(MergeInstr);
- }
+ }
unsigned NewOpc = getUpdatingLSMultipleOpcode(Opcode, Mode);
MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc))
@@ -1338,7 +1338,7 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLSMultiple(MachineInstr *MI) {
// Transfer memoperands.
MIB.setMemRefs(MI->memoperands());
- LLVM_DEBUG(dbgs() << " Added new load/store: " << *MIB);
+ LLVM_DEBUG(dbgs() << " Added new load/store: " << *MIB);
MBB.erase(MBBI);
return true;
}
@@ -1386,27 +1386,27 @@ static unsigned getPostIndexedLoadStoreOpcode(unsigned Opc,
case ARM::t2LDRi8:
case ARM::t2LDRi12:
return ARM::t2LDR_POST;
- case ARM::t2LDRBi8:
- case ARM::t2LDRBi12:
- return ARM::t2LDRB_POST;
- case ARM::t2LDRSBi8:
- case ARM::t2LDRSBi12:
- return ARM::t2LDRSB_POST;
- case ARM::t2LDRHi8:
- case ARM::t2LDRHi12:
- return ARM::t2LDRH_POST;
- case ARM::t2LDRSHi8:
- case ARM::t2LDRSHi12:
- return ARM::t2LDRSH_POST;
+ case ARM::t2LDRBi8:
+ case ARM::t2LDRBi12:
+ return ARM::t2LDRB_POST;
+ case ARM::t2LDRSBi8:
+ case ARM::t2LDRSBi12:
+ return ARM::t2LDRSB_POST;
+ case ARM::t2LDRHi8:
+ case ARM::t2LDRHi12:
+ return ARM::t2LDRH_POST;
+ case ARM::t2LDRSHi8:
+ case ARM::t2LDRSHi12:
+ return ARM::t2LDRSH_POST;
case ARM::t2STRi8:
case ARM::t2STRi12:
return ARM::t2STR_POST;
- case ARM::t2STRBi8:
- case ARM::t2STRBi12:
- return ARM::t2STRB_POST;
- case ARM::t2STRHi8:
- case ARM::t2STRHi12:
- return ARM::t2STRH_POST;
+ case ARM::t2STRBi8:
+ case ARM::t2STRBi12:
+ return ARM::t2STRB_POST;
+ case ARM::t2STRHi8:
+ case ARM::t2STRHi12:
+ return ARM::t2STRH_POST;
case ARM::MVE_VLDRBS16:
return ARM::MVE_VLDRBS16_post;
@@ -1449,7 +1449,7 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLoadStore(MachineInstr *MI) {
// Thumb1 doesn't have updating LDR/STR.
// FIXME: Use LDM/STM with single register instead.
if (isThumb1) return false;
- LLVM_DEBUG(dbgs() << "Attempting to merge update of: " << *MI);
+ LLVM_DEBUG(dbgs() << "Attempting to merge update of: " << *MI);
Register Base = getLoadStoreBaseOp(*MI).getReg();
bool BaseKill = getLoadStoreBaseOp(*MI).isKill();
@@ -1491,7 +1491,7 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLoadStore(MachineInstr *MI) {
} else
return false;
}
- LLVM_DEBUG(dbgs() << " Erasing old increment: " << *MergeInstr);
+ LLVM_DEBUG(dbgs() << " Erasing old increment: " << *MergeInstr);
MBB.erase(MergeInstr);
ARM_AM::AddrOpc AddSub = Offset < 0 ? ARM_AM::sub : ARM_AM::add;
@@ -1503,54 +1503,54 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLoadStore(MachineInstr *MI) {
// updating load/store-multiple instructions can be used with only one
// register.)
MachineOperand &MO = MI->getOperand(0);
- auto MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc))
- .addReg(Base, getDefRegState(true)) // WB base register
- .addReg(Base, getKillRegState(isLd ? BaseKill : false))
- .addImm(Pred)
- .addReg(PredReg)
- .addReg(MO.getReg(), (isLd ? getDefRegState(true)
- : getKillRegState(MO.isKill())))
- .cloneMemRefs(*MI);
- (void)MIB;
- LLVM_DEBUG(dbgs() << " Added new instruction: " << *MIB);
+ auto MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc))
+ .addReg(Base, getDefRegState(true)) // WB base register
+ .addReg(Base, getKillRegState(isLd ? BaseKill : false))
+ .addImm(Pred)
+ .addReg(PredReg)
+ .addReg(MO.getReg(), (isLd ? getDefRegState(true)
+ : getKillRegState(MO.isKill())))
+ .cloneMemRefs(*MI);
+ (void)MIB;
+ LLVM_DEBUG(dbgs() << " Added new instruction: " << *MIB);
} else if (isLd) {
if (isAM2) {
// LDR_PRE, LDR_POST
if (NewOpc == ARM::LDR_PRE_IMM || NewOpc == ARM::LDRB_PRE_IMM) {
- auto MIB =
- BuildMI(MBB, MBBI, DL, TII->get(NewOpc), MI->getOperand(0).getReg())
- .addReg(Base, RegState::Define)
- .addReg(Base)
- .addImm(Offset)
- .addImm(Pred)
- .addReg(PredReg)
- .cloneMemRefs(*MI);
- (void)MIB;
- LLVM_DEBUG(dbgs() << " Added new instruction: " << *MIB);
+ auto MIB =
+ BuildMI(MBB, MBBI, DL, TII->get(NewOpc), MI->getOperand(0).getReg())
+ .addReg(Base, RegState::Define)
+ .addReg(Base)
+ .addImm(Offset)
+ .addImm(Pred)
+ .addReg(PredReg)
+ .cloneMemRefs(*MI);
+ (void)MIB;
+ LLVM_DEBUG(dbgs() << " Added new instruction: " << *MIB);
} else {
int Imm = ARM_AM::getAM2Opc(AddSub, Bytes, ARM_AM::no_shift);
- auto MIB =
- BuildMI(MBB, MBBI, DL, TII->get(NewOpc), MI->getOperand(0).getReg())
- .addReg(Base, RegState::Define)
- .addReg(Base)
- .addReg(0)
- .addImm(Imm)
- .add(predOps(Pred, PredReg))
- .cloneMemRefs(*MI);
- (void)MIB;
- LLVM_DEBUG(dbgs() << " Added new instruction: " << *MIB);
+ auto MIB =
+ BuildMI(MBB, MBBI, DL, TII->get(NewOpc), MI->getOperand(0).getReg())
+ .addReg(Base, RegState::Define)
+ .addReg(Base)
+ .addReg(0)
+ .addImm(Imm)
+ .add(predOps(Pred, PredReg))
+ .cloneMemRefs(*MI);
+ (void)MIB;
+ LLVM_DEBUG(dbgs() << " Added new instruction: " << *MIB);
}
} else {
// t2LDR_PRE, t2LDR_POST
- auto MIB =
- BuildMI(MBB, MBBI, DL, TII->get(NewOpc), MI->getOperand(0).getReg())
- .addReg(Base, RegState::Define)
- .addReg(Base)
- .addImm(Offset)
- .add(predOps(Pred, PredReg))
- .cloneMemRefs(*MI);
- (void)MIB;
- LLVM_DEBUG(dbgs() << " Added new instruction: " << *MIB);
+ auto MIB =
+ BuildMI(MBB, MBBI, DL, TII->get(NewOpc), MI->getOperand(0).getReg())
+ .addReg(Base, RegState::Define)
+ .addReg(Base)
+ .addImm(Offset)
+ .add(predOps(Pred, PredReg))
+ .cloneMemRefs(*MI);
+ (void)MIB;
+ LLVM_DEBUG(dbgs() << " Added new instruction: " << *MIB);
}
} else {
MachineOperand &MO = MI->getOperand(0);
@@ -1560,25 +1560,25 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLoadStore(MachineInstr *MI) {
if (isAM2 && NewOpc == ARM::STR_POST_IMM) {
int Imm = ARM_AM::getAM2Opc(AddSub, Bytes, ARM_AM::no_shift);
// STR_PRE, STR_POST
- auto MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc), Base)
- .addReg(MO.getReg(), getKillRegState(MO.isKill()))
- .addReg(Base)
- .addReg(0)
- .addImm(Imm)
- .add(predOps(Pred, PredReg))
- .cloneMemRefs(*MI);
- (void)MIB;
- LLVM_DEBUG(dbgs() << " Added new instruction: " << *MIB);
+ auto MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc), Base)
+ .addReg(MO.getReg(), getKillRegState(MO.isKill()))
+ .addReg(Base)
+ .addReg(0)
+ .addImm(Imm)
+ .add(predOps(Pred, PredReg))
+ .cloneMemRefs(*MI);
+ (void)MIB;
+ LLVM_DEBUG(dbgs() << " Added new instruction: " << *MIB);
} else {
// t2STR_PRE, t2STR_POST
- auto MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc), Base)
- .addReg(MO.getReg(), getKillRegState(MO.isKill()))
- .addReg(Base)
- .addImm(Offset)
- .add(predOps(Pred, PredReg))
- .cloneMemRefs(*MI);
- (void)MIB;
- LLVM_DEBUG(dbgs() << " Added new instruction: " << *MIB);
+ auto MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc), Base)
+ .addReg(MO.getReg(), getKillRegState(MO.isKill()))
+ .addReg(Base)
+ .addImm(Offset)
+ .add(predOps(Pred, PredReg))
+ .cloneMemRefs(*MI);
+ (void)MIB;
+ LLVM_DEBUG(dbgs() << " Added new instruction: " << *MIB);
}
}
MBB.erase(MBBI);
@@ -1592,7 +1592,7 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLSDouble(MachineInstr &MI) const {
"Must have t2STRDi8 or t2LDRDi8");
if (MI.getOperand(3).getImm() != 0)
return false;
- LLVM_DEBUG(dbgs() << "Attempting to merge update of: " << MI);
+ LLVM_DEBUG(dbgs() << "Attempting to merge update of: " << MI);
// Behaviour for writeback is undefined if base register is the same as one
// of the others.
@@ -1620,7 +1620,7 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLSDouble(MachineInstr &MI) const {
} else
return false;
}
- LLVM_DEBUG(dbgs() << " Erasing old increment: " << *MergeInstr);
+ LLVM_DEBUG(dbgs() << " Erasing old increment: " << *MergeInstr);
MBB.erase(MergeInstr);
DebugLoc DL = MI.getDebugLoc();
@@ -1642,7 +1642,7 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLSDouble(MachineInstr &MI) const {
MIB.add(MO);
MIB.cloneMemRefs(MI);
- LLVM_DEBUG(dbgs() << " Added new load/store: " << *MIB);
+ LLVM_DEBUG(dbgs() << " Added new load/store: " << *MIB);
MBB.erase(MBBI);
return true;
}
@@ -2585,169 +2585,169 @@ static int getBaseOperandIndex(MachineInstr &MI) {
case ARM::MVE_VSTRBU8:
case ARM::MVE_VSTRHU16:
case ARM::MVE_VSTRWU32:
- case ARM::t2LDRHi8:
- case ARM::t2LDRHi12:
- case ARM::t2LDRSHi8:
- case ARM::t2LDRSHi12:
- case ARM::t2LDRBi8:
- case ARM::t2LDRBi12:
- case ARM::t2LDRSBi8:
- case ARM::t2LDRSBi12:
- case ARM::t2STRBi8:
- case ARM::t2STRBi12:
- case ARM::t2STRHi8:
- case ARM::t2STRHi12:
+ case ARM::t2LDRHi8:
+ case ARM::t2LDRHi12:
+ case ARM::t2LDRSHi8:
+ case ARM::t2LDRSHi12:
+ case ARM::t2LDRBi8:
+ case ARM::t2LDRBi12:
+ case ARM::t2LDRSBi8:
+ case ARM::t2LDRSBi12:
+ case ARM::t2STRBi8:
+ case ARM::t2STRBi12:
+ case ARM::t2STRHi8:
+ case ARM::t2STRHi12:
return 1;
- case ARM::MVE_VLDRBS16_post:
- case ARM::MVE_VLDRBS32_post:
- case ARM::MVE_VLDRBU16_post:
- case ARM::MVE_VLDRBU32_post:
- case ARM::MVE_VLDRHS32_post:
- case ARM::MVE_VLDRHU32_post:
- case ARM::MVE_VLDRBU8_post:
- case ARM::MVE_VLDRHU16_post:
- case ARM::MVE_VLDRWU32_post:
- case ARM::MVE_VSTRB16_post:
- case ARM::MVE_VSTRB32_post:
- case ARM::MVE_VSTRH32_post:
- case ARM::MVE_VSTRBU8_post:
- case ARM::MVE_VSTRHU16_post:
- case ARM::MVE_VSTRWU32_post:
- case ARM::MVE_VLDRBS16_pre:
- case ARM::MVE_VLDRBS32_pre:
- case ARM::MVE_VLDRBU16_pre:
- case ARM::MVE_VLDRBU32_pre:
- case ARM::MVE_VLDRHS32_pre:
- case ARM::MVE_VLDRHU32_pre:
- case ARM::MVE_VLDRBU8_pre:
- case ARM::MVE_VLDRHU16_pre:
- case ARM::MVE_VLDRWU32_pre:
- case ARM::MVE_VSTRB16_pre:
- case ARM::MVE_VSTRB32_pre:
- case ARM::MVE_VSTRH32_pre:
- case ARM::MVE_VSTRBU8_pre:
- case ARM::MVE_VSTRHU16_pre:
- case ARM::MVE_VSTRWU32_pre:
- return 2;
+ case ARM::MVE_VLDRBS16_post:
+ case ARM::MVE_VLDRBS32_post:
+ case ARM::MVE_VLDRBU16_post:
+ case ARM::MVE_VLDRBU32_post:
+ case ARM::MVE_VLDRHS32_post:
+ case ARM::MVE_VLDRHU32_post:
+ case ARM::MVE_VLDRBU8_post:
+ case ARM::MVE_VLDRHU16_post:
+ case ARM::MVE_VLDRWU32_post:
+ case ARM::MVE_VSTRB16_post:
+ case ARM::MVE_VSTRB32_post:
+ case ARM::MVE_VSTRH32_post:
+ case ARM::MVE_VSTRBU8_post:
+ case ARM::MVE_VSTRHU16_post:
+ case ARM::MVE_VSTRWU32_post:
+ case ARM::MVE_VLDRBS16_pre:
+ case ARM::MVE_VLDRBS32_pre:
+ case ARM::MVE_VLDRBU16_pre:
+ case ARM::MVE_VLDRBU32_pre:
+ case ARM::MVE_VLDRHS32_pre:
+ case ARM::MVE_VLDRHU32_pre:
+ case ARM::MVE_VLDRBU8_pre:
+ case ARM::MVE_VLDRHU16_pre:
+ case ARM::MVE_VLDRWU32_pre:
+ case ARM::MVE_VSTRB16_pre:
+ case ARM::MVE_VSTRB32_pre:
+ case ARM::MVE_VSTRH32_pre:
+ case ARM::MVE_VSTRBU8_pre:
+ case ARM::MVE_VSTRHU16_pre:
+ case ARM::MVE_VSTRWU32_pre:
+ return 2;
}
return -1;
}
-static bool isPostIndex(MachineInstr &MI) {
- switch (MI.getOpcode()) {
- case ARM::MVE_VLDRBS16_post:
- case ARM::MVE_VLDRBS32_post:
- case ARM::MVE_VLDRBU16_post:
- case ARM::MVE_VLDRBU32_post:
- case ARM::MVE_VLDRHS32_post:
- case ARM::MVE_VLDRHU32_post:
- case ARM::MVE_VLDRBU8_post:
- case ARM::MVE_VLDRHU16_post:
- case ARM::MVE_VLDRWU32_post:
- case ARM::MVE_VSTRB16_post:
- case ARM::MVE_VSTRB32_post:
- case ARM::MVE_VSTRH32_post:
- case ARM::MVE_VSTRBU8_post:
- case ARM::MVE_VSTRHU16_post:
- case ARM::MVE_VSTRWU32_post:
- return true;
- }
- return false;
-}
-
-static bool isPreIndex(MachineInstr &MI) {
- switch (MI.getOpcode()) {
- case ARM::MVE_VLDRBS16_pre:
- case ARM::MVE_VLDRBS32_pre:
- case ARM::MVE_VLDRBU16_pre:
- case ARM::MVE_VLDRBU32_pre:
- case ARM::MVE_VLDRHS32_pre:
- case ARM::MVE_VLDRHU32_pre:
- case ARM::MVE_VLDRBU8_pre:
- case ARM::MVE_VLDRHU16_pre:
- case ARM::MVE_VLDRWU32_pre:
- case ARM::MVE_VSTRB16_pre:
- case ARM::MVE_VSTRB32_pre:
- case ARM::MVE_VSTRH32_pre:
- case ARM::MVE_VSTRBU8_pre:
- case ARM::MVE_VSTRHU16_pre:
- case ARM::MVE_VSTRWU32_pre:
- return true;
- }
- return false;
-}
-
-// Given a memory access Opcode, check that the give Imm would be a valid Offset
-// for this instruction (same as isLegalAddressImm), Or if the instruction
-// could be easily converted to one where that was valid. For example converting
-// t2LDRi12 to t2LDRi8 for negative offsets. Works in conjunction with
-// AdjustBaseAndOffset below.
-static bool isLegalOrConvertableAddressImm(unsigned Opcode, int Imm,
- const TargetInstrInfo *TII,
- int &CodesizeEstimate) {
- if (isLegalAddressImm(Opcode, Imm, TII))
- return true;
-
- // We can convert AddrModeT2_i12 to AddrModeT2_i8.
- const MCInstrDesc &Desc = TII->get(Opcode);
- unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
- switch (AddrMode) {
- case ARMII::AddrModeT2_i12:
- CodesizeEstimate += 1;
- return std::abs(Imm) < (((1 << 8) * 1) - 1);
- }
- return false;
-}
-
-// Given an MI adjust its address BaseReg to use NewBaseReg and address offset
-// by -Offset. This can either happen in-place or be a replacement as MI is
-// converted to another instruction type.
-static void AdjustBaseAndOffset(MachineInstr *MI, Register NewBaseReg,
- int Offset, const TargetInstrInfo *TII) {
- unsigned BaseOp = getBaseOperandIndex(*MI);
- MI->getOperand(BaseOp).setReg(NewBaseReg);
- int OldOffset = MI->getOperand(BaseOp + 1).getImm();
- if (isLegalAddressImm(MI->getOpcode(), OldOffset - Offset, TII))
- MI->getOperand(BaseOp + 1).setImm(OldOffset - Offset);
- else {
- unsigned ConvOpcode;
- switch (MI->getOpcode()) {
- case ARM::t2LDRHi12:
- ConvOpcode = ARM::t2LDRHi8;
- break;
- case ARM::t2LDRSHi12:
- ConvOpcode = ARM::t2LDRSHi8;
- break;
- case ARM::t2LDRBi12:
- ConvOpcode = ARM::t2LDRBi8;
- break;
- case ARM::t2LDRSBi12:
- ConvOpcode = ARM::t2LDRSBi8;
- break;
- case ARM::t2STRHi12:
- ConvOpcode = ARM::t2STRHi8;
- break;
- case ARM::t2STRBi12:
- ConvOpcode = ARM::t2STRBi8;
- break;
- default:
- llvm_unreachable("Unhandled convertable opcode");
- }
- assert(isLegalAddressImm(ConvOpcode, OldOffset - Offset, TII) &&
- "Illegal Address Immediate after convert!");
-
- const MCInstrDesc &MCID = TII->get(ConvOpcode);
- BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), MCID)
- .add(MI->getOperand(0))
- .add(MI->getOperand(1))
- .addImm(OldOffset - Offset)
- .add(MI->getOperand(3))
- .add(MI->getOperand(4))
- .cloneMemRefs(*MI);
- MI->eraseFromParent();
- }
-}
-
+static bool isPostIndex(MachineInstr &MI) {
+ switch (MI.getOpcode()) {
+ case ARM::MVE_VLDRBS16_post:
+ case ARM::MVE_VLDRBS32_post:
+ case ARM::MVE_VLDRBU16_post:
+ case ARM::MVE_VLDRBU32_post:
+ case ARM::MVE_VLDRHS32_post:
+ case ARM::MVE_VLDRHU32_post:
+ case ARM::MVE_VLDRBU8_post:
+ case ARM::MVE_VLDRHU16_post:
+ case ARM::MVE_VLDRWU32_post:
+ case ARM::MVE_VSTRB16_post:
+ case ARM::MVE_VSTRB32_post:
+ case ARM::MVE_VSTRH32_post:
+ case ARM::MVE_VSTRBU8_post:
+ case ARM::MVE_VSTRHU16_post:
+ case ARM::MVE_VSTRWU32_post:
+ return true;
+ }
+ return false;
+}
+
+static bool isPreIndex(MachineInstr &MI) {
+ switch (MI.getOpcode()) {
+ case ARM::MVE_VLDRBS16_pre:
+ case ARM::MVE_VLDRBS32_pre:
+ case ARM::MVE_VLDRBU16_pre:
+ case ARM::MVE_VLDRBU32_pre:
+ case ARM::MVE_VLDRHS32_pre:
+ case ARM::MVE_VLDRHU32_pre:
+ case ARM::MVE_VLDRBU8_pre:
+ case ARM::MVE_VLDRHU16_pre:
+ case ARM::MVE_VLDRWU32_pre:
+ case ARM::MVE_VSTRB16_pre:
+ case ARM::MVE_VSTRB32_pre:
+ case ARM::MVE_VSTRH32_pre:
+ case ARM::MVE_VSTRBU8_pre:
+ case ARM::MVE_VSTRHU16_pre:
+ case ARM::MVE_VSTRWU32_pre:
+ return true;
+ }
+ return false;
+}
+
+// Given a memory access Opcode, check that the give Imm would be a valid Offset
+// for this instruction (same as isLegalAddressImm), Or if the instruction
+// could be easily converted to one where that was valid. For example converting
+// t2LDRi12 to t2LDRi8 for negative offsets. Works in conjunction with
+// AdjustBaseAndOffset below.
+static bool isLegalOrConvertableAddressImm(unsigned Opcode, int Imm,
+ const TargetInstrInfo *TII,
+ int &CodesizeEstimate) {
+ if (isLegalAddressImm(Opcode, Imm, TII))
+ return true;
+
+ // We can convert AddrModeT2_i12 to AddrModeT2_i8.
+ const MCInstrDesc &Desc = TII->get(Opcode);
+ unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
+ switch (AddrMode) {
+ case ARMII::AddrModeT2_i12:
+ CodesizeEstimate += 1;
+ return std::abs(Imm) < (((1 << 8) * 1) - 1);
+ }
+ return false;
+}
+
+// Given an MI adjust its address BaseReg to use NewBaseReg and address offset
+// by -Offset. This can either happen in-place or be a replacement as MI is
+// converted to another instruction type.
+static void AdjustBaseAndOffset(MachineInstr *MI, Register NewBaseReg,
+ int Offset, const TargetInstrInfo *TII) {
+ unsigned BaseOp = getBaseOperandIndex(*MI);
+ MI->getOperand(BaseOp).setReg(NewBaseReg);
+ int OldOffset = MI->getOperand(BaseOp + 1).getImm();
+ if (isLegalAddressImm(MI->getOpcode(), OldOffset - Offset, TII))
+ MI->getOperand(BaseOp + 1).setImm(OldOffset - Offset);
+ else {
+ unsigned ConvOpcode;
+ switch (MI->getOpcode()) {
+ case ARM::t2LDRHi12:
+ ConvOpcode = ARM::t2LDRHi8;
+ break;
+ case ARM::t2LDRSHi12:
+ ConvOpcode = ARM::t2LDRSHi8;
+ break;
+ case ARM::t2LDRBi12:
+ ConvOpcode = ARM::t2LDRBi8;
+ break;
+ case ARM::t2LDRSBi12:
+ ConvOpcode = ARM::t2LDRSBi8;
+ break;
+ case ARM::t2STRHi12:
+ ConvOpcode = ARM::t2STRHi8;
+ break;
+ case ARM::t2STRBi12:
+ ConvOpcode = ARM::t2STRBi8;
+ break;
+ default:
+ llvm_unreachable("Unhandled convertable opcode");
+ }
+ assert(isLegalAddressImm(ConvOpcode, OldOffset - Offset, TII) &&
+ "Illegal Address Immediate after convert!");
+
+ const MCInstrDesc &MCID = TII->get(ConvOpcode);
+ BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), MCID)
+ .add(MI->getOperand(0))
+ .add(MI->getOperand(1))
+ .addImm(OldOffset - Offset)
+ .add(MI->getOperand(3))
+ .add(MI->getOperand(4))
+ .cloneMemRefs(*MI);
+ MI->eraseFromParent();
+ }
+}
+
static MachineInstr *createPostIncLoadStore(MachineInstr *MI, int Offset,
Register NewReg,
const TargetInstrInfo *TII,
@@ -2766,70 +2766,70 @@ static MachineInstr *createPostIncLoadStore(MachineInstr *MI, int Offset,
TRC = TII->getRegClass(MCID, 2, TRI, *MF);
MRI.constrainRegClass(MI->getOperand(1).getReg(), TRC);
- unsigned AddrMode = (MCID.TSFlags & ARMII::AddrModeMask);
- switch (AddrMode) {
- case ARMII::AddrModeT2_i7:
- case ARMII::AddrModeT2_i7s2:
- case ARMII::AddrModeT2_i7s4:
- // Any MVE load/store
- return BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), MCID)
- .addReg(NewReg, RegState::Define)
- .add(MI->getOperand(0))
- .add(MI->getOperand(1))
- .addImm(Offset)
- .add(MI->getOperand(3))
- .add(MI->getOperand(4))
- .cloneMemRefs(*MI);
- case ARMII::AddrModeT2_i8:
- if (MI->mayLoad()) {
- return BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), MCID)
- .add(MI->getOperand(0))
- .addReg(NewReg, RegState::Define)
- .add(MI->getOperand(1))
- .addImm(Offset)
- .add(MI->getOperand(3))
- .add(MI->getOperand(4))
- .cloneMemRefs(*MI);
- } else {
- return BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), MCID)
- .addReg(NewReg, RegState::Define)
- .add(MI->getOperand(0))
- .add(MI->getOperand(1))
- .addImm(Offset)
- .add(MI->getOperand(3))
- .add(MI->getOperand(4))
- .cloneMemRefs(*MI);
- }
- default:
- llvm_unreachable("Unhandled createPostIncLoadStore");
- }
+ unsigned AddrMode = (MCID.TSFlags & ARMII::AddrModeMask);
+ switch (AddrMode) {
+ case ARMII::AddrModeT2_i7:
+ case ARMII::AddrModeT2_i7s2:
+ case ARMII::AddrModeT2_i7s4:
+ // Any MVE load/store
+ return BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), MCID)
+ .addReg(NewReg, RegState::Define)
+ .add(MI->getOperand(0))
+ .add(MI->getOperand(1))
+ .addImm(Offset)
+ .add(MI->getOperand(3))
+ .add(MI->getOperand(4))
+ .cloneMemRefs(*MI);
+ case ARMII::AddrModeT2_i8:
+ if (MI->mayLoad()) {
+ return BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), MCID)
+ .add(MI->getOperand(0))
+ .addReg(NewReg, RegState::Define)
+ .add(MI->getOperand(1))
+ .addImm(Offset)
+ .add(MI->getOperand(3))
+ .add(MI->getOperand(4))
+ .cloneMemRefs(*MI);
+ } else {
+ return BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), MCID)
+ .addReg(NewReg, RegState::Define)
+ .add(MI->getOperand(0))
+ .add(MI->getOperand(1))
+ .addImm(Offset)
+ .add(MI->getOperand(3))
+ .add(MI->getOperand(4))
+ .cloneMemRefs(*MI);
+ }
+ default:
+ llvm_unreachable("Unhandled createPostIncLoadStore");
+ }
}
// Given a Base Register, optimise the load/store uses to attempt to create more
-// post-inc accesses and less register moves. We do this by taking zero offset
-// loads/stores with an add, and convert them to a postinc load/store of the
-// same type. Any subsequent accesses will be adjusted to use and account for
-// the post-inc value.
+// post-inc accesses and less register moves. We do this by taking zero offset
+// loads/stores with an add, and convert them to a postinc load/store of the
+// same type. Any subsequent accesses will be adjusted to use and account for
+// the post-inc value.
// For example:
// LDR #0 LDR_POSTINC #16
// LDR #4 LDR #-12
// LDR #8 LDR #-8
// LDR #12 LDR #-4
// ADD #16
-//
-// At the same time if we do not find an increment but do find an existing
-// pre/post inc instruction, we can still adjust the offsets of subsequent
-// instructions to save the register move that would otherwise be needed for the
-// in-place increment.
+//
+// At the same time if we do not find an increment but do find an existing
+// pre/post inc instruction, we can still adjust the offsets of subsequent
+// instructions to save the register move that would otherwise be needed for the
+// in-place increment.
bool ARMPreAllocLoadStoreOpt::DistributeIncrements(Register Base) {
// We are looking for:
// One zero offset load/store that can become postinc
MachineInstr *BaseAccess = nullptr;
- MachineInstr *PrePostInc = nullptr;
+ MachineInstr *PrePostInc = nullptr;
// An increment that can be folded in
MachineInstr *Increment = nullptr;
// Other accesses after BaseAccess that will need to be updated to use the
- // postinc value.
+ // postinc value.
SmallPtrSet<MachineInstr *, 8> OtherAccesses;
for (auto &Use : MRI->use_nodbg_instructions(Base)) {
if (!Increment && getAddSubImmediate(Use) != 0) {
@@ -2844,81 +2844,81 @@ bool ARMPreAllocLoadStoreOpt::DistributeIncrements(Register Base) {
if (!Use.getOperand(BaseOp).isReg() ||
Use.getOperand(BaseOp).getReg() != Base)
return false;
- if (isPreIndex(Use) || isPostIndex(Use))
- PrePostInc = &Use;
- else if (Use.getOperand(BaseOp + 1).getImm() == 0)
+ if (isPreIndex(Use) || isPostIndex(Use))
+ PrePostInc = &Use;
+ else if (Use.getOperand(BaseOp + 1).getImm() == 0)
BaseAccess = &Use;
else
OtherAccesses.insert(&Use);
}
- int IncrementOffset;
- Register NewBaseReg;
- if (BaseAccess && Increment) {
- if (PrePostInc || BaseAccess->getParent() != Increment->getParent())
- return false;
- Register PredReg;
- if (Increment->definesRegister(ARM::CPSR) ||
- getInstrPredicate(*Increment, PredReg) != ARMCC::AL)
- return false;
-
- LLVM_DEBUG(dbgs() << "\nAttempting to distribute increments on VirtualReg "
- << Base.virtRegIndex() << "\n");
-
- // Make sure that Increment has no uses before BaseAccess.
- for (MachineInstr &Use :
- MRI->use_nodbg_instructions(Increment->getOperand(0).getReg())) {
- if (!DT->dominates(BaseAccess, &Use) || &Use == BaseAccess) {
- LLVM_DEBUG(dbgs() << " BaseAccess doesn't dominate use of increment\n");
- return false;
- }
- }
-
- // Make sure that Increment can be folded into Base
- IncrementOffset = getAddSubImmediate(*Increment);
- unsigned NewPostIncOpcode = getPostIndexedLoadStoreOpcode(
- BaseAccess->getOpcode(), IncrementOffset > 0 ? ARM_AM::add : ARM_AM::sub);
- if (!isLegalAddressImm(NewPostIncOpcode, IncrementOffset, TII)) {
- LLVM_DEBUG(dbgs() << " Illegal addressing mode immediate on postinc\n");
+ int IncrementOffset;
+ Register NewBaseReg;
+ if (BaseAccess && Increment) {
+ if (PrePostInc || BaseAccess->getParent() != Increment->getParent())
+ return false;
+ Register PredReg;
+ if (Increment->definesRegister(ARM::CPSR) ||
+ getInstrPredicate(*Increment, PredReg) != ARMCC::AL)
+ return false;
+
+ LLVM_DEBUG(dbgs() << "\nAttempting to distribute increments on VirtualReg "
+ << Base.virtRegIndex() << "\n");
+
+ // Make sure that Increment has no uses before BaseAccess.
+ for (MachineInstr &Use :
+ MRI->use_nodbg_instructions(Increment->getOperand(0).getReg())) {
+ if (!DT->dominates(BaseAccess, &Use) || &Use == BaseAccess) {
+ LLVM_DEBUG(dbgs() << " BaseAccess doesn't dominate use of increment\n");
+ return false;
+ }
+ }
+
+ // Make sure that Increment can be folded into Base
+ IncrementOffset = getAddSubImmediate(*Increment);
+ unsigned NewPostIncOpcode = getPostIndexedLoadStoreOpcode(
+ BaseAccess->getOpcode(), IncrementOffset > 0 ? ARM_AM::add : ARM_AM::sub);
+ if (!isLegalAddressImm(NewPostIncOpcode, IncrementOffset, TII)) {
+ LLVM_DEBUG(dbgs() << " Illegal addressing mode immediate on postinc\n");
return false;
}
}
- else if (PrePostInc) {
- // If we already have a pre/post index load/store then set BaseAccess,
- // IncrementOffset and NewBaseReg to the values it already produces,
- // allowing us to update and subsequent uses of BaseOp reg with the
- // incremented value.
- if (Increment)
- return false;
-
- LLVM_DEBUG(dbgs() << "\nAttempting to distribute increments on already "
- << "indexed VirtualReg " << Base.virtRegIndex() << "\n");
- int BaseOp = getBaseOperandIndex(*PrePostInc);
- IncrementOffset = PrePostInc->getOperand(BaseOp+1).getImm();
- BaseAccess = PrePostInc;
- NewBaseReg = PrePostInc->getOperand(0).getReg();
- }
- else
+ else if (PrePostInc) {
+ // If we already have a pre/post index load/store then set BaseAccess,
+ // IncrementOffset and NewBaseReg to the values it already produces,
+ // allowing us to update and subsequent uses of BaseOp reg with the
+ // incremented value.
+ if (Increment)
+ return false;
+
+ LLVM_DEBUG(dbgs() << "\nAttempting to distribute increments on already "
+ << "indexed VirtualReg " << Base.virtRegIndex() << "\n");
+ int BaseOp = getBaseOperandIndex(*PrePostInc);
+ IncrementOffset = PrePostInc->getOperand(BaseOp+1).getImm();
+ BaseAccess = PrePostInc;
+ NewBaseReg = PrePostInc->getOperand(0).getReg();
+ }
+ else
return false;
// And make sure that the negative value of increment can be added to all
// other offsets after the BaseAccess. We rely on either
// dominates(BaseAccess, OtherAccess) or dominates(OtherAccess, BaseAccess)
// to keep things simple.
- // This also adds a simple codesize metric, to detect if an instruction (like
- // t2LDRBi12) which can often be shrunk to a thumb1 instruction (tLDRBi)
- // cannot because it is converted to something else (t2LDRBi8). We start this
- // at -1 for the gain from removing the increment.
+ // This also adds a simple codesize metric, to detect if an instruction (like
+ // t2LDRBi12) which can often be shrunk to a thumb1 instruction (tLDRBi)
+ // cannot because it is converted to something else (t2LDRBi8). We start this
+ // at -1 for the gain from removing the increment.
SmallPtrSet<MachineInstr *, 4> SuccessorAccesses;
- int CodesizeEstimate = -1;
+ int CodesizeEstimate = -1;
for (auto *Use : OtherAccesses) {
if (DT->dominates(BaseAccess, Use)) {
SuccessorAccesses.insert(Use);
unsigned BaseOp = getBaseOperandIndex(*Use);
- if (!isLegalOrConvertableAddressImm(Use->getOpcode(),
- Use->getOperand(BaseOp + 1).getImm() -
- IncrementOffset,
- TII, CodesizeEstimate)) {
+ if (!isLegalOrConvertableAddressImm(Use->getOpcode(),
+ Use->getOperand(BaseOp + 1).getImm() -
+ IncrementOffset,
+ TII, CodesizeEstimate)) {
LLVM_DEBUG(dbgs() << " Illegal addressing mode immediate on use\n");
return false;
}
@@ -2928,27 +2928,27 @@ bool ARMPreAllocLoadStoreOpt::DistributeIncrements(Register Base) {
return false;
}
}
- if (STI->hasMinSize() && CodesizeEstimate > 0) {
- LLVM_DEBUG(dbgs() << " Expected to grow instructions under minsize\n");
- return false;
- }
-
- if (!PrePostInc) {
- // Replace BaseAccess with a post inc
- LLVM_DEBUG(dbgs() << "Changing: "; BaseAccess->dump());
- LLVM_DEBUG(dbgs() << " And : "; Increment->dump());
- NewBaseReg = Increment->getOperand(0).getReg();
- MachineInstr *BaseAccessPost =
- createPostIncLoadStore(BaseAccess, IncrementOffset, NewBaseReg, TII, TRI);
- BaseAccess->eraseFromParent();
- Increment->eraseFromParent();
- (void)BaseAccessPost;
- LLVM_DEBUG(dbgs() << " To : "; BaseAccessPost->dump());
- }
+ if (STI->hasMinSize() && CodesizeEstimate > 0) {
+ LLVM_DEBUG(dbgs() << " Expected to grow instructions under minsize\n");
+ return false;
+ }
+
+ if (!PrePostInc) {
+ // Replace BaseAccess with a post inc
+ LLVM_DEBUG(dbgs() << "Changing: "; BaseAccess->dump());
+ LLVM_DEBUG(dbgs() << " And : "; Increment->dump());
+ NewBaseReg = Increment->getOperand(0).getReg();
+ MachineInstr *BaseAccessPost =
+ createPostIncLoadStore(BaseAccess, IncrementOffset, NewBaseReg, TII, TRI);
+ BaseAccess->eraseFromParent();
+ Increment->eraseFromParent();
+ (void)BaseAccessPost;
+ LLVM_DEBUG(dbgs() << " To : "; BaseAccessPost->dump());
+ }
for (auto *Use : SuccessorAccesses) {
LLVM_DEBUG(dbgs() << "Changing: "; Use->dump());
- AdjustBaseAndOffset(Use, NewBaseReg, IncrementOffset, TII);
+ AdjustBaseAndOffset(Use, NewBaseReg, IncrementOffset, TII);
LLVM_DEBUG(dbgs() << " To : "; Use->dump());
}
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMLowOverheadLoops.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMLowOverheadLoops.cpp
index 144e845550..8dc5320584 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMLowOverheadLoops.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMLowOverheadLoops.cpp
@@ -56,7 +56,7 @@
#include "ARMBaseRegisterInfo.h"
#include "ARMBasicBlockInfo.h"
#include "ARMSubtarget.h"
-#include "MVETailPredUtils.h"
+#include "MVETailPredUtils.h"
#include "Thumb2InstrInfo.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/SmallSet.h"
@@ -74,37 +74,37 @@ using namespace llvm;
#define DEBUG_TYPE "arm-low-overhead-loops"
#define ARM_LOW_OVERHEAD_LOOPS_NAME "ARM Low Overhead Loops pass"
-static cl::opt<bool>
-DisableTailPredication("arm-loloops-disable-tailpred", cl::Hidden,
- cl::desc("Disable tail-predication in the ARM LowOverheadLoop pass"),
- cl::init(false));
-
-static bool isVectorPredicated(MachineInstr *MI) {
- int PIdx = llvm::findFirstVPTPredOperandIdx(*MI);
- return PIdx != -1 && MI->getOperand(PIdx + 1).getReg() == ARM::VPR;
-}
-
-static bool isVectorPredicate(MachineInstr *MI) {
- return MI->findRegisterDefOperandIdx(ARM::VPR) != -1;
-}
-
-static bool hasVPRUse(MachineInstr &MI) {
- return MI.findRegisterUseOperandIdx(ARM::VPR) != -1;
-}
-
-static bool isDomainMVE(MachineInstr *MI) {
- uint64_t Domain = MI->getDesc().TSFlags & ARMII::DomainMask;
- return Domain == ARMII::DomainMVE;
-}
-
-static bool shouldInspect(MachineInstr &MI) {
- return isDomainMVE(&MI) || isVectorPredicate(&MI) || hasVPRUse(MI);
-}
-
-static bool isDo(MachineInstr *MI) {
- return MI->getOpcode() != ARM::t2WhileLoopStart;
-}
-
+static cl::opt<bool>
+DisableTailPredication("arm-loloops-disable-tailpred", cl::Hidden,
+ cl::desc("Disable tail-predication in the ARM LowOverheadLoop pass"),
+ cl::init(false));
+
+static bool isVectorPredicated(MachineInstr *MI) {
+ int PIdx = llvm::findFirstVPTPredOperandIdx(*MI);
+ return PIdx != -1 && MI->getOperand(PIdx + 1).getReg() == ARM::VPR;
+}
+
+static bool isVectorPredicate(MachineInstr *MI) {
+ return MI->findRegisterDefOperandIdx(ARM::VPR) != -1;
+}
+
+static bool hasVPRUse(MachineInstr &MI) {
+ return MI.findRegisterUseOperandIdx(ARM::VPR) != -1;
+}
+
+static bool isDomainMVE(MachineInstr *MI) {
+ uint64_t Domain = MI->getDesc().TSFlags & ARMII::DomainMask;
+ return Domain == ARMII::DomainMVE;
+}
+
+static bool shouldInspect(MachineInstr &MI) {
+ return isDomainMVE(&MI) || isVectorPredicate(&MI) || hasVPRUse(MI);
+}
+
+static bool isDo(MachineInstr *MI) {
+ return MI->getOpcode() != ARM::t2WhileLoopStart;
+}
+
namespace {
using InstSet = SmallPtrSetImpl<MachineInstr *>;
@@ -143,7 +143,7 @@ namespace {
// Insert exit blocks.
SmallVector<MachineBasicBlock*, 2> ExitBlocks;
ML.getExitBlocks(ExitBlocks);
- append_range(Order, ExitBlocks);
+ append_range(Order, ExitBlocks);
// Then add the loop body.
Search(ML.getHeader());
@@ -174,187 +174,187 @@ namespace {
}
};
- // Represent the current state of the VPR and hold all instances which
- // represent a VPT block, which is a list of instructions that begins with a
- // VPT/VPST and has a maximum of four proceeding instructions. All
- // instructions within the block are predicated upon the vpr and we allow
- // instructions to define the vpr within in the block too.
- class VPTState {
- friend struct LowOverheadLoop;
-
- SmallVector<MachineInstr *, 4> Insts;
-
- static SmallVector<VPTState, 4> Blocks;
- static SetVector<MachineInstr *> CurrentPredicates;
- static std::map<MachineInstr *,
- std::unique_ptr<PredicatedMI>> PredicatedInsts;
-
- static void CreateVPTBlock(MachineInstr *MI) {
- assert((CurrentPredicates.size() || MI->getParent()->isLiveIn(ARM::VPR))
- && "Can't begin VPT without predicate");
- Blocks.emplace_back(MI);
- // The execution of MI is predicated upon the current set of instructions
- // that are AND'ed together to form the VPR predicate value. In the case
- // that MI is a VPT, CurrentPredicates will also just be MI.
- PredicatedInsts.emplace(
- MI, std::make_unique<PredicatedMI>(MI, CurrentPredicates));
+ // Represent the current state of the VPR and hold all instances which
+ // represent a VPT block, which is a list of instructions that begins with a
+ // VPT/VPST and has a maximum of four proceeding instructions. All
+ // instructions within the block are predicated upon the vpr and we allow
+ // instructions to define the vpr within in the block too.
+ class VPTState {
+ friend struct LowOverheadLoop;
+
+ SmallVector<MachineInstr *, 4> Insts;
+
+ static SmallVector<VPTState, 4> Blocks;
+ static SetVector<MachineInstr *> CurrentPredicates;
+ static std::map<MachineInstr *,
+ std::unique_ptr<PredicatedMI>> PredicatedInsts;
+
+ static void CreateVPTBlock(MachineInstr *MI) {
+ assert((CurrentPredicates.size() || MI->getParent()->isLiveIn(ARM::VPR))
+ && "Can't begin VPT without predicate");
+ Blocks.emplace_back(MI);
+ // The execution of MI is predicated upon the current set of instructions
+ // that are AND'ed together to form the VPR predicate value. In the case
+ // that MI is a VPT, CurrentPredicates will also just be MI.
+ PredicatedInsts.emplace(
+ MI, std::make_unique<PredicatedMI>(MI, CurrentPredicates));
+ }
+
+ static void reset() {
+ Blocks.clear();
+ PredicatedInsts.clear();
+ CurrentPredicates.clear();
+ }
+
+ static void addInst(MachineInstr *MI) {
+ Blocks.back().insert(MI);
+ PredicatedInsts.emplace(
+ MI, std::make_unique<PredicatedMI>(MI, CurrentPredicates));
+ }
+
+ static void addPredicate(MachineInstr *MI) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: Adding VPT Predicate: " << *MI);
+ CurrentPredicates.insert(MI);
}
- static void reset() {
- Blocks.clear();
- PredicatedInsts.clear();
- CurrentPredicates.clear();
+ static void resetPredicate(MachineInstr *MI) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: Resetting VPT Predicate: " << *MI);
+ CurrentPredicates.clear();
+ CurrentPredicates.insert(MI);
}
- static void addInst(MachineInstr *MI) {
- Blocks.back().insert(MI);
- PredicatedInsts.emplace(
- MI, std::make_unique<PredicatedMI>(MI, CurrentPredicates));
- }
-
- static void addPredicate(MachineInstr *MI) {
- LLVM_DEBUG(dbgs() << "ARM Loops: Adding VPT Predicate: " << *MI);
- CurrentPredicates.insert(MI);
- }
-
- static void resetPredicate(MachineInstr *MI) {
- LLVM_DEBUG(dbgs() << "ARM Loops: Resetting VPT Predicate: " << *MI);
- CurrentPredicates.clear();
- CurrentPredicates.insert(MI);
- }
-
- public:
+ public:
// Have we found an instruction within the block which defines the vpr? If
// so, not all the instructions in the block will have the same predicate.
- static bool hasUniformPredicate(VPTState &Block) {
- return getDivergent(Block) == nullptr;
+ static bool hasUniformPredicate(VPTState &Block) {
+ return getDivergent(Block) == nullptr;
}
- // If it exists, return the first internal instruction which modifies the
- // VPR.
- static MachineInstr *getDivergent(VPTState &Block) {
- SmallVectorImpl<MachineInstr *> &Insts = Block.getInsts();
- for (unsigned i = 1; i < Insts.size(); ++i) {
- MachineInstr *Next = Insts[i];
- if (isVectorPredicate(Next))
- return Next; // Found an instruction altering the vpr.
- }
- return nullptr;
+ // If it exists, return the first internal instruction which modifies the
+ // VPR.
+ static MachineInstr *getDivergent(VPTState &Block) {
+ SmallVectorImpl<MachineInstr *> &Insts = Block.getInsts();
+ for (unsigned i = 1; i < Insts.size(); ++i) {
+ MachineInstr *Next = Insts[i];
+ if (isVectorPredicate(Next))
+ return Next; // Found an instruction altering the vpr.
+ }
+ return nullptr;
+ }
+
+ // Return whether the given instruction is predicated upon a VCTP.
+ static bool isPredicatedOnVCTP(MachineInstr *MI, bool Exclusive = false) {
+ SetVector<MachineInstr *> &Predicates = PredicatedInsts[MI]->Predicates;
+ if (Exclusive && Predicates.size() != 1)
+ return false;
+ for (auto *PredMI : Predicates)
+ if (isVCTP(PredMI))
+ return true;
+ return false;
+ }
+
+ // Is the VPST, controlling the block entry, predicated upon a VCTP.
+ static bool isEntryPredicatedOnVCTP(VPTState &Block,
+ bool Exclusive = false) {
+ SmallVectorImpl<MachineInstr *> &Insts = Block.getInsts();
+ return isPredicatedOnVCTP(Insts.front(), Exclusive);
+ }
+
+ // If this block begins with a VPT, we can check whether it's using
+ // at least one predicated input(s), as well as possible loop invariant
+ // which would result in it being implicitly predicated.
+ static bool hasImplicitlyValidVPT(VPTState &Block,
+ ReachingDefAnalysis &RDA) {
+ SmallVectorImpl<MachineInstr *> &Insts = Block.getInsts();
+ MachineInstr *VPT = Insts.front();
+ assert(isVPTOpcode(VPT->getOpcode()) &&
+ "Expected VPT block to begin with VPT/VPST");
+
+ if (VPT->getOpcode() == ARM::MVE_VPST)
+ return false;
+
+ auto IsOperandPredicated = [&](MachineInstr *MI, unsigned Idx) {
+ MachineInstr *Op = RDA.getMIOperand(MI, MI->getOperand(Idx));
+ return Op && PredicatedInsts.count(Op) && isPredicatedOnVCTP(Op);
+ };
+
+ auto IsOperandInvariant = [&](MachineInstr *MI, unsigned Idx) {
+ MachineOperand &MO = MI->getOperand(Idx);
+ if (!MO.isReg() || !MO.getReg())
+ return true;
+
+ SmallPtrSet<MachineInstr *, 2> Defs;
+ RDA.getGlobalReachingDefs(MI, MO.getReg(), Defs);
+ if (Defs.empty())
+ return true;
+
+ for (auto *Def : Defs)
+ if (Def->getParent() == VPT->getParent())
+ return false;
+ return true;
+ };
+
+ // Check that at least one of the operands is directly predicated on a
+ // vctp and allow an invariant value too.
+ return (IsOperandPredicated(VPT, 1) || IsOperandPredicated(VPT, 2)) &&
+ (IsOperandPredicated(VPT, 1) || IsOperandInvariant(VPT, 1)) &&
+ (IsOperandPredicated(VPT, 2) || IsOperandInvariant(VPT, 2));
+ }
+
+ static bool isValid(ReachingDefAnalysis &RDA) {
+ // All predication within the loop should be based on vctp. If the block
+ // isn't predicated on entry, check whether the vctp is within the block
+ // and that all other instructions are then predicated on it.
+ for (auto &Block : Blocks) {
+ if (isEntryPredicatedOnVCTP(Block, false) ||
+ hasImplicitlyValidVPT(Block, RDA))
+ continue;
+
+ SmallVectorImpl<MachineInstr *> &Insts = Block.getInsts();
+ // We don't know how to convert a block with just a VPT;VCTP into
+ // anything valid once we remove the VCTP. For now just bail out.
+ assert(isVPTOpcode(Insts.front()->getOpcode()) &&
+ "Expected VPT block to start with a VPST or VPT!");
+ if (Insts.size() == 2 && Insts.front()->getOpcode() != ARM::MVE_VPST &&
+ isVCTP(Insts.back()))
+ return false;
+
+ for (auto *MI : Insts) {
+ // Check that any internal VCTPs are 'Then' predicated.
+ if (isVCTP(MI) && getVPTInstrPredicate(*MI) != ARMVCC::Then)
+ return false;
+ // Skip other instructions that build up the predicate.
+ if (MI->getOpcode() == ARM::MVE_VPST || isVectorPredicate(MI))
+ continue;
+ // Check that any other instructions are predicated upon a vctp.
+ // TODO: We could infer when VPTs are implicitly predicated on the
+ // vctp (when the operands are predicated).
+ if (!isPredicatedOnVCTP(MI)) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: Can't convert: " << *MI);
+ return false;
+ }
+ }
+ }
+ return true;
}
- // Return whether the given instruction is predicated upon a VCTP.
- static bool isPredicatedOnVCTP(MachineInstr *MI, bool Exclusive = false) {
- SetVector<MachineInstr *> &Predicates = PredicatedInsts[MI]->Predicates;
- if (Exclusive && Predicates.size() != 1)
- return false;
- for (auto *PredMI : Predicates)
- if (isVCTP(PredMI))
- return true;
- return false;
- }
-
- // Is the VPST, controlling the block entry, predicated upon a VCTP.
- static bool isEntryPredicatedOnVCTP(VPTState &Block,
- bool Exclusive = false) {
- SmallVectorImpl<MachineInstr *> &Insts = Block.getInsts();
- return isPredicatedOnVCTP(Insts.front(), Exclusive);
+ VPTState(MachineInstr *MI) { Insts.push_back(MI); }
+
+ void insert(MachineInstr *MI) {
+ Insts.push_back(MI);
+ // VPT/VPST + 4 predicated instructions.
+ assert(Insts.size() <= 5 && "Too many instructions in VPT block!");
}
- // If this block begins with a VPT, we can check whether it's using
- // at least one predicated input(s), as well as possible loop invariant
- // which would result in it being implicitly predicated.
- static bool hasImplicitlyValidVPT(VPTState &Block,
- ReachingDefAnalysis &RDA) {
- SmallVectorImpl<MachineInstr *> &Insts = Block.getInsts();
- MachineInstr *VPT = Insts.front();
- assert(isVPTOpcode(VPT->getOpcode()) &&
- "Expected VPT block to begin with VPT/VPST");
-
- if (VPT->getOpcode() == ARM::MVE_VPST)
- return false;
-
- auto IsOperandPredicated = [&](MachineInstr *MI, unsigned Idx) {
- MachineInstr *Op = RDA.getMIOperand(MI, MI->getOperand(Idx));
- return Op && PredicatedInsts.count(Op) && isPredicatedOnVCTP(Op);
- };
-
- auto IsOperandInvariant = [&](MachineInstr *MI, unsigned Idx) {
- MachineOperand &MO = MI->getOperand(Idx);
- if (!MO.isReg() || !MO.getReg())
- return true;
-
- SmallPtrSet<MachineInstr *, 2> Defs;
- RDA.getGlobalReachingDefs(MI, MO.getReg(), Defs);
- if (Defs.empty())
- return true;
-
- for (auto *Def : Defs)
- if (Def->getParent() == VPT->getParent())
- return false;
- return true;
- };
-
- // Check that at least one of the operands is directly predicated on a
- // vctp and allow an invariant value too.
- return (IsOperandPredicated(VPT, 1) || IsOperandPredicated(VPT, 2)) &&
- (IsOperandPredicated(VPT, 1) || IsOperandInvariant(VPT, 1)) &&
- (IsOperandPredicated(VPT, 2) || IsOperandInvariant(VPT, 2));
+ bool containsVCTP() const {
+ for (auto *MI : Insts)
+ if (isVCTP(MI))
+ return true;
+ return false;
}
- static bool isValid(ReachingDefAnalysis &RDA) {
- // All predication within the loop should be based on vctp. If the block
- // isn't predicated on entry, check whether the vctp is within the block
- // and that all other instructions are then predicated on it.
- for (auto &Block : Blocks) {
- if (isEntryPredicatedOnVCTP(Block, false) ||
- hasImplicitlyValidVPT(Block, RDA))
- continue;
-
- SmallVectorImpl<MachineInstr *> &Insts = Block.getInsts();
- // We don't know how to convert a block with just a VPT;VCTP into
- // anything valid once we remove the VCTP. For now just bail out.
- assert(isVPTOpcode(Insts.front()->getOpcode()) &&
- "Expected VPT block to start with a VPST or VPT!");
- if (Insts.size() == 2 && Insts.front()->getOpcode() != ARM::MVE_VPST &&
- isVCTP(Insts.back()))
- return false;
-
- for (auto *MI : Insts) {
- // Check that any internal VCTPs are 'Then' predicated.
- if (isVCTP(MI) && getVPTInstrPredicate(*MI) != ARMVCC::Then)
- return false;
- // Skip other instructions that build up the predicate.
- if (MI->getOpcode() == ARM::MVE_VPST || isVectorPredicate(MI))
- continue;
- // Check that any other instructions are predicated upon a vctp.
- // TODO: We could infer when VPTs are implicitly predicated on the
- // vctp (when the operands are predicated).
- if (!isPredicatedOnVCTP(MI)) {
- LLVM_DEBUG(dbgs() << "ARM Loops: Can't convert: " << *MI);
- return false;
- }
- }
- }
- return true;
- }
-
- VPTState(MachineInstr *MI) { Insts.push_back(MI); }
-
- void insert(MachineInstr *MI) {
- Insts.push_back(MI);
- // VPT/VPST + 4 predicated instructions.
- assert(Insts.size() <= 5 && "Too many instructions in VPT block!");
- }
-
- bool containsVCTP() const {
- for (auto *MI : Insts)
- if (isVCTP(MI))
- return true;
- return false;
- }
-
- unsigned size() const { return Insts.size(); }
- SmallVectorImpl<MachineInstr *> &getInsts() { return Insts; }
+ unsigned size() const { return Insts.size(); }
+ SmallVectorImpl<MachineInstr *> &getInsts() { return Insts; }
};
struct LowOverheadLoop {
@@ -366,13 +366,13 @@ namespace {
const TargetRegisterInfo &TRI;
const ARMBaseInstrInfo &TII;
MachineFunction *MF = nullptr;
- MachineBasicBlock::iterator StartInsertPt;
- MachineBasicBlock *StartInsertBB = nullptr;
+ MachineBasicBlock::iterator StartInsertPt;
+ MachineBasicBlock *StartInsertBB = nullptr;
MachineInstr *Start = nullptr;
MachineInstr *Dec = nullptr;
MachineInstr *End = nullptr;
- MachineOperand TPNumElements;
- SmallVector<MachineInstr*, 4> VCTPs;
+ MachineOperand TPNumElements;
+ SmallVector<MachineInstr*, 4> VCTPs;
SmallPtrSet<MachineInstr*, 4> ToRemove;
SmallPtrSet<MachineInstr*, 4> BlockMasksToRecompute;
bool Revert = false;
@@ -381,14 +381,14 @@ namespace {
LowOverheadLoop(MachineLoop &ML, MachineLoopInfo &MLI,
ReachingDefAnalysis &RDA, const TargetRegisterInfo &TRI,
const ARMBaseInstrInfo &TII)
- : ML(ML), MLI(MLI), RDA(RDA), TRI(TRI), TII(TII),
- TPNumElements(MachineOperand::CreateImm(0)) {
+ : ML(ML), MLI(MLI), RDA(RDA), TRI(TRI), TII(TII),
+ TPNumElements(MachineOperand::CreateImm(0)) {
MF = ML.getHeader()->getParent();
if (auto *MBB = ML.getLoopPreheader())
Preheader = MBB;
else if (auto *MBB = MLI.findLoopPreheader(&ML, true))
Preheader = MBB;
- VPTState::reset();
+ VPTState::reset();
}
// If this is an MVE instruction, check that we know how to use tail
@@ -403,18 +403,18 @@ namespace {
bool IsTailPredicationLegal() const {
// For now, let's keep things really simple and only support a single
// block for tail predication.
- return !Revert && FoundAllComponents() && !VCTPs.empty() &&
+ return !Revert && FoundAllComponents() && !VCTPs.empty() &&
!CannotTailPredicate && ML.getNumBlocks() == 1;
}
- // Given that MI is a VCTP, check that is equivalent to any other VCTPs
- // found.
- bool AddVCTP(MachineInstr *MI);
-
+ // Given that MI is a VCTP, check that is equivalent to any other VCTPs
+ // found.
+ bool AddVCTP(MachineInstr *MI);
+
// Check that the predication in the loop will be equivalent once we
// perform the conversion. Also ensure that we can provide the number
// of elements to the loop start instruction.
- bool ValidateTailPredicate();
+ bool ValidateTailPredicate();
// Check that any values available outside of the loop will be the same
// after tail predication conversion.
@@ -427,41 +427,41 @@ namespace {
// Check the branch targets are within range and we satisfy our
// restrictions.
- void Validate(ARMBasicBlockUtils *BBUtils);
+ void Validate(ARMBasicBlockUtils *BBUtils);
bool FoundAllComponents() const {
return Start && Dec && End;
}
- SmallVectorImpl<VPTState> &getVPTBlocks() {
- return VPTState::Blocks;
- }
+ SmallVectorImpl<VPTState> &getVPTBlocks() {
+ return VPTState::Blocks;
+ }
- // Return the operand for the loop start instruction. This will be the loop
- // iteration count, or the number of elements if we're tail predicating.
- MachineOperand &getLoopStartOperand() {
- if (IsTailPredicationLegal())
- return TPNumElements;
- return isDo(Start) ? Start->getOperand(1) : Start->getOperand(0);
+ // Return the operand for the loop start instruction. This will be the loop
+ // iteration count, or the number of elements if we're tail predicating.
+ MachineOperand &getLoopStartOperand() {
+ if (IsTailPredicationLegal())
+ return TPNumElements;
+ return isDo(Start) ? Start->getOperand(1) : Start->getOperand(0);
}
unsigned getStartOpcode() const {
- bool IsDo = isDo(Start);
+ bool IsDo = isDo(Start);
if (!IsTailPredicationLegal())
return IsDo ? ARM::t2DLS : ARM::t2WLS;
- return VCTPOpcodeToLSTP(VCTPs.back()->getOpcode(), IsDo);
+ return VCTPOpcodeToLSTP(VCTPs.back()->getOpcode(), IsDo);
}
void dump() const {
if (Start) dbgs() << "ARM Loops: Found Loop Start: " << *Start;
if (Dec) dbgs() << "ARM Loops: Found Loop Dec: " << *Dec;
if (End) dbgs() << "ARM Loops: Found Loop End: " << *End;
- if (!VCTPs.empty()) {
- dbgs() << "ARM Loops: Found VCTP(s):\n";
- for (auto *MI : VCTPs)
- dbgs() << " - " << *MI;
- }
+ if (!VCTPs.empty()) {
+ dbgs() << "ARM Loops: Found VCTP(s):\n";
+ for (auto *MI : VCTPs)
+ dbgs() << " - " << *MI;
+ }
if (!FoundAllComponents())
dbgs() << "ARM Loops: Not a low-overhead loop.\n";
else if (!(Start && Dec && End))
@@ -508,14 +508,14 @@ namespace {
bool RevertNonLoops();
void RevertWhile(MachineInstr *MI) const;
- void RevertDo(MachineInstr *MI) const;
+ void RevertDo(MachineInstr *MI) const;
bool RevertLoopDec(MachineInstr *MI) const;
void RevertLoopEnd(MachineInstr *MI, bool SkipCmp = false) const;
- void RevertLoopEndDec(MachineInstr *MI) const;
-
+ void RevertLoopEndDec(MachineInstr *MI) const;
+
void ConvertVPTBlocks(LowOverheadLoop &LoLoop);
MachineInstr *ExpandLoopStart(LowOverheadLoop &LoLoop);
@@ -528,230 +528,230 @@ namespace {
char ARMLowOverheadLoops::ID = 0;
-SmallVector<VPTState, 4> VPTState::Blocks;
-SetVector<MachineInstr *> VPTState::CurrentPredicates;
-std::map<MachineInstr *,
- std::unique_ptr<PredicatedMI>> VPTState::PredicatedInsts;
-
+SmallVector<VPTState, 4> VPTState::Blocks;
+SetVector<MachineInstr *> VPTState::CurrentPredicates;
+std::map<MachineInstr *,
+ std::unique_ptr<PredicatedMI>> VPTState::PredicatedInsts;
+
INITIALIZE_PASS(ARMLowOverheadLoops, DEBUG_TYPE, ARM_LOW_OVERHEAD_LOOPS_NAME,
false, false)
-static bool TryRemove(MachineInstr *MI, ReachingDefAnalysis &RDA,
- InstSet &ToRemove, InstSet &Ignore) {
-
- // Check that we can remove all of Killed without having to modify any IT
- // blocks.
- auto WontCorruptITs = [](InstSet &Killed, ReachingDefAnalysis &RDA) {
- // Collect the dead code and the MBBs in which they reside.
- SmallPtrSet<MachineBasicBlock*, 2> BasicBlocks;
- for (auto *Dead : Killed)
- BasicBlocks.insert(Dead->getParent());
-
- // Collect IT blocks in all affected basic blocks.
- std::map<MachineInstr *, SmallPtrSet<MachineInstr *, 2>> ITBlocks;
- for (auto *MBB : BasicBlocks) {
- for (auto &IT : *MBB) {
- if (IT.getOpcode() != ARM::t2IT)
- continue;
- RDA.getReachingLocalUses(&IT, MCRegister::from(ARM::ITSTATE),
- ITBlocks[&IT]);
- }
- }
-
- // If we're removing all of the instructions within an IT block, then
- // also remove the IT instruction.
- SmallPtrSet<MachineInstr *, 2> ModifiedITs;
- SmallPtrSet<MachineInstr *, 2> RemoveITs;
- for (auto *Dead : Killed) {
- if (MachineOperand *MO = Dead->findRegisterUseOperand(ARM::ITSTATE)) {
- MachineInstr *IT = RDA.getMIOperand(Dead, *MO);
- RemoveITs.insert(IT);
- auto &CurrentBlock = ITBlocks[IT];
- CurrentBlock.erase(Dead);
- if (CurrentBlock.empty())
- ModifiedITs.erase(IT);
- else
- ModifiedITs.insert(IT);
- }
- }
- if (!ModifiedITs.empty())
- return false;
- Killed.insert(RemoveITs.begin(), RemoveITs.end());
- return true;
- };
-
- SmallPtrSet<MachineInstr *, 2> Uses;
- if (!RDA.isSafeToRemove(MI, Uses, Ignore))
- return false;
-
- if (WontCorruptITs(Uses, RDA)) {
- ToRemove.insert(Uses.begin(), Uses.end());
- LLVM_DEBUG(dbgs() << "ARM Loops: Able to remove: " << *MI
- << " - can also remove:\n";
- for (auto *Use : Uses)
- dbgs() << " - " << *Use);
-
- SmallPtrSet<MachineInstr*, 4> Killed;
- RDA.collectKilledOperands(MI, Killed);
- if (WontCorruptITs(Killed, RDA)) {
- ToRemove.insert(Killed.begin(), Killed.end());
- LLVM_DEBUG(for (auto *Dead : Killed)
- dbgs() << " - " << *Dead);
+static bool TryRemove(MachineInstr *MI, ReachingDefAnalysis &RDA,
+ InstSet &ToRemove, InstSet &Ignore) {
+
+ // Check that we can remove all of Killed without having to modify any IT
+ // blocks.
+ auto WontCorruptITs = [](InstSet &Killed, ReachingDefAnalysis &RDA) {
+ // Collect the dead code and the MBBs in which they reside.
+ SmallPtrSet<MachineBasicBlock*, 2> BasicBlocks;
+ for (auto *Dead : Killed)
+ BasicBlocks.insert(Dead->getParent());
+
+ // Collect IT blocks in all affected basic blocks.
+ std::map<MachineInstr *, SmallPtrSet<MachineInstr *, 2>> ITBlocks;
+ for (auto *MBB : BasicBlocks) {
+ for (auto &IT : *MBB) {
+ if (IT.getOpcode() != ARM::t2IT)
+ continue;
+ RDA.getReachingLocalUses(&IT, MCRegister::from(ARM::ITSTATE),
+ ITBlocks[&IT]);
+ }
+ }
+
+ // If we're removing all of the instructions within an IT block, then
+ // also remove the IT instruction.
+ SmallPtrSet<MachineInstr *, 2> ModifiedITs;
+ SmallPtrSet<MachineInstr *, 2> RemoveITs;
+ for (auto *Dead : Killed) {
+ if (MachineOperand *MO = Dead->findRegisterUseOperand(ARM::ITSTATE)) {
+ MachineInstr *IT = RDA.getMIOperand(Dead, *MO);
+ RemoveITs.insert(IT);
+ auto &CurrentBlock = ITBlocks[IT];
+ CurrentBlock.erase(Dead);
+ if (CurrentBlock.empty())
+ ModifiedITs.erase(IT);
+ else
+ ModifiedITs.insert(IT);
+ }
}
- return true;
+ if (!ModifiedITs.empty())
+ return false;
+ Killed.insert(RemoveITs.begin(), RemoveITs.end());
+ return true;
+ };
+
+ SmallPtrSet<MachineInstr *, 2> Uses;
+ if (!RDA.isSafeToRemove(MI, Uses, Ignore))
+ return false;
+
+ if (WontCorruptITs(Uses, RDA)) {
+ ToRemove.insert(Uses.begin(), Uses.end());
+ LLVM_DEBUG(dbgs() << "ARM Loops: Able to remove: " << *MI
+ << " - can also remove:\n";
+ for (auto *Use : Uses)
+ dbgs() << " - " << *Use);
+
+ SmallPtrSet<MachineInstr*, 4> Killed;
+ RDA.collectKilledOperands(MI, Killed);
+ if (WontCorruptITs(Killed, RDA)) {
+ ToRemove.insert(Killed.begin(), Killed.end());
+ LLVM_DEBUG(for (auto *Dead : Killed)
+ dbgs() << " - " << *Dead);
+ }
+ return true;
+ }
+ return false;
+}
+
+bool LowOverheadLoop::ValidateTailPredicate() {
+ if (!IsTailPredicationLegal()) {
+ LLVM_DEBUG(if (VCTPs.empty())
+ dbgs() << "ARM Loops: Didn't find a VCTP instruction.\n";
+ dbgs() << "ARM Loops: Tail-predication is not valid.\n");
+ return false;
}
- return false;
-}
-
-bool LowOverheadLoop::ValidateTailPredicate() {
- if (!IsTailPredicationLegal()) {
- LLVM_DEBUG(if (VCTPs.empty())
- dbgs() << "ARM Loops: Didn't find a VCTP instruction.\n";
- dbgs() << "ARM Loops: Tail-predication is not valid.\n");
+
+ assert(!VCTPs.empty() && "VCTP instruction expected but is not set");
+ assert(ML.getBlocks().size() == 1 &&
+ "Shouldn't be processing a loop with more than one block");
+
+ if (DisableTailPredication) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: tail-predication is disabled\n");
return false;
- }
+ }
- assert(!VCTPs.empty() && "VCTP instruction expected but is not set");
- assert(ML.getBlocks().size() == 1 &&
- "Shouldn't be processing a loop with more than one block");
+ if (!VPTState::isValid(RDA)) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: Invalid VPT state.\n");
+ return false;
+ }
- if (DisableTailPredication) {
- LLVM_DEBUG(dbgs() << "ARM Loops: tail-predication is disabled\n");
+ if (!ValidateLiveOuts()) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: Invalid live outs.\n");
return false;
}
- if (!VPTState::isValid(RDA)) {
- LLVM_DEBUG(dbgs() << "ARM Loops: Invalid VPT state.\n");
- return false;
- }
-
- if (!ValidateLiveOuts()) {
- LLVM_DEBUG(dbgs() << "ARM Loops: Invalid live outs.\n");
- return false;
- }
-
- // Check that creating a [W|D]LSTP, which will define LR with an element
- // count instead of iteration count, won't affect any other instructions
- // than the LoopStart and LoopDec.
- // TODO: We should try to insert the [W|D]LSTP after any of the other uses.
- Register StartReg = isDo(Start) ? Start->getOperand(1).getReg()
- : Start->getOperand(0).getReg();
- if (StartInsertPt == Start && StartReg == ARM::LR) {
- if (auto *IterCount = RDA.getMIOperand(Start, isDo(Start) ? 1 : 0)) {
- SmallPtrSet<MachineInstr *, 2> Uses;
- RDA.getGlobalUses(IterCount, MCRegister::from(ARM::LR), Uses);
- for (auto *Use : Uses) {
- if (Use != Start && Use != Dec) {
- LLVM_DEBUG(dbgs() << " ARM Loops: Found LR use: " << *Use);
- return false;
- }
+ // Check that creating a [W|D]LSTP, which will define LR with an element
+ // count instead of iteration count, won't affect any other instructions
+ // than the LoopStart and LoopDec.
+ // TODO: We should try to insert the [W|D]LSTP after any of the other uses.
+ Register StartReg = isDo(Start) ? Start->getOperand(1).getReg()
+ : Start->getOperand(0).getReg();
+ if (StartInsertPt == Start && StartReg == ARM::LR) {
+ if (auto *IterCount = RDA.getMIOperand(Start, isDo(Start) ? 1 : 0)) {
+ SmallPtrSet<MachineInstr *, 2> Uses;
+ RDA.getGlobalUses(IterCount, MCRegister::from(ARM::LR), Uses);
+ for (auto *Use : Uses) {
+ if (Use != Start && Use != Dec) {
+ LLVM_DEBUG(dbgs() << " ARM Loops: Found LR use: " << *Use);
+ return false;
+ }
}
}
}
- // For tail predication, we need to provide the number of elements, instead
- // of the iteration count, to the loop start instruction. The number of
- // elements is provided to the vctp instruction, so we need to check that
- // we can use this register at InsertPt.
- MachineInstr *VCTP = VCTPs.back();
- if (Start->getOpcode() == ARM::t2DoLoopStartTP) {
- TPNumElements = Start->getOperand(2);
- StartInsertPt = Start;
- StartInsertBB = Start->getParent();
- } else {
- TPNumElements = VCTP->getOperand(1);
- MCRegister NumElements = TPNumElements.getReg().asMCReg();
-
- // If the register is defined within loop, then we can't perform TP.
- // TODO: Check whether this is just a mov of a register that would be
- // available.
- if (RDA.hasLocalDefBefore(VCTP, NumElements)) {
- LLVM_DEBUG(dbgs() << "ARM Loops: VCTP operand is defined in the loop.\n");
- return false;
- }
-
- // The element count register maybe defined after InsertPt, in which case we
- // need to try to move either InsertPt or the def so that the [w|d]lstp can
- // use the value.
-
- if (StartInsertPt != StartInsertBB->end() &&
- !RDA.isReachingDefLiveOut(&*StartInsertPt, NumElements)) {
- if (auto *ElemDef =
- RDA.getLocalLiveOutMIDef(StartInsertBB, NumElements)) {
- if (RDA.isSafeToMoveForwards(ElemDef, &*StartInsertPt)) {
- ElemDef->removeFromParent();
- StartInsertBB->insert(StartInsertPt, ElemDef);
- LLVM_DEBUG(dbgs()
- << "ARM Loops: Moved element count def: " << *ElemDef);
- } else if (RDA.isSafeToMoveBackwards(&*StartInsertPt, ElemDef)) {
- StartInsertPt->removeFromParent();
- StartInsertBB->insertAfter(MachineBasicBlock::iterator(ElemDef),
- &*StartInsertPt);
- LLVM_DEBUG(dbgs() << "ARM Loops: Moved start past: " << *ElemDef);
- } else {
- // If we fail to move an instruction and the element count is provided
- // by a mov, use the mov operand if it will have the same value at the
- // insertion point
- MachineOperand Operand = ElemDef->getOperand(1);
- if (isMovRegOpcode(ElemDef->getOpcode()) &&
- RDA.getUniqueReachingMIDef(ElemDef, Operand.getReg().asMCReg()) ==
- RDA.getUniqueReachingMIDef(&*StartInsertPt,
- Operand.getReg().asMCReg())) {
- TPNumElements = Operand;
- NumElements = TPNumElements.getReg();
- } else {
- LLVM_DEBUG(dbgs()
- << "ARM Loops: Unable to move element count to loop "
- << "start instruction.\n");
- return false;
- }
- }
- }
- }
-
- // Especially in the case of while loops, InsertBB may not be the
- // preheader, so we need to check that the register isn't redefined
- // before entering the loop.
- auto CannotProvideElements = [this](MachineBasicBlock *MBB,
- MCRegister NumElements) {
- if (MBB->empty())
- return false;
- // NumElements is redefined in this block.
- if (RDA.hasLocalDefBefore(&MBB->back(), NumElements))
- return true;
-
- // Don't continue searching up through multiple predecessors.
- if (MBB->pred_size() > 1)
- return true;
-
+ // For tail predication, we need to provide the number of elements, instead
+ // of the iteration count, to the loop start instruction. The number of
+ // elements is provided to the vctp instruction, so we need to check that
+ // we can use this register at InsertPt.
+ MachineInstr *VCTP = VCTPs.back();
+ if (Start->getOpcode() == ARM::t2DoLoopStartTP) {
+ TPNumElements = Start->getOperand(2);
+ StartInsertPt = Start;
+ StartInsertBB = Start->getParent();
+ } else {
+ TPNumElements = VCTP->getOperand(1);
+ MCRegister NumElements = TPNumElements.getReg().asMCReg();
+
+ // If the register is defined within loop, then we can't perform TP.
+ // TODO: Check whether this is just a mov of a register that would be
+ // available.
+ if (RDA.hasLocalDefBefore(VCTP, NumElements)) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: VCTP operand is defined in the loop.\n");
return false;
- };
-
- // Search backwards for a def, until we get to InsertBB.
- MachineBasicBlock *MBB = Preheader;
- while (MBB && MBB != StartInsertBB) {
- if (CannotProvideElements(MBB, NumElements)) {
- LLVM_DEBUG(dbgs() << "ARM Loops: Unable to provide element count.\n");
- return false;
- }
- MBB = *MBB->pred_begin();
}
+
+ // The element count register maybe defined after InsertPt, in which case we
+ // need to try to move either InsertPt or the def so that the [w|d]lstp can
+ // use the value.
+
+ if (StartInsertPt != StartInsertBB->end() &&
+ !RDA.isReachingDefLiveOut(&*StartInsertPt, NumElements)) {
+ if (auto *ElemDef =
+ RDA.getLocalLiveOutMIDef(StartInsertBB, NumElements)) {
+ if (RDA.isSafeToMoveForwards(ElemDef, &*StartInsertPt)) {
+ ElemDef->removeFromParent();
+ StartInsertBB->insert(StartInsertPt, ElemDef);
+ LLVM_DEBUG(dbgs()
+ << "ARM Loops: Moved element count def: " << *ElemDef);
+ } else if (RDA.isSafeToMoveBackwards(&*StartInsertPt, ElemDef)) {
+ StartInsertPt->removeFromParent();
+ StartInsertBB->insertAfter(MachineBasicBlock::iterator(ElemDef),
+ &*StartInsertPt);
+ LLVM_DEBUG(dbgs() << "ARM Loops: Moved start past: " << *ElemDef);
+ } else {
+ // If we fail to move an instruction and the element count is provided
+ // by a mov, use the mov operand if it will have the same value at the
+ // insertion point
+ MachineOperand Operand = ElemDef->getOperand(1);
+ if (isMovRegOpcode(ElemDef->getOpcode()) &&
+ RDA.getUniqueReachingMIDef(ElemDef, Operand.getReg().asMCReg()) ==
+ RDA.getUniqueReachingMIDef(&*StartInsertPt,
+ Operand.getReg().asMCReg())) {
+ TPNumElements = Operand;
+ NumElements = TPNumElements.getReg();
+ } else {
+ LLVM_DEBUG(dbgs()
+ << "ARM Loops: Unable to move element count to loop "
+ << "start instruction.\n");
+ return false;
+ }
+ }
+ }
+ }
+
+ // Especially in the case of while loops, InsertBB may not be the
+ // preheader, so we need to check that the register isn't redefined
+ // before entering the loop.
+ auto CannotProvideElements = [this](MachineBasicBlock *MBB,
+ MCRegister NumElements) {
+ if (MBB->empty())
+ return false;
+ // NumElements is redefined in this block.
+ if (RDA.hasLocalDefBefore(&MBB->back(), NumElements))
+ return true;
+
+ // Don't continue searching up through multiple predecessors.
+ if (MBB->pred_size() > 1)
+ return true;
+
+ return false;
+ };
+
+ // Search backwards for a def, until we get to InsertBB.
+ MachineBasicBlock *MBB = Preheader;
+ while (MBB && MBB != StartInsertBB) {
+ if (CannotProvideElements(MBB, NumElements)) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: Unable to provide element count.\n");
+ return false;
+ }
+ MBB = *MBB->pred_begin();
+ }
+ }
+
+ // Could inserting the [W|D]LSTP cause some unintended affects? In a perfect
+ // world the [w|d]lstp instruction would be last instruction in the preheader
+ // and so it would only affect instructions within the loop body. But due to
+ // scheduling, and/or the logic in this pass (above), the insertion point can
+ // be moved earlier. So if the Loop Start isn't the last instruction in the
+ // preheader, and if the initial element count is smaller than the vector
+ // width, the Loop Start instruction will immediately generate one or more
+ // false lane mask which can, incorrectly, affect the proceeding MVE
+ // instructions in the preheader.
+ if (std::any_of(StartInsertPt, StartInsertBB->end(), shouldInspect)) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: Instruction blocks [W|D]LSTP\n");
+ return false;
}
- // Could inserting the [W|D]LSTP cause some unintended affects? In a perfect
- // world the [w|d]lstp instruction would be last instruction in the preheader
- // and so it would only affect instructions within the loop body. But due to
- // scheduling, and/or the logic in this pass (above), the insertion point can
- // be moved earlier. So if the Loop Start isn't the last instruction in the
- // preheader, and if the initial element count is smaller than the vector
- // width, the Loop Start instruction will immediately generate one or more
- // false lane mask which can, incorrectly, affect the proceeding MVE
- // instructions in the preheader.
- if (std::any_of(StartInsertPt, StartInsertBB->end(), shouldInspect)) {
- LLVM_DEBUG(dbgs() << "ARM Loops: Instruction blocks [W|D]LSTP\n");
- return false;
- }
-
// Check that the value change of the element count is what we expect and
// that the predication will be equivalent. For this we need:
// NumElements = NumElements - VectorWidth. The sub will be a sub immediate
@@ -760,20 +760,20 @@ bool LowOverheadLoop::ValidateTailPredicate() {
return -getAddSubImmediate(*MI) == ExpectedVecWidth;
};
- MachineBasicBlock *MBB = VCTP->getParent();
- // Remove modifications to the element count since they have no purpose in a
- // tail predicated loop. Explicitly refer to the vctp operand no matter which
- // register NumElements has been assigned to, since that is what the
- // modifications will be using
- if (auto *Def = RDA.getUniqueReachingMIDef(
- &MBB->back(), VCTP->getOperand(1).getReg().asMCReg())) {
+ MachineBasicBlock *MBB = VCTP->getParent();
+ // Remove modifications to the element count since they have no purpose in a
+ // tail predicated loop. Explicitly refer to the vctp operand no matter which
+ // register NumElements has been assigned to, since that is what the
+ // modifications will be using
+ if (auto *Def = RDA.getUniqueReachingMIDef(
+ &MBB->back(), VCTP->getOperand(1).getReg().asMCReg())) {
SmallPtrSet<MachineInstr*, 2> ElementChain;
- SmallPtrSet<MachineInstr*, 2> Ignore;
+ SmallPtrSet<MachineInstr*, 2> Ignore;
unsigned ExpectedVectorWidth = getTailPredVectorWidth(VCTP->getOpcode());
- Ignore.insert(VCTPs.begin(), VCTPs.end());
+ Ignore.insert(VCTPs.begin(), VCTPs.end());
- if (TryRemove(Def, RDA, ElementChain, Ignore)) {
+ if (TryRemove(Def, RDA, ElementChain, Ignore)) {
bool FoundSub = false;
for (auto *MI : ElementChain) {
@@ -781,17 +781,17 @@ bool LowOverheadLoop::ValidateTailPredicate() {
continue;
if (isSubImmOpcode(MI->getOpcode())) {
- if (FoundSub || !IsValidSub(MI, ExpectedVectorWidth)) {
- LLVM_DEBUG(dbgs() << "ARM Loops: Unexpected instruction in element"
- " count: " << *MI);
+ if (FoundSub || !IsValidSub(MI, ExpectedVectorWidth)) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: Unexpected instruction in element"
+ " count: " << *MI);
return false;
- }
+ }
FoundSub = true;
- } else {
- LLVM_DEBUG(dbgs() << "ARM Loops: Unexpected instruction in element"
- " count: " << *MI);
+ } else {
+ LLVM_DEBUG(dbgs() << "ARM Loops: Unexpected instruction in element"
+ " count: " << *MI);
return false;
- }
+ }
}
ToRemove.insert(ElementChain.begin(), ElementChain.end());
}
@@ -868,18 +868,18 @@ static bool producesFalseLanesZero(MachineInstr &MI,
if (canGenerateNonZeros(MI))
return false;
- bool isPredicated = isVectorPredicated(&MI);
- // Predicated loads will write zeros to the falsely predicated bytes of the
- // destination register.
- if (MI.mayLoad())
- return isPredicated;
-
- auto IsZeroInit = [](MachineInstr *Def) {
- return !isVectorPredicated(Def) &&
- Def->getOpcode() == ARM::MVE_VMOVimmi32 &&
- Def->getOperand(1).getImm() == 0;
- };
-
+ bool isPredicated = isVectorPredicated(&MI);
+ // Predicated loads will write zeros to the falsely predicated bytes of the
+ // destination register.
+ if (MI.mayLoad())
+ return isPredicated;
+
+ auto IsZeroInit = [](MachineInstr *Def) {
+ return !isVectorPredicated(Def) &&
+ Def->getOpcode() == ARM::MVE_VMOVimmi32 &&
+ Def->getOperand(1).getImm() == 0;
+ };
+
bool AllowScalars = isHorizontalReduction(MI);
for (auto &MO : MI.operands()) {
if (!MO.isReg() || !MO.getReg())
@@ -887,21 +887,21 @@ static bool producesFalseLanesZero(MachineInstr &MI,
if (!isRegInClass(MO, QPRs) && AllowScalars)
continue;
- // Check that this instruction will produce zeros in its false lanes:
- // - If it only consumes false lanes zero or constant 0 (vmov #0)
- // - If it's predicated, it only matters that it's def register already has
- // false lane zeros, so we can ignore the uses.
- SmallPtrSet<MachineInstr *, 2> Defs;
- RDA.getGlobalReachingDefs(&MI, MO.getReg(), Defs);
- for (auto *Def : Defs) {
- if (Def == &MI || FalseLanesZero.count(Def) || IsZeroInit(Def))
- continue;
- if (MO.isUse() && isPredicated)
- continue;
+ // Check that this instruction will produce zeros in its false lanes:
+ // - If it only consumes false lanes zero or constant 0 (vmov #0)
+ // - If it's predicated, it only matters that it's def register already has
+ // false lane zeros, so we can ignore the uses.
+ SmallPtrSet<MachineInstr *, 2> Defs;
+ RDA.getGlobalReachingDefs(&MI, MO.getReg(), Defs);
+ for (auto *Def : Defs) {
+ if (Def == &MI || FalseLanesZero.count(Def) || IsZeroInit(Def))
+ continue;
+ if (MO.isUse() && isPredicated)
+ continue;
return false;
- }
+ }
}
- LLVM_DEBUG(dbgs() << "ARM Loops: Always False Zeros: " << MI);
+ LLVM_DEBUG(dbgs() << "ARM Loops: Always False Zeros: " << MI);
return true;
}
@@ -921,7 +921,7 @@ bool LowOverheadLoop::ValidateLiveOuts() {
// the false lanes are zeroed and here we're trying to track that those false
// lanes remain zero, or where they change, the differences are masked away
// by their user(s).
- // All MVE stores have to be predicated, so we know that any predicate load
+ // All MVE stores have to be predicated, so we know that any predicate load
// operands, or stored results are equivalent already. Other explicitly
// predicated instructions will perform the same operation in the original
// loop and the tail-predicated form too. Because of this, we can insert
@@ -934,32 +934,32 @@ bool LowOverheadLoop::ValidateLiveOuts() {
MachineBasicBlock *Header = ML.getHeader();
for (auto &MI : *Header) {
- if (!shouldInspect(MI))
+ if (!shouldInspect(MI))
continue;
if (isVCTP(&MI) || isVPTOpcode(MI.getOpcode()))
continue;
- bool isPredicated = isVectorPredicated(&MI);
- bool retainsOrReduces =
- retainsPreviousHalfElement(MI) || isHorizontalReduction(MI);
-
- if (isPredicated)
+ bool isPredicated = isVectorPredicated(&MI);
+ bool retainsOrReduces =
+ retainsPreviousHalfElement(MI) || isHorizontalReduction(MI);
+
+ if (isPredicated)
Predicated.insert(&MI);
- if (producesFalseLanesZero(MI, QPRs, RDA, FalseLanesZero))
- FalseLanesZero.insert(&MI);
- else if (MI.getNumDefs() == 0)
+ if (producesFalseLanesZero(MI, QPRs, RDA, FalseLanesZero))
+ FalseLanesZero.insert(&MI);
+ else if (MI.getNumDefs() == 0)
continue;
- else if (!isPredicated && retainsOrReduces)
- return false;
- else if (!isPredicated)
+ else if (!isPredicated && retainsOrReduces)
+ return false;
+ else if (!isPredicated)
FalseLanesUnknown.insert(&MI);
}
auto HasPredicatedUsers = [this](MachineInstr *MI, const MachineOperand &MO,
SmallPtrSetImpl<MachineInstr *> &Predicated) {
SmallPtrSet<MachineInstr *, 2> Uses;
- RDA.getGlobalUses(MI, MO.getReg().asMCReg(), Uses);
+ RDA.getGlobalUses(MI, MO.getReg().asMCReg(), Uses);
for (auto *Use : Uses) {
if (Use != MI && !Predicated.count(Use))
return false;
@@ -982,12 +982,12 @@ bool LowOverheadLoop::ValidateLiveOuts() {
LLVM_DEBUG(dbgs() << "ARM Loops: Found an unknown def of : "
<< TRI.getRegAsmName(MO.getReg()) << " at " << *MI);
NonPredicated.insert(MI);
- break;
+ break;
}
}
// Any unknown false lanes have been masked away by the user(s).
- if (!NonPredicated.contains(MI))
- Predicated.insert(MI);
+ if (!NonPredicated.contains(MI))
+ Predicated.insert(MI);
}
SmallPtrSet<MachineInstr *, 2> LiveOutMIs;
@@ -997,13 +997,13 @@ bool LowOverheadLoop::ValidateLiveOuts() {
assert(ExitBlocks.size() == 1 && "Expected a single exit block");
MachineBasicBlock *ExitBB = ExitBlocks.front();
for (const MachineBasicBlock::RegisterMaskPair &RegMask : ExitBB->liveins()) {
- // TODO: Instead of blocking predication, we could move the vctp to the exit
- // block and calculate it's operand there in or the preheader.
- if (RegMask.PhysReg == ARM::VPR)
- return false;
+ // TODO: Instead of blocking predication, we could move the vctp to the exit
+ // block and calculate it's operand there in or the preheader.
+ if (RegMask.PhysReg == ARM::VPR)
+ return false;
// Check Q-regs that are live in the exit blocks. We don't collect scalars
// because they won't be affected by lane predication.
- if (QPRs->contains(RegMask.PhysReg))
+ if (QPRs->contains(RegMask.PhysReg))
if (auto *MI = RDA.getLocalLiveOutMIDef(Header, RegMask.PhysReg))
LiveOutMIs.insert(MI);
}
@@ -1014,123 +1014,123 @@ bool LowOverheadLoop::ValidateLiveOuts() {
// instruction needs to be predicated, so check this here. The instructions
// in NonPredicated have been found to be a reduction that we can ensure its
// legality.
- for (auto *MI : LiveOutMIs) {
- if (NonPredicated.count(MI) && FalseLanesUnknown.contains(MI)) {
- LLVM_DEBUG(dbgs() << "ARM Loops: Unable to handle live out: " << *MI);
+ for (auto *MI : LiveOutMIs) {
+ if (NonPredicated.count(MI) && FalseLanesUnknown.contains(MI)) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: Unable to handle live out: " << *MI);
return false;
- }
- }
+ }
+ }
return true;
}
-void LowOverheadLoop::Validate(ARMBasicBlockUtils *BBUtils) {
+void LowOverheadLoop::Validate(ARMBasicBlockUtils *BBUtils) {
if (Revert)
return;
- // Check branch target ranges: WLS[TP] can only branch forwards and LE[TP]
- // can only jump back.
- auto ValidateRanges = [](MachineInstr *Start, MachineInstr *End,
- ARMBasicBlockUtils *BBUtils, MachineLoop &ML) {
- MachineBasicBlock *TgtBB = End->getOpcode() == ARM::t2LoopEnd
- ? End->getOperand(1).getMBB()
- : End->getOperand(2).getMBB();
- // TODO Maybe there's cases where the target doesn't have to be the header,
- // but for now be safe and revert.
- if (TgtBB != ML.getHeader()) {
- LLVM_DEBUG(dbgs() << "ARM Loops: LoopEnd is not targeting header.\n");
- return false;
- }
-
- // The WLS and LE instructions have 12-bits for the label offset. WLS
- // requires a positive offset, while LE uses negative.
- if (BBUtils->getOffsetOf(End) < BBUtils->getOffsetOf(ML.getHeader()) ||
- !BBUtils->isBBInRange(End, ML.getHeader(), 4094)) {
- LLVM_DEBUG(dbgs() << "ARM Loops: LE offset is out-of-range\n");
- return false;
- }
-
- if (Start->getOpcode() == ARM::t2WhileLoopStart &&
- (BBUtils->getOffsetOf(Start) >
- BBUtils->getOffsetOf(Start->getOperand(1).getMBB()) ||
- !BBUtils->isBBInRange(Start, Start->getOperand(1).getMBB(), 4094))) {
- LLVM_DEBUG(dbgs() << "ARM Loops: WLS offset is out-of-range!\n");
- return false;
- }
- return true;
- };
-
- // Find a suitable position to insert the loop start instruction. It needs to
- // be able to safely define LR.
- auto FindStartInsertionPoint = [](MachineInstr *Start, MachineInstr *Dec,
- MachineBasicBlock::iterator &InsertPt,
- MachineBasicBlock *&InsertBB,
- ReachingDefAnalysis &RDA,
- InstSet &ToRemove) {
- // For a t2DoLoopStart it is always valid to use the start insertion point.
- // For WLS we can define LR if LR already contains the same value.
- if (isDo(Start) || Start->getOperand(0).getReg() == ARM::LR) {
- InsertPt = MachineBasicBlock::iterator(Start);
- InsertBB = Start->getParent();
- return true;
- }
-
- // We've found no suitable LR def and Start doesn't use LR directly. Can we
- // just define LR anyway?
- if (!RDA.isSafeToDefRegAt(Start, MCRegister::from(ARM::LR)))
- return false;
-
- InsertPt = MachineBasicBlock::iterator(Start);
- InsertBB = Start->getParent();
- return true;
- };
-
- if (!FindStartInsertionPoint(Start, Dec, StartInsertPt, StartInsertBB, RDA,
- ToRemove)) {
+ // Check branch target ranges: WLS[TP] can only branch forwards and LE[TP]
+ // can only jump back.
+ auto ValidateRanges = [](MachineInstr *Start, MachineInstr *End,
+ ARMBasicBlockUtils *BBUtils, MachineLoop &ML) {
+ MachineBasicBlock *TgtBB = End->getOpcode() == ARM::t2LoopEnd
+ ? End->getOperand(1).getMBB()
+ : End->getOperand(2).getMBB();
+ // TODO Maybe there's cases where the target doesn't have to be the header,
+ // but for now be safe and revert.
+ if (TgtBB != ML.getHeader()) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: LoopEnd is not targeting header.\n");
+ return false;
+ }
+
+ // The WLS and LE instructions have 12-bits for the label offset. WLS
+ // requires a positive offset, while LE uses negative.
+ if (BBUtils->getOffsetOf(End) < BBUtils->getOffsetOf(ML.getHeader()) ||
+ !BBUtils->isBBInRange(End, ML.getHeader(), 4094)) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: LE offset is out-of-range\n");
+ return false;
+ }
+
+ if (Start->getOpcode() == ARM::t2WhileLoopStart &&
+ (BBUtils->getOffsetOf(Start) >
+ BBUtils->getOffsetOf(Start->getOperand(1).getMBB()) ||
+ !BBUtils->isBBInRange(Start, Start->getOperand(1).getMBB(), 4094))) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: WLS offset is out-of-range!\n");
+ return false;
+ }
+ return true;
+ };
+
+ // Find a suitable position to insert the loop start instruction. It needs to
+ // be able to safely define LR.
+ auto FindStartInsertionPoint = [](MachineInstr *Start, MachineInstr *Dec,
+ MachineBasicBlock::iterator &InsertPt,
+ MachineBasicBlock *&InsertBB,
+ ReachingDefAnalysis &RDA,
+ InstSet &ToRemove) {
+ // For a t2DoLoopStart it is always valid to use the start insertion point.
+ // For WLS we can define LR if LR already contains the same value.
+ if (isDo(Start) || Start->getOperand(0).getReg() == ARM::LR) {
+ InsertPt = MachineBasicBlock::iterator(Start);
+ InsertBB = Start->getParent();
+ return true;
+ }
+
+ // We've found no suitable LR def and Start doesn't use LR directly. Can we
+ // just define LR anyway?
+ if (!RDA.isSafeToDefRegAt(Start, MCRegister::from(ARM::LR)))
+ return false;
+
+ InsertPt = MachineBasicBlock::iterator(Start);
+ InsertBB = Start->getParent();
+ return true;
+ };
+
+ if (!FindStartInsertionPoint(Start, Dec, StartInsertPt, StartInsertBB, RDA,
+ ToRemove)) {
LLVM_DEBUG(dbgs() << "ARM Loops: Unable to find safe insertion point.\n");
Revert = true;
return;
- }
- LLVM_DEBUG(if (StartInsertPt == StartInsertBB->end())
- dbgs() << "ARM Loops: Will insert LoopStart at end of block\n";
- else
- dbgs() << "ARM Loops: Will insert LoopStart at "
- << *StartInsertPt
- );
-
- Revert = !ValidateRanges(Start, End, BBUtils, ML);
- CannotTailPredicate = !ValidateTailPredicate();
-}
-
-bool LowOverheadLoop::AddVCTP(MachineInstr *MI) {
- LLVM_DEBUG(dbgs() << "ARM Loops: Adding VCTP: " << *MI);
- if (VCTPs.empty()) {
- VCTPs.push_back(MI);
- return true;
+ }
+ LLVM_DEBUG(if (StartInsertPt == StartInsertBB->end())
+ dbgs() << "ARM Loops: Will insert LoopStart at end of block\n";
+ else
+ dbgs() << "ARM Loops: Will insert LoopStart at "
+ << *StartInsertPt
+ );
+
+ Revert = !ValidateRanges(Start, End, BBUtils, ML);
+ CannotTailPredicate = !ValidateTailPredicate();
+}
+
+bool LowOverheadLoop::AddVCTP(MachineInstr *MI) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: Adding VCTP: " << *MI);
+ if (VCTPs.empty()) {
+ VCTPs.push_back(MI);
+ return true;
}
- // If we find another VCTP, check whether it uses the same value as the main VCTP.
- // If it does, store it in the VCTPs set, else refuse it.
- MachineInstr *Prev = VCTPs.back();
- if (!Prev->getOperand(1).isIdenticalTo(MI->getOperand(1)) ||
- !RDA.hasSameReachingDef(Prev, MI, MI->getOperand(1).getReg().asMCReg())) {
- LLVM_DEBUG(dbgs() << "ARM Loops: Found VCTP with a different reaching "
- "definition from the main VCTP");
- return false;
- }
- VCTPs.push_back(MI);
- return true;
+ // If we find another VCTP, check whether it uses the same value as the main VCTP.
+ // If it does, store it in the VCTPs set, else refuse it.
+ MachineInstr *Prev = VCTPs.back();
+ if (!Prev->getOperand(1).isIdenticalTo(MI->getOperand(1)) ||
+ !RDA.hasSameReachingDef(Prev, MI, MI->getOperand(1).getReg().asMCReg())) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: Found VCTP with a different reaching "
+ "definition from the main VCTP");
+ return false;
+ }
+ VCTPs.push_back(MI);
+ return true;
}
bool LowOverheadLoop::ValidateMVEInst(MachineInstr* MI) {
if (CannotTailPredicate)
return false;
- if (!shouldInspect(*MI))
- return true;
+ if (!shouldInspect(*MI))
+ return true;
- if (MI->getOpcode() == ARM::MVE_VPSEL ||
- MI->getOpcode() == ARM::MVE_VPNOT) {
+ if (MI->getOpcode() == ARM::MVE_VPSEL ||
+ MI->getOpcode() == ARM::MVE_VPNOT) {
// TODO: Allow VPSEL and VPNOT, we currently cannot because:
// 1) It will use the VPR as a predicate operand, but doesn't have to be
// instead a VPT block, which means we can assert while building up
@@ -1142,24 +1142,24 @@ bool LowOverheadLoop::ValidateMVEInst(MachineInstr* MI) {
return false;
}
- // Record all VCTPs and check that they're equivalent to one another.
- if (isVCTP(MI) && !AddVCTP(MI))
- return false;
-
- // Inspect uses first so that any instructions that alter the VPR don't
- // alter the predicate upon themselves.
- const MCInstrDesc &MCID = MI->getDesc();
+ // Record all VCTPs and check that they're equivalent to one another.
+ if (isVCTP(MI) && !AddVCTP(MI))
+ return false;
+
+ // Inspect uses first so that any instructions that alter the VPR don't
+ // alter the predicate upon themselves.
+ const MCInstrDesc &MCID = MI->getDesc();
bool IsUse = false;
- unsigned LastOpIdx = MI->getNumOperands() - 1;
- for (auto &Op : enumerate(reverse(MCID.operands()))) {
- const MachineOperand &MO = MI->getOperand(LastOpIdx - Op.index());
- if (!MO.isReg() || !MO.isUse() || MO.getReg() != ARM::VPR)
+ unsigned LastOpIdx = MI->getNumOperands() - 1;
+ for (auto &Op : enumerate(reverse(MCID.operands()))) {
+ const MachineOperand &MO = MI->getOperand(LastOpIdx - Op.index());
+ if (!MO.isReg() || !MO.isUse() || MO.getReg() != ARM::VPR)
continue;
- if (ARM::isVpred(Op.value().OperandType)) {
- VPTState::addInst(MI);
+ if (ARM::isVpred(Op.value().OperandType)) {
+ VPTState::addInst(MI);
IsUse = true;
- } else if (MI->getOpcode() != ARM::MVE_VPST) {
+ } else if (MI->getOpcode() != ARM::MVE_VPST) {
LLVM_DEBUG(dbgs() << "ARM Loops: Found instruction using vpr: " << *MI);
return false;
}
@@ -1168,36 +1168,36 @@ bool LowOverheadLoop::ValidateMVEInst(MachineInstr* MI) {
// If we find an instruction that has been marked as not valid for tail
// predication, only allow the instruction if it's contained within a valid
// VPT block.
- bool RequiresExplicitPredication =
- (MCID.TSFlags & ARMII::ValidForTailPredication) == 0;
- if (isDomainMVE(MI) && RequiresExplicitPredication) {
- LLVM_DEBUG(if (!IsUse)
- dbgs() << "ARM Loops: Can't tail predicate: " << *MI);
- return IsUse;
+ bool RequiresExplicitPredication =
+ (MCID.TSFlags & ARMII::ValidForTailPredication) == 0;
+ if (isDomainMVE(MI) && RequiresExplicitPredication) {
+ LLVM_DEBUG(if (!IsUse)
+ dbgs() << "ARM Loops: Can't tail predicate: " << *MI);
+ return IsUse;
}
// If the instruction is already explicitly predicated, then the conversion
- // will be fine, but ensure that all store operations are predicated.
- if (MI->mayStore())
- return IsUse;
-
- // If this instruction defines the VPR, update the predicate for the
- // proceeding instructions.
- if (isVectorPredicate(MI)) {
- // Clear the existing predicate when we're not in VPT Active state,
- // otherwise we add to it.
- if (!isVectorPredicated(MI))
- VPTState::resetPredicate(MI);
- else
- VPTState::addPredicate(MI);
- }
-
- // Finally once the predicate has been modified, we can start a new VPT
- // block if necessary.
- if (isVPTOpcode(MI->getOpcode()))
- VPTState::CreateVPTBlock(MI);
-
- return true;
+ // will be fine, but ensure that all store operations are predicated.
+ if (MI->mayStore())
+ return IsUse;
+
+ // If this instruction defines the VPR, update the predicate for the
+ // proceeding instructions.
+ if (isVectorPredicate(MI)) {
+ // Clear the existing predicate when we're not in VPT Active state,
+ // otherwise we add to it.
+ if (!isVectorPredicated(MI))
+ VPTState::resetPredicate(MI);
+ else
+ VPTState::addPredicate(MI);
+ }
+
+ // Finally once the predicate has been modified, we can start a new VPT
+ // block if necessary.
+ if (isVPTOpcode(MI->getOpcode()))
+ VPTState::CreateVPTBlock(MI);
+
+ return true;
}
bool ARMLowOverheadLoops::runOnMachineFunction(MachineFunction &mf) {
@@ -1220,7 +1220,7 @@ bool ARMLowOverheadLoops::runOnMachineFunction(MachineFunction &mf) {
bool Changed = false;
for (auto ML : *MLI) {
- if (ML->isOutermost())
+ if (ML->isOutermost())
Changed |= ProcessLoop(ML);
}
Changed |= RevertNonLoops();
@@ -1279,8 +1279,8 @@ bool ARMLowOverheadLoops::ProcessLoop(MachineLoop *ML) {
LoLoop.Dec = &MI;
else if (MI.getOpcode() == ARM::t2LoopEnd)
LoLoop.End = &MI;
- else if (MI.getOpcode() == ARM::t2LoopEndDec)
- LoLoop.End = LoLoop.Dec = &MI;
+ else if (MI.getOpcode() == ARM::t2LoopEndDec)
+ LoLoop.End = LoLoop.Dec = &MI;
else if (isLoopStart(MI))
LoLoop.Start = &MI;
else if (MI.getDesc().isCall()) {
@@ -1303,18 +1303,18 @@ bool ARMLowOverheadLoops::ProcessLoop(MachineLoop *ML) {
return false;
}
- // Check that the only instruction using LoopDec is LoopEnd. This can only
- // happen when the Dec and End are separate, not a single t2LoopEndDec.
+ // Check that the only instruction using LoopDec is LoopEnd. This can only
+ // happen when the Dec and End are separate, not a single t2LoopEndDec.
// TODO: Check for copy chains that really have no effect.
- if (LoLoop.Dec != LoLoop.End) {
- SmallPtrSet<MachineInstr *, 2> Uses;
- RDA->getReachingLocalUses(LoLoop.Dec, MCRegister::from(ARM::LR), Uses);
- if (Uses.size() > 1 || !Uses.count(LoLoop.End)) {
- LLVM_DEBUG(dbgs() << "ARM Loops: Unable to remove LoopDec.\n");
- LoLoop.Revert = true;
- }
+ if (LoLoop.Dec != LoLoop.End) {
+ SmallPtrSet<MachineInstr *, 2> Uses;
+ RDA->getReachingLocalUses(LoLoop.Dec, MCRegister::from(ARM::LR), Uses);
+ if (Uses.size() > 1 || !Uses.count(LoLoop.End)) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: Unable to remove LoopDec.\n");
+ LoLoop.Revert = true;
+ }
}
- LoLoop.Validate(BBUtils.get());
+ LoLoop.Validate(BBUtils.get());
Expand(LoLoop);
return true;
}
@@ -1329,14 +1329,14 @@ void ARMLowOverheadLoops::RevertWhile(MachineInstr *MI) const {
unsigned BrOpc = BBUtils->isBBInRange(MI, DestBB, 254) ?
ARM::tBcc : ARM::t2Bcc;
- RevertWhileLoopStart(MI, TII, BrOpc);
+ RevertWhileLoopStart(MI, TII, BrOpc);
+}
+
+void ARMLowOverheadLoops::RevertDo(MachineInstr *MI) const {
+ LLVM_DEBUG(dbgs() << "ARM Loops: Reverting to mov: " << *MI);
+ RevertDoLoopStart(MI, TII);
}
-void ARMLowOverheadLoops::RevertDo(MachineInstr *MI) const {
- LLVM_DEBUG(dbgs() << "ARM Loops: Reverting to mov: " << *MI);
- RevertDoLoopStart(MI, TII);
-}
-
bool ARMLowOverheadLoops::RevertLoopDec(MachineInstr *MI) const {
LLVM_DEBUG(dbgs() << "ARM Loops: Reverting to sub: " << *MI);
MachineBasicBlock *MBB = MI->getParent();
@@ -1349,10 +1349,10 @@ bool ARMLowOverheadLoops::RevertLoopDec(MachineInstr *MI) const {
}
// If nothing defines CPSR between LoopDec and LoopEnd, use a t2SUBS.
- bool SetFlags =
- RDA->isSafeToDefRegAt(MI, MCRegister::from(ARM::CPSR), Ignore);
+ bool SetFlags =
+ RDA->isSafeToDefRegAt(MI, MCRegister::from(ARM::CPSR), Ignore);
- llvm::RevertLoopDec(MI, TII, SetFlags);
+ llvm::RevertLoopDec(MI, TII, SetFlags);
return SetFlags;
}
@@ -1364,35 +1364,35 @@ void ARMLowOverheadLoops::RevertLoopEnd(MachineInstr *MI, bool SkipCmp) const {
unsigned BrOpc = BBUtils->isBBInRange(MI, DestBB, 254) ?
ARM::tBcc : ARM::t2Bcc;
- llvm::RevertLoopEnd(MI, TII, BrOpc, SkipCmp);
-}
-
-// Generate a subs, or sub and cmp, and a branch instead of an LE.
-void ARMLowOverheadLoops::RevertLoopEndDec(MachineInstr *MI) const {
- LLVM_DEBUG(dbgs() << "ARM Loops: Reverting to subs, br: " << *MI);
- assert(MI->getOpcode() == ARM::t2LoopEndDec && "Expected a t2LoopEndDec!");
- MachineBasicBlock *MBB = MI->getParent();
-
+ llvm::RevertLoopEnd(MI, TII, BrOpc, SkipCmp);
+}
+
+// Generate a subs, or sub and cmp, and a branch instead of an LE.
+void ARMLowOverheadLoops::RevertLoopEndDec(MachineInstr *MI) const {
+ LLVM_DEBUG(dbgs() << "ARM Loops: Reverting to subs, br: " << *MI);
+ assert(MI->getOpcode() == ARM::t2LoopEndDec && "Expected a t2LoopEndDec!");
+ MachineBasicBlock *MBB = MI->getParent();
+
MachineInstrBuilder MIB =
- BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2SUBri));
- MIB.addDef(ARM::LR);
- MIB.add(MI->getOperand(1));
- MIB.addImm(1);
- MIB.addImm(ARMCC::AL);
- MIB.addReg(ARM::NoRegister);
+ BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2SUBri));
+ MIB.addDef(ARM::LR);
+ MIB.add(MI->getOperand(1));
+ MIB.addImm(1);
+ MIB.addImm(ARMCC::AL);
+ MIB.addReg(ARM::NoRegister);
+ MIB.addReg(ARM::CPSR);
+ MIB->getOperand(5).setIsDef(true);
+
+ MachineBasicBlock *DestBB = MI->getOperand(2).getMBB();
+ unsigned BrOpc =
+ BBUtils->isBBInRange(MI, DestBB, 254) ? ARM::tBcc : ARM::t2Bcc;
+
+ // Create bne
+ MIB = BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(BrOpc));
+ MIB.add(MI->getOperand(2)); // branch target
+ MIB.addImm(ARMCC::NE); // condition code
MIB.addReg(ARM::CPSR);
- MIB->getOperand(5).setIsDef(true);
-
- MachineBasicBlock *DestBB = MI->getOperand(2).getMBB();
- unsigned BrOpc =
- BBUtils->isBBInRange(MI, DestBB, 254) ? ARM::tBcc : ARM::t2Bcc;
-
- // Create bne
- MIB = BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(BrOpc));
- MIB.add(MI->getOperand(2)); // branch target
- MIB.addImm(ARMCC::NE); // condition code
- MIB.addReg(ARM::CPSR);
-
+
MI->eraseFromParent();
}
@@ -1403,7 +1403,7 @@ void ARMLowOverheadLoops::RevertLoopEndDec(MachineInstr *MI) const {
//
// $lr = big-itercount-expression
// ..
-// $lr = t2DoLoopStart renamable $lr
+// $lr = t2DoLoopStart renamable $lr
// vector.body:
// ..
// $vpr = MVE_VCTP32 renamable $r3
@@ -1426,8 +1426,8 @@ void ARMLowOverheadLoops::IterationCountDCE(LowOverheadLoop &LoLoop) {
LLVM_DEBUG(dbgs() << "ARM Loops: Trying DCE on loop iteration count.\n");
- MachineInstr *Def =
- RDA->getMIOperand(LoLoop.Start, isDo(LoLoop.Start) ? 1 : 0);
+ MachineInstr *Def =
+ RDA->getMIOperand(LoLoop.Start, isDo(LoLoop.Start) ? 1 : 0);
if (!Def) {
LLVM_DEBUG(dbgs() << "ARM Loops: Couldn't find iteration count.\n");
return;
@@ -1435,8 +1435,8 @@ void ARMLowOverheadLoops::IterationCountDCE(LowOverheadLoop &LoLoop) {
// Collect and remove the users of iteration count.
SmallPtrSet<MachineInstr*, 4> Killed = { LoLoop.Start, LoLoop.Dec,
- LoLoop.End };
- if (!TryRemove(Def, *RDA, LoLoop.ToRemove, Killed))
+ LoLoop.End };
+ if (!TryRemove(Def, *RDA, LoLoop.ToRemove, Killed))
LLVM_DEBUG(dbgs() << "ARM Loops: Unsafe to remove loop iteration count.\n");
}
@@ -1446,18 +1446,18 @@ MachineInstr* ARMLowOverheadLoops::ExpandLoopStart(LowOverheadLoop &LoLoop) {
// calculate the number of loop iterations.
IterationCountDCE(LoLoop);
- MachineBasicBlock::iterator InsertPt = LoLoop.StartInsertPt;
+ MachineBasicBlock::iterator InsertPt = LoLoop.StartInsertPt;
MachineInstr *Start = LoLoop.Start;
- MachineBasicBlock *MBB = LoLoop.StartInsertBB;
+ MachineBasicBlock *MBB = LoLoop.StartInsertBB;
unsigned Opc = LoLoop.getStartOpcode();
- MachineOperand &Count = LoLoop.getLoopStartOperand();
+ MachineOperand &Count = LoLoop.getLoopStartOperand();
MachineInstrBuilder MIB =
- BuildMI(*MBB, InsertPt, Start->getDebugLoc(), TII->get(Opc));
+ BuildMI(*MBB, InsertPt, Start->getDebugLoc(), TII->get(Opc));
MIB.addDef(ARM::LR);
MIB.add(Count);
- if (!isDo(Start))
+ if (!isDo(Start))
MIB.add(Start->getOperand(1));
LoLoop.ToRemove.insert(Start);
@@ -1467,50 +1467,50 @@ MachineInstr* ARMLowOverheadLoops::ExpandLoopStart(LowOverheadLoop &LoLoop) {
void ARMLowOverheadLoops::ConvertVPTBlocks(LowOverheadLoop &LoLoop) {
auto RemovePredicate = [](MachineInstr *MI) {
- if (MI->isDebugInstr())
- return;
+ if (MI->isDebugInstr())
+ return;
LLVM_DEBUG(dbgs() << "ARM Loops: Removing predicate from: " << *MI);
- int PIdx = llvm::findFirstVPTPredOperandIdx(*MI);
- assert(PIdx >= 1 && "Trying to unpredicate a non-predicated instruction");
- assert(MI->getOperand(PIdx).getImm() == ARMVCC::Then &&
- "Expected Then predicate!");
- MI->getOperand(PIdx).setImm(ARMVCC::None);
- MI->getOperand(PIdx + 1).setReg(0);
+ int PIdx = llvm::findFirstVPTPredOperandIdx(*MI);
+ assert(PIdx >= 1 && "Trying to unpredicate a non-predicated instruction");
+ assert(MI->getOperand(PIdx).getImm() == ARMVCC::Then &&
+ "Expected Then predicate!");
+ MI->getOperand(PIdx).setImm(ARMVCC::None);
+ MI->getOperand(PIdx + 1).setReg(0);
};
for (auto &Block : LoLoop.getVPTBlocks()) {
- SmallVectorImpl<MachineInstr *> &Insts = Block.getInsts();
-
- auto ReplaceVCMPWithVPT = [&](MachineInstr *&TheVCMP, MachineInstr *At) {
- assert(TheVCMP && "Replacing a removed or non-existent VCMP");
- // Replace the VCMP with a VPT
- MachineInstrBuilder MIB =
- BuildMI(*At->getParent(), At, At->getDebugLoc(),
- TII->get(VCMPOpcodeToVPT(TheVCMP->getOpcode())));
- MIB.addImm(ARMVCC::Then);
- // Register one
- MIB.add(TheVCMP->getOperand(1));
- // Register two
- MIB.add(TheVCMP->getOperand(2));
- // The comparison code, e.g. ge, eq, lt
- MIB.add(TheVCMP->getOperand(3));
- LLVM_DEBUG(dbgs() << "ARM Loops: Combining with VCMP to VPT: " << *MIB);
- LoLoop.BlockMasksToRecompute.insert(MIB.getInstr());
- LoLoop.ToRemove.insert(TheVCMP);
- TheVCMP = nullptr;
- };
-
- if (VPTState::isEntryPredicatedOnVCTP(Block, /*exclusive*/ true)) {
- MachineInstr *VPST = Insts.front();
- if (VPTState::hasUniformPredicate(Block)) {
- // A vpt block starting with VPST, is only predicated upon vctp and has no
- // internal vpr defs:
- // - Remove vpst.
- // - Unpredicate the remaining instructions.
- LLVM_DEBUG(dbgs() << "ARM Loops: Removing VPST: " << *VPST);
- for (unsigned i = 1; i < Insts.size(); ++i)
- RemovePredicate(Insts[i]);
- } else {
+ SmallVectorImpl<MachineInstr *> &Insts = Block.getInsts();
+
+ auto ReplaceVCMPWithVPT = [&](MachineInstr *&TheVCMP, MachineInstr *At) {
+ assert(TheVCMP && "Replacing a removed or non-existent VCMP");
+ // Replace the VCMP with a VPT
+ MachineInstrBuilder MIB =
+ BuildMI(*At->getParent(), At, At->getDebugLoc(),
+ TII->get(VCMPOpcodeToVPT(TheVCMP->getOpcode())));
+ MIB.addImm(ARMVCC::Then);
+ // Register one
+ MIB.add(TheVCMP->getOperand(1));
+ // Register two
+ MIB.add(TheVCMP->getOperand(2));
+ // The comparison code, e.g. ge, eq, lt
+ MIB.add(TheVCMP->getOperand(3));
+ LLVM_DEBUG(dbgs() << "ARM Loops: Combining with VCMP to VPT: " << *MIB);
+ LoLoop.BlockMasksToRecompute.insert(MIB.getInstr());
+ LoLoop.ToRemove.insert(TheVCMP);
+ TheVCMP = nullptr;
+ };
+
+ if (VPTState::isEntryPredicatedOnVCTP(Block, /*exclusive*/ true)) {
+ MachineInstr *VPST = Insts.front();
+ if (VPTState::hasUniformPredicate(Block)) {
+ // A vpt block starting with VPST, is only predicated upon vctp and has no
+ // internal vpr defs:
+ // - Remove vpst.
+ // - Unpredicate the remaining instructions.
+ LLVM_DEBUG(dbgs() << "ARM Loops: Removing VPST: " << *VPST);
+ for (unsigned i = 1; i < Insts.size(); ++i)
+ RemovePredicate(Insts[i]);
+ } else {
// The VPT block has a non-uniform predicate but it uses a vpst and its
// entry is guarded only by a vctp, which means we:
// - Need to remove the original vpst.
@@ -1518,88 +1518,88 @@ void ARMLowOverheadLoops::ConvertVPTBlocks(LowOverheadLoop &LoLoop) {
// we come across the divergent vpr def.
// - Insert a new vpst to predicate the instruction(s) that following
// the divergent vpr def.
- MachineInstr *Divergent = VPTState::getDivergent(Block);
- MachineBasicBlock *MBB = Divergent->getParent();
- auto DivergentNext = ++MachineBasicBlock::iterator(Divergent);
- while (DivergentNext != MBB->end() && DivergentNext->isDebugInstr())
- ++DivergentNext;
-
- bool DivergentNextIsPredicated =
- DivergentNext != MBB->end() &&
- getVPTInstrPredicate(*DivergentNext) != ARMVCC::None;
-
- for (auto I = ++MachineBasicBlock::iterator(VPST), E = DivergentNext;
- I != E; ++I)
+ MachineInstr *Divergent = VPTState::getDivergent(Block);
+ MachineBasicBlock *MBB = Divergent->getParent();
+ auto DivergentNext = ++MachineBasicBlock::iterator(Divergent);
+ while (DivergentNext != MBB->end() && DivergentNext->isDebugInstr())
+ ++DivergentNext;
+
+ bool DivergentNextIsPredicated =
+ DivergentNext != MBB->end() &&
+ getVPTInstrPredicate(*DivergentNext) != ARMVCC::None;
+
+ for (auto I = ++MachineBasicBlock::iterator(VPST), E = DivergentNext;
+ I != E; ++I)
RemovePredicate(&*I);
- // Check if the instruction defining vpr is a vcmp so it can be combined
- // with the VPST This should be the divergent instruction
- MachineInstr *VCMP =
- VCMPOpcodeToVPT(Divergent->getOpcode()) != 0 ? Divergent : nullptr;
-
- if (DivergentNextIsPredicated) {
- // Insert a VPST at the divergent only if the next instruction
- // would actually use it. A VCMP following a VPST can be
- // merged into a VPT so do that instead if the VCMP exists.
- if (!VCMP) {
- // Create a VPST (with a null mask for now, we'll recompute it
- // later)
- MachineInstrBuilder MIB =
- BuildMI(*Divergent->getParent(), Divergent,
- Divergent->getDebugLoc(), TII->get(ARM::MVE_VPST));
- MIB.addImm(0);
- LLVM_DEBUG(dbgs() << "ARM Loops: Created VPST: " << *MIB);
- LoLoop.BlockMasksToRecompute.insert(MIB.getInstr());
- } else {
- // No RDA checks are necessary here since the VPST would have been
- // directly after the VCMP
- ReplaceVCMPWithVPT(VCMP, VCMP);
- }
+ // Check if the instruction defining vpr is a vcmp so it can be combined
+ // with the VPST This should be the divergent instruction
+ MachineInstr *VCMP =
+ VCMPOpcodeToVPT(Divergent->getOpcode()) != 0 ? Divergent : nullptr;
+
+ if (DivergentNextIsPredicated) {
+ // Insert a VPST at the divergent only if the next instruction
+ // would actually use it. A VCMP following a VPST can be
+ // merged into a VPT so do that instead if the VCMP exists.
+ if (!VCMP) {
+ // Create a VPST (with a null mask for now, we'll recompute it
+ // later)
+ MachineInstrBuilder MIB =
+ BuildMI(*Divergent->getParent(), Divergent,
+ Divergent->getDebugLoc(), TII->get(ARM::MVE_VPST));
+ MIB.addImm(0);
+ LLVM_DEBUG(dbgs() << "ARM Loops: Created VPST: " << *MIB);
+ LoLoop.BlockMasksToRecompute.insert(MIB.getInstr());
+ } else {
+ // No RDA checks are necessary here since the VPST would have been
+ // directly after the VCMP
+ ReplaceVCMPWithVPT(VCMP, VCMP);
+ }
}
}
- LLVM_DEBUG(dbgs() << "ARM Loops: Removing VPST: " << *VPST);
- LoLoop.ToRemove.insert(VPST);
- } else if (Block.containsVCTP()) {
- // The vctp will be removed, so either the entire block will be dead or
- // the block mask of the vp(s)t will need to be recomputed.
- MachineInstr *VPST = Insts.front();
- if (Block.size() == 2) {
- assert(VPST->getOpcode() == ARM::MVE_VPST &&
- "Found a VPST in an otherwise empty vpt block");
- LoLoop.ToRemove.insert(VPST);
- } else
- LoLoop.BlockMasksToRecompute.insert(VPST);
- } else if (Insts.front()->getOpcode() == ARM::MVE_VPST) {
- // If this block starts with a VPST then attempt to merge it with the
- // preceeding un-merged VCMP into a VPT. This VCMP comes from a VPT
- // block that no longer exists
- MachineInstr *VPST = Insts.front();
- auto Next = ++MachineBasicBlock::iterator(VPST);
- assert(getVPTInstrPredicate(*Next) != ARMVCC::None &&
- "The instruction after a VPST must be predicated");
- (void)Next;
- MachineInstr *VprDef = RDA->getUniqueReachingMIDef(VPST, ARM::VPR);
- if (VprDef && VCMPOpcodeToVPT(VprDef->getOpcode()) &&
- !LoLoop.ToRemove.contains(VprDef)) {
- MachineInstr *VCMP = VprDef;
- // The VCMP and VPST can only be merged if the VCMP's operands will have
- // the same values at the VPST.
- // If any of the instructions between the VCMP and VPST are predicated
- // then a different code path is expected to have merged the VCMP and
- // VPST already.
- if (!std::any_of(++MachineBasicBlock::iterator(VCMP),
- MachineBasicBlock::iterator(VPST), hasVPRUse) &&
- RDA->hasSameReachingDef(VCMP, VPST, VCMP->getOperand(1).getReg()) &&
- RDA->hasSameReachingDef(VCMP, VPST, VCMP->getOperand(2).getReg())) {
- ReplaceVCMPWithVPT(VCMP, VPST);
- LLVM_DEBUG(dbgs() << "ARM Loops: Removing VPST: " << *VPST);
- LoLoop.ToRemove.insert(VPST);
+ LLVM_DEBUG(dbgs() << "ARM Loops: Removing VPST: " << *VPST);
+ LoLoop.ToRemove.insert(VPST);
+ } else if (Block.containsVCTP()) {
+ // The vctp will be removed, so either the entire block will be dead or
+ // the block mask of the vp(s)t will need to be recomputed.
+ MachineInstr *VPST = Insts.front();
+ if (Block.size() == 2) {
+ assert(VPST->getOpcode() == ARM::MVE_VPST &&
+ "Found a VPST in an otherwise empty vpt block");
+ LoLoop.ToRemove.insert(VPST);
+ } else
+ LoLoop.BlockMasksToRecompute.insert(VPST);
+ } else if (Insts.front()->getOpcode() == ARM::MVE_VPST) {
+ // If this block starts with a VPST then attempt to merge it with the
+ // preceeding un-merged VCMP into a VPT. This VCMP comes from a VPT
+ // block that no longer exists
+ MachineInstr *VPST = Insts.front();
+ auto Next = ++MachineBasicBlock::iterator(VPST);
+ assert(getVPTInstrPredicate(*Next) != ARMVCC::None &&
+ "The instruction after a VPST must be predicated");
+ (void)Next;
+ MachineInstr *VprDef = RDA->getUniqueReachingMIDef(VPST, ARM::VPR);
+ if (VprDef && VCMPOpcodeToVPT(VprDef->getOpcode()) &&
+ !LoLoop.ToRemove.contains(VprDef)) {
+ MachineInstr *VCMP = VprDef;
+ // The VCMP and VPST can only be merged if the VCMP's operands will have
+ // the same values at the VPST.
+ // If any of the instructions between the VCMP and VPST are predicated
+ // then a different code path is expected to have merged the VCMP and
+ // VPST already.
+ if (!std::any_of(++MachineBasicBlock::iterator(VCMP),
+ MachineBasicBlock::iterator(VPST), hasVPRUse) &&
+ RDA->hasSameReachingDef(VCMP, VPST, VCMP->getOperand(1).getReg()) &&
+ RDA->hasSameReachingDef(VCMP, VPST, VCMP->getOperand(2).getReg())) {
+ ReplaceVCMPWithVPT(VCMP, VPST);
+ LLVM_DEBUG(dbgs() << "ARM Loops: Removing VPST: " << *VPST);
+ LoLoop.ToRemove.insert(VPST);
}
}
}
}
-
- LoLoop.ToRemove.insert(LoLoop.VCTPs.begin(), LoLoop.VCTPs.end());
+
+ LoLoop.ToRemove.insert(LoLoop.VCTPs.begin(), LoLoop.VCTPs.end());
}
void ARMLowOverheadLoops::Expand(LowOverheadLoop &LoLoop) {
@@ -1613,9 +1613,9 @@ void ARMLowOverheadLoops::Expand(LowOverheadLoop &LoLoop) {
MachineInstrBuilder MIB = BuildMI(*MBB, End, End->getDebugLoc(),
TII->get(Opc));
MIB.addDef(ARM::LR);
- unsigned Off = LoLoop.Dec == LoLoop.End ? 1 : 0;
- MIB.add(End->getOperand(Off + 0));
- MIB.add(End->getOperand(Off + 1));
+ unsigned Off = LoLoop.Dec == LoLoop.End ? 1 : 0;
+ MIB.add(End->getOperand(Off + 0));
+ MIB.add(End->getOperand(Off + 1));
LLVM_DEBUG(dbgs() << "ARM Loops: Inserted LE: " << *MIB);
LoLoop.ToRemove.insert(LoLoop.Dec);
LoLoop.ToRemove.insert(End);
@@ -1643,17 +1643,17 @@ void ARMLowOverheadLoops::Expand(LowOverheadLoop &LoLoop) {
if (LoLoop.Start->getOpcode() == ARM::t2WhileLoopStart)
RevertWhile(LoLoop.Start);
else
- RevertDo(LoLoop.Start);
- if (LoLoop.Dec == LoLoop.End)
- RevertLoopEndDec(LoLoop.End);
- else
- RevertLoopEnd(LoLoop.End, RevertLoopDec(LoLoop.Dec));
+ RevertDo(LoLoop.Start);
+ if (LoLoop.Dec == LoLoop.End)
+ RevertLoopEndDec(LoLoop.End);
+ else
+ RevertLoopEnd(LoLoop.End, RevertLoopDec(LoLoop.Dec));
} else {
LoLoop.Start = ExpandLoopStart(LoLoop);
RemoveDeadBranch(LoLoop.Start);
LoLoop.End = ExpandLoopEnd(LoLoop);
RemoveDeadBranch(LoLoop.End);
- if (LoLoop.IsTailPredicationLegal())
+ if (LoLoop.IsTailPredicationLegal())
ConvertVPTBlocks(LoLoop);
for (auto *I : LoLoop.ToRemove) {
LLVM_DEBUG(dbgs() << "ARM Loops: Erasing " << *I);
@@ -1691,7 +1691,7 @@ bool ARMLowOverheadLoops::RevertNonLoops() {
SmallVector<MachineInstr*, 4> Starts;
SmallVector<MachineInstr*, 4> Decs;
SmallVector<MachineInstr*, 4> Ends;
- SmallVector<MachineInstr *, 4> EndDecs;
+ SmallVector<MachineInstr *, 4> EndDecs;
for (auto &I : MBB) {
if (isLoopStart(I))
@@ -1700,11 +1700,11 @@ bool ARMLowOverheadLoops::RevertNonLoops() {
Decs.push_back(&I);
else if (I.getOpcode() == ARM::t2LoopEnd)
Ends.push_back(&I);
- else if (I.getOpcode() == ARM::t2LoopEndDec)
- EndDecs.push_back(&I);
+ else if (I.getOpcode() == ARM::t2LoopEndDec)
+ EndDecs.push_back(&I);
}
- if (Starts.empty() && Decs.empty() && Ends.empty() && EndDecs.empty())
+ if (Starts.empty() && Decs.empty() && Ends.empty() && EndDecs.empty())
continue;
Changed = true;
@@ -1713,15 +1713,15 @@ bool ARMLowOverheadLoops::RevertNonLoops() {
if (Start->getOpcode() == ARM::t2WhileLoopStart)
RevertWhile(Start);
else
- RevertDo(Start);
+ RevertDo(Start);
}
for (auto *Dec : Decs)
RevertLoopDec(Dec);
for (auto *End : Ends)
RevertLoopEnd(End);
- for (auto *End : EndDecs)
- RevertLoopEndDec(End);
+ for (auto *End : EndDecs)
+ RevertLoopEndDec(End);
}
return Changed;
}
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMParallelDSP.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMParallelDSP.cpp
index cd3c3b4ca6..9a7c1f541a 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMParallelDSP.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMParallelDSP.cpp
@@ -22,7 +22,7 @@
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/LoopAccessAnalysis.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicsARM.h"
@@ -202,7 +202,7 @@ namespace {
public:
WidenedLoad(SmallVectorImpl<LoadInst*> &Lds, LoadInst *Wide)
: NewLd(Wide) {
- append_range(Loads, Lds);
+ append_range(Loads, Lds);
}
LoadInst *getLoad() {
return NewLd;
@@ -374,7 +374,7 @@ bool ARMParallelDSP::RecordMemoryOps(BasicBlock *BB) {
DepMap RAWDeps;
// Record any writes that may alias a load.
- const auto Size = LocationSize::beforeOrAfterPointer();
+ const auto Size = LocationSize::beforeOrAfterPointer();
for (auto Write : Writes) {
for (auto Read : Loads) {
MemoryLocation ReadLoc =
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMPredicates.td b/contrib/libs/llvm12/lib/Target/ARM/ARMPredicates.td
index 3c03b95e26..2dc097566d 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMPredicates.td
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMPredicates.td
@@ -77,8 +77,8 @@ def HasV8_5a : Predicate<"Subtarget->hasV8_5aOps()">,
AssemblerPredicate<(all_of HasV8_5aOps), "armv8.5a">;
def HasV8_6a : Predicate<"Subtarget->hasV8_6aOps()">,
AssemblerPredicate<(all_of HasV8_6aOps), "armv8.6a">;
-def HasV8_7a : Predicate<"Subtarget->hasV8_7aOps()">,
- AssemblerPredicate<(all_of HasV8_7aOps), "armv8.7a">;
+def HasV8_7a : Predicate<"Subtarget->hasV8_7aOps()">,
+ AssemblerPredicate<(all_of HasV8_7aOps), "armv8.7a">;
def NoVFP : Predicate<"!Subtarget->hasVFP2Base()">;
def HasVFP2 : Predicate<"Subtarget->hasVFP2Base()">,
AssemblerPredicate<(all_of FeatureVFP2_SP), "VFP2">;
@@ -189,9 +189,9 @@ let RecomputePerFunction = 1 in {
def UseFPVMLx: Predicate<"((Subtarget->useFPVMLx() &&"
" TM.Options.AllowFPOpFusion != FPOpFusion::Fast) ||"
"Subtarget->hasMinSize())">;
- def SLSBLRMitigation : Predicate<[{ MF->getSubtarget<ARMSubtarget>().hardenSlsBlr() }]>;
- def NoSLSBLRMitigation : Predicate<[{ !MF->getSubtarget<ARMSubtarget>().hardenSlsBlr() }]>;
-
+ def SLSBLRMitigation : Predicate<[{ MF->getSubtarget<ARMSubtarget>().hardenSlsBlr() }]>;
+ def NoSLSBLRMitigation : Predicate<[{ !MF->getSubtarget<ARMSubtarget>().hardenSlsBlr() }]>;
+
}
def UseMulOps : Predicate<"Subtarget->useMulOps()">;
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMRegisterBankInfo.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMRegisterBankInfo.cpp
index eb905282dc..1a7f10a13e 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMRegisterBankInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMRegisterBankInfo.cpp
@@ -156,10 +156,10 @@ ARMRegisterBankInfo::ARMRegisterBankInfo(const TargetRegisterInfo &TRI)
"Subclass not added?");
assert(RBGPR.covers(*TRI.getRegClass(ARM::tcGPRRegClassID)) &&
"Subclass not added?");
- assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRnoip_and_tcGPRRegClassID)) &&
+ assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRnoip_and_tcGPRRegClassID)) &&
"Subclass not added?");
- assert(RBGPR.covers(*TRI.getRegClass(
- ARM::tGPREven_and_GPRnoip_and_tcGPRRegClassID)) &&
+ assert(RBGPR.covers(*TRI.getRegClass(
+ ARM::tGPREven_and_GPRnoip_and_tcGPRRegClassID)) &&
"Subclass not added?");
assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPROdd_and_tcGPRRegClassID)) &&
"Subclass not added?");
@@ -182,12 +182,12 @@ ARMRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
switch (RC.getID()) {
case GPRRegClassID:
case GPRwithAPSRRegClassID:
- case GPRnoipRegClassID:
+ case GPRnoipRegClassID:
case GPRnopcRegClassID:
- case GPRnoip_and_GPRnopcRegClassID:
+ case GPRnoip_and_GPRnopcRegClassID:
case rGPRRegClassID:
case GPRspRegClassID:
- case GPRnoip_and_tcGPRRegClassID:
+ case GPRnoip_and_tcGPRRegClassID:
case tcGPRRegClassID:
case tGPRRegClassID:
case tGPREvenRegClassID:
@@ -195,7 +195,7 @@ ARMRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
case tGPR_and_tGPREvenRegClassID:
case tGPR_and_tGPROddRegClassID:
case tGPREven_and_tcGPRRegClassID:
- case tGPREven_and_GPRnoip_and_tcGPRRegClassID:
+ case tGPREven_and_GPRnoip_and_tcGPRRegClassID:
case tGPROdd_and_tcGPRRegClassID:
return getRegBank(ARM::GPRRegBankID);
case HPRRegClassID:
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMRegisterInfo.td b/contrib/libs/llvm12/lib/Target/ARM/ARMRegisterInfo.td
index 8ac3e3c402..fe3243315d 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMRegisterInfo.td
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMRegisterInfo.td
@@ -235,23 +235,23 @@ def GPR : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12),
let DiagnosticString = "operand must be a register in range [r0, r15]";
}
-// Register set that excludes registers that are reserved for procedure calls.
-// This is used for pseudo-instructions that are actually implemented using a
-// procedure call.
-def GPRnoip : RegisterClass<"ARM", [i32], 32, (sub GPR, R12, LR)> {
- // Allocate LR as the first CSR since it is always saved anyway.
- // For Thumb1 mode, we don't want to allocate hi regs at all, as we don't
- // know how to spill them. If we make our prologue/epilogue code smarter at
- // some point, we can go back to using the above allocation orders for the
- // Thumb1 instructions that know how to use hi regs.
- let AltOrders = [(add GPRnoip, GPRnoip), (trunc GPRnoip, 8),
- (add (trunc GPRnoip, 8), (shl GPRnoip, 8))];
- let AltOrderSelect = [{
- return MF.getSubtarget<ARMSubtarget>().getGPRAllocationOrder(MF);
- }];
- let DiagnosticString = "operand must be a register in range [r0, r14]";
-}
-
+// Register set that excludes registers that are reserved for procedure calls.
+// This is used for pseudo-instructions that are actually implemented using a
+// procedure call.
+def GPRnoip : RegisterClass<"ARM", [i32], 32, (sub GPR, R12, LR)> {
+ // Allocate LR as the first CSR since it is always saved anyway.
+ // For Thumb1 mode, we don't want to allocate hi regs at all, as we don't
+ // know how to spill them. If we make our prologue/epilogue code smarter at
+ // some point, we can go back to using the above allocation orders for the
+ // Thumb1 instructions that know how to use hi regs.
+ let AltOrders = [(add GPRnoip, GPRnoip), (trunc GPRnoip, 8),
+ (add (trunc GPRnoip, 8), (shl GPRnoip, 8))];
+ let AltOrderSelect = [{
+ return MF.getSubtarget<ARMSubtarget>().getGPRAllocationOrder(MF);
+ }];
+ let DiagnosticString = "operand must be a register in range [r0, r14]";
+}
+
// GPRs without the PC. Some ARM instructions do not allow the PC in
// certain operand slots, particularly as the destination. Primarily
// useful for disassembly.
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMSLSHardening.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMSLSHardening.cpp
index de2cd45c14..cfcc7d5a04 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMSLSHardening.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMSLSHardening.cpp
@@ -1,416 +1,416 @@
-//===- ARMSLSHardening.cpp - Harden Straight Line Missspeculation ---------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains a pass to insert code to mitigate against side channel
-// vulnerabilities that may happen under straight line miss-speculation.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ARM.h"
-#include "ARMInstrInfo.h"
-#include "ARMSubtarget.h"
-#include "llvm/CodeGen/IndirectThunks.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineOperand.h"
-#include "llvm/IR/DebugLoc.h"
-#include <cassert>
-
-using namespace llvm;
-
-#define DEBUG_TYPE "arm-sls-hardening"
-
-#define ARM_SLS_HARDENING_NAME "ARM sls hardening pass"
-
-namespace {
-
-class ARMSLSHardening : public MachineFunctionPass {
-public:
- const TargetInstrInfo *TII;
- const ARMSubtarget *ST;
-
- static char ID;
-
- ARMSLSHardening() : MachineFunctionPass(ID) {
- initializeARMSLSHardeningPass(*PassRegistry::getPassRegistry());
- }
-
- bool runOnMachineFunction(MachineFunction &Fn) override;
-
- StringRef getPassName() const override { return ARM_SLS_HARDENING_NAME; }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesCFG();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
-
-private:
- bool hardenReturnsAndBRs(MachineBasicBlock &MBB) const;
- bool hardenIndirectCalls(MachineBasicBlock &MBB) const;
- MachineBasicBlock &
- ConvertIndirectCallToIndirectJump(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator) const;
-};
-
-} // end anonymous namespace
-
-char ARMSLSHardening::ID = 0;
-
-INITIALIZE_PASS(ARMSLSHardening, "arm-sls-hardening",
- ARM_SLS_HARDENING_NAME, false, false)
-
-static void insertSpeculationBarrier(const ARMSubtarget *ST,
- MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MBBI,
- DebugLoc DL,
- bool AlwaysUseISBDSB = false) {
- assert(MBBI != MBB.begin() &&
- "Must not insert SpeculationBarrierEndBB as only instruction in MBB.");
- assert(std::prev(MBBI)->isBarrier() &&
- "SpeculationBarrierEndBB must only follow unconditional control flow "
- "instructions.");
- assert(std::prev(MBBI)->isTerminator() &&
- "SpeculationBarrierEndBB must only follow terminators.");
- const TargetInstrInfo *TII = ST->getInstrInfo();
- assert(ST->hasDataBarrier() || ST->hasSB());
- bool ProduceSB = ST->hasSB() && !AlwaysUseISBDSB;
- unsigned BarrierOpc =
- ProduceSB ? (ST->isThumb() ? ARM::t2SpeculationBarrierSBEndBB
- : ARM::SpeculationBarrierSBEndBB)
- : (ST->isThumb() ? ARM::t2SpeculationBarrierISBDSBEndBB
- : ARM::SpeculationBarrierISBDSBEndBB);
- if (MBBI == MBB.end() || !isSpeculationBarrierEndBBOpcode(MBBI->getOpcode()))
- BuildMI(MBB, MBBI, DL, TII->get(BarrierOpc));
-}
-
-bool ARMSLSHardening::runOnMachineFunction(MachineFunction &MF) {
- ST = &MF.getSubtarget<ARMSubtarget>();
- TII = MF.getSubtarget().getInstrInfo();
-
- bool Modified = false;
- for (auto &MBB : MF) {
- Modified |= hardenReturnsAndBRs(MBB);
- Modified |= hardenIndirectCalls(MBB);
- }
-
- return Modified;
-}
-
-bool ARMSLSHardening::hardenReturnsAndBRs(MachineBasicBlock &MBB) const {
- if (!ST->hardenSlsRetBr())
- return false;
- assert(!ST->isThumb1Only());
- bool Modified = false;
- MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator(), E = MBB.end();
- MachineBasicBlock::iterator NextMBBI;
- for (; MBBI != E; MBBI = NextMBBI) {
- MachineInstr &MI = *MBBI;
- NextMBBI = std::next(MBBI);
- if (isIndirectControlFlowNotComingBack(MI)) {
- assert(MI.isTerminator());
- assert(!TII->isPredicated(MI));
- insertSpeculationBarrier(ST, MBB, std::next(MBBI), MI.getDebugLoc());
- Modified = true;
- }
- }
- return Modified;
-}
-
-static const char SLSBLRNamePrefix[] = "__llvm_slsblr_thunk_";
-
-static const struct ThunkNameRegMode {
- const char* Name;
- Register Reg;
- bool isThumb;
-} SLSBLRThunks[] = {
- {"__llvm_slsblr_thunk_arm_r0", ARM::R0, false},
- {"__llvm_slsblr_thunk_arm_r1", ARM::R1, false},
- {"__llvm_slsblr_thunk_arm_r2", ARM::R2, false},
- {"__llvm_slsblr_thunk_arm_r3", ARM::R3, false},
- {"__llvm_slsblr_thunk_arm_r4", ARM::R4, false},
- {"__llvm_slsblr_thunk_arm_r5", ARM::R5, false},
- {"__llvm_slsblr_thunk_arm_r6", ARM::R6, false},
- {"__llvm_slsblr_thunk_arm_r7", ARM::R7, false},
- {"__llvm_slsblr_thunk_arm_r8", ARM::R8, false},
- {"__llvm_slsblr_thunk_arm_r9", ARM::R9, false},
- {"__llvm_slsblr_thunk_arm_r10", ARM::R10, false},
- {"__llvm_slsblr_thunk_arm_r11", ARM::R11, false},
- {"__llvm_slsblr_thunk_arm_sp", ARM::SP, false},
- {"__llvm_slsblr_thunk_arm_pc", ARM::PC, false},
- {"__llvm_slsblr_thunk_thumb_r0", ARM::R0, true},
- {"__llvm_slsblr_thunk_thumb_r1", ARM::R1, true},
- {"__llvm_slsblr_thunk_thumb_r2", ARM::R2, true},
- {"__llvm_slsblr_thunk_thumb_r3", ARM::R3, true},
- {"__llvm_slsblr_thunk_thumb_r4", ARM::R4, true},
- {"__llvm_slsblr_thunk_thumb_r5", ARM::R5, true},
- {"__llvm_slsblr_thunk_thumb_r6", ARM::R6, true},
- {"__llvm_slsblr_thunk_thumb_r7", ARM::R7, true},
- {"__llvm_slsblr_thunk_thumb_r8", ARM::R8, true},
- {"__llvm_slsblr_thunk_thumb_r9", ARM::R9, true},
- {"__llvm_slsblr_thunk_thumb_r10", ARM::R10, true},
- {"__llvm_slsblr_thunk_thumb_r11", ARM::R11, true},
- {"__llvm_slsblr_thunk_thumb_sp", ARM::SP, true},
- {"__llvm_slsblr_thunk_thumb_pc", ARM::PC, true},
-};
-
-namespace {
-struct SLSBLRThunkInserter : ThunkInserter<SLSBLRThunkInserter> {
- const char *getThunkPrefix() { return SLSBLRNamePrefix; }
- bool mayUseThunk(const MachineFunction &MF) {
- // FIXME: This could also check if there are any indirect calls in the
- // function to more accurately reflect if a thunk will be needed.
- return MF.getSubtarget<ARMSubtarget>().hardenSlsBlr();
- }
- void insertThunks(MachineModuleInfo &MMI);
- void populateThunk(MachineFunction &MF);
-};
-} // namespace
-
-void SLSBLRThunkInserter::insertThunks(MachineModuleInfo &MMI) {
- // FIXME: It probably would be possible to filter which thunks to produce
- // based on which registers are actually used in indirect calls in this
- // function. But would that be a worthwhile optimization?
- for (auto T : SLSBLRThunks)
- createThunkFunction(MMI, T.Name);
-}
-
-void SLSBLRThunkInserter::populateThunk(MachineFunction &MF) {
- // FIXME: How to better communicate Register number, rather than through
- // name and lookup table?
- assert(MF.getName().startswith(getThunkPrefix()));
- auto ThunkIt = llvm::find_if(
- SLSBLRThunks, [&MF](auto T) { return T.Name == MF.getName(); });
- assert(ThunkIt != std::end(SLSBLRThunks));
- Register ThunkReg = ThunkIt->Reg;
- bool isThumb = ThunkIt->isThumb;
-
- const TargetInstrInfo *TII = MF.getSubtarget<ARMSubtarget>().getInstrInfo();
- MachineBasicBlock *Entry = &MF.front();
- Entry->clear();
-
- // These thunks need to consist of the following instructions:
- // __llvm_slsblr_thunk_(arm/thumb)_rN:
- // bx rN
- // barrierInsts
- Entry->addLiveIn(ThunkReg);
- if (isThumb)
- BuildMI(Entry, DebugLoc(), TII->get(ARM::tBX))
- .addReg(ThunkReg)
- .add(predOps(ARMCC::AL));
- else
- BuildMI(Entry, DebugLoc(), TII->get(ARM::BX))
- .addReg(ThunkReg);
-
- // Make sure the thunks do not make use of the SB extension in case there is
- // a function somewhere that will call to it that for some reason disabled
- // the SB extension locally on that function, even though it's enabled for
- // the module otherwise. Therefore set AlwaysUseISBSDB to true.
- insertSpeculationBarrier(&MF.getSubtarget<ARMSubtarget>(), *Entry,
- Entry->end(), DebugLoc(), true /*AlwaysUseISBDSB*/);
-}
-
-MachineBasicBlock &ARMSLSHardening::ConvertIndirectCallToIndirectJump(
- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const {
- // Transform an indirect call to an indirect jump as follows:
- // Before:
- // |-----------------------------|
- // | ... |
- // | instI |
- // | BLX rN |
- // | instJ |
- // | ... |
- // |-----------------------------|
- //
- // After:
- // |---------- -------------------------|
- // | ... |
- // | instI |
- // | *call* __llvm_slsblr_thunk_mode_xN |
- // | instJ |
- // | ... |
- // |--------------------------------------|
- //
- // __llvm_slsblr_thunk_mode_xN:
- // |-----------------------------|
- // | BX rN |
- // | barrierInsts |
- // |-----------------------------|
- //
- // The __llvm_slsblr_thunk_mode_xN thunks are created by the
- // SLSBLRThunkInserter.
- // This function merely needs to transform an indirect call to a direct call
- // to __llvm_slsblr_thunk_xN.
- MachineInstr &IndirectCall = *MBBI;
- assert(isIndirectCall(IndirectCall) && !IndirectCall.isReturn());
- int RegOpIdxOnIndirectCall = -1;
- bool isThumb;
- switch (IndirectCall.getOpcode()) {
- case ARM::BLX: // !isThumb2
- case ARM::BLX_noip: // !isThumb2
- isThumb = false;
- RegOpIdxOnIndirectCall = 0;
- break;
- case ARM::tBLXr: // isThumb2
- case ARM::tBLXr_noip: // isThumb2
- isThumb = true;
- RegOpIdxOnIndirectCall = 2;
- break;
- default:
- llvm_unreachable("unhandled Indirect Call");
- }
-
- Register Reg = IndirectCall.getOperand(RegOpIdxOnIndirectCall).getReg();
- // Since linkers are allowed to clobber R12 on function calls, the above
- // mitigation only works if the original indirect call instruction was not
- // using R12. Code generation before must make sure that no indirect call
- // using R12 was produced if the mitigation is enabled.
- // Also, the transformation is incorrect if the indirect call uses LR, so
- // also have to avoid that.
- assert(Reg != ARM::R12 && Reg != ARM::LR);
- bool RegIsKilled = IndirectCall.getOperand(RegOpIdxOnIndirectCall).isKill();
-
- DebugLoc DL = IndirectCall.getDebugLoc();
-
- MachineFunction &MF = *MBBI->getMF();
- auto ThunkIt = llvm::find_if(SLSBLRThunks, [Reg, isThumb](auto T) {
- return T.Reg == Reg && T.isThumb == isThumb;
- });
- assert(ThunkIt != std::end(SLSBLRThunks));
- Module *M = MF.getFunction().getParent();
- const GlobalValue *GV = cast<GlobalValue>(M->getNamedValue(ThunkIt->Name));
-
- MachineInstr *BL =
- isThumb ? BuildMI(MBB, MBBI, DL, TII->get(ARM::tBL))
- .addImm(IndirectCall.getOperand(0).getImm())
- .addReg(IndirectCall.getOperand(1).getReg())
- .addGlobalAddress(GV)
- : BuildMI(MBB, MBBI, DL, TII->get(ARM::BL)).addGlobalAddress(GV);
-
- // Now copy the implicit operands from IndirectCall to BL and copy other
- // necessary info.
- // However, both IndirectCall and BL instructions implictly use SP and
- // implicitly define LR. Blindly copying implicit operands would result in SP
- // and LR operands to be present multiple times. While this may not be too
- // much of an issue, let's avoid that for cleanliness, by removing those
- // implicit operands from the BL created above before we copy over all
- // implicit operands from the IndirectCall.
- int ImpLROpIdx = -1;
- int ImpSPOpIdx = -1;
- for (unsigned OpIdx = BL->getNumExplicitOperands();
- OpIdx < BL->getNumOperands(); OpIdx++) {
- MachineOperand Op = BL->getOperand(OpIdx);
- if (!Op.isReg())
- continue;
- if (Op.getReg() == ARM::LR && Op.isDef())
- ImpLROpIdx = OpIdx;
- if (Op.getReg() == ARM::SP && !Op.isDef())
- ImpSPOpIdx = OpIdx;
- }
- assert(ImpLROpIdx != -1);
- assert(ImpSPOpIdx != -1);
- int FirstOpIdxToRemove = std::max(ImpLROpIdx, ImpSPOpIdx);
- int SecondOpIdxToRemove = std::min(ImpLROpIdx, ImpSPOpIdx);
- BL->RemoveOperand(FirstOpIdxToRemove);
- BL->RemoveOperand(SecondOpIdxToRemove);
- // Now copy over the implicit operands from the original IndirectCall
- BL->copyImplicitOps(MF, IndirectCall);
- MF.moveCallSiteInfo(&IndirectCall, BL);
- // Also add the register called in the IndirectCall as being used in the
- // called thunk.
- BL->addOperand(MachineOperand::CreateReg(Reg, false /*isDef*/, true /*isImp*/,
- RegIsKilled /*isKill*/));
- // Remove IndirectCallinstruction
- MBB.erase(MBBI);
- return MBB;
-}
-
-bool ARMSLSHardening::hardenIndirectCalls(MachineBasicBlock &MBB) const {
- if (!ST->hardenSlsBlr())
- return false;
- bool Modified = false;
- MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
- MachineBasicBlock::iterator NextMBBI;
- for (; MBBI != E; MBBI = NextMBBI) {
- MachineInstr &MI = *MBBI;
- NextMBBI = std::next(MBBI);
- // Tail calls are both indirect calls and "returns".
- // They are also indirect jumps, so should be handled by sls-harden-retbr,
- // rather than sls-harden-blr.
- if (isIndirectCall(MI) && !MI.isReturn()) {
- ConvertIndirectCallToIndirectJump(MBB, MBBI);
- Modified = true;
- }
- }
- return Modified;
-}
-
-
-
-FunctionPass *llvm::createARMSLSHardeningPass() {
- return new ARMSLSHardening();
-}
-
-namespace {
-class ARMIndirectThunks : public MachineFunctionPass {
-public:
- static char ID;
-
- ARMIndirectThunks() : MachineFunctionPass(ID) {}
-
- StringRef getPassName() const override { return "ARM Indirect Thunks"; }
-
- bool doInitialization(Module &M) override;
- bool runOnMachineFunction(MachineFunction &MF) override;
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- MachineFunctionPass::getAnalysisUsage(AU);
- AU.addRequired<MachineModuleInfoWrapperPass>();
- AU.addPreserved<MachineModuleInfoWrapperPass>();
- }
-
-private:
- std::tuple<SLSBLRThunkInserter> TIs;
-
- // FIXME: When LLVM moves to C++17, these can become folds
- template <typename... ThunkInserterT>
- static void initTIs(Module &M,
- std::tuple<ThunkInserterT...> &ThunkInserters) {
- (void)std::initializer_list<int>{
- (std::get<ThunkInserterT>(ThunkInserters).init(M), 0)...};
- }
- template <typename... ThunkInserterT>
- static bool runTIs(MachineModuleInfo &MMI, MachineFunction &MF,
- std::tuple<ThunkInserterT...> &ThunkInserters) {
- bool Modified = false;
- (void)std::initializer_list<int>{
- Modified |= std::get<ThunkInserterT>(ThunkInserters).run(MMI, MF)...};
- return Modified;
- }
-};
-
-} // end anonymous namespace
-
-char ARMIndirectThunks::ID = 0;
-
-FunctionPass *llvm::createARMIndirectThunks() {
- return new ARMIndirectThunks();
-}
-
-bool ARMIndirectThunks::doInitialization(Module &M) {
- initTIs(M, TIs);
- return false;
-}
-
-bool ARMIndirectThunks::runOnMachineFunction(MachineFunction &MF) {
- LLVM_DEBUG(dbgs() << getPassName() << '\n');
- auto &MMI = getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
- return runTIs(MMI, MF, TIs);
-}
+//===- ARMSLSHardening.cpp - Harden Straight Line Missspeculation ---------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a pass to insert code to mitigate against side channel
+// vulnerabilities that may happen under straight line miss-speculation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ARM.h"
+#include "ARMInstrInfo.h"
+#include "ARMSubtarget.h"
+#include "llvm/CodeGen/IndirectThunks.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/IR/DebugLoc.h"
+#include <cassert>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "arm-sls-hardening"
+
+#define ARM_SLS_HARDENING_NAME "ARM sls hardening pass"
+
+namespace {
+
+class ARMSLSHardening : public MachineFunctionPass {
+public:
+ const TargetInstrInfo *TII;
+ const ARMSubtarget *ST;
+
+ static char ID;
+
+ ARMSLSHardening() : MachineFunctionPass(ID) {
+ initializeARMSLSHardeningPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool runOnMachineFunction(MachineFunction &Fn) override;
+
+ StringRef getPassName() const override { return ARM_SLS_HARDENING_NAME; }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesCFG();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+private:
+ bool hardenReturnsAndBRs(MachineBasicBlock &MBB) const;
+ bool hardenIndirectCalls(MachineBasicBlock &MBB) const;
+ MachineBasicBlock &
+ ConvertIndirectCallToIndirectJump(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator) const;
+};
+
+} // end anonymous namespace
+
+char ARMSLSHardening::ID = 0;
+
+INITIALIZE_PASS(ARMSLSHardening, "arm-sls-hardening",
+ ARM_SLS_HARDENING_NAME, false, false)
+
+static void insertSpeculationBarrier(const ARMSubtarget *ST,
+ MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ DebugLoc DL,
+ bool AlwaysUseISBDSB = false) {
+ assert(MBBI != MBB.begin() &&
+ "Must not insert SpeculationBarrierEndBB as only instruction in MBB.");
+ assert(std::prev(MBBI)->isBarrier() &&
+ "SpeculationBarrierEndBB must only follow unconditional control flow "
+ "instructions.");
+ assert(std::prev(MBBI)->isTerminator() &&
+ "SpeculationBarrierEndBB must only follow terminators.");
+ const TargetInstrInfo *TII = ST->getInstrInfo();
+ assert(ST->hasDataBarrier() || ST->hasSB());
+ bool ProduceSB = ST->hasSB() && !AlwaysUseISBDSB;
+ unsigned BarrierOpc =
+ ProduceSB ? (ST->isThumb() ? ARM::t2SpeculationBarrierSBEndBB
+ : ARM::SpeculationBarrierSBEndBB)
+ : (ST->isThumb() ? ARM::t2SpeculationBarrierISBDSBEndBB
+ : ARM::SpeculationBarrierISBDSBEndBB);
+ if (MBBI == MBB.end() || !isSpeculationBarrierEndBBOpcode(MBBI->getOpcode()))
+ BuildMI(MBB, MBBI, DL, TII->get(BarrierOpc));
+}
+
+bool ARMSLSHardening::runOnMachineFunction(MachineFunction &MF) {
+ ST = &MF.getSubtarget<ARMSubtarget>();
+ TII = MF.getSubtarget().getInstrInfo();
+
+ bool Modified = false;
+ for (auto &MBB : MF) {
+ Modified |= hardenReturnsAndBRs(MBB);
+ Modified |= hardenIndirectCalls(MBB);
+ }
+
+ return Modified;
+}
+
+bool ARMSLSHardening::hardenReturnsAndBRs(MachineBasicBlock &MBB) const {
+ if (!ST->hardenSlsRetBr())
+ return false;
+ assert(!ST->isThumb1Only());
+ bool Modified = false;
+ MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator(), E = MBB.end();
+ MachineBasicBlock::iterator NextMBBI;
+ for (; MBBI != E; MBBI = NextMBBI) {
+ MachineInstr &MI = *MBBI;
+ NextMBBI = std::next(MBBI);
+ if (isIndirectControlFlowNotComingBack(MI)) {
+ assert(MI.isTerminator());
+ assert(!TII->isPredicated(MI));
+ insertSpeculationBarrier(ST, MBB, std::next(MBBI), MI.getDebugLoc());
+ Modified = true;
+ }
+ }
+ return Modified;
+}
+
+static const char SLSBLRNamePrefix[] = "__llvm_slsblr_thunk_";
+
+static const struct ThunkNameRegMode {
+ const char* Name;
+ Register Reg;
+ bool isThumb;
+} SLSBLRThunks[] = {
+ {"__llvm_slsblr_thunk_arm_r0", ARM::R0, false},
+ {"__llvm_slsblr_thunk_arm_r1", ARM::R1, false},
+ {"__llvm_slsblr_thunk_arm_r2", ARM::R2, false},
+ {"__llvm_slsblr_thunk_arm_r3", ARM::R3, false},
+ {"__llvm_slsblr_thunk_arm_r4", ARM::R4, false},
+ {"__llvm_slsblr_thunk_arm_r5", ARM::R5, false},
+ {"__llvm_slsblr_thunk_arm_r6", ARM::R6, false},
+ {"__llvm_slsblr_thunk_arm_r7", ARM::R7, false},
+ {"__llvm_slsblr_thunk_arm_r8", ARM::R8, false},
+ {"__llvm_slsblr_thunk_arm_r9", ARM::R9, false},
+ {"__llvm_slsblr_thunk_arm_r10", ARM::R10, false},
+ {"__llvm_slsblr_thunk_arm_r11", ARM::R11, false},
+ {"__llvm_slsblr_thunk_arm_sp", ARM::SP, false},
+ {"__llvm_slsblr_thunk_arm_pc", ARM::PC, false},
+ {"__llvm_slsblr_thunk_thumb_r0", ARM::R0, true},
+ {"__llvm_slsblr_thunk_thumb_r1", ARM::R1, true},
+ {"__llvm_slsblr_thunk_thumb_r2", ARM::R2, true},
+ {"__llvm_slsblr_thunk_thumb_r3", ARM::R3, true},
+ {"__llvm_slsblr_thunk_thumb_r4", ARM::R4, true},
+ {"__llvm_slsblr_thunk_thumb_r5", ARM::R5, true},
+ {"__llvm_slsblr_thunk_thumb_r6", ARM::R6, true},
+ {"__llvm_slsblr_thunk_thumb_r7", ARM::R7, true},
+ {"__llvm_slsblr_thunk_thumb_r8", ARM::R8, true},
+ {"__llvm_slsblr_thunk_thumb_r9", ARM::R9, true},
+ {"__llvm_slsblr_thunk_thumb_r10", ARM::R10, true},
+ {"__llvm_slsblr_thunk_thumb_r11", ARM::R11, true},
+ {"__llvm_slsblr_thunk_thumb_sp", ARM::SP, true},
+ {"__llvm_slsblr_thunk_thumb_pc", ARM::PC, true},
+};
+
+namespace {
+struct SLSBLRThunkInserter : ThunkInserter<SLSBLRThunkInserter> {
+ const char *getThunkPrefix() { return SLSBLRNamePrefix; }
+ bool mayUseThunk(const MachineFunction &MF) {
+ // FIXME: This could also check if there are any indirect calls in the
+ // function to more accurately reflect if a thunk will be needed.
+ return MF.getSubtarget<ARMSubtarget>().hardenSlsBlr();
+ }
+ void insertThunks(MachineModuleInfo &MMI);
+ void populateThunk(MachineFunction &MF);
+};
+} // namespace
+
+void SLSBLRThunkInserter::insertThunks(MachineModuleInfo &MMI) {
+ // FIXME: It probably would be possible to filter which thunks to produce
+ // based on which registers are actually used in indirect calls in this
+ // function. But would that be a worthwhile optimization?
+ for (auto T : SLSBLRThunks)
+ createThunkFunction(MMI, T.Name);
+}
+
+void SLSBLRThunkInserter::populateThunk(MachineFunction &MF) {
+ // FIXME: How to better communicate Register number, rather than through
+ // name and lookup table?
+ assert(MF.getName().startswith(getThunkPrefix()));
+ auto ThunkIt = llvm::find_if(
+ SLSBLRThunks, [&MF](auto T) { return T.Name == MF.getName(); });
+ assert(ThunkIt != std::end(SLSBLRThunks));
+ Register ThunkReg = ThunkIt->Reg;
+ bool isThumb = ThunkIt->isThumb;
+
+ const TargetInstrInfo *TII = MF.getSubtarget<ARMSubtarget>().getInstrInfo();
+ MachineBasicBlock *Entry = &MF.front();
+ Entry->clear();
+
+ // These thunks need to consist of the following instructions:
+ // __llvm_slsblr_thunk_(arm/thumb)_rN:
+ // bx rN
+ // barrierInsts
+ Entry->addLiveIn(ThunkReg);
+ if (isThumb)
+ BuildMI(Entry, DebugLoc(), TII->get(ARM::tBX))
+ .addReg(ThunkReg)
+ .add(predOps(ARMCC::AL));
+ else
+ BuildMI(Entry, DebugLoc(), TII->get(ARM::BX))
+ .addReg(ThunkReg);
+
+ // Make sure the thunks do not make use of the SB extension in case there is
+ // a function somewhere that will call to it that for some reason disabled
+ // the SB extension locally on that function, even though it's enabled for
+ // the module otherwise. Therefore set AlwaysUseISBSDB to true.
+ insertSpeculationBarrier(&MF.getSubtarget<ARMSubtarget>(), *Entry,
+ Entry->end(), DebugLoc(), true /*AlwaysUseISBDSB*/);
+}
+
+MachineBasicBlock &ARMSLSHardening::ConvertIndirectCallToIndirectJump(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const {
+ // Transform an indirect call to an indirect jump as follows:
+ // Before:
+ // |-----------------------------|
+ // | ... |
+ // | instI |
+ // | BLX rN |
+ // | instJ |
+ // | ... |
+ // |-----------------------------|
+ //
+ // After:
+ // |---------- -------------------------|
+ // | ... |
+ // | instI |
+ // | *call* __llvm_slsblr_thunk_mode_xN |
+ // | instJ |
+ // | ... |
+ // |--------------------------------------|
+ //
+ // __llvm_slsblr_thunk_mode_xN:
+ // |-----------------------------|
+ // | BX rN |
+ // | barrierInsts |
+ // |-----------------------------|
+ //
+ // The __llvm_slsblr_thunk_mode_xN thunks are created by the
+ // SLSBLRThunkInserter.
+ // This function merely needs to transform an indirect call to a direct call
+ // to __llvm_slsblr_thunk_xN.
+ MachineInstr &IndirectCall = *MBBI;
+ assert(isIndirectCall(IndirectCall) && !IndirectCall.isReturn());
+ int RegOpIdxOnIndirectCall = -1;
+ bool isThumb;
+ switch (IndirectCall.getOpcode()) {
+ case ARM::BLX: // !isThumb2
+ case ARM::BLX_noip: // !isThumb2
+ isThumb = false;
+ RegOpIdxOnIndirectCall = 0;
+ break;
+ case ARM::tBLXr: // isThumb2
+ case ARM::tBLXr_noip: // isThumb2
+ isThumb = true;
+ RegOpIdxOnIndirectCall = 2;
+ break;
+ default:
+ llvm_unreachable("unhandled Indirect Call");
+ }
+
+ Register Reg = IndirectCall.getOperand(RegOpIdxOnIndirectCall).getReg();
+ // Since linkers are allowed to clobber R12 on function calls, the above
+ // mitigation only works if the original indirect call instruction was not
+ // using R12. Code generation before must make sure that no indirect call
+ // using R12 was produced if the mitigation is enabled.
+ // Also, the transformation is incorrect if the indirect call uses LR, so
+ // also have to avoid that.
+ assert(Reg != ARM::R12 && Reg != ARM::LR);
+ bool RegIsKilled = IndirectCall.getOperand(RegOpIdxOnIndirectCall).isKill();
+
+ DebugLoc DL = IndirectCall.getDebugLoc();
+
+ MachineFunction &MF = *MBBI->getMF();
+ auto ThunkIt = llvm::find_if(SLSBLRThunks, [Reg, isThumb](auto T) {
+ return T.Reg == Reg && T.isThumb == isThumb;
+ });
+ assert(ThunkIt != std::end(SLSBLRThunks));
+ Module *M = MF.getFunction().getParent();
+ const GlobalValue *GV = cast<GlobalValue>(M->getNamedValue(ThunkIt->Name));
+
+ MachineInstr *BL =
+ isThumb ? BuildMI(MBB, MBBI, DL, TII->get(ARM::tBL))
+ .addImm(IndirectCall.getOperand(0).getImm())
+ .addReg(IndirectCall.getOperand(1).getReg())
+ .addGlobalAddress(GV)
+ : BuildMI(MBB, MBBI, DL, TII->get(ARM::BL)).addGlobalAddress(GV);
+
+ // Now copy the implicit operands from IndirectCall to BL and copy other
+ // necessary info.
+ // However, both IndirectCall and BL instructions implictly use SP and
+ // implicitly define LR. Blindly copying implicit operands would result in SP
+ // and LR operands to be present multiple times. While this may not be too
+ // much of an issue, let's avoid that for cleanliness, by removing those
+ // implicit operands from the BL created above before we copy over all
+ // implicit operands from the IndirectCall.
+ int ImpLROpIdx = -1;
+ int ImpSPOpIdx = -1;
+ for (unsigned OpIdx = BL->getNumExplicitOperands();
+ OpIdx < BL->getNumOperands(); OpIdx++) {
+ MachineOperand Op = BL->getOperand(OpIdx);
+ if (!Op.isReg())
+ continue;
+ if (Op.getReg() == ARM::LR && Op.isDef())
+ ImpLROpIdx = OpIdx;
+ if (Op.getReg() == ARM::SP && !Op.isDef())
+ ImpSPOpIdx = OpIdx;
+ }
+ assert(ImpLROpIdx != -1);
+ assert(ImpSPOpIdx != -1);
+ int FirstOpIdxToRemove = std::max(ImpLROpIdx, ImpSPOpIdx);
+ int SecondOpIdxToRemove = std::min(ImpLROpIdx, ImpSPOpIdx);
+ BL->RemoveOperand(FirstOpIdxToRemove);
+ BL->RemoveOperand(SecondOpIdxToRemove);
+ // Now copy over the implicit operands from the original IndirectCall
+ BL->copyImplicitOps(MF, IndirectCall);
+ MF.moveCallSiteInfo(&IndirectCall, BL);
+ // Also add the register called in the IndirectCall as being used in the
+ // called thunk.
+ BL->addOperand(MachineOperand::CreateReg(Reg, false /*isDef*/, true /*isImp*/,
+ RegIsKilled /*isKill*/));
+ // Remove IndirectCallinstruction
+ MBB.erase(MBBI);
+ return MBB;
+}
+
+bool ARMSLSHardening::hardenIndirectCalls(MachineBasicBlock &MBB) const {
+ if (!ST->hardenSlsBlr())
+ return false;
+ bool Modified = false;
+ MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
+ MachineBasicBlock::iterator NextMBBI;
+ for (; MBBI != E; MBBI = NextMBBI) {
+ MachineInstr &MI = *MBBI;
+ NextMBBI = std::next(MBBI);
+ // Tail calls are both indirect calls and "returns".
+ // They are also indirect jumps, so should be handled by sls-harden-retbr,
+ // rather than sls-harden-blr.
+ if (isIndirectCall(MI) && !MI.isReturn()) {
+ ConvertIndirectCallToIndirectJump(MBB, MBBI);
+ Modified = true;
+ }
+ }
+ return Modified;
+}
+
+
+
+FunctionPass *llvm::createARMSLSHardeningPass() {
+ return new ARMSLSHardening();
+}
+
+namespace {
+class ARMIndirectThunks : public MachineFunctionPass {
+public:
+ static char ID;
+
+ ARMIndirectThunks() : MachineFunctionPass(ID) {}
+
+ StringRef getPassName() const override { return "ARM Indirect Thunks"; }
+
+ bool doInitialization(Module &M) override;
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ MachineFunctionPass::getAnalysisUsage(AU);
+ AU.addRequired<MachineModuleInfoWrapperPass>();
+ AU.addPreserved<MachineModuleInfoWrapperPass>();
+ }
+
+private:
+ std::tuple<SLSBLRThunkInserter> TIs;
+
+ // FIXME: When LLVM moves to C++17, these can become folds
+ template <typename... ThunkInserterT>
+ static void initTIs(Module &M,
+ std::tuple<ThunkInserterT...> &ThunkInserters) {
+ (void)std::initializer_list<int>{
+ (std::get<ThunkInserterT>(ThunkInserters).init(M), 0)...};
+ }
+ template <typename... ThunkInserterT>
+ static bool runTIs(MachineModuleInfo &MMI, MachineFunction &MF,
+ std::tuple<ThunkInserterT...> &ThunkInserters) {
+ bool Modified = false;
+ (void)std::initializer_list<int>{
+ Modified |= std::get<ThunkInserterT>(ThunkInserters).run(MMI, MF)...};
+ return Modified;
+ }
+};
+
+} // end anonymous namespace
+
+char ARMIndirectThunks::ID = 0;
+
+FunctionPass *llvm::createARMIndirectThunks() {
+ return new ARMIndirectThunks();
+}
+
+bool ARMIndirectThunks::doInitialization(Module &M) {
+ initTIs(M, TIs);
+ return false;
+}
+
+bool ARMIndirectThunks::runOnMachineFunction(MachineFunction &MF) {
+ LLVM_DEBUG(dbgs() << getPassName() << '\n');
+ auto &MMI = getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
+ return runTIs(MMI, MF, TIs);
+}
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMSchedule.td b/contrib/libs/llvm12/lib/Target/ARM/ARMSchedule.td
index 503a0fbd96..53a2a6fec5 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMSchedule.td
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMSchedule.td
@@ -151,61 +151,61 @@ def : PredicateProlog<[{
(void)STI;
}]>;
-def IsPredicated : CheckFunctionPredicateWithTII<
- "ARM_MC::isPredicated",
- "isPredicated"
->;
-def IsPredicatedPred : MCSchedPredicate<IsPredicated>;
+def IsPredicated : CheckFunctionPredicateWithTII<
+ "ARM_MC::isPredicated",
+ "isPredicated"
+>;
+def IsPredicatedPred : MCSchedPredicate<IsPredicated>;
+
+def IsCPSRDefined : CheckFunctionPredicateWithTII<
+ "ARM_MC::isCPSRDefined",
+ "ARMBaseInstrInfo::isCPSRDefined"
+>;
+
+def IsCPSRDefinedPred : MCSchedPredicate<IsCPSRDefined>;
+
+let FunctionMapper = "ARM_AM::getAM2ShiftOpc" in {
+ class CheckAM2NoShift<int n> : CheckImmOperand_s<n, "ARM_AM::no_shift">;
+ class CheckAM2ShiftLSL<int n> : CheckImmOperand_s<n, "ARM_AM::lsl">;
+}
+
+let FunctionMapper = "ARM_AM::getAM2Op" in {
+ class CheckAM2OpAdd<int n> : CheckImmOperand_s<n, "ARM_AM::add"> {}
+ class CheckAM2OpSub<int n> : CheckImmOperand_s<n, "ARM_AM::sub"> {}
+}
+
+let FunctionMapper = "ARM_AM::getAM2Offset" in {
+ class CheckAM2Offset<int n, int of> : CheckImmOperand<n, of> {}
+}
+
+def IsLDMBaseRegInList : CheckFunctionPredicate<
+ "ARM_MC::isLDMBaseRegInList", "ARM_MC::isLDMBaseRegInList"
+>;
+
+let FunctionMapper = "ARM_AM::getAM3Op" in {
+ class CheckAM3OpSub<int n> : CheckImmOperand_s<n, "ARM_AM::sub"> {}
+}
+
+// LDM, base reg in list
+def IsLDMBaseRegInListPred : MCSchedPredicate<IsLDMBaseRegInList>;
+
+class IsRegPCPred<int n> : MCSchedPredicate<CheckRegOperand<n, PC>>;
+
+class BranchWriteRes<int lat, int uops, list<ProcResourceKind> resl,
+ list<int> rcl, SchedWriteRes wr> :
+ SchedWriteRes<!listconcat(wr.ProcResources, resl)> {
+ let Latency = !add(wr.Latency, lat);
+ let ResourceCycles = !listconcat(wr.ResourceCycles, rcl);
+ let NumMicroOps = !add(wr.NumMicroOps, uops);
+ SchedWriteRes BaseWr = wr;
+}
+
+class CheckBranchForm<int n, BranchWriteRes br> :
+ SchedWriteVariant<[
+ SchedVar<IsRegPCPred<n>, [br]>,
+ SchedVar<NoSchedPred, [br.BaseWr]>
+ ]>;
-def IsCPSRDefined : CheckFunctionPredicateWithTII<
- "ARM_MC::isCPSRDefined",
- "ARMBaseInstrInfo::isCPSRDefined"
->;
-
-def IsCPSRDefinedPred : MCSchedPredicate<IsCPSRDefined>;
-
-let FunctionMapper = "ARM_AM::getAM2ShiftOpc" in {
- class CheckAM2NoShift<int n> : CheckImmOperand_s<n, "ARM_AM::no_shift">;
- class CheckAM2ShiftLSL<int n> : CheckImmOperand_s<n, "ARM_AM::lsl">;
-}
-
-let FunctionMapper = "ARM_AM::getAM2Op" in {
- class CheckAM2OpAdd<int n> : CheckImmOperand_s<n, "ARM_AM::add"> {}
- class CheckAM2OpSub<int n> : CheckImmOperand_s<n, "ARM_AM::sub"> {}
-}
-
-let FunctionMapper = "ARM_AM::getAM2Offset" in {
- class CheckAM2Offset<int n, int of> : CheckImmOperand<n, of> {}
-}
-
-def IsLDMBaseRegInList : CheckFunctionPredicate<
- "ARM_MC::isLDMBaseRegInList", "ARM_MC::isLDMBaseRegInList"
->;
-
-let FunctionMapper = "ARM_AM::getAM3Op" in {
- class CheckAM3OpSub<int n> : CheckImmOperand_s<n, "ARM_AM::sub"> {}
-}
-
-// LDM, base reg in list
-def IsLDMBaseRegInListPred : MCSchedPredicate<IsLDMBaseRegInList>;
-
-class IsRegPCPred<int n> : MCSchedPredicate<CheckRegOperand<n, PC>>;
-
-class BranchWriteRes<int lat, int uops, list<ProcResourceKind> resl,
- list<int> rcl, SchedWriteRes wr> :
- SchedWriteRes<!listconcat(wr.ProcResources, resl)> {
- let Latency = !add(wr.Latency, lat);
- let ResourceCycles = !listconcat(wr.ResourceCycles, rcl);
- let NumMicroOps = !add(wr.NumMicroOps, uops);
- SchedWriteRes BaseWr = wr;
-}
-
-class CheckBranchForm<int n, BranchWriteRes br> :
- SchedWriteVariant<[
- SchedVar<IsRegPCPred<n>, [br]>,
- SchedVar<NoSchedPred, [br.BaseWr]>
- ]>;
-
//===----------------------------------------------------------------------===//
// Instruction Itinerary classes used for ARM
//
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleA57.td b/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleA57.td
index fe8c220db4..0c610a4839 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleA57.td
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleA57.td
@@ -21,47 +21,47 @@
// Therefore, IssueWidth is set to the narrower of the two at three, while still
// modeling the machine as out-of-order.
-def IsCPSRDefinedAndPredicated : CheckAll<[IsCPSRDefined, IsPredicated]>;
+def IsCPSRDefinedAndPredicated : CheckAll<[IsCPSRDefined, IsPredicated]>;
def IsCPSRDefinedAndPredicatedPred :
- MCSchedPredicate<IsCPSRDefinedAndPredicated>;
+ MCSchedPredicate<IsCPSRDefinedAndPredicated>;
// Cortex A57 rev. r1p0 or later (false = r0px)
-def IsR1P0AndLaterPred : MCSchedPredicate<FalsePred>;
+def IsR1P0AndLaterPred : MCSchedPredicate<FalsePred>;
-def IsLdrAm3RegOffPred : MCSchedPredicate<CheckInvalidRegOperand<2>>;
-def IsLdrAm3RegOffPredX2 : MCSchedPredicate<CheckInvalidRegOperand<3>>;
-def IsLdrAm3RegOffPredX3 : MCSchedPredicate<CheckInvalidRegOperand<4>>;
+def IsLdrAm3RegOffPred : MCSchedPredicate<CheckInvalidRegOperand<2>>;
+def IsLdrAm3RegOffPredX2 : MCSchedPredicate<CheckInvalidRegOperand<3>>;
+def IsLdrAm3RegOffPredX3 : MCSchedPredicate<CheckInvalidRegOperand<4>>;
// If Addrmode3 contains "minus register"
-class Am3NegativeRegOffset<int n> : MCSchedPredicate<CheckAll<[
- CheckValidRegOperand<n>,
- CheckAM3OpSub<!add(n, 1)>]>>;
-
-def IsLdrAm3NegRegOffPred : Am3NegativeRegOffset<2>;
-def IsLdrAm3NegRegOffPredX2 : Am3NegativeRegOffset<3>;
-def IsLdrAm3NegRegOffPredX3 : Am3NegativeRegOffset<4>;
-
+class Am3NegativeRegOffset<int n> : MCSchedPredicate<CheckAll<[
+ CheckValidRegOperand<n>,
+ CheckAM3OpSub<!add(n, 1)>]>>;
+
+def IsLdrAm3NegRegOffPred : Am3NegativeRegOffset<2>;
+def IsLdrAm3NegRegOffPredX2 : Am3NegativeRegOffset<3>;
+def IsLdrAm3NegRegOffPredX3 : Am3NegativeRegOffset<4>;
+
// Load, scaled register offset, not plus LSL2
-class ScaledRegNotPlusLsl2<int n> : CheckNot<
- CheckAny<[
- CheckAM2NoShift<n>,
- CheckAll<[
- CheckAM2OpAdd<n>,
- CheckAM2ShiftLSL<n>,
- CheckAM2Offset<n, 2>
- ]>
- ]>
- >;
-
-def IsLdstsoScaledNotOptimalPredX0 : MCSchedPredicate<ScaledRegNotPlusLsl2<2>>;
-def IsLdstsoScaledNotOptimalPred : MCSchedPredicate<ScaledRegNotPlusLsl2<3>>;
-def IsLdstsoScaledNotOptimalPredX2 : MCSchedPredicate<ScaledRegNotPlusLsl2<4>>;
-
-def IsLdstsoScaledPredX2 : MCSchedPredicate<CheckNot<CheckAM2NoShift<4>>>;
-
-def IsLdstsoMinusRegPredX0 : MCSchedPredicate<CheckAM2OpSub<2>>;
-def IsLdstsoMinusRegPred : MCSchedPredicate<CheckAM2OpSub<3>>;
-def IsLdstsoMinusRegPredX2 : MCSchedPredicate<CheckAM2OpSub<4>>;
+class ScaledRegNotPlusLsl2<int n> : CheckNot<
+ CheckAny<[
+ CheckAM2NoShift<n>,
+ CheckAll<[
+ CheckAM2OpAdd<n>,
+ CheckAM2ShiftLSL<n>,
+ CheckAM2Offset<n, 2>
+ ]>
+ ]>
+ >;
+
+def IsLdstsoScaledNotOptimalPredX0 : MCSchedPredicate<ScaledRegNotPlusLsl2<2>>;
+def IsLdstsoScaledNotOptimalPred : MCSchedPredicate<ScaledRegNotPlusLsl2<3>>;
+def IsLdstsoScaledNotOptimalPredX2 : MCSchedPredicate<ScaledRegNotPlusLsl2<4>>;
+
+def IsLdstsoScaledPredX2 : MCSchedPredicate<CheckNot<CheckAM2NoShift<4>>>;
+
+def IsLdstsoMinusRegPredX0 : MCSchedPredicate<CheckAM2OpSub<2>>;
+def IsLdstsoMinusRegPred : MCSchedPredicate<CheckAM2OpSub<3>>;
+def IsLdstsoMinusRegPredX2 : MCSchedPredicate<CheckAM2OpSub<4>>;
class A57WriteLMOpsListType<list<SchedWriteRes> writes> {
list <SchedWriteRes> Writes = writes;
@@ -173,29 +173,29 @@ def : InstRW<[A57Write_6cyc_1B_1L], (instregex "BR_JTm")>;
def : InstRW<[A57Write_1cyc_1I], (instregex "tADDframe")>;
-// Check branch forms of ALU ops:
-// check reg 0 for ARM_AM::PC
-// if so adds 2 cyc to latency, 1 uop, 1 res cycle for A57UnitB
-class A57BranchForm<SchedWriteRes non_br> :
- BranchWriteRes<2, 1, [A57UnitB], [1], non_br>;
-
+// Check branch forms of ALU ops:
+// check reg 0 for ARM_AM::PC
+// if so adds 2 cyc to latency, 1 uop, 1 res cycle for A57UnitB
+class A57BranchForm<SchedWriteRes non_br> :
+ BranchWriteRes<2, 1, [A57UnitB], [1], non_br>;
+
// shift by register, conditional or unconditional
// TODO: according to the doc, conditional uses I0/I1, unconditional uses M
// Why more complex instruction uses more simple pipeline?
// May be an error in doc.
def A57WriteALUsr : SchedWriteVariant<[
- SchedVar<IsPredicatedPred, [CheckBranchForm<0, A57BranchForm<A57Write_2cyc_1I>>]>,
- SchedVar<NoSchedPred, [CheckBranchForm<0, A57BranchForm<A57Write_2cyc_1M>>]>
+ SchedVar<IsPredicatedPred, [CheckBranchForm<0, A57BranchForm<A57Write_2cyc_1I>>]>,
+ SchedVar<NoSchedPred, [CheckBranchForm<0, A57BranchForm<A57Write_2cyc_1M>>]>
]>;
def A57WriteALUSsr : SchedWriteVariant<[
- SchedVar<IsPredicatedPred, [CheckBranchForm<0, A57BranchForm<A57Write_2cyc_1I>>]>,
- SchedVar<NoSchedPred, [CheckBranchForm<0, A57BranchForm<A57Write_2cyc_1M>>]>
+ SchedVar<IsPredicatedPred, [CheckBranchForm<0, A57BranchForm<A57Write_2cyc_1I>>]>,
+ SchedVar<NoSchedPred, [CheckBranchForm<0, A57BranchForm<A57Write_2cyc_1M>>]>
]>;
def A57ReadALUsr : SchedReadVariant<[
SchedVar<IsPredicatedPred, [ReadDefault]>,
SchedVar<NoSchedPred, [ReadDefault]>
]>;
-def : SchedAlias<WriteALUsi, CheckBranchForm<0, A57BranchForm<A57Write_2cyc_1M>>>;
+def : SchedAlias<WriteALUsi, CheckBranchForm<0, A57BranchForm<A57Write_2cyc_1M>>>;
def : SchedAlias<WriteALUsr, A57WriteALUsr>;
def : SchedAlias<WriteALUSsr, A57WriteALUSsr>;
def : SchedAlias<ReadALUsr, A57ReadALUsr>;
@@ -271,11 +271,11 @@ def : ReadAdvance<ReadMUL, 0>;
// from similar μops, allowing a typical sequence of multiply-accumulate μops
// to issue one every 1 cycle (sched advance = 2).
def A57WriteMLA : SchedWriteRes<[A57UnitM]> { let Latency = 3; }
-def A57WriteMLAL : SchedWriteVariant<[
- SchedVar<IsCPSRDefinedPred, [A57Write_5cyc_1I_1M]>,
- SchedVar<NoSchedPred, [A57Write_4cyc_1M]>
-]>;
-
+def A57WriteMLAL : SchedWriteVariant<[
+ SchedVar<IsCPSRDefinedPred, [A57Write_5cyc_1I_1M]>,
+ SchedVar<NoSchedPred, [A57Write_4cyc_1M]>
+]>;
+
def A57ReadMLA : SchedReadAdvance<2, [A57WriteMLA, A57WriteMLAL]>;
def : InstRW<[A57WriteMLA],
@@ -470,11 +470,11 @@ def : InstRW<[A57Write_4cyc_1L_1I, A57WrBackTwo], (instregex "LDR_POST_REG",
"LDRB_POST_REG", "LDR(B?)T_POST$")>;
def A57WriteLdrTRegPost : SchedWriteVariant<[
- SchedVar<IsLdstsoScaledPredX2, [A57Write_4cyc_1I_1L_1M]>,
+ SchedVar<IsLdstsoScaledPredX2, [A57Write_4cyc_1I_1L_1M]>,
SchedVar<NoSchedPred, [A57Write_4cyc_1L_1I]>
]>;
def A57WriteLdrTRegPostWrBack : SchedWriteVariant<[
- SchedVar<IsLdstsoScaledPredX2, [A57WrBackThree]>,
+ SchedVar<IsLdstsoScaledPredX2, [A57WrBackThree]>,
SchedVar<NoSchedPred, [A57WrBackTwo]>
]>;
// 4(3) "I0/I1,L,M" for scaled register, otherwise 4(2) "I0/I1,L"
@@ -510,12 +510,12 @@ def : InstRW<[A57WritePLD], (instregex "PLDrs", "PLDWrs")>;
// --- Load multiple instructions ---
foreach NumAddr = 1-8 in {
- def A57LMAddrPred#NumAddr : MCSchedPredicate<CheckAny<[
- CheckNumOperands<!add(!shl(NumAddr, 1), 2)>,
- CheckNumOperands<!add(!shl(NumAddr, 1), 3)>]>>;
- def A57LMAddrUpdPred#NumAddr : MCSchedPredicate<CheckAny<[
- CheckNumOperands<!add(!shl(NumAddr, 1), 3)>,
- CheckNumOperands<!add(!shl(NumAddr, 1), 4)>]>>;
+ def A57LMAddrPred#NumAddr : MCSchedPredicate<CheckAny<[
+ CheckNumOperands<!add(!shl(NumAddr, 1), 2)>,
+ CheckNumOperands<!add(!shl(NumAddr, 1), 3)>]>>;
+ def A57LMAddrUpdPred#NumAddr : MCSchedPredicate<CheckAny<[
+ CheckNumOperands<!add(!shl(NumAddr, 1), 3)>,
+ CheckNumOperands<!add(!shl(NumAddr, 1), 4)>]>>;
}
def A57LDMOpsListNoregin : A57WriteLMOpsListType<
@@ -571,20 +571,20 @@ def A57LDMOpsList_Upd : A57WriteLMOpsListType<
A57Write_9cyc_1L_1I, A57Write_9cyc_1L_1I,
A57Write_10cyc_1L_1I, A57Write_10cyc_1L_1I]>;
def A57WriteLDM_Upd : SchedWriteVariant<[
- SchedVar<A57LMAddrUpdPred1, A57LDMOpsList_Upd.Writes[0-2]>,
- SchedVar<A57LMAddrUpdPred2, A57LDMOpsList_Upd.Writes[0-4]>,
- SchedVar<A57LMAddrUpdPred3, A57LDMOpsList_Upd.Writes[0-6]>,
- SchedVar<A57LMAddrUpdPred4, A57LDMOpsList_Upd.Writes[0-8]>,
- SchedVar<A57LMAddrUpdPred5, A57LDMOpsList_Upd.Writes[0-10]>,
- SchedVar<A57LMAddrUpdPred6, A57LDMOpsList_Upd.Writes[0-12]>,
- SchedVar<A57LMAddrUpdPred7, A57LDMOpsList_Upd.Writes[0-14]>,
- SchedVar<A57LMAddrUpdPred8, A57LDMOpsList_Upd.Writes[0-16]>,
- SchedVar<NoSchedPred, A57LDMOpsList_Upd.Writes[0-16]>
+ SchedVar<A57LMAddrUpdPred1, A57LDMOpsList_Upd.Writes[0-2]>,
+ SchedVar<A57LMAddrUpdPred2, A57LDMOpsList_Upd.Writes[0-4]>,
+ SchedVar<A57LMAddrUpdPred3, A57LDMOpsList_Upd.Writes[0-6]>,
+ SchedVar<A57LMAddrUpdPred4, A57LDMOpsList_Upd.Writes[0-8]>,
+ SchedVar<A57LMAddrUpdPred5, A57LDMOpsList_Upd.Writes[0-10]>,
+ SchedVar<A57LMAddrUpdPred6, A57LDMOpsList_Upd.Writes[0-12]>,
+ SchedVar<A57LMAddrUpdPred7, A57LDMOpsList_Upd.Writes[0-14]>,
+ SchedVar<A57LMAddrUpdPred8, A57LDMOpsList_Upd.Writes[0-16]>,
+ SchedVar<NoSchedPred, A57LDMOpsList_Upd.Writes[0-16]>
]> { let Variadic=1; }
def A57WriteLDM : SchedWriteVariant<[
- SchedVar<IsLDMBaseRegInListPred, [A57WriteLDMreginlist]>,
- SchedVar<NoSchedPred, [A57WriteLDMnoreginlist]>
+ SchedVar<IsLDMBaseRegInListPred, [A57WriteLDMreginlist]>,
+ SchedVar<NoSchedPred, [A57WriteLDMnoreginlist]>
]> { let Variadic=1; }
def : InstRW<[A57WriteLDM], (instregex "(t|t2|sys)?LDM(IA|DA|DB|IB)$")>;
@@ -1194,7 +1194,7 @@ def : InstRW<[A57Write_5cyc_1V], (instregex
// --- 3.16 ASIMD Miscellaneous Instructions ---
// ASIMD bitwise insert
-def : InstRW<[A57Write_3cyc_1V], (instregex "VBIF", "VBIT", "VBSL", "VBSP")>;
+def : InstRW<[A57Write_3cyc_1V], (instregex "VBIF", "VBIT", "VBSL", "VBSP")>;
// ASIMD count
def : InstRW<[A57Write_3cyc_1V], (instregex "VCLS", "VCLZ", "VCNT")>;
@@ -1483,7 +1483,7 @@ def : InstRW<[A57Write_3cyc_1W], (instregex "^(t2)?CRC32")>;
// -----------------------------------------------------------------------------
// Common definitions
def : WriteRes<WriteNoop, []> { let Latency = 0; let NumMicroOps = 0; }
-def : SchedAlias<WriteALU, CheckBranchForm<0, A57BranchForm<A57Write_1cyc_1I>>>;
+def : SchedAlias<WriteALU, CheckBranchForm<0, A57BranchForm<A57Write_1cyc_1I>>>;
def : SchedAlias<WriteBr, A57Write_1cyc_1B>;
def : SchedAlias<WriteBrL, A57Write_1cyc_1B_1I>;
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleA57WriteRes.td b/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleA57WriteRes.td
index 3ed917682c..531b10bc5c 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleA57WriteRes.td
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleA57WriteRes.td
@@ -36,16 +36,16 @@ def A57Write_19cyc_1M : SchedWriteRes<[A57UnitM]> { let Latency = 19;
def A57Write_20cyc_1M : SchedWriteRes<[A57UnitM]> { let Latency = 20;
let ResourceCycles = [20]; }
def A57Write_1cyc_1B : SchedWriteRes<[A57UnitB]> { let Latency = 1; }
-def A57Write_1cyc_1I : SchedWriteRes<[A57UnitI]> { let Latency = 1;
- let ResourceCycles = [1]; }
-def A57Write_2cyc_1I : SchedWriteRes<[A57UnitI]> { let Latency = 2;
- let ResourceCycles = [1]; }
+def A57Write_1cyc_1I : SchedWriteRes<[A57UnitI]> { let Latency = 1;
+ let ResourceCycles = [1]; }
+def A57Write_2cyc_1I : SchedWriteRes<[A57UnitI]> { let Latency = 2;
+ let ResourceCycles = [1]; }
def A57Write_3cyc_1I : SchedWriteRes<[A57UnitI]> { let Latency = 3; }
def A57Write_1cyc_1S : SchedWriteRes<[A57UnitS]> { let Latency = 1; }
def A57Write_2cyc_1S : SchedWriteRes<[A57UnitS]> { let Latency = 2; }
def A57Write_3cyc_1S : SchedWriteRes<[A57UnitS]> { let Latency = 3; }
-def A57Write_2cyc_1M : SchedWriteRes<[A57UnitM]> { let Latency = 2;
- let ResourceCycles = [1]; }
+def A57Write_2cyc_1M : SchedWriteRes<[A57UnitM]> { let Latency = 2;
+ let ResourceCycles = [1]; }
def A57Write_32cyc_1W : SchedWriteRes<[A57UnitW]> { let Latency = 32;
let ResourceCycles = [32]; }
def A57Write_32cyc_1X : SchedWriteRes<[A57UnitX]> { let Latency = 32;
@@ -71,7 +71,7 @@ foreach Lat = 4-16 in {
}
}
-def A57Write_4cyc_1M : SchedWriteRes<[A57UnitM]> { let Latency = 4; }
+def A57Write_4cyc_1M : SchedWriteRes<[A57UnitM]> { let Latency = 4; }
def A57Write_4cyc_1X : SchedWriteRes<[A57UnitX]> { let Latency = 4; }
def A57Write_4cyc_1W : SchedWriteRes<[A57UnitW]> { let Latency = 4; }
def A57Write_5cyc_1X : SchedWriteRes<[A57UnitX]> { let Latency = 5; }
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleA9.td b/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleA9.td
index dfda6c6b4b..be7017a7b4 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleA9.td
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleA9.td
@@ -2525,8 +2525,8 @@ def : ReadAdvance<ReadFPMAC, 0>;
def : InstRW< [WriteALU],
(instregex "ANDri", "ORRri", "EORri", "BICri", "ANDrr", "ORRrr", "EORrr",
"BICrr")>;
-def : InstRW< [WriteALUsi], (instrs ANDrsi, ORRrsi, EORrsi, BICrsi)>;
-def : InstRW< [WriteALUsr], (instrs ANDrsr, ORRrsr, EORrsr, BICrsr)>;
+def : InstRW< [WriteALUsi], (instrs ANDrsi, ORRrsi, EORrsi, BICrsi)>;
+def : InstRW< [WriteALUsr], (instrs ANDrsr, ORRrsr, EORrsr, BICrsr)>;
def : SchedAlias<WriteCMP, A9WriteALU>;
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleM7.td b/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleM7.td
index c5e1d32e8d..12296ad092 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleM7.td
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleM7.td
@@ -1,488 +1,488 @@
-//=- ARMScheduleM7.td - ARM Cortex-M7 Scheduling Definitions -*- tablegen -*-=//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the SchedRead/Write data for the ARM Cortex-M7 processor.
-//
-//===----------------------------------------------------------------------===//
-
-def CortexM7Model : SchedMachineModel {
- let IssueWidth = 2; // Dual issue for most instructions.
- let MicroOpBufferSize = 0; // The Cortex-M7 is in-order.
- let LoadLatency = 2; // Best case for load-use case.
- let MispredictPenalty = 4; // Mispredict cost for forward branches is 6,
- // but 4 works better
- let CompleteModel = 0;
-}
-
-//===--------------------------------------------------------------------===//
-// The Cortex-M7 has two ALU, two LOAD, a STORE, a MAC, a BRANCH and a VFP
-// pipe. The stages relevant to scheduling are as follows:
-//
-// EX1: address generation shifts
-// EX2: fast load data ALUs FP operation
-// EX3: slow load data integer writeback FP operation
-// EX4: store data FP writeback
-//
-// There are shifters in both EX1 and EX2, and some instructions can be
-// flexibly allocated between them. EX2 is used as the "zero" point
-// for scheduling, so simple ALU operations executing in EX2 will have
-// ReadAdvance<0> (the default) for their source operands and Latency = 1.
-
-def M7UnitLoad : ProcResource<2> { let BufferSize = 0; }
-def M7UnitStore : ProcResource<1> { let BufferSize = 0; }
-def M7UnitALU : ProcResource<2>;
-def M7UnitShift1 : ProcResource<1> { let BufferSize = 0; }
-def M7UnitShift2 : ProcResource<1> { let BufferSize = 0; }
-def M7UnitMAC : ProcResource<1> { let BufferSize = 0; }
-def M7UnitBranch : ProcResource<1> { let BufferSize = 0; }
-def M7UnitVFP : ProcResource<1> { let BufferSize = 0; }
-def M7UnitVPort : ProcResource<2> { let BufferSize = 0; }
-def M7UnitSIMD : ProcResource<1> { let BufferSize = 0; }
-
-//===---------------------------------------------------------------------===//
-// Subtarget-specific SchedWrite types with map ProcResources and set latency.
-
-let SchedModel = CortexM7Model in {
-
-def : WriteRes<WriteALU, [M7UnitALU]> { let Latency = 1; }
-
-// Basic ALU with shifts.
-let Latency = 1 in {
- def : WriteRes<WriteALUsi, [M7UnitALU, M7UnitShift1]>;
- def : WriteRes<WriteALUsr, [M7UnitALU, M7UnitShift1]>;
- def : WriteRes<WriteALUSsr, [M7UnitALU, M7UnitShift1]>;
-}
-
-// Compares.
-def : WriteRes<WriteCMP, [M7UnitALU]> { let Latency = 1; }
-def : WriteRes<WriteCMPsi, [M7UnitALU, M7UnitShift1]> { let Latency = 2; }
-def : WriteRes<WriteCMPsr, [M7UnitALU, M7UnitShift1]> { let Latency = 2; }
-
-// Multiplies.
-let Latency = 2 in {
- def : WriteRes<WriteMUL16, [M7UnitMAC]>;
- def : WriteRes<WriteMUL32, [M7UnitMAC]>;
- def : WriteRes<WriteMUL64Lo, [M7UnitMAC]>;
- def : WriteRes<WriteMUL64Hi, []> { let NumMicroOps = 0; }
-}
-
-// Multiply-accumulates.
-let Latency = 2 in {
- def : WriteRes<WriteMAC16, [M7UnitMAC]>;
- def : WriteRes<WriteMAC32, [M7UnitMAC]>;
- def : WriteRes<WriteMAC64Lo, [M7UnitMAC]> { let Latency = 2; }
- def : WriteRes<WriteMAC64Hi, []> { let NumMicroOps = 0; }
-}
-
-// Divisions.
-// These cannot be dual-issued with any instructions.
-def : WriteRes<WriteDIV, [M7UnitALU]> {
- let Latency = 7;
- let SingleIssue = 1;
-}
-
-// Loads/Stores.
-def : WriteRes<WriteLd, [M7UnitLoad]> { let Latency = 1; }
-def : WriteRes<WritePreLd, [M7UnitLoad]> { let Latency = 2; }
-def : WriteRes<WriteST, [M7UnitStore]> { let Latency = 2; }
-
-// Branches.
-def : WriteRes<WriteBr, [M7UnitBranch]> { let Latency = 2; }
-def : WriteRes<WriteBrL, [M7UnitBranch]> { let Latency = 2; }
-def : WriteRes<WriteBrTbl, [M7UnitBranch]> { let Latency = 2; }
-
-// Noop.
-def : WriteRes<WriteNoop, []> { let Latency = 0; }
-
-//===---------------------------------------------------------------------===//
-// Sched definitions for floating-point instructions
-//
-// Floating point conversions.
-def : WriteRes<WriteFPCVT, [M7UnitVFP, M7UnitVPort]> { let Latency = 3; }
-def : WriteRes<WriteFPMOV, [M7UnitVPort]> { let Latency = 3; }
-
-// The FP pipeline has a latency of 3 cycles.
-// ALU operations (32/64-bit). These go down the FP pipeline.
-def : WriteRes<WriteFPALU32, [M7UnitVFP, M7UnitVPort]> { let Latency = 3; }
-def : WriteRes<WriteFPALU64, [M7UnitVFP, M7UnitVPort, M7UnitVPort]> {
- let Latency = 4;
- let BeginGroup = 1;
-}
-
-// Multiplication
-def : WriteRes<WriteFPMUL32, [M7UnitVFP, M7UnitVPort]> { let Latency = 3; }
-def : WriteRes<WriteFPMUL64, [M7UnitVFP, M7UnitVPort, M7UnitVPort]> {
- let Latency = 7;
- let BeginGroup = 1;
-}
-
-// Multiply-accumulate. FPMAC goes down the FP Pipeline.
-def : WriteRes<WriteFPMAC32, [M7UnitVFP, M7UnitVPort]> { let Latency = 6; }
-def : WriteRes<WriteFPMAC64, [M7UnitVFP, M7UnitVPort, M7UnitVPort]> {
- let Latency = 11;
- let BeginGroup = 1;
-}
-
-// Division. Effective scheduling latency is 3, though real latency is larger
-def : WriteRes<WriteFPDIV32, [M7UnitVFP, M7UnitVPort]> { let Latency = 16; }
-def : WriteRes<WriteFPDIV64, [M7UnitVFP, M7UnitVPort, M7UnitVPort]> {
- let Latency = 30;
- let BeginGroup = 1;
-}
-
-// Square-root. Effective scheduling latency is 3; real latency is larger
-def : WriteRes<WriteFPSQRT32, [M7UnitVFP, M7UnitVPort]> { let Latency = 16; }
-def : WriteRes<WriteFPSQRT64, [M7UnitVFP, M7UnitVPort, M7UnitVPort]> {
- let Latency = 30;
- let BeginGroup = 1;
-}
-
-def M7WriteShift2 : SchedWriteRes<[M7UnitALU, M7UnitShift2]> {}
-
-// Not used for M7, but needing definitions anyway
-def : WriteRes<WriteVLD1, []>;
-def : WriteRes<WriteVLD2, []>;
-def : WriteRes<WriteVLD3, []>;
-def : WriteRes<WriteVLD4, []>;
-def : WriteRes<WriteVST1, []>;
-def : WriteRes<WriteVST2, []>;
-def : WriteRes<WriteVST3, []>;
-def : WriteRes<WriteVST4, []>;
-
-def M7SingleIssue : SchedWriteRes<[]> {
- let SingleIssue = 1;
- let NumMicroOps = 0;
-}
-def M7Slot0Only : SchedWriteRes<[]> {
- let BeginGroup = 1;
- let NumMicroOps = 0;
-}
-
-// What pipeline stage operands need to be ready for depending on
-// where they come from.
-def : ReadAdvance<ReadALUsr, 0>;
-def : ReadAdvance<ReadMUL, 0>;
-def : ReadAdvance<ReadMAC, 1>;
-def : ReadAdvance<ReadALU, 0>;
-def : ReadAdvance<ReadFPMUL, 0>;
-def : ReadAdvance<ReadFPMAC, 3>;
-def M7Read_ISS : SchedReadAdvance<-1>; // operands needed at EX1
-def M7Read_EX2 : SchedReadAdvance<1>; // operands needed at EX3
-def M7Read_EX3 : SchedReadAdvance<2>; // operands needed at EX4
-
-// Non general purpose instructions may not be dual issued. These
-// use both issue units.
-def M7NonGeneralPurpose : SchedWriteRes<[]> {
- // Assume that these will go down the main ALU pipeline.
- // In reality, many look likely to stall the whole pipeline.
- let Latency = 3;
- let SingleIssue = 1;
-}
-
-// List the non general purpose instructions.
-def : InstRW<[M7NonGeneralPurpose], (instregex "t2MRS", "tSVC", "tBKPT",
- "t2MSR", "t2DMB", "t2DSB", "t2ISB",
- "t2HVC", "t2SMC", "t2UDF", "ERET",
- "tHINT", "t2HINT", "t2CLREX", "BUNDLE")>;
-
-//===---------------------------------------------------------------------===//
-// Sched definitions for load/store
-//
-// Mark whether the loads/stores must be single-issue
-// Address operands are needed earlier
-// Data operands are needed later
-
-def M7BaseUpdate : SchedWriteRes<[]> {
- let Latency = 0; // Update is bypassable out of EX1
- let NumMicroOps = 0;
-}
-def M7LoadLatency1 : SchedWriteRes<[]> {
- let Latency = 1;
- let NumMicroOps = 0;
-}
-def M7SlowLoad : SchedWriteRes<[M7UnitLoad]> { let Latency = 2; }
-
-// Byte and half-word loads should have greater latency than other loads.
-// So should load exclusive.
-
-def : InstRW<[M7SlowLoad],
- (instregex "t2LDR(B|H|SB|SH)pc")>;
-def : InstRW<[M7SlowLoad, M7Read_ISS],
- (instregex "t2LDR(B|H|SB|SH)T", "t2LDR(B|H|SB|SH)i",
- "tLDR(B|H)i")>;
-def : InstRW<[M7SlowLoad, M7Read_ISS, M7Read_ISS],
- (instregex "t2LDR(B|H|SB|SH)s", "tLDR(B|H)r", "tLDR(SB|SH)")>;
-def : InstRW<[M7SlowLoad, M7BaseUpdate, M7Read_ISS],
- (instregex "t2LDR(B|H|SB|SH)_(POST|PRE)")>;
-
-// Exclusive loads/stores cannot be dual-issued
-def : InstRW<[WriteLd, M7Slot0Only, M7Read_ISS],
- (instregex "t2LDREX$")>;
-def : InstRW<[M7SlowLoad, M7Slot0Only, M7Read_ISS],
- (instregex "t2LDREX(B|H)")>;
-def : InstRW<[WriteST, M7SingleIssue, M7Read_EX2, M7Read_ISS],
- (instregex "t2STREX(B|H)?$")>;
-
-// Load/store multiples cannot be dual-issued. Note that default scheduling
-// occurs around read/write times of individual registers in the list; read
-// time for STM cannot be overridden because it is a variadic source operand.
-
-def : InstRW<[WriteLd, M7SingleIssue, M7Read_ISS],
- (instregex "(t|t2)LDM(DB|IA)$")>;
-def : InstRW<[WriteST, M7SingleIssue, M7Read_ISS],
- (instregex "(t|t2)STM(DB|IA)$")>;
-def : InstRW<[M7BaseUpdate, WriteLd, M7SingleIssue, M7Read_ISS],
- (instregex "(t|t2)LDM(DB|IA)_UPD$", "tPOP")>;
-def : InstRW<[M7BaseUpdate, WriteST, M7SingleIssue, M7Read_ISS],
- (instregex "(t|t2)STM(DB|IA)_UPD$", "tPUSH")>;
-
-// Load/store doubles cannot be dual-issued.
-
-def : InstRW<[M7BaseUpdate, WriteST, M7SingleIssue,
- M7Read_EX2, M7Read_EX2, M7Read_ISS],
- (instregex "t2STRD_(PRE|POST)")>;
-def : InstRW<[WriteST, M7SingleIssue, M7Read_EX2, M7Read_EX2, M7Read_ISS],
- (instregex "t2STRDi")>;
-def : InstRW<[WriteLd, M7LoadLatency1, M7SingleIssue, M7BaseUpdate, M7Read_ISS],
- (instregex "t2LDRD_(PRE|POST)")>;
-def : InstRW<[WriteLd, M7LoadLatency1, M7SingleIssue, M7Read_ISS],
- (instregex "t2LDRDi")>;
-
-// Word load / preload
-def : InstRW<[WriteLd],
- (instregex "t2LDRpc", "t2PL[DI]pci", "tLDRpci")>;
-def : InstRW<[WriteLd, M7Read_ISS],
- (instregex "t2LDR(i|T)", "t2PL[DI](W)?i", "tLDRi", "tLDRspi")>;
-def : InstRW<[WriteLd, M7Read_ISS, M7Read_ISS],
- (instregex "t2LDRs", "t2PL[DI](w)?s", "tLDRr")>;
-def : InstRW<[WriteLd, M7BaseUpdate, M7Read_ISS],
- (instregex "t2LDR_(POST|PRE)")>;
-
-// Stores
-def : InstRW<[M7BaseUpdate, WriteST, M7Read_EX2, M7Read_ISS],
- (instregex "t2STR(B|H)?_(POST|PRE)")>;
-def : InstRW<[WriteST, M7Read_EX2, M7Read_ISS, M7Read_ISS],
- (instregex "t2STR(B|H)?s$", "tSTR(B|H)?r$")>;
-def : InstRW<[WriteST, M7Read_EX2, M7Read_ISS],
- (instregex "t2STR(B|H)?(i|T)", "tSTR(B|H)?i$", "tSTRspi")>;
-
-// TBB/TBH - single-issue only; takes two cycles to issue
-
-def M7TableLoad : SchedWriteRes<[M7UnitLoad]> {
- let NumMicroOps = 2;
- let SingleIssue = 1;
-}
-
-def : InstRW<[M7TableLoad, M7Read_ISS, M7Read_ISS], (instregex "t2TB")>;
-
-// VFP loads and stores
-
-def M7LoadSP : SchedWriteRes<[M7UnitLoad, M7UnitVPort]> { let Latency = 1; }
-def M7LoadDP : SchedWriteRes<[M7UnitLoad, M7UnitVPort, M7UnitVPort]> {
- let Latency = 2;
- let SingleIssue = 1;
-}
-def M7StoreSP : SchedWriteRes<[M7UnitStore, M7UnitVPort]>;
-def M7StoreDP : SchedWriteRes<[M7UnitStore, M7UnitVPort, M7UnitVPort]> {
- let SingleIssue = 1;
-}
-
-def : InstRW<[M7LoadSP, M7Read_ISS], (instregex "VLDR(S|H)$")>;
-def : InstRW<[M7LoadDP, M7Read_ISS], (instregex "VLDRD$")>;
-def : InstRW<[M7StoreSP, M7Read_EX3, M7Read_ISS], (instregex "VSTR(S|H)$")>;
-def : InstRW<[M7StoreDP, M7Read_EX3, M7Read_ISS], (instregex "VSTRD$")>;
-
-// Load/store multiples cannot be dual-issued.
-
-def : InstRW<[WriteLd, M7SingleIssue, M7Read_ISS],
- (instregex "VLDM(S|D|Q)(DB|IA)$")>;
-def : InstRW<[WriteST, M7SingleIssue, M7Read_ISS],
- (instregex "VSTM(S|D|Q)(DB|IA)$")>;
-def : InstRW<[M7BaseUpdate, WriteLd, M7SingleIssue, M7Read_ISS],
- (instregex "VLDM(S|D|Q)(DB|IA)_UPD$")>;
-def : InstRW<[M7BaseUpdate, WriteST, M7SingleIssue, M7Read_ISS],
- (instregex "VSTM(S|D|Q)(DB|IA)_UPD$")>;
-
-//===---------------------------------------------------------------------===//
-// Sched definitions for ALU
-//
-
-// Shifted ALU operands are read a cycle early.
-def M7Ex1ReadNoFastBypass : SchedReadAdvance<-1, [WriteLd, M7LoadLatency1]>;
-
-def : InstRW<[WriteALUsi, M7Ex1ReadNoFastBypass, M7Read_ISS],
- (instregex "t2(ADC|ADDS|ADD|BIC|EOR|ORN|ORR|RSBS|RSB|SBC|SUBS)rs$",
- "t2(SUB|CMP|CMNz|TEQ|TST)rs$",
- "t2MOVsr(a|l)")>;
-def : InstRW<[WriteALUsi, M7Read_ISS],
- (instregex "t2MVNs")>;
-
-// Treat pure shift operations (except for RRX) as if they used the EX1
-// shifter but have timing as if they used the EX2 shifter as they usually
-// can choose the EX2 shifter when needed. Will miss a few dual-issue cases,
-// but the results prove to be better than trying to get them exact.
-
-def : InstRW<[M7WriteShift2, M7Read_ISS], (instregex "t2RRX$")>;
-def : InstRW<[WriteALUsi], (instregex "(t|t2)(LSL|LSR|ASR|ROR)")>;
-
-// Instructions that use the shifter, but have normal timing.
-
-def : InstRW<[WriteALUsi,M7Slot0Only], (instregex "t2(BFC|BFI)$")>;
-
-// Instructions which are slot zero only but otherwise normal.
-
-def : InstRW<[WriteALU, M7Slot0Only], (instregex "t2CLZ")>;
-
-// MAC operations that don't have SchedRW set.
-
-def : InstRW<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC], (instregex "t2SML[AS]D")>;
-
-// Divides are special because they stall for their latency, and so look like a
-// single-cycle as far as scheduling opportunities go. By putting WriteALU
-// first, we make the operand latency 1, but keep the instruction latency 7.
-
-def : InstRW<[WriteALU, WriteDIV], (instregex "t2(S|U)DIV")>;
-
-// DSP extension operations
-
-def M7WriteSIMD1 : SchedWriteRes<[M7UnitSIMD, M7UnitALU]> {
- let Latency = 1;
- let BeginGroup = 1;
-}
-def M7WriteSIMD2 : SchedWriteRes<[M7UnitSIMD, M7UnitALU]> {
- let Latency = 2;
- let BeginGroup = 1;
-}
-def M7WriteShSIMD1 : SchedWriteRes<[M7UnitSIMD, M7UnitALU, M7UnitShift1]> {
- let Latency = 1;
- let BeginGroup = 1;
-}
-def M7WriteShSIMD0 : SchedWriteRes<[M7UnitSIMD, M7UnitALU, M7UnitShift1]> {
- let Latency = 0; // Bypassable out of EX1
- let BeginGroup = 1;
-}
-def M7WriteShSIMD2 : SchedWriteRes<[M7UnitSIMD, M7UnitALU, M7UnitShift1]> {
- let Latency = 2;
- let BeginGroup = 1;
-}
-
-def : InstRW<[M7WriteShSIMD2, M7Read_ISS],
- (instregex "t2(S|U)SAT")>;
-def : InstRW<[M7WriteSIMD1, ReadALU],
- (instregex "(t|t2)(S|U)XT(B|H)")>;
-def : InstRW<[M7WriteSIMD1, ReadALU, ReadALU],
- (instregex "t2(S|SH|U|UH)(ADD16|ADD8|ASX|SAX|SUB16|SUB8)",
- "t2SEL")>;
-def : InstRW<[M7WriteSIMD2, ReadALU, ReadALU],
- (instregex "t2(Q|UQ)(ADD|ASX|SAX|SUB)", "t2USAD8")>;
-def : InstRW<[M7WriteShSIMD2, M7Read_ISS, M7Read_ISS],
- (instregex "t2QD(ADD|SUB)")>;
-def : InstRW<[M7WriteShSIMD0, M7Read_ISS],
- (instregex "t2(RBIT|REV)", "tREV")>;
-def : InstRW<[M7WriteShSIMD1, M7Read_ISS],
- (instregex "t2(SBFX|UBFX)")>;
-def : InstRW<[M7WriteShSIMD1, ReadALU, M7Read_ISS],
- (instregex "t2PKH(BT|TB)", "t2(S|U)XTA")>;
-def : InstRW<[M7WriteSIMD2, ReadALU, ReadALU, M7Read_EX2],
- (instregex "t2USADA8")>;
-
-// MSR/MRS
-def : InstRW<[M7NonGeneralPurpose], (instregex "MSR", "MRS")>;
-
-//===---------------------------------------------------------------------===//
-// Sched definitions for FP operations
-//
-
-// Effective scheduling latency is really 3 for nearly all FP operations,
-// even if their true latency is higher.
-def M7WriteVFPLatOverride : SchedWriteRes<[]> {
- let Latency = 3;
- let NumMicroOps = 0;
-}
-def M7WriteVFPExtraVPort : SchedWriteRes<[M7UnitVPort]> {
- let Latency = 3;
- let NumMicroOps = 0;
-}
-
-// Instructions which are missing default schedules.
-def : InstRW<[WriteFPALU32],
- (instregex "V(ABS|CVT.*|NEG|FP_VMAX.*|FP_VMIN.*|RINT.*)S$")>;
-def : InstRW<[M7WriteVFPLatOverride, WriteFPALU64],
- (instregex "V(ABS|CVT.*|NEG|FP_VMAX.*|FP_VMIN.*|RINT.*)D$")>;
-
-// VCMP
-def M7WriteVCMPS : SchedWriteRes<[M7UnitVFP, M7UnitVPort]> { let Latency = 0; }
-def M7WriteVCMPD : SchedWriteRes<[M7UnitVFP, M7UnitVPort, M7UnitVPort]> {
- let Latency = 0;
- let BeginGroup = 1;
-}
-def : InstRW<[M7WriteVCMPS], (instregex "VCMPS$")>;
-def : InstRW<[M7WriteVCMPD], (instregex "VCMPD$")>;
-
- // VMRS/VMSR
-def M7VMRS : SchedWriteRes<[M7UnitVFP, M7UnitVPort]> { let SingleIssue = 1; }
-def M7VMSR : SchedWriteRes<[M7UnitVFP, M7UnitVPort]> { let SingleIssue = 1; }
-def : InstRW<[M7VMRS], (instregex "FMSTAT")>;
-def : InstRW<[M7VMSR], (instregex "VMSR")>;
-
-// VSEL cannot bypass in its implied $cpsr operand; model as earlier read
-def : InstRW<[WriteFPALU32, M7Slot0Only, ReadALU, ReadALU, M7Read_ISS],
- (instregex "VSEL.*S$")>;
-def : InstRW<[M7WriteVFPLatOverride, WriteFPALU64, M7Slot0Only,
- ReadALU, ReadALU, M7Read_ISS],
- (instregex "VSEL.*D$")>;
-
-// VMOV
-def : InstRW<[WriteFPMOV],
- (instregex "VMOV(H|S)$", "FCONST(H|S)")>;
-def : InstRW<[WriteFPMOV, M7WriteVFPExtraVPort, M7Slot0Only],
- (instregex "VMOVD$")>;
-def : InstRW<[WriteFPMOV, M7WriteVFPExtraVPort, M7Slot0Only],
- (instregex "FCONSTD")>;
-def : InstRW<[WriteFPMOV, M7WriteVFPExtraVPort, M7SingleIssue],
- (instregex "VMOV(DRR|RRD|RRS|SRR)")>;
-
-// Larger-latency overrides.
-
-def : InstRW<[M7WriteVFPLatOverride, WriteFPDIV32], (instregex "VDIVS")>;
-def : InstRW<[M7WriteVFPLatOverride, WriteFPDIV64], (instregex "VDIVD")>;
-def : InstRW<[M7WriteVFPLatOverride, WriteFPSQRT32], (instregex "VSQRTS")>;
-def : InstRW<[M7WriteVFPLatOverride, WriteFPSQRT64], (instregex "VSQRTD")>;
-def : InstRW<[M7WriteVFPLatOverride, WriteFPMUL64],
- (instregex "V(MUL|NMUL)D")>;
-def : InstRW<[M7WriteVFPLatOverride, WriteFPALU64],
- (instregex "V(ADD|SUB)D")>;
-
-// Multiply-accumulate. Chained SP timing is correct; rest need overrides
-// Double-precision chained MAC stalls the pipeline behind it for 3 cycles,
-// making it appear to have 3 cycle latency for scheduling.
-
-def : InstRW<[M7WriteVFPLatOverride, WriteFPMAC64,
- ReadFPMAC, ReadFPMUL, ReadFPMUL],
- (instregex "V(N)?ML(A|S)D$")>;
-
-// Single-precision fused MACs look like latency 5 with advance of 2.
-
-def M7WriteVFPLatOverride5 : SchedWriteRes<[]> {
- let Latency = 5;
- let NumMicroOps = 0;
-}
-def M7ReadFPMAC2 : SchedReadAdvance<2>;
-
-def : InstRW<[M7WriteVFPLatOverride5, WriteFPMAC32,
- M7ReadFPMAC2, ReadFPMUL, ReadFPMUL],
- (instregex "VF(N)?M(A|S)S$")>;
-
-// Double-precision fused MAC stalls the pipeline behind it for 2 cycles, making
-// it appear to have 3 cycle latency for scheduling.
-
-def : InstRW<[M7WriteVFPLatOverride, WriteFPMAC64,
- ReadFPMAC, ReadFPMUL, ReadFPMUL],
- (instregex "VF(N)?M(A|S)D$")>;
-
-} // SchedModel = CortexM7Model
+//=- ARMScheduleM7.td - ARM Cortex-M7 Scheduling Definitions -*- tablegen -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SchedRead/Write data for the ARM Cortex-M7 processor.
+//
+//===----------------------------------------------------------------------===//
+
+def CortexM7Model : SchedMachineModel {
+ let IssueWidth = 2; // Dual issue for most instructions.
+ let MicroOpBufferSize = 0; // The Cortex-M7 is in-order.
+ let LoadLatency = 2; // Best case for load-use case.
+ let MispredictPenalty = 4; // Mispredict cost for forward branches is 6,
+ // but 4 works better
+ let CompleteModel = 0;
+}
+
+//===--------------------------------------------------------------------===//
+// The Cortex-M7 has two ALU, two LOAD, a STORE, a MAC, a BRANCH and a VFP
+// pipe. The stages relevant to scheduling are as follows:
+//
+// EX1: address generation shifts
+// EX2: fast load data ALUs FP operation
+// EX3: slow load data integer writeback FP operation
+// EX4: store data FP writeback
+//
+// There are shifters in both EX1 and EX2, and some instructions can be
+// flexibly allocated between them. EX2 is used as the "zero" point
+// for scheduling, so simple ALU operations executing in EX2 will have
+// ReadAdvance<0> (the default) for their source operands and Latency = 1.
+
+def M7UnitLoad : ProcResource<2> { let BufferSize = 0; }
+def M7UnitStore : ProcResource<1> { let BufferSize = 0; }
+def M7UnitALU : ProcResource<2>;
+def M7UnitShift1 : ProcResource<1> { let BufferSize = 0; }
+def M7UnitShift2 : ProcResource<1> { let BufferSize = 0; }
+def M7UnitMAC : ProcResource<1> { let BufferSize = 0; }
+def M7UnitBranch : ProcResource<1> { let BufferSize = 0; }
+def M7UnitVFP : ProcResource<1> { let BufferSize = 0; }
+def M7UnitVPort : ProcResource<2> { let BufferSize = 0; }
+def M7UnitSIMD : ProcResource<1> { let BufferSize = 0; }
+
+//===---------------------------------------------------------------------===//
+// Subtarget-specific SchedWrite types with map ProcResources and set latency.
+
+let SchedModel = CortexM7Model in {
+
+def : WriteRes<WriteALU, [M7UnitALU]> { let Latency = 1; }
+
+// Basic ALU with shifts.
+let Latency = 1 in {
+ def : WriteRes<WriteALUsi, [M7UnitALU, M7UnitShift1]>;
+ def : WriteRes<WriteALUsr, [M7UnitALU, M7UnitShift1]>;
+ def : WriteRes<WriteALUSsr, [M7UnitALU, M7UnitShift1]>;
+}
+
+// Compares.
+def : WriteRes<WriteCMP, [M7UnitALU]> { let Latency = 1; }
+def : WriteRes<WriteCMPsi, [M7UnitALU, M7UnitShift1]> { let Latency = 2; }
+def : WriteRes<WriteCMPsr, [M7UnitALU, M7UnitShift1]> { let Latency = 2; }
+
+// Multiplies.
+let Latency = 2 in {
+ def : WriteRes<WriteMUL16, [M7UnitMAC]>;
+ def : WriteRes<WriteMUL32, [M7UnitMAC]>;
+ def : WriteRes<WriteMUL64Lo, [M7UnitMAC]>;
+ def : WriteRes<WriteMUL64Hi, []> { let NumMicroOps = 0; }
+}
+
+// Multiply-accumulates.
+let Latency = 2 in {
+ def : WriteRes<WriteMAC16, [M7UnitMAC]>;
+ def : WriteRes<WriteMAC32, [M7UnitMAC]>;
+ def : WriteRes<WriteMAC64Lo, [M7UnitMAC]> { let Latency = 2; }
+ def : WriteRes<WriteMAC64Hi, []> { let NumMicroOps = 0; }
+}
+
+// Divisions.
+// These cannot be dual-issued with any instructions.
+def : WriteRes<WriteDIV, [M7UnitALU]> {
+ let Latency = 7;
+ let SingleIssue = 1;
+}
+
+// Loads/Stores.
+def : WriteRes<WriteLd, [M7UnitLoad]> { let Latency = 1; }
+def : WriteRes<WritePreLd, [M7UnitLoad]> { let Latency = 2; }
+def : WriteRes<WriteST, [M7UnitStore]> { let Latency = 2; }
+
+// Branches.
+def : WriteRes<WriteBr, [M7UnitBranch]> { let Latency = 2; }
+def : WriteRes<WriteBrL, [M7UnitBranch]> { let Latency = 2; }
+def : WriteRes<WriteBrTbl, [M7UnitBranch]> { let Latency = 2; }
+
+// Noop.
+def : WriteRes<WriteNoop, []> { let Latency = 0; }
+
+//===---------------------------------------------------------------------===//
+// Sched definitions for floating-point instructions
+//
+// Floating point conversions.
+def : WriteRes<WriteFPCVT, [M7UnitVFP, M7UnitVPort]> { let Latency = 3; }
+def : WriteRes<WriteFPMOV, [M7UnitVPort]> { let Latency = 3; }
+
+// The FP pipeline has a latency of 3 cycles.
+// ALU operations (32/64-bit). These go down the FP pipeline.
+def : WriteRes<WriteFPALU32, [M7UnitVFP, M7UnitVPort]> { let Latency = 3; }
+def : WriteRes<WriteFPALU64, [M7UnitVFP, M7UnitVPort, M7UnitVPort]> {
+ let Latency = 4;
+ let BeginGroup = 1;
+}
+
+// Multiplication
+def : WriteRes<WriteFPMUL32, [M7UnitVFP, M7UnitVPort]> { let Latency = 3; }
+def : WriteRes<WriteFPMUL64, [M7UnitVFP, M7UnitVPort, M7UnitVPort]> {
+ let Latency = 7;
+ let BeginGroup = 1;
+}
+
+// Multiply-accumulate. FPMAC goes down the FP Pipeline.
+def : WriteRes<WriteFPMAC32, [M7UnitVFP, M7UnitVPort]> { let Latency = 6; }
+def : WriteRes<WriteFPMAC64, [M7UnitVFP, M7UnitVPort, M7UnitVPort]> {
+ let Latency = 11;
+ let BeginGroup = 1;
+}
+
+// Division. Effective scheduling latency is 3, though real latency is larger
+def : WriteRes<WriteFPDIV32, [M7UnitVFP, M7UnitVPort]> { let Latency = 16; }
+def : WriteRes<WriteFPDIV64, [M7UnitVFP, M7UnitVPort, M7UnitVPort]> {
+ let Latency = 30;
+ let BeginGroup = 1;
+}
+
+// Square-root. Effective scheduling latency is 3; real latency is larger
+def : WriteRes<WriteFPSQRT32, [M7UnitVFP, M7UnitVPort]> { let Latency = 16; }
+def : WriteRes<WriteFPSQRT64, [M7UnitVFP, M7UnitVPort, M7UnitVPort]> {
+ let Latency = 30;
+ let BeginGroup = 1;
+}
+
+def M7WriteShift2 : SchedWriteRes<[M7UnitALU, M7UnitShift2]> {}
+
+// Not used for M7, but needing definitions anyway
+def : WriteRes<WriteVLD1, []>;
+def : WriteRes<WriteVLD2, []>;
+def : WriteRes<WriteVLD3, []>;
+def : WriteRes<WriteVLD4, []>;
+def : WriteRes<WriteVST1, []>;
+def : WriteRes<WriteVST2, []>;
+def : WriteRes<WriteVST3, []>;
+def : WriteRes<WriteVST4, []>;
+
+def M7SingleIssue : SchedWriteRes<[]> {
+ let SingleIssue = 1;
+ let NumMicroOps = 0;
+}
+def M7Slot0Only : SchedWriteRes<[]> {
+ let BeginGroup = 1;
+ let NumMicroOps = 0;
+}
+
+// What pipeline stage operands need to be ready for depending on
+// where they come from.
+def : ReadAdvance<ReadALUsr, 0>;
+def : ReadAdvance<ReadMUL, 0>;
+def : ReadAdvance<ReadMAC, 1>;
+def : ReadAdvance<ReadALU, 0>;
+def : ReadAdvance<ReadFPMUL, 0>;
+def : ReadAdvance<ReadFPMAC, 3>;
+def M7Read_ISS : SchedReadAdvance<-1>; // operands needed at EX1
+def M7Read_EX2 : SchedReadAdvance<1>; // operands needed at EX3
+def M7Read_EX3 : SchedReadAdvance<2>; // operands needed at EX4
+
+// Non general purpose instructions may not be dual issued. These
+// use both issue units.
+def M7NonGeneralPurpose : SchedWriteRes<[]> {
+ // Assume that these will go down the main ALU pipeline.
+ // In reality, many look likely to stall the whole pipeline.
+ let Latency = 3;
+ let SingleIssue = 1;
+}
+
+// List the non general purpose instructions.
+def : InstRW<[M7NonGeneralPurpose], (instregex "t2MRS", "tSVC", "tBKPT",
+ "t2MSR", "t2DMB", "t2DSB", "t2ISB",
+ "t2HVC", "t2SMC", "t2UDF", "ERET",
+ "tHINT", "t2HINT", "t2CLREX", "BUNDLE")>;
+
+//===---------------------------------------------------------------------===//
+// Sched definitions for load/store
+//
+// Mark whether the loads/stores must be single-issue
+// Address operands are needed earlier
+// Data operands are needed later
+
+def M7BaseUpdate : SchedWriteRes<[]> {
+ let Latency = 0; // Update is bypassable out of EX1
+ let NumMicroOps = 0;
+}
+def M7LoadLatency1 : SchedWriteRes<[]> {
+ let Latency = 1;
+ let NumMicroOps = 0;
+}
+def M7SlowLoad : SchedWriteRes<[M7UnitLoad]> { let Latency = 2; }
+
+// Byte and half-word loads should have greater latency than other loads.
+// So should load exclusive.
+
+def : InstRW<[M7SlowLoad],
+ (instregex "t2LDR(B|H|SB|SH)pc")>;
+def : InstRW<[M7SlowLoad, M7Read_ISS],
+ (instregex "t2LDR(B|H|SB|SH)T", "t2LDR(B|H|SB|SH)i",
+ "tLDR(B|H)i")>;
+def : InstRW<[M7SlowLoad, M7Read_ISS, M7Read_ISS],
+ (instregex "t2LDR(B|H|SB|SH)s", "tLDR(B|H)r", "tLDR(SB|SH)")>;
+def : InstRW<[M7SlowLoad, M7BaseUpdate, M7Read_ISS],
+ (instregex "t2LDR(B|H|SB|SH)_(POST|PRE)")>;
+
+// Exclusive loads/stores cannot be dual-issued
+def : InstRW<[WriteLd, M7Slot0Only, M7Read_ISS],
+ (instregex "t2LDREX$")>;
+def : InstRW<[M7SlowLoad, M7Slot0Only, M7Read_ISS],
+ (instregex "t2LDREX(B|H)")>;
+def : InstRW<[WriteST, M7SingleIssue, M7Read_EX2, M7Read_ISS],
+ (instregex "t2STREX(B|H)?$")>;
+
+// Load/store multiples cannot be dual-issued. Note that default scheduling
+// occurs around read/write times of individual registers in the list; read
+// time for STM cannot be overridden because it is a variadic source operand.
+
+def : InstRW<[WriteLd, M7SingleIssue, M7Read_ISS],
+ (instregex "(t|t2)LDM(DB|IA)$")>;
+def : InstRW<[WriteST, M7SingleIssue, M7Read_ISS],
+ (instregex "(t|t2)STM(DB|IA)$")>;
+def : InstRW<[M7BaseUpdate, WriteLd, M7SingleIssue, M7Read_ISS],
+ (instregex "(t|t2)LDM(DB|IA)_UPD$", "tPOP")>;
+def : InstRW<[M7BaseUpdate, WriteST, M7SingleIssue, M7Read_ISS],
+ (instregex "(t|t2)STM(DB|IA)_UPD$", "tPUSH")>;
+
+// Load/store doubles cannot be dual-issued.
+
+def : InstRW<[M7BaseUpdate, WriteST, M7SingleIssue,
+ M7Read_EX2, M7Read_EX2, M7Read_ISS],
+ (instregex "t2STRD_(PRE|POST)")>;
+def : InstRW<[WriteST, M7SingleIssue, M7Read_EX2, M7Read_EX2, M7Read_ISS],
+ (instregex "t2STRDi")>;
+def : InstRW<[WriteLd, M7LoadLatency1, M7SingleIssue, M7BaseUpdate, M7Read_ISS],
+ (instregex "t2LDRD_(PRE|POST)")>;
+def : InstRW<[WriteLd, M7LoadLatency1, M7SingleIssue, M7Read_ISS],
+ (instregex "t2LDRDi")>;
+
+// Word load / preload
+def : InstRW<[WriteLd],
+ (instregex "t2LDRpc", "t2PL[DI]pci", "tLDRpci")>;
+def : InstRW<[WriteLd, M7Read_ISS],
+ (instregex "t2LDR(i|T)", "t2PL[DI](W)?i", "tLDRi", "tLDRspi")>;
+def : InstRW<[WriteLd, M7Read_ISS, M7Read_ISS],
+ (instregex "t2LDRs", "t2PL[DI](w)?s", "tLDRr")>;
+def : InstRW<[WriteLd, M7BaseUpdate, M7Read_ISS],
+ (instregex "t2LDR_(POST|PRE)")>;
+
+// Stores
+def : InstRW<[M7BaseUpdate, WriteST, M7Read_EX2, M7Read_ISS],
+ (instregex "t2STR(B|H)?_(POST|PRE)")>;
+def : InstRW<[WriteST, M7Read_EX2, M7Read_ISS, M7Read_ISS],
+ (instregex "t2STR(B|H)?s$", "tSTR(B|H)?r$")>;
+def : InstRW<[WriteST, M7Read_EX2, M7Read_ISS],
+ (instregex "t2STR(B|H)?(i|T)", "tSTR(B|H)?i$", "tSTRspi")>;
+
+// TBB/TBH - single-issue only; takes two cycles to issue
+
+def M7TableLoad : SchedWriteRes<[M7UnitLoad]> {
+ let NumMicroOps = 2;
+ let SingleIssue = 1;
+}
+
+def : InstRW<[M7TableLoad, M7Read_ISS, M7Read_ISS], (instregex "t2TB")>;
+
+// VFP loads and stores
+
+def M7LoadSP : SchedWriteRes<[M7UnitLoad, M7UnitVPort]> { let Latency = 1; }
+def M7LoadDP : SchedWriteRes<[M7UnitLoad, M7UnitVPort, M7UnitVPort]> {
+ let Latency = 2;
+ let SingleIssue = 1;
+}
+def M7StoreSP : SchedWriteRes<[M7UnitStore, M7UnitVPort]>;
+def M7StoreDP : SchedWriteRes<[M7UnitStore, M7UnitVPort, M7UnitVPort]> {
+ let SingleIssue = 1;
+}
+
+def : InstRW<[M7LoadSP, M7Read_ISS], (instregex "VLDR(S|H)$")>;
+def : InstRW<[M7LoadDP, M7Read_ISS], (instregex "VLDRD$")>;
+def : InstRW<[M7StoreSP, M7Read_EX3, M7Read_ISS], (instregex "VSTR(S|H)$")>;
+def : InstRW<[M7StoreDP, M7Read_EX3, M7Read_ISS], (instregex "VSTRD$")>;
+
+// Load/store multiples cannot be dual-issued.
+
+def : InstRW<[WriteLd, M7SingleIssue, M7Read_ISS],
+ (instregex "VLDM(S|D|Q)(DB|IA)$")>;
+def : InstRW<[WriteST, M7SingleIssue, M7Read_ISS],
+ (instregex "VSTM(S|D|Q)(DB|IA)$")>;
+def : InstRW<[M7BaseUpdate, WriteLd, M7SingleIssue, M7Read_ISS],
+ (instregex "VLDM(S|D|Q)(DB|IA)_UPD$")>;
+def : InstRW<[M7BaseUpdate, WriteST, M7SingleIssue, M7Read_ISS],
+ (instregex "VSTM(S|D|Q)(DB|IA)_UPD$")>;
+
+//===---------------------------------------------------------------------===//
+// Sched definitions for ALU
+//
+
+// Shifted ALU operands are read a cycle early.
+def M7Ex1ReadNoFastBypass : SchedReadAdvance<-1, [WriteLd, M7LoadLatency1]>;
+
+def : InstRW<[WriteALUsi, M7Ex1ReadNoFastBypass, M7Read_ISS],
+ (instregex "t2(ADC|ADDS|ADD|BIC|EOR|ORN|ORR|RSBS|RSB|SBC|SUBS)rs$",
+ "t2(SUB|CMP|CMNz|TEQ|TST)rs$",
+ "t2MOVsr(a|l)")>;
+def : InstRW<[WriteALUsi, M7Read_ISS],
+ (instregex "t2MVNs")>;
+
+// Treat pure shift operations (except for RRX) as if they used the EX1
+// shifter but have timing as if they used the EX2 shifter as they usually
+// can choose the EX2 shifter when needed. Will miss a few dual-issue cases,
+// but the results prove to be better than trying to get them exact.
+
+def : InstRW<[M7WriteShift2, M7Read_ISS], (instregex "t2RRX$")>;
+def : InstRW<[WriteALUsi], (instregex "(t|t2)(LSL|LSR|ASR|ROR)")>;
+
+// Instructions that use the shifter, but have normal timing.
+
+def : InstRW<[WriteALUsi,M7Slot0Only], (instregex "t2(BFC|BFI)$")>;
+
+// Instructions which are slot zero only but otherwise normal.
+
+def : InstRW<[WriteALU, M7Slot0Only], (instregex "t2CLZ")>;
+
+// MAC operations that don't have SchedRW set.
+
+def : InstRW<[WriteMAC32, ReadMUL, ReadMUL, ReadMAC], (instregex "t2SML[AS]D")>;
+
+// Divides are special because they stall for their latency, and so look like a
+// single-cycle as far as scheduling opportunities go. By putting WriteALU
+// first, we make the operand latency 1, but keep the instruction latency 7.
+
+def : InstRW<[WriteALU, WriteDIV], (instregex "t2(S|U)DIV")>;
+
+// DSP extension operations
+
+def M7WriteSIMD1 : SchedWriteRes<[M7UnitSIMD, M7UnitALU]> {
+ let Latency = 1;
+ let BeginGroup = 1;
+}
+def M7WriteSIMD2 : SchedWriteRes<[M7UnitSIMD, M7UnitALU]> {
+ let Latency = 2;
+ let BeginGroup = 1;
+}
+def M7WriteShSIMD1 : SchedWriteRes<[M7UnitSIMD, M7UnitALU, M7UnitShift1]> {
+ let Latency = 1;
+ let BeginGroup = 1;
+}
+def M7WriteShSIMD0 : SchedWriteRes<[M7UnitSIMD, M7UnitALU, M7UnitShift1]> {
+ let Latency = 0; // Bypassable out of EX1
+ let BeginGroup = 1;
+}
+def M7WriteShSIMD2 : SchedWriteRes<[M7UnitSIMD, M7UnitALU, M7UnitShift1]> {
+ let Latency = 2;
+ let BeginGroup = 1;
+}
+
+def : InstRW<[M7WriteShSIMD2, M7Read_ISS],
+ (instregex "t2(S|U)SAT")>;
+def : InstRW<[M7WriteSIMD1, ReadALU],
+ (instregex "(t|t2)(S|U)XT(B|H)")>;
+def : InstRW<[M7WriteSIMD1, ReadALU, ReadALU],
+ (instregex "t2(S|SH|U|UH)(ADD16|ADD8|ASX|SAX|SUB16|SUB8)",
+ "t2SEL")>;
+def : InstRW<[M7WriteSIMD2, ReadALU, ReadALU],
+ (instregex "t2(Q|UQ)(ADD|ASX|SAX|SUB)", "t2USAD8")>;
+def : InstRW<[M7WriteShSIMD2, M7Read_ISS, M7Read_ISS],
+ (instregex "t2QD(ADD|SUB)")>;
+def : InstRW<[M7WriteShSIMD0, M7Read_ISS],
+ (instregex "t2(RBIT|REV)", "tREV")>;
+def : InstRW<[M7WriteShSIMD1, M7Read_ISS],
+ (instregex "t2(SBFX|UBFX)")>;
+def : InstRW<[M7WriteShSIMD1, ReadALU, M7Read_ISS],
+ (instregex "t2PKH(BT|TB)", "t2(S|U)XTA")>;
+def : InstRW<[M7WriteSIMD2, ReadALU, ReadALU, M7Read_EX2],
+ (instregex "t2USADA8")>;
+
+// MSR/MRS
+def : InstRW<[M7NonGeneralPurpose], (instregex "MSR", "MRS")>;
+
+//===---------------------------------------------------------------------===//
+// Sched definitions for FP operations
+//
+
+// Effective scheduling latency is really 3 for nearly all FP operations,
+// even if their true latency is higher.
+def M7WriteVFPLatOverride : SchedWriteRes<[]> {
+ let Latency = 3;
+ let NumMicroOps = 0;
+}
+def M7WriteVFPExtraVPort : SchedWriteRes<[M7UnitVPort]> {
+ let Latency = 3;
+ let NumMicroOps = 0;
+}
+
+// Instructions which are missing default schedules.
+def : InstRW<[WriteFPALU32],
+ (instregex "V(ABS|CVT.*|NEG|FP_VMAX.*|FP_VMIN.*|RINT.*)S$")>;
+def : InstRW<[M7WriteVFPLatOverride, WriteFPALU64],
+ (instregex "V(ABS|CVT.*|NEG|FP_VMAX.*|FP_VMIN.*|RINT.*)D$")>;
+
+// VCMP
+def M7WriteVCMPS : SchedWriteRes<[M7UnitVFP, M7UnitVPort]> { let Latency = 0; }
+def M7WriteVCMPD : SchedWriteRes<[M7UnitVFP, M7UnitVPort, M7UnitVPort]> {
+ let Latency = 0;
+ let BeginGroup = 1;
+}
+def : InstRW<[M7WriteVCMPS], (instregex "VCMPS$")>;
+def : InstRW<[M7WriteVCMPD], (instregex "VCMPD$")>;
+
+ // VMRS/VMSR
+def M7VMRS : SchedWriteRes<[M7UnitVFP, M7UnitVPort]> { let SingleIssue = 1; }
+def M7VMSR : SchedWriteRes<[M7UnitVFP, M7UnitVPort]> { let SingleIssue = 1; }
+def : InstRW<[M7VMRS], (instregex "FMSTAT")>;
+def : InstRW<[M7VMSR], (instregex "VMSR")>;
+
+// VSEL cannot bypass in its implied $cpsr operand; model as earlier read
+def : InstRW<[WriteFPALU32, M7Slot0Only, ReadALU, ReadALU, M7Read_ISS],
+ (instregex "VSEL.*S$")>;
+def : InstRW<[M7WriteVFPLatOverride, WriteFPALU64, M7Slot0Only,
+ ReadALU, ReadALU, M7Read_ISS],
+ (instregex "VSEL.*D$")>;
+
+// VMOV
+def : InstRW<[WriteFPMOV],
+ (instregex "VMOV(H|S)$", "FCONST(H|S)")>;
+def : InstRW<[WriteFPMOV, M7WriteVFPExtraVPort, M7Slot0Only],
+ (instregex "VMOVD$")>;
+def : InstRW<[WriteFPMOV, M7WriteVFPExtraVPort, M7Slot0Only],
+ (instregex "FCONSTD")>;
+def : InstRW<[WriteFPMOV, M7WriteVFPExtraVPort, M7SingleIssue],
+ (instregex "VMOV(DRR|RRD|RRS|SRR)")>;
+
+// Larger-latency overrides.
+
+def : InstRW<[M7WriteVFPLatOverride, WriteFPDIV32], (instregex "VDIVS")>;
+def : InstRW<[M7WriteVFPLatOverride, WriteFPDIV64], (instregex "VDIVD")>;
+def : InstRW<[M7WriteVFPLatOverride, WriteFPSQRT32], (instregex "VSQRTS")>;
+def : InstRW<[M7WriteVFPLatOverride, WriteFPSQRT64], (instregex "VSQRTD")>;
+def : InstRW<[M7WriteVFPLatOverride, WriteFPMUL64],
+ (instregex "V(MUL|NMUL)D")>;
+def : InstRW<[M7WriteVFPLatOverride, WriteFPALU64],
+ (instregex "V(ADD|SUB)D")>;
+
+// Multiply-accumulate. Chained SP timing is correct; rest need overrides
+// Double-precision chained MAC stalls the pipeline behind it for 3 cycles,
+// making it appear to have 3 cycle latency for scheduling.
+
+def : InstRW<[M7WriteVFPLatOverride, WriteFPMAC64,
+ ReadFPMAC, ReadFPMUL, ReadFPMUL],
+ (instregex "V(N)?ML(A|S)D$")>;
+
+// Single-precision fused MACs look like latency 5 with advance of 2.
+
+def M7WriteVFPLatOverride5 : SchedWriteRes<[]> {
+ let Latency = 5;
+ let NumMicroOps = 0;
+}
+def M7ReadFPMAC2 : SchedReadAdvance<2>;
+
+def : InstRW<[M7WriteVFPLatOverride5, WriteFPMAC32,
+ M7ReadFPMAC2, ReadFPMUL, ReadFPMUL],
+ (instregex "VF(N)?M(A|S)S$")>;
+
+// Double-precision fused MAC stalls the pipeline behind it for 2 cycles, making
+// it appear to have 3 cycle latency for scheduling.
+
+def : InstRW<[M7WriteVFPLatOverride, WriteFPMAC64,
+ ReadFPMAC, ReadFPMUL, ReadFPMUL],
+ (instregex "VF(N)?M(A|S)D$")>;
+
+} // SchedModel = CortexM7Model
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleR52.td b/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleR52.td
index aabce817a9..466acec6f7 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleR52.td
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleR52.td
@@ -787,8 +787,8 @@ def : InstRW<[R52Write2FPALU_F3, R52Read_F2, R52Read_F2], (instregex "(VAND|VBIC
def : InstRW<[R52WriteFPALU_F3, R52Read_F2], (instregex "VBICi(v4i16|v2i32)")>;
def : InstRW<[R52Write2FPALU_F3, R52Read_F2], (instregex "VBICi(v8i16|v4i32)")>;
-def : InstRW<[R52WriteFPALU_F3, R52Read_F1, R52Read_F2, R52Read_F2], (instregex "(VBIF|VBIT|VBSL|VBSP)d")>;
-def : InstRW<[R52Write2FPALU_F3, R52Read_F1, R52Read_F2, R52Read_F2], (instregex "(VBIF|VBIT|VBSL|VBSP)q")>;
+def : InstRW<[R52WriteFPALU_F3, R52Read_F1, R52Read_F2, R52Read_F2], (instregex "(VBIF|VBIT|VBSL|VBSP)d")>;
+def : InstRW<[R52Write2FPALU_F3, R52Read_F1, R52Read_F2, R52Read_F2], (instregex "(VBIF|VBIT|VBSL|VBSP)q")>;
def : InstRW<[R52WriteFPALU_F3, R52Read_F1, R52Read_F1],
(instregex "(VCEQ|VCGE|VCGT|VCLE|VCLT|VCLZ|VCMP|VCMPE|VCNT)")>;
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleSwift.td b/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleSwift.td
index ef2bde2a0d..d66b3065c7 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleSwift.td
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMScheduleSwift.td
@@ -558,8 +558,8 @@ let SchedModel = SwiftModel in {
(instregex "VADDv", "VSUBv", "VNEG(s|f|v)", "VADDL", "VSUBL",
"VADDW", "VSUBW", "VHADD", "VHSUB", "VRHADD", "VPADDi",
"VPADDL", "VAND", "VBIC", "VEOR", "VORN", "VORR", "VTST",
- "VSHL", "VSHR(s|u)", "VSHLL", "VQSHL(s|u)", "VBIF", "VBIT",
- "VBSL", "VBSP", "VSLI", "VSRI", "VCLS", "VCLZ", "VCNT")>;
+ "VSHL", "VSHR(s|u)", "VSHLL", "VQSHL(s|u)", "VBIF", "VBIT",
+ "VBSL", "VBSP", "VSLI", "VSRI", "VCLS", "VCLZ", "VCNT")>;
def : InstRW<[SwiftWriteP1TwoCycle],
(instregex "VEXT", "VREV16", "VREV32", "VREV64")>;
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMSubtarget.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMSubtarget.cpp
index c49135d536..5cb608b74a 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMSubtarget.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMSubtarget.cpp
@@ -97,9 +97,9 @@ ARMSubtarget::ARMSubtarget(const Triple &TT, const std::string &CPU,
const std::string &FS,
const ARMBaseTargetMachine &TM, bool IsLittle,
bool MinSize)
- : ARMGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS),
- UseMulOps(UseFusedMulOps), CPUString(CPU), OptMinSize(MinSize),
- IsLittle(IsLittle), TargetTriple(TT), Options(TM.Options), TM(TM),
+ : ARMGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS),
+ UseMulOps(UseFusedMulOps), CPUString(CPU), OptMinSize(MinSize),
+ IsLittle(IsLittle), TargetTriple(TT), Options(TM.Options), TM(TM),
FrameLowering(initializeFrameLowering(CPU, FS)),
// At this point initializeSubtargetDependencies has been called so
// we can query directly.
@@ -185,7 +185,7 @@ void ARMSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
else
ArchFS = std::string(FS);
}
- ParseSubtargetFeatures(CPUString, /*TuneCPU*/ CPUString, ArchFS);
+ ParseSubtargetFeatures(CPUString, /*TuneCPU*/ CPUString, ArchFS);
// FIXME: This used enable V6T2 support implicitly for Thumb2 mode.
// Assert this for now to make the change obvious.
@@ -237,7 +237,7 @@ void ARMSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
switch (IT) {
case DefaultIT:
- RestrictIT = hasV8Ops() && !hasMinSize();
+ RestrictIT = hasV8Ops() && !hasMinSize();
break;
case RestrictedIT:
RestrictIT = true;
@@ -294,13 +294,13 @@ void ARMSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
case CortexA76:
case CortexA77:
case CortexA78:
- case CortexA78C:
+ case CortexA78C:
case CortexR4:
case CortexR4F:
case CortexR5:
case CortexR7:
case CortexM3:
- case CortexM7:
+ case CortexM7:
case CortexR52:
case CortexX1:
break;
@@ -316,8 +316,8 @@ void ARMSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
PreISelOperandLatencyAdjustment = 1;
break;
case NeoverseN1:
- case NeoverseN2:
- case NeoverseV1:
+ case NeoverseN2:
+ case NeoverseV1:
break;
case Swift:
MaxInterleaveFactor = 2;
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMSubtarget.h b/contrib/libs/llvm12/lib/Target/ARM/ARMSubtarget.h
index a6335c6984..fd9b94fdaa 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMSubtarget.h
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMSubtarget.h
@@ -63,11 +63,11 @@ protected:
CortexA76,
CortexA77,
CortexA78,
- CortexA78C,
+ CortexA78C,
CortexA8,
CortexA9,
CortexM3,
- CortexM7,
+ CortexM7,
CortexR4,
CortexR4F,
CortexR5,
@@ -78,8 +78,8 @@ protected:
Krait,
Kryo,
NeoverseN1,
- NeoverseN2,
- NeoverseV1,
+ NeoverseN2,
+ NeoverseV1,
Swift
};
enum ARMProcClassEnum {
@@ -167,7 +167,7 @@ protected:
bool HasV8_4aOps = false;
bool HasV8_5aOps = false;
bool HasV8_6aOps = false;
- bool HasV8_7aOps = false;
+ bool HasV8_7aOps = false;
bool HasV8MBaselineOps = false;
bool HasV8MMainlineOps = false;
bool HasV8_1MMainlineOps = false;
@@ -466,13 +466,13 @@ protected:
/// cannot be encoded. For example, ADD r0, r1, #FFFFFFFF -> SUB r0, r1, #1.
bool NegativeImmediates = true;
- /// Harden against Straight Line Speculation for Returns and Indirect
- /// Branches.
- bool HardenSlsRetBr = false;
-
- /// Harden against Straight Line Speculation for indirect calls.
- bool HardenSlsBlr = false;
-
+ /// Harden against Straight Line Speculation for Returns and Indirect
+ /// Branches.
+ bool HardenSlsRetBr = false;
+
+ /// Harden against Straight Line Speculation for indirect calls.
+ bool HardenSlsBlr = false;
+
/// stackAlignment - The minimum alignment known to hold of the stack frame on
/// entry to the function and which must be maintained by every function.
Align stackAlignment = Align(4);
@@ -538,7 +538,7 @@ public:
/// ParseSubtargetFeatures - Parses features string setting specified
/// subtarget options. Definition of function is auto generated by tblgen.
- void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
+ void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
/// initializeSubtargetDependencies - Initializes using a CPU and feature string
/// so that we can use initializer lists for subtarget initialization.
@@ -606,7 +606,7 @@ public:
bool hasV8_4aOps() const { return HasV8_4aOps; }
bool hasV8_5aOps() const { return HasV8_5aOps; }
bool hasV8_6aOps() const { return HasV8_6aOps; }
- bool hasV8_7aOps() const { return HasV8_7aOps; }
+ bool hasV8_7aOps() const { return HasV8_7aOps; }
bool hasV8MBaselineOps() const { return HasV8MBaselineOps; }
bool hasV8MMainlineOps() const { return HasV8MMainlineOps; }
bool hasV8_1MMainlineOps() const { return HasV8_1MMainlineOps; }
@@ -627,7 +627,7 @@ public:
bool isCortexA15() const { return ARMProcFamily == CortexA15; }
bool isSwift() const { return ARMProcFamily == Swift; }
bool isCortexM3() const { return ARMProcFamily == CortexM3; }
- bool isCortexM7() const { return ARMProcFamily == CortexM7; }
+ bool isCortexM7() const { return ARMProcFamily == CortexM7; }
bool isLikeA9() const { return isCortexA9() || isCortexA15() || isKrait(); }
bool isCortexR5() const { return ARMProcFamily == CortexR5; }
bool isKrait() const { return ARMProcFamily == Krait; }
@@ -915,9 +915,9 @@ public:
bool ignoreCSRForAllocationOrder(const MachineFunction &MF,
unsigned PhysReg) const override;
unsigned getGPRAllocationOrder(const MachineFunction &MF) const;
-
- bool hardenSlsRetBr() const { return HardenSlsRetBr; }
- bool hardenSlsBlr() const { return HardenSlsBlr; }
+
+ bool hardenSlsRetBr() const { return HardenSlsRetBr; }
+ bool hardenSlsBlr() const { return HardenSlsBlr; }
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMTargetMachine.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMTargetMachine.cpp
index c4841aabdf..237ef54c83 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMTargetMachine.cpp
@@ -99,9 +99,9 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMTarget() {
initializeMVEVPTOptimisationsPass(Registry);
initializeMVETailPredicationPass(Registry);
initializeARMLowOverheadLoopsPass(Registry);
- initializeARMBlockPlacementPass(Registry);
+ initializeARMBlockPlacementPass(Registry);
initializeMVEGatherScatterLoweringPass(Registry);
- initializeARMSLSHardeningPass(Registry);
+ initializeARMSLSHardeningPass(Registry);
}
static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
@@ -253,7 +253,7 @@ ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const Triple &TT,
// ARM supports the MachineOutliner.
setMachineOutliner(true);
- setSupportsDefaultOutlining(true);
+ setSupportsDefaultOutlining(true);
}
ARMBaseTargetMachine::~ARMBaseTargetMachine() = default;
@@ -263,10 +263,10 @@ ARMBaseTargetMachine::getSubtargetImpl(const Function &F) const {
Attribute CPUAttr = F.getFnAttribute("target-cpu");
Attribute FSAttr = F.getFnAttribute("target-features");
- std::string CPU =
- CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
- std::string FS =
- FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
+ std::string CPU =
+ CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
+ std::string FS =
+ FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
// FIXME: This is related to the code below to reset the target options,
// we need to know whether or not the soft float flag is set on the
@@ -409,8 +409,8 @@ void ARMPassConfig::addIRPasses() {
// ldrex/strex loops to simplify this, but it needs tidying up.
if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy)
addPass(createCFGSimplificationPass(
- SimplifyCFGOptions().hoistCommonInsts(true).sinkCommonInsts(true),
- [this](const Function &F) {
+ SimplifyCFGOptions().hoistCommonInsts(true).sinkCommonInsts(true),
+ [this](const Function &F) {
const auto &ST = this->TM->getSubtarget<ARMSubtarget>(F);
return ST.hasAnyDataBarrier() && !ST.isThumb1Only();
}));
@@ -472,7 +472,7 @@ bool ARMPassConfig::addInstSelector() {
}
bool ARMPassConfig::addIRTranslator() {
- addPass(new IRTranslator(getOptLevel()));
+ addPass(new IRTranslator(getOptLevel()));
return false;
}
@@ -540,9 +540,9 @@ void ARMPassConfig::addPreSched2() {
addPass(&PostMachineSchedulerID);
addPass(&PostRASchedulerID);
}
-
- addPass(createARMIndirectThunks());
- addPass(createARMSLSHardeningPass());
+
+ addPass(createARMIndirectThunks());
+ addPass(createARMSLSHardeningPass());
}
void ARMPassConfig::addPreEmitPass() {
@@ -553,11 +553,11 @@ void ARMPassConfig::addPreEmitPass() {
return MF.getSubtarget<ARMSubtarget>().isThumb2();
}));
- // Don't optimize barriers or block placement at -O0.
- if (getOptLevel() != CodeGenOpt::None) {
- addPass(createARMBlockPlacementPass());
+ // Don't optimize barriers or block placement at -O0.
+ if (getOptLevel() != CodeGenOpt::None) {
+ addPass(createARMBlockPlacementPass());
addPass(createARMOptimizeBarriersPass());
- }
+ }
}
void ARMPassConfig::addPreEmitPass2() {
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMTargetMachine.h b/contrib/libs/llvm12/lib/Target/ARM/ARMTargetMachine.h
index d9f5d40eb1..8428092bf1 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMTargetMachine.h
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMTargetMachine.h
@@ -72,12 +72,12 @@ public:
}
bool targetSchedulesPostRAScheduling() const override { return true; };
-
- /// Returns true if a cast between SrcAS and DestAS is a noop.
- bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override {
- // Addrspacecasts are always noops.
- return true;
- }
+
+ /// Returns true if a cast between SrcAS and DestAS is a noop.
+ bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override {
+ // Addrspacecasts are always noops.
+ return true;
+ }
};
/// ARM/Thumb little endian target machine.
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMTargetTransformInfo.cpp b/contrib/libs/llvm12/lib/Target/ARM/ARMTargetTransformInfo.cpp
index e4e4252041..8901934013 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMTargetTransformInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMTargetTransformInfo.cpp
@@ -20,18 +20,18 @@
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/IntrinsicsARM.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/KnownBits.h"
+#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MachineValueType.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Transforms/InstCombine/InstCombiner.h"
-#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/InstCombine/InstCombiner.h"
+#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
#include <algorithm>
#include <cassert>
@@ -50,38 +50,38 @@ static cl::opt<bool> DisableLowOverheadLoops(
"disable-arm-loloops", cl::Hidden, cl::init(false),
cl::desc("Disable the generation of low-overhead loops"));
-static cl::opt<bool>
- AllowWLSLoops("allow-arm-wlsloops", cl::Hidden, cl::init(true),
- cl::desc("Enable the generation of WLS loops"));
-
+static cl::opt<bool>
+ AllowWLSLoops("allow-arm-wlsloops", cl::Hidden, cl::init(true),
+ cl::desc("Enable the generation of WLS loops"));
+
extern cl::opt<TailPredication::Mode> EnableTailPredication;
extern cl::opt<bool> EnableMaskedGatherScatters;
-extern cl::opt<unsigned> MVEMaxSupportedInterleaveFactor;
-
-/// Convert a vector load intrinsic into a simple llvm load instruction.
-/// This is beneficial when the underlying object being addressed comes
-/// from a constant, since we get constant-folding for free.
-static Value *simplifyNeonVld1(const IntrinsicInst &II, unsigned MemAlign,
- InstCombiner::BuilderTy &Builder) {
- auto *IntrAlign = dyn_cast<ConstantInt>(II.getArgOperand(1));
-
- if (!IntrAlign)
- return nullptr;
-
- unsigned Alignment = IntrAlign->getLimitedValue() < MemAlign
- ? MemAlign
- : IntrAlign->getLimitedValue();
-
- if (!isPowerOf2_32(Alignment))
- return nullptr;
-
- auto *BCastInst = Builder.CreateBitCast(II.getArgOperand(0),
- PointerType::get(II.getType(), 0));
- return Builder.CreateAlignedLoad(II.getType(), BCastInst, Align(Alignment));
-}
-
+extern cl::opt<unsigned> MVEMaxSupportedInterleaveFactor;
+
+/// Convert a vector load intrinsic into a simple llvm load instruction.
+/// This is beneficial when the underlying object being addressed comes
+/// from a constant, since we get constant-folding for free.
+static Value *simplifyNeonVld1(const IntrinsicInst &II, unsigned MemAlign,
+ InstCombiner::BuilderTy &Builder) {
+ auto *IntrAlign = dyn_cast<ConstantInt>(II.getArgOperand(1));
+
+ if (!IntrAlign)
+ return nullptr;
+
+ unsigned Alignment = IntrAlign->getLimitedValue() < MemAlign
+ ? MemAlign
+ : IntrAlign->getLimitedValue();
+
+ if (!isPowerOf2_32(Alignment))
+ return nullptr;
+
+ auto *BCastInst = Builder.CreateBitCast(II.getArgOperand(0),
+ PointerType::get(II.getType(), 0));
+ return Builder.CreateAlignedLoad(II.getType(), BCastInst, Align(Alignment));
+}
+
bool ARMTTIImpl::areInlineCompatible(const Function *Caller,
const Function *Callee) const {
const TargetMachine &TM = getTLI()->getTargetMachine();
@@ -114,138 +114,138 @@ bool ARMTTIImpl::shouldFavorPostInc() const {
return false;
}
-Optional<Instruction *>
-ARMTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
- using namespace PatternMatch;
- Intrinsic::ID IID = II.getIntrinsicID();
- switch (IID) {
- default:
- break;
- case Intrinsic::arm_neon_vld1: {
- Align MemAlign =
- getKnownAlignment(II.getArgOperand(0), IC.getDataLayout(), &II,
- &IC.getAssumptionCache(), &IC.getDominatorTree());
- if (Value *V = simplifyNeonVld1(II, MemAlign.value(), IC.Builder)) {
- return IC.replaceInstUsesWith(II, V);
- }
- break;
- }
-
- case Intrinsic::arm_neon_vld2:
- case Intrinsic::arm_neon_vld3:
- case Intrinsic::arm_neon_vld4:
- case Intrinsic::arm_neon_vld2lane:
- case Intrinsic::arm_neon_vld3lane:
- case Intrinsic::arm_neon_vld4lane:
- case Intrinsic::arm_neon_vst1:
- case Intrinsic::arm_neon_vst2:
- case Intrinsic::arm_neon_vst3:
- case Intrinsic::arm_neon_vst4:
- case Intrinsic::arm_neon_vst2lane:
- case Intrinsic::arm_neon_vst3lane:
- case Intrinsic::arm_neon_vst4lane: {
- Align MemAlign =
- getKnownAlignment(II.getArgOperand(0), IC.getDataLayout(), &II,
- &IC.getAssumptionCache(), &IC.getDominatorTree());
- unsigned AlignArg = II.getNumArgOperands() - 1;
- Value *AlignArgOp = II.getArgOperand(AlignArg);
- MaybeAlign Align = cast<ConstantInt>(AlignArgOp)->getMaybeAlignValue();
- if (Align && *Align < MemAlign) {
- return IC.replaceOperand(
- II, AlignArg,
- ConstantInt::get(Type::getInt32Ty(II.getContext()), MemAlign.value(),
- false));
- }
- break;
- }
-
- case Intrinsic::arm_mve_pred_i2v: {
- Value *Arg = II.getArgOperand(0);
- Value *ArgArg;
- if (match(Arg, PatternMatch::m_Intrinsic<Intrinsic::arm_mve_pred_v2i>(
- PatternMatch::m_Value(ArgArg))) &&
- II.getType() == ArgArg->getType()) {
- return IC.replaceInstUsesWith(II, ArgArg);
- }
- Constant *XorMask;
- if (match(Arg, m_Xor(PatternMatch::m_Intrinsic<Intrinsic::arm_mve_pred_v2i>(
- PatternMatch::m_Value(ArgArg)),
- PatternMatch::m_Constant(XorMask))) &&
- II.getType() == ArgArg->getType()) {
- if (auto *CI = dyn_cast<ConstantInt>(XorMask)) {
- if (CI->getValue().trunc(16).isAllOnesValue()) {
- auto TrueVector = IC.Builder.CreateVectorSplat(
- cast<FixedVectorType>(II.getType())->getNumElements(),
- IC.Builder.getTrue());
- return BinaryOperator::Create(Instruction::Xor, ArgArg, TrueVector);
- }
- }
- }
- KnownBits ScalarKnown(32);
- if (IC.SimplifyDemandedBits(&II, 0, APInt::getLowBitsSet(32, 16),
- ScalarKnown, 0)) {
- return &II;
- }
- break;
- }
- case Intrinsic::arm_mve_pred_v2i: {
- Value *Arg = II.getArgOperand(0);
- Value *ArgArg;
- if (match(Arg, PatternMatch::m_Intrinsic<Intrinsic::arm_mve_pred_i2v>(
- PatternMatch::m_Value(ArgArg)))) {
- return IC.replaceInstUsesWith(II, ArgArg);
- }
- if (!II.getMetadata(LLVMContext::MD_range)) {
- Type *IntTy32 = Type::getInt32Ty(II.getContext());
- Metadata *M[] = {
- ConstantAsMetadata::get(ConstantInt::get(IntTy32, 0)),
- ConstantAsMetadata::get(ConstantInt::get(IntTy32, 0xFFFF))};
- II.setMetadata(LLVMContext::MD_range, MDNode::get(II.getContext(), M));
- return &II;
- }
- break;
- }
- case Intrinsic::arm_mve_vadc:
- case Intrinsic::arm_mve_vadc_predicated: {
- unsigned CarryOp =
- (II.getIntrinsicID() == Intrinsic::arm_mve_vadc_predicated) ? 3 : 2;
- assert(II.getArgOperand(CarryOp)->getType()->getScalarSizeInBits() == 32 &&
- "Bad type for intrinsic!");
-
- KnownBits CarryKnown(32);
- if (IC.SimplifyDemandedBits(&II, CarryOp, APInt::getOneBitSet(32, 29),
- CarryKnown)) {
- return &II;
- }
- break;
- }
- case Intrinsic::arm_mve_vmldava: {
- Instruction *I = cast<Instruction>(&II);
- if (I->hasOneUse()) {
- auto *User = cast<Instruction>(*I->user_begin());
- Value *OpZ;
- if (match(User, m_c_Add(m_Specific(I), m_Value(OpZ))) &&
- match(I->getOperand(3), m_Zero())) {
- Value *OpX = I->getOperand(4);
- Value *OpY = I->getOperand(5);
- Type *OpTy = OpX->getType();
-
- IC.Builder.SetInsertPoint(User);
- Value *V =
- IC.Builder.CreateIntrinsic(Intrinsic::arm_mve_vmldava, {OpTy},
- {I->getOperand(0), I->getOperand(1),
- I->getOperand(2), OpZ, OpX, OpY});
-
- IC.replaceInstUsesWith(*User, V);
- return IC.eraseInstFromFunction(*User);
- }
- }
- return None;
- }
- }
- return None;
-}
-
+Optional<Instruction *>
+ARMTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
+ using namespace PatternMatch;
+ Intrinsic::ID IID = II.getIntrinsicID();
+ switch (IID) {
+ default:
+ break;
+ case Intrinsic::arm_neon_vld1: {
+ Align MemAlign =
+ getKnownAlignment(II.getArgOperand(0), IC.getDataLayout(), &II,
+ &IC.getAssumptionCache(), &IC.getDominatorTree());
+ if (Value *V = simplifyNeonVld1(II, MemAlign.value(), IC.Builder)) {
+ return IC.replaceInstUsesWith(II, V);
+ }
+ break;
+ }
+
+ case Intrinsic::arm_neon_vld2:
+ case Intrinsic::arm_neon_vld3:
+ case Intrinsic::arm_neon_vld4:
+ case Intrinsic::arm_neon_vld2lane:
+ case Intrinsic::arm_neon_vld3lane:
+ case Intrinsic::arm_neon_vld4lane:
+ case Intrinsic::arm_neon_vst1:
+ case Intrinsic::arm_neon_vst2:
+ case Intrinsic::arm_neon_vst3:
+ case Intrinsic::arm_neon_vst4:
+ case Intrinsic::arm_neon_vst2lane:
+ case Intrinsic::arm_neon_vst3lane:
+ case Intrinsic::arm_neon_vst4lane: {
+ Align MemAlign =
+ getKnownAlignment(II.getArgOperand(0), IC.getDataLayout(), &II,
+ &IC.getAssumptionCache(), &IC.getDominatorTree());
+ unsigned AlignArg = II.getNumArgOperands() - 1;
+ Value *AlignArgOp = II.getArgOperand(AlignArg);
+ MaybeAlign Align = cast<ConstantInt>(AlignArgOp)->getMaybeAlignValue();
+ if (Align && *Align < MemAlign) {
+ return IC.replaceOperand(
+ II, AlignArg,
+ ConstantInt::get(Type::getInt32Ty(II.getContext()), MemAlign.value(),
+ false));
+ }
+ break;
+ }
+
+ case Intrinsic::arm_mve_pred_i2v: {
+ Value *Arg = II.getArgOperand(0);
+ Value *ArgArg;
+ if (match(Arg, PatternMatch::m_Intrinsic<Intrinsic::arm_mve_pred_v2i>(
+ PatternMatch::m_Value(ArgArg))) &&
+ II.getType() == ArgArg->getType()) {
+ return IC.replaceInstUsesWith(II, ArgArg);
+ }
+ Constant *XorMask;
+ if (match(Arg, m_Xor(PatternMatch::m_Intrinsic<Intrinsic::arm_mve_pred_v2i>(
+ PatternMatch::m_Value(ArgArg)),
+ PatternMatch::m_Constant(XorMask))) &&
+ II.getType() == ArgArg->getType()) {
+ if (auto *CI = dyn_cast<ConstantInt>(XorMask)) {
+ if (CI->getValue().trunc(16).isAllOnesValue()) {
+ auto TrueVector = IC.Builder.CreateVectorSplat(
+ cast<FixedVectorType>(II.getType())->getNumElements(),
+ IC.Builder.getTrue());
+ return BinaryOperator::Create(Instruction::Xor, ArgArg, TrueVector);
+ }
+ }
+ }
+ KnownBits ScalarKnown(32);
+ if (IC.SimplifyDemandedBits(&II, 0, APInt::getLowBitsSet(32, 16),
+ ScalarKnown, 0)) {
+ return &II;
+ }
+ break;
+ }
+ case Intrinsic::arm_mve_pred_v2i: {
+ Value *Arg = II.getArgOperand(0);
+ Value *ArgArg;
+ if (match(Arg, PatternMatch::m_Intrinsic<Intrinsic::arm_mve_pred_i2v>(
+ PatternMatch::m_Value(ArgArg)))) {
+ return IC.replaceInstUsesWith(II, ArgArg);
+ }
+ if (!II.getMetadata(LLVMContext::MD_range)) {
+ Type *IntTy32 = Type::getInt32Ty(II.getContext());
+ Metadata *M[] = {
+ ConstantAsMetadata::get(ConstantInt::get(IntTy32, 0)),
+ ConstantAsMetadata::get(ConstantInt::get(IntTy32, 0xFFFF))};
+ II.setMetadata(LLVMContext::MD_range, MDNode::get(II.getContext(), M));
+ return &II;
+ }
+ break;
+ }
+ case Intrinsic::arm_mve_vadc:
+ case Intrinsic::arm_mve_vadc_predicated: {
+ unsigned CarryOp =
+ (II.getIntrinsicID() == Intrinsic::arm_mve_vadc_predicated) ? 3 : 2;
+ assert(II.getArgOperand(CarryOp)->getType()->getScalarSizeInBits() == 32 &&
+ "Bad type for intrinsic!");
+
+ KnownBits CarryKnown(32);
+ if (IC.SimplifyDemandedBits(&II, CarryOp, APInt::getOneBitSet(32, 29),
+ CarryKnown)) {
+ return &II;
+ }
+ break;
+ }
+ case Intrinsic::arm_mve_vmldava: {
+ Instruction *I = cast<Instruction>(&II);
+ if (I->hasOneUse()) {
+ auto *User = cast<Instruction>(*I->user_begin());
+ Value *OpZ;
+ if (match(User, m_c_Add(m_Specific(I), m_Value(OpZ))) &&
+ match(I->getOperand(3), m_Zero())) {
+ Value *OpX = I->getOperand(4);
+ Value *OpY = I->getOperand(5);
+ Type *OpTy = OpX->getType();
+
+ IC.Builder.SetInsertPoint(User);
+ Value *V =
+ IC.Builder.CreateIntrinsic(Intrinsic::arm_mve_vmldava, {OpTy},
+ {I->getOperand(0), I->getOperand(1),
+ I->getOperand(2), OpZ, OpX, OpY});
+
+ IC.replaceInstUsesWith(*User, V);
+ return IC.eraseInstFromFunction(*User);
+ }
+ }
+ return None;
+ }
+ }
+ return None;
+}
+
int ARMTTIImpl::getIntImmCost(const APInt &Imm, Type *Ty,
TTI::TargetCostKind CostKind) {
assert(Ty->isIntegerTy());
@@ -289,43 +289,43 @@ int ARMTTIImpl::getIntImmCodeSizeCost(unsigned Opcode, unsigned Idx,
return 1;
}
-// Checks whether Inst is part of a min(max()) or max(min()) pattern
-// that will match to an SSAT instruction
-static bool isSSATMinMaxPattern(Instruction *Inst, const APInt &Imm) {
- Value *LHS, *RHS;
- ConstantInt *C;
- SelectPatternFlavor InstSPF = matchSelectPattern(Inst, LHS, RHS).Flavor;
-
- if (InstSPF == SPF_SMAX &&
- PatternMatch::match(RHS, PatternMatch::m_ConstantInt(C)) &&
- C->getValue() == Imm && Imm.isNegative() && (-Imm).isPowerOf2()) {
-
- auto isSSatMin = [&](Value *MinInst) {
- if (isa<SelectInst>(MinInst)) {
- Value *MinLHS, *MinRHS;
- ConstantInt *MinC;
- SelectPatternFlavor MinSPF =
- matchSelectPattern(MinInst, MinLHS, MinRHS).Flavor;
- if (MinSPF == SPF_SMIN &&
- PatternMatch::match(MinRHS, PatternMatch::m_ConstantInt(MinC)) &&
- MinC->getValue() == ((-Imm) - 1))
- return true;
- }
- return false;
- };
-
- if (isSSatMin(Inst->getOperand(1)) ||
- (Inst->hasNUses(2) && (isSSatMin(*Inst->user_begin()) ||
- isSSatMin(*(++Inst->user_begin())))))
- return true;
- }
- return false;
-}
-
-int ARMTTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx,
- const APInt &Imm, Type *Ty,
- TTI::TargetCostKind CostKind,
- Instruction *Inst) {
+// Checks whether Inst is part of a min(max()) or max(min()) pattern
+// that will match to an SSAT instruction
+static bool isSSATMinMaxPattern(Instruction *Inst, const APInt &Imm) {
+ Value *LHS, *RHS;
+ ConstantInt *C;
+ SelectPatternFlavor InstSPF = matchSelectPattern(Inst, LHS, RHS).Flavor;
+
+ if (InstSPF == SPF_SMAX &&
+ PatternMatch::match(RHS, PatternMatch::m_ConstantInt(C)) &&
+ C->getValue() == Imm && Imm.isNegative() && (-Imm).isPowerOf2()) {
+
+ auto isSSatMin = [&](Value *MinInst) {
+ if (isa<SelectInst>(MinInst)) {
+ Value *MinLHS, *MinRHS;
+ ConstantInt *MinC;
+ SelectPatternFlavor MinSPF =
+ matchSelectPattern(MinInst, MinLHS, MinRHS).Flavor;
+ if (MinSPF == SPF_SMIN &&
+ PatternMatch::match(MinRHS, PatternMatch::m_ConstantInt(MinC)) &&
+ MinC->getValue() == ((-Imm) - 1))
+ return true;
+ }
+ return false;
+ };
+
+ if (isSSatMin(Inst->getOperand(1)) ||
+ (Inst->hasNUses(2) && (isSSatMin(*Inst->user_begin()) ||
+ isSSatMin(*(++Inst->user_begin())))))
+ return true;
+ }
+ return false;
+}
+
+int ARMTTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx,
+ const APInt &Imm, Type *Ty,
+ TTI::TargetCostKind CostKind,
+ Instruction *Inst) {
// Division by a constant can be turned into multiplication, but only if we
// know it's constant. So it's not so much that the immediate is cheap (it's
// not), but that the alternative is worse.
@@ -364,33 +364,33 @@ int ARMTTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx,
if (Opcode == Instruction::Xor && Imm.isAllOnesValue())
return 0;
- // Ensures negative constant of min(max()) or max(min()) patterns that
- // match to SSAT instructions don't get hoisted
- if (Inst && ((ST->hasV6Ops() && !ST->isThumb()) || ST->isThumb2()) &&
- Ty->getIntegerBitWidth() <= 32) {
- if (isSSATMinMaxPattern(Inst, Imm) ||
- (isa<ICmpInst>(Inst) && Inst->hasOneUse() &&
- isSSATMinMaxPattern(cast<Instruction>(*Inst->user_begin()), Imm)))
- return 0;
- }
-
+ // Ensures negative constant of min(max()) or max(min()) patterns that
+ // match to SSAT instructions don't get hoisted
+ if (Inst && ((ST->hasV6Ops() && !ST->isThumb()) || ST->isThumb2()) &&
+ Ty->getIntegerBitWidth() <= 32) {
+ if (isSSATMinMaxPattern(Inst, Imm) ||
+ (isa<ICmpInst>(Inst) && Inst->hasOneUse() &&
+ isSSATMinMaxPattern(cast<Instruction>(*Inst->user_begin()), Imm)))
+ return 0;
+ }
+
return getIntImmCost(Imm, Ty, CostKind);
}
-int ARMTTIImpl::getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind) {
- if (CostKind == TTI::TCK_RecipThroughput &&
- (ST->hasNEON() || ST->hasMVEIntegerOps())) {
- // FIXME: The vectorizer is highly sensistive to the cost of these
- // instructions, which suggests that it may be using the costs incorrectly.
- // But, for now, just make them free to avoid performance regressions for
- // vector targets.
- return 0;
- }
- return BaseT::getCFInstrCost(Opcode, CostKind);
-}
-
+int ARMTTIImpl::getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind) {
+ if (CostKind == TTI::TCK_RecipThroughput &&
+ (ST->hasNEON() || ST->hasMVEIntegerOps())) {
+ // FIXME: The vectorizer is highly sensistive to the cost of these
+ // instructions, which suggests that it may be using the costs incorrectly.
+ // But, for now, just make them free to avoid performance regressions for
+ // vector targets.
+ return 0;
+ }
+ return BaseT::getCFInstrCost(Opcode, CostKind);
+}
+
int ARMTTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
- TTI::CastContextHint CCH,
+ TTI::CastContextHint CCH,
TTI::TargetCostKind CostKind,
const Instruction *I) {
int ISD = TLI->InstructionOpcodeToISD(Opcode);
@@ -402,35 +402,35 @@ int ARMTTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
return Cost == 0 ? 0 : 1;
return Cost;
};
- auto IsLegalFPType = [this](EVT VT) {
- EVT EltVT = VT.getScalarType();
- return (EltVT == MVT::f32 && ST->hasVFP2Base()) ||
- (EltVT == MVT::f64 && ST->hasFP64()) ||
- (EltVT == MVT::f16 && ST->hasFullFP16());
- };
+ auto IsLegalFPType = [this](EVT VT) {
+ EVT EltVT = VT.getScalarType();
+ return (EltVT == MVT::f32 && ST->hasVFP2Base()) ||
+ (EltVT == MVT::f64 && ST->hasFP64()) ||
+ (EltVT == MVT::f16 && ST->hasFullFP16());
+ };
EVT SrcTy = TLI->getValueType(DL, Src);
EVT DstTy = TLI->getValueType(DL, Dst);
if (!SrcTy.isSimple() || !DstTy.isSimple())
- return AdjustCost(
- BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I));
-
- // Extending masked load/Truncating masked stores is expensive because we
- // currently don't split them. This means that we'll likely end up
- // loading/storing each element individually (hence the high cost).
- if ((ST->hasMVEIntegerOps() &&
- (Opcode == Instruction::Trunc || Opcode == Instruction::ZExt ||
- Opcode == Instruction::SExt)) ||
- (ST->hasMVEFloatOps() &&
- (Opcode == Instruction::FPExt || Opcode == Instruction::FPTrunc) &&
- IsLegalFPType(SrcTy) && IsLegalFPType(DstTy)))
- if (CCH == TTI::CastContextHint::Masked && DstTy.getSizeInBits() > 128)
- return 2 * DstTy.getVectorNumElements() * ST->getMVEVectorCostFactor();
-
- // The extend of other kinds of load is free
- if (CCH == TTI::CastContextHint::Normal ||
- CCH == TTI::CastContextHint::Masked) {
+ return AdjustCost(
+ BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I));
+
+ // Extending masked load/Truncating masked stores is expensive because we
+ // currently don't split them. This means that we'll likely end up
+ // loading/storing each element individually (hence the high cost).
+ if ((ST->hasMVEIntegerOps() &&
+ (Opcode == Instruction::Trunc || Opcode == Instruction::ZExt ||
+ Opcode == Instruction::SExt)) ||
+ (ST->hasMVEFloatOps() &&
+ (Opcode == Instruction::FPExt || Opcode == Instruction::FPTrunc) &&
+ IsLegalFPType(SrcTy) && IsLegalFPType(DstTy)))
+ if (CCH == TTI::CastContextHint::Masked && DstTy.getSizeInBits() > 128)
+ return 2 * DstTy.getVectorNumElements() * ST->getMVEVectorCostFactor();
+
+ // The extend of other kinds of load is free
+ if (CCH == TTI::CastContextHint::Normal ||
+ CCH == TTI::CastContextHint::Masked) {
static const TypeConversionCostTblEntry LoadConversionTbl[] = {
{ISD::SIGN_EXTEND, MVT::i32, MVT::i16, 0},
{ISD::ZERO_EXTEND, MVT::i32, MVT::i16, 0},
@@ -485,31 +485,31 @@ int ARMTTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
return AdjustCost(Entry->Cost * ST->getMVEVectorCostFactor());
}
- // The truncate of a store is free. This is the mirror of extends above.
- static const TypeConversionCostTblEntry MVEStoreConversionTbl[] = {
+ // The truncate of a store is free. This is the mirror of extends above.
+ static const TypeConversionCostTblEntry MVEStoreConversionTbl[] = {
{ISD::TRUNCATE, MVT::v4i32, MVT::v4i16, 0},
{ISD::TRUNCATE, MVT::v4i32, MVT::v4i8, 0},
{ISD::TRUNCATE, MVT::v8i16, MVT::v8i8, 0},
{ISD::TRUNCATE, MVT::v8i32, MVT::v8i16, 1},
- {ISD::TRUNCATE, MVT::v8i32, MVT::v8i8, 1},
+ {ISD::TRUNCATE, MVT::v8i32, MVT::v8i8, 1},
{ISD::TRUNCATE, MVT::v16i32, MVT::v16i8, 3},
{ISD::TRUNCATE, MVT::v16i16, MVT::v16i8, 1},
};
if (SrcTy.isVector() && ST->hasMVEIntegerOps()) {
if (const auto *Entry =
- ConvertCostTableLookup(MVEStoreConversionTbl, ISD,
- SrcTy.getSimpleVT(), DstTy.getSimpleVT()))
+ ConvertCostTableLookup(MVEStoreConversionTbl, ISD,
+ SrcTy.getSimpleVT(), DstTy.getSimpleVT()))
return AdjustCost(Entry->Cost * ST->getMVEVectorCostFactor());
}
- static const TypeConversionCostTblEntry MVEFStoreConversionTbl[] = {
+ static const TypeConversionCostTblEntry MVEFStoreConversionTbl[] = {
{ISD::FP_ROUND, MVT::v4f32, MVT::v4f16, 1},
{ISD::FP_ROUND, MVT::v8f32, MVT::v8f16, 3},
};
if (SrcTy.isVector() && ST->hasMVEFloatOps()) {
if (const auto *Entry =
- ConvertCostTableLookup(MVEFStoreConversionTbl, ISD,
- SrcTy.getSimpleVT(), DstTy.getSimpleVT()))
+ ConvertCostTableLookup(MVEFStoreConversionTbl, ISD,
+ SrcTy.getSimpleVT(), DstTy.getSimpleVT()))
return AdjustCost(Entry->Cost * ST->getMVEVectorCostFactor());
}
}
@@ -746,24 +746,24 @@ int ARMTTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
if (SrcTy.isFixedLengthVector())
Lanes = SrcTy.getVectorNumElements();
- if (IsLegalFPType(SrcTy) && IsLegalFPType(DstTy))
+ if (IsLegalFPType(SrcTy) && IsLegalFPType(DstTy))
return Lanes;
else
return Lanes * CallCost;
}
- if (ISD == ISD::TRUNCATE && ST->hasMVEIntegerOps() &&
- SrcTy.isFixedLengthVector()) {
- // Treat a truncate with larger than legal source (128bits for MVE) as
- // expensive, 2 instructions per lane.
- if ((SrcTy.getScalarType() == MVT::i8 ||
- SrcTy.getScalarType() == MVT::i16 ||
- SrcTy.getScalarType() == MVT::i32) &&
- SrcTy.getSizeInBits() > 128 &&
- SrcTy.getSizeInBits() > DstTy.getSizeInBits())
- return SrcTy.getVectorNumElements() * 2;
- }
-
+ if (ISD == ISD::TRUNCATE && ST->hasMVEIntegerOps() &&
+ SrcTy.isFixedLengthVector()) {
+ // Treat a truncate with larger than legal source (128bits for MVE) as
+ // expensive, 2 instructions per lane.
+ if ((SrcTy.getScalarType() == MVT::i8 ||
+ SrcTy.getScalarType() == MVT::i16 ||
+ SrcTy.getScalarType() == MVT::i32) &&
+ SrcTy.getSizeInBits() > 128 &&
+ SrcTy.getSizeInBits() > DstTy.getSizeInBits())
+ return SrcTy.getVectorNumElements() * 2;
+ }
+
// Scalar integer conversion costs.
static const TypeConversionCostTblEntry ARMIntegerConversionTbl[] = {
// i16 -> i64 requires two dependent operations.
@@ -787,7 +787,7 @@ int ARMTTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
? ST->getMVEVectorCostFactor()
: 1;
return AdjustCost(
- BaseCost * BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I));
+ BaseCost * BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I));
}
int ARMTTIImpl::getVectorInstrCost(unsigned Opcode, Type *ValTy,
@@ -827,37 +827,37 @@ int ARMTTIImpl::getVectorInstrCost(unsigned Opcode, Type *ValTy,
}
int ARMTTIImpl::getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
- CmpInst::Predicate VecPred,
+ CmpInst::Predicate VecPred,
TTI::TargetCostKind CostKind,
const Instruction *I) {
- int ISD = TLI->InstructionOpcodeToISD(Opcode);
-
- // Thumb scalar code size cost for select.
- if (CostKind == TTI::TCK_CodeSize && ISD == ISD::SELECT &&
- ST->isThumb() && !ValTy->isVectorTy()) {
- // Assume expensive structs.
- if (TLI->getValueType(DL, ValTy, true) == MVT::Other)
- return TTI::TCC_Expensive;
-
- // Select costs can vary because they:
- // - may require one or more conditional mov (including an IT),
- // - can't operate directly on immediates,
- // - require live flags, which we can't copy around easily.
- int Cost = TLI->getTypeLegalizationCost(DL, ValTy).first;
-
- // Possible IT instruction for Thumb2, or more for Thumb1.
- ++Cost;
-
- // i1 values may need rematerialising by using mov immediates and/or
- // flag setting instructions.
- if (ValTy->isIntegerTy(1))
- ++Cost;
-
- return Cost;
- }
-
+ int ISD = TLI->InstructionOpcodeToISD(Opcode);
+
+ // Thumb scalar code size cost for select.
+ if (CostKind == TTI::TCK_CodeSize && ISD == ISD::SELECT &&
+ ST->isThumb() && !ValTy->isVectorTy()) {
+ // Assume expensive structs.
+ if (TLI->getValueType(DL, ValTy, true) == MVT::Other)
+ return TTI::TCC_Expensive;
+
+ // Select costs can vary because they:
+ // - may require one or more conditional mov (including an IT),
+ // - can't operate directly on immediates,
+ // - require live flags, which we can't copy around easily.
+ int Cost = TLI->getTypeLegalizationCost(DL, ValTy).first;
+
+ // Possible IT instruction for Thumb2, or more for Thumb1.
+ ++Cost;
+
+ // i1 values may need rematerialising by using mov immediates and/or
+ // flag setting instructions.
+ if (ValTy->isIntegerTy(1))
+ ++Cost;
+
+ return Cost;
+ }
+
// On NEON a vector select gets lowered to vbsl.
- if (ST->hasNEON() && ValTy->isVectorTy() && ISD == ISD::SELECT && CondTy) {
+ if (ST->hasNEON() && ValTy->isVectorTy() && ISD == ISD::SELECT && CondTy) {
// Lowering of some vector selects is currently far from perfect.
static const TypeConversionCostTblEntry NEONVectorSelectTbl[] = {
{ ISD::SELECT, MVT::v4i1, MVT::v4i64, 4*4 + 1*2 + 1 },
@@ -878,15 +878,15 @@ int ARMTTIImpl::getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
return LT.first;
}
- // Default to cheap (throughput/size of 1 instruction) but adjust throughput
- // for "multiple beats" potentially needed by MVE instructions.
- int BaseCost = 1;
- if (CostKind != TTI::TCK_CodeSize && ST->hasMVEIntegerOps() &&
- ValTy->isVectorTy())
- BaseCost = ST->getMVEVectorCostFactor();
-
- return BaseCost *
- BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind, I);
+ // Default to cheap (throughput/size of 1 instruction) but adjust throughput
+ // for "multiple beats" potentially needed by MVE instructions.
+ int BaseCost = 1;
+ if (CostKind != TTI::TCK_CodeSize && ST->hasMVEIntegerOps() &&
+ ValTy->isVectorTy())
+ BaseCost = ST->getMVEVectorCostFactor();
+
+ return BaseCost *
+ BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind, I);
}
int ARMTTIImpl::getAddressComputationCost(Type *Ty, ScalarEvolution *SE,
@@ -968,85 +968,85 @@ bool ARMTTIImpl::isLegalMaskedGather(Type *Ty, Align Alignment) {
(EltWidth == 16 && Alignment >= 2) || EltWidth == 8);
}
-/// Given a memcpy/memset/memmove instruction, return the number of memory
-/// operations performed, via querying findOptimalMemOpLowering. Returns -1 if a
-/// call is used.
-int ARMTTIImpl::getNumMemOps(const IntrinsicInst *I) const {
- MemOp MOp;
- unsigned DstAddrSpace = ~0u;
- unsigned SrcAddrSpace = ~0u;
- const Function *F = I->getParent()->getParent();
-
- if (const auto *MC = dyn_cast<MemTransferInst>(I)) {
- ConstantInt *C = dyn_cast<ConstantInt>(MC->getLength());
- // If 'size' is not a constant, a library call will be generated.
- if (!C)
- return -1;
-
- const unsigned Size = C->getValue().getZExtValue();
- const Align DstAlign = *MC->getDestAlign();
- const Align SrcAlign = *MC->getSourceAlign();
-
- MOp = MemOp::Copy(Size, /*DstAlignCanChange*/ false, DstAlign, SrcAlign,
- /*IsVolatile*/ false);
- DstAddrSpace = MC->getDestAddressSpace();
- SrcAddrSpace = MC->getSourceAddressSpace();
- }
- else if (const auto *MS = dyn_cast<MemSetInst>(I)) {
- ConstantInt *C = dyn_cast<ConstantInt>(MS->getLength());
- // If 'size' is not a constant, a library call will be generated.
- if (!C)
- return -1;
-
- const unsigned Size = C->getValue().getZExtValue();
- const Align DstAlign = *MS->getDestAlign();
-
- MOp = MemOp::Set(Size, /*DstAlignCanChange*/ false, DstAlign,
- /*IsZeroMemset*/ false, /*IsVolatile*/ false);
- DstAddrSpace = MS->getDestAddressSpace();
- }
- else
- llvm_unreachable("Expected a memcpy/move or memset!");
-
- unsigned Limit, Factor = 2;
- switch(I->getIntrinsicID()) {
- case Intrinsic::memcpy:
- Limit = TLI->getMaxStoresPerMemcpy(F->hasMinSize());
- break;
- case Intrinsic::memmove:
- Limit = TLI->getMaxStoresPerMemmove(F->hasMinSize());
- break;
- case Intrinsic::memset:
- Limit = TLI->getMaxStoresPerMemset(F->hasMinSize());
- Factor = 1;
- break;
- default:
- llvm_unreachable("Expected a memcpy/move or memset!");
- }
-
+/// Given a memcpy/memset/memmove instruction, return the number of memory
+/// operations performed, via querying findOptimalMemOpLowering. Returns -1 if a
+/// call is used.
+int ARMTTIImpl::getNumMemOps(const IntrinsicInst *I) const {
+ MemOp MOp;
+ unsigned DstAddrSpace = ~0u;
+ unsigned SrcAddrSpace = ~0u;
+ const Function *F = I->getParent()->getParent();
+
+ if (const auto *MC = dyn_cast<MemTransferInst>(I)) {
+ ConstantInt *C = dyn_cast<ConstantInt>(MC->getLength());
+ // If 'size' is not a constant, a library call will be generated.
+ if (!C)
+ return -1;
+
+ const unsigned Size = C->getValue().getZExtValue();
+ const Align DstAlign = *MC->getDestAlign();
+ const Align SrcAlign = *MC->getSourceAlign();
+
+ MOp = MemOp::Copy(Size, /*DstAlignCanChange*/ false, DstAlign, SrcAlign,
+ /*IsVolatile*/ false);
+ DstAddrSpace = MC->getDestAddressSpace();
+ SrcAddrSpace = MC->getSourceAddressSpace();
+ }
+ else if (const auto *MS = dyn_cast<MemSetInst>(I)) {
+ ConstantInt *C = dyn_cast<ConstantInt>(MS->getLength());
+ // If 'size' is not a constant, a library call will be generated.
+ if (!C)
+ return -1;
+
+ const unsigned Size = C->getValue().getZExtValue();
+ const Align DstAlign = *MS->getDestAlign();
+
+ MOp = MemOp::Set(Size, /*DstAlignCanChange*/ false, DstAlign,
+ /*IsZeroMemset*/ false, /*IsVolatile*/ false);
+ DstAddrSpace = MS->getDestAddressSpace();
+ }
+ else
+ llvm_unreachable("Expected a memcpy/move or memset!");
+
+ unsigned Limit, Factor = 2;
+ switch(I->getIntrinsicID()) {
+ case Intrinsic::memcpy:
+ Limit = TLI->getMaxStoresPerMemcpy(F->hasMinSize());
+ break;
+ case Intrinsic::memmove:
+ Limit = TLI->getMaxStoresPerMemmove(F->hasMinSize());
+ break;
+ case Intrinsic::memset:
+ Limit = TLI->getMaxStoresPerMemset(F->hasMinSize());
+ Factor = 1;
+ break;
+ default:
+ llvm_unreachable("Expected a memcpy/move or memset!");
+ }
+
// MemOps will be poplulated with a list of data types that needs to be
// loaded and stored. That's why we multiply the number of elements by 2 to
// get the cost for this memcpy.
- std::vector<EVT> MemOps;
+ std::vector<EVT> MemOps;
if (getTLI()->findOptimalMemOpLowering(
- MemOps, Limit, MOp, DstAddrSpace,
- SrcAddrSpace, F->getAttributes()))
- return MemOps.size() * Factor;
+ MemOps, Limit, MOp, DstAddrSpace,
+ SrcAddrSpace, F->getAttributes()))
+ return MemOps.size() * Factor;
// If we can't find an optimal memop lowering, return the default cost
- return -1;
+ return -1;
+}
+
+int ARMTTIImpl::getMemcpyCost(const Instruction *I) {
+ int NumOps = getNumMemOps(cast<IntrinsicInst>(I));
+
+ // To model the cost of a library call, we assume 1 for the call, and
+ // 3 for the argument setup.
+ if (NumOps == -1)
+ return 4;
+ return NumOps;
}
-int ARMTTIImpl::getMemcpyCost(const Instruction *I) {
- int NumOps = getNumMemOps(cast<IntrinsicInst>(I));
-
- // To model the cost of a library call, we assume 1 for the call, and
- // 3 for the argument setup.
- if (NumOps == -1)
- return 4;
- return NumOps;
-}
-
int ARMTTIImpl::getShuffleCost(TTI::ShuffleKind Kind, VectorType *Tp,
int Index, VectorType *SubTp) {
if (ST->hasNEON()) {
@@ -1149,21 +1149,21 @@ int ARMTTIImpl::getArithmeticInstrCost(unsigned Opcode, Type *Ty,
TTI::OperandValueProperties Opd2PropInfo,
ArrayRef<const Value *> Args,
const Instruction *CxtI) {
- int ISDOpcode = TLI->InstructionOpcodeToISD(Opcode);
- if (ST->isThumb() && CostKind == TTI::TCK_CodeSize && Ty->isIntegerTy(1)) {
- // Make operations on i1 relatively expensive as this often involves
- // combining predicates. AND and XOR should be easier to handle with IT
- // blocks.
- switch (ISDOpcode) {
- default:
- break;
- case ISD::AND:
- case ISD::XOR:
- return 2;
- case ISD::OR:
- return 3;
- }
- }
+ int ISDOpcode = TLI->InstructionOpcodeToISD(Opcode);
+ if (ST->isThumb() && CostKind == TTI::TCK_CodeSize && Ty->isIntegerTy(1)) {
+ // Make operations on i1 relatively expensive as this often involves
+ // combining predicates. AND and XOR should be easier to handle with IT
+ // blocks.
+ switch (ISDOpcode) {
+ default:
+ break;
+ case ISD::AND:
+ case ISD::XOR:
+ return 2;
+ case ISD::OR:
+ return 3;
+ }
+ }
std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, Ty);
@@ -1259,12 +1259,12 @@ int ARMTTIImpl::getArithmeticInstrCost(unsigned Opcode, Type *Ty,
if (LooksLikeAFreeShift())
return 0;
- // Default to cheap (throughput/size of 1 instruction) but adjust throughput
- // for "multiple beats" potentially needed by MVE instructions.
- int BaseCost = 1;
- if (CostKind != TTI::TCK_CodeSize && ST->hasMVEIntegerOps() &&
- Ty->isVectorTy())
- BaseCost = ST->getMVEVectorCostFactor();
+ // Default to cheap (throughput/size of 1 instruction) but adjust throughput
+ // for "multiple beats" potentially needed by MVE instructions.
+ int BaseCost = 1;
+ if (CostKind != TTI::TCK_CodeSize && ST->hasMVEIntegerOps() &&
+ Ty->isVectorTy())
+ BaseCost = ST->getMVEVectorCostFactor();
// The rest of this mostly follows what is done in BaseT::getArithmeticInstrCost,
// without treating floats as more expensive that scalars or increasing the
@@ -1331,24 +1331,24 @@ int ARMTTIImpl::getMemoryOpCost(unsigned Opcode, Type *Src,
CostKind, I);
}
-unsigned ARMTTIImpl::getMaskedMemoryOpCost(unsigned Opcode, Type *Src,
- Align Alignment,
- unsigned AddressSpace,
- TTI::TargetCostKind CostKind) {
- if (ST->hasMVEIntegerOps()) {
- if (Opcode == Instruction::Load && isLegalMaskedLoad(Src, Alignment))
- return ST->getMVEVectorCostFactor();
- if (Opcode == Instruction::Store && isLegalMaskedStore(Src, Alignment))
- return ST->getMVEVectorCostFactor();
- }
- if (!isa<FixedVectorType>(Src))
- return BaseT::getMaskedMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
- CostKind);
- // Scalar cost, which is currently very high due to the efficiency of the
- // generated code.
- return cast<FixedVectorType>(Src)->getNumElements() * 8;
-}
-
+unsigned ARMTTIImpl::getMaskedMemoryOpCost(unsigned Opcode, Type *Src,
+ Align Alignment,
+ unsigned AddressSpace,
+ TTI::TargetCostKind CostKind) {
+ if (ST->hasMVEIntegerOps()) {
+ if (Opcode == Instruction::Load && isLegalMaskedLoad(Src, Alignment))
+ return ST->getMVEVectorCostFactor();
+ if (Opcode == Instruction::Store && isLegalMaskedStore(Src, Alignment))
+ return ST->getMVEVectorCostFactor();
+ }
+ if (!isa<FixedVectorType>(Src))
+ return BaseT::getMaskedMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
+ CostKind);
+ // Scalar cost, which is currently very high due to the efficiency of the
+ // generated code.
+ return cast<FixedVectorType>(Src)->getNumElements() * 8;
+}
+
int ARMTTIImpl::getInterleavedMemoryOpCost(
unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
@@ -1379,8 +1379,8 @@ int ARMTTIImpl::getInterleavedMemoryOpCost(
// promoted differently). The cost of 2 here is then a load and vrev or
// vmovn.
if (ST->hasMVEIntegerOps() && Factor == 2 && NumElts / Factor > 2 &&
- VecTy->isIntOrIntVectorTy() &&
- DL.getTypeSizeInBits(SubVecTy).getFixedSize() <= 64)
+ VecTy->isIntOrIntVectorTy() &&
+ DL.getTypeSizeInBits(SubVecTy).getFixedSize() <= 64)
return 2 * BaseCost;
}
@@ -1413,13 +1413,13 @@ unsigned ARMTTIImpl::getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
// multiplied by the number of elements being loaded. This is possibly very
// conservative, but even so we still end up vectorising loops because the
// cost per iteration for many loops is lower than for scalar loops.
- unsigned VectorCost = NumElems * LT.first * ST->getMVEVectorCostFactor();
+ unsigned VectorCost = NumElems * LT.first * ST->getMVEVectorCostFactor();
// The scalarization cost should be a lot higher. We use the number of vector
// elements plus the scalarization overhead.
unsigned ScalarCost =
NumElems * LT.first + BaseT::getScalarizationOverhead(VTy, {});
- if (EltSize < 8 || Alignment < EltSize / 8)
+ if (EltSize < 8 || Alignment < EltSize / 8)
return ScalarCost;
unsigned ExtSize = EltSize;
@@ -1488,92 +1488,92 @@ unsigned ARMTTIImpl::getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
return ScalarCost;
}
-int ARMTTIImpl::getArithmeticReductionCost(unsigned Opcode, VectorType *ValTy,
- bool IsPairwiseForm,
- TTI::TargetCostKind CostKind) {
- EVT ValVT = TLI->getValueType(DL, ValTy);
- int ISD = TLI->InstructionOpcodeToISD(Opcode);
- if (!ST->hasMVEIntegerOps() || !ValVT.isSimple() || ISD != ISD::ADD)
- return BaseT::getArithmeticReductionCost(Opcode, ValTy, IsPairwiseForm,
- CostKind);
-
- std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, ValTy);
-
- static const CostTblEntry CostTblAdd[]{
- {ISD::ADD, MVT::v16i8, 1},
- {ISD::ADD, MVT::v8i16, 1},
- {ISD::ADD, MVT::v4i32, 1},
- };
- if (const auto *Entry = CostTableLookup(CostTblAdd, ISD, LT.second))
- return Entry->Cost * ST->getMVEVectorCostFactor() * LT.first;
-
- return BaseT::getArithmeticReductionCost(Opcode, ValTy, IsPairwiseForm,
- CostKind);
-}
-
-InstructionCost
-ARMTTIImpl::getExtendedAddReductionCost(bool IsMLA, bool IsUnsigned,
- Type *ResTy, VectorType *ValTy,
- TTI::TargetCostKind CostKind) {
- EVT ValVT = TLI->getValueType(DL, ValTy);
- EVT ResVT = TLI->getValueType(DL, ResTy);
- if (ST->hasMVEIntegerOps() && ValVT.isSimple() && ResVT.isSimple()) {
- std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, ValTy);
- if ((LT.second == MVT::v16i8 && ResVT.getSizeInBits() <= 32) ||
- (LT.second == MVT::v8i16 &&
- ResVT.getSizeInBits() <= (IsMLA ? 64 : 32)) ||
- (LT.second == MVT::v4i32 && ResVT.getSizeInBits() <= 64))
- return ST->getMVEVectorCostFactor() * LT.first;
- }
-
- return BaseT::getExtendedAddReductionCost(IsMLA, IsUnsigned, ResTy, ValTy,
- CostKind);
-}
-
-int ARMTTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
- TTI::TargetCostKind CostKind) {
- switch (ICA.getID()) {
- case Intrinsic::get_active_lane_mask:
- // Currently we make a somewhat optimistic assumption that
- // active_lane_mask's are always free. In reality it may be freely folded
- // into a tail predicated loop, expanded into a VCPT or expanded into a lot
- // of add/icmp code. We may need to improve this in the future, but being
- // able to detect if it is free or not involves looking at a lot of other
- // code. We currently assume that the vectorizer inserted these, and knew
- // what it was doing in adding one.
- if (ST->hasMVEIntegerOps())
- return 0;
- break;
- case Intrinsic::sadd_sat:
- case Intrinsic::ssub_sat:
- case Intrinsic::uadd_sat:
- case Intrinsic::usub_sat: {
- if (!ST->hasMVEIntegerOps())
- break;
- // Get the Return type, either directly of from ICA.ReturnType and ICA.VF.
- Type *VT = ICA.getReturnType();
- if (!VT->isVectorTy() && !ICA.getVectorFactor().isScalar())
- VT = VectorType::get(VT, ICA.getVectorFactor());
-
- std::pair<int, MVT> LT =
- TLI->getTypeLegalizationCost(DL, VT);
- if (LT.second == MVT::v4i32 || LT.second == MVT::v8i16 ||
- LT.second == MVT::v16i8) {
- // This is a base cost of 1 for the vadd, plus 3 extract shifts if we
- // need to extend the type, as it uses shr(qadd(shl, shl)).
- unsigned Instrs = LT.second.getScalarSizeInBits() ==
- ICA.getReturnType()->getScalarSizeInBits()
- ? 1
- : 4;
- return LT.first * ST->getMVEVectorCostFactor() * Instrs;
- }
- break;
- }
- }
-
- return BaseT::getIntrinsicInstrCost(ICA, CostKind);
-}
-
+int ARMTTIImpl::getArithmeticReductionCost(unsigned Opcode, VectorType *ValTy,
+ bool IsPairwiseForm,
+ TTI::TargetCostKind CostKind) {
+ EVT ValVT = TLI->getValueType(DL, ValTy);
+ int ISD = TLI->InstructionOpcodeToISD(Opcode);
+ if (!ST->hasMVEIntegerOps() || !ValVT.isSimple() || ISD != ISD::ADD)
+ return BaseT::getArithmeticReductionCost(Opcode, ValTy, IsPairwiseForm,
+ CostKind);
+
+ std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, ValTy);
+
+ static const CostTblEntry CostTblAdd[]{
+ {ISD::ADD, MVT::v16i8, 1},
+ {ISD::ADD, MVT::v8i16, 1},
+ {ISD::ADD, MVT::v4i32, 1},
+ };
+ if (const auto *Entry = CostTableLookup(CostTblAdd, ISD, LT.second))
+ return Entry->Cost * ST->getMVEVectorCostFactor() * LT.first;
+
+ return BaseT::getArithmeticReductionCost(Opcode, ValTy, IsPairwiseForm,
+ CostKind);
+}
+
+InstructionCost
+ARMTTIImpl::getExtendedAddReductionCost(bool IsMLA, bool IsUnsigned,
+ Type *ResTy, VectorType *ValTy,
+ TTI::TargetCostKind CostKind) {
+ EVT ValVT = TLI->getValueType(DL, ValTy);
+ EVT ResVT = TLI->getValueType(DL, ResTy);
+ if (ST->hasMVEIntegerOps() && ValVT.isSimple() && ResVT.isSimple()) {
+ std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, ValTy);
+ if ((LT.second == MVT::v16i8 && ResVT.getSizeInBits() <= 32) ||
+ (LT.second == MVT::v8i16 &&
+ ResVT.getSizeInBits() <= (IsMLA ? 64 : 32)) ||
+ (LT.second == MVT::v4i32 && ResVT.getSizeInBits() <= 64))
+ return ST->getMVEVectorCostFactor() * LT.first;
+ }
+
+ return BaseT::getExtendedAddReductionCost(IsMLA, IsUnsigned, ResTy, ValTy,
+ CostKind);
+}
+
+int ARMTTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
+ TTI::TargetCostKind CostKind) {
+ switch (ICA.getID()) {
+ case Intrinsic::get_active_lane_mask:
+ // Currently we make a somewhat optimistic assumption that
+ // active_lane_mask's are always free. In reality it may be freely folded
+ // into a tail predicated loop, expanded into a VCPT or expanded into a lot
+ // of add/icmp code. We may need to improve this in the future, but being
+ // able to detect if it is free or not involves looking at a lot of other
+ // code. We currently assume that the vectorizer inserted these, and knew
+ // what it was doing in adding one.
+ if (ST->hasMVEIntegerOps())
+ return 0;
+ break;
+ case Intrinsic::sadd_sat:
+ case Intrinsic::ssub_sat:
+ case Intrinsic::uadd_sat:
+ case Intrinsic::usub_sat: {
+ if (!ST->hasMVEIntegerOps())
+ break;
+ // Get the Return type, either directly of from ICA.ReturnType and ICA.VF.
+ Type *VT = ICA.getReturnType();
+ if (!VT->isVectorTy() && !ICA.getVectorFactor().isScalar())
+ VT = VectorType::get(VT, ICA.getVectorFactor());
+
+ std::pair<int, MVT> LT =
+ TLI->getTypeLegalizationCost(DL, VT);
+ if (LT.second == MVT::v4i32 || LT.second == MVT::v8i16 ||
+ LT.second == MVT::v16i8) {
+ // This is a base cost of 1 for the vadd, plus 3 extract shifts if we
+ // need to extend the type, as it uses shr(qadd(shl, shl)).
+ unsigned Instrs = LT.second.getScalarSizeInBits() ==
+ ICA.getReturnType()->getScalarSizeInBits()
+ ? 1
+ : 4;
+ return LT.first * ST->getMVEVectorCostFactor() * Instrs;
+ }
+ break;
+ }
+ }
+
+ return BaseT::getIntrinsicInstrCost(ICA, CostKind);
+}
+
bool ARMTTIImpl::isLoweredToCall(const Function *F) {
if (!F->isIntrinsic())
BaseT::isLoweredToCall(F);
@@ -1635,93 +1635,93 @@ bool ARMTTIImpl::isLoweredToCall(const Function *F) {
return BaseT::isLoweredToCall(F);
}
-bool ARMTTIImpl::maybeLoweredToCall(Instruction &I) {
- unsigned ISD = TLI->InstructionOpcodeToISD(I.getOpcode());
- EVT VT = TLI->getValueType(DL, I.getType(), true);
- if (TLI->getOperationAction(ISD, VT) == TargetLowering::LibCall)
- return true;
-
- // Check if an intrinsic will be lowered to a call and assume that any
- // other CallInst will generate a bl.
- if (auto *Call = dyn_cast<CallInst>(&I)) {
- if (auto *II = dyn_cast<IntrinsicInst>(Call)) {
- switch(II->getIntrinsicID()) {
- case Intrinsic::memcpy:
- case Intrinsic::memset:
- case Intrinsic::memmove:
- return getNumMemOps(II) == -1;
- default:
- if (const Function *F = Call->getCalledFunction())
- return isLoweredToCall(F);
- }
- }
- return true;
- }
-
- // FPv5 provides conversions between integer, double-precision,
- // single-precision, and half-precision formats.
- switch (I.getOpcode()) {
- default:
- break;
- case Instruction::FPToSI:
- case Instruction::FPToUI:
- case Instruction::SIToFP:
- case Instruction::UIToFP:
- case Instruction::FPTrunc:
- case Instruction::FPExt:
- return !ST->hasFPARMv8Base();
- }
-
- // FIXME: Unfortunately the approach of checking the Operation Action does
- // not catch all cases of Legalization that use library calls. Our
- // Legalization step categorizes some transformations into library calls as
- // Custom, Expand or even Legal when doing type legalization. So for now
- // we have to special case for instance the SDIV of 64bit integers and the
- // use of floating point emulation.
- if (VT.isInteger() && VT.getSizeInBits() >= 64) {
- switch (ISD) {
- default:
- break;
- case ISD::SDIV:
- case ISD::UDIV:
- case ISD::SREM:
- case ISD::UREM:
- case ISD::SDIVREM:
- case ISD::UDIVREM:
- return true;
- }
- }
-
- // Assume all other non-float operations are supported.
- if (!VT.isFloatingPoint())
- return false;
-
- // We'll need a library call to handle most floats when using soft.
- if (TLI->useSoftFloat()) {
- switch (I.getOpcode()) {
- default:
- return true;
- case Instruction::Alloca:
- case Instruction::Load:
- case Instruction::Store:
- case Instruction::Select:
- case Instruction::PHI:
- return false;
- }
- }
-
- // We'll need a libcall to perform double precision operations on a single
- // precision only FPU.
- if (I.getType()->isDoubleTy() && !ST->hasFP64())
- return true;
-
- // Likewise for half precision arithmetic.
- if (I.getType()->isHalfTy() && !ST->hasFullFP16())
- return true;
-
- return false;
-}
-
+bool ARMTTIImpl::maybeLoweredToCall(Instruction &I) {
+ unsigned ISD = TLI->InstructionOpcodeToISD(I.getOpcode());
+ EVT VT = TLI->getValueType(DL, I.getType(), true);
+ if (TLI->getOperationAction(ISD, VT) == TargetLowering::LibCall)
+ return true;
+
+ // Check if an intrinsic will be lowered to a call and assume that any
+ // other CallInst will generate a bl.
+ if (auto *Call = dyn_cast<CallInst>(&I)) {
+ if (auto *II = dyn_cast<IntrinsicInst>(Call)) {
+ switch(II->getIntrinsicID()) {
+ case Intrinsic::memcpy:
+ case Intrinsic::memset:
+ case Intrinsic::memmove:
+ return getNumMemOps(II) == -1;
+ default:
+ if (const Function *F = Call->getCalledFunction())
+ return isLoweredToCall(F);
+ }
+ }
+ return true;
+ }
+
+ // FPv5 provides conversions between integer, double-precision,
+ // single-precision, and half-precision formats.
+ switch (I.getOpcode()) {
+ default:
+ break;
+ case Instruction::FPToSI:
+ case Instruction::FPToUI:
+ case Instruction::SIToFP:
+ case Instruction::UIToFP:
+ case Instruction::FPTrunc:
+ case Instruction::FPExt:
+ return !ST->hasFPARMv8Base();
+ }
+
+ // FIXME: Unfortunately the approach of checking the Operation Action does
+ // not catch all cases of Legalization that use library calls. Our
+ // Legalization step categorizes some transformations into library calls as
+ // Custom, Expand or even Legal when doing type legalization. So for now
+ // we have to special case for instance the SDIV of 64bit integers and the
+ // use of floating point emulation.
+ if (VT.isInteger() && VT.getSizeInBits() >= 64) {
+ switch (ISD) {
+ default:
+ break;
+ case ISD::SDIV:
+ case ISD::UDIV:
+ case ISD::SREM:
+ case ISD::UREM:
+ case ISD::SDIVREM:
+ case ISD::UDIVREM:
+ return true;
+ }
+ }
+
+ // Assume all other non-float operations are supported.
+ if (!VT.isFloatingPoint())
+ return false;
+
+ // We'll need a library call to handle most floats when using soft.
+ if (TLI->useSoftFloat()) {
+ switch (I.getOpcode()) {
+ default:
+ return true;
+ case Instruction::Alloca:
+ case Instruction::Load:
+ case Instruction::Store:
+ case Instruction::Select:
+ case Instruction::PHI:
+ return false;
+ }
+ }
+
+ // We'll need a libcall to perform double precision operations on a single
+ // precision only FPU.
+ if (I.getType()->isDoubleTy() && !ST->hasFP64())
+ return true;
+
+ // Likewise for half precision arithmetic.
+ if (I.getType()->isHalfTy() && !ST->hasFullFP16())
+ return true;
+
+ return false;
+}
+
bool ARMTTIImpl::isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
AssumptionCache &AC,
TargetLibraryInfo *LibInfo,
@@ -1762,7 +1762,7 @@ bool ARMTTIImpl::isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
switch (Call->getIntrinsicID()) {
default:
break;
- case Intrinsic::start_loop_iterations:
+ case Intrinsic::start_loop_iterations:
case Intrinsic::test_set_loop_iterations:
case Intrinsic::loop_decrement:
case Intrinsic::loop_decrement_reg:
@@ -1773,24 +1773,24 @@ bool ARMTTIImpl::isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
};
// Scan the instructions to see if there's any that we know will turn into a
- // call or if this loop is already a low-overhead loop or will become a tail
- // predicated loop.
- bool IsTailPredLoop = false;
+ // call or if this loop is already a low-overhead loop or will become a tail
+ // predicated loop.
+ bool IsTailPredLoop = false;
auto ScanLoop = [&](Loop *L) {
for (auto *BB : L->getBlocks()) {
for (auto &I : *BB) {
- if (maybeLoweredToCall(I) || IsHardwareLoopIntrinsic(I) ||
- isa<InlineAsm>(I)) {
+ if (maybeLoweredToCall(I) || IsHardwareLoopIntrinsic(I) ||
+ isa<InlineAsm>(I)) {
LLVM_DEBUG(dbgs() << "ARMHWLoops: Bad instruction: " << I << "\n");
return false;
}
- if (auto *II = dyn_cast<IntrinsicInst>(&I))
- IsTailPredLoop |=
- II->getIntrinsicID() == Intrinsic::get_active_lane_mask ||
- II->getIntrinsicID() == Intrinsic::arm_mve_vctp8 ||
- II->getIntrinsicID() == Intrinsic::arm_mve_vctp16 ||
- II->getIntrinsicID() == Intrinsic::arm_mve_vctp32 ||
- II->getIntrinsicID() == Intrinsic::arm_mve_vctp64;
+ if (auto *II = dyn_cast<IntrinsicInst>(&I))
+ IsTailPredLoop |=
+ II->getIntrinsicID() == Intrinsic::get_active_lane_mask ||
+ II->getIntrinsicID() == Intrinsic::arm_mve_vctp8 ||
+ II->getIntrinsicID() == Intrinsic::arm_mve_vctp16 ||
+ II->getIntrinsicID() == Intrinsic::arm_mve_vctp32 ||
+ II->getIntrinsicID() == Intrinsic::arm_mve_vctp64;
}
}
return true;
@@ -1811,7 +1811,7 @@ bool ARMTTIImpl::isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
LLVMContext &C = L->getHeader()->getContext();
HWLoopInfo.CounterInReg = true;
HWLoopInfo.IsNestingLegal = false;
- HWLoopInfo.PerformEntryTest = AllowWLSLoops && !IsTailPredLoop;
+ HWLoopInfo.PerformEntryTest = AllowWLSLoops && !IsTailPredLoop;
HWLoopInfo.CountType = Type::getInt32Ty(C);
HWLoopInfo.LoopDecrement = ConstantInt::get(HWLoopInfo.CountType, 1);
return true;
@@ -1859,28 +1859,28 @@ static bool canTailPredicateLoop(Loop *L, LoopInfo *LI, ScalarEvolution &SE,
const LoopAccessInfo *LAI) {
LLVM_DEBUG(dbgs() << "Tail-predication: checking allowed instructions\n");
- // If there are live-out values, it is probably a reduction. We can predicate
- // most reduction operations freely under MVE using a combination of
- // prefer-predicated-reduction-select and inloop reductions. We limit this to
- // floating point and integer reductions, but don't check for operators
- // specifically here. If the value ends up not being a reduction (and so the
- // vectorizer cannot tailfold the loop), we should fall back to standard
- // vectorization automatically.
+ // If there are live-out values, it is probably a reduction. We can predicate
+ // most reduction operations freely under MVE using a combination of
+ // prefer-predicated-reduction-select and inloop reductions. We limit this to
+ // floating point and integer reductions, but don't check for operators
+ // specifically here. If the value ends up not being a reduction (and so the
+ // vectorizer cannot tailfold the loop), we should fall back to standard
+ // vectorization automatically.
SmallVector< Instruction *, 8 > LiveOuts;
LiveOuts = llvm::findDefsUsedOutsideOfLoop(L);
- bool ReductionsDisabled =
+ bool ReductionsDisabled =
EnableTailPredication == TailPredication::EnabledNoReductions ||
EnableTailPredication == TailPredication::ForceEnabledNoReductions;
for (auto *I : LiveOuts) {
- if (!I->getType()->isIntegerTy() && !I->getType()->isFloatTy() &&
- !I->getType()->isHalfTy()) {
- LLVM_DEBUG(dbgs() << "Don't tail-predicate loop with non-integer/float "
+ if (!I->getType()->isIntegerTy() && !I->getType()->isFloatTy() &&
+ !I->getType()->isHalfTy()) {
+ LLVM_DEBUG(dbgs() << "Don't tail-predicate loop with non-integer/float "
"live-out value\n");
return false;
}
- if (ReductionsDisabled) {
- LLVM_DEBUG(dbgs() << "Reductions not enabled\n");
+ if (ReductionsDisabled) {
+ LLVM_DEBUG(dbgs() << "Reductions not enabled\n");
return false;
}
}
@@ -1910,35 +1910,35 @@ static bool canTailPredicateLoop(Loop *L, LoopInfo *LI, ScalarEvolution &SE,
if (isa<StoreInst>(I) || isa<LoadInst>(I)) {
Value *Ptr = isa<LoadInst>(I) ? I.getOperand(0) : I.getOperand(1);
int64_t NextStride = getPtrStride(PSE, Ptr, L);
- if (NextStride == 1) {
- // TODO: for now only allow consecutive strides of 1. We could support
- // other strides as long as it is uniform, but let's keep it simple
- // for now.
+ if (NextStride == 1) {
+ // TODO: for now only allow consecutive strides of 1. We could support
+ // other strides as long as it is uniform, but let's keep it simple
+ // for now.
continue;
- } else if (NextStride == -1 ||
- (NextStride == 2 && MVEMaxSupportedInterleaveFactor >= 2) ||
- (NextStride == 4 && MVEMaxSupportedInterleaveFactor >= 4)) {
- LLVM_DEBUG(dbgs()
- << "Consecutive strides of 2 found, vld2/vstr2 can't "
- "be tail-predicated\n.");
+ } else if (NextStride == -1 ||
+ (NextStride == 2 && MVEMaxSupportedInterleaveFactor >= 2) ||
+ (NextStride == 4 && MVEMaxSupportedInterleaveFactor >= 4)) {
+ LLVM_DEBUG(dbgs()
+ << "Consecutive strides of 2 found, vld2/vstr2 can't "
+ "be tail-predicated\n.");
return false;
- // TODO: don't tail predicate if there is a reversed load?
- } else if (EnableMaskedGatherScatters) {
- // Gather/scatters do allow loading from arbitrary strides, at
- // least if they are loop invariant.
- // TODO: Loop variant strides should in theory work, too, but
- // this requires further testing.
- const SCEV *PtrScev =
- replaceSymbolicStrideSCEV(PSE, llvm::ValueToValueMap(), Ptr);
- if (auto AR = dyn_cast<SCEVAddRecExpr>(PtrScev)) {
- const SCEV *Step = AR->getStepRecurrence(*PSE.getSE());
- if (PSE.getSE()->isLoopInvariant(Step, L))
- continue;
- }
+ // TODO: don't tail predicate if there is a reversed load?
+ } else if (EnableMaskedGatherScatters) {
+ // Gather/scatters do allow loading from arbitrary strides, at
+ // least if they are loop invariant.
+ // TODO: Loop variant strides should in theory work, too, but
+ // this requires further testing.
+ const SCEV *PtrScev =
+ replaceSymbolicStrideSCEV(PSE, llvm::ValueToValueMap(), Ptr);
+ if (auto AR = dyn_cast<SCEVAddRecExpr>(PtrScev)) {
+ const SCEV *Step = AR->getStepRecurrence(*PSE.getSE());
+ if (PSE.getSE()->isLoopInvariant(Step, L))
+ continue;
+ }
}
- LLVM_DEBUG(dbgs() << "Bad stride found, can't "
- "tail-predicate\n.");
- return false;
+ LLVM_DEBUG(dbgs() << "Bad stride found, can't "
+ "tail-predicate\n.");
+ return false;
}
}
}
@@ -1971,7 +1971,7 @@ bool ARMTTIImpl::preferPredicateOverEpilogue(Loop *L, LoopInfo *LI,
return false;
}
- assert(L->isInnermost() && "preferPredicateOverEpilogue: inner-loop expected");
+ assert(L->isInnermost() && "preferPredicateOverEpilogue: inner-loop expected");
HardwareLoopInfo HWLoopInfo(L);
if (!HWLoopInfo.canAnalyze(*LI)) {
@@ -2039,10 +2039,10 @@ void ARMTTIImpl::getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
if (ST->hasBranchPredictor() && L->getNumBlocks() > 4)
return;
- // Don't unroll vectorized loops, including the remainder loop
- if (getBooleanLoopAttribute(L, "llvm.loop.isvectorized"))
- return;
-
+ // Don't unroll vectorized loops, including the remainder loop
+ if (getBooleanLoopAttribute(L, "llvm.loop.isvectorized"))
+ return;
+
// Scan the loop: don't unroll loops with calls as this could prevent
// inlining.
unsigned Cost = 0;
@@ -2061,9 +2061,9 @@ void ARMTTIImpl::getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
return;
}
- SmallVector<const Value*, 4> Operands(I.operand_values());
- Cost +=
- getUserCost(&I, Operands, TargetTransformInfo::TCK_SizeAndLatency);
+ SmallVector<const Value*, 4> Operands(I.operand_values());
+ Cost +=
+ getUserCost(&I, Operands, TargetTransformInfo::TCK_SizeAndLatency);
}
}
@@ -2092,24 +2092,24 @@ bool ARMTTIImpl::useReductionIntrinsic(unsigned Opcode, Type *Ty,
TTI::ReductionFlags Flags) const {
return ST->hasMVEIntegerOps();
}
-
-bool ARMTTIImpl::preferInLoopReduction(unsigned Opcode, Type *Ty,
- TTI::ReductionFlags Flags) const {
- if (!ST->hasMVEIntegerOps())
- return false;
-
- unsigned ScalarBits = Ty->getScalarSizeInBits();
- switch (Opcode) {
- case Instruction::Add:
- return ScalarBits <= 64;
- default:
- return false;
- }
-}
-
-bool ARMTTIImpl::preferPredicatedReductionSelect(
- unsigned Opcode, Type *Ty, TTI::ReductionFlags Flags) const {
- if (!ST->hasMVEIntegerOps())
- return false;
- return true;
-}
+
+bool ARMTTIImpl::preferInLoopReduction(unsigned Opcode, Type *Ty,
+ TTI::ReductionFlags Flags) const {
+ if (!ST->hasMVEIntegerOps())
+ return false;
+
+ unsigned ScalarBits = Ty->getScalarSizeInBits();
+ switch (Opcode) {
+ case Instruction::Add:
+ return ScalarBits <= 64;
+ default:
+ return false;
+ }
+}
+
+bool ARMTTIImpl::preferPredicatedReductionSelect(
+ unsigned Opcode, Type *Ty, TTI::ReductionFlags Flags) const {
+ if (!ST->hasMVEIntegerOps())
+ return false;
+ return true;
+}
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ARMTargetTransformInfo.h b/contrib/libs/llvm12/lib/Target/ARM/ARMTargetTransformInfo.h
index 257e325a28..7f045080e3 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ARMTargetTransformInfo.h
+++ b/contrib/libs/llvm12/lib/Target/ARM/ARMTargetTransformInfo.h
@@ -113,9 +113,9 @@ public:
return !ST->isTargetDarwin() && !ST->hasMVEFloatOps();
}
- Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
- IntrinsicInst &II) const;
-
+ Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
+ IntrinsicInst &II) const;
+
/// \name Scalar TTI Implementations
/// @{
@@ -126,8 +126,8 @@ public:
int getIntImmCost(const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind);
int getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm,
- Type *Ty, TTI::TargetCostKind CostKind,
- Instruction *Inst = nullptr);
+ Type *Ty, TTI::TargetCostKind CostKind,
+ Instruction *Inst = nullptr);
/// @}
@@ -181,31 +181,31 @@ public:
int getMemcpyCost(const Instruction *I);
- int getNumMemOps(const IntrinsicInst *I) const;
-
+ int getNumMemOps(const IntrinsicInst *I) const;
+
int getShuffleCost(TTI::ShuffleKind Kind, VectorType *Tp, int Index,
VectorType *SubTp);
bool useReductionIntrinsic(unsigned Opcode, Type *Ty,
TTI::ReductionFlags Flags) const;
- bool preferInLoopReduction(unsigned Opcode, Type *Ty,
- TTI::ReductionFlags Flags) const;
+ bool preferInLoopReduction(unsigned Opcode, Type *Ty,
+ TTI::ReductionFlags Flags) const;
+
+ bool preferPredicatedReductionSelect(unsigned Opcode, Type *Ty,
+ TTI::ReductionFlags Flags) const;
- bool preferPredicatedReductionSelect(unsigned Opcode, Type *Ty,
- TTI::ReductionFlags Flags) const;
+ bool shouldExpandReduction(const IntrinsicInst *II) const { return false; }
- bool shouldExpandReduction(const IntrinsicInst *II) const { return false; }
+ int getCFInstrCost(unsigned Opcode,
+ TTI::TargetCostKind CostKind);
- int getCFInstrCost(unsigned Opcode,
- TTI::TargetCostKind CostKind);
-
int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
- TTI::CastContextHint CCH, TTI::TargetCostKind CostKind,
+ TTI::CastContextHint CCH, TTI::TargetCostKind CostKind,
const Instruction *I = nullptr);
int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
- CmpInst::Predicate VecPred,
+ CmpInst::Predicate VecPred,
TTI::TargetCostKind CostKind,
const Instruction *I = nullptr);
@@ -229,10 +229,10 @@ public:
TTI::TargetCostKind CostKind,
const Instruction *I = nullptr);
- unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment,
- unsigned AddressSpace,
- TTI::TargetCostKind CostKind);
-
+ unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment,
+ unsigned AddressSpace,
+ TTI::TargetCostKind CostKind);
+
int getInterleavedMemoryOpCost(
unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
Align Alignment, unsigned AddressSpace,
@@ -244,17 +244,17 @@ public:
Align Alignment, TTI::TargetCostKind CostKind,
const Instruction *I = nullptr);
- int getArithmeticReductionCost(unsigned Opcode, VectorType *ValTy,
- bool IsPairwiseForm,
- TTI::TargetCostKind CostKind);
- InstructionCost getExtendedAddReductionCost(bool IsMLA, bool IsUnsigned,
- Type *ResTy, VectorType *ValTy,
- TTI::TargetCostKind CostKind);
-
- int getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
- TTI::TargetCostKind CostKind);
-
- bool maybeLoweredToCall(Instruction &I);
+ int getArithmeticReductionCost(unsigned Opcode, VectorType *ValTy,
+ bool IsPairwiseForm,
+ TTI::TargetCostKind CostKind);
+ InstructionCost getExtendedAddReductionCost(bool IsMLA, bool IsUnsigned,
+ Type *ResTy, VectorType *ValTy,
+ TTI::TargetCostKind CostKind);
+
+ int getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
+ TTI::TargetCostKind CostKind);
+
+ bool maybeLoweredToCall(Instruction &I);
bool isLoweredToCall(const Function *F);
bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
AssumptionCache &AC,
diff --git a/contrib/libs/llvm12/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/contrib/libs/llvm12/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index b65cfc3811..52577d75dd 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -6239,9 +6239,9 @@ bool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
StringRef IDVal = Parser.getTok().getIdentifier();
const auto &Prefix =
- llvm::find_if(PrefixEntries, [&IDVal](const PrefixEntry &PE) {
- return PE.Spelling == IDVal;
- });
+ llvm::find_if(PrefixEntries, [&IDVal](const PrefixEntry &PE) {
+ return PE.Spelling == IDVal;
+ });
if (Prefix == std::end(PrefixEntries)) {
Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
return true;
@@ -10307,14 +10307,14 @@ bool ARMAsmParser::processInstruction(MCInst &Inst,
!HasWideQualifier) {
// The operands aren't the same for tMOV[S]r... (no cc_out)
MCInst TmpInst;
- unsigned Op = Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr;
- TmpInst.setOpcode(Op);
+ unsigned Op = Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr;
+ TmpInst.setOpcode(Op);
TmpInst.addOperand(Inst.getOperand(0));
TmpInst.addOperand(Inst.getOperand(1));
- if (Op == ARM::tMOVr) {
- TmpInst.addOperand(Inst.getOperand(2));
- TmpInst.addOperand(Inst.getOperand(3));
- }
+ if (Op == ARM::tMOVr) {
+ TmpInst.addOperand(Inst.getOperand(2));
+ TmpInst.addOperand(Inst.getOperand(3));
+ }
Inst = TmpInst;
return true;
}
@@ -10599,12 +10599,12 @@ unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
(isThumb() && !hasV8Ops()))
return Match_InvalidOperand;
break;
- case ARM::t2TBB:
- case ARM::t2TBH:
- // Rn = sp is only allowed with ARMv8-A
- if (!hasV8Ops() && (Inst.getOperand(0).getReg() == ARM::SP))
- return Match_RequiresV8;
- break;
+ case ARM::t2TBB:
+ case ARM::t2TBH:
+ // Rn = sp is only allowed with ARMv8-A
+ if (!hasV8Ops() && (Inst.getOperand(0).getReg() == ARM::SP))
+ return Match_RequiresV8;
+ break;
default:
break;
}
@@ -11135,8 +11135,8 @@ bool ARMAsmParser::parseDirectiveArch(SMLoc L) {
bool WasThumb = isThumb();
Triple T;
MCSubtargetInfo &STI = copySTI();
- STI.setDefaultFeatures("", /*TuneCPU*/ "",
- ("+" + ARM::getArchName(ID)).str());
+ STI.setDefaultFeatures("", /*TuneCPU*/ "",
+ ("+" + ARM::getArchName(ID)).str());
setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
FixModeAfterArchChange(WasThumb, L);
@@ -11249,7 +11249,7 @@ bool ARMAsmParser::parseDirectiveCPU(SMLoc L) {
bool WasThumb = isThumb();
MCSubtargetInfo &STI = copySTI();
- STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, "");
+ STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, "");
setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
FixModeAfterArchChange(WasThumb, L);
diff --git a/contrib/libs/llvm12/lib/Target/ARM/AsmParser/ya.make b/contrib/libs/llvm12/lib/Target/ARM/AsmParser/ya.make
index ed9aa8099d..572d301570 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/AsmParser/ya.make
+++ b/contrib/libs/llvm12/lib/Target/ARM/AsmParser/ya.make
@@ -12,20 +12,20 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/MC/MCParser
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc
- contrib/libs/llvm12/lib/Target/ARM/TargetInfo
- contrib/libs/llvm12/lib/Target/ARM/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/MC/MCParser
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/ARM/TargetInfo
+ contrib/libs/llvm12/lib/Target/ARM/Utils
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM
- contrib/libs/llvm12/lib/Target/ARM
- contrib/libs/llvm12/lib/Target/ARM/AsmParser
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM
+ contrib/libs/llvm12/lib/Target/ARM
+ contrib/libs/llvm12/lib/Target/ARM/AsmParser
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/contrib/libs/llvm12/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index 7953681421..8ea323a9ce 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -860,8 +860,8 @@ ARMDisassembler::AddThumbPredicate(MCInst &MI) const {
VCCPos + 2, MCOI::TIED_TO);
assert(TiedOp >= 0 &&
"Inactive register in vpred_r is not tied to an output!");
- // Copy the operand to ensure it's not invalidated when MI grows.
- MI.insert(VCCI, MCOperand(MI.getOperand(TiedOp)));
+ // Copy the operand to ensure it's not invalidated when MI grows.
+ MI.insert(VCCI, MCOperand(MI.getOperand(TiedOp)));
}
} else if (VCC != ARMVCC::None) {
Check(S, SoftFail);
@@ -4530,14 +4530,14 @@ static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val,
static DecodeStatus
DecodeThumbTableBranch(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder) {
- const FeatureBitset &FeatureBits =
- ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
+ const FeatureBitset &FeatureBits =
+ ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
DecodeStatus S = MCDisassembler::Success;
unsigned Rn = fieldFromInstruction(Insn, 16, 4);
unsigned Rm = fieldFromInstruction(Insn, 0, 4);
- if (Rn == 13 && !FeatureBits[ARM::HasV8Ops]) S = MCDisassembler::SoftFail;
+ if (Rn == 13 && !FeatureBits[ARM::HasV8Ops]) S = MCDisassembler::SoftFail;
if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
return MCDisassembler::Fail;
if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
diff --git a/contrib/libs/llvm12/lib/Target/ARM/Disassembler/ya.make b/contrib/libs/llvm12/lib/Target/ARM/Disassembler/ya.make
index 660cfd1063..f8ce0c24d9 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/Disassembler/ya.make
+++ b/contrib/libs/llvm12/lib/Target/ARM/Disassembler/ya.make
@@ -12,19 +12,19 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/MC/MCDisassembler
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc
- contrib/libs/llvm12/lib/Target/ARM/TargetInfo
- contrib/libs/llvm12/lib/Target/ARM/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/MC/MCDisassembler
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/ARM/TargetInfo
+ contrib/libs/llvm12/lib/Target/ARM/Utils
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM
- contrib/libs/llvm12/lib/Target/ARM
- contrib/libs/llvm12/lib/Target/ARM/Disassembler
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM
+ contrib/libs/llvm12/lib/Target/ARM
+ contrib/libs/llvm12/lib/Target/ARM/Disassembler
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h b/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h
index 07376848c4..8459b4ff2a 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h
+++ b/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h
@@ -205,20 +205,20 @@ namespace ARM_AM {
return V;
}
- /// isSOImmTwoPartValNeg - Return true if the specified value can be obtained
- /// by two SOImmVal, that -V = First + Second.
- /// "R+V" can be optimized to (sub (sub R, First), Second).
- /// "R=V" can be optimized to (sub (mvn R, ~(-First)), Second).
- inline bool isSOImmTwoPartValNeg(unsigned V) {
- unsigned First;
- if (!isSOImmTwoPartVal(-V))
- return false;
- // Return false if ~(-First) is not a SoImmval.
- First = getSOImmTwoPartFirst(-V);
- First = ~(-First);
- return !(rotr32(~255U, getSOImmValRotate(First)) & First);
- }
-
+ /// isSOImmTwoPartValNeg - Return true if the specified value can be obtained
+ /// by two SOImmVal, that -V = First + Second.
+ /// "R+V" can be optimized to (sub (sub R, First), Second).
+ /// "R=V" can be optimized to (sub (mvn R, ~(-First)), Second).
+ inline bool isSOImmTwoPartValNeg(unsigned V) {
+ unsigned First;
+ if (!isSOImmTwoPartVal(-V))
+ return false;
+ // Return false if ~(-First) is not a SoImmval.
+ First = getSOImmTwoPartFirst(-V);
+ First = ~(-First);
+ return !(rotr32(~255U, getSOImmValRotate(First)) & First);
+ }
+
/// getThumbImmValShift - Try to handle Imm with a 8-bit immediate followed
/// by a left shift. Returns the shift amount to use.
inline unsigned getThumbImmValShift(unsigned Imm) {
@@ -687,18 +687,18 @@ namespace ARM_AM {
return getFP16Imm(FPImm.bitcastToAPInt());
}
- /// If this is a FP16Imm encoded as a fp32 value, return the 8-bit encoding
- /// for it. Otherwise return -1 like getFP16Imm.
- inline int getFP32FP16Imm(const APInt &Imm) {
- if (Imm.getActiveBits() > 16)
- return -1;
- return ARM_AM::getFP16Imm(Imm.trunc(16));
- }
-
- inline int getFP32FP16Imm(const APFloat &FPImm) {
- return getFP32FP16Imm(FPImm.bitcastToAPInt());
- }
-
+ /// If this is a FP16Imm encoded as a fp32 value, return the 8-bit encoding
+ /// for it. Otherwise return -1 like getFP16Imm.
+ inline int getFP32FP16Imm(const APInt &Imm) {
+ if (Imm.getActiveBits() > 16)
+ return -1;
+ return ARM_AM::getFP16Imm(Imm.trunc(16));
+ }
+
+ inline int getFP32FP16Imm(const APFloat &FPImm) {
+ return getFP32FP16Imm(FPImm.bitcastToAPInt());
+ }
+
/// getFP32Imm - Return an 8-bit floating-point version of the 32-bit
/// floating-point value. If the value cannot be represented as an 8-bit
/// floating-point value, then return -1.
diff --git a/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 697eeab4e5..b02aef3c33 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -1010,7 +1010,7 @@ static unsigned getFixupKindContainerSizeBytes(unsigned Kind) {
case ARM::fixup_t2_condbranch:
case ARM::fixup_t2_uncondbranch:
case ARM::fixup_t2_pcrel_10:
- case ARM::fixup_t2_pcrel_9:
+ case ARM::fixup_t2_pcrel_9:
case ARM::fixup_t2_adr_pcrel_12:
case ARM::fixup_arm_thumb_bl:
case ARM::fixup_arm_thumb_blx:
diff --git a/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h b/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
index 5599eaaf2f..ecd96114e8 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
+++ b/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
@@ -254,7 +254,7 @@ namespace ARMII {
MO_OPTION_MASK = 0x3,
/// MO_COFFSTUB - On a symbol operand "FOO", this indicates that the
- /// reference is actually to the ".refptr.FOO" symbol. This is used for
+ /// reference is actually to the ".refptr.FOO" symbol. This is used for
/// stub symbols on windows.
MO_COFFSTUB = 0x4,
diff --git a/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h b/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h
index ac75bf3fca..d975d799e0 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h
+++ b/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h
@@ -30,7 +30,7 @@ public:
void printRegName(raw_ostream &OS, unsigned RegNo) const override;
// Autogenerated by tblgen.
- std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
+ std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
void printInstruction(const MCInst *MI, uint64_t Address,
const MCSubtargetInfo &STI, raw_ostream &O);
virtual bool printAliasInstr(const MCInst *MI, uint64_t Address,
diff --git a/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp b/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp
index a26944a38f..40e8e244e3 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp
@@ -87,7 +87,7 @@ void ARMCOFFMCAsmInfoMicrosoft::anchor() { }
ARMCOFFMCAsmInfoMicrosoft::ARMCOFFMCAsmInfoMicrosoft() {
AlignmentIsInBytes = false;
- SupportsDebugInformation = true;
+ SupportsDebugInformation = true;
ExceptionsType = ExceptionHandling::WinEH;
PrivateGlobalPrefix = "$M";
PrivateLabelPrefix = "$M";
diff --git a/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
index 3da71ade87..774f2507b8 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
@@ -11,13 +11,13 @@
//===----------------------------------------------------------------------===//
#include "ARMMCTargetDesc.h"
-#include "ARMAddressingModes.h"
+#include "ARMAddressingModes.h"
#include "ARMBaseInfo.h"
#include "ARMInstPrinter.h"
#include "ARMMCAsmInfo.h"
#include "TargetInfo/ARMTargetInfo.h"
#include "llvm/ADT/Triple.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCELFStreamer.h"
@@ -182,23 +182,23 @@ std::string ARM_MC::ParseARMTriple(const Triple &TT, StringRef CPU) {
return ARMArchFeature;
}
-bool ARM_MC::isPredicated(const MCInst &MI, const MCInstrInfo *MCII) {
- const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
- int PredOpIdx = Desc.findFirstPredOperandIdx();
- return PredOpIdx != -1 && MI.getOperand(PredOpIdx).getImm() != ARMCC::AL;
-}
-
-bool ARM_MC::isCPSRDefined(const MCInst &MI, const MCInstrInfo *MCII) {
- const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
- for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
- const MCOperand &MO = MI.getOperand(I);
- if (MO.isReg() && MO.getReg() == ARM::CPSR &&
- Desc.OpInfo[I].isOptionalDef())
- return true;
- }
- return false;
-}
-
+bool ARM_MC::isPredicated(const MCInst &MI, const MCInstrInfo *MCII) {
+ const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
+ int PredOpIdx = Desc.findFirstPredOperandIdx();
+ return PredOpIdx != -1 && MI.getOperand(PredOpIdx).getImm() != ARMCC::AL;
+}
+
+bool ARM_MC::isCPSRDefined(const MCInst &MI, const MCInstrInfo *MCII) {
+ const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
+ for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
+ const MCOperand &MO = MI.getOperand(I);
+ if (MO.isReg() && MO.getReg() == ARM::CPSR &&
+ Desc.OpInfo[I].isOptionalDef())
+ return true;
+ }
+ return false;
+}
+
MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(const Triple &TT,
StringRef CPU, StringRef FS) {
std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
@@ -209,7 +209,7 @@ MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(const Triple &TT,
ArchFS = std::string(FS);
}
- return createARMMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, ArchFS);
+ return createARMMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, ArchFS);
}
static MCInstrInfo *createARMMCInstrInfo() {
@@ -218,120 +218,120 @@ static MCInstrInfo *createARMMCInstrInfo() {
return X;
}
-void ARM_MC::initLLVMToCVRegMapping(MCRegisterInfo *MRI) {
- // Mapping from CodeView to MC register id.
- static const struct {
- codeview::RegisterId CVReg;
- MCPhysReg Reg;
- } RegMap[] = {
- {codeview::RegisterId::ARM_R0, ARM::R0},
- {codeview::RegisterId::ARM_R1, ARM::R1},
- {codeview::RegisterId::ARM_R2, ARM::R2},
- {codeview::RegisterId::ARM_R3, ARM::R3},
- {codeview::RegisterId::ARM_R4, ARM::R4},
- {codeview::RegisterId::ARM_R5, ARM::R5},
- {codeview::RegisterId::ARM_R6, ARM::R6},
- {codeview::RegisterId::ARM_R7, ARM::R7},
- {codeview::RegisterId::ARM_R8, ARM::R8},
- {codeview::RegisterId::ARM_R9, ARM::R9},
- {codeview::RegisterId::ARM_R10, ARM::R10},
- {codeview::RegisterId::ARM_R11, ARM::R11},
- {codeview::RegisterId::ARM_R12, ARM::R12},
- {codeview::RegisterId::ARM_SP, ARM::SP},
- {codeview::RegisterId::ARM_LR, ARM::LR},
- {codeview::RegisterId::ARM_PC, ARM::PC},
- {codeview::RegisterId::ARM_CPSR, ARM::CPSR},
- {codeview::RegisterId::ARM_FPSCR, ARM::FPSCR},
- {codeview::RegisterId::ARM_FPEXC, ARM::FPEXC},
- {codeview::RegisterId::ARM_FS0, ARM::S0},
- {codeview::RegisterId::ARM_FS1, ARM::S1},
- {codeview::RegisterId::ARM_FS2, ARM::S2},
- {codeview::RegisterId::ARM_FS3, ARM::S3},
- {codeview::RegisterId::ARM_FS4, ARM::S4},
- {codeview::RegisterId::ARM_FS5, ARM::S5},
- {codeview::RegisterId::ARM_FS6, ARM::S6},
- {codeview::RegisterId::ARM_FS7, ARM::S7},
- {codeview::RegisterId::ARM_FS8, ARM::S8},
- {codeview::RegisterId::ARM_FS9, ARM::S9},
- {codeview::RegisterId::ARM_FS10, ARM::S10},
- {codeview::RegisterId::ARM_FS11, ARM::S11},
- {codeview::RegisterId::ARM_FS12, ARM::S12},
- {codeview::RegisterId::ARM_FS13, ARM::S13},
- {codeview::RegisterId::ARM_FS14, ARM::S14},
- {codeview::RegisterId::ARM_FS15, ARM::S15},
- {codeview::RegisterId::ARM_FS16, ARM::S16},
- {codeview::RegisterId::ARM_FS17, ARM::S17},
- {codeview::RegisterId::ARM_FS18, ARM::S18},
- {codeview::RegisterId::ARM_FS19, ARM::S19},
- {codeview::RegisterId::ARM_FS20, ARM::S20},
- {codeview::RegisterId::ARM_FS21, ARM::S21},
- {codeview::RegisterId::ARM_FS22, ARM::S22},
- {codeview::RegisterId::ARM_FS23, ARM::S23},
- {codeview::RegisterId::ARM_FS24, ARM::S24},
- {codeview::RegisterId::ARM_FS25, ARM::S25},
- {codeview::RegisterId::ARM_FS26, ARM::S26},
- {codeview::RegisterId::ARM_FS27, ARM::S27},
- {codeview::RegisterId::ARM_FS28, ARM::S28},
- {codeview::RegisterId::ARM_FS29, ARM::S29},
- {codeview::RegisterId::ARM_FS30, ARM::S30},
- {codeview::RegisterId::ARM_FS31, ARM::S31},
- {codeview::RegisterId::ARM_ND0, ARM::D0},
- {codeview::RegisterId::ARM_ND1, ARM::D1},
- {codeview::RegisterId::ARM_ND2, ARM::D2},
- {codeview::RegisterId::ARM_ND3, ARM::D3},
- {codeview::RegisterId::ARM_ND4, ARM::D4},
- {codeview::RegisterId::ARM_ND5, ARM::D5},
- {codeview::RegisterId::ARM_ND6, ARM::D6},
- {codeview::RegisterId::ARM_ND7, ARM::D7},
- {codeview::RegisterId::ARM_ND8, ARM::D8},
- {codeview::RegisterId::ARM_ND9, ARM::D9},
- {codeview::RegisterId::ARM_ND10, ARM::D10},
- {codeview::RegisterId::ARM_ND11, ARM::D11},
- {codeview::RegisterId::ARM_ND12, ARM::D12},
- {codeview::RegisterId::ARM_ND13, ARM::D13},
- {codeview::RegisterId::ARM_ND14, ARM::D14},
- {codeview::RegisterId::ARM_ND15, ARM::D15},
- {codeview::RegisterId::ARM_ND16, ARM::D16},
- {codeview::RegisterId::ARM_ND17, ARM::D17},
- {codeview::RegisterId::ARM_ND18, ARM::D18},
- {codeview::RegisterId::ARM_ND19, ARM::D19},
- {codeview::RegisterId::ARM_ND20, ARM::D20},
- {codeview::RegisterId::ARM_ND21, ARM::D21},
- {codeview::RegisterId::ARM_ND22, ARM::D22},
- {codeview::RegisterId::ARM_ND23, ARM::D23},
- {codeview::RegisterId::ARM_ND24, ARM::D24},
- {codeview::RegisterId::ARM_ND25, ARM::D25},
- {codeview::RegisterId::ARM_ND26, ARM::D26},
- {codeview::RegisterId::ARM_ND27, ARM::D27},
- {codeview::RegisterId::ARM_ND28, ARM::D28},
- {codeview::RegisterId::ARM_ND29, ARM::D29},
- {codeview::RegisterId::ARM_ND30, ARM::D30},
- {codeview::RegisterId::ARM_ND31, ARM::D31},
- {codeview::RegisterId::ARM_NQ0, ARM::Q0},
- {codeview::RegisterId::ARM_NQ1, ARM::Q1},
- {codeview::RegisterId::ARM_NQ2, ARM::Q2},
- {codeview::RegisterId::ARM_NQ3, ARM::Q3},
- {codeview::RegisterId::ARM_NQ4, ARM::Q4},
- {codeview::RegisterId::ARM_NQ5, ARM::Q5},
- {codeview::RegisterId::ARM_NQ6, ARM::Q6},
- {codeview::RegisterId::ARM_NQ7, ARM::Q7},
- {codeview::RegisterId::ARM_NQ8, ARM::Q8},
- {codeview::RegisterId::ARM_NQ9, ARM::Q9},
- {codeview::RegisterId::ARM_NQ10, ARM::Q10},
- {codeview::RegisterId::ARM_NQ11, ARM::Q11},
- {codeview::RegisterId::ARM_NQ12, ARM::Q12},
- {codeview::RegisterId::ARM_NQ13, ARM::Q13},
- {codeview::RegisterId::ARM_NQ14, ARM::Q14},
- {codeview::RegisterId::ARM_NQ15, ARM::Q15},
- };
- for (unsigned I = 0; I < array_lengthof(RegMap); ++I)
- MRI->mapLLVMRegToCVReg(RegMap[I].Reg, static_cast<int>(RegMap[I].CVReg));
-}
-
+void ARM_MC::initLLVMToCVRegMapping(MCRegisterInfo *MRI) {
+ // Mapping from CodeView to MC register id.
+ static const struct {
+ codeview::RegisterId CVReg;
+ MCPhysReg Reg;
+ } RegMap[] = {
+ {codeview::RegisterId::ARM_R0, ARM::R0},
+ {codeview::RegisterId::ARM_R1, ARM::R1},
+ {codeview::RegisterId::ARM_R2, ARM::R2},
+ {codeview::RegisterId::ARM_R3, ARM::R3},
+ {codeview::RegisterId::ARM_R4, ARM::R4},
+ {codeview::RegisterId::ARM_R5, ARM::R5},
+ {codeview::RegisterId::ARM_R6, ARM::R6},
+ {codeview::RegisterId::ARM_R7, ARM::R7},
+ {codeview::RegisterId::ARM_R8, ARM::R8},
+ {codeview::RegisterId::ARM_R9, ARM::R9},
+ {codeview::RegisterId::ARM_R10, ARM::R10},
+ {codeview::RegisterId::ARM_R11, ARM::R11},
+ {codeview::RegisterId::ARM_R12, ARM::R12},
+ {codeview::RegisterId::ARM_SP, ARM::SP},
+ {codeview::RegisterId::ARM_LR, ARM::LR},
+ {codeview::RegisterId::ARM_PC, ARM::PC},
+ {codeview::RegisterId::ARM_CPSR, ARM::CPSR},
+ {codeview::RegisterId::ARM_FPSCR, ARM::FPSCR},
+ {codeview::RegisterId::ARM_FPEXC, ARM::FPEXC},
+ {codeview::RegisterId::ARM_FS0, ARM::S0},
+ {codeview::RegisterId::ARM_FS1, ARM::S1},
+ {codeview::RegisterId::ARM_FS2, ARM::S2},
+ {codeview::RegisterId::ARM_FS3, ARM::S3},
+ {codeview::RegisterId::ARM_FS4, ARM::S4},
+ {codeview::RegisterId::ARM_FS5, ARM::S5},
+ {codeview::RegisterId::ARM_FS6, ARM::S6},
+ {codeview::RegisterId::ARM_FS7, ARM::S7},
+ {codeview::RegisterId::ARM_FS8, ARM::S8},
+ {codeview::RegisterId::ARM_FS9, ARM::S9},
+ {codeview::RegisterId::ARM_FS10, ARM::S10},
+ {codeview::RegisterId::ARM_FS11, ARM::S11},
+ {codeview::RegisterId::ARM_FS12, ARM::S12},
+ {codeview::RegisterId::ARM_FS13, ARM::S13},
+ {codeview::RegisterId::ARM_FS14, ARM::S14},
+ {codeview::RegisterId::ARM_FS15, ARM::S15},
+ {codeview::RegisterId::ARM_FS16, ARM::S16},
+ {codeview::RegisterId::ARM_FS17, ARM::S17},
+ {codeview::RegisterId::ARM_FS18, ARM::S18},
+ {codeview::RegisterId::ARM_FS19, ARM::S19},
+ {codeview::RegisterId::ARM_FS20, ARM::S20},
+ {codeview::RegisterId::ARM_FS21, ARM::S21},
+ {codeview::RegisterId::ARM_FS22, ARM::S22},
+ {codeview::RegisterId::ARM_FS23, ARM::S23},
+ {codeview::RegisterId::ARM_FS24, ARM::S24},
+ {codeview::RegisterId::ARM_FS25, ARM::S25},
+ {codeview::RegisterId::ARM_FS26, ARM::S26},
+ {codeview::RegisterId::ARM_FS27, ARM::S27},
+ {codeview::RegisterId::ARM_FS28, ARM::S28},
+ {codeview::RegisterId::ARM_FS29, ARM::S29},
+ {codeview::RegisterId::ARM_FS30, ARM::S30},
+ {codeview::RegisterId::ARM_FS31, ARM::S31},
+ {codeview::RegisterId::ARM_ND0, ARM::D0},
+ {codeview::RegisterId::ARM_ND1, ARM::D1},
+ {codeview::RegisterId::ARM_ND2, ARM::D2},
+ {codeview::RegisterId::ARM_ND3, ARM::D3},
+ {codeview::RegisterId::ARM_ND4, ARM::D4},
+ {codeview::RegisterId::ARM_ND5, ARM::D5},
+ {codeview::RegisterId::ARM_ND6, ARM::D6},
+ {codeview::RegisterId::ARM_ND7, ARM::D7},
+ {codeview::RegisterId::ARM_ND8, ARM::D8},
+ {codeview::RegisterId::ARM_ND9, ARM::D9},
+ {codeview::RegisterId::ARM_ND10, ARM::D10},
+ {codeview::RegisterId::ARM_ND11, ARM::D11},
+ {codeview::RegisterId::ARM_ND12, ARM::D12},
+ {codeview::RegisterId::ARM_ND13, ARM::D13},
+ {codeview::RegisterId::ARM_ND14, ARM::D14},
+ {codeview::RegisterId::ARM_ND15, ARM::D15},
+ {codeview::RegisterId::ARM_ND16, ARM::D16},
+ {codeview::RegisterId::ARM_ND17, ARM::D17},
+ {codeview::RegisterId::ARM_ND18, ARM::D18},
+ {codeview::RegisterId::ARM_ND19, ARM::D19},
+ {codeview::RegisterId::ARM_ND20, ARM::D20},
+ {codeview::RegisterId::ARM_ND21, ARM::D21},
+ {codeview::RegisterId::ARM_ND22, ARM::D22},
+ {codeview::RegisterId::ARM_ND23, ARM::D23},
+ {codeview::RegisterId::ARM_ND24, ARM::D24},
+ {codeview::RegisterId::ARM_ND25, ARM::D25},
+ {codeview::RegisterId::ARM_ND26, ARM::D26},
+ {codeview::RegisterId::ARM_ND27, ARM::D27},
+ {codeview::RegisterId::ARM_ND28, ARM::D28},
+ {codeview::RegisterId::ARM_ND29, ARM::D29},
+ {codeview::RegisterId::ARM_ND30, ARM::D30},
+ {codeview::RegisterId::ARM_ND31, ARM::D31},
+ {codeview::RegisterId::ARM_NQ0, ARM::Q0},
+ {codeview::RegisterId::ARM_NQ1, ARM::Q1},
+ {codeview::RegisterId::ARM_NQ2, ARM::Q2},
+ {codeview::RegisterId::ARM_NQ3, ARM::Q3},
+ {codeview::RegisterId::ARM_NQ4, ARM::Q4},
+ {codeview::RegisterId::ARM_NQ5, ARM::Q5},
+ {codeview::RegisterId::ARM_NQ6, ARM::Q6},
+ {codeview::RegisterId::ARM_NQ7, ARM::Q7},
+ {codeview::RegisterId::ARM_NQ8, ARM::Q8},
+ {codeview::RegisterId::ARM_NQ9, ARM::Q9},
+ {codeview::RegisterId::ARM_NQ10, ARM::Q10},
+ {codeview::RegisterId::ARM_NQ11, ARM::Q11},
+ {codeview::RegisterId::ARM_NQ12, ARM::Q12},
+ {codeview::RegisterId::ARM_NQ13, ARM::Q13},
+ {codeview::RegisterId::ARM_NQ14, ARM::Q14},
+ {codeview::RegisterId::ARM_NQ15, ARM::Q15},
+ };
+ for (unsigned I = 0; I < array_lengthof(RegMap); ++I)
+ MRI->mapLLVMRegToCVReg(RegMap[I].Reg, static_cast<int>(RegMap[I].CVReg));
+}
+
static MCRegisterInfo *createARMMCRegisterInfo(const Triple &Triple) {
MCRegisterInfo *X = new MCRegisterInfo();
InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC);
- ARM_MC::initLLVMToCVRegMapping(X);
+ ARM_MC::initLLVMToCVRegMapping(X);
return X;
}
diff --git a/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h b/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h
index a84576e757..5a0874f0ef 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h
+++ b/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h
@@ -41,22 +41,22 @@ class raw_pwrite_stream;
namespace ARM_MC {
std::string ParseARMTriple(const Triple &TT, StringRef CPU);
-void initLLVMToCVRegMapping(MCRegisterInfo *MRI);
-
-bool isPredicated(const MCInst &MI, const MCInstrInfo *MCII);
-bool isCPSRDefined(const MCInst &MI, const MCInstrInfo *MCII);
-
-template<class Inst>
-bool isLDMBaseRegInList(const Inst &MI) {
- auto BaseReg = MI.getOperand(0).getReg();
- for (unsigned I = 1, E = MI.getNumOperands(); I < E; ++I) {
- const auto &Op = MI.getOperand(I);
- if (Op.isReg() && Op.getReg() == BaseReg)
- return true;
- }
- return false;
-}
-
+void initLLVMToCVRegMapping(MCRegisterInfo *MRI);
+
+bool isPredicated(const MCInst &MI, const MCInstrInfo *MCII);
+bool isCPSRDefined(const MCInst &MI, const MCInstrInfo *MCII);
+
+template<class Inst>
+bool isLDMBaseRegInList(const Inst &MI) {
+ auto BaseReg = MI.getOperand(0).getReg();
+ for (unsigned I = 1, E = MI.getNumOperands(); I < E; ++I) {
+ const auto &Op = MI.getOperand(I);
+ if (Op.isReg() && Op.getReg() == BaseReg)
+ return true;
+ }
+ return false;
+}
+
/// Create a ARM MCSubtargetInfo instance. This is exposed so Asm parser, etc.
/// do not need to go through TargetRegistry.
MCSubtargetInfo *createARMMCSubtargetInfo(const Triple &TT, StringRef CPU,
diff --git a/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ya.make b/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ya.make
index 0256e1fdac..b92b47d057 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ya.make
+++ b/contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc/ya.make
@@ -12,20 +12,20 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/MC/MCDisassembler
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target/ARM/TargetInfo
- contrib/libs/llvm12/lib/Target/ARM/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/MC/MCDisassembler
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target/ARM/TargetInfo
+ contrib/libs/llvm12/lib/Target/ARM/Utils
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM
- contrib/libs/llvm12/lib/Target/ARM
- contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM
+ contrib/libs/llvm12/lib/Target/ARM
+ contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/ARM/MVEGatherScatterLowering.cpp b/contrib/libs/llvm12/lib/Target/ARM/MVEGatherScatterLowering.cpp
index 0b6cdee512..56823735e2 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/MVEGatherScatterLowering.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/MVEGatherScatterLowering.cpp
@@ -44,10 +44,10 @@
using namespace llvm;
-#define DEBUG_TYPE "arm-mve-gather-scatter-lowering"
+#define DEBUG_TYPE "arm-mve-gather-scatter-lowering"
cl::opt<bool> EnableMaskedGatherScatters(
- "enable-arm-maskedgatscat", cl::Hidden, cl::init(true),
+ "enable-arm-maskedgatscat", cl::Hidden, cl::init(true),
cl::desc("Enable the generation of masked gathers and scatters"));
namespace {
@@ -84,7 +84,7 @@ private:
// Check for a getelementptr and deduce base and offsets from it, on success
// returning the base directly and the offsets indirectly using the Offsets
// argument
- Value *checkGEP(Value *&Offsets, FixedVectorType *Ty, GetElementPtrInst *GEP,
+ Value *checkGEP(Value *&Offsets, FixedVectorType *Ty, GetElementPtrInst *GEP,
IRBuilder<> &Builder);
// Compute the scale of this gather/scatter instruction
int computeScale(unsigned GEPElemSize, unsigned MemoryElemSize);
@@ -132,11 +132,11 @@ private:
Value *tryCreateIncrementingWBGatScat(IntrinsicInst *I, Value *BasePtr,
Value *Ptr, unsigned TypeScale,
IRBuilder<> &Builder);
-
- // Optimise the base and offsets of the given address
- bool optimiseAddress(Value *Address, BasicBlock *BB, LoopInfo *LI);
- // Try to fold consecutive geps together into one
- Value *foldGEP(GetElementPtrInst *GEP, Value *&Offsets, IRBuilder<> &Builder);
+
+ // Optimise the base and offsets of the given address
+ bool optimiseAddress(Value *Address, BasicBlock *BB, LoopInfo *LI);
+ // Try to fold consecutive geps together into one
+ Value *foldGEP(GetElementPtrInst *GEP, Value *&Offsets, IRBuilder<> &Builder);
// Check whether these offsets could be moved out of the loop they're in
bool optimiseOffsets(Value *Offsets, BasicBlock *BB, LoopInfo *LI);
// Pushes the given add out of the loop
@@ -172,49 +172,49 @@ bool MVEGatherScatterLowering::isLegalTypeAndAlignment(unsigned NumElements,
return false;
}
-static bool checkOffsetSize(Value *Offsets, unsigned TargetElemCount) {
- // Offsets that are not of type <N x i32> are sign extended by the
- // getelementptr instruction, and MVE gathers/scatters treat the offset as
- // unsigned. Thus, if the element size is smaller than 32, we can only allow
- // positive offsets - i.e., the offsets are not allowed to be variables we
- // can't look into.
- // Additionally, <N x i32> offsets have to either originate from a zext of a
- // vector with element types smaller or equal the type of the gather we're
- // looking at, or consist of constants that we can check are small enough
- // to fit into the gather type.
- // Thus we check that 0 < value < 2^TargetElemSize.
- unsigned TargetElemSize = 128 / TargetElemCount;
- unsigned OffsetElemSize = cast<FixedVectorType>(Offsets->getType())
- ->getElementType()
- ->getScalarSizeInBits();
- if (OffsetElemSize != TargetElemSize || OffsetElemSize != 32) {
- Constant *ConstOff = dyn_cast<Constant>(Offsets);
- if (!ConstOff)
- return false;
- int64_t TargetElemMaxSize = (1ULL << TargetElemSize);
- auto CheckValueSize = [TargetElemMaxSize](Value *OffsetElem) {
- ConstantInt *OConst = dyn_cast<ConstantInt>(OffsetElem);
- if (!OConst)
- return false;
- int SExtValue = OConst->getSExtValue();
- if (SExtValue >= TargetElemMaxSize || SExtValue < 0)
- return false;
- return true;
- };
- if (isa<FixedVectorType>(ConstOff->getType())) {
- for (unsigned i = 0; i < TargetElemCount; i++) {
- if (!CheckValueSize(ConstOff->getAggregateElement(i)))
- return false;
- }
- } else {
- if (!CheckValueSize(ConstOff))
- return false;
- }
- }
- return true;
-}
-
-Value *MVEGatherScatterLowering::checkGEP(Value *&Offsets, FixedVectorType *Ty,
+static bool checkOffsetSize(Value *Offsets, unsigned TargetElemCount) {
+ // Offsets that are not of type <N x i32> are sign extended by the
+ // getelementptr instruction, and MVE gathers/scatters treat the offset as
+ // unsigned. Thus, if the element size is smaller than 32, we can only allow
+ // positive offsets - i.e., the offsets are not allowed to be variables we
+ // can't look into.
+ // Additionally, <N x i32> offsets have to either originate from a zext of a
+ // vector with element types smaller or equal the type of the gather we're
+ // looking at, or consist of constants that we can check are small enough
+ // to fit into the gather type.
+ // Thus we check that 0 < value < 2^TargetElemSize.
+ unsigned TargetElemSize = 128 / TargetElemCount;
+ unsigned OffsetElemSize = cast<FixedVectorType>(Offsets->getType())
+ ->getElementType()
+ ->getScalarSizeInBits();
+ if (OffsetElemSize != TargetElemSize || OffsetElemSize != 32) {
+ Constant *ConstOff = dyn_cast<Constant>(Offsets);
+ if (!ConstOff)
+ return false;
+ int64_t TargetElemMaxSize = (1ULL << TargetElemSize);
+ auto CheckValueSize = [TargetElemMaxSize](Value *OffsetElem) {
+ ConstantInt *OConst = dyn_cast<ConstantInt>(OffsetElem);
+ if (!OConst)
+ return false;
+ int SExtValue = OConst->getSExtValue();
+ if (SExtValue >= TargetElemMaxSize || SExtValue < 0)
+ return false;
+ return true;
+ };
+ if (isa<FixedVectorType>(ConstOff->getType())) {
+ for (unsigned i = 0; i < TargetElemCount; i++) {
+ if (!CheckValueSize(ConstOff->getAggregateElement(i)))
+ return false;
+ }
+ } else {
+ if (!CheckValueSize(ConstOff))
+ return false;
+ }
+ }
+ return true;
+}
+
+Value *MVEGatherScatterLowering::checkGEP(Value *&Offsets, FixedVectorType *Ty,
GetElementPtrInst *GEP,
IRBuilder<> &Builder) {
if (!GEP) {
@@ -225,43 +225,43 @@ Value *MVEGatherScatterLowering::checkGEP(Value *&Offsets, FixedVectorType *Ty,
LLVM_DEBUG(dbgs() << "masked gathers/scatters: getelementpointer found."
<< " Looking at intrinsic for base + vector of offsets\n");
Value *GEPPtr = GEP->getPointerOperand();
- Offsets = GEP->getOperand(1);
- if (GEPPtr->getType()->isVectorTy() ||
- !isa<FixedVectorType>(Offsets->getType()))
+ Offsets = GEP->getOperand(1);
+ if (GEPPtr->getType()->isVectorTy() ||
+ !isa<FixedVectorType>(Offsets->getType()))
return nullptr;
-
+
if (GEP->getNumOperands() != 2) {
LLVM_DEBUG(dbgs() << "masked gathers/scatters: getelementptr with too many"
<< " operands. Expanding.\n");
return nullptr;
}
Offsets = GEP->getOperand(1);
- unsigned OffsetsElemCount =
- cast<FixedVectorType>(Offsets->getType())->getNumElements();
+ unsigned OffsetsElemCount =
+ cast<FixedVectorType>(Offsets->getType())->getNumElements();
// Paranoid check whether the number of parallel lanes is the same
- assert(Ty->getNumElements() == OffsetsElemCount);
-
- ZExtInst *ZextOffs = dyn_cast<ZExtInst>(Offsets);
- if (ZextOffs)
+ assert(Ty->getNumElements() == OffsetsElemCount);
+
+ ZExtInst *ZextOffs = dyn_cast<ZExtInst>(Offsets);
+ if (ZextOffs)
Offsets = ZextOffs->getOperand(0);
- FixedVectorType *OffsetType = cast<FixedVectorType>(Offsets->getType());
-
- // If the offsets are already being zext-ed to <N x i32>, that relieves us of
- // having to make sure that they won't overflow.
- if (!ZextOffs || cast<FixedVectorType>(ZextOffs->getDestTy())
- ->getElementType()
- ->getScalarSizeInBits() != 32)
- if (!checkOffsetSize(Offsets, OffsetsElemCount))
- return nullptr;
-
- // The offset sizes have been checked; if any truncating or zext-ing is
- // required to fix them, do that now
+ FixedVectorType *OffsetType = cast<FixedVectorType>(Offsets->getType());
+
+ // If the offsets are already being zext-ed to <N x i32>, that relieves us of
+ // having to make sure that they won't overflow.
+ if (!ZextOffs || cast<FixedVectorType>(ZextOffs->getDestTy())
+ ->getElementType()
+ ->getScalarSizeInBits() != 32)
+ if (!checkOffsetSize(Offsets, OffsetsElemCount))
+ return nullptr;
+
+ // The offset sizes have been checked; if any truncating or zext-ing is
+ // required to fix them, do that now
if (Ty != Offsets->getType()) {
- if ((Ty->getElementType()->getScalarSizeInBits() <
- OffsetType->getElementType()->getScalarSizeInBits())) {
- Offsets = Builder.CreateTrunc(Offsets, Ty);
+ if ((Ty->getElementType()->getScalarSizeInBits() <
+ OffsetType->getElementType()->getScalarSizeInBits())) {
+ Offsets = Builder.CreateTrunc(Offsets, Ty);
} else {
- Offsets = Builder.CreateZExt(Offsets, VectorType::getInteger(Ty));
+ Offsets = Builder.CreateZExt(Offsets, VectorType::getInteger(Ty));
}
}
// If none of the checks failed, return the gep's base pointer
@@ -476,8 +476,8 @@ Value *MVEGatherScatterLowering::tryCreateMaskedGatherOffset(
GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Ptr);
Value *Offsets;
- Value *BasePtr =
- checkGEP(Offsets, cast<FixedVectorType>(ResultTy), GEP, Builder);
+ Value *BasePtr =
+ checkGEP(Offsets, cast<FixedVectorType>(ResultTy), GEP, Builder);
if (!BasePtr)
return nullptr;
// Check whether the offset is a constant increment that could be merged into
@@ -617,8 +617,8 @@ Value *MVEGatherScatterLowering::tryCreateMaskedScatterOffset(
GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Ptr);
Value *Offsets;
- Value *BasePtr =
- checkGEP(Offsets, cast<FixedVectorType>(InputTy), GEP, Builder);
+ Value *BasePtr =
+ checkGEP(Offsets, cast<FixedVectorType>(InputTy), GEP, Builder);
if (!BasePtr)
return nullptr;
// Check whether the offset is a constant increment that could be merged into
@@ -941,7 +941,7 @@ bool MVEGatherScatterLowering::optimiseOffsets(Value *Offsets, BasicBlock *BB,
int IncrementingBlock = -1;
for (int i = 0; i < 2; i++)
- if (auto *Op = dyn_cast<Instruction>(Phi->getIncomingValue(i)))
+ if (auto *Op = dyn_cast<Instruction>(Phi->getIncomingValue(i)))
if (Op->getOpcode() == Instruction::Add &&
(Op->getOperand(0) == Phi || Op->getOperand(1) == Phi))
IncrementingBlock = i;
@@ -960,8 +960,8 @@ bool MVEGatherScatterLowering::optimiseOffsets(Value *Offsets, BasicBlock *BB,
// Get the value that is added to/multiplied with the phi
Value *OffsSecondOperand = Offs->getOperand(OffsSecondOp);
- if (IncrementPerRound->getType() != OffsSecondOperand->getType() ||
- !L->isLoopInvariant(OffsSecondOperand))
+ if (IncrementPerRound->getType() != OffsSecondOperand->getType() ||
+ !L->isLoopInvariant(OffsSecondOperand))
// Something has gone wrong, abort
return false;
@@ -1029,128 +1029,128 @@ bool MVEGatherScatterLowering::optimiseOffsets(Value *Offsets, BasicBlock *BB,
return true;
}
-static Value *CheckAndCreateOffsetAdd(Value *X, Value *Y, Value *GEP,
- IRBuilder<> &Builder) {
- // Splat the non-vector value to a vector of the given type - if the value is
- // a constant (and its value isn't too big), we can even use this opportunity
- // to scale it to the size of the vector elements
- auto FixSummands = [&Builder](FixedVectorType *&VT, Value *&NonVectorVal) {
- ConstantInt *Const;
- if ((Const = dyn_cast<ConstantInt>(NonVectorVal)) &&
- VT->getElementType() != NonVectorVal->getType()) {
- unsigned TargetElemSize = VT->getElementType()->getPrimitiveSizeInBits();
- uint64_t N = Const->getZExtValue();
- if (N < (unsigned)(1 << (TargetElemSize - 1))) {
- NonVectorVal = Builder.CreateVectorSplat(
- VT->getNumElements(), Builder.getIntN(TargetElemSize, N));
- return;
- }
- }
- NonVectorVal =
- Builder.CreateVectorSplat(VT->getNumElements(), NonVectorVal);
- };
-
- FixedVectorType *XElType = dyn_cast<FixedVectorType>(X->getType());
- FixedVectorType *YElType = dyn_cast<FixedVectorType>(Y->getType());
- // If one of X, Y is not a vector, we have to splat it in order
- // to add the two of them.
- if (XElType && !YElType) {
- FixSummands(XElType, Y);
- YElType = cast<FixedVectorType>(Y->getType());
- } else if (YElType && !XElType) {
- FixSummands(YElType, X);
- XElType = cast<FixedVectorType>(X->getType());
- }
- assert(XElType && YElType && "Unknown vector types");
- // Check that the summands are of compatible types
- if (XElType != YElType) {
- LLVM_DEBUG(dbgs() << "masked gathers/scatters: incompatible gep offsets\n");
- return nullptr;
- }
-
- if (XElType->getElementType()->getScalarSizeInBits() != 32) {
- // Check that by adding the vectors we do not accidentally
- // create an overflow
- Constant *ConstX = dyn_cast<Constant>(X);
- Constant *ConstY = dyn_cast<Constant>(Y);
- if (!ConstX || !ConstY)
- return nullptr;
- unsigned TargetElemSize = 128 / XElType->getNumElements();
- for (unsigned i = 0; i < XElType->getNumElements(); i++) {
- ConstantInt *ConstXEl =
- dyn_cast<ConstantInt>(ConstX->getAggregateElement(i));
- ConstantInt *ConstYEl =
- dyn_cast<ConstantInt>(ConstY->getAggregateElement(i));
- if (!ConstXEl || !ConstYEl ||
- ConstXEl->getZExtValue() + ConstYEl->getZExtValue() >=
- (unsigned)(1 << (TargetElemSize - 1)))
- return nullptr;
- }
- }
-
- Value *Add = Builder.CreateAdd(X, Y);
-
- FixedVectorType *GEPType = cast<FixedVectorType>(GEP->getType());
- if (checkOffsetSize(Add, GEPType->getNumElements()))
- return Add;
- else
- return nullptr;
-}
-
-Value *MVEGatherScatterLowering::foldGEP(GetElementPtrInst *GEP,
- Value *&Offsets,
- IRBuilder<> &Builder) {
- Value *GEPPtr = GEP->getPointerOperand();
- Offsets = GEP->getOperand(1);
- // We only merge geps with constant offsets, because only for those
- // we can make sure that we do not cause an overflow
- if (!isa<Constant>(Offsets))
- return nullptr;
- GetElementPtrInst *BaseGEP;
- if ((BaseGEP = dyn_cast<GetElementPtrInst>(GEPPtr))) {
- // Merge the two geps into one
- Value *BaseBasePtr = foldGEP(BaseGEP, Offsets, Builder);
- if (!BaseBasePtr)
- return nullptr;
- Offsets =
- CheckAndCreateOffsetAdd(Offsets, GEP->getOperand(1), GEP, Builder);
- if (Offsets == nullptr)
- return nullptr;
- return BaseBasePtr;
- }
- return GEPPtr;
-}
-
-bool MVEGatherScatterLowering::optimiseAddress(Value *Address, BasicBlock *BB,
- LoopInfo *LI) {
- GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Address);
- if (!GEP)
- return false;
- bool Changed = false;
- if (GEP->hasOneUse() &&
- dyn_cast<GetElementPtrInst>(GEP->getPointerOperand())) {
- IRBuilder<> Builder(GEP->getContext());
- Builder.SetInsertPoint(GEP);
- Builder.SetCurrentDebugLocation(GEP->getDebugLoc());
- Value *Offsets;
- Value *Base = foldGEP(GEP, Offsets, Builder);
- // We only want to merge the geps if there is a real chance that they can be
- // used by an MVE gather; thus the offset has to have the correct size
- // (always i32 if it is not of vector type) and the base has to be a
- // pointer.
- if (Offsets && Base && Base != GEP) {
- PointerType *BaseType = cast<PointerType>(Base->getType());
- GetElementPtrInst *NewAddress = GetElementPtrInst::Create(
- BaseType->getPointerElementType(), Base, Offsets, "gep.merged", GEP);
- GEP->replaceAllUsesWith(NewAddress);
- GEP = NewAddress;
- Changed = true;
- }
- }
- Changed |= optimiseOffsets(GEP->getOperand(1), GEP->getParent(), LI);
- return Changed;
-}
-
+static Value *CheckAndCreateOffsetAdd(Value *X, Value *Y, Value *GEP,
+ IRBuilder<> &Builder) {
+ // Splat the non-vector value to a vector of the given type - if the value is
+ // a constant (and its value isn't too big), we can even use this opportunity
+ // to scale it to the size of the vector elements
+ auto FixSummands = [&Builder](FixedVectorType *&VT, Value *&NonVectorVal) {
+ ConstantInt *Const;
+ if ((Const = dyn_cast<ConstantInt>(NonVectorVal)) &&
+ VT->getElementType() != NonVectorVal->getType()) {
+ unsigned TargetElemSize = VT->getElementType()->getPrimitiveSizeInBits();
+ uint64_t N = Const->getZExtValue();
+ if (N < (unsigned)(1 << (TargetElemSize - 1))) {
+ NonVectorVal = Builder.CreateVectorSplat(
+ VT->getNumElements(), Builder.getIntN(TargetElemSize, N));
+ return;
+ }
+ }
+ NonVectorVal =
+ Builder.CreateVectorSplat(VT->getNumElements(), NonVectorVal);
+ };
+
+ FixedVectorType *XElType = dyn_cast<FixedVectorType>(X->getType());
+ FixedVectorType *YElType = dyn_cast<FixedVectorType>(Y->getType());
+ // If one of X, Y is not a vector, we have to splat it in order
+ // to add the two of them.
+ if (XElType && !YElType) {
+ FixSummands(XElType, Y);
+ YElType = cast<FixedVectorType>(Y->getType());
+ } else if (YElType && !XElType) {
+ FixSummands(YElType, X);
+ XElType = cast<FixedVectorType>(X->getType());
+ }
+ assert(XElType && YElType && "Unknown vector types");
+ // Check that the summands are of compatible types
+ if (XElType != YElType) {
+ LLVM_DEBUG(dbgs() << "masked gathers/scatters: incompatible gep offsets\n");
+ return nullptr;
+ }
+
+ if (XElType->getElementType()->getScalarSizeInBits() != 32) {
+ // Check that by adding the vectors we do not accidentally
+ // create an overflow
+ Constant *ConstX = dyn_cast<Constant>(X);
+ Constant *ConstY = dyn_cast<Constant>(Y);
+ if (!ConstX || !ConstY)
+ return nullptr;
+ unsigned TargetElemSize = 128 / XElType->getNumElements();
+ for (unsigned i = 0; i < XElType->getNumElements(); i++) {
+ ConstantInt *ConstXEl =
+ dyn_cast<ConstantInt>(ConstX->getAggregateElement(i));
+ ConstantInt *ConstYEl =
+ dyn_cast<ConstantInt>(ConstY->getAggregateElement(i));
+ if (!ConstXEl || !ConstYEl ||
+ ConstXEl->getZExtValue() + ConstYEl->getZExtValue() >=
+ (unsigned)(1 << (TargetElemSize - 1)))
+ return nullptr;
+ }
+ }
+
+ Value *Add = Builder.CreateAdd(X, Y);
+
+ FixedVectorType *GEPType = cast<FixedVectorType>(GEP->getType());
+ if (checkOffsetSize(Add, GEPType->getNumElements()))
+ return Add;
+ else
+ return nullptr;
+}
+
+Value *MVEGatherScatterLowering::foldGEP(GetElementPtrInst *GEP,
+ Value *&Offsets,
+ IRBuilder<> &Builder) {
+ Value *GEPPtr = GEP->getPointerOperand();
+ Offsets = GEP->getOperand(1);
+ // We only merge geps with constant offsets, because only for those
+ // we can make sure that we do not cause an overflow
+ if (!isa<Constant>(Offsets))
+ return nullptr;
+ GetElementPtrInst *BaseGEP;
+ if ((BaseGEP = dyn_cast<GetElementPtrInst>(GEPPtr))) {
+ // Merge the two geps into one
+ Value *BaseBasePtr = foldGEP(BaseGEP, Offsets, Builder);
+ if (!BaseBasePtr)
+ return nullptr;
+ Offsets =
+ CheckAndCreateOffsetAdd(Offsets, GEP->getOperand(1), GEP, Builder);
+ if (Offsets == nullptr)
+ return nullptr;
+ return BaseBasePtr;
+ }
+ return GEPPtr;
+}
+
+bool MVEGatherScatterLowering::optimiseAddress(Value *Address, BasicBlock *BB,
+ LoopInfo *LI) {
+ GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Address);
+ if (!GEP)
+ return false;
+ bool Changed = false;
+ if (GEP->hasOneUse() &&
+ dyn_cast<GetElementPtrInst>(GEP->getPointerOperand())) {
+ IRBuilder<> Builder(GEP->getContext());
+ Builder.SetInsertPoint(GEP);
+ Builder.SetCurrentDebugLocation(GEP->getDebugLoc());
+ Value *Offsets;
+ Value *Base = foldGEP(GEP, Offsets, Builder);
+ // We only want to merge the geps if there is a real chance that they can be
+ // used by an MVE gather; thus the offset has to have the correct size
+ // (always i32 if it is not of vector type) and the base has to be a
+ // pointer.
+ if (Offsets && Base && Base != GEP) {
+ PointerType *BaseType = cast<PointerType>(Base->getType());
+ GetElementPtrInst *NewAddress = GetElementPtrInst::Create(
+ BaseType->getPointerElementType(), Base, Offsets, "gep.merged", GEP);
+ GEP->replaceAllUsesWith(NewAddress);
+ GEP = NewAddress;
+ Changed = true;
+ }
+ }
+ Changed |= optimiseOffsets(GEP->getOperand(1), GEP->getParent(), LI);
+ return Changed;
+}
+
bool MVEGatherScatterLowering::runOnFunction(Function &F) {
if (!EnableMaskedGatherScatters)
return false;
@@ -1166,18 +1166,18 @@ bool MVEGatherScatterLowering::runOnFunction(Function &F) {
bool Changed = false;
for (BasicBlock &BB : F) {
- Changed |= SimplifyInstructionsInBlock(&BB);
-
+ Changed |= SimplifyInstructionsInBlock(&BB);
+
for (Instruction &I : BB) {
IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I);
- if (II && II->getIntrinsicID() == Intrinsic::masked_gather &&
- isa<FixedVectorType>(II->getType())) {
+ if (II && II->getIntrinsicID() == Intrinsic::masked_gather &&
+ isa<FixedVectorType>(II->getType())) {
Gathers.push_back(II);
- Changed |= optimiseAddress(II->getArgOperand(0), II->getParent(), LI);
- } else if (II && II->getIntrinsicID() == Intrinsic::masked_scatter &&
- isa<FixedVectorType>(II->getArgOperand(0)->getType())) {
+ Changed |= optimiseAddress(II->getArgOperand(0), II->getParent(), LI);
+ } else if (II && II->getIntrinsicID() == Intrinsic::masked_scatter &&
+ isa<FixedVectorType>(II->getArgOperand(0)->getType())) {
Scatters.push_back(II);
- Changed |= optimiseAddress(II->getArgOperand(1), II->getParent(), LI);
+ Changed |= optimiseAddress(II->getArgOperand(1), II->getParent(), LI);
}
}
}
diff --git a/contrib/libs/llvm12/lib/Target/ARM/MVETailPredUtils.h b/contrib/libs/llvm12/lib/Target/ARM/MVETailPredUtils.h
index 1bb23cc725..9ab5d92729 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/MVETailPredUtils.h
+++ b/contrib/libs/llvm12/lib/Target/ARM/MVETailPredUtils.h
@@ -1,157 +1,157 @@
-//===-- MVETailPredUtils.h - Tail predication utility functions -*- C++-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains utility functions for low overhead and tail predicated
-// loops, shared between the ARMLowOverheadLoops pass and anywhere else that
-// needs them.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_TARGET_ARM_MVETAILPREDUTILS_H
-#define LLVM_LIB_TARGET_ARM_MVETAILPREDUTILS_H
-
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineOperand.h"
-#include "llvm/CodeGen/TargetInstrInfo.h"
-
-namespace llvm {
-
-static inline unsigned VCTPOpcodeToLSTP(unsigned Opcode, bool IsDoLoop) {
- switch (Opcode) {
- default:
- llvm_unreachable("unhandled vctp opcode");
- break;
- case ARM::MVE_VCTP8:
- return IsDoLoop ? ARM::MVE_DLSTP_8 : ARM::MVE_WLSTP_8;
- case ARM::MVE_VCTP16:
- return IsDoLoop ? ARM::MVE_DLSTP_16 : ARM::MVE_WLSTP_16;
- case ARM::MVE_VCTP32:
- return IsDoLoop ? ARM::MVE_DLSTP_32 : ARM::MVE_WLSTP_32;
- case ARM::MVE_VCTP64:
- return IsDoLoop ? ARM::MVE_DLSTP_64 : ARM::MVE_WLSTP_64;
- }
- return 0;
-}
-
-static inline unsigned getTailPredVectorWidth(unsigned Opcode) {
- switch (Opcode) {
- default:
- llvm_unreachable("unhandled vctp opcode");
- case ARM::MVE_VCTP8:
- return 16;
- case ARM::MVE_VCTP16:
- return 8;
- case ARM::MVE_VCTP32:
- return 4;
- case ARM::MVE_VCTP64:
- return 2;
- }
- return 0;
-}
-
-static inline bool isVCTP(const MachineInstr *MI) {
- switch (MI->getOpcode()) {
- default:
- break;
- case ARM::MVE_VCTP8:
- case ARM::MVE_VCTP16:
- case ARM::MVE_VCTP32:
- case ARM::MVE_VCTP64:
- return true;
- }
- return false;
-}
-
-static inline bool isLoopStart(MachineInstr &MI) {
- return MI.getOpcode() == ARM::t2DoLoopStart ||
- MI.getOpcode() == ARM::t2DoLoopStartTP ||
- MI.getOpcode() == ARM::t2WhileLoopStart;
-}
-
-// WhileLoopStart holds the exit block, so produce a cmp lr, 0 and then a
-// beq that branches to the exit branch.
-inline void RevertWhileLoopStart(MachineInstr *MI, const TargetInstrInfo *TII,
- unsigned BrOpc = ARM::t2Bcc) {
- MachineBasicBlock *MBB = MI->getParent();
-
- // Cmp
- MachineInstrBuilder MIB =
- BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2CMPri));
- MIB.add(MI->getOperand(0));
- MIB.addImm(0);
- MIB.addImm(ARMCC::AL);
- MIB.addReg(ARM::NoRegister);
-
- // Branch
- MIB = BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(BrOpc));
- MIB.add(MI->getOperand(1)); // branch target
- MIB.addImm(ARMCC::EQ); // condition code
- MIB.addReg(ARM::CPSR);
-
- MI->eraseFromParent();
-}
-
-inline void RevertDoLoopStart(MachineInstr *MI, const TargetInstrInfo *TII) {
- MachineBasicBlock *MBB = MI->getParent();
- BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::tMOVr))
- .add(MI->getOperand(0))
- .add(MI->getOperand(1))
- .add(predOps(ARMCC::AL));
-
- MI->eraseFromParent();
-}
-
-inline void RevertLoopDec(MachineInstr *MI, const TargetInstrInfo *TII,
- bool SetFlags = false) {
- MachineBasicBlock *MBB = MI->getParent();
-
- MachineInstrBuilder MIB =
- BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2SUBri));
- MIB.add(MI->getOperand(0));
- MIB.add(MI->getOperand(1));
- MIB.add(MI->getOperand(2));
- MIB.addImm(ARMCC::AL);
- MIB.addReg(0);
-
- if (SetFlags) {
- MIB.addReg(ARM::CPSR);
- MIB->getOperand(5).setIsDef(true);
- } else
- MIB.addReg(0);
-
- MI->eraseFromParent();
-}
-
-// Generate a subs, or sub and cmp, and a branch instead of an LE.
-inline void RevertLoopEnd(MachineInstr *MI, const TargetInstrInfo *TII,
- unsigned BrOpc = ARM::t2Bcc, bool SkipCmp = false) {
- MachineBasicBlock *MBB = MI->getParent();
-
- // Create cmp
- if (!SkipCmp) {
- MachineInstrBuilder MIB =
- BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2CMPri));
- MIB.add(MI->getOperand(0));
- MIB.addImm(0);
- MIB.addImm(ARMCC::AL);
- MIB.addReg(ARM::NoRegister);
- }
-
- // Create bne
- MachineInstrBuilder MIB =
- BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(BrOpc));
- MIB.add(MI->getOperand(1)); // branch target
- MIB.addImm(ARMCC::NE); // condition code
- MIB.addReg(ARM::CPSR);
- MI->eraseFromParent();
-}
-
-} // end namespace llvm
-
-#endif // LLVM_LIB_TARGET_ARM_MVETAILPREDUTILS_H
+//===-- MVETailPredUtils.h - Tail predication utility functions -*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains utility functions for low overhead and tail predicated
+// loops, shared between the ARMLowOverheadLoops pass and anywhere else that
+// needs them.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_ARM_MVETAILPREDUTILS_H
+#define LLVM_LIB_TARGET_ARM_MVETAILPREDUTILS_H
+
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+
+namespace llvm {
+
+static inline unsigned VCTPOpcodeToLSTP(unsigned Opcode, bool IsDoLoop) {
+ switch (Opcode) {
+ default:
+ llvm_unreachable("unhandled vctp opcode");
+ break;
+ case ARM::MVE_VCTP8:
+ return IsDoLoop ? ARM::MVE_DLSTP_8 : ARM::MVE_WLSTP_8;
+ case ARM::MVE_VCTP16:
+ return IsDoLoop ? ARM::MVE_DLSTP_16 : ARM::MVE_WLSTP_16;
+ case ARM::MVE_VCTP32:
+ return IsDoLoop ? ARM::MVE_DLSTP_32 : ARM::MVE_WLSTP_32;
+ case ARM::MVE_VCTP64:
+ return IsDoLoop ? ARM::MVE_DLSTP_64 : ARM::MVE_WLSTP_64;
+ }
+ return 0;
+}
+
+static inline unsigned getTailPredVectorWidth(unsigned Opcode) {
+ switch (Opcode) {
+ default:
+ llvm_unreachable("unhandled vctp opcode");
+ case ARM::MVE_VCTP8:
+ return 16;
+ case ARM::MVE_VCTP16:
+ return 8;
+ case ARM::MVE_VCTP32:
+ return 4;
+ case ARM::MVE_VCTP64:
+ return 2;
+ }
+ return 0;
+}
+
+static inline bool isVCTP(const MachineInstr *MI) {
+ switch (MI->getOpcode()) {
+ default:
+ break;
+ case ARM::MVE_VCTP8:
+ case ARM::MVE_VCTP16:
+ case ARM::MVE_VCTP32:
+ case ARM::MVE_VCTP64:
+ return true;
+ }
+ return false;
+}
+
+static inline bool isLoopStart(MachineInstr &MI) {
+ return MI.getOpcode() == ARM::t2DoLoopStart ||
+ MI.getOpcode() == ARM::t2DoLoopStartTP ||
+ MI.getOpcode() == ARM::t2WhileLoopStart;
+}
+
+// WhileLoopStart holds the exit block, so produce a cmp lr, 0 and then a
+// beq that branches to the exit branch.
+inline void RevertWhileLoopStart(MachineInstr *MI, const TargetInstrInfo *TII,
+ unsigned BrOpc = ARM::t2Bcc) {
+ MachineBasicBlock *MBB = MI->getParent();
+
+ // Cmp
+ MachineInstrBuilder MIB =
+ BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2CMPri));
+ MIB.add(MI->getOperand(0));
+ MIB.addImm(0);
+ MIB.addImm(ARMCC::AL);
+ MIB.addReg(ARM::NoRegister);
+
+ // Branch
+ MIB = BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(BrOpc));
+ MIB.add(MI->getOperand(1)); // branch target
+ MIB.addImm(ARMCC::EQ); // condition code
+ MIB.addReg(ARM::CPSR);
+
+ MI->eraseFromParent();
+}
+
+inline void RevertDoLoopStart(MachineInstr *MI, const TargetInstrInfo *TII) {
+ MachineBasicBlock *MBB = MI->getParent();
+ BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::tMOVr))
+ .add(MI->getOperand(0))
+ .add(MI->getOperand(1))
+ .add(predOps(ARMCC::AL));
+
+ MI->eraseFromParent();
+}
+
+inline void RevertLoopDec(MachineInstr *MI, const TargetInstrInfo *TII,
+ bool SetFlags = false) {
+ MachineBasicBlock *MBB = MI->getParent();
+
+ MachineInstrBuilder MIB =
+ BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2SUBri));
+ MIB.add(MI->getOperand(0));
+ MIB.add(MI->getOperand(1));
+ MIB.add(MI->getOperand(2));
+ MIB.addImm(ARMCC::AL);
+ MIB.addReg(0);
+
+ if (SetFlags) {
+ MIB.addReg(ARM::CPSR);
+ MIB->getOperand(5).setIsDef(true);
+ } else
+ MIB.addReg(0);
+
+ MI->eraseFromParent();
+}
+
+// Generate a subs, or sub and cmp, and a branch instead of an LE.
+inline void RevertLoopEnd(MachineInstr *MI, const TargetInstrInfo *TII,
+ unsigned BrOpc = ARM::t2Bcc, bool SkipCmp = false) {
+ MachineBasicBlock *MBB = MI->getParent();
+
+ // Create cmp
+ if (!SkipCmp) {
+ MachineInstrBuilder MIB =
+ BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2CMPri));
+ MIB.add(MI->getOperand(0));
+ MIB.addImm(0);
+ MIB.addImm(ARMCC::AL);
+ MIB.addReg(ARM::NoRegister);
+ }
+
+ // Create bne
+ MachineInstrBuilder MIB =
+ BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(BrOpc));
+ MIB.add(MI->getOperand(1)); // branch target
+ MIB.addImm(ARMCC::NE); // condition code
+ MIB.addReg(ARM::CPSR);
+ MI->eraseFromParent();
+}
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_ARM_MVETAILPREDUTILS_H
diff --git a/contrib/libs/llvm12/lib/Target/ARM/MVETailPredication.cpp b/contrib/libs/llvm12/lib/Target/ARM/MVETailPredication.cpp
index 94e71f1d60..cccac55952 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/MVETailPredication.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/MVETailPredication.cpp
@@ -22,13 +22,13 @@
/// The HardwareLoops pass inserts intrinsics identifying loops that the
/// backend will attempt to convert into a low-overhead loop. The vectorizer is
/// responsible for generating a vectorized loop in which the lanes are
-/// predicated upon an get.active.lane.mask intrinsic. This pass looks at these
-/// get.active.lane.mask intrinsic and attempts to convert them to VCTP
-/// instructions. This will be picked up by the ARM Low-overhead loop pass later
-/// in the backend, which performs the final transformation to a DLSTP or WLSTP
-/// tail-predicated loop.
-//
-//===----------------------------------------------------------------------===//
+/// predicated upon an get.active.lane.mask intrinsic. This pass looks at these
+/// get.active.lane.mask intrinsic and attempts to convert them to VCTP
+/// instructions. This will be picked up by the ARM Low-overhead loop pass later
+/// in the backend, which performs the final transformation to a DLSTP or WLSTP
+/// tail-predicated loop.
+//
+//===----------------------------------------------------------------------===//
#include "ARM.h"
#include "ARMSubtarget.h"
@@ -47,7 +47,7 @@
#include "llvm/InitializePasses.h"
#include "llvm/Support/Debug.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
#include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
@@ -57,8 +57,8 @@ using namespace llvm;
#define DESC "Transform predicated vector loops to use MVE tail predication"
cl::opt<TailPredication::Mode> EnableTailPredication(
- "tail-predication", cl::desc("MVE tail-predication pass options"),
- cl::init(TailPredication::Enabled),
+ "tail-predication", cl::desc("MVE tail-predication pass options"),
+ cl::init(TailPredication::Enabled),
cl::values(clEnumValN(TailPredication::Disabled, "disabled",
"Don't tail-predicate loops"),
clEnumValN(TailPredication::EnabledNoReductions,
@@ -103,18 +103,18 @@ public:
bool runOnLoop(Loop *L, LPPassManager&) override;
private:
- /// Perform the relevant checks on the loop and convert active lane masks if
- /// possible.
- bool TryConvertActiveLaneMask(Value *TripCount);
+ /// Perform the relevant checks on the loop and convert active lane masks if
+ /// possible.
+ bool TryConvertActiveLaneMask(Value *TripCount);
- /// Perform several checks on the arguments of @llvm.get.active.lane.mask
- /// intrinsic. E.g., check that the loop induction variable and the element
- /// count are of the form we expect, and also perform overflow checks for
- /// the new expressions that are created.
- bool IsSafeActiveMask(IntrinsicInst *ActiveLaneMask, Value *TripCount);
+ /// Perform several checks on the arguments of @llvm.get.active.lane.mask
+ /// intrinsic. E.g., check that the loop induction variable and the element
+ /// count are of the form we expect, and also perform overflow checks for
+ /// the new expressions that are created.
+ bool IsSafeActiveMask(IntrinsicInst *ActiveLaneMask, Value *TripCount);
/// Insert the intrinsic to represent the effect of tail predication.
- void InsertVCTPIntrinsic(IntrinsicInst *ActiveLaneMask, Value *TripCount);
+ void InsertVCTPIntrinsic(IntrinsicInst *ActiveLaneMask, Value *TripCount);
/// Rematerialize the iteration count in exit blocks, which enables
/// ARMLowOverheadLoops to better optimise away loop update statements inside
@@ -155,7 +155,7 @@ bool MVETailPredication::runOnLoop(Loop *L, LPPassManager&) {
continue;
Intrinsic::ID ID = Call->getIntrinsicID();
- if (ID == Intrinsic::start_loop_iterations ||
+ if (ID == Intrinsic::start_loop_iterations ||
ID == Intrinsic::test_set_loop_iterations)
return cast<IntrinsicInst>(&I);
}
@@ -174,23 +174,23 @@ bool MVETailPredication::runOnLoop(Loop *L, LPPassManager&) {
return false;
}
- LLVM_DEBUG(dbgs() << "ARM TP: Running on Loop: " << *L << *Setup << "\n");
+ LLVM_DEBUG(dbgs() << "ARM TP: Running on Loop: " << *L << *Setup << "\n");
- bool Changed = TryConvertActiveLaneMask(Setup->getArgOperand(0));
+ bool Changed = TryConvertActiveLaneMask(Setup->getArgOperand(0));
- return Changed;
+ return Changed;
}
// The active lane intrinsic has this form:
//
-// @llvm.get.active.lane.mask(IV, TC)
+// @llvm.get.active.lane.mask(IV, TC)
//
// Here we perform checks that this intrinsic behaves as expected,
// which means:
//
-// 1) Check that the TripCount (TC) belongs to this loop (originally).
-// 2) The element count (TC) needs to be sufficiently large that the decrement
-// of element counter doesn't overflow, which means that we need to prove:
+// 1) Check that the TripCount (TC) belongs to this loop (originally).
+// 2) The element count (TC) needs to be sufficiently large that the decrement
+// of element counter doesn't overflow, which means that we need to prove:
// ceil(ElementCount / VectorWidth) >= TripCount
// by rounding up ElementCount up:
// ((ElementCount + (VectorWidth - 1)) / VectorWidth
@@ -199,122 +199,122 @@ bool MVETailPredication::runOnLoop(Loop *L, LPPassManager&) {
// 3) The IV must be an induction phi with an increment equal to the
// vector width.
bool MVETailPredication::IsSafeActiveMask(IntrinsicInst *ActiveLaneMask,
- Value *TripCount) {
+ Value *TripCount) {
bool ForceTailPredication =
EnableTailPredication == TailPredication::ForceEnabledNoReductions ||
EnableTailPredication == TailPredication::ForceEnabled;
- Value *ElemCount = ActiveLaneMask->getOperand(1);
- bool Changed = false;
- if (!L->makeLoopInvariant(ElemCount, Changed))
- return false;
-
- auto *EC= SE->getSCEV(ElemCount);
- auto *TC = SE->getSCEV(TripCount);
- int VectorWidth =
- cast<FixedVectorType>(ActiveLaneMask->getType())->getNumElements();
- if (VectorWidth != 4 && VectorWidth != 8 && VectorWidth != 16)
- return false;
- ConstantInt *ConstElemCount = nullptr;
-
- // 1) Smoke tests that the original scalar loop TripCount (TC) belongs to
- // this loop. The scalar tripcount corresponds the number of elements
- // processed by the loop, so we will refer to that from this point on.
- if (!SE->isLoopInvariant(EC, L)) {
- LLVM_DEBUG(dbgs() << "ARM TP: element count must be loop invariant.\n");
+ Value *ElemCount = ActiveLaneMask->getOperand(1);
+ bool Changed = false;
+ if (!L->makeLoopInvariant(ElemCount, Changed))
+ return false;
+
+ auto *EC= SE->getSCEV(ElemCount);
+ auto *TC = SE->getSCEV(TripCount);
+ int VectorWidth =
+ cast<FixedVectorType>(ActiveLaneMask->getType())->getNumElements();
+ if (VectorWidth != 4 && VectorWidth != 8 && VectorWidth != 16)
+ return false;
+ ConstantInt *ConstElemCount = nullptr;
+
+ // 1) Smoke tests that the original scalar loop TripCount (TC) belongs to
+ // this loop. The scalar tripcount corresponds the number of elements
+ // processed by the loop, so we will refer to that from this point on.
+ if (!SE->isLoopInvariant(EC, L)) {
+ LLVM_DEBUG(dbgs() << "ARM TP: element count must be loop invariant.\n");
return false;
}
- if ((ConstElemCount = dyn_cast<ConstantInt>(ElemCount))) {
- ConstantInt *TC = dyn_cast<ConstantInt>(TripCount);
- if (!TC) {
- LLVM_DEBUG(dbgs() << "ARM TP: Constant tripcount expected in "
- "set.loop.iterations\n");
- return false;
- }
-
- // Calculate 2 tripcount values and check that they are consistent with
- // each other. The TripCount for a predicated vector loop body is
- // ceil(ElementCount/Width), or floor((ElementCount+Width-1)/Width) as we
- // work it out here.
- uint64_t TC1 = TC->getZExtValue();
- uint64_t TC2 =
- (ConstElemCount->getZExtValue() + VectorWidth - 1) / VectorWidth;
-
- // If the tripcount values are inconsistent, we can't insert the VCTP and
- // trigger tail-predication; keep the intrinsic as a get.active.lane.mask
- // and legalize this.
- if (TC1 != TC2) {
- LLVM_DEBUG(dbgs() << "ARM TP: inconsistent constant tripcount values: "
- << TC1 << " from set.loop.iterations, and "
- << TC2 << " from get.active.lane.mask\n");
- return false;
- }
- } else if (!ForceTailPredication) {
- // 2) We need to prove that the sub expression that we create in the
- // tail-predicated loop body, which calculates the remaining elements to be
- // processed, is non-negative, i.e. it doesn't overflow:
- //
- // ((ElementCount + VectorWidth - 1) / VectorWidth) - TripCount >= 0
- //
- // This is true if:
- //
- // TripCount == (ElementCount + VectorWidth - 1) / VectorWidth
- //
- // which what we will be using here.
- //
- auto *VW = SE->getSCEV(ConstantInt::get(TripCount->getType(), VectorWidth));
- // ElementCount + (VW-1):
- auto *ECPlusVWMinus1 = SE->getAddExpr(EC,
- SE->getSCEV(ConstantInt::get(TripCount->getType(), VectorWidth - 1)));
-
- // Ceil = ElementCount + (VW-1) / VW
- auto *Ceil = SE->getUDivExpr(ECPlusVWMinus1, VW);
-
- // Prevent unused variable warnings with TC
- (void)TC;
- LLVM_DEBUG(
- dbgs() << "ARM TP: Analysing overflow behaviour for:\n";
- dbgs() << "ARM TP: - TripCount = "; TC->dump();
- dbgs() << "ARM TP: - ElemCount = "; EC->dump();
- dbgs() << "ARM TP: - VecWidth = " << VectorWidth << "\n";
- dbgs() << "ARM TP: - (ElemCount+VW-1) / VW = "; Ceil->dump();
- );
-
- // As an example, almost all the tripcount expressions (produced by the
- // vectoriser) look like this:
- //
- // TC = ((-4 + (4 * ((3 + %N) /u 4))<nuw>) /u 4)
- //
- // and "ElementCount + (VW-1) / VW":
- //
- // Ceil = ((3 + %N) /u 4)
- //
- // Check for equality of TC and Ceil by calculating SCEV expression
- // TC - Ceil and test it for zero.
- //
- bool Zero = SE->getMinusSCEV(
- SE->getBackedgeTakenCount(L),
- SE->getUDivExpr(SE->getAddExpr(SE->getMulExpr(Ceil, VW),
- SE->getNegativeSCEV(VW)),
- VW))
- ->isZero();
-
- if (!Zero) {
- LLVM_DEBUG(dbgs() << "ARM TP: possible overflow in sub expression.\n");
- return false;
- }
+ if ((ConstElemCount = dyn_cast<ConstantInt>(ElemCount))) {
+ ConstantInt *TC = dyn_cast<ConstantInt>(TripCount);
+ if (!TC) {
+ LLVM_DEBUG(dbgs() << "ARM TP: Constant tripcount expected in "
+ "set.loop.iterations\n");
+ return false;
+ }
+
+ // Calculate 2 tripcount values and check that they are consistent with
+ // each other. The TripCount for a predicated vector loop body is
+ // ceil(ElementCount/Width), or floor((ElementCount+Width-1)/Width) as we
+ // work it out here.
+ uint64_t TC1 = TC->getZExtValue();
+ uint64_t TC2 =
+ (ConstElemCount->getZExtValue() + VectorWidth - 1) / VectorWidth;
+
+ // If the tripcount values are inconsistent, we can't insert the VCTP and
+ // trigger tail-predication; keep the intrinsic as a get.active.lane.mask
+ // and legalize this.
+ if (TC1 != TC2) {
+ LLVM_DEBUG(dbgs() << "ARM TP: inconsistent constant tripcount values: "
+ << TC1 << " from set.loop.iterations, and "
+ << TC2 << " from get.active.lane.mask\n");
+ return false;
+ }
+ } else if (!ForceTailPredication) {
+ // 2) We need to prove that the sub expression that we create in the
+ // tail-predicated loop body, which calculates the remaining elements to be
+ // processed, is non-negative, i.e. it doesn't overflow:
+ //
+ // ((ElementCount + VectorWidth - 1) / VectorWidth) - TripCount >= 0
+ //
+ // This is true if:
+ //
+ // TripCount == (ElementCount + VectorWidth - 1) / VectorWidth
+ //
+ // which what we will be using here.
+ //
+ auto *VW = SE->getSCEV(ConstantInt::get(TripCount->getType(), VectorWidth));
+ // ElementCount + (VW-1):
+ auto *ECPlusVWMinus1 = SE->getAddExpr(EC,
+ SE->getSCEV(ConstantInt::get(TripCount->getType(), VectorWidth - 1)));
+
+ // Ceil = ElementCount + (VW-1) / VW
+ auto *Ceil = SE->getUDivExpr(ECPlusVWMinus1, VW);
+
+ // Prevent unused variable warnings with TC
+ (void)TC;
+ LLVM_DEBUG(
+ dbgs() << "ARM TP: Analysing overflow behaviour for:\n";
+ dbgs() << "ARM TP: - TripCount = "; TC->dump();
+ dbgs() << "ARM TP: - ElemCount = "; EC->dump();
+ dbgs() << "ARM TP: - VecWidth = " << VectorWidth << "\n";
+ dbgs() << "ARM TP: - (ElemCount+VW-1) / VW = "; Ceil->dump();
+ );
+
+ // As an example, almost all the tripcount expressions (produced by the
+ // vectoriser) look like this:
+ //
+ // TC = ((-4 + (4 * ((3 + %N) /u 4))<nuw>) /u 4)
+ //
+ // and "ElementCount + (VW-1) / VW":
+ //
+ // Ceil = ((3 + %N) /u 4)
+ //
+ // Check for equality of TC and Ceil by calculating SCEV expression
+ // TC - Ceil and test it for zero.
+ //
+ bool Zero = SE->getMinusSCEV(
+ SE->getBackedgeTakenCount(L),
+ SE->getUDivExpr(SE->getAddExpr(SE->getMulExpr(Ceil, VW),
+ SE->getNegativeSCEV(VW)),
+ VW))
+ ->isZero();
+
+ if (!Zero) {
+ LLVM_DEBUG(dbgs() << "ARM TP: possible overflow in sub expression.\n");
+ return false;
+ }
}
- // 3) Find out if IV is an induction phi. Note that we can't use Loop
+ // 3) Find out if IV is an induction phi. Note that we can't use Loop
// helpers here to get the induction variable, because the hardware loop is
- // no longer in loopsimplify form, and also the hwloop intrinsic uses a
- // different counter. Using SCEV, we check that the induction is of the
+ // no longer in loopsimplify form, and also the hwloop intrinsic uses a
+ // different counter. Using SCEV, we check that the induction is of the
// form i = i + 4, where the increment must be equal to the VectorWidth.
auto *IV = ActiveLaneMask->getOperand(0);
auto *IVExpr = SE->getSCEV(IV);
auto *AddExpr = dyn_cast<SCEVAddRecExpr>(IVExpr);
-
+
if (!AddExpr) {
LLVM_DEBUG(dbgs() << "ARM TP: induction not an add expr: "; IVExpr->dump());
return false;
@@ -324,11 +324,11 @@ bool MVETailPredication::IsSafeActiveMask(IntrinsicInst *ActiveLaneMask,
LLVM_DEBUG(dbgs() << "ARM TP: phi not part of this loop\n");
return false;
}
- auto *Base = dyn_cast<SCEVConstant>(AddExpr->getOperand(0));
- if (!Base || !Base->isZero()) {
- LLVM_DEBUG(dbgs() << "ARM TP: induction base is not 0\n");
- return false;
- }
+ auto *Base = dyn_cast<SCEVConstant>(AddExpr->getOperand(0));
+ if (!Base || !Base->isZero()) {
+ LLVM_DEBUG(dbgs() << "ARM TP: induction base is not 0\n");
+ return false;
+ }
auto *Step = dyn_cast<SCEVConstant>(AddExpr->getOperand(1));
if (!Step) {
LLVM_DEBUG(dbgs() << "ARM TP: induction step is not a constant: ";
@@ -339,29 +339,29 @@ bool MVETailPredication::IsSafeActiveMask(IntrinsicInst *ActiveLaneMask,
if (VectorWidth == StepValue)
return true;
- LLVM_DEBUG(dbgs() << "ARM TP: Step value " << StepValue
- << " doesn't match vector width " << VectorWidth << "\n");
+ LLVM_DEBUG(dbgs() << "ARM TP: Step value " << StepValue
+ << " doesn't match vector width " << VectorWidth << "\n");
return false;
}
void MVETailPredication::InsertVCTPIntrinsic(IntrinsicInst *ActiveLaneMask,
- Value *TripCount) {
+ Value *TripCount) {
IRBuilder<> Builder(L->getLoopPreheader()->getTerminator());
Module *M = L->getHeader()->getModule();
Type *Ty = IntegerType::get(M->getContext(), 32);
- unsigned VectorWidth =
- cast<FixedVectorType>(ActiveLaneMask->getType())->getNumElements();
+ unsigned VectorWidth =
+ cast<FixedVectorType>(ActiveLaneMask->getType())->getNumElements();
// Insert a phi to count the number of elements processed by the loop.
- Builder.SetInsertPoint(L->getHeader()->getFirstNonPHI());
+ Builder.SetInsertPoint(L->getHeader()->getFirstNonPHI());
PHINode *Processed = Builder.CreatePHI(Ty, 2);
- Processed->addIncoming(ActiveLaneMask->getOperand(1), L->getLoopPreheader());
+ Processed->addIncoming(ActiveLaneMask->getOperand(1), L->getLoopPreheader());
- // Replace @llvm.get.active.mask() with the ARM specific VCTP intrinic, and
- // thus represent the effect of tail predication.
+ // Replace @llvm.get.active.mask() with the ARM specific VCTP intrinic, and
+ // thus represent the effect of tail predication.
Builder.SetInsertPoint(ActiveLaneMask);
- ConstantInt *Factor = ConstantInt::get(cast<IntegerType>(Ty), VectorWidth);
+ ConstantInt *Factor = ConstantInt::get(cast<IntegerType>(Ty), VectorWidth);
Intrinsic::ID VCTPID;
switch (VectorWidth) {
@@ -390,36 +390,36 @@ void MVETailPredication::InsertVCTPIntrinsic(IntrinsicInst *ActiveLaneMask,
<< "ARM TP: Inserted VCTP: " << *VCTPCall << "\n");
}
-bool MVETailPredication::TryConvertActiveLaneMask(Value *TripCount) {
- SmallVector<IntrinsicInst *, 4> ActiveLaneMasks;
- for (auto *BB : L->getBlocks())
- for (auto &I : *BB)
- if (auto *Int = dyn_cast<IntrinsicInst>(&I))
- if (Int->getIntrinsicID() == Intrinsic::get_active_lane_mask)
- ActiveLaneMasks.push_back(Int);
-
- if (ActiveLaneMasks.empty())
+bool MVETailPredication::TryConvertActiveLaneMask(Value *TripCount) {
+ SmallVector<IntrinsicInst *, 4> ActiveLaneMasks;
+ for (auto *BB : L->getBlocks())
+ for (auto &I : *BB)
+ if (auto *Int = dyn_cast<IntrinsicInst>(&I))
+ if (Int->getIntrinsicID() == Intrinsic::get_active_lane_mask)
+ ActiveLaneMasks.push_back(Int);
+
+ if (ActiveLaneMasks.empty())
return false;
LLVM_DEBUG(dbgs() << "ARM TP: Found predicated vector loop.\n");
- for (auto *ActiveLaneMask : ActiveLaneMasks) {
+ for (auto *ActiveLaneMask : ActiveLaneMasks) {
LLVM_DEBUG(dbgs() << "ARM TP: Found active lane mask: "
<< *ActiveLaneMask << "\n");
- if (!IsSafeActiveMask(ActiveLaneMask, TripCount)) {
+ if (!IsSafeActiveMask(ActiveLaneMask, TripCount)) {
LLVM_DEBUG(dbgs() << "ARM TP: Not safe to insert VCTP.\n");
return false;
}
LLVM_DEBUG(dbgs() << "ARM TP: Safe to insert VCTP.\n");
- InsertVCTPIntrinsic(ActiveLaneMask, TripCount);
+ InsertVCTPIntrinsic(ActiveLaneMask, TripCount);
}
- // Remove dead instructions and now dead phis.
- for (auto *II : ActiveLaneMasks)
- RecursivelyDeleteTriviallyDeadInstructions(II);
- for (auto I : L->blocks())
- DeleteDeadPHIs(I);
+ // Remove dead instructions and now dead phis.
+ for (auto *II : ActiveLaneMasks)
+ RecursivelyDeleteTriviallyDeadInstructions(II);
+ for (auto I : L->blocks())
+ DeleteDeadPHIs(I);
return true;
}
diff --git a/contrib/libs/llvm12/lib/Target/ARM/MVEVPTBlockPass.cpp b/contrib/libs/llvm12/lib/Target/ARM/MVEVPTBlockPass.cpp
index 89183c16ac..c7f451cba1 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/MVEVPTBlockPass.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/MVEVPTBlockPass.cpp
@@ -107,12 +107,12 @@ static bool StepOverPredicatedInstrs(MachineBasicBlock::instr_iterator &Iter,
NumInstrsSteppedOver = 0;
while (Iter != EndIter) {
- if (Iter->isDebugInstr()) {
- // Skip debug instructions
- ++Iter;
- continue;
- }
-
+ if (Iter->isDebugInstr()) {
+ // Skip debug instructions
+ ++Iter;
+ continue;
+ }
+
NextPred = getVPTInstrPredicate(*Iter, PredReg);
assert(NextPred != ARMVCC::Else &&
"VPT block pass does not expect Else preds");
@@ -176,8 +176,8 @@ CreateVPTBlock(MachineBasicBlock::instr_iterator &Iter,
LLVM_DEBUG(for (MachineBasicBlock::instr_iterator AddedInstIter =
std::next(BlockBeg);
AddedInstIter != Iter; ++AddedInstIter) {
- if (AddedInstIter->isDebugInstr())
- continue;
+ if (AddedInstIter->isDebugInstr())
+ continue;
dbgs() << " adding: ";
AddedInstIter->dump();
});
@@ -205,7 +205,7 @@ CreateVPTBlock(MachineBasicBlock::instr_iterator &Iter,
if (!IsVPRDefinedOrKilledByBlock(Iter, VPNOTBlockEndIter))
break;
- LLVM_DEBUG(dbgs() << " removing VPNOT: "; Iter->dump());
+ LLVM_DEBUG(dbgs() << " removing VPNOT: "; Iter->dump());
// Record the new size of the block
BlockSize += ElseInstCnt;
@@ -219,9 +219,9 @@ CreateVPTBlock(MachineBasicBlock::instr_iterator &Iter,
// Note that we are using "Iter" to iterate over the block so we can update
// it at the same time.
for (; Iter != VPNOTBlockEndIter; ++Iter) {
- if (Iter->isDebugInstr())
- continue;
-
+ if (Iter->isDebugInstr())
+ continue;
+
// Find the register in which the predicate is
int OpIdx = findFirstVPTPredOperandIdx(*Iter);
assert(OpIdx != -1);
@@ -281,27 +281,27 @@ bool MVEVPTBlock::InsertVPTBlocks(MachineBasicBlock &Block) {
MIBuilder.add(VCMP->getOperand(1));
MIBuilder.add(VCMP->getOperand(2));
MIBuilder.add(VCMP->getOperand(3));
-
- // We need to remove any kill flags between the original VCMP and the new
- // insertion point.
- for (MachineInstr &MII :
- make_range(VCMP->getIterator(), MI->getIterator())) {
- MII.clearRegisterKills(VCMP->getOperand(1).getReg(), TRI);
- MII.clearRegisterKills(VCMP->getOperand(2).getReg(), TRI);
- }
-
+
+ // We need to remove any kill flags between the original VCMP and the new
+ // insertion point.
+ for (MachineInstr &MII :
+ make_range(VCMP->getIterator(), MI->getIterator())) {
+ MII.clearRegisterKills(VCMP->getOperand(1).getReg(), TRI);
+ MII.clearRegisterKills(VCMP->getOperand(2).getReg(), TRI);
+ }
+
VCMP->eraseFromParent();
} else {
MIBuilder = BuildMI(Block, MI, DL, TII->get(ARM::MVE_VPST));
MIBuilder.addImm((uint64_t)BlockMask);
}
- // Erase all dead instructions (VPNOT's). Do that now so that they do not
- // mess with the bundle creation.
- for (MachineInstr *DeadMI : DeadInstructions)
- DeadMI->eraseFromParent();
- DeadInstructions.clear();
-
+ // Erase all dead instructions (VPNOT's). Do that now so that they do not
+ // mess with the bundle creation.
+ for (MachineInstr *DeadMI : DeadInstructions)
+ DeadMI->eraseFromParent();
+ DeadInstructions.clear();
+
finalizeBundle(
Block, MachineBasicBlock::instr_iterator(MIBuilder.getInstr()), MBIter);
diff --git a/contrib/libs/llvm12/lib/Target/ARM/MVEVPTOptimisationsPass.cpp b/contrib/libs/llvm12/lib/Target/ARM/MVEVPTOptimisationsPass.cpp
index 70fb8c5383..00e4449769 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/MVEVPTOptimisationsPass.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/MVEVPTOptimisationsPass.cpp
@@ -6,28 +6,28 @@
//
//===----------------------------------------------------------------------===//
//
-/// \file This pass does a few optimisations related to Tail predicated loops
-/// and MVE VPT blocks before register allocation is performed. For VPT blocks
-/// the goal is to maximize the sizes of the blocks that will be created by the
-/// MVE VPT Block Insertion pass (which runs after register allocation). For
-/// tail predicated loops we transform the loop into something that will
-/// hopefully make the backend ARMLowOverheadLoops pass's job easier.
-///
+/// \file This pass does a few optimisations related to Tail predicated loops
+/// and MVE VPT blocks before register allocation is performed. For VPT blocks
+/// the goal is to maximize the sizes of the blocks that will be created by the
+/// MVE VPT Block Insertion pass (which runs after register allocation). For
+/// tail predicated loops we transform the loop into something that will
+/// hopefully make the backend ARMLowOverheadLoops pass's job easier.
+///
//===----------------------------------------------------------------------===//
#include "ARM.h"
#include "ARMSubtarget.h"
#include "MCTargetDesc/ARMBaseInfo.h"
-#include "MVETailPredUtils.h"
+#include "MVETailPredUtils.h"
#include "Thumb2InstrInfo.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineLoopInfo.h"
-#include "llvm/InitializePasses.h"
+#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/InitializePasses.h"
#include "llvm/Support/Debug.h"
#include <cassert>
@@ -35,11 +35,11 @@ using namespace llvm;
#define DEBUG_TYPE "arm-mve-vpt-opts"
-static cl::opt<bool>
-MergeEndDec("arm-enable-merge-loopenddec", cl::Hidden,
- cl::desc("Enable merging Loop End and Dec instructions."),
- cl::init(true));
-
+static cl::opt<bool>
+MergeEndDec("arm-enable-merge-loopenddec", cl::Hidden,
+ cl::desc("Enable merging Loop End and Dec instructions."),
+ cl::init(true));
+
namespace {
class MVEVPTOptimisations : public MachineFunctionPass {
public:
@@ -51,315 +51,315 @@ public:
bool runOnMachineFunction(MachineFunction &Fn) override;
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<MachineLoopInfo>();
- AU.addPreserved<MachineLoopInfo>();
- AU.addRequired<MachineDominatorTree>();
- AU.addPreserved<MachineDominatorTree>();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
-
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<MachineLoopInfo>();
+ AU.addPreserved<MachineLoopInfo>();
+ AU.addRequired<MachineDominatorTree>();
+ AU.addPreserved<MachineDominatorTree>();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
StringRef getPassName() const override {
- return "ARM MVE TailPred and VPT Optimisation Pass";
+ return "ARM MVE TailPred and VPT Optimisation Pass";
}
private:
- bool MergeLoopEnd(MachineLoop *ML);
- bool ConvertTailPredLoop(MachineLoop *ML, MachineDominatorTree *DT);
+ bool MergeLoopEnd(MachineLoop *ML);
+ bool ConvertTailPredLoop(MachineLoop *ML, MachineDominatorTree *DT);
MachineInstr &ReplaceRegisterUseWithVPNOT(MachineBasicBlock &MBB,
MachineInstr &Instr,
MachineOperand &User,
Register Target);
bool ReduceOldVCCRValueUses(MachineBasicBlock &MBB);
bool ReplaceVCMPsByVPNOTs(MachineBasicBlock &MBB);
- bool ReplaceConstByVPNOTs(MachineBasicBlock &MBB, MachineDominatorTree *DT);
- bool ConvertVPSEL(MachineBasicBlock &MBB);
+ bool ReplaceConstByVPNOTs(MachineBasicBlock &MBB, MachineDominatorTree *DT);
+ bool ConvertVPSEL(MachineBasicBlock &MBB);
};
char MVEVPTOptimisations::ID = 0;
} // end anonymous namespace
-INITIALIZE_PASS_BEGIN(MVEVPTOptimisations, DEBUG_TYPE,
- "ARM MVE TailPred and VPT Optimisations pass", false,
- false)
-INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
-INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
-INITIALIZE_PASS_END(MVEVPTOptimisations, DEBUG_TYPE,
- "ARM MVE TailPred and VPT Optimisations pass", false, false)
-
-static MachineInstr *LookThroughCOPY(MachineInstr *MI,
- MachineRegisterInfo *MRI) {
- while (MI && MI->getOpcode() == TargetOpcode::COPY &&
- MI->getOperand(1).getReg().isVirtual())
- MI = MRI->getVRegDef(MI->getOperand(1).getReg());
- return MI;
-}
-
-// Given a loop ML, this attempts to find the t2LoopEnd, t2LoopDec and
-// corresponding PHI that make up a low overhead loop. Only handles 'do' loops
-// at the moment, returning a t2DoLoopStart in LoopStart.
-static bool findLoopComponents(MachineLoop *ML, MachineRegisterInfo *MRI,
- MachineInstr *&LoopStart, MachineInstr *&LoopPhi,
- MachineInstr *&LoopDec, MachineInstr *&LoopEnd) {
- MachineBasicBlock *Header = ML->getHeader();
- MachineBasicBlock *Latch = ML->getLoopLatch();
- if (!Header || !Latch) {
- LLVM_DEBUG(dbgs() << " no Loop Latch or Header\n");
- return false;
- }
-
- // Find the loop end from the terminators.
- LoopEnd = nullptr;
- for (auto &T : Latch->terminators()) {
- if (T.getOpcode() == ARM::t2LoopEnd && T.getOperand(1).getMBB() == Header) {
- LoopEnd = &T;
- break;
- }
- if (T.getOpcode() == ARM::t2LoopEndDec &&
- T.getOperand(2).getMBB() == Header) {
- LoopEnd = &T;
- break;
- }
- }
- if (!LoopEnd) {
- LLVM_DEBUG(dbgs() << " no LoopEnd\n");
- return false;
- }
- LLVM_DEBUG(dbgs() << " found loop end: " << *LoopEnd);
-
- // Find the dec from the use of the end. There may be copies between
- // instructions. We expect the loop to loop like:
- // $vs = t2DoLoopStart ...
- // loop:
- // $vp = phi [ $vs ], [ $vd ]
- // ...
- // $vd = t2LoopDec $vp
- // ...
- // t2LoopEnd $vd, loop
- if (LoopEnd->getOpcode() == ARM::t2LoopEndDec)
- LoopDec = LoopEnd;
- else {
- LoopDec =
- LookThroughCOPY(MRI->getVRegDef(LoopEnd->getOperand(0).getReg()), MRI);
- if (!LoopDec || LoopDec->getOpcode() != ARM::t2LoopDec) {
- LLVM_DEBUG(dbgs() << " didn't find LoopDec where we expected!\n");
- return false;
- }
- }
- LLVM_DEBUG(dbgs() << " found loop dec: " << *LoopDec);
-
- LoopPhi =
- LookThroughCOPY(MRI->getVRegDef(LoopDec->getOperand(1).getReg()), MRI);
- if (!LoopPhi || LoopPhi->getOpcode() != TargetOpcode::PHI ||
- LoopPhi->getNumOperands() != 5 ||
- (LoopPhi->getOperand(2).getMBB() != Latch &&
- LoopPhi->getOperand(4).getMBB() != Latch)) {
- LLVM_DEBUG(dbgs() << " didn't find PHI where we expected!\n");
- return false;
- }
- LLVM_DEBUG(dbgs() << " found loop phi: " << *LoopPhi);
-
- Register StartReg = LoopPhi->getOperand(2).getMBB() == Latch
- ? LoopPhi->getOperand(3).getReg()
- : LoopPhi->getOperand(1).getReg();
- LoopStart = LookThroughCOPY(MRI->getVRegDef(StartReg), MRI);
- if (!LoopStart || LoopStart->getOpcode() != ARM::t2DoLoopStart) {
- LLVM_DEBUG(dbgs() << " didn't find Start where we expected!\n");
- return false;
- }
- LLVM_DEBUG(dbgs() << " found loop start: " << *LoopStart);
-
- return true;
-}
-
-// This function converts loops with t2LoopEnd and t2LoopEnd instructions into
-// a single t2LoopEndDec instruction. To do that it needs to make sure that LR
-// will be valid to be used for the low overhead loop, which means nothing else
-// is using LR (especially calls) and there are no superfluous copies in the
-// loop. The t2LoopEndDec is a branching terminator that produces a value (the
-// decrement) around the loop edge, which means we need to be careful that they
-// will be valid to allocate without any spilling.
-bool MVEVPTOptimisations::MergeLoopEnd(MachineLoop *ML) {
- if (!MergeEndDec)
- return false;
-
- LLVM_DEBUG(dbgs() << "MergeLoopEnd on loop " << ML->getHeader()->getName()
- << "\n");
-
- MachineInstr *LoopEnd, *LoopPhi, *LoopStart, *LoopDec;
- if (!findLoopComponents(ML, MRI, LoopStart, LoopPhi, LoopDec, LoopEnd))
- return false;
-
- // Check if there is an illegal instruction (a call) in the low overhead loop
- // and if so revert it now before we get any further.
- for (MachineBasicBlock *MBB : ML->blocks()) {
- for (MachineInstr &MI : *MBB) {
- if (MI.isCall()) {
- LLVM_DEBUG(dbgs() << "Found call in loop, reverting: " << MI);
- RevertDoLoopStart(LoopStart, TII);
- RevertLoopDec(LoopDec, TII);
- RevertLoopEnd(LoopEnd, TII);
- return true;
- }
- }
- }
-
- // Remove any copies from the loop, to ensure the phi that remains is both
- // simpler and contains no extra uses. Because t2LoopEndDec is a terminator
- // that cannot spill, we need to be careful what remains in the loop.
- Register PhiReg = LoopPhi->getOperand(0).getReg();
- Register DecReg = LoopDec->getOperand(0).getReg();
- Register StartReg = LoopStart->getOperand(0).getReg();
- // Ensure the uses are expected, and collect any copies we want to remove.
- SmallVector<MachineInstr *, 4> Copies;
- auto CheckUsers = [&Copies](Register BaseReg,
- ArrayRef<MachineInstr *> ExpectedUsers,
- MachineRegisterInfo *MRI) {
- SmallVector<Register, 4> Worklist;
- Worklist.push_back(BaseReg);
- while (!Worklist.empty()) {
- Register Reg = Worklist.pop_back_val();
- for (MachineInstr &MI : MRI->use_nodbg_instructions(Reg)) {
- if (count(ExpectedUsers, &MI))
- continue;
- if (MI.getOpcode() != TargetOpcode::COPY ||
- !MI.getOperand(0).getReg().isVirtual()) {
- LLVM_DEBUG(dbgs() << "Extra users of register found: " << MI);
- return false;
- }
- Worklist.push_back(MI.getOperand(0).getReg());
- Copies.push_back(&MI);
- }
- }
- return true;
- };
- if (!CheckUsers(PhiReg, {LoopDec}, MRI) ||
- !CheckUsers(DecReg, {LoopPhi, LoopEnd}, MRI) ||
- !CheckUsers(StartReg, {LoopPhi}, MRI))
- return false;
-
- MRI->constrainRegClass(StartReg, &ARM::GPRlrRegClass);
- MRI->constrainRegClass(PhiReg, &ARM::GPRlrRegClass);
- MRI->constrainRegClass(DecReg, &ARM::GPRlrRegClass);
-
- if (LoopPhi->getOperand(2).getMBB() == ML->getLoopLatch()) {
- LoopPhi->getOperand(3).setReg(StartReg);
- LoopPhi->getOperand(1).setReg(DecReg);
- } else {
- LoopPhi->getOperand(1).setReg(StartReg);
- LoopPhi->getOperand(3).setReg(DecReg);
- }
-
- // Replace the loop dec and loop end as a single instruction.
- MachineInstrBuilder MI =
- BuildMI(*LoopEnd->getParent(), *LoopEnd, LoopEnd->getDebugLoc(),
- TII->get(ARM::t2LoopEndDec), DecReg)
- .addReg(PhiReg)
- .add(LoopEnd->getOperand(1));
- (void)MI;
- LLVM_DEBUG(dbgs() << "Merged LoopDec and End into: " << *MI.getInstr());
-
- LoopDec->eraseFromParent();
- LoopEnd->eraseFromParent();
- for (auto *MI : Copies)
- MI->eraseFromParent();
- return true;
-}
-
-// Convert t2DoLoopStart to t2DoLoopStartTP if the loop contains VCTP
-// instructions. This keeps the VCTP count reg operand on the t2DoLoopStartTP
-// instruction, making the backend ARMLowOverheadLoops passes job of finding the
-// VCTP operand much simpler.
-bool MVEVPTOptimisations::ConvertTailPredLoop(MachineLoop *ML,
- MachineDominatorTree *DT) {
- LLVM_DEBUG(dbgs() << "ConvertTailPredLoop on loop "
- << ML->getHeader()->getName() << "\n");
-
- // Find some loop components including the LoopEnd/Dec/Start, and any VCTP's
- // in the loop.
- MachineInstr *LoopEnd, *LoopPhi, *LoopStart, *LoopDec;
- if (!findLoopComponents(ML, MRI, LoopStart, LoopPhi, LoopDec, LoopEnd))
- return false;
- if (LoopDec != LoopEnd)
- return false;
-
- SmallVector<MachineInstr *, 4> VCTPs;
- for (MachineBasicBlock *BB : ML->blocks())
- for (MachineInstr &MI : *BB)
- if (isVCTP(&MI))
- VCTPs.push_back(&MI);
-
- if (VCTPs.empty()) {
- LLVM_DEBUG(dbgs() << " no VCTPs\n");
- return false;
- }
-
- // Check all VCTPs are the same.
- MachineInstr *FirstVCTP = *VCTPs.begin();
- for (MachineInstr *VCTP : VCTPs) {
- LLVM_DEBUG(dbgs() << " with VCTP " << *VCTP);
- if (VCTP->getOpcode() != FirstVCTP->getOpcode() ||
- VCTP->getOperand(0).getReg() != FirstVCTP->getOperand(0).getReg()) {
- LLVM_DEBUG(dbgs() << " VCTP's are not identical\n");
- return false;
- }
- }
-
- // Check for the register being used can be setup before the loop. We expect
- // this to be:
- // $vx = ...
- // loop:
- // $vp = PHI [ $vx ], [ $vd ]
- // ..
- // $vpr = VCTP $vp
- // ..
- // $vd = t2SUBri $vp, #n
- // ..
- Register CountReg = FirstVCTP->getOperand(1).getReg();
- if (!CountReg.isVirtual()) {
- LLVM_DEBUG(dbgs() << " cannot determine VCTP PHI\n");
- return false;
- }
- MachineInstr *Phi = LookThroughCOPY(MRI->getVRegDef(CountReg), MRI);
- if (!Phi || Phi->getOpcode() != TargetOpcode::PHI ||
- Phi->getNumOperands() != 5 ||
- (Phi->getOperand(2).getMBB() != ML->getLoopLatch() &&
- Phi->getOperand(4).getMBB() != ML->getLoopLatch())) {
- LLVM_DEBUG(dbgs() << " cannot determine VCTP Count\n");
- return false;
- }
- CountReg = Phi->getOperand(2).getMBB() == ML->getLoopLatch()
- ? Phi->getOperand(3).getReg()
- : Phi->getOperand(1).getReg();
-
- // Replace the t2DoLoopStart with the t2DoLoopStartTP, move it to the end of
- // the preheader and add the new CountReg to it. We attempt to place it late
- // in the preheader, but may need to move that earlier based on uses.
- MachineBasicBlock *MBB = LoopStart->getParent();
- MachineBasicBlock::iterator InsertPt = MBB->getFirstTerminator();
- for (MachineInstr &Use :
- MRI->use_instructions(LoopStart->getOperand(0).getReg()))
- if ((InsertPt != MBB->end() && !DT->dominates(&*InsertPt, &Use)) ||
- !DT->dominates(ML->getHeader(), Use.getParent())) {
- LLVM_DEBUG(dbgs() << " InsertPt could not be a terminator!\n");
- return false;
- }
-
- MachineInstrBuilder MI = BuildMI(*MBB, InsertPt, LoopStart->getDebugLoc(),
- TII->get(ARM::t2DoLoopStartTP))
- .add(LoopStart->getOperand(0))
- .add(LoopStart->getOperand(1))
- .addReg(CountReg);
- (void)MI;
- LLVM_DEBUG(dbgs() << "Replacing " << *LoopStart << " with "
- << *MI.getInstr());
- MRI->constrainRegClass(CountReg, &ARM::rGPRRegClass);
- LoopStart->eraseFromParent();
-
- return true;
-}
-
+INITIALIZE_PASS_BEGIN(MVEVPTOptimisations, DEBUG_TYPE,
+ "ARM MVE TailPred and VPT Optimisations pass", false,
+ false)
+INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
+INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
+INITIALIZE_PASS_END(MVEVPTOptimisations, DEBUG_TYPE,
+ "ARM MVE TailPred and VPT Optimisations pass", false, false)
+
+static MachineInstr *LookThroughCOPY(MachineInstr *MI,
+ MachineRegisterInfo *MRI) {
+ while (MI && MI->getOpcode() == TargetOpcode::COPY &&
+ MI->getOperand(1).getReg().isVirtual())
+ MI = MRI->getVRegDef(MI->getOperand(1).getReg());
+ return MI;
+}
+
+// Given a loop ML, this attempts to find the t2LoopEnd, t2LoopDec and
+// corresponding PHI that make up a low overhead loop. Only handles 'do' loops
+// at the moment, returning a t2DoLoopStart in LoopStart.
+static bool findLoopComponents(MachineLoop *ML, MachineRegisterInfo *MRI,
+ MachineInstr *&LoopStart, MachineInstr *&LoopPhi,
+ MachineInstr *&LoopDec, MachineInstr *&LoopEnd) {
+ MachineBasicBlock *Header = ML->getHeader();
+ MachineBasicBlock *Latch = ML->getLoopLatch();
+ if (!Header || !Latch) {
+ LLVM_DEBUG(dbgs() << " no Loop Latch or Header\n");
+ return false;
+ }
+
+ // Find the loop end from the terminators.
+ LoopEnd = nullptr;
+ for (auto &T : Latch->terminators()) {
+ if (T.getOpcode() == ARM::t2LoopEnd && T.getOperand(1).getMBB() == Header) {
+ LoopEnd = &T;
+ break;
+ }
+ if (T.getOpcode() == ARM::t2LoopEndDec &&
+ T.getOperand(2).getMBB() == Header) {
+ LoopEnd = &T;
+ break;
+ }
+ }
+ if (!LoopEnd) {
+ LLVM_DEBUG(dbgs() << " no LoopEnd\n");
+ return false;
+ }
+ LLVM_DEBUG(dbgs() << " found loop end: " << *LoopEnd);
+
+ // Find the dec from the use of the end. There may be copies between
+ // instructions. We expect the loop to loop like:
+ // $vs = t2DoLoopStart ...
+ // loop:
+ // $vp = phi [ $vs ], [ $vd ]
+ // ...
+ // $vd = t2LoopDec $vp
+ // ...
+ // t2LoopEnd $vd, loop
+ if (LoopEnd->getOpcode() == ARM::t2LoopEndDec)
+ LoopDec = LoopEnd;
+ else {
+ LoopDec =
+ LookThroughCOPY(MRI->getVRegDef(LoopEnd->getOperand(0).getReg()), MRI);
+ if (!LoopDec || LoopDec->getOpcode() != ARM::t2LoopDec) {
+ LLVM_DEBUG(dbgs() << " didn't find LoopDec where we expected!\n");
+ return false;
+ }
+ }
+ LLVM_DEBUG(dbgs() << " found loop dec: " << *LoopDec);
+
+ LoopPhi =
+ LookThroughCOPY(MRI->getVRegDef(LoopDec->getOperand(1).getReg()), MRI);
+ if (!LoopPhi || LoopPhi->getOpcode() != TargetOpcode::PHI ||
+ LoopPhi->getNumOperands() != 5 ||
+ (LoopPhi->getOperand(2).getMBB() != Latch &&
+ LoopPhi->getOperand(4).getMBB() != Latch)) {
+ LLVM_DEBUG(dbgs() << " didn't find PHI where we expected!\n");
+ return false;
+ }
+ LLVM_DEBUG(dbgs() << " found loop phi: " << *LoopPhi);
+
+ Register StartReg = LoopPhi->getOperand(2).getMBB() == Latch
+ ? LoopPhi->getOperand(3).getReg()
+ : LoopPhi->getOperand(1).getReg();
+ LoopStart = LookThroughCOPY(MRI->getVRegDef(StartReg), MRI);
+ if (!LoopStart || LoopStart->getOpcode() != ARM::t2DoLoopStart) {
+ LLVM_DEBUG(dbgs() << " didn't find Start where we expected!\n");
+ return false;
+ }
+ LLVM_DEBUG(dbgs() << " found loop start: " << *LoopStart);
+
+ return true;
+}
+
+// This function converts loops with t2LoopEnd and t2LoopEnd instructions into
+// a single t2LoopEndDec instruction. To do that it needs to make sure that LR
+// will be valid to be used for the low overhead loop, which means nothing else
+// is using LR (especially calls) and there are no superfluous copies in the
+// loop. The t2LoopEndDec is a branching terminator that produces a value (the
+// decrement) around the loop edge, which means we need to be careful that they
+// will be valid to allocate without any spilling.
+bool MVEVPTOptimisations::MergeLoopEnd(MachineLoop *ML) {
+ if (!MergeEndDec)
+ return false;
+
+ LLVM_DEBUG(dbgs() << "MergeLoopEnd on loop " << ML->getHeader()->getName()
+ << "\n");
+
+ MachineInstr *LoopEnd, *LoopPhi, *LoopStart, *LoopDec;
+ if (!findLoopComponents(ML, MRI, LoopStart, LoopPhi, LoopDec, LoopEnd))
+ return false;
+
+ // Check if there is an illegal instruction (a call) in the low overhead loop
+ // and if so revert it now before we get any further.
+ for (MachineBasicBlock *MBB : ML->blocks()) {
+ for (MachineInstr &MI : *MBB) {
+ if (MI.isCall()) {
+ LLVM_DEBUG(dbgs() << "Found call in loop, reverting: " << MI);
+ RevertDoLoopStart(LoopStart, TII);
+ RevertLoopDec(LoopDec, TII);
+ RevertLoopEnd(LoopEnd, TII);
+ return true;
+ }
+ }
+ }
+
+ // Remove any copies from the loop, to ensure the phi that remains is both
+ // simpler and contains no extra uses. Because t2LoopEndDec is a terminator
+ // that cannot spill, we need to be careful what remains in the loop.
+ Register PhiReg = LoopPhi->getOperand(0).getReg();
+ Register DecReg = LoopDec->getOperand(0).getReg();
+ Register StartReg = LoopStart->getOperand(0).getReg();
+ // Ensure the uses are expected, and collect any copies we want to remove.
+ SmallVector<MachineInstr *, 4> Copies;
+ auto CheckUsers = [&Copies](Register BaseReg,
+ ArrayRef<MachineInstr *> ExpectedUsers,
+ MachineRegisterInfo *MRI) {
+ SmallVector<Register, 4> Worklist;
+ Worklist.push_back(BaseReg);
+ while (!Worklist.empty()) {
+ Register Reg = Worklist.pop_back_val();
+ for (MachineInstr &MI : MRI->use_nodbg_instructions(Reg)) {
+ if (count(ExpectedUsers, &MI))
+ continue;
+ if (MI.getOpcode() != TargetOpcode::COPY ||
+ !MI.getOperand(0).getReg().isVirtual()) {
+ LLVM_DEBUG(dbgs() << "Extra users of register found: " << MI);
+ return false;
+ }
+ Worklist.push_back(MI.getOperand(0).getReg());
+ Copies.push_back(&MI);
+ }
+ }
+ return true;
+ };
+ if (!CheckUsers(PhiReg, {LoopDec}, MRI) ||
+ !CheckUsers(DecReg, {LoopPhi, LoopEnd}, MRI) ||
+ !CheckUsers(StartReg, {LoopPhi}, MRI))
+ return false;
+
+ MRI->constrainRegClass(StartReg, &ARM::GPRlrRegClass);
+ MRI->constrainRegClass(PhiReg, &ARM::GPRlrRegClass);
+ MRI->constrainRegClass(DecReg, &ARM::GPRlrRegClass);
+
+ if (LoopPhi->getOperand(2).getMBB() == ML->getLoopLatch()) {
+ LoopPhi->getOperand(3).setReg(StartReg);
+ LoopPhi->getOperand(1).setReg(DecReg);
+ } else {
+ LoopPhi->getOperand(1).setReg(StartReg);
+ LoopPhi->getOperand(3).setReg(DecReg);
+ }
+
+ // Replace the loop dec and loop end as a single instruction.
+ MachineInstrBuilder MI =
+ BuildMI(*LoopEnd->getParent(), *LoopEnd, LoopEnd->getDebugLoc(),
+ TII->get(ARM::t2LoopEndDec), DecReg)
+ .addReg(PhiReg)
+ .add(LoopEnd->getOperand(1));
+ (void)MI;
+ LLVM_DEBUG(dbgs() << "Merged LoopDec and End into: " << *MI.getInstr());
+
+ LoopDec->eraseFromParent();
+ LoopEnd->eraseFromParent();
+ for (auto *MI : Copies)
+ MI->eraseFromParent();
+ return true;
+}
+
+// Convert t2DoLoopStart to t2DoLoopStartTP if the loop contains VCTP
+// instructions. This keeps the VCTP count reg operand on the t2DoLoopStartTP
+// instruction, making the backend ARMLowOverheadLoops passes job of finding the
+// VCTP operand much simpler.
+bool MVEVPTOptimisations::ConvertTailPredLoop(MachineLoop *ML,
+ MachineDominatorTree *DT) {
+ LLVM_DEBUG(dbgs() << "ConvertTailPredLoop on loop "
+ << ML->getHeader()->getName() << "\n");
+
+ // Find some loop components including the LoopEnd/Dec/Start, and any VCTP's
+ // in the loop.
+ MachineInstr *LoopEnd, *LoopPhi, *LoopStart, *LoopDec;
+ if (!findLoopComponents(ML, MRI, LoopStart, LoopPhi, LoopDec, LoopEnd))
+ return false;
+ if (LoopDec != LoopEnd)
+ return false;
+
+ SmallVector<MachineInstr *, 4> VCTPs;
+ for (MachineBasicBlock *BB : ML->blocks())
+ for (MachineInstr &MI : *BB)
+ if (isVCTP(&MI))
+ VCTPs.push_back(&MI);
+
+ if (VCTPs.empty()) {
+ LLVM_DEBUG(dbgs() << " no VCTPs\n");
+ return false;
+ }
+
+ // Check all VCTPs are the same.
+ MachineInstr *FirstVCTP = *VCTPs.begin();
+ for (MachineInstr *VCTP : VCTPs) {
+ LLVM_DEBUG(dbgs() << " with VCTP " << *VCTP);
+ if (VCTP->getOpcode() != FirstVCTP->getOpcode() ||
+ VCTP->getOperand(0).getReg() != FirstVCTP->getOperand(0).getReg()) {
+ LLVM_DEBUG(dbgs() << " VCTP's are not identical\n");
+ return false;
+ }
+ }
+
+ // Check for the register being used can be setup before the loop. We expect
+ // this to be:
+ // $vx = ...
+ // loop:
+ // $vp = PHI [ $vx ], [ $vd ]
+ // ..
+ // $vpr = VCTP $vp
+ // ..
+ // $vd = t2SUBri $vp, #n
+ // ..
+ Register CountReg = FirstVCTP->getOperand(1).getReg();
+ if (!CountReg.isVirtual()) {
+ LLVM_DEBUG(dbgs() << " cannot determine VCTP PHI\n");
+ return false;
+ }
+ MachineInstr *Phi = LookThroughCOPY(MRI->getVRegDef(CountReg), MRI);
+ if (!Phi || Phi->getOpcode() != TargetOpcode::PHI ||
+ Phi->getNumOperands() != 5 ||
+ (Phi->getOperand(2).getMBB() != ML->getLoopLatch() &&
+ Phi->getOperand(4).getMBB() != ML->getLoopLatch())) {
+ LLVM_DEBUG(dbgs() << " cannot determine VCTP Count\n");
+ return false;
+ }
+ CountReg = Phi->getOperand(2).getMBB() == ML->getLoopLatch()
+ ? Phi->getOperand(3).getReg()
+ : Phi->getOperand(1).getReg();
+
+ // Replace the t2DoLoopStart with the t2DoLoopStartTP, move it to the end of
+ // the preheader and add the new CountReg to it. We attempt to place it late
+ // in the preheader, but may need to move that earlier based on uses.
+ MachineBasicBlock *MBB = LoopStart->getParent();
+ MachineBasicBlock::iterator InsertPt = MBB->getFirstTerminator();
+ for (MachineInstr &Use :
+ MRI->use_instructions(LoopStart->getOperand(0).getReg()))
+ if ((InsertPt != MBB->end() && !DT->dominates(&*InsertPt, &Use)) ||
+ !DT->dominates(ML->getHeader(), Use.getParent())) {
+ LLVM_DEBUG(dbgs() << " InsertPt could not be a terminator!\n");
+ return false;
+ }
+
+ MachineInstrBuilder MI = BuildMI(*MBB, InsertPt, LoopStart->getDebugLoc(),
+ TII->get(ARM::t2DoLoopStartTP))
+ .add(LoopStart->getOperand(0))
+ .add(LoopStart->getOperand(1))
+ .addReg(CountReg);
+ (void)MI;
+ LLVM_DEBUG(dbgs() << "Replacing " << *LoopStart << " with "
+ << *MI.getInstr());
+ MRI->constrainRegClass(CountReg, &ARM::rGPRRegClass);
+ LoopStart->eraseFromParent();
+
+ return true;
+}
+
// Returns true if Opcode is any VCMP Opcode.
static bool IsVCMP(unsigned Opcode) { return VCMPOpcodeToVPT(Opcode) != 0; }
@@ -650,7 +650,7 @@ bool MVEVPTOptimisations::ReduceOldVCCRValueUses(MachineBasicBlock &MBB) {
}
for (MachineInstr *DeadInstruction : DeadInstructions)
- DeadInstruction->eraseFromParent();
+ DeadInstruction->eraseFromParent();
return Modified;
}
@@ -724,160 +724,160 @@ bool MVEVPTOptimisations::ReplaceVCMPsByVPNOTs(MachineBasicBlock &MBB) {
}
for (MachineInstr *DeadInstruction : DeadInstructions)
- DeadInstruction->eraseFromParent();
+ DeadInstruction->eraseFromParent();
+
+ return !DeadInstructions.empty();
+}
+
+bool MVEVPTOptimisations::ReplaceConstByVPNOTs(MachineBasicBlock &MBB,
+ MachineDominatorTree *DT) {
+ // Scan through the block, looking for instructions that use constants moves
+ // into VPR that are the negative of one another. These are expected to be
+ // COPY's to VCCRRegClass, from a t2MOVi or t2MOVi16. The last seen constant
+ // mask is kept it or and VPNOT's of it are added or reused as we scan through
+ // the function.
+ unsigned LastVPTImm = 0;
+ Register LastVPTReg = 0;
+ SmallSet<MachineInstr *, 4> DeadInstructions;
+
+ for (MachineInstr &Instr : MBB.instrs()) {
+ // Look for predicated MVE instructions.
+ int PIdx = llvm::findFirstVPTPredOperandIdx(Instr);
+ if (PIdx == -1)
+ continue;
+ Register VPR = Instr.getOperand(PIdx + 1).getReg();
+ if (!VPR.isVirtual())
+ continue;
+
+ // From that we are looking for an instruction like %11:vccr = COPY %9:rgpr.
+ MachineInstr *Copy = MRI->getVRegDef(VPR);
+ if (!Copy || Copy->getOpcode() != TargetOpcode::COPY ||
+ !Copy->getOperand(1).getReg().isVirtual() ||
+ MRI->getRegClass(Copy->getOperand(1).getReg()) == &ARM::VCCRRegClass) {
+ LastVPTReg = 0;
+ continue;
+ }
+ Register GPR = Copy->getOperand(1).getReg();
+
+ // Find the Immediate used by the copy.
+ auto getImm = [&](Register GPR) -> unsigned {
+ MachineInstr *Def = MRI->getVRegDef(GPR);
+ if (Def && (Def->getOpcode() == ARM::t2MOVi ||
+ Def->getOpcode() == ARM::t2MOVi16))
+ return Def->getOperand(1).getImm();
+ return -1U;
+ };
+ unsigned Imm = getImm(GPR);
+ if (Imm == -1U) {
+ LastVPTReg = 0;
+ continue;
+ }
+
+ unsigned NotImm = ~Imm & 0xffff;
+ if (LastVPTReg != 0 && LastVPTReg != VPR && LastVPTImm == Imm) {
+ Instr.getOperand(PIdx + 1).setReg(LastVPTReg);
+ if (MRI->use_empty(VPR)) {
+ DeadInstructions.insert(Copy);
+ if (MRI->hasOneUse(GPR))
+ DeadInstructions.insert(MRI->getVRegDef(GPR));
+ }
+ LLVM_DEBUG(dbgs() << "Reusing predicate: in " << Instr);
+ } else if (LastVPTReg != 0 && LastVPTImm == NotImm) {
+ // We have found the not of a previous constant. Create a VPNot of the
+ // earlier predicate reg and use it instead of the copy.
+ Register NewVPR = MRI->createVirtualRegister(&ARM::VCCRRegClass);
+ auto VPNot = BuildMI(MBB, &Instr, Instr.getDebugLoc(),
+ TII->get(ARM::MVE_VPNOT), NewVPR)
+ .addReg(LastVPTReg);
+ addUnpredicatedMveVpredNOp(VPNot);
+
+ // Use the new register and check if the def is now dead.
+ Instr.getOperand(PIdx + 1).setReg(NewVPR);
+ if (MRI->use_empty(VPR)) {
+ DeadInstructions.insert(Copy);
+ if (MRI->hasOneUse(GPR))
+ DeadInstructions.insert(MRI->getVRegDef(GPR));
+ }
+ LLVM_DEBUG(dbgs() << "Adding VPNot: " << *VPNot << " to replace use at "
+ << Instr);
+ VPR = NewVPR;
+ }
+
+ LastVPTImm = Imm;
+ LastVPTReg = VPR;
+ }
+
+ for (MachineInstr *DI : DeadInstructions)
+ DI->eraseFromParent();
+
+ return !DeadInstructions.empty();
+}
+
+// Replace VPSEL with a predicated VMOV in blocks with a VCTP. This is a
+// somewhat blunt approximation to allow tail predicated with vpsel
+// instructions. We turn a vselect into a VPSEL in ISEL, but they have slightly
+// different semantics under tail predication. Until that is modelled we just
+// convert to a VMOVT (via a predicated VORR) instead.
+bool MVEVPTOptimisations::ConvertVPSEL(MachineBasicBlock &MBB) {
+ bool HasVCTP = false;
+ SmallVector<MachineInstr *, 4> DeadInstructions;
+
+ for (MachineInstr &MI : MBB.instrs()) {
+ if (isVCTP(&MI)) {
+ HasVCTP = true;
+ continue;
+ }
+
+ if (!HasVCTP || MI.getOpcode() != ARM::MVE_VPSEL)
+ continue;
+
+ MachineInstrBuilder MIBuilder =
+ BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(ARM::MVE_VORR))
+ .add(MI.getOperand(0))
+ .add(MI.getOperand(1))
+ .add(MI.getOperand(1))
+ .addImm(ARMVCC::Then)
+ .add(MI.getOperand(4))
+ .add(MI.getOperand(2));
+ // Silence unused variable warning in release builds.
+ (void)MIBuilder;
+ LLVM_DEBUG(dbgs() << "Replacing VPSEL: "; MI.dump();
+ dbgs() << " with VMOVT: "; MIBuilder.getInstr()->dump());
+ DeadInstructions.push_back(&MI);
+ }
+
+ for (MachineInstr *DeadInstruction : DeadInstructions)
+ DeadInstruction->eraseFromParent();
return !DeadInstructions.empty();
}
-bool MVEVPTOptimisations::ReplaceConstByVPNOTs(MachineBasicBlock &MBB,
- MachineDominatorTree *DT) {
- // Scan through the block, looking for instructions that use constants moves
- // into VPR that are the negative of one another. These are expected to be
- // COPY's to VCCRRegClass, from a t2MOVi or t2MOVi16. The last seen constant
- // mask is kept it or and VPNOT's of it are added or reused as we scan through
- // the function.
- unsigned LastVPTImm = 0;
- Register LastVPTReg = 0;
- SmallSet<MachineInstr *, 4> DeadInstructions;
-
- for (MachineInstr &Instr : MBB.instrs()) {
- // Look for predicated MVE instructions.
- int PIdx = llvm::findFirstVPTPredOperandIdx(Instr);
- if (PIdx == -1)
- continue;
- Register VPR = Instr.getOperand(PIdx + 1).getReg();
- if (!VPR.isVirtual())
- continue;
-
- // From that we are looking for an instruction like %11:vccr = COPY %9:rgpr.
- MachineInstr *Copy = MRI->getVRegDef(VPR);
- if (!Copy || Copy->getOpcode() != TargetOpcode::COPY ||
- !Copy->getOperand(1).getReg().isVirtual() ||
- MRI->getRegClass(Copy->getOperand(1).getReg()) == &ARM::VCCRRegClass) {
- LastVPTReg = 0;
- continue;
- }
- Register GPR = Copy->getOperand(1).getReg();
-
- // Find the Immediate used by the copy.
- auto getImm = [&](Register GPR) -> unsigned {
- MachineInstr *Def = MRI->getVRegDef(GPR);
- if (Def && (Def->getOpcode() == ARM::t2MOVi ||
- Def->getOpcode() == ARM::t2MOVi16))
- return Def->getOperand(1).getImm();
- return -1U;
- };
- unsigned Imm = getImm(GPR);
- if (Imm == -1U) {
- LastVPTReg = 0;
- continue;
- }
-
- unsigned NotImm = ~Imm & 0xffff;
- if (LastVPTReg != 0 && LastVPTReg != VPR && LastVPTImm == Imm) {
- Instr.getOperand(PIdx + 1).setReg(LastVPTReg);
- if (MRI->use_empty(VPR)) {
- DeadInstructions.insert(Copy);
- if (MRI->hasOneUse(GPR))
- DeadInstructions.insert(MRI->getVRegDef(GPR));
- }
- LLVM_DEBUG(dbgs() << "Reusing predicate: in " << Instr);
- } else if (LastVPTReg != 0 && LastVPTImm == NotImm) {
- // We have found the not of a previous constant. Create a VPNot of the
- // earlier predicate reg and use it instead of the copy.
- Register NewVPR = MRI->createVirtualRegister(&ARM::VCCRRegClass);
- auto VPNot = BuildMI(MBB, &Instr, Instr.getDebugLoc(),
- TII->get(ARM::MVE_VPNOT), NewVPR)
- .addReg(LastVPTReg);
- addUnpredicatedMveVpredNOp(VPNot);
-
- // Use the new register and check if the def is now dead.
- Instr.getOperand(PIdx + 1).setReg(NewVPR);
- if (MRI->use_empty(VPR)) {
- DeadInstructions.insert(Copy);
- if (MRI->hasOneUse(GPR))
- DeadInstructions.insert(MRI->getVRegDef(GPR));
- }
- LLVM_DEBUG(dbgs() << "Adding VPNot: " << *VPNot << " to replace use at "
- << Instr);
- VPR = NewVPR;
- }
-
- LastVPTImm = Imm;
- LastVPTReg = VPR;
- }
-
- for (MachineInstr *DI : DeadInstructions)
- DI->eraseFromParent();
-
- return !DeadInstructions.empty();
-}
-
-// Replace VPSEL with a predicated VMOV in blocks with a VCTP. This is a
-// somewhat blunt approximation to allow tail predicated with vpsel
-// instructions. We turn a vselect into a VPSEL in ISEL, but they have slightly
-// different semantics under tail predication. Until that is modelled we just
-// convert to a VMOVT (via a predicated VORR) instead.
-bool MVEVPTOptimisations::ConvertVPSEL(MachineBasicBlock &MBB) {
- bool HasVCTP = false;
- SmallVector<MachineInstr *, 4> DeadInstructions;
-
- for (MachineInstr &MI : MBB.instrs()) {
- if (isVCTP(&MI)) {
- HasVCTP = true;
- continue;
- }
-
- if (!HasVCTP || MI.getOpcode() != ARM::MVE_VPSEL)
- continue;
-
- MachineInstrBuilder MIBuilder =
- BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(ARM::MVE_VORR))
- .add(MI.getOperand(0))
- .add(MI.getOperand(1))
- .add(MI.getOperand(1))
- .addImm(ARMVCC::Then)
- .add(MI.getOperand(4))
- .add(MI.getOperand(2));
- // Silence unused variable warning in release builds.
- (void)MIBuilder;
- LLVM_DEBUG(dbgs() << "Replacing VPSEL: "; MI.dump();
- dbgs() << " with VMOVT: "; MIBuilder.getInstr()->dump());
- DeadInstructions.push_back(&MI);
- }
-
- for (MachineInstr *DeadInstruction : DeadInstructions)
- DeadInstruction->eraseFromParent();
-
- return !DeadInstructions.empty();
-}
-
bool MVEVPTOptimisations::runOnMachineFunction(MachineFunction &Fn) {
const ARMSubtarget &STI =
static_cast<const ARMSubtarget &>(Fn.getSubtarget());
- if (!STI.isThumb2() || !STI.hasLOB())
+ if (!STI.isThumb2() || !STI.hasLOB())
return false;
TII = static_cast<const Thumb2InstrInfo *>(STI.getInstrInfo());
MRI = &Fn.getRegInfo();
- MachineLoopInfo *MLI = &getAnalysis<MachineLoopInfo>();
- MachineDominatorTree *DT = &getAnalysis<MachineDominatorTree>();
+ MachineLoopInfo *MLI = &getAnalysis<MachineLoopInfo>();
+ MachineDominatorTree *DT = &getAnalysis<MachineDominatorTree>();
LLVM_DEBUG(dbgs() << "********** ARM MVE VPT Optimisations **********\n"
<< "********** Function: " << Fn.getName() << '\n');
bool Modified = false;
- for (MachineLoop *ML : MLI->getBase().getLoopsInPreorder()) {
- Modified |= MergeLoopEnd(ML);
- Modified |= ConvertTailPredLoop(ML, DT);
- }
-
+ for (MachineLoop *ML : MLI->getBase().getLoopsInPreorder()) {
+ Modified |= MergeLoopEnd(ML);
+ Modified |= ConvertTailPredLoop(ML, DT);
+ }
+
for (MachineBasicBlock &MBB : Fn) {
- Modified |= ReplaceConstByVPNOTs(MBB, DT);
+ Modified |= ReplaceConstByVPNOTs(MBB, DT);
Modified |= ReplaceVCMPsByVPNOTs(MBB);
Modified |= ReduceOldVCCRValueUses(MBB);
- Modified |= ConvertVPSEL(MBB);
+ Modified |= ConvertVPSEL(MBB);
}
LLVM_DEBUG(dbgs() << "**************************************\n");
diff --git a/contrib/libs/llvm12/lib/Target/ARM/TargetInfo/ya.make b/contrib/libs/llvm12/lib/Target/ARM/TargetInfo/ya.make
index 3f7fdcb6de..089e7bf206 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/TargetInfo/ya.make
+++ b/contrib/libs/llvm12/lib/Target/ARM/TargetInfo/ya.make
@@ -12,13 +12,13 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
- contrib/libs/llvm12/lib/Target/ARM
- contrib/libs/llvm12/lib/Target/ARM/TargetInfo
+ contrib/libs/llvm12/lib/Target/ARM
+ contrib/libs/llvm12/lib/Target/ARM/TargetInfo
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/ARM/Thumb2InstrInfo.cpp b/contrib/libs/llvm12/lib/Target/ARM/Thumb2InstrInfo.cpp
index 9dd389f440..d728572e28 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/Thumb2InstrInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/Thumb2InstrInfo.cpp
@@ -12,7 +12,7 @@
#include "Thumb2InstrInfo.h"
#include "ARMMachineFunctionInfo.h"
-#include "ARMSubtarget.h"
+#include "ARMSubtarget.h"
#include "MCTargetDesc/ARMAddressingModes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
@@ -39,11 +39,11 @@ OldT2IfCvt("old-thumb2-ifcvt", cl::Hidden,
cl::desc("Use old-style Thumb2 if-conversion heuristics"),
cl::init(false));
-static cl::opt<bool>
-PreferNoCSEL("prefer-no-csel", cl::Hidden,
- cl::desc("Prefer predicated Move to CSEL"),
- cl::init(false));
-
+static cl::opt<bool>
+PreferNoCSEL("prefer-no-csel", cl::Hidden,
+ cl::desc("Prefer predicated Move to CSEL"),
+ cl::init(false));
+
Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI)
: ARMBaseInstrInfo(STI) {}
@@ -124,31 +124,31 @@ Thumb2InstrInfo::isLegalToSplitMBBAt(MachineBasicBlock &MBB,
return getITInstrPredicate(*MBBI, PredReg) == ARMCC::AL;
}
-MachineInstr *
-Thumb2InstrInfo::optimizeSelect(MachineInstr &MI,
- SmallPtrSetImpl<MachineInstr *> &SeenMIs,
- bool PreferFalse) const {
- // Try to use the base optimizeSelect, which uses canFoldIntoMOVCC to fold the
- // MOVCC into another instruction. If that fails on 8.1-M fall back to using a
- // CSEL.
- MachineInstr *RV = ARMBaseInstrInfo::optimizeSelect(MI, SeenMIs, PreferFalse);
- if (!RV && getSubtarget().hasV8_1MMainlineOps() && !PreferNoCSEL) {
- Register DestReg = MI.getOperand(0).getReg();
-
- if (!DestReg.isVirtual())
- return nullptr;
-
- MachineInstrBuilder NewMI = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
- get(ARM::t2CSEL), DestReg)
- .add(MI.getOperand(2))
- .add(MI.getOperand(1))
- .add(MI.getOperand(3));
- SeenMIs.insert(NewMI);
- return NewMI;
- }
- return RV;
-}
-
+MachineInstr *
+Thumb2InstrInfo::optimizeSelect(MachineInstr &MI,
+ SmallPtrSetImpl<MachineInstr *> &SeenMIs,
+ bool PreferFalse) const {
+ // Try to use the base optimizeSelect, which uses canFoldIntoMOVCC to fold the
+ // MOVCC into another instruction. If that fails on 8.1-M fall back to using a
+ // CSEL.
+ MachineInstr *RV = ARMBaseInstrInfo::optimizeSelect(MI, SeenMIs, PreferFalse);
+ if (!RV && getSubtarget().hasV8_1MMainlineOps() && !PreferNoCSEL) {
+ Register DestReg = MI.getOperand(0).getReg();
+
+ if (!DestReg.isVirtual())
+ return nullptr;
+
+ MachineInstrBuilder NewMI = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
+ get(ARM::t2CSEL), DestReg)
+ .add(MI.getOperand(2))
+ .add(MI.getOperand(1))
+ .add(MI.getOperand(3));
+ SeenMIs.insert(NewMI);
+ return NewMI;
+ }
+ return RV;
+}
+
void Thumb2InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
const DebugLoc &DL, MCRegister DestReg,
@@ -258,22 +258,22 @@ void Thumb2InstrInfo::expandLoadStackGuard(
expandLoadStackGuardBase(MI, ARM::t2MOVi32imm, ARM::t2LDRi12);
}
-MachineInstr *Thumb2InstrInfo::commuteInstructionImpl(MachineInstr &MI,
- bool NewMI,
- unsigned OpIdx1,
- unsigned OpIdx2) const {
- switch (MI.getOpcode()) {
- case ARM::MVE_VMAXNMAf16:
- case ARM::MVE_VMAXNMAf32:
- case ARM::MVE_VMINNMAf16:
- case ARM::MVE_VMINNMAf32:
- // Don't allow predicated instructions to be commuted.
- if (getVPTInstrPredicate(MI) != ARMVCC::None)
- return nullptr;
- }
- return ARMBaseInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
-}
-
+MachineInstr *Thumb2InstrInfo::commuteInstructionImpl(MachineInstr &MI,
+ bool NewMI,
+ unsigned OpIdx1,
+ unsigned OpIdx2) const {
+ switch (MI.getOpcode()) {
+ case ARM::MVE_VMAXNMAf16:
+ case ARM::MVE_VMAXNMAf32:
+ case ARM::MVE_VMINNMAf16:
+ case ARM::MVE_VMINNMAf32:
+ // Don't allow predicated instructions to be commuted.
+ if (getVPTInstrPredicate(MI) != ARMVCC::None)
+ return nullptr;
+ }
+ return ARMBaseInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
+}
+
void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI,
const DebugLoc &dl, Register DestReg,
diff --git a/contrib/libs/llvm12/lib/Target/ARM/Thumb2InstrInfo.h b/contrib/libs/llvm12/lib/Target/ARM/Thumb2InstrInfo.h
index 6fda236159..808167bfdc 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/Thumb2InstrInfo.h
+++ b/contrib/libs/llvm12/lib/Target/ARM/Thumb2InstrInfo.h
@@ -60,14 +60,14 @@ public:
///
const ThumbRegisterInfo &getRegisterInfo() const override { return RI; }
- MachineInstr *optimizeSelect(MachineInstr &MI,
- SmallPtrSetImpl<MachineInstr *> &SeenMIs,
- bool) const override;
-
- MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
- unsigned OpIdx1,
- unsigned OpIdx2) const override;
-
+ MachineInstr *optimizeSelect(MachineInstr &MI,
+ SmallPtrSetImpl<MachineInstr *> &SeenMIs,
+ bool) const override;
+
+ MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
+ unsigned OpIdx1,
+ unsigned OpIdx2) const override;
+
private:
void expandLoadStackGuard(MachineBasicBlock::iterator MI) const override;
};
diff --git a/contrib/libs/llvm12/lib/Target/ARM/Thumb2SizeReduction.cpp b/contrib/libs/llvm12/lib/Target/ARM/Thumb2SizeReduction.cpp
index a200a5cf35..0f7e190386 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/Thumb2SizeReduction.cpp
+++ b/contrib/libs/llvm12/lib/Target/ARM/Thumb2SizeReduction.cpp
@@ -43,7 +43,7 @@
using namespace llvm;
-#define DEBUG_TYPE "thumb2-reduce-size"
+#define DEBUG_TYPE "thumb2-reduce-size"
#define THUMB2_SIZE_REDUCE_NAME "Thumb2 instruction size reduce pass"
STATISTIC(NumNarrows, "Number of 32-bit instrs reduced to 16-bit ones");
diff --git a/contrib/libs/llvm12/lib/Target/ARM/Utils/ya.make b/contrib/libs/llvm12/lib/Target/ARM/Utils/ya.make
index fed79316b8..7a980b708c 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/Utils/ya.make
+++ b/contrib/libs/llvm12/lib/Target/ARM/Utils/ya.make
@@ -12,15 +12,15 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM
- contrib/libs/llvm12/lib/Target/ARM
- contrib/libs/llvm12/lib/Target/ARM/Utils
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM
+ contrib/libs/llvm12/lib/Target/ARM
+ contrib/libs/llvm12/lib/Target/ARM/Utils
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/ARM/ya.make b/contrib/libs/llvm12/lib/Target/ARM/ya.make
index 7387bc4532..9551f9f11b 100644
--- a/contrib/libs/llvm12/lib/Target/ARM/ya.make
+++ b/contrib/libs/llvm12/lib/Target/ARM/ya.make
@@ -12,28 +12,28 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/CodeGen
- contrib/libs/llvm12/lib/CodeGen/AsmPrinter
- contrib/libs/llvm12/lib/CodeGen/GlobalISel
- contrib/libs/llvm12/lib/CodeGen/SelectionDAG
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target
- contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc
- contrib/libs/llvm12/lib/Target/ARM/TargetInfo
- contrib/libs/llvm12/lib/Target/ARM/Utils
- contrib/libs/llvm12/lib/Transforms/CFGuard
- contrib/libs/llvm12/lib/Transforms/Scalar
- contrib/libs/llvm12/lib/Transforms/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/CodeGen
+ contrib/libs/llvm12/lib/CodeGen/AsmPrinter
+ contrib/libs/llvm12/lib/CodeGen/GlobalISel
+ contrib/libs/llvm12/lib/CodeGen/SelectionDAG
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target
+ contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/ARM/TargetInfo
+ contrib/libs/llvm12/lib/Target/ARM/Utils
+ contrib/libs/llvm12/lib/Transforms/CFGuard
+ contrib/libs/llvm12/lib/Transforms/Scalar
+ contrib/libs/llvm12/lib/Transforms/Utils
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM
- contrib/libs/llvm12/lib/Target/ARM
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/ARM
+ contrib/libs/llvm12/lib/Target/ARM
)
NO_COMPILER_WARNINGS()
@@ -46,7 +46,7 @@ SRCS(
ARMBaseInstrInfo.cpp
ARMBaseRegisterInfo.cpp
ARMBasicBlockInfo.cpp
- ARMBlockPlacement.cpp
+ ARMBlockPlacement.cpp
ARMCallLowering.cpp
ARMCallingConv.cpp
ARMConstantIslandPass.cpp
@@ -69,7 +69,7 @@ SRCS(
ARMParallelDSP.cpp
ARMRegisterBankInfo.cpp
ARMRegisterInfo.cpp
- ARMSLSHardening.cpp
+ ARMSLSHardening.cpp
ARMSelectionDAGInfo.cpp
ARMSubtarget.cpp
ARMTargetMachine.cpp
diff --git a/contrib/libs/llvm12/lib/Target/BPF/AsmParser/ya.make b/contrib/libs/llvm12/lib/Target/BPF/AsmParser/ya.make
index 25f1bc8eb5..b61ac06cdd 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/AsmParser/ya.make
+++ b/contrib/libs/llvm12/lib/Target/BPF/AsmParser/ya.make
@@ -12,19 +12,19 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/MC/MCParser
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc
- contrib/libs/llvm12/lib/Target/BPF/TargetInfo
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/MC/MCParser
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/BPF/TargetInfo
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF
- contrib/libs/llvm12/lib/Target/BPF
- contrib/libs/llvm12/lib/Target/BPF/AsmParser
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF
+ contrib/libs/llvm12/lib/Target/BPF
+ contrib/libs/llvm12/lib/Target/BPF/AsmParser
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/BPF/BPF.h b/contrib/libs/llvm12/lib/Target/BPF/BPF.h
index ad49a647cc..a98a3e08d5 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/BPF.h
+++ b/contrib/libs/llvm12/lib/Target/BPF/BPF.h
@@ -10,17 +10,17 @@
#define LLVM_LIB_TARGET_BPF_BPF_H
#include "MCTargetDesc/BPFMCTargetDesc.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/Target/TargetMachine.h"
namespace llvm {
class BPFTargetMachine;
-ModulePass *createBPFAdjustOpt();
-ModulePass *createBPFCheckAndAdjustIR();
+ModulePass *createBPFAdjustOpt();
+ModulePass *createBPFCheckAndAdjustIR();
-FunctionPass *createBPFAbstractMemberAccess(BPFTargetMachine *TM);
-FunctionPass *createBPFPreserveDIType();
+FunctionPass *createBPFAbstractMemberAccess(BPFTargetMachine *TM);
+FunctionPass *createBPFPreserveDIType();
FunctionPass *createBPFISelDag(BPFTargetMachine &TM);
FunctionPass *createBPFMISimplifyPatchablePass();
FunctionPass *createBPFMIPeepholePass();
@@ -28,10 +28,10 @@ FunctionPass *createBPFMIPeepholeTruncElimPass();
FunctionPass *createBPFMIPreEmitPeepholePass();
FunctionPass *createBPFMIPreEmitCheckingPass();
-void initializeBPFAdjustOptPass(PassRegistry&);
-void initializeBPFCheckAndAdjustIRPass(PassRegistry&);
-
-void initializeBPFAbstractMemberAccessLegacyPassPass(PassRegistry &);
+void initializeBPFAdjustOptPass(PassRegistry&);
+void initializeBPFCheckAndAdjustIRPass(PassRegistry&);
+
+void initializeBPFAbstractMemberAccessLegacyPassPass(PassRegistry &);
void initializeBPFPreserveDITypePass(PassRegistry&);
void initializeBPFMISimplifyPatchablePass(PassRegistry&);
void initializeBPFMIPeepholePass(PassRegistry&);
@@ -39,28 +39,28 @@ void initializeBPFMIPeepholeTruncElimPass(PassRegistry&);
void initializeBPFMIPreEmitPeepholePass(PassRegistry&);
void initializeBPFMIPreEmitCheckingPass(PassRegistry&);
-class BPFAbstractMemberAccessPass
- : public PassInfoMixin<BPFAbstractMemberAccessPass> {
- BPFTargetMachine *TM;
-
-public:
- BPFAbstractMemberAccessPass(BPFTargetMachine *TM) : TM(TM) {}
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-
- static bool isRequired() { return true; }
-};
-
-class BPFPreserveDITypePass : public PassInfoMixin<BPFPreserveDITypePass> {
-public:
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-
- static bool isRequired() { return true; }
-};
-
-class BPFAdjustOptPass : public PassInfoMixin<BPFAdjustOptPass> {
-public:
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-};
-} // namespace llvm
-
+class BPFAbstractMemberAccessPass
+ : public PassInfoMixin<BPFAbstractMemberAccessPass> {
+ BPFTargetMachine *TM;
+
+public:
+ BPFAbstractMemberAccessPass(BPFTargetMachine *TM) : TM(TM) {}
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+
+ static bool isRequired() { return true; }
+};
+
+class BPFPreserveDITypePass : public PassInfoMixin<BPFPreserveDITypePass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+
+ static bool isRequired() { return true; }
+};
+
+class BPFAdjustOptPass : public PassInfoMixin<BPFAdjustOptPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+} // namespace llvm
+
#endif
diff --git a/contrib/libs/llvm12/lib/Target/BPF/BPFAbstractMemberAccess.cpp b/contrib/libs/llvm12/lib/Target/BPF/BPFAbstractMemberAccess.cpp
index 5809fe501f..cd994a9c83 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/BPFAbstractMemberAccess.cpp
+++ b/contrib/libs/llvm12/lib/Target/BPF/BPFAbstractMemberAccess.cpp
@@ -81,9 +81,9 @@
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
-#include "llvm/IR/IntrinsicsBPF.h"
+#include "llvm/IR/IntrinsicsBPF.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
@@ -95,30 +95,30 @@
namespace llvm {
constexpr StringRef BPFCoreSharedInfo::AmaAttr;
-uint32_t BPFCoreSharedInfo::SeqNum;
-
-Instruction *BPFCoreSharedInfo::insertPassThrough(Module *M, BasicBlock *BB,
- Instruction *Input,
- Instruction *Before) {
- Function *Fn = Intrinsic::getDeclaration(
- M, Intrinsic::bpf_passthrough, {Input->getType(), Input->getType()});
- Constant *SeqNumVal = ConstantInt::get(Type::getInt32Ty(BB->getContext()),
- BPFCoreSharedInfo::SeqNum++);
-
- auto *NewInst = CallInst::Create(Fn, {SeqNumVal, Input});
- BB->getInstList().insert(Before->getIterator(), NewInst);
- return NewInst;
-}
+uint32_t BPFCoreSharedInfo::SeqNum;
+
+Instruction *BPFCoreSharedInfo::insertPassThrough(Module *M, BasicBlock *BB,
+ Instruction *Input,
+ Instruction *Before) {
+ Function *Fn = Intrinsic::getDeclaration(
+ M, Intrinsic::bpf_passthrough, {Input->getType(), Input->getType()});
+ Constant *SeqNumVal = ConstantInt::get(Type::getInt32Ty(BB->getContext()),
+ BPFCoreSharedInfo::SeqNum++);
+
+ auto *NewInst = CallInst::Create(Fn, {SeqNumVal, Input});
+ BB->getInstList().insert(Before->getIterator(), NewInst);
+ return NewInst;
+}
} // namespace llvm
using namespace llvm;
namespace {
-class BPFAbstractMemberAccess final {
-public:
- BPFAbstractMemberAccess(BPFTargetMachine *TM) : TM(TM) {}
+class BPFAbstractMemberAccess final {
+public:
+ BPFAbstractMemberAccess(BPFTargetMachine *TM) : TM(TM) {}
- bool run(Function &F);
+ bool run(Function &F);
struct CallInfo {
uint32_t Kind;
@@ -137,11 +137,11 @@ private:
BPFPreserveFieldInfoAI = 4,
};
- TargetMachine *TM;
+ TargetMachine *TM;
const DataLayout *DL = nullptr;
- Module *M = nullptr;
+ Module *M = nullptr;
- static std::map<std::string, GlobalVariable *> GEPGlobals;
+ static std::map<std::string, GlobalVariable *> GEPGlobals;
// A map to link preserve_*_access_index instrinsic calls.
std::map<CallInst *, std::pair<CallInst *, CallInfo>> AIChain;
// A map to hold all the base preserve_*_access_index instrinsic calls.
@@ -149,19 +149,19 @@ private:
// intrinsics.
std::map<CallInst *, CallInfo> BaseAICalls;
- bool doTransformation(Function &F);
+ bool doTransformation(Function &F);
void traceAICall(CallInst *Call, CallInfo &ParentInfo);
void traceBitCast(BitCastInst *BitCast, CallInst *Parent,
CallInfo &ParentInfo);
void traceGEP(GetElementPtrInst *GEP, CallInst *Parent,
CallInfo &ParentInfo);
- void collectAICallChains(Function &F);
+ void collectAICallChains(Function &F);
bool IsPreserveDIAccessIndexCall(const CallInst *Call, CallInfo &Cinfo);
bool IsValidAIChain(const MDNode *ParentMeta, uint32_t ParentAI,
const MDNode *ChildMeta);
- bool removePreserveAccessIndexIntrinsic(Function &F);
+ bool removePreserveAccessIndexIntrinsic(Function &F);
void replaceWithGEP(std::vector<CallInst *> &CallList,
uint32_t NumOfZerosIndex, uint32_t DIIndex);
bool HasPreserveFieldInfoCall(CallInfoStack &CallStack);
@@ -173,55 +173,55 @@ private:
Value *computeBaseAndAccessKey(CallInst *Call, CallInfo &CInfo,
std::string &AccessKey, MDNode *&BaseMeta);
- MDNode *computeAccessKey(CallInst *Call, CallInfo &CInfo,
- std::string &AccessKey, bool &IsInt32Ret);
+ MDNode *computeAccessKey(CallInst *Call, CallInfo &CInfo,
+ std::string &AccessKey, bool &IsInt32Ret);
uint64_t getConstant(const Value *IndexValue);
- bool transformGEPChain(CallInst *Call, CallInfo &CInfo);
+ bool transformGEPChain(CallInst *Call, CallInfo &CInfo);
+};
+
+std::map<std::string, GlobalVariable *> BPFAbstractMemberAccess::GEPGlobals;
+
+class BPFAbstractMemberAccessLegacyPass final : public FunctionPass {
+ BPFTargetMachine *TM;
+
+ bool runOnFunction(Function &F) override {
+ return BPFAbstractMemberAccess(TM).run(F);
+ }
+
+public:
+ static char ID;
+
+ // Add optional BPFTargetMachine parameter so that BPF backend can add the
+ // phase with target machine to find out the endianness. The default
+ // constructor (without parameters) is used by the pass manager for managing
+ // purposes.
+ BPFAbstractMemberAccessLegacyPass(BPFTargetMachine *TM = nullptr)
+ : FunctionPass(ID), TM(TM) {}
};
-
-std::map<std::string, GlobalVariable *> BPFAbstractMemberAccess::GEPGlobals;
-
-class BPFAbstractMemberAccessLegacyPass final : public FunctionPass {
- BPFTargetMachine *TM;
-
- bool runOnFunction(Function &F) override {
- return BPFAbstractMemberAccess(TM).run(F);
- }
-
-public:
- static char ID;
-
- // Add optional BPFTargetMachine parameter so that BPF backend can add the
- // phase with target machine to find out the endianness. The default
- // constructor (without parameters) is used by the pass manager for managing
- // purposes.
- BPFAbstractMemberAccessLegacyPass(BPFTargetMachine *TM = nullptr)
- : FunctionPass(ID), TM(TM) {}
-};
-
+
} // End anonymous namespace
-char BPFAbstractMemberAccessLegacyPass::ID = 0;
-INITIALIZE_PASS(BPFAbstractMemberAccessLegacyPass, DEBUG_TYPE,
- "BPF Abstract Member Access", false, false)
+char BPFAbstractMemberAccessLegacyPass::ID = 0;
+INITIALIZE_PASS(BPFAbstractMemberAccessLegacyPass, DEBUG_TYPE,
+ "BPF Abstract Member Access", false, false)
-FunctionPass *llvm::createBPFAbstractMemberAccess(BPFTargetMachine *TM) {
- return new BPFAbstractMemberAccessLegacyPass(TM);
+FunctionPass *llvm::createBPFAbstractMemberAccess(BPFTargetMachine *TM) {
+ return new BPFAbstractMemberAccessLegacyPass(TM);
}
-bool BPFAbstractMemberAccess::run(Function &F) {
+bool BPFAbstractMemberAccess::run(Function &F) {
LLVM_DEBUG(dbgs() << "********** Abstract Member Accesses **********\n");
- M = F.getParent();
- if (!M)
- return false;
-
+ M = F.getParent();
+ if (!M)
+ return false;
+
// Bail out if no debug info.
- if (M->debug_compile_units().empty())
+ if (M->debug_compile_units().empty())
return false;
- DL = &M->getDataLayout();
- return doTransformation(F);
+ DL = &M->getDataLayout();
+ return doTransformation(F);
}
static bool SkipDIDerivedTag(unsigned Tag, bool skipTypedef) {
@@ -320,34 +320,34 @@ bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(const CallInst *Call,
CInfo.AccessIndex = InfoKind;
return true;
}
- if (GV->getName().startswith("llvm.bpf.preserve.type.info")) {
- CInfo.Kind = BPFPreserveFieldInfoAI;
- CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
- if (!CInfo.Metadata)
- report_fatal_error("Missing metadata for llvm.preserve.type.info intrinsic");
- uint64_t Flag = getConstant(Call->getArgOperand(1));
- if (Flag >= BPFCoreSharedInfo::MAX_PRESERVE_TYPE_INFO_FLAG)
- report_fatal_error("Incorrect flag for llvm.bpf.preserve.type.info intrinsic");
- if (Flag == BPFCoreSharedInfo::PRESERVE_TYPE_INFO_EXISTENCE)
- CInfo.AccessIndex = BPFCoreSharedInfo::TYPE_EXISTENCE;
- else
- CInfo.AccessIndex = BPFCoreSharedInfo::TYPE_SIZE;
- return true;
- }
- if (GV->getName().startswith("llvm.bpf.preserve.enum.value")) {
- CInfo.Kind = BPFPreserveFieldInfoAI;
- CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
- if (!CInfo.Metadata)
- report_fatal_error("Missing metadata for llvm.preserve.enum.value intrinsic");
- uint64_t Flag = getConstant(Call->getArgOperand(2));
- if (Flag >= BPFCoreSharedInfo::MAX_PRESERVE_ENUM_VALUE_FLAG)
- report_fatal_error("Incorrect flag for llvm.bpf.preserve.enum.value intrinsic");
- if (Flag == BPFCoreSharedInfo::PRESERVE_ENUM_VALUE_EXISTENCE)
- CInfo.AccessIndex = BPFCoreSharedInfo::ENUM_VALUE_EXISTENCE;
- else
- CInfo.AccessIndex = BPFCoreSharedInfo::ENUM_VALUE;
- return true;
- }
+ if (GV->getName().startswith("llvm.bpf.preserve.type.info")) {
+ CInfo.Kind = BPFPreserveFieldInfoAI;
+ CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
+ if (!CInfo.Metadata)
+ report_fatal_error("Missing metadata for llvm.preserve.type.info intrinsic");
+ uint64_t Flag = getConstant(Call->getArgOperand(1));
+ if (Flag >= BPFCoreSharedInfo::MAX_PRESERVE_TYPE_INFO_FLAG)
+ report_fatal_error("Incorrect flag for llvm.bpf.preserve.type.info intrinsic");
+ if (Flag == BPFCoreSharedInfo::PRESERVE_TYPE_INFO_EXISTENCE)
+ CInfo.AccessIndex = BPFCoreSharedInfo::TYPE_EXISTENCE;
+ else
+ CInfo.AccessIndex = BPFCoreSharedInfo::TYPE_SIZE;
+ return true;
+ }
+ if (GV->getName().startswith("llvm.bpf.preserve.enum.value")) {
+ CInfo.Kind = BPFPreserveFieldInfoAI;
+ CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
+ if (!CInfo.Metadata)
+ report_fatal_error("Missing metadata for llvm.preserve.enum.value intrinsic");
+ uint64_t Flag = getConstant(Call->getArgOperand(2));
+ if (Flag >= BPFCoreSharedInfo::MAX_PRESERVE_ENUM_VALUE_FLAG)
+ report_fatal_error("Incorrect flag for llvm.bpf.preserve.enum.value intrinsic");
+ if (Flag == BPFCoreSharedInfo::PRESERVE_ENUM_VALUE_EXISTENCE)
+ CInfo.AccessIndex = BPFCoreSharedInfo::ENUM_VALUE_EXISTENCE;
+ else
+ CInfo.AccessIndex = BPFCoreSharedInfo::ENUM_VALUE;
+ return true;
+ }
return false;
}
@@ -374,27 +374,27 @@ void BPFAbstractMemberAccess::replaceWithGEP(std::vector<CallInst *> &CallList,
}
}
-bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(Function &F) {
+bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(Function &F) {
std::vector<CallInst *> PreserveArrayIndexCalls;
std::vector<CallInst *> PreserveUnionIndexCalls;
std::vector<CallInst *> PreserveStructIndexCalls;
bool Found = false;
- for (auto &BB : F)
- for (auto &I : BB) {
- auto *Call = dyn_cast<CallInst>(&I);
- CallInfo CInfo;
- if (!IsPreserveDIAccessIndexCall(Call, CInfo))
- continue;
-
- Found = true;
- if (CInfo.Kind == BPFPreserveArrayAI)
- PreserveArrayIndexCalls.push_back(Call);
- else if (CInfo.Kind == BPFPreserveUnionAI)
- PreserveUnionIndexCalls.push_back(Call);
- else
- PreserveStructIndexCalls.push_back(Call);
- }
+ for (auto &BB : F)
+ for (auto &I : BB) {
+ auto *Call = dyn_cast<CallInst>(&I);
+ CallInfo CInfo;
+ if (!IsPreserveDIAccessIndexCall(Call, CInfo))
+ continue;
+
+ Found = true;
+ if (CInfo.Kind == BPFPreserveArrayAI)
+ PreserveArrayIndexCalls.push_back(Call);
+ else if (CInfo.Kind == BPFPreserveUnionAI)
+ PreserveUnionIndexCalls.push_back(Call);
+ else
+ PreserveStructIndexCalls.push_back(Call);
+ }
// do the following transformation:
// . addr = preserve_array_access_index(base, dimension, index)
@@ -560,7 +560,7 @@ void BPFAbstractMemberAccess::traceGEP(GetElementPtrInst *GEP, CallInst *Parent,
}
}
-void BPFAbstractMemberAccess::collectAICallChains(Function &F) {
+void BPFAbstractMemberAccess::collectAICallChains(Function &F) {
AIChain.clear();
BaseAICalls.clear();
@@ -909,94 +909,94 @@ Value *BPFAbstractMemberAccess::computeBaseAndAccessKey(CallInst *Call,
return Base;
}
-MDNode *BPFAbstractMemberAccess::computeAccessKey(CallInst *Call,
- CallInfo &CInfo,
- std::string &AccessKey,
- bool &IsInt32Ret) {
- DIType *Ty = stripQualifiers(cast<DIType>(CInfo.Metadata), false);
- assert(!Ty->getName().empty());
-
- int64_t PatchImm;
- std::string AccessStr("0");
- if (CInfo.AccessIndex == BPFCoreSharedInfo::TYPE_EXISTENCE) {
- PatchImm = 1;
- } else if (CInfo.AccessIndex == BPFCoreSharedInfo::TYPE_SIZE) {
- // typedef debuginfo type has size 0, get the eventual base type.
- DIType *BaseTy = stripQualifiers(Ty, true);
- PatchImm = BaseTy->getSizeInBits() / 8;
- } else {
- // ENUM_VALUE_EXISTENCE and ENUM_VALUE
- IsInt32Ret = false;
-
- const auto *CE = cast<ConstantExpr>(Call->getArgOperand(1));
- const GlobalVariable *GV = cast<GlobalVariable>(CE->getOperand(0));
- assert(GV->hasInitializer());
- const ConstantDataArray *DA = cast<ConstantDataArray>(GV->getInitializer());
- assert(DA->isString());
- StringRef ValueStr = DA->getAsString();
-
- // ValueStr format: <EnumeratorStr>:<Value>
- size_t Separator = ValueStr.find_first_of(':');
- StringRef EnumeratorStr = ValueStr.substr(0, Separator);
-
- // Find enumerator index in the debuginfo
- DIType *BaseTy = stripQualifiers(Ty, true);
- const auto *CTy = cast<DICompositeType>(BaseTy);
- assert(CTy->getTag() == dwarf::DW_TAG_enumeration_type);
- int EnumIndex = 0;
- for (const auto Element : CTy->getElements()) {
- const auto *Enum = cast<DIEnumerator>(Element);
- if (Enum->getName() == EnumeratorStr) {
- AccessStr = std::to_string(EnumIndex);
- break;
- }
- EnumIndex++;
- }
-
- if (CInfo.AccessIndex == BPFCoreSharedInfo::ENUM_VALUE) {
- StringRef EValueStr = ValueStr.substr(Separator + 1);
- PatchImm = std::stoll(std::string(EValueStr));
- } else {
- PatchImm = 1;
- }
- }
-
- AccessKey = "llvm." + Ty->getName().str() + ":" +
- std::to_string(CInfo.AccessIndex) + std::string(":") +
- std::to_string(PatchImm) + std::string("$") + AccessStr;
-
- return Ty;
-}
-
+MDNode *BPFAbstractMemberAccess::computeAccessKey(CallInst *Call,
+ CallInfo &CInfo,
+ std::string &AccessKey,
+ bool &IsInt32Ret) {
+ DIType *Ty = stripQualifiers(cast<DIType>(CInfo.Metadata), false);
+ assert(!Ty->getName().empty());
+
+ int64_t PatchImm;
+ std::string AccessStr("0");
+ if (CInfo.AccessIndex == BPFCoreSharedInfo::TYPE_EXISTENCE) {
+ PatchImm = 1;
+ } else if (CInfo.AccessIndex == BPFCoreSharedInfo::TYPE_SIZE) {
+ // typedef debuginfo type has size 0, get the eventual base type.
+ DIType *BaseTy = stripQualifiers(Ty, true);
+ PatchImm = BaseTy->getSizeInBits() / 8;
+ } else {
+ // ENUM_VALUE_EXISTENCE and ENUM_VALUE
+ IsInt32Ret = false;
+
+ const auto *CE = cast<ConstantExpr>(Call->getArgOperand(1));
+ const GlobalVariable *GV = cast<GlobalVariable>(CE->getOperand(0));
+ assert(GV->hasInitializer());
+ const ConstantDataArray *DA = cast<ConstantDataArray>(GV->getInitializer());
+ assert(DA->isString());
+ StringRef ValueStr = DA->getAsString();
+
+ // ValueStr format: <EnumeratorStr>:<Value>
+ size_t Separator = ValueStr.find_first_of(':');
+ StringRef EnumeratorStr = ValueStr.substr(0, Separator);
+
+ // Find enumerator index in the debuginfo
+ DIType *BaseTy = stripQualifiers(Ty, true);
+ const auto *CTy = cast<DICompositeType>(BaseTy);
+ assert(CTy->getTag() == dwarf::DW_TAG_enumeration_type);
+ int EnumIndex = 0;
+ for (const auto Element : CTy->getElements()) {
+ const auto *Enum = cast<DIEnumerator>(Element);
+ if (Enum->getName() == EnumeratorStr) {
+ AccessStr = std::to_string(EnumIndex);
+ break;
+ }
+ EnumIndex++;
+ }
+
+ if (CInfo.AccessIndex == BPFCoreSharedInfo::ENUM_VALUE) {
+ StringRef EValueStr = ValueStr.substr(Separator + 1);
+ PatchImm = std::stoll(std::string(EValueStr));
+ } else {
+ PatchImm = 1;
+ }
+ }
+
+ AccessKey = "llvm." + Ty->getName().str() + ":" +
+ std::to_string(CInfo.AccessIndex) + std::string(":") +
+ std::to_string(PatchImm) + std::string("$") + AccessStr;
+
+ return Ty;
+}
+
/// Call/Kind is the base preserve_*_access_index() call. Attempts to do
/// transformation to a chain of relocable GEPs.
-bool BPFAbstractMemberAccess::transformGEPChain(CallInst *Call,
+bool BPFAbstractMemberAccess::transformGEPChain(CallInst *Call,
CallInfo &CInfo) {
std::string AccessKey;
MDNode *TypeMeta;
- Value *Base = nullptr;
- bool IsInt32Ret;
-
- IsInt32Ret = CInfo.Kind == BPFPreserveFieldInfoAI;
- if (CInfo.Kind == BPFPreserveFieldInfoAI && CInfo.Metadata) {
- TypeMeta = computeAccessKey(Call, CInfo, AccessKey, IsInt32Ret);
- } else {
- Base = computeBaseAndAccessKey(Call, CInfo, AccessKey, TypeMeta);
- if (!Base)
- return false;
- }
-
+ Value *Base = nullptr;
+ bool IsInt32Ret;
+
+ IsInt32Ret = CInfo.Kind == BPFPreserveFieldInfoAI;
+ if (CInfo.Kind == BPFPreserveFieldInfoAI && CInfo.Metadata) {
+ TypeMeta = computeAccessKey(Call, CInfo, AccessKey, IsInt32Ret);
+ } else {
+ Base = computeBaseAndAccessKey(Call, CInfo, AccessKey, TypeMeta);
+ if (!Base)
+ return false;
+ }
+
BasicBlock *BB = Call->getParent();
GlobalVariable *GV;
if (GEPGlobals.find(AccessKey) == GEPGlobals.end()) {
IntegerType *VarType;
- if (IsInt32Ret)
+ if (IsInt32Ret)
VarType = Type::getInt32Ty(BB->getContext()); // 32bit return value
else
- VarType = Type::getInt64Ty(BB->getContext()); // 64bit ptr or enum value
+ VarType = Type::getInt64Ty(BB->getContext()); // 64bit ptr or enum value
- GV = new GlobalVariable(*M, VarType, false, GlobalVariable::ExternalLinkage,
+ GV = new GlobalVariable(*M, VarType, false, GlobalVariable::ExternalLinkage,
NULL, AccessKey);
GV->addAttribute(BPFCoreSharedInfo::AmaAttr);
GV->setMetadata(LLVMContext::MD_preserve_access_index, TypeMeta);
@@ -1007,15 +1007,15 @@ bool BPFAbstractMemberAccess::transformGEPChain(CallInst *Call,
if (CInfo.Kind == BPFPreserveFieldInfoAI) {
// Load the global variable which represents the returned field info.
- LoadInst *LDInst;
- if (IsInt32Ret)
- LDInst = new LoadInst(Type::getInt32Ty(BB->getContext()), GV, "", Call);
- else
- LDInst = new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "", Call);
-
- Instruction *PassThroughInst =
- BPFCoreSharedInfo::insertPassThrough(M, BB, LDInst, Call);
- Call->replaceAllUsesWith(PassThroughInst);
+ LoadInst *LDInst;
+ if (IsInt32Ret)
+ LDInst = new LoadInst(Type::getInt32Ty(BB->getContext()), GV, "", Call);
+ else
+ LDInst = new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "", Call);
+
+ Instruction *PassThroughInst =
+ BPFCoreSharedInfo::insertPassThrough(M, BB, LDInst, Call);
+ Call->replaceAllUsesWith(PassThroughInst);
Call->eraseFromParent();
return true;
}
@@ -1023,7 +1023,7 @@ bool BPFAbstractMemberAccess::transformGEPChain(CallInst *Call,
// For any original GEP Call and Base %2 like
// %4 = bitcast %struct.net_device** %dev1 to i64*
// it is transformed to:
- // %6 = load llvm.sk_buff:0:50$0:0:0:2:0
+ // %6 = load llvm.sk_buff:0:50$0:0:0:2:0
// %7 = bitcast %struct.sk_buff* %2 to i8*
// %8 = getelementptr i8, i8* %7, %6
// %9 = bitcast i8* %8 to i64*
@@ -1046,75 +1046,75 @@ bool BPFAbstractMemberAccess::transformGEPChain(CallInst *Call,
auto *BCInst2 = new BitCastInst(GEP, Call->getType());
BB->getInstList().insert(Call->getIterator(), BCInst2);
- // For the following code,
- // Block0:
- // ...
- // if (...) goto Block1 else ...
- // Block1:
- // %6 = load llvm.sk_buff:0:50$0:0:0:2:0
- // %7 = bitcast %struct.sk_buff* %2 to i8*
- // %8 = getelementptr i8, i8* %7, %6
- // ...
- // goto CommonExit
- // Block2:
- // ...
- // if (...) goto Block3 else ...
- // Block3:
- // %6 = load llvm.bpf_map:0:40$0:0:0:2:0
- // %7 = bitcast %struct.sk_buff* %2 to i8*
- // %8 = getelementptr i8, i8* %7, %6
- // ...
- // goto CommonExit
- // CommonExit
- // SimplifyCFG may generate:
- // Block0:
- // ...
- // if (...) goto Block_Common else ...
- // Block2:
- // ...
- // if (...) goto Block_Common else ...
- // Block_Common:
- // PHI = [llvm.sk_buff:0:50$0:0:0:2:0, llvm.bpf_map:0:40$0:0:0:2:0]
- // %6 = load PHI
- // %7 = bitcast %struct.sk_buff* %2 to i8*
- // %8 = getelementptr i8, i8* %7, %6
- // ...
- // goto CommonExit
- // For the above code, we cannot perform proper relocation since
- // "load PHI" has two possible relocations.
- //
- // To prevent above tail merging, we use __builtin_bpf_passthrough()
- // where one of its parameters is a seq_num. Since two
- // __builtin_bpf_passthrough() funcs will always have different seq_num,
- // tail merging cannot happen. The __builtin_bpf_passthrough() will be
- // removed in the beginning of Target IR passes.
- //
- // This approach is also used in other places when global var
- // representing a relocation is used.
- Instruction *PassThroughInst =
- BPFCoreSharedInfo::insertPassThrough(M, BB, BCInst2, Call);
- Call->replaceAllUsesWith(PassThroughInst);
+ // For the following code,
+ // Block0:
+ // ...
+ // if (...) goto Block1 else ...
+ // Block1:
+ // %6 = load llvm.sk_buff:0:50$0:0:0:2:0
+ // %7 = bitcast %struct.sk_buff* %2 to i8*
+ // %8 = getelementptr i8, i8* %7, %6
+ // ...
+ // goto CommonExit
+ // Block2:
+ // ...
+ // if (...) goto Block3 else ...
+ // Block3:
+ // %6 = load llvm.bpf_map:0:40$0:0:0:2:0
+ // %7 = bitcast %struct.sk_buff* %2 to i8*
+ // %8 = getelementptr i8, i8* %7, %6
+ // ...
+ // goto CommonExit
+ // CommonExit
+ // SimplifyCFG may generate:
+ // Block0:
+ // ...
+ // if (...) goto Block_Common else ...
+ // Block2:
+ // ...
+ // if (...) goto Block_Common else ...
+ // Block_Common:
+ // PHI = [llvm.sk_buff:0:50$0:0:0:2:0, llvm.bpf_map:0:40$0:0:0:2:0]
+ // %6 = load PHI
+ // %7 = bitcast %struct.sk_buff* %2 to i8*
+ // %8 = getelementptr i8, i8* %7, %6
+ // ...
+ // goto CommonExit
+ // For the above code, we cannot perform proper relocation since
+ // "load PHI" has two possible relocations.
+ //
+ // To prevent above tail merging, we use __builtin_bpf_passthrough()
+ // where one of its parameters is a seq_num. Since two
+ // __builtin_bpf_passthrough() funcs will always have different seq_num,
+ // tail merging cannot happen. The __builtin_bpf_passthrough() will be
+ // removed in the beginning of Target IR passes.
+ //
+ // This approach is also used in other places when global var
+ // representing a relocation is used.
+ Instruction *PassThroughInst =
+ BPFCoreSharedInfo::insertPassThrough(M, BB, BCInst2, Call);
+ Call->replaceAllUsesWith(PassThroughInst);
Call->eraseFromParent();
return true;
}
-bool BPFAbstractMemberAccess::doTransformation(Function &F) {
+bool BPFAbstractMemberAccess::doTransformation(Function &F) {
bool Transformed = false;
- // Collect PreserveDIAccessIndex Intrinsic call chains.
- // The call chains will be used to generate the access
- // patterns similar to GEP.
- collectAICallChains(F);
+ // Collect PreserveDIAccessIndex Intrinsic call chains.
+ // The call chains will be used to generate the access
+ // patterns similar to GEP.
+ collectAICallChains(F);
+
+ for (auto &C : BaseAICalls)
+ Transformed = transformGEPChain(C.first, C.second) || Transformed;
- for (auto &C : BaseAICalls)
- Transformed = transformGEPChain(C.first, C.second) || Transformed;
+ return removePreserveAccessIndexIntrinsic(F) || Transformed;
+}
- return removePreserveAccessIndexIntrinsic(F) || Transformed;
+PreservedAnalyses
+BPFAbstractMemberAccessPass::run(Function &F, FunctionAnalysisManager &AM) {
+ return BPFAbstractMemberAccess(TM).run(F) ? PreservedAnalyses::none()
+ : PreservedAnalyses::all();
}
-
-PreservedAnalyses
-BPFAbstractMemberAccessPass::run(Function &F, FunctionAnalysisManager &AM) {
- return BPFAbstractMemberAccess(TM).run(F) ? PreservedAnalyses::none()
- : PreservedAnalyses::all();
-}
diff --git a/contrib/libs/llvm12/lib/Target/BPF/BPFAdjustOpt.cpp b/contrib/libs/llvm12/lib/Target/BPF/BPFAdjustOpt.cpp
index 9b774357bb..da543e7eba 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/BPFAdjustOpt.cpp
+++ b/contrib/libs/llvm12/lib/Target/BPF/BPFAdjustOpt.cpp
@@ -1,323 +1,323 @@
-//===---------------- BPFAdjustOpt.cpp - Adjust Optimization --------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Adjust optimization to make the code more kernel verifier friendly.
-//
-//===----------------------------------------------------------------------===//
-
-#include "BPF.h"
-#include "BPFCORE.h"
-#include "BPFTargetMachine.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/Type.h"
-#include "llvm/IR/User.h"
-#include "llvm/IR/Value.h"
-#include "llvm/Pass.h"
-#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-
-#define DEBUG_TYPE "bpf-adjust-opt"
-
-using namespace llvm;
-
-static cl::opt<bool>
- DisableBPFserializeICMP("bpf-disable-serialize-icmp", cl::Hidden,
- cl::desc("BPF: Disable Serializing ICMP insns."),
- cl::init(false));
-
-static cl::opt<bool> DisableBPFavoidSpeculation(
- "bpf-disable-avoid-speculation", cl::Hidden,
- cl::desc("BPF: Disable Avoiding Speculative Code Motion."),
- cl::init(false));
-
-namespace {
-
-class BPFAdjustOpt final : public ModulePass {
-public:
- static char ID;
-
- BPFAdjustOpt() : ModulePass(ID) {}
- bool runOnModule(Module &M) override;
-};
-
-class BPFAdjustOptImpl {
- struct PassThroughInfo {
- Instruction *Input;
- Instruction *UsedInst;
- uint32_t OpIdx;
- PassThroughInfo(Instruction *I, Instruction *U, uint32_t Idx)
- : Input(I), UsedInst(U), OpIdx(Idx) {}
- };
-
-public:
- BPFAdjustOptImpl(Module *M) : M(M) {}
-
- bool run();
-
-private:
- Module *M;
- SmallVector<PassThroughInfo, 16> PassThroughs;
-
- void adjustBasicBlock(BasicBlock &BB);
- bool serializeICMPCrossBB(BasicBlock &BB);
- void adjustInst(Instruction &I);
- bool serializeICMPInBB(Instruction &I);
- bool avoidSpeculation(Instruction &I);
- bool insertPassThrough();
-};
-
-} // End anonymous namespace
-
-char BPFAdjustOpt::ID = 0;
-INITIALIZE_PASS(BPFAdjustOpt, "bpf-adjust-opt", "BPF Adjust Optimization",
- false, false)
-
-ModulePass *llvm::createBPFAdjustOpt() { return new BPFAdjustOpt(); }
-
-bool BPFAdjustOpt::runOnModule(Module &M) { return BPFAdjustOptImpl(&M).run(); }
-
-bool BPFAdjustOptImpl::run() {
- for (Function &F : *M)
- for (auto &BB : F) {
- adjustBasicBlock(BB);
- for (auto &I : BB)
- adjustInst(I);
- }
-
- return insertPassThrough();
-}
-
-bool BPFAdjustOptImpl::insertPassThrough() {
- for (auto &Info : PassThroughs) {
- auto *CI = BPFCoreSharedInfo::insertPassThrough(
- M, Info.UsedInst->getParent(), Info.Input, Info.UsedInst);
- Info.UsedInst->setOperand(Info.OpIdx, CI);
- }
-
- return !PassThroughs.empty();
-}
-
-// To avoid combining conditionals in the same basic block by
-// instrcombine optimization.
-bool BPFAdjustOptImpl::serializeICMPInBB(Instruction &I) {
- // For:
- // comp1 = icmp <opcode> ...;
- // comp2 = icmp <opcode> ...;
- // ... or comp1 comp2 ...
- // changed to:
- // comp1 = icmp <opcode> ...;
- // comp2 = icmp <opcode> ...;
- // new_comp1 = __builtin_bpf_passthrough(seq_num, comp1)
- // ... or new_comp1 comp2 ...
- if (I.getOpcode() != Instruction::Or)
- return false;
- auto *Icmp1 = dyn_cast<ICmpInst>(I.getOperand(0));
- if (!Icmp1)
- return false;
- auto *Icmp2 = dyn_cast<ICmpInst>(I.getOperand(1));
- if (!Icmp2)
- return false;
-
- Value *Icmp1Op0 = Icmp1->getOperand(0);
- Value *Icmp2Op0 = Icmp2->getOperand(0);
- if (Icmp1Op0 != Icmp2Op0)
- return false;
-
- // Now we got two icmp instructions which feed into
- // an "or" instruction.
- PassThroughInfo Info(Icmp1, &I, 0);
- PassThroughs.push_back(Info);
- return true;
-}
-
-// To avoid combining conditionals in the same basic block by
-// instrcombine optimization.
-bool BPFAdjustOptImpl::serializeICMPCrossBB(BasicBlock &BB) {
- // For:
- // B1:
- // comp1 = icmp <opcode> ...;
- // if (comp1) goto B2 else B3;
- // B2:
- // comp2 = icmp <opcode> ...;
- // if (comp2) goto B4 else B5;
- // B4:
- // ...
- // changed to:
- // B1:
- // comp1 = icmp <opcode> ...;
- // comp1 = __builtin_bpf_passthrough(seq_num, comp1);
- // if (comp1) goto B2 else B3;
- // B2:
- // comp2 = icmp <opcode> ...;
- // if (comp2) goto B4 else B5;
- // B4:
- // ...
-
- // Check basic predecessors, if two of them (say B1, B2) are using
- // icmp instructions to generate conditions and one is the predesessor
- // of another (e.g., B1 is the predecessor of B2). Add a passthrough
- // barrier after icmp inst of block B1.
- BasicBlock *B2 = BB.getSinglePredecessor();
- if (!B2)
- return false;
-
- BasicBlock *B1 = B2->getSinglePredecessor();
- if (!B1)
- return false;
-
- Instruction *TI = B2->getTerminator();
- auto *BI = dyn_cast<BranchInst>(TI);
- if (!BI || !BI->isConditional())
- return false;
- auto *Cond = dyn_cast<ICmpInst>(BI->getCondition());
- if (!Cond || B2->getFirstNonPHI() != Cond)
- return false;
- Value *B2Op0 = Cond->getOperand(0);
- auto Cond2Op = Cond->getPredicate();
-
- TI = B1->getTerminator();
- BI = dyn_cast<BranchInst>(TI);
- if (!BI || !BI->isConditional())
- return false;
- Cond = dyn_cast<ICmpInst>(BI->getCondition());
- if (!Cond)
- return false;
- Value *B1Op0 = Cond->getOperand(0);
- auto Cond1Op = Cond->getPredicate();
-
- if (B1Op0 != B2Op0)
- return false;
-
- if (Cond1Op == ICmpInst::ICMP_SGT || Cond1Op == ICmpInst::ICMP_SGE) {
- if (Cond2Op != ICmpInst::ICMP_SLT && Cond1Op != ICmpInst::ICMP_SLE)
- return false;
- } else if (Cond1Op == ICmpInst::ICMP_SLT || Cond1Op == ICmpInst::ICMP_SLE) {
- if (Cond2Op != ICmpInst::ICMP_SGT && Cond1Op != ICmpInst::ICMP_SGE)
- return false;
- } else {
- return false;
- }
-
- PassThroughInfo Info(Cond, BI, 0);
- PassThroughs.push_back(Info);
-
- return true;
-}
-
-// To avoid speculative hoisting certain computations out of
-// a basic block.
-bool BPFAdjustOptImpl::avoidSpeculation(Instruction &I) {
- if (auto *LdInst = dyn_cast<LoadInst>(&I)) {
- if (auto *GV = dyn_cast<GlobalVariable>(LdInst->getOperand(0))) {
- if (GV->hasAttribute(BPFCoreSharedInfo::AmaAttr) ||
- GV->hasAttribute(BPFCoreSharedInfo::TypeIdAttr))
- return false;
- }
- }
-
- if (!isa<LoadInst>(&I) && !isa<CallInst>(&I))
- return false;
-
- // For:
- // B1:
- // var = ...
- // ...
- // /* icmp may not be in the same block as var = ... */
- // comp1 = icmp <opcode> var, <const>;
- // if (comp1) goto B2 else B3;
- // B2:
- // ... var ...
- // change to:
- // B1:
- // var = ...
- // ...
- // /* icmp may not be in the same block as var = ... */
- // comp1 = icmp <opcode> var, <const>;
- // if (comp1) goto B2 else B3;
- // B2:
- // var = __builtin_bpf_passthrough(seq_num, var);
- // ... var ...
- bool isCandidate = false;
- SmallVector<PassThroughInfo, 4> Candidates;
- for (User *U : I.users()) {
- Instruction *Inst = dyn_cast<Instruction>(U);
- if (!Inst)
- continue;
-
- // May cover a little bit more than the
- // above pattern.
- if (auto *Icmp1 = dyn_cast<ICmpInst>(Inst)) {
- Value *Icmp1Op1 = Icmp1->getOperand(1);
- if (!isa<Constant>(Icmp1Op1))
- return false;
- isCandidate = true;
- continue;
- }
-
- // Ignore the use in the same basic block as the definition.
- if (Inst->getParent() == I.getParent())
- continue;
-
- // use in a different basic block, If there is a call or
- // load/store insn before this instruction in this basic
- // block. Most likely it cannot be hoisted out. Skip it.
- for (auto &I2 : *Inst->getParent()) {
- if (dyn_cast<CallInst>(&I2))
- return false;
- if (dyn_cast<LoadInst>(&I2) || dyn_cast<StoreInst>(&I2))
- return false;
- if (&I2 == Inst)
- break;
- }
-
- // It should be used in a GEP or a simple arithmetic like
- // ZEXT/SEXT which is used for GEP.
- if (Inst->getOpcode() == Instruction::ZExt ||
- Inst->getOpcode() == Instruction::SExt) {
- PassThroughInfo Info(&I, Inst, 0);
- Candidates.push_back(Info);
- } else if (auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
- // traverse GEP inst to find Use operand index
- unsigned i, e;
- for (i = 1, e = GI->getNumOperands(); i != e; ++i) {
- Value *V = GI->getOperand(i);
- if (V == &I)
- break;
- }
- if (i == e)
- continue;
-
- PassThroughInfo Info(&I, GI, i);
- Candidates.push_back(Info);
- }
- }
-
- if (!isCandidate || Candidates.empty())
- return false;
-
- llvm::append_range(PassThroughs, Candidates);
- return true;
-}
-
-void BPFAdjustOptImpl::adjustBasicBlock(BasicBlock &BB) {
- if (!DisableBPFserializeICMP && serializeICMPCrossBB(BB))
- return;
-}
-
-void BPFAdjustOptImpl::adjustInst(Instruction &I) {
- if (!DisableBPFserializeICMP && serializeICMPInBB(I))
- return;
- if (!DisableBPFavoidSpeculation && avoidSpeculation(I))
- return;
-}
-
-PreservedAnalyses BPFAdjustOptPass::run(Module &M, ModuleAnalysisManager &AM) {
- return BPFAdjustOptImpl(&M).run() ? PreservedAnalyses::none()
- : PreservedAnalyses::all();
-}
+//===---------------- BPFAdjustOpt.cpp - Adjust Optimization --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Adjust optimization to make the code more kernel verifier friendly.
+//
+//===----------------------------------------------------------------------===//
+
+#include "BPF.h"
+#include "BPFCORE.h"
+#include "BPFTargetMachine.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/User.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Pass.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+
+#define DEBUG_TYPE "bpf-adjust-opt"
+
+using namespace llvm;
+
+static cl::opt<bool>
+ DisableBPFserializeICMP("bpf-disable-serialize-icmp", cl::Hidden,
+ cl::desc("BPF: Disable Serializing ICMP insns."),
+ cl::init(false));
+
+static cl::opt<bool> DisableBPFavoidSpeculation(
+ "bpf-disable-avoid-speculation", cl::Hidden,
+ cl::desc("BPF: Disable Avoiding Speculative Code Motion."),
+ cl::init(false));
+
+namespace {
+
+class BPFAdjustOpt final : public ModulePass {
+public:
+ static char ID;
+
+ BPFAdjustOpt() : ModulePass(ID) {}
+ bool runOnModule(Module &M) override;
+};
+
+class BPFAdjustOptImpl {
+ struct PassThroughInfo {
+ Instruction *Input;
+ Instruction *UsedInst;
+ uint32_t OpIdx;
+ PassThroughInfo(Instruction *I, Instruction *U, uint32_t Idx)
+ : Input(I), UsedInst(U), OpIdx(Idx) {}
+ };
+
+public:
+ BPFAdjustOptImpl(Module *M) : M(M) {}
+
+ bool run();
+
+private:
+ Module *M;
+ SmallVector<PassThroughInfo, 16> PassThroughs;
+
+ void adjustBasicBlock(BasicBlock &BB);
+ bool serializeICMPCrossBB(BasicBlock &BB);
+ void adjustInst(Instruction &I);
+ bool serializeICMPInBB(Instruction &I);
+ bool avoidSpeculation(Instruction &I);
+ bool insertPassThrough();
+};
+
+} // End anonymous namespace
+
+char BPFAdjustOpt::ID = 0;
+INITIALIZE_PASS(BPFAdjustOpt, "bpf-adjust-opt", "BPF Adjust Optimization",
+ false, false)
+
+ModulePass *llvm::createBPFAdjustOpt() { return new BPFAdjustOpt(); }
+
+bool BPFAdjustOpt::runOnModule(Module &M) { return BPFAdjustOptImpl(&M).run(); }
+
+bool BPFAdjustOptImpl::run() {
+ for (Function &F : *M)
+ for (auto &BB : F) {
+ adjustBasicBlock(BB);
+ for (auto &I : BB)
+ adjustInst(I);
+ }
+
+ return insertPassThrough();
+}
+
+bool BPFAdjustOptImpl::insertPassThrough() {
+ for (auto &Info : PassThroughs) {
+ auto *CI = BPFCoreSharedInfo::insertPassThrough(
+ M, Info.UsedInst->getParent(), Info.Input, Info.UsedInst);
+ Info.UsedInst->setOperand(Info.OpIdx, CI);
+ }
+
+ return !PassThroughs.empty();
+}
+
+// To avoid combining conditionals in the same basic block by
+// instrcombine optimization.
+bool BPFAdjustOptImpl::serializeICMPInBB(Instruction &I) {
+ // For:
+ // comp1 = icmp <opcode> ...;
+ // comp2 = icmp <opcode> ...;
+ // ... or comp1 comp2 ...
+ // changed to:
+ // comp1 = icmp <opcode> ...;
+ // comp2 = icmp <opcode> ...;
+ // new_comp1 = __builtin_bpf_passthrough(seq_num, comp1)
+ // ... or new_comp1 comp2 ...
+ if (I.getOpcode() != Instruction::Or)
+ return false;
+ auto *Icmp1 = dyn_cast<ICmpInst>(I.getOperand(0));
+ if (!Icmp1)
+ return false;
+ auto *Icmp2 = dyn_cast<ICmpInst>(I.getOperand(1));
+ if (!Icmp2)
+ return false;
+
+ Value *Icmp1Op0 = Icmp1->getOperand(0);
+ Value *Icmp2Op0 = Icmp2->getOperand(0);
+ if (Icmp1Op0 != Icmp2Op0)
+ return false;
+
+ // Now we got two icmp instructions which feed into
+ // an "or" instruction.
+ PassThroughInfo Info(Icmp1, &I, 0);
+ PassThroughs.push_back(Info);
+ return true;
+}
+
+// To avoid combining conditionals in the same basic block by
+// instrcombine optimization.
+bool BPFAdjustOptImpl::serializeICMPCrossBB(BasicBlock &BB) {
+ // For:
+ // B1:
+ // comp1 = icmp <opcode> ...;
+ // if (comp1) goto B2 else B3;
+ // B2:
+ // comp2 = icmp <opcode> ...;
+ // if (comp2) goto B4 else B5;
+ // B4:
+ // ...
+ // changed to:
+ // B1:
+ // comp1 = icmp <opcode> ...;
+ // comp1 = __builtin_bpf_passthrough(seq_num, comp1);
+ // if (comp1) goto B2 else B3;
+ // B2:
+ // comp2 = icmp <opcode> ...;
+ // if (comp2) goto B4 else B5;
+ // B4:
+ // ...
+
+ // Check basic predecessors, if two of them (say B1, B2) are using
+ // icmp instructions to generate conditions and one is the predesessor
+ // of another (e.g., B1 is the predecessor of B2). Add a passthrough
+ // barrier after icmp inst of block B1.
+ BasicBlock *B2 = BB.getSinglePredecessor();
+ if (!B2)
+ return false;
+
+ BasicBlock *B1 = B2->getSinglePredecessor();
+ if (!B1)
+ return false;
+
+ Instruction *TI = B2->getTerminator();
+ auto *BI = dyn_cast<BranchInst>(TI);
+ if (!BI || !BI->isConditional())
+ return false;
+ auto *Cond = dyn_cast<ICmpInst>(BI->getCondition());
+ if (!Cond || B2->getFirstNonPHI() != Cond)
+ return false;
+ Value *B2Op0 = Cond->getOperand(0);
+ auto Cond2Op = Cond->getPredicate();
+
+ TI = B1->getTerminator();
+ BI = dyn_cast<BranchInst>(TI);
+ if (!BI || !BI->isConditional())
+ return false;
+ Cond = dyn_cast<ICmpInst>(BI->getCondition());
+ if (!Cond)
+ return false;
+ Value *B1Op0 = Cond->getOperand(0);
+ auto Cond1Op = Cond->getPredicate();
+
+ if (B1Op0 != B2Op0)
+ return false;
+
+ if (Cond1Op == ICmpInst::ICMP_SGT || Cond1Op == ICmpInst::ICMP_SGE) {
+ if (Cond2Op != ICmpInst::ICMP_SLT && Cond1Op != ICmpInst::ICMP_SLE)
+ return false;
+ } else if (Cond1Op == ICmpInst::ICMP_SLT || Cond1Op == ICmpInst::ICMP_SLE) {
+ if (Cond2Op != ICmpInst::ICMP_SGT && Cond1Op != ICmpInst::ICMP_SGE)
+ return false;
+ } else {
+ return false;
+ }
+
+ PassThroughInfo Info(Cond, BI, 0);
+ PassThroughs.push_back(Info);
+
+ return true;
+}
+
+// To avoid speculative hoisting certain computations out of
+// a basic block.
+bool BPFAdjustOptImpl::avoidSpeculation(Instruction &I) {
+ if (auto *LdInst = dyn_cast<LoadInst>(&I)) {
+ if (auto *GV = dyn_cast<GlobalVariable>(LdInst->getOperand(0))) {
+ if (GV->hasAttribute(BPFCoreSharedInfo::AmaAttr) ||
+ GV->hasAttribute(BPFCoreSharedInfo::TypeIdAttr))
+ return false;
+ }
+ }
+
+ if (!isa<LoadInst>(&I) && !isa<CallInst>(&I))
+ return false;
+
+ // For:
+ // B1:
+ // var = ...
+ // ...
+ // /* icmp may not be in the same block as var = ... */
+ // comp1 = icmp <opcode> var, <const>;
+ // if (comp1) goto B2 else B3;
+ // B2:
+ // ... var ...
+ // change to:
+ // B1:
+ // var = ...
+ // ...
+ // /* icmp may not be in the same block as var = ... */
+ // comp1 = icmp <opcode> var, <const>;
+ // if (comp1) goto B2 else B3;
+ // B2:
+ // var = __builtin_bpf_passthrough(seq_num, var);
+ // ... var ...
+ bool isCandidate = false;
+ SmallVector<PassThroughInfo, 4> Candidates;
+ for (User *U : I.users()) {
+ Instruction *Inst = dyn_cast<Instruction>(U);
+ if (!Inst)
+ continue;
+
+ // May cover a little bit more than the
+ // above pattern.
+ if (auto *Icmp1 = dyn_cast<ICmpInst>(Inst)) {
+ Value *Icmp1Op1 = Icmp1->getOperand(1);
+ if (!isa<Constant>(Icmp1Op1))
+ return false;
+ isCandidate = true;
+ continue;
+ }
+
+ // Ignore the use in the same basic block as the definition.
+ if (Inst->getParent() == I.getParent())
+ continue;
+
+ // use in a different basic block, If there is a call or
+ // load/store insn before this instruction in this basic
+ // block. Most likely it cannot be hoisted out. Skip it.
+ for (auto &I2 : *Inst->getParent()) {
+ if (dyn_cast<CallInst>(&I2))
+ return false;
+ if (dyn_cast<LoadInst>(&I2) || dyn_cast<StoreInst>(&I2))
+ return false;
+ if (&I2 == Inst)
+ break;
+ }
+
+ // It should be used in a GEP or a simple arithmetic like
+ // ZEXT/SEXT which is used for GEP.
+ if (Inst->getOpcode() == Instruction::ZExt ||
+ Inst->getOpcode() == Instruction::SExt) {
+ PassThroughInfo Info(&I, Inst, 0);
+ Candidates.push_back(Info);
+ } else if (auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
+ // traverse GEP inst to find Use operand index
+ unsigned i, e;
+ for (i = 1, e = GI->getNumOperands(); i != e; ++i) {
+ Value *V = GI->getOperand(i);
+ if (V == &I)
+ break;
+ }
+ if (i == e)
+ continue;
+
+ PassThroughInfo Info(&I, GI, i);
+ Candidates.push_back(Info);
+ }
+ }
+
+ if (!isCandidate || Candidates.empty())
+ return false;
+
+ llvm::append_range(PassThroughs, Candidates);
+ return true;
+}
+
+void BPFAdjustOptImpl::adjustBasicBlock(BasicBlock &BB) {
+ if (!DisableBPFserializeICMP && serializeICMPCrossBB(BB))
+ return;
+}
+
+void BPFAdjustOptImpl::adjustInst(Instruction &I) {
+ if (!DisableBPFserializeICMP && serializeICMPInBB(I))
+ return;
+ if (!DisableBPFavoidSpeculation && avoidSpeculation(I))
+ return;
+}
+
+PreservedAnalyses BPFAdjustOptPass::run(Module &M, ModuleAnalysisManager &AM) {
+ return BPFAdjustOptImpl(&M).run() ? PreservedAnalyses::none()
+ : PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Target/BPF/BPFCORE.h b/contrib/libs/llvm12/lib/Target/BPF/BPFCORE.h
index c7692786d4..0c50441248 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/BPFCORE.h
+++ b/contrib/libs/llvm12/lib/Target/BPF/BPFCORE.h
@@ -13,10 +13,10 @@
namespace llvm {
-class BasicBlock;
-class Instruction;
-class Module;
-
+class BasicBlock;
+class Instruction;
+class Module;
+
class BPFCoreSharedInfo {
public:
enum PatchableRelocKind : uint32_t {
@@ -28,10 +28,10 @@ public:
FIELD_RSHIFT_U64,
BTF_TYPE_ID_LOCAL,
BTF_TYPE_ID_REMOTE,
- TYPE_EXISTENCE,
- TYPE_SIZE,
- ENUM_VALUE_EXISTENCE,
- ENUM_VALUE,
+ TYPE_EXISTENCE,
+ TYPE_SIZE,
+ ENUM_VALUE_EXISTENCE,
+ ENUM_VALUE,
MAX_FIELD_RELOC_KIND,
};
@@ -43,32 +43,32 @@ public:
MAX_BTF_TYPE_ID_FLAG,
};
- enum PreserveTypeInfo : uint32_t {
- PRESERVE_TYPE_INFO_EXISTENCE = 0,
- PRESERVE_TYPE_INFO_SIZE,
-
- MAX_PRESERVE_TYPE_INFO_FLAG,
- };
-
- enum PreserveEnumValue : uint32_t {
- PRESERVE_ENUM_VALUE_EXISTENCE = 0,
- PRESERVE_ENUM_VALUE,
-
- MAX_PRESERVE_ENUM_VALUE_FLAG,
- };
-
+ enum PreserveTypeInfo : uint32_t {
+ PRESERVE_TYPE_INFO_EXISTENCE = 0,
+ PRESERVE_TYPE_INFO_SIZE,
+
+ MAX_PRESERVE_TYPE_INFO_FLAG,
+ };
+
+ enum PreserveEnumValue : uint32_t {
+ PRESERVE_ENUM_VALUE_EXISTENCE = 0,
+ PRESERVE_ENUM_VALUE,
+
+ MAX_PRESERVE_ENUM_VALUE_FLAG,
+ };
+
/// The attribute attached to globals representing a field access
static constexpr StringRef AmaAttr = "btf_ama";
/// The attribute attached to globals representing a type id
static constexpr StringRef TypeIdAttr = "btf_type_id";
-
- /// llvm.bpf.passthrough builtin seq number
- static uint32_t SeqNum;
-
- /// Insert a bpf passthrough builtin function.
- static Instruction *insertPassThrough(Module *M, BasicBlock *BB,
- Instruction *Input,
- Instruction *Before);
+
+ /// llvm.bpf.passthrough builtin seq number
+ static uint32_t SeqNum;
+
+ /// Insert a bpf passthrough builtin function.
+ static Instruction *insertPassThrough(Module *M, BasicBlock *BB,
+ Instruction *Input,
+ Instruction *Before);
};
} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/Target/BPF/BPFCheckAndAdjustIR.cpp b/contrib/libs/llvm12/lib/Target/BPF/BPFCheckAndAdjustIR.cpp
index c829f923b1..5239218ad0 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/BPFCheckAndAdjustIR.cpp
+++ b/contrib/libs/llvm12/lib/Target/BPF/BPFCheckAndAdjustIR.cpp
@@ -1,130 +1,130 @@
-//===------------ BPFCheckAndAdjustIR.cpp - Check and Adjust IR -----------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Check IR and adjust IR for verifier friendly codes.
-// The following are done for IR checking:
-// - no relocation globals in PHI node.
-// The following are done for IR adjustment:
-// - remove __builtin_bpf_passthrough builtins. Target independent IR
-// optimizations are done and those builtins can be removed.
-//
-//===----------------------------------------------------------------------===//
-
-#include "BPF.h"
-#include "BPFCORE.h"
-#include "BPFTargetMachine.h"
-#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/GlobalVariable.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/Type.h"
-#include "llvm/IR/User.h"
-#include "llvm/IR/Value.h"
-#include "llvm/Pass.h"
-#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-
-#define DEBUG_TYPE "bpf-check-and-opt-ir"
-
-using namespace llvm;
-
-namespace {
-
-class BPFCheckAndAdjustIR final : public ModulePass {
- bool runOnModule(Module &F) override;
-
-public:
- static char ID;
- BPFCheckAndAdjustIR() : ModulePass(ID) {}
-
-private:
- void checkIR(Module &M);
- bool adjustIR(Module &M);
- bool removePassThroughBuiltin(Module &M);
-};
-} // End anonymous namespace
-
-char BPFCheckAndAdjustIR::ID = 0;
-INITIALIZE_PASS(BPFCheckAndAdjustIR, DEBUG_TYPE, "BPF Check And Adjust IR",
- false, false)
-
-ModulePass *llvm::createBPFCheckAndAdjustIR() {
- return new BPFCheckAndAdjustIR();
-}
-
-void BPFCheckAndAdjustIR::checkIR(Module &M) {
- // Ensure relocation global won't appear in PHI node
- // This may happen if the compiler generated the following code:
- // B1:
- // g1 = @llvm.skb_buff:0:1...
- // ...
- // goto B_COMMON
- // B2:
- // g2 = @llvm.skb_buff:0:2...
- // ...
- // goto B_COMMON
- // B_COMMON:
- // g = PHI(g1, g2)
- // x = load g
- // ...
- // If anything likes the above "g = PHI(g1, g2)", issue a fatal error.
- for (Function &F : M)
- for (auto &BB : F)
- for (auto &I : BB) {
- PHINode *PN = dyn_cast<PHINode>(&I);
- if (!PN || PN->use_empty())
- continue;
- for (int i = 0, e = PN->getNumIncomingValues(); i < e; ++i) {
- auto *GV = dyn_cast<GlobalVariable>(PN->getIncomingValue(i));
- if (!GV)
- continue;
- if (GV->hasAttribute(BPFCoreSharedInfo::AmaAttr) ||
- GV->hasAttribute(BPFCoreSharedInfo::TypeIdAttr))
- report_fatal_error("relocation global in PHI node");
- }
- }
-}
-
-bool BPFCheckAndAdjustIR::removePassThroughBuiltin(Module &M) {
- // Remove __builtin_bpf_passthrough()'s which are used to prevent
- // certain IR optimizations. Now major IR optimizations are done,
- // remove them.
- bool Changed = false;
- CallInst *ToBeDeleted = nullptr;
- for (Function &F : M)
- for (auto &BB : F)
- for (auto &I : BB) {
- if (ToBeDeleted) {
- ToBeDeleted->eraseFromParent();
- ToBeDeleted = nullptr;
- }
-
- auto *Call = dyn_cast<CallInst>(&I);
- if (!Call)
- continue;
- auto *GV = dyn_cast<GlobalValue>(Call->getCalledOperand());
- if (!GV)
- continue;
- if (!GV->getName().startswith("llvm.bpf.passthrough"))
- continue;
- Changed = true;
- Value *Arg = Call->getArgOperand(1);
- Call->replaceAllUsesWith(Arg);
- ToBeDeleted = Call;
- }
- return Changed;
-}
-
-bool BPFCheckAndAdjustIR::adjustIR(Module &M) {
- return removePassThroughBuiltin(M);
-}
-
-bool BPFCheckAndAdjustIR::runOnModule(Module &M) {
- checkIR(M);
- return adjustIR(M);
-}
+//===------------ BPFCheckAndAdjustIR.cpp - Check and Adjust IR -----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Check IR and adjust IR for verifier friendly codes.
+// The following are done for IR checking:
+// - no relocation globals in PHI node.
+// The following are done for IR adjustment:
+// - remove __builtin_bpf_passthrough builtins. Target independent IR
+// optimizations are done and those builtins can be removed.
+//
+//===----------------------------------------------------------------------===//
+
+#include "BPF.h"
+#include "BPFCORE.h"
+#include "BPFTargetMachine.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/User.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Pass.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+
+#define DEBUG_TYPE "bpf-check-and-opt-ir"
+
+using namespace llvm;
+
+namespace {
+
+class BPFCheckAndAdjustIR final : public ModulePass {
+ bool runOnModule(Module &F) override;
+
+public:
+ static char ID;
+ BPFCheckAndAdjustIR() : ModulePass(ID) {}
+
+private:
+ void checkIR(Module &M);
+ bool adjustIR(Module &M);
+ bool removePassThroughBuiltin(Module &M);
+};
+} // End anonymous namespace
+
+char BPFCheckAndAdjustIR::ID = 0;
+INITIALIZE_PASS(BPFCheckAndAdjustIR, DEBUG_TYPE, "BPF Check And Adjust IR",
+ false, false)
+
+ModulePass *llvm::createBPFCheckAndAdjustIR() {
+ return new BPFCheckAndAdjustIR();
+}
+
+void BPFCheckAndAdjustIR::checkIR(Module &M) {
+ // Ensure relocation global won't appear in PHI node
+ // This may happen if the compiler generated the following code:
+ // B1:
+ // g1 = @llvm.skb_buff:0:1...
+ // ...
+ // goto B_COMMON
+ // B2:
+ // g2 = @llvm.skb_buff:0:2...
+ // ...
+ // goto B_COMMON
+ // B_COMMON:
+ // g = PHI(g1, g2)
+ // x = load g
+ // ...
+ // If anything likes the above "g = PHI(g1, g2)", issue a fatal error.
+ for (Function &F : M)
+ for (auto &BB : F)
+ for (auto &I : BB) {
+ PHINode *PN = dyn_cast<PHINode>(&I);
+ if (!PN || PN->use_empty())
+ continue;
+ for (int i = 0, e = PN->getNumIncomingValues(); i < e; ++i) {
+ auto *GV = dyn_cast<GlobalVariable>(PN->getIncomingValue(i));
+ if (!GV)
+ continue;
+ if (GV->hasAttribute(BPFCoreSharedInfo::AmaAttr) ||
+ GV->hasAttribute(BPFCoreSharedInfo::TypeIdAttr))
+ report_fatal_error("relocation global in PHI node");
+ }
+ }
+}
+
+bool BPFCheckAndAdjustIR::removePassThroughBuiltin(Module &M) {
+ // Remove __builtin_bpf_passthrough()'s which are used to prevent
+ // certain IR optimizations. Now major IR optimizations are done,
+ // remove them.
+ bool Changed = false;
+ CallInst *ToBeDeleted = nullptr;
+ for (Function &F : M)
+ for (auto &BB : F)
+ for (auto &I : BB) {
+ if (ToBeDeleted) {
+ ToBeDeleted->eraseFromParent();
+ ToBeDeleted = nullptr;
+ }
+
+ auto *Call = dyn_cast<CallInst>(&I);
+ if (!Call)
+ continue;
+ auto *GV = dyn_cast<GlobalValue>(Call->getCalledOperand());
+ if (!GV)
+ continue;
+ if (!GV->getName().startswith("llvm.bpf.passthrough"))
+ continue;
+ Changed = true;
+ Value *Arg = Call->getArgOperand(1);
+ Call->replaceAllUsesWith(Arg);
+ ToBeDeleted = Call;
+ }
+ return Changed;
+}
+
+bool BPFCheckAndAdjustIR::adjustIR(Module &M) {
+ return removePassThroughBuiltin(M);
+}
+
+bool BPFCheckAndAdjustIR::runOnModule(Module &M) {
+ checkIR(M);
+ return adjustIR(M);
+}
diff --git a/contrib/libs/llvm12/lib/Target/BPF/BPFInstrFormats.td b/contrib/libs/llvm12/lib/Target/BPF/BPFInstrFormats.td
index 0601b400c4..a809065014 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/BPFInstrFormats.td
+++ b/contrib/libs/llvm12/lib/Target/BPF/BPFInstrFormats.td
@@ -44,9 +44,9 @@ def BPF_MOV : BPFArithOp<0xb>;
def BPF_ARSH : BPFArithOp<0xc>;
def BPF_END : BPFArithOp<0xd>;
-def BPF_XCHG : BPFArithOp<0xe>;
-def BPF_CMPXCHG : BPFArithOp<0xf>;
-
+def BPF_XCHG : BPFArithOp<0xe>;
+def BPF_CMPXCHG : BPFArithOp<0xf>;
+
class BPFEndDir<bits<1> val> {
bits<1> Value = val;
}
@@ -89,14 +89,14 @@ def BPF_IMM : BPFModeModifer<0x0>;
def BPF_ABS : BPFModeModifer<0x1>;
def BPF_IND : BPFModeModifer<0x2>;
def BPF_MEM : BPFModeModifer<0x3>;
-def BPF_ATOMIC : BPFModeModifer<0x6>;
-
-class BPFAtomicFlag<bits<4> val> {
- bits<4> Value = val;
-}
-
-def BPF_FETCH : BPFAtomicFlag<0x1>;
-
+def BPF_ATOMIC : BPFModeModifer<0x6>;
+
+class BPFAtomicFlag<bits<4> val> {
+ bits<4> Value = val;
+}
+
+def BPF_FETCH : BPFAtomicFlag<0x1>;
+
class InstBPF<dag outs, dag ins, string asmstr, list<dag> pattern>
: Instruction {
field bits<64> Inst;
diff --git a/contrib/libs/llvm12/lib/Target/BPF/BPFInstrInfo.td b/contrib/libs/llvm12/lib/Target/BPF/BPFInstrInfo.td
index b520ee7121..082e1f4a92 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/BPFInstrInfo.td
+++ b/contrib/libs/llvm12/lib/Target/BPF/BPFInstrInfo.td
@@ -617,9 +617,9 @@ let Predicates = [BPFNoALU32] in {
def : Pat<(i64 (extloadi32 ADDRri:$src)), (i64 (LDW ADDRri:$src))>;
}
-// Atomic XADD for BPFNoALU32
+// Atomic XADD for BPFNoALU32
class XADD<BPFWidthModifer SizeOp, string OpcodeStr, PatFrag OpNode>
- : TYPE_LD_ST<BPF_ATOMIC.Value, SizeOp.Value,
+ : TYPE_LD_ST<BPF_ATOMIC.Value, SizeOp.Value,
(outs GPR:$dst),
(ins MEMri:$addr, GPR:$val),
"lock *("#OpcodeStr#" *)($addr) += $val",
@@ -630,88 +630,88 @@ class XADD<BPFWidthModifer SizeOp, string OpcodeStr, PatFrag OpNode>
let Inst{51-48} = addr{19-16}; // base reg
let Inst{55-52} = dst;
let Inst{47-32} = addr{15-0}; // offset
- let Inst{7-4} = BPF_ADD.Value;
+ let Inst{7-4} = BPF_ADD.Value;
let BPFClass = BPF_STX;
}
-let Constraints = "$dst = $val" in {
- let Predicates = [BPFNoALU32] in {
- def XADDW : XADD<BPF_W, "u32", atomic_load_add_32>;
- }
-}
-
-// Atomic add, and, or, xor
-class ATOMIC_NOFETCH<BPFArithOp Opc, string Opstr>
- : TYPE_LD_ST<BPF_ATOMIC.Value, BPF_DW.Value,
- (outs GPR:$dst),
- (ins MEMri:$addr, GPR:$val),
- "lock *(u64 *)($addr) " #Opstr# "= $val",
- []> {
- bits<4> dst;
- bits<20> addr;
-
- let Inst{51-48} = addr{19-16}; // base reg
- let Inst{55-52} = dst;
- let Inst{47-32} = addr{15-0}; // offset
- let Inst{7-4} = Opc.Value;
- let BPFClass = BPF_STX;
-}
-
-class ATOMIC32_NOFETCH<BPFArithOp Opc, string Opstr>
- : TYPE_LD_ST<BPF_ATOMIC.Value, BPF_W.Value,
+let Constraints = "$dst = $val" in {
+ let Predicates = [BPFNoALU32] in {
+ def XADDW : XADD<BPF_W, "u32", atomic_load_add_32>;
+ }
+}
+
+// Atomic add, and, or, xor
+class ATOMIC_NOFETCH<BPFArithOp Opc, string Opstr>
+ : TYPE_LD_ST<BPF_ATOMIC.Value, BPF_DW.Value,
+ (outs GPR:$dst),
+ (ins MEMri:$addr, GPR:$val),
+ "lock *(u64 *)($addr) " #Opstr# "= $val",
+ []> {
+ bits<4> dst;
+ bits<20> addr;
+
+ let Inst{51-48} = addr{19-16}; // base reg
+ let Inst{55-52} = dst;
+ let Inst{47-32} = addr{15-0}; // offset
+ let Inst{7-4} = Opc.Value;
+ let BPFClass = BPF_STX;
+}
+
+class ATOMIC32_NOFETCH<BPFArithOp Opc, string Opstr>
+ : TYPE_LD_ST<BPF_ATOMIC.Value, BPF_W.Value,
(outs GPR32:$dst),
(ins MEMri:$addr, GPR32:$val),
- "lock *(u32 *)($addr) " #Opstr# "= $val",
- []> {
- bits<4> dst;
- bits<20> addr;
-
- let Inst{51-48} = addr{19-16}; // base reg
- let Inst{55-52} = dst;
- let Inst{47-32} = addr{15-0}; // offset
- let Inst{7-4} = Opc.Value;
- let BPFClass = BPF_STX;
-}
-
-let Constraints = "$dst = $val" in {
- let Predicates = [BPFHasALU32], DecoderNamespace = "BPFALU32" in {
- def XADDW32 : ATOMIC32_NOFETCH<BPF_ADD, "+">;
- def XANDW32 : ATOMIC32_NOFETCH<BPF_AND, "&">;
- def XORW32 : ATOMIC32_NOFETCH<BPF_OR, "|">;
- def XXORW32 : ATOMIC32_NOFETCH<BPF_XOR, "^">;
- }
-
- def XADDD : ATOMIC_NOFETCH<BPF_ADD, "+">;
- def XANDD : ATOMIC_NOFETCH<BPF_AND, "&">;
- def XORD : ATOMIC_NOFETCH<BPF_OR, "|">;
- def XXORD : ATOMIC_NOFETCH<BPF_XOR, "^">;
-}
-
-// Atomic Fetch-and-<add, and, or, xor> operations
-class XFALU64<BPFWidthModifer SizeOp, BPFArithOp Opc, string OpcodeStr,
- string OpcStr, PatFrag OpNode>
- : TYPE_LD_ST<BPF_ATOMIC.Value, SizeOp.Value,
- (outs GPR:$dst),
- (ins MEMri:$addr, GPR:$val),
- "$dst = atomic_fetch_"#OpcStr#"(("#OpcodeStr#" *)($addr), $val)",
- [(set GPR:$dst, (OpNode ADDRri:$addr, GPR:$val))]> {
- bits<4> dst;
- bits<20> addr;
-
- let Inst{51-48} = addr{19-16}; // base reg
- let Inst{55-52} = dst;
- let Inst{47-32} = addr{15-0}; // offset
- let Inst{7-4} = Opc.Value;
- let Inst{3-0} = BPF_FETCH.Value;
- let BPFClass = BPF_STX;
-}
-
-class XFALU32<BPFWidthModifer SizeOp, BPFArithOp Opc, string OpcodeStr,
- string OpcStr, PatFrag OpNode>
- : TYPE_LD_ST<BPF_ATOMIC.Value, SizeOp.Value,
- (outs GPR32:$dst),
- (ins MEMri:$addr, GPR32:$val),
- "$dst = atomic_fetch_"#OpcStr#"(("#OpcodeStr#" *)($addr), $val)",
+ "lock *(u32 *)($addr) " #Opstr# "= $val",
+ []> {
+ bits<4> dst;
+ bits<20> addr;
+
+ let Inst{51-48} = addr{19-16}; // base reg
+ let Inst{55-52} = dst;
+ let Inst{47-32} = addr{15-0}; // offset
+ let Inst{7-4} = Opc.Value;
+ let BPFClass = BPF_STX;
+}
+
+let Constraints = "$dst = $val" in {
+ let Predicates = [BPFHasALU32], DecoderNamespace = "BPFALU32" in {
+ def XADDW32 : ATOMIC32_NOFETCH<BPF_ADD, "+">;
+ def XANDW32 : ATOMIC32_NOFETCH<BPF_AND, "&">;
+ def XORW32 : ATOMIC32_NOFETCH<BPF_OR, "|">;
+ def XXORW32 : ATOMIC32_NOFETCH<BPF_XOR, "^">;
+ }
+
+ def XADDD : ATOMIC_NOFETCH<BPF_ADD, "+">;
+ def XANDD : ATOMIC_NOFETCH<BPF_AND, "&">;
+ def XORD : ATOMIC_NOFETCH<BPF_OR, "|">;
+ def XXORD : ATOMIC_NOFETCH<BPF_XOR, "^">;
+}
+
+// Atomic Fetch-and-<add, and, or, xor> operations
+class XFALU64<BPFWidthModifer SizeOp, BPFArithOp Opc, string OpcodeStr,
+ string OpcStr, PatFrag OpNode>
+ : TYPE_LD_ST<BPF_ATOMIC.Value, SizeOp.Value,
+ (outs GPR:$dst),
+ (ins MEMri:$addr, GPR:$val),
+ "$dst = atomic_fetch_"#OpcStr#"(("#OpcodeStr#" *)($addr), $val)",
+ [(set GPR:$dst, (OpNode ADDRri:$addr, GPR:$val))]> {
+ bits<4> dst;
+ bits<20> addr;
+
+ let Inst{51-48} = addr{19-16}; // base reg
+ let Inst{55-52} = dst;
+ let Inst{47-32} = addr{15-0}; // offset
+ let Inst{7-4} = Opc.Value;
+ let Inst{3-0} = BPF_FETCH.Value;
+ let BPFClass = BPF_STX;
+}
+
+class XFALU32<BPFWidthModifer SizeOp, BPFArithOp Opc, string OpcodeStr,
+ string OpcStr, PatFrag OpNode>
+ : TYPE_LD_ST<BPF_ATOMIC.Value, SizeOp.Value,
+ (outs GPR32:$dst),
+ (ins MEMri:$addr, GPR32:$val),
+ "$dst = atomic_fetch_"#OpcStr#"(("#OpcodeStr#" *)($addr), $val)",
[(set GPR32:$dst, (OpNode ADDRri:$addr, GPR32:$val))]> {
bits<4> dst;
bits<20> addr;
@@ -719,119 +719,119 @@ class XFALU32<BPFWidthModifer SizeOp, BPFArithOp Opc, string OpcodeStr,
let Inst{51-48} = addr{19-16}; // base reg
let Inst{55-52} = dst;
let Inst{47-32} = addr{15-0}; // offset
- let Inst{7-4} = Opc.Value;
- let Inst{3-0} = BPF_FETCH.Value;
+ let Inst{7-4} = Opc.Value;
+ let Inst{3-0} = BPF_FETCH.Value;
let BPFClass = BPF_STX;
}
let Constraints = "$dst = $val" in {
- let Predicates = [BPFHasALU32], DecoderNamespace = "BPFALU32" in {
- def XFADDW32 : XFALU32<BPF_W, BPF_ADD, "u32", "add", atomic_load_add_32>;
- def XFANDW32 : XFALU32<BPF_W, BPF_AND, "u32", "and", atomic_load_and_32>;
- def XFORW32 : XFALU32<BPF_W, BPF_OR, "u32", "or", atomic_load_or_32>;
- def XFXORW32 : XFALU32<BPF_W, BPF_XOR, "u32", "xor", atomic_load_xor_32>;
+ let Predicates = [BPFHasALU32], DecoderNamespace = "BPFALU32" in {
+ def XFADDW32 : XFALU32<BPF_W, BPF_ADD, "u32", "add", atomic_load_add_32>;
+ def XFANDW32 : XFALU32<BPF_W, BPF_AND, "u32", "and", atomic_load_and_32>;
+ def XFORW32 : XFALU32<BPF_W, BPF_OR, "u32", "or", atomic_load_or_32>;
+ def XFXORW32 : XFALU32<BPF_W, BPF_XOR, "u32", "xor", atomic_load_xor_32>;
}
- def XFADDD : XFALU64<BPF_DW, BPF_ADD, "u64", "add", atomic_load_add_64>;
- def XFANDD : XFALU64<BPF_DW, BPF_AND, "u64", "and", atomic_load_and_64>;
- def XFORD : XFALU64<BPF_DW, BPF_OR, "u64", "or", atomic_load_or_64>;
- def XFXORD : XFALU64<BPF_DW, BPF_XOR, "u64", "xor", atomic_load_xor_64>;
-}
-
-// atomic_load_sub can be represented as a neg followed
-// by an atomic_load_add.
-def : Pat<(atomic_load_sub_32 ADDRri:$addr, GPR32:$val),
- (XFADDW32 ADDRri:$addr, (NEG_32 GPR32:$val))>;
-def : Pat<(atomic_load_sub_64 ADDRri:$addr, GPR:$val),
- (XFADDD ADDRri:$addr, (NEG_64 GPR:$val))>;
-
-// Atomic Exchange
-class XCHG<BPFWidthModifer SizeOp, string OpcodeStr, PatFrag OpNode>
- : TYPE_LD_ST<BPF_ATOMIC.Value, SizeOp.Value,
- (outs GPR:$dst),
- (ins MEMri:$addr, GPR:$val),
- "$dst = xchg_"#OpcodeStr#"($addr, $val)",
- [(set GPR:$dst, (OpNode ADDRri:$addr,GPR:$val))]> {
- bits<4> dst;
- bits<20> addr;
-
- let Inst{51-48} = addr{19-16}; // base reg
- let Inst{55-52} = dst;
- let Inst{47-32} = addr{15-0}; // offset
- let Inst{7-4} = BPF_XCHG.Value;
- let Inst{3-0} = BPF_FETCH.Value;
- let BPFClass = BPF_STX;
-}
-
-class XCHG32<BPFWidthModifer SizeOp, string OpcodeStr, PatFrag OpNode>
- : TYPE_LD_ST<BPF_ATOMIC.Value, SizeOp.Value,
- (outs GPR32:$dst),
- (ins MEMri:$addr, GPR32:$val),
- "$dst = xchg32_"#OpcodeStr#"($addr, $val)",
- [(set GPR32:$dst, (OpNode ADDRri:$addr,GPR32:$val))]> {
- bits<4> dst;
- bits<20> addr;
-
- let Inst{51-48} = addr{19-16}; // base reg
- let Inst{55-52} = dst;
- let Inst{47-32} = addr{15-0}; // offset
- let Inst{7-4} = BPF_XCHG.Value;
- let Inst{3-0} = BPF_FETCH.Value;
- let BPFClass = BPF_STX;
-}
-
-let Constraints = "$dst = $val" in {
+ def XFADDD : XFALU64<BPF_DW, BPF_ADD, "u64", "add", atomic_load_add_64>;
+ def XFANDD : XFALU64<BPF_DW, BPF_AND, "u64", "and", atomic_load_and_64>;
+ def XFORD : XFALU64<BPF_DW, BPF_OR, "u64", "or", atomic_load_or_64>;
+ def XFXORD : XFALU64<BPF_DW, BPF_XOR, "u64", "xor", atomic_load_xor_64>;
+}
+
+// atomic_load_sub can be represented as a neg followed
+// by an atomic_load_add.
+def : Pat<(atomic_load_sub_32 ADDRri:$addr, GPR32:$val),
+ (XFADDW32 ADDRri:$addr, (NEG_32 GPR32:$val))>;
+def : Pat<(atomic_load_sub_64 ADDRri:$addr, GPR:$val),
+ (XFADDD ADDRri:$addr, (NEG_64 GPR:$val))>;
+
+// Atomic Exchange
+class XCHG<BPFWidthModifer SizeOp, string OpcodeStr, PatFrag OpNode>
+ : TYPE_LD_ST<BPF_ATOMIC.Value, SizeOp.Value,
+ (outs GPR:$dst),
+ (ins MEMri:$addr, GPR:$val),
+ "$dst = xchg_"#OpcodeStr#"($addr, $val)",
+ [(set GPR:$dst, (OpNode ADDRri:$addr,GPR:$val))]> {
+ bits<4> dst;
+ bits<20> addr;
+
+ let Inst{51-48} = addr{19-16}; // base reg
+ let Inst{55-52} = dst;
+ let Inst{47-32} = addr{15-0}; // offset
+ let Inst{7-4} = BPF_XCHG.Value;
+ let Inst{3-0} = BPF_FETCH.Value;
+ let BPFClass = BPF_STX;
+}
+
+class XCHG32<BPFWidthModifer SizeOp, string OpcodeStr, PatFrag OpNode>
+ : TYPE_LD_ST<BPF_ATOMIC.Value, SizeOp.Value,
+ (outs GPR32:$dst),
+ (ins MEMri:$addr, GPR32:$val),
+ "$dst = xchg32_"#OpcodeStr#"($addr, $val)",
+ [(set GPR32:$dst, (OpNode ADDRri:$addr,GPR32:$val))]> {
+ bits<4> dst;
+ bits<20> addr;
+
+ let Inst{51-48} = addr{19-16}; // base reg
+ let Inst{55-52} = dst;
+ let Inst{47-32} = addr{15-0}; // offset
+ let Inst{7-4} = BPF_XCHG.Value;
+ let Inst{3-0} = BPF_FETCH.Value;
+ let BPFClass = BPF_STX;
+}
+
+let Constraints = "$dst = $val" in {
let Predicates = [BPFHasALU32], DecoderNamespace = "BPFALU32" in {
- def XCHGW32 : XCHG32<BPF_W, "32", atomic_swap_32>;
+ def XCHGW32 : XCHG32<BPF_W, "32", atomic_swap_32>;
}
- def XCHGD : XCHG<BPF_DW, "64", atomic_swap_64>;
-}
-
-// Compare-And-Exchange
-class CMPXCHG<BPFWidthModifer SizeOp, string OpcodeStr, PatFrag OpNode>
- : TYPE_LD_ST<BPF_ATOMIC.Value, SizeOp.Value,
- (outs),
- (ins MEMri:$addr, GPR:$new),
- "r0 = cmpxchg_"#OpcodeStr#"($addr, r0, $new)",
- [(set R0, (OpNode ADDRri:$addr, R0, GPR:$new))]> {
- bits<4> new;
- bits<20> addr;
-
- let Inst{51-48} = addr{19-16}; // base reg
- let Inst{55-52} = new;
- let Inst{47-32} = addr{15-0}; // offset
- let Inst{7-4} = BPF_CMPXCHG.Value;
- let Inst{3-0} = BPF_FETCH.Value;
- let BPFClass = BPF_STX;
-}
-
-class CMPXCHG32<BPFWidthModifer SizeOp, string OpcodeStr, PatFrag OpNode>
- : TYPE_LD_ST<BPF_ATOMIC.Value, SizeOp.Value,
- (outs),
- (ins MEMri:$addr, GPR32:$new),
- "w0 = cmpxchg32_"#OpcodeStr#"($addr, w0, $new)",
- [(set W0, (OpNode ADDRri:$addr, W0, GPR32:$new))]> {
- bits<4> new;
- bits<20> addr;
-
- let Inst{51-48} = addr{19-16}; // base reg
- let Inst{55-52} = new;
- let Inst{47-32} = addr{15-0}; // offset
- let Inst{7-4} = BPF_CMPXCHG.Value;
- let Inst{3-0} = BPF_FETCH.Value;
- let BPFClass = BPF_STX;
-}
-
-let Predicates = [BPFHasALU32], Defs = [W0], Uses = [W0],
- DecoderNamespace = "BPFALU32" in {
- def CMPXCHGW32 : CMPXCHG32<BPF_W, "32", atomic_cmp_swap_32>;
-}
-
-let Defs = [R0], Uses = [R0] in {
- def CMPXCHGD : CMPXCHG<BPF_DW, "64", atomic_cmp_swap_64>;
-}
-
+ def XCHGD : XCHG<BPF_DW, "64", atomic_swap_64>;
+}
+
+// Compare-And-Exchange
+class CMPXCHG<BPFWidthModifer SizeOp, string OpcodeStr, PatFrag OpNode>
+ : TYPE_LD_ST<BPF_ATOMIC.Value, SizeOp.Value,
+ (outs),
+ (ins MEMri:$addr, GPR:$new),
+ "r0 = cmpxchg_"#OpcodeStr#"($addr, r0, $new)",
+ [(set R0, (OpNode ADDRri:$addr, R0, GPR:$new))]> {
+ bits<4> new;
+ bits<20> addr;
+
+ let Inst{51-48} = addr{19-16}; // base reg
+ let Inst{55-52} = new;
+ let Inst{47-32} = addr{15-0}; // offset
+ let Inst{7-4} = BPF_CMPXCHG.Value;
+ let Inst{3-0} = BPF_FETCH.Value;
+ let BPFClass = BPF_STX;
+}
+
+class CMPXCHG32<BPFWidthModifer SizeOp, string OpcodeStr, PatFrag OpNode>
+ : TYPE_LD_ST<BPF_ATOMIC.Value, SizeOp.Value,
+ (outs),
+ (ins MEMri:$addr, GPR32:$new),
+ "w0 = cmpxchg32_"#OpcodeStr#"($addr, w0, $new)",
+ [(set W0, (OpNode ADDRri:$addr, W0, GPR32:$new))]> {
+ bits<4> new;
+ bits<20> addr;
+
+ let Inst{51-48} = addr{19-16}; // base reg
+ let Inst{55-52} = new;
+ let Inst{47-32} = addr{15-0}; // offset
+ let Inst{7-4} = BPF_CMPXCHG.Value;
+ let Inst{3-0} = BPF_FETCH.Value;
+ let BPFClass = BPF_STX;
+}
+
+let Predicates = [BPFHasALU32], Defs = [W0], Uses = [W0],
+ DecoderNamespace = "BPFALU32" in {
+ def CMPXCHGW32 : CMPXCHG32<BPF_W, "32", atomic_cmp_swap_32>;
+}
+
+let Defs = [R0], Uses = [R0] in {
+ def CMPXCHGD : CMPXCHG<BPF_DW, "64", atomic_cmp_swap_64>;
+}
+
// bswap16, bswap32, bswap64
class BSWAP<bits<32> SizeOp, string OpcodeStr, BPFSrcType SrcType, list<dag> Pattern>
: TYPE_ALU_JMP<BPF_END.Value, SrcType.Value,
diff --git a/contrib/libs/llvm12/lib/Target/BPF/BPFMIChecking.cpp b/contrib/libs/llvm12/lib/Target/BPF/BPFMIChecking.cpp
index 5354a67571..4e24e3d911 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/BPFMIChecking.cpp
+++ b/contrib/libs/llvm12/lib/Target/BPF/BPFMIChecking.cpp
@@ -41,7 +41,7 @@ private:
// Initialize class variables.
void initialize(MachineFunction &MFParm);
- bool processAtomicInsts(void);
+ bool processAtomicInsts(void);
public:
@@ -49,7 +49,7 @@ public:
bool runOnMachineFunction(MachineFunction &MF) override {
if (!skipFunction(MF.getFunction())) {
initialize(MF);
- return processAtomicInsts();
+ return processAtomicInsts();
}
return false;
}
@@ -145,13 +145,13 @@ static bool hasLiveDefs(const MachineInstr &MI, const TargetRegisterInfo *TRI) {
// Otherwise, return true if any aliased SuperReg of GPR32 is not dead.
for (auto I : GPR32LiveDefs)
for (MCSuperRegIterator SR(I, TRI); SR.isValid(); ++SR)
- if (!llvm::is_contained(GPR64DeadDefs, *SR))
- return true;
+ if (!llvm::is_contained(GPR64DeadDefs, *SR))
+ return true;
return false;
}
-bool BPFMIPreEmitChecking::processAtomicInsts(void) {
+bool BPFMIPreEmitChecking::processAtomicInsts(void) {
for (MachineBasicBlock &MBB : *MF) {
for (MachineInstr &MI : MBB) {
if (MI.getOpcode() != BPF::XADDW &&
@@ -172,71 +172,71 @@ bool BPFMIPreEmitChecking::processAtomicInsts(void) {
}
}
- // Check return values of atomic_fetch_and_{add,and,or,xor}.
- // If the return is not used, the atomic_fetch_and_<op> instruction
- // is replaced with atomic_<op> instruction.
- MachineInstr *ToErase = nullptr;
- bool Changed = false;
- const BPFInstrInfo *TII = MF->getSubtarget<BPFSubtarget>().getInstrInfo();
- for (MachineBasicBlock &MBB : *MF) {
- for (MachineInstr &MI : MBB) {
- if (ToErase) {
- ToErase->eraseFromParent();
- ToErase = nullptr;
- }
-
- if (MI.getOpcode() != BPF::XFADDW32 && MI.getOpcode() != BPF::XFADDD &&
- MI.getOpcode() != BPF::XFANDW32 && MI.getOpcode() != BPF::XFANDD &&
- MI.getOpcode() != BPF::XFXORW32 && MI.getOpcode() != BPF::XFXORD &&
- MI.getOpcode() != BPF::XFORW32 && MI.getOpcode() != BPF::XFORD)
- continue;
-
- if (hasLiveDefs(MI, TRI))
- continue;
-
- LLVM_DEBUG(dbgs() << "Transforming "; MI.dump());
- unsigned newOpcode;
- switch (MI.getOpcode()) {
- case BPF::XFADDW32:
- newOpcode = BPF::XADDW32;
- break;
- case BPF::XFADDD:
- newOpcode = BPF::XADDD;
- break;
- case BPF::XFANDW32:
- newOpcode = BPF::XANDW32;
- break;
- case BPF::XFANDD:
- newOpcode = BPF::XANDD;
- break;
- case BPF::XFXORW32:
- newOpcode = BPF::XXORW32;
- break;
- case BPF::XFXORD:
- newOpcode = BPF::XXORD;
- break;
- case BPF::XFORW32:
- newOpcode = BPF::XORW32;
- break;
- case BPF::XFORD:
- newOpcode = BPF::XORD;
- break;
- default:
- llvm_unreachable("Incorrect Atomic Instruction Opcode");
- }
-
- BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(newOpcode))
- .add(MI.getOperand(0))
- .add(MI.getOperand(1))
- .add(MI.getOperand(2))
- .add(MI.getOperand(3));
-
- ToErase = &MI;
- Changed = true;
- }
- }
-
- return Changed;
+ // Check return values of atomic_fetch_and_{add,and,or,xor}.
+ // If the return is not used, the atomic_fetch_and_<op> instruction
+ // is replaced with atomic_<op> instruction.
+ MachineInstr *ToErase = nullptr;
+ bool Changed = false;
+ const BPFInstrInfo *TII = MF->getSubtarget<BPFSubtarget>().getInstrInfo();
+ for (MachineBasicBlock &MBB : *MF) {
+ for (MachineInstr &MI : MBB) {
+ if (ToErase) {
+ ToErase->eraseFromParent();
+ ToErase = nullptr;
+ }
+
+ if (MI.getOpcode() != BPF::XFADDW32 && MI.getOpcode() != BPF::XFADDD &&
+ MI.getOpcode() != BPF::XFANDW32 && MI.getOpcode() != BPF::XFANDD &&
+ MI.getOpcode() != BPF::XFXORW32 && MI.getOpcode() != BPF::XFXORD &&
+ MI.getOpcode() != BPF::XFORW32 && MI.getOpcode() != BPF::XFORD)
+ continue;
+
+ if (hasLiveDefs(MI, TRI))
+ continue;
+
+ LLVM_DEBUG(dbgs() << "Transforming "; MI.dump());
+ unsigned newOpcode;
+ switch (MI.getOpcode()) {
+ case BPF::XFADDW32:
+ newOpcode = BPF::XADDW32;
+ break;
+ case BPF::XFADDD:
+ newOpcode = BPF::XADDD;
+ break;
+ case BPF::XFANDW32:
+ newOpcode = BPF::XANDW32;
+ break;
+ case BPF::XFANDD:
+ newOpcode = BPF::XANDD;
+ break;
+ case BPF::XFXORW32:
+ newOpcode = BPF::XXORW32;
+ break;
+ case BPF::XFXORD:
+ newOpcode = BPF::XXORD;
+ break;
+ case BPF::XFORW32:
+ newOpcode = BPF::XORW32;
+ break;
+ case BPF::XFORD:
+ newOpcode = BPF::XORD;
+ break;
+ default:
+ llvm_unreachable("Incorrect Atomic Instruction Opcode");
+ }
+
+ BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(newOpcode))
+ .add(MI.getOperand(0))
+ .add(MI.getOperand(1))
+ .add(MI.getOperand(2))
+ .add(MI.getOperand(3));
+
+ ToErase = &MI;
+ Changed = true;
+ }
+ }
+
+ return Changed;
}
} // end default namespace
diff --git a/contrib/libs/llvm12/lib/Target/BPF/BPFMIPeephole.cpp b/contrib/libs/llvm12/lib/Target/BPF/BPFMIPeephole.cpp
index cf91a90278..354980e4bf 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/BPFMIPeephole.cpp
+++ b/contrib/libs/llvm12/lib/Target/BPF/BPFMIPeephole.cpp
@@ -475,9 +475,9 @@ bool BPFMIPeepholeTruncElim::eliminateTruncSeq(void) {
if (MI.getOpcode() == BPF::SRL_ri &&
MI.getOperand(2).getImm() == 32) {
SrcReg = MI.getOperand(1).getReg();
- if (!MRI->hasOneNonDBGUse(SrcReg))
- continue;
-
+ if (!MRI->hasOneNonDBGUse(SrcReg))
+ continue;
+
MI2 = MRI->getVRegDef(SrcReg);
DstReg = MI.getOperand(0).getReg();
diff --git a/contrib/libs/llvm12/lib/Target/BPF/BPFPreserveDIType.cpp b/contrib/libs/llvm12/lib/Target/BPF/BPFPreserveDIType.cpp
index ac396e5471..0348e2200a 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/BPFPreserveDIType.cpp
+++ b/contrib/libs/llvm12/lib/Target/BPF/BPFPreserveDIType.cpp
@@ -17,7 +17,7 @@
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
@@ -34,32 +34,32 @@ using namespace llvm;
namespace {
-static bool BPFPreserveDITypeImpl(Function &F) {
- LLVM_DEBUG(dbgs() << "********** preserve debuginfo type **********\n");
+static bool BPFPreserveDITypeImpl(Function &F) {
+ LLVM_DEBUG(dbgs() << "********** preserve debuginfo type **********\n");
- Module *M = F.getParent();
+ Module *M = F.getParent();
// Bail out if no debug info.
- if (M->debug_compile_units().empty())
+ if (M->debug_compile_units().empty())
return false;
std::vector<CallInst *> PreserveDITypeCalls;
- for (auto &BB : F) {
- for (auto &I : BB) {
- auto *Call = dyn_cast<CallInst>(&I);
- if (!Call)
- continue;
-
- const auto *GV = dyn_cast<GlobalValue>(Call->getCalledOperand());
- if (!GV)
- continue;
-
- if (GV->getName().startswith("llvm.bpf.btf.type.id")) {
- if (!Call->getMetadata(LLVMContext::MD_preserve_access_index))
- report_fatal_error(
- "Missing metadata for llvm.bpf.btf.type.id intrinsic");
- PreserveDITypeCalls.push_back(Call);
+ for (auto &BB : F) {
+ for (auto &I : BB) {
+ auto *Call = dyn_cast<CallInst>(&I);
+ if (!Call)
+ continue;
+
+ const auto *GV = dyn_cast<GlobalValue>(Call->getCalledOperand());
+ if (!GV)
+ continue;
+
+ if (GV->getName().startswith("llvm.bpf.btf.type.id")) {
+ if (!Call->getMetadata(LLVMContext::MD_preserve_access_index))
+ report_fatal_error(
+ "Missing metadata for llvm.bpf.btf.type.id intrinsic");
+ PreserveDITypeCalls.push_back(Call);
}
}
}
@@ -68,81 +68,81 @@ static bool BPFPreserveDITypeImpl(Function &F) {
return false;
std::string BaseName = "llvm.btf_type_id.";
- static int Count = 0;
+ static int Count = 0;
for (auto Call : PreserveDITypeCalls) {
- const ConstantInt *Flag = dyn_cast<ConstantInt>(Call->getArgOperand(1));
+ const ConstantInt *Flag = dyn_cast<ConstantInt>(Call->getArgOperand(1));
assert(Flag);
uint64_t FlagValue = Flag->getValue().getZExtValue();
if (FlagValue >= BPFCoreSharedInfo::MAX_BTF_TYPE_ID_FLAG)
report_fatal_error("Incorrect flag for llvm.bpf.btf.type.id intrinsic");
- MDNode *MD = Call->getMetadata(LLVMContext::MD_preserve_access_index);
-
+ MDNode *MD = Call->getMetadata(LLVMContext::MD_preserve_access_index);
+
uint32_t Reloc;
- if (FlagValue == BPFCoreSharedInfo::BTF_TYPE_ID_LOCAL_RELOC) {
+ if (FlagValue == BPFCoreSharedInfo::BTF_TYPE_ID_LOCAL_RELOC) {
Reloc = BPFCoreSharedInfo::BTF_TYPE_ID_LOCAL;
- } else {
+ } else {
Reloc = BPFCoreSharedInfo::BTF_TYPE_ID_REMOTE;
- DIType *Ty = cast<DIType>(MD);
- while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
- unsigned Tag = DTy->getTag();
- if (Tag != dwarf::DW_TAG_const_type &&
- Tag != dwarf::DW_TAG_volatile_type)
- break;
- Ty = DTy->getBaseType();
- }
-
- if (Ty->getName().empty())
- report_fatal_error("Empty type name for BTF_TYPE_ID_REMOTE reloc");
- MD = Ty;
- }
+ DIType *Ty = cast<DIType>(MD);
+ while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
+ unsigned Tag = DTy->getTag();
+ if (Tag != dwarf::DW_TAG_const_type &&
+ Tag != dwarf::DW_TAG_volatile_type)
+ break;
+ Ty = DTy->getBaseType();
+ }
+
+ if (Ty->getName().empty())
+ report_fatal_error("Empty type name for BTF_TYPE_ID_REMOTE reloc");
+ MD = Ty;
+ }
BasicBlock *BB = Call->getParent();
- IntegerType *VarType = Type::getInt64Ty(BB->getContext());
+ IntegerType *VarType = Type::getInt64Ty(BB->getContext());
std::string GVName = BaseName + std::to_string(Count) + "$" +
std::to_string(Reloc);
- GlobalVariable *GV = new GlobalVariable(
- *M, VarType, false, GlobalVariable::ExternalLinkage, NULL, GVName);
+ GlobalVariable *GV = new GlobalVariable(
+ *M, VarType, false, GlobalVariable::ExternalLinkage, NULL, GVName);
GV->addAttribute(BPFCoreSharedInfo::TypeIdAttr);
GV->setMetadata(LLVMContext::MD_preserve_access_index, MD);
// Load the global variable which represents the type info.
- auto *LDInst =
- new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "", Call);
- Instruction *PassThroughInst =
- BPFCoreSharedInfo::insertPassThrough(M, BB, LDInst, Call);
- Call->replaceAllUsesWith(PassThroughInst);
+ auto *LDInst =
+ new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "", Call);
+ Instruction *PassThroughInst =
+ BPFCoreSharedInfo::insertPassThrough(M, BB, LDInst, Call);
+ Call->replaceAllUsesWith(PassThroughInst);
Call->eraseFromParent();
Count++;
}
return true;
}
-
-class BPFPreserveDIType final : public FunctionPass {
- bool runOnFunction(Function &F) override;
-
-public:
- static char ID;
- BPFPreserveDIType() : FunctionPass(ID) {}
-};
-} // End anonymous namespace
-
-char BPFPreserveDIType::ID = 0;
-INITIALIZE_PASS(BPFPreserveDIType, DEBUG_TYPE, "BPF Preserve Debuginfo Type",
- false, false)
-
-FunctionPass *llvm::createBPFPreserveDIType() {
- return new BPFPreserveDIType();
-}
-
-bool BPFPreserveDIType::runOnFunction(Function &F) {
- return BPFPreserveDITypeImpl(F);
-}
-
-PreservedAnalyses BPFPreserveDITypePass::run(Function &F,
- FunctionAnalysisManager &AM) {
- return BPFPreserveDITypeImpl(F) ? PreservedAnalyses::none()
- : PreservedAnalyses::all();
-}
+
+class BPFPreserveDIType final : public FunctionPass {
+ bool runOnFunction(Function &F) override;
+
+public:
+ static char ID;
+ BPFPreserveDIType() : FunctionPass(ID) {}
+};
+} // End anonymous namespace
+
+char BPFPreserveDIType::ID = 0;
+INITIALIZE_PASS(BPFPreserveDIType, DEBUG_TYPE, "BPF Preserve Debuginfo Type",
+ false, false)
+
+FunctionPass *llvm::createBPFPreserveDIType() {
+ return new BPFPreserveDIType();
+}
+
+bool BPFPreserveDIType::runOnFunction(Function &F) {
+ return BPFPreserveDITypeImpl(F);
+}
+
+PreservedAnalyses BPFPreserveDITypePass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ return BPFPreserveDITypeImpl(F) ? PreservedAnalyses::none()
+ : PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Target/BPF/BPFSubtarget.cpp b/contrib/libs/llvm12/lib/Target/BPF/BPFSubtarget.cpp
index 7697603d22..fac02e6476 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/BPFSubtarget.cpp
+++ b/contrib/libs/llvm12/lib/Target/BPF/BPFSubtarget.cpp
@@ -29,7 +29,7 @@ BPFSubtarget &BPFSubtarget::initializeSubtargetDependencies(StringRef CPU,
StringRef FS) {
initializeEnvironment();
initSubtargetFeatures(CPU, FS);
- ParseSubtargetFeatures(CPU, /*TuneCPU*/ CPU, FS);
+ ParseSubtargetFeatures(CPU, /*TuneCPU*/ CPU, FS);
return *this;
}
@@ -59,6 +59,6 @@ void BPFSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
BPFSubtarget::BPFSubtarget(const Triple &TT, const std::string &CPU,
const std::string &FS, const TargetMachine &TM)
- : BPFGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), InstrInfo(),
+ : BPFGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), InstrInfo(),
FrameLowering(initializeSubtargetDependencies(CPU, FS)),
TLInfo(TM, *this) {}
diff --git a/contrib/libs/llvm12/lib/Target/BPF/BPFSubtarget.h b/contrib/libs/llvm12/lib/Target/BPF/BPFSubtarget.h
index 59716ae777..7649e0e922 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/BPFSubtarget.h
+++ b/contrib/libs/llvm12/lib/Target/BPF/BPFSubtarget.h
@@ -67,7 +67,7 @@ public:
// ParseSubtargetFeatures - Parses features string setting specified
// subtarget options. Definition of function is auto generated by tblgen.
- void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
+ void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
bool getHasJmpExt() const { return HasJmpExt; }
bool getHasJmp32() const { return HasJmp32; }
bool getHasAlu32() const { return HasAlu32; }
diff --git a/contrib/libs/llvm12/lib/Target/BPF/BPFTargetMachine.cpp b/contrib/libs/llvm12/lib/Target/BPF/BPFTargetMachine.cpp
index 8cf9ef2921..a8fef2517b 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/BPFTargetMachine.cpp
+++ b/contrib/libs/llvm12/lib/Target/BPF/BPFTargetMachine.cpp
@@ -12,22 +12,22 @@
#include "BPFTargetMachine.h"
#include "BPF.h"
-#include "BPFTargetTransformInfo.h"
+#include "BPFTargetTransformInfo.h"
#include "MCTargetDesc/BPFMCAsmInfo.h"
#include "TargetInfo/BPFTargetInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/IR/PassManager.h"
-#include "llvm/Passes/PassBuilder.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Passes/PassBuilder.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/Transforms/Scalar/SimplifyCFG.h"
-#include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Scalar/SimplifyCFG.h"
+#include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
using namespace llvm;
static cl::
@@ -41,10 +41,10 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFTarget() {
RegisterTargetMachine<BPFTargetMachine> Z(getTheBPFTarget());
PassRegistry &PR = *PassRegistry::getPassRegistry();
- initializeBPFAbstractMemberAccessLegacyPassPass(PR);
+ initializeBPFAbstractMemberAccessLegacyPassPass(PR);
initializeBPFPreserveDITypePass(PR);
- initializeBPFAdjustOptPass(PR);
- initializeBPFCheckAndAdjustIRPass(PR);
+ initializeBPFAdjustOptPass(PR);
+ initializeBPFCheckAndAdjustIRPass(PR);
initializeBPFMIPeepholePass(PR);
initializeBPFMIPeepholeTruncElimPass(PR);
}
@@ -58,7 +58,7 @@ static std::string computeDataLayout(const Triple &TT) {
}
static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) {
- return RM.getValueOr(Reloc::PIC_);
+ return RM.getValueOr(Reloc::PIC_);
}
BPFTargetMachine::BPFTargetMachine(const Target &T, const Triple &TT,
@@ -101,56 +101,56 @@ TargetPassConfig *BPFTargetMachine::createPassConfig(PassManagerBase &PM) {
return new BPFPassConfig(*this, PM);
}
-void BPFTargetMachine::adjustPassManager(PassManagerBuilder &Builder) {
- Builder.addExtension(
- PassManagerBuilder::EP_EarlyAsPossible,
- [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) {
- PM.add(createBPFAbstractMemberAccess(this));
- PM.add(createBPFPreserveDIType());
- });
-
- Builder.addExtension(
- PassManagerBuilder::EP_Peephole,
- [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) {
- PM.add(createCFGSimplificationPass(
- SimplifyCFGOptions().hoistCommonInsts(true)));
- });
- Builder.addExtension(
- PassManagerBuilder::EP_ModuleOptimizerEarly,
- [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) {
- PM.add(createBPFAdjustOpt());
- });
-}
-
-void BPFTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB,
- bool DebugPassManager) {
- PB.registerPipelineStartEPCallback(
- [=](ModulePassManager &MPM, PassBuilder::OptimizationLevel) {
- FunctionPassManager FPM(DebugPassManager);
- FPM.addPass(BPFAbstractMemberAccessPass(this));
- FPM.addPass(BPFPreserveDITypePass());
- MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
- });
- PB.registerPeepholeEPCallback([=](FunctionPassManager &FPM,
- PassBuilder::OptimizationLevel Level) {
- FPM.addPass(SimplifyCFGPass(SimplifyCFGOptions().hoistCommonInsts(true)));
- });
- PB.registerPipelineEarlySimplificationEPCallback(
- [=](ModulePassManager &MPM, PassBuilder::OptimizationLevel) {
- MPM.addPass(BPFAdjustOptPass());
- });
-}
-
-void BPFPassConfig::addIRPasses() {
- addPass(createBPFCheckAndAdjustIR());
+void BPFTargetMachine::adjustPassManager(PassManagerBuilder &Builder) {
+ Builder.addExtension(
+ PassManagerBuilder::EP_EarlyAsPossible,
+ [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) {
+ PM.add(createBPFAbstractMemberAccess(this));
+ PM.add(createBPFPreserveDIType());
+ });
+
+ Builder.addExtension(
+ PassManagerBuilder::EP_Peephole,
+ [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) {
+ PM.add(createCFGSimplificationPass(
+ SimplifyCFGOptions().hoistCommonInsts(true)));
+ });
+ Builder.addExtension(
+ PassManagerBuilder::EP_ModuleOptimizerEarly,
+ [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) {
+ PM.add(createBPFAdjustOpt());
+ });
+}
+
+void BPFTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB,
+ bool DebugPassManager) {
+ PB.registerPipelineStartEPCallback(
+ [=](ModulePassManager &MPM, PassBuilder::OptimizationLevel) {
+ FunctionPassManager FPM(DebugPassManager);
+ FPM.addPass(BPFAbstractMemberAccessPass(this));
+ FPM.addPass(BPFPreserveDITypePass());
+ MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+ });
+ PB.registerPeepholeEPCallback([=](FunctionPassManager &FPM,
+ PassBuilder::OptimizationLevel Level) {
+ FPM.addPass(SimplifyCFGPass(SimplifyCFGOptions().hoistCommonInsts(true)));
+ });
+ PB.registerPipelineEarlySimplificationEPCallback(
+ [=](ModulePassManager &MPM, PassBuilder::OptimizationLevel) {
+ MPM.addPass(BPFAdjustOptPass());
+ });
+}
+
+void BPFPassConfig::addIRPasses() {
+ addPass(createBPFCheckAndAdjustIR());
TargetPassConfig::addIRPasses();
}
-TargetTransformInfo
-BPFTargetMachine::getTargetTransformInfo(const Function &F) {
- return TargetTransformInfo(BPFTTIImpl(this, F));
-}
-
+TargetTransformInfo
+BPFTargetMachine::getTargetTransformInfo(const Function &F) {
+ return TargetTransformInfo(BPFTTIImpl(this, F));
+}
+
// Install an instruction selector pass using
// the ISelDag to gen BPF code.
bool BPFPassConfig::addInstSelector() {
diff --git a/contrib/libs/llvm12/lib/Target/BPF/BPFTargetMachine.h b/contrib/libs/llvm12/lib/Target/BPF/BPFTargetMachine.h
index 2e78f5c4d3..61c8a44cc4 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/BPFTargetMachine.h
+++ b/contrib/libs/llvm12/lib/Target/BPF/BPFTargetMachine.h
@@ -34,15 +34,15 @@ public:
TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
- TargetTransformInfo getTargetTransformInfo(const Function &F) override;
-
+ TargetTransformInfo getTargetTransformInfo(const Function &F) override;
+
TargetLoweringObjectFile *getObjFileLowering() const override {
return TLOF.get();
}
-
- void adjustPassManager(PassManagerBuilder &) override;
- void registerPassBuilderCallbacks(PassBuilder &PB,
- bool DebugPassManager) override;
+
+ void adjustPassManager(PassManagerBuilder &) override;
+ void registerPassBuilderCallbacks(PassBuilder &PB,
+ bool DebugPassManager) override;
};
}
diff --git a/contrib/libs/llvm12/lib/Target/BPF/BPFTargetTransformInfo.h b/contrib/libs/llvm12/lib/Target/BPF/BPFTargetTransformInfo.h
index 01808aa50a..62055497e6 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/BPFTargetTransformInfo.h
+++ b/contrib/libs/llvm12/lib/Target/BPF/BPFTargetTransformInfo.h
@@ -1,61 +1,61 @@
-//===------ BPFTargetTransformInfo.h - BPF specific TTI ---------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file uses the target's specific information to
-// provide more precise answers to certain TTI queries, while letting the
-// target independent and default TTI implementations handle the rest.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_TARGET_BPF_BPFTARGETTRANSFORMINFO_H
-#define LLVM_LIB_TARGET_BPF_BPFTARGETTRANSFORMINFO_H
-
-#include "BPFTargetMachine.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/CodeGen/BasicTTIImpl.h"
-#include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
-
-namespace llvm {
-class BPFTTIImpl : public BasicTTIImplBase<BPFTTIImpl> {
- typedef BasicTTIImplBase<BPFTTIImpl> BaseT;
- typedef TargetTransformInfo TTI;
- friend BaseT;
-
- const BPFSubtarget *ST;
- const BPFTargetLowering *TLI;
-
- const BPFSubtarget *getST() const { return ST; }
- const BPFTargetLowering *getTLI() const { return TLI; }
-
-public:
- explicit BPFTTIImpl(const BPFTargetMachine *TM, const Function &F)
- : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)),
- TLI(ST->getTargetLowering()) {}
-
- int getIntImmCost(const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind) {
- if (Imm.getBitWidth() <= 64 && isInt<32>(Imm.getSExtValue()))
- return TTI::TCC_Free;
-
- return TTI::TCC_Basic;
- }
-
- int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
- CmpInst::Predicate VecPred,
- TTI::TargetCostKind CostKind,
- const llvm::Instruction *I = nullptr) {
- if (Opcode == Instruction::Select)
- return SCEVCheapExpansionBudget;
-
- return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
- I);
- }
-};
-
-} // end namespace llvm
-
-#endif // LLVM_LIB_TARGET_BPF_BPFTARGETTRANSFORMINFO_H
+//===------ BPFTargetTransformInfo.h - BPF specific TTI ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file uses the target's specific information to
+// provide more precise answers to certain TTI queries, while letting the
+// target independent and default TTI implementations handle the rest.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_BPF_BPFTARGETTRANSFORMINFO_H
+#define LLVM_LIB_TARGET_BPF_BPFTARGETTRANSFORMINFO_H
+
+#include "BPFTargetMachine.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/CodeGen/BasicTTIImpl.h"
+#include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
+
+namespace llvm {
+class BPFTTIImpl : public BasicTTIImplBase<BPFTTIImpl> {
+ typedef BasicTTIImplBase<BPFTTIImpl> BaseT;
+ typedef TargetTransformInfo TTI;
+ friend BaseT;
+
+ const BPFSubtarget *ST;
+ const BPFTargetLowering *TLI;
+
+ const BPFSubtarget *getST() const { return ST; }
+ const BPFTargetLowering *getTLI() const { return TLI; }
+
+public:
+ explicit BPFTTIImpl(const BPFTargetMachine *TM, const Function &F)
+ : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)),
+ TLI(ST->getTargetLowering()) {}
+
+ int getIntImmCost(const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind) {
+ if (Imm.getBitWidth() <= 64 && isInt<32>(Imm.getSExtValue()))
+ return TTI::TCC_Free;
+
+ return TTI::TCC_Basic;
+ }
+
+ int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
+ CmpInst::Predicate VecPred,
+ TTI::TargetCostKind CostKind,
+ const llvm::Instruction *I = nullptr) {
+ if (Opcode == Instruction::Select)
+ return SCEVCheapExpansionBudget;
+
+ return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
+ I);
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_BPF_BPFTARGETTRANSFORMINFO_H
diff --git a/contrib/libs/llvm12/lib/Target/BPF/BTF.def b/contrib/libs/llvm12/lib/Target/BPF/BTF.def
index 557b4a5c03..66cf2c90ea 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/BTF.def
+++ b/contrib/libs/llvm12/lib/Target/BPF/BTF.def
@@ -30,6 +30,6 @@ HANDLE_BTF_KIND(12, FUNC)
HANDLE_BTF_KIND(13, FUNC_PROTO)
HANDLE_BTF_KIND(14, VAR)
HANDLE_BTF_KIND(15, DATASEC)
-HANDLE_BTF_KIND(16, FLOAT)
+HANDLE_BTF_KIND(16, FLOAT)
#undef HANDLE_BTF_KIND
diff --git a/contrib/libs/llvm12/lib/Target/BPF/BTFDebug.cpp b/contrib/libs/llvm12/lib/Target/BPF/BTFDebug.cpp
index 4caf1ea3e2..9249d679c7 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/BTFDebug.cpp
+++ b/contrib/libs/llvm12/lib/Target/BPF/BTFDebug.cpp
@@ -22,7 +22,7 @@
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/LineIterator.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
using namespace llvm;
@@ -371,21 +371,21 @@ void BTFKindDataSec::emitType(MCStreamer &OS) {
}
}
-BTFTypeFloat::BTFTypeFloat(uint32_t SizeInBits, StringRef TypeName)
- : Name(TypeName) {
- Kind = BTF::BTF_KIND_FLOAT;
- BTFType.Info = Kind << 24;
- BTFType.Size = roundupToBytes(SizeInBits);
-}
-
-void BTFTypeFloat::completeType(BTFDebug &BDebug) {
- if (IsCompleted)
- return;
- IsCompleted = true;
-
- BTFType.NameOff = BDebug.addString(Name);
-}
-
+BTFTypeFloat::BTFTypeFloat(uint32_t SizeInBits, StringRef TypeName)
+ : Name(TypeName) {
+ Kind = BTF::BTF_KIND_FLOAT;
+ BTFType.Info = Kind << 24;
+ BTFType.Size = roundupToBytes(SizeInBits);
+}
+
+void BTFTypeFloat::completeType(BTFDebug &BDebug) {
+ if (IsCompleted)
+ return;
+ IsCompleted = true;
+
+ BTFType.NameOff = BDebug.addString(Name);
+}
+
uint32_t BTFStringTable::addString(StringRef S) {
// Check whether the string already exists.
for (auto &OffsetM : OffsetToIdMap) {
@@ -424,27 +424,27 @@ uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry) {
}
void BTFDebug::visitBasicType(const DIBasicType *BTy, uint32_t &TypeId) {
- // Only int and binary floating point types are supported in BTF.
+ // Only int and binary floating point types are supported in BTF.
uint32_t Encoding = BTy->getEncoding();
- std::unique_ptr<BTFTypeBase> TypeEntry;
- switch (Encoding) {
- case dwarf::DW_ATE_boolean:
- case dwarf::DW_ATE_signed:
- case dwarf::DW_ATE_signed_char:
- case dwarf::DW_ATE_unsigned:
- case dwarf::DW_ATE_unsigned_char:
- // Create a BTF type instance for this DIBasicType and put it into
- // DIToIdMap for cross-type reference check.
- TypeEntry = std::make_unique<BTFTypeInt>(
- Encoding, BTy->getSizeInBits(), BTy->getOffsetInBits(), BTy->getName());
- break;
- case dwarf::DW_ATE_float:
- TypeEntry =
- std::make_unique<BTFTypeFloat>(BTy->getSizeInBits(), BTy->getName());
- break;
- default:
+ std::unique_ptr<BTFTypeBase> TypeEntry;
+ switch (Encoding) {
+ case dwarf::DW_ATE_boolean:
+ case dwarf::DW_ATE_signed:
+ case dwarf::DW_ATE_signed_char:
+ case dwarf::DW_ATE_unsigned:
+ case dwarf::DW_ATE_unsigned_char:
+ // Create a BTF type instance for this DIBasicType and put it into
+ // DIToIdMap for cross-type reference check.
+ TypeEntry = std::make_unique<BTFTypeInt>(
+ Encoding, BTy->getSizeInBits(), BTy->getOffsetInBits(), BTy->getName());
+ break;
+ case dwarf::DW_ATE_float:
+ TypeEntry =
+ std::make_unique<BTFTypeFloat>(BTy->getSizeInBits(), BTy->getName());
+ break;
+ default:
return;
- }
+ }
TypeId = addType(std::move(TypeEntry), BTy);
}
@@ -1019,13 +1019,13 @@ void BTFDebug::generatePatchImmReloc(const MCSymbol *ORSym, uint32_t RootId,
FieldReloc.OffsetNameOff = addString(IndexPattern);
FieldReloc.RelocKind = std::stoull(std::string(RelocKindStr));
- PatchImms[GVar] = std::make_pair(std::stoll(std::string(PatchImmStr)),
- FieldReloc.RelocKind);
+ PatchImms[GVar] = std::make_pair(std::stoll(std::string(PatchImmStr)),
+ FieldReloc.RelocKind);
} else {
StringRef RelocStr = AccessPattern.substr(FirstDollar + 1);
FieldReloc.OffsetNameOff = addString("0");
FieldReloc.RelocKind = std::stoull(std::string(RelocStr));
- PatchImms[GVar] = std::make_pair(RootId, FieldReloc.RelocKind);
+ PatchImms[GVar] = std::make_pair(RootId, FieldReloc.RelocKind);
}
FieldRelocTable[SecNameOff].push_back(FieldReloc);
}
@@ -1101,9 +1101,9 @@ void BTFDebug::beginInstruction(const MachineInstr *MI) {
}
}
- if (!CurMI) // no debug info
- return;
-
+ if (!CurMI) // no debug info
+ return;
+
// Skip this instruction if no DebugLoc or the DebugLoc
// is the same as the previous instruction.
const DebugLoc &DL = MI->getDebugLoc();
@@ -1155,20 +1155,20 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) {
if (ProcessingMapDef != SecName.startswith(".maps"))
continue;
- // Create a .rodata datasec if the global variable is an initialized
- // constant with private linkage and if it won't be in .rodata.str<#>
- // and .rodata.cst<#> sections.
- if (SecName == ".rodata" && Global.hasPrivateLinkage() &&
- DataSecEntries.find(std::string(SecName)) == DataSecEntries.end()) {
- SectionKind GVKind =
- TargetLoweringObjectFile::getKindForGlobal(&Global, Asm->TM);
- // skip .rodata.str<#> and .rodata.cst<#> sections
- if (!GVKind.isMergeableCString() && !GVKind.isMergeableConst()) {
- DataSecEntries[std::string(SecName)] =
- std::make_unique<BTFKindDataSec>(Asm, std::string(SecName));
- }
- }
-
+ // Create a .rodata datasec if the global variable is an initialized
+ // constant with private linkage and if it won't be in .rodata.str<#>
+ // and .rodata.cst<#> sections.
+ if (SecName == ".rodata" && Global.hasPrivateLinkage() &&
+ DataSecEntries.find(std::string(SecName)) == DataSecEntries.end()) {
+ SectionKind GVKind =
+ TargetLoweringObjectFile::getKindForGlobal(&Global, Asm->TM);
+ // skip .rodata.str<#> and .rodata.cst<#> sections
+ if (!GVKind.isMergeableCString() && !GVKind.isMergeableConst()) {
+ DataSecEntries[std::string(SecName)] =
+ std::make_unique<BTFKindDataSec>(Asm, std::string(SecName));
+ }
+ }
+
SmallVector<DIGlobalVariableExpression *, 1> GVs;
Global.getDebugInfo(GVs);
@@ -1196,7 +1196,7 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) {
if (Linkage != GlobalValue::InternalLinkage &&
Linkage != GlobalValue::ExternalLinkage &&
Linkage != GlobalValue::WeakAnyLinkage &&
- Linkage != GlobalValue::WeakODRLinkage &&
+ Linkage != GlobalValue::WeakODRLinkage &&
Linkage != GlobalValue::ExternalWeakLinkage)
continue;
@@ -1225,8 +1225,8 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) {
const DataLayout &DL = Global.getParent()->getDataLayout();
uint32_t Size = DL.getTypeAllocSize(Global.getType()->getElementType());
- DataSecEntries[std::string(SecName)]->addDataSecEntry(VarId,
- Asm->getSymbol(&Global), Size);
+ DataSecEntries[std::string(SecName)]->addDataSecEntry(VarId,
+ Asm->getSymbol(&Global), Size);
}
}
@@ -1239,23 +1239,23 @@ bool BTFDebug::InstLower(const MachineInstr *MI, MCInst &OutMI) {
auto *GVar = dyn_cast<GlobalVariable>(GVal);
if (GVar) {
// Emit "mov ri, <imm>"
- int64_t Imm;
- uint32_t Reloc;
+ int64_t Imm;
+ uint32_t Reloc;
if (GVar->hasAttribute(BPFCoreSharedInfo::AmaAttr) ||
- GVar->hasAttribute(BPFCoreSharedInfo::TypeIdAttr)) {
- Imm = PatchImms[GVar].first;
- Reloc = PatchImms[GVar].second;
- } else {
+ GVar->hasAttribute(BPFCoreSharedInfo::TypeIdAttr)) {
+ Imm = PatchImms[GVar].first;
+ Reloc = PatchImms[GVar].second;
+ } else {
return false;
- }
-
- if (Reloc == BPFCoreSharedInfo::ENUM_VALUE_EXISTENCE ||
- Reloc == BPFCoreSharedInfo::ENUM_VALUE ||
- Reloc == BPFCoreSharedInfo::BTF_TYPE_ID_LOCAL ||
- Reloc == BPFCoreSharedInfo::BTF_TYPE_ID_REMOTE)
- OutMI.setOpcode(BPF::LD_imm64);
- else
- OutMI.setOpcode(BPF::MOV_ri);
+ }
+
+ if (Reloc == BPFCoreSharedInfo::ENUM_VALUE_EXISTENCE ||
+ Reloc == BPFCoreSharedInfo::ENUM_VALUE ||
+ Reloc == BPFCoreSharedInfo::BTF_TYPE_ID_LOCAL ||
+ Reloc == BPFCoreSharedInfo::BTF_TYPE_ID_REMOTE)
+ OutMI.setOpcode(BPF::LD_imm64);
+ else
+ OutMI.setOpcode(BPF::MOV_ri);
OutMI.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
OutMI.addOperand(MCOperand::createImm(Imm));
return true;
@@ -1269,7 +1269,7 @@ bool BTFDebug::InstLower(const MachineInstr *MI, MCInst &OutMI) {
const GlobalValue *GVal = MO.getGlobal();
auto *GVar = dyn_cast<GlobalVariable>(GVal);
if (GVar && GVar->hasAttribute(BPFCoreSharedInfo::AmaAttr)) {
- uint32_t Imm = PatchImms[GVar].first;
+ uint32_t Imm = PatchImms[GVar].first;
OutMI.setOpcode(MI->getOperand(1).getImm());
if (MI->getOperand(0).isImm())
OutMI.addOperand(MCOperand::createImm(MI->getOperand(0).getImm()));
@@ -1304,19 +1304,19 @@ void BTFDebug::processFuncPrototypes(const Function *F) {
uint8_t Scope = BTF::FUNC_EXTERN;
auto FuncTypeEntry =
std::make_unique<BTFTypeFunc>(SP->getName(), ProtoTypeId, Scope);
- uint32_t FuncId = addType(std::move(FuncTypeEntry));
- if (F->hasSection()) {
- StringRef SecName = F->getSection();
-
- if (DataSecEntries.find(std::string(SecName)) == DataSecEntries.end()) {
- DataSecEntries[std::string(SecName)] =
- std::make_unique<BTFKindDataSec>(Asm, std::string(SecName));
- }
-
- // We really don't know func size, set it to 0.
- DataSecEntries[std::string(SecName)]->addDataSecEntry(FuncId,
- Asm->getSymbol(F), 0);
- }
+ uint32_t FuncId = addType(std::move(FuncTypeEntry));
+ if (F->hasSection()) {
+ StringRef SecName = F->getSection();
+
+ if (DataSecEntries.find(std::string(SecName)) == DataSecEntries.end()) {
+ DataSecEntries[std::string(SecName)] =
+ std::make_unique<BTFKindDataSec>(Asm, std::string(SecName));
+ }
+
+ // We really don't know func size, set it to 0.
+ DataSecEntries[std::string(SecName)]->addDataSecEntry(FuncId,
+ Asm->getSymbol(F), 0);
+ }
}
void BTFDebug::endModule() {
diff --git a/contrib/libs/llvm12/lib/Target/BPF/BTFDebug.h b/contrib/libs/llvm12/lib/Target/BPF/BTFDebug.h
index c9dd664467..76f1901779 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/BTFDebug.h
+++ b/contrib/libs/llvm12/lib/Target/BPF/BTFDebug.h
@@ -16,8 +16,8 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/CodeGen/DebugHandlerBase.h"
-#include <cstdint>
-#include <map>
+#include <cstdint>
+#include <map>
#include <set>
#include <unordered_map>
#include "BTF.h"
@@ -28,10 +28,10 @@ class AsmPrinter;
class BTFDebug;
class DIType;
class GlobalVariable;
-class MachineFunction;
-class MachineInstr;
-class MachineOperand;
-class MCInst;
+class MachineFunction;
+class MachineInstr;
+class MachineOperand;
+class MCInst;
class MCStreamer;
class MCSymbol;
@@ -187,7 +187,7 @@ public:
uint32_t getSize() override {
return BTFTypeBase::getSize() + BTF::BTFDataSecVarSize * Vars.size();
}
- void addDataSecEntry(uint32_t Id, const MCSymbol *Sym, uint32_t Size) {
+ void addDataSecEntry(uint32_t Id, const MCSymbol *Sym, uint32_t Size) {
Vars.push_back(std::make_tuple(Id, Sym, Size));
}
std::string getName() { return Name; }
@@ -195,15 +195,15 @@ public:
void emitType(MCStreamer &OS) override;
};
-/// Handle binary floating point type.
-class BTFTypeFloat : public BTFTypeBase {
- StringRef Name;
-
-public:
- BTFTypeFloat(uint32_t SizeInBits, StringRef TypeName);
- void completeType(BTFDebug &BDebug) override;
-};
-
+/// Handle binary floating point type.
+class BTFTypeFloat : public BTFTypeBase {
+ StringRef Name;
+
+public:
+ BTFTypeFloat(uint32_t SizeInBits, StringRef TypeName);
+ void completeType(BTFDebug &BDebug) override;
+};
+
/// String table.
class BTFStringTable {
/// String table size in bytes.
@@ -264,7 +264,7 @@ class BTFDebug : public DebugHandlerBase {
StringMap<std::vector<std::string>> FileContent;
std::map<std::string, std::unique_ptr<BTFKindDataSec>> DataSecEntries;
std::vector<BTFTypeStruct *> StructTypes;
- std::map<const GlobalVariable *, std::pair<int64_t, uint32_t>> PatchImms;
+ std::map<const GlobalVariable *, std::pair<int64_t, uint32_t>> PatchImms;
std::map<StringRef, std::pair<bool, std::vector<BTFTypeDerived *>>>
FixupDerivedTypes;
std::set<const Function *>ProtoFunctions;
diff --git a/contrib/libs/llvm12/lib/Target/BPF/Disassembler/BPFDisassembler.cpp b/contrib/libs/llvm12/lib/Target/BPF/Disassembler/BPFDisassembler.cpp
index 264ef42635..3a1492743b 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/Disassembler/BPFDisassembler.cpp
+++ b/contrib/libs/llvm12/lib/Target/BPF/Disassembler/BPFDisassembler.cpp
@@ -58,7 +58,7 @@ public:
BPF_MEM = 0x3,
BPF_LEN = 0x4,
BPF_MSH = 0x5,
- BPF_ATOMIC = 0x6
+ BPF_ATOMIC = 0x6
};
BPFDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
@@ -176,7 +176,7 @@ DecodeStatus BPFDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
uint8_t InstMode = getInstMode(Insn);
if ((InstClass == BPF_LDX || InstClass == BPF_STX) &&
getInstSize(Insn) != BPF_DW &&
- (InstMode == BPF_MEM || InstMode == BPF_ATOMIC) &&
+ (InstMode == BPF_MEM || InstMode == BPF_ATOMIC) &&
STI.getFeatureBits()[BPF::ALU32])
Result = decodeInstruction(DecoderTableBPFALU3264, Instr, Insn, Address,
this, STI);
diff --git a/contrib/libs/llvm12/lib/Target/BPF/Disassembler/ya.make b/contrib/libs/llvm12/lib/Target/BPF/Disassembler/ya.make
index ca048de77d..cb7872eeee 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/Disassembler/ya.make
+++ b/contrib/libs/llvm12/lib/Target/BPF/Disassembler/ya.make
@@ -12,17 +12,17 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/MC/MCDisassembler
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target/BPF/TargetInfo
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/MC/MCDisassembler
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target/BPF/TargetInfo
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF
- contrib/libs/llvm12/lib/Target/BPF
- contrib/libs/llvm12/lib/Target/BPF/Disassembler
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF
+ contrib/libs/llvm12/lib/Target/BPF
+ contrib/libs/llvm12/lib/Target/BPF/Disassembler
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.h b/contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.h
index 34fa4539e5..e76067ea41 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.h
+++ b/contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.h
@@ -32,7 +32,7 @@ public:
void printBrTargetOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
// Autogenerated by tblgen.
- std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
+ std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
static const char *getRegisterName(unsigned RegNo);
};
diff --git a/contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp b/contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp
index 3ecd8bd5a4..12af92e0d1 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp
+++ b/contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp
@@ -13,7 +13,7 @@
#include "MCTargetDesc/BPFMCTargetDesc.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCCodeEmitter.h"
-#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
@@ -159,18 +159,18 @@ void BPFMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
uint64_t BPFMCCodeEmitter::getMemoryOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
- // For CMPXCHG instructions, output is implicitly in R0/W0,
- // so memory operand starts from operand 0.
- int MemOpStartIndex = 1, Opcode = MI.getOpcode();
- if (Opcode == BPF::CMPXCHGW32 || Opcode == BPF::CMPXCHGD)
- MemOpStartIndex = 0;
-
+ // For CMPXCHG instructions, output is implicitly in R0/W0,
+ // so memory operand starts from operand 0.
+ int MemOpStartIndex = 1, Opcode = MI.getOpcode();
+ if (Opcode == BPF::CMPXCHGW32 || Opcode == BPF::CMPXCHGD)
+ MemOpStartIndex = 0;
+
uint64_t Encoding;
- const MCOperand Op1 = MI.getOperand(MemOpStartIndex);
+ const MCOperand Op1 = MI.getOperand(MemOpStartIndex);
assert(Op1.isReg() && "First operand is not register.");
Encoding = MRI.getEncodingValue(Op1.getReg());
Encoding <<= 16;
- MCOperand Op2 = MI.getOperand(MemOpStartIndex + 1);
+ MCOperand Op2 = MI.getOperand(MemOpStartIndex + 1);
assert(Op2.isImm() && "Second operand is not immediate.");
Encoding |= Op2.getImm() & 0xffff;
return Encoding;
diff --git a/contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp b/contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp
index 0d9fcaa0e1..8fb7d7e89f 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp
+++ b/contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp
@@ -46,7 +46,7 @@ static MCRegisterInfo *createBPFMCRegisterInfo(const Triple &TT) {
static MCSubtargetInfo *createBPFMCSubtargetInfo(const Triple &TT,
StringRef CPU, StringRef FS) {
- return createBPFMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
+ return createBPFMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
}
static MCStreamer *createBPFMCStreamer(const Triple &T, MCContext &Ctx,
diff --git a/contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/ya.make b/contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/ya.make
index 9f1a1f9c3a..6522c7ef00 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/ya.make
+++ b/contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc/ya.make
@@ -12,17 +12,17 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target/BPF/TargetInfo
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target/BPF/TargetInfo
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF
- contrib/libs/llvm12/lib/Target/BPF
- contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF
+ contrib/libs/llvm12/lib/Target/BPF
+ contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/BPF/TargetInfo/ya.make b/contrib/libs/llvm12/lib/Target/BPF/TargetInfo/ya.make
index 1498dd77d8..3a882dad3e 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/TargetInfo/ya.make
+++ b/contrib/libs/llvm12/lib/Target/BPF/TargetInfo/ya.make
@@ -12,13 +12,13 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
- contrib/libs/llvm12/lib/Target/BPF
- contrib/libs/llvm12/lib/Target/BPF/TargetInfo
+ contrib/libs/llvm12/lib/Target/BPF
+ contrib/libs/llvm12/lib/Target/BPF/TargetInfo
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/BPF/ya.make b/contrib/libs/llvm12/lib/Target/BPF/ya.make
index bc05712021..0f122e4afe 100644
--- a/contrib/libs/llvm12/lib/Target/BPF/ya.make
+++ b/contrib/libs/llvm12/lib/Target/BPF/ya.make
@@ -12,26 +12,26 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/CodeGen
- contrib/libs/llvm12/lib/CodeGen/AsmPrinter
- contrib/libs/llvm12/lib/CodeGen/SelectionDAG
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target
- contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc
- contrib/libs/llvm12/lib/Target/BPF/TargetInfo
- contrib/libs/llvm12/lib/Transforms/IPO
- contrib/libs/llvm12/lib/Transforms/Scalar
- contrib/libs/llvm12/lib/Transforms/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/CodeGen
+ contrib/libs/llvm12/lib/CodeGen/AsmPrinter
+ contrib/libs/llvm12/lib/CodeGen/SelectionDAG
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target
+ contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/BPF/TargetInfo
+ contrib/libs/llvm12/lib/Transforms/IPO
+ contrib/libs/llvm12/lib/Transforms/Scalar
+ contrib/libs/llvm12/lib/Transforms/Utils
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF
- contrib/libs/llvm12/lib/Target/BPF
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/BPF
+ contrib/libs/llvm12/lib/Target/BPF
)
NO_COMPILER_WARNINGS()
@@ -40,9 +40,9 @@ NO_UTIL()
SRCS(
BPFAbstractMemberAccess.cpp
- BPFAdjustOpt.cpp
+ BPFAdjustOpt.cpp
BPFAsmPrinter.cpp
- BPFCheckAndAdjustIR.cpp
+ BPFCheckAndAdjustIR.cpp
BPFFrameLowering.cpp
BPFISelDAGToDAG.cpp
BPFISelLowering.cpp
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/NVPTXInstPrinter.h b/contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/NVPTXInstPrinter.h
index 8a15343ea9..503f0497b6 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/NVPTXInstPrinter.h
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/NVPTXInstPrinter.h
@@ -29,7 +29,7 @@ public:
const MCSubtargetInfo &STI, raw_ostream &OS) override;
// Autogenerated by tblgen.
- std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
+ std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
static const char *getRegisterName(unsigned RegNo);
// End
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/NVPTXMCAsmInfo.cpp b/contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/NVPTXMCAsmInfo.cpp
index d43bbf6a84..f275011018 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/NVPTXMCAsmInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/NVPTXMCAsmInfo.cpp
@@ -47,7 +47,7 @@ NVPTXMCAsmInfo::NVPTXMCAsmInfo(const Triple &TheTriple,
AscizDirective = nullptr; // not supported
SupportsQuotedNames = false;
SupportsExtendedDwarfLocDirective = false;
- SupportsSignedData = false;
+ SupportsSignedData = false;
// @TODO: Can we just disable this?
WeakDirective = "\t// .weak\t";
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp b/contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp
index 648b3ff0bf..d69166feb0 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp
@@ -46,7 +46,7 @@ static MCRegisterInfo *createNVPTXMCRegisterInfo(const Triple &TT) {
static MCSubtargetInfo *
createNVPTXMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
- return createNVPTXMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
+ return createNVPTXMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
}
static MCInstPrinter *createNVPTXMCInstPrinter(const Triple &T,
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/ya.make b/contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/ya.make
index fadad8ac79..81ad30663e 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/ya.make
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc/ya.make
@@ -12,17 +12,17 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/NVPTX
- contrib/libs/llvm12/lib/Target/NVPTX
- contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/NVPTX
+ contrib/libs/llvm12/lib/Target/NVPTX
+ contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTX.h b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTX.h
index 3a356942d5..c2fd090da0 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTX.h
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTX.h
@@ -14,7 +14,7 @@
#ifndef LLVM_LIB_TARGET_NVPTX_NVPTX_H
#define LLVM_LIB_TARGET_NVPTX_NVPTX_H
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/Support/CodeGen.h"
@@ -48,24 +48,24 @@ FunctionPass *createNVPTXLowerAllocaPass();
MachineFunctionPass *createNVPTXPeephole();
MachineFunctionPass *createNVPTXProxyRegErasurePass();
-struct NVVMIntrRangePass : PassInfoMixin<NVVMIntrRangePass> {
- NVVMIntrRangePass();
- NVVMIntrRangePass(unsigned SmVersion) : SmVersion(SmVersion) {}
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-
-private:
- unsigned SmVersion;
-};
-
-struct NVVMReflectPass : PassInfoMixin<NVVMReflectPass> {
- NVVMReflectPass();
- NVVMReflectPass(unsigned SmVersion) : SmVersion(SmVersion) {}
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-
-private:
- unsigned SmVersion;
-};
-
+struct NVVMIntrRangePass : PassInfoMixin<NVVMIntrRangePass> {
+ NVVMIntrRangePass();
+ NVVMIntrRangePass(unsigned SmVersion) : SmVersion(SmVersion) {}
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+
+private:
+ unsigned SmVersion;
+};
+
+struct NVVMReflectPass : PassInfoMixin<NVVMReflectPass> {
+ NVVMReflectPass();
+ NVVMReflectPass(unsigned SmVersion) : SmVersion(SmVersion) {}
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+
+private:
+ unsigned SmVersion;
+};
+
namespace NVPTX {
enum DrvInterface {
NVCL,
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
index e4d1256798..38844ff4dd 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
@@ -1302,8 +1302,8 @@ NVPTXAsmPrinter::getPTXFundamentalTypeStr(Type *Ty, bool useB4PTR) const {
return "b32";
else
return "u32";
- default:
- break;
+ default:
+ break;
}
llvm_unreachable("unexpected type");
}
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXFrameLowering.cpp b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXFrameLowering.cpp
index a14afad671..024e51e5f4 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXFrameLowering.cpp
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXFrameLowering.cpp
@@ -63,13 +63,13 @@ void NVPTXFrameLowering::emitPrologue(MachineFunction &MF,
}
}
-StackOffset
-NVPTXFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
- Register &FrameReg) const {
+StackOffset
+NVPTXFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
+ Register &FrameReg) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
FrameReg = NVPTX::VRDepot;
- return StackOffset::getFixed(MFI.getObjectOffset(FI) -
- getOffsetOfLocalArea());
+ return StackOffset::getFixed(MFI.getObjectOffset(FI) -
+ getOffsetOfLocalArea());
}
void NVPTXFrameLowering::emitEpilogue(MachineFunction &MF,
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXFrameLowering.h b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXFrameLowering.h
index 93f24fca40..a5d49ac3ab 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXFrameLowering.h
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXFrameLowering.h
@@ -14,7 +14,7 @@
#define LLVM_LIB_TARGET_NVPTX_NVPTXFRAMELOWERING_H
#include "llvm/CodeGen/TargetFrameLowering.h"
-#include "llvm/Support/TypeSize.h"
+#include "llvm/Support/TypeSize.h"
namespace llvm {
@@ -25,8 +25,8 @@ public:
bool hasFP(const MachineFunction &MF) const override;
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
- StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
- Register &FrameReg) const override;
+ StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
+ Register &FrameReg) const override;
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp
index c4df5dc36f..08f4ab87c6 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp
@@ -700,11 +700,11 @@ static bool canLowerToLDG(MemSDNode *N, const NVPTXSubtarget &Subtarget,
bool IsKernelFn = isKernelFunction(F->getFunction());
- // We use getUnderlyingObjects() here instead of getUnderlyingObject() mainly
+ // We use getUnderlyingObjects() here instead of getUnderlyingObject() mainly
// because the former looks through phi nodes while the latter does not. We
// need to look through phi nodes to handle pointer induction variables.
SmallVector<const Value *, 8> Objs;
- getUnderlyingObjects(N->getMemOperand()->getValue(), Objs);
+ getUnderlyingObjects(N->getMemOperand()->getValue(), Objs);
return all_of(Objs, [&](const Value *V) {
if (auto *A = dyn_cast<const Argument>(V))
@@ -2854,7 +2854,7 @@ bool NVPTXDAGToDAGISel::tryTextureIntrinsic(SDNode *N) {
}
// Copy over operands
- SmallVector<SDValue, 8> Ops(drop_begin(N->ops()));
+ SmallVector<SDValue, 8> Ops(drop_begin(N->ops()));
Ops.push_back(N->getOperand(0)); // Move chain to the back.
ReplaceNode(N, CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops));
@@ -3363,7 +3363,7 @@ bool NVPTXDAGToDAGISel::trySurfaceIntrinsic(SDNode *N) {
}
// Copy over operands
- SmallVector<SDValue, 8> Ops(drop_begin(N->ops()));
+ SmallVector<SDValue, 8> Ops(drop_begin(N->ops()));
Ops.push_back(N->getOperand(0)); // Move chain to the back.
ReplaceNode(N, CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops));
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXISelLowering.cpp b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXISelLowering.cpp
index 753f3bf777..8860e90f28 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXISelLowering.cpp
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXISelLowering.cpp
@@ -19,7 +19,7 @@
#include "NVPTXTargetObjectFile.h"
#include "NVPTXUtilities.h"
#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/Analysis.h"
@@ -65,7 +65,7 @@
using namespace llvm;
-static std::atomic<unsigned> GlobalUniqueCallSite;
+static std::atomic<unsigned> GlobalUniqueCallSite;
static cl::opt<bool> sched4reg(
"nvptx-sched4reg",
@@ -1243,7 +1243,7 @@ NVPTXTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const {
std::string NVPTXTargetLowering::getPrototype(
const DataLayout &DL, Type *retTy, const ArgListTy &Args,
const SmallVectorImpl<ISD::OutputArg> &Outs, MaybeAlign retAlignment,
- const CallBase &CB, unsigned UniqueCallSite) const {
+ const CallBase &CB, unsigned UniqueCallSite) const {
auto PtrVT = getPointerTy(DL);
bool isABI = (STI.getSmVersion() >= 20);
@@ -1252,7 +1252,7 @@ std::string NVPTXTargetLowering::getPrototype(
return "";
std::stringstream O;
- O << "prototype_" << UniqueCallSite << " : .callprototype ";
+ O << "prototype_" << UniqueCallSite << " : .callprototype ";
if (retTy->getTypeID() == Type::VoidTyID) {
O << "()";
@@ -1422,9 +1422,9 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
if (!isABI)
return Chain;
- unsigned UniqueCallSite = GlobalUniqueCallSite.fetch_add(1);
+ unsigned UniqueCallSite = GlobalUniqueCallSite.fetch_add(1);
SDValue tempChain = Chain;
- Chain = DAG.getCALLSEQ_START(Chain, UniqueCallSite, 0, dl);
+ Chain = DAG.getCALLSEQ_START(Chain, UniqueCallSite, 0, dl);
SDValue InFlag = Chain.getValue(1);
unsigned paramCount = 0;
@@ -1679,8 +1679,8 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// The prototype is embedded in a string and put as the operand for a
// CallPrototype SDNode which will print out to the value of the string.
SDVTList ProtoVTs = DAG.getVTList(MVT::Other, MVT::Glue);
- std::string Proto =
- getPrototype(DL, RetTy, Args, Outs, retAlignment, *CB, UniqueCallSite);
+ std::string Proto =
+ getPrototype(DL, RetTy, Args, Outs, retAlignment, *CB, UniqueCallSite);
const char *ProtoStr =
nvTM->getManagedStrPool()->getManagedString(Proto.c_str())->c_str();
SDValue ProtoOps[] = {
@@ -1736,8 +1736,8 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
if (isIndirectCall) {
SDVTList PrototypeVTs = DAG.getVTList(MVT::Other, MVT::Glue);
- SDValue PrototypeOps[] = {
- Chain, DAG.getConstant(UniqueCallSite, dl, MVT::i32), InFlag};
+ SDValue PrototypeOps[] = {
+ Chain, DAG.getConstant(UniqueCallSite, dl, MVT::i32), InFlag};
Chain = DAG.getNode(NVPTXISD::Prototype, dl, PrototypeVTs, PrototypeOps);
InFlag = Chain.getValue(1);
}
@@ -1833,9 +1833,9 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
}
}
- Chain = DAG.getCALLSEQ_END(
- Chain, DAG.getIntPtrConstant(UniqueCallSite, dl, true),
- DAG.getIntPtrConstant(UniqueCallSite + 1, dl, true), InFlag, dl);
+ Chain = DAG.getCALLSEQ_END(
+ Chain, DAG.getIntPtrConstant(UniqueCallSite, dl, true),
+ DAG.getIntPtrConstant(UniqueCallSite + 1, dl, true), InFlag, dl);
InFlag = Chain.getValue(1);
// Append ProxyReg instructions to the chain to make sure that `callseq_end`
@@ -2437,7 +2437,7 @@ static bool isImageOrSamplerVal(const Value *arg, const Module *context) {
if (!STy || STy->isLiteral())
return false;
- return llvm::is_contained(specialTypes, STy->getName());
+ return llvm::is_contained(specialTypes, STy->getName());
}
SDValue NVPTXTargetLowering::LowerFormalArguments(
@@ -2588,8 +2588,8 @@ SDValue NVPTXTargetLowering::LowerFormalArguments(
// Extend the element if necessary (e.g. an i8 is loaded
// into an i16 register)
if (Ins[InsIdx].VT.isInteger() &&
- Ins[InsIdx].VT.getFixedSizeInBits() >
- LoadVT.getFixedSizeInBits()) {
+ Ins[InsIdx].VT.getFixedSizeInBits() >
+ LoadVT.getFixedSizeInBits()) {
unsigned Extend = Ins[InsIdx].Flags.isSExt() ? ISD::SIGN_EXTEND
: ISD::ZERO_EXTEND;
Elt = DAG.getNode(Extend, dl, Ins[InsIdx].VT, Elt);
@@ -4563,13 +4563,13 @@ static bool IsMulWideOperandDemotable(SDValue Op,
if (Op.getOpcode() == ISD::SIGN_EXTEND ||
Op.getOpcode() == ISD::SIGN_EXTEND_INREG) {
EVT OrigVT = Op.getOperand(0).getValueType();
- if (OrigVT.getFixedSizeInBits() <= OptSize) {
+ if (OrigVT.getFixedSizeInBits() <= OptSize) {
S = Signed;
return true;
}
} else if (Op.getOpcode() == ISD::ZERO_EXTEND) {
EVT OrigVT = Op.getOperand(0).getValueType();
- if (OrigVT.getFixedSizeInBits() <= OptSize) {
+ if (OrigVT.getFixedSizeInBits() <= OptSize) {
S = Unsigned;
return true;
}
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXISelLowering.h b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXISelLowering.h
index 660ca65e39..13829b924d 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXISelLowering.h
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXISelLowering.h
@@ -491,8 +491,8 @@ public:
std::string getPrototype(const DataLayout &DL, Type *, const ArgListTy &,
const SmallVectorImpl<ISD::OutputArg> &,
- MaybeAlign retAlignment, const CallBase &CB,
- unsigned UniqueCallSite) const;
+ MaybeAlign retAlignment, const CallBase &CB,
+ unsigned UniqueCallSite) const;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrFormats.td b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrFormats.td
index 9410b463bb..9220f4766d 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrFormats.td
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrFormats.td
@@ -31,14 +31,14 @@ class NVPTXInst<dag outs, dag ins, string asmstr, list<dag> pattern>
// TSFlagFields
bits<4> VecInstType = VecNOP.Value;
- bit IsSimpleMove = false;
- bit IsLoad = false;
- bit IsStore = false;
+ bit IsSimpleMove = false;
+ bit IsLoad = false;
+ bit IsStore = false;
- bit IsTex = false;
- bit IsSust = false;
- bit IsSurfTexQuery = false;
- bit IsTexModeUnified = false;
+ bit IsTex = false;
+ bit IsSust = false;
+ bit IsSurfTexQuery = false;
+ bit IsTexModeUnified = false;
// The following field is encoded as log2 of the vector size minus one,
// with 0 meaning the operation is not a surface instruction. For example,
@@ -46,13 +46,13 @@ class NVPTXInst<dag outs, dag ins, string asmstr, list<dag> pattern>
// 2**(2-1) = 2.
bits<2> IsSuld = 0;
- let TSFlags{3...0} = VecInstType;
- let TSFlags{4...4} = IsSimpleMove;
- let TSFlags{5...5} = IsLoad;
- let TSFlags{6...6} = IsStore;
- let TSFlags{7} = IsTex;
- let TSFlags{9...8} = IsSuld;
- let TSFlags{10} = IsSust;
- let TSFlags{11} = IsSurfTexQuery;
- let TSFlags{12} = IsTexModeUnified;
+ let TSFlags{3...0} = VecInstType;
+ let TSFlags{4...4} = IsSimpleMove;
+ let TSFlags{5...5} = IsLoad;
+ let TSFlags{6...6} = IsStore;
+ let TSFlags{7} = IsTex;
+ let TSFlags{9...8} = IsSuld;
+ let TSFlags{10} = IsSust;
+ let TSFlags{11} = IsSurfTexQuery;
+ let TSFlags{12} = IsTexModeUnified;
}
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrInfo.td b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrInfo.td
index 345c4c5142..381ed4dd68 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrInfo.td
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXInstrInfo.td
@@ -13,7 +13,7 @@
include "NVPTXInstrFormats.td"
// A NOP instruction
-let hasSideEffects = false in {
+let hasSideEffects = false in {
def NOP : NVPTXInst<(outs), (ins), "", []>;
}
@@ -137,7 +137,7 @@ def do_SQRTF32_RN : Predicate<"usePrecSqrtF32()">;
def hasHWROT32 : Predicate<"Subtarget->hasHWROT32()">;
def noHWROT32 : Predicate<"!Subtarget->hasHWROT32()">;
-def True : Predicate<"true">;
+def True : Predicate<"true">;
def hasPTX31 : Predicate<"Subtarget->getPTXVersion() >= 31">;
def hasPTX60 : Predicate<"Subtarget->getPTXVersion() >= 60">;
@@ -407,7 +407,7 @@ multiclass F2<string OpcStr, SDNode OpNode> {
// Type Conversion
//-----------------------------------
-let hasSideEffects = false in {
+let hasSideEffects = false in {
// Generate a cvt to the given type from all possible types. Each instance
// takes a CvtMode immediate that defines the conversion mode to use. It can
// be CvtNONE to omit a conversion mode.
@@ -1022,12 +1022,12 @@ multiclass FMA_F16<string OpcStr, RegisterClass RC, Predicate Pred> {
}
defm FMA16_ftz : FMA_F16<"fma.rn.ftz.f16", Float16Regs, doF32FTZ>;
-defm FMA16 : FMA_F16<"fma.rn.f16", Float16Regs, True>;
+defm FMA16 : FMA_F16<"fma.rn.f16", Float16Regs, True>;
defm FMA16x2_ftz : FMA_F16<"fma.rn.ftz.f16x2", Float16x2Regs, doF32FTZ>;
-defm FMA16x2 : FMA_F16<"fma.rn.f16x2", Float16x2Regs, True>;
+defm FMA16x2 : FMA_F16<"fma.rn.f16x2", Float16x2Regs, True>;
defm FMA32_ftz : FMA<"fma.rn.ftz.f32", Float32Regs, f32imm, doF32FTZ>;
-defm FMA32 : FMA<"fma.rn.f32", Float32Regs, f32imm, True>;
-defm FMA64 : FMA<"fma.rn.f64", Float64Regs, f64imm, True>;
+defm FMA32 : FMA<"fma.rn.f32", Float32Regs, f32imm, True>;
+defm FMA64 : FMA<"fma.rn.f64", Float64Regs, f64imm, True>;
// sin/cos
def SINF: NVPTXInst<(outs Float32Regs:$dst), (ins Float32Regs:$src),
@@ -1367,7 +1367,7 @@ multiclass BFE<string TyStr, RegisterClass RC> {
!strconcat("bfe.", TyStr, " \t$d, $a, $b, $c;"), []>;
}
-let hasSideEffects = false in {
+let hasSideEffects = false in {
defm BFE_S32 : BFE<"s32", Int32Regs>;
defm BFE_U32 : BFE<"u32", Int32Regs>;
defm BFE_S64 : BFE<"s64", Int64Regs>;
@@ -1381,7 +1381,7 @@ let hasSideEffects = false in {
// FIXME: This doesn't cover versions of set and setp that combine with a
// boolean predicate, e.g. setp.eq.and.b16.
-let hasSideEffects = false in {
+let hasSideEffects = false in {
multiclass SETP<string TypeStr, RegisterClass RC, Operand ImmCls> {
def rr :
NVPTXInst<(outs Int1Regs:$dst), (ins RC:$a, RC:$b, CmpMode:$cmp),
@@ -1427,7 +1427,7 @@ def SETP_f16x2rr :
// "set.CmpOp{.ftz}.dtype.stype", where dtype is the type of the destination
// reg, either u32, s32, or f32. Anyway these aren't used at the moment.
-let hasSideEffects = false in {
+let hasSideEffects = false in {
multiclass SET<string TypeStr, RegisterClass RC, Operand ImmCls> {
def rr : NVPTXInst<(outs Int32Regs:$dst),
(ins RC:$a, RC:$b, CmpMode:$cmp),
@@ -1462,7 +1462,7 @@ defm SET_f64 : SET<"f64", Float64Regs, f64imm>;
// selp instructions that don't have any pattern matches; we explicitly use
// them within this file.
-let hasSideEffects = false in {
+let hasSideEffects = false in {
multiclass SELP<string TypeStr, RegisterClass RC, Operand ImmCls> {
def rr : NVPTXInst<(outs RC:$dst),
(ins RC:$a, RC:$b, Int1Regs:$p),
@@ -1572,7 +1572,7 @@ def MOV_ADDR64 : NVPTXInst<(outs Int64Regs:$dst), (ins imem:$a),
[(set Int64Regs:$dst, (Wrapper tglobaladdr:$a))]>;
// Get pointer to local stack.
-let hasSideEffects = false in {
+let hasSideEffects = false in {
def MOV_DEPOT_ADDR : NVPTXInst<(outs Int32Regs:$d), (ins i32imm:$num),
"mov.u32 \t$d, __local_depot$num;", []>;
def MOV_DEPOT_ADDR_64 : NVPTXInst<(outs Int64Regs:$d), (ins i32imm:$num),
@@ -1988,7 +1988,7 @@ def ProxyReg :
SDNode<"NVPTXISD::ProxyReg", SDTProxyRegProfile,
[SDNPHasChain, SDNPOutGlue, SDNPInGlue, SDNPSideEffect]>;
-let mayLoad = true in {
+let mayLoad = true in {
class LoadParamMemInst<NVPTXRegClass regclass, string opstr> :
NVPTXInst<(outs regclass:$dst), (ins i32imm:$b),
!strconcat("ld.param", opstr, " \t$dst, [retval0+$b];"),
@@ -2013,7 +2013,7 @@ class LoadParamRegInst<NVPTXRegClass regclass, string opstr> :
!strconcat("mov", opstr, " \t$dst, retval$b;"),
[(set regclass:$dst, (LoadParam (i32 0), (i32 imm:$b)))]>;
-let mayStore = true in {
+let mayStore = true in {
class StoreParamInst<NVPTXRegClass regclass, string opstr> :
NVPTXInst<(outs), (ins regclass:$val, i32imm:$a, i32imm:$b),
!strconcat("st.param", opstr, " \t[param$a+$b], $val;"),
@@ -2823,7 +2823,7 @@ def : Pat<(select Int32Regs:$pred, Float64Regs:$a, Float64Regs:$b),
(SETP_b32ri (ANDb32ri Int32Regs:$pred, 1), 1, CmpEQ))>;
-let hasSideEffects = false in {
+let hasSideEffects = false in {
// pack a set of smaller int registers to a larger int register
def V4I16toI64 : NVPTXInst<(outs Int64Regs:$d),
(ins Int16Regs:$s1, Int16Regs:$s2,
@@ -2856,7 +2856,7 @@ let hasSideEffects = false in {
}
-let hasSideEffects = false in {
+let hasSideEffects = false in {
// Extract element of f16x2 register. PTX does not provide any way
// to access elements of f16x2 vector directly, so we need to
// extract it using a temporary register.
@@ -2899,7 +2899,7 @@ let hasSideEffects = false in {
}
// Count leading zeros
-let hasSideEffects = false in {
+let hasSideEffects = false in {
def CLZr32 : NVPTXInst<(outs Int32Regs:$d), (ins Int32Regs:$a),
"clz.b32 \t$d, $a;", []>;
def CLZr64 : NVPTXInst<(outs Int32Regs:$d), (ins Int64Regs:$a),
@@ -2937,7 +2937,7 @@ def : Pat<(i32 (zext (i16 (ctlz Int16Regs:$a)))),
(SUBi32ri (CLZr32 (CVT_u32_u16 Int16Regs:$a, CvtNONE)), 16)>;
// Population count
-let hasSideEffects = false in {
+let hasSideEffects = false in {
def POPCr32 : NVPTXInst<(outs Int32Regs:$d), (ins Int32Regs:$a),
"popc.b32 \t$d, $a;", []>;
def POPCr64 : NVPTXInst<(outs Int32Regs:$d), (ins Int64Regs:$a),
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXIntrinsics.td b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXIntrinsics.td
index d9d586a0a6..8ccd47c0fc 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXIntrinsics.td
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXIntrinsics.td
@@ -51,19 +51,19 @@ def ptx : PTX;
// Generates list of n sequential register names.
// E.g. RegNames<3,"r">.ret -> ["r0", "r1", "r2" ]
class RegSeq<int n, string prefix> {
- list<string> ret = !if(n, !listconcat(RegSeq<!sub(n, 1), prefix>.ret,
- [prefix # !sub(n, 1)]),
+ list<string> ret = !if(n, !listconcat(RegSeq<!sub(n, 1), prefix>.ret,
+ [prefix # !sub(n, 1)]),
[]);
}
class THREADMASK_INFO<bit sync> {
- list<bit> ret = !if(sync, [0, 1], [0]);
+ list<bit> ret = !if(sync, [0, 1], [0]);
}
//-----------------------------------
// Synchronization and shuffle functions
//-----------------------------------
-let isConvergent = true in {
+let isConvergent = true in {
def INT_BARRIER0 : NVPTXInst<(outs), (ins),
"bar.sync \t0;",
[(int_nvvm_barrier0)]>;
@@ -173,12 +173,12 @@ class SHFL_INSTR<bit sync, string mode, string reg, bit return_pred,
)];
}
-foreach sync = [false, true] in {
+foreach sync = [false, true] in {
foreach mode = ["up", "down", "bfly", "idx"] in {
foreach regclass = ["i32", "f32"] in {
- foreach return_pred = [false, true] in {
- foreach offset_imm = [false, true] in {
- foreach mask_imm = [false, true] in {
+ foreach return_pred = [false, true] in {
+ foreach offset_imm = [false, true] in {
+ foreach mask_imm = [false, true] in {
foreach threadmask_imm = THREADMASK_INFO<sync>.ret in {
def : SHFL_INSTR<sync, mode, regclass, return_pred,
offset_imm, mask_imm, threadmask_imm>,
@@ -274,7 +274,7 @@ defm MATCH_ALLP_SYNC_32 : MATCH_ALLP_SYNC<Int32Regs, "b32", int_nvvm_match_all_s
defm MATCH_ALLP_SYNC_64 : MATCH_ALLP_SYNC<Int64Regs, "b64", int_nvvm_match_all_sync_i64p,
i64imm>;
-} // isConvergent = true
+} // isConvergent = true
//-----------------------------------
// Explicit Memory Fence Functions
@@ -1548,7 +1548,7 @@ multiclass ATOM2N_impl<string OpStr, string IntTypeStr, string TypeStr,
!cast<Intrinsic>(
"int_nvvm_atomic_" # OpStr
# "_" # SpaceStr # "_" # IntTypeStr
- # !if(!empty(ScopeStr), "", "_" # ScopeStr)),
+ # !if(!empty(ScopeStr), "", "_" # ScopeStr)),
regclass, ImmType, Imm, ImmTy, Preds>;
}
multiclass ATOM3N_impl<string OpStr, string IntTypeStr, string TypeStr,
@@ -1562,7 +1562,7 @@ multiclass ATOM3N_impl<string OpStr, string IntTypeStr, string TypeStr,
!cast<Intrinsic>(
"int_nvvm_atomic_" # OpStr
# "_" # SpaceStr # "_" # IntTypeStr
- # !if(!empty(ScopeStr), "", "_" # ScopeStr)),
+ # !if(!empty(ScopeStr), "", "_" # ScopeStr)),
regclass, ImmType, Imm, ImmTy, Preds>;
}
@@ -2131,7 +2131,7 @@ def : Pat<(int_nvvm_rotate_b32 Int32Regs:$src, Int32Regs:$amt),
(ROTL32reg_sw Int32Regs:$src, Int32Regs:$amt)>,
Requires<[noHWROT32]> ;
-let hasSideEffects = false in {
+let hasSideEffects = false in {
def GET_LO_INT64 : NVPTXInst<(outs Int32Regs:$dst), (ins Int64Regs:$src),
!strconcat("{{\n\t",
".reg .b32 %dummy;\n\t",
@@ -2147,7 +2147,7 @@ let hasSideEffects = false in {
[]> ;
}
-let hasSideEffects = false in {
+let hasSideEffects = false in {
def PACK_TWO_INT32
: NVPTXInst<(outs Int64Regs:$dst), (ins Int32Regs:$lo, Int32Regs:$hi),
"mov.b64 \t$dst, {{$lo, $hi}};", []> ;
@@ -2159,7 +2159,7 @@ def : Pat<(int_nvvm_swap_lo_hi_b64 Int64Regs:$src),
// Funnel shift, requires >= sm_32. Does not trap if amt is out of range, so
// no side effects.
-let hasSideEffects = false in {
+let hasSideEffects = false in {
def SHF_L_WRAP_B32_IMM
: NVPTXInst<(outs Int32Regs:$dst),
(ins Int32Regs:$lo, Int32Regs:$hi, i32imm:$amt),
@@ -2242,7 +2242,7 @@ def : Pat<(int_nvvm_rotate_right_b64 Int64Regs:$src, Int32Regs:$amt),
// also defined in NVPTXReplaceImageHandles.cpp
// texmode_independent
-let IsTex = true, IsTexModeUnified = false in {
+let IsTex = true, IsTexModeUnified = false in {
// Texture fetch instructions using handles
def TEX_1D_F32_S32
: NVPTXInst<(outs Float32Regs:$r, Float32Regs:$g,
@@ -2925,7 +2925,7 @@ def TLD4_A_2D_U32_F32
// texmode_unified
-let IsTex = true, IsTexModeUnified = true in {
+let IsTex = true, IsTexModeUnified = true in {
// Texture fetch instructions using handles
def TEX_UNIFIED_1D_F32_S32
: NVPTXInst<(outs Float32Regs:$r, Float32Regs:$g,
@@ -3610,7 +3610,7 @@ def TLD4_UNIFIED_A_2D_U32_F32
//=== Surface load instructions
// .clamp variant
-let IsSuld = true in {
+let IsSuld = true in {
def SULD_1D_I8_CLAMP
: NVPTXInst<(outs Int16Regs:$r),
(ins Int64Regs:$s, Int32Regs:$x),
@@ -3922,7 +3922,7 @@ def SULD_3D_V4I32_CLAMP
// .trap variant
-let IsSuld = true in {
+let IsSuld = true in {
def SULD_1D_I8_TRAP
: NVPTXInst<(outs Int16Regs:$r),
(ins Int64Regs:$s, Int32Regs:$x),
@@ -4233,7 +4233,7 @@ def SULD_3D_V4I32_TRAP
}
// .zero variant
-let IsSuld = true in {
+let IsSuld = true in {
def SULD_1D_I8_ZERO
: NVPTXInst<(outs Int16Regs:$r),
(ins Int64Regs:$s, Int32Regs:$x),
@@ -4547,7 +4547,7 @@ def SULD_3D_V4I32_ZERO
// Texture Query Intrinsics
//-----------------------------------
-let IsSurfTexQuery = true in {
+let IsSurfTexQuery = true in {
def TXQ_CHANNEL_ORDER
: NVPTXInst<(outs Int32Regs:$d), (ins Int64Regs:$a),
"txq.channel_order.b32 \t$d, [$a];",
@@ -4604,7 +4604,7 @@ def : Pat<(int_nvvm_txq_num_mipmap_levels Int64Regs:$a),
// Surface Query Intrinsics
//-----------------------------------
-let IsSurfTexQuery = true in {
+let IsSurfTexQuery = true in {
def SUQ_CHANNEL_ORDER
: NVPTXInst<(outs Int32Regs:$d), (ins Int64Regs:$a),
"suq.channel_order.b32 \t$d, [$a];",
@@ -4663,7 +4663,7 @@ def ISTYPEP_TEXTURE
//===- Surface Stores -----------------------------------------------------===//
-let IsSust = true in {
+let IsSust = true in {
// Unformatted
// .clamp variant
def SUST_B_1D_B8_CLAMP
@@ -7361,13 +7361,13 @@ class WMMA_REGINFO<WMMA_REGS r>
!eq(ptx_elt_type, "b1") : Int32Regs);
// Instruction input/output arguments for the fragment.
- list<NVPTXRegClass> ptx_regs = !listsplat(regclass, !size(regs));
+ list<NVPTXRegClass> ptx_regs = !listsplat(regclass, !size(regs));
// List of register names for the fragment -- ["ra0", "ra1",...]
list<string> reg_names = RegSeq<!size(ptx_regs), "r"#frag>.ret;
// Generates "{{$r0, $r1,.... $rN-1}}" for use in asm string construction.
- string regstring = "{{$" # !interleave(reg_names, ", $") # "}}";
+ string regstring = "{{$" # !interleave(reg_names, ", $") # "}}";
// Predicates for particular fragment variant. Technically those are
// per-instruction predicates, but currently all fragments that can be used in
@@ -7450,13 +7450,13 @@ class WMMA_LOAD<WMMA_REGINFO Frag, string Layout, string Space, bit WithStride,
// To match the right intrinsic, we need to build AS-constrained PatFrag.
// Operands is a dag equivalent in shape to Args, but using (ops node:$name, .....).
dag PFOperands = !if(WithStride, (ops node:$src, node:$ldm), (ops node:$src));
- dag PFOperandsIntr = !if(WithStride, (Intr node:$src, node:$ldm), (Intr node:$src));
+ dag PFOperandsIntr = !if(WithStride, (Intr node:$src, node:$ldm), (Intr node:$src));
// Build PatFrag that only matches particular address space.
PatFrag IntrFrag = PatFrag<PFOperands,
- PFOperandsIntr,
+ PFOperandsIntr,
!cond(!eq(Space, ".shared"): AS_match.shared,
!eq(Space, ".global"): AS_match.global,
- true: AS_match.generic)>;
+ true: AS_match.generic)>;
// Build AS-constrained pattern.
let IntrinsicPattern = BuildPatternPF<IntrFrag, Args>.ret;
@@ -7491,14 +7491,14 @@ class WMMA_STORE_D<WMMA_REGINFO Frag, string Layout, string Space,
// To match the right intrinsic, we need to build AS-constrained PatFrag.
// Operands is a dag equivalent in shape to Args, but using (ops node:$name, .....).
dag PFOperands = !con((ops node:$dst),
- !dag(ops, !listsplat(node, !size(Frag.regs)), Frag.reg_names),
+ !dag(ops, !listsplat(node, !size(Frag.regs)), Frag.reg_names),
!if(WithStride, (ops node:$ldm), (ops)));
// Build PatFrag that only matches particular address space.
PatFrag IntrFrag = PatFrag<PFOperands,
!foreach(tmp, PFOperands, !subst(ops, Intr, tmp)),
!cond(!eq(Space, ".shared"): AS_match.shared,
!eq(Space, ".global"): AS_match.global,
- true: AS_match.generic)>;
+ true: AS_match.generic)>;
// Build AS-constrained pattern.
let IntrinsicPattern = BuildPatternPF<IntrFrag, Args>.ret;
@@ -7519,14 +7519,14 @@ class WMMA_STORE_D<WMMA_REGINFO Frag, string Layout, string Space,
// Create all load/store variants
defset list<WMMA_INSTR> MMA_LDSTs = {
foreach layout = ["row", "col"] in {
- foreach stride = [false, true] in {
+ foreach stride = [false, true] in {
foreach space = [".global", ".shared", ""] in {
foreach addr = [imem, Int32Regs, Int64Regs, MEMri, MEMri64] in {
foreach frag = NVVM_MMA_OPS.all_ld_ops in
- if NVVM_MMA_SUPPORTED<[frag], layout>.ret then
+ if NVVM_MMA_SUPPORTED<[frag], layout>.ret then
def : WMMA_LOAD<WMMA_REGINFO<frag>, layout, space, stride, addr>;
foreach frag = NVVM_MMA_OPS.all_st_ops in
- if NVVM_MMA_SUPPORTED<[frag], layout>.ret then
+ if NVVM_MMA_SUPPORTED<[frag], layout>.ret then
def : WMMA_STORE_D<WMMA_REGINFO<frag>, layout, space, stride, addr>;
} // addr
} // space
@@ -7584,7 +7584,7 @@ defset list<WMMA_INSTR> MMAs = {
foreach layout_b = ["row", "col"] in {
foreach satf = [0, 1] in {
foreach op = NVVM_MMA_OPS.all_mma_ops in {
- if NVVM_MMA_SUPPORTED<op, layout_a, layout_b, satf>.ret then {
+ if NVVM_MMA_SUPPORTED<op, layout_a, layout_b, satf>.ret then {
def : WMMA_MMA<WMMA_REGINFO<op[0]>,
WMMA_REGINFO<op[1]>,
WMMA_REGINFO<op[2]>,
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXLowerArgs.cpp b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXLowerArgs.cpp
index 0048984968..fd58ff1378 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXLowerArgs.cpp
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXLowerArgs.cpp
@@ -172,12 +172,12 @@ void NVPTXLowerArgs::handleByValParam(Argument *Arg) {
Value *ArgInParam = new AddrSpaceCastInst(
Arg, PointerType::get(StructType, ADDRESS_SPACE_PARAM), Arg->getName(),
FirstInst);
- // Be sure to propagate alignment to this load; LLVM doesn't know that NVPTX
- // addrspacecast preserves alignment. Since params are constant, this load is
- // definitely not volatile.
+ // Be sure to propagate alignment to this load; LLVM doesn't know that NVPTX
+ // addrspacecast preserves alignment. Since params are constant, this load is
+ // definitely not volatile.
LoadInst *LI =
- new LoadInst(StructType, ArgInParam, Arg->getName(),
- /*isVolatile=*/false, AllocA->getAlign(), FirstInst);
+ new LoadInst(StructType, ArgInParam, Arg->getName(),
+ /*isVolatile=*/false, AllocA->getAlign(), FirstInst);
new StoreInst(LI, AllocA, FirstInst);
}
@@ -218,7 +218,7 @@ bool NVPTXLowerArgs::runOnKernelFunction(Function &F) {
for (auto &I : B) {
if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
if (LI->getType()->isPointerTy()) {
- Value *UO = getUnderlyingObject(LI->getPointerOperand());
+ Value *UO = getUnderlyingObject(LI->getPointerOperand());
if (Argument *Arg = dyn_cast<Argument>(UO)) {
if (Arg->hasByValAttr()) {
// LI is a load from a pointer within a byval kernel parameter.
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp
index 9829fa416b..756355f75e 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp
@@ -69,8 +69,8 @@ bool NVPTXPrologEpilogPass::runOnMachineFunction(MachineFunction &MF) {
"operand of a DBG_VALUE machine instruction");
Register Reg;
int64_t Offset =
- TFI.getFrameIndexReference(MF, MI.getOperand(0).getIndex(), Reg)
- .getFixed();
+ TFI.getFrameIndexReference(MF, MI.getOperand(0).getIndex(), Reg)
+ .getFixed();
MI.getOperand(0).ChangeToRegister(Reg, /*isDef=*/false);
MI.getOperand(0).setIsDebug();
auto *DIExpr = DIExpression::prepend(
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXRegisterInfo.td b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXRegisterInfo.td
index 7d6dff48d1..19895a20ba 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXRegisterInfo.td
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXRegisterInfo.td
@@ -30,7 +30,7 @@ def VRDepot : NVPTXReg<"%Depot">;
// We use virtual registers, but define a few physical registers here to keep
// SDAG and the MachineInstr layers happy.
-foreach i = 0...4 in {
+foreach i = 0...4 in {
def P#i : NVPTXReg<"%p"#i>; // Predicate
def RS#i : NVPTXReg<"%rs"#i>; // 16-bit
def R#i : NVPTXReg<"%r"#i>; // 32-bit
@@ -47,7 +47,7 @@ foreach i = 0...4 in {
def da#i : NVPTXReg<"%da"#i>;
}
-foreach i = 0...31 in {
+foreach i = 0...31 in {
def ENVREG#i : NVPTXReg<"%envreg"#i>;
}
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXSubtarget.cpp b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXSubtarget.cpp
index 9d998619f8..05c20369ab 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXSubtarget.cpp
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXSubtarget.cpp
@@ -35,7 +35,7 @@ NVPTXSubtarget &NVPTXSubtarget::initializeSubtargetDependencies(StringRef CPU,
// Provide the default CPU if we don't have one.
TargetName = std::string(CPU.empty() ? "sm_20" : CPU);
- ParseSubtargetFeatures(TargetName, /*TuneCPU*/ TargetName, FS);
+ ParseSubtargetFeatures(TargetName, /*TuneCPU*/ TargetName, FS);
// Set default to PTX 3.2 (CUDA 5.5)
if (PTXVersion == 0) {
@@ -48,9 +48,9 @@ NVPTXSubtarget &NVPTXSubtarget::initializeSubtargetDependencies(StringRef CPU,
NVPTXSubtarget::NVPTXSubtarget(const Triple &TT, const std::string &CPU,
const std::string &FS,
const NVPTXTargetMachine &TM)
- : NVPTXGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), PTXVersion(0),
- SmVersion(20), TM(TM), InstrInfo(),
- TLInfo(TM, initializeSubtargetDependencies(CPU, FS)), FrameLowering() {}
+ : NVPTXGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), PTXVersion(0),
+ SmVersion(20), TM(TM), InstrInfo(),
+ TLInfo(TM, initializeSubtargetDependencies(CPU, FS)), FrameLowering() {}
bool NVPTXSubtarget::hasImageHandles() const {
// Enable handles for Kepler+, where CUDA supports indirect surfaces and
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXSubtarget.h b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXSubtarget.h
index 886f200160..9a249d3da3 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXSubtarget.h
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXSubtarget.h
@@ -83,7 +83,7 @@ public:
unsigned getPTXVersion() const { return PTXVersion; }
NVPTXSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);
- void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
+ void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
};
} // End llvm namespace
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetMachine.cpp b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetMachine.cpp
index 57fe1b8fa8..f1a82f1cf6 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetMachine.cpp
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetMachine.cpp
@@ -24,7 +24,7 @@
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Pass.h"
-#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Passes/PassBuilder.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/TargetMachine.h"
@@ -171,11 +171,11 @@ public:
void addFastRegAlloc() override;
void addOptimizedRegAlloc() override;
- bool addRegAssignAndRewriteFast() override {
+ bool addRegAssignAndRewriteFast() override {
llvm_unreachable("should not be used");
}
- bool addRegAssignAndRewriteOptimized() override {
+ bool addRegAssignAndRewriteOptimized() override {
llvm_unreachable("should not be used");
}
@@ -206,32 +206,32 @@ void NVPTXTargetMachine::adjustPassManager(PassManagerBuilder &Builder) {
});
}
-void NVPTXTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB,
- bool DebugPassManager) {
- PB.registerPipelineParsingCallback(
- [](StringRef PassName, FunctionPassManager &PM,
- ArrayRef<PassBuilder::PipelineElement>) {
- if (PassName == "nvvm-reflect") {
- PM.addPass(NVVMReflectPass());
- return true;
- }
- if (PassName == "nvvm-intr-range") {
- PM.addPass(NVVMIntrRangePass());
- return true;
- }
- return false;
- });
-
- PB.registerPipelineStartEPCallback(
- [this, DebugPassManager](ModulePassManager &PM,
- PassBuilder::OptimizationLevel Level) {
- FunctionPassManager FPM(DebugPassManager);
- FPM.addPass(NVVMReflectPass(Subtarget.getSmVersion()));
- FPM.addPass(NVVMIntrRangePass(Subtarget.getSmVersion()));
- PM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
- });
-}
-
+void NVPTXTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB,
+ bool DebugPassManager) {
+ PB.registerPipelineParsingCallback(
+ [](StringRef PassName, FunctionPassManager &PM,
+ ArrayRef<PassBuilder::PipelineElement>) {
+ if (PassName == "nvvm-reflect") {
+ PM.addPass(NVVMReflectPass());
+ return true;
+ }
+ if (PassName == "nvvm-intr-range") {
+ PM.addPass(NVVMIntrRangePass());
+ return true;
+ }
+ return false;
+ });
+
+ PB.registerPipelineStartEPCallback(
+ [this, DebugPassManager](ModulePassManager &PM,
+ PassBuilder::OptimizationLevel Level) {
+ FunctionPassManager FPM(DebugPassManager);
+ FPM.addPass(NVVMReflectPass(Subtarget.getSmVersion()));
+ FPM.addPass(NVVMIntrRangePass(Subtarget.getSmVersion()));
+ PM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+ });
+}
+
TargetTransformInfo
NVPTXTargetMachine::getTargetTransformInfo(const Function &F) {
return TargetTransformInfo(NVPTXTTIImpl(this, F));
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetMachine.h b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetMachine.h
index 2a2defe0bf..bef541c2b2 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetMachine.h
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetMachine.h
@@ -62,8 +62,8 @@ public:
}
void adjustPassManager(PassManagerBuilder &) override;
- void registerPassBuilderCallbacks(PassBuilder &PB,
- bool DebugPassManager) override;
+ void registerPassBuilderCallbacks(PassBuilder &PB,
+ bool DebugPassManager) override;
TargetTransformInfo getTargetTransformInfo(const Function &F) override;
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetTransformInfo.cpp b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetTransformInfo.cpp
index 28662d9314..d4b2ae3840 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetTransformInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetTransformInfo.cpp
@@ -111,263 +111,263 @@ bool NVPTXTTIImpl::isSourceOfDivergence(const Value *V) {
return false;
}
-// Convert NVVM intrinsics to target-generic LLVM code where possible.
-static Instruction *simplifyNvvmIntrinsic(IntrinsicInst *II, InstCombiner &IC) {
- // Each NVVM intrinsic we can simplify can be replaced with one of:
- //
- // * an LLVM intrinsic,
- // * an LLVM cast operation,
- // * an LLVM binary operation, or
- // * ad-hoc LLVM IR for the particular operation.
-
- // Some transformations are only valid when the module's
- // flush-denormals-to-zero (ftz) setting is true/false, whereas other
- // transformations are valid regardless of the module's ftz setting.
- enum FtzRequirementTy {
- FTZ_Any, // Any ftz setting is ok.
- FTZ_MustBeOn, // Transformation is valid only if ftz is on.
- FTZ_MustBeOff, // Transformation is valid only if ftz is off.
- };
- // Classes of NVVM intrinsics that can't be replaced one-to-one with a
- // target-generic intrinsic, cast op, or binary op but that we can nonetheless
- // simplify.
- enum SpecialCase {
- SPC_Reciprocal,
- };
-
- // SimplifyAction is a poor-man's variant (plus an additional flag) that
- // represents how to replace an NVVM intrinsic with target-generic LLVM IR.
- struct SimplifyAction {
- // Invariant: At most one of these Optionals has a value.
- Optional<Intrinsic::ID> IID;
- Optional<Instruction::CastOps> CastOp;
- Optional<Instruction::BinaryOps> BinaryOp;
- Optional<SpecialCase> Special;
-
- FtzRequirementTy FtzRequirement = FTZ_Any;
-
- SimplifyAction() = default;
-
- SimplifyAction(Intrinsic::ID IID, FtzRequirementTy FtzReq)
- : IID(IID), FtzRequirement(FtzReq) {}
-
- // Cast operations don't have anything to do with FTZ, so we skip that
- // argument.
- SimplifyAction(Instruction::CastOps CastOp) : CastOp(CastOp) {}
-
- SimplifyAction(Instruction::BinaryOps BinaryOp, FtzRequirementTy FtzReq)
- : BinaryOp(BinaryOp), FtzRequirement(FtzReq) {}
-
- SimplifyAction(SpecialCase Special, FtzRequirementTy FtzReq)
- : Special(Special), FtzRequirement(FtzReq) {}
- };
-
- // Try to generate a SimplifyAction describing how to replace our
- // IntrinsicInstr with target-generic LLVM IR.
- const SimplifyAction Action = [II]() -> SimplifyAction {
- switch (II->getIntrinsicID()) {
- // NVVM intrinsics that map directly to LLVM intrinsics.
- case Intrinsic::nvvm_ceil_d:
- return {Intrinsic::ceil, FTZ_Any};
- case Intrinsic::nvvm_ceil_f:
- return {Intrinsic::ceil, FTZ_MustBeOff};
- case Intrinsic::nvvm_ceil_ftz_f:
- return {Intrinsic::ceil, FTZ_MustBeOn};
- case Intrinsic::nvvm_fabs_d:
- return {Intrinsic::fabs, FTZ_Any};
- case Intrinsic::nvvm_fabs_f:
- return {Intrinsic::fabs, FTZ_MustBeOff};
- case Intrinsic::nvvm_fabs_ftz_f:
- return {Intrinsic::fabs, FTZ_MustBeOn};
- case Intrinsic::nvvm_floor_d:
- return {Intrinsic::floor, FTZ_Any};
- case Intrinsic::nvvm_floor_f:
- return {Intrinsic::floor, FTZ_MustBeOff};
- case Intrinsic::nvvm_floor_ftz_f:
- return {Intrinsic::floor, FTZ_MustBeOn};
- case Intrinsic::nvvm_fma_rn_d:
- return {Intrinsic::fma, FTZ_Any};
- case Intrinsic::nvvm_fma_rn_f:
- return {Intrinsic::fma, FTZ_MustBeOff};
- case Intrinsic::nvvm_fma_rn_ftz_f:
- return {Intrinsic::fma, FTZ_MustBeOn};
- case Intrinsic::nvvm_fmax_d:
- return {Intrinsic::maxnum, FTZ_Any};
- case Intrinsic::nvvm_fmax_f:
- return {Intrinsic::maxnum, FTZ_MustBeOff};
- case Intrinsic::nvvm_fmax_ftz_f:
- return {Intrinsic::maxnum, FTZ_MustBeOn};
- case Intrinsic::nvvm_fmin_d:
- return {Intrinsic::minnum, FTZ_Any};
- case Intrinsic::nvvm_fmin_f:
- return {Intrinsic::minnum, FTZ_MustBeOff};
- case Intrinsic::nvvm_fmin_ftz_f:
- return {Intrinsic::minnum, FTZ_MustBeOn};
- case Intrinsic::nvvm_round_d:
- return {Intrinsic::round, FTZ_Any};
- case Intrinsic::nvvm_round_f:
- return {Intrinsic::round, FTZ_MustBeOff};
- case Intrinsic::nvvm_round_ftz_f:
- return {Intrinsic::round, FTZ_MustBeOn};
- case Intrinsic::nvvm_sqrt_rn_d:
- return {Intrinsic::sqrt, FTZ_Any};
- case Intrinsic::nvvm_sqrt_f:
- // nvvm_sqrt_f is a special case. For most intrinsics, foo_ftz_f is the
- // ftz version, and foo_f is the non-ftz version. But nvvm_sqrt_f adopts
- // the ftz-ness of the surrounding code. sqrt_rn_f and sqrt_rn_ftz_f are
- // the versions with explicit ftz-ness.
- return {Intrinsic::sqrt, FTZ_Any};
- case Intrinsic::nvvm_sqrt_rn_f:
- return {Intrinsic::sqrt, FTZ_MustBeOff};
- case Intrinsic::nvvm_sqrt_rn_ftz_f:
- return {Intrinsic::sqrt, FTZ_MustBeOn};
- case Intrinsic::nvvm_trunc_d:
- return {Intrinsic::trunc, FTZ_Any};
- case Intrinsic::nvvm_trunc_f:
- return {Intrinsic::trunc, FTZ_MustBeOff};
- case Intrinsic::nvvm_trunc_ftz_f:
- return {Intrinsic::trunc, FTZ_MustBeOn};
-
- // NVVM intrinsics that map to LLVM cast operations.
- //
- // Note that llvm's target-generic conversion operators correspond to the rz
- // (round to zero) versions of the nvvm conversion intrinsics, even though
- // most everything else here uses the rn (round to nearest even) nvvm ops.
- case Intrinsic::nvvm_d2i_rz:
- case Intrinsic::nvvm_f2i_rz:
- case Intrinsic::nvvm_d2ll_rz:
- case Intrinsic::nvvm_f2ll_rz:
- return {Instruction::FPToSI};
- case Intrinsic::nvvm_d2ui_rz:
- case Intrinsic::nvvm_f2ui_rz:
- case Intrinsic::nvvm_d2ull_rz:
- case Intrinsic::nvvm_f2ull_rz:
- return {Instruction::FPToUI};
- case Intrinsic::nvvm_i2d_rz:
- case Intrinsic::nvvm_i2f_rz:
- case Intrinsic::nvvm_ll2d_rz:
- case Intrinsic::nvvm_ll2f_rz:
- return {Instruction::SIToFP};
- case Intrinsic::nvvm_ui2d_rz:
- case Intrinsic::nvvm_ui2f_rz:
- case Intrinsic::nvvm_ull2d_rz:
- case Intrinsic::nvvm_ull2f_rz:
- return {Instruction::UIToFP};
-
- // NVVM intrinsics that map to LLVM binary ops.
- case Intrinsic::nvvm_add_rn_d:
- return {Instruction::FAdd, FTZ_Any};
- case Intrinsic::nvvm_add_rn_f:
- return {Instruction::FAdd, FTZ_MustBeOff};
- case Intrinsic::nvvm_add_rn_ftz_f:
- return {Instruction::FAdd, FTZ_MustBeOn};
- case Intrinsic::nvvm_mul_rn_d:
- return {Instruction::FMul, FTZ_Any};
- case Intrinsic::nvvm_mul_rn_f:
- return {Instruction::FMul, FTZ_MustBeOff};
- case Intrinsic::nvvm_mul_rn_ftz_f:
- return {Instruction::FMul, FTZ_MustBeOn};
- case Intrinsic::nvvm_div_rn_d:
- return {Instruction::FDiv, FTZ_Any};
- case Intrinsic::nvvm_div_rn_f:
- return {Instruction::FDiv, FTZ_MustBeOff};
- case Intrinsic::nvvm_div_rn_ftz_f:
- return {Instruction::FDiv, FTZ_MustBeOn};
-
- // The remainder of cases are NVVM intrinsics that map to LLVM idioms, but
- // need special handling.
- //
- // We seem to be missing intrinsics for rcp.approx.{ftz.}f32, which is just
- // as well.
- case Intrinsic::nvvm_rcp_rn_d:
- return {SPC_Reciprocal, FTZ_Any};
- case Intrinsic::nvvm_rcp_rn_f:
- return {SPC_Reciprocal, FTZ_MustBeOff};
- case Intrinsic::nvvm_rcp_rn_ftz_f:
- return {SPC_Reciprocal, FTZ_MustBeOn};
-
- // We do not currently simplify intrinsics that give an approximate
- // answer. These include:
- //
- // - nvvm_cos_approx_{f,ftz_f}
- // - nvvm_ex2_approx_{d,f,ftz_f}
- // - nvvm_lg2_approx_{d,f,ftz_f}
- // - nvvm_sin_approx_{f,ftz_f}
- // - nvvm_sqrt_approx_{f,ftz_f}
- // - nvvm_rsqrt_approx_{d,f,ftz_f}
- // - nvvm_div_approx_{ftz_d,ftz_f,f}
- // - nvvm_rcp_approx_ftz_d
- //
- // Ideally we'd encode them as e.g. "fast call @llvm.cos", where "fast"
- // means that fastmath is enabled in the intrinsic. Unfortunately only
- // binary operators (currently) have a fastmath bit in SelectionDAG, so
- // this information gets lost and we can't select on it.
- //
- // TODO: div and rcp are lowered to a binary op, so these we could in
- // theory lower them to "fast fdiv".
-
- default:
- return {};
- }
- }();
-
- // If Action.FtzRequirementTy is not satisfied by the module's ftz state, we
- // can bail out now. (Notice that in the case that IID is not an NVVM
- // intrinsic, we don't have to look up any module metadata, as
- // FtzRequirementTy will be FTZ_Any.)
- if (Action.FtzRequirement != FTZ_Any) {
- StringRef Attr = II->getFunction()
- ->getFnAttribute("denormal-fp-math-f32")
- .getValueAsString();
- DenormalMode Mode = parseDenormalFPAttribute(Attr);
- bool FtzEnabled = Mode.Output != DenormalMode::IEEE;
-
- if (FtzEnabled != (Action.FtzRequirement == FTZ_MustBeOn))
- return nullptr;
- }
-
- // Simplify to target-generic intrinsic.
- if (Action.IID) {
- SmallVector<Value *, 4> Args(II->arg_operands());
- // All the target-generic intrinsics currently of interest to us have one
- // type argument, equal to that of the nvvm intrinsic's argument.
- Type *Tys[] = {II->getArgOperand(0)->getType()};
- return CallInst::Create(
- Intrinsic::getDeclaration(II->getModule(), *Action.IID, Tys), Args);
- }
-
- // Simplify to target-generic binary op.
- if (Action.BinaryOp)
- return BinaryOperator::Create(*Action.BinaryOp, II->getArgOperand(0),
- II->getArgOperand(1), II->getName());
-
- // Simplify to target-generic cast op.
- if (Action.CastOp)
- return CastInst::Create(*Action.CastOp, II->getArgOperand(0), II->getType(),
- II->getName());
-
- // All that's left are the special cases.
- if (!Action.Special)
- return nullptr;
-
- switch (*Action.Special) {
- case SPC_Reciprocal:
- // Simplify reciprocal.
- return BinaryOperator::Create(
- Instruction::FDiv, ConstantFP::get(II->getArgOperand(0)->getType(), 1),
- II->getArgOperand(0), II->getName());
- }
- llvm_unreachable("All SpecialCase enumerators should be handled in switch.");
-}
-
-Optional<Instruction *>
-NVPTXTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
- if (Instruction *I = simplifyNvvmIntrinsic(&II, IC)) {
- return I;
- }
- return None;
-}
-
+// Convert NVVM intrinsics to target-generic LLVM code where possible.
+static Instruction *simplifyNvvmIntrinsic(IntrinsicInst *II, InstCombiner &IC) {
+ // Each NVVM intrinsic we can simplify can be replaced with one of:
+ //
+ // * an LLVM intrinsic,
+ // * an LLVM cast operation,
+ // * an LLVM binary operation, or
+ // * ad-hoc LLVM IR for the particular operation.
+
+ // Some transformations are only valid when the module's
+ // flush-denormals-to-zero (ftz) setting is true/false, whereas other
+ // transformations are valid regardless of the module's ftz setting.
+ enum FtzRequirementTy {
+ FTZ_Any, // Any ftz setting is ok.
+ FTZ_MustBeOn, // Transformation is valid only if ftz is on.
+ FTZ_MustBeOff, // Transformation is valid only if ftz is off.
+ };
+ // Classes of NVVM intrinsics that can't be replaced one-to-one with a
+ // target-generic intrinsic, cast op, or binary op but that we can nonetheless
+ // simplify.
+ enum SpecialCase {
+ SPC_Reciprocal,
+ };
+
+ // SimplifyAction is a poor-man's variant (plus an additional flag) that
+ // represents how to replace an NVVM intrinsic with target-generic LLVM IR.
+ struct SimplifyAction {
+ // Invariant: At most one of these Optionals has a value.
+ Optional<Intrinsic::ID> IID;
+ Optional<Instruction::CastOps> CastOp;
+ Optional<Instruction::BinaryOps> BinaryOp;
+ Optional<SpecialCase> Special;
+
+ FtzRequirementTy FtzRequirement = FTZ_Any;
+
+ SimplifyAction() = default;
+
+ SimplifyAction(Intrinsic::ID IID, FtzRequirementTy FtzReq)
+ : IID(IID), FtzRequirement(FtzReq) {}
+
+ // Cast operations don't have anything to do with FTZ, so we skip that
+ // argument.
+ SimplifyAction(Instruction::CastOps CastOp) : CastOp(CastOp) {}
+
+ SimplifyAction(Instruction::BinaryOps BinaryOp, FtzRequirementTy FtzReq)
+ : BinaryOp(BinaryOp), FtzRequirement(FtzReq) {}
+
+ SimplifyAction(SpecialCase Special, FtzRequirementTy FtzReq)
+ : Special(Special), FtzRequirement(FtzReq) {}
+ };
+
+ // Try to generate a SimplifyAction describing how to replace our
+ // IntrinsicInstr with target-generic LLVM IR.
+ const SimplifyAction Action = [II]() -> SimplifyAction {
+ switch (II->getIntrinsicID()) {
+ // NVVM intrinsics that map directly to LLVM intrinsics.
+ case Intrinsic::nvvm_ceil_d:
+ return {Intrinsic::ceil, FTZ_Any};
+ case Intrinsic::nvvm_ceil_f:
+ return {Intrinsic::ceil, FTZ_MustBeOff};
+ case Intrinsic::nvvm_ceil_ftz_f:
+ return {Intrinsic::ceil, FTZ_MustBeOn};
+ case Intrinsic::nvvm_fabs_d:
+ return {Intrinsic::fabs, FTZ_Any};
+ case Intrinsic::nvvm_fabs_f:
+ return {Intrinsic::fabs, FTZ_MustBeOff};
+ case Intrinsic::nvvm_fabs_ftz_f:
+ return {Intrinsic::fabs, FTZ_MustBeOn};
+ case Intrinsic::nvvm_floor_d:
+ return {Intrinsic::floor, FTZ_Any};
+ case Intrinsic::nvvm_floor_f:
+ return {Intrinsic::floor, FTZ_MustBeOff};
+ case Intrinsic::nvvm_floor_ftz_f:
+ return {Intrinsic::floor, FTZ_MustBeOn};
+ case Intrinsic::nvvm_fma_rn_d:
+ return {Intrinsic::fma, FTZ_Any};
+ case Intrinsic::nvvm_fma_rn_f:
+ return {Intrinsic::fma, FTZ_MustBeOff};
+ case Intrinsic::nvvm_fma_rn_ftz_f:
+ return {Intrinsic::fma, FTZ_MustBeOn};
+ case Intrinsic::nvvm_fmax_d:
+ return {Intrinsic::maxnum, FTZ_Any};
+ case Intrinsic::nvvm_fmax_f:
+ return {Intrinsic::maxnum, FTZ_MustBeOff};
+ case Intrinsic::nvvm_fmax_ftz_f:
+ return {Intrinsic::maxnum, FTZ_MustBeOn};
+ case Intrinsic::nvvm_fmin_d:
+ return {Intrinsic::minnum, FTZ_Any};
+ case Intrinsic::nvvm_fmin_f:
+ return {Intrinsic::minnum, FTZ_MustBeOff};
+ case Intrinsic::nvvm_fmin_ftz_f:
+ return {Intrinsic::minnum, FTZ_MustBeOn};
+ case Intrinsic::nvvm_round_d:
+ return {Intrinsic::round, FTZ_Any};
+ case Intrinsic::nvvm_round_f:
+ return {Intrinsic::round, FTZ_MustBeOff};
+ case Intrinsic::nvvm_round_ftz_f:
+ return {Intrinsic::round, FTZ_MustBeOn};
+ case Intrinsic::nvvm_sqrt_rn_d:
+ return {Intrinsic::sqrt, FTZ_Any};
+ case Intrinsic::nvvm_sqrt_f:
+ // nvvm_sqrt_f is a special case. For most intrinsics, foo_ftz_f is the
+ // ftz version, and foo_f is the non-ftz version. But nvvm_sqrt_f adopts
+ // the ftz-ness of the surrounding code. sqrt_rn_f and sqrt_rn_ftz_f are
+ // the versions with explicit ftz-ness.
+ return {Intrinsic::sqrt, FTZ_Any};
+ case Intrinsic::nvvm_sqrt_rn_f:
+ return {Intrinsic::sqrt, FTZ_MustBeOff};
+ case Intrinsic::nvvm_sqrt_rn_ftz_f:
+ return {Intrinsic::sqrt, FTZ_MustBeOn};
+ case Intrinsic::nvvm_trunc_d:
+ return {Intrinsic::trunc, FTZ_Any};
+ case Intrinsic::nvvm_trunc_f:
+ return {Intrinsic::trunc, FTZ_MustBeOff};
+ case Intrinsic::nvvm_trunc_ftz_f:
+ return {Intrinsic::trunc, FTZ_MustBeOn};
+
+ // NVVM intrinsics that map to LLVM cast operations.
+ //
+ // Note that llvm's target-generic conversion operators correspond to the rz
+ // (round to zero) versions of the nvvm conversion intrinsics, even though
+ // most everything else here uses the rn (round to nearest even) nvvm ops.
+ case Intrinsic::nvvm_d2i_rz:
+ case Intrinsic::nvvm_f2i_rz:
+ case Intrinsic::nvvm_d2ll_rz:
+ case Intrinsic::nvvm_f2ll_rz:
+ return {Instruction::FPToSI};
+ case Intrinsic::nvvm_d2ui_rz:
+ case Intrinsic::nvvm_f2ui_rz:
+ case Intrinsic::nvvm_d2ull_rz:
+ case Intrinsic::nvvm_f2ull_rz:
+ return {Instruction::FPToUI};
+ case Intrinsic::nvvm_i2d_rz:
+ case Intrinsic::nvvm_i2f_rz:
+ case Intrinsic::nvvm_ll2d_rz:
+ case Intrinsic::nvvm_ll2f_rz:
+ return {Instruction::SIToFP};
+ case Intrinsic::nvvm_ui2d_rz:
+ case Intrinsic::nvvm_ui2f_rz:
+ case Intrinsic::nvvm_ull2d_rz:
+ case Intrinsic::nvvm_ull2f_rz:
+ return {Instruction::UIToFP};
+
+ // NVVM intrinsics that map to LLVM binary ops.
+ case Intrinsic::nvvm_add_rn_d:
+ return {Instruction::FAdd, FTZ_Any};
+ case Intrinsic::nvvm_add_rn_f:
+ return {Instruction::FAdd, FTZ_MustBeOff};
+ case Intrinsic::nvvm_add_rn_ftz_f:
+ return {Instruction::FAdd, FTZ_MustBeOn};
+ case Intrinsic::nvvm_mul_rn_d:
+ return {Instruction::FMul, FTZ_Any};
+ case Intrinsic::nvvm_mul_rn_f:
+ return {Instruction::FMul, FTZ_MustBeOff};
+ case Intrinsic::nvvm_mul_rn_ftz_f:
+ return {Instruction::FMul, FTZ_MustBeOn};
+ case Intrinsic::nvvm_div_rn_d:
+ return {Instruction::FDiv, FTZ_Any};
+ case Intrinsic::nvvm_div_rn_f:
+ return {Instruction::FDiv, FTZ_MustBeOff};
+ case Intrinsic::nvvm_div_rn_ftz_f:
+ return {Instruction::FDiv, FTZ_MustBeOn};
+
+ // The remainder of cases are NVVM intrinsics that map to LLVM idioms, but
+ // need special handling.
+ //
+ // We seem to be missing intrinsics for rcp.approx.{ftz.}f32, which is just
+ // as well.
+ case Intrinsic::nvvm_rcp_rn_d:
+ return {SPC_Reciprocal, FTZ_Any};
+ case Intrinsic::nvvm_rcp_rn_f:
+ return {SPC_Reciprocal, FTZ_MustBeOff};
+ case Intrinsic::nvvm_rcp_rn_ftz_f:
+ return {SPC_Reciprocal, FTZ_MustBeOn};
+
+ // We do not currently simplify intrinsics that give an approximate
+ // answer. These include:
+ //
+ // - nvvm_cos_approx_{f,ftz_f}
+ // - nvvm_ex2_approx_{d,f,ftz_f}
+ // - nvvm_lg2_approx_{d,f,ftz_f}
+ // - nvvm_sin_approx_{f,ftz_f}
+ // - nvvm_sqrt_approx_{f,ftz_f}
+ // - nvvm_rsqrt_approx_{d,f,ftz_f}
+ // - nvvm_div_approx_{ftz_d,ftz_f,f}
+ // - nvvm_rcp_approx_ftz_d
+ //
+ // Ideally we'd encode them as e.g. "fast call @llvm.cos", where "fast"
+ // means that fastmath is enabled in the intrinsic. Unfortunately only
+ // binary operators (currently) have a fastmath bit in SelectionDAG, so
+ // this information gets lost and we can't select on it.
+ //
+ // TODO: div and rcp are lowered to a binary op, so these we could in
+ // theory lower them to "fast fdiv".
+
+ default:
+ return {};
+ }
+ }();
+
+ // If Action.FtzRequirementTy is not satisfied by the module's ftz state, we
+ // can bail out now. (Notice that in the case that IID is not an NVVM
+ // intrinsic, we don't have to look up any module metadata, as
+ // FtzRequirementTy will be FTZ_Any.)
+ if (Action.FtzRequirement != FTZ_Any) {
+ StringRef Attr = II->getFunction()
+ ->getFnAttribute("denormal-fp-math-f32")
+ .getValueAsString();
+ DenormalMode Mode = parseDenormalFPAttribute(Attr);
+ bool FtzEnabled = Mode.Output != DenormalMode::IEEE;
+
+ if (FtzEnabled != (Action.FtzRequirement == FTZ_MustBeOn))
+ return nullptr;
+ }
+
+ // Simplify to target-generic intrinsic.
+ if (Action.IID) {
+ SmallVector<Value *, 4> Args(II->arg_operands());
+ // All the target-generic intrinsics currently of interest to us have one
+ // type argument, equal to that of the nvvm intrinsic's argument.
+ Type *Tys[] = {II->getArgOperand(0)->getType()};
+ return CallInst::Create(
+ Intrinsic::getDeclaration(II->getModule(), *Action.IID, Tys), Args);
+ }
+
+ // Simplify to target-generic binary op.
+ if (Action.BinaryOp)
+ return BinaryOperator::Create(*Action.BinaryOp, II->getArgOperand(0),
+ II->getArgOperand(1), II->getName());
+
+ // Simplify to target-generic cast op.
+ if (Action.CastOp)
+ return CastInst::Create(*Action.CastOp, II->getArgOperand(0), II->getType(),
+ II->getName());
+
+ // All that's left are the special cases.
+ if (!Action.Special)
+ return nullptr;
+
+ switch (*Action.Special) {
+ case SPC_Reciprocal:
+ // Simplify reciprocal.
+ return BinaryOperator::Create(
+ Instruction::FDiv, ConstantFP::get(II->getArgOperand(0)->getType(), 1),
+ II->getArgOperand(0), II->getName());
+ }
+ llvm_unreachable("All SpecialCase enumerators should be handled in switch.");
+}
+
+Optional<Instruction *>
+NVPTXTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
+ if (Instruction *I = simplifyNvvmIntrinsic(&II, IC)) {
+ return I;
+ }
+ return None;
+}
+
int NVPTXTTIImpl::getArithmeticInstrCost(
unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
TTI::OperandValueKind Opd1Info,
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetTransformInfo.h b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetTransformInfo.h
index 9176c5db7b..6f071040dd 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetTransformInfo.h
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVPTXTargetTransformInfo.h
@@ -48,9 +48,9 @@ public:
return AddressSpace::ADDRESS_SPACE_GENERIC;
}
- Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
- IntrinsicInst &II) const;
-
+ Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
+ IntrinsicInst &II) const;
+
// Loads and stores can be vectorized if the alignment is at least as big as
// the load/store we want to vectorize.
bool isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes, Align Alignment,
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVVMIntrRange.cpp b/contrib/libs/llvm12/lib/Target/NVPTX/NVVMIntrRange.cpp
index 7f5e3edb3b..5381646434 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVVMIntrRange.cpp
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVVMIntrRange.cpp
@@ -17,7 +17,7 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsNVPTX.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/Support/CommandLine.h"
using namespace llvm;
@@ -33,13 +33,13 @@ static cl::opt<unsigned> NVVMIntrRangeSM("nvvm-intr-range-sm", cl::init(20),
namespace {
class NVVMIntrRange : public FunctionPass {
private:
- unsigned SmVersion;
+ unsigned SmVersion;
public:
static char ID;
NVVMIntrRange() : NVVMIntrRange(NVVMIntrRangeSM) {}
- NVVMIntrRange(unsigned int SmVersion)
- : FunctionPass(ID), SmVersion(SmVersion) {
+ NVVMIntrRange(unsigned int SmVersion)
+ : FunctionPass(ID), SmVersion(SmVersion) {
initializeNVVMIntrRangePass(*PassRegistry::getPassRegistry());
}
@@ -72,18 +72,18 @@ static bool addRangeMetadata(uint64_t Low, uint64_t High, CallInst *C) {
return true;
}
-static bool runNVVMIntrRange(Function &F, unsigned SmVersion) {
- struct {
- unsigned x, y, z;
- } MaxBlockSize, MaxGridSize;
- MaxBlockSize.x = 1024;
- MaxBlockSize.y = 1024;
- MaxBlockSize.z = 64;
-
- MaxGridSize.x = SmVersion >= 30 ? 0x7fffffff : 0xffff;
- MaxGridSize.y = 0xffff;
- MaxGridSize.z = 0xffff;
-
+static bool runNVVMIntrRange(Function &F, unsigned SmVersion) {
+ struct {
+ unsigned x, y, z;
+ } MaxBlockSize, MaxGridSize;
+ MaxBlockSize.x = 1024;
+ MaxBlockSize.y = 1024;
+ MaxBlockSize.z = 64;
+
+ MaxGridSize.x = SmVersion >= 30 ? 0x7fffffff : 0xffff;
+ MaxGridSize.y = 0xffff;
+ MaxGridSize.z = 0xffff;
+
// Go through the calls in this function.
bool Changed = false;
for (Instruction &I : instructions(F)) {
@@ -155,15 +155,15 @@ static bool runNVVMIntrRange(Function &F, unsigned SmVersion) {
return Changed;
}
-
-bool NVVMIntrRange::runOnFunction(Function &F) {
- return runNVVMIntrRange(F, SmVersion);
-}
-
-NVVMIntrRangePass::NVVMIntrRangePass() : NVVMIntrRangePass(NVVMIntrRangeSM) {}
-
-PreservedAnalyses NVVMIntrRangePass::run(Function &F,
- FunctionAnalysisManager &AM) {
- return runNVVMIntrRange(F, SmVersion) ? PreservedAnalyses::none()
- : PreservedAnalyses::all();
-}
+
+bool NVVMIntrRange::runOnFunction(Function &F) {
+ return runNVVMIntrRange(F, SmVersion);
+}
+
+NVVMIntrRangePass::NVVMIntrRangePass() : NVVMIntrRangePass(NVVMIntrRangeSM) {}
+
+PreservedAnalyses NVVMIntrRangePass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ return runNVVMIntrRange(F, SmVersion) ? PreservedAnalyses::none()
+ : PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/NVVMReflect.cpp b/contrib/libs/llvm12/lib/Target/NVPTX/NVVMReflect.cpp
index c740ded1fd..339f51d210 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/NVVMReflect.cpp
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/NVVMReflect.cpp
@@ -29,7 +29,7 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsNVPTX.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/Type.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
@@ -74,7 +74,7 @@ INITIALIZE_PASS(NVVMReflect, "nvvm-reflect",
"Replace occurrences of __nvvm_reflect() calls with 0/1", false,
false)
-static bool runNVVMReflect(Function &F, unsigned SmVersion) {
+static bool runNVVMReflect(Function &F, unsigned SmVersion) {
if (!NVVMReflectEnabled)
return false;
@@ -180,15 +180,15 @@ static bool runNVVMReflect(Function &F, unsigned SmVersion) {
return ToRemove.size() > 0;
}
-
-bool NVVMReflect::runOnFunction(Function &F) {
- return runNVVMReflect(F, SmVersion);
-}
-
-NVVMReflectPass::NVVMReflectPass() : NVVMReflectPass(0) {}
-
-PreservedAnalyses NVVMReflectPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- return runNVVMReflect(F, SmVersion) ? PreservedAnalyses::none()
- : PreservedAnalyses::all();
-}
+
+bool NVVMReflect::runOnFunction(Function &F) {
+ return runNVVMReflect(F, SmVersion);
+}
+
+NVVMReflectPass::NVVMReflectPass() : NVVMReflectPass(0) {}
+
+PreservedAnalyses NVVMReflectPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ return runNVVMReflect(F, SmVersion) ? PreservedAnalyses::none()
+ : PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo/ya.make b/contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo/ya.make
index 8e9644a1eb..52ef1e5f5b 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo/ya.make
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo/ya.make
@@ -12,13 +12,13 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
- contrib/libs/llvm12/lib/Target/NVPTX
- contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo
+ contrib/libs/llvm12/lib/Target/NVPTX
+ contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/NVPTX/ya.make b/contrib/libs/llvm12/lib/Target/NVPTX/ya.make
index b6325732ad..4f7542eb65 100644
--- a/contrib/libs/llvm12/lib/Target/NVPTX/ya.make
+++ b/contrib/libs/llvm12/lib/Target/NVPTX/ya.make
@@ -12,27 +12,27 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/CodeGen
- contrib/libs/llvm12/lib/CodeGen/AsmPrinter
- contrib/libs/llvm12/lib/CodeGen/SelectionDAG
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target
- contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc
- contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo
- contrib/libs/llvm12/lib/Transforms/IPO
- contrib/libs/llvm12/lib/Transforms/Scalar
- contrib/libs/llvm12/lib/Transforms/Utils
- contrib/libs/llvm12/lib/Transforms/Vectorize
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/CodeGen
+ contrib/libs/llvm12/lib/CodeGen/AsmPrinter
+ contrib/libs/llvm12/lib/CodeGen/SelectionDAG
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target
+ contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo
+ contrib/libs/llvm12/lib/Transforms/IPO
+ contrib/libs/llvm12/lib/Transforms/Scalar
+ contrib/libs/llvm12/lib/Transforms/Utils
+ contrib/libs/llvm12/lib/Transforms/Vectorize
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/NVPTX
- contrib/libs/llvm12/lib/Target/NVPTX
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/NVPTX
+ contrib/libs/llvm12/lib/Target/NVPTX
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
index 2bcbb4f781..197fd3c7aa 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
@@ -284,16 +284,16 @@ public:
return (unsigned) Imm.Val;
}
- unsigned getACCReg() const {
- assert(isACCRegNumber() && "Invalid access!");
- return (unsigned) Imm.Val;
- }
-
- unsigned getVSRpEvenReg() const {
- assert(isVSRpEvenRegNumber() && "Invalid access!");
- return (unsigned) Imm.Val >> 1;
- }
-
+ unsigned getACCReg() const {
+ assert(isACCRegNumber() && "Invalid access!");
+ return (unsigned) Imm.Val;
+ }
+
+ unsigned getVSRpEvenReg() const {
+ assert(isVSRpEvenRegNumber() && "Invalid access!");
+ return (unsigned) Imm.Val >> 1;
+ }
+
unsigned getCCReg() const {
assert(isCCRegNumber() && "Invalid access!");
return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);
@@ -406,12 +406,12 @@ public:
(getImm() & 3) == 0); }
bool isImmZero() const { return Kind == Immediate && getImm() == 0; }
bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); }
- bool isACCRegNumber() const {
- return Kind == Immediate && isUInt<3>(getImm());
- }
- bool isVSRpEvenRegNumber() const {
- return Kind == Immediate && isUInt<6>(getImm()) && ((getImm() & 1) == 0);
- }
+ bool isACCRegNumber() const {
+ return Kind == Immediate && isUInt<3>(getImm());
+ }
+ bool isVSRpEvenRegNumber() const {
+ return Kind == Immediate && isUInt<6>(getImm()) && ((getImm() & 1) == 0);
+ }
bool isVSRegNumber() const {
return Kind == Immediate && isUInt<6>(getImm());
}
@@ -502,29 +502,29 @@ public:
Inst.addOperand(MCOperand::createReg(VSSRegs[getVSReg()]));
}
- void addRegSPE4RCOperands(MCInst &Inst, unsigned N) const {
+ void addRegSPE4RCOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(RRegs[getReg()]));
+ Inst.addOperand(MCOperand::createReg(RRegs[getReg()]));
}
- void addRegSPERCOperands(MCInst &Inst, unsigned N) const {
+ void addRegSPERCOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(SPERegs[getReg()]));
+ Inst.addOperand(MCOperand::createReg(SPERegs[getReg()]));
}
- void addRegACCRCOperands(MCInst &Inst, unsigned N) const {
+ void addRegACCRCOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(ACCRegs[getACCReg()]));
+ Inst.addOperand(MCOperand::createReg(ACCRegs[getACCReg()]));
}
- void addRegVSRpRCOperands(MCInst &Inst, unsigned N) const {
+ void addRegVSRpRCOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));
+ Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));
}
- void addRegVSRpEvenRCOperands(MCInst &Inst, unsigned N) const {
+ void addRegVSRpEvenRCOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));
+ Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));
}
void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const {
@@ -676,8 +676,8 @@ public:
return CreateImm(CE->getValue(), S, E, IsPPC64);
if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Val))
- if (SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS ||
- SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS_PCREL)
+ if (SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS ||
+ SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS_PCREL)
return CreateTLSReg(SRE, S, E, IsPPC64);
if (const PPCMCExpr *TE = dyn_cast<PPCMCExpr>(Val)) {
@@ -773,18 +773,18 @@ void PPCAsmParser::ProcessInstruction(MCInst &Inst,
}
case PPC::DCBFx:
case PPC::DCBFL:
- case PPC::DCBFLP:
- case PPC::DCBFPS:
- case PPC::DCBSTPS: {
+ case PPC::DCBFLP:
+ case PPC::DCBFPS:
+ case PPC::DCBSTPS: {
int L = 0;
if (Opcode == PPC::DCBFL)
L = 1;
else if (Opcode == PPC::DCBFLP)
L = 3;
- else if (Opcode == PPC::DCBFPS)
- L = 4;
- else if (Opcode == PPC::DCBSTPS)
- L = 6;
+ else if (Opcode == PPC::DCBFPS)
+ L = 4;
+ else if (Opcode == PPC::DCBSTPS)
+ L = 6;
MCInst TmpInst;
TmpInst.setOpcode(PPC::DCBF);
@@ -1201,41 +1201,41 @@ bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
}
bool PPCAsmParser::MatchRegisterName(unsigned &RegNo, int64_t &IntVal) {
- if (getParser().getTok().is(AsmToken::Percent))
- getParser().Lex(); // Eat the '%'.
-
- if (!getParser().getTok().is(AsmToken::Identifier))
- return true;
-
- StringRef Name = getParser().getTok().getString();
- if (Name.equals_lower("lr")) {
- RegNo = isPPC64() ? PPC::LR8 : PPC::LR;
- IntVal = 8;
- } else if (Name.equals_lower("ctr")) {
- RegNo = isPPC64() ? PPC::CTR8 : PPC::CTR;
- IntVal = 9;
- } else if (Name.equals_lower("vrsave")) {
- RegNo = PPC::VRSAVE;
- IntVal = 256;
- } else if (Name.startswith_lower("r") &&
- !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
- RegNo = isPPC64() ? XRegs[IntVal] : RRegs[IntVal];
- } else if (Name.startswith_lower("f") &&
- !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
- RegNo = FRegs[IntVal];
- } else if (Name.startswith_lower("vs") &&
- !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 64) {
- RegNo = VSRegs[IntVal];
- } else if (Name.startswith_lower("v") &&
- !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
- RegNo = VRegs[IntVal];
- } else if (Name.startswith_lower("cr") &&
- !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 8) {
- RegNo = CRRegs[IntVal];
- } else
- return true;
- getParser().Lex();
- return false;
+ if (getParser().getTok().is(AsmToken::Percent))
+ getParser().Lex(); // Eat the '%'.
+
+ if (!getParser().getTok().is(AsmToken::Identifier))
+ return true;
+
+ StringRef Name = getParser().getTok().getString();
+ if (Name.equals_lower("lr")) {
+ RegNo = isPPC64() ? PPC::LR8 : PPC::LR;
+ IntVal = 8;
+ } else if (Name.equals_lower("ctr")) {
+ RegNo = isPPC64() ? PPC::CTR8 : PPC::CTR;
+ IntVal = 9;
+ } else if (Name.equals_lower("vrsave")) {
+ RegNo = PPC::VRSAVE;
+ IntVal = 256;
+ } else if (Name.startswith_lower("r") &&
+ !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
+ RegNo = isPPC64() ? XRegs[IntVal] : RRegs[IntVal];
+ } else if (Name.startswith_lower("f") &&
+ !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
+ RegNo = FRegs[IntVal];
+ } else if (Name.startswith_lower("vs") &&
+ !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 64) {
+ RegNo = VSRegs[IntVal];
+ } else if (Name.startswith_lower("v") &&
+ !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
+ RegNo = VRegs[IntVal];
+ } else if (Name.startswith_lower("cr") &&
+ !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 8) {
+ RegNo = CRRegs[IntVal];
+ } else
+ return true;
+ getParser().Lex();
+ return false;
}
bool PPCAsmParser::
@@ -1432,7 +1432,7 @@ bool PPCAsmParser::ParseOperand(OperandVector &Operands) {
switch (getLexer().getKind()) {
// Special handling for register names. These are interpreted
// as immediates corresponding to the register number.
- case AsmToken::Percent: {
+ case AsmToken::Percent: {
unsigned RegNo;
int64_t IntVal;
if (MatchRegisterName(RegNo, IntVal))
@@ -1440,7 +1440,7 @@ bool PPCAsmParser::ParseOperand(OperandVector &Operands) {
Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
return false;
- }
+ }
case AsmToken::Identifier:
case AsmToken::LParen:
case AsmToken::Plus:
@@ -1488,18 +1488,18 @@ bool PPCAsmParser::ParseOperand(OperandVector &Operands) {
int64_t IntVal;
switch (getLexer().getKind()) {
- case AsmToken::Percent: {
+ case AsmToken::Percent: {
unsigned RegNo;
if (MatchRegisterName(RegNo, IntVal))
return Error(S, "invalid register name");
break;
- }
+ }
case AsmToken::Integer:
- if (getParser().parseAbsoluteExpression(IntVal) || IntVal < 0 ||
- IntVal > 31)
+ if (getParser().parseAbsoluteExpression(IntVal) || IntVal < 0 ||
+ IntVal > 31)
return Error(S, "invalid register number");
break;
- case AsmToken::Identifier:
+ case AsmToken::Identifier:
default:
return Error(S, "invalid memory operand");
}
@@ -1583,7 +1583,7 @@ bool PPCAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
/// ParseDirective parses the PPC specific directives
bool PPCAsmParser::ParseDirective(AsmToken DirectiveID) {
StringRef IDVal = DirectiveID.getIdentifier();
- if (IDVal == ".word")
+ if (IDVal == ".word")
ParseDirectiveWord(2, DirectiveID);
else if (IDVal == ".llong")
ParseDirectiveWord(8, DirectiveID);
@@ -1655,7 +1655,7 @@ bool PPCAsmParser::ParseDirectiveMachine(SMLoc L) {
// FIXME: Right now, the parser always allows any available
// instruction, so the .machine directive is not useful.
- // In the wild, any/push/pop/ppc64/altivec/power[4-9] are seen.
+ // In the wild, any/push/pop/ppc64/altivec/power[4-9] are seen.
Parser.Lex();
@@ -1715,9 +1715,9 @@ bool PPCAsmParser::ParseDirectiveLocalEntry(SMLoc L) {
/// Force static initialization.
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmParser() {
RegisterMCAsmParser<PPCAsmParser> A(getThePPC32Target());
- RegisterMCAsmParser<PPCAsmParser> B(getThePPC32LETarget());
- RegisterMCAsmParser<PPCAsmParser> C(getThePPC64Target());
- RegisterMCAsmParser<PPCAsmParser> D(getThePPC64LETarget());
+ RegisterMCAsmParser<PPCAsmParser> B(getThePPC32LETarget());
+ RegisterMCAsmParser<PPCAsmParser> C(getThePPC64Target());
+ RegisterMCAsmParser<PPCAsmParser> D(getThePPC64LETarget());
}
#define GET_REGISTER_MATCHER
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/AsmParser/ya.make b/contrib/libs/llvm12/lib/Target/PowerPC/AsmParser/ya.make
index e8ca90aaed..24183440dc 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/AsmParser/ya.make
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/AsmParser/ya.make
@@ -12,19 +12,19 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/MC/MCParser
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc
- contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/MC/MCParser
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC
- contrib/libs/llvm12/lib/Target/PowerPC
- contrib/libs/llvm12/lib/Target/PowerPC/AsmParser
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC
+ contrib/libs/llvm12/lib/Target/PowerPC
+ contrib/libs/llvm12/lib/Target/PowerPC/AsmParser
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
index 2441b6d91b..3e9286fb0b 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
@@ -54,8 +54,8 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCDisassembler() {
// Register the disassembler for each target.
TargetRegistry::RegisterMCDisassembler(getThePPC32Target(),
createPPCDisassembler);
- TargetRegistry::RegisterMCDisassembler(getThePPC32LETarget(),
- createPPCLEDisassembler);
+ TargetRegistry::RegisterMCDisassembler(getThePPC32LETarget(),
+ createPPCLEDisassembler);
TargetRegistry::RegisterMCDisassembler(getThePPC64Target(),
createPPCDisassembler);
TargetRegistry::RegisterMCDisassembler(getThePPC64LETarget(),
@@ -175,18 +175,18 @@ static DecodeStatus DecodeSPERCRegisterClass(MCInst &Inst, uint64_t RegNo,
return decodeRegisterClass(Inst, RegNo, SPERegs);
}
-static DecodeStatus DecodeACCRCRegisterClass(MCInst &Inst, uint64_t RegNo,
- uint64_t Address,
- const void *Decoder) {
- return decodeRegisterClass(Inst, RegNo, ACCRegs);
-}
-
-static DecodeStatus DecodeVSRpRCRegisterClass(MCInst &Inst, uint64_t RegNo,
- uint64_t Address,
- const void *Decoder) {
- return decodeRegisterClass(Inst, RegNo, VSRpRegs);
-}
-
+static DecodeStatus DecodeACCRCRegisterClass(MCInst &Inst, uint64_t RegNo,
+ uint64_t Address,
+ const void *Decoder) {
+ return decodeRegisterClass(Inst, RegNo, ACCRegs);
+}
+
+static DecodeStatus DecodeVSRpRCRegisterClass(MCInst &Inst, uint64_t RegNo,
+ uint64_t Address,
+ const void *Decoder) {
+ return decodeRegisterClass(Inst, RegNo, VSRpRegs);
+}
+
#define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
#define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
@@ -214,15 +214,15 @@ static DecodeStatus decodeImmZeroOperand(MCInst &Inst, uint64_t Imm,
return MCDisassembler::Success;
}
-static DecodeStatus decodeVSRpEvenOperands(MCInst &Inst, uint64_t RegNo,
- uint64_t Address,
- const void *Decoder) {
- if (RegNo & 1)
- return MCDisassembler::Fail;
- Inst.addOperand(MCOperand::createReg(VSRpRegs[RegNo >> 1]));
- return MCDisassembler::Success;
-}
-
+static DecodeStatus decodeVSRpEvenOperands(MCInst &Inst, uint64_t RegNo,
+ uint64_t Address,
+ const void *Decoder) {
+ if (RegNo & 1)
+ return MCDisassembler::Fail;
+ Inst.addOperand(MCOperand::createReg(VSRpRegs[RegNo >> 1]));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus decodeMemRIOperands(MCInst &Inst, uint64_t Imm,
int64_t Address, const void *Decoder) {
// Decode the memri field (imm, reg), which has the low 16-bits as the
@@ -418,9 +418,9 @@ DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
// Read the instruction in the proper endianness.
uint64_t Inst = ReadFunc(Bytes.data());
- if (STI.getFeatureBits()[PPC::FeatureSPE]) {
+ if (STI.getFeatureBits()[PPC::FeatureSPE]) {
DecodeStatus result =
- decodeInstruction(DecoderTableSPE32, MI, Inst, Address, this, STI);
+ decodeInstruction(DecoderTableSPE32, MI, Inst, Address, this, STI);
if (result != MCDisassembler::Fail)
return result;
}
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/Disassembler/ya.make b/contrib/libs/llvm12/lib/Target/PowerPC/Disassembler/ya.make
index 30a45916df..a412740df2 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/Disassembler/ya.make
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/Disassembler/ya.make
@@ -12,17 +12,17 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/MC/MCDisassembler
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/MC/MCDisassembler
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC
- contrib/libs/llvm12/lib/Target/PowerPC
- contrib/libs/llvm12/lib/Target/PowerPC/Disassembler
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC
+ contrib/libs/llvm12/lib/Target/PowerPC
+ contrib/libs/llvm12/lib/Target/PowerPC/Disassembler
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCCallLowering.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCCallLowering.cpp
index 24cca73180..e8f8cbfee6 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCCallLowering.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCCallLowering.cpp
@@ -1,53 +1,53 @@
-//===-- PPCCallLowering.h - Call lowering for GlobalISel -------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This file implements the lowering of LLVM calls to machine code calls for
-/// GlobalISel.
-///
-//===----------------------------------------------------------------------===//
-
-#include "PPCCallLowering.h"
-#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
-#include "llvm/Support/Debug.h"
-
-#define DEBUG_TYPE "ppc-call-lowering"
-
-using namespace llvm;
-
-PPCCallLowering::PPCCallLowering(const PPCTargetLowering &TLI)
- : CallLowering(&TLI) {}
-
-bool PPCCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
- const Value *Val, ArrayRef<Register> VRegs,
- FunctionLoweringInfo &FLI,
- Register SwiftErrorVReg) const {
- assert(((Val && !VRegs.empty()) || (!Val && VRegs.empty())) &&
- "Return value without a vreg");
- if (VRegs.size() > 0)
- return false;
-
- MIRBuilder.buildInstr(PPC::BLR8);
- return true;
-}
-
-bool PPCCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
- const Function &F,
- ArrayRef<ArrayRef<Register>> VRegs,
- FunctionLoweringInfo &FLI) const {
-
- // If VRegs is empty, then there are no formal arguments to lower and thus can
- // always return true. If there are formal arguments, we currently do not
- // handle them and thus return false.
- return VRegs.empty();
-}
-
-bool PPCCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
- CallLoweringInfo &Info) const {
- return false;
-}
+//===-- PPCCallLowering.h - Call lowering for GlobalISel -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements the lowering of LLVM calls to machine code calls for
+/// GlobalISel.
+///
+//===----------------------------------------------------------------------===//
+
+#include "PPCCallLowering.h"
+#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "ppc-call-lowering"
+
+using namespace llvm;
+
+PPCCallLowering::PPCCallLowering(const PPCTargetLowering &TLI)
+ : CallLowering(&TLI) {}
+
+bool PPCCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
+ const Value *Val, ArrayRef<Register> VRegs,
+ FunctionLoweringInfo &FLI,
+ Register SwiftErrorVReg) const {
+ assert(((Val && !VRegs.empty()) || (!Val && VRegs.empty())) &&
+ "Return value without a vreg");
+ if (VRegs.size() > 0)
+ return false;
+
+ MIRBuilder.buildInstr(PPC::BLR8);
+ return true;
+}
+
+bool PPCCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
+ const Function &F,
+ ArrayRef<ArrayRef<Register>> VRegs,
+ FunctionLoweringInfo &FLI) const {
+
+ // If VRegs is empty, then there are no formal arguments to lower and thus can
+ // always return true. If there are formal arguments, we currently do not
+ // handle them and thus return false.
+ return VRegs.empty();
+}
+
+bool PPCCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
+ CallLoweringInfo &Info) const {
+ return false;
+}
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCCallLowering.h b/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCCallLowering.h
index d503f5df9c..5a449f4cab 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCCallLowering.h
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCCallLowering.h
@@ -1,40 +1,40 @@
-//===-- PPCCallLowering.h - Call lowering for GlobalISel -------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This file describes how to lower LLVM calls to machine code calls.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_TARGET_POWERPC_GISEL_PPCCALLLOWERING_H
-#define LLVM_LIB_TARGET_POWERPC_GISEL_PPCCALLLOWERING_H
-
-#include "PPCISelLowering.h"
-#include "llvm/CodeGen/GlobalISel/CallLowering.h"
-#include "llvm/IR/CallingConv.h"
-
-namespace llvm {
-
-class PPCTargetLowering;
-
-class PPCCallLowering : public CallLowering {
-public:
- PPCCallLowering(const PPCTargetLowering &TLI);
-
- bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
- ArrayRef<Register> VRegs, FunctionLoweringInfo &FLI,
- Register SwiftErrorVReg) const override;
- bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F,
- ArrayRef<ArrayRef<Register>> VRegs,
- FunctionLoweringInfo &FLI) const override;
- bool lowerCall(MachineIRBuilder &MIRBuilder,
- CallLoweringInfo &Info) const override;
-};
-} // end namespace llvm
-
-#endif
+//===-- PPCCallLowering.h - Call lowering for GlobalISel -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file describes how to lower LLVM calls to machine code calls.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_POWERPC_GISEL_PPCCALLLOWERING_H
+#define LLVM_LIB_TARGET_POWERPC_GISEL_PPCCALLLOWERING_H
+
+#include "PPCISelLowering.h"
+#include "llvm/CodeGen/GlobalISel/CallLowering.h"
+#include "llvm/IR/CallingConv.h"
+
+namespace llvm {
+
+class PPCTargetLowering;
+
+class PPCCallLowering : public CallLowering {
+public:
+ PPCCallLowering(const PPCTargetLowering &TLI);
+
+ bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
+ ArrayRef<Register> VRegs, FunctionLoweringInfo &FLI,
+ Register SwiftErrorVReg) const override;
+ bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F,
+ ArrayRef<ArrayRef<Register>> VRegs,
+ FunctionLoweringInfo &FLI) const override;
+ bool lowerCall(MachineIRBuilder &MIRBuilder,
+ CallLoweringInfo &Info) const override;
+};
+} // end namespace llvm
+
+#endif
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
index f7f43c8bfe..7d64816ed6 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
@@ -1,92 +1,92 @@
-//===- PPCInstructionSelector.cpp --------------------------------*- C++ -*-==//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// This file implements the targeting of the InstructionSelector class for
-/// PowerPC.
-//===----------------------------------------------------------------------===//
-
-#include "PPCInstrInfo.h"
-#include "PPCRegisterBankInfo.h"
-#include "PPCSubtarget.h"
-#include "PPCTargetMachine.h"
-#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
-#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/IR/IntrinsicsPowerPC.h"
-#include "llvm/Support/Debug.h"
-
-#define DEBUG_TYPE "ppc-gisel"
-
-using namespace llvm;
-
-namespace {
-
-#define GET_GLOBALISEL_PREDICATE_BITSET
-#include "PPCGenGlobalISel.inc"
-#undef GET_GLOBALISEL_PREDICATE_BITSET
-
-class PPCInstructionSelector : public InstructionSelector {
-public:
- PPCInstructionSelector(const PPCTargetMachine &TM, const PPCSubtarget &STI,
- const PPCRegisterBankInfo &RBI);
-
- bool select(MachineInstr &I) override;
- static const char *getName() { return DEBUG_TYPE; }
-
-private:
- /// tblgen generated 'select' implementation that is used as the initial
- /// selector for the patterns that do not require complex C++.
- bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
-
- const PPCInstrInfo &TII;
- const PPCRegisterInfo &TRI;
- const PPCRegisterBankInfo &RBI;
-
-#define GET_GLOBALISEL_PREDICATES_DECL
-#include "PPCGenGlobalISel.inc"
-#undef GET_GLOBALISEL_PREDICATES_DECL
-
-#define GET_GLOBALISEL_TEMPORARIES_DECL
-#include "PPCGenGlobalISel.inc"
-#undef GET_GLOBALISEL_TEMPORARIES_DECL
-};
-
-} // end anonymous namespace
-
-#define GET_GLOBALISEL_IMPL
-#include "PPCGenGlobalISel.inc"
-#undef GET_GLOBALISEL_IMPL
-
-PPCInstructionSelector::PPCInstructionSelector(const PPCTargetMachine &TM,
- const PPCSubtarget &STI,
- const PPCRegisterBankInfo &RBI)
- : InstructionSelector(), TII(*STI.getInstrInfo()),
- TRI(*STI.getRegisterInfo()), RBI(RBI),
-#define GET_GLOBALISEL_PREDICATES_INIT
-#include "PPCGenGlobalISel.inc"
-#undef GET_GLOBALISEL_PREDICATES_INIT
-#define GET_GLOBALISEL_TEMPORARIES_INIT
-#include "PPCGenGlobalISel.inc"
-#undef GET_GLOBALISEL_TEMPORARIES_INIT
-{
-}
-
-bool PPCInstructionSelector::select(MachineInstr &I) {
- if (selectImpl(I, *CoverageInfo))
- return true;
- return false;
-}
-
-namespace llvm {
-InstructionSelector *
-createPPCInstructionSelector(const PPCTargetMachine &TM,
- const PPCSubtarget &Subtarget,
- const PPCRegisterBankInfo &RBI) {
- return new PPCInstructionSelector(TM, Subtarget, RBI);
-}
-} // end namespace llvm
+//===- PPCInstructionSelector.cpp --------------------------------*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file implements the targeting of the InstructionSelector class for
+/// PowerPC.
+//===----------------------------------------------------------------------===//
+
+#include "PPCInstrInfo.h"
+#include "PPCRegisterBankInfo.h"
+#include "PPCSubtarget.h"
+#include "PPCTargetMachine.h"
+#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
+#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/IR/IntrinsicsPowerPC.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "ppc-gisel"
+
+using namespace llvm;
+
+namespace {
+
+#define GET_GLOBALISEL_PREDICATE_BITSET
+#include "PPCGenGlobalISel.inc"
+#undef GET_GLOBALISEL_PREDICATE_BITSET
+
+class PPCInstructionSelector : public InstructionSelector {
+public:
+ PPCInstructionSelector(const PPCTargetMachine &TM, const PPCSubtarget &STI,
+ const PPCRegisterBankInfo &RBI);
+
+ bool select(MachineInstr &I) override;
+ static const char *getName() { return DEBUG_TYPE; }
+
+private:
+ /// tblgen generated 'select' implementation that is used as the initial
+ /// selector for the patterns that do not require complex C++.
+ bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
+
+ const PPCInstrInfo &TII;
+ const PPCRegisterInfo &TRI;
+ const PPCRegisterBankInfo &RBI;
+
+#define GET_GLOBALISEL_PREDICATES_DECL
+#include "PPCGenGlobalISel.inc"
+#undef GET_GLOBALISEL_PREDICATES_DECL
+
+#define GET_GLOBALISEL_TEMPORARIES_DECL
+#include "PPCGenGlobalISel.inc"
+#undef GET_GLOBALISEL_TEMPORARIES_DECL
+};
+
+} // end anonymous namespace
+
+#define GET_GLOBALISEL_IMPL
+#include "PPCGenGlobalISel.inc"
+#undef GET_GLOBALISEL_IMPL
+
+PPCInstructionSelector::PPCInstructionSelector(const PPCTargetMachine &TM,
+ const PPCSubtarget &STI,
+ const PPCRegisterBankInfo &RBI)
+ : InstructionSelector(), TII(*STI.getInstrInfo()),
+ TRI(*STI.getRegisterInfo()), RBI(RBI),
+#define GET_GLOBALISEL_PREDICATES_INIT
+#include "PPCGenGlobalISel.inc"
+#undef GET_GLOBALISEL_PREDICATES_INIT
+#define GET_GLOBALISEL_TEMPORARIES_INIT
+#include "PPCGenGlobalISel.inc"
+#undef GET_GLOBALISEL_TEMPORARIES_INIT
+{
+}
+
+bool PPCInstructionSelector::select(MachineInstr &I) {
+ if (selectImpl(I, *CoverageInfo))
+ return true;
+ return false;
+}
+
+namespace llvm {
+InstructionSelector *
+createPPCInstructionSelector(const PPCTargetMachine &TM,
+ const PPCSubtarget &Subtarget,
+ const PPCRegisterBankInfo &RBI) {
+ return new PPCInstructionSelector(TM, Subtarget, RBI);
+}
+} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
index 61ea84b9bd..c16bcaea59 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
@@ -1,20 +1,20 @@
-//===- PPCLegalizerInfo.h ----------------------------------------*- C++ -*-==//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// This file implements the targeting of the Machinelegalizer class for PowerPC
-//===----------------------------------------------------------------------===//
-
-#include "PPCLegalizerInfo.h"
-#include "llvm/Support/Debug.h"
-
-#define DEBUG_TYPE "ppc-legalinfo"
-
-using namespace llvm;
-using namespace LegalizeActions;
-
-PPCLegalizerInfo::PPCLegalizerInfo(const PPCSubtarget &ST) { computeTables(); }
+//===- PPCLegalizerInfo.h ----------------------------------------*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file implements the targeting of the Machinelegalizer class for PowerPC
+//===----------------------------------------------------------------------===//
+
+#include "PPCLegalizerInfo.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "ppc-legalinfo"
+
+using namespace llvm;
+using namespace LegalizeActions;
+
+PPCLegalizerInfo::PPCLegalizerInfo(const PPCSubtarget &ST) { computeTables(); }
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCLegalizerInfo.h b/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCLegalizerInfo.h
index d0e513c1b9..c73186d3d0 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCLegalizerInfo.h
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCLegalizerInfo.h
@@ -1,28 +1,28 @@
-//===- PPCLegalizerInfo.h ----------------------------------------*- C++ -*-==//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// This file declares the targeting of the Machinelegalizer class for PowerPC
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_TARGET_POWERPC_GISEL_PPCMACHINELEGALIZER_H
-#define LLVM_LIB_TARGET_POWERPC_GISEL_PPCMACHINELEGALIZER_H
-
-#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
-
-namespace llvm {
-
-class PPCSubtarget;
-
-/// This class provides the information for the PowerPC target legalizer for
-/// GlobalISel.
-class PPCLegalizerInfo : public LegalizerInfo {
-public:
- PPCLegalizerInfo(const PPCSubtarget &ST);
-};
-} // namespace llvm
-#endif
+//===- PPCLegalizerInfo.h ----------------------------------------*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file declares the targeting of the Machinelegalizer class for PowerPC
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_POWERPC_GISEL_PPCMACHINELEGALIZER_H
+#define LLVM_LIB_TARGET_POWERPC_GISEL_PPCMACHINELEGALIZER_H
+
+#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
+
+namespace llvm {
+
+class PPCSubtarget;
+
+/// This class provides the information for the PowerPC target legalizer for
+/// GlobalISel.
+class PPCLegalizerInfo : public LegalizerInfo {
+public:
+ PPCLegalizerInfo(const PPCSubtarget &ST);
+};
+} // namespace llvm
+#endif
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
index 4c4c12da51..6af7932491 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
@@ -1,27 +1,27 @@
-//===- PPCRegisterBankInfo.cpp --------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// This file implements the targeting of the RegisterBankInfo class for
-/// PowerPC.
-//===----------------------------------------------------------------------===//
-
-#include "PPCRegisterBankInfo.h"
-#include "PPCRegisterInfo.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/Support/Debug.h"
-
-#define DEBUG_TYPE "ppc-reg-bank-info"
-
-#define GET_TARGET_REGBANK_IMPL
-#include "PPCGenRegisterBank.inc"
-
-using namespace llvm;
-
-PPCRegisterBankInfo::PPCRegisterBankInfo(const TargetRegisterInfo &TRI)
- : PPCGenRegisterBankInfo() {}
+//===- PPCRegisterBankInfo.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file implements the targeting of the RegisterBankInfo class for
+/// PowerPC.
+//===----------------------------------------------------------------------===//
+
+#include "PPCRegisterBankInfo.h"
+#include "PPCRegisterInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "ppc-reg-bank-info"
+
+#define GET_TARGET_REGBANK_IMPL
+#include "PPCGenRegisterBank.inc"
+
+using namespace llvm;
+
+PPCRegisterBankInfo::PPCRegisterBankInfo(const TargetRegisterInfo &TRI)
+ : PPCGenRegisterBankInfo() {}
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h b/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
index cdaba6ff01..358d5ed3cf 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
@@ -1,39 +1,39 @@
-//===-- PPCRegisterBankInfo.h -----------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This file declares the targeting of the RegisterBankInfo class for PowerPC.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_TARGET_PPC_GISEL_PPCREGISTERBANKINFO_H
-#define LLVM_LIB_TARGET_PPC_GISEL_PPCREGISTERBANKINFO_H
-
-#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
-#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
-#include "llvm/CodeGen/TargetRegisterInfo.h"
-
-#define GET_REGBANK_DECLARATIONS
-#include "PPCGenRegisterBank.inc"
-
-namespace llvm {
-class TargetRegisterInfo;
-
-class PPCGenRegisterBankInfo : public RegisterBankInfo {
-protected:
-#define GET_TARGET_REGBANK_CLASS
-#include "PPCGenRegisterBank.inc"
-};
-
-class PPCRegisterBankInfo final : public PPCGenRegisterBankInfo {
-public:
- PPCRegisterBankInfo(const TargetRegisterInfo &TRI);
-};
-} // namespace llvm
-
-#endif
+//===-- PPCRegisterBankInfo.h -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file declares the targeting of the RegisterBankInfo class for PowerPC.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_PPC_GISEL_PPCREGISTERBANKINFO_H
+#define LLVM_LIB_TARGET_PPC_GISEL_PPCREGISTERBANKINFO_H
+
+#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
+#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+
+#define GET_REGBANK_DECLARATIONS
+#include "PPCGenRegisterBank.inc"
+
+namespace llvm {
+class TargetRegisterInfo;
+
+class PPCGenRegisterBankInfo : public RegisterBankInfo {
+protected:
+#define GET_TARGET_REGBANK_CLASS
+#include "PPCGenRegisterBank.inc"
+};
+
+class PPCRegisterBankInfo final : public PPCGenRegisterBankInfo {
+public:
+ PPCRegisterBankInfo(const TargetRegisterInfo &TRI);
+};
+} // namespace llvm
+
+#endif
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBanks.td b/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
index c07d1531a6..0e8a4b7061 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
@@ -1,15 +1,15 @@
-//===-- PPCRegisterBanks.td - Describe the PPC Banks -------*- tablegen -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// Define the PPC register banks used for GlobalISel.
-///
-//===----------------------------------------------------------------------===//
-
-/// General Purpose Registers
-def GPRRegBank : RegisterBank<"GPR", [G8RC]>;
+//===-- PPCRegisterBanks.td - Describe the PPC Banks -------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Define the PPC register banks used for GlobalISel.
+///
+//===----------------------------------------------------------------------===//
+
+/// General Purpose Registers
+def GPRRegBank : RegisterBank<"GPR", [G8RC]>;
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
index c8f12555e9..72401668c8 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
@@ -46,7 +46,7 @@ static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value) {
case PPC::fixup_ppc_half16ds:
return Value & 0xfffc;
case PPC::fixup_ppc_pcrel34:
- case PPC::fixup_ppc_imm34:
+ case PPC::fixup_ppc_imm34:
return Value & 0x3ffffffff;
}
}
@@ -69,7 +69,7 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
case PPC::fixup_ppc_br24_notoc:
return 4;
case PPC::fixup_ppc_pcrel34:
- case PPC::fixup_ppc_imm34:
+ case PPC::fixup_ppc_imm34:
case FK_Data_8:
return 8;
case PPC::fixup_ppc_nofixup:
@@ -102,7 +102,7 @@ public:
{ "fixup_ppc_half16", 0, 16, 0 },
{ "fixup_ppc_half16ds", 0, 14, 0 },
{ "fixup_ppc_pcrel34", 0, 34, MCFixupKindInfo::FKF_IsPCRel },
- { "fixup_ppc_imm34", 0, 34, 0 },
+ { "fixup_ppc_imm34", 0, 34, 0 },
{ "fixup_ppc_nofixup", 0, 0, 0 }
};
const static MCFixupKindInfo InfosLE[PPC::NumTargetFixupKinds] = {
@@ -115,7 +115,7 @@ public:
{ "fixup_ppc_half16", 0, 16, 0 },
{ "fixup_ppc_half16ds", 2, 14, 0 },
{ "fixup_ppc_pcrel34", 0, 34, MCFixupKindInfo::FKF_IsPCRel },
- { "fixup_ppc_imm34", 0, 34, 0 },
+ { "fixup_ppc_imm34", 0, 34, 0 },
{ "fixup_ppc_nofixup", 0, 0, 0 }
};
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
index 594b3b09fc..94ef7b4543 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
@@ -138,15 +138,15 @@ unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
case MCSymbolRefExpr::VK_PPC_GOT_PCREL:
Type = ELF::R_PPC64_GOT_PCREL34;
break;
- case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL:
- Type = ELF::R_PPC64_GOT_TLSGD_PCREL34;
- break;
- case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL:
- Type = ELF::R_PPC64_GOT_TLSLD_PCREL34;
- break;
- case MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL:
- Type = ELF::R_PPC64_GOT_TPREL_PCREL34;
- break;
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL:
+ Type = ELF::R_PPC64_GOT_TLSGD_PCREL34;
+ break;
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL:
+ Type = ELF::R_PPC64_GOT_TLSLD_PCREL34;
+ break;
+ case MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL:
+ Type = ELF::R_PPC64_GOT_TPREL_PCREL34;
+ break;
}
break;
case FK_Data_4:
@@ -416,23 +416,23 @@ unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
else
Type = ELF::R_PPC_TLS;
break;
- case MCSymbolRefExpr::VK_PPC_TLS_PCREL:
- Type = ELF::R_PPC64_TLS;
- break;
+ case MCSymbolRefExpr::VK_PPC_TLS_PCREL:
+ Type = ELF::R_PPC64_TLS;
+ break;
+ }
+ break;
+ case PPC::fixup_ppc_imm34:
+ switch (Modifier) {
+ default:
+ report_fatal_error("Unsupported Modifier for fixup_ppc_imm34.");
+ case MCSymbolRefExpr::VK_DTPREL:
+ Type = ELF::R_PPC64_DTPREL34;
+ break;
+ case MCSymbolRefExpr::VK_TPREL:
+ Type = ELF::R_PPC64_TPREL34;
+ break;
}
break;
- case PPC::fixup_ppc_imm34:
- switch (Modifier) {
- default:
- report_fatal_error("Unsupported Modifier for fixup_ppc_imm34.");
- case MCSymbolRefExpr::VK_DTPREL:
- Type = ELF::R_PPC64_DTPREL34;
- break;
- case MCSymbolRefExpr::VK_TPREL:
- Type = ELF::R_PPC64_TPREL34;
- break;
- }
- break;
case FK_Data_8:
switch (Modifier) {
default: llvm_unreachable("Unsupported Modifier");
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp
index 27784d7e58..386d592660 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp
@@ -20,7 +20,7 @@
#include "PPCELFStreamer.h"
-#include "PPCFixupKinds.h"
+#include "PPCFixupKinds.h"
#include "PPCInstrInfo.h"
#include "PPCMCCodeEmitter.h"
#include "llvm/BinaryFormat/ELF.h"
@@ -90,33 +90,33 @@ void PPCELFStreamer::emitInstruction(const MCInst &Inst,
PPCMCCodeEmitter *Emitter =
static_cast<PPCMCCodeEmitter*>(getAssembler().getEmitterPtr());
- // If the instruction is a part of the GOT to PC-Rel link time optimization
- // instruction pair, return a value, otherwise return None. A true returned
- // value means the instruction is the PLDpc and a false value means it is
- // the user instruction.
- Optional<bool> IsPartOfGOTToPCRelPair = isPartOfGOTToPCRelPair(Inst, STI);
-
- // User of the GOT-indirect address.
- // For example, the load that will get the relocation as follows:
- // .reloc .Lpcrel1-8,R_PPC64_PCREL_OPT,.-(.Lpcrel1-8)
- // lwa 3, 4(3)
- if (IsPartOfGOTToPCRelPair.hasValue() && !IsPartOfGOTToPCRelPair.getValue())
- emitGOTToPCRelReloc(Inst);
-
+ // If the instruction is a part of the GOT to PC-Rel link time optimization
+ // instruction pair, return a value, otherwise return None. A true returned
+ // value means the instruction is the PLDpc and a false value means it is
+ // the user instruction.
+ Optional<bool> IsPartOfGOTToPCRelPair = isPartOfGOTToPCRelPair(Inst, STI);
+
+ // User of the GOT-indirect address.
+ // For example, the load that will get the relocation as follows:
+ // .reloc .Lpcrel1-8,R_PPC64_PCREL_OPT,.-(.Lpcrel1-8)
+ // lwa 3, 4(3)
+ if (IsPartOfGOTToPCRelPair.hasValue() && !IsPartOfGOTToPCRelPair.getValue())
+ emitGOTToPCRelReloc(Inst);
+
// Special handling is only for prefixed instructions.
if (!Emitter->isPrefixedInstruction(Inst)) {
MCELFStreamer::emitInstruction(Inst, STI);
return;
}
emitPrefixedInstruction(Inst, STI);
-
- // Producer of the GOT-indirect address.
- // For example, the prefixed load from the got that will get the label as
- // follows:
- // pld 3, vec@got@pcrel(0), 1
- // .Lpcrel1:
- if (IsPartOfGOTToPCRelPair.hasValue() && IsPartOfGOTToPCRelPair.getValue())
- emitGOTToPCRelLabel(Inst);
+
+ // Producer of the GOT-indirect address.
+ // For example, the prefixed load from the got that will get the label as
+ // follows:
+ // pld 3, vec@got@pcrel(0), 1
+ // .Lpcrel1:
+ if (IsPartOfGOTToPCRelPair.hasValue() && IsPartOfGOTToPCRelPair.getValue())
+ emitGOTToPCRelLabel(Inst);
}
void PPCELFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
@@ -125,102 +125,102 @@ void PPCELFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
MCELFStreamer::emitLabel(Symbol);
}
-// This linker time GOT PC Relative optimization relocation will look like this:
-// pld <reg> symbol@got@pcrel
-// <Label###>:
-// .reloc Label###-8,R_PPC64_PCREL_OPT,.-(Label###-8)
-// load <loadedreg>, 0(<reg>)
-// The reason we place the label after the PLDpc instruction is that there
-// may be an alignment nop before it since prefixed instructions must not
-// cross a 64-byte boundary (please see
-// PPCELFStreamer::emitPrefixedInstruction()). When referring to the
-// label, we subtract the width of a prefixed instruction (8 bytes) to ensure
-// we refer to the PLDpc.
-void PPCELFStreamer::emitGOTToPCRelReloc(const MCInst &Inst) {
- // Get the last operand which contains the symbol.
- const MCOperand &Operand = Inst.getOperand(Inst.getNumOperands() - 1);
- assert(Operand.isExpr() && "Expecting an MCExpr.");
- // Cast the last operand to MCSymbolRefExpr to get the symbol.
- const MCExpr *Expr = Operand.getExpr();
- const MCSymbolRefExpr *SymExpr = static_cast<const MCSymbolRefExpr *>(Expr);
- assert(SymExpr->getKind() == MCSymbolRefExpr::VK_PPC_PCREL_OPT &&
- "Expecting a symbol of type VK_PPC_PCREL_OPT");
- MCSymbol *LabelSym =
- getContext().getOrCreateSymbol(SymExpr->getSymbol().getName());
- const MCExpr *LabelExpr = MCSymbolRefExpr::create(LabelSym, getContext());
- const MCExpr *Eight = MCConstantExpr::create(8, getContext());
- // SubExpr is just Label###-8
- const MCExpr *SubExpr =
- MCBinaryExpr::createSub(LabelExpr, Eight, getContext());
- MCSymbol *CurrentLocation = getContext().createTempSymbol();
- const MCExpr *CurrentLocationExpr =
- MCSymbolRefExpr::create(CurrentLocation, getContext());
- // SubExpr2 is .-(Label###-8)
- const MCExpr *SubExpr2 =
- MCBinaryExpr::createSub(CurrentLocationExpr, SubExpr, getContext());
-
- MCDataFragment *DF = static_cast<MCDataFragment *>(LabelSym->getFragment());
- assert(DF && "Expecting a valid data fragment.");
- MCFixupKind FixupKind = static_cast<MCFixupKind>(FirstLiteralRelocationKind +
- ELF::R_PPC64_PCREL_OPT);
- DF->getFixups().push_back(
- MCFixup::create(LabelSym->getOffset() - 8, SubExpr2,
- FixupKind, Inst.getLoc()));
- emitLabel(CurrentLocation, Inst.getLoc());
-}
-
-// Emit the label that immediately follows the PLDpc for a link time GOT PC Rel
-// optimization.
-void PPCELFStreamer::emitGOTToPCRelLabel(const MCInst &Inst) {
- // Get the last operand which contains the symbol.
- const MCOperand &Operand = Inst.getOperand(Inst.getNumOperands() - 1);
- assert(Operand.isExpr() && "Expecting an MCExpr.");
- // Cast the last operand to MCSymbolRefExpr to get the symbol.
- const MCExpr *Expr = Operand.getExpr();
- const MCSymbolRefExpr *SymExpr = static_cast<const MCSymbolRefExpr *>(Expr);
- assert(SymExpr->getKind() == MCSymbolRefExpr::VK_PPC_PCREL_OPT &&
- "Expecting a symbol of type VK_PPC_PCREL_OPT");
- MCSymbol *LabelSym =
- getContext().getOrCreateSymbol(SymExpr->getSymbol().getName());
- emitLabel(LabelSym, Inst.getLoc());
-}
-
-// This funciton checks if the parameter Inst is part of the setup for a link
-// time GOT PC Relative optimization. For example in this situation:
-// <MCInst PLDpc <MCOperand Reg:282> <MCOperand Expr:(glob_double@got@pcrel)>
-// <MCOperand Imm:0> <MCOperand Expr:(.Lpcrel@<<invalid>>)>>
-// <MCInst SOME_LOAD <MCOperand Reg:22> <MCOperand Imm:0> <MCOperand Reg:282>
-// <MCOperand Expr:(.Lpcrel@<<invalid>>)>>
-// The above is a pair of such instructions and this function will not return
-// None for either one of them. In both cases we are looking for the last
-// operand <MCOperand Expr:(.Lpcrel@<<invalid>>)> which needs to be an MCExpr
-// and has the flag MCSymbolRefExpr::VK_PPC_PCREL_OPT. After that we just look
-// at the opcode and in the case of PLDpc we will return true. For the load
-// (or store) this function will return false indicating it has found the second
-// instruciton in the pair.
-Optional<bool> llvm::isPartOfGOTToPCRelPair(const MCInst &Inst,
- const MCSubtargetInfo &STI) {
- // Need at least two operands.
- if (Inst.getNumOperands() < 2)
- return None;
-
- unsigned LastOp = Inst.getNumOperands() - 1;
- // The last operand needs to be an MCExpr and it needs to have a variant kind
- // of VK_PPC_PCREL_OPT. If it does not satisfy these conditions it is not a
- // link time GOT PC Rel opt instruction and we can ignore it and return None.
- const MCOperand &Operand = Inst.getOperand(LastOp);
- if (!Operand.isExpr())
- return None;
-
- // Check for the variant kind VK_PPC_PCREL_OPT in this expression.
- const MCExpr *Expr = Operand.getExpr();
- const MCSymbolRefExpr *SymExpr = static_cast<const MCSymbolRefExpr *>(Expr);
- if (!SymExpr || SymExpr->getKind() != MCSymbolRefExpr::VK_PPC_PCREL_OPT)
- return None;
-
- return (Inst.getOpcode() == PPC::PLDpc);
-}
-
+// This linker time GOT PC Relative optimization relocation will look like this:
+// pld <reg> symbol@got@pcrel
+// <Label###>:
+// .reloc Label###-8,R_PPC64_PCREL_OPT,.-(Label###-8)
+// load <loadedreg>, 0(<reg>)
+// The reason we place the label after the PLDpc instruction is that there
+// may be an alignment nop before it since prefixed instructions must not
+// cross a 64-byte boundary (please see
+// PPCELFStreamer::emitPrefixedInstruction()). When referring to the
+// label, we subtract the width of a prefixed instruction (8 bytes) to ensure
+// we refer to the PLDpc.
+void PPCELFStreamer::emitGOTToPCRelReloc(const MCInst &Inst) {
+ // Get the last operand which contains the symbol.
+ const MCOperand &Operand = Inst.getOperand(Inst.getNumOperands() - 1);
+ assert(Operand.isExpr() && "Expecting an MCExpr.");
+ // Cast the last operand to MCSymbolRefExpr to get the symbol.
+ const MCExpr *Expr = Operand.getExpr();
+ const MCSymbolRefExpr *SymExpr = static_cast<const MCSymbolRefExpr *>(Expr);
+ assert(SymExpr->getKind() == MCSymbolRefExpr::VK_PPC_PCREL_OPT &&
+ "Expecting a symbol of type VK_PPC_PCREL_OPT");
+ MCSymbol *LabelSym =
+ getContext().getOrCreateSymbol(SymExpr->getSymbol().getName());
+ const MCExpr *LabelExpr = MCSymbolRefExpr::create(LabelSym, getContext());
+ const MCExpr *Eight = MCConstantExpr::create(8, getContext());
+ // SubExpr is just Label###-8
+ const MCExpr *SubExpr =
+ MCBinaryExpr::createSub(LabelExpr, Eight, getContext());
+ MCSymbol *CurrentLocation = getContext().createTempSymbol();
+ const MCExpr *CurrentLocationExpr =
+ MCSymbolRefExpr::create(CurrentLocation, getContext());
+ // SubExpr2 is .-(Label###-8)
+ const MCExpr *SubExpr2 =
+ MCBinaryExpr::createSub(CurrentLocationExpr, SubExpr, getContext());
+
+ MCDataFragment *DF = static_cast<MCDataFragment *>(LabelSym->getFragment());
+ assert(DF && "Expecting a valid data fragment.");
+ MCFixupKind FixupKind = static_cast<MCFixupKind>(FirstLiteralRelocationKind +
+ ELF::R_PPC64_PCREL_OPT);
+ DF->getFixups().push_back(
+ MCFixup::create(LabelSym->getOffset() - 8, SubExpr2,
+ FixupKind, Inst.getLoc()));
+ emitLabel(CurrentLocation, Inst.getLoc());
+}
+
+// Emit the label that immediately follows the PLDpc for a link time GOT PC Rel
+// optimization.
+void PPCELFStreamer::emitGOTToPCRelLabel(const MCInst &Inst) {
+ // Get the last operand which contains the symbol.
+ const MCOperand &Operand = Inst.getOperand(Inst.getNumOperands() - 1);
+ assert(Operand.isExpr() && "Expecting an MCExpr.");
+ // Cast the last operand to MCSymbolRefExpr to get the symbol.
+ const MCExpr *Expr = Operand.getExpr();
+ const MCSymbolRefExpr *SymExpr = static_cast<const MCSymbolRefExpr *>(Expr);
+ assert(SymExpr->getKind() == MCSymbolRefExpr::VK_PPC_PCREL_OPT &&
+ "Expecting a symbol of type VK_PPC_PCREL_OPT");
+ MCSymbol *LabelSym =
+ getContext().getOrCreateSymbol(SymExpr->getSymbol().getName());
+ emitLabel(LabelSym, Inst.getLoc());
+}
+
+// This funciton checks if the parameter Inst is part of the setup for a link
+// time GOT PC Relative optimization. For example in this situation:
+// <MCInst PLDpc <MCOperand Reg:282> <MCOperand Expr:(glob_double@got@pcrel)>
+// <MCOperand Imm:0> <MCOperand Expr:(.Lpcrel@<<invalid>>)>>
+// <MCInst SOME_LOAD <MCOperand Reg:22> <MCOperand Imm:0> <MCOperand Reg:282>
+// <MCOperand Expr:(.Lpcrel@<<invalid>>)>>
+// The above is a pair of such instructions and this function will not return
+// None for either one of them. In both cases we are looking for the last
+// operand <MCOperand Expr:(.Lpcrel@<<invalid>>)> which needs to be an MCExpr
+// and has the flag MCSymbolRefExpr::VK_PPC_PCREL_OPT. After that we just look
+// at the opcode and in the case of PLDpc we will return true. For the load
+// (or store) this function will return false indicating it has found the second
+// instruciton in the pair.
+Optional<bool> llvm::isPartOfGOTToPCRelPair(const MCInst &Inst,
+ const MCSubtargetInfo &STI) {
+ // Need at least two operands.
+ if (Inst.getNumOperands() < 2)
+ return None;
+
+ unsigned LastOp = Inst.getNumOperands() - 1;
+ // The last operand needs to be an MCExpr and it needs to have a variant kind
+ // of VK_PPC_PCREL_OPT. If it does not satisfy these conditions it is not a
+ // link time GOT PC Rel opt instruction and we can ignore it and return None.
+ const MCOperand &Operand = Inst.getOperand(LastOp);
+ if (!Operand.isExpr())
+ return None;
+
+ // Check for the variant kind VK_PPC_PCREL_OPT in this expression.
+ const MCExpr *Expr = Operand.getExpr();
+ const MCSymbolRefExpr *SymExpr = static_cast<const MCSymbolRefExpr *>(Expr);
+ if (!SymExpr || SymExpr->getKind() != MCSymbolRefExpr::VK_PPC_PCREL_OPT)
+ return None;
+
+ return (Inst.getOpcode() == PPC::PLDpc);
+}
+
MCELFStreamer *llvm::createPPCELFStreamer(
MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
std::unique_ptr<MCObjectWriter> OW,
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.h b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.h
index c30ca4b187..f44200104f 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.h
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.h
@@ -43,15 +43,15 @@ public:
void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
private:
void emitPrefixedInstruction(const MCInst &Inst, const MCSubtargetInfo &STI);
- void emitGOTToPCRelReloc(const MCInst &Inst);
- void emitGOTToPCRelLabel(const MCInst &Inst);
+ void emitGOTToPCRelReloc(const MCInst &Inst);
+ void emitGOTToPCRelLabel(const MCInst &Inst);
};
-// Check if the instruction Inst is part of a pair of instructions that make up
-// a link time GOT PC Rel optimization.
-Optional<bool> isPartOfGOTToPCRelPair(const MCInst &Inst,
- const MCSubtargetInfo &STI);
-
+// Check if the instruction Inst is part of a pair of instructions that make up
+// a link time GOT PC Rel optimization.
+Optional<bool> isPartOfGOTToPCRelPair(const MCInst &Inst,
+ const MCSubtargetInfo &STI);
+
MCELFStreamer *createPPCELFStreamer(MCContext &Context,
std::unique_ptr<MCAsmBackend> MAB,
std::unique_ptr<MCObjectWriter> OW,
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
index 018aa1b558..73292f7b79 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
@@ -43,9 +43,9 @@ enum Fixups {
// A 34-bit fixup corresponding to PC-relative paddi.
fixup_ppc_pcrel34,
- // A 34-bit fixup corresponding to Non-PC-relative paddi.
- fixup_ppc_imm34,
-
+ // A 34-bit fixup corresponding to Non-PC-relative paddi.
+ fixup_ppc_imm34,
+
/// Not a true fixup, but ties a symbol to a call to __tls_get_addr for the
/// TLS general and local dynamic models, or inserts the thread-pointer
/// register number.
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
index bd64f007df..a291a34d4c 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
@@ -71,45 +71,45 @@ void PPCInstPrinter::printInst(const MCInst *MI, uint64_t Address,
"reference expression if it is an expression at all.");
O << "\taddis ";
- printOperand(MI, 0, STI, O);
+ printOperand(MI, 0, STI, O);
O << ", ";
- printOperand(MI, 2, STI, O);
+ printOperand(MI, 2, STI, O);
O << "(";
- printOperand(MI, 1, STI, O);
+ printOperand(MI, 1, STI, O);
O << ")";
return;
}
- // Check if the last operand is an expression with the variant kind
- // VK_PPC_PCREL_OPT. If this is the case then this is a linker optimization
- // relocation and the .reloc directive needs to be added.
- unsigned LastOp = MI->getNumOperands() - 1;
- if (MI->getNumOperands() > 1) {
- const MCOperand &Operand = MI->getOperand(LastOp);
- if (Operand.isExpr()) {
- const MCExpr *Expr = Operand.getExpr();
- const MCSymbolRefExpr *SymExpr =
- static_cast<const MCSymbolRefExpr *>(Expr);
-
- if (SymExpr && SymExpr->getKind() == MCSymbolRefExpr::VK_PPC_PCREL_OPT) {
- const MCSymbol &Symbol = SymExpr->getSymbol();
- if (MI->getOpcode() == PPC::PLDpc) {
- printInstruction(MI, Address, STI, O);
- O << "\n";
- Symbol.print(O, &MAI);
- O << ":";
- return;
- } else {
- O << "\t.reloc ";
- Symbol.print(O, &MAI);
- O << "-8,R_PPC64_PCREL_OPT,.-(";
- Symbol.print(O, &MAI);
- O << "-8)\n";
- }
- }
- }
- }
-
+ // Check if the last operand is an expression with the variant kind
+ // VK_PPC_PCREL_OPT. If this is the case then this is a linker optimization
+ // relocation and the .reloc directive needs to be added.
+ unsigned LastOp = MI->getNumOperands() - 1;
+ if (MI->getNumOperands() > 1) {
+ const MCOperand &Operand = MI->getOperand(LastOp);
+ if (Operand.isExpr()) {
+ const MCExpr *Expr = Operand.getExpr();
+ const MCSymbolRefExpr *SymExpr =
+ static_cast<const MCSymbolRefExpr *>(Expr);
+
+ if (SymExpr && SymExpr->getKind() == MCSymbolRefExpr::VK_PPC_PCREL_OPT) {
+ const MCSymbol &Symbol = SymExpr->getSymbol();
+ if (MI->getOpcode() == PPC::PLDpc) {
+ printInstruction(MI, Address, STI, O);
+ O << "\n";
+ Symbol.print(O, &MAI);
+ O << ":";
+ return;
+ } else {
+ O << "\t.reloc ";
+ Symbol.print(O, &MAI);
+ O << "-8,R_PPC64_PCREL_OPT,.-(";
+ Symbol.print(O, &MAI);
+ O << "-8)\n";
+ }
+ }
+ }
+ }
+
// Check for slwi/srwi mnemonics.
if (MI->getOpcode() == PPC::RLWINM) {
unsigned char SH = MI->getOperand(2).getImm();
@@ -124,9 +124,9 @@ void PPCInstPrinter::printInst(const MCInst *MI, uint64_t Address,
SH = 32-SH;
}
if (useSubstituteMnemonic) {
- printOperand(MI, 0, STI, O);
+ printOperand(MI, 0, STI, O);
O << ", ";
- printOperand(MI, 1, STI, O);
+ printOperand(MI, 1, STI, O);
O << ", " << (unsigned int)SH;
printAnnotation(O, Annot);
@@ -141,9 +141,9 @@ void PPCInstPrinter::printInst(const MCInst *MI, uint64_t Address,
// rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
if (63-SH == ME) {
O << "\tsldi ";
- printOperand(MI, 0, STI, O);
+ printOperand(MI, 0, STI, O);
O << ", ";
- printOperand(MI, 1, STI, O);
+ printOperand(MI, 1, STI, O);
O << ", " << (unsigned int)SH;
printAnnotation(O, Annot);
return;
@@ -171,9 +171,9 @@ void PPCInstPrinter::printInst(const MCInst *MI, uint64_t Address,
if (IsBookE && TH != 0 && TH != 16)
O << (unsigned int) TH << ", ";
- printOperand(MI, 1, STI, O);
+ printOperand(MI, 1, STI, O);
O << ", ";
- printOperand(MI, 2, STI, O);
+ printOperand(MI, 2, STI, O);
if (!IsBookE && TH != 0 && TH != 16)
O << ", " << (unsigned int) TH;
@@ -184,36 +184,36 @@ void PPCInstPrinter::printInst(const MCInst *MI, uint64_t Address,
if (MI->getOpcode() == PPC::DCBF) {
unsigned char L = MI->getOperand(0).getImm();
- if (!L || L == 1 || L == 3 || L == 4 || L == 6) {
- O << "\tdcb";
- if (L != 6)
- O << "f";
- if (L == 1)
+ if (!L || L == 1 || L == 3 || L == 4 || L == 6) {
+ O << "\tdcb";
+ if (L != 6)
+ O << "f";
+ if (L == 1)
O << "l";
if (L == 3)
- O << "lp";
- if (L == 4)
- O << "ps";
- if (L == 6)
- O << "stps";
+ O << "lp";
+ if (L == 4)
+ O << "ps";
+ if (L == 6)
+ O << "stps";
O << " ";
- printOperand(MI, 1, STI, O);
+ printOperand(MI, 1, STI, O);
O << ", ";
- printOperand(MI, 2, STI, O);
+ printOperand(MI, 2, STI, O);
printAnnotation(O, Annot);
return;
}
}
- if (!printAliasInstr(MI, Address, STI, O))
- printInstruction(MI, Address, STI, O);
+ if (!printAliasInstr(MI, Address, STI, O))
+ printInstruction(MI, Address, STI, O);
printAnnotation(O, Annot);
}
void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O,
const char *Modifier) {
unsigned Code = MI->getOperand(OpNo).getImm();
@@ -307,11 +307,11 @@ void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
assert(StringRef(Modifier) == "reg" &&
"Need to specify 'cc', 'pm' or 'reg' as predicate op modifier!");
- printOperand(MI, OpNo + 1, STI, O);
+ printOperand(MI, OpNo + 1, STI, O);
}
void PPCInstPrinter::printATBitsAsHint(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
unsigned Code = MI->getOperand(OpNo).getImm();
if (Code == 2)
@@ -321,7 +321,7 @@ void PPCInstPrinter::printATBitsAsHint(const MCInst *MI, unsigned OpNo,
}
void PPCInstPrinter::printU1ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
unsigned int Value = MI->getOperand(OpNo).getImm();
assert(Value <= 1 && "Invalid u1imm argument!");
@@ -329,7 +329,7 @@ void PPCInstPrinter::printU1ImmOperand(const MCInst *MI, unsigned OpNo,
}
void PPCInstPrinter::printU2ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
unsigned int Value = MI->getOperand(OpNo).getImm();
assert(Value <= 3 && "Invalid u2imm argument!");
@@ -337,7 +337,7 @@ void PPCInstPrinter::printU2ImmOperand(const MCInst *MI, unsigned OpNo,
}
void PPCInstPrinter::printU3ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
unsigned int Value = MI->getOperand(OpNo).getImm();
assert(Value <= 8 && "Invalid u3imm argument!");
@@ -345,7 +345,7 @@ void PPCInstPrinter::printU3ImmOperand(const MCInst *MI, unsigned OpNo,
}
void PPCInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
unsigned int Value = MI->getOperand(OpNo).getImm();
assert(Value <= 15 && "Invalid u4imm argument!");
@@ -353,7 +353,7 @@ void PPCInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
}
void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
int Value = MI->getOperand(OpNo).getImm();
Value = SignExtend32<5>(Value);
@@ -361,7 +361,7 @@ void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo,
}
void PPCInstPrinter::printImmZeroOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
unsigned int Value = MI->getOperand(OpNo).getImm();
assert(Value == 0 && "Operand must be zero");
@@ -369,7 +369,7 @@ void PPCInstPrinter::printImmZeroOperand(const MCInst *MI, unsigned OpNo,
}
void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
unsigned int Value = MI->getOperand(OpNo).getImm();
assert(Value <= 31 && "Invalid u5imm argument!");
@@ -377,7 +377,7 @@ void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo,
}
void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
unsigned int Value = MI->getOperand(OpNo).getImm();
assert(Value <= 63 && "Invalid u6imm argument!");
@@ -385,7 +385,7 @@ void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo,
}
void PPCInstPrinter::printU7ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
unsigned int Value = MI->getOperand(OpNo).getImm();
assert(Value <= 127 && "Invalid u7imm argument!");
@@ -396,14 +396,14 @@ void PPCInstPrinter::printU7ImmOperand(const MCInst *MI, unsigned OpNo,
// of XXSPLTIB which are unsigned. So we simply truncate to 8 bits and
// print as unsigned.
void PPCInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
unsigned char Value = MI->getOperand(OpNo).getImm();
O << (unsigned int)Value;
}
void PPCInstPrinter::printU10ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
unsigned short Value = MI->getOperand(OpNo).getImm();
assert(Value <= 1023 && "Invalid u10imm argument!");
@@ -411,7 +411,7 @@ void PPCInstPrinter::printU10ImmOperand(const MCInst *MI, unsigned OpNo,
}
void PPCInstPrinter::printU12ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
unsigned short Value = MI->getOperand(OpNo).getImm();
assert(Value <= 4095 && "Invalid u12imm argument!");
@@ -419,16 +419,16 @@ void PPCInstPrinter::printU12ImmOperand(const MCInst *MI, unsigned OpNo,
}
void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
if (MI->getOperand(OpNo).isImm())
O << (short)MI->getOperand(OpNo).getImm();
else
- printOperand(MI, OpNo, STI, O);
+ printOperand(MI, OpNo, STI, O);
}
void PPCInstPrinter::printS34ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
if (MI->getOperand(OpNo).isImm()) {
long long Value = MI->getOperand(OpNo).getImm();
@@ -436,24 +436,24 @@ void PPCInstPrinter::printS34ImmOperand(const MCInst *MI, unsigned OpNo,
O << (long long)Value;
}
else
- printOperand(MI, OpNo, STI, O);
+ printOperand(MI, OpNo, STI, O);
}
void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
if (MI->getOperand(OpNo).isImm())
O << (unsigned short)MI->getOperand(OpNo).getImm();
else
- printOperand(MI, OpNo, STI, O);
+ printOperand(MI, OpNo, STI, O);
}
void PPCInstPrinter::printBranchOperand(const MCInst *MI, uint64_t Address,
- unsigned OpNo,
- const MCSubtargetInfo &STI,
- raw_ostream &O) {
+ unsigned OpNo,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
if (!MI->getOperand(OpNo).isImm())
- return printOperand(MI, OpNo, STI, O);
+ return printOperand(MI, OpNo, STI, O);
int32_t Imm = SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2);
if (PrintBranchImmAsAddress) {
uint64_t Target = Address + Imm;
@@ -476,16 +476,16 @@ void PPCInstPrinter::printBranchOperand(const MCInst *MI, uint64_t Address,
}
void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
if (!MI->getOperand(OpNo).isImm())
- return printOperand(MI, OpNo, STI, O);
+ return printOperand(MI, OpNo, STI, O);
O << SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2);
}
void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O) {
+ const MCSubtargetInfo &STI, raw_ostream &O) {
unsigned CCReg = MI->getOperand(OpNo).getReg();
unsigned RegNo;
switch (CCReg) {
@@ -503,37 +503,37 @@ void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo,
}
void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
- printS16ImmOperand(MI, OpNo, STI, O);
+ printS16ImmOperand(MI, OpNo, STI, O);
O << '(';
if (MI->getOperand(OpNo+1).getReg() == PPC::R0)
O << "0";
else
- printOperand(MI, OpNo + 1, STI, O);
+ printOperand(MI, OpNo + 1, STI, O);
O << ')';
}
void PPCInstPrinter::printMemRegImm34PCRel(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
- printS34ImmOperand(MI, OpNo, STI, O);
+ printS34ImmOperand(MI, OpNo, STI, O);
O << '(';
- printImmZeroOperand(MI, OpNo + 1, STI, O);
+ printImmZeroOperand(MI, OpNo + 1, STI, O);
O << ')';
}
void PPCInstPrinter::printMemRegImm34(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
- raw_ostream &O) {
- printS34ImmOperand(MI, OpNo, STI, O);
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
+ printS34ImmOperand(MI, OpNo, STI, O);
O << '(';
- printOperand(MI, OpNo + 1, STI, O);
+ printOperand(MI, OpNo + 1, STI, O);
O << ')';
}
void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &O) {
// When used as the base register, r0 reads constant zero rather than
// the value contained in the register. For this reason, the darwin
@@ -541,13 +541,13 @@ void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo,
if (MI->getOperand(OpNo).getReg() == PPC::R0)
O << "0";
else
- printOperand(MI, OpNo, STI, O);
+ printOperand(MI, OpNo, STI, O);
O << ", ";
- printOperand(MI, OpNo + 1, STI, O);
+ printOperand(MI, OpNo + 1, STI, O);
}
void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O) {
+ const MCSubtargetInfo &STI, raw_ostream &O) {
// On PPC64, VariantKind is VK_None, but on PPC32, it's VK_PLT, and it must
// come at the _end_ of the expression.
const MCOperand &Op = MI->getOperand(OpNo);
@@ -560,17 +560,17 @@ void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo,
RefExp = cast<MCSymbolRefExpr>(Op.getExpr());
O << RefExp->getSymbol().getName();
- // The variant kind VK_PPC_NOTOC needs to be handled as a special case
- // because we do not want the assembly to print out the @notoc at the
- // end like __tls_get_addr(x@tlsgd)@notoc. Instead we want it to look
- // like __tls_get_addr@notoc(x@tlsgd).
- if (RefExp->getKind() == MCSymbolRefExpr::VK_PPC_NOTOC)
- O << '@' << MCSymbolRefExpr::getVariantKindName(RefExp->getKind());
+ // The variant kind VK_PPC_NOTOC needs to be handled as a special case
+ // because we do not want the assembly to print out the @notoc at the
+ // end like __tls_get_addr(x@tlsgd)@notoc. Instead we want it to look
+ // like __tls_get_addr@notoc(x@tlsgd).
+ if (RefExp->getKind() == MCSymbolRefExpr::VK_PPC_NOTOC)
+ O << '@' << MCSymbolRefExpr::getVariantKindName(RefExp->getKind());
O << '(';
- printOperand(MI, OpNo + 1, STI, O);
+ printOperand(MI, OpNo + 1, STI, O);
O << ')';
- if (RefExp->getKind() != MCSymbolRefExpr::VK_None &&
- RefExp->getKind() != MCSymbolRefExpr::VK_PPC_NOTOC)
+ if (RefExp->getKind() != MCSymbolRefExpr::VK_None &&
+ RefExp->getKind() != MCSymbolRefExpr::VK_PPC_NOTOC)
O << '@' << MCSymbolRefExpr::getVariantKindName(RefExp->getKind());
if (ConstExp != nullptr)
O << '+' << ConstExp->getValue();
@@ -579,7 +579,7 @@ void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo,
/// showRegistersWithPercentPrefix - Check if this register name should be
/// printed with a percentage symbol as prefix.
bool PPCInstPrinter::showRegistersWithPercentPrefix(const char *RegName) const {
- if (!FullRegNamesWithPercent || TT.getOS() == Triple::AIX)
+ if (!FullRegNamesWithPercent || TT.getOS() == Triple::AIX)
return false;
switch (RegName[0]) {
@@ -599,7 +599,7 @@ bool PPCInstPrinter::showRegistersWithPercentPrefix(const char *RegName) const {
const char *PPCInstPrinter::getVerboseConditionRegName(unsigned RegNum,
unsigned RegEncoding)
const {
- if (!FullRegNames)
+ if (!FullRegNames)
return nullptr;
if (RegNum < PPC::CR0EQ || RegNum > PPC::CR7UN)
return nullptr;
@@ -621,11 +621,11 @@ const char *PPCInstPrinter::getVerboseConditionRegName(unsigned RegNum,
bool PPCInstPrinter::showRegistersWithPrefix() const {
if (TT.getOS() == Triple::AIX)
return false;
- return FullRegNamesWithPercent || FullRegNames;
+ return FullRegNamesWithPercent || FullRegNames;
}
void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O) {
+ const MCSubtargetInfo &STI, raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isReg()) {
unsigned Reg = Op.getReg();
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
index 7b6c4c9fa3..5e9b014944 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
@@ -36,73 +36,73 @@ public:
const MCSubtargetInfo &STI, raw_ostream &O) override;
// Autogenerated by tblgen.
- std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
- void printInstruction(const MCInst *MI, uint64_t Address,
- const MCSubtargetInfo &STI, raw_ostream &O);
+ std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
+ void printInstruction(const MCInst *MI, uint64_t Address,
+ const MCSubtargetInfo &STI, raw_ostream &O);
static const char *getRegisterName(unsigned RegNo);
- bool printAliasInstr(const MCInst *MI, uint64_t Address,
- const MCSubtargetInfo &STI, raw_ostream &OS);
+ bool printAliasInstr(const MCInst *MI, uint64_t Address,
+ const MCSubtargetInfo &STI, raw_ostream &OS);
void printCustomAliasOperand(const MCInst *MI, uint64_t Address,
unsigned OpIdx, unsigned PrintMethodIdx,
- const MCSubtargetInfo &STI, raw_ostream &OS);
+ const MCSubtargetInfo &STI, raw_ostream &OS);
- void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
- raw_ostream &O);
+ void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
+ raw_ostream &O);
void printPredicateOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O,
- const char *Modifier = nullptr);
- void printATBitsAsHint(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
+ const MCSubtargetInfo &STI, raw_ostream &O,
+ const char *Modifier = nullptr);
+ void printATBitsAsHint(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
- void printU1ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printU2ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printU3ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printU4ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printS5ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printU5ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printU6ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printU7ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printU8ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printU10ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printU12ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printS16ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printS34ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printU16ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printImmZeroOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
+ void printU1ImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printU2ImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printU3ImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printU4ImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printS5ImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printU5ImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printU6ImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printU7ImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printU8ImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printU10ImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printU12ImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printS16ImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printS34ImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printU16ImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printImmZeroOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
void printBranchOperand(const MCInst *MI, uint64_t Address, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printAbsBranchOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printTLSCall(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
- raw_ostream &O);
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printAbsBranchOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printTLSCall(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
+ raw_ostream &O);
- void printcrbitm(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
- raw_ostream &O);
+ void printcrbitm(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
+ raw_ostream &O);
- void printMemRegImm(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printMemRegImm34PCRel(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printMemRegImm34(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printMemRegReg(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
+ void printMemRegImm(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printMemRegImm34PCRel(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printMemRegImm34(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printMemRegReg(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
index dfadde0cd4..2b76af279c 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
@@ -26,8 +26,8 @@ PPCELFMCAsmInfo::PPCELFMCAsmInfo(bool is64Bit, const Triple& T) {
if (is64Bit) {
CodePointerSize = CalleeSaveStackSlotSize = 8;
}
- IsLittleEndian =
- T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppcle;
+ IsLittleEndian =
+ T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppcle;
// ".comm align is in bytes but .align is pow-2."
AlignmentIsInBytes = false;
@@ -57,7 +57,7 @@ PPCELFMCAsmInfo::PPCELFMCAsmInfo(bool is64Bit, const Triple& T) {
void PPCXCOFFMCAsmInfo::anchor() {}
PPCXCOFFMCAsmInfo::PPCXCOFFMCAsmInfo(bool Is64Bit, const Triple &T) {
- if (T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppcle)
+ if (T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppcle)
report_fatal_error("XCOFF is not supported for little-endian targets");
CodePointerSize = CalleeSaveStackSlotSize = Is64Bit ? 8 : 4;
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
index f481106939..5f0769fd21 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
@@ -45,12 +45,12 @@ getDirectBrEncoding(const MCInst &MI, unsigned OpNo,
const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpNo);
- if (MO.isReg() || MO.isImm())
- return getMachineOpValue(MI, MO, Fixups, STI);
+ if (MO.isReg() || MO.isImm())
+ return getMachineOpValue(MI, MO, Fixups, STI);
// Add a fixup for the branch target.
Fixups.push_back(MCFixup::create(0, MO.getExpr(),
- ((MI.getOpcode() == PPC::BL8_NOTOC ||
- MI.getOpcode() == PPC::BL8_NOTOC_TLS)
+ ((MI.getOpcode() == PPC::BL8_NOTOC ||
+ MI.getOpcode() == PPC::BL8_NOTOC_TLS)
? (MCFixupKind)PPC::fixup_ppc_br24_notoc
: (MCFixupKind)PPC::fixup_ppc_br24)));
return 0;
@@ -94,16 +94,16 @@ getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo,
return 0;
}
-unsigned
-PPCMCCodeEmitter::getVSRpEvenEncoding(const MCInst &MI, unsigned OpNo,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
- assert(MI.getOperand(OpNo).isReg() && "Operand should be a register");
- unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI)
- << 1;
- return RegBits;
-}
-
+unsigned
+PPCMCCodeEmitter::getVSRpEvenEncoding(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ assert(MI.getOperand(OpNo).isReg() && "Operand should be a register");
+ unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI)
+ << 1;
+ return RegBits;
+}
+
unsigned PPCMCCodeEmitter::getImm16Encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
@@ -116,36 +116,36 @@ unsigned PPCMCCodeEmitter::getImm16Encoding(const MCInst &MI, unsigned OpNo,
return 0;
}
-uint64_t PPCMCCodeEmitter::getImm34Encoding(const MCInst &MI, unsigned OpNo,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI,
- MCFixupKind Fixup) const {
+uint64_t PPCMCCodeEmitter::getImm34Encoding(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI,
+ MCFixupKind Fixup) const {
const MCOperand &MO = MI.getOperand(OpNo);
- assert(!MO.isReg() && "Not expecting a register for this operand.");
- if (MO.isImm())
+ assert(!MO.isReg() && "Not expecting a register for this operand.");
+ if (MO.isImm())
return getMachineOpValue(MI, MO, Fixups, STI);
// Add a fixup for the immediate field.
- Fixups.push_back(MCFixup::create(0, MO.getExpr(), Fixup));
+ Fixups.push_back(MCFixup::create(0, MO.getExpr(), Fixup));
return 0;
}
-uint64_t
-PPCMCCodeEmitter::getImm34EncodingNoPCRel(const MCInst &MI, unsigned OpNo,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
- return getImm34Encoding(MI, OpNo, Fixups, STI,
- (MCFixupKind)PPC::fixup_ppc_imm34);
-}
-
-uint64_t
-PPCMCCodeEmitter::getImm34EncodingPCRel(const MCInst &MI, unsigned OpNo,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
- return getImm34Encoding(MI, OpNo, Fixups, STI,
- (MCFixupKind)PPC::fixup_ppc_pcrel34);
-}
-
+uint64_t
+PPCMCCodeEmitter::getImm34EncodingNoPCRel(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ return getImm34Encoding(MI, OpNo, Fixups, STI,
+ (MCFixupKind)PPC::fixup_ppc_imm34);
+}
+
+uint64_t
+PPCMCCodeEmitter::getImm34EncodingPCRel(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ return getImm34Encoding(MI, OpNo, Fixups, STI,
+ (MCFixupKind)PPC::fixup_ppc_pcrel34);
+}
+
unsigned PPCMCCodeEmitter::getMemRIEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
@@ -241,13 +241,13 @@ PPCMCCodeEmitter::getMemRI34PCRelEncoding(const MCInst &MI, unsigned OpNo,
(void)SRE;
// Currently these are the only valid PCRelative Relocations.
assert((SRE->getKind() == MCSymbolRefExpr::VK_PCREL ||
- SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_PCREL ||
- SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL ||
- SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL ||
- SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL) &&
- "VariantKind must be VK_PCREL or VK_PPC_GOT_PCREL or "
- "VK_PPC_GOT_TLSGD_PCREL or VK_PPC_GOT_TLSLD_PCREL or "
- "VK_PPC_GOT_TPREL_PCREL.");
+ SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_PCREL ||
+ SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL ||
+ SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL ||
+ SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL) &&
+ "VariantKind must be VK_PCREL or VK_PPC_GOT_PCREL or "
+ "VK_PPC_GOT_TLSGD_PCREL or VK_PPC_GOT_TLSLD_PCREL or "
+ "VK_PPC_GOT_TPREL_PCREL.");
// Generate the fixup for the relocation.
Fixups.push_back(
MCFixup::create(0, Expr,
@@ -359,12 +359,12 @@ unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
// Add a fixup for the TLS register, which simply provides a relocation
// hint to the linker that this statement is part of a relocation sequence.
- // Return the thread-pointer register's encoding. Add a one byte displacement
- // if using PC relative memops.
- const MCExpr *Expr = MO.getExpr();
- const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(Expr);
- bool IsPCRel = SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS_PCREL;
- Fixups.push_back(MCFixup::create(IsPCRel ? 1 : 0, Expr,
+ // Return the thread-pointer register's encoding. Add a one byte displacement
+ // if using PC relative memops.
+ const MCExpr *Expr = MO.getExpr();
+ const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(Expr);
+ bool IsPCRel = SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS_PCREL;
+ Fixups.push_back(MCFixup::create(IsPCRel ? 1 : 0, Expr,
(MCFixupKind)PPC::fixup_ppc_nofixup));
const Triple &TT = STI.getTargetTriple();
bool isPPC64 = TT.isPPC64();
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h
index a3618f858b..347e163c95 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h
@@ -52,14 +52,14 @@ public:
const MCSubtargetInfo &STI) const;
uint64_t getImm34Encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI,
- MCFixupKind Fixup) const;
- uint64_t getImm34EncodingNoPCRel(const MCInst &MI, unsigned OpNo,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const;
- uint64_t getImm34EncodingPCRel(const MCInst &MI, unsigned OpNo,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const;
+ const MCSubtargetInfo &STI,
+ MCFixupKind Fixup) const;
+ uint64_t getImm34EncodingNoPCRel(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+ uint64_t getImm34EncodingPCRel(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
unsigned getMemRIEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
@@ -93,9 +93,9 @@ public:
unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
- unsigned getVSRpEvenEncoding(const MCInst &MI, unsigned OpNo,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const;
+ unsigned getVSRpEvenEncoding(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
index 19ceda2c62..bf9c6feb54 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
@@ -20,7 +20,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/BinaryFormat/ELF.h"
-#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
@@ -30,7 +30,7 @@
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCSectionXCOFF.h"
+#include "llvm/MC/MCSectionXCOFF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
@@ -78,17 +78,17 @@ static MCRegisterInfo *createPPCMCRegisterInfo(const Triple &TT) {
static MCSubtargetInfo *createPPCMCSubtargetInfo(const Triple &TT,
StringRef CPU, StringRef FS) {
- // Set some default feature to MC layer.
- std::string FullFS = std::string(FS);
-
- if (TT.isOSAIX()) {
- if (!FullFS.empty())
- FullFS = "+aix," + FullFS;
- else
- FullFS = "+aix";
- }
-
- return createPPCMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FullFS);
+ // Set some default feature to MC layer.
+ std::string FullFS = std::string(FS);
+
+ if (TT.isOSAIX()) {
+ if (!FullFS.empty())
+ FullFS = "+aix," + FullFS;
+ else
+ FullFS = "+aix";
+ }
+
+ return createPPCMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FullFS);
}
static MCAsmInfo *createPPCMCAsmInfo(const MCRegisterInfo &MRI,
@@ -133,10 +133,10 @@ public:
void emitTCEntry(const MCSymbol &S) override {
if (const MCSymbolXCOFF *XSym = dyn_cast<MCSymbolXCOFF>(&S)) {
MCSymbolXCOFF *TCSym =
- cast<MCSectionXCOFF>(Streamer.getCurrentSectionOnly())
- ->getQualNameSymbol();
- OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << '\n';
-
+ cast<MCSectionXCOFF>(Streamer.getCurrentSectionOnly())
+ ->getQualNameSymbol();
+ OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << '\n';
+
if (TCSym->hasRename())
Streamer.emitXCOFFRenameDirective(TCSym, TCSym->getSymbolTableName());
return;
@@ -346,8 +346,8 @@ static MCInstPrinter *createPPCMCInstPrinter(const Triple &T,
}
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTargetMC() {
- for (Target *T : {&getThePPC32Target(), &getThePPC32LETarget(),
- &getThePPC64Target(), &getThePPC64LETarget()}) {
+ for (Target *T : {&getThePPC32Target(), &getThePPC32LETarget(),
+ &getThePPC64Target(), &getThePPC64LETarget()}) {
// Register the MC asm info.
RegisterMCAsmInfoFn C(*T, createPPCMCAsmInfo);
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h
index 75a119301a..03b3163417 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h
@@ -124,11 +124,11 @@ static inline bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME) {
#define GET_SUBTARGETINFO_ENUM
#include "PPCGenSubtargetInfo.inc"
-#define PPC_REGS0_7(X) \
- { \
- X##0, X##1, X##2, X##3, X##4, X##5, X##6, X##7 \
- }
-
+#define PPC_REGS0_7(X) \
+ { \
+ X##0, X##1, X##2, X##3, X##4, X##5, X##6, X##7 \
+ }
+
#define PPC_REGS0_31(X) \
{ \
X##0, X##1, X##2, X##3, X##4, X##5, X##6, X##7, X##8, X##9, X##10, X##11, \
@@ -161,7 +161,7 @@ using llvm::MCPhysReg;
static const MCPhysReg RRegs[32] = PPC_REGS0_31(PPC::R); \
static const MCPhysReg XRegs[32] = PPC_REGS0_31(PPC::X); \
static const MCPhysReg FRegs[32] = PPC_REGS0_31(PPC::F); \
- static const MCPhysReg VSRpRegs[32] = PPC_REGS0_31(PPC::VSRp); \
+ static const MCPhysReg VSRpRegs[32] = PPC_REGS0_31(PPC::VSRp); \
static const MCPhysReg SPERegs[32] = PPC_REGS0_31(PPC::S); \
static const MCPhysReg VFRegs[32] = PPC_REGS0_31(PPC::VF); \
static const MCPhysReg VRegs[32] = PPC_REGS0_31(PPC::V); \
@@ -184,6 +184,6 @@ using llvm::MCPhysReg;
PPC::CR5LT, PPC::CR5GT, PPC::CR5EQ, PPC::CR5UN, \
PPC::CR6LT, PPC::CR6GT, PPC::CR6EQ, PPC::CR6UN, \
PPC::CR7LT, PPC::CR7GT, PPC::CR7EQ, PPC::CR7UN}; \
- static const MCPhysReg CRRegs[8] = PPC_REGS0_7(PPC::CR); \
- static const MCPhysReg ACCRegs[8] = PPC_REGS0_7(PPC::ACC)
+ static const MCPhysReg CRRegs[8] = PPC_REGS0_7(PPC::CR); \
+ static const MCPhysReg ACCRegs[8] = PPC_REGS0_7(PPC::ACC)
#endif // LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCTARGETDESC_H
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp
index d8451d4064..77b0331bb1 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp
@@ -58,19 +58,19 @@ std::pair<uint8_t, uint8_t> PPCXCOFFObjectWriter::getRelocTypeAndSignSize(
switch ((unsigned)Fixup.getKind()) {
default:
report_fatal_error("Unimplemented fixup kind.");
- case PPC::fixup_ppc_half16: {
- const uint8_t SignAndSizeForHalf16 = EncodedSignednessIndicator | 15;
+ case PPC::fixup_ppc_half16: {
+ const uint8_t SignAndSizeForHalf16 = EncodedSignednessIndicator | 15;
switch (Modifier) {
default:
report_fatal_error("Unsupported modifier for half16 fixup.");
case MCSymbolRefExpr::VK_None:
- return {XCOFF::RelocationType::R_TOC, SignAndSizeForHalf16};
- case MCSymbolRefExpr::VK_PPC_U:
- return {XCOFF::RelocationType::R_TOCU, SignAndSizeForHalf16};
- case MCSymbolRefExpr::VK_PPC_L:
- return {XCOFF::RelocationType::R_TOCL, SignAndSizeForHalf16};
+ return {XCOFF::RelocationType::R_TOC, SignAndSizeForHalf16};
+ case MCSymbolRefExpr::VK_PPC_U:
+ return {XCOFF::RelocationType::R_TOCU, SignAndSizeForHalf16};
+ case MCSymbolRefExpr::VK_PPC_L:
+ return {XCOFF::RelocationType::R_TOCL, SignAndSizeForHalf16};
}
- } break;
+ } break;
case PPC::fixup_ppc_br24:
// Branches are 4 byte aligned, so the 24 bits we encode in
// the instruction actually represents a 26 bit offset.
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/ya.make b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/ya.make
index 1eee490274..903dc6ec7f 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/ya.make
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/ya.make
@@ -15,18 +15,18 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC
- contrib/libs/llvm12/lib/Target/PowerPC
- contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC
+ contrib/libs/llvm12/lib/Target/PowerPC
+ contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/P9InstrResources.td b/contrib/libs/llvm12/lib/Target/PowerPC/P9InstrResources.td
index 69119b12e7..63531f72ad 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/P9InstrResources.td
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/P9InstrResources.td
@@ -94,7 +94,7 @@ def : InstRW<[P9_ALU_3C, IP_EXEC_1C, DISP_3SLOTS_1C],
(instregex "CMPRB(8)?$"),
(instregex "TD(I)?$"),
(instregex "TW(I)?$"),
- (instregex "FCMP(O|U)(S|D)$"),
+ (instregex "FCMP(O|U)(S|D)$"),
(instregex "XSTSTDC(S|D)P$"),
FTDIV,
FTSQRT,
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPC.h b/contrib/libs/llvm12/lib/Target/PowerPC/PPC.h
index e4d72dd6c2..264582b244 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPC.h
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPC.h
@@ -20,20 +20,20 @@
#undef PPC
namespace llvm {
-class PPCRegisterBankInfo;
-class PPCSubtarget;
-class PPCTargetMachine;
-class PassRegistry;
-class FunctionPass;
-class InstructionSelector;
-class MachineInstr;
-class MachineOperand;
-class AsmPrinter;
-class MCInst;
-class MCOperand;
-class ModulePass;
-
-FunctionPass *createPPCCTRLoops();
+class PPCRegisterBankInfo;
+class PPCSubtarget;
+class PPCTargetMachine;
+class PassRegistry;
+class FunctionPass;
+class InstructionSelector;
+class MachineInstr;
+class MachineOperand;
+class AsmPrinter;
+class MCInst;
+class MCOperand;
+class ModulePass;
+
+FunctionPass *createPPCCTRLoops();
#ifndef NDEBUG
FunctionPass *createPPCCTRLoopsVerify();
#endif
@@ -81,10 +81,10 @@ FunctionPass *createPPCCTRLoops();
ModulePass *createPPCLowerMASSVEntriesPass();
void initializePPCLowerMASSVEntriesPass(PassRegistry &);
extern char &PPCLowerMASSVEntriesID;
-
- InstructionSelector *
- createPPCInstructionSelector(const PPCTargetMachine &, const PPCSubtarget &,
- const PPCRegisterBankInfo &);
+
+ InstructionSelector *
+ createPPCInstructionSelector(const PPCTargetMachine &, const PPCSubtarget &,
+ const PPCRegisterBankInfo &);
namespace PPCII {
/// Target Operand Flag enum.
@@ -111,37 +111,37 @@ FunctionPass *createPPCCTRLoops();
/// produce the relocation @got@pcrel. Fixup is VK_PPC_GOT_PCREL.
MO_GOT_FLAG = 8,
- // MO_PCREL_OPT_FLAG - If this bit is set the operand is part of a
- // PC Relative linker optimization.
- MO_PCREL_OPT_FLAG = 16,
-
- /// MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to
- /// TLS General Dynamic model.
- MO_TLSGD_FLAG = 32,
-
- /// MO_TPREL_FLAG - If this bit is set the symbol reference is relative to
- /// TLS Initial Exec model.
- MO_TPREL_FLAG = 64,
-
- /// MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to
- /// TLS Local Dynamic model.
- MO_TLSLD_FLAG = 128,
-
- /// MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set
- /// they should produce the relocation @got@tlsgd@pcrel.
- /// Fix up is VK_PPC_GOT_TLSGD_PCREL
- MO_GOT_TLSGD_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG | MO_TLSGD_FLAG,
-
- /// MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set
- /// they should produce the relocation @got@tlsld@pcrel.
- /// Fix up is VK_PPC_GOT_TLSLD_PCREL
- MO_GOT_TLSLD_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG | MO_TLSLD_FLAG,
-
- /// MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set
- /// they should produce the relocation @got@tprel@pcrel.
- /// Fix up is VK_PPC_GOT_TPREL_PCREL
- MO_GOT_TPREL_PCREL_FLAG = MO_GOT_FLAG | MO_TPREL_FLAG | MO_PCREL_FLAG,
-
+ // MO_PCREL_OPT_FLAG - If this bit is set the operand is part of a
+ // PC Relative linker optimization.
+ MO_PCREL_OPT_FLAG = 16,
+
+ /// MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to
+ /// TLS General Dynamic model.
+ MO_TLSGD_FLAG = 32,
+
+ /// MO_TPREL_FLAG - If this bit is set the symbol reference is relative to
+ /// TLS Initial Exec model.
+ MO_TPREL_FLAG = 64,
+
+ /// MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to
+ /// TLS Local Dynamic model.
+ MO_TLSLD_FLAG = 128,
+
+ /// MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set
+ /// they should produce the relocation @got@tlsgd@pcrel.
+ /// Fix up is VK_PPC_GOT_TLSGD_PCREL
+ MO_GOT_TLSGD_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG | MO_TLSGD_FLAG,
+
+ /// MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set
+ /// they should produce the relocation @got@tlsld@pcrel.
+ /// Fix up is VK_PPC_GOT_TLSLD_PCREL
+ MO_GOT_TLSLD_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG | MO_TLSLD_FLAG,
+
+ /// MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set
+ /// they should produce the relocation @got@tprel@pcrel.
+ /// Fix up is VK_PPC_GOT_TPREL_PCREL
+ MO_GOT_TPREL_PCREL_FLAG = MO_GOT_FLAG | MO_TPREL_FLAG | MO_PCREL_FLAG,
+
/// The next are not flags but distinct values.
MO_ACCESS_MASK = 0xf00,
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPC.td b/contrib/libs/llvm12/lib/Target/PowerPC/PPC.td
index 2e90fe46fb..1e6ded2315 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPC.td
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPC.td
@@ -57,10 +57,10 @@ def DirectivePwrFuture
def Feature64Bit : SubtargetFeature<"64bit","Has64BitSupport", "true",
"Enable 64-bit instructions">;
-def AIXOS: SubtargetFeature<"aix", "IsAIX", "true", "AIX OS">;
-def FeatureModernAIXAs
- : SubtargetFeature<"modern-aix-as", "HasModernAIXAs", "true",
- "AIX system assembler is modern enough to support new mnes">;
+def AIXOS: SubtargetFeature<"aix", "IsAIX", "true", "AIX OS">;
+def FeatureModernAIXAs
+ : SubtargetFeature<"modern-aix-as", "HasModernAIXAs", "true",
+ "AIX system assembler is modern enough to support new mnes">;
def FeatureHardFloat : SubtargetFeature<"hard-float", "HasHardFloat", "true",
"Enable floating-point instructions">;
def Feature64BitRegs : SubtargetFeature<"64bitregs","Use64BitRegs", "true",
@@ -76,9 +76,9 @@ def FeatureAltivec : SubtargetFeature<"altivec","HasAltivec", "true",
def FeatureSPE : SubtargetFeature<"spe","HasSPE", "true",
"Enable SPE instructions",
[FeatureHardFloat]>;
-def FeatureEFPU2 : SubtargetFeature<"efpu2", "HasEFPU2", "true",
- "Enable Embedded Floating-Point APU 2 instructions",
- [FeatureSPE]>;
+def FeatureEFPU2 : SubtargetFeature<"efpu2", "HasEFPU2", "true",
+ "Enable Embedded Floating-Point APU 2 instructions",
+ [FeatureSPE]>;
def FeatureMFOCRF : SubtargetFeature<"mfocrf","HasMFOCRF", "true",
"Enable the MFOCRF instruction">;
def FeatureFSqrt : SubtargetFeature<"fsqrt","HasFSQRT", "true",
@@ -181,9 +181,9 @@ def FeatureAddisLoadFusion : SubtargetFeature<"fuse-addis-load",
"HasAddisLoadFusion", "true",
"Power8 Addis-Load fusion",
[FeatureFusion]>;
-def FeatureStoreFusion : SubtargetFeature<"fuse-store", "HasStoreFusion", "true",
- "Target supports store clustering",
- [FeatureFusion]>;
+def FeatureStoreFusion : SubtargetFeature<"fuse-store", "HasStoreFusion", "true",
+ "Target supports store clustering",
+ [FeatureFusion]>;
def FeatureUnalignedFloats :
SubtargetFeature<"allow-unaligned-fp-access", "AllowsUnalignedFPAccess",
"true", "CPU does not trap on unaligned FP access">;
@@ -200,7 +200,7 @@ def FeatureFloat128 :
def FeaturePOPCNTD : SubtargetFeature<"popcntd","HasPOPCNTD",
"POPCNTD_Fast",
"Enable the popcnt[dw] instructions">;
-// Note that for the a2 processor models we should not use popcnt[dw] by
+// Note that for the a2 processor models we should not use popcnt[dw] by
// default. These processors do support the instructions, but they're
// microcoded, and the software emulation is about twice as fast.
def FeatureSlowPOPCNTD : SubtargetFeature<"slow-popcntd","HasPOPCNTD",
@@ -243,15 +243,15 @@ def FeaturePrefixInstrs : SubtargetFeature<"prefix-instrs", "HasPrefixInstrs",
def FeaturePCRelativeMemops :
SubtargetFeature<"pcrelative-memops", "HasPCRelativeMemops", "true",
"Enable PC relative Memory Ops",
- [FeatureISA3_0, FeaturePrefixInstrs]>;
-def FeaturePairedVectorMemops:
- SubtargetFeature<"paired-vector-memops", "PairedVectorMemops", "true",
- "32Byte load and store instructions",
+ [FeatureISA3_0, FeaturePrefixInstrs]>;
+def FeaturePairedVectorMemops:
+ SubtargetFeature<"paired-vector-memops", "PairedVectorMemops", "true",
+ "32Byte load and store instructions",
[FeatureISA3_0]>;
-def FeatureMMA : SubtargetFeature<"mma", "HasMMA", "true",
- "Enable MMA instructions",
- [FeatureP8Vector, FeatureP9Altivec,
- FeaturePairedVectorMemops]>;
+def FeatureMMA : SubtargetFeature<"mma", "HasMMA", "true",
+ "Enable MMA instructions",
+ [FeatureP8Vector, FeatureP9Altivec,
+ FeaturePairedVectorMemops]>;
def FeaturePredictableSelectIsExpensive :
SubtargetFeature<"predictable-select-expensive",
@@ -335,8 +335,8 @@ def ProcessorFeatures {
[DirectivePwr9,
FeatureP9Altivec,
FeatureP9Vector,
- FeaturePPCPreRASched,
- FeaturePPCPostRASched,
+ FeaturePPCPreRASched,
+ FeaturePPCPostRASched,
FeatureISA3_0,
FeaturePredictableSelectIsExpensive
];
@@ -346,7 +346,7 @@ def ProcessorFeatures {
// dispatch for vector operations than scalar ones. For the time being,
// this list also includes scheduling-related features since we do not have
// enough info to create custom scheduling strategies for future CPUs.
- list<SubtargetFeature> P9SpecificFeatures = [FeatureVectorsUseTwoUnits];
+ list<SubtargetFeature> P9SpecificFeatures = [FeatureVectorsUseTwoUnits];
list<SubtargetFeature> P9InheritableFeatures =
!listconcat(P8InheritableFeatures, P9AdditionalFeatures);
list<SubtargetFeature> P9Features =
@@ -355,12 +355,12 @@ def ProcessorFeatures {
// Power10
// For P10 CPU we assume that all of the existing features from Power9
// still exist with the exception of those we know are Power9 specific.
- list<SubtargetFeature> FusionFeatures = [FeatureStoreFusion];
+ list<SubtargetFeature> FusionFeatures = [FeatureStoreFusion];
list<SubtargetFeature> P10AdditionalFeatures =
- !listconcat(FusionFeatures, [
- DirectivePwr10, FeatureISA3_1, FeaturePrefixInstrs,
- FeaturePCRelativeMemops, FeatureP10Vector, FeatureMMA,
- FeaturePairedVectorMemops]);
+ !listconcat(FusionFeatures, [
+ DirectivePwr10, FeatureISA3_1, FeaturePrefixInstrs,
+ FeaturePCRelativeMemops, FeatureP10Vector, FeatureMMA,
+ FeaturePairedVectorMemops]);
list<SubtargetFeature> P10SpecificFeatures = [];
list<SubtargetFeature> P10InheritableFeatures =
!listconcat(P9InheritableFeatures, P10AdditionalFeatures);
@@ -445,7 +445,7 @@ def getAltVSXFMAOpcode : InstrMapping {
include "PPCRegisterInfo.td"
include "PPCSchedule.td"
-include "GISel/PPCRegisterBanks.td"
+include "GISel/PPCRegisterBanks.td"
//===----------------------------------------------------------------------===//
// PowerPC processors supported.
@@ -571,7 +571,7 @@ def : ProcessorModel<"pwr7", P7Model, ProcessorFeatures.P7Features>;
def : ProcessorModel<"pwr8", P8Model, ProcessorFeatures.P8Features>;
def : ProcessorModel<"pwr9", P9Model, ProcessorFeatures.P9Features>;
// No scheduler model yet.
-def : ProcessorModel<"pwr10", P9Model, ProcessorFeatures.P10Features>;
+def : ProcessorModel<"pwr10", P9Model, ProcessorFeatures.P10Features>;
// No scheduler model for future CPU.
def : ProcessorModel<"future", NoSchedModel,
ProcessorFeatures.FutureFeatures>;
@@ -602,13 +602,13 @@ def PPCInstrInfo : InstrInfo {
let noNamedPositionallyEncodedOperands = 1;
}
-def PPCAsmWriter : AsmWriter {
- string AsmWriterClassName = "InstPrinter";
- int PassSubtarget = 1;
- int Variant = 0;
- bit isMCAsmWriter = 1;
-}
-
+def PPCAsmWriter : AsmWriter {
+ string AsmWriterClassName = "InstPrinter";
+ int PassSubtarget = 1;
+ int Variant = 0;
+ bit isMCAsmWriter = 1;
+}
+
def PPCAsmParser : AsmParser {
let ShouldEmitMatchRegisterName = 0;
}
@@ -627,7 +627,7 @@ def PPC : Target {
// Information about the instructions.
let InstructionSet = PPCInstrInfo;
- let AssemblyWriters = [PPCAsmWriter];
+ let AssemblyWriters = [PPCAsmWriter];
let AssemblyParsers = [PPCAsmParser];
let AssemblyParserVariants = [PPCAsmParserVariant];
let AllowRegisterRenaming = 1;
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCAsmPrinter.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCAsmPrinter.cpp
index f6e59a2718..6257709731 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -27,7 +27,7 @@
#include "PPCTargetStreamer.h"
#include "TargetInfo/PowerPCTargetInfo.h"
#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
@@ -47,7 +47,7 @@
#include "llvm/IR/Module.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstBuilder.h"
@@ -62,11 +62,11 @@
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Process.h"
+#include "llvm/Support/Process.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Transforms/Utils/ModuleUtils.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
@@ -74,7 +74,7 @@
#include <new>
using namespace llvm;
-using namespace llvm::XCOFF;
+using namespace llvm::XCOFF;
#define DEBUG_TYPE "asmprinter"
@@ -150,22 +150,22 @@ public:
class PPCAIXAsmPrinter : public PPCAsmPrinter {
private:
- /// Symbols lowered from ExternalSymbolSDNodes, we will need to emit extern
- /// linkage for them in AIX.
- SmallPtrSet<MCSymbol *, 8> ExtSymSDNodeSymbols;
-
- /// A format indicator and unique trailing identifier to form part of the
- /// sinit/sterm function names.
- std::string FormatIndicatorAndUniqueModId;
-
+ /// Symbols lowered from ExternalSymbolSDNodes, we will need to emit extern
+ /// linkage for them in AIX.
+ SmallPtrSet<MCSymbol *, 8> ExtSymSDNodeSymbols;
+
+ /// A format indicator and unique trailing identifier to form part of the
+ /// sinit/sterm function names.
+ std::string FormatIndicatorAndUniqueModId;
+
static void ValidateGV(const GlobalVariable *GV);
- // Record a list of GlobalAlias associated with a GlobalObject.
- // This is used for AIX's extra-label-at-definition aliasing strategy.
- DenseMap<const GlobalObject *, SmallVector<const GlobalAlias *, 1>>
- GOAliasMap;
+ // Record a list of GlobalAlias associated with a GlobalObject.
+ // This is used for AIX's extra-label-at-definition aliasing strategy.
+ DenseMap<const GlobalObject *, SmallVector<const GlobalAlias *, 1>>
+ GOAliasMap;
+
+ void emitTracebackTable();
- void emitTracebackTable();
-
public:
PPCAIXAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
: PPCAsmPrinter(TM, std::move(Streamer)) {
@@ -178,28 +178,28 @@ public:
bool doInitialization(Module &M) override;
- void emitXXStructorList(const DataLayout &DL, const Constant *List,
- bool IsCtor) override;
-
+ void emitXXStructorList(const DataLayout &DL, const Constant *List,
+ bool IsCtor) override;
+
void SetupMachineFunction(MachineFunction &MF) override;
void emitGlobalVariable(const GlobalVariable *GV) override;
void emitFunctionDescriptor() override;
- void emitFunctionEntryLabel() override;
-
- void emitFunctionBodyEnd() override;
-
+ void emitFunctionEntryLabel() override;
+
+ void emitFunctionBodyEnd() override;
+
void emitEndOfAsmFile(Module &) override;
void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const override;
-
- void emitInstruction(const MachineInstr *MI) override;
-
- bool doFinalization(Module &M) override;
-
- void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override;
+
+ void emitInstruction(const MachineInstr *MI) override;
+
+ bool doFinalization(Module &M) override;
+
+ void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override;
};
} // end anonymous namespace
@@ -321,12 +321,12 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
O << "0, ";
printOperand(MI, OpNo, O);
return false;
- case 'I':
- // Write 'i' if an integer constant, otherwise nothing. Used to print
- // addi vs add, etc.
- if (MI->getOperand(OpNo).isImm())
- O << "i";
- return false;
+ case 'I':
+ // Write 'i' if an integer constant, otherwise nothing. Used to print
+ // addi vs add, etc.
+ if (MI->getOperand(OpNo).isImm())
+ O << "i";
+ return false;
case 'U': // Print 'u' for update form.
case 'X': // Print 'x' for indexed form.
// FIXME: Currently for PowerPC memory operands are always loaded
@@ -499,14 +499,14 @@ void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI,
StringRef Name = "__tls_get_addr";
MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(Name);
MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
- unsigned Opcode = PPC::BL8_NOP_TLS;
-
- assert(MI->getNumOperands() >= 3 && "Expecting at least 3 operands from MI");
- if (MI->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSGD_PCREL_FLAG ||
- MI->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSLD_PCREL_FLAG) {
- Kind = MCSymbolRefExpr::VK_PPC_NOTOC;
- Opcode = PPC::BL8_NOTOC_TLS;
- }
+ unsigned Opcode = PPC::BL8_NOP_TLS;
+
+ assert(MI->getNumOperands() >= 3 && "Expecting at least 3 operands from MI");
+ if (MI->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSGD_PCREL_FLAG ||
+ MI->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSLD_PCREL_FLAG) {
+ Kind = MCSymbolRefExpr::VK_PPC_NOTOC;
+ Opcode = PPC::BL8_NOTOC_TLS;
+ }
const Module *M = MF->getFunction().getParent();
assert(MI->getOperand(0).isReg() &&
@@ -534,10 +534,10 @@ void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI,
MCSymbol *MOSymbol = getSymbol(GValue);
const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, VK, OutContext);
EmitToStreamer(*OutStreamer,
- MCInstBuilder(Subtarget->isPPC64() ? Opcode
- : (unsigned)PPC::BL_TLS)
- .addExpr(TlsRef)
- .addExpr(SymVar));
+ MCInstBuilder(Subtarget->isPPC64() ? Opcode
+ : (unsigned)PPC::BL_TLS)
+ .addExpr(TlsRef)
+ .addExpr(SymVar));
}
/// Map a machine operand for a TOC pseudo-machine instruction to its
@@ -591,38 +591,38 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
}
}
#endif
-
- auto getTOCRelocAdjustedExprForXCOFF = [this](const MCExpr *Expr,
- ptrdiff_t OriginalOffset) {
- // Apply an offset to the TOC-based expression such that the adjusted
- // notional offset from the TOC base (to be encoded into the instruction's D
- // or DS field) is the signed 16-bit truncation of the original notional
- // offset from the TOC base.
- // This is consistent with the treatment used both by XL C/C++ and
- // by AIX ld -r.
- ptrdiff_t Adjustment =
- OriginalOffset - llvm::SignExtend32<16>(OriginalOffset);
- return MCBinaryExpr::createAdd(
- Expr, MCConstantExpr::create(-Adjustment, OutContext), OutContext);
- };
-
- auto getTOCEntryLoadingExprForXCOFF =
- [IsPPC64, getTOCRelocAdjustedExprForXCOFF,
- this](const MCSymbol *MOSymbol, const MCExpr *Expr) -> const MCExpr * {
- const unsigned EntryByteSize = IsPPC64 ? 8 : 4;
- const auto TOCEntryIter = TOC.find(MOSymbol);
- assert(TOCEntryIter != TOC.end() &&
- "Could not find the TOC entry for this symbol.");
- const ptrdiff_t EntryDistanceFromTOCBase =
- (TOCEntryIter - TOC.begin()) * EntryByteSize;
- constexpr int16_t PositiveTOCRange = INT16_MAX;
-
- if (EntryDistanceFromTOCBase > PositiveTOCRange)
- return getTOCRelocAdjustedExprForXCOFF(Expr, EntryDistanceFromTOCBase);
-
- return Expr;
- };
-
+
+ auto getTOCRelocAdjustedExprForXCOFF = [this](const MCExpr *Expr,
+ ptrdiff_t OriginalOffset) {
+ // Apply an offset to the TOC-based expression such that the adjusted
+ // notional offset from the TOC base (to be encoded into the instruction's D
+ // or DS field) is the signed 16-bit truncation of the original notional
+ // offset from the TOC base.
+ // This is consistent with the treatment used both by XL C/C++ and
+ // by AIX ld -r.
+ ptrdiff_t Adjustment =
+ OriginalOffset - llvm::SignExtend32<16>(OriginalOffset);
+ return MCBinaryExpr::createAdd(
+ Expr, MCConstantExpr::create(-Adjustment, OutContext), OutContext);
+ };
+
+ auto getTOCEntryLoadingExprForXCOFF =
+ [IsPPC64, getTOCRelocAdjustedExprForXCOFF,
+ this](const MCSymbol *MOSymbol, const MCExpr *Expr) -> const MCExpr * {
+ const unsigned EntryByteSize = IsPPC64 ? 8 : 4;
+ const auto TOCEntryIter = TOC.find(MOSymbol);
+ assert(TOCEntryIter != TOC.end() &&
+ "Could not find the TOC entry for this symbol.");
+ const ptrdiff_t EntryDistanceFromTOCBase =
+ (TOCEntryIter - TOC.begin()) * EntryByteSize;
+ constexpr int16_t PositiveTOCRange = INT16_MAX;
+
+ if (EntryDistanceFromTOCBase > PositiveTOCRange)
+ return getTOCRelocAdjustedExprForXCOFF(Expr, EntryDistanceFromTOCBase);
+
+ return Expr;
+ };
+
// Lower multi-instruction pseudo operations.
switch (MI->getOpcode()) {
default: break;
@@ -769,7 +769,7 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
assert(
TM.getCodeModel() == CodeModel::Small &&
"This pseudo should only be selected for 32-bit small code model.");
- Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp);
+ Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp);
TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
EmitToStreamer(*OutStreamer, TmpInst);
return;
@@ -798,20 +798,20 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
"Invalid operand!");
- // Map the operand to its corresponding MCSymbol.
- const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
-
+ // Map the operand to its corresponding MCSymbol.
+ const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
+
// Map the machine operand to its corresponding MCSymbol, then map the
// global address operand to be a reference to the TOC entry we will
// synthesize later.
- MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
+ MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
const MCSymbolRefExpr::VariantKind VK =
IsAIX ? MCSymbolRefExpr::VK_None : MCSymbolRefExpr::VK_PPC_TOC;
const MCExpr *Exp =
MCSymbolRefExpr::create(TOCEntry, VK, OutContext);
- TmpInst.getOperand(1) = MCOperand::createExpr(
- IsAIX ? getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp) : Exp);
+ TmpInst.getOperand(1) = MCOperand::createExpr(
+ IsAIX ? getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp) : Exp);
EmitToStreamer(*OutStreamer, TmpInst);
return;
}
@@ -1087,7 +1087,7 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
case PPC::GETtlsADDR:
// Transform: %x3 = GETtlsADDR %x3, @sym
// Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd)
- case PPC::GETtlsADDRPCREL:
+ case PPC::GETtlsADDRPCREL:
case PPC::GETtlsADDR32: {
// Transform: %r3 = GETtlsADDR32 %r3, @sym
// Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT
@@ -1133,7 +1133,7 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
case PPC::GETtlsldADDR:
// Transform: %x3 = GETtlsldADDR %x3, @sym
// Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld)
- case PPC::GETtlsldADDRPCREL:
+ case PPC::GETtlsldADDRPCREL:
case PPC::GETtlsldADDR32: {
// Transform: %r3 = GETtlsldADDR32 %r3, @sym
// Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT
@@ -1160,21 +1160,21 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
.addExpr(SymDtprel));
return;
}
- case PPC::PADDIdtprel: {
- // Transform: %rd = PADDIdtprel %rs, @sym
- // Into: %rd = PADDI8 %rs, sym@dtprel
- const MachineOperand &MO = MI->getOperand(2);
- const GlobalValue *GValue = MO.getGlobal();
- MCSymbol *MOSymbol = getSymbol(GValue);
- const MCExpr *SymDtprel = MCSymbolRefExpr::create(
- MOSymbol, MCSymbolRefExpr::VK_DTPREL, OutContext);
- EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::PADDI8)
- .addReg(MI->getOperand(0).getReg())
- .addReg(MI->getOperand(1).getReg())
- .addExpr(SymDtprel));
- return;
- }
-
+ case PPC::PADDIdtprel: {
+ // Transform: %rd = PADDIdtprel %rs, @sym
+ // Into: %rd = PADDI8 %rs, sym@dtprel
+ const MachineOperand &MO = MI->getOperand(2);
+ const GlobalValue *GValue = MO.getGlobal();
+ MCSymbol *MOSymbol = getSymbol(GValue);
+ const MCExpr *SymDtprel = MCSymbolRefExpr::create(
+ MOSymbol, MCSymbolRefExpr::VK_DTPREL, OutContext);
+ EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::PADDI8)
+ .addReg(MI->getOperand(0).getReg())
+ .addReg(MI->getOperand(1).getReg())
+ .addExpr(SymDtprel));
+ return;
+ }
+
case PPC::ADDIdtprelL:
// Transform: %xd = ADDIdtprelL %xs, @sym
// Into: %xd = ADDI8 %xs, sym@dtprel@l
@@ -1711,19 +1711,19 @@ void PPCAIXAsmPrinter::emitLinkage(const GlobalValue *GV,
assert(LinkageAttr != MCSA_Invalid && "LinkageAttr should not MCSA_Invalid.");
MCSymbolAttr VisibilityAttr = MCSA_Invalid;
- if (!TM.getIgnoreXCOFFVisibility()) {
- switch (GV->getVisibility()) {
+ if (!TM.getIgnoreXCOFFVisibility()) {
+ switch (GV->getVisibility()) {
- // TODO: "exported" and "internal" Visibility needs to go here.
- case GlobalValue::DefaultVisibility:
- break;
- case GlobalValue::HiddenVisibility:
- VisibilityAttr = MAI->getHiddenVisibilityAttr();
- break;
- case GlobalValue::ProtectedVisibility:
- VisibilityAttr = MAI->getProtectedVisibilityAttr();
- break;
- }
+ // TODO: "exported" and "internal" Visibility needs to go here.
+ case GlobalValue::DefaultVisibility:
+ break;
+ case GlobalValue::HiddenVisibility:
+ VisibilityAttr = MAI->getHiddenVisibilityAttr();
+ break;
+ case GlobalValue::ProtectedVisibility:
+ VisibilityAttr = MAI->getProtectedVisibilityAttr();
+ break;
+ }
}
OutStreamer->emitXCOFFSymbolLinkageWithVisibility(GVSym, LinkageAttr,
@@ -1742,284 +1742,284 @@ void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction &MF) {
return AsmPrinter::SetupMachineFunction(MF);
}
-void PPCAIXAsmPrinter::emitFunctionBodyEnd() {
-
- if (!TM.getXCOFFTracebackTable())
- return;
-
- emitTracebackTable();
-}
-
-void PPCAIXAsmPrinter::emitTracebackTable() {
-
- // Create a symbol for the end of function.
- MCSymbol *FuncEnd = createTempSymbol(MF->getName());
- OutStreamer->emitLabel(FuncEnd);
-
- OutStreamer->AddComment("Traceback table begin");
- // Begin with a fullword of zero.
- OutStreamer->emitIntValueInHexWithPadding(0, 4 /*size*/);
-
- SmallString<128> CommentString;
- raw_svector_ostream CommentOS(CommentString);
-
- auto EmitComment = [&]() {
- OutStreamer->AddComment(CommentOS.str());
- CommentString.clear();
- };
-
- auto EmitCommentAndValue = [&](uint64_t Value, int Size) {
- EmitComment();
- OutStreamer->emitIntValueInHexWithPadding(Value, Size);
- };
-
- unsigned int Version = 0;
- CommentOS << "Version = " << Version;
- EmitCommentAndValue(Version, 1);
-
- // There is a lack of information in the IR to assist with determining the
- // source language. AIX exception handling mechanism would only search for
- // personality routine and LSDA area when such language supports exception
- // handling. So to be conservatively correct and allow runtime to do its job,
- // we need to set it to C++ for now.
- TracebackTable::LanguageID LanguageIdentifier =
- TracebackTable::CPlusPlus; // C++
-
- CommentOS << "Language = "
- << getNameForTracebackTableLanguageId(LanguageIdentifier);
- EmitCommentAndValue(LanguageIdentifier, 1);
-
- // This is only populated for the third and fourth bytes.
- uint32_t FirstHalfOfMandatoryField = 0;
-
- // Emit the 3rd byte of the mandatory field.
-
- // We always set traceback offset bit to true.
- FirstHalfOfMandatoryField |= TracebackTable::HasTraceBackTableOffsetMask;
-
- const PPCFunctionInfo *FI = MF->getInfo<PPCFunctionInfo>();
- const MachineRegisterInfo &MRI = MF->getRegInfo();
-
- // Check the function uses floating-point processor instructions or not
- for (unsigned Reg = PPC::F0; Reg <= PPC::F31; ++Reg) {
- if (MRI.isPhysRegUsed(Reg)) {
- FirstHalfOfMandatoryField |= TracebackTable::IsFloatingPointPresentMask;
- break;
- }
- }
-
-#define GENBOOLCOMMENT(Prefix, V, Field) \
- CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \
- << #Field
-
-#define GENVALUECOMMENT(PrefixAndName, V, Field) \
- CommentOS << (PrefixAndName) << " = " \
- << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >> \
- (TracebackTable::Field##Shift))
-
- GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsGlobaLinkage);
- GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsOutOfLineEpilogOrPrologue);
- EmitComment();
-
- GENBOOLCOMMENT("", FirstHalfOfMandatoryField, HasTraceBackTableOffset);
- GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsInternalProcedure);
- EmitComment();
-
- GENBOOLCOMMENT("", FirstHalfOfMandatoryField, HasControlledStorage);
- GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsTOCless);
- EmitComment();
-
- GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsFloatingPointPresent);
- EmitComment();
- GENBOOLCOMMENT("", FirstHalfOfMandatoryField,
- IsFloatingPointOperationLogOrAbortEnabled);
- EmitComment();
-
- OutStreamer->emitIntValueInHexWithPadding(
- (FirstHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
-
- // Set the 4th byte of the mandatory field.
- FirstHalfOfMandatoryField |= TracebackTable::IsFunctionNamePresentMask;
-
- static_assert(XCOFF::AllocRegNo == 31, "Unexpected register usage!");
- if (MRI.isPhysRegUsed(Subtarget->isPPC64() ? PPC::X31 : PPC::R31))
- FirstHalfOfMandatoryField |= TracebackTable::IsAllocaUsedMask;
-
- const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs();
- if (!MustSaveCRs.empty())
- FirstHalfOfMandatoryField |= TracebackTable::IsCRSavedMask;
-
- if (FI->mustSaveLR())
- FirstHalfOfMandatoryField |= TracebackTable::IsLRSavedMask;
-
- GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsInterruptHandler);
- GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsFunctionNamePresent);
- GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsAllocaUsed);
- EmitComment();
- GENVALUECOMMENT("OnConditionDirective", FirstHalfOfMandatoryField,
- OnConditionDirective);
- GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsCRSaved);
- GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsLRSaved);
- EmitComment();
- OutStreamer->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField & 0xff),
- 1);
-
- // Set the 5th byte of mandatory field.
- uint32_t SecondHalfOfMandatoryField = 0;
-
- // Always store back chain.
- SecondHalfOfMandatoryField |= TracebackTable::IsBackChainStoredMask;
-
- uint32_t FPRSaved = 0;
- for (unsigned Reg = PPC::F14; Reg <= PPC::F31; ++Reg) {
- if (MRI.isPhysRegModified(Reg)) {
- FPRSaved = PPC::F31 - Reg + 1;
- break;
- }
- }
- SecondHalfOfMandatoryField |= (FPRSaved << TracebackTable::FPRSavedShift) &
- TracebackTable::FPRSavedMask;
- GENBOOLCOMMENT("", SecondHalfOfMandatoryField, IsBackChainStored);
- GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, IsFixup);
- GENVALUECOMMENT(", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved);
- EmitComment();
- OutStreamer->emitIntValueInHexWithPadding(
- (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);
-
- // Set the 6th byte of mandatory field.
- bool ShouldEmitEHBlock = TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF);
- if (ShouldEmitEHBlock)
- SecondHalfOfMandatoryField |= TracebackTable::HasExtensionTableMask;
-
- uint32_t GPRSaved = 0;
-
- // X13 is reserved under 64-bit environment.
- unsigned GPRBegin = Subtarget->isPPC64() ? PPC::X14 : PPC::R13;
- unsigned GPREnd = Subtarget->isPPC64() ? PPC::X31 : PPC::R31;
-
- for (unsigned Reg = GPRBegin; Reg <= GPREnd; ++Reg) {
- if (MRI.isPhysRegModified(Reg)) {
- GPRSaved = GPREnd - Reg + 1;
- break;
- }
- }
-
- SecondHalfOfMandatoryField |= (GPRSaved << TracebackTable::GPRSavedShift) &
- TracebackTable::GPRSavedMask;
-
- GENBOOLCOMMENT("", SecondHalfOfMandatoryField, HasVectorInfo);
- GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, HasExtensionTable);
- GENVALUECOMMENT(", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved);
- EmitComment();
- OutStreamer->emitIntValueInHexWithPadding(
- (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);
-
- // Set the 7th byte of mandatory field.
- uint32_t NumberOfFixedPara = FI->getFixedParamNum();
- SecondHalfOfMandatoryField |=
- (NumberOfFixedPara << TracebackTable::NumberOfFixedParmsShift) &
- TracebackTable::NumberOfFixedParmsMask;
- GENVALUECOMMENT("NumberOfFixedParms", SecondHalfOfMandatoryField,
- NumberOfFixedParms);
- EmitComment();
- OutStreamer->emitIntValueInHexWithPadding(
- (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
-
- // Set the 8th byte of mandatory field.
-
- // Always set parameter on stack.
- SecondHalfOfMandatoryField |= TracebackTable::HasParmsOnStackMask;
-
- uint32_t NumberOfFPPara = FI->getFloatingPointParamNum();
- SecondHalfOfMandatoryField |=
- (NumberOfFPPara << TracebackTable::NumberOfFloatingPointParmsShift) &
- TracebackTable::NumberOfFloatingPointParmsMask;
-
- GENVALUECOMMENT("NumberOfFPParms", SecondHalfOfMandatoryField,
- NumberOfFloatingPointParms);
- GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, HasParmsOnStack);
- EmitComment();
- OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff,
- 1);
-
- // Generate the optional fields of traceback table.
-
- // Parameter type.
- if (NumberOfFixedPara || NumberOfFPPara) {
- assert((SecondHalfOfMandatoryField & TracebackTable::HasVectorInfoMask) ==
- 0 &&
- "VectorInfo has not been implemented.");
- uint32_t ParaType = FI->getParameterType();
- CommentOS << "Parameter type = "
- << XCOFF::parseParmsType(ParaType,
- NumberOfFixedPara + NumberOfFPPara);
- EmitComment();
- OutStreamer->emitIntValueInHexWithPadding(ParaType, sizeof(ParaType));
- }
-
- // Traceback table offset.
- OutStreamer->AddComment("Function size");
- if (FirstHalfOfMandatoryField & TracebackTable::HasTraceBackTableOffsetMask) {
- MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol(
- &(MF->getFunction()), TM);
- OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4);
- }
-
- // Since we unset the Int_Handler.
- if (FirstHalfOfMandatoryField & TracebackTable::IsInterruptHandlerMask)
- report_fatal_error("Hand_Mask not implement yet");
-
- if (FirstHalfOfMandatoryField & TracebackTable::HasControlledStorageMask)
- report_fatal_error("Ctl_Info not implement yet");
-
- if (FirstHalfOfMandatoryField & TracebackTable::IsFunctionNamePresentMask) {
- StringRef Name = MF->getName().substr(0, INT16_MAX);
- int16_t NameLength = Name.size();
- CommentOS << "Function name len = "
- << static_cast<unsigned int>(NameLength);
- EmitCommentAndValue(NameLength, 2);
- OutStreamer->AddComment("Function Name");
- OutStreamer->emitBytes(Name);
- }
-
- if (FirstHalfOfMandatoryField & TracebackTable::IsAllocaUsedMask) {
- uint8_t AllocReg = XCOFF::AllocRegNo;
- OutStreamer->AddComment("AllocaUsed");
- OutStreamer->emitIntValueInHex(AllocReg, sizeof(AllocReg));
- }
-
- uint8_t ExtensionTableFlag = 0;
- if (SecondHalfOfMandatoryField & TracebackTable::HasExtensionTableMask) {
- if (ShouldEmitEHBlock)
- ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO;
-
- CommentOS << "ExtensionTableFlag = "
- << getExtendedTBTableFlagString(ExtensionTableFlag);
- EmitCommentAndValue(ExtensionTableFlag, sizeof(ExtensionTableFlag));
- }
-
- if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) {
- auto &Ctx = OutStreamer->getContext();
- MCSymbol *EHInfoSym =
- TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(MF);
- MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym);
- const MCSymbol *TOCBaseSym =
- cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
- ->getQualNameSymbol();
- const MCExpr *Exp =
- MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCEntry, Ctx),
- MCSymbolRefExpr::create(TOCBaseSym, Ctx), Ctx);
-
- const DataLayout &DL = getDataLayout();
- OutStreamer->emitValueToAlignment(4);
- OutStreamer->AddComment("EHInfo Table");
- OutStreamer->emitValue(Exp, DL.getPointerSize());
- }
-
-#undef GENBOOLCOMMENT
-#undef GENVALUECOMMENT
-}
-
+void PPCAIXAsmPrinter::emitFunctionBodyEnd() {
+
+ if (!TM.getXCOFFTracebackTable())
+ return;
+
+ emitTracebackTable();
+}
+
+void PPCAIXAsmPrinter::emitTracebackTable() {
+
+ // Create a symbol for the end of function.
+ MCSymbol *FuncEnd = createTempSymbol(MF->getName());
+ OutStreamer->emitLabel(FuncEnd);
+
+ OutStreamer->AddComment("Traceback table begin");
+ // Begin with a fullword of zero.
+ OutStreamer->emitIntValueInHexWithPadding(0, 4 /*size*/);
+
+ SmallString<128> CommentString;
+ raw_svector_ostream CommentOS(CommentString);
+
+ auto EmitComment = [&]() {
+ OutStreamer->AddComment(CommentOS.str());
+ CommentString.clear();
+ };
+
+ auto EmitCommentAndValue = [&](uint64_t Value, int Size) {
+ EmitComment();
+ OutStreamer->emitIntValueInHexWithPadding(Value, Size);
+ };
+
+ unsigned int Version = 0;
+ CommentOS << "Version = " << Version;
+ EmitCommentAndValue(Version, 1);
+
+ // There is a lack of information in the IR to assist with determining the
+ // source language. AIX exception handling mechanism would only search for
+ // personality routine and LSDA area when such language supports exception
+ // handling. So to be conservatively correct and allow runtime to do its job,
+ // we need to set it to C++ for now.
+ TracebackTable::LanguageID LanguageIdentifier =
+ TracebackTable::CPlusPlus; // C++
+
+ CommentOS << "Language = "
+ << getNameForTracebackTableLanguageId(LanguageIdentifier);
+ EmitCommentAndValue(LanguageIdentifier, 1);
+
+ // This is only populated for the third and fourth bytes.
+ uint32_t FirstHalfOfMandatoryField = 0;
+
+ // Emit the 3rd byte of the mandatory field.
+
+ // We always set traceback offset bit to true.
+ FirstHalfOfMandatoryField |= TracebackTable::HasTraceBackTableOffsetMask;
+
+ const PPCFunctionInfo *FI = MF->getInfo<PPCFunctionInfo>();
+ const MachineRegisterInfo &MRI = MF->getRegInfo();
+
+ // Check the function uses floating-point processor instructions or not
+ for (unsigned Reg = PPC::F0; Reg <= PPC::F31; ++Reg) {
+ if (MRI.isPhysRegUsed(Reg)) {
+ FirstHalfOfMandatoryField |= TracebackTable::IsFloatingPointPresentMask;
+ break;
+ }
+ }
+
+#define GENBOOLCOMMENT(Prefix, V, Field) \
+ CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \
+ << #Field
+
+#define GENVALUECOMMENT(PrefixAndName, V, Field) \
+ CommentOS << (PrefixAndName) << " = " \
+ << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >> \
+ (TracebackTable::Field##Shift))
+
+ GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsGlobaLinkage);
+ GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsOutOfLineEpilogOrPrologue);
+ EmitComment();
+
+ GENBOOLCOMMENT("", FirstHalfOfMandatoryField, HasTraceBackTableOffset);
+ GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsInternalProcedure);
+ EmitComment();
+
+ GENBOOLCOMMENT("", FirstHalfOfMandatoryField, HasControlledStorage);
+ GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsTOCless);
+ EmitComment();
+
+ GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsFloatingPointPresent);
+ EmitComment();
+ GENBOOLCOMMENT("", FirstHalfOfMandatoryField,
+ IsFloatingPointOperationLogOrAbortEnabled);
+ EmitComment();
+
+ OutStreamer->emitIntValueInHexWithPadding(
+ (FirstHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
+
+ // Set the 4th byte of the mandatory field.
+ FirstHalfOfMandatoryField |= TracebackTable::IsFunctionNamePresentMask;
+
+ static_assert(XCOFF::AllocRegNo == 31, "Unexpected register usage!");
+ if (MRI.isPhysRegUsed(Subtarget->isPPC64() ? PPC::X31 : PPC::R31))
+ FirstHalfOfMandatoryField |= TracebackTable::IsAllocaUsedMask;
+
+ const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs();
+ if (!MustSaveCRs.empty())
+ FirstHalfOfMandatoryField |= TracebackTable::IsCRSavedMask;
+
+ if (FI->mustSaveLR())
+ FirstHalfOfMandatoryField |= TracebackTable::IsLRSavedMask;
+
+ GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsInterruptHandler);
+ GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsFunctionNamePresent);
+ GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsAllocaUsed);
+ EmitComment();
+ GENVALUECOMMENT("OnConditionDirective", FirstHalfOfMandatoryField,
+ OnConditionDirective);
+ GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsCRSaved);
+ GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsLRSaved);
+ EmitComment();
+ OutStreamer->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField & 0xff),
+ 1);
+
+ // Set the 5th byte of mandatory field.
+ uint32_t SecondHalfOfMandatoryField = 0;
+
+ // Always store back chain.
+ SecondHalfOfMandatoryField |= TracebackTable::IsBackChainStoredMask;
+
+ uint32_t FPRSaved = 0;
+ for (unsigned Reg = PPC::F14; Reg <= PPC::F31; ++Reg) {
+ if (MRI.isPhysRegModified(Reg)) {
+ FPRSaved = PPC::F31 - Reg + 1;
+ break;
+ }
+ }
+ SecondHalfOfMandatoryField |= (FPRSaved << TracebackTable::FPRSavedShift) &
+ TracebackTable::FPRSavedMask;
+ GENBOOLCOMMENT("", SecondHalfOfMandatoryField, IsBackChainStored);
+ GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, IsFixup);
+ GENVALUECOMMENT(", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved);
+ EmitComment();
+ OutStreamer->emitIntValueInHexWithPadding(
+ (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);
+
+ // Set the 6th byte of mandatory field.
+ bool ShouldEmitEHBlock = TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF);
+ if (ShouldEmitEHBlock)
+ SecondHalfOfMandatoryField |= TracebackTable::HasExtensionTableMask;
+
+ uint32_t GPRSaved = 0;
+
+ // X13 is reserved under 64-bit environment.
+ unsigned GPRBegin = Subtarget->isPPC64() ? PPC::X14 : PPC::R13;
+ unsigned GPREnd = Subtarget->isPPC64() ? PPC::X31 : PPC::R31;
+
+ for (unsigned Reg = GPRBegin; Reg <= GPREnd; ++Reg) {
+ if (MRI.isPhysRegModified(Reg)) {
+ GPRSaved = GPREnd - Reg + 1;
+ break;
+ }
+ }
+
+ SecondHalfOfMandatoryField |= (GPRSaved << TracebackTable::GPRSavedShift) &
+ TracebackTable::GPRSavedMask;
+
+ GENBOOLCOMMENT("", SecondHalfOfMandatoryField, HasVectorInfo);
+ GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, HasExtensionTable);
+ GENVALUECOMMENT(", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved);
+ EmitComment();
+ OutStreamer->emitIntValueInHexWithPadding(
+ (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);
+
+ // Set the 7th byte of mandatory field.
+ uint32_t NumberOfFixedPara = FI->getFixedParamNum();
+ SecondHalfOfMandatoryField |=
+ (NumberOfFixedPara << TracebackTable::NumberOfFixedParmsShift) &
+ TracebackTable::NumberOfFixedParmsMask;
+ GENVALUECOMMENT("NumberOfFixedParms", SecondHalfOfMandatoryField,
+ NumberOfFixedParms);
+ EmitComment();
+ OutStreamer->emitIntValueInHexWithPadding(
+ (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
+
+ // Set the 8th byte of mandatory field.
+
+ // Always set parameter on stack.
+ SecondHalfOfMandatoryField |= TracebackTable::HasParmsOnStackMask;
+
+ uint32_t NumberOfFPPara = FI->getFloatingPointParamNum();
+ SecondHalfOfMandatoryField |=
+ (NumberOfFPPara << TracebackTable::NumberOfFloatingPointParmsShift) &
+ TracebackTable::NumberOfFloatingPointParmsMask;
+
+ GENVALUECOMMENT("NumberOfFPParms", SecondHalfOfMandatoryField,
+ NumberOfFloatingPointParms);
+ GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, HasParmsOnStack);
+ EmitComment();
+ OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff,
+ 1);
+
+ // Generate the optional fields of traceback table.
+
+ // Parameter type.
+ if (NumberOfFixedPara || NumberOfFPPara) {
+ assert((SecondHalfOfMandatoryField & TracebackTable::HasVectorInfoMask) ==
+ 0 &&
+ "VectorInfo has not been implemented.");
+ uint32_t ParaType = FI->getParameterType();
+ CommentOS << "Parameter type = "
+ << XCOFF::parseParmsType(ParaType,
+ NumberOfFixedPara + NumberOfFPPara);
+ EmitComment();
+ OutStreamer->emitIntValueInHexWithPadding(ParaType, sizeof(ParaType));
+ }
+
+ // Traceback table offset.
+ OutStreamer->AddComment("Function size");
+ if (FirstHalfOfMandatoryField & TracebackTable::HasTraceBackTableOffsetMask) {
+ MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol(
+ &(MF->getFunction()), TM);
+ OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4);
+ }
+
+ // Since we unset the Int_Handler.
+ if (FirstHalfOfMandatoryField & TracebackTable::IsInterruptHandlerMask)
+ report_fatal_error("Hand_Mask not implement yet");
+
+ if (FirstHalfOfMandatoryField & TracebackTable::HasControlledStorageMask)
+ report_fatal_error("Ctl_Info not implement yet");
+
+ if (FirstHalfOfMandatoryField & TracebackTable::IsFunctionNamePresentMask) {
+ StringRef Name = MF->getName().substr(0, INT16_MAX);
+ int16_t NameLength = Name.size();
+ CommentOS << "Function name len = "
+ << static_cast<unsigned int>(NameLength);
+ EmitCommentAndValue(NameLength, 2);
+ OutStreamer->AddComment("Function Name");
+ OutStreamer->emitBytes(Name);
+ }
+
+ if (FirstHalfOfMandatoryField & TracebackTable::IsAllocaUsedMask) {
+ uint8_t AllocReg = XCOFF::AllocRegNo;
+ OutStreamer->AddComment("AllocaUsed");
+ OutStreamer->emitIntValueInHex(AllocReg, sizeof(AllocReg));
+ }
+
+ uint8_t ExtensionTableFlag = 0;
+ if (SecondHalfOfMandatoryField & TracebackTable::HasExtensionTableMask) {
+ if (ShouldEmitEHBlock)
+ ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO;
+
+ CommentOS << "ExtensionTableFlag = "
+ << getExtendedTBTableFlagString(ExtensionTableFlag);
+ EmitCommentAndValue(ExtensionTableFlag, sizeof(ExtensionTableFlag));
+ }
+
+ if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) {
+ auto &Ctx = OutStreamer->getContext();
+ MCSymbol *EHInfoSym =
+ TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(MF);
+ MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym);
+ const MCSymbol *TOCBaseSym =
+ cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
+ ->getQualNameSymbol();
+ const MCExpr *Exp =
+ MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCEntry, Ctx),
+ MCSymbolRefExpr::create(TOCBaseSym, Ctx), Ctx);
+
+ const DataLayout &DL = getDataLayout();
+ OutStreamer->emitValueToAlignment(4);
+ OutStreamer->AddComment("EHInfo Table");
+ OutStreamer->emitValue(Exp, DL.getPointerSize());
+ }
+
+#undef GENBOOLCOMMENT
+#undef GENVALUECOMMENT
+}
+
void PPCAIXAsmPrinter::ValidateGV(const GlobalVariable *GV) {
// Early error checking limiting what is supported.
if (GV->isThreadLocal())
@@ -2029,18 +2029,18 @@ void PPCAIXAsmPrinter::ValidateGV(const GlobalVariable *GV) {
report_fatal_error("COMDAT not yet supported by AIX.");
}
-static bool isSpecialLLVMGlobalArrayToSkip(const GlobalVariable *GV) {
- return GV->hasAppendingLinkage() &&
- StringSwitch<bool>(GV->getName())
- // TODO: Linker could still eliminate the GV if we just skip
- // handling llvm.used array. Skipping them for now until we or the
- // AIX OS team come up with a good solution.
- .Case("llvm.used", true)
- // It's correct to just skip llvm.compiler.used array here.
- .Case("llvm.compiler.used", true)
- .Default(false);
-}
-
+static bool isSpecialLLVMGlobalArrayToSkip(const GlobalVariable *GV) {
+ return GV->hasAppendingLinkage() &&
+ StringSwitch<bool>(GV->getName())
+ // TODO: Linker could still eliminate the GV if we just skip
+ // handling llvm.used array. Skipping them for now until we or the
+ // AIX OS team come up with a good solution.
+ .Case("llvm.used", true)
+ // It's correct to just skip llvm.compiler.used array here.
+ .Case("llvm.compiler.used", true)
+ .Default(false);
+}
+
static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable *GV) {
return StringSwitch<bool>(GV->getName())
.Cases("llvm.global_ctors", "llvm.global_dtors", true)
@@ -2048,12 +2048,12 @@ static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable *GV) {
}
void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
- // Special LLVM global arrays have been handled at the initialization.
- if (isSpecialLLVMGlobalArrayToSkip(GV) || isSpecialLLVMGlobalArrayForStaticInit(GV))
- return;
-
- assert(!GV->getName().startswith("llvm.") &&
- "Unhandled intrinsic global variable.");
+ // Special LLVM global arrays have been handled at the initialization.
+ if (isSpecialLLVMGlobalArrayToSkip(GV) || isSpecialLLVMGlobalArrayForStaticInit(GV))
+ return;
+
+ assert(!GV->getName().startswith("llvm.") &&
+ "Unhandled intrinsic global variable.");
ValidateGV(GV);
MCSymbolXCOFF *GVSym = cast<MCSymbolXCOFF>(getSymbol(GV));
@@ -2080,12 +2080,12 @@ void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
if (GVKind.isCommon() || GVKind.isBSSLocal()) {
Align Alignment = GV->getAlign().getValueOr(DL.getPreferredAlign(GV));
uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType());
- GVSym->setStorageClass(
- TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV));
+ GVSym->setStorageClass(
+ TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV));
if (GVKind.isBSSLocal())
OutStreamer->emitXCOFFLocalCommonSymbol(
- OutContext.getOrCreateSymbol(GVSym->getSymbolTableName()), Size,
+ OutContext.getOrCreateSymbol(GVSym->getSymbolTableName()), Size,
GVSym, Alignment.value());
else
OutStreamer->emitCommonSymbol(GVSym, Size, Alignment.value());
@@ -2095,18 +2095,18 @@ void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
MCSymbol *EmittedInitSym = GVSym;
emitLinkage(GV, EmittedInitSym);
emitAlignment(getGVAlignment(GV, DL), GV);
-
- // When -fdata-sections is enabled, every GlobalVariable will
- // be put into its own csect; therefore, label is not necessary here.
- if (!TM.getDataSections() || GV->hasSection()) {
- OutStreamer->emitLabel(EmittedInitSym);
- }
-
- // Emit aliasing label for global variable.
- llvm::for_each(GOAliasMap[GV], [this](const GlobalAlias *Alias) {
- OutStreamer->emitLabel(getSymbol(Alias));
- });
-
+
+ // When -fdata-sections is enabled, every GlobalVariable will
+ // be put into its own csect; therefore, label is not necessary here.
+ if (!TM.getDataSections() || GV->hasSection()) {
+ OutStreamer->emitLabel(EmittedInitSym);
+ }
+
+ // Emit aliasing label for global variable.
+ llvm::for_each(GOAliasMap[GV], [this](const GlobalAlias *Alias) {
+ OutStreamer->emitLabel(getSymbol(Alias));
+ });
+
emitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer());
}
@@ -2118,13 +2118,13 @@ void PPCAIXAsmPrinter::emitFunctionDescriptor() {
// Emit function descriptor.
OutStreamer->SwitchSection(
cast<MCSymbolXCOFF>(CurrentFnDescSym)->getRepresentedCsect());
-
- // Emit aliasing label for function descriptor csect.
- llvm::for_each(GOAliasMap[&MF->getFunction()],
- [this](const GlobalAlias *Alias) {
- OutStreamer->emitLabel(getSymbol(Alias));
- });
-
+
+ // Emit aliasing label for function descriptor csect.
+ llvm::for_each(GOAliasMap[&MF->getFunction()],
+ [this](const GlobalAlias *Alias) {
+ OutStreamer->emitLabel(getSymbol(Alias));
+ });
+
// Emit function entry point address.
OutStreamer->emitValue(MCSymbolRefExpr::create(CurrentFnSym, OutContext),
PointerSize);
@@ -2140,20 +2140,20 @@ void PPCAIXAsmPrinter::emitFunctionDescriptor() {
OutStreamer->SwitchSection(Current.first, Current.second);
}
-void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
- // It's not necessary to emit the label when we have individual
- // function in its own csect.
- if (!TM.getFunctionSections())
- PPCAsmPrinter::emitFunctionEntryLabel();
-
- // Emit aliasing label for function entry point label.
- llvm::for_each(
- GOAliasMap[&MF->getFunction()], [this](const GlobalAlias *Alias) {
- OutStreamer->emitLabel(
- getObjFileLowering().getFunctionEntryPointSymbol(Alias, TM));
- });
-}
-
+void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
+ // It's not necessary to emit the label when we have individual
+ // function in its own csect.
+ if (!TM.getFunctionSections())
+ PPCAsmPrinter::emitFunctionEntryLabel();
+
+ // Emit aliasing label for function entry point label.
+ llvm::for_each(
+ GOAliasMap[&MF->getFunction()], [this](const GlobalAlias *Alias) {
+ OutStreamer->emitLabel(
+ getObjFileLowering().getFunctionEntryPointSymbol(Alias, TM));
+ });
+}
+
void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {
// If there are no functions in this module, we will never need to reference
// the TOC base.
@@ -2169,7 +2169,7 @@ void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {
for (auto &I : TOC) {
// Setup the csect for the current TC entry.
MCSectionXCOFF *TCEntry = cast<MCSectionXCOFF>(
- getObjFileLowering().getSectionForTOCEntry(I.first, TM));
+ getObjFileLowering().getSectionForTOCEntry(I.first, TM));
OutStreamer->SwitchSection(TCEntry);
OutStreamer->emitLabel(I.second);
@@ -2198,174 +2198,174 @@ bool PPCAIXAsmPrinter::doInitialization(Module &M) {
// We need to know, up front, the alignment of csects for the assembly path,
// because once a .csect directive gets emitted, we could not change the
// alignment value on it.
- for (const auto &G : M.globals()) {
- if (isSpecialLLVMGlobalArrayToSkip(&G))
- continue;
-
- if (isSpecialLLVMGlobalArrayForStaticInit(&G)) {
- // Generate a format indicator and a unique module id to be a part of
- // the sinit and sterm function names.
- if (FormatIndicatorAndUniqueModId.empty()) {
- std::string UniqueModuleId = getUniqueModuleId(&M);
- if (UniqueModuleId != "")
- // TODO: Use source file full path to generate the unique module id
- // and add a format indicator as a part of function name in case we
- // will support more than one format.
- FormatIndicatorAndUniqueModId = "clang_" + UniqueModuleId.substr(1);
- else
- // Use the Pid and current time as the unique module id when we cannot
- // generate one based on a module's strong external symbols.
- // FIXME: Adjust the comment accordingly after we use source file full
- // path instead.
- FormatIndicatorAndUniqueModId =
- "clangPidTime_" + llvm::itostr(sys::Process::getProcessId()) +
- "_" + llvm::itostr(time(nullptr));
- }
-
- emitSpecialLLVMGlobal(&G);
- continue;
- }
-
+ for (const auto &G : M.globals()) {
+ if (isSpecialLLVMGlobalArrayToSkip(&G))
+ continue;
+
+ if (isSpecialLLVMGlobalArrayForStaticInit(&G)) {
+ // Generate a format indicator and a unique module id to be a part of
+ // the sinit and sterm function names.
+ if (FormatIndicatorAndUniqueModId.empty()) {
+ std::string UniqueModuleId = getUniqueModuleId(&M);
+ if (UniqueModuleId != "")
+ // TODO: Use source file full path to generate the unique module id
+ // and add a format indicator as a part of function name in case we
+ // will support more than one format.
+ FormatIndicatorAndUniqueModId = "clang_" + UniqueModuleId.substr(1);
+ else
+ // Use the Pid and current time as the unique module id when we cannot
+ // generate one based on a module's strong external symbols.
+ // FIXME: Adjust the comment accordingly after we use source file full
+ // path instead.
+ FormatIndicatorAndUniqueModId =
+ "clangPidTime_" + llvm::itostr(sys::Process::getProcessId()) +
+ "_" + llvm::itostr(time(nullptr));
+ }
+
+ emitSpecialLLVMGlobal(&G);
+ continue;
+ }
+
setCsectAlignment(&G);
- }
+ }
for (const auto &F : M)
setCsectAlignment(&F);
- // Construct an aliasing list for each GlobalObject.
- for (const auto &Alias : M.aliases()) {
- const GlobalObject *Base = Alias.getBaseObject();
- if (!Base)
- report_fatal_error(
- "alias without a base object is not yet supported on AIX");
- GOAliasMap[Base].push_back(&Alias);
- }
-
+ // Construct an aliasing list for each GlobalObject.
+ for (const auto &Alias : M.aliases()) {
+ const GlobalObject *Base = Alias.getBaseObject();
+ if (!Base)
+ report_fatal_error(
+ "alias without a base object is not yet supported on AIX");
+ GOAliasMap[Base].push_back(&Alias);
+ }
+
return Result;
}
-void PPCAIXAsmPrinter::emitInstruction(const MachineInstr *MI) {
- switch (MI->getOpcode()) {
- default:
- break;
- case PPC::BL8:
- case PPC::BL:
- case PPC::BL8_NOP:
- case PPC::BL_NOP: {
- const MachineOperand &MO = MI->getOperand(0);
- if (MO.isSymbol()) {
- MCSymbolXCOFF *S =
- cast<MCSymbolXCOFF>(OutContext.getOrCreateSymbol(MO.getSymbolName()));
- ExtSymSDNodeSymbols.insert(S);
- }
- } break;
- case PPC::BL_TLS:
- case PPC::BL8_TLS:
- case PPC::BL8_TLS_:
- case PPC::BL8_NOP_TLS:
- report_fatal_error("TLS call not yet implemented");
- case PPC::TAILB:
- case PPC::TAILB8:
- case PPC::TAILBA:
- case PPC::TAILBA8:
- case PPC::TAILBCTR:
- case PPC::TAILBCTR8:
- if (MI->getOperand(0).isSymbol())
- report_fatal_error("Tail call for extern symbol not yet supported.");
- break;
- }
- return PPCAsmPrinter::emitInstruction(MI);
-}
-
-bool PPCAIXAsmPrinter::doFinalization(Module &M) {
- for (MCSymbol *Sym : ExtSymSDNodeSymbols)
- OutStreamer->emitSymbolAttribute(Sym, MCSA_Extern);
- return PPCAsmPrinter::doFinalization(M);
-}
-
-static unsigned mapToSinitPriority(int P) {
- if (P < 0 || P > 65535)
- report_fatal_error("invalid init priority");
-
- if (P <= 20)
- return P;
-
- if (P < 81)
- return 20 + (P - 20) * 16;
-
- if (P <= 1124)
- return 1004 + (P - 81);
-
- if (P < 64512)
- return 2047 + (P - 1124) * 33878;
-
- return 2147482625u + (P - 64512);
-}
-
-static std::string convertToSinitPriority(int Priority) {
- // This helper function converts clang init priority to values used in sinit
- // and sterm functions.
- //
- // The conversion strategies are:
- // We map the reserved clang/gnu priority range [0, 100] into the sinit/sterm
- // reserved priority range [0, 1023] by
- // - directly mapping the first 21 and the last 20 elements of the ranges
- // - linear interpolating the intermediate values with a step size of 16.
- //
- // We map the non reserved clang/gnu priority range of [101, 65535] into the
- // sinit/sterm priority range [1024, 2147483648] by:
- // - directly mapping the first and the last 1024 elements of the ranges
- // - linear interpolating the intermediate values with a step size of 33878.
- unsigned int P = mapToSinitPriority(Priority);
-
- std::string PrioritySuffix;
- llvm::raw_string_ostream os(PrioritySuffix);
- os << llvm::format_hex_no_prefix(P, 8);
- os.flush();
- return PrioritySuffix;
-}
-
-void PPCAIXAsmPrinter::emitXXStructorList(const DataLayout &DL,
- const Constant *List, bool IsCtor) {
- SmallVector<Structor, 8> Structors;
- preprocessXXStructorList(DL, List, Structors);
- if (Structors.empty())
- return;
-
- unsigned Index = 0;
- for (Structor &S : Structors) {
- if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(S.Func))
- S.Func = CE->getOperand(0);
-
- llvm::GlobalAlias::create(
- GlobalValue::ExternalLinkage,
- (IsCtor ? llvm::Twine("__sinit") : llvm::Twine("__sterm")) +
- llvm::Twine(convertToSinitPriority(S.Priority)) +
- llvm::Twine("_", FormatIndicatorAndUniqueModId) +
- llvm::Twine("_", llvm::utostr(Index++)),
- cast<Function>(S.Func));
- }
-}
-
-void PPCAIXAsmPrinter::emitTTypeReference(const GlobalValue *GV,
- unsigned Encoding) {
- if (GV) {
- MCSymbol *TypeInfoSym = TM.getSymbol(GV);
- MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym);
- const MCSymbol *TOCBaseSym =
- cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
- ->getQualNameSymbol();
- auto &Ctx = OutStreamer->getContext();
- const MCExpr *Exp =
- MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCEntry, Ctx),
- MCSymbolRefExpr::create(TOCBaseSym, Ctx), Ctx);
- OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
- } else
- OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
-}
-
-// Return a pass that prints the PPC assembly code for a MachineFunction to the
-// given output stream.
+void PPCAIXAsmPrinter::emitInstruction(const MachineInstr *MI) {
+ switch (MI->getOpcode()) {
+ default:
+ break;
+ case PPC::BL8:
+ case PPC::BL:
+ case PPC::BL8_NOP:
+ case PPC::BL_NOP: {
+ const MachineOperand &MO = MI->getOperand(0);
+ if (MO.isSymbol()) {
+ MCSymbolXCOFF *S =
+ cast<MCSymbolXCOFF>(OutContext.getOrCreateSymbol(MO.getSymbolName()));
+ ExtSymSDNodeSymbols.insert(S);
+ }
+ } break;
+ case PPC::BL_TLS:
+ case PPC::BL8_TLS:
+ case PPC::BL8_TLS_:
+ case PPC::BL8_NOP_TLS:
+ report_fatal_error("TLS call not yet implemented");
+ case PPC::TAILB:
+ case PPC::TAILB8:
+ case PPC::TAILBA:
+ case PPC::TAILBA8:
+ case PPC::TAILBCTR:
+ case PPC::TAILBCTR8:
+ if (MI->getOperand(0).isSymbol())
+ report_fatal_error("Tail call for extern symbol not yet supported.");
+ break;
+ }
+ return PPCAsmPrinter::emitInstruction(MI);
+}
+
+bool PPCAIXAsmPrinter::doFinalization(Module &M) {
+ for (MCSymbol *Sym : ExtSymSDNodeSymbols)
+ OutStreamer->emitSymbolAttribute(Sym, MCSA_Extern);
+ return PPCAsmPrinter::doFinalization(M);
+}
+
+static unsigned mapToSinitPriority(int P) {
+ if (P < 0 || P > 65535)
+ report_fatal_error("invalid init priority");
+
+ if (P <= 20)
+ return P;
+
+ if (P < 81)
+ return 20 + (P - 20) * 16;
+
+ if (P <= 1124)
+ return 1004 + (P - 81);
+
+ if (P < 64512)
+ return 2047 + (P - 1124) * 33878;
+
+ return 2147482625u + (P - 64512);
+}
+
+static std::string convertToSinitPriority(int Priority) {
+ // This helper function converts clang init priority to values used in sinit
+ // and sterm functions.
+ //
+ // The conversion strategies are:
+ // We map the reserved clang/gnu priority range [0, 100] into the sinit/sterm
+ // reserved priority range [0, 1023] by
+ // - directly mapping the first 21 and the last 20 elements of the ranges
+ // - linear interpolating the intermediate values with a step size of 16.
+ //
+ // We map the non reserved clang/gnu priority range of [101, 65535] into the
+ // sinit/sterm priority range [1024, 2147483648] by:
+ // - directly mapping the first and the last 1024 elements of the ranges
+ // - linear interpolating the intermediate values with a step size of 33878.
+ unsigned int P = mapToSinitPriority(Priority);
+
+ std::string PrioritySuffix;
+ llvm::raw_string_ostream os(PrioritySuffix);
+ os << llvm::format_hex_no_prefix(P, 8);
+ os.flush();
+ return PrioritySuffix;
+}
+
+void PPCAIXAsmPrinter::emitXXStructorList(const DataLayout &DL,
+ const Constant *List, bool IsCtor) {
+ SmallVector<Structor, 8> Structors;
+ preprocessXXStructorList(DL, List, Structors);
+ if (Structors.empty())
+ return;
+
+ unsigned Index = 0;
+ for (Structor &S : Structors) {
+ if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(S.Func))
+ S.Func = CE->getOperand(0);
+
+ llvm::GlobalAlias::create(
+ GlobalValue::ExternalLinkage,
+ (IsCtor ? llvm::Twine("__sinit") : llvm::Twine("__sterm")) +
+ llvm::Twine(convertToSinitPriority(S.Priority)) +
+ llvm::Twine("_", FormatIndicatorAndUniqueModId) +
+ llvm::Twine("_", llvm::utostr(Index++)),
+ cast<Function>(S.Func));
+ }
+}
+
+void PPCAIXAsmPrinter::emitTTypeReference(const GlobalValue *GV,
+ unsigned Encoding) {
+ if (GV) {
+ MCSymbol *TypeInfoSym = TM.getSymbol(GV);
+ MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym);
+ const MCSymbol *TOCBaseSym =
+ cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
+ ->getQualNameSymbol();
+ auto &Ctx = OutStreamer->getContext();
+ const MCExpr *Exp =
+ MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCEntry, Ctx),
+ MCSymbolRefExpr::create(TOCBaseSym, Ctx), Ctx);
+ OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
+ } else
+ OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
+}
+
+// Return a pass that prints the PPC assembly code for a MachineFunction to the
+// given output stream.
static AsmPrinter *
createPPCAsmPrinterPass(TargetMachine &tm,
std::unique_ptr<MCStreamer> &&Streamer) {
@@ -2379,8 +2379,8 @@ createPPCAsmPrinterPass(TargetMachine &tm,
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter() {
TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
createPPCAsmPrinterPass);
- TargetRegistry::RegisterAsmPrinter(getThePPC32LETarget(),
- createPPCAsmPrinterPass);
+ TargetRegistry::RegisterAsmPrinter(getThePPC32LETarget(),
+ createPPCAsmPrinterPass);
TargetRegistry::RegisterAsmPrinter(getThePPC64Target(),
createPPCAsmPrinterPass);
TargetRegistry::RegisterAsmPrinter(getThePPC64LETarget(),
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCBoolRetToInt.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCBoolRetToInt.cpp
index 1f83428533..3c6b1f84b8 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCBoolRetToInt.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCBoolRetToInt.cpp
@@ -59,7 +59,7 @@ using namespace llvm;
namespace {
-#define DEBUG_TYPE "ppc-bool-ret-to-int"
+#define DEBUG_TYPE "ppc-bool-ret-to-int"
STATISTIC(NumBoolRetPromotion,
"Number of times a bool feeding a RetInst was promoted to an int");
@@ -75,7 +75,7 @@ class PPCBoolRetToInt : public FunctionPass {
WorkList.push_back(V);
Defs.insert(V);
while (!WorkList.empty()) {
- Value *Curr = WorkList.pop_back_val();
+ Value *Curr = WorkList.pop_back_val();
auto *CurrUser = dyn_cast<User>(Curr);
// Operands of CallInst/Constant are skipped because they may not be Bool
// type. For CallInst, their positions are defined by ABI.
@@ -282,8 +282,8 @@ private:
} // end anonymous namespace
char PPCBoolRetToInt::ID = 0;
-INITIALIZE_PASS(PPCBoolRetToInt, "ppc-bool-ret-to-int",
- "Convert i1 constants to i32/i64 if they are returned", false,
- false)
+INITIALIZE_PASS(PPCBoolRetToInt, "ppc-bool-ret-to-int",
+ "Convert i1 constants to i32/i64 if they are returned", false,
+ false)
FunctionPass *llvm::createPPCBoolRetToIntPass() { return new PPCBoolRetToInt(); }
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCCCState.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCCCState.cpp
index 144ef15b7c..79ffc6627a 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCCCState.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCCCState.cpp
@@ -32,4 +32,4 @@ void PPCCCState::PreAnalyzeFormalArguments(
OriginalArgWasPPCF128.push_back(false);
}
}
-}
+}
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCCTRLoops.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCCTRLoops.cpp
index b8b13c6dde..b9518d6d70 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCCTRLoops.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCCTRLoops.cpp
@@ -1,4 +1,4 @@
-//===-- PPCCTRLoops.cpp - Verify CTR loops -----------------===//
+//===-- PPCCTRLoops.cpp - Verify CTR loops -----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,45 +6,45 @@
//
//===----------------------------------------------------------------------===//
//
-// This pass verifies that all bdnz/bdz instructions are dominated by a loop
-// mtctr before any other instructions that might clobber the ctr register.
+// This pass verifies that all bdnz/bdz instructions are dominated by a loop
+// mtctr before any other instructions that might clobber the ctr register.
//
//===----------------------------------------------------------------------===//
-// CTR loops are produced by the HardwareLoops pass and this pass is simply a
-// verification that no invalid CTR loops are produced. As such, it isn't
-// something that needs to be run (or even defined) for Release builds so the
-// entire file is guarded by NDEBUG.
-#ifndef NDEBUG
-#include <vector>
-
-#include "MCTargetDesc/PPCMCTargetDesc.h"
+// CTR loops are produced by the HardwareLoops pass and this pass is simply a
+// verification that no invalid CTR loops are produced. As such, it isn't
+// something that needs to be run (or even defined) for Release builds so the
+// entire file is guarded by NDEBUG.
+#ifndef NDEBUG
+#include <vector>
+
+#include "MCTargetDesc/PPCMCTargetDesc.h"
#include "PPC.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/ilist_iterator.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineDominators.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineInstrBundleIterator.h"
-#include "llvm/CodeGen/MachineOperand.h"
-#include "llvm/CodeGen/Register.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/ilist_iterator.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineInstrBundleIterator.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/Register.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
-#include "llvm/PassRegistry.h"
-#include "llvm/Support/CodeGen.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/GenericDomTreeConstruction.h"
-#include "llvm/Support/Printable.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/GenericDomTreeConstruction.h"
+#include "llvm/Support/Printable.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-#define DEBUG_TYPE "ppc-ctrloops-verify"
+#define DEBUG_TYPE "ppc-ctrloops-verify"
namespace {
@@ -148,7 +148,7 @@ queue_preds:
return false;
}
- append_range(Preds, MBB->predecessors());
+ append_range(Preds, MBB->predecessors());
}
do {
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCCallingConv.td b/contrib/libs/llvm12/lib/Target/PowerPC/PPCCallingConv.td
index 095e6e6e6a..cc34867181 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCCallingConv.td
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCCallingConv.td
@@ -59,7 +59,7 @@ def RetCC_PPC_Cold : CallingConv<[
CCIfType<[f32], CCAssignToReg<[F1]>>,
CCIfType<[f64], CCAssignToReg<[F1]>>,
- CCIfType<[f128], CCIfSubtarget<"hasAltivec()", CCAssignToReg<[V2]>>>,
+ CCIfType<[f128], CCIfSubtarget<"hasAltivec()", CCAssignToReg<[V2]>>>,
CCIfType<[v16i8, v8i16, v4i32, v2i64, v1i128, v4f32, v2f64],
CCIfSubtarget<"hasAltivec()",
@@ -92,7 +92,7 @@ def RetCC_PPC : CallingConv<[
// For P9, f128 are passed in vector registers.
CCIfType<[f128],
- CCIfSubtarget<"hasAltivec()",
+ CCIfSubtarget<"hasAltivec()",
CCAssignToReg<[V2, V3, V4, V5, V6, V7, V8, V9]>>>,
// Vector types returned as "direct" go into V2 .. V9; note that only the
@@ -149,7 +149,7 @@ def RetCC_PPC64_ELF_FIS : CallingConv<[
CCIfType<[f32], CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8]>>,
CCIfType<[f64], CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8]>>,
CCIfType<[f128],
- CCIfSubtarget<"hasAltivec()",
+ CCIfSubtarget<"hasAltivec()",
CCAssignToReg<[V2, V3, V4, V5, V6, V7, V8, V9]>>>,
CCIfType<[v16i8, v8i16, v4i32, v2i64, v1i128, v4f32, v2f64],
CCIfSubtarget<"hasAltivec()",
@@ -216,7 +216,7 @@ def CC_PPC32_SVR4_Common : CallingConv<[
// Vectors and float128 get 16-byte stack slots that are 16-byte aligned.
CCIfType<[v16i8, v8i16, v4i32, v4f32, v2f64, v2i64], CCAssignToStack<16, 16>>,
- CCIfType<[f128], CCIfSubtarget<"hasAltivec()", CCAssignToStack<16, 16>>>
+ CCIfType<[f128], CCIfSubtarget<"hasAltivec()", CCAssignToStack<16, 16>>>
]>;
// This calling convention puts vector arguments always on the stack. It is used
@@ -238,7 +238,7 @@ def CC_PPC32_SVR4 : CallingConv<[
// Float128 types treated as vector arguments.
CCIfType<[f128],
- CCIfSubtarget<"hasAltivec()", CCAssignToReg<[V2, V3, V4, V5, V6, V7,
+ CCIfSubtarget<"hasAltivec()", CCAssignToReg<[V2, V3, V4, V5, V6, V7,
V8, V9, V10, V11, V12, V13]>>>,
CCDelegateTo<CC_PPC32_SVR4_Common>
@@ -291,8 +291,8 @@ def CSR_AIX32 : CalleeSavedRegs<(add R13, R14, R15, R16, R17, R18, R19, R20,
F27, F28, F29, F30, F31, CR2, CR3, CR4
)>;
-def CSR_AIX32_Altivec : CalleeSavedRegs<(add CSR_AIX32, CSR_Altivec)>;
-
+def CSR_AIX32_Altivec : CalleeSavedRegs<(add CSR_AIX32, CSR_Altivec)>;
+
// Common CalleeSavedRegs for SVR4 and AIX.
def CSR_PPC64 : CalleeSavedRegs<(add X14, X15, X16, X17, X18, X19, X20,
X21, X22, X23, X24, X25, X26, X27, X28,
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCEarlyReturn.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCEarlyReturn.cpp
index f3f0b013a2..08b7bdb3ac 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCEarlyReturn.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCEarlyReturn.cpp
@@ -77,9 +77,9 @@ protected:
if (J->getOperand(0).getMBB() == &ReturnMBB) {
// This is an unconditional branch to the return. Replace the
// branch with a blr.
- MachineInstr *MI = ReturnMBB.getParent()->CloneMachineInstr(&*I);
- (*PI)->insert(J, MI);
-
+ MachineInstr *MI = ReturnMBB.getParent()->CloneMachineInstr(&*I);
+ (*PI)->insert(J, MI);
+
MachineBasicBlock::iterator K = J--;
K->eraseFromParent();
BlockChanged = true;
@@ -90,13 +90,13 @@ protected:
if (J->getOperand(2).getMBB() == &ReturnMBB) {
// This is a conditional branch to the return. Replace the branch
// with a bclr.
- MachineInstr *MI = ReturnMBB.getParent()->CloneMachineInstr(&*I);
- MI->setDesc(TII->get(PPC::BCCLR));
- MachineInstrBuilder(*ReturnMBB.getParent(), MI)
+ MachineInstr *MI = ReturnMBB.getParent()->CloneMachineInstr(&*I);
+ MI->setDesc(TII->get(PPC::BCCLR));
+ MachineInstrBuilder(*ReturnMBB.getParent(), MI)
.add(J->getOperand(0))
- .add(J->getOperand(1));
- (*PI)->insert(J, MI);
-
+ .add(J->getOperand(1));
+ (*PI)->insert(J, MI);
+
MachineBasicBlock::iterator K = J--;
K->eraseFromParent();
BlockChanged = true;
@@ -107,13 +107,13 @@ protected:
if (J->getOperand(1).getMBB() == &ReturnMBB) {
// This is a conditional branch to the return. Replace the branch
// with a bclr.
- MachineInstr *MI = ReturnMBB.getParent()->CloneMachineInstr(&*I);
- MI->setDesc(
- TII->get(J->getOpcode() == PPC::BC ? PPC::BCLR : PPC::BCLRn));
- MachineInstrBuilder(*ReturnMBB.getParent(), MI)
- .add(J->getOperand(0));
- (*PI)->insert(J, MI);
-
+ MachineInstr *MI = ReturnMBB.getParent()->CloneMachineInstr(&*I);
+ MI->setDesc(
+ TII->get(J->getOpcode() == PPC::BC ? PPC::BCLR : PPC::BCLRn));
+ MachineInstrBuilder(*ReturnMBB.getParent(), MI)
+ .add(J->getOperand(0));
+ (*PI)->insert(J, MI);
+
MachineBasicBlock::iterator K = J--;
K->eraseFromParent();
BlockChanged = true;
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCFastISel.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCFastISel.cpp
index f944ce1dbf..c181816e31 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCFastISel.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCFastISel.cpp
@@ -1565,10 +1565,10 @@ bool PPCFastISel::fastLowerCall(CallLoweringInfo &CLI) {
if (IsVarArg)
return false;
- // If this is a PC-Rel function, let SDISel handle the call.
- if (Subtarget->isUsingPCRelativeCalls())
- return false;
-
+ // If this is a PC-Rel function, let SDISel handle the call.
+ if (Subtarget->isUsingPCRelativeCalls())
+ return false;
+
// Handle simple calls for now, with legal return types and
// those that can be extended.
Type *RetTy = CLI.RetTy;
@@ -1624,10 +1624,10 @@ bool PPCFastISel::fastLowerCall(CallLoweringInfo &CLI) {
if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8)
return false;
- // FIXME: FastISel cannot handle non-simple types yet, including 128-bit FP
- // types, which is passed through vector register. Skip these types and
- // fallback to default SelectionDAG based selection.
- if (ArgVT.isVector() || ArgVT == MVT::f128)
+ // FIXME: FastISel cannot handle non-simple types yet, including 128-bit FP
+ // types, which is passed through vector register. Skip these types and
+ // fallback to default SelectionDAG based selection.
+ if (ArgVT.isVector() || ArgVT == MVT::f128)
return false;
unsigned Arg = getRegForValue(ArgValue);
@@ -1996,10 +1996,10 @@ bool PPCFastISel::fastSelectInstruction(const Instruction *I) {
// Materialize a floating-point constant into a register, and return
// the register number (or zero if we failed to handle it).
unsigned PPCFastISel::PPCMaterializeFP(const ConstantFP *CFP, MVT VT) {
- // If this is a PC-Rel function, let SDISel handle constant pool.
- if (Subtarget->isUsingPCRelativeCalls())
- return false;
-
+ // If this is a PC-Rel function, let SDISel handle constant pool.
+ if (Subtarget->isUsingPCRelativeCalls())
+ return false;
+
// No plans to handle long double here.
if (VT != MVT::f32 && VT != MVT::f64)
return 0;
@@ -2064,10 +2064,10 @@ unsigned PPCFastISel::PPCMaterializeFP(const ConstantFP *CFP, MVT VT) {
// Materialize the address of a global value into a register, and return
// the register number (or zero if we failed to handle it).
unsigned PPCFastISel::PPCMaterializeGV(const GlobalValue *GV, MVT VT) {
- // If this is a PC-Rel function, let SDISel handle GV materialization.
- if (Subtarget->isUsingPCRelativeCalls())
- return false;
-
+ // If this is a PC-Rel function, let SDISel handle GV materialization.
+ if (Subtarget->isUsingPCRelativeCalls())
+ return false;
+
assert(VT == MVT::i64 && "Non-address!");
const TargetRegisterClass *RC = &PPC::G8RC_and_G8RC_NOX0RegClass;
unsigned DestReg = createResultReg(RC);
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCFrameLowering.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCFrameLowering.cpp
index 86ae5f5b9e..16536bf23d 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCFrameLowering.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCFrameLowering.cpp
@@ -218,14 +218,14 @@ const PPCFrameLowering::SpillSlot *PPCFrameLowering::getCalleeSavedSpillSlots(
CALLEE_SAVED_VRS
};
- static const SpillSlot AIXOffsets32[] = {CALLEE_SAVED_FPRS,
- CALLEE_SAVED_GPRS32,
- // Add AIX's extra CSR.
- {PPC::R13, -76},
- CALLEE_SAVED_VRS};
+ static const SpillSlot AIXOffsets32[] = {CALLEE_SAVED_FPRS,
+ CALLEE_SAVED_GPRS32,
+ // Add AIX's extra CSR.
+ {PPC::R13, -76},
+ CALLEE_SAVED_VRS};
static const SpillSlot AIXOffsets64[] = {
- CALLEE_SAVED_FPRS, CALLEE_SAVED_GPRS64, CALLEE_SAVED_VRS};
+ CALLEE_SAVED_FPRS, CALLEE_SAVED_GPRS64, CALLEE_SAVED_VRS};
if (Subtarget.is64BitELFABI()) {
NumEntries = array_lengthof(ELFOffsets64);
@@ -318,7 +318,7 @@ PPCFrameLowering::determineFrameLayout(const MachineFunction &MF,
!FI->mustSaveTOC() && // No need to save TOC.
!RegInfo->hasBasePointer(MF); // No special alignment.
- // Note: for PPC32 SVR4ABI, we can still generate stackless
+ // Note: for PPC32 SVR4ABI, we can still generate stackless
// code if all local vars are reg-allocated.
bool FitsInRedZone = FrameSize <= Subtarget.getRedZoneSize();
@@ -375,10 +375,10 @@ bool PPCFrameLowering::needsFP(const MachineFunction &MF) const {
return false;
return MF.getTarget().Options.DisableFramePointerElim(MF) ||
- MFI.hasVarSizedObjects() || MFI.hasStackMap() || MFI.hasPatchPoint() ||
- MF.exposesReturnsTwice() ||
- (MF.getTarget().Options.GuaranteedTailCallOpt &&
- MF.getInfo<PPCFunctionInfo>()->hasFastCall());
+ MFI.hasVarSizedObjects() || MFI.hasStackMap() || MFI.hasPatchPoint() ||
+ MF.exposesReturnsTwice() ||
+ (MF.getTarget().Options.GuaranteedTailCallOpt &&
+ MF.getInfo<PPCFunctionInfo>()->hasFastCall());
}
void PPCFrameLowering::replaceFPWithRealFP(MachineFunction &MF) const {
@@ -526,8 +526,8 @@ PPCFrameLowering::findScratchRegister(MachineBasicBlock *MBB,
// register is available, we can adjust for that by not overlapping the spill
// code. However, if we need to realign the stack (i.e. have a base pointer)
// and the stack frame is large, we need two scratch registers.
-// Also, stack probe requires two scratch registers, one for old sp, one for
-// large frame and large probe size.
+// Also, stack probe requires two scratch registers, one for old sp, one for
+// large frame and large probe size.
bool
PPCFrameLowering::twoUniqueScratchRegsRequired(MachineBasicBlock *MBB) const {
const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
@@ -539,10 +539,10 @@ PPCFrameLowering::twoUniqueScratchRegsRequired(MachineBasicBlock *MBB) const {
MachineFrameInfo &MFI = MF.getFrameInfo();
Align MaxAlign = MFI.getMaxAlign();
bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI();
- const PPCTargetLowering &TLI = *Subtarget.getTargetLowering();
+ const PPCTargetLowering &TLI = *Subtarget.getTargetLowering();
- return ((IsLargeFrame || !HasRedZone) && HasBP && MaxAlign > 1) ||
- TLI.hasInlineStackProbe(MF);
+ return ((IsLargeFrame || !HasRedZone) && HasBP && MaxAlign > 1) ||
+ TLI.hasInlineStackProbe(MF);
}
bool PPCFrameLowering::canUseAsPrologue(const MachineBasicBlock &MBB) const {
@@ -585,8 +585,8 @@ bool PPCFrameLowering::stackUpdateCanBeMoved(MachineFunction &MF) const {
// Frame pointers and base pointers complicate matters so don't do anything
// if we have them. For example having a frame pointer will sometimes require
// a copy of r1 into r31 and that makes keeping track of updates to r1 more
- // difficult. Similar situation exists with setjmp.
- if (hasFP(MF) || RegInfo->hasBasePointer(MF) || MF.exposesReturnsTwice())
+ // difficult. Similar situation exists with setjmp.
+ if (hasFP(MF) || RegInfo->hasBasePointer(MF) || MF.exposesReturnsTwice())
return false;
// Calls to fast_cc functions use different rules for passing parameters on
@@ -621,7 +621,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF,
// Get the ABI.
bool isSVR4ABI = Subtarget.isSVR4ABI();
bool isELFv2ABI = Subtarget.isELFv2ABI();
- assert((isSVR4ABI || Subtarget.isAIXABI()) && "Unsupported PPC ABI.");
+ assert((isSVR4ABI || Subtarget.isAIXABI()) && "Unsupported PPC ABI.");
// Work out frame sizes.
unsigned FrameSize = determineFrameLayoutAndUpdate(MF);
@@ -682,7 +682,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF,
// Using the same bool variable as below to suppress compiler warnings.
bool SingleScratchReg = findScratchRegister(
- &MBB, false, twoUniqueScratchRegsRequired(&MBB), &ScratchReg, &TempReg);
+ &MBB, false, twoUniqueScratchRegsRequired(&MBB), &ScratchReg, &TempReg);
assert(SingleScratchReg &&
"Required number of registers not available in this block");
@@ -692,18 +692,18 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF,
int FPOffset = 0;
if (HasFP) {
- MachineFrameInfo &MFI = MF.getFrameInfo();
- int FPIndex = FI->getFramePointerSaveIndex();
- assert(FPIndex && "No Frame Pointer Save Slot!");
- FPOffset = MFI.getObjectOffset(FPIndex);
+ MachineFrameInfo &MFI = MF.getFrameInfo();
+ int FPIndex = FI->getFramePointerSaveIndex();
+ assert(FPIndex && "No Frame Pointer Save Slot!");
+ FPOffset = MFI.getObjectOffset(FPIndex);
}
int BPOffset = 0;
if (HasBP) {
- MachineFrameInfo &MFI = MF.getFrameInfo();
- int BPIndex = FI->getBasePointerSaveIndex();
- assert(BPIndex && "No Base Pointer Save Slot!");
- BPOffset = MFI.getObjectOffset(BPIndex);
+ MachineFrameInfo &MFI = MF.getFrameInfo();
+ int BPIndex = FI->getBasePointerSaveIndex();
+ assert(BPIndex && "No Base Pointer Save Slot!");
+ BPOffset = MFI.getObjectOffset(BPIndex);
}
int PBPOffset = 0;
@@ -859,15 +859,15 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF,
BuildMI(MBB, MBBI, dl,
TII.get(isPPC64 ? PPC::PROBED_STACKALLOC_64
: PPC::PROBED_STACKALLOC_32))
- .addDef(TempReg)
- .addDef(ScratchReg) // ScratchReg stores the old sp.
+ .addDef(TempReg)
+ .addDef(ScratchReg) // ScratchReg stores the old sp.
.addImm(NegFrameSize);
// FIXME: HasSTUX is only read if HasRedZone is not set, in such case, we
// update the ScratchReg to meet the assumption that ScratchReg contains
// the NegFrameSize. This solution is rather tricky.
if (!HasRedZone) {
BuildMI(MBB, MBBI, dl, TII.get(PPC::SUBF), ScratchReg)
- .addReg(ScratchReg)
+ .addReg(ScratchReg)
.addReg(SPReg);
HasSTUX = true;
}
@@ -1202,12 +1202,12 @@ void PPCFrameLowering::inlineStackProbe(MachineFunction &MF,
if (StackAllocMIPos == PrologMBB.end())
return;
const BasicBlock *ProbedBB = PrologMBB.getBasicBlock();
- MachineBasicBlock *CurrentMBB = &PrologMBB;
+ MachineBasicBlock *CurrentMBB = &PrologMBB;
DebugLoc DL = PrologMBB.findDebugLoc(StackAllocMIPos);
MachineInstr &MI = *StackAllocMIPos;
int64_t NegFrameSize = MI.getOperand(2).getImm();
- unsigned ProbeSize = TLI.getStackProbeSize(MF);
- int64_t NegProbeSize = -(int64_t)ProbeSize;
+ unsigned ProbeSize = TLI.getStackProbeSize(MF);
+ int64_t NegProbeSize = -(int64_t)ProbeSize;
assert(isInt<32>(NegProbeSize) && "Unhandled probe size");
int64_t NumBlocks = NegFrameSize / NegProbeSize;
int64_t NegResidualSize = NegFrameSize % NegProbeSize;
@@ -1216,9 +1216,9 @@ void PPCFrameLowering::inlineStackProbe(MachineFunction &MF,
Register FPReg = MI.getOperand(1).getReg();
const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
bool HasBP = RegInfo->hasBasePointer(MF);
- Register BPReg = RegInfo->getBaseRegister(MF);
+ Register BPReg = RegInfo->getBaseRegister(MF);
Align MaxAlign = MFI.getMaxAlign();
- bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI();
+ bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI();
const MCInstrDesc &CopyInst = TII.get(isPPC64 ? PPC::OR8 : PPC::OR);
// Subroutines to generate .cfi_* directives.
auto buildDefCFAReg = [&](MachineBasicBlock &MBB,
@@ -1259,233 +1259,233 @@ void PPCFrameLowering::inlineStackProbe(MachineFunction &MF,
// Subroutine to store frame pointer and decrease stack pointer by probe size.
auto allocateAndProbe = [&](MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI, int64_t NegSize,
- Register NegSizeReg, bool UseDForm,
- Register StoreReg) {
+ Register NegSizeReg, bool UseDForm,
+ Register StoreReg) {
if (UseDForm)
BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::STDU : PPC::STWU), SPReg)
- .addReg(StoreReg)
+ .addReg(StoreReg)
.addImm(NegSize)
.addReg(SPReg);
else
BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
- .addReg(StoreReg)
+ .addReg(StoreReg)
.addReg(SPReg)
.addReg(NegSizeReg);
};
- // Used to probe stack when realignment is required.
- // Note that, according to ABI's requirement, *sp must always equals the
- // value of back-chain pointer, only st(w|d)u(x) can be used to update sp.
- // Following is pseudo code:
- // final_sp = (sp & align) + negframesize;
- // neg_gap = final_sp - sp;
- // while (neg_gap < negprobesize) {
- // stdu fp, negprobesize(sp);
- // neg_gap -= negprobesize;
- // }
- // stdux fp, sp, neg_gap
- //
- // When HasBP & HasRedzone, back-chain pointer is already saved in BPReg
- // before probe code, we don't need to save it, so we get one additional reg
- // that can be used to materialize the probeside if needed to use xform.
- // Otherwise, we can NOT materialize probeside, so we can only use Dform for
- // now.
- //
- // The allocations are:
- // if (HasBP && HasRedzone) {
- // r0: materialize the probesize if needed so that we can use xform.
- // r12: `neg_gap`
- // } else {
- // r0: back-chain pointer
- // r12: `neg_gap`.
- // }
- auto probeRealignedStack = [&](MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MBBI,
- Register ScratchReg, Register TempReg) {
- assert(HasBP && "The function is supposed to have base pointer when its "
- "stack is realigned.");
- assert(isPowerOf2_64(ProbeSize) && "Probe size should be power of 2");
-
- // FIXME: We can eliminate this limitation if we get more infomation about
- // which part of redzone are already used. Used redzone can be treated
- // probed. But there might be `holes' in redzone probed, this could
- // complicate the implementation.
- assert(ProbeSize >= Subtarget.getRedZoneSize() &&
- "Probe size should be larger or equal to the size of red-zone so "
- "that red-zone is not clobbered by probing.");
-
- Register &FinalStackPtr = TempReg;
- // FIXME: We only support NegProbeSize materializable by DForm currently.
- // When HasBP && HasRedzone, we can use xform if we have an additional idle
- // register.
- NegProbeSize = std::max(NegProbeSize, -((int64_t)1 << 15));
- assert(isInt<16>(NegProbeSize) &&
- "NegProbeSize should be materializable by DForm");
- Register CRReg = PPC::CR0;
- // Layout of output assembly kinda like:
- // bb.0:
- // ...
- // sub $scratchreg, $finalsp, r1
- // cmpdi $scratchreg, <negprobesize>
- // bge bb.2
- // bb.1:
- // stdu <backchain>, <negprobesize>(r1)
- // sub $scratchreg, $scratchreg, negprobesize
- // cmpdi $scratchreg, <negprobesize>
- // blt bb.1
- // bb.2:
- // stdux <backchain>, r1, $scratchreg
- MachineFunction::iterator MBBInsertPoint = std::next(MBB.getIterator());
- MachineBasicBlock *ProbeLoopBodyMBB = MF.CreateMachineBasicBlock(ProbedBB);
- MF.insert(MBBInsertPoint, ProbeLoopBodyMBB);
- MachineBasicBlock *ProbeExitMBB = MF.CreateMachineBasicBlock(ProbedBB);
- MF.insert(MBBInsertPoint, ProbeExitMBB);
- // bb.2
- {
- Register BackChainPointer = HasRedZone ? BPReg : TempReg;
- allocateAndProbe(*ProbeExitMBB, ProbeExitMBB->end(), 0, ScratchReg, false,
- BackChainPointer);
- if (HasRedZone)
- // PROBED_STACKALLOC_64 assumes Operand(1) stores the old sp, copy BPReg
- // to TempReg to satisfy it.
- BuildMI(*ProbeExitMBB, ProbeExitMBB->end(), DL, CopyInst, TempReg)
- .addReg(BPReg)
- .addReg(BPReg);
- ProbeExitMBB->splice(ProbeExitMBB->end(), &MBB, MBBI, MBB.end());
- ProbeExitMBB->transferSuccessorsAndUpdatePHIs(&MBB);
- }
- // bb.0
- {
- BuildMI(&MBB, DL, TII.get(isPPC64 ? PPC::SUBF8 : PPC::SUBF), ScratchReg)
- .addReg(SPReg)
- .addReg(FinalStackPtr);
- if (!HasRedZone)
- BuildMI(&MBB, DL, CopyInst, TempReg).addReg(SPReg).addReg(SPReg);
- BuildMI(&MBB, DL, TII.get(isPPC64 ? PPC::CMPDI : PPC::CMPWI), CRReg)
- .addReg(ScratchReg)
- .addImm(NegProbeSize);
- BuildMI(&MBB, DL, TII.get(PPC::BCC))
- .addImm(PPC::PRED_GE)
- .addReg(CRReg)
- .addMBB(ProbeExitMBB);
- MBB.addSuccessor(ProbeLoopBodyMBB);
- MBB.addSuccessor(ProbeExitMBB);
- }
- // bb.1
- {
- Register BackChainPointer = HasRedZone ? BPReg : TempReg;
- allocateAndProbe(*ProbeLoopBodyMBB, ProbeLoopBodyMBB->end(), NegProbeSize,
- 0, true /*UseDForm*/, BackChainPointer);
- BuildMI(ProbeLoopBodyMBB, DL, TII.get(isPPC64 ? PPC::ADDI8 : PPC::ADDI),
- ScratchReg)
- .addReg(ScratchReg)
- .addImm(-NegProbeSize);
- BuildMI(ProbeLoopBodyMBB, DL, TII.get(isPPC64 ? PPC::CMPDI : PPC::CMPWI),
- CRReg)
- .addReg(ScratchReg)
- .addImm(NegProbeSize);
- BuildMI(ProbeLoopBodyMBB, DL, TII.get(PPC::BCC))
- .addImm(PPC::PRED_LT)
- .addReg(CRReg)
- .addMBB(ProbeLoopBodyMBB);
- ProbeLoopBodyMBB->addSuccessor(ProbeExitMBB);
- ProbeLoopBodyMBB->addSuccessor(ProbeLoopBodyMBB);
- }
- // Update liveins.
- recomputeLiveIns(*ProbeLoopBodyMBB);
- recomputeLiveIns(*ProbeExitMBB);
- return ProbeExitMBB;
- };
- // For case HasBP && MaxAlign > 1, we have to realign the SP by performing
- // SP = SP - SP % MaxAlign, thus make the probe more like dynamic probe since
- // the offset subtracted from SP is determined by SP's runtime value.
+ // Used to probe stack when realignment is required.
+ // Note that, according to ABI's requirement, *sp must always equals the
+ // value of back-chain pointer, only st(w|d)u(x) can be used to update sp.
+ // Following is pseudo code:
+ // final_sp = (sp & align) + negframesize;
+ // neg_gap = final_sp - sp;
+ // while (neg_gap < negprobesize) {
+ // stdu fp, negprobesize(sp);
+ // neg_gap -= negprobesize;
+ // }
+ // stdux fp, sp, neg_gap
+ //
+ // When HasBP & HasRedzone, back-chain pointer is already saved in BPReg
+ // before probe code, we don't need to save it, so we get one additional reg
+ // that can be used to materialize the probeside if needed to use xform.
+ // Otherwise, we can NOT materialize probeside, so we can only use Dform for
+ // now.
+ //
+ // The allocations are:
+ // if (HasBP && HasRedzone) {
+ // r0: materialize the probesize if needed so that we can use xform.
+ // r12: `neg_gap`
+ // } else {
+ // r0: back-chain pointer
+ // r12: `neg_gap`.
+ // }
+ auto probeRealignedStack = [&](MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ Register ScratchReg, Register TempReg) {
+ assert(HasBP && "The function is supposed to have base pointer when its "
+ "stack is realigned.");
+ assert(isPowerOf2_64(ProbeSize) && "Probe size should be power of 2");
+
+ // FIXME: We can eliminate this limitation if we get more infomation about
+ // which part of redzone are already used. Used redzone can be treated
+ // probed. But there might be `holes' in redzone probed, this could
+ // complicate the implementation.
+ assert(ProbeSize >= Subtarget.getRedZoneSize() &&
+ "Probe size should be larger or equal to the size of red-zone so "
+ "that red-zone is not clobbered by probing.");
+
+ Register &FinalStackPtr = TempReg;
+ // FIXME: We only support NegProbeSize materializable by DForm currently.
+ // When HasBP && HasRedzone, we can use xform if we have an additional idle
+ // register.
+ NegProbeSize = std::max(NegProbeSize, -((int64_t)1 << 15));
+ assert(isInt<16>(NegProbeSize) &&
+ "NegProbeSize should be materializable by DForm");
+ Register CRReg = PPC::CR0;
+ // Layout of output assembly kinda like:
+ // bb.0:
+ // ...
+ // sub $scratchreg, $finalsp, r1
+ // cmpdi $scratchreg, <negprobesize>
+ // bge bb.2
+ // bb.1:
+ // stdu <backchain>, <negprobesize>(r1)
+ // sub $scratchreg, $scratchreg, negprobesize
+ // cmpdi $scratchreg, <negprobesize>
+ // blt bb.1
+ // bb.2:
+ // stdux <backchain>, r1, $scratchreg
+ MachineFunction::iterator MBBInsertPoint = std::next(MBB.getIterator());
+ MachineBasicBlock *ProbeLoopBodyMBB = MF.CreateMachineBasicBlock(ProbedBB);
+ MF.insert(MBBInsertPoint, ProbeLoopBodyMBB);
+ MachineBasicBlock *ProbeExitMBB = MF.CreateMachineBasicBlock(ProbedBB);
+ MF.insert(MBBInsertPoint, ProbeExitMBB);
+ // bb.2
+ {
+ Register BackChainPointer = HasRedZone ? BPReg : TempReg;
+ allocateAndProbe(*ProbeExitMBB, ProbeExitMBB->end(), 0, ScratchReg, false,
+ BackChainPointer);
+ if (HasRedZone)
+ // PROBED_STACKALLOC_64 assumes Operand(1) stores the old sp, copy BPReg
+ // to TempReg to satisfy it.
+ BuildMI(*ProbeExitMBB, ProbeExitMBB->end(), DL, CopyInst, TempReg)
+ .addReg(BPReg)
+ .addReg(BPReg);
+ ProbeExitMBB->splice(ProbeExitMBB->end(), &MBB, MBBI, MBB.end());
+ ProbeExitMBB->transferSuccessorsAndUpdatePHIs(&MBB);
+ }
+ // bb.0
+ {
+ BuildMI(&MBB, DL, TII.get(isPPC64 ? PPC::SUBF8 : PPC::SUBF), ScratchReg)
+ .addReg(SPReg)
+ .addReg(FinalStackPtr);
+ if (!HasRedZone)
+ BuildMI(&MBB, DL, CopyInst, TempReg).addReg(SPReg).addReg(SPReg);
+ BuildMI(&MBB, DL, TII.get(isPPC64 ? PPC::CMPDI : PPC::CMPWI), CRReg)
+ .addReg(ScratchReg)
+ .addImm(NegProbeSize);
+ BuildMI(&MBB, DL, TII.get(PPC::BCC))
+ .addImm(PPC::PRED_GE)
+ .addReg(CRReg)
+ .addMBB(ProbeExitMBB);
+ MBB.addSuccessor(ProbeLoopBodyMBB);
+ MBB.addSuccessor(ProbeExitMBB);
+ }
+ // bb.1
+ {
+ Register BackChainPointer = HasRedZone ? BPReg : TempReg;
+ allocateAndProbe(*ProbeLoopBodyMBB, ProbeLoopBodyMBB->end(), NegProbeSize,
+ 0, true /*UseDForm*/, BackChainPointer);
+ BuildMI(ProbeLoopBodyMBB, DL, TII.get(isPPC64 ? PPC::ADDI8 : PPC::ADDI),
+ ScratchReg)
+ .addReg(ScratchReg)
+ .addImm(-NegProbeSize);
+ BuildMI(ProbeLoopBodyMBB, DL, TII.get(isPPC64 ? PPC::CMPDI : PPC::CMPWI),
+ CRReg)
+ .addReg(ScratchReg)
+ .addImm(NegProbeSize);
+ BuildMI(ProbeLoopBodyMBB, DL, TII.get(PPC::BCC))
+ .addImm(PPC::PRED_LT)
+ .addReg(CRReg)
+ .addMBB(ProbeLoopBodyMBB);
+ ProbeLoopBodyMBB->addSuccessor(ProbeExitMBB);
+ ProbeLoopBodyMBB->addSuccessor(ProbeLoopBodyMBB);
+ }
+ // Update liveins.
+ recomputeLiveIns(*ProbeLoopBodyMBB);
+ recomputeLiveIns(*ProbeExitMBB);
+ return ProbeExitMBB;
+ };
+ // For case HasBP && MaxAlign > 1, we have to realign the SP by performing
+ // SP = SP - SP % MaxAlign, thus make the probe more like dynamic probe since
+ // the offset subtracted from SP is determined by SP's runtime value.
if (HasBP && MaxAlign > 1) {
- // Calculate final stack pointer.
- if (isPPC64)
- BuildMI(*CurrentMBB, {MI}, DL, TII.get(PPC::RLDICL), ScratchReg)
- .addReg(SPReg)
- .addImm(0)
- .addImm(64 - Log2(MaxAlign));
- else
- BuildMI(*CurrentMBB, {MI}, DL, TII.get(PPC::RLWINM), ScratchReg)
- .addReg(SPReg)
+ // Calculate final stack pointer.
+ if (isPPC64)
+ BuildMI(*CurrentMBB, {MI}, DL, TII.get(PPC::RLDICL), ScratchReg)
+ .addReg(SPReg)
+ .addImm(0)
+ .addImm(64 - Log2(MaxAlign));
+ else
+ BuildMI(*CurrentMBB, {MI}, DL, TII.get(PPC::RLWINM), ScratchReg)
+ .addReg(SPReg)
.addImm(0)
.addImm(32 - Log2(MaxAlign))
.addImm(31);
- BuildMI(*CurrentMBB, {MI}, DL, TII.get(isPPC64 ? PPC::SUBF8 : PPC::SUBF),
- FPReg)
- .addReg(ScratchReg)
- .addReg(SPReg);
- MaterializeImm(*CurrentMBB, {MI}, NegFrameSize, ScratchReg);
- BuildMI(*CurrentMBB, {MI}, DL, TII.get(isPPC64 ? PPC::ADD8 : PPC::ADD4),
- FPReg)
- .addReg(ScratchReg)
- .addReg(FPReg);
- CurrentMBB = probeRealignedStack(*CurrentMBB, {MI}, ScratchReg, FPReg);
- if (needsCFI)
- buildDefCFAReg(*CurrentMBB, {MI}, FPReg);
- } else {
- // Initialize current frame pointer.
- BuildMI(*CurrentMBB, {MI}, DL, CopyInst, FPReg).addReg(SPReg).addReg(SPReg);
- // Use FPReg to calculate CFA.
- if (needsCFI)
- buildDefCFA(*CurrentMBB, {MI}, FPReg, 0);
- // Probe residual part.
- if (NegResidualSize) {
- bool ResidualUseDForm = CanUseDForm(NegResidualSize);
- if (!ResidualUseDForm)
- MaterializeImm(*CurrentMBB, {MI}, NegResidualSize, ScratchReg);
- allocateAndProbe(*CurrentMBB, {MI}, NegResidualSize, ScratchReg,
- ResidualUseDForm, FPReg);
+ BuildMI(*CurrentMBB, {MI}, DL, TII.get(isPPC64 ? PPC::SUBF8 : PPC::SUBF),
+ FPReg)
+ .addReg(ScratchReg)
+ .addReg(SPReg);
+ MaterializeImm(*CurrentMBB, {MI}, NegFrameSize, ScratchReg);
+ BuildMI(*CurrentMBB, {MI}, DL, TII.get(isPPC64 ? PPC::ADD8 : PPC::ADD4),
+ FPReg)
+ .addReg(ScratchReg)
+ .addReg(FPReg);
+ CurrentMBB = probeRealignedStack(*CurrentMBB, {MI}, ScratchReg, FPReg);
+ if (needsCFI)
+ buildDefCFAReg(*CurrentMBB, {MI}, FPReg);
+ } else {
+ // Initialize current frame pointer.
+ BuildMI(*CurrentMBB, {MI}, DL, CopyInst, FPReg).addReg(SPReg).addReg(SPReg);
+ // Use FPReg to calculate CFA.
+ if (needsCFI)
+ buildDefCFA(*CurrentMBB, {MI}, FPReg, 0);
+ // Probe residual part.
+ if (NegResidualSize) {
+ bool ResidualUseDForm = CanUseDForm(NegResidualSize);
+ if (!ResidualUseDForm)
+ MaterializeImm(*CurrentMBB, {MI}, NegResidualSize, ScratchReg);
+ allocateAndProbe(*CurrentMBB, {MI}, NegResidualSize, ScratchReg,
+ ResidualUseDForm, FPReg);
}
- bool UseDForm = CanUseDForm(NegProbeSize);
- // If number of blocks is small, just probe them directly.
- if (NumBlocks < 3) {
- if (!UseDForm)
- MaterializeImm(*CurrentMBB, {MI}, NegProbeSize, ScratchReg);
- for (int i = 0; i < NumBlocks; ++i)
- allocateAndProbe(*CurrentMBB, {MI}, NegProbeSize, ScratchReg, UseDForm,
- FPReg);
- if (needsCFI) {
- // Restore using SPReg to calculate CFA.
- buildDefCFAReg(*CurrentMBB, {MI}, SPReg);
- }
- } else {
- // Since CTR is a volatile register and current shrinkwrap implementation
- // won't choose an MBB in a loop as the PrologMBB, it's safe to synthesize a
- // CTR loop to probe.
- // Calculate trip count and stores it in CTRReg.
- MaterializeImm(*CurrentMBB, {MI}, NumBlocks, ScratchReg);
- BuildMI(*CurrentMBB, {MI}, DL, TII.get(isPPC64 ? PPC::MTCTR8 : PPC::MTCTR))
- .addReg(ScratchReg, RegState::Kill);
- if (!UseDForm)
- MaterializeImm(*CurrentMBB, {MI}, NegProbeSize, ScratchReg);
- // Create MBBs of the loop.
- MachineFunction::iterator MBBInsertPoint =
- std::next(CurrentMBB->getIterator());
- MachineBasicBlock *LoopMBB = MF.CreateMachineBasicBlock(ProbedBB);
- MF.insert(MBBInsertPoint, LoopMBB);
- MachineBasicBlock *ExitMBB = MF.CreateMachineBasicBlock(ProbedBB);
- MF.insert(MBBInsertPoint, ExitMBB);
- // Synthesize the loop body.
- allocateAndProbe(*LoopMBB, LoopMBB->end(), NegProbeSize, ScratchReg,
- UseDForm, FPReg);
- BuildMI(LoopMBB, DL, TII.get(isPPC64 ? PPC::BDNZ8 : PPC::BDNZ))
- .addMBB(LoopMBB);
- LoopMBB->addSuccessor(ExitMBB);
- LoopMBB->addSuccessor(LoopMBB);
- // Synthesize the exit MBB.
- ExitMBB->splice(ExitMBB->end(), CurrentMBB,
- std::next(MachineBasicBlock::iterator(MI)),
- CurrentMBB->end());
- ExitMBB->transferSuccessorsAndUpdatePHIs(CurrentMBB);
- CurrentMBB->addSuccessor(LoopMBB);
- if (needsCFI) {
- // Restore using SPReg to calculate CFA.
- buildDefCFAReg(*ExitMBB, ExitMBB->begin(), SPReg);
- }
- // Update liveins.
- recomputeLiveIns(*LoopMBB);
- recomputeLiveIns(*ExitMBB);
+ bool UseDForm = CanUseDForm(NegProbeSize);
+ // If number of blocks is small, just probe them directly.
+ if (NumBlocks < 3) {
+ if (!UseDForm)
+ MaterializeImm(*CurrentMBB, {MI}, NegProbeSize, ScratchReg);
+ for (int i = 0; i < NumBlocks; ++i)
+ allocateAndProbe(*CurrentMBB, {MI}, NegProbeSize, ScratchReg, UseDForm,
+ FPReg);
+ if (needsCFI) {
+ // Restore using SPReg to calculate CFA.
+ buildDefCFAReg(*CurrentMBB, {MI}, SPReg);
+ }
+ } else {
+ // Since CTR is a volatile register and current shrinkwrap implementation
+ // won't choose an MBB in a loop as the PrologMBB, it's safe to synthesize a
+ // CTR loop to probe.
+ // Calculate trip count and stores it in CTRReg.
+ MaterializeImm(*CurrentMBB, {MI}, NumBlocks, ScratchReg);
+ BuildMI(*CurrentMBB, {MI}, DL, TII.get(isPPC64 ? PPC::MTCTR8 : PPC::MTCTR))
+ .addReg(ScratchReg, RegState::Kill);
+ if (!UseDForm)
+ MaterializeImm(*CurrentMBB, {MI}, NegProbeSize, ScratchReg);
+ // Create MBBs of the loop.
+ MachineFunction::iterator MBBInsertPoint =
+ std::next(CurrentMBB->getIterator());
+ MachineBasicBlock *LoopMBB = MF.CreateMachineBasicBlock(ProbedBB);
+ MF.insert(MBBInsertPoint, LoopMBB);
+ MachineBasicBlock *ExitMBB = MF.CreateMachineBasicBlock(ProbedBB);
+ MF.insert(MBBInsertPoint, ExitMBB);
+ // Synthesize the loop body.
+ allocateAndProbe(*LoopMBB, LoopMBB->end(), NegProbeSize, ScratchReg,
+ UseDForm, FPReg);
+ BuildMI(LoopMBB, DL, TII.get(isPPC64 ? PPC::BDNZ8 : PPC::BDNZ))
+ .addMBB(LoopMBB);
+ LoopMBB->addSuccessor(ExitMBB);
+ LoopMBB->addSuccessor(LoopMBB);
+ // Synthesize the exit MBB.
+ ExitMBB->splice(ExitMBB->end(), CurrentMBB,
+ std::next(MachineBasicBlock::iterator(MI)),
+ CurrentMBB->end());
+ ExitMBB->transferSuccessorsAndUpdatePHIs(CurrentMBB);
+ CurrentMBB->addSuccessor(LoopMBB);
+ if (needsCFI) {
+ // Restore using SPReg to calculate CFA.
+ buildDefCFAReg(*ExitMBB, ExitMBB->begin(), SPReg);
+ }
+ // Update liveins.
+ recomputeLiveIns(*LoopMBB);
+ recomputeLiveIns(*ExitMBB);
}
}
++NumPrologProbed;
@@ -1558,9 +1558,9 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
SingleScratchReg = ScratchReg == TempReg;
if (HasFP) {
- int FPIndex = FI->getFramePointerSaveIndex();
- assert(FPIndex && "No Frame Pointer Save Slot!");
- FPOffset = MFI.getObjectOffset(FPIndex);
+ int FPIndex = FI->getFramePointerSaveIndex();
+ assert(FPIndex && "No Frame Pointer Save Slot!");
+ FPOffset = MFI.getObjectOffset(FPIndex);
}
int BPOffset = 0;
@@ -1653,18 +1653,18 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
// offset by the STDU/STDUX/STWU/STWUX instruction. For targets with red
// zone add this offset back now.
- // If the function has a base pointer, the stack pointer has been copied
- // to it so we can restore it by copying in the other direction.
- if (HasRedZone && HasBP) {
- BuildMI(MBB, MBBI, dl, OrInst, RBReg).
- addReg(BPReg).
- addReg(BPReg);
- }
+ // If the function has a base pointer, the stack pointer has been copied
+ // to it so we can restore it by copying in the other direction.
+ if (HasRedZone && HasBP) {
+ BuildMI(MBB, MBBI, dl, OrInst, RBReg).
+ addReg(BPReg).
+ addReg(BPReg);
+ }
// If this function contained a fastcc call and GuaranteedTailCallOpt is
// enabled (=> hasFastCall()==true) the fastcc call might contain a tail
// call which invalidates the stack pointer value in SP(0). So we use the
- // value of R31 in this case. Similar situation exists with setjmp.
- else if (FI->hasFastCall() || MF.exposesReturnsTwice()) {
+ // value of R31 in this case. Similar situation exists with setjmp.
+ else if (FI->hasFastCall() || MF.exposesReturnsTwice()) {
assert(HasFP && "Expecting a valid frame pointer.");
if (!HasRedZone)
RBReg = FPReg;
@@ -2210,8 +2210,8 @@ PPCFrameLowering::addScavengingSpillSlot(MachineFunction &MF,
// needed alignment padding.
unsigned StackSize = determineFrameLayout(MF, true);
MachineFrameInfo &MFI = MF.getFrameInfo();
- if (MFI.hasVarSizedObjects() || spillsCR(MF) || hasNonRISpills(MF) ||
- (hasSpills(MF) && !isInt<16>(StackSize))) {
+ if (MFI.hasVarSizedObjects() || spillsCR(MF) || hasNonRISpills(MF) ||
+ (hasSpills(MF) && !isInt<16>(StackSize))) {
const TargetRegisterClass &GPRC = PPC::GPRCRegClass;
const TargetRegisterClass &G8RC = PPC::G8RCRegClass;
const TargetRegisterClass &RC = Subtarget.isPPC64() ? G8RC : GPRC;
@@ -2225,7 +2225,7 @@ PPCFrameLowering::addScavengingSpillSlot(MachineFunction &MF,
MFI.hasVarSizedObjects() && MFI.getMaxAlign() > getStackAlign();
// These kinds of spills might need two registers.
- if (spillsCR(MF) || HasAlVars)
+ if (spillsCR(MF) || HasAlVars)
RS->addScavengingFrameIndex(
MFI.CreateStackObject(Size, Alignment, false));
}
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 746193861d..2604218da1 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -43,7 +43,7 @@
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/InstrTypes.h"
-#include "llvm/IR/IntrinsicsPowerPC.h"
+#include "llvm/IR/IntrinsicsPowerPC.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CodeGen.h"
@@ -214,7 +214,7 @@ namespace {
/// SelectCC - Select a comparison of the specified values with the
/// specified condition code, returning the CR# of the expression.
SDValue SelectCC(SDValue LHS, SDValue RHS, ISD::CondCode CC,
- const SDLoc &dl, SDValue Chain = SDValue());
+ const SDLoc &dl, SDValue Chain = SDValue());
/// SelectAddrImmOffs - Return true if the operand is valid for a preinc
/// immediate field. Note that the operand at this point is already the
@@ -291,13 +291,13 @@ namespace {
Align(16));
}
- /// SelectAddrImmX34 - Returns true if the address N can be represented by
- /// a base register plus a signed 34-bit displacement. Suitable for use by
- /// PSTXVP and friends.
- bool SelectAddrImmX34(SDValue N, SDValue &Disp, SDValue &Base) {
- return PPCLowering->SelectAddressRegImm34(N, Disp, Base, *CurDAG);
- }
-
+ /// SelectAddrImmX34 - Returns true if the address N can be represented by
+ /// a base register plus a signed 34-bit displacement. Suitable for use by
+ /// PSTXVP and friends.
+ bool SelectAddrImmX34(SDValue N, SDValue &Disp, SDValue &Base) {
+ return PPCLowering->SelectAddressRegImm34(N, Disp, Base, *CurDAG);
+ }
+
// Select an address into a single register.
bool SelectAddr(SDValue N, SDValue &Base) {
Base = N;
@@ -352,7 +352,7 @@ namespace {
private:
bool trySETCC(SDNode *N);
- bool tryFoldSWTestBRCC(SDNode *N);
+ bool tryFoldSWTestBRCC(SDNode *N);
bool tryAsSingleRLDICL(SDNode *N);
bool tryAsSingleRLDICR(SDNode *N);
bool tryAsSingleRLWINM(SDNode *N);
@@ -586,8 +586,8 @@ bool PPCDAGToDAGISel::tryTLSXFormStore(StoreSDNode *ST) {
SDValue Offset = ST->getOffset();
if (!Offset.isUndef())
return false;
- if (Base.getOperand(1).getOpcode() == PPCISD::TLS_LOCAL_EXEC_MAT_ADDR)
- return false;
+ if (Base.getOperand(1).getOpcode() == PPCISD::TLS_LOCAL_EXEC_MAT_ADDR)
+ return false;
SDLoc dl(ST);
EVT MemVT = ST->getMemoryVT();
@@ -631,8 +631,8 @@ bool PPCDAGToDAGISel::tryTLSXFormLoad(LoadSDNode *LD) {
SDValue Offset = LD->getOffset();
if (!Offset.isUndef())
return false;
- if (Base.getOperand(1).getOpcode() == PPCISD::TLS_LOCAL_EXEC_MAT_ADDR)
- return false;
+ if (Base.getOperand(1).getOpcode() == PPCISD::TLS_LOCAL_EXEC_MAT_ADDR)
+ return false;
SDLoc dl(LD);
EVT MemVT = LD->getMemoryVT();
@@ -798,274 +798,274 @@ static unsigned allUsesTruncate(SelectionDAG *CurDAG, SDNode *N) {
return MaxTruncation;
}
-// For any 32 < Num < 64, check if the Imm contains at least Num consecutive
-// zeros and return the number of bits by the left of these consecutive zeros.
-static int findContiguousZerosAtLeast(uint64_t Imm, unsigned Num) {
- unsigned HiTZ = countTrailingZeros<uint32_t>(Hi_32(Imm));
- unsigned LoLZ = countLeadingZeros<uint32_t>(Lo_32(Imm));
- if ((HiTZ + LoLZ) >= Num)
- return (32 + HiTZ);
- return 0;
-}
-
-// Direct materialization of 64-bit constants by enumerated patterns.
-static SDNode *selectI64ImmDirect(SelectionDAG *CurDAG, const SDLoc &dl,
- uint64_t Imm, unsigned &InstCnt) {
- unsigned TZ = countTrailingZeros<uint64_t>(Imm);
- unsigned LZ = countLeadingZeros<uint64_t>(Imm);
- unsigned TO = countTrailingOnes<uint64_t>(Imm);
- unsigned LO = countLeadingOnes<uint64_t>(Imm);
- unsigned Hi32 = Hi_32(Imm);
- unsigned Lo32 = Lo_32(Imm);
- SDNode *Result = nullptr;
- unsigned Shift = 0;
-
- auto getI32Imm = [CurDAG, dl](unsigned Imm) {
- return CurDAG->getTargetConstant(Imm, dl, MVT::i32);
- };
-
- // Following patterns use 1 instructions to materialize the Imm.
- InstCnt = 1;
- // 1-1) Patterns : {zeros}{15-bit valve}
- // {ones}{15-bit valve}
- if (isInt<16>(Imm)) {
- SDValue SDImm = CurDAG->getTargetConstant(Imm, dl, MVT::i64);
- return CurDAG->getMachineNode(PPC::LI8, dl, MVT::i64, SDImm);
- }
- // 1-2) Patterns : {zeros}{15-bit valve}{16 zeros}
- // {ones}{15-bit valve}{16 zeros}
- if (TZ > 15 && (LZ > 32 || LO > 32))
- return CurDAG->getMachineNode(PPC::LIS8, dl, MVT::i64,
- getI32Imm((Imm >> 16) & 0xffff));
-
- // Following patterns use 2 instructions to materialize the Imm.
- InstCnt = 2;
- assert(LZ < 64 && "Unexpected leading zeros here.");
- // Count of ones follwing the leading zeros.
- unsigned FO = countLeadingOnes<uint64_t>(Imm << LZ);
- // 2-1) Patterns : {zeros}{31-bit value}
- // {ones}{31-bit value}
- if (isInt<32>(Imm)) {
- uint64_t ImmHi16 = (Imm >> 16) & 0xffff;
- unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
- Result = CurDAG->getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
- return CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, SDValue(Result, 0),
- getI32Imm(Imm & 0xffff));
- }
- // 2-2) Patterns : {zeros}{ones}{15-bit value}{zeros}
- // {zeros}{15-bit value}{zeros}
- // {zeros}{ones}{15-bit value}
- // {ones}{15-bit value}{zeros}
- // We can take advantage of LI's sign-extension semantics to generate leading
- // ones, and then use RLDIC to mask off the ones in both sides after rotation.
- if ((LZ + FO + TZ) > 48) {
- Result = CurDAG->getMachineNode(PPC::LI8, dl, MVT::i64,
- getI32Imm((Imm >> TZ) & 0xffff));
- return CurDAG->getMachineNode(PPC::RLDIC, dl, MVT::i64, SDValue(Result, 0),
- getI32Imm(TZ), getI32Imm(LZ));
- }
- // 2-3) Pattern : {zeros}{15-bit value}{ones}
- // Shift right the Imm by (48 - LZ) bits to construct a negtive 16 bits value,
- // therefore we can take advantage of LI's sign-extension semantics, and then
- // mask them off after rotation.
- //
- // +--LZ--||-15-bit-||--TO--+ +-------------|--16-bit--+
- // |00000001bbbbbbbbb1111111| -> |00000000000001bbbbbbbbb1|
- // +------------------------+ +------------------------+
- // 63 0 63 0
- // Imm (Imm >> (48 - LZ) & 0xffff)
- // +----sext-----|--16-bit--+ +clear-|-----------------+
- // |11111111111111bbbbbbbbb1| -> |00000001bbbbbbbbb1111111|
- // +------------------------+ +------------------------+
- // 63 0 63 0
- // LI8: sext many leading zeros RLDICL: rotate left (48 - LZ), clear left LZ
- if ((LZ + TO) > 48) {
- // Since the immediates with (LZ > 32) have been handled by previous
- // patterns, here we have (LZ <= 32) to make sure we will not shift right
- // the Imm by a negative value.
- assert(LZ <= 32 && "Unexpected shift value.");
- Result = CurDAG->getMachineNode(PPC::LI8, dl, MVT::i64,
- getI32Imm((Imm >> (48 - LZ) & 0xffff)));
- return CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, SDValue(Result, 0),
- getI32Imm(48 - LZ), getI32Imm(LZ));
- }
- // 2-4) Patterns : {zeros}{ones}{15-bit value}{ones}
- // {ones}{15-bit value}{ones}
- // We can take advantage of LI's sign-extension semantics to generate leading
- // ones, and then use RLDICL to mask off the ones in left sides (if required)
- // after rotation.
- //
- // +-LZ-FO||-15-bit-||--TO--+ +-------------|--16-bit--+
- // |00011110bbbbbbbbb1111111| -> |000000000011110bbbbbbbbb|
- // +------------------------+ +------------------------+
- // 63 0 63 0
- // Imm (Imm >> TO) & 0xffff
- // +----sext-----|--16-bit--+ +LZ|---------------------+
- // |111111111111110bbbbbbbbb| -> |00011110bbbbbbbbb1111111|
- // +------------------------+ +------------------------+
- // 63 0 63 0
- // LI8: sext many leading zeros RLDICL: rotate left TO, clear left LZ
- if ((LZ + FO + TO) > 48) {
- Result = CurDAG->getMachineNode(PPC::LI8, dl, MVT::i64,
- getI32Imm((Imm >> TO) & 0xffff));
- return CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, SDValue(Result, 0),
- getI32Imm(TO), getI32Imm(LZ));
- }
- // 2-5) Pattern : {32 zeros}{****}{0}{15-bit value}
- // If Hi32 is zero and the Lo16(in Lo32) can be presented as a positive 16 bit
- // value, we can use LI for Lo16 without generating leading ones then add the
- // Hi16(in Lo32).
- if (LZ == 32 && ((Lo32 & 0x8000) == 0)) {
- Result = CurDAG->getMachineNode(PPC::LI8, dl, MVT::i64,
- getI32Imm(Lo32 & 0xffff));
- return CurDAG->getMachineNode(PPC::ORIS8, dl, MVT::i64, SDValue(Result, 0),
- getI32Imm(Lo32 >> 16));
- }
- // 2-6) Patterns : {******}{49 zeros}{******}
- // {******}{49 ones}{******}
- // If the Imm contains 49 consecutive zeros/ones, it means that a total of 15
- // bits remain on both sides. Rotate right the Imm to construct an int<16>
- // value, use LI for int<16> value and then use RLDICL without mask to rotate
- // it back.
- //
- // 1) findContiguousZerosAtLeast(Imm, 49)
- // +------|--zeros-|------+ +---ones--||---15 bit--+
- // |bbbbbb0000000000aaaaaa| -> |0000000000aaaaaabbbbbb|
- // +----------------------+ +----------------------+
- // 63 0 63 0
- //
- // 2) findContiguousZerosAtLeast(~Imm, 49)
- // +------|--ones--|------+ +---ones--||---15 bit--+
- // |bbbbbb1111111111aaaaaa| -> |1111111111aaaaaabbbbbb|
- // +----------------------+ +----------------------+
- // 63 0 63 0
- if ((Shift = findContiguousZerosAtLeast(Imm, 49)) ||
- (Shift = findContiguousZerosAtLeast(~Imm, 49))) {
- uint64_t RotImm = (Imm >> Shift) | (Imm << (64 - Shift));
- Result = CurDAG->getMachineNode(PPC::LI8, dl, MVT::i64,
- getI32Imm(RotImm & 0xffff));
- return CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, SDValue(Result, 0),
- getI32Imm(Shift), getI32Imm(0));
- }
-
- // Following patterns use 3 instructions to materialize the Imm.
- InstCnt = 3;
- // 3-1) Patterns : {zeros}{ones}{31-bit value}{zeros}
- // {zeros}{31-bit value}{zeros}
- // {zeros}{ones}{31-bit value}
- // {ones}{31-bit value}{zeros}
- // We can take advantage of LIS's sign-extension semantics to generate leading
- // ones, add the remaining bits with ORI, and then use RLDIC to mask off the
- // ones in both sides after rotation.
- if ((LZ + FO + TZ) > 32) {
- uint64_t ImmHi16 = (Imm >> (TZ + 16)) & 0xffff;
- unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
- Result = CurDAG->getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
- Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, SDValue(Result, 0),
- getI32Imm((Imm >> TZ) & 0xffff));
- return CurDAG->getMachineNode(PPC::RLDIC, dl, MVT::i64, SDValue(Result, 0),
- getI32Imm(TZ), getI32Imm(LZ));
- }
- // 3-2) Pattern : {zeros}{31-bit value}{ones}
- // Shift right the Imm by (32 - LZ) bits to construct a negtive 32 bits value,
- // therefore we can take advantage of LIS's sign-extension semantics, add
- // the remaining bits with ORI, and then mask them off after rotation.
- // This is similar to Pattern 2-3, please refer to the diagram there.
- if ((LZ + TO) > 32) {
- // Since the immediates with (LZ > 32) have been handled by previous
- // patterns, here we have (LZ <= 32) to make sure we will not shift right
- // the Imm by a negative value.
- assert(LZ <= 32 && "Unexpected shift value.");
- Result = CurDAG->getMachineNode(PPC::LIS8, dl, MVT::i64,
- getI32Imm((Imm >> (48 - LZ)) & 0xffff));
- Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, SDValue(Result, 0),
- getI32Imm((Imm >> (32 - LZ)) & 0xffff));
- return CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, SDValue(Result, 0),
- getI32Imm(32 - LZ), getI32Imm(LZ));
- }
- // 3-3) Patterns : {zeros}{ones}{31-bit value}{ones}
- // {ones}{31-bit value}{ones}
- // We can take advantage of LIS's sign-extension semantics to generate leading
- // ones, add the remaining bits with ORI, and then use RLDICL to mask off the
- // ones in left sides (if required) after rotation.
- // This is similar to Pattern 2-4, please refer to the diagram there.
- if ((LZ + FO + TO) > 32) {
- Result = CurDAG->getMachineNode(PPC::LIS8, dl, MVT::i64,
- getI32Imm((Imm >> (TO + 16)) & 0xffff));
- Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, SDValue(Result, 0),
- getI32Imm((Imm >> TO) & 0xffff));
- return CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, SDValue(Result, 0),
- getI32Imm(TO), getI32Imm(LZ));
- }
- // 3-4) Patterns : High word == Low word
- if (Hi32 == Lo32) {
- // Handle the first 32 bits.
- uint64_t ImmHi16 = (Lo32 >> 16) & 0xffff;
- unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
- Result = CurDAG->getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
- Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, SDValue(Result, 0),
- getI32Imm(Lo32 & 0xffff));
- // Use rldimi to insert the Low word into High word.
- SDValue Ops[] = {SDValue(Result, 0), SDValue(Result, 0), getI32Imm(32),
- getI32Imm(0)};
- return CurDAG->getMachineNode(PPC::RLDIMI, dl, MVT::i64, Ops);
- }
- // 3-5) Patterns : {******}{33 zeros}{******}
- // {******}{33 ones}{******}
- // If the Imm contains 33 consecutive zeros/ones, it means that a total of 31
- // bits remain on both sides. Rotate right the Imm to construct an int<32>
- // value, use LIS + ORI for int<32> value and then use RLDICL without mask to
- // rotate it back.
- // This is similar to Pattern 2-6, please refer to the diagram there.
- if ((Shift = findContiguousZerosAtLeast(Imm, 33)) ||
- (Shift = findContiguousZerosAtLeast(~Imm, 33))) {
- uint64_t RotImm = (Imm >> Shift) | (Imm << (64 - Shift));
- uint64_t ImmHi16 = (RotImm >> 16) & 0xffff;
- unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
- Result = CurDAG->getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
- Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, SDValue(Result, 0),
- getI32Imm(RotImm & 0xffff));
- return CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, SDValue(Result, 0),
- getI32Imm(Shift), getI32Imm(0));
- }
-
- InstCnt = 0;
- return nullptr;
-}
-
-static SDNode *selectI64Imm(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm,
- unsigned *InstCnt = nullptr) {
- unsigned InstCntDirect = 0;
- // No more than 3 instructions is used if we can select the i64 immediate
- // directly.
- SDNode *Result = selectI64ImmDirect(CurDAG, dl, Imm, InstCntDirect);
- if (Result) {
- if (InstCnt)
- *InstCnt = InstCntDirect;
- return Result;
- }
- auto getI32Imm = [CurDAG, dl](unsigned Imm) {
- return CurDAG->getTargetConstant(Imm, dl, MVT::i32);
- };
- // Handle the upper 32 bit value.
- Result =
- selectI64ImmDirect(CurDAG, dl, Imm & 0xffffffff00000000, InstCntDirect);
- // Add in the last bits as required.
- if (uint32_t Hi16 = (Lo_32(Imm) >> 16) & 0xffff) {
- Result = CurDAG->getMachineNode(PPC::ORIS8, dl, MVT::i64,
- SDValue(Result, 0), getI32Imm(Hi16));
- ++InstCntDirect;
- }
- if (uint32_t Lo16 = Lo_32(Imm) & 0xffff) {
- Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, SDValue(Result, 0),
- getI32Imm(Lo16));
- ++InstCntDirect;
- }
- if (InstCnt)
- *InstCnt = InstCntDirect;
- return Result;
-}
-
+// For any 32 < Num < 64, check if the Imm contains at least Num consecutive
+// zeros and return the number of bits by the left of these consecutive zeros.
+static int findContiguousZerosAtLeast(uint64_t Imm, unsigned Num) {
+ unsigned HiTZ = countTrailingZeros<uint32_t>(Hi_32(Imm));
+ unsigned LoLZ = countLeadingZeros<uint32_t>(Lo_32(Imm));
+ if ((HiTZ + LoLZ) >= Num)
+ return (32 + HiTZ);
+ return 0;
+}
+
+// Direct materialization of 64-bit constants by enumerated patterns.
+static SDNode *selectI64ImmDirect(SelectionDAG *CurDAG, const SDLoc &dl,
+ uint64_t Imm, unsigned &InstCnt) {
+ unsigned TZ = countTrailingZeros<uint64_t>(Imm);
+ unsigned LZ = countLeadingZeros<uint64_t>(Imm);
+ unsigned TO = countTrailingOnes<uint64_t>(Imm);
+ unsigned LO = countLeadingOnes<uint64_t>(Imm);
+ unsigned Hi32 = Hi_32(Imm);
+ unsigned Lo32 = Lo_32(Imm);
+ SDNode *Result = nullptr;
+ unsigned Shift = 0;
+
+ auto getI32Imm = [CurDAG, dl](unsigned Imm) {
+ return CurDAG->getTargetConstant(Imm, dl, MVT::i32);
+ };
+
+ // Following patterns use 1 instructions to materialize the Imm.
+ InstCnt = 1;
+ // 1-1) Patterns : {zeros}{15-bit valve}
+ // {ones}{15-bit valve}
+ if (isInt<16>(Imm)) {
+ SDValue SDImm = CurDAG->getTargetConstant(Imm, dl, MVT::i64);
+ return CurDAG->getMachineNode(PPC::LI8, dl, MVT::i64, SDImm);
+ }
+ // 1-2) Patterns : {zeros}{15-bit valve}{16 zeros}
+ // {ones}{15-bit valve}{16 zeros}
+ if (TZ > 15 && (LZ > 32 || LO > 32))
+ return CurDAG->getMachineNode(PPC::LIS8, dl, MVT::i64,
+ getI32Imm((Imm >> 16) & 0xffff));
+
+ // Following patterns use 2 instructions to materialize the Imm.
+ InstCnt = 2;
+ assert(LZ < 64 && "Unexpected leading zeros here.");
+ // Count of ones follwing the leading zeros.
+ unsigned FO = countLeadingOnes<uint64_t>(Imm << LZ);
+ // 2-1) Patterns : {zeros}{31-bit value}
+ // {ones}{31-bit value}
+ if (isInt<32>(Imm)) {
+ uint64_t ImmHi16 = (Imm >> 16) & 0xffff;
+ unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
+ Result = CurDAG->getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
+ return CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, SDValue(Result, 0),
+ getI32Imm(Imm & 0xffff));
+ }
+ // 2-2) Patterns : {zeros}{ones}{15-bit value}{zeros}
+ // {zeros}{15-bit value}{zeros}
+ // {zeros}{ones}{15-bit value}
+ // {ones}{15-bit value}{zeros}
+ // We can take advantage of LI's sign-extension semantics to generate leading
+ // ones, and then use RLDIC to mask off the ones in both sides after rotation.
+ if ((LZ + FO + TZ) > 48) {
+ Result = CurDAG->getMachineNode(PPC::LI8, dl, MVT::i64,
+ getI32Imm((Imm >> TZ) & 0xffff));
+ return CurDAG->getMachineNode(PPC::RLDIC, dl, MVT::i64, SDValue(Result, 0),
+ getI32Imm(TZ), getI32Imm(LZ));
+ }
+ // 2-3) Pattern : {zeros}{15-bit value}{ones}
+ // Shift right the Imm by (48 - LZ) bits to construct a negtive 16 bits value,
+ // therefore we can take advantage of LI's sign-extension semantics, and then
+ // mask them off after rotation.
+ //
+ // +--LZ--||-15-bit-||--TO--+ +-------------|--16-bit--+
+ // |00000001bbbbbbbbb1111111| -> |00000000000001bbbbbbbbb1|
+ // +------------------------+ +------------------------+
+ // 63 0 63 0
+ // Imm (Imm >> (48 - LZ) & 0xffff)
+ // +----sext-----|--16-bit--+ +clear-|-----------------+
+ // |11111111111111bbbbbbbbb1| -> |00000001bbbbbbbbb1111111|
+ // +------------------------+ +------------------------+
+ // 63 0 63 0
+ // LI8: sext many leading zeros RLDICL: rotate left (48 - LZ), clear left LZ
+ if ((LZ + TO) > 48) {
+ // Since the immediates with (LZ > 32) have been handled by previous
+ // patterns, here we have (LZ <= 32) to make sure we will not shift right
+ // the Imm by a negative value.
+ assert(LZ <= 32 && "Unexpected shift value.");
+ Result = CurDAG->getMachineNode(PPC::LI8, dl, MVT::i64,
+ getI32Imm((Imm >> (48 - LZ) & 0xffff)));
+ return CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, SDValue(Result, 0),
+ getI32Imm(48 - LZ), getI32Imm(LZ));
+ }
+ // 2-4) Patterns : {zeros}{ones}{15-bit value}{ones}
+ // {ones}{15-bit value}{ones}
+ // We can take advantage of LI's sign-extension semantics to generate leading
+ // ones, and then use RLDICL to mask off the ones in left sides (if required)
+ // after rotation.
+ //
+ // +-LZ-FO||-15-bit-||--TO--+ +-------------|--16-bit--+
+ // |00011110bbbbbbbbb1111111| -> |000000000011110bbbbbbbbb|
+ // +------------------------+ +------------------------+
+ // 63 0 63 0
+ // Imm (Imm >> TO) & 0xffff
+ // +----sext-----|--16-bit--+ +LZ|---------------------+
+ // |111111111111110bbbbbbbbb| -> |00011110bbbbbbbbb1111111|
+ // +------------------------+ +------------------------+
+ // 63 0 63 0
+ // LI8: sext many leading zeros RLDICL: rotate left TO, clear left LZ
+ if ((LZ + FO + TO) > 48) {
+ Result = CurDAG->getMachineNode(PPC::LI8, dl, MVT::i64,
+ getI32Imm((Imm >> TO) & 0xffff));
+ return CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, SDValue(Result, 0),
+ getI32Imm(TO), getI32Imm(LZ));
+ }
+ // 2-5) Pattern : {32 zeros}{****}{0}{15-bit value}
+ // If Hi32 is zero and the Lo16(in Lo32) can be presented as a positive 16 bit
+ // value, we can use LI for Lo16 without generating leading ones then add the
+ // Hi16(in Lo32).
+ if (LZ == 32 && ((Lo32 & 0x8000) == 0)) {
+ Result = CurDAG->getMachineNode(PPC::LI8, dl, MVT::i64,
+ getI32Imm(Lo32 & 0xffff));
+ return CurDAG->getMachineNode(PPC::ORIS8, dl, MVT::i64, SDValue(Result, 0),
+ getI32Imm(Lo32 >> 16));
+ }
+ // 2-6) Patterns : {******}{49 zeros}{******}
+ // {******}{49 ones}{******}
+ // If the Imm contains 49 consecutive zeros/ones, it means that a total of 15
+ // bits remain on both sides. Rotate right the Imm to construct an int<16>
+ // value, use LI for int<16> value and then use RLDICL without mask to rotate
+ // it back.
+ //
+ // 1) findContiguousZerosAtLeast(Imm, 49)
+ // +------|--zeros-|------+ +---ones--||---15 bit--+
+ // |bbbbbb0000000000aaaaaa| -> |0000000000aaaaaabbbbbb|
+ // +----------------------+ +----------------------+
+ // 63 0 63 0
+ //
+ // 2) findContiguousZerosAtLeast(~Imm, 49)
+ // +------|--ones--|------+ +---ones--||---15 bit--+
+ // |bbbbbb1111111111aaaaaa| -> |1111111111aaaaaabbbbbb|
+ // +----------------------+ +----------------------+
+ // 63 0 63 0
+ if ((Shift = findContiguousZerosAtLeast(Imm, 49)) ||
+ (Shift = findContiguousZerosAtLeast(~Imm, 49))) {
+ uint64_t RotImm = (Imm >> Shift) | (Imm << (64 - Shift));
+ Result = CurDAG->getMachineNode(PPC::LI8, dl, MVT::i64,
+ getI32Imm(RotImm & 0xffff));
+ return CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, SDValue(Result, 0),
+ getI32Imm(Shift), getI32Imm(0));
+ }
+
+ // Following patterns use 3 instructions to materialize the Imm.
+ InstCnt = 3;
+ // 3-1) Patterns : {zeros}{ones}{31-bit value}{zeros}
+ // {zeros}{31-bit value}{zeros}
+ // {zeros}{ones}{31-bit value}
+ // {ones}{31-bit value}{zeros}
+ // We can take advantage of LIS's sign-extension semantics to generate leading
+ // ones, add the remaining bits with ORI, and then use RLDIC to mask off the
+ // ones in both sides after rotation.
+ if ((LZ + FO + TZ) > 32) {
+ uint64_t ImmHi16 = (Imm >> (TZ + 16)) & 0xffff;
+ unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
+ Result = CurDAG->getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
+ Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, SDValue(Result, 0),
+ getI32Imm((Imm >> TZ) & 0xffff));
+ return CurDAG->getMachineNode(PPC::RLDIC, dl, MVT::i64, SDValue(Result, 0),
+ getI32Imm(TZ), getI32Imm(LZ));
+ }
+ // 3-2) Pattern : {zeros}{31-bit value}{ones}
+ // Shift right the Imm by (32 - LZ) bits to construct a negtive 32 bits value,
+ // therefore we can take advantage of LIS's sign-extension semantics, add
+ // the remaining bits with ORI, and then mask them off after rotation.
+ // This is similar to Pattern 2-3, please refer to the diagram there.
+ if ((LZ + TO) > 32) {
+ // Since the immediates with (LZ > 32) have been handled by previous
+ // patterns, here we have (LZ <= 32) to make sure we will not shift right
+ // the Imm by a negative value.
+ assert(LZ <= 32 && "Unexpected shift value.");
+ Result = CurDAG->getMachineNode(PPC::LIS8, dl, MVT::i64,
+ getI32Imm((Imm >> (48 - LZ)) & 0xffff));
+ Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, SDValue(Result, 0),
+ getI32Imm((Imm >> (32 - LZ)) & 0xffff));
+ return CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, SDValue(Result, 0),
+ getI32Imm(32 - LZ), getI32Imm(LZ));
+ }
+ // 3-3) Patterns : {zeros}{ones}{31-bit value}{ones}
+ // {ones}{31-bit value}{ones}
+ // We can take advantage of LIS's sign-extension semantics to generate leading
+ // ones, add the remaining bits with ORI, and then use RLDICL to mask off the
+ // ones in left sides (if required) after rotation.
+ // This is similar to Pattern 2-4, please refer to the diagram there.
+ if ((LZ + FO + TO) > 32) {
+ Result = CurDAG->getMachineNode(PPC::LIS8, dl, MVT::i64,
+ getI32Imm((Imm >> (TO + 16)) & 0xffff));
+ Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, SDValue(Result, 0),
+ getI32Imm((Imm >> TO) & 0xffff));
+ return CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, SDValue(Result, 0),
+ getI32Imm(TO), getI32Imm(LZ));
+ }
+ // 3-4) Patterns : High word == Low word
+ if (Hi32 == Lo32) {
+ // Handle the first 32 bits.
+ uint64_t ImmHi16 = (Lo32 >> 16) & 0xffff;
+ unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
+ Result = CurDAG->getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
+ Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, SDValue(Result, 0),
+ getI32Imm(Lo32 & 0xffff));
+ // Use rldimi to insert the Low word into High word.
+ SDValue Ops[] = {SDValue(Result, 0), SDValue(Result, 0), getI32Imm(32),
+ getI32Imm(0)};
+ return CurDAG->getMachineNode(PPC::RLDIMI, dl, MVT::i64, Ops);
+ }
+ // 3-5) Patterns : {******}{33 zeros}{******}
+ // {******}{33 ones}{******}
+ // If the Imm contains 33 consecutive zeros/ones, it means that a total of 31
+ // bits remain on both sides. Rotate right the Imm to construct an int<32>
+ // value, use LIS + ORI for int<32> value and then use RLDICL without mask to
+ // rotate it back.
+ // This is similar to Pattern 2-6, please refer to the diagram there.
+ if ((Shift = findContiguousZerosAtLeast(Imm, 33)) ||
+ (Shift = findContiguousZerosAtLeast(~Imm, 33))) {
+ uint64_t RotImm = (Imm >> Shift) | (Imm << (64 - Shift));
+ uint64_t ImmHi16 = (RotImm >> 16) & 0xffff;
+ unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
+ Result = CurDAG->getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
+ Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, SDValue(Result, 0),
+ getI32Imm(RotImm & 0xffff));
+ return CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, SDValue(Result, 0),
+ getI32Imm(Shift), getI32Imm(0));
+ }
+
+ InstCnt = 0;
+ return nullptr;
+}
+
+static SDNode *selectI64Imm(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm,
+ unsigned *InstCnt = nullptr) {
+ unsigned InstCntDirect = 0;
+ // No more than 3 instructions is used if we can select the i64 immediate
+ // directly.
+ SDNode *Result = selectI64ImmDirect(CurDAG, dl, Imm, InstCntDirect);
+ if (Result) {
+ if (InstCnt)
+ *InstCnt = InstCntDirect;
+ return Result;
+ }
+ auto getI32Imm = [CurDAG, dl](unsigned Imm) {
+ return CurDAG->getTargetConstant(Imm, dl, MVT::i32);
+ };
+ // Handle the upper 32 bit value.
+ Result =
+ selectI64ImmDirect(CurDAG, dl, Imm & 0xffffffff00000000, InstCntDirect);
+ // Add in the last bits as required.
+ if (uint32_t Hi16 = (Lo_32(Imm) >> 16) & 0xffff) {
+ Result = CurDAG->getMachineNode(PPC::ORIS8, dl, MVT::i64,
+ SDValue(Result, 0), getI32Imm(Hi16));
+ ++InstCntDirect;
+ }
+ if (uint32_t Lo16 = Lo_32(Imm) & 0xffff) {
+ Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, SDValue(Result, 0),
+ getI32Imm(Lo16));
+ ++InstCntDirect;
+ }
+ if (InstCnt)
+ *InstCnt = InstCntDirect;
+ return Result;
+}
+
// Select a 64-bit constant.
static SDNode *selectI64Imm(SelectionDAG *CurDAG, SDNode *N) {
SDLoc dl(N);
@@ -1218,7 +1218,7 @@ class BitPermutationSelector {
}
break;
case ISD::SHL:
- case PPCISD::SHL:
+ case PPCISD::SHL:
if (isa<ConstantSDNode>(V.getOperand(1))) {
unsigned ShiftAmt = V.getConstantOperandVal(1);
@@ -1234,7 +1234,7 @@ class BitPermutationSelector {
}
break;
case ISD::SRL:
- case PPCISD::SRL:
+ case PPCISD::SRL:
if (isa<ConstantSDNode>(V.getOperand(1))) {
unsigned ShiftAmt = V.getConstantOperandVal(1);
@@ -2114,14 +2114,14 @@ class BitPermutationSelector {
unsigned NumAndInsts = (unsigned) NeedsRotate +
(unsigned) (bool) Res;
- unsigned NumOfSelectInsts = 0;
- selectI64Imm(CurDAG, dl, Mask, &NumOfSelectInsts);
- assert(NumOfSelectInsts > 0 && "Failed to select an i64 constant.");
+ unsigned NumOfSelectInsts = 0;
+ selectI64Imm(CurDAG, dl, Mask, &NumOfSelectInsts);
+ assert(NumOfSelectInsts > 0 && "Failed to select an i64 constant.");
if (Use32BitInsts)
NumAndInsts += (unsigned) (ANDIMask != 0) + (unsigned) (ANDISMask != 0) +
(unsigned) (ANDIMask != 0 && ANDISMask != 0);
else
- NumAndInsts += NumOfSelectInsts + /* and */ 1;
+ NumAndInsts += NumOfSelectInsts + /* and */ 1;
unsigned NumRLInsts = 0;
bool FirstBG = true;
@@ -2345,14 +2345,14 @@ class BitPermutationSelector {
Res = SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
ExtendToInt64(ANDIVal, dl), ANDISVal), 0);
} else {
- unsigned NumOfSelectInsts = 0;
- SDValue MaskVal =
- SDValue(selectI64Imm(CurDAG, dl, Mask, &NumOfSelectInsts), 0);
- Res = SDValue(CurDAG->getMachineNode(PPC::AND8, dl, MVT::i64,
- ExtendToInt64(Res, dl), MaskVal),
- 0);
- if (InstCnt)
- *InstCnt += NumOfSelectInsts + /* and */ 1;
+ unsigned NumOfSelectInsts = 0;
+ SDValue MaskVal =
+ SDValue(selectI64Imm(CurDAG, dl, Mask, &NumOfSelectInsts), 0);
+ Res = SDValue(CurDAG->getMachineNode(PPC::AND8, dl, MVT::i64,
+ ExtendToInt64(Res, dl), MaskVal),
+ 0);
+ if (InstCnt)
+ *InstCnt += NumOfSelectInsts + /* and */ 1;
}
}
@@ -2383,7 +2383,7 @@ class BitPermutationSelector {
}
void eraseMatchingBitGroups(function_ref<bool(const BitGroup &)> F) {
- erase_if(BitGroups, F);
+ erase_if(BitGroups, F);
}
SmallVector<ValueBit, 64> Bits;
@@ -3633,12 +3633,12 @@ bool PPCDAGToDAGISel::tryIntCompareInGPR(SDNode *N) {
if (TM.getOptLevel() == CodeGenOpt::None || !TM.isPPC64())
return false;
- // For POWER10, it is more profitable to use the set boolean extension
- // instructions rather than the integer compare elimination codegen.
- // Users can override this via the command line option, `--ppc-gpr-icmps`.
- if (!(CmpInGPR.getNumOccurrences() > 0) && Subtarget->isISA3_1())
- return false;
-
+ // For POWER10, it is more profitable to use the set boolean extension
+ // instructions rather than the integer compare elimination codegen.
+ // Users can override this via the command line option, `--ppc-gpr-icmps`.
+ if (!(CmpInGPR.getNumOccurrences() > 0) && Subtarget->isISA3_1())
+ return false;
+
switch (N->getOpcode()) {
default: break;
case ISD::ZERO_EXTEND:
@@ -3686,7 +3686,7 @@ bool PPCDAGToDAGISel::tryBitPermutation(SDNode *N) {
/// SelectCC - Select a comparison of the specified values with the specified
/// condition code, returning the CR# of the expression.
SDValue PPCDAGToDAGISel::SelectCC(SDValue LHS, SDValue RHS, ISD::CondCode CC,
- const SDLoc &dl, SDValue Chain) {
+ const SDLoc &dl, SDValue Chain) {
// Always select the LHS.
unsigned Opc;
@@ -3839,12 +3839,12 @@ SDValue PPCDAGToDAGISel::SelectCC(SDValue LHS, SDValue RHS, ISD::CondCode CC,
assert(Subtarget->hasVSX() && "__float128 requires VSX");
Opc = PPC::XSCMPUQP;
}
- if (Chain)
- return SDValue(
- CurDAG->getMachineNode(Opc, dl, MVT::i32, MVT::Other, LHS, RHS, Chain),
- 0);
- else
- return SDValue(CurDAG->getMachineNode(Opc, dl, MVT::i32, LHS, RHS), 0);
+ if (Chain)
+ return SDValue(
+ CurDAG->getMachineNode(Opc, dl, MVT::i32, MVT::Other, LHS, RHS, Chain),
+ 0);
+ else
+ return SDValue(CurDAG->getMachineNode(Opc, dl, MVT::i32, LHS, RHS), 0);
}
static PPC::Predicate getPredicateForSetCC(ISD::CondCode CC, const EVT &VT,
@@ -3919,8 +3919,8 @@ static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool &Invert) {
// getVCmpInst: return the vector compare instruction for the specified
// vector type and condition code. Since this is for altivec specific code,
-// only support the altivec types (v16i8, v8i16, v4i32, v2i64, v1i128,
-// and v4f32).
+// only support the altivec types (v16i8, v8i16, v4i32, v2i64, v1i128,
+// and v4f32).
static unsigned int getVCmpInst(MVT VecVT, ISD::CondCode CC,
bool HasVSX, bool &Swap, bool &Negate) {
Swap = false;
@@ -4001,8 +4001,8 @@ static unsigned int getVCmpInst(MVT VecVT, ISD::CondCode CC,
return PPC::VCMPEQUW;
else if (VecVT == MVT::v2i64)
return PPC::VCMPEQUD;
- else if (VecVT == MVT::v1i128)
- return PPC::VCMPEQUQ;
+ else if (VecVT == MVT::v1i128)
+ return PPC::VCMPEQUQ;
break;
case ISD::SETGT:
if (VecVT == MVT::v16i8)
@@ -4013,8 +4013,8 @@ static unsigned int getVCmpInst(MVT VecVT, ISD::CondCode CC,
return PPC::VCMPGTSW;
else if (VecVT == MVT::v2i64)
return PPC::VCMPGTSD;
- else if (VecVT == MVT::v1i128)
- return PPC::VCMPGTSQ;
+ else if (VecVT == MVT::v1i128)
+ return PPC::VCMPGTSQ;
break;
case ISD::SETUGT:
if (VecVT == MVT::v16i8)
@@ -4025,8 +4025,8 @@ static unsigned int getVCmpInst(MVT VecVT, ISD::CondCode CC,
return PPC::VCMPGTUW;
else if (VecVT == MVT::v2i64)
return PPC::VCMPGTUD;
- else if (VecVT == MVT::v1i128)
- return PPC::VCMPGTUQ;
+ else if (VecVT == MVT::v1i128)
+ return PPC::VCMPGTUQ;
break;
default:
break;
@@ -4038,23 +4038,23 @@ static unsigned int getVCmpInst(MVT VecVT, ISD::CondCode CC,
bool PPCDAGToDAGISel::trySETCC(SDNode *N) {
SDLoc dl(N);
unsigned Imm;
- bool IsStrict = N->isStrictFPOpcode();
- ISD::CondCode CC =
- cast<CondCodeSDNode>(N->getOperand(IsStrict ? 3 : 2))->get();
+ bool IsStrict = N->isStrictFPOpcode();
+ ISD::CondCode CC =
+ cast<CondCodeSDNode>(N->getOperand(IsStrict ? 3 : 2))->get();
EVT PtrVT =
CurDAG->getTargetLoweringInfo().getPointerTy(CurDAG->getDataLayout());
bool isPPC64 = (PtrVT == MVT::i64);
- SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
+ SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
+
+ SDValue LHS = N->getOperand(IsStrict ? 1 : 0);
+ SDValue RHS = N->getOperand(IsStrict ? 2 : 1);
- SDValue LHS = N->getOperand(IsStrict ? 1 : 0);
- SDValue RHS = N->getOperand(IsStrict ? 2 : 1);
-
- if (!IsStrict && !Subtarget->useCRBits() && isInt32Immediate(RHS, Imm)) {
+ if (!IsStrict && !Subtarget->useCRBits() && isInt32Immediate(RHS, Imm)) {
// We can codegen setcc op, imm very efficiently compared to a brcond.
// Check for those cases here.
// setcc op, 0
if (Imm == 0) {
- SDValue Op = LHS;
+ SDValue Op = LHS;
switch (CC) {
default: break;
case ISD::SETEQ: {
@@ -4089,7 +4089,7 @@ bool PPCDAGToDAGISel::trySETCC(SDNode *N) {
}
}
} else if (Imm == ~0U) { // setcc op, -1
- SDValue Op = LHS;
+ SDValue Op = LHS;
switch (CC) {
default: break;
case ISD::SETEQ:
@@ -4134,8 +4134,8 @@ bool PPCDAGToDAGISel::trySETCC(SDNode *N) {
// Altivec Vector compare instructions do not set any CR register by default and
// vector compare operations return the same type as the operands.
- if (!IsStrict && LHS.getValueType().isVector()) {
- if (Subtarget->hasSPE())
+ if (!IsStrict && LHS.getValueType().isVector()) {
+ if (Subtarget->hasSPE())
return false;
EVT VecVT = LHS.getValueType();
@@ -4162,9 +4162,9 @@ bool PPCDAGToDAGISel::trySETCC(SDNode *N) {
bool Inv;
unsigned Idx = getCRIdxForSetCC(CC, Inv);
- SDValue CCReg = SelectCC(LHS, RHS, CC, dl, Chain);
- if (IsStrict)
- CurDAG->ReplaceAllUsesOfValueWith(SDValue(N, 1), CCReg.getValue(1));
+ SDValue CCReg = SelectCC(LHS, RHS, CC, dl, Chain);
+ if (IsStrict)
+ CurDAG->ReplaceAllUsesOfValueWith(SDValue(N, 1), CCReg.getValue(1));
SDValue IntCR;
// SPE e*cmp* instructions only set the 'gt' bit, so hard-code that
@@ -4267,10 +4267,10 @@ static bool mayUseP9Setb(SDNode *N, const ISD::CondCode &CC, SelectionDAG *DAG,
(FalseRes.getOpcode() != ISD::SELECT_CC || CC != ISD::SETEQ)))
return false;
- SDValue SetOrSelCC = FalseRes.getOpcode() == ISD::SELECT_CC
- ? FalseRes
- : FalseRes.getOperand(0);
- bool InnerIsSel = SetOrSelCC.getOpcode() == ISD::SELECT_CC;
+ SDValue SetOrSelCC = FalseRes.getOpcode() == ISD::SELECT_CC
+ ? FalseRes
+ : FalseRes.getOperand(0);
+ bool InnerIsSel = SetOrSelCC.getOpcode() == ISD::SELECT_CC;
if (SetOrSelCC.getOpcode() != ISD::SETCC &&
SetOrSelCC.getOpcode() != ISD::SELECT_CC)
return false;
@@ -4379,81 +4379,81 @@ static bool mayUseP9Setb(SDNode *N, const ISD::CondCode &CC, SelectionDAG *DAG,
return true;
}
-// Return true if it's a software square-root/divide operand.
-static bool isSWTestOp(SDValue N) {
- if (N.getOpcode() == PPCISD::FTSQRT)
- return true;
- if (N.getNumOperands() < 1 || !isa<ConstantSDNode>(N.getOperand(0)))
- return false;
- switch (N.getConstantOperandVal(0)) {
- case Intrinsic::ppc_vsx_xvtdivdp:
- case Intrinsic::ppc_vsx_xvtdivsp:
- case Intrinsic::ppc_vsx_xvtsqrtdp:
- case Intrinsic::ppc_vsx_xvtsqrtsp:
- return true;
- }
- return false;
-}
-
-bool PPCDAGToDAGISel::tryFoldSWTestBRCC(SDNode *N) {
- assert(N->getOpcode() == ISD::BR_CC && "ISD::BR_CC is expected.");
- // We are looking for following patterns, where `truncate to i1` actually has
- // the same semantic with `and 1`.
- // (br_cc seteq, (truncateToi1 SWTestOp), 0) -> (BCC PRED_NU, SWTestOp)
- // (br_cc seteq, (and SWTestOp, 2), 0) -> (BCC PRED_NE, SWTestOp)
- // (br_cc seteq, (and SWTestOp, 4), 0) -> (BCC PRED_LE, SWTestOp)
- // (br_cc seteq, (and SWTestOp, 8), 0) -> (BCC PRED_GE, SWTestOp)
- // (br_cc setne, (truncateToi1 SWTestOp), 0) -> (BCC PRED_UN, SWTestOp)
- // (br_cc setne, (and SWTestOp, 2), 0) -> (BCC PRED_EQ, SWTestOp)
- // (br_cc setne, (and SWTestOp, 4), 0) -> (BCC PRED_GT, SWTestOp)
- // (br_cc setne, (and SWTestOp, 8), 0) -> (BCC PRED_LT, SWTestOp)
- ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(1))->get();
- if (CC != ISD::SETEQ && CC != ISD::SETNE)
- return false;
-
- SDValue CmpRHS = N->getOperand(3);
- if (!isa<ConstantSDNode>(CmpRHS) ||
- cast<ConstantSDNode>(CmpRHS)->getSExtValue() != 0)
- return false;
-
- SDValue CmpLHS = N->getOperand(2);
- if (CmpLHS.getNumOperands() < 1 || !isSWTestOp(CmpLHS.getOperand(0)))
- return false;
-
- unsigned PCC = 0;
- bool IsCCNE = CC == ISD::SETNE;
- if (CmpLHS.getOpcode() == ISD::AND &&
- isa<ConstantSDNode>(CmpLHS.getOperand(1)))
- switch (CmpLHS.getConstantOperandVal(1)) {
- case 1:
- PCC = IsCCNE ? PPC::PRED_UN : PPC::PRED_NU;
- break;
- case 2:
- PCC = IsCCNE ? PPC::PRED_EQ : PPC::PRED_NE;
- break;
- case 4:
- PCC = IsCCNE ? PPC::PRED_GT : PPC::PRED_LE;
- break;
- case 8:
- PCC = IsCCNE ? PPC::PRED_LT : PPC::PRED_GE;
- break;
- default:
- return false;
- }
- else if (CmpLHS.getOpcode() == ISD::TRUNCATE &&
- CmpLHS.getValueType() == MVT::i1)
- PCC = IsCCNE ? PPC::PRED_UN : PPC::PRED_NU;
-
- if (PCC) {
- SDLoc dl(N);
- SDValue Ops[] = {getI32Imm(PCC, dl), CmpLHS.getOperand(0), N->getOperand(4),
- N->getOperand(0)};
- CurDAG->SelectNodeTo(N, PPC::BCC, MVT::Other, Ops);
- return true;
- }
- return false;
-}
-
+// Return true if it's a software square-root/divide operand.
+static bool isSWTestOp(SDValue N) {
+ if (N.getOpcode() == PPCISD::FTSQRT)
+ return true;
+ if (N.getNumOperands() < 1 || !isa<ConstantSDNode>(N.getOperand(0)))
+ return false;
+ switch (N.getConstantOperandVal(0)) {
+ case Intrinsic::ppc_vsx_xvtdivdp:
+ case Intrinsic::ppc_vsx_xvtdivsp:
+ case Intrinsic::ppc_vsx_xvtsqrtdp:
+ case Intrinsic::ppc_vsx_xvtsqrtsp:
+ return true;
+ }
+ return false;
+}
+
+bool PPCDAGToDAGISel::tryFoldSWTestBRCC(SDNode *N) {
+ assert(N->getOpcode() == ISD::BR_CC && "ISD::BR_CC is expected.");
+ // We are looking for following patterns, where `truncate to i1` actually has
+ // the same semantic with `and 1`.
+ // (br_cc seteq, (truncateToi1 SWTestOp), 0) -> (BCC PRED_NU, SWTestOp)
+ // (br_cc seteq, (and SWTestOp, 2), 0) -> (BCC PRED_NE, SWTestOp)
+ // (br_cc seteq, (and SWTestOp, 4), 0) -> (BCC PRED_LE, SWTestOp)
+ // (br_cc seteq, (and SWTestOp, 8), 0) -> (BCC PRED_GE, SWTestOp)
+ // (br_cc setne, (truncateToi1 SWTestOp), 0) -> (BCC PRED_UN, SWTestOp)
+ // (br_cc setne, (and SWTestOp, 2), 0) -> (BCC PRED_EQ, SWTestOp)
+ // (br_cc setne, (and SWTestOp, 4), 0) -> (BCC PRED_GT, SWTestOp)
+ // (br_cc setne, (and SWTestOp, 8), 0) -> (BCC PRED_LT, SWTestOp)
+ ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(1))->get();
+ if (CC != ISD::SETEQ && CC != ISD::SETNE)
+ return false;
+
+ SDValue CmpRHS = N->getOperand(3);
+ if (!isa<ConstantSDNode>(CmpRHS) ||
+ cast<ConstantSDNode>(CmpRHS)->getSExtValue() != 0)
+ return false;
+
+ SDValue CmpLHS = N->getOperand(2);
+ if (CmpLHS.getNumOperands() < 1 || !isSWTestOp(CmpLHS.getOperand(0)))
+ return false;
+
+ unsigned PCC = 0;
+ bool IsCCNE = CC == ISD::SETNE;
+ if (CmpLHS.getOpcode() == ISD::AND &&
+ isa<ConstantSDNode>(CmpLHS.getOperand(1)))
+ switch (CmpLHS.getConstantOperandVal(1)) {
+ case 1:
+ PCC = IsCCNE ? PPC::PRED_UN : PPC::PRED_NU;
+ break;
+ case 2:
+ PCC = IsCCNE ? PPC::PRED_EQ : PPC::PRED_NE;
+ break;
+ case 4:
+ PCC = IsCCNE ? PPC::PRED_GT : PPC::PRED_LE;
+ break;
+ case 8:
+ PCC = IsCCNE ? PPC::PRED_LT : PPC::PRED_GE;
+ break;
+ default:
+ return false;
+ }
+ else if (CmpLHS.getOpcode() == ISD::TRUNCATE &&
+ CmpLHS.getValueType() == MVT::i1)
+ PCC = IsCCNE ? PPC::PRED_UN : PPC::PRED_NU;
+
+ if (PCC) {
+ SDLoc dl(N);
+ SDValue Ops[] = {getI32Imm(PCC, dl), CmpLHS.getOperand(0), N->getOperand(4),
+ N->getOperand(0)};
+ CurDAG->SelectNodeTo(N, PPC::BCC, MVT::Other, Ops);
+ return true;
+ }
+ return false;
+}
+
bool PPCDAGToDAGISel::tryAsSingleRLWINM(SDNode *N) {
assert(N->getOpcode() == ISD::AND && "ISD::AND SDNode expected");
unsigned Imm;
@@ -4733,48 +4733,48 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
}
break;
- case ISD::INTRINSIC_WO_CHAIN: {
- if (!Subtarget->isISA3_1())
- break;
- unsigned Opcode = 0;
- switch (N->getConstantOperandVal(0)) {
- default:
- break;
- case Intrinsic::ppc_altivec_vstribr_p:
- Opcode = PPC::VSTRIBR_rec;
- break;
- case Intrinsic::ppc_altivec_vstribl_p:
- Opcode = PPC::VSTRIBL_rec;
- break;
- case Intrinsic::ppc_altivec_vstrihr_p:
- Opcode = PPC::VSTRIHR_rec;
- break;
- case Intrinsic::ppc_altivec_vstrihl_p:
- Opcode = PPC::VSTRIHL_rec;
- break;
- }
- if (!Opcode)
- break;
-
- // Generate the appropriate vector string isolate intrinsic to match.
- EVT VTs[] = {MVT::v16i8, MVT::Glue};
- SDValue VecStrOp =
- SDValue(CurDAG->getMachineNode(Opcode, dl, VTs, N->getOperand(2)), 0);
- // Vector string isolate instructions update the EQ bit of CR6.
- // Generate a SETBC instruction to extract the bit and place it in a GPR.
- SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_eq, dl, MVT::i32);
- SDValue CR6Reg = CurDAG->getRegister(PPC::CR6, MVT::i32);
- SDValue CRBit = SDValue(
- CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
- CR6Reg, SubRegIdx, VecStrOp.getValue(1)),
- 0);
- CurDAG->SelectNodeTo(N, PPC::SETBC, MVT::i32, CRBit);
- return;
- }
-
+ case ISD::INTRINSIC_WO_CHAIN: {
+ if (!Subtarget->isISA3_1())
+ break;
+ unsigned Opcode = 0;
+ switch (N->getConstantOperandVal(0)) {
+ default:
+ break;
+ case Intrinsic::ppc_altivec_vstribr_p:
+ Opcode = PPC::VSTRIBR_rec;
+ break;
+ case Intrinsic::ppc_altivec_vstribl_p:
+ Opcode = PPC::VSTRIBL_rec;
+ break;
+ case Intrinsic::ppc_altivec_vstrihr_p:
+ Opcode = PPC::VSTRIHR_rec;
+ break;
+ case Intrinsic::ppc_altivec_vstrihl_p:
+ Opcode = PPC::VSTRIHL_rec;
+ break;
+ }
+ if (!Opcode)
+ break;
+
+ // Generate the appropriate vector string isolate intrinsic to match.
+ EVT VTs[] = {MVT::v16i8, MVT::Glue};
+ SDValue VecStrOp =
+ SDValue(CurDAG->getMachineNode(Opcode, dl, VTs, N->getOperand(2)), 0);
+ // Vector string isolate instructions update the EQ bit of CR6.
+ // Generate a SETBC instruction to extract the bit and place it in a GPR.
+ SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_eq, dl, MVT::i32);
+ SDValue CR6Reg = CurDAG->getRegister(PPC::CR6, MVT::i32);
+ SDValue CRBit = SDValue(
+ CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
+ CR6Reg, SubRegIdx, VecStrOp.getValue(1)),
+ 0);
+ CurDAG->SelectNodeTo(N, PPC::SETBC, MVT::i32, CRBit);
+ return;
+ }
+
case ISD::SETCC:
- case ISD::STRICT_FSETCC:
- case ISD::STRICT_FSETCCS:
+ case ISD::STRICT_FSETCC:
+ case ISD::STRICT_FSETCCS:
if (trySETCC(N))
return;
break;
@@ -5072,32 +5072,32 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
// Other cases are autogenerated.
break;
}
- case ISD::MUL: {
- SDValue Op1 = N->getOperand(1);
- if (Op1.getOpcode() != ISD::Constant || Op1.getValueType() != MVT::i64)
- break;
-
- // If the multiplier fits int16, we can handle it with mulli.
- int64_t Imm = cast<ConstantSDNode>(Op1)->getZExtValue();
- unsigned Shift = countTrailingZeros<uint64_t>(Imm);
- if (isInt<16>(Imm) || !Shift)
- break;
-
- // If the shifted value fits int16, we can do this transformation:
- // (mul X, c1 << c2) -> (rldicr (mulli X, c1) c2). We do this in ISEL due to
- // DAGCombiner prefers (shl (mul X, c1), c2) -> (mul X, c1 << c2).
- uint64_t ImmSh = Imm >> Shift;
- if (isInt<16>(ImmSh)) {
- uint64_t SextImm = SignExtend64(ImmSh & 0xFFFF, 16);
- SDValue SDImm = CurDAG->getTargetConstant(SextImm, dl, MVT::i64);
- SDNode *MulNode = CurDAG->getMachineNode(PPC::MULLI8, dl, MVT::i64,
- N->getOperand(0), SDImm);
- CurDAG->SelectNodeTo(N, PPC::RLDICR, MVT::i64, SDValue(MulNode, 0),
- getI32Imm(Shift, dl), getI32Imm(63 - Shift, dl));
- return;
- }
- break;
- }
+ case ISD::MUL: {
+ SDValue Op1 = N->getOperand(1);
+ if (Op1.getOpcode() != ISD::Constant || Op1.getValueType() != MVT::i64)
+ break;
+
+ // If the multiplier fits int16, we can handle it with mulli.
+ int64_t Imm = cast<ConstantSDNode>(Op1)->getZExtValue();
+ unsigned Shift = countTrailingZeros<uint64_t>(Imm);
+ if (isInt<16>(Imm) || !Shift)
+ break;
+
+ // If the shifted value fits int16, we can do this transformation:
+ // (mul X, c1 << c2) -> (rldicr (mulli X, c1) c2). We do this in ISEL due to
+ // DAGCombiner prefers (shl (mul X, c1), c2) -> (mul X, c1 << c2).
+ uint64_t ImmSh = Imm >> Shift;
+ if (isInt<16>(ImmSh)) {
+ uint64_t SextImm = SignExtend64(ImmSh & 0xFFFF, 16);
+ SDValue SDImm = CurDAG->getTargetConstant(SextImm, dl, MVT::i64);
+ SDNode *MulNode = CurDAG->getMachineNode(PPC::MULLI8, dl, MVT::i64,
+ N->getOperand(0), SDImm);
+ CurDAG->SelectNodeTo(N, PPC::RLDICR, MVT::i64, SDValue(MulNode, 0),
+ getI32Imm(Shift, dl), getI32Imm(63 - Shift, dl));
+ return;
+ }
+ break;
+ }
// FIXME: Remove this once the ANDI glue bug is fixed:
case PPCISD::ANDI_rec_1_EQ_BIT:
case PPCISD::ANDI_rec_1_GT_BIT: {
@@ -5323,8 +5323,8 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
return;
}
case ISD::BR_CC: {
- if (tryFoldSWTestBRCC(N))
- return;
+ if (tryFoldSWTestBRCC(N))
+ return;
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(1))->get();
unsigned PCC =
getPredicateForSetCC(CC, N->getOperand(2).getValueType(), Subtarget);
@@ -5896,13 +5896,13 @@ bool PPCDAGToDAGISel::AllUsersSelectZero(SDNode *N) {
User->getMachineOpcode() != PPC::SELECT_I8)
return false;
- SDNode *Op1 = User->getOperand(1).getNode();
+ SDNode *Op1 = User->getOperand(1).getNode();
SDNode *Op2 = User->getOperand(2).getNode();
- // If we have a degenerate select with two equal operands, swapping will
- // not do anything, and we may run into an infinite loop.
- if (Op1 == Op2)
- return false;
-
+ // If we have a degenerate select with two equal operands, swapping will
+ // not do anything, and we may run into an infinite loop.
+ if (Op1 == Op2)
+ return false;
+
if (!Op2->isMachineOpcode())
return false;
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCISelLowering.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCISelLowering.cpp
index 69a2ed730d..26dc3afc89 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -74,7 +74,7 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCSectionXCOFF.h"
+#include "llvm/MC/MCSectionXCOFF.h"
#include "llvm/MC/MCSymbolXCOFF.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/BranchProbability.h"
@@ -121,11 +121,11 @@ cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden);
static cl::opt<bool> UseAbsoluteJumpTables("ppc-use-absolute-jumptables",
cl::desc("use absolute jump tables on ppc"), cl::Hidden);
-// TODO - Remove this option if soft fp128 has been fully supported .
-static cl::opt<bool>
- EnableSoftFP128("enable-soft-fp128",
- cl::desc("temp option to enable soft fp128"), cl::Hidden);
-
+// TODO - Remove this option if soft fp128 has been fully supported .
+static cl::opt<bool>
+ EnableSoftFP128("enable-soft-fp128",
+ cl::desc("temp option to enable soft fp128"), cl::Hidden);
+
STATISTIC(NumTailCalls, "Number of tail calls");
STATISTIC(NumSiblingCalls, "Number of sibling calls");
STATISTIC(ShufflesHandledWithVPERM, "Number of shuffles lowered to a VPERM");
@@ -151,9 +151,9 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
if (!useSoftFloat()) {
if (hasSPE()) {
addRegisterClass(MVT::f32, &PPC::GPRCRegClass);
- // EFPU2 APU only supports f32
- if (!Subtarget.hasEFPU2())
- addRegisterClass(MVT::f64, &PPC::SPERCRegClass);
+ // EFPU2 APU only supports f32
+ if (!Subtarget.hasEFPU2())
+ addRegisterClass(MVT::f64, &PPC::SPERCRegClass);
} else {
addRegisterClass(MVT::f32, &PPC::F4RCRegClass);
addRegisterClass(MVT::f64, &PPC::F8RCRegClass);
@@ -167,10 +167,10 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
// Sub-word ATOMIC_CMP_SWAP need to ensure that the input is zero-extended.
setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, Custom);
- // Custom lower inline assembly to check for special registers.
- setOperationAction(ISD::INLINEASM, MVT::Other, Custom);
- setOperationAction(ISD::INLINEASM_BR, MVT::Other, Custom);
-
+ // Custom lower inline assembly to check for special registers.
+ setOperationAction(ISD::INLINEASM, MVT::Other, Custom);
+ setOperationAction(ISD::INLINEASM_BR, MVT::Other, Custom);
+
// PowerPC has an i16 but no i8 (or i1) SEXTLOAD.
for (MVT VT : MVT::integer_valuetypes()) {
setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote);
@@ -227,36 +227,36 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
if (isPPC64 || Subtarget.hasFPCVT()) {
- setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i1, Promote);
- AddPromotedToType(ISD::STRICT_SINT_TO_FP, MVT::i1,
- isPPC64 ? MVT::i64 : MVT::i32);
- setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i1, Promote);
- AddPromotedToType(ISD::STRICT_UINT_TO_FP, MVT::i1,
- isPPC64 ? MVT::i64 : MVT::i32);
-
+ setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i1, Promote);
+ AddPromotedToType(ISD::STRICT_SINT_TO_FP, MVT::i1,
+ isPPC64 ? MVT::i64 : MVT::i32);
+ setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i1, Promote);
+ AddPromotedToType(ISD::STRICT_UINT_TO_FP, MVT::i1,
+ isPPC64 ? MVT::i64 : MVT::i32);
+
setOperationAction(ISD::SINT_TO_FP, MVT::i1, Promote);
AddPromotedToType (ISD::SINT_TO_FP, MVT::i1,
isPPC64 ? MVT::i64 : MVT::i32);
setOperationAction(ISD::UINT_TO_FP, MVT::i1, Promote);
AddPromotedToType(ISD::UINT_TO_FP, MVT::i1,
isPPC64 ? MVT::i64 : MVT::i32);
-
- setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i1, Promote);
- AddPromotedToType(ISD::STRICT_FP_TO_SINT, MVT::i1,
- isPPC64 ? MVT::i64 : MVT::i32);
- setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i1, Promote);
- AddPromotedToType(ISD::STRICT_FP_TO_UINT, MVT::i1,
- isPPC64 ? MVT::i64 : MVT::i32);
-
- setOperationAction(ISD::FP_TO_SINT, MVT::i1, Promote);
- AddPromotedToType(ISD::FP_TO_SINT, MVT::i1,
- isPPC64 ? MVT::i64 : MVT::i32);
- setOperationAction(ISD::FP_TO_UINT, MVT::i1, Promote);
- AddPromotedToType(ISD::FP_TO_UINT, MVT::i1,
- isPPC64 ? MVT::i64 : MVT::i32);
+
+ setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i1, Promote);
+ AddPromotedToType(ISD::STRICT_FP_TO_SINT, MVT::i1,
+ isPPC64 ? MVT::i64 : MVT::i32);
+ setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i1, Promote);
+ AddPromotedToType(ISD::STRICT_FP_TO_UINT, MVT::i1,
+ isPPC64 ? MVT::i64 : MVT::i32);
+
+ setOperationAction(ISD::FP_TO_SINT, MVT::i1, Promote);
+ AddPromotedToType(ISD::FP_TO_SINT, MVT::i1,
+ isPPC64 ? MVT::i64 : MVT::i32);
+ setOperationAction(ISD::FP_TO_UINT, MVT::i1, Promote);
+ AddPromotedToType(ISD::FP_TO_UINT, MVT::i1,
+ isPPC64 ? MVT::i64 : MVT::i32);
} else {
- setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i1, Custom);
- setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i1, Custom);
+ setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i1, Custom);
+ setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i1, Custom);
setOperationAction(ISD::SINT_TO_FP, MVT::i1, Custom);
setOperationAction(ISD::UINT_TO_FP, MVT::i1, Custom);
}
@@ -282,8 +282,8 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
// PPC (the libcall is not available).
setOperationAction(ISD::FP_TO_SINT, MVT::ppcf128, Custom);
setOperationAction(ISD::FP_TO_UINT, MVT::ppcf128, Custom);
- setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::ppcf128, Custom);
- setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::ppcf128, Custom);
+ setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::ppcf128, Custom);
+ setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::ppcf128, Custom);
// We do not currently implement these libm ops for PowerPC.
setOperationAction(ISD::FFLOOR, MVT::ppcf128, Expand);
@@ -336,10 +336,10 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setOperationAction(ISD::STRICT_FMUL, MVT::f64, Legal);
setOperationAction(ISD::STRICT_FDIV, MVT::f64, Legal);
setOperationAction(ISD::STRICT_FMA, MVT::f64, Legal);
- if (Subtarget.hasVSX()) {
- setOperationAction(ISD::STRICT_FRINT, MVT::f32, Legal);
- setOperationAction(ISD::STRICT_FRINT, MVT::f64, Legal);
- }
+ if (Subtarget.hasVSX()) {
+ setOperationAction(ISD::STRICT_FRINT, MVT::f32, Legal);
+ setOperationAction(ISD::STRICT_FRINT, MVT::f64, Legal);
+ }
if (Subtarget.hasFSQRT()) {
setOperationAction(ISD::STRICT_FSQRT, MVT::f32, Legal);
@@ -377,9 +377,9 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setOperationAction(ISD::FMA , MVT::f32, Legal);
}
- if (Subtarget.hasSPE())
- setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand);
-
+ if (Subtarget.hasSPE())
+ setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand);
+
setOperationAction(ISD::FLT_ROUNDS_, MVT::i32, Custom);
// If we're enabling GP optimizations, use hardware square root
@@ -457,16 +457,16 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
if (!Subtarget.useCRBits())
setOperationAction(ISD::SETCC, MVT::i32, Custom);
- if (Subtarget.hasFPU()) {
- setOperationAction(ISD::STRICT_FSETCC, MVT::f32, Legal);
- setOperationAction(ISD::STRICT_FSETCC, MVT::f64, Legal);
- setOperationAction(ISD::STRICT_FSETCC, MVT::f128, Legal);
-
- setOperationAction(ISD::STRICT_FSETCCS, MVT::f32, Legal);
- setOperationAction(ISD::STRICT_FSETCCS, MVT::f64, Legal);
- setOperationAction(ISD::STRICT_FSETCCS, MVT::f128, Legal);
- }
-
+ if (Subtarget.hasFPU()) {
+ setOperationAction(ISD::STRICT_FSETCC, MVT::f32, Legal);
+ setOperationAction(ISD::STRICT_FSETCC, MVT::f64, Legal);
+ setOperationAction(ISD::STRICT_FSETCC, MVT::f128, Legal);
+
+ setOperationAction(ISD::STRICT_FSETCCS, MVT::f32, Legal);
+ setOperationAction(ISD::STRICT_FSETCCS, MVT::f64, Legal);
+ setOperationAction(ISD::STRICT_FSETCCS, MVT::f128, Legal);
+ }
+
// PowerPC does not have BRCOND which requires SetCC
if (!Subtarget.useCRBits())
setOperationAction(ISD::BRCOND, MVT::Other, Expand);
@@ -483,12 +483,12 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal);
} else {
// PowerPC turns FP_TO_SINT into FCTIWZ and some load/stores.
- setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i32, Custom);
+ setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i32, Custom);
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
// PowerPC does not have [U|S]INT_TO_FP
- setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i32, Expand);
- setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i32, Expand);
+ setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i32, Expand);
+ setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i32, Expand);
setOperationAction(ISD::SINT_TO_FP, MVT::i32, Expand);
setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
}
@@ -616,56 +616,56 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setCondCodeAction(ISD::SETONE, MVT::f32, Expand);
setCondCodeAction(ISD::SETONE, MVT::f64, Expand);
- setOperationAction(ISD::STRICT_FP_EXTEND, MVT::f32, Legal);
- setOperationAction(ISD::STRICT_FP_EXTEND, MVT::f64, Legal);
-
+ setOperationAction(ISD::STRICT_FP_EXTEND, MVT::f32, Legal);
+ setOperationAction(ISD::STRICT_FP_EXTEND, MVT::f64, Legal);
+
if (Subtarget.has64BitSupport()) {
// They also have instructions for converting between i64 and fp.
- setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i64, Custom);
- setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i64, Expand);
- setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i64, Custom);
- setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i64, Expand);
+ setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i64, Custom);
+ setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i64, Expand);
+ setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i64, Custom);
+ setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i64, Expand);
setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand);
setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand);
// This is just the low 32 bits of a (signed) fp->i64 conversion.
// We cannot do this with Promote because i64 is not a legal type.
- setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Custom);
+ setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Custom);
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
- if (Subtarget.hasLFIWAX() || Subtarget.isPPC64()) {
+ if (Subtarget.hasLFIWAX() || Subtarget.isPPC64()) {
setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
- setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i32, Custom);
- }
+ setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i32, Custom);
+ }
} else {
// PowerPC does not have FP_TO_UINT on 32-bit implementations.
if (Subtarget.hasSPE()) {
setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Legal);
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal);
- } else {
- setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Expand);
+ } else {
+ setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Expand);
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
- }
+ }
}
// With the instructions enabled under FPCVT, we can do everything.
if (Subtarget.hasFPCVT()) {
if (Subtarget.has64BitSupport()) {
- setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i64, Custom);
- setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i64, Custom);
- setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i64, Custom);
- setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i64, Custom);
+ setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i64, Custom);
+ setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i64, Custom);
+ setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i64, Custom);
+ setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i64, Custom);
setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
}
- setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i32, Custom);
- setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Custom);
- setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i32, Custom);
- setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i32, Custom);
+ setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i32, Custom);
+ setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Custom);
+ setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i32, Custom);
+ setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i32, Custom);
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
@@ -688,15 +688,15 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setOperationAction(ISD::SRL_PARTS, MVT::i32, Custom);
}
- // PowerPC has better expansions for funnel shifts than the generic
- // TargetLowering::expandFunnelShift.
- if (Subtarget.has64BitSupport()) {
- setOperationAction(ISD::FSHL, MVT::i64, Custom);
- setOperationAction(ISD::FSHR, MVT::i64, Custom);
- }
- setOperationAction(ISD::FSHL, MVT::i32, Custom);
- setOperationAction(ISD::FSHR, MVT::i32, Custom);
-
+ // PowerPC has better expansions for funnel shifts than the generic
+ // TargetLowering::expandFunnelShift.
+ if (Subtarget.has64BitSupport()) {
+ setOperationAction(ISD::FSHL, MVT::i64, Custom);
+ setOperationAction(ISD::FSHR, MVT::i64, Custom);
+ }
+ setOperationAction(ISD::FSHL, MVT::i32, Custom);
+ setOperationAction(ISD::FSHR, MVT::i32, Custom);
+
if (Subtarget.hasVSX()) {
setOperationAction(ISD::FMAXNUM_IEEE, MVT::f64, Legal);
setOperationAction(ISD::FMAXNUM_IEEE, MVT::f32, Legal);
@@ -848,10 +848,10 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setOperationAction(ISD::SELECT, MVT::v4i32,
Subtarget.useCRBits() ? Legal : Expand);
setOperationAction(ISD::STORE , MVT::v4i32, Legal);
- setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::v4i32, Legal);
- setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::v4i32, Legal);
- setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v4i32, Legal);
- setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v4i32, Legal);
+ setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::v4i32, Legal);
+ setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::v4i32, Legal);
+ setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v4i32, Legal);
+ setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v4i32, Legal);
setOperationAction(ISD::FP_TO_SINT, MVT::v4i32, Legal);
setOperationAction(ISD::FP_TO_UINT, MVT::v4i32, Legal);
setOperationAction(ISD::SINT_TO_FP, MVT::v4i32, Legal);
@@ -889,27 +889,27 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
else
setOperationAction(ISD::MUL, MVT::v4i32, Custom);
- if (Subtarget.isISA3_1()) {
- setOperationAction(ISD::MUL, MVT::v2i64, Legal);
- setOperationAction(ISD::MULHS, MVT::v2i64, Legal);
- setOperationAction(ISD::MULHU, MVT::v2i64, Legal);
- setOperationAction(ISD::MULHS, MVT::v4i32, Legal);
- setOperationAction(ISD::MULHU, MVT::v4i32, Legal);
- setOperationAction(ISD::UDIV, MVT::v2i64, Legal);
- setOperationAction(ISD::SDIV, MVT::v2i64, Legal);
- setOperationAction(ISD::UDIV, MVT::v4i32, Legal);
- setOperationAction(ISD::SDIV, MVT::v4i32, Legal);
- setOperationAction(ISD::UREM, MVT::v2i64, Legal);
- setOperationAction(ISD::SREM, MVT::v2i64, Legal);
- setOperationAction(ISD::UREM, MVT::v4i32, Legal);
- setOperationAction(ISD::SREM, MVT::v4i32, Legal);
- setOperationAction(ISD::UREM, MVT::v1i128, Legal);
- setOperationAction(ISD::SREM, MVT::v1i128, Legal);
- setOperationAction(ISD::UDIV, MVT::v1i128, Legal);
- setOperationAction(ISD::SDIV, MVT::v1i128, Legal);
- setOperationAction(ISD::ROTL, MVT::v1i128, Legal);
- }
-
+ if (Subtarget.isISA3_1()) {
+ setOperationAction(ISD::MUL, MVT::v2i64, Legal);
+ setOperationAction(ISD::MULHS, MVT::v2i64, Legal);
+ setOperationAction(ISD::MULHU, MVT::v2i64, Legal);
+ setOperationAction(ISD::MULHS, MVT::v4i32, Legal);
+ setOperationAction(ISD::MULHU, MVT::v4i32, Legal);
+ setOperationAction(ISD::UDIV, MVT::v2i64, Legal);
+ setOperationAction(ISD::SDIV, MVT::v2i64, Legal);
+ setOperationAction(ISD::UDIV, MVT::v4i32, Legal);
+ setOperationAction(ISD::SDIV, MVT::v4i32, Legal);
+ setOperationAction(ISD::UREM, MVT::v2i64, Legal);
+ setOperationAction(ISD::SREM, MVT::v2i64, Legal);
+ setOperationAction(ISD::UREM, MVT::v4i32, Legal);
+ setOperationAction(ISD::SREM, MVT::v4i32, Legal);
+ setOperationAction(ISD::UREM, MVT::v1i128, Legal);
+ setOperationAction(ISD::SREM, MVT::v1i128, Legal);
+ setOperationAction(ISD::UDIV, MVT::v1i128, Legal);
+ setOperationAction(ISD::SDIV, MVT::v1i128, Legal);
+ setOperationAction(ISD::ROTL, MVT::v1i128, Legal);
+ }
+
setOperationAction(ISD::MUL, MVT::v8i16, Legal);
setOperationAction(ISD::MUL, MVT::v16i8, Custom);
@@ -1021,10 +1021,10 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setOperationAction(ISD::SUB, MVT::v2i64, Expand);
}
- if (Subtarget.isISA3_1())
- setOperationAction(ISD::SETCC, MVT::v1i128, Legal);
- else
- setOperationAction(ISD::SETCC, MVT::v1i128, Expand);
+ if (Subtarget.isISA3_1())
+ setOperationAction(ISD::SETCC, MVT::v1i128, Legal);
+ else
+ setOperationAction(ISD::SETCC, MVT::v1i128, Expand);
setOperationAction(ISD::LOAD, MVT::v2i64, Promote);
AddPromotedToType (ISD::LOAD, MVT::v2i64, MVT::v2f64);
@@ -1033,10 +1033,10 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v2i64, Legal);
- setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v2i64, Legal);
- setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v2i64, Legal);
- setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::v2i64, Legal);
- setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::v2i64, Legal);
+ setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v2i64, Legal);
+ setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v2i64, Legal);
+ setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::v2i64, Legal);
+ setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::v2i64, Legal);
setOperationAction(ISD::SINT_TO_FP, MVT::v2i64, Legal);
setOperationAction(ISD::UINT_TO_FP, MVT::v2i64, Legal);
setOperationAction(ISD::FP_TO_SINT, MVT::v2i64, Legal);
@@ -1045,14 +1045,14 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
// Custom handling for partial vectors of integers converted to
// floating point. We already have optimal handling for v2i32 through
// the DAG combine, so those aren't necessary.
- setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v2i8, Custom);
- setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v4i8, Custom);
- setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v2i16, Custom);
- setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v4i16, Custom);
- setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v2i8, Custom);
- setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v4i8, Custom);
- setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v2i16, Custom);
- setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v4i16, Custom);
+ setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v2i8, Custom);
+ setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v4i8, Custom);
+ setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v2i16, Custom);
+ setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::v4i16, Custom);
+ setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v2i8, Custom);
+ setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v4i8, Custom);
+ setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v2i16, Custom);
+ setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v4i16, Custom);
setOperationAction(ISD::UINT_TO_FP, MVT::v2i8, Custom);
setOperationAction(ISD::UINT_TO_FP, MVT::v4i8, Custom);
setOperationAction(ISD::UINT_TO_FP, MVT::v2i16, Custom);
@@ -1084,7 +1084,7 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setOperationAction(ISD::STRICT_FSQRT, MVT::v4f32, Legal);
setOperationAction(ISD::STRICT_FMAXNUM, MVT::v4f32, Legal);
setOperationAction(ISD::STRICT_FMINNUM, MVT::v4f32, Legal);
- setOperationAction(ISD::STRICT_FRINT, MVT::v4f32, Legal);
+ setOperationAction(ISD::STRICT_FRINT, MVT::v4f32, Legal);
setOperationAction(ISD::STRICT_FFLOOR, MVT::v4f32, Legal);
setOperationAction(ISD::STRICT_FCEIL, MVT::v4f32, Legal);
setOperationAction(ISD::STRICT_FTRUNC, MVT::v4f32, Legal);
@@ -1098,7 +1098,7 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setOperationAction(ISD::STRICT_FSQRT, MVT::v2f64, Legal);
setOperationAction(ISD::STRICT_FMAXNUM, MVT::v2f64, Legal);
setOperationAction(ISD::STRICT_FMINNUM, MVT::v2f64, Legal);
- setOperationAction(ISD::STRICT_FRINT, MVT::v2f64, Legal);
+ setOperationAction(ISD::STRICT_FRINT, MVT::v2f64, Legal);
setOperationAction(ISD::STRICT_FFLOOR, MVT::v2f64, Legal);
setOperationAction(ISD::STRICT_FCEIL, MVT::v2f64, Legal);
setOperationAction(ISD::STRICT_FTRUNC, MVT::v2f64, Legal);
@@ -1181,48 +1181,48 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setOperationAction(ISD::BSWAP, MVT::v4i32, Legal);
setOperationAction(ISD::BSWAP, MVT::v2i64, Legal);
setOperationAction(ISD::BSWAP, MVT::v1i128, Legal);
- } else if (Subtarget.hasAltivec() && EnableSoftFP128) {
- addRegisterClass(MVT::f128, &PPC::VRRCRegClass);
-
- for (MVT FPT : MVT::fp_valuetypes())
- setLoadExtAction(ISD::EXTLOAD, MVT::f128, FPT, Expand);
-
- setOperationAction(ISD::LOAD, MVT::f128, Promote);
- setOperationAction(ISD::STORE, MVT::f128, Promote);
-
- AddPromotedToType(ISD::LOAD, MVT::f128, MVT::v4i32);
- AddPromotedToType(ISD::STORE, MVT::f128, MVT::v4i32);
-
- // Set FADD/FSUB as libcall to avoid the legalizer to expand the
- // fp_to_uint and int_to_fp.
- setOperationAction(ISD::FADD, MVT::f128, LibCall);
- setOperationAction(ISD::FSUB, MVT::f128, LibCall);
-
- setOperationAction(ISD::FMUL, MVT::f128, Expand);
- setOperationAction(ISD::FDIV, MVT::f128, Expand);
- setOperationAction(ISD::FNEG, MVT::f128, Expand);
- setOperationAction(ISD::FABS, MVT::f128, Expand);
- setOperationAction(ISD::FSIN, MVT::f128, Expand);
- setOperationAction(ISD::FCOS, MVT::f128, Expand);
- setOperationAction(ISD::FPOW, MVT::f128, Expand);
- setOperationAction(ISD::FPOWI, MVT::f128, Expand);
- setOperationAction(ISD::FREM, MVT::f128, Expand);
- setOperationAction(ISD::FSQRT, MVT::f128, Expand);
- setOperationAction(ISD::FMA, MVT::f128, Expand);
- setOperationAction(ISD::FCOPYSIGN, MVT::f128, Expand);
-
- setTruncStoreAction(MVT::f128, MVT::f64, Expand);
- setTruncStoreAction(MVT::f128, MVT::f32, Expand);
-
- // Expand the fp_extend if the target type is fp128.
- setOperationAction(ISD::FP_EXTEND, MVT::f128, Expand);
- setOperationAction(ISD::STRICT_FP_EXTEND, MVT::f128, Expand);
-
- // Expand the fp_round if the source type is fp128.
- for (MVT VT : {MVT::f32, MVT::f64}) {
- setOperationAction(ISD::FP_ROUND, VT, Custom);
- setOperationAction(ISD::STRICT_FP_ROUND, VT, Custom);
- }
+ } else if (Subtarget.hasAltivec() && EnableSoftFP128) {
+ addRegisterClass(MVT::f128, &PPC::VRRCRegClass);
+
+ for (MVT FPT : MVT::fp_valuetypes())
+ setLoadExtAction(ISD::EXTLOAD, MVT::f128, FPT, Expand);
+
+ setOperationAction(ISD::LOAD, MVT::f128, Promote);
+ setOperationAction(ISD::STORE, MVT::f128, Promote);
+
+ AddPromotedToType(ISD::LOAD, MVT::f128, MVT::v4i32);
+ AddPromotedToType(ISD::STORE, MVT::f128, MVT::v4i32);
+
+ // Set FADD/FSUB as libcall to avoid the legalizer to expand the
+ // fp_to_uint and int_to_fp.
+ setOperationAction(ISD::FADD, MVT::f128, LibCall);
+ setOperationAction(ISD::FSUB, MVT::f128, LibCall);
+
+ setOperationAction(ISD::FMUL, MVT::f128, Expand);
+ setOperationAction(ISD::FDIV, MVT::f128, Expand);
+ setOperationAction(ISD::FNEG, MVT::f128, Expand);
+ setOperationAction(ISD::FABS, MVT::f128, Expand);
+ setOperationAction(ISD::FSIN, MVT::f128, Expand);
+ setOperationAction(ISD::FCOS, MVT::f128, Expand);
+ setOperationAction(ISD::FPOW, MVT::f128, Expand);
+ setOperationAction(ISD::FPOWI, MVT::f128, Expand);
+ setOperationAction(ISD::FREM, MVT::f128, Expand);
+ setOperationAction(ISD::FSQRT, MVT::f128, Expand);
+ setOperationAction(ISD::FMA, MVT::f128, Expand);
+ setOperationAction(ISD::FCOPYSIGN, MVT::f128, Expand);
+
+ setTruncStoreAction(MVT::f128, MVT::f64, Expand);
+ setTruncStoreAction(MVT::f128, MVT::f32, Expand);
+
+ // Expand the fp_extend if the target type is fp128.
+ setOperationAction(ISD::FP_EXTEND, MVT::f128, Expand);
+ setOperationAction(ISD::STRICT_FP_EXTEND, MVT::f128, Expand);
+
+ // Expand the fp_round if the source type is fp128.
+ for (MVT VT : {MVT::f32, MVT::f64}) {
+ setOperationAction(ISD::FP_ROUND, VT, Custom);
+ setOperationAction(ISD::STRICT_FP_ROUND, VT, Custom);
+ }
}
if (Subtarget.hasP9Altivec()) {
@@ -1239,24 +1239,24 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
}
}
- if (Subtarget.pairedVectorMemops()) {
- addRegisterClass(MVT::v256i1, &PPC::VSRpRCRegClass);
- setOperationAction(ISD::LOAD, MVT::v256i1, Custom);
- setOperationAction(ISD::STORE, MVT::v256i1, Custom);
+ if (Subtarget.pairedVectorMemops()) {
+ addRegisterClass(MVT::v256i1, &PPC::VSRpRCRegClass);
+ setOperationAction(ISD::LOAD, MVT::v256i1, Custom);
+ setOperationAction(ISD::STORE, MVT::v256i1, Custom);
+ }
+ if (Subtarget.hasMMA()) {
+ addRegisterClass(MVT::v512i1, &PPC::UACCRCRegClass);
+ setOperationAction(ISD::LOAD, MVT::v512i1, Custom);
+ setOperationAction(ISD::STORE, MVT::v512i1, Custom);
+ setOperationAction(ISD::BUILD_VECTOR, MVT::v512i1, Custom);
}
- if (Subtarget.hasMMA()) {
- addRegisterClass(MVT::v512i1, &PPC::UACCRCRegClass);
- setOperationAction(ISD::LOAD, MVT::v512i1, Custom);
- setOperationAction(ISD::STORE, MVT::v512i1, Custom);
- setOperationAction(ISD::BUILD_VECTOR, MVT::v512i1, Custom);
- }
if (Subtarget.has64BitSupport())
setOperationAction(ISD::PREFETCH, MVT::Other, Legal);
- if (Subtarget.isISA3_1())
- setOperationAction(ISD::SRA, MVT::v1i128, Legal);
-
+ if (Subtarget.isISA3_1())
+ setOperationAction(ISD::SRA, MVT::v1i128, Legal);
+
setOperationAction(ISD::READCYCLECOUNTER, MVT::i64, isPPC64 ? Legal : Custom);
if (!isPPC64) {
@@ -1334,18 +1334,18 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setLibcallName(RTLIB::FMIN_F128, "fminf128");
setLibcallName(RTLIB::FMAX_F128, "fmaxf128");
setLibcallName(RTLIB::REM_F128, "fmodf128");
- setLibcallName(RTLIB::SQRT_F128, "sqrtf128");
- setLibcallName(RTLIB::CEIL_F128, "ceilf128");
- setLibcallName(RTLIB::FLOOR_F128, "floorf128");
- setLibcallName(RTLIB::TRUNC_F128, "truncf128");
- setLibcallName(RTLIB::ROUND_F128, "roundf128");
- setLibcallName(RTLIB::LROUND_F128, "lroundf128");
- setLibcallName(RTLIB::LLROUND_F128, "llroundf128");
- setLibcallName(RTLIB::RINT_F128, "rintf128");
- setLibcallName(RTLIB::LRINT_F128, "lrintf128");
- setLibcallName(RTLIB::LLRINT_F128, "llrintf128");
- setLibcallName(RTLIB::NEARBYINT_F128, "nearbyintf128");
- setLibcallName(RTLIB::FMA_F128, "fmaf128");
+ setLibcallName(RTLIB::SQRT_F128, "sqrtf128");
+ setLibcallName(RTLIB::CEIL_F128, "ceilf128");
+ setLibcallName(RTLIB::FLOOR_F128, "floorf128");
+ setLibcallName(RTLIB::TRUNC_F128, "truncf128");
+ setLibcallName(RTLIB::ROUND_F128, "roundf128");
+ setLibcallName(RTLIB::LROUND_F128, "lroundf128");
+ setLibcallName(RTLIB::LLROUND_F128, "llroundf128");
+ setLibcallName(RTLIB::RINT_F128, "rintf128");
+ setLibcallName(RTLIB::LRINT_F128, "lrintf128");
+ setLibcallName(RTLIB::LLRINT_F128, "llrintf128");
+ setLibcallName(RTLIB::NEARBYINT_F128, "nearbyintf128");
+ setLibcallName(RTLIB::FMA_F128, "fmaf128");
// With 32 condition bits, we don't need to sink (and duplicate) compares
// aggressively in CodeGenPrep.
@@ -1408,8 +1408,8 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
MaxLoadsPerMemcmpOptSize = 4;
}
- IsStrictFPEnabled = true;
-
+ IsStrictFPEnabled = true;
+
// Let the subtarget (CPU) decide if a predictable select is more expensive
// than the corresponding branch. This information is used in CGP to decide
// when to convert selects into branches.
@@ -1452,8 +1452,8 @@ unsigned PPCTargetLowering::getByValTypeAlignment(Type *Ty,
// 16byte and wider vectors are passed on 16byte boundary.
// The rest is 8 on PPC64 and 4 on PPC32 boundary.
Align Alignment = Subtarget.isPPC64() ? Align(8) : Align(4);
- if (Subtarget.hasAltivec())
- getMaxByValAlign(Ty, Alignment, Align(16));
+ if (Subtarget.hasAltivec())
+ getMaxByValAlign(Ty, Alignment, Align(16));
return Alignment.value();
}
@@ -1489,10 +1489,10 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
return "PPCISD::FP_TO_SINT_IN_VSR";
case PPCISD::FRE: return "PPCISD::FRE";
case PPCISD::FRSQRTE: return "PPCISD::FRSQRTE";
- case PPCISD::FTSQRT:
- return "PPCISD::FTSQRT";
- case PPCISD::FSQRT:
- return "PPCISD::FSQRT";
+ case PPCISD::FTSQRT:
+ return "PPCISD::FTSQRT";
+ case PPCISD::FSQRT:
+ return "PPCISD::FSQRT";
case PPCISD::STFIWX: return "PPCISD::STFIWX";
case PPCISD::VPERM: return "PPCISD::VPERM";
case PPCISD::XXSPLT: return "PPCISD::XXSPLT";
@@ -1540,7 +1540,7 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
case PPCISD::ANDI_rec_1_GT_BIT:
return "PPCISD::ANDI_rec_1_GT_BIT";
case PPCISD::VCMP: return "PPCISD::VCMP";
- case PPCISD::VCMP_rec: return "PPCISD::VCMP_rec";
+ case PPCISD::VCMP_rec: return "PPCISD::VCMP_rec";
case PPCISD::LBRX: return "PPCISD::LBRX";
case PPCISD::STBRX: return "PPCISD::STBRX";
case PPCISD::LFIWAX: return "PPCISD::LFIWAX";
@@ -1577,8 +1577,8 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
case PPCISD::ADDI_TLSLD_L_ADDR: return "PPCISD::ADDI_TLSLD_L_ADDR";
case PPCISD::ADDIS_DTPREL_HA: return "PPCISD::ADDIS_DTPREL_HA";
case PPCISD::ADDI_DTPREL_L: return "PPCISD::ADDI_DTPREL_L";
- case PPCISD::PADDI_DTPREL:
- return "PPCISD::PADDI_DTPREL";
+ case PPCISD::PADDI_DTPREL:
+ return "PPCISD::PADDI_DTPREL";
case PPCISD::VADD_SPLAT: return "PPCISD::VADD_SPLAT";
case PPCISD::SC: return "PPCISD::SC";
case PPCISD::CLRBHRB: return "PPCISD::CLRBHRB";
@@ -1594,35 +1594,35 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
case PPCISD::LD_VSX_LH: return "PPCISD::LD_VSX_LH";
case PPCISD::FP_EXTEND_HALF: return "PPCISD::FP_EXTEND_HALF";
case PPCISD::MAT_PCREL_ADDR: return "PPCISD::MAT_PCREL_ADDR";
- case PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR:
- return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
- case PPCISD::TLS_LOCAL_EXEC_MAT_ADDR:
- return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
- case PPCISD::ACC_BUILD: return "PPCISD::ACC_BUILD";
- case PPCISD::PAIR_BUILD: return "PPCISD::PAIR_BUILD";
- case PPCISD::EXTRACT_VSX_REG: return "PPCISD::EXTRACT_VSX_REG";
- case PPCISD::XXMFACC: return "PPCISD::XXMFACC";
+ case PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR:
+ return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
+ case PPCISD::TLS_LOCAL_EXEC_MAT_ADDR:
+ return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
+ case PPCISD::ACC_BUILD: return "PPCISD::ACC_BUILD";
+ case PPCISD::PAIR_BUILD: return "PPCISD::PAIR_BUILD";
+ case PPCISD::EXTRACT_VSX_REG: return "PPCISD::EXTRACT_VSX_REG";
+ case PPCISD::XXMFACC: return "PPCISD::XXMFACC";
case PPCISD::LD_SPLAT: return "PPCISD::LD_SPLAT";
case PPCISD::FNMSUB: return "PPCISD::FNMSUB";
- case PPCISD::STRICT_FADDRTZ:
- return "PPCISD::STRICT_FADDRTZ";
- case PPCISD::STRICT_FCTIDZ:
- return "PPCISD::STRICT_FCTIDZ";
- case PPCISD::STRICT_FCTIWZ:
- return "PPCISD::STRICT_FCTIWZ";
- case PPCISD::STRICT_FCTIDUZ:
- return "PPCISD::STRICT_FCTIDUZ";
- case PPCISD::STRICT_FCTIWUZ:
- return "PPCISD::STRICT_FCTIWUZ";
- case PPCISD::STRICT_FCFID:
- return "PPCISD::STRICT_FCFID";
- case PPCISD::STRICT_FCFIDU:
- return "PPCISD::STRICT_FCFIDU";
- case PPCISD::STRICT_FCFIDS:
- return "PPCISD::STRICT_FCFIDS";
- case PPCISD::STRICT_FCFIDUS:
- return "PPCISD::STRICT_FCFIDUS";
- case PPCISD::LXVRZX: return "PPCISD::LXVRZX";
+ case PPCISD::STRICT_FADDRTZ:
+ return "PPCISD::STRICT_FADDRTZ";
+ case PPCISD::STRICT_FCTIDZ:
+ return "PPCISD::STRICT_FCTIDZ";
+ case PPCISD::STRICT_FCTIWZ:
+ return "PPCISD::STRICT_FCTIWZ";
+ case PPCISD::STRICT_FCTIDUZ:
+ return "PPCISD::STRICT_FCTIDUZ";
+ case PPCISD::STRICT_FCTIWUZ:
+ return "PPCISD::STRICT_FCTIWUZ";
+ case PPCISD::STRICT_FCFID:
+ return "PPCISD::STRICT_FCFID";
+ case PPCISD::STRICT_FCFIDU:
+ return "PPCISD::STRICT_FCFIDU";
+ case PPCISD::STRICT_FCFIDS:
+ return "PPCISD::STRICT_FCFIDS";
+ case PPCISD::STRICT_FCFIDUS:
+ return "PPCISD::STRICT_FCFIDUS";
+ case PPCISD::LXVRZX: return "PPCISD::LXVRZX";
}
return nullptr;
}
@@ -2446,20 +2446,20 @@ bool PPCTargetLowering::SelectAddressEVXRegReg(SDValue N, SDValue &Base,
return false;
}
-/// isIntS34Immediate - This method tests if value of node given can be
-/// accurately represented as a sign extension from a 34-bit value. If so,
-/// this returns true and the immediate.
-bool llvm::isIntS34Immediate(SDNode *N, int64_t &Imm) {
- if (!isa<ConstantSDNode>(N))
- return false;
-
- Imm = (int64_t)cast<ConstantSDNode>(N)->getZExtValue();
- return isInt<34>(Imm);
-}
-bool llvm::isIntS34Immediate(SDValue Op, int64_t &Imm) {
- return isIntS34Immediate(Op.getNode(), Imm);
-}
-
+/// isIntS34Immediate - This method tests if value of node given can be
+/// accurately represented as a sign extension from a 34-bit value. If so,
+/// this returns true and the immediate.
+bool llvm::isIntS34Immediate(SDNode *N, int64_t &Imm) {
+ if (!isa<ConstantSDNode>(N))
+ return false;
+
+ Imm = (int64_t)cast<ConstantSDNode>(N)->getZExtValue();
+ return isInt<34>(Imm);
+}
+bool llvm::isIntS34Immediate(SDValue Op, int64_t &Imm) {
+ return isIntS34Immediate(Op.getNode(), Imm);
+}
+
/// SelectAddressRegReg - Given the specified addressed, check to see if it
/// can be represented as an indexed [r+r] operation. Returns false if it
/// can be more efficiently represented as [r+imm]. If \p EncodingAlignment is
@@ -2660,55 +2660,55 @@ bool PPCTargetLowering::SelectAddressRegImm(
return true; // [r+0]
}
-/// Similar to the 16-bit case but for instructions that take a 34-bit
-/// displacement field (prefixed loads/stores).
-bool PPCTargetLowering::SelectAddressRegImm34(SDValue N, SDValue &Disp,
- SDValue &Base,
- SelectionDAG &DAG) const {
- // Only on 64-bit targets.
- if (N.getValueType() != MVT::i64)
- return false;
-
- SDLoc dl(N);
- int64_t Imm = 0;
-
- if (N.getOpcode() == ISD::ADD) {
- if (!isIntS34Immediate(N.getOperand(1), Imm))
- return false;
- Disp = DAG.getTargetConstant(Imm, dl, N.getValueType());
- if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N.getOperand(0)))
- Base = DAG.getTargetFrameIndex(FI->getIndex(), N.getValueType());
- else
- Base = N.getOperand(0);
- return true;
- }
-
- if (N.getOpcode() == ISD::OR) {
- if (!isIntS34Immediate(N.getOperand(1), Imm))
- return false;
- // If this is an or of disjoint bitfields, we can codegen this as an add
- // (for better address arithmetic) if the LHS and RHS of the OR are
- // provably disjoint.
- KnownBits LHSKnown = DAG.computeKnownBits(N.getOperand(0));
- if ((LHSKnown.Zero.getZExtValue() | ~(uint64_t)Imm) != ~0ULL)
- return false;
- if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N.getOperand(0)))
- Base = DAG.getTargetFrameIndex(FI->getIndex(), N.getValueType());
- else
- Base = N.getOperand(0);
- Disp = DAG.getTargetConstant(Imm, dl, N.getValueType());
- return true;
- }
-
- if (isIntS34Immediate(N, Imm)) { // If the address is a 34-bit const.
- Disp = DAG.getTargetConstant(Imm, dl, N.getValueType());
- Base = DAG.getRegister(PPC::ZERO8, N.getValueType());
- return true;
- }
-
- return false;
-}
-
+/// Similar to the 16-bit case but for instructions that take a 34-bit
+/// displacement field (prefixed loads/stores).
+bool PPCTargetLowering::SelectAddressRegImm34(SDValue N, SDValue &Disp,
+ SDValue &Base,
+ SelectionDAG &DAG) const {
+ // Only on 64-bit targets.
+ if (N.getValueType() != MVT::i64)
+ return false;
+
+ SDLoc dl(N);
+ int64_t Imm = 0;
+
+ if (N.getOpcode() == ISD::ADD) {
+ if (!isIntS34Immediate(N.getOperand(1), Imm))
+ return false;
+ Disp = DAG.getTargetConstant(Imm, dl, N.getValueType());
+ if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N.getOperand(0)))
+ Base = DAG.getTargetFrameIndex(FI->getIndex(), N.getValueType());
+ else
+ Base = N.getOperand(0);
+ return true;
+ }
+
+ if (N.getOpcode() == ISD::OR) {
+ if (!isIntS34Immediate(N.getOperand(1), Imm))
+ return false;
+ // If this is an or of disjoint bitfields, we can codegen this as an add
+ // (for better address arithmetic) if the LHS and RHS of the OR are
+ // provably disjoint.
+ KnownBits LHSKnown = DAG.computeKnownBits(N.getOperand(0));
+ if ((LHSKnown.Zero.getZExtValue() | ~(uint64_t)Imm) != ~0ULL)
+ return false;
+ if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N.getOperand(0)))
+ Base = DAG.getTargetFrameIndex(FI->getIndex(), N.getValueType());
+ else
+ Base = N.getOperand(0);
+ Disp = DAG.getTargetConstant(Imm, dl, N.getValueType());
+ return true;
+ }
+
+ if (isIntS34Immediate(N, Imm)) { // If the address is a 34-bit const.
+ Disp = DAG.getTargetConstant(Imm, dl, N.getValueType());
+ Base = DAG.getRegister(PPC::ZERO8, N.getValueType());
+ return true;
+ }
+
+ return false;
+}
+
/// SelectAddressRegRegOnly - Given the specified addressed, force it to be
/// represented as an indexed [r+r] operation.
bool PPCTargetLowering::SelectAddressRegRegOnly(SDValue N, SDValue &Base,
@@ -2838,9 +2838,9 @@ bool PPCTargetLowering::getPreIndexedAddressParts(SDNode *N, SDValue &Base,
return false;
}
- // PowerPC doesn't have preinc load/store instructions for vectors
- if (VT.isVector())
- return false;
+ // PowerPC doesn't have preinc load/store instructions for vectors
+ if (VT.isVector())
+ return false;
if (SelectAddressRegReg(Ptr, Base, Offset, DAG)) {
// Common code will reject creating a pre-inc form if the base pointer
@@ -3135,15 +3135,15 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
TLSModel::Model Model = TM.getTLSModel(GV);
if (Model == TLSModel::LocalExec) {
- if (Subtarget.isUsingPCRelativeCalls()) {
- SDValue TLSReg = DAG.getRegister(PPC::X13, MVT::i64);
- SDValue TGA = DAG.getTargetGlobalAddress(
- GV, dl, PtrVT, 0, (PPCII::MO_PCREL_FLAG | PPCII::MO_TPREL_FLAG));
- SDValue MatAddr =
- DAG.getNode(PPCISD::TLS_LOCAL_EXEC_MAT_ADDR, dl, PtrVT, TGA);
- return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, MatAddr);
- }
-
+ if (Subtarget.isUsingPCRelativeCalls()) {
+ SDValue TLSReg = DAG.getRegister(PPC::X13, MVT::i64);
+ SDValue TGA = DAG.getTargetGlobalAddress(
+ GV, dl, PtrVT, 0, (PPCII::MO_PCREL_FLAG | PPCII::MO_TPREL_FLAG));
+ SDValue MatAddr =
+ DAG.getNode(PPCISD::TLS_LOCAL_EXEC_MAT_ADDR, dl, PtrVT, TGA);
+ return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, MatAddr);
+ }
+
SDValue TGAHi = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
PPCII::MO_TPREL_HA);
SDValue TGALo = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
@@ -3156,44 +3156,44 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
}
if (Model == TLSModel::InitialExec) {
- bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
- SDValue TGA = DAG.getTargetGlobalAddress(
- GV, dl, PtrVT, 0, IsPCRel ? PPCII::MO_GOT_TPREL_PCREL_FLAG : 0);
- SDValue TGATLS = DAG.getTargetGlobalAddress(
- GV, dl, PtrVT, 0,
- IsPCRel ? (PPCII::MO_TLS | PPCII::MO_PCREL_FLAG) : PPCII::MO_TLS);
- SDValue TPOffset;
- if (IsPCRel) {
- SDValue MatPCRel = DAG.getNode(PPCISD::MAT_PCREL_ADDR, dl, PtrVT, TGA);
- TPOffset = DAG.getLoad(MVT::i64, dl, DAG.getEntryNode(), MatPCRel,
- MachinePointerInfo());
+ bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
+ SDValue TGA = DAG.getTargetGlobalAddress(
+ GV, dl, PtrVT, 0, IsPCRel ? PPCII::MO_GOT_TPREL_PCREL_FLAG : 0);
+ SDValue TGATLS = DAG.getTargetGlobalAddress(
+ GV, dl, PtrVT, 0,
+ IsPCRel ? (PPCII::MO_TLS | PPCII::MO_PCREL_FLAG) : PPCII::MO_TLS);
+ SDValue TPOffset;
+ if (IsPCRel) {
+ SDValue MatPCRel = DAG.getNode(PPCISD::MAT_PCREL_ADDR, dl, PtrVT, TGA);
+ TPOffset = DAG.getLoad(MVT::i64, dl, DAG.getEntryNode(), MatPCRel,
+ MachinePointerInfo());
} else {
- SDValue GOTPtr;
- if (is64bit) {
- setUsesTOCBasePtr(DAG);
- SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
- GOTPtr =
- DAG.getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, PtrVT, GOTReg, TGA);
- } else {
- if (!TM.isPositionIndependent())
- GOTPtr = DAG.getNode(PPCISD::PPC32_GOT, dl, PtrVT);
- else if (picLevel == PICLevel::SmallPIC)
- GOTPtr = DAG.getNode(PPCISD::GlobalBaseReg, dl, PtrVT);
- else
- GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT);
- }
- TPOffset = DAG.getNode(PPCISD::LD_GOT_TPREL_L, dl, PtrVT, TGA, GOTPtr);
+ SDValue GOTPtr;
+ if (is64bit) {
+ setUsesTOCBasePtr(DAG);
+ SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
+ GOTPtr =
+ DAG.getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, PtrVT, GOTReg, TGA);
+ } else {
+ if (!TM.isPositionIndependent())
+ GOTPtr = DAG.getNode(PPCISD::PPC32_GOT, dl, PtrVT);
+ else if (picLevel == PICLevel::SmallPIC)
+ GOTPtr = DAG.getNode(PPCISD::GlobalBaseReg, dl, PtrVT);
+ else
+ GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT);
+ }
+ TPOffset = DAG.getNode(PPCISD::LD_GOT_TPREL_L, dl, PtrVT, TGA, GOTPtr);
}
return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TGATLS);
}
if (Model == TLSModel::GeneralDynamic) {
- if (Subtarget.isUsingPCRelativeCalls()) {
- SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
- PPCII::MO_GOT_TLSGD_PCREL_FLAG);
- return DAG.getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
- }
-
+ if (Subtarget.isUsingPCRelativeCalls()) {
+ SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
+ PPCII::MO_GOT_TLSGD_PCREL_FLAG);
+ return DAG.getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
+ }
+
SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
SDValue GOTPtr;
if (is64bit) {
@@ -3212,14 +3212,14 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
}
if (Model == TLSModel::LocalDynamic) {
- if (Subtarget.isUsingPCRelativeCalls()) {
- SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
- PPCII::MO_GOT_TLSLD_PCREL_FLAG);
- SDValue MatPCRel =
- DAG.getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
- return DAG.getNode(PPCISD::PADDI_DTPREL, dl, PtrVT, MatPCRel, TGA);
- }
-
+ if (Subtarget.isUsingPCRelativeCalls()) {
+ SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
+ PPCII::MO_GOT_TLSLD_PCREL_FLAG);
+ SDValue MatPCRel =
+ DAG.getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
+ return DAG.getNode(PPCISD::PADDI_DTPREL, dl, PtrVT, MatPCRel, TGA);
+ }
+
SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
SDValue GOTPtr;
if (is64bit) {
@@ -3465,57 +3465,57 @@ SDValue PPCTargetLowering::LowerADJUST_TRAMPOLINE(SDValue Op,
return Op.getOperand(0);
}
-SDValue PPCTargetLowering::LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const {
- MachineFunction &MF = DAG.getMachineFunction();
- PPCFunctionInfo &MFI = *MF.getInfo<PPCFunctionInfo>();
-
- assert((Op.getOpcode() == ISD::INLINEASM ||
- Op.getOpcode() == ISD::INLINEASM_BR) &&
- "Expecting Inline ASM node.");
-
- // If an LR store is already known to be required then there is not point in
- // checking this ASM as well.
- if (MFI.isLRStoreRequired())
- return Op;
-
- // Inline ASM nodes have an optional last operand that is an incoming Flag of
- // type MVT::Glue. We want to ignore this last operand if that is the case.
- unsigned NumOps = Op.getNumOperands();
- if (Op.getOperand(NumOps - 1).getValueType() == MVT::Glue)
- --NumOps;
-
- // Check all operands that may contain the LR.
- for (unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) {
- unsigned Flags = cast<ConstantSDNode>(Op.getOperand(i))->getZExtValue();
- unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
- ++i; // Skip the ID value.
-
- switch (InlineAsm::getKind(Flags)) {
- default:
- llvm_unreachable("Bad flags!");
- case InlineAsm::Kind_RegUse:
- case InlineAsm::Kind_Imm:
- case InlineAsm::Kind_Mem:
- i += NumVals;
- break;
- case InlineAsm::Kind_Clobber:
- case InlineAsm::Kind_RegDef:
- case InlineAsm::Kind_RegDefEarlyClobber: {
- for (; NumVals; --NumVals, ++i) {
- Register Reg = cast<RegisterSDNode>(Op.getOperand(i))->getReg();
- if (Reg != PPC::LR && Reg != PPC::LR8)
- continue;
- MFI.setLRStoreRequired();
- return Op;
- }
- break;
- }
- }
- }
-
- return Op;
-}
-
+SDValue PPCTargetLowering::LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const {
+ MachineFunction &MF = DAG.getMachineFunction();
+ PPCFunctionInfo &MFI = *MF.getInfo<PPCFunctionInfo>();
+
+ assert((Op.getOpcode() == ISD::INLINEASM ||
+ Op.getOpcode() == ISD::INLINEASM_BR) &&
+ "Expecting Inline ASM node.");
+
+ // If an LR store is already known to be required then there is not point in
+ // checking this ASM as well.
+ if (MFI.isLRStoreRequired())
+ return Op;
+
+ // Inline ASM nodes have an optional last operand that is an incoming Flag of
+ // type MVT::Glue. We want to ignore this last operand if that is the case.
+ unsigned NumOps = Op.getNumOperands();
+ if (Op.getOperand(NumOps - 1).getValueType() == MVT::Glue)
+ --NumOps;
+
+ // Check all operands that may contain the LR.
+ for (unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) {
+ unsigned Flags = cast<ConstantSDNode>(Op.getOperand(i))->getZExtValue();
+ unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
+ ++i; // Skip the ID value.
+
+ switch (InlineAsm::getKind(Flags)) {
+ default:
+ llvm_unreachable("Bad flags!");
+ case InlineAsm::Kind_RegUse:
+ case InlineAsm::Kind_Imm:
+ case InlineAsm::Kind_Mem:
+ i += NumVals;
+ break;
+ case InlineAsm::Kind_Clobber:
+ case InlineAsm::Kind_RegDef:
+ case InlineAsm::Kind_RegDefEarlyClobber: {
+ for (; NumVals; --NumVals, ++i) {
+ Register Reg = cast<RegisterSDNode>(Op.getOperand(i))->getReg();
+ if (Reg != PPC::LR && Reg != PPC::LR8)
+ continue;
+ MFI.setLRStoreRequired();
+ return Op;
+ }
+ break;
+ }
+ }
+ }
+
+ return Op;
+}
+
SDValue PPCTargetLowering::LowerINIT_TRAMPOLINE(SDValue Op,
SelectionDAG &DAG) const {
if (Subtarget.isAIXABI())
@@ -3705,11 +3705,11 @@ static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT,
/// stack slot (instead of being passed in registers). ArgOffset,
/// AvailableFPRs, and AvailableVRs must hold the current argument
/// position, and will be updated to account for this argument.
-static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags,
- unsigned PtrByteSize, unsigned LinkageSize,
- unsigned ParamAreaSize, unsigned &ArgOffset,
+static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags,
+ unsigned PtrByteSize, unsigned LinkageSize,
+ unsigned ParamAreaSize, unsigned &ArgOffset,
unsigned &AvailableFPRs,
- unsigned &AvailableVRs) {
+ unsigned &AvailableVRs) {
bool UseMemory = false;
// Respect alignment of argument on the stack.
@@ -3733,7 +3733,7 @@ static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags,
// However, if the argument is actually passed in an FPR or a VR,
// we don't use memory after all.
if (!Flags.isByVal()) {
- if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
+ if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
if (AvailableFPRs > 0) {
--AvailableFPRs;
return false;
@@ -3768,8 +3768,8 @@ SDValue PPCTargetLowering::LowerFormalArguments(
if (Subtarget.is64BitELFABI())
return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
InVals);
- assert(Subtarget.is32BitELFABI());
- return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
+ assert(Subtarget.is32BitELFABI());
+ return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
InVals);
}
@@ -3869,7 +3869,7 @@ SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
RC = &PPC::VRRCRegClass;
break;
case MVT::v4f32:
- RC = &PPC::VRRCRegClass;
+ RC = &PPC::VRRCRegClass;
break;
case MVT::v2f64:
case MVT::v2i64:
@@ -4091,7 +4091,7 @@ SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
if (CalculateStackSlotUsed(Ins[i].VT, Ins[i].ArgVT, Ins[i].Flags,
PtrByteSize, LinkageSize, ParamAreaSize,
- NumBytes, AvailableFPRs, AvailableVRs))
+ NumBytes, AvailableFPRs, AvailableVRs))
HasParameterArea = true;
}
@@ -4343,20 +4343,20 @@ SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
case MVT::v2i64:
case MVT::v1i128:
case MVT::f128:
- // These can be scalar arguments or elements of a vector array type
- // passed directly. The latter are used to implement ELFv2 homogenous
- // vector aggregates.
- if (VR_idx != Num_VR_Regs) {
- unsigned VReg = MF.addLiveIn(VR[VR_idx], &PPC::VRRCRegClass);
+ // These can be scalar arguments or elements of a vector array type
+ // passed directly. The latter are used to implement ELFv2 homogenous
+ // vector aggregates.
+ if (VR_idx != Num_VR_Regs) {
+ unsigned VReg = MF.addLiveIn(VR[VR_idx], &PPC::VRRCRegClass);
ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, ObjectVT);
- ++VR_idx;
+ ++VR_idx;
} else {
if (CallConv == CallingConv::Fast)
ComputeArgOffset();
needsLoad = true;
}
if (CallConv != CallingConv::Fast || needsLoad)
- ArgOffset += 16;
+ ArgOffset += 16;
break;
}
@@ -4493,13 +4493,13 @@ static bool callsShareTOCBase(const Function *Caller, SDValue Callee,
if (STICallee->isUsingPCRelativeCalls())
return false;
- // If the GV is not a strong definition then we need to assume it can be
- // replaced by another function at link time. The function that replaces
- // it may not share the same TOC as the caller since the callee may be
- // replaced by a PC Relative version of the same function.
- if (!GV->isStrongDefinitionForLinker())
- return false;
-
+ // If the GV is not a strong definition then we need to assume it can be
+ // replaced by another function at link time. The function that replaces
+ // it may not share the same TOC as the caller since the callee may be
+ // replaced by a PC Relative version of the same function.
+ if (!GV->isStrongDefinitionForLinker())
+ return false;
+
// The medium and large code models are expected to provide a sufficiently
// large TOC to provide all data addressing needs of a module with a
// single TOC.
@@ -4550,9 +4550,9 @@ needStackSlotPassParameters(const PPCSubtarget &Subtarget,
for (const ISD::OutputArg& Param : Outs) {
if (Param.Flags.isNest()) continue;
- if (CalculateStackSlotUsed(Param.VT, Param.ArgVT, Param.Flags, PtrByteSize,
- LinkageSize, ParamAreaSize, NumBytes,
- AvailableFPRs, AvailableVRs))
+ if (CalculateStackSlotUsed(Param.VT, Param.ArgVT, Param.Flags, PtrByteSize,
+ LinkageSize, ParamAreaSize, NumBytes,
+ AvailableFPRs, AvailableVRs))
return true;
}
return false;
@@ -5066,53 +5066,53 @@ static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG,
Subtarget.is32BitELFABI() && !isLocalCallee() &&
Subtarget.getTargetMachine().getRelocationModel() == Reloc::PIC_;
- const auto getAIXFuncEntryPointSymbolSDNode = [&](const GlobalValue *GV) {
- const TargetMachine &TM = Subtarget.getTargetMachine();
- const TargetLoweringObjectFile *TLOF = TM.getObjFileLowering();
- MCSymbolXCOFF *S =
- cast<MCSymbolXCOFF>(TLOF->getFunctionEntryPointSymbol(GV, TM));
+ const auto getAIXFuncEntryPointSymbolSDNode = [&](const GlobalValue *GV) {
+ const TargetMachine &TM = Subtarget.getTargetMachine();
+ const TargetLoweringObjectFile *TLOF = TM.getObjFileLowering();
+ MCSymbolXCOFF *S =
+ cast<MCSymbolXCOFF>(TLOF->getFunctionEntryPointSymbol(GV, TM));
- MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout());
- return DAG.getMCSymbol(S, PtrVT);
- };
+ MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout());
+ return DAG.getMCSymbol(S, PtrVT);
+ };
if (isFunctionGlobalAddress(Callee)) {
- const GlobalValue *GV = cast<GlobalAddressSDNode>(Callee)->getGlobal();
+ const GlobalValue *GV = cast<GlobalAddressSDNode>(Callee)->getGlobal();
- if (Subtarget.isAIXABI()) {
- assert(!isa<GlobalIFunc>(GV) && "IFunc is not supported on AIX.");
- return getAIXFuncEntryPointSymbolSDNode(GV);
- }
- return DAG.getTargetGlobalAddress(GV, dl, Callee.getValueType(), 0,
- UsePlt ? PPCII::MO_PLT : 0);
+ if (Subtarget.isAIXABI()) {
+ assert(!isa<GlobalIFunc>(GV) && "IFunc is not supported on AIX.");
+ return getAIXFuncEntryPointSymbolSDNode(GV);
+ }
+ return DAG.getTargetGlobalAddress(GV, dl, Callee.getValueType(), 0,
+ UsePlt ? PPCII::MO_PLT : 0);
}
if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
const char *SymName = S->getSymbol();
- if (Subtarget.isAIXABI()) {
- // If there exists a user-declared function whose name is the same as the
- // ExternalSymbol's, then we pick up the user-declared version.
- const Module *Mod = DAG.getMachineFunction().getFunction().getParent();
- if (const Function *F =
- dyn_cast_or_null<Function>(Mod->getNamedValue(SymName)))
- return getAIXFuncEntryPointSymbolSDNode(F);
-
- // On AIX, direct function calls reference the symbol for the function's
- // entry point, which is named by prepending a "." before the function's
- // C-linkage name. A Qualname is returned here because an external
- // function entry point is a csect with XTY_ER property.
- const auto getExternalFunctionEntryPointSymbol = [&](StringRef SymName) {
- auto &Context = DAG.getMachineFunction().getMMI().getContext();
- MCSectionXCOFF *Sec = Context.getXCOFFSection(
- (Twine(".") + Twine(SymName)).str(), XCOFF::XMC_PR, XCOFF::XTY_ER,
- SectionKind::getMetadata());
- return Sec->getQualNameSymbol();
- };
-
- SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
+ if (Subtarget.isAIXABI()) {
+ // If there exists a user-declared function whose name is the same as the
+ // ExternalSymbol's, then we pick up the user-declared version.
+ const Module *Mod = DAG.getMachineFunction().getFunction().getParent();
+ if (const Function *F =
+ dyn_cast_or_null<Function>(Mod->getNamedValue(SymName)))
+ return getAIXFuncEntryPointSymbolSDNode(F);
+
+ // On AIX, direct function calls reference the symbol for the function's
+ // entry point, which is named by prepending a "." before the function's
+ // C-linkage name. A Qualname is returned here because an external
+ // function entry point is a csect with XTY_ER property.
+ const auto getExternalFunctionEntryPointSymbol = [&](StringRef SymName) {
+ auto &Context = DAG.getMachineFunction().getMMI().getContext();
+ MCSectionXCOFF *Sec = Context.getXCOFFSection(
+ (Twine(".") + Twine(SymName)).str(), XCOFF::XMC_PR, XCOFF::XTY_ER,
+ SectionKind::getMetadata());
+ return Sec->getQualNameSymbol();
+ };
+
+ SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
}
- return DAG.getTargetExternalSymbol(SymName, Callee.getValueType(),
- UsePlt ? PPCII::MO_PLT : 0);
+ return DAG.getTargetExternalSymbol(SymName, Callee.getValueType(),
+ UsePlt ? PPCII::MO_PLT : 0);
}
// No transformation needed.
@@ -5461,11 +5461,11 @@ PPCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
InVals, CB);
- assert(Subtarget.isSVR4ABI());
- if (Subtarget.isPPC64())
- return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
- InVals, CB);
- return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
+ assert(Subtarget.isSVR4ABI());
+ if (Subtarget.isPPC64())
+ return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
+ InVals, CB);
+ return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
InVals, CB);
}
@@ -5789,8 +5789,8 @@ SDValue PPCTargetLowering::LowerCall_64SVR4(
for (unsigned i = 0; i != NumOps; ++i) {
if (Outs[i].Flags.isNest()) continue;
if (CalculateStackSlotUsed(Outs[i].VT, Outs[i].ArgVT, Outs[i].Flags,
- PtrByteSize, LinkageSize, ParamAreaSize,
- NumBytesTmp, AvailableFPRs, AvailableVRs))
+ PtrByteSize, LinkageSize, ParamAreaSize,
+ NumBytesTmp, AvailableFPRs, AvailableVRs))
HasParameterArea = true;
}
}
@@ -5838,8 +5838,8 @@ SDValue PPCTargetLowering::LowerCall_64SVR4(
continue;
break;
case MVT::v4f32:
- if (++NumVRsUsed <= NumVRs)
- continue;
+ if (++NumVRsUsed <= NumVRs)
+ continue;
break;
case MVT::f32:
case MVT::f64:
@@ -6322,10 +6322,10 @@ static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT,
const Align PtrAlign = IsPPC64 ? Align(8) : Align(4);
const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
- if (ValVT.isVector() && !State.getMachineFunction()
- .getTarget()
- .Options.EnableAIXExtendedAltivecABI)
- report_fatal_error("the default Altivec AIX ABI is not yet supported");
+ if (ValVT.isVector() && !State.getMachineFunction()
+ .getTarget()
+ .Options.EnableAIXExtendedAltivecABI)
+ report_fatal_error("the default Altivec AIX ABI is not yet supported");
if (ValVT == MVT::f128)
report_fatal_error("f128 is unimplemented on AIX.");
@@ -6340,11 +6340,11 @@ static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT,
PPC::X3, PPC::X4, PPC::X5, PPC::X6,
PPC::X7, PPC::X8, PPC::X9, PPC::X10};
- static const MCPhysReg VR[] = {// Vector registers.
- PPC::V2, PPC::V3, PPC::V4, PPC::V5,
- PPC::V6, PPC::V7, PPC::V8, PPC::V9,
- PPC::V10, PPC::V11, PPC::V12, PPC::V13};
-
+ static const MCPhysReg VR[] = {// Vector registers.
+ PPC::V2, PPC::V3, PPC::V4, PPC::V5,
+ PPC::V6, PPC::V7, PPC::V8, PPC::V9,
+ PPC::V10, PPC::V11, PPC::V12, PPC::V13};
+
if (ArgFlags.isByVal()) {
if (ArgFlags.getNonZeroByValAlign() > PtrAlign)
report_fatal_error("Pass-by-value arguments with alignment greater than "
@@ -6389,7 +6389,7 @@ static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT,
case MVT::i32: {
const unsigned Offset = State.AllocateStack(PtrAlign.value(), PtrAlign);
// AIX integer arguments are always passed in register width.
- if (ValVT.getFixedSizeInBits() < RegVT.getFixedSizeInBits())
+ if (ValVT.getFixedSizeInBits() < RegVT.getFixedSizeInBits())
LocInfo = ArgFlags.isSExt() ? CCValAssign::LocInfo::SExt
: CCValAssign::LocInfo::ZExt;
if (unsigned Reg = State.AllocateReg(IsPPC64 ? GPR_64 : GPR_32))
@@ -6440,26 +6440,26 @@ static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT,
return false;
}
- case MVT::v4f32:
- case MVT::v4i32:
- case MVT::v8i16:
- case MVT::v16i8:
- case MVT::v2i64:
- case MVT::v2f64:
- case MVT::v1i128: {
- if (State.isVarArg())
- report_fatal_error(
- "variadic arguments for vector types are unimplemented for AIX");
-
- if (unsigned VReg = State.AllocateReg(VR))
- State.addLoc(CCValAssign::getReg(ValNo, ValVT, VReg, LocVT, LocInfo));
- else {
- report_fatal_error(
- "passing vector parameters to the stack is unimplemented for AIX");
- }
- return false;
- }
- }
+ case MVT::v4f32:
+ case MVT::v4i32:
+ case MVT::v8i16:
+ case MVT::v16i8:
+ case MVT::v2i64:
+ case MVT::v2f64:
+ case MVT::v1i128: {
+ if (State.isVarArg())
+ report_fatal_error(
+ "variadic arguments for vector types are unimplemented for AIX");
+
+ if (unsigned VReg = State.AllocateReg(VR))
+ State.addLoc(CCValAssign::getReg(ValNo, ValVT, VReg, LocVT, LocInfo));
+ else {
+ report_fatal_error(
+ "passing vector parameters to the stack is unimplemented for AIX");
+ }
+ return false;
+ }
+ }
return true;
}
@@ -6479,14 +6479,14 @@ static const TargetRegisterClass *getRegClassForSVT(MVT::SimpleValueType SVT,
return &PPC::F4RCRegClass;
case MVT::f64:
return &PPC::F8RCRegClass;
- case MVT::v4f32:
- case MVT::v4i32:
- case MVT::v8i16:
- case MVT::v16i8:
- case MVT::v2i64:
- case MVT::v2f64:
- case MVT::v1i128:
- return &PPC::VRRCRegClass;
+ case MVT::v4f32:
+ case MVT::v4i32:
+ case MVT::v8i16:
+ case MVT::v16i8:
+ case MVT::v2i64:
+ case MVT::v2f64:
+ case MVT::v1i128:
+ return &PPC::VRRCRegClass;
}
}
@@ -6494,7 +6494,7 @@ static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT,
SelectionDAG &DAG, SDValue ArgValue,
MVT LocVT, const SDLoc &dl) {
assert(ValVT.isScalarInteger() && LocVT.isScalarInteger());
- assert(ValVT.getFixedSizeInBits() < LocVT.getFixedSizeInBits());
+ assert(ValVT.getFixedSizeInBits() < LocVT.getFixedSizeInBits());
if (Flags.isSExt())
ArgValue = DAG.getNode(ISD::AssertSext, dl, LocVT, ArgValue,
@@ -6589,7 +6589,7 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
SmallVector<CCValAssign, 16> ArgLocs;
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo &MFI = MF.getFrameInfo();
- PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
+ PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.getContext());
const EVT PtrVT = getPointerTy(MF.getDataLayout());
@@ -6604,9 +6604,9 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
CCValAssign &VA = ArgLocs[I++];
MVT LocVT = VA.getLocVT();
ISD::ArgFlagsTy Flags = Ins[VA.getValNo()].Flags;
- if (VA.isMemLoc() && VA.getValVT().isVector())
- report_fatal_error(
- "passing vector parameters to the stack is unimplemented for AIX");
+ if (VA.isMemLoc() && VA.getValVT().isVector())
+ report_fatal_error(
+ "passing vector parameters to the stack is unimplemented for AIX");
// For compatibility with the AIX XL compiler, the float args in the
// parameter save area are initialized even if the argument is available
@@ -6617,15 +6617,15 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
if (VA.isMemLoc() && VA.needsCustom())
continue;
- if (VA.isRegLoc()) {
- if (VA.getValVT().isScalarInteger())
- FuncInfo->appendParameterType(PPCFunctionInfo::FixedType);
- else if (VA.getValVT().isFloatingPoint() && !VA.getValVT().isVector())
- FuncInfo->appendParameterType(VA.getValVT().SimpleTy == MVT::f32
- ? PPCFunctionInfo::ShortFloatPoint
- : PPCFunctionInfo::LongFloatPoint);
- }
-
+ if (VA.isRegLoc()) {
+ if (VA.getValVT().isScalarInteger())
+ FuncInfo->appendParameterType(PPCFunctionInfo::FixedType);
+ else if (VA.getValVT().isFloatingPoint() && !VA.getValVT().isVector())
+ FuncInfo->appendParameterType(VA.getValVT().SimpleTy == MVT::f32
+ ? PPCFunctionInfo::ShortFloatPoint
+ : PPCFunctionInfo::LongFloatPoint);
+ }
+
if (Flags.isByVal() && VA.isMemLoc()) {
const unsigned Size =
alignTo(Flags.getByValSize() ? Flags.getByValSize() : PtrByteSize,
@@ -6671,10 +6671,10 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
// to extracting the value from the register directly, and elide the
// stores when the arguments address is not taken, but that will need to
// be future work.
- SDValue Store = DAG.getStore(
- CopyFrom.getValue(1), dl, CopyFrom,
- DAG.getObjectPtrOffset(dl, FIN, TypeSize::Fixed(Offset)),
- MachinePointerInfo::getFixedStack(MF, FI, Offset));
+ SDValue Store = DAG.getStore(
+ CopyFrom.getValue(1), dl, CopyFrom,
+ DAG.getObjectPtrOffset(dl, FIN, TypeSize::Fixed(Offset)),
+ MachinePointerInfo::getFixedStack(MF, FI, Offset));
MemOps.push_back(Store);
};
@@ -6689,7 +6689,7 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
const CCValAssign RL = ArgLocs[I++];
HandleRegLoc(RL.getLocReg(), Offset);
- FuncInfo->appendParameterType(PPCFunctionInfo::FixedType);
+ FuncInfo->appendParameterType(PPCFunctionInfo::FixedType);
}
if (Offset != StackSize) {
@@ -6711,7 +6711,7 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
MF.addLiveIn(VA.getLocReg(), getRegClassForSVT(SVT, IsPPC64));
SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, LocVT);
if (ValVT.isScalarInteger() &&
- (ValVT.getFixedSizeInBits() < LocVT.getFixedSizeInBits())) {
+ (ValVT.getFixedSizeInBits() < LocVT.getFixedSizeInBits())) {
ArgValue =
truncateScalarIntegerArg(Flags, ValVT, DAG, ArgValue, LocVT, dl);
}
@@ -6869,12 +6869,12 @@ SDValue PPCTargetLowering::LowerCall_AIX(
}
auto GetLoad = [&](EVT VT, unsigned LoadOffset) {
- return DAG.getExtLoad(
- ISD::ZEXTLOAD, dl, PtrVT, Chain,
- (LoadOffset != 0)
- ? DAG.getObjectPtrOffset(dl, Arg, TypeSize::Fixed(LoadOffset))
- : Arg,
- MachinePointerInfo(), VT);
+ return DAG.getExtLoad(
+ ISD::ZEXTLOAD, dl, PtrVT, Chain,
+ (LoadOffset != 0)
+ ? DAG.getObjectPtrOffset(dl, Arg, TypeSize::Fixed(LoadOffset))
+ : Arg,
+ MachinePointerInfo(), VT);
};
unsigned LoadOffset = 0;
@@ -6904,11 +6904,11 @@ SDValue PPCTargetLowering::LowerCall_AIX(
// Only memcpy the bytes that don't pass in register.
MemcpyFlags.setByValSize(ByValSize - LoadOffset);
Chain = CallSeqStart = createMemcpyOutsideCallSeq(
- (LoadOffset != 0)
- ? DAG.getObjectPtrOffset(dl, Arg, TypeSize::Fixed(LoadOffset))
- : Arg,
- DAG.getObjectPtrOffset(dl, StackPtr,
- TypeSize::Fixed(ByValVA.getLocMemOffset())),
+ (LoadOffset != 0)
+ ? DAG.getObjectPtrOffset(dl, Arg, TypeSize::Fixed(LoadOffset))
+ : Arg,
+ DAG.getObjectPtrOffset(dl, StackPtr,
+ TypeSize::Fixed(ByValVA.getLocMemOffset())),
CallSeqStart, MemcpyFlags, DAG, dl);
continue;
}
@@ -6958,10 +6958,10 @@ SDValue PPCTargetLowering::LowerCall_AIX(
const MVT LocVT = VA.getLocVT();
const MVT ValVT = VA.getValVT();
- if (VA.isMemLoc() && VA.getValVT().isVector())
- report_fatal_error(
- "passing vector parameters to the stack is unimplemented for AIX");
-
+ if (VA.isMemLoc() && VA.getValVT().isVector())
+ report_fatal_error(
+ "passing vector parameters to the stack is unimplemented for AIX");
+
switch (VA.getLocInfo()) {
default:
report_fatal_error("Unexpected argument extension type.");
@@ -7003,8 +7003,8 @@ SDValue PPCTargetLowering::LowerCall_AIX(
// f32 in 32-bit GPR
// f64 in 64-bit GPR
RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgAsInt));
- else if (Arg.getValueType().getFixedSizeInBits() <
- LocVT.getFixedSizeInBits())
+ else if (Arg.getValueType().getFixedSizeInBits() <
+ LocVT.getFixedSizeInBits())
// f32 in 64-bit GPR.
RegsToPass.push_back(std::make_pair(
VA.getLocReg(), DAG.getZExtOrTrunc(ArgAsInt, dl, LocVT)));
@@ -7363,45 +7363,45 @@ SDValue PPCTargetLowering::LowerTRUNCATEVector(SDValue Op,
// <uu, uu, uu, uu, uu, uu, LSB2|MSB2, LSB1|MSB1> to
// <u, u, u, u, u, u, u, u, u, u, u, u, u, u, LSB2, LSB1>
- EVT TrgVT = Op.getValueType();
- assert(TrgVT.isVector() && "Vector type expected.");
- unsigned TrgNumElts = TrgVT.getVectorNumElements();
- EVT EltVT = TrgVT.getVectorElementType();
- if (!isOperationCustom(Op.getOpcode(), TrgVT) ||
- TrgVT.getSizeInBits() > 128 || !isPowerOf2_32(TrgNumElts) ||
- !isPowerOf2_32(EltVT.getSizeInBits()))
- return SDValue();
+ EVT TrgVT = Op.getValueType();
+ assert(TrgVT.isVector() && "Vector type expected.");
+ unsigned TrgNumElts = TrgVT.getVectorNumElements();
+ EVT EltVT = TrgVT.getVectorElementType();
+ if (!isOperationCustom(Op.getOpcode(), TrgVT) ||
+ TrgVT.getSizeInBits() > 128 || !isPowerOf2_32(TrgNumElts) ||
+ !isPowerOf2_32(EltVT.getSizeInBits()))
+ return SDValue();
SDValue N1 = Op.getOperand(0);
- EVT SrcVT = N1.getValueType();
- unsigned SrcSize = SrcVT.getSizeInBits();
- if (SrcSize > 256 ||
- !isPowerOf2_32(SrcVT.getVectorNumElements()) ||
- !isPowerOf2_32(SrcVT.getVectorElementType().getSizeInBits()))
- return SDValue();
- if (SrcSize == 256 && SrcVT.getVectorNumElements() < 2)
- return SDValue();
+ EVT SrcVT = N1.getValueType();
+ unsigned SrcSize = SrcVT.getSizeInBits();
+ if (SrcSize > 256 ||
+ !isPowerOf2_32(SrcVT.getVectorNumElements()) ||
+ !isPowerOf2_32(SrcVT.getVectorElementType().getSizeInBits()))
+ return SDValue();
+ if (SrcSize == 256 && SrcVT.getVectorNumElements() < 2)
+ return SDValue();
unsigned WideNumElts = 128 / EltVT.getSizeInBits();
EVT WideVT = EVT::getVectorVT(*DAG.getContext(), EltVT, WideNumElts);
- SDLoc DL(Op);
- SDValue Op1, Op2;
- if (SrcSize == 256) {
- EVT VecIdxTy = getVectorIdxTy(DAG.getDataLayout());
- EVT SplitVT =
- N1.getValueType().getHalfNumVectorElementsVT(*DAG.getContext());
- unsigned SplitNumElts = SplitVT.getVectorNumElements();
- Op1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SplitVT, N1,
- DAG.getConstant(0, DL, VecIdxTy));
- Op2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SplitVT, N1,
- DAG.getConstant(SplitNumElts, DL, VecIdxTy));
- }
- else {
- Op1 = SrcSize == 128 ? N1 : widenVec(DAG, N1, DL);
- Op2 = DAG.getUNDEF(WideVT);
- }
-
+ SDLoc DL(Op);
+ SDValue Op1, Op2;
+ if (SrcSize == 256) {
+ EVT VecIdxTy = getVectorIdxTy(DAG.getDataLayout());
+ EVT SplitVT =
+ N1.getValueType().getHalfNumVectorElementsVT(*DAG.getContext());
+ unsigned SplitNumElts = SplitVT.getVectorNumElements();
+ Op1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SplitVT, N1,
+ DAG.getConstant(0, DL, VecIdxTy));
+ Op2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SplitVT, N1,
+ DAG.getConstant(SplitNumElts, DL, VecIdxTy));
+ }
+ else {
+ Op1 = SrcSize == 128 ? N1 : widenVec(DAG, N1, DL);
+ Op2 = DAG.getUNDEF(WideVT);
+ }
+
// First list the elements we want to keep.
unsigned SizeMult = SrcSize / TrgVT.getSizeInBits();
SmallVector<int, 16> ShuffV;
@@ -7417,17 +7417,17 @@ SDValue PPCTargetLowering::LowerTRUNCATEVector(SDValue Op,
// ShuffV.push_back(i + WideNumElts);
ShuffV.push_back(WideNumElts + 1);
- Op1 = DAG.getNode(ISD::BITCAST, DL, WideVT, Op1);
- Op2 = DAG.getNode(ISD::BITCAST, DL, WideVT, Op2);
- return DAG.getVectorShuffle(WideVT, DL, Op1, Op2, ShuffV);
+ Op1 = DAG.getNode(ISD::BITCAST, DL, WideVT, Op1);
+ Op2 = DAG.getNode(ISD::BITCAST, DL, WideVT, Op2);
+ return DAG.getVectorShuffle(WideVT, DL, Op1, Op2, ShuffV);
}
/// LowerSELECT_CC - Lower floating point select_cc's into fsel instruction when
/// possible.
SDValue PPCTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
- // Not FP, or using SPE? Not a fsel.
+ // Not FP, or using SPE? Not a fsel.
if (!Op.getOperand(0).getValueType().isFloatingPoint() ||
- !Op.getOperand(2).getValueType().isFloatingPoint() || Subtarget.hasSPE())
+ !Op.getOperand(2).getValueType().isFloatingPoint() || Subtarget.hasSPE())
return Op;
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
@@ -7543,105 +7543,105 @@ SDValue PPCTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
return Op;
}
-static unsigned getPPCStrictOpcode(unsigned Opc) {
- switch (Opc) {
- default:
- llvm_unreachable("No strict version of this opcode!");
- case PPCISD::FCTIDZ:
- return PPCISD::STRICT_FCTIDZ;
- case PPCISD::FCTIWZ:
- return PPCISD::STRICT_FCTIWZ;
- case PPCISD::FCTIDUZ:
- return PPCISD::STRICT_FCTIDUZ;
- case PPCISD::FCTIWUZ:
- return PPCISD::STRICT_FCTIWUZ;
- case PPCISD::FCFID:
- return PPCISD::STRICT_FCFID;
- case PPCISD::FCFIDU:
- return PPCISD::STRICT_FCFIDU;
- case PPCISD::FCFIDS:
- return PPCISD::STRICT_FCFIDS;
- case PPCISD::FCFIDUS:
- return PPCISD::STRICT_FCFIDUS;
- }
-}
-
-static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG,
- const PPCSubtarget &Subtarget) {
- SDLoc dl(Op);
- bool IsStrict = Op->isStrictFPOpcode();
- bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT ||
- Op.getOpcode() == ISD::STRICT_FP_TO_SINT;
-
- // TODO: Any other flags to propagate?
- SDNodeFlags Flags;
- Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());
-
- // For strict nodes, source is the second operand.
- SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
- SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
- assert(Src.getValueType().isFloatingPoint());
- if (Src.getValueType() == MVT::f32) {
- if (IsStrict) {
- Src =
- DAG.getNode(ISD::STRICT_FP_EXTEND, dl,
- DAG.getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
- Chain = Src.getValue(1);
- } else
- Src = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
- }
- SDValue Conv;
- unsigned Opc = ISD::DELETED_NODE;
+static unsigned getPPCStrictOpcode(unsigned Opc) {
+ switch (Opc) {
+ default:
+ llvm_unreachable("No strict version of this opcode!");
+ case PPCISD::FCTIDZ:
+ return PPCISD::STRICT_FCTIDZ;
+ case PPCISD::FCTIWZ:
+ return PPCISD::STRICT_FCTIWZ;
+ case PPCISD::FCTIDUZ:
+ return PPCISD::STRICT_FCTIDUZ;
+ case PPCISD::FCTIWUZ:
+ return PPCISD::STRICT_FCTIWUZ;
+ case PPCISD::FCFID:
+ return PPCISD::STRICT_FCFID;
+ case PPCISD::FCFIDU:
+ return PPCISD::STRICT_FCFIDU;
+ case PPCISD::FCFIDS:
+ return PPCISD::STRICT_FCFIDS;
+ case PPCISD::FCFIDUS:
+ return PPCISD::STRICT_FCFIDUS;
+ }
+}
+
+static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG,
+ const PPCSubtarget &Subtarget) {
+ SDLoc dl(Op);
+ bool IsStrict = Op->isStrictFPOpcode();
+ bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT ||
+ Op.getOpcode() == ISD::STRICT_FP_TO_SINT;
+
+ // TODO: Any other flags to propagate?
+ SDNodeFlags Flags;
+ Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());
+
+ // For strict nodes, source is the second operand.
+ SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
+ SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
+ assert(Src.getValueType().isFloatingPoint());
+ if (Src.getValueType() == MVT::f32) {
+ if (IsStrict) {
+ Src =
+ DAG.getNode(ISD::STRICT_FP_EXTEND, dl,
+ DAG.getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
+ Chain = Src.getValue(1);
+ } else
+ Src = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
+ }
+ SDValue Conv;
+ unsigned Opc = ISD::DELETED_NODE;
switch (Op.getSimpleValueType().SimpleTy) {
default: llvm_unreachable("Unhandled FP_TO_INT type in custom expander!");
case MVT::i32:
- Opc = IsSigned ? PPCISD::FCTIWZ
- : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ);
+ Opc = IsSigned ? PPCISD::FCTIWZ
+ : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ);
break;
case MVT::i64:
- assert((IsSigned || Subtarget.hasFPCVT()) &&
+ assert((IsSigned || Subtarget.hasFPCVT()) &&
"i64 FP_TO_UINT is supported only with FPCVT");
- Opc = IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ;
- }
- if (IsStrict) {
- Opc = getPPCStrictOpcode(Opc);
- Conv = DAG.getNode(Opc, dl, DAG.getVTList(MVT::f64, MVT::Other),
- {Chain, Src}, Flags);
- } else {
- Conv = DAG.getNode(Opc, dl, MVT::f64, Src);
- }
- return Conv;
-}
-
-void PPCTargetLowering::LowerFP_TO_INTForReuse(SDValue Op, ReuseLoadInfo &RLI,
- SelectionDAG &DAG,
- const SDLoc &dl) const {
- SDValue Tmp = convertFPToInt(Op, DAG, Subtarget);
- bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT ||
- Op.getOpcode() == ISD::STRICT_FP_TO_SINT;
- bool IsStrict = Op->isStrictFPOpcode();
-
+ Opc = IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ;
+ }
+ if (IsStrict) {
+ Opc = getPPCStrictOpcode(Opc);
+ Conv = DAG.getNode(Opc, dl, DAG.getVTList(MVT::f64, MVT::Other),
+ {Chain, Src}, Flags);
+ } else {
+ Conv = DAG.getNode(Opc, dl, MVT::f64, Src);
+ }
+ return Conv;
+}
+
+void PPCTargetLowering::LowerFP_TO_INTForReuse(SDValue Op, ReuseLoadInfo &RLI,
+ SelectionDAG &DAG,
+ const SDLoc &dl) const {
+ SDValue Tmp = convertFPToInt(Op, DAG, Subtarget);
+ bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT ||
+ Op.getOpcode() == ISD::STRICT_FP_TO_SINT;
+ bool IsStrict = Op->isStrictFPOpcode();
+
// Convert the FP value to an int value through memory.
bool i32Stack = Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
- (IsSigned || Subtarget.hasFPCVT());
+ (IsSigned || Subtarget.hasFPCVT());
SDValue FIPtr = DAG.CreateStackTemporary(i32Stack ? MVT::i32 : MVT::f64);
int FI = cast<FrameIndexSDNode>(FIPtr)->getIndex();
MachinePointerInfo MPI =
MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI);
// Emit a store to the stack slot.
- SDValue Chain = IsStrict ? Tmp.getValue(1) : DAG.getEntryNode();
+ SDValue Chain = IsStrict ? Tmp.getValue(1) : DAG.getEntryNode();
Align Alignment(DAG.getEVTAlign(Tmp.getValueType()));
if (i32Stack) {
MachineFunction &MF = DAG.getMachineFunction();
Alignment = Align(4);
MachineMemOperand *MMO =
MF.getMachineMemOperand(MPI, MachineMemOperand::MOStore, 4, Alignment);
- SDValue Ops[] = { Chain, Tmp, FIPtr };
+ SDValue Ops[] = { Chain, Tmp, FIPtr };
Chain = DAG.getMemIntrinsicNode(PPCISD::STFIWX, dl,
DAG.getVTList(MVT::Other), Ops, MVT::i32, MMO);
} else
- Chain = DAG.getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
+ Chain = DAG.getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
// Result is a load from the stack slot. If loading 4 bytes, make sure to
// add in a bias on big endian.
@@ -7663,100 +7663,100 @@ void PPCTargetLowering::LowerFP_TO_INTForReuse(SDValue Op, ReuseLoadInfo &RLI,
SDValue PPCTargetLowering::LowerFP_TO_INTDirectMove(SDValue Op,
SelectionDAG &DAG,
const SDLoc &dl) const {
- SDValue Conv = convertFPToInt(Op, DAG, Subtarget);
- SDValue Mov = DAG.getNode(PPCISD::MFVSR, dl, Op.getValueType(), Conv);
- if (Op->isStrictFPOpcode())
- return DAG.getMergeValues({Mov, Conv.getValue(1)}, dl);
- else
- return Mov;
+ SDValue Conv = convertFPToInt(Op, DAG, Subtarget);
+ SDValue Mov = DAG.getNode(PPCISD::MFVSR, dl, Op.getValueType(), Conv);
+ if (Op->isStrictFPOpcode())
+ return DAG.getMergeValues({Mov, Conv.getValue(1)}, dl);
+ else
+ return Mov;
}
SDValue PPCTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
const SDLoc &dl) const {
- bool IsStrict = Op->isStrictFPOpcode();
- bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT ||
- Op.getOpcode() == ISD::STRICT_FP_TO_SINT;
- SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
- EVT SrcVT = Src.getValueType();
- EVT DstVT = Op.getValueType();
+ bool IsStrict = Op->isStrictFPOpcode();
+ bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT ||
+ Op.getOpcode() == ISD::STRICT_FP_TO_SINT;
+ SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
+ EVT SrcVT = Src.getValueType();
+ EVT DstVT = Op.getValueType();
// FP to INT conversions are legal for f128.
- if (SrcVT == MVT::f128)
- return Subtarget.hasP9Vector() ? Op : SDValue();
+ if (SrcVT == MVT::f128)
+ return Subtarget.hasP9Vector() ? Op : SDValue();
// Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
// PPC (the libcall is not available).
- if (SrcVT == MVT::ppcf128) {
- if (DstVT == MVT::i32) {
- // TODO: Conservatively pass only nofpexcept flag here. Need to check and
- // set other fast-math flags to FP operations in both strict and
- // non-strict cases. (FP_TO_SINT, FSUB)
- SDNodeFlags Flags;
- Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());
-
- if (IsSigned) {
- SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::f64, Src,
+ if (SrcVT == MVT::ppcf128) {
+ if (DstVT == MVT::i32) {
+ // TODO: Conservatively pass only nofpexcept flag here. Need to check and
+ // set other fast-math flags to FP operations in both strict and
+ // non-strict cases. (FP_TO_SINT, FSUB)
+ SDNodeFlags Flags;
+ Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());
+
+ if (IsSigned) {
+ SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::f64, Src,
DAG.getIntPtrConstant(0, dl));
- SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::f64, Src,
+ SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::f64, Src,
DAG.getIntPtrConstant(1, dl));
- // Add the two halves of the long double in round-to-zero mode, and use
- // a smaller FP_TO_SINT.
- if (IsStrict) {
- SDValue Res = DAG.getNode(PPCISD::STRICT_FADDRTZ, dl,
- DAG.getVTList(MVT::f64, MVT::Other),
- {Op.getOperand(0), Lo, Hi}, Flags);
- return DAG.getNode(ISD::STRICT_FP_TO_SINT, dl,
- DAG.getVTList(MVT::i32, MVT::Other),
- {Res.getValue(1), Res}, Flags);
- } else {
- SDValue Res = DAG.getNode(PPCISD::FADDRTZ, dl, MVT::f64, Lo, Hi);
- return DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Res);
- }
- } else {
+ // Add the two halves of the long double in round-to-zero mode, and use
+ // a smaller FP_TO_SINT.
+ if (IsStrict) {
+ SDValue Res = DAG.getNode(PPCISD::STRICT_FADDRTZ, dl,
+ DAG.getVTList(MVT::f64, MVT::Other),
+ {Op.getOperand(0), Lo, Hi}, Flags);
+ return DAG.getNode(ISD::STRICT_FP_TO_SINT, dl,
+ DAG.getVTList(MVT::i32, MVT::Other),
+ {Res.getValue(1), Res}, Flags);
+ } else {
+ SDValue Res = DAG.getNode(PPCISD::FADDRTZ, dl, MVT::f64, Lo, Hi);
+ return DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Res);
+ }
+ } else {
const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
APFloat APF = APFloat(APFloat::PPCDoubleDouble(), APInt(128, TwoE31));
- SDValue Cst = DAG.getConstantFP(APF, dl, SrcVT);
- SDValue SignMask = DAG.getConstant(0x80000000, dl, DstVT);
- if (IsStrict) {
- // Sel = Src < 0x80000000
- // FltOfs = select Sel, 0.0, 0x80000000
- // IntOfs = select Sel, 0, 0x80000000
- // Result = fp_to_sint(Src - FltOfs) ^ IntOfs
- SDValue Chain = Op.getOperand(0);
- EVT SetCCVT =
- getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), SrcVT);
- EVT DstSetCCVT =
- getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), DstVT);
- SDValue Sel = DAG.getSetCC(dl, SetCCVT, Src, Cst, ISD::SETLT,
- Chain, true);
- Chain = Sel.getValue(1);
-
- SDValue FltOfs = DAG.getSelect(
- dl, SrcVT, Sel, DAG.getConstantFP(0.0, dl, SrcVT), Cst);
- Sel = DAG.getBoolExtOrTrunc(Sel, dl, DstSetCCVT, DstVT);
-
- SDValue Val = DAG.getNode(ISD::STRICT_FSUB, dl,
- DAG.getVTList(SrcVT, MVT::Other),
- {Chain, Src, FltOfs}, Flags);
- Chain = Val.getValue(1);
- SDValue SInt = DAG.getNode(ISD::STRICT_FP_TO_SINT, dl,
- DAG.getVTList(DstVT, MVT::Other),
- {Chain, Val}, Flags);
- Chain = SInt.getValue(1);
- SDValue IntOfs = DAG.getSelect(
- dl, DstVT, Sel, DAG.getConstant(0, dl, DstVT), SignMask);
- SDValue Result = DAG.getNode(ISD::XOR, dl, DstVT, SInt, IntOfs);
- return DAG.getMergeValues({Result, Chain}, dl);
- } else {
- // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X
- // FIXME: generated code sucks.
- SDValue True = DAG.getNode(ISD::FSUB, dl, MVT::ppcf128, Src, Cst);
- True = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, True);
- True = DAG.getNode(ISD::ADD, dl, MVT::i32, True, SignMask);
- SDValue False = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Src);
- return DAG.getSelectCC(dl, Src, Cst, True, False, ISD::SETGE);
- }
+ SDValue Cst = DAG.getConstantFP(APF, dl, SrcVT);
+ SDValue SignMask = DAG.getConstant(0x80000000, dl, DstVT);
+ if (IsStrict) {
+ // Sel = Src < 0x80000000
+ // FltOfs = select Sel, 0.0, 0x80000000
+ // IntOfs = select Sel, 0, 0x80000000
+ // Result = fp_to_sint(Src - FltOfs) ^ IntOfs
+ SDValue Chain = Op.getOperand(0);
+ EVT SetCCVT =
+ getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), SrcVT);
+ EVT DstSetCCVT =
+ getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), DstVT);
+ SDValue Sel = DAG.getSetCC(dl, SetCCVT, Src, Cst, ISD::SETLT,
+ Chain, true);
+ Chain = Sel.getValue(1);
+
+ SDValue FltOfs = DAG.getSelect(
+ dl, SrcVT, Sel, DAG.getConstantFP(0.0, dl, SrcVT), Cst);
+ Sel = DAG.getBoolExtOrTrunc(Sel, dl, DstSetCCVT, DstVT);
+
+ SDValue Val = DAG.getNode(ISD::STRICT_FSUB, dl,
+ DAG.getVTList(SrcVT, MVT::Other),
+ {Chain, Src, FltOfs}, Flags);
+ Chain = Val.getValue(1);
+ SDValue SInt = DAG.getNode(ISD::STRICT_FP_TO_SINT, dl,
+ DAG.getVTList(DstVT, MVT::Other),
+ {Chain, Val}, Flags);
+ Chain = SInt.getValue(1);
+ SDValue IntOfs = DAG.getSelect(
+ dl, DstVT, Sel, DAG.getConstant(0, dl, DstVT), SignMask);
+ SDValue Result = DAG.getNode(ISD::XOR, dl, DstVT, SInt, IntOfs);
+ return DAG.getMergeValues({Result, Chain}, dl);
+ } else {
+ // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X
+ // FIXME: generated code sucks.
+ SDValue True = DAG.getNode(ISD::FSUB, dl, MVT::ppcf128, Src, Cst);
+ True = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, True);
+ True = DAG.getNode(ISD::ADD, dl, MVT::i32, True, SignMask);
+ SDValue False = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Src);
+ return DAG.getSelectCC(dl, Src, Cst, True, False, ISD::SETGE);
+ }
}
}
@@ -7785,10 +7785,10 @@ bool PPCTargetLowering::canReuseLoadAddress(SDValue Op, EVT MemVT,
ReuseLoadInfo &RLI,
SelectionDAG &DAG,
ISD::LoadExtType ET) const {
- // Conservatively skip reusing for constrained FP nodes.
- if (Op->isStrictFPOpcode())
- return false;
-
+ // Conservatively skip reusing for constrained FP nodes.
+ if (Op->isStrictFPOpcode())
+ return false;
+
SDLoc dl(Op);
bool ValidFPToUint = Op.getOpcode() == ISD::FP_TO_UINT &&
(Subtarget.hasFPCVT() || Op.getValueType() == MVT::i32);
@@ -7808,13 +7808,13 @@ bool PPCTargetLowering::canReuseLoadAddress(SDValue Op, EVT MemVT,
if (LD->getMemoryVT() != MemVT)
return false;
- // If the result of the load is an illegal type, then we can't build a
- // valid chain for reuse since the legalised loads and token factor node that
- // ties the legalised loads together uses a different output chain then the
- // illegal load.
- if (!isTypeLegal(LD->getValueType(0)))
- return false;
-
+ // If the result of the load is an illegal type, then we can't build a
+ // valid chain for reuse since the legalised loads and token factor node that
+ // ties the legalised loads together uses a different output chain then the
+ // illegal load.
+ if (!isTypeLegal(LD->getValueType(0)))
+ return false;
+
RLI.Ptr = LD->getBasePtr();
if (LD->isIndexed() && !LD->getOffset().isUndef()) {
assert(LD->getAddressingMode() == ISD::PRE_INC &&
@@ -7879,41 +7879,41 @@ bool PPCTargetLowering::directMoveIsProfitable(const SDValue &Op) const {
continue;
if (UI->getOpcode() != ISD::SINT_TO_FP &&
- UI->getOpcode() != ISD::UINT_TO_FP &&
- UI->getOpcode() != ISD::STRICT_SINT_TO_FP &&
- UI->getOpcode() != ISD::STRICT_UINT_TO_FP)
+ UI->getOpcode() != ISD::UINT_TO_FP &&
+ UI->getOpcode() != ISD::STRICT_SINT_TO_FP &&
+ UI->getOpcode() != ISD::STRICT_UINT_TO_FP)
return true;
}
return false;
}
-static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG,
- const PPCSubtarget &Subtarget,
- SDValue Chain = SDValue()) {
- bool IsSigned = Op.getOpcode() == ISD::SINT_TO_FP ||
- Op.getOpcode() == ISD::STRICT_SINT_TO_FP;
- SDLoc dl(Op);
-
- // TODO: Any other flags to propagate?
- SDNodeFlags Flags;
- Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());
-
- // If we have FCFIDS, then use it when converting to single-precision.
- // Otherwise, convert to double-precision and then round.
- bool IsSingle = Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
- unsigned ConvOpc = IsSingle ? (IsSigned ? PPCISD::FCFIDS : PPCISD::FCFIDUS)
- : (IsSigned ? PPCISD::FCFID : PPCISD::FCFIDU);
- EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
- if (Op->isStrictFPOpcode()) {
- if (!Chain)
- Chain = Op.getOperand(0);
- return DAG.getNode(getPPCStrictOpcode(ConvOpc), dl,
- DAG.getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
- } else
- return DAG.getNode(ConvOpc, dl, ConvTy, Src);
-}
-
+static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG,
+ const PPCSubtarget &Subtarget,
+ SDValue Chain = SDValue()) {
+ bool IsSigned = Op.getOpcode() == ISD::SINT_TO_FP ||
+ Op.getOpcode() == ISD::STRICT_SINT_TO_FP;
+ SDLoc dl(Op);
+
+ // TODO: Any other flags to propagate?
+ SDNodeFlags Flags;
+ Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());
+
+ // If we have FCFIDS, then use it when converting to single-precision.
+ // Otherwise, convert to double-precision and then round.
+ bool IsSingle = Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
+ unsigned ConvOpc = IsSingle ? (IsSigned ? PPCISD::FCFIDS : PPCISD::FCFIDUS)
+ : (IsSigned ? PPCISD::FCFID : PPCISD::FCFIDU);
+ EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
+ if (Op->isStrictFPOpcode()) {
+ if (!Chain)
+ Chain = Op.getOperand(0);
+ return DAG.getNode(getPPCStrictOpcode(ConvOpc), dl,
+ DAG.getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
+ } else
+ return DAG.getNode(ConvOpc, dl, ConvTy, Src);
+}
+
/// Custom lowers integer to floating point conversions to use
/// the direct move instructions available in ISA 2.07 to avoid the
/// need for load/store combinations.
@@ -7925,13 +7925,13 @@ SDValue PPCTargetLowering::LowerINT_TO_FPDirectMove(SDValue Op,
"Invalid floating point type as target of conversion");
assert(Subtarget.hasFPCVT() &&
"Int to FP conversions with direct moves require FPCVT");
- SDValue Src = Op.getOperand(Op->isStrictFPOpcode() ? 1 : 0);
+ SDValue Src = Op.getOperand(Op->isStrictFPOpcode() ? 1 : 0);
bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
- bool Signed = Op.getOpcode() == ISD::SINT_TO_FP ||
- Op.getOpcode() == ISD::STRICT_SINT_TO_FP;
- unsigned MovOpc = (WordInt && !Signed) ? PPCISD::MTVSRZ : PPCISD::MTVSRA;
- SDValue Mov = DAG.getNode(MovOpc, dl, MVT::f64, Src);
- return convertIntToFP(Op, Mov, DAG, Subtarget);
+ bool Signed = Op.getOpcode() == ISD::SINT_TO_FP ||
+ Op.getOpcode() == ISD::STRICT_SINT_TO_FP;
+ unsigned MovOpc = (WordInt && !Signed) ? PPCISD::MTVSRZ : PPCISD::MTVSRA;
+ SDValue Mov = DAG.getNode(MovOpc, dl, MVT::f64, Src);
+ return convertIntToFP(Op, Mov, DAG, Subtarget);
}
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl) {
@@ -7956,23 +7956,23 @@ static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl) {
SDValue PPCTargetLowering::LowerINT_TO_FPVector(SDValue Op, SelectionDAG &DAG,
const SDLoc &dl) const {
- bool IsStrict = Op->isStrictFPOpcode();
+ bool IsStrict = Op->isStrictFPOpcode();
unsigned Opc = Op.getOpcode();
- SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
- assert((Opc == ISD::UINT_TO_FP || Opc == ISD::SINT_TO_FP ||
- Opc == ISD::STRICT_UINT_TO_FP || Opc == ISD::STRICT_SINT_TO_FP) &&
+ SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
+ assert((Opc == ISD::UINT_TO_FP || Opc == ISD::SINT_TO_FP ||
+ Opc == ISD::STRICT_UINT_TO_FP || Opc == ISD::STRICT_SINT_TO_FP) &&
"Unexpected conversion type");
assert((Op.getValueType() == MVT::v2f64 || Op.getValueType() == MVT::v4f32) &&
"Supports conversions to v2f64/v4f32 only.");
- // TODO: Any other flags to propagate?
- SDNodeFlags Flags;
- Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());
-
- bool SignedConv = Opc == ISD::SINT_TO_FP || Opc == ISD::STRICT_SINT_TO_FP;
+ // TODO: Any other flags to propagate?
+ SDNodeFlags Flags;
+ Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());
+
+ bool SignedConv = Opc == ISD::SINT_TO_FP || Opc == ISD::STRICT_SINT_TO_FP;
bool FourEltRes = Op.getValueType() == MVT::v4f32;
- SDValue Wide = widenVec(DAG, Src, dl);
+ SDValue Wide = widenVec(DAG, Src, dl);
EVT WideVT = Wide.getValueType();
unsigned WideNumElts = WideVT.getVectorNumElements();
MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
@@ -7997,7 +7997,7 @@ SDValue PPCTargetLowering::LowerINT_TO_FPVector(SDValue Op, SelectionDAG &DAG,
SDValue Extend;
if (SignedConv) {
Arrange = DAG.getBitcast(IntermediateVT, Arrange);
- EVT ExtVT = Src.getValueType();
+ EVT ExtVT = Src.getValueType();
if (Subtarget.hasP9Altivec())
ExtVT = EVT::getVectorVT(*DAG.getContext(), WideVT.getVectorElementType(),
IntermediateVT.getVectorNumElements());
@@ -8007,27 +8007,27 @@ SDValue PPCTargetLowering::LowerINT_TO_FPVector(SDValue Op, SelectionDAG &DAG,
} else
Extend = DAG.getNode(ISD::BITCAST, dl, IntermediateVT, Arrange);
- if (IsStrict)
- return DAG.getNode(Opc, dl, DAG.getVTList(Op.getValueType(), MVT::Other),
- {Op.getOperand(0), Extend}, Flags);
-
+ if (IsStrict)
+ return DAG.getNode(Opc, dl, DAG.getVTList(Op.getValueType(), MVT::Other),
+ {Op.getOperand(0), Extend}, Flags);
+
return DAG.getNode(Opc, dl, Op.getValueType(), Extend);
}
SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
SelectionDAG &DAG) const {
SDLoc dl(Op);
- bool IsSigned = Op.getOpcode() == ISD::SINT_TO_FP ||
- Op.getOpcode() == ISD::STRICT_SINT_TO_FP;
- bool IsStrict = Op->isStrictFPOpcode();
- SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
- SDValue Chain = IsStrict ? Op.getOperand(0) : DAG.getEntryNode();
-
- // TODO: Any other flags to propagate?
- SDNodeFlags Flags;
- Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());
-
- EVT InVT = Src.getValueType();
+ bool IsSigned = Op.getOpcode() == ISD::SINT_TO_FP ||
+ Op.getOpcode() == ISD::STRICT_SINT_TO_FP;
+ bool IsStrict = Op->isStrictFPOpcode();
+ SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
+ SDValue Chain = IsStrict ? Op.getOperand(0) : DAG.getEntryNode();
+
+ // TODO: Any other flags to propagate?
+ SDNodeFlags Flags;
+ Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());
+
+ EVT InVT = Src.getValueType();
EVT OutVT = Op.getValueType();
if (OutVT.isVector() && OutVT.isFloatingPoint() &&
isOperationCustom(Op.getOpcode(), InVT))
@@ -8035,21 +8035,21 @@ SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
// Conversions to f128 are legal.
if (Op.getValueType() == MVT::f128)
- return Subtarget.hasP9Vector() ? Op : SDValue();
+ return Subtarget.hasP9Vector() ? Op : SDValue();
// Don't handle ppc_fp128 here; let it be lowered to a libcall.
if (Op.getValueType() != MVT::f32 && Op.getValueType() != MVT::f64)
return SDValue();
- if (Src.getValueType() == MVT::i1) {
- SDValue Sel = DAG.getNode(ISD::SELECT, dl, Op.getValueType(), Src,
- DAG.getConstantFP(1.0, dl, Op.getValueType()),
- DAG.getConstantFP(0.0, dl, Op.getValueType()));
- if (IsStrict)
- return DAG.getMergeValues({Sel, Chain}, dl);
- else
- return Sel;
- }
+ if (Src.getValueType() == MVT::i1) {
+ SDValue Sel = DAG.getNode(ISD::SELECT, dl, Op.getValueType(), Src,
+ DAG.getConstantFP(1.0, dl, Op.getValueType()),
+ DAG.getConstantFP(0.0, dl, Op.getValueType()));
+ if (IsStrict)
+ return DAG.getMergeValues({Sel, Chain}, dl);
+ else
+ return Sel;
+ }
// If we have direct moves, we can do all the conversion, skip the store/load
// however, without FPCVT we can't do most conversions.
@@ -8057,11 +8057,11 @@ SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
Subtarget.isPPC64() && Subtarget.hasFPCVT())
return LowerINT_TO_FPDirectMove(Op, DAG, dl);
- assert((IsSigned || Subtarget.hasFPCVT()) &&
+ assert((IsSigned || Subtarget.hasFPCVT()) &&
"UINT_TO_FP is supported only with FPCVT");
- if (Src.getValueType() == MVT::i64) {
- SDValue SINT = Src;
+ if (Src.getValueType() == MVT::i64) {
+ SDValue SINT = Src;
// When converting to single-precision, we actually need to convert
// to double-precision first and then round to single-precision.
// To avoid double-rounding effects during that operation, we have
@@ -8149,16 +8149,16 @@ SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
int FrameIdx = MFI.CreateStackObject(4, Align(4), false);
SDValue FIdx = DAG.getFrameIndex(FrameIdx, PtrVT);
- SDValue Store = DAG.getStore(Chain, dl, SINT.getOperand(0), FIdx,
- MachinePointerInfo::getFixedStack(
- DAG.getMachineFunction(), FrameIdx));
- Chain = Store;
+ SDValue Store = DAG.getStore(Chain, dl, SINT.getOperand(0), FIdx,
+ MachinePointerInfo::getFixedStack(
+ DAG.getMachineFunction(), FrameIdx));
+ Chain = Store;
assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
"Expected an i32 store");
RLI.Ptr = FIdx;
- RLI.Chain = Chain;
+ RLI.Chain = Chain;
RLI.MPI =
MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FrameIdx);
RLI.Alignment = Align(4);
@@ -8171,27 +8171,27 @@ SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
PPCISD::LFIWZX : PPCISD::LFIWAX,
dl, DAG.getVTList(MVT::f64, MVT::Other),
Ops, MVT::i32, MMO);
- Chain = Bits.getValue(1);
+ Chain = Bits.getValue(1);
} else
Bits = DAG.getNode(ISD::BITCAST, dl, MVT::f64, SINT);
- SDValue FP = convertIntToFP(Op, Bits, DAG, Subtarget, Chain);
- if (IsStrict)
- Chain = FP.getValue(1);
-
- if (Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
- if (IsStrict)
- FP = DAG.getNode(ISD::STRICT_FP_ROUND, dl,
- DAG.getVTList(MVT::f32, MVT::Other),
- {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
- else
- FP = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, FP,
- DAG.getIntPtrConstant(0, dl));
- }
+ SDValue FP = convertIntToFP(Op, Bits, DAG, Subtarget, Chain);
+ if (IsStrict)
+ Chain = FP.getValue(1);
+
+ if (Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
+ if (IsStrict)
+ FP = DAG.getNode(ISD::STRICT_FP_ROUND, dl,
+ DAG.getVTList(MVT::f32, MVT::Other),
+ {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
+ else
+ FP = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, FP,
+ DAG.getIntPtrConstant(0, dl));
+ }
return FP;
}
- assert(Src.getValueType() == MVT::i32 &&
+ assert(Src.getValueType() == MVT::i32 &&
"Unhandled INT_TO_FP type in custom expander!");
// Since we only generate this in 64-bit mode, we can take advantage of
// 64-bit registers. In particular, sign extend the input value into the
@@ -8205,20 +8205,20 @@ SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
ReuseLoadInfo RLI;
bool ReusingLoad;
- if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
+ if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
int FrameIdx = MFI.CreateStackObject(4, Align(4), false);
SDValue FIdx = DAG.getFrameIndex(FrameIdx, PtrVT);
- SDValue Store = DAG.getStore(Chain, dl, Src, FIdx,
- MachinePointerInfo::getFixedStack(
- DAG.getMachineFunction(), FrameIdx));
- Chain = Store;
+ SDValue Store = DAG.getStore(Chain, dl, Src, FIdx,
+ MachinePointerInfo::getFixedStack(
+ DAG.getMachineFunction(), FrameIdx));
+ Chain = Store;
assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
"Expected an i32 store");
RLI.Ptr = FIdx;
- RLI.Chain = Chain;
+ RLI.Chain = Chain;
RLI.MPI =
MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FrameIdx);
RLI.Alignment = Align(4);
@@ -8228,10 +8228,10 @@ SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
MF.getMachineMemOperand(RLI.MPI, MachineMemOperand::MOLoad, 4,
RLI.Alignment, RLI.AAInfo, RLI.Ranges);
SDValue Ops[] = { RLI.Chain, RLI.Ptr };
- Ld = DAG.getMemIntrinsicNode(IsSigned ? PPCISD::LFIWAX : PPCISD::LFIWZX, dl,
- DAG.getVTList(MVT::f64, MVT::Other), Ops,
- MVT::i32, MMO);
- Chain = Ld.getValue(1);
+ Ld = DAG.getMemIntrinsicNode(IsSigned ? PPCISD::LFIWAX : PPCISD::LFIWZX, dl,
+ DAG.getVTList(MVT::f64, MVT::Other), Ops,
+ MVT::i32, MMO);
+ Chain = Ld.getValue(1);
if (ReusingLoad)
spliceIntoChain(RLI.ResChain, Ld.getValue(1), DAG);
} else {
@@ -8241,34 +8241,34 @@ SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
int FrameIdx = MFI.CreateStackObject(8, Align(8), false);
SDValue FIdx = DAG.getFrameIndex(FrameIdx, PtrVT);
- SDValue Ext64 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i64, Src);
+ SDValue Ext64 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i64, Src);
// STD the extended value into the stack slot.
SDValue Store = DAG.getStore(
- Chain, dl, Ext64, FIdx,
+ Chain, dl, Ext64, FIdx,
MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FrameIdx));
- Chain = Store;
+ Chain = Store;
// Load the value as a double.
Ld = DAG.getLoad(
- MVT::f64, dl, Chain, FIdx,
+ MVT::f64, dl, Chain, FIdx,
MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FrameIdx));
- Chain = Ld.getValue(1);
+ Chain = Ld.getValue(1);
}
// FCFID it and return it.
- SDValue FP = convertIntToFP(Op, Ld, DAG, Subtarget, Chain);
- if (IsStrict)
- Chain = FP.getValue(1);
- if (Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
- if (IsStrict)
- FP = DAG.getNode(ISD::STRICT_FP_ROUND, dl,
- DAG.getVTList(MVT::f32, MVT::Other),
- {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
- else
- FP = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, FP,
- DAG.getIntPtrConstant(0, dl));
- }
+ SDValue FP = convertIntToFP(Op, Ld, DAG, Subtarget, Chain);
+ if (IsStrict)
+ Chain = FP.getValue(1);
+ if (Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
+ if (IsStrict)
+ FP = DAG.getNode(ISD::STRICT_FP_ROUND, dl,
+ DAG.getVTList(MVT::f32, MVT::Other),
+ {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
+ else
+ FP = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, FP,
+ DAG.getIntPtrConstant(0, dl));
+ }
return FP;
}
@@ -8303,24 +8303,24 @@ SDValue PPCTargetLowering::LowerFLT_ROUNDS_(SDValue Op,
SDValue MFFS = DAG.getNode(PPCISD::MFFS, dl, {MVT::f64, MVT::Other}, Chain);
Chain = MFFS.getValue(1);
- SDValue CWD;
- if (isTypeLegal(MVT::i64)) {
- CWD = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32,
- DAG.getNode(ISD::BITCAST, dl, MVT::i64, MFFS));
- } else {
- // Save FP register to stack slot
- int SSFI = MF.getFrameInfo().CreateStackObject(8, Align(8), false);
- SDValue StackSlot = DAG.getFrameIndex(SSFI, PtrVT);
- Chain = DAG.getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
-
- // Load FP Control Word from low 32 bits of stack slot.
- assert(hasBigEndianPartOrdering(MVT::i64, MF.getDataLayout()) &&
- "Stack slot adjustment is valid only on big endian subtargets!");
- SDValue Four = DAG.getConstant(4, dl, PtrVT);
- SDValue Addr = DAG.getNode(ISD::ADD, dl, PtrVT, StackSlot, Four);
- CWD = DAG.getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
- Chain = CWD.getValue(1);
- }
+ SDValue CWD;
+ if (isTypeLegal(MVT::i64)) {
+ CWD = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32,
+ DAG.getNode(ISD::BITCAST, dl, MVT::i64, MFFS));
+ } else {
+ // Save FP register to stack slot
+ int SSFI = MF.getFrameInfo().CreateStackObject(8, Align(8), false);
+ SDValue StackSlot = DAG.getFrameIndex(SSFI, PtrVT);
+ Chain = DAG.getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
+
+ // Load FP Control Word from low 32 bits of stack slot.
+ assert(hasBigEndianPartOrdering(MVT::i64, MF.getDataLayout()) &&
+ "Stack slot adjustment is valid only on big endian subtargets!");
+ SDValue Four = DAG.getConstant(4, dl, PtrVT);
+ SDValue Addr = DAG.getNode(ISD::ADD, dl, PtrVT, StackSlot, Four);
+ CWD = DAG.getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
+ Chain = CWD.getValue(1);
+ }
// Transform as necessary
SDValue CWD1 =
@@ -8431,31 +8431,31 @@ SDValue PPCTargetLowering::LowerSRA_PARTS(SDValue Op, SelectionDAG &DAG) const {
return DAG.getMergeValues(OutOps, dl);
}
-SDValue PPCTargetLowering::LowerFunnelShift(SDValue Op,
- SelectionDAG &DAG) const {
- SDLoc dl(Op);
- EVT VT = Op.getValueType();
- unsigned BitWidth = VT.getSizeInBits();
-
- bool IsFSHL = Op.getOpcode() == ISD::FSHL;
- SDValue X = Op.getOperand(0);
- SDValue Y = Op.getOperand(1);
- SDValue Z = Op.getOperand(2);
- EVT AmtVT = Z.getValueType();
-
- // fshl: (X << (Z % BW)) | (Y >> (BW - (Z % BW)))
- // fshr: (X << (BW - (Z % BW))) | (Y >> (Z % BW))
- // This is simpler than TargetLowering::expandFunnelShift because we can rely
- // on PowerPC shift by BW being well defined.
- Z = DAG.getNode(ISD::AND, dl, AmtVT, Z,
- DAG.getConstant(BitWidth - 1, dl, AmtVT));
- SDValue SubZ =
- DAG.getNode(ISD::SUB, dl, AmtVT, DAG.getConstant(BitWidth, dl, AmtVT), Z);
- X = DAG.getNode(PPCISD::SHL, dl, VT, X, IsFSHL ? Z : SubZ);
- Y = DAG.getNode(PPCISD::SRL, dl, VT, Y, IsFSHL ? SubZ : Z);
- return DAG.getNode(ISD::OR, dl, VT, X, Y);
-}
-
+SDValue PPCTargetLowering::LowerFunnelShift(SDValue Op,
+ SelectionDAG &DAG) const {
+ SDLoc dl(Op);
+ EVT VT = Op.getValueType();
+ unsigned BitWidth = VT.getSizeInBits();
+
+ bool IsFSHL = Op.getOpcode() == ISD::FSHL;
+ SDValue X = Op.getOperand(0);
+ SDValue Y = Op.getOperand(1);
+ SDValue Z = Op.getOperand(2);
+ EVT AmtVT = Z.getValueType();
+
+ // fshl: (X << (Z % BW)) | (Y >> (BW - (Z % BW)))
+ // fshr: (X << (BW - (Z % BW))) | (Y >> (Z % BW))
+ // This is simpler than TargetLowering::expandFunnelShift because we can rely
+ // on PowerPC shift by BW being well defined.
+ Z = DAG.getNode(ISD::AND, dl, AmtVT, Z,
+ DAG.getConstant(BitWidth - 1, dl, AmtVT));
+ SDValue SubZ =
+ DAG.getNode(ISD::SUB, dl, AmtVT, DAG.getConstant(BitWidth, dl, AmtVT), Z);
+ X = DAG.getNode(PPCISD::SHL, dl, VT, X, IsFSHL ? Z : SubZ);
+ Y = DAG.getNode(PPCISD::SRL, dl, VT, Y, IsFSHL ? SubZ : Z);
+ return DAG.getNode(ISD::OR, dl, VT, X, Y);
+}
+
//===----------------------------------------------------------------------===//
// Vector related lowering.
//
@@ -8471,7 +8471,7 @@ static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT,
EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
// For a splat with all ones, turn it to vspltisb 0xFF to canonicalize.
- if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
+ if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
SplatSize = 1;
Val = 0xFF;
}
@@ -8660,44 +8660,44 @@ SDValue PPCTargetLowering::LowerBUILD_VECTOR(SDValue Op,
// If it is a splat of a double, check if we can shrink it to a 32 bit
// non-denormal float which when converted back to double gives us the same
// double. This is to exploit the XXSPLTIDP instruction.
- // If we lose precision, we use XXSPLTI32DX.
- if (BVNIsConstantSplat && (SplatBitSize == 64) &&
- Subtarget.hasPrefixInstrs()) {
- // Check the type first to short-circuit so we don't modify APSplatBits if
- // this block isn't executed.
- if ((Op->getValueType(0) == MVT::v2f64) &&
- convertToNonDenormSingle(APSplatBits)) {
- SDValue SplatNode = DAG.getNode(
- PPCISD::XXSPLTI_SP_TO_DP, dl, MVT::v2f64,
- DAG.getTargetConstant(APSplatBits.getZExtValue(), dl, MVT::i32));
- return DAG.getBitcast(Op.getValueType(), SplatNode);
- } else {
- // We may lose precision, so we have to use XXSPLTI32DX.
-
- uint32_t Hi =
- (uint32_t)((APSplatBits.getZExtValue() & 0xFFFFFFFF00000000LL) >> 32);
- uint32_t Lo =
- (uint32_t)(APSplatBits.getZExtValue() & 0xFFFFFFFF);
- SDValue SplatNode = DAG.getUNDEF(MVT::v2i64);
-
- if (!Hi || !Lo)
- // If either load is 0, then we should generate XXLXOR to set to 0.
- SplatNode = DAG.getTargetConstant(0, dl, MVT::v2i64);
-
- if (Hi)
- SplatNode = DAG.getNode(
- PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
- DAG.getTargetConstant(0, dl, MVT::i32),
- DAG.getTargetConstant(Hi, dl, MVT::i32));
-
- if (Lo)
- SplatNode =
- DAG.getNode(PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
- DAG.getTargetConstant(1, dl, MVT::i32),
- DAG.getTargetConstant(Lo, dl, MVT::i32));
-
- return DAG.getBitcast(Op.getValueType(), SplatNode);
- }
+ // If we lose precision, we use XXSPLTI32DX.
+ if (BVNIsConstantSplat && (SplatBitSize == 64) &&
+ Subtarget.hasPrefixInstrs()) {
+ // Check the type first to short-circuit so we don't modify APSplatBits if
+ // this block isn't executed.
+ if ((Op->getValueType(0) == MVT::v2f64) &&
+ convertToNonDenormSingle(APSplatBits)) {
+ SDValue SplatNode = DAG.getNode(
+ PPCISD::XXSPLTI_SP_TO_DP, dl, MVT::v2f64,
+ DAG.getTargetConstant(APSplatBits.getZExtValue(), dl, MVT::i32));
+ return DAG.getBitcast(Op.getValueType(), SplatNode);
+ } else {
+ // We may lose precision, so we have to use XXSPLTI32DX.
+
+ uint32_t Hi =
+ (uint32_t)((APSplatBits.getZExtValue() & 0xFFFFFFFF00000000LL) >> 32);
+ uint32_t Lo =
+ (uint32_t)(APSplatBits.getZExtValue() & 0xFFFFFFFF);
+ SDValue SplatNode = DAG.getUNDEF(MVT::v2i64);
+
+ if (!Hi || !Lo)
+ // If either load is 0, then we should generate XXLXOR to set to 0.
+ SplatNode = DAG.getTargetConstant(0, dl, MVT::v2i64);
+
+ if (Hi)
+ SplatNode = DAG.getNode(
+ PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
+ DAG.getTargetConstant(0, dl, MVT::i32),
+ DAG.getTargetConstant(Hi, dl, MVT::i32));
+
+ if (Lo)
+ SplatNode =
+ DAG.getNode(PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
+ DAG.getTargetConstant(1, dl, MVT::i32),
+ DAG.getTargetConstant(Lo, dl, MVT::i32));
+
+ return DAG.getBitcast(Op.getValueType(), SplatNode);
+ }
}
if (!BVNIsConstantSplat || SplatBitSize > 32) {
@@ -8716,12 +8716,12 @@ SDValue PPCTargetLowering::LowerBUILD_VECTOR(SDValue Op,
// Checking for a single use of this load, we have to check for vector
// width (128 bits) / ElementSize uses (since each operand of the
// BUILD_VECTOR is a separate use of the value.
- unsigned NumUsesOfInputLD = 128 / ElementSize;
- for (SDValue BVInOp : Op->ops())
- if (BVInOp.isUndef())
- NumUsesOfInputLD--;
- assert(NumUsesOfInputLD > 0 && "No uses of input LD of a build_vector?");
- if (InputLoad->getNode()->hasNUsesOfValue(NumUsesOfInputLD, 0) &&
+ unsigned NumUsesOfInputLD = 128 / ElementSize;
+ for (SDValue BVInOp : Op->ops())
+ if (BVInOp.isUndef())
+ NumUsesOfInputLD--;
+ assert(NumUsesOfInputLD > 0 && "No uses of input LD of a build_vector?");
+ if (InputLoad->getNode()->hasNUsesOfValue(NumUsesOfInputLD, 0) &&
((Subtarget.hasVSX() && ElementSize == 64) ||
(Subtarget.hasP9Vector() && ElementSize == 32))) {
SDValue Ops[] = {
@@ -8729,21 +8729,21 @@ SDValue PPCTargetLowering::LowerBUILD_VECTOR(SDValue Op,
LD->getBasePtr(), // Ptr
DAG.getValueType(Op.getValueType()) // VT
};
- SDValue LdSplt = DAG.getMemIntrinsicNode(
- PPCISD::LD_SPLAT, dl, DAG.getVTList(Op.getValueType(), MVT::Other),
- Ops, LD->getMemoryVT(), LD->getMemOperand());
- // Replace all uses of the output chain of the original load with the
- // output chain of the new load.
- DAG.ReplaceAllUsesOfValueWith(InputLoad->getValue(1),
- LdSplt.getValue(1));
- return LdSplt;
+ SDValue LdSplt = DAG.getMemIntrinsicNode(
+ PPCISD::LD_SPLAT, dl, DAG.getVTList(Op.getValueType(), MVT::Other),
+ Ops, LD->getMemoryVT(), LD->getMemOperand());
+ // Replace all uses of the output chain of the original load with the
+ // output chain of the new load.
+ DAG.ReplaceAllUsesOfValueWith(InputLoad->getValue(1),
+ LdSplt.getValue(1));
+ return LdSplt;
}
}
- // In 64BIT mode BUILD_VECTOR nodes that are not constant splats of up to
- // 32-bits can be lowered to VSX instructions under certain conditions.
+ // In 64BIT mode BUILD_VECTOR nodes that are not constant splats of up to
+ // 32-bits can be lowered to VSX instructions under certain conditions.
// Without VSX, there is no pattern more efficient than expanding the node.
- if (Subtarget.hasVSX() && Subtarget.isPPC64() &&
+ if (Subtarget.hasVSX() && Subtarget.isPPC64() &&
haveEfficientBuildVectorPattern(BVN, Subtarget.hasDirectMove(),
Subtarget.hasP8Vector()))
return Op;
@@ -8772,7 +8772,7 @@ SDValue PPCTargetLowering::LowerBUILD_VECTOR(SDValue Op,
// make a 4-byte splat element. For example: 2-byte splat of 0xABAB can be
// turned into a 4-byte splat of 0xABABABAB.
if (Subtarget.hasPrefixInstrs() && SplatSize == 2)
- return getCanonicalConstSplat(SplatBits | (SplatBits << 16), SplatSize * 2,
+ return getCanonicalConstSplat(SplatBits | (SplatBits << 16), SplatSize * 2,
Op.getValueType(), DAG, dl);
if (Subtarget.hasPrefixInstrs() && SplatSize == 4)
@@ -9367,7 +9367,7 @@ SDValue PPCTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op,
SDValue LdSplt =
DAG.getMemIntrinsicNode(PPCISD::LD_SPLAT, dl, VTL,
Ops, LD->getMemoryVT(), LD->getMemOperand());
- DAG.ReplaceAllUsesOfValueWith(InputLoad->getValue(1), LdSplt.getValue(1));
+ DAG.ReplaceAllUsesOfValueWith(InputLoad->getValue(1), LdSplt.getValue(1));
if (LdSplt.getValueType() != SVOp->getValueType(0))
LdSplt = DAG.getBitcast(SVOp->getValueType(0), LdSplt);
return LdSplt;
@@ -9732,26 +9732,26 @@ static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc,
return false;
break;
- case Intrinsic::ppc_altivec_vcmpequq:
- case Intrinsic::ppc_altivec_vcmpgtsq:
- case Intrinsic::ppc_altivec_vcmpgtuq:
- if (!Subtarget.isISA3_1())
- return false;
- switch (IntrinsicID) {
- default:
- llvm_unreachable("Unknown comparison intrinsic.");
- case Intrinsic::ppc_altivec_vcmpequq:
- CompareOpc = 455;
- break;
- case Intrinsic::ppc_altivec_vcmpgtsq:
- CompareOpc = 903;
- break;
- case Intrinsic::ppc_altivec_vcmpgtuq:
- CompareOpc = 647;
- break;
- }
- break;
-
+ case Intrinsic::ppc_altivec_vcmpequq:
+ case Intrinsic::ppc_altivec_vcmpgtsq:
+ case Intrinsic::ppc_altivec_vcmpgtuq:
+ if (!Subtarget.isISA3_1())
+ return false;
+ switch (IntrinsicID) {
+ default:
+ llvm_unreachable("Unknown comparison intrinsic.");
+ case Intrinsic::ppc_altivec_vcmpequq:
+ CompareOpc = 455;
+ break;
+ case Intrinsic::ppc_altivec_vcmpgtsq:
+ CompareOpc = 903;
+ break;
+ case Intrinsic::ppc_altivec_vcmpgtuq:
+ CompareOpc = 647;
+ break;
+ }
+ break;
+
// VSX predicate comparisons use the same infrastructure
case Intrinsic::ppc_vsx_xvcmpeqdp_p:
case Intrinsic::ppc_vsx_xvcmpgedp_p:
@@ -9875,26 +9875,26 @@ static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc,
else
return false;
break;
- case Intrinsic::ppc_altivec_vcmpequq_p:
- case Intrinsic::ppc_altivec_vcmpgtsq_p:
- case Intrinsic::ppc_altivec_vcmpgtuq_p:
- if (!Subtarget.isISA3_1())
- return false;
- switch (IntrinsicID) {
- default:
- llvm_unreachable("Unknown comparison intrinsic.");
- case Intrinsic::ppc_altivec_vcmpequq_p:
- CompareOpc = 455;
- break;
- case Intrinsic::ppc_altivec_vcmpgtsq_p:
- CompareOpc = 903;
- break;
- case Intrinsic::ppc_altivec_vcmpgtuq_p:
- CompareOpc = 647;
- break;
- }
- isDot = true;
- break;
+ case Intrinsic::ppc_altivec_vcmpequq_p:
+ case Intrinsic::ppc_altivec_vcmpgtsq_p:
+ case Intrinsic::ppc_altivec_vcmpgtuq_p:
+ if (!Subtarget.isISA3_1())
+ return false;
+ switch (IntrinsicID) {
+ default:
+ llvm_unreachable("Unknown comparison intrinsic.");
+ case Intrinsic::ppc_altivec_vcmpequq_p:
+ CompareOpc = 455;
+ break;
+ case Intrinsic::ppc_altivec_vcmpgtsq_p:
+ CompareOpc = 903;
+ break;
+ case Intrinsic::ppc_altivec_vcmpgtuq_p:
+ CompareOpc = 647;
+ break;
+ }
+ isDot = true;
+ break;
}
return true;
}
@@ -9908,33 +9908,33 @@ SDValue PPCTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
SDLoc dl(Op);
- switch (IntrinsicID) {
- case Intrinsic::thread_pointer:
+ switch (IntrinsicID) {
+ case Intrinsic::thread_pointer:
// Reads the thread pointer register, used for __builtin_thread_pointer.
if (Subtarget.isPPC64())
return DAG.getRegister(PPC::X13, MVT::i64);
return DAG.getRegister(PPC::R2, MVT::i32);
-
- case Intrinsic::ppc_mma_disassemble_acc:
- case Intrinsic::ppc_vsx_disassemble_pair: {
- int NumVecs = 2;
- SDValue WideVec = Op.getOperand(1);
- if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
- NumVecs = 4;
- WideVec = DAG.getNode(PPCISD::XXMFACC, dl, MVT::v512i1, WideVec);
- }
- SmallVector<SDValue, 4> RetOps;
- for (int VecNo = 0; VecNo < NumVecs; VecNo++) {
- SDValue Extract = DAG.getNode(
- PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, WideVec,
- DAG.getConstant(Subtarget.isLittleEndian() ? NumVecs - 1 - VecNo
- : VecNo,
- dl, MVT::i64));
- RetOps.push_back(Extract);
- }
- return DAG.getMergeValues(RetOps, dl);
- }
- }
+
+ case Intrinsic::ppc_mma_disassemble_acc:
+ case Intrinsic::ppc_vsx_disassemble_pair: {
+ int NumVecs = 2;
+ SDValue WideVec = Op.getOperand(1);
+ if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
+ NumVecs = 4;
+ WideVec = DAG.getNode(PPCISD::XXMFACC, dl, MVT::v512i1, WideVec);
+ }
+ SmallVector<SDValue, 4> RetOps;
+ for (int VecNo = 0; VecNo < NumVecs; VecNo++) {
+ SDValue Extract = DAG.getNode(
+ PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, WideVec,
+ DAG.getConstant(Subtarget.isLittleEndian() ? NumVecs - 1 - VecNo
+ : VecNo,
+ dl, MVT::i64));
+ RetOps.push_back(Extract);
+ }
+ return DAG.getMergeValues(RetOps, dl);
+ }
+ }
// If this is a lowered altivec predicate compare, CompareOpc is set to the
// opcode number of the comparison.
@@ -9958,7 +9958,7 @@ SDValue PPCTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
DAG.getConstant(CompareOpc, dl, MVT::i32)
};
EVT VTs[] = { Op.getOperand(2).getValueType(), MVT::Glue };
- SDValue CompNode = DAG.getNode(PPCISD::VCMP_rec, dl, VTs, Ops);
+ SDValue CompNode = DAG.getNode(PPCISD::VCMP_rec, dl, VTs, Ops);
// Now that we have the comparison, emit a copy from the CR to a GPR.
// This is flagged to the above dot comparison.
@@ -10125,43 +10125,43 @@ SDValue PPCTargetLowering::LowerVectorLoad(SDValue Op,
LoadSDNode *LN = cast<LoadSDNode>(Op.getNode());
SDValue LoadChain = LN->getChain();
SDValue BasePtr = LN->getBasePtr();
- EVT VT = Op.getValueType();
-
- if (VT != MVT::v256i1 && VT != MVT::v512i1)
- return Op;
-
- // Type v256i1 is used for pairs and v512i1 is used for accumulators.
- // Here we create 2 or 4 v16i8 loads to load the pair or accumulator value in
- // 2 or 4 vsx registers.
- assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
- "Type unsupported without MMA");
- assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
- "Type unsupported without paired vector support");
- Align Alignment = LN->getAlign();
- SmallVector<SDValue, 4> Loads;
- SmallVector<SDValue, 4> LoadChains;
- unsigned NumVecs = VT.getSizeInBits() / 128;
- for (unsigned Idx = 0; Idx < NumVecs; ++Idx) {
- SDValue Load =
- DAG.getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
- LN->getPointerInfo().getWithOffset(Idx * 16),
- commonAlignment(Alignment, Idx * 16),
- LN->getMemOperand()->getFlags(), LN->getAAInfo());
- BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
- DAG.getConstant(16, dl, BasePtr.getValueType()));
- Loads.push_back(Load);
- LoadChains.push_back(Load.getValue(1));
- }
- if (Subtarget.isLittleEndian()) {
- std::reverse(Loads.begin(), Loads.end());
- std::reverse(LoadChains.begin(), LoadChains.end());
- }
- SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, LoadChains);
- SDValue Value =
- DAG.getNode(VT == MVT::v512i1 ? PPCISD::ACC_BUILD : PPCISD::PAIR_BUILD,
- dl, VT, Loads);
- SDValue RetOps[] = {Value, TF};
- return DAG.getMergeValues(RetOps, dl);
+ EVT VT = Op.getValueType();
+
+ if (VT != MVT::v256i1 && VT != MVT::v512i1)
+ return Op;
+
+ // Type v256i1 is used for pairs and v512i1 is used for accumulators.
+ // Here we create 2 or 4 v16i8 loads to load the pair or accumulator value in
+ // 2 or 4 vsx registers.
+ assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
+ "Type unsupported without MMA");
+ assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
+ "Type unsupported without paired vector support");
+ Align Alignment = LN->getAlign();
+ SmallVector<SDValue, 4> Loads;
+ SmallVector<SDValue, 4> LoadChains;
+ unsigned NumVecs = VT.getSizeInBits() / 128;
+ for (unsigned Idx = 0; Idx < NumVecs; ++Idx) {
+ SDValue Load =
+ DAG.getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
+ LN->getPointerInfo().getWithOffset(Idx * 16),
+ commonAlignment(Alignment, Idx * 16),
+ LN->getMemOperand()->getFlags(), LN->getAAInfo());
+ BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
+ DAG.getConstant(16, dl, BasePtr.getValueType()));
+ Loads.push_back(Load);
+ LoadChains.push_back(Load.getValue(1));
+ }
+ if (Subtarget.isLittleEndian()) {
+ std::reverse(Loads.begin(), Loads.end());
+ std::reverse(LoadChains.begin(), LoadChains.end());
+ }
+ SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, LoadChains);
+ SDValue Value =
+ DAG.getNode(VT == MVT::v512i1 ? PPCISD::ACC_BUILD : PPCISD::PAIR_BUILD,
+ dl, VT, Loads);
+ SDValue RetOps[] = {Value, TF};
+ return DAG.getMergeValues(RetOps, dl);
}
SDValue PPCTargetLowering::LowerVectorStore(SDValue Op,
@@ -10171,40 +10171,40 @@ SDValue PPCTargetLowering::LowerVectorStore(SDValue Op,
SDValue StoreChain = SN->getChain();
SDValue BasePtr = SN->getBasePtr();
SDValue Value = SN->getValue();
- EVT StoreVT = Value.getValueType();
-
- if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
- return Op;
-
- // Type v256i1 is used for pairs and v512i1 is used for accumulators.
- // Here we create 2 or 4 v16i8 stores to store the pair or accumulator
- // underlying registers individually.
- assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
- "Type unsupported without MMA");
- assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
- "Type unsupported without paired vector support");
- Align Alignment = SN->getAlign();
- SmallVector<SDValue, 4> Stores;
- unsigned NumVecs = 2;
- if (StoreVT == MVT::v512i1) {
- Value = DAG.getNode(PPCISD::XXMFACC, dl, MVT::v512i1, Value);
- NumVecs = 4;
- }
- for (unsigned Idx = 0; Idx < NumVecs; ++Idx) {
- unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 - Idx : Idx;
- SDValue Elt = DAG.getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, Value,
- DAG.getConstant(VecNum, dl, MVT::i64));
- SDValue Store =
- DAG.getStore(StoreChain, dl, Elt, BasePtr,
- SN->getPointerInfo().getWithOffset(Idx * 16),
- commonAlignment(Alignment, Idx * 16),
- SN->getMemOperand()->getFlags(), SN->getAAInfo());
- BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
- DAG.getConstant(16, dl, BasePtr.getValueType()));
- Stores.push_back(Store);
- }
- SDValue TF = DAG.getTokenFactor(dl, Stores);
- return TF;
+ EVT StoreVT = Value.getValueType();
+
+ if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
+ return Op;
+
+ // Type v256i1 is used for pairs and v512i1 is used for accumulators.
+ // Here we create 2 or 4 v16i8 stores to store the pair or accumulator
+ // underlying registers individually.
+ assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
+ "Type unsupported without MMA");
+ assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
+ "Type unsupported without paired vector support");
+ Align Alignment = SN->getAlign();
+ SmallVector<SDValue, 4> Stores;
+ unsigned NumVecs = 2;
+ if (StoreVT == MVT::v512i1) {
+ Value = DAG.getNode(PPCISD::XXMFACC, dl, MVT::v512i1, Value);
+ NumVecs = 4;
+ }
+ for (unsigned Idx = 0; Idx < NumVecs; ++Idx) {
+ unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 - Idx : Idx;
+ SDValue Elt = DAG.getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, Value,
+ DAG.getConstant(VecNum, dl, MVT::i64));
+ SDValue Store =
+ DAG.getStore(StoreChain, dl, Elt, BasePtr,
+ SN->getPointerInfo().getWithOffset(Idx * 16),
+ commonAlignment(Alignment, Idx * 16),
+ SN->getMemOperand()->getFlags(), SN->getAAInfo());
+ BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
+ DAG.getConstant(16, dl, BasePtr.getValueType()));
+ Stores.push_back(Store);
+ }
+ SDValue TF = DAG.getTokenFactor(dl, Stores);
+ return TF;
}
SDValue PPCTargetLowering::LowerMUL(SDValue Op, SelectionDAG &DAG) const {
@@ -10271,13 +10271,13 @@ SDValue PPCTargetLowering::LowerMUL(SDValue Op, SelectionDAG &DAG) const {
}
}
-SDValue PPCTargetLowering::LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const {
- bool IsStrict = Op->isStrictFPOpcode();
- if (Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
- !Subtarget.hasP9Vector())
- return SDValue();
+SDValue PPCTargetLowering::LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const {
+ bool IsStrict = Op->isStrictFPOpcode();
+ if (Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
+ !Subtarget.hasP9Vector())
+ return SDValue();
- return Op;
+ return Op;
}
// Custom lowering for fpext vf32 to v2f64
@@ -10371,8 +10371,8 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::INIT_TRAMPOLINE: return LowerINIT_TRAMPOLINE(Op, DAG);
case ISD::ADJUST_TRAMPOLINE: return LowerADJUST_TRAMPOLINE(Op, DAG);
- case ISD::INLINEASM:
- case ISD::INLINEASM_BR: return LowerINLINEASM(Op, DAG);
+ case ISD::INLINEASM:
+ case ISD::INLINEASM_BR: return LowerINLINEASM(Op, DAG);
// Variable argument lowering.
case ISD::VASTART: return LowerVASTART(Op, DAG);
case ISD::VAARG: return LowerVAARG(Op, DAG);
@@ -10392,12 +10392,12 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::STORE: return LowerSTORE(Op, DAG);
case ISD::TRUNCATE: return LowerTRUNCATE(Op, DAG);
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
- case ISD::STRICT_FP_TO_UINT:
- case ISD::STRICT_FP_TO_SINT:
+ case ISD::STRICT_FP_TO_UINT:
+ case ISD::STRICT_FP_TO_SINT:
case ISD::FP_TO_UINT:
case ISD::FP_TO_SINT: return LowerFP_TO_INT(Op, DAG, SDLoc(Op));
- case ISD::STRICT_UINT_TO_FP:
- case ISD::STRICT_SINT_TO_FP:
+ case ISD::STRICT_UINT_TO_FP:
+ case ISD::STRICT_SINT_TO_FP:
case ISD::UINT_TO_FP:
case ISD::SINT_TO_FP: return LowerINT_TO_FP(Op, DAG);
case ISD::FLT_ROUNDS_: return LowerFLT_ROUNDS_(Op, DAG);
@@ -10407,9 +10407,9 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::SRL_PARTS: return LowerSRL_PARTS(Op, DAG);
case ISD::SRA_PARTS: return LowerSRA_PARTS(Op, DAG);
- case ISD::FSHL: return LowerFunnelShift(Op, DAG);
- case ISD::FSHR: return LowerFunnelShift(Op, DAG);
-
+ case ISD::FSHL: return LowerFunnelShift(Op, DAG);
+ case ISD::FSHR: return LowerFunnelShift(Op, DAG);
+
// Vector-related lowering.
case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG);
case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG);
@@ -10418,9 +10418,9 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::INSERT_VECTOR_ELT: return LowerINSERT_VECTOR_ELT(Op, DAG);
case ISD::MUL: return LowerMUL(Op, DAG);
case ISD::FP_EXTEND: return LowerFP_EXTEND(Op, DAG);
- case ISD::STRICT_FP_ROUND:
- case ISD::FP_ROUND:
- return LowerFP_ROUND(Op, DAG);
+ case ISD::STRICT_FP_ROUND:
+ case ISD::FP_ROUND:
+ return LowerFP_ROUND(Op, DAG);
case ISD::ROTL: return LowerROTL(Op, DAG);
// For counter-based loop handling.
@@ -10488,28 +10488,28 @@ void PPCTargetLowering::ReplaceNodeResults(SDNode *N,
}
return;
}
- case ISD::STRICT_FP_TO_SINT:
- case ISD::STRICT_FP_TO_UINT:
+ case ISD::STRICT_FP_TO_SINT:
+ case ISD::STRICT_FP_TO_UINT:
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT:
// LowerFP_TO_INT() can only handle f32 and f64.
- if (N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
- MVT::ppcf128)
+ if (N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
+ MVT::ppcf128)
return;
Results.push_back(LowerFP_TO_INT(SDValue(N, 0), DAG, dl));
return;
case ISD::TRUNCATE: {
- if (!N->getValueType(0).isVector())
- return;
- SDValue Lowered = LowerTRUNCATEVector(SDValue(N, 0), DAG);
- if (Lowered)
- Results.push_back(Lowered);
+ if (!N->getValueType(0).isVector())
+ return;
+ SDValue Lowered = LowerTRUNCATEVector(SDValue(N, 0), DAG);
+ if (Lowered)
+ Results.push_back(Lowered);
return;
}
- case ISD::FSHL:
- case ISD::FSHR:
- // Don't handle funnel shifts here.
- return;
+ case ISD::FSHL:
+ case ISD::FSHR:
+ // Don't handle funnel shifts here.
+ return;
case ISD::BITCAST:
// Don't handle bitcast here.
return;
@@ -10681,83 +10681,83 @@ PPCTargetLowering::EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *BB,
return BB;
}
-static bool isSignExtended(MachineInstr &MI, const PPCInstrInfo *TII) {
- switch(MI.getOpcode()) {
- default:
- return false;
- case PPC::COPY:
- return TII->isSignExtended(MI);
- case PPC::LHA:
- case PPC::LHA8:
- case PPC::LHAU:
- case PPC::LHAU8:
- case PPC::LHAUX:
- case PPC::LHAUX8:
- case PPC::LHAX:
- case PPC::LHAX8:
- case PPC::LWA:
- case PPC::LWAUX:
- case PPC::LWAX:
- case PPC::LWAX_32:
- case PPC::LWA_32:
- case PPC::PLHA:
- case PPC::PLHA8:
- case PPC::PLHA8pc:
- case PPC::PLHApc:
- case PPC::PLWA:
- case PPC::PLWA8:
- case PPC::PLWA8pc:
- case PPC::PLWApc:
- case PPC::EXTSB:
- case PPC::EXTSB8:
- case PPC::EXTSB8_32_64:
- case PPC::EXTSB8_rec:
- case PPC::EXTSB_rec:
- case PPC::EXTSH:
- case PPC::EXTSH8:
- case PPC::EXTSH8_32_64:
- case PPC::EXTSH8_rec:
- case PPC::EXTSH_rec:
- case PPC::EXTSW:
- case PPC::EXTSWSLI:
- case PPC::EXTSWSLI_32_64:
- case PPC::EXTSWSLI_32_64_rec:
- case PPC::EXTSWSLI_rec:
- case PPC::EXTSW_32:
- case PPC::EXTSW_32_64:
- case PPC::EXTSW_32_64_rec:
- case PPC::EXTSW_rec:
- case PPC::SRAW:
- case PPC::SRAWI:
- case PPC::SRAWI_rec:
- case PPC::SRAW_rec:
- return true;
- }
- return false;
-}
-
+static bool isSignExtended(MachineInstr &MI, const PPCInstrInfo *TII) {
+ switch(MI.getOpcode()) {
+ default:
+ return false;
+ case PPC::COPY:
+ return TII->isSignExtended(MI);
+ case PPC::LHA:
+ case PPC::LHA8:
+ case PPC::LHAU:
+ case PPC::LHAU8:
+ case PPC::LHAUX:
+ case PPC::LHAUX8:
+ case PPC::LHAX:
+ case PPC::LHAX8:
+ case PPC::LWA:
+ case PPC::LWAUX:
+ case PPC::LWAX:
+ case PPC::LWAX_32:
+ case PPC::LWA_32:
+ case PPC::PLHA:
+ case PPC::PLHA8:
+ case PPC::PLHA8pc:
+ case PPC::PLHApc:
+ case PPC::PLWA:
+ case PPC::PLWA8:
+ case PPC::PLWA8pc:
+ case PPC::PLWApc:
+ case PPC::EXTSB:
+ case PPC::EXTSB8:
+ case PPC::EXTSB8_32_64:
+ case PPC::EXTSB8_rec:
+ case PPC::EXTSB_rec:
+ case PPC::EXTSH:
+ case PPC::EXTSH8:
+ case PPC::EXTSH8_32_64:
+ case PPC::EXTSH8_rec:
+ case PPC::EXTSH_rec:
+ case PPC::EXTSW:
+ case PPC::EXTSWSLI:
+ case PPC::EXTSWSLI_32_64:
+ case PPC::EXTSWSLI_32_64_rec:
+ case PPC::EXTSWSLI_rec:
+ case PPC::EXTSW_32:
+ case PPC::EXTSW_32_64:
+ case PPC::EXTSW_32_64_rec:
+ case PPC::EXTSW_rec:
+ case PPC::SRAW:
+ case PPC::SRAWI:
+ case PPC::SRAWI_rec:
+ case PPC::SRAW_rec:
+ return true;
+ }
+ return false;
+}
+
MachineBasicBlock *PPCTargetLowering::EmitPartwordAtomicBinary(
MachineInstr &MI, MachineBasicBlock *BB,
bool is8bit, // operation
unsigned BinOpcode, unsigned CmpOpcode, unsigned CmpPred) const {
- // This also handles ATOMIC_SWAP, indicated by BinOpcode==0.
- const PPCInstrInfo *TII = Subtarget.getInstrInfo();
-
- // If this is a signed comparison and the value being compared is not known
- // to be sign extended, sign extend it here.
- DebugLoc dl = MI.getDebugLoc();
- MachineFunction *F = BB->getParent();
- MachineRegisterInfo &RegInfo = F->getRegInfo();
- Register incr = MI.getOperand(3).getReg();
- bool IsSignExtended = Register::isVirtualRegister(incr) &&
- isSignExtended(*RegInfo.getVRegDef(incr), TII);
-
- if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
- Register ValueReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
- BuildMI(*BB, MI, dl, TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
- .addReg(MI.getOperand(3).getReg());
- MI.getOperand(3).setReg(ValueReg);
- }
+ // This also handles ATOMIC_SWAP, indicated by BinOpcode==0.
+ const PPCInstrInfo *TII = Subtarget.getInstrInfo();
+
+ // If this is a signed comparison and the value being compared is not known
+ // to be sign extended, sign extend it here.
+ DebugLoc dl = MI.getDebugLoc();
+ MachineFunction *F = BB->getParent();
+ MachineRegisterInfo &RegInfo = F->getRegInfo();
+ Register incr = MI.getOperand(3).getReg();
+ bool IsSignExtended = Register::isVirtualRegister(incr) &&
+ isSignExtended(*RegInfo.getVRegDef(incr), TII);
+
+ if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
+ Register ValueReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
+ BuildMI(*BB, MI, dl, TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
+ .addReg(MI.getOperand(3).getReg());
+ MI.getOperand(3).setReg(ValueReg);
+ }
// If we support part-word atomic mnemonics, just use them
if (Subtarget.hasPartwordAtomics())
return EmitAtomicBinary(MI, BB, is8bit ? 1 : 2, BinOpcode, CmpOpcode,
@@ -11960,20 +11960,20 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
BuildMI(*BB, MI, dl, TII->get(PPC::MFFS), MFFSReg);
// Set rounding mode to round-to-zero.
- BuildMI(*BB, MI, dl, TII->get(PPC::MTFSB1))
- .addImm(31)
- .addReg(PPC::RM, RegState::ImplicitDefine);
-
- BuildMI(*BB, MI, dl, TII->get(PPC::MTFSB0))
- .addImm(30)
- .addReg(PPC::RM, RegState::ImplicitDefine);
-
+ BuildMI(*BB, MI, dl, TII->get(PPC::MTFSB1))
+ .addImm(31)
+ .addReg(PPC::RM, RegState::ImplicitDefine);
+
+ BuildMI(*BB, MI, dl, TII->get(PPC::MTFSB0))
+ .addImm(30)
+ .addReg(PPC::RM, RegState::ImplicitDefine);
+
// Perform addition.
- auto MIB = BuildMI(*BB, MI, dl, TII->get(PPC::FADD), Dest)
- .addReg(Src1)
- .addReg(Src2);
- if (MI.getFlag(MachineInstr::NoFPExcept))
- MIB.setMIFlag(MachineInstr::NoFPExcept);
+ auto MIB = BuildMI(*BB, MI, dl, TII->get(PPC::FADD), Dest)
+ .addReg(Src1)
+ .addReg(Src2);
+ if (MI.getFlag(MachineInstr::NoFPExcept))
+ MIB.setMIFlag(MachineInstr::NoFPExcept);
// Restore FPSCR value.
BuildMI(*BB, MI, dl, TII->get(PPC::MTFSFb)).addImm(1).addReg(MFFSReg);
@@ -12032,12 +12032,12 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
// the immediate to set the bits 62:63 of FPSCR.
unsigned Mode = MI.getOperand(1).getImm();
BuildMI(*BB, MI, dl, TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
- .addImm(31)
- .addReg(PPC::RM, RegState::ImplicitDefine);
+ .addImm(31)
+ .addReg(PPC::RM, RegState::ImplicitDefine);
BuildMI(*BB, MI, dl, TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
- .addImm(30)
- .addReg(PPC::RM, RegState::ImplicitDefine);
+ .addImm(30)
+ .addReg(PPC::RM, RegState::ImplicitDefine);
} else if (MI.getOpcode() == PPC::SETRND) {
DebugLoc dl = MI.getDebugLoc();
@@ -12147,20 +12147,20 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
.addReg(NewFPSCRReg)
.addImm(0)
.addImm(0);
- } else if (MI.getOpcode() == PPC::SETFLM) {
- DebugLoc Dl = MI.getDebugLoc();
-
- // Result of setflm is previous FPSCR content, so we need to save it first.
- Register OldFPSCRReg = MI.getOperand(0).getReg();
- BuildMI(*BB, MI, Dl, TII->get(PPC::MFFS), OldFPSCRReg);
-
- // Put bits in 32:63 to FPSCR.
- Register NewFPSCRReg = MI.getOperand(1).getReg();
- BuildMI(*BB, MI, Dl, TII->get(PPC::MTFSF))
- .addImm(255)
- .addReg(NewFPSCRReg)
- .addImm(0)
- .addImm(0);
+ } else if (MI.getOpcode() == PPC::SETFLM) {
+ DebugLoc Dl = MI.getDebugLoc();
+
+ // Result of setflm is previous FPSCR content, so we need to save it first.
+ Register OldFPSCRReg = MI.getOperand(0).getReg();
+ BuildMI(*BB, MI, Dl, TII->get(PPC::MFFS), OldFPSCRReg);
+
+ // Put bits in 32:63 to FPSCR.
+ Register NewFPSCRReg = MI.getOperand(1).getReg();
+ BuildMI(*BB, MI, Dl, TII->get(PPC::MTFSF))
+ .addImm(255)
+ .addReg(NewFPSCRReg)
+ .addImm(0)
+ .addImm(0);
} else if (MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
return emitProbedAlloca(MI, BB);
@@ -12187,47 +12187,47 @@ static int getEstimateRefinementSteps(EVT VT, const PPCSubtarget &Subtarget) {
return RefinementSteps;
}
-SDValue PPCTargetLowering::getSqrtInputTest(SDValue Op, SelectionDAG &DAG,
- const DenormalMode &Mode) const {
- // We only have VSX Vector Test for software Square Root.
- EVT VT = Op.getValueType();
- if (!isTypeLegal(MVT::i1) ||
- (VT != MVT::f64 &&
- ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
- return TargetLowering::getSqrtInputTest(Op, DAG, Mode);
-
- SDLoc DL(Op);
- // The output register of FTSQRT is CR field.
- SDValue FTSQRT = DAG.getNode(PPCISD::FTSQRT, DL, MVT::i32, Op);
- // ftsqrt BF,FRB
- // Let e_b be the unbiased exponent of the double-precision
- // floating-point operand in register FRB.
- // fe_flag is set to 1 if either of the following conditions occurs.
- // - The double-precision floating-point operand in register FRB is a zero,
- // a NaN, or an infinity, or a negative value.
- // - e_b is less than or equal to -970.
- // Otherwise fe_flag is set to 0.
- // Both VSX and non-VSX versions would set EQ bit in the CR if the number is
- // not eligible for iteration. (zero/negative/infinity/nan or unbiased
- // exponent is less than -970)
- SDValue SRIdxVal = DAG.getTargetConstant(PPC::sub_eq, DL, MVT::i32);
- return SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, MVT::i1,
- FTSQRT, SRIdxVal),
- 0);
-}
-
-SDValue
-PPCTargetLowering::getSqrtResultForDenormInput(SDValue Op,
- SelectionDAG &DAG) const {
- // We only have VSX Vector Square Root.
- EVT VT = Op.getValueType();
- if (VT != MVT::f64 &&
- ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
- return TargetLowering::getSqrtResultForDenormInput(Op, DAG);
-
- return DAG.getNode(PPCISD::FSQRT, SDLoc(Op), VT, Op);
-}
-
+SDValue PPCTargetLowering::getSqrtInputTest(SDValue Op, SelectionDAG &DAG,
+ const DenormalMode &Mode) const {
+ // We only have VSX Vector Test for software Square Root.
+ EVT VT = Op.getValueType();
+ if (!isTypeLegal(MVT::i1) ||
+ (VT != MVT::f64 &&
+ ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
+ return TargetLowering::getSqrtInputTest(Op, DAG, Mode);
+
+ SDLoc DL(Op);
+ // The output register of FTSQRT is CR field.
+ SDValue FTSQRT = DAG.getNode(PPCISD::FTSQRT, DL, MVT::i32, Op);
+ // ftsqrt BF,FRB
+ // Let e_b be the unbiased exponent of the double-precision
+ // floating-point operand in register FRB.
+ // fe_flag is set to 1 if either of the following conditions occurs.
+ // - The double-precision floating-point operand in register FRB is a zero,
+ // a NaN, or an infinity, or a negative value.
+ // - e_b is less than or equal to -970.
+ // Otherwise fe_flag is set to 0.
+ // Both VSX and non-VSX versions would set EQ bit in the CR if the number is
+ // not eligible for iteration. (zero/negative/infinity/nan or unbiased
+ // exponent is less than -970)
+ SDValue SRIdxVal = DAG.getTargetConstant(PPC::sub_eq, DL, MVT::i32);
+ return SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, MVT::i1,
+ FTSQRT, SRIdxVal),
+ 0);
+}
+
+SDValue
+PPCTargetLowering::getSqrtResultForDenormInput(SDValue Op,
+ SelectionDAG &DAG) const {
+ // We only have VSX Vector Square Root.
+ EVT VT = Op.getValueType();
+ if (VT != MVT::f64 &&
+ ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
+ return TargetLowering::getSqrtResultForDenormInput(Op, DAG);
+
+ return DAG.getNode(PPCISD::FSQRT, SDLoc(Op), VT, Op);
+}
+
SDValue PPCTargetLowering::getSqrtEstimate(SDValue Operand, SelectionDAG &DAG,
int Enabled, int &RefinementSteps,
bool &UseOneConstNR,
@@ -12236,7 +12236,7 @@ SDValue PPCTargetLowering::getSqrtEstimate(SDValue Operand, SelectionDAG &DAG,
if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
(VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
(VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
- (VT == MVT::v2f64 && Subtarget.hasVSX())) {
+ (VT == MVT::v2f64 && Subtarget.hasVSX())) {
if (RefinementSteps == ReciprocalEstimate::Unspecified)
RefinementSteps = getEstimateRefinementSteps(VT, Subtarget);
@@ -12255,7 +12255,7 @@ SDValue PPCTargetLowering::getRecipEstimate(SDValue Operand, SelectionDAG &DAG,
if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
(VT == MVT::f64 && Subtarget.hasFRE()) ||
(VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
- (VT == MVT::v2f64 && Subtarget.hasVSX())) {
+ (VT == MVT::v2f64 && Subtarget.hasVSX())) {
if (RefinementSteps == ReciprocalEstimate::Unspecified)
RefinementSteps = getEstimateRefinementSteps(VT, Subtarget);
return DAG.getNode(PPCISD::FRE, SDLoc(Operand), VT, Operand);
@@ -12608,13 +12608,13 @@ SDValue PPCTargetLowering::DAGCombineTruncBoolExt(SDNode *N,
KnownBits Op2Known = DAG.computeKnownBits(N->getOperand(1));
// We don't really care about what is known about the first bit (if
- // anything), so pretend that it is known zero for both to ensure they can
- // be compared as constants.
- Op1Known.Zero.setBit(0); Op1Known.One.clearBit(0);
- Op2Known.Zero.setBit(0); Op2Known.One.clearBit(0);
+ // anything), so pretend that it is known zero for both to ensure they can
+ // be compared as constants.
+ Op1Known.Zero.setBit(0); Op1Known.One.clearBit(0);
+ Op2Known.Zero.setBit(0); Op2Known.One.clearBit(0);
- if (!Op1Known.isConstant() || !Op2Known.isConstant() ||
- Op1Known.getConstant() != Op2Known.getConstant())
+ if (!Op1Known.isConstant() || !Op2Known.isConstant() ||
+ Op1Known.getConstant() != Op2Known.getConstant())
return SDValue();
}
}
@@ -12666,7 +12666,7 @@ SDValue PPCTargetLowering::DAGCombineTruncBoolExt(SDNode *N,
// Visit all inputs, collect all binary operations (and, or, xor and
// select) that are all fed by extensions.
while (!BinOps.empty()) {
- SDValue BinOp = BinOps.pop_back_val();
+ SDValue BinOp = BinOps.pop_back_val();
if (!Visited.insert(BinOp.getNode()).second)
continue;
@@ -12881,7 +12881,7 @@ SDValue PPCTargetLowering::DAGCombineExtBoolTrunc(SDNode *N,
// Visit all inputs, collect all binary operations (and, or, xor and
// select) that are all fed by truncations.
while (!BinOps.empty()) {
- SDValue BinOp = BinOps.pop_back_val();
+ SDValue BinOp = BinOps.pop_back_val();
if (!Visited.insert(BinOp.getNode()).second)
continue;
@@ -13478,46 +13478,46 @@ static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG) {
return SDValue();
}
-// Look for the pattern of a load from a narrow width to i128, feeding
-// into a BUILD_VECTOR of v1i128. Replace this sequence with a PPCISD node
-// (LXVRZX). This node represents a zero extending load that will be matched
-// to the Load VSX Vector Rightmost instructions.
-static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG) {
- SDLoc DL(N);
-
- // This combine is only eligible for a BUILD_VECTOR of v1i128.
- if (N->getValueType(0) != MVT::v1i128)
- return SDValue();
-
- SDValue Operand = N->getOperand(0);
- // Proceed with the transformation if the operand to the BUILD_VECTOR
- // is a load instruction.
- if (Operand.getOpcode() != ISD::LOAD)
- return SDValue();
-
- LoadSDNode *LD = dyn_cast<LoadSDNode>(Operand);
- EVT MemoryType = LD->getMemoryVT();
-
- // This transformation is only valid if the we are loading either a byte,
- // halfword, word, or doubleword.
- bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
- MemoryType == MVT::i32 || MemoryType == MVT::i64;
-
- // Ensure that the load from the narrow width is being zero extended to i128.
- if (!ValidLDType ||
- (LD->getExtensionType() != ISD::ZEXTLOAD &&
- LD->getExtensionType() != ISD::EXTLOAD))
- return SDValue();
-
- SDValue LoadOps[] = {
- LD->getChain(), LD->getBasePtr(),
- DAG.getIntPtrConstant(MemoryType.getScalarSizeInBits(), DL)};
-
- return DAG.getMemIntrinsicNode(PPCISD::LXVRZX, DL,
- DAG.getVTList(MVT::v1i128, MVT::Other),
- LoadOps, MemoryType, LD->getMemOperand());
-}
-
+// Look for the pattern of a load from a narrow width to i128, feeding
+// into a BUILD_VECTOR of v1i128. Replace this sequence with a PPCISD node
+// (LXVRZX). This node represents a zero extending load that will be matched
+// to the Load VSX Vector Rightmost instructions.
+static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG) {
+ SDLoc DL(N);
+
+ // This combine is only eligible for a BUILD_VECTOR of v1i128.
+ if (N->getValueType(0) != MVT::v1i128)
+ return SDValue();
+
+ SDValue Operand = N->getOperand(0);
+ // Proceed with the transformation if the operand to the BUILD_VECTOR
+ // is a load instruction.
+ if (Operand.getOpcode() != ISD::LOAD)
+ return SDValue();
+
+ LoadSDNode *LD = dyn_cast<LoadSDNode>(Operand);
+ EVT MemoryType = LD->getMemoryVT();
+
+ // This transformation is only valid if the we are loading either a byte,
+ // halfword, word, or doubleword.
+ bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
+ MemoryType == MVT::i32 || MemoryType == MVT::i64;
+
+ // Ensure that the load from the narrow width is being zero extended to i128.
+ if (!ValidLDType ||
+ (LD->getExtensionType() != ISD::ZEXTLOAD &&
+ LD->getExtensionType() != ISD::EXTLOAD))
+ return SDValue();
+
+ SDValue LoadOps[] = {
+ LD->getChain(), LD->getBasePtr(),
+ DAG.getIntPtrConstant(MemoryType.getScalarSizeInBits(), DL)};
+
+ return DAG.getMemIntrinsicNode(PPCISD::LXVRZX, DL,
+ DAG.getVTList(MVT::v1i128, MVT::Other),
+ LoadOps, MemoryType, LD->getMemOperand());
+}
+
SDValue PPCTargetLowering::DAGCombineBuildVector(SDNode *N,
DAGCombinerInfo &DCI) const {
assert(N->getOpcode() == ISD::BUILD_VECTOR &&
@@ -13555,14 +13555,14 @@ SDValue PPCTargetLowering::DAGCombineBuildVector(SDNode *N,
return Reduced;
}
- // On Power10, the Load VSX Vector Rightmost instructions can be utilized
- // if this is a BUILD_VECTOR of v1i128, and if the operand to the BUILD_VECTOR
- // is a load from <valid narrow width> to i128.
- if (Subtarget.isISA3_1()) {
- SDValue BVOfZLoad = combineBVZEXTLOAD(N, DAG);
- if (BVOfZLoad)
- return BVOfZLoad;
- }
+ // On Power10, the Load VSX Vector Rightmost instructions can be utilized
+ // if this is a BUILD_VECTOR of v1i128, and if the operand to the BUILD_VECTOR
+ // is a load from <valid narrow width> to i128.
+ if (Subtarget.isISA3_1()) {
+ SDValue BVOfZLoad = combineBVZEXTLOAD(N, DAG);
+ if (BVOfZLoad)
+ return BVOfZLoad;
+ }
if (N->getValueType(0) != MVT::v2f64)
return SDValue();
@@ -13626,8 +13626,8 @@ SDValue PPCTargetLowering::combineFPToIntToFP(SDNode *N,
// from the hardware.
if (Op.getValueType() != MVT::f32 && Op.getValueType() != MVT::f64)
return SDValue();
- if (!Op.getOperand(0).getValueType().isSimple())
- return SDValue();
+ if (!Op.getOperand(0).getValueType().isSimple())
+ return SDValue();
if (Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
return SDValue();
@@ -13864,7 +13864,7 @@ SDValue PPCTargetLowering::combineStoreFPToInt(SDNode *N,
EVT Op1VT = N->getOperand(1).getValueType();
EVT ResVT = Val.getValueType();
- if (!isTypeLegal(ResVT))
+ if (!isTypeLegal(ResVT))
return SDValue();
// Only perform combine for conversion to i64/i32 or power9 i16/i8.
@@ -14431,9 +14431,9 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
// P8 and later hardware should just use LOAD.
!Subtarget.hasP8Vector() &&
(VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
- VT == MVT::v4f32))) &&
+ VT == MVT::v4f32))) &&
LD->getAlign() < ABIAlignment) {
- // This is a type-legal unaligned Altivec load.
+ // This is a type-legal unaligned Altivec load.
SDValue Chain = LD->getChain();
SDValue Ptr = LD->getBasePtr();
bool isLittleEndian = Subtarget.isLittleEndian();
@@ -14464,13 +14464,13 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
// optimization later.
Intrinsic::ID Intr, IntrLD, IntrPerm;
MVT PermCntlTy, PermTy, LDTy;
- Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
- : Intrinsic::ppc_altivec_lvsl;
- IntrLD = Intrinsic::ppc_altivec_lvx;
- IntrPerm = Intrinsic::ppc_altivec_vperm;
- PermCntlTy = MVT::v16i8;
- PermTy = MVT::v4i32;
- LDTy = MVT::v4i32;
+ Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
+ : Intrinsic::ppc_altivec_lvsl;
+ IntrLD = Intrinsic::ppc_altivec_lvx;
+ IntrPerm = Intrinsic::ppc_altivec_vperm;
+ PermCntlTy = MVT::v16i8;
+ PermTy = MVT::v4i32;
+ LDTy = MVT::v4i32;
SDValue PermCntl = BuildIntrinsicOp(Intr, Ptr, DAG, dl, PermCntlTy);
@@ -14541,10 +14541,10 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
BaseLoad, ExtraLoad, PermCntl, DAG, dl);
if (VT != PermTy)
- Perm = Subtarget.hasAltivec()
- ? DAG.getNode(ISD::BITCAST, dl, VT, Perm)
- : DAG.getNode(ISD::FP_ROUND, dl, VT, Perm,
- DAG.getTargetConstant(1, dl, MVT::i64));
+ Perm = Subtarget.hasAltivec()
+ ? DAG.getNode(ISD::BITCAST, dl, VT, Perm)
+ : DAG.getNode(ISD::FP_ROUND, dl, VT, Perm,
+ DAG.getTargetConstant(1, dl, MVT::i64));
// second argument is 1 because this rounding
// is always exact.
@@ -14560,10 +14560,10 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
unsigned IID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
: Intrinsic::ppc_altivec_lvsl);
- if (IID == Intr && N->getOperand(1)->getOpcode() == ISD::ADD) {
+ if (IID == Intr && N->getOperand(1)->getOpcode() == ISD::ADD) {
SDValue Add = N->getOperand(1);
- int Bits = 4 /* 16 byte alignment */;
+ int Bits = 4 /* 16 byte alignment */;
if (DAG.MaskedValueIsZero(Add->getOperand(1),
APInt::getAllOnesValue(Bits /* alignment */)
@@ -14573,8 +14573,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
UE = BasePtr->use_end();
UI != UE; ++UI) {
if (UI->getOpcode() == ISD::INTRINSIC_WO_CHAIN &&
- cast<ConstantSDNode>(UI->getOperand(0))->getZExtValue() ==
- IID) {
+ cast<ConstantSDNode>(UI->getOperand(0))->getZExtValue() ==
+ IID) {
// We've found another LVSL/LVSR, and this address is an aligned
// multiple of that one. The results will be the same, so use the
// one we've just found instead.
@@ -14706,43 +14706,43 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
}
break;
case PPCISD::VCMP:
- // If a VCMP_rec node already exists with exactly the same operands as this
- // node, use its result instead of this node (VCMP_rec computes both a CR6
- // and a normal output).
+ // If a VCMP_rec node already exists with exactly the same operands as this
+ // node, use its result instead of this node (VCMP_rec computes both a CR6
+ // and a normal output).
//
if (!N->getOperand(0).hasOneUse() &&
!N->getOperand(1).hasOneUse() &&
!N->getOperand(2).hasOneUse()) {
- // Scan all of the users of the LHS, looking for VCMP_rec's that match.
- SDNode *VCMPrecNode = nullptr;
+ // Scan all of the users of the LHS, looking for VCMP_rec's that match.
+ SDNode *VCMPrecNode = nullptr;
SDNode *LHSN = N->getOperand(0).getNode();
for (SDNode::use_iterator UI = LHSN->use_begin(), E = LHSN->use_end();
UI != E; ++UI)
- if (UI->getOpcode() == PPCISD::VCMP_rec &&
+ if (UI->getOpcode() == PPCISD::VCMP_rec &&
UI->getOperand(1) == N->getOperand(1) &&
UI->getOperand(2) == N->getOperand(2) &&
UI->getOperand(0) == N->getOperand(0)) {
- VCMPrecNode = *UI;
+ VCMPrecNode = *UI;
break;
}
- // If there is no VCMP_rec node, or if the flag value has a single use,
- // don't transform this.
- if (!VCMPrecNode || VCMPrecNode->hasNUsesOfValue(0, 1))
+ // If there is no VCMP_rec node, or if the flag value has a single use,
+ // don't transform this.
+ if (!VCMPrecNode || VCMPrecNode->hasNUsesOfValue(0, 1))
break;
// Look at the (necessarily single) use of the flag value. If it has a
// chain, this transformation is more complex. Note that multiple things
// could use the value result, which we should ignore.
SDNode *FlagUser = nullptr;
- for (SDNode::use_iterator UI = VCMPrecNode->use_begin();
+ for (SDNode::use_iterator UI = VCMPrecNode->use_begin();
FlagUser == nullptr; ++UI) {
- assert(UI != VCMPrecNode->use_end() && "Didn't find user!");
+ assert(UI != VCMPrecNode->use_end() && "Didn't find user!");
SDNode *User = *UI;
for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) {
- if (User->getOperand(i) == SDValue(VCMPrecNode, 1)) {
+ if (User->getOperand(i) == SDValue(VCMPrecNode, 1)) {
FlagUser = User;
break;
}
@@ -14752,7 +14752,7 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
// If the user is a MFOCRF instruction, we know this is safe.
// Otherwise we give up for right now.
if (FlagUser->getOpcode() == PPCISD::MFOCRF)
- return SDValue(VCMPrecNode, 0);
+ return SDValue(VCMPrecNode, 0);
}
break;
case ISD::BRCOND: {
@@ -14841,7 +14841,7 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
DAG.getConstant(CompareOpc, dl, MVT::i32)
};
EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
- SDValue CompNode = DAG.getNode(PPCISD::VCMP_rec, dl, VTs, Ops);
+ SDValue CompNode = DAG.getNode(PPCISD::VCMP_rec, dl, VTs, Ops);
// Unpack the result based on how the target uses it.
PPC::Predicate CompOpc;
@@ -14936,19 +14936,19 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
case Intrinsic::ppc_altivec_vcmpequh_p:
case Intrinsic::ppc_altivec_vcmpequw_p:
case Intrinsic::ppc_altivec_vcmpequd_p:
- case Intrinsic::ppc_altivec_vcmpequq_p:
+ case Intrinsic::ppc_altivec_vcmpequq_p:
case Intrinsic::ppc_altivec_vcmpgefp_p:
case Intrinsic::ppc_altivec_vcmpgtfp_p:
case Intrinsic::ppc_altivec_vcmpgtsb_p:
case Intrinsic::ppc_altivec_vcmpgtsh_p:
case Intrinsic::ppc_altivec_vcmpgtsw_p:
case Intrinsic::ppc_altivec_vcmpgtsd_p:
- case Intrinsic::ppc_altivec_vcmpgtsq_p:
+ case Intrinsic::ppc_altivec_vcmpgtsq_p:
case Intrinsic::ppc_altivec_vcmpgtub_p:
case Intrinsic::ppc_altivec_vcmpgtuh_p:
case Intrinsic::ppc_altivec_vcmpgtuw_p:
case Intrinsic::ppc_altivec_vcmpgtud_p:
- case Intrinsic::ppc_altivec_vcmpgtuq_p:
+ case Intrinsic::ppc_altivec_vcmpgtuq_p:
Known.Zero = ~1U; // All bits but the low one are known to be zero.
break;
}
@@ -15147,45 +15147,45 @@ PPCTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
return std::make_pair(0U, &PPC::VSSRCRegClass);
else
return std::make_pair(0U, &PPC::VSFRCRegClass);
- } else if (Constraint == "lr") {
- if (VT == MVT::i64)
- return std::make_pair(0U, &PPC::LR8RCRegClass);
- else
- return std::make_pair(0U, &PPC::LRRCRegClass);
- }
-
- // Handle special cases of physical registers that are not properly handled
- // by the base class.
- if (Constraint[0] == '{' && Constraint[Constraint.size() - 1] == '}') {
- // If we name a VSX register, we can't defer to the base class because it
- // will not recognize the correct register (their names will be VSL{0-31}
- // and V{0-31} so they won't match). So we match them here.
- if (Constraint.size() > 3 && Constraint[1] == 'v' && Constraint[2] == 's') {
- int VSNum = atoi(Constraint.data() + 3);
- assert(VSNum >= 0 && VSNum <= 63 &&
- "Attempted to access a vsr out of range");
- if (VSNum < 32)
- return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
- return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
- }
-
- // For float registers, we can't defer to the base class as it will match
- // the SPILLTOVSRRC class.
- if (Constraint.size() > 3 && Constraint[1] == 'f') {
- int RegNum = atoi(Constraint.data() + 2);
- if (RegNum > 31 || RegNum < 0)
- report_fatal_error("Invalid floating point register number");
- if (VT == MVT::f32 || VT == MVT::i32)
- return Subtarget.hasSPE()
- ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
- : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
- if (VT == MVT::f64 || VT == MVT::i64)
- return Subtarget.hasSPE()
- ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
- : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
- }
- }
-
+ } else if (Constraint == "lr") {
+ if (VT == MVT::i64)
+ return std::make_pair(0U, &PPC::LR8RCRegClass);
+ else
+ return std::make_pair(0U, &PPC::LRRCRegClass);
+ }
+
+ // Handle special cases of physical registers that are not properly handled
+ // by the base class.
+ if (Constraint[0] == '{' && Constraint[Constraint.size() - 1] == '}') {
+ // If we name a VSX register, we can't defer to the base class because it
+ // will not recognize the correct register (their names will be VSL{0-31}
+ // and V{0-31} so they won't match). So we match them here.
+ if (Constraint.size() > 3 && Constraint[1] == 'v' && Constraint[2] == 's') {
+ int VSNum = atoi(Constraint.data() + 3);
+ assert(VSNum >= 0 && VSNum <= 63 &&
+ "Attempted to access a vsr out of range");
+ if (VSNum < 32)
+ return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
+ return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
+ }
+
+ // For float registers, we can't defer to the base class as it will match
+ // the SPILLTOVSRRC class.
+ if (Constraint.size() > 3 && Constraint[1] == 'f') {
+ int RegNum = atoi(Constraint.data() + 2);
+ if (RegNum > 31 || RegNum < 0)
+ report_fatal_error("Invalid floating point register number");
+ if (VT == MVT::f32 || VT == MVT::i32)
+ return Subtarget.hasSPE()
+ ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
+ : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
+ if (VT == MVT::f64 || VT == MVT::i64)
+ return Subtarget.hasSPE()
+ ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
+ : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
+ }
+ }
+
std::pair<unsigned, const TargetRegisterClass *> R =
TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
@@ -15290,15 +15290,15 @@ void PPCTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
// by AM is legal for this target, for a load/store of the specified type.
bool PPCTargetLowering::isLegalAddressingMode(const DataLayout &DL,
const AddrMode &AM, Type *Ty,
- unsigned AS,
- Instruction *I) const {
- // Vector type r+i form is supported since power9 as DQ form. We don't check
- // the offset matching DQ form requirement(off % 16 == 0), because on PowerPC,
- // imm form is preferred and the offset can be adjusted to use imm form later
- // in pass PPCLoopInstrFormPrep. Also in LSR, for one LSRUse, it uses min and
- // max offset to check legal addressing mode, we should be a little aggressive
- // to contain other offsets for that LSRUse.
- if (Ty->isVectorTy() && AM.BaseOffs != 0 && !Subtarget.hasP9Vector())
+ unsigned AS,
+ Instruction *I) const {
+ // Vector type r+i form is supported since power9 as DQ form. We don't check
+ // the offset matching DQ form requirement(off % 16 == 0), because on PowerPC,
+ // imm form is preferred and the offset can be adjusted to use imm form later
+ // in pass PPCLoopInstrFormPrep. Also in LSR, for one LSRUse, it uses min and
+ // max offset to check legal addressing mode, we should be a little aggressive
+ // to contain other offsets for that LSRUse.
+ if (Ty->isVectorTy() && AM.BaseOffs != 0 && !Subtarget.hasP9Vector())
return false;
// PPC allows a sign-extended 16-bit immediate field.
@@ -15458,11 +15458,11 @@ bool PPCTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
case Intrinsic::ppc_altivec_lvehx:
case Intrinsic::ppc_altivec_lvewx:
case Intrinsic::ppc_vsx_lxvd2x:
- case Intrinsic::ppc_vsx_lxvw4x:
- case Intrinsic::ppc_vsx_lxvd2x_be:
- case Intrinsic::ppc_vsx_lxvw4x_be:
- case Intrinsic::ppc_vsx_lxvl:
- case Intrinsic::ppc_vsx_lxvll: {
+ case Intrinsic::ppc_vsx_lxvw4x:
+ case Intrinsic::ppc_vsx_lxvd2x_be:
+ case Intrinsic::ppc_vsx_lxvw4x_be:
+ case Intrinsic::ppc_vsx_lxvl:
+ case Intrinsic::ppc_vsx_lxvll: {
EVT VT;
switch (Intrinsic) {
case Intrinsic::ppc_altivec_lvebx:
@@ -15475,7 +15475,7 @@ bool PPCTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
VT = MVT::i32;
break;
case Intrinsic::ppc_vsx_lxvd2x:
- case Intrinsic::ppc_vsx_lxvd2x_be:
+ case Intrinsic::ppc_vsx_lxvd2x_be:
VT = MVT::v2f64;
break;
default:
@@ -15498,11 +15498,11 @@ bool PPCTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
case Intrinsic::ppc_altivec_stvehx:
case Intrinsic::ppc_altivec_stvewx:
case Intrinsic::ppc_vsx_stxvd2x:
- case Intrinsic::ppc_vsx_stxvw4x:
- case Intrinsic::ppc_vsx_stxvd2x_be:
- case Intrinsic::ppc_vsx_stxvw4x_be:
- case Intrinsic::ppc_vsx_stxvl:
- case Intrinsic::ppc_vsx_stxvll: {
+ case Intrinsic::ppc_vsx_stxvw4x:
+ case Intrinsic::ppc_vsx_stxvd2x_be:
+ case Intrinsic::ppc_vsx_stxvw4x_be:
+ case Intrinsic::ppc_vsx_stxvl:
+ case Intrinsic::ppc_vsx_stxvll: {
EVT VT;
switch (Intrinsic) {
case Intrinsic::ppc_altivec_stvebx:
@@ -15515,7 +15515,7 @@ bool PPCTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
VT = MVT::i32;
break;
case Intrinsic::ppc_vsx_stxvd2x:
- case Intrinsic::ppc_vsx_stxvd2x_be:
+ case Intrinsic::ppc_vsx_stxvd2x_be:
VT = MVT::v2f64;
break;
default:
@@ -15662,33 +15662,33 @@ bool PPCTargetLowering::allowsMisalignedMemoryAccesses(EVT VT,
return true;
}
-bool PPCTargetLowering::decomposeMulByConstant(LLVMContext &Context, EVT VT,
- SDValue C) const {
- // Check integral scalar types.
- if (!VT.isScalarInteger())
- return false;
- if (auto *ConstNode = dyn_cast<ConstantSDNode>(C.getNode())) {
- if (!ConstNode->getAPIntValue().isSignedIntN(64))
- return false;
- // This transformation will generate >= 2 operations. But the following
- // cases will generate <= 2 instructions during ISEL. So exclude them.
- // 1. If the constant multiplier fits 16 bits, it can be handled by one
- // HW instruction, ie. MULLI
- // 2. If the multiplier after shifted fits 16 bits, an extra shift
- // instruction is needed than case 1, ie. MULLI and RLDICR
- int64_t Imm = ConstNode->getSExtValue();
- unsigned Shift = countTrailingZeros<uint64_t>(Imm);
- Imm >>= Shift;
- if (isInt<16>(Imm))
- return false;
- uint64_t UImm = static_cast<uint64_t>(Imm);
- if (isPowerOf2_64(UImm + 1) || isPowerOf2_64(UImm - 1) ||
- isPowerOf2_64(1 - UImm) || isPowerOf2_64(-1 - UImm))
- return true;
- }
- return false;
-}
-
+bool PPCTargetLowering::decomposeMulByConstant(LLVMContext &Context, EVT VT,
+ SDValue C) const {
+ // Check integral scalar types.
+ if (!VT.isScalarInteger())
+ return false;
+ if (auto *ConstNode = dyn_cast<ConstantSDNode>(C.getNode())) {
+ if (!ConstNode->getAPIntValue().isSignedIntN(64))
+ return false;
+ // This transformation will generate >= 2 operations. But the following
+ // cases will generate <= 2 instructions during ISEL. So exclude them.
+ // 1. If the constant multiplier fits 16 bits, it can be handled by one
+ // HW instruction, ie. MULLI
+ // 2. If the multiplier after shifted fits 16 bits, an extra shift
+ // instruction is needed than case 1, ie. MULLI and RLDICR
+ int64_t Imm = ConstNode->getSExtValue();
+ unsigned Shift = countTrailingZeros<uint64_t>(Imm);
+ Imm >>= Shift;
+ if (isInt<16>(Imm))
+ return false;
+ uint64_t UImm = static_cast<uint64_t>(Imm);
+ if (isPowerOf2_64(UImm + 1) || isPowerOf2_64(UImm - 1) ||
+ isPowerOf2_64(1 - UImm) || isPowerOf2_64(-1 - UImm))
+ return true;
+ }
+ return false;
+}
+
bool PPCTargetLowering::isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
EVT VT) const {
return isFMAFasterThanFMulAndFAdd(
@@ -15708,7 +15708,7 @@ bool PPCTargetLowering::isFMAFasterThanFMulAndFAdd(const Function &F,
}
}
-// FIXME: add more patterns which are not profitable to hoist.
+// FIXME: add more patterns which are not profitable to hoist.
bool PPCTargetLowering::isProfitableToHoist(Instruction *I) const {
if (!I->hasOneUse())
return true;
@@ -15716,48 +15716,48 @@ bool PPCTargetLowering::isProfitableToHoist(Instruction *I) const {
Instruction *User = I->user_back();
assert(User && "A single use instruction with no uses.");
- switch (I->getOpcode()) {
- case Instruction::FMul: {
- // Don't break FMA, PowerPC prefers FMA.
- if (User->getOpcode() != Instruction::FSub &&
- User->getOpcode() != Instruction::FAdd)
- return true;
-
- const TargetOptions &Options = getTargetMachine().Options;
- const Function *F = I->getFunction();
- const DataLayout &DL = F->getParent()->getDataLayout();
- Type *Ty = User->getOperand(0)->getType();
-
- return !(
- isFMAFasterThanFMulAndFAdd(*F, Ty) &&
- isOperationLegalOrCustom(ISD::FMA, getValueType(DL, Ty)) &&
- (Options.AllowFPOpFusion == FPOpFusion::Fast || Options.UnsafeFPMath));
- }
- case Instruction::Load: {
- // Don't break "store (load float*)" pattern, this pattern will be combined
- // to "store (load int32)" in later InstCombine pass. See function
- // combineLoadToOperationType. On PowerPC, loading a float point takes more
- // cycles than loading a 32 bit integer.
- LoadInst *LI = cast<LoadInst>(I);
- // For the loads that combineLoadToOperationType does nothing, like
- // ordered load, it should be profitable to hoist them.
- // For swifterror load, it can only be used for pointer to pointer type, so
- // later type check should get rid of this case.
- if (!LI->isUnordered())
- return true;
-
- if (User->getOpcode() != Instruction::Store)
- return true;
-
- if (I->getType()->getTypeID() != Type::FloatTyID)
- return true;
-
- return false;
- }
- default:
- return true;
- }
- return true;
+ switch (I->getOpcode()) {
+ case Instruction::FMul: {
+ // Don't break FMA, PowerPC prefers FMA.
+ if (User->getOpcode() != Instruction::FSub &&
+ User->getOpcode() != Instruction::FAdd)
+ return true;
+
+ const TargetOptions &Options = getTargetMachine().Options;
+ const Function *F = I->getFunction();
+ const DataLayout &DL = F->getParent()->getDataLayout();
+ Type *Ty = User->getOperand(0)->getType();
+
+ return !(
+ isFMAFasterThanFMulAndFAdd(*F, Ty) &&
+ isOperationLegalOrCustom(ISD::FMA, getValueType(DL, Ty)) &&
+ (Options.AllowFPOpFusion == FPOpFusion::Fast || Options.UnsafeFPMath));
+ }
+ case Instruction::Load: {
+ // Don't break "store (load float*)" pattern, this pattern will be combined
+ // to "store (load int32)" in later InstCombine pass. See function
+ // combineLoadToOperationType. On PowerPC, loading a float point takes more
+ // cycles than loading a 32 bit integer.
+ LoadInst *LI = cast<LoadInst>(I);
+ // For the loads that combineLoadToOperationType does nothing, like
+ // ordered load, it should be profitable to hoist them.
+ // For swifterror load, it can only be used for pointer to pointer type, so
+ // later type check should get rid of this case.
+ if (!LI->isUnordered())
+ return true;
+
+ if (User->getOpcode() != Instruction::Store)
+ return true;
+
+ if (I->getType()->getTypeID() != Type::FloatTyID)
+ return true;
+
+ return false;
+ }
+ default:
+ return true;
+ }
+ return true;
}
const MCPhysReg *
@@ -15789,7 +15789,7 @@ PPCTargetLowering::shouldExpandBuildVectorWithShuffles(
if (VT == MVT::v2i64)
return Subtarget.hasDirectMove(); // Don't need stack ops with direct moves
- if (Subtarget.hasVSX())
+ if (Subtarget.hasVSX())
return true;
return TargetLowering::shouldExpandBuildVectorWithShuffles(VT, DefinedValues);
@@ -15835,7 +15835,7 @@ SDValue PPCTargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
switch (Opc) {
case PPCISD::FNMSUB:
- if (!Op.hasOneUse() || !isTypeLegal(VT))
+ if (!Op.hasOneUse() || !isTypeLegal(VT))
break;
const TargetOptions &Options = getTargetMachine().Options;
@@ -15964,10 +15964,10 @@ SDValue PPCTargetLowering::combineSHL(SDNode *N, DAGCombinerInfo &DCI) const {
SDValue N0 = N->getOperand(0);
ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(N->getOperand(1));
- if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
+ if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
N0.getOpcode() != ISD::SIGN_EXTEND ||
- N0.getOperand(0).getValueType() != MVT::i32 || CN1 == nullptr ||
- N->getValueType(0) != MVT::i64)
+ N0.getOperand(0).getValueType() != MVT::i32 || CN1 == nullptr ||
+ N->getValueType(0) != MVT::i64)
return SDValue();
// We can't save an operation here if the value is already extended, and
@@ -16316,7 +16316,7 @@ SDValue PPCTargetLowering::combineFMALike(SDNode *N,
bool LegalOps = !DCI.isBeforeLegalizeOps();
SDLoc Loc(N);
- if (!isOperationLegal(ISD::FMA, VT))
+ if (!isOperationLegal(ISD::FMA, VT))
return SDValue();
// Allowing transformation to FNMSUB may change sign of zeroes when ab-c=0
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCISelLowering.h b/contrib/libs/llvm12/lib/Target/PowerPC/PPCISelLowering.h
index 2a0b6d3eb0..836c52bdff 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCISelLowering.h
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCISelLowering.h
@@ -89,12 +89,12 @@ namespace llvm {
FRE,
FRSQRTE,
- /// Test instruction for software square root.
- FTSQRT,
-
- /// Square root instruction.
- FSQRT,
-
+ /// Test instruction for software square root.
+ FTSQRT,
+
+ /// Square root instruction.
+ FSQRT,
+
/// VPERM - The PPC VPERM Instruction.
///
VPERM,
@@ -152,7 +152,7 @@ namespace llvm {
/// probed.
PROBED_ALLOCA,
- /// The result of the mflr at function entry, used for PIC code.
+ /// The result of the mflr at function entry, used for PIC code.
GlobalBaseReg,
/// These nodes represent PPC shifts.
@@ -270,11 +270,11 @@ namespace llvm {
/// is VCMPGTSH.
VCMP,
- /// RESVEC, OUTFLAG = VCMP_rec(LHS, RHS, OPC) - Represents one of the
- /// altivec VCMP*_rec instructions. For lack of better number, we use the
+ /// RESVEC, OUTFLAG = VCMP_rec(LHS, RHS, OPC) - Represents one of the
+ /// altivec VCMP*_rec instructions. For lack of better number, we use the
/// opcode number encoding for the OPC field to identify the compare. For
/// example, 838 is VCMPGTSH.
- VCMP_rec,
+ VCMP_rec,
/// CHAIN = COND_BRANCH CHAIN, CRRC, OPC, DESTBB [, INFLAG] - This
/// corresponds to the COND_BRANCH pseudo instruction. CRRC is the
@@ -386,10 +386,10 @@ namespace llvm {
/// sym\@got\@dtprel\@l.
ADDI_DTPREL_L,
- /// G8RC = PADDI_DTPREL %x3, Symbol - For the pc-rel based local-dynamic TLS
- /// model, produces a PADDI8 instruction that adds X3 to sym\@dtprel.
- PADDI_DTPREL,
-
+ /// G8RC = PADDI_DTPREL %x3, Symbol - For the pc-rel based local-dynamic TLS
+ /// model, produces a PADDI8 instruction that adds X3 to sym\@dtprel.
+ PADDI_DTPREL,
+
/// VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded
/// during instruction selection to optimize a BUILD_VECTOR into
/// operations on splats. This is necessary to avoid losing these
@@ -445,46 +445,46 @@ namespace llvm {
/// PLD.
MAT_PCREL_ADDR,
- /// TLS_DYNAMIC_MAT_PCREL_ADDR = Materialize a PC Relative address for
- /// TLS global address when using dynamic access models. This can be done
- /// through an add like PADDI.
- TLS_DYNAMIC_MAT_PCREL_ADDR,
-
- /// TLS_LOCAL_EXEC_MAT_ADDR = Materialize an address for TLS global address
- /// when using local exec access models, and when prefixed instructions are
- /// available. This is used with ADD_TLS to produce an add like PADDI.
- TLS_LOCAL_EXEC_MAT_ADDR,
-
- /// ACC_BUILD = Build an accumulator register from 4 VSX registers.
- ACC_BUILD,
-
- /// PAIR_BUILD = Build a vector pair register from 2 VSX registers.
- PAIR_BUILD,
-
- /// EXTRACT_VSX_REG = Extract one of the underlying vsx registers of
- /// an accumulator or pair register. This node is needed because
- /// EXTRACT_SUBVECTOR expects the input and output vectors to have the same
- /// element type.
- EXTRACT_VSX_REG,
-
- /// XXMFACC = This corresponds to the xxmfacc instruction.
- XXMFACC,
-
- // Constrained conversion from floating point to int
- STRICT_FCTIDZ = ISD::FIRST_TARGET_STRICTFP_OPCODE,
- STRICT_FCTIWZ,
- STRICT_FCTIDUZ,
- STRICT_FCTIWUZ,
-
- /// Constrained integer-to-floating-point conversion instructions.
- STRICT_FCFID,
- STRICT_FCFIDU,
- STRICT_FCFIDS,
- STRICT_FCFIDUS,
-
- /// Constrained floating point add in round-to-zero mode.
- STRICT_FADDRTZ,
-
+ /// TLS_DYNAMIC_MAT_PCREL_ADDR = Materialize a PC Relative address for
+ /// TLS global address when using dynamic access models. This can be done
+ /// through an add like PADDI.
+ TLS_DYNAMIC_MAT_PCREL_ADDR,
+
+ /// TLS_LOCAL_EXEC_MAT_ADDR = Materialize an address for TLS global address
+ /// when using local exec access models, and when prefixed instructions are
+ /// available. This is used with ADD_TLS to produce an add like PADDI.
+ TLS_LOCAL_EXEC_MAT_ADDR,
+
+ /// ACC_BUILD = Build an accumulator register from 4 VSX registers.
+ ACC_BUILD,
+
+ /// PAIR_BUILD = Build a vector pair register from 2 VSX registers.
+ PAIR_BUILD,
+
+ /// EXTRACT_VSX_REG = Extract one of the underlying vsx registers of
+ /// an accumulator or pair register. This node is needed because
+ /// EXTRACT_SUBVECTOR expects the input and output vectors to have the same
+ /// element type.
+ EXTRACT_VSX_REG,
+
+ /// XXMFACC = This corresponds to the xxmfacc instruction.
+ XXMFACC,
+
+ // Constrained conversion from floating point to int
+ STRICT_FCTIDZ = ISD::FIRST_TARGET_STRICTFP_OPCODE,
+ STRICT_FCTIWZ,
+ STRICT_FCTIDUZ,
+ STRICT_FCTIWUZ,
+
+ /// Constrained integer-to-floating-point conversion instructions.
+ STRICT_FCFID,
+ STRICT_FCFIDU,
+ STRICT_FCFIDS,
+ STRICT_FCFIDUS,
+
+ /// Constrained floating point add in round-to-zero mode.
+ STRICT_FADDRTZ,
+
/// CHAIN = STBRX CHAIN, GPRC, Ptr, Type - This is a
/// byte-swapping store instruction. It byte-swaps the low "Type" bits of
/// the GPRC input, then stores it through Ptr. Type can be either i16 or
@@ -526,12 +526,12 @@ namespace llvm {
/// an xxswapd.
LXVD2X,
- /// LXVRZX - Load VSX Vector Rightmost and Zero Extend
- /// This node represents v1i128 BUILD_VECTOR of a zero extending load
- /// instruction from <byte, halfword, word, or doubleword> to i128.
- /// Allows utilization of the Load VSX Vector Rightmost Instructions.
- LXVRZX,
-
+ /// LXVRZX - Load VSX Vector Rightmost and Zero Extend
+ /// This node represents v1i128 BUILD_VECTOR of a zero extending load
+ /// instruction from <byte, halfword, word, or doubleword> to i128.
+ /// Allows utilization of the Load VSX Vector Rightmost Instructions.
+ LXVRZX,
+
/// VSRC, CHAIN = LOAD_VEC_BE CHAIN, Ptr - Occurs only for little endian.
/// Maps directly to one of lxvd2x/lxvw4x/lxvh8x/lxvb16x depending on
/// the vector type to load vector in big-endian element order.
@@ -771,8 +771,8 @@ namespace llvm {
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base,
SelectionDAG &DAG,
MaybeAlign EncodingAlignment) const;
- bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base,
- SelectionDAG &DAG) const;
+ bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base,
+ SelectionDAG &DAG) const;
/// SelectAddressRegRegOnly - Given the specified addressed, force it to be
/// represented as an indexed [r+r] operation.
@@ -928,9 +928,9 @@ namespace llvm {
return true;
}
- bool decomposeMulByConstant(LLVMContext &Context, EVT VT,
- SDValue C) const override;
-
+ bool decomposeMulByConstant(LLVMContext &Context, EVT VT,
+ SDValue C) const override;
+
bool isDesirableToTransformToIntegerOp(unsigned Opc,
EVT VT) const override {
// Only handle float load/store pair because float(fpr) load/store
@@ -987,9 +987,9 @@ namespace llvm {
shouldExpandBuildVectorWithShuffles(EVT VT,
unsigned DefinedValues) const override;
- // Keep the zero-extensions for arguments to libcalls.
- bool shouldKeepZExtForFP16Conv() const override { return true; }
-
+ // Keep the zero-extensions for arguments to libcalls.
+ bool shouldKeepZExtForFP16Conv() const override { return true; }
+
/// createFastISel - This method returns a target-specific FastISel object,
/// or null if the target does not support "fast" instruction selection.
FastISel *createFastISel(FunctionLoweringInfo &FuncInfo,
@@ -1128,7 +1128,7 @@ namespace llvm {
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVACOPY(SDValue Op, SelectionDAG &DAG) const;
@@ -1147,7 +1147,7 @@ namespace llvm {
SDValue LowerSHL_PARTS(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSRL_PARTS(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSRA_PARTS(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerFunnelShift(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerFunnelShift(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
@@ -1158,7 +1158,7 @@ namespace llvm {
SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerROTL(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVectorLoad(SDValue Op, SelectionDAG &DAG) const;
@@ -1275,10 +1275,10 @@ namespace llvm {
bool Reciprocal) const override;
SDValue getRecipEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled,
int &RefinementSteps) const override;
- SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG,
- const DenormalMode &Mode) const override;
- SDValue getSqrtResultForDenormInput(SDValue Operand,
- SelectionDAG &DAG) const override;
+ SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG,
+ const DenormalMode &Mode) const override;
+ SDValue getSqrtResultForDenormInput(SDValue Operand,
+ SelectionDAG &DAG) const override;
unsigned combineRepeatedFPDivisors() const override;
SDValue
@@ -1317,8 +1317,8 @@ namespace llvm {
bool isIntS16Immediate(SDNode *N, int16_t &Imm);
bool isIntS16Immediate(SDValue Op, int16_t &Imm);
- bool isIntS34Immediate(SDNode *N, int64_t &Imm);
- bool isIntS34Immediate(SDValue Op, int64_t &Imm);
+ bool isIntS34Immediate(SDNode *N, int64_t &Imm);
+ bool isIntS34Immediate(SDValue Op, int64_t &Imm);
bool convertToNonDenormSingle(APInt &ArgAPInt);
bool convertToNonDenormSingle(APFloat &ArgAPFloat);
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstr64Bit.td b/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstr64Bit.td
index f5307bf690..03e9d6970a 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -19,14 +19,14 @@ def s16imm64 : Operand<i64> {
let EncoderMethod = "getImm16Encoding";
let ParserMatchClass = PPCS16ImmAsmOperand;
let DecoderMethod = "decodeSImmOperand<16>";
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def u16imm64 : Operand<i64> {
let PrintMethod = "printU16ImmOperand";
let EncoderMethod = "getImm16Encoding";
let ParserMatchClass = PPCU16ImmAsmOperand;
let DecoderMethod = "decodeUImmOperand<16>";
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def s17imm64 : Operand<i64> {
// This operand type is used for addis/lis to allow the assembler parser
@@ -36,7 +36,7 @@ def s17imm64 : Operand<i64> {
let EncoderMethod = "getImm16Encoding";
let ParserMatchClass = PPCS17ImmAsmOperand;
let DecoderMethod = "decodeSImmOperand<16>";
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def tocentry : Operand<iPTR> {
let MIOperandInfo = (ops i64imm:$imm);
@@ -151,9 +151,9 @@ let isCall = 1, PPC970_Unit = 7, Defs = [LR8] in {
def BL8_NOTOC : IForm<18, 0, 1, (outs),
(ins calltarget:$func),
"bl $func", IIC_BrB, []>;
- def BL8_NOTOC_TLS : IForm<18, 0, 1, (outs),
- (ins tlscall:$func),
- "bl $func", IIC_BrB, []>;
+ def BL8_NOTOC_TLS : IForm<18, 0, 1, (outs),
+ (ins tlscall:$func),
+ "bl $func", IIC_BrB, []>;
}
}
let Uses = [CTR8, RM] in {
@@ -846,7 +846,7 @@ let Interpretation64Bit = 1, isCodeGenOnly = 1 in {
def SETB8 : XForm_44<31, 128, (outs g8rc:$RT), (ins crrc:$BFA),
"setb $RT, $BFA", IIC_IntGeneral>, isPPC64;
}
-def DARN : XForm_45<31, 755, (outs g8rc:$RT), (ins u2imm:$L),
+def DARN : XForm_45<31, 755, (outs g8rc:$RT), (ins u2imm:$L),
"darn $RT, $L", IIC_LdStLD>, isPPC64;
def ADDPCIS : DXForm<19, 2, (outs g8rc:$RT), (ins i32imm:$D),
"addpcis $RT, $D", IIC_BrB, []>, isPPC64;
@@ -987,11 +987,11 @@ def : InstAlias<"cntlzw. $rA, $rS", (CNTLZW8_rec g8rc:$rA, g8rc:$rS)>;
def : InstAlias<"mtxer $Rx", (MTSPR8 1, g8rc:$Rx)>;
def : InstAlias<"mfxer $Rx", (MFSPR8 g8rc:$Rx, 1)>;
-//Disable this alias on AIX for now because as does not support them.
-let Predicates = [ModernAs] in {
- def : InstAlias<"mtudscr $Rx", (MTSPR8 3, g8rc:$Rx)>;
- def : InstAlias<"mfudscr $Rx", (MFSPR8 g8rc:$Rx, 3)>;
-}
+//Disable this alias on AIX for now because as does not support them.
+let Predicates = [ModernAs] in {
+ def : InstAlias<"mtudscr $Rx", (MTSPR8 3, g8rc:$Rx)>;
+ def : InstAlias<"mfudscr $Rx", (MFSPR8 g8rc:$Rx, 3)>;
+}
def : InstAlias<"mfrtcu $Rx", (MFSPR8 g8rc:$Rx, 4)>;
def : InstAlias<"mfrtcl $Rx", (MFSPR8 g8rc:$Rx, 5)>;
@@ -1065,7 +1065,7 @@ def LHA8: DForm_1<42, (outs g8rc:$rD), (ins memri:$src),
def LWA : DSForm_1<58, 2, (outs g8rc:$rD), (ins memrix:$src),
"lwa $rD, $src", IIC_LdStLWA,
[(set i64:$rD,
- (DSFormSextLoadi32 iaddrX4:$src))]>, isPPC64,
+ (DSFormSextLoadi32 iaddrX4:$src))]>, isPPC64,
PPC970_DGroup_Cracked;
let Interpretation64Bit = 1, isCodeGenOnly = 1 in
def LHAX8: XForm_1_memOp<31, 343, (outs g8rc:$rD), (ins memrr:$src),
@@ -1176,7 +1176,7 @@ def LWZUX8 : XForm_1_memOp<31, 55, (outs g8rc:$rD, ptr_rc_nor0:$ea_result),
let PPC970_Unit = 2 in {
def LD : DSForm_1<58, 0, (outs g8rc:$rD), (ins memrix:$src),
"ld $rD, $src", IIC_LdStLD,
- [(set i64:$rD, (DSFormLoad iaddrX4:$src))]>, isPPC64;
+ [(set i64:$rD, (DSFormLoad iaddrX4:$src))]>, isPPC64;
// The following four definitions are selected for small code model only.
// Otherwise, we need to create two instructions to form a 32-bit offset,
// so we have a custom matcher for TOC_ENTRY in PPCDAGToDAGIsel::Select().
@@ -1271,36 +1271,36 @@ def ADDItlsgdL : PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc_nox0:$reg, s16imm6
[(set i64:$rD,
(PPCaddiTlsgdL i64:$reg, tglobaltlsaddr:$disp))]>,
isPPC64;
-
-class GETtlsADDRPseudo <string asmstr> : PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc:$reg, tlsgd:$sym),
- asmstr,
- [(set i64:$rD,
- (PPCgetTlsAddr i64:$reg, tglobaltlsaddr:$sym))]>,
- isPPC64;
-class GETtlsldADDRPseudo <string asmstr> : PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc:$reg, tlsgd:$sym),
- asmstr,
- [(set i64:$rD,
- (PPCgetTlsldAddr i64:$reg, tglobaltlsaddr:$sym))]>,
- isPPC64;
-
-let hasExtraSrcRegAllocReq = 1, hasExtraDefRegAllocReq = 1 in {
-// LR8 is a true define, while the rest of the Defs are clobbers. X3 is
+
+class GETtlsADDRPseudo <string asmstr> : PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc:$reg, tlsgd:$sym),
+ asmstr,
+ [(set i64:$rD,
+ (PPCgetTlsAddr i64:$reg, tglobaltlsaddr:$sym))]>,
+ isPPC64;
+class GETtlsldADDRPseudo <string asmstr> : PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc:$reg, tlsgd:$sym),
+ asmstr,
+ [(set i64:$rD,
+ (PPCgetTlsldAddr i64:$reg, tglobaltlsaddr:$sym))]>,
+ isPPC64;
+
+let hasExtraSrcRegAllocReq = 1, hasExtraDefRegAllocReq = 1 in {
+// LR8 is a true define, while the rest of the Defs are clobbers. X3 is
// explicitly defined when this op is created, so not mentioned here.
// This is lowered to BL8_NOP_TLS by the assembly printer, so the size must be
// correct because the branch select pass is relying on it.
-let Defs = [X0,X4,X5,X6,X7,X8,X9,X10,X11,X12,LR8,CTR8,CR0,CR1,CR5,CR6,CR7], Size = 8 in
-def GETtlsADDR : GETtlsADDRPseudo <"#GETtlsADDR">;
-let Defs = [X0,X2,X4,X5,X6,X7,X8,X9,X10,X11,X12,LR8,CTR8,CR0,CR1,CR5,CR6,CR7], Size = 8 in
-def GETtlsADDRPCREL : GETtlsADDRPseudo <"#GETtlsADDRPCREL">;
-
-// LR8 is a true define, while the rest of the Defs are clobbers. X3 is
-// explicitly defined when this op is created, so not mentioned here.
-let Defs = [X0,X4,X5,X6,X7,X8,X9,X10,X11,X12,LR8,CTR8,CR0,CR1,CR5,CR6,CR7] in
-def GETtlsldADDR : GETtlsldADDRPseudo <"#GETtlsldADDR">;
-let Defs = [X0,X2,X4,X5,X6,X7,X8,X9,X10,X11,X12,LR8,CTR8,CR0,CR1,CR5,CR6,CR7] in
-def GETtlsldADDRPCREL : GETtlsldADDRPseudo <"#GETtlsldADDRPCREL">;
-}
-
+let Defs = [X0,X4,X5,X6,X7,X8,X9,X10,X11,X12,LR8,CTR8,CR0,CR1,CR5,CR6,CR7], Size = 8 in
+def GETtlsADDR : GETtlsADDRPseudo <"#GETtlsADDR">;
+let Defs = [X0,X2,X4,X5,X6,X7,X8,X9,X10,X11,X12,LR8,CTR8,CR0,CR1,CR5,CR6,CR7], Size = 8 in
+def GETtlsADDRPCREL : GETtlsADDRPseudo <"#GETtlsADDRPCREL">;
+
+// LR8 is a true define, while the rest of the Defs are clobbers. X3 is
+// explicitly defined when this op is created, so not mentioned here.
+let Defs = [X0,X4,X5,X6,X7,X8,X9,X10,X11,X12,LR8,CTR8,CR0,CR1,CR5,CR6,CR7] in
+def GETtlsldADDR : GETtlsldADDRPseudo <"#GETtlsldADDR">;
+let Defs = [X0,X2,X4,X5,X6,X7,X8,X9,X10,X11,X12,LR8,CTR8,CR0,CR1,CR5,CR6,CR7] in
+def GETtlsldADDRPCREL : GETtlsldADDRPseudo <"#GETtlsldADDRPCREL">;
+}
+
// Combined op for ADDItlsgdL and GETtlsADDR, late expanded. X3 and LR8
// are true defines while the rest of the Defs are clobbers.
let hasExtraSrcRegAllocReq = 1, hasExtraDefRegAllocReq = 1,
@@ -1348,11 +1348,11 @@ def ADDIdtprelL : PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc_nox0:$reg, s16imm
[(set i64:$rD,
(PPCaddiDtprelL i64:$reg, tglobaltlsaddr:$disp))]>,
isPPC64;
-def PADDIdtprel : PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc_nox0:$reg, s16imm64:$disp),
- "#PADDIdtprel",
- [(set i64:$rD,
- (PPCpaddiDtprel i64:$reg, tglobaltlsaddr:$disp))]>,
- isPPC64;
+def PADDIdtprel : PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc_nox0:$reg, s16imm64:$disp),
+ "#PADDIdtprel",
+ [(set i64:$rD,
+ (PPCpaddiDtprel i64:$reg, tglobaltlsaddr:$disp))]>,
+ isPPC64;
let PPC970_Unit = 2 in {
let Interpretation64Bit = 1, isCodeGenOnly = 1 in {
@@ -1383,7 +1383,7 @@ def STWX8 : XForm_8_memOp<31, 151, (outs), (ins g8rc:$rS, memrr:$dst),
// Normal 8-byte stores.
def STD : DSForm_1<62, 0, (outs), (ins g8rc:$rS, memrix:$dst),
"std $rS, $dst", IIC_LdStSTD,
- [(DSFormStore i64:$rS, iaddrX4:$dst)]>, isPPC64;
+ [(DSFormStore i64:$rS, iaddrX4:$dst)]>, isPPC64;
def STDX : XForm_8_memOp<31, 149, (outs), (ins g8rc:$rS, memrr:$dst),
"stdx $rS, $dst", IIC_LdStSTD,
[(store i64:$rS, xaddrX4:$dst)]>, isPPC64,
@@ -1450,7 +1450,7 @@ def : Pat<(pre_truncsti16 i64:$rS, iPTR:$ptrreg, iaddroff:$ptroff),
(STHU8 $rS, iaddroff:$ptroff, $ptrreg)>;
def : Pat<(pre_truncsti32 i64:$rS, iPTR:$ptrreg, iaddroff:$ptroff),
(STWU8 $rS, iaddroff:$ptroff, $ptrreg)>;
-def : Pat<(DSFormPreStore i64:$rS, iPTR:$ptrreg, iaddroff:$ptroff),
+def : Pat<(DSFormPreStore i64:$rS, iPTR:$ptrreg, iaddroff:$ptroff),
(STDU $rS, iaddroff:$ptroff, $ptrreg)>;
def : Pat<(pre_truncsti8 i64:$rS, iPTR:$ptrreg, iPTR:$ptroff),
@@ -1468,11 +1468,11 @@ def : Pat<(pre_store i64:$rS, iPTR:$ptrreg, iPTR:$ptroff),
//
-let PPC970_Unit = 3, hasSideEffects = 0, mayRaiseFPException = 1,
+let PPC970_Unit = 3, hasSideEffects = 0, mayRaiseFPException = 1,
Uses = [RM] in { // FPU Operations.
defm FCFID : XForm_26r<63, 846, (outs f8rc:$frD), (ins f8rc:$frB),
"fcfid", "$frD, $frB", IIC_FPGeneral,
- [(set f64:$frD, (PPCany_fcfid f64:$frB))]>, isPPC64;
+ [(set f64:$frD, (PPCany_fcfid f64:$frB))]>, isPPC64;
defm FCTID : XForm_26r<63, 814, (outs f8rc:$frD), (ins f8rc:$frB),
"fctid", "$frD, $frB", IIC_FPGeneral,
[]>, isPPC64;
@@ -1481,23 +1481,23 @@ defm FCTIDU : XForm_26r<63, 942, (outs f8rc:$frD), (ins f8rc:$frB),
[]>, isPPC64;
defm FCTIDZ : XForm_26r<63, 815, (outs f8rc:$frD), (ins f8rc:$frB),
"fctidz", "$frD, $frB", IIC_FPGeneral,
- [(set f64:$frD, (PPCany_fctidz f64:$frB))]>, isPPC64;
+ [(set f64:$frD, (PPCany_fctidz f64:$frB))]>, isPPC64;
defm FCFIDU : XForm_26r<63, 974, (outs f8rc:$frD), (ins f8rc:$frB),
"fcfidu", "$frD, $frB", IIC_FPGeneral,
- [(set f64:$frD, (PPCany_fcfidu f64:$frB))]>, isPPC64;
+ [(set f64:$frD, (PPCany_fcfidu f64:$frB))]>, isPPC64;
defm FCFIDS : XForm_26r<59, 846, (outs f4rc:$frD), (ins f8rc:$frB),
"fcfids", "$frD, $frB", IIC_FPGeneral,
- [(set f32:$frD, (PPCany_fcfids f64:$frB))]>, isPPC64;
+ [(set f32:$frD, (PPCany_fcfids f64:$frB))]>, isPPC64;
defm FCFIDUS : XForm_26r<59, 974, (outs f4rc:$frD), (ins f8rc:$frB),
"fcfidus", "$frD, $frB", IIC_FPGeneral,
- [(set f32:$frD, (PPCany_fcfidus f64:$frB))]>, isPPC64;
+ [(set f32:$frD, (PPCany_fcfidus f64:$frB))]>, isPPC64;
defm FCTIDUZ : XForm_26r<63, 943, (outs f8rc:$frD), (ins f8rc:$frB),
"fctiduz", "$frD, $frB", IIC_FPGeneral,
- [(set f64:$frD, (PPCany_fctiduz f64:$frB))]>, isPPC64;
+ [(set f64:$frD, (PPCany_fctiduz f64:$frB))]>, isPPC64;
defm FCTIWUZ : XForm_26r<63, 143, (outs f8rc:$frD), (ins f8rc:$frB),
"fctiwuz", "$frD, $frB", IIC_FPGeneral,
- [(set f64:$frD, (PPCany_fctiwuz f64:$frB))]>, isPPC64;
+ [(set f64:$frD, (PPCany_fctiwuz f64:$frB))]>, isPPC64;
}
@@ -1594,11 +1594,11 @@ def : Pat<(add i64:$in, (PPChi tblockaddress:$g, 0)),
// Patterns to match r+r indexed loads and stores for
// addresses without at least 4-byte alignment.
-def : Pat<(i64 (NonDSFormSextLoadi32 xoaddr:$src)),
+def : Pat<(i64 (NonDSFormSextLoadi32 xoaddr:$src)),
(LWAX xoaddr:$src)>;
-def : Pat<(i64 (NonDSFormLoad xoaddr:$src)),
+def : Pat<(i64 (NonDSFormLoad xoaddr:$src)),
(LDX xoaddr:$src)>;
-def : Pat<(NonDSFormStore i64:$rS, xoaddr:$dst),
+def : Pat<(NonDSFormStore i64:$rS, xoaddr:$dst),
(STDX $rS, xoaddr:$dst)>;
// 64-bits atomic loads and stores
@@ -1609,11 +1609,11 @@ def : Pat<(atomic_store_64 iaddrX4:$ptr, i64:$val), (STD g8rc:$val, memrix:$ptr
def : Pat<(atomic_store_64 xaddrX4:$ptr, i64:$val), (STDX g8rc:$val, memrr:$ptr)>;
let Predicates = [IsISA3_0] in {
-// DARN (deliver random number)
-// L=0 for 32-bit, L=1 for conditioned random, L=2 for raw random
-def : Pat<(int_ppc_darn32), (EXTRACT_SUBREG (DARN 0), sub_32)>;
-def : Pat<(int_ppc_darn), (DARN 1)>;
-def : Pat<(int_ppc_darnraw), (DARN 2)>;
+// DARN (deliver random number)
+// L=0 for 32-bit, L=1 for conditioned random, L=2 for raw random
+def : Pat<(int_ppc_darn32), (EXTRACT_SUBREG (DARN 0), sub_32)>;
+def : Pat<(int_ppc_darn), (DARN 1)>;
+def : Pat<(int_ppc_darnraw), (DARN 2)>;
class X_L1_RA5_RB5<bits<6> opcode, bits<10> xo, string opc, RegisterOperand ty,
InstrItinClass itin, list<dag> pattern>
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrAltivec.td b/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrAltivec.td
index b6b1f3d442..1a34aa0931 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrAltivec.td
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrAltivec.td
@@ -404,14 +404,14 @@ let isCodeGenOnly = 1 in {
Deprecated<DeprecatedDST>;
}
-let hasSideEffects = 1 in {
- def MFVSCR : VXForm_4<1540, (outs vrrc:$vD), (ins),
- "mfvscr $vD", IIC_LdStStore,
- [(set v8i16:$vD, (int_ppc_altivec_mfvscr))]>;
- def MTVSCR : VXForm_5<1604, (outs), (ins vrrc:$vB),
- "mtvscr $vB", IIC_LdStLoad,
- [(int_ppc_altivec_mtvscr v4i32:$vB)]>;
-}
+let hasSideEffects = 1 in {
+ def MFVSCR : VXForm_4<1540, (outs vrrc:$vD), (ins),
+ "mfvscr $vD", IIC_LdStStore,
+ [(set v8i16:$vD, (int_ppc_altivec_mfvscr))]>;
+ def MTVSCR : VXForm_5<1604, (outs), (ins vrrc:$vB),
+ "mtvscr $vB", IIC_LdStLoad,
+ [(int_ppc_altivec_mtvscr v4i32:$vB)]>;
+}
let PPC970_Unit = 2, mayLoad = 1, mayStore = 0 in { // Loads.
def LVEBX: XForm_1_memOp<31, 7, (outs vrrc:$vD), (ins memrr:$src),
@@ -471,11 +471,11 @@ def VNMSUBFP: VAForm_1<47, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vC, vrrc:$vB),
"vnmsubfp $vD, $vA, $vC, $vB", IIC_VecFP,
[(set v4f32:$vD, (fneg (fma v4f32:$vA, v4f32:$vC,
(fneg v4f32:$vB))))]>;
-let hasSideEffects = 1 in {
- def VMHADDSHS : VA1a_Int_Ty<32, "vmhaddshs", int_ppc_altivec_vmhaddshs, v8i16>;
- def VMHRADDSHS : VA1a_Int_Ty<33, "vmhraddshs", int_ppc_altivec_vmhraddshs,
- v8i16>;
-}
+let hasSideEffects = 1 in {
+ def VMHADDSHS : VA1a_Int_Ty<32, "vmhaddshs", int_ppc_altivec_vmhaddshs, v8i16>;
+ def VMHRADDSHS : VA1a_Int_Ty<33, "vmhraddshs", int_ppc_altivec_vmhraddshs,
+ v8i16>;
+}
def VMLADDUHM : VA1a_Int_Ty<34, "vmladduhm", int_ppc_altivec_vmladduhm, v8i16>;
} // isCommutable
@@ -615,12 +615,12 @@ def VMSUMUBM : VA1a_Int_Ty3<36, "vmsumubm", int_ppc_altivec_vmsumubm,
v4i32, v16i8, v4i32>;
def VMSUMUHM : VA1a_Int_Ty3<38, "vmsumuhm", int_ppc_altivec_vmsumuhm,
v4i32, v8i16, v4i32>;
-let hasSideEffects = 1 in {
- def VMSUMSHS : VA1a_Int_Ty3<41, "vmsumshs", int_ppc_altivec_vmsumshs,
- v4i32, v8i16, v4i32>;
- def VMSUMUHS : VA1a_Int_Ty3<39, "vmsumuhs", int_ppc_altivec_vmsumuhs,
- v4i32, v8i16, v4i32>;
-}
+let hasSideEffects = 1 in {
+ def VMSUMSHS : VA1a_Int_Ty3<41, "vmsumshs", int_ppc_altivec_vmsumshs,
+ v4i32, v8i16, v4i32>;
+ def VMSUMUHS : VA1a_Int_Ty3<39, "vmsumuhs", int_ppc_altivec_vmsumuhs,
+ v4i32, v8i16, v4i32>;
+}
let isCommutable = 1 in {
def VMULESB : VX1_Int_Ty2<776, "vmulesb", int_ppc_altivec_vmulesb,
@@ -670,17 +670,17 @@ def VSUBUBS : VX1_Int_Ty<1536, "vsububs" , int_ppc_altivec_vsububs, v16i8>;
def VSUBUHS : VX1_Int_Ty<1600, "vsubuhs" , int_ppc_altivec_vsubuhs, v8i16>;
def VSUBUWS : VX1_Int_Ty<1664, "vsubuws" , int_ppc_altivec_vsubuws, v4i32>;
-let hasSideEffects = 1 in {
- def VSUMSWS : VX1_Int_Ty<1928, "vsumsws" , int_ppc_altivec_vsumsws, v4i32>;
- def VSUM2SWS: VX1_Int_Ty<1672, "vsum2sws", int_ppc_altivec_vsum2sws, v4i32>;
+let hasSideEffects = 1 in {
+ def VSUMSWS : VX1_Int_Ty<1928, "vsumsws" , int_ppc_altivec_vsumsws, v4i32>;
+ def VSUM2SWS: VX1_Int_Ty<1672, "vsum2sws", int_ppc_altivec_vsum2sws, v4i32>;
- def VSUM4SBS: VX1_Int_Ty3<1800, "vsum4sbs", int_ppc_altivec_vsum4sbs,
- v4i32, v16i8, v4i32>;
- def VSUM4SHS: VX1_Int_Ty3<1608, "vsum4shs", int_ppc_altivec_vsum4shs,
- v4i32, v8i16, v4i32>;
- def VSUM4UBS: VX1_Int_Ty3<1544, "vsum4ubs", int_ppc_altivec_vsum4ubs,
- v4i32, v16i8, v4i32>;
-}
+ def VSUM4SBS: VX1_Int_Ty3<1800, "vsum4sbs", int_ppc_altivec_vsum4sbs,
+ v4i32, v16i8, v4i32>;
+ def VSUM4SHS: VX1_Int_Ty3<1608, "vsum4shs", int_ppc_altivec_vsum4shs,
+ v4i32, v8i16, v4i32>;
+ def VSUM4UBS: VX1_Int_Ty3<1544, "vsum4ubs", int_ppc_altivec_vsum4ubs,
+ v4i32, v16i8, v4i32>;
+}
def VNOR : VXForm_1<1284, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
"vnor $vD, $vA, $vB", IIC_VecFP,
@@ -749,20 +749,20 @@ def VSPLTISW : VXForm_3<908, (outs vrrc:$vD), (ins s5imm:$SIMM),
// Vector Pack.
def VPKPX : VX1_Int_Ty2<782, "vpkpx", int_ppc_altivec_vpkpx,
v8i16, v4i32>;
-let hasSideEffects = 1 in {
- def VPKSHSS : VX1_Int_Ty2<398, "vpkshss", int_ppc_altivec_vpkshss,
- v16i8, v8i16>;
- def VPKSHUS : VX1_Int_Ty2<270, "vpkshus", int_ppc_altivec_vpkshus,
- v16i8, v8i16>;
- def VPKSWSS : VX1_Int_Ty2<462, "vpkswss", int_ppc_altivec_vpkswss,
- v8i16, v4i32>;
- def VPKSWUS : VX1_Int_Ty2<334, "vpkswus", int_ppc_altivec_vpkswus,
- v8i16, v4i32>;
- def VPKUHUS : VX1_Int_Ty2<142, "vpkuhus", int_ppc_altivec_vpkuhus,
- v16i8, v8i16>;
- def VPKUWUS : VX1_Int_Ty2<206, "vpkuwus", int_ppc_altivec_vpkuwus,
- v8i16, v4i32>;
-}
+let hasSideEffects = 1 in {
+ def VPKSHSS : VX1_Int_Ty2<398, "vpkshss", int_ppc_altivec_vpkshss,
+ v16i8, v8i16>;
+ def VPKSHUS : VX1_Int_Ty2<270, "vpkshus", int_ppc_altivec_vpkshus,
+ v16i8, v8i16>;
+ def VPKSWSS : VX1_Int_Ty2<462, "vpkswss", int_ppc_altivec_vpkswss,
+ v8i16, v4i32>;
+ def VPKSWUS : VX1_Int_Ty2<334, "vpkswus", int_ppc_altivec_vpkswus,
+ v8i16, v4i32>;
+ def VPKUHUS : VX1_Int_Ty2<142, "vpkuhus", int_ppc_altivec_vpkuhus,
+ v16i8, v8i16>;
+ def VPKUWUS : VX1_Int_Ty2<206, "vpkuwus", int_ppc_altivec_vpkuwus,
+ v8i16, v4i32>;
+}
def VPKUHUM : VXForm_1<14, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
"vpkuhum $vD, $vA, $vB", IIC_VecFP,
[(set v16i8:$vD,
@@ -793,47 +793,47 @@ class VCMP<bits<10> xo, string asmstr, ValueType Ty>
: VXRForm_1<xo, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB), asmstr,
IIC_VecFPCompare,
[(set Ty:$vD, (Ty (PPCvcmp Ty:$vA, Ty:$vB, xo)))]>;
-class VCMP_rec<bits<10> xo, string asmstr, ValueType Ty>
+class VCMP_rec<bits<10> xo, string asmstr, ValueType Ty>
: VXRForm_1<xo, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB), asmstr,
IIC_VecFPCompare,
- [(set Ty:$vD, (Ty (PPCvcmp_rec Ty:$vA, Ty:$vB, xo)))]> {
+ [(set Ty:$vD, (Ty (PPCvcmp_rec Ty:$vA, Ty:$vB, xo)))]> {
let Defs = [CR6];
let RC = 1;
}
// f32 element comparisons.0
def VCMPBFP : VCMP <966, "vcmpbfp $vD, $vA, $vB" , v4f32>;
-def VCMPBFP_rec : VCMP_rec<966, "vcmpbfp. $vD, $vA, $vB" , v4f32>;
+def VCMPBFP_rec : VCMP_rec<966, "vcmpbfp. $vD, $vA, $vB" , v4f32>;
def VCMPEQFP : VCMP <198, "vcmpeqfp $vD, $vA, $vB" , v4f32>;
-def VCMPEQFP_rec : VCMP_rec<198, "vcmpeqfp. $vD, $vA, $vB", v4f32>;
+def VCMPEQFP_rec : VCMP_rec<198, "vcmpeqfp. $vD, $vA, $vB", v4f32>;
def VCMPGEFP : VCMP <454, "vcmpgefp $vD, $vA, $vB" , v4f32>;
-def VCMPGEFP_rec : VCMP_rec<454, "vcmpgefp. $vD, $vA, $vB", v4f32>;
+def VCMPGEFP_rec : VCMP_rec<454, "vcmpgefp. $vD, $vA, $vB", v4f32>;
def VCMPGTFP : VCMP <710, "vcmpgtfp $vD, $vA, $vB" , v4f32>;
-def VCMPGTFP_rec : VCMP_rec<710, "vcmpgtfp. $vD, $vA, $vB", v4f32>;
+def VCMPGTFP_rec : VCMP_rec<710, "vcmpgtfp. $vD, $vA, $vB", v4f32>;
// i8 element comparisons.
def VCMPEQUB : VCMP < 6, "vcmpequb $vD, $vA, $vB" , v16i8>;
-def VCMPEQUB_rec : VCMP_rec< 6, "vcmpequb. $vD, $vA, $vB", v16i8>;
+def VCMPEQUB_rec : VCMP_rec< 6, "vcmpequb. $vD, $vA, $vB", v16i8>;
def VCMPGTSB : VCMP <774, "vcmpgtsb $vD, $vA, $vB" , v16i8>;
-def VCMPGTSB_rec : VCMP_rec<774, "vcmpgtsb. $vD, $vA, $vB", v16i8>;
+def VCMPGTSB_rec : VCMP_rec<774, "vcmpgtsb. $vD, $vA, $vB", v16i8>;
def VCMPGTUB : VCMP <518, "vcmpgtub $vD, $vA, $vB" , v16i8>;
-def VCMPGTUB_rec : VCMP_rec<518, "vcmpgtub. $vD, $vA, $vB", v16i8>;
+def VCMPGTUB_rec : VCMP_rec<518, "vcmpgtub. $vD, $vA, $vB", v16i8>;
// i16 element comparisons.
def VCMPEQUH : VCMP < 70, "vcmpequh $vD, $vA, $vB" , v8i16>;
-def VCMPEQUH_rec : VCMP_rec< 70, "vcmpequh. $vD, $vA, $vB", v8i16>;
+def VCMPEQUH_rec : VCMP_rec< 70, "vcmpequh. $vD, $vA, $vB", v8i16>;
def VCMPGTSH : VCMP <838, "vcmpgtsh $vD, $vA, $vB" , v8i16>;
-def VCMPGTSH_rec : VCMP_rec<838, "vcmpgtsh. $vD, $vA, $vB", v8i16>;
+def VCMPGTSH_rec : VCMP_rec<838, "vcmpgtsh. $vD, $vA, $vB", v8i16>;
def VCMPGTUH : VCMP <582, "vcmpgtuh $vD, $vA, $vB" , v8i16>;
-def VCMPGTUH_rec : VCMP_rec<582, "vcmpgtuh. $vD, $vA, $vB", v8i16>;
+def VCMPGTUH_rec : VCMP_rec<582, "vcmpgtuh. $vD, $vA, $vB", v8i16>;
// i32 element comparisons.
def VCMPEQUW : VCMP <134, "vcmpequw $vD, $vA, $vB" , v4i32>;
-def VCMPEQUW_rec : VCMP_rec<134, "vcmpequw. $vD, $vA, $vB", v4i32>;
+def VCMPEQUW_rec : VCMP_rec<134, "vcmpequw. $vD, $vA, $vB", v4i32>;
def VCMPGTSW : VCMP <902, "vcmpgtsw $vD, $vA, $vB" , v4i32>;
-def VCMPGTSW_rec : VCMP_rec<902, "vcmpgtsw. $vD, $vA, $vB", v4i32>;
+def VCMPGTSW_rec : VCMP_rec<902, "vcmpgtsw. $vD, $vA, $vB", v4i32>;
def VCMPGTUW : VCMP <646, "vcmpgtuw $vD, $vA, $vB" , v4i32>;
-def VCMPGTUW_rec : VCMP_rec<646, "vcmpgtuw. $vD, $vA, $vB", v4i32>;
+def VCMPGTUW_rec : VCMP_rec<646, "vcmpgtuw. $vD, $vA, $vB", v4i32>;
let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1,
isReMaterializable = 1 in {
@@ -942,18 +942,18 @@ def : Pat<(v1i128 (bitconvert (v4i32 VRRC:$src))), (v1i128 VRRC:$src)>;
def : Pat<(v1i128 (bitconvert (v4f32 VRRC:$src))), (v1i128 VRRC:$src)>;
def : Pat<(v1i128 (bitconvert (v2i64 VRRC:$src))), (v1i128 VRRC:$src)>;
-def : Pat<(f128 (bitconvert (v16i8 VRRC:$src))), (f128 VRRC:$src)>;
-def : Pat<(f128 (bitconvert (v8i16 VRRC:$src))), (f128 VRRC:$src)>;
-def : Pat<(f128 (bitconvert (v4i32 VRRC:$src))), (f128 VRRC:$src)>;
-def : Pat<(f128 (bitconvert (v4f32 VRRC:$src))), (f128 VRRC:$src)>;
-def : Pat<(f128 (bitconvert (v2f64 VRRC:$src))), (f128 VRRC:$src)>;
-
-def : Pat<(v16i8 (bitconvert (f128 VRRC:$src))), (v16i8 VRRC:$src)>;
-def : Pat<(v8i16 (bitconvert (f128 VRRC:$src))), (v8i16 VRRC:$src)>;
-def : Pat<(v4i32 (bitconvert (f128 VRRC:$src))), (v4i32 VRRC:$src)>;
-def : Pat<(v4f32 (bitconvert (f128 VRRC:$src))), (v4f32 VRRC:$src)>;
-def : Pat<(v2f64 (bitconvert (f128 VRRC:$src))), (v2f64 VRRC:$src)>;
-
+def : Pat<(f128 (bitconvert (v16i8 VRRC:$src))), (f128 VRRC:$src)>;
+def : Pat<(f128 (bitconvert (v8i16 VRRC:$src))), (f128 VRRC:$src)>;
+def : Pat<(f128 (bitconvert (v4i32 VRRC:$src))), (f128 VRRC:$src)>;
+def : Pat<(f128 (bitconvert (v4f32 VRRC:$src))), (f128 VRRC:$src)>;
+def : Pat<(f128 (bitconvert (v2f64 VRRC:$src))), (f128 VRRC:$src)>;
+
+def : Pat<(v16i8 (bitconvert (f128 VRRC:$src))), (v16i8 VRRC:$src)>;
+def : Pat<(v8i16 (bitconvert (f128 VRRC:$src))), (v8i16 VRRC:$src)>;
+def : Pat<(v4i32 (bitconvert (f128 VRRC:$src))), (v4i32 VRRC:$src)>;
+def : Pat<(v4f32 (bitconvert (f128 VRRC:$src))), (v4f32 VRRC:$src)>;
+def : Pat<(v2f64 (bitconvert (f128 VRRC:$src))), (v2f64 VRRC:$src)>;
+
// Max/Min
def : Pat<(v16i8 (umax v16i8:$src1, v16i8:$src2)),
(v16i8 (VMAXUB $src1, $src2))>;
@@ -1312,11 +1312,11 @@ def VORC : VXForm_1<1348, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
// i64 element comparisons.
def VCMPEQUD : VCMP <199, "vcmpequd $vD, $vA, $vB" , v2i64>;
-def VCMPEQUD_rec : VCMP_rec<199, "vcmpequd. $vD, $vA, $vB", v2i64>;
+def VCMPEQUD_rec : VCMP_rec<199, "vcmpequd. $vD, $vA, $vB", v2i64>;
def VCMPGTSD : VCMP <967, "vcmpgtsd $vD, $vA, $vB" , v2i64>;
-def VCMPGTSD_rec : VCMP_rec<967, "vcmpgtsd. $vD, $vA, $vB", v2i64>;
+def VCMPGTSD_rec : VCMP_rec<967, "vcmpgtsd. $vD, $vA, $vB", v2i64>;
def VCMPGTUD : VCMP <711, "vcmpgtud $vD, $vA, $vB" , v2i64>;
-def VCMPGTUD_rec : VCMP_rec<711, "vcmpgtud. $vD, $vA, $vB", v2i64>;
+def VCMPGTUD_rec : VCMP_rec<711, "vcmpgtud. $vD, $vA, $vB", v2i64>;
// The cryptography instructions that do not require Category:Vector.Crypto
def VPMSUMB : VX1_Int_Ty<1032, "vpmsumb",
@@ -1327,18 +1327,18 @@ def VPMSUMW : VX1_Int_Ty<1160, "vpmsumw",
int_ppc_altivec_crypto_vpmsumw, v4i32>;
def VPMSUMD : VX1_Int_Ty<1224, "vpmsumd",
int_ppc_altivec_crypto_vpmsumd, v2i64>;
-def VPERMXOR : VAForm_1<45, (outs vrrc:$VD), (ins vrrc:$VA, vrrc:$VB, vrrc:$VC),
- "vpermxor $VD, $VA, $VB, $VC", IIC_VecFP, []>;
+def VPERMXOR : VAForm_1<45, (outs vrrc:$VD), (ins vrrc:$VA, vrrc:$VB, vrrc:$VC),
+ "vpermxor $VD, $VA, $VB, $VC", IIC_VecFP, []>;
// Vector doubleword integer pack and unpack.
-let hasSideEffects = 1 in {
- def VPKSDSS : VX1_Int_Ty2<1486, "vpksdss", int_ppc_altivec_vpksdss,
- v4i32, v2i64>;
- def VPKSDUS : VX1_Int_Ty2<1358, "vpksdus", int_ppc_altivec_vpksdus,
- v4i32, v2i64>;
- def VPKUDUS : VX1_Int_Ty2<1230, "vpkudus", int_ppc_altivec_vpkudus,
- v4i32, v2i64>;
-}
+let hasSideEffects = 1 in {
+ def VPKSDSS : VX1_Int_Ty2<1486, "vpksdss", int_ppc_altivec_vpksdss,
+ v4i32, v2i64>;
+ def VPKSDUS : VX1_Int_Ty2<1358, "vpksdus", int_ppc_altivec_vpksdus,
+ v4i32, v2i64>;
+ def VPKUDUS : VX1_Int_Ty2<1230, "vpkudus", int_ppc_altivec_vpkudus,
+ v4i32, v2i64>;
+}
def VPKUDUM : VXForm_1<1102, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
"vpkudum $vD, $vA, $vB", IIC_VecFP,
[(set v16i8:$vD,
@@ -1386,21 +1386,21 @@ def VMSUMUDM : VA1a_Int_Ty3<35, "vmsumudm", int_ppc_altivec_vmsumudm,
// i8 element comparisons.
def VCMPNEB : VCMP < 7, "vcmpneb $vD, $vA, $vB" , v16i8>;
-def VCMPNEB_rec : VCMP_rec < 7, "vcmpneb. $vD, $vA, $vB" , v16i8>;
+def VCMPNEB_rec : VCMP_rec < 7, "vcmpneb. $vD, $vA, $vB" , v16i8>;
def VCMPNEZB : VCMP <263, "vcmpnezb $vD, $vA, $vB" , v16i8>;
-def VCMPNEZB_rec : VCMP_rec<263, "vcmpnezb. $vD, $vA, $vB", v16i8>;
+def VCMPNEZB_rec : VCMP_rec<263, "vcmpnezb. $vD, $vA, $vB", v16i8>;
// i16 element comparisons.
def VCMPNEH : VCMP < 71, "vcmpneh $vD, $vA, $vB" , v8i16>;
-def VCMPNEH_rec : VCMP_rec< 71, "vcmpneh. $vD, $vA, $vB" , v8i16>;
+def VCMPNEH_rec : VCMP_rec< 71, "vcmpneh. $vD, $vA, $vB" , v8i16>;
def VCMPNEZH : VCMP <327, "vcmpnezh $vD, $vA, $vB" , v8i16>;
-def VCMPNEZH_rec : VCMP_rec<327, "vcmpnezh. $vD, $vA, $vB", v8i16>;
+def VCMPNEZH_rec : VCMP_rec<327, "vcmpnezh. $vD, $vA, $vB", v8i16>;
// i32 element comparisons.
def VCMPNEW : VCMP <135, "vcmpnew $vD, $vA, $vB" , v4i32>;
-def VCMPNEW_rec : VCMP_rec<135, "vcmpnew. $vD, $vA, $vB" , v4i32>;
+def VCMPNEW_rec : VCMP_rec<135, "vcmpnew. $vD, $vA, $vB" , v4i32>;
def VCMPNEZW : VCMP <391, "vcmpnezw $vD, $vA, $vB" , v4i32>;
-def VCMPNEZW_rec : VCMP_rec<391, "vcmpnezw. $vD, $vA, $vB", v4i32>;
+def VCMPNEZW_rec : VCMP_rec<391, "vcmpnezw. $vD, $vA, $vB", v4i32>;
// VX-Form: [PO VRT / UIM VRB XO].
// We use VXForm_1 to implement it, that is, we use "VRA" (5 bit) to represent
@@ -1472,16 +1472,16 @@ def VCTZD : VX_VT5_EO5_VB5<1538, 31, "vctzd",
[(set v2i64:$vD, (cttz v2i64:$vB))]>;
// Vector Extend Sign
-def VEXTSB2W : VX_VT5_EO5_VB5<1538, 16, "vextsb2w",
- [(set v4i32:$vD, (int_ppc_altivec_vextsb2w v16i8:$vB))]>;
-def VEXTSH2W : VX_VT5_EO5_VB5<1538, 17, "vextsh2w",
- [(set v4i32:$vD, (int_ppc_altivec_vextsh2w v8i16:$vB))]>;
-def VEXTSB2D : VX_VT5_EO5_VB5<1538, 24, "vextsb2d",
- [(set v2i64:$vD, (int_ppc_altivec_vextsb2d v16i8:$vB))]>;
-def VEXTSH2D : VX_VT5_EO5_VB5<1538, 25, "vextsh2d",
- [(set v2i64:$vD, (int_ppc_altivec_vextsh2d v8i16:$vB))]>;
-def VEXTSW2D : VX_VT5_EO5_VB5<1538, 26, "vextsw2d",
- [(set v2i64:$vD, (int_ppc_altivec_vextsw2d v4i32:$vB))]>;
+def VEXTSB2W : VX_VT5_EO5_VB5<1538, 16, "vextsb2w",
+ [(set v4i32:$vD, (int_ppc_altivec_vextsb2w v16i8:$vB))]>;
+def VEXTSH2W : VX_VT5_EO5_VB5<1538, 17, "vextsh2w",
+ [(set v4i32:$vD, (int_ppc_altivec_vextsh2w v8i16:$vB))]>;
+def VEXTSB2D : VX_VT5_EO5_VB5<1538, 24, "vextsb2d",
+ [(set v2i64:$vD, (int_ppc_altivec_vextsb2d v16i8:$vB))]>;
+def VEXTSH2D : VX_VT5_EO5_VB5<1538, 25, "vextsh2d",
+ [(set v2i64:$vD, (int_ppc_altivec_vextsh2d v8i16:$vB))]>;
+def VEXTSW2D : VX_VT5_EO5_VB5<1538, 26, "vextsw2d",
+ [(set v2i64:$vD, (int_ppc_altivec_vextsw2d v4i32:$vB))]>;
let isCodeGenOnly = 1 in {
def VEXTSB2Ws : VX_VT5_EO5_VB5s<1538, 16, "vextsb2w", []>;
def VEXTSH2Ws : VX_VT5_EO5_VB5s<1538, 17, "vextsh2w", []>;
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrFormats.td b/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrFormats.td
index 0acd55b12d..646efe64a2 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrFormats.td
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrFormats.td
@@ -637,10 +637,10 @@ class XForm_17<bits<6> opcode, bits<10> xo, dag OOL, dag IOL, string asmstr,
}
class XForm_17a<bits<6> opcode, bits<10> xo, dag OOL, dag IOL, string asmstr,
- InstrItinClass itin, list<dag> pattern>
+ InstrItinClass itin, list<dag> pattern>
: XForm_17<opcode, xo, OOL, IOL, asmstr, itin > {
let FRA = 0;
- let Pattern = pattern;
+ let Pattern = pattern;
}
class XForm_18<bits<6> opcode, bits<10> xo, dag OOL, dag IOL, string asmstr,
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrHTM.td b/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrHTM.td
index 0504695469..e59a08774d 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrHTM.td
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrHTM.td
@@ -164,8 +164,8 @@ def : Pat<(int_ppc_tsuspend),
(TSR 0)>;
def : Pat<(i64 (int_ppc_ttest)),
- (i64 (INSERT_SUBREG
- (i64 (IMPLICIT_DEF)), (TABORTWCI 0, (LI 0), 0), sub_32))>;
+ (i64 (INSERT_SUBREG
+ (i64 (IMPLICIT_DEF)), (TABORTWCI 0, (LI 0), 0), sub_32))>;
} // [HasHTM]
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrInfo.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrInfo.cpp
index 4b23a63eb0..9e3c6c569b 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -21,15 +21,15 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/LiveIntervals.h"
-#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
-#include "llvm/CodeGen/RegisterClassInfo.h"
-#include "llvm/CodeGen/RegisterPressure.h"
+#include "llvm/CodeGen/RegisterClassInfo.h"
+#include "llvm/CodeGen/RegisterPressure.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/CodeGen/StackMaps.h"
@@ -76,14 +76,14 @@ static cl::opt<bool>
UseOldLatencyCalc("ppc-old-latency-calc", cl::Hidden,
cl::desc("Use the old (incorrect) instruction latency calculation"));
-static cl::opt<float>
- FMARPFactor("ppc-fma-rp-factor", cl::Hidden, cl::init(1.5),
- cl::desc("register pressure factor for the transformations."));
-
-static cl::opt<bool> EnableFMARegPressureReduction(
- "ppc-fma-rp-reduction", cl::Hidden, cl::init(true),
- cl::desc("enable register pressure reduce in machine combiner pass."));
-
+static cl::opt<float>
+ FMARPFactor("ppc-fma-rp-factor", cl::Hidden, cl::init(1.5),
+ cl::desc("register pressure factor for the transformations."));
+
+static cl::opt<bool> EnableFMARegPressureReduction(
+ "ppc-fma-rp-reduction", cl::Hidden, cl::init(true),
+ cl::desc("enable register pressure reduce in machine combiner pass."));
+
// Pin the vtable to this file.
void PPCInstrInfo::anchor() {}
@@ -289,23 +289,23 @@ bool PPCInstrInfo::isAssociativeAndCommutative(const MachineInstr &Inst) const {
#define InfoArrayIdxFMULInst 2
#define InfoArrayIdxAddOpIdx 3
#define InfoArrayIdxMULOpIdx 4
-#define InfoArrayIdxFSubInst 5
+#define InfoArrayIdxFSubInst 5
// Array keeps info for FMA instructions:
// Index 0(InfoArrayIdxFMAInst): FMA instruction;
-// Index 1(InfoArrayIdxFAddInst): ADD instruction associated with FMA;
-// Index 2(InfoArrayIdxFMULInst): MUL instruction associated with FMA;
+// Index 1(InfoArrayIdxFAddInst): ADD instruction associated with FMA;
+// Index 2(InfoArrayIdxFMULInst): MUL instruction associated with FMA;
// Index 3(InfoArrayIdxAddOpIdx): ADD operand index in FMA operands;
// Index 4(InfoArrayIdxMULOpIdx): first MUL operand index in FMA operands;
-// second MUL operand index is plus 1;
-// Index 5(InfoArrayIdxFSubInst): SUB instruction associated with FMA.
-static const uint16_t FMAOpIdxInfo[][6] = {
+// second MUL operand index is plus 1;
+// Index 5(InfoArrayIdxFSubInst): SUB instruction associated with FMA.
+static const uint16_t FMAOpIdxInfo[][6] = {
// FIXME: Add more FMA instructions like XSNMADDADP and so on.
- {PPC::XSMADDADP, PPC::XSADDDP, PPC::XSMULDP, 1, 2, PPC::XSSUBDP},
- {PPC::XSMADDASP, PPC::XSADDSP, PPC::XSMULSP, 1, 2, PPC::XSSUBSP},
- {PPC::XVMADDADP, PPC::XVADDDP, PPC::XVMULDP, 1, 2, PPC::XVSUBDP},
- {PPC::XVMADDASP, PPC::XVADDSP, PPC::XVMULSP, 1, 2, PPC::XVSUBSP},
- {PPC::FMADD, PPC::FADD, PPC::FMUL, 3, 1, PPC::FSUB},
- {PPC::FMADDS, PPC::FADDS, PPC::FMULS, 3, 1, PPC::FSUBS}};
+ {PPC::XSMADDADP, PPC::XSADDDP, PPC::XSMULDP, 1, 2, PPC::XSSUBDP},
+ {PPC::XSMADDASP, PPC::XSADDSP, PPC::XSMULSP, 1, 2, PPC::XSSUBSP},
+ {PPC::XVMADDADP, PPC::XVADDDP, PPC::XVMULDP, 1, 2, PPC::XVSUBDP},
+ {PPC::XVMADDASP, PPC::XVADDSP, PPC::XVMULSP, 1, 2, PPC::XVSUBSP},
+ {PPC::FMADD, PPC::FADD, PPC::FMUL, 3, 1, PPC::FSUB},
+ {PPC::FMADDS, PPC::FADDS, PPC::FMULS, 3, 1, PPC::FSUBS}};
// Check if an opcode is a FMA instruction. If it is, return the index in array
// FMAOpIdxInfo. Otherwise, return -1.
@@ -316,8 +316,8 @@ int16_t PPCInstrInfo::getFMAOpIdxInfo(unsigned Opcode) const {
return -1;
}
-// On PowerPC target, we have two kinds of patterns related to FMA:
-// 1: Improve ILP.
+// On PowerPC target, we have two kinds of patterns related to FMA:
+// 1: Improve ILP.
// Try to reassociate FMA chains like below:
//
// Pattern 1:
@@ -341,35 +341,35 @@ int16_t PPCInstrInfo::getFMAOpIdxInfo(unsigned Opcode) const {
//
// breaking the dependency between A and B, allowing FMA to be executed in
// parallel (or back-to-back in a pipeline) instead of depending on each other.
-//
-// 2: Reduce register pressure.
-// Try to reassociate FMA with FSUB and a constant like below:
-// C is a floatint point const.
-//
-// Pattern 1:
-// A = FSUB X, Y (Leaf)
-// D = FMA B, C, A (Root)
-// -->
-// A = FMA B, Y, -C
-// D = FMA A, X, C
-//
-// Pattern 2:
-// A = FSUB X, Y (Leaf)
-// D = FMA B, A, C (Root)
-// -->
-// A = FMA B, Y, -C
-// D = FMA A, X, C
-//
-// Before the transformation, A must be assigned with different hardware
-// register with D. After the transformation, A and D must be assigned with
-// same hardware register due to TIE attricute of FMA instructions.
-//
+//
+// 2: Reduce register pressure.
+// Try to reassociate FMA with FSUB and a constant like below:
+// C is a floatint point const.
+//
+// Pattern 1:
+// A = FSUB X, Y (Leaf)
+// D = FMA B, C, A (Root)
+// -->
+// A = FMA B, Y, -C
+// D = FMA A, X, C
+//
+// Pattern 2:
+// A = FSUB X, Y (Leaf)
+// D = FMA B, A, C (Root)
+// -->
+// A = FMA B, Y, -C
+// D = FMA A, X, C
+//
+// Before the transformation, A must be assigned with different hardware
+// register with D. After the transformation, A and D must be assigned with
+// same hardware register due to TIE attricute of FMA instructions.
+//
bool PPCInstrInfo::getFMAPatterns(
- MachineInstr &Root, SmallVectorImpl<MachineCombinerPattern> &Patterns,
- bool DoRegPressureReduce) const {
+ MachineInstr &Root, SmallVectorImpl<MachineCombinerPattern> &Patterns,
+ bool DoRegPressureReduce) const {
MachineBasicBlock *MBB = Root.getParent();
- const MachineRegisterInfo *MRI = &MBB->getParent()->getRegInfo();
- const TargetRegisterInfo *TRI = &getRegisterInfo();
+ const MachineRegisterInfo *MRI = &MBB->getParent()->getRegInfo();
+ const TargetRegisterInfo *TRI = &getRegisterInfo();
auto IsAllOpsVirtualReg = [](const MachineInstr &Instr) {
for (const auto &MO : Instr.explicit_operands())
@@ -378,10 +378,35 @@ bool PPCInstrInfo::getFMAPatterns(
return true;
};
- auto IsReassociableAddOrSub = [&](const MachineInstr &Instr,
- unsigned OpType) {
- if (Instr.getOpcode() !=
- FMAOpIdxInfo[getFMAOpIdxInfo(Root.getOpcode())][OpType])
+ auto IsReassociableAddOrSub = [&](const MachineInstr &Instr,
+ unsigned OpType) {
+ if (Instr.getOpcode() !=
+ FMAOpIdxInfo[getFMAOpIdxInfo(Root.getOpcode())][OpType])
+ return false;
+
+ // Instruction can be reassociated.
+ // fast math flags may prohibit reassociation.
+ if (!(Instr.getFlag(MachineInstr::MIFlag::FmReassoc) &&
+ Instr.getFlag(MachineInstr::MIFlag::FmNsz)))
+ return false;
+
+ // Instruction operands are virtual registers for reassociation.
+ if (!IsAllOpsVirtualReg(Instr))
+ return false;
+
+ // For register pressure reassociation, the FSub must have only one use as
+ // we want to delete the sub to save its def.
+ if (OpType == InfoArrayIdxFSubInst &&
+ !MRI->hasOneNonDBGUse(Instr.getOperand(0).getReg()))
+ return false;
+
+ return true;
+ };
+
+ auto IsReassociableFMA = [&](const MachineInstr &Instr, int16_t &AddOpIdx,
+ int16_t &MulOpIdx, bool IsLeaf) {
+ int16_t Idx = getFMAOpIdxInfo(Instr.getOpcode());
+ if (Idx < 0)
return false;
// Instruction can be reassociated.
@@ -394,381 +419,356 @@ bool PPCInstrInfo::getFMAPatterns(
if (!IsAllOpsVirtualReg(Instr))
return false;
- // For register pressure reassociation, the FSub must have only one use as
- // we want to delete the sub to save its def.
- if (OpType == InfoArrayIdxFSubInst &&
- !MRI->hasOneNonDBGUse(Instr.getOperand(0).getReg()))
- return false;
-
- return true;
- };
-
- auto IsReassociableFMA = [&](const MachineInstr &Instr, int16_t &AddOpIdx,
- int16_t &MulOpIdx, bool IsLeaf) {
- int16_t Idx = getFMAOpIdxInfo(Instr.getOpcode());
- if (Idx < 0)
- return false;
-
- // Instruction can be reassociated.
- // fast math flags may prohibit reassociation.
- if (!(Instr.getFlag(MachineInstr::MIFlag::FmReassoc) &&
- Instr.getFlag(MachineInstr::MIFlag::FmNsz)))
- return false;
-
- // Instruction operands are virtual registers for reassociation.
- if (!IsAllOpsVirtualReg(Instr))
- return false;
-
- MulOpIdx = FMAOpIdxInfo[Idx][InfoArrayIdxMULOpIdx];
- if (IsLeaf)
+ MulOpIdx = FMAOpIdxInfo[Idx][InfoArrayIdxMULOpIdx];
+ if (IsLeaf)
return true;
AddOpIdx = FMAOpIdxInfo[Idx][InfoArrayIdxAddOpIdx];
const MachineOperand &OpAdd = Instr.getOperand(AddOpIdx);
- MachineInstr *MIAdd = MRI->getUniqueVRegDef(OpAdd.getReg());
+ MachineInstr *MIAdd = MRI->getUniqueVRegDef(OpAdd.getReg());
// If 'add' operand's def is not in current block, don't do ILP related opt.
if (!MIAdd || MIAdd->getParent() != MBB)
return false;
// If this is not Leaf FMA Instr, its 'add' operand should only have one use
// as this fma will be changed later.
- return IsLeaf ? true : MRI->hasOneNonDBGUse(OpAdd.getReg());
+ return IsLeaf ? true : MRI->hasOneNonDBGUse(OpAdd.getReg());
};
int16_t AddOpIdx = -1;
- int16_t MulOpIdx = -1;
-
- bool IsUsedOnceL = false;
- bool IsUsedOnceR = false;
- MachineInstr *MULInstrL = nullptr;
- MachineInstr *MULInstrR = nullptr;
-
- auto IsRPReductionCandidate = [&]() {
- // Currently, we only support float and double.
- // FIXME: add support for other types.
- unsigned Opcode = Root.getOpcode();
- if (Opcode != PPC::XSMADDASP && Opcode != PPC::XSMADDADP)
- return false;
-
- // Root must be a valid FMA like instruction.
- // Treat it as leaf as we don't care its add operand.
- if (IsReassociableFMA(Root, AddOpIdx, MulOpIdx, true)) {
- assert((MulOpIdx >= 0) && "mul operand index not right!");
- Register MULRegL = TRI->lookThruSingleUseCopyChain(
- Root.getOperand(MulOpIdx).getReg(), MRI);
- Register MULRegR = TRI->lookThruSingleUseCopyChain(
- Root.getOperand(MulOpIdx + 1).getReg(), MRI);
- if (!MULRegL && !MULRegR)
- return false;
-
- if (MULRegL && !MULRegR) {
- MULRegR =
- TRI->lookThruCopyLike(Root.getOperand(MulOpIdx + 1).getReg(), MRI);
- IsUsedOnceL = true;
- } else if (!MULRegL && MULRegR) {
- MULRegL =
- TRI->lookThruCopyLike(Root.getOperand(MulOpIdx).getReg(), MRI);
- IsUsedOnceR = true;
- } else {
- IsUsedOnceL = true;
- IsUsedOnceR = true;
- }
-
- if (!Register::isVirtualRegister(MULRegL) ||
- !Register::isVirtualRegister(MULRegR))
- return false;
-
- MULInstrL = MRI->getVRegDef(MULRegL);
- MULInstrR = MRI->getVRegDef(MULRegR);
- return true;
- }
- return false;
- };
-
- // Register pressure fma reassociation patterns.
- if (DoRegPressureReduce && IsRPReductionCandidate()) {
- assert((MULInstrL && MULInstrR) && "wrong register preduction candidate!");
- // Register pressure pattern 1
- if (isLoadFromConstantPool(MULInstrL) && IsUsedOnceR &&
- IsReassociableAddOrSub(*MULInstrR, InfoArrayIdxFSubInst)) {
- LLVM_DEBUG(dbgs() << "add pattern REASSOC_XY_BCA\n");
- Patterns.push_back(MachineCombinerPattern::REASSOC_XY_BCA);
- return true;
- }
-
- // Register pressure pattern 2
- if ((isLoadFromConstantPool(MULInstrR) && IsUsedOnceL &&
- IsReassociableAddOrSub(*MULInstrL, InfoArrayIdxFSubInst))) {
- LLVM_DEBUG(dbgs() << "add pattern REASSOC_XY_BAC\n");
- Patterns.push_back(MachineCombinerPattern::REASSOC_XY_BAC);
- return true;
- }
- }
-
- // ILP fma reassociation patterns.
+ int16_t MulOpIdx = -1;
+
+ bool IsUsedOnceL = false;
+ bool IsUsedOnceR = false;
+ MachineInstr *MULInstrL = nullptr;
+ MachineInstr *MULInstrR = nullptr;
+
+ auto IsRPReductionCandidate = [&]() {
+ // Currently, we only support float and double.
+ // FIXME: add support for other types.
+ unsigned Opcode = Root.getOpcode();
+ if (Opcode != PPC::XSMADDASP && Opcode != PPC::XSMADDADP)
+ return false;
+
+ // Root must be a valid FMA like instruction.
+ // Treat it as leaf as we don't care its add operand.
+ if (IsReassociableFMA(Root, AddOpIdx, MulOpIdx, true)) {
+ assert((MulOpIdx >= 0) && "mul operand index not right!");
+ Register MULRegL = TRI->lookThruSingleUseCopyChain(
+ Root.getOperand(MulOpIdx).getReg(), MRI);
+ Register MULRegR = TRI->lookThruSingleUseCopyChain(
+ Root.getOperand(MulOpIdx + 1).getReg(), MRI);
+ if (!MULRegL && !MULRegR)
+ return false;
+
+ if (MULRegL && !MULRegR) {
+ MULRegR =
+ TRI->lookThruCopyLike(Root.getOperand(MulOpIdx + 1).getReg(), MRI);
+ IsUsedOnceL = true;
+ } else if (!MULRegL && MULRegR) {
+ MULRegL =
+ TRI->lookThruCopyLike(Root.getOperand(MulOpIdx).getReg(), MRI);
+ IsUsedOnceR = true;
+ } else {
+ IsUsedOnceL = true;
+ IsUsedOnceR = true;
+ }
+
+ if (!Register::isVirtualRegister(MULRegL) ||
+ !Register::isVirtualRegister(MULRegR))
+ return false;
+
+ MULInstrL = MRI->getVRegDef(MULRegL);
+ MULInstrR = MRI->getVRegDef(MULRegR);
+ return true;
+ }
+ return false;
+ };
+
+ // Register pressure fma reassociation patterns.
+ if (DoRegPressureReduce && IsRPReductionCandidate()) {
+ assert((MULInstrL && MULInstrR) && "wrong register preduction candidate!");
+ // Register pressure pattern 1
+ if (isLoadFromConstantPool(MULInstrL) && IsUsedOnceR &&
+ IsReassociableAddOrSub(*MULInstrR, InfoArrayIdxFSubInst)) {
+ LLVM_DEBUG(dbgs() << "add pattern REASSOC_XY_BCA\n");
+ Patterns.push_back(MachineCombinerPattern::REASSOC_XY_BCA);
+ return true;
+ }
+
+ // Register pressure pattern 2
+ if ((isLoadFromConstantPool(MULInstrR) && IsUsedOnceL &&
+ IsReassociableAddOrSub(*MULInstrL, InfoArrayIdxFSubInst))) {
+ LLVM_DEBUG(dbgs() << "add pattern REASSOC_XY_BAC\n");
+ Patterns.push_back(MachineCombinerPattern::REASSOC_XY_BAC);
+ return true;
+ }
+ }
+
+ // ILP fma reassociation patterns.
// Root must be a valid FMA like instruction.
- AddOpIdx = -1;
- if (!IsReassociableFMA(Root, AddOpIdx, MulOpIdx, false))
+ AddOpIdx = -1;
+ if (!IsReassociableFMA(Root, AddOpIdx, MulOpIdx, false))
return false;
assert((AddOpIdx >= 0) && "add operand index not right!");
Register RegB = Root.getOperand(AddOpIdx).getReg();
- MachineInstr *Prev = MRI->getUniqueVRegDef(RegB);
+ MachineInstr *Prev = MRI->getUniqueVRegDef(RegB);
// Prev must be a valid FMA like instruction.
AddOpIdx = -1;
- if (!IsReassociableFMA(*Prev, AddOpIdx, MulOpIdx, false))
+ if (!IsReassociableFMA(*Prev, AddOpIdx, MulOpIdx, false))
return false;
assert((AddOpIdx >= 0) && "add operand index not right!");
Register RegA = Prev->getOperand(AddOpIdx).getReg();
- MachineInstr *Leaf = MRI->getUniqueVRegDef(RegA);
+ MachineInstr *Leaf = MRI->getUniqueVRegDef(RegA);
AddOpIdx = -1;
- if (IsReassociableFMA(*Leaf, AddOpIdx, MulOpIdx, true)) {
+ if (IsReassociableFMA(*Leaf, AddOpIdx, MulOpIdx, true)) {
Patterns.push_back(MachineCombinerPattern::REASSOC_XMM_AMM_BMM);
- LLVM_DEBUG(dbgs() << "add pattern REASSOC_XMM_AMM_BMM\n");
+ LLVM_DEBUG(dbgs() << "add pattern REASSOC_XMM_AMM_BMM\n");
return true;
}
- if (IsReassociableAddOrSub(*Leaf, InfoArrayIdxFAddInst)) {
+ if (IsReassociableAddOrSub(*Leaf, InfoArrayIdxFAddInst)) {
Patterns.push_back(MachineCombinerPattern::REASSOC_XY_AMM_BMM);
- LLVM_DEBUG(dbgs() << "add pattern REASSOC_XY_AMM_BMM\n");
+ LLVM_DEBUG(dbgs() << "add pattern REASSOC_XY_AMM_BMM\n");
return true;
}
return false;
}
-void PPCInstrInfo::finalizeInsInstrs(
- MachineInstr &Root, MachineCombinerPattern &P,
- SmallVectorImpl<MachineInstr *> &InsInstrs) const {
- assert(!InsInstrs.empty() && "Instructions set to be inserted is empty!");
-
- MachineFunction *MF = Root.getMF();
- MachineRegisterInfo *MRI = &MF->getRegInfo();
- const TargetRegisterInfo *TRI = &getRegisterInfo();
- MachineConstantPool *MCP = MF->getConstantPool();
-
- int16_t Idx = getFMAOpIdxInfo(Root.getOpcode());
- if (Idx < 0)
- return;
-
- uint16_t FirstMulOpIdx = FMAOpIdxInfo[Idx][InfoArrayIdxMULOpIdx];
-
- // For now we only need to fix up placeholder for register pressure reduce
- // patterns.
- Register ConstReg = 0;
- switch (P) {
- case MachineCombinerPattern::REASSOC_XY_BCA:
- ConstReg =
- TRI->lookThruCopyLike(Root.getOperand(FirstMulOpIdx).getReg(), MRI);
- break;
- case MachineCombinerPattern::REASSOC_XY_BAC:
- ConstReg =
- TRI->lookThruCopyLike(Root.getOperand(FirstMulOpIdx + 1).getReg(), MRI);
- break;
- default:
- // Not register pressure reduce patterns.
- return;
- }
-
- MachineInstr *ConstDefInstr = MRI->getVRegDef(ConstReg);
- // Get const value from const pool.
- const Constant *C = getConstantFromConstantPool(ConstDefInstr);
- assert(isa<llvm::ConstantFP>(C) && "not a valid constant!");
-
- // Get negative fp const.
- APFloat F1((dyn_cast<ConstantFP>(C))->getValueAPF());
- F1.changeSign();
- Constant *NegC = ConstantFP::get(dyn_cast<ConstantFP>(C)->getContext(), F1);
- Align Alignment = MF->getDataLayout().getPrefTypeAlign(C->getType());
-
- // Put negative fp const into constant pool.
- unsigned ConstPoolIdx = MCP->getConstantPoolIndex(NegC, Alignment);
-
- MachineOperand *Placeholder = nullptr;
- // Record the placeholder PPC::ZERO8 we add in reassociateFMA.
- for (auto *Inst : InsInstrs) {
- for (MachineOperand &Operand : Inst->explicit_operands()) {
- assert(Operand.isReg() && "Invalid instruction in InsInstrs!");
- if (Operand.getReg() == PPC::ZERO8) {
- Placeholder = &Operand;
- break;
- }
- }
- }
-
- assert(Placeholder && "Placeholder does not exist!");
-
- // Generate instructions to load the const fp from constant pool.
- // We only support PPC64 and medium code model.
- Register LoadNewConst =
- generateLoadForNewConst(ConstPoolIdx, &Root, C->getType(), InsInstrs);
-
- // Fill the placeholder with the new load from constant pool.
- Placeholder->setReg(LoadNewConst);
-}
-
-bool PPCInstrInfo::shouldReduceRegisterPressure(
- MachineBasicBlock *MBB, RegisterClassInfo *RegClassInfo) const {
-
- if (!EnableFMARegPressureReduction)
- return false;
-
- // Currently, we only enable register pressure reducing in machine combiner
- // for: 1: PPC64; 2: Code Model is Medium; 3: Power9 which also has vector
- // support.
- //
- // So we need following instructions to access a TOC entry:
- //
- // %6:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, %const.0
- // %7:vssrc = DFLOADf32 target-flags(ppc-toc-lo) %const.0,
- // killed %6:g8rc_and_g8rc_nox0, implicit $x2 :: (load 4 from constant-pool)
- //
- // FIXME: add more supported targets, like Small and Large code model, PPC32,
- // AIX.
- if (!(Subtarget.isPPC64() && Subtarget.hasP9Vector() &&
- Subtarget.getTargetMachine().getCodeModel() == CodeModel::Medium))
- return false;
-
- const TargetRegisterInfo *TRI = &getRegisterInfo();
- MachineFunction *MF = MBB->getParent();
- MachineRegisterInfo *MRI = &MF->getRegInfo();
-
- auto GetMBBPressure = [&](MachineBasicBlock *MBB) -> std::vector<unsigned> {
- RegionPressure Pressure;
- RegPressureTracker RPTracker(Pressure);
-
- // Initialize the register pressure tracker.
- RPTracker.init(MBB->getParent(), RegClassInfo, nullptr, MBB, MBB->end(),
- /*TrackLaneMasks*/ false, /*TrackUntiedDefs=*/true);
-
- for (MachineBasicBlock::iterator MII = MBB->instr_end(),
- MIE = MBB->instr_begin();
- MII != MIE; --MII) {
- MachineInstr &MI = *std::prev(MII);
- if (MI.isDebugValue() || MI.isDebugLabel())
- continue;
- RegisterOperands RegOpers;
- RegOpers.collect(MI, *TRI, *MRI, false, false);
- RPTracker.recedeSkipDebugValues();
- assert(&*RPTracker.getPos() == &MI && "RPTracker sync error!");
- RPTracker.recede(RegOpers);
- }
-
- // Close the RPTracker to finalize live ins.
- RPTracker.closeRegion();
-
- return RPTracker.getPressure().MaxSetPressure;
- };
-
- // For now we only care about float and double type fma.
- unsigned VSSRCLimit = TRI->getRegPressureSetLimit(
- *MBB->getParent(), PPC::RegisterPressureSets::VSSRC);
-
- // Only reduce register pressure when pressure is high.
- return GetMBBPressure(MBB)[PPC::RegisterPressureSets::VSSRC] >
- (float)VSSRCLimit * FMARPFactor;
-}
-
-bool PPCInstrInfo::isLoadFromConstantPool(MachineInstr *I) const {
- // I has only one memory operand which is load from constant pool.
- if (!I->hasOneMemOperand())
- return false;
-
- MachineMemOperand *Op = I->memoperands()[0];
- return Op->isLoad() && Op->getPseudoValue() &&
- Op->getPseudoValue()->kind() == PseudoSourceValue::ConstantPool;
-}
-
-Register PPCInstrInfo::generateLoadForNewConst(
- unsigned Idx, MachineInstr *MI, Type *Ty,
- SmallVectorImpl<MachineInstr *> &InsInstrs) const {
- // Now we only support PPC64, Medium code model and P9 with vector.
- // We have immutable pattern to access const pool. See function
- // shouldReduceRegisterPressure.
- assert((Subtarget.isPPC64() && Subtarget.hasP9Vector() &&
- Subtarget.getTargetMachine().getCodeModel() == CodeModel::Medium) &&
- "Target not supported!\n");
-
- MachineFunction *MF = MI->getMF();
- MachineRegisterInfo *MRI = &MF->getRegInfo();
-
- // Generate ADDIStocHA8
- Register VReg1 = MRI->createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
- MachineInstrBuilder TOCOffset =
- BuildMI(*MF, MI->getDebugLoc(), get(PPC::ADDIStocHA8), VReg1)
- .addReg(PPC::X2)
- .addConstantPoolIndex(Idx);
-
- assert((Ty->isFloatTy() || Ty->isDoubleTy()) &&
- "Only float and double are supported!");
-
- unsigned LoadOpcode;
- // Should be float type or double type.
- if (Ty->isFloatTy())
- LoadOpcode = PPC::DFLOADf32;
- else
- LoadOpcode = PPC::DFLOADf64;
-
- const TargetRegisterClass *RC = MRI->getRegClass(MI->getOperand(0).getReg());
- Register VReg2 = MRI->createVirtualRegister(RC);
- MachineMemOperand *MMO = MF->getMachineMemOperand(
- MachinePointerInfo::getConstantPool(*MF), MachineMemOperand::MOLoad,
- Ty->getScalarSizeInBits() / 8, MF->getDataLayout().getPrefTypeAlign(Ty));
-
- // Generate Load from constant pool.
- MachineInstrBuilder Load =
- BuildMI(*MF, MI->getDebugLoc(), get(LoadOpcode), VReg2)
- .addConstantPoolIndex(Idx)
- .addReg(VReg1, getKillRegState(true))
- .addMemOperand(MMO);
-
- Load->getOperand(1).setTargetFlags(PPCII::MO_TOC_LO);
-
- // Insert the toc load instructions into InsInstrs.
- InsInstrs.insert(InsInstrs.begin(), Load);
- InsInstrs.insert(InsInstrs.begin(), TOCOffset);
- return VReg2;
-}
-
-// This function returns the const value in constant pool if the \p I is a load
-// from constant pool.
-const Constant *
-PPCInstrInfo::getConstantFromConstantPool(MachineInstr *I) const {
- MachineFunction *MF = I->getMF();
- MachineRegisterInfo *MRI = &MF->getRegInfo();
- MachineConstantPool *MCP = MF->getConstantPool();
- assert(I->mayLoad() && "Should be a load instruction.\n");
- for (auto MO : I->uses()) {
- if (!MO.isReg())
- continue;
- Register Reg = MO.getReg();
- if (Reg == 0 || !Register::isVirtualRegister(Reg))
- continue;
- // Find the toc address.
- MachineInstr *DefMI = MRI->getVRegDef(Reg);
- for (auto MO2 : DefMI->uses())
- if (MO2.isCPI())
- return (MCP->getConstants())[MO2.getIndex()].Val.ConstVal;
- }
- return nullptr;
-}
-
+void PPCInstrInfo::finalizeInsInstrs(
+ MachineInstr &Root, MachineCombinerPattern &P,
+ SmallVectorImpl<MachineInstr *> &InsInstrs) const {
+ assert(!InsInstrs.empty() && "Instructions set to be inserted is empty!");
+
+ MachineFunction *MF = Root.getMF();
+ MachineRegisterInfo *MRI = &MF->getRegInfo();
+ const TargetRegisterInfo *TRI = &getRegisterInfo();
+ MachineConstantPool *MCP = MF->getConstantPool();
+
+ int16_t Idx = getFMAOpIdxInfo(Root.getOpcode());
+ if (Idx < 0)
+ return;
+
+ uint16_t FirstMulOpIdx = FMAOpIdxInfo[Idx][InfoArrayIdxMULOpIdx];
+
+ // For now we only need to fix up placeholder for register pressure reduce
+ // patterns.
+ Register ConstReg = 0;
+ switch (P) {
+ case MachineCombinerPattern::REASSOC_XY_BCA:
+ ConstReg =
+ TRI->lookThruCopyLike(Root.getOperand(FirstMulOpIdx).getReg(), MRI);
+ break;
+ case MachineCombinerPattern::REASSOC_XY_BAC:
+ ConstReg =
+ TRI->lookThruCopyLike(Root.getOperand(FirstMulOpIdx + 1).getReg(), MRI);
+ break;
+ default:
+ // Not register pressure reduce patterns.
+ return;
+ }
+
+ MachineInstr *ConstDefInstr = MRI->getVRegDef(ConstReg);
+ // Get const value from const pool.
+ const Constant *C = getConstantFromConstantPool(ConstDefInstr);
+ assert(isa<llvm::ConstantFP>(C) && "not a valid constant!");
+
+ // Get negative fp const.
+ APFloat F1((dyn_cast<ConstantFP>(C))->getValueAPF());
+ F1.changeSign();
+ Constant *NegC = ConstantFP::get(dyn_cast<ConstantFP>(C)->getContext(), F1);
+ Align Alignment = MF->getDataLayout().getPrefTypeAlign(C->getType());
+
+ // Put negative fp const into constant pool.
+ unsigned ConstPoolIdx = MCP->getConstantPoolIndex(NegC, Alignment);
+
+ MachineOperand *Placeholder = nullptr;
+ // Record the placeholder PPC::ZERO8 we add in reassociateFMA.
+ for (auto *Inst : InsInstrs) {
+ for (MachineOperand &Operand : Inst->explicit_operands()) {
+ assert(Operand.isReg() && "Invalid instruction in InsInstrs!");
+ if (Operand.getReg() == PPC::ZERO8) {
+ Placeholder = &Operand;
+ break;
+ }
+ }
+ }
+
+ assert(Placeholder && "Placeholder does not exist!");
+
+ // Generate instructions to load the const fp from constant pool.
+ // We only support PPC64 and medium code model.
+ Register LoadNewConst =
+ generateLoadForNewConst(ConstPoolIdx, &Root, C->getType(), InsInstrs);
+
+ // Fill the placeholder with the new load from constant pool.
+ Placeholder->setReg(LoadNewConst);
+}
+
+bool PPCInstrInfo::shouldReduceRegisterPressure(
+ MachineBasicBlock *MBB, RegisterClassInfo *RegClassInfo) const {
+
+ if (!EnableFMARegPressureReduction)
+ return false;
+
+ // Currently, we only enable register pressure reducing in machine combiner
+ // for: 1: PPC64; 2: Code Model is Medium; 3: Power9 which also has vector
+ // support.
+ //
+ // So we need following instructions to access a TOC entry:
+ //
+ // %6:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, %const.0
+ // %7:vssrc = DFLOADf32 target-flags(ppc-toc-lo) %const.0,
+ // killed %6:g8rc_and_g8rc_nox0, implicit $x2 :: (load 4 from constant-pool)
+ //
+ // FIXME: add more supported targets, like Small and Large code model, PPC32,
+ // AIX.
+ if (!(Subtarget.isPPC64() && Subtarget.hasP9Vector() &&
+ Subtarget.getTargetMachine().getCodeModel() == CodeModel::Medium))
+ return false;
+
+ const TargetRegisterInfo *TRI = &getRegisterInfo();
+ MachineFunction *MF = MBB->getParent();
+ MachineRegisterInfo *MRI = &MF->getRegInfo();
+
+ auto GetMBBPressure = [&](MachineBasicBlock *MBB) -> std::vector<unsigned> {
+ RegionPressure Pressure;
+ RegPressureTracker RPTracker(Pressure);
+
+ // Initialize the register pressure tracker.
+ RPTracker.init(MBB->getParent(), RegClassInfo, nullptr, MBB, MBB->end(),
+ /*TrackLaneMasks*/ false, /*TrackUntiedDefs=*/true);
+
+ for (MachineBasicBlock::iterator MII = MBB->instr_end(),
+ MIE = MBB->instr_begin();
+ MII != MIE; --MII) {
+ MachineInstr &MI = *std::prev(MII);
+ if (MI.isDebugValue() || MI.isDebugLabel())
+ continue;
+ RegisterOperands RegOpers;
+ RegOpers.collect(MI, *TRI, *MRI, false, false);
+ RPTracker.recedeSkipDebugValues();
+ assert(&*RPTracker.getPos() == &MI && "RPTracker sync error!");
+ RPTracker.recede(RegOpers);
+ }
+
+ // Close the RPTracker to finalize live ins.
+ RPTracker.closeRegion();
+
+ return RPTracker.getPressure().MaxSetPressure;
+ };
+
+ // For now we only care about float and double type fma.
+ unsigned VSSRCLimit = TRI->getRegPressureSetLimit(
+ *MBB->getParent(), PPC::RegisterPressureSets::VSSRC);
+
+ // Only reduce register pressure when pressure is high.
+ return GetMBBPressure(MBB)[PPC::RegisterPressureSets::VSSRC] >
+ (float)VSSRCLimit * FMARPFactor;
+}
+
+bool PPCInstrInfo::isLoadFromConstantPool(MachineInstr *I) const {
+ // I has only one memory operand which is load from constant pool.
+ if (!I->hasOneMemOperand())
+ return false;
+
+ MachineMemOperand *Op = I->memoperands()[0];
+ return Op->isLoad() && Op->getPseudoValue() &&
+ Op->getPseudoValue()->kind() == PseudoSourceValue::ConstantPool;
+}
+
+Register PPCInstrInfo::generateLoadForNewConst(
+ unsigned Idx, MachineInstr *MI, Type *Ty,
+ SmallVectorImpl<MachineInstr *> &InsInstrs) const {
+ // Now we only support PPC64, Medium code model and P9 with vector.
+ // We have immutable pattern to access const pool. See function
+ // shouldReduceRegisterPressure.
+ assert((Subtarget.isPPC64() && Subtarget.hasP9Vector() &&
+ Subtarget.getTargetMachine().getCodeModel() == CodeModel::Medium) &&
+ "Target not supported!\n");
+
+ MachineFunction *MF = MI->getMF();
+ MachineRegisterInfo *MRI = &MF->getRegInfo();
+
+ // Generate ADDIStocHA8
+ Register VReg1 = MRI->createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
+ MachineInstrBuilder TOCOffset =
+ BuildMI(*MF, MI->getDebugLoc(), get(PPC::ADDIStocHA8), VReg1)
+ .addReg(PPC::X2)
+ .addConstantPoolIndex(Idx);
+
+ assert((Ty->isFloatTy() || Ty->isDoubleTy()) &&
+ "Only float and double are supported!");
+
+ unsigned LoadOpcode;
+ // Should be float type or double type.
+ if (Ty->isFloatTy())
+ LoadOpcode = PPC::DFLOADf32;
+ else
+ LoadOpcode = PPC::DFLOADf64;
+
+ const TargetRegisterClass *RC = MRI->getRegClass(MI->getOperand(0).getReg());
+ Register VReg2 = MRI->createVirtualRegister(RC);
+ MachineMemOperand *MMO = MF->getMachineMemOperand(
+ MachinePointerInfo::getConstantPool(*MF), MachineMemOperand::MOLoad,
+ Ty->getScalarSizeInBits() / 8, MF->getDataLayout().getPrefTypeAlign(Ty));
+
+ // Generate Load from constant pool.
+ MachineInstrBuilder Load =
+ BuildMI(*MF, MI->getDebugLoc(), get(LoadOpcode), VReg2)
+ .addConstantPoolIndex(Idx)
+ .addReg(VReg1, getKillRegState(true))
+ .addMemOperand(MMO);
+
+ Load->getOperand(1).setTargetFlags(PPCII::MO_TOC_LO);
+
+ // Insert the toc load instructions into InsInstrs.
+ InsInstrs.insert(InsInstrs.begin(), Load);
+ InsInstrs.insert(InsInstrs.begin(), TOCOffset);
+ return VReg2;
+}
+
+// This function returns the const value in constant pool if the \p I is a load
+// from constant pool.
+const Constant *
+PPCInstrInfo::getConstantFromConstantPool(MachineInstr *I) const {
+ MachineFunction *MF = I->getMF();
+ MachineRegisterInfo *MRI = &MF->getRegInfo();
+ MachineConstantPool *MCP = MF->getConstantPool();
+ assert(I->mayLoad() && "Should be a load instruction.\n");
+ for (auto MO : I->uses()) {
+ if (!MO.isReg())
+ continue;
+ Register Reg = MO.getReg();
+ if (Reg == 0 || !Register::isVirtualRegister(Reg))
+ continue;
+ // Find the toc address.
+ MachineInstr *DefMI = MRI->getVRegDef(Reg);
+ for (auto MO2 : DefMI->uses())
+ if (MO2.isCPI())
+ return (MCP->getConstants())[MO2.getIndex()].Val.ConstVal;
+ }
+ return nullptr;
+}
+
bool PPCInstrInfo::getMachineCombinerPatterns(
- MachineInstr &Root, SmallVectorImpl<MachineCombinerPattern> &Patterns,
- bool DoRegPressureReduce) const {
+ MachineInstr &Root, SmallVectorImpl<MachineCombinerPattern> &Patterns,
+ bool DoRegPressureReduce) const {
// Using the machine combiner in this way is potentially expensive, so
// restrict to when aggressive optimizations are desired.
if (Subtarget.getTargetMachine().getOptLevel() != CodeGenOpt::Aggressive)
return false;
- if (getFMAPatterns(Root, Patterns, DoRegPressureReduce))
+ if (getFMAPatterns(Root, Patterns, DoRegPressureReduce))
return true;
- return TargetInstrInfo::getMachineCombinerPatterns(Root, Patterns,
- DoRegPressureReduce);
+ return TargetInstrInfo::getMachineCombinerPatterns(Root, Patterns,
+ DoRegPressureReduce);
}
void PPCInstrInfo::genAlternativeCodeSequence(
@@ -779,8 +779,8 @@ void PPCInstrInfo::genAlternativeCodeSequence(
switch (Pattern) {
case MachineCombinerPattern::REASSOC_XY_AMM_BMM:
case MachineCombinerPattern::REASSOC_XMM_AMM_BMM:
- case MachineCombinerPattern::REASSOC_XY_BCA:
- case MachineCombinerPattern::REASSOC_XY_BAC:
+ case MachineCombinerPattern::REASSOC_XY_BCA:
+ case MachineCombinerPattern::REASSOC_XY_BAC:
reassociateFMA(Root, Pattern, InsInstrs, DelInstrs, InstrIdxForVirtReg);
break;
default:
@@ -798,7 +798,7 @@ void PPCInstrInfo::reassociateFMA(
DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const {
MachineFunction *MF = Root.getMF();
MachineRegisterInfo &MRI = MF->getRegInfo();
- const TargetRegisterInfo *TRI = &getRegisterInfo();
+ const TargetRegisterInfo *TRI = &getRegisterInfo();
MachineOperand &OpC = Root.getOperand(0);
Register RegC = OpC.getReg();
const TargetRegisterClass *RC = MRI.getRegClass(RegC);
@@ -808,43 +808,43 @@ void PPCInstrInfo::reassociateFMA(
int16_t Idx = getFMAOpIdxInfo(FmaOp);
assert(Idx >= 0 && "Root must be a FMA instruction");
- bool IsILPReassociate =
- (Pattern == MachineCombinerPattern::REASSOC_XY_AMM_BMM) ||
- (Pattern == MachineCombinerPattern::REASSOC_XMM_AMM_BMM);
-
+ bool IsILPReassociate =
+ (Pattern == MachineCombinerPattern::REASSOC_XY_AMM_BMM) ||
+ (Pattern == MachineCombinerPattern::REASSOC_XMM_AMM_BMM);
+
uint16_t AddOpIdx = FMAOpIdxInfo[Idx][InfoArrayIdxAddOpIdx];
uint16_t FirstMulOpIdx = FMAOpIdxInfo[Idx][InfoArrayIdxMULOpIdx];
- MachineInstr *Prev = nullptr;
- MachineInstr *Leaf = nullptr;
- switch (Pattern) {
- default:
- llvm_unreachable("not recognized pattern!");
- case MachineCombinerPattern::REASSOC_XY_AMM_BMM:
- case MachineCombinerPattern::REASSOC_XMM_AMM_BMM:
- Prev = MRI.getUniqueVRegDef(Root.getOperand(AddOpIdx).getReg());
- Leaf = MRI.getUniqueVRegDef(Prev->getOperand(AddOpIdx).getReg());
- break;
- case MachineCombinerPattern::REASSOC_XY_BAC: {
- Register MULReg =
- TRI->lookThruCopyLike(Root.getOperand(FirstMulOpIdx).getReg(), &MRI);
- Leaf = MRI.getVRegDef(MULReg);
- break;
- }
- case MachineCombinerPattern::REASSOC_XY_BCA: {
- Register MULReg = TRI->lookThruCopyLike(
- Root.getOperand(FirstMulOpIdx + 1).getReg(), &MRI);
- Leaf = MRI.getVRegDef(MULReg);
- break;
- }
- }
-
- uint16_t IntersectedFlags = 0;
- if (IsILPReassociate)
- IntersectedFlags = Root.getFlags() & Prev->getFlags() & Leaf->getFlags();
- else
- IntersectedFlags = Root.getFlags() & Leaf->getFlags();
-
+ MachineInstr *Prev = nullptr;
+ MachineInstr *Leaf = nullptr;
+ switch (Pattern) {
+ default:
+ llvm_unreachable("not recognized pattern!");
+ case MachineCombinerPattern::REASSOC_XY_AMM_BMM:
+ case MachineCombinerPattern::REASSOC_XMM_AMM_BMM:
+ Prev = MRI.getUniqueVRegDef(Root.getOperand(AddOpIdx).getReg());
+ Leaf = MRI.getUniqueVRegDef(Prev->getOperand(AddOpIdx).getReg());
+ break;
+ case MachineCombinerPattern::REASSOC_XY_BAC: {
+ Register MULReg =
+ TRI->lookThruCopyLike(Root.getOperand(FirstMulOpIdx).getReg(), &MRI);
+ Leaf = MRI.getVRegDef(MULReg);
+ break;
+ }
+ case MachineCombinerPattern::REASSOC_XY_BCA: {
+ Register MULReg = TRI->lookThruCopyLike(
+ Root.getOperand(FirstMulOpIdx + 1).getReg(), &MRI);
+ Leaf = MRI.getVRegDef(MULReg);
+ break;
+ }
+ }
+
+ uint16_t IntersectedFlags = 0;
+ if (IsILPReassociate)
+ IntersectedFlags = Root.getFlags() & Prev->getFlags() & Leaf->getFlags();
+ else
+ IntersectedFlags = Root.getFlags() & Leaf->getFlags();
+
auto GetOperandInfo = [&](const MachineOperand &Operand, Register &Reg,
bool &KillFlag) {
Reg = Operand.getReg();
@@ -853,51 +853,51 @@ void PPCInstrInfo::reassociateFMA(
};
auto GetFMAInstrInfo = [&](const MachineInstr &Instr, Register &MulOp1,
- Register &MulOp2, Register &AddOp,
- bool &MulOp1KillFlag, bool &MulOp2KillFlag,
- bool &AddOpKillFlag) {
+ Register &MulOp2, Register &AddOp,
+ bool &MulOp1KillFlag, bool &MulOp2KillFlag,
+ bool &AddOpKillFlag) {
GetOperandInfo(Instr.getOperand(FirstMulOpIdx), MulOp1, MulOp1KillFlag);
GetOperandInfo(Instr.getOperand(FirstMulOpIdx + 1), MulOp2, MulOp2KillFlag);
- GetOperandInfo(Instr.getOperand(AddOpIdx), AddOp, AddOpKillFlag);
+ GetOperandInfo(Instr.getOperand(AddOpIdx), AddOp, AddOpKillFlag);
};
- Register RegM11, RegM12, RegX, RegY, RegM21, RegM22, RegM31, RegM32, RegA11,
- RegA21, RegB;
+ Register RegM11, RegM12, RegX, RegY, RegM21, RegM22, RegM31, RegM32, RegA11,
+ RegA21, RegB;
bool KillX = false, KillY = false, KillM11 = false, KillM12 = false,
- KillM21 = false, KillM22 = false, KillM31 = false, KillM32 = false,
- KillA11 = false, KillA21 = false, KillB = false;
+ KillM21 = false, KillM22 = false, KillM31 = false, KillM32 = false,
+ KillA11 = false, KillA21 = false, KillB = false;
- GetFMAInstrInfo(Root, RegM31, RegM32, RegB, KillM31, KillM32, KillB);
+ GetFMAInstrInfo(Root, RegM31, RegM32, RegB, KillM31, KillM32, KillB);
+
+ if (IsILPReassociate)
+ GetFMAInstrInfo(*Prev, RegM21, RegM22, RegA21, KillM21, KillM22, KillA21);
- if (IsILPReassociate)
- GetFMAInstrInfo(*Prev, RegM21, RegM22, RegA21, KillM21, KillM22, KillA21);
-
if (Pattern == MachineCombinerPattern::REASSOC_XMM_AMM_BMM) {
- GetFMAInstrInfo(*Leaf, RegM11, RegM12, RegA11, KillM11, KillM12, KillA11);
+ GetFMAInstrInfo(*Leaf, RegM11, RegM12, RegA11, KillM11, KillM12, KillA11);
GetOperandInfo(Leaf->getOperand(AddOpIdx), RegX, KillX);
} else if (Pattern == MachineCombinerPattern::REASSOC_XY_AMM_BMM) {
GetOperandInfo(Leaf->getOperand(1), RegX, KillX);
GetOperandInfo(Leaf->getOperand(2), RegY, KillY);
- } else {
- // Get FSUB instruction info.
- GetOperandInfo(Leaf->getOperand(1), RegX, KillX);
- GetOperandInfo(Leaf->getOperand(2), RegY, KillY);
+ } else {
+ // Get FSUB instruction info.
+ GetOperandInfo(Leaf->getOperand(1), RegX, KillX);
+ GetOperandInfo(Leaf->getOperand(2), RegY, KillY);
}
// Create new virtual registers for the new results instead of
// recycling legacy ones because the MachineCombiner's computation of the
// critical path requires a new register definition rather than an existing
// one.
- // For register pressure reassociation, we only need create one virtual
- // register for the new fma.
+ // For register pressure reassociation, we only need create one virtual
+ // register for the new fma.
Register NewVRA = MRI.createVirtualRegister(RC);
InstrIdxForVirtReg.insert(std::make_pair(NewVRA, 0));
- Register NewVRB = 0;
- if (IsILPReassociate) {
- NewVRB = MRI.createVirtualRegister(RC);
- InstrIdxForVirtReg.insert(std::make_pair(NewVRB, 1));
- }
+ Register NewVRB = 0;
+ if (IsILPReassociate) {
+ NewVRB = MRI.createVirtualRegister(RC);
+ InstrIdxForVirtReg.insert(std::make_pair(NewVRB, 1));
+ }
Register NewVRD = 0;
if (Pattern == MachineCombinerPattern::REASSOC_XMM_AMM_BMM) {
@@ -916,11 +916,11 @@ void PPCInstrInfo::reassociateFMA(
MI->getOperand(FirstMulOpIdx + 1).setIsKill(KillRegMul2);
};
- MachineInstrBuilder NewARegPressure, NewCRegPressure;
- switch (Pattern) {
- default:
- llvm_unreachable("not recognized pattern!");
- case MachineCombinerPattern::REASSOC_XY_AMM_BMM: {
+ MachineInstrBuilder NewARegPressure, NewCRegPressure;
+ switch (Pattern) {
+ default:
+ llvm_unreachable("not recognized pattern!");
+ case MachineCombinerPattern::REASSOC_XY_AMM_BMM: {
// Create new instructions for insertion.
MachineInstrBuilder MINewB =
BuildMI(*MF, Prev->getDebugLoc(), get(FmaOp), NewVRB)
@@ -953,9 +953,9 @@ void PPCInstrInfo::reassociateFMA(
InsInstrs.push_back(MINewA);
InsInstrs.push_back(MINewB);
InsInstrs.push_back(MINewC);
- break;
- }
- case MachineCombinerPattern::REASSOC_XMM_AMM_BMM: {
+ break;
+ }
+ case MachineCombinerPattern::REASSOC_XMM_AMM_BMM: {
assert(NewVRD && "new FMA register not created!");
// Create new instructions for insertion.
MachineInstrBuilder MINewA =
@@ -997,56 +997,56 @@ void PPCInstrInfo::reassociateFMA(
InsInstrs.push_back(MINewB);
InsInstrs.push_back(MINewD);
InsInstrs.push_back(MINewC);
- break;
+ break;
}
- case MachineCombinerPattern::REASSOC_XY_BAC:
- case MachineCombinerPattern::REASSOC_XY_BCA: {
- Register VarReg;
- bool KillVarReg = false;
- if (Pattern == MachineCombinerPattern::REASSOC_XY_BCA) {
- VarReg = RegM31;
- KillVarReg = KillM31;
- } else {
- VarReg = RegM32;
- KillVarReg = KillM32;
- }
- // We don't want to get negative const from memory pool too early, as the
- // created entry will not be deleted even if it has no users. Since all
- // operand of Leaf and Root are virtual register, we use zero register
- // here as a placeholder. When the InsInstrs is selected in
- // MachineCombiner, we call finalizeInsInstrs to replace the zero register
- // with a virtual register which is a load from constant pool.
- NewARegPressure = BuildMI(*MF, Root.getDebugLoc(), get(FmaOp), NewVRA)
- .addReg(RegB, getKillRegState(RegB))
- .addReg(RegY, getKillRegState(KillY))
- .addReg(PPC::ZERO8);
- NewCRegPressure = BuildMI(*MF, Root.getDebugLoc(), get(FmaOp), RegC)
- .addReg(NewVRA, getKillRegState(true))
- .addReg(RegX, getKillRegState(KillX))
- .addReg(VarReg, getKillRegState(KillVarReg));
- // For now, we only support xsmaddadp/xsmaddasp, their add operand are
- // both at index 1, no need to adjust.
- // FIXME: when add more fma instructions support, like fma/fmas, adjust
- // the operand index here.
- break;
- }
- }
-
- if (!IsILPReassociate) {
- setSpecialOperandAttr(*NewARegPressure, IntersectedFlags);
- setSpecialOperandAttr(*NewCRegPressure, IntersectedFlags);
-
- InsInstrs.push_back(NewARegPressure);
- InsInstrs.push_back(NewCRegPressure);
- }
-
+ case MachineCombinerPattern::REASSOC_XY_BAC:
+ case MachineCombinerPattern::REASSOC_XY_BCA: {
+ Register VarReg;
+ bool KillVarReg = false;
+ if (Pattern == MachineCombinerPattern::REASSOC_XY_BCA) {
+ VarReg = RegM31;
+ KillVarReg = KillM31;
+ } else {
+ VarReg = RegM32;
+ KillVarReg = KillM32;
+ }
+ // We don't want to get negative const from memory pool too early, as the
+ // created entry will not be deleted even if it has no users. Since all
+ // operand of Leaf and Root are virtual register, we use zero register
+ // here as a placeholder. When the InsInstrs is selected in
+ // MachineCombiner, we call finalizeInsInstrs to replace the zero register
+ // with a virtual register which is a load from constant pool.
+ NewARegPressure = BuildMI(*MF, Root.getDebugLoc(), get(FmaOp), NewVRA)
+ .addReg(RegB, getKillRegState(RegB))
+ .addReg(RegY, getKillRegState(KillY))
+ .addReg(PPC::ZERO8);
+ NewCRegPressure = BuildMI(*MF, Root.getDebugLoc(), get(FmaOp), RegC)
+ .addReg(NewVRA, getKillRegState(true))
+ .addReg(RegX, getKillRegState(KillX))
+ .addReg(VarReg, getKillRegState(KillVarReg));
+ // For now, we only support xsmaddadp/xsmaddasp, their add operand are
+ // both at index 1, no need to adjust.
+ // FIXME: when add more fma instructions support, like fma/fmas, adjust
+ // the operand index here.
+ break;
+ }
+ }
+
+ if (!IsILPReassociate) {
+ setSpecialOperandAttr(*NewARegPressure, IntersectedFlags);
+ setSpecialOperandAttr(*NewCRegPressure, IntersectedFlags);
+
+ InsInstrs.push_back(NewARegPressure);
+ InsInstrs.push_back(NewCRegPressure);
+ }
+
assert(!InsInstrs.empty() &&
"Insertion instructions set should not be empty!");
// Record old instructions for deletion.
DelInstrs.push_back(Leaf);
- if (IsILPReassociate)
- DelInstrs.push_back(Prev);
+ if (IsILPReassociate)
+ DelInstrs.push_back(Prev);
DelInstrs.push_back(&Root);
}
@@ -1114,7 +1114,7 @@ bool PPCInstrInfo::isReallyTriviallyReMaterializable(const MachineInstr &MI,
case PPC::V_SETALLONES:
case PPC::CRSET:
case PPC::CRUNSET:
- case PPC::XXSETACCZ:
+ case PPC::XXSETACCZ:
return true;
}
return false;
@@ -1715,22 +1715,22 @@ void PPCInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
.addImm(31);
return;
} else if (PPC::CRRCRegClass.contains(SrcReg) &&
- (PPC::G8RCRegClass.contains(DestReg) ||
- PPC::GPRCRegClass.contains(DestReg))) {
- bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);
- unsigned MvCode = Is64Bit ? PPC::MFOCRF8 : PPC::MFOCRF;
- unsigned ShCode = Is64Bit ? PPC::RLWINM8 : PPC::RLWINM;
- unsigned CRNum = TRI->getEncodingValue(SrcReg);
- BuildMI(MBB, I, DL, get(MvCode), DestReg).addReg(SrcReg);
+ (PPC::G8RCRegClass.contains(DestReg) ||
+ PPC::GPRCRegClass.contains(DestReg))) {
+ bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);
+ unsigned MvCode = Is64Bit ? PPC::MFOCRF8 : PPC::MFOCRF;
+ unsigned ShCode = Is64Bit ? PPC::RLWINM8 : PPC::RLWINM;
+ unsigned CRNum = TRI->getEncodingValue(SrcReg);
+ BuildMI(MBB, I, DL, get(MvCode), DestReg).addReg(SrcReg);
getKillRegState(KillSrc);
- if (CRNum == 7)
- return;
- // Shift the CR bits to make the CR field in the lowest 4 bits of GRC.
- BuildMI(MBB, I, DL, get(ShCode), DestReg)
- .addReg(DestReg, RegState::Kill)
- .addImm(CRNum * 4 + 4)
- .addImm(28)
- .addImm(31);
+ if (CRNum == 7)
+ return;
+ // Shift the CR bits to make the CR field in the lowest 4 bits of GRC.
+ BuildMI(MBB, I, DL, get(ShCode), DestReg)
+ .addReg(DestReg, RegState::Kill)
+ .addImm(CRNum * 4 + 4)
+ .addImm(28)
+ .addImm(31);
return;
} else if (PPC::G8RCRegClass.contains(SrcReg) &&
PPC::VSFRCRegClass.contains(DestReg)) {
@@ -1783,53 +1783,53 @@ void PPCInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
else if (PPC::VSFRCRegClass.contains(DestReg, SrcReg) ||
PPC::VSSRCRegClass.contains(DestReg, SrcReg))
Opc = (Subtarget.hasP9Vector()) ? PPC::XSCPSGNDP : PPC::XXLORf;
- else if (Subtarget.pairedVectorMemops() &&
- PPC::VSRpRCRegClass.contains(DestReg, SrcReg)) {
- if (SrcReg > PPC::VSRp15)
- SrcReg = PPC::V0 + (SrcReg - PPC::VSRp16) * 2;
- else
- SrcReg = PPC::VSL0 + (SrcReg - PPC::VSRp0) * 2;
- if (DestReg > PPC::VSRp15)
- DestReg = PPC::V0 + (DestReg - PPC::VSRp16) * 2;
- else
- DestReg = PPC::VSL0 + (DestReg - PPC::VSRp0) * 2;
- BuildMI(MBB, I, DL, get(PPC::XXLOR), DestReg).
- addReg(SrcReg).addReg(SrcReg, getKillRegState(KillSrc));
- BuildMI(MBB, I, DL, get(PPC::XXLOR), DestReg + 1).
- addReg(SrcReg + 1).addReg(SrcReg + 1, getKillRegState(KillSrc));
- return;
- }
+ else if (Subtarget.pairedVectorMemops() &&
+ PPC::VSRpRCRegClass.contains(DestReg, SrcReg)) {
+ if (SrcReg > PPC::VSRp15)
+ SrcReg = PPC::V0 + (SrcReg - PPC::VSRp16) * 2;
+ else
+ SrcReg = PPC::VSL0 + (SrcReg - PPC::VSRp0) * 2;
+ if (DestReg > PPC::VSRp15)
+ DestReg = PPC::V0 + (DestReg - PPC::VSRp16) * 2;
+ else
+ DestReg = PPC::VSL0 + (DestReg - PPC::VSRp0) * 2;
+ BuildMI(MBB, I, DL, get(PPC::XXLOR), DestReg).
+ addReg(SrcReg).addReg(SrcReg, getKillRegState(KillSrc));
+ BuildMI(MBB, I, DL, get(PPC::XXLOR), DestReg + 1).
+ addReg(SrcReg + 1).addReg(SrcReg + 1, getKillRegState(KillSrc));
+ return;
+ }
else if (PPC::CRBITRCRegClass.contains(DestReg, SrcReg))
Opc = PPC::CROR;
else if (PPC::SPERCRegClass.contains(DestReg, SrcReg))
Opc = PPC::EVOR;
- else if ((PPC::ACCRCRegClass.contains(DestReg) ||
- PPC::UACCRCRegClass.contains(DestReg)) &&
- (PPC::ACCRCRegClass.contains(SrcReg) ||
- PPC::UACCRCRegClass.contains(SrcReg))) {
- // If primed, de-prime the source register, copy the individual registers
- // and prime the destination if needed. The vector subregisters are
- // vs[(u)acc * 4] - vs[(u)acc * 4 + 3]. If the copy is not a kill and the
- // source is primed, we need to re-prime it after the copy as well.
- PPCRegisterInfo::emitAccCopyInfo(MBB, DestReg, SrcReg);
- bool DestPrimed = PPC::ACCRCRegClass.contains(DestReg);
- bool SrcPrimed = PPC::ACCRCRegClass.contains(SrcReg);
- MCRegister VSLSrcReg =
- PPC::VSL0 + (SrcReg - (SrcPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
- MCRegister VSLDestReg =
- PPC::VSL0 + (DestReg - (DestPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
- if (SrcPrimed)
- BuildMI(MBB, I, DL, get(PPC::XXMFACC), SrcReg).addReg(SrcReg);
- for (unsigned Idx = 0; Idx < 4; Idx++)
- BuildMI(MBB, I, DL, get(PPC::XXLOR), VSLDestReg + Idx)
- .addReg(VSLSrcReg + Idx)
- .addReg(VSLSrcReg + Idx, getKillRegState(KillSrc));
- if (DestPrimed)
- BuildMI(MBB, I, DL, get(PPC::XXMTACC), DestReg).addReg(DestReg);
- if (SrcPrimed && !KillSrc)
- BuildMI(MBB, I, DL, get(PPC::XXMTACC), SrcReg).addReg(SrcReg);
- return;
- } else
+ else if ((PPC::ACCRCRegClass.contains(DestReg) ||
+ PPC::UACCRCRegClass.contains(DestReg)) &&
+ (PPC::ACCRCRegClass.contains(SrcReg) ||
+ PPC::UACCRCRegClass.contains(SrcReg))) {
+ // If primed, de-prime the source register, copy the individual registers
+ // and prime the destination if needed. The vector subregisters are
+ // vs[(u)acc * 4] - vs[(u)acc * 4 + 3]. If the copy is not a kill and the
+ // source is primed, we need to re-prime it after the copy as well.
+ PPCRegisterInfo::emitAccCopyInfo(MBB, DestReg, SrcReg);
+ bool DestPrimed = PPC::ACCRCRegClass.contains(DestReg);
+ bool SrcPrimed = PPC::ACCRCRegClass.contains(SrcReg);
+ MCRegister VSLSrcReg =
+ PPC::VSL0 + (SrcReg - (SrcPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
+ MCRegister VSLDestReg =
+ PPC::VSL0 + (DestReg - (DestPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
+ if (SrcPrimed)
+ BuildMI(MBB, I, DL, get(PPC::XXMFACC), SrcReg).addReg(SrcReg);
+ for (unsigned Idx = 0; Idx < 4; Idx++)
+ BuildMI(MBB, I, DL, get(PPC::XXLOR), VSLDestReg + Idx)
+ .addReg(VSLSrcReg + Idx)
+ .addReg(VSLSrcReg + Idx, getKillRegState(KillSrc));
+ if (DestPrimed)
+ BuildMI(MBB, I, DL, get(PPC::XXMTACC), DestReg).addReg(DestReg);
+ if (SrcPrimed && !KillSrc)
+ BuildMI(MBB, I, DL, get(PPC::XXMTACC), SrcReg).addReg(SrcReg);
+ return;
+ } else
llvm_unreachable("Impossible reg-to-reg copy");
const MCInstrDesc &MCID = get(Opc);
@@ -1840,7 +1840,7 @@ void PPCInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
BuildMI(MBB, I, DL, MCID, DestReg).addReg(SrcReg, getKillRegState(KillSrc));
}
-unsigned PPCInstrInfo::getSpillIndex(const TargetRegisterClass *RC) const {
+unsigned PPCInstrInfo::getSpillIndex(const TargetRegisterClass *RC) const {
int OpcodeIndex = 0;
if (PPC::GPRCRegClass.hasSubClassEq(RC) ||
@@ -1869,18 +1869,18 @@ unsigned PPCInstrInfo::getSpillIndex(const TargetRegisterClass *RC) const {
OpcodeIndex = SOK_VectorFloat4Spill;
} else if (PPC::SPILLTOVSRRCRegClass.hasSubClassEq(RC)) {
OpcodeIndex = SOK_SpillToVSR;
- } else if (PPC::ACCRCRegClass.hasSubClassEq(RC)) {
- assert(Subtarget.pairedVectorMemops() &&
- "Register unexpected when paired memops are disabled.");
- OpcodeIndex = SOK_AccumulatorSpill;
- } else if (PPC::UACCRCRegClass.hasSubClassEq(RC)) {
- assert(Subtarget.pairedVectorMemops() &&
- "Register unexpected when paired memops are disabled.");
- OpcodeIndex = SOK_UAccumulatorSpill;
- } else if (PPC::VSRpRCRegClass.hasSubClassEq(RC)) {
- assert(Subtarget.pairedVectorMemops() &&
- "Register unexpected when paired memops are disabled.");
- OpcodeIndex = SOK_PairedVecSpill;
+ } else if (PPC::ACCRCRegClass.hasSubClassEq(RC)) {
+ assert(Subtarget.pairedVectorMemops() &&
+ "Register unexpected when paired memops are disabled.");
+ OpcodeIndex = SOK_AccumulatorSpill;
+ } else if (PPC::UACCRCRegClass.hasSubClassEq(RC)) {
+ assert(Subtarget.pairedVectorMemops() &&
+ "Register unexpected when paired memops are disabled.");
+ OpcodeIndex = SOK_UAccumulatorSpill;
+ } else if (PPC::VSRpRCRegClass.hasSubClassEq(RC)) {
+ assert(Subtarget.pairedVectorMemops() &&
+ "Register unexpected when paired memops are disabled.");
+ OpcodeIndex = SOK_PairedVecSpill;
} else {
llvm_unreachable("Unknown regclass!");
}
@@ -2141,17 +2141,17 @@ bool PPCInstrInfo::isPredicated(const MachineInstr &MI) const {
return false;
}
-bool PPCInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
- const MachineBasicBlock *MBB,
- const MachineFunction &MF) const {
- // Set MFFS and MTFSF as scheduling boundary to avoid unexpected code motion
- // across them, since some FP operations may change content of FPSCR.
- // TODO: Model FPSCR in PPC instruction definitions and remove the workaround
- if (MI.getOpcode() == PPC::MFFS || MI.getOpcode() == PPC::MTFSF)
- return true;
- return TargetInstrInfo::isSchedulingBoundary(MI, MBB, MF);
-}
-
+bool PPCInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
+ const MachineBasicBlock *MBB,
+ const MachineFunction &MF) const {
+ // Set MFFS and MTFSF as scheduling boundary to avoid unexpected code motion
+ // across them, since some FP operations may change content of FPSCR.
+ // TODO: Model FPSCR in PPC instruction definitions and remove the workaround
+ if (MI.getOpcode() == PPC::MFFS || MI.getOpcode() == PPC::MTFSF)
+ return true;
+ return TargetInstrInfo::isSchedulingBoundary(MI, MBB, MF);
+}
+
bool PPCInstrInfo::PredicateInstruction(MachineInstr &MI,
ArrayRef<MachineOperand> Pred) const {
unsigned OpC = MI.getOpcode();
@@ -2160,10 +2160,10 @@ bool PPCInstrInfo::PredicateInstruction(MachineInstr &MI,
bool isPPC64 = Subtarget.isPPC64();
MI.setDesc(get(Pred[0].getImm() ? (isPPC64 ? PPC::BDNZLR8 : PPC::BDNZLR)
: (isPPC64 ? PPC::BDZLR8 : PPC::BDZLR)));
- // Need add Def and Use for CTR implicit operand.
- MachineInstrBuilder(*MI.getParent()->getParent(), MI)
- .addReg(Pred[1].getReg(), RegState::Implicit)
- .addReg(Pred[1].getReg(), RegState::ImplicitDefine);
+ // Need add Def and Use for CTR implicit operand.
+ MachineInstrBuilder(*MI.getParent()->getParent(), MI)
+ .addReg(Pred[1].getReg(), RegState::Implicit)
+ .addReg(Pred[1].getReg(), RegState::ImplicitDefine);
} else if (Pred[0].getImm() == PPC::PRED_BIT_SET) {
MI.setDesc(get(PPC::BCLR));
MachineInstrBuilder(*MI.getParent()->getParent(), MI).add(Pred[1]);
@@ -2183,10 +2183,10 @@ bool PPCInstrInfo::PredicateInstruction(MachineInstr &MI,
bool isPPC64 = Subtarget.isPPC64();
MI.setDesc(get(Pred[0].getImm() ? (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
: (isPPC64 ? PPC::BDZ8 : PPC::BDZ)));
- // Need add Def and Use for CTR implicit operand.
- MachineInstrBuilder(*MI.getParent()->getParent(), MI)
- .addReg(Pred[1].getReg(), RegState::Implicit)
- .addReg(Pred[1].getReg(), RegState::ImplicitDefine);
+ // Need add Def and Use for CTR implicit operand.
+ MachineInstrBuilder(*MI.getParent()->getParent(), MI)
+ .addReg(Pred[1].getReg(), RegState::Implicit)
+ .addReg(Pred[1].getReg(), RegState::ImplicitDefine);
} else if (Pred[0].getImm() == PPC::PRED_BIT_SET) {
MachineBasicBlock *MBB = MI.getOperand(0).getMBB();
MI.RemoveOperand(0);
@@ -2231,20 +2231,20 @@ bool PPCInstrInfo::PredicateInstruction(MachineInstr &MI,
MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8n : PPC::BCCTR8n)
: (setLR ? PPC::BCCTRLn : PPC::BCCTRn)));
MachineInstrBuilder(*MI.getParent()->getParent(), MI).add(Pred[1]);
- } else {
- MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCCTRL8 : PPC::BCCCTR8)
- : (setLR ? PPC::BCCCTRL : PPC::BCCCTR)));
- MachineInstrBuilder(*MI.getParent()->getParent(), MI)
- .addImm(Pred[0].getImm())
- .add(Pred[1]);
+ } else {
+ MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCCTRL8 : PPC::BCCCTR8)
+ : (setLR ? PPC::BCCCTRL : PPC::BCCCTR)));
+ MachineInstrBuilder(*MI.getParent()->getParent(), MI)
+ .addImm(Pred[0].getImm())
+ .add(Pred[1]);
}
- // Need add Def and Use for LR implicit operand.
- if (setLR)
- MachineInstrBuilder(*MI.getParent()->getParent(), MI)
- .addReg(isPPC64 ? PPC::LR8 : PPC::LR, RegState::Implicit)
- .addReg(isPPC64 ? PPC::LR8 : PPC::LR, RegState::ImplicitDefine);
-
+ // Need add Def and Use for LR implicit operand.
+ if (setLR)
+ MachineInstrBuilder(*MI.getParent()->getParent(), MI)
+ .addReg(isPPC64 ? PPC::LR8 : PPC::LR, RegState::Implicit)
+ .addReg(isPPC64 ? PPC::LR8 : PPC::LR, RegState::ImplicitDefine);
+
return true;
}
@@ -2282,9 +2282,9 @@ bool PPCInstrInfo::SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
return false;
}
-bool PPCInstrInfo::ClobbersPredicate(MachineInstr &MI,
- std::vector<MachineOperand> &Pred,
- bool SkipDead) const {
+bool PPCInstrInfo::ClobbersPredicate(MachineInstr &MI,
+ std::vector<MachineOperand> &Pred,
+ bool SkipDead) const {
// Note: At the present time, the contents of Pred from this function is
// unused by IfConversion. This implementation follows ARM by pushing the
// CR-defining operand. Because the 'DZ' and 'DNZ' count as types of
@@ -2570,14 +2570,14 @@ bool PPCInstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
if (NewOpC == -1)
return false;
- // This transformation should not be performed if `nsw` is missing and is not
- // `equalityOnly` comparison. Since if there is overflow, sub_lt, sub_gt in
- // CRReg do not reflect correct order. If `equalityOnly` is true, sub_eq in
- // CRReg can reflect if compared values are equal, this optz is still valid.
- if (!equalityOnly && (NewOpC == PPC::SUBF_rec || NewOpC == PPC::SUBF8_rec) &&
- Sub && !Sub->getFlag(MachineInstr::NoSWrap))
- return false;
-
+ // This transformation should not be performed if `nsw` is missing and is not
+ // `equalityOnly` comparison. Since if there is overflow, sub_lt, sub_gt in
+ // CRReg do not reflect correct order. If `equalityOnly` is true, sub_eq in
+ // CRReg can reflect if compared values are equal, this optz is still valid.
+ if (!equalityOnly && (NewOpC == PPC::SUBF_rec || NewOpC == PPC::SUBF8_rec) &&
+ Sub && !Sub->getFlag(MachineInstr::NoSWrap))
+ return false;
+
// If we have SUB(r1, r2) and CMP(r2, r1), the condition code based on CMP
// needs to be updated to be based on SUB. Push the condition code
// operands to OperandsToUpdate. If it is safe to remove CmpInstr, the
@@ -2728,112 +2728,112 @@ bool PPCInstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
return true;
}
-bool PPCInstrInfo::getMemOperandsWithOffsetWidth(
- const MachineInstr &LdSt, SmallVectorImpl<const MachineOperand *> &BaseOps,
- int64_t &Offset, bool &OffsetIsScalable, unsigned &Width,
- const TargetRegisterInfo *TRI) const {
- const MachineOperand *BaseOp;
- OffsetIsScalable = false;
- if (!getMemOperandWithOffsetWidth(LdSt, BaseOp, Offset, Width, TRI))
- return false;
- BaseOps.push_back(BaseOp);
- return true;
-}
-
-static bool isLdStSafeToCluster(const MachineInstr &LdSt,
- const TargetRegisterInfo *TRI) {
- // If this is a volatile load/store, don't mess with it.
- if (LdSt.hasOrderedMemoryRef() || LdSt.getNumExplicitOperands() != 3)
- return false;
-
- if (LdSt.getOperand(2).isFI())
- return true;
-
- assert(LdSt.getOperand(2).isReg() && "Expected a reg operand.");
- // Can't cluster if the instruction modifies the base register
- // or it is update form. e.g. ld r2,3(r2)
- if (LdSt.modifiesRegister(LdSt.getOperand(2).getReg(), TRI))
- return false;
-
- return true;
-}
-
-// Only cluster instruction pair that have the same opcode, and they are
-// clusterable according to PowerPC specification.
-static bool isClusterableLdStOpcPair(unsigned FirstOpc, unsigned SecondOpc,
- const PPCSubtarget &Subtarget) {
- switch (FirstOpc) {
- default:
- return false;
- case PPC::STD:
- case PPC::STFD:
- case PPC::STXSD:
- case PPC::DFSTOREf64:
- return FirstOpc == SecondOpc;
- // PowerPC backend has opcode STW/STW8 for instruction "stw" to deal with
- // 32bit and 64bit instruction selection. They are clusterable pair though
- // they are different opcode.
- case PPC::STW:
- case PPC::STW8:
- return SecondOpc == PPC::STW || SecondOpc == PPC::STW8;
- }
-}
-
-bool PPCInstrInfo::shouldClusterMemOps(
- ArrayRef<const MachineOperand *> BaseOps1,
- ArrayRef<const MachineOperand *> BaseOps2, unsigned NumLoads,
- unsigned NumBytes) const {
-
- assert(BaseOps1.size() == 1 && BaseOps2.size() == 1);
- const MachineOperand &BaseOp1 = *BaseOps1.front();
- const MachineOperand &BaseOp2 = *BaseOps2.front();
- assert((BaseOp1.isReg() || BaseOp1.isFI()) &&
- "Only base registers and frame indices are supported.");
-
- // The NumLoads means the number of loads that has been clustered.
- // Don't cluster memory op if there are already two ops clustered at least.
- if (NumLoads > 2)
- return false;
-
- // Cluster the load/store only when they have the same base
- // register or FI.
- if ((BaseOp1.isReg() != BaseOp2.isReg()) ||
- (BaseOp1.isReg() && BaseOp1.getReg() != BaseOp2.getReg()) ||
- (BaseOp1.isFI() && BaseOp1.getIndex() != BaseOp2.getIndex()))
- return false;
-
- // Check if the load/store are clusterable according to the PowerPC
- // specification.
- const MachineInstr &FirstLdSt = *BaseOp1.getParent();
- const MachineInstr &SecondLdSt = *BaseOp2.getParent();
- unsigned FirstOpc = FirstLdSt.getOpcode();
- unsigned SecondOpc = SecondLdSt.getOpcode();
- const TargetRegisterInfo *TRI = &getRegisterInfo();
- // Cluster the load/store only when they have the same opcode, and they are
- // clusterable opcode according to PowerPC specification.
- if (!isClusterableLdStOpcPair(FirstOpc, SecondOpc, Subtarget))
- return false;
-
- // Can't cluster load/store that have ordered or volatile memory reference.
- if (!isLdStSafeToCluster(FirstLdSt, TRI) ||
- !isLdStSafeToCluster(SecondLdSt, TRI))
- return false;
-
- int64_t Offset1 = 0, Offset2 = 0;
- unsigned Width1 = 0, Width2 = 0;
- const MachineOperand *Base1 = nullptr, *Base2 = nullptr;
- if (!getMemOperandWithOffsetWidth(FirstLdSt, Base1, Offset1, Width1, TRI) ||
- !getMemOperandWithOffsetWidth(SecondLdSt, Base2, Offset2, Width2, TRI) ||
- Width1 != Width2)
- return false;
-
- assert(Base1 == &BaseOp1 && Base2 == &BaseOp2 &&
- "getMemOperandWithOffsetWidth return incorrect base op");
- // The caller should already have ordered FirstMemOp/SecondMemOp by offset.
- assert(Offset1 <= Offset2 && "Caller should have ordered offsets.");
- return Offset1 + Width1 == Offset2;
-}
-
+bool PPCInstrInfo::getMemOperandsWithOffsetWidth(
+ const MachineInstr &LdSt, SmallVectorImpl<const MachineOperand *> &BaseOps,
+ int64_t &Offset, bool &OffsetIsScalable, unsigned &Width,
+ const TargetRegisterInfo *TRI) const {
+ const MachineOperand *BaseOp;
+ OffsetIsScalable = false;
+ if (!getMemOperandWithOffsetWidth(LdSt, BaseOp, Offset, Width, TRI))
+ return false;
+ BaseOps.push_back(BaseOp);
+ return true;
+}
+
+static bool isLdStSafeToCluster(const MachineInstr &LdSt,
+ const TargetRegisterInfo *TRI) {
+ // If this is a volatile load/store, don't mess with it.
+ if (LdSt.hasOrderedMemoryRef() || LdSt.getNumExplicitOperands() != 3)
+ return false;
+
+ if (LdSt.getOperand(2).isFI())
+ return true;
+
+ assert(LdSt.getOperand(2).isReg() && "Expected a reg operand.");
+ // Can't cluster if the instruction modifies the base register
+ // or it is update form. e.g. ld r2,3(r2)
+ if (LdSt.modifiesRegister(LdSt.getOperand(2).getReg(), TRI))
+ return false;
+
+ return true;
+}
+
+// Only cluster instruction pair that have the same opcode, and they are
+// clusterable according to PowerPC specification.
+static bool isClusterableLdStOpcPair(unsigned FirstOpc, unsigned SecondOpc,
+ const PPCSubtarget &Subtarget) {
+ switch (FirstOpc) {
+ default:
+ return false;
+ case PPC::STD:
+ case PPC::STFD:
+ case PPC::STXSD:
+ case PPC::DFSTOREf64:
+ return FirstOpc == SecondOpc;
+ // PowerPC backend has opcode STW/STW8 for instruction "stw" to deal with
+ // 32bit and 64bit instruction selection. They are clusterable pair though
+ // they are different opcode.
+ case PPC::STW:
+ case PPC::STW8:
+ return SecondOpc == PPC::STW || SecondOpc == PPC::STW8;
+ }
+}
+
+bool PPCInstrInfo::shouldClusterMemOps(
+ ArrayRef<const MachineOperand *> BaseOps1,
+ ArrayRef<const MachineOperand *> BaseOps2, unsigned NumLoads,
+ unsigned NumBytes) const {
+
+ assert(BaseOps1.size() == 1 && BaseOps2.size() == 1);
+ const MachineOperand &BaseOp1 = *BaseOps1.front();
+ const MachineOperand &BaseOp2 = *BaseOps2.front();
+ assert((BaseOp1.isReg() || BaseOp1.isFI()) &&
+ "Only base registers and frame indices are supported.");
+
+ // The NumLoads means the number of loads that has been clustered.
+ // Don't cluster memory op if there are already two ops clustered at least.
+ if (NumLoads > 2)
+ return false;
+
+ // Cluster the load/store only when they have the same base
+ // register or FI.
+ if ((BaseOp1.isReg() != BaseOp2.isReg()) ||
+ (BaseOp1.isReg() && BaseOp1.getReg() != BaseOp2.getReg()) ||
+ (BaseOp1.isFI() && BaseOp1.getIndex() != BaseOp2.getIndex()))
+ return false;
+
+ // Check if the load/store are clusterable according to the PowerPC
+ // specification.
+ const MachineInstr &FirstLdSt = *BaseOp1.getParent();
+ const MachineInstr &SecondLdSt = *BaseOp2.getParent();
+ unsigned FirstOpc = FirstLdSt.getOpcode();
+ unsigned SecondOpc = SecondLdSt.getOpcode();
+ const TargetRegisterInfo *TRI = &getRegisterInfo();
+ // Cluster the load/store only when they have the same opcode, and they are
+ // clusterable opcode according to PowerPC specification.
+ if (!isClusterableLdStOpcPair(FirstOpc, SecondOpc, Subtarget))
+ return false;
+
+ // Can't cluster load/store that have ordered or volatile memory reference.
+ if (!isLdStSafeToCluster(FirstLdSt, TRI) ||
+ !isLdStSafeToCluster(SecondLdSt, TRI))
+ return false;
+
+ int64_t Offset1 = 0, Offset2 = 0;
+ unsigned Width1 = 0, Width2 = 0;
+ const MachineOperand *Base1 = nullptr, *Base2 = nullptr;
+ if (!getMemOperandWithOffsetWidth(FirstLdSt, Base1, Offset1, Width1, TRI) ||
+ !getMemOperandWithOffsetWidth(SecondLdSt, Base2, Offset2, Width2, TRI) ||
+ Width1 != Width2)
+ return false;
+
+ assert(Base1 == &BaseOp1 && Base2 == &BaseOp2 &&
+ "getMemOperandWithOffsetWidth return incorrect base op");
+ // The caller should already have ordered FirstMemOp/SecondMemOp by offset.
+ assert(Offset1 <= Offset2 && "Caller should have ordered offsets.");
+ return Offset1 + Width1 == Offset2;
+}
+
/// GetInstSize - Return the number of bytes of code the specified
/// instruction may be. This returns the maximum number of bytes.
///
@@ -2883,14 +2883,14 @@ PPCInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
{MO_PLT, "ppc-plt"},
{MO_PIC_FLAG, "ppc-pic"},
{MO_PCREL_FLAG, "ppc-pcrel"},
- {MO_GOT_FLAG, "ppc-got"},
- {MO_PCREL_OPT_FLAG, "ppc-opt-pcrel"},
- {MO_TLSGD_FLAG, "ppc-tlsgd"},
- {MO_TLSLD_FLAG, "ppc-tlsld"},
- {MO_TPREL_FLAG, "ppc-tprel"},
- {MO_GOT_TLSGD_PCREL_FLAG, "ppc-got-tlsgd-pcrel"},
- {MO_GOT_TLSLD_PCREL_FLAG, "ppc-got-tlsld-pcrel"},
- {MO_GOT_TPREL_PCREL_FLAG, "ppc-got-tprel-pcrel"}};
+ {MO_GOT_FLAG, "ppc-got"},
+ {MO_PCREL_OPT_FLAG, "ppc-opt-pcrel"},
+ {MO_TLSGD_FLAG, "ppc-tlsgd"},
+ {MO_TLSLD_FLAG, "ppc-tlsld"},
+ {MO_TPREL_FLAG, "ppc-tprel"},
+ {MO_GOT_TLSGD_PCREL_FLAG, "ppc-got-tlsgd-pcrel"},
+ {MO_GOT_TLSLD_PCREL_FLAG, "ppc-got-tlsld-pcrel"},
+ {MO_GOT_TPREL_PCREL_FLAG, "ppc-got-tprel-pcrel"}};
return makeArrayRef(TargetFlags);
}
@@ -2971,31 +2971,31 @@ bool PPCInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
auto DL = MI.getDebugLoc();
switch (MI.getOpcode()) {
- case PPC::BUILD_UACC: {
- MCRegister ACC = MI.getOperand(0).getReg();
- MCRegister UACC = MI.getOperand(1).getReg();
- if (ACC - PPC::ACC0 != UACC - PPC::UACC0) {
- MCRegister SrcVSR = PPC::VSL0 + (UACC - PPC::UACC0) * 4;
- MCRegister DstVSR = PPC::VSL0 + (ACC - PPC::ACC0) * 4;
- // FIXME: This can easily be improved to look up to the top of the MBB
- // to see if the inputs are XXLOR's. If they are and SrcReg is killed,
- // we can just re-target any such XXLOR's to DstVSR + offset.
- for (int VecNo = 0; VecNo < 4; VecNo++)
- BuildMI(MBB, MI, DL, get(PPC::XXLOR), DstVSR + VecNo)
- .addReg(SrcVSR + VecNo)
- .addReg(SrcVSR + VecNo);
- }
- // BUILD_UACC is expanded to 4 copies of the underlying vsx regisers.
- // So after building the 4 copies, we can replace the BUILD_UACC instruction
- // with a NOP.
- LLVM_FALLTHROUGH;
- }
- case PPC::KILL_PAIR: {
- MI.setDesc(get(PPC::UNENCODED_NOP));
- MI.RemoveOperand(1);
- MI.RemoveOperand(0);
- return true;
- }
+ case PPC::BUILD_UACC: {
+ MCRegister ACC = MI.getOperand(0).getReg();
+ MCRegister UACC = MI.getOperand(1).getReg();
+ if (ACC - PPC::ACC0 != UACC - PPC::UACC0) {
+ MCRegister SrcVSR = PPC::VSL0 + (UACC - PPC::UACC0) * 4;
+ MCRegister DstVSR = PPC::VSL0 + (ACC - PPC::ACC0) * 4;
+ // FIXME: This can easily be improved to look up to the top of the MBB
+ // to see if the inputs are XXLOR's. If they are and SrcReg is killed,
+ // we can just re-target any such XXLOR's to DstVSR + offset.
+ for (int VecNo = 0; VecNo < 4; VecNo++)
+ BuildMI(MBB, MI, DL, get(PPC::XXLOR), DstVSR + VecNo)
+ .addReg(SrcVSR + VecNo)
+ .addReg(SrcVSR + VecNo);
+ }
+ // BUILD_UACC is expanded to 4 copies of the underlying vsx regisers.
+ // So after building the 4 copies, we can replace the BUILD_UACC instruction
+ // with a NOP.
+ LLVM_FALLTHROUGH;
+ }
+ case PPC::KILL_PAIR: {
+ MI.setDesc(get(PPC::UNENCODED_NOP));
+ MI.RemoveOperand(1);
+ MI.RemoveOperand(0);
+ return true;
+ }
case TargetOpcode::LOAD_STACK_GUARD: {
assert(Subtarget.isTargetLinux() &&
"Only Linux target is expected to contain LOAD_STACK_GUARD");
@@ -3287,10 +3287,10 @@ MachineInstr *PPCInstrInfo::getForwardingDefMI(
}
unsigned PPCInstrInfo::getSpillTarget() const {
- // With P10, we may need to spill paired vector registers or accumulator
- // registers. MMA implies paired vectors, so we can just check that.
- bool IsP10Variant = Subtarget.isISA3_1() || Subtarget.pairedVectorMemops();
- return IsP10Variant ? 2 : Subtarget.hasP9Vector() ? 1 : 0;
+ // With P10, we may need to spill paired vector registers or accumulator
+ // registers. MMA implies paired vectors, so we can just check that.
+ bool IsP10Variant = Subtarget.isISA3_1() || Subtarget.pairedVectorMemops();
+ return IsP10Variant ? 2 : Subtarget.hasP9Vector() ? 1 : 0;
}
const unsigned *PPCInstrInfo::getStoreOpcodesForSpillArray() const {
@@ -3681,143 +3681,143 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI,
return false;
}
-bool PPCInstrInfo::combineRLWINM(MachineInstr &MI,
- MachineInstr **ToErase) const {
- MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo();
- unsigned FoldingReg = MI.getOperand(1).getReg();
- if (!Register::isVirtualRegister(FoldingReg))
- return false;
- MachineInstr *SrcMI = MRI->getVRegDef(FoldingReg);
- if (SrcMI->getOpcode() != PPC::RLWINM &&
- SrcMI->getOpcode() != PPC::RLWINM_rec &&
- SrcMI->getOpcode() != PPC::RLWINM8 &&
- SrcMI->getOpcode() != PPC::RLWINM8_rec)
- return false;
- assert((MI.getOperand(2).isImm() && MI.getOperand(3).isImm() &&
- MI.getOperand(4).isImm() && SrcMI->getOperand(2).isImm() &&
- SrcMI->getOperand(3).isImm() && SrcMI->getOperand(4).isImm()) &&
- "Invalid PPC::RLWINM Instruction!");
- uint64_t SHSrc = SrcMI->getOperand(2).getImm();
- uint64_t SHMI = MI.getOperand(2).getImm();
- uint64_t MBSrc = SrcMI->getOperand(3).getImm();
- uint64_t MBMI = MI.getOperand(3).getImm();
- uint64_t MESrc = SrcMI->getOperand(4).getImm();
- uint64_t MEMI = MI.getOperand(4).getImm();
-
- assert((MEMI < 32 && MESrc < 32 && MBMI < 32 && MBSrc < 32) &&
- "Invalid PPC::RLWINM Instruction!");
- // If MBMI is bigger than MEMI, we always can not get run of ones.
- // RotatedSrcMask non-wrap:
- // 0........31|32........63
- // RotatedSrcMask: B---E B---E
- // MaskMI: -----------|--E B------
- // Result: ----- --- (Bad candidate)
- //
- // RotatedSrcMask wrap:
- // 0........31|32........63
- // RotatedSrcMask: --E B----|--E B----
- // MaskMI: -----------|--E B------
- // Result: --- -----|--- ----- (Bad candidate)
- //
- // One special case is RotatedSrcMask is a full set mask.
- // RotatedSrcMask full:
- // 0........31|32........63
- // RotatedSrcMask: ------EB---|-------EB---
- // MaskMI: -----------|--E B------
- // Result: -----------|--- ------- (Good candidate)
-
- // Mark special case.
- bool SrcMaskFull = (MBSrc - MESrc == 1) || (MBSrc == 0 && MESrc == 31);
-
- // For other MBMI > MEMI cases, just return.
- if ((MBMI > MEMI) && !SrcMaskFull)
- return false;
-
- // Handle MBMI <= MEMI cases.
- APInt MaskMI = APInt::getBitsSetWithWrap(32, 32 - MEMI - 1, 32 - MBMI);
- // In MI, we only need low 32 bits of SrcMI, just consider about low 32
- // bit of SrcMI mask. Note that in APInt, lowerest bit is at index 0,
- // while in PowerPC ISA, lowerest bit is at index 63.
- APInt MaskSrc = APInt::getBitsSetWithWrap(32, 32 - MESrc - 1, 32 - MBSrc);
-
- APInt RotatedSrcMask = MaskSrc.rotl(SHMI);
- APInt FinalMask = RotatedSrcMask & MaskMI;
- uint32_t NewMB, NewME;
- bool Simplified = false;
-
- // If final mask is 0, MI result should be 0 too.
- if (FinalMask.isNullValue()) {
- bool Is64Bit =
- (MI.getOpcode() == PPC::RLWINM8 || MI.getOpcode() == PPC::RLWINM8_rec);
- Simplified = true;
- LLVM_DEBUG(dbgs() << "Replace Instr: ");
- LLVM_DEBUG(MI.dump());
-
- if (MI.getOpcode() == PPC::RLWINM || MI.getOpcode() == PPC::RLWINM8) {
- // Replace MI with "LI 0"
- MI.RemoveOperand(4);
- MI.RemoveOperand(3);
- MI.RemoveOperand(2);
- MI.getOperand(1).ChangeToImmediate(0);
- MI.setDesc(get(Is64Bit ? PPC::LI8 : PPC::LI));
- } else {
- // Replace MI with "ANDI_rec reg, 0"
- MI.RemoveOperand(4);
- MI.RemoveOperand(3);
- MI.getOperand(2).setImm(0);
- MI.setDesc(get(Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
- MI.getOperand(1).setReg(SrcMI->getOperand(1).getReg());
- if (SrcMI->getOperand(1).isKill()) {
- MI.getOperand(1).setIsKill(true);
- SrcMI->getOperand(1).setIsKill(false);
- } else
- // About to replace MI.getOperand(1), clear its kill flag.
- MI.getOperand(1).setIsKill(false);
- }
-
- LLVM_DEBUG(dbgs() << "With: ");
- LLVM_DEBUG(MI.dump());
-
- } else if ((isRunOfOnes((unsigned)(FinalMask.getZExtValue()), NewMB, NewME) &&
- NewMB <= NewME) ||
- SrcMaskFull) {
- // Here we only handle MBMI <= MEMI case, so NewMB must be no bigger
- // than NewME. Otherwise we get a 64 bit value after folding, but MI
- // return a 32 bit value.
- Simplified = true;
- LLVM_DEBUG(dbgs() << "Converting Instr: ");
- LLVM_DEBUG(MI.dump());
-
- uint16_t NewSH = (SHSrc + SHMI) % 32;
- MI.getOperand(2).setImm(NewSH);
- // If SrcMI mask is full, no need to update MBMI and MEMI.
- if (!SrcMaskFull) {
- MI.getOperand(3).setImm(NewMB);
- MI.getOperand(4).setImm(NewME);
- }
- MI.getOperand(1).setReg(SrcMI->getOperand(1).getReg());
- if (SrcMI->getOperand(1).isKill()) {
- MI.getOperand(1).setIsKill(true);
- SrcMI->getOperand(1).setIsKill(false);
- } else
- // About to replace MI.getOperand(1), clear its kill flag.
- MI.getOperand(1).setIsKill(false);
-
- LLVM_DEBUG(dbgs() << "To: ");
- LLVM_DEBUG(MI.dump());
- }
- if (Simplified & MRI->use_nodbg_empty(FoldingReg) &&
- !SrcMI->hasImplicitDef()) {
- // If FoldingReg has no non-debug use and it has no implicit def (it
- // is not RLWINMO or RLWINM8o), it's safe to delete its def SrcMI.
- // Otherwise keep it.
- *ToErase = SrcMI;
- LLVM_DEBUG(dbgs() << "Delete dead instruction: ");
- LLVM_DEBUG(SrcMI->dump());
- }
- return Simplified;
-}
-
+bool PPCInstrInfo::combineRLWINM(MachineInstr &MI,
+ MachineInstr **ToErase) const {
+ MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo();
+ unsigned FoldingReg = MI.getOperand(1).getReg();
+ if (!Register::isVirtualRegister(FoldingReg))
+ return false;
+ MachineInstr *SrcMI = MRI->getVRegDef(FoldingReg);
+ if (SrcMI->getOpcode() != PPC::RLWINM &&
+ SrcMI->getOpcode() != PPC::RLWINM_rec &&
+ SrcMI->getOpcode() != PPC::RLWINM8 &&
+ SrcMI->getOpcode() != PPC::RLWINM8_rec)
+ return false;
+ assert((MI.getOperand(2).isImm() && MI.getOperand(3).isImm() &&
+ MI.getOperand(4).isImm() && SrcMI->getOperand(2).isImm() &&
+ SrcMI->getOperand(3).isImm() && SrcMI->getOperand(4).isImm()) &&
+ "Invalid PPC::RLWINM Instruction!");
+ uint64_t SHSrc = SrcMI->getOperand(2).getImm();
+ uint64_t SHMI = MI.getOperand(2).getImm();
+ uint64_t MBSrc = SrcMI->getOperand(3).getImm();
+ uint64_t MBMI = MI.getOperand(3).getImm();
+ uint64_t MESrc = SrcMI->getOperand(4).getImm();
+ uint64_t MEMI = MI.getOperand(4).getImm();
+
+ assert((MEMI < 32 && MESrc < 32 && MBMI < 32 && MBSrc < 32) &&
+ "Invalid PPC::RLWINM Instruction!");
+ // If MBMI is bigger than MEMI, we always can not get run of ones.
+ // RotatedSrcMask non-wrap:
+ // 0........31|32........63
+ // RotatedSrcMask: B---E B---E
+ // MaskMI: -----------|--E B------
+ // Result: ----- --- (Bad candidate)
+ //
+ // RotatedSrcMask wrap:
+ // 0........31|32........63
+ // RotatedSrcMask: --E B----|--E B----
+ // MaskMI: -----------|--E B------
+ // Result: --- -----|--- ----- (Bad candidate)
+ //
+ // One special case is RotatedSrcMask is a full set mask.
+ // RotatedSrcMask full:
+ // 0........31|32........63
+ // RotatedSrcMask: ------EB---|-------EB---
+ // MaskMI: -----------|--E B------
+ // Result: -----------|--- ------- (Good candidate)
+
+ // Mark special case.
+ bool SrcMaskFull = (MBSrc - MESrc == 1) || (MBSrc == 0 && MESrc == 31);
+
+ // For other MBMI > MEMI cases, just return.
+ if ((MBMI > MEMI) && !SrcMaskFull)
+ return false;
+
+ // Handle MBMI <= MEMI cases.
+ APInt MaskMI = APInt::getBitsSetWithWrap(32, 32 - MEMI - 1, 32 - MBMI);
+ // In MI, we only need low 32 bits of SrcMI, just consider about low 32
+ // bit of SrcMI mask. Note that in APInt, lowerest bit is at index 0,
+ // while in PowerPC ISA, lowerest bit is at index 63.
+ APInt MaskSrc = APInt::getBitsSetWithWrap(32, 32 - MESrc - 1, 32 - MBSrc);
+
+ APInt RotatedSrcMask = MaskSrc.rotl(SHMI);
+ APInt FinalMask = RotatedSrcMask & MaskMI;
+ uint32_t NewMB, NewME;
+ bool Simplified = false;
+
+ // If final mask is 0, MI result should be 0 too.
+ if (FinalMask.isNullValue()) {
+ bool Is64Bit =
+ (MI.getOpcode() == PPC::RLWINM8 || MI.getOpcode() == PPC::RLWINM8_rec);
+ Simplified = true;
+ LLVM_DEBUG(dbgs() << "Replace Instr: ");
+ LLVM_DEBUG(MI.dump());
+
+ if (MI.getOpcode() == PPC::RLWINM || MI.getOpcode() == PPC::RLWINM8) {
+ // Replace MI with "LI 0"
+ MI.RemoveOperand(4);
+ MI.RemoveOperand(3);
+ MI.RemoveOperand(2);
+ MI.getOperand(1).ChangeToImmediate(0);
+ MI.setDesc(get(Is64Bit ? PPC::LI8 : PPC::LI));
+ } else {
+ // Replace MI with "ANDI_rec reg, 0"
+ MI.RemoveOperand(4);
+ MI.RemoveOperand(3);
+ MI.getOperand(2).setImm(0);
+ MI.setDesc(get(Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
+ MI.getOperand(1).setReg(SrcMI->getOperand(1).getReg());
+ if (SrcMI->getOperand(1).isKill()) {
+ MI.getOperand(1).setIsKill(true);
+ SrcMI->getOperand(1).setIsKill(false);
+ } else
+ // About to replace MI.getOperand(1), clear its kill flag.
+ MI.getOperand(1).setIsKill(false);
+ }
+
+ LLVM_DEBUG(dbgs() << "With: ");
+ LLVM_DEBUG(MI.dump());
+
+ } else if ((isRunOfOnes((unsigned)(FinalMask.getZExtValue()), NewMB, NewME) &&
+ NewMB <= NewME) ||
+ SrcMaskFull) {
+ // Here we only handle MBMI <= MEMI case, so NewMB must be no bigger
+ // than NewME. Otherwise we get a 64 bit value after folding, but MI
+ // return a 32 bit value.
+ Simplified = true;
+ LLVM_DEBUG(dbgs() << "Converting Instr: ");
+ LLVM_DEBUG(MI.dump());
+
+ uint16_t NewSH = (SHSrc + SHMI) % 32;
+ MI.getOperand(2).setImm(NewSH);
+ // If SrcMI mask is full, no need to update MBMI and MEMI.
+ if (!SrcMaskFull) {
+ MI.getOperand(3).setImm(NewMB);
+ MI.getOperand(4).setImm(NewME);
+ }
+ MI.getOperand(1).setReg(SrcMI->getOperand(1).getReg());
+ if (SrcMI->getOperand(1).isKill()) {
+ MI.getOperand(1).setIsKill(true);
+ SrcMI->getOperand(1).setIsKill(false);
+ } else
+ // About to replace MI.getOperand(1), clear its kill flag.
+ MI.getOperand(1).setIsKill(false);
+
+ LLVM_DEBUG(dbgs() << "To: ");
+ LLVM_DEBUG(MI.dump());
+ }
+ if (Simplified & MRI->use_nodbg_empty(FoldingReg) &&
+ !SrcMI->hasImplicitDef()) {
+ // If FoldingReg has no non-debug use and it has no implicit def (it
+ // is not RLWINMO or RLWINM8o), it's safe to delete its def SrcMI.
+ // Otherwise keep it.
+ *ToErase = SrcMI;
+ LLVM_DEBUG(dbgs() << "Delete dead instruction: ");
+ LLVM_DEBUG(SrcMI->dump());
+ }
+ return Simplified;
+}
+
bool PPCInstrInfo::instrHasImmForm(unsigned Opc, bool IsVFReg,
ImmInstrInfo &III, bool PostRA) const {
// The vast majority of the instructions would need their operand 2 replaced
@@ -4539,20 +4539,20 @@ bool PPCInstrInfo::simplifyToLI(MachineInstr &MI, MachineInstr &DefMI,
}
return false;
}
- case PPC::SUBFIC:
- case PPC::SUBFIC8: {
- // Only transform this if the CARRY implicit operand is dead.
- if (MI.getNumOperands() > 3 && !MI.getOperand(3).isDead())
- return false;
- int64_t Minuend = MI.getOperand(2).getImm();
- if (isInt<16>(Minuend - SExtImm)) {
- ReplaceWithLI = true;
- Is64BitLI = Opc == PPC::SUBFIC8;
- NewImm = Minuend - SExtImm;
- break;
- }
- return false;
- }
+ case PPC::SUBFIC:
+ case PPC::SUBFIC8: {
+ // Only transform this if the CARRY implicit operand is dead.
+ if (MI.getNumOperands() > 3 && !MI.getOperand(3).isDead())
+ return false;
+ int64_t Minuend = MI.getOperand(2).getImm();
+ if (isInt<16>(Minuend - SExtImm)) {
+ ReplaceWithLI = true;
+ Is64BitLI = Opc == PPC::SUBFIC8;
+ NewImm = Minuend - SExtImm;
+ break;
+ }
+ return false;
+ }
case PPC::RLDICL:
case PPC::RLDICL_rec:
case PPC::RLDICL_32:
@@ -5439,15 +5439,15 @@ MachineInstr *PPCInstrInfo::findLoopInstr(
bool PPCInstrInfo::getMemOperandWithOffsetWidth(
const MachineInstr &LdSt, const MachineOperand *&BaseReg, int64_t &Offset,
unsigned &Width, const TargetRegisterInfo *TRI) const {
- if (!LdSt.mayLoadOrStore() || LdSt.getNumExplicitOperands() != 3)
+ if (!LdSt.mayLoadOrStore() || LdSt.getNumExplicitOperands() != 3)
return false;
// Handle only loads/stores with base register followed by immediate offset.
- if (!LdSt.getOperand(1).isImm() ||
- (!LdSt.getOperand(2).isReg() && !LdSt.getOperand(2).isFI()))
+ if (!LdSt.getOperand(1).isImm() ||
+ (!LdSt.getOperand(2).isReg() && !LdSt.getOperand(2).isFI()))
return false;
- if (!LdSt.getOperand(1).isImm() ||
- (!LdSt.getOperand(2).isReg() && !LdSt.getOperand(2).isFI()))
+ if (!LdSt.getOperand(1).isImm() ||
+ (!LdSt.getOperand(2).isReg() && !LdSt.getOperand(2).isFI()))
return false;
if (!LdSt.hasOneMemOperand())
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrInfo.h b/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrInfo.h
index 1f4fc87086..c6ef1742b7 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrInfo.h
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrInfo.h
@@ -123,72 +123,72 @@ enum SpillOpcodeKey {
SOK_VectorFloat8Spill,
SOK_VectorFloat4Spill,
SOK_SpillToVSR,
- SOK_PairedVecSpill,
- SOK_AccumulatorSpill,
- SOK_UAccumulatorSpill,
+ SOK_PairedVecSpill,
+ SOK_AccumulatorSpill,
+ SOK_UAccumulatorSpill,
SOK_SPESpill,
SOK_LastOpcodeSpill // This must be last on the enum.
};
// Define list of load and store spill opcodes.
-#define NoInstr PPC::INSTRUCTION_LIST_END
+#define NoInstr PPC::INSTRUCTION_LIST_END
#define Pwr8LoadOpcodes \
{ \
PPC::LWZ, PPC::LD, PPC::LFD, PPC::LFS, PPC::RESTORE_CR, \
PPC::RESTORE_CRBIT, PPC::LVX, PPC::LXVD2X, PPC::LXSDX, PPC::LXSSPX, \
- PPC::SPILLTOVSR_LD, NoInstr, NoInstr, NoInstr, PPC::EVLDD \
+ PPC::SPILLTOVSR_LD, NoInstr, NoInstr, NoInstr, PPC::EVLDD \
}
#define Pwr9LoadOpcodes \
{ \
PPC::LWZ, PPC::LD, PPC::LFD, PPC::LFS, PPC::RESTORE_CR, \
PPC::RESTORE_CRBIT, PPC::LVX, PPC::LXV, PPC::DFLOADf64, \
- PPC::DFLOADf32, PPC::SPILLTOVSR_LD, NoInstr, NoInstr, NoInstr, NoInstr \
+ PPC::DFLOADf32, PPC::SPILLTOVSR_LD, NoInstr, NoInstr, NoInstr, NoInstr \
+ }
+
+#define Pwr10LoadOpcodes \
+ { \
+ PPC::LWZ, PPC::LD, PPC::LFD, PPC::LFS, PPC::RESTORE_CR, \
+ PPC::RESTORE_CRBIT, PPC::LVX, PPC::LXV, PPC::DFLOADf64, \
+ PPC::DFLOADf32, PPC::SPILLTOVSR_LD, PPC::LXVP, PPC::RESTORE_ACC, \
+ PPC::RESTORE_UACC, NoInstr \
}
-#define Pwr10LoadOpcodes \
- { \
- PPC::LWZ, PPC::LD, PPC::LFD, PPC::LFS, PPC::RESTORE_CR, \
- PPC::RESTORE_CRBIT, PPC::LVX, PPC::LXV, PPC::DFLOADf64, \
- PPC::DFLOADf32, PPC::SPILLTOVSR_LD, PPC::LXVP, PPC::RESTORE_ACC, \
- PPC::RESTORE_UACC, NoInstr \
- }
-
#define Pwr8StoreOpcodes \
{ \
PPC::STW, PPC::STD, PPC::STFD, PPC::STFS, PPC::SPILL_CR, PPC::SPILL_CRBIT, \
- PPC::STVX, PPC::STXVD2X, PPC::STXSDX, PPC::STXSSPX, \
- PPC::SPILLTOVSR_ST, NoInstr, NoInstr, NoInstr, PPC::EVSTDD \
+ PPC::STVX, PPC::STXVD2X, PPC::STXSDX, PPC::STXSSPX, \
+ PPC::SPILLTOVSR_ST, NoInstr, NoInstr, NoInstr, PPC::EVSTDD \
}
#define Pwr9StoreOpcodes \
{ \
PPC::STW, PPC::STD, PPC::STFD, PPC::STFS, PPC::SPILL_CR, PPC::SPILL_CRBIT, \
PPC::STVX, PPC::STXV, PPC::DFSTOREf64, PPC::DFSTOREf32, \
- PPC::SPILLTOVSR_ST, NoInstr, NoInstr, NoInstr, NoInstr \
+ PPC::SPILLTOVSR_ST, NoInstr, NoInstr, NoInstr, NoInstr \
+ }
+
+#define Pwr10StoreOpcodes \
+ { \
+ PPC::STW, PPC::STD, PPC::STFD, PPC::STFS, PPC::SPILL_CR, PPC::SPILL_CRBIT, \
+ PPC::STVX, PPC::STXV, PPC::DFSTOREf64, PPC::DFSTOREf32, \
+ PPC::SPILLTOVSR_ST, PPC::STXVP, PPC::SPILL_ACC, PPC::SPILL_UACC, \
+ NoInstr \
}
-#define Pwr10StoreOpcodes \
- { \
- PPC::STW, PPC::STD, PPC::STFD, PPC::STFS, PPC::SPILL_CR, PPC::SPILL_CRBIT, \
- PPC::STVX, PPC::STXV, PPC::DFSTOREf64, PPC::DFSTOREf32, \
- PPC::SPILLTOVSR_ST, PPC::STXVP, PPC::SPILL_ACC, PPC::SPILL_UACC, \
- NoInstr \
- }
-
// Initialize arrays for load and store spill opcodes on supported subtargets.
#define StoreOpcodesForSpill \
- { Pwr8StoreOpcodes, Pwr9StoreOpcodes, Pwr10StoreOpcodes }
+ { Pwr8StoreOpcodes, Pwr9StoreOpcodes, Pwr10StoreOpcodes }
#define LoadOpcodesForSpill \
- { Pwr8LoadOpcodes, Pwr9LoadOpcodes, Pwr10LoadOpcodes }
+ { Pwr8LoadOpcodes, Pwr9LoadOpcodes, Pwr10LoadOpcodes }
class PPCSubtarget;
class PPCInstrInfo : public PPCGenInstrInfo {
PPCSubtarget &Subtarget;
const PPCRegisterInfo RI;
- const unsigned StoreSpillOpcodesArray[3][SOK_LastOpcodeSpill] =
+ const unsigned StoreSpillOpcodesArray[3][SOK_LastOpcodeSpill] =
StoreOpcodesForSpill;
- const unsigned LoadSpillOpcodesArray[3][SOK_LastOpcodeSpill] =
+ const unsigned LoadSpillOpcodesArray[3][SOK_LastOpcodeSpill] =
LoadOpcodesForSpill;
void StoreRegToStackSlot(MachineFunction &MF, unsigned SrcReg, bool isKill,
@@ -246,17 +246,17 @@ class PPCInstrInfo : public PPCGenInstrInfo {
unsigned getSpillTarget() const;
const unsigned *getStoreOpcodesForSpillArray() const;
const unsigned *getLoadOpcodesForSpillArray() const;
- unsigned getSpillIndex(const TargetRegisterClass *RC) const;
+ unsigned getSpillIndex(const TargetRegisterClass *RC) const;
int16_t getFMAOpIdxInfo(unsigned Opcode) const;
void reassociateFMA(MachineInstr &Root, MachineCombinerPattern Pattern,
SmallVectorImpl<MachineInstr *> &InsInstrs,
SmallVectorImpl<MachineInstr *> &DelInstrs,
DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const;
- bool isLoadFromConstantPool(MachineInstr *I) const;
- Register
- generateLoadForNewConst(unsigned Idx, MachineInstr *MI, Type *Ty,
- SmallVectorImpl<MachineInstr *> &InsInstrs) const;
- const Constant *getConstantFromConstantPool(MachineInstr *I) const;
+ bool isLoadFromConstantPool(MachineInstr *I) const;
+ Register
+ generateLoadForNewConst(unsigned Idx, MachineInstr *MI, Type *Ty,
+ SmallVectorImpl<MachineInstr *> &InsInstrs) const;
+ const Constant *getConstantFromConstantPool(MachineInstr *I) const;
virtual void anchor();
protected:
@@ -291,10 +291,10 @@ public:
}
static bool isSameClassPhysRegCopy(unsigned Opcode) {
- unsigned CopyOpcodes[] = {PPC::OR, PPC::OR8, PPC::FMR,
- PPC::VOR, PPC::XXLOR, PPC::XXLORf,
- PPC::XSCPSGNDP, PPC::MCRF, PPC::CROR,
- PPC::EVOR, -1U};
+ unsigned CopyOpcodes[] = {PPC::OR, PPC::OR8, PPC::FMR,
+ PPC::VOR, PPC::XXLOR, PPC::XXLORf,
+ PPC::XSCPSGNDP, PPC::MCRF, PPC::CROR,
+ PPC::EVOR, -1U};
for (int i = 0; CopyOpcodes[i] != -1U; i++)
if (Opcode == CopyOpcodes[i])
return true;
@@ -348,30 +348,30 @@ public:
/// chain ending in \p Root. All potential patterns are output in the \p
/// P array.
bool getFMAPatterns(MachineInstr &Root,
- SmallVectorImpl<MachineCombinerPattern> &P,
- bool DoRegPressureReduce) const;
+ SmallVectorImpl<MachineCombinerPattern> &P,
+ bool DoRegPressureReduce) const;
/// Return true when there is potentially a faster code sequence
/// for an instruction chain ending in <Root>. All potential patterns are
/// output in the <Pattern> array.
- bool getMachineCombinerPatterns(MachineInstr &Root,
- SmallVectorImpl<MachineCombinerPattern> &P,
- bool DoRegPressureReduce) const override;
-
- /// On PowerPC, we leverage machine combiner pass to reduce register pressure
- /// when the register pressure is high for one BB.
- /// Return true if register pressure for \p MBB is high and ABI is supported
- /// to reduce register pressure. Otherwise return false.
- bool
- shouldReduceRegisterPressure(MachineBasicBlock *MBB,
- RegisterClassInfo *RegClassInfo) const override;
-
- /// Fixup the placeholders we put in genAlternativeCodeSequence() for
- /// MachineCombiner.
- void
- finalizeInsInstrs(MachineInstr &Root, MachineCombinerPattern &P,
- SmallVectorImpl<MachineInstr *> &InsInstrs) const override;
-
+ bool getMachineCombinerPatterns(MachineInstr &Root,
+ SmallVectorImpl<MachineCombinerPattern> &P,
+ bool DoRegPressureReduce) const override;
+
+ /// On PowerPC, we leverage machine combiner pass to reduce register pressure
+ /// when the register pressure is high for one BB.
+ /// Return true if register pressure for \p MBB is high and ABI is supported
+ /// to reduce register pressure. Otherwise return false.
+ bool
+ shouldReduceRegisterPressure(MachineBasicBlock *MBB,
+ RegisterClassInfo *RegClassInfo) const override;
+
+ /// Fixup the placeholders we put in genAlternativeCodeSequence() for
+ /// MachineCombiner.
+ void
+ finalizeInsInstrs(MachineInstr &Root, MachineCombinerPattern &P,
+ SmallVectorImpl<MachineInstr *> &InsInstrs) const override;
+
bool isAssociativeAndCommutative(const MachineInstr &Inst) const override;
/// On PowerPC, we try to reassociate FMA chain which will increase
@@ -503,18 +503,18 @@ public:
// Predication support.
bool isPredicated(const MachineInstr &MI) const override;
- bool isSchedulingBoundary(const MachineInstr &MI,
- const MachineBasicBlock *MBB,
- const MachineFunction &MF) const override;
-
+ bool isSchedulingBoundary(const MachineInstr &MI,
+ const MachineBasicBlock *MBB,
+ const MachineFunction &MF) const override;
+
bool PredicateInstruction(MachineInstr &MI,
ArrayRef<MachineOperand> Pred) const override;
bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
ArrayRef<MachineOperand> Pred2) const override;
- bool ClobbersPredicate(MachineInstr &MI, std::vector<MachineOperand> &Pred,
- bool SkipDead) const override;
+ bool ClobbersPredicate(MachineInstr &MI, std::vector<MachineOperand> &Pred,
+ bool SkipDead) const override;
// Comparison optimization.
@@ -534,20 +534,20 @@ public:
int64_t &Offset, unsigned &Width,
const TargetRegisterInfo *TRI) const;
- /// Get the base operand and byte offset of an instruction that reads/writes
- /// memory.
- bool getMemOperandsWithOffsetWidth(
- const MachineInstr &LdSt,
- SmallVectorImpl<const MachineOperand *> &BaseOps, int64_t &Offset,
- bool &OffsetIsScalable, unsigned &Width,
- const TargetRegisterInfo *TRI) const override;
-
- /// Returns true if the two given memory operations should be scheduled
- /// adjacent.
- bool shouldClusterMemOps(ArrayRef<const MachineOperand *> BaseOps1,
- ArrayRef<const MachineOperand *> BaseOps2,
- unsigned NumLoads, unsigned NumBytes) const override;
-
+ /// Get the base operand and byte offset of an instruction that reads/writes
+ /// memory.
+ bool getMemOperandsWithOffsetWidth(
+ const MachineInstr &LdSt,
+ SmallVectorImpl<const MachineOperand *> &BaseOps, int64_t &Offset,
+ bool &OffsetIsScalable, unsigned &Width,
+ const TargetRegisterInfo *TRI) const override;
+
+ /// Returns true if the two given memory operations should be scheduled
+ /// adjacent.
+ bool shouldClusterMemOps(ArrayRef<const MachineOperand *> BaseOps1,
+ ArrayRef<const MachineOperand *> BaseOps2,
+ unsigned NumLoads, unsigned NumBytes) const override;
+
/// Return true if two MIs access different memory addresses and false
/// otherwise
bool
@@ -605,7 +605,7 @@ public:
bool convertToImmediateForm(MachineInstr &MI,
MachineInstr **KilledDef = nullptr) const;
bool foldFrameOffset(MachineInstr &MI) const;
- bool combineRLWINM(MachineInstr &MI, MachineInstr **ToErase = nullptr) const;
+ bool combineRLWINM(MachineInstr &MI, MachineInstr **ToErase = nullptr) const;
bool isADDIInstrEligibleForFolding(MachineInstr &ADDIMI, int64_t &Imm) const;
bool isADDInstrEligibleForFolding(MachineInstr &ADDMI) const;
bool isImmInstrEligibleForFolding(MachineInstr &MI, unsigned &BaseReg,
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrInfo.td b/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrInfo.td
index a063963821..724af23542 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrInfo.td
@@ -74,9 +74,9 @@ def SDT_PPCcondbr : SDTypeProfile<0, 3, [
SDTCisVT<0, i32>, SDTCisVT<2, OtherVT>
]>;
-def SDT_PPCFtsqrt : SDTypeProfile<1, 1, [
- SDTCisVT<0, i32>]>;
-
+def SDT_PPCFtsqrt : SDTypeProfile<1, 1, [
+ SDTCisVT<0, i32>]>;
+
def SDT_PPClbrx : SDTypeProfile<1, 2, [
SDTCisInt<0>, SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>
]>;
@@ -127,8 +127,8 @@ def SDT_PPCFPMinMax : SDTypeProfile<1, 2, [
def PPCfre : SDNode<"PPCISD::FRE", SDTFPUnaryOp, []>;
def PPCfrsqrte: SDNode<"PPCISD::FRSQRTE", SDTFPUnaryOp, []>;
-def PPCfsqrt : SDNode<"PPCISD::FSQRT", SDTFPUnaryOp, []>;
-def PPCftsqrt : SDNode<"PPCISD::FTSQRT", SDT_PPCFtsqrt,[]>;
+def PPCfsqrt : SDNode<"PPCISD::FSQRT", SDTFPUnaryOp, []>;
+def PPCftsqrt : SDNode<"PPCISD::FTSQRT", SDT_PPCFtsqrt,[]>;
def PPCfcfid : SDNode<"PPCISD::FCFID", SDTFPUnaryOp, []>;
def PPCfcfidu : SDNode<"PPCISD::FCFIDU", SDTFPUnaryOp, []>;
@@ -139,28 +139,28 @@ def PPCfctiwz : SDNode<"PPCISD::FCTIWZ", SDTFPUnaryOp, []>;
def PPCfctiduz: SDNode<"PPCISD::FCTIDUZ",SDTFPUnaryOp, []>;
def PPCfctiwuz: SDNode<"PPCISD::FCTIWUZ",SDTFPUnaryOp, []>;
-def PPCstrict_fcfid : SDNode<"PPCISD::STRICT_FCFID",
- SDTFPUnaryOp, [SDNPHasChain]>;
-def PPCstrict_fcfidu : SDNode<"PPCISD::STRICT_FCFIDU",
- SDTFPUnaryOp, [SDNPHasChain]>;
-def PPCstrict_fcfids : SDNode<"PPCISD::STRICT_FCFIDS",
- SDTFPRoundOp, [SDNPHasChain]>;
-def PPCstrict_fcfidus : SDNode<"PPCISD::STRICT_FCFIDUS",
- SDTFPRoundOp, [SDNPHasChain]>;
-
-def PPCany_fcfid : PatFrags<(ops node:$op),
- [(PPCfcfid node:$op),
- (PPCstrict_fcfid node:$op)]>;
-def PPCany_fcfidu : PatFrags<(ops node:$op),
- [(PPCfcfidu node:$op),
- (PPCstrict_fcfidu node:$op)]>;
-def PPCany_fcfids : PatFrags<(ops node:$op),
- [(PPCfcfids node:$op),
- (PPCstrict_fcfids node:$op)]>;
-def PPCany_fcfidus : PatFrags<(ops node:$op),
- [(PPCfcfidus node:$op),
- (PPCstrict_fcfidus node:$op)]>;
-
+def PPCstrict_fcfid : SDNode<"PPCISD::STRICT_FCFID",
+ SDTFPUnaryOp, [SDNPHasChain]>;
+def PPCstrict_fcfidu : SDNode<"PPCISD::STRICT_FCFIDU",
+ SDTFPUnaryOp, [SDNPHasChain]>;
+def PPCstrict_fcfids : SDNode<"PPCISD::STRICT_FCFIDS",
+ SDTFPRoundOp, [SDNPHasChain]>;
+def PPCstrict_fcfidus : SDNode<"PPCISD::STRICT_FCFIDUS",
+ SDTFPRoundOp, [SDNPHasChain]>;
+
+def PPCany_fcfid : PatFrags<(ops node:$op),
+ [(PPCfcfid node:$op),
+ (PPCstrict_fcfid node:$op)]>;
+def PPCany_fcfidu : PatFrags<(ops node:$op),
+ [(PPCfcfidu node:$op),
+ (PPCstrict_fcfidu node:$op)]>;
+def PPCany_fcfids : PatFrags<(ops node:$op),
+ [(PPCfcfids node:$op),
+ (PPCstrict_fcfids node:$op)]>;
+def PPCany_fcfidus : PatFrags<(ops node:$op),
+ [(PPCfcfidus node:$op),
+ (PPCstrict_fcfidus node:$op)]>;
+
def PPCcv_fp_to_uint_in_vsr:
SDNode<"PPCISD::FP_TO_UINT_IN_VSR", SDT_PPCcv_fp_to_int, []>;
def PPCcv_fp_to_sint_in_vsr:
@@ -187,12 +187,12 @@ def PPCmffs : SDNode<"PPCISD::MFFS",
// Perform FADD in round-to-zero mode.
def PPCfaddrtz: SDNode<"PPCISD::FADDRTZ", SDTFPBinOp, []>;
-def PPCstrict_faddrtz: SDNode<"PPCISD::STRICT_FADDRTZ", SDTFPBinOp,
- [SDNPHasChain]>;
+def PPCstrict_faddrtz: SDNode<"PPCISD::STRICT_FADDRTZ", SDTFPBinOp,
+ [SDNPHasChain]>;
-def PPCany_faddrtz: PatFrags<(ops node:$lhs, node:$rhs),
- [(PPCfaddrtz node:$lhs, node:$rhs),
- (PPCstrict_faddrtz node:$lhs, node:$rhs)]>;
+def PPCany_faddrtz: PatFrags<(ops node:$lhs, node:$rhs),
+ [(PPCfaddrtz node:$lhs, node:$rhs),
+ (PPCstrict_faddrtz node:$lhs, node:$rhs)]>;
def PPCfsel : SDNode<"PPCISD::FSEL",
// Type constraint for fsel.
@@ -227,7 +227,7 @@ def PPCaddiTlsldLAddr : SDNode<"PPCISD::ADDI_TLSLD_L_ADDR",
SDTCisSameAs<0, 3>, SDTCisInt<0> ]>>;
def PPCaddisDtprelHA : SDNode<"PPCISD::ADDIS_DTPREL_HA", SDTIntBinOp>;
def PPCaddiDtprelL : SDNode<"PPCISD::ADDI_DTPREL_L", SDTIntBinOp>;
-def PPCpaddiDtprel : SDNode<"PPCISD::PADDI_DTPREL", SDTIntBinOp>;
+def PPCpaddiDtprel : SDNode<"PPCISD::PADDI_DTPREL", SDTIntBinOp>;
def PPCvperm : SDNode<"PPCISD::VPERM", SDT_PPCvperm, []>;
def PPCxxsplt : SDNode<"PPCISD::XXSPLT", SDT_PPCVecSplat, []>;
@@ -248,28 +248,28 @@ def PPCfnmsub : SDNode<"PPCISD::FNMSUB" , SDTFPTernaryOp>;
def PPCextswsli : SDNode<"PPCISD::EXTSWSLI" , SDT_PPCextswsli>;
-def PPCstrict_fctidz : SDNode<"PPCISD::STRICT_FCTIDZ",
- SDTFPUnaryOp, [SDNPHasChain]>;
-def PPCstrict_fctiwz : SDNode<"PPCISD::STRICT_FCTIWZ",
- SDTFPUnaryOp, [SDNPHasChain]>;
-def PPCstrict_fctiduz : SDNode<"PPCISD::STRICT_FCTIDUZ",
- SDTFPUnaryOp, [SDNPHasChain]>;
-def PPCstrict_fctiwuz : SDNode<"PPCISD::STRICT_FCTIWUZ",
- SDTFPUnaryOp, [SDNPHasChain]>;
-
-def PPCany_fctidz : PatFrags<(ops node:$op),
- [(PPCstrict_fctidz node:$op),
- (PPCfctidz node:$op)]>;
-def PPCany_fctiwz : PatFrags<(ops node:$op),
- [(PPCstrict_fctiwz node:$op),
- (PPCfctiwz node:$op)]>;
-def PPCany_fctiduz : PatFrags<(ops node:$op),
- [(PPCstrict_fctiduz node:$op),
- (PPCfctiduz node:$op)]>;
-def PPCany_fctiwuz : PatFrags<(ops node:$op),
- [(PPCstrict_fctiwuz node:$op),
- (PPCfctiwuz node:$op)]>;
-
+def PPCstrict_fctidz : SDNode<"PPCISD::STRICT_FCTIDZ",
+ SDTFPUnaryOp, [SDNPHasChain]>;
+def PPCstrict_fctiwz : SDNode<"PPCISD::STRICT_FCTIWZ",
+ SDTFPUnaryOp, [SDNPHasChain]>;
+def PPCstrict_fctiduz : SDNode<"PPCISD::STRICT_FCTIDUZ",
+ SDTFPUnaryOp, [SDNPHasChain]>;
+def PPCstrict_fctiwuz : SDNode<"PPCISD::STRICT_FCTIWUZ",
+ SDTFPUnaryOp, [SDNPHasChain]>;
+
+def PPCany_fctidz : PatFrags<(ops node:$op),
+ [(PPCstrict_fctidz node:$op),
+ (PPCfctidz node:$op)]>;
+def PPCany_fctiwz : PatFrags<(ops node:$op),
+ [(PPCstrict_fctiwz node:$op),
+ (PPCfctiwz node:$op)]>;
+def PPCany_fctiduz : PatFrags<(ops node:$op),
+ [(PPCstrict_fctiduz node:$op),
+ (PPCfctiduz node:$op)]>;
+def PPCany_fctiwuz : PatFrags<(ops node:$op),
+ [(PPCstrict_fctiwuz node:$op),
+ (PPCfctiwuz node:$op)]>;
+
// Move 2 i64 values into a VSX register
def PPCbuild_fp128: SDNode<"PPCISD::BUILD_FP128",
SDTypeProfile<1, 2,
@@ -340,7 +340,7 @@ def PPCrfebb : SDNode<"PPCISD::RFEBB", SDT_PPCsc,
[SDNPHasChain, SDNPSideEffect]>;
def PPCvcmp : SDNode<"PPCISD::VCMP" , SDT_PPCvcmp, []>;
-def PPCvcmp_rec : SDNode<"PPCISD::VCMP_rec", SDT_PPCvcmp, [SDNPOutGlue]>;
+def PPCvcmp_rec : SDNode<"PPCISD::VCMP_rec", SDT_PPCvcmp, [SDNPOutGlue]>;
def PPCcondbranch : SDNode<"PPCISD::COND_BRANCH", SDT_PPCcondbr,
[SDNPHasChain, SDNPOptInGlue]>;
@@ -372,10 +372,10 @@ def PPCprobedalloca : SDNode<"PPCISD::PROBED_ALLOCA", SDTDynOp, [SDNPHasChain]>;
// PC Relative Specific Nodes
def PPCmatpcreladdr : SDNode<"PPCISD::MAT_PCREL_ADDR", SDTIntUnaryOp, []>;
-def PPCtlsdynamatpcreladdr : SDNode<"PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR",
- SDTIntUnaryOp, []>;
-def PPCtlslocalexecmataddr : SDNode<"PPCISD::TLS_LOCAL_EXEC_MAT_ADDR",
- SDTIntUnaryOp, []>;
+def PPCtlsdynamatpcreladdr : SDNode<"PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR",
+ SDTIntUnaryOp, []>;
+def PPCtlslocalexecmataddr : SDNode<"PPCISD::TLS_LOCAL_EXEC_MAT_ADDR",
+ SDTIntUnaryOp, []>;
//===----------------------------------------------------------------------===//
// PowerPC specific transformation functions and pattern fragments.
@@ -495,41 +495,41 @@ def imm64ZExt32 : Operand<i64>, ImmLeaf<i64, [{
return isUInt<32>(Imm);
}]>;
-// This is a somewhat weaker condition than actually checking for 4-byte
-// alignment. It is simply checking that the displacement can be represented
-// as an immediate that is a multiple of 4 (i.e. the requirements for DS-Form
-// instructions).
-// But some r+i load/store instructions (such as LD, STD, LDU, etc.) that require
+// This is a somewhat weaker condition than actually checking for 4-byte
+// alignment. It is simply checking that the displacement can be represented
+// as an immediate that is a multiple of 4 (i.e. the requirements for DS-Form
+// instructions).
+// But some r+i load/store instructions (such as LD, STD, LDU, etc.) that require
// restricted memrix (4-aligned) constants are alignment sensitive. If these
// offsets are hidden behind TOC entries than the values of the lower-order
// bits cannot be checked directly. As a result, we need to also incorporate
// an alignment check into the relevant patterns.
-def DSFormLoad : PatFrag<(ops node:$ptr), (load node:$ptr), [{
- return isOffsetMultipleOf(N, 4) || cast<LoadSDNode>(N)->getAlignment() >= 4;
+def DSFormLoad : PatFrag<(ops node:$ptr), (load node:$ptr), [{
+ return isOffsetMultipleOf(N, 4) || cast<LoadSDNode>(N)->getAlignment() >= 4;
}]>;
-def DSFormStore : PatFrag<(ops node:$val, node:$ptr),
+def DSFormStore : PatFrag<(ops node:$val, node:$ptr),
(store node:$val, node:$ptr), [{
- return isOffsetMultipleOf(N, 4) || cast<StoreSDNode>(N)->getAlignment() >= 4;
+ return isOffsetMultipleOf(N, 4) || cast<StoreSDNode>(N)->getAlignment() >= 4;
}]>;
-def DSFormSextLoadi32 : PatFrag<(ops node:$ptr), (sextloadi32 node:$ptr), [{
- return isOffsetMultipleOf(N, 4) || cast<LoadSDNode>(N)->getAlignment() >= 4;
+def DSFormSextLoadi32 : PatFrag<(ops node:$ptr), (sextloadi32 node:$ptr), [{
+ return isOffsetMultipleOf(N, 4) || cast<LoadSDNode>(N)->getAlignment() >= 4;
}]>;
-def DSFormPreStore : PatFrag<
+def DSFormPreStore : PatFrag<
(ops node:$val, node:$base, node:$offset),
(pre_store node:$val, node:$base, node:$offset), [{
- return isOffsetMultipleOf(N, 4) || cast<StoreSDNode>(N)->getAlignment() >= 4;
+ return isOffsetMultipleOf(N, 4) || cast<StoreSDNode>(N)->getAlignment() >= 4;
}]>;
-def NonDSFormLoad : PatFrag<(ops node:$ptr), (load node:$ptr), [{
- return cast<LoadSDNode>(N)->getAlignment() < 4 && !isOffsetMultipleOf(N, 4);
+def NonDSFormLoad : PatFrag<(ops node:$ptr), (load node:$ptr), [{
+ return cast<LoadSDNode>(N)->getAlignment() < 4 && !isOffsetMultipleOf(N, 4);
}]>;
-def NonDSFormStore : PatFrag<(ops node:$val, node:$ptr),
+def NonDSFormStore : PatFrag<(ops node:$val, node:$ptr),
(store node:$val, node:$ptr), [{
- return cast<StoreSDNode>(N)->getAlignment() < 4 && !isOffsetMultipleOf(N, 4);
+ return cast<StoreSDNode>(N)->getAlignment() < 4 && !isOffsetMultipleOf(N, 4);
}]>;
-def NonDSFormSextLoadi32 : PatFrag<(ops node:$ptr), (sextloadi32 node:$ptr), [{
- return cast<LoadSDNode>(N)->getAlignment() < 4 && !isOffsetMultipleOf(N, 4);
+def NonDSFormSextLoadi32 : PatFrag<(ops node:$ptr), (sextloadi32 node:$ptr), [{
+ return cast<LoadSDNode>(N)->getAlignment() < 4 && !isOffsetMultipleOf(N, 4);
}]>;
// This is a somewhat weaker condition than actually checking for 16-byte
@@ -670,7 +670,7 @@ def PPCU1ImmAsmOperand : AsmOperandClass {
def u1imm : Operand<i32> {
let PrintMethod = "printU1ImmOperand";
let ParserMatchClass = PPCU1ImmAsmOperand;
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def PPCU2ImmAsmOperand : AsmOperandClass {
@@ -680,7 +680,7 @@ def PPCU2ImmAsmOperand : AsmOperandClass {
def u2imm : Operand<i32> {
let PrintMethod = "printU2ImmOperand";
let ParserMatchClass = PPCU2ImmAsmOperand;
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def PPCATBitsAsHintAsmOperand : AsmOperandClass {
@@ -690,7 +690,7 @@ def PPCATBitsAsHintAsmOperand : AsmOperandClass {
def atimm : Operand<i32> {
let PrintMethod = "printATBitsAsHint";
let ParserMatchClass = PPCATBitsAsHintAsmOperand;
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def PPCU3ImmAsmOperand : AsmOperandClass {
@@ -700,7 +700,7 @@ def PPCU3ImmAsmOperand : AsmOperandClass {
def u3imm : Operand<i32> {
let PrintMethod = "printU3ImmOperand";
let ParserMatchClass = PPCU3ImmAsmOperand;
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def PPCU4ImmAsmOperand : AsmOperandClass {
@@ -710,7 +710,7 @@ def PPCU4ImmAsmOperand : AsmOperandClass {
def u4imm : Operand<i32> {
let PrintMethod = "printU4ImmOperand";
let ParserMatchClass = PPCU4ImmAsmOperand;
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def PPCS5ImmAsmOperand : AsmOperandClass {
let Name = "S5Imm"; let PredicateMethod = "isS5Imm";
@@ -720,7 +720,7 @@ def s5imm : Operand<i32> {
let PrintMethod = "printS5ImmOperand";
let ParserMatchClass = PPCS5ImmAsmOperand;
let DecoderMethod = "decodeSImmOperand<5>";
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def PPCU5ImmAsmOperand : AsmOperandClass {
let Name = "U5Imm"; let PredicateMethod = "isU5Imm";
@@ -730,7 +730,7 @@ def u5imm : Operand<i32> {
let PrintMethod = "printU5ImmOperand";
let ParserMatchClass = PPCU5ImmAsmOperand;
let DecoderMethod = "decodeUImmOperand<5>";
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def PPCU6ImmAsmOperand : AsmOperandClass {
let Name = "U6Imm"; let PredicateMethod = "isU6Imm";
@@ -740,7 +740,7 @@ def u6imm : Operand<i32> {
let PrintMethod = "printU6ImmOperand";
let ParserMatchClass = PPCU6ImmAsmOperand;
let DecoderMethod = "decodeUImmOperand<6>";
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def PPCU7ImmAsmOperand : AsmOperandClass {
let Name = "U7Imm"; let PredicateMethod = "isU7Imm";
@@ -750,7 +750,7 @@ def u7imm : Operand<i32> {
let PrintMethod = "printU7ImmOperand";
let ParserMatchClass = PPCU7ImmAsmOperand;
let DecoderMethod = "decodeUImmOperand<7>";
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def PPCU8ImmAsmOperand : AsmOperandClass {
let Name = "U8Imm"; let PredicateMethod = "isU8Imm";
@@ -760,7 +760,7 @@ def u8imm : Operand<i32> {
let PrintMethod = "printU8ImmOperand";
let ParserMatchClass = PPCU8ImmAsmOperand;
let DecoderMethod = "decodeUImmOperand<8>";
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def PPCU10ImmAsmOperand : AsmOperandClass {
let Name = "U10Imm"; let PredicateMethod = "isU10Imm";
@@ -770,7 +770,7 @@ def u10imm : Operand<i32> {
let PrintMethod = "printU10ImmOperand";
let ParserMatchClass = PPCU10ImmAsmOperand;
let DecoderMethod = "decodeUImmOperand<10>";
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def PPCU12ImmAsmOperand : AsmOperandClass {
let Name = "U12Imm"; let PredicateMethod = "isU12Imm";
@@ -780,7 +780,7 @@ def u12imm : Operand<i32> {
let PrintMethod = "printU12ImmOperand";
let ParserMatchClass = PPCU12ImmAsmOperand;
let DecoderMethod = "decodeUImmOperand<12>";
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def PPCS16ImmAsmOperand : AsmOperandClass {
let Name = "S16Imm"; let PredicateMethod = "isS16Imm";
@@ -791,7 +791,7 @@ def s16imm : Operand<i32> {
let EncoderMethod = "getImm16Encoding";
let ParserMatchClass = PPCS16ImmAsmOperand;
let DecoderMethod = "decodeSImmOperand<16>";
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def PPCU16ImmAsmOperand : AsmOperandClass {
let Name = "U16Imm"; let PredicateMethod = "isU16Imm";
@@ -802,7 +802,7 @@ def u16imm : Operand<i32> {
let EncoderMethod = "getImm16Encoding";
let ParserMatchClass = PPCU16ImmAsmOperand;
let DecoderMethod = "decodeUImmOperand<16>";
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def PPCS17ImmAsmOperand : AsmOperandClass {
let Name = "S17Imm"; let PredicateMethod = "isS17Imm";
@@ -816,7 +816,7 @@ def s17imm : Operand<i32> {
let EncoderMethod = "getImm16Encoding";
let ParserMatchClass = PPCS17ImmAsmOperand;
let DecoderMethod = "decodeSImmOperand<16>";
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def PPCS34ImmAsmOperand : AsmOperandClass {
let Name = "S34Imm";
@@ -825,18 +825,18 @@ def PPCS34ImmAsmOperand : AsmOperandClass {
}
def s34imm : Operand<i64> {
let PrintMethod = "printS34ImmOperand";
- let EncoderMethod = "getImm34EncodingNoPCRel";
+ let EncoderMethod = "getImm34EncodingNoPCRel";
let ParserMatchClass = PPCS34ImmAsmOperand;
let DecoderMethod = "decodeSImmOperand<34>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def s34imm_pcrel : Operand<i64> {
- let PrintMethod = "printS34ImmOperand";
- let EncoderMethod = "getImm34EncodingPCRel";
- let ParserMatchClass = PPCS34ImmAsmOperand;
- let DecoderMethod = "decodeSImmOperand<34>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
+ let OperandType = "OPERAND_IMMEDIATE";
+}
+def s34imm_pcrel : Operand<i64> {
+ let PrintMethod = "printS34ImmOperand";
+ let EncoderMethod = "getImm34EncodingPCRel";
+ let ParserMatchClass = PPCS34ImmAsmOperand;
+ let DecoderMethod = "decodeSImmOperand<34>";
+ let OperandType = "OPERAND_IMMEDIATE";
+}
def PPCImmZeroAsmOperand : AsmOperandClass {
let Name = "ImmZero";
let PredicateMethod = "isImmZero";
@@ -846,7 +846,7 @@ def immZero : Operand<i32> {
let PrintMethod = "printImmZeroOperand";
let ParserMatchClass = PPCImmZeroAsmOperand;
let DecoderMethod = "decodeImmZeroOperand";
- let OperandType = "OPERAND_IMMEDIATE";
+ let OperandType = "OPERAND_IMMEDIATE";
}
def fpimm0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(+0.0); }]>;
@@ -992,47 +992,47 @@ def memri : Operand<iPTR> {
let MIOperandInfo = (ops dispRI:$imm, ptr_rc_nor0:$reg);
let EncoderMethod = "getMemRIEncoding";
let DecoderMethod = "decodeMemRIOperands";
- let OperandType = "OPERAND_MEMORY";
+ let OperandType = "OPERAND_MEMORY";
}
def memrr : Operand<iPTR> {
let PrintMethod = "printMemRegReg";
let MIOperandInfo = (ops ptr_rc_nor0:$ptrreg, ptr_rc_idx:$offreg);
- let OperandType = "OPERAND_MEMORY";
+ let OperandType = "OPERAND_MEMORY";
}
def memrix : Operand<iPTR> { // memri where the imm is 4-aligned.
let PrintMethod = "printMemRegImm";
let MIOperandInfo = (ops dispRIX:$imm, ptr_rc_nor0:$reg);
let EncoderMethod = "getMemRIXEncoding";
let DecoderMethod = "decodeMemRIXOperands";
- let OperandType = "OPERAND_MEMORY";
+ let OperandType = "OPERAND_MEMORY";
}
def memrix16 : Operand<iPTR> { // memri, imm is 16-aligned, 12-bit, Inst{16:27}
let PrintMethod = "printMemRegImm";
let MIOperandInfo = (ops dispRIX16:$imm, ptr_rc_nor0:$reg);
let EncoderMethod = "getMemRIX16Encoding";
let DecoderMethod = "decodeMemRIX16Operands";
- let OperandType = "OPERAND_MEMORY";
+ let OperandType = "OPERAND_MEMORY";
}
def spe8dis : Operand<iPTR> { // SPE displacement where the imm is 8-aligned.
let PrintMethod = "printMemRegImm";
let MIOperandInfo = (ops dispSPE8:$imm, ptr_rc_nor0:$reg);
let EncoderMethod = "getSPE8DisEncoding";
let DecoderMethod = "decodeSPE8Operands";
- let OperandType = "OPERAND_MEMORY";
+ let OperandType = "OPERAND_MEMORY";
}
def spe4dis : Operand<iPTR> { // SPE displacement where the imm is 4-aligned.
let PrintMethod = "printMemRegImm";
let MIOperandInfo = (ops dispSPE4:$imm, ptr_rc_nor0:$reg);
let EncoderMethod = "getSPE4DisEncoding";
let DecoderMethod = "decodeSPE4Operands";
- let OperandType = "OPERAND_MEMORY";
+ let OperandType = "OPERAND_MEMORY";
}
def spe2dis : Operand<iPTR> { // SPE displacement where the imm is 2-aligned.
let PrintMethod = "printMemRegImm";
let MIOperandInfo = (ops dispSPE2:$imm, ptr_rc_nor0:$reg);
let EncoderMethod = "getSPE2DisEncoding";
let DecoderMethod = "decodeSPE2Operands";
- let OperandType = "OPERAND_MEMORY";
+ let OperandType = "OPERAND_MEMORY";
}
// A single-register address. This is used with the SjLj
@@ -1040,7 +1040,7 @@ def spe2dis : Operand<iPTR> { // SPE displacement where the imm is 2-aligned.
// G8RC_NOX0 registers.
def memr : Operand<iPTR> {
let MIOperandInfo = (ops ptr_rc_nor0:$ptrreg);
- let OperandType = "OPERAND_MEMORY";
+ let OperandType = "OPERAND_MEMORY";
}
def PPCTLSRegOperand : AsmOperandClass {
let Name = "TLSReg"; let PredicateMethod = "isTLSReg";
@@ -1066,13 +1066,13 @@ def pred : Operand<OtherVT> {
// Define PowerPC specific addressing mode.
// d-form
-def iaddr : ComplexPattern<iPTR, 2, "SelectAddrImm", [], []>; // "stb"
+def iaddr : ComplexPattern<iPTR, 2, "SelectAddrImm", [], []>; // "stb"
// ds-form
-def iaddrX4 : ComplexPattern<iPTR, 2, "SelectAddrImmX4", [], []>; // "std"
+def iaddrX4 : ComplexPattern<iPTR, 2, "SelectAddrImmX4", [], []>; // "std"
// dq-form
-def iaddrX16 : ComplexPattern<iPTR, 2, "SelectAddrImmX16", [], []>; // "stxv"
-// 8LS:d-form
-def iaddrX34 : ComplexPattern<iPTR, 2, "SelectAddrImmX34", [], []>; // "pstxvp"
+def iaddrX16 : ComplexPattern<iPTR, 2, "SelectAddrImmX16", [], []>; // "stxv"
+// 8LS:d-form
+def iaddrX34 : ComplexPattern<iPTR, 2, "SelectAddrImmX34", [], []>; // "pstxvp"
// Below forms are all x-form addressing mode, use three different ones so we
// can make a accurate check for x-form instructions in ISEL.
@@ -1118,12 +1118,12 @@ def HasExtDiv : Predicate<"Subtarget->hasExtDiv()">;
def IsISA3_0 : Predicate<"Subtarget->isISA3_0()">;
def HasFPU : Predicate<"Subtarget->hasFPU()">;
def PCRelativeMemops : Predicate<"Subtarget->hasPCRelativeMemops()">;
-def IsNotISA3_1 : Predicate<"!Subtarget->isISA3_1()">;
+def IsNotISA3_1 : Predicate<"!Subtarget->isISA3_1()">;
+
+// AIX assembler may not be modern enough to support some extended mne.
+def ModernAs: Predicate<"!Subtarget->isAIXABI() || Subtarget->HasModernAIXAs">,
+ AssemblerPredicate<(any_of (not AIXOS), FeatureModernAIXAs)>;
-// AIX assembler may not be modern enough to support some extended mne.
-def ModernAs: Predicate<"!Subtarget->isAIXABI() || Subtarget->HasModernAIXAs">,
- AssemblerPredicate<(any_of (not AIXOS), FeatureModernAIXAs)>;
-
//===----------------------------------------------------------------------===//
// PowerPC Multiclass Definitions.
@@ -1481,7 +1481,7 @@ def ADJCALLSTACKUP : PPCEmitTimePseudo<(outs), (ins u16imm:$amt1, u16imm:$amt2
"#ADJCALLSTACKUP $amt1 $amt2",
[(callseq_end timm:$amt1, timm:$amt2)]>;
}
-} // hasCtrlDep
+} // hasCtrlDep
let Defs = [R1], Uses = [R1] in
def DYNALLOC : PPCEmitTimePseudo<(outs gprc:$result), (ins gprc:$negsize, memri:$fpsi), "#DYNALLOC",
@@ -1607,9 +1607,9 @@ def SETRNDi : PPCCustomInserterPseudo<(outs f8rc:$FRT), (ins u2imm:$RND),
def SETRND : PPCCustomInserterPseudo<(outs f8rc:$FRT), (ins gprc:$in),
"#SETRND", [(set f64:$FRT, (int_ppc_setrnd gprc :$in))]>;
-
-def SETFLM : PPCCustomInserterPseudo<(outs f8rc:$FRT), (ins f8rc:$FLM),
- "#SETFLM", [(set f64:$FRT, (int_ppc_setflm f8rc:$FLM))]>;
+
+def SETFLM : PPCCustomInserterPseudo<(outs f8rc:$FRT), (ins f8rc:$FLM),
+ "#SETFLM", [(set f64:$FRT, (int_ppc_setflm f8rc:$FLM))]>;
}
let Defs = [LR] in
@@ -1659,12 +1659,12 @@ let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7 in {
def BCn : BForm_4<16, 4, 0, 0, (outs), (ins crbitrc:$bi, condbrtarget:$dst),
"bc 4, $bi, $dst">;
- let isReturn = 1, Uses = [LR, RM] in {
+ let isReturn = 1, Uses = [LR, RM] in {
def BCLR : XLForm_2_br2<19, 16, 12, 0, (outs), (ins crbitrc:$bi),
"bclr 12, $bi, 0", IIC_BrB, []>;
def BCLRn : XLForm_2_br2<19, 16, 4, 0, (outs), (ins crbitrc:$bi),
"bclr 4, $bi, 0", IIC_BrB, []>;
- }
+ }
}
let isReturn = 1, Defs = [CTR], Uses = [CTR, LR, RM] in {
@@ -1936,7 +1936,7 @@ def DCBZL : DCB_Form<1014, 1, (outs), (ins memrr:$dst), "dcbzl $dst",
IIC_LdStDCBF, [(int_ppc_dcbzl xoaddr:$dst)]>,
PPC970_DGroup_Single;
-def DCBF : DCB_Form_hint<86, (outs), (ins u3imm:$TH, memrr:$dst),
+def DCBF : DCB_Form_hint<86, (outs), (ins u3imm:$TH, memrr:$dst),
"dcbf $dst, $TH", IIC_LdStDCBF, []>,
PPC970_DGroup_Single;
@@ -2471,7 +2471,7 @@ let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
def STMW : DForm_1<47, (outs), (ins gprc:$rS, memri:$dst),
"stmw $rS, $dst", IIC_LdStLMW, []>;
-def SYNC : XForm_24_sync<31, 598, (outs), (ins u2imm:$L),
+def SYNC : XForm_24_sync<31, 598, (outs), (ins u2imm:$L),
"sync $L", IIC_LdStSync, []>;
let isCodeGenOnly = 1 in {
@@ -2666,26 +2666,26 @@ let isCompare = 1, hasSideEffects = 0 in {
}
}
let PPC970_Unit = 3, Predicates = [HasFPU] in { // FPU Operations.
-let isCompare = 1, mayRaiseFPException = 1, hasSideEffects = 0 in {
+let isCompare = 1, mayRaiseFPException = 1, hasSideEffects = 0 in {
def FCMPUS : XForm_17<63, 0, (outs crrc:$crD), (ins f4rc:$fA, f4rc:$fB),
"fcmpu $crD, $fA, $fB", IIC_FPCompare>;
- def FCMPOS : XForm_17<63, 32, (outs crrc:$crD), (ins f4rc:$fA, f4rc:$fB),
- "fcmpo $crD, $fA, $fB", IIC_FPCompare>;
- let Interpretation64Bit = 1, isCodeGenOnly = 1 in {
- def FCMPUD : XForm_17<63, 0, (outs crrc:$crD), (ins f8rc:$fA, f8rc:$fB),
- "fcmpu $crD, $fA, $fB", IIC_FPCompare>;
- def FCMPOD : XForm_17<63, 32, (outs crrc:$crD), (ins f8rc:$fA, f8rc:$fB),
- "fcmpo $crD, $fA, $fB", IIC_FPCompare>;
- }
+ def FCMPOS : XForm_17<63, 32, (outs crrc:$crD), (ins f4rc:$fA, f4rc:$fB),
+ "fcmpo $crD, $fA, $fB", IIC_FPCompare>;
+ let Interpretation64Bit = 1, isCodeGenOnly = 1 in {
+ def FCMPUD : XForm_17<63, 0, (outs crrc:$crD), (ins f8rc:$fA, f8rc:$fB),
+ "fcmpu $crD, $fA, $fB", IIC_FPCompare>;
+ def FCMPOD : XForm_17<63, 32, (outs crrc:$crD), (ins f8rc:$fA, f8rc:$fB),
+ "fcmpo $crD, $fA, $fB", IIC_FPCompare>;
+ }
}
def FTDIV: XForm_17<63, 128, (outs crrc:$crD), (ins f8rc:$fA, f8rc:$fB),
"ftdiv $crD, $fA, $fB", IIC_FPCompare>;
def FTSQRT: XForm_17a<63, 160, (outs crrc:$crD), (ins f8rc:$fB),
- "ftsqrt $crD, $fB", IIC_FPCompare,
- [(set i32:$crD, (PPCftsqrt f64:$fB))]>;
+ "ftsqrt $crD, $fB", IIC_FPCompare,
+ [(set i32:$crD, (PPCftsqrt f64:$fB))]>;
-let mayRaiseFPException = 1, hasSideEffects = 0 in {
+let mayRaiseFPException = 1, hasSideEffects = 0 in {
let Interpretation64Bit = 1, isCodeGenOnly = 1 in
defm FRIND : XForm_26r<63, 392, (outs f8rc:$frD), (ins f8rc:$frB),
"frin", "$frD, $frB", IIC_FPGeneral,
@@ -2715,23 +2715,23 @@ let mayRaiseFPException = 1, hasSideEffects = 0 in {
defm FRIMS : XForm_26r<63, 488, (outs f4rc:$frD), (ins f4rc:$frB),
"frim", "$frD, $frB", IIC_FPGeneral,
[(set f32:$frD, (any_ffloor f32:$frB))]>;
-}
-
-let Uses = [RM], mayRaiseFPException = 1, hasSideEffects = 0 in {
- defm FCTIW : XForm_26r<63, 14, (outs f8rc:$frD), (ins f8rc:$frB),
- "fctiw", "$frD, $frB", IIC_FPGeneral,
- []>;
- defm FCTIWU : XForm_26r<63, 142, (outs f8rc:$frD), (ins f8rc:$frB),
- "fctiwu", "$frD, $frB", IIC_FPGeneral,
- []>;
- defm FCTIWZ : XForm_26r<63, 15, (outs f8rc:$frD), (ins f8rc:$frB),
- "fctiwz", "$frD, $frB", IIC_FPGeneral,
- [(set f64:$frD, (PPCany_fctiwz f64:$frB))]>;
-
- defm FRSP : XForm_26r<63, 12, (outs f4rc:$frD), (ins f8rc:$frB),
- "frsp", "$frD, $frB", IIC_FPGeneral,
- [(set f32:$frD, (any_fpround f64:$frB))]>;
-
+}
+
+let Uses = [RM], mayRaiseFPException = 1, hasSideEffects = 0 in {
+ defm FCTIW : XForm_26r<63, 14, (outs f8rc:$frD), (ins f8rc:$frB),
+ "fctiw", "$frD, $frB", IIC_FPGeneral,
+ []>;
+ defm FCTIWU : XForm_26r<63, 142, (outs f8rc:$frD), (ins f8rc:$frB),
+ "fctiwu", "$frD, $frB", IIC_FPGeneral,
+ []>;
+ defm FCTIWZ : XForm_26r<63, 15, (outs f8rc:$frD), (ins f8rc:$frB),
+ "fctiwz", "$frD, $frB", IIC_FPGeneral,
+ [(set f64:$frD, (PPCany_fctiwz f64:$frB))]>;
+
+ defm FRSP : XForm_26r<63, 12, (outs f4rc:$frD), (ins f8rc:$frB),
+ "frsp", "$frD, $frB", IIC_FPGeneral,
+ [(set f32:$frD, (any_fpround f64:$frB))]>;
+
defm FSQRT : XForm_26r<63, 22, (outs f8rc:$frD), (ins f8rc:$frB),
"fsqrt", "$frD, $frB", IIC_FPSqrtD,
[(set f64:$frD, (any_fsqrt f64:$frB))]>;
@@ -2739,10 +2739,10 @@ let Uses = [RM], mayRaiseFPException = 1, hasSideEffects = 0 in {
"fsqrts", "$frD, $frB", IIC_FPSqrtS,
[(set f32:$frD, (any_fsqrt f32:$frB))]>;
}
-}
+}
+
+def : Pat<(PPCfsqrt f64:$frA), (FSQRT $frA)>;
-def : Pat<(PPCfsqrt f64:$frA), (FSQRT $frA)>;
-
/// Note that FMR is defined as pseudo-ops on the PPC970 because they are
/// often coalesced away and we don't want the dispatch group builder to think
/// that they will fill slots (which could cause the load of a LSU reject to
@@ -2786,7 +2786,7 @@ defm FCPSGND : XForm_28r<63, 8, (outs f8rc:$frD), (ins f8rc:$frA, f8rc:$frB),
[(set f64:$frD, (fcopysign f64:$frB, f64:$frA))]>;
// Reciprocal estimates.
-let mayRaiseFPException = 1 in {
+let mayRaiseFPException = 1 in {
defm FRE : XForm_26r<63, 24, (outs f8rc:$frD), (ins f8rc:$frB),
"fre", "$frD, $frB", IIC_FPGeneral,
[(set f64:$frD, (PPCfre f64:$frB))]>;
@@ -2800,7 +2800,7 @@ defm FRSQRTES : XForm_26r<59, 26, (outs f4rc:$frD), (ins f4rc:$frB),
"frsqrtes", "$frD, $frB", IIC_FPGeneral,
[(set f32:$frD, (PPCfrsqrte f32:$frB))]>;
}
-}
+}
// XL-Form instructions. condition register logical ops.
//
@@ -3000,24 +3000,24 @@ def : InstAlias<"mtcr $rA", (MTCRF 255, gprc:$rA)>;
let Predicates = [HasFPU] in {
// Custom inserter instruction to perform FADD in round-to-zero mode.
-let Uses = [RM], mayRaiseFPException = 1 in {
+let Uses = [RM], mayRaiseFPException = 1 in {
def FADDrtz: PPCCustomInserterPseudo<(outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRB), "",
- [(set f64:$FRT, (PPCany_faddrtz f64:$FRA, f64:$FRB))]>;
+ [(set f64:$FRT, (PPCany_faddrtz f64:$FRA, f64:$FRB))]>;
}
// The above pseudo gets expanded to make use of the following instructions
// to manipulate FPSCR. Note that FPSCR is not modeled at the DAG level.
-
-// When FM is 30/31, we are setting the 62/63 bit of FPSCR, the implicit-def
-// RM should be set.
-def MTFSB0 : XForm_43<63, 70, (outs), (ins u5imm:$FM),
- "mtfsb0 $FM", IIC_IntMTFSB0, []>,
- PPC970_DGroup_Single, PPC970_Unit_FPU;
-def MTFSB1 : XForm_43<63, 38, (outs), (ins u5imm:$FM),
- "mtfsb1 $FM", IIC_IntMTFSB0, []>,
- PPC970_DGroup_Single, PPC970_Unit_FPU;
-
-let Defs = [RM] in {
+
+// When FM is 30/31, we are setting the 62/63 bit of FPSCR, the implicit-def
+// RM should be set.
+def MTFSB0 : XForm_43<63, 70, (outs), (ins u5imm:$FM),
+ "mtfsb0 $FM", IIC_IntMTFSB0, []>,
+ PPC970_DGroup_Single, PPC970_Unit_FPU;
+def MTFSB1 : XForm_43<63, 38, (outs), (ins u5imm:$FM),
+ "mtfsb1 $FM", IIC_IntMTFSB0, []>,
+ PPC970_DGroup_Single, PPC970_Unit_FPU;
+
+let Defs = [RM] in {
let isCodeGenOnly = 1 in
def MTFSFb : XFLForm<63, 711, (outs), (ins i32imm:$FM, f8rc:$rT),
"mtfsf $FM, $rT", IIC_IntMTFSB0, []>,
@@ -3156,7 +3156,7 @@ def : InstAlias<"subc. $rA, $rB, $rC", (SUBFC_rec gprc:$rA, gprc:$rC, gprc:$rB)>
// this type.
//
let PPC970_Unit = 3, hasSideEffects = 0, Predicates = [HasFPU] in { // FPU Operations.
-let mayRaiseFPException = 1, Uses = [RM] in {
+let mayRaiseFPException = 1, Uses = [RM] in {
let isCommutable = 1 in {
defm FMADD : AForm_1r<63, 29,
(outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRC, f8rc:$FRB),
@@ -3342,13 +3342,13 @@ def : Pat<(PPCcall (i32 texternalsym:$dst)),
// Calls for AIX only
def : Pat<(PPCcall (i32 mcsym:$dst)),
(BL mcsym:$dst)>;
-
+
def : Pat<(PPCcall_nop (i32 mcsym:$dst)),
(BL_NOP mcsym:$dst)>;
-def : Pat<(PPCcall_nop (i32 texternalsym:$dst)),
- (BL_NOP texternalsym:$dst)>;
-
+def : Pat<(PPCcall_nop (i32 texternalsym:$dst)),
+ (BL_NOP texternalsym:$dst)>;
+
def : Pat<(PPCtc_return (i32 tglobaladdr:$dst), imm:$imm),
(TCRETURNdi tglobaladdr:$dst, imm:$imm)>;
@@ -3358,7 +3358,7 @@ def : Pat<(PPCtc_return (i32 texternalsym:$dst), imm:$imm),
def : Pat<(PPCtc_return CTRRC:$dst, imm:$imm),
(TCRETURNri CTRRC:$dst, imm:$imm)>;
-def : Pat<(int_ppc_readflm), (MFFS)>;
+def : Pat<(int_ppc_readflm), (MFFS)>;
// Hi and Lo for Darwin Global Addresses.
def : Pat<(PPChi tglobaladdr:$in, 0), (LIS tglobaladdr:$in)>;
@@ -3512,7 +3512,7 @@ def : Pat<(f64 (extloadf32 iaddr:$src)),
def : Pat<(f64 (extloadf32 xaddr:$src)),
(COPY_TO_REGCLASS (LFSX xaddr:$src), F8RC)>;
-def : Pat<(f64 (any_fpextend f32:$src)),
+def : Pat<(f64 (any_fpextend f32:$src)),
(COPY_TO_REGCLASS $src, F8RC)>;
}
@@ -3935,7 +3935,7 @@ def : Pat<(i1 (setcc i64:$s1, i64:$s2, SETGT)),
def : Pat<(i1 (setcc i64:$s1, i64:$s2, SETEQ)),
(EXTRACT_SUBREG (CMPD $s1, $s2), sub_eq)>;
-let Predicates = [IsNotISA3_1] in {
+let Predicates = [IsNotISA3_1] in {
// Instantiations of CRNotPat for i32.
defm : CRNotPat<(i1 (setcc i32:$s1, immZExt16:$imm, SETUGE)),
(EXTRACT_SUBREG (CMPLWI $s1, imm:$imm), sub_lt)>;
@@ -3993,62 +3993,62 @@ defm : CRNotPat<(i1 (setcc i64:$s1, i64:$s2, SETLE)),
(EXTRACT_SUBREG (CMPD $s1, $s2), sub_gt)>;
defm : CRNotPat<(i1 (setcc i64:$s1, i64:$s2, SETNE)),
(EXTRACT_SUBREG (CMPD $s1, $s2), sub_eq)>;
-}
-
-multiclass FSetCCPat<SDNode SetCC, ValueType Ty, PatLeaf FCmp> {
- defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETUGE)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
- defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETGE)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
- defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETULE)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
- defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETLE)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
- defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETUNE)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
- defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETNE)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
- defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETO)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_un)>;
-
- def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETOLT)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
- def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETLT)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
- def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETOGT)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
- def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETGT)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
- def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETOEQ)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
- def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETEQ)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
- def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETUO)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_un)>;
-}
-
-let Predicates = [HasFPU] in {
-// FCMPU: If either of the operands is a Signaling NaN, then VXSNAN is set.
+}
+
+multiclass FSetCCPat<SDNode SetCC, ValueType Ty, PatLeaf FCmp> {
+ defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETUGE)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
+ defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETGE)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
+ defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETULE)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
+ defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETLE)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
+ defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETUNE)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
+ defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETNE)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
+ defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETO)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_un)>;
+
+ def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETOLT)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
+ def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETLT)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
+ def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETOGT)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
+ def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETGT)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
+ def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETOEQ)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
+ def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETEQ)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
+ def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETUO)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_un)>;
+}
+
+let Predicates = [HasFPU] in {
+// FCMPU: If either of the operands is a Signaling NaN, then VXSNAN is set.
// SETCC for f32.
-defm : FSetCCPat<any_fsetcc, f32, FCMPUS>;
+defm : FSetCCPat<any_fsetcc, f32, FCMPUS>;
// SETCC for f64.
-defm : FSetCCPat<any_fsetcc, f64, FCMPUD>;
+defm : FSetCCPat<any_fsetcc, f64, FCMPUD>;
// SETCC for f128.
-defm : FSetCCPat<any_fsetcc, f128, XSCMPUQP>;
+defm : FSetCCPat<any_fsetcc, f128, XSCMPUQP>;
+
+// FCMPO: If either of the operands is a Signaling NaN, then VXSNAN is set and,
+// if neither operand is a Signaling NaN but at least one operand is a Quiet NaN,
+// then VXVC is set.
+// SETCCS for f32.
+defm : FSetCCPat<strict_fsetccs, f32, FCMPOS>;
-// FCMPO: If either of the operands is a Signaling NaN, then VXSNAN is set and,
-// if neither operand is a Signaling NaN but at least one operand is a Quiet NaN,
-// then VXVC is set.
-// SETCCS for f32.
-defm : FSetCCPat<strict_fsetccs, f32, FCMPOS>;
-
-// SETCCS for f64.
-defm : FSetCCPat<strict_fsetccs, f64, FCMPOD>;
-
-// SETCCS for f128.
-defm : FSetCCPat<strict_fsetccs, f128, XSCMPOQP>;
+// SETCCS for f64.
+defm : FSetCCPat<strict_fsetccs, f64, FCMPOD>;
+
+// SETCCS for f128.
+defm : FSetCCPat<strict_fsetccs, f128, XSCMPOQP>;
}
// This must be in this file because it relies on patterns defined in this file
@@ -4317,7 +4317,7 @@ def ISYNC : XLForm_2_ext<19, 150, 0, 0, 0, (outs), (ins),
def ICBI : XForm_1a<31, 982, (outs), (ins memrr:$src),
"icbi $src", IIC_LdStICBI, []>;
-def WAIT : XForm_24_sync<31, 30, (outs), (ins u2imm:$L),
+def WAIT : XForm_24_sync<31, 30, (outs), (ins u2imm:$L),
"wait $L", IIC_LdStLoad, []>;
def MBAR : XForm_mbar<31, 854, (outs), (ins u5imm:$MO),
@@ -4335,7 +4335,7 @@ def MTSRIN: XForm_srin<31, 242, (outs), (ins gprc:$RS, gprc:$RB),
def MFSRIN: XForm_srin<31, 659, (outs gprc:$RS), (ins gprc:$RB),
"mfsrin $RS, $RB", IIC_SprMFSR>;
-def MTMSR: XForm_mtmsr<31, 146, (outs), (ins gprc:$RS, u1imm:$L),
+def MTMSR: XForm_mtmsr<31, 146, (outs), (ins gprc:$RS, u1imm:$L),
"mtmsr $RS, $L", IIC_SprMTMSR>;
def WRTEE: XForm_mtmsr<31, 131, (outs), (ins gprc:$RS),
@@ -4364,17 +4364,17 @@ def : InstAlias<"iccci", (ICCCI R0, R0)>, Requires<[IsPPC4xx]>;
def MFMSR : XForm_rs<31, 83, (outs gprc:$RT), (ins),
"mfmsr $RT", IIC_SprMFMSR, []>;
-def MTMSRD : XForm_mtmsr<31, 178, (outs), (ins gprc:$RS, u1imm:$L),
+def MTMSRD : XForm_mtmsr<31, 178, (outs), (ins gprc:$RS, u1imm:$L),
"mtmsrd $RS, $L", IIC_SprMTMSRD>;
def MCRFS : XLForm_3<63, 64, (outs crrc:$BF), (ins crrc:$BFA),
"mcrfs $BF, $BFA", IIC_BrMCR>;
-// If W is 0 and BF is 7, the 60:63 bits will be set, we should set the
-// implicit-def RM.
+// If W is 0 and BF is 7, the 60:63 bits will be set, we should set the
+// implicit-def RM.
def MTFSFI : XLForm_4<63, 134, (outs crrc:$BF), (ins i32imm:$U, i32imm:$W),
"mtfsfi $BF, $U, $W", IIC_IntMFFS>;
-let Defs = [CR1] in
+let Defs = [CR1] in
def MTFSFI_rec : XLForm_4<63, 134, (outs crrc:$BF), (ins i32imm:$U, i32imm:$W),
"mtfsfi. $BF, $U, $W", IIC_IntMFFS>, isRecordForm;
@@ -4382,15 +4382,15 @@ def : InstAlias<"mtfsfi $BF, $U", (MTFSFI crrc:$BF, i32imm:$U, 0)>;
def : InstAlias<"mtfsfi. $BF, $U", (MTFSFI_rec crrc:$BF, i32imm:$U, 0)>;
let Predicates = [HasFPU] in {
-let Defs = [RM] in {
+let Defs = [RM] in {
def MTFSF : XFLForm_1<63, 711, (outs),
- (ins i32imm:$FLM, f8rc:$FRB, u1imm:$L, i32imm:$W),
+ (ins i32imm:$FLM, f8rc:$FRB, u1imm:$L, i32imm:$W),
"mtfsf $FLM, $FRB, $L, $W", IIC_IntMFFS, []>;
-let Defs = [CR1] in
+let Defs = [CR1] in
def MTFSF_rec : XFLForm_1<63, 711, (outs),
- (ins i32imm:$FLM, f8rc:$FRB, u1imm:$L, i32imm:$W),
+ (ins i32imm:$FLM, f8rc:$FRB, u1imm:$L, i32imm:$W),
"mtfsf. $FLM, $FRB, $L, $W", IIC_IntMFFS, []>, isRecordForm;
-}
+}
def : InstAlias<"mtfsf $FLM, $FRB", (MTFSF i32imm:$FLM, f8rc:$FRB, 0, 0)>;
def : InstAlias<"mtfsf. $FLM, $FRB", (MTFSF_rec i32imm:$FLM, f8rc:$FRB, 0, 0)>;
@@ -4617,16 +4617,16 @@ def : Pat<(int_ppc_dcbfl xoaddr:$dst),
def : Pat<(int_ppc_dcbflp xoaddr:$dst),
(DCBF 3, xoaddr:$dst)>;
-let Predicates = [IsISA3_1] in {
- def DCBFPS : PPCAsmPseudo<"dcbfps $dst", (ins memrr:$dst)>;
- def DCBSTPS : PPCAsmPseudo<"dcbstps $dst", (ins memrr:$dst)>;
-
- def : Pat<(int_ppc_dcbfps xoaddr:$dst),
- (DCBF 4, xoaddr:$dst)>;
- def : Pat<(int_ppc_dcbstps xoaddr:$dst),
- (DCBF 6, xoaddr:$dst)>;
-}
-
+let Predicates = [IsISA3_1] in {
+ def DCBFPS : PPCAsmPseudo<"dcbfps $dst", (ins memrr:$dst)>;
+ def DCBSTPS : PPCAsmPseudo<"dcbstps $dst", (ins memrr:$dst)>;
+
+ def : Pat<(int_ppc_dcbfps xoaddr:$dst),
+ (DCBF 4, xoaddr:$dst)>;
+ def : Pat<(int_ppc_dcbstps xoaddr:$dst),
+ (DCBF 6, xoaddr:$dst)>;
+}
+
def : InstAlias<"crset $bx", (CREQV crbitrc:$bx, crbitrc:$bx, crbitrc:$bx)>;
def : InstAlias<"crclr $bx", (CRXOR crbitrc:$bx, crbitrc:$bx, crbitrc:$bx)>;
def : InstAlias<"crmove $bx, $by", (CROR crbitrc:$bx, crbitrc:$by, crbitrc:$by)>;
@@ -4653,11 +4653,11 @@ def : InstAlias<"mtmsr $RS", (MTMSR gprc:$RS, 0)>;
def : InstAlias<"mtxer $Rx", (MTSPR 1, gprc:$Rx)>;
def : InstAlias<"mfxer $Rx", (MFSPR gprc:$Rx, 1)>;
-//Disable this alias on AIX for now because as does not support them.
-let Predicates = [ModernAs] in {
+//Disable this alias on AIX for now because as does not support them.
+let Predicates = [ModernAs] in {
def : InstAlias<"mtudscr $Rx", (MTSPR 3, gprc:$Rx)>;
def : InstAlias<"mfudscr $Rx", (MFSPR gprc:$Rx, 3)>;
-}
+}
def : InstAlias<"mfrtcu $Rx", (MFSPR gprc:$Rx, 4)>;
def : InstAlias<"mfrtcl $Rx", (MFSPR gprc:$Rx, 5)>;
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrPrefix.td b/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrPrefix.td
index 0460c7bedc..b9eb3b3b7d 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrPrefix.td
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrPrefix.td
@@ -1,8 +1,8 @@
-// Mask immediates for MMA instructions (2, 4 and 8 bits).
-def Msk2Imm : ImmLeaf<i32, [{ return isUInt<2>(Imm); }]>;
-def Msk4Imm : ImmLeaf<i32, [{ return isUInt<4>(Imm); }]>;
-def Msk8Imm : ImmLeaf<i32, [{ return isUInt<8>(Imm); }]>;
-
+// Mask immediates for MMA instructions (2, 4 and 8 bits).
+def Msk2Imm : ImmLeaf<i32, [{ return isUInt<2>(Imm); }]>;
+def Msk4Imm : ImmLeaf<i32, [{ return isUInt<4>(Imm); }]>;
+def Msk8Imm : ImmLeaf<i32, [{ return isUInt<8>(Imm); }]>;
+
//===----------------------------------------------------------------------===//
// PowerPC ISA 3.1 specific type constraints.
//
@@ -10,35 +10,35 @@ def Msk8Imm : ImmLeaf<i32, [{ return isUInt<8>(Imm); }]>;
def SDT_PPCSplat32 : SDTypeProfile<1, 3, [ SDTCisVT<0, v2i64>,
SDTCisVec<1>, SDTCisInt<2>, SDTCisInt<3>
]>;
-def SDT_PPCAccBuild : SDTypeProfile<1, 4, [
- SDTCisVT<0, v512i1>, SDTCisVT<1, v4i32>, SDTCisVT<2, v4i32>,
- SDTCisVT<3, v4i32>, SDTCisVT<4, v4i32>
-]>;
-def SDT_PPCPairBuild : SDTypeProfile<1, 2, [
- SDTCisVT<0, v256i1>, SDTCisVT<1, v4i32>, SDTCisVT<2, v4i32>
-]>;
-def SDT_PPCAccExtractVsx : SDTypeProfile<1, 2, [
- SDTCisVT<0, v4i32>, SDTCisVT<1, v512i1>, SDTCisInt<2>
-]>;
-def SDT_PPCPairExtractVsx : SDTypeProfile<1, 2, [
- SDTCisVT<0, v4i32>, SDTCisVT<1, v256i1>, SDTCisInt<2>
-]>;
-def SDT_PPCxxmfacc : SDTypeProfile<1, 1, [
- SDTCisVT<0, v512i1>, SDTCisVT<1, v512i1>
-]>;
+def SDT_PPCAccBuild : SDTypeProfile<1, 4, [
+ SDTCisVT<0, v512i1>, SDTCisVT<1, v4i32>, SDTCisVT<2, v4i32>,
+ SDTCisVT<3, v4i32>, SDTCisVT<4, v4i32>
+]>;
+def SDT_PPCPairBuild : SDTypeProfile<1, 2, [
+ SDTCisVT<0, v256i1>, SDTCisVT<1, v4i32>, SDTCisVT<2, v4i32>
+]>;
+def SDT_PPCAccExtractVsx : SDTypeProfile<1, 2, [
+ SDTCisVT<0, v4i32>, SDTCisVT<1, v512i1>, SDTCisInt<2>
+]>;
+def SDT_PPCPairExtractVsx : SDTypeProfile<1, 2, [
+ SDTCisVT<0, v4i32>, SDTCisVT<1, v256i1>, SDTCisInt<2>
+]>;
+def SDT_PPCxxmfacc : SDTypeProfile<1, 1, [
+ SDTCisVT<0, v512i1>, SDTCisVT<1, v512i1>
+]>;
//===----------------------------------------------------------------------===//
// ISA 3.1 specific PPCISD nodes.
//
def PPCxxsplti32dx : SDNode<"PPCISD::XXSPLTI32DX", SDT_PPCSplat32, []>;
-def PPCAccBuild : SDNode<"PPCISD::ACC_BUILD", SDT_PPCAccBuild, []>;
-def PPCPairBuild : SDNode<"PPCISD::PAIR_BUILD", SDT_PPCPairBuild, []>;
-def PPCAccExtractVsx : SDNode<"PPCISD::EXTRACT_VSX_REG", SDT_PPCAccExtractVsx,
- []>;
-def PPCPairExtractVsx : SDNode<"PPCISD::EXTRACT_VSX_REG", SDT_PPCPairExtractVsx,
- []>;
-def PPCxxmfacc : SDNode<"PPCISD::XXMFACC", SDT_PPCxxmfacc, []>;
+def PPCAccBuild : SDNode<"PPCISD::ACC_BUILD", SDT_PPCAccBuild, []>;
+def PPCPairBuild : SDNode<"PPCISD::PAIR_BUILD", SDT_PPCPairBuild, []>;
+def PPCAccExtractVsx : SDNode<"PPCISD::EXTRACT_VSX_REG", SDT_PPCAccExtractVsx,
+ []>;
+def PPCPairExtractVsx : SDNode<"PPCISD::EXTRACT_VSX_REG", SDT_PPCPairExtractVsx,
+ []>;
+def PPCxxmfacc : SDNode<"PPCISD::XXMFACC", SDT_PPCxxmfacc, []>;
//===----------------------------------------------------------------------===//
@@ -46,15 +46,15 @@ def PPCxxmfacc : SDNode<"PPCISD::XXMFACC", SDT_PPCxxmfacc, []>;
// address computations).
class isPCRel { bit PCRel = 1; }
-// PowerPC specific type constraints.
-def SDT_PPCLXVRZX : SDTypeProfile<1, 2, [
- SDTCisVT<0, v1i128>, SDTCisPtrTy<1>, SDTCisPtrTy<2>
-]>;
-
-// PPC Specific DAG Nodes.
-def PPClxvrzx : SDNode<"PPCISD::LXVRZX", SDT_PPCLXVRZX,
- [SDNPHasChain, SDNPMayLoad]>;
-
+// PowerPC specific type constraints.
+def SDT_PPCLXVRZX : SDTypeProfile<1, 2, [
+ SDTCisVT<0, v1i128>, SDTCisPtrTy<1>, SDTCisPtrTy<2>
+]>;
+
+// PPC Specific DAG Nodes.
+def PPClxvrzx : SDNode<"PPCISD::LXVRZX", SDT_PPCLXVRZX,
+ [SDNPHasChain, SDNPMayLoad]>;
+
// Top-level class for prefixed instructions.
class PI<bits<6> pref, bits<6> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin> : Instruction {
@@ -96,39 +96,39 @@ class PI<bits<6> pref, bits<6> opcode, dag OOL, dag IOL, string asmstr,
string BaseName = "";
}
-// VX-Form: [ PO VT R VB RC XO ]
-class VXForm_VTB5_RC<bits<10> xo, bits<5> R, dag OOL, dag IOL, string asmstr,
- InstrItinClass itin, list<dag> pattern>
- : I<4, OOL, IOL, asmstr, itin> {
- bits<5> VT;
- bits<5> VB;
- bit RC = 0;
-
- let Pattern = pattern;
-
- let Inst{6-10} = VT;
- let Inst{11-15} = R;
- let Inst{16-20} = VB;
- let Inst{21} = RC;
- let Inst{22-31} = xo;
-}
-
-// Multiclass definition to account for record and non-record form
-// instructions of VXRForm.
-multiclass VXForm_VTB5_RCr<bits<10> xo, bits<5> R, dag OOL, dag IOL,
- string asmbase, string asmstr,
- InstrItinClass itin, list<dag> pattern> {
- let BaseName = asmbase in {
- def NAME : VXForm_VTB5_RC<xo, R, OOL, IOL,
- !strconcat(asmbase, !strconcat(" ", asmstr)),
- itin, pattern>, RecFormRel;
- let Defs = [CR6] in
- def _rec : VXForm_VTB5_RC<xo, R, OOL, IOL,
- !strconcat(asmbase, !strconcat(". ", asmstr)),
- itin, []>, isRecordForm, RecFormRel;
- }
-}
-
+// VX-Form: [ PO VT R VB RC XO ]
+class VXForm_VTB5_RC<bits<10> xo, bits<5> R, dag OOL, dag IOL, string asmstr,
+ InstrItinClass itin, list<dag> pattern>
+ : I<4, OOL, IOL, asmstr, itin> {
+ bits<5> VT;
+ bits<5> VB;
+ bit RC = 0;
+
+ let Pattern = pattern;
+
+ let Inst{6-10} = VT;
+ let Inst{11-15} = R;
+ let Inst{16-20} = VB;
+ let Inst{21} = RC;
+ let Inst{22-31} = xo;
+}
+
+// Multiclass definition to account for record and non-record form
+// instructions of VXRForm.
+multiclass VXForm_VTB5_RCr<bits<10> xo, bits<5> R, dag OOL, dag IOL,
+ string asmbase, string asmstr,
+ InstrItinClass itin, list<dag> pattern> {
+ let BaseName = asmbase in {
+ def NAME : VXForm_VTB5_RC<xo, R, OOL, IOL,
+ !strconcat(asmbase, !strconcat(" ", asmstr)),
+ itin, pattern>, RecFormRel;
+ let Defs = [CR6] in
+ def _rec : VXForm_VTB5_RC<xo, R, OOL, IOL,
+ !strconcat(asmbase, !strconcat(". ", asmstr)),
+ itin, []>, isRecordForm, RecFormRel;
+ }
+}
+
class MLS_DForm_R_SI34_RTA5_MEM<bits<6> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
: PI<1, opcode, OOL, IOL, asmstr, itin> {
@@ -315,34 +315,34 @@ class VXForm_RD5_N3_VB5<bits<11> xo, dag OOL, dag IOL, string asmstr,
// VX-Form: [PO VRT RA VRB XO].
// Destructive (insert) forms are suffixed with _ins.
class VXForm_VTB5_RA5_ins<bits<11> xo, string opc, list<dag> pattern>
- : VXForm_1<xo, (outs vrrc:$vD), (ins vrrc:$vDi, gprc:$rA, vrrc:$vB),
+ : VXForm_1<xo, (outs vrrc:$vD), (ins vrrc:$vDi, gprc:$rA, vrrc:$vB),
!strconcat(opc, " $vD, $rA, $vB"), IIC_VecGeneral, pattern>,
RegConstraint<"$vDi = $vD">, NoEncode<"$vDi">;
// VX-Form: [PO VRT RA RB XO].
// Destructive (insert) forms are suffixed with _ins.
class VXForm_VRT5_RAB5_ins<bits<11> xo, string opc, list<dag> pattern>
- : VXForm_1<xo, (outs vrrc:$vD), (ins vrrc:$vDi, gprc:$rA, gprc:$rB),
+ : VXForm_1<xo, (outs vrrc:$vD), (ins vrrc:$vDi, gprc:$rA, gprc:$rB),
!strconcat(opc, " $vD, $rA, $rB"), IIC_VecGeneral, pattern>,
RegConstraint<"$vDi = $vD">, NoEncode<"$vDi">;
-// VX-Form: [ PO BF // VRA VRB XO ]
-class VXForm_BF3_VAB5<bits<11> xo, dag OOL, dag IOL, string asmstr,
- InstrItinClass itin, list<dag> pattern>
- : I<4, OOL, IOL, asmstr, itin> {
- bits<3> BF;
- bits<5> VA;
- bits<5> VB;
-
- let Pattern = pattern;
-
- let Inst{6-8} = BF;
- let Inst{9-10} = 0;
- let Inst{11-15} = VA;
- let Inst{16-20} = VB;
- let Inst{21-31} = xo;
-}
-
+// VX-Form: [ PO BF // VRA VRB XO ]
+class VXForm_BF3_VAB5<bits<11> xo, dag OOL, dag IOL, string asmstr,
+ InstrItinClass itin, list<dag> pattern>
+ : I<4, OOL, IOL, asmstr, itin> {
+ bits<3> BF;
+ bits<5> VA;
+ bits<5> VB;
+
+ let Pattern = pattern;
+
+ let Inst{6-8} = BF;
+ let Inst{9-10} = 0;
+ let Inst{11-15} = VA;
+ let Inst{16-20} = VB;
+ let Inst{21-31} = xo;
+}
+
// VN-Form: [PO VRT VRA VRB PS SD XO]
// SD is "Shift Direction"
class VNForm_VTAB5_SD3<bits<6> xo, bits<2> ps, dag OOL, dag IOL, string asmstr,
@@ -363,22 +363,22 @@ class VNForm_VTAB5_SD3<bits<6> xo, bits<2> ps, dag OOL, dag IOL, string asmstr,
let Inst{26-31} = xo;
}
-class VXForm_RD5_MP_VB5<bits<11> xo, bits<4> eo, dag OOL, dag IOL,
- string asmstr, InstrItinClass itin, list<dag> pattern>
- : I<4, OOL, IOL, asmstr, itin> {
- bits<5> RD;
- bits<5> VB;
- bit MP;
-
- let Pattern = pattern;
-
- let Inst{6-10} = RD;
- let Inst{11-14} = eo;
- let Inst{15} = MP;
- let Inst{16-20} = VB;
- let Inst{21-31} = xo;
-}
-
+class VXForm_RD5_MP_VB5<bits<11> xo, bits<4> eo, dag OOL, dag IOL,
+ string asmstr, InstrItinClass itin, list<dag> pattern>
+ : I<4, OOL, IOL, asmstr, itin> {
+ bits<5> RD;
+ bits<5> VB;
+ bit MP;
+
+ let Pattern = pattern;
+
+ let Inst{6-10} = RD;
+ let Inst{11-14} = eo;
+ let Inst{15} = MP;
+ let Inst{16-20} = VB;
+ let Inst{21-31} = xo;
+}
+
// 8RR:D-Form: [ 1 1 0 // // imm0
// PO T XO TX imm1 ].
class 8RR_DForm_IMM32_XT6<bits<6> opcode, bits<4> xo, dag OOL, dag IOL,
@@ -509,13 +509,13 @@ class XX2_BF3_XO5_XB6_XO9<bits<6> opcode, bits<5> xo2, bits<9> xo, dag OOL,
let Inst{31} = 0;
}
-// X-Form: [ PO RT BI /// XO / ]
-class XForm_XT5_BI5<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
- string asmstr, InstrItinClass itin, list<dag> pattern>
- : XForm_base_r3xo<opcode, xo, OOL, IOL, asmstr, itin, pattern> {
- let B = 0;
-}
-
+// X-Form: [ PO RT BI /// XO / ]
+class XForm_XT5_BI5<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
+ string asmstr, InstrItinClass itin, list<dag> pattern>
+ : XForm_base_r3xo<opcode, xo, OOL, IOL, asmstr, itin, pattern> {
+ let B = 0;
+}
+
multiclass MLS_DForm_R_SI34_RTA5_MEM_p<bits<6> opcode, dag OOL, dag IOL,
dag PCRel_IOL, string asmstr,
InstrItinClass itin> {
@@ -545,307 +545,307 @@ multiclass 8LS_DForm_R_SI34_XT6_RA5_p<bits<5> opcode, dag OOL, dag IOL,
isPCRel;
}
-def PPCRegVSRpRCAsmOperand : AsmOperandClass {
- let Name = "RegVSRpRC"; let PredicateMethod = "isVSRpEvenRegNumber";
-}
-
-def vsrprc : RegisterOperand<VSRpRC> {
- let ParserMatchClass = PPCRegVSRpRCAsmOperand;
-}
-
-def PPCRegVSRpEvenRCAsmOperand : AsmOperandClass {
- let Name = "RegVSRpEvenRC"; let PredicateMethod = "isVSRpEvenRegNumber";
-}
-
-def vsrpevenrc : RegisterOperand<VSRpRC> {
- let ParserMatchClass = PPCRegVSRpEvenRCAsmOperand;
- let EncoderMethod = "getVSRpEvenEncoding";
- let DecoderMethod = "decodeVSRpEvenOperands";
-}
-
-class DQForm_XTp5_RA17_MEM<bits<6> opcode, bits<4> xo, dag OOL, dag IOL,
- string asmstr, InstrItinClass itin, list<dag> pattern>
- : I<opcode, OOL, IOL, asmstr, itin> {
- bits<5> XTp;
- bits<17> DQ_RA;
- let Pattern = pattern;
-
- let Inst{6-9} = XTp{3-0};
- let Inst{10} = XTp{4};
- let Inst{11-15} = DQ_RA{16-12}; // Register #
- let Inst{16-27} = DQ_RA{11-0}; // Displacement.
- let Inst{28-31} = xo;
-}
-
-class XForm_XTp5_XAB5<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
- string asmstr, InstrItinClass itin, list<dag> pattern>
- : I<opcode, OOL, IOL, asmstr, itin>, XFormMemOp {
- bits<5> XTp;
- bits<5> A;
- bits<5> B;
-
- let Pattern = pattern;
- let Inst{6-9} = XTp{3-0};
- let Inst{10} = XTp{4};
- let Inst{11-15} = A;
- let Inst{16-20} = B;
- let Inst{21-30} = xo;
- let Inst{31} = 0;
-}
-
-class 8LS_DForm_R_XTp5_SI34_MEM<bits<6> opcode, dag OOL, dag IOL, string asmstr,
- InstrItinClass itin, list<dag> pattern>
- : PI<1, opcode, OOL, IOL, asmstr, itin> {
- bits<5> XTp;
- bits<39> D_RA;
-
- let Pattern = pattern;
-
- // The prefix.
- let Inst{6-10} = 0;
- let Inst{11} = PCRel;
- let Inst{12-13} = 0;
- let Inst{14-31} = D_RA{33-16}; // Imm18
-
- // The instruction.
- let Inst{38-41} = XTp{3-0};
- let Inst{42} = XTp{4};
- let Inst{43-47} = D_RA{38-34}; // Register #
- let Inst{48-63} = D_RA{15-0}; // D
-}
-
-multiclass 8LS_DForm_R_XTp5_SI34_MEM_p<bits<6> pref, bits<6> opcode, dag OOL,
- dag IOL, dag PCRel_IOL,
- string asmstr, InstrItinClass itin> {
- def NAME : 8LS_DForm_R_XTp5_SI34_MEM<opcode, OOL, IOL,
- !strconcat(asmstr, ", 0"), itin, []>;
- def pc : 8LS_DForm_R_XTp5_SI34_MEM<opcode, OOL, PCRel_IOL,
- !strconcat(asmstr, ", 1"), itin, []>,
- isPCRel;
-}
-
-def PPCRegACCRCAsmOperand : AsmOperandClass {
- let Name = "RegACCRC"; let PredicateMethod = "isACCRegNumber";
-}
-
-def acc : RegisterOperand<ACCRC> {
- let ParserMatchClass = PPCRegACCRCAsmOperand;
-}
-
-def uacc : RegisterOperand<UACCRC> {
- let ParserMatchClass = PPCRegACCRCAsmOperand;
-}
-
-// [PO AS XO2 XO]
-class XForm_AT3<bits<6> opcode, bits<5> xo2, bits<10> xo, dag OOL, dag IOL,
- string asmstr, InstrItinClass itin, list<dag> pattern>
- : I<opcode, OOL, IOL, asmstr, itin> {
- bits<3> AT;
-
- let Pattern = pattern;
-
- let Inst{6-8} = AT;
- let Inst{9-10} = 0;
- let Inst{11-15} = xo2;
- let Inst{16-20} = 0;
- let Inst{21-30} = xo;
- let Inst{31} = 0;
-}
-
-class XX3Form_AT3_XAB6<bits<6> opcode, bits<8> xo, dag OOL, dag IOL,
- string asmstr, InstrItinClass itin,
- list<dag> pattern>
- : I<opcode, OOL, IOL, asmstr, itin> {
- bits<3> AT;
- bits<6> XA;
- bits<6> XB;
-
- let Pattern = pattern;
-
- let Inst{6-8} = AT;
- let Inst{9-10} = 0;
- let Inst{11-15} = XA{4-0};
- let Inst{16-20} = XB{4-0};
- let Inst{21-28} = xo;
- let Inst{29} = XA{5};
- let Inst{30} = XB{5};
- let Inst{31} = 0;
-}
-
-class MMIRR_XX3Form_XY4P2_XAB6<bits<6> opcode, bits<8> xo, dag OOL, dag IOL,
- string asmstr, InstrItinClass itin,
- list<dag> pattern>
- : PI<1, opcode, OOL, IOL, asmstr, itin> {
- bits<3> AT;
- bits<6> XA;
- bits<6> XB;
- bits<4> XMSK;
- bits<4> YMSK;
- bits<2> PMSK;
-
- let Pattern = pattern;
-
- // The prefix.
- let Inst{6-7} = 3;
- let Inst{8-11} = 9;
- let Inst{12-15} = 0;
- let Inst{16-17} = PMSK;
- let Inst{18-23} = 0;
- let Inst{24-27} = XMSK;
- let Inst{28-31} = YMSK;
-
- // The instruction.
- let Inst{38-40} = AT;
- let Inst{41-42} = 0;
- let Inst{43-47} = XA{4-0};
- let Inst{48-52} = XB{4-0};
- let Inst{53-60} = xo;
- let Inst{61} = XA{5};
- let Inst{62} = XB{5};
- let Inst{63} = 0;
-}
-
-class MMIRR_XX3Form_XY4_XAB6<bits<6> opcode, bits<8> xo, dag OOL, dag IOL,
- string asmstr, InstrItinClass itin,
- list<dag> pattern>
- : PI<1, opcode, OOL, IOL, asmstr, itin> {
- bits<3> AT;
- bits<6> XA;
- bits<6> XB;
- bits<4> XMSK;
- bits<4> YMSK;
-
- let Pattern = pattern;
-
- // The prefix.
- let Inst{6-7} = 3;
- let Inst{8-11} = 9;
- let Inst{12-23} = 0;
- let Inst{24-27} = XMSK;
- let Inst{28-31} = YMSK;
-
- // The instruction.
- let Inst{38-40} = AT;
- let Inst{41-42} = 0;
- let Inst{43-47} = XA{4-0};
- let Inst{48-52} = XB{4-0};
- let Inst{53-60} = xo;
- let Inst{61} = XA{5};
- let Inst{62} = XB{5};
- let Inst{63} = 0;
-}
-
-class MMIRR_XX3Form_X4Y2_XAB6<bits<6> opcode, bits<8> xo, dag OOL, dag IOL,
- string asmstr, InstrItinClass itin,
- list<dag> pattern>
- : PI<1, opcode, OOL, IOL, asmstr, itin> {
- bits<3> AT;
- bits<6> XA;
- bits<6> XB;
- bits<4> XMSK;
- bits<2> YMSK;
-
- let Pattern = pattern;
-
- // The prefix.
- let Inst{6-7} = 3;
- let Inst{8-11} = 9;
- let Inst{12-23} = 0;
- let Inst{24-27} = XMSK;
- let Inst{28-29} = YMSK;
- let Inst{30-31} = 0;
-
- // The instruction.
- let Inst{38-40} = AT;
- let Inst{41-42} = 0;
- let Inst{43-47} = XA{4-0};
- let Inst{48-52} = XB{4-0};
- let Inst{53-60} = xo;
- let Inst{61} = XA{5};
- let Inst{62} = XB{5};
- let Inst{63} = 0;
-}
-
-class MMIRR_XX3Form_XY4P8_XAB6<bits<6> opcode, bits<8> xo, dag OOL, dag IOL,
- string asmstr, InstrItinClass itin,
- list<dag> pattern>
- : PI<1, opcode, OOL, IOL, asmstr, itin> {
- bits<3> AT;
- bits<6> XA;
- bits<6> XB;
- bits<4> XMSK;
- bits<4> YMSK;
- bits<8> PMSK;
-
- let Pattern = pattern;
-
- // The prefix.
- let Inst{6-7} = 3;
- let Inst{8-11} = 9;
- let Inst{12-15} = 0;
- let Inst{16-23} = PMSK;
- let Inst{24-27} = XMSK;
- let Inst{28-31} = YMSK;
-
- // The instruction.
- let Inst{38-40} = AT;
- let Inst{41-42} = 0;
- let Inst{43-47} = XA{4-0};
- let Inst{48-52} = XB{4-0};
- let Inst{53-60} = xo;
- let Inst{61} = XA{5};
- let Inst{62} = XB{5};
- let Inst{63} = 0;
-}
-
-class MMIRR_XX3Form_XYP4_XAB6<bits<6> opcode, bits<8> xo, dag OOL, dag IOL,
- string asmstr, InstrItinClass itin,
- list<dag> pattern>
- : PI<1, opcode, OOL, IOL, asmstr, itin> {
- bits<3> AT;
- bits<6> XA;
- bits<6> XB;
- bits<4> XMSK;
- bits<4> YMSK;
- bits<4> PMSK;
-
- let Pattern = pattern;
-
- // The prefix.
- let Inst{6-7} = 3;
- let Inst{8-11} = 9;
- let Inst{12-15} = 0;
- let Inst{16-19} = PMSK;
- let Inst{20-23} = 0;
- let Inst{24-27} = XMSK;
- let Inst{28-31} = YMSK;
-
- // The instruction.
- let Inst{38-40} = AT;
- let Inst{41-42} = 0;
- let Inst{43-47} = XA{4-0};
- let Inst{48-52} = XB{4-0};
- let Inst{53-60} = xo;
- let Inst{61} = XA{5};
- let Inst{62} = XB{5};
- let Inst{63} = 0;
-}
-
+def PPCRegVSRpRCAsmOperand : AsmOperandClass {
+ let Name = "RegVSRpRC"; let PredicateMethod = "isVSRpEvenRegNumber";
+}
+
+def vsrprc : RegisterOperand<VSRpRC> {
+ let ParserMatchClass = PPCRegVSRpRCAsmOperand;
+}
+
+def PPCRegVSRpEvenRCAsmOperand : AsmOperandClass {
+ let Name = "RegVSRpEvenRC"; let PredicateMethod = "isVSRpEvenRegNumber";
+}
+
+def vsrpevenrc : RegisterOperand<VSRpRC> {
+ let ParserMatchClass = PPCRegVSRpEvenRCAsmOperand;
+ let EncoderMethod = "getVSRpEvenEncoding";
+ let DecoderMethod = "decodeVSRpEvenOperands";
+}
+
+class DQForm_XTp5_RA17_MEM<bits<6> opcode, bits<4> xo, dag OOL, dag IOL,
+ string asmstr, InstrItinClass itin, list<dag> pattern>
+ : I<opcode, OOL, IOL, asmstr, itin> {
+ bits<5> XTp;
+ bits<17> DQ_RA;
+ let Pattern = pattern;
+
+ let Inst{6-9} = XTp{3-0};
+ let Inst{10} = XTp{4};
+ let Inst{11-15} = DQ_RA{16-12}; // Register #
+ let Inst{16-27} = DQ_RA{11-0}; // Displacement.
+ let Inst{28-31} = xo;
+}
+
+class XForm_XTp5_XAB5<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
+ string asmstr, InstrItinClass itin, list<dag> pattern>
+ : I<opcode, OOL, IOL, asmstr, itin>, XFormMemOp {
+ bits<5> XTp;
+ bits<5> A;
+ bits<5> B;
+
+ let Pattern = pattern;
+ let Inst{6-9} = XTp{3-0};
+ let Inst{10} = XTp{4};
+ let Inst{11-15} = A;
+ let Inst{16-20} = B;
+ let Inst{21-30} = xo;
+ let Inst{31} = 0;
+}
+
+class 8LS_DForm_R_XTp5_SI34_MEM<bits<6> opcode, dag OOL, dag IOL, string asmstr,
+ InstrItinClass itin, list<dag> pattern>
+ : PI<1, opcode, OOL, IOL, asmstr, itin> {
+ bits<5> XTp;
+ bits<39> D_RA;
+
+ let Pattern = pattern;
+
+ // The prefix.
+ let Inst{6-10} = 0;
+ let Inst{11} = PCRel;
+ let Inst{12-13} = 0;
+ let Inst{14-31} = D_RA{33-16}; // Imm18
+
+ // The instruction.
+ let Inst{38-41} = XTp{3-0};
+ let Inst{42} = XTp{4};
+ let Inst{43-47} = D_RA{38-34}; // Register #
+ let Inst{48-63} = D_RA{15-0}; // D
+}
+
+multiclass 8LS_DForm_R_XTp5_SI34_MEM_p<bits<6> pref, bits<6> opcode, dag OOL,
+ dag IOL, dag PCRel_IOL,
+ string asmstr, InstrItinClass itin> {
+ def NAME : 8LS_DForm_R_XTp5_SI34_MEM<opcode, OOL, IOL,
+ !strconcat(asmstr, ", 0"), itin, []>;
+ def pc : 8LS_DForm_R_XTp5_SI34_MEM<opcode, OOL, PCRel_IOL,
+ !strconcat(asmstr, ", 1"), itin, []>,
+ isPCRel;
+}
+
+def PPCRegACCRCAsmOperand : AsmOperandClass {
+ let Name = "RegACCRC"; let PredicateMethod = "isACCRegNumber";
+}
+
+def acc : RegisterOperand<ACCRC> {
+ let ParserMatchClass = PPCRegACCRCAsmOperand;
+}
+
+def uacc : RegisterOperand<UACCRC> {
+ let ParserMatchClass = PPCRegACCRCAsmOperand;
+}
+
+// [PO AS XO2 XO]
+class XForm_AT3<bits<6> opcode, bits<5> xo2, bits<10> xo, dag OOL, dag IOL,
+ string asmstr, InstrItinClass itin, list<dag> pattern>
+ : I<opcode, OOL, IOL, asmstr, itin> {
+ bits<3> AT;
+
+ let Pattern = pattern;
+
+ let Inst{6-8} = AT;
+ let Inst{9-10} = 0;
+ let Inst{11-15} = xo2;
+ let Inst{16-20} = 0;
+ let Inst{21-30} = xo;
+ let Inst{31} = 0;
+}
+
+class XX3Form_AT3_XAB6<bits<6> opcode, bits<8> xo, dag OOL, dag IOL,
+ string asmstr, InstrItinClass itin,
+ list<dag> pattern>
+ : I<opcode, OOL, IOL, asmstr, itin> {
+ bits<3> AT;
+ bits<6> XA;
+ bits<6> XB;
+
+ let Pattern = pattern;
+
+ let Inst{6-8} = AT;
+ let Inst{9-10} = 0;
+ let Inst{11-15} = XA{4-0};
+ let Inst{16-20} = XB{4-0};
+ let Inst{21-28} = xo;
+ let Inst{29} = XA{5};
+ let Inst{30} = XB{5};
+ let Inst{31} = 0;
+}
+
+class MMIRR_XX3Form_XY4P2_XAB6<bits<6> opcode, bits<8> xo, dag OOL, dag IOL,
+ string asmstr, InstrItinClass itin,
+ list<dag> pattern>
+ : PI<1, opcode, OOL, IOL, asmstr, itin> {
+ bits<3> AT;
+ bits<6> XA;
+ bits<6> XB;
+ bits<4> XMSK;
+ bits<4> YMSK;
+ bits<2> PMSK;
+
+ let Pattern = pattern;
+
+ // The prefix.
+ let Inst{6-7} = 3;
+ let Inst{8-11} = 9;
+ let Inst{12-15} = 0;
+ let Inst{16-17} = PMSK;
+ let Inst{18-23} = 0;
+ let Inst{24-27} = XMSK;
+ let Inst{28-31} = YMSK;
+
+ // The instruction.
+ let Inst{38-40} = AT;
+ let Inst{41-42} = 0;
+ let Inst{43-47} = XA{4-0};
+ let Inst{48-52} = XB{4-0};
+ let Inst{53-60} = xo;
+ let Inst{61} = XA{5};
+ let Inst{62} = XB{5};
+ let Inst{63} = 0;
+}
+
+class MMIRR_XX3Form_XY4_XAB6<bits<6> opcode, bits<8> xo, dag OOL, dag IOL,
+ string asmstr, InstrItinClass itin,
+ list<dag> pattern>
+ : PI<1, opcode, OOL, IOL, asmstr, itin> {
+ bits<3> AT;
+ bits<6> XA;
+ bits<6> XB;
+ bits<4> XMSK;
+ bits<4> YMSK;
+
+ let Pattern = pattern;
+
+ // The prefix.
+ let Inst{6-7} = 3;
+ let Inst{8-11} = 9;
+ let Inst{12-23} = 0;
+ let Inst{24-27} = XMSK;
+ let Inst{28-31} = YMSK;
+
+ // The instruction.
+ let Inst{38-40} = AT;
+ let Inst{41-42} = 0;
+ let Inst{43-47} = XA{4-0};
+ let Inst{48-52} = XB{4-0};
+ let Inst{53-60} = xo;
+ let Inst{61} = XA{5};
+ let Inst{62} = XB{5};
+ let Inst{63} = 0;
+}
+
+class MMIRR_XX3Form_X4Y2_XAB6<bits<6> opcode, bits<8> xo, dag OOL, dag IOL,
+ string asmstr, InstrItinClass itin,
+ list<dag> pattern>
+ : PI<1, opcode, OOL, IOL, asmstr, itin> {
+ bits<3> AT;
+ bits<6> XA;
+ bits<6> XB;
+ bits<4> XMSK;
+ bits<2> YMSK;
+
+ let Pattern = pattern;
+
+ // The prefix.
+ let Inst{6-7} = 3;
+ let Inst{8-11} = 9;
+ let Inst{12-23} = 0;
+ let Inst{24-27} = XMSK;
+ let Inst{28-29} = YMSK;
+ let Inst{30-31} = 0;
+
+ // The instruction.
+ let Inst{38-40} = AT;
+ let Inst{41-42} = 0;
+ let Inst{43-47} = XA{4-0};
+ let Inst{48-52} = XB{4-0};
+ let Inst{53-60} = xo;
+ let Inst{61} = XA{5};
+ let Inst{62} = XB{5};
+ let Inst{63} = 0;
+}
+
+class MMIRR_XX3Form_XY4P8_XAB6<bits<6> opcode, bits<8> xo, dag OOL, dag IOL,
+ string asmstr, InstrItinClass itin,
+ list<dag> pattern>
+ : PI<1, opcode, OOL, IOL, asmstr, itin> {
+ bits<3> AT;
+ bits<6> XA;
+ bits<6> XB;
+ bits<4> XMSK;
+ bits<4> YMSK;
+ bits<8> PMSK;
+
+ let Pattern = pattern;
+
+ // The prefix.
+ let Inst{6-7} = 3;
+ let Inst{8-11} = 9;
+ let Inst{12-15} = 0;
+ let Inst{16-23} = PMSK;
+ let Inst{24-27} = XMSK;
+ let Inst{28-31} = YMSK;
+
+ // The instruction.
+ let Inst{38-40} = AT;
+ let Inst{41-42} = 0;
+ let Inst{43-47} = XA{4-0};
+ let Inst{48-52} = XB{4-0};
+ let Inst{53-60} = xo;
+ let Inst{61} = XA{5};
+ let Inst{62} = XB{5};
+ let Inst{63} = 0;
+}
+
+class MMIRR_XX3Form_XYP4_XAB6<bits<6> opcode, bits<8> xo, dag OOL, dag IOL,
+ string asmstr, InstrItinClass itin,
+ list<dag> pattern>
+ : PI<1, opcode, OOL, IOL, asmstr, itin> {
+ bits<3> AT;
+ bits<6> XA;
+ bits<6> XB;
+ bits<4> XMSK;
+ bits<4> YMSK;
+ bits<4> PMSK;
+
+ let Pattern = pattern;
+
+ // The prefix.
+ let Inst{6-7} = 3;
+ let Inst{8-11} = 9;
+ let Inst{12-15} = 0;
+ let Inst{16-19} = PMSK;
+ let Inst{20-23} = 0;
+ let Inst{24-27} = XMSK;
+ let Inst{28-31} = YMSK;
+
+ // The instruction.
+ let Inst{38-40} = AT;
+ let Inst{41-42} = 0;
+ let Inst{43-47} = XA{4-0};
+ let Inst{48-52} = XB{4-0};
+ let Inst{53-60} = xo;
+ let Inst{61} = XA{5};
+ let Inst{62} = XB{5};
+ let Inst{63} = 0;
+}
+
def PrefixInstrs : Predicate<"Subtarget->hasPrefixInstrs()">;
def IsISA3_1 : Predicate<"Subtarget->isISA3_1()">;
-def PairedVectorMemops : Predicate<"Subtarget->pairedVectorMemops()">;
-def MMA : Predicate<"Subtarget->hasMMA()">;
-
-def RCCp {
- dag AToVSRC = (COPY_TO_REGCLASS $XA, VSRC);
- dag BToVSRC = (COPY_TO_REGCLASS $XB, VSRC);
-}
-
+def PairedVectorMemops : Predicate<"Subtarget->pairedVectorMemops()">;
+def MMA : Predicate<"Subtarget->hasMMA()">;
+
+def RCCp {
+ dag AToVSRC = (COPY_TO_REGCLASS $XA, VSRC);
+ dag BToVSRC = (COPY_TO_REGCLASS $XB, VSRC);
+}
+
let Predicates = [PrefixInstrs] in {
let Interpretation64Bit = 1, isCodeGenOnly = 1 in {
defm PADDI8 :
MLS_DForm_R_SI34_RTA5_p<14, (outs g8rc:$RT), (ins g8rc:$RA, s34imm:$SI),
- (ins immZero:$RA, s34imm_pcrel:$SI),
+ (ins immZero:$RA, s34imm_pcrel:$SI),
"paddi $RT, $RA, $SI", IIC_LdStLFD>;
let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
def PLI8 : MLS_DForm_SI34_RT5<14, (outs g8rc:$RT),
@@ -855,7 +855,7 @@ let Predicates = [PrefixInstrs] in {
}
defm PADDI :
MLS_DForm_R_SI34_RTA5_p<14, (outs gprc:$RT), (ins gprc:$RA, s34imm:$SI),
- (ins immZero:$RA, s34imm_pcrel:$SI),
+ (ins immZero:$RA, s34imm_pcrel:$SI),
"paddi $RT, $RA, $SI", IIC_LdStLFD>;
let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
def PLI : MLS_DForm_SI34_RT5<14, (outs gprc:$RT),
@@ -986,695 +986,695 @@ let Predicates = [PrefixInstrs] in {
}
}
-// Multiclass definitions for MMA accumulator instructions.
-// ----------------------------------------------------------------------------
-
-// Defines 2 unmasked instructions where the xo field for acc/non-acc version
-// is even/odd.
-multiclass ACC_UM_XOEO<bits<6> opcode, bits<8> xo, dag IOL, string asmbase,
- string asmstr> {
- let Predicates = [MMA] in {
- def NAME :
- XX3Form_AT3_XAB6<opcode, !or(xo, 0x01), (outs acc:$AT), IOL,
- !strconcat(asmbase#" ", asmstr), IIC_VecFP, []>,
- RegConstraint<"@earlyclobber $AT">;
- def PP :
- XX3Form_AT3_XAB6<opcode, xo, (outs acc:$AT), !con((ins acc:$ATi), IOL),
- !strconcat(asmbase#"pp ", asmstr), IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- }
-}
-
-// Defines 4 instructions, masked/unmasked with masks 8, 4, 4 bits.
-// The XO field for acc/non-acc version is even/odd.
-multiclass ACC_UM_M844_XOEO<bits<6> opcode, bits<8> xo, dag IOL, string asmbase,
- string asmstr> {
- defm NAME : ACC_UM_XOEO<opcode, xo, IOL, asmbase, asmstr>;
- let Predicates = [MMA, PrefixInstrs] in {
- def PM#NAME :
- MMIRR_XX3Form_XY4P8_XAB6<
- opcode, !or(xo, 0x01), (outs acc:$AT),
- !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u8imm:$PMSK)),
- !strconcat("pm"#asmbase#" ", asmstr#", $XMSK, $YMSK, $PMSK"),
- IIC_VecFP, []>,
- RegConstraint<"@earlyclobber $AT">;
- def PM#NAME#PP :
- MMIRR_XX3Form_XY4P8_XAB6<
- opcode, xo, (outs acc:$AT),
- !con((ins acc:$ATi),
- !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u8imm:$PMSK))),
- !strconcat("pm"#asmbase#"pp ", asmstr#", $XMSK, $YMSK, $PMSK"),
- IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- }
-}
-
-// Defines 4 instructions, masked/unmasked with masks 4, 4, 4 bits.
-// The XO field for acc/non-acc version is even/odd.
-multiclass ACC_UM_M444_XOEO<bits<6> opcode, bits<8> xo, dag IOL, string asmbase,
- string asmstr> {
- defm NAME : ACC_UM_XOEO<opcode, xo, IOL, asmbase, asmstr>;
- let Predicates = [MMA, PrefixInstrs] in {
- def PM#NAME :
- MMIRR_XX3Form_XYP4_XAB6<
- opcode, !or(xo, 0x01), (outs acc:$AT),
- !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u4imm:$PMSK)),
- !strconcat("pm"#asmbase#" ", asmstr#", $XMSK, $YMSK, $PMSK"),
- IIC_VecFP, []>,
- RegConstraint<"@earlyclobber $AT">;
- def PM#NAME#PP :
- MMIRR_XX3Form_XYP4_XAB6<
- opcode, xo, (outs acc:$AT),
- !con((ins acc:$ATi),
- !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u4imm:$PMSK))),
- !strconcat("pm"#asmbase#"pp ", asmstr#", $XMSK, $YMSK, $PMSK"),
- IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- }
-}
-
-// Defines 4 instructions, masked/unmasked with masks 2, 4, 4 bits.
-// The XO field for acc/non-acc version is even/odd.
-multiclass ACC_UM_M244_XOEO<bits<6> opcode, bits<8> xo, dag IOL, string asmbase,
- string asmstr> {
- defm NAME : ACC_UM_XOEO<opcode, xo, IOL, asmbase, asmstr>;
- let Predicates = [MMA, PrefixInstrs] in {
- def PM#NAME :
- MMIRR_XX3Form_XY4P2_XAB6<
- opcode, !or(xo, 0x01), (outs acc:$AT),
- !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u2imm:$PMSK)),
- !strconcat("pm"#asmbase#" ", asmstr#", $XMSK, $YMSK, $PMSK"),
- IIC_VecFP, []>,
- RegConstraint<"@earlyclobber $AT">;
- def PM#NAME#PP :
- MMIRR_XX3Form_XY4P2_XAB6<
- opcode, xo, (outs acc:$AT),
- !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u2imm:$PMSK))),
- !strconcat("pm"#asmbase#"pp ", asmstr#", $XMSK, $YMSK, $PMSK"),
- IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- }
-}
-
-// Defines 4 instructions, masked/unmasked with masks 2, 4, 4 bits.
-// Upper nibble of XO field for acc/non-acc version is 0x4/0x6.
-multiclass ACC_UM_M244_XO46<bits<6> opcode, bits<8> xo, dag IOL, string asmbase,
- string asmstr> {
- let Predicates = [MMA] in {
- def NAME :
- XX3Form_AT3_XAB6<opcode, xo, (outs acc:$AT), IOL,
- !strconcat(asmbase#" ", asmstr), IIC_VecFP, []>,
- RegConstraint<"@earlyclobber $AT">;
- def PP :
- XX3Form_AT3_XAB6<
- opcode, !or(xo, 0x20), (outs acc:$AT), !con((ins acc:$ATi), IOL),
- !strconcat(asmbase#"pp ", asmstr), IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- }
- let Predicates = [MMA, PrefixInstrs] in {
- def PM#NAME :
- MMIRR_XX3Form_XY4P2_XAB6<
- opcode, xo, (outs acc:$AT),
- !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u2imm:$PMSK)),
- !strconcat("pm"#asmbase#" ", asmstr#", $XMSK, $YMSK, $PMSK"),
- IIC_VecFP, []>,
- RegConstraint<"@earlyclobber $AT">;
- def PM#NAME#PP :
- MMIRR_XX3Form_XY4P2_XAB6<
- opcode, !or(xo, 0x20), (outs acc:$AT),
- !con((ins acc:$ATi),
- !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u2imm:$PMSK))),
- !strconcat("pm"#asmbase#"pp ", asmstr#", $XMSK, $YMSK, $PMSK"),
- IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- }
-}
-
-// Defines 10 instructions, operand negating, unmasked, masked with 2, 4, 4
-// bits. Upper nibble are masked with 0x8, 0x4, 0xC for negating operands.
-multiclass ACC_NEG_UM_M244_XOM84C<bits<6> opcode, bits<8> xo, dag IOL,
- string asmbase, string asmstr> {
- defm NAME : ACC_UM_M244_XOEO<opcode, xo, IOL, asmbase, asmstr>;
- let Predicates = [MMA] in {
- def PN : XX3Form_AT3_XAB6<
- opcode, !or(xo, 0x80), (outs acc:$AT), !con((ins acc:$ATi), IOL),
- !strconcat(asmbase#"pn ", asmstr), IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- def NP : XX3Form_AT3_XAB6<
- opcode, !or(xo, 0x40), (outs acc:$AT), !con((ins acc:$ATi), IOL),
- !strconcat(asmbase#"np ", asmstr), IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- def NN : XX3Form_AT3_XAB6<
- opcode, !or(xo, 0xC0), (outs acc:$AT), !con((ins acc:$ATi), IOL),
- !strconcat(asmbase#"nn ", asmstr), IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- }
- let Predicates = [MMA, PrefixInstrs] in {
- def PM#NAME#PN :
- MMIRR_XX3Form_XY4P2_XAB6<
- opcode, !or(xo, 0x80), (outs acc:$AT),
- !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u2imm:$PMSK))),
- !strconcat("pm"#asmbase#"pn ", asmstr#", $XMSK, $YMSK, $PMSK"),
- IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- def PM#NAME#NP :
- MMIRR_XX3Form_XY4P2_XAB6<
- opcode, !or(xo, 0x40), (outs acc:$AT),
- !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u2imm:$PMSK))),
- !strconcat("pm"#asmbase#"np ", asmstr#", $XMSK, $YMSK, $PMSK"),
- IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- def PM#NAME#NN :
- MMIRR_XX3Form_XY4P2_XAB6<
- opcode, !or(xo, 0xC0), (outs acc:$AT),
- !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u2imm:$PMSK))),
- !strconcat("pm"#asmbase#"nn ", asmstr#", $XMSK, $YMSK, $PMSK"),
- IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- }
-}
-
-// Defines 5 instructions, unmasked, operand negating.
-// Upper nibble are masked with 0x8, 0x4, 0xC for negating operands.
-multiclass ACC_NEG_UM_XOM84C<bits<6> opcode, bits<8> xo, dag IOL,
- string asmbase, string asmstr> {
- defm NAME : ACC_UM_XOEO<opcode, xo, IOL, asmbase, asmstr>;
- let Predicates = [MMA] in {
- def PN : XX3Form_AT3_XAB6<opcode, !or(xo, 0x80), (outs acc:$AT),
- !con((ins acc:$ATi), IOL),
- !strconcat(asmbase#"pn ", asmstr), IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- def NP : XX3Form_AT3_XAB6<opcode, !or(xo, 0x40), (outs acc:$AT),
- !con((ins acc:$ATi), IOL),
- !strconcat(asmbase#"np ", asmstr), IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- def NN : XX3Form_AT3_XAB6<opcode, !or(xo, 0xC0), (outs acc:$AT),
- !con((ins acc:$ATi), IOL),
- !strconcat(asmbase#"nn ", asmstr), IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- }
-}
-
-// Defines 10 instructions, operand negating, unmasked, masked with 4, 4 bits.
-// Upper nibble are masked with 0x8, 0x4, 0xC for negating operands.
-multiclass ACC_NEG_UM_M44_XOM84C<bits<6> opcode, bits<8> xo, dag IOL,
- string asmbase, string asmstr> {
- defm NAME : ACC_NEG_UM_XOM84C<opcode, xo, IOL, asmbase, asmstr>;
- let Predicates = [MMA, PrefixInstrs] in {
- def PM#NAME :
- MMIRR_XX3Form_XY4_XAB6<
- opcode, !or(xo, 0x01), (outs acc:$AT),
- !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK)),
- !strconcat("pm"#asmbase#" ", asmstr#", $XMSK, $YMSK"),
- IIC_VecFP, []>,
- RegConstraint<"@earlyclobber $AT">;
- def PM#NAME#PP :
- MMIRR_XX3Form_XY4_XAB6<
- opcode, xo, (outs acc:$AT),
- !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK))),
- !strconcat("pm"#asmbase#"pp ", asmstr#", $XMSK, $YMSK"),
- IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- def PM#NAME#PN :
- MMIRR_XX3Form_XY4_XAB6<
- opcode, !or(xo, 0x80), (outs acc:$AT),
- !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK))),
- !strconcat("pm"#asmbase#"pn ", asmstr#", $XMSK, $YMSK"),
- IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- def PM#NAME#NP :
- MMIRR_XX3Form_XY4_XAB6<
- opcode, !or(xo, 0x40), (outs acc:$AT),
- !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK))),
- !strconcat("pm"#asmbase#"np ", asmstr#", $XMSK, $YMSK"),
- IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- def PM#NAME#NN :
- MMIRR_XX3Form_XY4_XAB6<
- opcode, !or(xo, 0xC0), (outs acc:$AT),
- !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK))),
- !strconcat("pm"#asmbase#"nn ", asmstr#", $XMSK, $YMSK"),
- IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- }
-}
-
-// Defines 10 instructions, operand negating, unmasked, masked with 4, 2 bits.
-// Upper nibble are masked with 0x8, 0x4, 0xC for negating operands.
-multiclass ACC_NEG_UM_M42_XOM84C<bits<6> opcode, bits<8> xo, dag IOL,
- string asmbase, string asmstr> {
- defm NAME : ACC_NEG_UM_XOM84C<opcode, xo, IOL, asmbase, asmstr>;
- let Predicates = [MMA, PrefixInstrs] in {
- def PM#NAME :
- MMIRR_XX3Form_X4Y2_XAB6<
- opcode, !or(xo, 0x01), (outs acc:$AT),
- !con(IOL, (ins u4imm:$XMSK, u2imm:$YMSK)),
- !strconcat("pm"#asmbase#" ", asmstr#", $XMSK, $YMSK"),
- IIC_VecFP, []>,
- RegConstraint<"@earlyclobber $AT">;
- def PM#NAME#PP :
- MMIRR_XX3Form_X4Y2_XAB6<
- opcode, xo, (outs acc:$AT),
- !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u2imm:$YMSK))),
- !strconcat("pm"#asmbase#"pp ", asmstr#", $XMSK, $YMSK"),
- IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- def PM#NAME#PN :
- MMIRR_XX3Form_X4Y2_XAB6<
- opcode, !or(xo, 0x80), (outs acc:$AT),
- !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u2imm:$YMSK))),
- !strconcat("pm"#asmbase#"pn ", asmstr#", $XMSK, $YMSK"),
- IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- def PM#NAME#NP :
- MMIRR_XX3Form_X4Y2_XAB6<
- opcode, !or(xo, 0x40), (outs acc:$AT),
- !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u2imm:$YMSK))),
- !strconcat("pm"#asmbase#"np ", asmstr#", $XMSK, $YMSK"),
- IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- def PM#NAME#NN :
- MMIRR_XX3Form_X4Y2_XAB6<
- opcode, !or(xo, 0xC0), (outs acc:$AT),
- !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u2imm:$YMSK))),
- !strconcat("pm"#asmbase#"nn ", asmstr#", $XMSK, $YMSK"),
- IIC_VecFP, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- }
-}
-
-// End of class definitions.
-//-----------------------------------------------------------------------------
-
-let Predicates = [MMA] in {
- def XXMFACC :
- XForm_AT3<31, 0, 177, (outs acc:$ASo), (ins acc:$AS), "xxmfacc $AS",
- IIC_VecGeneral,
- [(set v512i1:$ASo, (int_ppc_mma_xxmfacc v512i1:$AS))]>,
- RegConstraint<"$ASo = $AS">, NoEncode<"$ASo">;
- def XXMTACC :
- XForm_AT3<31, 1, 177, (outs acc:$AT), (ins acc:$ATi), "xxmtacc $AT",
- IIC_VecGeneral,
- [(set v512i1:$AT, (int_ppc_mma_xxmtacc v512i1:$ATi))]>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- def KILL_PAIR : PPCPostRAExpPseudo<(outs vsrprc:$XTp), (ins vsrprc:$XSp),
- "#KILL_PAIR", []>,
- RegConstraint<"$XTp = $XSp">;
- def BUILD_UACC : PPCPostRAExpPseudo<(outs acc:$AT), (ins uacc:$AS),
- "#BUILD_UACC $AT, $AS", []>;
- // We define XXSETACCZ as rematerializable to undo CSE of that intrinsic in
- // the backend. We avoid CSE here because it generates a copy of the acc
- // register and this copy is more expensive than calling the intrinsic again.
- let isAsCheapAsAMove = 1, isReMaterializable = 1 in {
- def XXSETACCZ :
- XForm_AT3<31, 3, 177, (outs acc:$AT), (ins), "xxsetaccz $AT", IIC_VecGeneral,
- [(set v512i1:$AT, (int_ppc_mma_xxsetaccz))]>;
- }
- def XVI8GER4SPP :
- XX3Form_AT3_XAB6<59, 99, (outs acc:$AT), (ins acc:$ATi, vsrc:$XA, vsrc:$XB),
- "xvi8ger4spp $AT, $XA, $XB", IIC_VecGeneral, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
- let mayStore = 1 in {
- def SPILL_ACC: PPCEmitTimePseudo<(outs), (ins acc:$AT, memrix16:$dst),
- "#SPILL_ACC", []>;
- def SPILL_UACC: PPCEmitTimePseudo<(outs), (ins uacc:$AT, memrix16:$dst),
- "#SPILL_UACC", []>;
- }
- let mayLoad = 1, hasSideEffects = 0 in {
- def RESTORE_ACC: PPCEmitTimePseudo<(outs acc:$AT), (ins memrix16:$src),
- "#RESTORE_ACC", []>;
- def RESTORE_UACC: PPCEmitTimePseudo<(outs uacc:$AT), (ins memrix16:$src),
- "#RESTORE_UACC", []>;
- }
-}
-
-let Predicates = [MMA, PrefixInstrs] in {
- def PMXVI8GER4SPP :
- MMIRR_XX3Form_XYP4_XAB6<59, 99, (outs acc:$AT),
- (ins acc:$ATi, vsrc:$XA,vsrc:$XB, u4imm:$XMSK,
- u4imm:$YMSK, u4imm:$PMSK),
- "pmxvi8ger4spp $AT, $XA, $XB, $XMSK, $YMSK, $PMSK",
- IIC_VecGeneral, []>,
- RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
-}
-
-// MMA accumulating/non-accumulating instructions.
-//------------------------------------------------------------------------------
-
-// XVBF16GER2, XVBF16GER2PP, XVBF16GER2PN, XVBF16GER2NP, XVBF16GER2NN
-// PMXVBF16GER2, PMXVBF16GER2PP, PMXVBF16GER2PN, PMXVBF16GER2NP, PMXVBF16GER2NN
-defm XVBF16GER2 : ACC_NEG_UM_M244_XOM84C<59, 50, (ins vsrc:$XA, vsrc:$XB),
- "xvbf16ger2", "$AT, $XA, $XB">;
-
-// XVI4GER8, XVI4GER8PP, PMXVI4GER8, PMXVI4GER8PP
-defm XVI4GER8 : ACC_UM_M844_XOEO<59, 34, (ins vsrc:$XA, vsrc:$XB),
- "xvi4ger8", "$AT, $XA, $XB">;
-
-// XVI8GER4, XVI8GER4PP, PMXVI8GER4, PMXVI8GER4PP
-defm XVI8GER4 : ACC_UM_M444_XOEO<59, 2, (ins vsrc:$XA, vsrc:$XB),
- "xvi8ger4", "$AT, $XA, $XB">;
-
-// XVI16GER2, XVI16GER2PP, PMXVI16GER2, PMXVI16GER2PP
-defm XVI16GER2 : ACC_UM_M244_XO46<59, 75, (ins vsrc:$XA, vsrc:$XB),
- "xvi16ger2", "$AT, $XA, $XB">;
-
-// XVI16GER2S, XVI16GER2SPP, PMXVI16GER2S, PMXVI16GER2SPP
-defm XVI16GER2S : ACC_UM_M244_XOEO<59, 42, (ins vsrc:$XA, vsrc:$XB),
- "xvi16ger2s", "$AT, $XA, $XB">;
-
-// XVF16GER2, XVF16GER2PP, XVF16GER2PN, XVF16GER2NP, XVF16GER2NN
-// PMXVF16GER2, PMXVF16GER2PP, PMXVF16GER2PN, PMXVF16GER2NP, PMXVF16GER2NN
-defm XVF16GER2 : ACC_NEG_UM_M244_XOM84C<59, 18, (ins vsrc:$XA, vsrc:$XB),
- "xvf16ger2", "$AT, $XA, $XB">;
-
-// XVF32GER, XVF32GERPP, XVF32GERPN, XVF32GERNP, XVF32GERPP
-// PMXVF32GER, PMXVF32GERPP, PMXVF32GERPN, PMXVF32GERNP, PMXVF32GERPP
-defm XVF32GER : ACC_NEG_UM_M44_XOM84C<59, 26, (ins vsrc:$XA, vsrc:$XB),
- "xvf32ger", "$AT, $XA, $XB">;
-
-// XVF64GER, XVF64GERPP, XVF64GERPN, XVF64GERNP, XVF64GERNN
-// PMXVF64GER, PMXVF64GERPP, PMXVF64GERPN, PMXVF64GERNP, PMXVF64GERNN
-defm XVF64GER : ACC_NEG_UM_M42_XOM84C<59, 58, (ins vsrpevenrc:$XA, vsrc:$XB),
- "xvf64ger", "$AT, $XA, $XB">;
-//------------------------------------------------------------------------------
-
-// MMA Intrinsics
-let Predicates = [MMA] in {
- def : Pat<(v512i1 (int_ppc_mma_xvi4ger8 v16i8:$XA, v16i8:$XB)),
- (XVI4GER8 RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvi4ger8pp v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
- (XVI4GER8PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
-
- def : Pat<(v512i1 (int_ppc_mma_xvi8ger4 v16i8:$XA, v16i8:$XB)),
- (XVI8GER4 RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvi8ger4pp v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
- (XVI8GER4PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
-
- def : Pat<(v512i1 (int_ppc_mma_xvi16ger2s v16i8:$XA, v16i8:$XB)),
- (XVI16GER2S RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvi16ger2spp v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
- (XVI16GER2SPP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
-
- def : Pat<(v512i1 (int_ppc_mma_xvf16ger2 v16i8:$XA, v16i8:$XB)),
- (XVF16GER2 RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvf16ger2pp v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
- (XVF16GER2PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvf16ger2pn v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
- (XVF16GER2PN $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvf16ger2np v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
- (XVF16GER2NP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvf16ger2nn v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
- (XVF16GER2NN $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
-
- def : Pat<(v512i1 (int_ppc_mma_xvf32ger v16i8:$XA, v16i8:$XB)),
- (XVF32GER RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvf32gerpp v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
- (XVF32GERPP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvf32gerpn v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
- (XVF32GERPN $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvf32gernp v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
- (XVF32GERNP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvf32gernn v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
- (XVF32GERNN $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvf64ger v256i1:$XA, v16i8:$XB)),
- (XVF64GER $XA, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvf64gerpp v512i1:$ATi, v256i1:$XA, v16i8:$XB)),
- (XVF64GERPP $ATi, $XA, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvf64gerpn v512i1:$ATi, v256i1:$XA, v16i8:$XB)),
- (XVF64GERPN $ATi, $XA, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvf64gernp v512i1:$ATi, v256i1:$XA, v16i8:$XB)),
- (XVF64GERNP $ATi, $XA, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvf64gernn v512i1:$ATi, v256i1:$XA, v16i8:$XB)),
- (XVF64GERNN $ATi, $XA, RCCp.BToVSRC)>;
-
- def : Pat<(v512i1 (int_ppc_mma_xvbf16ger2 v16i8:$XA, v16i8:$XB)),
- (XVBF16GER2 RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvbf16ger2pp v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
- (XVBF16GER2PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvbf16ger2pn v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
- (XVBF16GER2PN $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvbf16ger2np v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
- (XVBF16GER2NP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvbf16ger2nn v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
- (XVBF16GER2NN $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvi16ger2 v16i8:$XA, v16i8:$XB)),
- (XVI16GER2 RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvi16ger2pp v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
- (XVI16GER2PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
- def : Pat<(v512i1 (int_ppc_mma_xvi8ger4spp v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
- (XVI8GER4SPP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
-}
-
-// MMA Intrinsics
-let Predicates = [MMA, PrefixInstrs] in {
- def : Pat<(v512i1 (int_ppc_mma_pmxvi4ger8 v16i8:$XA, v16i8:$XB, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk8Imm:$PMSK)),
- (PMXVI4GER8 RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk8Imm:$PMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvi4ger8pp v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK,
- Msk8Imm:$PMSK)),
- (PMXVI4GER8PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk8Imm:$PMSK)>;
-
- def : Pat<(v512i1 (int_ppc_mma_pmxvi8ger4 v16i8:$XA, v16i8:$XB, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk4Imm:$PMSK)),
- (PMXVI8GER4 RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk4Imm:$PMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvi8ger4pp v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK,
- Msk4Imm:$PMSK)),
- (PMXVI8GER4PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk4Imm:$PMSK)>;
-
- def : Pat<(v512i1 (int_ppc_mma_pmxvi16ger2s v16i8:$XA, v16i8:$XB, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)),
- (PMXVI16GER2S RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvi16ger2spp v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK,
- Msk2Imm:$PMSK)),
- (PMXVI16GER2SPP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvf16ger2 v16i8:$XA, v16i8:$XB, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)),
- (PMXVF16GER2 RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvf16ger2pp v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK,
- Msk2Imm:$PMSK)),
- (PMXVF16GER2PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvf16ger2pn v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK,
- Msk2Imm:$PMSK)),
- (PMXVF16GER2PN $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvf16ger2np v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK,
- Msk2Imm:$PMSK)),
- (PMXVF16GER2NP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvf16ger2pn v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK,
- Msk2Imm:$PMSK)),
- (PMXVF16GER2PN $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvf16ger2np v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK,
- Msk2Imm:$PMSK)),
- (PMXVF16GER2NP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvf16ger2nn v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK,
- Msk2Imm:$PMSK)),
- (PMXVF16GER2NN $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
-
- def : Pat<(v512i1 (int_ppc_mma_pmxvf32ger v16i8:$XA, v16i8:$XB, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK)),
- (PMXVF32GER RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvf32gerpp v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK)),
- (PMXVF32GERPP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvf32gerpn v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK)),
- (PMXVF32GERPN $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvf32gernp v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK)),
- (PMXVF32GERNP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvf32gernn v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK)),
- (PMXVF32GERNN $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK)>;
-
- def : Pat<(v512i1 (int_ppc_mma_pmxvf64ger v256i1:$XA, v16i8:$XB, Msk4Imm:$XMSK,
- Msk2Imm:$YMSK)),
- (PMXVF64GER $XA, RCCp.BToVSRC, Msk4Imm:$XMSK, Msk2Imm:$YMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvf64gerpp v512i1:$ATi, v256i1:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk2Imm:$YMSK)),
- (PMXVF64GERPP $ATi, $XA, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk2Imm:$YMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvf64gerpn v512i1:$ATi, v256i1:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk2Imm:$YMSK)),
- (PMXVF64GERPN $ATi, $XA, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk2Imm:$YMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvf64gernp v512i1:$ATi, v256i1:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk2Imm:$YMSK)),
- (PMXVF64GERNP $ATi, $XA, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk2Imm:$YMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvf64gernn v512i1:$ATi, v256i1:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk2Imm:$YMSK)),
- (PMXVF64GERNN $ATi, $XA, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk2Imm:$YMSK)>;
-
- def : Pat<(v512i1 (int_ppc_mma_pmxvbf16ger2 v16i8:$XA, v16i8:$XB, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)),
- (PMXVBF16GER2 RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvbf16ger2pp v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK,
- Msk2Imm:$PMSK)),
- (PMXVBF16GER2PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvbf16ger2pn v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK,
- Msk2Imm:$PMSK)),
- (PMXVBF16GER2PN $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvbf16ger2np v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK,
- Msk2Imm:$PMSK)),
- (PMXVBF16GER2NP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvbf16ger2nn v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK,
- Msk2Imm:$PMSK)),
- (PMXVBF16GER2NN $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvi16ger2 v16i8:$XA, v16i8:$XB, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)),
- (PMXVI16GER2 RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvi8ger4spp v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK,
- Msk2Imm:$PMSK)),
- (PMXVI8GER4SPP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
- def : Pat<(v512i1 (int_ppc_mma_pmxvi16ger2pp v512i1:$ATi, v16i8:$XA, v16i8:$XB,
- Msk4Imm:$XMSK, Msk4Imm:$YMSK,
- Msk2Imm:$PMSK)),
- (PMXVI16GER2PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
- Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
-}
-
-def Concats {
- dag VecsToVecPair0 =
- (v256i1 (INSERT_SUBREG
- (INSERT_SUBREG (IMPLICIT_DEF), $vs0, sub_vsx1),
- $vs1, sub_vsx0));
- dag VecsToVecPair1 =
- (v256i1 (INSERT_SUBREG
- (INSERT_SUBREG (IMPLICIT_DEF), $vs2, sub_vsx1),
- $vs3, sub_vsx0));
- dag VecsToVecQuad =
- (BUILD_UACC (INSERT_SUBREG
- (INSERT_SUBREG (v512i1 (IMPLICIT_DEF)),
- (KILL_PAIR VecsToVecPair0), sub_pair0),
- (KILL_PAIR VecsToVecPair1), sub_pair1));
-}
-
-def Extracts {
- dag Pair0 = (v256i1 (EXTRACT_SUBREG $v, sub_pair0));
- dag Pair1 = (v256i1 (EXTRACT_SUBREG $v, sub_pair1));
- dag Vec0 = (v4i32 (EXTRACT_SUBREG Pair0, sub_vsx0));
- dag Vec1 = (v4i32 (EXTRACT_SUBREG Pair0, sub_vsx1));
- dag Vec2 = (v4i32 (EXTRACT_SUBREG Pair1, sub_vsx0));
- dag Vec3 = (v4i32 (EXTRACT_SUBREG Pair1, sub_vsx1));
-}
-
-let Predicates = [MMA] in {
- def : Pat<(v512i1 (PPCAccBuild v4i32:$vs1, v4i32:$vs0, v4i32:$vs3, v4i32:$vs2)),
- (XXMTACC Concats.VecsToVecQuad)>;
- def : Pat<(v512i1 (int_ppc_mma_assemble_acc v16i8:$vs1, v16i8:$vs0,
- v16i8:$vs3, v16i8:$vs2)),
- (XXMTACC Concats.VecsToVecQuad)>;
- def : Pat<(v512i1 (PPCxxmfacc v512i1:$AS)), (XXMFACC acc:$AS)>;
- def : Pat<(v4i32 (PPCAccExtractVsx acc:$v, (i64 0))),
- Extracts.Vec0>;
- def : Pat<(v4i32 (PPCAccExtractVsx acc:$v, (i64 1))),
- Extracts.Vec1>;
- def : Pat<(v4i32 (PPCAccExtractVsx acc:$v, (i64 2))),
- Extracts.Vec2>;
- def : Pat<(v4i32 (PPCAccExtractVsx acc:$v, (i64 3))),
- Extracts.Vec3>;
-}
-
-let Predicates = [PairedVectorMemops] in {
- def : Pat<(v256i1 (PPCPairBuild v4i32:$vs1, v4i32:$vs0)),
- Concats.VecsToVecPair0>;
- def : Pat<(v256i1 (int_ppc_vsx_assemble_pair v16i8:$vs1, v16i8:$vs0)),
- Concats.VecsToVecPair0>;
- def : Pat<(v4i32 (PPCPairExtractVsx vsrpevenrc:$v, (i64 0))),
- (v4i32 (EXTRACT_SUBREG $v, sub_vsx0))>;
- def : Pat<(v4i32 (PPCPairExtractVsx vsrpevenrc:$v, (i64 1))),
- (v4i32 (EXTRACT_SUBREG $v, sub_vsx1))>;
-}
-
-let mayLoad = 1, mayStore = 0, Predicates = [PairedVectorMemops] in {
- def LXVP : DQForm_XTp5_RA17_MEM<6, 0, (outs vsrprc:$XTp),
- (ins memrix16:$DQ_RA), "lxvp $XTp, $DQ_RA",
- IIC_LdStLFD, []>;
- def LXVPX : XForm_XTp5_XAB5<31, 333, (outs vsrprc:$XTp), (ins memrr:$src),
- "lxvpx $XTp, $src", IIC_LdStLFD,
- []>;
-}
-
-let mayLoad = 0, mayStore = 1, Predicates = [PairedVectorMemops] in {
- def STXVP : DQForm_XTp5_RA17_MEM<6, 1, (outs), (ins vsrprc:$XTp,
- memrix16:$DQ_RA), "stxvp $XTp, $DQ_RA",
- IIC_LdStLFD, []>;
- def STXVPX : XForm_XTp5_XAB5<31, 461, (outs), (ins vsrprc:$XTp, memrr:$dst),
- "stxvpx $XTp, $dst", IIC_LdStLFD,
- []>;
-}
-
-let mayLoad = 1, mayStore = 0, Predicates = [PairedVectorMemops, PrefixInstrs] in {
- defm PLXVP :
- 8LS_DForm_R_XTp5_SI34_MEM_p<1, 58, (outs vsrprc:$XTp), (ins memri34:$D_RA),
- (ins memri34_pcrel:$D_RA), "plxvp $XTp, $D_RA",
- IIC_LdStLFD>;
-}
-
-let mayLoad = 0, mayStore = 1, Predicates = [PairedVectorMemops, PrefixInstrs] in {
- defm PSTXVP :
- 8LS_DForm_R_XTp5_SI34_MEM_p<1, 62, (outs), (ins vsrprc:$XTp, memri34:$D_RA),
- (ins vsrprc:$XTp, memri34_pcrel:$D_RA),
- "pstxvp $XTp, $D_RA", IIC_LdStLFD>;
-}
-
-let Predicates = [PairedVectorMemops] in {
- // Intrinsics for Paired Vector Loads.
- def : Pat<(v256i1 (int_ppc_vsx_lxvp iaddrX16:$src)), (LXVP memrix16:$src)>;
- def : Pat<(v256i1 (int_ppc_vsx_lxvp xaddrX16:$src)), (LXVPX xaddrX16:$src)>;
- let Predicates = [PairedVectorMemops, PrefixInstrs] in {
- def : Pat<(v256i1 (int_ppc_vsx_lxvp iaddrX34:$src)), (PLXVP memri34:$src)>;
- }
- // Intrinsics for Paired Vector Stores.
- def : Pat<(int_ppc_vsx_stxvp v256i1:$XSp, iaddrX16:$dst),
- (STXVP $XSp, memrix16:$dst)>;
- def : Pat<(int_ppc_vsx_stxvp v256i1:$XSp, xaddrX16:$dst),
- (STXVPX $XSp, xaddrX16:$dst)>;
- let Predicates = [PairedVectorMemops, PrefixInstrs] in {
- def : Pat<(int_ppc_vsx_stxvp v256i1:$XSp, iaddrX34:$dst),
- (PSTXVP $XSp, memri34:$dst)>;
- }
-}
-
+// Multiclass definitions for MMA accumulator instructions.
+// ----------------------------------------------------------------------------
+
+// Defines 2 unmasked instructions where the xo field for acc/non-acc version
+// is even/odd.
+multiclass ACC_UM_XOEO<bits<6> opcode, bits<8> xo, dag IOL, string asmbase,
+ string asmstr> {
+ let Predicates = [MMA] in {
+ def NAME :
+ XX3Form_AT3_XAB6<opcode, !or(xo, 0x01), (outs acc:$AT), IOL,
+ !strconcat(asmbase#" ", asmstr), IIC_VecFP, []>,
+ RegConstraint<"@earlyclobber $AT">;
+ def PP :
+ XX3Form_AT3_XAB6<opcode, xo, (outs acc:$AT), !con((ins acc:$ATi), IOL),
+ !strconcat(asmbase#"pp ", asmstr), IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ }
+}
+
+// Defines 4 instructions, masked/unmasked with masks 8, 4, 4 bits.
+// The XO field for acc/non-acc version is even/odd.
+multiclass ACC_UM_M844_XOEO<bits<6> opcode, bits<8> xo, dag IOL, string asmbase,
+ string asmstr> {
+ defm NAME : ACC_UM_XOEO<opcode, xo, IOL, asmbase, asmstr>;
+ let Predicates = [MMA, PrefixInstrs] in {
+ def PM#NAME :
+ MMIRR_XX3Form_XY4P8_XAB6<
+ opcode, !or(xo, 0x01), (outs acc:$AT),
+ !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u8imm:$PMSK)),
+ !strconcat("pm"#asmbase#" ", asmstr#", $XMSK, $YMSK, $PMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"@earlyclobber $AT">;
+ def PM#NAME#PP :
+ MMIRR_XX3Form_XY4P8_XAB6<
+ opcode, xo, (outs acc:$AT),
+ !con((ins acc:$ATi),
+ !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u8imm:$PMSK))),
+ !strconcat("pm"#asmbase#"pp ", asmstr#", $XMSK, $YMSK, $PMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ }
+}
+
+// Defines 4 instructions, masked/unmasked with masks 4, 4, 4 bits.
+// The XO field for acc/non-acc version is even/odd.
+multiclass ACC_UM_M444_XOEO<bits<6> opcode, bits<8> xo, dag IOL, string asmbase,
+ string asmstr> {
+ defm NAME : ACC_UM_XOEO<opcode, xo, IOL, asmbase, asmstr>;
+ let Predicates = [MMA, PrefixInstrs] in {
+ def PM#NAME :
+ MMIRR_XX3Form_XYP4_XAB6<
+ opcode, !or(xo, 0x01), (outs acc:$AT),
+ !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u4imm:$PMSK)),
+ !strconcat("pm"#asmbase#" ", asmstr#", $XMSK, $YMSK, $PMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"@earlyclobber $AT">;
+ def PM#NAME#PP :
+ MMIRR_XX3Form_XYP4_XAB6<
+ opcode, xo, (outs acc:$AT),
+ !con((ins acc:$ATi),
+ !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u4imm:$PMSK))),
+ !strconcat("pm"#asmbase#"pp ", asmstr#", $XMSK, $YMSK, $PMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ }
+}
+
+// Defines 4 instructions, masked/unmasked with masks 2, 4, 4 bits.
+// The XO field for acc/non-acc version is even/odd.
+multiclass ACC_UM_M244_XOEO<bits<6> opcode, bits<8> xo, dag IOL, string asmbase,
+ string asmstr> {
+ defm NAME : ACC_UM_XOEO<opcode, xo, IOL, asmbase, asmstr>;
+ let Predicates = [MMA, PrefixInstrs] in {
+ def PM#NAME :
+ MMIRR_XX3Form_XY4P2_XAB6<
+ opcode, !or(xo, 0x01), (outs acc:$AT),
+ !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u2imm:$PMSK)),
+ !strconcat("pm"#asmbase#" ", asmstr#", $XMSK, $YMSK, $PMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"@earlyclobber $AT">;
+ def PM#NAME#PP :
+ MMIRR_XX3Form_XY4P2_XAB6<
+ opcode, xo, (outs acc:$AT),
+ !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u2imm:$PMSK))),
+ !strconcat("pm"#asmbase#"pp ", asmstr#", $XMSK, $YMSK, $PMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ }
+}
+
+// Defines 4 instructions, masked/unmasked with masks 2, 4, 4 bits.
+// Upper nibble of XO field for acc/non-acc version is 0x4/0x6.
+multiclass ACC_UM_M244_XO46<bits<6> opcode, bits<8> xo, dag IOL, string asmbase,
+ string asmstr> {
+ let Predicates = [MMA] in {
+ def NAME :
+ XX3Form_AT3_XAB6<opcode, xo, (outs acc:$AT), IOL,
+ !strconcat(asmbase#" ", asmstr), IIC_VecFP, []>,
+ RegConstraint<"@earlyclobber $AT">;
+ def PP :
+ XX3Form_AT3_XAB6<
+ opcode, !or(xo, 0x20), (outs acc:$AT), !con((ins acc:$ATi), IOL),
+ !strconcat(asmbase#"pp ", asmstr), IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ }
+ let Predicates = [MMA, PrefixInstrs] in {
+ def PM#NAME :
+ MMIRR_XX3Form_XY4P2_XAB6<
+ opcode, xo, (outs acc:$AT),
+ !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u2imm:$PMSK)),
+ !strconcat("pm"#asmbase#" ", asmstr#", $XMSK, $YMSK, $PMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"@earlyclobber $AT">;
+ def PM#NAME#PP :
+ MMIRR_XX3Form_XY4P2_XAB6<
+ opcode, !or(xo, 0x20), (outs acc:$AT),
+ !con((ins acc:$ATi),
+ !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u2imm:$PMSK))),
+ !strconcat("pm"#asmbase#"pp ", asmstr#", $XMSK, $YMSK, $PMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ }
+}
+
+// Defines 10 instructions, operand negating, unmasked, masked with 2, 4, 4
+// bits. Upper nibble are masked with 0x8, 0x4, 0xC for negating operands.
+multiclass ACC_NEG_UM_M244_XOM84C<bits<6> opcode, bits<8> xo, dag IOL,
+ string asmbase, string asmstr> {
+ defm NAME : ACC_UM_M244_XOEO<opcode, xo, IOL, asmbase, asmstr>;
+ let Predicates = [MMA] in {
+ def PN : XX3Form_AT3_XAB6<
+ opcode, !or(xo, 0x80), (outs acc:$AT), !con((ins acc:$ATi), IOL),
+ !strconcat(asmbase#"pn ", asmstr), IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ def NP : XX3Form_AT3_XAB6<
+ opcode, !or(xo, 0x40), (outs acc:$AT), !con((ins acc:$ATi), IOL),
+ !strconcat(asmbase#"np ", asmstr), IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ def NN : XX3Form_AT3_XAB6<
+ opcode, !or(xo, 0xC0), (outs acc:$AT), !con((ins acc:$ATi), IOL),
+ !strconcat(asmbase#"nn ", asmstr), IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ }
+ let Predicates = [MMA, PrefixInstrs] in {
+ def PM#NAME#PN :
+ MMIRR_XX3Form_XY4P2_XAB6<
+ opcode, !or(xo, 0x80), (outs acc:$AT),
+ !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u2imm:$PMSK))),
+ !strconcat("pm"#asmbase#"pn ", asmstr#", $XMSK, $YMSK, $PMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ def PM#NAME#NP :
+ MMIRR_XX3Form_XY4P2_XAB6<
+ opcode, !or(xo, 0x40), (outs acc:$AT),
+ !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u2imm:$PMSK))),
+ !strconcat("pm"#asmbase#"np ", asmstr#", $XMSK, $YMSK, $PMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ def PM#NAME#NN :
+ MMIRR_XX3Form_XY4P2_XAB6<
+ opcode, !or(xo, 0xC0), (outs acc:$AT),
+ !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK, u2imm:$PMSK))),
+ !strconcat("pm"#asmbase#"nn ", asmstr#", $XMSK, $YMSK, $PMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ }
+}
+
+// Defines 5 instructions, unmasked, operand negating.
+// Upper nibble are masked with 0x8, 0x4, 0xC for negating operands.
+multiclass ACC_NEG_UM_XOM84C<bits<6> opcode, bits<8> xo, dag IOL,
+ string asmbase, string asmstr> {
+ defm NAME : ACC_UM_XOEO<opcode, xo, IOL, asmbase, asmstr>;
+ let Predicates = [MMA] in {
+ def PN : XX3Form_AT3_XAB6<opcode, !or(xo, 0x80), (outs acc:$AT),
+ !con((ins acc:$ATi), IOL),
+ !strconcat(asmbase#"pn ", asmstr), IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ def NP : XX3Form_AT3_XAB6<opcode, !or(xo, 0x40), (outs acc:$AT),
+ !con((ins acc:$ATi), IOL),
+ !strconcat(asmbase#"np ", asmstr), IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ def NN : XX3Form_AT3_XAB6<opcode, !or(xo, 0xC0), (outs acc:$AT),
+ !con((ins acc:$ATi), IOL),
+ !strconcat(asmbase#"nn ", asmstr), IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ }
+}
+
+// Defines 10 instructions, operand negating, unmasked, masked with 4, 4 bits.
+// Upper nibble are masked with 0x8, 0x4, 0xC for negating operands.
+multiclass ACC_NEG_UM_M44_XOM84C<bits<6> opcode, bits<8> xo, dag IOL,
+ string asmbase, string asmstr> {
+ defm NAME : ACC_NEG_UM_XOM84C<opcode, xo, IOL, asmbase, asmstr>;
+ let Predicates = [MMA, PrefixInstrs] in {
+ def PM#NAME :
+ MMIRR_XX3Form_XY4_XAB6<
+ opcode, !or(xo, 0x01), (outs acc:$AT),
+ !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK)),
+ !strconcat("pm"#asmbase#" ", asmstr#", $XMSK, $YMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"@earlyclobber $AT">;
+ def PM#NAME#PP :
+ MMIRR_XX3Form_XY4_XAB6<
+ opcode, xo, (outs acc:$AT),
+ !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK))),
+ !strconcat("pm"#asmbase#"pp ", asmstr#", $XMSK, $YMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ def PM#NAME#PN :
+ MMIRR_XX3Form_XY4_XAB6<
+ opcode, !or(xo, 0x80), (outs acc:$AT),
+ !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK))),
+ !strconcat("pm"#asmbase#"pn ", asmstr#", $XMSK, $YMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ def PM#NAME#NP :
+ MMIRR_XX3Form_XY4_XAB6<
+ opcode, !or(xo, 0x40), (outs acc:$AT),
+ !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK))),
+ !strconcat("pm"#asmbase#"np ", asmstr#", $XMSK, $YMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ def PM#NAME#NN :
+ MMIRR_XX3Form_XY4_XAB6<
+ opcode, !or(xo, 0xC0), (outs acc:$AT),
+ !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u4imm:$YMSK))),
+ !strconcat("pm"#asmbase#"nn ", asmstr#", $XMSK, $YMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ }
+}
+
+// Defines 10 instructions, operand negating, unmasked, masked with 4, 2 bits.
+// Upper nibble are masked with 0x8, 0x4, 0xC for negating operands.
+multiclass ACC_NEG_UM_M42_XOM84C<bits<6> opcode, bits<8> xo, dag IOL,
+ string asmbase, string asmstr> {
+ defm NAME : ACC_NEG_UM_XOM84C<opcode, xo, IOL, asmbase, asmstr>;
+ let Predicates = [MMA, PrefixInstrs] in {
+ def PM#NAME :
+ MMIRR_XX3Form_X4Y2_XAB6<
+ opcode, !or(xo, 0x01), (outs acc:$AT),
+ !con(IOL, (ins u4imm:$XMSK, u2imm:$YMSK)),
+ !strconcat("pm"#asmbase#" ", asmstr#", $XMSK, $YMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"@earlyclobber $AT">;
+ def PM#NAME#PP :
+ MMIRR_XX3Form_X4Y2_XAB6<
+ opcode, xo, (outs acc:$AT),
+ !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u2imm:$YMSK))),
+ !strconcat("pm"#asmbase#"pp ", asmstr#", $XMSK, $YMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ def PM#NAME#PN :
+ MMIRR_XX3Form_X4Y2_XAB6<
+ opcode, !or(xo, 0x80), (outs acc:$AT),
+ !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u2imm:$YMSK))),
+ !strconcat("pm"#asmbase#"pn ", asmstr#", $XMSK, $YMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ def PM#NAME#NP :
+ MMIRR_XX3Form_X4Y2_XAB6<
+ opcode, !or(xo, 0x40), (outs acc:$AT),
+ !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u2imm:$YMSK))),
+ !strconcat("pm"#asmbase#"np ", asmstr#", $XMSK, $YMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ def PM#NAME#NN :
+ MMIRR_XX3Form_X4Y2_XAB6<
+ opcode, !or(xo, 0xC0), (outs acc:$AT),
+ !con((ins acc:$ATi), !con(IOL, (ins u4imm:$XMSK, u2imm:$YMSK))),
+ !strconcat("pm"#asmbase#"nn ", asmstr#", $XMSK, $YMSK"),
+ IIC_VecFP, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ }
+}
+
+// End of class definitions.
+//-----------------------------------------------------------------------------
+
+let Predicates = [MMA] in {
+ def XXMFACC :
+ XForm_AT3<31, 0, 177, (outs acc:$ASo), (ins acc:$AS), "xxmfacc $AS",
+ IIC_VecGeneral,
+ [(set v512i1:$ASo, (int_ppc_mma_xxmfacc v512i1:$AS))]>,
+ RegConstraint<"$ASo = $AS">, NoEncode<"$ASo">;
+ def XXMTACC :
+ XForm_AT3<31, 1, 177, (outs acc:$AT), (ins acc:$ATi), "xxmtacc $AT",
+ IIC_VecGeneral,
+ [(set v512i1:$AT, (int_ppc_mma_xxmtacc v512i1:$ATi))]>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ def KILL_PAIR : PPCPostRAExpPseudo<(outs vsrprc:$XTp), (ins vsrprc:$XSp),
+ "#KILL_PAIR", []>,
+ RegConstraint<"$XTp = $XSp">;
+ def BUILD_UACC : PPCPostRAExpPseudo<(outs acc:$AT), (ins uacc:$AS),
+ "#BUILD_UACC $AT, $AS", []>;
+ // We define XXSETACCZ as rematerializable to undo CSE of that intrinsic in
+ // the backend. We avoid CSE here because it generates a copy of the acc
+ // register and this copy is more expensive than calling the intrinsic again.
+ let isAsCheapAsAMove = 1, isReMaterializable = 1 in {
+ def XXSETACCZ :
+ XForm_AT3<31, 3, 177, (outs acc:$AT), (ins), "xxsetaccz $AT", IIC_VecGeneral,
+ [(set v512i1:$AT, (int_ppc_mma_xxsetaccz))]>;
+ }
+ def XVI8GER4SPP :
+ XX3Form_AT3_XAB6<59, 99, (outs acc:$AT), (ins acc:$ATi, vsrc:$XA, vsrc:$XB),
+ "xvi8ger4spp $AT, $XA, $XB", IIC_VecGeneral, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+ let mayStore = 1 in {
+ def SPILL_ACC: PPCEmitTimePseudo<(outs), (ins acc:$AT, memrix16:$dst),
+ "#SPILL_ACC", []>;
+ def SPILL_UACC: PPCEmitTimePseudo<(outs), (ins uacc:$AT, memrix16:$dst),
+ "#SPILL_UACC", []>;
+ }
+ let mayLoad = 1, hasSideEffects = 0 in {
+ def RESTORE_ACC: PPCEmitTimePseudo<(outs acc:$AT), (ins memrix16:$src),
+ "#RESTORE_ACC", []>;
+ def RESTORE_UACC: PPCEmitTimePseudo<(outs uacc:$AT), (ins memrix16:$src),
+ "#RESTORE_UACC", []>;
+ }
+}
+
+let Predicates = [MMA, PrefixInstrs] in {
+ def PMXVI8GER4SPP :
+ MMIRR_XX3Form_XYP4_XAB6<59, 99, (outs acc:$AT),
+ (ins acc:$ATi, vsrc:$XA,vsrc:$XB, u4imm:$XMSK,
+ u4imm:$YMSK, u4imm:$PMSK),
+ "pmxvi8ger4spp $AT, $XA, $XB, $XMSK, $YMSK, $PMSK",
+ IIC_VecGeneral, []>,
+ RegConstraint<"$ATi = $AT">, NoEncode<"$ATi">;
+}
+
+// MMA accumulating/non-accumulating instructions.
+//------------------------------------------------------------------------------
+
+// XVBF16GER2, XVBF16GER2PP, XVBF16GER2PN, XVBF16GER2NP, XVBF16GER2NN
+// PMXVBF16GER2, PMXVBF16GER2PP, PMXVBF16GER2PN, PMXVBF16GER2NP, PMXVBF16GER2NN
+defm XVBF16GER2 : ACC_NEG_UM_M244_XOM84C<59, 50, (ins vsrc:$XA, vsrc:$XB),
+ "xvbf16ger2", "$AT, $XA, $XB">;
+
+// XVI4GER8, XVI4GER8PP, PMXVI4GER8, PMXVI4GER8PP
+defm XVI4GER8 : ACC_UM_M844_XOEO<59, 34, (ins vsrc:$XA, vsrc:$XB),
+ "xvi4ger8", "$AT, $XA, $XB">;
+
+// XVI8GER4, XVI8GER4PP, PMXVI8GER4, PMXVI8GER4PP
+defm XVI8GER4 : ACC_UM_M444_XOEO<59, 2, (ins vsrc:$XA, vsrc:$XB),
+ "xvi8ger4", "$AT, $XA, $XB">;
+
+// XVI16GER2, XVI16GER2PP, PMXVI16GER2, PMXVI16GER2PP
+defm XVI16GER2 : ACC_UM_M244_XO46<59, 75, (ins vsrc:$XA, vsrc:$XB),
+ "xvi16ger2", "$AT, $XA, $XB">;
+
+// XVI16GER2S, XVI16GER2SPP, PMXVI16GER2S, PMXVI16GER2SPP
+defm XVI16GER2S : ACC_UM_M244_XOEO<59, 42, (ins vsrc:$XA, vsrc:$XB),
+ "xvi16ger2s", "$AT, $XA, $XB">;
+
+// XVF16GER2, XVF16GER2PP, XVF16GER2PN, XVF16GER2NP, XVF16GER2NN
+// PMXVF16GER2, PMXVF16GER2PP, PMXVF16GER2PN, PMXVF16GER2NP, PMXVF16GER2NN
+defm XVF16GER2 : ACC_NEG_UM_M244_XOM84C<59, 18, (ins vsrc:$XA, vsrc:$XB),
+ "xvf16ger2", "$AT, $XA, $XB">;
+
+// XVF32GER, XVF32GERPP, XVF32GERPN, XVF32GERNP, XVF32GERPP
+// PMXVF32GER, PMXVF32GERPP, PMXVF32GERPN, PMXVF32GERNP, PMXVF32GERPP
+defm XVF32GER : ACC_NEG_UM_M44_XOM84C<59, 26, (ins vsrc:$XA, vsrc:$XB),
+ "xvf32ger", "$AT, $XA, $XB">;
+
+// XVF64GER, XVF64GERPP, XVF64GERPN, XVF64GERNP, XVF64GERNN
+// PMXVF64GER, PMXVF64GERPP, PMXVF64GERPN, PMXVF64GERNP, PMXVF64GERNN
+defm XVF64GER : ACC_NEG_UM_M42_XOM84C<59, 58, (ins vsrpevenrc:$XA, vsrc:$XB),
+ "xvf64ger", "$AT, $XA, $XB">;
+//------------------------------------------------------------------------------
+
+// MMA Intrinsics
+let Predicates = [MMA] in {
+ def : Pat<(v512i1 (int_ppc_mma_xvi4ger8 v16i8:$XA, v16i8:$XB)),
+ (XVI4GER8 RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvi4ger8pp v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
+ (XVI4GER8PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
+
+ def : Pat<(v512i1 (int_ppc_mma_xvi8ger4 v16i8:$XA, v16i8:$XB)),
+ (XVI8GER4 RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvi8ger4pp v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
+ (XVI8GER4PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
+
+ def : Pat<(v512i1 (int_ppc_mma_xvi16ger2s v16i8:$XA, v16i8:$XB)),
+ (XVI16GER2S RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvi16ger2spp v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
+ (XVI16GER2SPP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
+
+ def : Pat<(v512i1 (int_ppc_mma_xvf16ger2 v16i8:$XA, v16i8:$XB)),
+ (XVF16GER2 RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvf16ger2pp v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
+ (XVF16GER2PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvf16ger2pn v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
+ (XVF16GER2PN $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvf16ger2np v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
+ (XVF16GER2NP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvf16ger2nn v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
+ (XVF16GER2NN $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
+
+ def : Pat<(v512i1 (int_ppc_mma_xvf32ger v16i8:$XA, v16i8:$XB)),
+ (XVF32GER RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvf32gerpp v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
+ (XVF32GERPP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvf32gerpn v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
+ (XVF32GERPN $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvf32gernp v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
+ (XVF32GERNP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvf32gernn v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
+ (XVF32GERNN $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvf64ger v256i1:$XA, v16i8:$XB)),
+ (XVF64GER $XA, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvf64gerpp v512i1:$ATi, v256i1:$XA, v16i8:$XB)),
+ (XVF64GERPP $ATi, $XA, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvf64gerpn v512i1:$ATi, v256i1:$XA, v16i8:$XB)),
+ (XVF64GERPN $ATi, $XA, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvf64gernp v512i1:$ATi, v256i1:$XA, v16i8:$XB)),
+ (XVF64GERNP $ATi, $XA, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvf64gernn v512i1:$ATi, v256i1:$XA, v16i8:$XB)),
+ (XVF64GERNN $ATi, $XA, RCCp.BToVSRC)>;
+
+ def : Pat<(v512i1 (int_ppc_mma_xvbf16ger2 v16i8:$XA, v16i8:$XB)),
+ (XVBF16GER2 RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvbf16ger2pp v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
+ (XVBF16GER2PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvbf16ger2pn v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
+ (XVBF16GER2PN $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvbf16ger2np v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
+ (XVBF16GER2NP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvbf16ger2nn v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
+ (XVBF16GER2NN $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvi16ger2 v16i8:$XA, v16i8:$XB)),
+ (XVI16GER2 RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvi16ger2pp v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
+ (XVI16GER2PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
+ def : Pat<(v512i1 (int_ppc_mma_xvi8ger4spp v512i1:$ATi, v16i8:$XA, v16i8:$XB)),
+ (XVI8GER4SPP $ATi, RCCp.AToVSRC, RCCp.BToVSRC)>;
+}
+
+// MMA Intrinsics
+let Predicates = [MMA, PrefixInstrs] in {
+ def : Pat<(v512i1 (int_ppc_mma_pmxvi4ger8 v16i8:$XA, v16i8:$XB, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk8Imm:$PMSK)),
+ (PMXVI4GER8 RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk8Imm:$PMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvi4ger8pp v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK,
+ Msk8Imm:$PMSK)),
+ (PMXVI4GER8PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk8Imm:$PMSK)>;
+
+ def : Pat<(v512i1 (int_ppc_mma_pmxvi8ger4 v16i8:$XA, v16i8:$XB, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk4Imm:$PMSK)),
+ (PMXVI8GER4 RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk4Imm:$PMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvi8ger4pp v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK,
+ Msk4Imm:$PMSK)),
+ (PMXVI8GER4PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk4Imm:$PMSK)>;
+
+ def : Pat<(v512i1 (int_ppc_mma_pmxvi16ger2s v16i8:$XA, v16i8:$XB, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)),
+ (PMXVI16GER2S RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvi16ger2spp v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK,
+ Msk2Imm:$PMSK)),
+ (PMXVI16GER2SPP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvf16ger2 v16i8:$XA, v16i8:$XB, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)),
+ (PMXVF16GER2 RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvf16ger2pp v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK,
+ Msk2Imm:$PMSK)),
+ (PMXVF16GER2PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvf16ger2pn v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK,
+ Msk2Imm:$PMSK)),
+ (PMXVF16GER2PN $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvf16ger2np v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK,
+ Msk2Imm:$PMSK)),
+ (PMXVF16GER2NP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvf16ger2pn v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK,
+ Msk2Imm:$PMSK)),
+ (PMXVF16GER2PN $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvf16ger2np v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK,
+ Msk2Imm:$PMSK)),
+ (PMXVF16GER2NP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvf16ger2nn v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK,
+ Msk2Imm:$PMSK)),
+ (PMXVF16GER2NN $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
+
+ def : Pat<(v512i1 (int_ppc_mma_pmxvf32ger v16i8:$XA, v16i8:$XB, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK)),
+ (PMXVF32GER RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvf32gerpp v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK)),
+ (PMXVF32GERPP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvf32gerpn v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK)),
+ (PMXVF32GERPN $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvf32gernp v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK)),
+ (PMXVF32GERNP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvf32gernn v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK)),
+ (PMXVF32GERNN $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK)>;
+
+ def : Pat<(v512i1 (int_ppc_mma_pmxvf64ger v256i1:$XA, v16i8:$XB, Msk4Imm:$XMSK,
+ Msk2Imm:$YMSK)),
+ (PMXVF64GER $XA, RCCp.BToVSRC, Msk4Imm:$XMSK, Msk2Imm:$YMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvf64gerpp v512i1:$ATi, v256i1:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk2Imm:$YMSK)),
+ (PMXVF64GERPP $ATi, $XA, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk2Imm:$YMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvf64gerpn v512i1:$ATi, v256i1:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk2Imm:$YMSK)),
+ (PMXVF64GERPN $ATi, $XA, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk2Imm:$YMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvf64gernp v512i1:$ATi, v256i1:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk2Imm:$YMSK)),
+ (PMXVF64GERNP $ATi, $XA, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk2Imm:$YMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvf64gernn v512i1:$ATi, v256i1:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk2Imm:$YMSK)),
+ (PMXVF64GERNN $ATi, $XA, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk2Imm:$YMSK)>;
+
+ def : Pat<(v512i1 (int_ppc_mma_pmxvbf16ger2 v16i8:$XA, v16i8:$XB, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)),
+ (PMXVBF16GER2 RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvbf16ger2pp v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK,
+ Msk2Imm:$PMSK)),
+ (PMXVBF16GER2PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvbf16ger2pn v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK,
+ Msk2Imm:$PMSK)),
+ (PMXVBF16GER2PN $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvbf16ger2np v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK,
+ Msk2Imm:$PMSK)),
+ (PMXVBF16GER2NP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvbf16ger2nn v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK,
+ Msk2Imm:$PMSK)),
+ (PMXVBF16GER2NN $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvi16ger2 v16i8:$XA, v16i8:$XB, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)),
+ (PMXVI16GER2 RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvi8ger4spp v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK,
+ Msk2Imm:$PMSK)),
+ (PMXVI8GER4SPP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
+ def : Pat<(v512i1 (int_ppc_mma_pmxvi16ger2pp v512i1:$ATi, v16i8:$XA, v16i8:$XB,
+ Msk4Imm:$XMSK, Msk4Imm:$YMSK,
+ Msk2Imm:$PMSK)),
+ (PMXVI16GER2PP $ATi, RCCp.AToVSRC, RCCp.BToVSRC, Msk4Imm:$XMSK,
+ Msk4Imm:$YMSK, Msk2Imm:$PMSK)>;
+}
+
+def Concats {
+ dag VecsToVecPair0 =
+ (v256i1 (INSERT_SUBREG
+ (INSERT_SUBREG (IMPLICIT_DEF), $vs0, sub_vsx1),
+ $vs1, sub_vsx0));
+ dag VecsToVecPair1 =
+ (v256i1 (INSERT_SUBREG
+ (INSERT_SUBREG (IMPLICIT_DEF), $vs2, sub_vsx1),
+ $vs3, sub_vsx0));
+ dag VecsToVecQuad =
+ (BUILD_UACC (INSERT_SUBREG
+ (INSERT_SUBREG (v512i1 (IMPLICIT_DEF)),
+ (KILL_PAIR VecsToVecPair0), sub_pair0),
+ (KILL_PAIR VecsToVecPair1), sub_pair1));
+}
+
+def Extracts {
+ dag Pair0 = (v256i1 (EXTRACT_SUBREG $v, sub_pair0));
+ dag Pair1 = (v256i1 (EXTRACT_SUBREG $v, sub_pair1));
+ dag Vec0 = (v4i32 (EXTRACT_SUBREG Pair0, sub_vsx0));
+ dag Vec1 = (v4i32 (EXTRACT_SUBREG Pair0, sub_vsx1));
+ dag Vec2 = (v4i32 (EXTRACT_SUBREG Pair1, sub_vsx0));
+ dag Vec3 = (v4i32 (EXTRACT_SUBREG Pair1, sub_vsx1));
+}
+
+let Predicates = [MMA] in {
+ def : Pat<(v512i1 (PPCAccBuild v4i32:$vs1, v4i32:$vs0, v4i32:$vs3, v4i32:$vs2)),
+ (XXMTACC Concats.VecsToVecQuad)>;
+ def : Pat<(v512i1 (int_ppc_mma_assemble_acc v16i8:$vs1, v16i8:$vs0,
+ v16i8:$vs3, v16i8:$vs2)),
+ (XXMTACC Concats.VecsToVecQuad)>;
+ def : Pat<(v512i1 (PPCxxmfacc v512i1:$AS)), (XXMFACC acc:$AS)>;
+ def : Pat<(v4i32 (PPCAccExtractVsx acc:$v, (i64 0))),
+ Extracts.Vec0>;
+ def : Pat<(v4i32 (PPCAccExtractVsx acc:$v, (i64 1))),
+ Extracts.Vec1>;
+ def : Pat<(v4i32 (PPCAccExtractVsx acc:$v, (i64 2))),
+ Extracts.Vec2>;
+ def : Pat<(v4i32 (PPCAccExtractVsx acc:$v, (i64 3))),
+ Extracts.Vec3>;
+}
+
+let Predicates = [PairedVectorMemops] in {
+ def : Pat<(v256i1 (PPCPairBuild v4i32:$vs1, v4i32:$vs0)),
+ Concats.VecsToVecPair0>;
+ def : Pat<(v256i1 (int_ppc_vsx_assemble_pair v16i8:$vs1, v16i8:$vs0)),
+ Concats.VecsToVecPair0>;
+ def : Pat<(v4i32 (PPCPairExtractVsx vsrpevenrc:$v, (i64 0))),
+ (v4i32 (EXTRACT_SUBREG $v, sub_vsx0))>;
+ def : Pat<(v4i32 (PPCPairExtractVsx vsrpevenrc:$v, (i64 1))),
+ (v4i32 (EXTRACT_SUBREG $v, sub_vsx1))>;
+}
+
+let mayLoad = 1, mayStore = 0, Predicates = [PairedVectorMemops] in {
+ def LXVP : DQForm_XTp5_RA17_MEM<6, 0, (outs vsrprc:$XTp),
+ (ins memrix16:$DQ_RA), "lxvp $XTp, $DQ_RA",
+ IIC_LdStLFD, []>;
+ def LXVPX : XForm_XTp5_XAB5<31, 333, (outs vsrprc:$XTp), (ins memrr:$src),
+ "lxvpx $XTp, $src", IIC_LdStLFD,
+ []>;
+}
+
+let mayLoad = 0, mayStore = 1, Predicates = [PairedVectorMemops] in {
+ def STXVP : DQForm_XTp5_RA17_MEM<6, 1, (outs), (ins vsrprc:$XTp,
+ memrix16:$DQ_RA), "stxvp $XTp, $DQ_RA",
+ IIC_LdStLFD, []>;
+ def STXVPX : XForm_XTp5_XAB5<31, 461, (outs), (ins vsrprc:$XTp, memrr:$dst),
+ "stxvpx $XTp, $dst", IIC_LdStLFD,
+ []>;
+}
+
+let mayLoad = 1, mayStore = 0, Predicates = [PairedVectorMemops, PrefixInstrs] in {
+ defm PLXVP :
+ 8LS_DForm_R_XTp5_SI34_MEM_p<1, 58, (outs vsrprc:$XTp), (ins memri34:$D_RA),
+ (ins memri34_pcrel:$D_RA), "plxvp $XTp, $D_RA",
+ IIC_LdStLFD>;
+}
+
+let mayLoad = 0, mayStore = 1, Predicates = [PairedVectorMemops, PrefixInstrs] in {
+ defm PSTXVP :
+ 8LS_DForm_R_XTp5_SI34_MEM_p<1, 62, (outs), (ins vsrprc:$XTp, memri34:$D_RA),
+ (ins vsrprc:$XTp, memri34_pcrel:$D_RA),
+ "pstxvp $XTp, $D_RA", IIC_LdStLFD>;
+}
+
+let Predicates = [PairedVectorMemops] in {
+ // Intrinsics for Paired Vector Loads.
+ def : Pat<(v256i1 (int_ppc_vsx_lxvp iaddrX16:$src)), (LXVP memrix16:$src)>;
+ def : Pat<(v256i1 (int_ppc_vsx_lxvp xaddrX16:$src)), (LXVPX xaddrX16:$src)>;
+ let Predicates = [PairedVectorMemops, PrefixInstrs] in {
+ def : Pat<(v256i1 (int_ppc_vsx_lxvp iaddrX34:$src)), (PLXVP memri34:$src)>;
+ }
+ // Intrinsics for Paired Vector Stores.
+ def : Pat<(int_ppc_vsx_stxvp v256i1:$XSp, iaddrX16:$dst),
+ (STXVP $XSp, memrix16:$dst)>;
+ def : Pat<(int_ppc_vsx_stxvp v256i1:$XSp, xaddrX16:$dst),
+ (STXVPX $XSp, xaddrX16:$dst)>;
+ let Predicates = [PairedVectorMemops, PrefixInstrs] in {
+ def : Pat<(int_ppc_vsx_stxvp v256i1:$XSp, iaddrX34:$dst),
+ (PSTXVP $XSp, memri34:$dst)>;
+ }
+}
+
// TODO: We have an added complexity of 500 here. This is only a temporary
// solution to have tablegen consider these patterns first. The way we do
// addressing for PowerPC is complex depending on available D form, X form, or
@@ -1836,13 +1836,13 @@ let Predicates = [PCRelativeMemops], AddedComplexity = 500 in {
// If the PPCmatpcreladdr node is not caught by any other pattern it should be
// caught here and turned into a paddi instruction to materialize the address.
def : Pat<(PPCmatpcreladdr pcreladdr:$addr), (PADDI8pc 0, $addr)>;
- // PPCtlsdynamatpcreladdr node is used for TLS dynamic models to materialize
- // tls global address with paddi instruction.
- def : Pat<(PPCtlsdynamatpcreladdr pcreladdr:$addr), (PADDI8pc 0, $addr)>;
- // PPCtlslocalexecmataddr node is used for TLS local exec models to
- // materialize tls global address with paddi instruction.
- def : Pat<(PPCaddTls i64:$in, (PPCtlslocalexecmataddr tglobaltlsaddr:$addr)),
- (PADDI8 $in, $addr)>;
+ // PPCtlsdynamatpcreladdr node is used for TLS dynamic models to materialize
+ // tls global address with paddi instruction.
+ def : Pat<(PPCtlsdynamatpcreladdr pcreladdr:$addr), (PADDI8pc 0, $addr)>;
+ // PPCtlslocalexecmataddr node is used for TLS local exec models to
+ // materialize tls global address with paddi instruction.
+ def : Pat<(PPCaddTls i64:$in, (PPCtlslocalexecmataddr tglobaltlsaddr:$addr)),
+ (PADDI8 $in, $addr)>;
}
let Predicates = [PrefixInstrs] in {
@@ -1887,26 +1887,26 @@ let Predicates = [PrefixInstrs] in {
}
let Predicates = [IsISA3_1] in {
- def SETBC : XForm_XT5_BI5<31, 384, (outs gprc:$RT), (ins crbitrc:$BI),
- "setbc $RT, $BI", IIC_IntCompare, []>;
- def SETBCR : XForm_XT5_BI5<31, 416, (outs gprc:$RT), (ins crbitrc:$BI),
- "setbcr $RT, $BI", IIC_IntCompare, []>;
- def SETNBC : XForm_XT5_BI5<31, 448, (outs gprc:$RT), (ins crbitrc:$BI),
- "setnbc $RT, $BI", IIC_IntCompare, []>;
- def SETNBCR : XForm_XT5_BI5<31, 480, (outs gprc:$RT), (ins crbitrc:$BI),
- "setnbcr $RT, $BI", IIC_IntCompare, []>;
-
- let Interpretation64Bit = 1, isCodeGenOnly = 1 in {
- def SETBC8 : XForm_XT5_BI5<31, 384, (outs g8rc:$RT), (ins crbitrc:$BI),
- "setbc $RT, $BI", IIC_IntCompare, []>;
- def SETBCR8 : XForm_XT5_BI5<31, 416, (outs g8rc:$RT), (ins crbitrc:$BI),
- "setbcr $RT, $BI", IIC_IntCompare, []>;
- def SETNBC8 : XForm_XT5_BI5<31, 448, (outs g8rc:$RT), (ins crbitrc:$BI),
- "setnbc $RT, $BI", IIC_IntCompare, []>;
- def SETNBCR8 : XForm_XT5_BI5<31, 480, (outs g8rc:$RT), (ins crbitrc:$BI),
- "setnbcr $RT, $BI", IIC_IntCompare, []>;
- }
-
+ def SETBC : XForm_XT5_BI5<31, 384, (outs gprc:$RT), (ins crbitrc:$BI),
+ "setbc $RT, $BI", IIC_IntCompare, []>;
+ def SETBCR : XForm_XT5_BI5<31, 416, (outs gprc:$RT), (ins crbitrc:$BI),
+ "setbcr $RT, $BI", IIC_IntCompare, []>;
+ def SETNBC : XForm_XT5_BI5<31, 448, (outs gprc:$RT), (ins crbitrc:$BI),
+ "setnbc $RT, $BI", IIC_IntCompare, []>;
+ def SETNBCR : XForm_XT5_BI5<31, 480, (outs gprc:$RT), (ins crbitrc:$BI),
+ "setnbcr $RT, $BI", IIC_IntCompare, []>;
+
+ let Interpretation64Bit = 1, isCodeGenOnly = 1 in {
+ def SETBC8 : XForm_XT5_BI5<31, 384, (outs g8rc:$RT), (ins crbitrc:$BI),
+ "setbc $RT, $BI", IIC_IntCompare, []>;
+ def SETBCR8 : XForm_XT5_BI5<31, 416, (outs g8rc:$RT), (ins crbitrc:$BI),
+ "setbcr $RT, $BI", IIC_IntCompare, []>;
+ def SETNBC8 : XForm_XT5_BI5<31, 448, (outs g8rc:$RT), (ins crbitrc:$BI),
+ "setnbc $RT, $BI", IIC_IntCompare, []>;
+ def SETNBCR8 : XForm_XT5_BI5<31, 480, (outs g8rc:$RT), (ins crbitrc:$BI),
+ "setnbcr $RT, $BI", IIC_IntCompare, []>;
+ }
+
def VSLDBI : VNForm_VTAB5_SD3<22, 0, (outs vrrc:$VRT),
(ins vrrc:$VRA, vrrc:$VRB, u3imm:$SH),
"vsldbi $VRT, $VRA, $VRB, $SH",
@@ -1923,254 +1923,254 @@ let Predicates = [IsISA3_1] in {
(int_ppc_altivec_vsrdbi v16i8:$VRA,
v16i8:$VRB,
i32:$SH))]>;
- defm VSTRIBR : VXForm_VTB5_RCr<13, 1, (outs vrrc:$vT), (ins vrrc:$vB),
- "vstribr", "$vT, $vB", IIC_VecGeneral,
- [(set v16i8:$vT,
- (int_ppc_altivec_vstribr v16i8:$vB))]>;
- defm VSTRIBL : VXForm_VTB5_RCr<13, 0, (outs vrrc:$vT), (ins vrrc:$vB),
- "vstribl", "$vT, $vB", IIC_VecGeneral,
- [(set v16i8:$vT,
- (int_ppc_altivec_vstribl v16i8:$vB))]>;
- defm VSTRIHR : VXForm_VTB5_RCr<13, 3, (outs vrrc:$vT), (ins vrrc:$vB),
- "vstrihr", "$vT, $vB", IIC_VecGeneral,
- [(set v8i16:$vT,
- (int_ppc_altivec_vstrihr v8i16:$vB))]>;
- defm VSTRIHL : VXForm_VTB5_RCr<13, 2, (outs vrrc:$vT), (ins vrrc:$vB),
- "vstrihl", "$vT, $vB", IIC_VecGeneral,
- [(set v8i16:$vT,
- (int_ppc_altivec_vstrihl v8i16:$vB))]>;
- def VINSW :
- VXForm_1<207, (outs vrrc:$vD), (ins vrrc:$vDi, u4imm:$UIM, gprc:$rB),
- "vinsw $vD, $rB, $UIM", IIC_VecGeneral,
- [(set v4i32:$vD,
- (int_ppc_altivec_vinsw v4i32:$vDi, i32:$rB, timm:$UIM))]>,
- RegConstraint<"$vDi = $vD">, NoEncode<"$vDi">;
+ defm VSTRIBR : VXForm_VTB5_RCr<13, 1, (outs vrrc:$vT), (ins vrrc:$vB),
+ "vstribr", "$vT, $vB", IIC_VecGeneral,
+ [(set v16i8:$vT,
+ (int_ppc_altivec_vstribr v16i8:$vB))]>;
+ defm VSTRIBL : VXForm_VTB5_RCr<13, 0, (outs vrrc:$vT), (ins vrrc:$vB),
+ "vstribl", "$vT, $vB", IIC_VecGeneral,
+ [(set v16i8:$vT,
+ (int_ppc_altivec_vstribl v16i8:$vB))]>;
+ defm VSTRIHR : VXForm_VTB5_RCr<13, 3, (outs vrrc:$vT), (ins vrrc:$vB),
+ "vstrihr", "$vT, $vB", IIC_VecGeneral,
+ [(set v8i16:$vT,
+ (int_ppc_altivec_vstrihr v8i16:$vB))]>;
+ defm VSTRIHL : VXForm_VTB5_RCr<13, 2, (outs vrrc:$vT), (ins vrrc:$vB),
+ "vstrihl", "$vT, $vB", IIC_VecGeneral,
+ [(set v8i16:$vT,
+ (int_ppc_altivec_vstrihl v8i16:$vB))]>;
+ def VINSW :
+ VXForm_1<207, (outs vrrc:$vD), (ins vrrc:$vDi, u4imm:$UIM, gprc:$rB),
+ "vinsw $vD, $rB, $UIM", IIC_VecGeneral,
+ [(set v4i32:$vD,
+ (int_ppc_altivec_vinsw v4i32:$vDi, i32:$rB, timm:$UIM))]>,
+ RegConstraint<"$vDi = $vD">, NoEncode<"$vDi">;
def VINSD :
- VXForm_1<463, (outs vrrc:$vD), (ins vrrc:$vDi, u4imm:$UIM, g8rc:$rB),
- "vinsd $vD, $rB, $UIM", IIC_VecGeneral,
- [(set v2i64:$vD,
- (int_ppc_altivec_vinsd v2i64:$vDi, i64:$rB, timm:$UIM))]>,
- RegConstraint<"$vDi = $vD">, NoEncode<"$vDi">;
+ VXForm_1<463, (outs vrrc:$vD), (ins vrrc:$vDi, u4imm:$UIM, g8rc:$rB),
+ "vinsd $vD, $rB, $UIM", IIC_VecGeneral,
+ [(set v2i64:$vD,
+ (int_ppc_altivec_vinsd v2i64:$vDi, i64:$rB, timm:$UIM))]>,
+ RegConstraint<"$vDi = $vD">, NoEncode<"$vDi">;
def VINSBVLX :
VXForm_VTB5_RA5_ins<15, "vinsbvlx",
[(set v16i8:$vD,
- (int_ppc_altivec_vinsbvlx v16i8:$vDi, i32:$rA,
+ (int_ppc_altivec_vinsbvlx v16i8:$vDi, i32:$rA,
v16i8:$vB))]>;
def VINSBVRX :
VXForm_VTB5_RA5_ins<271, "vinsbvrx",
[(set v16i8:$vD,
- (int_ppc_altivec_vinsbvrx v16i8:$vDi, i32:$rA,
+ (int_ppc_altivec_vinsbvrx v16i8:$vDi, i32:$rA,
v16i8:$vB))]>;
def VINSHVLX :
VXForm_VTB5_RA5_ins<79, "vinshvlx",
[(set v8i16:$vD,
- (int_ppc_altivec_vinshvlx v8i16:$vDi, i32:$rA,
+ (int_ppc_altivec_vinshvlx v8i16:$vDi, i32:$rA,
v8i16:$vB))]>;
def VINSHVRX :
VXForm_VTB5_RA5_ins<335, "vinshvrx",
[(set v8i16:$vD,
- (int_ppc_altivec_vinshvrx v8i16:$vDi, i32:$rA,
+ (int_ppc_altivec_vinshvrx v8i16:$vDi, i32:$rA,
v8i16:$vB))]>;
def VINSWVLX :
VXForm_VTB5_RA5_ins<143, "vinswvlx",
[(set v4i32:$vD,
- (int_ppc_altivec_vinswvlx v4i32:$vDi, i32:$rA,
+ (int_ppc_altivec_vinswvlx v4i32:$vDi, i32:$rA,
v4i32:$vB))]>;
def VINSWVRX :
VXForm_VTB5_RA5_ins<399, "vinswvrx",
[(set v4i32:$vD,
- (int_ppc_altivec_vinswvrx v4i32:$vDi, i32:$rA,
+ (int_ppc_altivec_vinswvrx v4i32:$vDi, i32:$rA,
v4i32:$vB))]>;
def VINSBLX :
VXForm_VRT5_RAB5_ins<527, "vinsblx",
[(set v16i8:$vD,
- (int_ppc_altivec_vinsblx v16i8:$vDi, i32:$rA,
- i32:$rB))]>;
+ (int_ppc_altivec_vinsblx v16i8:$vDi, i32:$rA,
+ i32:$rB))]>;
def VINSBRX :
VXForm_VRT5_RAB5_ins<783, "vinsbrx",
[(set v16i8:$vD,
- (int_ppc_altivec_vinsbrx v16i8:$vDi, i32:$rA,
- i32:$rB))]>;
+ (int_ppc_altivec_vinsbrx v16i8:$vDi, i32:$rA,
+ i32:$rB))]>;
def VINSHLX :
VXForm_VRT5_RAB5_ins<591, "vinshlx",
[(set v8i16:$vD,
- (int_ppc_altivec_vinshlx v8i16:$vDi, i32:$rA,
- i32:$rB))]>;
+ (int_ppc_altivec_vinshlx v8i16:$vDi, i32:$rA,
+ i32:$rB))]>;
def VINSHRX :
VXForm_VRT5_RAB5_ins<847, "vinshrx",
[(set v8i16:$vD,
- (int_ppc_altivec_vinshrx v8i16:$vDi, i32:$rA,
- i32:$rB))]>;
+ (int_ppc_altivec_vinshrx v8i16:$vDi, i32:$rA,
+ i32:$rB))]>;
def VINSWLX :
VXForm_VRT5_RAB5_ins<655, "vinswlx",
[(set v4i32:$vD,
- (int_ppc_altivec_vinswlx v4i32:$vDi, i32:$rA,
- i32:$rB))]>;
+ (int_ppc_altivec_vinswlx v4i32:$vDi, i32:$rA,
+ i32:$rB))]>;
def VINSWRX :
VXForm_VRT5_RAB5_ins<911, "vinswrx",
[(set v4i32:$vD,
- (int_ppc_altivec_vinswrx v4i32:$vDi, i32:$rA,
- i32:$rB))]>;
+ (int_ppc_altivec_vinswrx v4i32:$vDi, i32:$rA,
+ i32:$rB))]>;
def VINSDLX :
- VXForm_1<719, (outs vrrc:$vD), (ins vrrc:$vDi, g8rc:$rA, g8rc:$rB),
- "vinsdlx $vD, $rA, $rB", IIC_VecGeneral,
- [(set v2i64:$vD,
- (int_ppc_altivec_vinsdlx v2i64:$vDi, i64:$rA, i64:$rB))]>,
- RegConstraint<"$vDi = $vD">, NoEncode<"$vDi">;
+ VXForm_1<719, (outs vrrc:$vD), (ins vrrc:$vDi, g8rc:$rA, g8rc:$rB),
+ "vinsdlx $vD, $rA, $rB", IIC_VecGeneral,
+ [(set v2i64:$vD,
+ (int_ppc_altivec_vinsdlx v2i64:$vDi, i64:$rA, i64:$rB))]>,
+ RegConstraint<"$vDi = $vD">, NoEncode<"$vDi">;
def VINSDRX :
- VXForm_1<975, (outs vrrc:$vD), (ins vrrc:$vDi, g8rc:$rA, g8rc:$rB),
- "vinsdrx $vD, $rA, $rB", IIC_VecGeneral,
- [(set v2i64:$vD,
- (int_ppc_altivec_vinsdrx v2i64:$vDi, i64:$rA, i64:$rB))]>,
- RegConstraint<"$vDi = $vD">, NoEncode<"$vDi">;
- def VEXTRACTBM : VXForm_RD5_XO5_RS5<1602, 8, (outs gprc:$rD), (ins vrrc:$vB),
- "vextractbm $rD, $vB", IIC_VecGeneral,
- [(set i32:$rD,
- (int_ppc_altivec_vextractbm v16i8:$vB))]>;
- def VEXTRACTHM : VXForm_RD5_XO5_RS5<1602, 9, (outs gprc:$rD), (ins vrrc:$vB),
- "vextracthm $rD, $vB", IIC_VecGeneral,
- [(set i32:$rD,
- (int_ppc_altivec_vextracthm v8i16:$vB))]>;
- def VEXTRACTWM : VXForm_RD5_XO5_RS5<1602, 10, (outs gprc:$rD), (ins vrrc:$vB),
- "vextractwm $rD, $vB", IIC_VecGeneral,
- [(set i32:$rD,
- (int_ppc_altivec_vextractwm v4i32:$vB))]>;
- def VEXTRACTDM : VXForm_RD5_XO5_RS5<1602, 11, (outs gprc:$rD), (ins vrrc:$vB),
- "vextractdm $rD, $vB", IIC_VecGeneral,
- [(set i32:$rD,
- (int_ppc_altivec_vextractdm v2i64:$vB))]>;
- def VEXTRACTQM : VXForm_RD5_XO5_RS5<1602, 12, (outs gprc:$rD), (ins vrrc:$vB),
- "vextractqm $rD, $vB", IIC_VecGeneral,
- [(set i32:$rD,
- (int_ppc_altivec_vextractqm v1i128:$vB))]>;
- def VEXPANDBM : VXForm_RD5_XO5_RS5<1602, 0, (outs vrrc:$vD), (ins vrrc:$vB),
- "vexpandbm $vD, $vB", IIC_VecGeneral,
- [(set v16i8:$vD, (int_ppc_altivec_vexpandbm
- v16i8:$vB))]>;
- def VEXPANDHM : VXForm_RD5_XO5_RS5<1602, 1, (outs vrrc:$vD), (ins vrrc:$vB),
- "vexpandhm $vD, $vB", IIC_VecGeneral,
- [(set v8i16:$vD, (int_ppc_altivec_vexpandhm
- v8i16:$vB))]>;
- def VEXPANDWM : VXForm_RD5_XO5_RS5<1602, 2, (outs vrrc:$vD), (ins vrrc:$vB),
- "vexpandwm $vD, $vB", IIC_VecGeneral,
- [(set v4i32:$vD, (int_ppc_altivec_vexpandwm
- v4i32:$vB))]>;
- def VEXPANDDM : VXForm_RD5_XO5_RS5<1602, 3, (outs vrrc:$vD), (ins vrrc:$vB),
- "vexpanddm $vD, $vB", IIC_VecGeneral,
- [(set v2i64:$vD, (int_ppc_altivec_vexpanddm
- v2i64:$vB))]>;
- def VEXPANDQM : VXForm_RD5_XO5_RS5<1602, 4, (outs vrrc:$vD), (ins vrrc:$vB),
- "vexpandqm $vD, $vB", IIC_VecGeneral,
- [(set v1i128:$vD, (int_ppc_altivec_vexpandqm
- v1i128:$vB))]>;
- def MTVSRBM : VXForm_RD5_XO5_RS5<1602, 16, (outs vrrc:$vD), (ins g8rc:$rB),
- "mtvsrbm $vD, $rB", IIC_VecGeneral,
- [(set v16i8:$vD,
- (int_ppc_altivec_mtvsrbm i64:$rB))]>;
- def MTVSRHM : VXForm_RD5_XO5_RS5<1602, 17, (outs vrrc:$vD), (ins g8rc:$rB),
- "mtvsrhm $vD, $rB", IIC_VecGeneral,
- [(set v8i16:$vD,
- (int_ppc_altivec_mtvsrhm i64:$rB))]>;
- def MTVSRWM : VXForm_RD5_XO5_RS5<1602, 18, (outs vrrc:$vD), (ins g8rc:$rB),
- "mtvsrwm $vD, $rB", IIC_VecGeneral,
- [(set v4i32:$vD,
- (int_ppc_altivec_mtvsrwm i64:$rB))]>;
- def MTVSRDM : VXForm_RD5_XO5_RS5<1602, 19, (outs vrrc:$vD), (ins g8rc:$rB),
- "mtvsrdm $vD, $rB", IIC_VecGeneral,
- [(set v2i64:$vD,
- (int_ppc_altivec_mtvsrdm i64:$rB))]>;
- def MTVSRQM : VXForm_RD5_XO5_RS5<1602, 20, (outs vrrc:$vD), (ins g8rc:$rB),
- "mtvsrqm $vD, $rB", IIC_VecGeneral,
- [(set v1i128:$vD,
- (int_ppc_altivec_mtvsrqm i64:$rB))]>;
- def MTVSRBMI : DXForm<4, 10, (outs vrrc:$vD), (ins u16imm64:$D),
- "mtvsrbmi $vD, $D", IIC_VecGeneral,
- [(set v16i8:$vD,
- (int_ppc_altivec_mtvsrbm imm:$D))]>;
- def VCNTMBB : VXForm_RD5_MP_VB5<1602, 12, (outs g8rc:$rD),
- (ins vrrc:$vB, u1imm:$MP),
- "vcntmbb $rD, $vB, $MP", IIC_VecGeneral,
- [(set i64:$rD, (int_ppc_altivec_vcntmbb
- v16i8:$vB, timm:$MP))]>;
- def VCNTMBH : VXForm_RD5_MP_VB5<1602, 13, (outs g8rc:$rD),
- (ins vrrc:$vB, u1imm:$MP),
- "vcntmbh $rD, $vB, $MP", IIC_VecGeneral,
- [(set i64:$rD, (int_ppc_altivec_vcntmbh
- v8i16:$vB, timm:$MP))]>;
- def VCNTMBW : VXForm_RD5_MP_VB5<1602, 14, (outs g8rc:$rD),
- (ins vrrc:$vB, u1imm:$MP),
- "vcntmbw $rD, $vB, $MP", IIC_VecGeneral,
- [(set i64:$rD, (int_ppc_altivec_vcntmbw
- v4i32:$vB, timm:$MP))]>;
- def VCNTMBD : VXForm_RD5_MP_VB5<1602, 15, (outs g8rc:$rD),
- (ins vrrc:$vB, u1imm:$MP),
- "vcntmbd $rD, $vB, $MP", IIC_VecGeneral,
- [(set i64:$rD, (int_ppc_altivec_vcntmbd
- v2i64:$vB, timm:$MP))]>;
- def VEXTDUBVLX : VAForm_1a<24, (outs vrrc:$vD),
- (ins vrrc:$vA, vrrc:$vB, gprc:$rC),
- "vextdubvlx $vD, $vA, $vB, $rC",
- IIC_VecGeneral,
- [(set v2i64:$vD,
- (int_ppc_altivec_vextdubvlx v16i8:$vA,
- v16i8:$vB,
- i32:$rC))]>;
- def VEXTDUBVRX : VAForm_1a<25, (outs vrrc:$vD),
- (ins vrrc:$vA, vrrc:$vB, gprc:$rC),
- "vextdubvrx $vD, $vA, $vB, $rC",
- IIC_VecGeneral,
- [(set v2i64:$vD,
- (int_ppc_altivec_vextdubvrx v16i8:$vA,
- v16i8:$vB,
- i32:$rC))]>;
- def VEXTDUHVLX : VAForm_1a<26, (outs vrrc:$vD),
- (ins vrrc:$vA, vrrc:$vB, gprc:$rC),
- "vextduhvlx $vD, $vA, $vB, $rC",
- IIC_VecGeneral,
- [(set v2i64:$vD,
- (int_ppc_altivec_vextduhvlx v8i16:$vA,
- v8i16:$vB,
- i32:$rC))]>;
- def VEXTDUHVRX : VAForm_1a<27, (outs vrrc:$vD),
- (ins vrrc:$vA, vrrc:$vB, gprc:$rC),
- "vextduhvrx $vD, $vA, $vB, $rC",
- IIC_VecGeneral,
- [(set v2i64:$vD,
- (int_ppc_altivec_vextduhvrx v8i16:$vA,
- v8i16:$vB,
- i32:$rC))]>;
- def VEXTDUWVLX : VAForm_1a<28, (outs vrrc:$vD),
- (ins vrrc:$vA, vrrc:$vB, gprc:$rC),
- "vextduwvlx $vD, $vA, $vB, $rC",
- IIC_VecGeneral,
- [(set v2i64:$vD,
- (int_ppc_altivec_vextduwvlx v4i32:$vA,
- v4i32:$vB,
- i32:$rC))]>;
- def VEXTDUWVRX : VAForm_1a<29, (outs vrrc:$vD),
- (ins vrrc:$vA, vrrc:$vB, gprc:$rC),
- "vextduwvrx $vD, $vA, $vB, $rC",
- IIC_VecGeneral,
- [(set v2i64:$vD,
- (int_ppc_altivec_vextduwvrx v4i32:$vA,
- v4i32:$vB,
- i32:$rC))]>;
- def VEXTDDVLX : VAForm_1a<30, (outs vrrc:$vD),
- (ins vrrc:$vA, vrrc:$vB, gprc:$rC),
- "vextddvlx $vD, $vA, $vB, $rC",
- IIC_VecGeneral,
- [(set v2i64:$vD,
- (int_ppc_altivec_vextddvlx v2i64:$vA,
- v2i64:$vB,
- i32:$rC))]>;
- def VEXTDDVRX : VAForm_1a<31, (outs vrrc:$vD),
- (ins vrrc:$vA, vrrc:$vB, gprc:$rC),
- "vextddvrx $vD, $vA, $vB, $rC",
- IIC_VecGeneral,
- [(set v2i64:$vD,
- (int_ppc_altivec_vextddvrx v2i64:$vA,
- v2i64:$vB,
- i32:$rC))]>;
+ VXForm_1<975, (outs vrrc:$vD), (ins vrrc:$vDi, g8rc:$rA, g8rc:$rB),
+ "vinsdrx $vD, $rA, $rB", IIC_VecGeneral,
+ [(set v2i64:$vD,
+ (int_ppc_altivec_vinsdrx v2i64:$vDi, i64:$rA, i64:$rB))]>,
+ RegConstraint<"$vDi = $vD">, NoEncode<"$vDi">;
+ def VEXTRACTBM : VXForm_RD5_XO5_RS5<1602, 8, (outs gprc:$rD), (ins vrrc:$vB),
+ "vextractbm $rD, $vB", IIC_VecGeneral,
+ [(set i32:$rD,
+ (int_ppc_altivec_vextractbm v16i8:$vB))]>;
+ def VEXTRACTHM : VXForm_RD5_XO5_RS5<1602, 9, (outs gprc:$rD), (ins vrrc:$vB),
+ "vextracthm $rD, $vB", IIC_VecGeneral,
+ [(set i32:$rD,
+ (int_ppc_altivec_vextracthm v8i16:$vB))]>;
+ def VEXTRACTWM : VXForm_RD5_XO5_RS5<1602, 10, (outs gprc:$rD), (ins vrrc:$vB),
+ "vextractwm $rD, $vB", IIC_VecGeneral,
+ [(set i32:$rD,
+ (int_ppc_altivec_vextractwm v4i32:$vB))]>;
+ def VEXTRACTDM : VXForm_RD5_XO5_RS5<1602, 11, (outs gprc:$rD), (ins vrrc:$vB),
+ "vextractdm $rD, $vB", IIC_VecGeneral,
+ [(set i32:$rD,
+ (int_ppc_altivec_vextractdm v2i64:$vB))]>;
+ def VEXTRACTQM : VXForm_RD5_XO5_RS5<1602, 12, (outs gprc:$rD), (ins vrrc:$vB),
+ "vextractqm $rD, $vB", IIC_VecGeneral,
+ [(set i32:$rD,
+ (int_ppc_altivec_vextractqm v1i128:$vB))]>;
+ def VEXPANDBM : VXForm_RD5_XO5_RS5<1602, 0, (outs vrrc:$vD), (ins vrrc:$vB),
+ "vexpandbm $vD, $vB", IIC_VecGeneral,
+ [(set v16i8:$vD, (int_ppc_altivec_vexpandbm
+ v16i8:$vB))]>;
+ def VEXPANDHM : VXForm_RD5_XO5_RS5<1602, 1, (outs vrrc:$vD), (ins vrrc:$vB),
+ "vexpandhm $vD, $vB", IIC_VecGeneral,
+ [(set v8i16:$vD, (int_ppc_altivec_vexpandhm
+ v8i16:$vB))]>;
+ def VEXPANDWM : VXForm_RD5_XO5_RS5<1602, 2, (outs vrrc:$vD), (ins vrrc:$vB),
+ "vexpandwm $vD, $vB", IIC_VecGeneral,
+ [(set v4i32:$vD, (int_ppc_altivec_vexpandwm
+ v4i32:$vB))]>;
+ def VEXPANDDM : VXForm_RD5_XO5_RS5<1602, 3, (outs vrrc:$vD), (ins vrrc:$vB),
+ "vexpanddm $vD, $vB", IIC_VecGeneral,
+ [(set v2i64:$vD, (int_ppc_altivec_vexpanddm
+ v2i64:$vB))]>;
+ def VEXPANDQM : VXForm_RD5_XO5_RS5<1602, 4, (outs vrrc:$vD), (ins vrrc:$vB),
+ "vexpandqm $vD, $vB", IIC_VecGeneral,
+ [(set v1i128:$vD, (int_ppc_altivec_vexpandqm
+ v1i128:$vB))]>;
+ def MTVSRBM : VXForm_RD5_XO5_RS5<1602, 16, (outs vrrc:$vD), (ins g8rc:$rB),
+ "mtvsrbm $vD, $rB", IIC_VecGeneral,
+ [(set v16i8:$vD,
+ (int_ppc_altivec_mtvsrbm i64:$rB))]>;
+ def MTVSRHM : VXForm_RD5_XO5_RS5<1602, 17, (outs vrrc:$vD), (ins g8rc:$rB),
+ "mtvsrhm $vD, $rB", IIC_VecGeneral,
+ [(set v8i16:$vD,
+ (int_ppc_altivec_mtvsrhm i64:$rB))]>;
+ def MTVSRWM : VXForm_RD5_XO5_RS5<1602, 18, (outs vrrc:$vD), (ins g8rc:$rB),
+ "mtvsrwm $vD, $rB", IIC_VecGeneral,
+ [(set v4i32:$vD,
+ (int_ppc_altivec_mtvsrwm i64:$rB))]>;
+ def MTVSRDM : VXForm_RD5_XO5_RS5<1602, 19, (outs vrrc:$vD), (ins g8rc:$rB),
+ "mtvsrdm $vD, $rB", IIC_VecGeneral,
+ [(set v2i64:$vD,
+ (int_ppc_altivec_mtvsrdm i64:$rB))]>;
+ def MTVSRQM : VXForm_RD5_XO5_RS5<1602, 20, (outs vrrc:$vD), (ins g8rc:$rB),
+ "mtvsrqm $vD, $rB", IIC_VecGeneral,
+ [(set v1i128:$vD,
+ (int_ppc_altivec_mtvsrqm i64:$rB))]>;
+ def MTVSRBMI : DXForm<4, 10, (outs vrrc:$vD), (ins u16imm64:$D),
+ "mtvsrbmi $vD, $D", IIC_VecGeneral,
+ [(set v16i8:$vD,
+ (int_ppc_altivec_mtvsrbm imm:$D))]>;
+ def VCNTMBB : VXForm_RD5_MP_VB5<1602, 12, (outs g8rc:$rD),
+ (ins vrrc:$vB, u1imm:$MP),
+ "vcntmbb $rD, $vB, $MP", IIC_VecGeneral,
+ [(set i64:$rD, (int_ppc_altivec_vcntmbb
+ v16i8:$vB, timm:$MP))]>;
+ def VCNTMBH : VXForm_RD5_MP_VB5<1602, 13, (outs g8rc:$rD),
+ (ins vrrc:$vB, u1imm:$MP),
+ "vcntmbh $rD, $vB, $MP", IIC_VecGeneral,
+ [(set i64:$rD, (int_ppc_altivec_vcntmbh
+ v8i16:$vB, timm:$MP))]>;
+ def VCNTMBW : VXForm_RD5_MP_VB5<1602, 14, (outs g8rc:$rD),
+ (ins vrrc:$vB, u1imm:$MP),
+ "vcntmbw $rD, $vB, $MP", IIC_VecGeneral,
+ [(set i64:$rD, (int_ppc_altivec_vcntmbw
+ v4i32:$vB, timm:$MP))]>;
+ def VCNTMBD : VXForm_RD5_MP_VB5<1602, 15, (outs g8rc:$rD),
+ (ins vrrc:$vB, u1imm:$MP),
+ "vcntmbd $rD, $vB, $MP", IIC_VecGeneral,
+ [(set i64:$rD, (int_ppc_altivec_vcntmbd
+ v2i64:$vB, timm:$MP))]>;
+ def VEXTDUBVLX : VAForm_1a<24, (outs vrrc:$vD),
+ (ins vrrc:$vA, vrrc:$vB, gprc:$rC),
+ "vextdubvlx $vD, $vA, $vB, $rC",
+ IIC_VecGeneral,
+ [(set v2i64:$vD,
+ (int_ppc_altivec_vextdubvlx v16i8:$vA,
+ v16i8:$vB,
+ i32:$rC))]>;
+ def VEXTDUBVRX : VAForm_1a<25, (outs vrrc:$vD),
+ (ins vrrc:$vA, vrrc:$vB, gprc:$rC),
+ "vextdubvrx $vD, $vA, $vB, $rC",
+ IIC_VecGeneral,
+ [(set v2i64:$vD,
+ (int_ppc_altivec_vextdubvrx v16i8:$vA,
+ v16i8:$vB,
+ i32:$rC))]>;
+ def VEXTDUHVLX : VAForm_1a<26, (outs vrrc:$vD),
+ (ins vrrc:$vA, vrrc:$vB, gprc:$rC),
+ "vextduhvlx $vD, $vA, $vB, $rC",
+ IIC_VecGeneral,
+ [(set v2i64:$vD,
+ (int_ppc_altivec_vextduhvlx v8i16:$vA,
+ v8i16:$vB,
+ i32:$rC))]>;
+ def VEXTDUHVRX : VAForm_1a<27, (outs vrrc:$vD),
+ (ins vrrc:$vA, vrrc:$vB, gprc:$rC),
+ "vextduhvrx $vD, $vA, $vB, $rC",
+ IIC_VecGeneral,
+ [(set v2i64:$vD,
+ (int_ppc_altivec_vextduhvrx v8i16:$vA,
+ v8i16:$vB,
+ i32:$rC))]>;
+ def VEXTDUWVLX : VAForm_1a<28, (outs vrrc:$vD),
+ (ins vrrc:$vA, vrrc:$vB, gprc:$rC),
+ "vextduwvlx $vD, $vA, $vB, $rC",
+ IIC_VecGeneral,
+ [(set v2i64:$vD,
+ (int_ppc_altivec_vextduwvlx v4i32:$vA,
+ v4i32:$vB,
+ i32:$rC))]>;
+ def VEXTDUWVRX : VAForm_1a<29, (outs vrrc:$vD),
+ (ins vrrc:$vA, vrrc:$vB, gprc:$rC),
+ "vextduwvrx $vD, $vA, $vB, $rC",
+ IIC_VecGeneral,
+ [(set v2i64:$vD,
+ (int_ppc_altivec_vextduwvrx v4i32:$vA,
+ v4i32:$vB,
+ i32:$rC))]>;
+ def VEXTDDVLX : VAForm_1a<30, (outs vrrc:$vD),
+ (ins vrrc:$vA, vrrc:$vB, gprc:$rC),
+ "vextddvlx $vD, $vA, $vB, $rC",
+ IIC_VecGeneral,
+ [(set v2i64:$vD,
+ (int_ppc_altivec_vextddvlx v2i64:$vA,
+ v2i64:$vB,
+ i32:$rC))]>;
+ def VEXTDDVRX : VAForm_1a<31, (outs vrrc:$vD),
+ (ins vrrc:$vA, vrrc:$vB, gprc:$rC),
+ "vextddvrx $vD, $vA, $vB, $rC",
+ IIC_VecGeneral,
+ [(set v2i64:$vD,
+ (int_ppc_altivec_vextddvrx v2i64:$vA,
+ v2i64:$vB,
+ i32:$rC))]>;
def VPDEPD : VXForm_1<1485, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
"vpdepd $vD, $vA, $vB", IIC_VecGeneral,
[(set v2i64:$vD,
@@ -2238,61 +2238,61 @@ let Predicates = [IsISA3_1] in {
"vclrrb $vD, $vA, $rB", IIC_VecGeneral,
[(set v16i8:$vD,
(int_ppc_altivec_vclrrb v16i8:$vA, i32:$rB))]>;
- def VMULLD : VXForm_1<457, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vmulld $vD, $vA, $vB", IIC_VecGeneral,
- [(set v2i64:$vD, (mul v2i64:$vA, v2i64:$vB))]>;
- def VMULHSW : VXForm_1<905, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vmulhsw $vD, $vA, $vB", IIC_VecGeneral,
- [(set v4i32:$vD, (mulhs v4i32:$vA, v4i32:$vB))]>;
- def VMULHUW : VXForm_1<649, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vmulhuw $vD, $vA, $vB", IIC_VecGeneral,
- [(set v4i32:$vD, (mulhu v4i32:$vA, v4i32:$vB))]>;
- def VMULHSD : VXForm_1<969, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vmulhsd $vD, $vA, $vB", IIC_VecGeneral,
- [(set v2i64:$vD, (mulhs v2i64:$vA, v2i64:$vB))]>;
- def VMULHUD : VXForm_1<713, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vmulhud $vD, $vA, $vB", IIC_VecGeneral,
- [(set v2i64:$vD, (mulhu v2i64:$vA, v2i64:$vB))]>;
- def VMODSW : VXForm_1<1931, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vmodsw $vD, $vA, $vB", IIC_VecGeneral,
- [(set v4i32:$vD, (srem v4i32:$vA, v4i32:$vB))]>;
- def VMODUW : VXForm_1<1675, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vmoduw $vD, $vA, $vB", IIC_VecGeneral,
- [(set v4i32:$vD, (urem v4i32:$vA, v4i32:$vB))]>;
- def VMODSD : VXForm_1<1995, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vmodsd $vD, $vA, $vB", IIC_VecGeneral,
- [(set v2i64:$vD, (srem v2i64:$vA, v2i64:$vB))]>;
- def VMODUD : VXForm_1<1739, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vmodud $vD, $vA, $vB", IIC_VecGeneral,
- [(set v2i64:$vD, (urem v2i64:$vA, v2i64:$vB))]>;
- def VDIVSW : VXForm_1<395, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vdivsw $vD, $vA, $vB", IIC_VecGeneral,
- [(set v4i32:$vD, (sdiv v4i32:$vA, v4i32:$vB))]>;
- def VDIVUW : VXForm_1<139, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vdivuw $vD, $vA, $vB", IIC_VecGeneral,
- [(set v4i32:$vD, (udiv v4i32:$vA, v4i32:$vB))]>;
- def VDIVSD : VXForm_1<459, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vdivsd $vD, $vA, $vB", IIC_VecGeneral,
- [(set v2i64:$vD, (sdiv v2i64:$vA, v2i64:$vB))]>;
- def VDIVUD : VXForm_1<203, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vdivud $vD, $vA, $vB", IIC_VecGeneral,
- [(set v2i64:$vD, (udiv v2i64:$vA, v2i64:$vB))]>;
- def VDIVESW : VXForm_1<907, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vdivesw $vD, $vA, $vB", IIC_VecGeneral,
- [(set v4i32:$vD, (int_ppc_altivec_vdivesw v4i32:$vA,
- v4i32:$vB))]>;
- def VDIVEUW : VXForm_1<651, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vdiveuw $vD, $vA, $vB", IIC_VecGeneral,
- [(set v4i32:$vD, (int_ppc_altivec_vdiveuw v4i32:$vA,
- v4i32:$vB))]>;
- def VDIVESD : VXForm_1<971, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vdivesd $vD, $vA, $vB", IIC_VecGeneral,
- [(set v2i64:$vD, (int_ppc_altivec_vdivesd v2i64:$vA,
- v2i64:$vB))]>;
- def VDIVEUD : VXForm_1<715, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vdiveud $vD, $vA, $vB", IIC_VecGeneral,
- [(set v2i64:$vD, (int_ppc_altivec_vdiveud v2i64:$vA,
- v2i64:$vB))]>;
+ def VMULLD : VXForm_1<457, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vmulld $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v2i64:$vD, (mul v2i64:$vA, v2i64:$vB))]>;
+ def VMULHSW : VXForm_1<905, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vmulhsw $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v4i32:$vD, (mulhs v4i32:$vA, v4i32:$vB))]>;
+ def VMULHUW : VXForm_1<649, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vmulhuw $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v4i32:$vD, (mulhu v4i32:$vA, v4i32:$vB))]>;
+ def VMULHSD : VXForm_1<969, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vmulhsd $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v2i64:$vD, (mulhs v2i64:$vA, v2i64:$vB))]>;
+ def VMULHUD : VXForm_1<713, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vmulhud $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v2i64:$vD, (mulhu v2i64:$vA, v2i64:$vB))]>;
+ def VMODSW : VXForm_1<1931, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vmodsw $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v4i32:$vD, (srem v4i32:$vA, v4i32:$vB))]>;
+ def VMODUW : VXForm_1<1675, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vmoduw $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v4i32:$vD, (urem v4i32:$vA, v4i32:$vB))]>;
+ def VMODSD : VXForm_1<1995, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vmodsd $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v2i64:$vD, (srem v2i64:$vA, v2i64:$vB))]>;
+ def VMODUD : VXForm_1<1739, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vmodud $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v2i64:$vD, (urem v2i64:$vA, v2i64:$vB))]>;
+ def VDIVSW : VXForm_1<395, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vdivsw $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v4i32:$vD, (sdiv v4i32:$vA, v4i32:$vB))]>;
+ def VDIVUW : VXForm_1<139, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vdivuw $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v4i32:$vD, (udiv v4i32:$vA, v4i32:$vB))]>;
+ def VDIVSD : VXForm_1<459, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vdivsd $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v2i64:$vD, (sdiv v2i64:$vA, v2i64:$vB))]>;
+ def VDIVUD : VXForm_1<203, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vdivud $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v2i64:$vD, (udiv v2i64:$vA, v2i64:$vB))]>;
+ def VDIVESW : VXForm_1<907, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vdivesw $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v4i32:$vD, (int_ppc_altivec_vdivesw v4i32:$vA,
+ v4i32:$vB))]>;
+ def VDIVEUW : VXForm_1<651, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vdiveuw $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v4i32:$vD, (int_ppc_altivec_vdiveuw v4i32:$vA,
+ v4i32:$vB))]>;
+ def VDIVESD : VXForm_1<971, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vdivesd $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v2i64:$vD, (int_ppc_altivec_vdivesd v2i64:$vA,
+ v2i64:$vB))]>;
+ def VDIVEUD : VXForm_1<715, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vdiveud $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v2i64:$vD, (int_ppc_altivec_vdiveud v2i64:$vA,
+ v2i64:$vB))]>;
def XVTLSBB : XX2_BF3_XO5_XB6_XO9<60, 2, 475, (outs crrc:$BF), (ins vsrc:$XB),
"xvtlsbb $BF, $XB", IIC_VecGeneral, []>;
@@ -2311,204 +2311,204 @@ let Predicates = [IsISA3_1] in {
def STXVRWX : X_XS6_RA5_RB5<31, 205, "stxvrwx", vsrc, []>;
def STXVRDX : X_XS6_RA5_RB5<31, 237, "stxvrdx", vsrc, []>;
}
-
- def VMULESD : VXForm_1<968, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vmulesd $vD, $vA, $vB", IIC_VecGeneral,
- [(set v1i128:$vD, (int_ppc_altivec_vmulesd v2i64:$vA,
- v2i64:$vB))]>;
- def VMULEUD : VXForm_1<712, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vmuleud $vD, $vA, $vB", IIC_VecGeneral,
- [(set v1i128:$vD, (int_ppc_altivec_vmuleud v2i64:$vA,
- v2i64:$vB))]>;
- def VMULOSD : VXForm_1<456, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vmulosd $vD, $vA, $vB", IIC_VecGeneral,
- [(set v1i128:$vD, (int_ppc_altivec_vmulosd v2i64:$vA,
- v2i64:$vB))]>;
- def VMULOUD : VXForm_1<200, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vmuloud $vD, $vA, $vB", IIC_VecGeneral,
- [(set v1i128:$vD, (int_ppc_altivec_vmuloud v2i64:$vA,
- v2i64:$vB))]>;
- def VMSUMCUD : VAForm_1a<23, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB, vrrc:$vC),
- "vmsumcud $vD, $vA, $vB, $vC", IIC_VecGeneral,
- [(set v1i128:$vD, (int_ppc_altivec_vmsumcud
- v2i64:$vA, v2i64:$vB, v1i128:$vC))]>;
- def VDIVSQ : VXForm_1<267, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vdivsq $vD, $vA, $vB", IIC_VecGeneral,
- [(set v1i128:$vD, (sdiv v1i128:$vA, v1i128:$vB))]>;
- def VDIVUQ : VXForm_1<11, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vdivuq $vD, $vA, $vB", IIC_VecGeneral,
- [(set v1i128:$vD, (udiv v1i128:$vA, v1i128:$vB))]>;
- def VDIVESQ : VXForm_1<779, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vdivesq $vD, $vA, $vB", IIC_VecGeneral,
- [(set v1i128:$vD, (int_ppc_altivec_vdivesq v1i128:$vA,
- v1i128:$vB))]>;
- def VDIVEUQ : VXForm_1<523, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vdiveuq $vD, $vA, $vB", IIC_VecGeneral,
- [(set v1i128:$vD, (int_ppc_altivec_vdiveuq v1i128:$vA,
- v1i128:$vB))]>;
- def VCMPEQUQ : VCMP <455, "vcmpequq $vD, $vA, $vB" , v1i128>;
- def VCMPGTSQ : VCMP <903, "vcmpgtsq $vD, $vA, $vB" , v1i128>;
- def VCMPGTUQ : VCMP <647, "vcmpgtuq $vD, $vA, $vB" , v1i128>;
- def VCMPEQUQ_rec : VCMP_rec <455, "vcmpequq. $vD, $vA, $vB" , v1i128>;
- def VCMPGTSQ_rec : VCMP_rec <903, "vcmpgtsq. $vD, $vA, $vB" , v1i128>;
- def VCMPGTUQ_rec : VCMP_rec <647, "vcmpgtuq. $vD, $vA, $vB" , v1i128>;
- def VMODSQ : VXForm_1<1803, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vmodsq $vD, $vA, $vB", IIC_VecGeneral,
- [(set v1i128:$vD, (srem v1i128:$vA, v1i128:$vB))]>;
- def VMODUQ : VXForm_1<1547, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
- "vmoduq $vD, $vA, $vB", IIC_VecGeneral,
- [(set v1i128:$vD, (urem v1i128:$vA, v1i128:$vB))]>;
- def VEXTSD2Q : VXForm_RD5_XO5_RS5<1538, 27, (outs vrrc:$vD), (ins vrrc:$vB),
- "vextsd2q $vD, $vB", IIC_VecGeneral,
- [(set v1i128:$vD, (int_ppc_altivec_vextsd2q v2i64:$vB))]>;
- def VCMPUQ : VXForm_BF3_VAB5<257, (outs crrc:$BF), (ins vrrc:$vA, vrrc:$vB),
- "vcmpuq $BF, $vA, $vB", IIC_VecGeneral, []>;
- def VCMPSQ : VXForm_BF3_VAB5<321, (outs crrc:$BF), (ins vrrc:$vA, vrrc:$vB),
- "vcmpsq $BF, $vA, $vB", IIC_VecGeneral, []>;
- def VRLQNM : VX1_VT5_VA5_VB5<325, "vrlqnm",
- [(set v1i128:$vD,
- (int_ppc_altivec_vrlqnm v1i128:$vA,
- v1i128:$vB))]>;
- def VRLQMI : VXForm_1<69, (outs vrrc:$vD),
- (ins vrrc:$vA, vrrc:$vB, vrrc:$vDi),
- "vrlqmi $vD, $vA, $vB", IIC_VecFP,
- [(set v1i128:$vD,
- (int_ppc_altivec_vrlqmi v1i128:$vA, v1i128:$vB,
- v1i128:$vDi))]>,
- RegConstraint<"$vDi = $vD">, NoEncode<"$vDi">;
- def VSLQ : VX1_VT5_VA5_VB5<261, "vslq", []>;
- def VSRAQ : VX1_VT5_VA5_VB5<773, "vsraq", []>;
- def VSRQ : VX1_VT5_VA5_VB5<517, "vsrq", []>;
- def VRLQ : VX1_VT5_VA5_VB5<5, "vrlq", []>;
- def XSCVQPUQZ : X_VT5_XO5_VB5<63, 0, 836, "xscvqpuqz", []>;
- def XSCVQPSQZ : X_VT5_XO5_VB5<63, 8, 836, "xscvqpsqz", []>;
- def XSCVUQQP : X_VT5_XO5_VB5<63, 3, 836, "xscvuqqp", []>;
- def XSCVSQQP : X_VT5_XO5_VB5<63, 11, 836, "xscvsqqp", []>;
-}
-
-let Predicates = [IsISA3_1, HasVSX] in {
- def XVCVSPBF16 : XX2_XT6_XO5_XB6<60, 17, 475, "xvcvspbf16", vsrc, []>;
- def XVCVBF16SPN : XX2_XT6_XO5_XB6<60, 16, 475, "xvcvbf16spn", vsrc, []>;
-}
-
-// Multiclass defining patterns for Set Boolean Extension Reverse Instructions.
-// This is analogous to the CRNotPat multiclass but specifically for Power10
-// and newer subtargets since the extended forms use Set Boolean instructions.
-// The first two anonymous patterns defined are actually a duplicate of those
-// in CRNotPat, but it is preferable to define both multiclasses as complete
-// ones rather than pulling that small common section out.
-multiclass P10ReverseSetBool<dag pattern, dag result> {
- def : Pat<pattern, (crnot result)>;
- def : Pat<(not pattern), result>;
-
- def : Pat<(i32 (zext pattern)),
- (SETBCR result)>;
- def : Pat<(i64 (zext pattern)),
- (SETBCR8 result)>;
-
- def : Pat<(i32 (sext pattern)),
- (SETNBCR result)>;
- def : Pat<(i64 (sext pattern)),
- (SETNBCR8 result)>;
-
- def : Pat<(i32 (anyext pattern)),
- (SETBCR result)>;
- def : Pat<(i64 (anyext pattern)),
- (SETBCR8 result)>;
-}
-
-multiclass IntSetP10RevSetBool<SDNode SetCC, ValueType Ty, ImmLeaf ZExtTy,
- ImmLeaf SExtTy, PatLeaf Cmpi, PatLeaf Cmpli,
- PatLeaf Cmp, PatLeaf Cmpl> {
- defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETUGE)),
- (EXTRACT_SUBREG (Cmpl $s1, $s2), sub_lt)>;
- defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETGE)),
- (EXTRACT_SUBREG (Cmp $s1, $s2), sub_lt)>;
- defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETULE)),
- (EXTRACT_SUBREG (Cmpl $s1, $s2), sub_gt)>;
- defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETLE)),
- (EXTRACT_SUBREG (Cmp $s1, $s2), sub_gt)>;
- defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETNE)),
- (EXTRACT_SUBREG (Cmp $s1, $s2), sub_eq)>;
-
- defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, ZExtTy:$imm, SETUGE)),
- (EXTRACT_SUBREG (Cmpli $s1, imm:$imm), sub_lt)>;
- defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, SExtTy:$imm, SETGE)),
- (EXTRACT_SUBREG (Cmpi $s1, imm:$imm), sub_lt)>;
- defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, ZExtTy:$imm, SETULE)),
- (EXTRACT_SUBREG (Cmpli $s1, imm:$imm), sub_gt)>;
- defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, SExtTy:$imm, SETLE)),
- (EXTRACT_SUBREG (Cmpi $s1, imm:$imm), sub_gt)>;
- defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, SExtTy:$imm, SETNE)),
- (EXTRACT_SUBREG (Cmpi $s1, imm:$imm), sub_eq)>;
- defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, ZExtTy:$imm, SETNE)),
- (EXTRACT_SUBREG (Cmpli $s1, imm:$imm), sub_eq)>;
-}
-
-multiclass FSetP10RevSetBool<SDNode SetCC, ValueType Ty, PatLeaf FCmp> {
- defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETUGE)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
- defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETGE)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
- defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETULE)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
- defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETLE)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
- defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETUNE)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
- defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETNE)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
- defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETO)),
- (EXTRACT_SUBREG (FCmp $s1, $s2), sub_un)>;
-}
-
-let Predicates = [IsISA3_1] in {
- def : Pat<(i32 (zext i1:$in)),
- (SETBC $in)>;
- def : Pat<(i64 (zext i1:$in)),
- (SETBC8 $in)>;
- def : Pat<(i32 (sext i1:$in)),
- (SETNBC $in)>;
- def : Pat<(i64 (sext i1:$in)),
- (SETNBC8 $in)>;
- def : Pat<(i32 (anyext i1:$in)),
- (SETBC $in)>;
- def : Pat<(i64 (anyext i1:$in)),
- (SETBC8 $in)>;
-
- // Instantiation of the set boolean reverse patterns for 32-bit integers.
- defm : IntSetP10RevSetBool<setcc, i32, immZExt16, imm32SExt16,
- CMPWI, CMPLWI, CMPW, CMPLW>;
- defm : P10ReverseSetBool<(i1 (setcc i32:$s1, imm:$imm, SETNE)),
- (EXTRACT_SUBREG (CMPLWI (XORIS $s1, (HI16 imm:$imm)),
- (LO16 imm:$imm)), sub_eq)>;
-
- // Instantiation of the set boolean reverse patterns for 64-bit integers.
- defm : IntSetP10RevSetBool<setcc, i64, immZExt16, imm64SExt16,
- CMPDI, CMPLDI, CMPD, CMPLD>;
- defm : P10ReverseSetBool<(i1 (setcc i64:$s1, imm64ZExt32:$imm, SETNE)),
- (EXTRACT_SUBREG (CMPLDI (XORIS8 $s1, (HI16 imm:$imm)),
- (LO16 imm:$imm)), sub_eq)>;
-}
-
-// Instantiation of the set boolean reverse patterns for f32, f64, f128.
-let Predicates = [IsISA3_1, HasFPU] in {
- defm : FSetP10RevSetBool<setcc, f32, FCMPUS>;
- defm : FSetP10RevSetBool<setcc, f64, FCMPUD>;
- defm : FSetP10RevSetBool<setcc, f128, XSCMPUQP>;
-}
-
+
+ def VMULESD : VXForm_1<968, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vmulesd $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v1i128:$vD, (int_ppc_altivec_vmulesd v2i64:$vA,
+ v2i64:$vB))]>;
+ def VMULEUD : VXForm_1<712, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vmuleud $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v1i128:$vD, (int_ppc_altivec_vmuleud v2i64:$vA,
+ v2i64:$vB))]>;
+ def VMULOSD : VXForm_1<456, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vmulosd $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v1i128:$vD, (int_ppc_altivec_vmulosd v2i64:$vA,
+ v2i64:$vB))]>;
+ def VMULOUD : VXForm_1<200, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vmuloud $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v1i128:$vD, (int_ppc_altivec_vmuloud v2i64:$vA,
+ v2i64:$vB))]>;
+ def VMSUMCUD : VAForm_1a<23, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB, vrrc:$vC),
+ "vmsumcud $vD, $vA, $vB, $vC", IIC_VecGeneral,
+ [(set v1i128:$vD, (int_ppc_altivec_vmsumcud
+ v2i64:$vA, v2i64:$vB, v1i128:$vC))]>;
+ def VDIVSQ : VXForm_1<267, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vdivsq $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v1i128:$vD, (sdiv v1i128:$vA, v1i128:$vB))]>;
+ def VDIVUQ : VXForm_1<11, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vdivuq $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v1i128:$vD, (udiv v1i128:$vA, v1i128:$vB))]>;
+ def VDIVESQ : VXForm_1<779, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vdivesq $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v1i128:$vD, (int_ppc_altivec_vdivesq v1i128:$vA,
+ v1i128:$vB))]>;
+ def VDIVEUQ : VXForm_1<523, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vdiveuq $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v1i128:$vD, (int_ppc_altivec_vdiveuq v1i128:$vA,
+ v1i128:$vB))]>;
+ def VCMPEQUQ : VCMP <455, "vcmpequq $vD, $vA, $vB" , v1i128>;
+ def VCMPGTSQ : VCMP <903, "vcmpgtsq $vD, $vA, $vB" , v1i128>;
+ def VCMPGTUQ : VCMP <647, "vcmpgtuq $vD, $vA, $vB" , v1i128>;
+ def VCMPEQUQ_rec : VCMP_rec <455, "vcmpequq. $vD, $vA, $vB" , v1i128>;
+ def VCMPGTSQ_rec : VCMP_rec <903, "vcmpgtsq. $vD, $vA, $vB" , v1i128>;
+ def VCMPGTUQ_rec : VCMP_rec <647, "vcmpgtuq. $vD, $vA, $vB" , v1i128>;
+ def VMODSQ : VXForm_1<1803, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vmodsq $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v1i128:$vD, (srem v1i128:$vA, v1i128:$vB))]>;
+ def VMODUQ : VXForm_1<1547, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
+ "vmoduq $vD, $vA, $vB", IIC_VecGeneral,
+ [(set v1i128:$vD, (urem v1i128:$vA, v1i128:$vB))]>;
+ def VEXTSD2Q : VXForm_RD5_XO5_RS5<1538, 27, (outs vrrc:$vD), (ins vrrc:$vB),
+ "vextsd2q $vD, $vB", IIC_VecGeneral,
+ [(set v1i128:$vD, (int_ppc_altivec_vextsd2q v2i64:$vB))]>;
+ def VCMPUQ : VXForm_BF3_VAB5<257, (outs crrc:$BF), (ins vrrc:$vA, vrrc:$vB),
+ "vcmpuq $BF, $vA, $vB", IIC_VecGeneral, []>;
+ def VCMPSQ : VXForm_BF3_VAB5<321, (outs crrc:$BF), (ins vrrc:$vA, vrrc:$vB),
+ "vcmpsq $BF, $vA, $vB", IIC_VecGeneral, []>;
+ def VRLQNM : VX1_VT5_VA5_VB5<325, "vrlqnm",
+ [(set v1i128:$vD,
+ (int_ppc_altivec_vrlqnm v1i128:$vA,
+ v1i128:$vB))]>;
+ def VRLQMI : VXForm_1<69, (outs vrrc:$vD),
+ (ins vrrc:$vA, vrrc:$vB, vrrc:$vDi),
+ "vrlqmi $vD, $vA, $vB", IIC_VecFP,
+ [(set v1i128:$vD,
+ (int_ppc_altivec_vrlqmi v1i128:$vA, v1i128:$vB,
+ v1i128:$vDi))]>,
+ RegConstraint<"$vDi = $vD">, NoEncode<"$vDi">;
+ def VSLQ : VX1_VT5_VA5_VB5<261, "vslq", []>;
+ def VSRAQ : VX1_VT5_VA5_VB5<773, "vsraq", []>;
+ def VSRQ : VX1_VT5_VA5_VB5<517, "vsrq", []>;
+ def VRLQ : VX1_VT5_VA5_VB5<5, "vrlq", []>;
+ def XSCVQPUQZ : X_VT5_XO5_VB5<63, 0, 836, "xscvqpuqz", []>;
+ def XSCVQPSQZ : X_VT5_XO5_VB5<63, 8, 836, "xscvqpsqz", []>;
+ def XSCVUQQP : X_VT5_XO5_VB5<63, 3, 836, "xscvuqqp", []>;
+ def XSCVSQQP : X_VT5_XO5_VB5<63, 11, 836, "xscvsqqp", []>;
+}
+
+let Predicates = [IsISA3_1, HasVSX] in {
+ def XVCVSPBF16 : XX2_XT6_XO5_XB6<60, 17, 475, "xvcvspbf16", vsrc, []>;
+ def XVCVBF16SPN : XX2_XT6_XO5_XB6<60, 16, 475, "xvcvbf16spn", vsrc, []>;
+}
+
+// Multiclass defining patterns for Set Boolean Extension Reverse Instructions.
+// This is analogous to the CRNotPat multiclass but specifically for Power10
+// and newer subtargets since the extended forms use Set Boolean instructions.
+// The first two anonymous patterns defined are actually a duplicate of those
+// in CRNotPat, but it is preferable to define both multiclasses as complete
+// ones rather than pulling that small common section out.
+multiclass P10ReverseSetBool<dag pattern, dag result> {
+ def : Pat<pattern, (crnot result)>;
+ def : Pat<(not pattern), result>;
+
+ def : Pat<(i32 (zext pattern)),
+ (SETBCR result)>;
+ def : Pat<(i64 (zext pattern)),
+ (SETBCR8 result)>;
+
+ def : Pat<(i32 (sext pattern)),
+ (SETNBCR result)>;
+ def : Pat<(i64 (sext pattern)),
+ (SETNBCR8 result)>;
+
+ def : Pat<(i32 (anyext pattern)),
+ (SETBCR result)>;
+ def : Pat<(i64 (anyext pattern)),
+ (SETBCR8 result)>;
+}
+
+multiclass IntSetP10RevSetBool<SDNode SetCC, ValueType Ty, ImmLeaf ZExtTy,
+ ImmLeaf SExtTy, PatLeaf Cmpi, PatLeaf Cmpli,
+ PatLeaf Cmp, PatLeaf Cmpl> {
+ defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETUGE)),
+ (EXTRACT_SUBREG (Cmpl $s1, $s2), sub_lt)>;
+ defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETGE)),
+ (EXTRACT_SUBREG (Cmp $s1, $s2), sub_lt)>;
+ defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETULE)),
+ (EXTRACT_SUBREG (Cmpl $s1, $s2), sub_gt)>;
+ defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETLE)),
+ (EXTRACT_SUBREG (Cmp $s1, $s2), sub_gt)>;
+ defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETNE)),
+ (EXTRACT_SUBREG (Cmp $s1, $s2), sub_eq)>;
+
+ defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, ZExtTy:$imm, SETUGE)),
+ (EXTRACT_SUBREG (Cmpli $s1, imm:$imm), sub_lt)>;
+ defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, SExtTy:$imm, SETGE)),
+ (EXTRACT_SUBREG (Cmpi $s1, imm:$imm), sub_lt)>;
+ defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, ZExtTy:$imm, SETULE)),
+ (EXTRACT_SUBREG (Cmpli $s1, imm:$imm), sub_gt)>;
+ defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, SExtTy:$imm, SETLE)),
+ (EXTRACT_SUBREG (Cmpi $s1, imm:$imm), sub_gt)>;
+ defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, SExtTy:$imm, SETNE)),
+ (EXTRACT_SUBREG (Cmpi $s1, imm:$imm), sub_eq)>;
+ defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, ZExtTy:$imm, SETNE)),
+ (EXTRACT_SUBREG (Cmpli $s1, imm:$imm), sub_eq)>;
+}
+
+multiclass FSetP10RevSetBool<SDNode SetCC, ValueType Ty, PatLeaf FCmp> {
+ defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETUGE)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
+ defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETGE)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
+ defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETULE)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
+ defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETLE)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
+ defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETUNE)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
+ defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETNE)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
+ defm : P10ReverseSetBool<(i1 (SetCC Ty:$s1, Ty:$s2, SETO)),
+ (EXTRACT_SUBREG (FCmp $s1, $s2), sub_un)>;
+}
+
+let Predicates = [IsISA3_1] in {
+ def : Pat<(i32 (zext i1:$in)),
+ (SETBC $in)>;
+ def : Pat<(i64 (zext i1:$in)),
+ (SETBC8 $in)>;
+ def : Pat<(i32 (sext i1:$in)),
+ (SETNBC $in)>;
+ def : Pat<(i64 (sext i1:$in)),
+ (SETNBC8 $in)>;
+ def : Pat<(i32 (anyext i1:$in)),
+ (SETBC $in)>;
+ def : Pat<(i64 (anyext i1:$in)),
+ (SETBC8 $in)>;
+
+ // Instantiation of the set boolean reverse patterns for 32-bit integers.
+ defm : IntSetP10RevSetBool<setcc, i32, immZExt16, imm32SExt16,
+ CMPWI, CMPLWI, CMPW, CMPLW>;
+ defm : P10ReverseSetBool<(i1 (setcc i32:$s1, imm:$imm, SETNE)),
+ (EXTRACT_SUBREG (CMPLWI (XORIS $s1, (HI16 imm:$imm)),
+ (LO16 imm:$imm)), sub_eq)>;
+
+ // Instantiation of the set boolean reverse patterns for 64-bit integers.
+ defm : IntSetP10RevSetBool<setcc, i64, immZExt16, imm64SExt16,
+ CMPDI, CMPLDI, CMPD, CMPLD>;
+ defm : P10ReverseSetBool<(i1 (setcc i64:$s1, imm64ZExt32:$imm, SETNE)),
+ (EXTRACT_SUBREG (CMPLDI (XORIS8 $s1, (HI16 imm:$imm)),
+ (LO16 imm:$imm)), sub_eq)>;
+}
+
+// Instantiation of the set boolean reverse patterns for f32, f64, f128.
+let Predicates = [IsISA3_1, HasFPU] in {
+ defm : FSetP10RevSetBool<setcc, f32, FCMPUS>;
+ defm : FSetP10RevSetBool<setcc, f64, FCMPUD>;
+ defm : FSetP10RevSetBool<setcc, f128, XSCMPUQP>;
+}
+
//---------------------------- Anonymous Patterns ----------------------------//
let Predicates = [IsISA3_1] in {
- // Exploit the vector multiply high instructions using intrinsics.
- def : Pat<(v4i32 (int_ppc_altivec_vmulhsw v4i32:$vA, v4i32:$vB)),
- (v4i32 (VMULHSW $vA, $vB))>;
- def : Pat<(v4i32 (int_ppc_altivec_vmulhuw v4i32:$vA, v4i32:$vB)),
- (v4i32 (VMULHUW $vA, $vB))>;
- def : Pat<(v2i64 (int_ppc_altivec_vmulhsd v2i64:$vA, v2i64:$vB)),
- (v2i64 (VMULHSD $vA, $vB))>;
- def : Pat<(v2i64 (int_ppc_altivec_vmulhud v2i64:$vA, v2i64:$vB)),
- (v2i64 (VMULHUD $vA, $vB))>;
+ // Exploit the vector multiply high instructions using intrinsics.
+ def : Pat<(v4i32 (int_ppc_altivec_vmulhsw v4i32:$vA, v4i32:$vB)),
+ (v4i32 (VMULHSW $vA, $vB))>;
+ def : Pat<(v4i32 (int_ppc_altivec_vmulhuw v4i32:$vA, v4i32:$vB)),
+ (v4i32 (VMULHUW $vA, $vB))>;
+ def : Pat<(v2i64 (int_ppc_altivec_vmulhsd v2i64:$vA, v2i64:$vB)),
+ (v2i64 (VMULHSD $vA, $vB))>;
+ def : Pat<(v2i64 (int_ppc_altivec_vmulhud v2i64:$vA, v2i64:$vB)),
+ (v2i64 (VMULHUD $vA, $vB))>;
def : Pat<(v16i8 (int_ppc_vsx_xxgenpcvbm v16i8:$VRB, imm:$IMM)),
(v16i8 (COPY_TO_REGCLASS (XXGENPCVBM $VRB, imm:$IMM), VRRC))>;
def : Pat<(v8i16 (int_ppc_vsx_xxgenpcvhm v8i16:$VRB, imm:$IMM)),
@@ -2517,82 +2517,82 @@ let Predicates = [IsISA3_1] in {
(v4i32 (COPY_TO_REGCLASS (XXGENPCVWM $VRB, imm:$IMM), VRRC))>;
def : Pat<(v2i64 (int_ppc_vsx_xxgenpcvdm v2i64:$VRB, imm:$IMM)),
(v2i64 (COPY_TO_REGCLASS (XXGENPCVDM $VRB, imm:$IMM), VRRC))>;
- def : Pat<(i32 (int_ppc_vsx_xvtlsbb v16i8:$XB, 1)),
+ def : Pat<(i32 (int_ppc_vsx_xvtlsbb v16i8:$XB, 1)),
(EXTRACT_SUBREG (XVTLSBB (COPY_TO_REGCLASS $XB, VSRC)), sub_lt)>;
def : Pat<(i32 (int_ppc_vsx_xvtlsbb v16i8:$XB, 0)),
(EXTRACT_SUBREG (XVTLSBB (COPY_TO_REGCLASS $XB, VSRC)), sub_eq)>;
-
- def : Pat <(v1i128 (PPClxvrzx xoaddr:$src, 8)),
- (v1i128 (COPY_TO_REGCLASS (LXVRBX xoaddr:$src), VRRC))>;
- def : Pat <(v1i128 (PPClxvrzx xoaddr:$src, 16)),
- (v1i128 (COPY_TO_REGCLASS (LXVRHX xoaddr:$src), VRRC))>;
- def : Pat <(v1i128 (PPClxvrzx xoaddr:$src, 32)),
- (v1i128 (COPY_TO_REGCLASS (LXVRWX xoaddr:$src), VRRC))>;
- def : Pat <(v1i128 (PPClxvrzx xoaddr:$src, 64)),
- (v1i128 (COPY_TO_REGCLASS (LXVRDX xoaddr:$src), VRRC))>;
-
- def : Pat<(v1i128 (rotl v1i128:$vA, v1i128:$vB)),
- (v1i128 (VRLQ v1i128:$vA, v1i128:$vB))>;
-
- def : Pat <(v2i64 (PPCxxsplti32dx v2i64:$XT, i32:$XI, i32:$IMM32)),
- (v2i64 (XXSPLTI32DX v2i64:$XT, i32:$XI, i32:$IMM32))>;
-}
-
-let Predicates = [IsISA3_1, HasVSX] in {
- def : Pat<(v16i8 (int_ppc_vsx_xvcvspbf16 v16i8:$XA)),
- (COPY_TO_REGCLASS (XVCVSPBF16 RCCp.AToVSRC), VRRC)>;
- def : Pat<(v16i8 (int_ppc_vsx_xvcvbf16spn v16i8:$XA)),
- (COPY_TO_REGCLASS (XVCVBF16SPN RCCp.AToVSRC), VRRC)>;
-}
-
-let AddedComplexity = 400, Predicates = [IsISA3_1, IsLittleEndian] in {
- // Store element 0 of a VSX register to memory
- def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$src, 0)), xoaddr:$dst),
- (STXVRBX (COPY_TO_REGCLASS v16i8:$src, VSRC), xoaddr:$dst)>;
- def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$src, 0)), xoaddr:$dst),
- (STXVRHX (COPY_TO_REGCLASS v8i16:$src, VSRC), xoaddr:$dst)>;
- def : Pat<(store (i32 (extractelt v4i32:$src, 0)), xoaddr:$dst),
- (STXVRWX $src, xoaddr:$dst)>;
- def : Pat<(store (f32 (extractelt v4f32:$src, 0)), xoaddr:$dst),
- (STXVRWX $src, xoaddr:$dst)>;
- def : Pat<(store (i64 (extractelt v2i64:$src, 0)), xoaddr:$dst),
- (STXVRDX $src, xoaddr:$dst)>;
- def : Pat<(store (f64 (extractelt v2f64:$src, 0)), xoaddr:$dst),
- (STXVRDX $src, xoaddr:$dst)>;
- }
-
-// FIXME: The swap is overkill when the shift amount is a constant.
-// We should just fix the constant in the DAG.
-let AddedComplexity = 400, Predicates = [IsISA3_1, HasVSX] in {
- def : Pat<(v1i128 (shl v1i128:$VRA, v1i128:$VRB)),
- (v1i128 (VSLQ v1i128:$VRA,
- (XXPERMDI (COPY_TO_REGCLASS $VRB, VSRC),
- (COPY_TO_REGCLASS $VRB, VSRC), 2)))>;
- def : Pat<(v1i128 (PPCshl v1i128:$VRA, v1i128:$VRB)),
- (v1i128 (VSLQ v1i128:$VRA,
- (XXPERMDI (COPY_TO_REGCLASS $VRB, VSRC),
- (COPY_TO_REGCLASS $VRB, VSRC), 2)))>;
- def : Pat<(v1i128 (srl v1i128:$VRA, v1i128:$VRB)),
- (v1i128 (VSRQ v1i128:$VRA,
- (XXPERMDI (COPY_TO_REGCLASS $VRB, VSRC),
- (COPY_TO_REGCLASS $VRB, VSRC), 2)))>;
- def : Pat<(v1i128 (PPCsrl v1i128:$VRA, v1i128:$VRB)),
- (v1i128 (VSRQ v1i128:$VRA,
- (XXPERMDI (COPY_TO_REGCLASS $VRB, VSRC),
- (COPY_TO_REGCLASS $VRB, VSRC), 2)))>;
- def : Pat<(v1i128 (sra v1i128:$VRA, v1i128:$VRB)),
- (v1i128 (VSRAQ v1i128:$VRA,
- (XXPERMDI (COPY_TO_REGCLASS $VRB, VSRC),
- (COPY_TO_REGCLASS $VRB, VSRC), 2)))>;
- def : Pat<(v1i128 (PPCsra v1i128:$VRA, v1i128:$VRB)),
- (v1i128 (VSRAQ v1i128:$VRA,
- (XXPERMDI (COPY_TO_REGCLASS $VRB, VSRC),
- (COPY_TO_REGCLASS $VRB, VSRC), 2)))>;
-}
-
-class xxevalPattern <dag pattern, bits<8> imm> :
- Pat<(v4i32 pattern), (XXEVAL $vA, $vB, $vC, imm)> {}
-
+
+ def : Pat <(v1i128 (PPClxvrzx xoaddr:$src, 8)),
+ (v1i128 (COPY_TO_REGCLASS (LXVRBX xoaddr:$src), VRRC))>;
+ def : Pat <(v1i128 (PPClxvrzx xoaddr:$src, 16)),
+ (v1i128 (COPY_TO_REGCLASS (LXVRHX xoaddr:$src), VRRC))>;
+ def : Pat <(v1i128 (PPClxvrzx xoaddr:$src, 32)),
+ (v1i128 (COPY_TO_REGCLASS (LXVRWX xoaddr:$src), VRRC))>;
+ def : Pat <(v1i128 (PPClxvrzx xoaddr:$src, 64)),
+ (v1i128 (COPY_TO_REGCLASS (LXVRDX xoaddr:$src), VRRC))>;
+
+ def : Pat<(v1i128 (rotl v1i128:$vA, v1i128:$vB)),
+ (v1i128 (VRLQ v1i128:$vA, v1i128:$vB))>;
+
+ def : Pat <(v2i64 (PPCxxsplti32dx v2i64:$XT, i32:$XI, i32:$IMM32)),
+ (v2i64 (XXSPLTI32DX v2i64:$XT, i32:$XI, i32:$IMM32))>;
+}
+
+let Predicates = [IsISA3_1, HasVSX] in {
+ def : Pat<(v16i8 (int_ppc_vsx_xvcvspbf16 v16i8:$XA)),
+ (COPY_TO_REGCLASS (XVCVSPBF16 RCCp.AToVSRC), VRRC)>;
+ def : Pat<(v16i8 (int_ppc_vsx_xvcvbf16spn v16i8:$XA)),
+ (COPY_TO_REGCLASS (XVCVBF16SPN RCCp.AToVSRC), VRRC)>;
+}
+
+let AddedComplexity = 400, Predicates = [IsISA3_1, IsLittleEndian] in {
+ // Store element 0 of a VSX register to memory
+ def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$src, 0)), xoaddr:$dst),
+ (STXVRBX (COPY_TO_REGCLASS v16i8:$src, VSRC), xoaddr:$dst)>;
+ def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$src, 0)), xoaddr:$dst),
+ (STXVRHX (COPY_TO_REGCLASS v8i16:$src, VSRC), xoaddr:$dst)>;
+ def : Pat<(store (i32 (extractelt v4i32:$src, 0)), xoaddr:$dst),
+ (STXVRWX $src, xoaddr:$dst)>;
+ def : Pat<(store (f32 (extractelt v4f32:$src, 0)), xoaddr:$dst),
+ (STXVRWX $src, xoaddr:$dst)>;
+ def : Pat<(store (i64 (extractelt v2i64:$src, 0)), xoaddr:$dst),
+ (STXVRDX $src, xoaddr:$dst)>;
+ def : Pat<(store (f64 (extractelt v2f64:$src, 0)), xoaddr:$dst),
+ (STXVRDX $src, xoaddr:$dst)>;
+ }
+
+// FIXME: The swap is overkill when the shift amount is a constant.
+// We should just fix the constant in the DAG.
+let AddedComplexity = 400, Predicates = [IsISA3_1, HasVSX] in {
+ def : Pat<(v1i128 (shl v1i128:$VRA, v1i128:$VRB)),
+ (v1i128 (VSLQ v1i128:$VRA,
+ (XXPERMDI (COPY_TO_REGCLASS $VRB, VSRC),
+ (COPY_TO_REGCLASS $VRB, VSRC), 2)))>;
+ def : Pat<(v1i128 (PPCshl v1i128:$VRA, v1i128:$VRB)),
+ (v1i128 (VSLQ v1i128:$VRA,
+ (XXPERMDI (COPY_TO_REGCLASS $VRB, VSRC),
+ (COPY_TO_REGCLASS $VRB, VSRC), 2)))>;
+ def : Pat<(v1i128 (srl v1i128:$VRA, v1i128:$VRB)),
+ (v1i128 (VSRQ v1i128:$VRA,
+ (XXPERMDI (COPY_TO_REGCLASS $VRB, VSRC),
+ (COPY_TO_REGCLASS $VRB, VSRC), 2)))>;
+ def : Pat<(v1i128 (PPCsrl v1i128:$VRA, v1i128:$VRB)),
+ (v1i128 (VSRQ v1i128:$VRA,
+ (XXPERMDI (COPY_TO_REGCLASS $VRB, VSRC),
+ (COPY_TO_REGCLASS $VRB, VSRC), 2)))>;
+ def : Pat<(v1i128 (sra v1i128:$VRA, v1i128:$VRB)),
+ (v1i128 (VSRAQ v1i128:$VRA,
+ (XXPERMDI (COPY_TO_REGCLASS $VRB, VSRC),
+ (COPY_TO_REGCLASS $VRB, VSRC), 2)))>;
+ def : Pat<(v1i128 (PPCsra v1i128:$VRA, v1i128:$VRB)),
+ (v1i128 (VSRAQ v1i128:$VRA,
+ (XXPERMDI (COPY_TO_REGCLASS $VRB, VSRC),
+ (COPY_TO_REGCLASS $VRB, VSRC), 2)))>;
+}
+
+class xxevalPattern <dag pattern, bits<8> imm> :
+ Pat<(v4i32 pattern), (XXEVAL $vA, $vB, $vC, imm)> {}
+
let AddedComplexity = 400, Predicates = [PrefixInstrs] in {
def : Pat<(v4i32 (build_vector i32immNonAllOneNonZero:$A,
i32immNonAllOneNonZero:$A,
@@ -2605,44 +2605,44 @@ let AddedComplexity = 400, Predicates = [PrefixInstrs] in {
def : Pat<(f64 nzFPImmAsi32:$A),
(COPY_TO_REGCLASS (XXSPLTIDP (getFPAs32BitInt fpimm:$A)),
VSFRC)>;
-
- // Anonymous patterns for XXEVAL
- // AND
- // and(A, B, C)
- def : xxevalPattern<(and v4i32:$vA, (and v4i32:$vB, v4i32:$vC)), 1>;
- // and(A, xor(B, C))
- def : xxevalPattern<(and v4i32:$vA, (xor v4i32:$vB, v4i32:$vC)), 6>;
- // and(A, or(B, C))
- def : xxevalPattern<(and v4i32:$vA, (or v4i32:$vB, v4i32:$vC)), 7>;
- // and(A, nor(B, C))
- def : xxevalPattern<(and v4i32:$vA, (vnot_ppc (or v4i32:$vB, v4i32:$vC))),
- 8>;
- // and(A, eqv(B, C))
- def : xxevalPattern<(and v4i32:$vA, (vnot_ppc (xor v4i32:$vB, v4i32:$vC))),
- 9>;
- // and(A, nand(B, C))
- def : xxevalPattern<(and v4i32:$vA, (vnot_ppc (and v4i32:$vB, v4i32:$vC))),
- 14>;
-
- // NAND
- // nand(A, B, C)
- def : xxevalPattern<(vnot_ppc (and v4i32:$vA, (and v4i32:$vB, v4i32:$vC))),
- !sub(255, 1)>;
- // nand(A, xor(B, C))
- def : xxevalPattern<(vnot_ppc (and v4i32:$vA, (xor v4i32:$vB, v4i32:$vC))),
- !sub(255, 6)>;
- // nand(A, or(B, C))
- def : xxevalPattern<(vnot_ppc (and v4i32:$vA, (or v4i32:$vB, v4i32:$vC))),
- !sub(255, 7)>;
- // nand(A, nor(B, C))
- def : xxevalPattern<(or (vnot_ppc v4i32:$vA), (or v4i32:$vB, v4i32:$vC)),
- !sub(255, 8)>;
- // nand(A, eqv(B, C))
- def : xxevalPattern<(or (vnot_ppc v4i32:$vA), (xor v4i32:$vB, v4i32:$vC)),
- !sub(255, 9)>;
- // nand(A, nand(B, C))
- def : xxevalPattern<(or (vnot_ppc v4i32:$vA), (and v4i32:$vB, v4i32:$vC)),
- !sub(255, 14)>;
+
+ // Anonymous patterns for XXEVAL
+ // AND
+ // and(A, B, C)
+ def : xxevalPattern<(and v4i32:$vA, (and v4i32:$vB, v4i32:$vC)), 1>;
+ // and(A, xor(B, C))
+ def : xxevalPattern<(and v4i32:$vA, (xor v4i32:$vB, v4i32:$vC)), 6>;
+ // and(A, or(B, C))
+ def : xxevalPattern<(and v4i32:$vA, (or v4i32:$vB, v4i32:$vC)), 7>;
+ // and(A, nor(B, C))
+ def : xxevalPattern<(and v4i32:$vA, (vnot_ppc (or v4i32:$vB, v4i32:$vC))),
+ 8>;
+ // and(A, eqv(B, C))
+ def : xxevalPattern<(and v4i32:$vA, (vnot_ppc (xor v4i32:$vB, v4i32:$vC))),
+ 9>;
+ // and(A, nand(B, C))
+ def : xxevalPattern<(and v4i32:$vA, (vnot_ppc (and v4i32:$vB, v4i32:$vC))),
+ 14>;
+
+ // NAND
+ // nand(A, B, C)
+ def : xxevalPattern<(vnot_ppc (and v4i32:$vA, (and v4i32:$vB, v4i32:$vC))),
+ !sub(255, 1)>;
+ // nand(A, xor(B, C))
+ def : xxevalPattern<(vnot_ppc (and v4i32:$vA, (xor v4i32:$vB, v4i32:$vC))),
+ !sub(255, 6)>;
+ // nand(A, or(B, C))
+ def : xxevalPattern<(vnot_ppc (and v4i32:$vA, (or v4i32:$vB, v4i32:$vC))),
+ !sub(255, 7)>;
+ // nand(A, nor(B, C))
+ def : xxevalPattern<(or (vnot_ppc v4i32:$vA), (or v4i32:$vB, v4i32:$vC)),
+ !sub(255, 8)>;
+ // nand(A, eqv(B, C))
+ def : xxevalPattern<(or (vnot_ppc v4i32:$vA), (xor v4i32:$vB, v4i32:$vC)),
+ !sub(255, 9)>;
+ // nand(A, nand(B, C))
+ def : xxevalPattern<(or (vnot_ppc v4i32:$vA), (and v4i32:$vB, v4i32:$vC)),
+ !sub(255, 14)>;
}
let Predicates = [PrefixInstrs] in {
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrVSX.td b/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrVSX.td
index 563da075ba..db6e00c71b 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrVSX.td
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCInstrVSX.td
@@ -145,7 +145,7 @@ def PPCSToV : SDNode<"PPCISD::SCALAR_TO_VECTOR_PERMUTED",
def HasVSX : Predicate<"Subtarget->hasVSX()">;
def IsLittleEndian : Predicate<"Subtarget->isLittleEndian()">;
def IsBigEndian : Predicate<"!Subtarget->isLittleEndian()">;
-def IsPPC64 : Predicate<"Subtarget->isPPC64()">;
+def IsPPC64 : Predicate<"Subtarget->isPPC64()">;
def HasOnlySwappingMemOps : Predicate<"!Subtarget->hasP9Vector()">;
def HasP8Vector : Predicate<"Subtarget->hasP8Vector()">;
def HasDirectMove : Predicate<"Subtarget->hasDirectMove()">;
@@ -168,7 +168,7 @@ multiclass XX3Form_Rcr<bits<6> opcode, bits<7> xo, string asmbase,
def _rec : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
!strconcat(asmbase, !strconcat(". ", asmstr)), itin,
[(set InTy:$XT,
- (InTy (PPCvcmp_rec InTy:$XA, InTy:$XB, xo)))]>,
+ (InTy (PPCvcmp_rec InTy:$XA, InTy:$XB, xo)))]>,
isRecordForm;
}
}
@@ -363,8 +363,8 @@ let hasSideEffects = 0 in {
}
} // mayStore
- let mayRaiseFPException = 1 in {
- let Uses = [RM] in {
+ let mayRaiseFPException = 1 in {
+ let Uses = [RM] in {
// Add/Mul Instructions
let isCommutable = 1 in {
def XSADDDP : XX3Form<60, 32,
@@ -624,31 +624,31 @@ let hasSideEffects = 0 in {
"xsrsqrtedp $XT, $XB", IIC_VecFP,
[(set f64:$XT, (PPCfrsqrte f64:$XB))]>;
- let mayRaiseFPException = 0 in {
+ let mayRaiseFPException = 0 in {
def XSTDIVDP : XX3Form_1<60, 61,
(outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
"xstdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
def XSTSQRTDP : XX2Form_1<60, 106,
(outs crrc:$crD), (ins vsfrc:$XB),
- "xstsqrtdp $crD, $XB", IIC_FPCompare,
- [(set i32:$crD, (PPCftsqrt f64:$XB))]>;
- def XVTDIVDP : XX3Form_1<60, 125,
- (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
- "xvtdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
- def XVTDIVSP : XX3Form_1<60, 93,
- (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
- "xvtdivsp $crD, $XA, $XB", IIC_FPCompare, []>;
-
- def XVTSQRTDP : XX2Form_1<60, 234,
- (outs crrc:$crD), (ins vsrc:$XB),
- "xvtsqrtdp $crD, $XB", IIC_FPCompare,
- [(set i32:$crD, (PPCftsqrt v2f64:$XB))]>;
- def XVTSQRTSP : XX2Form_1<60, 170,
- (outs crrc:$crD), (ins vsrc:$XB),
- "xvtsqrtsp $crD, $XB", IIC_FPCompare,
- [(set i32:$crD, (PPCftsqrt v4f32:$XB))]>;
- }
-
+ "xstsqrtdp $crD, $XB", IIC_FPCompare,
+ [(set i32:$crD, (PPCftsqrt f64:$XB))]>;
+ def XVTDIVDP : XX3Form_1<60, 125,
+ (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
+ "xvtdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
+ def XVTDIVSP : XX3Form_1<60, 93,
+ (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
+ "xvtdivsp $crD, $XA, $XB", IIC_FPCompare, []>;
+
+ def XVTSQRTDP : XX2Form_1<60, 234,
+ (outs crrc:$crD), (ins vsrc:$XB),
+ "xvtsqrtdp $crD, $XB", IIC_FPCompare,
+ [(set i32:$crD, (PPCftsqrt v2f64:$XB))]>;
+ def XVTSQRTSP : XX2Form_1<60, 170,
+ (outs crrc:$crD), (ins vsrc:$XB),
+ "xvtsqrtsp $crD, $XB", IIC_FPCompare,
+ [(set i32:$crD, (PPCftsqrt v4f32:$XB))]>;
+ }
+
def XVDIVDP : XX3Form<60, 120,
(outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
"xvdivdp $XT, $XA, $XB", IIC_FPDivD,
@@ -713,7 +713,7 @@ let hasSideEffects = 0 in {
int_ppc_vsx_xvcmpgtsp, v4i32, v4f32>;
// Move Instructions
- let mayRaiseFPException = 0 in {
+ let mayRaiseFPException = 0 in {
def XSABSDP : XX2Form<60, 345,
(outs vsfrc:$XT), (ins vsfrc:$XB),
"xsabsdp $XT, $XB", IIC_VecFP,
@@ -767,7 +767,7 @@ let hasSideEffects = 0 in {
(outs vsrc:$XT), (ins vsrc:$XB),
"xvnegsp $XT, $XB", IIC_VecFP,
[(set v4f32:$XT, (fneg v4f32:$XB))]>;
- }
+ }
// Conversion Instructions
def XSCVDPSP : XX2Form<60, 265,
@@ -776,50 +776,50 @@ let hasSideEffects = 0 in {
def XSCVDPSXDS : XX2Form<60, 344,
(outs vsfrc:$XT), (ins vsfrc:$XB),
"xscvdpsxds $XT, $XB", IIC_VecFP,
- [(set f64:$XT, (PPCany_fctidz f64:$XB))]>;
+ [(set f64:$XT, (PPCany_fctidz f64:$XB))]>;
let isCodeGenOnly = 1 in
def XSCVDPSXDSs : XX2Form<60, 344,
(outs vssrc:$XT), (ins vssrc:$XB),
"xscvdpsxds $XT, $XB", IIC_VecFP,
- [(set f32:$XT, (PPCany_fctidz f32:$XB))]>;
+ [(set f32:$XT, (PPCany_fctidz f32:$XB))]>;
def XSCVDPSXWS : XX2Form<60, 88,
(outs vsfrc:$XT), (ins vsfrc:$XB),
"xscvdpsxws $XT, $XB", IIC_VecFP,
- [(set f64:$XT, (PPCany_fctiwz f64:$XB))]>;
+ [(set f64:$XT, (PPCany_fctiwz f64:$XB))]>;
let isCodeGenOnly = 1 in
def XSCVDPSXWSs : XX2Form<60, 88,
(outs vssrc:$XT), (ins vssrc:$XB),
"xscvdpsxws $XT, $XB", IIC_VecFP,
- [(set f32:$XT, (PPCany_fctiwz f32:$XB))]>;
+ [(set f32:$XT, (PPCany_fctiwz f32:$XB))]>;
def XSCVDPUXDS : XX2Form<60, 328,
(outs vsfrc:$XT), (ins vsfrc:$XB),
"xscvdpuxds $XT, $XB", IIC_VecFP,
- [(set f64:$XT, (PPCany_fctiduz f64:$XB))]>;
+ [(set f64:$XT, (PPCany_fctiduz f64:$XB))]>;
let isCodeGenOnly = 1 in
def XSCVDPUXDSs : XX2Form<60, 328,
(outs vssrc:$XT), (ins vssrc:$XB),
"xscvdpuxds $XT, $XB", IIC_VecFP,
- [(set f32:$XT, (PPCany_fctiduz f32:$XB))]>;
+ [(set f32:$XT, (PPCany_fctiduz f32:$XB))]>;
def XSCVDPUXWS : XX2Form<60, 72,
(outs vsfrc:$XT), (ins vsfrc:$XB),
"xscvdpuxws $XT, $XB", IIC_VecFP,
- [(set f64:$XT, (PPCany_fctiwuz f64:$XB))]>;
+ [(set f64:$XT, (PPCany_fctiwuz f64:$XB))]>;
let isCodeGenOnly = 1 in
def XSCVDPUXWSs : XX2Form<60, 72,
(outs vssrc:$XT), (ins vssrc:$XB),
"xscvdpuxws $XT, $XB", IIC_VecFP,
- [(set f32:$XT, (PPCany_fctiwuz f32:$XB))]>;
+ [(set f32:$XT, (PPCany_fctiwuz f32:$XB))]>;
def XSCVSPDP : XX2Form<60, 329,
(outs vsfrc:$XT), (ins vsfrc:$XB),
"xscvspdp $XT, $XB", IIC_VecFP, []>;
def XSCVSXDDP : XX2Form<60, 376,
(outs vsfrc:$XT), (ins vsfrc:$XB),
"xscvsxddp $XT, $XB", IIC_VecFP,
- [(set f64:$XT, (PPCany_fcfid f64:$XB))]>;
+ [(set f64:$XT, (PPCany_fcfid f64:$XB))]>;
def XSCVUXDDP : XX2Form<60, 360,
(outs vsfrc:$XT), (ins vsfrc:$XB),
"xscvuxddp $XT, $XB", IIC_VecFP,
- [(set f64:$XT, (PPCany_fcfidu f64:$XB))]>;
+ [(set f64:$XT, (PPCany_fcfidu f64:$XB))]>;
def XVCVDPSP : XX2Form<60, 393,
(outs vsrc:$XT), (ins vsrc:$XB),
@@ -828,7 +828,7 @@ let hasSideEffects = 0 in {
def XVCVDPSXDS : XX2Form<60, 472,
(outs vsrc:$XT), (ins vsrc:$XB),
"xvcvdpsxds $XT, $XB", IIC_VecFP,
- [(set v2i64:$XT, (any_fp_to_sint v2f64:$XB))]>;
+ [(set v2i64:$XT, (any_fp_to_sint v2f64:$XB))]>;
def XVCVDPSXWS : XX2Form<60, 216,
(outs vsrc:$XT), (ins vsrc:$XB),
"xvcvdpsxws $XT, $XB", IIC_VecFP,
@@ -836,7 +836,7 @@ let hasSideEffects = 0 in {
def XVCVDPUXDS : XX2Form<60, 456,
(outs vsrc:$XT), (ins vsrc:$XB),
"xvcvdpuxds $XT, $XB", IIC_VecFP,
- [(set v2i64:$XT, (any_fp_to_uint v2f64:$XB))]>;
+ [(set v2i64:$XT, (any_fp_to_uint v2f64:$XB))]>;
def XVCVDPUXWS : XX2Form<60, 200,
(outs vsrc:$XT), (ins vsrc:$XB),
"xvcvdpuxws $XT, $XB", IIC_VecFP,
@@ -852,18 +852,18 @@ let hasSideEffects = 0 in {
def XVCVSPSXWS : XX2Form<60, 152,
(outs vsrc:$XT), (ins vsrc:$XB),
"xvcvspsxws $XT, $XB", IIC_VecFP,
- [(set v4i32:$XT, (any_fp_to_sint v4f32:$XB))]>;
+ [(set v4i32:$XT, (any_fp_to_sint v4f32:$XB))]>;
def XVCVSPUXDS : XX2Form<60, 392,
(outs vsrc:$XT), (ins vsrc:$XB),
"xvcvspuxds $XT, $XB", IIC_VecFP, []>;
def XVCVSPUXWS : XX2Form<60, 136,
(outs vsrc:$XT), (ins vsrc:$XB),
"xvcvspuxws $XT, $XB", IIC_VecFP,
- [(set v4i32:$XT, (any_fp_to_uint v4f32:$XB))]>;
+ [(set v4i32:$XT, (any_fp_to_uint v4f32:$XB))]>;
def XVCVSXDDP : XX2Form<60, 504,
(outs vsrc:$XT), (ins vsrc:$XB),
"xvcvsxddp $XT, $XB", IIC_VecFP,
- [(set v2f64:$XT, (any_sint_to_fp v2i64:$XB))]>;
+ [(set v2f64:$XT, (any_sint_to_fp v2i64:$XB))]>;
def XVCVSXDSP : XX2Form<60, 440,
(outs vsrc:$XT), (ins vsrc:$XB),
"xvcvsxdsp $XT, $XB", IIC_VecFP,
@@ -871,82 +871,82 @@ let hasSideEffects = 0 in {
def XVCVSXWSP : XX2Form<60, 184,
(outs vsrc:$XT), (ins vsrc:$XB),
"xvcvsxwsp $XT, $XB", IIC_VecFP,
- [(set v4f32:$XT, (any_sint_to_fp v4i32:$XB))]>;
+ [(set v4f32:$XT, (any_sint_to_fp v4i32:$XB))]>;
def XVCVUXDDP : XX2Form<60, 488,
(outs vsrc:$XT), (ins vsrc:$XB),
"xvcvuxddp $XT, $XB", IIC_VecFP,
- [(set v2f64:$XT, (any_uint_to_fp v2i64:$XB))]>;
+ [(set v2f64:$XT, (any_uint_to_fp v2i64:$XB))]>;
def XVCVUXDSP : XX2Form<60, 424,
(outs vsrc:$XT), (ins vsrc:$XB),
"xvcvuxdsp $XT, $XB", IIC_VecFP,
[(set v4f32:$XT, (int_ppc_vsx_xvcvuxdsp v2i64:$XB))]>;
- def XVCVUXWSP : XX2Form<60, 168,
- (outs vsrc:$XT), (ins vsrc:$XB),
- "xvcvuxwsp $XT, $XB", IIC_VecFP,
- [(set v4f32:$XT, (any_uint_to_fp v4i32:$XB))]>;
-
- let mayRaiseFPException = 0 in {
- def XVCVSXWDP : XX2Form<60, 248,
- (outs vsrc:$XT), (ins vsrc:$XB),
- "xvcvsxwdp $XT, $XB", IIC_VecFP,
- [(set v2f64:$XT, (int_ppc_vsx_xvcvsxwdp v4i32:$XB))]>;
+ def XVCVUXWSP : XX2Form<60, 168,
+ (outs vsrc:$XT), (ins vsrc:$XB),
+ "xvcvuxwsp $XT, $XB", IIC_VecFP,
+ [(set v4f32:$XT, (any_uint_to_fp v4i32:$XB))]>;
+
+ let mayRaiseFPException = 0 in {
+ def XVCVSXWDP : XX2Form<60, 248,
+ (outs vsrc:$XT), (ins vsrc:$XB),
+ "xvcvsxwdp $XT, $XB", IIC_VecFP,
+ [(set v2f64:$XT, (int_ppc_vsx_xvcvsxwdp v4i32:$XB))]>;
def XVCVUXWDP : XX2Form<60, 232,
(outs vsrc:$XT), (ins vsrc:$XB),
"xvcvuxwdp $XT, $XB", IIC_VecFP,
[(set v2f64:$XT, (int_ppc_vsx_xvcvuxwdp v4i32:$XB))]>;
- }
-
- // Rounding Instructions respecting current rounding mode
- def XSRDPIC : XX2Form<60, 107,
- (outs vsfrc:$XT), (ins vsfrc:$XB),
- "xsrdpic $XT, $XB", IIC_VecFP,
- [(set f64:$XT, (fnearbyint f64:$XB))]>;
- def XVRDPIC : XX2Form<60, 235,
+ }
+
+ // Rounding Instructions respecting current rounding mode
+ def XSRDPIC : XX2Form<60, 107,
+ (outs vsfrc:$XT), (ins vsfrc:$XB),
+ "xsrdpic $XT, $XB", IIC_VecFP,
+ [(set f64:$XT, (fnearbyint f64:$XB))]>;
+ def XVRDPIC : XX2Form<60, 235,
(outs vsrc:$XT), (ins vsrc:$XB),
- "xvrdpic $XT, $XB", IIC_VecFP,
- [(set v2f64:$XT, (fnearbyint v2f64:$XB))]>;
- def XVRSPIC : XX2Form<60, 171,
- (outs vsrc:$XT), (ins vsrc:$XB),
- "xvrspic $XT, $XB", IIC_VecFP,
- [(set v4f32:$XT, (fnearbyint v4f32:$XB))]>;
- // Max/Min Instructions
- let isCommutable = 1 in {
- def XSMAXDP : XX3Form<60, 160,
- (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
- "xsmaxdp $XT, $XA, $XB", IIC_VecFP,
- [(set vsfrc:$XT,
- (int_ppc_vsx_xsmaxdp vsfrc:$XA, vsfrc:$XB))]>;
- def XSMINDP : XX3Form<60, 168,
- (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
- "xsmindp $XT, $XA, $XB", IIC_VecFP,
- [(set vsfrc:$XT,
- (int_ppc_vsx_xsmindp vsfrc:$XA, vsfrc:$XB))]>;
-
- def XVMAXDP : XX3Form<60, 224,
- (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
- "xvmaxdp $XT, $XA, $XB", IIC_VecFP,
- [(set vsrc:$XT,
- (int_ppc_vsx_xvmaxdp vsrc:$XA, vsrc:$XB))]>;
- def XVMINDP : XX3Form<60, 232,
- (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
- "xvmindp $XT, $XA, $XB", IIC_VecFP,
- [(set vsrc:$XT,
- (int_ppc_vsx_xvmindp vsrc:$XA, vsrc:$XB))]>;
-
- def XVMAXSP : XX3Form<60, 192,
- (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
- "xvmaxsp $XT, $XA, $XB", IIC_VecFP,
- [(set vsrc:$XT,
- (int_ppc_vsx_xvmaxsp vsrc:$XA, vsrc:$XB))]>;
- def XVMINSP : XX3Form<60, 200,
- (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
- "xvminsp $XT, $XA, $XB", IIC_VecFP,
- [(set vsrc:$XT,
- (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>;
- } // isCommutable
- } // Uses = [RM]
-
- // Rounding Instructions with static direction.
+ "xvrdpic $XT, $XB", IIC_VecFP,
+ [(set v2f64:$XT, (fnearbyint v2f64:$XB))]>;
+ def XVRSPIC : XX2Form<60, 171,
+ (outs vsrc:$XT), (ins vsrc:$XB),
+ "xvrspic $XT, $XB", IIC_VecFP,
+ [(set v4f32:$XT, (fnearbyint v4f32:$XB))]>;
+ // Max/Min Instructions
+ let isCommutable = 1 in {
+ def XSMAXDP : XX3Form<60, 160,
+ (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
+ "xsmaxdp $XT, $XA, $XB", IIC_VecFP,
+ [(set vsfrc:$XT,
+ (int_ppc_vsx_xsmaxdp vsfrc:$XA, vsfrc:$XB))]>;
+ def XSMINDP : XX3Form<60, 168,
+ (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
+ "xsmindp $XT, $XA, $XB", IIC_VecFP,
+ [(set vsfrc:$XT,
+ (int_ppc_vsx_xsmindp vsfrc:$XA, vsfrc:$XB))]>;
+
+ def XVMAXDP : XX3Form<60, 224,
+ (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
+ "xvmaxdp $XT, $XA, $XB", IIC_VecFP,
+ [(set vsrc:$XT,
+ (int_ppc_vsx_xvmaxdp vsrc:$XA, vsrc:$XB))]>;
+ def XVMINDP : XX3Form<60, 232,
+ (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
+ "xvmindp $XT, $XA, $XB", IIC_VecFP,
+ [(set vsrc:$XT,
+ (int_ppc_vsx_xvmindp vsrc:$XA, vsrc:$XB))]>;
+
+ def XVMAXSP : XX3Form<60, 192,
+ (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
+ "xvmaxsp $XT, $XA, $XB", IIC_VecFP,
+ [(set vsrc:$XT,
+ (int_ppc_vsx_xvmaxsp vsrc:$XA, vsrc:$XB))]>;
+ def XVMINSP : XX3Form<60, 200,
+ (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
+ "xvminsp $XT, $XA, $XB", IIC_VecFP,
+ [(set vsrc:$XT,
+ (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>;
+ } // isCommutable
+ } // Uses = [RM]
+
+ // Rounding Instructions with static direction.
def XSRDPI : XX2Form<60, 73,
(outs vsfrc:$XT), (ins vsfrc:$XB),
"xsrdpi $XT, $XB", IIC_VecFP,
@@ -997,7 +997,7 @@ let hasSideEffects = 0 in {
(outs vsrc:$XT), (ins vsrc:$XB),
"xvrspiz $XT, $XB", IIC_VecFP,
[(set v4f32:$XT, (any_ftrunc v4f32:$XB))]>;
- } // mayRaiseFPException
+ } // mayRaiseFPException
// Logical Instructions
let isCommutable = 1 in
@@ -1183,7 +1183,7 @@ let Predicates = [HasVSX, HasP8Vector] in {
"xsresp $XT, $XB", IIC_VecFP,
[(set f32:$XT, (PPCfre f32:$XB))]>;
// FIXME: Setting the hasSideEffects flag here to match current behaviour.
- let hasSideEffects = 1 in
+ let hasSideEffects = 1 in
def XSRSP : XX2Form<60, 281,
(outs vssrc:$XT), (ins vsfrc:$XB),
"xsrsp $XT, $XB", IIC_VecFP,
@@ -1281,12 +1281,12 @@ let Predicates = [HasVSX, HasP8Vector] in {
def XSCVSXDSP : XX2Form<60, 312,
(outs vssrc:$XT), (ins vsfrc:$XB),
"xscvsxdsp $XT, $XB", IIC_VecFP,
- [(set f32:$XT, (PPCany_fcfids f64:$XB))]>;
+ [(set f32:$XT, (PPCany_fcfids f64:$XB))]>;
def XSCVUXDSP : XX2Form<60, 296,
(outs vssrc:$XT), (ins vsfrc:$XB),
"xscvuxdsp $XT, $XB", IIC_VecFP,
- [(set f32:$XT, (PPCany_fcfidus f64:$XB))]>;
- } // mayRaiseFPException
+ [(set f32:$XT, (PPCany_fcfidus f64:$XB))]>;
+ } // mayRaiseFPException
// Conversions between vector and scalar single precision
def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB),
@@ -1459,10 +1459,10 @@ let Predicates = [HasVSX, HasP9Vector] in {
"xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>;
def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>;
- let mayRaiseFPException = 1 in {
- def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>;
- def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>;
-
+ let mayRaiseFPException = 1 in {
+ def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>;
+ def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>;
+
// DP Compare ==, >=, >, !=
// Use vsrc for XT, because the entire register of XT is set.
// XT.dword[1] = 0x0000_0000_0000_0000
@@ -1472,7 +1472,7 @@ let Predicates = [HasVSX, HasP9Vector] in {
IIC_FPCompare, []>;
def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc,
IIC_FPCompare, []>;
- }
+ }
}
//===--------------------------------------------------------------------===//
@@ -1492,7 +1492,7 @@ let Predicates = [HasVSX, HasP9Vector] in {
}
// Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero)
- let mayRaiseFPException = 1 in {
+ let mayRaiseFPException = 1 in {
def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>;
def XSCVQPSWZ : X_VT5_XO5_VB5<63, 9, 836, "xscvqpswz", []>;
def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>;
@@ -1508,12 +1508,12 @@ let Predicates = [HasVSX, HasP9Vector] in {
// vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits,
// but we still use vsfrc for it.
// FIXME: Setting the hasSideEffects flag here to match current behaviour.
- let hasSideEffects = 1, mayRaiseFPException = 1 in {
+ let hasSideEffects = 1, mayRaiseFPException = 1 in {
def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>;
def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>;
}
- let mayRaiseFPException = 1 in {
+ let mayRaiseFPException = 1 in {
// Vector HP -> SP
// FIXME: Setting the hasSideEffects flag here to match current behaviour.
let hasSideEffects = 1 in
@@ -1522,15 +1522,15 @@ let Predicates = [HasVSX, HasP9Vector] in {
[(set v4f32:$XT,
(int_ppc_vsx_xvcvsphp v4f32:$XB))]>;
- // Round to Quad-Precision Integer [with Inexact]
- def XSRQPI : Z23_VT5_R1_VB5_RMC2_EX1<63, 5, 0, "xsrqpi" , []>;
- def XSRQPIX : Z23_VT5_R1_VB5_RMC2_EX1<63, 5, 1, "xsrqpix", []>;
+ // Round to Quad-Precision Integer [with Inexact]
+ def XSRQPI : Z23_VT5_R1_VB5_RMC2_EX1<63, 5, 0, "xsrqpi" , []>;
+ def XSRQPIX : Z23_VT5_R1_VB5_RMC2_EX1<63, 5, 1, "xsrqpix", []>;
// Round Quad-Precision to Double-Extended Precision (fp80)
// FIXME: Setting the hasSideEffects flag here to match current behaviour.
let hasSideEffects = 1 in
def XSRQPXP : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>;
- }
+ }
//===--------------------------------------------------------------------===//
// Insert/Extract Instructions
@@ -1621,7 +1621,7 @@ let Predicates = [HasVSX, HasP9Vector] in {
(int_ppc_vsx_xvtstdcdp v2f64:$XB, timm:$DCMX))]>;
// Maximum/Minimum Type-C/Type-J DP
- let mayRaiseFPException = 1 in {
+ let mayRaiseFPException = 1 in {
def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsfrc, vsfrc, vsfrc,
IIC_VecFP,
[(set f64:$XT, (PPCxsmaxc f64:$XA, f64:$XB))]>;
@@ -1636,7 +1636,7 @@ let Predicates = [HasVSX, HasP9Vector] in {
def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc,
IIC_VecFP, []>;
}
- }
+ }
// Vector Byte-Reverse H/W/D/Q Word
// FIXME: Setting the hasSideEffects flag here to match current behaviour.
@@ -2408,48 +2408,48 @@ def MrgWords {
// arbitrarily chosen to be Big, Little.
//
// Predicate combinations available:
-// [HasVSX, IsLittleEndian, HasP8Altivec] Altivec patterns using VSX instr.
-// [HasVSX, IsBigEndian, HasP8Altivec] Altivec patterns using VSX instr.
+// [HasVSX, IsLittleEndian, HasP8Altivec] Altivec patterns using VSX instr.
+// [HasVSX, IsBigEndian, HasP8Altivec] Altivec patterns using VSX instr.
// [HasVSX]
// [HasVSX, IsBigEndian]
// [HasVSX, IsLittleEndian]
// [HasVSX, NoP9Vector]
-// [HasVSX, NoP9Vector, IsLittleEndian]
+// [HasVSX, NoP9Vector, IsLittleEndian]
// [HasVSX, HasOnlySwappingMemOps]
// [HasVSX, HasOnlySwappingMemOps, IsBigEndian]
// [HasVSX, HasP8Vector]
-// [HasVSX, HasP8Vector, IsBigEndian, IsPPC64]
+// [HasVSX, HasP8Vector, IsBigEndian, IsPPC64]
// [HasVSX, HasP8Vector, IsLittleEndian]
-// [HasVSX, HasP8Vector, NoP9Vector, IsBigEndian, IsPPC64]
+// [HasVSX, HasP8Vector, NoP9Vector, IsBigEndian, IsPPC64]
// [HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian]
// [HasVSX, HasDirectMove]
// [HasVSX, HasDirectMove, IsBigEndian]
// [HasVSX, HasDirectMove, IsLittleEndian]
-// [HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian, IsPPC64]
-// [HasVSX, HasDirectMove, NoP9Vector, IsBigEndian, IsPPC64]
+// [HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian, IsPPC64]
+// [HasVSX, HasDirectMove, NoP9Vector, IsBigEndian, IsPPC64]
// [HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian]
// [HasVSX, HasDirectMove, NoP9Vector, IsLittleEndian]
// [HasVSX, HasP9Vector]
-// [HasVSX, HasP9Vector, IsBigEndian, IsPPC64]
+// [HasVSX, HasP9Vector, IsBigEndian, IsPPC64]
// [HasVSX, HasP9Vector, IsLittleEndian]
// [HasVSX, HasP9Altivec]
-// [HasVSX, HasP9Altivec, IsBigEndian, IsPPC64]
+// [HasVSX, HasP9Altivec, IsBigEndian, IsPPC64]
// [HasVSX, HasP9Altivec, IsLittleEndian]
-// [HasVSX, IsISA3_0, HasDirectMove, IsBigEndian, IsPPC64]
+// [HasVSX, IsISA3_0, HasDirectMove, IsBigEndian, IsPPC64]
// [HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian]
-// These Altivec patterns are here because we need a VSX instruction to match
-// the intrinsic (but only for little endian system).
-let Predicates = [HasVSX, IsLittleEndian, HasP8Altivec] in
- def : Pat<(v16i8 (int_ppc_altivec_crypto_vpermxor v16i8:$a,
- v16i8:$b, v16i8:$c)),
- (v16i8 (VPERMXOR $a, $b, (XXLNOR (COPY_TO_REGCLASS $c, VSRC),
- (COPY_TO_REGCLASS $c, VSRC))))>;
-let Predicates = [HasVSX, IsBigEndian, HasP8Altivec] in
- def : Pat<(v16i8 (int_ppc_altivec_crypto_vpermxor v16i8:$a,
- v16i8:$b, v16i8:$c)),
- (v16i8 (VPERMXOR $a, $b, $c))>;
-
+// These Altivec patterns are here because we need a VSX instruction to match
+// the intrinsic (but only for little endian system).
+let Predicates = [HasVSX, IsLittleEndian, HasP8Altivec] in
+ def : Pat<(v16i8 (int_ppc_altivec_crypto_vpermxor v16i8:$a,
+ v16i8:$b, v16i8:$c)),
+ (v16i8 (VPERMXOR $a, $b, (XXLNOR (COPY_TO_REGCLASS $c, VSRC),
+ (COPY_TO_REGCLASS $c, VSRC))))>;
+let Predicates = [HasVSX, IsBigEndian, HasP8Altivec] in
+ def : Pat<(v16i8 (int_ppc_altivec_crypto_vpermxor v16i8:$a,
+ v16i8:$b, v16i8:$c)),
+ (v16i8 (VPERMXOR $a, $b, $c))>;
+
let AddedComplexity = 400 in {
// Valid for any VSX subtarget, regardless of endianness.
let Predicates = [HasVSX] in {
@@ -2481,10 +2481,10 @@ def : Pat<(fneg (PPCfnmsub v4f32:$A, v4f32:$B, v4f32:$C)),
def : Pat<(PPCfnmsub v4f32:$A, v4f32:$B, (fneg v4f32:$C)),
(XVNMADDASP $C, $A, $B)>;
-def : Pat<(PPCfsqrt f64:$frA), (XSSQRTDP $frA)>;
-def : Pat<(PPCfsqrt v2f64:$frA), (XVSQRTDP $frA)>;
-def : Pat<(PPCfsqrt v4f32:$frA), (XVSQRTSP $frA)>;
-
+def : Pat<(PPCfsqrt f64:$frA), (XSSQRTDP $frA)>;
+def : Pat<(PPCfsqrt v2f64:$frA), (XVSQRTDP $frA)>;
+def : Pat<(PPCfsqrt v4f32:$frA), (XVSQRTSP $frA)>;
+
def : Pat<(v2f64 (bitconvert v4f32:$A)),
(COPY_TO_REGCLASS $A, VSRC)>;
def : Pat<(v2f64 (bitconvert v4i32:$A)),
@@ -2614,16 +2614,16 @@ def : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B),
def : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B),
(XVDIVDP $A, $B)>;
-// Vector test for software divide and sqrt.
-def : Pat<(i32 (int_ppc_vsx_xvtdivdp v2f64:$A, v2f64:$B)),
- (COPY_TO_REGCLASS (XVTDIVDP $A, $B), GPRC)>;
-def : Pat<(i32 (int_ppc_vsx_xvtdivsp v4f32:$A, v4f32:$B)),
- (COPY_TO_REGCLASS (XVTDIVSP $A, $B), GPRC)>;
-def : Pat<(i32 (int_ppc_vsx_xvtsqrtdp v2f64:$A)),
- (COPY_TO_REGCLASS (XVTSQRTDP $A), GPRC)>;
-def : Pat<(i32 (int_ppc_vsx_xvtsqrtsp v4f32:$A)),
- (COPY_TO_REGCLASS (XVTSQRTSP $A), GPRC)>;
-
+// Vector test for software divide and sqrt.
+def : Pat<(i32 (int_ppc_vsx_xvtdivdp v2f64:$A, v2f64:$B)),
+ (COPY_TO_REGCLASS (XVTDIVDP $A, $B), GPRC)>;
+def : Pat<(i32 (int_ppc_vsx_xvtdivsp v4f32:$A, v4f32:$B)),
+ (COPY_TO_REGCLASS (XVTDIVSP $A, $B), GPRC)>;
+def : Pat<(i32 (int_ppc_vsx_xvtsqrtdp v2f64:$A)),
+ (COPY_TO_REGCLASS (XVTSQRTDP $A), GPRC)>;
+def : Pat<(i32 (int_ppc_vsx_xvtsqrtsp v4f32:$A)),
+ (COPY_TO_REGCLASS (XVTSQRTSP $A), GPRC)>;
+
// Reciprocal estimate
def : Pat<(int_ppc_vsx_xvresp v4f32:$A),
(XVRESP $A)>;
@@ -2724,7 +2724,7 @@ def : Pat<(v2f64 (int_ppc_vsx_lxvd2x_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
def : Pat<(f32 (any_fround f32:$S)),
(f32 (COPY_TO_REGCLASS (XSRDPI
(COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
-def : Pat<(f32 (fnearbyint f32:$S)),
+def : Pat<(f32 (fnearbyint f32:$S)),
(f32 (COPY_TO_REGCLASS (XSRDPIC
(COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
def : Pat<(f32 (any_ffloor f32:$S)),
@@ -2739,11 +2739,11 @@ def : Pat<(f32 (any_ftrunc f32:$S)),
def : Pat<(f32 (any_frint f32:$S)),
(f32 (COPY_TO_REGCLASS (XSRDPIC
(COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
-def : Pat<(v4f32 (any_frint v4f32:$S)), (v4f32 (XVRSPIC $S))>;
+def : Pat<(v4f32 (any_frint v4f32:$S)), (v4f32 (XVRSPIC $S))>;
// Rounding for double precision.
-def : Pat<(f64 (any_frint f64:$S)), (f64 (XSRDPIC $S))>;
-def : Pat<(v2f64 (any_frint v2f64:$S)), (v2f64 (XVRDPIC $S))>;
+def : Pat<(f64 (any_frint f64:$S)), (f64 (XSRDPIC $S))>;
+def : Pat<(v2f64 (any_frint v2f64:$S)), (v2f64 (XVRDPIC $S))>;
// Materialize a zero-vector of long long
def : Pat<(v2i64 immAllZerosV),
@@ -3020,19 +3020,19 @@ defm : ScalToVecWPermute<
VSFRC)), sub_64)>;
} // HasVSX, NoP9Vector
-// Any little endian pre-Power9 VSX subtarget.
-let Predicates = [HasVSX, NoP9Vector, IsLittleEndian] in {
-// Load-and-splat using only X-Form VSX loads.
-defm : ScalToVecWPermute<
- v2i64, (i64 (load xoaddr:$src)),
- (XXPERMDIs (XFLOADf64 xoaddr:$src), 2),
- (SUBREG_TO_REG (i64 1), (XFLOADf64 xoaddr:$src), sub_64)>;
-defm : ScalToVecWPermute<
- v2f64, (f64 (load xoaddr:$src)),
- (XXPERMDIs (XFLOADf64 xoaddr:$src), 2),
- (SUBREG_TO_REG (i64 1), (XFLOADf64 xoaddr:$src), sub_64)>;
-} // HasVSX, NoP9Vector, IsLittleEndian
-
+// Any little endian pre-Power9 VSX subtarget.
+let Predicates = [HasVSX, NoP9Vector, IsLittleEndian] in {
+// Load-and-splat using only X-Form VSX loads.
+defm : ScalToVecWPermute<
+ v2i64, (i64 (load xoaddr:$src)),
+ (XXPERMDIs (XFLOADf64 xoaddr:$src), 2),
+ (SUBREG_TO_REG (i64 1), (XFLOADf64 xoaddr:$src), sub_64)>;
+defm : ScalToVecWPermute<
+ v2f64, (f64 (load xoaddr:$src)),
+ (XXPERMDIs (XFLOADf64 xoaddr:$src), 2),
+ (SUBREG_TO_REG (i64 1), (XFLOADf64 xoaddr:$src), sub_64)>;
+} // HasVSX, NoP9Vector, IsLittleEndian
+
// Any VSX subtarget that only has loads and stores that load in big endian
// order regardless of endianness. This is really pre-Power9 subtargets.
let Predicates = [HasVSX, HasOnlySwappingMemOps] in {
@@ -3044,8 +3044,8 @@ let Predicates = [HasVSX, HasOnlySwappingMemOps] in {
def : Pat<(PPCstxvd2x v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
} // HasVSX, HasOnlySwappingMemOps
-// Big endian VSX subtarget that only has loads and stores that always
-// load in big endian order. Really big endian pre-Power9 subtargets.
+// Big endian VSX subtarget that only has loads and stores that always
+// load in big endian order. Really big endian pre-Power9 subtargets.
let Predicates = [HasVSX, HasOnlySwappingMemOps, IsBigEndian] in {
def : Pat<(v2f64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
def : Pat<(v2i64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
@@ -3138,7 +3138,7 @@ def : Pat<(v16i8 (bitconvert (v16i8 immAllOnesV))),
} // HasVSX, HasP8Vector
// Big endian Power8 VSX subtarget.
-let Predicates = [HasVSX, HasP8Vector, IsBigEndian, IsPPC64] in {
+let Predicates = [HasVSX, HasP8Vector, IsBigEndian, IsPPC64] in {
def : Pat<DWToSPExtractConv.El0SS1,
(f32 (XSCVSXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>;
def : Pat<DWToSPExtractConv.El1SS1,
@@ -3216,7 +3216,7 @@ foreach Idx = [ [0,3], [2,1], [3,2] ] in {
(STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
sub_64), xoaddr:$src)>;
}
-} // HasVSX, HasP8Vector, IsBigEndian, IsPPC64
+} // HasVSX, HasP8Vector, IsBigEndian, IsPPC64
// Little endian Power8 VSX subtarget.
let Predicates = [HasVSX, HasP8Vector, IsLittleEndian] in {
@@ -3315,7 +3315,7 @@ foreach Idx = [ [0,2], [1,1], [3,3] ] in {
} // HasVSX, HasP8Vector, IsLittleEndian
// Big endian pre-Power9 VSX subtarget.
-let Predicates = [HasVSX, HasP8Vector, NoP9Vector, IsBigEndian, IsPPC64] in {
+let Predicates = [HasVSX, HasP8Vector, NoP9Vector, IsBigEndian, IsPPC64] in {
def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xoaddr:$src),
(XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xoaddr:$src),
@@ -3326,7 +3326,7 @@ def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xoaddr:$src),
def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xoaddr:$src),
(XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
xoaddr:$src)>;
-} // HasVSX, HasP8Vector, NoP9Vector, IsBigEndian, IsPPC64
+} // HasVSX, HasP8Vector, NoP9Vector, IsBigEndian, IsPPC64
// Little endian pre-Power9 VSX subtarget.
let Predicates = [HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian] in {
@@ -3583,8 +3583,8 @@ def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
(i32 VectorExtractions.LE_VARIABLE_WORD)>;
} // HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian
-// Big endian pre-Power9 64Bit VSX subtarget that has direct moves.
-let Predicates = [HasVSX, HasDirectMove, NoP9Vector, IsBigEndian, IsPPC64] in {
+// Big endian pre-Power9 64Bit VSX subtarget that has direct moves.
+let Predicates = [HasVSX, HasDirectMove, NoP9Vector, IsBigEndian, IsPPC64] in {
// Big endian integer vectors using direct moves.
def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
(v2i64 (XXPERMDI
@@ -3598,7 +3598,7 @@ def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
(MTVSRD (RLDIMI AnyExts.D, AnyExts.C, 32, 0)), VSRC), 0)>;
def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
(XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
-} // HasVSX, HasDirectMove, NoP9Vector, IsBigEndian, IsPPC64
+} // HasVSX, HasDirectMove, NoP9Vector, IsBigEndian, IsPPC64
// Little endian pre-Power9 VSX subtarget that has direct moves.
let Predicates = [HasVSX, HasDirectMove, NoP9Vector, IsLittleEndian] in {
@@ -3627,25 +3627,25 @@ def : Pat<(fneg (PPCfnmsub f128:$A, f128:$B, f128:$C)),
def : Pat<(PPCfnmsub f128:$A, f128:$B, (fneg f128:$C)),
(XSNMADDQP $C, $A, $B)>;
-def : Pat<(f128 (any_sint_to_fp i64:$src)),
+def : Pat<(f128 (any_sint_to_fp i64:$src)),
(f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
-def : Pat<(f128 (any_sint_to_fp (i64 (PPCmfvsr f64:$src)))),
+def : Pat<(f128 (any_sint_to_fp (i64 (PPCmfvsr f64:$src)))),
(f128 (XSCVSDQP $src))>;
-def : Pat<(f128 (any_sint_to_fp (i32 (PPCmfvsr f64:$src)))),
+def : Pat<(f128 (any_sint_to_fp (i32 (PPCmfvsr f64:$src)))),
(f128 (XSCVSDQP (VEXTSW2Ds $src)))>;
-def : Pat<(f128 (any_uint_to_fp i64:$src)),
+def : Pat<(f128 (any_uint_to_fp i64:$src)),
(f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
-def : Pat<(f128 (any_uint_to_fp (i64 (PPCmfvsr f64:$src)))),
+def : Pat<(f128 (any_uint_to_fp (i64 (PPCmfvsr f64:$src)))),
(f128 (XSCVUDQP $src))>;
// Convert (Un)Signed Word -> QP.
-def : Pat<(f128 (any_sint_to_fp i32:$src)),
+def : Pat<(f128 (any_sint_to_fp i32:$src)),
(f128 (XSCVSDQP (MTVSRWA $src)))>;
-def : Pat<(f128 (any_sint_to_fp (i32 (load xoaddr:$src)))),
+def : Pat<(f128 (any_sint_to_fp (i32 (load xoaddr:$src)))),
(f128 (XSCVSDQP (LIWAX xoaddr:$src)))>;
-def : Pat<(f128 (any_uint_to_fp i32:$src)),
+def : Pat<(f128 (any_uint_to_fp i32:$src)),
(f128 (XSCVUDQP (MTVSRWZ $src)))>;
-def : Pat<(f128 (any_uint_to_fp (i32 (load xoaddr:$src)))),
+def : Pat<(f128 (any_uint_to_fp (i32 (load xoaddr:$src)))),
(f128 (XSCVUDQP (LIWZX xoaddr:$src)))>;
// Pattern for matching Vector HP -> Vector SP intrinsic. Defined as a
@@ -3819,11 +3819,11 @@ def : Pat<(f128 (uint_to_fp ScalarLoads.ZELi8)),
(f128 (XSCVUDQP (LXSIBZX xoaddr:$src)))>;
// Truncate & Convert QP -> (Un)Signed (D)Word.
-def : Pat<(i64 (any_fp_to_sint f128:$src)), (i64 (MFVRD (XSCVQPSDZ $src)))>;
-def : Pat<(i64 (any_fp_to_uint f128:$src)), (i64 (MFVRD (XSCVQPUDZ $src)))>;
-def : Pat<(i32 (any_fp_to_sint f128:$src)),
+def : Pat<(i64 (any_fp_to_sint f128:$src)), (i64 (MFVRD (XSCVQPSDZ $src)))>;
+def : Pat<(i64 (any_fp_to_uint f128:$src)), (i64 (MFVRD (XSCVQPUDZ $src)))>;
+def : Pat<(i32 (any_fp_to_sint f128:$src)),
(i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC)))>;
-def : Pat<(i32 (any_fp_to_uint f128:$src)),
+def : Pat<(i32 (any_fp_to_uint f128:$src)),
(i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC)))>;
// Instructions for store(fptosi).
@@ -3951,8 +3951,8 @@ def : Pat<(v4i32 (PPCldsplat xoaddr:$A)),
(v4i32 (LXVWSX xoaddr:$A))>;
} // HasVSX, HasP9Vector
-// Big endian 64Bit Power9 subtarget.
-let Predicates = [HasVSX, HasP9Vector, IsBigEndian, IsPPC64] in {
+// Big endian 64Bit Power9 subtarget.
+let Predicates = [HasVSX, HasP9Vector, IsBigEndian, IsPPC64] in {
def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
(f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
@@ -4125,7 +4125,7 @@ foreach Idx = 0-15 in {
def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
(f128 (XSCVUDQP
(XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 4)))>;
-} // HasVSX, HasP9Vector, IsBigEndian, IsPPC64
+} // HasVSX, HasP9Vector, IsBigEndian, IsPPC64
// Little endian Power9 subtarget.
let Predicates = [HasVSX, HasP9Vector, IsLittleEndian] in {
@@ -4350,8 +4350,8 @@ def : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 1))),
(v4i32 (VABSDUW (XVNEGSP $A), (XVNEGSP $B)))>;
} // HasVSX, HasP9Altivec
-// Big endian Power9 64Bit VSX subtargets with P9 Altivec support.
-let Predicates = [HasVSX, HasP9Altivec, IsBigEndian, IsPPC64] in {
+// Big endian Power9 64Bit VSX subtargets with P9 Altivec support.
+let Predicates = [HasVSX, HasP9Altivec, IsBigEndian, IsPPC64] in {
def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
(VEXTUBLX $Idx, $S)>;
@@ -4484,7 +4484,7 @@ def : Pat<(v4i32 (build_vector ByteToWord.BE_A0, ByteToWord.BE_A1,
(v4i32 (VEXTSB2W $A))>;
def : Pat<(v2i64 (build_vector ByteToDWord.BE_A0, ByteToDWord.BE_A1)),
(v2i64 (VEXTSB2D $A))>;
-} // HasVSX, HasP9Altivec, IsBigEndian, IsPPC64
+} // HasVSX, HasP9Altivec, IsBigEndian, IsPPC64
// Little endian Power9 VSX subtargets with P9 Altivec support.
let Predicates = [HasVSX, HasP9Altivec, IsLittleEndian] in {
@@ -4621,9 +4621,9 @@ def : Pat<(v2i64 (build_vector ByteToDWord.LE_A0, ByteToDWord.LE_A1)),
(v2i64 (VEXTSB2D $A))>;
} // HasVSX, HasP9Altivec, IsLittleEndian
-// Big endian 64Bit VSX subtarget that supports additional direct moves from
-// ISA3.0.
-let Predicates = [HasVSX, IsISA3_0, HasDirectMove, IsBigEndian, IsPPC64] in {
+// Big endian 64Bit VSX subtarget that supports additional direct moves from
+// ISA3.0.
+let Predicates = [HasVSX, IsISA3_0, HasDirectMove, IsBigEndian, IsPPC64] in {
def : Pat<(i64 (extractelt v2i64:$A, 1)),
(i64 (MFVSRLD $A))>;
// Better way to build integer vectors if we have MTVSRDD. Big endian.
@@ -4636,7 +4636,7 @@ def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
def : Pat<(f128 (PPCbuild_fp128 i64:$rB, i64:$rA)),
(f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
-} // HasVSX, IsISA3_0, HasDirectMove, IsBigEndian, IsPPC64
+} // HasVSX, IsISA3_0, HasDirectMove, IsBigEndian, IsPPC64
// Little endian VSX subtarget that supports direct moves from ISA3.0.
let Predicates = [HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian] in {
@@ -4661,18 +4661,18 @@ def : InstAlias<"xvmovdp $XT, $XB",
def : InstAlias<"xvmovsp $XT, $XB",
(XVCPSGNSP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
-// Certain versions of the AIX assembler may missassemble these mnemonics.
-let Predicates = [ModernAs] in {
- def : InstAlias<"xxspltd $XT, $XB, 0",
- (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 0)>;
- def : InstAlias<"xxspltd $XT, $XB, 1",
- (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 3)>;
- def : InstAlias<"xxspltd $XT, $XB, 0",
- (XXPERMDIs vsrc:$XT, vsfrc:$XB, 0)>;
- def : InstAlias<"xxspltd $XT, $XB, 1",
- (XXPERMDIs vsrc:$XT, vsfrc:$XB, 3)>;
-}
-
+// Certain versions of the AIX assembler may missassemble these mnemonics.
+let Predicates = [ModernAs] in {
+ def : InstAlias<"xxspltd $XT, $XB, 0",
+ (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 0)>;
+ def : InstAlias<"xxspltd $XT, $XB, 1",
+ (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 3)>;
+ def : InstAlias<"xxspltd $XT, $XB, 0",
+ (XXPERMDIs vsrc:$XT, vsfrc:$XB, 0)>;
+ def : InstAlias<"xxspltd $XT, $XB, 1",
+ (XXPERMDIs vsrc:$XT, vsfrc:$XB, 3)>;
+}
+
def : InstAlias<"xxmrghd $XT, $XA, $XB",
(XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 0)>;
def : InstAlias<"xxmrgld $XT, $XA, $XB",
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp
index d84d9a65ce..c242409097 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp
@@ -60,7 +60,7 @@
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/IntrinsicsPowerPC.h"
+#include "llvm/IR/IntrinsicsPowerPC.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
@@ -82,7 +82,7 @@
using namespace llvm;
static cl::opt<unsigned> MaxVarsPrep("ppc-formprep-max-vars",
- cl::Hidden, cl::init(24),
+ cl::Hidden, cl::init(24),
cl::desc("Potential common base number threshold per function for PPC loop "
"prep"));
@@ -92,7 +92,7 @@ static cl::opt<bool> PreferUpdateForm("ppc-formprep-prefer-update",
// Sum of following 3 per loop thresholds for all loops can not be larger
// than MaxVarsPrep.
-// now the thresholds for each kind prep are exterimental values on Power9.
+// now the thresholds for each kind prep are exterimental values on Power9.
static cl::opt<unsigned> MaxVarsUpdateForm("ppc-preinc-prep-max-vars",
cl::Hidden, cl::init(3),
cl::desc("Potential PHI threshold per loop for PPC loop prep of update "
@@ -103,7 +103,7 @@ static cl::opt<unsigned> MaxVarsDSForm("ppc-dsprep-max-vars",
cl::desc("Potential PHI threshold per loop for PPC loop prep of DS form"));
static cl::opt<unsigned> MaxVarsDQForm("ppc-dqprep-max-vars",
- cl::Hidden, cl::init(8),
+ cl::Hidden, cl::init(8),
cl::desc("Potential PHI threshold per loop for PPC loop prep of DQ form"));
@@ -275,11 +275,11 @@ static Value *GetPointerOperand(Value *MemI) {
} else if (StoreInst *SMemI = dyn_cast<StoreInst>(MemI)) {
return SMemI->getPointerOperand();
} else if (IntrinsicInst *IMemI = dyn_cast<IntrinsicInst>(MemI)) {
- if (IMemI->getIntrinsicID() == Intrinsic::prefetch ||
- IMemI->getIntrinsicID() == Intrinsic::ppc_vsx_lxvp)
+ if (IMemI->getIntrinsicID() == Intrinsic::prefetch ||
+ IMemI->getIntrinsicID() == Intrinsic::ppc_vsx_lxvp)
return IMemI->getArgOperand(0);
- if (IMemI->getIntrinsicID() == Intrinsic::ppc_vsx_stxvp)
- return IMemI->getArgOperand(1);
+ if (IMemI->getIntrinsicID() == Intrinsic::ppc_vsx_stxvp)
+ return IMemI->getArgOperand(1);
}
return nullptr;
@@ -346,13 +346,13 @@ SmallVector<Bucket, 16> PPCLoopInstrFormPrep::collectCandidates(
MemI = SMemI;
PtrValue = SMemI->getPointerOperand();
} else if (IntrinsicInst *IMemI = dyn_cast<IntrinsicInst>(&J)) {
- if (IMemI->getIntrinsicID() == Intrinsic::prefetch ||
- IMemI->getIntrinsicID() == Intrinsic::ppc_vsx_lxvp) {
+ if (IMemI->getIntrinsicID() == Intrinsic::prefetch ||
+ IMemI->getIntrinsicID() == Intrinsic::ppc_vsx_lxvp) {
MemI = IMemI;
PtrValue = IMemI->getArgOperand(0);
- } else if (IMemI->getIntrinsicID() == Intrinsic::ppc_vsx_stxvp) {
- MemI = IMemI;
- PtrValue = IMemI->getArgOperand(1);
+ } else if (IMemI->getIntrinsicID() == Intrinsic::ppc_vsx_stxvp) {
+ MemI = IMemI;
+ PtrValue = IMemI->getArgOperand(1);
} else continue;
} else continue;
@@ -611,10 +611,10 @@ bool PPCLoopInstrFormPrep::rewriteLoadStores(Loop *L, Bucket &BucketChain,
NewBasePtr = NewPHI;
}
- // Clear the rewriter cache, because values that are in the rewriter's cache
- // can be deleted below, causing the AssertingVH in the cache to trigger.
- SCEVE.clear();
-
+ // Clear the rewriter cache, because values that are in the rewriter's cache
+ // can be deleted below, causing the AssertingVH in the cache to trigger.
+ SCEVE.clear();
+
if (Instruction *IDel = dyn_cast<Instruction>(BasePtr))
BBChanged.insert(IDel->getParent());
BasePtr->replaceAllUsesWith(NewBasePtr);
@@ -800,7 +800,7 @@ bool PPCLoopInstrFormPrep::runOnLoop(Loop *L) {
bool MadeChange = false;
// Only prep. the inner-most loop
- if (!L->isInnermost())
+ if (!L->isInnermost())
return MadeChange;
// Return if already done enough preparation.
@@ -832,11 +832,11 @@ bool PPCLoopInstrFormPrep::runOnLoop(Loop *L) {
if (ST && ST->hasAltivec() &&
PtrValue->getType()->getPointerElementType()->isVectorTy())
return false;
- // There are no update forms for P10 lxvp/stxvp intrinsic.
- auto *II = dyn_cast<IntrinsicInst>(I);
- if (II && ((II->getIntrinsicID() == Intrinsic::ppc_vsx_lxvp) ||
- II->getIntrinsicID() == Intrinsic::ppc_vsx_stxvp))
- return false;
+ // There are no update forms for P10 lxvp/stxvp intrinsic.
+ auto *II = dyn_cast<IntrinsicInst>(I);
+ if (II && ((II->getIntrinsicID() == Intrinsic::ppc_vsx_lxvp) ||
+ II->getIntrinsicID() == Intrinsic::ppc_vsx_stxvp))
+ return false;
// See getPreIndexedAddressParts, the displacement for LDU/STDU has to
// be 4's multiple (DS-form). For i64 loads/stores when the displacement
// fits in a 16-bit signed field but isn't a multiple of 4, it will be
@@ -874,13 +874,13 @@ bool PPCLoopInstrFormPrep::runOnLoop(Loop *L) {
// Check if a load/store has DQ form.
auto isDQFormCandidate = [&] (const Instruction *I, const Value *PtrValue) {
assert((PtrValue && I) && "Invalid parameter!");
- // Check if it is a P10 lxvp/stxvp intrinsic.
- auto *II = dyn_cast<IntrinsicInst>(I);
- if (II)
- return II->getIntrinsicID() == Intrinsic::ppc_vsx_lxvp ||
- II->getIntrinsicID() == Intrinsic::ppc_vsx_stxvp;
- // Check if it is a P9 vector load/store.
- return ST && ST->hasP9Vector() &&
+ // Check if it is a P10 lxvp/stxvp intrinsic.
+ auto *II = dyn_cast<IntrinsicInst>(I);
+ if (II)
+ return II->getIntrinsicID() == Intrinsic::ppc_vsx_lxvp ||
+ II->getIntrinsicID() == Intrinsic::ppc_vsx_stxvp;
+ // Check if it is a P9 vector load/store.
+ return ST && ST->hasP9Vector() &&
(PtrValue->getType()->getPointerElementType()->isVectorTy());
};
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCLowerMASSVEntries.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCLowerMASSVEntries.cpp
index c2d81f9dfa..27b2c9a628 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCLowerMASSVEntries.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCLowerMASSVEntries.cpp
@@ -16,7 +16,7 @@
#include "PPC.h"
#include "PPCSubtarget.h"
#include "PPCTargetMachine.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/Instructions.h"
@@ -65,7 +65,7 @@ private:
/// Checks if the specified function name represents an entry in the MASSV
/// library.
bool PPCLowerMASSVEntries::isMASSVFunc(StringRef Name) {
- return llvm::is_contained(MASSVFuncs, Name);
+ return llvm::is_contained(MASSVFuncs, Name);
}
// FIXME:
@@ -105,7 +105,7 @@ bool PPCLowerMASSVEntries::handlePowSpecialCases(CallInst *CI, Function &Func,
return false;
if (Constant *Exp = dyn_cast<Constant>(CI->getArgOperand(1)))
- if (ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(Exp->getSplatValue())) {
+ if (ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(Exp->getSplatValue())) {
// If the argument is 0.75 or 0.25 it is cheaper to turn it into pow
// intrinsic so that it could be optimzed as sequence of sqrt's.
if (!CI->hasNoInfs() || !CI->hasApproxFunc())
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCMCInstLower.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCMCInstLower.cpp
index 150814474e..5cc180d770 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCMCInstLower.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCMCInstLower.cpp
@@ -74,9 +74,9 @@ static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
RefKind = MCSymbolRefExpr::VK_PPC_TOC_LO;
break;
case PPCII::MO_TLS:
- bool IsPCRel = (MO.getTargetFlags() & ~access) == PPCII::MO_PCREL_FLAG;
- RefKind = IsPCRel ? MCSymbolRefExpr::VK_PPC_TLS_PCREL
- : MCSymbolRefExpr::VK_PPC_TLS;
+ bool IsPCRel = (MO.getTargetFlags() & ~access) == PPCII::MO_PCREL_FLAG;
+ RefKind = IsPCRel ? MCSymbolRefExpr::VK_PPC_TLS_PCREL
+ : MCSymbolRefExpr::VK_PPC_TLS;
break;
}
@@ -86,14 +86,14 @@ static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
RefKind = MCSymbolRefExpr::VK_PCREL;
else if (MO.getTargetFlags() == (PPCII::MO_PCREL_FLAG | PPCII::MO_GOT_FLAG))
RefKind = MCSymbolRefExpr::VK_PPC_GOT_PCREL;
- else if (MO.getTargetFlags() == (PPCII::MO_PCREL_FLAG | PPCII::MO_TPREL_FLAG))
- RefKind = MCSymbolRefExpr::VK_TPREL;
- else if (MO.getTargetFlags() == PPCII::MO_GOT_TLSGD_PCREL_FLAG)
- RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL;
- else if (MO.getTargetFlags() == PPCII::MO_GOT_TLSLD_PCREL_FLAG)
- RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL;
- else if (MO.getTargetFlags() == PPCII::MO_GOT_TPREL_PCREL_FLAG)
- RefKind = MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL;
+ else if (MO.getTargetFlags() == (PPCII::MO_PCREL_FLAG | PPCII::MO_TPREL_FLAG))
+ RefKind = MCSymbolRefExpr::VK_TPREL;
+ else if (MO.getTargetFlags() == PPCII::MO_GOT_TLSGD_PCREL_FLAG)
+ RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL;
+ else if (MO.getTargetFlags() == PPCII::MO_GOT_TLSLD_PCREL_FLAG)
+ RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL;
+ else if (MO.getTargetFlags() == PPCII::MO_GOT_TPREL_PCREL_FLAG)
+ RefKind = MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL;
const MachineInstr *MI = MO.getParent();
const MachineFunction *MF = MI->getMF();
@@ -110,8 +110,8 @@ static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
MIOpcode == PPC::BL8_NOTOC) {
RefKind = MCSymbolRefExpr::VK_PPC_NOTOC;
}
- if (MO.getTargetFlags() == PPCII::MO_PCREL_OPT_FLAG)
- RefKind = MCSymbolRefExpr::VK_PPC_PCREL_OPT;
+ if (MO.getTargetFlags() == PPCII::MO_PCREL_OPT_FLAG)
+ RefKind = MCSymbolRefExpr::VK_PPC_PCREL_OPT;
}
const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, RefKind, Ctx);
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCMIPeephole.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCMIPeephole.cpp
index f2d1f35067..c8b01aaef8 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCMIPeephole.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCMIPeephole.cpp
@@ -267,113 +267,113 @@ void PPCMIPeephole::UpdateTOCSaves(
TOCSaves[MI] = Keep;
}
-// This function returns a list of all PHI nodes in the tree starting from
-// the RootPHI node. We perform a BFS traversal to get an ordered list of nodes.
-// The list initially only contains the root PHI. When we visit a PHI node, we
-// add it to the list. We continue to look for other PHI node operands while
-// there are nodes to visit in the list. The function returns false if the
-// optimization cannot be applied on this tree.
-static bool collectUnprimedAccPHIs(MachineRegisterInfo *MRI,
- MachineInstr *RootPHI,
- SmallVectorImpl<MachineInstr *> &PHIs) {
- PHIs.push_back(RootPHI);
- unsigned VisitedIndex = 0;
- while (VisitedIndex < PHIs.size()) {
- MachineInstr *VisitedPHI = PHIs[VisitedIndex];
- for (unsigned PHIOp = 1, NumOps = VisitedPHI->getNumOperands();
- PHIOp != NumOps; PHIOp += 2) {
- Register RegOp = VisitedPHI->getOperand(PHIOp).getReg();
- if (!Register::isVirtualRegister(RegOp))
- return false;
- MachineInstr *Instr = MRI->getVRegDef(RegOp);
- // While collecting the PHI nodes, we check if they can be converted (i.e.
- // all the operands are either copies, implicit defs or PHI nodes).
- unsigned Opcode = Instr->getOpcode();
- if (Opcode == PPC::COPY) {
- Register Reg = Instr->getOperand(1).getReg();
- if (!Register::isVirtualRegister(Reg) ||
- MRI->getRegClass(Reg) != &PPC::ACCRCRegClass)
- return false;
- } else if (Opcode != PPC::IMPLICIT_DEF && Opcode != PPC::PHI)
- return false;
- // If we detect a cycle in the PHI nodes, we exit. It would be
- // possible to change cycles as well, but that would add a lot
- // of complexity for a case that is unlikely to occur with MMA
- // code.
- if (Opcode != PPC::PHI)
- continue;
- if (llvm::is_contained(PHIs, Instr))
- return false;
- PHIs.push_back(Instr);
- }
- VisitedIndex++;
- }
- return true;
-}
-
-// This function changes the unprimed accumulator PHI nodes in the PHIs list to
-// primed accumulator PHI nodes. The list is traversed in reverse order to
-// change all the PHI operands of a PHI node before changing the node itself.
-// We keep a map to associate each changed PHI node to its non-changed form.
-static void convertUnprimedAccPHIs(const PPCInstrInfo *TII,
- MachineRegisterInfo *MRI,
- SmallVectorImpl<MachineInstr *> &PHIs,
- Register Dst) {
- DenseMap<MachineInstr *, MachineInstr *> ChangedPHIMap;
- for (auto It = PHIs.rbegin(), End = PHIs.rend(); It != End; ++It) {
- MachineInstr *PHI = *It;
- SmallVector<std::pair<MachineOperand, MachineOperand>, 4> PHIOps;
- // We check if the current PHI node can be changed by looking at its
- // operands. If all the operands are either copies from primed
- // accumulators, implicit definitions or other unprimed accumulator
- // PHI nodes, we change it.
- for (unsigned PHIOp = 1, NumOps = PHI->getNumOperands(); PHIOp != NumOps;
- PHIOp += 2) {
- Register RegOp = PHI->getOperand(PHIOp).getReg();
- MachineInstr *PHIInput = MRI->getVRegDef(RegOp);
- unsigned Opcode = PHIInput->getOpcode();
- assert((Opcode == PPC::COPY || Opcode == PPC::IMPLICIT_DEF ||
- Opcode == PPC::PHI) &&
- "Unexpected instruction");
- if (Opcode == PPC::COPY) {
- assert(MRI->getRegClass(PHIInput->getOperand(1).getReg()) ==
- &PPC::ACCRCRegClass &&
- "Unexpected register class");
- PHIOps.push_back({PHIInput->getOperand(1), PHI->getOperand(PHIOp + 1)});
- } else if (Opcode == PPC::IMPLICIT_DEF) {
- Register AccReg = MRI->createVirtualRegister(&PPC::ACCRCRegClass);
- BuildMI(*PHIInput->getParent(), PHIInput, PHIInput->getDebugLoc(),
- TII->get(PPC::IMPLICIT_DEF), AccReg);
- PHIOps.push_back({MachineOperand::CreateReg(AccReg, false),
- PHI->getOperand(PHIOp + 1)});
- } else if (Opcode == PPC::PHI) {
- // We found a PHI operand. At this point we know this operand
- // has already been changed so we get its associated changed form
- // from the map.
- assert(ChangedPHIMap.count(PHIInput) == 1 &&
- "This PHI node should have already been changed.");
- MachineInstr *PrimedAccPHI = ChangedPHIMap.lookup(PHIInput);
- PHIOps.push_back({MachineOperand::CreateReg(
- PrimedAccPHI->getOperand(0).getReg(), false),
- PHI->getOperand(PHIOp + 1)});
- }
- }
- Register AccReg = Dst;
- // If the PHI node we are changing is the root node, the register it defines
- // will be the destination register of the original copy (of the PHI def).
- // For all other PHI's in the list, we need to create another primed
- // accumulator virtual register as the PHI will no longer define the
- // unprimed accumulator.
- if (PHI != PHIs[0])
- AccReg = MRI->createVirtualRegister(&PPC::ACCRCRegClass);
- MachineInstrBuilder NewPHI = BuildMI(
- *PHI->getParent(), PHI, PHI->getDebugLoc(), TII->get(PPC::PHI), AccReg);
- for (auto RegMBB : PHIOps)
- NewPHI.add(RegMBB.first).add(RegMBB.second);
- ChangedPHIMap[PHI] = NewPHI.getInstr();
- }
-}
-
+// This function returns a list of all PHI nodes in the tree starting from
+// the RootPHI node. We perform a BFS traversal to get an ordered list of nodes.
+// The list initially only contains the root PHI. When we visit a PHI node, we
+// add it to the list. We continue to look for other PHI node operands while
+// there are nodes to visit in the list. The function returns false if the
+// optimization cannot be applied on this tree.
+static bool collectUnprimedAccPHIs(MachineRegisterInfo *MRI,
+ MachineInstr *RootPHI,
+ SmallVectorImpl<MachineInstr *> &PHIs) {
+ PHIs.push_back(RootPHI);
+ unsigned VisitedIndex = 0;
+ while (VisitedIndex < PHIs.size()) {
+ MachineInstr *VisitedPHI = PHIs[VisitedIndex];
+ for (unsigned PHIOp = 1, NumOps = VisitedPHI->getNumOperands();
+ PHIOp != NumOps; PHIOp += 2) {
+ Register RegOp = VisitedPHI->getOperand(PHIOp).getReg();
+ if (!Register::isVirtualRegister(RegOp))
+ return false;
+ MachineInstr *Instr = MRI->getVRegDef(RegOp);
+ // While collecting the PHI nodes, we check if they can be converted (i.e.
+ // all the operands are either copies, implicit defs or PHI nodes).
+ unsigned Opcode = Instr->getOpcode();
+ if (Opcode == PPC::COPY) {
+ Register Reg = Instr->getOperand(1).getReg();
+ if (!Register::isVirtualRegister(Reg) ||
+ MRI->getRegClass(Reg) != &PPC::ACCRCRegClass)
+ return false;
+ } else if (Opcode != PPC::IMPLICIT_DEF && Opcode != PPC::PHI)
+ return false;
+ // If we detect a cycle in the PHI nodes, we exit. It would be
+ // possible to change cycles as well, but that would add a lot
+ // of complexity for a case that is unlikely to occur with MMA
+ // code.
+ if (Opcode != PPC::PHI)
+ continue;
+ if (llvm::is_contained(PHIs, Instr))
+ return false;
+ PHIs.push_back(Instr);
+ }
+ VisitedIndex++;
+ }
+ return true;
+}
+
+// This function changes the unprimed accumulator PHI nodes in the PHIs list to
+// primed accumulator PHI nodes. The list is traversed in reverse order to
+// change all the PHI operands of a PHI node before changing the node itself.
+// We keep a map to associate each changed PHI node to its non-changed form.
+static void convertUnprimedAccPHIs(const PPCInstrInfo *TII,
+ MachineRegisterInfo *MRI,
+ SmallVectorImpl<MachineInstr *> &PHIs,
+ Register Dst) {
+ DenseMap<MachineInstr *, MachineInstr *> ChangedPHIMap;
+ for (auto It = PHIs.rbegin(), End = PHIs.rend(); It != End; ++It) {
+ MachineInstr *PHI = *It;
+ SmallVector<std::pair<MachineOperand, MachineOperand>, 4> PHIOps;
+ // We check if the current PHI node can be changed by looking at its
+ // operands. If all the operands are either copies from primed
+ // accumulators, implicit definitions or other unprimed accumulator
+ // PHI nodes, we change it.
+ for (unsigned PHIOp = 1, NumOps = PHI->getNumOperands(); PHIOp != NumOps;
+ PHIOp += 2) {
+ Register RegOp = PHI->getOperand(PHIOp).getReg();
+ MachineInstr *PHIInput = MRI->getVRegDef(RegOp);
+ unsigned Opcode = PHIInput->getOpcode();
+ assert((Opcode == PPC::COPY || Opcode == PPC::IMPLICIT_DEF ||
+ Opcode == PPC::PHI) &&
+ "Unexpected instruction");
+ if (Opcode == PPC::COPY) {
+ assert(MRI->getRegClass(PHIInput->getOperand(1).getReg()) ==
+ &PPC::ACCRCRegClass &&
+ "Unexpected register class");
+ PHIOps.push_back({PHIInput->getOperand(1), PHI->getOperand(PHIOp + 1)});
+ } else if (Opcode == PPC::IMPLICIT_DEF) {
+ Register AccReg = MRI->createVirtualRegister(&PPC::ACCRCRegClass);
+ BuildMI(*PHIInput->getParent(), PHIInput, PHIInput->getDebugLoc(),
+ TII->get(PPC::IMPLICIT_DEF), AccReg);
+ PHIOps.push_back({MachineOperand::CreateReg(AccReg, false),
+ PHI->getOperand(PHIOp + 1)});
+ } else if (Opcode == PPC::PHI) {
+ // We found a PHI operand. At this point we know this operand
+ // has already been changed so we get its associated changed form
+ // from the map.
+ assert(ChangedPHIMap.count(PHIInput) == 1 &&
+ "This PHI node should have already been changed.");
+ MachineInstr *PrimedAccPHI = ChangedPHIMap.lookup(PHIInput);
+ PHIOps.push_back({MachineOperand::CreateReg(
+ PrimedAccPHI->getOperand(0).getReg(), false),
+ PHI->getOperand(PHIOp + 1)});
+ }
+ }
+ Register AccReg = Dst;
+ // If the PHI node we are changing is the root node, the register it defines
+ // will be the destination register of the original copy (of the PHI def).
+ // For all other PHI's in the list, we need to create another primed
+ // accumulator virtual register as the PHI will no longer define the
+ // unprimed accumulator.
+ if (PHI != PHIs[0])
+ AccReg = MRI->createVirtualRegister(&PPC::ACCRCRegClass);
+ MachineInstrBuilder NewPHI = BuildMI(
+ *PHI->getParent(), PHI, PHI->getDebugLoc(), TII->get(PPC::PHI), AccReg);
+ for (auto RegMBB : PHIOps)
+ NewPHI.add(RegMBB.first).add(RegMBB.second);
+ ChangedPHIMap[PHI] = NewPHI.getInstr();
+ }
+}
+
// Perform peephole optimizations.
bool PPCMIPeephole::simplifyCode(void) {
bool Simplified = false;
@@ -428,38 +428,38 @@ bool PPCMIPeephole::simplifyCode(void) {
default:
break;
- case PPC::COPY: {
- Register Src = MI.getOperand(1).getReg();
- Register Dst = MI.getOperand(0).getReg();
- if (!Register::isVirtualRegister(Src) ||
- !Register::isVirtualRegister(Dst))
- break;
- if (MRI->getRegClass(Src) != &PPC::UACCRCRegClass ||
- MRI->getRegClass(Dst) != &PPC::ACCRCRegClass)
- break;
-
- // We are copying an unprimed accumulator to a primed accumulator.
- // If the input to the copy is a PHI that is fed only by (i) copies in
- // the other direction (ii) implicitly defined unprimed accumulators or
- // (iii) other PHI nodes satisfying (i) and (ii), we can change
- // the PHI to a PHI on primed accumulators (as long as we also change
- // its operands). To detect and change such copies, we first get a list
- // of all the PHI nodes starting from the root PHI node in BFS order.
- // We then visit all these PHI nodes to check if they can be changed to
- // primed accumulator PHI nodes and if so, we change them.
- MachineInstr *RootPHI = MRI->getVRegDef(Src);
- if (RootPHI->getOpcode() != PPC::PHI)
- break;
-
- SmallVector<MachineInstr *, 4> PHIs;
- if (!collectUnprimedAccPHIs(MRI, RootPHI, PHIs))
- break;
-
- convertUnprimedAccPHIs(TII, MRI, PHIs, Dst);
-
- ToErase = &MI;
- break;
- }
+ case PPC::COPY: {
+ Register Src = MI.getOperand(1).getReg();
+ Register Dst = MI.getOperand(0).getReg();
+ if (!Register::isVirtualRegister(Src) ||
+ !Register::isVirtualRegister(Dst))
+ break;
+ if (MRI->getRegClass(Src) != &PPC::UACCRCRegClass ||
+ MRI->getRegClass(Dst) != &PPC::ACCRCRegClass)
+ break;
+
+ // We are copying an unprimed accumulator to a primed accumulator.
+ // If the input to the copy is a PHI that is fed only by (i) copies in
+ // the other direction (ii) implicitly defined unprimed accumulators or
+ // (iii) other PHI nodes satisfying (i) and (ii), we can change
+ // the PHI to a PHI on primed accumulators (as long as we also change
+ // its operands). To detect and change such copies, we first get a list
+ // of all the PHI nodes starting from the root PHI node in BFS order.
+ // We then visit all these PHI nodes to check if they can be changed to
+ // primed accumulator PHI nodes and if so, we change them.
+ MachineInstr *RootPHI = MRI->getVRegDef(Src);
+ if (RootPHI->getOpcode() != PPC::PHI)
+ break;
+
+ SmallVector<MachineInstr *, 4> PHIs;
+ if (!collectUnprimedAccPHIs(MRI, RootPHI, PHIs))
+ break;
+
+ convertUnprimedAccPHIs(TII, MRI, PHIs, Dst);
+
+ ToErase = &MI;
+ break;
+ }
case PPC::LI:
case PPC::LI8: {
// If we are materializing a zero, look for any use operands for which
@@ -712,7 +712,7 @@ bool PPCMIPeephole::simplifyCode(void) {
Simplified = true;
Register ConvReg1 = RoundInstr->getOperand(1).getReg();
Register FRSPDefines = RoundInstr->getOperand(0).getReg();
- MachineInstr &Use = *(MRI->use_instr_nodbg_begin(FRSPDefines));
+ MachineInstr &Use = *(MRI->use_instr_nodbg_begin(FRSPDefines));
for (int i = 0, e = Use.getNumOperands(); i < e; ++i)
if (Use.getOperand(i).isReg() &&
Use.getOperand(i).getReg() == FRSPDefines)
@@ -987,8 +987,8 @@ bool PPCMIPeephole::simplifyCode(void) {
case PPC::RLWINM_rec:
case PPC::RLWINM8:
case PPC::RLWINM8_rec: {
- Simplified = TII->combineRLWINM(MI, &ToErase);
- if (Simplified)
+ Simplified = TII->combineRLWINM(MI, &ToErase);
+ if (Simplified)
++NumRotatesCollapsed;
break;
}
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp
index 34c531c7cb..c976a9c62d 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp
@@ -8,7 +8,7 @@
#include "PPCMachineFunctionInfo.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/BinaryFormat/XCOFF.h"
+#include "llvm/BinaryFormat/XCOFF.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/MC/MCContext.h"
#include "llvm/Support/CommandLine.h"
@@ -64,36 +64,36 @@ bool PPCFunctionInfo::isLiveInZExt(Register VReg) const {
return LiveIn.second.isZExt();
return false;
}
-
-void PPCFunctionInfo::appendParameterType(ParamType Type) {
- uint32_t CopyParamType = ParameterType;
- int Bits = 0;
-
- // If it is fixed type, we only need to increase the FixedParamNum, for
- // the bit encode of fixed type is bit of zero, we do not need to change the
- // ParamType.
- if (Type == FixedType) {
- ++FixedParamNum;
- return;
- }
-
- ++FloatingPointParamNum;
-
- for (int I = 0;
- I < static_cast<int>(FloatingPointParamNum + FixedParamNum - 1); ++I) {
- if (CopyParamType & XCOFF::TracebackTable::ParmTypeIsFloatingBit) {
- // '10'b => floating point short parameter.
- // '11'b => floating point long parameter.
- CopyParamType <<= 2;
- Bits += 2;
- } else {
- // '0'b => fixed parameter.
- CopyParamType <<= 1;
- ++Bits;
- }
- }
-
- assert(Type != FixedType && "FixedType should already be handled.");
- if (Bits < 31)
- ParameterType |= Type << (30 - Bits);
-}
+
+void PPCFunctionInfo::appendParameterType(ParamType Type) {
+ uint32_t CopyParamType = ParameterType;
+ int Bits = 0;
+
+ // If it is fixed type, we only need to increase the FixedParamNum, for
+ // the bit encode of fixed type is bit of zero, we do not need to change the
+ // ParamType.
+ if (Type == FixedType) {
+ ++FixedParamNum;
+ return;
+ }
+
+ ++FloatingPointParamNum;
+
+ for (int I = 0;
+ I < static_cast<int>(FloatingPointParamNum + FixedParamNum - 1); ++I) {
+ if (CopyParamType & XCOFF::TracebackTable::ParmTypeIsFloatingBit) {
+ // '10'b => floating point short parameter.
+ // '11'b => floating point long parameter.
+ CopyParamType <<= 2;
+ Bits += 2;
+ } else {
+ // '0'b => fixed parameter.
+ CopyParamType <<= 1;
+ ++Bits;
+ }
+ }
+
+ assert(Type != FixedType && "FixedType should already be handled.");
+ if (Bits < 31)
+ ParameterType |= Type << (30 - Bits);
+}
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCMachineFunctionInfo.h b/contrib/libs/llvm12/lib/Target/PowerPC/PPCMachineFunctionInfo.h
index f34d23ee29..4b73b36318 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCMachineFunctionInfo.h
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCMachineFunctionInfo.h
@@ -22,16 +22,16 @@ namespace llvm {
/// PPCFunctionInfo - This class is derived from MachineFunction private
/// PowerPC target-specific information for each MachineFunction.
class PPCFunctionInfo : public MachineFunctionInfo {
-public:
- // The value in the ParamType are used to indicate the bitstrings used in the
- // encoding format.
- enum ParamType {
- FixedType = 0x0,
- ShortFloatPoint = 0x2,
- LongFloatPoint = 0x3
- };
-
-private:
+public:
+ // The value in the ParamType are used to indicate the bitstrings used in the
+ // encoding format.
+ enum ParamType {
+ FixedType = 0x0,
+ ShortFloatPoint = 0x2,
+ LongFloatPoint = 0x3
+ };
+
+private:
virtual void anchor();
/// FramePointerSaveIndex - Frame index of where the old frame pointer is
@@ -117,20 +117,20 @@ private:
/// register for parameter passing.
unsigned VarArgsNumFPR = 0;
- /// FixedParamNum - Number of fixed parameter.
- unsigned FixedParamNum = 0;
-
- /// FloatingParamNum - Number of floating point parameter.
- unsigned FloatingPointParamNum = 0;
-
- /// ParamType - Encode type for every parameter
- /// in the order of parameters passing in.
- /// Bitstring starts from the most significant (leftmost) bit.
- /// '0'b => fixed parameter.
- /// '10'b => floating point short parameter.
- /// '11'b => floating point long parameter.
- uint32_t ParameterType = 0;
-
+ /// FixedParamNum - Number of fixed parameter.
+ unsigned FixedParamNum = 0;
+
+ /// FloatingParamNum - Number of floating point parameter.
+ unsigned FloatingPointParamNum = 0;
+
+ /// ParamType - Encode type for every parameter
+ /// in the order of parameters passing in.
+ /// Bitstring starts from the most significant (leftmost) bit.
+ /// '0'b => fixed parameter.
+ /// '10'b => floating point short parameter.
+ /// '11'b => floating point long parameter.
+ uint32_t ParameterType = 0;
+
/// CRSpillFrameIndex - FrameIndex for CR spill slot for 32-bit SVR4.
int CRSpillFrameIndex = 0;
@@ -214,13 +214,13 @@ public:
unsigned getVarArgsNumGPR() const { return VarArgsNumGPR; }
void setVarArgsNumGPR(unsigned Num) { VarArgsNumGPR = Num; }
- unsigned getFixedParamNum() const { return FixedParamNum; }
-
- unsigned getFloatingPointParamNum() const { return FloatingPointParamNum; }
-
- uint32_t getParameterType() const { return ParameterType; }
- void appendParameterType(ParamType Type);
-
+ unsigned getFixedParamNum() const { return FixedParamNum; }
+
+ unsigned getFloatingPointParamNum() const { return FloatingPointParamNum; }
+
+ uint32_t getParameterType() const { return ParameterType; }
+ void appendParameterType(ParamType Type);
+
unsigned getVarArgsNumFPR() const { return VarArgsNumFPR; }
void setVarArgsNumFPR(unsigned Num) { VarArgsNumFPR = Num; }
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCMachineScheduler.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCMachineScheduler.cpp
index 445767b120..ce615e554d 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCMachineScheduler.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCMachineScheduler.cpp
@@ -49,104 +49,104 @@ bool PPCPreRASchedStrategy::biasAddiLoadCandidate(SchedCandidate &Cand,
void PPCPreRASchedStrategy::tryCandidate(SchedCandidate &Cand,
SchedCandidate &TryCand,
SchedBoundary *Zone) const {
- // From GenericScheduler::tryCandidate
+ // From GenericScheduler::tryCandidate
- // Initialize the candidate if needed.
- if (!Cand.isValid()) {
- TryCand.Reason = NodeOrder;
+ // Initialize the candidate if needed.
+ if (!Cand.isValid()) {
+ TryCand.Reason = NodeOrder;
return;
- }
-
- // Bias PhysReg Defs and copies to their uses and defined respectively.
- if (tryGreater(biasPhysReg(TryCand.SU, TryCand.AtTop),
- biasPhysReg(Cand.SU, Cand.AtTop), TryCand, Cand, PhysReg))
- return;
-
- // Avoid exceeding the target's limit.
- if (DAG->isTrackingPressure() &&
- tryPressure(TryCand.RPDelta.Excess, Cand.RPDelta.Excess, TryCand, Cand,
- RegExcess, TRI, DAG->MF))
- return;
-
- // Avoid increasing the max critical pressure in the scheduled region.
- if (DAG->isTrackingPressure() &&
- tryPressure(TryCand.RPDelta.CriticalMax, Cand.RPDelta.CriticalMax,
- TryCand, Cand, RegCritical, TRI, DAG->MF))
- return;
-
- // We only compare a subset of features when comparing nodes between
- // Top and Bottom boundary. Some properties are simply incomparable, in many
- // other instances we should only override the other boundary if something
- // is a clear good pick on one boundary. Skip heuristics that are more
- // "tie-breaking" in nature.
- bool SameBoundary = Zone != nullptr;
- if (SameBoundary) {
- // For loops that are acyclic path limited, aggressively schedule for
- // latency. Within an single cycle, whenever CurrMOps > 0, allow normal
- // heuristics to take precedence.
- if (Rem.IsAcyclicLatencyLimited && !Zone->getCurrMOps() &&
- tryLatency(TryCand, Cand, *Zone))
- return;
-
- // Prioritize instructions that read unbuffered resources by stall cycles.
- if (tryLess(Zone->getLatencyStallCycles(TryCand.SU),
- Zone->getLatencyStallCycles(Cand.SU), TryCand, Cand, Stall))
- return;
- }
-
- // Keep clustered nodes together to encourage downstream peephole
- // optimizations which may reduce resource requirements.
- //
- // This is a best effort to set things up for a post-RA pass. Optimizations
- // like generating loads of multiple registers should ideally be done within
- // the scheduler pass by combining the loads during DAG postprocessing.
- const SUnit *CandNextClusterSU =
- Cand.AtTop ? DAG->getNextClusterSucc() : DAG->getNextClusterPred();
- const SUnit *TryCandNextClusterSU =
- TryCand.AtTop ? DAG->getNextClusterSucc() : DAG->getNextClusterPred();
- if (tryGreater(TryCand.SU == TryCandNextClusterSU,
- Cand.SU == CandNextClusterSU, TryCand, Cand, Cluster))
- return;
-
- if (SameBoundary) {
- // Weak edges are for clustering and other constraints.
- if (tryLess(getWeakLeft(TryCand.SU, TryCand.AtTop),
- getWeakLeft(Cand.SU, Cand.AtTop), TryCand, Cand, Weak))
- return;
- }
-
- // Avoid increasing the max pressure of the entire region.
- if (DAG->isTrackingPressure() &&
- tryPressure(TryCand.RPDelta.CurrentMax, Cand.RPDelta.CurrentMax, TryCand,
- Cand, RegMax, TRI, DAG->MF))
- return;
-
- if (SameBoundary) {
- // Avoid critical resource consumption and balance the schedule.
- TryCand.initResourceDelta(DAG, SchedModel);
- if (tryLess(TryCand.ResDelta.CritResources, Cand.ResDelta.CritResources,
- TryCand, Cand, ResourceReduce))
- return;
- if (tryGreater(TryCand.ResDelta.DemandedResources,
- Cand.ResDelta.DemandedResources, TryCand, Cand,
- ResourceDemand))
- return;
-
- // Avoid serializing long latency dependence chains.
- // For acyclic path limited loops, latency was already checked above.
- if (!RegionPolicy.DisableLatencyHeuristic && TryCand.Policy.ReduceLatency &&
- !Rem.IsAcyclicLatencyLimited && tryLatency(TryCand, Cand, *Zone))
- return;
-
- // Fall through to original instruction order.
- if ((Zone->isTop() && TryCand.SU->NodeNum < Cand.SU->NodeNum) ||
- (!Zone->isTop() && TryCand.SU->NodeNum > Cand.SU->NodeNum)) {
- TryCand.Reason = NodeOrder;
- }
- }
-
- // GenericScheduler::tryCandidate end
-
+ }
+
+ // Bias PhysReg Defs and copies to their uses and defined respectively.
+ if (tryGreater(biasPhysReg(TryCand.SU, TryCand.AtTop),
+ biasPhysReg(Cand.SU, Cand.AtTop), TryCand, Cand, PhysReg))
+ return;
+
+ // Avoid exceeding the target's limit.
+ if (DAG->isTrackingPressure() &&
+ tryPressure(TryCand.RPDelta.Excess, Cand.RPDelta.Excess, TryCand, Cand,
+ RegExcess, TRI, DAG->MF))
+ return;
+
+ // Avoid increasing the max critical pressure in the scheduled region.
+ if (DAG->isTrackingPressure() &&
+ tryPressure(TryCand.RPDelta.CriticalMax, Cand.RPDelta.CriticalMax,
+ TryCand, Cand, RegCritical, TRI, DAG->MF))
+ return;
+
+ // We only compare a subset of features when comparing nodes between
+ // Top and Bottom boundary. Some properties are simply incomparable, in many
+ // other instances we should only override the other boundary if something
+ // is a clear good pick on one boundary. Skip heuristics that are more
+ // "tie-breaking" in nature.
+ bool SameBoundary = Zone != nullptr;
+ if (SameBoundary) {
+ // For loops that are acyclic path limited, aggressively schedule for
+ // latency. Within an single cycle, whenever CurrMOps > 0, allow normal
+ // heuristics to take precedence.
+ if (Rem.IsAcyclicLatencyLimited && !Zone->getCurrMOps() &&
+ tryLatency(TryCand, Cand, *Zone))
+ return;
+
+ // Prioritize instructions that read unbuffered resources by stall cycles.
+ if (tryLess(Zone->getLatencyStallCycles(TryCand.SU),
+ Zone->getLatencyStallCycles(Cand.SU), TryCand, Cand, Stall))
+ return;
+ }
+
+ // Keep clustered nodes together to encourage downstream peephole
+ // optimizations which may reduce resource requirements.
+ //
+ // This is a best effort to set things up for a post-RA pass. Optimizations
+ // like generating loads of multiple registers should ideally be done within
+ // the scheduler pass by combining the loads during DAG postprocessing.
+ const SUnit *CandNextClusterSU =
+ Cand.AtTop ? DAG->getNextClusterSucc() : DAG->getNextClusterPred();
+ const SUnit *TryCandNextClusterSU =
+ TryCand.AtTop ? DAG->getNextClusterSucc() : DAG->getNextClusterPred();
+ if (tryGreater(TryCand.SU == TryCandNextClusterSU,
+ Cand.SU == CandNextClusterSU, TryCand, Cand, Cluster))
+ return;
+
+ if (SameBoundary) {
+ // Weak edges are for clustering and other constraints.
+ if (tryLess(getWeakLeft(TryCand.SU, TryCand.AtTop),
+ getWeakLeft(Cand.SU, Cand.AtTop), TryCand, Cand, Weak))
+ return;
+ }
+
+ // Avoid increasing the max pressure of the entire region.
+ if (DAG->isTrackingPressure() &&
+ tryPressure(TryCand.RPDelta.CurrentMax, Cand.RPDelta.CurrentMax, TryCand,
+ Cand, RegMax, TRI, DAG->MF))
+ return;
+
+ if (SameBoundary) {
+ // Avoid critical resource consumption and balance the schedule.
+ TryCand.initResourceDelta(DAG, SchedModel);
+ if (tryLess(TryCand.ResDelta.CritResources, Cand.ResDelta.CritResources,
+ TryCand, Cand, ResourceReduce))
+ return;
+ if (tryGreater(TryCand.ResDelta.DemandedResources,
+ Cand.ResDelta.DemandedResources, TryCand, Cand,
+ ResourceDemand))
+ return;
+
+ // Avoid serializing long latency dependence chains.
+ // For acyclic path limited loops, latency was already checked above.
+ if (!RegionPolicy.DisableLatencyHeuristic && TryCand.Policy.ReduceLatency &&
+ !Rem.IsAcyclicLatencyLimited && tryLatency(TryCand, Cand, *Zone))
+ return;
+
+ // Fall through to original instruction order.
+ if ((Zone->isTop() && TryCand.SU->NodeNum < Cand.SU->NodeNum) ||
+ (!Zone->isTop() && TryCand.SU->NodeNum > Cand.SU->NodeNum)) {
+ TryCand.Reason = NodeOrder;
+ }
+ }
+
+ // GenericScheduler::tryCandidate end
+
// Add powerpc specific heuristic only when TryCand isn't selected or
// selected as node order.
if (TryCand.Reason != NodeOrder && TryCand.Reason != NoCand)
@@ -154,10 +154,10 @@ void PPCPreRASchedStrategy::tryCandidate(SchedCandidate &Cand,
// There are some benefits to schedule the ADDI before the load to hide the
// latency, as RA may create a true dependency between the load and addi.
- if (SameBoundary) {
- if (biasAddiLoadCandidate(Cand, TryCand, *Zone))
- return;
- }
+ if (SameBoundary) {
+ if (biasAddiLoadCandidate(Cand, TryCand, *Zone))
+ return;
+ }
}
bool PPCPostRASchedStrategy::biasAddiCandidate(SchedCandidate &Cand,
@@ -174,44 +174,44 @@ bool PPCPostRASchedStrategy::biasAddiCandidate(SchedCandidate &Cand,
void PPCPostRASchedStrategy::tryCandidate(SchedCandidate &Cand,
SchedCandidate &TryCand) {
- // From PostGenericScheduler::tryCandidate
+ // From PostGenericScheduler::tryCandidate
- // Initialize the candidate if needed.
- if (!Cand.isValid()) {
- TryCand.Reason = NodeOrder;
+ // Initialize the candidate if needed.
+ if (!Cand.isValid()) {
+ TryCand.Reason = NodeOrder;
return;
- }
-
- // Prioritize instructions that read unbuffered resources by stall cycles.
- if (tryLess(Top.getLatencyStallCycles(TryCand.SU),
- Top.getLatencyStallCycles(Cand.SU), TryCand, Cand, Stall))
- return;
-
- // Keep clustered nodes together.
- if (tryGreater(TryCand.SU == DAG->getNextClusterSucc(),
- Cand.SU == DAG->getNextClusterSucc(), TryCand, Cand, Cluster))
- return;
-
- // Avoid critical resource consumption and balance the schedule.
- if (tryLess(TryCand.ResDelta.CritResources, Cand.ResDelta.CritResources,
- TryCand, Cand, ResourceReduce))
- return;
- if (tryGreater(TryCand.ResDelta.DemandedResources,
- Cand.ResDelta.DemandedResources, TryCand, Cand,
- ResourceDemand))
- return;
-
- // Avoid serializing long latency dependence chains.
- if (Cand.Policy.ReduceLatency && tryLatency(TryCand, Cand, Top)) {
- return;
- }
-
- // Fall through to original instruction order.
- if (TryCand.SU->NodeNum < Cand.SU->NodeNum)
- TryCand.Reason = NodeOrder;
-
- // PostGenericScheduler::tryCandidate end
-
+ }
+
+ // Prioritize instructions that read unbuffered resources by stall cycles.
+ if (tryLess(Top.getLatencyStallCycles(TryCand.SU),
+ Top.getLatencyStallCycles(Cand.SU), TryCand, Cand, Stall))
+ return;
+
+ // Keep clustered nodes together.
+ if (tryGreater(TryCand.SU == DAG->getNextClusterSucc(),
+ Cand.SU == DAG->getNextClusterSucc(), TryCand, Cand, Cluster))
+ return;
+
+ // Avoid critical resource consumption and balance the schedule.
+ if (tryLess(TryCand.ResDelta.CritResources, Cand.ResDelta.CritResources,
+ TryCand, Cand, ResourceReduce))
+ return;
+ if (tryGreater(TryCand.ResDelta.DemandedResources,
+ Cand.ResDelta.DemandedResources, TryCand, Cand,
+ ResourceDemand))
+ return;
+
+ // Avoid serializing long latency dependence chains.
+ if (Cand.Policy.ReduceLatency && tryLatency(TryCand, Cand, Top)) {
+ return;
+ }
+
+ // Fall through to original instruction order.
+ if (TryCand.SU->NodeNum < Cand.SU->NodeNum)
+ TryCand.Reason = NodeOrder;
+
+ // PostGenericScheduler::tryCandidate end
+
// Add powerpc post ra specific heuristic only when TryCand isn't selected or
// selected as node order.
if (TryCand.Reason != NodeOrder && TryCand.Reason != NoCand)
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCMacroFusion.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCMacroFusion.cpp
index 5175b0a279..d12c6d9cd4 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCMacroFusion.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCMacroFusion.cpp
@@ -51,8 +51,8 @@ public:
Kd(Kind), Supported(HasFeature), DepOpIdx(Index), OpSet1(First),
OpSet2(Second) {}
- bool hasOp1(unsigned Opc) const { return OpSet1.contains(Opc); }
- bool hasOp2(unsigned Opc) const { return OpSet2.contains(Opc); }
+ bool hasOp1(unsigned Opc) const { return OpSet1.contains(Opc); }
+ bool hasOp2(unsigned Opc) const { return OpSet2.contains(Opc); }
bool isSupported() const { return Supported; }
Optional<unsigned> depOpIdx() const {
if (DepOpIdx < 0)
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCPreEmitPeephole.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCPreEmitPeephole.cpp
index 013c928bdb..a8853609a7 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCPreEmitPeephole.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCPreEmitPeephole.cpp
@@ -21,7 +21,7 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -39,54 +39,54 @@ STATISTIC(NumFrameOffFoldInPreEmit,
"Number of folding frame offset by using r+r in pre-emit peephole");
static cl::opt<bool>
-EnablePCRelLinkerOpt("ppc-pcrel-linker-opt", cl::Hidden, cl::init(true),
- cl::desc("enable PC Relative linker optimization"));
-
-static cl::opt<bool>
+EnablePCRelLinkerOpt("ppc-pcrel-linker-opt", cl::Hidden, cl::init(true),
+ cl::desc("enable PC Relative linker optimization"));
+
+static cl::opt<bool>
RunPreEmitPeephole("ppc-late-peephole", cl::Hidden, cl::init(true),
cl::desc("Run pre-emit peephole optimizations."));
namespace {
-
-static bool hasPCRelativeForm(MachineInstr &Use) {
- switch (Use.getOpcode()) {
- default:
- return false;
- case PPC::LBZ:
- case PPC::LBZ8:
- case PPC::LHA:
- case PPC::LHA8:
- case PPC::LHZ:
- case PPC::LHZ8:
- case PPC::LWZ:
- case PPC::LWZ8:
- case PPC::STB:
- case PPC::STB8:
- case PPC::STH:
- case PPC::STH8:
- case PPC::STW:
- case PPC::STW8:
- case PPC::LD:
- case PPC::STD:
- case PPC::LWA:
- case PPC::LXSD:
- case PPC::LXSSP:
- case PPC::LXV:
- case PPC::STXSD:
- case PPC::STXSSP:
- case PPC::STXV:
- case PPC::LFD:
- case PPC::LFS:
- case PPC::STFD:
- case PPC::STFS:
- case PPC::DFLOADf32:
- case PPC::DFLOADf64:
- case PPC::DFSTOREf32:
- case PPC::DFSTOREf64:
- return true;
- }
-}
-
+
+static bool hasPCRelativeForm(MachineInstr &Use) {
+ switch (Use.getOpcode()) {
+ default:
+ return false;
+ case PPC::LBZ:
+ case PPC::LBZ8:
+ case PPC::LHA:
+ case PPC::LHA8:
+ case PPC::LHZ:
+ case PPC::LHZ8:
+ case PPC::LWZ:
+ case PPC::LWZ8:
+ case PPC::STB:
+ case PPC::STB8:
+ case PPC::STH:
+ case PPC::STH8:
+ case PPC::STW:
+ case PPC::STW8:
+ case PPC::LD:
+ case PPC::STD:
+ case PPC::LWA:
+ case PPC::LXSD:
+ case PPC::LXSSP:
+ case PPC::LXV:
+ case PPC::STXSD:
+ case PPC::STXSSP:
+ case PPC::STXV:
+ case PPC::LFD:
+ case PPC::LFS:
+ case PPC::STFD:
+ case PPC::STFS:
+ case PPC::DFLOADf32:
+ case PPC::DFLOADf64:
+ case PPC::DFSTOREf32:
+ case PPC::DFSTOREf64:
+ return true;
+ }
+}
+
class PPCPreEmitPeephole : public MachineFunctionPass {
public:
static char ID;
@@ -121,7 +121,7 @@ static bool hasPCRelativeForm(MachineInstr &Use) {
for (auto BBI = MBB.instr_begin(); BBI != MBB.instr_end(); ++BBI) {
// Skip load immediate that is marked to be erased later because it
// cannot be used to replace any other instructions.
- if (InstrsToErase.contains(&*BBI))
+ if (InstrsToErase.contains(&*BBI))
continue;
// Skip non-load immediate.
unsigned Opc = BBI->getOpcode();
@@ -216,196 +216,196 @@ static bool hasPCRelativeForm(MachineInstr &Use) {
return !InstrsToErase.empty();
}
- // Check if this instruction is a PLDpc that is part of a GOT indirect
- // access.
- bool isGOTPLDpc(MachineInstr &Instr) {
- if (Instr.getOpcode() != PPC::PLDpc)
- return false;
-
- // The result must be a register.
- const MachineOperand &LoadedAddressReg = Instr.getOperand(0);
- if (!LoadedAddressReg.isReg())
- return false;
-
- // Make sure that this is a global symbol.
- const MachineOperand &SymbolOp = Instr.getOperand(1);
- if (!SymbolOp.isGlobal())
- return false;
-
- // Finally return true only if the GOT flag is present.
- return (SymbolOp.getTargetFlags() & PPCII::MO_GOT_FLAG);
- }
-
- bool addLinkerOpt(MachineBasicBlock &MBB, const TargetRegisterInfo *TRI) {
- MachineFunction *MF = MBB.getParent();
- // If the linker opt is disabled then just return.
- if (!EnablePCRelLinkerOpt)
- return false;
-
- // Add this linker opt only if we are using PC Relative memops.
- if (!MF->getSubtarget<PPCSubtarget>().isUsingPCRelativeCalls())
- return false;
-
- // Struct to keep track of one def/use pair for a GOT indirect access.
- struct GOTDefUsePair {
- MachineBasicBlock::iterator DefInst;
- MachineBasicBlock::iterator UseInst;
- Register DefReg;
- Register UseReg;
- bool StillValid;
- };
- // Vector of def/ues pairs in this basic block.
- SmallVector<GOTDefUsePair, 4> CandPairs;
- SmallVector<GOTDefUsePair, 4> ValidPairs;
- bool MadeChange = false;
-
- // Run through all of the instructions in the basic block and try to
- // collect potential pairs of GOT indirect access instructions.
- for (auto BBI = MBB.instr_begin(); BBI != MBB.instr_end(); ++BBI) {
- // Look for the initial GOT indirect load.
- if (isGOTPLDpc(*BBI)) {
- GOTDefUsePair CurrentPair{BBI, MachineBasicBlock::iterator(),
- BBI->getOperand(0).getReg(),
- PPC::NoRegister, true};
- CandPairs.push_back(CurrentPair);
- continue;
- }
-
- // We haven't encountered any new PLD instructions, nothing to check.
- if (CandPairs.empty())
- continue;
-
- // Run through the candidate pairs and see if any of the registers
- // defined in the PLD instructions are used by this instruction.
- // Note: the size of CandPairs can change in the loop.
- for (unsigned Idx = 0; Idx < CandPairs.size(); Idx++) {
- GOTDefUsePair &Pair = CandPairs[Idx];
- // The instruction does not use or modify this PLD's def reg,
- // ignore it.
- if (!BBI->readsRegister(Pair.DefReg, TRI) &&
- !BBI->modifiesRegister(Pair.DefReg, TRI))
- continue;
-
- // The use needs to be used in the address compuation and not
- // as the register being stored for a store.
- const MachineOperand *UseOp =
- hasPCRelativeForm(*BBI) ? &BBI->getOperand(2) : nullptr;
-
- // Check for a valid use.
- if (UseOp && UseOp->isReg() && UseOp->getReg() == Pair.DefReg &&
- UseOp->isUse() && UseOp->isKill()) {
- Pair.UseInst = BBI;
- Pair.UseReg = BBI->getOperand(0).getReg();
- ValidPairs.push_back(Pair);
- }
- CandPairs.erase(CandPairs.begin() + Idx);
- }
- }
-
- // Go through all of the pairs and check for any more valid uses.
- for (auto Pair = ValidPairs.begin(); Pair != ValidPairs.end(); Pair++) {
- // We shouldn't be here if we don't have a valid pair.
- assert(Pair->UseInst.isValid() && Pair->StillValid &&
- "Kept an invalid def/use pair for GOT PCRel opt");
- // We have found a potential pair. Search through the instructions
- // between the def and the use to see if it is valid to mark this as a
- // linker opt.
- MachineBasicBlock::iterator BBI = Pair->DefInst;
- ++BBI;
- for (; BBI != Pair->UseInst; ++BBI) {
- if (BBI->readsRegister(Pair->UseReg, TRI) ||
- BBI->modifiesRegister(Pair->UseReg, TRI)) {
- Pair->StillValid = false;
- break;
- }
- }
-
- if (!Pair->StillValid)
- continue;
-
- // The load/store instruction that uses the address from the PLD will
- // either use a register (for a store) or define a register (for the
- // load). That register will be added as an implicit def to the PLD
- // and as an implicit use on the second memory op. This is a precaution
- // to prevent future passes from using that register between the two
- // instructions.
- MachineOperand ImplDef =
- MachineOperand::CreateReg(Pair->UseReg, true, true);
- MachineOperand ImplUse =
- MachineOperand::CreateReg(Pair->UseReg, false, true);
- Pair->DefInst->addOperand(ImplDef);
- Pair->UseInst->addOperand(ImplUse);
-
- // Create the symbol.
- MCContext &Context = MF->getContext();
- MCSymbol *Symbol = Context.createNamedTempSymbol("pcrel");
- MachineOperand PCRelLabel =
- MachineOperand::CreateMCSymbol(Symbol, PPCII::MO_PCREL_OPT_FLAG);
- Pair->DefInst->addOperand(*MF, PCRelLabel);
- Pair->UseInst->addOperand(*MF, PCRelLabel);
- MadeChange |= true;
- }
- return MadeChange;
- }
-
- // This function removes redundant pairs of accumulator prime/unprime
- // instructions. In some situations, it's possible the compiler inserts an
- // accumulator prime instruction followed by an unprime instruction (e.g.
- // when we store an accumulator after restoring it from a spill). If the
- // accumulator is not used between the two, they can be removed. This
- // function removes these redundant pairs from basic blocks.
- // The algorithm is quite straightforward - every time we encounter a prime
- // instruction, the primed register is added to a candidate set. Any use
- // other than a prime removes the candidate from the set and any de-prime
- // of a current candidate marks both the prime and de-prime for removal.
- // This way we ensure we only remove prime/de-prime *pairs* with no
- // intervening uses.
- bool removeAccPrimeUnprime(MachineBasicBlock &MBB) {
- DenseSet<MachineInstr *> InstrsToErase;
- // Initially, none of the acc registers are candidates.
- SmallVector<MachineInstr *, 8> Candidates(
- PPC::UACCRCRegClass.getNumRegs(), nullptr);
-
- for (MachineInstr &BBI : MBB.instrs()) {
- unsigned Opc = BBI.getOpcode();
- // If we are visiting a xxmtacc instruction, we add it and its operand
- // register to the candidate set.
- if (Opc == PPC::XXMTACC) {
- Register Acc = BBI.getOperand(0).getReg();
- assert(PPC::ACCRCRegClass.contains(Acc) &&
- "Unexpected register for XXMTACC");
- Candidates[Acc - PPC::ACC0] = &BBI;
- }
- // If we are visiting a xxmfacc instruction and its operand register is
- // in the candidate set, we mark the two instructions for removal.
- else if (Opc == PPC::XXMFACC) {
- Register Acc = BBI.getOperand(0).getReg();
- assert(PPC::ACCRCRegClass.contains(Acc) &&
- "Unexpected register for XXMFACC");
- if (!Candidates[Acc - PPC::ACC0])
- continue;
- InstrsToErase.insert(&BBI);
- InstrsToErase.insert(Candidates[Acc - PPC::ACC0]);
- }
- // If we are visiting an instruction using an accumulator register
- // as operand, we remove it from the candidate set.
- else {
- for (MachineOperand &Operand : BBI.operands()) {
- if (!Operand.isReg())
- continue;
- Register Reg = Operand.getReg();
- if (PPC::ACCRCRegClass.contains(Reg))
- Candidates[Reg - PPC::ACC0] = nullptr;
- }
- }
- }
-
- for (MachineInstr *MI : InstrsToErase)
- MI->eraseFromParent();
- NumRemovedInPreEmit += InstrsToErase.size();
- return !InstrsToErase.empty();
- }
-
+ // Check if this instruction is a PLDpc that is part of a GOT indirect
+ // access.
+ bool isGOTPLDpc(MachineInstr &Instr) {
+ if (Instr.getOpcode() != PPC::PLDpc)
+ return false;
+
+ // The result must be a register.
+ const MachineOperand &LoadedAddressReg = Instr.getOperand(0);
+ if (!LoadedAddressReg.isReg())
+ return false;
+
+ // Make sure that this is a global symbol.
+ const MachineOperand &SymbolOp = Instr.getOperand(1);
+ if (!SymbolOp.isGlobal())
+ return false;
+
+ // Finally return true only if the GOT flag is present.
+ return (SymbolOp.getTargetFlags() & PPCII::MO_GOT_FLAG);
+ }
+
+ bool addLinkerOpt(MachineBasicBlock &MBB, const TargetRegisterInfo *TRI) {
+ MachineFunction *MF = MBB.getParent();
+ // If the linker opt is disabled then just return.
+ if (!EnablePCRelLinkerOpt)
+ return false;
+
+ // Add this linker opt only if we are using PC Relative memops.
+ if (!MF->getSubtarget<PPCSubtarget>().isUsingPCRelativeCalls())
+ return false;
+
+ // Struct to keep track of one def/use pair for a GOT indirect access.
+ struct GOTDefUsePair {
+ MachineBasicBlock::iterator DefInst;
+ MachineBasicBlock::iterator UseInst;
+ Register DefReg;
+ Register UseReg;
+ bool StillValid;
+ };
+ // Vector of def/ues pairs in this basic block.
+ SmallVector<GOTDefUsePair, 4> CandPairs;
+ SmallVector<GOTDefUsePair, 4> ValidPairs;
+ bool MadeChange = false;
+
+ // Run through all of the instructions in the basic block and try to
+ // collect potential pairs of GOT indirect access instructions.
+ for (auto BBI = MBB.instr_begin(); BBI != MBB.instr_end(); ++BBI) {
+ // Look for the initial GOT indirect load.
+ if (isGOTPLDpc(*BBI)) {
+ GOTDefUsePair CurrentPair{BBI, MachineBasicBlock::iterator(),
+ BBI->getOperand(0).getReg(),
+ PPC::NoRegister, true};
+ CandPairs.push_back(CurrentPair);
+ continue;
+ }
+
+ // We haven't encountered any new PLD instructions, nothing to check.
+ if (CandPairs.empty())
+ continue;
+
+ // Run through the candidate pairs and see if any of the registers
+ // defined in the PLD instructions are used by this instruction.
+ // Note: the size of CandPairs can change in the loop.
+ for (unsigned Idx = 0; Idx < CandPairs.size(); Idx++) {
+ GOTDefUsePair &Pair = CandPairs[Idx];
+ // The instruction does not use or modify this PLD's def reg,
+ // ignore it.
+ if (!BBI->readsRegister(Pair.DefReg, TRI) &&
+ !BBI->modifiesRegister(Pair.DefReg, TRI))
+ continue;
+
+ // The use needs to be used in the address compuation and not
+ // as the register being stored for a store.
+ const MachineOperand *UseOp =
+ hasPCRelativeForm(*BBI) ? &BBI->getOperand(2) : nullptr;
+
+ // Check for a valid use.
+ if (UseOp && UseOp->isReg() && UseOp->getReg() == Pair.DefReg &&
+ UseOp->isUse() && UseOp->isKill()) {
+ Pair.UseInst = BBI;
+ Pair.UseReg = BBI->getOperand(0).getReg();
+ ValidPairs.push_back(Pair);
+ }
+ CandPairs.erase(CandPairs.begin() + Idx);
+ }
+ }
+
+ // Go through all of the pairs and check for any more valid uses.
+ for (auto Pair = ValidPairs.begin(); Pair != ValidPairs.end(); Pair++) {
+ // We shouldn't be here if we don't have a valid pair.
+ assert(Pair->UseInst.isValid() && Pair->StillValid &&
+ "Kept an invalid def/use pair for GOT PCRel opt");
+ // We have found a potential pair. Search through the instructions
+ // between the def and the use to see if it is valid to mark this as a
+ // linker opt.
+ MachineBasicBlock::iterator BBI = Pair->DefInst;
+ ++BBI;
+ for (; BBI != Pair->UseInst; ++BBI) {
+ if (BBI->readsRegister(Pair->UseReg, TRI) ||
+ BBI->modifiesRegister(Pair->UseReg, TRI)) {
+ Pair->StillValid = false;
+ break;
+ }
+ }
+
+ if (!Pair->StillValid)
+ continue;
+
+ // The load/store instruction that uses the address from the PLD will
+ // either use a register (for a store) or define a register (for the
+ // load). That register will be added as an implicit def to the PLD
+ // and as an implicit use on the second memory op. This is a precaution
+ // to prevent future passes from using that register between the two
+ // instructions.
+ MachineOperand ImplDef =
+ MachineOperand::CreateReg(Pair->UseReg, true, true);
+ MachineOperand ImplUse =
+ MachineOperand::CreateReg(Pair->UseReg, false, true);
+ Pair->DefInst->addOperand(ImplDef);
+ Pair->UseInst->addOperand(ImplUse);
+
+ // Create the symbol.
+ MCContext &Context = MF->getContext();
+ MCSymbol *Symbol = Context.createNamedTempSymbol("pcrel");
+ MachineOperand PCRelLabel =
+ MachineOperand::CreateMCSymbol(Symbol, PPCII::MO_PCREL_OPT_FLAG);
+ Pair->DefInst->addOperand(*MF, PCRelLabel);
+ Pair->UseInst->addOperand(*MF, PCRelLabel);
+ MadeChange |= true;
+ }
+ return MadeChange;
+ }
+
+ // This function removes redundant pairs of accumulator prime/unprime
+ // instructions. In some situations, it's possible the compiler inserts an
+ // accumulator prime instruction followed by an unprime instruction (e.g.
+ // when we store an accumulator after restoring it from a spill). If the
+ // accumulator is not used between the two, they can be removed. This
+ // function removes these redundant pairs from basic blocks.
+ // The algorithm is quite straightforward - every time we encounter a prime
+ // instruction, the primed register is added to a candidate set. Any use
+ // other than a prime removes the candidate from the set and any de-prime
+ // of a current candidate marks both the prime and de-prime for removal.
+ // This way we ensure we only remove prime/de-prime *pairs* with no
+ // intervening uses.
+ bool removeAccPrimeUnprime(MachineBasicBlock &MBB) {
+ DenseSet<MachineInstr *> InstrsToErase;
+ // Initially, none of the acc registers are candidates.
+ SmallVector<MachineInstr *, 8> Candidates(
+ PPC::UACCRCRegClass.getNumRegs(), nullptr);
+
+ for (MachineInstr &BBI : MBB.instrs()) {
+ unsigned Opc = BBI.getOpcode();
+ // If we are visiting a xxmtacc instruction, we add it and its operand
+ // register to the candidate set.
+ if (Opc == PPC::XXMTACC) {
+ Register Acc = BBI.getOperand(0).getReg();
+ assert(PPC::ACCRCRegClass.contains(Acc) &&
+ "Unexpected register for XXMTACC");
+ Candidates[Acc - PPC::ACC0] = &BBI;
+ }
+ // If we are visiting a xxmfacc instruction and its operand register is
+ // in the candidate set, we mark the two instructions for removal.
+ else if (Opc == PPC::XXMFACC) {
+ Register Acc = BBI.getOperand(0).getReg();
+ assert(PPC::ACCRCRegClass.contains(Acc) &&
+ "Unexpected register for XXMFACC");
+ if (!Candidates[Acc - PPC::ACC0])
+ continue;
+ InstrsToErase.insert(&BBI);
+ InstrsToErase.insert(Candidates[Acc - PPC::ACC0]);
+ }
+ // If we are visiting an instruction using an accumulator register
+ // as operand, we remove it from the candidate set.
+ else {
+ for (MachineOperand &Operand : BBI.operands()) {
+ if (!Operand.isReg())
+ continue;
+ Register Reg = Operand.getReg();
+ if (PPC::ACCRCRegClass.contains(Reg))
+ Candidates[Reg - PPC::ACC0] = nullptr;
+ }
+ }
+ }
+
+ for (MachineInstr *MI : InstrsToErase)
+ MI->eraseFromParent();
+ NumRemovedInPreEmit += InstrsToErase.size();
+ return !InstrsToErase.empty();
+ }
+
bool runOnMachineFunction(MachineFunction &MF) override {
if (skipFunction(MF.getFunction()) || !RunPreEmitPeephole) {
// Remove UNENCODED_NOP even when this pass is disabled.
@@ -426,8 +426,8 @@ static bool hasPCRelativeForm(MachineInstr &Use) {
SmallVector<MachineInstr *, 4> InstrsToErase;
for (MachineBasicBlock &MBB : MF) {
Changed |= removeRedundantLIs(MBB, TRI);
- Changed |= addLinkerOpt(MBB, TRI);
- Changed |= removeAccPrimeUnprime(MBB);
+ Changed |= addLinkerOpt(MBB, TRI);
+ Changed |= removeAccPrimeUnprime(MBB);
for (MachineInstr &MI : MBB) {
unsigned Opc = MI.getOpcode();
if (Opc == PPC::UNENCODED_NOP) {
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCReduceCRLogicals.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCReduceCRLogicals.cpp
index 2f717b3adf..5cee00c61f 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCReduceCRLogicals.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCReduceCRLogicals.cpp
@@ -206,9 +206,9 @@ static bool splitMBB(BlockSplitInfo &BSI) {
NewMBB->splice(NewMBB->end(), ThisMBB, InsertPoint, ThisMBB->end());
NewMBB->transferSuccessors(ThisMBB);
if (!ProbOrigTarget.isUnknown()) {
- auto MBBI = find(NewMBB->successors(), OrigTarget);
+ auto MBBI = find(NewMBB->successors(), OrigTarget);
NewMBB->setSuccProbability(MBBI, ProbOrigTarget);
- MBBI = find(NewMBB->successors(), OrigFallThrough);
+ MBBI = find(NewMBB->successors(), OrigFallThrough);
NewMBB->setSuccProbability(MBBI, ProbOrigFallThrough);
}
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCRegisterInfo.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCRegisterInfo.cpp
index fc44a2b490..178a13443e 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -75,21 +75,21 @@ MaxCRBitSpillDist("ppc-max-crbit-spill-dist",
"spill on ppc"),
cl::Hidden, cl::init(100));
-// Copies/moves of physical accumulators are expensive operations
-// that should be avoided whenever possible. MMA instructions are
-// meant to be used in performance-sensitive computational kernels.
-// This option is provided, at least for the time being, to give the
-// user a tool to detect this expensive operation and either rework
-// their code or report a compiler bug if that turns out to be the
-// cause.
-#ifndef NDEBUG
-static cl::opt<bool>
-ReportAccMoves("ppc-report-acc-moves",
- cl::desc("Emit information about accumulator register spills "
- "and copies"),
- cl::Hidden, cl::init(false));
-#endif
-
+// Copies/moves of physical accumulators are expensive operations
+// that should be avoided whenever possible. MMA instructions are
+// meant to be used in performance-sensitive computational kernels.
+// This option is provided, at least for the time being, to give the
+// user a tool to detect this expensive operation and either rework
+// their code or report a compiler bug if that turns out to be the
+// cause.
+#ifndef NDEBUG
+static cl::opt<bool>
+ReportAccMoves("ppc-report-acc-moves",
+ cl::desc("Emit information about accumulator register spills "
+ "and copies"),
+ cl::Hidden, cl::init(false));
+#endif
+
static unsigned offsetMinAlignForOpcode(unsigned OpC);
PPCRegisterInfo::PPCRegisterInfo(const PPCTargetMachine &TM)
@@ -156,10 +156,10 @@ PPCRegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
const MCPhysReg*
PPCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
const PPCSubtarget &Subtarget = MF->getSubtarget<PPCSubtarget>();
- if (Subtarget.isAIXABI() &&
- (Subtarget.hasAltivec() && !TM.getAIXExtendedAltivecABI()))
- report_fatal_error("the default AIX Altivec ABI is not yet "
- "supported.");
+ if (Subtarget.isAIXABI() &&
+ (Subtarget.hasAltivec() && !TM.getAIXExtendedAltivecABI()))
+ report_fatal_error("the default AIX Altivec ABI is not yet "
+ "supported.");
if (MF->getFunction().getCallingConv() == CallingConv::AnyReg) {
if (!TM.isPPC64() && Subtarget.isAIXABI())
report_fatal_error("AnyReg unimplemented on 32-bit AIX.");
@@ -206,11 +206,11 @@ PPCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
return SaveR2 ? CSR_PPC64_R2_SaveList : CSR_PPC64_SaveList;
}
// 32-bit targets.
- if (Subtarget.isAIXABI()) {
- if (Subtarget.hasAltivec())
- return CSR_AIX32_Altivec_SaveList;
+ if (Subtarget.isAIXABI()) {
+ if (Subtarget.hasAltivec())
+ return CSR_AIX32_Altivec_SaveList;
return CSR_AIX32_SaveList;
- }
+ }
if (Subtarget.hasAltivec())
return CSR_SVR432_Altivec_SaveList;
else if (Subtarget.hasSPE())
@@ -231,10 +231,10 @@ PPCRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
}
if (Subtarget.isAIXABI()) {
- return TM.isPPC64() ? (Subtarget.hasAltivec() ? CSR_PPC64_Altivec_RegMask
- : CSR_PPC64_RegMask)
- : (Subtarget.hasAltivec() ? CSR_AIX32_Altivec_RegMask
- : CSR_AIX32_RegMask);
+ return TM.isPPC64() ? (Subtarget.hasAltivec() ? CSR_PPC64_Altivec_RegMask
+ : CSR_PPC64_RegMask)
+ : (Subtarget.hasAltivec() ? CSR_AIX32_Altivec_RegMask
+ : CSR_AIX32_RegMask);
}
if (CC == CallingConv::Cold) {
@@ -851,16 +851,16 @@ void PPCRegisterInfo::lowerCRBitSpilling(MachineBasicBlock::iterator II,
SpillsKnownBit = true;
break;
default:
- // On Power10, we can use SETNBC to spill all CR bits. SETNBC will set all
- // bits (specifically, it produces a -1 if the CR bit is set). Ultimately,
- // the bit that is of importance to us is bit 32 (bit 0 of a 32-bit
- // register), and SETNBC will set this.
- if (Subtarget.isISA3_1()) {
- BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::SETNBC8 : PPC::SETNBC), Reg)
- .addReg(SrcReg, RegState::Undef);
- break;
- }
-
+ // On Power10, we can use SETNBC to spill all CR bits. SETNBC will set all
+ // bits (specifically, it produces a -1 if the CR bit is set). Ultimately,
+ // the bit that is of importance to us is bit 32 (bit 0 of a 32-bit
+ // register), and SETNBC will set this.
+ if (Subtarget.isISA3_1()) {
+ BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::SETNBC8 : PPC::SETNBC), Reg)
+ .addReg(SrcReg, RegState::Undef);
+ break;
+ }
+
// On Power9, we can use SETB to extract the LT bit. This only works for
// the LT bit since SETB produces -1/1/0 for LT/GT/<neither>. So the value
// of the bit we care about (32-bit sign bit) will be set to the value of
@@ -960,105 +960,105 @@ void PPCRegisterInfo::lowerCRBitRestore(MachineBasicBlock::iterator II,
MBB.erase(II);
}
-void PPCRegisterInfo::emitAccCopyInfo(MachineBasicBlock &MBB,
- MCRegister DestReg, MCRegister SrcReg) {
-#ifdef NDEBUG
- return;
-#else
- if (ReportAccMoves) {
- std::string Dest = PPC::ACCRCRegClass.contains(DestReg) ? "acc" : "uacc";
- std::string Src = PPC::ACCRCRegClass.contains(SrcReg) ? "acc" : "uacc";
- dbgs() << "Emitting copy from " << Src << " to " << Dest << ":\n";
- MBB.dump();
- }
-#endif
-}
-
-static void emitAccSpillRestoreInfo(MachineBasicBlock &MBB, bool IsPrimed,
- bool IsRestore) {
-#ifdef NDEBUG
- return;
-#else
- if (ReportAccMoves) {
- dbgs() << "Emitting " << (IsPrimed ? "acc" : "uacc") << " register "
- << (IsRestore ? "restore" : "spill") << ":\n";
- MBB.dump();
- }
-#endif
-}
-
-/// lowerACCSpilling - Generate the code for spilling the accumulator register.
-/// Similarly to other spills/reloads that use pseudo-ops, we do not actually
-/// eliminate the FrameIndex here nor compute the stack offset. We simply
-/// create a real instruction with an FI and rely on eliminateFrameIndex to
-/// handle the FI elimination.
-void PPCRegisterInfo::lowerACCSpilling(MachineBasicBlock::iterator II,
- unsigned FrameIndex) const {
- MachineInstr &MI = *II; // SPILL_ACC <SrcReg>, <offset>
+void PPCRegisterInfo::emitAccCopyInfo(MachineBasicBlock &MBB,
+ MCRegister DestReg, MCRegister SrcReg) {
+#ifdef NDEBUG
+ return;
+#else
+ if (ReportAccMoves) {
+ std::string Dest = PPC::ACCRCRegClass.contains(DestReg) ? "acc" : "uacc";
+ std::string Src = PPC::ACCRCRegClass.contains(SrcReg) ? "acc" : "uacc";
+ dbgs() << "Emitting copy from " << Src << " to " << Dest << ":\n";
+ MBB.dump();
+ }
+#endif
+}
+
+static void emitAccSpillRestoreInfo(MachineBasicBlock &MBB, bool IsPrimed,
+ bool IsRestore) {
+#ifdef NDEBUG
+ return;
+#else
+ if (ReportAccMoves) {
+ dbgs() << "Emitting " << (IsPrimed ? "acc" : "uacc") << " register "
+ << (IsRestore ? "restore" : "spill") << ":\n";
+ MBB.dump();
+ }
+#endif
+}
+
+/// lowerACCSpilling - Generate the code for spilling the accumulator register.
+/// Similarly to other spills/reloads that use pseudo-ops, we do not actually
+/// eliminate the FrameIndex here nor compute the stack offset. We simply
+/// create a real instruction with an FI and rely on eliminateFrameIndex to
+/// handle the FI elimination.
+void PPCRegisterInfo::lowerACCSpilling(MachineBasicBlock::iterator II,
+ unsigned FrameIndex) const {
+ MachineInstr &MI = *II; // SPILL_ACC <SrcReg>, <offset>
MachineBasicBlock &MBB = *MI.getParent();
MachineFunction &MF = *MBB.getParent();
const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
- DebugLoc DL = MI.getDebugLoc();
+ DebugLoc DL = MI.getDebugLoc();
Register SrcReg = MI.getOperand(0).getReg();
- bool IsKilled = MI.getOperand(0).isKill();
-
- bool IsPrimed = PPC::ACCRCRegClass.contains(SrcReg);
- Register Reg =
- PPC::VSRp0 + (SrcReg - (IsPrimed ? PPC::ACC0 : PPC::UACC0)) * 2;
- bool IsLittleEndian = Subtarget.isLittleEndian();
-
- emitAccSpillRestoreInfo(MBB, IsPrimed, false);
-
- // De-prime the register being spilled, create two stores for the pair
- // subregisters accounting for endianness and then re-prime the register if
- // it isn't killed. This uses the Offset parameter to addFrameReference() to
- // adjust the offset of the store that is within the 64-byte stack slot.
- if (IsPrimed)
- BuildMI(MBB, II, DL, TII.get(PPC::XXMFACC), SrcReg).addReg(SrcReg);
- addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::STXVP))
- .addReg(Reg, getKillRegState(IsKilled)),
- FrameIndex, IsLittleEndian ? 32 : 0);
- addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::STXVP))
- .addReg(Reg + 1, getKillRegState(IsKilled)),
- FrameIndex, IsLittleEndian ? 0 : 32);
- if (IsPrimed && !IsKilled)
- BuildMI(MBB, II, DL, TII.get(PPC::XXMTACC), SrcReg).addReg(SrcReg);
-
+ bool IsKilled = MI.getOperand(0).isKill();
+
+ bool IsPrimed = PPC::ACCRCRegClass.contains(SrcReg);
+ Register Reg =
+ PPC::VSRp0 + (SrcReg - (IsPrimed ? PPC::ACC0 : PPC::UACC0)) * 2;
+ bool IsLittleEndian = Subtarget.isLittleEndian();
+
+ emitAccSpillRestoreInfo(MBB, IsPrimed, false);
+
+ // De-prime the register being spilled, create two stores for the pair
+ // subregisters accounting for endianness and then re-prime the register if
+ // it isn't killed. This uses the Offset parameter to addFrameReference() to
+ // adjust the offset of the store that is within the 64-byte stack slot.
+ if (IsPrimed)
+ BuildMI(MBB, II, DL, TII.get(PPC::XXMFACC), SrcReg).addReg(SrcReg);
+ addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::STXVP))
+ .addReg(Reg, getKillRegState(IsKilled)),
+ FrameIndex, IsLittleEndian ? 32 : 0);
+ addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::STXVP))
+ .addReg(Reg + 1, getKillRegState(IsKilled)),
+ FrameIndex, IsLittleEndian ? 0 : 32);
+ if (IsPrimed && !IsKilled)
+ BuildMI(MBB, II, DL, TII.get(PPC::XXMTACC), SrcReg).addReg(SrcReg);
+
// Discard the pseudo instruction.
MBB.erase(II);
}
-/// lowerACCRestore - Generate the code to restore the accumulator register.
-void PPCRegisterInfo::lowerACCRestore(MachineBasicBlock::iterator II,
- unsigned FrameIndex) const {
- MachineInstr &MI = *II; // <DestReg> = RESTORE_ACC <offset>
+/// lowerACCRestore - Generate the code to restore the accumulator register.
+void PPCRegisterInfo::lowerACCRestore(MachineBasicBlock::iterator II,
+ unsigned FrameIndex) const {
+ MachineInstr &MI = *II; // <DestReg> = RESTORE_ACC <offset>
MachineBasicBlock &MBB = *MI.getParent();
MachineFunction &MF = *MBB.getParent();
const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
- DebugLoc DL = MI.getDebugLoc();
+ DebugLoc DL = MI.getDebugLoc();
Register DestReg = MI.getOperand(0).getReg();
assert(MI.definesRegister(DestReg) &&
- "RESTORE_ACC does not define its destination");
-
- bool IsPrimed = PPC::ACCRCRegClass.contains(DestReg);
- Register Reg =
- PPC::VSRp0 + (DestReg - (IsPrimed ? PPC::ACC0 : PPC::UACC0)) * 2;
- bool IsLittleEndian = Subtarget.isLittleEndian();
-
- emitAccSpillRestoreInfo(MBB, IsPrimed, true);
-
- // Create two loads for the pair subregisters accounting for endianness and
- // then prime the accumulator register being restored.
- addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::LXVP), Reg),
- FrameIndex, IsLittleEndian ? 32 : 0);
- addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::LXVP), Reg + 1),
- FrameIndex, IsLittleEndian ? 0 : 32);
- if (IsPrimed)
- BuildMI(MBB, II, DL, TII.get(PPC::XXMTACC), DestReg).addReg(DestReg);
-
+ "RESTORE_ACC does not define its destination");
+
+ bool IsPrimed = PPC::ACCRCRegClass.contains(DestReg);
+ Register Reg =
+ PPC::VSRp0 + (DestReg - (IsPrimed ? PPC::ACC0 : PPC::UACC0)) * 2;
+ bool IsLittleEndian = Subtarget.isLittleEndian();
+
+ emitAccSpillRestoreInfo(MBB, IsPrimed, true);
+
+ // Create two loads for the pair subregisters accounting for endianness and
+ // then prime the accumulator register being restored.
+ addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::LXVP), Reg),
+ FrameIndex, IsLittleEndian ? 32 : 0);
+ addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::LXVP), Reg + 1),
+ FrameIndex, IsLittleEndian ? 0 : 32);
+ if (IsPrimed)
+ BuildMI(MBB, II, DL, TII.get(PPC::XXMTACC), DestReg).addReg(DestReg);
+
// Discard the pseudo instruction.
MBB.erase(II);
}
@@ -1194,11 +1194,11 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
} else if (OpC == PPC::RESTORE_CRBIT) {
lowerCRBitRestore(II, FrameIndex);
return;
- } else if (OpC == PPC::SPILL_ACC || OpC == PPC::SPILL_UACC) {
- lowerACCSpilling(II, FrameIndex);
+ } else if (OpC == PPC::SPILL_ACC || OpC == PPC::SPILL_UACC) {
+ lowerACCSpilling(II, FrameIndex);
return;
- } else if (OpC == PPC::RESTORE_ACC || OpC == PPC::RESTORE_UACC) {
- lowerACCRestore(II, FrameIndex);
+ } else if (OpC == PPC::RESTORE_ACC || OpC == PPC::RESTORE_UACC) {
+ lowerACCRestore(II, FrameIndex);
return;
}
@@ -1375,9 +1375,9 @@ needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const {
/// Insert defining instruction(s) for BaseReg to
/// be a pointer to FrameIdx at the beginning of the basic block.
-Register PPCRegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,
- int FrameIdx,
- int64_t Offset) const {
+Register PPCRegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,
+ int FrameIdx,
+ int64_t Offset) const {
unsigned ADDriOpc = TM.isPPC64() ? PPC::ADDI8 : PPC::ADDI;
MachineBasicBlock::iterator Ins = MBB->begin();
@@ -1390,14 +1390,14 @@ Register PPCRegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,
const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
const MCInstrDesc &MCID = TII.get(ADDriOpc);
MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
- const TargetRegisterClass *RC = getPointerRegClass(MF);
- Register BaseReg = MRI.createVirtualRegister(RC);
+ const TargetRegisterClass *RC = getPointerRegClass(MF);
+ Register BaseReg = MRI.createVirtualRegister(RC);
MRI.constrainRegClass(BaseReg, TII.getRegClass(MCID, 0, this, MF));
BuildMI(*MBB, Ins, DL, MCID, BaseReg)
.addFrameIndex(FrameIdx).addImm(Offset);
-
- return BaseReg;
+
+ return BaseReg;
}
void PPCRegisterInfo::resolveFrameIndex(MachineInstr &MI, Register BaseReg,
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCRegisterInfo.h b/contrib/libs/llvm12/lib/Target/PowerPC/PPCRegisterInfo.h
index e1785c512a..93f330ab56 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCRegisterInfo.h
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCRegisterInfo.h
@@ -120,14 +120,14 @@ public:
void lowerCRBitRestore(MachineBasicBlock::iterator II,
unsigned FrameIndex) const;
- void lowerACCSpilling(MachineBasicBlock::iterator II,
- unsigned FrameIndex) const;
- void lowerACCRestore(MachineBasicBlock::iterator II,
- unsigned FrameIndex) const;
-
- static void emitAccCopyInfo(MachineBasicBlock &MBB, MCRegister DestReg,
- MCRegister SrcReg);
-
+ void lowerACCSpilling(MachineBasicBlock::iterator II,
+ unsigned FrameIndex) const;
+ void lowerACCRestore(MachineBasicBlock::iterator II,
+ unsigned FrameIndex) const;
+
+ static void emitAccCopyInfo(MachineBasicBlock &MBB, MCRegister DestReg,
+ MCRegister SrcReg);
+
bool hasReservedSpillSlot(const MachineFunction &MF, Register Reg,
int &FrameIdx) const override;
void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
@@ -136,8 +136,8 @@ public:
// Support for virtual base registers.
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
- Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx,
- int64_t Offset) const override;
+ Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx,
+ int64_t Offset) const override;
void resolveFrameIndex(MachineInstr &MI, Register BaseReg,
int64_t Offset) const override;
bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg,
@@ -154,18 +154,18 @@ public:
/// register name so that only the number is left. Used by for linux asm.
static const char *stripRegisterPrefix(const char *RegName) {
switch (RegName[0]) {
- case 'a':
- if (RegName[1] == 'c' && RegName[2] == 'c')
- return RegName + 3;
- break;
+ case 'a':
+ if (RegName[1] == 'c' && RegName[2] == 'c')
+ return RegName + 3;
+ break;
case 'r':
case 'f':
case 'v':
- if (RegName[1] == 's') {
- if (RegName[2] == 'p')
- return RegName + 3;
+ if (RegName[1] == 's') {
+ if (RegName[2] == 'p')
+ return RegName + 3;
return RegName + 2;
- }
+ }
return RegName + 1;
case 'c': if (RegName[1] == 'r') return RegName + 2;
}
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCRegisterInfo.td b/contrib/libs/llvm12/lib/Target/PowerPC/PPCRegisterInfo.td
index 4a01821b19..551735c85b 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCRegisterInfo.td
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCRegisterInfo.td
@@ -16,10 +16,10 @@ def sub_eq : SubRegIndex<1, 2>;
def sub_un : SubRegIndex<1, 3>;
def sub_32 : SubRegIndex<32>;
def sub_64 : SubRegIndex<64>;
-def sub_vsx0 : SubRegIndex<128>;
-def sub_vsx1 : SubRegIndex<128, 128>;
-def sub_pair0 : SubRegIndex<256>;
-def sub_pair1 : SubRegIndex<256, 256>;
+def sub_vsx0 : SubRegIndex<128>;
+def sub_vsx1 : SubRegIndex<128, 128>;
+def sub_pair0 : SubRegIndex<256>;
+def sub_pair1 : SubRegIndex<256, 256>;
}
@@ -98,27 +98,27 @@ class CRBIT<bits<5> num, string n> : PPCReg<n> {
let HWEncoding{4-0} = num;
}
-// ACC - One of the 8 512-bit VSX accumulators.
-class ACC<bits<3> num, string n, list<Register> subregs> : PPCReg<n> {
- let HWEncoding{2-0} = num;
- let SubRegs = subregs;
-}
-
-// UACC - One of the 8 512-bit VSX accumulators prior to being primed.
-// Without using this register class, the register allocator has no way to
-// differentiate a primed accumulator from an unprimed accumulator.
-// This may result in invalid copies between primed and unprimed accumulators.
-class UACC<bits<3> num, string n, list<Register> subregs> : PPCReg<n> {
- let HWEncoding{2-0} = num;
- let SubRegs = subregs;
-}
-
-// VSR Pairs - One of the 32 paired even-odd consecutive VSRs.
-class VSRPair<bits<5> num, string n, list<Register> subregs> : PPCReg<n> {
- let HWEncoding{4-0} = num;
- let SubRegs = subregs;
-}
-
+// ACC - One of the 8 512-bit VSX accumulators.
+class ACC<bits<3> num, string n, list<Register> subregs> : PPCReg<n> {
+ let HWEncoding{2-0} = num;
+ let SubRegs = subregs;
+}
+
+// UACC - One of the 8 512-bit VSX accumulators prior to being primed.
+// Without using this register class, the register allocator has no way to
+// differentiate a primed accumulator from an unprimed accumulator.
+// This may result in invalid copies between primed and unprimed accumulators.
+class UACC<bits<3> num, string n, list<Register> subregs> : PPCReg<n> {
+ let HWEncoding{2-0} = num;
+ let SubRegs = subregs;
+}
+
+// VSR Pairs - One of the 32 paired even-odd consecutive VSRs.
+class VSRPair<bits<5> num, string n, list<Register> subregs> : PPCReg<n> {
+ let HWEncoding{4-0} = num;
+ let SubRegs = subregs;
+}
+
// General-purpose registers
foreach Index = 0-31 in {
def R#Index : GPR<Index, "r"#Index>, DwarfRegNum<[-2, Index]>;
@@ -168,23 +168,23 @@ foreach Index = 32-63 in {
def VSX#Index : VSXReg<Index, "vs"#Index>;
}
-let SubRegIndices = [sub_vsx0, sub_vsx1] in {
- // VSR pairs 0 - 15 (corresponding to VSRs 0 - 30 paired with 1 - 31).
- foreach Index = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 } in {
- def VSRp#!srl(Index, 1) : VSRPair<!srl(Index, 1), "vsp"#Index,
- [!cast<VSRL>("VSL"#Index), !cast<VSRL>("VSL"#!add(Index, 1))]>,
- DwarfRegNum<[-1, -1]>;
- }
-
- // VSR pairs 16 - 31 (corresponding to VSRs 32 - 62 paired with 33 - 63).
- foreach Index = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 } in {
- def VSRp#!add(!srl(Index, 1), 16) :
- VSRPair<!add(!srl(Index, 1), 16), "vsp"#!add(Index, 32),
- [!cast<VR>("V"#Index), !cast<VR>("V"#!add(Index, 1))]>,
- DwarfRegNum<[-1, -1]>;
- }
-}
-
+let SubRegIndices = [sub_vsx0, sub_vsx1] in {
+ // VSR pairs 0 - 15 (corresponding to VSRs 0 - 30 paired with 1 - 31).
+ foreach Index = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 } in {
+ def VSRp#!srl(Index, 1) : VSRPair<!srl(Index, 1), "vsp"#Index,
+ [!cast<VSRL>("VSL"#Index), !cast<VSRL>("VSL"#!add(Index, 1))]>,
+ DwarfRegNum<[-1, -1]>;
+ }
+
+ // VSR pairs 16 - 31 (corresponding to VSRs 32 - 62 paired with 33 - 63).
+ foreach Index = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 } in {
+ def VSRp#!add(!srl(Index, 1), 16) :
+ VSRPair<!add(!srl(Index, 1), 16), "vsp"#!add(Index, 32),
+ [!cast<VR>("V"#Index), !cast<VR>("V"#!add(Index, 1))]>,
+ DwarfRegNum<[-1, -1]>;
+ }
+}
+
// The representation of r0 when treated as the constant 0.
def ZERO : GPR<0, "0">, DwarfRegAlias<R0>;
def ZERO8 : GP8<ZERO, "0">, DwarfRegAlias<X0>;
@@ -409,56 +409,56 @@ def CTRRC8 : RegisterClass<"PPC", [i64], 64, (add CTR8)> {
let isAllocatable = 0;
}
-def LRRC : RegisterClass<"PPC", [i32], 32, (add LR)> {
- let isAllocatable = 0;
-}
-def LR8RC : RegisterClass<"PPC", [i64], 64, (add LR8)> {
- let isAllocatable = 0;
-}
-
+def LRRC : RegisterClass<"PPC", [i32], 32, (add LR)> {
+ let isAllocatable = 0;
+}
+def LR8RC : RegisterClass<"PPC", [i64], 64, (add LR8)> {
+ let isAllocatable = 0;
+}
+
def VRSAVERC : RegisterClass<"PPC", [i32], 32, (add VRSAVE)>;
def CARRYRC : RegisterClass<"PPC", [i32], 32, (add CARRY, XER)> {
let CopyCost = -1;
}
-let SubRegIndices = [sub_pair0, sub_pair1] in {
- def ACC0 : ACC<0, "acc0", [VSRp0, VSRp1]>, DwarfRegNum<[-1, -1]>;
- def ACC1 : ACC<1, "acc1", [VSRp2, VSRp3]>, DwarfRegNum<[-1, -1]>;
- def ACC2 : ACC<2, "acc2", [VSRp4, VSRp5]>, DwarfRegNum<[-1, -1]>;
- def ACC3 : ACC<3, "acc3", [VSRp6, VSRp7]>, DwarfRegNum<[-1, -1]>;
- def ACC4 : ACC<4, "acc4", [VSRp8, VSRp9]>, DwarfRegNum<[-1, -1]>;
- def ACC5 : ACC<5, "acc5", [VSRp10, VSRp11]>, DwarfRegNum<[-1, -1]>;
- def ACC6 : ACC<6, "acc6", [VSRp12, VSRp13]>, DwarfRegNum<[-1, -1]>;
- def ACC7 : ACC<7, "acc7", [VSRp14, VSRp15]>, DwarfRegNum<[-1, -1]>;
-}
-def ACCRC : RegisterClass<"PPC", [v512i1], 128, (add ACC0, ACC1, ACC2, ACC3,
- ACC4, ACC5, ACC6, ACC7)> {
- let Size = 512;
-}
-
-let SubRegIndices = [sub_pair0, sub_pair1] in {
- def UACC0 : UACC<0, "acc0", [VSRp0, VSRp1]>, DwarfRegNum<[-1, -1]>;
- def UACC1 : UACC<1, "acc1", [VSRp2, VSRp3]>, DwarfRegNum<[-1, -1]>;
- def UACC2 : UACC<2, "acc2", [VSRp4, VSRp5]>, DwarfRegNum<[-1, -1]>;
- def UACC3 : UACC<3, "acc3", [VSRp6, VSRp7]>, DwarfRegNum<[-1, -1]>;
- def UACC4 : UACC<4, "acc4", [VSRp8, VSRp9]>, DwarfRegNum<[-1, -1]>;
- def UACC5 : UACC<5, "acc5", [VSRp10, VSRp11]>, DwarfRegNum<[-1, -1]>;
- def UACC6 : UACC<6, "acc6", [VSRp12, VSRp13]>, DwarfRegNum<[-1, -1]>;
- def UACC7 : UACC<7, "acc7", [VSRp14, VSRp15]>, DwarfRegNum<[-1, -1]>;
-}
-def UACCRC : RegisterClass<"PPC", [v512i1], 128,
- (add UACC0, UACC1, UACC2, UACC3,
- UACC4, UACC5, UACC6, UACC7)> {
- let Size = 512;
-}
-
-// Allocate in the same order as the underlying VSX registers.
-def VSRpRC :
- RegisterClass<"PPC", [v256i1], 128,
- (add (sequence "VSRp%u", 0, 6),
- (sequence "VSRp%u", 15, 7), VSRp17, VSRp18,
- VSRp16, VSRp19, VSRp20, VSRp21, VSRp22, VSRp23,
- VSRp24, VSRp25, VSRp31, VSRp30, VSRp29, VSRp28,
- VSRp27, VSRp26)> {
- let Size = 256;
-}
+let SubRegIndices = [sub_pair0, sub_pair1] in {
+ def ACC0 : ACC<0, "acc0", [VSRp0, VSRp1]>, DwarfRegNum<[-1, -1]>;
+ def ACC1 : ACC<1, "acc1", [VSRp2, VSRp3]>, DwarfRegNum<[-1, -1]>;
+ def ACC2 : ACC<2, "acc2", [VSRp4, VSRp5]>, DwarfRegNum<[-1, -1]>;
+ def ACC3 : ACC<3, "acc3", [VSRp6, VSRp7]>, DwarfRegNum<[-1, -1]>;
+ def ACC4 : ACC<4, "acc4", [VSRp8, VSRp9]>, DwarfRegNum<[-1, -1]>;
+ def ACC5 : ACC<5, "acc5", [VSRp10, VSRp11]>, DwarfRegNum<[-1, -1]>;
+ def ACC6 : ACC<6, "acc6", [VSRp12, VSRp13]>, DwarfRegNum<[-1, -1]>;
+ def ACC7 : ACC<7, "acc7", [VSRp14, VSRp15]>, DwarfRegNum<[-1, -1]>;
+}
+def ACCRC : RegisterClass<"PPC", [v512i1], 128, (add ACC0, ACC1, ACC2, ACC3,
+ ACC4, ACC5, ACC6, ACC7)> {
+ let Size = 512;
+}
+
+let SubRegIndices = [sub_pair0, sub_pair1] in {
+ def UACC0 : UACC<0, "acc0", [VSRp0, VSRp1]>, DwarfRegNum<[-1, -1]>;
+ def UACC1 : UACC<1, "acc1", [VSRp2, VSRp3]>, DwarfRegNum<[-1, -1]>;
+ def UACC2 : UACC<2, "acc2", [VSRp4, VSRp5]>, DwarfRegNum<[-1, -1]>;
+ def UACC3 : UACC<3, "acc3", [VSRp6, VSRp7]>, DwarfRegNum<[-1, -1]>;
+ def UACC4 : UACC<4, "acc4", [VSRp8, VSRp9]>, DwarfRegNum<[-1, -1]>;
+ def UACC5 : UACC<5, "acc5", [VSRp10, VSRp11]>, DwarfRegNum<[-1, -1]>;
+ def UACC6 : UACC<6, "acc6", [VSRp12, VSRp13]>, DwarfRegNum<[-1, -1]>;
+ def UACC7 : UACC<7, "acc7", [VSRp14, VSRp15]>, DwarfRegNum<[-1, -1]>;
+}
+def UACCRC : RegisterClass<"PPC", [v512i1], 128,
+ (add UACC0, UACC1, UACC2, UACC3,
+ UACC4, UACC5, UACC6, UACC7)> {
+ let Size = 512;
+}
+
+// Allocate in the same order as the underlying VSX registers.
+def VSRpRC :
+ RegisterClass<"PPC", [v256i1], 128,
+ (add (sequence "VSRp%u", 0, 6),
+ (sequence "VSRp%u", 15, 7), VSRp17, VSRp18,
+ VSRp16, VSRp19, VSRp20, VSRp21, VSRp22, VSRp23,
+ VSRp24, VSRp25, VSRp31, VSRp30, VSRp29, VSRp28,
+ VSRp27, VSRp26)> {
+ let Size = 256;
+}
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCScheduleP9.td b/contrib/libs/llvm12/lib/Target/PowerPC/PPCScheduleP9.td
index 598d6e4c3b..571cc219ff 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCScheduleP9.td
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCScheduleP9.td
@@ -40,11 +40,11 @@ def P9Model : SchedMachineModel {
let CompleteModel = 1;
- // Do not support SPE (Signal Processing Engine), prefixed instructions on
- // Power 9, paired vector mem ops, MMA, PC relative mem ops, or instructions
- // introduced in ISA 3.1.
- let UnsupportedFeatures = [HasSPE, PrefixInstrs, PairedVectorMemops, MMA,
- PCRelativeMemops, IsISA3_1];
+ // Do not support SPE (Signal Processing Engine), prefixed instructions on
+ // Power 9, paired vector mem ops, MMA, PC relative mem ops, or instructions
+ // introduced in ISA 3.1.
+ let UnsupportedFeatures = [HasSPE, PrefixInstrs, PairedVectorMemops, MMA,
+ PCRelativeMemops, IsISA3_1];
}
let SchedModel = P9Model in {
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCSubtarget.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCSubtarget.cpp
index 1ec28066dc..d31195f67e 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCSubtarget.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCSubtarget.cpp
@@ -11,13 +11,13 @@
//===----------------------------------------------------------------------===//
#include "PPCSubtarget.h"
-#include "GISel/PPCCallLowering.h"
-#include "GISel/PPCLegalizerInfo.h"
-#include "GISel/PPCRegisterBankInfo.h"
+#include "GISel/PPCCallLowering.h"
+#include "GISel/PPCLegalizerInfo.h"
+#include "GISel/PPCRegisterBankInfo.h"
#include "PPC.h"
#include "PPCRegisterInfo.h"
#include "PPCTargetMachine.h"
-#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
+#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineScheduler.h"
#include "llvm/IR/Attributes.h"
@@ -53,20 +53,20 @@ PPCSubtarget &PPCSubtarget::initializeSubtargetDependencies(StringRef CPU,
PPCSubtarget::PPCSubtarget(const Triple &TT, const std::string &CPU,
const std::string &FS, const PPCTargetMachine &TM)
- : PPCGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), TargetTriple(TT),
+ : PPCGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), TargetTriple(TT),
IsPPC64(TargetTriple.getArch() == Triple::ppc64 ||
TargetTriple.getArch() == Triple::ppc64le),
TM(TM), FrameLowering(initializeSubtargetDependencies(CPU, FS)),
- InstrInfo(*this), TLInfo(TM, *this) {
- CallLoweringInfo.reset(new PPCCallLowering(*getTargetLowering()));
- Legalizer.reset(new PPCLegalizerInfo(*this));
- auto *RBI = new PPCRegisterBankInfo(*getRegisterInfo());
- RegBankInfo.reset(RBI);
-
- InstSelector.reset(createPPCInstructionSelector(
- *static_cast<const PPCTargetMachine *>(&TM), *this, *RBI));
-}
-
+ InstrInfo(*this), TLInfo(TM, *this) {
+ CallLoweringInfo.reset(new PPCCallLowering(*getTargetLowering()));
+ Legalizer.reset(new PPCLegalizerInfo(*this));
+ auto *RBI = new PPCRegisterBankInfo(*getRegisterInfo());
+ RegBankInfo.reset(RBI);
+
+ InstSelector.reset(createPPCInstructionSelector(
+ *static_cast<const PPCTargetMachine *>(&TM), *this, *RBI));
+}
+
void PPCSubtarget::initializeEnvironment() {
StackAlignment = Align(16);
CPUDirective = PPC::DIR_NONE;
@@ -77,7 +77,7 @@ void PPCSubtarget::initializeEnvironment() {
HasHardFloat = false;
HasAltivec = false;
HasSPE = false;
- HasEFPU2 = false;
+ HasEFPU2 = false;
HasFPU = false;
HasVSX = false;
NeedsTwoConstNR = false;
@@ -86,7 +86,7 @@ void PPCSubtarget::initializeEnvironment() {
HasP8Crypto = false;
HasP9Vector = false;
HasP9Altivec = false;
- HasMMA = false;
+ HasMMA = false;
HasP10Vector = false;
HasPrefixInstrs = false;
HasPCRelativeMemops = false;
@@ -121,7 +121,7 @@ void PPCSubtarget::initializeEnvironment() {
HasHTM = false;
HasFloat128 = false;
HasFusion = false;
- HasStoreFusion = false;
+ HasStoreFusion = false;
HasAddiLoadFusion = false;
HasAddisLoadFusion = false;
IsISA3_0 = false;
@@ -131,10 +131,10 @@ void PPCSubtarget::initializeEnvironment() {
VectorsUseTwoUnits = false;
UsePPCPreRASchedStrategy = false;
UsePPCPostRASchedStrategy = false;
- PairedVectorMemops = false;
+ PairedVectorMemops = false;
PredictableSelectIsExpensive = false;
- HasModernAIXAs = false;
- IsAIX = false;
+ HasModernAIXAs = false;
+ IsAIX = false;
HasPOPCNTD = POPCNTD_Unavailable;
}
@@ -156,7 +156,7 @@ void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
InstrItins = getInstrItineraryForCPU(CPUName);
// Parse features string.
- ParseSubtargetFeatures(CPUName, /*TuneCPU*/ CPUName, FS);
+ ParseSubtargetFeatures(CPUName, /*TuneCPU*/ CPUName, FS);
// If the user requested use of 64-bit regs, but the cpu selected doesn't
// support it, ignore.
@@ -170,7 +170,7 @@ void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
if (HasSPE && IsPPC64)
report_fatal_error( "SPE is only supported for 32-bit targets.\n", false);
- if (HasSPE && (HasAltivec || HasVSX || HasFPU))
+ if (HasSPE && (HasAltivec || HasVSX || HasFPU))
report_fatal_error(
"SPE and traditional floating point cannot both be enabled.\n", false);
@@ -182,8 +182,8 @@ void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
// Determine endianness.
// FIXME: Part of the TargetMachine.
- IsLittleEndian = (TargetTriple.getArch() == Triple::ppc64le ||
- TargetTriple.getArch() == Triple::ppcle);
+ IsLittleEndian = (TargetTriple.getArch() == Triple::ppc64le ||
+ TargetTriple.getArch() == Triple::ppcle);
}
bool PPCSubtarget::enableMachineScheduler() const { return true; }
@@ -244,20 +244,20 @@ bool PPCSubtarget::isUsingPCRelativeCalls() const {
return isPPC64() && hasPCRelativeMemops() && isELFv2ABI() &&
CodeModel::Medium == getTargetMachine().getCodeModel();
}
-
-// GlobalISEL
-const CallLowering *PPCSubtarget::getCallLowering() const {
- return CallLoweringInfo.get();
-}
-
-const RegisterBankInfo *PPCSubtarget::getRegBankInfo() const {
- return RegBankInfo.get();
-}
-
-const LegalizerInfo *PPCSubtarget::getLegalizerInfo() const {
- return Legalizer.get();
-}
-
-InstructionSelector *PPCSubtarget::getInstructionSelector() const {
- return InstSelector.get();
-}
+
+// GlobalISEL
+const CallLowering *PPCSubtarget::getCallLowering() const {
+ return CallLoweringInfo.get();
+}
+
+const RegisterBankInfo *PPCSubtarget::getRegBankInfo() const {
+ return RegBankInfo.get();
+}
+
+const LegalizerInfo *PPCSubtarget::getLegalizerInfo() const {
+ return Legalizer.get();
+}
+
+InstructionSelector *PPCSubtarget::getInstructionSelector() const {
+ return InstSelector.get();
+}
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCSubtarget.h b/contrib/libs/llvm12/lib/Target/PowerPC/PPCSubtarget.h
index 17de081c39..50d89390d5 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCSubtarget.h
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCSubtarget.h
@@ -17,9 +17,9 @@
#include "PPCISelLowering.h"
#include "PPCInstrInfo.h"
#include "llvm/ADT/Triple.h"
-#include "llvm/CodeGen/GlobalISel/CallLowering.h"
-#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
-#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
+#include "llvm/CodeGen/GlobalISel/CallLowering.h"
+#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
+#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DataLayout.h"
@@ -100,7 +100,7 @@ protected:
bool HasAltivec;
bool HasFPU;
bool HasSPE;
- bool HasEFPU2;
+ bool HasEFPU2;
bool HasVSX;
bool NeedsTwoConstNR;
bool HasP8Vector;
@@ -111,7 +111,7 @@ protected:
bool HasP10Vector;
bool HasPrefixInstrs;
bool HasPCRelativeMemops;
- bool HasMMA;
+ bool HasMMA;
bool HasFCPSGN;
bool HasFSQRT;
bool HasFRE, HasFRES, HasFRSQRTE, HasFRSQRTES;
@@ -141,7 +141,7 @@ protected:
bool HasHTM;
bool HasFloat128;
bool HasFusion;
- bool HasStoreFusion;
+ bool HasStoreFusion;
bool HasAddiLoadFusion;
bool HasAddisLoadFusion;
bool IsISA3_0;
@@ -151,10 +151,10 @@ protected:
bool VectorsUseTwoUnits;
bool UsePPCPreRASchedStrategy;
bool UsePPCPostRASchedStrategy;
- bool PairedVectorMemops;
+ bool PairedVectorMemops;
bool PredictableSelectIsExpensive;
- bool HasModernAIXAs;
- bool IsAIX;
+ bool HasModernAIXAs;
+ bool IsAIX;
POPCNTDKind HasPOPCNTD;
@@ -164,12 +164,12 @@ protected:
PPCTargetLowering TLInfo;
SelectionDAGTargetInfo TSInfo;
- /// GlobalISel related APIs.
- std::unique_ptr<CallLowering> CallLoweringInfo;
- std::unique_ptr<LegalizerInfo> Legalizer;
- std::unique_ptr<RegisterBankInfo> RegBankInfo;
- std::unique_ptr<InstructionSelector> InstSelector;
-
+ /// GlobalISel related APIs.
+ std::unique_ptr<CallLowering> CallLoweringInfo;
+ std::unique_ptr<LegalizerInfo> Legalizer;
+ std::unique_ptr<RegisterBankInfo> RegBankInfo;
+ std::unique_ptr<InstructionSelector> InstSelector;
+
public:
/// This constructor initializes the data members to match that
/// of the specified triple.
@@ -179,7 +179,7 @@ public:
/// ParseSubtargetFeatures - Parses features string setting specified
/// subtarget options. Definition of function is auto generated by tblgen.
- void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
+ void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
/// getStackAlignment - Returns the minimum alignment known to hold of the
/// stack frame on entry to the function and which must be maintained by every
@@ -260,7 +260,7 @@ public:
bool hasFPCVT() const { return HasFPCVT; }
bool hasAltivec() const { return HasAltivec; }
bool hasSPE() const { return HasSPE; }
- bool hasEFPU2() const { return HasEFPU2; }
+ bool hasEFPU2() const { return HasEFPU2; }
bool hasFPU() const { return HasFPU; }
bool hasVSX() const { return HasVSX; }
bool needsTwoConstNR() const { return NeedsTwoConstNR; }
@@ -272,8 +272,8 @@ public:
bool hasP10Vector() const { return HasP10Vector; }
bool hasPrefixInstrs() const { return HasPrefixInstrs; }
bool hasPCRelativeMemops() const { return HasPCRelativeMemops; }
- bool hasMMA() const { return HasMMA; }
- bool pairedVectorMemops() const { return PairedVectorMemops; }
+ bool hasMMA() const { return HasMMA; }
+ bool pairedVectorMemops() const { return PairedVectorMemops; }
bool hasMFOCRF() const { return HasMFOCRF; }
bool hasISEL() const { return HasISEL; }
bool hasBPERMD() const { return HasBPERMD; }
@@ -319,7 +319,7 @@ public:
bool isISA3_1() const { return IsISA3_1; }
bool useLongCalls() const { return UseLongCalls; }
bool hasFusion() const { return HasFusion; }
- bool hasStoreFusion() const { return HasStoreFusion; }
+ bool hasStoreFusion() const { return HasStoreFusion; }
bool hasAddiLoadFusion() const { return HasAddiLoadFusion; }
bool hasAddisLoadFusion() const { return HasAddisLoadFusion; }
bool needsSwapsForVSXMemOps() const {
@@ -406,12 +406,12 @@ public:
bool isPredictableSelectIsExpensive() const {
return PredictableSelectIsExpensive;
}
-
- // GlobalISEL
- const CallLowering *getCallLowering() const override;
- const RegisterBankInfo *getRegBankInfo() const override;
- const LegalizerInfo *getLegalizerInfo() const override;
- InstructionSelector *getInstructionSelector() const override;
+
+ // GlobalISEL
+ const CallLowering *getCallLowering() const override;
+ const RegisterBankInfo *getRegBankInfo() const override;
+ const LegalizerInfo *getLegalizerInfo() const override;
+ InstructionSelector *getInstructionSelector() const override;
};
} // End llvm namespace
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCTLSDynamicCall.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCTLSDynamicCall.cpp
index ad88a87529..43dcc5844c 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCTLSDynamicCall.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCTLSDynamicCall.cpp
@@ -50,17 +50,17 @@ protected:
bool Changed = false;
bool NeedFence = true;
bool Is64Bit = MBB.getParent()->getSubtarget<PPCSubtarget>().isPPC64();
- bool IsPCREL = false;
+ bool IsPCREL = false;
for (MachineBasicBlock::iterator I = MBB.begin(), IE = MBB.end();
I != IE;) {
MachineInstr &MI = *I;
- IsPCREL = isPCREL(MI);
+ IsPCREL = isPCREL(MI);
if (MI.getOpcode() != PPC::ADDItlsgdLADDR &&
MI.getOpcode() != PPC::ADDItlsldLADDR &&
MI.getOpcode() != PPC::ADDItlsgdLADDR32 &&
- MI.getOpcode() != PPC::ADDItlsldLADDR32 && !IsPCREL) {
+ MI.getOpcode() != PPC::ADDItlsldLADDR32 && !IsPCREL) {
// Although we create ADJCALLSTACKDOWN and ADJCALLSTACKUP
// as scheduling fences, we skip creating fences if we already
// have existing ADJCALLSTACKDOWN/UP to avoid nesting,
@@ -77,15 +77,15 @@ protected:
LLVM_DEBUG(dbgs() << "TLS Dynamic Call Fixup:\n " << MI);
Register OutReg = MI.getOperand(0).getReg();
- Register InReg = PPC::NoRegister;
- Register GPR3 = Is64Bit ? PPC::X3 : PPC::R3;
- SmallVector<Register, 3> OrigRegs = {OutReg, GPR3};
- if (!IsPCREL) {
- InReg = MI.getOperand(1).getReg();
- OrigRegs.push_back(InReg);
- }
+ Register InReg = PPC::NoRegister;
+ Register GPR3 = Is64Bit ? PPC::X3 : PPC::R3;
+ SmallVector<Register, 3> OrigRegs = {OutReg, GPR3};
+ if (!IsPCREL) {
+ InReg = MI.getOperand(1).getReg();
+ OrigRegs.push_back(InReg);
+ }
DebugLoc DL = MI.getDebugLoc();
-
+
unsigned Opc1, Opc2;
switch (MI.getOpcode()) {
default:
@@ -106,13 +106,13 @@ protected:
Opc1 = PPC::ADDItlsldL32;
Opc2 = PPC::GETtlsldADDR32;
break;
- case PPC::PADDI8pc:
- assert(IsPCREL && "Expecting General/Local Dynamic PCRel");
- Opc1 = PPC::PADDI8pc;
- Opc2 = MI.getOperand(2).getTargetFlags() ==
- PPCII::MO_GOT_TLSGD_PCREL_FLAG
- ? PPC::GETtlsADDRPCREL
- : PPC::GETtlsldADDRPCREL;
+ case PPC::PADDI8pc:
+ assert(IsPCREL && "Expecting General/Local Dynamic PCRel");
+ Opc1 = PPC::PADDI8pc;
+ Opc2 = MI.getOperand(2).getTargetFlags() ==
+ PPCII::MO_GOT_TLSGD_PCREL_FLAG
+ ? PPC::GETtlsADDRPCREL
+ : PPC::GETtlsldADDRPCREL;
}
// We create ADJCALLSTACKUP and ADJCALLSTACKDOWN around _tls_get_addr
@@ -125,15 +125,15 @@ protected:
BuildMI(MBB, I, DL, TII->get(PPC::ADJCALLSTACKDOWN)).addImm(0)
.addImm(0);
- MachineInstr *Addi;
- if (IsPCREL) {
- Addi = BuildMI(MBB, I, DL, TII->get(Opc1), GPR3).addImm(0);
- } else {
- // Expand into two ops built prior to the existing instruction.
- assert(InReg != PPC::NoRegister && "Operand must be a register");
- Addi = BuildMI(MBB, I, DL, TII->get(Opc1), GPR3).addReg(InReg);
- }
-
+ MachineInstr *Addi;
+ if (IsPCREL) {
+ Addi = BuildMI(MBB, I, DL, TII->get(Opc1), GPR3).addImm(0);
+ } else {
+ // Expand into two ops built prior to the existing instruction.
+ assert(InReg != PPC::NoRegister && "Operand must be a register");
+ Addi = BuildMI(MBB, I, DL, TII->get(Opc1), GPR3).addReg(InReg);
+ }
+
Addi->addOperand(MI.getOperand(2));
// The ADDItls* instruction is the first instruction in the
@@ -143,10 +143,10 @@ protected:
MachineInstr *Call = (BuildMI(MBB, I, DL, TII->get(Opc2), GPR3)
.addReg(GPR3));
- if (IsPCREL)
- Call->addOperand(MI.getOperand(2));
- else
- Call->addOperand(MI.getOperand(3));
+ if (IsPCREL)
+ Call->addOperand(MI.getOperand(2));
+ else
+ Call->addOperand(MI.getOperand(3));
if (NeedFence)
BuildMI(MBB, I, DL, TII->get(PPC::ADJCALLSTACKUP)).addImm(0).addImm(0);
@@ -171,14 +171,14 @@ protected:
}
public:
- bool isPCREL(const MachineInstr &MI) {
- return (MI.getOpcode() == PPC::PADDI8pc) &&
- (MI.getOperand(2).getTargetFlags() ==
- PPCII::MO_GOT_TLSGD_PCREL_FLAG ||
- MI.getOperand(2).getTargetFlags() ==
- PPCII::MO_GOT_TLSLD_PCREL_FLAG);
- }
-
+ bool isPCREL(const MachineInstr &MI) {
+ return (MI.getOpcode() == PPC::PADDI8pc) &&
+ (MI.getOperand(2).getTargetFlags() ==
+ PPCII::MO_GOT_TLSGD_PCREL_FLAG ||
+ MI.getOperand(2).getTargetFlags() ==
+ PPCII::MO_GOT_TLSLD_PCREL_FLAG);
+ }
+
bool runOnMachineFunction(MachineFunction &MF) override {
TII = MF.getSubtarget<PPCSubtarget>().getInstrInfo();
LIS = &getAnalysis<LiveIntervals>();
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetMachine.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetMachine.cpp
index d9ffab3ceb..0634833e64 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetMachine.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetMachine.cpp
@@ -24,18 +24,18 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
-#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
-#include "llvm/CodeGen/GlobalISel/Legalizer.h"
-#include "llvm/CodeGen/GlobalISel/Localizer.h"
-#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
-#include "llvm/CodeGen/MachineScheduler.h"
+#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
+#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
+#include "llvm/CodeGen/GlobalISel/Legalizer.h"
+#include "llvm/CodeGen/GlobalISel/Localizer.h"
+#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
+#include "llvm/CodeGen/MachineScheduler.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
-#include "llvm/InitializePasses.h"
+#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/CommandLine.h"
@@ -100,9 +100,9 @@ static cl::opt<bool>
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTarget() {
// Register the targets
RegisterTargetMachine<PPCTargetMachine> A(getThePPC32Target());
- RegisterTargetMachine<PPCTargetMachine> B(getThePPC32LETarget());
- RegisterTargetMachine<PPCTargetMachine> C(getThePPC64Target());
- RegisterTargetMachine<PPCTargetMachine> D(getThePPC64LETarget());
+ RegisterTargetMachine<PPCTargetMachine> B(getThePPC32LETarget());
+ RegisterTargetMachine<PPCTargetMachine> C(getThePPC64Target());
+ RegisterTargetMachine<PPCTargetMachine> D(getThePPC64LETarget());
PassRegistry &PR = *PassRegistry::getPassRegistry();
#ifndef NDEBUG
@@ -123,7 +123,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTarget() {
initializePPCTLSDynamicCallPass(PR);
initializePPCMIPeepholePass(PR);
initializePPCLowerMASSVEntriesPass(PR);
- initializeGlobalISel(PR);
+ initializeGlobalISel(PR);
}
/// Return the datalayout string of a subtarget.
@@ -131,8 +131,8 @@ static std::string getDataLayoutString(const Triple &T) {
bool is64Bit = T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le;
std::string Ret;
- // Most PPC* platforms are big endian, PPC(64)LE is little endian.
- if (T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppcle)
+ // Most PPC* platforms are big endian, PPC(64)LE is little endian.
+ if (T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppcle)
Ret = "e";
else
Ret = "E";
@@ -146,7 +146,7 @@ static std::string getDataLayoutString(const Triple &T) {
// Note, the alignment values for f64 and i64 on ppc64 in Darwin
// documentation are wrong; these are correct (i.e. "what gcc does").
- Ret += "-i64:64";
+ Ret += "-i64:64";
// PPC64 has 32 and 64 bit registers, PPC32 has only 32 bit ones.
if (is64Bit)
@@ -154,13 +154,13 @@ static std::string getDataLayoutString(const Triple &T) {
else
Ret += "-n32";
- // Specify the vector alignment explicitly. For v256i1 and v512i1, the
- // calculated alignment would be 256*alignment(i1) and 512*alignment(i1),
- // which is 256 and 512 bytes - way over aligned.
- if ((T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppc64) &&
- (T.isOSAIX() || T.isOSLinux()))
- Ret += "-v256:256:256-v512:512:512";
-
+ // Specify the vector alignment explicitly. For v256i1 and v512i1, the
+ // calculated alignment would be 256*alignment(i1) and 512*alignment(i1),
+ // which is 256 and 512 bytes - way over aligned.
+ if ((T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppc64) &&
+ (T.isOSAIX() || T.isOSLinux()))
+ Ret += "-v256:256:256-v512:512:512";
+
return Ret;
}
@@ -190,13 +190,13 @@ static std::string computeFSAdditions(StringRef FS, CodeGenOpt::Level OL,
FullFS = "+invariant-function-descriptors";
}
- if (TT.isOSAIX()) {
- if (!FullFS.empty())
- FullFS = "+aix," + FullFS;
- else
- FullFS = "+aix";
- }
-
+ if (TT.isOSAIX()) {
+ if (!FullFS.empty())
+ FullFS = "+aix," + FullFS;
+ else
+ FullFS = "+aix";
+ }
+
return FullFS;
}
@@ -280,8 +280,8 @@ static ScheduleDAGInstrs *createPPCMachineScheduler(MachineSchedContext *C) {
std::make_unique<GenericScheduler>(C));
// add DAG Mutations here.
DAG->addMutation(createCopyConstrainDAGMutation(DAG->TII, DAG->TRI));
- if (ST.hasStoreFusion())
- DAG->addMutation(createStoreClusterDAGMutation(DAG->TII, DAG->TRI));
+ if (ST.hasStoreFusion())
+ DAG->addMutation(createStoreClusterDAGMutation(DAG->TII, DAG->TRI));
if (ST.hasFusion())
DAG->addMutation(createPowerPCMacroFusionDAGMutation());
@@ -296,8 +296,8 @@ static ScheduleDAGInstrs *createPPCPostMachineScheduler(
std::make_unique<PPCPostRASchedStrategy>(C) :
std::make_unique<PostGenericScheduler>(C), true);
// add DAG Mutations here.
- if (ST.hasStoreFusion())
- DAG->addMutation(createStoreClusterDAGMutation(DAG->TII, DAG->TRI));
+ if (ST.hasStoreFusion())
+ DAG->addMutation(createStoreClusterDAGMutation(DAG->TII, DAG->TRI));
if (ST.hasFusion())
DAG->addMutation(createPowerPCMacroFusionDAGMutation());
return DAG;
@@ -329,10 +329,10 @@ PPCTargetMachine::getSubtargetImpl(const Function &F) const {
Attribute CPUAttr = F.getFnAttribute("target-cpu");
Attribute FSAttr = F.getFnAttribute("target-features");
- std::string CPU =
- CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
- std::string FS =
- FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
+ std::string CPU =
+ CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
+ std::string FS =
+ FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
// FIXME: This is related to the code below to reset the target options,
// we need to know whether or not the soft float flag is set on the
@@ -394,12 +394,12 @@ public:
void addPreRegAlloc() override;
void addPreSched2() override;
void addPreEmitPass() override;
- // GlobalISEL
- bool addIRTranslator() override;
- bool addLegalizeMachineIR() override;
- bool addRegBankSelect() override;
- bool addGlobalInstructionSelect() override;
-
+ // GlobalISEL
+ bool addIRTranslator() override;
+ bool addLegalizeMachineIR() override;
+ bool addRegBankSelect() override;
+ bool addGlobalInstructionSelect() override;
+
ScheduleDAGInstrs *
createMachineScheduler(MachineSchedContext *C) const override {
return createPPCMachineScheduler(C);
@@ -423,8 +423,8 @@ void PPCPassConfig::addIRPasses() {
// Lower generic MASSV routines to PowerPC subtarget-specific entries.
addPass(createPPCLowerMASSVEntriesPass());
-
- // If explicitly requested, add explicit data prefetch intrinsics.
+
+ // If explicitly requested, add explicit data prefetch intrinsics.
if (EnablePrefetch.getNumOccurrences() > 0)
addPass(createLoopDataPrefetchPass());
@@ -522,7 +522,7 @@ void PPCPassConfig::addPreRegAlloc() {
}
void PPCPassConfig::addPreSched2() {
- if (getOptLevel() != CodeGenOpt::None)
+ if (getOptLevel() != CodeGenOpt::None)
addPass(&IfConverterID);
}
@@ -550,24 +550,24 @@ static MachineSchedRegistry
PPCPostRASchedRegistry("ppc-postra",
"Run PowerPC PostRA specific scheduler",
createPPCPostMachineScheduler);
-
-// Global ISEL
-bool PPCPassConfig::addIRTranslator() {
- addPass(new IRTranslator());
- return false;
-}
-
-bool PPCPassConfig::addLegalizeMachineIR() {
- addPass(new Legalizer());
- return false;
-}
-
-bool PPCPassConfig::addRegBankSelect() {
- addPass(new RegBankSelect());
- return false;
-}
-
-bool PPCPassConfig::addGlobalInstructionSelect() {
- addPass(new InstructionSelect());
- return false;
-}
+
+// Global ISEL
+bool PPCPassConfig::addIRTranslator() {
+ addPass(new IRTranslator());
+ return false;
+}
+
+bool PPCPassConfig::addLegalizeMachineIR() {
+ addPass(new Legalizer());
+ return false;
+}
+
+bool PPCPassConfig::addRegBankSelect() {
+ addPass(new RegBankSelect());
+ return false;
+}
+
+bool PPCPassConfig::addGlobalInstructionSelect() {
+ addPass(new InstructionSelect());
+ return false;
+}
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetMachine.h b/contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetMachine.h
index 347ce1fc83..21faa4e710 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetMachine.h
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetMachine.h
@@ -58,11 +58,11 @@ public:
const Triple &TT = getTargetTriple();
return (TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le);
};
-
- bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override {
- // Addrspacecasts are always noops.
- return true;
- }
+
+ bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override {
+ // Addrspacecasts are always noops.
+ return true;
+ }
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetTransformInfo.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetTransformInfo.cpp
index 9f100e63b0..c90ff8b7d5 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetTransformInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetTransformInfo.cpp
@@ -8,19 +8,19 @@
#include "PPCTargetTransformInfo.h"
#include "llvm/Analysis/CodeMetrics.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/CodeGen/BasicTTIImpl.h"
#include "llvm/CodeGen/CostTable.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetSchedule.h"
-#include "llvm/IR/IntrinsicsPowerPC.h"
+#include "llvm/IR/IntrinsicsPowerPC.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/KnownBits.h"
-#include "llvm/Transforms/InstCombine/InstCombiner.h"
-#include "llvm/Transforms/Utils/Local.h"
-
+#include "llvm/Support/KnownBits.h"
+#include "llvm/Transforms/InstCombine/InstCombiner.h"
+#include "llvm/Transforms/Utils/Local.h"
+
using namespace llvm;
#define DEBUG_TYPE "ppctti"
@@ -28,7 +28,7 @@ using namespace llvm;
static cl::opt<bool> DisablePPCConstHoist("disable-ppc-constant-hoisting",
cl::desc("disable constant hoisting on PPC"), cl::init(false), cl::Hidden);
-// This is currently only used for the data prefetch pass
+// This is currently only used for the data prefetch pass
static cl::opt<unsigned>
CacheLineSize("ppc-loop-prefetch-cache-line", cl::Hidden, cl::init(64),
cl::desc("The loop prefetch cache line size"));
@@ -64,109 +64,109 @@ PPCTTIImpl::getPopcntSupport(unsigned TyWidth) {
return TTI::PSK_Software;
}
-Optional<Instruction *>
-PPCTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
- Intrinsic::ID IID = II.getIntrinsicID();
- switch (IID) {
- default:
- break;
- case Intrinsic::ppc_altivec_lvx:
- case Intrinsic::ppc_altivec_lvxl:
- // Turn PPC lvx -> load if the pointer is known aligned.
- if (getOrEnforceKnownAlignment(
- II.getArgOperand(0), Align(16), IC.getDataLayout(), &II,
- &IC.getAssumptionCache(), &IC.getDominatorTree()) >= 16) {
- Value *Ptr = IC.Builder.CreateBitCast(
- II.getArgOperand(0), PointerType::getUnqual(II.getType()));
- return new LoadInst(II.getType(), Ptr, "", false, Align(16));
- }
- break;
- case Intrinsic::ppc_vsx_lxvw4x:
- case Intrinsic::ppc_vsx_lxvd2x: {
- // Turn PPC VSX loads into normal loads.
- Value *Ptr = IC.Builder.CreateBitCast(II.getArgOperand(0),
- PointerType::getUnqual(II.getType()));
- return new LoadInst(II.getType(), Ptr, Twine(""), false, Align(1));
- }
- case Intrinsic::ppc_altivec_stvx:
- case Intrinsic::ppc_altivec_stvxl:
- // Turn stvx -> store if the pointer is known aligned.
- if (getOrEnforceKnownAlignment(
- II.getArgOperand(1), Align(16), IC.getDataLayout(), &II,
- &IC.getAssumptionCache(), &IC.getDominatorTree()) >= 16) {
- Type *OpPtrTy = PointerType::getUnqual(II.getArgOperand(0)->getType());
- Value *Ptr = IC.Builder.CreateBitCast(II.getArgOperand(1), OpPtrTy);
- return new StoreInst(II.getArgOperand(0), Ptr, false, Align(16));
- }
- break;
- case Intrinsic::ppc_vsx_stxvw4x:
- case Intrinsic::ppc_vsx_stxvd2x: {
- // Turn PPC VSX stores into normal stores.
- Type *OpPtrTy = PointerType::getUnqual(II.getArgOperand(0)->getType());
- Value *Ptr = IC.Builder.CreateBitCast(II.getArgOperand(1), OpPtrTy);
- return new StoreInst(II.getArgOperand(0), Ptr, false, Align(1));
- }
- case Intrinsic::ppc_altivec_vperm:
- // Turn vperm(V1,V2,mask) -> shuffle(V1,V2,mask) if mask is a constant.
- // Note that ppc_altivec_vperm has a big-endian bias, so when creating
- // a vectorshuffle for little endian, we must undo the transformation
- // performed on vec_perm in altivec.h. That is, we must complement
- // the permutation mask with respect to 31 and reverse the order of
- // V1 and V2.
- if (Constant *Mask = dyn_cast<Constant>(II.getArgOperand(2))) {
- assert(cast<FixedVectorType>(Mask->getType())->getNumElements() == 16 &&
- "Bad type for intrinsic!");
-
- // Check that all of the elements are integer constants or undefs.
- bool AllEltsOk = true;
- for (unsigned i = 0; i != 16; ++i) {
- Constant *Elt = Mask->getAggregateElement(i);
- if (!Elt || !(isa<ConstantInt>(Elt) || isa<UndefValue>(Elt))) {
- AllEltsOk = false;
- break;
- }
- }
-
- if (AllEltsOk) {
- // Cast the input vectors to byte vectors.
- Value *Op0 =
- IC.Builder.CreateBitCast(II.getArgOperand(0), Mask->getType());
- Value *Op1 =
- IC.Builder.CreateBitCast(II.getArgOperand(1), Mask->getType());
- Value *Result = UndefValue::get(Op0->getType());
-
- // Only extract each element once.
- Value *ExtractedElts[32];
- memset(ExtractedElts, 0, sizeof(ExtractedElts));
-
- for (unsigned i = 0; i != 16; ++i) {
- if (isa<UndefValue>(Mask->getAggregateElement(i)))
- continue;
- unsigned Idx =
- cast<ConstantInt>(Mask->getAggregateElement(i))->getZExtValue();
- Idx &= 31; // Match the hardware behavior.
- if (DL.isLittleEndian())
- Idx = 31 - Idx;
-
- if (!ExtractedElts[Idx]) {
- Value *Op0ToUse = (DL.isLittleEndian()) ? Op1 : Op0;
- Value *Op1ToUse = (DL.isLittleEndian()) ? Op0 : Op1;
- ExtractedElts[Idx] = IC.Builder.CreateExtractElement(
- Idx < 16 ? Op0ToUse : Op1ToUse, IC.Builder.getInt32(Idx & 15));
- }
-
- // Insert this value into the result vector.
- Result = IC.Builder.CreateInsertElement(Result, ExtractedElts[Idx],
- IC.Builder.getInt32(i));
- }
- return CastInst::Create(Instruction::BitCast, Result, II.getType());
- }
- }
- break;
- }
- return None;
-}
-
+Optional<Instruction *>
+PPCTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
+ Intrinsic::ID IID = II.getIntrinsicID();
+ switch (IID) {
+ default:
+ break;
+ case Intrinsic::ppc_altivec_lvx:
+ case Intrinsic::ppc_altivec_lvxl:
+ // Turn PPC lvx -> load if the pointer is known aligned.
+ if (getOrEnforceKnownAlignment(
+ II.getArgOperand(0), Align(16), IC.getDataLayout(), &II,
+ &IC.getAssumptionCache(), &IC.getDominatorTree()) >= 16) {
+ Value *Ptr = IC.Builder.CreateBitCast(
+ II.getArgOperand(0), PointerType::getUnqual(II.getType()));
+ return new LoadInst(II.getType(), Ptr, "", false, Align(16));
+ }
+ break;
+ case Intrinsic::ppc_vsx_lxvw4x:
+ case Intrinsic::ppc_vsx_lxvd2x: {
+ // Turn PPC VSX loads into normal loads.
+ Value *Ptr = IC.Builder.CreateBitCast(II.getArgOperand(0),
+ PointerType::getUnqual(II.getType()));
+ return new LoadInst(II.getType(), Ptr, Twine(""), false, Align(1));
+ }
+ case Intrinsic::ppc_altivec_stvx:
+ case Intrinsic::ppc_altivec_stvxl:
+ // Turn stvx -> store if the pointer is known aligned.
+ if (getOrEnforceKnownAlignment(
+ II.getArgOperand(1), Align(16), IC.getDataLayout(), &II,
+ &IC.getAssumptionCache(), &IC.getDominatorTree()) >= 16) {
+ Type *OpPtrTy = PointerType::getUnqual(II.getArgOperand(0)->getType());
+ Value *Ptr = IC.Builder.CreateBitCast(II.getArgOperand(1), OpPtrTy);
+ return new StoreInst(II.getArgOperand(0), Ptr, false, Align(16));
+ }
+ break;
+ case Intrinsic::ppc_vsx_stxvw4x:
+ case Intrinsic::ppc_vsx_stxvd2x: {
+ // Turn PPC VSX stores into normal stores.
+ Type *OpPtrTy = PointerType::getUnqual(II.getArgOperand(0)->getType());
+ Value *Ptr = IC.Builder.CreateBitCast(II.getArgOperand(1), OpPtrTy);
+ return new StoreInst(II.getArgOperand(0), Ptr, false, Align(1));
+ }
+ case Intrinsic::ppc_altivec_vperm:
+ // Turn vperm(V1,V2,mask) -> shuffle(V1,V2,mask) if mask is a constant.
+ // Note that ppc_altivec_vperm has a big-endian bias, so when creating
+ // a vectorshuffle for little endian, we must undo the transformation
+ // performed on vec_perm in altivec.h. That is, we must complement
+ // the permutation mask with respect to 31 and reverse the order of
+ // V1 and V2.
+ if (Constant *Mask = dyn_cast<Constant>(II.getArgOperand(2))) {
+ assert(cast<FixedVectorType>(Mask->getType())->getNumElements() == 16 &&
+ "Bad type for intrinsic!");
+
+ // Check that all of the elements are integer constants or undefs.
+ bool AllEltsOk = true;
+ for (unsigned i = 0; i != 16; ++i) {
+ Constant *Elt = Mask->getAggregateElement(i);
+ if (!Elt || !(isa<ConstantInt>(Elt) || isa<UndefValue>(Elt))) {
+ AllEltsOk = false;
+ break;
+ }
+ }
+
+ if (AllEltsOk) {
+ // Cast the input vectors to byte vectors.
+ Value *Op0 =
+ IC.Builder.CreateBitCast(II.getArgOperand(0), Mask->getType());
+ Value *Op1 =
+ IC.Builder.CreateBitCast(II.getArgOperand(1), Mask->getType());
+ Value *Result = UndefValue::get(Op0->getType());
+
+ // Only extract each element once.
+ Value *ExtractedElts[32];
+ memset(ExtractedElts, 0, sizeof(ExtractedElts));
+
+ for (unsigned i = 0; i != 16; ++i) {
+ if (isa<UndefValue>(Mask->getAggregateElement(i)))
+ continue;
+ unsigned Idx =
+ cast<ConstantInt>(Mask->getAggregateElement(i))->getZExtValue();
+ Idx &= 31; // Match the hardware behavior.
+ if (DL.isLittleEndian())
+ Idx = 31 - Idx;
+
+ if (!ExtractedElts[Idx]) {
+ Value *Op0ToUse = (DL.isLittleEndian()) ? Op1 : Op0;
+ Value *Op1ToUse = (DL.isLittleEndian()) ? Op0 : Op1;
+ ExtractedElts[Idx] = IC.Builder.CreateExtractElement(
+ Idx < 16 ? Op0ToUse : Op1ToUse, IC.Builder.getInt32(Idx & 15));
+ }
+
+ // Insert this value into the result vector.
+ Result = IC.Builder.CreateInsertElement(Result, ExtractedElts[Idx],
+ IC.Builder.getInt32(i));
+ }
+ return CastInst::Create(Instruction::BitCast, Result, II.getType());
+ }
+ }
+ break;
+ }
+ return None;
+}
+
int PPCTTIImpl::getIntImmCost(const APInt &Imm, Type *Ty,
TTI::TargetCostKind CostKind) {
if (DisablePPCConstHoist)
@@ -234,10 +234,10 @@ int PPCTTIImpl::getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
int PPCTTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx,
const APInt &Imm, Type *Ty,
- TTI::TargetCostKind CostKind,
- Instruction *Inst) {
+ TTI::TargetCostKind CostKind,
+ Instruction *Inst) {
if (DisablePPCConstHoist)
- return BaseT::getIntImmCostInst(Opcode, Idx, Imm, Ty, CostKind, Inst);
+ return BaseT::getIntImmCostInst(Opcode, Idx, Imm, Ty, CostKind, Inst);
assert(Ty->isIntegerTy());
@@ -335,29 +335,29 @@ PPCTTIImpl::getUserCost(const User *U, ArrayRef<const Value *> Operands,
return BaseT::getUserCost(U, Operands, CostKind);
}
-// Determining the address of a TLS variable results in a function call in
-// certain TLS models.
-static bool memAddrUsesCTR(const Value *MemAddr, const PPCTargetMachine &TM,
- SmallPtrSetImpl<const Value *> &Visited) {
- // No need to traverse again if we already checked this operand.
- if (!Visited.insert(MemAddr).second)
- return false;
- const auto *GV = dyn_cast<GlobalValue>(MemAddr);
- if (!GV) {
- // Recurse to check for constants that refer to TLS global variables.
- if (const auto *CV = dyn_cast<Constant>(MemAddr))
- for (const auto &CO : CV->operands())
- if (memAddrUsesCTR(CO, TM, Visited))
- return true;
- return false;
- }
-
- if (!GV->isThreadLocal())
- return false;
- TLSModel::Model Model = TM.getTLSModel(GV);
- return Model == TLSModel::GeneralDynamic || Model == TLSModel::LocalDynamic;
-}
-
+// Determining the address of a TLS variable results in a function call in
+// certain TLS models.
+static bool memAddrUsesCTR(const Value *MemAddr, const PPCTargetMachine &TM,
+ SmallPtrSetImpl<const Value *> &Visited) {
+ // No need to traverse again if we already checked this operand.
+ if (!Visited.insert(MemAddr).second)
+ return false;
+ const auto *GV = dyn_cast<GlobalValue>(MemAddr);
+ if (!GV) {
+ // Recurse to check for constants that refer to TLS global variables.
+ if (const auto *CV = dyn_cast<Constant>(MemAddr))
+ for (const auto &CO : CV->operands())
+ if (memAddrUsesCTR(CO, TM, Visited))
+ return true;
+ return false;
+ }
+
+ if (!GV->isThreadLocal())
+ return false;
+ TLSModel::Model Model = TM.getTLSModel(GV);
+ return Model == TLSModel::GeneralDynamic || Model == TLSModel::LocalDynamic;
+}
+
bool PPCTTIImpl::mightUseCTR(BasicBlock *BB, TargetLibraryInfo *LibInfo,
SmallPtrSetImpl<const Value *> &Visited) {
const PPCTargetMachine &TM = ST->getTargetMachine();
@@ -383,34 +383,34 @@ bool PPCTTIImpl::mightUseCTR(BasicBlock *BB, TargetLibraryInfo *LibInfo,
return false;
};
- auto supportedHalfPrecisionOp = [](Instruction *Inst) {
- switch (Inst->getOpcode()) {
- default:
- return false;
- case Instruction::FPTrunc:
- case Instruction::FPExt:
- case Instruction::Load:
- case Instruction::Store:
- case Instruction::FPToUI:
- case Instruction::UIToFP:
- case Instruction::FPToSI:
- case Instruction::SIToFP:
- return true;
- }
- };
-
+ auto supportedHalfPrecisionOp = [](Instruction *Inst) {
+ switch (Inst->getOpcode()) {
+ default:
+ return false;
+ case Instruction::FPTrunc:
+ case Instruction::FPExt:
+ case Instruction::Load:
+ case Instruction::Store:
+ case Instruction::FPToUI:
+ case Instruction::UIToFP:
+ case Instruction::FPToSI:
+ case Instruction::SIToFP:
+ return true;
+ }
+ };
+
for (BasicBlock::iterator J = BB->begin(), JE = BB->end();
J != JE; ++J) {
- // There are no direct operations on half precision so assume that
- // anything with that type requires a call except for a few select
- // operations with Power9.
- if (Instruction *CurrInst = dyn_cast<Instruction>(J)) {
- for (const auto &Op : CurrInst->operands()) {
- if (Op->getType()->getScalarType()->isHalfTy() ||
- CurrInst->getType()->getScalarType()->isHalfTy())
- return !(ST->isISA3_0() && supportedHalfPrecisionOp(CurrInst));
- }
- }
+ // There are no direct operations on half precision so assume that
+ // anything with that type requires a call except for a few select
+ // operations with Power9.
+ if (Instruction *CurrInst = dyn_cast<Instruction>(J)) {
+ for (const auto &Op : CurrInst->operands()) {
+ if (Op->getType()->getScalarType()->isHalfTy() ||
+ CurrInst->getType()->getScalarType()->isHalfTy())
+ return !(ST->isISA3_0() && supportedHalfPrecisionOp(CurrInst));
+ }
+ }
if (CallInst *CI = dyn_cast<CallInst>(J)) {
// Inline ASM is okay, unless it clobbers the ctr register.
if (InlineAsm *IA = dyn_cast<InlineAsm>(CI->getCalledOperand())) {
@@ -432,30 +432,30 @@ bool PPCTTIImpl::mightUseCTR(BasicBlock *BB, TargetLibraryInfo *LibInfo,
case Intrinsic::loop_decrement:
return true;
- // Binary operations on 128-bit value will use CTR.
- case Intrinsic::experimental_constrained_fadd:
- case Intrinsic::experimental_constrained_fsub:
- case Intrinsic::experimental_constrained_fmul:
- case Intrinsic::experimental_constrained_fdiv:
- case Intrinsic::experimental_constrained_frem:
- if (F->getType()->getScalarType()->isFP128Ty() ||
- F->getType()->getScalarType()->isPPC_FP128Ty())
- return true;
- break;
-
- case Intrinsic::experimental_constrained_fptosi:
- case Intrinsic::experimental_constrained_fptoui:
- case Intrinsic::experimental_constrained_sitofp:
- case Intrinsic::experimental_constrained_uitofp: {
- Type *SrcType = CI->getArgOperand(0)->getType()->getScalarType();
- Type *DstType = CI->getType()->getScalarType();
- if (SrcType->isPPC_FP128Ty() || DstType->isPPC_FP128Ty() ||
- isLargeIntegerTy(!TM.isPPC64(), SrcType) ||
- isLargeIntegerTy(!TM.isPPC64(), DstType))
- return true;
- break;
- }
-
+ // Binary operations on 128-bit value will use CTR.
+ case Intrinsic::experimental_constrained_fadd:
+ case Intrinsic::experimental_constrained_fsub:
+ case Intrinsic::experimental_constrained_fmul:
+ case Intrinsic::experimental_constrained_fdiv:
+ case Intrinsic::experimental_constrained_frem:
+ if (F->getType()->getScalarType()->isFP128Ty() ||
+ F->getType()->getScalarType()->isPPC_FP128Ty())
+ return true;
+ break;
+
+ case Intrinsic::experimental_constrained_fptosi:
+ case Intrinsic::experimental_constrained_fptoui:
+ case Intrinsic::experimental_constrained_sitofp:
+ case Intrinsic::experimental_constrained_uitofp: {
+ Type *SrcType = CI->getArgOperand(0)->getType()->getScalarType();
+ Type *DstType = CI->getType()->getScalarType();
+ if (SrcType->isPPC_FP128Ty() || DstType->isPPC_FP128Ty() ||
+ isLargeIntegerTy(!TM.isPPC64(), SrcType) ||
+ isLargeIntegerTy(!TM.isPPC64(), DstType))
+ return true;
+ break;
+ }
+
// Exclude eh_sjlj_setjmp; we don't need to exclude eh_sjlj_longjmp
// because, although it does clobber the counter register, the
// control can't then return to inside the loop unless there is also
@@ -474,15 +474,15 @@ bool PPCTTIImpl::mightUseCTR(BasicBlock *BB, TargetLibraryInfo *LibInfo,
case Intrinsic::pow:
case Intrinsic::sin:
case Intrinsic::cos:
- case Intrinsic::experimental_constrained_powi:
- case Intrinsic::experimental_constrained_log:
- case Intrinsic::experimental_constrained_log2:
- case Intrinsic::experimental_constrained_log10:
- case Intrinsic::experimental_constrained_exp:
- case Intrinsic::experimental_constrained_exp2:
- case Intrinsic::experimental_constrained_pow:
- case Intrinsic::experimental_constrained_sin:
- case Intrinsic::experimental_constrained_cos:
+ case Intrinsic::experimental_constrained_powi:
+ case Intrinsic::experimental_constrained_log:
+ case Intrinsic::experimental_constrained_log2:
+ case Intrinsic::experimental_constrained_log10:
+ case Intrinsic::experimental_constrained_exp:
+ case Intrinsic::experimental_constrained_exp2:
+ case Intrinsic::experimental_constrained_pow:
+ case Intrinsic::experimental_constrained_sin:
+ case Intrinsic::experimental_constrained_cos:
return true;
case Intrinsic::copysign:
if (CI->getArgOperand(0)->getType()->getScalarType()->
@@ -504,54 +504,54 @@ bool PPCTTIImpl::mightUseCTR(BasicBlock *BB, TargetLibraryInfo *LibInfo,
case Intrinsic::llround: Opcode = ISD::LLROUND; break;
case Intrinsic::minnum: Opcode = ISD::FMINNUM; break;
case Intrinsic::maxnum: Opcode = ISD::FMAXNUM; break;
- case Intrinsic::experimental_constrained_fcmp:
- Opcode = ISD::STRICT_FSETCC;
- break;
- case Intrinsic::experimental_constrained_fcmps:
- Opcode = ISD::STRICT_FSETCCS;
- break;
- case Intrinsic::experimental_constrained_fma:
- Opcode = ISD::STRICT_FMA;
- break;
- case Intrinsic::experimental_constrained_sqrt:
- Opcode = ISD::STRICT_FSQRT;
- break;
- case Intrinsic::experimental_constrained_floor:
- Opcode = ISD::STRICT_FFLOOR;
- break;
- case Intrinsic::experimental_constrained_ceil:
- Opcode = ISD::STRICT_FCEIL;
- break;
- case Intrinsic::experimental_constrained_trunc:
- Opcode = ISD::STRICT_FTRUNC;
- break;
- case Intrinsic::experimental_constrained_rint:
- Opcode = ISD::STRICT_FRINT;
- break;
- case Intrinsic::experimental_constrained_lrint:
- Opcode = ISD::STRICT_LRINT;
- break;
- case Intrinsic::experimental_constrained_llrint:
- Opcode = ISD::STRICT_LLRINT;
- break;
- case Intrinsic::experimental_constrained_nearbyint:
- Opcode = ISD::STRICT_FNEARBYINT;
- break;
- case Intrinsic::experimental_constrained_round:
- Opcode = ISD::STRICT_FROUND;
- break;
- case Intrinsic::experimental_constrained_lround:
- Opcode = ISD::STRICT_LROUND;
- break;
- case Intrinsic::experimental_constrained_llround:
- Opcode = ISD::STRICT_LLROUND;
- break;
- case Intrinsic::experimental_constrained_minnum:
- Opcode = ISD::STRICT_FMINNUM;
- break;
- case Intrinsic::experimental_constrained_maxnum:
- Opcode = ISD::STRICT_FMAXNUM;
- break;
+ case Intrinsic::experimental_constrained_fcmp:
+ Opcode = ISD::STRICT_FSETCC;
+ break;
+ case Intrinsic::experimental_constrained_fcmps:
+ Opcode = ISD::STRICT_FSETCCS;
+ break;
+ case Intrinsic::experimental_constrained_fma:
+ Opcode = ISD::STRICT_FMA;
+ break;
+ case Intrinsic::experimental_constrained_sqrt:
+ Opcode = ISD::STRICT_FSQRT;
+ break;
+ case Intrinsic::experimental_constrained_floor:
+ Opcode = ISD::STRICT_FFLOOR;
+ break;
+ case Intrinsic::experimental_constrained_ceil:
+ Opcode = ISD::STRICT_FCEIL;
+ break;
+ case Intrinsic::experimental_constrained_trunc:
+ Opcode = ISD::STRICT_FTRUNC;
+ break;
+ case Intrinsic::experimental_constrained_rint:
+ Opcode = ISD::STRICT_FRINT;
+ break;
+ case Intrinsic::experimental_constrained_lrint:
+ Opcode = ISD::STRICT_LRINT;
+ break;
+ case Intrinsic::experimental_constrained_llrint:
+ Opcode = ISD::STRICT_LLRINT;
+ break;
+ case Intrinsic::experimental_constrained_nearbyint:
+ Opcode = ISD::STRICT_FNEARBYINT;
+ break;
+ case Intrinsic::experimental_constrained_round:
+ Opcode = ISD::STRICT_FROUND;
+ break;
+ case Intrinsic::experimental_constrained_lround:
+ Opcode = ISD::STRICT_LROUND;
+ break;
+ case Intrinsic::experimental_constrained_llround:
+ Opcode = ISD::STRICT_LLROUND;
+ break;
+ case Intrinsic::experimental_constrained_minnum:
+ Opcode = ISD::STRICT_FMINNUM;
+ break;
+ case Intrinsic::experimental_constrained_maxnum:
+ Opcode = ISD::STRICT_FMAXNUM;
+ break;
case Intrinsic::umul_with_overflow: Opcode = ISD::UMULO; break;
case Intrinsic::smul_with_overflow: Opcode = ISD::SMULO; break;
}
@@ -700,7 +700,7 @@ bool PPCTTIImpl::mightUseCTR(BasicBlock *BB, TargetLibraryInfo *LibInfo,
}
for (Value *Operand : J->operands())
- if (memAddrUsesCTR(Operand, TM, Visited))
+ if (memAddrUsesCTR(Operand, TM, Visited))
return true;
}
@@ -760,24 +760,24 @@ bool PPCTTIImpl::isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
}
}
- // If an exit block has a PHI that accesses a TLS variable as one of the
- // incoming values from the loop, we cannot produce a CTR loop because the
- // address for that value will be computed in the loop.
- SmallVector<BasicBlock *, 4> ExitBlocks;
- L->getExitBlocks(ExitBlocks);
- for (auto &BB : ExitBlocks) {
- for (auto &PHI : BB->phis()) {
- for (int Idx = 0, EndIdx = PHI.getNumIncomingValues(); Idx < EndIdx;
- Idx++) {
- const BasicBlock *IncomingBB = PHI.getIncomingBlock(Idx);
- const Value *IncomingValue = PHI.getIncomingValue(Idx);
- if (L->contains(IncomingBB) &&
- memAddrUsesCTR(IncomingValue, TM, Visited))
- return false;
- }
- }
- }
-
+ // If an exit block has a PHI that accesses a TLS variable as one of the
+ // incoming values from the loop, we cannot produce a CTR loop because the
+ // address for that value will be computed in the loop.
+ SmallVector<BasicBlock *, 4> ExitBlocks;
+ L->getExitBlocks(ExitBlocks);
+ for (auto &BB : ExitBlocks) {
+ for (auto &PHI : BB->phis()) {
+ for (int Idx = 0, EndIdx = PHI.getNumIncomingValues(); Idx < EndIdx;
+ Idx++) {
+ const BasicBlock *IncomingBB = PHI.getIncomingBlock(Idx);
+ const Value *IncomingValue = PHI.getIncomingValue(Idx);
+ if (L->contains(IncomingBB) &&
+ memAddrUsesCTR(IncomingValue, TM, Visited))
+ return false;
+ }
+ }
+ }
+
LLVMContext &C = L->getHeader()->getContext();
HWLoopInfo.CountType = TM.isPPC64() ?
Type::getInt64Ty(C) : Type::getInt32Ty(C);
@@ -813,7 +813,7 @@ bool PPCTTIImpl::useColdCCForColdCall(Function &F) {
}
bool PPCTTIImpl::enableAggressiveInterleaving(bool LoopHasReductions) {
- // On the A2, always unroll aggressively.
+ // On the A2, always unroll aggressively.
if (ST->getCPUDirective() == PPC::DIR_A2)
return true;
@@ -989,7 +989,7 @@ int PPCTTIImpl::getShuffleCost(TTI::ShuffleKind Kind, Type *Tp, int Index,
// Legalize the type.
std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, Tp);
- // PPC, for both Altivec/VSX, support cheap arbitrary permutations
+ // PPC, for both Altivec/VSX, support cheap arbitrary permutations
// (at least in the sense that there need only be one non-loop-invariant
// instruction). We need one such shuffle instruction for each actual
// register (this is not true for arbitrary shuffles, but is true for the
@@ -1006,12 +1006,12 @@ int PPCTTIImpl::getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind) {
}
int PPCTTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
- TTI::CastContextHint CCH,
+ TTI::CastContextHint CCH,
TTI::TargetCostKind CostKind,
const Instruction *I) {
assert(TLI->InstructionOpcodeToISD(Opcode) && "Invalid opcode");
- int Cost = BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
+ int Cost = BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
Cost = vectorCostAdjustment(Cost, Opcode, Dst, Src);
// TODO: Allow non-throughput costs that aren't binary.
if (CostKind != TTI::TCK_RecipThroughput)
@@ -1020,11 +1020,11 @@ int PPCTTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
}
int PPCTTIImpl::getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
- CmpInst::Predicate VecPred,
+ CmpInst::Predicate VecPred,
TTI::TargetCostKind CostKind,
const Instruction *I) {
- int Cost =
- BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind, I);
+ int Cost =
+ BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind, I);
// TODO: Handle other cost kinds.
if (CostKind != TTI::TCK_RecipThroughput)
return Cost;
@@ -1071,7 +1071,7 @@ int PPCTTIImpl::getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index) {
// The cost of the load constant for a vector extract is disregarded
// (invariant, easily schedulable).
return vectorCostAdjustment(1, Opcode, Val, nullptr);
-
+
} else if (ST->hasDirectMove())
// Assume permute has standard cost.
// Assume move-to/move-from VSR have 2x standard cost.
@@ -1144,7 +1144,7 @@ int PPCTTIImpl::getMemoryOpCost(unsigned Opcode, Type *Src,
// for Altivec types using the VSX instructions, but that's more expensive
// than using the permutation-based load sequence. On the P8, that's no
// longer true.
- if (Opcode == Instruction::Load && (!ST->hasP8Vector() && IsAltivecType) &&
+ if (Opcode == Instruction::Load && (!ST->hasP8Vector() && IsAltivecType) &&
*Alignment >= LT.second.getScalarType().getStoreSize())
return Cost + LT.first; // Add the cost of the permutations.
@@ -1197,7 +1197,7 @@ int PPCTTIImpl::getInterleavedMemoryOpCost(
getMemoryOpCost(Opcode, VecTy, MaybeAlign(Alignment), AddressSpace,
CostKind);
- // PPC, for both Altivec/VSX, support cheap arbitrary permutations
+ // PPC, for both Altivec/VSX, support cheap arbitrary permutations
// (at least in the sense that there need only be one non-loop-invariant
// instruction). For each result vector, we need one shuffle per incoming
// vector (except that the first shuffle can take two incoming vectors
@@ -1212,27 +1212,27 @@ unsigned PPCTTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
return BaseT::getIntrinsicInstrCost(ICA, CostKind);
}
-bool PPCTTIImpl::areFunctionArgsABICompatible(
- const Function *Caller, const Function *Callee,
- SmallPtrSetImpl<Argument *> &Args) const {
-
- // We need to ensure that argument promotion does not
- // attempt to promote pointers to MMA types (__vector_pair
- // and __vector_quad) since these types explicitly cannot be
- // passed as arguments. Both of these types are larger than
- // the 128-bit Altivec vectors and have a scalar size of 1 bit.
- if (!BaseT::areFunctionArgsABICompatible(Caller, Callee, Args))
- return false;
-
- return llvm::none_of(Args, [](Argument *A) {
- auto *EltTy = cast<PointerType>(A->getType())->getElementType();
- if (EltTy->isSized())
- return (EltTy->isIntOrIntVectorTy(1) &&
- EltTy->getPrimitiveSizeInBits() > 128);
- return false;
- });
-}
-
+bool PPCTTIImpl::areFunctionArgsABICompatible(
+ const Function *Caller, const Function *Callee,
+ SmallPtrSetImpl<Argument *> &Args) const {
+
+ // We need to ensure that argument promotion does not
+ // attempt to promote pointers to MMA types (__vector_pair
+ // and __vector_quad) since these types explicitly cannot be
+ // passed as arguments. Both of these types are larger than
+ // the 128-bit Altivec vectors and have a scalar size of 1 bit.
+ if (!BaseT::areFunctionArgsABICompatible(Caller, Callee, Args))
+ return false;
+
+ return llvm::none_of(Args, [](Argument *A) {
+ auto *EltTy = cast<PointerType>(A->getType())->getElementType();
+ if (EltTy->isSized())
+ return (EltTy->isIntOrIntVectorTy(1) &&
+ EltTy->getPrimitiveSizeInBits() > 128);
+ return false;
+ });
+}
+
bool PPCTTIImpl::canSaveCmp(Loop *L, BranchInst **BI, ScalarEvolution *SE,
LoopInfo *LI, DominatorTree *DT,
AssumptionCache *AC, TargetLibraryInfo *LibInfo) {
@@ -1268,51 +1268,51 @@ bool PPCTTIImpl::isLSRCostLess(TargetTransformInfo::LSRCost &C1,
else
return TargetTransformInfoImplBase::isLSRCostLess(C1, C2);
}
-
-bool PPCTTIImpl::isNumRegsMajorCostOfLSR() {
- return false;
-}
-
-bool PPCTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
- MemIntrinsicInfo &Info) {
- switch (Inst->getIntrinsicID()) {
- case Intrinsic::ppc_altivec_lvx:
- case Intrinsic::ppc_altivec_lvxl:
- case Intrinsic::ppc_altivec_lvebx:
- case Intrinsic::ppc_altivec_lvehx:
- case Intrinsic::ppc_altivec_lvewx:
- case Intrinsic::ppc_vsx_lxvd2x:
- case Intrinsic::ppc_vsx_lxvw4x:
- case Intrinsic::ppc_vsx_lxvd2x_be:
- case Intrinsic::ppc_vsx_lxvw4x_be:
- case Intrinsic::ppc_vsx_lxvl:
- case Intrinsic::ppc_vsx_lxvll:
- case Intrinsic::ppc_vsx_lxvp: {
- Info.PtrVal = Inst->getArgOperand(0);
- Info.ReadMem = true;
- Info.WriteMem = false;
- return true;
- }
- case Intrinsic::ppc_altivec_stvx:
- case Intrinsic::ppc_altivec_stvxl:
- case Intrinsic::ppc_altivec_stvebx:
- case Intrinsic::ppc_altivec_stvehx:
- case Intrinsic::ppc_altivec_stvewx:
- case Intrinsic::ppc_vsx_stxvd2x:
- case Intrinsic::ppc_vsx_stxvw4x:
- case Intrinsic::ppc_vsx_stxvd2x_be:
- case Intrinsic::ppc_vsx_stxvw4x_be:
- case Intrinsic::ppc_vsx_stxvl:
- case Intrinsic::ppc_vsx_stxvll:
- case Intrinsic::ppc_vsx_stxvp: {
- Info.PtrVal = Inst->getArgOperand(1);
- Info.ReadMem = false;
- Info.WriteMem = true;
- return true;
- }
- default:
- break;
- }
-
- return false;
-}
+
+bool PPCTTIImpl::isNumRegsMajorCostOfLSR() {
+ return false;
+}
+
+bool PPCTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
+ MemIntrinsicInfo &Info) {
+ switch (Inst->getIntrinsicID()) {
+ case Intrinsic::ppc_altivec_lvx:
+ case Intrinsic::ppc_altivec_lvxl:
+ case Intrinsic::ppc_altivec_lvebx:
+ case Intrinsic::ppc_altivec_lvehx:
+ case Intrinsic::ppc_altivec_lvewx:
+ case Intrinsic::ppc_vsx_lxvd2x:
+ case Intrinsic::ppc_vsx_lxvw4x:
+ case Intrinsic::ppc_vsx_lxvd2x_be:
+ case Intrinsic::ppc_vsx_lxvw4x_be:
+ case Intrinsic::ppc_vsx_lxvl:
+ case Intrinsic::ppc_vsx_lxvll:
+ case Intrinsic::ppc_vsx_lxvp: {
+ Info.PtrVal = Inst->getArgOperand(0);
+ Info.ReadMem = true;
+ Info.WriteMem = false;
+ return true;
+ }
+ case Intrinsic::ppc_altivec_stvx:
+ case Intrinsic::ppc_altivec_stvxl:
+ case Intrinsic::ppc_altivec_stvebx:
+ case Intrinsic::ppc_altivec_stvehx:
+ case Intrinsic::ppc_altivec_stvewx:
+ case Intrinsic::ppc_vsx_stxvd2x:
+ case Intrinsic::ppc_vsx_stxvw4x:
+ case Intrinsic::ppc_vsx_stxvd2x_be:
+ case Intrinsic::ppc_vsx_stxvw4x_be:
+ case Intrinsic::ppc_vsx_stxvl:
+ case Intrinsic::ppc_vsx_stxvll:
+ case Intrinsic::ppc_vsx_stxvp: {
+ Info.PtrVal = Inst->getArgOperand(1);
+ Info.ReadMem = false;
+ Info.WriteMem = true;
+ return true;
+ }
+ default:
+ break;
+ }
+
+ return false;
+}
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetTransformInfo.h b/contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetTransformInfo.h
index 3ef091b13d..c38ae90bc7 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetTransformInfo.h
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCTargetTransformInfo.h
@@ -41,9 +41,9 @@ public:
: BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)),
TLI(ST->getTargetLowering()) {}
- Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
- IntrinsicInst &II) const;
-
+ Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
+ IntrinsicInst &II) const;
+
/// \name Scalar TTI Implementations
/// @{
@@ -52,8 +52,8 @@ public:
TTI::TargetCostKind CostKind);
int getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm,
- Type *Ty, TTI::TargetCostKind CostKind,
- Instruction *Inst = nullptr);
+ Type *Ty, TTI::TargetCostKind CostKind,
+ Instruction *Inst = nullptr);
int getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
Type *Ty, TTI::TargetCostKind CostKind);
@@ -68,14 +68,14 @@ public:
bool canSaveCmp(Loop *L, BranchInst **BI, ScalarEvolution *SE, LoopInfo *LI,
DominatorTree *DT, AssumptionCache *AC,
TargetLibraryInfo *LibInfo);
- bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info);
+ bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info);
void getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
TTI::UnrollingPreferences &UP);
void getPeelingPreferences(Loop *L, ScalarEvolution &SE,
TTI::PeelingPreferences &PP);
bool isLSRCostLess(TargetTransformInfo::LSRCost &C1,
TargetTransformInfo::LSRCost &C2);
- bool isNumRegsMajorCostOfLSR();
+ bool isNumRegsMajorCostOfLSR();
/// @}
@@ -109,11 +109,11 @@ public:
const Instruction *CxtI = nullptr);
int getShuffleCost(TTI::ShuffleKind Kind, Type *Tp, int Index, Type *SubTp);
int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
- TTI::CastContextHint CCH, TTI::TargetCostKind CostKind,
+ TTI::CastContextHint CCH, TTI::TargetCostKind CostKind,
const Instruction *I = nullptr);
int getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind);
int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
- CmpInst::Predicate VecPred,
+ CmpInst::Predicate VecPred,
TTI::TargetCostKind CostKind,
const Instruction *I = nullptr);
int getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index);
@@ -129,9 +129,9 @@ public:
unsigned getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
TTI::TargetCostKind CostKind);
- bool areFunctionArgsABICompatible(const Function *Caller,
- const Function *Callee,
- SmallPtrSetImpl<Argument *> &Args) const;
+ bool areFunctionArgsABICompatible(const Function *Caller,
+ const Function *Callee,
+ SmallPtrSetImpl<Argument *> &Args) const;
/// @}
};
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCVSXFMAMutate.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCVSXFMAMutate.cpp
index 3c0eae1d7a..e72e29112d 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCVSXFMAMutate.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCVSXFMAMutate.cpp
@@ -315,9 +315,9 @@ protected:
// Extend the live interval of the addend source (it might end at the
// copy to be removed, or somewhere in between there and here). This
// is necessary only if it is a physical register.
- if (!AddendSrcReg.isVirtual())
- for (MCRegUnitIterator Units(AddendSrcReg.asMCReg(), TRI);
- Units.isValid(); ++Units) {
+ if (!AddendSrcReg.isVirtual())
+ for (MCRegUnitIterator Units(AddendSrcReg.asMCReg(), TRI);
+ Units.isValid(); ++Units) {
unsigned Unit = *Units;
LiveRange &AddendSrcRange = LIS->getRegUnit(Unit);
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp
index 62ec6c3003..ff251f55af 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp
@@ -254,10 +254,10 @@ bool PPCVSXSwapRemoval::gatherVectorInstructions() {
if (!MO.isReg())
continue;
Register Reg = MO.getReg();
- // All operands need to be checked because there are instructions that
- // operate on a partial register and produce a full register (such as
- // XXPERMDIs).
- if (isAnyVecReg(Reg, Partial))
+ // All operands need to be checked because there are instructions that
+ // operate on a partial register and produce a full register (such as
+ // XXPERMDIs).
+ if (isAnyVecReg(Reg, Partial))
RelevantInstr = true;
}
@@ -690,29 +690,29 @@ void PPCVSXSwapRemoval::recordUnoptimizableWebs() {
LLVM_DEBUG(UseMI.dump());
LLVM_DEBUG(dbgs() << "\n");
}
-
- // It is possible that the load feeds a swap and that swap feeds a
- // store. In such a case, the code is actually trying to store a swapped
- // vector. We must reject such webs.
- if (SwapVector[UseIdx].IsSwap && !SwapVector[UseIdx].IsLoad &&
- !SwapVector[UseIdx].IsStore) {
- Register SwapDefReg = UseMI.getOperand(0).getReg();
- for (MachineInstr &UseOfUseMI :
- MRI->use_nodbg_instructions(SwapDefReg)) {
- int UseOfUseIdx = SwapMap[&UseOfUseMI];
- if (SwapVector[UseOfUseIdx].IsStore) {
- SwapVector[Repr].WebRejected = 1;
- LLVM_DEBUG(
- dbgs() << format(
- "Web %d rejected for load/swap feeding a store\n", Repr));
- LLVM_DEBUG(dbgs() << " def " << EntryIdx << ": ");
- LLVM_DEBUG(MI->dump());
- LLVM_DEBUG(dbgs() << " use " << UseIdx << ": ");
- LLVM_DEBUG(UseMI.dump());
- LLVM_DEBUG(dbgs() << "\n");
- }
- }
- }
+
+ // It is possible that the load feeds a swap and that swap feeds a
+ // store. In such a case, the code is actually trying to store a swapped
+ // vector. We must reject such webs.
+ if (SwapVector[UseIdx].IsSwap && !SwapVector[UseIdx].IsLoad &&
+ !SwapVector[UseIdx].IsStore) {
+ Register SwapDefReg = UseMI.getOperand(0).getReg();
+ for (MachineInstr &UseOfUseMI :
+ MRI->use_nodbg_instructions(SwapDefReg)) {
+ int UseOfUseIdx = SwapMap[&UseOfUseMI];
+ if (SwapVector[UseOfUseIdx].IsStore) {
+ SwapVector[Repr].WebRejected = 1;
+ LLVM_DEBUG(
+ dbgs() << format(
+ "Web %d rejected for load/swap feeding a store\n", Repr));
+ LLVM_DEBUG(dbgs() << " def " << EntryIdx << ": ");
+ LLVM_DEBUG(MI->dump());
+ LLVM_DEBUG(dbgs() << " use " << UseIdx << ": ");
+ LLVM_DEBUG(UseMI.dump());
+ LLVM_DEBUG(dbgs() << "\n");
+ }
+ }
+ }
}
// Reject webs that contain swapping stores that are fed by something
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.cpp
index c051e56e8d..6bb952f27f 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.cpp
@@ -14,10 +14,10 @@ Target &llvm::getThePPC32Target() {
static Target ThePPC32Target;
return ThePPC32Target;
}
-Target &llvm::getThePPC32LETarget() {
- static Target ThePPC32LETarget;
- return ThePPC32LETarget;
-}
+Target &llvm::getThePPC32LETarget() {
+ static Target ThePPC32LETarget;
+ return ThePPC32LETarget;
+}
Target &llvm::getThePPC64Target() {
static Target ThePPC64Target;
return ThePPC64Target;
@@ -28,12 +28,12 @@ Target &llvm::getThePPC64LETarget() {
}
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTargetInfo() {
- RegisterTarget<Triple::ppc, /*HasJIT=*/true> W(getThePPC32Target(), "ppc32",
+ RegisterTarget<Triple::ppc, /*HasJIT=*/true> W(getThePPC32Target(), "ppc32",
"PowerPC 32", "PPC");
- RegisterTarget<Triple::ppcle, /*HasJIT=*/true> X(
- getThePPC32LETarget(), "ppc32le", "PowerPC 32 LE", "PPC");
-
+ RegisterTarget<Triple::ppcle, /*HasJIT=*/true> X(
+ getThePPC32LETarget(), "ppc32le", "PowerPC 32 LE", "PPC");
+
RegisterTarget<Triple::ppc64, /*HasJIT=*/true> Y(getThePPC64Target(), "ppc64",
"PowerPC 64", "PPC");
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.h b/contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.h
index d741e55287..f9d20ef00d 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.h
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.h
@@ -14,7 +14,7 @@ namespace llvm {
class Target;
Target &getThePPC32Target();
-Target &getThePPC32LETarget();
+Target &getThePPC32LETarget();
Target &getThePPC64Target();
Target &getThePPC64LETarget();
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo/ya.make b/contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo/ya.make
index 551efb30b2..68badb4490 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo/ya.make
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo/ya.make
@@ -12,13 +12,13 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
- contrib/libs/llvm12/lib/Target/PowerPC
- contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo
+ contrib/libs/llvm12/lib/Target/PowerPC
+ contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/ya.make b/contrib/libs/llvm12/lib/Target/PowerPC/ya.make
index 04512f12fe..8c7039a575 100644
--- a/contrib/libs/llvm12/lib/Target/PowerPC/ya.make
+++ b/contrib/libs/llvm12/lib/Target/PowerPC/ya.make
@@ -12,27 +12,27 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/CodeGen
- contrib/libs/llvm12/lib/CodeGen/AsmPrinter
- contrib/libs/llvm12/lib/CodeGen/GlobalISel
- contrib/libs/llvm12/lib/CodeGen/SelectionDAG
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target
- contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc
- contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo
- contrib/libs/llvm12/lib/Transforms/Scalar
- contrib/libs/llvm12/lib/Transforms/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/CodeGen
+ contrib/libs/llvm12/lib/CodeGen/AsmPrinter
+ contrib/libs/llvm12/lib/CodeGen/GlobalISel
+ contrib/libs/llvm12/lib/CodeGen/SelectionDAG
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target
+ contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo
+ contrib/libs/llvm12/lib/Transforms/Scalar
+ contrib/libs/llvm12/lib/Transforms/Utils
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC
- contrib/libs/llvm12/lib/Target/PowerPC
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC
+ contrib/libs/llvm12/lib/Target/PowerPC
)
NO_COMPILER_WARNINGS()
@@ -40,10 +40,10 @@ NO_COMPILER_WARNINGS()
NO_UTIL()
SRCS(
- GISel/PPCCallLowering.cpp
- GISel/PPCInstructionSelector.cpp
- GISel/PPCLegalizerInfo.cpp
- GISel/PPCRegisterBankInfo.cpp
+ GISel/PPCCallLowering.cpp
+ GISel/PPCInstructionSelector.cpp
+ GISel/PPCLegalizerInfo.cpp
+ GISel/PPCRegisterBankInfo.cpp
PPCAsmPrinter.cpp
PPCBoolRetToInt.cpp
PPCBranchCoalescing.cpp
diff --git a/contrib/libs/llvm12/lib/Target/README.txt b/contrib/libs/llvm12/lib/Target/README.txt
index 1528417696..e172abbbd8 100644
--- a/contrib/libs/llvm12/lib/Target/README.txt
+++ b/contrib/libs/llvm12/lib/Target/README.txt
@@ -1541,9 +1541,9 @@ int bar() { return foo("abcd"); }
//===---------------------------------------------------------------------===//
-function-attrs doesn't know much about memcpy/memset. This function should be
+function-attrs doesn't know much about memcpy/memset. This function should be
marked readnone rather than readonly, since it only twiddles local memory, but
-function-attrs doesn't handle memset/memcpy/memmove aggressively:
+function-attrs doesn't handle memset/memcpy/memmove aggressively:
struct X { int *p; int *q; };
int foo() {
@@ -1557,7 +1557,7 @@ int foo() {
}
This can be seen at:
-$ clang t.c -S -o - -mkernel -O0 -emit-llvm | opt -function-attrs -S
+$ clang t.c -S -o - -mkernel -O0 -emit-llvm | opt -function-attrs -S
//===---------------------------------------------------------------------===//
@@ -1840,7 +1840,7 @@ current definition always folds to a constant. We also should make sure that
we remove checking in code like
char *p = malloc(strlen(s)+1);
- __strcpy_chk(p, s, __builtin_object_size(p, 0));
+ __strcpy_chk(p, s, __builtin_object_size(p, 0));
//===---------------------------------------------------------------------===//
diff --git a/contrib/libs/llvm12/lib/Target/TargetLoweringObjectFile.cpp b/contrib/libs/llvm12/lib/Target/TargetLoweringObjectFile.cpp
index 1c8d852504..81af4eead6 100644
--- a/contrib/libs/llvm12/lib/Target/TargetLoweringObjectFile.cpp
+++ b/contrib/libs/llvm12/lib/Target/TargetLoweringObjectFile.cpp
@@ -20,7 +20,7 @@
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
-#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCStreamer.h"
@@ -50,23 +50,23 @@ void TargetLoweringObjectFile::Initialize(MCContext &ctx,
// Reset various EH DWARF encodings.
PersonalityEncoding = LSDAEncoding = TTypeEncoding = dwarf::DW_EH_PE_absptr;
CallSiteEncoding = dwarf::DW_EH_PE_uleb128;
-
- this->TM = &TM;
+
+ this->TM = &TM;
}
TargetLoweringObjectFile::~TargetLoweringObjectFile() {
delete Mang;
}
-unsigned TargetLoweringObjectFile::getCallSiteEncoding() const {
- // If target does not have LEB128 directives, we would need the
- // call site encoding to be udata4 so that the alternative path
- // for not having LEB128 directives could work.
- if (!getContext().getAsmInfo()->hasLEB128Directives())
- return dwarf::DW_EH_PE_udata4;
- return CallSiteEncoding;
-}
-
+unsigned TargetLoweringObjectFile::getCallSiteEncoding() const {
+ // If target does not have LEB128 directives, we would need the
+ // call site encoding to be udata4 so that the alternative path
+ // for not having LEB128 directives could work.
+ if (!getContext().getAsmInfo()->hasLEB128Directives())
+ return dwarf::DW_EH_PE_udata4;
+ return CallSiteEncoding;
+}
+
static bool isNullOrUndef(const Constant *C) {
// Check that the constant isn't all zeros or undefs.
if (C->isNullValue() || isa<UndefValue>(C))
@@ -148,53 +148,53 @@ void TargetLoweringObjectFile::emitPersonalityValue(MCStreamer &Streamer,
const MCSymbol *Sym) const {
}
-void TargetLoweringObjectFile::emitCGProfileMetadata(MCStreamer &Streamer,
- Module &M) const {
- MCContext &C = getContext();
- SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
- M.getModuleFlagsMetadata(ModuleFlags);
-
- MDNode *CFGProfile = nullptr;
-
- for (const auto &MFE : ModuleFlags) {
- StringRef Key = MFE.Key->getString();
- if (Key == "CG Profile") {
- CFGProfile = cast<MDNode>(MFE.Val);
- break;
- }
- }
-
- if (!CFGProfile)
- return;
-
- auto GetSym = [this](const MDOperand &MDO) -> MCSymbol * {
- if (!MDO)
- return nullptr;
- auto *V = cast<ValueAsMetadata>(MDO);
- const Function *F = cast<Function>(V->getValue()->stripPointerCasts());
- if (F->hasDLLImportStorageClass())
- return nullptr;
- return TM->getSymbol(F);
- };
-
- for (const auto &Edge : CFGProfile->operands()) {
- MDNode *E = cast<MDNode>(Edge);
- const MCSymbol *From = GetSym(E->getOperand(0));
- const MCSymbol *To = GetSym(E->getOperand(1));
- // Skip null functions. This can happen if functions are dead stripped after
- // the CGProfile pass has been run.
- if (!From || !To)
- continue;
- uint64_t Count = cast<ConstantAsMetadata>(E->getOperand(2))
- ->getValue()
- ->getUniqueInteger()
- .getZExtValue();
- Streamer.emitCGProfileEntry(
- MCSymbolRefExpr::create(From, MCSymbolRefExpr::VK_None, C),
- MCSymbolRefExpr::create(To, MCSymbolRefExpr::VK_None, C), Count);
- }
-}
-
+void TargetLoweringObjectFile::emitCGProfileMetadata(MCStreamer &Streamer,
+ Module &M) const {
+ MCContext &C = getContext();
+ SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
+ M.getModuleFlagsMetadata(ModuleFlags);
+
+ MDNode *CFGProfile = nullptr;
+
+ for (const auto &MFE : ModuleFlags) {
+ StringRef Key = MFE.Key->getString();
+ if (Key == "CG Profile") {
+ CFGProfile = cast<MDNode>(MFE.Val);
+ break;
+ }
+ }
+
+ if (!CFGProfile)
+ return;
+
+ auto GetSym = [this](const MDOperand &MDO) -> MCSymbol * {
+ if (!MDO)
+ return nullptr;
+ auto *V = cast<ValueAsMetadata>(MDO);
+ const Function *F = cast<Function>(V->getValue()->stripPointerCasts());
+ if (F->hasDLLImportStorageClass())
+ return nullptr;
+ return TM->getSymbol(F);
+ };
+
+ for (const auto &Edge : CFGProfile->operands()) {
+ MDNode *E = cast<MDNode>(Edge);
+ const MCSymbol *From = GetSym(E->getOperand(0));
+ const MCSymbol *To = GetSym(E->getOperand(1));
+ // Skip null functions. This can happen if functions are dead stripped after
+ // the CGProfile pass has been run.
+ if (!From || !To)
+ continue;
+ uint64_t Count = cast<ConstantAsMetadata>(E->getOperand(2))
+ ->getValue()
+ ->getUniqueInteger()
+ .getZExtValue();
+ Streamer.emitCGProfileEntry(
+ MCSymbolRefExpr::create(From, MCSymbolRefExpr::VK_None, C),
+ MCSymbolRefExpr::create(To, MCSymbolRefExpr::VK_None, C), Count);
+ }
+}
+
/// getKindForGlobal - This is a top-level target-independent classifier for
/// a global object. Given a global variable and information from the TM, this
/// function classifies the global in a target independent manner. This function
diff --git a/contrib/libs/llvm12/lib/Target/TargetMachine.cpp b/contrib/libs/llvm12/lib/Target/TargetMachine.cpp
index 17b58c8ee1..2aee0e5c3f 100644
--- a/contrib/libs/llvm12/lib/Target/TargetMachine.cpp
+++ b/contrib/libs/llvm12/lib/Target/TargetMachine.cpp
@@ -93,30 +93,30 @@ static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) {
bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
const GlobalValue *GV) const {
- const Triple &TT = getTargetTriple();
- Reloc::Model RM = getRelocationModel();
+ const Triple &TT = getTargetTriple();
+ Reloc::Model RM = getRelocationModel();
// According to the llvm language reference, we should be able to
// just return false in here if we have a GV, as we know it is
// dso_preemptable. At this point in time, the various IR producers
// have not been transitioned to always produce a dso_local when it
// is possible to do so.
- // In the case of ExternalSymbolSDNode, GV is null and we should just return
- // false. However, COFF currently relies on this to be true
- //
+ // In the case of ExternalSymbolSDNode, GV is null and we should just return
+ // false. However, COFF currently relies on this to be true
+ //
// As a result we still have some logic in here to improve the quality of the
// generated code.
// FIXME: Add a module level metadata for whether intrinsics should be assumed
// local.
- if (!GV)
- return TT.isOSBinFormatCOFF();
+ if (!GV)
+ return TT.isOSBinFormatCOFF();
- // If the IR producer requested that this GV be treated as dso local, obey.
- if (GV->isDSOLocal())
- return true;
+ // If the IR producer requested that this GV be treated as dso local, obey.
+ if (GV->isDSOLocal())
+ return true;
// DLLImport explicitly marks the GV as external.
- if (GV->hasDLLImportStorageClass())
+ if (GV->hasDLLImportStorageClass())
return false;
// On MinGW, variables that haven't been declared with DLLImport may still
@@ -124,14 +124,14 @@ bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
// don't assume the variables to be DSO local unless we actually know
// that for sure. This only has to be done for variables; for functions
// the linker can insert thunks for calling functions from another DLL.
- if (TT.isWindowsGNUEnvironment() && TT.isOSBinFormatCOFF() &&
+ if (TT.isWindowsGNUEnvironment() && TT.isOSBinFormatCOFF() &&
GV->isDeclarationForLinker() && isa<GlobalVariable>(GV))
return false;
// On COFF, don't mark 'extern_weak' symbols as DSO local. If these symbols
// remain unresolved in the link, they can be resolved to zero, which is
// outside the current DSO.
- if (TT.isOSBinFormatCOFF() && GV->hasExternalWeakLinkage())
+ if (TT.isOSBinFormatCOFF() && GV->hasExternalWeakLinkage())
return false;
// Every other GV is local on COFF.
@@ -146,7 +146,7 @@ bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
if (TT.isOSBinFormatMachO()) {
if (RM == Reloc::Static)
return true;
- return GV->isStrongDefinitionForLinker();
+ return GV->isStrongDefinitionForLinker();
}
// Due to the AIX linkage model, any global with default visibility is
@@ -233,12 +233,12 @@ TargetIRAnalysis TargetMachine::getTargetIRAnalysis() {
return TargetIRAnalysis(
[this](const Function &F) { return this->getTargetTransformInfo(F); });
}
-
-std::pair<int, int> TargetMachine::parseBinutilsVersion(StringRef Version) {
- if (Version == "none")
- return {INT_MAX, INT_MAX}; // Make binutilsIsAtLeast() return true.
- std::pair<int, int> Ret;
- if (!Version.consumeInteger(10, Ret.first) && Version.consume_front("."))
- Version.consumeInteger(10, Ret.second);
- return Ret;
-}
+
+std::pair<int, int> TargetMachine::parseBinutilsVersion(StringRef Version) {
+ if (Version == "none")
+ return {INT_MAX, INT_MAX}; // Make binutilsIsAtLeast() return true.
+ std::pair<int, int> Ret;
+ if (!Version.consumeInteger(10, Ret.first) && Version.consume_front("."))
+ Version.consumeInteger(10, Ret.second);
+ return Ret;
+}
diff --git a/contrib/libs/llvm12/lib/Target/X86/AsmParser/X86AsmParser.cpp b/contrib/libs/llvm12/lib/Target/X86/AsmParser/X86AsmParser.cpp
index f063bdbf6a..9d9a20183f 100644
--- a/contrib/libs/llvm12/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -32,7 +32,7 @@
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
@@ -57,53 +57,53 @@ static bool checkScale(unsigned Scale, StringRef &ErrMsg) {
namespace {
static const char OpPrecedence[] = {
- 0, // IC_OR
- 1, // IC_XOR
- 2, // IC_AND
- 4, // IC_LSHIFT
- 4, // IC_RSHIFT
- 5, // IC_PLUS
- 5, // IC_MINUS
- 6, // IC_MULTIPLY
- 6, // IC_DIVIDE
- 6, // IC_MOD
- 7, // IC_NOT
- 8, // IC_NEG
- 9, // IC_RPAREN
- 10, // IC_LPAREN
- 0, // IC_IMM
- 0, // IC_REGISTER
- 3, // IC_EQ
- 3, // IC_NE
- 3, // IC_LT
- 3, // IC_LE
- 3, // IC_GT
- 3 // IC_GE
+ 0, // IC_OR
+ 1, // IC_XOR
+ 2, // IC_AND
+ 4, // IC_LSHIFT
+ 4, // IC_RSHIFT
+ 5, // IC_PLUS
+ 5, // IC_MINUS
+ 6, // IC_MULTIPLY
+ 6, // IC_DIVIDE
+ 6, // IC_MOD
+ 7, // IC_NOT
+ 8, // IC_NEG
+ 9, // IC_RPAREN
+ 10, // IC_LPAREN
+ 0, // IC_IMM
+ 0, // IC_REGISTER
+ 3, // IC_EQ
+ 3, // IC_NE
+ 3, // IC_LT
+ 3, // IC_LE
+ 3, // IC_GT
+ 3 // IC_GE
};
class X86AsmParser : public MCTargetAsmParser {
ParseInstructionInfo *InstInfo;
bool Code16GCC;
- unsigned ForcedDataPrefix = 0;
+ unsigned ForcedDataPrefix = 0;
enum VEXEncoding {
VEXEncoding_Default,
VEXEncoding_VEX,
- VEXEncoding_VEX2,
+ VEXEncoding_VEX2,
VEXEncoding_VEX3,
VEXEncoding_EVEX,
};
VEXEncoding ForcedVEXEncoding = VEXEncoding_Default;
- enum DispEncoding {
- DispEncoding_Default,
- DispEncoding_Disp8,
- DispEncoding_Disp32,
- };
-
- DispEncoding ForcedDispEncoding = DispEncoding_Default;
-
+ enum DispEncoding {
+ DispEncoding_Default,
+ DispEncoding_Disp8,
+ DispEncoding_Disp32,
+ };
+
+ DispEncoding ForcedDispEncoding = DispEncoding_Default;
+
private:
SMLoc consumeToken() {
MCAsmParser &Parser = getParser();
@@ -149,13 +149,13 @@ private:
IC_RPAREN,
IC_LPAREN,
IC_IMM,
- IC_REGISTER,
- IC_EQ,
- IC_NE,
- IC_LT,
- IC_LE,
- IC_GT,
- IC_GE
+ IC_REGISTER,
+ IC_EQ,
+ IC_NE,
+ IC_LT,
+ IC_LE,
+ IC_GT,
+ IC_GE
};
enum IntelOperatorKind {
@@ -165,19 +165,19 @@ private:
IOK_TYPE,
};
- enum MasmOperatorKind {
- MOK_INVALID = 0,
- MOK_LENGTHOF,
- MOK_SIZEOF,
- MOK_TYPE,
- };
-
+ enum MasmOperatorKind {
+ MOK_INVALID = 0,
+ MOK_LENGTHOF,
+ MOK_SIZEOF,
+ MOK_TYPE,
+ };
+
class InfixCalculator {
typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;
SmallVector<ICToken, 4> PostfixStack;
- bool isUnaryOperator(InfixCalculatorTok Op) const {
+ bool isUnaryOperator(InfixCalculatorTok Op) const {
return Op == IC_NEG || Op == IC_NOT;
}
@@ -344,44 +344,44 @@ private:
Val = Op1.second >> Op2.second;
OperandStack.push_back(std::make_pair(IC_IMM, Val));
break;
- case IC_EQ:
- assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
- "Equals operation with an immediate and a register!");
- Val = (Op1.second == Op2.second) ? -1 : 0;
- OperandStack.push_back(std::make_pair(IC_IMM, Val));
- break;
- case IC_NE:
- assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
- "Not-equals operation with an immediate and a register!");
- Val = (Op1.second != Op2.second) ? -1 : 0;
- OperandStack.push_back(std::make_pair(IC_IMM, Val));
- break;
- case IC_LT:
- assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
- "Less-than operation with an immediate and a register!");
- Val = (Op1.second < Op2.second) ? -1 : 0;
- OperandStack.push_back(std::make_pair(IC_IMM, Val));
- break;
- case IC_LE:
- assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
- "Less-than-or-equal operation with an immediate and a "
- "register!");
- Val = (Op1.second <= Op2.second) ? -1 : 0;
- OperandStack.push_back(std::make_pair(IC_IMM, Val));
- break;
- case IC_GT:
- assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
- "Greater-than operation with an immediate and a register!");
- Val = (Op1.second > Op2.second) ? -1 : 0;
- OperandStack.push_back(std::make_pair(IC_IMM, Val));
- break;
- case IC_GE:
- assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
- "Greater-than-or-equal operation with an immediate and a "
- "register!");
- Val = (Op1.second >= Op2.second) ? -1 : 0;
- OperandStack.push_back(std::make_pair(IC_IMM, Val));
- break;
+ case IC_EQ:
+ assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
+ "Equals operation with an immediate and a register!");
+ Val = (Op1.second == Op2.second) ? -1 : 0;
+ OperandStack.push_back(std::make_pair(IC_IMM, Val));
+ break;
+ case IC_NE:
+ assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
+ "Not-equals operation with an immediate and a register!");
+ Val = (Op1.second != Op2.second) ? -1 : 0;
+ OperandStack.push_back(std::make_pair(IC_IMM, Val));
+ break;
+ case IC_LT:
+ assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
+ "Less-than operation with an immediate and a register!");
+ Val = (Op1.second < Op2.second) ? -1 : 0;
+ OperandStack.push_back(std::make_pair(IC_IMM, Val));
+ break;
+ case IC_LE:
+ assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
+ "Less-than-or-equal operation with an immediate and a "
+ "register!");
+ Val = (Op1.second <= Op2.second) ? -1 : 0;
+ OperandStack.push_back(std::make_pair(IC_IMM, Val));
+ break;
+ case IC_GT:
+ assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
+ "Greater-than operation with an immediate and a register!");
+ Val = (Op1.second > Op2.second) ? -1 : 0;
+ OperandStack.push_back(std::make_pair(IC_IMM, Val));
+ break;
+ case IC_GE:
+ assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
+ "Greater-than-or-equal operation with an immediate and a "
+ "register!");
+ Val = (Op1.second >= Op2.second) ? -1 : 0;
+ OperandStack.push_back(std::make_pair(IC_IMM, Val));
+ break;
}
}
}
@@ -395,12 +395,12 @@ private:
IES_OR,
IES_XOR,
IES_AND,
- IES_EQ,
- IES_NE,
- IES_LT,
- IES_LE,
- IES_GT,
- IES_GE,
+ IES_EQ,
+ IES_NE,
+ IES_LT,
+ IES_LE,
+ IES_GT,
+ IES_GE,
IES_LSHIFT,
IES_RSHIFT,
IES_PLUS,
@@ -433,7 +433,7 @@ private:
bool MemExpr;
bool OffsetOperator;
SMLoc OffsetOperatorLoc;
- AsmTypeInfo CurType;
+ AsmTypeInfo CurType;
bool setSymRef(const MCExpr *Val, StringRef ID, StringRef &ErrMsg) {
if (Sym) {
@@ -452,25 +452,25 @@ private:
MemExpr(false), OffsetOperator(false) {}
void addImm(int64_t imm) { Imm += imm; }
- short getBracCount() const { return BracCount; }
- bool isMemExpr() const { return MemExpr; }
- bool isOffsetOperator() const { return OffsetOperator; }
- SMLoc getOffsetLoc() const { return OffsetOperatorLoc; }
- unsigned getBaseReg() const { return BaseReg; }
- unsigned getIndexReg() const { return IndexReg; }
- unsigned getScale() const { return Scale; }
- const MCExpr *getSym() const { return Sym; }
- StringRef getSymName() const { return SymName; }
- StringRef getType() const { return CurType.Name; }
- unsigned getSize() const { return CurType.Size; }
- unsigned getElementSize() const { return CurType.ElementSize; }
- unsigned getLength() const { return CurType.Length; }
+ short getBracCount() const { return BracCount; }
+ bool isMemExpr() const { return MemExpr; }
+ bool isOffsetOperator() const { return OffsetOperator; }
+ SMLoc getOffsetLoc() const { return OffsetOperatorLoc; }
+ unsigned getBaseReg() const { return BaseReg; }
+ unsigned getIndexReg() const { return IndexReg; }
+ unsigned getScale() const { return Scale; }
+ const MCExpr *getSym() const { return Sym; }
+ StringRef getSymName() const { return SymName; }
+ StringRef getType() const { return CurType.Name; }
+ unsigned getSize() const { return CurType.Size; }
+ unsigned getElementSize() const { return CurType.ElementSize; }
+ unsigned getLength() const { return CurType.Length; }
int64_t getImm() { return Imm + IC.execute(); }
- bool isValidEndState() const {
+ bool isValidEndState() const {
return State == IES_RBRAC || State == IES_INTEGER;
}
- bool hadError() const { return State == IES_ERROR; }
- const InlineAsmIdentifierInfo &getIdentifierInfo() const { return Info; }
+ bool hadError() const { return State == IES_ERROR; }
+ const InlineAsmIdentifierInfo &getIdentifierInfo() const { return Info; }
void onOr() {
IntelExprState CurrState = State;
@@ -517,96 +517,96 @@ private:
}
PrevState = CurrState;
}
- void onEq() {
- IntelExprState CurrState = State;
- switch (State) {
- default:
- State = IES_ERROR;
- break;
- case IES_INTEGER:
- case IES_RPAREN:
- case IES_REGISTER:
- State = IES_EQ;
- IC.pushOperator(IC_EQ);
- break;
- }
- PrevState = CurrState;
- }
- void onNE() {
- IntelExprState CurrState = State;
- switch (State) {
- default:
- State = IES_ERROR;
- break;
- case IES_INTEGER:
- case IES_RPAREN:
- case IES_REGISTER:
- State = IES_NE;
- IC.pushOperator(IC_NE);
- break;
- }
- PrevState = CurrState;
- }
- void onLT() {
- IntelExprState CurrState = State;
- switch (State) {
- default:
- State = IES_ERROR;
- break;
- case IES_INTEGER:
- case IES_RPAREN:
- case IES_REGISTER:
- State = IES_LT;
- IC.pushOperator(IC_LT);
- break;
- }
- PrevState = CurrState;
- }
- void onLE() {
- IntelExprState CurrState = State;
- switch (State) {
- default:
- State = IES_ERROR;
- break;
- case IES_INTEGER:
- case IES_RPAREN:
- case IES_REGISTER:
- State = IES_LE;
- IC.pushOperator(IC_LE);
- break;
- }
- PrevState = CurrState;
- }
- void onGT() {
- IntelExprState CurrState = State;
- switch (State) {
- default:
- State = IES_ERROR;
- break;
- case IES_INTEGER:
- case IES_RPAREN:
- case IES_REGISTER:
- State = IES_GT;
- IC.pushOperator(IC_GT);
- break;
- }
- PrevState = CurrState;
- }
- void onGE() {
- IntelExprState CurrState = State;
- switch (State) {
- default:
- State = IES_ERROR;
- break;
- case IES_INTEGER:
- case IES_RPAREN:
- case IES_REGISTER:
- State = IES_GE;
- IC.pushOperator(IC_GE);
- break;
- }
- PrevState = CurrState;
- }
+ void onEq() {
+ IntelExprState CurrState = State;
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_INTEGER:
+ case IES_RPAREN:
+ case IES_REGISTER:
+ State = IES_EQ;
+ IC.pushOperator(IC_EQ);
+ break;
+ }
+ PrevState = CurrState;
+ }
+ void onNE() {
+ IntelExprState CurrState = State;
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_INTEGER:
+ case IES_RPAREN:
+ case IES_REGISTER:
+ State = IES_NE;
+ IC.pushOperator(IC_NE);
+ break;
+ }
+ PrevState = CurrState;
+ }
+ void onLT() {
+ IntelExprState CurrState = State;
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_INTEGER:
+ case IES_RPAREN:
+ case IES_REGISTER:
+ State = IES_LT;
+ IC.pushOperator(IC_LT);
+ break;
+ }
+ PrevState = CurrState;
+ }
+ void onLE() {
+ IntelExprState CurrState = State;
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_INTEGER:
+ case IES_RPAREN:
+ case IES_REGISTER:
+ State = IES_LE;
+ IC.pushOperator(IC_LE);
+ break;
+ }
+ PrevState = CurrState;
+ }
+ void onGT() {
+ IntelExprState CurrState = State;
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_INTEGER:
+ case IES_RPAREN:
+ case IES_REGISTER:
+ State = IES_GT;
+ IC.pushOperator(IC_GT);
+ break;
+ }
+ PrevState = CurrState;
+ }
+ void onGE() {
+ IntelExprState CurrState = State;
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_INTEGER:
+ case IES_RPAREN:
+ case IES_REGISTER:
+ State = IES_GE;
+ IC.pushOperator(IC_GE);
+ break;
+ }
+ PrevState = CurrState;
+ }
void onLShift() {
IntelExprState CurrState = State;
switch (State) {
@@ -677,12 +677,12 @@ private:
case IES_OR:
case IES_XOR:
case IES_AND:
- case IES_EQ:
- case IES_NE:
- case IES_LT:
- case IES_LE:
- case IES_GT:
- case IES_GE:
+ case IES_EQ:
+ case IES_NE:
+ case IES_LT:
+ case IES_LE:
+ case IES_GT:
+ case IES_GE:
case IES_LSHIFT:
case IES_RSHIFT:
case IES_PLUS:
@@ -738,12 +738,12 @@ private:
case IES_OR:
case IES_XOR:
case IES_AND:
- case IES_EQ:
- case IES_NE:
- case IES_LT:
- case IES_LE:
- case IES_GT:
- case IES_GE:
+ case IES_EQ:
+ case IES_NE:
+ case IES_LT:
+ case IES_LE:
+ case IES_GT:
+ case IES_GE:
case IES_LSHIFT:
case IES_RSHIFT:
case IES_PLUS:
@@ -799,8 +799,8 @@ private:
}
bool onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName,
const InlineAsmIdentifierInfo &IDInfo,
- const AsmTypeInfo &Type, bool ParsingMSInlineAsm,
- StringRef &ErrMsg) {
+ const AsmTypeInfo &Type, bool ParsingMSInlineAsm,
+ StringRef &ErrMsg) {
// InlineAsm: Treat an enum value as an integer
if (ParsingMSInlineAsm)
if (IDInfo.isKind(InlineAsmIdentifierInfo::IK_EnumVal))
@@ -819,7 +819,7 @@ private:
case IES_NOT:
case IES_INIT:
case IES_LBRAC:
- case IES_LPAREN:
+ case IES_LPAREN:
if (setSymRef(SymRef, SymRefName, ErrMsg))
return true;
MemExpr = true;
@@ -827,7 +827,7 @@ private:
IC.pushOperand(IC_IMM);
if (ParsingMSInlineAsm)
Info = IDInfo;
- setTypeInfo(Type);
+ setTypeInfo(Type);
break;
}
return false;
@@ -844,12 +844,12 @@ private:
case IES_OR:
case IES_XOR:
case IES_AND:
- case IES_EQ:
- case IES_NE:
- case IES_LT:
- case IES_LE:
- case IES_GT:
- case IES_GE:
+ case IES_EQ:
+ case IES_NE:
+ case IES_LT:
+ case IES_LE:
+ case IES_GT:
+ case IES_GE:
case IES_LSHIFT:
case IES_RSHIFT:
case IES_DIVIDE:
@@ -932,8 +932,8 @@ private:
case IES_RPAREN:
State = IES_PLUS;
IC.pushOperator(IC_PLUS);
- CurType.Length = 1;
- CurType.Size = CurType.ElementSize;
+ CurType.Length = 1;
+ CurType.Size = CurType.ElementSize;
break;
case IES_INIT:
case IES_CAST:
@@ -986,12 +986,12 @@ private:
case IES_OR:
case IES_XOR:
case IES_AND:
- case IES_EQ:
- case IES_NE:
- case IES_LT:
- case IES_LE:
- case IES_GT:
- case IES_GE:
+ case IES_EQ:
+ case IES_NE:
+ case IES_LT:
+ case IES_LE:
+ case IES_GT:
+ case IES_GE:
case IES_LSHIFT:
case IES_RSHIFT:
case IES_MULTIPLY:
@@ -1023,8 +1023,8 @@ private:
}
}
bool onOffset(const MCExpr *Val, SMLoc OffsetLoc, StringRef ID,
- const InlineAsmIdentifierInfo &IDInfo,
- bool ParsingMSInlineAsm, StringRef &ErrMsg) {
+ const InlineAsmIdentifierInfo &IDInfo,
+ bool ParsingMSInlineAsm, StringRef &ErrMsg) {
PrevState = State;
switch (State) {
default:
@@ -1048,19 +1048,19 @@ private:
}
return false;
}
- void onCast(AsmTypeInfo Info) {
+ void onCast(AsmTypeInfo Info) {
PrevState = State;
switch (State) {
default:
State = IES_ERROR;
break;
case IES_LPAREN:
- setTypeInfo(Info);
+ setTypeInfo(Info);
State = IES_CAST;
break;
}
}
- void setTypeInfo(AsmTypeInfo Type) { CurType = Type; }
+ void setTypeInfo(AsmTypeInfo Type) { CurType = Type; }
};
bool Error(SMLoc L, const Twine &Msg, SMRange Range = None,
@@ -1089,21 +1089,21 @@ private:
std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
bool VerifyAndAdjustOperands(OperandVector &OrigOperands,
OperandVector &FinalOperands);
- bool ParseOperand(OperandVector &Operands);
- bool ParseATTOperand(OperandVector &Operands);
- bool ParseIntelOperand(OperandVector &Operands);
+ bool ParseOperand(OperandVector &Operands);
+ bool ParseATTOperand(OperandVector &Operands);
+ bool ParseIntelOperand(OperandVector &Operands);
bool ParseIntelOffsetOperator(const MCExpr *&Val, StringRef &ID,
InlineAsmIdentifierInfo &Info, SMLoc &End);
bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End);
unsigned IdentifyIntelInlineAsmOperator(StringRef Name);
unsigned ParseIntelInlineAsmOperator(unsigned OpKind);
- unsigned IdentifyMasmOperator(StringRef Name);
- bool ParseMasmOperator(unsigned OpKind, int64_t &Val);
- bool ParseRoundingModeOp(SMLoc Start, OperandVector &Operands);
+ unsigned IdentifyMasmOperator(StringRef Name);
+ bool ParseMasmOperator(unsigned OpKind, int64_t &Val);
+ bool ParseRoundingModeOp(SMLoc Start, OperandVector &Operands);
bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM,
bool &ParseError, SMLoc &End);
- bool ParseMasmNamedOperator(StringRef Name, IntelExprStateMachine &SM,
- bool &ParseError, SMLoc &End);
+ bool ParseMasmNamedOperator(StringRef Name, IntelExprStateMachine &SM,
+ bool &ParseError, SMLoc &End);
void RewriteIntelExpression(IntelExprStateMachine &SM, SMLoc Start,
SMLoc End);
bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
@@ -1112,21 +1112,21 @@ private:
bool IsUnevaluatedOperand, SMLoc &End,
bool IsParsingOffsetOperator = false);
- bool ParseMemOperand(unsigned SegReg, const MCExpr *Disp, SMLoc StartLoc,
- SMLoc EndLoc, OperandVector &Operands);
+ bool ParseMemOperand(unsigned SegReg, const MCExpr *Disp, SMLoc StartLoc,
+ SMLoc EndLoc, OperandVector &Operands);
X86::CondCode ParseConditionCode(StringRef CCode);
bool ParseIntelMemoryOperandSize(unsigned &Size);
- bool CreateMemForMSInlineAsm(unsigned SegReg, const MCExpr *Disp,
- unsigned BaseReg, unsigned IndexReg,
- unsigned Scale, SMLoc Start, SMLoc End,
- unsigned Size, StringRef Identifier,
- const InlineAsmIdentifierInfo &Info,
- OperandVector &Operands);
-
- bool parseDirectiveArch();
- bool parseDirectiveNops(SMLoc L);
+ bool CreateMemForMSInlineAsm(unsigned SegReg, const MCExpr *Disp,
+ unsigned BaseReg, unsigned IndexReg,
+ unsigned Scale, SMLoc Start, SMLoc End,
+ unsigned Size, StringRef Identifier,
+ const InlineAsmIdentifierInfo &Info,
+ OperandVector &Operands);
+
+ bool parseDirectiveArch();
+ bool parseDirectiveNops(SMLoc L);
bool parseDirectiveEven(SMLoc L);
bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
@@ -1187,7 +1187,7 @@ private:
/// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
/// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
/// return false if no parsing errors occurred, true otherwise.
- bool HandleAVX512Operand(OperandVector &Operands);
+ bool HandleAVX512Operand(OperandVector &Operands);
bool ParseZ(std::unique_ptr<X86Operand> &Z, const SMLoc &StartLoc);
@@ -1716,17 +1716,17 @@ bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands,
return false;
}
-bool X86AsmParser::ParseOperand(OperandVector &Operands) {
+bool X86AsmParser::ParseOperand(OperandVector &Operands) {
if (isParsingIntelSyntax())
- return ParseIntelOperand(Operands);
-
- return ParseATTOperand(Operands);
+ return ParseIntelOperand(Operands);
+
+ return ParseATTOperand(Operands);
}
-bool X86AsmParser::CreateMemForMSInlineAsm(
+bool X86AsmParser::CreateMemForMSInlineAsm(
unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
- const InlineAsmIdentifierInfo &Info, OperandVector &Operands) {
+ const InlineAsmIdentifierInfo &Info, OperandVector &Operands) {
// If we found a decl other than a VarDecl, then assume it is a FuncDecl or
// some other label reference.
if (Info.isKind(InlineAsmIdentifierInfo::IK_Label)) {
@@ -1738,10 +1738,10 @@ bool X86AsmParser::CreateMemForMSInlineAsm(
}
// Create an absolute memory reference in order to match against
// instructions taking a PC relative operand.
- Operands.push_back(X86Operand::CreateMem(getPointerWidth(), Disp, Start,
- End, Size, Identifier,
- Info.Label.Decl));
- return false;
+ Operands.push_back(X86Operand::CreateMem(getPointerWidth(), Disp, Start,
+ End, Size, Identifier,
+ Info.Label.Decl));
+ return false;
}
// We either have a direct symbol reference, or an offset from a symbol. The
// parser always puts the symbol on the LHS, so look there for size
@@ -1758,19 +1758,19 @@ bool X86AsmParser::CreateMemForMSInlineAsm(
// It is widely common for MS InlineAsm to use a global variable and one/two
// registers in a mmory expression, and though unaccessible via rip/eip.
if (IsGlobalLV && (BaseReg || IndexReg)) {
- Operands.push_back(
- X86Operand::CreateMem(getPointerWidth(), Disp, Start, End));
- return false;
- }
+ Operands.push_back(
+ X86Operand::CreateMem(getPointerWidth(), Disp, Start, End));
+ return false;
+ }
// Otherwise, we set the base register to a non-zero value
// if we don't know the actual value at this time. This is necessary to
// get the matching correct in some cases.
- BaseReg = BaseReg ? BaseReg : 1;
- Operands.push_back(X86Operand::CreateMem(
- getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End,
- Size,
- /*DefaultBaseReg=*/X86::RIP, Identifier, Decl, FrontendSize));
- return false;
+ BaseReg = BaseReg ? BaseReg : 1;
+ Operands.push_back(X86Operand::CreateMem(
+ getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End,
+ Size,
+ /*DefaultBaseReg=*/X86::RIP, Identifier, Decl, FrontendSize));
+ return false;
}
// Some binary bitwise operators have a named synonymous
@@ -1779,10 +1779,10 @@ bool X86AsmParser::CreateMemForMSInlineAsm(
bool X86AsmParser::ParseIntelNamedOperator(StringRef Name,
IntelExprStateMachine &SM,
bool &ParseError, SMLoc &End) {
- // A named operator should be either lower or upper case, but not a mix...
- // except in MASM, which uses full case-insensitivity.
- if (Name.compare(Name.lower()) && Name.compare(Name.upper()) &&
- !getParser().isParsingMasm())
+ // A named operator should be either lower or upper case, but not a mix...
+ // except in MASM, which uses full case-insensitivity.
+ if (Name.compare(Name.lower()) && Name.compare(Name.upper()) &&
+ !getParser().isParsingMasm())
return false;
if (Name.equals_lower("not")) {
SM.onNot();
@@ -1818,27 +1818,27 @@ bool X86AsmParser::ParseIntelNamedOperator(StringRef Name,
End = consumeToken();
return true;
}
-bool X86AsmParser::ParseMasmNamedOperator(StringRef Name,
- IntelExprStateMachine &SM,
- bool &ParseError, SMLoc &End) {
- if (Name.equals_lower("eq")) {
- SM.onEq();
- } else if (Name.equals_lower("ne")) {
- SM.onNE();
- } else if (Name.equals_lower("lt")) {
- SM.onLT();
- } else if (Name.equals_lower("le")) {
- SM.onLE();
- } else if (Name.equals_lower("gt")) {
- SM.onGT();
- } else if (Name.equals_lower("ge")) {
- SM.onGE();
- } else {
- return false;
- }
- End = consumeToken();
- return true;
-}
+bool X86AsmParser::ParseMasmNamedOperator(StringRef Name,
+ IntelExprStateMachine &SM,
+ bool &ParseError, SMLoc &End) {
+ if (Name.equals_lower("eq")) {
+ SM.onEq();
+ } else if (Name.equals_lower("ne")) {
+ SM.onNE();
+ } else if (Name.equals_lower("lt")) {
+ SM.onLT();
+ } else if (Name.equals_lower("le")) {
+ SM.onLE();
+ } else if (Name.equals_lower("gt")) {
+ SM.onGT();
+ } else if (Name.equals_lower("ge")) {
+ SM.onGE();
+ } else {
+ return false;
+ }
+ End = consumeToken();
+ return true;
+}
bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
MCAsmParser &Parser = getParser();
@@ -1847,10 +1847,10 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
AsmToken::TokenKind PrevTK = AsmToken::Error;
bool Done = false;
while (!Done) {
- // Get a fresh reference on each loop iteration in case the previous
- // iteration moved the token storage during UnLex().
- const AsmToken &Tok = Parser.getTok();
-
+ // Get a fresh reference on each loop iteration in case the previous
+ // iteration moved the token storage during UnLex().
+ const AsmToken &Tok = Parser.getTok();
+
bool UpdateLocLex = true;
AsmToken::TokenKind TK = getLexer().getKind();
@@ -1859,9 +1859,9 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
if ((Done = SM.isValidEndState()))
break;
return Error(Tok.getLoc(), "unknown token in expression");
- case AsmToken::Error:
- return Error(getLexer().getErrLoc(), getLexer().getErr());
- break;
+ case AsmToken::Error:
+ return Error(getLexer().getErrLoc(), getLexer().getErr());
+ break;
case AsmToken::EndOfStatement:
Done = true;
break;
@@ -1871,73 +1871,73 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
if (ParseIntelDotOperator(SM, End))
return true;
break;
- case AsmToken::Dot:
- if (!Parser.isParsingMasm()) {
- if ((Done = SM.isValidEndState()))
- break;
- return Error(Tok.getLoc(), "unknown token in expression");
- }
- // MASM allows spaces around the dot operator (e.g., "var . x")
- Lex();
- UpdateLocLex = false;
- if (ParseIntelDotOperator(SM, End))
- return true;
- break;
- case AsmToken::Dollar:
- if (!Parser.isParsingMasm()) {
- if ((Done = SM.isValidEndState()))
- break;
- return Error(Tok.getLoc(), "unknown token in expression");
- }
- LLVM_FALLTHROUGH;
- case AsmToken::String: {
- if (Parser.isParsingMasm()) {
- // MASM parsers handle strings in expressions as constants.
- SMLoc ValueLoc = Tok.getLoc();
- int64_t Res;
- const MCExpr *Val;
- if (Parser.parsePrimaryExpr(Val, End, nullptr))
- return true;
- UpdateLocLex = false;
- if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
- return Error(ValueLoc, "expected absolute value");
- if (SM.onInteger(Res, ErrMsg))
- return Error(ValueLoc, ErrMsg);
- break;
- }
- LLVM_FALLTHROUGH;
- }
+ case AsmToken::Dot:
+ if (!Parser.isParsingMasm()) {
+ if ((Done = SM.isValidEndState()))
+ break;
+ return Error(Tok.getLoc(), "unknown token in expression");
+ }
+ // MASM allows spaces around the dot operator (e.g., "var . x")
+ Lex();
+ UpdateLocLex = false;
+ if (ParseIntelDotOperator(SM, End))
+ return true;
+ break;
+ case AsmToken::Dollar:
+ if (!Parser.isParsingMasm()) {
+ if ((Done = SM.isValidEndState()))
+ break;
+ return Error(Tok.getLoc(), "unknown token in expression");
+ }
+ LLVM_FALLTHROUGH;
+ case AsmToken::String: {
+ if (Parser.isParsingMasm()) {
+ // MASM parsers handle strings in expressions as constants.
+ SMLoc ValueLoc = Tok.getLoc();
+ int64_t Res;
+ const MCExpr *Val;
+ if (Parser.parsePrimaryExpr(Val, End, nullptr))
+ return true;
+ UpdateLocLex = false;
+ if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
+ return Error(ValueLoc, "expected absolute value");
+ if (SM.onInteger(Res, ErrMsg))
+ return Error(ValueLoc, ErrMsg);
+ break;
+ }
+ LLVM_FALLTHROUGH;
+ }
case AsmToken::At:
case AsmToken::Identifier: {
SMLoc IdentLoc = Tok.getLoc();
StringRef Identifier = Tok.getString();
UpdateLocLex = false;
- if (Parser.isParsingMasm()) {
- size_t DotOffset = Identifier.find_first_of('.');
- if (DotOffset != StringRef::npos) {
- consumeToken();
- StringRef LHS = Identifier.slice(0, DotOffset);
- StringRef Dot = Identifier.slice(DotOffset, DotOffset + 1);
- StringRef RHS = Identifier.slice(DotOffset + 1, StringRef::npos);
- if (!RHS.empty()) {
- getLexer().UnLex(AsmToken(AsmToken::Identifier, RHS));
- }
- getLexer().UnLex(AsmToken(AsmToken::Dot, Dot));
- if (!LHS.empty()) {
- getLexer().UnLex(AsmToken(AsmToken::Identifier, LHS));
- }
- break;
- }
- }
+ if (Parser.isParsingMasm()) {
+ size_t DotOffset = Identifier.find_first_of('.');
+ if (DotOffset != StringRef::npos) {
+ consumeToken();
+ StringRef LHS = Identifier.slice(0, DotOffset);
+ StringRef Dot = Identifier.slice(DotOffset, DotOffset + 1);
+ StringRef RHS = Identifier.slice(DotOffset + 1, StringRef::npos);
+ if (!RHS.empty()) {
+ getLexer().UnLex(AsmToken(AsmToken::Identifier, RHS));
+ }
+ getLexer().UnLex(AsmToken(AsmToken::Dot, Dot));
+ if (!LHS.empty()) {
+ getLexer().UnLex(AsmToken(AsmToken::Identifier, LHS));
+ }
+ break;
+ }
+ }
// (MASM only) <TYPE> PTR operator
if (Parser.isParsingMasm()) {
const AsmToken &NextTok = getLexer().peekTok();
if (NextTok.is(AsmToken::Identifier) &&
NextTok.getIdentifier().equals_lower("ptr")) {
- AsmTypeInfo Info;
- if (Parser.lookUpType(Identifier, Info))
- return Error(Tok.getLoc(), "unknown type");
- SM.onCast(Info);
+ AsmTypeInfo Info;
+ if (Parser.lookUpType(Identifier, Info))
+ return Error(Tok.getLoc(), "unknown type");
+ SM.onCast(Info);
// Eat type and PTR.
consumeToken();
End = consumeToken();
@@ -1962,15 +1962,15 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
if (SM.onRegister(Reg, ErrMsg))
return Error(IdentLoc, ErrMsg);
- AsmFieldInfo Info;
+ AsmFieldInfo Info;
SMLoc FieldStartLoc = SMLoc::getFromPointer(Field.data());
- if (Parser.lookUpField(Field, Info))
+ if (Parser.lookUpField(Field, Info))
return Error(FieldStartLoc, "unknown offset");
else if (SM.onPlus(ErrMsg))
return Error(getTok().getLoc(), ErrMsg);
- else if (SM.onInteger(Info.Offset, ErrMsg))
+ else if (SM.onInteger(Info.Offset, ErrMsg))
return Error(IdentLoc, ErrMsg);
- SM.setTypeInfo(Info.Type);
+ SM.setTypeInfo(Info.Type);
End = consumeToken();
break;
@@ -1984,15 +1984,15 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
return true;
break;
}
- if (Parser.isParsingMasm() &&
- ParseMasmNamedOperator(Identifier, SM, ParseError, End)) {
- if (ParseError)
- return true;
- break;
- }
+ if (Parser.isParsingMasm() &&
+ ParseMasmNamedOperator(Identifier, SM, ParseError, End)) {
+ if (ParseError)
+ return true;
+ break;
+ }
// Symbol reference, when parsing assembly content
InlineAsmIdentifierInfo Info;
- AsmFieldInfo FieldInfo;
+ AsmFieldInfo FieldInfo;
const MCExpr *Val;
if (isParsingMSInlineAsm() || Parser.isParsingMasm()) {
// MS Dot Operator expression
@@ -2009,9 +2009,9 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
if (SM.onInteger(Val, ErrMsg))
return Error(IdentLoc, ErrMsg);
- } else {
+ } else {
return true;
- }
+ }
break;
}
// MS InlineAsm identifier
@@ -2020,49 +2020,49 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
return Error(IdentLoc, "expected identifier");
if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info, false, End))
return true;
- else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.Type,
- true, ErrMsg))
+ else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.Type,
+ true, ErrMsg))
return Error(IdentLoc, ErrMsg);
break;
}
- if (Parser.isParsingMasm()) {
- if (unsigned OpKind = IdentifyMasmOperator(Identifier)) {
- int64_t Val;
- if (ParseMasmOperator(OpKind, Val))
- return true;
- if (SM.onInteger(Val, ErrMsg))
- return Error(IdentLoc, ErrMsg);
- break;
- }
- if (!getParser().lookUpType(Identifier, FieldInfo.Type)) {
- // Field offset immediate; <TYPE>.<field specification>
- Lex(); // eat type
- bool EndDot = parseOptionalToken(AsmToken::Dot);
- while (EndDot || (getTok().is(AsmToken::Identifier) &&
- getTok().getString().startswith("."))) {
- getParser().parseIdentifier(Identifier);
- if (!EndDot)
- Identifier.consume_front(".");
- EndDot = Identifier.consume_back(".");
- if (getParser().lookUpField(FieldInfo.Type.Name, Identifier,
- FieldInfo)) {
- SMLoc IDEnd =
- SMLoc::getFromPointer(Identifier.data() + Identifier.size());
- return Error(IdentLoc, "Unable to lookup field reference!",
- SMRange(IdentLoc, IDEnd));
- }
- if (!EndDot)
- EndDot = parseOptionalToken(AsmToken::Dot);
- }
- if (SM.onInteger(FieldInfo.Offset, ErrMsg))
- return Error(IdentLoc, ErrMsg);
- break;
- }
- }
- if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.Type)) {
+ if (Parser.isParsingMasm()) {
+ if (unsigned OpKind = IdentifyMasmOperator(Identifier)) {
+ int64_t Val;
+ if (ParseMasmOperator(OpKind, Val))
+ return true;
+ if (SM.onInteger(Val, ErrMsg))
+ return Error(IdentLoc, ErrMsg);
+ break;
+ }
+ if (!getParser().lookUpType(Identifier, FieldInfo.Type)) {
+ // Field offset immediate; <TYPE>.<field specification>
+ Lex(); // eat type
+ bool EndDot = parseOptionalToken(AsmToken::Dot);
+ while (EndDot || (getTok().is(AsmToken::Identifier) &&
+ getTok().getString().startswith("."))) {
+ getParser().parseIdentifier(Identifier);
+ if (!EndDot)
+ Identifier.consume_front(".");
+ EndDot = Identifier.consume_back(".");
+ if (getParser().lookUpField(FieldInfo.Type.Name, Identifier,
+ FieldInfo)) {
+ SMLoc IDEnd =
+ SMLoc::getFromPointer(Identifier.data() + Identifier.size());
+ return Error(IdentLoc, "Unable to lookup field reference!",
+ SMRange(IdentLoc, IDEnd));
+ }
+ if (!EndDot)
+ EndDot = parseOptionalToken(AsmToken::Dot);
+ }
+ if (SM.onInteger(FieldInfo.Offset, ErrMsg))
+ return Error(IdentLoc, ErrMsg);
+ break;
+ }
+ }
+ if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.Type)) {
return Error(Tok.getLoc(), "Unexpected identifier!");
- } else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.Type,
- false, ErrMsg)) {
+ } else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.Type,
+ false, ErrMsg)) {
return Error(IdentLoc, ErrMsg);
}
break;
@@ -2085,9 +2085,9 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
return Error(Loc, "invalid reference to undefined symbol");
StringRef Identifier = Sym->getName();
InlineAsmIdentifierInfo Info;
- AsmTypeInfo Type;
- if (SM.onIdentifierExpr(Val, Identifier, Info, Type,
- isParsingMSInlineAsm(), ErrMsg))
+ AsmTypeInfo Type;
+ if (SM.onIdentifierExpr(Val, Identifier, Info, Type,
+ isParsingMSInlineAsm(), ErrMsg))
return Error(Loc, ErrMsg);
End = consumeToken();
} else {
@@ -2229,13 +2229,13 @@ bool X86AsmParser::ParseIntelInlineAsmIdentifier(
}
//ParseRoundingModeOp - Parse AVX-512 rounding mode operand
-bool X86AsmParser::ParseRoundingModeOp(SMLoc Start, OperandVector &Operands) {
+bool X86AsmParser::ParseRoundingModeOp(SMLoc Start, OperandVector &Operands) {
MCAsmParser &Parser = getParser();
const AsmToken &Tok = Parser.getTok();
// Eat "{" and mark the current place.
const SMLoc consumedToken = consumeToken();
if (Tok.isNot(AsmToken::Identifier))
- return Error(Tok.getLoc(), "Expected an identifier after {");
+ return Error(Tok.getLoc(), "Expected an identifier after {");
if (Tok.getIdentifier().startswith("r")){
int rndMode = StringSwitch<int>(Tok.getIdentifier())
.Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
@@ -2244,76 +2244,76 @@ bool X86AsmParser::ParseRoundingModeOp(SMLoc Start, OperandVector &Operands) {
.Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
.Default(-1);
if (-1 == rndMode)
- return Error(Tok.getLoc(), "Invalid rounding mode.");
+ return Error(Tok.getLoc(), "Invalid rounding mode.");
Parser.Lex(); // Eat "r*" of r*-sae
if (!getLexer().is(AsmToken::Minus))
- return Error(Tok.getLoc(), "Expected - at this point");
+ return Error(Tok.getLoc(), "Expected - at this point");
Parser.Lex(); // Eat "-"
Parser.Lex(); // Eat the sae
if (!getLexer().is(AsmToken::RCurly))
- return Error(Tok.getLoc(), "Expected } at this point");
+ return Error(Tok.getLoc(), "Expected } at this point");
SMLoc End = Tok.getEndLoc();
Parser.Lex(); // Eat "}"
const MCExpr *RndModeOp =
MCConstantExpr::create(rndMode, Parser.getContext());
- Operands.push_back(X86Operand::CreateImm(RndModeOp, Start, End));
- return false;
+ Operands.push_back(X86Operand::CreateImm(RndModeOp, Start, End));
+ return false;
}
if(Tok.getIdentifier().equals("sae")){
Parser.Lex(); // Eat the sae
if (!getLexer().is(AsmToken::RCurly))
- return Error(Tok.getLoc(), "Expected } at this point");
+ return Error(Tok.getLoc(), "Expected } at this point");
Parser.Lex(); // Eat "}"
- Operands.push_back(X86Operand::CreateToken("{sae}", consumedToken));
- return false;
+ Operands.push_back(X86Operand::CreateToken("{sae}", consumedToken));
+ return false;
}
- return Error(Tok.getLoc(), "unknown token in expression");
+ return Error(Tok.getLoc(), "unknown token in expression");
}
/// Parse the '.' operator.
bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM,
SMLoc &End) {
const AsmToken &Tok = getTok();
- AsmFieldInfo Info;
+ AsmFieldInfo Info;
// Drop the optional '.'.
StringRef DotDispStr = Tok.getString();
if (DotDispStr.startswith("."))
DotDispStr = DotDispStr.drop_front(1);
- StringRef TrailingDot;
+ StringRef TrailingDot;
// .Imm gets lexed as a real.
if (Tok.is(AsmToken::Real)) {
APInt DotDisp;
DotDispStr.getAsInteger(10, DotDisp);
- Info.Offset = DotDisp.getZExtValue();
+ Info.Offset = DotDisp.getZExtValue();
} else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&
Tok.is(AsmToken::Identifier)) {
- if (DotDispStr.endswith(".")) {
- TrailingDot = DotDispStr.substr(DotDispStr.size() - 1);
- DotDispStr = DotDispStr.drop_back(1);
- }
+ if (DotDispStr.endswith(".")) {
+ TrailingDot = DotDispStr.substr(DotDispStr.size() - 1);
+ DotDispStr = DotDispStr.drop_back(1);
+ }
const std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
const StringRef Base = BaseMember.first, Member = BaseMember.second;
- if (getParser().lookUpField(SM.getType(), DotDispStr, Info) &&
- getParser().lookUpField(SM.getSymName(), DotDispStr, Info) &&
- getParser().lookUpField(DotDispStr, Info) &&
+ if (getParser().lookUpField(SM.getType(), DotDispStr, Info) &&
+ getParser().lookUpField(SM.getSymName(), DotDispStr, Info) &&
+ getParser().lookUpField(DotDispStr, Info) &&
(!SemaCallback ||
- SemaCallback->LookupInlineAsmField(Base, Member, Info.Offset)))
+ SemaCallback->LookupInlineAsmField(Base, Member, Info.Offset)))
return Error(Tok.getLoc(), "Unable to lookup field reference!");
- } else {
+ } else {
return Error(Tok.getLoc(), "Unexpected token type!");
- }
+ }
// Eat the DotExpression and update End
End = SMLoc::getFromPointer(DotDispStr.data());
const char *DotExprEndLoc = DotDispStr.data() + DotDispStr.size();
while (Tok.getLoc().getPointer() < DotExprEndLoc)
Lex();
- if (!TrailingDot.empty())
- getLexer().UnLex(AsmToken(AsmToken::Dot, TrailingDot));
- SM.addImm(Info.Offset);
- SM.setTypeInfo(Info.Type);
+ if (!TrailingDot.empty())
+ getLexer().UnLex(AsmToken(AsmToken::Dot, TrailingDot));
+ SM.addImm(Info.Offset);
+ SM.setTypeInfo(Info.Type);
return false;
}
@@ -2328,7 +2328,7 @@ bool X86AsmParser::ParseIntelOffsetOperator(const MCExpr *&Val, StringRef &ID,
if (!isParsingMSInlineAsm()) {
if ((getTok().isNot(AsmToken::Identifier) &&
getTok().isNot(AsmToken::String)) ||
- getParser().parsePrimaryExpr(Val, End, nullptr))
+ getParser().parsePrimaryExpr(Val, End, nullptr))
return Error(Start, "unexpected token!");
} else if (ParseIntelInlineAsmIdentifier(Val, ID, Info, false, End, true)) {
return Error(Start, "unable to lookup expression");
@@ -2364,7 +2364,7 @@ unsigned X86AsmParser::ParseIntelInlineAsmOperator(unsigned OpKind) {
SMLoc Start = Tok.getLoc(), End;
StringRef Identifier = Tok.getString();
if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
- /*IsUnevaluatedOperand=*/true, End))
+ /*IsUnevaluatedOperand=*/true, End))
return 0;
if (!Info.isKind(InlineAsmIdentifierInfo::IK_Var)) {
@@ -2383,73 +2383,73 @@ unsigned X86AsmParser::ParseIntelInlineAsmOperator(unsigned OpKind) {
return CVal;
}
-// Query a candidate string for being an Intel assembly operator
-// Report back its kind, or IOK_INVALID if does not evaluated as a known one
-unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) {
- return StringSwitch<unsigned>(Name.lower())
- .Case("type", MOK_TYPE)
- .Cases("size", "sizeof", MOK_SIZEOF)
- .Cases("length", "lengthof", MOK_LENGTHOF)
- .Default(MOK_INVALID);
-}
-
-/// Parse the 'LENGTHOF', 'SIZEOF', and 'TYPE' operators. The LENGTHOF operator
-/// returns the number of elements in an array. It returns the value 1 for
-/// non-array variables. The SIZEOF operator returns the size of a type or
-/// variable in bytes. A variable's size is the product of its LENGTH and TYPE.
-/// The TYPE operator returns the size of a variable. If the variable is an
-/// array, TYPE returns the size of a single element.
-bool X86AsmParser::ParseMasmOperator(unsigned OpKind, int64_t &Val) {
- MCAsmParser &Parser = getParser();
- SMLoc OpLoc = Parser.getTok().getLoc();
- Parser.Lex(); // Eat operator.
-
- Val = 0;
- if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
- // Check for SIZEOF(<type>) and TYPE(<type>).
- bool InParens = Parser.getTok().is(AsmToken::LParen);
- const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.getTok();
- AsmTypeInfo Type;
- if (IDTok.is(AsmToken::Identifier) &&
- !Parser.lookUpType(IDTok.getIdentifier(), Type)) {
- Val = Type.Size;
-
- // Eat tokens.
- if (InParens)
- parseToken(AsmToken::LParen);
- parseToken(AsmToken::Identifier);
- if (InParens)
- parseToken(AsmToken::RParen);
- }
- }
-
- if (!Val) {
- IntelExprStateMachine SM;
- SMLoc End, Start = Parser.getTok().getLoc();
- if (ParseIntelExpression(SM, End))
- return true;
-
- switch (OpKind) {
- default:
- llvm_unreachable("Unexpected operand kind!");
- case MOK_SIZEOF:
- Val = SM.getSize();
- break;
- case MOK_LENGTHOF:
- Val = SM.getLength();
- break;
- case MOK_TYPE:
- Val = SM.getElementSize();
- break;
- }
-
- if (!Val)
- return Error(OpLoc, "expression has unknown type", SMRange(Start, End));
- }
-
- return false;
-}
-
+// Query a candidate string for being an Intel assembly operator
+// Report back its kind, or IOK_INVALID if does not evaluated as a known one
+unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) {
+ return StringSwitch<unsigned>(Name.lower())
+ .Case("type", MOK_TYPE)
+ .Cases("size", "sizeof", MOK_SIZEOF)
+ .Cases("length", "lengthof", MOK_LENGTHOF)
+ .Default(MOK_INVALID);
+}
+
+/// Parse the 'LENGTHOF', 'SIZEOF', and 'TYPE' operators. The LENGTHOF operator
+/// returns the number of elements in an array. It returns the value 1 for
+/// non-array variables. The SIZEOF operator returns the size of a type or
+/// variable in bytes. A variable's size is the product of its LENGTH and TYPE.
+/// The TYPE operator returns the size of a variable. If the variable is an
+/// array, TYPE returns the size of a single element.
+bool X86AsmParser::ParseMasmOperator(unsigned OpKind, int64_t &Val) {
+ MCAsmParser &Parser = getParser();
+ SMLoc OpLoc = Parser.getTok().getLoc();
+ Parser.Lex(); // Eat operator.
+
+ Val = 0;
+ if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
+ // Check for SIZEOF(<type>) and TYPE(<type>).
+ bool InParens = Parser.getTok().is(AsmToken::LParen);
+ const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.getTok();
+ AsmTypeInfo Type;
+ if (IDTok.is(AsmToken::Identifier) &&
+ !Parser.lookUpType(IDTok.getIdentifier(), Type)) {
+ Val = Type.Size;
+
+ // Eat tokens.
+ if (InParens)
+ parseToken(AsmToken::LParen);
+ parseToken(AsmToken::Identifier);
+ if (InParens)
+ parseToken(AsmToken::RParen);
+ }
+ }
+
+ if (!Val) {
+ IntelExprStateMachine SM;
+ SMLoc End, Start = Parser.getTok().getLoc();
+ if (ParseIntelExpression(SM, End))
+ return true;
+
+ switch (OpKind) {
+ default:
+ llvm_unreachable("Unexpected operand kind!");
+ case MOK_SIZEOF:
+ Val = SM.getSize();
+ break;
+ case MOK_LENGTHOF:
+ Val = SM.getLength();
+ break;
+ case MOK_TYPE:
+ Val = SM.getElementSize();
+ break;
+ }
+
+ if (!Val)
+ return Error(OpLoc, "expression has unknown type", SMRange(Start, End));
+ }
+
+ return false;
+}
+
bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) {
Size = StringSwitch<unsigned>(getTok().getString())
.Cases("BYTE", "byte", 8)
@@ -2476,7 +2476,7 @@ bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) {
return false;
}
-bool X86AsmParser::ParseIntelOperand(OperandVector &Operands) {
+bool X86AsmParser::ParseIntelOperand(OperandVector &Operands) {
MCAsmParser &Parser = getParser();
const AsmToken &Tok = Parser.getTok();
SMLoc Start, End;
@@ -2484,31 +2484,31 @@ bool X86AsmParser::ParseIntelOperand(OperandVector &Operands) {
// Parse optional Size directive.
unsigned Size;
if (ParseIntelMemoryOperandSize(Size))
- return true;
+ return true;
bool PtrInOperand = bool(Size);
Start = Tok.getLoc();
// Rounding mode operand.
if (getLexer().is(AsmToken::LCurly))
- return ParseRoundingModeOp(Start, Operands);
+ return ParseRoundingModeOp(Start, Operands);
// Register operand.
unsigned RegNo = 0;
if (Tok.is(AsmToken::Identifier) && !ParseRegister(RegNo, Start, End)) {
if (RegNo == X86::RIP)
- return Error(Start, "rip can only be used as a base register");
+ return Error(Start, "rip can only be used as a base register");
// A Register followed by ':' is considered a segment override
- if (Tok.isNot(AsmToken::Colon)) {
- if (PtrInOperand)
- return Error(Start, "expected memory operand after 'ptr', "
+ if (Tok.isNot(AsmToken::Colon)) {
+ if (PtrInOperand)
+ return Error(Start, "expected memory operand after 'ptr', "
"found register operand instead");
- Operands.push_back(X86Operand::CreateReg(RegNo, Start, End));
- return false;
- }
+ Operands.push_back(X86Operand::CreateReg(RegNo, Start, End));
+ return false;
+ }
// An alleged segment override. check if we have a valid segment register
if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
- return Error(Start, "invalid segment register");
+ return Error(Start, "invalid segment register");
// Eat ':' and update Start location
Start = Lex().getLoc();
}
@@ -2516,7 +2516,7 @@ bool X86AsmParser::ParseIntelOperand(OperandVector &Operands) {
// Immediates and Memory
IntelExprStateMachine SM;
if (ParseIntelExpression(SM, End))
- return true;
+ return true;
if (isParsingMSInlineAsm())
RewriteIntelExpression(SM, Start, Tok.getLoc());
@@ -2533,27 +2533,27 @@ bool X86AsmParser::ParseIntelOperand(OperandVector &Operands) {
// and we are parsing a segment override
if (!SM.isMemExpr() && !RegNo) {
if (isParsingMSInlineAsm() && SM.isOffsetOperator()) {
- const InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
+ const InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
if (Info.isKind(InlineAsmIdentifierInfo::IK_Var)) {
// Disp includes the address of a variable; make sure this is recorded
// for later handling.
- Operands.push_back(X86Operand::CreateImm(Disp, Start, End,
- SM.getSymName(), Info.Var.Decl,
- Info.Var.IsGlobalLV));
- return false;
+ Operands.push_back(X86Operand::CreateImm(Disp, Start, End,
+ SM.getSymName(), Info.Var.Decl,
+ Info.Var.IsGlobalLV));
+ return false;
}
}
- Operands.push_back(X86Operand::CreateImm(Disp, Start, End));
- return false;
+ Operands.push_back(X86Operand::CreateImm(Disp, Start, End));
+ return false;
}
StringRef ErrMsg;
unsigned BaseReg = SM.getBaseReg();
unsigned IndexReg = SM.getIndexReg();
unsigned Scale = SM.getScale();
- if (!PtrInOperand)
- Size = SM.getElementSize() << 3;
+ if (!PtrInOperand)
+ Size = SM.getElementSize() << 3;
if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
(IndexReg == X86::ESP || IndexReg == X86::RSP))
@@ -2572,7 +2572,7 @@ bool X86AsmParser::ParseIntelOperand(OperandVector &Operands) {
if (Scale != 0 &&
X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg))
- return Error(Start, "16-bit addresses cannot have a scale");
+ return Error(Start, "16-bit addresses cannot have a scale");
// If there was no explicit scale specified, change it to 1.
if (Scale == 0)
@@ -2588,33 +2588,33 @@ bool X86AsmParser::ParseIntelOperand(OperandVector &Operands) {
if ((BaseReg || IndexReg) &&
CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(),
ErrMsg))
- return Error(Start, ErrMsg);
+ return Error(Start, ErrMsg);
if (isParsingMSInlineAsm())
return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale, Start,
End, Size, SM.getSymName(),
- SM.getIdentifierInfo(), Operands);
+ SM.getIdentifierInfo(), Operands);
// When parsing x64 MS-style assembly, all memory operands default to
// RIP-relative when interpreted as non-absolute references.
- if (Parser.isParsingMasm() && is64BitMode()) {
- Operands.push_back(X86Operand::CreateMem(getPointerWidth(), RegNo, Disp,
- BaseReg, IndexReg, Scale, Start,
- End, Size,
- /*DefaultBaseReg=*/X86::RIP));
- return false;
- }
-
- if ((BaseReg || IndexReg || RegNo))
- Operands.push_back(X86Operand::CreateMem(getPointerWidth(), RegNo, Disp,
- BaseReg, IndexReg, Scale, Start,
- End, Size));
- else
- Operands.push_back(
- X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size));
- return false;
+ if (Parser.isParsingMasm() && is64BitMode()) {
+ Operands.push_back(X86Operand::CreateMem(getPointerWidth(), RegNo, Disp,
+ BaseReg, IndexReg, Scale, Start,
+ End, Size,
+ /*DefaultBaseReg=*/X86::RIP));
+ return false;
+ }
+
+ if ((BaseReg || IndexReg || RegNo))
+ Operands.push_back(X86Operand::CreateMem(getPointerWidth(), RegNo, Disp,
+ BaseReg, IndexReg, Scale, Start,
+ End, Size));
+ else
+ Operands.push_back(
+ X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size));
+ return false;
}
-bool X86AsmParser::ParseATTOperand(OperandVector &Operands) {
+bool X86AsmParser::ParseATTOperand(OperandVector &Operands) {
MCAsmParser &Parser = getParser();
switch (getLexer().getKind()) {
case AsmToken::Dollar: {
@@ -2629,13 +2629,13 @@ bool X86AsmParser::ParseATTOperand(OperandVector &Operands) {
"expected immediate expression") ||
getParser().parseExpression(Val, End) ||
check(isa<X86MCExpr>(Val), L, "expected immediate expression"))
- return true;
- Operands.push_back(X86Operand::CreateImm(Val, Start, End));
- return false;
+ return true;
+ Operands.push_back(X86Operand::CreateImm(Val, Start, End));
+ return false;
}
case AsmToken::LCurly: {
SMLoc Start = Parser.getTok().getLoc();
- return ParseRoundingModeOp(Start, Operands);
+ return ParseRoundingModeOp(Start, Operands);
}
default: {
// This a memory operand or a register. We have some parsing complications
@@ -2649,7 +2649,7 @@ bool X86AsmParser::ParseATTOperand(OperandVector &Operands) {
if (getLexer().isNot(AsmToken::LParen)) {
// No '(' so this is either a displacement expression or a register.
if (Parser.parseExpression(Expr, EndLoc))
- return true;
+ return true;
if (auto *RE = dyn_cast<X86MCExpr>(Expr)) {
// Segment Register. Reset Expr and copy value to register.
Expr = nullptr;
@@ -2657,27 +2657,27 @@ bool X86AsmParser::ParseATTOperand(OperandVector &Operands) {
// Sanity check register.
if (Reg == X86::EIZ || Reg == X86::RIZ)
- return Error(
+ return Error(
Loc, "%eiz and %riz can only be used as index registers",
SMRange(Loc, EndLoc));
if (Reg == X86::RIP)
- return Error(Loc, "%rip can only be used as a base register",
- SMRange(Loc, EndLoc));
+ return Error(Loc, "%rip can only be used as a base register",
+ SMRange(Loc, EndLoc));
// Return register that are not segment prefixes immediately.
- if (!Parser.parseOptionalToken(AsmToken::Colon)) {
- Operands.push_back(X86Operand::CreateReg(Reg, Loc, EndLoc));
- return false;
- }
+ if (!Parser.parseOptionalToken(AsmToken::Colon)) {
+ Operands.push_back(X86Operand::CreateReg(Reg, Loc, EndLoc));
+ return false;
+ }
if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(Reg))
- return Error(Loc, "invalid segment register");
- // Accept a '*' absolute memory reference after the segment. Place it
- // before the full memory operand.
- if (getLexer().is(AsmToken::Star))
- Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
+ return Error(Loc, "invalid segment register");
+ // Accept a '*' absolute memory reference after the segment. Place it
+ // before the full memory operand.
+ if (getLexer().is(AsmToken::Star))
+ Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
}
}
// This is a Memory operand.
- return ParseMemOperand(Reg, Expr, Loc, EndLoc, Operands);
+ return ParseMemOperand(Reg, Expr, Loc, EndLoc, Operands);
}
}
}
@@ -2727,7 +2727,7 @@ bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z,
}
// true on failure, false otherwise
-bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands) {
+bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands) {
MCAsmParser &Parser = getParser();
if (getLexer().is(AsmToken::LCurly)) {
// Eat "{" and mark the current place.
@@ -2737,26 +2737,26 @@ bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands) {
// Parse memory broadcasting ({1to<NUM>}).
if (getLexer().getTok().getIntVal() != 1)
return TokError("Expected 1to<NUM> at this point");
- StringRef Prefix = getLexer().getTok().getString();
- Parser.Lex(); // Eat first token of 1to8
- if (!getLexer().is(AsmToken::Identifier))
+ StringRef Prefix = getLexer().getTok().getString();
+ Parser.Lex(); // Eat first token of 1to8
+ if (!getLexer().is(AsmToken::Identifier))
return TokError("Expected 1to<NUM> at this point");
// Recognize only reasonable suffixes.
- SmallVector<char, 5> BroadcastVector;
- StringRef BroadcastString = (Prefix + getLexer().getTok().getIdentifier())
- .toStringRef(BroadcastVector);
- if (!BroadcastString.startswith("1to"))
- return TokError("Expected 1to<NUM> at this point");
+ SmallVector<char, 5> BroadcastVector;
+ StringRef BroadcastString = (Prefix + getLexer().getTok().getIdentifier())
+ .toStringRef(BroadcastVector);
+ if (!BroadcastString.startswith("1to"))
+ return TokError("Expected 1to<NUM> at this point");
const char *BroadcastPrimitive =
- StringSwitch<const char *>(BroadcastString)
- .Case("1to2", "{1to2}")
- .Case("1to4", "{1to4}")
- .Case("1to8", "{1to8}")
- .Case("1to16", "{1to16}")
- .Default(nullptr);
+ StringSwitch<const char *>(BroadcastString)
+ .Case("1to2", "{1to2}")
+ .Case("1to4", "{1to4}")
+ .Case("1to8", "{1to8}")
+ .Case("1to16", "{1to16}")
+ .Default(nullptr);
if (!BroadcastPrimitive)
return TokError("Invalid memory broadcast primitive.");
- Parser.Lex(); // Eat trailing token of 1toN
+ Parser.Lex(); // Eat trailing token of 1toN
if (!getLexer().is(AsmToken::RCurly))
return TokError("Expected } at this point");
Parser.Lex(); // Eat "}"
@@ -2816,9 +2816,9 @@ bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands) {
/// ParseMemOperand: 'seg : disp(basereg, indexreg, scale)'. The '%ds:' prefix
/// has already been parsed if present. disp may be provided as well.
-bool X86AsmParser::ParseMemOperand(unsigned SegReg, const MCExpr *Disp,
- SMLoc StartLoc, SMLoc EndLoc,
- OperandVector &Operands) {
+bool X86AsmParser::ParseMemOperand(unsigned SegReg, const MCExpr *Disp,
+ SMLoc StartLoc, SMLoc EndLoc,
+ OperandVector &Operands) {
MCAsmParser &Parser = getParser();
SMLoc Loc;
// Based on the initial passed values, we may be in any of these cases, we are
@@ -2880,7 +2880,7 @@ bool X86AsmParser::ParseMemOperand(unsigned SegReg, const MCExpr *Disp,
// Parse immediate if we're not at a mem operand yet.
if (!isAtMemOperand()) {
if (Parser.parseTokenLoc(Loc) || Parser.parseExpression(Disp, EndLoc))
- return true;
+ return true;
assert(!isa<X86MCExpr>(Disp) && "Expected non-register here.");
} else {
// Disp is implicitly zero if we haven't parsed it yet.
@@ -2893,12 +2893,12 @@ bool X86AsmParser::ParseMemOperand(unsigned SegReg, const MCExpr *Disp,
if (!parseOptionalToken(AsmToken::LParen)) {
if (SegReg == 0)
- Operands.push_back(
- X86Operand::CreateMem(getPointerWidth(), Disp, StartLoc, EndLoc));
- else
- Operands.push_back(X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
- 0, 0, 1, StartLoc, EndLoc));
- return false;
+ Operands.push_back(
+ X86Operand::CreateMem(getPointerWidth(), Disp, StartLoc, EndLoc));
+ else
+ Operands.push_back(X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
+ 0, 0, 1, StartLoc, EndLoc));
+ return false;
}
// If we reached here, then eat the '(' and Process
@@ -2912,13 +2912,13 @@ bool X86AsmParser::ParseMemOperand(unsigned SegReg, const MCExpr *Disp,
if (getLexer().isNot(AsmToken::Comma) && getLexer().isNot(AsmToken::RParen)) {
if (Parser.parseExpression(E, EndLoc) ||
check(!isa<X86MCExpr>(E), BaseLoc, "expected register here"))
- return true;
+ return true;
// Sanity check register.
BaseReg = cast<X86MCExpr>(E)->getRegNo();
if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
- return Error(BaseLoc, "eiz and riz can only be used as index registers",
- SMRange(BaseLoc, EndLoc));
+ return Error(BaseLoc, "eiz and riz can only be used as index registers",
+ SMRange(BaseLoc, EndLoc));
}
if (parseOptionalToken(AsmToken::Comma)) {
@@ -2930,14 +2930,14 @@ bool X86AsmParser::ParseMemOperand(unsigned SegReg, const MCExpr *Disp,
// "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
if (getLexer().isNot(AsmToken::RParen)) {
if (Parser.parseTokenLoc(Loc) || Parser.parseExpression(E, EndLoc))
- return true;
+ return true;
if (!isa<X86MCExpr>(E)) {
// We've parsed an unexpected Scale Value instead of an index
// register. Interpret it as an absolute.
int64_t ScaleVal;
if (!E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
- return Error(Loc, "expected absolute expression");
+ return Error(Loc, "expected absolute expression");
if (ScaleVal != 1)
Warning(Loc, "scale factor without index register is ignored");
Scale = 1;
@@ -2945,10 +2945,10 @@ bool X86AsmParser::ParseMemOperand(unsigned SegReg, const MCExpr *Disp,
IndexReg = cast<X86MCExpr>(E)->getRegNo();
if (BaseReg == X86::RIP)
- return Error(Loc,
- "%rip as base register can not have an index register");
+ return Error(Loc,
+ "%rip as base register can not have an index register");
if (IndexReg == X86::RIP)
- return Error(Loc, "%rip is not allowed as an index register");
+ return Error(Loc, "%rip is not allowed as an index register");
if (parseOptionalToken(AsmToken::Comma)) {
// Parse the scale amount:
@@ -2959,14 +2959,14 @@ bool X86AsmParser::ParseMemOperand(unsigned SegReg, const MCExpr *Disp,
int64_t ScaleVal;
if (Parser.parseTokenLoc(Loc) ||
Parser.parseAbsoluteExpression(ScaleVal))
- return Error(Loc, "expected scale expression");
+ return Error(Loc, "expected scale expression");
Scale = (unsigned)ScaleVal;
// Validate the scale amount.
if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
Scale != 1)
- return Error(Loc, "scale factor in 16-bit address must be 1");
+ return Error(Loc, "scale factor in 16-bit address must be 1");
if (checkScale(Scale, ErrMsg))
- return Error(Loc, ErrMsg);
+ return Error(Loc, ErrMsg);
}
}
}
@@ -2975,30 +2975,30 @@ bool X86AsmParser::ParseMemOperand(unsigned SegReg, const MCExpr *Disp,
// Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
if (parseToken(AsmToken::RParen, "unexpected token in memory operand"))
- return true;
+ return true;
// This is to support otherwise illegal operand (%dx) found in various
// unofficial manuals examples (e.g. "out[s]?[bwl]? %al, (%dx)") and must now
// be supported. Mark such DX variants separately fix only in special cases.
if (BaseReg == X86::DX && IndexReg == 0 && Scale == 1 && SegReg == 0 &&
- isa<MCConstantExpr>(Disp) &&
- cast<MCConstantExpr>(Disp)->getValue() == 0) {
- Operands.push_back(X86Operand::CreateDXReg(BaseLoc, BaseLoc));
- return false;
- }
+ isa<MCConstantExpr>(Disp) &&
+ cast<MCConstantExpr>(Disp)->getValue() == 0) {
+ Operands.push_back(X86Operand::CreateDXReg(BaseLoc, BaseLoc));
+ return false;
+ }
if (CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(),
ErrMsg))
- return Error(BaseLoc, ErrMsg);
+ return Error(BaseLoc, ErrMsg);
if (SegReg || BaseReg || IndexReg)
- Operands.push_back(X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
- BaseReg, IndexReg, Scale, StartLoc,
- EndLoc));
- else
- Operands.push_back(
- X86Operand::CreateMem(getPointerWidth(), Disp, StartLoc, EndLoc));
- return false;
+ Operands.push_back(X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
+ BaseReg, IndexReg, Scale, StartLoc,
+ EndLoc));
+ else
+ Operands.push_back(
+ X86Operand::CreateMem(getPointerWidth(), Disp, StartLoc, EndLoc));
+ return false;
}
// Parse either a standard primary expression or a register.
@@ -3015,7 +3015,7 @@ bool X86AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
Res = X86MCExpr::create(RegNo, Parser.getContext());
return false;
}
- return Parser.parsePrimaryExpr(Res, EndLoc, nullptr);
+ return Parser.parsePrimaryExpr(Res, EndLoc, nullptr);
}
bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
@@ -3025,7 +3025,7 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
// Reset the forced VEX encoding.
ForcedVEXEncoding = VEXEncoding_Default;
- ForcedDispEncoding = DispEncoding_Default;
+ ForcedDispEncoding = DispEncoding_Default;
// Parse pseudo prefixes.
while (1) {
@@ -3038,18 +3038,18 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
return Error(Parser.getTok().getLoc(), "Expected '}'");
Parser.Lex(); // Eat curly.
- if (Prefix == "vex")
+ if (Prefix == "vex")
ForcedVEXEncoding = VEXEncoding_VEX;
- else if (Prefix == "vex2")
- ForcedVEXEncoding = VEXEncoding_VEX2;
+ else if (Prefix == "vex2")
+ ForcedVEXEncoding = VEXEncoding_VEX2;
else if (Prefix == "vex3")
ForcedVEXEncoding = VEXEncoding_VEX3;
else if (Prefix == "evex")
ForcedVEXEncoding = VEXEncoding_EVEX;
- else if (Prefix == "disp8")
- ForcedDispEncoding = DispEncoding_Disp8;
- else if (Prefix == "disp32")
- ForcedDispEncoding = DispEncoding_Disp32;
+ else if (Prefix == "disp8")
+ ForcedDispEncoding = DispEncoding_Disp8;
+ else if (Prefix == "disp32")
+ ForcedDispEncoding = DispEncoding_Disp32;
else
return Error(NameLoc, "unknown prefix");
@@ -3066,36 +3066,36 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
}
continue;
}
- // Parse MASM style pseudo prefixes.
- if (isParsingMSInlineAsm()) {
- if (Name.equals_lower("vex"))
- ForcedVEXEncoding = VEXEncoding_VEX;
- else if (Name.equals_lower("vex2"))
- ForcedVEXEncoding = VEXEncoding_VEX2;
- else if (Name.equals_lower("vex3"))
- ForcedVEXEncoding = VEXEncoding_VEX3;
- else if (Name.equals_lower("evex"))
- ForcedVEXEncoding = VEXEncoding_EVEX;
-
- if (ForcedVEXEncoding != VEXEncoding_Default) {
- if (getLexer().isNot(AsmToken::Identifier))
- return Error(Parser.getTok().getLoc(), "Expected identifier");
- // FIXME: The mnemonic won't match correctly if its not in lower case.
- Name = Parser.getTok().getString();
- NameLoc = Parser.getTok().getLoc();
- Parser.Lex();
- }
- }
+ // Parse MASM style pseudo prefixes.
+ if (isParsingMSInlineAsm()) {
+ if (Name.equals_lower("vex"))
+ ForcedVEXEncoding = VEXEncoding_VEX;
+ else if (Name.equals_lower("vex2"))
+ ForcedVEXEncoding = VEXEncoding_VEX2;
+ else if (Name.equals_lower("vex3"))
+ ForcedVEXEncoding = VEXEncoding_VEX3;
+ else if (Name.equals_lower("evex"))
+ ForcedVEXEncoding = VEXEncoding_EVEX;
+
+ if (ForcedVEXEncoding != VEXEncoding_Default) {
+ if (getLexer().isNot(AsmToken::Identifier))
+ return Error(Parser.getTok().getLoc(), "Expected identifier");
+ // FIXME: The mnemonic won't match correctly if its not in lower case.
+ Name = Parser.getTok().getString();
+ NameLoc = Parser.getTok().getLoc();
+ Parser.Lex();
+ }
+ }
break;
}
- // Support the suffix syntax for overriding displacement size as well.
- if (Name.consume_back(".d32")) {
- ForcedDispEncoding = DispEncoding_Disp32;
- } else if (Name.consume_back(".d8")) {
- ForcedDispEncoding = DispEncoding_Disp8;
- }
-
+ // Support the suffix syntax for overriding displacement size as well.
+ if (Name.consume_back(".d32")) {
+ ForcedDispEncoding = DispEncoding_Disp32;
+ } else if (Name.consume_back(".d8")) {
+ ForcedDispEncoding = DispEncoding_Disp8;
+ }
+
StringRef PatchedName = Name;
// Hack to skip "short" following Jcc.
@@ -3263,13 +3263,13 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
// repz repnz <insn> ; GAS errors for the use of two similar prefixes
// lock addq %rax, %rbx ; Destination operand must be of memory type
// xacquire <insn> ; xacquire must be accompanied by 'lock'
- bool IsPrefix =
- StringSwitch<bool>(Name)
- .Cases("cs", "ds", "es", "fs", "gs", "ss", true)
- .Cases("rex64", "data32", "data16", "addr32", "addr16", true)
- .Cases("xacquire", "xrelease", true)
- .Cases("acquire", "release", isParsingIntelSyntax())
- .Default(false);
+ bool IsPrefix =
+ StringSwitch<bool>(Name)
+ .Cases("cs", "ds", "es", "fs", "gs", "ss", true)
+ .Cases("rex64", "data32", "data16", "addr32", "addr16", true)
+ .Cases("xacquire", "xrelease", true)
+ .Cases("acquire", "release", isParsingIntelSyntax())
+ .Default(false);
auto isLockRepeatNtPrefix = [](StringRef N) {
return StringSwitch<bool>(N)
@@ -3324,22 +3324,22 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
return Error(NameLoc, "'data32' is not supported in 64-bit mode");
// Hack to 'data16' for the table lookup.
PatchedName = "data16";
-
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- StringRef Next = Parser.getTok().getString();
- getLexer().Lex();
- // data32 effectively changes the instruction suffix.
- // TODO Generalize.
- if (Next == "callw")
- Next = "calll";
- if (Next == "ljmpw")
- Next = "ljmpl";
-
- Name = Next;
- PatchedName = Name;
- ForcedDataPrefix = X86::Mode32Bit;
- IsPrefix = false;
- }
+
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ StringRef Next = Parser.getTok().getString();
+ getLexer().Lex();
+ // data32 effectively changes the instruction suffix.
+ // TODO Generalize.
+ if (Next == "callw")
+ Next = "calll";
+ if (Next == "ljmpw")
+ Next = "ljmpl";
+
+ Name = Next;
+ PatchedName = Name;
+ ForcedDataPrefix = X86::Mode32Bit;
+ IsPrefix = false;
+ }
}
Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
@@ -3355,18 +3355,18 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
// prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
// just want to parse the "lock" as the first instruction and the "incl" as
// the next one.
- if (getLexer().isNot(AsmToken::EndOfStatement) && !IsPrefix) {
+ if (getLexer().isNot(AsmToken::EndOfStatement) && !IsPrefix) {
// Parse '*' modifier.
if (getLexer().is(AsmToken::Star))
Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
// Read the operands.
while(1) {
- if (ParseOperand(Operands))
- return true;
- if (HandleAVX512Operand(Operands))
- return true;
-
+ if (ParseOperand(Operands))
+ return true;
+ if (HandleAVX512Operand(Operands))
+ return true;
+
// check for comma and eat it
if (getLexer().is(AsmToken::Comma))
Parser.Lex();
@@ -3392,7 +3392,7 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
// Consume the EndOfStatement or the prefix separator Slash
if (getLexer().is(AsmToken::EndOfStatement) ||
- (IsPrefix && getLexer().is(AsmToken::Slash)))
+ (IsPrefix && getLexer().is(AsmToken::Slash)))
Parser.Lex();
else if (CurlyAsEndOfStatement)
// Add an actual EndOfStatement before the curly brace
@@ -3567,26 +3567,26 @@ bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
switch (Inst.getOpcode()) {
default: return false;
- case X86::JMP_1:
- // {disp32} forces a larger displacement as if the instruction was relaxed.
- // NOTE: 16-bit mode uses 16-bit displacement even though it says {disp32}.
- // This matches GNU assembler.
- if (ForcedDispEncoding == DispEncoding_Disp32) {
- Inst.setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
- return true;
- }
-
- return false;
- case X86::JCC_1:
- // {disp32} forces a larger displacement as if the instruction was relaxed.
- // NOTE: 16-bit mode uses 16-bit displacement even though it says {disp32}.
- // This matches GNU assembler.
- if (ForcedDispEncoding == DispEncoding_Disp32) {
- Inst.setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
- return true;
- }
-
- return false;
+ case X86::JMP_1:
+ // {disp32} forces a larger displacement as if the instruction was relaxed.
+ // NOTE: 16-bit mode uses 16-bit displacement even though it says {disp32}.
+ // This matches GNU assembler.
+ if (ForcedDispEncoding == DispEncoding_Disp32) {
+ Inst.setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
+ return true;
+ }
+
+ return false;
+ case X86::JCC_1:
+ // {disp32} forces a larger displacement as if the instruction was relaxed.
+ // NOTE: 16-bit mode uses 16-bit displacement even though it says {disp32}.
+ // This matches GNU assembler.
+ if (ForcedDispEncoding == DispEncoding_Disp32) {
+ Inst.setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
+ return true;
+ }
+
+ return false;
case X86::VMOVZPQILo2PQIrr:
case X86::VMOVAPDrr:
case X86::VMOVAPDYrr:
@@ -3645,123 +3645,123 @@ bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
Inst.setOpcode(NewOpc);
return true;
}
- case X86::RCR8ri: case X86::RCR16ri: case X86::RCR32ri: case X86::RCR64ri:
- case X86::RCL8ri: case X86::RCL16ri: case X86::RCL32ri: case X86::RCL64ri:
- case X86::ROR8ri: case X86::ROR16ri: case X86::ROR32ri: case X86::ROR64ri:
- case X86::ROL8ri: case X86::ROL16ri: case X86::ROL32ri: case X86::ROL64ri:
- case X86::SAR8ri: case X86::SAR16ri: case X86::SAR32ri: case X86::SAR64ri:
- case X86::SHR8ri: case X86::SHR16ri: case X86::SHR32ri: case X86::SHR64ri:
- case X86::SHL8ri: case X86::SHL16ri: case X86::SHL32ri: case X86::SHL64ri: {
- // Optimize s{hr,ar,hl} $1, <op> to "shift <op>". Similar for rotate.
- // FIXME: It would be great if we could just do this with an InstAlias.
- if (!Inst.getOperand(2).isImm() || Inst.getOperand(2).getImm() != 1)
- return false;
-
- unsigned NewOpc;
- switch (Inst.getOpcode()) {
- default: llvm_unreachable("Invalid opcode");
- case X86::RCR8ri: NewOpc = X86::RCR8r1; break;
- case X86::RCR16ri: NewOpc = X86::RCR16r1; break;
- case X86::RCR32ri: NewOpc = X86::RCR32r1; break;
- case X86::RCR64ri: NewOpc = X86::RCR64r1; break;
- case X86::RCL8ri: NewOpc = X86::RCL8r1; break;
- case X86::RCL16ri: NewOpc = X86::RCL16r1; break;
- case X86::RCL32ri: NewOpc = X86::RCL32r1; break;
- case X86::RCL64ri: NewOpc = X86::RCL64r1; break;
- case X86::ROR8ri: NewOpc = X86::ROR8r1; break;
- case X86::ROR16ri: NewOpc = X86::ROR16r1; break;
- case X86::ROR32ri: NewOpc = X86::ROR32r1; break;
- case X86::ROR64ri: NewOpc = X86::ROR64r1; break;
- case X86::ROL8ri: NewOpc = X86::ROL8r1; break;
- case X86::ROL16ri: NewOpc = X86::ROL16r1; break;
- case X86::ROL32ri: NewOpc = X86::ROL32r1; break;
- case X86::ROL64ri: NewOpc = X86::ROL64r1; break;
- case X86::SAR8ri: NewOpc = X86::SAR8r1; break;
- case X86::SAR16ri: NewOpc = X86::SAR16r1; break;
- case X86::SAR32ri: NewOpc = X86::SAR32r1; break;
- case X86::SAR64ri: NewOpc = X86::SAR64r1; break;
- case X86::SHR8ri: NewOpc = X86::SHR8r1; break;
- case X86::SHR16ri: NewOpc = X86::SHR16r1; break;
- case X86::SHR32ri: NewOpc = X86::SHR32r1; break;
- case X86::SHR64ri: NewOpc = X86::SHR64r1; break;
- case X86::SHL8ri: NewOpc = X86::SHL8r1; break;
- case X86::SHL16ri: NewOpc = X86::SHL16r1; break;
- case X86::SHL32ri: NewOpc = X86::SHL32r1; break;
- case X86::SHL64ri: NewOpc = X86::SHL64r1; break;
- }
-
- MCInst TmpInst;
- TmpInst.setOpcode(NewOpc);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- Inst = TmpInst;
- return true;
- }
- case X86::RCR8mi: case X86::RCR16mi: case X86::RCR32mi: case X86::RCR64mi:
- case X86::RCL8mi: case X86::RCL16mi: case X86::RCL32mi: case X86::RCL64mi:
- case X86::ROR8mi: case X86::ROR16mi: case X86::ROR32mi: case X86::ROR64mi:
- case X86::ROL8mi: case X86::ROL16mi: case X86::ROL32mi: case X86::ROL64mi:
- case X86::SAR8mi: case X86::SAR16mi: case X86::SAR32mi: case X86::SAR64mi:
- case X86::SHR8mi: case X86::SHR16mi: case X86::SHR32mi: case X86::SHR64mi:
- case X86::SHL8mi: case X86::SHL16mi: case X86::SHL32mi: case X86::SHL64mi: {
- // Optimize s{hr,ar,hl} $1, <op> to "shift <op>". Similar for rotate.
- // FIXME: It would be great if we could just do this with an InstAlias.
- if (!Inst.getOperand(X86::AddrNumOperands).isImm() ||
- Inst.getOperand(X86::AddrNumOperands).getImm() != 1)
- return false;
-
- unsigned NewOpc;
- switch (Inst.getOpcode()) {
- default: llvm_unreachable("Invalid opcode");
- case X86::RCR8mi: NewOpc = X86::RCR8m1; break;
- case X86::RCR16mi: NewOpc = X86::RCR16m1; break;
- case X86::RCR32mi: NewOpc = X86::RCR32m1; break;
- case X86::RCR64mi: NewOpc = X86::RCR64m1; break;
- case X86::RCL8mi: NewOpc = X86::RCL8m1; break;
- case X86::RCL16mi: NewOpc = X86::RCL16m1; break;
- case X86::RCL32mi: NewOpc = X86::RCL32m1; break;
- case X86::RCL64mi: NewOpc = X86::RCL64m1; break;
- case X86::ROR8mi: NewOpc = X86::ROR8m1; break;
- case X86::ROR16mi: NewOpc = X86::ROR16m1; break;
- case X86::ROR32mi: NewOpc = X86::ROR32m1; break;
- case X86::ROR64mi: NewOpc = X86::ROR64m1; break;
- case X86::ROL8mi: NewOpc = X86::ROL8m1; break;
- case X86::ROL16mi: NewOpc = X86::ROL16m1; break;
- case X86::ROL32mi: NewOpc = X86::ROL32m1; break;
- case X86::ROL64mi: NewOpc = X86::ROL64m1; break;
- case X86::SAR8mi: NewOpc = X86::SAR8m1; break;
- case X86::SAR16mi: NewOpc = X86::SAR16m1; break;
- case X86::SAR32mi: NewOpc = X86::SAR32m1; break;
- case X86::SAR64mi: NewOpc = X86::SAR64m1; break;
- case X86::SHR8mi: NewOpc = X86::SHR8m1; break;
- case X86::SHR16mi: NewOpc = X86::SHR16m1; break;
- case X86::SHR32mi: NewOpc = X86::SHR32m1; break;
- case X86::SHR64mi: NewOpc = X86::SHR64m1; break;
- case X86::SHL8mi: NewOpc = X86::SHL8m1; break;
- case X86::SHL16mi: NewOpc = X86::SHL16m1; break;
- case X86::SHL32mi: NewOpc = X86::SHL32m1; break;
- case X86::SHL64mi: NewOpc = X86::SHL64m1; break;
- }
-
- MCInst TmpInst;
- TmpInst.setOpcode(NewOpc);
- for (int i = 0; i != X86::AddrNumOperands; ++i)
- TmpInst.addOperand(Inst.getOperand(i));
- Inst = TmpInst;
- return true;
- }
- case X86::INT: {
- // Transforms "int $3" into "int3" as a size optimization. We can't write an
- // instalias with an immediate operand yet.
- if (!Inst.getOperand(0).isImm() || Inst.getOperand(0).getImm() != 3)
- return false;
-
- MCInst TmpInst;
- TmpInst.setOpcode(X86::INT3);
- Inst = TmpInst;
- return true;
- }
- }
+ case X86::RCR8ri: case X86::RCR16ri: case X86::RCR32ri: case X86::RCR64ri:
+ case X86::RCL8ri: case X86::RCL16ri: case X86::RCL32ri: case X86::RCL64ri:
+ case X86::ROR8ri: case X86::ROR16ri: case X86::ROR32ri: case X86::ROR64ri:
+ case X86::ROL8ri: case X86::ROL16ri: case X86::ROL32ri: case X86::ROL64ri:
+ case X86::SAR8ri: case X86::SAR16ri: case X86::SAR32ri: case X86::SAR64ri:
+ case X86::SHR8ri: case X86::SHR16ri: case X86::SHR32ri: case X86::SHR64ri:
+ case X86::SHL8ri: case X86::SHL16ri: case X86::SHL32ri: case X86::SHL64ri: {
+ // Optimize s{hr,ar,hl} $1, <op> to "shift <op>". Similar for rotate.
+ // FIXME: It would be great if we could just do this with an InstAlias.
+ if (!Inst.getOperand(2).isImm() || Inst.getOperand(2).getImm() != 1)
+ return false;
+
+ unsigned NewOpc;
+ switch (Inst.getOpcode()) {
+ default: llvm_unreachable("Invalid opcode");
+ case X86::RCR8ri: NewOpc = X86::RCR8r1; break;
+ case X86::RCR16ri: NewOpc = X86::RCR16r1; break;
+ case X86::RCR32ri: NewOpc = X86::RCR32r1; break;
+ case X86::RCR64ri: NewOpc = X86::RCR64r1; break;
+ case X86::RCL8ri: NewOpc = X86::RCL8r1; break;
+ case X86::RCL16ri: NewOpc = X86::RCL16r1; break;
+ case X86::RCL32ri: NewOpc = X86::RCL32r1; break;
+ case X86::RCL64ri: NewOpc = X86::RCL64r1; break;
+ case X86::ROR8ri: NewOpc = X86::ROR8r1; break;
+ case X86::ROR16ri: NewOpc = X86::ROR16r1; break;
+ case X86::ROR32ri: NewOpc = X86::ROR32r1; break;
+ case X86::ROR64ri: NewOpc = X86::ROR64r1; break;
+ case X86::ROL8ri: NewOpc = X86::ROL8r1; break;
+ case X86::ROL16ri: NewOpc = X86::ROL16r1; break;
+ case X86::ROL32ri: NewOpc = X86::ROL32r1; break;
+ case X86::ROL64ri: NewOpc = X86::ROL64r1; break;
+ case X86::SAR8ri: NewOpc = X86::SAR8r1; break;
+ case X86::SAR16ri: NewOpc = X86::SAR16r1; break;
+ case X86::SAR32ri: NewOpc = X86::SAR32r1; break;
+ case X86::SAR64ri: NewOpc = X86::SAR64r1; break;
+ case X86::SHR8ri: NewOpc = X86::SHR8r1; break;
+ case X86::SHR16ri: NewOpc = X86::SHR16r1; break;
+ case X86::SHR32ri: NewOpc = X86::SHR32r1; break;
+ case X86::SHR64ri: NewOpc = X86::SHR64r1; break;
+ case X86::SHL8ri: NewOpc = X86::SHL8r1; break;
+ case X86::SHL16ri: NewOpc = X86::SHL16r1; break;
+ case X86::SHL32ri: NewOpc = X86::SHL32r1; break;
+ case X86::SHL64ri: NewOpc = X86::SHL64r1; break;
+ }
+
+ MCInst TmpInst;
+ TmpInst.setOpcode(NewOpc);
+ TmpInst.addOperand(Inst.getOperand(0));
+ TmpInst.addOperand(Inst.getOperand(1));
+ Inst = TmpInst;
+ return true;
+ }
+ case X86::RCR8mi: case X86::RCR16mi: case X86::RCR32mi: case X86::RCR64mi:
+ case X86::RCL8mi: case X86::RCL16mi: case X86::RCL32mi: case X86::RCL64mi:
+ case X86::ROR8mi: case X86::ROR16mi: case X86::ROR32mi: case X86::ROR64mi:
+ case X86::ROL8mi: case X86::ROL16mi: case X86::ROL32mi: case X86::ROL64mi:
+ case X86::SAR8mi: case X86::SAR16mi: case X86::SAR32mi: case X86::SAR64mi:
+ case X86::SHR8mi: case X86::SHR16mi: case X86::SHR32mi: case X86::SHR64mi:
+ case X86::SHL8mi: case X86::SHL16mi: case X86::SHL32mi: case X86::SHL64mi: {
+ // Optimize s{hr,ar,hl} $1, <op> to "shift <op>". Similar for rotate.
+ // FIXME: It would be great if we could just do this with an InstAlias.
+ if (!Inst.getOperand(X86::AddrNumOperands).isImm() ||
+ Inst.getOperand(X86::AddrNumOperands).getImm() != 1)
+ return false;
+
+ unsigned NewOpc;
+ switch (Inst.getOpcode()) {
+ default: llvm_unreachable("Invalid opcode");
+ case X86::RCR8mi: NewOpc = X86::RCR8m1; break;
+ case X86::RCR16mi: NewOpc = X86::RCR16m1; break;
+ case X86::RCR32mi: NewOpc = X86::RCR32m1; break;
+ case X86::RCR64mi: NewOpc = X86::RCR64m1; break;
+ case X86::RCL8mi: NewOpc = X86::RCL8m1; break;
+ case X86::RCL16mi: NewOpc = X86::RCL16m1; break;
+ case X86::RCL32mi: NewOpc = X86::RCL32m1; break;
+ case X86::RCL64mi: NewOpc = X86::RCL64m1; break;
+ case X86::ROR8mi: NewOpc = X86::ROR8m1; break;
+ case X86::ROR16mi: NewOpc = X86::ROR16m1; break;
+ case X86::ROR32mi: NewOpc = X86::ROR32m1; break;
+ case X86::ROR64mi: NewOpc = X86::ROR64m1; break;
+ case X86::ROL8mi: NewOpc = X86::ROL8m1; break;
+ case X86::ROL16mi: NewOpc = X86::ROL16m1; break;
+ case X86::ROL32mi: NewOpc = X86::ROL32m1; break;
+ case X86::ROL64mi: NewOpc = X86::ROL64m1; break;
+ case X86::SAR8mi: NewOpc = X86::SAR8m1; break;
+ case X86::SAR16mi: NewOpc = X86::SAR16m1; break;
+ case X86::SAR32mi: NewOpc = X86::SAR32m1; break;
+ case X86::SAR64mi: NewOpc = X86::SAR64m1; break;
+ case X86::SHR8mi: NewOpc = X86::SHR8m1; break;
+ case X86::SHR16mi: NewOpc = X86::SHR16m1; break;
+ case X86::SHR32mi: NewOpc = X86::SHR32m1; break;
+ case X86::SHR64mi: NewOpc = X86::SHR64m1; break;
+ case X86::SHL8mi: NewOpc = X86::SHL8m1; break;
+ case X86::SHL16mi: NewOpc = X86::SHL16m1; break;
+ case X86::SHL32mi: NewOpc = X86::SHL32m1; break;
+ case X86::SHL64mi: NewOpc = X86::SHL64m1; break;
+ }
+
+ MCInst TmpInst;
+ TmpInst.setOpcode(NewOpc);
+ for (int i = 0; i != X86::AddrNumOperands; ++i)
+ TmpInst.addOperand(Inst.getOperand(i));
+ Inst = TmpInst;
+ return true;
+ }
+ case X86::INT: {
+ // Transforms "int $3" into "int3" as a size optimization. We can't write an
+ // instalias with an immediate operand yet.
+ if (!Inst.getOperand(0).isImm() || Inst.getOperand(0).getImm() != 3)
+ return false;
+
+ MCInst TmpInst;
+ TmpInst.setOpcode(X86::INT3);
+ Inst = TmpInst;
+ return true;
+ }
+ }
}
bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
@@ -3860,33 +3860,33 @@ bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
}
}
- const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
- // Check that we aren't mixing AH/BH/CH/DH with REX prefix. We only need to
- // check this with the legacy encoding, VEX/EVEX/XOP don't use REX.
- if ((MCID.TSFlags & X86II::EncodingMask) == 0) {
- MCPhysReg HReg = X86::NoRegister;
- bool UsesRex = MCID.TSFlags & X86II::REX_W;
- unsigned NumOps = Inst.getNumOperands();
- for (unsigned i = 0; i != NumOps; ++i) {
- const MCOperand &MO = Inst.getOperand(i);
- if (!MO.isReg())
- continue;
- unsigned Reg = MO.getReg();
- if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
- HReg = Reg;
- if (X86II::isX86_64NonExtLowByteReg(Reg) ||
- X86II::isX86_64ExtendedReg(Reg))
- UsesRex = true;
- }
-
- if (UsesRex && HReg != X86::NoRegister) {
- StringRef RegName = X86IntelInstPrinter::getRegisterName(HReg);
- return Error(Ops[0]->getStartLoc(),
- "can't encode '" + RegName + "' in an instruction requiring "
- "REX prefix");
- }
- }
-
+ const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
+ // Check that we aren't mixing AH/BH/CH/DH with REX prefix. We only need to
+ // check this with the legacy encoding, VEX/EVEX/XOP don't use REX.
+ if ((MCID.TSFlags & X86II::EncodingMask) == 0) {
+ MCPhysReg HReg = X86::NoRegister;
+ bool UsesRex = MCID.TSFlags & X86II::REX_W;
+ unsigned NumOps = Inst.getNumOperands();
+ for (unsigned i = 0; i != NumOps; ++i) {
+ const MCOperand &MO = Inst.getOperand(i);
+ if (!MO.isReg())
+ continue;
+ unsigned Reg = MO.getReg();
+ if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
+ HReg = Reg;
+ if (X86II::isX86_64NonExtLowByteReg(Reg) ||
+ X86II::isX86_64ExtendedReg(Reg))
+ UsesRex = true;
+ }
+
+ if (UsesRex && HReg != X86::NoRegister) {
+ StringRef RegName = X86IntelInstPrinter::getRegisterName(HReg);
+ return Error(Ops[0]->getStartLoc(),
+ "can't encode '" + RegName + "' in an instruction requiring "
+ "REX prefix");
+ }
+ }
+
return false;
}
@@ -4080,18 +4080,18 @@ unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
return Match_Unsupported;
if ((ForcedVEXEncoding == VEXEncoding_VEX ||
- ForcedVEXEncoding == VEXEncoding_VEX2 ||
+ ForcedVEXEncoding == VEXEncoding_VEX2 ||
ForcedVEXEncoding == VEXEncoding_VEX3) &&
(MCID.TSFlags & X86II::EncodingMask) != X86II::VEX)
return Match_Unsupported;
- // These instructions are only available with {vex}, {vex2} or {vex3} prefix
- if (MCID.TSFlags & X86II::ExplicitVEXPrefix &&
- (ForcedVEXEncoding != VEXEncoding_VEX &&
- ForcedVEXEncoding != VEXEncoding_VEX2 &&
- ForcedVEXEncoding != VEXEncoding_VEX3))
- return Match_Unsupported;
-
+ // These instructions are only available with {vex}, {vex2} or {vex3} prefix
+ if (MCID.TSFlags & X86II::ExplicitVEXPrefix &&
+ (ForcedVEXEncoding != VEXEncoding_VEX &&
+ ForcedVEXEncoding != VEXEncoding_VEX2 &&
+ ForcedVEXEncoding != VEXEncoding_VEX3))
+ return Match_Unsupported;
+
// These instructions match ambiguously with their VEX encoded counterparts
// and appear first in the matching table. Reject them unless we're forcing
// EVEX encoding.
@@ -4130,39 +4130,39 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
MCInst Inst;
- // If VEX/EVEX encoding is forced, we need to pass the USE_* flag to the
- // encoder and printer.
- if (ForcedVEXEncoding == VEXEncoding_VEX)
- Prefixes |= X86::IP_USE_VEX;
- else if (ForcedVEXEncoding == VEXEncoding_VEX2)
- Prefixes |= X86::IP_USE_VEX2;
- else if (ForcedVEXEncoding == VEXEncoding_VEX3)
+ // If VEX/EVEX encoding is forced, we need to pass the USE_* flag to the
+ // encoder and printer.
+ if (ForcedVEXEncoding == VEXEncoding_VEX)
+ Prefixes |= X86::IP_USE_VEX;
+ else if (ForcedVEXEncoding == VEXEncoding_VEX2)
+ Prefixes |= X86::IP_USE_VEX2;
+ else if (ForcedVEXEncoding == VEXEncoding_VEX3)
Prefixes |= X86::IP_USE_VEX3;
- else if (ForcedVEXEncoding == VEXEncoding_EVEX)
- Prefixes |= X86::IP_USE_EVEX;
-
- // Set encoded flags for {disp8} and {disp32}.
- if (ForcedDispEncoding == DispEncoding_Disp8)
- Prefixes |= X86::IP_USE_DISP8;
- else if (ForcedDispEncoding == DispEncoding_Disp32)
- Prefixes |= X86::IP_USE_DISP32;
-
+ else if (ForcedVEXEncoding == VEXEncoding_EVEX)
+ Prefixes |= X86::IP_USE_EVEX;
+
+ // Set encoded flags for {disp8} and {disp32}.
+ if (ForcedDispEncoding == DispEncoding_Disp8)
+ Prefixes |= X86::IP_USE_DISP8;
+ else if (ForcedDispEncoding == DispEncoding_Disp32)
+ Prefixes |= X86::IP_USE_DISP32;
+
if (Prefixes)
Inst.setFlags(Prefixes);
- // In 16-bit mode, if data32 is specified, temporarily switch to 32-bit mode
- // when matching the instruction.
- if (ForcedDataPrefix == X86::Mode32Bit)
- SwitchMode(X86::Mode32Bit);
+ // In 16-bit mode, if data32 is specified, temporarily switch to 32-bit mode
+ // when matching the instruction.
+ if (ForcedDataPrefix == X86::Mode32Bit)
+ SwitchMode(X86::Mode32Bit);
// First, try a direct match.
FeatureBitset MissingFeatures;
unsigned OriginalError = MatchInstruction(Operands, Inst, ErrorInfo,
MissingFeatures, MatchingInlineAsm,
isParsingIntelSyntax());
- if (ForcedDataPrefix == X86::Mode32Bit) {
- SwitchMode(X86::Mode16Bit);
- ForcedDataPrefix = 0;
- }
+ if (ForcedDataPrefix == X86::Mode32Bit) {
+ SwitchMode(X86::Mode16Bit);
+ ForcedDataPrefix = 0;
+ }
switch (OriginalError) {
default: llvm_unreachable("Unexpected match result!");
case Match_Success:
@@ -4271,15 +4271,15 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
unsigned NumSuccessfulMatches =
std::count(std::begin(Match), std::end(Match), Match_Success);
if (NumSuccessfulMatches == 1) {
- if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
- return true;
- // Some instructions need post-processing to, for example, tweak which
- // encoding is selected. Loop on it while changes happen so the
- // individual transformations can chain off each other.
- if (!MatchingInlineAsm)
- while (processInstruction(Inst, Operands))
- ;
-
+ if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
+ return true;
+ // Some instructions need post-processing to, for example, tweak which
+ // encoding is selected. Loop on it while changes happen so the
+ // individual transformations can chain off each other.
+ if (!MatchingInlineAsm)
+ while (processInstruction(Inst, Operands))
+ ;
+
Inst.setLoc(IDLoc);
if (!MatchingInlineAsm)
emitInstruction(Inst, Operands, Out);
@@ -4393,23 +4393,23 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
MCInst Inst;
- // If VEX/EVEX encoding is forced, we need to pass the USE_* flag to the
- // encoder and printer.
- if (ForcedVEXEncoding == VEXEncoding_VEX)
- Prefixes |= X86::IP_USE_VEX;
- else if (ForcedVEXEncoding == VEXEncoding_VEX2)
- Prefixes |= X86::IP_USE_VEX2;
- else if (ForcedVEXEncoding == VEXEncoding_VEX3)
+ // If VEX/EVEX encoding is forced, we need to pass the USE_* flag to the
+ // encoder and printer.
+ if (ForcedVEXEncoding == VEXEncoding_VEX)
+ Prefixes |= X86::IP_USE_VEX;
+ else if (ForcedVEXEncoding == VEXEncoding_VEX2)
+ Prefixes |= X86::IP_USE_VEX2;
+ else if (ForcedVEXEncoding == VEXEncoding_VEX3)
Prefixes |= X86::IP_USE_VEX3;
- else if (ForcedVEXEncoding == VEXEncoding_EVEX)
- Prefixes |= X86::IP_USE_EVEX;
-
- // Set encoded flags for {disp8} and {disp32}.
- if (ForcedDispEncoding == DispEncoding_Disp8)
- Prefixes |= X86::IP_USE_DISP8;
- else if (ForcedDispEncoding == DispEncoding_Disp32)
- Prefixes |= X86::IP_USE_DISP32;
-
+ else if (ForcedVEXEncoding == VEXEncoding_EVEX)
+ Prefixes |= X86::IP_USE_EVEX;
+
+ // Set encoded flags for {disp8} and {disp32}.
+ if (ForcedDispEncoding == DispEncoding_Disp8)
+ Prefixes |= X86::IP_USE_DISP8;
+ else if (ForcedDispEncoding == DispEncoding_Disp32)
+ Prefixes |= X86::IP_USE_DISP32;
+
if (Prefixes)
Inst.setFlags(Prefixes);
@@ -4603,8 +4603,8 @@ bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
MCAsmParser &Parser = getParser();
StringRef IDVal = DirectiveID.getIdentifier();
- if (IDVal.startswith(".arch"))
- return parseDirectiveArch();
+ if (IDVal.startswith(".arch"))
+ return parseDirectiveArch();
if (IDVal.startswith(".code"))
return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
else if (IDVal.startswith(".att_syntax")) {
@@ -4629,9 +4629,9 @@ bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
"a '%' prefix in .intel_syntax");
}
return false;
- } else if (IDVal == ".nops")
- return parseDirectiveNops(DirectiveID.getLoc());
- else if (IDVal == ".even")
+ } else if (IDVal == ".nops")
+ return parseDirectiveNops(DirectiveID.getLoc());
+ else if (IDVal == ".even")
return parseDirectiveEven(DirectiveID.getLoc());
else if (IDVal == ".cv_fpo_proc")
return parseDirectiveFPOProc(DirectiveID.getLoc());
@@ -4647,67 +4647,67 @@ bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
return parseDirectiveFPOEndPrologue(DirectiveID.getLoc());
else if (IDVal == ".cv_fpo_endproc")
return parseDirectiveFPOEndProc(DirectiveID.getLoc());
- else if (IDVal == ".seh_pushreg" ||
- (Parser.isParsingMasm() && IDVal.equals_lower(".pushreg")))
+ else if (IDVal == ".seh_pushreg" ||
+ (Parser.isParsingMasm() && IDVal.equals_lower(".pushreg")))
return parseDirectiveSEHPushReg(DirectiveID.getLoc());
- else if (IDVal == ".seh_setframe" ||
- (Parser.isParsingMasm() && IDVal.equals_lower(".setframe")))
+ else if (IDVal == ".seh_setframe" ||
+ (Parser.isParsingMasm() && IDVal.equals_lower(".setframe")))
return parseDirectiveSEHSetFrame(DirectiveID.getLoc());
- else if (IDVal == ".seh_savereg" ||
- (Parser.isParsingMasm() && IDVal.equals_lower(".savereg")))
+ else if (IDVal == ".seh_savereg" ||
+ (Parser.isParsingMasm() && IDVal.equals_lower(".savereg")))
return parseDirectiveSEHSaveReg(DirectiveID.getLoc());
- else if (IDVal == ".seh_savexmm" ||
- (Parser.isParsingMasm() && IDVal.equals_lower(".savexmm128")))
+ else if (IDVal == ".seh_savexmm" ||
+ (Parser.isParsingMasm() && IDVal.equals_lower(".savexmm128")))
return parseDirectiveSEHSaveXMM(DirectiveID.getLoc());
- else if (IDVal == ".seh_pushframe" ||
- (Parser.isParsingMasm() && IDVal.equals_lower(".pushframe")))
+ else if (IDVal == ".seh_pushframe" ||
+ (Parser.isParsingMasm() && IDVal.equals_lower(".pushframe")))
return parseDirectiveSEHPushFrame(DirectiveID.getLoc());
return true;
}
-bool X86AsmParser::parseDirectiveArch() {
- // Ignore .arch for now.
- getParser().parseStringToEndOfStatement();
- return false;
-}
-
-/// parseDirectiveNops
-/// ::= .nops size[, control]
-bool X86AsmParser::parseDirectiveNops(SMLoc L) {
- int64_t NumBytes = 0, Control = 0;
- SMLoc NumBytesLoc, ControlLoc;
- const MCSubtargetInfo STI = getSTI();
- NumBytesLoc = getTok().getLoc();
- if (getParser().checkForValidSection() ||
- getParser().parseAbsoluteExpression(NumBytes))
- return true;
-
- if (parseOptionalToken(AsmToken::Comma)) {
- ControlLoc = getTok().getLoc();
- if (getParser().parseAbsoluteExpression(Control))
- return true;
- }
- if (getParser().parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.nops' directive"))
- return true;
-
- if (NumBytes <= 0) {
- Error(NumBytesLoc, "'.nops' directive with non-positive size");
- return false;
- }
-
- if (Control < 0) {
- Error(ControlLoc, "'.nops' directive with negative NOP size");
- return false;
- }
-
- /// Emit nops
- getParser().getStreamer().emitNops(NumBytes, Control, L);
-
- return false;
-}
-
+bool X86AsmParser::parseDirectiveArch() {
+ // Ignore .arch for now.
+ getParser().parseStringToEndOfStatement();
+ return false;
+}
+
+/// parseDirectiveNops
+/// ::= .nops size[, control]
+bool X86AsmParser::parseDirectiveNops(SMLoc L) {
+ int64_t NumBytes = 0, Control = 0;
+ SMLoc NumBytesLoc, ControlLoc;
+ const MCSubtargetInfo STI = getSTI();
+ NumBytesLoc = getTok().getLoc();
+ if (getParser().checkForValidSection() ||
+ getParser().parseAbsoluteExpression(NumBytes))
+ return true;
+
+ if (parseOptionalToken(AsmToken::Comma)) {
+ ControlLoc = getTok().getLoc();
+ if (getParser().parseAbsoluteExpression(Control))
+ return true;
+ }
+ if (getParser().parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.nops' directive"))
+ return true;
+
+ if (NumBytes <= 0) {
+ Error(NumBytesLoc, "'.nops' directive with non-positive size");
+ return false;
+ }
+
+ if (Control < 0) {
+ Error(ControlLoc, "'.nops' directive with negative NOP size");
+ return false;
+ }
+
+ /// Emit nops
+ getParser().getStreamer().emitNops(NumBytes, Control, L);
+
+ return false;
+}
+
/// parseDirectiveEven
/// ::= .even
bool X86AsmParser::parseDirectiveEven(SMLoc L) {
diff --git a/contrib/libs/llvm12/lib/Target/X86/AsmParser/ya.make b/contrib/libs/llvm12/lib/Target/X86/AsmParser/ya.make
index b3115c55b9..f88283f4e5 100644
--- a/contrib/libs/llvm12/lib/Target/X86/AsmParser/ya.make
+++ b/contrib/libs/llvm12/lib/Target/X86/AsmParser/ya.make
@@ -12,19 +12,19 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/MC/MCParser
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target/X86/MCTargetDesc
- contrib/libs/llvm12/lib/Target/X86/TargetInfo
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/MC/MCParser
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target/X86/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/X86/TargetInfo
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86
- contrib/libs/llvm12/lib/Target/X86
- contrib/libs/llvm12/lib/Target/X86/AsmParser
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86
+ contrib/libs/llvm12/lib/Target/X86
+ contrib/libs/llvm12/lib/Target/X86/AsmParser
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/X86/Disassembler/X86Disassembler.cpp b/contrib/libs/llvm12/lib/Target/X86/Disassembler/X86Disassembler.cpp
index 1d396796e7..4e6d8e8e1a 100644
--- a/contrib/libs/llvm12/lib/Target/X86/Disassembler/X86Disassembler.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/Disassembler/X86Disassembler.cpp
@@ -492,7 +492,7 @@ static int readPrefixes(struct InternalInstruction *insn) {
insn->addressSize = (insn->hasAdSize ? 4 : 8);
insn->displacementSize = 4;
insn->immediateSize = 4;
- insn->hasOpSize = false;
+ insn->hasOpSize = false;
} else {
insn->registerSize = (insn->hasOpSize ? 2 : 4);
insn->addressSize = (insn->hasAdSize ? 4 : 8);
@@ -1663,9 +1663,9 @@ namespace X86 {
sib = 504,
sib64 = 505
};
-} // namespace X86
+} // namespace X86
-} // namespace llvm
+} // namespace llvm
static bool translateInstruction(MCInst &target,
InternalInstruction &source,
@@ -1690,7 +1690,7 @@ private:
DisassemblerMode fMode;
};
-} // namespace
+} // namespace
X86GenericDisassembler::X86GenericDisassembler(
const MCSubtargetInfo &STI,
diff --git a/contrib/libs/llvm12/lib/Target/X86/Disassembler/ya.make b/contrib/libs/llvm12/lib/Target/X86/Disassembler/ya.make
index 07b83642cc..b55833692f 100644
--- a/contrib/libs/llvm12/lib/Target/X86/Disassembler/ya.make
+++ b/contrib/libs/llvm12/lib/Target/X86/Disassembler/ya.make
@@ -12,17 +12,17 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/MC/MCDisassembler
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target/X86/TargetInfo
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/MC/MCDisassembler
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target/X86/TargetInfo
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86
- contrib/libs/llvm12/lib/Target/X86
- contrib/libs/llvm12/lib/Target/X86/Disassembler
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86
+ contrib/libs/llvm12/lib/Target/X86
+ contrib/libs/llvm12/lib/Target/X86/Disassembler
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp
index fef6c33a90..c685d7e0db 100644
--- a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp
@@ -16,7 +16,7 @@
#include "X86InstComments.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCInstrAnalysis.h"
+#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/Casting.h"
@@ -385,16 +385,16 @@ void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
raw_ostream &O) {
- // Do not print the exact form of the memory operand if it references a known
- // binary object.
- if (SymbolizeOperands && MIA) {
- uint64_t Target;
- if (MIA->evaluateBranch(*MI, 0, 0, Target))
- return;
- if (MIA->evaluateMemoryOperandAddress(*MI, 0, 0))
- return;
- }
-
+ // Do not print the exact form of the memory operand if it references a known
+ // binary object.
+ if (SymbolizeOperands && MIA) {
+ uint64_t Target;
+ if (MIA->evaluateBranch(*MI, 0, 0, Target))
+ return;
+ if (MIA->evaluateMemoryOperandAddress(*MI, 0, 0))
+ return;
+ }
+
const MCOperand &BaseReg = MI->getOperand(Op + X86::AddrBaseReg);
const MCOperand &IndexReg = MI->getOperand(Op + X86::AddrIndexReg);
const MCOperand &DispSpec = MI->getOperand(Op + X86::AddrDisp);
diff --git a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.h b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.h
index 5926418c57..f7a8505712 100644
--- a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.h
+++ b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.h
@@ -36,7 +36,7 @@ public:
raw_ostream &O);
// Autogenerated by tblgen.
- std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
+ std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &OS);
static const char *getRegisterName(unsigned RegNo);
diff --git a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index 0b1812c935..95012a148d 100644
--- a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -109,7 +109,7 @@ cl::opt<unsigned> X86PadMaxPrefixSize(
cl::desc("Maximum number of prefixes to use for padding"));
cl::opt<bool> X86PadForAlign(
- "x86-pad-for-align", cl::init(false), cl::Hidden,
+ "x86-pad-for-align", cl::init(false), cl::Hidden,
cl::desc("Pad previous instructions to implement align directives"));
cl::opt<bool> X86PadForBranchAlign(
@@ -207,8 +207,8 @@ public:
void finishLayout(MCAssembler const &Asm, MCAsmLayout &Layout) const override;
- unsigned getMaximumNopSize() const override;
-
+ unsigned getMaximumNopSize() const override;
+
bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
};
} // end anonymous namespace
@@ -957,9 +957,9 @@ void X86AsmBackend::finishLayout(MCAssembler const &Asm,
if (!X86PadForAlign && !X86PadForBranchAlign)
return;
- // The processed regions are delimitered by LabeledFragments. -g may have more
- // MCSymbols and therefore different relaxation results. X86PadForAlign is
- // disabled by default to eliminate the -g vs non -g difference.
+ // The processed regions are delimitered by LabeledFragments. -g may have more
+ // MCSymbols and therefore different relaxation results. X86PadForAlign is
+ // disabled by default to eliminate the -g vs non -g difference.
DenseSet<MCFragment *> LabeledFragments;
for (const MCSymbol &S : Asm.symbols())
LabeledFragments.insert(S.getFragment(false));
@@ -1072,21 +1072,21 @@ void X86AsmBackend::finishLayout(MCAssembler const &Asm,
}
}
-unsigned X86AsmBackend::getMaximumNopSize() const {
- if (!STI.hasFeature(X86::FeatureNOPL) && !STI.hasFeature(X86::Mode64Bit))
- return 1;
- if (STI.getFeatureBits()[X86::FeatureFast7ByteNOP])
- return 7;
- if (STI.getFeatureBits()[X86::FeatureFast15ByteNOP])
- return 15;
- if (STI.getFeatureBits()[X86::FeatureFast11ByteNOP])
- return 11;
- // FIXME: handle 32-bit mode
- // 15-bytes is the longest single NOP instruction, but 10-bytes is
- // commonly the longest that can be efficiently decoded.
- return 10;
-}
-
+unsigned X86AsmBackend::getMaximumNopSize() const {
+ if (!STI.hasFeature(X86::FeatureNOPL) && !STI.hasFeature(X86::Mode64Bit))
+ return 1;
+ if (STI.getFeatureBits()[X86::FeatureFast7ByteNOP])
+ return 7;
+ if (STI.getFeatureBits()[X86::FeatureFast15ByteNOP])
+ return 15;
+ if (STI.getFeatureBits()[X86::FeatureFast11ByteNOP])
+ return 11;
+ // FIXME: handle 32-bit mode
+ // 15-bytes is the longest single NOP instruction, but 10-bytes is
+ // commonly the longest that can be efficiently decoded.
+ return 10;
+}
+
/// Write a sequence of optimal nops to the output, covering \p Count
/// bytes.
/// \return - true on success, false on failure
@@ -1114,7 +1114,7 @@ bool X86AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
"\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00",
};
- uint64_t MaxNopLength = (uint64_t)getMaximumNopSize();
+ uint64_t MaxNopLength = (uint64_t)getMaximumNopSize();
// Emit as many MaxNopLength NOPs as needed, then emit a NOP of the remaining
// length.
@@ -1241,7 +1241,7 @@ namespace CU {
UNWIND_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF
};
-} // namespace CU
+} // namespace CU
class DarwinX86AsmBackend : public X86AsmBackend {
const MCRegisterInfo &MRI;
diff --git a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
index fc60496917..4db1bfc251 100644
--- a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
+++ b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
@@ -55,18 +55,18 @@ namespace X86 {
/// The constants to describe instr prefixes if there are
enum IPREFIXES {
IP_NO_PREFIX = 0,
- IP_HAS_OP_SIZE = 1U << 0,
- IP_HAS_AD_SIZE = 1U << 1,
- IP_HAS_REPEAT_NE = 1U << 2,
- IP_HAS_REPEAT = 1U << 3,
- IP_HAS_LOCK = 1U << 4,
- IP_HAS_NOTRACK = 1U << 5,
- IP_USE_VEX = 1U << 6,
- IP_USE_VEX2 = 1U << 7,
- IP_USE_VEX3 = 1U << 8,
- IP_USE_EVEX = 1U << 9,
- IP_USE_DISP8 = 1U << 10,
- IP_USE_DISP32 = 1U << 11,
+ IP_HAS_OP_SIZE = 1U << 0,
+ IP_HAS_AD_SIZE = 1U << 1,
+ IP_HAS_REPEAT_NE = 1U << 2,
+ IP_HAS_REPEAT = 1U << 3,
+ IP_HAS_LOCK = 1U << 4,
+ IP_HAS_NOTRACK = 1U << 5,
+ IP_USE_VEX = 1U << 6,
+ IP_USE_VEX2 = 1U << 7,
+ IP_USE_VEX3 = 1U << 8,
+ IP_USE_EVEX = 1U << 9,
+ IP_USE_DISP8 = 1U << 10,
+ IP_USE_DISP32 = 1U << 11,
};
enum OperandType : unsigned {
@@ -952,11 +952,11 @@ namespace X86II {
// NOTRACK prefix
NoTrackShift = EVEX_RCShift + 1,
- NOTRACK = 1ULL << NoTrackShift,
-
- // Force VEX encoding
- ExplicitVEXShift = NoTrackShift + 1,
- ExplicitVEXPrefix = 1ULL << ExplicitVEXShift
+ NOTRACK = 1ULL << NoTrackShift,
+
+ // Force VEX encoding
+ ExplicitVEXShift = NoTrackShift + 1,
+ ExplicitVEXPrefix = 1ULL << ExplicitVEXShift
};
/// \returns true if the instruction with given opcode is a prefix.
diff --git a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
index 177f8efdf3..fa937d3816 100644
--- a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
@@ -94,12 +94,12 @@ static void checkIs32(MCContext &Ctx, SMLoc Loc, X86_64RelType Type) {
"32 bit reloc applied to a field with a different size");
}
-static void checkIs64(MCContext &Ctx, SMLoc Loc, X86_64RelType Type) {
- if (Type != RT64_64)
- Ctx.reportError(Loc,
- "64 bit reloc applied to a field with a different size");
-}
-
+static void checkIs64(MCContext &Ctx, SMLoc Loc, X86_64RelType Type) {
+ if (Type != RT64_64)
+ Ctx.reportError(Loc,
+ "64 bit reloc applied to a field with a different size");
+}
+
static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc,
MCSymbolRefExpr::VariantKind Modifier,
X86_64RelType Type, bool IsPCRel,
@@ -218,9 +218,9 @@ static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc,
return ELF::R_X86_64_REX_GOTPCRELX;
}
llvm_unreachable("unexpected relocation type!");
- case MCSymbolRefExpr::VK_X86_PLTOFF:
- checkIs64(Ctx, Loc, Type);
- return ELF::R_X86_64_PLTOFF64;
+ case MCSymbolRefExpr::VK_X86_PLTOFF:
+ checkIs64(Ctx, Loc, Type);
+ return ELF::R_X86_64_PLTOFF64;
}
}
diff --git a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp
index 9c6db0fcb7..d8dbbbbf27 100644
--- a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp
@@ -295,10 +295,10 @@ void X86InstPrinterCommon::printRoundingControl(const MCInst *MI, unsigned Op,
/// \see MCInstPrinter::printInst
void X86InstPrinterCommon::printPCRelImm(const MCInst *MI, uint64_t Address,
unsigned OpNo, raw_ostream &O) {
- // Do not print the numberic target address when symbolizing.
- if (SymbolizeOperands)
- return;
-
+ // Do not print the numberic target address when symbolizing.
+ if (SymbolizeOperands)
+ return;
+
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isImm()) {
if (PrintBranchImmAsAddress) {
@@ -346,21 +346,21 @@ void X86InstPrinterCommon::printInstFlags(const MCInst *MI, raw_ostream &O) {
O << "\trepne\t";
else if (Flags & X86::IP_HAS_REPEAT)
O << "\trep\t";
-
- // These all require a pseudo prefix
- if ((Flags & X86::IP_USE_VEX) || (TSFlags & X86II::ExplicitVEXPrefix))
- O << "\t{vex}";
- else if (Flags & X86::IP_USE_VEX2)
- O << "\t{vex2}";
- else if (Flags & X86::IP_USE_VEX3)
- O << "\t{vex3}";
- else if (Flags & X86::IP_USE_EVEX)
- O << "\t{evex}";
-
- if (Flags & X86::IP_USE_DISP8)
- O << "\t{disp8}";
- else if (Flags & X86::IP_USE_DISP32)
- O << "\t{disp32}";
+
+ // These all require a pseudo prefix
+ if ((Flags & X86::IP_USE_VEX) || (TSFlags & X86II::ExplicitVEXPrefix))
+ O << "\t{vex}";
+ else if (Flags & X86::IP_USE_VEX2)
+ O << "\t{vex2}";
+ else if (Flags & X86::IP_USE_VEX3)
+ O << "\t{vex3}";
+ else if (Flags & X86::IP_USE_EVEX)
+ O << "\t{evex}";
+
+ if (Flags & X86::IP_USE_DISP8)
+ O << "\t{disp8}";
+ else if (Flags & X86::IP_USE_DISP32)
+ O << "\t{disp32}";
}
void X86InstPrinterCommon::printVKPair(const MCInst *MI, unsigned OpNo,
diff --git a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp
index 371f3a223a..d5b205ad9a 100644
--- a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp
@@ -16,7 +16,7 @@
#include "X86InstComments.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCInstrAnalysis.h"
+#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
@@ -343,15 +343,15 @@ void X86IntelInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
void X86IntelInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
raw_ostream &O) {
- // Do not print the exact form of the memory operand if it references a known
- // binary object.
- if (SymbolizeOperands && MIA) {
- uint64_t Target;
- if (MIA->evaluateBranch(*MI, 0, 0, Target))
- return;
- if (MIA->evaluateMemoryOperandAddress(*MI, 0, 0))
- return;
- }
+ // Do not print the exact form of the memory operand if it references a known
+ // binary object.
+ if (SymbolizeOperands && MIA) {
+ uint64_t Target;
+ if (MIA->evaluateBranch(*MI, 0, 0, Target))
+ return;
+ if (MIA->evaluateMemoryOperandAddress(*MI, 0, 0))
+ return;
+ }
const MCOperand &BaseReg = MI->getOperand(Op+X86::AddrBaseReg);
unsigned ScaleVal = MI->getOperand(Op+X86::AddrScaleAmt).getImm();
const MCOperand &IndexReg = MI->getOperand(Op+X86::AddrIndexReg);
diff --git a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.h b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.h
index 48ee4fbfcf..aa4d0545ea 100644
--- a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.h
+++ b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.h
@@ -37,7 +37,7 @@ public:
raw_ostream &O);
// Autogenerated by tblgen.
- std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
+ std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
static const char *getRegisterName(unsigned RegNo);
diff --git a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index d1e4d3bd4f..260253a530 100644
--- a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -93,8 +93,8 @@ private:
bool emitOpcodePrefix(int MemOperand, const MCInst &MI,
const MCSubtargetInfo &STI, raw_ostream &OS) const;
- bool emitREXPrefix(int MemOperand, const MCInst &MI,
- const MCSubtargetInfo &STI, raw_ostream &OS) const;
+ bool emitREXPrefix(int MemOperand, const MCInst &MI,
+ const MCSubtargetInfo &STI, raw_ostream &OS) const;
};
} // end anonymous namespace
@@ -114,28 +114,28 @@ static void emitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) {
}
}
-/// Determine if this immediate can fit in a disp8 or a compressed disp8 for
-/// EVEX instructions. \p will be set to the value to pass to the ImmOffset
-/// parameter of emitImmediate.
-static bool isDispOrCDisp8(uint64_t TSFlags, int Value, int &ImmOffset) {
- bool HasEVEX = (TSFlags & X86II::EncodingMask) == X86II::EVEX;
+/// Determine if this immediate can fit in a disp8 or a compressed disp8 for
+/// EVEX instructions. \p will be set to the value to pass to the ImmOffset
+/// parameter of emitImmediate.
+static bool isDispOrCDisp8(uint64_t TSFlags, int Value, int &ImmOffset) {
+ bool HasEVEX = (TSFlags & X86II::EncodingMask) == X86II::EVEX;
- int CD8_Scale =
+ int CD8_Scale =
(TSFlags & X86II::CD8_Scale_Mask) >> X86II::CD8_Scale_Shift;
- if (!HasEVEX || CD8_Scale == 0)
- return isInt<8>(Value);
+ if (!HasEVEX || CD8_Scale == 0)
+ return isInt<8>(Value);
- assert(isPowerOf2_32(CD8_Scale) && "Unexpected CD8 scale!");
- if (Value & (CD8_Scale - 1)) // Unaligned offset
+ assert(isPowerOf2_32(CD8_Scale) && "Unexpected CD8 scale!");
+ if (Value & (CD8_Scale - 1)) // Unaligned offset
return false;
- int CDisp8 = Value / CD8_Scale;
- if (!isInt<8>(CDisp8))
- return false;
-
- // ImmOffset will be added to Value in emitImmediate leaving just CDisp8.
- ImmOffset = CDisp8 - Value;
- return true;
+ int CDisp8 = Value / CD8_Scale;
+ if (!isInt<8>(CDisp8))
+ return false;
+
+ // ImmOffset will be added to Value in emitImmediate leaving just CDisp8.
+ ImmOffset = CDisp8 - Value;
+ return true;
}
/// \returns the appropriate fixup kind to use for an immediate in an
@@ -160,18 +160,18 @@ static MCFixupKind getImmFixupKind(uint64_t TSFlags) {
/// \returns true if the specified instruction has a 16-bit memory operand.
static bool is16BitMemOperand(const MCInst &MI, unsigned Op,
const MCSubtargetInfo &STI) {
- const MCOperand &Base = MI.getOperand(Op + X86::AddrBaseReg);
- const MCOperand &Index = MI.getOperand(Op + X86::AddrIndexReg);
+ const MCOperand &Base = MI.getOperand(Op + X86::AddrBaseReg);
+ const MCOperand &Index = MI.getOperand(Op + X86::AddrIndexReg);
- unsigned BaseReg = Base.getReg();
- unsigned IndexReg = Index.getReg();
-
- if (STI.hasFeature(X86::Mode16Bit) && BaseReg == 0 && IndexReg == 0)
+ unsigned BaseReg = Base.getReg();
+ unsigned IndexReg = Index.getReg();
+
+ if (STI.hasFeature(X86::Mode16Bit) && BaseReg == 0 && IndexReg == 0)
return true;
- if ((BaseReg != 0 &&
- X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) ||
- (IndexReg != 0 &&
- X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)))
+ if ((BaseReg != 0 &&
+ X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) ||
+ (IndexReg != 0 &&
+ X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)))
return true;
return false;
}
@@ -398,33 +398,33 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
emitByte(modRMByte(0, RegOpcodeField, 5), OS);
unsigned Opcode = MI.getOpcode();
- unsigned FixupKind = [&]() {
- // Enable relaxed relocation only for a MCSymbolRefExpr. We cannot use a
- // relaxed relocation if an offset is present (e.g. x@GOTPCREL+4).
- if (!(Disp.isExpr() && isa<MCSymbolRefExpr>(Disp.getExpr())))
- return X86::reloc_riprel_4byte;
-
- // Certain loads for GOT references can be relocated against the symbol
- // directly if the symbol ends up in the same linkage unit.
+ unsigned FixupKind = [&]() {
+ // Enable relaxed relocation only for a MCSymbolRefExpr. We cannot use a
+ // relaxed relocation if an offset is present (e.g. x@GOTPCREL+4).
+ if (!(Disp.isExpr() && isa<MCSymbolRefExpr>(Disp.getExpr())))
+ return X86::reloc_riprel_4byte;
+
+ // Certain loads for GOT references can be relocated against the symbol
+ // directly if the symbol ends up in the same linkage unit.
switch (Opcode) {
default:
return X86::reloc_riprel_4byte;
case X86::MOV64rm:
- // movq loads is a subset of reloc_riprel_4byte_relax_rex. It is a
- // special case because COFF and Mach-O don't support ELF's more
- // flexible R_X86_64_REX_GOTPCRELX relaxation.
+ // movq loads is a subset of reloc_riprel_4byte_relax_rex. It is a
+ // special case because COFF and Mach-O don't support ELF's more
+ // flexible R_X86_64_REX_GOTPCRELX relaxation.
assert(HasREX);
return X86::reloc_riprel_4byte_movq_load;
- case X86::ADC32rm:
- case X86::ADD32rm:
- case X86::AND32rm:
- case X86::CMP32rm:
- case X86::MOV32rm:
- case X86::OR32rm:
- case X86::SBB32rm:
- case X86::SUB32rm:
- case X86::TEST32mr:
- case X86::XOR32rm:
+ case X86::ADC32rm:
+ case X86::ADD32rm:
+ case X86::AND32rm:
+ case X86::CMP32rm:
+ case X86::MOV32rm:
+ case X86::OR32rm:
+ case X86::SBB32rm:
+ case X86::SUB32rm:
+ case X86::TEST32mr:
+ case X86::XOR32rm:
case X86::CALL64m:
case X86::JMP64m:
case X86::TAILJMPm64:
@@ -497,7 +497,7 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
RMfield = (IndexReg16 & 1) | ((7 - RMfield) << 1);
}
- if (Disp.isImm() && isInt<8>(Disp.getImm())) {
+ if (Disp.isImm() && isInt<8>(Disp.getImm())) {
if (Disp.getImm() == 0 && RMfield != 6) {
// There is no displacement; just the register.
emitByte(modRMByte(0, RegOpcodeField, RMfield), OS);
@@ -511,7 +511,7 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
// This is the [REG]+disp16 case.
emitByte(modRMByte(2, RegOpcodeField, RMfield), OS);
} else {
- assert(IndexReg.getReg() == 0 && "Unexpected index register!");
+ assert(IndexReg.getReg() == 0 && "Unexpected index register!");
// There is no BaseReg; this is the plain [disp16] case.
emitByte(modRMByte(0, RegOpcodeField, 6), OS);
}
@@ -521,18 +521,18 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
return;
}
- // Check for presence of {disp8} or {disp32} pseudo prefixes.
- bool UseDisp8 = MI.getFlags() & X86::IP_USE_DISP8;
- bool UseDisp32 = MI.getFlags() & X86::IP_USE_DISP32;
-
- // We only allow no displacement if no pseudo prefix is present.
- bool AllowNoDisp = !UseDisp8 && !UseDisp32;
- // Disp8 is allowed unless the {disp32} prefix is present.
- bool AllowDisp8 = !UseDisp32;
-
+ // Check for presence of {disp8} or {disp32} pseudo prefixes.
+ bool UseDisp8 = MI.getFlags() & X86::IP_USE_DISP8;
+ bool UseDisp32 = MI.getFlags() & X86::IP_USE_DISP32;
+
+ // We only allow no displacement if no pseudo prefix is present.
+ bool AllowNoDisp = !UseDisp8 && !UseDisp32;
+ // Disp8 is allowed unless the {disp32} prefix is present.
+ bool AllowDisp8 = !UseDisp32;
+
// Determine whether a SIB byte is needed.
- if (// The SIB byte must be used if there is an index register or the
- // encoding requires a SIB byte.
+ if (// The SIB byte must be used if there is an index register or the
+ // encoding requires a SIB byte.
!ForceSIB && IndexReg.getReg() == 0 &&
// The SIB byte must be used if the base is ESP/RSP/R12, all of which
// encode to an R/M value of 4, which indicates that a SIB byte is
@@ -548,12 +548,12 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
return;
}
- // If the base is not EBP/ESP/R12/R13 and there is no displacement, use
- // simple indirect register encoding, this handles addresses like [EAX].
- // The encoding for [EBP] or[R13] with no displacement means [disp32] so we
- // handle it by emitting a displacement of 0 later.
+ // If the base is not EBP/ESP/R12/R13 and there is no displacement, use
+ // simple indirect register encoding, this handles addresses like [EAX].
+ // The encoding for [EBP] or[R13] with no displacement means [disp32] so we
+ // handle it by emitting a displacement of 0 later.
if (BaseRegNo != N86::EBP) {
- if (Disp.isImm() && Disp.getImm() == 0 && AllowNoDisp) {
+ if (Disp.isImm() && Disp.getImm() == 0 && AllowNoDisp) {
emitByte(modRMByte(0, RegOpcodeField, BaseRegNo), OS);
return;
}
@@ -572,22 +572,22 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
}
// Otherwise, if the displacement fits in a byte, encode as [REG+disp8].
- // Including a compressed disp8 for EVEX instructions that support it.
- // This also handles the 0 displacement for [EBP] or [R13]. We can't use
- // disp8 if the {disp32} pseudo prefix is present.
- if (Disp.isImm() && AllowDisp8) {
- int ImmOffset = 0;
- if (isDispOrCDisp8(TSFlags, Disp.getImm(), ImmOffset)) {
+ // Including a compressed disp8 for EVEX instructions that support it.
+ // This also handles the 0 displacement for [EBP] or [R13]. We can't use
+ // disp8 if the {disp32} pseudo prefix is present.
+ if (Disp.isImm() && AllowDisp8) {
+ int ImmOffset = 0;
+ if (isDispOrCDisp8(TSFlags, Disp.getImm(), ImmOffset)) {
emitByte(modRMByte(1, RegOpcodeField, BaseRegNo), OS);
emitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, StartByte, OS, Fixups,
- ImmOffset);
+ ImmOffset);
return;
}
}
- // Otherwise, emit the most general non-SIB encoding: [REG+disp32].
- // Displacement may be 0 for [EBP] or [R13] case if {disp32} pseudo prefix
- // prevented using disp8 above.
+ // Otherwise, emit the most general non-SIB encoding: [REG+disp32].
+ // Displacement may be 0 for [EBP] or [R13] case if {disp32} pseudo prefix
+ // prevented using disp8 above.
emitByte(modRMByte(2, RegOpcodeField, BaseRegNo), OS);
unsigned Opcode = MI.getOpcode();
unsigned FixupKind = Opcode == X86::MOV32rm ? X86::reloc_signed_4byte_relax
@@ -607,43 +607,43 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
if (BaseReg == 0) {
// If there is no base register, we emit the special case SIB byte with
// MOD=0, BASE=5, to JUST get the index, scale, and displacement.
- BaseRegNo = 5;
+ BaseRegNo = 5;
emitByte(modRMByte(0, RegOpcodeField, 4), OS);
ForceDisp32 = true;
- } else if (Disp.isImm() && Disp.getImm() == 0 && AllowNoDisp &&
- // Base reg can't be EBP/RBP/R13 as that would end up with '5' as
- // the base field, but that is the magic [*] nomenclature that
- // indicates no base when mod=0. For these cases we'll emit a 0
- // displacement instead.
+ } else if (Disp.isImm() && Disp.getImm() == 0 && AllowNoDisp &&
+ // Base reg can't be EBP/RBP/R13 as that would end up with '5' as
+ // the base field, but that is the magic [*] nomenclature that
+ // indicates no base when mod=0. For these cases we'll emit a 0
+ // displacement instead.
BaseRegNo != N86::EBP) {
// Emit no displacement ModR/M byte
emitByte(modRMByte(0, RegOpcodeField, 4), OS);
- } else if (Disp.isImm() && AllowDisp8 &&
- isDispOrCDisp8(TSFlags, Disp.getImm(), ImmOffset)) {
- // Displacement fits in a byte or matches an EVEX compressed disp8, use
- // disp8 encoding. This also handles EBP/R13 base with 0 displacement unless
- // {disp32} pseudo prefix was used.
+ } else if (Disp.isImm() && AllowDisp8 &&
+ isDispOrCDisp8(TSFlags, Disp.getImm(), ImmOffset)) {
+ // Displacement fits in a byte or matches an EVEX compressed disp8, use
+ // disp8 encoding. This also handles EBP/R13 base with 0 displacement unless
+ // {disp32} pseudo prefix was used.
emitByte(modRMByte(1, RegOpcodeField, 4), OS);
- ForceDisp8 = true;
+ ForceDisp8 = true;
} else {
- // Otherwise, emit the normal disp32 encoding.
+ // Otherwise, emit the normal disp32 encoding.
emitByte(modRMByte(2, RegOpcodeField, 4), OS);
- ForceDisp32 = true;
+ ForceDisp32 = true;
}
// Calculate what the SS field value should be...
static const unsigned SSTable[] = {~0U, 0, 1, ~0U, 2, ~0U, ~0U, ~0U, 3};
unsigned SS = SSTable[Scale.getImm()];
- unsigned IndexRegNo = IndexReg.getReg() ? getX86RegNum(IndexReg) : 4;
+ unsigned IndexRegNo = IndexReg.getReg() ? getX86RegNum(IndexReg) : 4;
+
+ emitSIBByte(SS, IndexRegNo, BaseRegNo, OS);
- emitSIBByte(SS, IndexRegNo, BaseRegNo, OS);
-
// Do we need to output a displacement?
if (ForceDisp8)
emitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, StartByte, OS, Fixups,
ImmOffset);
- else if (ForceDisp32)
+ else if (ForceDisp32)
emitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte),
StartByte, OS, Fixups);
}
@@ -1201,7 +1201,7 @@ void X86MCCodeEmitter::emitVEXOpcodePrefix(int MemOperand, const MCInst &MI,
///
/// \returns true if REX prefix is used, otherwise returns false.
bool X86MCCodeEmitter::emitREXPrefix(int MemOperand, const MCInst &MI,
- const MCSubtargetInfo &STI,
+ const MCSubtargetInfo &STI,
raw_ostream &OS) const {
uint8_t REX = [&, MemOperand]() {
uint8_t REX = 0;
@@ -1222,28 +1222,28 @@ bool X86MCCodeEmitter::emitREXPrefix(int MemOperand, const MCInst &MI,
// If it accesses SPL, BPL, SIL, or DIL, then it requires a 0x40 REX prefix.
for (unsigned i = CurOp; i != NumOps; ++i) {
const MCOperand &MO = MI.getOperand(i);
- if (MO.isReg()) {
- unsigned Reg = MO.getReg();
- if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH ||
- Reg == X86::DH)
- UsesHighByteReg = true;
- if (X86II::isX86_64NonExtLowByteReg(Reg))
- // FIXME: The caller of determineREXPrefix slaps this prefix onto
- // anything that returns non-zero.
- REX |= 0x40; // REX fixed encoding prefix
- } else if (MO.isExpr() &&
- STI.getTargetTriple().getEnvironment() == Triple::GNUX32) {
- // GOTTPOFF and TLSDESC relocations require a REX prefix to allow
- // linker optimizations: even if the instructions we see may not require
- // any prefix, they may be replaced by instructions that do. This is
- // handled as a special case here so that it also works for hand-written
- // assembly without the user needing to write REX, as with GNU as.
- const auto *Ref = dyn_cast<MCSymbolRefExpr>(MO.getExpr());
- if (Ref && (Ref->getKind() == MCSymbolRefExpr::VK_GOTTPOFF ||
- Ref->getKind() == MCSymbolRefExpr::VK_TLSDESC)) {
- REX |= 0x40; // REX fixed encoding prefix
- }
- }
+ if (MO.isReg()) {
+ unsigned Reg = MO.getReg();
+ if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH ||
+ Reg == X86::DH)
+ UsesHighByteReg = true;
+ if (X86II::isX86_64NonExtLowByteReg(Reg))
+ // FIXME: The caller of determineREXPrefix slaps this prefix onto
+ // anything that returns non-zero.
+ REX |= 0x40; // REX fixed encoding prefix
+ } else if (MO.isExpr() &&
+ STI.getTargetTriple().getEnvironment() == Triple::GNUX32) {
+ // GOTTPOFF and TLSDESC relocations require a REX prefix to allow
+ // linker optimizations: even if the instructions we see may not require
+ // any prefix, they may be replaced by instructions that do. This is
+ // handled as a special case here so that it also works for hand-written
+ // assembly without the user needing to write REX, as with GNU as.
+ const auto *Ref = dyn_cast<MCSymbolRefExpr>(MO.getExpr());
+ if (Ref && (Ref->getKind() == MCSymbolRefExpr::VK_GOTTPOFF ||
+ Ref->getKind() == MCSymbolRefExpr::VK_TLSDESC)) {
+ REX |= 0x40; // REX fixed encoding prefix
+ }
+ }
}
switch (TSFlags & X86II::FormMask) {
@@ -1366,7 +1366,7 @@ bool X86MCCodeEmitter::emitOpcodePrefix(int MemOperand, const MCInst &MI,
assert((STI.hasFeature(X86::Mode64Bit) || !(TSFlags & X86II::REX_W)) &&
"REX.W requires 64bit mode.");
bool HasREX = STI.hasFeature(X86::Mode64Bit)
- ? emitREXPrefix(MemOperand, MI, STI, OS)
+ ? emitREXPrefix(MemOperand, MI, STI, OS)
: false;
// 0x0F escape code must be emitted just before the opcode.
diff --git a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
index 7214b80941..5cf8d77519 100644
--- a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
@@ -44,10 +44,10 @@ using namespace llvm;
std::string X86_MC::ParseX86Triple(const Triple &TT) {
std::string FS;
- // SSE2 should default to enabled in 64-bit mode, but can be turned off
- // explicitly.
- if (TT.isArch64Bit())
- FS = "+64bit-mode,-32bit-mode,-16bit-mode,+sse2";
+ // SSE2 should default to enabled in 64-bit mode, but can be turned off
+ // explicitly.
+ if (TT.isArch64Bit())
+ FS = "+64bit-mode,-32bit-mode,-16bit-mode,+sse2";
else if (TT.getEnvironment() != Triple::CODE16)
FS = "-64bit-mode,+32bit-mode,-16bit-mode";
else
@@ -292,10 +292,10 @@ MCSubtargetInfo *X86_MC::createX86MCSubtargetInfo(const Triple &TT,
if (!FS.empty())
ArchFS = (Twine(ArchFS) + "," + FS).str();
- if (CPU.empty())
- CPU = "generic";
+ if (CPU.empty())
+ CPU = "generic";
- return createX86MCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, ArchFS);
+ return createX86MCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, ArchFS);
}
static MCInstrInfo *createX86MCInstrInfo() {
diff --git a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h
index 69fc238074..35604cd3ec 100644
--- a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h
+++ b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h
@@ -85,11 +85,11 @@ MCAsmBackend *createX86_64AsmBackend(const Target &T,
/// Implements X86-only directives for assembly emission.
MCTargetStreamer *createX86AsmTargetStreamer(MCStreamer &S,
formatted_raw_ostream &OS,
- MCInstPrinter *InstPrinter,
- bool IsVerboseAsm);
+ MCInstPrinter *InstPrinter,
+ bool IsVerboseAsm);
/// Implements X86-only directives for object files.
-MCTargetStreamer *createX86ObjectTargetStreamer(MCStreamer &S,
+MCTargetStreamer *createX86ObjectTargetStreamer(MCStreamer &S,
const MCSubtargetInfo &STI);
/// Construct an X86 Windows COFF machine code streamer which will generate
diff --git a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
index 40fc8527c3..b98e58d653 100644
--- a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
@@ -68,7 +68,7 @@ public:
FixedValue);
}
};
-} // namespace
+} // namespace
static bool isFixupKindRIPRel(unsigned Kind) {
return Kind == X86::reloc_riprel_4byte ||
diff --git a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ShuffleDecode.cpp b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ShuffleDecode.cpp
index 7e3f6d8335..201b22d623 100644
--- a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ShuffleDecode.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86ShuffleDecode.cpp
@@ -568,4 +568,4 @@ void DecodeVPERMV3Mask(ArrayRef<uint64_t> RawMask, const APInt &UndefElts,
}
}
-} // namespace llvm
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86WinCOFFStreamer.cpp b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86WinCOFFStreamer.cpp
index 72bb41e94b..c292112461 100644
--- a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86WinCOFFStreamer.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/X86WinCOFFStreamer.cpp
@@ -26,7 +26,7 @@ public:
: MCWinCOFFStreamer(C, std::move(AB), std::move(CE), std::move(OW)) {}
void EmitWinEHHandlerData(SMLoc Loc) override;
- void EmitWindowsUnwindTables(WinEH::FrameInfo *Frame) override;
+ void EmitWindowsUnwindTables(WinEH::FrameInfo *Frame) override;
void EmitWindowsUnwindTables() override;
void EmitCVFPOData(const MCSymbol *ProcSym, SMLoc Loc) override;
void finishImpl() override;
@@ -38,13 +38,13 @@ void X86WinCOFFStreamer::EmitWinEHHandlerData(SMLoc Loc) {
// We have to emit the unwind info now, because this directive
// actually switches to the .xdata section.
if (WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo())
- EHStreamer.EmitUnwindInfo(*this, CurFrame, /* HandlerData = */ true);
+ EHStreamer.EmitUnwindInfo(*this, CurFrame, /* HandlerData = */ true);
+}
+
+void X86WinCOFFStreamer::EmitWindowsUnwindTables(WinEH::FrameInfo *Frame) {
+ EHStreamer.EmitUnwindInfo(*this, Frame, /* HandlerData = */ false);
}
-void X86WinCOFFStreamer::EmitWindowsUnwindTables(WinEH::FrameInfo *Frame) {
- EHStreamer.EmitUnwindInfo(*this, Frame, /* HandlerData = */ false);
-}
-
void X86WinCOFFStreamer::EmitWindowsUnwindTables() {
if (!getNumWinFrameInfos())
return;
@@ -63,7 +63,7 @@ void X86WinCOFFStreamer::finishImpl() {
MCWinCOFFStreamer::finishImpl();
}
-} // namespace
+} // namespace
MCStreamer *llvm::createX86WinCOFFStreamer(MCContext &C,
std::unique_ptr<MCAsmBackend> &&AB,
diff --git a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/ya.make b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/ya.make
index 77b54a6412..8da0d02f5b 100644
--- a/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/ya.make
+++ b/contrib/libs/llvm12/lib/Target/X86/MCTargetDesc/ya.make
@@ -12,19 +12,19 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/MC/MCDisassembler
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target/X86/TargetInfo
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/MC/MCDisassembler
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target/X86/TargetInfo
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86
- contrib/libs/llvm12/lib/Target/X86
- contrib/libs/llvm12/lib/Target/X86/MCTargetDesc
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86
+ contrib/libs/llvm12/lib/Target/X86
+ contrib/libs/llvm12/lib/Target/X86/MCTargetDesc
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/X86/TargetInfo/ya.make b/contrib/libs/llvm12/lib/Target/X86/TargetInfo/ya.make
index b21991ca46..2f30db941e 100644
--- a/contrib/libs/llvm12/lib/Target/X86/TargetInfo/ya.make
+++ b/contrib/libs/llvm12/lib/Target/X86/TargetInfo/ya.make
@@ -12,13 +12,13 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
- contrib/libs/llvm12/lib/Target/X86
- contrib/libs/llvm12/lib/Target/X86/TargetInfo
+ contrib/libs/llvm12/lib/Target/X86
+ contrib/libs/llvm12/lib/Target/X86/TargetInfo
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86.h b/contrib/libs/llvm12/lib/Target/X86/X86.h
index f5a9baefa2..e17b9ba550 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86.h
+++ b/contrib/libs/llvm12/lib/Target/X86/X86.h
@@ -76,10 +76,10 @@ FunctionPass *createX86FlagsCopyLoweringPass();
/// Return a pass that expands WinAlloca pseudo-instructions.
FunctionPass *createX86WinAllocaExpander();
-FunctionPass *createX86TileConfigPass();
-
-FunctionPass *createX86PreTileConfigPass();
-
+FunctionPass *createX86TileConfigPass();
+
+FunctionPass *createX86PreTileConfigPass();
+
/// Return a pass that inserts int3 at the end of the function if it ends with a
/// CALL instruction. The pass does the same for each funclet as well. This
/// ensures that the open interval of function start and end PCs contains all
@@ -166,9 +166,9 @@ void initializeX86OptimizeLEAPassPass(PassRegistry &);
void initializeX86PartialReductionPass(PassRegistry &);
void initializeX86SpeculativeLoadHardeningPassPass(PassRegistry &);
void initializeX86SpeculativeExecutionSideEffectSuppressionPass(PassRegistry &);
-void initializeX86PreTileConfigPass(PassRegistry &);
-void initializeX86TileConfigPass(PassRegistry &);
-void initializeX86LowerAMXTypeLegacyPassPass(PassRegistry &);
+void initializeX86PreTileConfigPass(PassRegistry &);
+void initializeX86TileConfigPass(PassRegistry &);
+void initializeX86LowerAMXTypeLegacyPassPass(PassRegistry &);
namespace X86AS {
enum : unsigned {
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86.td b/contrib/libs/llvm12/lib/Target/X86/X86.td
index d17c7f4f9b..c492d686c5 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86.td
@@ -171,9 +171,9 @@ def FeaturePKU : SubtargetFeature<"pku", "HasPKU", "true",
def FeatureVNNI : SubtargetFeature<"avx512vnni", "HasVNNI", "true",
"Enable AVX-512 Vector Neural Network Instructions",
[FeatureAVX512]>;
-def FeatureAVXVNNI : SubtargetFeature<"avxvnni", "HasAVXVNNI", "true",
- "Support AVX_VNNI encoding",
- [FeatureAVX2]>;
+def FeatureAVXVNNI : SubtargetFeature<"avxvnni", "HasAVXVNNI", "true",
+ "Support AVX_VNNI encoding",
+ [FeatureAVX2]>;
def FeatureBF16 : SubtargetFeature<"avx512bf16", "HasBF16", "true",
"Support bfloat16 floating point",
[FeatureBWI]>;
@@ -237,8 +237,8 @@ def FeaturePRFCHW : SubtargetFeature<"prfchw", "HasPRFCHW", "true",
"Support PRFCHW instructions">;
def FeatureRDSEED : SubtargetFeature<"rdseed", "HasRDSEED", "true",
"Support RDSEED instruction">;
-def FeatureLAHFSAHF : SubtargetFeature<"sahf", "HasLAHFSAHF64", "true",
- "Support LAHF and SAHF instructions in 64-bit mode">;
+def FeatureLAHFSAHF : SubtargetFeature<"sahf", "HasLAHFSAHF64", "true",
+ "Support LAHF and SAHF instructions in 64-bit mode">;
def FeatureMWAITX : SubtargetFeature<"mwaitx", "HasMWAITX", "true",
"Enable MONITORX/MWAITX timer functionality">;
def FeatureCLZERO : SubtargetFeature<"clzero", "HasCLZERO", "true",
@@ -282,20 +282,20 @@ def FeatureWAITPKG : SubtargetFeature<"waitpkg", "HasWAITPKG", "true",
"Wait and pause enhancements">;
def FeatureENQCMD : SubtargetFeature<"enqcmd", "HasENQCMD", "true",
"Has ENQCMD instructions">;
-def FeatureKL : SubtargetFeature<"kl", "HasKL", "true",
- "Support Key Locker kl Instructions",
- [FeatureSSE2]>;
-def FeatureWIDEKL : SubtargetFeature<"widekl", "HasWIDEKL", "true",
- "Support Key Locker wide Instructions",
- [FeatureKL]>;
-def FeatureHRESET : SubtargetFeature<"hreset", "HasHRESET", "true",
- "Has hreset instruction">;
+def FeatureKL : SubtargetFeature<"kl", "HasKL", "true",
+ "Support Key Locker kl Instructions",
+ [FeatureSSE2]>;
+def FeatureWIDEKL : SubtargetFeature<"widekl", "HasWIDEKL", "true",
+ "Support Key Locker wide Instructions",
+ [FeatureKL]>;
+def FeatureHRESET : SubtargetFeature<"hreset", "HasHRESET", "true",
+ "Has hreset instruction">;
def FeatureSERIALIZE : SubtargetFeature<"serialize", "HasSERIALIZE", "true",
"Has serialize instruction">;
def FeatureTSXLDTRK : SubtargetFeature<"tsxldtrk", "HasTSXLDTRK", "true",
"Support TSXLDTRK instructions">;
-def FeatureUINTR : SubtargetFeature<"uintr", "HasUINTR", "true",
- "Has UINTR Instructions">;
+def FeatureUINTR : SubtargetFeature<"uintr", "HasUINTR", "true",
+ "Has UINTR Instructions">;
// On some processors, instructions that implicitly take two memory operands are
// slow. In practice, this means that CALL, PUSH, and POP with memory operands
// should be avoided in favor of a MOV + register CALL/PUSH/POP.
@@ -385,12 +385,12 @@ def FeatureERMSB
"ermsb", "HasERMSB", "true",
"REP MOVS/STOS are fast">;
-// Icelake and newer processors have Fast Short REP MOV.
-def FeatureFSRM
- : SubtargetFeature<
- "fsrm", "HasFSRM", "true",
- "REP MOVSB of short lengths is faster">;
-
+// Icelake and newer processors have Fast Short REP MOV.
+def FeatureFSRM
+ : SubtargetFeature<
+ "fsrm", "HasFSRM", "true",
+ "REP MOVSB of short lengths is faster">;
+
// Bulldozer and newer processors can merge CMP/TEST (but not other
// instructions) with conditional branches.
def FeatureBranchFusion
@@ -565,59 +565,59 @@ include "X86SchedSkylakeServer.td"
//===----------------------------------------------------------------------===//
def ProcessorFeatures {
- // x86-64 and x86-64-v[234]
- list<SubtargetFeature> X86_64V1Features = [
- FeatureX87, FeatureCMPXCHG8B, FeatureCMOV, FeatureMMX, FeatureSSE2,
- FeatureFXSR, FeatureNOPL, Feature64Bit
- ];
- list<SubtargetFeature> X86_64V2Features = !listconcat(
- X86_64V1Features,
- [FeatureCMPXCHG16B, FeatureLAHFSAHF, FeaturePOPCNT, FeatureSSE42]);
- list<SubtargetFeature> X86_64V3Features = !listconcat(X86_64V2Features, [
- FeatureAVX2, FeatureBMI, FeatureBMI2, FeatureF16C, FeatureFMA, FeatureLZCNT,
- FeatureMOVBE, FeatureXSAVE
- ]);
- list<SubtargetFeature> X86_64V4Features = !listconcat(X86_64V3Features, [
- FeatureBWI,
- FeatureCDI,
- FeatureDQI,
- FeatureVLX,
- ]);
-
+ // x86-64 and x86-64-v[234]
+ list<SubtargetFeature> X86_64V1Features = [
+ FeatureX87, FeatureCMPXCHG8B, FeatureCMOV, FeatureMMX, FeatureSSE2,
+ FeatureFXSR, FeatureNOPL, Feature64Bit
+ ];
+ list<SubtargetFeature> X86_64V2Features = !listconcat(
+ X86_64V1Features,
+ [FeatureCMPXCHG16B, FeatureLAHFSAHF, FeaturePOPCNT, FeatureSSE42]);
+ list<SubtargetFeature> X86_64V3Features = !listconcat(X86_64V2Features, [
+ FeatureAVX2, FeatureBMI, FeatureBMI2, FeatureF16C, FeatureFMA, FeatureLZCNT,
+ FeatureMOVBE, FeatureXSAVE
+ ]);
+ list<SubtargetFeature> X86_64V4Features = !listconcat(X86_64V3Features, [
+ FeatureBWI,
+ FeatureCDI,
+ FeatureDQI,
+ FeatureVLX,
+ ]);
+
// Nehalem
- list<SubtargetFeature> NHMFeatures = X86_64V2Features;
- list<SubtargetFeature> NHMTuning = [FeatureMacroFusion,
- FeatureInsertVZEROUPPER];
+ list<SubtargetFeature> NHMFeatures = X86_64V2Features;
+ list<SubtargetFeature> NHMTuning = [FeatureMacroFusion,
+ FeatureInsertVZEROUPPER];
// Westmere
list<SubtargetFeature> WSMAdditionalFeatures = [FeaturePCLMUL];
- list<SubtargetFeature> WSMTuning = NHMTuning;
+ list<SubtargetFeature> WSMTuning = NHMTuning;
list<SubtargetFeature> WSMFeatures =
- !listconcat(NHMFeatures, WSMAdditionalFeatures);
+ !listconcat(NHMFeatures, WSMAdditionalFeatures);
// Sandybridge
list<SubtargetFeature> SNBAdditionalFeatures = [FeatureAVX,
FeatureXSAVE,
- FeatureXSAVEOPT];
- list<SubtargetFeature> SNBTuning = [FeatureMacroFusion,
- FeatureSlow3OpsLEA,
- FeatureSlowDivide64,
- FeatureSlowUAMem32,
- FeatureFastScalarFSQRT,
- FeatureFastSHLDRotate,
- FeatureFast15ByteNOP,
- FeaturePOPCNTFalseDeps,
- FeatureInsertVZEROUPPER];
+ FeatureXSAVEOPT];
+ list<SubtargetFeature> SNBTuning = [FeatureMacroFusion,
+ FeatureSlow3OpsLEA,
+ FeatureSlowDivide64,
+ FeatureSlowUAMem32,
+ FeatureFastScalarFSQRT,
+ FeatureFastSHLDRotate,
+ FeatureFast15ByteNOP,
+ FeaturePOPCNTFalseDeps,
+ FeatureInsertVZEROUPPER];
list<SubtargetFeature> SNBFeatures =
- !listconcat(WSMFeatures, SNBAdditionalFeatures);
+ !listconcat(WSMFeatures, SNBAdditionalFeatures);
// Ivybridge
list<SubtargetFeature> IVBAdditionalFeatures = [FeatureRDRAND,
FeatureF16C,
FeatureFSGSBase];
- list<SubtargetFeature> IVBTuning = SNBTuning;
+ list<SubtargetFeature> IVBTuning = SNBTuning;
list<SubtargetFeature> IVBFeatures =
- !listconcat(SNBFeatures, IVBAdditionalFeatures);
+ !listconcat(SNBFeatures, IVBAdditionalFeatures);
// Haswell
list<SubtargetFeature> HSWAdditionalFeatures = [FeatureAVX2,
@@ -627,86 +627,86 @@ def ProcessorFeatures {
FeatureFMA,
FeatureINVPCID,
FeatureLZCNT,
- FeatureMOVBE];
- list<SubtargetFeature> HSWTuning = [FeatureMacroFusion,
- FeatureSlow3OpsLEA,
- FeatureSlowDivide64,
- FeatureFastScalarFSQRT,
- FeatureFastSHLDRotate,
- FeatureFast15ByteNOP,
- FeatureFastVariableShuffle,
- FeaturePOPCNTFalseDeps,
- FeatureLZCNTFalseDeps,
- FeatureInsertVZEROUPPER];
+ FeatureMOVBE];
+ list<SubtargetFeature> HSWTuning = [FeatureMacroFusion,
+ FeatureSlow3OpsLEA,
+ FeatureSlowDivide64,
+ FeatureFastScalarFSQRT,
+ FeatureFastSHLDRotate,
+ FeatureFast15ByteNOP,
+ FeatureFastVariableShuffle,
+ FeaturePOPCNTFalseDeps,
+ FeatureLZCNTFalseDeps,
+ FeatureInsertVZEROUPPER];
list<SubtargetFeature> HSWFeatures =
- !listconcat(IVBFeatures, HSWAdditionalFeatures);
+ !listconcat(IVBFeatures, HSWAdditionalFeatures);
// Broadwell
list<SubtargetFeature> BDWAdditionalFeatures = [FeatureADX,
FeatureRDSEED,
FeaturePRFCHW];
- list<SubtargetFeature> BDWTuning = HSWTuning;
+ list<SubtargetFeature> BDWTuning = HSWTuning;
list<SubtargetFeature> BDWFeatures =
- !listconcat(HSWFeatures, BDWAdditionalFeatures);
+ !listconcat(HSWFeatures, BDWAdditionalFeatures);
// Skylake
list<SubtargetFeature> SKLAdditionalFeatures = [FeatureAES,
FeatureXSAVEC,
FeatureXSAVES,
FeatureCLFLUSHOPT,
- FeatureSGX];
- list<SubtargetFeature> SKLTuning = [FeatureHasFastGather,
- FeatureMacroFusion,
- FeatureSlow3OpsLEA,
- FeatureSlowDivide64,
- FeatureFastScalarFSQRT,
- FeatureFastVectorFSQRT,
- FeatureFastSHLDRotate,
- FeatureFast15ByteNOP,
- FeatureFastVariableShuffle,
- FeaturePOPCNTFalseDeps,
- FeatureInsertVZEROUPPER];
+ FeatureSGX];
+ list<SubtargetFeature> SKLTuning = [FeatureHasFastGather,
+ FeatureMacroFusion,
+ FeatureSlow3OpsLEA,
+ FeatureSlowDivide64,
+ FeatureFastScalarFSQRT,
+ FeatureFastVectorFSQRT,
+ FeatureFastSHLDRotate,
+ FeatureFast15ByteNOP,
+ FeatureFastVariableShuffle,
+ FeaturePOPCNTFalseDeps,
+ FeatureInsertVZEROUPPER];
list<SubtargetFeature> SKLFeatures =
- !listconcat(BDWFeatures, SKLAdditionalFeatures);
+ !listconcat(BDWFeatures, SKLAdditionalFeatures);
// Skylake-AVX512
- list<SubtargetFeature> SKXAdditionalFeatures = [FeatureAES,
- FeatureXSAVEC,
- FeatureXSAVES,
- FeatureCLFLUSHOPT,
- FeatureAVX512,
+ list<SubtargetFeature> SKXAdditionalFeatures = [FeatureAES,
+ FeatureXSAVEC,
+ FeatureXSAVES,
+ FeatureCLFLUSHOPT,
+ FeatureAVX512,
FeatureCDI,
FeatureDQI,
FeatureBWI,
FeatureVLX,
FeaturePKU,
FeatureCLWB];
- list<SubtargetFeature> SKXTuning = [FeatureHasFastGather,
- FeatureMacroFusion,
- FeatureSlow3OpsLEA,
- FeatureSlowDivide64,
- FeatureFastScalarFSQRT,
- FeatureFastVectorFSQRT,
- FeatureFastSHLDRotate,
- FeatureFast15ByteNOP,
- FeatureFastVariableShuffle,
- FeaturePrefer256Bit,
- FeaturePOPCNTFalseDeps,
- FeatureInsertVZEROUPPER];
+ list<SubtargetFeature> SKXTuning = [FeatureHasFastGather,
+ FeatureMacroFusion,
+ FeatureSlow3OpsLEA,
+ FeatureSlowDivide64,
+ FeatureFastScalarFSQRT,
+ FeatureFastVectorFSQRT,
+ FeatureFastSHLDRotate,
+ FeatureFast15ByteNOP,
+ FeatureFastVariableShuffle,
+ FeaturePrefer256Bit,
+ FeaturePOPCNTFalseDeps,
+ FeatureInsertVZEROUPPER];
list<SubtargetFeature> SKXFeatures =
- !listconcat(BDWFeatures, SKXAdditionalFeatures);
+ !listconcat(BDWFeatures, SKXAdditionalFeatures);
// Cascadelake
list<SubtargetFeature> CLXAdditionalFeatures = [FeatureVNNI];
- list<SubtargetFeature> CLXTuning = SKXTuning;
+ list<SubtargetFeature> CLXTuning = SKXTuning;
list<SubtargetFeature> CLXFeatures =
- !listconcat(SKXFeatures, CLXAdditionalFeatures);
+ !listconcat(SKXFeatures, CLXAdditionalFeatures);
// Cooperlake
list<SubtargetFeature> CPXAdditionalFeatures = [FeatureBF16];
- list<SubtargetFeature> CPXTuning = SKXTuning;
+ list<SubtargetFeature> CPXTuning = SKXTuning;
list<SubtargetFeature> CPXFeatures =
- !listconcat(CLXFeatures, CPXAdditionalFeatures);
+ !listconcat(CLXFeatures, CPXAdditionalFeatures);
// Cannonlake
list<SubtargetFeature> CNLAdditionalFeatures = [FeatureAVX512,
@@ -717,20 +717,20 @@ def ProcessorFeatures {
FeaturePKU,
FeatureVBMI,
FeatureIFMA,
- FeatureSHA];
- list<SubtargetFeature> CNLTuning = [FeatureHasFastGather,
- FeatureMacroFusion,
- FeatureSlow3OpsLEA,
- FeatureSlowDivide64,
- FeatureFastScalarFSQRT,
- FeatureFastVectorFSQRT,
- FeatureFastSHLDRotate,
- FeatureFast15ByteNOP,
- FeatureFastVariableShuffle,
- FeaturePrefer256Bit,
- FeatureInsertVZEROUPPER];
+ FeatureSHA];
+ list<SubtargetFeature> CNLTuning = [FeatureHasFastGather,
+ FeatureMacroFusion,
+ FeatureSlow3OpsLEA,
+ FeatureSlowDivide64,
+ FeatureFastScalarFSQRT,
+ FeatureFastVectorFSQRT,
+ FeatureFastSHLDRotate,
+ FeatureFast15ByteNOP,
+ FeatureFastVariableShuffle,
+ FeaturePrefer256Bit,
+ FeatureInsertVZEROUPPER];
list<SubtargetFeature> CNLFeatures =
- !listconcat(SKLFeatures, CNLAdditionalFeatures);
+ !listconcat(SKLFeatures, CNLAdditionalFeatures);
// Icelake
list<SubtargetFeature> ICLAdditionalFeatures = [FeatureBITALG,
@@ -741,81 +741,81 @@ def ProcessorFeatures {
FeatureVPOPCNTDQ,
FeatureGFNI,
FeatureCLWB,
- FeatureRDPID,
- FeatureFSRM];
- list<SubtargetFeature> ICLTuning = CNLTuning;
+ FeatureRDPID,
+ FeatureFSRM];
+ list<SubtargetFeature> ICLTuning = CNLTuning;
list<SubtargetFeature> ICLFeatures =
- !listconcat(CNLFeatures, ICLAdditionalFeatures);
+ !listconcat(CNLFeatures, ICLAdditionalFeatures);
// Icelake Server
- list<SubtargetFeature> ICXAdditionalFeatures = [FeaturePCONFIG,
- FeatureWBNOINVD];
- list<SubtargetFeature> ICXTuning = CNLTuning;
+ list<SubtargetFeature> ICXAdditionalFeatures = [FeaturePCONFIG,
+ FeatureWBNOINVD];
+ list<SubtargetFeature> ICXTuning = CNLTuning;
list<SubtargetFeature> ICXFeatures =
- !listconcat(ICLFeatures, ICXAdditionalFeatures);
+ !listconcat(ICLFeatures, ICXAdditionalFeatures);
//Tigerlake
list<SubtargetFeature> TGLAdditionalFeatures = [FeatureVP2INTERSECT,
FeatureMOVDIRI,
FeatureMOVDIR64B,
FeatureSHSTK];
- list<SubtargetFeature> TGLTuning = CNLTuning;
+ list<SubtargetFeature> TGLTuning = CNLTuning;
list<SubtargetFeature> TGLFeatures =
- !listconcat(ICLFeatures, TGLAdditionalFeatures );
-
- //Sapphirerapids
- list<SubtargetFeature> SPRAdditionalFeatures = [FeatureAMXTILE,
- FeatureAMXINT8,
- FeatureAMXBF16,
- FeatureBF16,
- FeatureSERIALIZE,
- FeatureCLDEMOTE,
- FeatureWAITPKG,
- FeaturePTWRITE,
- FeatureAVXVNNI,
- FeatureTSXLDTRK,
- FeatureENQCMD,
- FeatureSHSTK,
- FeatureVP2INTERSECT,
- FeatureMOVDIRI,
- FeatureMOVDIR64B,
- FeatureUINTR];
- list<SubtargetFeature> SPRTuning = ICXTuning;
- list<SubtargetFeature> SPRFeatures =
- !listconcat(ICXFeatures, SPRAdditionalFeatures);
-
- // Alderlake
- list<SubtargetFeature> ADLAdditionalFeatures = [FeatureAVXVNNI,
- FeatureCLDEMOTE,
- FeatureHRESET,
- FeaturePTWRITE,
- FeatureSERIALIZE,
- FeatureWAITPKG];
- list<SubtargetFeature> ADLTuning = SKLTuning;
- list<SubtargetFeature> ADLFeatures =
- !listconcat(SKLFeatures, ADLAdditionalFeatures);
-
+ !listconcat(ICLFeatures, TGLAdditionalFeatures );
+
+ //Sapphirerapids
+ list<SubtargetFeature> SPRAdditionalFeatures = [FeatureAMXTILE,
+ FeatureAMXINT8,
+ FeatureAMXBF16,
+ FeatureBF16,
+ FeatureSERIALIZE,
+ FeatureCLDEMOTE,
+ FeatureWAITPKG,
+ FeaturePTWRITE,
+ FeatureAVXVNNI,
+ FeatureTSXLDTRK,
+ FeatureENQCMD,
+ FeatureSHSTK,
+ FeatureVP2INTERSECT,
+ FeatureMOVDIRI,
+ FeatureMOVDIR64B,
+ FeatureUINTR];
+ list<SubtargetFeature> SPRTuning = ICXTuning;
+ list<SubtargetFeature> SPRFeatures =
+ !listconcat(ICXFeatures, SPRAdditionalFeatures);
+
+ // Alderlake
+ list<SubtargetFeature> ADLAdditionalFeatures = [FeatureAVXVNNI,
+ FeatureCLDEMOTE,
+ FeatureHRESET,
+ FeaturePTWRITE,
+ FeatureSERIALIZE,
+ FeatureWAITPKG];
+ list<SubtargetFeature> ADLTuning = SKLTuning;
+ list<SubtargetFeature> ADLFeatures =
+ !listconcat(SKLFeatures, ADLAdditionalFeatures);
+
// Atom
- list<SubtargetFeature> AtomFeatures = [FeatureX87,
- FeatureCMPXCHG8B,
- FeatureCMOV,
- FeatureMMX,
- FeatureSSSE3,
- FeatureFXSR,
- FeatureNOPL,
- Feature64Bit,
- FeatureCMPXCHG16B,
- FeatureMOVBE,
- FeatureLAHFSAHF];
- list<SubtargetFeature> AtomTuning = [ProcIntelAtom,
- FeatureSlowUAMem16,
- FeatureLEAForSP,
- FeatureSlowDivide32,
- FeatureSlowDivide64,
- FeatureSlowTwoMemOps,
- FeatureLEAUsesAG,
- FeaturePadShortFunctions,
- FeatureInsertVZEROUPPER];
+ list<SubtargetFeature> AtomFeatures = [FeatureX87,
+ FeatureCMPXCHG8B,
+ FeatureCMOV,
+ FeatureMMX,
+ FeatureSSSE3,
+ FeatureFXSR,
+ FeatureNOPL,
+ Feature64Bit,
+ FeatureCMPXCHG16B,
+ FeatureMOVBE,
+ FeatureLAHFSAHF];
+ list<SubtargetFeature> AtomTuning = [ProcIntelAtom,
+ FeatureSlowUAMem16,
+ FeatureLEAForSP,
+ FeatureSlowDivide32,
+ FeatureSlowDivide64,
+ FeatureSlowTwoMemOps,
+ FeatureLEAUsesAG,
+ FeaturePadShortFunctions,
+ FeatureInsertVZEROUPPER];
// Silvermont
list<SubtargetFeature> SLMAdditionalFeatures = [FeatureSSE42,
@@ -823,17 +823,17 @@ def ProcessorFeatures {
FeaturePCLMUL,
FeaturePRFCHW,
FeatureRDRAND];
- list<SubtargetFeature> SLMTuning = [ProcIntelSLM,
- FeatureSlowTwoMemOps,
- FeatureSlowLEA,
- FeatureSlowIncDec,
- FeatureSlowDivide64,
- FeatureSlowPMULLD,
- FeatureFast7ByteNOP,
- FeaturePOPCNTFalseDeps,
- FeatureInsertVZEROUPPER];
+ list<SubtargetFeature> SLMTuning = [ProcIntelSLM,
+ FeatureSlowTwoMemOps,
+ FeatureSlowLEA,
+ FeatureSlowIncDec,
+ FeatureSlowDivide64,
+ FeatureSlowPMULLD,
+ FeatureFast7ByteNOP,
+ FeaturePOPCNTFalseDeps,
+ FeatureInsertVZEROUPPER];
list<SubtargetFeature> SLMFeatures =
- !listconcat(AtomFeatures, SLMAdditionalFeatures);
+ !listconcat(AtomFeatures, SLMAdditionalFeatures);
// Goldmont
list<SubtargetFeature> GLMAdditionalFeatures = [FeatureAES,
@@ -845,33 +845,33 @@ def ProcessorFeatures {
FeatureXSAVES,
FeatureCLFLUSHOPT,
FeatureFSGSBase];
- list<SubtargetFeature> GLMTuning = [FeatureUseGLMDivSqrtCosts,
- FeatureSlowTwoMemOps,
- FeatureSlowLEA,
- FeatureSlowIncDec,
- FeaturePOPCNTFalseDeps,
- FeatureInsertVZEROUPPER];
+ list<SubtargetFeature> GLMTuning = [FeatureUseGLMDivSqrtCosts,
+ FeatureSlowTwoMemOps,
+ FeatureSlowLEA,
+ FeatureSlowIncDec,
+ FeaturePOPCNTFalseDeps,
+ FeatureInsertVZEROUPPER];
list<SubtargetFeature> GLMFeatures =
- !listconcat(SLMFeatures, GLMAdditionalFeatures);
+ !listconcat(SLMFeatures, GLMAdditionalFeatures);
// Goldmont Plus
list<SubtargetFeature> GLPAdditionalFeatures = [FeaturePTWRITE,
FeatureRDPID,
FeatureSGX];
- list<SubtargetFeature> GLPTuning = [FeatureUseGLMDivSqrtCosts,
- FeatureSlowTwoMemOps,
- FeatureSlowLEA,
- FeatureSlowIncDec,
- FeatureInsertVZEROUPPER];
+ list<SubtargetFeature> GLPTuning = [FeatureUseGLMDivSqrtCosts,
+ FeatureSlowTwoMemOps,
+ FeatureSlowLEA,
+ FeatureSlowIncDec,
+ FeatureInsertVZEROUPPER];
list<SubtargetFeature> GLPFeatures =
- !listconcat(GLMFeatures, GLPAdditionalFeatures);
+ !listconcat(GLMFeatures, GLPAdditionalFeatures);
// Tremont
list<SubtargetFeature> TRMAdditionalFeatures = [FeatureCLWB,
FeatureGFNI];
- list<SubtargetFeature> TRMTuning = GLPTuning;
+ list<SubtargetFeature> TRMTuning = GLPTuning;
list<SubtargetFeature> TRMFeatures =
- !listconcat(GLPFeatures, TRMAdditionalFeatures);
+ !listconcat(GLPFeatures, TRMAdditionalFeatures);
// Knights Landing
list<SubtargetFeature> KNLFeatures = [FeatureX87,
@@ -903,56 +903,56 @@ def ProcessorFeatures {
FeatureBMI,
FeatureBMI2,
FeatureFMA,
- FeaturePRFCHW];
- list<SubtargetFeature> KNLTuning = [FeatureSlowDivide64,
- FeatureSlow3OpsLEA,
- FeatureSlowIncDec,
- FeatureSlowTwoMemOps,
- FeaturePreferMaskRegisters,
- FeatureHasFastGather,
- FeatureSlowPMADDWD];
+ FeaturePRFCHW];
+ list<SubtargetFeature> KNLTuning = [FeatureSlowDivide64,
+ FeatureSlow3OpsLEA,
+ FeatureSlowIncDec,
+ FeatureSlowTwoMemOps,
+ FeaturePreferMaskRegisters,
+ FeatureHasFastGather,
+ FeatureSlowPMADDWD];
// TODO Add AVX5124FMAPS/AVX5124VNNIW features
list<SubtargetFeature> KNMFeatures =
!listconcat(KNLFeatures, [FeatureVPOPCNTDQ]);
// Barcelona
- list<SubtargetFeature> BarcelonaFeatures = [FeatureX87,
- FeatureCMPXCHG8B,
- FeatureSSE4A,
- Feature3DNowA,
- FeatureFXSR,
- FeatureNOPL,
- FeatureCMPXCHG16B,
- FeaturePRFCHW,
- FeatureLZCNT,
- FeaturePOPCNT,
- FeatureLAHFSAHF,
- FeatureCMOV,
- Feature64Bit];
- list<SubtargetFeature> BarcelonaTuning = [FeatureFastScalarShiftMasks,
- FeatureSlowSHLD,
- FeatureInsertVZEROUPPER];
+ list<SubtargetFeature> BarcelonaFeatures = [FeatureX87,
+ FeatureCMPXCHG8B,
+ FeatureSSE4A,
+ Feature3DNowA,
+ FeatureFXSR,
+ FeatureNOPL,
+ FeatureCMPXCHG16B,
+ FeaturePRFCHW,
+ FeatureLZCNT,
+ FeaturePOPCNT,
+ FeatureLAHFSAHF,
+ FeatureCMOV,
+ Feature64Bit];
+ list<SubtargetFeature> BarcelonaTuning = [FeatureFastScalarShiftMasks,
+ FeatureSlowSHLD,
+ FeatureInsertVZEROUPPER];
// Bobcat
- list<SubtargetFeature> BtVer1Features = [FeatureX87,
- FeatureCMPXCHG8B,
- FeatureCMOV,
- FeatureMMX,
- FeatureSSSE3,
- FeatureSSE4A,
- FeatureFXSR,
- FeatureNOPL,
- Feature64Bit,
- FeatureCMPXCHG16B,
- FeaturePRFCHW,
- FeatureLZCNT,
- FeaturePOPCNT,
- FeatureLAHFSAHF];
- list<SubtargetFeature> BtVer1Tuning = [FeatureFast15ByteNOP,
- FeatureFastScalarShiftMasks,
- FeatureFastVectorShiftMasks,
- FeatureSlowSHLD,
- FeatureInsertVZEROUPPER];
+ list<SubtargetFeature> BtVer1Features = [FeatureX87,
+ FeatureCMPXCHG8B,
+ FeatureCMOV,
+ FeatureMMX,
+ FeatureSSSE3,
+ FeatureSSE4A,
+ FeatureFXSR,
+ FeatureNOPL,
+ Feature64Bit,
+ FeatureCMPXCHG16B,
+ FeaturePRFCHW,
+ FeatureLZCNT,
+ FeaturePOPCNT,
+ FeatureLAHFSAHF];
+ list<SubtargetFeature> BtVer1Tuning = [FeatureFast15ByteNOP,
+ FeatureFastScalarShiftMasks,
+ FeatureFastVectorShiftMasks,
+ FeatureSlowSHLD,
+ FeatureInsertVZEROUPPER];
// Jaguar
list<SubtargetFeature> BtVer2AdditionalFeatures = [FeatureAVX,
@@ -963,39 +963,39 @@ def ProcessorFeatures {
FeatureMOVBE,
FeatureXSAVE,
FeatureXSAVEOPT];
- list<SubtargetFeature> BtVer2Tuning = [FeatureFastLZCNT,
- FeatureFastBEXTR,
- FeatureFastHorizontalOps,
- FeatureFast15ByteNOP,
- FeatureFastScalarShiftMasks,
- FeatureFastVectorShiftMasks,
- FeatureSlowSHLD];
+ list<SubtargetFeature> BtVer2Tuning = [FeatureFastLZCNT,
+ FeatureFastBEXTR,
+ FeatureFastHorizontalOps,
+ FeatureFast15ByteNOP,
+ FeatureFastScalarShiftMasks,
+ FeatureFastVectorShiftMasks,
+ FeatureSlowSHLD];
list<SubtargetFeature> BtVer2Features =
- !listconcat(BtVer1Features, BtVer2AdditionalFeatures);
+ !listconcat(BtVer1Features, BtVer2AdditionalFeatures);
// Bulldozer
- list<SubtargetFeature> BdVer1Features = [FeatureX87,
- FeatureCMPXCHG8B,
- FeatureCMOV,
- FeatureXOP,
- Feature64Bit,
- FeatureCMPXCHG16B,
- FeatureAES,
- FeaturePRFCHW,
- FeaturePCLMUL,
- FeatureMMX,
- FeatureFXSR,
- FeatureNOPL,
- FeatureLZCNT,
- FeaturePOPCNT,
- FeatureXSAVE,
- FeatureLWP,
- FeatureLAHFSAHF];
- list<SubtargetFeature> BdVer1Tuning = [FeatureSlowSHLD,
- FeatureFast11ByteNOP,
- FeatureFastScalarShiftMasks,
- FeatureBranchFusion,
- FeatureInsertVZEROUPPER];
+ list<SubtargetFeature> BdVer1Features = [FeatureX87,
+ FeatureCMPXCHG8B,
+ FeatureCMOV,
+ FeatureXOP,
+ Feature64Bit,
+ FeatureCMPXCHG16B,
+ FeatureAES,
+ FeaturePRFCHW,
+ FeaturePCLMUL,
+ FeatureMMX,
+ FeatureFXSR,
+ FeatureNOPL,
+ FeatureLZCNT,
+ FeaturePOPCNT,
+ FeatureXSAVE,
+ FeatureLWP,
+ FeatureLAHFSAHF];
+ list<SubtargetFeature> BdVer1Tuning = [FeatureSlowSHLD,
+ FeatureFast11ByteNOP,
+ FeatureFastScalarShiftMasks,
+ FeatureBranchFusion,
+ FeatureInsertVZEROUPPER];
// PileDriver
list<SubtargetFeature> BdVer2AdditionalFeatures = [FeatureF16C,
@@ -1003,16 +1003,16 @@ def ProcessorFeatures {
FeatureTBM,
FeatureFMA,
FeatureFastBEXTR];
- list<SubtargetFeature> BdVer2Tuning = BdVer1Tuning;
- list<SubtargetFeature> BdVer2Features =
- !listconcat(BdVer1Features, BdVer2AdditionalFeatures);
+ list<SubtargetFeature> BdVer2Tuning = BdVer1Tuning;
+ list<SubtargetFeature> BdVer2Features =
+ !listconcat(BdVer1Features, BdVer2AdditionalFeatures);
// Steamroller
list<SubtargetFeature> BdVer3AdditionalFeatures = [FeatureXSAVEOPT,
FeatureFSGSBase];
- list<SubtargetFeature> BdVer3Tuning = BdVer2Tuning;
- list<SubtargetFeature> BdVer3Features =
- !listconcat(BdVer2Features, BdVer3AdditionalFeatures);
+ list<SubtargetFeature> BdVer3Tuning = BdVer2Tuning;
+ list<SubtargetFeature> BdVer3Features =
+ !listconcat(BdVer2Features, BdVer3AdditionalFeatures);
// Excavator
list<SubtargetFeature> BdVer4AdditionalFeatures = [FeatureAVX2,
@@ -1020,9 +1020,9 @@ def ProcessorFeatures {
FeatureMOVBE,
FeatureRDRAND,
FeatureMWAITX];
- list<SubtargetFeature> BdVer4Tuning = BdVer3Tuning;
- list<SubtargetFeature> BdVer4Features =
- !listconcat(BdVer3Features, BdVer4AdditionalFeatures);
+ list<SubtargetFeature> BdVer4Tuning = BdVer3Tuning;
+ list<SubtargetFeature> BdVer4Features =
+ !listconcat(BdVer3Features, BdVer4AdditionalFeatures);
// AMD Zen Processors common ISAs
@@ -1058,80 +1058,80 @@ def ProcessorFeatures {
FeatureXSAVEC,
FeatureXSAVEOPT,
FeatureXSAVES];
- list<SubtargetFeature> ZNTuning = [FeatureFastLZCNT,
- FeatureFastBEXTR,
- FeatureFast15ByteNOP,
- FeatureBranchFusion,
- FeatureFastScalarShiftMasks,
- FeatureSlowSHLD,
- FeatureInsertVZEROUPPER];
+ list<SubtargetFeature> ZNTuning = [FeatureFastLZCNT,
+ FeatureFastBEXTR,
+ FeatureFast15ByteNOP,
+ FeatureBranchFusion,
+ FeatureFastScalarShiftMasks,
+ FeatureSlowSHLD,
+ FeatureInsertVZEROUPPER];
list<SubtargetFeature> ZN2AdditionalFeatures = [FeatureCLWB,
FeatureRDPID,
FeatureWBNOINVD];
- list<SubtargetFeature> ZN2Tuning = ZNTuning;
+ list<SubtargetFeature> ZN2Tuning = ZNTuning;
list<SubtargetFeature> ZN2Features =
!listconcat(ZNFeatures, ZN2AdditionalFeatures);
- list<SubtargetFeature> ZN3AdditionalFeatures = [FeatureFSRM,
- FeatureINVPCID,
- FeaturePKU,
- FeatureVAES,
- FeatureVPCLMULQDQ];
- list<SubtargetFeature> ZN3Tuning = ZNTuning;
- list<SubtargetFeature> ZN3Features =
- !listconcat(ZN2Features, ZN3AdditionalFeatures);
+ list<SubtargetFeature> ZN3AdditionalFeatures = [FeatureFSRM,
+ FeatureINVPCID,
+ FeaturePKU,
+ FeatureVAES,
+ FeatureVPCLMULQDQ];
+ list<SubtargetFeature> ZN3Tuning = ZNTuning;
+ list<SubtargetFeature> ZN3Features =
+ !listconcat(ZN2Features, ZN3AdditionalFeatures);
}
//===----------------------------------------------------------------------===//
// X86 processors supported.
//===----------------------------------------------------------------------===//
-class Proc<string Name, list<SubtargetFeature> Features,
- list<SubtargetFeature> TuneFeatures>
- : ProcessorModel<Name, GenericModel, Features, TuneFeatures>;
+class Proc<string Name, list<SubtargetFeature> Features,
+ list<SubtargetFeature> TuneFeatures>
+ : ProcessorModel<Name, GenericModel, Features, TuneFeatures>;
+
+class ProcModel<string Name, SchedMachineModel Model,
+ list<SubtargetFeature> Features,
+ list<SubtargetFeature> TuneFeatures>
+ : ProcessorModel<Name, Model, Features, TuneFeatures>;
-class ProcModel<string Name, SchedMachineModel Model,
- list<SubtargetFeature> Features,
- list<SubtargetFeature> TuneFeatures>
- : ProcessorModel<Name, Model, Features, TuneFeatures>;
-
// NOTE: CMPXCHG8B is here for legacy compatibility so that it is only disabled
// if i386/i486 is specifically requested.
-// NOTE: 64Bit is here as "generic" is the default llc CPU. The X86Subtarget
-// constructor checks that any CPU used in 64-bit mode has Feature64Bit enabled.
-// It has no effect on code generation.
-def : ProcModel<"generic", SandyBridgeModel,
- [FeatureX87, FeatureCMPXCHG8B, Feature64Bit],
- [FeatureSlow3OpsLEA,
- FeatureSlowDivide64,
- FeatureSlowIncDec,
- FeatureMacroFusion,
- FeatureInsertVZEROUPPER]>;
-
-def : Proc<"i386", [FeatureX87],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
-def : Proc<"i486", [FeatureX87],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
-def : Proc<"i586", [FeatureX87, FeatureCMPXCHG8B],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
-def : Proc<"pentium", [FeatureX87, FeatureCMPXCHG8B],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
-def : Proc<"pentium-mmx", [FeatureX87, FeatureCMPXCHG8B, FeatureMMX],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
-
-def : Proc<"i686", [FeatureX87, FeatureCMPXCHG8B, FeatureCMOV],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
-def : Proc<"pentiumpro", [FeatureX87, FeatureCMPXCHG8B, FeatureCMOV,
- FeatureNOPL],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
-
-def : Proc<"pentium2", [FeatureX87, FeatureCMPXCHG8B, FeatureMMX, FeatureCMOV,
- FeatureFXSR, FeatureNOPL],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
-
+// NOTE: 64Bit is here as "generic" is the default llc CPU. The X86Subtarget
+// constructor checks that any CPU used in 64-bit mode has Feature64Bit enabled.
+// It has no effect on code generation.
+def : ProcModel<"generic", SandyBridgeModel,
+ [FeatureX87, FeatureCMPXCHG8B, Feature64Bit],
+ [FeatureSlow3OpsLEA,
+ FeatureSlowDivide64,
+ FeatureSlowIncDec,
+ FeatureMacroFusion,
+ FeatureInsertVZEROUPPER]>;
+
+def : Proc<"i386", [FeatureX87],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+def : Proc<"i486", [FeatureX87],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+def : Proc<"i586", [FeatureX87, FeatureCMPXCHG8B],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+def : Proc<"pentium", [FeatureX87, FeatureCMPXCHG8B],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+def : Proc<"pentium-mmx", [FeatureX87, FeatureCMPXCHG8B, FeatureMMX],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+
+def : Proc<"i686", [FeatureX87, FeatureCMPXCHG8B, FeatureCMOV],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+def : Proc<"pentiumpro", [FeatureX87, FeatureCMPXCHG8B, FeatureCMOV,
+ FeatureNOPL],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+
+def : Proc<"pentium2", [FeatureX87, FeatureCMPXCHG8B, FeatureMMX, FeatureCMOV,
+ FeatureFXSR, FeatureNOPL],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+
foreach P = ["pentium3", "pentium3m"] in {
- def : Proc<P, [FeatureX87, FeatureCMPXCHG8B, FeatureMMX,
- FeatureSSE1, FeatureFXSR, FeatureNOPL, FeatureCMOV],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+ def : Proc<P, [FeatureX87, FeatureCMPXCHG8B, FeatureMMX,
+ FeatureSSE1, FeatureFXSR, FeatureNOPL, FeatureCMOV],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
}
// Enable the PostRAScheduler for SSE2 and SSE3 class cpus.
@@ -1144,34 +1144,34 @@ foreach P = ["pentium3", "pentium3m"] in {
// measure to avoid performance surprises, in case clang's default cpu
// changes slightly.
-def : ProcModel<"pentium-m", GenericPostRAModel,
- [FeatureX87, FeatureCMPXCHG8B, FeatureMMX, FeatureSSE2,
- FeatureFXSR, FeatureNOPL, FeatureCMOV],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+def : ProcModel<"pentium-m", GenericPostRAModel,
+ [FeatureX87, FeatureCMPXCHG8B, FeatureMMX, FeatureSSE2,
+ FeatureFXSR, FeatureNOPL, FeatureCMOV],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
foreach P = ["pentium4", "pentium4m"] in {
- def : ProcModel<P, GenericPostRAModel,
- [FeatureX87, FeatureCMPXCHG8B, FeatureMMX, FeatureSSE2,
- FeatureFXSR, FeatureNOPL, FeatureCMOV],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+ def : ProcModel<P, GenericPostRAModel,
+ [FeatureX87, FeatureCMPXCHG8B, FeatureMMX, FeatureSSE2,
+ FeatureFXSR, FeatureNOPL, FeatureCMOV],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
}
// Intel Quark.
-def : Proc<"lakemont", [FeatureCMPXCHG8B],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+def : Proc<"lakemont", [FeatureCMPXCHG8B],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
// Intel Core Duo.
-def : ProcModel<"yonah", SandyBridgeModel,
- [FeatureX87, FeatureCMPXCHG8B, FeatureMMX, FeatureSSE3,
- FeatureFXSR, FeatureNOPL, FeatureCMOV],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+def : ProcModel<"yonah", SandyBridgeModel,
+ [FeatureX87, FeatureCMPXCHG8B, FeatureMMX, FeatureSSE3,
+ FeatureFXSR, FeatureNOPL, FeatureCMOV],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
// NetBurst.
-def : ProcModel<"prescott", GenericPostRAModel,
- [FeatureX87, FeatureCMPXCHG8B, FeatureMMX, FeatureSSE3,
- FeatureFXSR, FeatureNOPL, FeatureCMOV],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
-def : ProcModel<"nocona", GenericPostRAModel, [
+def : ProcModel<"prescott", GenericPostRAModel,
+ [FeatureX87, FeatureCMPXCHG8B, FeatureMMX, FeatureSSE3,
+ FeatureFXSR, FeatureNOPL, FeatureCMOV],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+def : ProcModel<"nocona", GenericPostRAModel, [
FeatureX87,
FeatureCMPXCHG8B,
FeatureCMOV,
@@ -1181,14 +1181,14 @@ def : ProcModel<"nocona", GenericPostRAModel, [
FeatureNOPL,
Feature64Bit,
FeatureCMPXCHG16B,
-],
-[
- FeatureSlowUAMem16,
+],
+[
+ FeatureSlowUAMem16,
FeatureInsertVZEROUPPER
]>;
// Intel Core 2 Solo/Duo.
-def : ProcModel<"core2", SandyBridgeModel, [
+def : ProcModel<"core2", SandyBridgeModel, [
FeatureX87,
FeatureCMPXCHG8B,
FeatureCMOV,
@@ -1198,14 +1198,14 @@ def : ProcModel<"core2", SandyBridgeModel, [
FeatureNOPL,
Feature64Bit,
FeatureCMPXCHG16B,
- FeatureLAHFSAHF
-],
-[
+ FeatureLAHFSAHF
+],
+[
FeatureMacroFusion,
- FeatureSlowUAMem16,
+ FeatureSlowUAMem16,
FeatureInsertVZEROUPPER
]>;
-def : ProcModel<"penryn", SandyBridgeModel, [
+def : ProcModel<"penryn", SandyBridgeModel, [
FeatureX87,
FeatureCMPXCHG8B,
FeatureCMOV,
@@ -1215,171 +1215,171 @@ def : ProcModel<"penryn", SandyBridgeModel, [
FeatureNOPL,
Feature64Bit,
FeatureCMPXCHG16B,
- FeatureLAHFSAHF
-],
-[
+ FeatureLAHFSAHF
+],
+[
FeatureMacroFusion,
- FeatureSlowUAMem16,
+ FeatureSlowUAMem16,
FeatureInsertVZEROUPPER
]>;
// Atom CPUs.
foreach P = ["bonnell", "atom"] in {
- def : ProcModel<P, AtomModel, ProcessorFeatures.AtomFeatures,
- ProcessorFeatures.AtomTuning>;
+ def : ProcModel<P, AtomModel, ProcessorFeatures.AtomFeatures,
+ ProcessorFeatures.AtomTuning>;
}
foreach P = ["silvermont", "slm"] in {
- def : ProcModel<P, SLMModel, ProcessorFeatures.SLMFeatures,
- ProcessorFeatures.SLMTuning>;
+ def : ProcModel<P, SLMModel, ProcessorFeatures.SLMFeatures,
+ ProcessorFeatures.SLMTuning>;
}
-def : ProcModel<"goldmont", SLMModel, ProcessorFeatures.GLMFeatures,
- ProcessorFeatures.GLMTuning>;
-def : ProcModel<"goldmont-plus", SLMModel, ProcessorFeatures.GLPFeatures,
- ProcessorFeatures.GLPTuning>;
-def : ProcModel<"tremont", SLMModel, ProcessorFeatures.TRMFeatures,
- ProcessorFeatures.TRMTuning>;
+def : ProcModel<"goldmont", SLMModel, ProcessorFeatures.GLMFeatures,
+ ProcessorFeatures.GLMTuning>;
+def : ProcModel<"goldmont-plus", SLMModel, ProcessorFeatures.GLPFeatures,
+ ProcessorFeatures.GLPTuning>;
+def : ProcModel<"tremont", SLMModel, ProcessorFeatures.TRMFeatures,
+ ProcessorFeatures.TRMTuning>;
// "Arrandale" along with corei3 and corei5
foreach P = ["nehalem", "corei7"] in {
- def : ProcModel<P, SandyBridgeModel, ProcessorFeatures.NHMFeatures,
- ProcessorFeatures.NHMTuning>;
+ def : ProcModel<P, SandyBridgeModel, ProcessorFeatures.NHMFeatures,
+ ProcessorFeatures.NHMTuning>;
}
// Westmere is the corei3/i5/i7 path from nehalem to sandybridge
-def : ProcModel<"westmere", SandyBridgeModel, ProcessorFeatures.WSMFeatures,
- ProcessorFeatures.WSMTuning>;
+def : ProcModel<"westmere", SandyBridgeModel, ProcessorFeatures.WSMFeatures,
+ ProcessorFeatures.WSMTuning>;
foreach P = ["sandybridge", "corei7-avx"] in {
- def : ProcModel<P, SandyBridgeModel, ProcessorFeatures.SNBFeatures,
- ProcessorFeatures.SNBTuning>;
+ def : ProcModel<P, SandyBridgeModel, ProcessorFeatures.SNBFeatures,
+ ProcessorFeatures.SNBTuning>;
}
foreach P = ["ivybridge", "core-avx-i"] in {
- def : ProcModel<P, SandyBridgeModel, ProcessorFeatures.IVBFeatures,
- ProcessorFeatures.IVBTuning>;
+ def : ProcModel<P, SandyBridgeModel, ProcessorFeatures.IVBFeatures,
+ ProcessorFeatures.IVBTuning>;
}
foreach P = ["haswell", "core-avx2"] in {
- def : ProcModel<P, HaswellModel, ProcessorFeatures.HSWFeatures,
- ProcessorFeatures.HSWTuning>;
+ def : ProcModel<P, HaswellModel, ProcessorFeatures.HSWFeatures,
+ ProcessorFeatures.HSWTuning>;
}
-def : ProcModel<"broadwell", BroadwellModel, ProcessorFeatures.BDWFeatures,
- ProcessorFeatures.BDWTuning>;
+def : ProcModel<"broadwell", BroadwellModel, ProcessorFeatures.BDWFeatures,
+ ProcessorFeatures.BDWTuning>;
-def : ProcModel<"skylake", SkylakeClientModel, ProcessorFeatures.SKLFeatures,
- ProcessorFeatures.SKLTuning>;
+def : ProcModel<"skylake", SkylakeClientModel, ProcessorFeatures.SKLFeatures,
+ ProcessorFeatures.SKLTuning>;
// FIXME: define KNL scheduler model
-def : ProcModel<"knl", HaswellModel, ProcessorFeatures.KNLFeatures,
- ProcessorFeatures.KNLTuning>;
-def : ProcModel<"knm", HaswellModel, ProcessorFeatures.KNMFeatures,
- ProcessorFeatures.KNLTuning>;
+def : ProcModel<"knl", HaswellModel, ProcessorFeatures.KNLFeatures,
+ ProcessorFeatures.KNLTuning>;
+def : ProcModel<"knm", HaswellModel, ProcessorFeatures.KNMFeatures,
+ ProcessorFeatures.KNLTuning>;
foreach P = ["skylake-avx512", "skx"] in {
- def : ProcModel<P, SkylakeServerModel, ProcessorFeatures.SKXFeatures,
- ProcessorFeatures.SKXTuning>;
+ def : ProcModel<P, SkylakeServerModel, ProcessorFeatures.SKXFeatures,
+ ProcessorFeatures.SKXTuning>;
}
-def : ProcModel<"cascadelake", SkylakeServerModel,
- ProcessorFeatures.CLXFeatures, ProcessorFeatures.CLXTuning>;
-def : ProcModel<"cooperlake", SkylakeServerModel,
- ProcessorFeatures.CPXFeatures, ProcessorFeatures.CPXTuning>;
-def : ProcModel<"cannonlake", SkylakeServerModel,
- ProcessorFeatures.CNLFeatures, ProcessorFeatures.CNLTuning>;
-def : ProcModel<"icelake-client", SkylakeServerModel,
- ProcessorFeatures.ICLFeatures, ProcessorFeatures.ICLTuning>;
-def : ProcModel<"icelake-server", SkylakeServerModel,
- ProcessorFeatures.ICXFeatures, ProcessorFeatures.ICXTuning>;
-def : ProcModel<"tigerlake", SkylakeServerModel,
- ProcessorFeatures.TGLFeatures, ProcessorFeatures.TGLTuning>;
-def : ProcModel<"sapphirerapids", SkylakeServerModel,
- ProcessorFeatures.SPRFeatures, ProcessorFeatures.SPRTuning>;
-def : ProcModel<"alderlake", SkylakeClientModel,
- ProcessorFeatures.ADLFeatures, ProcessorFeatures.ADLTuning>;
+def : ProcModel<"cascadelake", SkylakeServerModel,
+ ProcessorFeatures.CLXFeatures, ProcessorFeatures.CLXTuning>;
+def : ProcModel<"cooperlake", SkylakeServerModel,
+ ProcessorFeatures.CPXFeatures, ProcessorFeatures.CPXTuning>;
+def : ProcModel<"cannonlake", SkylakeServerModel,
+ ProcessorFeatures.CNLFeatures, ProcessorFeatures.CNLTuning>;
+def : ProcModel<"icelake-client", SkylakeServerModel,
+ ProcessorFeatures.ICLFeatures, ProcessorFeatures.ICLTuning>;
+def : ProcModel<"icelake-server", SkylakeServerModel,
+ ProcessorFeatures.ICXFeatures, ProcessorFeatures.ICXTuning>;
+def : ProcModel<"tigerlake", SkylakeServerModel,
+ ProcessorFeatures.TGLFeatures, ProcessorFeatures.TGLTuning>;
+def : ProcModel<"sapphirerapids", SkylakeServerModel,
+ ProcessorFeatures.SPRFeatures, ProcessorFeatures.SPRTuning>;
+def : ProcModel<"alderlake", SkylakeClientModel,
+ ProcessorFeatures.ADLFeatures, ProcessorFeatures.ADLTuning>;
// AMD CPUs.
-def : Proc<"k6", [FeatureX87, FeatureCMPXCHG8B, FeatureMMX],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
-def : Proc<"k6-2", [FeatureX87, FeatureCMPXCHG8B, Feature3DNow],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
-def : Proc<"k6-3", [FeatureX87, FeatureCMPXCHG8B, Feature3DNow],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+def : Proc<"k6", [FeatureX87, FeatureCMPXCHG8B, FeatureMMX],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+def : Proc<"k6-2", [FeatureX87, FeatureCMPXCHG8B, Feature3DNow],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+def : Proc<"k6-3", [FeatureX87, FeatureCMPXCHG8B, Feature3DNow],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
foreach P = ["athlon", "athlon-tbird"] in {
- def : Proc<P, [FeatureX87, FeatureCMPXCHG8B, FeatureCMOV, Feature3DNowA,
- FeatureNOPL],
- [FeatureSlowSHLD, FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+ def : Proc<P, [FeatureX87, FeatureCMPXCHG8B, FeatureCMOV, Feature3DNowA,
+ FeatureNOPL],
+ [FeatureSlowSHLD, FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
}
foreach P = ["athlon-4", "athlon-xp", "athlon-mp"] in {
- def : Proc<P, [FeatureX87, FeatureCMPXCHG8B, FeatureCMOV,
- FeatureSSE1, Feature3DNowA, FeatureFXSR, FeatureNOPL],
- [FeatureSlowSHLD, FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+ def : Proc<P, [FeatureX87, FeatureCMPXCHG8B, FeatureCMOV,
+ FeatureSSE1, Feature3DNowA, FeatureFXSR, FeatureNOPL],
+ [FeatureSlowSHLD, FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
}
foreach P = ["k8", "opteron", "athlon64", "athlon-fx"] in {
- def : Proc<P, [FeatureX87, FeatureCMPXCHG8B, FeatureSSE2, Feature3DNowA,
- FeatureFXSR, FeatureNOPL, Feature64Bit, FeatureCMOV],
- [FeatureFastScalarShiftMasks, FeatureSlowSHLD, FeatureSlowUAMem16,
- FeatureInsertVZEROUPPER]>;
+ def : Proc<P, [FeatureX87, FeatureCMPXCHG8B, FeatureSSE2, Feature3DNowA,
+ FeatureFXSR, FeatureNOPL, Feature64Bit, FeatureCMOV],
+ [FeatureFastScalarShiftMasks, FeatureSlowSHLD, FeatureSlowUAMem16,
+ FeatureInsertVZEROUPPER]>;
}
foreach P = ["k8-sse3", "opteron-sse3", "athlon64-sse3"] in {
- def : Proc<P, [FeatureX87, FeatureCMPXCHG8B, FeatureSSE3, Feature3DNowA,
- FeatureFXSR, FeatureNOPL, FeatureCMPXCHG16B, FeatureCMOV,
- Feature64Bit],
- [FeatureFastScalarShiftMasks, FeatureSlowSHLD, FeatureSlowUAMem16,
- FeatureInsertVZEROUPPER]>;
+ def : Proc<P, [FeatureX87, FeatureCMPXCHG8B, FeatureSSE3, Feature3DNowA,
+ FeatureFXSR, FeatureNOPL, FeatureCMPXCHG16B, FeatureCMOV,
+ Feature64Bit],
+ [FeatureFastScalarShiftMasks, FeatureSlowSHLD, FeatureSlowUAMem16,
+ FeatureInsertVZEROUPPER]>;
}
foreach P = ["amdfam10", "barcelona"] in {
- def : Proc<P, ProcessorFeatures.BarcelonaFeatures,
- ProcessorFeatures.BarcelonaTuning>;
+ def : Proc<P, ProcessorFeatures.BarcelonaFeatures,
+ ProcessorFeatures.BarcelonaTuning>;
}
// Bobcat
-def : Proc<"btver1", ProcessorFeatures.BtVer1Features,
- ProcessorFeatures.BtVer1Tuning>;
+def : Proc<"btver1", ProcessorFeatures.BtVer1Features,
+ ProcessorFeatures.BtVer1Tuning>;
// Jaguar
-def : ProcModel<"btver2", BtVer2Model, ProcessorFeatures.BtVer2Features,
- ProcessorFeatures.BtVer2Tuning>;
+def : ProcModel<"btver2", BtVer2Model, ProcessorFeatures.BtVer2Features,
+ ProcessorFeatures.BtVer2Tuning>;
// Bulldozer
-def : ProcModel<"bdver1", BdVer2Model, ProcessorFeatures.BdVer1Features,
- ProcessorFeatures.BdVer1Tuning>;
+def : ProcModel<"bdver1", BdVer2Model, ProcessorFeatures.BdVer1Features,
+ ProcessorFeatures.BdVer1Tuning>;
// Piledriver
-def : ProcModel<"bdver2", BdVer2Model, ProcessorFeatures.BdVer2Features,
- ProcessorFeatures.BdVer2Tuning>;
+def : ProcModel<"bdver2", BdVer2Model, ProcessorFeatures.BdVer2Features,
+ ProcessorFeatures.BdVer2Tuning>;
// Steamroller
-def : Proc<"bdver3", ProcessorFeatures.BdVer3Features,
- ProcessorFeatures.BdVer3Tuning>;
+def : Proc<"bdver3", ProcessorFeatures.BdVer3Features,
+ ProcessorFeatures.BdVer3Tuning>;
// Excavator
-def : Proc<"bdver4", ProcessorFeatures.BdVer4Features,
- ProcessorFeatures.BdVer4Tuning>;
-
-def : ProcModel<"znver1", Znver1Model, ProcessorFeatures.ZNFeatures,
- ProcessorFeatures.ZNTuning>;
-def : ProcModel<"znver2", Znver2Model, ProcessorFeatures.ZN2Features,
- ProcessorFeatures.ZN2Tuning>;
-def : ProcModel<"znver3", Znver2Model, ProcessorFeatures.ZN3Features,
- ProcessorFeatures.ZN3Tuning>;
-
-def : Proc<"geode", [FeatureX87, FeatureCMPXCHG8B, Feature3DNowA],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
-
-def : Proc<"winchip-c6", [FeatureX87, FeatureMMX],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
-def : Proc<"winchip2", [FeatureX87, Feature3DNow],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
-def : Proc<"c3", [FeatureX87, Feature3DNow],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
-def : Proc<"c3-2", [FeatureX87, FeatureCMPXCHG8B, FeatureMMX,
- FeatureSSE1, FeatureFXSR, FeatureCMOV],
- [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+def : Proc<"bdver4", ProcessorFeatures.BdVer4Features,
+ ProcessorFeatures.BdVer4Tuning>;
+
+def : ProcModel<"znver1", Znver1Model, ProcessorFeatures.ZNFeatures,
+ ProcessorFeatures.ZNTuning>;
+def : ProcModel<"znver2", Znver2Model, ProcessorFeatures.ZN2Features,
+ ProcessorFeatures.ZN2Tuning>;
+def : ProcModel<"znver3", Znver2Model, ProcessorFeatures.ZN3Features,
+ ProcessorFeatures.ZN3Tuning>;
+
+def : Proc<"geode", [FeatureX87, FeatureCMPXCHG8B, Feature3DNowA],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+
+def : Proc<"winchip-c6", [FeatureX87, FeatureMMX],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+def : Proc<"winchip2", [FeatureX87, Feature3DNow],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+def : Proc<"c3", [FeatureX87, Feature3DNow],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
+def : Proc<"c3-2", [FeatureX87, FeatureCMPXCHG8B, FeatureMMX,
+ FeatureSSE1, FeatureFXSR, FeatureCMOV],
+ [FeatureSlowUAMem16, FeatureInsertVZEROUPPER]>;
// We also provide a generic 64-bit specific x86 processor model which tries to
// be good for modern chips without enabling instruction set encodings past the
@@ -1391,8 +1391,8 @@ def : Proc<"c3-2", [FeatureX87, FeatureCMPXCHG8B, FeatureMMX,
// covers a huge swath of x86 processors. If there are specific scheduling
// knobs which need to be tuned differently for AMD chips, we might consider
// forming a common base for them.
-def : ProcModel<"x86-64", SandyBridgeModel, ProcessorFeatures.X86_64V1Features,
-[
+def : ProcModel<"x86-64", SandyBridgeModel, ProcessorFeatures.X86_64V1Features,
+[
FeatureSlow3OpsLEA,
FeatureSlowDivide64,
FeatureSlowIncDec,
@@ -1400,16 +1400,16 @@ def : ProcModel<"x86-64", SandyBridgeModel, ProcessorFeatures.X86_64V1Features,
FeatureInsertVZEROUPPER
]>;
-// x86-64 micro-architecture levels.
-def : ProcModel<"x86-64-v2", SandyBridgeModel, ProcessorFeatures.X86_64V2Features,
- ProcessorFeatures.SNBTuning>;
-// Close to Haswell.
-def : ProcModel<"x86-64-v3", HaswellModel, ProcessorFeatures.X86_64V3Features,
- ProcessorFeatures.HSWTuning>;
-// Close to the AVX-512 level implemented by Xeon Scalable Processors.
-def : ProcModel<"x86-64-v4", HaswellModel, ProcessorFeatures.X86_64V4Features,
- ProcessorFeatures.SKXTuning>;
-
+// x86-64 micro-architecture levels.
+def : ProcModel<"x86-64-v2", SandyBridgeModel, ProcessorFeatures.X86_64V2Features,
+ ProcessorFeatures.SNBTuning>;
+// Close to Haswell.
+def : ProcModel<"x86-64-v3", HaswellModel, ProcessorFeatures.X86_64V3Features,
+ ProcessorFeatures.HSWTuning>;
+// Close to the AVX-512 level implemented by Xeon Scalable Processors.
+def : ProcModel<"x86-64-v4", HaswellModel, ProcessorFeatures.X86_64V4Features,
+ ProcessorFeatures.SKXTuning>;
+
//===----------------------------------------------------------------------===//
// Calling Conventions
//===----------------------------------------------------------------------===//
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86AsmPrinter.cpp b/contrib/libs/llvm12/lib/Target/X86/X86AsmPrinter.cpp
index 7086ee858b..2d434bda55 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86AsmPrinter.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86AsmPrinter.cpp
@@ -404,7 +404,7 @@ void X86AsmPrinter::PrintIntelMemReference(const MachineInstr *MI,
O << ']';
}
-static bool printAsmMRegister(const X86AsmPrinter &P, const MachineOperand &MO,
+static bool printAsmMRegister(const X86AsmPrinter &P, const MachineOperand &MO,
char Mode, raw_ostream &O) {
Register Reg = MO.getReg();
bool EmitPercent = MO.getParent()->getInlineAsmDialect() == InlineAsm::AD_ATT;
@@ -446,9 +446,9 @@ static bool printAsmMRegister(const X86AsmPrinter &P, const MachineOperand &MO,
return false;
}
-static bool printAsmVRegister(const MachineOperand &MO, char Mode,
- raw_ostream &O) {
- Register Reg = MO.getReg();
+static bool printAsmVRegister(const MachineOperand &MO, char Mode,
+ raw_ostream &O) {
+ Register Reg = MO.getReg();
bool EmitPercent = MO.getParent()->getInlineAsmDialect() == InlineAsm::AD_ATT;
unsigned Index;
@@ -560,7 +560,7 @@ bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
case 't': // Print V8SFmode register
case 'g': // Print V16SFmode register
if (MO.isReg())
- return printAsmVRegister(MO, ExtraCode[0], O);
+ return printAsmVRegister(MO, ExtraCode[0], O);
PrintOperand(MI, OpNo, O);
return false;
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86AsmPrinter.h b/contrib/libs/llvm12/lib/Target/X86/X86AsmPrinter.h
index fe0a4d551a..a3b74c8ee3 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86AsmPrinter.h
+++ b/contrib/libs/llvm12/lib/Target/X86/X86AsmPrinter.h
@@ -134,9 +134,9 @@ public:
}
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- const char *ExtraCode, raw_ostream &O) override;
+ const char *ExtraCode, raw_ostream &O) override;
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
- const char *ExtraCode, raw_ostream &O) override;
+ const char *ExtraCode, raw_ostream &O) override;
bool doInitialization(Module &M) override {
SMShadowTracker.reset(0);
@@ -145,7 +145,7 @@ public:
return AsmPrinter::doInitialization(M);
}
- bool runOnMachineFunction(MachineFunction &MF) override;
+ bool runOnMachineFunction(MachineFunction &MF) override;
void emitFunctionBodyStart() override;
void emitFunctionBodyEnd() override;
};
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86AvoidStoreForwardingBlocks.cpp b/contrib/libs/llvm12/lib/Target/X86/X86AvoidStoreForwardingBlocks.cpp
index f95e27173f..fdc65acffe 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86AvoidStoreForwardingBlocks.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86AvoidStoreForwardingBlocks.cpp
@@ -154,7 +154,7 @@ static bool isPotentialBlockedMemCpyLd(unsigned Opcode) {
return isXMMLoadOpcode(Opcode) || isYMMLoadOpcode(Opcode);
}
-static bool isPotentialBlockedMemCpyPair(unsigned LdOpcode, unsigned StOpcode) {
+static bool isPotentialBlockedMemCpyPair(unsigned LdOpcode, unsigned StOpcode) {
switch (LdOpcode) {
case X86::MOVUPSrm:
case X86::MOVAPSrm:
@@ -206,7 +206,7 @@ static bool isPotentialBlockedMemCpyPair(unsigned LdOpcode, unsigned StOpcode) {
}
}
-static bool isPotentialBlockingStoreInst(unsigned Opcode, unsigned LoadOpcode) {
+static bool isPotentialBlockingStoreInst(unsigned Opcode, unsigned LoadOpcode) {
bool PBlock = false;
PBlock |= Opcode == X86::MOV64mr || Opcode == X86::MOV64mi32 ||
Opcode == X86::MOV32mr || Opcode == X86::MOV32mi ||
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86CallFrameOptimization.cpp b/contrib/libs/llvm12/lib/Target/X86/X86CallFrameOptimization.cpp
index 46e18b6c46..fae4e688c8 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86CallFrameOptimization.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86CallFrameOptimization.cpp
@@ -105,7 +105,7 @@ private:
void adjustCallSequence(MachineFunction &MF, const CallContext &Context);
MachineInstr *canFoldIntoRegPush(MachineBasicBlock::iterator FrameSetup,
- Register Reg);
+ Register Reg);
enum InstClassification { Convert, Skip, Exit };
@@ -202,7 +202,7 @@ bool X86CallFrameOptimization::isProfitable(MachineFunction &MF,
Align StackAlign = TFL->getStackAlign();
int64_t Advantage = 0;
- for (const auto &CC : CallSeqVector) {
+ for (const auto &CC : CallSeqVector) {
// Call sites where no parameters are passed on the stack
// do not affect the cost, since there needs to be no
// stack adjustment.
@@ -265,7 +265,7 @@ bool X86CallFrameOptimization::runOnMachineFunction(MachineFunction &MF) {
if (!isProfitable(MF, CallSeqVector))
return false;
- for (const auto &CC : CallSeqVector) {
+ for (const auto &CC : CallSeqVector) {
if (CC.UsePush) {
adjustCallSequence(MF, CC);
Changed = true;
@@ -288,13 +288,13 @@ X86CallFrameOptimization::classifyInstruction(
case X86::AND16mi8:
case X86::AND32mi8:
case X86::AND64mi8: {
- const MachineOperand &ImmOp = MI->getOperand(X86::AddrNumOperands);
+ const MachineOperand &ImmOp = MI->getOperand(X86::AddrNumOperands);
return ImmOp.getImm() == 0 ? Convert : Exit;
}
case X86::OR16mi8:
case X86::OR32mi8:
case X86::OR64mi8: {
- const MachineOperand &ImmOp = MI->getOperand(X86::AddrNumOperands);
+ const MachineOperand &ImmOp = MI->getOperand(X86::AddrNumOperands);
return ImmOp.getImm() == -1 ? Convert : Exit;
}
case X86::MOV32mi:
@@ -336,7 +336,7 @@ X86CallFrameOptimization::classifyInstruction(
if (!MO.isReg())
continue;
Register Reg = MO.getReg();
- if (!Reg.isPhysical())
+ if (!Reg.isPhysical())
continue;
if (RegInfo.regsOverlap(Reg, RegInfo.getStackRegister()))
return Exit;
@@ -454,7 +454,7 @@ void X86CallFrameOptimization::collectCallInfo(MachineFunction &MF,
if (!MO.isReg())
continue;
Register Reg = MO.getReg();
- if (Reg.isPhysical())
+ if (Reg.isPhysical())
UsedRegs.insert(Reg);
}
}
@@ -506,7 +506,7 @@ void X86CallFrameOptimization::adjustCallSequence(MachineFunction &MF,
// replace uses.
for (int Idx = (Context.ExpectedDist >> Log2SlotSize) - 1; Idx >= 0; --Idx) {
MachineBasicBlock::iterator Store = *Context.ArgStoreVector[Idx];
- const MachineOperand &PushOp = Store->getOperand(X86::AddrNumOperands);
+ const MachineOperand &PushOp = Store->getOperand(X86::AddrNumOperands);
MachineBasicBlock::iterator Push = nullptr;
unsigned PushOpcode;
switch (Store->getOpcode()) {
@@ -563,7 +563,7 @@ void X86CallFrameOptimization::adjustCallSequence(MachineFunction &MF,
unsigned NumOps = DefMov->getDesc().getNumOperands();
for (unsigned i = NumOps - X86::AddrNumOperands; i != NumOps; ++i)
Push->addOperand(DefMov->getOperand(i));
- Push->cloneMergedMemRefs(MF, {DefMov, &*Store});
+ Push->cloneMergedMemRefs(MF, {DefMov, &*Store});
DefMov->eraseFromParent();
} else {
PushOpcode = Is64Bit ? X86::PUSH64r : X86::PUSH32r;
@@ -599,7 +599,7 @@ void X86CallFrameOptimization::adjustCallSequence(MachineFunction &MF,
}
MachineInstr *X86CallFrameOptimization::canFoldIntoRegPush(
- MachineBasicBlock::iterator FrameSetup, Register Reg) {
+ MachineBasicBlock::iterator FrameSetup, Register Reg) {
// Do an extremely restricted form of load folding.
// ISel will often create patterns like:
// movl 4(%edi), %eax
@@ -610,7 +610,7 @@ MachineInstr *X86CallFrameOptimization::canFoldIntoRegPush(
// movl %eax, (%esp)
// call
// Get rid of those with prejudice.
- if (!Reg.isVirtual())
+ if (!Reg.isVirtual())
return nullptr;
// Make sure this is the only use of Reg.
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86CallLowering.cpp b/contrib/libs/llvm12/lib/Target/X86/X86CallLowering.cpp
index a497375bd0..53f57565d5 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86CallLowering.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86CallLowering.cpp
@@ -95,11 +95,11 @@ bool X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg,
namespace {
-struct X86OutgoingValueHandler : public CallLowering::OutgoingValueHandler {
- X86OutgoingValueHandler(MachineIRBuilder &MIRBuilder,
- MachineRegisterInfo &MRI, MachineInstrBuilder &MIB,
- CCAssignFn *AssignFn)
- : OutgoingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB),
+struct X86OutgoingValueHandler : public CallLowering::OutgoingValueHandler {
+ X86OutgoingValueHandler(MachineIRBuilder &MIRBuilder,
+ MachineRegisterInfo &MRI, MachineInstrBuilder &MIB,
+ CCAssignFn *AssignFn)
+ : OutgoingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB),
DL(MIRBuilder.getMF().getDataLayout()),
STI(MIRBuilder.getMF().getSubtarget<X86Subtarget>()) {}
@@ -134,10 +134,10 @@ struct X86OutgoingValueHandler : public CallLowering::OutgoingValueHandler {
unsigned ValSize = VA.getValVT().getSizeInBits();
unsigned LocSize = VA.getLocVT().getSizeInBits();
if (PhysRegSize > ValSize && LocSize == ValSize) {
- assert((PhysRegSize == 128 || PhysRegSize == 80) &&
- "We expect that to be 128 bit");
- ExtReg =
- MIRBuilder.buildAnyExt(LLT::scalar(PhysRegSize), ValVReg).getReg(0);
+ assert((PhysRegSize == 128 || PhysRegSize == 80) &&
+ "We expect that to be 128 bit");
+ ExtReg =
+ MIRBuilder.buildAnyExt(LLT::scalar(PhysRegSize), ValVReg).getReg(0);
} else
ExtReg = extendRegister(ValVReg, VA);
@@ -149,9 +149,9 @@ struct X86OutgoingValueHandler : public CallLowering::OutgoingValueHandler {
MachineFunction &MF = MIRBuilder.getMF();
Register ExtReg = extendRegister(ValVReg, VA);
- auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore,
- VA.getLocVT().getStoreSize(),
- inferAlignFromPtrInfo(MF, MPO));
+ auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore,
+ VA.getLocVT().getStoreSize(),
+ inferAlignFromPtrInfo(MF, MPO));
MIRBuilder.buildStore(ExtReg, Addr, *MMO);
}
@@ -184,9 +184,9 @@ protected:
} // end anonymous namespace
-bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
- const Value *Val, ArrayRef<Register> VRegs,
- FunctionLoweringInfo &FLI) const {
+bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
+ const Value *Val, ArrayRef<Register> VRegs,
+ FunctionLoweringInfo &FLI) const {
assert(((Val && !VRegs.empty()) || (!Val && VRegs.empty())) &&
"Return value without a vreg");
auto MIB = MIRBuilder.buildInstrNoInsert(X86::RET).addImm(0);
@@ -195,7 +195,7 @@ bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
MachineFunction &MF = MIRBuilder.getMF();
const Function &F = MF.getFunction();
MachineRegisterInfo &MRI = MF.getRegInfo();
- const DataLayout &DL = MF.getDataLayout();
+ const DataLayout &DL = MF.getDataLayout();
LLVMContext &Ctx = Val->getType()->getContext();
const X86TargetLowering &TLI = *getTLI<X86TargetLowering>();
@@ -215,7 +215,7 @@ bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
return false;
}
- X86OutgoingValueHandler Handler(MIRBuilder, MRI, MIB, RetCC_X86);
+ X86OutgoingValueHandler Handler(MIRBuilder, MRI, MIB, RetCC_X86);
if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
return false;
}
@@ -226,10 +226,10 @@ bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
namespace {
-struct X86IncomingValueHandler : public CallLowering::IncomingValueHandler {
- X86IncomingValueHandler(MachineIRBuilder &MIRBuilder,
- MachineRegisterInfo &MRI, CCAssignFn *AssignFn)
- : IncomingValueHandler(MIRBuilder, MRI, AssignFn),
+struct X86IncomingValueHandler : public CallLowering::IncomingValueHandler {
+ X86IncomingValueHandler(MachineIRBuilder &MIRBuilder,
+ MachineRegisterInfo &MRI, CCAssignFn *AssignFn)
+ : IncomingValueHandler(MIRBuilder, MRI, AssignFn),
DL(MIRBuilder.getMF().getDataLayout()) {}
Register getStackAddress(uint64_t Size, int64_t Offset,
@@ -246,7 +246,7 @@ struct X86IncomingValueHandler : public CallLowering::IncomingValueHandler {
void assignValueToAddress(Register ValVReg, Register Addr, uint64_t Size,
MachinePointerInfo &MPO, CCValAssign &VA) override {
MachineFunction &MF = MIRBuilder.getMF();
- auto *MMO = MF.getMachineMemOperand(
+ auto *MMO = MF.getMachineMemOperand(
MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, Size,
inferAlignFromPtrInfo(MF, MPO));
MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
@@ -296,10 +296,10 @@ protected:
const DataLayout &DL;
};
-struct FormalArgHandler : public X86IncomingValueHandler {
+struct FormalArgHandler : public X86IncomingValueHandler {
FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
CCAssignFn *AssignFn)
- : X86IncomingValueHandler(MIRBuilder, MRI, AssignFn) {}
+ : X86IncomingValueHandler(MIRBuilder, MRI, AssignFn) {}
void markPhysRegUsed(unsigned PhysReg) override {
MIRBuilder.getMRI()->addLiveIn(PhysReg);
@@ -307,10 +307,10 @@ struct FormalArgHandler : public X86IncomingValueHandler {
}
};
-struct CallReturnHandler : public X86IncomingValueHandler {
+struct CallReturnHandler : public X86IncomingValueHandler {
CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
CCAssignFn *AssignFn, MachineInstrBuilder &MIB)
- : X86IncomingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
+ : X86IncomingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
void markPhysRegUsed(unsigned PhysReg) override {
MIB.addDef(PhysReg, RegState::Implicit);
@@ -322,10 +322,10 @@ protected:
} // end anonymous namespace
-bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
- const Function &F,
- ArrayRef<ArrayRef<Register>> VRegs,
- FunctionLoweringInfo &FLI) const {
+bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
+ const Function &F,
+ ArrayRef<ArrayRef<Register>> VRegs,
+ FunctionLoweringInfo &FLI) const {
if (F.arg_empty())
return true;
@@ -339,7 +339,7 @@ bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
SmallVector<ArgInfo, 8> SplitArgs;
unsigned Idx = 0;
- for (const auto &Arg : F.args()) {
+ for (const auto &Arg : F.args()) {
// TODO: handle not simple cases.
if (Arg.hasAttribute(Attribute::ByVal) ||
Arg.hasAttribute(Attribute::InReg) ||
@@ -378,10 +378,10 @@ bool X86CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
MachineFunction &MF = MIRBuilder.getMF();
const Function &F = MF.getFunction();
MachineRegisterInfo &MRI = MF.getRegInfo();
- const DataLayout &DL = F.getParent()->getDataLayout();
+ const DataLayout &DL = F.getParent()->getDataLayout();
const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>();
const TargetInstrInfo &TII = *STI.getInstrInfo();
- const X86RegisterInfo *TRI = STI.getRegisterInfo();
+ const X86RegisterInfo *TRI = STI.getRegisterInfo();
// Handle only Linux C, X86_64_SysV calling conventions for now.
if (!STI.isTargetLinux() || !(Info.CallConv == CallingConv::C ||
@@ -419,7 +419,7 @@ bool X86CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
return false;
}
// Do the actual argument marshalling.
- X86OutgoingValueHandler Handler(MIRBuilder, MRI, MIB, CC_X86);
+ X86OutgoingValueHandler Handler(MIRBuilder, MRI, MIB, CC_X86);
if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
return false;
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86CallLowering.h b/contrib/libs/llvm12/lib/Target/X86/X86CallLowering.h
index 33d2143ef8..9390122d76 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86CallLowering.h
+++ b/contrib/libs/llvm12/lib/Target/X86/X86CallLowering.h
@@ -29,12 +29,12 @@ public:
X86CallLowering(const X86TargetLowering &TLI);
bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
- ArrayRef<Register> VRegs,
- FunctionLoweringInfo &FLI) const override;
+ ArrayRef<Register> VRegs,
+ FunctionLoweringInfo &FLI) const override;
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F,
- ArrayRef<ArrayRef<Register>> VRegs,
- FunctionLoweringInfo &FLI) const override;
+ ArrayRef<ArrayRef<Register>> VRegs,
+ FunctionLoweringInfo &FLI) const override;
bool lowerCall(MachineIRBuilder &MIRBuilder,
CallLoweringInfo &Info) const override;
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86CallingConv.cpp b/contrib/libs/llvm12/lib/Target/X86/X86CallingConv.cpp
index eada1f1540..c80a5d5bb3 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86CallingConv.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86CallingConv.cpp
@@ -330,15 +330,15 @@ static bool CC_X86_Intr(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
return true;
}
-static bool CC_X86_64_Pointer(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
- CCValAssign::LocInfo &LocInfo,
- ISD::ArgFlagsTy &ArgFlags, CCState &State) {
- if (LocVT != MVT::i64) {
- LocVT = MVT::i64;
- LocInfo = CCValAssign::ZExt;
- }
- return false;
-}
-
+static bool CC_X86_64_Pointer(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
+ CCValAssign::LocInfo &LocInfo,
+ ISD::ArgFlagsTy &ArgFlags, CCState &State) {
+ if (LocVT != MVT::i64) {
+ LocVT = MVT::i64;
+ LocInfo = CCValAssign::ZExt;
+ }
+ return false;
+}
+
// Provides entry points of CC_X86 and RetCC_X86.
#include "X86GenCallingConv.inc"
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td b/contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td
index 2fbd0f5cfd..3735fab818 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86CallingConv.td
@@ -336,9 +336,9 @@ def RetCC_X86_64_C : CallingConv<[
// MMX vector types are always returned in XMM0.
CCIfType<[x86mmx], CCAssignToReg<[XMM0, XMM1]>>,
- // Pointers are always returned in full 64-bit registers.
- CCIfPtr<CCCustom<"CC_X86_64_Pointer">>,
-
+ // Pointers are always returned in full 64-bit registers.
+ CCIfPtr<CCCustom<"CC_X86_64_Pointer">>,
+
CCIfSwiftError<CCIfType<[i64], CCAssignToReg<[R12]>>>,
CCDelegateTo<RetCC_X86Common>
@@ -521,9 +521,9 @@ def CC_X86_64_C : CallingConv<[
CCIfCC<"CallingConv::Swift",
CCIfSRet<CCIfType<[i64], CCAssignToReg<[RAX]>>>>,
- // Pointers are always passed in full 64-bit registers.
- CCIfPtr<CCCustom<"CC_X86_64_Pointer">>,
-
+ // Pointers are always passed in full 64-bit registers.
+ CCIfPtr<CCCustom<"CC_X86_64_Pointer">>,
+
// The first 6 integer arguments are passed in integer registers.
CCIfType<[i32], CCAssignToReg<[EDI, ESI, EDX, ECX, R8D, R9D]>>,
CCIfType<[i64], CCAssignToReg<[RDI, RSI, RDX, RCX, R8 , R9 ]>>,
@@ -1102,7 +1102,7 @@ def CSR_64_CXX_TLS_Darwin_ViaCopy : CalleeSavedRegs<(sub CSR_64_TLS_Darwin, RBP)
// All GPRs - except r11
def CSR_64_RT_MostRegs : CalleeSavedRegs<(add CSR_64, RAX, RCX, RDX, RSI, RDI,
- R8, R9, R10)>;
+ R8, R9, R10)>;
// All registers - except r11
def CSR_64_RT_AllRegs : CalleeSavedRegs<(add CSR_64_RT_MostRegs,
@@ -1160,16 +1160,16 @@ def CSR_64_Intel_OCL_BI_AVX512 : CalleeSavedRegs<(add RBX, RSI, R14, R15,
def CSR_64_HHVM : CalleeSavedRegs<(add R12)>;
// Register calling convention preserves few GPR and XMM8-15
-def CSR_32_RegCall_NoSSE : CalleeSavedRegs<(add ESI, EDI, EBX, EBP)>;
+def CSR_32_RegCall_NoSSE : CalleeSavedRegs<(add ESI, EDI, EBX, EBP)>;
def CSR_32_RegCall : CalleeSavedRegs<(add CSR_32_RegCall_NoSSE,
(sequence "XMM%u", 4, 7))>;
def CSR_Win32_CFGuard_Check_NoSSE : CalleeSavedRegs<(add CSR_32_RegCall_NoSSE, ECX)>;
def CSR_Win32_CFGuard_Check : CalleeSavedRegs<(add CSR_32_RegCall, ECX)>;
-def CSR_Win64_RegCall_NoSSE : CalleeSavedRegs<(add RBX, RBP,
+def CSR_Win64_RegCall_NoSSE : CalleeSavedRegs<(add RBX, RBP,
(sequence "R%u", 10, 15))>;
def CSR_Win64_RegCall : CalleeSavedRegs<(add CSR_Win64_RegCall_NoSSE,
(sequence "XMM%u", 8, 15))>;
-def CSR_SysV64_RegCall_NoSSE : CalleeSavedRegs<(add RBX, RBP,
+def CSR_SysV64_RegCall_NoSSE : CalleeSavedRegs<(add RBX, RBP,
(sequence "R%u", 12, 15))>;
def CSR_SysV64_RegCall : CalleeSavedRegs<(add CSR_SysV64_RegCall_NoSSE,
(sequence "XMM%u", 8, 15))>;
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86CmovConversion.cpp b/contrib/libs/llvm12/lib/Target/X86/X86CmovConversion.cpp
index e840d30ce3..a2de0dc082 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86CmovConversion.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86CmovConversion.cpp
@@ -439,7 +439,7 @@ bool X86CmovConverterPass::checkForProfitableCmovCandidates(
if (!MO.isReg() || !MO.isUse())
continue;
Register Reg = MO.getReg();
- auto &RDM = RegDefMaps[Reg.isVirtual()];
+ auto &RDM = RegDefMaps[Reg.isVirtual()];
if (MachineInstr *DefMI = RDM.lookup(Reg)) {
OperandToDefMap[&MO] = DefMI;
DepthInfo Info = DepthMap.lookup(DefMI);
@@ -459,7 +459,7 @@ bool X86CmovConverterPass::checkForProfitableCmovCandidates(
if (!MO.isReg() || !MO.isDef())
continue;
Register Reg = MO.getReg();
- RegDefMaps[Reg.isVirtual()][Reg] = &MI;
+ RegDefMaps[Reg.isVirtual()][Reg] = &MI;
}
unsigned Latency = TSchedModel.computeInstrLatency(&MI);
@@ -537,7 +537,7 @@ bool X86CmovConverterPass::checkForProfitableCmovCandidates(
// This is another conservative check to avoid converting CMOV instruction
// used with tree-search like algorithm, where the branch is unpredicted.
auto UIs = MRI->use_instructions(MI->defs().begin()->getReg());
- if (!UIs.empty() && ++UIs.begin() == UIs.end()) {
+ if (!UIs.empty() && ++UIs.begin() == UIs.end()) {
unsigned Op = UIs.begin()->getOpcode();
if (Op == X86::MOV64rm || Op == X86::MOV32rm) {
WorthOpGroup = false;
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86DomainReassignment.cpp b/contrib/libs/llvm12/lib/Target/X86/X86DomainReassignment.cpp
index 8fd8b38f70..a2ae6345c0 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86DomainReassignment.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86DomainReassignment.cpp
@@ -141,7 +141,7 @@ public:
return false;
// It's illegal to replace an instruction that implicitly defines a register
// with an instruction that doesn't, unless that register dead.
- for (const auto &MO : MI->implicit_operands())
+ for (const auto &MO : MI->implicit_operands())
if (MO.isReg() && MO.isDef() && !MO.isDead() &&
!TII->get(DstOpcode).hasImplicitDefOfPhysReg(MO.getReg()))
return false;
@@ -180,7 +180,7 @@ public:
MachineRegisterInfo *MRI) const override {
assert(isLegal(MI, TII) && "Cannot convert instruction");
MachineBasicBlock *MBB = MI->getParent();
- const DebugLoc &DL = MI->getDebugLoc();
+ const DebugLoc &DL = MI->getDebugLoc();
Register Reg = MRI->createVirtualRegister(
TII->getRegClass(TII->get(DstOpcode), 0, MRI->getTargetRegisterInfo(),
@@ -220,12 +220,12 @@ public:
// Don't allow copies to/flow GR8/GR16 physical registers.
// FIXME: Is there some better way to support this?
Register DstReg = MI->getOperand(0).getReg();
- if (DstReg.isPhysical() && (X86::GR8RegClass.contains(DstReg) ||
- X86::GR16RegClass.contains(DstReg)))
+ if (DstReg.isPhysical() && (X86::GR8RegClass.contains(DstReg) ||
+ X86::GR16RegClass.contains(DstReg)))
return false;
Register SrcReg = MI->getOperand(1).getReg();
- if (SrcReg.isPhysical() && (X86::GR8RegClass.contains(SrcReg) ||
- X86::GR16RegClass.contains(SrcReg)))
+ if (SrcReg.isPhysical() && (X86::GR8RegClass.contains(SrcReg) ||
+ X86::GR16RegClass.contains(SrcReg)))
return false;
return true;
@@ -235,7 +235,7 @@ public:
MachineRegisterInfo *MRI) const override {
assert(MI->getOpcode() == TargetOpcode::COPY && "Expected a COPY");
- for (const auto &MO : MI->operands()) {
+ for (const auto &MO : MI->operands()) {
// Physical registers will not be converted. Assume that converting the
// COPY to the destination domain will eventually result in a actual
// instruction.
@@ -298,7 +298,7 @@ typedef DenseMap<InstrConverterBaseKeyTy, std::unique_ptr<InstrConverterBase>>
class Closure {
private:
/// Virtual registers in the closure.
- DenseSet<Register> Edges;
+ DenseSet<Register> Edges;
/// Instructions in the closure.
SmallVector<MachineInstr *, 8> Instrs;
@@ -330,9 +330,9 @@ public:
bool empty() const { return Edges.empty(); }
- bool insertEdge(Register Reg) { return Edges.insert(Reg).second; }
+ bool insertEdge(Register Reg) { return Edges.insert(Reg).second; }
- using const_edge_iterator = DenseSet<Register>::const_iterator;
+ using const_edge_iterator = DenseSet<Register>::const_iterator;
iterator_range<const_edge_iterator> edges() const {
return iterator_range<const_edge_iterator>(Edges.begin(), Edges.end());
}
@@ -348,7 +348,7 @@ public:
LLVM_DUMP_METHOD void dump(const MachineRegisterInfo *MRI) const {
dbgs() << "Registers: ";
bool First = true;
- for (Register Reg : Edges) {
+ for (Register Reg : Edges) {
if (!First)
dbgs() << ", ";
First = false;
@@ -403,10 +403,10 @@ private:
void initConverters();
/// Starting from \Reg, expand the closure as much as possible.
- void buildClosure(Closure &, Register Reg);
+ void buildClosure(Closure &, Register Reg);
/// Enqueue \p Reg to be considered for addition to the closure.
- void visitRegister(Closure &, Register Reg, RegDomain &Domain,
+ void visitRegister(Closure &, Register Reg, RegDomain &Domain,
SmallVectorImpl<unsigned> &Worklist);
/// Reassign the closure to \p Domain.
@@ -426,13 +426,13 @@ char X86DomainReassignment::ID = 0;
} // End anonymous namespace.
-void X86DomainReassignment::visitRegister(Closure &C, Register Reg,
+void X86DomainReassignment::visitRegister(Closure &C, Register Reg,
RegDomain &Domain,
SmallVectorImpl<unsigned> &Worklist) {
if (EnclosedEdges.count(Reg))
return;
- if (!Reg.isVirtual())
+ if (!Reg.isVirtual())
return;
if (!MRI->hasOneDef(Reg))
@@ -503,7 +503,7 @@ void X86DomainReassignment::reassign(const Closure &C, RegDomain Domain) const {
// Iterate all registers in the closure, replace them with registers in the
// destination domain.
- for (Register Reg : C.edges()) {
+ for (Register Reg : C.edges()) {
MRI->setRegClass(Reg, getDstRC(MRI->getRegClass(Reg), Domain));
for (auto &MO : MRI->use_operands(Reg)) {
if (MO.isReg())
@@ -513,13 +513,13 @@ void X86DomainReassignment::reassign(const Closure &C, RegDomain Domain) const {
}
}
- for (auto *MI : ToErase)
+ for (auto *MI : ToErase)
MI->eraseFromParent();
}
/// \returns true when \p Reg is used as part of an address calculation in \p
/// MI.
-static bool usedAsAddr(const MachineInstr &MI, Register Reg,
+static bool usedAsAddr(const MachineInstr &MI, Register Reg,
const TargetInstrInfo *TII) {
if (!MI.mayLoadOrStore())
return false;
@@ -533,14 +533,14 @@ static bool usedAsAddr(const MachineInstr &MI, Register Reg,
for (unsigned MemOpIdx = MemOpStart,
MemOpEnd = MemOpStart + X86::AddrNumOperands;
MemOpIdx < MemOpEnd; ++MemOpIdx) {
- const MachineOperand &Op = MI.getOperand(MemOpIdx);
+ const MachineOperand &Op = MI.getOperand(MemOpIdx);
if (Op.isReg() && Op.getReg() == Reg)
return true;
}
return false;
}
-void X86DomainReassignment::buildClosure(Closure &C, Register Reg) {
+void X86DomainReassignment::buildClosure(Closure &C, Register Reg) {
SmallVector<unsigned, 4> Worklist;
RegDomain Domain = NoDomain;
visitRegister(C, Reg, Domain, Worklist);
@@ -590,7 +590,7 @@ void X86DomainReassignment::buildClosure(Closure &C, Register Reg) {
continue;
Register DefReg = DefOp.getReg();
- if (!DefReg.isVirtual()) {
+ if (!DefReg.isVirtual()) {
C.setAllIllegal();
continue;
}
@@ -749,7 +749,7 @@ bool X86DomainReassignment::runOnMachineFunction(MachineFunction &MF) {
// Go over all virtual registers and calculate a closure.
unsigned ClosureID = 0;
for (unsigned Idx = 0; Idx < MRI->getNumVirtRegs(); ++Idx) {
- Register Reg = Register::index2VirtReg(Idx);
+ Register Reg = Register::index2VirtReg(Idx);
// GPR only current source domain supported.
if (!isGPR(MRI->getRegClass(Reg)))
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86EvexToVex.cpp b/contrib/libs/llvm12/lib/Target/X86/X86EvexToVex.cpp
index 1ac8851ecd..97f843fa24 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86EvexToVex.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86EvexToVex.cpp
@@ -85,8 +85,8 @@ public:
private:
/// Machine instruction info used throughout the class.
const X86InstrInfo *TII = nullptr;
-
- const X86Subtarget *ST = nullptr;
+
+ const X86Subtarget *ST = nullptr;
};
} // end anonymous namespace
@@ -96,8 +96,8 @@ char EvexToVexInstPass::ID = 0;
bool EvexToVexInstPass::runOnMachineFunction(MachineFunction &MF) {
TII = MF.getSubtarget<X86Subtarget>().getInstrInfo();
- ST = &MF.getSubtarget<X86Subtarget>();
- if (!ST->hasAVX512())
+ ST = &MF.getSubtarget<X86Subtarget>();
+ if (!ST->hasAVX512())
return false;
bool Changed = false;
@@ -146,29 +146,29 @@ static bool usesExtendedRegister(const MachineInstr &MI) {
}
// Do any custom cleanup needed to finalize the conversion.
-static bool performCustomAdjustments(MachineInstr &MI, unsigned NewOpc,
- const X86Subtarget *ST) {
+static bool performCustomAdjustments(MachineInstr &MI, unsigned NewOpc,
+ const X86Subtarget *ST) {
(void)NewOpc;
unsigned Opc = MI.getOpcode();
switch (Opc) {
- case X86::VPDPBUSDSZ256m:
- case X86::VPDPBUSDSZ256r:
- case X86::VPDPBUSDSZ128m:
- case X86::VPDPBUSDSZ128r:
- case X86::VPDPBUSDZ256m:
- case X86::VPDPBUSDZ256r:
- case X86::VPDPBUSDZ128m:
- case X86::VPDPBUSDZ128r:
- case X86::VPDPWSSDSZ256m:
- case X86::VPDPWSSDSZ256r:
- case X86::VPDPWSSDSZ128m:
- case X86::VPDPWSSDSZ128r:
- case X86::VPDPWSSDZ256m:
- case X86::VPDPWSSDZ256r:
- case X86::VPDPWSSDZ128m:
- case X86::VPDPWSSDZ128r:
- // These can only VEX convert if AVXVNNI is enabled.
- return ST->hasAVXVNNI();
+ case X86::VPDPBUSDSZ256m:
+ case X86::VPDPBUSDSZ256r:
+ case X86::VPDPBUSDSZ128m:
+ case X86::VPDPBUSDSZ128r:
+ case X86::VPDPBUSDZ256m:
+ case X86::VPDPBUSDZ256r:
+ case X86::VPDPBUSDZ128m:
+ case X86::VPDPBUSDZ128r:
+ case X86::VPDPWSSDSZ256m:
+ case X86::VPDPWSSDSZ256r:
+ case X86::VPDPWSSDSZ128m:
+ case X86::VPDPWSSDSZ128r:
+ case X86::VPDPWSSDZ256m:
+ case X86::VPDPWSSDZ256r:
+ case X86::VPDPWSSDZ128m:
+ case X86::VPDPWSSDZ128r:
+ // These can only VEX convert if AVXVNNI is enabled.
+ return ST->hasAVXVNNI();
case X86::VALIGNDZ128rri:
case X86::VALIGNDZ128rmi:
case X86::VALIGNQZ128rri:
@@ -271,7 +271,7 @@ bool EvexToVexInstPass::CompressEvexToVexImpl(MachineInstr &MI) const {
(Desc.TSFlags & X86II::VEX_L) ? makeArrayRef(X86EvexToVex256CompressTable)
: makeArrayRef(X86EvexToVex128CompressTable);
- const auto *I = llvm::lower_bound(Table, MI.getOpcode());
+ const auto *I = llvm::lower_bound(Table, MI.getOpcode());
if (I == Table.end() || I->EvexOpcode != MI.getOpcode())
return false;
@@ -280,7 +280,7 @@ bool EvexToVexInstPass::CompressEvexToVexImpl(MachineInstr &MI) const {
if (usesExtendedRegister(MI))
return false;
- if (!performCustomAdjustments(MI, NewOpc, ST))
+ if (!performCustomAdjustments(MI, NewOpc, ST))
return false;
MI.setDesc(TII->get(NewOpc));
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86ExpandPseudo.cpp b/contrib/libs/llvm12/lib/Target/X86/X86ExpandPseudo.cpp
index 9998b30754..15af0fb2e8 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86ExpandPseudo.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86ExpandPseudo.cpp
@@ -338,24 +338,24 @@ bool X86ExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
// Perform the following transformation.
// SaveRbx = pseudocmpxchg Addr, <4 opds for the address>, InArg, SaveRbx
// =>
- // RBX = InArg
+ // RBX = InArg
// actualcmpxchg Addr
- // RBX = SaveRbx
+ // RBX = SaveRbx
const MachineOperand &InArg = MBBI->getOperand(6);
Register SaveRbx = MBBI->getOperand(7).getReg();
// Copy the input argument of the pseudo into the argument of the
// actual instruction.
- // NOTE: We don't copy the kill flag since the input might be the same reg
- // as one of the other operands of LCMPXCHG16B.
- TII->copyPhysReg(MBB, MBBI, DL, X86::RBX, InArg.getReg(), false);
+ // NOTE: We don't copy the kill flag since the input might be the same reg
+ // as one of the other operands of LCMPXCHG16B.
+ TII->copyPhysReg(MBB, MBBI, DL, X86::RBX, InArg.getReg(), false);
// Create the actual instruction.
- MachineInstr *NewInstr = BuildMI(MBB, MBBI, DL, TII->get(X86::LCMPXCHG16B));
+ MachineInstr *NewInstr = BuildMI(MBB, MBBI, DL, TII->get(X86::LCMPXCHG16B));
// Copy the operands related to the address.
for (unsigned Idx = 1; Idx < 6; ++Idx)
NewInstr->addOperand(MBBI->getOperand(Idx));
// Finally, restore the value of RBX.
- TII->copyPhysReg(MBB, MBBI, DL, X86::RBX, SaveRbx,
+ TII->copyPhysReg(MBB, MBBI, DL, X86::RBX, SaveRbx,
/*SrcIsKill*/ true);
// Delete the pseudo.
@@ -438,69 +438,69 @@ bool X86ExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
MBB.erase(MBBI);
return true;
}
- case X86::MWAITX_SAVE_RBX: {
- // Perform the following transformation.
- // SaveRbx = pseudomwaitx InArg, SaveRbx
- // =>
- // [E|R]BX = InArg
- // actualmwaitx
- // [E|R]BX = SaveRbx
- const MachineOperand &InArg = MBBI->getOperand(1);
- // Copy the input argument of the pseudo into the argument of the
- // actual instruction.
- TII->copyPhysReg(MBB, MBBI, DL, X86::EBX, InArg.getReg(), InArg.isKill());
- // Create the actual instruction.
- BuildMI(MBB, MBBI, DL, TII->get(X86::MWAITXrrr));
- // Finally, restore the value of RBX.
- Register SaveRbx = MBBI->getOperand(2).getReg();
- TII->copyPhysReg(MBB, MBBI, DL, X86::RBX, SaveRbx, /*SrcIsKill*/ true);
- // Delete the pseudo.
- MBBI->eraseFromParent();
- return true;
- }
+ case X86::MWAITX_SAVE_RBX: {
+ // Perform the following transformation.
+ // SaveRbx = pseudomwaitx InArg, SaveRbx
+ // =>
+ // [E|R]BX = InArg
+ // actualmwaitx
+ // [E|R]BX = SaveRbx
+ const MachineOperand &InArg = MBBI->getOperand(1);
+ // Copy the input argument of the pseudo into the argument of the
+ // actual instruction.
+ TII->copyPhysReg(MBB, MBBI, DL, X86::EBX, InArg.getReg(), InArg.isKill());
+ // Create the actual instruction.
+ BuildMI(MBB, MBBI, DL, TII->get(X86::MWAITXrrr));
+ // Finally, restore the value of RBX.
+ Register SaveRbx = MBBI->getOperand(2).getReg();
+ TII->copyPhysReg(MBB, MBBI, DL, X86::RBX, SaveRbx, /*SrcIsKill*/ true);
+ // Delete the pseudo.
+ MBBI->eraseFromParent();
+ return true;
+ }
case TargetOpcode::ICALL_BRANCH_FUNNEL:
ExpandICallBranchFunnel(&MBB, MBBI);
return true;
- case X86::PLDTILECFG: {
- MI.RemoveOperand(0);
- MI.setDesc(TII->get(X86::LDTILECFG));
- return true;
+ case X86::PLDTILECFG: {
+ MI.RemoveOperand(0);
+ MI.setDesc(TII->get(X86::LDTILECFG));
+ return true;
+ }
+ case X86::PSTTILECFG: {
+ MI.RemoveOperand(MI.getNumOperands() - 1); // Remove $tmmcfg
+ MI.setDesc(TII->get(X86::STTILECFG));
+ return true;
+ }
+ case X86::PTILELOADDV: {
+ MI.RemoveOperand(8); // Remove $tmmcfg
+ for (unsigned i = 2; i > 0; --i)
+ MI.RemoveOperand(i);
+ MI.setDesc(TII->get(X86::TILELOADD));
+ return true;
+ }
+ case X86::PTDPBSSDV: {
+ MI.RemoveOperand(7); // Remove $tmmcfg
+ MI.untieRegOperand(4);
+ for (unsigned i = 3; i > 0; --i)
+ MI.RemoveOperand(i);
+ MI.setDesc(TII->get(X86::TDPBSSD));
+ MI.tieOperands(0, 1);
+ return true;
+ }
+ case X86::PTILESTOREDV: {
+ MI.RemoveOperand(8); // Remove $tmmcfg
+ for (int i = 1; i >= 0; --i)
+ MI.RemoveOperand(i);
+ MI.setDesc(TII->get(X86::TILESTORED));
+ return true;
+ }
+ case X86::PTILEZEROV: {
+ for (int i = 3; i > 0; --i) // Remove row, col, $tmmcfg
+ MI.RemoveOperand(i);
+ MI.setDesc(TII->get(X86::TILEZERO));
+ return true;
+ }
}
- case X86::PSTTILECFG: {
- MI.RemoveOperand(MI.getNumOperands() - 1); // Remove $tmmcfg
- MI.setDesc(TII->get(X86::STTILECFG));
- return true;
- }
- case X86::PTILELOADDV: {
- MI.RemoveOperand(8); // Remove $tmmcfg
- for (unsigned i = 2; i > 0; --i)
- MI.RemoveOperand(i);
- MI.setDesc(TII->get(X86::TILELOADD));
- return true;
- }
- case X86::PTDPBSSDV: {
- MI.RemoveOperand(7); // Remove $tmmcfg
- MI.untieRegOperand(4);
- for (unsigned i = 3; i > 0; --i)
- MI.RemoveOperand(i);
- MI.setDesc(TII->get(X86::TDPBSSD));
- MI.tieOperands(0, 1);
- return true;
- }
- case X86::PTILESTOREDV: {
- MI.RemoveOperand(8); // Remove $tmmcfg
- for (int i = 1; i >= 0; --i)
- MI.RemoveOperand(i);
- MI.setDesc(TII->get(X86::TILESTORED));
- return true;
- }
- case X86::PTILEZEROV: {
- for (int i = 3; i > 0; --i) // Remove row, col, $tmmcfg
- MI.RemoveOperand(i);
- MI.setDesc(TII->get(X86::TILEZERO));
- return true;
- }
- }
llvm_unreachable("Previous switch has a fallthrough?");
}
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86FastISel.cpp b/contrib/libs/llvm12/lib/Target/X86/X86FastISel.cpp
index b53aa41575..a1a16a19f5 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86FastISel.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86FastISel.cpp
@@ -284,14 +284,14 @@ bool X86FastISel::foldX86XALUIntrinsic(X86::CondCode &CC, const Instruction *I,
return false;
}
- // Make sure no potentially eflags clobbering phi moves can be inserted in
- // between.
- auto HasPhis = [](const BasicBlock *Succ) {
- return !llvm::empty(Succ->phis());
- };
- if (I->isTerminator() && llvm::any_of(successors(I), HasPhis))
- return false;
-
+ // Make sure no potentially eflags clobbering phi moves can be inserted in
+ // between.
+ auto HasPhis = [](const BasicBlock *Succ) {
+ return !llvm::empty(Succ->phis());
+ };
+ if (I->isTerminator() && llvm::any_of(successors(I), HasPhis))
+ return false;
+
CC = TmpCC;
return true;
}
@@ -792,9 +792,9 @@ bool X86FastISel::handleConstantAddresses(const Value *V, X86AddressMode &AM) {
RC = &X86::GR32RegClass;
}
- if (Subtarget->isPICStyleRIPRel() || GVFlags == X86II::MO_GOTPCREL)
- StubAM.Base.Reg = X86::RIP;
-
+ if (Subtarget->isPICStyleRIPRel() || GVFlags == X86II::MO_GOTPCREL)
+ StubAM.Base.Reg = X86::RIP;
+
LoadReg = createResultReg(RC);
MachineInstrBuilder LoadMI =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), LoadReg);
@@ -1090,35 +1090,35 @@ bool X86FastISel::X86SelectCallAddress(const Value *V, X86AddressMode &AM) {
// If all else fails, try to materialize the value in a register.
if (!AM.GV || !Subtarget->isPICStyleRIPRel()) {
- auto GetCallRegForValue = [this](const Value *V) {
- Register Reg = getRegForValue(V);
-
- // In 64-bit mode, we need a 64-bit register even if pointers are 32 bits.
- if (Reg && Subtarget->isTarget64BitILP32()) {
- Register CopyReg = createResultReg(&X86::GR32RegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::MOV32rr),
- CopyReg)
- .addReg(Reg);
-
- Register ExtReg = createResultReg(&X86::GR64RegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
- TII.get(TargetOpcode::SUBREG_TO_REG), ExtReg)
- .addImm(0)
- .addReg(CopyReg)
- .addImm(X86::sub_32bit);
- Reg = ExtReg;
- }
-
- return Reg;
- };
-
+ auto GetCallRegForValue = [this](const Value *V) {
+ Register Reg = getRegForValue(V);
+
+ // In 64-bit mode, we need a 64-bit register even if pointers are 32 bits.
+ if (Reg && Subtarget->isTarget64BitILP32()) {
+ Register CopyReg = createResultReg(&X86::GR32RegClass);
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::MOV32rr),
+ CopyReg)
+ .addReg(Reg);
+
+ Register ExtReg = createResultReg(&X86::GR64RegClass);
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
+ TII.get(TargetOpcode::SUBREG_TO_REG), ExtReg)
+ .addImm(0)
+ .addReg(CopyReg)
+ .addImm(X86::sub_32bit);
+ Reg = ExtReg;
+ }
+
+ return Reg;
+ };
+
if (AM.Base.Reg == 0) {
- AM.Base.Reg = GetCallRegForValue(V);
+ AM.Base.Reg = GetCallRegForValue(V);
return AM.Base.Reg != 0;
}
if (AM.IndexReg == 0) {
assert(AM.Scale == 1 && "Scale with no index!");
- AM.IndexReg = GetCallRegForValue(V);
+ AM.IndexReg = GetCallRegForValue(V);
return AM.IndexReg != 0;
}
}
@@ -1261,15 +1261,15 @@ bool X86FastISel::X86SelectRet(const Instruction *I) {
if (SrcVT == MVT::i1) {
if (Outs[0].Flags.isSExt())
return false;
- // TODO
- SrcReg = fastEmitZExtFromI1(MVT::i8, SrcReg, /*Op0IsKill=*/false);
+ // TODO
+ SrcReg = fastEmitZExtFromI1(MVT::i8, SrcReg, /*Op0IsKill=*/false);
SrcVT = MVT::i8;
}
unsigned Op = Outs[0].Flags.isZExt() ? ISD::ZERO_EXTEND :
ISD::SIGN_EXTEND;
- // TODO
- SrcReg = fastEmit_r(SrcVT.getSimpleVT(), DstVT.getSimpleVT(), Op, SrcReg,
- /*Op0IsKill=*/false);
+ // TODO
+ SrcReg = fastEmit_r(SrcVT.getSimpleVT(), DstVT.getSimpleVT(), Op, SrcReg,
+ /*Op0IsKill=*/false);
}
// Make the copy.
@@ -1463,8 +1463,8 @@ bool X86FastISel::X86SelectCmp(const Instruction *I) {
ResultReg = createResultReg(&X86::GR32RegClass);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::MOV32r0),
ResultReg);
- ResultReg = fastEmitInst_extractsubreg(MVT::i8, ResultReg,
- /*Op0IsKill=*/true, X86::sub_8bit);
+ ResultReg = fastEmitInst_extractsubreg(MVT::i8, ResultReg,
+ /*Op0IsKill=*/true, X86::sub_8bit);
if (!ResultReg)
return false;
break;
@@ -1587,11 +1587,11 @@ bool X86FastISel::X86SelectZExt(const Instruction *I) {
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::MOVZX32rr8),
Result32).addReg(ResultReg);
- ResultReg = fastEmitInst_extractsubreg(MVT::i16, Result32,
- /*Op0IsKill=*/true, X86::sub_16bit);
+ ResultReg = fastEmitInst_extractsubreg(MVT::i16, Result32,
+ /*Op0IsKill=*/true, X86::sub_16bit);
} else if (DstVT != MVT::i8) {
ResultReg = fastEmit_r(MVT::i8, DstVT.getSimpleVT(), ISD::ZERO_EXTEND,
- ResultReg, /*Op0IsKill=*/true);
+ ResultReg, /*Op0IsKill=*/true);
if (ResultReg == 0)
return false;
}
@@ -1633,11 +1633,11 @@ bool X86FastISel::X86SelectSExt(const Instruction *I) {
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::MOVSX32rr8),
Result32).addReg(ResultReg);
- ResultReg = fastEmitInst_extractsubreg(MVT::i16, Result32,
- /*Op0IsKill=*/true, X86::sub_16bit);
+ ResultReg = fastEmitInst_extractsubreg(MVT::i16, Result32,
+ /*Op0IsKill=*/true, X86::sub_16bit);
} else if (DstVT != MVT::i8) {
ResultReg = fastEmit_r(MVT::i8, DstVT.getSimpleVT(), ISD::SIGN_EXTEND,
- ResultReg, /*Op0IsKill=*/true);
+ ResultReg, /*Op0IsKill=*/true);
if (ResultReg == 0)
return false;
}
@@ -1789,7 +1789,7 @@ bool X86FastISel::X86SelectBranch(const Instruction *I) {
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(TargetOpcode::COPY), OpReg)
.addReg(KOpReg);
- OpReg = fastEmitInst_extractsubreg(MVT::i8, OpReg, /*Op0IsKill=*/true,
+ OpReg = fastEmitInst_extractsubreg(MVT::i8, OpReg, /*Op0IsKill=*/true,
X86::sub_8bit);
}
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::TEST8ri))
@@ -2021,7 +2021,7 @@ bool X86FastISel::X86SelectDivRem(const Instruction *I) {
// Now reference the 8-bit subreg of the result.
ResultReg = fastEmitInst_extractsubreg(MVT::i8, ResultSuperReg,
- /*Op0IsKill=*/true, X86::sub_8bit);
+ /*Op0IsKill=*/true, X86::sub_8bit);
}
// Copy the result out of the physreg if we haven't already.
if (!ResultReg) {
@@ -2135,7 +2135,7 @@ bool X86FastISel::X86FastEmitCMoveSelect(MVT RetVT, const Instruction *I) {
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(TargetOpcode::COPY), CondReg)
.addReg(KCondReg, getKillRegState(CondIsKill));
- CondReg = fastEmitInst_extractsubreg(MVT::i8, CondReg, /*Op0IsKill=*/true,
+ CondReg = fastEmitInst_extractsubreg(MVT::i8, CondReg, /*Op0IsKill=*/true,
X86::sub_8bit);
}
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::TEST8ri))
@@ -2289,12 +2289,12 @@ bool X86FastISel::X86FastEmitSSESelect(MVT RetVT, const Instruction *I) {
const TargetRegisterClass *VR128 = &X86::VR128RegClass;
Register CmpReg = fastEmitInst_rri(Opc[0], RC, CmpLHSReg, CmpLHSIsKill,
CmpRHSReg, CmpRHSIsKill, CC);
- Register AndReg = fastEmitInst_rr(Opc[1], VR128, CmpReg,
- /*Op0IsKill=*/false, LHSReg, LHSIsKill);
- Register AndNReg = fastEmitInst_rr(Opc[2], VR128, CmpReg,
- /*Op0IsKill=*/true, RHSReg, RHSIsKill);
- Register OrReg = fastEmitInst_rr(Opc[3], VR128, AndNReg, /*Op0IsKill=*/true,
- AndReg, /*Op1IsKill=*/true);
+ Register AndReg = fastEmitInst_rr(Opc[1], VR128, CmpReg,
+ /*Op0IsKill=*/false, LHSReg, LHSIsKill);
+ Register AndNReg = fastEmitInst_rr(Opc[2], VR128, CmpReg,
+ /*Op0IsKill=*/true, RHSReg, RHSIsKill);
+ Register OrReg = fastEmitInst_rr(Opc[3], VR128, AndNReg, /*Op0IsKill=*/true,
+ AndReg, /*Op1IsKill=*/true);
ResultReg = createResultReg(RC);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(TargetOpcode::COPY), ResultReg).addReg(OrReg);
@@ -2353,7 +2353,7 @@ bool X86FastISel::X86FastEmitPseudoSelect(MVT RetVT, const Instruction *I) {
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(TargetOpcode::COPY), CondReg)
.addReg(KCondReg, getKillRegState(CondIsKill));
- CondReg = fastEmitInst_extractsubreg(MVT::i8, CondReg, /*Op0IsKill=*/true,
+ CondReg = fastEmitInst_extractsubreg(MVT::i8, CondReg, /*Op0IsKill=*/true,
X86::sub_8bit);
}
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::TEST8ri))
@@ -2610,7 +2610,7 @@ bool X86FastISel::TryEmitSmallMemcpy(X86AddressMode DestAM,
unsigned Reg;
bool RV = X86FastEmitLoad(VT, SrcAM, nullptr, Reg);
- RV &= X86FastEmitStore(VT, Reg, /*ValIsKill=*/true, DestAM);
+ RV &= X86FastEmitStore(VT, Reg, /*ValIsKill=*/true, DestAM);
assert(RV && "Failed to emit load or store??");
unsigned Size = VT.getSizeInBits()/8;
@@ -2674,15 +2674,15 @@ bool X86FastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) {
assert(Op->getType()->isIntegerTy(16) && "Expected a 16-bit integer!");
// Explicitly zero-extend the input to 32-bit.
InputReg = fastEmit_r(MVT::i16, MVT::i32, ISD::ZERO_EXTEND, InputReg,
- /*Op0IsKill=*/false);
+ /*Op0IsKill=*/false);
// The following SCALAR_TO_VECTOR will be expanded into a VMOVDI2PDIrr.
InputReg = fastEmit_r(MVT::i32, MVT::v4i32, ISD::SCALAR_TO_VECTOR,
- InputReg, /*Op0IsKill=*/true);
+ InputReg, /*Op0IsKill=*/true);
unsigned Opc = Subtarget->hasVLX() ? X86::VCVTPH2PSZ128rr
: X86::VCVTPH2PSrr;
- InputReg = fastEmitInst_r(Opc, RC, InputReg, /*Op0IsKill=*/true);
+ InputReg = fastEmitInst_r(Opc, RC, InputReg, /*Op0IsKill=*/true);
// The result value is in the lower 32-bits of ResultReg.
// Emit an explicit copy from register class VR128 to register class FR32.
@@ -2740,7 +2740,7 @@ bool X86FastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) {
// ...
unsigned Depth = cast<ConstantInt>(II->getOperand(0))->getZExtValue();
while (Depth--) {
- Register DestReg = createResultReg(RC);
+ Register DestReg = createResultReg(RC);
addDirectMem(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Opc), DestReg), SrcReg);
SrcReg = DestReg;
@@ -2910,7 +2910,7 @@ bool X86FastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) {
const Value *RHS = II->getArgOperand(1);
// Canonicalize immediate to the RHS.
- if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS) && II->isCommutative())
+ if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS) && II->isCommutative())
std::swap(LHS, RHS);
unsigned BaseOpc, CondCode;
@@ -3723,10 +3723,10 @@ unsigned X86FastISel::X86MaterializeInt(const ConstantInt *CI, MVT VT) {
default: llvm_unreachable("Unexpected value type");
case MVT::i1:
case MVT::i8:
- return fastEmitInst_extractsubreg(MVT::i8, SrcReg, /*Op0IsKill=*/true,
+ return fastEmitInst_extractsubreg(MVT::i8, SrcReg, /*Op0IsKill=*/true,
X86::sub_8bit);
case MVT::i16:
- return fastEmitInst_extractsubreg(MVT::i16, SrcReg, /*Op0IsKill=*/true,
+ return fastEmitInst_extractsubreg(MVT::i16, SrcReg, /*Op0IsKill=*/true,
X86::sub_16bit);
case MVT::i32:
return SrcReg;
@@ -3823,7 +3823,7 @@ unsigned X86FastISel::X86MaterializeFP(const ConstantFP *CFP, MVT VT) {
.addConstantPoolIndex(CPI, 0, OpFlag);
MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Opc), ResultReg);
- addRegReg(MIB, AddrReg, false, PICBase, false);
+ addRegReg(MIB, AddrReg, false, PICBase, false);
MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
MachinePointerInfo::getConstantPool(*FuncInfo.MF),
MachineMemOperand::MOLoad, DL.getPointerSize(), Alignment);
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86FixupBWInsts.cpp b/contrib/libs/llvm12/lib/Target/X86/X86FixupBWInsts.cpp
index ddf96bc7b6..f8d822aebc 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86FixupBWInsts.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86FixupBWInsts.cpp
@@ -187,7 +187,7 @@ bool FixupBWInstPass::runOnMachineFunction(MachineFunction &MF) {
/// If so, return that super register in \p SuperDestReg.
bool FixupBWInstPass::getSuperRegDestIfDead(MachineInstr *OrigMI,
Register &SuperDestReg) const {
- const X86RegisterInfo *TRI = &TII->getRegisterInfo();
+ const X86RegisterInfo *TRI = &TII->getRegisterInfo();
Register OrigDestReg = OrigMI->getOperand(0).getReg();
SuperDestReg = getX86SubSuperRegister(OrigDestReg, 32);
@@ -319,7 +319,7 @@ MachineInstr *FixupBWInstPass::tryReplaceCopy(MachineInstr *MI) const {
// This is only correct if we access the same subregister index: otherwise,
// we could try to replace "movb %ah, %al" with "movl %eax, %eax".
- const X86RegisterInfo *TRI = &TII->getRegisterInfo();
+ const X86RegisterInfo *TRI = &TII->getRegisterInfo();
if (TRI->getSubRegIndex(NewSrcReg, OldSrc.getReg()) !=
TRI->getSubRegIndex(NewDestReg, OldDest.getReg()))
return nullptr;
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86FixupLEAs.cpp b/contrib/libs/llvm12/lib/Target/X86/X86FixupLEAs.cpp
index 482708e30d..0054d5818a 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86FixupLEAs.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86FixupLEAs.cpp
@@ -376,8 +376,8 @@ bool FixupLEAPass::optTwoAddrLEA(MachineBasicBlock::iterator &I,
const MachineOperand &Segment = MI.getOperand(1 + X86::AddrSegmentReg);
if (Segment.getReg() != 0 || !Disp.isImm() || Scale.getImm() > 1 ||
- MBB.computeRegisterLiveness(TRI, X86::EFLAGS, I) !=
- MachineBasicBlock::LQR_Dead)
+ MBB.computeRegisterLiveness(TRI, X86::EFLAGS, I) !=
+ MachineBasicBlock::LQR_Dead)
return false;
Register DestReg = MI.getOperand(0).getReg();
@@ -450,7 +450,7 @@ bool FixupLEAPass::optTwoAddrLEA(MachineBasicBlock::iterator &I,
} else
return false;
- MBB.getParent()->substituteDebugValuesForInst(*I, *NewMI, 1);
+ MBB.getParent()->substituteDebugValuesForInst(*I, *NewMI, 1);
MBB.erase(I);
I = NewMI;
return true;
@@ -486,7 +486,7 @@ void FixupLEAPass::seekLEAFixup(MachineOperand &p,
LLVM_DEBUG(dbgs() << "FixLEA: Candidate to replace:"; MBI->dump(););
// now to replace with an equivalent LEA...
LLVM_DEBUG(dbgs() << "FixLEA: Replaced by: "; NewMI->dump(););
- MBB.getParent()->substituteDebugValuesForInst(*MBI, *NewMI, 1);
+ MBB.getParent()->substituteDebugValuesForInst(*MBI, *NewMI, 1);
MBB.erase(MBI);
MachineBasicBlock::iterator J =
static_cast<MachineBasicBlock::iterator>(NewMI);
@@ -508,8 +508,8 @@ void FixupLEAPass::processInstructionForSlowLEA(MachineBasicBlock::iterator &I,
const MachineOperand &Segment = MI.getOperand(1 + X86::AddrSegmentReg);
if (Segment.getReg() != 0 || !Offset.isImm() ||
- MBB.computeRegisterLiveness(TRI, X86::EFLAGS, I, 4) !=
- MachineBasicBlock::LQR_Dead)
+ MBB.computeRegisterLiveness(TRI, X86::EFLAGS, I, 4) !=
+ MachineBasicBlock::LQR_Dead)
return;
const Register DstR = Dst.getReg();
const Register SrcR1 = Base.getReg();
@@ -540,7 +540,7 @@ void FixupLEAPass::processInstructionForSlowLEA(MachineBasicBlock::iterator &I,
LLVM_DEBUG(NewMI->dump(););
}
if (NewMI) {
- MBB.getParent()->substituteDebugValuesForInst(*I, *NewMI, 1);
+ MBB.getParent()->substituteDebugValuesForInst(*I, *NewMI, 1);
MBB.erase(I);
I = NewMI;
}
@@ -560,8 +560,8 @@ void FixupLEAPass::processInstrForSlow3OpLEA(MachineBasicBlock::iterator &I,
const MachineOperand &Segment = MI.getOperand(1 + X86::AddrSegmentReg);
if (!(TII->isThreeOperandsLEA(MI) || hasInefficientLEABaseReg(Base, Index)) ||
- MBB.computeRegisterLiveness(TRI, X86::EFLAGS, I, 4) !=
- MachineBasicBlock::LQR_Dead ||
+ MBB.computeRegisterLiveness(TRI, X86::EFLAGS, I, 4) !=
+ MachineBasicBlock::LQR_Dead ||
Segment.getReg() != X86::NoRegister)
return;
@@ -647,7 +647,7 @@ void FixupLEAPass::processInstrForSlow3OpLEA(MachineBasicBlock::iterator &I,
}
}
- MBB.getParent()->substituteDebugValuesForInst(*I, *NewMI, 1);
+ MBB.getParent()->substituteDebugValuesForInst(*I, *NewMI, 1);
MBB.erase(I);
I = NewMI;
return;
@@ -673,7 +673,7 @@ void FixupLEAPass::processInstrForSlow3OpLEA(MachineBasicBlock::iterator &I,
.add(Index);
LLVM_DEBUG(NewMI->dump(););
- MBB.getParent()->substituteDebugValuesForInst(*I, *NewMI, 1);
+ MBB.getParent()->substituteDebugValuesForInst(*I, *NewMI, 1);
MBB.erase(I);
I = NewMI;
return;
@@ -696,7 +696,7 @@ void FixupLEAPass::processInstrForSlow3OpLEA(MachineBasicBlock::iterator &I,
.add(Base);
LLVM_DEBUG(NewMI->dump(););
- MBB.getParent()->substituteDebugValuesForInst(*I, *NewMI, 1);
+ MBB.getParent()->substituteDebugValuesForInst(*I, *NewMI, 1);
MBB.erase(I);
I = NewMI;
}
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86FixupSetCC.cpp b/contrib/libs/llvm12/lib/Target/X86/X86FixupSetCC.cpp
index a46da8aa48..269f8ce6bd 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86FixupSetCC.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86FixupSetCC.cpp
@@ -101,24 +101,24 @@ bool X86FixupSetCCPass::runOnMachineFunction(MachineFunction &MF) {
const TargetRegisterClass *RC = MF.getSubtarget<X86Subtarget>().is64Bit()
? &X86::GR32RegClass
: &X86::GR32_ABCDRegClass;
- if (!MRI->constrainRegClass(ZExt->getOperand(0).getReg(), RC)) {
- // If we cannot constrain the register, we would need an additional copy
- // and are better off keeping the MOVZX32rr8 we have now.
- continue;
- }
-
- ++NumSubstZexts;
- Changed = true;
-
+ if (!MRI->constrainRegClass(ZExt->getOperand(0).getReg(), RC)) {
+ // If we cannot constrain the register, we would need an additional copy
+ // and are better off keeping the MOVZX32rr8 we have now.
+ continue;
+ }
+
+ ++NumSubstZexts;
+ Changed = true;
+
// Initialize a register with 0. This must go before the eflags def
- Register ZeroReg = MRI->createVirtualRegister(RC);
+ Register ZeroReg = MRI->createVirtualRegister(RC);
BuildMI(MBB, FlagsDefMI, MI.getDebugLoc(), TII->get(X86::MOV32r0),
ZeroReg);
// X86 setcc only takes an output GR8, so fake a GR32 input by inserting
// the setcc result into the low byte of the zeroed register.
BuildMI(*ZExt->getParent(), ZExt, ZExt->getDebugLoc(),
- TII->get(X86::INSERT_SUBREG), ZExt->getOperand(0).getReg())
+ TII->get(X86::INSERT_SUBREG), ZExt->getOperand(0).getReg())
.addReg(ZeroReg)
.addReg(MI.getOperand(0).getReg())
.addImm(X86::sub_8bit);
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86FlagsCopyLowering.cpp b/contrib/libs/llvm12/lib/Target/X86/X86FlagsCopyLowering.cpp
index 539a3e2a20..d43fd807a5 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86FlagsCopyLowering.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86FlagsCopyLowering.cpp
@@ -97,7 +97,7 @@ private:
CondRegArray collectCondsInRegs(MachineBasicBlock &MBB,
MachineBasicBlock::iterator CopyDefI);
- Register promoteCondToReg(MachineBasicBlock &MBB,
+ Register promoteCondToReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator TestPos,
DebugLoc TestLoc, X86::CondCode Cond);
std::pair<unsigned, bool>
@@ -739,7 +739,7 @@ CondRegArray X86FlagsCopyLoweringPass::collectCondsInRegs(
llvm::reverse(llvm::make_range(MBB.begin(), TestPos))) {
X86::CondCode Cond = X86::getCondFromSETCC(MI);
if (Cond != X86::COND_INVALID && !MI.mayStore() &&
- MI.getOperand(0).isReg() && MI.getOperand(0).getReg().isVirtual()) {
+ MI.getOperand(0).isReg() && MI.getOperand(0).getReg().isVirtual()) {
assert(MI.getOperand(0).isDef() &&
"A non-storing SETcc should always define a register!");
CondRegs[Cond] = MI.getOperand(0).getReg();
@@ -753,7 +753,7 @@ CondRegArray X86FlagsCopyLoweringPass::collectCondsInRegs(
return CondRegs;
}
-Register X86FlagsCopyLoweringPass::promoteCondToReg(
+Register X86FlagsCopyLoweringPass::promoteCondToReg(
MachineBasicBlock &TestMBB, MachineBasicBlock::iterator TestPos,
DebugLoc TestLoc, X86::CondCode Cond) {
Register Reg = MRI->createVirtualRegister(PromoteRC);
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86FrameLowering.cpp b/contrib/libs/llvm12/lib/Target/X86/X86FrameLowering.cpp
index 54003a72c1..866f113640 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86FrameLowering.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86FrameLowering.cpp
@@ -28,7 +28,7 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetOptions.h"
@@ -235,7 +235,7 @@ void X86FrameLowering::emitSPUpdate(MachineBasicBlock &MBB,
if (isSub && !isEAXLiveIn(MBB))
Reg = Rax;
else
- Reg = TRI->findDeadCallerSavedReg(MBB, MBBI);
+ Reg = TRI->findDeadCallerSavedReg(MBB, MBBI);
unsigned MovRIOpc = Is64Bit ? X86::MOV64ri : X86::MOV32ri;
unsigned AddSubRROpc =
@@ -292,7 +292,7 @@ void X86FrameLowering::emitSPUpdate(MachineBasicBlock &MBB,
// need to find a dead register when using pop.
unsigned Reg = isSub
? (unsigned)(Is64Bit ? X86::RAX : X86::EAX)
- : TRI->findDeadCallerSavedReg(MBB, MBBI);
+ : TRI->findDeadCallerSavedReg(MBB, MBBI);
if (Reg) {
unsigned Opc = isSub
? (Is64Bit ? X86::PUSH64r : X86::PUSH32r)
@@ -437,9 +437,9 @@ void X86FrameLowering::emitCalleeSavedFrameMoves(
}
const MachineModuleInfo &MMI = MF.getMMI();
const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
- const Register FramePtr = TRI->getFrameRegister(MF);
- const Register MachineFramePtr =
- STI.isTarget64BitILP32() ? Register(getX86SubSuperRegister(FramePtr, 64))
+ const Register FramePtr = TRI->getFrameRegister(MF);
+ const Register MachineFramePtr =
+ STI.isTarget64BitILP32() ? Register(getX86SubSuperRegister(FramePtr, 64))
: FramePtr;
unsigned DwarfReg = MRI->getDwarfRegNum(MachineFramePtr, true);
// Offset = space for return address + size of the frame pointer itself.
@@ -1690,7 +1690,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
assert(Personality == EHPersonality::MSVC_CXX);
Register FrameReg;
int FI = MF.getWinEHFuncInfo()->EHRegNodeFrameIndex;
- int64_t EHRegOffset = getFrameIndexReference(MF, FI, FrameReg).getFixed();
+ int64_t EHRegOffset = getFrameIndexReference(MF, FI, FrameReg).getFixed();
// ESP is the first field, so no extra displacement is needed.
addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32mr)), FrameReg,
false, EHRegOffset)
@@ -1711,9 +1711,9 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
if (IsWin64Prologue && IsFunclet)
Offset = getWin64EHFrameIndexRef(MF, FI, IgnoredFrameReg);
else
- Offset =
- getFrameIndexReference(MF, FI, IgnoredFrameReg).getFixed() +
- SEHFrameOffset;
+ Offset =
+ getFrameIndexReference(MF, FI, IgnoredFrameReg).getFixed() +
+ SEHFrameOffset;
HasWinCFI = true;
assert(!NeedsWinFPO && "SEH_SaveXMM incompatible with FPO data");
@@ -1785,8 +1785,8 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
unsigned Opm = Uses64BitFramePtr ? X86::MOV64mr : X86::MOV32mr;
Register UsedReg;
int Offset =
- getFrameIndexReference(MF, X86FI->getSEHFramePtrSaveIndex(), UsedReg)
- .getFixed();
+ getFrameIndexReference(MF, X86FI->getSEHFramePtrSaveIndex(), UsedReg)
+ .getFixed();
assert(UsedReg == BasePtr);
addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(Opm)), UsedReg, true, Offset)
.addReg(FramePtr)
@@ -1864,8 +1864,8 @@ X86FrameLowering::getPSPSlotOffsetFromSP(const MachineFunction &MF) const {
const WinEHFuncInfo &Info = *MF.getWinEHFuncInfo();
Register SPReg;
int Offset = getFrameIndexReferencePreferSP(MF, Info.PSPSymFrameIdx, SPReg,
- /*IgnoreSPUpdates*/ true)
- .getFixed();
+ /*IgnoreSPUpdates*/ true)
+ .getFixed();
assert(Offset >= 0 && SPReg == TRI->getStackRegister());
return static_cast<unsigned>(Offset);
}
@@ -1920,7 +1920,7 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
// standard x86_64 and NaCl use 64-bit frame/stack pointers, x32 - 32-bit.
const bool Is64BitILP32 = STI.isTarget64BitILP32();
Register FramePtr = TRI->getFrameRegister(MF);
- Register MachineFramePtr =
+ Register MachineFramePtr =
Is64BitILP32 ? Register(getX86SubSuperRegister(FramePtr, 64)) : FramePtr;
bool IsWin64Prologue = MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
@@ -2091,16 +2091,16 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
emitSPUpdate(MBB, Terminator, DL, Offset, /*InEpilogue=*/true);
}
}
-
- // Emit tilerelease for AMX kernel.
- const MachineRegisterInfo &MRI = MF.getRegInfo();
- if (!MRI.reg_nodbg_empty(X86::TMMCFG))
- BuildMI(MBB, Terminator, DL, TII.get(X86::TILERELEASE));
+
+ // Emit tilerelease for AMX kernel.
+ const MachineRegisterInfo &MRI = MF.getRegInfo();
+ if (!MRI.reg_nodbg_empty(X86::TMMCFG))
+ BuildMI(MBB, Terminator, DL, TII.get(X86::TILERELEASE));
}
-StackOffset X86FrameLowering::getFrameIndexReference(const MachineFunction &MF,
- int FI,
- Register &FrameReg) const {
+StackOffset X86FrameLowering::getFrameIndexReference(const MachineFunction &MF,
+ int FI,
+ Register &FrameReg) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
bool IsFixed = MFI.isFixedObjectIndex(FI);
@@ -2147,7 +2147,7 @@ StackOffset X86FrameLowering::getFrameIndexReference(const MachineFunction &MF,
uint64_t SEHFrameOffset = calculateSetFPREG(NumBytes);
if (FI && FI == X86FI->getFAIndex())
- return StackOffset::getFixed(-SEHFrameOffset);
+ return StackOffset::getFixed(-SEHFrameOffset);
// FPDelta is the offset from the "traditional" FP location of the old base
// pointer followed by return address and the location required by the
@@ -2163,23 +2163,23 @@ StackOffset X86FrameLowering::getFrameIndexReference(const MachineFunction &MF,
assert(HasFP && "VLAs and dynamic stack realign, but no FP?!");
if (FI < 0) {
// Skip the saved EBP.
- return StackOffset::getFixed(Offset + SlotSize + FPDelta);
+ return StackOffset::getFixed(Offset + SlotSize + FPDelta);
} else {
assert(isAligned(MFI.getObjectAlign(FI), -(Offset + StackSize)));
- return StackOffset::getFixed(Offset + StackSize);
+ return StackOffset::getFixed(Offset + StackSize);
}
} else if (TRI->needsStackRealignment(MF)) {
if (FI < 0) {
// Skip the saved EBP.
- return StackOffset::getFixed(Offset + SlotSize + FPDelta);
+ return StackOffset::getFixed(Offset + SlotSize + FPDelta);
} else {
assert(isAligned(MFI.getObjectAlign(FI), -(Offset + StackSize)));
- return StackOffset::getFixed(Offset + StackSize);
+ return StackOffset::getFixed(Offset + StackSize);
}
// FIXME: Support tail calls
} else {
if (!HasFP)
- return StackOffset::getFixed(Offset + StackSize);
+ return StackOffset::getFixed(Offset + StackSize);
// Skip the saved EBP.
Offset += SlotSize;
@@ -2190,7 +2190,7 @@ StackOffset X86FrameLowering::getFrameIndexReference(const MachineFunction &MF,
Offset -= TailCallReturnAddrDelta;
}
- return StackOffset::getFixed(Offset + FPDelta);
+ return StackOffset::getFixed(Offset + FPDelta);
}
int X86FrameLowering::getWin64EHFrameIndexRef(const MachineFunction &MF, int FI,
@@ -2201,27 +2201,27 @@ int X86FrameLowering::getWin64EHFrameIndexRef(const MachineFunction &MF, int FI,
const auto it = WinEHXMMSlotInfo.find(FI);
if (it == WinEHXMMSlotInfo.end())
- return getFrameIndexReference(MF, FI, FrameReg).getFixed();
+ return getFrameIndexReference(MF, FI, FrameReg).getFixed();
FrameReg = TRI->getStackRegister();
return alignDown(MFI.getMaxCallFrameSize(), getStackAlign().value()) +
it->second;
}
-StackOffset
-X86FrameLowering::getFrameIndexReferenceSP(const MachineFunction &MF, int FI,
- Register &FrameReg,
- int Adjustment) const {
+StackOffset
+X86FrameLowering::getFrameIndexReferenceSP(const MachineFunction &MF, int FI,
+ Register &FrameReg,
+ int Adjustment) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
FrameReg = TRI->getStackRegister();
- return StackOffset::getFixed(MFI.getObjectOffset(FI) -
- getOffsetOfLocalArea() + Adjustment);
+ return StackOffset::getFixed(MFI.getObjectOffset(FI) -
+ getOffsetOfLocalArea() + Adjustment);
}
-StackOffset
-X86FrameLowering::getFrameIndexReferencePreferSP(const MachineFunction &MF,
- int FI, Register &FrameReg,
- bool IgnoreSPUpdates) const {
+StackOffset
+X86FrameLowering::getFrameIndexReferencePreferSP(const MachineFunction &MF,
+ int FI, Register &FrameReg,
+ bool IgnoreSPUpdates) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
// Does not include any dynamic realign.
@@ -2898,8 +2898,8 @@ static unsigned getHiPELiteral(
// non-meta instructions between MBBI and MBB.end().
static bool blockEndIsUnreachable(const MachineBasicBlock &MBB,
MachineBasicBlock::const_iterator MBBI) {
- return llvm::all_of(
- MBB.successors(),
+ return llvm::all_of(
+ MBB.successors(),
[](const MachineBasicBlock *Succ) { return Succ->isEHPad(); }) &&
std::all_of(MBBI, MBB.end(), [](const MachineInstr &MI) {
return MI.isMetaInstruction();
@@ -3082,8 +3082,8 @@ bool X86FrameLowering::adjustStackWithPops(MachineBasicBlock &MBB,
unsigned Regs[2];
unsigned FoundRegs = 0;
- const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
- const MachineOperand &RegMask = Prev->getOperand(1);
+ const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
+ const MachineOperand &RegMask = Prev->getOperand(1);
auto &RegClass =
Is64Bit ? X86::GR64_NOREX_NOSPRegClass : X86::GR32_NOREX_NOSPRegClass;
@@ -3269,14 +3269,14 @@ bool X86FrameLowering::canUseAsEpilogue(const MachineBasicBlock &MBB) const {
bool X86FrameLowering::enableShrinkWrapping(const MachineFunction &MF) const {
// If we may need to emit frameless compact unwind information, give
// up as this is currently broken: PR25614.
- bool CompactUnwind =
- MF.getMMI().getContext().getObjectFileInfo()->getCompactUnwindSection() !=
- nullptr;
- return (MF.getFunction().hasFnAttribute(Attribute::NoUnwind) || hasFP(MF) ||
- !CompactUnwind) &&
- // The lowering of segmented stack and HiPE only support entry
- // blocks as prologue blocks: PR26107. This limitation may be
- // lifted if we fix:
+ bool CompactUnwind =
+ MF.getMMI().getContext().getObjectFileInfo()->getCompactUnwindSection() !=
+ nullptr;
+ return (MF.getFunction().hasFnAttribute(Attribute::NoUnwind) || hasFP(MF) ||
+ !CompactUnwind) &&
+ // The lowering of segmented stack and HiPE only support entry
+ // blocks as prologue blocks: PR26107. This limitation may be
+ // lifted if we fix:
// - adjustForSegmentedStacks
// - adjustForHiPEPrologue
MF.getFunction().getCallingConv() != CallingConv::HiPE &&
@@ -3311,7 +3311,7 @@ MachineBasicBlock::iterator X86FrameLowering::restoreWin32EHStackPointers(
}
Register UsedReg;
- int EHRegOffset = getFrameIndexReference(MF, FI, UsedReg).getFixed();
+ int EHRegOffset = getFrameIndexReference(MF, FI, UsedReg).getFixed();
int EndOffset = -EHRegOffset - EHRegSize;
FuncInfo.EHRegNodeEndOffset = EndOffset;
@@ -3334,8 +3334,8 @@ MachineBasicBlock::iterator X86FrameLowering::restoreWin32EHStackPointers(
// MOV32rm SavedEBPOffset(%esi), %ebp
assert(X86FI->getHasSEHFramePtrSave());
int Offset =
- getFrameIndexReference(MF, X86FI->getSEHFramePtrSaveIndex(), UsedReg)
- .getFixed();
+ getFrameIndexReference(MF, X86FI->getSEHFramePtrSaveIndex(), UsedReg)
+ .getFixed();
assert(UsedReg == BasePtr);
addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32rm), FramePtr),
UsedReg, true, Offset)
@@ -3380,7 +3380,7 @@ struct X86FrameSortingObject {
// at the end of our list.
struct X86FrameSortingComparator {
inline bool operator()(const X86FrameSortingObject &A,
- const X86FrameSortingObject &B) const {
+ const X86FrameSortingObject &B) const {
uint64_t DensityAScaled, DensityBScaled;
// For consistency in our comparison, all invalid objects are placed
@@ -3516,21 +3516,21 @@ void X86FrameLowering::processFunctionBeforeFrameFinalized(
// emitPrologue if it gets called and emits CFI.
MF.setHasWinCFI(false);
- // If we are using Windows x64 CFI, ensure that the stack is always 8 byte
- // aligned. The format doesn't support misaligned stack adjustments.
- if (MF.getTarget().getMCAsmInfo()->usesWindowsCFI())
- MF.getFrameInfo().ensureMaxAlignment(Align(SlotSize));
-
+ // If we are using Windows x64 CFI, ensure that the stack is always 8 byte
+ // aligned. The format doesn't support misaligned stack adjustments.
+ if (MF.getTarget().getMCAsmInfo()->usesWindowsCFI())
+ MF.getFrameInfo().ensureMaxAlignment(Align(SlotSize));
+
// If this function isn't doing Win64-style C++ EH, we don't need to do
// anything.
- if (STI.is64Bit() && MF.hasEHFunclets() &&
- classifyEHPersonality(MF.getFunction().getPersonalityFn()) ==
- EHPersonality::MSVC_CXX) {
- adjustFrameForMsvcCxxEh(MF);
- }
-}
-
-void X86FrameLowering::adjustFrameForMsvcCxxEh(MachineFunction &MF) const {
+ if (STI.is64Bit() && MF.hasEHFunclets() &&
+ classifyEHPersonality(MF.getFunction().getPersonalityFn()) ==
+ EHPersonality::MSVC_CXX) {
+ adjustFrameForMsvcCxxEh(MF);
+ }
+}
+
+void X86FrameLowering::adjustFrameForMsvcCxxEh(MachineFunction &MF) const {
// Win64 C++ EH needs to allocate the UnwindHelp object at some fixed offset
// relative to RSP after the prologue. Find the offset of the last fixed
// object, so that we can allocate a slot immediately following it. If there
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86FrameLowering.h b/contrib/libs/llvm12/lib/Target/X86/X86FrameLowering.h
index a8c6320afa..26e80811af 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86FrameLowering.h
+++ b/contrib/libs/llvm12/lib/Target/X86/X86FrameLowering.h
@@ -14,7 +14,7 @@
#define LLVM_LIB_TARGET_X86_X86FRAMELOWERING_H
#include "llvm/CodeGen/TargetFrameLowering.h"
-#include "llvm/Support/TypeSize.h"
+#include "llvm/Support/TypeSize.h"
namespace llvm {
@@ -103,17 +103,17 @@ public:
bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override;
bool needsFrameIndexResolution(const MachineFunction &MF) const override;
- StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
- Register &FrameReg) const override;
+ StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
+ Register &FrameReg) const override;
int getWin64EHFrameIndexRef(const MachineFunction &MF, int FI,
Register &SPReg) const;
- StackOffset getFrameIndexReferenceSP(const MachineFunction &MF, int FI,
- Register &SPReg, int Adjustment) const;
- StackOffset
- getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI,
- Register &FrameReg,
- bool IgnoreSPUpdates) const override;
+ StackOffset getFrameIndexReferenceSP(const MachineFunction &MF, int FI,
+ Register &SPReg, int Adjustment) const;
+ StackOffset
+ getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI,
+ Register &FrameReg,
+ bool IgnoreSPUpdates) const override;
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
@@ -224,7 +224,7 @@ private:
const DebugLoc &DL, uint64_t Offset,
uint64_t Align) const;
- void adjustFrameForMsvcCxxEh(MachineFunction &MF) const;
+ void adjustFrameForMsvcCxxEh(MachineFunction &MF) const;
/// Aligns the stack pointer by ANDing it with -MaxAlign.
void BuildStackAlignAND(MachineBasicBlock &MBB,
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86ISelDAGToDAG.cpp b/contrib/libs/llvm12/lib/Target/X86/X86ISelDAGToDAG.cpp
index c4f21ed402..1df9a0d170 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -17,7 +17,7 @@
#include "X86Subtarget.h"
#include "X86TargetMachine.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/ConstantRange.h"
@@ -45,8 +45,8 @@ static cl::opt<bool> EnablePromoteAnyextLoad(
"x86-promote-anyext-load", cl::init(true),
cl::desc("Enable promoting aligned anyext load to wider load"), cl::Hidden);
-extern cl::opt<bool> IndirectBranchTracking;
-
+extern cl::opt<bool> IndirectBranchTracking;
+
//===----------------------------------------------------------------------===//
// Pattern Matcher Implementation
//===----------------------------------------------------------------------===//
@@ -207,8 +207,8 @@ namespace {
void Select(SDNode *N) override;
bool foldOffsetIntoAddress(uint64_t Offset, X86ISelAddressMode &AM);
- bool matchLoadInAddress(LoadSDNode *N, X86ISelAddressMode &AM,
- bool AllowSegmentRegForX32 = false);
+ bool matchLoadInAddress(LoadSDNode *N, X86ISelAddressMode &AM,
+ bool AllowSegmentRegForX32 = false);
bool matchWrapper(SDValue N, X86ISelAddressMode &AM);
bool matchAddress(SDValue N, X86ISelAddressMode &AM);
bool matchVectorAddress(SDValue N, X86ISelAddressMode &AM);
@@ -503,8 +503,8 @@ namespace {
bool tryShiftAmountMod(SDNode *N);
bool tryShrinkShlLogicImm(SDNode *N);
bool tryVPTERNLOG(SDNode *N);
- bool matchVPTERNLOG(SDNode *Root, SDNode *ParentA, SDNode *ParentBC,
- SDValue A, SDValue B, SDValue C, uint8_t Imm);
+ bool matchVPTERNLOG(SDNode *Root, SDNode *ParentA, SDNode *ParentBC,
+ SDValue A, SDValue B, SDValue C, uint8_t Imm);
bool tryVPTESTM(SDNode *Root, SDValue Setcc, SDValue Mask);
bool tryMatchBitSelect(SDNode *N);
@@ -527,9 +527,9 @@ namespace {
// type.
static bool isLegalMaskCompare(SDNode *N, const X86Subtarget *Subtarget) {
unsigned Opcode = N->getOpcode();
- if (Opcode == X86ISD::CMPM || Opcode == X86ISD::CMPMM ||
- Opcode == X86ISD::STRICT_CMPM || Opcode == ISD::SETCC ||
- Opcode == X86ISD::CMPMM_SAE || Opcode == X86ISD::VFPCLASS) {
+ if (Opcode == X86ISD::CMPM || Opcode == X86ISD::CMPMM ||
+ Opcode == X86ISD::STRICT_CMPM || Opcode == ISD::SETCC ||
+ Opcode == X86ISD::CMPMM_SAE || Opcode == X86ISD::VFPCLASS) {
// We can get 256-bit 8 element types here without VLX being enabled. When
// this happens we will use 512-bit operations and the mask will not be
// zero extended.
@@ -801,69 +801,69 @@ static bool isCalleeLoad(SDValue Callee, SDValue &Chain, bool HasCallSeq) {
return false;
}
-static bool isEndbrImm64(uint64_t Imm) {
-// There may be some other prefix bytes between 0xF3 and 0x0F1EFA.
-// i.g: 0xF3660F1EFA, 0xF3670F1EFA
- if ((Imm & 0x00FFFFFF) != 0x0F1EFA)
- return false;
-
- uint8_t OptionalPrefixBytes [] = {0x26, 0x2e, 0x36, 0x3e, 0x64,
- 0x65, 0x66, 0x67, 0xf0, 0xf2};
- int i = 24; // 24bit 0x0F1EFA has matched
- while (i < 64) {
- uint8_t Byte = (Imm >> i) & 0xFF;
- if (Byte == 0xF3)
- return true;
- if (!llvm::is_contained(OptionalPrefixBytes, Byte))
- return false;
- i += 8;
- }
-
- return false;
-}
-
+static bool isEndbrImm64(uint64_t Imm) {
+// There may be some other prefix bytes between 0xF3 and 0x0F1EFA.
+// i.g: 0xF3660F1EFA, 0xF3670F1EFA
+ if ((Imm & 0x00FFFFFF) != 0x0F1EFA)
+ return false;
+
+ uint8_t OptionalPrefixBytes [] = {0x26, 0x2e, 0x36, 0x3e, 0x64,
+ 0x65, 0x66, 0x67, 0xf0, 0xf2};
+ int i = 24; // 24bit 0x0F1EFA has matched
+ while (i < 64) {
+ uint8_t Byte = (Imm >> i) & 0xFF;
+ if (Byte == 0xF3)
+ return true;
+ if (!llvm::is_contained(OptionalPrefixBytes, Byte))
+ return false;
+ i += 8;
+ }
+
+ return false;
+}
+
void X86DAGToDAGISel::PreprocessISelDAG() {
bool MadeChange = false;
for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
E = CurDAG->allnodes_end(); I != E; ) {
SDNode *N = &*I++; // Preincrement iterator to avoid invalidation issues.
- // This is for CET enhancement.
- //
- // ENDBR32 and ENDBR64 have specific opcodes:
- // ENDBR32: F3 0F 1E FB
- // ENDBR64: F3 0F 1E FA
- // And we want that attackers won’t find unintended ENDBR32/64
- // opcode matches in the binary
- // Here’s an example:
- // If the compiler had to generate asm for the following code:
- // a = 0xF30F1EFA
- // it could, for example, generate:
- // mov 0xF30F1EFA, dword ptr[a]
- // In such a case, the binary would include a gadget that starts
- // with a fake ENDBR64 opcode. Therefore, we split such generation
- // into multiple operations, let it not shows in the binary
- if (N->getOpcode() == ISD::Constant) {
- MVT VT = N->getSimpleValueType(0);
- int64_t Imm = cast<ConstantSDNode>(N)->getSExtValue();
- int32_t EndbrImm = Subtarget->is64Bit() ? 0xF30F1EFA : 0xF30F1EFB;
- if (Imm == EndbrImm || isEndbrImm64(Imm)) {
- // Check that the cf-protection-branch is enabled.
- Metadata *CFProtectionBranch =
- MF->getMMI().getModule()->getModuleFlag("cf-protection-branch");
- if (CFProtectionBranch || IndirectBranchTracking) {
- SDLoc dl(N);
- SDValue Complement = CurDAG->getConstant(~Imm, dl, VT, false, true);
- Complement = CurDAG->getNOT(dl, Complement, VT);
- --I;
- CurDAG->ReplaceAllUsesOfValueWith(SDValue(N, 0), Complement);
- ++I;
- MadeChange = true;
- continue;
- }
- }
- }
-
+ // This is for CET enhancement.
+ //
+ // ENDBR32 and ENDBR64 have specific opcodes:
+ // ENDBR32: F3 0F 1E FB
+ // ENDBR64: F3 0F 1E FA
+ // And we want that attackers won’t find unintended ENDBR32/64
+ // opcode matches in the binary
+ // Here’s an example:
+ // If the compiler had to generate asm for the following code:
+ // a = 0xF30F1EFA
+ // it could, for example, generate:
+ // mov 0xF30F1EFA, dword ptr[a]
+ // In such a case, the binary would include a gadget that starts
+ // with a fake ENDBR64 opcode. Therefore, we split such generation
+ // into multiple operations, let it not shows in the binary
+ if (N->getOpcode() == ISD::Constant) {
+ MVT VT = N->getSimpleValueType(0);
+ int64_t Imm = cast<ConstantSDNode>(N)->getSExtValue();
+ int32_t EndbrImm = Subtarget->is64Bit() ? 0xF30F1EFA : 0xF30F1EFB;
+ if (Imm == EndbrImm || isEndbrImm64(Imm)) {
+ // Check that the cf-protection-branch is enabled.
+ Metadata *CFProtectionBranch =
+ MF->getMMI().getModule()->getModuleFlag("cf-protection-branch");
+ if (CFProtectionBranch || IndirectBranchTracking) {
+ SDLoc dl(N);
+ SDValue Complement = CurDAG->getConstant(~Imm, dl, VT, false, true);
+ Complement = CurDAG->getNOT(dl, Complement, VT);
+ --I;
+ CurDAG->ReplaceAllUsesOfValueWith(SDValue(N, 0), Complement);
+ ++I;
+ MadeChange = true;
+ continue;
+ }
+ }
+ }
+
// If this is a target specific AND node with no flag usages, turn it back
// into ISD::AND to enable test instruction matching.
if (N->getOpcode() == X86ISD::AND && !N->hasAnyUseOfValue(1)) {
@@ -1068,8 +1068,8 @@ void X86DAGToDAGISel::PreprocessISelDAG() {
case ISD::STRICT_FFLOOR:
case ISD::FTRUNC:
case ISD::STRICT_FTRUNC:
- case ISD::FROUNDEVEN:
- case ISD::STRICT_FROUNDEVEN:
+ case ISD::FROUNDEVEN:
+ case ISD::STRICT_FROUNDEVEN:
case ISD::FNEARBYINT:
case ISD::STRICT_FNEARBYINT:
case ISD::FRINT:
@@ -1085,8 +1085,8 @@ void X86DAGToDAGISel::PreprocessISelDAG() {
case ISD::FFLOOR: Imm = 0x9; break;
case ISD::STRICT_FTRUNC:
case ISD::FTRUNC: Imm = 0xB; break;
- case ISD::STRICT_FROUNDEVEN:
- case ISD::FROUNDEVEN: Imm = 0x8; break;
+ case ISD::STRICT_FROUNDEVEN:
+ case ISD::FROUNDEVEN: Imm = 0x8; break;
case ISD::STRICT_FNEARBYINT:
case ISD::FNEARBYINT: Imm = 0xC; break;
case ISD::STRICT_FRINT:
@@ -1099,11 +1099,11 @@ void X86DAGToDAGISel::PreprocessISelDAG() {
Res = CurDAG->getNode(X86ISD::STRICT_VRNDSCALE, dl,
{N->getValueType(0), MVT::Other},
{N->getOperand(0), N->getOperand(1),
- CurDAG->getTargetConstant(Imm, dl, MVT::i32)});
+ CurDAG->getTargetConstant(Imm, dl, MVT::i32)});
else
Res = CurDAG->getNode(X86ISD::VRNDSCALE, dl, N->getValueType(0),
N->getOperand(0),
- CurDAG->getTargetConstant(Imm, dl, MVT::i32));
+ CurDAG->getTargetConstant(Imm, dl, MVT::i32));
--I;
CurDAG->ReplaceAllUsesWith(N, Res.getNode());
++I;
@@ -1614,26 +1614,26 @@ bool X86DAGToDAGISel::foldOffsetIntoAddress(uint64_t Offset,
}
-bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *N, X86ISelAddressMode &AM,
- bool AllowSegmentRegForX32) {
+bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *N, X86ISelAddressMode &AM,
+ bool AllowSegmentRegForX32) {
SDValue Address = N->getOperand(1);
// load gs:0 -> GS segment register.
// load fs:0 -> FS segment register.
//
- // This optimization is generally valid because the GNU TLS model defines that
- // gs:0 (or fs:0 on X86-64) contains its own address. However, for X86-64 mode
- // with 32-bit registers, as we get in ILP32 mode, those registers are first
- // zero-extended to 64 bits and then added it to the base address, which gives
- // unwanted results when the register holds a negative value.
+ // This optimization is generally valid because the GNU TLS model defines that
+ // gs:0 (or fs:0 on X86-64) contains its own address. However, for X86-64 mode
+ // with 32-bit registers, as we get in ILP32 mode, those registers are first
+ // zero-extended to 64 bits and then added it to the base address, which gives
+ // unwanted results when the register holds a negative value.
// For more information see http://people.redhat.com/drepper/tls.pdf
- if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Address)) {
+ if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Address)) {
if (C->getSExtValue() == 0 && AM.Segment.getNode() == nullptr &&
!IndirectTlsSegRefs &&
(Subtarget->isTargetGlibc() || Subtarget->isTargetAndroid() ||
- Subtarget->isTargetFuchsia())) {
- if (Subtarget->isTarget64BitILP32() && !AllowSegmentRegForX32)
- return true;
+ Subtarget->isTargetFuchsia())) {
+ if (Subtarget->isTarget64BitILP32() && !AllowSegmentRegForX32)
+ return true;
switch (N->getPointerInfo().getAddrSpace()) {
case X86AS::GS:
AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
@@ -1644,8 +1644,8 @@ bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *N, X86ISelAddressMode &AM,
// Address space X86AS::SS is not handled here, because it is not used to
// address TLS areas.
}
- }
- }
+ }
+ }
return true;
}
@@ -1729,21 +1729,21 @@ bool X86DAGToDAGISel::matchAddress(SDValue N, X86ISelAddressMode &AM) {
if (matchAddressRecursively(N, AM, 0))
return true;
- // Post-processing: Make a second attempt to fold a load, if we now know
- // that there will not be any other register. This is only performed for
- // 64-bit ILP32 mode since 32-bit mode and 64-bit LP64 mode will have folded
- // any foldable load the first time.
- if (Subtarget->isTarget64BitILP32() &&
- AM.BaseType == X86ISelAddressMode::RegBase &&
- AM.Base_Reg.getNode() != nullptr && AM.IndexReg.getNode() == nullptr) {
- SDValue Save_Base_Reg = AM.Base_Reg;
- if (auto *LoadN = dyn_cast<LoadSDNode>(Save_Base_Reg)) {
- AM.Base_Reg = SDValue();
- if (matchLoadInAddress(LoadN, AM, /*AllowSegmentRegForX32=*/true))
- AM.Base_Reg = Save_Base_Reg;
- }
- }
-
+ // Post-processing: Make a second attempt to fold a load, if we now know
+ // that there will not be any other register. This is only performed for
+ // 64-bit ILP32 mode since 32-bit mode and 64-bit LP64 mode will have folded
+ // any foldable load the first time.
+ if (Subtarget->isTarget64BitILP32() &&
+ AM.BaseType == X86ISelAddressMode::RegBase &&
+ AM.Base_Reg.getNode() != nullptr && AM.IndexReg.getNode() == nullptr) {
+ SDValue Save_Base_Reg = AM.Base_Reg;
+ if (auto *LoadN = dyn_cast<LoadSDNode>(Save_Base_Reg)) {
+ AM.Base_Reg = SDValue();
+ if (matchLoadInAddress(LoadN, AM, /*AllowSegmentRegForX32=*/true))
+ AM.Base_Reg = Save_Base_Reg;
+ }
+ }
+
// Post-processing: Convert lea(,%reg,2) to lea(%reg,%reg), which has
// a smaller encoding and avoids a scaled-index.
if (AM.Scale == 2 &&
@@ -2718,12 +2718,12 @@ bool X86DAGToDAGISel::selectTLSADDRAddr(SDValue N, SDValue &Base,
AM.Disp += GA->getOffset();
AM.SymbolFlags = GA->getTargetFlags();
- if (Subtarget->is32Bit()) {
+ if (Subtarget->is32Bit()) {
AM.Scale = 1;
AM.IndexReg = CurDAG->getRegister(X86::EBX, MVT::i32);
}
- MVT VT = N.getSimpleValueType();
+ MVT VT = N.getSimpleValueType();
getAddressOperands(AM, SDLoc(N), VT, Base, Scale, Index, Disp, Segment);
return true;
}
@@ -2813,10 +2813,10 @@ bool X86DAGToDAGISel::isSExtAbsoluteSymbolRef(unsigned Width, SDNode *N) const {
return false;
Optional<ConstantRange> CR = GA->getGlobal()->getAbsoluteSymbolRange();
- if (!CR)
- return Width == 32 && TM.getCodeModel() == CodeModel::Small;
-
- return CR->getSignedMin().sge(-1ull << Width) &&
+ if (!CR)
+ return Width == 32 && TM.getCodeModel() == CodeModel::Small;
+
+ return CR->getSignedMin().sge(-1ull << Width) &&
CR->getSignedMax().slt(1ull << Width);
}
@@ -3210,7 +3210,7 @@ bool X86DAGToDAGISel::foldLoadStoreIntoMemOperand(SDNode *Node) {
bool IsNegOne = isAllOnesConstant(StoredVal.getOperand(1));
// ADD/SUB with 1/-1 and carry flag isn't used can use inc/dec.
if ((IsOne || IsNegOne) && hasNoCarryFlagUses(StoredVal.getValue(1))) {
- unsigned NewOpc =
+ unsigned NewOpc =
((Opc == X86ISD::ADD) == IsOne)
? SelectOpcode(X86::INC64m, X86::INC32m, X86::INC16m, X86::INC8m)
: SelectOpcode(X86::DEC64m, X86::DEC32m, X86::DEC16m, X86::DEC8m);
@@ -3466,7 +3466,7 @@ bool X86DAGToDAGISel::matchBitExtract(SDNode *Node) {
// Match the shift amount as: (bitwidth - y). It should go away, too.
if (ShiftAmt.getOpcode() != ISD::SUB)
return false;
- auto *V0 = dyn_cast<ConstantSDNode>(ShiftAmt.getOperand(0));
+ auto *V0 = dyn_cast<ConstantSDNode>(ShiftAmt.getOperand(0));
if (!V0 || V0->getZExtValue() != Bitwidth)
return false;
NBits = ShiftAmt.getOperand(1);
@@ -3589,7 +3589,7 @@ bool X86DAGToDAGISel::matchBitExtract(SDNode *Node) {
// Shift NBits left by 8 bits, thus producing 'control'.
// This makes the low 8 bits to be zero.
SDValue C8 = CurDAG->getConstant(8, DL, MVT::i8);
- insertDAGNode(*CurDAG, SDValue(Node, 0), C8);
+ insertDAGNode(*CurDAG, SDValue(Node, 0), C8);
SDValue Control = CurDAG->getNode(ISD::SHL, DL, MVT::i32, NBits, C8);
insertDAGNode(*CurDAG, SDValue(Node, 0), Control);
@@ -4019,129 +4019,129 @@ bool X86DAGToDAGISel::tryShrinkShlLogicImm(SDNode *N) {
return true;
}
-bool X86DAGToDAGISel::matchVPTERNLOG(SDNode *Root, SDNode *ParentA,
- SDNode *ParentBC, SDValue A, SDValue B,
- SDValue C, uint8_t Imm) {
- assert(A.isOperandOf(ParentA));
- assert(B.isOperandOf(ParentBC));
- assert(C.isOperandOf(ParentBC));
-
- auto tryFoldLoadOrBCast =
- [this](SDNode *Root, SDNode *P, SDValue &L, SDValue &Base, SDValue &Scale,
- SDValue &Index, SDValue &Disp, SDValue &Segment) {
- if (tryFoldLoad(Root, P, L, Base, Scale, Index, Disp, Segment))
- return true;
-
- // Not a load, check for broadcast which may be behind a bitcast.
- if (L.getOpcode() == ISD::BITCAST && L.hasOneUse()) {
- P = L.getNode();
- L = L.getOperand(0);
- }
-
- if (L.getOpcode() != X86ISD::VBROADCAST_LOAD)
- return false;
-
- // Only 32 and 64 bit broadcasts are supported.
- auto *MemIntr = cast<MemIntrinsicSDNode>(L);
- unsigned Size = MemIntr->getMemoryVT().getSizeInBits();
- if (Size != 32 && Size != 64)
- return false;
-
- return tryFoldBroadcast(Root, P, L, Base, Scale, Index, Disp, Segment);
- };
-
- bool FoldedLoad = false;
- SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
- if (tryFoldLoadOrBCast(Root, ParentBC, C, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
- FoldedLoad = true;
- } else if (tryFoldLoadOrBCast(Root, ParentA, A, Tmp0, Tmp1, Tmp2, Tmp3,
- Tmp4)) {
- FoldedLoad = true;
- std::swap(A, C);
- // Swap bits 1/4 and 3/6.
- uint8_t OldImm = Imm;
- Imm = OldImm & 0xa5;
- if (OldImm & 0x02) Imm |= 0x10;
- if (OldImm & 0x10) Imm |= 0x02;
- if (OldImm & 0x08) Imm |= 0x40;
- if (OldImm & 0x40) Imm |= 0x08;
- } else if (tryFoldLoadOrBCast(Root, ParentBC, B, Tmp0, Tmp1, Tmp2, Tmp3,
- Tmp4)) {
- FoldedLoad = true;
- std::swap(B, C);
- // Swap bits 1/2 and 5/6.
- uint8_t OldImm = Imm;
- Imm = OldImm & 0x99;
- if (OldImm & 0x02) Imm |= 0x04;
- if (OldImm & 0x04) Imm |= 0x02;
- if (OldImm & 0x20) Imm |= 0x40;
- if (OldImm & 0x40) Imm |= 0x20;
- }
-
- SDLoc DL(Root);
-
- SDValue TImm = CurDAG->getTargetConstant(Imm, DL, MVT::i8);
-
- MVT NVT = Root->getSimpleValueType(0);
-
- MachineSDNode *MNode;
- if (FoldedLoad) {
- SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
-
- unsigned Opc;
- if (C.getOpcode() == X86ISD::VBROADCAST_LOAD) {
- auto *MemIntr = cast<MemIntrinsicSDNode>(C);
- unsigned EltSize = MemIntr->getMemoryVT().getSizeInBits();
- assert((EltSize == 32 || EltSize == 64) && "Unexpected broadcast size!");
-
- bool UseD = EltSize == 32;
- if (NVT.is128BitVector())
- Opc = UseD ? X86::VPTERNLOGDZ128rmbi : X86::VPTERNLOGQZ128rmbi;
- else if (NVT.is256BitVector())
- Opc = UseD ? X86::VPTERNLOGDZ256rmbi : X86::VPTERNLOGQZ256rmbi;
- else if (NVT.is512BitVector())
- Opc = UseD ? X86::VPTERNLOGDZrmbi : X86::VPTERNLOGQZrmbi;
- else
- llvm_unreachable("Unexpected vector size!");
- } else {
- bool UseD = NVT.getVectorElementType() == MVT::i32;
- if (NVT.is128BitVector())
- Opc = UseD ? X86::VPTERNLOGDZ128rmi : X86::VPTERNLOGQZ128rmi;
- else if (NVT.is256BitVector())
- Opc = UseD ? X86::VPTERNLOGDZ256rmi : X86::VPTERNLOGQZ256rmi;
- else if (NVT.is512BitVector())
- Opc = UseD ? X86::VPTERNLOGDZrmi : X86::VPTERNLOGQZrmi;
- else
- llvm_unreachable("Unexpected vector size!");
- }
-
- SDValue Ops[] = {A, B, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, TImm, C.getOperand(0)};
- MNode = CurDAG->getMachineNode(Opc, DL, VTs, Ops);
-
- // Update the chain.
- ReplaceUses(C.getValue(1), SDValue(MNode, 1));
- // Record the mem-refs
- CurDAG->setNodeMemRefs(MNode, {cast<MemSDNode>(C)->getMemOperand()});
- } else {
- bool UseD = NVT.getVectorElementType() == MVT::i32;
- unsigned Opc;
- if (NVT.is128BitVector())
- Opc = UseD ? X86::VPTERNLOGDZ128rri : X86::VPTERNLOGQZ128rri;
- else if (NVT.is256BitVector())
- Opc = UseD ? X86::VPTERNLOGDZ256rri : X86::VPTERNLOGQZ256rri;
- else if (NVT.is512BitVector())
- Opc = UseD ? X86::VPTERNLOGDZrri : X86::VPTERNLOGQZrri;
- else
- llvm_unreachable("Unexpected vector size!");
-
- MNode = CurDAG->getMachineNode(Opc, DL, NVT, {A, B, C, TImm});
- }
-
- ReplaceUses(SDValue(Root, 0), SDValue(MNode, 0));
- CurDAG->RemoveDeadNode(Root);
- return true;
-}
-
+bool X86DAGToDAGISel::matchVPTERNLOG(SDNode *Root, SDNode *ParentA,
+ SDNode *ParentBC, SDValue A, SDValue B,
+ SDValue C, uint8_t Imm) {
+ assert(A.isOperandOf(ParentA));
+ assert(B.isOperandOf(ParentBC));
+ assert(C.isOperandOf(ParentBC));
+
+ auto tryFoldLoadOrBCast =
+ [this](SDNode *Root, SDNode *P, SDValue &L, SDValue &Base, SDValue &Scale,
+ SDValue &Index, SDValue &Disp, SDValue &Segment) {
+ if (tryFoldLoad(Root, P, L, Base, Scale, Index, Disp, Segment))
+ return true;
+
+ // Not a load, check for broadcast which may be behind a bitcast.
+ if (L.getOpcode() == ISD::BITCAST && L.hasOneUse()) {
+ P = L.getNode();
+ L = L.getOperand(0);
+ }
+
+ if (L.getOpcode() != X86ISD::VBROADCAST_LOAD)
+ return false;
+
+ // Only 32 and 64 bit broadcasts are supported.
+ auto *MemIntr = cast<MemIntrinsicSDNode>(L);
+ unsigned Size = MemIntr->getMemoryVT().getSizeInBits();
+ if (Size != 32 && Size != 64)
+ return false;
+
+ return tryFoldBroadcast(Root, P, L, Base, Scale, Index, Disp, Segment);
+ };
+
+ bool FoldedLoad = false;
+ SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
+ if (tryFoldLoadOrBCast(Root, ParentBC, C, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
+ FoldedLoad = true;
+ } else if (tryFoldLoadOrBCast(Root, ParentA, A, Tmp0, Tmp1, Tmp2, Tmp3,
+ Tmp4)) {
+ FoldedLoad = true;
+ std::swap(A, C);
+ // Swap bits 1/4 and 3/6.
+ uint8_t OldImm = Imm;
+ Imm = OldImm & 0xa5;
+ if (OldImm & 0x02) Imm |= 0x10;
+ if (OldImm & 0x10) Imm |= 0x02;
+ if (OldImm & 0x08) Imm |= 0x40;
+ if (OldImm & 0x40) Imm |= 0x08;
+ } else if (tryFoldLoadOrBCast(Root, ParentBC, B, Tmp0, Tmp1, Tmp2, Tmp3,
+ Tmp4)) {
+ FoldedLoad = true;
+ std::swap(B, C);
+ // Swap bits 1/2 and 5/6.
+ uint8_t OldImm = Imm;
+ Imm = OldImm & 0x99;
+ if (OldImm & 0x02) Imm |= 0x04;
+ if (OldImm & 0x04) Imm |= 0x02;
+ if (OldImm & 0x20) Imm |= 0x40;
+ if (OldImm & 0x40) Imm |= 0x20;
+ }
+
+ SDLoc DL(Root);
+
+ SDValue TImm = CurDAG->getTargetConstant(Imm, DL, MVT::i8);
+
+ MVT NVT = Root->getSimpleValueType(0);
+
+ MachineSDNode *MNode;
+ if (FoldedLoad) {
+ SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
+
+ unsigned Opc;
+ if (C.getOpcode() == X86ISD::VBROADCAST_LOAD) {
+ auto *MemIntr = cast<MemIntrinsicSDNode>(C);
+ unsigned EltSize = MemIntr->getMemoryVT().getSizeInBits();
+ assert((EltSize == 32 || EltSize == 64) && "Unexpected broadcast size!");
+
+ bool UseD = EltSize == 32;
+ if (NVT.is128BitVector())
+ Opc = UseD ? X86::VPTERNLOGDZ128rmbi : X86::VPTERNLOGQZ128rmbi;
+ else if (NVT.is256BitVector())
+ Opc = UseD ? X86::VPTERNLOGDZ256rmbi : X86::VPTERNLOGQZ256rmbi;
+ else if (NVT.is512BitVector())
+ Opc = UseD ? X86::VPTERNLOGDZrmbi : X86::VPTERNLOGQZrmbi;
+ else
+ llvm_unreachable("Unexpected vector size!");
+ } else {
+ bool UseD = NVT.getVectorElementType() == MVT::i32;
+ if (NVT.is128BitVector())
+ Opc = UseD ? X86::VPTERNLOGDZ128rmi : X86::VPTERNLOGQZ128rmi;
+ else if (NVT.is256BitVector())
+ Opc = UseD ? X86::VPTERNLOGDZ256rmi : X86::VPTERNLOGQZ256rmi;
+ else if (NVT.is512BitVector())
+ Opc = UseD ? X86::VPTERNLOGDZrmi : X86::VPTERNLOGQZrmi;
+ else
+ llvm_unreachable("Unexpected vector size!");
+ }
+
+ SDValue Ops[] = {A, B, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, TImm, C.getOperand(0)};
+ MNode = CurDAG->getMachineNode(Opc, DL, VTs, Ops);
+
+ // Update the chain.
+ ReplaceUses(C.getValue(1), SDValue(MNode, 1));
+ // Record the mem-refs
+ CurDAG->setNodeMemRefs(MNode, {cast<MemSDNode>(C)->getMemOperand()});
+ } else {
+ bool UseD = NVT.getVectorElementType() == MVT::i32;
+ unsigned Opc;
+ if (NVT.is128BitVector())
+ Opc = UseD ? X86::VPTERNLOGDZ128rri : X86::VPTERNLOGQZ128rri;
+ else if (NVT.is256BitVector())
+ Opc = UseD ? X86::VPTERNLOGDZ256rri : X86::VPTERNLOGQZ256rri;
+ else if (NVT.is512BitVector())
+ Opc = UseD ? X86::VPTERNLOGDZrri : X86::VPTERNLOGQZrri;
+ else
+ llvm_unreachable("Unexpected vector size!");
+
+ MNode = CurDAG->getMachineNode(Opc, DL, NVT, {A, B, C, TImm});
+ }
+
+ ReplaceUses(SDValue(Root, 0), SDValue(MNode, 0));
+ CurDAG->RemoveDeadNode(Root);
+ return true;
+}
+
// Try to match two logic ops to a VPTERNLOG.
// FIXME: Handle inverted inputs?
// FIXME: Handle more complex patterns that use an operand more than once?
@@ -4160,62 +4160,62 @@ bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
- auto getFoldableLogicOp = [](SDValue Op) {
- // Peek through single use bitcast.
- if (Op.getOpcode() == ISD::BITCAST && Op.hasOneUse())
- Op = Op.getOperand(0);
-
- if (!Op.hasOneUse())
- return SDValue();
-
- unsigned Opc = Op.getOpcode();
- if (Opc == ISD::AND || Opc == ISD::OR || Opc == ISD::XOR ||
- Opc == X86ISD::ANDNP)
- return Op;
-
- return SDValue();
+ auto getFoldableLogicOp = [](SDValue Op) {
+ // Peek through single use bitcast.
+ if (Op.getOpcode() == ISD::BITCAST && Op.hasOneUse())
+ Op = Op.getOperand(0);
+
+ if (!Op.hasOneUse())
+ return SDValue();
+
+ unsigned Opc = Op.getOpcode();
+ if (Opc == ISD::AND || Opc == ISD::OR || Opc == ISD::XOR ||
+ Opc == X86ISD::ANDNP)
+ return Op;
+
+ return SDValue();
};
- SDValue A, FoldableOp;
- if ((FoldableOp = getFoldableLogicOp(N1))) {
+ SDValue A, FoldableOp;
+ if ((FoldableOp = getFoldableLogicOp(N1))) {
A = N0;
- } else if ((FoldableOp = getFoldableLogicOp(N0))) {
+ } else if ((FoldableOp = getFoldableLogicOp(N0))) {
A = N1;
} else
return false;
- SDValue B = FoldableOp.getOperand(0);
- SDValue C = FoldableOp.getOperand(1);
-
- // We can build the appropriate control immediate by performing the logic
- // operation we're matching using these constants for A, B, and C.
- const uint8_t TernlogMagicA = 0xf0;
- const uint8_t TernlogMagicB = 0xcc;
- const uint8_t TernlogMagicC = 0xaa;
-
- uint8_t Imm;
- switch (FoldableOp.getOpcode()) {
+ SDValue B = FoldableOp.getOperand(0);
+ SDValue C = FoldableOp.getOperand(1);
+
+ // We can build the appropriate control immediate by performing the logic
+ // operation we're matching using these constants for A, B, and C.
+ const uint8_t TernlogMagicA = 0xf0;
+ const uint8_t TernlogMagicB = 0xcc;
+ const uint8_t TernlogMagicC = 0xaa;
+
+ uint8_t Imm;
+ switch (FoldableOp.getOpcode()) {
+ default: llvm_unreachable("Unexpected opcode!");
+ case ISD::AND: Imm = TernlogMagicB & TernlogMagicC; break;
+ case ISD::OR: Imm = TernlogMagicB | TernlogMagicC; break;
+ case ISD::XOR: Imm = TernlogMagicB ^ TernlogMagicC; break;
+ case X86ISD::ANDNP: Imm = ~(TernlogMagicB) & TernlogMagicC; break;
+ }
+
+ switch (N->getOpcode()) {
default: llvm_unreachable("Unexpected opcode!");
- case ISD::AND: Imm = TernlogMagicB & TernlogMagicC; break;
- case ISD::OR: Imm = TernlogMagicB | TernlogMagicC; break;
- case ISD::XOR: Imm = TernlogMagicB ^ TernlogMagicC; break;
- case X86ISD::ANDNP: Imm = ~(TernlogMagicB) & TernlogMagicC; break;
- }
-
- switch (N->getOpcode()) {
- default: llvm_unreachable("Unexpected opcode!");
- case X86ISD::ANDNP:
- if (A == N0)
- Imm &= ~TernlogMagicA;
- else
- Imm = ~(Imm) & TernlogMagicA;
+ case X86ISD::ANDNP:
+ if (A == N0)
+ Imm &= ~TernlogMagicA;
+ else
+ Imm = ~(Imm) & TernlogMagicA;
break;
- case ISD::AND: Imm &= TernlogMagicA; break;
- case ISD::OR: Imm |= TernlogMagicA; break;
- case ISD::XOR: Imm ^= TernlogMagicA; break;
+ case ISD::AND: Imm &= TernlogMagicA; break;
+ case ISD::OR: Imm |= TernlogMagicA; break;
+ case ISD::XOR: Imm ^= TernlogMagicA; break;
}
- return matchVPTERNLOG(N, N, FoldableOp.getNode(), A, B, C, Imm);
+ return matchVPTERNLOG(N, N, FoldableOp.getNode(), A, B, C, Imm);
}
/// If the high bits of an 'and' operand are known zero, try setting the
@@ -4282,7 +4282,7 @@ bool X86DAGToDAGISel::shrinkAndImmediate(SDNode *And) {
// A negative mask allows a smaller encoding. Create a new 'and' node.
SDValue NewMask = CurDAG->getConstant(NegMaskVal, SDLoc(And), VT);
- insertDAGNode(*CurDAG, SDValue(And, 0), NewMask);
+ insertDAGNode(*CurDAG, SDValue(And, 0), NewMask);
SDValue NewAnd = CurDAG->getNode(ISD::AND, SDLoc(And), VT, And0, NewMask);
ReplaceNode(And, NewAnd.getNode());
SelectCode(NewAnd.getNode());
@@ -4316,15 +4316,15 @@ VPTESTM_CASE(v16i16, WZ256##SUFFIX) \
VPTESTM_CASE(v64i8, BZ##SUFFIX) \
VPTESTM_CASE(v32i16, WZ##SUFFIX)
- if (FoldedBCast) {
+ if (FoldedBCast) {
switch (TestVT.SimpleTy) {
- VPTESTM_BROADCAST_CASES(rmb)
+ VPTESTM_BROADCAST_CASES(rmb)
}
}
- if (FoldedLoad) {
+ if (FoldedLoad) {
switch (TestVT.SimpleTy) {
- VPTESTM_FULL_CASES(rm)
+ VPTESTM_FULL_CASES(rm)
}
}
@@ -4383,56 +4383,56 @@ bool X86DAGToDAGISel::tryVPTESTM(SDNode *Root, SDValue Setcc,
}
}
- // Without VLX we need to widen the operation.
+ // Without VLX we need to widen the operation.
bool Widen = !Subtarget->hasVLX() && !CmpVT.is512BitVector();
- auto tryFoldLoadOrBCast = [&](SDNode *Root, SDNode *P, SDValue &L,
- SDValue &Base, SDValue &Scale, SDValue &Index,
- SDValue &Disp, SDValue &Segment) {
- // If we need to widen, we can't fold the load.
- if (!Widen)
- if (tryFoldLoad(Root, P, L, Base, Scale, Index, Disp, Segment))
- return true;
+ auto tryFoldLoadOrBCast = [&](SDNode *Root, SDNode *P, SDValue &L,
+ SDValue &Base, SDValue &Scale, SDValue &Index,
+ SDValue &Disp, SDValue &Segment) {
+ // If we need to widen, we can't fold the load.
+ if (!Widen)
+ if (tryFoldLoad(Root, P, L, Base, Scale, Index, Disp, Segment))
+ return true;
- // If we didn't fold a load, try to match broadcast. No widening limitation
- // for this. But only 32 and 64 bit types are supported.
- if (CmpSVT != MVT::i32 && CmpSVT != MVT::i64)
- return false;
+ // If we didn't fold a load, try to match broadcast. No widening limitation
+ // for this. But only 32 and 64 bit types are supported.
+ if (CmpSVT != MVT::i32 && CmpSVT != MVT::i64)
+ return false;
// Look through single use bitcasts.
- if (L.getOpcode() == ISD::BITCAST && L.hasOneUse()) {
- P = L.getNode();
- L = L.getOperand(0);
+ if (L.getOpcode() == ISD::BITCAST && L.hasOneUse()) {
+ P = L.getNode();
+ L = L.getOperand(0);
}
- if (L.getOpcode() != X86ISD::VBROADCAST_LOAD)
- return false;
+ if (L.getOpcode() != X86ISD::VBROADCAST_LOAD)
+ return false;
+
+ auto *MemIntr = cast<MemIntrinsicSDNode>(L);
+ if (MemIntr->getMemoryVT().getSizeInBits() != CmpSVT.getSizeInBits())
+ return false;
- auto *MemIntr = cast<MemIntrinsicSDNode>(L);
- if (MemIntr->getMemoryVT().getSizeInBits() != CmpSVT.getSizeInBits())
- return false;
-
- return tryFoldBroadcast(Root, P, L, Base, Scale, Index, Disp, Segment);
+ return tryFoldBroadcast(Root, P, L, Base, Scale, Index, Disp, Segment);
};
- // We can only fold loads if the sources are unique.
- bool CanFoldLoads = Src0 != Src1;
-
- bool FoldedLoad = false;
- SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
- if (CanFoldLoads) {
- FoldedLoad = tryFoldLoadOrBCast(Root, N0.getNode(), Src1, Tmp0, Tmp1, Tmp2,
- Tmp3, Tmp4);
- if (!FoldedLoad) {
- // And is commutative.
- FoldedLoad = tryFoldLoadOrBCast(Root, N0.getNode(), Src0, Tmp0, Tmp1,
- Tmp2, Tmp3, Tmp4);
- if (FoldedLoad)
- std::swap(Src0, Src1);
+ // We can only fold loads if the sources are unique.
+ bool CanFoldLoads = Src0 != Src1;
+
+ bool FoldedLoad = false;
+ SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
+ if (CanFoldLoads) {
+ FoldedLoad = tryFoldLoadOrBCast(Root, N0.getNode(), Src1, Tmp0, Tmp1, Tmp2,
+ Tmp3, Tmp4);
+ if (!FoldedLoad) {
+ // And is commutative.
+ FoldedLoad = tryFoldLoadOrBCast(Root, N0.getNode(), Src0, Tmp0, Tmp1,
+ Tmp2, Tmp3, Tmp4);
+ if (FoldedLoad)
+ std::swap(Src0, Src1);
}
}
- bool FoldedBCast = FoldedLoad && Src1.getOpcode() == X86ISD::VBROADCAST_LOAD;
+ bool FoldedBCast = FoldedLoad && Src1.getOpcode() == X86ISD::VBROADCAST_LOAD;
bool IsMasked = InMask.getNode() != nullptr;
@@ -4456,7 +4456,7 @@ bool X86DAGToDAGISel::tryVPTESTM(SDNode *Root, SDValue Setcc,
if (IsMasked) {
// Widen the mask.
- unsigned RegClass = TLI->getRegClassFor(MaskVT)->getID();
+ unsigned RegClass = TLI->getRegClassFor(MaskVT)->getID();
SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
InMask = SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
dl, MaskVT, InMask, RC), 0);
@@ -4468,23 +4468,23 @@ bool X86DAGToDAGISel::tryVPTESTM(SDNode *Root, SDValue Setcc,
IsMasked);
MachineSDNode *CNode;
- if (FoldedLoad) {
+ if (FoldedLoad) {
SDVTList VTs = CurDAG->getVTList(MaskVT, MVT::Other);
if (IsMasked) {
SDValue Ops[] = { InMask, Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
- Src1.getOperand(0) };
+ Src1.getOperand(0) };
CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops);
} else {
SDValue Ops[] = { Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
- Src1.getOperand(0) };
+ Src1.getOperand(0) };
CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops);
}
// Update the chain.
- ReplaceUses(Src1.getValue(1), SDValue(CNode, 1));
+ ReplaceUses(Src1.getValue(1), SDValue(CNode, 1));
// Record the mem-refs
- CurDAG->setNodeMemRefs(CNode, {cast<MemSDNode>(Src1)->getMemOperand()});
+ CurDAG->setNodeMemRefs(CNode, {cast<MemSDNode>(Src1)->getMemOperand()});
} else {
if (IsMasked)
CNode = CurDAG->getMachineNode(Opc, dl, MaskVT, InMask, Src0, Src1);
@@ -4494,7 +4494,7 @@ bool X86DAGToDAGISel::tryVPTESTM(SDNode *Root, SDValue Setcc,
// If we widened, we need to shrink the mask VT.
if (Widen) {
- unsigned RegClass = TLI->getRegClassFor(ResVT)->getID();
+ unsigned RegClass = TLI->getRegClassFor(ResVT)->getID();
SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
CNode = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
dl, ResVT, SDValue(CNode, 0), RC);
@@ -4550,9 +4550,9 @@ bool X86DAGToDAGISel::tryMatchBitSelect(SDNode *N) {
SDValue Imm = CurDAG->getTargetConstant(0xCA, dl, MVT::i8);
SDValue Ternlog = CurDAG->getNode(X86ISD::VPTERNLOG, dl, NVT, A, B, C, Imm);
ReplaceNode(N, Ternlog.getNode());
-
- return matchVPTERNLOG(Ternlog.getNode(), Ternlog.getNode(), Ternlog.getNode(),
- A, B, C, 0xCA);
+
+ return matchVPTERNLOG(Ternlog.getNode(), Ternlog.getNode(), Ternlog.getNode(),
+ A, B, C, 0xCA);
}
void X86DAGToDAGISel::Select(SDNode *Node) {
@@ -4568,95 +4568,95 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
switch (Opcode) {
default: break;
- case ISD::INTRINSIC_W_CHAIN: {
- unsigned IntNo = Node->getConstantOperandVal(1);
- switch (IntNo) {
- default: break;
- case Intrinsic::x86_encodekey128:
- case Intrinsic::x86_encodekey256: {
- if (!Subtarget->hasKL())
- break;
-
- unsigned Opcode;
- switch (IntNo) {
- default: llvm_unreachable("Impossible intrinsic");
- case Intrinsic::x86_encodekey128: Opcode = X86::ENCODEKEY128; break;
- case Intrinsic::x86_encodekey256: Opcode = X86::ENCODEKEY256; break;
- }
-
- SDValue Chain = Node->getOperand(0);
- Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0, Node->getOperand(3),
- SDValue());
- if (Opcode == X86::ENCODEKEY256)
- Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1, Node->getOperand(4),
- Chain.getValue(1));
-
- MachineSDNode *Res = CurDAG->getMachineNode(
- Opcode, dl, Node->getVTList(),
- {Node->getOperand(2), Chain, Chain.getValue(1)});
- ReplaceNode(Node, Res);
- return;
- }
- case Intrinsic::x86_tileloadd64_internal: {
- if (!Subtarget->hasAMXTILE())
- break;
- unsigned Opc = X86::PTILELOADDV;
- // _tile_loadd_internal(row, col, buf, STRIDE)
- SDValue Base = Node->getOperand(4);
- SDValue Scale = getI8Imm(1, dl);
- SDValue Index = Node->getOperand(5);
- SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
- SDValue Segment = CurDAG->getRegister(0, MVT::i16);
- SDValue CFG = CurDAG->getRegister(0, MVT::Untyped);
- SDValue Chain = Node->getOperand(0);
- MachineSDNode *CNode;
- SDValue Ops[] = {Node->getOperand(2),
- Node->getOperand(3),
- Base,
- Scale,
- Index,
- Disp,
- Segment,
- CFG,
- Chain};
- CNode = CurDAG->getMachineNode(Opc, dl, {MVT::x86amx, MVT::Other}, Ops);
- ReplaceNode(Node, CNode);
- return;
- }
- case Intrinsic::x86_tdpbssd_internal: {
- if (!Subtarget->hasAMXTILE())
- break;
- SDValue Chain = Node->getOperand(0);
- unsigned Opc = X86::PTDPBSSDV;
- SDValue CFG = CurDAG->getRegister(0, MVT::Untyped);
- SDValue Ops[] = {Node->getOperand(2),
- Node->getOperand(3),
- Node->getOperand(4),
- Node->getOperand(5),
- Node->getOperand(6),
- Node->getOperand(7),
- CFG,
- Chain};
- MachineSDNode *CNode =
- CurDAG->getMachineNode(Opc, dl, {MVT::x86amx, MVT::Other}, Ops);
- ReplaceNode(Node, CNode);
- return;
- }
- case Intrinsic::x86_tilezero_internal: {
- if (!Subtarget->hasAMXTILE())
- break;
- unsigned Opc = X86::PTILEZEROV;
- SDValue Chain = Node->getOperand(0);
- SDValue CFG = CurDAG->getRegister(0, MVT::Untyped);
- SDValue Ops[] = {Node->getOperand(2), Node->getOperand(3), CFG, Chain};
- MachineSDNode *CNode =
- CurDAG->getMachineNode(Opc, dl, {MVT::x86amx, MVT::Other}, Ops);
- ReplaceNode(Node, CNode);
- return;
- }
- }
- break;
- }
+ case ISD::INTRINSIC_W_CHAIN: {
+ unsigned IntNo = Node->getConstantOperandVal(1);
+ switch (IntNo) {
+ default: break;
+ case Intrinsic::x86_encodekey128:
+ case Intrinsic::x86_encodekey256: {
+ if (!Subtarget->hasKL())
+ break;
+
+ unsigned Opcode;
+ switch (IntNo) {
+ default: llvm_unreachable("Impossible intrinsic");
+ case Intrinsic::x86_encodekey128: Opcode = X86::ENCODEKEY128; break;
+ case Intrinsic::x86_encodekey256: Opcode = X86::ENCODEKEY256; break;
+ }
+
+ SDValue Chain = Node->getOperand(0);
+ Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0, Node->getOperand(3),
+ SDValue());
+ if (Opcode == X86::ENCODEKEY256)
+ Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1, Node->getOperand(4),
+ Chain.getValue(1));
+
+ MachineSDNode *Res = CurDAG->getMachineNode(
+ Opcode, dl, Node->getVTList(),
+ {Node->getOperand(2), Chain, Chain.getValue(1)});
+ ReplaceNode(Node, Res);
+ return;
+ }
+ case Intrinsic::x86_tileloadd64_internal: {
+ if (!Subtarget->hasAMXTILE())
+ break;
+ unsigned Opc = X86::PTILELOADDV;
+ // _tile_loadd_internal(row, col, buf, STRIDE)
+ SDValue Base = Node->getOperand(4);
+ SDValue Scale = getI8Imm(1, dl);
+ SDValue Index = Node->getOperand(5);
+ SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
+ SDValue Segment = CurDAG->getRegister(0, MVT::i16);
+ SDValue CFG = CurDAG->getRegister(0, MVT::Untyped);
+ SDValue Chain = Node->getOperand(0);
+ MachineSDNode *CNode;
+ SDValue Ops[] = {Node->getOperand(2),
+ Node->getOperand(3),
+ Base,
+ Scale,
+ Index,
+ Disp,
+ Segment,
+ CFG,
+ Chain};
+ CNode = CurDAG->getMachineNode(Opc, dl, {MVT::x86amx, MVT::Other}, Ops);
+ ReplaceNode(Node, CNode);
+ return;
+ }
+ case Intrinsic::x86_tdpbssd_internal: {
+ if (!Subtarget->hasAMXTILE())
+ break;
+ SDValue Chain = Node->getOperand(0);
+ unsigned Opc = X86::PTDPBSSDV;
+ SDValue CFG = CurDAG->getRegister(0, MVT::Untyped);
+ SDValue Ops[] = {Node->getOperand(2),
+ Node->getOperand(3),
+ Node->getOperand(4),
+ Node->getOperand(5),
+ Node->getOperand(6),
+ Node->getOperand(7),
+ CFG,
+ Chain};
+ MachineSDNode *CNode =
+ CurDAG->getMachineNode(Opc, dl, {MVT::x86amx, MVT::Other}, Ops);
+ ReplaceNode(Node, CNode);
+ return;
+ }
+ case Intrinsic::x86_tilezero_internal: {
+ if (!Subtarget->hasAMXTILE())
+ break;
+ unsigned Opc = X86::PTILEZEROV;
+ SDValue Chain = Node->getOperand(0);
+ SDValue CFG = CurDAG->getRegister(0, MVT::Untyped);
+ SDValue Ops[] = {Node->getOperand(2), Node->getOperand(3), CFG, Chain};
+ MachineSDNode *CNode =
+ CurDAG->getMachineNode(Opc, dl, {MVT::x86amx, MVT::Other}, Ops);
+ ReplaceNode(Node, CNode);
+ return;
+ }
+ }
+ break;
+ }
case ISD::INTRINSIC_VOID: {
unsigned IntNo = Node->getConstantOperandVal(1);
switch (IntNo) {
@@ -4711,31 +4711,31 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
break;
}
- case Intrinsic::x86_tilestored64_internal: {
- unsigned Opc = X86::PTILESTOREDV;
- // _tile_stored_internal(row, col, buf, STRIDE, c)
- SDValue Base = Node->getOperand(4);
- SDValue Scale = getI8Imm(1, dl);
- SDValue Index = Node->getOperand(5);
- SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
- SDValue Segment = CurDAG->getRegister(0, MVT::i16);
- SDValue CFG = CurDAG->getRegister(0, MVT::Untyped);
- SDValue Chain = Node->getOperand(0);
- MachineSDNode *CNode;
- SDValue Ops[] = {Node->getOperand(2),
- Node->getOperand(3),
- Base,
- Scale,
- Index,
- Disp,
- Segment,
- Node->getOperand(6),
- CFG,
- Chain};
- CNode = CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops);
- ReplaceNode(Node, CNode);
- return;
- }
+ case Intrinsic::x86_tilestored64_internal: {
+ unsigned Opc = X86::PTILESTOREDV;
+ // _tile_stored_internal(row, col, buf, STRIDE, c)
+ SDValue Base = Node->getOperand(4);
+ SDValue Scale = getI8Imm(1, dl);
+ SDValue Index = Node->getOperand(5);
+ SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
+ SDValue Segment = CurDAG->getRegister(0, MVT::i16);
+ SDValue CFG = CurDAG->getRegister(0, MVT::Untyped);
+ SDValue Chain = Node->getOperand(0);
+ MachineSDNode *CNode;
+ SDValue Ops[] = {Node->getOperand(2),
+ Node->getOperand(3),
+ Base,
+ Scale,
+ Index,
+ Disp,
+ Segment,
+ Node->getOperand(6),
+ CFG,
+ Chain};
+ CNode = CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops);
+ ReplaceNode(Node, CNode);
+ return;
+ }
case Intrinsic::x86_tileloadd64:
case Intrinsic::x86_tileloaddt164:
case Intrinsic::x86_tilestored64: {
@@ -4816,19 +4816,19 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
return;
break;
- case X86ISD::VPTERNLOG: {
- uint8_t Imm = cast<ConstantSDNode>(Node->getOperand(3))->getZExtValue();
- if (matchVPTERNLOG(Node, Node, Node, Node->getOperand(0),
- Node->getOperand(1), Node->getOperand(2), Imm))
- return;
- break;
- }
-
- case X86ISD::ANDNP:
- if (tryVPTERNLOG(Node))
- return;
- break;
-
+ case X86ISD::VPTERNLOG: {
+ uint8_t Imm = cast<ConstantSDNode>(Node->getOperand(3))->getZExtValue();
+ if (matchVPTERNLOG(Node, Node, Node, Node->getOperand(0),
+ Node->getOperand(1), Node->getOperand(2), Imm))
+ return;
+ break;
+ }
+
+ case X86ISD::ANDNP:
+ if (tryVPTERNLOG(Node))
+ return;
+ break;
+
case ISD::AND:
if (NVT.isVector() && NVT.getVectorElementType() == MVT::i1) {
// Try to form a masked VPTESTM. Operands can be in either order.
@@ -5927,63 +5927,63 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
CurDAG->RemoveDeadNode(Node);
return;
}
- case X86ISD::AESENCWIDE128KL:
- case X86ISD::AESDECWIDE128KL:
- case X86ISD::AESENCWIDE256KL:
- case X86ISD::AESDECWIDE256KL: {
- if (!Subtarget->hasWIDEKL())
- break;
-
- unsigned Opcode;
- switch (Node->getOpcode()) {
- default:
- llvm_unreachable("Unexpected opcode!");
- case X86ISD::AESENCWIDE128KL:
- Opcode = X86::AESENCWIDE128KL;
- break;
- case X86ISD::AESDECWIDE128KL:
- Opcode = X86::AESDECWIDE128KL;
- break;
- case X86ISD::AESENCWIDE256KL:
- Opcode = X86::AESENCWIDE256KL;
- break;
- case X86ISD::AESDECWIDE256KL:
- Opcode = X86::AESDECWIDE256KL;
- break;
- }
-
- SDValue Chain = Node->getOperand(0);
- SDValue Addr = Node->getOperand(1);
-
- SDValue Base, Scale, Index, Disp, Segment;
- if (!selectAddr(Node, Addr, Base, Scale, Index, Disp, Segment))
- break;
-
- Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0, Node->getOperand(2),
- SDValue());
- Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1, Node->getOperand(3),
- Chain.getValue(1));
- Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM2, Node->getOperand(4),
- Chain.getValue(1));
- Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM3, Node->getOperand(5),
- Chain.getValue(1));
- Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM4, Node->getOperand(6),
- Chain.getValue(1));
- Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM5, Node->getOperand(7),
- Chain.getValue(1));
- Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM6, Node->getOperand(8),
- Chain.getValue(1));
- Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM7, Node->getOperand(9),
- Chain.getValue(1));
-
- MachineSDNode *Res = CurDAG->getMachineNode(
- Opcode, dl, Node->getVTList(),
- {Base, Scale, Index, Disp, Segment, Chain, Chain.getValue(1)});
- CurDAG->setNodeMemRefs(Res, cast<MemSDNode>(Node)->getMemOperand());
- ReplaceNode(Node, Res);
- return;
+ case X86ISD::AESENCWIDE128KL:
+ case X86ISD::AESDECWIDE128KL:
+ case X86ISD::AESENCWIDE256KL:
+ case X86ISD::AESDECWIDE256KL: {
+ if (!Subtarget->hasWIDEKL())
+ break;
+
+ unsigned Opcode;
+ switch (Node->getOpcode()) {
+ default:
+ llvm_unreachable("Unexpected opcode!");
+ case X86ISD::AESENCWIDE128KL:
+ Opcode = X86::AESENCWIDE128KL;
+ break;
+ case X86ISD::AESDECWIDE128KL:
+ Opcode = X86::AESDECWIDE128KL;
+ break;
+ case X86ISD::AESENCWIDE256KL:
+ Opcode = X86::AESENCWIDE256KL;
+ break;
+ case X86ISD::AESDECWIDE256KL:
+ Opcode = X86::AESDECWIDE256KL;
+ break;
+ }
+
+ SDValue Chain = Node->getOperand(0);
+ SDValue Addr = Node->getOperand(1);
+
+ SDValue Base, Scale, Index, Disp, Segment;
+ if (!selectAddr(Node, Addr, Base, Scale, Index, Disp, Segment))
+ break;
+
+ Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0, Node->getOperand(2),
+ SDValue());
+ Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1, Node->getOperand(3),
+ Chain.getValue(1));
+ Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM2, Node->getOperand(4),
+ Chain.getValue(1));
+ Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM3, Node->getOperand(5),
+ Chain.getValue(1));
+ Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM4, Node->getOperand(6),
+ Chain.getValue(1));
+ Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM5, Node->getOperand(7),
+ Chain.getValue(1));
+ Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM6, Node->getOperand(8),
+ Chain.getValue(1));
+ Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM7, Node->getOperand(9),
+ Chain.getValue(1));
+
+ MachineSDNode *Res = CurDAG->getMachineNode(
+ Opcode, dl, Node->getVTList(),
+ {Base, Scale, Index, Disp, Segment, Chain, Chain.getValue(1)});
+ CurDAG->setNodeMemRefs(Res, cast<MemSDNode>(Node)->getMemOperand());
+ ReplaceNode(Node, Res);
+ return;
+ }
}
- }
SelectCode(Node);
}
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86ISelLowering.cpp b/contrib/libs/llvm12/lib/Target/X86/X86ISelLowering.cpp
index c1320facd0..1e2407c7e7 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86ISelLowering.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86ISelLowering.cpp
@@ -35,7 +35,7 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
-#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
@@ -77,14 +77,14 @@ static cl::opt<int> ExperimentalPrefLoopAlignment(
" of the loop header PC will be 0)."),
cl::Hidden);
-static cl::opt<int> ExperimentalPrefInnermostLoopAlignment(
- "x86-experimental-pref-innermost-loop-alignment", cl::init(4),
- cl::desc(
- "Sets the preferable loop alignment for experiments (as log2 bytes) "
- "for innermost loops only. If specified, this option overrides "
- "alignment set by x86-experimental-pref-loop-alignment."),
- cl::Hidden);
-
+static cl::opt<int> ExperimentalPrefInnermostLoopAlignment(
+ "x86-experimental-pref-innermost-loop-alignment", cl::init(4),
+ cl::desc(
+ "Sets the preferable loop alignment for experiments (as log2 bytes) "
+ "for innermost loops only. If specified, this option overrides "
+ "alignment set by x86-experimental-pref-loop-alignment."),
+ cl::Hidden);
+
static cl::opt<bool> MulConstantOptimization(
"mul-constant-optimization", cl::init(true),
cl::desc("Replace 'mul x, Const' with more effective instructions like "
@@ -144,24 +144,24 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
addBypassSlowDiv(64, 32);
}
- // Setup Windows compiler runtime calls.
- if (Subtarget.isTargetWindowsMSVC() || Subtarget.isTargetWindowsItanium()) {
- static const struct {
- const RTLIB::Libcall Op;
- const char * const Name;
- const CallingConv::ID CC;
- } LibraryCalls[] = {
- { RTLIB::SDIV_I64, "_alldiv", CallingConv::X86_StdCall },
- { RTLIB::UDIV_I64, "_aulldiv", CallingConv::X86_StdCall },
- { RTLIB::SREM_I64, "_allrem", CallingConv::X86_StdCall },
- { RTLIB::UREM_I64, "_aullrem", CallingConv::X86_StdCall },
- { RTLIB::MUL_I64, "_allmul", CallingConv::X86_StdCall },
- };
-
- for (const auto &LC : LibraryCalls) {
- setLibcallName(LC.Op, LC.Name);
- setLibcallCallingConv(LC.Op, LC.CC);
- }
+ // Setup Windows compiler runtime calls.
+ if (Subtarget.isTargetWindowsMSVC() || Subtarget.isTargetWindowsItanium()) {
+ static const struct {
+ const RTLIB::Libcall Op;
+ const char * const Name;
+ const CallingConv::ID CC;
+ } LibraryCalls[] = {
+ { RTLIB::SDIV_I64, "_alldiv", CallingConv::X86_StdCall },
+ { RTLIB::UDIV_I64, "_aulldiv", CallingConv::X86_StdCall },
+ { RTLIB::SREM_I64, "_allrem", CallingConv::X86_StdCall },
+ { RTLIB::UREM_I64, "_aullrem", CallingConv::X86_StdCall },
+ { RTLIB::MUL_I64, "_allmul", CallingConv::X86_StdCall },
+ };
+
+ for (const auto &LC : LibraryCalls) {
+ setLibcallName(LC.Op, LC.Name);
+ setLibcallCallingConv(LC.Op, LC.CC);
+ }
}
if (Subtarget.getTargetTriple().isOSMSVCRT()) {
@@ -207,8 +207,8 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
if (Subtarget.hasCMov()) {
setOperationAction(ISD::ABS , MVT::i16 , Custom);
setOperationAction(ISD::ABS , MVT::i32 , Custom);
- if (Subtarget.is64Bit())
- setOperationAction(ISD::ABS , MVT::i64 , Custom);
+ if (Subtarget.is64Bit())
+ setOperationAction(ISD::ABS , MVT::i64 , Custom);
}
// Funnel shifts.
@@ -293,19 +293,19 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
}
}
- if (Subtarget.hasSSE2()) {
- // Custom lowering for saturating float to int conversions.
- // We handle promotion to larger result types manually.
- for (MVT VT : { MVT::i8, MVT::i16, MVT::i32 }) {
- setOperationAction(ISD::FP_TO_UINT_SAT, VT, Custom);
- setOperationAction(ISD::FP_TO_SINT_SAT, VT, Custom);
- }
- if (Subtarget.is64Bit()) {
- setOperationAction(ISD::FP_TO_UINT_SAT, MVT::i64, Custom);
- setOperationAction(ISD::FP_TO_SINT_SAT, MVT::i64, Custom);
- }
- }
-
+ if (Subtarget.hasSSE2()) {
+ // Custom lowering for saturating float to int conversions.
+ // We handle promotion to larger result types manually.
+ for (MVT VT : { MVT::i8, MVT::i16, MVT::i32 }) {
+ setOperationAction(ISD::FP_TO_UINT_SAT, VT, Custom);
+ setOperationAction(ISD::FP_TO_SINT_SAT, VT, Custom);
+ }
+ if (Subtarget.is64Bit()) {
+ setOperationAction(ISD::FP_TO_UINT_SAT, MVT::i64, Custom);
+ setOperationAction(ISD::FP_TO_SINT_SAT, MVT::i64, Custom);
+ }
+ }
+
// Handle address space casts between mixed sized pointers.
setOperationAction(ISD::ADDRSPACECAST, MVT::i32, Custom);
setOperationAction(ISD::ADDRSPACECAST, MVT::i64, Custom);
@@ -412,7 +412,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setTruncStoreAction(MVT::f80, MVT::f16, Expand);
setTruncStoreAction(MVT::f128, MVT::f16, Expand);
- setOperationAction(ISD::PARITY, MVT::i8, Custom);
+ setOperationAction(ISD::PARITY, MVT::i8, Custom);
if (Subtarget.hasPOPCNT()) {
setOperationPromotedToType(ISD::CTPOP, MVT::i8, MVT::i32);
} else {
@@ -423,11 +423,11 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::CTPOP , MVT::i64 , Expand);
else
setOperationAction(ISD::CTPOP , MVT::i64 , Custom);
-
- setOperationAction(ISD::PARITY, MVT::i16, Custom);
- setOperationAction(ISD::PARITY, MVT::i32, Custom);
- if (Subtarget.is64Bit())
- setOperationAction(ISD::PARITY, MVT::i64, Custom);
+
+ setOperationAction(ISD::PARITY, MVT::i16, Custom);
+ setOperationAction(ISD::PARITY, MVT::i32, Custom);
+ if (Subtarget.is64Bit())
+ setOperationAction(ISD::PARITY, MVT::i64, Custom);
}
setOperationAction(ISD::READCYCLECOUNTER , MVT::i64 , Custom);
@@ -521,7 +521,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::TRAP, MVT::Other, Legal);
setOperationAction(ISD::DEBUGTRAP, MVT::Other, Legal);
- setOperationAction(ISD::UBSANTRAP, MVT::Other, Legal);
+ setOperationAction(ISD::UBSANTRAP, MVT::Other, Legal);
// VASTART needs to be custom lowered to use the VarArgsFrameIndex
setOperationAction(ISD::VASTART , MVT::Other, Custom);
@@ -1114,8 +1114,8 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::STRICT_FRINT, RoundedTy, Legal);
setOperationAction(ISD::FNEARBYINT, RoundedTy, Legal);
setOperationAction(ISD::STRICT_FNEARBYINT, RoundedTy, Legal);
- setOperationAction(ISD::FROUNDEVEN, RoundedTy, Legal);
- setOperationAction(ISD::STRICT_FROUNDEVEN, RoundedTy, Legal);
+ setOperationAction(ISD::FROUNDEVEN, RoundedTy, Legal);
+ setOperationAction(ISD::STRICT_FROUNDEVEN, RoundedTy, Legal);
setOperationAction(ISD::FROUND, RoundedTy, Custom);
}
@@ -1129,8 +1129,8 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::UMIN, MVT::v8i16, Legal);
setOperationAction(ISD::UMIN, MVT::v4i32, Legal);
- setOperationAction(ISD::UADDSAT, MVT::v4i32, Custom);
-
+ setOperationAction(ISD::UADDSAT, MVT::v4i32, Custom);
+
// FIXME: Do we need to handle scalar-to-vector here?
setOperationAction(ISD::MUL, MVT::v4i32, Legal);
@@ -1171,10 +1171,10 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
}
}
- if (!Subtarget.useSoftFloat() && Subtarget.hasSSE42()) {
- setOperationAction(ISD::UADDSAT, MVT::v2i64, Custom);
- }
-
+ if (!Subtarget.useSoftFloat() && Subtarget.hasSSE42()) {
+ setOperationAction(ISD::UADDSAT, MVT::v2i64, Custom);
+ }
+
if (!Subtarget.useSoftFloat() && Subtarget.hasXOP()) {
for (auto VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64,
MVT::v32i8, MVT::v16i16, MVT::v8i32, MVT::v4i64 })
@@ -1216,8 +1216,8 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::STRICT_FRINT, VT, Legal);
setOperationAction(ISD::FNEARBYINT, VT, Legal);
setOperationAction(ISD::STRICT_FNEARBYINT, VT, Legal);
- setOperationAction(ISD::FROUNDEVEN, VT, Legal);
- setOperationAction(ISD::STRICT_FROUNDEVEN, VT, Legal);
+ setOperationAction(ISD::FROUNDEVEN, VT, Legal);
+ setOperationAction(ISD::STRICT_FROUNDEVEN, VT, Legal);
setOperationAction(ISD::FROUND, VT, Custom);
@@ -1345,10 +1345,10 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::SADDSAT, MVT::v16i16, HasInt256 ? Legal : Custom);
setOperationAction(ISD::USUBSAT, MVT::v16i16, HasInt256 ? Legal : Custom);
setOperationAction(ISD::SSUBSAT, MVT::v16i16, HasInt256 ? Legal : Custom);
- setOperationAction(ISD::UADDSAT, MVT::v8i32, Custom);
- setOperationAction(ISD::USUBSAT, MVT::v8i32, Custom);
- setOperationAction(ISD::UADDSAT, MVT::v4i64, Custom);
- setOperationAction(ISD::USUBSAT, MVT::v4i64, Custom);
+ setOperationAction(ISD::UADDSAT, MVT::v8i32, Custom);
+ setOperationAction(ISD::USUBSAT, MVT::v8i32, Custom);
+ setOperationAction(ISD::UADDSAT, MVT::v4i64, Custom);
+ setOperationAction(ISD::USUBSAT, MVT::v4i64, Custom);
for (auto VT : { MVT::v32i8, MVT::v16i16, MVT::v8i32 }) {
setOperationAction(ISD::ABS, VT, HasInt256 ? Legal : Custom);
@@ -1607,8 +1607,8 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::STRICT_FRINT, VT, Legal);
setOperationAction(ISD::FNEARBYINT, VT, Legal);
setOperationAction(ISD::STRICT_FNEARBYINT, VT, Legal);
- setOperationAction(ISD::FROUNDEVEN, VT, Legal);
- setOperationAction(ISD::STRICT_FROUNDEVEN, VT, Legal);
+ setOperationAction(ISD::FROUNDEVEN, VT, Legal);
+ setOperationAction(ISD::STRICT_FROUNDEVEN, VT, Legal);
setOperationAction(ISD::FROUND, VT, Custom);
}
@@ -1737,17 +1737,17 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
}
if (Subtarget.hasVBMI2()) {
- for (auto VT : { MVT::v8i16, MVT::v4i32, MVT::v2i64,
- MVT::v16i16, MVT::v8i32, MVT::v4i64,
- MVT::v32i16, MVT::v16i32, MVT::v8i64 }) {
+ for (auto VT : { MVT::v8i16, MVT::v4i32, MVT::v2i64,
+ MVT::v16i16, MVT::v8i32, MVT::v4i64,
+ MVT::v32i16, MVT::v16i32, MVT::v8i64 }) {
setOperationAction(ISD::FSHL, VT, Custom);
setOperationAction(ISD::FSHR, VT, Custom);
}
-
- setOperationAction(ISD::ROTL, MVT::v32i16, Custom);
- setOperationAction(ISD::ROTR, MVT::v8i16, Custom);
- setOperationAction(ISD::ROTR, MVT::v16i16, Custom);
- setOperationAction(ISD::ROTR, MVT::v32i16, Custom);
+
+ setOperationAction(ISD::ROTL, MVT::v32i16, Custom);
+ setOperationAction(ISD::ROTR, MVT::v8i16, Custom);
+ setOperationAction(ISD::ROTR, MVT::v16i16, Custom);
+ setOperationAction(ISD::ROTR, MVT::v32i16, Custom);
}
}// useAVX512Regs
@@ -1919,10 +1919,10 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::TRUNCATE, MVT::v16i64, Custom);
}
- if (Subtarget.hasAMXTILE()) {
- addRegisterClass(MVT::x86amx, &X86::TILERegClass);
- }
-
+ if (Subtarget.hasAMXTILE()) {
+ addRegisterClass(MVT::x86amx, &X86::TILERegClass);
+ }
+
// We want to custom lower some of our intrinsics.
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
@@ -1952,8 +1952,8 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::ADDCARRY, VT, Custom);
setOperationAction(ISD::SUBCARRY, VT, Custom);
setOperationAction(ISD::SETCCCARRY, VT, Custom);
- setOperationAction(ISD::SADDO_CARRY, VT, Custom);
- setOperationAction(ISD::SSUBO_CARRY, VT, Custom);
+ setOperationAction(ISD::SADDO_CARRY, VT, Custom);
+ setOperationAction(ISD::SSUBO_CARRY, VT, Custom);
}
if (!Subtarget.is64Bit()) {
@@ -2507,21 +2507,21 @@ Value *X86TargetLowering::getIRStackGuard(IRBuilder<> &IRB) const {
// <zircon/tls.h> defines ZX_TLS_STACK_GUARD_OFFSET with this value.
return SegmentOffset(IRB, 0x10, getAddressSpace());
} else {
- unsigned AddressSpace = getAddressSpace();
- // Specially, some users may customize the base reg and offset.
- unsigned Offset = getTargetMachine().Options.StackProtectorGuardOffset;
- // If we don't set -stack-protector-guard-offset value:
+ unsigned AddressSpace = getAddressSpace();
+ // Specially, some users may customize the base reg and offset.
+ unsigned Offset = getTargetMachine().Options.StackProtectorGuardOffset;
+ // If we don't set -stack-protector-guard-offset value:
// %fs:0x28, unless we're using a Kernel code model, in which case
// it's %gs:0x28. gs:0x14 on i386.
- if (Offset == (unsigned)-1)
- Offset = (Subtarget.is64Bit()) ? 0x28 : 0x14;
-
- const auto &GuardReg = getTargetMachine().Options.StackProtectorGuardReg;
- if (GuardReg == "fs")
- AddressSpace = X86AS::FS;
- else if (GuardReg == "gs")
- AddressSpace = X86AS::GS;
- return SegmentOffset(IRB, Offset, AddressSpace);
+ if (Offset == (unsigned)-1)
+ Offset = (Subtarget.is64Bit()) ? 0x28 : 0x14;
+
+ const auto &GuardReg = getTargetMachine().Options.StackProtectorGuardReg;
+ if (GuardReg == "fs")
+ AddressSpace = X86AS::FS;
+ else if (GuardReg == "gs")
+ AddressSpace = X86AS::GS;
+ return SegmentOffset(IRB, Offset, AddressSpace);
}
}
return TargetLowering::getIRStackGuard(IRB);
@@ -2545,13 +2545,13 @@ void X86TargetLowering::insertSSPDeclarations(Module &M) const {
}
return;
}
-
- auto GuardMode = getTargetMachine().Options.StackProtectorGuard;
-
+
+ auto GuardMode = getTargetMachine().Options.StackProtectorGuard;
+
// glibc, bionic, and Fuchsia have a special slot for the stack guard.
- if ((GuardMode == llvm::StackProtectorGuards::TLS ||
- GuardMode == llvm::StackProtectorGuards::None)
- && hasStackGuardSlotTLS(Subtarget.getTargetTriple()))
+ if ((GuardMode == llvm::StackProtectorGuards::TLS ||
+ GuardMode == llvm::StackProtectorGuards::None)
+ && hasStackGuardSlotTLS(Subtarget.getTargetTriple()))
return;
TargetLowering::insertSSPDeclarations(M);
}
@@ -3101,9 +3101,9 @@ SDValue X86TargetLowering::LowerCallResult(
// This truncation won't change the value.
DAG.getIntPtrConstant(1, dl));
- if (VA.isExtInLoc()) {
+ if (VA.isExtInLoc()) {
if (VA.getValVT().isVector() &&
- VA.getValVT().getScalarType() == MVT::i1 &&
+ VA.getValVT().getScalarType() == MVT::i1 &&
((VA.getLocVT() == MVT::i64) || (VA.getLocVT() == MVT::i32) ||
(VA.getLocVT() == MVT::i16) || (VA.getLocVT() == MVT::i8))) {
// promoting a mask type (v*i1) into a register of type i64/i32/i16/i8
@@ -3171,7 +3171,7 @@ argsAreStructReturn(ArrayRef<ISD::InputArg> Ins, bool IsMCU) {
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst,
SDValue Chain, ISD::ArgFlagsTy Flags,
SelectionDAG &DAG, const SDLoc &dl) {
- SDValue SizeNode = DAG.getIntPtrConstant(Flags.getByValSize(), dl);
+ SDValue SizeNode = DAG.getIntPtrConstant(Flags.getByValSize(), dl);
return DAG.getMemcpy(
Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
@@ -3420,8 +3420,8 @@ private:
void forwardMustTailParameters(SDValue &Chain);
- bool is64Bit() const { return Subtarget.is64Bit(); }
- bool isWin64() const { return Subtarget.isCallingConvWin64(CallConv); }
+ bool is64Bit() const { return Subtarget.is64Bit(); }
+ bool isWin64() const { return Subtarget.isCallingConvWin64(CallConv); }
X86MachineFunctionInfo *FuncInfo;
const SDLoc &DL;
@@ -3532,10 +3532,10 @@ void VarArgsLoweringHelper::createVarArgAreaAndStoreRegisters(
SaveXMMOps.push_back(Chain);
SaveXMMOps.push_back(ALVal);
SaveXMMOps.push_back(
- DAG.getTargetConstant(FuncInfo->getRegSaveFrameIndex(), DL, MVT::i32));
+ DAG.getTargetConstant(FuncInfo->getRegSaveFrameIndex(), DL, MVT::i32));
SaveXMMOps.push_back(
- DAG.getTargetConstant(FuncInfo->getVarArgsFPOffset(), DL, MVT::i32));
- llvm::append_range(SaveXMMOps, LiveXMMRegs);
+ DAG.getTargetConstant(FuncInfo->getVarArgsFPOffset(), DL, MVT::i32));
+ llvm::append_range(SaveXMMOps, LiveXMMRegs);
MemOps.push_back(DAG.getNode(X86ISD::VASTART_SAVE_XMM_REGS, DL,
MVT::Other, SaveXMMOps));
}
@@ -3809,7 +3809,7 @@ SDValue X86TargetLowering::LowerFormalArguments(
// same, so the size of funclets' (mostly empty) frames is dictated by
// how far this slot is from the bottom (since they allocate just enough
// space to accommodate holding this slot at the correct offset).
- int PSPSymFI = MFI.CreateStackObject(8, Align(8), /*isSpillSlot=*/false);
+ int PSPSymFI = MFI.CreateStackObject(8, Align(8), /*isSpillSlot=*/false);
EHInfo->PSPSymFrameIdx = PSPSymFI;
}
}
@@ -3916,7 +3916,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
const auto *II = dyn_cast_or_null<InvokeInst>(CLI.CB);
bool HasNoCfCheck =
(CI && CI->doesNoCfCheck()) || (II && II->doesNoCfCheck());
- bool IsIndirectCall = (CI && CI->isIndirectCall());
+ bool IsIndirectCall = (CI && CI->isIndirectCall());
const Module *M = MF.getMMI().getModule();
Metadata *IsCFProtectionSupported = M->getModuleFlag("cf-protection-branch");
@@ -4156,13 +4156,13 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
if (Subtarget.isPICStyleGOT()) {
// ELF / PIC requires GOT in the EBX register before function calls via PLT
- // GOT pointer (except regcall).
+ // GOT pointer (except regcall).
if (!isTailCall) {
- // Indirect call with RegCall calling convertion may use up all the
- // general registers, so it is not suitable to bind EBX reister for
- // GOT address, just let register allocator handle it.
- if (CallConv != CallingConv::X86_RegCall)
- RegsToPass.push_back(std::make_pair(
+ // Indirect call with RegCall calling convertion may use up all the
+ // general registers, so it is not suitable to bind EBX reister for
+ // GOT address, just let register allocator handle it.
+ if (CallConv != CallingConv::X86_RegCall)
+ RegsToPass.push_back(std::make_pair(
Register(X86::EBX), DAG.getNode(X86ISD::GlobalBaseReg, SDLoc(),
getPointerTy(DAG.getDataLayout()))));
} else {
@@ -4329,7 +4329,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
Ops.push_back(Callee);
if (isTailCall)
- Ops.push_back(DAG.getTargetConstant(FPDiff, dl, MVT::i32));
+ Ops.push_back(DAG.getTargetConstant(FPDiff, dl, MVT::i32));
// Add argument registers to the end of the list so that they are known live
// into the call.
@@ -4403,7 +4403,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
return Ret;
}
- if (HasNoCfCheck && IsCFProtectionSupported && IsIndirectCall) {
+ if (HasNoCfCheck && IsCFProtectionSupported && IsIndirectCall) {
Chain = DAG.getNode(X86ISD::NT_CALL, dl, NodeTys, Ops);
} else {
Chain = DAG.getNode(X86ISD::CALL, dl, NodeTys, Ops);
@@ -4522,7 +4522,7 @@ bool MatchingStackOffset(SDValue Arg, unsigned Offset, ISD::ArgFlagsTy Flags,
int FI = INT_MAX;
if (Arg.getOpcode() == ISD::CopyFromReg) {
Register VR = cast<RegisterSDNode>(Arg.getOperand(1))->getReg();
- if (!VR.isVirtual())
+ if (!VR.isVirtual())
return false;
MachineInstr *Def = MRI->getVRegDef(VR);
if (!Def)
@@ -4574,8 +4574,8 @@ bool MatchingStackOffset(SDValue Arg, unsigned Offset, ISD::ArgFlagsTy Flags,
if (!Flags.isByVal() && !MFI.isImmutableObjectIndex(FI))
return false;
- if (VA.getLocVT().getFixedSizeInBits() >
- Arg.getValueSizeInBits().getFixedSize()) {
+ if (VA.getLocVT().getFixedSizeInBits() >
+ Arg.getValueSizeInBits().getFixedSize()) {
// If the argument location is wider than the argument type, check that any
// extension flags match.
if (Flags.isZExt() != MFI.isObjectZExt(FI) ||
@@ -5083,47 +5083,47 @@ bool X86TargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
const CallInst &I,
MachineFunction &MF,
unsigned Intrinsic) const {
- Info.flags = MachineMemOperand::MONone;
- Info.offset = 0;
+ Info.flags = MachineMemOperand::MONone;
+ Info.offset = 0;
const IntrinsicData* IntrData = getIntrinsicWithChain(Intrinsic);
- if (!IntrData) {
- switch (Intrinsic) {
- case Intrinsic::x86_aesenc128kl:
- case Intrinsic::x86_aesdec128kl:
- Info.opc = ISD::INTRINSIC_W_CHAIN;
- Info.ptrVal = I.getArgOperand(1);
- Info.memVT = EVT::getIntegerVT(I.getType()->getContext(), 48);
- Info.align = Align(1);
- Info.flags |= MachineMemOperand::MOLoad;
- return true;
- case Intrinsic::x86_aesenc256kl:
- case Intrinsic::x86_aesdec256kl:
- Info.opc = ISD::INTRINSIC_W_CHAIN;
- Info.ptrVal = I.getArgOperand(1);
- Info.memVT = EVT::getIntegerVT(I.getType()->getContext(), 64);
- Info.align = Align(1);
- Info.flags |= MachineMemOperand::MOLoad;
- return true;
- case Intrinsic::x86_aesencwide128kl:
- case Intrinsic::x86_aesdecwide128kl:
- Info.opc = ISD::INTRINSIC_W_CHAIN;
- Info.ptrVal = I.getArgOperand(0);
- Info.memVT = EVT::getIntegerVT(I.getType()->getContext(), 48);
- Info.align = Align(1);
- Info.flags |= MachineMemOperand::MOLoad;
- return true;
- case Intrinsic::x86_aesencwide256kl:
- case Intrinsic::x86_aesdecwide256kl:
- Info.opc = ISD::INTRINSIC_W_CHAIN;
- Info.ptrVal = I.getArgOperand(0);
- Info.memVT = EVT::getIntegerVT(I.getType()->getContext(), 64);
- Info.align = Align(1);
- Info.flags |= MachineMemOperand::MOLoad;
- return true;
- }
+ if (!IntrData) {
+ switch (Intrinsic) {
+ case Intrinsic::x86_aesenc128kl:
+ case Intrinsic::x86_aesdec128kl:
+ Info.opc = ISD::INTRINSIC_W_CHAIN;
+ Info.ptrVal = I.getArgOperand(1);
+ Info.memVT = EVT::getIntegerVT(I.getType()->getContext(), 48);
+ Info.align = Align(1);
+ Info.flags |= MachineMemOperand::MOLoad;
+ return true;
+ case Intrinsic::x86_aesenc256kl:
+ case Intrinsic::x86_aesdec256kl:
+ Info.opc = ISD::INTRINSIC_W_CHAIN;
+ Info.ptrVal = I.getArgOperand(1);
+ Info.memVT = EVT::getIntegerVT(I.getType()->getContext(), 64);
+ Info.align = Align(1);
+ Info.flags |= MachineMemOperand::MOLoad;
+ return true;
+ case Intrinsic::x86_aesencwide128kl:
+ case Intrinsic::x86_aesdecwide128kl:
+ Info.opc = ISD::INTRINSIC_W_CHAIN;
+ Info.ptrVal = I.getArgOperand(0);
+ Info.memVT = EVT::getIntegerVT(I.getType()->getContext(), 48);
+ Info.align = Align(1);
+ Info.flags |= MachineMemOperand::MOLoad;
+ return true;
+ case Intrinsic::x86_aesencwide256kl:
+ case Intrinsic::x86_aesdecwide256kl:
+ Info.opc = ISD::INTRINSIC_W_CHAIN;
+ Info.ptrVal = I.getArgOperand(0);
+ Info.memVT = EVT::getIntegerVT(I.getType()->getContext(), 64);
+ Info.align = Align(1);
+ Info.flags |= MachineMemOperand::MOLoad;
+ return true;
+ }
return false;
- }
+ }
switch (IntrData->Type) {
case TRUNCATE_TO_MEM_VI8:
@@ -5193,7 +5193,7 @@ bool X86TargetLowering::shouldReduceLoadWidth(SDNode *Load,
ISD::LoadExtType ExtTy,
EVT NewVT) const {
assert(cast<LoadSDNode>(Load)->isSimple() && "illegal to narrow");
-
+
// "ELF Handling for Thread-Local Storage" specifies that R_X86_64_GOTTPOFF
// relocation target a movq or addq instruction: don't let the load shrink.
SDValue BasePtr = cast<LoadSDNode>(Load)->getBasePtr();
@@ -5366,7 +5366,7 @@ bool X86TargetLowering::canMergeStoresTo(unsigned AddressSpace, EVT MemVT,
// width.
if (MemVT.getSizeInBits() > Subtarget.getPreferVectorWidth())
return false;
-
+
return true;
}
@@ -5510,14 +5510,14 @@ static bool isUndefOrEqual(int Val, int CmpVal) {
return ((Val == SM_SentinelUndef) || (Val == CmpVal));
}
-/// Return true if every element in Mask is the undef sentinel value or equal to
-/// the specified value..
-static bool isUndefOrEqual(ArrayRef<int> Mask, int CmpVal) {
- return llvm::all_of(Mask, [CmpVal](int M) {
- return (M == SM_SentinelUndef) || (M == CmpVal);
- });
-}
-
+/// Return true if every element in Mask is the undef sentinel value or equal to
+/// the specified value..
+static bool isUndefOrEqual(ArrayRef<int> Mask, int CmpVal) {
+ return llvm::all_of(Mask, [CmpVal](int M) {
+ return (M == SM_SentinelUndef) || (M == CmpVal);
+ });
+}
+
/// Val is either the undef or zero sentinel value.
static bool isUndefOrZero(int Val) {
return ((Val == SM_SentinelUndef) || (Val == SM_SentinelZero));
@@ -5924,7 +5924,7 @@ static SDValue insert128BitVector(SDValue Result, SDValue Vec, unsigned IdxVal,
static SDValue widenSubVector(MVT VT, SDValue Vec, bool ZeroNewElements,
const X86Subtarget &Subtarget, SelectionDAG &DAG,
const SDLoc &dl) {
- assert(Vec.getValueSizeInBits().getFixedSize() < VT.getFixedSizeInBits() &&
+ assert(Vec.getValueSizeInBits().getFixedSize() < VT.getFixedSizeInBits() &&
Vec.getValueType().getScalarType() == VT.getScalarType() &&
"Unsupported vector widening type");
SDValue Res = ZeroNewElements ? getZeroVector(VT, Subtarget, DAG, dl)
@@ -6288,22 +6288,22 @@ static SDValue getOnesVector(EVT VT, SelectionDAG &DAG, const SDLoc &dl) {
return DAG.getBitcast(VT, Vec);
}
-// Convert *_EXTEND_VECTOR_INREG to *_EXTEND opcode.
-static unsigned getOpcode_EXTEND(unsigned Opcode) {
- switch (Opcode) {
- case ISD::ANY_EXTEND:
- case ISD::ANY_EXTEND_VECTOR_INREG:
- return ISD::ANY_EXTEND;
- case ISD::ZERO_EXTEND:
- case ISD::ZERO_EXTEND_VECTOR_INREG:
- return ISD::ZERO_EXTEND;
- case ISD::SIGN_EXTEND:
- case ISD::SIGN_EXTEND_VECTOR_INREG:
- return ISD::SIGN_EXTEND;
- }
- llvm_unreachable("Unknown opcode");
-}
-
+// Convert *_EXTEND_VECTOR_INREG to *_EXTEND opcode.
+static unsigned getOpcode_EXTEND(unsigned Opcode) {
+ switch (Opcode) {
+ case ISD::ANY_EXTEND:
+ case ISD::ANY_EXTEND_VECTOR_INREG:
+ return ISD::ANY_EXTEND;
+ case ISD::ZERO_EXTEND:
+ case ISD::ZERO_EXTEND_VECTOR_INREG:
+ return ISD::ZERO_EXTEND;
+ case ISD::SIGN_EXTEND:
+ case ISD::SIGN_EXTEND_VECTOR_INREG:
+ return ISD::SIGN_EXTEND;
+ }
+ llvm_unreachable("Unknown opcode");
+}
+
// Convert *_EXTEND to *_EXTEND_VECTOR_INREG opcode.
static unsigned getOpcode_EXTEND_VECTOR_INREG(unsigned Opcode) {
switch (Opcode) {
@@ -6320,8 +6320,8 @@ static unsigned getOpcode_EXTEND_VECTOR_INREG(unsigned Opcode) {
llvm_unreachable("Unknown opcode");
}
-static SDValue getEXTEND_VECTOR_INREG(unsigned Opcode, const SDLoc &DL, EVT VT,
- SDValue In, SelectionDAG &DAG) {
+static SDValue getEXTEND_VECTOR_INREG(unsigned Opcode, const SDLoc &DL, EVT VT,
+ SDValue In, SelectionDAG &DAG) {
EVT InVT = In.getValueType();
assert(VT.isVector() && InVT.isVector() && "Expected vector VTs.");
assert((ISD::ANY_EXTEND == Opcode || ISD::SIGN_EXTEND == Opcode ||
@@ -6373,10 +6373,10 @@ static SDValue IsNOT(SDValue V, SelectionDAG &DAG, bool OneUse = false) {
return SDValue();
}
-void llvm::createUnpackShuffleMask(EVT VT, SmallVectorImpl<int> &Mask,
+void llvm::createUnpackShuffleMask(EVT VT, SmallVectorImpl<int> &Mask,
bool Lo, bool Unary) {
- assert(VT.getScalarType().isSimple() && (VT.getSizeInBits() % 128) == 0 &&
- "Illegal vector type to unpack");
+ assert(VT.getScalarType().isSimple() && (VT.getSizeInBits() % 128) == 0 &&
+ "Illegal vector type to unpack");
assert(Mask.empty() && "Expected an empty shuffle mask vector");
int NumElts = VT.getVectorNumElements();
int NumEltsInLane = 128 / VT.getScalarSizeInBits();
@@ -6405,7 +6405,7 @@ void llvm::createSplat2ShuffleMask(MVT VT, SmallVectorImpl<int> &Mask,
}
/// Returns a vector_shuffle node for an unpackl operation.
-static SDValue getUnpackl(SelectionDAG &DAG, const SDLoc &dl, EVT VT,
+static SDValue getUnpackl(SelectionDAG &DAG, const SDLoc &dl, EVT VT,
SDValue V1, SDValue V2) {
SmallVector<int, 8> Mask;
createUnpackShuffleMask(VT, Mask, /* Lo = */ true, /* Unary = */ false);
@@ -6413,7 +6413,7 @@ static SDValue getUnpackl(SelectionDAG &DAG, const SDLoc &dl, EVT VT,
}
/// Returns a vector_shuffle node for an unpackh operation.
-static SDValue getUnpackh(SelectionDAG &DAG, const SDLoc &dl, EVT VT,
+static SDValue getUnpackh(SelectionDAG &DAG, const SDLoc &dl, EVT VT,
SDValue V1, SDValue V2) {
SmallVector<int, 8> Mask;
createUnpackShuffleMask(VT, Mask, /* Lo = */ false, /* Unary = */ false);
@@ -6660,30 +6660,30 @@ static bool getTargetConstantBitsFromNode(SDValue Op, unsigned EltSizeInBits,
}
// Extract constant bits from a subvector broadcast.
- if (Op.getOpcode() == X86ISD::SUBV_BROADCAST_LOAD) {
- auto *MemIntr = cast<MemIntrinsicSDNode>(Op);
- SDValue Ptr = MemIntr->getBasePtr();
- if (const Constant *Cst = getTargetConstantFromBasePtr(Ptr)) {
- Type *CstTy = Cst->getType();
- unsigned CstSizeInBits = CstTy->getPrimitiveSizeInBits();
- if (!CstTy->isVectorTy() || (SizeInBits % CstSizeInBits) != 0)
- return false;
- unsigned SubEltSizeInBits = CstTy->getScalarSizeInBits();
- unsigned NumSubElts = CstSizeInBits / SubEltSizeInBits;
- unsigned NumSubVecs = SizeInBits / CstSizeInBits;
- APInt UndefSubElts(NumSubElts, 0);
- SmallVector<APInt, 64> SubEltBits(NumSubElts * NumSubVecs,
- APInt(SubEltSizeInBits, 0));
- for (unsigned i = 0; i != NumSubElts; ++i) {
- if (!CollectConstantBits(Cst->getAggregateElement(i), SubEltBits[i],
- UndefSubElts, i))
- return false;
- for (unsigned j = 1; j != NumSubVecs; ++j)
- SubEltBits[i + (j * NumSubElts)] = SubEltBits[i];
- }
- UndefSubElts = APInt::getSplat(NumSubVecs * UndefSubElts.getBitWidth(),
- UndefSubElts);
- return CastBitData(UndefSubElts, SubEltBits);
+ if (Op.getOpcode() == X86ISD::SUBV_BROADCAST_LOAD) {
+ auto *MemIntr = cast<MemIntrinsicSDNode>(Op);
+ SDValue Ptr = MemIntr->getBasePtr();
+ if (const Constant *Cst = getTargetConstantFromBasePtr(Ptr)) {
+ Type *CstTy = Cst->getType();
+ unsigned CstSizeInBits = CstTy->getPrimitiveSizeInBits();
+ if (!CstTy->isVectorTy() || (SizeInBits % CstSizeInBits) != 0)
+ return false;
+ unsigned SubEltSizeInBits = CstTy->getScalarSizeInBits();
+ unsigned NumSubElts = CstSizeInBits / SubEltSizeInBits;
+ unsigned NumSubVecs = SizeInBits / CstSizeInBits;
+ APInt UndefSubElts(NumSubElts, 0);
+ SmallVector<APInt, 64> SubEltBits(NumSubElts * NumSubVecs,
+ APInt(SubEltSizeInBits, 0));
+ for (unsigned i = 0; i != NumSubElts; ++i) {
+ if (!CollectConstantBits(Cst->getAggregateElement(i), SubEltBits[i],
+ UndefSubElts, i))
+ return false;
+ for (unsigned j = 1; j != NumSubVecs; ++j)
+ SubEltBits[i + (j * NumSubElts)] = SubEltBits[i];
+ }
+ UndefSubElts = APInt::getSplat(NumSubVecs * UndefSubElts.getBitWidth(),
+ UndefSubElts);
+ return CastBitData(UndefSubElts, SubEltBits);
}
}
@@ -6704,26 +6704,26 @@ static bool getTargetConstantBitsFromNode(SDValue Op, unsigned EltSizeInBits,
// Insert constant bits from a base and sub vector sources.
if (Op.getOpcode() == ISD::INSERT_SUBVECTOR) {
- // If bitcasts to larger elements we might lose track of undefs - don't
- // allow any to be safe.
- unsigned SrcEltSizeInBits = VT.getScalarSizeInBits();
- bool AllowUndefs = EltSizeInBits >= SrcEltSizeInBits;
-
- APInt UndefSrcElts, UndefSubElts;
- SmallVector<APInt, 32> EltSrcBits, EltSubBits;
- if (getTargetConstantBitsFromNode(Op.getOperand(1), SrcEltSizeInBits,
+ // If bitcasts to larger elements we might lose track of undefs - don't
+ // allow any to be safe.
+ unsigned SrcEltSizeInBits = VT.getScalarSizeInBits();
+ bool AllowUndefs = EltSizeInBits >= SrcEltSizeInBits;
+
+ APInt UndefSrcElts, UndefSubElts;
+ SmallVector<APInt, 32> EltSrcBits, EltSubBits;
+ if (getTargetConstantBitsFromNode(Op.getOperand(1), SrcEltSizeInBits,
UndefSubElts, EltSubBits,
- AllowWholeUndefs && AllowUndefs,
- AllowPartialUndefs && AllowUndefs) &&
- getTargetConstantBitsFromNode(Op.getOperand(0), SrcEltSizeInBits,
- UndefSrcElts, EltSrcBits,
- AllowWholeUndefs && AllowUndefs,
- AllowPartialUndefs && AllowUndefs)) {
+ AllowWholeUndefs && AllowUndefs,
+ AllowPartialUndefs && AllowUndefs) &&
+ getTargetConstantBitsFromNode(Op.getOperand(0), SrcEltSizeInBits,
+ UndefSrcElts, EltSrcBits,
+ AllowWholeUndefs && AllowUndefs,
+ AllowPartialUndefs && AllowUndefs)) {
unsigned BaseIdx = Op.getConstantOperandVal(2);
- UndefSrcElts.insertBits(UndefSubElts, BaseIdx);
+ UndefSrcElts.insertBits(UndefSubElts, BaseIdx);
for (unsigned i = 0, e = EltSubBits.size(); i != e; ++i)
- EltSrcBits[BaseIdx + i] = EltSubBits[i];
- return CastBitData(UndefSrcElts, EltSrcBits);
+ EltSrcBits[BaseIdx + i] = EltSubBits[i];
+ return CastBitData(UndefSrcElts, EltSrcBits);
}
}
@@ -6836,7 +6836,7 @@ static bool getTargetShuffleMaskIndices(SDValue MaskNode,
return false;
// Insert the extracted elements into the mask.
- for (const APInt &Elt : EltBits)
+ for (const APInt &Elt : EltBits)
RawMask.push_back(Elt.getZExtValue());
return true;
@@ -7517,8 +7517,8 @@ static bool getFauxShuffleMask(SDValue N, const APInt &DemandedElts,
case ISD::OR: {
// Handle OR(SHUFFLE,SHUFFLE) case where one source is zero and the other
// is a valid shuffle index.
- SDValue N0 = peekThroughBitcasts(N.getOperand(0));
- SDValue N1 = peekThroughBitcasts(N.getOperand(1));
+ SDValue N0 = peekThroughBitcasts(N.getOperand(0));
+ SDValue N1 = peekThroughBitcasts(N.getOperand(1));
if (!N0.getValueType().isVector() || !N1.getValueType().isVector())
return false;
SmallVector<int, 64> SrcMask0, SrcMask1;
@@ -7533,20 +7533,20 @@ static bool getFauxShuffleMask(SDValue N, const APInt &DemandedElts,
SmallVector<int, 64> Mask0, Mask1;
narrowShuffleMaskElts(MaskSize / SrcMask0.size(), SrcMask0, Mask0);
narrowShuffleMaskElts(MaskSize / SrcMask1.size(), SrcMask1, Mask1);
- for (int i = 0; i != (int)MaskSize; ++i) {
+ for (int i = 0; i != (int)MaskSize; ++i) {
if (Mask0[i] == SM_SentinelUndef && Mask1[i] == SM_SentinelUndef)
Mask.push_back(SM_SentinelUndef);
else if (Mask0[i] == SM_SentinelZero && Mask1[i] == SM_SentinelZero)
Mask.push_back(SM_SentinelZero);
else if (Mask1[i] == SM_SentinelZero)
- Mask.push_back(i);
+ Mask.push_back(i);
else if (Mask0[i] == SM_SentinelZero)
- Mask.push_back(i + MaskSize);
+ Mask.push_back(i + MaskSize);
else
return false;
}
- Ops.push_back(N0);
- Ops.push_back(N1);
+ Ops.push_back(N0);
+ Ops.push_back(N1);
return true;
}
case ISD::INSERT_SUBVECTOR: {
@@ -7578,8 +7578,8 @@ static bool getFauxShuffleMask(SDValue N, const APInt &DemandedElts,
// Subvector shuffle inputs must not be larger than the subvector.
if (llvm::any_of(SubInputs, [SubVT](SDValue SubInput) {
- return SubVT.getFixedSizeInBits() <
- SubInput.getValueSizeInBits().getFixedSize();
+ return SubVT.getFixedSizeInBits() <
+ SubInput.getValueSizeInBits().getFixedSize();
}))
return false;
@@ -7600,11 +7600,11 @@ static bool getFauxShuffleMask(SDValue N, const APInt &DemandedElts,
}
Ops.push_back(Src);
Ops.append(SubInputs.begin(), SubInputs.end());
- if (ISD::isBuildVectorAllZeros(Src.getNode()))
- Mask.append(NumElts, SM_SentinelZero);
- else
- for (int i = 0; i != (int)NumElts; ++i)
- Mask.push_back(i);
+ if (ISD::isBuildVectorAllZeros(Src.getNode()))
+ Mask.append(NumElts, SM_SentinelZero);
+ else
+ for (int i = 0; i != (int)NumElts; ++i)
+ Mask.push_back(i);
for (int i = 0; i != (int)NumSubElts; ++i) {
int M = SubMask[i];
if (0 <= M) {
@@ -7705,33 +7705,33 @@ static bool getFauxShuffleMask(SDValue N, const APInt &DemandedElts,
APInt EltsLHS, EltsRHS;
getPackDemandedElts(VT, DemandedElts, EltsLHS, EltsRHS);
- // If we know input saturation won't happen (or we don't care for particular
- // lanes), we can treat this as a truncation shuffle.
- bool Offset0 = false, Offset1 = false;
+ // If we know input saturation won't happen (or we don't care for particular
+ // lanes), we can treat this as a truncation shuffle.
+ bool Offset0 = false, Offset1 = false;
if (Opcode == X86ISD::PACKSS) {
- if ((!(N0.isUndef() || EltsLHS.isNullValue()) &&
+ if ((!(N0.isUndef() || EltsLHS.isNullValue()) &&
DAG.ComputeNumSignBits(N0, EltsLHS, Depth + 1) <= NumBitsPerElt) ||
- (!(N1.isUndef() || EltsRHS.isNullValue()) &&
+ (!(N1.isUndef() || EltsRHS.isNullValue()) &&
DAG.ComputeNumSignBits(N1, EltsRHS, Depth + 1) <= NumBitsPerElt))
return false;
- // We can't easily fold ASHR into a shuffle, but if it was feeding a
- // PACKSS then it was likely being used for sign-extension for a
- // truncation, so just peek through and adjust the mask accordingly.
- if (N0.getOpcode() == X86ISD::VSRAI && N->isOnlyUserOf(N0.getNode()) &&
- N0.getConstantOperandAPInt(1) == NumBitsPerElt) {
- Offset0 = true;
- N0 = N0.getOperand(0);
- }
- if (N1.getOpcode() == X86ISD::VSRAI && N->isOnlyUserOf(N1.getNode()) &&
- N1.getConstantOperandAPInt(1) == NumBitsPerElt) {
- Offset1 = true;
- N1 = N1.getOperand(0);
- }
+ // We can't easily fold ASHR into a shuffle, but if it was feeding a
+ // PACKSS then it was likely being used for sign-extension for a
+ // truncation, so just peek through and adjust the mask accordingly.
+ if (N0.getOpcode() == X86ISD::VSRAI && N->isOnlyUserOf(N0.getNode()) &&
+ N0.getConstantOperandAPInt(1) == NumBitsPerElt) {
+ Offset0 = true;
+ N0 = N0.getOperand(0);
+ }
+ if (N1.getOpcode() == X86ISD::VSRAI && N->isOnlyUserOf(N1.getNode()) &&
+ N1.getConstantOperandAPInt(1) == NumBitsPerElt) {
+ Offset1 = true;
+ N1 = N1.getOperand(0);
+ }
} else {
APInt ZeroMask = APInt::getHighBitsSet(2 * NumBitsPerElt, NumBitsPerElt);
- if ((!(N0.isUndef() || EltsLHS.isNullValue()) &&
+ if ((!(N0.isUndef() || EltsLHS.isNullValue()) &&
!DAG.MaskedValueIsZero(N0, ZeroMask, EltsLHS, Depth + 1)) ||
- (!(N1.isUndef() || EltsRHS.isNullValue()) &&
+ (!(N1.isUndef() || EltsRHS.isNullValue()) &&
!DAG.MaskedValueIsZero(N1, ZeroMask, EltsRHS, Depth + 1)))
return false;
}
@@ -7743,13 +7743,13 @@ static bool getFauxShuffleMask(SDValue N, const APInt &DemandedElts,
Ops.push_back(N1);
createPackShuffleMask(VT, Mask, IsUnary);
-
- if (Offset0 || Offset1) {
- for (int &M : Mask)
- if ((Offset0 && isInRange(M, 0, NumElts)) ||
- (Offset1 && isInRange(M, NumElts, 2 * NumElts)))
- ++M;
- }
+
+ if (Offset0 || Offset1) {
+ for (int &M : Mask)
+ if ((Offset0 && isInRange(M, 0, NumElts)) ||
+ (Offset1 && isInRange(M, NumElts, 2 * NumElts)))
+ ++M;
+ }
return true;
}
case X86ISD::VTRUNC: {
@@ -8037,7 +8037,7 @@ static SDValue getShuffleScalarElt(SDValue Op, unsigned Index,
}
// Use PINSRB/PINSRW/PINSRD to create a build vector.
-static SDValue LowerBuildVectorAsInsert(SDValue Op, const APInt &NonZeroMask,
+static SDValue LowerBuildVectorAsInsert(SDValue Op, const APInt &NonZeroMask,
unsigned NumNonZero, unsigned NumZero,
SelectionDAG &DAG,
const X86Subtarget &Subtarget) {
@@ -8052,7 +8052,7 @@ static SDValue LowerBuildVectorAsInsert(SDValue Op, const APInt &NonZeroMask,
bool First = true;
for (unsigned i = 0; i < NumElts; ++i) {
- bool IsNonZero = NonZeroMask[i];
+ bool IsNonZero = NonZeroMask[i];
if (!IsNonZero)
continue;
@@ -8079,7 +8079,7 @@ static SDValue LowerBuildVectorAsInsert(SDValue Op, const APInt &NonZeroMask,
}
/// Custom lower build_vector of v16i8.
-static SDValue LowerBuildVectorv16i8(SDValue Op, const APInt &NonZeroMask,
+static SDValue LowerBuildVectorv16i8(SDValue Op, const APInt &NonZeroMask,
unsigned NumNonZero, unsigned NumZero,
SelectionDAG &DAG,
const X86Subtarget &Subtarget) {
@@ -8088,7 +8088,7 @@ static SDValue LowerBuildVectorv16i8(SDValue Op, const APInt &NonZeroMask,
// SSE4.1 - use PINSRB to insert each byte directly.
if (Subtarget.hasSSE41())
- return LowerBuildVectorAsInsert(Op, NonZeroMask, NumNonZero, NumZero, DAG,
+ return LowerBuildVectorAsInsert(Op, NonZeroMask, NumNonZero, NumZero, DAG,
Subtarget);
SDLoc dl(Op);
@@ -8096,8 +8096,8 @@ static SDValue LowerBuildVectorv16i8(SDValue Op, const APInt &NonZeroMask,
// Pre-SSE4.1 - merge byte pairs and insert with PINSRW.
for (unsigned i = 0; i < 16; i += 2) {
- bool ThisIsNonZero = NonZeroMask[i];
- bool NextIsNonZero = NonZeroMask[i + 1];
+ bool ThisIsNonZero = NonZeroMask[i];
+ bool NextIsNonZero = NonZeroMask[i + 1];
if (!ThisIsNonZero && !NextIsNonZero)
continue;
@@ -8145,7 +8145,7 @@ static SDValue LowerBuildVectorv16i8(SDValue Op, const APInt &NonZeroMask,
}
/// Custom lower build_vector of v8i16.
-static SDValue LowerBuildVectorv8i16(SDValue Op, const APInt &NonZeroMask,
+static SDValue LowerBuildVectorv8i16(SDValue Op, const APInt &NonZeroMask,
unsigned NumNonZero, unsigned NumZero,
SelectionDAG &DAG,
const X86Subtarget &Subtarget) {
@@ -8153,7 +8153,7 @@ static SDValue LowerBuildVectorv8i16(SDValue Op, const APInt &NonZeroMask,
return SDValue();
// Use PINSRW to insert each byte directly.
- return LowerBuildVectorAsInsert(Op, NonZeroMask, NumNonZero, NumZero, DAG,
+ return LowerBuildVectorAsInsert(Op, NonZeroMask, NumNonZero, NumZero, DAG,
Subtarget);
}
@@ -8487,8 +8487,8 @@ static SDValue EltsFromConsecutiveLoads(EVT VT, ArrayRef<SDValue> Elts,
assert(LDBase && "Did not find base load for merging consecutive loads");
unsigned BaseSizeInBits = EltBaseVT.getStoreSizeInBits();
unsigned BaseSizeInBytes = BaseSizeInBits / 8;
- int NumLoadedElts = (1 + LastLoadedElt - FirstLoadedElt);
- int LoadSizeInBits = NumLoadedElts * BaseSizeInBits;
+ int NumLoadedElts = (1 + LastLoadedElt - FirstLoadedElt);
+ int LoadSizeInBits = NumLoadedElts * BaseSizeInBits;
assert((BaseSizeInBits % 8) == 0 && "Sub-byte element loads detected");
// TODO: Support offsetting the base load.
@@ -8550,7 +8550,7 @@ static SDValue EltsFromConsecutiveLoads(EVT VT, ArrayRef<SDValue> Elts,
// base pointer. If the vector contains zeros, then attempt to shuffle those
// elements.
if (FirstLoadedElt == 0 &&
- (NumLoadedElts == (int)NumElems || IsDereferenceable) &&
+ (NumLoadedElts == (int)NumElems || IsDereferenceable) &&
(IsConsecutiveLoad || IsConsecutiveLoadWithZeros)) {
if (isAfterLegalize && !TLI.isOperationLegal(ISD::LOAD, VT))
return SDValue();
@@ -8638,11 +8638,11 @@ static SDValue EltsFromConsecutiveLoads(EVT VT, ArrayRef<SDValue> Elts,
if (!Subtarget.hasAVX2() && ScalarSize < 32)
continue;
- // Don't attempt a 1:N subvector broadcast - it should be caught by
- // combineConcatVectorOps, else will cause infinite loops.
- if (RepeatSize > ScalarSize && SubElems == 1)
- continue;
-
+ // Don't attempt a 1:N subvector broadcast - it should be caught by
+ // combineConcatVectorOps, else will cause infinite loops.
+ if (RepeatSize > ScalarSize && SubElems == 1)
+ continue;
+
bool Match = true;
SmallVector<SDValue, 8> RepeatedLoads(SubElems, DAG.getUNDEF(EltBaseVT));
for (unsigned i = 0; i != NumElems && Match; ++i) {
@@ -8674,14 +8674,14 @@ static SDValue EltsFromConsecutiveLoads(EVT VT, ArrayRef<SDValue> Elts,
if (TLI.isTypeLegal(BroadcastVT)) {
if (SDValue RepeatLoad = EltsFromConsecutiveLoads(
RepeatVT, RepeatedLoads, DL, DAG, Subtarget, isAfterLegalize)) {
- SDValue Broadcast = RepeatLoad;
- if (RepeatSize > ScalarSize) {
- while (Broadcast.getValueSizeInBits() < VT.getSizeInBits())
- Broadcast = concatSubVectors(Broadcast, Broadcast, DAG, DL);
- } else {
- Broadcast =
- DAG.getNode(X86ISD::VBROADCAST, DL, BroadcastVT, RepeatLoad);
- }
+ SDValue Broadcast = RepeatLoad;
+ if (RepeatSize > ScalarSize) {
+ while (Broadcast.getValueSizeInBits() < VT.getSizeInBits())
+ Broadcast = concatSubVectors(Broadcast, Broadcast, DAG, DL);
+ } else {
+ Broadcast =
+ DAG.getNode(X86ISD::VBROADCAST, DL, BroadcastVT, RepeatLoad);
+ }
return DAG.getBitcast(VT, Broadcast);
}
}
@@ -8769,21 +8769,21 @@ static SDValue lowerBuildVectorAsBroadcast(BuildVectorSDNode *BVOp,
return SDValue();
MVT VT = BVOp->getSimpleValueType(0);
- unsigned NumElts = VT.getVectorNumElements();
+ unsigned NumElts = VT.getVectorNumElements();
SDLoc dl(BVOp);
assert((VT.is128BitVector() || VT.is256BitVector() || VT.is512BitVector()) &&
"Unsupported vector type for broadcast.");
- // See if the build vector is a repeating sequence of scalars (inc. splat).
- SDValue Ld;
+ // See if the build vector is a repeating sequence of scalars (inc. splat).
+ SDValue Ld;
BitVector UndefElements;
- SmallVector<SDValue, 16> Sequence;
- if (BVOp->getRepeatedSequence(Sequence, &UndefElements)) {
- assert((NumElts % Sequence.size()) == 0 && "Sequence doesn't fit.");
- if (Sequence.size() == 1)
- Ld = Sequence[0];
- }
+ SmallVector<SDValue, 16> Sequence;
+ if (BVOp->getRepeatedSequence(Sequence, &UndefElements)) {
+ assert((NumElts % Sequence.size()) == 0 && "Sequence doesn't fit.");
+ if (Sequence.size() == 1)
+ Ld = Sequence[0];
+ }
// Attempt to use VBROADCASTM
// From this pattern:
@@ -8791,34 +8791,34 @@ static SDValue lowerBuildVectorAsBroadcast(BuildVectorSDNode *BVOp,
// b. t1 = (build_vector t0 t0)
//
// Create (VBROADCASTM v2i1 X)
- if (!Sequence.empty() && Subtarget.hasCDI()) {
- // If not a splat, are the upper sequence values zeroable?
- unsigned SeqLen = Sequence.size();
- bool UpperZeroOrUndef =
- SeqLen == 1 ||
- llvm::all_of(makeArrayRef(Sequence).drop_front(), [](SDValue V) {
- return !V || V.isUndef() || isNullConstant(V);
- });
- SDValue Op0 = Sequence[0];
- if (UpperZeroOrUndef && ((Op0.getOpcode() == ISD::BITCAST) ||
- (Op0.getOpcode() == ISD::ZERO_EXTEND &&
- Op0.getOperand(0).getOpcode() == ISD::BITCAST))) {
- SDValue BOperand = Op0.getOpcode() == ISD::BITCAST
- ? Op0.getOperand(0)
- : Op0.getOperand(0).getOperand(0);
+ if (!Sequence.empty() && Subtarget.hasCDI()) {
+ // If not a splat, are the upper sequence values zeroable?
+ unsigned SeqLen = Sequence.size();
+ bool UpperZeroOrUndef =
+ SeqLen == 1 ||
+ llvm::all_of(makeArrayRef(Sequence).drop_front(), [](SDValue V) {
+ return !V || V.isUndef() || isNullConstant(V);
+ });
+ SDValue Op0 = Sequence[0];
+ if (UpperZeroOrUndef && ((Op0.getOpcode() == ISD::BITCAST) ||
+ (Op0.getOpcode() == ISD::ZERO_EXTEND &&
+ Op0.getOperand(0).getOpcode() == ISD::BITCAST))) {
+ SDValue BOperand = Op0.getOpcode() == ISD::BITCAST
+ ? Op0.getOperand(0)
+ : Op0.getOperand(0).getOperand(0);
MVT MaskVT = BOperand.getSimpleValueType();
- MVT EltType = MVT::getIntegerVT(VT.getScalarSizeInBits() * SeqLen);
- if ((EltType == MVT::i64 && MaskVT == MVT::v8i1) || // for broadcastmb2q
+ MVT EltType = MVT::getIntegerVT(VT.getScalarSizeInBits() * SeqLen);
+ if ((EltType == MVT::i64 && MaskVT == MVT::v8i1) || // for broadcastmb2q
(EltType == MVT::i32 && MaskVT == MVT::v16i1)) { // for broadcastmw2d
- MVT BcstVT = MVT::getVectorVT(EltType, NumElts / SeqLen);
- if (!VT.is512BitVector() && !Subtarget.hasVLX()) {
- unsigned Scale = 512 / VT.getSizeInBits();
- BcstVT = MVT::getVectorVT(EltType, Scale * (NumElts / SeqLen));
- }
- SDValue Bcst = DAG.getNode(X86ISD::VBROADCASTM, dl, BcstVT, BOperand);
- if (BcstVT.getSizeInBits() != VT.getSizeInBits())
- Bcst = extractSubVector(Bcst, 0, DAG, dl, VT.getSizeInBits());
- return DAG.getBitcast(VT, Bcst);
+ MVT BcstVT = MVT::getVectorVT(EltType, NumElts / SeqLen);
+ if (!VT.is512BitVector() && !Subtarget.hasVLX()) {
+ unsigned Scale = 512 / VT.getSizeInBits();
+ BcstVT = MVT::getVectorVT(EltType, Scale * (NumElts / SeqLen));
+ }
+ SDValue Bcst = DAG.getNode(X86ISD::VBROADCASTM, dl, BcstVT, BOperand);
+ if (BcstVT.getSizeInBits() != VT.getSizeInBits())
+ Bcst = extractSubVector(Bcst, 0, DAG, dl, VT.getSizeInBits());
+ return DAG.getBitcast(VT, Bcst);
}
}
}
@@ -8868,15 +8868,15 @@ static SDValue lowerBuildVectorAsBroadcast(BuildVectorSDNode *BVOp,
*Ctx);
SDValue VCP = DAG.getConstantPool(VecC, PVT);
unsigned NumElm = SplatBitSize / VT.getScalarSizeInBits();
- MVT VVT = MVT::getVectorVT(VT.getScalarType(), NumElm);
+ MVT VVT = MVT::getVectorVT(VT.getScalarType(), NumElm);
Align Alignment = cast<ConstantPoolSDNode>(VCP)->getAlign();
- SDVTList Tys = DAG.getVTList(VT, MVT::Other);
- SDValue Ops[] = {DAG.getEntryNode(), VCP};
- MachinePointerInfo MPI =
- MachinePointerInfo::getConstantPool(DAG.getMachineFunction());
- return DAG.getMemIntrinsicNode(
- X86ISD::SUBV_BROADCAST_LOAD, dl, Tys, Ops, VVT, MPI, Alignment,
- MachineMemOperand::MOLoad);
+ SDVTList Tys = DAG.getVTList(VT, MVT::Other);
+ SDValue Ops[] = {DAG.getEntryNode(), VCP};
+ MachinePointerInfo MPI =
+ MachinePointerInfo::getConstantPool(DAG.getMachineFunction());
+ return DAG.getMemIntrinsicNode(
+ X86ISD::SUBV_BROADCAST_LOAD, dl, Tys, Ops, VVT, MPI, Alignment,
+ MachineMemOperand::MOLoad);
}
}
}
@@ -8897,8 +8897,8 @@ static SDValue lowerBuildVectorAsBroadcast(BuildVectorSDNode *BVOp,
(Ld.getOpcode() == ISD::Constant || Ld.getOpcode() == ISD::ConstantFP);
bool IsLoad = ISD::isNormalLoad(Ld.getNode());
- // TODO: Handle broadcasts of non-constant sequences.
-
+ // TODO: Handle broadcasts of non-constant sequences.
+
// Make sure that all of the users of a non-constant load are from the
// BUILD_VECTOR node.
// FIXME: Is the use count needed for non-constant, non-load case?
@@ -10233,69 +10233,69 @@ X86TargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const {
return VectorConstant;
unsigned EVTBits = EltVT.getSizeInBits();
- APInt UndefMask = APInt::getNullValue(NumElems);
- APInt ZeroMask = APInt::getNullValue(NumElems);
- APInt NonZeroMask = APInt::getNullValue(NumElems);
+ APInt UndefMask = APInt::getNullValue(NumElems);
+ APInt ZeroMask = APInt::getNullValue(NumElems);
+ APInt NonZeroMask = APInt::getNullValue(NumElems);
bool IsAllConstants = true;
SmallSet<SDValue, 8> Values;
unsigned NumConstants = NumElems;
for (unsigned i = 0; i < NumElems; ++i) {
SDValue Elt = Op.getOperand(i);
- if (Elt.isUndef()) {
- UndefMask.setBit(i);
+ if (Elt.isUndef()) {
+ UndefMask.setBit(i);
continue;
- }
+ }
Values.insert(Elt);
if (!isa<ConstantSDNode>(Elt) && !isa<ConstantFPSDNode>(Elt)) {
IsAllConstants = false;
NumConstants--;
}
- if (X86::isZeroNode(Elt)) {
- ZeroMask.setBit(i);
- } else {
- NonZeroMask.setBit(i);
+ if (X86::isZeroNode(Elt)) {
+ ZeroMask.setBit(i);
+ } else {
+ NonZeroMask.setBit(i);
}
}
- // All undef vector. Return an UNDEF. All zero vectors were handled above.
- if (NonZeroMask == 0) {
- assert(UndefMask.isAllOnesValue() && "Fully undef mask expected");
+ // All undef vector. Return an UNDEF. All zero vectors were handled above.
+ if (NonZeroMask == 0) {
+ assert(UndefMask.isAllOnesValue() && "Fully undef mask expected");
return DAG.getUNDEF(VT);
- }
-
- BuildVectorSDNode *BV = cast<BuildVectorSDNode>(Op.getNode());
-
- // If the upper elts of a ymm/zmm are undef/zero then we might be better off
- // lowering to a smaller build vector and padding with undef/zero.
- if ((VT.is256BitVector() || VT.is512BitVector()) &&
- !isFoldableUseOfShuffle(BV)) {
- unsigned UpperElems = NumElems / 2;
- APInt UndefOrZeroMask = UndefMask | ZeroMask;
- unsigned NumUpperUndefsOrZeros = UndefOrZeroMask.countLeadingOnes();
- if (NumUpperUndefsOrZeros >= UpperElems) {
- if (VT.is512BitVector() &&
- NumUpperUndefsOrZeros >= (NumElems - (NumElems / 4)))
- UpperElems = NumElems - (NumElems / 4);
- bool UndefUpper = UndefMask.countLeadingOnes() >= UpperElems;
- MVT LowerVT = MVT::getVectorVT(EltVT, NumElems - UpperElems);
- SDValue NewBV =
- DAG.getBuildVector(LowerVT, dl, Op->ops().drop_back(UpperElems));
- return widenSubVector(VT, NewBV, !UndefUpper, Subtarget, DAG, dl);
- }
- }
-
- if (SDValue AddSub = lowerToAddSubOrFMAddSub(BV, Subtarget, DAG))
- return AddSub;
- if (SDValue HorizontalOp = LowerToHorizontalOp(BV, Subtarget, DAG))
- return HorizontalOp;
- if (SDValue Broadcast = lowerBuildVectorAsBroadcast(BV, Subtarget, DAG))
- return Broadcast;
- if (SDValue BitOp = lowerBuildVectorToBitOp(BV, Subtarget, DAG))
- return BitOp;
-
- unsigned NumZero = ZeroMask.countPopulation();
- unsigned NumNonZero = NonZeroMask.countPopulation();
-
+ }
+
+ BuildVectorSDNode *BV = cast<BuildVectorSDNode>(Op.getNode());
+
+ // If the upper elts of a ymm/zmm are undef/zero then we might be better off
+ // lowering to a smaller build vector and padding with undef/zero.
+ if ((VT.is256BitVector() || VT.is512BitVector()) &&
+ !isFoldableUseOfShuffle(BV)) {
+ unsigned UpperElems = NumElems / 2;
+ APInt UndefOrZeroMask = UndefMask | ZeroMask;
+ unsigned NumUpperUndefsOrZeros = UndefOrZeroMask.countLeadingOnes();
+ if (NumUpperUndefsOrZeros >= UpperElems) {
+ if (VT.is512BitVector() &&
+ NumUpperUndefsOrZeros >= (NumElems - (NumElems / 4)))
+ UpperElems = NumElems - (NumElems / 4);
+ bool UndefUpper = UndefMask.countLeadingOnes() >= UpperElems;
+ MVT LowerVT = MVT::getVectorVT(EltVT, NumElems - UpperElems);
+ SDValue NewBV =
+ DAG.getBuildVector(LowerVT, dl, Op->ops().drop_back(UpperElems));
+ return widenSubVector(VT, NewBV, !UndefUpper, Subtarget, DAG, dl);
+ }
+ }
+
+ if (SDValue AddSub = lowerToAddSubOrFMAddSub(BV, Subtarget, DAG))
+ return AddSub;
+ if (SDValue HorizontalOp = LowerToHorizontalOp(BV, Subtarget, DAG))
+ return HorizontalOp;
+ if (SDValue Broadcast = lowerBuildVectorAsBroadcast(BV, Subtarget, DAG))
+ return Broadcast;
+ if (SDValue BitOp = lowerBuildVectorToBitOp(BV, Subtarget, DAG))
+ return BitOp;
+
+ unsigned NumZero = ZeroMask.countPopulation();
+ unsigned NumNonZero = NonZeroMask.countPopulation();
+
// If we are inserting one variable into a vector of non-zero constants, try
// to avoid loading each constant element as a scalar. Load the constants as a
// vector and then insert the variable scalar element. If insertion is not
@@ -10358,7 +10358,7 @@ X86TargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const {
// Special case for single non-zero, non-undef, element.
if (NumNonZero == 1) {
- unsigned Idx = NonZeroMask.countTrailingZeros();
+ unsigned Idx = NonZeroMask.countTrailingZeros();
SDValue Item = Op.getOperand(Idx);
// If we have a constant or non-constant insertion into the low element of
@@ -10422,7 +10422,7 @@ X86TargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const {
// shuffle (scalar_to_vector (load (ptr + 4))), undef, <0, 0, 0, 0>
// Check if it's possible to issue this instead.
// shuffle (vload ptr)), undef, <1, 1, 1, 1>
- unsigned Idx = NonZeroMask.countTrailingZeros();
+ unsigned Idx = NonZeroMask.countTrailingZeros();
SDValue Item = Op.getOperand(Idx);
if (Op.getNode()->isOnlyUserOf(Item.getNode()))
return LowerAsSplatVectorLoad(Item, VT, dl, DAG);
@@ -10491,7 +10491,7 @@ X86TargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const {
if (EVTBits == 64) {
if (NumNonZero == 1) {
// One half is zero or undef.
- unsigned Idx = NonZeroMask.countTrailingZeros();
+ unsigned Idx = NonZeroMask.countTrailingZeros();
SDValue V2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT,
Op.getOperand(Idx));
return getShuffleVectorZeroOrUndef(V2, Idx, true, Subtarget, DAG);
@@ -10501,12 +10501,12 @@ X86TargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const {
// If element VT is < 32 bits, convert it to inserts into a zero vector.
if (EVTBits == 8 && NumElems == 16)
- if (SDValue V = LowerBuildVectorv16i8(Op, NonZeroMask, NumNonZero, NumZero,
+ if (SDValue V = LowerBuildVectorv16i8(Op, NonZeroMask, NumNonZero, NumZero,
DAG, Subtarget))
return V;
if (EVTBits == 16 && NumElems == 8)
- if (SDValue V = LowerBuildVectorv8i16(Op, NonZeroMask, NumNonZero, NumZero,
+ if (SDValue V = LowerBuildVectorv8i16(Op, NonZeroMask, NumNonZero, NumZero,
DAG, Subtarget))
return V;
@@ -10519,7 +10519,7 @@ X86TargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const {
if (NumElems == 4 && NumZero > 0) {
SmallVector<SDValue, 8> Ops(NumElems);
for (unsigned i = 0; i < 4; ++i) {
- bool isZero = !NonZeroMask[i];
+ bool isZero = !NonZeroMask[i];
if (isZero)
Ops[i] = getZeroVector(VT, Subtarget, DAG, dl);
else
@@ -10527,7 +10527,7 @@ X86TargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const {
}
for (unsigned i = 0; i < 2; ++i) {
- switch (NonZeroMask.extractBitsAsZExtValue(2, i * 2)) {
+ switch (NonZeroMask.extractBitsAsZExtValue(2, i * 2)) {
default: llvm_unreachable("Unexpected NonZero count");
case 0:
Ops[i] = Ops[i*2]; // Must be a zero vector.
@@ -10544,8 +10544,8 @@ X86TargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const {
}
}
- bool Reverse1 = NonZeroMask.extractBitsAsZExtValue(2, 0) == 2;
- bool Reverse2 = NonZeroMask.extractBitsAsZExtValue(2, 2) == 2;
+ bool Reverse1 = NonZeroMask.extractBitsAsZExtValue(2, 0) == 2;
+ bool Reverse2 = NonZeroMask.extractBitsAsZExtValue(2, 2) == 2;
int MaskVec[] = {
Reverse1 ? 1 : 0,
Reverse1 ? 0 : 1,
@@ -10817,35 +10817,35 @@ static bool is128BitLaneCrossingShuffleMask(MVT VT, ArrayRef<int> Mask) {
return isLaneCrossingShuffleMask(128, VT.getScalarSizeInBits(), Mask);
}
-/// Test whether elements in each LaneSizeInBits lane in this shuffle mask come
-/// from multiple lanes - this is different to isLaneCrossingShuffleMask to
-/// better support 'repeated mask + lane permute' style shuffles.
-static bool isMultiLaneShuffleMask(unsigned LaneSizeInBits,
- unsigned ScalarSizeInBits,
- ArrayRef<int> Mask) {
- assert(LaneSizeInBits && ScalarSizeInBits &&
- (LaneSizeInBits % ScalarSizeInBits) == 0 &&
- "Illegal shuffle lane size");
- int NumElts = Mask.size();
- int NumEltsPerLane = LaneSizeInBits / ScalarSizeInBits;
- int NumLanes = NumElts / NumEltsPerLane;
- if (NumLanes > 1) {
- for (int i = 0; i != NumLanes; ++i) {
- int SrcLane = -1;
- for (int j = 0; j != NumEltsPerLane; ++j) {
- int M = Mask[(i * NumEltsPerLane) + j];
- if (M < 0)
- continue;
- int Lane = (M % NumElts) / NumEltsPerLane;
- if (SrcLane >= 0 && SrcLane != Lane)
- return true;
- SrcLane = Lane;
- }
- }
- }
- return false;
-}
-
+/// Test whether elements in each LaneSizeInBits lane in this shuffle mask come
+/// from multiple lanes - this is different to isLaneCrossingShuffleMask to
+/// better support 'repeated mask + lane permute' style shuffles.
+static bool isMultiLaneShuffleMask(unsigned LaneSizeInBits,
+ unsigned ScalarSizeInBits,
+ ArrayRef<int> Mask) {
+ assert(LaneSizeInBits && ScalarSizeInBits &&
+ (LaneSizeInBits % ScalarSizeInBits) == 0 &&
+ "Illegal shuffle lane size");
+ int NumElts = Mask.size();
+ int NumEltsPerLane = LaneSizeInBits / ScalarSizeInBits;
+ int NumLanes = NumElts / NumEltsPerLane;
+ if (NumLanes > 1) {
+ for (int i = 0; i != NumLanes; ++i) {
+ int SrcLane = -1;
+ for (int j = 0; j != NumEltsPerLane; ++j) {
+ int M = Mask[(i * NumEltsPerLane) + j];
+ if (M < 0)
+ continue;
+ int Lane = (M % NumElts) / NumEltsPerLane;
+ if (SrcLane >= 0 && SrcLane != Lane)
+ return true;
+ SrcLane = Lane;
+ }
+ }
+ }
+ return false;
+}
+
/// Test whether a shuffle mask is equivalent within each sub-lane.
///
/// This checks a shuffle mask to see if it is performing the same
@@ -10907,11 +10907,11 @@ is256BitLaneRepeatedShuffleMask(MVT VT, ArrayRef<int> Mask,
/// Test whether a target shuffle mask is equivalent within each sub-lane.
/// Unlike isRepeatedShuffleMask we must respect SM_SentinelZero.
-static bool isRepeatedTargetShuffleMask(unsigned LaneSizeInBits,
- unsigned EltSizeInBits,
+static bool isRepeatedTargetShuffleMask(unsigned LaneSizeInBits,
+ unsigned EltSizeInBits,
ArrayRef<int> Mask,
SmallVectorImpl<int> &RepeatedMask) {
- int LaneSize = LaneSizeInBits / EltSizeInBits;
+ int LaneSize = LaneSizeInBits / EltSizeInBits;
RepeatedMask.assign(LaneSize, SM_SentinelUndef);
int Size = Mask.size();
for (int i = 0; i < Size; ++i) {
@@ -10942,67 +10942,67 @@ static bool isRepeatedTargetShuffleMask(unsigned LaneSizeInBits,
return true;
}
-/// Test whether a target shuffle mask is equivalent within each sub-lane.
-/// Unlike isRepeatedShuffleMask we must respect SM_SentinelZero.
-static bool isRepeatedTargetShuffleMask(unsigned LaneSizeInBits, MVT VT,
- ArrayRef<int> Mask,
- SmallVectorImpl<int> &RepeatedMask) {
- return isRepeatedTargetShuffleMask(LaneSizeInBits, VT.getScalarSizeInBits(),
- Mask, RepeatedMask);
-}
-
-/// Checks whether the vector elements referenced by two shuffle masks are
-/// equivalent.
-static bool IsElementEquivalent(int MaskSize, SDValue Op, SDValue ExpectedOp,
- int Idx, int ExpectedIdx) {
- assert(0 <= Idx && Idx < MaskSize && 0 <= ExpectedIdx &&
- ExpectedIdx < MaskSize && "Out of range element index");
- if (!Op || !ExpectedOp || Op.getOpcode() != ExpectedOp.getOpcode())
- return false;
-
- switch (Op.getOpcode()) {
- case ISD::BUILD_VECTOR:
- // If the values are build vectors, we can look through them to find
- // equivalent inputs that make the shuffles equivalent.
- // TODO: Handle MaskSize != Op.getNumOperands()?
- if (MaskSize == (int)Op.getNumOperands() &&
- MaskSize == (int)ExpectedOp.getNumOperands())
- return Op.getOperand(Idx) == ExpectedOp.getOperand(ExpectedIdx);
- break;
- case X86ISD::VBROADCAST:
- case X86ISD::VBROADCAST_LOAD:
- // TODO: Handle MaskSize != Op.getValueType().getVectorNumElements()?
- return (Op == ExpectedOp &&
- (int)Op.getValueType().getVectorNumElements() == MaskSize);
- case X86ISD::HADD:
- case X86ISD::HSUB:
- case X86ISD::FHADD:
- case X86ISD::FHSUB:
- case X86ISD::PACKSS:
- case X86ISD::PACKUS:
- // HOP(X,X) can refer to the elt from the lower/upper half of a lane.
- // TODO: Handle MaskSize != NumElts?
- // TODO: Handle HOP(X,Y) vs HOP(Y,X) equivalence cases.
- if (Op == ExpectedOp && Op.getOperand(0) == Op.getOperand(1)) {
- MVT VT = Op.getSimpleValueType();
- int NumElts = VT.getVectorNumElements();
- if (MaskSize == NumElts) {
- int NumLanes = VT.getSizeInBits() / 128;
- int NumEltsPerLane = NumElts / NumLanes;
- int NumHalfEltsPerLane = NumEltsPerLane / 2;
- bool SameLane =
- (Idx / NumEltsPerLane) == (ExpectedIdx / NumEltsPerLane);
- bool SameElt =
- (Idx % NumHalfEltsPerLane) == (ExpectedIdx % NumHalfEltsPerLane);
- return SameLane && SameElt;
- }
- }
- break;
- }
-
- return false;
-}
-
+/// Test whether a target shuffle mask is equivalent within each sub-lane.
+/// Unlike isRepeatedShuffleMask we must respect SM_SentinelZero.
+static bool isRepeatedTargetShuffleMask(unsigned LaneSizeInBits, MVT VT,
+ ArrayRef<int> Mask,
+ SmallVectorImpl<int> &RepeatedMask) {
+ return isRepeatedTargetShuffleMask(LaneSizeInBits, VT.getScalarSizeInBits(),
+ Mask, RepeatedMask);
+}
+
+/// Checks whether the vector elements referenced by two shuffle masks are
+/// equivalent.
+static bool IsElementEquivalent(int MaskSize, SDValue Op, SDValue ExpectedOp,
+ int Idx, int ExpectedIdx) {
+ assert(0 <= Idx && Idx < MaskSize && 0 <= ExpectedIdx &&
+ ExpectedIdx < MaskSize && "Out of range element index");
+ if (!Op || !ExpectedOp || Op.getOpcode() != ExpectedOp.getOpcode())
+ return false;
+
+ switch (Op.getOpcode()) {
+ case ISD::BUILD_VECTOR:
+ // If the values are build vectors, we can look through them to find
+ // equivalent inputs that make the shuffles equivalent.
+ // TODO: Handle MaskSize != Op.getNumOperands()?
+ if (MaskSize == (int)Op.getNumOperands() &&
+ MaskSize == (int)ExpectedOp.getNumOperands())
+ return Op.getOperand(Idx) == ExpectedOp.getOperand(ExpectedIdx);
+ break;
+ case X86ISD::VBROADCAST:
+ case X86ISD::VBROADCAST_LOAD:
+ // TODO: Handle MaskSize != Op.getValueType().getVectorNumElements()?
+ return (Op == ExpectedOp &&
+ (int)Op.getValueType().getVectorNumElements() == MaskSize);
+ case X86ISD::HADD:
+ case X86ISD::HSUB:
+ case X86ISD::FHADD:
+ case X86ISD::FHSUB:
+ case X86ISD::PACKSS:
+ case X86ISD::PACKUS:
+ // HOP(X,X) can refer to the elt from the lower/upper half of a lane.
+ // TODO: Handle MaskSize != NumElts?
+ // TODO: Handle HOP(X,Y) vs HOP(Y,X) equivalence cases.
+ if (Op == ExpectedOp && Op.getOperand(0) == Op.getOperand(1)) {
+ MVT VT = Op.getSimpleValueType();
+ int NumElts = VT.getVectorNumElements();
+ if (MaskSize == NumElts) {
+ int NumLanes = VT.getSizeInBits() / 128;
+ int NumEltsPerLane = NumElts / NumLanes;
+ int NumHalfEltsPerLane = NumEltsPerLane / 2;
+ bool SameLane =
+ (Idx / NumEltsPerLane) == (ExpectedIdx / NumEltsPerLane);
+ bool SameElt =
+ (Idx % NumHalfEltsPerLane) == (ExpectedIdx % NumHalfEltsPerLane);
+ return SameLane && SameElt;
+ }
+ }
+ break;
+ }
+
+ return false;
+}
+
/// Checks whether a shuffle mask is equivalent to an explicit list of
/// arguments.
///
@@ -11013,23 +11013,23 @@ static bool IsElementEquivalent(int MaskSize, SDValue Op, SDValue ExpectedOp,
/// It returns true if the mask is exactly as wide as the argument list, and
/// each element of the mask is either -1 (signifying undef) or the value given
/// in the argument.
-static bool isShuffleEquivalent(ArrayRef<int> Mask, ArrayRef<int> ExpectedMask,
- SDValue V1 = SDValue(),
- SDValue V2 = SDValue()) {
- int Size = Mask.size();
- if (Size != (int)ExpectedMask.size())
+static bool isShuffleEquivalent(ArrayRef<int> Mask, ArrayRef<int> ExpectedMask,
+ SDValue V1 = SDValue(),
+ SDValue V2 = SDValue()) {
+ int Size = Mask.size();
+ if (Size != (int)ExpectedMask.size())
return false;
for (int i = 0; i < Size; ++i) {
assert(Mask[i] >= -1 && "Out of bound mask element!");
- int MaskIdx = Mask[i];
- int ExpectedIdx = ExpectedMask[i];
- if (0 <= MaskIdx && MaskIdx != ExpectedIdx) {
- SDValue MaskV = MaskIdx < Size ? V1 : V2;
- SDValue ExpectedV = ExpectedIdx < Size ? V1 : V2;
- MaskIdx = MaskIdx < Size ? MaskIdx : (MaskIdx - Size);
- ExpectedIdx = ExpectedIdx < Size ? ExpectedIdx : (ExpectedIdx - Size);
- if (!IsElementEquivalent(Size, MaskV, ExpectedV, MaskIdx, ExpectedIdx))
+ int MaskIdx = Mask[i];
+ int ExpectedIdx = ExpectedMask[i];
+ if (0 <= MaskIdx && MaskIdx != ExpectedIdx) {
+ SDValue MaskV = MaskIdx < Size ? V1 : V2;
+ SDValue ExpectedV = ExpectedIdx < Size ? V1 : V2;
+ MaskIdx = MaskIdx < Size ? MaskIdx : (MaskIdx - Size);
+ ExpectedIdx = ExpectedIdx < Size ? ExpectedIdx : (ExpectedIdx - Size);
+ if (!IsElementEquivalent(Size, MaskV, ExpectedV, MaskIdx, ExpectedIdx))
return false;
}
}
@@ -11045,7 +11045,7 @@ static bool isShuffleEquivalent(ArrayRef<int> Mask, ArrayRef<int> ExpectedMask,
///
/// SM_SentinelZero is accepted as a valid negative index but must match in
/// both.
-static bool isTargetShuffleEquivalent(MVT VT, ArrayRef<int> Mask,
+static bool isTargetShuffleEquivalent(MVT VT, ArrayRef<int> Mask,
ArrayRef<int> ExpectedMask,
SDValue V1 = SDValue(),
SDValue V2 = SDValue()) {
@@ -11059,23 +11059,23 @@ static bool isTargetShuffleEquivalent(MVT VT, ArrayRef<int> Mask,
if (!isUndefOrZeroOrInRange(Mask, 0, 2 * Size))
return false;
- // Don't use V1/V2 if they're not the same size as the shuffle mask type.
- if (V1 && V1.getValueSizeInBits() != VT.getSizeInBits())
- V1 = SDValue();
- if (V2 && V2.getValueSizeInBits() != VT.getSizeInBits())
- V2 = SDValue();
+ // Don't use V1/V2 if they're not the same size as the shuffle mask type.
+ if (V1 && V1.getValueSizeInBits() != VT.getSizeInBits())
+ V1 = SDValue();
+ if (V2 && V2.getValueSizeInBits() != VT.getSizeInBits())
+ V2 = SDValue();
for (int i = 0; i < Size; ++i) {
- int MaskIdx = Mask[i];
- int ExpectedIdx = ExpectedMask[i];
- if (MaskIdx == SM_SentinelUndef || MaskIdx == ExpectedIdx)
+ int MaskIdx = Mask[i];
+ int ExpectedIdx = ExpectedMask[i];
+ if (MaskIdx == SM_SentinelUndef || MaskIdx == ExpectedIdx)
continue;
- if (0 <= MaskIdx && 0 <= ExpectedIdx) {
- SDValue MaskV = MaskIdx < Size ? V1 : V2;
- SDValue ExpectedV = ExpectedIdx < Size ? V1 : V2;
- MaskIdx = MaskIdx < Size ? MaskIdx : (MaskIdx - Size);
- ExpectedIdx = ExpectedIdx < Size ? ExpectedIdx : (ExpectedIdx - Size);
- if (IsElementEquivalent(Size, MaskV, ExpectedV, MaskIdx, ExpectedIdx))
+ if (0 <= MaskIdx && 0 <= ExpectedIdx) {
+ SDValue MaskV = MaskIdx < Size ? V1 : V2;
+ SDValue ExpectedV = ExpectedIdx < Size ? V1 : V2;
+ MaskIdx = MaskIdx < Size ? MaskIdx : (MaskIdx - Size);
+ ExpectedIdx = ExpectedIdx < Size ? ExpectedIdx : (ExpectedIdx - Size);
+ if (IsElementEquivalent(Size, MaskV, ExpectedV, MaskIdx, ExpectedIdx))
continue;
}
// TODO - handle SM_Sentinel equivalences.
@@ -11087,25 +11087,25 @@ static bool isTargetShuffleEquivalent(MVT VT, ArrayRef<int> Mask,
// Attempt to create a shuffle mask from a VSELECT condition mask.
static bool createShuffleMaskFromVSELECT(SmallVectorImpl<int> &Mask,
SDValue Cond) {
- EVT CondVT = Cond.getValueType();
- unsigned EltSizeInBits = CondVT.getScalarSizeInBits();
- unsigned NumElts = CondVT.getVectorNumElements();
-
- APInt UndefElts;
- SmallVector<APInt, 32> EltBits;
- if (!getTargetConstantBitsFromNode(Cond, EltSizeInBits, UndefElts, EltBits,
- true, false))
+ EVT CondVT = Cond.getValueType();
+ unsigned EltSizeInBits = CondVT.getScalarSizeInBits();
+ unsigned NumElts = CondVT.getVectorNumElements();
+
+ APInt UndefElts;
+ SmallVector<APInt, 32> EltBits;
+ if (!getTargetConstantBitsFromNode(Cond, EltSizeInBits, UndefElts, EltBits,
+ true, false))
return false;
- Mask.resize(NumElts, SM_SentinelUndef);
+ Mask.resize(NumElts, SM_SentinelUndef);
- for (int i = 0; i != (int)NumElts; ++i) {
+ for (int i = 0; i != (int)NumElts; ++i) {
Mask[i] = i;
// Arbitrarily choose from the 2nd operand if the select condition element
// is undef.
// TODO: Can we do better by matching patterns such as even/odd?
- if (UndefElts[i] || EltBits[i].isNullValue())
- Mask[i] += NumElts;
+ if (UndefElts[i] || EltBits[i].isNullValue())
+ Mask[i] += NumElts;
}
return true;
@@ -11123,8 +11123,8 @@ static bool isUnpackWdShuffleMask(ArrayRef<int> Mask, MVT VT) {
SmallVector<int, 8> Unpckhwd;
createUnpackShuffleMask(MVT::v8i16, Unpckhwd, /* Lo = */ false,
/* Unary = */ false);
- bool IsUnpackwdMask = (isTargetShuffleEquivalent(VT, Mask, Unpcklwd) ||
- isTargetShuffleEquivalent(VT, Mask, Unpckhwd));
+ bool IsUnpackwdMask = (isTargetShuffleEquivalent(VT, Mask, Unpcklwd) ||
+ isTargetShuffleEquivalent(VT, Mask, Unpckhwd));
return IsUnpackwdMask;
}
@@ -11141,8 +11141,8 @@ static bool is128BitUnpackShuffleMask(ArrayRef<int> Mask) {
for (unsigned i = 0; i != 4; ++i) {
SmallVector<int, 16> UnpackMask;
createUnpackShuffleMask(VT, UnpackMask, (i >> 1) % 2, i % 2);
- if (isTargetShuffleEquivalent(VT, Mask, UnpackMask) ||
- isTargetShuffleEquivalent(VT, CommutedMask, UnpackMask))
+ if (isTargetShuffleEquivalent(VT, Mask, UnpackMask) ||
+ isTargetShuffleEquivalent(VT, CommutedMask, UnpackMask))
return true;
}
return false;
@@ -11177,15 +11177,15 @@ static unsigned getV4X86ShuffleImm(ArrayRef<int> Mask) {
assert(Mask[2] >= -1 && Mask[2] < 4 && "Out of bound mask element!");
assert(Mask[3] >= -1 && Mask[3] < 4 && "Out of bound mask element!");
- // If the mask only uses one non-undef element, then fully 'splat' it to
- // improve later broadcast matching.
- int FirstIndex = find_if(Mask, [](int M) { return M >= 0; }) - Mask.begin();
- assert(0 <= FirstIndex && FirstIndex < 4 && "All undef shuffle mask");
-
- int FirstElt = Mask[FirstIndex];
- if (all_of(Mask, [FirstElt](int M) { return M < 0 || M == FirstElt; }))
- return (FirstElt << 6) | (FirstElt << 4) | (FirstElt << 2) | FirstElt;
-
+ // If the mask only uses one non-undef element, then fully 'splat' it to
+ // improve later broadcast matching.
+ int FirstIndex = find_if(Mask, [](int M) { return M >= 0; }) - Mask.begin();
+ assert(0 <= FirstIndex && FirstIndex < 4 && "All undef shuffle mask");
+
+ int FirstElt = Mask[FirstIndex];
+ if (all_of(Mask, [FirstElt](int M) { return M < 0 || M == FirstElt; }))
+ return (FirstElt << 6) | (FirstElt << 4) | (FirstElt << 2) | FirstElt;
+
unsigned Imm = 0;
Imm |= (Mask[0] < 0 ? 0 : Mask[0]) << 0;
Imm |= (Mask[1] < 0 ? 1 : Mask[1]) << 2;
@@ -11335,8 +11335,8 @@ static bool matchShuffleWithUNPCK(MVT VT, SDValue &V1, SDValue &V2,
// Attempt to match the target mask against the unpack lo/hi mask patterns.
SmallVector<int, 64> Unpckl, Unpckh;
createUnpackShuffleMask(VT, Unpckl, /* Lo = */ true, IsUnary);
- if (isTargetShuffleEquivalent(VT, TargetMask, Unpckl, V1,
- (IsUnary ? V1 : V2))) {
+ if (isTargetShuffleEquivalent(VT, TargetMask, Unpckl, V1,
+ (IsUnary ? V1 : V2))) {
UnpackOpcode = X86ISD::UNPCKL;
V2 = (Undef2 ? DAG.getUNDEF(VT) : (IsUnary ? V1 : V2));
V1 = (Undef1 ? DAG.getUNDEF(VT) : V1);
@@ -11344,8 +11344,8 @@ static bool matchShuffleWithUNPCK(MVT VT, SDValue &V1, SDValue &V2,
}
createUnpackShuffleMask(VT, Unpckh, /* Lo = */ false, IsUnary);
- if (isTargetShuffleEquivalent(VT, TargetMask, Unpckh, V1,
- (IsUnary ? V1 : V2))) {
+ if (isTargetShuffleEquivalent(VT, TargetMask, Unpckh, V1,
+ (IsUnary ? V1 : V2))) {
UnpackOpcode = X86ISD::UNPCKH;
V2 = (Undef2 ? DAG.getUNDEF(VT) : (IsUnary ? V1 : V2));
V1 = (Undef1 ? DAG.getUNDEF(VT) : V1);
@@ -11383,14 +11383,14 @@ static bool matchShuffleWithUNPCK(MVT VT, SDValue &V1, SDValue &V2,
// If a binary shuffle, commute and try again.
if (!IsUnary) {
ShuffleVectorSDNode::commuteMask(Unpckl);
- if (isTargetShuffleEquivalent(VT, TargetMask, Unpckl)) {
+ if (isTargetShuffleEquivalent(VT, TargetMask, Unpckl)) {
UnpackOpcode = X86ISD::UNPCKL;
std::swap(V1, V2);
return true;
}
ShuffleVectorSDNode::commuteMask(Unpckh);
- if (isTargetShuffleEquivalent(VT, TargetMask, Unpckh)) {
+ if (isTargetShuffleEquivalent(VT, TargetMask, Unpckh)) {
UnpackOpcode = X86ISD::UNPCKH;
std::swap(V1, V2);
return true;
@@ -11407,21 +11407,21 @@ static SDValue lowerShuffleWithUNPCK(const SDLoc &DL, MVT VT,
SelectionDAG &DAG) {
SmallVector<int, 8> Unpckl;
createUnpackShuffleMask(VT, Unpckl, /* Lo = */ true, /* Unary = */ false);
- if (isShuffleEquivalent(Mask, Unpckl, V1, V2))
+ if (isShuffleEquivalent(Mask, Unpckl, V1, V2))
return DAG.getNode(X86ISD::UNPCKL, DL, VT, V1, V2);
SmallVector<int, 8> Unpckh;
createUnpackShuffleMask(VT, Unpckh, /* Lo = */ false, /* Unary = */ false);
- if (isShuffleEquivalent(Mask, Unpckh, V1, V2))
+ if (isShuffleEquivalent(Mask, Unpckh, V1, V2))
return DAG.getNode(X86ISD::UNPCKH, DL, VT, V1, V2);
// Commute and try again.
ShuffleVectorSDNode::commuteMask(Unpckl);
- if (isShuffleEquivalent(Mask, Unpckl, V1, V2))
+ if (isShuffleEquivalent(Mask, Unpckl, V1, V2))
return DAG.getNode(X86ISD::UNPCKL, DL, VT, V2, V1);
ShuffleVectorSDNode::commuteMask(Unpckh);
- if (isShuffleEquivalent(Mask, Unpckh, V1, V2))
+ if (isShuffleEquivalent(Mask, Unpckh, V1, V2))
return DAG.getNode(X86ISD::UNPCKH, DL, VT, V2, V1);
return SDValue();
@@ -11437,9 +11437,9 @@ static SDValue lowerShuffleWithUNPCK256(const SDLoc &DL, MVT VT,
createSplat2ShuffleMask(VT, Unpckh, /* Lo */ false);
unsigned UnpackOpcode;
- if (isShuffleEquivalent(Mask, Unpckl, V1, V2))
+ if (isShuffleEquivalent(Mask, Unpckl, V1, V2))
UnpackOpcode = X86ISD::UNPCKL;
- else if (isShuffleEquivalent(Mask, Unpckh, V1, V2))
+ else if (isShuffleEquivalent(Mask, Unpckh, V1, V2))
UnpackOpcode = X86ISD::UNPCKH;
else
return SDValue();
@@ -11491,51 +11491,51 @@ static bool matchShuffleAsVTRUNC(MVT &SrcVT, MVT &DstVT, MVT VT,
return false;
}
-// Helper to create TRUNCATE/VTRUNC nodes, optionally with zero/undef upper
-// element padding to the final DstVT.
-static SDValue getAVX512TruncNode(const SDLoc &DL, MVT DstVT, SDValue Src,
- const X86Subtarget &Subtarget,
- SelectionDAG &DAG, bool ZeroUppers) {
- MVT SrcVT = Src.getSimpleValueType();
- MVT DstSVT = DstVT.getScalarType();
- unsigned NumDstElts = DstVT.getVectorNumElements();
- unsigned NumSrcElts = SrcVT.getVectorNumElements();
- unsigned DstEltSizeInBits = DstVT.getScalarSizeInBits();
-
- if (!DAG.getTargetLoweringInfo().isTypeLegal(SrcVT))
- return SDValue();
-
- // Perform a direct ISD::TRUNCATE if possible.
- if (NumSrcElts == NumDstElts)
- return DAG.getNode(ISD::TRUNCATE, DL, DstVT, Src);
-
- if (NumSrcElts > NumDstElts) {
- MVT TruncVT = MVT::getVectorVT(DstSVT, NumSrcElts);
- SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, TruncVT, Src);
- return extractSubVector(Trunc, 0, DAG, DL, DstVT.getSizeInBits());
- }
-
- if ((NumSrcElts * DstEltSizeInBits) >= 128) {
- MVT TruncVT = MVT::getVectorVT(DstSVT, NumSrcElts);
- SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, TruncVT, Src);
- return widenSubVector(Trunc, ZeroUppers, Subtarget, DAG, DL,
- DstVT.getSizeInBits());
- }
-
- // Non-VLX targets must truncate from a 512-bit type, so we need to
- // widen, truncate and then possibly extract the original subvector.
- if (!Subtarget.hasVLX() && !SrcVT.is512BitVector()) {
- SDValue NewSrc = widenSubVector(Src, ZeroUppers, Subtarget, DAG, DL, 512);
- return getAVX512TruncNode(DL, DstVT, NewSrc, Subtarget, DAG, ZeroUppers);
- }
-
- // Fallback to a X86ISD::VTRUNC, padding if necessary.
- MVT TruncVT = MVT::getVectorVT(DstSVT, 128 / DstEltSizeInBits);
- SDValue Trunc = DAG.getNode(X86ISD::VTRUNC, DL, TruncVT, Src);
- if (DstVT != TruncVT)
- Trunc = widenSubVector(Trunc, ZeroUppers, Subtarget, DAG, DL,
- DstVT.getSizeInBits());
- return Trunc;
+// Helper to create TRUNCATE/VTRUNC nodes, optionally with zero/undef upper
+// element padding to the final DstVT.
+static SDValue getAVX512TruncNode(const SDLoc &DL, MVT DstVT, SDValue Src,
+ const X86Subtarget &Subtarget,
+ SelectionDAG &DAG, bool ZeroUppers) {
+ MVT SrcVT = Src.getSimpleValueType();
+ MVT DstSVT = DstVT.getScalarType();
+ unsigned NumDstElts = DstVT.getVectorNumElements();
+ unsigned NumSrcElts = SrcVT.getVectorNumElements();
+ unsigned DstEltSizeInBits = DstVT.getScalarSizeInBits();
+
+ if (!DAG.getTargetLoweringInfo().isTypeLegal(SrcVT))
+ return SDValue();
+
+ // Perform a direct ISD::TRUNCATE if possible.
+ if (NumSrcElts == NumDstElts)
+ return DAG.getNode(ISD::TRUNCATE, DL, DstVT, Src);
+
+ if (NumSrcElts > NumDstElts) {
+ MVT TruncVT = MVT::getVectorVT(DstSVT, NumSrcElts);
+ SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, TruncVT, Src);
+ return extractSubVector(Trunc, 0, DAG, DL, DstVT.getSizeInBits());
+ }
+
+ if ((NumSrcElts * DstEltSizeInBits) >= 128) {
+ MVT TruncVT = MVT::getVectorVT(DstSVT, NumSrcElts);
+ SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, TruncVT, Src);
+ return widenSubVector(Trunc, ZeroUppers, Subtarget, DAG, DL,
+ DstVT.getSizeInBits());
+ }
+
+ // Non-VLX targets must truncate from a 512-bit type, so we need to
+ // widen, truncate and then possibly extract the original subvector.
+ if (!Subtarget.hasVLX() && !SrcVT.is512BitVector()) {
+ SDValue NewSrc = widenSubVector(Src, ZeroUppers, Subtarget, DAG, DL, 512);
+ return getAVX512TruncNode(DL, DstVT, NewSrc, Subtarget, DAG, ZeroUppers);
+ }
+
+ // Fallback to a X86ISD::VTRUNC, padding if necessary.
+ MVT TruncVT = MVT::getVectorVT(DstSVT, 128 / DstEltSizeInBits);
+ SDValue Trunc = DAG.getNode(X86ISD::VTRUNC, DL, TruncVT, Src);
+ if (DstVT != TruncVT)
+ Trunc = widenSubVector(Trunc, ZeroUppers, Subtarget, DAG, DL,
+ DstVT.getSizeInBits());
+ return Trunc;
}
// Try to lower trunc+vector_shuffle to a vpmovdb or a vpmovdw instruction.
@@ -11551,99 +11551,99 @@ static SDValue getAVX512TruncNode(const SDLoc &DL, MVT DstVT, SDValue Src,
// t51: v8i16 = vector_shuffle<0,2,4,6,12,13,14,15> t41, t21
// t18: v2i64 = bitcast t51
//
-// One can just use a single vpmovdw instruction, without avx512vl we need to
-// use the zmm variant and extract the lower subvector, padding with zeroes.
-// TODO: Merge with lowerShuffleAsVTRUNC.
-static SDValue lowerShuffleWithVPMOV(const SDLoc &DL, MVT VT, SDValue V1,
- SDValue V2, ArrayRef<int> Mask,
- const APInt &Zeroable,
- const X86Subtarget &Subtarget,
- SelectionDAG &DAG) {
- assert((VT == MVT::v16i8 || VT == MVT::v8i16) && "Unexpected VTRUNC type");
- if (!Subtarget.hasAVX512())
- return SDValue();
-
- unsigned NumElts = VT.getVectorNumElements();
- unsigned EltSizeInBits = VT.getScalarSizeInBits();
- unsigned MaxScale = 64 / EltSizeInBits;
- for (unsigned Scale = 2; Scale <= MaxScale; Scale += Scale) {
- unsigned NumSrcElts = NumElts / Scale;
- unsigned UpperElts = NumElts - NumSrcElts;
- if (!isSequentialOrUndefInRange(Mask, 0, NumSrcElts, 0, Scale) ||
- !Zeroable.extractBits(UpperElts, NumSrcElts).isAllOnesValue())
- continue;
-
- SDValue Src = V1;
- if (!Src.hasOneUse())
- return SDValue();
-
- Src = peekThroughOneUseBitcasts(Src);
- if (Src.getOpcode() != ISD::TRUNCATE ||
- Src.getScalarValueSizeInBits() != (EltSizeInBits * Scale))
+// One can just use a single vpmovdw instruction, without avx512vl we need to
+// use the zmm variant and extract the lower subvector, padding with zeroes.
+// TODO: Merge with lowerShuffleAsVTRUNC.
+static SDValue lowerShuffleWithVPMOV(const SDLoc &DL, MVT VT, SDValue V1,
+ SDValue V2, ArrayRef<int> Mask,
+ const APInt &Zeroable,
+ const X86Subtarget &Subtarget,
+ SelectionDAG &DAG) {
+ assert((VT == MVT::v16i8 || VT == MVT::v8i16) && "Unexpected VTRUNC type");
+ if (!Subtarget.hasAVX512())
+ return SDValue();
+
+ unsigned NumElts = VT.getVectorNumElements();
+ unsigned EltSizeInBits = VT.getScalarSizeInBits();
+ unsigned MaxScale = 64 / EltSizeInBits;
+ for (unsigned Scale = 2; Scale <= MaxScale; Scale += Scale) {
+ unsigned NumSrcElts = NumElts / Scale;
+ unsigned UpperElts = NumElts - NumSrcElts;
+ if (!isSequentialOrUndefInRange(Mask, 0, NumSrcElts, 0, Scale) ||
+ !Zeroable.extractBits(UpperElts, NumSrcElts).isAllOnesValue())
+ continue;
+
+ SDValue Src = V1;
+ if (!Src.hasOneUse())
+ return SDValue();
+
+ Src = peekThroughOneUseBitcasts(Src);
+ if (Src.getOpcode() != ISD::TRUNCATE ||
+ Src.getScalarValueSizeInBits() != (EltSizeInBits * Scale))
+ return SDValue();
+ Src = Src.getOperand(0);
+
+ // VPMOVWB is only available with avx512bw.
+ MVT SrcVT = Src.getSimpleValueType();
+ if (SrcVT.getVectorElementType() == MVT::i16 && VT == MVT::v16i8 &&
+ !Subtarget.hasBWI())
return SDValue();
- Src = Src.getOperand(0);
-
- // VPMOVWB is only available with avx512bw.
- MVT SrcVT = Src.getSimpleValueType();
- if (SrcVT.getVectorElementType() == MVT::i16 && VT == MVT::v16i8 &&
- !Subtarget.hasBWI())
- return SDValue();
-
- bool UndefUppers = isUndefInRange(Mask, NumSrcElts, UpperElts);
- return getAVX512TruncNode(DL, VT, Src, Subtarget, DAG, !UndefUppers);
- }
-
- return SDValue();
-}
-
-// Attempt to match binary shuffle patterns as a truncate.
-static SDValue lowerShuffleAsVTRUNC(const SDLoc &DL, MVT VT, SDValue V1,
- SDValue V2, ArrayRef<int> Mask,
- const APInt &Zeroable,
- const X86Subtarget &Subtarget,
- SelectionDAG &DAG) {
- assert((VT.is128BitVector() || VT.is256BitVector()) &&
- "Unexpected VTRUNC type");
- if (!Subtarget.hasAVX512())
- return SDValue();
-
- unsigned NumElts = VT.getVectorNumElements();
- unsigned EltSizeInBits = VT.getScalarSizeInBits();
- unsigned MaxScale = 64 / EltSizeInBits;
- for (unsigned Scale = 2; Scale <= MaxScale; Scale += Scale) {
- // TODO: Support non-BWI VPMOVWB truncations?
- unsigned SrcEltBits = EltSizeInBits * Scale;
- if (SrcEltBits < 32 && !Subtarget.hasBWI())
- continue;
-
- // Match shuffle <0,Scale,2*Scale,..,undef_or_zero,undef_or_zero,...>
- // Bail if the V2 elements are undef.
- unsigned NumHalfSrcElts = NumElts / Scale;
- unsigned NumSrcElts = 2 * NumHalfSrcElts;
- if (!isSequentialOrUndefInRange(Mask, 0, NumSrcElts, 0, Scale) ||
- isUndefInRange(Mask, NumHalfSrcElts, NumHalfSrcElts))
- continue;
-
- // The elements beyond the truncation must be undef/zero.
- unsigned UpperElts = NumElts - NumSrcElts;
- if (UpperElts > 0 &&
- !Zeroable.extractBits(UpperElts, NumSrcElts).isAllOnesValue())
- continue;
- bool UndefUppers =
- UpperElts > 0 && isUndefInRange(Mask, NumSrcElts, UpperElts);
-
- // As we're using both sources then we need to concat them together
- // and truncate from the double-sized src.
- MVT ConcatVT = MVT::getVectorVT(VT.getScalarType(), NumElts * 2);
- SDValue Src = DAG.getNode(ISD::CONCAT_VECTORS, DL, ConcatVT, V1, V2);
-
- MVT SrcSVT = MVT::getIntegerVT(SrcEltBits);
- MVT SrcVT = MVT::getVectorVT(SrcSVT, NumSrcElts);
- Src = DAG.getBitcast(SrcVT, Src);
- return getAVX512TruncNode(DL, VT, Src, Subtarget, DAG, !UndefUppers);
- }
-
- return SDValue();
+
+ bool UndefUppers = isUndefInRange(Mask, NumSrcElts, UpperElts);
+ return getAVX512TruncNode(DL, VT, Src, Subtarget, DAG, !UndefUppers);
+ }
+
+ return SDValue();
+}
+
+// Attempt to match binary shuffle patterns as a truncate.
+static SDValue lowerShuffleAsVTRUNC(const SDLoc &DL, MVT VT, SDValue V1,
+ SDValue V2, ArrayRef<int> Mask,
+ const APInt &Zeroable,
+ const X86Subtarget &Subtarget,
+ SelectionDAG &DAG) {
+ assert((VT.is128BitVector() || VT.is256BitVector()) &&
+ "Unexpected VTRUNC type");
+ if (!Subtarget.hasAVX512())
+ return SDValue();
+
+ unsigned NumElts = VT.getVectorNumElements();
+ unsigned EltSizeInBits = VT.getScalarSizeInBits();
+ unsigned MaxScale = 64 / EltSizeInBits;
+ for (unsigned Scale = 2; Scale <= MaxScale; Scale += Scale) {
+ // TODO: Support non-BWI VPMOVWB truncations?
+ unsigned SrcEltBits = EltSizeInBits * Scale;
+ if (SrcEltBits < 32 && !Subtarget.hasBWI())
+ continue;
+
+ // Match shuffle <0,Scale,2*Scale,..,undef_or_zero,undef_or_zero,...>
+ // Bail if the V2 elements are undef.
+ unsigned NumHalfSrcElts = NumElts / Scale;
+ unsigned NumSrcElts = 2 * NumHalfSrcElts;
+ if (!isSequentialOrUndefInRange(Mask, 0, NumSrcElts, 0, Scale) ||
+ isUndefInRange(Mask, NumHalfSrcElts, NumHalfSrcElts))
+ continue;
+
+ // The elements beyond the truncation must be undef/zero.
+ unsigned UpperElts = NumElts - NumSrcElts;
+ if (UpperElts > 0 &&
+ !Zeroable.extractBits(UpperElts, NumSrcElts).isAllOnesValue())
+ continue;
+ bool UndefUppers =
+ UpperElts > 0 && isUndefInRange(Mask, NumSrcElts, UpperElts);
+
+ // As we're using both sources then we need to concat them together
+ // and truncate from the double-sized src.
+ MVT ConcatVT = MVT::getVectorVT(VT.getScalarType(), NumElts * 2);
+ SDValue Src = DAG.getNode(ISD::CONCAT_VECTORS, DL, ConcatVT, V1, V2);
+
+ MVT SrcSVT = MVT::getIntegerVT(SrcEltBits);
+ MVT SrcVT = MVT::getVectorVT(SrcSVT, NumSrcElts);
+ Src = DAG.getBitcast(SrcVT, Src);
+ return getAVX512TruncNode(DL, VT, Src, Subtarget, DAG, !UndefUppers);
+ }
+
+ return SDValue();
}
/// Check whether a compaction lowering can be done by dropping even
@@ -11761,14 +11761,14 @@ static bool matchShuffleWithPACK(MVT VT, MVT &SrcVT, SDValue &V1, SDValue &V2,
// Try binary shuffle.
SmallVector<int, 32> BinaryMask;
createPackShuffleMask(VT, BinaryMask, false, NumStages);
- if (isTargetShuffleEquivalent(VT, TargetMask, BinaryMask, V1, V2))
+ if (isTargetShuffleEquivalent(VT, TargetMask, BinaryMask, V1, V2))
if (MatchPACK(V1, V2, PackVT))
return true;
// Try unary shuffle.
SmallVector<int, 32> UnaryMask;
createPackShuffleMask(VT, UnaryMask, true, NumStages);
- if (isTargetShuffleEquivalent(VT, TargetMask, UnaryMask, V1))
+ if (isTargetShuffleEquivalent(VT, TargetMask, UnaryMask, V1))
if (MatchPACK(V1, V1, PackVT))
return true;
}
@@ -12317,32 +12317,32 @@ static SDValue lowerShuffleAsByteRotateAndPermute(
/// This matches the extremely common pattern for handling combined
/// shuffle+blend operations on newer X86 ISAs where we have very fast blend
/// operations. It will try to pick the best arrangement of shuffles and
-/// blends. For vXi8/vXi16 shuffles we may use unpack instead of blend.
-static SDValue lowerShuffleAsDecomposedShuffleMerge(
+/// blends. For vXi8/vXi16 shuffles we may use unpack instead of blend.
+static SDValue lowerShuffleAsDecomposedShuffleMerge(
const SDLoc &DL, MVT VT, SDValue V1, SDValue V2, ArrayRef<int> Mask,
const X86Subtarget &Subtarget, SelectionDAG &DAG) {
- int NumElts = Mask.size();
- int NumLanes = VT.getSizeInBits() / 128;
- int NumEltsPerLane = NumElts / NumLanes;
-
+ int NumElts = Mask.size();
+ int NumLanes = VT.getSizeInBits() / 128;
+ int NumEltsPerLane = NumElts / NumLanes;
+
// Shuffle the input elements into the desired positions in V1 and V2 and
- // unpack/blend them together.
- bool IsAlternating = true;
- SmallVector<int, 32> V1Mask(NumElts, -1);
- SmallVector<int, 32> V2Mask(NumElts, -1);
- SmallVector<int, 32> FinalMask(NumElts, -1);
- for (int i = 0; i < NumElts; ++i) {
- int M = Mask[i];
- if (M >= 0 && M < NumElts) {
- V1Mask[i] = M;
- FinalMask[i] = i;
- IsAlternating &= (i & 1) == 0;
- } else if (M >= NumElts) {
- V2Mask[i] = M - NumElts;
- FinalMask[i] = i + NumElts;
- IsAlternating &= (i & 1) == 1;
- }
- }
+ // unpack/blend them together.
+ bool IsAlternating = true;
+ SmallVector<int, 32> V1Mask(NumElts, -1);
+ SmallVector<int, 32> V2Mask(NumElts, -1);
+ SmallVector<int, 32> FinalMask(NumElts, -1);
+ for (int i = 0; i < NumElts; ++i) {
+ int M = Mask[i];
+ if (M >= 0 && M < NumElts) {
+ V1Mask[i] = M;
+ FinalMask[i] = i;
+ IsAlternating &= (i & 1) == 0;
+ } else if (M >= NumElts) {
+ V2Mask[i] = M - NumElts;
+ FinalMask[i] = i + NumElts;
+ IsAlternating &= (i & 1) == 1;
+ }
+ }
// Try to lower with the simpler initial blend/unpack/rotate strategies unless
// one of the input shuffles would be a no-op. We prefer to shuffle inputs as
@@ -12366,30 +12366,30 @@ static SDValue lowerShuffleAsDecomposedShuffleMerge(
return BlendPerm;
}
- // If the final mask is an alternating blend of vXi8/vXi16, convert to an
- // UNPCKL(SHUFFLE, SHUFFLE) pattern.
- // TODO: It doesn't have to be alternating - but each lane mustn't have more
- // than half the elements coming from each source.
- if (IsAlternating && VT.getScalarSizeInBits() < 32) {
- V1Mask.assign(NumElts, -1);
- V2Mask.assign(NumElts, -1);
- FinalMask.assign(NumElts, -1);
- for (int i = 0; i != NumElts; i += NumEltsPerLane)
- for (int j = 0; j != NumEltsPerLane; ++j) {
- int M = Mask[i + j];
- if (M >= 0 && M < NumElts) {
- V1Mask[i + (j / 2)] = M;
- FinalMask[i + j] = i + (j / 2);
- } else if (M >= NumElts) {
- V2Mask[i + (j / 2)] = M - NumElts;
- FinalMask[i + j] = i + (j / 2) + NumElts;
- }
- }
- }
-
+ // If the final mask is an alternating blend of vXi8/vXi16, convert to an
+ // UNPCKL(SHUFFLE, SHUFFLE) pattern.
+ // TODO: It doesn't have to be alternating - but each lane mustn't have more
+ // than half the elements coming from each source.
+ if (IsAlternating && VT.getScalarSizeInBits() < 32) {
+ V1Mask.assign(NumElts, -1);
+ V2Mask.assign(NumElts, -1);
+ FinalMask.assign(NumElts, -1);
+ for (int i = 0; i != NumElts; i += NumEltsPerLane)
+ for (int j = 0; j != NumEltsPerLane; ++j) {
+ int M = Mask[i + j];
+ if (M >= 0 && M < NumElts) {
+ V1Mask[i + (j / 2)] = M;
+ FinalMask[i + j] = i + (j / 2);
+ } else if (M >= NumElts) {
+ V2Mask[i + (j / 2)] = M - NumElts;
+ FinalMask[i + j] = i + (j / 2) + NumElts;
+ }
+ }
+ }
+
V1 = DAG.getVectorShuffle(VT, DL, V1, DAG.getUNDEF(VT), V1Mask);
V2 = DAG.getVectorShuffle(VT, DL, V2, DAG.getUNDEF(VT), V2Mask);
- return DAG.getVectorShuffle(VT, DL, V1, V2, FinalMask);
+ return DAG.getVectorShuffle(VT, DL, V1, V2, FinalMask);
}
/// Try to lower a vector shuffle as a bit rotation.
@@ -13047,8 +13047,8 @@ static SDValue lowerShuffleAsSpecificZeroOrAnyExtend(
MVT ExtVT = MVT::getVectorVT(MVT::getIntegerVT(EltBits * Scale),
NumElements / Scale);
InputV = ShuffleOffset(InputV);
- InputV = getEXTEND_VECTOR_INREG(AnyExt ? ISD::ANY_EXTEND : ISD::ZERO_EXTEND,
- DL, ExtVT, InputV, DAG);
+ InputV = getEXTEND_VECTOR_INREG(AnyExt ? ISD::ANY_EXTEND : ISD::ZERO_EXTEND,
+ DL, ExtVT, InputV, DAG);
return DAG.getBitcast(VT, InputV);
}
@@ -13656,8 +13656,8 @@ static SDValue lowerShuffleAsBroadcast(const SDLoc &DL, MVT VT, SDValue V1,
MVT SVT = VT.getScalarType();
unsigned Offset = BroadcastIdx * SVT.getStoreSize();
assert((int)(Offset * 8) == BitOffset && "Unexpected bit-offset");
- SDValue NewAddr =
- DAG.getMemBasePlusOffset(BaseAddr, TypeSize::Fixed(Offset), DL);
+ SDValue NewAddr =
+ DAG.getMemBasePlusOffset(BaseAddr, TypeSize::Fixed(Offset), DL);
// Directly form VBROADCAST_LOAD if we're using VBROADCAST opcode rather
// than MOVDDUP.
@@ -13830,7 +13830,7 @@ static SDValue lowerShuffleAsInsertPS(const SDLoc &DL, SDValue V1, SDValue V2,
assert(V2.getSimpleValueType() == MVT::v4f32 && "Bad operand type!");
// Attempt to match the insertps pattern.
- unsigned InsertPSMask = 0;
+ unsigned InsertPSMask = 0;
if (!matchShuffleAsInsertPS(V1, V2, InsertPSMask, Zeroable, Mask, DAG))
return SDValue();
@@ -14018,8 +14018,8 @@ static SDValue lowerV2F64Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
// Try to use one of the special instruction patterns to handle two common
// blend patterns if a zero-blend above didn't work.
- if (isShuffleEquivalent(Mask, {0, 3}, V1, V2) ||
- isShuffleEquivalent(Mask, {1, 3}, V1, V2))
+ if (isShuffleEquivalent(Mask, {0, 3}, V1, V2) ||
+ isShuffleEquivalent(Mask, {1, 3}, V1, V2))
if (SDValue V1S = getScalarValueForVectorElement(V1, Mask[0], DAG))
// We can either use a special instruction to load over the low double or
// to move just the low double.
@@ -14065,10 +14065,10 @@ static SDValue lowerV2I64Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
// onward this has a single fast instruction with no scary immediates.
// We have to map the mask as it is actually a v4i32 shuffle instruction.
V1 = DAG.getBitcast(MVT::v4i32, V1);
- int WidenedMask[4] = {Mask[0] < 0 ? -1 : (Mask[0] * 2),
- Mask[0] < 0 ? -1 : ((Mask[0] * 2) + 1),
- Mask[1] < 0 ? -1 : (Mask[1] * 2),
- Mask[1] < 0 ? -1 : ((Mask[1] * 2) + 1)};
+ int WidenedMask[4] = {Mask[0] < 0 ? -1 : (Mask[0] * 2),
+ Mask[0] < 0 ? -1 : ((Mask[0] * 2) + 1),
+ Mask[1] < 0 ? -1 : (Mask[1] * 2),
+ Mask[1] < 0 ? -1 : ((Mask[1] * 2) + 1)};
return DAG.getBitcast(
MVT::v2i64,
DAG.getNode(X86ISD::PSHUFD, DL, MVT::v4i32, V1,
@@ -14128,7 +14128,7 @@ static SDValue lowerV2I64Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
// If we have direct support for blends, we should lower by decomposing into
// a permute. That will be faster than the domain cross.
if (IsBlendSupported)
- return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v2i64, V1, V2, Mask,
+ return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v2i64, V1, V2, Mask,
Subtarget, DAG);
// We implement this with SHUFPD which is pretty lame because it will likely
@@ -14222,12 +14222,12 @@ static SDValue lowerShuffleWithSHUFPS(const SDLoc &DL, MVT VT,
NewMask[2] = Mask[2] < 4 ? 1 : 3;
NewMask[3] = Mask[2] < 4 ? 3 : 1;
}
- } else if (NumV2Elements == 3) {
- // Ideally canonicalizeShuffleMaskWithCommute should have caught this, but
- // we can get here due to other paths (e.g repeated mask matching) that we
- // don't want to do another round of lowerVECTOR_SHUFFLE.
- ShuffleVectorSDNode::commuteMask(NewMask);
- return lowerShuffleWithSHUFPS(DL, VT, NewMask, V2, V1, DAG);
+ } else if (NumV2Elements == 3) {
+ // Ideally canonicalizeShuffleMaskWithCommute should have caught this, but
+ // we can get here due to other paths (e.g repeated mask matching) that we
+ // don't want to do another round of lowerVECTOR_SHUFFLE.
+ ShuffleVectorSDNode::commuteMask(NewMask);
+ return lowerShuffleWithSHUFPS(DL, VT, NewMask, V2, V1, DAG);
}
return DAG.getNode(X86ISD::SHUFP, DL, VT, LowV, HighV,
getV4X86ShuffleImm8ForMask(NewMask, DL, DAG));
@@ -14256,9 +14256,9 @@ static SDValue lowerV4F32Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
// Use even/odd duplicate instructions for masks that match their pattern.
if (Subtarget.hasSSE3()) {
- if (isShuffleEquivalent(Mask, {0, 0, 2, 2}, V1, V2))
+ if (isShuffleEquivalent(Mask, {0, 0, 2, 2}, V1, V2))
return DAG.getNode(X86ISD::MOVSLDUP, DL, MVT::v4f32, V1);
- if (isShuffleEquivalent(Mask, {1, 1, 3, 3}, V1, V2))
+ if (isShuffleEquivalent(Mask, {1, 1, 3, 3}, V1, V2))
return DAG.getNode(X86ISD::MOVSHDUP, DL, MVT::v4f32, V1);
}
@@ -14272,9 +14272,9 @@ static SDValue lowerV4F32Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
// Use MOVLHPS/MOVHLPS to simulate unary shuffles. These are only valid
// in SSE1 because otherwise they are widened to v2f64 and never get here.
if (!Subtarget.hasSSE2()) {
- if (isShuffleEquivalent(Mask, {0, 1, 0, 1}, V1, V2))
+ if (isShuffleEquivalent(Mask, {0, 1, 0, 1}, V1, V2))
return DAG.getNode(X86ISD::MOVLHPS, DL, MVT::v4f32, V1, V1);
- if (isShuffleEquivalent(Mask, {2, 3, 2, 3}, V1, V2))
+ if (isShuffleEquivalent(Mask, {2, 3, 2, 3}, V1, V2))
return DAG.getNode(X86ISD::MOVHLPS, DL, MVT::v4f32, V1, V1);
}
@@ -14316,9 +14316,9 @@ static SDValue lowerV4F32Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
// Use low/high mov instructions. These are only valid in SSE1 because
// otherwise they are widened to v2f64 and never get here.
if (!Subtarget.hasSSE2()) {
- if (isShuffleEquivalent(Mask, {0, 1, 4, 5}, V1, V2))
+ if (isShuffleEquivalent(Mask, {0, 1, 4, 5}, V1, V2))
return DAG.getNode(X86ISD::MOVLHPS, DL, MVT::v4f32, V1, V2);
- if (isShuffleEquivalent(Mask, {2, 3, 6, 7}, V1, V2))
+ if (isShuffleEquivalent(Mask, {2, 3, 6, 7}, V1, V2))
return DAG.getNode(X86ISD::MOVHLPS, DL, MVT::v4f32, V2, V1);
}
@@ -14366,9 +14366,9 @@ static SDValue lowerV4I32Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
// so prevents folding a load into this instruction or making a copy.
const int UnpackLoMask[] = {0, 0, 1, 1};
const int UnpackHiMask[] = {2, 2, 3, 3};
- if (isShuffleEquivalent(Mask, {0, 0, 1, 1}, V1, V2))
+ if (isShuffleEquivalent(Mask, {0, 0, 1, 1}, V1, V2))
Mask = UnpackLoMask;
- else if (isShuffleEquivalent(Mask, {2, 2, 3, 3}, V1, V2))
+ else if (isShuffleEquivalent(Mask, {2, 2, 3, 3}, V1, V2))
Mask = UnpackHiMask;
return DAG.getNode(X86ISD::PSHUFD, DL, MVT::v4i32, V1,
@@ -14426,7 +14426,7 @@ static SDValue lowerV4I32Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
// If we have direct support for blends, we should lower by decomposing into
// a permute. That will be faster than the domain cross.
if (IsBlendSupported)
- return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v4i32, V1, V2, Mask,
+ return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v4i32, V1, V2, Mask,
Subtarget, DAG);
// Try to lower by permuting the inputs into an unpack instruction.
@@ -15035,11 +15035,11 @@ static SDValue lowerV8I16Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
Zeroable, Subtarget, DAG))
return ZExt;
- // Try to use lower using a truncation.
- if (SDValue V = lowerShuffleWithVPMOV(DL, MVT::v8i16, V1, V2, Mask, Zeroable,
- Subtarget, DAG))
- return V;
-
+ // Try to use lower using a truncation.
+ if (SDValue V = lowerShuffleWithVPMOV(DL, MVT::v8i16, V1, V2, Mask, Zeroable,
+ Subtarget, DAG))
+ return V;
+
int NumV2Inputs = count_if(Mask, [](int M) { return M >= 8; });
if (NumV2Inputs == 0) {
@@ -15120,11 +15120,11 @@ static SDValue lowerV8I16Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
Subtarget))
return V;
- // Try to use lower using a truncation.
- if (SDValue V = lowerShuffleAsVTRUNC(DL, MVT::v8i16, V1, V2, Mask, Zeroable,
- Subtarget, DAG))
- return V;
-
+ // Try to use lower using a truncation.
+ if (SDValue V = lowerShuffleAsVTRUNC(DL, MVT::v8i16, V1, V2, Mask, Zeroable,
+ Subtarget, DAG))
+ return V;
+
// Try to use byte rotation instructions.
if (SDValue Rotate = lowerShuffleAsByteRotate(DL, MVT::v8i16, V1, V2, Mask,
Subtarget, DAG))
@@ -15176,49 +15176,49 @@ static SDValue lowerV8I16Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
}
// We can always bit-blend if we have to so the fallback strategy is to
- // decompose into single-input permutes and blends/unpacks.
- return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v8i16, V1, V2,
+ // decompose into single-input permutes and blends/unpacks.
+ return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v8i16, V1, V2,
Mask, Subtarget, DAG);
}
-// Lowers unary/binary shuffle as VPERMV/VPERMV3, for non-VLX targets,
-// sub-512-bit shuffles are padded to 512-bits for the shuffle and then
-// the active subvector is extracted.
+// Lowers unary/binary shuffle as VPERMV/VPERMV3, for non-VLX targets,
+// sub-512-bit shuffles are padded to 512-bits for the shuffle and then
+// the active subvector is extracted.
static SDValue lowerShuffleWithPERMV(const SDLoc &DL, MVT VT,
- ArrayRef<int> Mask, SDValue V1, SDValue V2,
- const X86Subtarget &Subtarget,
- SelectionDAG &DAG) {
- MVT MaskVT = VT.changeTypeToInteger();
- SDValue MaskNode;
- MVT ShuffleVT = VT;
- if (!VT.is512BitVector() && !Subtarget.hasVLX()) {
- V1 = widenSubVector(V1, false, Subtarget, DAG, DL, 512);
- V2 = widenSubVector(V2, false, Subtarget, DAG, DL, 512);
- ShuffleVT = V1.getSimpleValueType();
-
- // Adjust mask to correct indices for the second input.
- int NumElts = VT.getVectorNumElements();
- unsigned Scale = 512 / VT.getSizeInBits();
- SmallVector<int, 32> AdjustedMask(Mask.begin(), Mask.end());
- for (int &M : AdjustedMask)
- if (NumElts <= M)
- M += (Scale - 1) * NumElts;
- MaskNode = getConstVector(AdjustedMask, MaskVT, DAG, DL, true);
- MaskNode = widenSubVector(MaskNode, false, Subtarget, DAG, DL, 512);
- } else {
- MaskNode = getConstVector(Mask, MaskVT, DAG, DL, true);
- }
-
- SDValue Result;
+ ArrayRef<int> Mask, SDValue V1, SDValue V2,
+ const X86Subtarget &Subtarget,
+ SelectionDAG &DAG) {
+ MVT MaskVT = VT.changeTypeToInteger();
+ SDValue MaskNode;
+ MVT ShuffleVT = VT;
+ if (!VT.is512BitVector() && !Subtarget.hasVLX()) {
+ V1 = widenSubVector(V1, false, Subtarget, DAG, DL, 512);
+ V2 = widenSubVector(V2, false, Subtarget, DAG, DL, 512);
+ ShuffleVT = V1.getSimpleValueType();
+
+ // Adjust mask to correct indices for the second input.
+ int NumElts = VT.getVectorNumElements();
+ unsigned Scale = 512 / VT.getSizeInBits();
+ SmallVector<int, 32> AdjustedMask(Mask.begin(), Mask.end());
+ for (int &M : AdjustedMask)
+ if (NumElts <= M)
+ M += (Scale - 1) * NumElts;
+ MaskNode = getConstVector(AdjustedMask, MaskVT, DAG, DL, true);
+ MaskNode = widenSubVector(MaskNode, false, Subtarget, DAG, DL, 512);
+ } else {
+ MaskNode = getConstVector(Mask, MaskVT, DAG, DL, true);
+ }
+
+ SDValue Result;
if (V2.isUndef())
- Result = DAG.getNode(X86ISD::VPERMV, DL, ShuffleVT, MaskNode, V1);
- else
- Result = DAG.getNode(X86ISD::VPERMV3, DL, ShuffleVT, V1, MaskNode, V2);
+ Result = DAG.getNode(X86ISD::VPERMV, DL, ShuffleVT, MaskNode, V1);
+ else
+ Result = DAG.getNode(X86ISD::VPERMV3, DL, ShuffleVT, V1, MaskNode, V2);
- if (VT != ShuffleVT)
- Result = extractSubVector(Result, 0, DAG, DL, VT.getSizeInBits());
-
- return Result;
+ if (VT != ShuffleVT)
+ Result = extractSubVector(Result, 0, DAG, DL, VT.getSizeInBits());
+
+ return Result;
}
/// Generic lowering of v16i8 shuffles.
@@ -15256,15 +15256,15 @@ static SDValue lowerV16I8Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
Zeroable, Subtarget, DAG))
return ZExt;
- // Try to use lower using a truncation.
- if (SDValue V = lowerShuffleWithVPMOV(DL, MVT::v16i8, V1, V2, Mask, Zeroable,
- Subtarget, DAG))
- return V;
-
- if (SDValue V = lowerShuffleAsVTRUNC(DL, MVT::v16i8, V1, V2, Mask, Zeroable,
- Subtarget, DAG))
- return V;
-
+ // Try to use lower using a truncation.
+ if (SDValue V = lowerShuffleWithVPMOV(DL, MVT::v16i8, V1, V2, Mask, Zeroable,
+ Subtarget, DAG))
+ return V;
+
+ if (SDValue V = lowerShuffleAsVTRUNC(DL, MVT::v16i8, V1, V2, Mask, Zeroable,
+ Subtarget, DAG))
+ return V;
+
// See if we can use SSE4A Extraction / Insertion.
if (Subtarget.hasSSE4A())
if (SDValue V = lowerShuffleWithSSE4A(DL, MVT::v16i8, V1, V2, Mask,
@@ -15447,17 +15447,17 @@ static SDValue lowerV16I8Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
DL, MVT::v16i8, V1, V2, Mask, Subtarget, DAG))
return Unpack;
- // AVX512VBMI can lower to VPERMB (non-VLX will pad to v64i8).
- if (Subtarget.hasVBMI())
- return lowerShuffleWithPERMV(DL, MVT::v16i8, Mask, V1, V2, Subtarget,
- DAG);
-
- // If we have XOP we can use one VPPERM instead of multiple PSHUFBs.
- if (Subtarget.hasXOP()) {
- SDValue MaskNode = getConstVector(Mask, MVT::v16i8, DAG, DL, true);
- return DAG.getNode(X86ISD::VPPERM, DL, MVT::v16i8, V1, V2, MaskNode);
- }
-
+ // AVX512VBMI can lower to VPERMB (non-VLX will pad to v64i8).
+ if (Subtarget.hasVBMI())
+ return lowerShuffleWithPERMV(DL, MVT::v16i8, Mask, V1, V2, Subtarget,
+ DAG);
+
+ // If we have XOP we can use one VPPERM instead of multiple PSHUFBs.
+ if (Subtarget.hasXOP()) {
+ SDValue MaskNode = getConstVector(Mask, MVT::v16i8, DAG, DL, true);
+ return DAG.getNode(X86ISD::VPPERM, DL, MVT::v16i8, V1, V2, MaskNode);
+ }
+
// Use PALIGNR+Permute if possible - permute might become PSHUFB but the
// PALIGNR will be cheaper than the second PSHUFB+OR.
if (SDValue V = lowerShuffleAsByteRotateAndPermute(
@@ -15512,9 +15512,9 @@ static SDValue lowerV16I8Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
return Result;
}
- // Handle multi-input cases by blending/unpacking single-input shuffles.
+ // Handle multi-input cases by blending/unpacking single-input shuffles.
if (NumV2Elements > 0)
- return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v16i8, V1, V2, Mask,
+ return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v16i8, V1, V2, Mask,
Subtarget, DAG);
// The fallback path for single-input shuffles widens this into two v8i16
@@ -15694,7 +15694,7 @@ static SDValue splitAndLowerShuffle(const SDLoc &DL, MVT VT, SDValue V1,
}
/// Either split a vector in halves or decompose the shuffles and the
-/// blend/unpack.
+/// blend/unpack.
///
/// This is provided as a good fallback for many lowerings of non-single-input
/// shuffles with more than one 128-bit lane. In those cases, we want to select
@@ -15729,8 +15729,8 @@ static SDValue lowerShuffleAsSplitOrBlend(const SDLoc &DL, MVT VT, SDValue V1,
return true;
};
if (DoBothBroadcast())
- return lowerShuffleAsDecomposedShuffleMerge(DL, VT, V1, V2, Mask, Subtarget,
- DAG);
+ return lowerShuffleAsDecomposedShuffleMerge(DL, VT, V1, V2, Mask, Subtarget,
+ DAG);
// If the inputs all stem from a single 128-bit lane of each input, then we
// split them rather than blending because the split will decompose to
@@ -15746,9 +15746,9 @@ static SDValue lowerShuffleAsSplitOrBlend(const SDLoc &DL, MVT VT, SDValue V1,
if (LaneInputs[0].count() <= 1 && LaneInputs[1].count() <= 1)
return splitAndLowerShuffle(DL, VT, V1, V2, Mask, DAG);
- // Otherwise, just fall back to decomposed shuffles and a blend/unpack. This
- // requires that the decomposed single-input shuffles don't end up here.
- return lowerShuffleAsDecomposedShuffleMerge(DL, VT, V1, V2, Mask, Subtarget,
+ // Otherwise, just fall back to decomposed shuffles and a blend/unpack. This
+ // requires that the decomposed single-input shuffles don't end up here.
+ return lowerShuffleAsDecomposedShuffleMerge(DL, VT, V1, V2, Mask, Subtarget,
DAG);
}
@@ -15796,94 +15796,94 @@ static SDValue lowerShuffleAsLanePermuteAndPermute(
int NumElts = VT.getVectorNumElements();
int NumLanes = VT.getSizeInBits() / 128;
int NumEltsPerLane = NumElts / NumLanes;
- bool CanUseSublanes = Subtarget.hasAVX2() && V2.isUndef();
-
- /// Attempts to find a sublane permute with the given size
- /// that gets all elements into their target lanes.
- ///
- /// If successful, fills CrossLaneMask and InLaneMask and returns true.
- /// If unsuccessful, returns false and may overwrite InLaneMask.
- auto getSublanePermute = [&](int NumSublanes) -> SDValue {
- int NumSublanesPerLane = NumSublanes / NumLanes;
- int NumEltsPerSublane = NumElts / NumSublanes;
-
- SmallVector<int, 16> CrossLaneMask;
- SmallVector<int, 16> InLaneMask(NumElts, SM_SentinelUndef);
- // CrossLaneMask but one entry == one sublane.
- SmallVector<int, 16> CrossLaneMaskLarge(NumSublanes, SM_SentinelUndef);
-
- for (int i = 0; i != NumElts; ++i) {
- int M = Mask[i];
- if (M < 0)
- continue;
-
- int SrcSublane = M / NumEltsPerSublane;
- int DstLane = i / NumEltsPerLane;
-
- // We only need to get the elements into the right lane, not sublane.
- // So search all sublanes that make up the destination lane.
- bool Found = false;
- int DstSubStart = DstLane * NumSublanesPerLane;
- int DstSubEnd = DstSubStart + NumSublanesPerLane;
- for (int DstSublane = DstSubStart; DstSublane < DstSubEnd; ++DstSublane) {
- if (!isUndefOrEqual(CrossLaneMaskLarge[DstSublane], SrcSublane))
- continue;
-
- Found = true;
- CrossLaneMaskLarge[DstSublane] = SrcSublane;
- int DstSublaneOffset = DstSublane * NumEltsPerSublane;
- InLaneMask[i] = DstSublaneOffset + M % NumEltsPerSublane;
- break;
- }
- if (!Found)
- return SDValue();
- }
-
- // Fill CrossLaneMask using CrossLaneMaskLarge.
- narrowShuffleMaskElts(NumEltsPerSublane, CrossLaneMaskLarge, CrossLaneMask);
-
- if (!CanUseSublanes) {
- // If we're only shuffling a single lowest lane and the rest are identity
- // then don't bother.
- // TODO - isShuffleMaskInputInPlace could be extended to something like
- // this.
- int NumIdentityLanes = 0;
- bool OnlyShuffleLowestLane = true;
- for (int i = 0; i != NumLanes; ++i) {
- int LaneOffset = i * NumEltsPerLane;
- if (isSequentialOrUndefInRange(InLaneMask, LaneOffset, NumEltsPerLane,
- i * NumEltsPerLane))
- NumIdentityLanes++;
- else if (CrossLaneMask[LaneOffset] != 0)
- OnlyShuffleLowestLane = false;
- }
- if (OnlyShuffleLowestLane && NumIdentityLanes == (NumLanes - 1))
- return SDValue();
- }
-
- SDValue CrossLane = DAG.getVectorShuffle(VT, DL, V1, V2, CrossLaneMask);
- return DAG.getVectorShuffle(VT, DL, CrossLane, DAG.getUNDEF(VT),
- InLaneMask);
- };
-
- // First attempt a solution with full lanes.
- if (SDValue V = getSublanePermute(/*NumSublanes=*/NumLanes))
- return V;
-
- // The rest of the solutions use sublanes.
- if (!CanUseSublanes)
- return SDValue();
-
- // Then attempt a solution with 64-bit sublanes (vpermq).
- if (SDValue V = getSublanePermute(/*NumSublanes=*/NumLanes * 2))
- return V;
-
- // If that doesn't work and we have fast variable shuffle,
- // attempt 32-bit sublanes (vpermd).
- if (!Subtarget.hasFastVariableShuffle())
- return SDValue();
-
- return getSublanePermute(/*NumSublanes=*/NumLanes * 4);
+ bool CanUseSublanes = Subtarget.hasAVX2() && V2.isUndef();
+
+ /// Attempts to find a sublane permute with the given size
+ /// that gets all elements into their target lanes.
+ ///
+ /// If successful, fills CrossLaneMask and InLaneMask and returns true.
+ /// If unsuccessful, returns false and may overwrite InLaneMask.
+ auto getSublanePermute = [&](int NumSublanes) -> SDValue {
+ int NumSublanesPerLane = NumSublanes / NumLanes;
+ int NumEltsPerSublane = NumElts / NumSublanes;
+
+ SmallVector<int, 16> CrossLaneMask;
+ SmallVector<int, 16> InLaneMask(NumElts, SM_SentinelUndef);
+ // CrossLaneMask but one entry == one sublane.
+ SmallVector<int, 16> CrossLaneMaskLarge(NumSublanes, SM_SentinelUndef);
+
+ for (int i = 0; i != NumElts; ++i) {
+ int M = Mask[i];
+ if (M < 0)
+ continue;
+
+ int SrcSublane = M / NumEltsPerSublane;
+ int DstLane = i / NumEltsPerLane;
+
+ // We only need to get the elements into the right lane, not sublane.
+ // So search all sublanes that make up the destination lane.
+ bool Found = false;
+ int DstSubStart = DstLane * NumSublanesPerLane;
+ int DstSubEnd = DstSubStart + NumSublanesPerLane;
+ for (int DstSublane = DstSubStart; DstSublane < DstSubEnd; ++DstSublane) {
+ if (!isUndefOrEqual(CrossLaneMaskLarge[DstSublane], SrcSublane))
+ continue;
+
+ Found = true;
+ CrossLaneMaskLarge[DstSublane] = SrcSublane;
+ int DstSublaneOffset = DstSublane * NumEltsPerSublane;
+ InLaneMask[i] = DstSublaneOffset + M % NumEltsPerSublane;
+ break;
+ }
+ if (!Found)
+ return SDValue();
+ }
+
+ // Fill CrossLaneMask using CrossLaneMaskLarge.
+ narrowShuffleMaskElts(NumEltsPerSublane, CrossLaneMaskLarge, CrossLaneMask);
+
+ if (!CanUseSublanes) {
+ // If we're only shuffling a single lowest lane and the rest are identity
+ // then don't bother.
+ // TODO - isShuffleMaskInputInPlace could be extended to something like
+ // this.
+ int NumIdentityLanes = 0;
+ bool OnlyShuffleLowestLane = true;
+ for (int i = 0; i != NumLanes; ++i) {
+ int LaneOffset = i * NumEltsPerLane;
+ if (isSequentialOrUndefInRange(InLaneMask, LaneOffset, NumEltsPerLane,
+ i * NumEltsPerLane))
+ NumIdentityLanes++;
+ else if (CrossLaneMask[LaneOffset] != 0)
+ OnlyShuffleLowestLane = false;
+ }
+ if (OnlyShuffleLowestLane && NumIdentityLanes == (NumLanes - 1))
+ return SDValue();
+ }
+
+ SDValue CrossLane = DAG.getVectorShuffle(VT, DL, V1, V2, CrossLaneMask);
+ return DAG.getVectorShuffle(VT, DL, CrossLane, DAG.getUNDEF(VT),
+ InLaneMask);
+ };
+
+ // First attempt a solution with full lanes.
+ if (SDValue V = getSublanePermute(/*NumSublanes=*/NumLanes))
+ return V;
+
+ // The rest of the solutions use sublanes.
+ if (!CanUseSublanes)
+ return SDValue();
+
+ // Then attempt a solution with 64-bit sublanes (vpermq).
+ if (SDValue V = getSublanePermute(/*NumSublanes=*/NumLanes * 2))
+ return V;
+
+ // If that doesn't work and we have fast variable shuffle,
+ // attempt 32-bit sublanes (vpermd).
+ if (!Subtarget.hasFastVariableShuffle())
+ return SDValue();
+
+ return getSublanePermute(/*NumSublanes=*/NumLanes * 4);
}
/// Lower a vector shuffle crossing multiple 128-bit lanes by shuffling one
@@ -15996,8 +15996,8 @@ static SDValue lowerV2X128Shuffle(const SDLoc &DL, MVT VT, SDValue V1,
if (!IsLowZero && !IsHighZero) {
// Check for patterns which can be matched with a single insert of a 128-bit
// subvector.
- bool OnlyUsesV1 = isShuffleEquivalent(Mask, {0, 1, 0, 1}, V1, V2);
- if (OnlyUsesV1 || isShuffleEquivalent(Mask, {0, 1, 4, 5}, V1, V2)) {
+ bool OnlyUsesV1 = isShuffleEquivalent(Mask, {0, 1, 0, 1}, V1, V2);
+ if (OnlyUsesV1 || isShuffleEquivalent(Mask, {0, 1, 4, 5}, V1, V2)) {
// With AVX1, use vperm2f128 (below) to allow load folding. Otherwise,
// this will likely become vinsertf128 which can't fold a 256-bit memop.
@@ -16739,7 +16739,7 @@ static SDValue lowerV4F64Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
return Broadcast;
// Use low duplicate instructions for masks that match their pattern.
- if (isShuffleEquivalent(Mask, {0, 0, 2, 2}, V1, V2))
+ if (isShuffleEquivalent(Mask, {0, 0, 2, 2}, V1, V2))
return DAG.getNode(X86ISD::MOVDDUP, DL, MVT::v4f64, V1);
if (!is128BitLaneCrossingShuffleMask(MVT::v4f64, Mask)) {
@@ -16800,7 +16800,7 @@ static SDValue lowerV4F64Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
// If we have one input in place, then we can permute the other input and
// blend the result.
if (isShuffleMaskInputInPlace(0, Mask) || isShuffleMaskInputInPlace(1, Mask))
- return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v4f64, V1, V2, Mask,
+ return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v4f64, V1, V2, Mask,
Subtarget, DAG);
// Try to create an in-lane repeating shuffle mask and then shuffle the
@@ -16828,7 +16828,7 @@ static SDValue lowerV4F64Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
// If we have AVX2 then we always want to lower with a blend because an v4 we
// can fully permute the elements.
if (Subtarget.hasAVX2())
- return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v4f64, V1, V2, Mask,
+ return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v4f64, V1, V2, Mask,
Subtarget, DAG);
// Otherwise fall back on generic lowering.
@@ -16910,7 +16910,7 @@ static SDValue lowerV4I64Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
// If we have one input in place, then we can permute the other input and
// blend the result.
if (isShuffleMaskInputInPlace(0, Mask) || isShuffleMaskInputInPlace(1, Mask))
- return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v4i64, V1, V2, Mask,
+ return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v4i64, V1, V2, Mask,
Subtarget, DAG);
// Try to create an in-lane repeating shuffle mask and then shuffle the
@@ -16930,7 +16930,7 @@ static SDValue lowerV4I64Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
return Result;
// Otherwise fall back on generic blend lowering.
- return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v4i64, V1, V2, Mask,
+ return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v4i64, V1, V2, Mask,
Subtarget, DAG);
}
@@ -16963,9 +16963,9 @@ static SDValue lowerV8F32Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
"Repeated masks must be half the mask width!");
// Use even/odd duplicate instructions for masks that match their pattern.
- if (isShuffleEquivalent(RepeatedMask, {0, 0, 2, 2}, V1, V2))
+ if (isShuffleEquivalent(RepeatedMask, {0, 0, 2, 2}, V1, V2))
return DAG.getNode(X86ISD::MOVSLDUP, DL, MVT::v8f32, V1);
- if (isShuffleEquivalent(RepeatedMask, {1, 1, 3, 3}, V1, V2))
+ if (isShuffleEquivalent(RepeatedMask, {1, 1, 3, 3}, V1, V2))
return DAG.getNode(X86ISD::MOVSHDUP, DL, MVT::v8f32, V1);
if (V2.isUndef())
@@ -17019,13 +17019,13 @@ static SDValue lowerV8F32Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
// since after split we get a more efficient code using vpunpcklwd and
// vpunpckhwd instrs than vblend.
if (!Subtarget.hasAVX512() && isUnpackWdShuffleMask(Mask, MVT::v8f32))
- return lowerShuffleAsSplitOrBlend(DL, MVT::v8f32, V1, V2, Mask, Subtarget,
- DAG);
+ return lowerShuffleAsSplitOrBlend(DL, MVT::v8f32, V1, V2, Mask, Subtarget,
+ DAG);
// If we have AVX2 then we always want to lower with a blend because at v8 we
// can fully permute the elements.
if (Subtarget.hasAVX2())
- return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v8f32, V1, V2, Mask,
+ return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v8f32, V1, V2, Mask,
Subtarget, DAG);
// Otherwise fall back on generic lowering.
@@ -17058,8 +17058,8 @@ static SDValue lowerV8I32Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
// vpunpcklwd and vpunpckhwd instrs.
if (isUnpackWdShuffleMask(Mask, MVT::v8i32) && !V2.isUndef() &&
!Subtarget.hasAVX512())
- return lowerShuffleAsSplitOrBlend(DL, MVT::v8i32, V1, V2, Mask, Subtarget,
- DAG);
+ return lowerShuffleAsSplitOrBlend(DL, MVT::v8i32, V1, V2, Mask, Subtarget,
+ DAG);
if (SDValue Blend = lowerShuffleAsBlend(DL, MVT::v8i32, V1, V2, Mask,
Zeroable, Subtarget, DAG))
@@ -17144,7 +17144,7 @@ static SDValue lowerV8I32Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
return Result;
// Otherwise fall back on generic blend lowering.
- return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v8i32, V1, V2, Mask,
+ return lowerShuffleAsDecomposedShuffleMerge(DL, MVT::v8i32, V1, V2, Mask,
Subtarget, DAG);
}
@@ -17186,11 +17186,11 @@ static SDValue lowerV16I16Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
Subtarget))
return V;
- // Try to use lower using a truncation.
- if (SDValue V = lowerShuffleAsVTRUNC(DL, MVT::v16i16, V1, V2, Mask, Zeroable,
- Subtarget, DAG))
- return V;
-
+ // Try to use lower using a truncation.
+ if (SDValue V = lowerShuffleAsVTRUNC(DL, MVT::v16i16, V1, V2, Mask, Zeroable,
+ Subtarget, DAG))
+ return V;
+
// Try to use shift instructions.
if (SDValue Shift = lowerShuffleAsShift(DL, MVT::v16i16, V1, V2, Mask,
Zeroable, Subtarget, DAG))
@@ -17243,9 +17243,9 @@ static SDValue lowerV16I16Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
Zeroable, Subtarget, DAG))
return PSHUFB;
- // AVX512BW can lower to VPERMW (non-VLX will pad to v32i16).
- if (Subtarget.hasBWI())
- return lowerShuffleWithPERMV(DL, MVT::v16i16, Mask, V1, V2, Subtarget, DAG);
+ // AVX512BW can lower to VPERMW (non-VLX will pad to v32i16).
+ if (Subtarget.hasBWI())
+ return lowerShuffleWithPERMV(DL, MVT::v16i16, Mask, V1, V2, Subtarget, DAG);
// Try to simplify this by merging 128-bit lanes to enable a lane-based
// shuffle.
@@ -17301,11 +17301,11 @@ static SDValue lowerV32I8Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
Subtarget))
return V;
- // Try to use lower using a truncation.
- if (SDValue V = lowerShuffleAsVTRUNC(DL, MVT::v32i8, V1, V2, Mask, Zeroable,
- Subtarget, DAG))
- return V;
-
+ // Try to use lower using a truncation.
+ if (SDValue V = lowerShuffleAsVTRUNC(DL, MVT::v32i8, V1, V2, Mask, Zeroable,
+ Subtarget, DAG))
+ return V;
+
// Try to use shift instructions.
if (SDValue Shift = lowerShuffleAsShift(DL, MVT::v32i8, V1, V2, Mask,
Zeroable, Subtarget, DAG))
@@ -17348,9 +17348,9 @@ static SDValue lowerV32I8Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
Zeroable, Subtarget, DAG))
return PSHUFB;
- // AVX512VBMI can lower to VPERMB (non-VLX will pad to v64i8).
- if (Subtarget.hasVBMI())
- return lowerShuffleWithPERMV(DL, MVT::v32i8, Mask, V1, V2, Subtarget, DAG);
+ // AVX512VBMI can lower to VPERMB (non-VLX will pad to v64i8).
+ if (Subtarget.hasVBMI())
+ return lowerShuffleWithPERMV(DL, MVT::v32i8, Mask, V1, V2, Subtarget, DAG);
// Try to simplify this by merging 128-bit lanes to enable a lane-based
// shuffle.
@@ -17477,9 +17477,9 @@ static SDValue lowerV4X128Shuffle(const SDLoc &DL, MVT VT, ArrayRef<int> Mask,
// Check for patterns which can be matched with a single insert of a 256-bit
// subvector.
- bool OnlyUsesV1 = isShuffleEquivalent(Mask, {0, 1, 2, 3, 0, 1, 2, 3}, V1, V2);
+ bool OnlyUsesV1 = isShuffleEquivalent(Mask, {0, 1, 2, 3, 0, 1, 2, 3}, V1, V2);
if (OnlyUsesV1 ||
- isShuffleEquivalent(Mask, {0, 1, 2, 3, 8, 9, 10, 11}, V1, V2)) {
+ isShuffleEquivalent(Mask, {0, 1, 2, 3, 8, 9, 10, 11}, V1, V2)) {
MVT SubVT = MVT::getVectorVT(VT.getVectorElementType(), 4);
SDValue SubVec =
DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SubVT, OnlyUsesV1 ? V1 : V2,
@@ -17564,7 +17564,7 @@ static SDValue lowerV8F64Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
if (V2.isUndef()) {
// Use low duplicate instructions for masks that match their pattern.
- if (isShuffleEquivalent(Mask, {0, 0, 2, 2, 4, 4, 6, 6}, V1, V2))
+ if (isShuffleEquivalent(Mask, {0, 0, 2, 2, 4, 4, 6, 6}, V1, V2))
return DAG.getNode(X86ISD::MOVDDUP, DL, MVT::v8f64, V1);
if (!is128BitLaneCrossingShuffleMask(MVT::v8f64, Mask)) {
@@ -17604,7 +17604,7 @@ static SDValue lowerV8F64Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
Zeroable, Subtarget, DAG))
return Blend;
- return lowerShuffleWithPERMV(DL, MVT::v8f64, Mask, V1, V2, Subtarget, DAG);
+ return lowerShuffleWithPERMV(DL, MVT::v8f64, Mask, V1, V2, Subtarget, DAG);
}
/// Handle lowering of 16-lane 32-bit floating point shuffles.
@@ -17623,9 +17623,9 @@ static SDValue lowerV16F32Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
assert(RepeatedMask.size() == 4 && "Unexpected repeated mask size!");
// Use even/odd duplicate instructions for masks that match their pattern.
- if (isShuffleEquivalent(RepeatedMask, {0, 0, 2, 2}, V1, V2))
+ if (isShuffleEquivalent(RepeatedMask, {0, 0, 2, 2}, V1, V2))
return DAG.getNode(X86ISD::MOVSLDUP, DL, MVT::v16f32, V1);
- if (isShuffleEquivalent(RepeatedMask, {1, 1, 3, 3}, V1, V2))
+ if (isShuffleEquivalent(RepeatedMask, {1, 1, 3, 3}, V1, V2))
return DAG.getNode(X86ISD::MOVSHDUP, DL, MVT::v16f32, V1);
if (V2.isUndef())
@@ -17663,7 +17663,7 @@ static SDValue lowerV16F32Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
V1, V2, DAG, Subtarget))
return V;
- return lowerShuffleWithPERMV(DL, MVT::v16f32, Mask, V1, V2, Subtarget, DAG);
+ return lowerShuffleWithPERMV(DL, MVT::v16f32, Mask, V1, V2, Subtarget, DAG);
}
/// Handle lowering of 8-lane 64-bit integer shuffles.
@@ -17711,14 +17711,14 @@ static SDValue lowerV8I64Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
return Rotate;
// Try to use PALIGNR.
- if (Subtarget.hasBWI())
- if (SDValue Rotate = lowerShuffleAsByteRotate(DL, MVT::v8i64, V1, V2, Mask,
- Subtarget, DAG))
- return Rotate;
+ if (Subtarget.hasBWI())
+ if (SDValue Rotate = lowerShuffleAsByteRotate(DL, MVT::v8i64, V1, V2, Mask,
+ Subtarget, DAG))
+ return Rotate;
if (SDValue Unpck = lowerShuffleWithUNPCK(DL, MVT::v8i64, Mask, V1, V2, DAG))
return Unpck;
-
+
// If we have AVX512F support, we can use VEXPAND.
if (SDValue V = lowerShuffleToEXPAND(DL, MVT::v8i64, Zeroable, Mask, V1, V2,
DAG, Subtarget))
@@ -17728,7 +17728,7 @@ static SDValue lowerV8I64Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
Zeroable, Subtarget, DAG))
return Blend;
- return lowerShuffleWithPERMV(DL, MVT::v8i64, Mask, V1, V2, Subtarget, DAG);
+ return lowerShuffleWithPERMV(DL, MVT::v8i64, Mask, V1, V2, Subtarget, DAG);
}
/// Handle lowering of 16-lane 32-bit integer shuffles.
@@ -17805,7 +17805,7 @@ static SDValue lowerV16I32Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
Zeroable, Subtarget, DAG))
return Blend;
- return lowerShuffleWithPERMV(DL, MVT::v16i32, Mask, V1, V2, Subtarget, DAG);
+ return lowerShuffleWithPERMV(DL, MVT::v16i32, Mask, V1, V2, Subtarget, DAG);
}
/// Handle lowering of 32-lane 16-bit integer shuffles.
@@ -17868,7 +17868,7 @@ static SDValue lowerV32I16Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
Zeroable, Subtarget, DAG))
return PSHUFB;
- return lowerShuffleWithPERMV(DL, MVT::v32i16, Mask, V1, V2, Subtarget, DAG);
+ return lowerShuffleWithPERMV(DL, MVT::v32i16, Mask, V1, V2, Subtarget, DAG);
}
/// Handle lowering of 64-lane 8-bit integer shuffles.
@@ -17924,7 +17924,7 @@ static SDValue lowerV64I8Shuffle(const SDLoc &DL, ArrayRef<int> Mask,
// VBMI can use VPERMV/VPERMV3 byte shuffles.
if (Subtarget.hasVBMI())
- return lowerShuffleWithPERMV(DL, MVT::v64i8, Mask, V1, V2, Subtarget, DAG);
+ return lowerShuffleWithPERMV(DL, MVT::v64i8, Mask, V1, V2, Subtarget, DAG);
// Try to create an in-lane repeating shuffle mask and then shuffle the
// results into the target lanes.
@@ -18378,7 +18378,7 @@ static SDValue lowerVECTOR_SHUFFLE(SDValue Op, const X86Subtarget &Subtarget,
// Modify the new Mask to take all zeros from the all-zero vector.
// Choose indices that are blend-friendly.
bool UsedZeroVector = false;
- assert(is_contained(WidenedMask, SM_SentinelZero) &&
+ assert(is_contained(WidenedMask, SM_SentinelZero) &&
"V2's non-undef elements are used?!");
for (int i = 0; i != NewNumElts; ++i)
if (WidenedMask[i] == SM_SentinelZero) {
@@ -18431,11 +18431,11 @@ static SDValue lowerVSELECTtoVectorShuffle(SDValue Op,
// Only non-legal VSELECTs reach this lowering, convert those into generic
// shuffles and re-use the shuffle lowering path for blends.
- if (ISD::isBuildVectorOfConstantSDNodes(Cond.getNode())) {
- SmallVector<int, 32> Mask;
- if (createShuffleMaskFromVSELECT(Mask, Cond))
- return DAG.getVectorShuffle(VT, SDLoc(Op), LHS, RHS, Mask);
- }
+ if (ISD::isBuildVectorOfConstantSDNodes(Cond.getNode())) {
+ SmallVector<int, 32> Mask;
+ if (createShuffleMaskFromVSELECT(Mask, Cond))
+ return DAG.getVectorShuffle(VT, SDLoc(Op), LHS, RHS, Mask);
+ }
return SDValue();
}
@@ -18549,9 +18549,9 @@ static SDValue LowerEXTRACT_VECTOR_ELT_SSE4(SDValue Op, SelectionDAG &DAG) {
DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32,
DAG.getBitcast(MVT::v4i32, Vec), Idx));
- unsigned IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
- SDValue Extract = DAG.getNode(X86ISD::PEXTRB, dl, MVT::i32, Vec,
- DAG.getTargetConstant(IdxVal, dl, MVT::i8));
+ unsigned IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
+ SDValue Extract = DAG.getNode(X86ISD::PEXTRB, dl, MVT::i32, Vec,
+ DAG.getTargetConstant(IdxVal, dl, MVT::i8));
return DAG.getNode(ISD::TRUNCATE, dl, VT, Extract);
}
@@ -18706,8 +18706,8 @@ X86TargetLowering::LowerEXTRACT_VECTOR_ELT(SDValue Op,
DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32,
DAG.getBitcast(MVT::v4i32, Vec), Idx));
- SDValue Extract = DAG.getNode(X86ISD::PEXTRW, dl, MVT::i32, Vec,
- DAG.getTargetConstant(IdxVal, dl, MVT::i8));
+ SDValue Extract = DAG.getNode(X86ISD::PEXTRW, dl, MVT::i32, Vec,
+ DAG.getTargetConstant(IdxVal, dl, MVT::i8));
return DAG.getNode(ISD::TRUNCATE, dl, VT, Extract);
}
@@ -18901,9 +18901,9 @@ SDValue X86TargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op,
Opc = X86ISD::PINSRB;
}
- assert(N1.getValueType() != MVT::i32 && "Unexpected VT");
- N1 = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, N1);
- N2 = DAG.getTargetConstant(IdxVal, dl, MVT::i8);
+ assert(N1.getValueType() != MVT::i32 && "Unexpected VT");
+ N1 = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, N1);
+ N2 = DAG.getTargetConstant(IdxVal, dl, MVT::i8);
return DAG.getNode(Opc, dl, VT, N0, N1, N2);
}
@@ -19151,12 +19151,12 @@ SDValue X86TargetLowering::LowerGlobalOrExternal(SDValue Op, SelectionDAG &DAG,
if (GV) {
// Create a target global address if this is a global. If possible, fold the
// offset into the global address reference. Otherwise, ADD it on later.
- // Suppress the folding if Offset is negative: movl foo-1, %eax is not
- // allowed because if the address of foo is 0, the ELF R_X86_64_32
- // relocation will compute to a negative value, which is invalid.
+ // Suppress the folding if Offset is negative: movl foo-1, %eax is not
+ // allowed because if the address of foo is 0, the ELF R_X86_64_32
+ // relocation will compute to a negative value, which is invalid.
int64_t GlobalOffset = 0;
- if (OpFlags == X86II::MO_NO_FLAG && Offset >= 0 &&
- X86::isOffsetSuitableForCodeModel(Offset, M, true)) {
+ if (OpFlags == X86II::MO_NO_FLAG && Offset >= 0 &&
+ X86::isOffsetSuitableForCodeModel(Offset, M, true)) {
std::swap(GlobalOffset, Offset);
}
Result = DAG.getTargetGlobalAddress(GV, dl, PtrVT, GlobalOffset, OpFlags);
@@ -19243,7 +19243,7 @@ LowerToTLSGeneralDynamicModel32(GlobalAddressSDNode *GA, SelectionDAG &DAG,
return GetTLSADDR(DAG, Chain, GA, &InFlag, PtrVT, X86::EAX, X86II::MO_TLSGD);
}
-// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 64 bit LP64
+// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 64 bit LP64
static SDValue
LowerToTLSGeneralDynamicModel64(GlobalAddressSDNode *GA, SelectionDAG &DAG,
const EVT PtrVT) {
@@ -19251,17 +19251,17 @@ LowerToTLSGeneralDynamicModel64(GlobalAddressSDNode *GA, SelectionDAG &DAG,
X86::RAX, X86II::MO_TLSGD);
}
-// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 64 bit ILP32
-static SDValue
-LowerToTLSGeneralDynamicModelX32(GlobalAddressSDNode *GA, SelectionDAG &DAG,
- const EVT PtrVT) {
- return GetTLSADDR(DAG, DAG.getEntryNode(), GA, nullptr, PtrVT,
- X86::EAX, X86II::MO_TLSGD);
-}
-
+// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 64 bit ILP32
+static SDValue
+LowerToTLSGeneralDynamicModelX32(GlobalAddressSDNode *GA, SelectionDAG &DAG,
+ const EVT PtrVT) {
+ return GetTLSADDR(DAG, DAG.getEntryNode(), GA, nullptr, PtrVT,
+ X86::EAX, X86II::MO_TLSGD);
+}
+
static SDValue LowerToTLSLocalDynamicModel(GlobalAddressSDNode *GA,
- SelectionDAG &DAG, const EVT PtrVT,
- bool Is64Bit, bool Is64BitLP64) {
+ SelectionDAG &DAG, const EVT PtrVT,
+ bool Is64Bit, bool Is64BitLP64) {
SDLoc dl(GA);
// Get the start address of the TLS block for this module.
@@ -19270,9 +19270,9 @@ static SDValue LowerToTLSLocalDynamicModel(GlobalAddressSDNode *GA,
MFI->incNumLocalDynamicTLSAccesses();
SDValue Base;
- if (Is64Bit) {
- unsigned ReturnReg = Is64BitLP64 ? X86::RAX : X86::EAX;
- Base = GetTLSADDR(DAG, DAG.getEntryNode(), GA, nullptr, PtrVT, ReturnReg,
+ if (Is64Bit) {
+ unsigned ReturnReg = Is64BitLP64 ? X86::RAX : X86::EAX;
+ Base = GetTLSADDR(DAG, DAG.getEntryNode(), GA, nullptr, PtrVT, ReturnReg,
X86II::MO_TLSLD, /*LocalDynamic=*/true);
} else {
SDValue InFlag;
@@ -19369,15 +19369,15 @@ X86TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
TLSModel::Model model = DAG.getTarget().getTLSModel(GV);
switch (model) {
case TLSModel::GeneralDynamic:
- if (Subtarget.is64Bit()) {
- if (Subtarget.isTarget64BitLP64())
- return LowerToTLSGeneralDynamicModel64(GA, DAG, PtrVT);
- return LowerToTLSGeneralDynamicModelX32(GA, DAG, PtrVT);
- }
+ if (Subtarget.is64Bit()) {
+ if (Subtarget.isTarget64BitLP64())
+ return LowerToTLSGeneralDynamicModel64(GA, DAG, PtrVT);
+ return LowerToTLSGeneralDynamicModelX32(GA, DAG, PtrVT);
+ }
return LowerToTLSGeneralDynamicModel32(GA, DAG, PtrVT);
case TLSModel::LocalDynamic:
- return LowerToTLSLocalDynamicModel(GA, DAG, PtrVT, Subtarget.is64Bit(),
- Subtarget.isTarget64BitLP64());
+ return LowerToTLSLocalDynamicModel(GA, DAG, PtrVT, Subtarget.is64Bit(),
+ Subtarget.isTarget64BitLP64());
case TLSModel::InitialExec:
case TLSModel::LocalExec:
return LowerToTLSExecModel(GA, DAG, PtrVT, model, Subtarget.is64Bit(),
@@ -19477,7 +19477,7 @@ X86TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
else
IDX = DAG.getLoad(PtrVT, dl, Chain, IDX, MachinePointerInfo());
- const DataLayout &DL = DAG.getDataLayout();
+ const DataLayout &DL = DAG.getDataLayout();
SDValue Scale =
DAG.getConstant(Log2_64_Ceil(DL.getPointerSize()), dl, MVT::i8);
IDX = DAG.getNode(ISD::SHL, dl, PtrVT, IDX, Scale);
@@ -19570,29 +19570,29 @@ static SDValue LowerFunnelShift(SDValue Op, const X86Subtarget &Subtarget,
if (IsFSHR)
std::swap(Op0, Op1);
- // With AVX512, but not VLX we need to widen to get a 512-bit result type.
- if (!Subtarget.hasVLX() && !VT.is512BitVector()) {
- Op0 = widenSubVector(Op0, false, Subtarget, DAG, DL, 512);
- Op1 = widenSubVector(Op1, false, Subtarget, DAG, DL, 512);
- }
-
- SDValue Funnel;
+ // With AVX512, but not VLX we need to widen to get a 512-bit result type.
+ if (!Subtarget.hasVLX() && !VT.is512BitVector()) {
+ Op0 = widenSubVector(Op0, false, Subtarget, DAG, DL, 512);
+ Op1 = widenSubVector(Op1, false, Subtarget, DAG, DL, 512);
+ }
+
+ SDValue Funnel;
APInt APIntShiftAmt;
- MVT ResultVT = Op0.getSimpleValueType();
+ MVT ResultVT = Op0.getSimpleValueType();
if (X86::isConstantSplat(Amt, APIntShiftAmt)) {
uint64_t ShiftAmt = APIntShiftAmt.urem(VT.getScalarSizeInBits());
- Funnel =
- DAG.getNode(IsFSHR ? X86ISD::VSHRD : X86ISD::VSHLD, DL, ResultVT, Op0,
- Op1, DAG.getTargetConstant(ShiftAmt, DL, MVT::i8));
- } else {
- if (!Subtarget.hasVLX() && !VT.is512BitVector())
- Amt = widenSubVector(Amt, false, Subtarget, DAG, DL, 512);
- Funnel = DAG.getNode(IsFSHR ? X86ISD::VSHRDV : X86ISD::VSHLDV, DL,
- ResultVT, Op0, Op1, Amt);
- }
- if (!Subtarget.hasVLX() && !VT.is512BitVector())
- Funnel = extractSubVector(Funnel, 0, DAG, DL, VT.getSizeInBits());
- return Funnel;
+ Funnel =
+ DAG.getNode(IsFSHR ? X86ISD::VSHRD : X86ISD::VSHLD, DL, ResultVT, Op0,
+ Op1, DAG.getTargetConstant(ShiftAmt, DL, MVT::i8));
+ } else {
+ if (!Subtarget.hasVLX() && !VT.is512BitVector())
+ Amt = widenSubVector(Amt, false, Subtarget, DAG, DL, 512);
+ Funnel = DAG.getNode(IsFSHR ? X86ISD::VSHRDV : X86ISD::VSHLDV, DL,
+ ResultVT, Op0, Op1, Amt);
+ }
+ if (!Subtarget.hasVLX() && !VT.is512BitVector())
+ Funnel = extractSubVector(Funnel, 0, DAG, DL, VT.getSizeInBits());
+ return Funnel;
}
assert(
(VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64) &&
@@ -19944,7 +19944,7 @@ SDValue X86TargetLowering::LowerSINT_TO_FP(SDValue Op,
}
if (VT == MVT::f128)
- return SDValue();
+ return SDValue();
SDValue ValueToStore = Src;
if (SrcVT == MVT::i64 && Subtarget.hasSSE2() && !Subtarget.is64Bit())
@@ -20025,10 +20025,10 @@ static bool shouldUseHorizontalOp(bool IsSingleSource, SelectionDAG &DAG,
/// 64-bit unsigned integer to double expansion.
static SDValue LowerUINT_TO_FP_i64(SDValue Op, SelectionDAG &DAG,
const X86Subtarget &Subtarget) {
- // We can't use this algorithm for strict fp. It produces -0.0 instead of +0.0
- // when converting 0 when rounding toward negative infinity. Caller will
- // fall back to Expand for when i64 or is legal or use FILD in 32-bit mode.
- assert(!Op->isStrictFPOpcode() && "Expected non-strict uint_to_fp!");
+ // We can't use this algorithm for strict fp. It produces -0.0 instead of +0.0
+ // when converting 0 when rounding toward negative infinity. Caller will
+ // fall back to Expand for when i64 or is legal or use FILD in 32-bit mode.
+ assert(!Op->isStrictFPOpcode() && "Expected non-strict uint_to_fp!");
// This algorithm is not obvious. Here it is what we're trying to output:
/*
movq %rax, %xmm0
@@ -20063,27 +20063,27 @@ static SDValue LowerUINT_TO_FP_i64(SDValue Op, SelectionDAG &DAG,
// Load the 64-bit value into an XMM register.
SDValue XR1 =
- DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2i64, Op.getOperand(0));
- SDValue CLod0 = DAG.getLoad(
- MVT::v4i32, dl, DAG.getEntryNode(), CPIdx0,
- MachinePointerInfo::getConstantPool(DAG.getMachineFunction()), Align(16));
+ DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2i64, Op.getOperand(0));
+ SDValue CLod0 = DAG.getLoad(
+ MVT::v4i32, dl, DAG.getEntryNode(), CPIdx0,
+ MachinePointerInfo::getConstantPool(DAG.getMachineFunction()), Align(16));
SDValue Unpck1 =
getUnpackl(DAG, dl, MVT::v4i32, DAG.getBitcast(MVT::v4i32, XR1), CLod0);
- SDValue CLod1 = DAG.getLoad(
- MVT::v2f64, dl, CLod0.getValue(1), CPIdx1,
- MachinePointerInfo::getConstantPool(DAG.getMachineFunction()), Align(16));
+ SDValue CLod1 = DAG.getLoad(
+ MVT::v2f64, dl, CLod0.getValue(1), CPIdx1,
+ MachinePointerInfo::getConstantPool(DAG.getMachineFunction()), Align(16));
SDValue XR2F = DAG.getBitcast(MVT::v2f64, Unpck1);
// TODO: Are there any fast-math-flags to propagate here?
- SDValue Sub = DAG.getNode(ISD::FSUB, dl, MVT::v2f64, XR2F, CLod1);
+ SDValue Sub = DAG.getNode(ISD::FSUB, dl, MVT::v2f64, XR2F, CLod1);
SDValue Result;
- if (Subtarget.hasSSE3() &&
+ if (Subtarget.hasSSE3() &&
shouldUseHorizontalOp(true, DAG, Subtarget)) {
Result = DAG.getNode(X86ISD::FHADD, dl, MVT::v2f64, Sub, Sub);
} else {
SDValue Shuffle = DAG.getVectorShuffle(MVT::v2f64, dl, Sub, Sub, {1,-1});
- Result = DAG.getNode(ISD::FADD, dl, MVT::v2f64, Shuffle, Sub);
+ Result = DAG.getNode(ISD::FADD, dl, MVT::v2f64, Shuffle, Sub);
}
Result = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Result,
DAG.getIntPtrConstant(0, dl));
@@ -20385,7 +20385,7 @@ SDValue X86TargetLowering::LowerUINT_TO_FP(SDValue Op,
SDValue Chain = IsStrict ? Op.getOperand(0) : DAG.getEntryNode();
if (DstVT == MVT::f128)
- return SDValue();
+ return SDValue();
if (DstVT.isVector())
return lowerUINT_TO_FP_vec(Op, DAG, Subtarget);
@@ -20412,30 +20412,30 @@ SDValue X86TargetLowering::LowerUINT_TO_FP(SDValue Op,
if (SDValue V = LowerI64IntToFP_AVX512DQ(Op, DAG, Subtarget))
return V;
- // The transform for i64->f64 isn't correct for 0 when rounding to negative
- // infinity. It produces -0.0, so disable under strictfp.
- if (SrcVT == MVT::i64 && DstVT == MVT::f64 && X86ScalarSSEf64 && !IsStrict)
+ // The transform for i64->f64 isn't correct for 0 when rounding to negative
+ // infinity. It produces -0.0, so disable under strictfp.
+ if (SrcVT == MVT::i64 && DstVT == MVT::f64 && X86ScalarSSEf64 && !IsStrict)
return LowerUINT_TO_FP_i64(Op, DAG, Subtarget);
if (SrcVT == MVT::i32 && X86ScalarSSEf64 && DstVT != MVT::f80)
return LowerUINT_TO_FP_i32(Op, DAG, Subtarget);
- if (Subtarget.is64Bit() && SrcVT == MVT::i64 &&
- (DstVT == MVT::f32 || DstVT == MVT::f64))
+ if (Subtarget.is64Bit() && SrcVT == MVT::i64 &&
+ (DstVT == MVT::f32 || DstVT == MVT::f64))
return SDValue();
// Make a 64-bit buffer, and use it to build an FILD.
SDValue StackSlot = DAG.CreateStackTemporary(MVT::i64, 8);
int SSFI = cast<FrameIndexSDNode>(StackSlot)->getIndex();
- Align SlotAlign(8);
+ Align SlotAlign(8);
MachinePointerInfo MPI =
MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SSFI);
if (SrcVT == MVT::i32) {
- SDValue OffsetSlot =
- DAG.getMemBasePlusOffset(StackSlot, TypeSize::Fixed(4), dl);
- SDValue Store1 = DAG.getStore(Chain, dl, Src, StackSlot, MPI, SlotAlign);
+ SDValue OffsetSlot =
+ DAG.getMemBasePlusOffset(StackSlot, TypeSize::Fixed(4), dl);
+ SDValue Store1 = DAG.getStore(Chain, dl, Src, StackSlot, MPI, SlotAlign);
SDValue Store2 = DAG.getStore(Store1, dl, DAG.getConstant(0, dl, MVT::i32),
- OffsetSlot, MPI.getWithOffset(4), SlotAlign);
+ OffsetSlot, MPI.getWithOffset(4), SlotAlign);
std::pair<SDValue, SDValue> Tmp =
- BuildFILD(DstVT, MVT::i64, dl, Store2, StackSlot, MPI, SlotAlign, DAG);
+ BuildFILD(DstVT, MVT::i64, dl, Store2, StackSlot, MPI, SlotAlign, DAG);
if (IsStrict)
return DAG.getMergeValues({Tmp.first, Tmp.second}, dl);
@@ -20451,15 +20451,15 @@ SDValue X86TargetLowering::LowerUINT_TO_FP(SDValue Op,
ValueToStore = DAG.getBitcast(MVT::f64, ValueToStore);
}
SDValue Store =
- DAG.getStore(Chain, dl, ValueToStore, StackSlot, MPI, SlotAlign);
+ DAG.getStore(Chain, dl, ValueToStore, StackSlot, MPI, SlotAlign);
// For i64 source, we need to add the appropriate power of 2 if the input
- // was negative. We must be careful to do the computation in x87 extended
- // precision, not in SSE.
+ // was negative. We must be careful to do the computation in x87 extended
+ // precision, not in SSE.
SDVTList Tys = DAG.getVTList(MVT::f80, MVT::Other);
SDValue Ops[] = { Store, StackSlot };
SDValue Fild =
DAG.getMemIntrinsicNode(X86ISD::FILD, dl, Tys, Ops, MVT::i64, MPI,
- SlotAlign, MachineMemOperand::MOLoad);
+ SlotAlign, MachineMemOperand::MOLoad);
Chain = Fild.getValue(1);
@@ -20562,8 +20562,8 @@ X86TargetLowering::FP_TO_INTHelper(SDValue Op, SelectionDAG &DAG,
// of a signed i64. Let Thresh be the FP equivalent of
// 0x8000000000000000ULL.
//
- // Adjust = (Value >= Thresh) ? 0x80000000 : 0;
- // FltOfs = (Value >= Thresh) ? 0x80000000 : 0;
+ // Adjust = (Value >= Thresh) ? 0x80000000 : 0;
+ // FltOfs = (Value >= Thresh) ? 0x80000000 : 0;
// FistSrc = (Value - FltOfs);
// Fist-to-mem64 FistSrc
// Add 0 or 0x800...0ULL to the 64-bit result, which is equivalent
@@ -20593,31 +20593,31 @@ X86TargetLowering::FP_TO_INTHelper(SDValue Op, SelectionDAG &DAG,
*DAG.getContext(), TheVT);
SDValue Cmp;
if (IsStrict) {
- Cmp = DAG.getSetCC(DL, ResVT, Value, ThreshVal, ISD::SETGE, Chain,
- /*IsSignaling*/ true);
+ Cmp = DAG.getSetCC(DL, ResVT, Value, ThreshVal, ISD::SETGE, Chain,
+ /*IsSignaling*/ true);
Chain = Cmp.getValue(1);
} else {
- Cmp = DAG.getSetCC(DL, ResVT, Value, ThreshVal, ISD::SETGE);
- }
-
- // Our preferred lowering of
- //
- // (Value >= Thresh) ? 0x8000000000000000ULL : 0
- //
- // is
- //
- // (Value >= Thresh) << 63
- //
- // but since we can get here after LegalOperations, DAGCombine might do the
- // wrong thing if we create a select. So, directly create the preferred
- // version.
- SDValue Zext = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Cmp);
- SDValue Const63 = DAG.getConstant(63, DL, MVT::i8);
- Adjust = DAG.getNode(ISD::SHL, DL, MVT::i64, Zext, Const63);
-
- SDValue FltOfs = DAG.getSelect(DL, TheVT, Cmp, ThreshVal,
- DAG.getConstantFP(0.0, DL, TheVT));
-
+ Cmp = DAG.getSetCC(DL, ResVT, Value, ThreshVal, ISD::SETGE);
+ }
+
+ // Our preferred lowering of
+ //
+ // (Value >= Thresh) ? 0x8000000000000000ULL : 0
+ //
+ // is
+ //
+ // (Value >= Thresh) << 63
+ //
+ // but since we can get here after LegalOperations, DAGCombine might do the
+ // wrong thing if we create a select. So, directly create the preferred
+ // version.
+ SDValue Zext = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Cmp);
+ SDValue Const63 = DAG.getConstant(63, DL, MVT::i8);
+ Adjust = DAG.getNode(ISD::SHL, DL, MVT::i64, Zext, Const63);
+
+ SDValue FltOfs = DAG.getSelect(DL, TheVT, Cmp, ThreshVal,
+ DAG.getConstantFP(0.0, DL, TheVT));
+
if (IsStrict) {
Value = DAG.getNode(ISD::STRICT_FSUB, DL, { TheVT, MVT::Other},
{ Chain, Value, FltOfs });
@@ -21075,8 +21075,8 @@ SDValue X86TargetLowering::LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) const {
assert(VT.is128BitVector() && InVT.is256BitVector() && "Unexpected types!");
if ((VT == MVT::v4i32) && (InVT == MVT::v4i64)) {
- In = DAG.getBitcast(MVT::v8i32, In);
-
+ In = DAG.getBitcast(MVT::v8i32, In);
+
// On AVX2, v4i64 -> v4i32 becomes VPERMD.
if (Subtarget.hasInt256()) {
static const int ShufMask[] = {0, 2, 4, 6, -1, -1, -1, -1};
@@ -21085,17 +21085,17 @@ SDValue X86TargetLowering::LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) const {
DAG.getIntPtrConstant(0, DL));
}
- SDValue OpLo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v4i32, In,
+ SDValue OpLo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v4i32, In,
DAG.getIntPtrConstant(0, DL));
- SDValue OpHi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v4i32, In,
- DAG.getIntPtrConstant(4, DL));
+ SDValue OpHi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v4i32, In,
+ DAG.getIntPtrConstant(4, DL));
static const int ShufMask[] = {0, 2, 4, 6};
return DAG.getVectorShuffle(VT, DL, OpLo, OpHi, ShufMask);
}
if ((VT == MVT::v8i16) && (InVT == MVT::v8i32)) {
- In = DAG.getBitcast(MVT::v32i8, In);
-
+ In = DAG.getBitcast(MVT::v32i8, In);
+
// On AVX2, v8i32 -> v8i16 becomes PSHUFB.
if (Subtarget.hasInt256()) {
// The PSHUFB mask:
@@ -21106,17 +21106,17 @@ SDValue X86TargetLowering::LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) const {
In = DAG.getVectorShuffle(MVT::v32i8, DL, In, In, ShufMask1);
In = DAG.getBitcast(MVT::v4i64, In);
- static const int ShufMask2[] = {0, 2, -1, -1};
- In = DAG.getVectorShuffle(MVT::v4i64, DL, In, In, ShufMask2);
- return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v8i16,
- DAG.getBitcast(MVT::v16i16, In),
- DAG.getIntPtrConstant(0, DL));
+ static const int ShufMask2[] = {0, 2, -1, -1};
+ In = DAG.getVectorShuffle(MVT::v4i64, DL, In, In, ShufMask2);
+ return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v8i16,
+ DAG.getBitcast(MVT::v16i16, In),
+ DAG.getIntPtrConstant(0, DL));
}
- SDValue OpLo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v16i8, In,
+ SDValue OpLo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v16i8, In,
DAG.getIntPtrConstant(0, DL));
- SDValue OpHi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v16i8, In,
- DAG.getIntPtrConstant(16, DL));
+ SDValue OpHi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, MVT::v16i8, In,
+ DAG.getIntPtrConstant(16, DL));
// The PSHUFB mask:
static const int ShufMask1[] = {0, 1, 4, 5, 8, 9, 12, 13,
@@ -21452,155 +21452,155 @@ SDValue X86TargetLowering::LRINT_LLRINTHelper(SDNode *N,
return DAG.getLoad(DstVT, DL, Chain, StackPtr, MPI);
}
-SDValue
-X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
- // This is based on the TargetLowering::expandFP_TO_INT_SAT implementation,
- // but making use of X86 specifics to produce better instruction sequences.
- SDNode *Node = Op.getNode();
- bool IsSigned = Node->getOpcode() == ISD::FP_TO_SINT_SAT;
- unsigned FpToIntOpcode = IsSigned ? ISD::FP_TO_SINT : ISD::FP_TO_UINT;
- SDLoc dl(SDValue(Node, 0));
- SDValue Src = Node->getOperand(0);
-
- // There are three types involved here: SrcVT is the source floating point
- // type, DstVT is the type of the result, and TmpVT is the result of the
- // intermediate FP_TO_*INT operation we'll use (which may be a promotion of
- // DstVT).
- EVT SrcVT = Src.getValueType();
- EVT DstVT = Node->getValueType(0);
- EVT TmpVT = DstVT;
-
- // This code is only for floats and doubles. Fall back to generic code for
- // anything else.
- if (!isScalarFPTypeInSSEReg(SrcVT))
- return SDValue();
-
- unsigned SatWidth = Node->getConstantOperandVal(1);
- unsigned DstWidth = DstVT.getScalarSizeInBits();
- unsigned TmpWidth = TmpVT.getScalarSizeInBits();
- assert(SatWidth <= DstWidth && SatWidth <= TmpWidth &&
- "Expected saturation width smaller than result width");
-
- // Promote result of FP_TO_*INT to at least 32 bits.
- if (TmpWidth < 32) {
- TmpVT = MVT::i32;
- TmpWidth = 32;
- }
-
- // Promote conversions to unsigned 32-bit to 64-bit, because it will allow
- // us to use a native signed conversion instead.
- if (SatWidth == 32 && !IsSigned && Subtarget.is64Bit()) {
- TmpVT = MVT::i64;
- TmpWidth = 64;
- }
-
- // If the saturation width is smaller than the size of the temporary result,
- // we can always use signed conversion, which is native.
- if (SatWidth < TmpWidth)
- FpToIntOpcode = ISD::FP_TO_SINT;
-
- // Determine minimum and maximum integer values and their corresponding
- // floating-point values.
- APInt MinInt, MaxInt;
- if (IsSigned) {
- MinInt = APInt::getSignedMinValue(SatWidth).sextOrSelf(DstWidth);
- MaxInt = APInt::getSignedMaxValue(SatWidth).sextOrSelf(DstWidth);
- } else {
- MinInt = APInt::getMinValue(SatWidth).zextOrSelf(DstWidth);
- MaxInt = APInt::getMaxValue(SatWidth).zextOrSelf(DstWidth);
- }
-
- APFloat MinFloat(DAG.EVTToAPFloatSemantics(SrcVT));
- APFloat MaxFloat(DAG.EVTToAPFloatSemantics(SrcVT));
-
- APFloat::opStatus MinStatus = MinFloat.convertFromAPInt(
- MinInt, IsSigned, APFloat::rmTowardZero);
- APFloat::opStatus MaxStatus = MaxFloat.convertFromAPInt(
- MaxInt, IsSigned, APFloat::rmTowardZero);
- bool AreExactFloatBounds = !(MinStatus & APFloat::opStatus::opInexact)
- && !(MaxStatus & APFloat::opStatus::opInexact);
-
- SDValue MinFloatNode = DAG.getConstantFP(MinFloat, dl, SrcVT);
- SDValue MaxFloatNode = DAG.getConstantFP(MaxFloat, dl, SrcVT);
-
- // If the integer bounds are exactly representable as floats, emit a
- // min+max+fptoi sequence. Otherwise use comparisons and selects.
- if (AreExactFloatBounds) {
- if (DstVT != TmpVT) {
- // Clamp by MinFloat from below. If Src is NaN, propagate NaN.
- SDValue MinClamped = DAG.getNode(
- X86ISD::FMAX, dl, SrcVT, MinFloatNode, Src);
- // Clamp by MaxFloat from above. If Src is NaN, propagate NaN.
- SDValue BothClamped = DAG.getNode(
- X86ISD::FMIN, dl, SrcVT, MaxFloatNode, MinClamped);
- // Convert clamped value to integer.
- SDValue FpToInt = DAG.getNode(FpToIntOpcode, dl, TmpVT, BothClamped);
-
- // NaN will become INDVAL, with the top bit set and the rest zero.
- // Truncation will discard the top bit, resulting in zero.
- return DAG.getNode(ISD::TRUNCATE, dl, DstVT, FpToInt);
- }
-
- // Clamp by MinFloat from below. If Src is NaN, the result is MinFloat.
- SDValue MinClamped = DAG.getNode(
- X86ISD::FMAX, dl, SrcVT, Src, MinFloatNode);
- // Clamp by MaxFloat from above. NaN cannot occur.
- SDValue BothClamped = DAG.getNode(
- X86ISD::FMINC, dl, SrcVT, MinClamped, MaxFloatNode);
- // Convert clamped value to integer.
- SDValue FpToInt = DAG.getNode(FpToIntOpcode, dl, DstVT, BothClamped);
-
- if (!IsSigned) {
- // In the unsigned case we're done, because we mapped NaN to MinFloat,
- // which is zero.
- return FpToInt;
- }
-
- // Otherwise, select zero if Src is NaN.
- SDValue ZeroInt = DAG.getConstant(0, dl, DstVT);
- return DAG.getSelectCC(
- dl, Src, Src, ZeroInt, FpToInt, ISD::CondCode::SETUO);
- }
-
- SDValue MinIntNode = DAG.getConstant(MinInt, dl, DstVT);
- SDValue MaxIntNode = DAG.getConstant(MaxInt, dl, DstVT);
-
- // Result of direct conversion, which may be selected away.
- SDValue FpToInt = DAG.getNode(FpToIntOpcode, dl, TmpVT, Src);
-
- if (DstVT != TmpVT) {
- // NaN will become INDVAL, with the top bit set and the rest zero.
- // Truncation will discard the top bit, resulting in zero.
- FpToInt = DAG.getNode(ISD::TRUNCATE, dl, DstVT, FpToInt);
- }
-
- SDValue Select = FpToInt;
- // For signed conversions where we saturate to the same size as the
- // result type of the fptoi instructions, INDVAL coincides with integer
- // minimum, so we don't need to explicitly check it.
- if (!IsSigned || SatWidth != TmpVT.getScalarSizeInBits()) {
- // If Src ULT MinFloat, select MinInt. In particular, this also selects
- // MinInt if Src is NaN.
- Select = DAG.getSelectCC(
- dl, Src, MinFloatNode, MinIntNode, Select, ISD::CondCode::SETULT);
- }
-
- // If Src OGT MaxFloat, select MaxInt.
- Select = DAG.getSelectCC(
- dl, Src, MaxFloatNode, MaxIntNode, Select, ISD::CondCode::SETOGT);
-
- // In the unsigned case we are done, because we mapped NaN to MinInt, which
- // is already zero. The promoted case was already handled above.
- if (!IsSigned || DstVT != TmpVT) {
- return Select;
- }
-
- // Otherwise, select 0 if Src is NaN.
- SDValue ZeroInt = DAG.getConstant(0, dl, DstVT);
- return DAG.getSelectCC(
- dl, Src, Src, ZeroInt, Select, ISD::CondCode::SETUO);
-}
-
+SDValue
+X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
+ // This is based on the TargetLowering::expandFP_TO_INT_SAT implementation,
+ // but making use of X86 specifics to produce better instruction sequences.
+ SDNode *Node = Op.getNode();
+ bool IsSigned = Node->getOpcode() == ISD::FP_TO_SINT_SAT;
+ unsigned FpToIntOpcode = IsSigned ? ISD::FP_TO_SINT : ISD::FP_TO_UINT;
+ SDLoc dl(SDValue(Node, 0));
+ SDValue Src = Node->getOperand(0);
+
+ // There are three types involved here: SrcVT is the source floating point
+ // type, DstVT is the type of the result, and TmpVT is the result of the
+ // intermediate FP_TO_*INT operation we'll use (which may be a promotion of
+ // DstVT).
+ EVT SrcVT = Src.getValueType();
+ EVT DstVT = Node->getValueType(0);
+ EVT TmpVT = DstVT;
+
+ // This code is only for floats and doubles. Fall back to generic code for
+ // anything else.
+ if (!isScalarFPTypeInSSEReg(SrcVT))
+ return SDValue();
+
+ unsigned SatWidth = Node->getConstantOperandVal(1);
+ unsigned DstWidth = DstVT.getScalarSizeInBits();
+ unsigned TmpWidth = TmpVT.getScalarSizeInBits();
+ assert(SatWidth <= DstWidth && SatWidth <= TmpWidth &&
+ "Expected saturation width smaller than result width");
+
+ // Promote result of FP_TO_*INT to at least 32 bits.
+ if (TmpWidth < 32) {
+ TmpVT = MVT::i32;
+ TmpWidth = 32;
+ }
+
+ // Promote conversions to unsigned 32-bit to 64-bit, because it will allow
+ // us to use a native signed conversion instead.
+ if (SatWidth == 32 && !IsSigned && Subtarget.is64Bit()) {
+ TmpVT = MVT::i64;
+ TmpWidth = 64;
+ }
+
+ // If the saturation width is smaller than the size of the temporary result,
+ // we can always use signed conversion, which is native.
+ if (SatWidth < TmpWidth)
+ FpToIntOpcode = ISD::FP_TO_SINT;
+
+ // Determine minimum and maximum integer values and their corresponding
+ // floating-point values.
+ APInt MinInt, MaxInt;
+ if (IsSigned) {
+ MinInt = APInt::getSignedMinValue(SatWidth).sextOrSelf(DstWidth);
+ MaxInt = APInt::getSignedMaxValue(SatWidth).sextOrSelf(DstWidth);
+ } else {
+ MinInt = APInt::getMinValue(SatWidth).zextOrSelf(DstWidth);
+ MaxInt = APInt::getMaxValue(SatWidth).zextOrSelf(DstWidth);
+ }
+
+ APFloat MinFloat(DAG.EVTToAPFloatSemantics(SrcVT));
+ APFloat MaxFloat(DAG.EVTToAPFloatSemantics(SrcVT));
+
+ APFloat::opStatus MinStatus = MinFloat.convertFromAPInt(
+ MinInt, IsSigned, APFloat::rmTowardZero);
+ APFloat::opStatus MaxStatus = MaxFloat.convertFromAPInt(
+ MaxInt, IsSigned, APFloat::rmTowardZero);
+ bool AreExactFloatBounds = !(MinStatus & APFloat::opStatus::opInexact)
+ && !(MaxStatus & APFloat::opStatus::opInexact);
+
+ SDValue MinFloatNode = DAG.getConstantFP(MinFloat, dl, SrcVT);
+ SDValue MaxFloatNode = DAG.getConstantFP(MaxFloat, dl, SrcVT);
+
+ // If the integer bounds are exactly representable as floats, emit a
+ // min+max+fptoi sequence. Otherwise use comparisons and selects.
+ if (AreExactFloatBounds) {
+ if (DstVT != TmpVT) {
+ // Clamp by MinFloat from below. If Src is NaN, propagate NaN.
+ SDValue MinClamped = DAG.getNode(
+ X86ISD::FMAX, dl, SrcVT, MinFloatNode, Src);
+ // Clamp by MaxFloat from above. If Src is NaN, propagate NaN.
+ SDValue BothClamped = DAG.getNode(
+ X86ISD::FMIN, dl, SrcVT, MaxFloatNode, MinClamped);
+ // Convert clamped value to integer.
+ SDValue FpToInt = DAG.getNode(FpToIntOpcode, dl, TmpVT, BothClamped);
+
+ // NaN will become INDVAL, with the top bit set and the rest zero.
+ // Truncation will discard the top bit, resulting in zero.
+ return DAG.getNode(ISD::TRUNCATE, dl, DstVT, FpToInt);
+ }
+
+ // Clamp by MinFloat from below. If Src is NaN, the result is MinFloat.
+ SDValue MinClamped = DAG.getNode(
+ X86ISD::FMAX, dl, SrcVT, Src, MinFloatNode);
+ // Clamp by MaxFloat from above. NaN cannot occur.
+ SDValue BothClamped = DAG.getNode(
+ X86ISD::FMINC, dl, SrcVT, MinClamped, MaxFloatNode);
+ // Convert clamped value to integer.
+ SDValue FpToInt = DAG.getNode(FpToIntOpcode, dl, DstVT, BothClamped);
+
+ if (!IsSigned) {
+ // In the unsigned case we're done, because we mapped NaN to MinFloat,
+ // which is zero.
+ return FpToInt;
+ }
+
+ // Otherwise, select zero if Src is NaN.
+ SDValue ZeroInt = DAG.getConstant(0, dl, DstVT);
+ return DAG.getSelectCC(
+ dl, Src, Src, ZeroInt, FpToInt, ISD::CondCode::SETUO);
+ }
+
+ SDValue MinIntNode = DAG.getConstant(MinInt, dl, DstVT);
+ SDValue MaxIntNode = DAG.getConstant(MaxInt, dl, DstVT);
+
+ // Result of direct conversion, which may be selected away.
+ SDValue FpToInt = DAG.getNode(FpToIntOpcode, dl, TmpVT, Src);
+
+ if (DstVT != TmpVT) {
+ // NaN will become INDVAL, with the top bit set and the rest zero.
+ // Truncation will discard the top bit, resulting in zero.
+ FpToInt = DAG.getNode(ISD::TRUNCATE, dl, DstVT, FpToInt);
+ }
+
+ SDValue Select = FpToInt;
+ // For signed conversions where we saturate to the same size as the
+ // result type of the fptoi instructions, INDVAL coincides with integer
+ // minimum, so we don't need to explicitly check it.
+ if (!IsSigned || SatWidth != TmpVT.getScalarSizeInBits()) {
+ // If Src ULT MinFloat, select MinInt. In particular, this also selects
+ // MinInt if Src is NaN.
+ Select = DAG.getSelectCC(
+ dl, Src, MinFloatNode, MinIntNode, Select, ISD::CondCode::SETULT);
+ }
+
+ // If Src OGT MaxFloat, select MaxInt.
+ Select = DAG.getSelectCC(
+ dl, Src, MaxFloatNode, MaxIntNode, Select, ISD::CondCode::SETOGT);
+
+ // In the unsigned case we are done, because we mapped NaN to MinInt, which
+ // is already zero. The promoted case was already handled above.
+ if (!IsSigned || DstVT != TmpVT) {
+ return Select;
+ }
+
+ // Otherwise, select 0 if Src is NaN.
+ SDValue ZeroInt = DAG.getConstant(0, dl, DstVT);
+ return DAG.getSelectCC(
+ dl, Src, Src, ZeroInt, Select, ISD::CondCode::SETUO);
+}
+
SDValue X86TargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
bool IsStrict = Op->isStrictFPOpcode();
@@ -21609,8 +21609,8 @@ SDValue X86TargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
SDValue In = Op.getOperand(IsStrict ? 1 : 0);
MVT SVT = In.getSimpleValueType();
- if (VT == MVT::f128)
- return SDValue();
+ if (VT == MVT::f128)
+ return SDValue();
assert(SVT == MVT::v2f32 && "Only customize MVT::v2f32 type legalization!");
@@ -21626,10 +21626,10 @@ SDValue X86TargetLowering::LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const {
bool IsStrict = Op->isStrictFPOpcode();
SDValue In = Op.getOperand(IsStrict ? 1 : 0);
// It's legal except when f128 is involved
- if (In.getSimpleValueType() != MVT::f128)
+ if (In.getSimpleValueType() != MVT::f128)
return Op;
- return SDValue();
+ return SDValue();
}
static SDValue LowerFP16_TO_FP(SDValue Op, SelectionDAG &DAG) {
@@ -21994,7 +21994,7 @@ static bool matchScalarReduction(SDValue Op, ISD::NodeType BinOp,
if (M == SrcOpMap.end()) {
VT = Src.getValueType();
// Quit if not the same type.
- if (!SrcOpMap.empty() && VT != SrcOpMap.begin()->first.getValueType())
+ if (!SrcOpMap.empty() && VT != SrcOpMap.begin()->first.getValueType())
return false;
unsigned NumElts = VT.getVectorNumElements();
APInt EltCount = APInt::getNullValue(NumElts);
@@ -22032,11 +22032,11 @@ static SDValue LowerVectorAllZero(const SDLoc &DL, SDValue V, ISD::CondCode CC,
const X86Subtarget &Subtarget,
SelectionDAG &DAG, X86::CondCode &X86CC) {
EVT VT = V.getValueType();
- unsigned ScalarSize = VT.getScalarSizeInBits();
- if (Mask.getBitWidth() != ScalarSize) {
- assert(ScalarSize == 1 && "Element Mask vs Vector bitwidth mismatch");
- return SDValue();
- }
+ unsigned ScalarSize = VT.getScalarSizeInBits();
+ if (Mask.getBitWidth() != ScalarSize) {
+ assert(ScalarSize == 1 && "Element Mask vs Vector bitwidth mismatch");
+ return SDValue();
+ }
assert((CC == ISD::SETEQ || CC == ISD::SETNE) && "Unsupported ISD::CondCode");
X86CC = (CC == ISD::SETEQ ? X86::COND_E : X86::COND_NE);
@@ -22940,8 +22940,8 @@ static SDValue LowerVSETCC(SDValue Op, const X86Subtarget &Subtarget,
Opc, dl, VT, Op0, Op1, DAG.getTargetConstant(SSECC, dl, MVT::i8));
}
- if (VT.getFixedSizeInBits() >
- Op.getSimpleValueType().getFixedSizeInBits()) {
+ if (VT.getFixedSizeInBits() >
+ Op.getSimpleValueType().getFixedSizeInBits()) {
// We emitted a compare with an XMM/YMM result. Finish converting to a
// mask register using a vptestm.
EVT CastVT = EVT(VT).changeVectorElementTypeToInteger();
@@ -23116,10 +23116,10 @@ static SDValue LowerVSETCC(SDValue Op, const X86Subtarget &Subtarget,
}
// Try to use SUBUS and PCMPEQ.
- if (FlipSigns)
- if (SDValue V =
- LowerVSETCCWithSUBUS(Op0, Op1, VT, Cond, dl, Subtarget, DAG))
- return V;
+ if (FlipSigns)
+ if (SDValue V =
+ LowerVSETCCWithSUBUS(Op0, Op1, VT, Cond, dl, Subtarget, DAG))
+ return V;
// We are handling one of the integer comparisons here. Since SSE only has
// GT and EQ comparisons for integer, swapping operands and multiple
@@ -23914,7 +23914,7 @@ static SDValue LowerEXTEND_VECTOR_INREG(SDValue Op,
MVT SVT = VT.getVectorElementType();
MVT InSVT = InVT.getVectorElementType();
- assert(SVT.getFixedSizeInBits() > InSVT.getFixedSizeInBits());
+ assert(SVT.getFixedSizeInBits() > InSVT.getFixedSizeInBits());
if (SVT != MVT::i64 && SVT != MVT::i32 && SVT != MVT::i16)
return SDValue();
@@ -24089,8 +24089,8 @@ static SDValue splitVectorStore(StoreSDNode *Store, SelectionDAG &DAG) {
std::tie(Value0, Value1) = splitVector(StoredVal, DAG, DL);
unsigned HalfOffset = Value0.getValueType().getStoreSize();
SDValue Ptr0 = Store->getBasePtr();
- SDValue Ptr1 =
- DAG.getMemBasePlusOffset(Ptr0, TypeSize::Fixed(HalfOffset), DL);
+ SDValue Ptr1 =
+ DAG.getMemBasePlusOffset(Ptr0, TypeSize::Fixed(HalfOffset), DL);
SDValue Ch0 =
DAG.getStore(Store->getChain(), DL, Value0, Ptr0, Store->getPointerInfo(),
Store->getOriginalAlign(),
@@ -24125,8 +24125,8 @@ static SDValue scalarizeVectorStore(StoreSDNode *Store, MVT StoreVT,
SmallVector<SDValue, 4> Stores;
for (unsigned i = 0; i != NumElems; ++i) {
unsigned Offset = i * ScalarSize;
- SDValue Ptr = DAG.getMemBasePlusOffset(Store->getBasePtr(),
- TypeSize::Fixed(Offset), DL);
+ SDValue Ptr = DAG.getMemBasePlusOffset(Store->getBasePtr(),
+ TypeSize::Fixed(Offset), DL);
SDValue Scl = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, StoreSVT, StoredVal,
DAG.getIntPtrConstant(i, DL));
SDValue Ch = DAG.getStore(Store->getChain(), DL, Scl, Ptr,
@@ -24147,22 +24147,22 @@ static SDValue LowerStore(SDValue Op, const X86Subtarget &Subtarget,
// Without AVX512DQ, we need to use a scalar type for v2i1/v4i1/v8i1 stores.
if (StoredVal.getValueType().isVector() &&
StoredVal.getValueType().getVectorElementType() == MVT::i1) {
- unsigned NumElts = StoredVal.getValueType().getVectorNumElements();
- assert(NumElts <= 8 && "Unexpected VT");
+ unsigned NumElts = StoredVal.getValueType().getVectorNumElements();
+ assert(NumElts <= 8 && "Unexpected VT");
assert(!St->isTruncatingStore() && "Expected non-truncating store");
assert(Subtarget.hasAVX512() && !Subtarget.hasDQI() &&
"Expected AVX512F without AVX512DQI");
- // We must pad with zeros to ensure we store zeroes to any unused bits.
+ // We must pad with zeros to ensure we store zeroes to any unused bits.
StoredVal = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, MVT::v16i1,
DAG.getUNDEF(MVT::v16i1), StoredVal,
DAG.getIntPtrConstant(0, dl));
StoredVal = DAG.getBitcast(MVT::i16, StoredVal);
StoredVal = DAG.getNode(ISD::TRUNCATE, dl, MVT::i8, StoredVal);
- // Make sure we store zeros in the extra bits.
- if (NumElts < 8)
- StoredVal = DAG.getZeroExtendInReg(
- StoredVal, dl, EVT::getIntegerVT(*DAG.getContext(), NumElts));
+ // Make sure we store zeros in the extra bits.
+ if (NumElts < 8)
+ StoredVal = DAG.getZeroExtendInReg(
+ StoredVal, dl, EVT::getIntegerVT(*DAG.getContext(), NumElts));
return DAG.getStore(St->getChain(), dl, StoredVal, St->getBasePtr(),
St->getPointerInfo(), St->getOriginalAlign(),
@@ -24418,7 +24418,7 @@ X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
SDValue Result;
if (!Lower) {
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
- Register SPReg = TLI.getStackPointerRegisterToSaveRestore();
+ Register SPReg = TLI.getStackPointerRegisterToSaveRestore();
assert(SPReg && "Target cannot require DYNAMIC_STACKALLOC expansion and"
" not tell us which reg is the stack pointer!");
@@ -24519,7 +24519,7 @@ SDValue X86TargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
MemOps.push_back(Store);
// Store fp_offset
- FIN = DAG.getMemBasePlusOffset(FIN, TypeSize::Fixed(4), DL);
+ FIN = DAG.getMemBasePlusOffset(FIN, TypeSize::Fixed(4), DL);
Store = DAG.getStore(
Op.getOperand(0), DL,
DAG.getConstant(FuncInfo->getVarArgsFPOffset(), DL, MVT::i32), FIN,
@@ -24584,18 +24584,18 @@ SDValue X86TargetLowering::LowerVAARG(SDValue Op, SelectionDAG &DAG) const {
Subtarget.hasSSE1());
}
- // Insert VAARG node into the DAG
- // VAARG returns two values: Variable Argument Address, Chain
- SDValue InstOps[] = {Chain, SrcPtr,
- DAG.getTargetConstant(ArgSize, dl, MVT::i32),
- DAG.getTargetConstant(ArgMode, dl, MVT::i8),
- DAG.getTargetConstant(Align, dl, MVT::i32)};
+ // Insert VAARG node into the DAG
+ // VAARG returns two values: Variable Argument Address, Chain
+ SDValue InstOps[] = {Chain, SrcPtr,
+ DAG.getTargetConstant(ArgSize, dl, MVT::i32),
+ DAG.getTargetConstant(ArgMode, dl, MVT::i8),
+ DAG.getTargetConstant(Align, dl, MVT::i32)};
SDVTList VTs = DAG.getVTList(getPointerTy(DAG.getDataLayout()), MVT::Other);
SDValue VAARG = DAG.getMemIntrinsicNode(
- Subtarget.isTarget64BitLP64() ? X86ISD::VAARG_64 : X86ISD::VAARG_X32, dl,
- VTs, InstOps, MVT::i64, MachinePointerInfo(SV),
- /*Alignment=*/None,
- MachineMemOperand::MOLoad | MachineMemOperand::MOStore);
+ Subtarget.isTarget64BitLP64() ? X86ISD::VAARG_64 : X86ISD::VAARG_X32, dl,
+ VTs, InstOps, MVT::i64, MachinePointerInfo(SV),
+ /*Alignment=*/None,
+ MachineMemOperand::MOLoad | MachineMemOperand::MOStore);
Chain = VAARG.getValue(1);
// Load the next argument and return it
@@ -24619,11 +24619,11 @@ static SDValue LowerVACOPY(SDValue Op, const X86Subtarget &Subtarget,
const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
SDLoc DL(Op);
- return DAG.getMemcpy(
- Chain, DL, DstPtr, SrcPtr,
- DAG.getIntPtrConstant(Subtarget.isTarget64BitLP64() ? 24 : 16, DL),
- Align(Subtarget.isTarget64BitLP64() ? 8 : 4), /*isVolatile*/ false, false,
- false, MachinePointerInfo(DstSV), MachinePointerInfo(SrcSV));
+ return DAG.getMemcpy(
+ Chain, DL, DstPtr, SrcPtr,
+ DAG.getIntPtrConstant(Subtarget.isTarget64BitLP64() ? 24 : 16, DL),
+ Align(Subtarget.isTarget64BitLP64() ? 8 : 4), /*isVolatile*/ false, false,
+ false, MachinePointerInfo(DstSV), MachinePointerInfo(SrcSV));
}
// Helper to get immediate/variable SSE shift opcode from other shift opcodes.
@@ -25070,12 +25070,12 @@ SDValue X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
SDValue Src2 = Op.getOperand(2);
SDValue Src3 = Op.getOperand(3);
- if (IntrData->Type == INTR_TYPE_3OP_IMM8 &&
- Src3.getValueType() != MVT::i8) {
- Src3 = DAG.getTargetConstant(
- cast<ConstantSDNode>(Src3)->getZExtValue() & 0xff, dl, MVT::i8);
- }
-
+ if (IntrData->Type == INTR_TYPE_3OP_IMM8 &&
+ Src3.getValueType() != MVT::i8) {
+ Src3 = DAG.getTargetConstant(
+ cast<ConstantSDNode>(Src3)->getZExtValue() & 0xff, dl, MVT::i8);
+ }
+
// We specify 2 possible opcodes for intrinsics with rounding modes.
// First, we check if the intrinsic may have non-default rounding mode,
// (IntrData->Opc1 != 0), then we check the rounding mode operand.
@@ -25094,18 +25094,18 @@ SDValue X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
return DAG.getNode(IntrData->Opc0, dl, Op.getValueType(),
{Src1, Src2, Src3});
}
- case INTR_TYPE_4OP_IMM8: {
- assert(Op.getOperand(4)->getOpcode() == ISD::TargetConstant);
- SDValue Src4 = Op.getOperand(4);
- if (Src4.getValueType() != MVT::i8) {
- Src4 = DAG.getTargetConstant(
- cast<ConstantSDNode>(Src4)->getZExtValue() & 0xff, dl, MVT::i8);
- }
-
- return DAG.getNode(IntrData->Opc0, dl, Op.getValueType(),
- Op.getOperand(1), Op.getOperand(2), Op.getOperand(3),
- Src4);
- }
+ case INTR_TYPE_4OP_IMM8: {
+ assert(Op.getOperand(4)->getOpcode() == ISD::TargetConstant);
+ SDValue Src4 = Op.getOperand(4);
+ if (Src4.getValueType() != MVT::i8) {
+ Src4 = DAG.getTargetConstant(
+ cast<ConstantSDNode>(Src4)->getZExtValue() & 0xff, dl, MVT::i8);
+ }
+
+ return DAG.getNode(IntrData->Opc0, dl, Op.getValueType(),
+ Op.getOperand(1), Op.getOperand(2), Op.getOperand(3),
+ Src4);
+ }
case INTR_TYPE_1OP_MASK: {
SDValue Src = Op.getOperand(1);
SDValue PassThru = Op.getOperand(2);
@@ -25338,21 +25338,21 @@ SDValue X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
case CMP_MASK_CC: {
MVT MaskVT = Op.getSimpleValueType();
SDValue CC = Op.getOperand(3);
- SDValue Mask = Op.getOperand(4);
+ SDValue Mask = Op.getOperand(4);
// We specify 2 possible opcodes for intrinsics with rounding modes.
// First, we check if the intrinsic may have non-default rounding mode,
// (IntrData->Opc1 != 0), then we check the rounding mode operand.
if (IntrData->Opc1 != 0) {
- SDValue Sae = Op.getOperand(5);
+ SDValue Sae = Op.getOperand(5);
if (isRoundModeSAE(Sae))
return DAG.getNode(IntrData->Opc1, dl, MaskVT, Op.getOperand(1),
- Op.getOperand(2), CC, Mask, Sae);
+ Op.getOperand(2), CC, Mask, Sae);
if (!isRoundModeCurDirection(Sae))
return SDValue();
}
//default rounding mode
return DAG.getNode(IntrData->Opc0, dl, MaskVT,
- {Op.getOperand(1), Op.getOperand(2), CC, Mask});
+ {Op.getOperand(1), Op.getOperand(2), CC, Mask});
}
case CMP_MASK_SCALAR_CC: {
SDValue Src1 = Op.getOperand(1);
@@ -25507,11 +25507,11 @@ SDValue X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
Op.getOperand(1), Op.getOperand(2), RoundingMode);
}
case BEXTRI: {
- assert(IntrData->Opc0 == X86ISD::BEXTRI && "Unexpected opcode");
+ assert(IntrData->Opc0 == X86ISD::BEXTRI && "Unexpected opcode");
uint64_t Imm = Op.getConstantOperandVal(2);
- SDValue Control = DAG.getTargetConstant(Imm & 0xffff, dl,
- Op.getValueType());
+ SDValue Control = DAG.getTargetConstant(Imm & 0xffff, dl,
+ Op.getValueType());
return DAG.getNode(IntrData->Opc0, dl, Op.getValueType(),
Op.getOperand(1), Control);
}
@@ -25902,8 +25902,8 @@ SDValue X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
// MMX register.
ShAmt = DAG.getNode(X86ISD::MMX_MOVW2D, DL, MVT::x86mmx, ShAmt);
return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, Op.getValueType(),
- DAG.getTargetConstant(NewIntrinsic, DL,
- getPointerTy(DAG.getDataLayout())),
+ DAG.getTargetConstant(NewIntrinsic, DL,
+ getPointerTy(DAG.getDataLayout())),
Op.getOperand(1), ShAmt);
}
}
@@ -26273,97 +26273,97 @@ static SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, const X86Subtarget &Subtarget,
return DAG.getNode(ISD::MERGE_VALUES, dl, Op->getVTList(), SetCC,
Operation.getValue(1));
}
- case Intrinsic::x86_aesenc128kl:
- case Intrinsic::x86_aesdec128kl:
- case Intrinsic::x86_aesenc256kl:
- case Intrinsic::x86_aesdec256kl: {
- SDLoc DL(Op);
- SDVTList VTs = DAG.getVTList(MVT::v2i64, MVT::i32, MVT::Other);
- SDValue Chain = Op.getOperand(0);
- unsigned Opcode;
-
- switch (IntNo) {
- default: llvm_unreachable("Impossible intrinsic");
- case Intrinsic::x86_aesenc128kl:
- Opcode = X86ISD::AESENC128KL;
- break;
- case Intrinsic::x86_aesdec128kl:
- Opcode = X86ISD::AESDEC128KL;
- break;
- case Intrinsic::x86_aesenc256kl:
- Opcode = X86ISD::AESENC256KL;
- break;
- case Intrinsic::x86_aesdec256kl:
- Opcode = X86ISD::AESDEC256KL;
- break;
- }
-
- MemIntrinsicSDNode *MemIntr = cast<MemIntrinsicSDNode>(Op);
- MachineMemOperand *MMO = MemIntr->getMemOperand();
- EVT MemVT = MemIntr->getMemoryVT();
- SDValue Operation = DAG.getMemIntrinsicNode(
- Opcode, DL, VTs, {Chain, Op.getOperand(2), Op.getOperand(3)}, MemVT,
- MMO);
- SDValue ZF = getSETCC(X86::COND_E, Operation.getValue(1), DL, DAG);
-
- return DAG.getNode(ISD::MERGE_VALUES, DL, Op->getVTList(),
- {ZF, Operation.getValue(0), Operation.getValue(2)});
- }
- case Intrinsic::x86_aesencwide128kl:
- case Intrinsic::x86_aesdecwide128kl:
- case Intrinsic::x86_aesencwide256kl:
- case Intrinsic::x86_aesdecwide256kl: {
- SDLoc DL(Op);
- SDVTList VTs = DAG.getVTList(
- {MVT::i32, MVT::v2i64, MVT::v2i64, MVT::v2i64, MVT::v2i64, MVT::v2i64,
- MVT::v2i64, MVT::v2i64, MVT::v2i64, MVT::Other});
- SDValue Chain = Op.getOperand(0);
- unsigned Opcode;
-
- switch (IntNo) {
- default: llvm_unreachable("Impossible intrinsic");
- case Intrinsic::x86_aesencwide128kl:
- Opcode = X86ISD::AESENCWIDE128KL;
- break;
- case Intrinsic::x86_aesdecwide128kl:
- Opcode = X86ISD::AESDECWIDE128KL;
- break;
- case Intrinsic::x86_aesencwide256kl:
- Opcode = X86ISD::AESENCWIDE256KL;
- break;
- case Intrinsic::x86_aesdecwide256kl:
- Opcode = X86ISD::AESDECWIDE256KL;
- break;
- }
-
- MemIntrinsicSDNode *MemIntr = cast<MemIntrinsicSDNode>(Op);
- MachineMemOperand *MMO = MemIntr->getMemOperand();
- EVT MemVT = MemIntr->getMemoryVT();
- SDValue Operation = DAG.getMemIntrinsicNode(
- Opcode, DL, VTs,
- {Chain, Op.getOperand(2), Op.getOperand(3), Op.getOperand(4),
- Op.getOperand(5), Op.getOperand(6), Op.getOperand(7),
- Op.getOperand(8), Op.getOperand(9), Op.getOperand(10)},
- MemVT, MMO);
- SDValue ZF = getSETCC(X86::COND_E, Operation.getValue(0), DL, DAG);
-
- return DAG.getNode(ISD::MERGE_VALUES, DL, Op->getVTList(),
- {ZF, Operation.getValue(1), Operation.getValue(2),
- Operation.getValue(3), Operation.getValue(4),
- Operation.getValue(5), Operation.getValue(6),
- Operation.getValue(7), Operation.getValue(8),
- Operation.getValue(9)});
- }
- case Intrinsic::x86_testui: {
- SDLoc dl(Op);
- SDValue Chain = Op.getOperand(0);
- SDVTList VTs = DAG.getVTList(MVT::i32, MVT::Other);
- SDValue Operation = DAG.getNode(X86ISD::TESTUI, dl, VTs, Chain);
- SDValue SetCC = getSETCC(X86::COND_B, Operation.getValue(0), dl, DAG);
- return DAG.getNode(ISD::MERGE_VALUES, dl, Op->getVTList(), SetCC,
- Operation.getValue(1));
- }
- }
+ case Intrinsic::x86_aesenc128kl:
+ case Intrinsic::x86_aesdec128kl:
+ case Intrinsic::x86_aesenc256kl:
+ case Intrinsic::x86_aesdec256kl: {
+ SDLoc DL(Op);
+ SDVTList VTs = DAG.getVTList(MVT::v2i64, MVT::i32, MVT::Other);
+ SDValue Chain = Op.getOperand(0);
+ unsigned Opcode;
+
+ switch (IntNo) {
+ default: llvm_unreachable("Impossible intrinsic");
+ case Intrinsic::x86_aesenc128kl:
+ Opcode = X86ISD::AESENC128KL;
+ break;
+ case Intrinsic::x86_aesdec128kl:
+ Opcode = X86ISD::AESDEC128KL;
+ break;
+ case Intrinsic::x86_aesenc256kl:
+ Opcode = X86ISD::AESENC256KL;
+ break;
+ case Intrinsic::x86_aesdec256kl:
+ Opcode = X86ISD::AESDEC256KL;
+ break;
+ }
+
+ MemIntrinsicSDNode *MemIntr = cast<MemIntrinsicSDNode>(Op);
+ MachineMemOperand *MMO = MemIntr->getMemOperand();
+ EVT MemVT = MemIntr->getMemoryVT();
+ SDValue Operation = DAG.getMemIntrinsicNode(
+ Opcode, DL, VTs, {Chain, Op.getOperand(2), Op.getOperand(3)}, MemVT,
+ MMO);
+ SDValue ZF = getSETCC(X86::COND_E, Operation.getValue(1), DL, DAG);
+
+ return DAG.getNode(ISD::MERGE_VALUES, DL, Op->getVTList(),
+ {ZF, Operation.getValue(0), Operation.getValue(2)});
+ }
+ case Intrinsic::x86_aesencwide128kl:
+ case Intrinsic::x86_aesdecwide128kl:
+ case Intrinsic::x86_aesencwide256kl:
+ case Intrinsic::x86_aesdecwide256kl: {
+ SDLoc DL(Op);
+ SDVTList VTs = DAG.getVTList(
+ {MVT::i32, MVT::v2i64, MVT::v2i64, MVT::v2i64, MVT::v2i64, MVT::v2i64,
+ MVT::v2i64, MVT::v2i64, MVT::v2i64, MVT::Other});
+ SDValue Chain = Op.getOperand(0);
+ unsigned Opcode;
+
+ switch (IntNo) {
+ default: llvm_unreachable("Impossible intrinsic");
+ case Intrinsic::x86_aesencwide128kl:
+ Opcode = X86ISD::AESENCWIDE128KL;
+ break;
+ case Intrinsic::x86_aesdecwide128kl:
+ Opcode = X86ISD::AESDECWIDE128KL;
+ break;
+ case Intrinsic::x86_aesencwide256kl:
+ Opcode = X86ISD::AESENCWIDE256KL;
+ break;
+ case Intrinsic::x86_aesdecwide256kl:
+ Opcode = X86ISD::AESDECWIDE256KL;
+ break;
+ }
+
+ MemIntrinsicSDNode *MemIntr = cast<MemIntrinsicSDNode>(Op);
+ MachineMemOperand *MMO = MemIntr->getMemOperand();
+ EVT MemVT = MemIntr->getMemoryVT();
+ SDValue Operation = DAG.getMemIntrinsicNode(
+ Opcode, DL, VTs,
+ {Chain, Op.getOperand(2), Op.getOperand(3), Op.getOperand(4),
+ Op.getOperand(5), Op.getOperand(6), Op.getOperand(7),
+ Op.getOperand(8), Op.getOperand(9), Op.getOperand(10)},
+ MemVT, MMO);
+ SDValue ZF = getSETCC(X86::COND_E, Operation.getValue(0), DL, DAG);
+
+ return DAG.getNode(ISD::MERGE_VALUES, DL, Op->getVTList(),
+ {ZF, Operation.getValue(1), Operation.getValue(2),
+ Operation.getValue(3), Operation.getValue(4),
+ Operation.getValue(5), Operation.getValue(6),
+ Operation.getValue(7), Operation.getValue(8),
+ Operation.getValue(9)});
+ }
+ case Intrinsic::x86_testui: {
+ SDLoc dl(Op);
+ SDValue Chain = Op.getOperand(0);
+ SDVTList VTs = DAG.getVTList(MVT::i32, MVT::Other);
+ SDValue Operation = DAG.getNode(X86ISD::TESTUI, dl, VTs, Chain);
+ SDValue SetCC = getSETCC(X86::COND_B, Operation.getValue(0), dl, DAG);
+ return DAG.getNode(ISD::MERGE_VALUES, dl, Op->getVTList(), SetCC,
+ Operation.getValue(1));
+ }
+ }
return SDValue();
}
@@ -26733,8 +26733,8 @@ SDValue X86TargetLowering::LowerINIT_TRAMPOLINE(SDValue Op,
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(2, dl, MVT::i64));
- OutChains[1] = DAG.getStore(Root, dl, FPtr, Addr,
- MachinePointerInfo(TrmpAddr, 2), Align(2));
+ OutChains[1] = DAG.getStore(Root, dl, FPtr, Addr,
+ MachinePointerInfo(TrmpAddr, 2), Align(2));
// Load the 'nest' parameter value into R10.
// R10 is specified in X86CallingConv.td
@@ -26746,8 +26746,8 @@ SDValue X86TargetLowering::LowerINIT_TRAMPOLINE(SDValue Op,
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(12, dl, MVT::i64));
- OutChains[3] = DAG.getStore(Root, dl, Nest, Addr,
- MachinePointerInfo(TrmpAddr, 12), Align(2));
+ OutChains[3] = DAG.getStore(Root, dl, Nest, Addr,
+ MachinePointerInfo(TrmpAddr, 12), Align(2));
// Jump to the nested function.
OpCode = (JMP64r << 8) | REX_WB; // jmpq *...
@@ -26789,7 +26789,7 @@ SDValue X86TargetLowering::LowerINIT_TRAMPOLINE(SDValue Op,
for (FunctionType::param_iterator I = FTy->param_begin(),
E = FTy->param_end(); I != E; ++I, ++Idx)
if (Attrs.hasAttribute(Idx, Attribute::InReg)) {
- const DataLayout &DL = DAG.getDataLayout();
+ const DataLayout &DL = DAG.getDataLayout();
// FIXME: should only count parameters that are lowered to integers.
InRegCount += (DL.getTypeSizeInBits(*I) + 31) / 32;
}
@@ -26827,20 +26827,20 @@ SDValue X86TargetLowering::LowerINIT_TRAMPOLINE(SDValue Op,
Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp,
DAG.getConstant(1, dl, MVT::i32));
- OutChains[1] = DAG.getStore(Root, dl, Nest, Addr,
- MachinePointerInfo(TrmpAddr, 1), Align(1));
+ OutChains[1] = DAG.getStore(Root, dl, Nest, Addr,
+ MachinePointerInfo(TrmpAddr, 1), Align(1));
const unsigned char JMP = 0xE9; // jmp <32bit dst> opcode.
Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp,
DAG.getConstant(5, dl, MVT::i32));
- OutChains[2] =
- DAG.getStore(Root, dl, DAG.getConstant(JMP, dl, MVT::i8), Addr,
- MachinePointerInfo(TrmpAddr, 5), Align(1));
+ OutChains[2] =
+ DAG.getStore(Root, dl, DAG.getConstant(JMP, dl, MVT::i8), Addr,
+ MachinePointerInfo(TrmpAddr, 5), Align(1));
Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp,
DAG.getConstant(6, dl, MVT::i32));
- OutChains[3] = DAG.getStore(Root, dl, Disp, Addr,
- MachinePointerInfo(TrmpAddr, 6), Align(1));
+ OutChains[3] = DAG.getStore(Root, dl, Disp, Addr,
+ MachinePointerInfo(TrmpAddr, 6), Align(1));
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
}
@@ -27134,47 +27134,47 @@ static SDValue LowerADDSAT_SUBSAT(SDValue Op, SelectionDAG &DAG,
MVT VT = Op.getSimpleValueType();
SDValue X = Op.getOperand(0), Y = Op.getOperand(1);
unsigned Opcode = Op.getOpcode();
- SDLoc DL(Op);
-
+ SDLoc DL(Op);
+
if (VT.getScalarType() == MVT::i1) {
switch (Opcode) {
default: llvm_unreachable("Expected saturated arithmetic opcode");
case ISD::UADDSAT:
case ISD::SADDSAT:
// *addsat i1 X, Y --> X | Y
- return DAG.getNode(ISD::OR, DL, VT, X, Y);
+ return DAG.getNode(ISD::OR, DL, VT, X, Y);
case ISD::USUBSAT:
case ISD::SSUBSAT:
// *subsat i1 X, Y --> X & ~Y
- return DAG.getNode(ISD::AND, DL, VT, X, DAG.getNOT(DL, Y, VT));
+ return DAG.getNode(ISD::AND, DL, VT, X, DAG.getNOT(DL, Y, VT));
}
}
- if (VT == MVT::v32i16 || VT == MVT::v64i8 ||
- (VT.is256BitVector() && !Subtarget.hasInt256())) {
- assert(Op.getSimpleValueType().isInteger() &&
- "Only handle AVX vector integer operation");
- return splitVectorIntBinary(Op, DAG);
+ if (VT == MVT::v32i16 || VT == MVT::v64i8 ||
+ (VT.is256BitVector() && !Subtarget.hasInt256())) {
+ assert(Op.getSimpleValueType().isInteger() &&
+ "Only handle AVX vector integer operation");
+ return splitVectorIntBinary(Op, DAG);
}
- // Avoid the generic expansion with min/max if we don't have pminu*/pmaxu*.
- const TargetLowering &TLI = DAG.getTargetLoweringInfo();
- EVT SetCCResultType =
- TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
+ // Avoid the generic expansion with min/max if we don't have pminu*/pmaxu*.
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ EVT SetCCResultType =
+ TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
+
+ if (Opcode == ISD::USUBSAT && !TLI.isOperationLegal(ISD::UMAX, VT)) {
+ // usubsat X, Y --> (X >u Y) ? X - Y : 0
+ SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, X, Y);
+ SDValue Cmp = DAG.getSetCC(DL, SetCCResultType, X, Y, ISD::SETUGT);
+ // TODO: Move this to DAGCombiner?
+ if (SetCCResultType == VT &&
+ DAG.ComputeNumSignBits(Cmp) == VT.getScalarSizeInBits())
+ return DAG.getNode(ISD::AND, DL, VT, Cmp, Sub);
+ return DAG.getSelect(DL, VT, Cmp, Sub, DAG.getConstant(0, DL, VT));
+ }
- if (Opcode == ISD::USUBSAT && !TLI.isOperationLegal(ISD::UMAX, VT)) {
- // usubsat X, Y --> (X >u Y) ? X - Y : 0
- SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, X, Y);
- SDValue Cmp = DAG.getSetCC(DL, SetCCResultType, X, Y, ISD::SETUGT);
- // TODO: Move this to DAGCombiner?
- if (SetCCResultType == VT &&
- DAG.ComputeNumSignBits(Cmp) == VT.getScalarSizeInBits())
- return DAG.getNode(ISD::AND, DL, VT, Cmp, Sub);
- return DAG.getSelect(DL, VT, Cmp, Sub, DAG.getConstant(0, DL, VT));
- }
-
- // Use default expansion.
- return SDValue();
+ // Use default expansion.
+ return SDValue();
}
static SDValue LowerABS(SDValue Op, const X86Subtarget &Subtarget,
@@ -27224,8 +27224,8 @@ static SDValue LowerMINMAX(SDValue Op, SelectionDAG &DAG) {
if (VT == MVT::v32i16 || VT == MVT::v64i8)
return splitVectorIntBinary(Op, DAG);
- // Default to expand.
- return SDValue();
+ // Default to expand.
+ return SDValue();
}
static SDValue LowerMUL(SDValue Op, const X86Subtarget &Subtarget,
@@ -27597,8 +27597,8 @@ SDValue X86TargetLowering::LowerWin64_i128OP(SDValue Op, SelectionDAG &DAG) cons
MachinePointerInfo MPI =
MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SPFI);
Entry.Node = StackPtr;
- InChain =
- DAG.getStore(InChain, dl, Op->getOperand(i), StackPtr, MPI, Align(16));
+ InChain =
+ DAG.getStore(InChain, dl, Op->getOperand(i), StackPtr, MPI, Align(16));
Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
Entry.Ty = PointerType::get(ArgTy,0);
Entry.IsSExt = false;
@@ -27889,7 +27889,7 @@ static SDValue convertShiftLeftToScale(SDValue Amt, const SDLoc &dl,
MVT VT = Amt.getSimpleValueType();
if (!(VT == MVT::v8i16 || VT == MVT::v4i32 ||
(Subtarget.hasInt256() && VT == MVT::v16i16) ||
- (Subtarget.hasVBMI2() && VT == MVT::v32i16) ||
+ (Subtarget.hasVBMI2() && VT == MVT::v32i16) ||
(!Subtarget.hasAVX512() && VT == MVT::v16i8)))
return SDValue();
@@ -28467,12 +28467,12 @@ static SDValue LowerRotate(SDValue Op, const X86Subtarget &Subtarget,
return Op;
}
- // AVX512 VBMI2 vXi16 - lower to funnel shifts.
- if (Subtarget.hasVBMI2() && 16 == EltSizeInBits) {
- unsigned FunnelOpc = (Opcode == ISD::ROTL ? ISD::FSHL : ISD::FSHR);
- return DAG.getNode(FunnelOpc, DL, VT, R, R, Amt);
- }
-
+ // AVX512 VBMI2 vXi16 - lower to funnel shifts.
+ if (Subtarget.hasVBMI2() && 16 == EltSizeInBits) {
+ unsigned FunnelOpc = (Opcode == ISD::ROTL ? ISD::FSHL : ISD::FSHR);
+ return DAG.getNode(FunnelOpc, DL, VT, R, R, Amt);
+ }
+
assert((Opcode == ISD::ROTL) && "Only ROTL supported");
// XOP has 128-bit vector variable + immediate rotates.
@@ -28499,8 +28499,8 @@ static SDValue LowerRotate(SDValue Op, const X86Subtarget &Subtarget,
return splitVectorIntBinary(Op, DAG);
assert((VT == MVT::v4i32 || VT == MVT::v8i16 || VT == MVT::v16i8 ||
- ((VT == MVT::v8i32 || VT == MVT::v16i16 || VT == MVT::v32i8 ||
- VT == MVT::v32i16) &&
+ ((VT == MVT::v8i32 || VT == MVT::v16i16 || VT == MVT::v32i8 ||
+ VT == MVT::v32i16) &&
Subtarget.hasAVX2())) &&
"Only vXi32/vXi16/vXi8 vector rotates supported");
@@ -28797,8 +28797,8 @@ bool X86TargetLowering::lowerAtomicLoadAsLoadSDNode(const LoadInst &LI) const {
/// a) very likely accessed only by a single thread to minimize cache traffic,
/// and b) definitely dereferenceable. Returns the new Chain result.
static SDValue emitLockedStackOp(SelectionDAG &DAG,
- const X86Subtarget &Subtarget, SDValue Chain,
- const SDLoc &DL) {
+ const X86Subtarget &Subtarget, SDValue Chain,
+ const SDLoc &DL) {
// Implementation notes:
// 1) LOCK prefix creates a full read/write reordering barrier for memory
// operations issued by the current processor. As such, the location
@@ -29236,28 +29236,28 @@ static SDValue LowerBITREVERSE(SDValue Op, const X86Subtarget &Subtarget,
SDValue In = Op.getOperand(0);
SDLoc DL(Op);
- assert(VT.getScalarType() == MVT::i8 &&
- "Only byte vector BITREVERSE supported");
-
+ assert(VT.getScalarType() == MVT::i8 &&
+ "Only byte vector BITREVERSE supported");
+
// Split v64i8 without BWI so that we can still use the PSHUFB lowering.
if (VT == MVT::v64i8 && !Subtarget.hasBWI())
return splitVectorIntUnary(Op, DAG);
// Decompose 256-bit ops into smaller 128-bit ops on pre-AVX2.
- if (VT == MVT::v32i8 && !Subtarget.hasInt256())
+ if (VT == MVT::v32i8 && !Subtarget.hasInt256())
return splitVectorIntUnary(Op, DAG);
- unsigned NumElts = VT.getVectorNumElements();
-
- // If we have GFNI, we can use GF2P8AFFINEQB to reverse the bits.
- if (Subtarget.hasGFNI()) {
- MVT MatrixVT = MVT::getVectorVT(MVT::i64, NumElts / 8);
- SDValue Matrix = DAG.getConstant(0x8040201008040201ULL, DL, MatrixVT);
- Matrix = DAG.getBitcast(VT, Matrix);
- return DAG.getNode(X86ISD::GF2P8AFFINEQB, DL, VT, In, Matrix,
- DAG.getTargetConstant(0, DL, MVT::i8));
- }
-
+ unsigned NumElts = VT.getVectorNumElements();
+
+ // If we have GFNI, we can use GF2P8AFFINEQB to reverse the bits.
+ if (Subtarget.hasGFNI()) {
+ MVT MatrixVT = MVT::getVectorVT(MVT::i64, NumElts / 8);
+ SDValue Matrix = DAG.getConstant(0x8040201008040201ULL, DL, MatrixVT);
+ Matrix = DAG.getBitcast(VT, Matrix);
+ return DAG.getNode(X86ISD::GF2P8AFFINEQB, DL, VT, In, Matrix,
+ DAG.getTargetConstant(0, DL, MVT::i8));
+ }
+
// Perform BITREVERSE using PSHUFB lookups. Each byte is split into
// two nibbles and a PSHUFB lookup to find the bitreverse of each
// 0-15 value (moved to the other nibble).
@@ -29289,58 +29289,58 @@ static SDValue LowerBITREVERSE(SDValue Op, const X86Subtarget &Subtarget,
return DAG.getNode(ISD::OR, DL, VT, Lo, Hi);
}
-static SDValue LowerPARITY(SDValue Op, const X86Subtarget &Subtarget,
- SelectionDAG &DAG) {
- SDLoc DL(Op);
- SDValue X = Op.getOperand(0);
- MVT VT = Op.getSimpleValueType();
-
- // Special case. If the input fits in 8-bits we can use a single 8-bit TEST.
- if (VT == MVT::i8 ||
- DAG.MaskedValueIsZero(X, APInt::getBitsSetFrom(VT.getSizeInBits(), 8))) {
- X = DAG.getNode(ISD::TRUNCATE, DL, MVT::i8, X);
- SDValue Flags = DAG.getNode(X86ISD::CMP, DL, MVT::i32, X,
- DAG.getConstant(0, DL, MVT::i8));
- // Copy the inverse of the parity flag into a register with setcc.
- SDValue Setnp = getSETCC(X86::COND_NP, Flags, DL, DAG);
- // Extend to the original type.
- return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Setnp);
- }
-
- if (VT == MVT::i64) {
- // Xor the high and low 16-bits together using a 32-bit operation.
- SDValue Hi = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32,
- DAG.getNode(ISD::SRL, DL, MVT::i64, X,
- DAG.getConstant(32, DL, MVT::i8)));
- SDValue Lo = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, X);
- X = DAG.getNode(ISD::XOR, DL, MVT::i32, Lo, Hi);
- }
-
- if (VT != MVT::i16) {
- // Xor the high and low 16-bits together using a 32-bit operation.
- SDValue Hi16 = DAG.getNode(ISD::SRL, DL, MVT::i32, X,
- DAG.getConstant(16, DL, MVT::i8));
- X = DAG.getNode(ISD::XOR, DL, MVT::i32, X, Hi16);
- } else {
- // If the input is 16-bits, we need to extend to use an i32 shift below.
- X = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, X);
- }
-
- // Finally xor the low 2 bytes together and use a 8-bit flag setting xor.
- // This should allow an h-reg to be used to save a shift.
- SDValue Hi = DAG.getNode(
- ISD::TRUNCATE, DL, MVT::i8,
- DAG.getNode(ISD::SRL, DL, MVT::i32, X, DAG.getConstant(8, DL, MVT::i8)));
- SDValue Lo = DAG.getNode(ISD::TRUNCATE, DL, MVT::i8, X);
- SDVTList VTs = DAG.getVTList(MVT::i8, MVT::i32);
- SDValue Flags = DAG.getNode(X86ISD::XOR, DL, VTs, Lo, Hi).getValue(1);
-
- // Copy the inverse of the parity flag into a register with setcc.
- SDValue Setnp = getSETCC(X86::COND_NP, Flags, DL, DAG);
- // Extend to the original type.
- return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Setnp);
-}
-
+static SDValue LowerPARITY(SDValue Op, const X86Subtarget &Subtarget,
+ SelectionDAG &DAG) {
+ SDLoc DL(Op);
+ SDValue X = Op.getOperand(0);
+ MVT VT = Op.getSimpleValueType();
+
+ // Special case. If the input fits in 8-bits we can use a single 8-bit TEST.
+ if (VT == MVT::i8 ||
+ DAG.MaskedValueIsZero(X, APInt::getBitsSetFrom(VT.getSizeInBits(), 8))) {
+ X = DAG.getNode(ISD::TRUNCATE, DL, MVT::i8, X);
+ SDValue Flags = DAG.getNode(X86ISD::CMP, DL, MVT::i32, X,
+ DAG.getConstant(0, DL, MVT::i8));
+ // Copy the inverse of the parity flag into a register with setcc.
+ SDValue Setnp = getSETCC(X86::COND_NP, Flags, DL, DAG);
+ // Extend to the original type.
+ return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Setnp);
+ }
+
+ if (VT == MVT::i64) {
+ // Xor the high and low 16-bits together using a 32-bit operation.
+ SDValue Hi = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32,
+ DAG.getNode(ISD::SRL, DL, MVT::i64, X,
+ DAG.getConstant(32, DL, MVT::i8)));
+ SDValue Lo = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, X);
+ X = DAG.getNode(ISD::XOR, DL, MVT::i32, Lo, Hi);
+ }
+
+ if (VT != MVT::i16) {
+ // Xor the high and low 16-bits together using a 32-bit operation.
+ SDValue Hi16 = DAG.getNode(ISD::SRL, DL, MVT::i32, X,
+ DAG.getConstant(16, DL, MVT::i8));
+ X = DAG.getNode(ISD::XOR, DL, MVT::i32, X, Hi16);
+ } else {
+ // If the input is 16-bits, we need to extend to use an i32 shift below.
+ X = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, X);
+ }
+
+ // Finally xor the low 2 bytes together and use a 8-bit flag setting xor.
+ // This should allow an h-reg to be used to save a shift.
+ SDValue Hi = DAG.getNode(
+ ISD::TRUNCATE, DL, MVT::i8,
+ DAG.getNode(ISD::SRL, DL, MVT::i32, X, DAG.getConstant(8, DL, MVT::i8)));
+ SDValue Lo = DAG.getNode(ISD::TRUNCATE, DL, MVT::i8, X);
+ SDVTList VTs = DAG.getVTList(MVT::i8, MVT::i32);
+ SDValue Flags = DAG.getNode(X86ISD::XOR, DL, VTs, Lo, Hi).getValue(1);
+
+ // Copy the inverse of the parity flag into a register with setcc.
+ SDValue Setnp = getSETCC(X86::COND_NP, Flags, DL, DAG);
+ // Extend to the original type.
+ return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Setnp);
+}
+
static SDValue lowerAtomicArithWithLOCK(SDValue N, SelectionDAG &DAG,
const X86Subtarget &Subtarget) {
unsigned NewOpc = 0;
@@ -29477,7 +29477,7 @@ static SDValue LowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG,
MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SPFI);
Chain =
DAG.getStore(Node->getChain(), dl, Node->getOperand(2), StackPtr,
- MPI, MaybeAlign(), MachineMemOperand::MOStore);
+ MPI, MaybeAlign(), MachineMemOperand::MOStore);
SDVTList Tys = DAG.getVTList(MVT::f80, MVT::Other);
SDValue LdOps[] = {Chain, StackPtr};
SDValue Value =
@@ -29517,7 +29517,7 @@ static SDValue LowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG,
static SDValue LowerADDSUBCARRY(SDValue Op, SelectionDAG &DAG) {
SDNode *N = Op.getNode();
MVT VT = N->getSimpleValueType(0);
- unsigned Opc = Op.getOpcode();
+ unsigned Opc = Op.getOpcode();
// Let legalize expand this if it isn't a legal type yet.
if (!DAG.getTargetLoweringInfo().isTypeLegal(VT))
@@ -29532,14 +29532,14 @@ static SDValue LowerADDSUBCARRY(SDValue Op, SelectionDAG &DAG) {
Carry = DAG.getNode(X86ISD::ADD, DL, DAG.getVTList(CarryVT, MVT::i32),
Carry, DAG.getAllOnesConstant(DL, CarryVT));
- bool IsAdd = Opc == ISD::ADDCARRY || Opc == ISD::SADDO_CARRY;
- SDValue Sum = DAG.getNode(IsAdd ? X86ISD::ADC : X86ISD::SBB, DL, VTs,
- Op.getOperand(0), Op.getOperand(1),
- Carry.getValue(1));
+ bool IsAdd = Opc == ISD::ADDCARRY || Opc == ISD::SADDO_CARRY;
+ SDValue Sum = DAG.getNode(IsAdd ? X86ISD::ADC : X86ISD::SBB, DL, VTs,
+ Op.getOperand(0), Op.getOperand(1),
+ Carry.getValue(1));
- bool IsSigned = Opc == ISD::SADDO_CARRY || Opc == ISD::SSUBO_CARRY;
- SDValue SetCC = getSETCC(IsSigned ? X86::COND_O : X86::COND_B,
- Sum.getValue(1), DL, DAG);
+ bool IsSigned = Opc == ISD::SADDO_CARRY || Opc == ISD::SSUBO_CARRY;
+ SDValue SetCC = getSETCC(IsSigned ? X86::COND_O : X86::COND_B,
+ Sum.getValue(1), DL, DAG);
if (N->getValueType(1) == MVT::i1)
SetCC = DAG.getNode(ISD::TRUNCATE, DL, MVT::i1, SetCC);
@@ -29944,7 +29944,7 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::ATOMIC_LOAD_AND: return lowerAtomicArith(Op, DAG, Subtarget);
case ISD::ATOMIC_STORE: return LowerATOMIC_STORE(Op, DAG, Subtarget);
case ISD::BITREVERSE: return LowerBITREVERSE(Op, Subtarget, DAG);
- case ISD::PARITY: return LowerPARITY(Op, Subtarget, DAG);
+ case ISD::PARITY: return LowerPARITY(Op, Subtarget, DAG);
case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG);
case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, Subtarget, DAG);
case ISD::VECTOR_SHUFFLE: return lowerVECTOR_SHUFFLE(Op, Subtarget, DAG);
@@ -29979,8 +29979,8 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::STRICT_FP_TO_SINT:
case ISD::FP_TO_UINT:
case ISD::STRICT_FP_TO_UINT: return LowerFP_TO_INT(Op, DAG);
- case ISD::FP_TO_SINT_SAT:
- case ISD::FP_TO_UINT_SAT: return LowerFP_TO_INT_SAT(Op, DAG);
+ case ISD::FP_TO_SINT_SAT:
+ case ISD::FP_TO_UINT_SAT: return LowerFP_TO_INT_SAT(Op, DAG);
case ISD::FP_EXTEND:
case ISD::STRICT_FP_EXTEND: return LowerFP_EXTEND(Op, DAG);
case ISD::FP_ROUND:
@@ -30047,8 +30047,8 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::UMULO: return LowerXALUO(Op, DAG);
case ISD::READCYCLECOUNTER: return LowerREADCYCLECOUNTER(Op, Subtarget,DAG);
case ISD::BITCAST: return LowerBITCAST(Op, Subtarget, DAG);
- case ISD::SADDO_CARRY:
- case ISD::SSUBO_CARRY:
+ case ISD::SADDO_CARRY:
+ case ISD::SSUBO_CARRY:
case ISD::ADDCARRY:
case ISD::SUBCARRY: return LowerADDSUBCARRY(Op, DAG);
case ISD::ADD:
@@ -30116,9 +30116,9 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N,
Results.push_back(Chain);
return;
}
- case X86ISD::CVTPS2PH:
- Results.push_back(LowerCVTPS2PH(SDValue(N, 0), DAG));
- return;
+ case X86ISD::CVTPS2PH:
+ Results.push_back(LowerCVTPS2PH(SDValue(N, 0), DAG));
+ return;
case ISD::CTPOP: {
assert(N->getValueType(0) == MVT::i64 && "Unexpected VT!");
// Use a v2i64 if possible.
@@ -30360,7 +30360,7 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N,
std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
assert(isTypeLegal(LoVT) && "Split VT not legal?");
- SDValue Lo = getEXTEND_VECTOR_INREG(N->getOpcode(), dl, LoVT, In, DAG);
+ SDValue Lo = getEXTEND_VECTOR_INREG(N->getOpcode(), dl, LoVT, In, DAG);
// We need to shift the input over by half the number of elements.
unsigned NumElts = InVT.getVectorNumElements();
@@ -30370,7 +30370,7 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N,
ShufMask[i] = i + HalfNumElts;
SDValue Hi = DAG.getVectorShuffle(InVT, dl, In, In, ShufMask);
- Hi = getEXTEND_VECTOR_INREG(N->getOpcode(), dl, HiVT, Hi, DAG);
+ Hi = getEXTEND_VECTOR_INREG(N->getOpcode(), dl, HiVT, Hi, DAG);
SDValue Res = DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Lo, Hi);
Results.push_back(Res);
@@ -30721,30 +30721,30 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N,
swapInH =
DAG.getCopyToReg(cpInH.getValue(0), dl, Regs64bit ? X86::RCX : X86::ECX,
swapInH, cpInH.getValue(1));
-
- // In 64-bit mode we might need the base pointer in RBX, but we can't know
- // until later. So we keep the RBX input in a vreg and use a custom
- // inserter.
- // Since RBX will be a reserved register the register allocator will not
- // make sure its value will be properly saved and restored around this
- // live-range.
+
+ // In 64-bit mode we might need the base pointer in RBX, but we can't know
+ // until later. So we keep the RBX input in a vreg and use a custom
+ // inserter.
+ // Since RBX will be a reserved register the register allocator will not
+ // make sure its value will be properly saved and restored around this
+ // live-range.
SDValue Result;
SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue);
MachineMemOperand *MMO = cast<AtomicSDNode>(N)->getMemOperand();
- if (Regs64bit) {
- SDValue Ops[] = {swapInH.getValue(0), N->getOperand(1), swapInL,
- swapInH.getValue(1)};
- Result =
- DAG.getMemIntrinsicNode(X86ISD::LCMPXCHG16_DAG, dl, Tys, Ops, T, MMO);
+ if (Regs64bit) {
+ SDValue Ops[] = {swapInH.getValue(0), N->getOperand(1), swapInL,
+ swapInH.getValue(1)};
+ Result =
+ DAG.getMemIntrinsicNode(X86ISD::LCMPXCHG16_DAG, dl, Tys, Ops, T, MMO);
} else {
- swapInL = DAG.getCopyToReg(swapInH.getValue(0), dl, X86::EBX, swapInL,
+ swapInL = DAG.getCopyToReg(swapInH.getValue(0), dl, X86::EBX, swapInL,
swapInH.getValue(1));
SDValue Ops[] = {swapInL.getValue(0), N->getOperand(1),
swapInL.getValue(1)};
- Result =
- DAG.getMemIntrinsicNode(X86ISD::LCMPXCHG8_DAG, dl, Tys, Ops, T, MMO);
+ Result =
+ DAG.getMemIntrinsicNode(X86ISD::LCMPXCHG8_DAG, dl, Tys, Ops, T, MMO);
}
-
+
SDValue cpOutL = DAG.getCopyFromReg(Result.getValue(0), dl,
Regs64bit ? X86::RAX : X86::EAX,
HalfT, Result.getValue(1));
@@ -30989,9 +30989,9 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
NODE_NAME_CASE(COMI)
NODE_NAME_CASE(UCOMI)
NODE_NAME_CASE(CMPM)
- NODE_NAME_CASE(CMPMM)
+ NODE_NAME_CASE(CMPMM)
NODE_NAME_CASE(STRICT_CMPM)
- NODE_NAME_CASE(CMPMM_SAE)
+ NODE_NAME_CASE(CMPMM_SAE)
NODE_NAME_CASE(SETCC)
NODE_NAME_CASE(SETCC_CARRY)
NODE_NAME_CASE(FSETCC)
@@ -31109,7 +31109,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
NODE_NAME_CASE(XOR)
NODE_NAME_CASE(AND)
NODE_NAME_CASE(BEXTR)
- NODE_NAME_CASE(BEXTRI)
+ NODE_NAME_CASE(BEXTRI)
NODE_NAME_CASE(BZHI)
NODE_NAME_CASE(PDEP)
NODE_NAME_CASE(PEXT)
@@ -31147,7 +31147,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
NODE_NAME_CASE(VBROADCAST)
NODE_NAME_CASE(VBROADCAST_LOAD)
NODE_NAME_CASE(VBROADCASTM)
- NODE_NAME_CASE(SUBV_BROADCAST_LOAD)
+ NODE_NAME_CASE(SUBV_BROADCAST_LOAD)
NODE_NAME_CASE(VPERMILPV)
NODE_NAME_CASE(VPERMILPI)
NODE_NAME_CASE(VPERM2X128)
@@ -31169,7 +31169,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
NODE_NAME_CASE(DBPSADBW)
NODE_NAME_CASE(VASTART_SAVE_XMM_REGS)
NODE_NAME_CASE(VAARG_64)
- NODE_NAME_CASE(VAARG_X32)
+ NODE_NAME_CASE(VAARG_X32)
NODE_NAME_CASE(WIN_ALLOCA)
NODE_NAME_CASE(MEMBARRIER)
NODE_NAME_CASE(MFENCE)
@@ -31326,15 +31326,15 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
NODE_NAME_CASE(ENQCMD)
NODE_NAME_CASE(ENQCMDS)
NODE_NAME_CASE(VP2INTERSECT)
- NODE_NAME_CASE(AESENC128KL)
- NODE_NAME_CASE(AESDEC128KL)
- NODE_NAME_CASE(AESENC256KL)
- NODE_NAME_CASE(AESDEC256KL)
- NODE_NAME_CASE(AESENCWIDE128KL)
- NODE_NAME_CASE(AESDECWIDE128KL)
- NODE_NAME_CASE(AESENCWIDE256KL)
- NODE_NAME_CASE(AESDECWIDE256KL)
- NODE_NAME_CASE(TESTUI)
+ NODE_NAME_CASE(AESENC128KL)
+ NODE_NAME_CASE(AESDEC128KL)
+ NODE_NAME_CASE(AESENC256KL)
+ NODE_NAME_CASE(AESDEC256KL)
+ NODE_NAME_CASE(AESENCWIDE128KL)
+ NODE_NAME_CASE(AESDECWIDE128KL)
+ NODE_NAME_CASE(AESENCWIDE256KL)
+ NODE_NAME_CASE(AESDECWIDE256KL)
+ NODE_NAME_CASE(TESTUI)
}
return nullptr;
#undef NODE_NAME_CASE
@@ -31680,7 +31680,7 @@ static bool isEFLAGSLiveAfter(MachineBasicBlock::iterator Itr,
/// Utility function to emit xbegin specifying the start of an RTM region.
static MachineBasicBlock *emitXBegin(MachineInstr &MI, MachineBasicBlock *MBB,
const TargetInstrInfo *TII) {
- const DebugLoc &DL = MI.getDebugLoc();
+ const DebugLoc &DL = MI.getDebugLoc();
const BasicBlock *BB = MBB->getBasicBlock();
MachineFunction::iterator I = ++MBB->getIterator();
@@ -31760,8 +31760,8 @@ static MachineBasicBlock *emitXBegin(MachineInstr &MI, MachineBasicBlock *MBB,
}
MachineBasicBlock *
-X86TargetLowering::EmitVAARGWithCustomInserter(MachineInstr &MI,
- MachineBasicBlock *MBB) const {
+X86TargetLowering::EmitVAARGWithCustomInserter(MachineInstr &MI,
+ MachineBasicBlock *MBB) const {
// Emit va_arg instruction on X86-64.
// Operands to this pseudo-instruction:
@@ -31772,8 +31772,8 @@ X86TargetLowering::EmitVAARGWithCustomInserter(MachineInstr &MI,
// 8 ) Align : Alignment of type
// 9 ) EFLAGS (implicit-def)
- assert(MI.getNumOperands() == 10 && "VAARG should have 10 operands!");
- static_assert(X86::AddrNumOperands == 5, "VAARG assumes 5 address operands");
+ assert(MI.getNumOperands() == 10 && "VAARG should have 10 operands!");
+ static_assert(X86::AddrNumOperands == 5, "VAARG assumes 5 address operands");
Register DestReg = MI.getOperand(0).getReg();
MachineOperand &Base = MI.getOperand(1);
@@ -31788,7 +31788,7 @@ X86TargetLowering::EmitVAARGWithCustomInserter(MachineInstr &MI,
MachineFunction *MF = MBB->getParent();
// Memory Reference
- assert(MI.hasOneMemOperand() && "Expected VAARG to have one memoperand");
+ assert(MI.hasOneMemOperand() && "Expected VAARG to have one memoperand");
MachineMemOperand *OldMMO = MI.memoperands().front();
@@ -31801,10 +31801,10 @@ X86TargetLowering::EmitVAARGWithCustomInserter(MachineInstr &MI,
// Machine Information
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
- const TargetRegisterClass *AddrRegClass =
- getRegClassFor(getPointerTy(MBB->getParent()->getDataLayout()));
+ const TargetRegisterClass *AddrRegClass =
+ getRegClassFor(getPointerTy(MBB->getParent()->getDataLayout()));
const TargetRegisterClass *OffsetRegClass = getRegClassFor(MVT::i32);
- const DebugLoc &DL = MI.getDebugLoc();
+ const DebugLoc &DL = MI.getDebugLoc();
// struct va_list {
// i32 gp_offset
@@ -31913,35 +31913,35 @@ X86TargetLowering::EmitVAARGWithCustomInserter(MachineInstr &MI,
// Read the reg_save_area address.
Register RegSaveReg = MRI.createVirtualRegister(AddrRegClass);
- BuildMI(
- offsetMBB, DL,
- TII->get(Subtarget.isTarget64BitLP64() ? X86::MOV64rm : X86::MOV32rm),
- RegSaveReg)
+ BuildMI(
+ offsetMBB, DL,
+ TII->get(Subtarget.isTarget64BitLP64() ? X86::MOV64rm : X86::MOV32rm),
+ RegSaveReg)
.add(Base)
.add(Scale)
.add(Index)
- .addDisp(Disp, Subtarget.isTarget64BitLP64() ? 16 : 12)
+ .addDisp(Disp, Subtarget.isTarget64BitLP64() ? 16 : 12)
.add(Segment)
.setMemRefs(LoadOnlyMMO);
- if (Subtarget.isTarget64BitLP64()) {
- // Zero-extend the offset
- Register OffsetReg64 = MRI.createVirtualRegister(AddrRegClass);
- BuildMI(offsetMBB, DL, TII->get(X86::SUBREG_TO_REG), OffsetReg64)
- .addImm(0)
- .addReg(OffsetReg)
- .addImm(X86::sub_32bit);
-
- // Add the offset to the reg_save_area to get the final address.
- BuildMI(offsetMBB, DL, TII->get(X86::ADD64rr), OffsetDestReg)
- .addReg(OffsetReg64)
- .addReg(RegSaveReg);
- } else {
- // Add the offset to the reg_save_area to get the final address.
- BuildMI(offsetMBB, DL, TII->get(X86::ADD32rr), OffsetDestReg)
- .addReg(OffsetReg)
- .addReg(RegSaveReg);
- }
+ if (Subtarget.isTarget64BitLP64()) {
+ // Zero-extend the offset
+ Register OffsetReg64 = MRI.createVirtualRegister(AddrRegClass);
+ BuildMI(offsetMBB, DL, TII->get(X86::SUBREG_TO_REG), OffsetReg64)
+ .addImm(0)
+ .addReg(OffsetReg)
+ .addImm(X86::sub_32bit);
+
+ // Add the offset to the reg_save_area to get the final address.
+ BuildMI(offsetMBB, DL, TII->get(X86::ADD64rr), OffsetDestReg)
+ .addReg(OffsetReg64)
+ .addReg(RegSaveReg);
+ } else {
+ // Add the offset to the reg_save_area to get the final address.
+ BuildMI(offsetMBB, DL, TII->get(X86::ADD32rr), OffsetDestReg)
+ .addReg(OffsetReg)
+ .addReg(RegSaveReg);
+ }
// Compute the offset for the next argument
Register NextOffsetReg = MRI.createVirtualRegister(OffsetRegClass);
@@ -31970,9 +31970,9 @@ X86TargetLowering::EmitVAARGWithCustomInserter(MachineInstr &MI,
// Load the overflow_area address into a register.
Register OverflowAddrReg = MRI.createVirtualRegister(AddrRegClass);
- BuildMI(overflowMBB, DL,
- TII->get(Subtarget.isTarget64BitLP64() ? X86::MOV64rm : X86::MOV32rm),
- OverflowAddrReg)
+ BuildMI(overflowMBB, DL,
+ TII->get(Subtarget.isTarget64BitLP64() ? X86::MOV64rm : X86::MOV32rm),
+ OverflowAddrReg)
.add(Base)
.add(Scale)
.add(Index)
@@ -31987,17 +31987,17 @@ X86TargetLowering::EmitVAARGWithCustomInserter(MachineInstr &MI,
Register TmpReg = MRI.createVirtualRegister(AddrRegClass);
// aligned_addr = (addr + (align-1)) & ~(align-1)
- BuildMI(
- overflowMBB, DL,
- TII->get(Subtarget.isTarget64BitLP64() ? X86::ADD64ri32 : X86::ADD32ri),
- TmpReg)
+ BuildMI(
+ overflowMBB, DL,
+ TII->get(Subtarget.isTarget64BitLP64() ? X86::ADD64ri32 : X86::ADD32ri),
+ TmpReg)
.addReg(OverflowAddrReg)
.addImm(Alignment.value() - 1);
- BuildMI(
- overflowMBB, DL,
- TII->get(Subtarget.isTarget64BitLP64() ? X86::AND64ri32 : X86::AND32ri),
- OverflowDestReg)
+ BuildMI(
+ overflowMBB, DL,
+ TII->get(Subtarget.isTarget64BitLP64() ? X86::AND64ri32 : X86::AND32ri),
+ OverflowDestReg)
.addReg(TmpReg)
.addImm(~(uint64_t)(Alignment.value() - 1));
} else {
@@ -32008,16 +32008,16 @@ X86TargetLowering::EmitVAARGWithCustomInserter(MachineInstr &MI,
// Compute the next overflow address after this argument.
// (the overflow address should be kept 8-byte aligned)
Register NextAddrReg = MRI.createVirtualRegister(AddrRegClass);
- BuildMI(
- overflowMBB, DL,
- TII->get(Subtarget.isTarget64BitLP64() ? X86::ADD64ri32 : X86::ADD32ri),
- NextAddrReg)
- .addReg(OverflowDestReg)
- .addImm(ArgSizeA8);
+ BuildMI(
+ overflowMBB, DL,
+ TII->get(Subtarget.isTarget64BitLP64() ? X86::ADD64ri32 : X86::ADD32ri),
+ NextAddrReg)
+ .addReg(OverflowDestReg)
+ .addImm(ArgSizeA8);
// Store the new overflow address.
- BuildMI(overflowMBB, DL,
- TII->get(Subtarget.isTarget64BitLP64() ? X86::MOV64mr : X86::MOV32mr))
+ BuildMI(overflowMBB, DL,
+ TII->get(Subtarget.isTarget64BitLP64() ? X86::MOV64mr : X86::MOV32mr))
.add(Base)
.add(Scale)
.add(Index)
@@ -32073,10 +32073,10 @@ MachineBasicBlock *X86TargetLowering::EmitVAStartSaveXMMRegsWithCustomInserter(
// Now add the instructions.
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
- const DebugLoc &DL = MI.getDebugLoc();
+ const DebugLoc &DL = MI.getDebugLoc();
Register CountReg = MI.getOperand(0).getReg();
- int RegSaveFrameIndex = MI.getOperand(1).getImm();
+ int RegSaveFrameIndex = MI.getOperand(1).getImm();
int64_t VarArgsFPOffset = MI.getOperand(2).getImm();
if (!Subtarget.isCallingConvWin64(F->getFunction().getCallingConv())) {
@@ -32385,7 +32385,7 @@ MachineBasicBlock *
X86TargetLowering::EmitLoweredSelect(MachineInstr &MI,
MachineBasicBlock *ThisMBB) const {
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
- const DebugLoc &DL = MI.getDebugLoc();
+ const DebugLoc &DL = MI.getDebugLoc();
// To "insert" a SELECT_CC instruction, we actually have to insert the
// diamond control-flow pattern. The incoming instruction knows the
@@ -32540,7 +32540,7 @@ X86TargetLowering::EmitLoweredProbedAlloca(MachineInstr &MI,
MachineFunction *MF = MBB->getParent();
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
const X86FrameLowering &TFI = *Subtarget.getFrameLowering();
- const DebugLoc &DL = MI.getDebugLoc();
+ const DebugLoc &DL = MI.getDebugLoc();
const BasicBlock *LLVM_BB = MBB->getBasicBlock();
const unsigned ProbeSize = getStackProbeSize(*MF);
@@ -32633,7 +32633,7 @@ X86TargetLowering::EmitLoweredSegAlloca(MachineInstr &MI,
MachineBasicBlock *BB) const {
MachineFunction *MF = BB->getParent();
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
- const DebugLoc &DL = MI.getDebugLoc();
+ const DebugLoc &DL = MI.getDebugLoc();
const BasicBlock *LLVM_BB = BB->getBasicBlock();
assert(MF->shouldSplitStack());
@@ -32668,7 +32668,7 @@ X86TargetLowering::EmitLoweredSegAlloca(MachineInstr &MI,
const TargetRegisterClass *AddrRegClass =
getRegClassFor(getPointerTy(MF->getDataLayout()));
- Register mallocPtrVReg = MRI.createVirtualRegister(AddrRegClass),
+ Register mallocPtrVReg = MRI.createVirtualRegister(AddrRegClass),
bumpSPPtrVReg = MRI.createVirtualRegister(AddrRegClass),
tmpSPVReg = MRI.createVirtualRegister(AddrRegClass),
SPLimitVReg = MRI.createVirtualRegister(AddrRegClass),
@@ -32768,7 +32768,7 @@ X86TargetLowering::EmitLoweredCatchRet(MachineInstr &MI,
MachineFunction *MF = BB->getParent();
const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
MachineBasicBlock *TargetMBB = MI.getOperand(0).getMBB();
- const DebugLoc &DL = MI.getDebugLoc();
+ const DebugLoc &DL = MI.getDebugLoc();
assert(!isAsynchronousEHPersonality(
classifyEHPersonality(MF->getFunction().getPersonalityFn())) &&
@@ -32806,7 +32806,7 @@ X86TargetLowering::EmitLoweredTLSAddr(MachineInstr &MI,
// inside MC, therefore without the two markers shrink-wrapping
// may push the prologue/epilogue pass them.
const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
- const DebugLoc &DL = MI.getDebugLoc();
+ const DebugLoc &DL = MI.getDebugLoc();
MachineFunction &MF = *BB->getParent();
// Emit CALLSEQ_START right before the instruction.
@@ -32835,7 +32835,7 @@ X86TargetLowering::EmitLoweredTLSCall(MachineInstr &MI,
// be in the normal return register.
MachineFunction *F = BB->getParent();
const X86InstrInfo *TII = Subtarget.getInstrInfo();
- const DebugLoc &DL = MI.getDebugLoc();
+ const DebugLoc &DL = MI.getDebugLoc();
assert(Subtarget.isTargetDarwin() && "Darwin only instr emitted?");
assert(MI.getOperand(3).isGlobal() && "This should be a global");
@@ -32974,7 +32974,7 @@ X86TargetLowering::EmitLoweredIndirectThunk(MachineInstr &MI,
MachineBasicBlock *BB) const {
// Copy the virtual register into the R11 physical register and
// call the retpoline thunk.
- const DebugLoc &DL = MI.getDebugLoc();
+ const DebugLoc &DL = MI.getDebugLoc();
const X86InstrInfo *TII = Subtarget.getInstrInfo();
Register CalleeVReg = MI.getOperand(0).getReg();
unsigned Opc = getOpcodeForIndirectThunk(MI.getOpcode());
@@ -33036,7 +33036,7 @@ X86TargetLowering::EmitLoweredIndirectThunk(MachineInstr &MI,
/// \param [in] MBB The Machine Basic Block that will be modified.
void X86TargetLowering::emitSetJmpShadowStackFix(MachineInstr &MI,
MachineBasicBlock *MBB) const {
- const DebugLoc &DL = MI.getDebugLoc();
+ const DebugLoc &DL = MI.getDebugLoc();
MachineFunction *MF = MBB->getParent();
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
MachineRegisterInfo &MRI = MF->getRegInfo();
@@ -33079,7 +33079,7 @@ void X86TargetLowering::emitSetJmpShadowStackFix(MachineInstr &MI,
MachineBasicBlock *
X86TargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
MachineBasicBlock *MBB) const {
- const DebugLoc &DL = MI.getDebugLoc();
+ const DebugLoc &DL = MI.getDebugLoc();
MachineFunction *MF = MBB->getParent();
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
@@ -33239,7 +33239,7 @@ X86TargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
MachineBasicBlock *
X86TargetLowering::emitLongJmpShadowStackFix(MachineInstr &MI,
MachineBasicBlock *MBB) const {
- const DebugLoc &DL = MI.getDebugLoc();
+ const DebugLoc &DL = MI.getDebugLoc();
MachineFunction *MF = MBB->getParent();
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
MachineRegisterInfo &MRI = MF->getRegInfo();
@@ -33420,7 +33420,7 @@ X86TargetLowering::emitLongJmpShadowStackFix(MachineInstr &MI,
MachineBasicBlock *
X86TargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
MachineBasicBlock *MBB) const {
- const DebugLoc &DL = MI.getDebugLoc();
+ const DebugLoc &DL = MI.getDebugLoc();
MachineFunction *MF = MBB->getParent();
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
MachineRegisterInfo &MRI = MF->getRegInfo();
@@ -33504,7 +33504,7 @@ void X86TargetLowering::SetupEntryBlockForSjLj(MachineInstr &MI,
MachineBasicBlock *MBB,
MachineBasicBlock *DispatchBB,
int FI) const {
- const DebugLoc &DL = MI.getDebugLoc();
+ const DebugLoc &DL = MI.getDebugLoc();
MachineFunction *MF = MBB->getParent();
MachineRegisterInfo *MRI = &MF->getRegInfo();
const X86InstrInfo *TII = Subtarget.getInstrInfo();
@@ -33553,7 +33553,7 @@ void X86TargetLowering::SetupEntryBlockForSjLj(MachineInstr &MI,
MachineBasicBlock *
X86TargetLowering::EmitSjLjDispatchBlock(MachineInstr &MI,
MachineBasicBlock *BB) const {
- const DebugLoc &DL = MI.getDebugLoc();
+ const DebugLoc &DL = MI.getDebugLoc();
MachineFunction *MF = BB->getParent();
MachineRegisterInfo *MRI = &MF->getRegInfo();
const X86InstrInfo *TII = Subtarget.getInstrInfo();
@@ -33783,7 +33783,7 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
MachineBasicBlock *BB) const {
MachineFunction *MF = BB->getParent();
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
- const DebugLoc &DL = MI.getDebugLoc();
+ const DebugLoc &DL = MI.getDebugLoc();
auto TMMImmToTMMReg = [](unsigned Imm) {
assert (Imm < 8 && "Illegal tmm index");
@@ -33793,10 +33793,10 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
default: llvm_unreachable("Unexpected instr type to insert");
case X86::TLS_addr32:
case X86::TLS_addr64:
- case X86::TLS_addrX32:
+ case X86::TLS_addrX32:
case X86::TLS_base_addr32:
case X86::TLS_base_addr64:
- case X86::TLS_base_addrX32:
+ case X86::TLS_base_addrX32:
return EmitLoweredTLSAddr(MI, BB);
case X86::INDIRECT_THUNK_CALL32:
case X86::INDIRECT_THUNK_CALL64:
@@ -33952,8 +33952,8 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
return EmitVAStartSaveXMMRegsWithCustomInserter(MI, BB);
case X86::VAARG_64:
- case X86::VAARG_X32:
- return EmitVAARGWithCustomInserter(MI, BB);
+ case X86::VAARG_X32:
+ return EmitVAARGWithCustomInserter(MI, BB);
case X86::EH_SjLj_SetJmp32:
case X86::EH_SjLj_SetJmp64:
@@ -33977,7 +33977,7 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
case TargetOpcode::PATCHABLE_EVENT_CALL:
case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL:
- return BB;
+ return BB;
case X86::LCMPXCHG8B: {
const X86RegisterInfo *TRI = Subtarget.getRegisterInfo();
@@ -34032,75 +34032,75 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
return BB;
}
- case X86::LCMPXCHG16B_NO_RBX: {
- const X86RegisterInfo *TRI = Subtarget.getRegisterInfo();
- Register BasePtr = TRI->getBaseRegister();
- if (TRI->hasBasePointer(*MF) &&
- (BasePtr == X86::RBX || BasePtr == X86::EBX)) {
- if (!BB->isLiveIn(BasePtr))
- BB->addLiveIn(BasePtr);
- // Save RBX into a virtual register.
- Register SaveRBX =
- MF->getRegInfo().createVirtualRegister(&X86::GR64RegClass);
- BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), SaveRBX)
- .addReg(X86::RBX);
- Register Dst = MF->getRegInfo().createVirtualRegister(&X86::GR64RegClass);
- MachineInstrBuilder MIB =
- BuildMI(*BB, MI, DL, TII->get(X86::LCMPXCHG16B_SAVE_RBX), Dst);
- for (unsigned Idx = 0; Idx < X86::AddrNumOperands; ++Idx)
- MIB.add(MI.getOperand(Idx));
- MIB.add(MI.getOperand(X86::AddrNumOperands));
- MIB.addReg(SaveRBX);
- } else {
- // Simple case, just copy the virtual register to RBX.
- BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), X86::RBX)
- .add(MI.getOperand(X86::AddrNumOperands));
- MachineInstrBuilder MIB =
- BuildMI(*BB, MI, DL, TII->get(X86::LCMPXCHG16B));
- for (unsigned Idx = 0; Idx < X86::AddrNumOperands; ++Idx)
- MIB.add(MI.getOperand(Idx));
- }
- MI.eraseFromParent();
+ case X86::LCMPXCHG16B_NO_RBX: {
+ const X86RegisterInfo *TRI = Subtarget.getRegisterInfo();
+ Register BasePtr = TRI->getBaseRegister();
+ if (TRI->hasBasePointer(*MF) &&
+ (BasePtr == X86::RBX || BasePtr == X86::EBX)) {
+ if (!BB->isLiveIn(BasePtr))
+ BB->addLiveIn(BasePtr);
+ // Save RBX into a virtual register.
+ Register SaveRBX =
+ MF->getRegInfo().createVirtualRegister(&X86::GR64RegClass);
+ BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), SaveRBX)
+ .addReg(X86::RBX);
+ Register Dst = MF->getRegInfo().createVirtualRegister(&X86::GR64RegClass);
+ MachineInstrBuilder MIB =
+ BuildMI(*BB, MI, DL, TII->get(X86::LCMPXCHG16B_SAVE_RBX), Dst);
+ for (unsigned Idx = 0; Idx < X86::AddrNumOperands; ++Idx)
+ MIB.add(MI.getOperand(Idx));
+ MIB.add(MI.getOperand(X86::AddrNumOperands));
+ MIB.addReg(SaveRBX);
+ } else {
+ // Simple case, just copy the virtual register to RBX.
+ BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), X86::RBX)
+ .add(MI.getOperand(X86::AddrNumOperands));
+ MachineInstrBuilder MIB =
+ BuildMI(*BB, MI, DL, TII->get(X86::LCMPXCHG16B));
+ for (unsigned Idx = 0; Idx < X86::AddrNumOperands; ++Idx)
+ MIB.add(MI.getOperand(Idx));
+ }
+ MI.eraseFromParent();
return BB;
- }
- case X86::MWAITX: {
- const X86RegisterInfo *TRI = Subtarget.getRegisterInfo();
- Register BasePtr = TRI->getBaseRegister();
- bool IsRBX = (BasePtr == X86::RBX || BasePtr == X86::EBX);
- // If no need to save the base pointer, we generate MWAITXrrr,
- // else we generate pseudo MWAITX_SAVE_RBX.
- if (!IsRBX || !TRI->hasBasePointer(*MF)) {
- BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), X86::ECX)
- .addReg(MI.getOperand(0).getReg());
- BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), X86::EAX)
- .addReg(MI.getOperand(1).getReg());
- BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), X86::EBX)
- .addReg(MI.getOperand(2).getReg());
- BuildMI(*BB, MI, DL, TII->get(X86::MWAITXrrr));
- MI.eraseFromParent();
- } else {
- if (!BB->isLiveIn(BasePtr)) {
- BB->addLiveIn(BasePtr);
- }
- // Parameters can be copied into ECX and EAX but not EBX yet.
- BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), X86::ECX)
- .addReg(MI.getOperand(0).getReg());
- BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), X86::EAX)
- .addReg(MI.getOperand(1).getReg());
- assert(Subtarget.is64Bit() && "Expected 64-bit mode!");
- // Save RBX into a virtual register.
- Register SaveRBX =
- MF->getRegInfo().createVirtualRegister(&X86::GR64RegClass);
- BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), SaveRBX)
- .addReg(X86::RBX);
- // Generate mwaitx pseudo.
- Register Dst = MF->getRegInfo().createVirtualRegister(&X86::GR64RegClass);
- BuildMI(*BB, MI, DL, TII->get(X86::MWAITX_SAVE_RBX))
- .addDef(Dst) // Destination tied in with SaveRBX.
- .addReg(MI.getOperand(2).getReg()) // input value of EBX.
- .addUse(SaveRBX); // Save of base pointer.
- MI.eraseFromParent();
- }
+ }
+ case X86::MWAITX: {
+ const X86RegisterInfo *TRI = Subtarget.getRegisterInfo();
+ Register BasePtr = TRI->getBaseRegister();
+ bool IsRBX = (BasePtr == X86::RBX || BasePtr == X86::EBX);
+ // If no need to save the base pointer, we generate MWAITXrrr,
+ // else we generate pseudo MWAITX_SAVE_RBX.
+ if (!IsRBX || !TRI->hasBasePointer(*MF)) {
+ BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), X86::ECX)
+ .addReg(MI.getOperand(0).getReg());
+ BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), X86::EAX)
+ .addReg(MI.getOperand(1).getReg());
+ BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), X86::EBX)
+ .addReg(MI.getOperand(2).getReg());
+ BuildMI(*BB, MI, DL, TII->get(X86::MWAITXrrr));
+ MI.eraseFromParent();
+ } else {
+ if (!BB->isLiveIn(BasePtr)) {
+ BB->addLiveIn(BasePtr);
+ }
+ // Parameters can be copied into ECX and EAX but not EBX yet.
+ BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), X86::ECX)
+ .addReg(MI.getOperand(0).getReg());
+ BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), X86::EAX)
+ .addReg(MI.getOperand(1).getReg());
+ assert(Subtarget.is64Bit() && "Expected 64-bit mode!");
+ // Save RBX into a virtual register.
+ Register SaveRBX =
+ MF->getRegInfo().createVirtualRegister(&X86::GR64RegClass);
+ BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), SaveRBX)
+ .addReg(X86::RBX);
+ // Generate mwaitx pseudo.
+ Register Dst = MF->getRegInfo().createVirtualRegister(&X86::GR64RegClass);
+ BuildMI(*BB, MI, DL, TII->get(X86::MWAITX_SAVE_RBX))
+ .addDef(Dst) // Destination tied in with SaveRBX.
+ .addReg(MI.getOperand(2).getReg()) // input value of EBX.
+ .addUse(SaveRBX); // Save of base pointer.
+ MI.eraseFromParent();
+ }
return BB;
}
case TargetOpcode::PREALLOCATED_SETUP: {
@@ -34365,11 +34365,11 @@ void X86TargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
KnownBits Known2;
if (!!DemandedLHS) {
Known2 = DAG.computeKnownBits(Op.getOperand(0), DemandedLHS, Depth + 1);
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
}
if (!!DemandedRHS) {
Known2 = DAG.computeKnownBits(Op.getOperand(1), DemandedRHS, Depth + 1);
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
}
if (Known.countMinLeadingZeros() < BitWidth)
@@ -34412,11 +34412,11 @@ void X86TargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
KnownBits Known2 = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
// Only known if known in both the LHS and RHS.
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
break;
}
- case X86ISD::BEXTR:
- case X86ISD::BEXTRI: {
+ case X86ISD::BEXTR:
+ case X86ISD::BEXTRI: {
SDValue Op0 = Op.getOperand(0);
SDValue Op1 = Op.getOperand(1);
@@ -34438,28 +34438,28 @@ void X86TargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
}
break;
}
- case X86ISD::PDEP: {
- KnownBits Known2;
- Known = DAG.computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
- Known2 = DAG.computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
- // Zeros are retained from the mask operand. But not ones.
- Known.One.clearAllBits();
- // The result will have at least as many trailing zeros as the non-mask
- // operand since bits can only map to the same or higher bit position.
- Known.Zero.setLowBits(Known2.countMinTrailingZeros());
- break;
- }
- case X86ISD::PEXT: {
- Known = DAG.computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
- // The result has as many leading zeros as the number of zeroes in the mask.
- unsigned Count = Known.Zero.countPopulation();
- Known.Zero = APInt::getHighBitsSet(BitWidth, Count);
- Known.One.clearAllBits();
- break;
- }
- case X86ISD::VTRUNC:
- case X86ISD::VTRUNCS:
- case X86ISD::VTRUNCUS:
+ case X86ISD::PDEP: {
+ KnownBits Known2;
+ Known = DAG.computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
+ Known2 = DAG.computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
+ // Zeros are retained from the mask operand. But not ones.
+ Known.One.clearAllBits();
+ // The result will have at least as many trailing zeros as the non-mask
+ // operand since bits can only map to the same or higher bit position.
+ Known.Zero.setLowBits(Known2.countMinTrailingZeros());
+ break;
+ }
+ case X86ISD::PEXT: {
+ Known = DAG.computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
+ // The result has as many leading zeros as the number of zeroes in the mask.
+ unsigned Count = Known.Zero.countPopulation();
+ Known.Zero = APInt::getHighBitsSet(BitWidth, Count);
+ Known.One.clearAllBits();
+ break;
+ }
+ case X86ISD::VTRUNC:
+ case X86ISD::VTRUNCS:
+ case X86ISD::VTRUNCUS:
case X86ISD::CVTSI2P:
case X86ISD::CVTUI2P:
case X86ISD::CVTP2SI:
@@ -34476,7 +34476,7 @@ void X86TargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
case X86ISD::VMFPROUND:
case X86ISD::CVTPS2PH:
case X86ISD::MCVTPS2PH: {
- // Truncations/Conversions - upper elements are known zero.
+ // Truncations/Conversions - upper elements are known zero.
EVT SrcVT = Op.getOperand(0).getValueType();
if (SrcVT.isVector()) {
unsigned NumSrcElts = SrcVT.getVectorNumElements();
@@ -34554,7 +34554,7 @@ void X86TargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
continue;
KnownBits Known2 =
DAG.computeKnownBits(Ops[i], DemandedOps[i], Depth + 1);
- Known = KnownBits::commonBits(Known, Known2);
+ Known = KnownBits::commonBits(Known, Known2);
}
}
}
@@ -34733,18 +34733,18 @@ static bool matchUnaryShuffle(MVT MaskVT, ArrayRef<int> Mask,
unsigned MaskEltSize = MaskVT.getScalarSizeInBits();
// Match against a VZEXT_MOVL vXi32 zero-extending instruction.
- if (MaskEltSize == 32 && Mask[0] == 0) {
- if (isUndefOrZero(Mask[1]) && isUndefInRange(Mask, 2, NumMaskElts - 2)) {
- Shuffle = X86ISD::VZEXT_MOVL;
- SrcVT = DstVT = !Subtarget.hasSSE2() ? MVT::v4f32 : MaskVT;
- return true;
- }
- if (V1.getOpcode() == ISD::SCALAR_TO_VECTOR &&
- isUndefOrZeroInRange(Mask, 1, NumMaskElts - 1)) {
- Shuffle = X86ISD::VZEXT_MOVL;
- SrcVT = DstVT = !Subtarget.hasSSE2() ? MVT::v4f32 : MaskVT;
- return true;
- }
+ if (MaskEltSize == 32 && Mask[0] == 0) {
+ if (isUndefOrZero(Mask[1]) && isUndefInRange(Mask, 2, NumMaskElts - 2)) {
+ Shuffle = X86ISD::VZEXT_MOVL;
+ SrcVT = DstVT = !Subtarget.hasSSE2() ? MVT::v4f32 : MaskVT;
+ return true;
+ }
+ if (V1.getOpcode() == ISD::SCALAR_TO_VECTOR &&
+ isUndefOrZeroInRange(Mask, 1, NumMaskElts - 1)) {
+ Shuffle = X86ISD::VZEXT_MOVL;
+ SrcVT = DstVT = !Subtarget.hasSSE2() ? MVT::v4f32 : MaskVT;
+ return true;
+ }
}
// Match against a ANY/ZERO_EXTEND_VECTOR_INREG instruction.
@@ -34798,17 +34798,17 @@ static bool matchUnaryShuffle(MVT MaskVT, ArrayRef<int> Mask,
// instructions are no slower than UNPCKLPD but has the option to
// fold the input operand into even an unaligned memory load.
if (MaskVT.is128BitVector() && Subtarget.hasSSE3() && AllowFloatDomain) {
- if (isTargetShuffleEquivalent(MaskVT, Mask, {0, 0}, V1)) {
+ if (isTargetShuffleEquivalent(MaskVT, Mask, {0, 0}, V1)) {
Shuffle = X86ISD::MOVDDUP;
SrcVT = DstVT = MVT::v2f64;
return true;
}
- if (isTargetShuffleEquivalent(MaskVT, Mask, {0, 0, 2, 2}, V1)) {
+ if (isTargetShuffleEquivalent(MaskVT, Mask, {0, 0, 2, 2}, V1)) {
Shuffle = X86ISD::MOVSLDUP;
SrcVT = DstVT = MVT::v4f32;
return true;
}
- if (isTargetShuffleEquivalent(MaskVT, Mask, {1, 1, 3, 3}, V1)) {
+ if (isTargetShuffleEquivalent(MaskVT, Mask, {1, 1, 3, 3}, V1)) {
Shuffle = X86ISD::MOVSHDUP;
SrcVT = DstVT = MVT::v4f32;
return true;
@@ -34817,17 +34817,17 @@ static bool matchUnaryShuffle(MVT MaskVT, ArrayRef<int> Mask,
if (MaskVT.is256BitVector() && AllowFloatDomain) {
assert(Subtarget.hasAVX() && "AVX required for 256-bit vector shuffles");
- if (isTargetShuffleEquivalent(MaskVT, Mask, {0, 0, 2, 2}, V1)) {
+ if (isTargetShuffleEquivalent(MaskVT, Mask, {0, 0, 2, 2}, V1)) {
Shuffle = X86ISD::MOVDDUP;
SrcVT = DstVT = MVT::v4f64;
return true;
}
- if (isTargetShuffleEquivalent(MaskVT, Mask, {0, 0, 2, 2, 4, 4, 6, 6}, V1)) {
+ if (isTargetShuffleEquivalent(MaskVT, Mask, {0, 0, 2, 2, 4, 4, 6, 6}, V1)) {
Shuffle = X86ISD::MOVSLDUP;
SrcVT = DstVT = MVT::v8f32;
return true;
}
- if (isTargetShuffleEquivalent(MaskVT, Mask, {1, 1, 3, 3, 5, 5, 7, 7}, V1)) {
+ if (isTargetShuffleEquivalent(MaskVT, Mask, {1, 1, 3, 3, 5, 5, 7, 7}, V1)) {
Shuffle = X86ISD::MOVSHDUP;
SrcVT = DstVT = MVT::v8f32;
return true;
@@ -34837,21 +34837,21 @@ static bool matchUnaryShuffle(MVT MaskVT, ArrayRef<int> Mask,
if (MaskVT.is512BitVector() && AllowFloatDomain) {
assert(Subtarget.hasAVX512() &&
"AVX512 required for 512-bit vector shuffles");
- if (isTargetShuffleEquivalent(MaskVT, Mask, {0, 0, 2, 2, 4, 4, 6, 6}, V1)) {
+ if (isTargetShuffleEquivalent(MaskVT, Mask, {0, 0, 2, 2, 4, 4, 6, 6}, V1)) {
Shuffle = X86ISD::MOVDDUP;
SrcVT = DstVT = MVT::v8f64;
return true;
}
if (isTargetShuffleEquivalent(
- MaskVT, Mask,
- {0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14}, V1)) {
+ MaskVT, Mask,
+ {0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14}, V1)) {
Shuffle = X86ISD::MOVSLDUP;
SrcVT = DstVT = MVT::v16f32;
return true;
}
if (isTargetShuffleEquivalent(
- MaskVT, Mask,
- {1, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11, 11, 13, 13, 15, 15}, V1)) {
+ MaskVT, Mask,
+ {1, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11, 11, 13, 13, 15, 15}, V1)) {
Shuffle = X86ISD::MOVSHDUP;
SrcVT = DstVT = MVT::v16f32;
return true;
@@ -34933,10 +34933,10 @@ static bool matchUnaryPermuteShuffle(MVT MaskVT, ArrayRef<int> Mask,
}
// Handle PSHUFLW/PSHUFHW vXi16 repeated patterns.
- if (!ContainsZeros && AllowIntDomain && MaskScalarSizeInBits == 16 &&
- ((MaskVT.is128BitVector() && Subtarget.hasSSE2()) ||
- (MaskVT.is256BitVector() && Subtarget.hasAVX2()) ||
- (MaskVT.is512BitVector() && Subtarget.hasBWI()))) {
+ if (!ContainsZeros && AllowIntDomain && MaskScalarSizeInBits == 16 &&
+ ((MaskVT.is128BitVector() && Subtarget.hasSSE2()) ||
+ (MaskVT.is256BitVector() && Subtarget.hasAVX2()) ||
+ (MaskVT.is512BitVector() && Subtarget.hasBWI()))) {
SmallVector<int, 4> RepeatedMask;
if (is128BitLaneRepeatedShuffleMask(MaskEltVT, Mask, RepeatedMask)) {
ArrayRef<int> LoMask(RepeatedMask.data() + 0, 4);
@@ -35006,31 +35006,31 @@ static bool matchBinaryShuffle(MVT MaskVT, ArrayRef<int> Mask,
SelectionDAG &DAG, const X86Subtarget &Subtarget,
unsigned &Shuffle, MVT &SrcVT, MVT &DstVT,
bool IsUnary) {
- unsigned NumMaskElts = Mask.size();
+ unsigned NumMaskElts = Mask.size();
unsigned EltSizeInBits = MaskVT.getScalarSizeInBits();
if (MaskVT.is128BitVector()) {
- if (isTargetShuffleEquivalent(MaskVT, Mask, {0, 0}) && AllowFloatDomain) {
+ if (isTargetShuffleEquivalent(MaskVT, Mask, {0, 0}) && AllowFloatDomain) {
V2 = V1;
V1 = (SM_SentinelUndef == Mask[0] ? DAG.getUNDEF(MVT::v4f32) : V1);
Shuffle = Subtarget.hasSSE2() ? X86ISD::UNPCKL : X86ISD::MOVLHPS;
SrcVT = DstVT = Subtarget.hasSSE2() ? MVT::v2f64 : MVT::v4f32;
return true;
}
- if (isTargetShuffleEquivalent(MaskVT, Mask, {1, 1}) && AllowFloatDomain) {
+ if (isTargetShuffleEquivalent(MaskVT, Mask, {1, 1}) && AllowFloatDomain) {
V2 = V1;
Shuffle = Subtarget.hasSSE2() ? X86ISD::UNPCKH : X86ISD::MOVHLPS;
SrcVT = DstVT = Subtarget.hasSSE2() ? MVT::v2f64 : MVT::v4f32;
return true;
}
- if (isTargetShuffleEquivalent(MaskVT, Mask, {0, 3}) &&
- Subtarget.hasSSE2() && (AllowFloatDomain || !Subtarget.hasSSE41())) {
+ if (isTargetShuffleEquivalent(MaskVT, Mask, {0, 3}) &&
+ Subtarget.hasSSE2() && (AllowFloatDomain || !Subtarget.hasSSE41())) {
std::swap(V1, V2);
Shuffle = X86ISD::MOVSD;
SrcVT = DstVT = MVT::v2f64;
return true;
}
- if (isTargetShuffleEquivalent(MaskVT, Mask, {4, 1, 2, 3}) &&
+ if (isTargetShuffleEquivalent(MaskVT, Mask, {4, 1, 2, 3}) &&
(AllowFloatDomain || !Subtarget.hasSSE41())) {
Shuffle = X86ISD::MOVSS;
SrcVT = DstVT = MVT::v4f32;
@@ -35064,46 +35064,46 @@ static bool matchBinaryShuffle(MVT MaskVT, ArrayRef<int> Mask,
}
}
- // Attempt to match against a OR if we're performing a blend shuffle and the
- // non-blended source element is zero in each case.
- if ((EltSizeInBits % V1.getScalarValueSizeInBits()) == 0 &&
- (EltSizeInBits % V2.getScalarValueSizeInBits()) == 0) {
- bool IsBlend = true;
- unsigned NumV1Elts = V1.getValueType().getVectorNumElements();
- unsigned NumV2Elts = V2.getValueType().getVectorNumElements();
- unsigned Scale1 = NumV1Elts / NumMaskElts;
- unsigned Scale2 = NumV2Elts / NumMaskElts;
- APInt DemandedZeroV1 = APInt::getNullValue(NumV1Elts);
- APInt DemandedZeroV2 = APInt::getNullValue(NumV2Elts);
- for (unsigned i = 0; i != NumMaskElts; ++i) {
- int M = Mask[i];
- if (M == SM_SentinelUndef)
- continue;
- if (M == SM_SentinelZero) {
- DemandedZeroV1.setBits(i * Scale1, (i + 1) * Scale1);
- DemandedZeroV2.setBits(i * Scale2, (i + 1) * Scale2);
- continue;
- }
- if (M == (int)i) {
- DemandedZeroV2.setBits(i * Scale2, (i + 1) * Scale2);
- continue;
- }
- if (M == (int)(i + NumMaskElts)) {
- DemandedZeroV1.setBits(i * Scale1, (i + 1) * Scale1);
- continue;
- }
- IsBlend = false;
- break;
- }
- if (IsBlend &&
- DAG.computeKnownBits(V1, DemandedZeroV1).isZero() &&
- DAG.computeKnownBits(V2, DemandedZeroV2).isZero()) {
- Shuffle = ISD::OR;
- SrcVT = DstVT = MaskVT.changeTypeToInteger();
- return true;
- }
- }
-
+ // Attempt to match against a OR if we're performing a blend shuffle and the
+ // non-blended source element is zero in each case.
+ if ((EltSizeInBits % V1.getScalarValueSizeInBits()) == 0 &&
+ (EltSizeInBits % V2.getScalarValueSizeInBits()) == 0) {
+ bool IsBlend = true;
+ unsigned NumV1Elts = V1.getValueType().getVectorNumElements();
+ unsigned NumV2Elts = V2.getValueType().getVectorNumElements();
+ unsigned Scale1 = NumV1Elts / NumMaskElts;
+ unsigned Scale2 = NumV2Elts / NumMaskElts;
+ APInt DemandedZeroV1 = APInt::getNullValue(NumV1Elts);
+ APInt DemandedZeroV2 = APInt::getNullValue(NumV2Elts);
+ for (unsigned i = 0; i != NumMaskElts; ++i) {
+ int M = Mask[i];
+ if (M == SM_SentinelUndef)
+ continue;
+ if (M == SM_SentinelZero) {
+ DemandedZeroV1.setBits(i * Scale1, (i + 1) * Scale1);
+ DemandedZeroV2.setBits(i * Scale2, (i + 1) * Scale2);
+ continue;
+ }
+ if (M == (int)i) {
+ DemandedZeroV2.setBits(i * Scale2, (i + 1) * Scale2);
+ continue;
+ }
+ if (M == (int)(i + NumMaskElts)) {
+ DemandedZeroV1.setBits(i * Scale1, (i + 1) * Scale1);
+ continue;
+ }
+ IsBlend = false;
+ break;
+ }
+ if (IsBlend &&
+ DAG.computeKnownBits(V1, DemandedZeroV1).isZero() &&
+ DAG.computeKnownBits(V2, DemandedZeroV2).isZero()) {
+ Shuffle = ISD::OR;
+ SrcVT = DstVT = MaskVT.changeTypeToInteger();
+ return true;
+ }
+ }
+
return false;
}
@@ -35292,16 +35292,16 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
assert((Inputs.size() == 1 || Inputs.size() == 2) &&
"Unexpected number of shuffle inputs!");
- MVT RootVT = Root.getSimpleValueType();
- unsigned RootSizeInBits = RootVT.getSizeInBits();
- unsigned NumRootElts = RootVT.getVectorNumElements();
-
- // Canonicalize shuffle input op to the requested type.
- // TODO: Support cases where Op is smaller than VT.
- auto CanonicalizeShuffleInput = [&](MVT VT, SDValue Op) {
- return DAG.getBitcast(VT, Op);
- };
-
+ MVT RootVT = Root.getSimpleValueType();
+ unsigned RootSizeInBits = RootVT.getSizeInBits();
+ unsigned NumRootElts = RootVT.getVectorNumElements();
+
+ // Canonicalize shuffle input op to the requested type.
+ // TODO: Support cases where Op is smaller than VT.
+ auto CanonicalizeShuffleInput = [&](MVT VT, SDValue Op) {
+ return DAG.getBitcast(VT, Op);
+ };
+
// Find the inputs that enter the chain. Note that multiple uses are OK
// here, we're not going to remove the operands we find.
bool UnaryShuffle = (Inputs.size() == 1);
@@ -35311,8 +35311,8 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
MVT VT1 = V1.getSimpleValueType();
MVT VT2 = V2.getSimpleValueType();
- assert(VT1.getSizeInBits() == RootSizeInBits &&
- VT2.getSizeInBits() == RootSizeInBits && "Vector size mismatch");
+ assert(VT1.getSizeInBits() == RootSizeInBits &&
+ VT2.getSizeInBits() == RootSizeInBits && "Vector size mismatch");
SDLoc DL(Root);
SDValue Res;
@@ -35320,7 +35320,7 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
unsigned NumBaseMaskElts = BaseMask.size();
if (NumBaseMaskElts == 1) {
assert(BaseMask[0] == 0 && "Invalid shuffle index found!");
- return CanonicalizeShuffleInput(RootVT, V1);
+ return CanonicalizeShuffleInput(RootVT, V1);
}
bool OptForSize = DAG.shouldOptForSize();
@@ -35344,9 +35344,9 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
// we can just use the broadcast directly. This works for smaller broadcast
// elements as well as they already repeat across each mask element
if (UnaryShuffle && isTargetShuffleSplat(V1) && !isAnyZero(BaseMask) &&
- (BaseMaskEltSizeInBits % V1.getScalarValueSizeInBits()) == 0 &&
- V1.getValueSizeInBits() >= RootSizeInBits) {
- return CanonicalizeShuffleInput(RootVT, V1);
+ (BaseMaskEltSizeInBits % V1.getScalarValueSizeInBits()) == 0 &&
+ V1.getValueSizeInBits() >= RootSizeInBits) {
+ return CanonicalizeShuffleInput(RootVT, V1);
}
// Handle 128/256-bit lane shuffles of 512-bit vectors.
@@ -35360,11 +35360,11 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
return SDValue(); // Nothing to do!
assert(isInRange(BaseMask[0], 0, NumBaseMaskElts) &&
"Unexpected lane shuffle");
- Res = CanonicalizeShuffleInput(RootVT, V1);
- unsigned SubIdx = BaseMask[0] * (NumRootElts / NumBaseMaskElts);
+ Res = CanonicalizeShuffleInput(RootVT, V1);
+ unsigned SubIdx = BaseMask[0] * (NumRootElts / NumBaseMaskElts);
bool UseZero = isAnyZero(BaseMask);
Res = extractSubVector(Res, SubIdx, DAG, DL, BaseMaskEltSizeInBits);
- return widenSubVector(Res, UseZero, Subtarget, DAG, DL, RootSizeInBits);
+ return widenSubVector(Res, UseZero, Subtarget, DAG, DL, RootSizeInBits);
}
// Narrow shuffle mask to v4x128.
@@ -35373,8 +35373,8 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
narrowShuffleMaskElts(BaseMaskEltSizeInBits / 128, BaseMask, Mask);
// Try to lower to vshuf64x2/vshuf32x4.
- auto MatchSHUF128 = [&](MVT ShuffleVT, const SDLoc &DL, ArrayRef<int> Mask,
- SDValue V1, SDValue V2, SelectionDAG &DAG) {
+ auto MatchSHUF128 = [&](MVT ShuffleVT, const SDLoc &DL, ArrayRef<int> Mask,
+ SDValue V1, SDValue V2, SelectionDAG &DAG) {
unsigned PermMask = 0;
// Insure elements came from the same Op.
SDValue Ops[2] = {DAG.getUNDEF(ShuffleVT), DAG.getUNDEF(ShuffleVT)};
@@ -35397,8 +35397,8 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
}
return DAG.getNode(X86ISD::SHUF128, DL, ShuffleVT,
- CanonicalizeShuffleInput(ShuffleVT, Ops[0]),
- CanonicalizeShuffleInput(ShuffleVT, Ops[1]),
+ CanonicalizeShuffleInput(ShuffleVT, Ops[0]),
+ CanonicalizeShuffleInput(ShuffleVT, Ops[1]),
DAG.getTargetConstant(PermMask, DL, MVT::i8));
};
@@ -35413,9 +35413,9 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
(Mask[1] < 0 || Mask[3] < 0 || Mask[1] == (Mask[3] % 2));
if (!isAnyZero(Mask) && !PreferPERMQ) {
- if (Depth == 0 && Root.getOpcode() == X86ISD::SHUF128)
- return SDValue(); // Nothing to do!
- MVT ShuffleVT = (FloatDomain ? MVT::v8f64 : MVT::v8i64);
+ if (Depth == 0 && Root.getOpcode() == X86ISD::SHUF128)
+ return SDValue(); // Nothing to do!
+ MVT ShuffleVT = (FloatDomain ? MVT::v8f64 : MVT::v8i64);
if (SDValue V = MatchSHUF128(ShuffleVT, DL, Mask, V1, V2, DAG))
return DAG.getBitcast(RootVT, V);
}
@@ -35430,10 +35430,10 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
if (Depth == 0 && Root.getOpcode() == ISD::INSERT_SUBVECTOR)
return SDValue(); // Nothing to do!
assert(isInRange(BaseMask[0], 0, 2) && "Unexpected lane shuffle");
- Res = CanonicalizeShuffleInput(RootVT, V1);
- Res = extract128BitVector(Res, BaseMask[0] * (NumRootElts / 2), DAG, DL);
- return widenSubVector(Res, BaseMask[1] == SM_SentinelZero, Subtarget, DAG,
- DL, 256);
+ Res = CanonicalizeShuffleInput(RootVT, V1);
+ Res = extract128BitVector(Res, BaseMask[0] * (NumRootElts / 2), DAG, DL);
+ return widenSubVector(Res, BaseMask[1] == SM_SentinelZero, Subtarget, DAG,
+ DL, 256);
}
if (Depth == 0 && Root.getOpcode() == X86ISD::VPERM2X128)
@@ -35448,9 +35448,9 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
unsigned PermMask = 0;
PermMask |= ((BaseMask[0] < 0 ? 0x8 : (BaseMask[0] & 1)) << 0);
PermMask |= ((BaseMask[1] < 0 ? 0x8 : (BaseMask[1] & 1)) << 4);
- return DAG.getNode(
- X86ISD::VPERM2X128, DL, RootVT, CanonicalizeShuffleInput(RootVT, V1),
- DAG.getUNDEF(RootVT), DAG.getTargetConstant(PermMask, DL, MVT::i8));
+ return DAG.getNode(
+ X86ISD::VPERM2X128, DL, RootVT, CanonicalizeShuffleInput(RootVT, V1),
+ DAG.getUNDEF(RootVT), DAG.getTargetConstant(PermMask, DL, MVT::i8));
}
if (Depth == 0 && Root.getOpcode() == X86ISD::SHUF128)
@@ -35466,12 +35466,12 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
unsigned PermMask = 0;
PermMask |= ((BaseMask[0] & 3) << 0);
PermMask |= ((BaseMask[1] & 3) << 4);
- SDValue LHS = isInRange(BaseMask[0], 0, 2) ? V1 : V2;
- SDValue RHS = isInRange(BaseMask[1], 0, 2) ? V1 : V2;
- return DAG.getNode(X86ISD::VPERM2X128, DL, RootVT,
- CanonicalizeShuffleInput(RootVT, LHS),
- CanonicalizeShuffleInput(RootVT, RHS),
- DAG.getTargetConstant(PermMask, DL, MVT::i8));
+ SDValue LHS = isInRange(BaseMask[0], 0, 2) ? V1 : V2;
+ SDValue RHS = isInRange(BaseMask[1], 0, 2) ? V1 : V2;
+ return DAG.getNode(X86ISD::VPERM2X128, DL, RootVT,
+ CanonicalizeShuffleInput(RootVT, LHS),
+ CanonicalizeShuffleInput(RootVT, RHS),
+ DAG.getTargetConstant(PermMask, DL, MVT::i8));
}
}
}
@@ -35533,7 +35533,7 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
if ((Subtarget.hasAVX2() ||
(Subtarget.hasAVX() && 32 <= MaskEltSizeInBits)) &&
(!IsMaskedShuffle || NumRootElts == NumMaskElts)) {
- if (isUndefOrEqual(Mask, 0)) {
+ if (isUndefOrEqual(Mask, 0)) {
if (V1.getValueType() == MaskVT &&
V1.getOpcode() == ISD::SCALAR_TO_VECTOR &&
MayFoldLoad(V1.getOperand(0))) {
@@ -35546,7 +35546,7 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
if (Subtarget.hasAVX2()) {
if (Depth == 0 && Root.getOpcode() == X86ISD::VBROADCAST)
return SDValue(); // Nothing to do!
- Res = CanonicalizeShuffleInput(MaskVT, V1);
+ Res = CanonicalizeShuffleInput(MaskVT, V1);
Res = DAG.getNode(X86ISD::VBROADCAST, DL, MaskVT, Res);
return DAG.getBitcast(RootVT, Res);
}
@@ -35561,7 +35561,7 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
(NumRootElts == ShuffleVT.getVectorNumElements()))) {
if (Depth == 0 && Root.getOpcode() == Shuffle)
return SDValue(); // Nothing to do!
- Res = CanonicalizeShuffleInput(ShuffleSrcVT, NewV1);
+ Res = CanonicalizeShuffleInput(ShuffleSrcVT, NewV1);
Res = DAG.getNode(Shuffle, DL, ShuffleVT, Res);
return DAG.getBitcast(RootVT, Res);
}
@@ -35573,7 +35573,7 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
(NumRootElts == ShuffleVT.getVectorNumElements()))) {
if (Depth == 0 && Root.getOpcode() == Shuffle)
return SDValue(); // Nothing to do!
- Res = CanonicalizeShuffleInput(ShuffleVT, V1);
+ Res = CanonicalizeShuffleInput(ShuffleVT, V1);
Res = DAG.getNode(Shuffle, DL, ShuffleVT, Res,
DAG.getTargetConstant(PermuteImm, DL, MVT::i8));
return DAG.getBitcast(RootVT, Res);
@@ -35584,32 +35584,32 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
// from a scalar.
// TODO: Handle other insertions here as well?
if (!UnaryShuffle && AllowFloatDomain && RootSizeInBits == 128 &&
- Subtarget.hasSSE41() &&
- !isTargetShuffleEquivalent(MaskVT, Mask, {4, 1, 2, 3})) {
- if (MaskEltSizeInBits == 32) {
- SDValue SrcV1 = V1, SrcV2 = V2;
- if (matchShuffleAsInsertPS(SrcV1, SrcV2, PermuteImm, Zeroable, Mask,
- DAG) &&
- SrcV2.getOpcode() == ISD::SCALAR_TO_VECTOR) {
- if (Depth == 0 && Root.getOpcode() == X86ISD::INSERTPS)
- return SDValue(); // Nothing to do!
- Res = DAG.getNode(X86ISD::INSERTPS, DL, MVT::v4f32,
- CanonicalizeShuffleInput(MVT::v4f32, SrcV1),
- CanonicalizeShuffleInput(MVT::v4f32, SrcV2),
- DAG.getTargetConstant(PermuteImm, DL, MVT::i8));
- return DAG.getBitcast(RootVT, Res);
- }
- }
- if (MaskEltSizeInBits == 64 &&
- isTargetShuffleEquivalent(MaskVT, Mask, {0, 2}) &&
- V2.getOpcode() == ISD::SCALAR_TO_VECTOR &&
- V2.getScalarValueSizeInBits() <= 32) {
+ Subtarget.hasSSE41() &&
+ !isTargetShuffleEquivalent(MaskVT, Mask, {4, 1, 2, 3})) {
+ if (MaskEltSizeInBits == 32) {
+ SDValue SrcV1 = V1, SrcV2 = V2;
+ if (matchShuffleAsInsertPS(SrcV1, SrcV2, PermuteImm, Zeroable, Mask,
+ DAG) &&
+ SrcV2.getOpcode() == ISD::SCALAR_TO_VECTOR) {
+ if (Depth == 0 && Root.getOpcode() == X86ISD::INSERTPS)
+ return SDValue(); // Nothing to do!
+ Res = DAG.getNode(X86ISD::INSERTPS, DL, MVT::v4f32,
+ CanonicalizeShuffleInput(MVT::v4f32, SrcV1),
+ CanonicalizeShuffleInput(MVT::v4f32, SrcV2),
+ DAG.getTargetConstant(PermuteImm, DL, MVT::i8));
+ return DAG.getBitcast(RootVT, Res);
+ }
+ }
+ if (MaskEltSizeInBits == 64 &&
+ isTargetShuffleEquivalent(MaskVT, Mask, {0, 2}) &&
+ V2.getOpcode() == ISD::SCALAR_TO_VECTOR &&
+ V2.getScalarValueSizeInBits() <= 32) {
if (Depth == 0 && Root.getOpcode() == X86ISD::INSERTPS)
return SDValue(); // Nothing to do!
- PermuteImm = (/*DstIdx*/2 << 4) | (/*SrcIdx*/0 << 0);
+ PermuteImm = (/*DstIdx*/2 << 4) | (/*SrcIdx*/0 << 0);
Res = DAG.getNode(X86ISD::INSERTPS, DL, MVT::v4f32,
- CanonicalizeShuffleInput(MVT::v4f32, V1),
- CanonicalizeShuffleInput(MVT::v4f32, V2),
+ CanonicalizeShuffleInput(MVT::v4f32, V1),
+ CanonicalizeShuffleInput(MVT::v4f32, V2),
DAG.getTargetConstant(PermuteImm, DL, MVT::i8));
return DAG.getBitcast(RootVT, Res);
}
@@ -35623,8 +35623,8 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
(!IsMaskedShuffle || (NumRootElts == ShuffleVT.getVectorNumElements()))) {
if (Depth == 0 && Root.getOpcode() == Shuffle)
return SDValue(); // Nothing to do!
- NewV1 = CanonicalizeShuffleInput(ShuffleSrcVT, NewV1);
- NewV2 = CanonicalizeShuffleInput(ShuffleSrcVT, NewV2);
+ NewV1 = CanonicalizeShuffleInput(ShuffleSrcVT, NewV1);
+ NewV2 = CanonicalizeShuffleInput(ShuffleSrcVT, NewV2);
Res = DAG.getNode(Shuffle, DL, ShuffleVT, NewV1, NewV2);
return DAG.getBitcast(RootVT, Res);
}
@@ -35637,8 +35637,8 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
(!IsMaskedShuffle || (NumRootElts == ShuffleVT.getVectorNumElements()))) {
if (Depth == 0 && Root.getOpcode() == Shuffle)
return SDValue(); // Nothing to do!
- NewV1 = CanonicalizeShuffleInput(ShuffleVT, NewV1);
- NewV2 = CanonicalizeShuffleInput(ShuffleVT, NewV2);
+ NewV1 = CanonicalizeShuffleInput(ShuffleVT, NewV1);
+ NewV2 = CanonicalizeShuffleInput(ShuffleVT, NewV2);
Res = DAG.getNode(Shuffle, DL, ShuffleVT, NewV1, NewV2,
DAG.getTargetConstant(PermuteImm, DL, MVT::i8));
return DAG.getBitcast(RootVT, Res);
@@ -35655,7 +35655,7 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
Zeroable)) {
if (Depth == 0 && Root.getOpcode() == X86ISD::EXTRQI)
return SDValue(); // Nothing to do!
- V1 = CanonicalizeShuffleInput(IntMaskVT, V1);
+ V1 = CanonicalizeShuffleInput(IntMaskVT, V1);
Res = DAG.getNode(X86ISD::EXTRQI, DL, IntMaskVT, V1,
DAG.getTargetConstant(BitLen, DL, MVT::i8),
DAG.getTargetConstant(BitIdx, DL, MVT::i8));
@@ -35665,8 +35665,8 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
if (matchShuffleAsINSERTQ(IntMaskVT, V1, V2, Mask, BitLen, BitIdx)) {
if (Depth == 0 && Root.getOpcode() == X86ISD::INSERTQI)
return SDValue(); // Nothing to do!
- V1 = CanonicalizeShuffleInput(IntMaskVT, V1);
- V2 = CanonicalizeShuffleInput(IntMaskVT, V2);
+ V1 = CanonicalizeShuffleInput(IntMaskVT, V1);
+ V2 = CanonicalizeShuffleInput(IntMaskVT, V2);
Res = DAG.getNode(X86ISD::INSERTQI, DL, IntMaskVT, V1, V2,
DAG.getTargetConstant(BitLen, DL, MVT::i8),
DAG.getTargetConstant(BitIdx, DL, MVT::i8));
@@ -35685,7 +35685,7 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
IsTRUNCATE ? (unsigned)ISD::TRUNCATE : (unsigned)X86ISD::VTRUNC;
if (Depth == 0 && Root.getOpcode() == Opc)
return SDValue(); // Nothing to do!
- V1 = CanonicalizeShuffleInput(ShuffleSrcVT, V1);
+ V1 = CanonicalizeShuffleInput(ShuffleSrcVT, V1);
Res = DAG.getNode(Opc, DL, ShuffleVT, V1);
if (ShuffleVT.getSizeInBits() < RootSizeInBits)
Res = widenSubVector(Res, true, Subtarget, DAG, DL, RootSizeInBits);
@@ -35702,8 +35702,8 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
return SDValue(); // Nothing to do!
ShuffleSrcVT = MVT::getIntegerVT(MaskEltSizeInBits * 2);
ShuffleSrcVT = MVT::getVectorVT(ShuffleSrcVT, NumMaskElts / 2);
- V1 = CanonicalizeShuffleInput(ShuffleSrcVT, V1);
- V2 = CanonicalizeShuffleInput(ShuffleSrcVT, V2);
+ V1 = CanonicalizeShuffleInput(ShuffleSrcVT, V1);
+ V2 = CanonicalizeShuffleInput(ShuffleSrcVT, V2);
ShuffleSrcVT = MVT::getIntegerVT(MaskEltSizeInBits * 2);
ShuffleSrcVT = MVT::getVectorVT(ShuffleSrcVT, NumMaskElts);
Res = DAG.getNode(ISD::CONCAT_VECTORS, DL, ShuffleSrcVT, V1, V2);
@@ -35720,56 +35720,56 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
// Depth threshold above which we can efficiently use variable mask shuffles.
int VariableShuffleDepth = Subtarget.hasFastVariableShuffle() ? 1 : 2;
AllowVariableMask &= (Depth >= VariableShuffleDepth) || HasVariableMask;
- // VPERMI2W/VPERMI2B are 3 uops on Skylake and Icelake so we require a
- // higher depth before combining them.
- bool AllowBWIVPERMV3 = (Depth >= 2 || HasVariableMask);
+ // VPERMI2W/VPERMI2B are 3 uops on Skylake and Icelake so we require a
+ // higher depth before combining them.
+ bool AllowBWIVPERMV3 = (Depth >= 2 || HasVariableMask);
bool MaskContainsZeros = isAnyZero(Mask);
if (is128BitLaneCrossingShuffleMask(MaskVT, Mask)) {
// If we have a single input lane-crossing shuffle then lower to VPERMV.
- if (UnaryShuffle && AllowVariableMask && !MaskContainsZeros) {
- if (Subtarget.hasAVX2() &&
- (MaskVT == MVT::v8f32 || MaskVT == MVT::v8i32)) {
- SDValue VPermMask = getConstVector(Mask, IntMaskVT, DAG, DL, true);
- Res = CanonicalizeShuffleInput(MaskVT, V1);
- Res = DAG.getNode(X86ISD::VPERMV, DL, MaskVT, VPermMask, Res);
- return DAG.getBitcast(RootVT, Res);
- }
- // AVX512 variants (non-VLX will pad to 512-bit shuffles).
- if ((Subtarget.hasAVX512() &&
- (MaskVT == MVT::v8f64 || MaskVT == MVT::v8i64 ||
- MaskVT == MVT::v16f32 || MaskVT == MVT::v16i32)) ||
- (Subtarget.hasBWI() &&
- (MaskVT == MVT::v16i16 || MaskVT == MVT::v32i16)) ||
- (Subtarget.hasVBMI() &&
- (MaskVT == MVT::v32i8 || MaskVT == MVT::v64i8))) {
- V1 = CanonicalizeShuffleInput(MaskVT, V1);
- V2 = DAG.getUNDEF(MaskVT);
- Res = lowerShuffleWithPERMV(DL, MaskVT, Mask, V1, V2, Subtarget, DAG);
- return DAG.getBitcast(RootVT, Res);
- }
+ if (UnaryShuffle && AllowVariableMask && !MaskContainsZeros) {
+ if (Subtarget.hasAVX2() &&
+ (MaskVT == MVT::v8f32 || MaskVT == MVT::v8i32)) {
+ SDValue VPermMask = getConstVector(Mask, IntMaskVT, DAG, DL, true);
+ Res = CanonicalizeShuffleInput(MaskVT, V1);
+ Res = DAG.getNode(X86ISD::VPERMV, DL, MaskVT, VPermMask, Res);
+ return DAG.getBitcast(RootVT, Res);
+ }
+ // AVX512 variants (non-VLX will pad to 512-bit shuffles).
+ if ((Subtarget.hasAVX512() &&
+ (MaskVT == MVT::v8f64 || MaskVT == MVT::v8i64 ||
+ MaskVT == MVT::v16f32 || MaskVT == MVT::v16i32)) ||
+ (Subtarget.hasBWI() &&
+ (MaskVT == MVT::v16i16 || MaskVT == MVT::v32i16)) ||
+ (Subtarget.hasVBMI() &&
+ (MaskVT == MVT::v32i8 || MaskVT == MVT::v64i8))) {
+ V1 = CanonicalizeShuffleInput(MaskVT, V1);
+ V2 = DAG.getUNDEF(MaskVT);
+ Res = lowerShuffleWithPERMV(DL, MaskVT, Mask, V1, V2, Subtarget, DAG);
+ return DAG.getBitcast(RootVT, Res);
+ }
}
// Lower a unary+zero lane-crossing shuffle as VPERMV3 with a zero
- // vector as the second source (non-VLX will pad to 512-bit shuffles).
+ // vector as the second source (non-VLX will pad to 512-bit shuffles).
if (UnaryShuffle && AllowVariableMask &&
((Subtarget.hasAVX512() &&
(MaskVT == MVT::v8f64 || MaskVT == MVT::v8i64 ||
- MaskVT == MVT::v4f64 || MaskVT == MVT::v4i64 ||
- MaskVT == MVT::v8f32 || MaskVT == MVT::v8i32 ||
+ MaskVT == MVT::v4f64 || MaskVT == MVT::v4i64 ||
+ MaskVT == MVT::v8f32 || MaskVT == MVT::v8i32 ||
MaskVT == MVT::v16f32 || MaskVT == MVT::v16i32)) ||
- (Subtarget.hasBWI() && AllowBWIVPERMV3 &&
- (MaskVT == MVT::v16i16 || MaskVT == MVT::v32i16)) ||
- (Subtarget.hasVBMI() && AllowBWIVPERMV3 &&
- (MaskVT == MVT::v32i8 || MaskVT == MVT::v64i8)))) {
+ (Subtarget.hasBWI() && AllowBWIVPERMV3 &&
+ (MaskVT == MVT::v16i16 || MaskVT == MVT::v32i16)) ||
+ (Subtarget.hasVBMI() && AllowBWIVPERMV3 &&
+ (MaskVT == MVT::v32i8 || MaskVT == MVT::v64i8)))) {
// Adjust shuffle mask - replace SM_SentinelZero with second source index.
for (unsigned i = 0; i != NumMaskElts; ++i)
if (Mask[i] == SM_SentinelZero)
Mask[i] = NumMaskElts + i;
- V1 = CanonicalizeShuffleInput(MaskVT, V1);
- V2 = getZeroVector(MaskVT, Subtarget, DAG, DL);
- Res = lowerShuffleWithPERMV(DL, MaskVT, Mask, V1, V2, Subtarget, DAG);
+ V1 = CanonicalizeShuffleInput(MaskVT, V1);
+ V2 = getZeroVector(MaskVT, Subtarget, DAG, DL);
+ Res = lowerShuffleWithPERMV(DL, MaskVT, Mask, V1, V2, Subtarget, DAG);
return DAG.getBitcast(RootVT, Res);
}
@@ -35780,21 +35780,21 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
DAG, Subtarget))
return WideShuffle;
- // If we have a dual input lane-crossing shuffle then lower to VPERMV3,
- // (non-VLX will pad to 512-bit shuffles).
+ // If we have a dual input lane-crossing shuffle then lower to VPERMV3,
+ // (non-VLX will pad to 512-bit shuffles).
if (AllowVariableMask && !MaskContainsZeros &&
((Subtarget.hasAVX512() &&
(MaskVT == MVT::v8f64 || MaskVT == MVT::v8i64 ||
- MaskVT == MVT::v4f64 || MaskVT == MVT::v4i64 ||
- MaskVT == MVT::v16f32 || MaskVT == MVT::v16i32 ||
+ MaskVT == MVT::v4f64 || MaskVT == MVT::v4i64 ||
+ MaskVT == MVT::v16f32 || MaskVT == MVT::v16i32 ||
MaskVT == MVT::v8f32 || MaskVT == MVT::v8i32)) ||
- (Subtarget.hasBWI() && AllowBWIVPERMV3 &&
- (MaskVT == MVT::v16i16 || MaskVT == MVT::v32i16)) ||
- (Subtarget.hasVBMI() && AllowBWIVPERMV3 &&
- (MaskVT == MVT::v32i8 || MaskVT == MVT::v64i8)))) {
- V1 = CanonicalizeShuffleInput(MaskVT, V1);
- V2 = CanonicalizeShuffleInput(MaskVT, V2);
- Res = lowerShuffleWithPERMV(DL, MaskVT, Mask, V1, V2, Subtarget, DAG);
+ (Subtarget.hasBWI() && AllowBWIVPERMV3 &&
+ (MaskVT == MVT::v16i16 || MaskVT == MVT::v32i16)) ||
+ (Subtarget.hasVBMI() && AllowBWIVPERMV3 &&
+ (MaskVT == MVT::v32i8 || MaskVT == MVT::v64i8)))) {
+ V1 = CanonicalizeShuffleInput(MaskVT, V1);
+ V2 = CanonicalizeShuffleInput(MaskVT, V2);
+ Res = lowerShuffleWithPERMV(DL, MaskVT, Mask, V1, V2, Subtarget, DAG);
return DAG.getBitcast(RootVT, Res);
}
return SDValue();
@@ -35820,7 +35820,7 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
EltBits[i] = AllOnes;
}
SDValue BitMask = getConstVector(EltBits, UndefElts, MaskVT, DAG, DL);
- Res = CanonicalizeShuffleInput(MaskVT, V1);
+ Res = CanonicalizeShuffleInput(MaskVT, V1);
unsigned AndOpcode =
MaskVT.isFloatingPoint() ? unsigned(X86ISD::FAND) : unsigned(ISD::AND);
Res = DAG.getNode(AndOpcode, DL, MaskVT, Res, BitMask);
@@ -35840,7 +35840,7 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
VPermIdx.push_back(Idx);
}
SDValue VPermMask = DAG.getBuildVector(IntMaskVT, DL, VPermIdx);
- Res = CanonicalizeShuffleInput(MaskVT, V1);
+ Res = CanonicalizeShuffleInput(MaskVT, V1);
Res = DAG.getNode(X86ISD::VPERMILPV, DL, MaskVT, Res, VPermMask);
return DAG.getBitcast(RootVT, Res);
}
@@ -35872,8 +35872,8 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
Index = (MaskVT.getScalarSizeInBits() == 64 ? Index << 1 : Index);
VPerm2Idx.push_back(Index);
}
- V1 = CanonicalizeShuffleInput(MaskVT, V1);
- V2 = CanonicalizeShuffleInput(MaskVT, V2);
+ V1 = CanonicalizeShuffleInput(MaskVT, V1);
+ V2 = CanonicalizeShuffleInput(MaskVT, V2);
SDValue VPerm2MaskOp = getConstVector(VPerm2Idx, IntMaskVT, DAG, DL, true);
Res = DAG.getNode(X86ISD::VPERMIL2, DL, MaskVT, V1, V2, VPerm2MaskOp,
DAG.getTargetConstant(M2ZImm, DL, MVT::i8));
@@ -35907,7 +35907,7 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
PSHUFBMask.push_back(DAG.getConstant(M, DL, MVT::i8));
}
MVT ByteVT = MVT::getVectorVT(MVT::i8, NumBytes);
- Res = CanonicalizeShuffleInput(ByteVT, V1);
+ Res = CanonicalizeShuffleInput(ByteVT, V1);
SDValue PSHUFBMaskOp = DAG.getBuildVector(ByteVT, DL, PSHUFBMask);
Res = DAG.getNode(X86ISD::PSHUFB, DL, ByteVT, Res, PSHUFBMaskOp);
return DAG.getBitcast(RootVT, Res);
@@ -35937,8 +35937,8 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
VPPERMMask.push_back(DAG.getConstant(M, DL, MVT::i8));
}
MVT ByteVT = MVT::v16i8;
- V1 = CanonicalizeShuffleInput(ByteVT, V1);
- V2 = CanonicalizeShuffleInput(ByteVT, V2);
+ V1 = CanonicalizeShuffleInput(ByteVT, V1);
+ V2 = CanonicalizeShuffleInput(ByteVT, V2);
SDValue VPPERMMaskOp = DAG.getBuildVector(ByteVT, DL, VPPERMMask);
Res = DAG.getNode(X86ISD::VPPERM, DL, ByteVT, V1, V2, VPPERMMaskOp);
return DAG.getBitcast(RootVT, Res);
@@ -35951,22 +35951,22 @@ static SDValue combineX86ShuffleChain(ArrayRef<SDValue> Inputs, SDValue Root,
DAG, Subtarget))
return WideShuffle;
- // If we have a dual input shuffle then lower to VPERMV3,
- // (non-VLX will pad to 512-bit shuffles)
+ // If we have a dual input shuffle then lower to VPERMV3,
+ // (non-VLX will pad to 512-bit shuffles)
if (!UnaryShuffle && AllowVariableMask && !MaskContainsZeros &&
((Subtarget.hasAVX512() &&
- (MaskVT == MVT::v2f64 || MaskVT == MVT::v4f64 || MaskVT == MVT::v8f64 ||
- MaskVT == MVT::v2i64 || MaskVT == MVT::v4i64 || MaskVT == MVT::v8i64 ||
- MaskVT == MVT::v4f32 || MaskVT == MVT::v4i32 || MaskVT == MVT::v8f32 ||
- MaskVT == MVT::v8i32 || MaskVT == MVT::v16f32 ||
- MaskVT == MVT::v16i32)) ||
- (Subtarget.hasBWI() && AllowBWIVPERMV3 &&
- (MaskVT == MVT::v8i16 || MaskVT == MVT::v16i16 || MaskVT == MVT::v32i16)) ||
- (Subtarget.hasVBMI() && AllowBWIVPERMV3 &&
- (MaskVT == MVT::v16i8 || MaskVT == MVT::v32i8 || MaskVT == MVT::v64i8)))) {
- V1 = CanonicalizeShuffleInput(MaskVT, V1);
- V2 = CanonicalizeShuffleInput(MaskVT, V2);
- Res = lowerShuffleWithPERMV(DL, MaskVT, Mask, V1, V2, Subtarget, DAG);
+ (MaskVT == MVT::v2f64 || MaskVT == MVT::v4f64 || MaskVT == MVT::v8f64 ||
+ MaskVT == MVT::v2i64 || MaskVT == MVT::v4i64 || MaskVT == MVT::v8i64 ||
+ MaskVT == MVT::v4f32 || MaskVT == MVT::v4i32 || MaskVT == MVT::v8f32 ||
+ MaskVT == MVT::v8i32 || MaskVT == MVT::v16f32 ||
+ MaskVT == MVT::v16i32)) ||
+ (Subtarget.hasBWI() && AllowBWIVPERMV3 &&
+ (MaskVT == MVT::v8i16 || MaskVT == MVT::v16i16 || MaskVT == MVT::v32i16)) ||
+ (Subtarget.hasVBMI() && AllowBWIVPERMV3 &&
+ (MaskVT == MVT::v16i8 || MaskVT == MVT::v32i8 || MaskVT == MVT::v64i8)))) {
+ V1 = CanonicalizeShuffleInput(MaskVT, V1);
+ V2 = CanonicalizeShuffleInput(MaskVT, V2);
+ Res = lowerShuffleWithPERMV(DL, MaskVT, Mask, V1, V2, Subtarget, DAG);
return DAG.getBitcast(RootVT, Res);
}
@@ -35991,16 +35991,16 @@ static SDValue combineX86ShuffleChainWithExtract(
if (NumInputs == 0)
return SDValue();
- EVT RootVT = Root.getValueType();
- unsigned RootSizeInBits = RootVT.getSizeInBits();
- assert((RootSizeInBits % NumMaskElts) == 0 && "Unexpected root shuffle mask");
-
+ EVT RootVT = Root.getValueType();
+ unsigned RootSizeInBits = RootVT.getSizeInBits();
+ assert((RootSizeInBits % NumMaskElts) == 0 && "Unexpected root shuffle mask");
+
SmallVector<SDValue, 4> WideInputs(Inputs.begin(), Inputs.end());
SmallVector<unsigned, 4> Offsets(NumInputs, 0);
// Peek through subvectors.
// TODO: Support inter-mixed EXTRACT_SUBVECTORs + BITCASTs?
- unsigned WideSizeInBits = RootSizeInBits;
+ unsigned WideSizeInBits = RootSizeInBits;
for (unsigned i = 0; i != NumInputs; ++i) {
SDValue &Src = WideInputs[i];
unsigned &Offset = Offsets[i];
@@ -36082,149 +36082,149 @@ static SDValue combineX86ShuffleChainWithExtract(
return SDValue();
}
-// Canonicalize the combined shuffle mask chain with horizontal ops.
-// NOTE: This may update the Ops and Mask.
-static SDValue canonicalizeShuffleMaskWithHorizOp(
- MutableArrayRef<SDValue> Ops, MutableArrayRef<int> Mask,
- unsigned RootSizeInBits, const SDLoc &DL, SelectionDAG &DAG,
- const X86Subtarget &Subtarget) {
- if (Mask.empty() || Ops.empty())
- return SDValue();
-
- SmallVector<SDValue> BC;
- for (SDValue Op : Ops)
- BC.push_back(peekThroughBitcasts(Op));
-
- // All ops must be the same horizop + type.
- SDValue BC0 = BC[0];
- EVT VT0 = BC0.getValueType();
- unsigned Opcode0 = BC0.getOpcode();
- if (VT0.getSizeInBits() != RootSizeInBits || llvm::any_of(BC, [&](SDValue V) {
- return V.getOpcode() != Opcode0 || V.getValueType() != VT0;
- }))
- return SDValue();
-
- bool isHoriz = (Opcode0 == X86ISD::FHADD || Opcode0 == X86ISD::HADD ||
- Opcode0 == X86ISD::FHSUB || Opcode0 == X86ISD::HSUB);
- bool isPack = (Opcode0 == X86ISD::PACKSS || Opcode0 == X86ISD::PACKUS);
- if (!isHoriz && !isPack)
- return SDValue();
-
- int NumElts = VT0.getVectorNumElements();
- int NumLanes = VT0.getSizeInBits() / 128;
- int NumEltsPerLane = NumElts / NumLanes;
- int NumHalfEltsPerLane = NumEltsPerLane / 2;
-
- // See if we can remove the shuffle by resorting the HOP chain so that
- // the HOP args are pre-shuffled.
- // TODO: Generalize to any sized/depth chain.
- // TODO: Add support for PACKSS/PACKUS.
- if (isHoriz && NumEltsPerLane == 4 && VT0.is128BitVector() &&
- shouldUseHorizontalOp(Ops.size() == 1, DAG, Subtarget)) {
- SmallVector<int> ScaledMask;
- if (scaleShuffleElements(Mask, 4, ScaledMask)) {
- // Attempt to find a HOP(HOP(X,Y),HOP(Z,W)) source operand.
- auto GetHOpSrc = [&](int M) {
- if (M == SM_SentinelUndef)
- return DAG.getUNDEF(VT0);
- if (M == SM_SentinelZero)
- return getZeroVector(VT0.getSimpleVT(), Subtarget, DAG, DL);
- SDValue Src0 = BC[M / NumElts];
- SDValue Src1 = Src0.getOperand((M % 4) >= 2);
- if (Src1.getOpcode() == Opcode0 && Src0->isOnlyUserOf(Src1.getNode()))
- return Src1.getOperand(M % 2);
- return SDValue();
- };
- SDValue M0 = GetHOpSrc(ScaledMask[0]);
- SDValue M1 = GetHOpSrc(ScaledMask[1]);
- SDValue M2 = GetHOpSrc(ScaledMask[2]);
- SDValue M3 = GetHOpSrc(ScaledMask[3]);
- if (M0 && M1 && M2 && M3) {
- SDValue LHS = DAG.getNode(Opcode0, DL, VT0, M0, M1);
- SDValue RHS = DAG.getNode(Opcode0, DL, VT0, M2, M3);
- return DAG.getNode(Opcode0, DL, VT0, LHS, RHS);
- }
- }
- }
-
- if (2 < Ops.size())
- return SDValue();
-
- SDValue BC1 = BC[BC.size() - 1];
- if (Mask.size() == VT0.getVectorNumElements()) {
- // Canonicalize binary shuffles of horizontal ops that use the
- // same sources to an unary shuffle.
- // TODO: Try to perform this fold even if the shuffle remains.
- if (Ops.size() == 2) {
- auto ContainsOps = [](SDValue HOp, SDValue Op) {
- return Op == HOp.getOperand(0) || Op == HOp.getOperand(1);
- };
- // Commute if all BC0's ops are contained in BC1.
- if (ContainsOps(BC1, BC0.getOperand(0)) &&
- ContainsOps(BC1, BC0.getOperand(1))) {
- ShuffleVectorSDNode::commuteMask(Mask);
- std::swap(Ops[0], Ops[1]);
- std::swap(BC0, BC1);
- }
-
- // If BC1 can be represented by BC0, then convert to unary shuffle.
- if (ContainsOps(BC0, BC1.getOperand(0)) &&
- ContainsOps(BC0, BC1.getOperand(1))) {
- for (int &M : Mask) {
- if (M < NumElts) // BC0 element or UNDEF/Zero sentinel.
- continue;
- int SubLane = ((M % NumEltsPerLane) >= NumHalfEltsPerLane) ? 1 : 0;
- M -= NumElts + (SubLane * NumHalfEltsPerLane);
- if (BC1.getOperand(SubLane) != BC0.getOperand(0))
- M += NumHalfEltsPerLane;
- }
- }
- }
-
- // Canonicalize unary horizontal ops to only refer to lower halves.
- for (int i = 0; i != NumElts; ++i) {
- int &M = Mask[i];
- if (isUndefOrZero(M))
- continue;
- if (M < NumElts && BC0.getOperand(0) == BC0.getOperand(1) &&
- (M % NumEltsPerLane) >= NumHalfEltsPerLane)
- M -= NumHalfEltsPerLane;
- if (NumElts <= M && BC1.getOperand(0) == BC1.getOperand(1) &&
- (M % NumEltsPerLane) >= NumHalfEltsPerLane)
- M -= NumHalfEltsPerLane;
- }
- }
-
- // Combine binary shuffle of 2 similar 'Horizontal' instructions into a
- // single instruction. Attempt to match a v2X64 repeating shuffle pattern that
- // represents the LHS/RHS inputs for the lower/upper halves.
- unsigned EltSizeInBits = RootSizeInBits / Mask.size();
- SmallVector<int, 16> TargetMask128, WideMask128;
- if (isRepeatedTargetShuffleMask(128, EltSizeInBits, Mask, TargetMask128) &&
- scaleShuffleElements(TargetMask128, 2, WideMask128)) {
- assert(isUndefOrZeroOrInRange(WideMask128, 0, 4) && "Illegal shuffle");
- bool SingleOp = (Ops.size() == 1);
- if (!isHoriz || shouldUseHorizontalOp(SingleOp, DAG, Subtarget)) {
- SDValue Lo = isInRange(WideMask128[0], 0, 2) ? BC0 : BC1;
- SDValue Hi = isInRange(WideMask128[1], 0, 2) ? BC0 : BC1;
- Lo = Lo.getOperand(WideMask128[0] & 1);
- Hi = Hi.getOperand(WideMask128[1] & 1);
- if (SingleOp) {
- MVT SrcVT = BC0.getOperand(0).getSimpleValueType();
- SDValue Undef = DAG.getUNDEF(SrcVT);
- SDValue Zero = getZeroVector(SrcVT, Subtarget, DAG, DL);
- Lo = (WideMask128[0] == SM_SentinelZero ? Zero : Lo);
- Hi = (WideMask128[1] == SM_SentinelZero ? Zero : Hi);
- Lo = (WideMask128[0] == SM_SentinelUndef ? Undef : Lo);
- Hi = (WideMask128[1] == SM_SentinelUndef ? Undef : Hi);
- }
- return DAG.getNode(Opcode0, DL, VT0, Lo, Hi);
- }
- }
-
- return SDValue();
-}
-
+// Canonicalize the combined shuffle mask chain with horizontal ops.
+// NOTE: This may update the Ops and Mask.
+static SDValue canonicalizeShuffleMaskWithHorizOp(
+ MutableArrayRef<SDValue> Ops, MutableArrayRef<int> Mask,
+ unsigned RootSizeInBits, const SDLoc &DL, SelectionDAG &DAG,
+ const X86Subtarget &Subtarget) {
+ if (Mask.empty() || Ops.empty())
+ return SDValue();
+
+ SmallVector<SDValue> BC;
+ for (SDValue Op : Ops)
+ BC.push_back(peekThroughBitcasts(Op));
+
+ // All ops must be the same horizop + type.
+ SDValue BC0 = BC[0];
+ EVT VT0 = BC0.getValueType();
+ unsigned Opcode0 = BC0.getOpcode();
+ if (VT0.getSizeInBits() != RootSizeInBits || llvm::any_of(BC, [&](SDValue V) {
+ return V.getOpcode() != Opcode0 || V.getValueType() != VT0;
+ }))
+ return SDValue();
+
+ bool isHoriz = (Opcode0 == X86ISD::FHADD || Opcode0 == X86ISD::HADD ||
+ Opcode0 == X86ISD::FHSUB || Opcode0 == X86ISD::HSUB);
+ bool isPack = (Opcode0 == X86ISD::PACKSS || Opcode0 == X86ISD::PACKUS);
+ if (!isHoriz && !isPack)
+ return SDValue();
+
+ int NumElts = VT0.getVectorNumElements();
+ int NumLanes = VT0.getSizeInBits() / 128;
+ int NumEltsPerLane = NumElts / NumLanes;
+ int NumHalfEltsPerLane = NumEltsPerLane / 2;
+
+ // See if we can remove the shuffle by resorting the HOP chain so that
+ // the HOP args are pre-shuffled.
+ // TODO: Generalize to any sized/depth chain.
+ // TODO: Add support for PACKSS/PACKUS.
+ if (isHoriz && NumEltsPerLane == 4 && VT0.is128BitVector() &&
+ shouldUseHorizontalOp(Ops.size() == 1, DAG, Subtarget)) {
+ SmallVector<int> ScaledMask;
+ if (scaleShuffleElements(Mask, 4, ScaledMask)) {
+ // Attempt to find a HOP(HOP(X,Y),HOP(Z,W)) source operand.
+ auto GetHOpSrc = [&](int M) {
+ if (M == SM_SentinelUndef)
+ return DAG.getUNDEF(VT0);
+ if (M == SM_SentinelZero)
+ return getZeroVector(VT0.getSimpleVT(), Subtarget, DAG, DL);
+ SDValue Src0 = BC[M / NumElts];
+ SDValue Src1 = Src0.getOperand((M % 4) >= 2);
+ if (Src1.getOpcode() == Opcode0 && Src0->isOnlyUserOf(Src1.getNode()))
+ return Src1.getOperand(M % 2);
+ return SDValue();
+ };
+ SDValue M0 = GetHOpSrc(ScaledMask[0]);
+ SDValue M1 = GetHOpSrc(ScaledMask[1]);
+ SDValue M2 = GetHOpSrc(ScaledMask[2]);
+ SDValue M3 = GetHOpSrc(ScaledMask[3]);
+ if (M0 && M1 && M2 && M3) {
+ SDValue LHS = DAG.getNode(Opcode0, DL, VT0, M0, M1);
+ SDValue RHS = DAG.getNode(Opcode0, DL, VT0, M2, M3);
+ return DAG.getNode(Opcode0, DL, VT0, LHS, RHS);
+ }
+ }
+ }
+
+ if (2 < Ops.size())
+ return SDValue();
+
+ SDValue BC1 = BC[BC.size() - 1];
+ if (Mask.size() == VT0.getVectorNumElements()) {
+ // Canonicalize binary shuffles of horizontal ops that use the
+ // same sources to an unary shuffle.
+ // TODO: Try to perform this fold even if the shuffle remains.
+ if (Ops.size() == 2) {
+ auto ContainsOps = [](SDValue HOp, SDValue Op) {
+ return Op == HOp.getOperand(0) || Op == HOp.getOperand(1);
+ };
+ // Commute if all BC0's ops are contained in BC1.
+ if (ContainsOps(BC1, BC0.getOperand(0)) &&
+ ContainsOps(BC1, BC0.getOperand(1))) {
+ ShuffleVectorSDNode::commuteMask(Mask);
+ std::swap(Ops[0], Ops[1]);
+ std::swap(BC0, BC1);
+ }
+
+ // If BC1 can be represented by BC0, then convert to unary shuffle.
+ if (ContainsOps(BC0, BC1.getOperand(0)) &&
+ ContainsOps(BC0, BC1.getOperand(1))) {
+ for (int &M : Mask) {
+ if (M < NumElts) // BC0 element or UNDEF/Zero sentinel.
+ continue;
+ int SubLane = ((M % NumEltsPerLane) >= NumHalfEltsPerLane) ? 1 : 0;
+ M -= NumElts + (SubLane * NumHalfEltsPerLane);
+ if (BC1.getOperand(SubLane) != BC0.getOperand(0))
+ M += NumHalfEltsPerLane;
+ }
+ }
+ }
+
+ // Canonicalize unary horizontal ops to only refer to lower halves.
+ for (int i = 0; i != NumElts; ++i) {
+ int &M = Mask[i];
+ if (isUndefOrZero(M))
+ continue;
+ if (M < NumElts && BC0.getOperand(0) == BC0.getOperand(1) &&
+ (M % NumEltsPerLane) >= NumHalfEltsPerLane)
+ M -= NumHalfEltsPerLane;
+ if (NumElts <= M && BC1.getOperand(0) == BC1.getOperand(1) &&
+ (M % NumEltsPerLane) >= NumHalfEltsPerLane)
+ M -= NumHalfEltsPerLane;
+ }
+ }
+
+ // Combine binary shuffle of 2 similar 'Horizontal' instructions into a
+ // single instruction. Attempt to match a v2X64 repeating shuffle pattern that
+ // represents the LHS/RHS inputs for the lower/upper halves.
+ unsigned EltSizeInBits = RootSizeInBits / Mask.size();
+ SmallVector<int, 16> TargetMask128, WideMask128;
+ if (isRepeatedTargetShuffleMask(128, EltSizeInBits, Mask, TargetMask128) &&
+ scaleShuffleElements(TargetMask128, 2, WideMask128)) {
+ assert(isUndefOrZeroOrInRange(WideMask128, 0, 4) && "Illegal shuffle");
+ bool SingleOp = (Ops.size() == 1);
+ if (!isHoriz || shouldUseHorizontalOp(SingleOp, DAG, Subtarget)) {
+ SDValue Lo = isInRange(WideMask128[0], 0, 2) ? BC0 : BC1;
+ SDValue Hi = isInRange(WideMask128[1], 0, 2) ? BC0 : BC1;
+ Lo = Lo.getOperand(WideMask128[0] & 1);
+ Hi = Hi.getOperand(WideMask128[1] & 1);
+ if (SingleOp) {
+ MVT SrcVT = BC0.getOperand(0).getSimpleValueType();
+ SDValue Undef = DAG.getUNDEF(SrcVT);
+ SDValue Zero = getZeroVector(SrcVT, Subtarget, DAG, DL);
+ Lo = (WideMask128[0] == SM_SentinelZero ? Zero : Lo);
+ Hi = (WideMask128[1] == SM_SentinelZero ? Zero : Hi);
+ Lo = (WideMask128[0] == SM_SentinelUndef ? Undef : Lo);
+ Hi = (WideMask128[1] == SM_SentinelUndef ? Undef : Hi);
+ }
+ return DAG.getNode(Opcode0, DL, VT0, Lo, Hi);
+ }
+ }
+
+ return SDValue();
+}
+
// Attempt to constant fold all of the constant source ops.
// Returns true if the entire shuffle is folded to a constant.
// TODO: Extend this to merge multiple constant Ops and update the mask.
@@ -36316,14 +36316,14 @@ static SDValue combineX86ShufflesConstants(ArrayRef<SDValue> Ops,
return DAG.getBitcast(VT, CstOp);
}
-namespace llvm {
- namespace X86 {
- enum {
- MaxShuffleCombineDepth = 8
- };
- }
-} // namespace llvm
-
+namespace llvm {
+ namespace X86 {
+ enum {
+ MaxShuffleCombineDepth = 8
+ };
+ }
+} // namespace llvm
+
/// Fully generic combining of x86 shuffle instructions.
///
/// This should be the last combine run over the x86 shuffle instructions. Once
@@ -36356,30 +36356,30 @@ namespace llvm {
static SDValue combineX86ShufflesRecursively(
ArrayRef<SDValue> SrcOps, int SrcOpIndex, SDValue Root,
ArrayRef<int> RootMask, ArrayRef<const SDNode *> SrcNodes, unsigned Depth,
- unsigned MaxDepth, bool HasVariableMask, bool AllowVariableMask,
- SelectionDAG &DAG, const X86Subtarget &Subtarget) {
+ unsigned MaxDepth, bool HasVariableMask, bool AllowVariableMask,
+ SelectionDAG &DAG, const X86Subtarget &Subtarget) {
assert(RootMask.size() > 0 &&
(RootMask.size() > 1 || (RootMask[0] == 0 && SrcOpIndex == 0)) &&
"Illegal shuffle root mask");
- assert(Root.getSimpleValueType().isVector() &&
- "Shuffles operate on vector types!");
- unsigned RootSizeInBits = Root.getSimpleValueType().getSizeInBits();
+ assert(Root.getSimpleValueType().isVector() &&
+ "Shuffles operate on vector types!");
+ unsigned RootSizeInBits = Root.getSimpleValueType().getSizeInBits();
// Bound the depth of our recursive combine because this is ultimately
// quadratic in nature.
- if (Depth >= MaxDepth)
+ if (Depth >= MaxDepth)
return SDValue();
// Directly rip through bitcasts to find the underlying operand.
SDValue Op = SrcOps[SrcOpIndex];
Op = peekThroughOneUseBitcasts(Op);
- EVT VT = Op.getValueType();
- if (!VT.isVector() || !VT.isSimple())
- return SDValue(); // Bail if we hit a non-simple non-vector.
+ EVT VT = Op.getValueType();
+ if (!VT.isVector() || !VT.isSimple())
+ return SDValue(); // Bail if we hit a non-simple non-vector.
- assert((RootSizeInBits % VT.getSizeInBits()) == 0 &&
- "Can only combine shuffles upto size of the root op.");
+ assert((RootSizeInBits % VT.getSizeInBits()) == 0 &&
+ "Can only combine shuffles upto size of the root op.");
// Extract target shuffle mask and resolve sentinels and inputs.
// TODO - determine Op's demanded elts from RootMask.
@@ -36392,32 +36392,32 @@ static SDValue combineX86ShufflesRecursively(
OpZero, DAG, Depth, false))
return SDValue();
- // Shuffle inputs must not be larger than the shuffle result.
- // TODO: Relax this for single input faux shuffles (trunc/extract_subvector).
- if (llvm::any_of(OpInputs, [VT](SDValue OpInput) {
- return OpInput.getValueSizeInBits() > VT.getSizeInBits();
+ // Shuffle inputs must not be larger than the shuffle result.
+ // TODO: Relax this for single input faux shuffles (trunc/extract_subvector).
+ if (llvm::any_of(OpInputs, [VT](SDValue OpInput) {
+ return OpInput.getValueSizeInBits() > VT.getSizeInBits();
}))
return SDValue();
- // If the shuffle result was smaller than the root, we need to adjust the
- // mask indices and pad the mask with undefs.
- if (RootSizeInBits > VT.getSizeInBits()) {
- unsigned NumSubVecs = RootSizeInBits / VT.getSizeInBits();
- unsigned OpMaskSize = OpMask.size();
- if (OpInputs.size() > 1) {
- unsigned PaddedMaskSize = NumSubVecs * OpMaskSize;
- for (int &M : OpMask) {
- if (M < 0)
- continue;
- int EltIdx = M % OpMaskSize;
- int OpIdx = M / OpMaskSize;
- M = (PaddedMaskSize * OpIdx) + EltIdx;
- }
- }
- OpZero = OpZero.zext(NumSubVecs * OpMaskSize);
- OpUndef = OpUndef.zext(NumSubVecs * OpMaskSize);
- OpMask.append((NumSubVecs - 1) * OpMaskSize, SM_SentinelUndef);
- }
+ // If the shuffle result was smaller than the root, we need to adjust the
+ // mask indices and pad the mask with undefs.
+ if (RootSizeInBits > VT.getSizeInBits()) {
+ unsigned NumSubVecs = RootSizeInBits / VT.getSizeInBits();
+ unsigned OpMaskSize = OpMask.size();
+ if (OpInputs.size() > 1) {
+ unsigned PaddedMaskSize = NumSubVecs * OpMaskSize;
+ for (int &M : OpMask) {
+ if (M < 0)
+ continue;
+ int EltIdx = M % OpMaskSize;
+ int OpIdx = M / OpMaskSize;
+ M = (PaddedMaskSize * OpIdx) + EltIdx;
+ }
+ }
+ OpZero = OpZero.zext(NumSubVecs * OpMaskSize);
+ OpUndef = OpUndef.zext(NumSubVecs * OpMaskSize);
+ OpMask.append((NumSubVecs - 1) * OpMaskSize, SM_SentinelUndef);
+ }
SmallVector<int, 64> Mask;
SmallVector<SDValue, 16> Ops;
@@ -36577,7 +36577,7 @@ static SDValue combineX86ShufflesRecursively(
// shuffles to avoid constant pool bloat.
// Don't recurse if we already have more source ops than we can combine in
// the remaining recursion depth.
- if (Ops.size() < (MaxDepth - Depth)) {
+ if (Ops.size() < (MaxDepth - Depth)) {
for (int i = 0, e = Ops.size(); i < e; ++i) {
// For empty roots, we need to resolve zeroable elements before combining
// them with other shuffles.
@@ -36589,7 +36589,7 @@ static SDValue combineX86ShufflesRecursively(
SDNode::areOnlyUsersOf(CombinedNodes, Ops[i].getNode()))
AllowVar = AllowVariableMask;
if (SDValue Res = combineX86ShufflesRecursively(
- Ops, i, Root, ResolvedMask, CombinedNodes, Depth + 1, MaxDepth,
+ Ops, i, Root, ResolvedMask, CombinedNodes, Depth + 1, MaxDepth,
HasVariableMask, AllowVar, DAG, Subtarget))
return Res;
}
@@ -36600,24 +36600,24 @@ static SDValue combineX86ShufflesRecursively(
Ops, Mask, Root, HasVariableMask, DAG, Subtarget))
return Cst;
- // Canonicalize the combined shuffle mask chain with horizontal ops.
- // NOTE: This will update the Ops and Mask.
- if (SDValue HOp = canonicalizeShuffleMaskWithHorizOp(
- Ops, Mask, RootSizeInBits, SDLoc(Root), DAG, Subtarget))
- return DAG.getBitcast(Root.getValueType(), HOp);
-
- // Widen any subvector shuffle inputs we've collected.
- if (any_of(Ops, [RootSizeInBits](SDValue Op) {
- return Op.getValueSizeInBits() < RootSizeInBits;
- })) {
- for (SDValue &Op : Ops)
- if (Op.getValueSizeInBits() < RootSizeInBits)
- Op = widenSubVector(Op, false, Subtarget, DAG, SDLoc(Op),
- RootSizeInBits);
- // Reresolve - we might have repeated subvector sources.
- resolveTargetShuffleInputsAndMask(Ops, Mask);
- }
-
+ // Canonicalize the combined shuffle mask chain with horizontal ops.
+ // NOTE: This will update the Ops and Mask.
+ if (SDValue HOp = canonicalizeShuffleMaskWithHorizOp(
+ Ops, Mask, RootSizeInBits, SDLoc(Root), DAG, Subtarget))
+ return DAG.getBitcast(Root.getValueType(), HOp);
+
+ // Widen any subvector shuffle inputs we've collected.
+ if (any_of(Ops, [RootSizeInBits](SDValue Op) {
+ return Op.getValueSizeInBits() < RootSizeInBits;
+ })) {
+ for (SDValue &Op : Ops)
+ if (Op.getValueSizeInBits() < RootSizeInBits)
+ Op = widenSubVector(Op, false, Subtarget, DAG, SDLoc(Op),
+ RootSizeInBits);
+ // Reresolve - we might have repeated subvector sources.
+ resolveTargetShuffleInputsAndMask(Ops, Mask);
+ }
+
// We can only combine unary and binary shuffle mask cases.
if (Ops.size() <= 2) {
// Minor canonicalization of the accumulated shuffle mask to make it easier
@@ -36625,10 +36625,10 @@ static SDValue combineX86ShufflesRecursively(
// elements, and shrink them to the half-width mask. It does this in a loop
// so it will reduce the size of the mask to the minimal width mask which
// performs an equivalent shuffle.
- while (Mask.size() > 1) {
- SmallVector<int, 64> WidenedMask;
- if (!canWidenShuffleElements(Mask, WidenedMask))
- break;
+ while (Mask.size() > 1) {
+ SmallVector<int, 64> WidenedMask;
+ if (!canWidenShuffleElements(Mask, WidenedMask))
+ break;
Mask = std::move(WidenedMask);
}
@@ -36655,7 +36655,7 @@ static SDValue combineX86ShufflesRecursively(
static SDValue combineX86ShufflesRecursively(SDValue Op, SelectionDAG &DAG,
const X86Subtarget &Subtarget) {
return combineX86ShufflesRecursively({Op}, 0, Op, {0}, {}, /*Depth*/ 0,
- X86::MaxShuffleCombineDepth,
+ X86::MaxShuffleCombineDepth,
/*HasVarMask*/ false,
/*AllowVarMask*/ true, DAG, Subtarget);
}
@@ -36889,61 +36889,61 @@ static SDValue combineCommutableSHUFP(SDValue N, MVT VT, const SDLoc &DL,
return SDValue();
}
-/// Attempt to fold vpermf128(op(),op()) -> op(vpermf128(),vpermf128()).
-static SDValue canonicalizeLaneShuffleWithRepeatedOps(SDValue V,
- SelectionDAG &DAG,
- const SDLoc &DL) {
- assert(V.getOpcode() == X86ISD::VPERM2X128 && "Unknown lane shuffle");
-
- MVT VT = V.getSimpleValueType();
- SDValue Src0 = peekThroughBitcasts(V.getOperand(0));
- SDValue Src1 = peekThroughBitcasts(V.getOperand(1));
- unsigned SrcOpc0 = Src0.getOpcode();
- unsigned SrcOpc1 = Src1.getOpcode();
- EVT SrcVT0 = Src0.getValueType();
- EVT SrcVT1 = Src1.getValueType();
-
- if (!Src1.isUndef() && (SrcVT0 != SrcVT1 || SrcOpc0 != SrcOpc1))
- return SDValue();
-
- switch (SrcOpc0) {
- case X86ISD::MOVDDUP: {
- SDValue LHS = DAG.getBitcast(VT, Src0.getOperand(0));
- SDValue RHS =
- DAG.getBitcast(VT, Src1.isUndef() ? Src1 : Src1.getOperand(0));
- SDValue Res =
- DAG.getNode(X86ISD::VPERM2X128, DL, VT, LHS, RHS, V.getOperand(2));
- Res = DAG.getNode(SrcOpc0, DL, SrcVT0, DAG.getBitcast(SrcVT0, Res));
- return DAG.getBitcast(VT, Res);
- }
- case X86ISD::VPERMILPI:
- // TODO: Handle v4f64 permutes with different low/high lane masks.
- if (SrcVT0 == MVT::v4f64) {
- uint64_t Mask = Src0.getConstantOperandVal(1);
- if ((Mask & 0x3) != ((Mask >> 2) & 0x3))
- break;
- }
- LLVM_FALLTHROUGH;
- case X86ISD::VSHLI:
- case X86ISD::VSRLI:
- case X86ISD::VSRAI:
- case X86ISD::PSHUFD:
- if (Src1.isUndef() || Src0.getOperand(1) == Src1.getOperand(1)) {
- SDValue LHS = DAG.getBitcast(VT, Src0.getOperand(0));
- SDValue RHS =
- DAG.getBitcast(VT, Src1.isUndef() ? Src1 : Src1.getOperand(0));
- SDValue Res =
- DAG.getNode(X86ISD::VPERM2X128, DL, VT, LHS, RHS, V.getOperand(2));
- Res = DAG.getNode(SrcOpc0, DL, SrcVT0, DAG.getBitcast(SrcVT0, Res),
- Src0.getOperand(1));
- return DAG.getBitcast(VT, Res);
- }
- break;
- }
-
- return SDValue();
-}
-
+/// Attempt to fold vpermf128(op(),op()) -> op(vpermf128(),vpermf128()).
+static SDValue canonicalizeLaneShuffleWithRepeatedOps(SDValue V,
+ SelectionDAG &DAG,
+ const SDLoc &DL) {
+ assert(V.getOpcode() == X86ISD::VPERM2X128 && "Unknown lane shuffle");
+
+ MVT VT = V.getSimpleValueType();
+ SDValue Src0 = peekThroughBitcasts(V.getOperand(0));
+ SDValue Src1 = peekThroughBitcasts(V.getOperand(1));
+ unsigned SrcOpc0 = Src0.getOpcode();
+ unsigned SrcOpc1 = Src1.getOpcode();
+ EVT SrcVT0 = Src0.getValueType();
+ EVT SrcVT1 = Src1.getValueType();
+
+ if (!Src1.isUndef() && (SrcVT0 != SrcVT1 || SrcOpc0 != SrcOpc1))
+ return SDValue();
+
+ switch (SrcOpc0) {
+ case X86ISD::MOVDDUP: {
+ SDValue LHS = DAG.getBitcast(VT, Src0.getOperand(0));
+ SDValue RHS =
+ DAG.getBitcast(VT, Src1.isUndef() ? Src1 : Src1.getOperand(0));
+ SDValue Res =
+ DAG.getNode(X86ISD::VPERM2X128, DL, VT, LHS, RHS, V.getOperand(2));
+ Res = DAG.getNode(SrcOpc0, DL, SrcVT0, DAG.getBitcast(SrcVT0, Res));
+ return DAG.getBitcast(VT, Res);
+ }
+ case X86ISD::VPERMILPI:
+ // TODO: Handle v4f64 permutes with different low/high lane masks.
+ if (SrcVT0 == MVT::v4f64) {
+ uint64_t Mask = Src0.getConstantOperandVal(1);
+ if ((Mask & 0x3) != ((Mask >> 2) & 0x3))
+ break;
+ }
+ LLVM_FALLTHROUGH;
+ case X86ISD::VSHLI:
+ case X86ISD::VSRLI:
+ case X86ISD::VSRAI:
+ case X86ISD::PSHUFD:
+ if (Src1.isUndef() || Src0.getOperand(1) == Src1.getOperand(1)) {
+ SDValue LHS = DAG.getBitcast(VT, Src0.getOperand(0));
+ SDValue RHS =
+ DAG.getBitcast(VT, Src1.isUndef() ? Src1 : Src1.getOperand(0));
+ SDValue Res =
+ DAG.getNode(X86ISD::VPERM2X128, DL, VT, LHS, RHS, V.getOperand(2));
+ Res = DAG.getNode(SrcOpc0, DL, SrcVT0, DAG.getBitcast(SrcVT0, Res),
+ Src0.getOperand(1));
+ return DAG.getBitcast(VT, Res);
+ }
+ break;
+ }
+
+ return SDValue();
+}
+
/// Try to combine x86 target specific shuffles.
static SDValue combineTargetShuffle(SDValue N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
@@ -37016,7 +37016,7 @@ static SDValue combineTargetShuffle(SDValue N, SelectionDAG &DAG,
DemandedMask[i] = i;
if (SDValue Res = combineX86ShufflesRecursively(
{BC}, 0, BC, DemandedMask, {}, /*Depth*/ 0,
- X86::MaxShuffleCombineDepth,
+ X86::MaxShuffleCombineDepth,
/*HasVarMask*/ false, /*AllowVarMask*/ true, DAG, Subtarget))
return DAG.getNode(X86ISD::VBROADCAST, DL, VT,
DAG.getBitcast(SrcVT, Res));
@@ -37046,8 +37046,8 @@ static SDValue combineTargetShuffle(SDValue N, SelectionDAG &DAG,
for (SDNode *User : Src->uses())
if (User != N.getNode() && User->getOpcode() == X86ISD::VBROADCAST &&
Src == User->getOperand(0) &&
- User->getValueSizeInBits(0).getFixedSize() >
- VT.getFixedSizeInBits()) {
+ User->getValueSizeInBits(0).getFixedSize() >
+ VT.getFixedSizeInBits()) {
return extractSubVector(SDValue(User, 0), 0, DAG, DL,
VT.getSizeInBits());
}
@@ -37133,8 +37133,8 @@ static SDValue combineTargetShuffle(SDValue N, SelectionDAG &DAG,
LN->isSimple()) {
unsigned Offset = ShiftAmt / 8;
SDVTList Tys = DAG.getVTList(VT, MVT::Other);
- SDValue Ptr = DAG.getMemBasePlusOffset(LN->getBasePtr(),
- TypeSize::Fixed(Offset), DL);
+ SDValue Ptr = DAG.getMemBasePlusOffset(LN->getBasePtr(),
+ TypeSize::Fixed(Offset), DL);
SDValue Ops[] = { LN->getChain(), Ptr };
SDValue BcastLd = DAG.getMemIntrinsicNode(
X86ISD::VBROADCAST_LOAD, DL, Tys, Ops, MVT::i16,
@@ -37166,16 +37166,16 @@ static SDValue combineTargetShuffle(SDValue N, SelectionDAG &DAG,
}
// vbroadcast(vector load X) -> vbroadcast_load
- if ((SrcVT == MVT::v2f64 || SrcVT == MVT::v4f32 || SrcVT == MVT::v2i64 ||
- SrcVT == MVT::v4i32) &&
- Src.hasOneUse() && ISD::isNormalLoad(Src.getNode())) {
+ if ((SrcVT == MVT::v2f64 || SrcVT == MVT::v4f32 || SrcVT == MVT::v2i64 ||
+ SrcVT == MVT::v4i32) &&
+ Src.hasOneUse() && ISD::isNormalLoad(Src.getNode())) {
LoadSDNode *LN = cast<LoadSDNode>(Src);
// Unless the load is volatile or atomic.
if (LN->isSimple()) {
SDVTList Tys = DAG.getVTList(VT, MVT::Other);
- SDValue Ops[] = {LN->getChain(), LN->getBasePtr()};
+ SDValue Ops[] = {LN->getChain(), LN->getBasePtr()};
SDValue BcastLd = DAG.getMemIntrinsicNode(
- X86ISD::VBROADCAST_LOAD, DL, Tys, Ops, SrcVT.getScalarType(),
+ X86ISD::VBROADCAST_LOAD, DL, Tys, Ops, SrcVT.getScalarType(),
LN->getPointerInfo(), LN->getOriginalAlign(),
LN->getMemOperand()->getFlags());
DCI.CombineTo(N.getNode(), BcastLd);
@@ -37262,27 +37262,27 @@ static SDValue combineTargetShuffle(SDValue N, SelectionDAG &DAG,
}
}
- // Pull subvector inserts into undef through VZEXT_MOVL by making it an
- // insert into a zero vector. This helps get VZEXT_MOVL closer to
- // scalar_to_vectors where 256/512 are canonicalized to an insert and a
- // 128-bit scalar_to_vector. This reduces the number of isel patterns.
- if (!DCI.isBeforeLegalizeOps() && N0.hasOneUse()) {
- SDValue V = peekThroughOneUseBitcasts(N0);
-
- if (V.getOpcode() == ISD::INSERT_SUBVECTOR && V.getOperand(0).isUndef() &&
- isNullConstant(V.getOperand(2))) {
- SDValue In = V.getOperand(1);
- MVT SubVT = MVT::getVectorVT(VT.getVectorElementType(),
- In.getValueSizeInBits() /
- VT.getScalarSizeInBits());
- In = DAG.getBitcast(SubVT, In);
- SDValue Movl = DAG.getNode(X86ISD::VZEXT_MOVL, DL, SubVT, In);
- return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT,
- getZeroVector(VT, Subtarget, DAG, DL), Movl,
- V.getOperand(2));
- }
- }
-
+ // Pull subvector inserts into undef through VZEXT_MOVL by making it an
+ // insert into a zero vector. This helps get VZEXT_MOVL closer to
+ // scalar_to_vectors where 256/512 are canonicalized to an insert and a
+ // 128-bit scalar_to_vector. This reduces the number of isel patterns.
+ if (!DCI.isBeforeLegalizeOps() && N0.hasOneUse()) {
+ SDValue V = peekThroughOneUseBitcasts(N0);
+
+ if (V.getOpcode() == ISD::INSERT_SUBVECTOR && V.getOperand(0).isUndef() &&
+ isNullConstant(V.getOperand(2))) {
+ SDValue In = V.getOperand(1);
+ MVT SubVT = MVT::getVectorVT(VT.getVectorElementType(),
+ In.getValueSizeInBits() /
+ VT.getScalarSizeInBits());
+ In = DAG.getBitcast(SubVT, In);
+ SDValue Movl = DAG.getNode(X86ISD::VZEXT_MOVL, DL, SubVT, In);
+ return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT,
+ getZeroVector(VT, Subtarget, DAG, DL), Movl,
+ V.getOperand(2));
+ }
+ }
+
return SDValue();
}
case X86ISD::BLENDI: {
@@ -37324,51 +37324,51 @@ static SDValue combineTargetShuffle(SDValue N, SelectionDAG &DAG,
return SDValue();
}
case X86ISD::VPERM2X128: {
- // Fold vperm2x128(bitcast(x),bitcast(y),c) -> bitcast(vperm2x128(x,y,c)).
- SDValue LHS = N->getOperand(0);
- SDValue RHS = N->getOperand(1);
- if (LHS.getOpcode() == ISD::BITCAST &&
- (RHS.getOpcode() == ISD::BITCAST || RHS.isUndef())) {
- EVT SrcVT = LHS.getOperand(0).getValueType();
- if (RHS.isUndef() || SrcVT == RHS.getOperand(0).getValueType()) {
- return DAG.getBitcast(VT, DAG.getNode(X86ISD::VPERM2X128, DL, SrcVT,
- DAG.getBitcast(SrcVT, LHS),
- DAG.getBitcast(SrcVT, RHS),
- N->getOperand(2)));
- }
- }
-
- // Fold vperm2x128(op(),op()) -> op(vperm2x128(),vperm2x128()).
- if (SDValue Res = canonicalizeLaneShuffleWithRepeatedOps(N, DAG, DL))
- return Res;
-
- // Fold vperm2x128 subvector shuffle with an inner concat pattern.
- // vperm2x128(concat(X,Y),concat(Z,W)) --> concat X,Y etc.
- auto FindSubVector128 = [&](unsigned Idx) {
- if (Idx > 3)
- return SDValue();
- SDValue Src = peekThroughBitcasts(N.getOperand(Idx < 2 ? 0 : 1));
- SmallVector<SDValue> SubOps;
- if (collectConcatOps(Src.getNode(), SubOps) && SubOps.size() == 2)
- return SubOps[Idx & 1];
- unsigned NumElts = Src.getValueType().getVectorNumElements();
- if ((Idx & 1) == 1 && Src.getOpcode() == ISD::INSERT_SUBVECTOR &&
- Src.getOperand(1).getValueSizeInBits() == 128 &&
- Src.getConstantOperandAPInt(2) == (NumElts / 2)) {
- return Src.getOperand(1);
- }
+ // Fold vperm2x128(bitcast(x),bitcast(y),c) -> bitcast(vperm2x128(x,y,c)).
+ SDValue LHS = N->getOperand(0);
+ SDValue RHS = N->getOperand(1);
+ if (LHS.getOpcode() == ISD::BITCAST &&
+ (RHS.getOpcode() == ISD::BITCAST || RHS.isUndef())) {
+ EVT SrcVT = LHS.getOperand(0).getValueType();
+ if (RHS.isUndef() || SrcVT == RHS.getOperand(0).getValueType()) {
+ return DAG.getBitcast(VT, DAG.getNode(X86ISD::VPERM2X128, DL, SrcVT,
+ DAG.getBitcast(SrcVT, LHS),
+ DAG.getBitcast(SrcVT, RHS),
+ N->getOperand(2)));
+ }
+ }
+
+ // Fold vperm2x128(op(),op()) -> op(vperm2x128(),vperm2x128()).
+ if (SDValue Res = canonicalizeLaneShuffleWithRepeatedOps(N, DAG, DL))
+ return Res;
+
+ // Fold vperm2x128 subvector shuffle with an inner concat pattern.
+ // vperm2x128(concat(X,Y),concat(Z,W)) --> concat X,Y etc.
+ auto FindSubVector128 = [&](unsigned Idx) {
+ if (Idx > 3)
+ return SDValue();
+ SDValue Src = peekThroughBitcasts(N.getOperand(Idx < 2 ? 0 : 1));
+ SmallVector<SDValue> SubOps;
+ if (collectConcatOps(Src.getNode(), SubOps) && SubOps.size() == 2)
+ return SubOps[Idx & 1];
+ unsigned NumElts = Src.getValueType().getVectorNumElements();
+ if ((Idx & 1) == 1 && Src.getOpcode() == ISD::INSERT_SUBVECTOR &&
+ Src.getOperand(1).getValueSizeInBits() == 128 &&
+ Src.getConstantOperandAPInt(2) == (NumElts / 2)) {
+ return Src.getOperand(1);
+ }
return SDValue();
- };
- unsigned Imm = N.getConstantOperandVal(2);
- if (SDValue SubLo = FindSubVector128(Imm & 0x0F)) {
- if (SDValue SubHi = FindSubVector128((Imm & 0xF0) >> 4)) {
- MVT SubVT = VT.getHalfNumVectorElementsVT();
- SubLo = DAG.getBitcast(SubVT, SubLo);
- SubHi = DAG.getBitcast(SubVT, SubHi);
- return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, SubLo, SubHi);
- }
- }
- return SDValue();
+ };
+ unsigned Imm = N.getConstantOperandVal(2);
+ if (SDValue SubLo = FindSubVector128(Imm & 0x0F)) {
+ if (SDValue SubHi = FindSubVector128((Imm & 0xF0) >> 4)) {
+ MVT SubVT = VT.getHalfNumVectorElementsVT();
+ SubLo = DAG.getBitcast(SubVT, SubLo);
+ SubHi = DAG.getBitcast(SubVT, SubHi);
+ return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, SubLo, SubHi);
+ }
+ }
+ return SDValue();
}
case X86ISD::PSHUFD:
case X86ISD::PSHUFLW:
@@ -37811,12 +37811,12 @@ static SDValue combineShuffleOfConcatUndef(SDNode *N, SelectionDAG &DAG,
/// Eliminate a redundant shuffle of a horizontal math op.
static SDValue foldShuffleOfHorizOp(SDNode *N, SelectionDAG &DAG) {
- // TODO: Can we use getTargetShuffleInputs instead?
+ // TODO: Can we use getTargetShuffleInputs instead?
unsigned Opcode = N->getOpcode();
if (Opcode != X86ISD::MOVDDUP && Opcode != X86ISD::VBROADCAST)
- if (Opcode != X86ISD::UNPCKL && Opcode != X86ISD::UNPCKH)
- if (Opcode != ISD::VECTOR_SHUFFLE || !N->getOperand(1).isUndef())
- return SDValue();
+ if (Opcode != X86ISD::UNPCKL && Opcode != X86ISD::UNPCKH)
+ if (Opcode != ISD::VECTOR_SHUFFLE || !N->getOperand(1).isUndef())
+ return SDValue();
// For a broadcast, peek through an extract element of index 0 to find the
// horizontal op: broadcast (ext_vec_elt HOp, 0)
@@ -37835,28 +37835,28 @@ static SDValue foldShuffleOfHorizOp(SDNode *N, SelectionDAG &DAG) {
HOp.getOpcode() != X86ISD::HSUB && HOp.getOpcode() != X86ISD::FHSUB)
return SDValue();
- // unpcklo(hop(x,y),hop(z,w)) -> permute(hop(x,z)).
- // unpckhi(hop(x,y),hop(z,w)) -> permute(hop(y,w)).
- // Don't fold if hop(x,y) == hop(z,w).
- if (Opcode == X86ISD::UNPCKL || Opcode == X86ISD::UNPCKH) {
- SDValue HOp2 = N->getOperand(1);
- if (HOp.getOpcode() != HOp2.getOpcode() || VT.getScalarSizeInBits() != 32)
- return SDValue();
- if (HOp == HOp2)
- return SDValue();
- SDLoc DL(HOp);
- unsigned LoHi = Opcode == X86ISD::UNPCKL ? 0 : 1;
- SDValue Res = DAG.getNode(HOp.getOpcode(), DL, VT, HOp.getOperand(LoHi),
- HOp2.getOperand(LoHi));
- // Use SHUFPS for the permute so this will work on SSE3 targets, shuffle
- // combining and domain handling will simplify this later on.
- EVT ShuffleVT = VT.changeVectorElementType(MVT::f32);
- Res = DAG.getBitcast(ShuffleVT, Res);
- Res = DAG.getNode(X86ISD::SHUFP, DL, ShuffleVT, Res, Res,
- getV4X86ShuffleImm8ForMask({0, 2, 1, 3}, DL, DAG));
- return DAG.getBitcast(VT, Res);
- }
-
+ // unpcklo(hop(x,y),hop(z,w)) -> permute(hop(x,z)).
+ // unpckhi(hop(x,y),hop(z,w)) -> permute(hop(y,w)).
+ // Don't fold if hop(x,y) == hop(z,w).
+ if (Opcode == X86ISD::UNPCKL || Opcode == X86ISD::UNPCKH) {
+ SDValue HOp2 = N->getOperand(1);
+ if (HOp.getOpcode() != HOp2.getOpcode() || VT.getScalarSizeInBits() != 32)
+ return SDValue();
+ if (HOp == HOp2)
+ return SDValue();
+ SDLoc DL(HOp);
+ unsigned LoHi = Opcode == X86ISD::UNPCKL ? 0 : 1;
+ SDValue Res = DAG.getNode(HOp.getOpcode(), DL, VT, HOp.getOperand(LoHi),
+ HOp2.getOperand(LoHi));
+ // Use SHUFPS for the permute so this will work on SSE3 targets, shuffle
+ // combining and domain handling will simplify this later on.
+ EVT ShuffleVT = VT.changeVectorElementType(MVT::f32);
+ Res = DAG.getBitcast(ShuffleVT, Res);
+ Res = DAG.getNode(X86ISD::SHUFP, DL, ShuffleVT, Res, Res,
+ getV4X86ShuffleImm8ForMask({0, 2, 1, 3}, DL, DAG));
+ return DAG.getBitcast(VT, Res);
+ }
+
// 128-bit horizontal math instructions are defined to operate on adjacent
// lanes of each operand as:
// v4X32: A[0] + A[1] , A[2] + A[3] , B[0] + B[1] , B[2] + B[3]
@@ -37889,8 +37889,8 @@ static SDValue foldShuffleOfHorizOp(SDNode *N, SelectionDAG &DAG) {
// replicating low and high halves (and without changing the type/length of
// the vector), we don't need the shuffle.
if (Opcode == X86ISD::MOVDDUP || Opcode == X86ISD::VBROADCAST) {
- if (Opcode == X86ISD::VBROADCAST && !VT.is128BitVector())
- return SDValue();
+ if (Opcode == X86ISD::VBROADCAST && !VT.is128BitVector())
+ return SDValue();
if (HOp.getScalarValueSizeInBits() == 64 && HOp.getValueType() == VT) {
// movddup (hadd X, X) --> hadd X, X
// broadcast (extract_vec_elt (hadd X, X), 0) --> hadd X, X
@@ -37903,20 +37903,20 @@ static SDValue foldShuffleOfHorizOp(SDNode *N, SelectionDAG &DAG) {
// shuffle (hadd X, X), undef, [low half...high half] --> hadd X, X
ArrayRef<int> Mask = cast<ShuffleVectorSDNode>(N)->getMask();
-
+
// TODO: Other mask possibilities like {1,1} and {1,0} could be added here,
// but this should be tied to whatever horizontal op matching and shuffle
// canonicalization are producing.
if (HOp.getValueSizeInBits() == 128 &&
- (isShuffleEquivalent(Mask, {0, 0}) ||
- isShuffleEquivalent(Mask, {0, 1, 0, 1}) ||
- isShuffleEquivalent(Mask, {0, 1, 2, 3, 0, 1, 2, 3})))
+ (isShuffleEquivalent(Mask, {0, 0}) ||
+ isShuffleEquivalent(Mask, {0, 1, 0, 1}) ||
+ isShuffleEquivalent(Mask, {0, 1, 2, 3, 0, 1, 2, 3})))
return updateHOp(HOp, DAG);
if (HOp.getValueSizeInBits() == 256 &&
- (isShuffleEquivalent(Mask, {0, 0, 2, 2}) ||
- isShuffleEquivalent(Mask, {0, 1, 0, 1, 4, 5, 4, 5}) ||
- isShuffleEquivalent(
+ (isShuffleEquivalent(Mask, {0, 0, 2, 2}) ||
+ isShuffleEquivalent(Mask, {0, 1, 0, 1, 4, 5, 4, 5}) ||
+ isShuffleEquivalent(
Mask, {0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11})))
return updateHOp(HOp, DAG);
@@ -37974,34 +37974,34 @@ static SDValue combineShuffle(SDNode *N, SelectionDAG &DAG,
if (SDValue HAddSub = foldShuffleOfHorizOp(N, DAG))
return HAddSub;
-
- // Merge shuffles through binops if its likely we'll be able to merge it
- // with other shuffles (as long as they aren't splats).
- // shuffle(bop(shuffle(x,y),shuffle(z,w)),bop(shuffle(a,b),shuffle(c,d)))
- // TODO: We might be able to move this to DAGCombiner::visitVECTOR_SHUFFLE.
- if (auto *SVN = dyn_cast<ShuffleVectorSDNode>(N)) {
- unsigned SrcOpcode = N->getOperand(0).getOpcode();
- if (SrcOpcode == N->getOperand(1).getOpcode() && TLI.isBinOp(SrcOpcode) &&
- N->isOnlyUserOf(N->getOperand(0).getNode()) &&
- N->isOnlyUserOf(N->getOperand(1).getNode())) {
- SDValue Op00 = N->getOperand(0).getOperand(0);
- SDValue Op10 = N->getOperand(1).getOperand(0);
- SDValue Op01 = N->getOperand(0).getOperand(1);
- SDValue Op11 = N->getOperand(1).getOperand(1);
- auto *SVN00 = dyn_cast<ShuffleVectorSDNode>(Op00);
- auto *SVN10 = dyn_cast<ShuffleVectorSDNode>(Op10);
- auto *SVN01 = dyn_cast<ShuffleVectorSDNode>(Op01);
- auto *SVN11 = dyn_cast<ShuffleVectorSDNode>(Op11);
- if (((SVN00 && !SVN00->isSplat()) || (SVN10 && !SVN10->isSplat())) &&
- ((SVN01 && !SVN01->isSplat()) || (SVN11 && !SVN11->isSplat()))) {
- SDLoc DL(N);
- ArrayRef<int> Mask = SVN->getMask();
- SDValue LHS = DAG.getVectorShuffle(VT, DL, Op00, Op10, Mask);
- SDValue RHS = DAG.getVectorShuffle(VT, DL, Op01, Op11, Mask);
- return DAG.getNode(SrcOpcode, DL, VT, LHS, RHS);
- }
- }
- }
+
+ // Merge shuffles through binops if its likely we'll be able to merge it
+ // with other shuffles (as long as they aren't splats).
+ // shuffle(bop(shuffle(x,y),shuffle(z,w)),bop(shuffle(a,b),shuffle(c,d)))
+ // TODO: We might be able to move this to DAGCombiner::visitVECTOR_SHUFFLE.
+ if (auto *SVN = dyn_cast<ShuffleVectorSDNode>(N)) {
+ unsigned SrcOpcode = N->getOperand(0).getOpcode();
+ if (SrcOpcode == N->getOperand(1).getOpcode() && TLI.isBinOp(SrcOpcode) &&
+ N->isOnlyUserOf(N->getOperand(0).getNode()) &&
+ N->isOnlyUserOf(N->getOperand(1).getNode())) {
+ SDValue Op00 = N->getOperand(0).getOperand(0);
+ SDValue Op10 = N->getOperand(1).getOperand(0);
+ SDValue Op01 = N->getOperand(0).getOperand(1);
+ SDValue Op11 = N->getOperand(1).getOperand(1);
+ auto *SVN00 = dyn_cast<ShuffleVectorSDNode>(Op00);
+ auto *SVN10 = dyn_cast<ShuffleVectorSDNode>(Op10);
+ auto *SVN01 = dyn_cast<ShuffleVectorSDNode>(Op01);
+ auto *SVN11 = dyn_cast<ShuffleVectorSDNode>(Op11);
+ if (((SVN00 && !SVN00->isSplat()) || (SVN10 && !SVN10->isSplat())) &&
+ ((SVN01 && !SVN01->isSplat()) || (SVN11 && !SVN11->isSplat()))) {
+ SDLoc DL(N);
+ ArrayRef<int> Mask = SVN->getMask();
+ SDValue LHS = DAG.getVectorShuffle(VT, DL, Op00, Op10, Mask);
+ SDValue RHS = DAG.getVectorShuffle(VT, DL, Op01, Op11, Mask);
+ return DAG.getNode(SrcOpcode, DL, VT, LHS, RHS);
+ }
+ }
+ }
}
// Attempt to combine into a vector load/broadcast.
@@ -38035,8 +38035,8 @@ static SDValue combineShuffle(SDNode *N, SelectionDAG &DAG,
// TODO - merge this into combineX86ShufflesRecursively.
APInt KnownUndef, KnownZero;
APInt DemandedElts = APInt::getAllOnesValue(VT.getVectorNumElements());
- if (TLI.SimplifyDemandedVectorElts(Op, DemandedElts, KnownUndef, KnownZero,
- DCI))
+ if (TLI.SimplifyDemandedVectorElts(Op, DemandedElts, KnownUndef, KnownZero,
+ DCI))
return SDValue(N, 0);
}
@@ -38170,13 +38170,13 @@ bool X86TargetLowering::SimplifyDemandedVectorEltsForTargetNode(
if (SimplifyDemandedVectorElts(Src, DemandedElts, SrcUndef, KnownZero, TLO,
Depth + 1))
return true;
-
- // Aggressively peek through ops to get at the demanded elts.
- if (!DemandedElts.isAllOnesValue())
- if (SDValue NewSrc = SimplifyMultipleUseDemandedVectorElts(
- Src, DemandedElts, TLO.DAG, Depth + 1))
- return TLO.CombineTo(
- Op, TLO.DAG.getNode(Opc, SDLoc(Op), VT, NewSrc, Op.getOperand(1)));
+
+ // Aggressively peek through ops to get at the demanded elts.
+ if (!DemandedElts.isAllOnesValue())
+ if (SDValue NewSrc = SimplifyMultipleUseDemandedVectorElts(
+ Src, DemandedElts, TLO.DAG, Depth + 1))
+ return TLO.CombineTo(
+ Op, TLO.DAG.getNode(Opc, SDLoc(Op), VT, NewSrc, Op.getOperand(1)));
break;
}
case X86ISD::KSHIFTL: {
@@ -38365,7 +38365,7 @@ bool X86TargetLowering::SimplifyDemandedVectorEltsForTargetNode(
SDValue Src = Op.getOperand(0);
MVT SrcVT = Src.getSimpleValueType();
if (!SrcVT.isVector())
- break;
+ break;
// Don't bother broadcasting if we just need the 0'th element.
if (DemandedElts == 1) {
if (Src.getValueType() != VT)
@@ -38418,62 +38418,62 @@ bool X86TargetLowering::SimplifyDemandedVectorEltsForTargetNode(
ExtSizeInBits = SizeInBits / 4;
switch (Opc) {
- // Scalar broadcast.
- case X86ISD::VBROADCAST: {
+ // Scalar broadcast.
+ case X86ISD::VBROADCAST: {
SDLoc DL(Op);
SDValue Src = Op.getOperand(0);
if (Src.getValueSizeInBits() > ExtSizeInBits)
Src = extractSubVector(Src, 0, TLO.DAG, DL, ExtSizeInBits);
- EVT BcstVT = EVT::getVectorVT(*TLO.DAG.getContext(), VT.getScalarType(),
- ExtSizeInBits / VT.getScalarSizeInBits());
- SDValue Bcst = TLO.DAG.getNode(X86ISD::VBROADCAST, DL, BcstVT, Src);
- return TLO.CombineTo(Op, insertSubVector(TLO.DAG.getUNDEF(VT), Bcst, 0,
+ EVT BcstVT = EVT::getVectorVT(*TLO.DAG.getContext(), VT.getScalarType(),
+ ExtSizeInBits / VT.getScalarSizeInBits());
+ SDValue Bcst = TLO.DAG.getNode(X86ISD::VBROADCAST, DL, BcstVT, Src);
+ return TLO.CombineTo(Op, insertSubVector(TLO.DAG.getUNDEF(VT), Bcst, 0,
+ TLO.DAG, DL, ExtSizeInBits));
+ }
+ case X86ISD::VBROADCAST_LOAD: {
+ SDLoc DL(Op);
+ auto *MemIntr = cast<MemIntrinsicSDNode>(Op);
+ EVT BcstVT = EVT::getVectorVT(*TLO.DAG.getContext(), VT.getScalarType(),
+ ExtSizeInBits / VT.getScalarSizeInBits());
+ SDVTList Tys = TLO.DAG.getVTList(BcstVT, MVT::Other);
+ SDValue Ops[] = {MemIntr->getOperand(0), MemIntr->getOperand(1)};
+ SDValue Bcst = TLO.DAG.getMemIntrinsicNode(
+ X86ISD::VBROADCAST_LOAD, DL, Tys, Ops, MemIntr->getMemoryVT(),
+ MemIntr->getMemOperand());
+ TLO.DAG.makeEquivalentMemoryOrdering(SDValue(MemIntr, 1),
+ Bcst.getValue(1));
+ return TLO.CombineTo(Op, insertSubVector(TLO.DAG.getUNDEF(VT), Bcst, 0,
TLO.DAG, DL, ExtSizeInBits));
}
- case X86ISD::VBROADCAST_LOAD: {
- SDLoc DL(Op);
- auto *MemIntr = cast<MemIntrinsicSDNode>(Op);
- EVT BcstVT = EVT::getVectorVT(*TLO.DAG.getContext(), VT.getScalarType(),
- ExtSizeInBits / VT.getScalarSizeInBits());
- SDVTList Tys = TLO.DAG.getVTList(BcstVT, MVT::Other);
- SDValue Ops[] = {MemIntr->getOperand(0), MemIntr->getOperand(1)};
- SDValue Bcst = TLO.DAG.getMemIntrinsicNode(
- X86ISD::VBROADCAST_LOAD, DL, Tys, Ops, MemIntr->getMemoryVT(),
- MemIntr->getMemOperand());
- TLO.DAG.makeEquivalentMemoryOrdering(SDValue(MemIntr, 1),
- Bcst.getValue(1));
- return TLO.CombineTo(Op, insertSubVector(TLO.DAG.getUNDEF(VT), Bcst, 0,
- TLO.DAG, DL, ExtSizeInBits));
- }
- // Subvector broadcast.
- case X86ISD::SUBV_BROADCAST_LOAD: {
- auto *MemIntr = cast<MemIntrinsicSDNode>(Op);
- EVT MemVT = MemIntr->getMemoryVT();
- if (ExtSizeInBits == MemVT.getStoreSizeInBits()) {
- SDLoc DL(Op);
- SDValue Ld =
- TLO.DAG.getLoad(MemVT, DL, MemIntr->getChain(),
- MemIntr->getBasePtr(), MemIntr->getMemOperand());
- TLO.DAG.makeEquivalentMemoryOrdering(SDValue(MemIntr, 1),
- Ld.getValue(1));
- return TLO.CombineTo(Op, insertSubVector(TLO.DAG.getUNDEF(VT), Ld, 0,
- TLO.DAG, DL, ExtSizeInBits));
- } else if ((ExtSizeInBits % MemVT.getStoreSizeInBits()) == 0) {
- SDLoc DL(Op);
- EVT BcstVT = EVT::getVectorVT(*TLO.DAG.getContext(), VT.getScalarType(),
- ExtSizeInBits / VT.getScalarSizeInBits());
- SDVTList Tys = TLO.DAG.getVTList(BcstVT, MVT::Other);
- SDValue Ops[] = {MemIntr->getOperand(0), MemIntr->getOperand(1)};
- SDValue Bcst =
- TLO.DAG.getMemIntrinsicNode(X86ISD::SUBV_BROADCAST_LOAD, DL, Tys,
- Ops, MemVT, MemIntr->getMemOperand());
- TLO.DAG.makeEquivalentMemoryOrdering(SDValue(MemIntr, 1),
- Bcst.getValue(1));
- return TLO.CombineTo(Op, insertSubVector(TLO.DAG.getUNDEF(VT), Bcst, 0,
- TLO.DAG, DL, ExtSizeInBits));
- }
- break;
- }
+ // Subvector broadcast.
+ case X86ISD::SUBV_BROADCAST_LOAD: {
+ auto *MemIntr = cast<MemIntrinsicSDNode>(Op);
+ EVT MemVT = MemIntr->getMemoryVT();
+ if (ExtSizeInBits == MemVT.getStoreSizeInBits()) {
+ SDLoc DL(Op);
+ SDValue Ld =
+ TLO.DAG.getLoad(MemVT, DL, MemIntr->getChain(),
+ MemIntr->getBasePtr(), MemIntr->getMemOperand());
+ TLO.DAG.makeEquivalentMemoryOrdering(SDValue(MemIntr, 1),
+ Ld.getValue(1));
+ return TLO.CombineTo(Op, insertSubVector(TLO.DAG.getUNDEF(VT), Ld, 0,
+ TLO.DAG, DL, ExtSizeInBits));
+ } else if ((ExtSizeInBits % MemVT.getStoreSizeInBits()) == 0) {
+ SDLoc DL(Op);
+ EVT BcstVT = EVT::getVectorVT(*TLO.DAG.getContext(), VT.getScalarType(),
+ ExtSizeInBits / VT.getScalarSizeInBits());
+ SDVTList Tys = TLO.DAG.getVTList(BcstVT, MVT::Other);
+ SDValue Ops[] = {MemIntr->getOperand(0), MemIntr->getOperand(1)};
+ SDValue Bcst =
+ TLO.DAG.getMemIntrinsicNode(X86ISD::SUBV_BROADCAST_LOAD, DL, Tys,
+ Ops, MemVT, MemIntr->getMemOperand());
+ TLO.DAG.makeEquivalentMemoryOrdering(SDValue(MemIntr, 1),
+ Bcst.getValue(1));
+ return TLO.CombineTo(Op, insertSubVector(TLO.DAG.getUNDEF(VT), Bcst, 0,
+ TLO.DAG, DL, ExtSizeInBits));
+ }
+ break;
+ }
// Byte shifts by immediate.
case X86ISD::VSHLDQ:
case X86ISD::VSRLDQ:
@@ -38525,8 +38525,8 @@ bool X86TargetLowering::SimplifyDemandedVectorEltsForTargetNode(
case X86ISD::UNPCKL:
case X86ISD::UNPCKH:
case X86ISD::BLENDI:
- // Integer ops.
- case X86ISD::AVG:
+ // Integer ops.
+ case X86ISD::AVG:
case X86ISD::PACKSS:
case X86ISD::PACKUS:
// Horizontal Ops.
@@ -38619,22 +38619,22 @@ bool X86TargetLowering::SimplifyDemandedVectorEltsForTargetNode(
// If we don't demand all elements, then attempt to combine to a simpler
// shuffle.
- // We need to convert the depth to something combineX86ShufflesRecursively
- // can handle - so pretend its Depth == 0 again, and reduce the max depth
- // to match. This prevents combineX86ShuffleChain from returning a
- // combined shuffle that's the same as the original root, causing an
- // infinite loop.
- if (!DemandedElts.isAllOnesValue()) {
- assert(Depth < X86::MaxShuffleCombineDepth && "Depth out of range");
-
+ // We need to convert the depth to something combineX86ShufflesRecursively
+ // can handle - so pretend its Depth == 0 again, and reduce the max depth
+ // to match. This prevents combineX86ShuffleChain from returning a
+ // combined shuffle that's the same as the original root, causing an
+ // infinite loop.
+ if (!DemandedElts.isAllOnesValue()) {
+ assert(Depth < X86::MaxShuffleCombineDepth && "Depth out of range");
+
SmallVector<int, 64> DemandedMask(NumElts, SM_SentinelUndef);
for (int i = 0; i != NumElts; ++i)
if (DemandedElts[i])
DemandedMask[i] = i;
SDValue NewShuffle = combineX86ShufflesRecursively(
- {Op}, 0, Op, DemandedMask, {}, 0, X86::MaxShuffleCombineDepth - Depth,
- /*HasVarMask*/ false,
+ {Op}, 0, Op, DemandedMask, {}, 0, X86::MaxShuffleCombineDepth - Depth,
+ /*HasVarMask*/ false,
/*AllowVarMask*/ true, TLO.DAG, Subtarget);
if (NewShuffle)
return TLO.CombineTo(Op, NewShuffle);
@@ -38737,7 +38737,7 @@ bool X86TargetLowering::SimplifyDemandedBitsForTargetNode(
// Low bits known zero.
Known.Zero.setLowBits(ShAmt);
- return false;
+ return false;
}
case X86ISD::VSRLI: {
unsigned ShAmt = Op.getConstantOperandVal(1);
@@ -38756,7 +38756,7 @@ bool X86TargetLowering::SimplifyDemandedBitsForTargetNode(
// High bits known zero.
Known.Zero.setHighBits(ShAmt);
- return false;
+ return false;
}
case X86ISD::VSRAI: {
SDValue Op0 = Op.getOperand(0);
@@ -38805,7 +38805,7 @@ bool X86TargetLowering::SimplifyDemandedBitsForTargetNode(
// High bits are known one.
if (Known.One[BitWidth - ShAmt - 1])
Known.One.setHighBits(ShAmt);
- return false;
+ return false;
}
case X86ISD::PEXTRB:
case X86ISD::PEXTRW: {
@@ -38871,7 +38871,7 @@ bool X86TargetLowering::SimplifyDemandedBitsForTargetNode(
return true;
KnownScl = KnownScl.trunc(VecVT.getScalarSizeInBits());
- Known = KnownBits::commonBits(KnownVec, KnownScl);
+ Known = KnownBits::commonBits(KnownVec, KnownScl);
return false;
}
break;
@@ -38951,83 +38951,83 @@ bool X86TargetLowering::SimplifyDemandedBitsForTargetNode(
return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, SDLoc(Op), VT, NewSrc));
return false;
}
- case X86ISD::BEXTR:
- case X86ISD::BEXTRI: {
+ case X86ISD::BEXTR:
+ case X86ISD::BEXTRI: {
SDValue Op0 = Op.getOperand(0);
SDValue Op1 = Op.getOperand(1);
// Only bottom 16-bits of the control bits are required.
if (auto *Cst1 = dyn_cast<ConstantSDNode>(Op1)) {
// NOTE: SimplifyDemandedBits won't do this for constants.
- uint64_t Val1 = Cst1->getZExtValue();
- uint64_t MaskedVal1 = Val1 & 0xFFFF;
- if (Opc == X86ISD::BEXTR && MaskedVal1 != Val1) {
+ uint64_t Val1 = Cst1->getZExtValue();
+ uint64_t MaskedVal1 = Val1 & 0xFFFF;
+ if (Opc == X86ISD::BEXTR && MaskedVal1 != Val1) {
SDLoc DL(Op);
return TLO.CombineTo(
Op, TLO.DAG.getNode(X86ISD::BEXTR, DL, VT, Op0,
TLO.DAG.getConstant(MaskedVal1, DL, VT)));
}
-
- unsigned Shift = Cst1->getAPIntValue().extractBitsAsZExtValue(8, 0);
- unsigned Length = Cst1->getAPIntValue().extractBitsAsZExtValue(8, 8);
-
- // If the length is 0, the result is 0.
- if (Length == 0) {
- Known.setAllZero();
- return false;
- }
-
- if ((Shift + Length) <= BitWidth) {
- APInt DemandedMask = APInt::getBitsSet(BitWidth, Shift, Shift + Length);
- if (SimplifyDemandedBits(Op0, DemandedMask, Known, TLO, Depth + 1))
- return true;
-
- Known = Known.extractBits(Length, Shift);
- Known = Known.zextOrTrunc(BitWidth);
- return false;
- }
- } else {
- assert(Opc == X86ISD::BEXTR && "Unexpected opcode!");
- KnownBits Known1;
- APInt DemandedMask(APInt::getLowBitsSet(BitWidth, 16));
- if (SimplifyDemandedBits(Op1, DemandedMask, Known1, TLO, Depth + 1))
- return true;
-
- // If the length is 0, replace with 0.
- KnownBits LengthBits = Known1.extractBits(8, 8);
- if (LengthBits.isZero())
- return TLO.CombineTo(Op, TLO.DAG.getConstant(0, SDLoc(Op), VT));
- }
-
- break;
- }
- case X86ISD::PDEP: {
- SDValue Op0 = Op.getOperand(0);
- SDValue Op1 = Op.getOperand(1);
-
- unsigned DemandedBitsLZ = OriginalDemandedBits.countLeadingZeros();
- APInt LoMask = APInt::getLowBitsSet(BitWidth, BitWidth - DemandedBitsLZ);
-
- // If the demanded bits has leading zeroes, we don't demand those from the
- // mask.
- if (SimplifyDemandedBits(Op1, LoMask, Known, TLO, Depth + 1))
+
+ unsigned Shift = Cst1->getAPIntValue().extractBitsAsZExtValue(8, 0);
+ unsigned Length = Cst1->getAPIntValue().extractBitsAsZExtValue(8, 8);
+
+ // If the length is 0, the result is 0.
+ if (Length == 0) {
+ Known.setAllZero();
+ return false;
+ }
+
+ if ((Shift + Length) <= BitWidth) {
+ APInt DemandedMask = APInt::getBitsSet(BitWidth, Shift, Shift + Length);
+ if (SimplifyDemandedBits(Op0, DemandedMask, Known, TLO, Depth + 1))
+ return true;
+
+ Known = Known.extractBits(Length, Shift);
+ Known = Known.zextOrTrunc(BitWidth);
+ return false;
+ }
+ } else {
+ assert(Opc == X86ISD::BEXTR && "Unexpected opcode!");
+ KnownBits Known1;
+ APInt DemandedMask(APInt::getLowBitsSet(BitWidth, 16));
+ if (SimplifyDemandedBits(Op1, DemandedMask, Known1, TLO, Depth + 1))
+ return true;
+
+ // If the length is 0, replace with 0.
+ KnownBits LengthBits = Known1.extractBits(8, 8);
+ if (LengthBits.isZero())
+ return TLO.CombineTo(Op, TLO.DAG.getConstant(0, SDLoc(Op), VT));
+ }
+
+ break;
+ }
+ case X86ISD::PDEP: {
+ SDValue Op0 = Op.getOperand(0);
+ SDValue Op1 = Op.getOperand(1);
+
+ unsigned DemandedBitsLZ = OriginalDemandedBits.countLeadingZeros();
+ APInt LoMask = APInt::getLowBitsSet(BitWidth, BitWidth - DemandedBitsLZ);
+
+ // If the demanded bits has leading zeroes, we don't demand those from the
+ // mask.
+ if (SimplifyDemandedBits(Op1, LoMask, Known, TLO, Depth + 1))
return true;
- // The number of possible 1s in the mask determines the number of LSBs of
- // operand 0 used. Undemanded bits from the mask don't matter so filter
- // them before counting.
- KnownBits Known2;
- uint64_t Count = (~Known.Zero & LoMask).countPopulation();
- APInt DemandedMask(APInt::getLowBitsSet(BitWidth, Count));
- if (SimplifyDemandedBits(Op0, DemandedMask, Known2, TLO, Depth + 1))
- return true;
+ // The number of possible 1s in the mask determines the number of LSBs of
+ // operand 0 used. Undemanded bits from the mask don't matter so filter
+ // them before counting.
+ KnownBits Known2;
+ uint64_t Count = (~Known.Zero & LoMask).countPopulation();
+ APInt DemandedMask(APInt::getLowBitsSet(BitWidth, Count));
+ if (SimplifyDemandedBits(Op0, DemandedMask, Known2, TLO, Depth + 1))
+ return true;
- // Zeroes are retained from the mask, but not ones.
- Known.One.clearAllBits();
- // The result will have at least as many trailing zeros as the non-mask
- // operand since bits can only map to the same or higher bit position.
- Known.Zero.setLowBits(Known2.countMinTrailingZeros());
- return false;
+ // Zeroes are retained from the mask, but not ones.
+ Known.One.clearAllBits();
+ // The result will have at least as many trailing zeros as the non-mask
+ // operand since bits can only map to the same or higher bit position.
+ Known.Zero.setLowBits(Known2.countMinTrailingZeros());
+ return false;
}
}
@@ -39438,8 +39438,8 @@ static SDValue createMMXBuildVector(BuildVectorSDNode *BV, SelectionDAG &DAG,
// Convert build vector ops to MMX data in the bottom elements.
SmallVector<SDValue, 8> Ops;
- const TargetLowering &TLI = DAG.getTargetLoweringInfo();
-
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+
// Broadcast - use (PUNPCKL+)PSHUFW to broadcast single element.
if (Splat) {
if (Splat.isUndef())
@@ -39452,16 +39452,16 @@ static SDValue createMMXBuildVector(BuildVectorSDNode *BV, SelectionDAG &DAG,
if (NumElts == 8)
Splat = DAG.getNode(
ISD::INTRINSIC_WO_CHAIN, DL, MVT::x86mmx,
- DAG.getTargetConstant(Intrinsic::x86_mmx_punpcklbw, DL,
- TLI.getPointerTy(DAG.getDataLayout())),
- Splat, Splat);
+ DAG.getTargetConstant(Intrinsic::x86_mmx_punpcklbw, DL,
+ TLI.getPointerTy(DAG.getDataLayout())),
+ Splat, Splat);
// Use PSHUFW to repeat 16-bit elements.
unsigned ShufMask = (NumElts > 2 ? 0 : 0x44);
return DAG.getNode(
ISD::INTRINSIC_WO_CHAIN, DL, MVT::x86mmx,
- DAG.getTargetConstant(Intrinsic::x86_sse_pshuf_w, DL,
- TLI.getPointerTy(DAG.getDataLayout())),
+ DAG.getTargetConstant(Intrinsic::x86_sse_pshuf_w, DL,
+ TLI.getPointerTy(DAG.getDataLayout())),
Splat, DAG.getTargetConstant(ShufMask, DL, MVT::i8));
}
Ops.append(NumElts, Splat);
@@ -39477,8 +39477,8 @@ static SDValue createMMXBuildVector(BuildVectorSDNode *BV, SelectionDAG &DAG,
(NumOps == 2 ? Intrinsic::x86_mmx_punpckldq
: (NumOps == 4 ? Intrinsic::x86_mmx_punpcklwd
: Intrinsic::x86_mmx_punpcklbw));
- SDValue Intrin = DAG.getTargetConstant(
- IntrinOp, DL, TLI.getPointerTy(DAG.getDataLayout()));
+ SDValue Intrin = DAG.getTargetConstant(
+ IntrinOp, DL, TLI.getPointerTy(DAG.getDataLayout()));
for (unsigned i = 0; i != NumOps; i += 2)
Ops[i / 2] = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::x86mmx, Intrin,
Ops[i], Ops[i + 1]);
@@ -39492,7 +39492,7 @@ static SDValue createMMXBuildVector(BuildVectorSDNode *BV, SelectionDAG &DAG,
// a vector/float/double that got truncated/extended/bitcast to/from a scalar
// integer. If so, replace the scalar ops with bool vector equivalents back down
// the chain.
-static SDValue combineBitcastToBoolVector(EVT VT, SDValue V, const SDLoc &DL,
+static SDValue combineBitcastToBoolVector(EVT VT, SDValue V, const SDLoc &DL,
SelectionDAG &DAG,
const X86Subtarget &Subtarget) {
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
@@ -39545,10 +39545,10 @@ static SDValue combineBitcastToBoolVector(EVT VT, SDValue V, const SDLoc &DL,
case ISD::SHL: {
// If we find a suitable source, a SHL becomes a KSHIFTL.
SDValue Src0 = V.getOperand(0);
- if ((VT == MVT::v8i1 && !Subtarget.hasDQI()) ||
- ((VT == MVT::v32i1 || VT == MVT::v64i1) && !Subtarget.hasBWI()))
- break;
-
+ if ((VT == MVT::v8i1 && !Subtarget.hasDQI()) ||
+ ((VT == MVT::v32i1 || VT == MVT::v64i1) && !Subtarget.hasBWI()))
+ break;
+
if (auto *Amt = dyn_cast<ConstantSDNode>(V.getOperand(1)))
if (SDValue N0 = combineBitcastToBoolVector(VT, Src0, DL, DAG, Subtarget))
return DAG.getNode(
@@ -39891,8 +39891,8 @@ static SDValue createPSADBW(SelectionDAG &DAG, const SDValue &Zext0,
// Attempt to replace an min/max v8i16/v16i8 horizontal reduction with
// PHMINPOSUW.
-static SDValue combineMinMaxReduction(SDNode *Extract, SelectionDAG &DAG,
- const X86Subtarget &Subtarget) {
+static SDValue combineMinMaxReduction(SDNode *Extract, SelectionDAG &DAG,
+ const X86Subtarget &Subtarget) {
// Bail without SSE41.
if (!Subtarget.hasSSE41())
return SDValue();
@@ -39965,8 +39965,8 @@ static SDValue combineMinMaxReduction(SDNode *Extract, SelectionDAG &DAG,
}
// Attempt to replace an all_of/any_of/parity style horizontal reduction with a MOVMSK.
-static SDValue combinePredicateReduction(SDNode *Extract, SelectionDAG &DAG,
- const X86Subtarget &Subtarget) {
+static SDValue combinePredicateReduction(SDNode *Extract, SelectionDAG &DAG,
+ const X86Subtarget &Subtarget) {
// Bail without SSE2.
if (!Subtarget.hasSSE2())
return SDValue();
@@ -40080,8 +40080,8 @@ static SDValue combinePredicateReduction(SDNode *Extract, SelectionDAG &DAG,
MVT CmpVT = NumElts == 64 ? MVT::i64 : MVT::i32;
if (BinOp == ISD::XOR) {
- // parity -> (PARITY(MOVMSK X))
- SDValue Result = DAG.getNode(ISD::PARITY, DL, CmpVT, Movmsk);
+ // parity -> (PARITY(MOVMSK X))
+ SDValue Result = DAG.getNode(ISD::PARITY, DL, CmpVT, Movmsk);
return DAG.getZExtOrTrunc(Result, DL, ExtractVT);
}
@@ -40269,12 +40269,12 @@ static SDValue combineExtractWithShuffle(SDNode *N, SelectionDAG &DAG,
// Handle extract(truncate(x)) for 0'th index.
// TODO: Treat this as a faux shuffle?
// TODO: When can we use this for general indices?
- if (ISD::TRUNCATE == Src.getOpcode() && IdxC == 0 &&
- (SrcVT.getSizeInBits() % 128) == 0) {
+ if (ISD::TRUNCATE == Src.getOpcode() && IdxC == 0 &&
+ (SrcVT.getSizeInBits() % 128) == 0) {
Src = extract128BitVector(Src.getOperand(0), 0, DAG, dl);
- MVT ExtractVT = MVT::getVectorVT(SrcSVT.getSimpleVT(), 128 / SrcEltBits);
- return DAG.getNode(N->getOpcode(), dl, VT, DAG.getBitcast(ExtractVT, Src),
- Idx);
+ MVT ExtractVT = MVT::getVectorVT(SrcSVT.getSimpleVT(), 128 / SrcEltBits);
+ return DAG.getNode(N->getOpcode(), dl, VT, DAG.getBitcast(ExtractVT, Src),
+ Idx);
}
// Resolve the target shuffle inputs and mask.
@@ -40350,7 +40350,7 @@ static SDValue combineExtractWithShuffle(SDNode *N, SelectionDAG &DAG,
unsigned OpCode = (SrcVT == MVT::v8i16 ? X86ISD::PEXTRW : X86ISD::PEXTRB);
SrcOp = DAG.getBitcast(SrcVT, SrcOp);
SDValue ExtOp = DAG.getNode(OpCode, dl, MVT::i32, SrcOp,
- DAG.getTargetConstant(SrcIdx, dl, MVT::i8));
+ DAG.getTargetConstant(SrcIdx, dl, MVT::i8));
return DAG.getZExtOrTrunc(ExtOp, dl, VT);
}
@@ -40457,8 +40457,8 @@ static SDValue scalarizeExtEltFP(SDNode *ExtElt, SelectionDAG &DAG) {
/// Try to convert a vector reduction sequence composed of binops and shuffles
/// into horizontal ops.
-static SDValue combineArithReduction(SDNode *ExtElt, SelectionDAG &DAG,
- const X86Subtarget &Subtarget) {
+static SDValue combineArithReduction(SDNode *ExtElt, SelectionDAG &DAG,
+ const X86Subtarget &Subtarget) {
assert(ExtElt->getOpcode() == ISD::EXTRACT_VECTOR_ELT && "Unexpected caller");
// We need at least SSE2 to anything here.
@@ -40466,8 +40466,8 @@ static SDValue combineArithReduction(SDNode *ExtElt, SelectionDAG &DAG,
return SDValue();
ISD::NodeType Opc;
- SDValue Rdx = DAG.matchBinOpReduction(ExtElt, Opc,
- {ISD::ADD, ISD::MUL, ISD::FADD}, true);
+ SDValue Rdx = DAG.matchBinOpReduction(ExtElt, Opc,
+ {ISD::ADD, ISD::MUL, ISD::FADD}, true);
if (!Rdx)
return SDValue();
@@ -40482,46 +40482,46 @@ static SDValue combineArithReduction(SDNode *ExtElt, SelectionDAG &DAG,
SDLoc DL(ExtElt);
- // vXi8 mul reduction - promote to vXi16 mul reduction.
- if (Opc == ISD::MUL) {
- unsigned NumElts = VecVT.getVectorNumElements();
- if (VT != MVT::i8 || NumElts < 4 || !isPowerOf2_32(NumElts))
- return SDValue();
- if (VecVT.getSizeInBits() >= 128) {
- EVT WideVT = EVT::getVectorVT(*DAG.getContext(), MVT::i16, NumElts / 2);
- SDValue Lo = getUnpackl(DAG, DL, VecVT, Rdx, DAG.getUNDEF(VecVT));
- SDValue Hi = getUnpackh(DAG, DL, VecVT, Rdx, DAG.getUNDEF(VecVT));
- Lo = DAG.getBitcast(WideVT, Lo);
- Hi = DAG.getBitcast(WideVT, Hi);
- Rdx = DAG.getNode(Opc, DL, WideVT, Lo, Hi);
- while (Rdx.getValueSizeInBits() > 128) {
- std::tie(Lo, Hi) = splitVector(Rdx, DAG, DL);
- Rdx = DAG.getNode(Opc, DL, Lo.getValueType(), Lo, Hi);
- }
- } else {
- if (VecVT == MVT::v4i8)
- Rdx = DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v8i8, Rdx,
- DAG.getUNDEF(MVT::v4i8));
- Rdx = DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v16i8, Rdx,
- DAG.getUNDEF(MVT::v8i8));
- Rdx = getUnpackl(DAG, DL, MVT::v16i8, Rdx, DAG.getUNDEF(MVT::v16i8));
- Rdx = DAG.getBitcast(MVT::v8i16, Rdx);
- }
- if (NumElts >= 8)
- Rdx = DAG.getNode(Opc, DL, MVT::v8i16, Rdx,
- DAG.getVectorShuffle(MVT::v8i16, DL, Rdx, Rdx,
- {4, 5, 6, 7, -1, -1, -1, -1}));
- Rdx = DAG.getNode(Opc, DL, MVT::v8i16, Rdx,
- DAG.getVectorShuffle(MVT::v8i16, DL, Rdx, Rdx,
- {2, 3, -1, -1, -1, -1, -1, -1}));
- Rdx = DAG.getNode(Opc, DL, MVT::v8i16, Rdx,
- DAG.getVectorShuffle(MVT::v8i16, DL, Rdx, Rdx,
- {1, -1, -1, -1, -1, -1, -1, -1}));
- Rdx = DAG.getBitcast(MVT::v16i8, Rdx);
- return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Rdx, Index);
- }
-
- // vXi8 add reduction - sub 128-bit vector.
+ // vXi8 mul reduction - promote to vXi16 mul reduction.
+ if (Opc == ISD::MUL) {
+ unsigned NumElts = VecVT.getVectorNumElements();
+ if (VT != MVT::i8 || NumElts < 4 || !isPowerOf2_32(NumElts))
+ return SDValue();
+ if (VecVT.getSizeInBits() >= 128) {
+ EVT WideVT = EVT::getVectorVT(*DAG.getContext(), MVT::i16, NumElts / 2);
+ SDValue Lo = getUnpackl(DAG, DL, VecVT, Rdx, DAG.getUNDEF(VecVT));
+ SDValue Hi = getUnpackh(DAG, DL, VecVT, Rdx, DAG.getUNDEF(VecVT));
+ Lo = DAG.getBitcast(WideVT, Lo);
+ Hi = DAG.getBitcast(WideVT, Hi);
+ Rdx = DAG.getNode(Opc, DL, WideVT, Lo, Hi);
+ while (Rdx.getValueSizeInBits() > 128) {
+ std::tie(Lo, Hi) = splitVector(Rdx, DAG, DL);
+ Rdx = DAG.getNode(Opc, DL, Lo.getValueType(), Lo, Hi);
+ }
+ } else {
+ if (VecVT == MVT::v4i8)
+ Rdx = DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v8i8, Rdx,
+ DAG.getUNDEF(MVT::v4i8));
+ Rdx = DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v16i8, Rdx,
+ DAG.getUNDEF(MVT::v8i8));
+ Rdx = getUnpackl(DAG, DL, MVT::v16i8, Rdx, DAG.getUNDEF(MVT::v16i8));
+ Rdx = DAG.getBitcast(MVT::v8i16, Rdx);
+ }
+ if (NumElts >= 8)
+ Rdx = DAG.getNode(Opc, DL, MVT::v8i16, Rdx,
+ DAG.getVectorShuffle(MVT::v8i16, DL, Rdx, Rdx,
+ {4, 5, 6, 7, -1, -1, -1, -1}));
+ Rdx = DAG.getNode(Opc, DL, MVT::v8i16, Rdx,
+ DAG.getVectorShuffle(MVT::v8i16, DL, Rdx, Rdx,
+ {2, 3, -1, -1, -1, -1, -1, -1}));
+ Rdx = DAG.getNode(Opc, DL, MVT::v8i16, Rdx,
+ DAG.getVectorShuffle(MVT::v8i16, DL, Rdx, Rdx,
+ {1, -1, -1, -1, -1, -1, -1, -1}));
+ Rdx = DAG.getBitcast(MVT::v16i8, Rdx);
+ return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Rdx, Index);
+ }
+
+ // vXi8 add reduction - sub 128-bit vector.
if (VecVT == MVT::v4i8 || VecVT == MVT::v8i8) {
if (VecVT == MVT::v4i8) {
// Pad with zero.
@@ -40552,7 +40552,7 @@ static SDValue combineArithReduction(SDNode *ExtElt, SelectionDAG &DAG,
!isPowerOf2_32(VecVT.getVectorNumElements()))
return SDValue();
- // vXi8 add reduction - sum lo/hi halves then use PSADBW.
+ // vXi8 add reduction - sum lo/hi halves then use PSADBW.
if (VT == MVT::i8) {
while (Rdx.getValueSizeInBits() > 128) {
SDValue Lo, Hi;
@@ -40658,7 +40658,7 @@ static SDValue combineExtractVectorElt(SDNode *N, SelectionDAG &DAG,
}
// TODO - Remove this once we can handle the implicit zero-extension of
- // X86ISD::PEXTRW/X86ISD::PEXTRB in combinePredicateReduction and
+ // X86ISD::PEXTRW/X86ISD::PEXTRB in combinePredicateReduction and
// combineBasicSADPattern.
return SDValue();
}
@@ -40690,15 +40690,15 @@ static SDValue combineExtractVectorElt(SDNode *N, SelectionDAG &DAG,
return SAD;
// Attempt to replace an all_of/any_of horizontal reduction with a MOVMSK.
- if (SDValue Cmp = combinePredicateReduction(N, DAG, Subtarget))
+ if (SDValue Cmp = combinePredicateReduction(N, DAG, Subtarget))
return Cmp;
// Attempt to replace min/max v8i16/v16i8 reductions with PHMINPOSUW.
- if (SDValue MinMax = combineMinMaxReduction(N, DAG, Subtarget))
+ if (SDValue MinMax = combineMinMaxReduction(N, DAG, Subtarget))
return MinMax;
- // Attempt to optimize ADD/FADD/MUL reductions with HADD, promotion etc..
- if (SDValue V = combineArithReduction(N, DAG, Subtarget))
+ // Attempt to optimize ADD/FADD/MUL reductions with HADD, promotion etc..
+ if (SDValue V = combineArithReduction(N, DAG, Subtarget))
return V;
if (SDValue V = scalarizeExtEltFP(N, DAG))
@@ -40822,7 +40822,7 @@ combineVSelectWithAllOnesOrZeros(SDNode *N, SelectionDAG &DAG,
if (TValIsAllOnes && FValIsAllZeros)
return DAG.getBitcast(VT, Cond);
- if (!TLI.isTypeLegal(CondVT))
+ if (!TLI.isTypeLegal(CondVT))
return SDValue();
// vselect Cond, 111..., X -> or Cond, X
@@ -41145,36 +41145,36 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
return DAG.getVectorShuffle(VT, DL, LHS, RHS, Mask);
}
- // fold vselect(cond, pshufb(x), pshufb(y)) -> or (pshufb(x), pshufb(y))
- // by forcing the unselected elements to zero.
- // TODO: Can we handle more shuffles with this?
- if (N->getOpcode() == ISD::VSELECT && CondVT.isVector() &&
- LHS.getOpcode() == X86ISD::PSHUFB && RHS.getOpcode() == X86ISD::PSHUFB &&
- LHS.hasOneUse() && RHS.hasOneUse()) {
- MVT SimpleVT = VT.getSimpleVT();
- bool LHSUnary, RHSUnary;
- SmallVector<SDValue, 1> LHSOps, RHSOps;
- SmallVector<int, 64> LHSMask, RHSMask, CondMask;
- if (createShuffleMaskFromVSELECT(CondMask, Cond) &&
- getTargetShuffleMask(LHS.getNode(), SimpleVT, true, LHSOps, LHSMask,
- LHSUnary) &&
- getTargetShuffleMask(RHS.getNode(), SimpleVT, true, RHSOps, RHSMask,
- RHSUnary)) {
- int NumElts = VT.getVectorNumElements();
- for (int i = 0; i != NumElts; ++i) {
- if (CondMask[i] < NumElts)
- RHSMask[i] = 0x80;
- else
- LHSMask[i] = 0x80;
- }
- LHS = DAG.getNode(X86ISD::PSHUFB, DL, VT, LHS.getOperand(0),
- getConstVector(LHSMask, SimpleVT, DAG, DL, true));
- RHS = DAG.getNode(X86ISD::PSHUFB, DL, VT, RHS.getOperand(0),
- getConstVector(RHSMask, SimpleVT, DAG, DL, true));
- return DAG.getNode(ISD::OR, DL, VT, LHS, RHS);
- }
- }
-
+ // fold vselect(cond, pshufb(x), pshufb(y)) -> or (pshufb(x), pshufb(y))
+ // by forcing the unselected elements to zero.
+ // TODO: Can we handle more shuffles with this?
+ if (N->getOpcode() == ISD::VSELECT && CondVT.isVector() &&
+ LHS.getOpcode() == X86ISD::PSHUFB && RHS.getOpcode() == X86ISD::PSHUFB &&
+ LHS.hasOneUse() && RHS.hasOneUse()) {
+ MVT SimpleVT = VT.getSimpleVT();
+ bool LHSUnary, RHSUnary;
+ SmallVector<SDValue, 1> LHSOps, RHSOps;
+ SmallVector<int, 64> LHSMask, RHSMask, CondMask;
+ if (createShuffleMaskFromVSELECT(CondMask, Cond) &&
+ getTargetShuffleMask(LHS.getNode(), SimpleVT, true, LHSOps, LHSMask,
+ LHSUnary) &&
+ getTargetShuffleMask(RHS.getNode(), SimpleVT, true, RHSOps, RHSMask,
+ RHSUnary)) {
+ int NumElts = VT.getVectorNumElements();
+ for (int i = 0; i != NumElts; ++i) {
+ if (CondMask[i] < NumElts)
+ RHSMask[i] = 0x80;
+ else
+ LHSMask[i] = 0x80;
+ }
+ LHS = DAG.getNode(X86ISD::PSHUFB, DL, VT, LHS.getOperand(0),
+ getConstVector(LHSMask, SimpleVT, DAG, DL, true));
+ RHS = DAG.getNode(X86ISD::PSHUFB, DL, VT, RHS.getOperand(0),
+ getConstVector(RHSMask, SimpleVT, DAG, DL, true));
+ return DAG.getNode(ISD::OR, DL, VT, LHS, RHS);
+ }
+ }
+
// If we have SSE[12] support, try to form min/max nodes. SSE min/max
// instructions match the semantics of the common C idiom x<y?x:y but not
// x<=y?x:y, because of how they handle negative zero (which can be
@@ -41401,12 +41401,12 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
if (SDValue V = combineSelectOfTwoConstants(N, DAG))
return V;
- // Canonicalize min/max:
- // (x > 0) ? x : 0 -> (x >= 0) ? x : 0
- // (x < -1) ? x : -1 -> (x <= -1) ? x : -1
+ // Canonicalize min/max:
+ // (x > 0) ? x : 0 -> (x >= 0) ? x : 0
+ // (x < -1) ? x : -1 -> (x <= -1) ? x : -1
// This allows use of COND_S / COND_NS (see TranslateX86CC) which eliminates
- // the need for an extra compare against zero. e.g.
- // (a - b) > 0 : (a - b) ? 0 -> (a - b) >= 0 : (a - b) ? 0
+ // the need for an extra compare against zero. e.g.
+ // (a - b) > 0 : (a - b) ? 0 -> (a - b) >= 0 : (a - b) ? 0
// subl %esi, %edi
// testl %edi, %edi
// movl $0, %eax
@@ -41415,27 +41415,27 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
// xorl %eax, %eax
// subl %esi, $edi
// cmovsl %eax, %edi
- //
- // We can also canonicalize
- // (x s> 1) ? x : 1 -> (x s>= 1) ? x : 1 -> (x s> 0) ? x : 1
- // (x u> 1) ? x : 1 -> (x u>= 1) ? x : 1 -> (x != 0) ? x : 1
- // This allows the use of a test instruction for the compare.
+ //
+ // We can also canonicalize
+ // (x s> 1) ? x : 1 -> (x s>= 1) ? x : 1 -> (x s> 0) ? x : 1
+ // (x u> 1) ? x : 1 -> (x u>= 1) ? x : 1 -> (x != 0) ? x : 1
+ // This allows the use of a test instruction for the compare.
if (N->getOpcode() == ISD::SELECT && Cond.getOpcode() == ISD::SETCC &&
Cond.hasOneUse() &&
- LHS == Cond.getOperand(0) && RHS == Cond.getOperand(1)) {
+ LHS == Cond.getOperand(0) && RHS == Cond.getOperand(1)) {
ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
- if ((CC == ISD::SETGT && (isNullConstant(RHS) || isOneConstant(RHS))) ||
- (CC == ISD::SETLT && isAllOnesConstant(RHS))) {
- ISD::CondCode NewCC = CC == ISD::SETGT ? ISD::SETGE : ISD::SETLE;
+ if ((CC == ISD::SETGT && (isNullConstant(RHS) || isOneConstant(RHS))) ||
+ (CC == ISD::SETLT && isAllOnesConstant(RHS))) {
+ ISD::CondCode NewCC = CC == ISD::SETGT ? ISD::SETGE : ISD::SETLE;
Cond = DAG.getSetCC(SDLoc(Cond), Cond.getValueType(),
Cond.getOperand(0), Cond.getOperand(1), NewCC);
return DAG.getSelect(DL, VT, Cond, LHS, RHS);
}
- if (CC == ISD::SETUGT && isOneConstant(RHS)) {
- ISD::CondCode NewCC = ISD::SETUGE;
- Cond = DAG.getSetCC(SDLoc(Cond), Cond.getValueType(),
- Cond.getOperand(0), Cond.getOperand(1), NewCC);
- return DAG.getSelect(DL, VT, Cond, LHS, RHS);
+ if (CC == ISD::SETUGT && isOneConstant(RHS)) {
+ ISD::CondCode NewCC = ISD::SETUGE;
+ Cond = DAG.getSetCC(SDLoc(Cond), Cond.getValueType(),
+ Cond.getOperand(0), Cond.getOperand(1), NewCC);
+ return DAG.getSelect(DL, VT, Cond, LHS, RHS);
}
}
@@ -41466,18 +41466,18 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
return V;
// select(~Cond, X, Y) -> select(Cond, Y, X)
- if (CondVT.getScalarType() != MVT::i1) {
+ if (CondVT.getScalarType() != MVT::i1) {
if (SDValue CondNot = IsNOT(Cond, DAG))
return DAG.getNode(N->getOpcode(), DL, VT,
DAG.getBitcast(CondVT, CondNot), RHS, LHS);
- // pcmpgt(X, -1) -> pcmpgt(0, X) to help select/blendv just use the signbit.
- if (Cond.getOpcode() == X86ISD::PCMPGT && Cond.hasOneUse() &&
- ISD::isBuildVectorAllOnes(Cond.getOperand(1).getNode())) {
- Cond = DAG.getNode(X86ISD::PCMPGT, DL, CondVT,
- DAG.getConstant(0, DL, CondVT), Cond.getOperand(0));
- return DAG.getNode(N->getOpcode(), DL, VT, Cond, RHS, LHS);
- }
- }
+ // pcmpgt(X, -1) -> pcmpgt(0, X) to help select/blendv just use the signbit.
+ if (Cond.getOpcode() == X86ISD::PCMPGT && Cond.hasOneUse() &&
+ ISD::isBuildVectorAllOnes(Cond.getOperand(1).getNode())) {
+ Cond = DAG.getNode(X86ISD::PCMPGT, DL, CondVT,
+ DAG.getConstant(0, DL, CondVT), Cond.getOperand(0));
+ return DAG.getNode(N->getOpcode(), DL, VT, Cond, RHS, LHS);
+ }
+ }
// Try to optimize vXi1 selects if both operands are either all constants or
// bitcasts from scalar integer type. In that case we can convert the operands
@@ -43094,116 +43094,116 @@ static SDValue combineShiftRightLogical(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
-static SDValue combineHorizOpWithShuffle(SDNode *N, SelectionDAG &DAG,
- const X86Subtarget &Subtarget) {
+static SDValue combineHorizOpWithShuffle(SDNode *N, SelectionDAG &DAG,
+ const X86Subtarget &Subtarget) {
unsigned Opcode = N->getOpcode();
- assert((X86ISD::HADD == Opcode || X86ISD::FHADD == Opcode ||
- X86ISD::HSUB == Opcode || X86ISD::FHSUB == Opcode ||
- X86ISD::PACKSS == Opcode || X86ISD::PACKUS == Opcode) &&
- "Unexpected hadd/hsub/pack opcode");
+ assert((X86ISD::HADD == Opcode || X86ISD::FHADD == Opcode ||
+ X86ISD::HSUB == Opcode || X86ISD::FHSUB == Opcode ||
+ X86ISD::PACKSS == Opcode || X86ISD::PACKUS == Opcode) &&
+ "Unexpected hadd/hsub/pack opcode");
EVT VT = N->getValueType(0);
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
- EVT SrcVT = N0.getValueType();
+ EVT SrcVT = N0.getValueType();
- // Attempt to fold HOP(LOSUBVECTOR(SHUFFLE(X)),HISUBVECTOR(SHUFFLE(X)))
- // to SHUFFLE(HOP(LOSUBVECTOR(X),HISUBVECTOR(X))), this is mainly for
+ // Attempt to fold HOP(LOSUBVECTOR(SHUFFLE(X)),HISUBVECTOR(SHUFFLE(X)))
+ // to SHUFFLE(HOP(LOSUBVECTOR(X),HISUBVECTOR(X))), this is mainly for
// truncation trees that help us avoid lane crossing shuffles.
// TODO: There's a lot more we can do for PACK/HADD style shuffle combines.
- // TODO: We don't handle vXf64 shuffles yet.
+ // TODO: We don't handle vXf64 shuffles yet.
if (N0.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
N1.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
N0.getConstantOperandAPInt(1) == 0 &&
- N1.getConstantOperandAPInt(1) == SrcVT.getVectorNumElements() &&
+ N1.getConstantOperandAPInt(1) == SrcVT.getVectorNumElements() &&
N0.getOperand(0) == N1.getOperand(0) && VT.is128BitVector() &&
- N0.getOperand(0).getValueType().is256BitVector() &&
- SrcVT.getScalarSizeInBits() <= 32) {
+ N0.getOperand(0).getValueType().is256BitVector() &&
+ SrcVT.getScalarSizeInBits() <= 32) {
// TODO - support target/faux shuffles.
SDValue Vec = peekThroughBitcasts(N0.getOperand(0));
if (auto *SVN = dyn_cast<ShuffleVectorSDNode>(Vec)) {
- // To keep the HOP LHS/RHS coherency, we must be able to scale the unary
+ // To keep the HOP LHS/RHS coherency, we must be able to scale the unary
// shuffle to a vXi64 width - we can probably relax this in the future.
SmallVector<int, 4> ShuffleMask;
if (SVN->getOperand(1).isUndef() &&
scaleShuffleElements(SVN->getMask(), 4, ShuffleMask)) {
SDLoc DL(N);
SDValue Lo, Hi;
- MVT ShufVT = VT.isFloatingPoint() ? MVT::v4f32 : MVT::v4i32;
+ MVT ShufVT = VT.isFloatingPoint() ? MVT::v4f32 : MVT::v4i32;
std::tie(Lo, Hi) = DAG.SplitVector(SVN->getOperand(0), DL);
Lo = DAG.getBitcast(N0.getValueType(), Lo);
Hi = DAG.getBitcast(N1.getValueType(), Hi);
SDValue Res = DAG.getNode(Opcode, DL, VT, Lo, Hi);
- Res = DAG.getBitcast(ShufVT, Res);
- Res = DAG.getVectorShuffle(ShufVT, DL, Res, Res, ShuffleMask);
+ Res = DAG.getBitcast(ShufVT, Res);
+ Res = DAG.getVectorShuffle(ShufVT, DL, Res, Res, ShuffleMask);
return DAG.getBitcast(VT, Res);
}
}
}
- // Attempt to fold HOP(SHUFFLE(X),SHUFFLE(Y)) -> SHUFFLE(HOP(X,Y)).
- // TODO: Merge with binary shuffle folds below.
- if (VT.is128BitVector() && SrcVT.getScalarSizeInBits() <= 32) {
- int PostShuffle[4] = {0, 1, 2, 3};
-
- // If the op is an unary shuffle that can scale to v2x64,
- // then we can perform this as a v4x32 post shuffle.
- auto AdjustOp = [&](SDValue V, int Offset) {
- auto *SVN = dyn_cast<ShuffleVectorSDNode>(V);
- SmallVector<int, 2> ScaledMask;
- if (!SVN || !SVN->getOperand(1).isUndef() ||
- !scaleShuffleElements(SVN->getMask(), 2, ScaledMask) ||
- !N->isOnlyUserOf(V.getNode()))
- return SDValue();
- PostShuffle[Offset + 0] = ScaledMask[0] < 0 ? -1 : Offset + ScaledMask[0];
- PostShuffle[Offset + 1] = ScaledMask[1] < 0 ? -1 : Offset + ScaledMask[1];
- return SVN->getOperand(0);
- };
-
- SDValue Src0 = AdjustOp(N0, 0);
- SDValue Src1 = AdjustOp(N1, 2);
- if (Src0 || Src1) {
- Src0 = Src0 ? Src0 : N0;
- Src1 = Src1 ? Src1 : N1;
- SDLoc DL(N);
- MVT ShufVT = VT.isFloatingPoint() ? MVT::v4f32 : MVT::v4i32;
- SDValue Res = DAG.getNode(Opcode, DL, VT, Src0, Src1);
- Res = DAG.getBitcast(ShufVT, Res);
- Res = DAG.getVectorShuffle(ShufVT, DL, Res, Res, PostShuffle);
- return DAG.getBitcast(VT, Res);
- }
- }
-
- // Attempt to fold HOP(SHUFFLE(X,Y),SHUFFLE(X,Y)) -> SHUFFLE(HOP(X,Y)).
+ // Attempt to fold HOP(SHUFFLE(X),SHUFFLE(Y)) -> SHUFFLE(HOP(X,Y)).
+ // TODO: Merge with binary shuffle folds below.
+ if (VT.is128BitVector() && SrcVT.getScalarSizeInBits() <= 32) {
+ int PostShuffle[4] = {0, 1, 2, 3};
+
+ // If the op is an unary shuffle that can scale to v2x64,
+ // then we can perform this as a v4x32 post shuffle.
+ auto AdjustOp = [&](SDValue V, int Offset) {
+ auto *SVN = dyn_cast<ShuffleVectorSDNode>(V);
+ SmallVector<int, 2> ScaledMask;
+ if (!SVN || !SVN->getOperand(1).isUndef() ||
+ !scaleShuffleElements(SVN->getMask(), 2, ScaledMask) ||
+ !N->isOnlyUserOf(V.getNode()))
+ return SDValue();
+ PostShuffle[Offset + 0] = ScaledMask[0] < 0 ? -1 : Offset + ScaledMask[0];
+ PostShuffle[Offset + 1] = ScaledMask[1] < 0 ? -1 : Offset + ScaledMask[1];
+ return SVN->getOperand(0);
+ };
+
+ SDValue Src0 = AdjustOp(N0, 0);
+ SDValue Src1 = AdjustOp(N1, 2);
+ if (Src0 || Src1) {
+ Src0 = Src0 ? Src0 : N0;
+ Src1 = Src1 ? Src1 : N1;
+ SDLoc DL(N);
+ MVT ShufVT = VT.isFloatingPoint() ? MVT::v4f32 : MVT::v4i32;
+ SDValue Res = DAG.getNode(Opcode, DL, VT, Src0, Src1);
+ Res = DAG.getBitcast(ShufVT, Res);
+ Res = DAG.getVectorShuffle(ShufVT, DL, Res, Res, PostShuffle);
+ return DAG.getBitcast(VT, Res);
+ }
+ }
+
+ // Attempt to fold HOP(SHUFFLE(X,Y),SHUFFLE(X,Y)) -> SHUFFLE(HOP(X,Y)).
// TODO: Relax shuffle scaling to support sub-128-bit subvector shuffles.
- if (VT.is256BitVector() && Subtarget.hasInt256()) {
- SmallVector<int> Mask0, Mask1;
- SmallVector<SDValue> Ops0, Ops1;
- if (getTargetShuffleInputs(N0, Ops0, Mask0, DAG) && !isAnyZero(Mask0) &&
- getTargetShuffleInputs(N1, Ops1, Mask1, DAG) && !isAnyZero(Mask1) &&
- !Ops0.empty() && !Ops1.empty()) {
- SDValue Op00 = Ops0.front(), Op01 = Ops0.back();
- SDValue Op10 = Ops1.front(), Op11 = Ops1.back();
- SmallVector<int, 2> ShuffleMask0, ShuffleMask1;
- if (Op00.getValueType() == SrcVT && Op01.getValueType() == SrcVT &&
- Op11.getValueType() == SrcVT && Op11.getValueType() == SrcVT &&
- scaleShuffleElements(Mask0, 2, ShuffleMask0) &&
- scaleShuffleElements(Mask1, 2, ShuffleMask1)) {
- if ((Op00 == Op11) && (Op01 == Op10)) {
- std::swap(Op10, Op11);
- ShuffleVectorSDNode::commuteMask(ShuffleMask1);
+ if (VT.is256BitVector() && Subtarget.hasInt256()) {
+ SmallVector<int> Mask0, Mask1;
+ SmallVector<SDValue> Ops0, Ops1;
+ if (getTargetShuffleInputs(N0, Ops0, Mask0, DAG) && !isAnyZero(Mask0) &&
+ getTargetShuffleInputs(N1, Ops1, Mask1, DAG) && !isAnyZero(Mask1) &&
+ !Ops0.empty() && !Ops1.empty()) {
+ SDValue Op00 = Ops0.front(), Op01 = Ops0.back();
+ SDValue Op10 = Ops1.front(), Op11 = Ops1.back();
+ SmallVector<int, 2> ShuffleMask0, ShuffleMask1;
+ if (Op00.getValueType() == SrcVT && Op01.getValueType() == SrcVT &&
+ Op11.getValueType() == SrcVT && Op11.getValueType() == SrcVT &&
+ scaleShuffleElements(Mask0, 2, ShuffleMask0) &&
+ scaleShuffleElements(Mask1, 2, ShuffleMask1)) {
+ if ((Op00 == Op11) && (Op01 == Op10)) {
+ std::swap(Op10, Op11);
+ ShuffleVectorSDNode::commuteMask(ShuffleMask1);
+ }
+ if ((Op00 == Op10) && (Op01 == Op11)) {
+ SmallVector<int, 4> ShuffleMask;
+ ShuffleMask.append(ShuffleMask0.begin(), ShuffleMask0.end());
+ ShuffleMask.append(ShuffleMask1.begin(), ShuffleMask1.end());
+ SDLoc DL(N);
+ MVT ShufVT = VT.isFloatingPoint() ? MVT::v4f64 : MVT::v4i64;
+ SDValue Res = DAG.getNode(Opcode, DL, VT, Op00, Op01);
+ Res = DAG.getBitcast(ShufVT, Res);
+ Res = DAG.getVectorShuffle(ShufVT, DL, Res, Res, ShuffleMask);
+ return DAG.getBitcast(VT, Res);
}
- if ((Op00 == Op10) && (Op01 == Op11)) {
- SmallVector<int, 4> ShuffleMask;
- ShuffleMask.append(ShuffleMask0.begin(), ShuffleMask0.end());
- ShuffleMask.append(ShuffleMask1.begin(), ShuffleMask1.end());
- SDLoc DL(N);
- MVT ShufVT = VT.isFloatingPoint() ? MVT::v4f64 : MVT::v4i64;
- SDValue Res = DAG.getNode(Opcode, DL, VT, Op00, Op01);
- Res = DAG.getBitcast(ShufVT, Res);
- Res = DAG.getVectorShuffle(ShufVT, DL, Res, Res, ShuffleMask);
- return DAG.getBitcast(VT, Res);
- }
}
}
}
@@ -43285,7 +43285,7 @@ static SDValue combineVectorPack(SDNode *N, SelectionDAG &DAG,
}
// Try to fold PACK(SHUFFLE(),SHUFFLE()) -> SHUFFLE(PACK()).
- if (SDValue V = combineHorizOpWithShuffle(N, DAG, Subtarget))
+ if (SDValue V = combineHorizOpWithShuffle(N, DAG, Subtarget))
return V;
// Try to combine a PACKUSWB/PACKSSWB implemented truncate with a regular
@@ -43307,28 +43307,28 @@ static SDValue combineVectorPack(SDNode *N, SelectionDAG &DAG,
}
}
- // Try to fold PACK(EXTEND(X),EXTEND(Y)) -> CONCAT(X,Y) subvectors.
- if (VT.is128BitVector()) {
- unsigned ExtOpc = IsSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
- SDValue Src0, Src1;
- if (N0.getOpcode() == ExtOpc &&
- N0.getOperand(0).getValueType().is64BitVector() &&
- N0.getOperand(0).getScalarValueSizeInBits() == DstBitsPerElt) {
- Src0 = N0.getOperand(0);
- }
- if (N1.getOpcode() == ExtOpc &&
- N1.getOperand(0).getValueType().is64BitVector() &&
- N1.getOperand(0).getScalarValueSizeInBits() == DstBitsPerElt) {
- Src1 = N1.getOperand(0);
- }
- if ((Src0 || N0.isUndef()) && (Src1 || N1.isUndef())) {
- assert((Src0 || Src1) && "Found PACK(UNDEF,UNDEF)");
- Src0 = Src0 ? Src0 : DAG.getUNDEF(Src1.getValueType());
- Src1 = Src1 ? Src1 : DAG.getUNDEF(Src0.getValueType());
- return DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(N), VT, Src0, Src1);
- }
- }
-
+ // Try to fold PACK(EXTEND(X),EXTEND(Y)) -> CONCAT(X,Y) subvectors.
+ if (VT.is128BitVector()) {
+ unsigned ExtOpc = IsSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
+ SDValue Src0, Src1;
+ if (N0.getOpcode() == ExtOpc &&
+ N0.getOperand(0).getValueType().is64BitVector() &&
+ N0.getOperand(0).getScalarValueSizeInBits() == DstBitsPerElt) {
+ Src0 = N0.getOperand(0);
+ }
+ if (N1.getOpcode() == ExtOpc &&
+ N1.getOperand(0).getValueType().is64BitVector() &&
+ N1.getOperand(0).getScalarValueSizeInBits() == DstBitsPerElt) {
+ Src1 = N1.getOperand(0);
+ }
+ if ((Src0 || N0.isUndef()) && (Src1 || N1.isUndef())) {
+ assert((Src0 || Src1) && "Found PACK(UNDEF,UNDEF)");
+ Src0 = Src0 ? Src0 : DAG.getUNDEF(Src1.getValueType());
+ Src1 = Src1 ? Src1 : DAG.getUNDEF(Src0.getValueType());
+ return DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(N), VT, Src0, Src1);
+ }
+ }
+
// Attempt to combine as shuffle.
SDValue Op(N, 0);
if (SDValue Res = combineX86ShufflesRecursively(Op, DAG, Subtarget))
@@ -43337,20 +43337,20 @@ static SDValue combineVectorPack(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
-static SDValue combineVectorHADDSUB(SDNode *N, SelectionDAG &DAG,
- TargetLowering::DAGCombinerInfo &DCI,
- const X86Subtarget &Subtarget) {
- assert((X86ISD::HADD == N->getOpcode() || X86ISD::FHADD == N->getOpcode() ||
- X86ISD::HSUB == N->getOpcode() || X86ISD::FHSUB == N->getOpcode()) &&
- "Unexpected horizontal add/sub opcode");
-
- // Try to fold HOP(SHUFFLE(),SHUFFLE()) -> SHUFFLE(HOP()).
- if (SDValue V = combineHorizOpWithShuffle(N, DAG, Subtarget))
- return V;
-
- return SDValue();
-}
-
+static SDValue combineVectorHADDSUB(SDNode *N, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI,
+ const X86Subtarget &Subtarget) {
+ assert((X86ISD::HADD == N->getOpcode() || X86ISD::FHADD == N->getOpcode() ||
+ X86ISD::HSUB == N->getOpcode() || X86ISD::FHSUB == N->getOpcode()) &&
+ "Unexpected horizontal add/sub opcode");
+
+ // Try to fold HOP(SHUFFLE(),SHUFFLE()) -> SHUFFLE(HOP()).
+ if (SDValue V = combineHorizOpWithShuffle(N, DAG, Subtarget))
+ return V;
+
+ return SDValue();
+}
+
static SDValue combineVectorShiftVar(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const X86Subtarget &Subtarget) {
@@ -44139,7 +44139,7 @@ static SDValue combineAnd(SDNode *N, SelectionDAG &DAG,
if (VT == SrcVecVT.getScalarType() &&
N->getOperand(0)->isOnlyUserOf(SrcVec.getNode()) &&
getTargetConstantBitsFromNode(BitMask, 8, UndefElts, EltBits) &&
- llvm::all_of(EltBits, [](const APInt &M) {
+ llvm::all_of(EltBits, [](const APInt &M) {
return M.isNullValue() || M.isAllOnesValue();
})) {
unsigned NumElts = SrcVecVT.getVectorNumElements();
@@ -44158,7 +44158,7 @@ static SDValue combineAnd(SDNode *N, SelectionDAG &DAG,
if (SDValue Shuffle = combineX86ShufflesRecursively(
{SrcVec}, 0, SrcVec, ShuffleMask, {}, /*Depth*/ 1,
- X86::MaxShuffleCombineDepth,
+ X86::MaxShuffleCombineDepth,
/*HasVarMask*/ false, /*AllowVarMask*/ true, DAG, Subtarget))
return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N), VT, Shuffle,
N->getOperand(0).getOperand(1));
@@ -44826,13 +44826,13 @@ static SDValue detectAVGPattern(SDValue In, EVT VT, SelectionDAG &DAG,
unsigned NumElems = VT.getVectorNumElements();
EVT ScalarVT = VT.getVectorElementType();
- if (!((ScalarVT == MVT::i8 || ScalarVT == MVT::i16) && NumElems >= 2))
+ if (!((ScalarVT == MVT::i8 || ScalarVT == MVT::i16) && NumElems >= 2))
return SDValue();
// InScalarVT is the intermediate type in AVG pattern and it should be greater
// than the original input type (i8/i16).
EVT InScalarVT = InVT.getVectorElementType();
- if (InScalarVT.getFixedSizeInBits() <= ScalarVT.getFixedSizeInBits())
+ if (InScalarVT.getFixedSizeInBits() <= ScalarVT.getFixedSizeInBits())
return SDValue();
if (!Subtarget.hasSSE2())
@@ -44860,8 +44860,8 @@ static SDValue detectAVGPattern(SDValue In, EVT VT, SelectionDAG &DAG,
};
// Check if each element of the vector is right-shifted by one.
- SDValue LHS = In.getOperand(0);
- SDValue RHS = In.getOperand(1);
+ SDValue LHS = In.getOperand(0);
+ SDValue RHS = In.getOperand(1);
if (!IsConstVectorInRange(RHS, 1, 1))
return SDValue();
if (LHS.getOpcode() != ISD::ADD)
@@ -44877,29 +44877,29 @@ static SDValue detectAVGPattern(SDValue In, EVT VT, SelectionDAG &DAG,
return DAG.getNode(X86ISD::AVG, DL, Ops[0].getValueType(), Ops);
};
- auto AVGSplitter = [&](SDValue Op0, SDValue Op1) {
- // Pad to a power-of-2 vector, split+apply and extract the original vector.
- unsigned NumElemsPow2 = PowerOf2Ceil(NumElems);
- EVT Pow2VT = EVT::getVectorVT(*DAG.getContext(), ScalarVT, NumElemsPow2);
- if (NumElemsPow2 != NumElems) {
- SmallVector<SDValue, 32> Ops0(NumElemsPow2, DAG.getUNDEF(ScalarVT));
- SmallVector<SDValue, 32> Ops1(NumElemsPow2, DAG.getUNDEF(ScalarVT));
- for (unsigned i = 0; i != NumElems; ++i) {
- SDValue Idx = DAG.getIntPtrConstant(i, DL);
- Ops0[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ScalarVT, Op0, Idx);
- Ops1[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ScalarVT, Op1, Idx);
- }
- Op0 = DAG.getBuildVector(Pow2VT, DL, Ops0);
- Op1 = DAG.getBuildVector(Pow2VT, DL, Ops1);
- }
- SDValue Res =
- SplitOpsAndApply(DAG, Subtarget, DL, Pow2VT, {Op0, Op1}, AVGBuilder);
- if (NumElemsPow2 == NumElems)
- return Res;
- return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, Res,
- DAG.getIntPtrConstant(0, DL));
- };
-
+ auto AVGSplitter = [&](SDValue Op0, SDValue Op1) {
+ // Pad to a power-of-2 vector, split+apply and extract the original vector.
+ unsigned NumElemsPow2 = PowerOf2Ceil(NumElems);
+ EVT Pow2VT = EVT::getVectorVT(*DAG.getContext(), ScalarVT, NumElemsPow2);
+ if (NumElemsPow2 != NumElems) {
+ SmallVector<SDValue, 32> Ops0(NumElemsPow2, DAG.getUNDEF(ScalarVT));
+ SmallVector<SDValue, 32> Ops1(NumElemsPow2, DAG.getUNDEF(ScalarVT));
+ for (unsigned i = 0; i != NumElems; ++i) {
+ SDValue Idx = DAG.getIntPtrConstant(i, DL);
+ Ops0[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ScalarVT, Op0, Idx);
+ Ops1[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ScalarVT, Op1, Idx);
+ }
+ Op0 = DAG.getBuildVector(Pow2VT, DL, Ops0);
+ Op1 = DAG.getBuildVector(Pow2VT, DL, Ops1);
+ }
+ SDValue Res =
+ SplitOpsAndApply(DAG, Subtarget, DL, Pow2VT, {Op0, Op1}, AVGBuilder);
+ if (NumElemsPow2 == NumElems)
+ return Res;
+ return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, Res,
+ DAG.getIntPtrConstant(0, DL));
+ };
+
// Take care of the case when one of the operands is a constant vector whose
// element is in the range [1, 256].
if (IsConstVectorInRange(Operands[1], 1, ScalarVT == MVT::i8 ? 256 : 65536) &&
@@ -44910,7 +44910,7 @@ static SDValue detectAVGPattern(SDValue In, EVT VT, SelectionDAG &DAG,
SDValue VecOnes = DAG.getConstant(1, DL, InVT);
Operands[1] = DAG.getNode(ISD::SUB, DL, InVT, Operands[1], VecOnes);
Operands[1] = DAG.getNode(ISD::TRUNCATE, DL, VT, Operands[1]);
- return AVGSplitter(Operands[0].getOperand(0), Operands[1]);
+ return AVGSplitter(Operands[0].getOperand(0), Operands[1]);
}
// Matches 'add like' patterns: add(Op0,Op1) + zext(or(Op0,Op1)).
@@ -44957,7 +44957,7 @@ static SDValue detectAVGPattern(SDValue In, EVT VT, SelectionDAG &DAG,
}
// The pattern is detected, emit X86ISD::AVG instruction(s).
- return AVGSplitter(Operands[0], Operands[1]);
+ return AVGSplitter(Operands[0], Operands[1]);
}
return SDValue();
@@ -44990,8 +44990,8 @@ static SDValue combineLoad(SDNode *N, SelectionDAG &DAG,
unsigned HalfOffset = 16;
SDValue Ptr1 = Ld->getBasePtr();
- SDValue Ptr2 =
- DAG.getMemBasePlusOffset(Ptr1, TypeSize::Fixed(HalfOffset), dl);
+ SDValue Ptr2 =
+ DAG.getMemBasePlusOffset(Ptr1, TypeSize::Fixed(HalfOffset), dl);
EVT HalfVT = EVT::getVectorVT(*DAG.getContext(), MemVT.getScalarType(),
NumElems / 2);
SDValue Load1 =
@@ -45025,29 +45025,29 @@ static SDValue combineLoad(SDNode *N, SelectionDAG &DAG,
}
}
- // If we also broadcast this as a subvector to a wider type, then just extract
- // the lowest subvector.
- if (Ext == ISD::NON_EXTLOAD && Subtarget.hasAVX() && Ld->isSimple() &&
- (RegVT.is128BitVector() || RegVT.is256BitVector())) {
- SDValue Ptr = Ld->getBasePtr();
- SDValue Chain = Ld->getChain();
- for (SDNode *User : Ptr->uses()) {
- if (User != N && User->getOpcode() == X86ISD::SUBV_BROADCAST_LOAD &&
- cast<MemIntrinsicSDNode>(User)->getBasePtr() == Ptr &&
- cast<MemIntrinsicSDNode>(User)->getChain() == Chain &&
- cast<MemIntrinsicSDNode>(User)->getMemoryVT().getSizeInBits() ==
- MemVT.getSizeInBits() &&
- !User->hasAnyUseOfValue(1) &&
- User->getValueSizeInBits(0).getFixedSize() >
- RegVT.getFixedSizeInBits()) {
- SDValue Extract = extractSubVector(SDValue(User, 0), 0, DAG, SDLoc(N),
- RegVT.getSizeInBits());
- Extract = DAG.getBitcast(RegVT, Extract);
- return DCI.CombineTo(N, Extract, SDValue(User, 1));
- }
- }
- }
-
+ // If we also broadcast this as a subvector to a wider type, then just extract
+ // the lowest subvector.
+ if (Ext == ISD::NON_EXTLOAD && Subtarget.hasAVX() && Ld->isSimple() &&
+ (RegVT.is128BitVector() || RegVT.is256BitVector())) {
+ SDValue Ptr = Ld->getBasePtr();
+ SDValue Chain = Ld->getChain();
+ for (SDNode *User : Ptr->uses()) {
+ if (User != N && User->getOpcode() == X86ISD::SUBV_BROADCAST_LOAD &&
+ cast<MemIntrinsicSDNode>(User)->getBasePtr() == Ptr &&
+ cast<MemIntrinsicSDNode>(User)->getChain() == Chain &&
+ cast<MemIntrinsicSDNode>(User)->getMemoryVT().getSizeInBits() ==
+ MemVT.getSizeInBits() &&
+ !User->hasAnyUseOfValue(1) &&
+ User->getValueSizeInBits(0).getFixedSize() >
+ RegVT.getFixedSizeInBits()) {
+ SDValue Extract = extractSubVector(SDValue(User, 0), 0, DAG, SDLoc(N),
+ RegVT.getSizeInBits());
+ Extract = DAG.getBitcast(RegVT, Extract);
+ return DCI.CombineTo(N, Extract, SDValue(User, 1));
+ }
+ }
+ }
+
// Cast ptr32 and ptr64 pointers to the default address space before a load.
unsigned AddrSpace = Ld->getAddressSpace();
if (AddrSpace == X86AS::PTR64 || AddrSpace == X86AS::PTR32_SPTR ||
@@ -45089,7 +45089,7 @@ static int getOneTrueElt(SDValue V) {
auto *ConstNode = dyn_cast<ConstantSDNode>(Op);
if (!ConstNode)
return -1;
- if (ConstNode->getAPIntValue().countTrailingOnes() >= 1) {
+ if (ConstNode->getAPIntValue().countTrailingOnes() >= 1) {
// If we already found a one, this is too many.
if (TrueIndex >= 0)
return -1;
@@ -45105,8 +45105,8 @@ static int getOneTrueElt(SDValue V) {
/// scalar element, and the alignment for the scalar memory access.
static bool getParamsForOneTrueMaskedElt(MaskedLoadStoreSDNode *MaskedOp,
SelectionDAG &DAG, SDValue &Addr,
- SDValue &Index, Align &Alignment,
- unsigned &Offset) {
+ SDValue &Index, Align &Alignment,
+ unsigned &Offset) {
int TrueMaskElt = getOneTrueElt(MaskedOp->getMask());
if (TrueMaskElt < 0)
return false;
@@ -45114,17 +45114,17 @@ static bool getParamsForOneTrueMaskedElt(MaskedLoadStoreSDNode *MaskedOp,
// Get the address of the one scalar element that is specified by the mask
// using the appropriate offset from the base pointer.
EVT EltVT = MaskedOp->getMemoryVT().getVectorElementType();
- Offset = 0;
+ Offset = 0;
Addr = MaskedOp->getBasePtr();
if (TrueMaskElt != 0) {
- Offset = TrueMaskElt * EltVT.getStoreSize();
- Addr = DAG.getMemBasePlusOffset(Addr, TypeSize::Fixed(Offset),
- SDLoc(MaskedOp));
+ Offset = TrueMaskElt * EltVT.getStoreSize();
+ Addr = DAG.getMemBasePlusOffset(Addr, TypeSize::Fixed(Offset),
+ SDLoc(MaskedOp));
}
Index = DAG.getIntPtrConstant(TrueMaskElt, SDLoc(MaskedOp));
- Alignment = commonAlignment(MaskedOp->getOriginalAlign(),
- EltVT.getStoreSize());
+ Alignment = commonAlignment(MaskedOp->getOriginalAlign(),
+ EltVT.getStoreSize());
return true;
}
@@ -45134,17 +45134,17 @@ static bool getParamsForOneTrueMaskedElt(MaskedLoadStoreSDNode *MaskedOp,
/// mask have already been optimized in IR, so we don't bother with those here.
static SDValue
reduceMaskedLoadToScalarLoad(MaskedLoadSDNode *ML, SelectionDAG &DAG,
- TargetLowering::DAGCombinerInfo &DCI,
- const X86Subtarget &Subtarget) {
+ TargetLowering::DAGCombinerInfo &DCI,
+ const X86Subtarget &Subtarget) {
assert(ML->isUnindexed() && "Unexpected indexed masked load!");
// TODO: This is not x86-specific, so it could be lifted to DAGCombiner.
// However, some target hooks may need to be added to know when the transform
// is profitable. Endianness would also have to be considered.
SDValue Addr, VecIndex;
- Align Alignment;
- unsigned Offset;
- if (!getParamsForOneTrueMaskedElt(ML, DAG, Addr, VecIndex, Alignment, Offset))
+ Align Alignment;
+ unsigned Offset;
+ if (!getParamsForOneTrueMaskedElt(ML, DAG, Addr, VecIndex, Alignment, Offset))
return SDValue();
// Load the one scalar element that is specified by the mask using the
@@ -45152,25 +45152,25 @@ reduceMaskedLoadToScalarLoad(MaskedLoadSDNode *ML, SelectionDAG &DAG,
SDLoc DL(ML);
EVT VT = ML->getValueType(0);
EVT EltVT = VT.getVectorElementType();
-
- EVT CastVT = VT;
- if (EltVT == MVT::i64 && !Subtarget.is64Bit()) {
- EltVT = MVT::f64;
- CastVT =
- EVT::getVectorVT(*DAG.getContext(), EltVT, VT.getVectorNumElements());
- }
-
+
+ EVT CastVT = VT;
+ if (EltVT == MVT::i64 && !Subtarget.is64Bit()) {
+ EltVT = MVT::f64;
+ CastVT =
+ EVT::getVectorVT(*DAG.getContext(), EltVT, VT.getVectorNumElements());
+ }
+
SDValue Load =
- DAG.getLoad(EltVT, DL, ML->getChain(), Addr,
- ML->getPointerInfo().getWithOffset(Offset),
+ DAG.getLoad(EltVT, DL, ML->getChain(), Addr,
+ ML->getPointerInfo().getWithOffset(Offset),
Alignment, ML->getMemOperand()->getFlags());
- SDValue PassThru = DAG.getBitcast(CastVT, ML->getPassThru());
-
+ SDValue PassThru = DAG.getBitcast(CastVT, ML->getPassThru());
+
// Insert the loaded element into the appropriate place in the vector.
- SDValue Insert =
- DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, CastVT, PassThru, Load, VecIndex);
- Insert = DAG.getBitcast(VT, Insert);
+ SDValue Insert =
+ DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, CastVT, PassThru, Load, VecIndex);
+ Insert = DAG.getBitcast(VT, Insert);
return DCI.CombineTo(ML, Insert, Load.getValue(1), true);
}
@@ -45233,8 +45233,8 @@ static SDValue combineMaskedLoad(SDNode *N, SelectionDAG &DAG,
return SDValue();
if (Mld->getExtensionType() == ISD::NON_EXTLOAD) {
- if (SDValue ScalarLoad =
- reduceMaskedLoadToScalarLoad(Mld, DAG, DCI, Subtarget))
+ if (SDValue ScalarLoad =
+ reduceMaskedLoadToScalarLoad(Mld, DAG, DCI, Subtarget))
return ScalarLoad;
// TODO: Do some AVX512 subsets benefit from this transform?
@@ -45271,35 +45271,35 @@ static SDValue combineMaskedLoad(SDNode *N, SelectionDAG &DAG,
/// Note: It is expected that the degenerate cases of an all-zeros or all-ones
/// mask have already been optimized in IR, so we don't bother with those here.
static SDValue reduceMaskedStoreToScalarStore(MaskedStoreSDNode *MS,
- SelectionDAG &DAG,
- const X86Subtarget &Subtarget) {
+ SelectionDAG &DAG,
+ const X86Subtarget &Subtarget) {
// TODO: This is not x86-specific, so it could be lifted to DAGCombiner.
// However, some target hooks may need to be added to know when the transform
// is profitable. Endianness would also have to be considered.
SDValue Addr, VecIndex;
- Align Alignment;
- unsigned Offset;
- if (!getParamsForOneTrueMaskedElt(MS, DAG, Addr, VecIndex, Alignment, Offset))
+ Align Alignment;
+ unsigned Offset;
+ if (!getParamsForOneTrueMaskedElt(MS, DAG, Addr, VecIndex, Alignment, Offset))
return SDValue();
// Extract the one scalar element that is actually being stored.
SDLoc DL(MS);
- SDValue Value = MS->getValue();
- EVT VT = Value.getValueType();
+ SDValue Value = MS->getValue();
+ EVT VT = Value.getValueType();
EVT EltVT = VT.getVectorElementType();
- if (EltVT == MVT::i64 && !Subtarget.is64Bit()) {
- EltVT = MVT::f64;
- EVT CastVT =
- EVT::getVectorVT(*DAG.getContext(), EltVT, VT.getVectorNumElements());
- Value = DAG.getBitcast(CastVT, Value);
- }
- SDValue Extract =
- DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT, Value, VecIndex);
+ if (EltVT == MVT::i64 && !Subtarget.is64Bit()) {
+ EltVT = MVT::f64;
+ EVT CastVT =
+ EVT::getVectorVT(*DAG.getContext(), EltVT, VT.getVectorNumElements());
+ Value = DAG.getBitcast(CastVT, Value);
+ }
+ SDValue Extract =
+ DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT, Value, VecIndex);
// Store that element at the appropriate offset from the base pointer.
- return DAG.getStore(MS->getChain(), DL, Extract, Addr,
- MS->getPointerInfo().getWithOffset(Offset),
+ return DAG.getStore(MS->getChain(), DL, Extract, Addr,
+ MS->getPointerInfo().getWithOffset(Offset),
Alignment, MS->getMemOperand()->getFlags());
}
@@ -45317,7 +45317,7 @@ static SDValue combineMaskedStore(SDNode *N, SelectionDAG &DAG,
if (Mst->isTruncatingStore())
return SDValue();
- if (SDValue ScalarStore = reduceMaskedStoreToScalarStore(Mst, DAG, Subtarget))
+ if (SDValue ScalarStore = reduceMaskedStoreToScalarStore(Mst, DAG, Subtarget))
return ScalarStore;
// If the mask value has been legalized to a non-boolean vector, try to
@@ -45378,21 +45378,21 @@ static SDValue combineStore(SDNode *N, SelectionDAG &DAG,
if (VT == MVT::v1i1 && VT == StVT && Subtarget.hasAVX512() &&
StoredVal.getOpcode() == ISD::SCALAR_TO_VECTOR &&
StoredVal.getOperand(0).getValueType() == MVT::i8) {
- SDValue Val = StoredVal.getOperand(0);
- // We must store zeros to the unused bits.
- Val = DAG.getZeroExtendInReg(Val, dl, MVT::i1);
- return DAG.getStore(St->getChain(), dl, Val,
+ SDValue Val = StoredVal.getOperand(0);
+ // We must store zeros to the unused bits.
+ Val = DAG.getZeroExtendInReg(Val, dl, MVT::i1);
+ return DAG.getStore(St->getChain(), dl, Val,
St->getBasePtr(), St->getPointerInfo(),
St->getOriginalAlign(),
St->getMemOperand()->getFlags());
}
// Widen v2i1/v4i1 stores to v8i1.
- if ((VT == MVT::v1i1 || VT == MVT::v2i1 || VT == MVT::v4i1) && VT == StVT &&
+ if ((VT == MVT::v1i1 || VT == MVT::v2i1 || VT == MVT::v4i1) && VT == StVT &&
Subtarget.hasAVX512()) {
unsigned NumConcats = 8 / VT.getVectorNumElements();
- // We must store zeros to the unused bits.
- SmallVector<SDValue, 4> Ops(NumConcats, DAG.getConstant(0, dl, VT));
+ // We must store zeros to the unused bits.
+ SmallVector<SDValue, 4> Ops(NumConcats, DAG.getConstant(0, dl, VT));
Ops[0] = StoredVal;
StoredVal = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v8i1, Ops);
return DAG.getStore(St->getChain(), dl, StoredVal, St->getBasePtr(),
@@ -45414,7 +45414,7 @@ static SDValue combineStore(SDNode *N, SelectionDAG &DAG,
Hi = combinevXi1ConstantToInteger(Hi, DAG);
SDValue Ptr0 = St->getBasePtr();
- SDValue Ptr1 = DAG.getMemBasePlusOffset(Ptr0, TypeSize::Fixed(4), dl);
+ SDValue Ptr1 = DAG.getMemBasePlusOffset(Ptr0, TypeSize::Fixed(4), dl);
SDValue Ch0 =
DAG.getStore(St->getChain(), dl, Lo, Ptr0, St->getPointerInfo(),
@@ -45493,36 +45493,36 @@ static SDValue combineStore(SDNode *N, SelectionDAG &DAG,
VT, St->getMemOperand(), DAG);
}
- // Try to fold a extract_element(VTRUNC) pattern into a truncating store.
- if (!St->isTruncatingStore() && StoredVal.hasOneUse()) {
- auto IsExtractedElement = [](SDValue V) {
- if (V.getOpcode() == ISD::TRUNCATE && V.getOperand(0).hasOneUse())
- V = V.getOperand(0);
- unsigned Opc = V.getOpcode();
- if (Opc == ISD::EXTRACT_VECTOR_ELT || Opc == X86ISD::PEXTRW) {
- if (V.getOperand(0).hasOneUse() && isNullConstant(V.getOperand(1)))
- return V.getOperand(0);
- }
- return SDValue();
- };
- if (SDValue Extract = IsExtractedElement(StoredVal)) {
- SDValue Trunc = peekThroughOneUseBitcasts(Extract);
- if (Trunc.getOpcode() == X86ISD::VTRUNC) {
- SDValue Src = Trunc.getOperand(0);
- MVT DstVT = Trunc.getSimpleValueType();
- MVT SrcVT = Src.getSimpleValueType();
- unsigned NumSrcElts = SrcVT.getVectorNumElements();
- unsigned NumTruncBits = DstVT.getScalarSizeInBits() * NumSrcElts;
- MVT TruncVT = MVT::getVectorVT(DstVT.getScalarType(), NumSrcElts);
- if (NumTruncBits == VT.getSizeInBits() &&
- TLI.isTruncStoreLegal(SrcVT, TruncVT)) {
- return DAG.getTruncStore(St->getChain(), dl, Src, St->getBasePtr(),
- TruncVT, St->getMemOperand());
- }
- }
- }
- }
-
+ // Try to fold a extract_element(VTRUNC) pattern into a truncating store.
+ if (!St->isTruncatingStore() && StoredVal.hasOneUse()) {
+ auto IsExtractedElement = [](SDValue V) {
+ if (V.getOpcode() == ISD::TRUNCATE && V.getOperand(0).hasOneUse())
+ V = V.getOperand(0);
+ unsigned Opc = V.getOpcode();
+ if (Opc == ISD::EXTRACT_VECTOR_ELT || Opc == X86ISD::PEXTRW) {
+ if (V.getOperand(0).hasOneUse() && isNullConstant(V.getOperand(1)))
+ return V.getOperand(0);
+ }
+ return SDValue();
+ };
+ if (SDValue Extract = IsExtractedElement(StoredVal)) {
+ SDValue Trunc = peekThroughOneUseBitcasts(Extract);
+ if (Trunc.getOpcode() == X86ISD::VTRUNC) {
+ SDValue Src = Trunc.getOperand(0);
+ MVT DstVT = Trunc.getSimpleValueType();
+ MVT SrcVT = Src.getSimpleValueType();
+ unsigned NumSrcElts = SrcVT.getVectorNumElements();
+ unsigned NumTruncBits = DstVT.getScalarSizeInBits() * NumSrcElts;
+ MVT TruncVT = MVT::getVectorVT(DstVT.getScalarType(), NumSrcElts);
+ if (NumTruncBits == VT.getSizeInBits() &&
+ TLI.isTruncStoreLegal(SrcVT, TruncVT)) {
+ return DAG.getTruncStore(St->getChain(), dl, Src, St->getBasePtr(),
+ TruncVT, St->getMemOperand());
+ }
+ }
+ }
+ }
+
// Optimize trunc store (of multiple scalars) to shuffle and store.
// First, pack all of the elements in one place. Next, store to memory
// in fewer chunks.
@@ -45665,9 +45665,9 @@ static SDValue combineVEXTRACT_STORE(SDNode *N, SelectionDAG &DAG,
/// In short, LHS and RHS are inspected to see if LHS op RHS is of the form
/// A horizontal-op B, for some already available A and B, and if so then LHS is
/// set to A, RHS to B, and the routine returns 'true'.
-static bool isHorizontalBinOp(unsigned HOpcode, SDValue &LHS, SDValue &RHS,
- SelectionDAG &DAG, const X86Subtarget &Subtarget,
- bool IsCommutative,
+static bool isHorizontalBinOp(unsigned HOpcode, SDValue &LHS, SDValue &RHS,
+ SelectionDAG &DAG, const X86Subtarget &Subtarget,
+ bool IsCommutative,
SmallVectorImpl<int> &PostShuffleMask) {
// If either operand is undef, bail out. The binop should be simplified.
if (LHS.isUndef() || RHS.isUndef())
@@ -45815,39 +45815,39 @@ static bool isHorizontalBinOp(unsigned HOpcode, SDValue &LHS, SDValue &RHS,
}
}
- SDValue NewLHS = A.getNode() ? A : B; // If A is 'UNDEF', use B for it.
- SDValue NewRHS = B.getNode() ? B : A; // If B is 'UNDEF', use A for it.
+ SDValue NewLHS = A.getNode() ? A : B; // If A is 'UNDEF', use B for it.
+ SDValue NewRHS = B.getNode() ? B : A; // If B is 'UNDEF', use A for it.
bool IsIdentityPostShuffle =
isSequentialOrUndefInRange(PostShuffleMask, 0, NumElts, 0);
if (IsIdentityPostShuffle)
PostShuffleMask.clear();
- // Avoid 128-bit multi lane shuffles if pre-AVX2 and FP (integer will split).
- if (!IsIdentityPostShuffle && !Subtarget.hasAVX2() && VT.isFloatingPoint() &&
- isMultiLaneShuffleMask(128, VT.getScalarSizeInBits(), PostShuffleMask))
- return false;
-
- // If the source nodes are already used in HorizOps then always accept this.
- // Shuffle folding should merge these back together.
- bool FoundHorizLHS = llvm::any_of(NewLHS->uses(), [&](SDNode *User) {
- return User->getOpcode() == HOpcode && User->getValueType(0) == VT;
- });
- bool FoundHorizRHS = llvm::any_of(NewRHS->uses(), [&](SDNode *User) {
- return User->getOpcode() == HOpcode && User->getValueType(0) == VT;
- });
- bool ForceHorizOp = FoundHorizLHS && FoundHorizRHS;
-
+ // Avoid 128-bit multi lane shuffles if pre-AVX2 and FP (integer will split).
+ if (!IsIdentityPostShuffle && !Subtarget.hasAVX2() && VT.isFloatingPoint() &&
+ isMultiLaneShuffleMask(128, VT.getScalarSizeInBits(), PostShuffleMask))
+ return false;
+
+ // If the source nodes are already used in HorizOps then always accept this.
+ // Shuffle folding should merge these back together.
+ bool FoundHorizLHS = llvm::any_of(NewLHS->uses(), [&](SDNode *User) {
+ return User->getOpcode() == HOpcode && User->getValueType(0) == VT;
+ });
+ bool FoundHorizRHS = llvm::any_of(NewRHS->uses(), [&](SDNode *User) {
+ return User->getOpcode() == HOpcode && User->getValueType(0) == VT;
+ });
+ bool ForceHorizOp = FoundHorizLHS && FoundHorizRHS;
+
// Assume a SingleSource HOP if we only shuffle one input and don't need to
// shuffle the result.
- if (!ForceHorizOp &&
- !shouldUseHorizontalOp(NewLHS == NewRHS &&
+ if (!ForceHorizOp &&
+ !shouldUseHorizontalOp(NewLHS == NewRHS &&
(NumShuffles < 2 || !IsIdentityPostShuffle),
DAG, Subtarget))
return false;
- LHS = DAG.getBitcast(VT, NewLHS);
- RHS = DAG.getBitcast(VT, NewRHS);
+ LHS = DAG.getBitcast(VT, NewLHS);
+ RHS = DAG.getBitcast(VT, NewRHS);
return true;
}
@@ -45865,8 +45865,8 @@ static SDValue combineFaddFsub(SDNode *N, SelectionDAG &DAG,
SmallVector<int, 8> PostShuffleMask;
if (((Subtarget.hasSSE3() && (VT == MVT::v4f32 || VT == MVT::v2f64)) ||
(Subtarget.hasAVX() && (VT == MVT::v8f32 || VT == MVT::v4f64))) &&
- isHorizontalBinOp(HorizOpcode, LHS, RHS, DAG, Subtarget, IsFadd,
- PostShuffleMask)) {
+ isHorizontalBinOp(HorizOpcode, LHS, RHS, DAG, Subtarget, IsFadd,
+ PostShuffleMask)) {
SDValue HorizBinOp = DAG.getNode(HorizOpcode, SDLoc(N), VT, LHS, RHS);
if (!PostShuffleMask.empty())
HorizBinOp = DAG.getVectorShuffle(VT, SDLoc(HorizBinOp), HorizBinOp,
@@ -46011,7 +46011,7 @@ static SDValue combineVectorTruncation(SDNode *N, SelectionDAG &DAG,
EVT OutSVT = OutVT.getVectorElementType();
EVT InSVT = InVT.getVectorElementType();
- if (!((InSVT == MVT::i16 || InSVT == MVT::i32 || InSVT == MVT::i64) &&
+ if (!((InSVT == MVT::i16 || InSVT == MVT::i32 || InSVT == MVT::i64) &&
(OutSVT == MVT::i8 || OutSVT == MVT::i16) && isPowerOf2_32(NumElems) &&
NumElems >= 8))
return SDValue();
@@ -46073,13 +46073,13 @@ static SDValue combineVectorSignBitsTruncation(SDNode *N, const SDLoc &DL,
// there's no harm in trying pack.
if (Subtarget.hasAVX512() &&
!(!Subtarget.useAVX512Regs() && VT.is256BitVector() &&
- InVT.is512BitVector())) {
- // PACK should still be worth it for 128-bit vectors if the sources were
- // originally concatenated from subvectors.
- SmallVector<SDValue> ConcatOps;
- if (VT.getSizeInBits() > 128 || !collectConcatOps(In.getNode(), ConcatOps))
+ InVT.is512BitVector())) {
+ // PACK should still be worth it for 128-bit vectors if the sources were
+ // originally concatenated from subvectors.
+ SmallVector<SDValue> ConcatOps;
+ if (VT.getSizeInBits() > 128 || !collectConcatOps(In.getNode(), ConcatOps))
return SDValue();
- }
+ }
unsigned NumPackedSignBits = std::min<unsigned>(SVT.getSizeInBits(), 16);
unsigned NumPackedZeroBits = Subtarget.hasSSE41() ? NumPackedSignBits : 8;
@@ -46101,23 +46101,23 @@ static SDValue combineVectorSignBitsTruncation(SDNode *N, const SDLoc &DL,
if (SVT == MVT::i32 && NumSignBits != InSVT.getSizeInBits())
return SDValue();
- unsigned MinSignBits = InSVT.getSizeInBits() - NumPackedSignBits;
- if (NumSignBits > MinSignBits)
+ unsigned MinSignBits = InSVT.getSizeInBits() - NumPackedSignBits;
+ if (NumSignBits > MinSignBits)
return truncateVectorWithPACK(X86ISD::PACKSS, VT, In, DL, DAG, Subtarget);
- // If we have a srl that only generates signbits that we will discard in
- // the truncation then we can use PACKSS by converting the srl to a sra.
- // SimplifyDemandedBits often relaxes sra to srl so we need to reverse it.
- if (In.getOpcode() == ISD::SRL && N->isOnlyUserOf(In.getNode()))
- if (const APInt *ShAmt = DAG.getValidShiftAmountConstant(
- In, APInt::getAllOnesValue(VT.getVectorNumElements()))) {
- if (*ShAmt == MinSignBits) {
- SDValue NewIn = DAG.getNode(ISD::SRA, DL, InVT, In->ops());
- return truncateVectorWithPACK(X86ISD::PACKSS, VT, NewIn, DL, DAG,
- Subtarget);
- }
- }
-
+ // If we have a srl that only generates signbits that we will discard in
+ // the truncation then we can use PACKSS by converting the srl to a sra.
+ // SimplifyDemandedBits often relaxes sra to srl so we need to reverse it.
+ if (In.getOpcode() == ISD::SRL && N->isOnlyUserOf(In.getNode()))
+ if (const APInt *ShAmt = DAG.getValidShiftAmountConstant(
+ In, APInt::getAllOnesValue(VT.getVectorNumElements()))) {
+ if (*ShAmt == MinSignBits) {
+ SDValue NewIn = DAG.getNode(ISD::SRA, DL, InVT, In->ops());
+ return truncateVectorWithPACK(X86ISD::PACKSS, VT, NewIn, DL, DAG,
+ Subtarget);
+ }
+ }
+
return SDValue();
}
@@ -47466,14 +47466,14 @@ static SDValue combineSext(SDNode *N, SelectionDAG &DAG,
if (SDValue V = combineToExtendBoolVectorInReg(N, DAG, DCI, Subtarget))
return V;
- if (VT.isVector()) {
+ if (VT.isVector()) {
if (SDValue R = PromoteMaskArithmetic(N, DAG, Subtarget))
return R;
- if (N0.getOpcode() == ISD::SIGN_EXTEND_VECTOR_INREG)
- return DAG.getNode(N0.getOpcode(), DL, VT, N0.getOperand(0));
- }
-
+ if (N0.getOpcode() == ISD::SIGN_EXTEND_VECTOR_INREG)
+ return DAG.getNode(N0.getOpcode(), DL, VT, N0.getOperand(0));
+ }
+
if (SDValue NewAdd = promoteExtBeforeAdd(N, DAG, Subtarget))
return NewAdd;
@@ -47492,19 +47492,19 @@ static SDValue combineFMA(SDNode *N, SelectionDAG &DAG,
if (!TLI.isTypeLegal(VT))
return SDValue();
- SDValue A = N->getOperand(IsStrict ? 1 : 0);
- SDValue B = N->getOperand(IsStrict ? 2 : 1);
- SDValue C = N->getOperand(IsStrict ? 3 : 2);
-
- // If the operation allows fast-math and the target does not support FMA,
- // split this into mul+add to avoid libcall(s).
- SDNodeFlags Flags = N->getFlags();
- if (!IsStrict && Flags.hasAllowReassociation() &&
- TLI.isOperationExpand(ISD::FMA, VT)) {
- SDValue Fmul = DAG.getNode(ISD::FMUL, dl, VT, A, B, Flags);
- return DAG.getNode(ISD::FADD, dl, VT, Fmul, C, Flags);
- }
-
+ SDValue A = N->getOperand(IsStrict ? 1 : 0);
+ SDValue B = N->getOperand(IsStrict ? 2 : 1);
+ SDValue C = N->getOperand(IsStrict ? 3 : 2);
+
+ // If the operation allows fast-math and the target does not support FMA,
+ // split this into mul+add to avoid libcall(s).
+ SDNodeFlags Flags = N->getFlags();
+ if (!IsStrict && Flags.hasAllowReassociation() &&
+ TLI.isOperationExpand(ISD::FMA, VT)) {
+ SDValue Fmul = DAG.getNode(ISD::FMUL, dl, VT, A, B, Flags);
+ return DAG.getNode(ISD::FADD, dl, VT, Fmul, C, Flags);
+ }
+
EVT ScalarVT = VT.getScalarType();
if ((ScalarVT != MVT::f32 && ScalarVT != MVT::f64) || !Subtarget.hasAnyFMA())
return SDValue();
@@ -47931,7 +47931,7 @@ static SDValue combineMOVMSK(SDNode *N, SelectionDAG &DAG,
Src.getOperand(0).getScalarValueSizeInBits() == EltWidth)
return DAG.getNode(X86ISD::MOVMSK, SDLoc(N), VT, Src.getOperand(0));
- // Fold movmsk(not(x)) -> not(movmsk(x)) to improve folding of movmsk results
+ // Fold movmsk(not(x)) -> not(movmsk(x)) to improve folding of movmsk results
// with scalar comparisons.
if (SDValue NotSrc = IsNOT(Src, DAG)) {
SDLoc DL(N);
@@ -47942,17 +47942,17 @@ static SDValue combineMOVMSK(SDNode *N, SelectionDAG &DAG,
DAG.getConstant(NotMask, DL, VT));
}
- // Fold movmsk(icmp_sgt(x,-1)) -> not(movmsk(x)) to improve folding of movmsk
- // results with scalar comparisons.
- if (Src.getOpcode() == X86ISD::PCMPGT &&
- ISD::isBuildVectorAllOnes(Src.getOperand(1).getNode())) {
- SDLoc DL(N);
- APInt NotMask = APInt::getLowBitsSet(NumBits, NumElts);
- return DAG.getNode(ISD::XOR, DL, VT,
- DAG.getNode(X86ISD::MOVMSK, DL, VT, Src.getOperand(0)),
- DAG.getConstant(NotMask, DL, VT));
- }
-
+ // Fold movmsk(icmp_sgt(x,-1)) -> not(movmsk(x)) to improve folding of movmsk
+ // results with scalar comparisons.
+ if (Src.getOpcode() == X86ISD::PCMPGT &&
+ ISD::isBuildVectorAllOnes(Src.getOperand(1).getNode())) {
+ SDLoc DL(N);
+ APInt NotMask = APInt::getLowBitsSet(NumBits, NumElts);
+ return DAG.getNode(ISD::XOR, DL, VT,
+ DAG.getNode(X86ISD::MOVMSK, DL, VT, Src.getOperand(0)),
+ DAG.getConstant(NotMask, DL, VT));
+ }
+
// Simplify the inputs.
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
APInt DemandedMask(APInt::getAllOnesValue(NumBits));
@@ -47990,8 +47990,8 @@ static SDValue rebuildGatherScatter(MaskedGatherScatterSDNode *GorS,
return DAG.getMaskedGather(Gather->getVTList(),
Gather->getMemoryVT(), DL, Ops,
Gather->getMemOperand(),
- Gather->getIndexType(),
- Gather->getExtensionType());
+ Gather->getIndexType(),
+ Gather->getExtensionType());
}
auto *Scatter = cast<MaskedScatterSDNode>(GorS);
SDValue Ops[] = { Scatter->getChain(), Scatter->getValue(),
@@ -47999,8 +47999,8 @@ static SDValue rebuildGatherScatter(MaskedGatherScatterSDNode *GorS,
return DAG.getMaskedScatter(Scatter->getVTList(),
Scatter->getMemoryVT(), DL,
Ops, Scatter->getMemOperand(),
- Scatter->getIndexType(),
- Scatter->isTruncatingStore());
+ Scatter->getIndexType(),
+ Scatter->isTruncatingStore());
}
static SDValue combineGatherScatter(SDNode *N, SelectionDAG &DAG,
@@ -48995,18 +48995,18 @@ static SDValue combineAddOrSubToHADDorHSUB(SDNode *N, SelectionDAG &DAG,
SDValue Op0 = N->getOperand(0);
SDValue Op1 = N->getOperand(1);
bool IsAdd = N->getOpcode() == ISD::ADD;
- auto HorizOpcode = IsAdd ? X86ISD::HADD : X86ISD::HSUB;
+ auto HorizOpcode = IsAdd ? X86ISD::HADD : X86ISD::HSUB;
assert((IsAdd || N->getOpcode() == ISD::SUB) && "Wrong opcode");
SmallVector<int, 8> PostShuffleMask;
if ((VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v16i16 ||
VT == MVT::v8i32) &&
Subtarget.hasSSSE3() &&
- isHorizontalBinOp(HorizOpcode, Op0, Op1, DAG, Subtarget, IsAdd,
- PostShuffleMask)) {
- auto HOpBuilder = [HorizOpcode](SelectionDAG &DAG, const SDLoc &DL,
- ArrayRef<SDValue> Ops) {
- return DAG.getNode(HorizOpcode, DL, Ops[0].getValueType(), Ops);
+ isHorizontalBinOp(HorizOpcode, Op0, Op1, DAG, Subtarget, IsAdd,
+ PostShuffleMask)) {
+ auto HOpBuilder = [HorizOpcode](SelectionDAG &DAG, const SDLoc &DL,
+ ArrayRef<SDValue> Ops) {
+ return DAG.getNode(HorizOpcode, DL, Ops[0].getValueType(), Ops);
};
SDValue HorizBinOp =
SplitOpsAndApply(DAG, Subtarget, SDLoc(N), VT, {Op0, Op1}, HOpBuilder);
@@ -49071,11 +49071,11 @@ static SDValue combineSubToSubus(SDNode *N, SelectionDAG &DAG,
if (!VT.isVector())
return SDValue();
- // PSUBUS is supported, starting from SSE2.
+ // PSUBUS is supported, starting from SSE2.
EVT EltVT = VT.getVectorElementType();
- if (!(Subtarget.hasSSE2() &&
- (EltVT == MVT::i8 || EltVT == MVT::i16 || VT == MVT::v8i32 ||
- VT == MVT::v8i64 || VT == MVT::v16i32)))
+ if (!(Subtarget.hasSSE2() &&
+ (EltVT == MVT::i8 || EltVT == MVT::i16 || VT == MVT::v8i32 ||
+ VT == MVT::v8i64 || VT == MVT::v16i32)))
return SDValue();
SDValue SubusLHS, SubusRHS;
@@ -49111,9 +49111,9 @@ static SDValue combineSubToSubus(SDNode *N, SelectionDAG &DAG,
SDValue MinLHS = Op1.getOperand(0).getOperand(0);
SDValue MinRHS = Op1.getOperand(0).getOperand(1);
EVT TruncVT = Op1.getOperand(0).getValueType();
- if (!(Subtarget.hasSSE2() &&
- (TruncVT == MVT::v8i32 || TruncVT == MVT::v8i64 ||
- TruncVT == MVT::v16i32)))
+ if (!(Subtarget.hasSSE2() &&
+ (TruncVT == MVT::v8i32 || TruncVT == MVT::v8i64 ||
+ TruncVT == MVT::v16i32)))
return SDValue();
SDValue OpToSaturate;
if (MinLHS.getOpcode() == ISD::ZERO_EXTEND &&
@@ -49151,7 +49151,7 @@ static SDValue combineSubToSubus(SDNode *N, SelectionDAG &DAG,
// values, or first 48 bits for 64 bit values.
KnownBits Known = DAG.computeKnownBits(SubusLHS);
unsigned NumZeros = Known.countMinLeadingZeros();
- if (NumZeros < (VT.getScalarSizeInBits() - 16))
+ if (NumZeros < (VT.getScalarSizeInBits() - 16))
return SDValue();
EVT ExtType = SubusLHS.getValueType();
@@ -49252,46 +49252,46 @@ static SDValue combineConcatVectorOps(const SDLoc &DL, MVT VT,
bool IsSplat = llvm::all_of(Ops, [&Op0](SDValue Op) { return Op == Op0; });
// Repeated subvectors.
- if (IsSplat &&
- (VT.is256BitVector() || (VT.is512BitVector() && Subtarget.hasAVX512()))) {
- // If this broadcast is inserted into both halves, use a larger broadcast.
- if (Op0.getOpcode() == X86ISD::VBROADCAST)
+ if (IsSplat &&
+ (VT.is256BitVector() || (VT.is512BitVector() && Subtarget.hasAVX512()))) {
+ // If this broadcast is inserted into both halves, use a larger broadcast.
+ if (Op0.getOpcode() == X86ISD::VBROADCAST)
return DAG.getNode(Op0.getOpcode(), DL, VT, Op0.getOperand(0));
- // If this scalar/subvector broadcast_load is inserted into both halves, use
- // a larger broadcast_load. Update other uses to use an extracted subvector.
- if (Op0.getOpcode() == X86ISD::VBROADCAST_LOAD ||
- Op0.getOpcode() == X86ISD::SUBV_BROADCAST_LOAD) {
+ // If this scalar/subvector broadcast_load is inserted into both halves, use
+ // a larger broadcast_load. Update other uses to use an extracted subvector.
+ if (Op0.getOpcode() == X86ISD::VBROADCAST_LOAD ||
+ Op0.getOpcode() == X86ISD::SUBV_BROADCAST_LOAD) {
auto *MemIntr = cast<MemIntrinsicSDNode>(Op0);
SDVTList Tys = DAG.getVTList(VT, MVT::Other);
SDValue Ops[] = {MemIntr->getChain(), MemIntr->getBasePtr()};
- SDValue BcastLd = DAG.getMemIntrinsicNode(Op0.getOpcode(), DL, Tys, Ops,
- MemIntr->getMemoryVT(),
- MemIntr->getMemOperand());
+ SDValue BcastLd = DAG.getMemIntrinsicNode(Op0.getOpcode(), DL, Tys, Ops,
+ MemIntr->getMemoryVT(),
+ MemIntr->getMemOperand());
DAG.ReplaceAllUsesOfValueWith(
Op0, extractSubVector(BcastLd, 0, DAG, DL, Op0.getValueSizeInBits()));
DAG.ReplaceAllUsesOfValueWith(SDValue(MemIntr, 1), BcastLd.getValue(1));
return BcastLd;
}
- // If this is a simple subvector load repeated across multiple lanes, then
- // broadcast the load. Update other uses to use an extracted subvector.
- if (auto *Ld = dyn_cast<LoadSDNode>(Op0)) {
- if (Ld->isSimple() && !Ld->isNonTemporal() &&
- Ld->getExtensionType() == ISD::NON_EXTLOAD) {
- SDVTList Tys = DAG.getVTList(VT, MVT::Other);
- SDValue Ops[] = {Ld->getChain(), Ld->getBasePtr()};
- SDValue BcastLd =
- DAG.getMemIntrinsicNode(X86ISD::SUBV_BROADCAST_LOAD, DL, Tys, Ops,
- Ld->getMemoryVT(), Ld->getMemOperand());
- DAG.ReplaceAllUsesOfValueWith(
- Op0,
- extractSubVector(BcastLd, 0, DAG, DL, Op0.getValueSizeInBits()));
- DAG.ReplaceAllUsesOfValueWith(SDValue(Ld, 1), BcastLd.getValue(1));
- return BcastLd;
- }
- }
-
+ // If this is a simple subvector load repeated across multiple lanes, then
+ // broadcast the load. Update other uses to use an extracted subvector.
+ if (auto *Ld = dyn_cast<LoadSDNode>(Op0)) {
+ if (Ld->isSimple() && !Ld->isNonTemporal() &&
+ Ld->getExtensionType() == ISD::NON_EXTLOAD) {
+ SDVTList Tys = DAG.getVTList(VT, MVT::Other);
+ SDValue Ops[] = {Ld->getChain(), Ld->getBasePtr()};
+ SDValue BcastLd =
+ DAG.getMemIntrinsicNode(X86ISD::SUBV_BROADCAST_LOAD, DL, Tys, Ops,
+ Ld->getMemoryVT(), Ld->getMemOperand());
+ DAG.ReplaceAllUsesOfValueWith(
+ Op0,
+ extractSubVector(BcastLd, 0, DAG, DL, Op0.getValueSizeInBits()));
+ DAG.ReplaceAllUsesOfValueWith(SDValue(Ld, 1), BcastLd.getValue(1));
+ return BcastLd;
+ }
+ }
+
// concat_vectors(movddup(x),movddup(x)) -> broadcast(x)
if (Op0.getOpcode() == X86ISD::MOVDDUP && VT == MVT::v4f64 &&
(Subtarget.hasAVX2() || MayFoldLoad(Op0.getOperand(0))))
@@ -49369,38 +49369,38 @@ static SDValue combineConcatVectorOps(const SDLoc &DL, MVT VT,
return DAG.getBitcast(VT, Res);
}
break;
- case X86ISD::VPERMV3:
- if (!IsSplat && NumOps == 2 && VT.is512BitVector()) {
- MVT OpVT = Op0.getSimpleValueType();
- int NumSrcElts = OpVT.getVectorNumElements();
- SmallVector<int, 64> ConcatMask;
- for (unsigned i = 0; i != NumOps; ++i) {
- bool IsUnary;
- SmallVector<int, 64> SubMask;
- SmallVector<SDValue, 2> SubOps;
- if (!getTargetShuffleMask(Ops[i].getNode(), OpVT, false, SubOps,
- SubMask, IsUnary))
- break;
- for (int M : SubMask) {
- if (0 <= M) {
- M += M < NumSrcElts ? 0 : NumSrcElts;
- M += i * NumSrcElts;
- }
- ConcatMask.push_back(M);
- }
- }
- if (ConcatMask.size() == (NumOps * NumSrcElts)) {
- SDValue Src0 = concatSubVectors(Ops[0].getOperand(0),
- Ops[1].getOperand(0), DAG, DL);
- SDValue Src1 = concatSubVectors(Ops[0].getOperand(2),
- Ops[1].getOperand(2), DAG, DL);
- MVT IntMaskSVT = MVT::getIntegerVT(VT.getScalarSizeInBits());
- MVT IntMaskVT = MVT::getVectorVT(IntMaskSVT, NumOps * NumSrcElts);
- SDValue Mask = getConstVector(ConcatMask, IntMaskVT, DAG, DL, true);
- return DAG.getNode(X86ISD::VPERMV3, DL, VT, Src0, Mask, Src1);
- }
- }
- break;
+ case X86ISD::VPERMV3:
+ if (!IsSplat && NumOps == 2 && VT.is512BitVector()) {
+ MVT OpVT = Op0.getSimpleValueType();
+ int NumSrcElts = OpVT.getVectorNumElements();
+ SmallVector<int, 64> ConcatMask;
+ for (unsigned i = 0; i != NumOps; ++i) {
+ bool IsUnary;
+ SmallVector<int, 64> SubMask;
+ SmallVector<SDValue, 2> SubOps;
+ if (!getTargetShuffleMask(Ops[i].getNode(), OpVT, false, SubOps,
+ SubMask, IsUnary))
+ break;
+ for (int M : SubMask) {
+ if (0 <= M) {
+ M += M < NumSrcElts ? 0 : NumSrcElts;
+ M += i * NumSrcElts;
+ }
+ ConcatMask.push_back(M);
+ }
+ }
+ if (ConcatMask.size() == (NumOps * NumSrcElts)) {
+ SDValue Src0 = concatSubVectors(Ops[0].getOperand(0),
+ Ops[1].getOperand(0), DAG, DL);
+ SDValue Src1 = concatSubVectors(Ops[0].getOperand(2),
+ Ops[1].getOperand(2), DAG, DL);
+ MVT IntMaskSVT = MVT::getIntegerVT(VT.getScalarSizeInBits());
+ MVT IntMaskVT = MVT::getVectorVT(IntMaskSVT, NumOps * NumSrcElts);
+ SDValue Mask = getConstVector(ConcatMask, IntMaskVT, DAG, DL, true);
+ return DAG.getNode(X86ISD::VPERMV3, DL, VT, Src0, Mask, Src1);
+ }
+ }
+ break;
case X86ISD::VSHLI:
case X86ISD::VSRAI:
case X86ISD::VSRLI:
@@ -49433,33 +49433,33 @@ static SDValue combineConcatVectorOps(const SDLoc &DL, MVT VT,
Op0.getOperand(1));
}
break;
- case ISD::AND:
- case ISD::OR:
- case ISD::XOR:
- case X86ISD::ANDNP:
- // TODO: Add 256-bit support.
- if (!IsSplat && VT.is512BitVector()) {
- SmallVector<SDValue, 2> LHS, RHS;
- for (unsigned i = 0; i != NumOps; ++i) {
- LHS.push_back(Ops[i].getOperand(0));
- RHS.push_back(Ops[i].getOperand(1));
- }
- MVT SrcVT = Op0.getOperand(0).getSimpleValueType();
- SrcVT = MVT::getVectorVT(SrcVT.getScalarType(),
- NumOps * SrcVT.getVectorNumElements());
- return DAG.getNode(Op0.getOpcode(), DL, VT,
- DAG.getNode(ISD::CONCAT_VECTORS, DL, SrcVT, LHS),
- DAG.getNode(ISD::CONCAT_VECTORS, DL, SrcVT, RHS));
- }
- break;
- case X86ISD::HADD:
- case X86ISD::HSUB:
- case X86ISD::FHADD:
- case X86ISD::FHSUB:
+ case ISD::AND:
+ case ISD::OR:
+ case ISD::XOR:
+ case X86ISD::ANDNP:
+ // TODO: Add 256-bit support.
+ if (!IsSplat && VT.is512BitVector()) {
+ SmallVector<SDValue, 2> LHS, RHS;
+ for (unsigned i = 0; i != NumOps; ++i) {
+ LHS.push_back(Ops[i].getOperand(0));
+ RHS.push_back(Ops[i].getOperand(1));
+ }
+ MVT SrcVT = Op0.getOperand(0).getSimpleValueType();
+ SrcVT = MVT::getVectorVT(SrcVT.getScalarType(),
+ NumOps * SrcVT.getVectorNumElements());
+ return DAG.getNode(Op0.getOpcode(), DL, VT,
+ DAG.getNode(ISD::CONCAT_VECTORS, DL, SrcVT, LHS),
+ DAG.getNode(ISD::CONCAT_VECTORS, DL, SrcVT, RHS));
+ }
+ break;
+ case X86ISD::HADD:
+ case X86ISD::HSUB:
+ case X86ISD::FHADD:
+ case X86ISD::FHSUB:
case X86ISD::PACKSS:
case X86ISD::PACKUS:
- if (!IsSplat && VT.is256BitVector() &&
- (VT.isFloatingPoint() || Subtarget.hasInt256())) {
+ if (!IsSplat && VT.is256BitVector() &&
+ (VT.isFloatingPoint() || Subtarget.hasInt256())) {
SmallVector<SDValue, 2> LHS, RHS;
for (unsigned i = 0; i != NumOps; ++i) {
LHS.push_back(Ops[i].getOperand(0));
@@ -49494,20 +49494,20 @@ static SDValue combineConcatVectorOps(const SDLoc &DL, MVT VT,
}
}
- // Fold subvector loads into one.
- // If needed, look through bitcasts to get to the load.
- if (auto *FirstLd = dyn_cast<LoadSDNode>(peekThroughBitcasts(Op0))) {
- bool Fast;
- const X86TargetLowering *TLI = Subtarget.getTargetLowering();
- if (TLI->allowsMemoryAccess(*DAG.getContext(), DAG.getDataLayout(), VT,
- *FirstLd->getMemOperand(), &Fast) &&
- Fast) {
- if (SDValue Ld =
- EltsFromConsecutiveLoads(VT, Ops, DL, DAG, Subtarget, false))
- return Ld;
- }
- }
-
+ // Fold subvector loads into one.
+ // If needed, look through bitcasts to get to the load.
+ if (auto *FirstLd = dyn_cast<LoadSDNode>(peekThroughBitcasts(Op0))) {
+ bool Fast;
+ const X86TargetLowering *TLI = Subtarget.getTargetLowering();
+ if (TLI->allowsMemoryAccess(*DAG.getContext(), DAG.getDataLayout(), VT,
+ *FirstLd->getMemOperand(), &Fast) &&
+ Fast) {
+ if (SDValue Ld =
+ EltsFromConsecutiveLoads(VT, Ops, DL, DAG, Subtarget, false))
+ return Ld;
+ }
+ }
+
return SDValue();
}
@@ -49579,8 +49579,8 @@ static SDValue combineInsertSubvector(SDNode *N, SelectionDAG &DAG,
SDValue Ins = SubVec.getOperand(0);
if (isNullConstant(Ins.getOperand(2)) &&
ISD::isBuildVectorAllZeros(Ins.getOperand(0).getNode()) &&
- Ins.getOperand(1).getValueSizeInBits().getFixedSize() <=
- SubVecVT.getFixedSizeInBits())
+ Ins.getOperand(1).getValueSizeInBits().getFixedSize() <=
+ SubVecVT.getFixedSizeInBits())
return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, OpVT,
getZeroVector(OpVT, Subtarget, DAG, dl),
Ins.getOperand(1), N->getOperand(2));
@@ -49733,14 +49733,14 @@ static SDValue combineExtractSubvector(SDNode *N, SelectionDAG &DAG,
unsigned IdxVal = N->getConstantOperandVal(1);
SDValue InVecBC = peekThroughBitcasts(InVec);
EVT InVecVT = InVec.getValueType();
- unsigned SizeInBits = VT.getSizeInBits();
- unsigned InSizeInBits = InVecVT.getSizeInBits();
+ unsigned SizeInBits = VT.getSizeInBits();
+ unsigned InSizeInBits = InVecVT.getSizeInBits();
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
if (Subtarget.hasAVX() && !Subtarget.hasAVX2() &&
TLI.isTypeLegal(InVecVT) &&
- InSizeInBits == 256 && InVecBC.getOpcode() == ISD::AND) {
- auto isConcatenatedNot = [](SDValue V) {
+ InSizeInBits == 256 && InVecBC.getOpcode() == ISD::AND) {
+ auto isConcatenatedNot = [](SDValue V) {
V = peekThroughBitcasts(V);
if (!isBitwiseNot(V))
return false;
@@ -49783,7 +49783,7 @@ static SDValue combineExtractSubvector(SDNode *N, SelectionDAG &DAG,
InVec.getOpcode() == ISD::INSERT_SUBVECTOR && IdxVal == 0 &&
InVec.hasOneUse() && isNullConstant(InVec.getOperand(2)) &&
ISD::isBuildVectorAllZeros(InVec.getOperand(0).getNode()) &&
- InVec.getOperand(1).getValueSizeInBits() <= SizeInBits) {
+ InVec.getOperand(1).getValueSizeInBits() <= SizeInBits) {
SDLoc DL(N);
return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT,
getZeroVector(VT, Subtarget, DAG, DL),
@@ -49795,20 +49795,20 @@ static SDValue combineExtractSubvector(SDNode *N, SelectionDAG &DAG,
// SimplifyDemandedVectorElts do more simplifications.
if (IdxVal != 0 && (InVec.getOpcode() == X86ISD::VBROADCAST ||
InVec.getOpcode() == X86ISD::VBROADCAST_LOAD))
- return extractSubVector(InVec, 0, DAG, SDLoc(N), SizeInBits);
+ return extractSubVector(InVec, 0, DAG, SDLoc(N), SizeInBits);
- // If we're extracting a broadcasted subvector, just use the lowest subvector.
- if (IdxVal != 0 && InVec.getOpcode() == X86ISD::SUBV_BROADCAST_LOAD &&
- cast<MemIntrinsicSDNode>(InVec)->getMemoryVT() == VT)
- return extractSubVector(InVec, 0, DAG, SDLoc(N), SizeInBits);
+ // If we're extracting a broadcasted subvector, just use the lowest subvector.
+ if (IdxVal != 0 && InVec.getOpcode() == X86ISD::SUBV_BROADCAST_LOAD &&
+ cast<MemIntrinsicSDNode>(InVec)->getMemoryVT() == VT)
+ return extractSubVector(InVec, 0, DAG, SDLoc(N), SizeInBits);
// Attempt to extract from the source of a shuffle vector.
- if ((InSizeInBits % SizeInBits) == 0 &&
+ if ((InSizeInBits % SizeInBits) == 0 &&
(IdxVal % VT.getVectorNumElements()) == 0) {
SmallVector<int, 32> ShuffleMask;
SmallVector<int, 32> ScaledMask;
SmallVector<SDValue, 2> ShuffleInputs;
- unsigned NumSubVecs = InSizeInBits / SizeInBits;
+ unsigned NumSubVecs = InSizeInBits / SizeInBits;
// Decode the shuffle mask and scale it so its shuffling subvectors.
if (getTargetShuffleInputs(InVecBC, ShuffleInputs, ShuffleMask, DAG) &&
scaleShuffleElements(ShuffleMask, NumSubVecs, ScaledMask)) {
@@ -49818,18 +49818,18 @@ static SDValue combineExtractSubvector(SDNode *N, SelectionDAG &DAG,
if (ScaledMask[SubVecIdx] == SM_SentinelZero)
return getZeroVector(VT, Subtarget, DAG, SDLoc(N));
SDValue Src = ShuffleInputs[ScaledMask[SubVecIdx] / NumSubVecs];
- if (Src.getValueSizeInBits() == InSizeInBits) {
+ if (Src.getValueSizeInBits() == InSizeInBits) {
unsigned SrcSubVecIdx = ScaledMask[SubVecIdx] % NumSubVecs;
unsigned SrcEltIdx = SrcSubVecIdx * VT.getVectorNumElements();
return extractSubVector(DAG.getBitcast(InVecVT, Src), SrcEltIdx, DAG,
- SDLoc(N), SizeInBits);
+ SDLoc(N), SizeInBits);
}
}
}
// If we're extracting the lowest subvector and we're the only user,
// we may be able to perform this with a smaller vector width.
- unsigned InOpcode = InVec.getOpcode();
+ unsigned InOpcode = InVec.getOpcode();
if (IdxVal == 0 && InVec.hasOneUse()) {
if (VT == MVT::v2f64 && InVecVT == MVT::v4f64) {
// v2f64 CVTDQ2PD(v4i32).
@@ -49854,14 +49854,14 @@ static SDValue combineExtractSubvector(SDNode *N, SelectionDAG &DAG,
InOpcode == ISD::ZERO_EXTEND_VECTOR_INREG ||
InOpcode == ISD::SIGN_EXTEND ||
InOpcode == ISD::SIGN_EXTEND_VECTOR_INREG) &&
- (SizeInBits == 128 || SizeInBits == 256) &&
- InVec.getOperand(0).getValueSizeInBits() >= SizeInBits) {
- SDLoc DL(N);
- SDValue Ext = InVec.getOperand(0);
- if (Ext.getValueSizeInBits() > SizeInBits)
- Ext = extractSubVector(Ext, 0, DAG, DL, SizeInBits);
+ (SizeInBits == 128 || SizeInBits == 256) &&
+ InVec.getOperand(0).getValueSizeInBits() >= SizeInBits) {
+ SDLoc DL(N);
+ SDValue Ext = InVec.getOperand(0);
+ if (Ext.getValueSizeInBits() > SizeInBits)
+ Ext = extractSubVector(Ext, 0, DAG, DL, SizeInBits);
unsigned ExtOp = getOpcode_EXTEND_VECTOR_INREG(InOpcode);
- return DAG.getNode(ExtOp, DL, VT, Ext);
+ return DAG.getNode(ExtOp, DL, VT, Ext);
}
if (InOpcode == ISD::VSELECT &&
InVec.getOperand(0).getValueType().is256BitVector() &&
@@ -49873,27 +49873,27 @@ static SDValue combineExtractSubvector(SDNode *N, SelectionDAG &DAG,
SDValue Ext2 = extractSubVector(InVec.getOperand(2), 0, DAG, DL, 128);
return DAG.getNode(InOpcode, DL, VT, Ext0, Ext1, Ext2);
}
- if (InOpcode == ISD::TRUNCATE && Subtarget.hasVLX() &&
- (VT.is128BitVector() || VT.is256BitVector())) {
- SDLoc DL(N);
- SDValue InVecSrc = InVec.getOperand(0);
- unsigned Scale = InVecSrc.getValueSizeInBits() / InSizeInBits;
- SDValue Ext = extractSubVector(InVecSrc, 0, DAG, DL, Scale * SizeInBits);
- return DAG.getNode(InOpcode, DL, VT, Ext);
- }
- }
-
- // Always split vXi64 logical shifts where we're extracting the upper 32-bits
- // as this is very likely to fold into a shuffle/truncation.
- if ((InOpcode == X86ISD::VSHLI || InOpcode == X86ISD::VSRLI) &&
- InVecVT.getScalarSizeInBits() == 64 &&
- InVec.getConstantOperandAPInt(1) == 32) {
- SDLoc DL(N);
- SDValue Ext =
- extractSubVector(InVec.getOperand(0), IdxVal, DAG, DL, SizeInBits);
- return DAG.getNode(InOpcode, DL, VT, Ext, InVec.getOperand(1));
- }
-
+ if (InOpcode == ISD::TRUNCATE && Subtarget.hasVLX() &&
+ (VT.is128BitVector() || VT.is256BitVector())) {
+ SDLoc DL(N);
+ SDValue InVecSrc = InVec.getOperand(0);
+ unsigned Scale = InVecSrc.getValueSizeInBits() / InSizeInBits;
+ SDValue Ext = extractSubVector(InVecSrc, 0, DAG, DL, Scale * SizeInBits);
+ return DAG.getNode(InOpcode, DL, VT, Ext);
+ }
+ }
+
+ // Always split vXi64 logical shifts where we're extracting the upper 32-bits
+ // as this is very likely to fold into a shuffle/truncation.
+ if ((InOpcode == X86ISD::VSHLI || InOpcode == X86ISD::VSRLI) &&
+ InVecVT.getScalarSizeInBits() == 64 &&
+ InVec.getConstantOperandAPInt(1) == 32) {
+ SDLoc DL(N);
+ SDValue Ext =
+ extractSubVector(InVec.getOperand(0), IdxVal, DAG, DL, SizeInBits);
+ return DAG.getNode(InOpcode, DL, VT, Ext, InVec.getOperand(1));
+ }
+
return SDValue();
}
@@ -49975,7 +49975,7 @@ static SDValue combinePMULDQ(SDNode *N, SelectionDAG &DAG,
// If the input is an extend_invec and the SimplifyDemandedBits call didn't
// convert it to any_extend_invec, due to the LegalOperations check, do the
// conversion directly to a vector shuffle manually. This exposes combine
- // opportunities missed by combineEXTEND_VECTOR_INREG not calling
+ // opportunities missed by combineEXTEND_VECTOR_INREG not calling
// combineX86ShufflesRecursively on SSE4.1 targets.
// FIXME: This is basically a hack around several other issues related to
// ANY_EXTEND_VECTOR_INREG.
@@ -50003,13 +50003,13 @@ static SDValue combinePMULDQ(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
-static SDValue combineEXTEND_VECTOR_INREG(SDNode *N, SelectionDAG &DAG,
- TargetLowering::DAGCombinerInfo &DCI,
- const X86Subtarget &Subtarget) {
+static SDValue combineEXTEND_VECTOR_INREG(SDNode *N, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI,
+ const X86Subtarget &Subtarget) {
EVT VT = N->getValueType(0);
SDValue In = N->getOperand(0);
- unsigned Opcode = N->getOpcode();
- unsigned InOpcode = In.getOpcode();
+ unsigned Opcode = N->getOpcode();
+ unsigned InOpcode = In.getOpcode();
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
// Try to merge vector loads and extend_inreg to an extload.
@@ -50018,7 +50018,7 @@ static SDValue combineEXTEND_VECTOR_INREG(SDNode *N, SelectionDAG &DAG,
auto *Ld = cast<LoadSDNode>(In);
if (Ld->isSimple()) {
MVT SVT = In.getSimpleValueType().getVectorElementType();
- ISD::LoadExtType Ext = Opcode == ISD::SIGN_EXTEND_VECTOR_INREG
+ ISD::LoadExtType Ext = Opcode == ISD::SIGN_EXTEND_VECTOR_INREG
? ISD::SEXTLOAD
: ISD::ZEXTLOAD;
EVT MemVT =
@@ -50026,7 +50026,7 @@ static SDValue combineEXTEND_VECTOR_INREG(SDNode *N, SelectionDAG &DAG,
if (TLI.isLoadExtLegal(Ext, VT, MemVT)) {
SDValue Load =
DAG.getExtLoad(Ext, SDLoc(N), VT, Ld->getChain(), Ld->getBasePtr(),
- Ld->getPointerInfo(), MemVT, Ld->getOriginalAlign(),
+ Ld->getPointerInfo(), MemVT, Ld->getOriginalAlign(),
Ld->getMemOperand()->getFlags());
DAG.ReplaceAllUsesOfValueWith(SDValue(Ld, 1), Load.getValue(1));
return Load;
@@ -50034,23 +50034,23 @@ static SDValue combineEXTEND_VECTOR_INREG(SDNode *N, SelectionDAG &DAG,
}
}
- // Fold EXTEND_VECTOR_INREG(EXTEND_VECTOR_INREG(X)) -> EXTEND_VECTOR_INREG(X).
- if (Opcode == InOpcode)
- return DAG.getNode(Opcode, SDLoc(N), VT, In.getOperand(0));
-
- // Fold EXTEND_VECTOR_INREG(EXTRACT_SUBVECTOR(EXTEND(X),0))
- // -> EXTEND_VECTOR_INREG(X).
- // TODO: Handle non-zero subvector indices.
- if (InOpcode == ISD::EXTRACT_SUBVECTOR && In.getConstantOperandVal(1) == 0 &&
- In.getOperand(0).getOpcode() == getOpcode_EXTEND(Opcode) &&
- In.getOperand(0).getOperand(0).getValueSizeInBits() ==
- In.getValueSizeInBits())
- return DAG.getNode(Opcode, SDLoc(N), VT, In.getOperand(0).getOperand(0));
-
+ // Fold EXTEND_VECTOR_INREG(EXTEND_VECTOR_INREG(X)) -> EXTEND_VECTOR_INREG(X).
+ if (Opcode == InOpcode)
+ return DAG.getNode(Opcode, SDLoc(N), VT, In.getOperand(0));
+
+ // Fold EXTEND_VECTOR_INREG(EXTRACT_SUBVECTOR(EXTEND(X),0))
+ // -> EXTEND_VECTOR_INREG(X).
+ // TODO: Handle non-zero subvector indices.
+ if (InOpcode == ISD::EXTRACT_SUBVECTOR && In.getConstantOperandVal(1) == 0 &&
+ In.getOperand(0).getOpcode() == getOpcode_EXTEND(Opcode) &&
+ In.getOperand(0).getOperand(0).getValueSizeInBits() ==
+ In.getValueSizeInBits())
+ return DAG.getNode(Opcode, SDLoc(N), VT, In.getOperand(0).getOperand(0));
+
// Attempt to combine as a shuffle.
- // TODO: General ZERO_EXTEND_VECTOR_INREG support.
- if (Opcode == ISD::ANY_EXTEND_VECTOR_INREG ||
- (Opcode == ISD::ZERO_EXTEND_VECTOR_INREG && Subtarget.hasSSE41())) {
+ // TODO: General ZERO_EXTEND_VECTOR_INREG support.
+ if (Opcode == ISD::ANY_EXTEND_VECTOR_INREG ||
+ (Opcode == ISD::ZERO_EXTEND_VECTOR_INREG && Subtarget.hasSSE41())) {
SDValue Op(N, 0);
if (TLI.isTypeLegal(VT) && TLI.isTypeLegal(In.getValueType()))
if (SDValue Res = combineX86ShufflesRecursively(Op, DAG, Subtarget))
@@ -50171,15 +50171,15 @@ static SDValue combineFP_EXTEND(SDNode *N, SelectionDAG &DAG,
return DAG.getNode(ISD::FP_EXTEND, dl, VT, Cvt);
}
-// Try to find a larger VBROADCAST_LOAD/SUBV_BROADCAST_LOAD that we can extract
-// from. Limit this to cases where the loads have the same input chain and the
-// output chains are unused. This avoids any memory ordering issues.
-static SDValue combineBROADCAST_LOAD(SDNode *N, SelectionDAG &DAG,
- TargetLowering::DAGCombinerInfo &DCI) {
- assert((N->getOpcode() == X86ISD::VBROADCAST_LOAD ||
- N->getOpcode() == X86ISD::SUBV_BROADCAST_LOAD) &&
- "Unknown broadcast load type");
-
+// Try to find a larger VBROADCAST_LOAD/SUBV_BROADCAST_LOAD that we can extract
+// from. Limit this to cases where the loads have the same input chain and the
+// output chains are unused. This avoids any memory ordering issues.
+static SDValue combineBROADCAST_LOAD(SDNode *N, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI) {
+ assert((N->getOpcode() == X86ISD::VBROADCAST_LOAD ||
+ N->getOpcode() == X86ISD::SUBV_BROADCAST_LOAD) &&
+ "Unknown broadcast load type");
+
// Only do this if the chain result is unused.
if (N->hasAnyUseOfValue(1))
return SDValue();
@@ -50194,13 +50194,13 @@ static SDValue combineBROADCAST_LOAD(SDNode *N, SelectionDAG &DAG,
// Look at other users of our base pointer and try to find a wider broadcast.
// The input chain and the size of the memory VT must match.
for (SDNode *User : Ptr->uses())
- if (User != N && User->getOpcode() == N->getOpcode() &&
+ if (User != N && User->getOpcode() == N->getOpcode() &&
cast<MemIntrinsicSDNode>(User)->getBasePtr() == Ptr &&
cast<MemIntrinsicSDNode>(User)->getChain() == Chain &&
cast<MemIntrinsicSDNode>(User)->getMemoryVT().getSizeInBits() ==
MemVT.getSizeInBits() &&
!User->hasAnyUseOfValue(1) &&
- User->getValueSizeInBits(0).getFixedSize() > VT.getFixedSizeInBits()) {
+ User->getValueSizeInBits(0).getFixedSize() > VT.getFixedSizeInBits()) {
SDValue Extract = extractSubVector(SDValue(User, 0), 0, DAG, SDLoc(N),
VT.getSizeInBits());
Extract = DAG.getBitcast(VT, Extract);
@@ -50271,17 +50271,17 @@ static SDValue combineMOVDQ2Q(SDNode *N, SelectionDAG &DAG) {
return SDValue();
}
-static SDValue combinePDEP(SDNode *N, SelectionDAG &DAG,
- TargetLowering::DAGCombinerInfo &DCI) {
- unsigned NumBits = N->getSimpleValueType(0).getSizeInBits();
- const TargetLowering &TLI = DAG.getTargetLoweringInfo();
- if (TLI.SimplifyDemandedBits(SDValue(N, 0),
- APInt::getAllOnesValue(NumBits), DCI))
- return SDValue(N, 0);
-
- return SDValue();
-}
-
+static SDValue combinePDEP(SDNode *N, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI) {
+ unsigned NumBits = N->getSimpleValueType(0).getSizeInBits();
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ if (TLI.SimplifyDemandedBits(SDValue(N, 0),
+ APInt::getAllOnesValue(NumBits), DCI))
+ return SDValue(N, 0);
+
+ return SDValue();
+}
+
SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
DAGCombinerInfo &DCI) const {
SelectionDAG &DAG = DCI.DAG;
@@ -50318,8 +50318,8 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
case ISD::AND: return combineAnd(N, DAG, DCI, Subtarget);
case ISD::OR: return combineOr(N, DAG, DCI, Subtarget);
case ISD::XOR: return combineXor(N, DAG, DCI, Subtarget);
- case X86ISD::BEXTR:
- case X86ISD::BEXTRI: return combineBEXTR(N, DAG, DCI, Subtarget);
+ case X86ISD::BEXTR:
+ case X86ISD::BEXTRI: return combineBEXTR(N, DAG, DCI, Subtarget);
case ISD::LOAD: return combineLoad(N, DAG, DCI, Subtarget);
case ISD::MLOAD: return combineMaskedLoad(N, DAG, DCI, Subtarget);
case ISD::STORE: return combineStore(N, DAG, DCI, Subtarget);
@@ -50364,17 +50364,17 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
case ISD::SIGN_EXTEND_INREG: return combineSignExtendInReg(N, DAG, Subtarget);
case ISD::ANY_EXTEND_VECTOR_INREG:
case ISD::SIGN_EXTEND_VECTOR_INREG:
- case ISD::ZERO_EXTEND_VECTOR_INREG:
- return combineEXTEND_VECTOR_INREG(N, DAG, DCI, Subtarget);
+ case ISD::ZERO_EXTEND_VECTOR_INREG:
+ return combineEXTEND_VECTOR_INREG(N, DAG, DCI, Subtarget);
case ISD::SETCC: return combineSetCC(N, DAG, Subtarget);
case X86ISD::SETCC: return combineX86SetCC(N, DAG, Subtarget);
case X86ISD::BRCOND: return combineBrCond(N, DAG, Subtarget);
case X86ISD::PACKSS:
case X86ISD::PACKUS: return combineVectorPack(N, DAG, DCI, Subtarget);
- case X86ISD::HADD:
- case X86ISD::HSUB:
- case X86ISD::FHADD:
- case X86ISD::FHSUB: return combineVectorHADDSUB(N, DAG, DCI, Subtarget);
+ case X86ISD::HADD:
+ case X86ISD::HSUB:
+ case X86ISD::FHADD:
+ case X86ISD::FHSUB: return combineVectorHADDSUB(N, DAG, DCI, Subtarget);
case X86ISD::VSHL:
case X86ISD::VSRA:
case X86ISD::VSRL:
@@ -50451,10 +50451,10 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
case ISD::STRICT_FP_EXTEND:
case ISD::FP_EXTEND: return combineFP_EXTEND(N, DAG, Subtarget);
case ISD::FP_ROUND: return combineFP_ROUND(N, DAG, Subtarget);
- case X86ISD::VBROADCAST_LOAD:
- case X86ISD::SUBV_BROADCAST_LOAD: return combineBROADCAST_LOAD(N, DAG, DCI);
+ case X86ISD::VBROADCAST_LOAD:
+ case X86ISD::SUBV_BROADCAST_LOAD: return combineBROADCAST_LOAD(N, DAG, DCI);
case X86ISD::MOVDQ2Q: return combineMOVDQ2Q(N, DAG);
- case X86ISD::PDEP: return combinePDEP(N, DAG, DCI);
+ case X86ISD::PDEP: return combinePDEP(N, DAG, DCI);
}
return SDValue();
@@ -50743,7 +50743,7 @@ static X86::CondCode parseConstraintCode(llvm::StringRef Constraint) {
.Case("{@ccnl}", X86::COND_GE)
.Case("{@ccnle}", X86::COND_G)
.Case("{@ccno}", X86::COND_NO)
- .Case("{@ccnp}", X86::COND_NP)
+ .Case("{@ccnp}", X86::COND_NP)
.Case("{@ccns}", X86::COND_NS)
.Case("{@cco}", X86::COND_O)
.Case("{@ccp}", X86::COND_P)
@@ -50979,8 +50979,8 @@ LowerXConstraint(EVT ConstraintVT) const {
// Lower @cc targets via setcc.
SDValue X86TargetLowering::LowerAsmOutputForConstraint(
- SDValue &Chain, SDValue &Flag, const SDLoc &DL,
- const AsmOperandInfo &OpInfo, SelectionDAG &DAG) const {
+ SDValue &Chain, SDValue &Flag, const SDLoc &DL,
+ const AsmOperandInfo &OpInfo, SelectionDAG &DAG) const {
X86::CondCode Cond = parseConstraintCode(OpInfo.ConstraintCode);
if (Cond == X86::COND_INVALID)
return SDValue();
@@ -51416,26 +51416,26 @@ X86TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
// Not found as a standard register?
if (!Res.second) {
- // Only match x87 registers if the VT is one SelectionDAGBuilder can convert
- // to/from f80.
- if (VT == MVT::Other || VT == MVT::f32 || VT == MVT::f64 || VT == MVT::f80) {
- // Map st(0) -> st(7) -> ST0
- if (Constraint.size() == 7 && Constraint[0] == '{' &&
- tolower(Constraint[1]) == 's' && tolower(Constraint[2]) == 't' &&
- Constraint[3] == '(' &&
- (Constraint[4] >= '0' && Constraint[4] <= '7') &&
- Constraint[5] == ')' && Constraint[6] == '}') {
- // st(7) is not allocatable and thus not a member of RFP80. Return
- // singleton class in cases where we have a reference to it.
- if (Constraint[4] == '7')
- return std::make_pair(X86::FP7, &X86::RFP80_7RegClass);
- return std::make_pair(X86::FP0 + Constraint[4] - '0',
- &X86::RFP80RegClass);
- }
-
- // GCC allows "st(0)" to be called just plain "st".
- if (StringRef("{st}").equals_lower(Constraint))
- return std::make_pair(X86::FP0, &X86::RFP80RegClass);
+ // Only match x87 registers if the VT is one SelectionDAGBuilder can convert
+ // to/from f80.
+ if (VT == MVT::Other || VT == MVT::f32 || VT == MVT::f64 || VT == MVT::f80) {
+ // Map st(0) -> st(7) -> ST0
+ if (Constraint.size() == 7 && Constraint[0] == '{' &&
+ tolower(Constraint[1]) == 's' && tolower(Constraint[2]) == 't' &&
+ Constraint[3] == '(' &&
+ (Constraint[4] >= '0' && Constraint[4] <= '7') &&
+ Constraint[5] == ')' && Constraint[6] == '}') {
+ // st(7) is not allocatable and thus not a member of RFP80. Return
+ // singleton class in cases where we have a reference to it.
+ if (Constraint[4] == '7')
+ return std::make_pair(X86::FP7, &X86::RFP80_7RegClass);
+ return std::make_pair(X86::FP0 + Constraint[4] - '0',
+ &X86::RFP80RegClass);
+ }
+
+ // GCC allows "st(0)" to be called just plain "st".
+ if (StringRef("{st}").equals_lower(Constraint))
+ return std::make_pair(X86::FP0, &X86::RFP80RegClass);
}
// flags -> EFLAGS
@@ -51443,8 +51443,8 @@ X86TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
return std::make_pair(X86::EFLAGS, &X86::CCRRegClass);
// dirflag -> DF
- // Only allow for clobber.
- if (StringRef("{dirflag}").equals_lower(Constraint) && VT == MVT::Other)
+ // Only allow for clobber.
+ if (StringRef("{dirflag}").equals_lower(Constraint) && VT == MVT::Other)
return std::make_pair(X86::DF, &X86::DFCCRRegClass);
// fpsr -> FPSW
@@ -51718,10 +51718,10 @@ X86TargetLowering::getStackProbeSize(MachineFunction &MF) const {
.getAsInteger(0, StackProbeSize);
return StackProbeSize;
}
-
-Align X86TargetLowering::getPrefLoopAlignment(MachineLoop *ML) const {
- if (ML->isInnermost() &&
- ExperimentalPrefInnermostLoopAlignment.getNumOccurrences())
- return Align(1ULL << ExperimentalPrefInnermostLoopAlignment);
- return TargetLowering::getPrefLoopAlignment();
-}
+
+Align X86TargetLowering::getPrefLoopAlignment(MachineLoop *ML) const {
+ if (ML->isInnermost() &&
+ ExperimentalPrefInnermostLoopAlignment.getNumOccurrences())
+ return Align(1ULL << ExperimentalPrefInnermostLoopAlignment);
+ return TargetLowering::getPrefLoopAlignment();
+}
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86ISelLowering.h b/contrib/libs/llvm12/lib/Target/X86/X86ISelLowering.h
index 8c2249a18f..76c83b7df9 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86ISelLowering.h
+++ b/contrib/libs/llvm12/lib/Target/X86/X86ISelLowering.h
@@ -384,10 +384,10 @@ namespace llvm {
/// Vector comparison generating mask bits for fp and
/// integer signed and unsigned data types.
CMPM,
- // Vector mask comparison generating mask bits for FP values.
- CMPMM,
- // Vector mask comparison with SAE for FP values.
- CMPMM_SAE,
+ // Vector mask comparison generating mask bits for FP values.
+ CMPMM,
+ // Vector mask comparison with SAE for FP values.
+ CMPMM_SAE,
// Arithmetic operations with FLAGS results.
ADD,
@@ -402,7 +402,7 @@ namespace llvm {
// Bit field extract.
BEXTR,
- BEXTRI,
+ BEXTRI,
// Zero High Bits Starting with Specified Bit Position.
BZHI,
@@ -709,9 +709,9 @@ namespace llvm {
// For avx512-vp2intersect
VP2INTERSECT,
- // User level interrupts - testui
- TESTUI,
-
+ // User level interrupts - testui
+ TESTUI,
+
/// X86 strict FP compare instructions.
STRICT_FCMP = ISD::FIRST_TARGET_STRICTFP_OPCODE,
STRICT_FCMPS,
@@ -751,9 +751,9 @@ namespace llvm {
STRICT_CVTPS2PH,
STRICT_CVTPH2PS,
- // WARNING: Only add nodes here if they are stric FP nodes. Non-memory and
- // non-strict FP nodes should be above FIRST_TARGET_STRICTFP_OPCODE.
-
+ // WARNING: Only add nodes here if they are stric FP nodes. Non-memory and
+ // non-strict FP nodes should be above FIRST_TARGET_STRICTFP_OPCODE.
+
// Compare and swap.
LCMPXCHG_DAG = ISD::FIRST_TARGET_MEMORY_OPCODE,
LCMPXCHG8_DAG,
@@ -774,12 +774,12 @@ namespace llvm {
// extract_vector_elt, store.
VEXTRACT_STORE,
- // scalar broadcast from memory.
+ // scalar broadcast from memory.
VBROADCAST_LOAD,
- // subvector broadcast from memory.
- SUBV_BROADCAST_LOAD,
-
+ // subvector broadcast from memory.
+ SUBV_BROADCAST_LOAD,
+
// Store FP control world into i16 memory.
FNSTCW16m,
@@ -815,10 +815,10 @@ namespace llvm {
/// specifies the type to store as.
FST,
- /// These instructions grab the address of the next argument
+ /// These instructions grab the address of the next argument
/// from a va_list. (reads and modifies the va_list in memory)
VAARG_64,
- VAARG_X32,
+ VAARG_X32,
// Vector truncating store with unsigned/signed saturation
VTRUNCSTOREUS,
@@ -831,16 +831,16 @@ namespace llvm {
MGATHER,
MSCATTER,
- // Key locker nodes that produce flags.
- AESENC128KL,
- AESDEC128KL,
- AESENC256KL,
- AESDEC256KL,
- AESENCWIDE128KL,
- AESDECWIDE128KL,
- AESENCWIDE256KL,
- AESDECWIDE256KL,
-
+ // Key locker nodes that produce flags.
+ AESENC128KL,
+ AESDEC128KL,
+ AESENC256KL,
+ AESDEC256KL,
+ AESENCWIDE128KL,
+ AESDECWIDE128KL,
+ AESENCWIDE256KL,
+ AESDECWIDE256KL,
+
// WARNING: Do not add anything in the end unless you want the node to
// have memop! In fact, starting from FIRST_TARGET_MEMORY_OPCODE all
// opcodes will be thought as target memory ops!
@@ -855,7 +855,7 @@ namespace llvm {
/// Returns true of the given offset can be
/// fit into displacement field of the instruction.
bool isOffsetSuitableForCodeModel(int64_t Offset, CodeModel::Model M,
- bool hasSymbolicDisplacement);
+ bool hasSymbolicDisplacement);
/// Determines whether the callee is required to pop its
/// own arguments. Callee pop is necessary to support tail calls.
@@ -1128,8 +1128,8 @@ namespace llvm {
}
/// Handle Lowering flag assembly outputs.
- SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue &Flag,
- const SDLoc &DL,
+ SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue &Flag,
+ const SDLoc &DL,
const AsmOperandInfo &Constraint,
SelectionDAG &DAG) const override;
@@ -1408,8 +1408,8 @@ namespace llvm {
SDValue Addr, SelectionDAG &DAG)
const override;
- Align getPrefLoopAlignment(MachineLoop *ML) const override;
-
+ Align getPrefLoopAlignment(MachineLoop *ML) const override;
+
protected:
std::pair<const TargetRegisterClass *, uint8_t>
findRepresentativeClass(const TargetRegisterInfo *TRI,
@@ -1501,7 +1501,7 @@ namespace llvm {
SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerLRINT_LLRINT(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSETCCCARRY(SDValue Op, SelectionDAG &DAG) const;
@@ -1583,7 +1583,7 @@ namespace llvm {
// Utility function to emit the low-level va_arg code for X86-64.
MachineBasicBlock *
- EmitVAARGWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const;
+ EmitVAARGWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const;
/// Utility function to emit the xmm reg save portion of va_start.
MachineBasicBlock *
@@ -1699,7 +1699,7 @@ namespace llvm {
};
/// Generate unpacklo/unpackhi shuffle mask.
- void createUnpackShuffleMask(EVT VT, SmallVectorImpl<int> &Mask, bool Lo,
+ void createUnpackShuffleMask(EVT VT, SmallVectorImpl<int> &Mask, bool Lo,
bool Unary);
/// Similar to unpacklo/unpackhi, but without the 128-bit lane limitation
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86IndirectBranchTracking.cpp b/contrib/libs/llvm12/lib/Target/X86/X86IndirectBranchTracking.cpp
index bba0e8d30d..85410c54a4 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86IndirectBranchTracking.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86IndirectBranchTracking.cpp
@@ -28,7 +28,7 @@ using namespace llvm;
#define DEBUG_TYPE "x86-indirect-branch-tracking"
-cl::opt<bool> IndirectBranchTracking(
+cl::opt<bool> IndirectBranchTracking(
"x86-indirect-branch-tracking", cl::init(false), cl::Hidden,
cl::desc("Enable X86 indirect branch tracking pass."));
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InsertPrefetch.cpp b/contrib/libs/llvm12/lib/Target/X86/X86InsertPrefetch.cpp
index 1c25934ded..004e6fa5eb 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InsertPrefetch.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InsertPrefetch.cpp
@@ -214,10 +214,10 @@ bool X86InsertPrefetch::runOnMachineFunction(MachineFunction &MF) {
MF.CreateMachineInstr(Desc, Current->getDebugLoc(), true);
MachineInstrBuilder MIB(MF, PFetch);
- static_assert(X86::AddrBaseReg == 0 && X86::AddrScaleAmt == 1 &&
- X86::AddrIndexReg == 2 && X86::AddrDisp == 3 &&
- X86::AddrSegmentReg == 4,
- "Unexpected change in X86 operand offset order.");
+ static_assert(X86::AddrBaseReg == 0 && X86::AddrScaleAmt == 1 &&
+ X86::AddrIndexReg == 2 && X86::AddrDisp == 3 &&
+ X86::AddrSegmentReg == 4,
+ "Unexpected change in X86 operand offset order.");
// This assumes X86::AddBaseReg = 0, {...}ScaleAmt = 1, etc.
// FIXME(mtrofin): consider adding a:
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InsertWait.cpp b/contrib/libs/llvm12/lib/Target/X86/X86InsertWait.cpp
index fe9bcfd0fd..56d2709f59 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InsertWait.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InsertWait.cpp
@@ -115,7 +115,7 @@ bool WaitInsert::runOnMachineFunction(MachineFunction &MF) {
return false;
const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>();
- const X86InstrInfo *TII = ST.getInstrInfo();
+ const X86InstrInfo *TII = ST.getInstrInfo();
bool Changed = false;
for (MachineBasicBlock &MBB : MF) {
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstCombineIntrinsic.cpp b/contrib/libs/llvm12/lib/Target/X86/X86InstCombineIntrinsic.cpp
index c6388617c6..c4150ed528 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstCombineIntrinsic.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstCombineIntrinsic.cpp
@@ -1,2017 +1,2017 @@
-//===-- X86InstCombineIntrinsic.cpp - X86 specific InstCombine pass -------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// This file implements a TargetTransformInfo analysis pass specific to the
-/// X86 target machine. It uses the target's detailed information to provide
-/// more precise answers to certain TTI queries, while letting the target
-/// independent and default TTI implementations handle the rest.
-///
-//===----------------------------------------------------------------------===//
-
-#include "X86TargetTransformInfo.h"
-#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/IntrinsicsX86.h"
-#include "llvm/Support/KnownBits.h"
-#include "llvm/Transforms/InstCombine/InstCombiner.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "x86tti"
-
-/// Return a constant boolean vector that has true elements in all positions
-/// where the input constant data vector has an element with the sign bit set.
-static Constant *getNegativeIsTrueBoolVec(Constant *V) {
- VectorType *IntTy = VectorType::getInteger(cast<VectorType>(V->getType()));
- V = ConstantExpr::getBitCast(V, IntTy);
- V = ConstantExpr::getICmp(CmpInst::ICMP_SGT, Constant::getNullValue(IntTy),
- V);
- return V;
-}
-
-/// Convert the x86 XMM integer vector mask to a vector of bools based on
-/// each element's most significant bit (the sign bit).
-static Value *getBoolVecFromMask(Value *Mask) {
- // Fold Constant Mask.
- if (auto *ConstantMask = dyn_cast<ConstantDataVector>(Mask))
- return getNegativeIsTrueBoolVec(ConstantMask);
-
- // Mask was extended from a boolean vector.
- Value *ExtMask;
- if (PatternMatch::match(
- Mask, PatternMatch::m_SExt(PatternMatch::m_Value(ExtMask))) &&
- ExtMask->getType()->isIntOrIntVectorTy(1))
- return ExtMask;
-
- return nullptr;
-}
-
-// TODO: If the x86 backend knew how to convert a bool vector mask back to an
-// XMM register mask efficiently, we could transform all x86 masked intrinsics
-// to LLVM masked intrinsics and remove the x86 masked intrinsic defs.
-static Instruction *simplifyX86MaskedLoad(IntrinsicInst &II, InstCombiner &IC) {
- Value *Ptr = II.getOperand(0);
- Value *Mask = II.getOperand(1);
- Constant *ZeroVec = Constant::getNullValue(II.getType());
-
- // Zero Mask - masked load instruction creates a zero vector.
- if (isa<ConstantAggregateZero>(Mask))
- return IC.replaceInstUsesWith(II, ZeroVec);
-
- // The mask is constant or extended from a bool vector. Convert this x86
- // intrinsic to the LLVM intrinsic to allow target-independent optimizations.
- if (Value *BoolMask = getBoolVecFromMask(Mask)) {
- // First, cast the x86 intrinsic scalar pointer to a vector pointer to match
- // the LLVM intrinsic definition for the pointer argument.
- unsigned AddrSpace = cast<PointerType>(Ptr->getType())->getAddressSpace();
- PointerType *VecPtrTy = PointerType::get(II.getType(), AddrSpace);
- Value *PtrCast = IC.Builder.CreateBitCast(Ptr, VecPtrTy, "castvec");
-
- // The pass-through vector for an x86 masked load is a zero vector.
- CallInst *NewMaskedLoad =
- IC.Builder.CreateMaskedLoad(PtrCast, Align(1), BoolMask, ZeroVec);
- return IC.replaceInstUsesWith(II, NewMaskedLoad);
- }
-
- return nullptr;
-}
-
-// TODO: If the x86 backend knew how to convert a bool vector mask back to an
-// XMM register mask efficiently, we could transform all x86 masked intrinsics
-// to LLVM masked intrinsics and remove the x86 masked intrinsic defs.
-static bool simplifyX86MaskedStore(IntrinsicInst &II, InstCombiner &IC) {
- Value *Ptr = II.getOperand(0);
- Value *Mask = II.getOperand(1);
- Value *Vec = II.getOperand(2);
-
- // Zero Mask - this masked store instruction does nothing.
- if (isa<ConstantAggregateZero>(Mask)) {
- IC.eraseInstFromFunction(II);
- return true;
- }
-
- // The SSE2 version is too weird (eg, unaligned but non-temporal) to do
- // anything else at this level.
- if (II.getIntrinsicID() == Intrinsic::x86_sse2_maskmov_dqu)
- return false;
-
- // The mask is constant or extended from a bool vector. Convert this x86
- // intrinsic to the LLVM intrinsic to allow target-independent optimizations.
- if (Value *BoolMask = getBoolVecFromMask(Mask)) {
- unsigned AddrSpace = cast<PointerType>(Ptr->getType())->getAddressSpace();
- PointerType *VecPtrTy = PointerType::get(Vec->getType(), AddrSpace);
- Value *PtrCast = IC.Builder.CreateBitCast(Ptr, VecPtrTy, "castvec");
-
- IC.Builder.CreateMaskedStore(Vec, PtrCast, Align(1), BoolMask);
-
- // 'Replace uses' doesn't work for stores. Erase the original masked store.
- IC.eraseInstFromFunction(II);
- return true;
- }
-
- return false;
-}
-
-static Value *simplifyX86immShift(const IntrinsicInst &II,
- InstCombiner::BuilderTy &Builder) {
- bool LogicalShift = false;
- bool ShiftLeft = false;
- bool IsImm = false;
-
- switch (II.getIntrinsicID()) {
- default:
- llvm_unreachable("Unexpected intrinsic!");
- case Intrinsic::x86_sse2_psrai_d:
- case Intrinsic::x86_sse2_psrai_w:
- case Intrinsic::x86_avx2_psrai_d:
- case Intrinsic::x86_avx2_psrai_w:
- case Intrinsic::x86_avx512_psrai_q_128:
- case Intrinsic::x86_avx512_psrai_q_256:
- case Intrinsic::x86_avx512_psrai_d_512:
- case Intrinsic::x86_avx512_psrai_q_512:
- case Intrinsic::x86_avx512_psrai_w_512:
- IsImm = true;
- LLVM_FALLTHROUGH;
- case Intrinsic::x86_sse2_psra_d:
- case Intrinsic::x86_sse2_psra_w:
- case Intrinsic::x86_avx2_psra_d:
- case Intrinsic::x86_avx2_psra_w:
- case Intrinsic::x86_avx512_psra_q_128:
- case Intrinsic::x86_avx512_psra_q_256:
- case Intrinsic::x86_avx512_psra_d_512:
- case Intrinsic::x86_avx512_psra_q_512:
- case Intrinsic::x86_avx512_psra_w_512:
- LogicalShift = false;
- ShiftLeft = false;
- break;
- case Intrinsic::x86_sse2_psrli_d:
- case Intrinsic::x86_sse2_psrli_q:
- case Intrinsic::x86_sse2_psrli_w:
- case Intrinsic::x86_avx2_psrli_d:
- case Intrinsic::x86_avx2_psrli_q:
- case Intrinsic::x86_avx2_psrli_w:
- case Intrinsic::x86_avx512_psrli_d_512:
- case Intrinsic::x86_avx512_psrli_q_512:
- case Intrinsic::x86_avx512_psrli_w_512:
- IsImm = true;
- LLVM_FALLTHROUGH;
- case Intrinsic::x86_sse2_psrl_d:
- case Intrinsic::x86_sse2_psrl_q:
- case Intrinsic::x86_sse2_psrl_w:
- case Intrinsic::x86_avx2_psrl_d:
- case Intrinsic::x86_avx2_psrl_q:
- case Intrinsic::x86_avx2_psrl_w:
- case Intrinsic::x86_avx512_psrl_d_512:
- case Intrinsic::x86_avx512_psrl_q_512:
- case Intrinsic::x86_avx512_psrl_w_512:
- LogicalShift = true;
- ShiftLeft = false;
- break;
- case Intrinsic::x86_sse2_pslli_d:
- case Intrinsic::x86_sse2_pslli_q:
- case Intrinsic::x86_sse2_pslli_w:
- case Intrinsic::x86_avx2_pslli_d:
- case Intrinsic::x86_avx2_pslli_q:
- case Intrinsic::x86_avx2_pslli_w:
- case Intrinsic::x86_avx512_pslli_d_512:
- case Intrinsic::x86_avx512_pslli_q_512:
- case Intrinsic::x86_avx512_pslli_w_512:
- IsImm = true;
- LLVM_FALLTHROUGH;
- case Intrinsic::x86_sse2_psll_d:
- case Intrinsic::x86_sse2_psll_q:
- case Intrinsic::x86_sse2_psll_w:
- case Intrinsic::x86_avx2_psll_d:
- case Intrinsic::x86_avx2_psll_q:
- case Intrinsic::x86_avx2_psll_w:
- case Intrinsic::x86_avx512_psll_d_512:
- case Intrinsic::x86_avx512_psll_q_512:
- case Intrinsic::x86_avx512_psll_w_512:
- LogicalShift = true;
- ShiftLeft = true;
- break;
- }
- assert((LogicalShift || !ShiftLeft) && "Only logical shifts can shift left");
-
- auto Vec = II.getArgOperand(0);
- auto Amt = II.getArgOperand(1);
- auto VT = cast<FixedVectorType>(Vec->getType());
- auto SVT = VT->getElementType();
- auto AmtVT = Amt->getType();
- unsigned VWidth = VT->getNumElements();
- unsigned BitWidth = SVT->getPrimitiveSizeInBits();
-
- // If the shift amount is guaranteed to be in-range we can replace it with a
- // generic shift. If its guaranteed to be out of range, logical shifts combine
- // to zero and arithmetic shifts are clamped to (BitWidth - 1).
- if (IsImm) {
- assert(AmtVT->isIntegerTy(32) && "Unexpected shift-by-immediate type");
- KnownBits KnownAmtBits =
- llvm::computeKnownBits(Amt, II.getModule()->getDataLayout());
- if (KnownAmtBits.getMaxValue().ult(BitWidth)) {
- Amt = Builder.CreateZExtOrTrunc(Amt, SVT);
- Amt = Builder.CreateVectorSplat(VWidth, Amt);
- return (LogicalShift ? (ShiftLeft ? Builder.CreateShl(Vec, Amt)
- : Builder.CreateLShr(Vec, Amt))
- : Builder.CreateAShr(Vec, Amt));
- }
- if (KnownAmtBits.getMinValue().uge(BitWidth)) {
- if (LogicalShift)
- return ConstantAggregateZero::get(VT);
- Amt = ConstantInt::get(SVT, BitWidth - 1);
- return Builder.CreateAShr(Vec, Builder.CreateVectorSplat(VWidth, Amt));
- }
- } else {
- // Ensure the first element has an in-range value and the rest of the
- // elements in the bottom 64 bits are zero.
- assert(AmtVT->isVectorTy() && AmtVT->getPrimitiveSizeInBits() == 128 &&
- cast<VectorType>(AmtVT)->getElementType() == SVT &&
- "Unexpected shift-by-scalar type");
- unsigned NumAmtElts = cast<FixedVectorType>(AmtVT)->getNumElements();
- APInt DemandedLower = APInt::getOneBitSet(NumAmtElts, 0);
- APInt DemandedUpper = APInt::getBitsSet(NumAmtElts, 1, NumAmtElts / 2);
- KnownBits KnownLowerBits = llvm::computeKnownBits(
- Amt, DemandedLower, II.getModule()->getDataLayout());
- KnownBits KnownUpperBits = llvm::computeKnownBits(
- Amt, DemandedUpper, II.getModule()->getDataLayout());
- if (KnownLowerBits.getMaxValue().ult(BitWidth) &&
- (DemandedUpper.isNullValue() || KnownUpperBits.isZero())) {
- SmallVector<int, 16> ZeroSplat(VWidth, 0);
- Amt = Builder.CreateShuffleVector(Amt, ZeroSplat);
- return (LogicalShift ? (ShiftLeft ? Builder.CreateShl(Vec, Amt)
- : Builder.CreateLShr(Vec, Amt))
- : Builder.CreateAShr(Vec, Amt));
- }
- }
-
- // Simplify if count is constant vector.
- auto CDV = dyn_cast<ConstantDataVector>(Amt);
- if (!CDV)
- return nullptr;
-
- // SSE2/AVX2 uses all the first 64-bits of the 128-bit vector
- // operand to compute the shift amount.
- assert(AmtVT->isVectorTy() && AmtVT->getPrimitiveSizeInBits() == 128 &&
- cast<VectorType>(AmtVT)->getElementType() == SVT &&
- "Unexpected shift-by-scalar type");
-
- // Concatenate the sub-elements to create the 64-bit value.
- APInt Count(64, 0);
- for (unsigned i = 0, NumSubElts = 64 / BitWidth; i != NumSubElts; ++i) {
- unsigned SubEltIdx = (NumSubElts - 1) - i;
- auto SubElt = cast<ConstantInt>(CDV->getElementAsConstant(SubEltIdx));
- Count <<= BitWidth;
- Count |= SubElt->getValue().zextOrTrunc(64);
- }
-
- // If shift-by-zero then just return the original value.
- if (Count.isNullValue())
- return Vec;
-
- // Handle cases when Shift >= BitWidth.
- if (Count.uge(BitWidth)) {
- // If LogicalShift - just return zero.
- if (LogicalShift)
- return ConstantAggregateZero::get(VT);
-
- // If ArithmeticShift - clamp Shift to (BitWidth - 1).
- Count = APInt(64, BitWidth - 1);
- }
-
- // Get a constant vector of the same type as the first operand.
- auto ShiftAmt = ConstantInt::get(SVT, Count.zextOrTrunc(BitWidth));
- auto ShiftVec = Builder.CreateVectorSplat(VWidth, ShiftAmt);
-
- if (ShiftLeft)
- return Builder.CreateShl(Vec, ShiftVec);
-
- if (LogicalShift)
- return Builder.CreateLShr(Vec, ShiftVec);
-
- return Builder.CreateAShr(Vec, ShiftVec);
-}
-
-// Attempt to simplify AVX2 per-element shift intrinsics to a generic IR shift.
-// Unlike the generic IR shifts, the intrinsics have defined behaviour for out
-// of range shift amounts (logical - set to zero, arithmetic - splat sign bit).
-static Value *simplifyX86varShift(const IntrinsicInst &II,
- InstCombiner::BuilderTy &Builder) {
- bool LogicalShift = false;
- bool ShiftLeft = false;
-
- switch (II.getIntrinsicID()) {
- default:
- llvm_unreachable("Unexpected intrinsic!");
- case Intrinsic::x86_avx2_psrav_d:
- case Intrinsic::x86_avx2_psrav_d_256:
- case Intrinsic::x86_avx512_psrav_q_128:
- case Intrinsic::x86_avx512_psrav_q_256:
- case Intrinsic::x86_avx512_psrav_d_512:
- case Intrinsic::x86_avx512_psrav_q_512:
- case Intrinsic::x86_avx512_psrav_w_128:
- case Intrinsic::x86_avx512_psrav_w_256:
- case Intrinsic::x86_avx512_psrav_w_512:
- LogicalShift = false;
- ShiftLeft = false;
- break;
- case Intrinsic::x86_avx2_psrlv_d:
- case Intrinsic::x86_avx2_psrlv_d_256:
- case Intrinsic::x86_avx2_psrlv_q:
- case Intrinsic::x86_avx2_psrlv_q_256:
- case Intrinsic::x86_avx512_psrlv_d_512:
- case Intrinsic::x86_avx512_psrlv_q_512:
- case Intrinsic::x86_avx512_psrlv_w_128:
- case Intrinsic::x86_avx512_psrlv_w_256:
- case Intrinsic::x86_avx512_psrlv_w_512:
- LogicalShift = true;
- ShiftLeft = false;
- break;
- case Intrinsic::x86_avx2_psllv_d:
- case Intrinsic::x86_avx2_psllv_d_256:
- case Intrinsic::x86_avx2_psllv_q:
- case Intrinsic::x86_avx2_psllv_q_256:
- case Intrinsic::x86_avx512_psllv_d_512:
- case Intrinsic::x86_avx512_psllv_q_512:
- case Intrinsic::x86_avx512_psllv_w_128:
- case Intrinsic::x86_avx512_psllv_w_256:
- case Intrinsic::x86_avx512_psllv_w_512:
- LogicalShift = true;
- ShiftLeft = true;
- break;
- }
- assert((LogicalShift || !ShiftLeft) && "Only logical shifts can shift left");
-
- auto Vec = II.getArgOperand(0);
- auto Amt = II.getArgOperand(1);
- auto VT = cast<FixedVectorType>(II.getType());
- auto SVT = VT->getElementType();
- int NumElts = VT->getNumElements();
- int BitWidth = SVT->getIntegerBitWidth();
-
- // If the shift amount is guaranteed to be in-range we can replace it with a
- // generic shift.
- APInt UpperBits =
- APInt::getHighBitsSet(BitWidth, BitWidth - Log2_32(BitWidth));
- if (llvm::MaskedValueIsZero(Amt, UpperBits,
- II.getModule()->getDataLayout())) {
- return (LogicalShift ? (ShiftLeft ? Builder.CreateShl(Vec, Amt)
- : Builder.CreateLShr(Vec, Amt))
- : Builder.CreateAShr(Vec, Amt));
- }
-
- // Simplify if all shift amounts are constant/undef.
- auto *CShift = dyn_cast<Constant>(Amt);
- if (!CShift)
- return nullptr;
-
- // Collect each element's shift amount.
- // We also collect special cases: UNDEF = -1, OUT-OF-RANGE = BitWidth.
- bool AnyOutOfRange = false;
- SmallVector<int, 8> ShiftAmts;
- for (int I = 0; I < NumElts; ++I) {
- auto *CElt = CShift->getAggregateElement(I);
- if (isa_and_nonnull<UndefValue>(CElt)) {
- ShiftAmts.push_back(-1);
- continue;
- }
-
- auto *COp = dyn_cast_or_null<ConstantInt>(CElt);
- if (!COp)
- return nullptr;
-
- // Handle out of range shifts.
- // If LogicalShift - set to BitWidth (special case).
- // If ArithmeticShift - set to (BitWidth - 1) (sign splat).
- APInt ShiftVal = COp->getValue();
- if (ShiftVal.uge(BitWidth)) {
- AnyOutOfRange = LogicalShift;
- ShiftAmts.push_back(LogicalShift ? BitWidth : BitWidth - 1);
- continue;
- }
-
- ShiftAmts.push_back((int)ShiftVal.getZExtValue());
- }
-
- // If all elements out of range or UNDEF, return vector of zeros/undefs.
- // ArithmeticShift should only hit this if they are all UNDEF.
- auto OutOfRange = [&](int Idx) { return (Idx < 0) || (BitWidth <= Idx); };
- if (llvm::all_of(ShiftAmts, OutOfRange)) {
- SmallVector<Constant *, 8> ConstantVec;
- for (int Idx : ShiftAmts) {
- if (Idx < 0) {
- ConstantVec.push_back(UndefValue::get(SVT));
- } else {
- assert(LogicalShift && "Logical shift expected");
- ConstantVec.push_back(ConstantInt::getNullValue(SVT));
- }
- }
- return ConstantVector::get(ConstantVec);
- }
-
- // We can't handle only some out of range values with generic logical shifts.
- if (AnyOutOfRange)
- return nullptr;
-
- // Build the shift amount constant vector.
- SmallVector<Constant *, 8> ShiftVecAmts;
- for (int Idx : ShiftAmts) {
- if (Idx < 0)
- ShiftVecAmts.push_back(UndefValue::get(SVT));
- else
- ShiftVecAmts.push_back(ConstantInt::get(SVT, Idx));
- }
- auto ShiftVec = ConstantVector::get(ShiftVecAmts);
-
- if (ShiftLeft)
- return Builder.CreateShl(Vec, ShiftVec);
-
- if (LogicalShift)
- return Builder.CreateLShr(Vec, ShiftVec);
-
- return Builder.CreateAShr(Vec, ShiftVec);
-}
-
-static Value *simplifyX86pack(IntrinsicInst &II,
- InstCombiner::BuilderTy &Builder, bool IsSigned) {
- Value *Arg0 = II.getArgOperand(0);
- Value *Arg1 = II.getArgOperand(1);
- Type *ResTy = II.getType();
-
- // Fast all undef handling.
- if (isa<UndefValue>(Arg0) && isa<UndefValue>(Arg1))
- return UndefValue::get(ResTy);
-
- auto *ArgTy = cast<FixedVectorType>(Arg0->getType());
- unsigned NumLanes = ResTy->getPrimitiveSizeInBits() / 128;
- unsigned NumSrcElts = ArgTy->getNumElements();
- assert(cast<FixedVectorType>(ResTy)->getNumElements() == (2 * NumSrcElts) &&
- "Unexpected packing types");
-
- unsigned NumSrcEltsPerLane = NumSrcElts / NumLanes;
- unsigned DstScalarSizeInBits = ResTy->getScalarSizeInBits();
- unsigned SrcScalarSizeInBits = ArgTy->getScalarSizeInBits();
- assert(SrcScalarSizeInBits == (2 * DstScalarSizeInBits) &&
- "Unexpected packing types");
-
- // Constant folding.
- if (!isa<Constant>(Arg0) || !isa<Constant>(Arg1))
- return nullptr;
-
- // Clamp Values - signed/unsigned both use signed clamp values, but they
- // differ on the min/max values.
- APInt MinValue, MaxValue;
- if (IsSigned) {
- // PACKSS: Truncate signed value with signed saturation.
- // Source values less than dst minint are saturated to minint.
- // Source values greater than dst maxint are saturated to maxint.
- MinValue =
- APInt::getSignedMinValue(DstScalarSizeInBits).sext(SrcScalarSizeInBits);
- MaxValue =
- APInt::getSignedMaxValue(DstScalarSizeInBits).sext(SrcScalarSizeInBits);
- } else {
- // PACKUS: Truncate signed value with unsigned saturation.
- // Source values less than zero are saturated to zero.
- // Source values greater than dst maxuint are saturated to maxuint.
- MinValue = APInt::getNullValue(SrcScalarSizeInBits);
- MaxValue = APInt::getLowBitsSet(SrcScalarSizeInBits, DstScalarSizeInBits);
- }
-
- auto *MinC = Constant::getIntegerValue(ArgTy, MinValue);
- auto *MaxC = Constant::getIntegerValue(ArgTy, MaxValue);
- Arg0 = Builder.CreateSelect(Builder.CreateICmpSLT(Arg0, MinC), MinC, Arg0);
- Arg1 = Builder.CreateSelect(Builder.CreateICmpSLT(Arg1, MinC), MinC, Arg1);
- Arg0 = Builder.CreateSelect(Builder.CreateICmpSGT(Arg0, MaxC), MaxC, Arg0);
- Arg1 = Builder.CreateSelect(Builder.CreateICmpSGT(Arg1, MaxC), MaxC, Arg1);
-
- // Shuffle clamped args together at the lane level.
- SmallVector<int, 32> PackMask;
- for (unsigned Lane = 0; Lane != NumLanes; ++Lane) {
- for (unsigned Elt = 0; Elt != NumSrcEltsPerLane; ++Elt)
- PackMask.push_back(Elt + (Lane * NumSrcEltsPerLane));
- for (unsigned Elt = 0; Elt != NumSrcEltsPerLane; ++Elt)
- PackMask.push_back(Elt + (Lane * NumSrcEltsPerLane) + NumSrcElts);
- }
- auto *Shuffle = Builder.CreateShuffleVector(Arg0, Arg1, PackMask);
-
- // Truncate to dst size.
- return Builder.CreateTrunc(Shuffle, ResTy);
-}
-
-static Value *simplifyX86movmsk(const IntrinsicInst &II,
- InstCombiner::BuilderTy &Builder) {
- Value *Arg = II.getArgOperand(0);
- Type *ResTy = II.getType();
-
- // movmsk(undef) -> zero as we must ensure the upper bits are zero.
- if (isa<UndefValue>(Arg))
- return Constant::getNullValue(ResTy);
-
- auto *ArgTy = dyn_cast<FixedVectorType>(Arg->getType());
- // We can't easily peek through x86_mmx types.
- if (!ArgTy)
- return nullptr;
-
- // Expand MOVMSK to compare/bitcast/zext:
- // e.g. PMOVMSKB(v16i8 x):
- // %cmp = icmp slt <16 x i8> %x, zeroinitializer
- // %int = bitcast <16 x i1> %cmp to i16
- // %res = zext i16 %int to i32
- unsigned NumElts = ArgTy->getNumElements();
- Type *IntegerVecTy = VectorType::getInteger(ArgTy);
- Type *IntegerTy = Builder.getIntNTy(NumElts);
-
- Value *Res = Builder.CreateBitCast(Arg, IntegerVecTy);
- Res = Builder.CreateICmpSLT(Res, Constant::getNullValue(IntegerVecTy));
- Res = Builder.CreateBitCast(Res, IntegerTy);
- Res = Builder.CreateZExtOrTrunc(Res, ResTy);
- return Res;
-}
-
-static Value *simplifyX86addcarry(const IntrinsicInst &II,
- InstCombiner::BuilderTy &Builder) {
- Value *CarryIn = II.getArgOperand(0);
- Value *Op1 = II.getArgOperand(1);
- Value *Op2 = II.getArgOperand(2);
- Type *RetTy = II.getType();
- Type *OpTy = Op1->getType();
- assert(RetTy->getStructElementType(0)->isIntegerTy(8) &&
- RetTy->getStructElementType(1) == OpTy && OpTy == Op2->getType() &&
- "Unexpected types for x86 addcarry");
-
- // If carry-in is zero, this is just an unsigned add with overflow.
- if (match(CarryIn, PatternMatch::m_ZeroInt())) {
- Value *UAdd = Builder.CreateIntrinsic(Intrinsic::uadd_with_overflow, OpTy,
- {Op1, Op2});
- // The types have to be adjusted to match the x86 call types.
- Value *UAddResult = Builder.CreateExtractValue(UAdd, 0);
- Value *UAddOV = Builder.CreateZExt(Builder.CreateExtractValue(UAdd, 1),
- Builder.getInt8Ty());
- Value *Res = UndefValue::get(RetTy);
- Res = Builder.CreateInsertValue(Res, UAddOV, 0);
- return Builder.CreateInsertValue(Res, UAddResult, 1);
- }
-
- return nullptr;
-}
-
-static Value *simplifyX86insertps(const IntrinsicInst &II,
- InstCombiner::BuilderTy &Builder) {
- auto *CInt = dyn_cast<ConstantInt>(II.getArgOperand(2));
- if (!CInt)
- return nullptr;
-
- auto *VecTy = cast<FixedVectorType>(II.getType());
- assert(VecTy->getNumElements() == 4 && "insertps with wrong vector type");
-
- // The immediate permute control byte looks like this:
- // [3:0] - zero mask for each 32-bit lane
- // [5:4] - select one 32-bit destination lane
- // [7:6] - select one 32-bit source lane
-
- uint8_t Imm = CInt->getZExtValue();
- uint8_t ZMask = Imm & 0xf;
- uint8_t DestLane = (Imm >> 4) & 0x3;
- uint8_t SourceLane = (Imm >> 6) & 0x3;
-
- ConstantAggregateZero *ZeroVector = ConstantAggregateZero::get(VecTy);
-
- // If all zero mask bits are set, this was just a weird way to
- // generate a zero vector.
- if (ZMask == 0xf)
- return ZeroVector;
-
- // Initialize by passing all of the first source bits through.
- int ShuffleMask[4] = {0, 1, 2, 3};
-
- // We may replace the second operand with the zero vector.
- Value *V1 = II.getArgOperand(1);
-
- if (ZMask) {
- // If the zero mask is being used with a single input or the zero mask
- // overrides the destination lane, this is a shuffle with the zero vector.
- if ((II.getArgOperand(0) == II.getArgOperand(1)) ||
- (ZMask & (1 << DestLane))) {
- V1 = ZeroVector;
- // We may still move 32-bits of the first source vector from one lane
- // to another.
- ShuffleMask[DestLane] = SourceLane;
- // The zero mask may override the previous insert operation.
- for (unsigned i = 0; i < 4; ++i)
- if ((ZMask >> i) & 0x1)
- ShuffleMask[i] = i + 4;
- } else {
- // TODO: Model this case as 2 shuffles or a 'logical and' plus shuffle?
- return nullptr;
- }
- } else {
- // Replace the selected destination lane with the selected source lane.
- ShuffleMask[DestLane] = SourceLane + 4;
- }
-
- return Builder.CreateShuffleVector(II.getArgOperand(0), V1, ShuffleMask);
-}
-
-/// Attempt to simplify SSE4A EXTRQ/EXTRQI instructions using constant folding
-/// or conversion to a shuffle vector.
-static Value *simplifyX86extrq(IntrinsicInst &II, Value *Op0,
- ConstantInt *CILength, ConstantInt *CIIndex,
- InstCombiner::BuilderTy &Builder) {
- auto LowConstantHighUndef = [&](uint64_t Val) {
- Type *IntTy64 = Type::getInt64Ty(II.getContext());
- Constant *Args[] = {ConstantInt::get(IntTy64, Val),
- UndefValue::get(IntTy64)};
- return ConstantVector::get(Args);
- };
-
- // See if we're dealing with constant values.
- Constant *C0 = dyn_cast<Constant>(Op0);
- ConstantInt *CI0 =
- C0 ? dyn_cast_or_null<ConstantInt>(C0->getAggregateElement((unsigned)0))
- : nullptr;
-
- // Attempt to constant fold.
- if (CILength && CIIndex) {
- // From AMD documentation: "The bit index and field length are each six
- // bits in length other bits of the field are ignored."
- APInt APIndex = CIIndex->getValue().zextOrTrunc(6);
- APInt APLength = CILength->getValue().zextOrTrunc(6);
-
- unsigned Index = APIndex.getZExtValue();
-
- // From AMD documentation: "a value of zero in the field length is
- // defined as length of 64".
- unsigned Length = APLength == 0 ? 64 : APLength.getZExtValue();
-
- // From AMD documentation: "If the sum of the bit index + length field
- // is greater than 64, the results are undefined".
- unsigned End = Index + Length;
-
- // Note that both field index and field length are 8-bit quantities.
- // Since variables 'Index' and 'Length' are unsigned values
- // obtained from zero-extending field index and field length
- // respectively, their sum should never wrap around.
- if (End > 64)
- return UndefValue::get(II.getType());
-
- // If we are inserting whole bytes, we can convert this to a shuffle.
- // Lowering can recognize EXTRQI shuffle masks.
- if ((Length % 8) == 0 && (Index % 8) == 0) {
- // Convert bit indices to byte indices.
- Length /= 8;
- Index /= 8;
-
- Type *IntTy8 = Type::getInt8Ty(II.getContext());
- auto *ShufTy = FixedVectorType::get(IntTy8, 16);
-
- SmallVector<int, 16> ShuffleMask;
- for (int i = 0; i != (int)Length; ++i)
- ShuffleMask.push_back(i + Index);
- for (int i = Length; i != 8; ++i)
- ShuffleMask.push_back(i + 16);
- for (int i = 8; i != 16; ++i)
- ShuffleMask.push_back(-1);
-
- Value *SV = Builder.CreateShuffleVector(
- Builder.CreateBitCast(Op0, ShufTy),
- ConstantAggregateZero::get(ShufTy), ShuffleMask);
- return Builder.CreateBitCast(SV, II.getType());
- }
-
- // Constant Fold - shift Index'th bit to lowest position and mask off
- // Length bits.
- if (CI0) {
- APInt Elt = CI0->getValue();
- Elt.lshrInPlace(Index);
- Elt = Elt.zextOrTrunc(Length);
- return LowConstantHighUndef(Elt.getZExtValue());
- }
-
- // If we were an EXTRQ call, we'll save registers if we convert to EXTRQI.
- if (II.getIntrinsicID() == Intrinsic::x86_sse4a_extrq) {
- Value *Args[] = {Op0, CILength, CIIndex};
- Module *M = II.getModule();
- Function *F = Intrinsic::getDeclaration(M, Intrinsic::x86_sse4a_extrqi);
- return Builder.CreateCall(F, Args);
- }
- }
-
- // Constant Fold - extraction from zero is always {zero, undef}.
- if (CI0 && CI0->isZero())
- return LowConstantHighUndef(0);
-
- return nullptr;
-}
-
-/// Attempt to simplify SSE4A INSERTQ/INSERTQI instructions using constant
-/// folding or conversion to a shuffle vector.
-static Value *simplifyX86insertq(IntrinsicInst &II, Value *Op0, Value *Op1,
- APInt APLength, APInt APIndex,
- InstCombiner::BuilderTy &Builder) {
- // From AMD documentation: "The bit index and field length are each six bits
- // in length other bits of the field are ignored."
- APIndex = APIndex.zextOrTrunc(6);
- APLength = APLength.zextOrTrunc(6);
-
- // Attempt to constant fold.
- unsigned Index = APIndex.getZExtValue();
-
- // From AMD documentation: "a value of zero in the field length is
- // defined as length of 64".
- unsigned Length = APLength == 0 ? 64 : APLength.getZExtValue();
-
- // From AMD documentation: "If the sum of the bit index + length field
- // is greater than 64, the results are undefined".
- unsigned End = Index + Length;
-
- // Note that both field index and field length are 8-bit quantities.
- // Since variables 'Index' and 'Length' are unsigned values
- // obtained from zero-extending field index and field length
- // respectively, their sum should never wrap around.
- if (End > 64)
- return UndefValue::get(II.getType());
-
- // If we are inserting whole bytes, we can convert this to a shuffle.
- // Lowering can recognize INSERTQI shuffle masks.
- if ((Length % 8) == 0 && (Index % 8) == 0) {
- // Convert bit indices to byte indices.
- Length /= 8;
- Index /= 8;
-
- Type *IntTy8 = Type::getInt8Ty(II.getContext());
- auto *ShufTy = FixedVectorType::get(IntTy8, 16);
-
- SmallVector<int, 16> ShuffleMask;
- for (int i = 0; i != (int)Index; ++i)
- ShuffleMask.push_back(i);
- for (int i = 0; i != (int)Length; ++i)
- ShuffleMask.push_back(i + 16);
- for (int i = Index + Length; i != 8; ++i)
- ShuffleMask.push_back(i);
- for (int i = 8; i != 16; ++i)
- ShuffleMask.push_back(-1);
-
- Value *SV = Builder.CreateShuffleVector(Builder.CreateBitCast(Op0, ShufTy),
- Builder.CreateBitCast(Op1, ShufTy),
- ShuffleMask);
- return Builder.CreateBitCast(SV, II.getType());
- }
-
- // See if we're dealing with constant values.
- Constant *C0 = dyn_cast<Constant>(Op0);
- Constant *C1 = dyn_cast<Constant>(Op1);
- ConstantInt *CI00 =
- C0 ? dyn_cast_or_null<ConstantInt>(C0->getAggregateElement((unsigned)0))
- : nullptr;
- ConstantInt *CI10 =
- C1 ? dyn_cast_or_null<ConstantInt>(C1->getAggregateElement((unsigned)0))
- : nullptr;
-
- // Constant Fold - insert bottom Length bits starting at the Index'th bit.
- if (CI00 && CI10) {
- APInt V00 = CI00->getValue();
- APInt V10 = CI10->getValue();
- APInt Mask = APInt::getLowBitsSet(64, Length).shl(Index);
- V00 = V00 & ~Mask;
- V10 = V10.zextOrTrunc(Length).zextOrTrunc(64).shl(Index);
- APInt Val = V00 | V10;
- Type *IntTy64 = Type::getInt64Ty(II.getContext());
- Constant *Args[] = {ConstantInt::get(IntTy64, Val.getZExtValue()),
- UndefValue::get(IntTy64)};
- return ConstantVector::get(Args);
- }
-
- // If we were an INSERTQ call, we'll save demanded elements if we convert to
- // INSERTQI.
- if (II.getIntrinsicID() == Intrinsic::x86_sse4a_insertq) {
- Type *IntTy8 = Type::getInt8Ty(II.getContext());
- Constant *CILength = ConstantInt::get(IntTy8, Length, false);
- Constant *CIIndex = ConstantInt::get(IntTy8, Index, false);
-
- Value *Args[] = {Op0, Op1, CILength, CIIndex};
- Module *M = II.getModule();
- Function *F = Intrinsic::getDeclaration(M, Intrinsic::x86_sse4a_insertqi);
- return Builder.CreateCall(F, Args);
- }
-
- return nullptr;
-}
-
-/// Attempt to convert pshufb* to shufflevector if the mask is constant.
-static Value *simplifyX86pshufb(const IntrinsicInst &II,
- InstCombiner::BuilderTy &Builder) {
- Constant *V = dyn_cast<Constant>(II.getArgOperand(1));
- if (!V)
- return nullptr;
-
- auto *VecTy = cast<FixedVectorType>(II.getType());
- unsigned NumElts = VecTy->getNumElements();
- assert((NumElts == 16 || NumElts == 32 || NumElts == 64) &&
- "Unexpected number of elements in shuffle mask!");
-
- // Construct a shuffle mask from constant integers or UNDEFs.
- int Indexes[64];
-
- // Each byte in the shuffle control mask forms an index to permute the
- // corresponding byte in the destination operand.
- for (unsigned I = 0; I < NumElts; ++I) {
- Constant *COp = V->getAggregateElement(I);
- if (!COp || (!isa<UndefValue>(COp) && !isa<ConstantInt>(COp)))
- return nullptr;
-
- if (isa<UndefValue>(COp)) {
- Indexes[I] = -1;
- continue;
- }
-
- int8_t Index = cast<ConstantInt>(COp)->getValue().getZExtValue();
-
- // If the most significant bit (bit[7]) of each byte of the shuffle
- // control mask is set, then zero is written in the result byte.
- // The zero vector is in the right-hand side of the resulting
- // shufflevector.
-
- // The value of each index for the high 128-bit lane is the least
- // significant 4 bits of the respective shuffle control byte.
- Index = ((Index < 0) ? NumElts : Index & 0x0F) + (I & 0xF0);
- Indexes[I] = Index;
- }
-
- auto V1 = II.getArgOperand(0);
- auto V2 = Constant::getNullValue(VecTy);
- return Builder.CreateShuffleVector(V1, V2, makeArrayRef(Indexes, NumElts));
-}
-
-/// Attempt to convert vpermilvar* to shufflevector if the mask is constant.
-static Value *simplifyX86vpermilvar(const IntrinsicInst &II,
- InstCombiner::BuilderTy &Builder) {
- Constant *V = dyn_cast<Constant>(II.getArgOperand(1));
- if (!V)
- return nullptr;
-
- auto *VecTy = cast<FixedVectorType>(II.getType());
- unsigned NumElts = VecTy->getNumElements();
- bool IsPD = VecTy->getScalarType()->isDoubleTy();
- unsigned NumLaneElts = IsPD ? 2 : 4;
- assert(NumElts == 16 || NumElts == 8 || NumElts == 4 || NumElts == 2);
-
- // Construct a shuffle mask from constant integers or UNDEFs.
- int Indexes[16];
-
- // The intrinsics only read one or two bits, clear the rest.
- for (unsigned I = 0; I < NumElts; ++I) {
- Constant *COp = V->getAggregateElement(I);
- if (!COp || (!isa<UndefValue>(COp) && !isa<ConstantInt>(COp)))
- return nullptr;
-
- if (isa<UndefValue>(COp)) {
- Indexes[I] = -1;
- continue;
- }
-
- APInt Index = cast<ConstantInt>(COp)->getValue();
- Index = Index.zextOrTrunc(32).getLoBits(2);
-
- // The PD variants uses bit 1 to select per-lane element index, so
- // shift down to convert to generic shuffle mask index.
- if (IsPD)
- Index.lshrInPlace(1);
-
- // The _256 variants are a bit trickier since the mask bits always index
- // into the corresponding 128 half. In order to convert to a generic
- // shuffle, we have to make that explicit.
- Index += APInt(32, (I / NumLaneElts) * NumLaneElts);
-
- Indexes[I] = Index.getZExtValue();
- }
-
- auto V1 = II.getArgOperand(0);
- return Builder.CreateShuffleVector(V1, makeArrayRef(Indexes, NumElts));
-}
-
-/// Attempt to convert vpermd/vpermps to shufflevector if the mask is constant.
-static Value *simplifyX86vpermv(const IntrinsicInst &II,
- InstCombiner::BuilderTy &Builder) {
- auto *V = dyn_cast<Constant>(II.getArgOperand(1));
- if (!V)
- return nullptr;
-
- auto *VecTy = cast<FixedVectorType>(II.getType());
- unsigned Size = VecTy->getNumElements();
- assert((Size == 4 || Size == 8 || Size == 16 || Size == 32 || Size == 64) &&
- "Unexpected shuffle mask size");
-
- // Construct a shuffle mask from constant integers or UNDEFs.
- int Indexes[64];
-
- for (unsigned I = 0; I < Size; ++I) {
- Constant *COp = V->getAggregateElement(I);
- if (!COp || (!isa<UndefValue>(COp) && !isa<ConstantInt>(COp)))
- return nullptr;
-
- if (isa<UndefValue>(COp)) {
- Indexes[I] = -1;
- continue;
- }
-
- uint32_t Index = cast<ConstantInt>(COp)->getZExtValue();
- Index &= Size - 1;
- Indexes[I] = Index;
- }
-
- auto V1 = II.getArgOperand(0);
- return Builder.CreateShuffleVector(V1, makeArrayRef(Indexes, Size));
-}
-
-Optional<Instruction *>
-X86TTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
- auto SimplifyDemandedVectorEltsLow = [&IC](Value *Op, unsigned Width,
- unsigned DemandedWidth) {
- APInt UndefElts(Width, 0);
- APInt DemandedElts = APInt::getLowBitsSet(Width, DemandedWidth);
- return IC.SimplifyDemandedVectorElts(Op, DemandedElts, UndefElts);
- };
-
- Intrinsic::ID IID = II.getIntrinsicID();
- switch (IID) {
- case Intrinsic::x86_bmi_bextr_32:
- case Intrinsic::x86_bmi_bextr_64:
- case Intrinsic::x86_tbm_bextri_u32:
- case Intrinsic::x86_tbm_bextri_u64:
- // If the RHS is a constant we can try some simplifications.
- if (auto *C = dyn_cast<ConstantInt>(II.getArgOperand(1))) {
- uint64_t Shift = C->getZExtValue();
- uint64_t Length = (Shift >> 8) & 0xff;
- Shift &= 0xff;
- unsigned BitWidth = II.getType()->getIntegerBitWidth();
- // If the length is 0 or the shift is out of range, replace with zero.
- if (Length == 0 || Shift >= BitWidth) {
- return IC.replaceInstUsesWith(II, ConstantInt::get(II.getType(), 0));
- }
- // If the LHS is also a constant, we can completely constant fold this.
- if (auto *InC = dyn_cast<ConstantInt>(II.getArgOperand(0))) {
- uint64_t Result = InC->getZExtValue() >> Shift;
- if (Length > BitWidth)
- Length = BitWidth;
- Result &= maskTrailingOnes<uint64_t>(Length);
- return IC.replaceInstUsesWith(II,
- ConstantInt::get(II.getType(), Result));
- }
- // TODO should we turn this into 'and' if shift is 0? Or 'shl' if we
- // are only masking bits that a shift already cleared?
- }
- break;
-
- case Intrinsic::x86_bmi_bzhi_32:
- case Intrinsic::x86_bmi_bzhi_64:
- // If the RHS is a constant we can try some simplifications.
- if (auto *C = dyn_cast<ConstantInt>(II.getArgOperand(1))) {
- uint64_t Index = C->getZExtValue() & 0xff;
- unsigned BitWidth = II.getType()->getIntegerBitWidth();
- if (Index >= BitWidth) {
- return IC.replaceInstUsesWith(II, II.getArgOperand(0));
- }
- if (Index == 0) {
- return IC.replaceInstUsesWith(II, ConstantInt::get(II.getType(), 0));
- }
- // If the LHS is also a constant, we can completely constant fold this.
- if (auto *InC = dyn_cast<ConstantInt>(II.getArgOperand(0))) {
- uint64_t Result = InC->getZExtValue();
- Result &= maskTrailingOnes<uint64_t>(Index);
- return IC.replaceInstUsesWith(II,
- ConstantInt::get(II.getType(), Result));
- }
- // TODO should we convert this to an AND if the RHS is constant?
- }
- break;
- case Intrinsic::x86_bmi_pext_32:
- case Intrinsic::x86_bmi_pext_64:
- if (auto *MaskC = dyn_cast<ConstantInt>(II.getArgOperand(1))) {
- if (MaskC->isNullValue()) {
- return IC.replaceInstUsesWith(II, ConstantInt::get(II.getType(), 0));
- }
- if (MaskC->isAllOnesValue()) {
- return IC.replaceInstUsesWith(II, II.getArgOperand(0));
- }
-
- if (MaskC->getValue().isShiftedMask()) {
- // any single contingous sequence of 1s anywhere in the mask simply
- // describes a subset of the input bits shifted to the appropriate
- // position. Replace with the straight forward IR.
- unsigned ShiftAmount = MaskC->getValue().countTrailingZeros();
- Value *Input = II.getArgOperand(0);
- Value *Masked = IC.Builder.CreateAnd(Input, II.getArgOperand(1));
- Value *Shifted = IC.Builder.CreateLShr(Masked,
- ConstantInt::get(II.getType(),
- ShiftAmount));
- return IC.replaceInstUsesWith(II, Shifted);
- }
-
-
- if (auto *SrcC = dyn_cast<ConstantInt>(II.getArgOperand(0))) {
- uint64_t Src = SrcC->getZExtValue();
- uint64_t Mask = MaskC->getZExtValue();
- uint64_t Result = 0;
- uint64_t BitToSet = 1;
-
- while (Mask) {
- // Isolate lowest set bit.
- uint64_t BitToTest = Mask & -Mask;
- if (BitToTest & Src)
- Result |= BitToSet;
-
- BitToSet <<= 1;
- // Clear lowest set bit.
- Mask &= Mask - 1;
- }
-
- return IC.replaceInstUsesWith(II,
- ConstantInt::get(II.getType(), Result));
- }
- }
- break;
- case Intrinsic::x86_bmi_pdep_32:
- case Intrinsic::x86_bmi_pdep_64:
- if (auto *MaskC = dyn_cast<ConstantInt>(II.getArgOperand(1))) {
- if (MaskC->isNullValue()) {
- return IC.replaceInstUsesWith(II, ConstantInt::get(II.getType(), 0));
- }
- if (MaskC->isAllOnesValue()) {
- return IC.replaceInstUsesWith(II, II.getArgOperand(0));
- }
- if (MaskC->getValue().isShiftedMask()) {
- // any single contingous sequence of 1s anywhere in the mask simply
- // describes a subset of the input bits shifted to the appropriate
- // position. Replace with the straight forward IR.
- unsigned ShiftAmount = MaskC->getValue().countTrailingZeros();
- Value *Input = II.getArgOperand(0);
- Value *Shifted = IC.Builder.CreateShl(Input,
- ConstantInt::get(II.getType(),
- ShiftAmount));
- Value *Masked = IC.Builder.CreateAnd(Shifted, II.getArgOperand(1));
- return IC.replaceInstUsesWith(II, Masked);
- }
-
- if (auto *SrcC = dyn_cast<ConstantInt>(II.getArgOperand(0))) {
- uint64_t Src = SrcC->getZExtValue();
- uint64_t Mask = MaskC->getZExtValue();
- uint64_t Result = 0;
- uint64_t BitToTest = 1;
-
- while (Mask) {
- // Isolate lowest set bit.
- uint64_t BitToSet = Mask & -Mask;
- if (BitToTest & Src)
- Result |= BitToSet;
-
- BitToTest <<= 1;
- // Clear lowest set bit;
- Mask &= Mask - 1;
- }
-
- return IC.replaceInstUsesWith(II,
- ConstantInt::get(II.getType(), Result));
- }
- }
- break;
-
- case Intrinsic::x86_sse_cvtss2si:
- case Intrinsic::x86_sse_cvtss2si64:
- case Intrinsic::x86_sse_cvttss2si:
- case Intrinsic::x86_sse_cvttss2si64:
- case Intrinsic::x86_sse2_cvtsd2si:
- case Intrinsic::x86_sse2_cvtsd2si64:
- case Intrinsic::x86_sse2_cvttsd2si:
- case Intrinsic::x86_sse2_cvttsd2si64:
- case Intrinsic::x86_avx512_vcvtss2si32:
- case Intrinsic::x86_avx512_vcvtss2si64:
- case Intrinsic::x86_avx512_vcvtss2usi32:
- case Intrinsic::x86_avx512_vcvtss2usi64:
- case Intrinsic::x86_avx512_vcvtsd2si32:
- case Intrinsic::x86_avx512_vcvtsd2si64:
- case Intrinsic::x86_avx512_vcvtsd2usi32:
- case Intrinsic::x86_avx512_vcvtsd2usi64:
- case Intrinsic::x86_avx512_cvttss2si:
- case Intrinsic::x86_avx512_cvttss2si64:
- case Intrinsic::x86_avx512_cvttss2usi:
- case Intrinsic::x86_avx512_cvttss2usi64:
- case Intrinsic::x86_avx512_cvttsd2si:
- case Intrinsic::x86_avx512_cvttsd2si64:
- case Intrinsic::x86_avx512_cvttsd2usi:
- case Intrinsic::x86_avx512_cvttsd2usi64: {
- // These intrinsics only demand the 0th element of their input vectors. If
- // we can simplify the input based on that, do so now.
- Value *Arg = II.getArgOperand(0);
- unsigned VWidth = cast<FixedVectorType>(Arg->getType())->getNumElements();
- if (Value *V = SimplifyDemandedVectorEltsLow(Arg, VWidth, 1)) {
- return IC.replaceOperand(II, 0, V);
- }
- break;
- }
-
- case Intrinsic::x86_mmx_pmovmskb:
- case Intrinsic::x86_sse_movmsk_ps:
- case Intrinsic::x86_sse2_movmsk_pd:
- case Intrinsic::x86_sse2_pmovmskb_128:
- case Intrinsic::x86_avx_movmsk_pd_256:
- case Intrinsic::x86_avx_movmsk_ps_256:
- case Intrinsic::x86_avx2_pmovmskb:
- if (Value *V = simplifyX86movmsk(II, IC.Builder)) {
- return IC.replaceInstUsesWith(II, V);
- }
- break;
-
- case Intrinsic::x86_sse_comieq_ss:
- case Intrinsic::x86_sse_comige_ss:
- case Intrinsic::x86_sse_comigt_ss:
- case Intrinsic::x86_sse_comile_ss:
- case Intrinsic::x86_sse_comilt_ss:
- case Intrinsic::x86_sse_comineq_ss:
- case Intrinsic::x86_sse_ucomieq_ss:
- case Intrinsic::x86_sse_ucomige_ss:
- case Intrinsic::x86_sse_ucomigt_ss:
- case Intrinsic::x86_sse_ucomile_ss:
- case Intrinsic::x86_sse_ucomilt_ss:
- case Intrinsic::x86_sse_ucomineq_ss:
- case Intrinsic::x86_sse2_comieq_sd:
- case Intrinsic::x86_sse2_comige_sd:
- case Intrinsic::x86_sse2_comigt_sd:
- case Intrinsic::x86_sse2_comile_sd:
- case Intrinsic::x86_sse2_comilt_sd:
- case Intrinsic::x86_sse2_comineq_sd:
- case Intrinsic::x86_sse2_ucomieq_sd:
- case Intrinsic::x86_sse2_ucomige_sd:
- case Intrinsic::x86_sse2_ucomigt_sd:
- case Intrinsic::x86_sse2_ucomile_sd:
- case Intrinsic::x86_sse2_ucomilt_sd:
- case Intrinsic::x86_sse2_ucomineq_sd:
- case Intrinsic::x86_avx512_vcomi_ss:
- case Intrinsic::x86_avx512_vcomi_sd:
- case Intrinsic::x86_avx512_mask_cmp_ss:
- case Intrinsic::x86_avx512_mask_cmp_sd: {
- // These intrinsics only demand the 0th element of their input vectors. If
- // we can simplify the input based on that, do so now.
- bool MadeChange = false;
- Value *Arg0 = II.getArgOperand(0);
- Value *Arg1 = II.getArgOperand(1);
- unsigned VWidth = cast<FixedVectorType>(Arg0->getType())->getNumElements();
- if (Value *V = SimplifyDemandedVectorEltsLow(Arg0, VWidth, 1)) {
- IC.replaceOperand(II, 0, V);
- MadeChange = true;
- }
- if (Value *V = SimplifyDemandedVectorEltsLow(Arg1, VWidth, 1)) {
- IC.replaceOperand(II, 1, V);
- MadeChange = true;
- }
- if (MadeChange) {
- return &II;
- }
- break;
- }
-
- case Intrinsic::x86_avx512_add_ps_512:
- case Intrinsic::x86_avx512_div_ps_512:
- case Intrinsic::x86_avx512_mul_ps_512:
- case Intrinsic::x86_avx512_sub_ps_512:
- case Intrinsic::x86_avx512_add_pd_512:
- case Intrinsic::x86_avx512_div_pd_512:
- case Intrinsic::x86_avx512_mul_pd_512:
- case Intrinsic::x86_avx512_sub_pd_512:
- // If the rounding mode is CUR_DIRECTION(4) we can turn these into regular
- // IR operations.
- if (auto *R = dyn_cast<ConstantInt>(II.getArgOperand(2))) {
- if (R->getValue() == 4) {
- Value *Arg0 = II.getArgOperand(0);
- Value *Arg1 = II.getArgOperand(1);
-
- Value *V;
- switch (IID) {
- default:
- llvm_unreachable("Case stmts out of sync!");
- case Intrinsic::x86_avx512_add_ps_512:
- case Intrinsic::x86_avx512_add_pd_512:
- V = IC.Builder.CreateFAdd(Arg0, Arg1);
- break;
- case Intrinsic::x86_avx512_sub_ps_512:
- case Intrinsic::x86_avx512_sub_pd_512:
- V = IC.Builder.CreateFSub(Arg0, Arg1);
- break;
- case Intrinsic::x86_avx512_mul_ps_512:
- case Intrinsic::x86_avx512_mul_pd_512:
- V = IC.Builder.CreateFMul(Arg0, Arg1);
- break;
- case Intrinsic::x86_avx512_div_ps_512:
- case Intrinsic::x86_avx512_div_pd_512:
- V = IC.Builder.CreateFDiv(Arg0, Arg1);
- break;
- }
-
- return IC.replaceInstUsesWith(II, V);
- }
- }
- break;
-
- case Intrinsic::x86_avx512_mask_add_ss_round:
- case Intrinsic::x86_avx512_mask_div_ss_round:
- case Intrinsic::x86_avx512_mask_mul_ss_round:
- case Intrinsic::x86_avx512_mask_sub_ss_round:
- case Intrinsic::x86_avx512_mask_add_sd_round:
- case Intrinsic::x86_avx512_mask_div_sd_round:
- case Intrinsic::x86_avx512_mask_mul_sd_round:
- case Intrinsic::x86_avx512_mask_sub_sd_round:
- // If the rounding mode is CUR_DIRECTION(4) we can turn these into regular
- // IR operations.
- if (auto *R = dyn_cast<ConstantInt>(II.getArgOperand(4))) {
- if (R->getValue() == 4) {
- // Extract the element as scalars.
- Value *Arg0 = II.getArgOperand(0);
- Value *Arg1 = II.getArgOperand(1);
- Value *LHS = IC.Builder.CreateExtractElement(Arg0, (uint64_t)0);
- Value *RHS = IC.Builder.CreateExtractElement(Arg1, (uint64_t)0);
-
- Value *V;
- switch (IID) {
- default:
- llvm_unreachable("Case stmts out of sync!");
- case Intrinsic::x86_avx512_mask_add_ss_round:
- case Intrinsic::x86_avx512_mask_add_sd_round:
- V = IC.Builder.CreateFAdd(LHS, RHS);
- break;
- case Intrinsic::x86_avx512_mask_sub_ss_round:
- case Intrinsic::x86_avx512_mask_sub_sd_round:
- V = IC.Builder.CreateFSub(LHS, RHS);
- break;
- case Intrinsic::x86_avx512_mask_mul_ss_round:
- case Intrinsic::x86_avx512_mask_mul_sd_round:
- V = IC.Builder.CreateFMul(LHS, RHS);
- break;
- case Intrinsic::x86_avx512_mask_div_ss_round:
- case Intrinsic::x86_avx512_mask_div_sd_round:
- V = IC.Builder.CreateFDiv(LHS, RHS);
- break;
- }
-
- // Handle the masking aspect of the intrinsic.
- Value *Mask = II.getArgOperand(3);
- auto *C = dyn_cast<ConstantInt>(Mask);
- // We don't need a select if we know the mask bit is a 1.
- if (!C || !C->getValue()[0]) {
- // Cast the mask to an i1 vector and then extract the lowest element.
- auto *MaskTy = FixedVectorType::get(
- IC.Builder.getInt1Ty(),
- cast<IntegerType>(Mask->getType())->getBitWidth());
- Mask = IC.Builder.CreateBitCast(Mask, MaskTy);
- Mask = IC.Builder.CreateExtractElement(Mask, (uint64_t)0);
- // Extract the lowest element from the passthru operand.
- Value *Passthru =
- IC.Builder.CreateExtractElement(II.getArgOperand(2), (uint64_t)0);
- V = IC.Builder.CreateSelect(Mask, V, Passthru);
- }
-
- // Insert the result back into the original argument 0.
- V = IC.Builder.CreateInsertElement(Arg0, V, (uint64_t)0);
-
- return IC.replaceInstUsesWith(II, V);
- }
- }
- break;
-
- // Constant fold ashr( <A x Bi>, Ci ).
- // Constant fold lshr( <A x Bi>, Ci ).
- // Constant fold shl( <A x Bi>, Ci ).
- case Intrinsic::x86_sse2_psrai_d:
- case Intrinsic::x86_sse2_psrai_w:
- case Intrinsic::x86_avx2_psrai_d:
- case Intrinsic::x86_avx2_psrai_w:
- case Intrinsic::x86_avx512_psrai_q_128:
- case Intrinsic::x86_avx512_psrai_q_256:
- case Intrinsic::x86_avx512_psrai_d_512:
- case Intrinsic::x86_avx512_psrai_q_512:
- case Intrinsic::x86_avx512_psrai_w_512:
- case Intrinsic::x86_sse2_psrli_d:
- case Intrinsic::x86_sse2_psrli_q:
- case Intrinsic::x86_sse2_psrli_w:
- case Intrinsic::x86_avx2_psrli_d:
- case Intrinsic::x86_avx2_psrli_q:
- case Intrinsic::x86_avx2_psrli_w:
- case Intrinsic::x86_avx512_psrli_d_512:
- case Intrinsic::x86_avx512_psrli_q_512:
- case Intrinsic::x86_avx512_psrli_w_512:
- case Intrinsic::x86_sse2_pslli_d:
- case Intrinsic::x86_sse2_pslli_q:
- case Intrinsic::x86_sse2_pslli_w:
- case Intrinsic::x86_avx2_pslli_d:
- case Intrinsic::x86_avx2_pslli_q:
- case Intrinsic::x86_avx2_pslli_w:
- case Intrinsic::x86_avx512_pslli_d_512:
- case Intrinsic::x86_avx512_pslli_q_512:
- case Intrinsic::x86_avx512_pslli_w_512:
- if (Value *V = simplifyX86immShift(II, IC.Builder)) {
- return IC.replaceInstUsesWith(II, V);
- }
- break;
-
- case Intrinsic::x86_sse2_psra_d:
- case Intrinsic::x86_sse2_psra_w:
- case Intrinsic::x86_avx2_psra_d:
- case Intrinsic::x86_avx2_psra_w:
- case Intrinsic::x86_avx512_psra_q_128:
- case Intrinsic::x86_avx512_psra_q_256:
- case Intrinsic::x86_avx512_psra_d_512:
- case Intrinsic::x86_avx512_psra_q_512:
- case Intrinsic::x86_avx512_psra_w_512:
- case Intrinsic::x86_sse2_psrl_d:
- case Intrinsic::x86_sse2_psrl_q:
- case Intrinsic::x86_sse2_psrl_w:
- case Intrinsic::x86_avx2_psrl_d:
- case Intrinsic::x86_avx2_psrl_q:
- case Intrinsic::x86_avx2_psrl_w:
- case Intrinsic::x86_avx512_psrl_d_512:
- case Intrinsic::x86_avx512_psrl_q_512:
- case Intrinsic::x86_avx512_psrl_w_512:
- case Intrinsic::x86_sse2_psll_d:
- case Intrinsic::x86_sse2_psll_q:
- case Intrinsic::x86_sse2_psll_w:
- case Intrinsic::x86_avx2_psll_d:
- case Intrinsic::x86_avx2_psll_q:
- case Intrinsic::x86_avx2_psll_w:
- case Intrinsic::x86_avx512_psll_d_512:
- case Intrinsic::x86_avx512_psll_q_512:
- case Intrinsic::x86_avx512_psll_w_512: {
- if (Value *V = simplifyX86immShift(II, IC.Builder)) {
- return IC.replaceInstUsesWith(II, V);
- }
-
- // SSE2/AVX2 uses only the first 64-bits of the 128-bit vector
- // operand to compute the shift amount.
- Value *Arg1 = II.getArgOperand(1);
- assert(Arg1->getType()->getPrimitiveSizeInBits() == 128 &&
- "Unexpected packed shift size");
- unsigned VWidth = cast<FixedVectorType>(Arg1->getType())->getNumElements();
-
- if (Value *V = SimplifyDemandedVectorEltsLow(Arg1, VWidth, VWidth / 2)) {
- return IC.replaceOperand(II, 1, V);
- }
- break;
- }
-
- case Intrinsic::x86_avx2_psllv_d:
- case Intrinsic::x86_avx2_psllv_d_256:
- case Intrinsic::x86_avx2_psllv_q:
- case Intrinsic::x86_avx2_psllv_q_256:
- case Intrinsic::x86_avx512_psllv_d_512:
- case Intrinsic::x86_avx512_psllv_q_512:
- case Intrinsic::x86_avx512_psllv_w_128:
- case Intrinsic::x86_avx512_psllv_w_256:
- case Intrinsic::x86_avx512_psllv_w_512:
- case Intrinsic::x86_avx2_psrav_d:
- case Intrinsic::x86_avx2_psrav_d_256:
- case Intrinsic::x86_avx512_psrav_q_128:
- case Intrinsic::x86_avx512_psrav_q_256:
- case Intrinsic::x86_avx512_psrav_d_512:
- case Intrinsic::x86_avx512_psrav_q_512:
- case Intrinsic::x86_avx512_psrav_w_128:
- case Intrinsic::x86_avx512_psrav_w_256:
- case Intrinsic::x86_avx512_psrav_w_512:
- case Intrinsic::x86_avx2_psrlv_d:
- case Intrinsic::x86_avx2_psrlv_d_256:
- case Intrinsic::x86_avx2_psrlv_q:
- case Intrinsic::x86_avx2_psrlv_q_256:
- case Intrinsic::x86_avx512_psrlv_d_512:
- case Intrinsic::x86_avx512_psrlv_q_512:
- case Intrinsic::x86_avx512_psrlv_w_128:
- case Intrinsic::x86_avx512_psrlv_w_256:
- case Intrinsic::x86_avx512_psrlv_w_512:
- if (Value *V = simplifyX86varShift(II, IC.Builder)) {
- return IC.replaceInstUsesWith(II, V);
- }
- break;
-
- case Intrinsic::x86_sse2_packssdw_128:
- case Intrinsic::x86_sse2_packsswb_128:
- case Intrinsic::x86_avx2_packssdw:
- case Intrinsic::x86_avx2_packsswb:
- case Intrinsic::x86_avx512_packssdw_512:
- case Intrinsic::x86_avx512_packsswb_512:
- if (Value *V = simplifyX86pack(II, IC.Builder, true)) {
- return IC.replaceInstUsesWith(II, V);
- }
- break;
-
- case Intrinsic::x86_sse2_packuswb_128:
- case Intrinsic::x86_sse41_packusdw:
- case Intrinsic::x86_avx2_packusdw:
- case Intrinsic::x86_avx2_packuswb:
- case Intrinsic::x86_avx512_packusdw_512:
- case Intrinsic::x86_avx512_packuswb_512:
- if (Value *V = simplifyX86pack(II, IC.Builder, false)) {
- return IC.replaceInstUsesWith(II, V);
- }
- break;
-
- case Intrinsic::x86_pclmulqdq:
- case Intrinsic::x86_pclmulqdq_256:
- case Intrinsic::x86_pclmulqdq_512: {
- if (auto *C = dyn_cast<ConstantInt>(II.getArgOperand(2))) {
- unsigned Imm = C->getZExtValue();
-
- bool MadeChange = false;
- Value *Arg0 = II.getArgOperand(0);
- Value *Arg1 = II.getArgOperand(1);
- unsigned VWidth =
- cast<FixedVectorType>(Arg0->getType())->getNumElements();
-
- APInt UndefElts1(VWidth, 0);
- APInt DemandedElts1 =
- APInt::getSplat(VWidth, APInt(2, (Imm & 0x01) ? 2 : 1));
- if (Value *V =
- IC.SimplifyDemandedVectorElts(Arg0, DemandedElts1, UndefElts1)) {
- IC.replaceOperand(II, 0, V);
- MadeChange = true;
- }
-
- APInt UndefElts2(VWidth, 0);
- APInt DemandedElts2 =
- APInt::getSplat(VWidth, APInt(2, (Imm & 0x10) ? 2 : 1));
- if (Value *V =
- IC.SimplifyDemandedVectorElts(Arg1, DemandedElts2, UndefElts2)) {
- IC.replaceOperand(II, 1, V);
- MadeChange = true;
- }
-
- // If either input elements are undef, the result is zero.
- if (DemandedElts1.isSubsetOf(UndefElts1) ||
- DemandedElts2.isSubsetOf(UndefElts2)) {
- return IC.replaceInstUsesWith(II,
- ConstantAggregateZero::get(II.getType()));
- }
-
- if (MadeChange) {
- return &II;
- }
- }
- break;
- }
-
- case Intrinsic::x86_sse41_insertps:
- if (Value *V = simplifyX86insertps(II, IC.Builder)) {
- return IC.replaceInstUsesWith(II, V);
- }
- break;
-
- case Intrinsic::x86_sse4a_extrq: {
- Value *Op0 = II.getArgOperand(0);
- Value *Op1 = II.getArgOperand(1);
- unsigned VWidth0 = cast<FixedVectorType>(Op0->getType())->getNumElements();
- unsigned VWidth1 = cast<FixedVectorType>(Op1->getType())->getNumElements();
- assert(Op0->getType()->getPrimitiveSizeInBits() == 128 &&
- Op1->getType()->getPrimitiveSizeInBits() == 128 && VWidth0 == 2 &&
- VWidth1 == 16 && "Unexpected operand sizes");
-
- // See if we're dealing with constant values.
- Constant *C1 = dyn_cast<Constant>(Op1);
- ConstantInt *CILength =
- C1 ? dyn_cast_or_null<ConstantInt>(C1->getAggregateElement((unsigned)0))
- : nullptr;
- ConstantInt *CIIndex =
- C1 ? dyn_cast_or_null<ConstantInt>(C1->getAggregateElement((unsigned)1))
- : nullptr;
-
- // Attempt to simplify to a constant, shuffle vector or EXTRQI call.
- if (Value *V = simplifyX86extrq(II, Op0, CILength, CIIndex, IC.Builder)) {
- return IC.replaceInstUsesWith(II, V);
- }
-
- // EXTRQ only uses the lowest 64-bits of the first 128-bit vector
- // operands and the lowest 16-bits of the second.
- bool MadeChange = false;
- if (Value *V = SimplifyDemandedVectorEltsLow(Op0, VWidth0, 1)) {
- IC.replaceOperand(II, 0, V);
- MadeChange = true;
- }
- if (Value *V = SimplifyDemandedVectorEltsLow(Op1, VWidth1, 2)) {
- IC.replaceOperand(II, 1, V);
- MadeChange = true;
- }
- if (MadeChange) {
- return &II;
- }
- break;
- }
-
- case Intrinsic::x86_sse4a_extrqi: {
- // EXTRQI: Extract Length bits starting from Index. Zero pad the remaining
- // bits of the lower 64-bits. The upper 64-bits are undefined.
- Value *Op0 = II.getArgOperand(0);
- unsigned VWidth = cast<FixedVectorType>(Op0->getType())->getNumElements();
- assert(Op0->getType()->getPrimitiveSizeInBits() == 128 && VWidth == 2 &&
- "Unexpected operand size");
-
- // See if we're dealing with constant values.
- ConstantInt *CILength = dyn_cast<ConstantInt>(II.getArgOperand(1));
- ConstantInt *CIIndex = dyn_cast<ConstantInt>(II.getArgOperand(2));
-
- // Attempt to simplify to a constant or shuffle vector.
- if (Value *V = simplifyX86extrq(II, Op0, CILength, CIIndex, IC.Builder)) {
- return IC.replaceInstUsesWith(II, V);
- }
-
- // EXTRQI only uses the lowest 64-bits of the first 128-bit vector
- // operand.
- if (Value *V = SimplifyDemandedVectorEltsLow(Op0, VWidth, 1)) {
- return IC.replaceOperand(II, 0, V);
- }
- break;
- }
-
- case Intrinsic::x86_sse4a_insertq: {
- Value *Op0 = II.getArgOperand(0);
- Value *Op1 = II.getArgOperand(1);
- unsigned VWidth = cast<FixedVectorType>(Op0->getType())->getNumElements();
- assert(Op0->getType()->getPrimitiveSizeInBits() == 128 &&
- Op1->getType()->getPrimitiveSizeInBits() == 128 && VWidth == 2 &&
- cast<FixedVectorType>(Op1->getType())->getNumElements() == 2 &&
- "Unexpected operand size");
-
- // See if we're dealing with constant values.
- Constant *C1 = dyn_cast<Constant>(Op1);
- ConstantInt *CI11 =
- C1 ? dyn_cast_or_null<ConstantInt>(C1->getAggregateElement((unsigned)1))
- : nullptr;
-
- // Attempt to simplify to a constant, shuffle vector or INSERTQI call.
- if (CI11) {
- const APInt &V11 = CI11->getValue();
- APInt Len = V11.zextOrTrunc(6);
- APInt Idx = V11.lshr(8).zextOrTrunc(6);
- if (Value *V = simplifyX86insertq(II, Op0, Op1, Len, Idx, IC.Builder)) {
- return IC.replaceInstUsesWith(II, V);
- }
- }
-
- // INSERTQ only uses the lowest 64-bits of the first 128-bit vector
- // operand.
- if (Value *V = SimplifyDemandedVectorEltsLow(Op0, VWidth, 1)) {
- return IC.replaceOperand(II, 0, V);
- }
- break;
- }
-
- case Intrinsic::x86_sse4a_insertqi: {
- // INSERTQI: Extract lowest Length bits from lower half of second source and
- // insert over first source starting at Index bit. The upper 64-bits are
- // undefined.
- Value *Op0 = II.getArgOperand(0);
- Value *Op1 = II.getArgOperand(1);
- unsigned VWidth0 = cast<FixedVectorType>(Op0->getType())->getNumElements();
- unsigned VWidth1 = cast<FixedVectorType>(Op1->getType())->getNumElements();
- assert(Op0->getType()->getPrimitiveSizeInBits() == 128 &&
- Op1->getType()->getPrimitiveSizeInBits() == 128 && VWidth0 == 2 &&
- VWidth1 == 2 && "Unexpected operand sizes");
-
- // See if we're dealing with constant values.
- ConstantInt *CILength = dyn_cast<ConstantInt>(II.getArgOperand(2));
- ConstantInt *CIIndex = dyn_cast<ConstantInt>(II.getArgOperand(3));
-
- // Attempt to simplify to a constant or shuffle vector.
- if (CILength && CIIndex) {
- APInt Len = CILength->getValue().zextOrTrunc(6);
- APInt Idx = CIIndex->getValue().zextOrTrunc(6);
- if (Value *V = simplifyX86insertq(II, Op0, Op1, Len, Idx, IC.Builder)) {
- return IC.replaceInstUsesWith(II, V);
- }
- }
-
- // INSERTQI only uses the lowest 64-bits of the first two 128-bit vector
- // operands.
- bool MadeChange = false;
- if (Value *V = SimplifyDemandedVectorEltsLow(Op0, VWidth0, 1)) {
- IC.replaceOperand(II, 0, V);
- MadeChange = true;
- }
- if (Value *V = SimplifyDemandedVectorEltsLow(Op1, VWidth1, 1)) {
- IC.replaceOperand(II, 1, V);
- MadeChange = true;
- }
- if (MadeChange) {
- return &II;
- }
- break;
- }
-
- case Intrinsic::x86_sse41_pblendvb:
- case Intrinsic::x86_sse41_blendvps:
- case Intrinsic::x86_sse41_blendvpd:
- case Intrinsic::x86_avx_blendv_ps_256:
- case Intrinsic::x86_avx_blendv_pd_256:
- case Intrinsic::x86_avx2_pblendvb: {
- // fold (blend A, A, Mask) -> A
- Value *Op0 = II.getArgOperand(0);
- Value *Op1 = II.getArgOperand(1);
- Value *Mask = II.getArgOperand(2);
- if (Op0 == Op1) {
- return IC.replaceInstUsesWith(II, Op0);
- }
-
- // Zero Mask - select 1st argument.
- if (isa<ConstantAggregateZero>(Mask)) {
- return IC.replaceInstUsesWith(II, Op0);
- }
-
- // Constant Mask - select 1st/2nd argument lane based on top bit of mask.
- if (auto *ConstantMask = dyn_cast<ConstantDataVector>(Mask)) {
- Constant *NewSelector = getNegativeIsTrueBoolVec(ConstantMask);
- return SelectInst::Create(NewSelector, Op1, Op0, "blendv");
- }
-
- // Convert to a vector select if we can bypass casts and find a boolean
- // vector condition value.
- Value *BoolVec;
- Mask = InstCombiner::peekThroughBitcast(Mask);
- if (match(Mask, PatternMatch::m_SExt(PatternMatch::m_Value(BoolVec))) &&
- BoolVec->getType()->isVectorTy() &&
- BoolVec->getType()->getScalarSizeInBits() == 1) {
- assert(Mask->getType()->getPrimitiveSizeInBits() ==
- II.getType()->getPrimitiveSizeInBits() &&
- "Not expecting mask and operands with different sizes");
-
- unsigned NumMaskElts =
- cast<FixedVectorType>(Mask->getType())->getNumElements();
- unsigned NumOperandElts =
- cast<FixedVectorType>(II.getType())->getNumElements();
- if (NumMaskElts == NumOperandElts) {
- return SelectInst::Create(BoolVec, Op1, Op0);
- }
-
- // If the mask has less elements than the operands, each mask bit maps to
- // multiple elements of the operands. Bitcast back and forth.
- if (NumMaskElts < NumOperandElts) {
- Value *CastOp0 = IC.Builder.CreateBitCast(Op0, Mask->getType());
- Value *CastOp1 = IC.Builder.CreateBitCast(Op1, Mask->getType());
- Value *Sel = IC.Builder.CreateSelect(BoolVec, CastOp1, CastOp0);
- return new BitCastInst(Sel, II.getType());
- }
- }
-
- break;
- }
-
- case Intrinsic::x86_ssse3_pshuf_b_128:
- case Intrinsic::x86_avx2_pshuf_b:
- case Intrinsic::x86_avx512_pshuf_b_512:
- if (Value *V = simplifyX86pshufb(II, IC.Builder)) {
- return IC.replaceInstUsesWith(II, V);
- }
- break;
-
- case Intrinsic::x86_avx_vpermilvar_ps:
- case Intrinsic::x86_avx_vpermilvar_ps_256:
- case Intrinsic::x86_avx512_vpermilvar_ps_512:
- case Intrinsic::x86_avx_vpermilvar_pd:
- case Intrinsic::x86_avx_vpermilvar_pd_256:
- case Intrinsic::x86_avx512_vpermilvar_pd_512:
- if (Value *V = simplifyX86vpermilvar(II, IC.Builder)) {
- return IC.replaceInstUsesWith(II, V);
- }
- break;
-
- case Intrinsic::x86_avx2_permd:
- case Intrinsic::x86_avx2_permps:
- case Intrinsic::x86_avx512_permvar_df_256:
- case Intrinsic::x86_avx512_permvar_df_512:
- case Intrinsic::x86_avx512_permvar_di_256:
- case Intrinsic::x86_avx512_permvar_di_512:
- case Intrinsic::x86_avx512_permvar_hi_128:
- case Intrinsic::x86_avx512_permvar_hi_256:
- case Intrinsic::x86_avx512_permvar_hi_512:
- case Intrinsic::x86_avx512_permvar_qi_128:
- case Intrinsic::x86_avx512_permvar_qi_256:
- case Intrinsic::x86_avx512_permvar_qi_512:
- case Intrinsic::x86_avx512_permvar_sf_512:
- case Intrinsic::x86_avx512_permvar_si_512:
- if (Value *V = simplifyX86vpermv(II, IC.Builder)) {
- return IC.replaceInstUsesWith(II, V);
- }
- break;
-
- case Intrinsic::x86_avx_maskload_ps:
- case Intrinsic::x86_avx_maskload_pd:
- case Intrinsic::x86_avx_maskload_ps_256:
- case Intrinsic::x86_avx_maskload_pd_256:
- case Intrinsic::x86_avx2_maskload_d:
- case Intrinsic::x86_avx2_maskload_q:
- case Intrinsic::x86_avx2_maskload_d_256:
- case Intrinsic::x86_avx2_maskload_q_256:
- if (Instruction *I = simplifyX86MaskedLoad(II, IC)) {
- return I;
- }
- break;
-
- case Intrinsic::x86_sse2_maskmov_dqu:
- case Intrinsic::x86_avx_maskstore_ps:
- case Intrinsic::x86_avx_maskstore_pd:
- case Intrinsic::x86_avx_maskstore_ps_256:
- case Intrinsic::x86_avx_maskstore_pd_256:
- case Intrinsic::x86_avx2_maskstore_d:
- case Intrinsic::x86_avx2_maskstore_q:
- case Intrinsic::x86_avx2_maskstore_d_256:
- case Intrinsic::x86_avx2_maskstore_q_256:
- if (simplifyX86MaskedStore(II, IC)) {
- return nullptr;
- }
- break;
-
- case Intrinsic::x86_addcarry_32:
- case Intrinsic::x86_addcarry_64:
- if (Value *V = simplifyX86addcarry(II, IC.Builder)) {
- return IC.replaceInstUsesWith(II, V);
- }
- break;
-
- default:
- break;
- }
- return None;
-}
-
-Optional<Value *> X86TTIImpl::simplifyDemandedUseBitsIntrinsic(
- InstCombiner &IC, IntrinsicInst &II, APInt DemandedMask, KnownBits &Known,
- bool &KnownBitsComputed) const {
- switch (II.getIntrinsicID()) {
- default:
- break;
- case Intrinsic::x86_mmx_pmovmskb:
- case Intrinsic::x86_sse_movmsk_ps:
- case Intrinsic::x86_sse2_movmsk_pd:
- case Intrinsic::x86_sse2_pmovmskb_128:
- case Intrinsic::x86_avx_movmsk_ps_256:
- case Intrinsic::x86_avx_movmsk_pd_256:
- case Intrinsic::x86_avx2_pmovmskb: {
- // MOVMSK copies the vector elements' sign bits to the low bits
- // and zeros the high bits.
- unsigned ArgWidth;
- if (II.getIntrinsicID() == Intrinsic::x86_mmx_pmovmskb) {
- ArgWidth = 8; // Arg is x86_mmx, but treated as <8 x i8>.
- } else {
- auto Arg = II.getArgOperand(0);
- auto ArgType = cast<FixedVectorType>(Arg->getType());
- ArgWidth = ArgType->getNumElements();
- }
-
- // If we don't need any of low bits then return zero,
- // we know that DemandedMask is non-zero already.
- APInt DemandedElts = DemandedMask.zextOrTrunc(ArgWidth);
- Type *VTy = II.getType();
- if (DemandedElts.isNullValue()) {
- return ConstantInt::getNullValue(VTy);
- }
-
- // We know that the upper bits are set to zero.
- Known.Zero.setBitsFrom(ArgWidth);
- KnownBitsComputed = true;
- break;
- }
- }
- return None;
-}
-
-Optional<Value *> X86TTIImpl::simplifyDemandedVectorEltsIntrinsic(
- InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
- APInt &UndefElts2, APInt &UndefElts3,
- std::function<void(Instruction *, unsigned, APInt, APInt &)>
- simplifyAndSetOp) const {
- unsigned VWidth = cast<FixedVectorType>(II.getType())->getNumElements();
- switch (II.getIntrinsicID()) {
- default:
- break;
- case Intrinsic::x86_xop_vfrcz_ss:
- case Intrinsic::x86_xop_vfrcz_sd:
- // The instructions for these intrinsics are speced to zero upper bits not
- // pass them through like other scalar intrinsics. So we shouldn't just
- // use Arg0 if DemandedElts[0] is clear like we do for other intrinsics.
- // Instead we should return a zero vector.
- if (!DemandedElts[0]) {
- IC.addToWorklist(&II);
- return ConstantAggregateZero::get(II.getType());
- }
-
- // Only the lower element is used.
- DemandedElts = 1;
- simplifyAndSetOp(&II, 0, DemandedElts, UndefElts);
-
- // Only the lower element is undefined. The high elements are zero.
- UndefElts = UndefElts[0];
- break;
-
- // Unary scalar-as-vector operations that work column-wise.
- case Intrinsic::x86_sse_rcp_ss:
- case Intrinsic::x86_sse_rsqrt_ss:
- simplifyAndSetOp(&II, 0, DemandedElts, UndefElts);
-
- // If lowest element of a scalar op isn't used then use Arg0.
- if (!DemandedElts[0]) {
- IC.addToWorklist(&II);
- return II.getArgOperand(0);
- }
- // TODO: If only low elt lower SQRT to FSQRT (with rounding/exceptions
- // checks).
- break;
-
- // Binary scalar-as-vector operations that work column-wise. The high
- // elements come from operand 0. The low element is a function of both
- // operands.
- case Intrinsic::x86_sse_min_ss:
- case Intrinsic::x86_sse_max_ss:
- case Intrinsic::x86_sse_cmp_ss:
- case Intrinsic::x86_sse2_min_sd:
- case Intrinsic::x86_sse2_max_sd:
- case Intrinsic::x86_sse2_cmp_sd: {
- simplifyAndSetOp(&II, 0, DemandedElts, UndefElts);
-
- // If lowest element of a scalar op isn't used then use Arg0.
- if (!DemandedElts[0]) {
- IC.addToWorklist(&II);
- return II.getArgOperand(0);
- }
-
- // Only lower element is used for operand 1.
- DemandedElts = 1;
- simplifyAndSetOp(&II, 1, DemandedElts, UndefElts2);
-
- // Lower element is undefined if both lower elements are undefined.
- // Consider things like undef&0. The result is known zero, not undef.
- if (!UndefElts2[0])
- UndefElts.clearBit(0);
-
- break;
- }
-
- // Binary scalar-as-vector operations that work column-wise. The high
- // elements come from operand 0 and the low element comes from operand 1.
- case Intrinsic::x86_sse41_round_ss:
- case Intrinsic::x86_sse41_round_sd: {
- // Don't use the low element of operand 0.
- APInt DemandedElts2 = DemandedElts;
- DemandedElts2.clearBit(0);
- simplifyAndSetOp(&II, 0, DemandedElts2, UndefElts);
-
- // If lowest element of a scalar op isn't used then use Arg0.
- if (!DemandedElts[0]) {
- IC.addToWorklist(&II);
- return II.getArgOperand(0);
- }
-
- // Only lower element is used for operand 1.
- DemandedElts = 1;
- simplifyAndSetOp(&II, 1, DemandedElts, UndefElts2);
-
- // Take the high undef elements from operand 0 and take the lower element
- // from operand 1.
- UndefElts.clearBit(0);
- UndefElts |= UndefElts2[0];
- break;
- }
-
- // Three input scalar-as-vector operations that work column-wise. The high
- // elements come from operand 0 and the low element is a function of all
- // three inputs.
- case Intrinsic::x86_avx512_mask_add_ss_round:
- case Intrinsic::x86_avx512_mask_div_ss_round:
- case Intrinsic::x86_avx512_mask_mul_ss_round:
- case Intrinsic::x86_avx512_mask_sub_ss_round:
- case Intrinsic::x86_avx512_mask_max_ss_round:
- case Intrinsic::x86_avx512_mask_min_ss_round:
- case Intrinsic::x86_avx512_mask_add_sd_round:
- case Intrinsic::x86_avx512_mask_div_sd_round:
- case Intrinsic::x86_avx512_mask_mul_sd_round:
- case Intrinsic::x86_avx512_mask_sub_sd_round:
- case Intrinsic::x86_avx512_mask_max_sd_round:
- case Intrinsic::x86_avx512_mask_min_sd_round:
- simplifyAndSetOp(&II, 0, DemandedElts, UndefElts);
-
- // If lowest element of a scalar op isn't used then use Arg0.
- if (!DemandedElts[0]) {
- IC.addToWorklist(&II);
- return II.getArgOperand(0);
- }
-
- // Only lower element is used for operand 1 and 2.
- DemandedElts = 1;
- simplifyAndSetOp(&II, 1, DemandedElts, UndefElts2);
- simplifyAndSetOp(&II, 2, DemandedElts, UndefElts3);
-
- // Lower element is undefined if all three lower elements are undefined.
- // Consider things like undef&0. The result is known zero, not undef.
- if (!UndefElts2[0] || !UndefElts3[0])
- UndefElts.clearBit(0);
- break;
-
- // TODO: Add fmaddsub support?
- case Intrinsic::x86_sse3_addsub_pd:
- case Intrinsic::x86_sse3_addsub_ps:
- case Intrinsic::x86_avx_addsub_pd_256:
- case Intrinsic::x86_avx_addsub_ps_256: {
- // If none of the even or none of the odd lanes are required, turn this
- // into a generic FP math instruction.
- APInt SubMask = APInt::getSplat(VWidth, APInt(2, 0x1));
- APInt AddMask = APInt::getSplat(VWidth, APInt(2, 0x2));
- bool IsSubOnly = DemandedElts.isSubsetOf(SubMask);
- bool IsAddOnly = DemandedElts.isSubsetOf(AddMask);
- if (IsSubOnly || IsAddOnly) {
- assert((IsSubOnly ^ IsAddOnly) && "Can't be both add-only and sub-only");
- IRBuilderBase::InsertPointGuard Guard(IC.Builder);
- IC.Builder.SetInsertPoint(&II);
- Value *Arg0 = II.getArgOperand(0), *Arg1 = II.getArgOperand(1);
- return IC.Builder.CreateBinOp(
- IsSubOnly ? Instruction::FSub : Instruction::FAdd, Arg0, Arg1);
- }
-
- simplifyAndSetOp(&II, 0, DemandedElts, UndefElts);
- simplifyAndSetOp(&II, 1, DemandedElts, UndefElts2);
- UndefElts &= UndefElts2;
- break;
- }
-
- case Intrinsic::x86_sse2_packssdw_128:
- case Intrinsic::x86_sse2_packsswb_128:
- case Intrinsic::x86_sse2_packuswb_128:
- case Intrinsic::x86_sse41_packusdw:
- case Intrinsic::x86_avx2_packssdw:
- case Intrinsic::x86_avx2_packsswb:
- case Intrinsic::x86_avx2_packusdw:
- case Intrinsic::x86_avx2_packuswb:
- case Intrinsic::x86_avx512_packssdw_512:
- case Intrinsic::x86_avx512_packsswb_512:
- case Intrinsic::x86_avx512_packusdw_512:
- case Intrinsic::x86_avx512_packuswb_512: {
- auto *Ty0 = II.getArgOperand(0)->getType();
- unsigned InnerVWidth = cast<FixedVectorType>(Ty0)->getNumElements();
- assert(VWidth == (InnerVWidth * 2) && "Unexpected input size");
-
- unsigned NumLanes = Ty0->getPrimitiveSizeInBits() / 128;
- unsigned VWidthPerLane = VWidth / NumLanes;
- unsigned InnerVWidthPerLane = InnerVWidth / NumLanes;
-
- // Per lane, pack the elements of the first input and then the second.
- // e.g.
- // v8i16 PACK(v4i32 X, v4i32 Y) - (X[0..3],Y[0..3])
- // v32i8 PACK(v16i16 X, v16i16 Y) - (X[0..7],Y[0..7]),(X[8..15],Y[8..15])
- for (int OpNum = 0; OpNum != 2; ++OpNum) {
- APInt OpDemandedElts(InnerVWidth, 0);
- for (unsigned Lane = 0; Lane != NumLanes; ++Lane) {
- unsigned LaneIdx = Lane * VWidthPerLane;
- for (unsigned Elt = 0; Elt != InnerVWidthPerLane; ++Elt) {
- unsigned Idx = LaneIdx + Elt + InnerVWidthPerLane * OpNum;
- if (DemandedElts[Idx])
- OpDemandedElts.setBit((Lane * InnerVWidthPerLane) + Elt);
- }
- }
-
- // Demand elements from the operand.
- APInt OpUndefElts(InnerVWidth, 0);
- simplifyAndSetOp(&II, OpNum, OpDemandedElts, OpUndefElts);
-
- // Pack the operand's UNDEF elements, one lane at a time.
- OpUndefElts = OpUndefElts.zext(VWidth);
- for (unsigned Lane = 0; Lane != NumLanes; ++Lane) {
- APInt LaneElts = OpUndefElts.lshr(InnerVWidthPerLane * Lane);
- LaneElts = LaneElts.getLoBits(InnerVWidthPerLane);
- LaneElts <<= InnerVWidthPerLane * (2 * Lane + OpNum);
- UndefElts |= LaneElts;
- }
- }
- break;
- }
-
- // PSHUFB
- case Intrinsic::x86_ssse3_pshuf_b_128:
- case Intrinsic::x86_avx2_pshuf_b:
- case Intrinsic::x86_avx512_pshuf_b_512:
- // PERMILVAR
- case Intrinsic::x86_avx_vpermilvar_ps:
- case Intrinsic::x86_avx_vpermilvar_ps_256:
- case Intrinsic::x86_avx512_vpermilvar_ps_512:
- case Intrinsic::x86_avx_vpermilvar_pd:
- case Intrinsic::x86_avx_vpermilvar_pd_256:
- case Intrinsic::x86_avx512_vpermilvar_pd_512:
- // PERMV
- case Intrinsic::x86_avx2_permd:
- case Intrinsic::x86_avx2_permps: {
- simplifyAndSetOp(&II, 1, DemandedElts, UndefElts);
- break;
- }
-
- // SSE4A instructions leave the upper 64-bits of the 128-bit result
- // in an undefined state.
- case Intrinsic::x86_sse4a_extrq:
- case Intrinsic::x86_sse4a_extrqi:
- case Intrinsic::x86_sse4a_insertq:
- case Intrinsic::x86_sse4a_insertqi:
- UndefElts.setHighBits(VWidth / 2);
- break;
- }
- return None;
-}
+//===-- X86InstCombineIntrinsic.cpp - X86 specific InstCombine pass -------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file implements a TargetTransformInfo analysis pass specific to the
+/// X86 target machine. It uses the target's detailed information to provide
+/// more precise answers to certain TTI queries, while letting the target
+/// independent and default TTI implementations handle the rest.
+///
+//===----------------------------------------------------------------------===//
+
+#include "X86TargetTransformInfo.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/IntrinsicsX86.h"
+#include "llvm/Support/KnownBits.h"
+#include "llvm/Transforms/InstCombine/InstCombiner.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "x86tti"
+
+/// Return a constant boolean vector that has true elements in all positions
+/// where the input constant data vector has an element with the sign bit set.
+static Constant *getNegativeIsTrueBoolVec(Constant *V) {
+ VectorType *IntTy = VectorType::getInteger(cast<VectorType>(V->getType()));
+ V = ConstantExpr::getBitCast(V, IntTy);
+ V = ConstantExpr::getICmp(CmpInst::ICMP_SGT, Constant::getNullValue(IntTy),
+ V);
+ return V;
+}
+
+/// Convert the x86 XMM integer vector mask to a vector of bools based on
+/// each element's most significant bit (the sign bit).
+static Value *getBoolVecFromMask(Value *Mask) {
+ // Fold Constant Mask.
+ if (auto *ConstantMask = dyn_cast<ConstantDataVector>(Mask))
+ return getNegativeIsTrueBoolVec(ConstantMask);
+
+ // Mask was extended from a boolean vector.
+ Value *ExtMask;
+ if (PatternMatch::match(
+ Mask, PatternMatch::m_SExt(PatternMatch::m_Value(ExtMask))) &&
+ ExtMask->getType()->isIntOrIntVectorTy(1))
+ return ExtMask;
+
+ return nullptr;
+}
+
+// TODO: If the x86 backend knew how to convert a bool vector mask back to an
+// XMM register mask efficiently, we could transform all x86 masked intrinsics
+// to LLVM masked intrinsics and remove the x86 masked intrinsic defs.
+static Instruction *simplifyX86MaskedLoad(IntrinsicInst &II, InstCombiner &IC) {
+ Value *Ptr = II.getOperand(0);
+ Value *Mask = II.getOperand(1);
+ Constant *ZeroVec = Constant::getNullValue(II.getType());
+
+ // Zero Mask - masked load instruction creates a zero vector.
+ if (isa<ConstantAggregateZero>(Mask))
+ return IC.replaceInstUsesWith(II, ZeroVec);
+
+ // The mask is constant or extended from a bool vector. Convert this x86
+ // intrinsic to the LLVM intrinsic to allow target-independent optimizations.
+ if (Value *BoolMask = getBoolVecFromMask(Mask)) {
+ // First, cast the x86 intrinsic scalar pointer to a vector pointer to match
+ // the LLVM intrinsic definition for the pointer argument.
+ unsigned AddrSpace = cast<PointerType>(Ptr->getType())->getAddressSpace();
+ PointerType *VecPtrTy = PointerType::get(II.getType(), AddrSpace);
+ Value *PtrCast = IC.Builder.CreateBitCast(Ptr, VecPtrTy, "castvec");
+
+ // The pass-through vector for an x86 masked load is a zero vector.
+ CallInst *NewMaskedLoad =
+ IC.Builder.CreateMaskedLoad(PtrCast, Align(1), BoolMask, ZeroVec);
+ return IC.replaceInstUsesWith(II, NewMaskedLoad);
+ }
+
+ return nullptr;
+}
+
+// TODO: If the x86 backend knew how to convert a bool vector mask back to an
+// XMM register mask efficiently, we could transform all x86 masked intrinsics
+// to LLVM masked intrinsics and remove the x86 masked intrinsic defs.
+static bool simplifyX86MaskedStore(IntrinsicInst &II, InstCombiner &IC) {
+ Value *Ptr = II.getOperand(0);
+ Value *Mask = II.getOperand(1);
+ Value *Vec = II.getOperand(2);
+
+ // Zero Mask - this masked store instruction does nothing.
+ if (isa<ConstantAggregateZero>(Mask)) {
+ IC.eraseInstFromFunction(II);
+ return true;
+ }
+
+ // The SSE2 version is too weird (eg, unaligned but non-temporal) to do
+ // anything else at this level.
+ if (II.getIntrinsicID() == Intrinsic::x86_sse2_maskmov_dqu)
+ return false;
+
+ // The mask is constant or extended from a bool vector. Convert this x86
+ // intrinsic to the LLVM intrinsic to allow target-independent optimizations.
+ if (Value *BoolMask = getBoolVecFromMask(Mask)) {
+ unsigned AddrSpace = cast<PointerType>(Ptr->getType())->getAddressSpace();
+ PointerType *VecPtrTy = PointerType::get(Vec->getType(), AddrSpace);
+ Value *PtrCast = IC.Builder.CreateBitCast(Ptr, VecPtrTy, "castvec");
+
+ IC.Builder.CreateMaskedStore(Vec, PtrCast, Align(1), BoolMask);
+
+ // 'Replace uses' doesn't work for stores. Erase the original masked store.
+ IC.eraseInstFromFunction(II);
+ return true;
+ }
+
+ return false;
+}
+
+static Value *simplifyX86immShift(const IntrinsicInst &II,
+ InstCombiner::BuilderTy &Builder) {
+ bool LogicalShift = false;
+ bool ShiftLeft = false;
+ bool IsImm = false;
+
+ switch (II.getIntrinsicID()) {
+ default:
+ llvm_unreachable("Unexpected intrinsic!");
+ case Intrinsic::x86_sse2_psrai_d:
+ case Intrinsic::x86_sse2_psrai_w:
+ case Intrinsic::x86_avx2_psrai_d:
+ case Intrinsic::x86_avx2_psrai_w:
+ case Intrinsic::x86_avx512_psrai_q_128:
+ case Intrinsic::x86_avx512_psrai_q_256:
+ case Intrinsic::x86_avx512_psrai_d_512:
+ case Intrinsic::x86_avx512_psrai_q_512:
+ case Intrinsic::x86_avx512_psrai_w_512:
+ IsImm = true;
+ LLVM_FALLTHROUGH;
+ case Intrinsic::x86_sse2_psra_d:
+ case Intrinsic::x86_sse2_psra_w:
+ case Intrinsic::x86_avx2_psra_d:
+ case Intrinsic::x86_avx2_psra_w:
+ case Intrinsic::x86_avx512_psra_q_128:
+ case Intrinsic::x86_avx512_psra_q_256:
+ case Intrinsic::x86_avx512_psra_d_512:
+ case Intrinsic::x86_avx512_psra_q_512:
+ case Intrinsic::x86_avx512_psra_w_512:
+ LogicalShift = false;
+ ShiftLeft = false;
+ break;
+ case Intrinsic::x86_sse2_psrli_d:
+ case Intrinsic::x86_sse2_psrli_q:
+ case Intrinsic::x86_sse2_psrli_w:
+ case Intrinsic::x86_avx2_psrli_d:
+ case Intrinsic::x86_avx2_psrli_q:
+ case Intrinsic::x86_avx2_psrli_w:
+ case Intrinsic::x86_avx512_psrli_d_512:
+ case Intrinsic::x86_avx512_psrli_q_512:
+ case Intrinsic::x86_avx512_psrli_w_512:
+ IsImm = true;
+ LLVM_FALLTHROUGH;
+ case Intrinsic::x86_sse2_psrl_d:
+ case Intrinsic::x86_sse2_psrl_q:
+ case Intrinsic::x86_sse2_psrl_w:
+ case Intrinsic::x86_avx2_psrl_d:
+ case Intrinsic::x86_avx2_psrl_q:
+ case Intrinsic::x86_avx2_psrl_w:
+ case Intrinsic::x86_avx512_psrl_d_512:
+ case Intrinsic::x86_avx512_psrl_q_512:
+ case Intrinsic::x86_avx512_psrl_w_512:
+ LogicalShift = true;
+ ShiftLeft = false;
+ break;
+ case Intrinsic::x86_sse2_pslli_d:
+ case Intrinsic::x86_sse2_pslli_q:
+ case Intrinsic::x86_sse2_pslli_w:
+ case Intrinsic::x86_avx2_pslli_d:
+ case Intrinsic::x86_avx2_pslli_q:
+ case Intrinsic::x86_avx2_pslli_w:
+ case Intrinsic::x86_avx512_pslli_d_512:
+ case Intrinsic::x86_avx512_pslli_q_512:
+ case Intrinsic::x86_avx512_pslli_w_512:
+ IsImm = true;
+ LLVM_FALLTHROUGH;
+ case Intrinsic::x86_sse2_psll_d:
+ case Intrinsic::x86_sse2_psll_q:
+ case Intrinsic::x86_sse2_psll_w:
+ case Intrinsic::x86_avx2_psll_d:
+ case Intrinsic::x86_avx2_psll_q:
+ case Intrinsic::x86_avx2_psll_w:
+ case Intrinsic::x86_avx512_psll_d_512:
+ case Intrinsic::x86_avx512_psll_q_512:
+ case Intrinsic::x86_avx512_psll_w_512:
+ LogicalShift = true;
+ ShiftLeft = true;
+ break;
+ }
+ assert((LogicalShift || !ShiftLeft) && "Only logical shifts can shift left");
+
+ auto Vec = II.getArgOperand(0);
+ auto Amt = II.getArgOperand(1);
+ auto VT = cast<FixedVectorType>(Vec->getType());
+ auto SVT = VT->getElementType();
+ auto AmtVT = Amt->getType();
+ unsigned VWidth = VT->getNumElements();
+ unsigned BitWidth = SVT->getPrimitiveSizeInBits();
+
+ // If the shift amount is guaranteed to be in-range we can replace it with a
+ // generic shift. If its guaranteed to be out of range, logical shifts combine
+ // to zero and arithmetic shifts are clamped to (BitWidth - 1).
+ if (IsImm) {
+ assert(AmtVT->isIntegerTy(32) && "Unexpected shift-by-immediate type");
+ KnownBits KnownAmtBits =
+ llvm::computeKnownBits(Amt, II.getModule()->getDataLayout());
+ if (KnownAmtBits.getMaxValue().ult(BitWidth)) {
+ Amt = Builder.CreateZExtOrTrunc(Amt, SVT);
+ Amt = Builder.CreateVectorSplat(VWidth, Amt);
+ return (LogicalShift ? (ShiftLeft ? Builder.CreateShl(Vec, Amt)
+ : Builder.CreateLShr(Vec, Amt))
+ : Builder.CreateAShr(Vec, Amt));
+ }
+ if (KnownAmtBits.getMinValue().uge(BitWidth)) {
+ if (LogicalShift)
+ return ConstantAggregateZero::get(VT);
+ Amt = ConstantInt::get(SVT, BitWidth - 1);
+ return Builder.CreateAShr(Vec, Builder.CreateVectorSplat(VWidth, Amt));
+ }
+ } else {
+ // Ensure the first element has an in-range value and the rest of the
+ // elements in the bottom 64 bits are zero.
+ assert(AmtVT->isVectorTy() && AmtVT->getPrimitiveSizeInBits() == 128 &&
+ cast<VectorType>(AmtVT)->getElementType() == SVT &&
+ "Unexpected shift-by-scalar type");
+ unsigned NumAmtElts = cast<FixedVectorType>(AmtVT)->getNumElements();
+ APInt DemandedLower = APInt::getOneBitSet(NumAmtElts, 0);
+ APInt DemandedUpper = APInt::getBitsSet(NumAmtElts, 1, NumAmtElts / 2);
+ KnownBits KnownLowerBits = llvm::computeKnownBits(
+ Amt, DemandedLower, II.getModule()->getDataLayout());
+ KnownBits KnownUpperBits = llvm::computeKnownBits(
+ Amt, DemandedUpper, II.getModule()->getDataLayout());
+ if (KnownLowerBits.getMaxValue().ult(BitWidth) &&
+ (DemandedUpper.isNullValue() || KnownUpperBits.isZero())) {
+ SmallVector<int, 16> ZeroSplat(VWidth, 0);
+ Amt = Builder.CreateShuffleVector(Amt, ZeroSplat);
+ return (LogicalShift ? (ShiftLeft ? Builder.CreateShl(Vec, Amt)
+ : Builder.CreateLShr(Vec, Amt))
+ : Builder.CreateAShr(Vec, Amt));
+ }
+ }
+
+ // Simplify if count is constant vector.
+ auto CDV = dyn_cast<ConstantDataVector>(Amt);
+ if (!CDV)
+ return nullptr;
+
+ // SSE2/AVX2 uses all the first 64-bits of the 128-bit vector
+ // operand to compute the shift amount.
+ assert(AmtVT->isVectorTy() && AmtVT->getPrimitiveSizeInBits() == 128 &&
+ cast<VectorType>(AmtVT)->getElementType() == SVT &&
+ "Unexpected shift-by-scalar type");
+
+ // Concatenate the sub-elements to create the 64-bit value.
+ APInt Count(64, 0);
+ for (unsigned i = 0, NumSubElts = 64 / BitWidth; i != NumSubElts; ++i) {
+ unsigned SubEltIdx = (NumSubElts - 1) - i;
+ auto SubElt = cast<ConstantInt>(CDV->getElementAsConstant(SubEltIdx));
+ Count <<= BitWidth;
+ Count |= SubElt->getValue().zextOrTrunc(64);
+ }
+
+ // If shift-by-zero then just return the original value.
+ if (Count.isNullValue())
+ return Vec;
+
+ // Handle cases when Shift >= BitWidth.
+ if (Count.uge(BitWidth)) {
+ // If LogicalShift - just return zero.
+ if (LogicalShift)
+ return ConstantAggregateZero::get(VT);
+
+ // If ArithmeticShift - clamp Shift to (BitWidth - 1).
+ Count = APInt(64, BitWidth - 1);
+ }
+
+ // Get a constant vector of the same type as the first operand.
+ auto ShiftAmt = ConstantInt::get(SVT, Count.zextOrTrunc(BitWidth));
+ auto ShiftVec = Builder.CreateVectorSplat(VWidth, ShiftAmt);
+
+ if (ShiftLeft)
+ return Builder.CreateShl(Vec, ShiftVec);
+
+ if (LogicalShift)
+ return Builder.CreateLShr(Vec, ShiftVec);
+
+ return Builder.CreateAShr(Vec, ShiftVec);
+}
+
+// Attempt to simplify AVX2 per-element shift intrinsics to a generic IR shift.
+// Unlike the generic IR shifts, the intrinsics have defined behaviour for out
+// of range shift amounts (logical - set to zero, arithmetic - splat sign bit).
+static Value *simplifyX86varShift(const IntrinsicInst &II,
+ InstCombiner::BuilderTy &Builder) {
+ bool LogicalShift = false;
+ bool ShiftLeft = false;
+
+ switch (II.getIntrinsicID()) {
+ default:
+ llvm_unreachable("Unexpected intrinsic!");
+ case Intrinsic::x86_avx2_psrav_d:
+ case Intrinsic::x86_avx2_psrav_d_256:
+ case Intrinsic::x86_avx512_psrav_q_128:
+ case Intrinsic::x86_avx512_psrav_q_256:
+ case Intrinsic::x86_avx512_psrav_d_512:
+ case Intrinsic::x86_avx512_psrav_q_512:
+ case Intrinsic::x86_avx512_psrav_w_128:
+ case Intrinsic::x86_avx512_psrav_w_256:
+ case Intrinsic::x86_avx512_psrav_w_512:
+ LogicalShift = false;
+ ShiftLeft = false;
+ break;
+ case Intrinsic::x86_avx2_psrlv_d:
+ case Intrinsic::x86_avx2_psrlv_d_256:
+ case Intrinsic::x86_avx2_psrlv_q:
+ case Intrinsic::x86_avx2_psrlv_q_256:
+ case Intrinsic::x86_avx512_psrlv_d_512:
+ case Intrinsic::x86_avx512_psrlv_q_512:
+ case Intrinsic::x86_avx512_psrlv_w_128:
+ case Intrinsic::x86_avx512_psrlv_w_256:
+ case Intrinsic::x86_avx512_psrlv_w_512:
+ LogicalShift = true;
+ ShiftLeft = false;
+ break;
+ case Intrinsic::x86_avx2_psllv_d:
+ case Intrinsic::x86_avx2_psllv_d_256:
+ case Intrinsic::x86_avx2_psllv_q:
+ case Intrinsic::x86_avx2_psllv_q_256:
+ case Intrinsic::x86_avx512_psllv_d_512:
+ case Intrinsic::x86_avx512_psllv_q_512:
+ case Intrinsic::x86_avx512_psllv_w_128:
+ case Intrinsic::x86_avx512_psllv_w_256:
+ case Intrinsic::x86_avx512_psllv_w_512:
+ LogicalShift = true;
+ ShiftLeft = true;
+ break;
+ }
+ assert((LogicalShift || !ShiftLeft) && "Only logical shifts can shift left");
+
+ auto Vec = II.getArgOperand(0);
+ auto Amt = II.getArgOperand(1);
+ auto VT = cast<FixedVectorType>(II.getType());
+ auto SVT = VT->getElementType();
+ int NumElts = VT->getNumElements();
+ int BitWidth = SVT->getIntegerBitWidth();
+
+ // If the shift amount is guaranteed to be in-range we can replace it with a
+ // generic shift.
+ APInt UpperBits =
+ APInt::getHighBitsSet(BitWidth, BitWidth - Log2_32(BitWidth));
+ if (llvm::MaskedValueIsZero(Amt, UpperBits,
+ II.getModule()->getDataLayout())) {
+ return (LogicalShift ? (ShiftLeft ? Builder.CreateShl(Vec, Amt)
+ : Builder.CreateLShr(Vec, Amt))
+ : Builder.CreateAShr(Vec, Amt));
+ }
+
+ // Simplify if all shift amounts are constant/undef.
+ auto *CShift = dyn_cast<Constant>(Amt);
+ if (!CShift)
+ return nullptr;
+
+ // Collect each element's shift amount.
+ // We also collect special cases: UNDEF = -1, OUT-OF-RANGE = BitWidth.
+ bool AnyOutOfRange = false;
+ SmallVector<int, 8> ShiftAmts;
+ for (int I = 0; I < NumElts; ++I) {
+ auto *CElt = CShift->getAggregateElement(I);
+ if (isa_and_nonnull<UndefValue>(CElt)) {
+ ShiftAmts.push_back(-1);
+ continue;
+ }
+
+ auto *COp = dyn_cast_or_null<ConstantInt>(CElt);
+ if (!COp)
+ return nullptr;
+
+ // Handle out of range shifts.
+ // If LogicalShift - set to BitWidth (special case).
+ // If ArithmeticShift - set to (BitWidth - 1) (sign splat).
+ APInt ShiftVal = COp->getValue();
+ if (ShiftVal.uge(BitWidth)) {
+ AnyOutOfRange = LogicalShift;
+ ShiftAmts.push_back(LogicalShift ? BitWidth : BitWidth - 1);
+ continue;
+ }
+
+ ShiftAmts.push_back((int)ShiftVal.getZExtValue());
+ }
+
+ // If all elements out of range or UNDEF, return vector of zeros/undefs.
+ // ArithmeticShift should only hit this if they are all UNDEF.
+ auto OutOfRange = [&](int Idx) { return (Idx < 0) || (BitWidth <= Idx); };
+ if (llvm::all_of(ShiftAmts, OutOfRange)) {
+ SmallVector<Constant *, 8> ConstantVec;
+ for (int Idx : ShiftAmts) {
+ if (Idx < 0) {
+ ConstantVec.push_back(UndefValue::get(SVT));
+ } else {
+ assert(LogicalShift && "Logical shift expected");
+ ConstantVec.push_back(ConstantInt::getNullValue(SVT));
+ }
+ }
+ return ConstantVector::get(ConstantVec);
+ }
+
+ // We can't handle only some out of range values with generic logical shifts.
+ if (AnyOutOfRange)
+ return nullptr;
+
+ // Build the shift amount constant vector.
+ SmallVector<Constant *, 8> ShiftVecAmts;
+ for (int Idx : ShiftAmts) {
+ if (Idx < 0)
+ ShiftVecAmts.push_back(UndefValue::get(SVT));
+ else
+ ShiftVecAmts.push_back(ConstantInt::get(SVT, Idx));
+ }
+ auto ShiftVec = ConstantVector::get(ShiftVecAmts);
+
+ if (ShiftLeft)
+ return Builder.CreateShl(Vec, ShiftVec);
+
+ if (LogicalShift)
+ return Builder.CreateLShr(Vec, ShiftVec);
+
+ return Builder.CreateAShr(Vec, ShiftVec);
+}
+
+static Value *simplifyX86pack(IntrinsicInst &II,
+ InstCombiner::BuilderTy &Builder, bool IsSigned) {
+ Value *Arg0 = II.getArgOperand(0);
+ Value *Arg1 = II.getArgOperand(1);
+ Type *ResTy = II.getType();
+
+ // Fast all undef handling.
+ if (isa<UndefValue>(Arg0) && isa<UndefValue>(Arg1))
+ return UndefValue::get(ResTy);
+
+ auto *ArgTy = cast<FixedVectorType>(Arg0->getType());
+ unsigned NumLanes = ResTy->getPrimitiveSizeInBits() / 128;
+ unsigned NumSrcElts = ArgTy->getNumElements();
+ assert(cast<FixedVectorType>(ResTy)->getNumElements() == (2 * NumSrcElts) &&
+ "Unexpected packing types");
+
+ unsigned NumSrcEltsPerLane = NumSrcElts / NumLanes;
+ unsigned DstScalarSizeInBits = ResTy->getScalarSizeInBits();
+ unsigned SrcScalarSizeInBits = ArgTy->getScalarSizeInBits();
+ assert(SrcScalarSizeInBits == (2 * DstScalarSizeInBits) &&
+ "Unexpected packing types");
+
+ // Constant folding.
+ if (!isa<Constant>(Arg0) || !isa<Constant>(Arg1))
+ return nullptr;
+
+ // Clamp Values - signed/unsigned both use signed clamp values, but they
+ // differ on the min/max values.
+ APInt MinValue, MaxValue;
+ if (IsSigned) {
+ // PACKSS: Truncate signed value with signed saturation.
+ // Source values less than dst minint are saturated to minint.
+ // Source values greater than dst maxint are saturated to maxint.
+ MinValue =
+ APInt::getSignedMinValue(DstScalarSizeInBits).sext(SrcScalarSizeInBits);
+ MaxValue =
+ APInt::getSignedMaxValue(DstScalarSizeInBits).sext(SrcScalarSizeInBits);
+ } else {
+ // PACKUS: Truncate signed value with unsigned saturation.
+ // Source values less than zero are saturated to zero.
+ // Source values greater than dst maxuint are saturated to maxuint.
+ MinValue = APInt::getNullValue(SrcScalarSizeInBits);
+ MaxValue = APInt::getLowBitsSet(SrcScalarSizeInBits, DstScalarSizeInBits);
+ }
+
+ auto *MinC = Constant::getIntegerValue(ArgTy, MinValue);
+ auto *MaxC = Constant::getIntegerValue(ArgTy, MaxValue);
+ Arg0 = Builder.CreateSelect(Builder.CreateICmpSLT(Arg0, MinC), MinC, Arg0);
+ Arg1 = Builder.CreateSelect(Builder.CreateICmpSLT(Arg1, MinC), MinC, Arg1);
+ Arg0 = Builder.CreateSelect(Builder.CreateICmpSGT(Arg0, MaxC), MaxC, Arg0);
+ Arg1 = Builder.CreateSelect(Builder.CreateICmpSGT(Arg1, MaxC), MaxC, Arg1);
+
+ // Shuffle clamped args together at the lane level.
+ SmallVector<int, 32> PackMask;
+ for (unsigned Lane = 0; Lane != NumLanes; ++Lane) {
+ for (unsigned Elt = 0; Elt != NumSrcEltsPerLane; ++Elt)
+ PackMask.push_back(Elt + (Lane * NumSrcEltsPerLane));
+ for (unsigned Elt = 0; Elt != NumSrcEltsPerLane; ++Elt)
+ PackMask.push_back(Elt + (Lane * NumSrcEltsPerLane) + NumSrcElts);
+ }
+ auto *Shuffle = Builder.CreateShuffleVector(Arg0, Arg1, PackMask);
+
+ // Truncate to dst size.
+ return Builder.CreateTrunc(Shuffle, ResTy);
+}
+
+static Value *simplifyX86movmsk(const IntrinsicInst &II,
+ InstCombiner::BuilderTy &Builder) {
+ Value *Arg = II.getArgOperand(0);
+ Type *ResTy = II.getType();
+
+ // movmsk(undef) -> zero as we must ensure the upper bits are zero.
+ if (isa<UndefValue>(Arg))
+ return Constant::getNullValue(ResTy);
+
+ auto *ArgTy = dyn_cast<FixedVectorType>(Arg->getType());
+ // We can't easily peek through x86_mmx types.
+ if (!ArgTy)
+ return nullptr;
+
+ // Expand MOVMSK to compare/bitcast/zext:
+ // e.g. PMOVMSKB(v16i8 x):
+ // %cmp = icmp slt <16 x i8> %x, zeroinitializer
+ // %int = bitcast <16 x i1> %cmp to i16
+ // %res = zext i16 %int to i32
+ unsigned NumElts = ArgTy->getNumElements();
+ Type *IntegerVecTy = VectorType::getInteger(ArgTy);
+ Type *IntegerTy = Builder.getIntNTy(NumElts);
+
+ Value *Res = Builder.CreateBitCast(Arg, IntegerVecTy);
+ Res = Builder.CreateICmpSLT(Res, Constant::getNullValue(IntegerVecTy));
+ Res = Builder.CreateBitCast(Res, IntegerTy);
+ Res = Builder.CreateZExtOrTrunc(Res, ResTy);
+ return Res;
+}
+
+static Value *simplifyX86addcarry(const IntrinsicInst &II,
+ InstCombiner::BuilderTy &Builder) {
+ Value *CarryIn = II.getArgOperand(0);
+ Value *Op1 = II.getArgOperand(1);
+ Value *Op2 = II.getArgOperand(2);
+ Type *RetTy = II.getType();
+ Type *OpTy = Op1->getType();
+ assert(RetTy->getStructElementType(0)->isIntegerTy(8) &&
+ RetTy->getStructElementType(1) == OpTy && OpTy == Op2->getType() &&
+ "Unexpected types for x86 addcarry");
+
+ // If carry-in is zero, this is just an unsigned add with overflow.
+ if (match(CarryIn, PatternMatch::m_ZeroInt())) {
+ Value *UAdd = Builder.CreateIntrinsic(Intrinsic::uadd_with_overflow, OpTy,
+ {Op1, Op2});
+ // The types have to be adjusted to match the x86 call types.
+ Value *UAddResult = Builder.CreateExtractValue(UAdd, 0);
+ Value *UAddOV = Builder.CreateZExt(Builder.CreateExtractValue(UAdd, 1),
+ Builder.getInt8Ty());
+ Value *Res = UndefValue::get(RetTy);
+ Res = Builder.CreateInsertValue(Res, UAddOV, 0);
+ return Builder.CreateInsertValue(Res, UAddResult, 1);
+ }
+
+ return nullptr;
+}
+
+static Value *simplifyX86insertps(const IntrinsicInst &II,
+ InstCombiner::BuilderTy &Builder) {
+ auto *CInt = dyn_cast<ConstantInt>(II.getArgOperand(2));
+ if (!CInt)
+ return nullptr;
+
+ auto *VecTy = cast<FixedVectorType>(II.getType());
+ assert(VecTy->getNumElements() == 4 && "insertps with wrong vector type");
+
+ // The immediate permute control byte looks like this:
+ // [3:0] - zero mask for each 32-bit lane
+ // [5:4] - select one 32-bit destination lane
+ // [7:6] - select one 32-bit source lane
+
+ uint8_t Imm = CInt->getZExtValue();
+ uint8_t ZMask = Imm & 0xf;
+ uint8_t DestLane = (Imm >> 4) & 0x3;
+ uint8_t SourceLane = (Imm >> 6) & 0x3;
+
+ ConstantAggregateZero *ZeroVector = ConstantAggregateZero::get(VecTy);
+
+ // If all zero mask bits are set, this was just a weird way to
+ // generate a zero vector.
+ if (ZMask == 0xf)
+ return ZeroVector;
+
+ // Initialize by passing all of the first source bits through.
+ int ShuffleMask[4] = {0, 1, 2, 3};
+
+ // We may replace the second operand with the zero vector.
+ Value *V1 = II.getArgOperand(1);
+
+ if (ZMask) {
+ // If the zero mask is being used with a single input or the zero mask
+ // overrides the destination lane, this is a shuffle with the zero vector.
+ if ((II.getArgOperand(0) == II.getArgOperand(1)) ||
+ (ZMask & (1 << DestLane))) {
+ V1 = ZeroVector;
+ // We may still move 32-bits of the first source vector from one lane
+ // to another.
+ ShuffleMask[DestLane] = SourceLane;
+ // The zero mask may override the previous insert operation.
+ for (unsigned i = 0; i < 4; ++i)
+ if ((ZMask >> i) & 0x1)
+ ShuffleMask[i] = i + 4;
+ } else {
+ // TODO: Model this case as 2 shuffles or a 'logical and' plus shuffle?
+ return nullptr;
+ }
+ } else {
+ // Replace the selected destination lane with the selected source lane.
+ ShuffleMask[DestLane] = SourceLane + 4;
+ }
+
+ return Builder.CreateShuffleVector(II.getArgOperand(0), V1, ShuffleMask);
+}
+
+/// Attempt to simplify SSE4A EXTRQ/EXTRQI instructions using constant folding
+/// or conversion to a shuffle vector.
+static Value *simplifyX86extrq(IntrinsicInst &II, Value *Op0,
+ ConstantInt *CILength, ConstantInt *CIIndex,
+ InstCombiner::BuilderTy &Builder) {
+ auto LowConstantHighUndef = [&](uint64_t Val) {
+ Type *IntTy64 = Type::getInt64Ty(II.getContext());
+ Constant *Args[] = {ConstantInt::get(IntTy64, Val),
+ UndefValue::get(IntTy64)};
+ return ConstantVector::get(Args);
+ };
+
+ // See if we're dealing with constant values.
+ Constant *C0 = dyn_cast<Constant>(Op0);
+ ConstantInt *CI0 =
+ C0 ? dyn_cast_or_null<ConstantInt>(C0->getAggregateElement((unsigned)0))
+ : nullptr;
+
+ // Attempt to constant fold.
+ if (CILength && CIIndex) {
+ // From AMD documentation: "The bit index and field length are each six
+ // bits in length other bits of the field are ignored."
+ APInt APIndex = CIIndex->getValue().zextOrTrunc(6);
+ APInt APLength = CILength->getValue().zextOrTrunc(6);
+
+ unsigned Index = APIndex.getZExtValue();
+
+ // From AMD documentation: "a value of zero in the field length is
+ // defined as length of 64".
+ unsigned Length = APLength == 0 ? 64 : APLength.getZExtValue();
+
+ // From AMD documentation: "If the sum of the bit index + length field
+ // is greater than 64, the results are undefined".
+ unsigned End = Index + Length;
+
+ // Note that both field index and field length are 8-bit quantities.
+ // Since variables 'Index' and 'Length' are unsigned values
+ // obtained from zero-extending field index and field length
+ // respectively, their sum should never wrap around.
+ if (End > 64)
+ return UndefValue::get(II.getType());
+
+ // If we are inserting whole bytes, we can convert this to a shuffle.
+ // Lowering can recognize EXTRQI shuffle masks.
+ if ((Length % 8) == 0 && (Index % 8) == 0) {
+ // Convert bit indices to byte indices.
+ Length /= 8;
+ Index /= 8;
+
+ Type *IntTy8 = Type::getInt8Ty(II.getContext());
+ auto *ShufTy = FixedVectorType::get(IntTy8, 16);
+
+ SmallVector<int, 16> ShuffleMask;
+ for (int i = 0; i != (int)Length; ++i)
+ ShuffleMask.push_back(i + Index);
+ for (int i = Length; i != 8; ++i)
+ ShuffleMask.push_back(i + 16);
+ for (int i = 8; i != 16; ++i)
+ ShuffleMask.push_back(-1);
+
+ Value *SV = Builder.CreateShuffleVector(
+ Builder.CreateBitCast(Op0, ShufTy),
+ ConstantAggregateZero::get(ShufTy), ShuffleMask);
+ return Builder.CreateBitCast(SV, II.getType());
+ }
+
+ // Constant Fold - shift Index'th bit to lowest position and mask off
+ // Length bits.
+ if (CI0) {
+ APInt Elt = CI0->getValue();
+ Elt.lshrInPlace(Index);
+ Elt = Elt.zextOrTrunc(Length);
+ return LowConstantHighUndef(Elt.getZExtValue());
+ }
+
+ // If we were an EXTRQ call, we'll save registers if we convert to EXTRQI.
+ if (II.getIntrinsicID() == Intrinsic::x86_sse4a_extrq) {
+ Value *Args[] = {Op0, CILength, CIIndex};
+ Module *M = II.getModule();
+ Function *F = Intrinsic::getDeclaration(M, Intrinsic::x86_sse4a_extrqi);
+ return Builder.CreateCall(F, Args);
+ }
+ }
+
+ // Constant Fold - extraction from zero is always {zero, undef}.
+ if (CI0 && CI0->isZero())
+ return LowConstantHighUndef(0);
+
+ return nullptr;
+}
+
+/// Attempt to simplify SSE4A INSERTQ/INSERTQI instructions using constant
+/// folding or conversion to a shuffle vector.
+static Value *simplifyX86insertq(IntrinsicInst &II, Value *Op0, Value *Op1,
+ APInt APLength, APInt APIndex,
+ InstCombiner::BuilderTy &Builder) {
+ // From AMD documentation: "The bit index and field length are each six bits
+ // in length other bits of the field are ignored."
+ APIndex = APIndex.zextOrTrunc(6);
+ APLength = APLength.zextOrTrunc(6);
+
+ // Attempt to constant fold.
+ unsigned Index = APIndex.getZExtValue();
+
+ // From AMD documentation: "a value of zero in the field length is
+ // defined as length of 64".
+ unsigned Length = APLength == 0 ? 64 : APLength.getZExtValue();
+
+ // From AMD documentation: "If the sum of the bit index + length field
+ // is greater than 64, the results are undefined".
+ unsigned End = Index + Length;
+
+ // Note that both field index and field length are 8-bit quantities.
+ // Since variables 'Index' and 'Length' are unsigned values
+ // obtained from zero-extending field index and field length
+ // respectively, their sum should never wrap around.
+ if (End > 64)
+ return UndefValue::get(II.getType());
+
+ // If we are inserting whole bytes, we can convert this to a shuffle.
+ // Lowering can recognize INSERTQI shuffle masks.
+ if ((Length % 8) == 0 && (Index % 8) == 0) {
+ // Convert bit indices to byte indices.
+ Length /= 8;
+ Index /= 8;
+
+ Type *IntTy8 = Type::getInt8Ty(II.getContext());
+ auto *ShufTy = FixedVectorType::get(IntTy8, 16);
+
+ SmallVector<int, 16> ShuffleMask;
+ for (int i = 0; i != (int)Index; ++i)
+ ShuffleMask.push_back(i);
+ for (int i = 0; i != (int)Length; ++i)
+ ShuffleMask.push_back(i + 16);
+ for (int i = Index + Length; i != 8; ++i)
+ ShuffleMask.push_back(i);
+ for (int i = 8; i != 16; ++i)
+ ShuffleMask.push_back(-1);
+
+ Value *SV = Builder.CreateShuffleVector(Builder.CreateBitCast(Op0, ShufTy),
+ Builder.CreateBitCast(Op1, ShufTy),
+ ShuffleMask);
+ return Builder.CreateBitCast(SV, II.getType());
+ }
+
+ // See if we're dealing with constant values.
+ Constant *C0 = dyn_cast<Constant>(Op0);
+ Constant *C1 = dyn_cast<Constant>(Op1);
+ ConstantInt *CI00 =
+ C0 ? dyn_cast_or_null<ConstantInt>(C0->getAggregateElement((unsigned)0))
+ : nullptr;
+ ConstantInt *CI10 =
+ C1 ? dyn_cast_or_null<ConstantInt>(C1->getAggregateElement((unsigned)0))
+ : nullptr;
+
+ // Constant Fold - insert bottom Length bits starting at the Index'th bit.
+ if (CI00 && CI10) {
+ APInt V00 = CI00->getValue();
+ APInt V10 = CI10->getValue();
+ APInt Mask = APInt::getLowBitsSet(64, Length).shl(Index);
+ V00 = V00 & ~Mask;
+ V10 = V10.zextOrTrunc(Length).zextOrTrunc(64).shl(Index);
+ APInt Val = V00 | V10;
+ Type *IntTy64 = Type::getInt64Ty(II.getContext());
+ Constant *Args[] = {ConstantInt::get(IntTy64, Val.getZExtValue()),
+ UndefValue::get(IntTy64)};
+ return ConstantVector::get(Args);
+ }
+
+ // If we were an INSERTQ call, we'll save demanded elements if we convert to
+ // INSERTQI.
+ if (II.getIntrinsicID() == Intrinsic::x86_sse4a_insertq) {
+ Type *IntTy8 = Type::getInt8Ty(II.getContext());
+ Constant *CILength = ConstantInt::get(IntTy8, Length, false);
+ Constant *CIIndex = ConstantInt::get(IntTy8, Index, false);
+
+ Value *Args[] = {Op0, Op1, CILength, CIIndex};
+ Module *M = II.getModule();
+ Function *F = Intrinsic::getDeclaration(M, Intrinsic::x86_sse4a_insertqi);
+ return Builder.CreateCall(F, Args);
+ }
+
+ return nullptr;
+}
+
+/// Attempt to convert pshufb* to shufflevector if the mask is constant.
+static Value *simplifyX86pshufb(const IntrinsicInst &II,
+ InstCombiner::BuilderTy &Builder) {
+ Constant *V = dyn_cast<Constant>(II.getArgOperand(1));
+ if (!V)
+ return nullptr;
+
+ auto *VecTy = cast<FixedVectorType>(II.getType());
+ unsigned NumElts = VecTy->getNumElements();
+ assert((NumElts == 16 || NumElts == 32 || NumElts == 64) &&
+ "Unexpected number of elements in shuffle mask!");
+
+ // Construct a shuffle mask from constant integers or UNDEFs.
+ int Indexes[64];
+
+ // Each byte in the shuffle control mask forms an index to permute the
+ // corresponding byte in the destination operand.
+ for (unsigned I = 0; I < NumElts; ++I) {
+ Constant *COp = V->getAggregateElement(I);
+ if (!COp || (!isa<UndefValue>(COp) && !isa<ConstantInt>(COp)))
+ return nullptr;
+
+ if (isa<UndefValue>(COp)) {
+ Indexes[I] = -1;
+ continue;
+ }
+
+ int8_t Index = cast<ConstantInt>(COp)->getValue().getZExtValue();
+
+ // If the most significant bit (bit[7]) of each byte of the shuffle
+ // control mask is set, then zero is written in the result byte.
+ // The zero vector is in the right-hand side of the resulting
+ // shufflevector.
+
+ // The value of each index for the high 128-bit lane is the least
+ // significant 4 bits of the respective shuffle control byte.
+ Index = ((Index < 0) ? NumElts : Index & 0x0F) + (I & 0xF0);
+ Indexes[I] = Index;
+ }
+
+ auto V1 = II.getArgOperand(0);
+ auto V2 = Constant::getNullValue(VecTy);
+ return Builder.CreateShuffleVector(V1, V2, makeArrayRef(Indexes, NumElts));
+}
+
+/// Attempt to convert vpermilvar* to shufflevector if the mask is constant.
+static Value *simplifyX86vpermilvar(const IntrinsicInst &II,
+ InstCombiner::BuilderTy &Builder) {
+ Constant *V = dyn_cast<Constant>(II.getArgOperand(1));
+ if (!V)
+ return nullptr;
+
+ auto *VecTy = cast<FixedVectorType>(II.getType());
+ unsigned NumElts = VecTy->getNumElements();
+ bool IsPD = VecTy->getScalarType()->isDoubleTy();
+ unsigned NumLaneElts = IsPD ? 2 : 4;
+ assert(NumElts == 16 || NumElts == 8 || NumElts == 4 || NumElts == 2);
+
+ // Construct a shuffle mask from constant integers or UNDEFs.
+ int Indexes[16];
+
+ // The intrinsics only read one or two bits, clear the rest.
+ for (unsigned I = 0; I < NumElts; ++I) {
+ Constant *COp = V->getAggregateElement(I);
+ if (!COp || (!isa<UndefValue>(COp) && !isa<ConstantInt>(COp)))
+ return nullptr;
+
+ if (isa<UndefValue>(COp)) {
+ Indexes[I] = -1;
+ continue;
+ }
+
+ APInt Index = cast<ConstantInt>(COp)->getValue();
+ Index = Index.zextOrTrunc(32).getLoBits(2);
+
+ // The PD variants uses bit 1 to select per-lane element index, so
+ // shift down to convert to generic shuffle mask index.
+ if (IsPD)
+ Index.lshrInPlace(1);
+
+ // The _256 variants are a bit trickier since the mask bits always index
+ // into the corresponding 128 half. In order to convert to a generic
+ // shuffle, we have to make that explicit.
+ Index += APInt(32, (I / NumLaneElts) * NumLaneElts);
+
+ Indexes[I] = Index.getZExtValue();
+ }
+
+ auto V1 = II.getArgOperand(0);
+ return Builder.CreateShuffleVector(V1, makeArrayRef(Indexes, NumElts));
+}
+
+/// Attempt to convert vpermd/vpermps to shufflevector if the mask is constant.
+static Value *simplifyX86vpermv(const IntrinsicInst &II,
+ InstCombiner::BuilderTy &Builder) {
+ auto *V = dyn_cast<Constant>(II.getArgOperand(1));
+ if (!V)
+ return nullptr;
+
+ auto *VecTy = cast<FixedVectorType>(II.getType());
+ unsigned Size = VecTy->getNumElements();
+ assert((Size == 4 || Size == 8 || Size == 16 || Size == 32 || Size == 64) &&
+ "Unexpected shuffle mask size");
+
+ // Construct a shuffle mask from constant integers or UNDEFs.
+ int Indexes[64];
+
+ for (unsigned I = 0; I < Size; ++I) {
+ Constant *COp = V->getAggregateElement(I);
+ if (!COp || (!isa<UndefValue>(COp) && !isa<ConstantInt>(COp)))
+ return nullptr;
+
+ if (isa<UndefValue>(COp)) {
+ Indexes[I] = -1;
+ continue;
+ }
+
+ uint32_t Index = cast<ConstantInt>(COp)->getZExtValue();
+ Index &= Size - 1;
+ Indexes[I] = Index;
+ }
+
+ auto V1 = II.getArgOperand(0);
+ return Builder.CreateShuffleVector(V1, makeArrayRef(Indexes, Size));
+}
+
+Optional<Instruction *>
+X86TTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
+ auto SimplifyDemandedVectorEltsLow = [&IC](Value *Op, unsigned Width,
+ unsigned DemandedWidth) {
+ APInt UndefElts(Width, 0);
+ APInt DemandedElts = APInt::getLowBitsSet(Width, DemandedWidth);
+ return IC.SimplifyDemandedVectorElts(Op, DemandedElts, UndefElts);
+ };
+
+ Intrinsic::ID IID = II.getIntrinsicID();
+ switch (IID) {
+ case Intrinsic::x86_bmi_bextr_32:
+ case Intrinsic::x86_bmi_bextr_64:
+ case Intrinsic::x86_tbm_bextri_u32:
+ case Intrinsic::x86_tbm_bextri_u64:
+ // If the RHS is a constant we can try some simplifications.
+ if (auto *C = dyn_cast<ConstantInt>(II.getArgOperand(1))) {
+ uint64_t Shift = C->getZExtValue();
+ uint64_t Length = (Shift >> 8) & 0xff;
+ Shift &= 0xff;
+ unsigned BitWidth = II.getType()->getIntegerBitWidth();
+ // If the length is 0 or the shift is out of range, replace with zero.
+ if (Length == 0 || Shift >= BitWidth) {
+ return IC.replaceInstUsesWith(II, ConstantInt::get(II.getType(), 0));
+ }
+ // If the LHS is also a constant, we can completely constant fold this.
+ if (auto *InC = dyn_cast<ConstantInt>(II.getArgOperand(0))) {
+ uint64_t Result = InC->getZExtValue() >> Shift;
+ if (Length > BitWidth)
+ Length = BitWidth;
+ Result &= maskTrailingOnes<uint64_t>(Length);
+ return IC.replaceInstUsesWith(II,
+ ConstantInt::get(II.getType(), Result));
+ }
+ // TODO should we turn this into 'and' if shift is 0? Or 'shl' if we
+ // are only masking bits that a shift already cleared?
+ }
+ break;
+
+ case Intrinsic::x86_bmi_bzhi_32:
+ case Intrinsic::x86_bmi_bzhi_64:
+ // If the RHS is a constant we can try some simplifications.
+ if (auto *C = dyn_cast<ConstantInt>(II.getArgOperand(1))) {
+ uint64_t Index = C->getZExtValue() & 0xff;
+ unsigned BitWidth = II.getType()->getIntegerBitWidth();
+ if (Index >= BitWidth) {
+ return IC.replaceInstUsesWith(II, II.getArgOperand(0));
+ }
+ if (Index == 0) {
+ return IC.replaceInstUsesWith(II, ConstantInt::get(II.getType(), 0));
+ }
+ // If the LHS is also a constant, we can completely constant fold this.
+ if (auto *InC = dyn_cast<ConstantInt>(II.getArgOperand(0))) {
+ uint64_t Result = InC->getZExtValue();
+ Result &= maskTrailingOnes<uint64_t>(Index);
+ return IC.replaceInstUsesWith(II,
+ ConstantInt::get(II.getType(), Result));
+ }
+ // TODO should we convert this to an AND if the RHS is constant?
+ }
+ break;
+ case Intrinsic::x86_bmi_pext_32:
+ case Intrinsic::x86_bmi_pext_64:
+ if (auto *MaskC = dyn_cast<ConstantInt>(II.getArgOperand(1))) {
+ if (MaskC->isNullValue()) {
+ return IC.replaceInstUsesWith(II, ConstantInt::get(II.getType(), 0));
+ }
+ if (MaskC->isAllOnesValue()) {
+ return IC.replaceInstUsesWith(II, II.getArgOperand(0));
+ }
+
+ if (MaskC->getValue().isShiftedMask()) {
+ // any single contingous sequence of 1s anywhere in the mask simply
+ // describes a subset of the input bits shifted to the appropriate
+ // position. Replace with the straight forward IR.
+ unsigned ShiftAmount = MaskC->getValue().countTrailingZeros();
+ Value *Input = II.getArgOperand(0);
+ Value *Masked = IC.Builder.CreateAnd(Input, II.getArgOperand(1));
+ Value *Shifted = IC.Builder.CreateLShr(Masked,
+ ConstantInt::get(II.getType(),
+ ShiftAmount));
+ return IC.replaceInstUsesWith(II, Shifted);
+ }
+
+
+ if (auto *SrcC = dyn_cast<ConstantInt>(II.getArgOperand(0))) {
+ uint64_t Src = SrcC->getZExtValue();
+ uint64_t Mask = MaskC->getZExtValue();
+ uint64_t Result = 0;
+ uint64_t BitToSet = 1;
+
+ while (Mask) {
+ // Isolate lowest set bit.
+ uint64_t BitToTest = Mask & -Mask;
+ if (BitToTest & Src)
+ Result |= BitToSet;
+
+ BitToSet <<= 1;
+ // Clear lowest set bit.
+ Mask &= Mask - 1;
+ }
+
+ return IC.replaceInstUsesWith(II,
+ ConstantInt::get(II.getType(), Result));
+ }
+ }
+ break;
+ case Intrinsic::x86_bmi_pdep_32:
+ case Intrinsic::x86_bmi_pdep_64:
+ if (auto *MaskC = dyn_cast<ConstantInt>(II.getArgOperand(1))) {
+ if (MaskC->isNullValue()) {
+ return IC.replaceInstUsesWith(II, ConstantInt::get(II.getType(), 0));
+ }
+ if (MaskC->isAllOnesValue()) {
+ return IC.replaceInstUsesWith(II, II.getArgOperand(0));
+ }
+ if (MaskC->getValue().isShiftedMask()) {
+ // any single contingous sequence of 1s anywhere in the mask simply
+ // describes a subset of the input bits shifted to the appropriate
+ // position. Replace with the straight forward IR.
+ unsigned ShiftAmount = MaskC->getValue().countTrailingZeros();
+ Value *Input = II.getArgOperand(0);
+ Value *Shifted = IC.Builder.CreateShl(Input,
+ ConstantInt::get(II.getType(),
+ ShiftAmount));
+ Value *Masked = IC.Builder.CreateAnd(Shifted, II.getArgOperand(1));
+ return IC.replaceInstUsesWith(II, Masked);
+ }
+
+ if (auto *SrcC = dyn_cast<ConstantInt>(II.getArgOperand(0))) {
+ uint64_t Src = SrcC->getZExtValue();
+ uint64_t Mask = MaskC->getZExtValue();
+ uint64_t Result = 0;
+ uint64_t BitToTest = 1;
+
+ while (Mask) {
+ // Isolate lowest set bit.
+ uint64_t BitToSet = Mask & -Mask;
+ if (BitToTest & Src)
+ Result |= BitToSet;
+
+ BitToTest <<= 1;
+ // Clear lowest set bit;
+ Mask &= Mask - 1;
+ }
+
+ return IC.replaceInstUsesWith(II,
+ ConstantInt::get(II.getType(), Result));
+ }
+ }
+ break;
+
+ case Intrinsic::x86_sse_cvtss2si:
+ case Intrinsic::x86_sse_cvtss2si64:
+ case Intrinsic::x86_sse_cvttss2si:
+ case Intrinsic::x86_sse_cvttss2si64:
+ case Intrinsic::x86_sse2_cvtsd2si:
+ case Intrinsic::x86_sse2_cvtsd2si64:
+ case Intrinsic::x86_sse2_cvttsd2si:
+ case Intrinsic::x86_sse2_cvttsd2si64:
+ case Intrinsic::x86_avx512_vcvtss2si32:
+ case Intrinsic::x86_avx512_vcvtss2si64:
+ case Intrinsic::x86_avx512_vcvtss2usi32:
+ case Intrinsic::x86_avx512_vcvtss2usi64:
+ case Intrinsic::x86_avx512_vcvtsd2si32:
+ case Intrinsic::x86_avx512_vcvtsd2si64:
+ case Intrinsic::x86_avx512_vcvtsd2usi32:
+ case Intrinsic::x86_avx512_vcvtsd2usi64:
+ case Intrinsic::x86_avx512_cvttss2si:
+ case Intrinsic::x86_avx512_cvttss2si64:
+ case Intrinsic::x86_avx512_cvttss2usi:
+ case Intrinsic::x86_avx512_cvttss2usi64:
+ case Intrinsic::x86_avx512_cvttsd2si:
+ case Intrinsic::x86_avx512_cvttsd2si64:
+ case Intrinsic::x86_avx512_cvttsd2usi:
+ case Intrinsic::x86_avx512_cvttsd2usi64: {
+ // These intrinsics only demand the 0th element of their input vectors. If
+ // we can simplify the input based on that, do so now.
+ Value *Arg = II.getArgOperand(0);
+ unsigned VWidth = cast<FixedVectorType>(Arg->getType())->getNumElements();
+ if (Value *V = SimplifyDemandedVectorEltsLow(Arg, VWidth, 1)) {
+ return IC.replaceOperand(II, 0, V);
+ }
+ break;
+ }
+
+ case Intrinsic::x86_mmx_pmovmskb:
+ case Intrinsic::x86_sse_movmsk_ps:
+ case Intrinsic::x86_sse2_movmsk_pd:
+ case Intrinsic::x86_sse2_pmovmskb_128:
+ case Intrinsic::x86_avx_movmsk_pd_256:
+ case Intrinsic::x86_avx_movmsk_ps_256:
+ case Intrinsic::x86_avx2_pmovmskb:
+ if (Value *V = simplifyX86movmsk(II, IC.Builder)) {
+ return IC.replaceInstUsesWith(II, V);
+ }
+ break;
+
+ case Intrinsic::x86_sse_comieq_ss:
+ case Intrinsic::x86_sse_comige_ss:
+ case Intrinsic::x86_sse_comigt_ss:
+ case Intrinsic::x86_sse_comile_ss:
+ case Intrinsic::x86_sse_comilt_ss:
+ case Intrinsic::x86_sse_comineq_ss:
+ case Intrinsic::x86_sse_ucomieq_ss:
+ case Intrinsic::x86_sse_ucomige_ss:
+ case Intrinsic::x86_sse_ucomigt_ss:
+ case Intrinsic::x86_sse_ucomile_ss:
+ case Intrinsic::x86_sse_ucomilt_ss:
+ case Intrinsic::x86_sse_ucomineq_ss:
+ case Intrinsic::x86_sse2_comieq_sd:
+ case Intrinsic::x86_sse2_comige_sd:
+ case Intrinsic::x86_sse2_comigt_sd:
+ case Intrinsic::x86_sse2_comile_sd:
+ case Intrinsic::x86_sse2_comilt_sd:
+ case Intrinsic::x86_sse2_comineq_sd:
+ case Intrinsic::x86_sse2_ucomieq_sd:
+ case Intrinsic::x86_sse2_ucomige_sd:
+ case Intrinsic::x86_sse2_ucomigt_sd:
+ case Intrinsic::x86_sse2_ucomile_sd:
+ case Intrinsic::x86_sse2_ucomilt_sd:
+ case Intrinsic::x86_sse2_ucomineq_sd:
+ case Intrinsic::x86_avx512_vcomi_ss:
+ case Intrinsic::x86_avx512_vcomi_sd:
+ case Intrinsic::x86_avx512_mask_cmp_ss:
+ case Intrinsic::x86_avx512_mask_cmp_sd: {
+ // These intrinsics only demand the 0th element of their input vectors. If
+ // we can simplify the input based on that, do so now.
+ bool MadeChange = false;
+ Value *Arg0 = II.getArgOperand(0);
+ Value *Arg1 = II.getArgOperand(1);
+ unsigned VWidth = cast<FixedVectorType>(Arg0->getType())->getNumElements();
+ if (Value *V = SimplifyDemandedVectorEltsLow(Arg0, VWidth, 1)) {
+ IC.replaceOperand(II, 0, V);
+ MadeChange = true;
+ }
+ if (Value *V = SimplifyDemandedVectorEltsLow(Arg1, VWidth, 1)) {
+ IC.replaceOperand(II, 1, V);
+ MadeChange = true;
+ }
+ if (MadeChange) {
+ return &II;
+ }
+ break;
+ }
+
+ case Intrinsic::x86_avx512_add_ps_512:
+ case Intrinsic::x86_avx512_div_ps_512:
+ case Intrinsic::x86_avx512_mul_ps_512:
+ case Intrinsic::x86_avx512_sub_ps_512:
+ case Intrinsic::x86_avx512_add_pd_512:
+ case Intrinsic::x86_avx512_div_pd_512:
+ case Intrinsic::x86_avx512_mul_pd_512:
+ case Intrinsic::x86_avx512_sub_pd_512:
+ // If the rounding mode is CUR_DIRECTION(4) we can turn these into regular
+ // IR operations.
+ if (auto *R = dyn_cast<ConstantInt>(II.getArgOperand(2))) {
+ if (R->getValue() == 4) {
+ Value *Arg0 = II.getArgOperand(0);
+ Value *Arg1 = II.getArgOperand(1);
+
+ Value *V;
+ switch (IID) {
+ default:
+ llvm_unreachable("Case stmts out of sync!");
+ case Intrinsic::x86_avx512_add_ps_512:
+ case Intrinsic::x86_avx512_add_pd_512:
+ V = IC.Builder.CreateFAdd(Arg0, Arg1);
+ break;
+ case Intrinsic::x86_avx512_sub_ps_512:
+ case Intrinsic::x86_avx512_sub_pd_512:
+ V = IC.Builder.CreateFSub(Arg0, Arg1);
+ break;
+ case Intrinsic::x86_avx512_mul_ps_512:
+ case Intrinsic::x86_avx512_mul_pd_512:
+ V = IC.Builder.CreateFMul(Arg0, Arg1);
+ break;
+ case Intrinsic::x86_avx512_div_ps_512:
+ case Intrinsic::x86_avx512_div_pd_512:
+ V = IC.Builder.CreateFDiv(Arg0, Arg1);
+ break;
+ }
+
+ return IC.replaceInstUsesWith(II, V);
+ }
+ }
+ break;
+
+ case Intrinsic::x86_avx512_mask_add_ss_round:
+ case Intrinsic::x86_avx512_mask_div_ss_round:
+ case Intrinsic::x86_avx512_mask_mul_ss_round:
+ case Intrinsic::x86_avx512_mask_sub_ss_round:
+ case Intrinsic::x86_avx512_mask_add_sd_round:
+ case Intrinsic::x86_avx512_mask_div_sd_round:
+ case Intrinsic::x86_avx512_mask_mul_sd_round:
+ case Intrinsic::x86_avx512_mask_sub_sd_round:
+ // If the rounding mode is CUR_DIRECTION(4) we can turn these into regular
+ // IR operations.
+ if (auto *R = dyn_cast<ConstantInt>(II.getArgOperand(4))) {
+ if (R->getValue() == 4) {
+ // Extract the element as scalars.
+ Value *Arg0 = II.getArgOperand(0);
+ Value *Arg1 = II.getArgOperand(1);
+ Value *LHS = IC.Builder.CreateExtractElement(Arg0, (uint64_t)0);
+ Value *RHS = IC.Builder.CreateExtractElement(Arg1, (uint64_t)0);
+
+ Value *V;
+ switch (IID) {
+ default:
+ llvm_unreachable("Case stmts out of sync!");
+ case Intrinsic::x86_avx512_mask_add_ss_round:
+ case Intrinsic::x86_avx512_mask_add_sd_round:
+ V = IC.Builder.CreateFAdd(LHS, RHS);
+ break;
+ case Intrinsic::x86_avx512_mask_sub_ss_round:
+ case Intrinsic::x86_avx512_mask_sub_sd_round:
+ V = IC.Builder.CreateFSub(LHS, RHS);
+ break;
+ case Intrinsic::x86_avx512_mask_mul_ss_round:
+ case Intrinsic::x86_avx512_mask_mul_sd_round:
+ V = IC.Builder.CreateFMul(LHS, RHS);
+ break;
+ case Intrinsic::x86_avx512_mask_div_ss_round:
+ case Intrinsic::x86_avx512_mask_div_sd_round:
+ V = IC.Builder.CreateFDiv(LHS, RHS);
+ break;
+ }
+
+ // Handle the masking aspect of the intrinsic.
+ Value *Mask = II.getArgOperand(3);
+ auto *C = dyn_cast<ConstantInt>(Mask);
+ // We don't need a select if we know the mask bit is a 1.
+ if (!C || !C->getValue()[0]) {
+ // Cast the mask to an i1 vector and then extract the lowest element.
+ auto *MaskTy = FixedVectorType::get(
+ IC.Builder.getInt1Ty(),
+ cast<IntegerType>(Mask->getType())->getBitWidth());
+ Mask = IC.Builder.CreateBitCast(Mask, MaskTy);
+ Mask = IC.Builder.CreateExtractElement(Mask, (uint64_t)0);
+ // Extract the lowest element from the passthru operand.
+ Value *Passthru =
+ IC.Builder.CreateExtractElement(II.getArgOperand(2), (uint64_t)0);
+ V = IC.Builder.CreateSelect(Mask, V, Passthru);
+ }
+
+ // Insert the result back into the original argument 0.
+ V = IC.Builder.CreateInsertElement(Arg0, V, (uint64_t)0);
+
+ return IC.replaceInstUsesWith(II, V);
+ }
+ }
+ break;
+
+ // Constant fold ashr( <A x Bi>, Ci ).
+ // Constant fold lshr( <A x Bi>, Ci ).
+ // Constant fold shl( <A x Bi>, Ci ).
+ case Intrinsic::x86_sse2_psrai_d:
+ case Intrinsic::x86_sse2_psrai_w:
+ case Intrinsic::x86_avx2_psrai_d:
+ case Intrinsic::x86_avx2_psrai_w:
+ case Intrinsic::x86_avx512_psrai_q_128:
+ case Intrinsic::x86_avx512_psrai_q_256:
+ case Intrinsic::x86_avx512_psrai_d_512:
+ case Intrinsic::x86_avx512_psrai_q_512:
+ case Intrinsic::x86_avx512_psrai_w_512:
+ case Intrinsic::x86_sse2_psrli_d:
+ case Intrinsic::x86_sse2_psrli_q:
+ case Intrinsic::x86_sse2_psrli_w:
+ case Intrinsic::x86_avx2_psrli_d:
+ case Intrinsic::x86_avx2_psrli_q:
+ case Intrinsic::x86_avx2_psrli_w:
+ case Intrinsic::x86_avx512_psrli_d_512:
+ case Intrinsic::x86_avx512_psrli_q_512:
+ case Intrinsic::x86_avx512_psrli_w_512:
+ case Intrinsic::x86_sse2_pslli_d:
+ case Intrinsic::x86_sse2_pslli_q:
+ case Intrinsic::x86_sse2_pslli_w:
+ case Intrinsic::x86_avx2_pslli_d:
+ case Intrinsic::x86_avx2_pslli_q:
+ case Intrinsic::x86_avx2_pslli_w:
+ case Intrinsic::x86_avx512_pslli_d_512:
+ case Intrinsic::x86_avx512_pslli_q_512:
+ case Intrinsic::x86_avx512_pslli_w_512:
+ if (Value *V = simplifyX86immShift(II, IC.Builder)) {
+ return IC.replaceInstUsesWith(II, V);
+ }
+ break;
+
+ case Intrinsic::x86_sse2_psra_d:
+ case Intrinsic::x86_sse2_psra_w:
+ case Intrinsic::x86_avx2_psra_d:
+ case Intrinsic::x86_avx2_psra_w:
+ case Intrinsic::x86_avx512_psra_q_128:
+ case Intrinsic::x86_avx512_psra_q_256:
+ case Intrinsic::x86_avx512_psra_d_512:
+ case Intrinsic::x86_avx512_psra_q_512:
+ case Intrinsic::x86_avx512_psra_w_512:
+ case Intrinsic::x86_sse2_psrl_d:
+ case Intrinsic::x86_sse2_psrl_q:
+ case Intrinsic::x86_sse2_psrl_w:
+ case Intrinsic::x86_avx2_psrl_d:
+ case Intrinsic::x86_avx2_psrl_q:
+ case Intrinsic::x86_avx2_psrl_w:
+ case Intrinsic::x86_avx512_psrl_d_512:
+ case Intrinsic::x86_avx512_psrl_q_512:
+ case Intrinsic::x86_avx512_psrl_w_512:
+ case Intrinsic::x86_sse2_psll_d:
+ case Intrinsic::x86_sse2_psll_q:
+ case Intrinsic::x86_sse2_psll_w:
+ case Intrinsic::x86_avx2_psll_d:
+ case Intrinsic::x86_avx2_psll_q:
+ case Intrinsic::x86_avx2_psll_w:
+ case Intrinsic::x86_avx512_psll_d_512:
+ case Intrinsic::x86_avx512_psll_q_512:
+ case Intrinsic::x86_avx512_psll_w_512: {
+ if (Value *V = simplifyX86immShift(II, IC.Builder)) {
+ return IC.replaceInstUsesWith(II, V);
+ }
+
+ // SSE2/AVX2 uses only the first 64-bits of the 128-bit vector
+ // operand to compute the shift amount.
+ Value *Arg1 = II.getArgOperand(1);
+ assert(Arg1->getType()->getPrimitiveSizeInBits() == 128 &&
+ "Unexpected packed shift size");
+ unsigned VWidth = cast<FixedVectorType>(Arg1->getType())->getNumElements();
+
+ if (Value *V = SimplifyDemandedVectorEltsLow(Arg1, VWidth, VWidth / 2)) {
+ return IC.replaceOperand(II, 1, V);
+ }
+ break;
+ }
+
+ case Intrinsic::x86_avx2_psllv_d:
+ case Intrinsic::x86_avx2_psllv_d_256:
+ case Intrinsic::x86_avx2_psllv_q:
+ case Intrinsic::x86_avx2_psllv_q_256:
+ case Intrinsic::x86_avx512_psllv_d_512:
+ case Intrinsic::x86_avx512_psllv_q_512:
+ case Intrinsic::x86_avx512_psllv_w_128:
+ case Intrinsic::x86_avx512_psllv_w_256:
+ case Intrinsic::x86_avx512_psllv_w_512:
+ case Intrinsic::x86_avx2_psrav_d:
+ case Intrinsic::x86_avx2_psrav_d_256:
+ case Intrinsic::x86_avx512_psrav_q_128:
+ case Intrinsic::x86_avx512_psrav_q_256:
+ case Intrinsic::x86_avx512_psrav_d_512:
+ case Intrinsic::x86_avx512_psrav_q_512:
+ case Intrinsic::x86_avx512_psrav_w_128:
+ case Intrinsic::x86_avx512_psrav_w_256:
+ case Intrinsic::x86_avx512_psrav_w_512:
+ case Intrinsic::x86_avx2_psrlv_d:
+ case Intrinsic::x86_avx2_psrlv_d_256:
+ case Intrinsic::x86_avx2_psrlv_q:
+ case Intrinsic::x86_avx2_psrlv_q_256:
+ case Intrinsic::x86_avx512_psrlv_d_512:
+ case Intrinsic::x86_avx512_psrlv_q_512:
+ case Intrinsic::x86_avx512_psrlv_w_128:
+ case Intrinsic::x86_avx512_psrlv_w_256:
+ case Intrinsic::x86_avx512_psrlv_w_512:
+ if (Value *V = simplifyX86varShift(II, IC.Builder)) {
+ return IC.replaceInstUsesWith(II, V);
+ }
+ break;
+
+ case Intrinsic::x86_sse2_packssdw_128:
+ case Intrinsic::x86_sse2_packsswb_128:
+ case Intrinsic::x86_avx2_packssdw:
+ case Intrinsic::x86_avx2_packsswb:
+ case Intrinsic::x86_avx512_packssdw_512:
+ case Intrinsic::x86_avx512_packsswb_512:
+ if (Value *V = simplifyX86pack(II, IC.Builder, true)) {
+ return IC.replaceInstUsesWith(II, V);
+ }
+ break;
+
+ case Intrinsic::x86_sse2_packuswb_128:
+ case Intrinsic::x86_sse41_packusdw:
+ case Intrinsic::x86_avx2_packusdw:
+ case Intrinsic::x86_avx2_packuswb:
+ case Intrinsic::x86_avx512_packusdw_512:
+ case Intrinsic::x86_avx512_packuswb_512:
+ if (Value *V = simplifyX86pack(II, IC.Builder, false)) {
+ return IC.replaceInstUsesWith(II, V);
+ }
+ break;
+
+ case Intrinsic::x86_pclmulqdq:
+ case Intrinsic::x86_pclmulqdq_256:
+ case Intrinsic::x86_pclmulqdq_512: {
+ if (auto *C = dyn_cast<ConstantInt>(II.getArgOperand(2))) {
+ unsigned Imm = C->getZExtValue();
+
+ bool MadeChange = false;
+ Value *Arg0 = II.getArgOperand(0);
+ Value *Arg1 = II.getArgOperand(1);
+ unsigned VWidth =
+ cast<FixedVectorType>(Arg0->getType())->getNumElements();
+
+ APInt UndefElts1(VWidth, 0);
+ APInt DemandedElts1 =
+ APInt::getSplat(VWidth, APInt(2, (Imm & 0x01) ? 2 : 1));
+ if (Value *V =
+ IC.SimplifyDemandedVectorElts(Arg0, DemandedElts1, UndefElts1)) {
+ IC.replaceOperand(II, 0, V);
+ MadeChange = true;
+ }
+
+ APInt UndefElts2(VWidth, 0);
+ APInt DemandedElts2 =
+ APInt::getSplat(VWidth, APInt(2, (Imm & 0x10) ? 2 : 1));
+ if (Value *V =
+ IC.SimplifyDemandedVectorElts(Arg1, DemandedElts2, UndefElts2)) {
+ IC.replaceOperand(II, 1, V);
+ MadeChange = true;
+ }
+
+ // If either input elements are undef, the result is zero.
+ if (DemandedElts1.isSubsetOf(UndefElts1) ||
+ DemandedElts2.isSubsetOf(UndefElts2)) {
+ return IC.replaceInstUsesWith(II,
+ ConstantAggregateZero::get(II.getType()));
+ }
+
+ if (MadeChange) {
+ return &II;
+ }
+ }
+ break;
+ }
+
+ case Intrinsic::x86_sse41_insertps:
+ if (Value *V = simplifyX86insertps(II, IC.Builder)) {
+ return IC.replaceInstUsesWith(II, V);
+ }
+ break;
+
+ case Intrinsic::x86_sse4a_extrq: {
+ Value *Op0 = II.getArgOperand(0);
+ Value *Op1 = II.getArgOperand(1);
+ unsigned VWidth0 = cast<FixedVectorType>(Op0->getType())->getNumElements();
+ unsigned VWidth1 = cast<FixedVectorType>(Op1->getType())->getNumElements();
+ assert(Op0->getType()->getPrimitiveSizeInBits() == 128 &&
+ Op1->getType()->getPrimitiveSizeInBits() == 128 && VWidth0 == 2 &&
+ VWidth1 == 16 && "Unexpected operand sizes");
+
+ // See if we're dealing with constant values.
+ Constant *C1 = dyn_cast<Constant>(Op1);
+ ConstantInt *CILength =
+ C1 ? dyn_cast_or_null<ConstantInt>(C1->getAggregateElement((unsigned)0))
+ : nullptr;
+ ConstantInt *CIIndex =
+ C1 ? dyn_cast_or_null<ConstantInt>(C1->getAggregateElement((unsigned)1))
+ : nullptr;
+
+ // Attempt to simplify to a constant, shuffle vector or EXTRQI call.
+ if (Value *V = simplifyX86extrq(II, Op0, CILength, CIIndex, IC.Builder)) {
+ return IC.replaceInstUsesWith(II, V);
+ }
+
+ // EXTRQ only uses the lowest 64-bits of the first 128-bit vector
+ // operands and the lowest 16-bits of the second.
+ bool MadeChange = false;
+ if (Value *V = SimplifyDemandedVectorEltsLow(Op0, VWidth0, 1)) {
+ IC.replaceOperand(II, 0, V);
+ MadeChange = true;
+ }
+ if (Value *V = SimplifyDemandedVectorEltsLow(Op1, VWidth1, 2)) {
+ IC.replaceOperand(II, 1, V);
+ MadeChange = true;
+ }
+ if (MadeChange) {
+ return &II;
+ }
+ break;
+ }
+
+ case Intrinsic::x86_sse4a_extrqi: {
+ // EXTRQI: Extract Length bits starting from Index. Zero pad the remaining
+ // bits of the lower 64-bits. The upper 64-bits are undefined.
+ Value *Op0 = II.getArgOperand(0);
+ unsigned VWidth = cast<FixedVectorType>(Op0->getType())->getNumElements();
+ assert(Op0->getType()->getPrimitiveSizeInBits() == 128 && VWidth == 2 &&
+ "Unexpected operand size");
+
+ // See if we're dealing with constant values.
+ ConstantInt *CILength = dyn_cast<ConstantInt>(II.getArgOperand(1));
+ ConstantInt *CIIndex = dyn_cast<ConstantInt>(II.getArgOperand(2));
+
+ // Attempt to simplify to a constant or shuffle vector.
+ if (Value *V = simplifyX86extrq(II, Op0, CILength, CIIndex, IC.Builder)) {
+ return IC.replaceInstUsesWith(II, V);
+ }
+
+ // EXTRQI only uses the lowest 64-bits of the first 128-bit vector
+ // operand.
+ if (Value *V = SimplifyDemandedVectorEltsLow(Op0, VWidth, 1)) {
+ return IC.replaceOperand(II, 0, V);
+ }
+ break;
+ }
+
+ case Intrinsic::x86_sse4a_insertq: {
+ Value *Op0 = II.getArgOperand(0);
+ Value *Op1 = II.getArgOperand(1);
+ unsigned VWidth = cast<FixedVectorType>(Op0->getType())->getNumElements();
+ assert(Op0->getType()->getPrimitiveSizeInBits() == 128 &&
+ Op1->getType()->getPrimitiveSizeInBits() == 128 && VWidth == 2 &&
+ cast<FixedVectorType>(Op1->getType())->getNumElements() == 2 &&
+ "Unexpected operand size");
+
+ // See if we're dealing with constant values.
+ Constant *C1 = dyn_cast<Constant>(Op1);
+ ConstantInt *CI11 =
+ C1 ? dyn_cast_or_null<ConstantInt>(C1->getAggregateElement((unsigned)1))
+ : nullptr;
+
+ // Attempt to simplify to a constant, shuffle vector or INSERTQI call.
+ if (CI11) {
+ const APInt &V11 = CI11->getValue();
+ APInt Len = V11.zextOrTrunc(6);
+ APInt Idx = V11.lshr(8).zextOrTrunc(6);
+ if (Value *V = simplifyX86insertq(II, Op0, Op1, Len, Idx, IC.Builder)) {
+ return IC.replaceInstUsesWith(II, V);
+ }
+ }
+
+ // INSERTQ only uses the lowest 64-bits of the first 128-bit vector
+ // operand.
+ if (Value *V = SimplifyDemandedVectorEltsLow(Op0, VWidth, 1)) {
+ return IC.replaceOperand(II, 0, V);
+ }
+ break;
+ }
+
+ case Intrinsic::x86_sse4a_insertqi: {
+ // INSERTQI: Extract lowest Length bits from lower half of second source and
+ // insert over first source starting at Index bit. The upper 64-bits are
+ // undefined.
+ Value *Op0 = II.getArgOperand(0);
+ Value *Op1 = II.getArgOperand(1);
+ unsigned VWidth0 = cast<FixedVectorType>(Op0->getType())->getNumElements();
+ unsigned VWidth1 = cast<FixedVectorType>(Op1->getType())->getNumElements();
+ assert(Op0->getType()->getPrimitiveSizeInBits() == 128 &&
+ Op1->getType()->getPrimitiveSizeInBits() == 128 && VWidth0 == 2 &&
+ VWidth1 == 2 && "Unexpected operand sizes");
+
+ // See if we're dealing with constant values.
+ ConstantInt *CILength = dyn_cast<ConstantInt>(II.getArgOperand(2));
+ ConstantInt *CIIndex = dyn_cast<ConstantInt>(II.getArgOperand(3));
+
+ // Attempt to simplify to a constant or shuffle vector.
+ if (CILength && CIIndex) {
+ APInt Len = CILength->getValue().zextOrTrunc(6);
+ APInt Idx = CIIndex->getValue().zextOrTrunc(6);
+ if (Value *V = simplifyX86insertq(II, Op0, Op1, Len, Idx, IC.Builder)) {
+ return IC.replaceInstUsesWith(II, V);
+ }
+ }
+
+ // INSERTQI only uses the lowest 64-bits of the first two 128-bit vector
+ // operands.
+ bool MadeChange = false;
+ if (Value *V = SimplifyDemandedVectorEltsLow(Op0, VWidth0, 1)) {
+ IC.replaceOperand(II, 0, V);
+ MadeChange = true;
+ }
+ if (Value *V = SimplifyDemandedVectorEltsLow(Op1, VWidth1, 1)) {
+ IC.replaceOperand(II, 1, V);
+ MadeChange = true;
+ }
+ if (MadeChange) {
+ return &II;
+ }
+ break;
+ }
+
+ case Intrinsic::x86_sse41_pblendvb:
+ case Intrinsic::x86_sse41_blendvps:
+ case Intrinsic::x86_sse41_blendvpd:
+ case Intrinsic::x86_avx_blendv_ps_256:
+ case Intrinsic::x86_avx_blendv_pd_256:
+ case Intrinsic::x86_avx2_pblendvb: {
+ // fold (blend A, A, Mask) -> A
+ Value *Op0 = II.getArgOperand(0);
+ Value *Op1 = II.getArgOperand(1);
+ Value *Mask = II.getArgOperand(2);
+ if (Op0 == Op1) {
+ return IC.replaceInstUsesWith(II, Op0);
+ }
+
+ // Zero Mask - select 1st argument.
+ if (isa<ConstantAggregateZero>(Mask)) {
+ return IC.replaceInstUsesWith(II, Op0);
+ }
+
+ // Constant Mask - select 1st/2nd argument lane based on top bit of mask.
+ if (auto *ConstantMask = dyn_cast<ConstantDataVector>(Mask)) {
+ Constant *NewSelector = getNegativeIsTrueBoolVec(ConstantMask);
+ return SelectInst::Create(NewSelector, Op1, Op0, "blendv");
+ }
+
+ // Convert to a vector select if we can bypass casts and find a boolean
+ // vector condition value.
+ Value *BoolVec;
+ Mask = InstCombiner::peekThroughBitcast(Mask);
+ if (match(Mask, PatternMatch::m_SExt(PatternMatch::m_Value(BoolVec))) &&
+ BoolVec->getType()->isVectorTy() &&
+ BoolVec->getType()->getScalarSizeInBits() == 1) {
+ assert(Mask->getType()->getPrimitiveSizeInBits() ==
+ II.getType()->getPrimitiveSizeInBits() &&
+ "Not expecting mask and operands with different sizes");
+
+ unsigned NumMaskElts =
+ cast<FixedVectorType>(Mask->getType())->getNumElements();
+ unsigned NumOperandElts =
+ cast<FixedVectorType>(II.getType())->getNumElements();
+ if (NumMaskElts == NumOperandElts) {
+ return SelectInst::Create(BoolVec, Op1, Op0);
+ }
+
+ // If the mask has less elements than the operands, each mask bit maps to
+ // multiple elements of the operands. Bitcast back and forth.
+ if (NumMaskElts < NumOperandElts) {
+ Value *CastOp0 = IC.Builder.CreateBitCast(Op0, Mask->getType());
+ Value *CastOp1 = IC.Builder.CreateBitCast(Op1, Mask->getType());
+ Value *Sel = IC.Builder.CreateSelect(BoolVec, CastOp1, CastOp0);
+ return new BitCastInst(Sel, II.getType());
+ }
+ }
+
+ break;
+ }
+
+ case Intrinsic::x86_ssse3_pshuf_b_128:
+ case Intrinsic::x86_avx2_pshuf_b:
+ case Intrinsic::x86_avx512_pshuf_b_512:
+ if (Value *V = simplifyX86pshufb(II, IC.Builder)) {
+ return IC.replaceInstUsesWith(II, V);
+ }
+ break;
+
+ case Intrinsic::x86_avx_vpermilvar_ps:
+ case Intrinsic::x86_avx_vpermilvar_ps_256:
+ case Intrinsic::x86_avx512_vpermilvar_ps_512:
+ case Intrinsic::x86_avx_vpermilvar_pd:
+ case Intrinsic::x86_avx_vpermilvar_pd_256:
+ case Intrinsic::x86_avx512_vpermilvar_pd_512:
+ if (Value *V = simplifyX86vpermilvar(II, IC.Builder)) {
+ return IC.replaceInstUsesWith(II, V);
+ }
+ break;
+
+ case Intrinsic::x86_avx2_permd:
+ case Intrinsic::x86_avx2_permps:
+ case Intrinsic::x86_avx512_permvar_df_256:
+ case Intrinsic::x86_avx512_permvar_df_512:
+ case Intrinsic::x86_avx512_permvar_di_256:
+ case Intrinsic::x86_avx512_permvar_di_512:
+ case Intrinsic::x86_avx512_permvar_hi_128:
+ case Intrinsic::x86_avx512_permvar_hi_256:
+ case Intrinsic::x86_avx512_permvar_hi_512:
+ case Intrinsic::x86_avx512_permvar_qi_128:
+ case Intrinsic::x86_avx512_permvar_qi_256:
+ case Intrinsic::x86_avx512_permvar_qi_512:
+ case Intrinsic::x86_avx512_permvar_sf_512:
+ case Intrinsic::x86_avx512_permvar_si_512:
+ if (Value *V = simplifyX86vpermv(II, IC.Builder)) {
+ return IC.replaceInstUsesWith(II, V);
+ }
+ break;
+
+ case Intrinsic::x86_avx_maskload_ps:
+ case Intrinsic::x86_avx_maskload_pd:
+ case Intrinsic::x86_avx_maskload_ps_256:
+ case Intrinsic::x86_avx_maskload_pd_256:
+ case Intrinsic::x86_avx2_maskload_d:
+ case Intrinsic::x86_avx2_maskload_q:
+ case Intrinsic::x86_avx2_maskload_d_256:
+ case Intrinsic::x86_avx2_maskload_q_256:
+ if (Instruction *I = simplifyX86MaskedLoad(II, IC)) {
+ return I;
+ }
+ break;
+
+ case Intrinsic::x86_sse2_maskmov_dqu:
+ case Intrinsic::x86_avx_maskstore_ps:
+ case Intrinsic::x86_avx_maskstore_pd:
+ case Intrinsic::x86_avx_maskstore_ps_256:
+ case Intrinsic::x86_avx_maskstore_pd_256:
+ case Intrinsic::x86_avx2_maskstore_d:
+ case Intrinsic::x86_avx2_maskstore_q:
+ case Intrinsic::x86_avx2_maskstore_d_256:
+ case Intrinsic::x86_avx2_maskstore_q_256:
+ if (simplifyX86MaskedStore(II, IC)) {
+ return nullptr;
+ }
+ break;
+
+ case Intrinsic::x86_addcarry_32:
+ case Intrinsic::x86_addcarry_64:
+ if (Value *V = simplifyX86addcarry(II, IC.Builder)) {
+ return IC.replaceInstUsesWith(II, V);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return None;
+}
+
+Optional<Value *> X86TTIImpl::simplifyDemandedUseBitsIntrinsic(
+ InstCombiner &IC, IntrinsicInst &II, APInt DemandedMask, KnownBits &Known,
+ bool &KnownBitsComputed) const {
+ switch (II.getIntrinsicID()) {
+ default:
+ break;
+ case Intrinsic::x86_mmx_pmovmskb:
+ case Intrinsic::x86_sse_movmsk_ps:
+ case Intrinsic::x86_sse2_movmsk_pd:
+ case Intrinsic::x86_sse2_pmovmskb_128:
+ case Intrinsic::x86_avx_movmsk_ps_256:
+ case Intrinsic::x86_avx_movmsk_pd_256:
+ case Intrinsic::x86_avx2_pmovmskb: {
+ // MOVMSK copies the vector elements' sign bits to the low bits
+ // and zeros the high bits.
+ unsigned ArgWidth;
+ if (II.getIntrinsicID() == Intrinsic::x86_mmx_pmovmskb) {
+ ArgWidth = 8; // Arg is x86_mmx, but treated as <8 x i8>.
+ } else {
+ auto Arg = II.getArgOperand(0);
+ auto ArgType = cast<FixedVectorType>(Arg->getType());
+ ArgWidth = ArgType->getNumElements();
+ }
+
+ // If we don't need any of low bits then return zero,
+ // we know that DemandedMask is non-zero already.
+ APInt DemandedElts = DemandedMask.zextOrTrunc(ArgWidth);
+ Type *VTy = II.getType();
+ if (DemandedElts.isNullValue()) {
+ return ConstantInt::getNullValue(VTy);
+ }
+
+ // We know that the upper bits are set to zero.
+ Known.Zero.setBitsFrom(ArgWidth);
+ KnownBitsComputed = true;
+ break;
+ }
+ }
+ return None;
+}
+
+Optional<Value *> X86TTIImpl::simplifyDemandedVectorEltsIntrinsic(
+ InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
+ APInt &UndefElts2, APInt &UndefElts3,
+ std::function<void(Instruction *, unsigned, APInt, APInt &)>
+ simplifyAndSetOp) const {
+ unsigned VWidth = cast<FixedVectorType>(II.getType())->getNumElements();
+ switch (II.getIntrinsicID()) {
+ default:
+ break;
+ case Intrinsic::x86_xop_vfrcz_ss:
+ case Intrinsic::x86_xop_vfrcz_sd:
+ // The instructions for these intrinsics are speced to zero upper bits not
+ // pass them through like other scalar intrinsics. So we shouldn't just
+ // use Arg0 if DemandedElts[0] is clear like we do for other intrinsics.
+ // Instead we should return a zero vector.
+ if (!DemandedElts[0]) {
+ IC.addToWorklist(&II);
+ return ConstantAggregateZero::get(II.getType());
+ }
+
+ // Only the lower element is used.
+ DemandedElts = 1;
+ simplifyAndSetOp(&II, 0, DemandedElts, UndefElts);
+
+ // Only the lower element is undefined. The high elements are zero.
+ UndefElts = UndefElts[0];
+ break;
+
+ // Unary scalar-as-vector operations that work column-wise.
+ case Intrinsic::x86_sse_rcp_ss:
+ case Intrinsic::x86_sse_rsqrt_ss:
+ simplifyAndSetOp(&II, 0, DemandedElts, UndefElts);
+
+ // If lowest element of a scalar op isn't used then use Arg0.
+ if (!DemandedElts[0]) {
+ IC.addToWorklist(&II);
+ return II.getArgOperand(0);
+ }
+ // TODO: If only low elt lower SQRT to FSQRT (with rounding/exceptions
+ // checks).
+ break;
+
+ // Binary scalar-as-vector operations that work column-wise. The high
+ // elements come from operand 0. The low element is a function of both
+ // operands.
+ case Intrinsic::x86_sse_min_ss:
+ case Intrinsic::x86_sse_max_ss:
+ case Intrinsic::x86_sse_cmp_ss:
+ case Intrinsic::x86_sse2_min_sd:
+ case Intrinsic::x86_sse2_max_sd:
+ case Intrinsic::x86_sse2_cmp_sd: {
+ simplifyAndSetOp(&II, 0, DemandedElts, UndefElts);
+
+ // If lowest element of a scalar op isn't used then use Arg0.
+ if (!DemandedElts[0]) {
+ IC.addToWorklist(&II);
+ return II.getArgOperand(0);
+ }
+
+ // Only lower element is used for operand 1.
+ DemandedElts = 1;
+ simplifyAndSetOp(&II, 1, DemandedElts, UndefElts2);
+
+ // Lower element is undefined if both lower elements are undefined.
+ // Consider things like undef&0. The result is known zero, not undef.
+ if (!UndefElts2[0])
+ UndefElts.clearBit(0);
+
+ break;
+ }
+
+ // Binary scalar-as-vector operations that work column-wise. The high
+ // elements come from operand 0 and the low element comes from operand 1.
+ case Intrinsic::x86_sse41_round_ss:
+ case Intrinsic::x86_sse41_round_sd: {
+ // Don't use the low element of operand 0.
+ APInt DemandedElts2 = DemandedElts;
+ DemandedElts2.clearBit(0);
+ simplifyAndSetOp(&II, 0, DemandedElts2, UndefElts);
+
+ // If lowest element of a scalar op isn't used then use Arg0.
+ if (!DemandedElts[0]) {
+ IC.addToWorklist(&II);
+ return II.getArgOperand(0);
+ }
+
+ // Only lower element is used for operand 1.
+ DemandedElts = 1;
+ simplifyAndSetOp(&II, 1, DemandedElts, UndefElts2);
+
+ // Take the high undef elements from operand 0 and take the lower element
+ // from operand 1.
+ UndefElts.clearBit(0);
+ UndefElts |= UndefElts2[0];
+ break;
+ }
+
+ // Three input scalar-as-vector operations that work column-wise. The high
+ // elements come from operand 0 and the low element is a function of all
+ // three inputs.
+ case Intrinsic::x86_avx512_mask_add_ss_round:
+ case Intrinsic::x86_avx512_mask_div_ss_round:
+ case Intrinsic::x86_avx512_mask_mul_ss_round:
+ case Intrinsic::x86_avx512_mask_sub_ss_round:
+ case Intrinsic::x86_avx512_mask_max_ss_round:
+ case Intrinsic::x86_avx512_mask_min_ss_round:
+ case Intrinsic::x86_avx512_mask_add_sd_round:
+ case Intrinsic::x86_avx512_mask_div_sd_round:
+ case Intrinsic::x86_avx512_mask_mul_sd_round:
+ case Intrinsic::x86_avx512_mask_sub_sd_round:
+ case Intrinsic::x86_avx512_mask_max_sd_round:
+ case Intrinsic::x86_avx512_mask_min_sd_round:
+ simplifyAndSetOp(&II, 0, DemandedElts, UndefElts);
+
+ // If lowest element of a scalar op isn't used then use Arg0.
+ if (!DemandedElts[0]) {
+ IC.addToWorklist(&II);
+ return II.getArgOperand(0);
+ }
+
+ // Only lower element is used for operand 1 and 2.
+ DemandedElts = 1;
+ simplifyAndSetOp(&II, 1, DemandedElts, UndefElts2);
+ simplifyAndSetOp(&II, 2, DemandedElts, UndefElts3);
+
+ // Lower element is undefined if all three lower elements are undefined.
+ // Consider things like undef&0. The result is known zero, not undef.
+ if (!UndefElts2[0] || !UndefElts3[0])
+ UndefElts.clearBit(0);
+ break;
+
+ // TODO: Add fmaddsub support?
+ case Intrinsic::x86_sse3_addsub_pd:
+ case Intrinsic::x86_sse3_addsub_ps:
+ case Intrinsic::x86_avx_addsub_pd_256:
+ case Intrinsic::x86_avx_addsub_ps_256: {
+ // If none of the even or none of the odd lanes are required, turn this
+ // into a generic FP math instruction.
+ APInt SubMask = APInt::getSplat(VWidth, APInt(2, 0x1));
+ APInt AddMask = APInt::getSplat(VWidth, APInt(2, 0x2));
+ bool IsSubOnly = DemandedElts.isSubsetOf(SubMask);
+ bool IsAddOnly = DemandedElts.isSubsetOf(AddMask);
+ if (IsSubOnly || IsAddOnly) {
+ assert((IsSubOnly ^ IsAddOnly) && "Can't be both add-only and sub-only");
+ IRBuilderBase::InsertPointGuard Guard(IC.Builder);
+ IC.Builder.SetInsertPoint(&II);
+ Value *Arg0 = II.getArgOperand(0), *Arg1 = II.getArgOperand(1);
+ return IC.Builder.CreateBinOp(
+ IsSubOnly ? Instruction::FSub : Instruction::FAdd, Arg0, Arg1);
+ }
+
+ simplifyAndSetOp(&II, 0, DemandedElts, UndefElts);
+ simplifyAndSetOp(&II, 1, DemandedElts, UndefElts2);
+ UndefElts &= UndefElts2;
+ break;
+ }
+
+ case Intrinsic::x86_sse2_packssdw_128:
+ case Intrinsic::x86_sse2_packsswb_128:
+ case Intrinsic::x86_sse2_packuswb_128:
+ case Intrinsic::x86_sse41_packusdw:
+ case Intrinsic::x86_avx2_packssdw:
+ case Intrinsic::x86_avx2_packsswb:
+ case Intrinsic::x86_avx2_packusdw:
+ case Intrinsic::x86_avx2_packuswb:
+ case Intrinsic::x86_avx512_packssdw_512:
+ case Intrinsic::x86_avx512_packsswb_512:
+ case Intrinsic::x86_avx512_packusdw_512:
+ case Intrinsic::x86_avx512_packuswb_512: {
+ auto *Ty0 = II.getArgOperand(0)->getType();
+ unsigned InnerVWidth = cast<FixedVectorType>(Ty0)->getNumElements();
+ assert(VWidth == (InnerVWidth * 2) && "Unexpected input size");
+
+ unsigned NumLanes = Ty0->getPrimitiveSizeInBits() / 128;
+ unsigned VWidthPerLane = VWidth / NumLanes;
+ unsigned InnerVWidthPerLane = InnerVWidth / NumLanes;
+
+ // Per lane, pack the elements of the first input and then the second.
+ // e.g.
+ // v8i16 PACK(v4i32 X, v4i32 Y) - (X[0..3],Y[0..3])
+ // v32i8 PACK(v16i16 X, v16i16 Y) - (X[0..7],Y[0..7]),(X[8..15],Y[8..15])
+ for (int OpNum = 0; OpNum != 2; ++OpNum) {
+ APInt OpDemandedElts(InnerVWidth, 0);
+ for (unsigned Lane = 0; Lane != NumLanes; ++Lane) {
+ unsigned LaneIdx = Lane * VWidthPerLane;
+ for (unsigned Elt = 0; Elt != InnerVWidthPerLane; ++Elt) {
+ unsigned Idx = LaneIdx + Elt + InnerVWidthPerLane * OpNum;
+ if (DemandedElts[Idx])
+ OpDemandedElts.setBit((Lane * InnerVWidthPerLane) + Elt);
+ }
+ }
+
+ // Demand elements from the operand.
+ APInt OpUndefElts(InnerVWidth, 0);
+ simplifyAndSetOp(&II, OpNum, OpDemandedElts, OpUndefElts);
+
+ // Pack the operand's UNDEF elements, one lane at a time.
+ OpUndefElts = OpUndefElts.zext(VWidth);
+ for (unsigned Lane = 0; Lane != NumLanes; ++Lane) {
+ APInt LaneElts = OpUndefElts.lshr(InnerVWidthPerLane * Lane);
+ LaneElts = LaneElts.getLoBits(InnerVWidthPerLane);
+ LaneElts <<= InnerVWidthPerLane * (2 * Lane + OpNum);
+ UndefElts |= LaneElts;
+ }
+ }
+ break;
+ }
+
+ // PSHUFB
+ case Intrinsic::x86_ssse3_pshuf_b_128:
+ case Intrinsic::x86_avx2_pshuf_b:
+ case Intrinsic::x86_avx512_pshuf_b_512:
+ // PERMILVAR
+ case Intrinsic::x86_avx_vpermilvar_ps:
+ case Intrinsic::x86_avx_vpermilvar_ps_256:
+ case Intrinsic::x86_avx512_vpermilvar_ps_512:
+ case Intrinsic::x86_avx_vpermilvar_pd:
+ case Intrinsic::x86_avx_vpermilvar_pd_256:
+ case Intrinsic::x86_avx512_vpermilvar_pd_512:
+ // PERMV
+ case Intrinsic::x86_avx2_permd:
+ case Intrinsic::x86_avx2_permps: {
+ simplifyAndSetOp(&II, 1, DemandedElts, UndefElts);
+ break;
+ }
+
+ // SSE4A instructions leave the upper 64-bits of the 128-bit result
+ // in an undefined state.
+ case Intrinsic::x86_sse4a_extrq:
+ case Intrinsic::x86_sse4a_extrqi:
+ case Intrinsic::x86_sse4a_insertq:
+ case Intrinsic::x86_sse4a_insertqi:
+ UndefElts.setHighBits(VWidth / 2);
+ break;
+ }
+ return None;
+}
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td b/contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td
index e9ec53476c..e4f3290cab 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrAMX.td
@@ -16,21 +16,21 @@
let Predicates = [HasAMXTILE, In64BitMode] in {
let SchedRW = [WriteSystem] in {
- let hasSideEffects = 1,
- Defs = [TMM0,TMM1,TMM2,TMM3,TMM4,TMM5,TMM6,TMM7] in
+ let hasSideEffects = 1,
+ Defs = [TMM0,TMM1,TMM2,TMM3,TMM4,TMM5,TMM6,TMM7] in
def LDTILECFG : I <0x49, MRM0m, (outs), (ins opaquemem:$src),
"ldtilecfg\t$src",
[(int_x86_ldtilecfg addr:$src)]>, VEX, T8PS;
- let hasSideEffects = 1 in
+ let hasSideEffects = 1 in
def STTILECFG : I <0x49, MRM0m, (outs), (ins opaquemem:$src),
"sttilecfg\t$src",
[(int_x86_sttilecfg addr:$src)]>, VEX, T8PD;
- let mayLoad = 1 in
+ let mayLoad = 1 in
def TILELOADD : I<0x4b, MRMSrcMemFSIB, (outs TILE:$dst),
(ins sibmem:$src),
"tileloadd\t{$src, $dst|$dst, $src}", []>,
VEX, T8XD;
- let mayLoad = 1 in
+ let mayLoad = 1 in
def TILELOADDT1 : I<0x4b, MRMSrcMemFSIB, (outs TILE:$dst),
(ins sibmem:$src),
"tileloaddt1\t{$src, $dst|$dst, $src}", []>,
@@ -38,7 +38,7 @@ let Predicates = [HasAMXTILE, In64BitMode] in {
let Defs = [TMM0,TMM1,TMM2,TMM3,TMM4,TMM5,TMM6,TMM7] in
def TILERELEASE : I<0x49, MRM_C0, (outs), (ins),
"tilerelease", [(int_x86_tilerelease)]>, VEX, T8PS;
- let mayStore = 1 in
+ let mayStore = 1 in
def TILESTORED : I<0x4b, MRMDestMemFSIB, (outs),
(ins sibmem:$dst, TILE:$src),
"tilestored\t{$src, $dst|$dst, $src}", []>,
@@ -47,25 +47,25 @@ let Predicates = [HasAMXTILE, In64BitMode] in {
"tilezero\t$dst", []>,
VEX, T8XD;
- // Pseduo instruction for RA.
- let hasSideEffects = 1, mayLoad = 1,
- Defs = [TMM0,TMM1,TMM2,TMM3,TMM4,TMM5,TMM6,TMM7] in
- def PLDTILECFG : PseudoI <(outs TILECFG:$cfg), (ins opaquemem:$src), []>;
-
- let hasSideEffects = 1, mayStore = 1 in
- def PSTTILECFG : PseudoI<(outs), (ins opaquemem:$dst, TILECFG:$cfg), []>;
-
- def PTILELOADDV : PseudoI<(outs TILE: $dst), (ins GR16:$src1,
- GR16:$src2,
- opaquemem:$src3,
- TILECFG:$cfg), []>;
- def PTILESTOREDV : PseudoI<(outs), (ins GR16:$src1,
- GR16:$src2, opaquemem:$src3,
- TILE:$src4, TILECFG:$cfg), []>;
- def PTILEZEROV : PseudoI<(outs TILE: $dst), (ins GR16:$src1,
- GR16:$src2,
- TILECFG:$cfg), []>;
-
+ // Pseduo instruction for RA.
+ let hasSideEffects = 1, mayLoad = 1,
+ Defs = [TMM0,TMM1,TMM2,TMM3,TMM4,TMM5,TMM6,TMM7] in
+ def PLDTILECFG : PseudoI <(outs TILECFG:$cfg), (ins opaquemem:$src), []>;
+
+ let hasSideEffects = 1, mayStore = 1 in
+ def PSTTILECFG : PseudoI<(outs), (ins opaquemem:$dst, TILECFG:$cfg), []>;
+
+ def PTILELOADDV : PseudoI<(outs TILE: $dst), (ins GR16:$src1,
+ GR16:$src2,
+ opaquemem:$src3,
+ TILECFG:$cfg), []>;
+ def PTILESTOREDV : PseudoI<(outs), (ins GR16:$src1,
+ GR16:$src2, opaquemem:$src3,
+ TILE:$src4, TILECFG:$cfg), []>;
+ def PTILEZEROV : PseudoI<(outs TILE: $dst), (ins GR16:$src1,
+ GR16:$src2,
+ TILECFG:$cfg), []>;
+
let usesCustomInserter = 1 in {
// Pseudo instructions, using immediates instead of tile registers.
// To be translated to the actual instructions in X86ISelLowering.cpp
@@ -74,7 +74,7 @@ let Predicates = [HasAMXTILE, In64BitMode] in {
sibmem:$src2), []>;
def PTILESTORED : PseudoI<(outs), (ins i8mem:$dst, u8imm:$src), []>;
def PTILEZERO : PseudoI<(outs), (ins u8imm:$src),
- [(int_x86_tilezero timm:$src)]>;
+ [(int_x86_tilezero timm:$src)]>;
}
} // SchedRW
} // HasAMXTILE
@@ -100,31 +100,31 @@ let Predicates = [HasAMXINT8, In64BitMode] in {
VEX_4V, T8PS;
}
- // Pseduo instruction for RA.
- let Constraints = "$src4 = $dst" in
- def PTDPBSSDV : PseudoI<(outs TILE: $dst), (ins GR16:$src1,
- GR16:$src2, GR16:$src3, TILE:$src4,
- TILE:$src5, TILE:$src6, TILECFG:$cfg), []>;
-
+ // Pseduo instruction for RA.
+ let Constraints = "$src4 = $dst" in
+ def PTDPBSSDV : PseudoI<(outs TILE: $dst), (ins GR16:$src1,
+ GR16:$src2, GR16:$src3, TILE:$src4,
+ TILE:$src5, TILE:$src6, TILECFG:$cfg), []>;
+
let usesCustomInserter = 1 in {
// Pseudo instructions, using immediates instead of tile registers.
// To be translated to the actual instructions in X86ISelLowering.cpp
def PTDPBSSD : PseudoI<(outs), (ins u8imm:$src1,
u8imm:$src2, u8imm:$src3),
- [(int_x86_tdpbssd timm:$src1,
- timm:$src2, timm:$src3)]>;
+ [(int_x86_tdpbssd timm:$src1,
+ timm:$src2, timm:$src3)]>;
def PTDPBSUD : PseudoI<(outs), (ins u8imm:$src1,
u8imm:$src2, u8imm:$src3),
- [(int_x86_tdpbsud timm:$src1,
- timm:$src2, timm:$src3)]>;
+ [(int_x86_tdpbsud timm:$src1,
+ timm:$src2, timm:$src3)]>;
def PTDPBUSD : PseudoI<(outs), (ins u8imm:$src1,
u8imm:$src2, u8imm:$src3),
- [(int_x86_tdpbusd timm:$src1,
- timm:$src2, timm:$src3)]>;
+ [(int_x86_tdpbusd timm:$src1,
+ timm:$src2, timm:$src3)]>;
def PTDPBUUD : PseudoI<(outs), (ins u8imm:$src1,
u8imm:$src2, u8imm:$src3),
- [(int_x86_tdpbuud timm:$src1,
- timm:$src2, timm:$src3)]>;
+ [(int_x86_tdpbuud timm:$src1,
+ timm:$src2, timm:$src3)]>;
}
}
} // HasAMXTILE
@@ -142,8 +142,8 @@ let Predicates = [HasAMXBF16, In64BitMode] in {
// To be translated to the actual instructions in X86ISelLowering.cpp
def PTDPBF16PS : PseudoI<(outs), (ins u8imm:$src1,
u8imm:$src2, u8imm:$src3),
- [(int_x86_tdpbf16ps timm:$src1,
- timm:$src2, timm:$src3)]>;
+ [(int_x86_tdpbf16ps timm:$src1,
+ timm:$src2, timm:$src3)]>;
}
}
} // HasAMXTILE, HasAMXBF16
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td b/contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td
index 654dcc1b39..19012797ae 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrAVX512.td
@@ -1123,10 +1123,10 @@ defm : vextract_for_mask_cast<"VEXTRACTI64x4Z", v64i8_info, v32i8x_info,
EXTRACT_get_vextract256_imm, [HasAVX512]>;
// vextractps - extract 32 bits from XMM
-def VEXTRACTPSZrr : AVX512AIi8<0x17, MRMDestReg, (outs GR32orGR64:$dst),
+def VEXTRACTPSZrr : AVX512AIi8<0x17, MRMDestReg, (outs GR32orGR64:$dst),
(ins VR128X:$src1, u8imm:$src2),
"vextractps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
- [(set GR32orGR64:$dst, (extractelt (bc_v4i32 (v4f32 VR128X:$src1)), imm:$src2))]>,
+ [(set GR32orGR64:$dst, (extractelt (bc_v4i32 (v4f32 VR128X:$src1)), imm:$src2))]>,
EVEX, VEX_WIG, Sched<[WriteVecExtract]>;
def VEXTRACTPSZmr : AVX512AIi8<0x17, MRMDestMem, (outs),
@@ -1414,12 +1414,12 @@ defm VPBROADCASTQ : avx512_int_broadcast_rm_vl<0x59, "vpbroadcastq",
avx512vl_i64_info, HasAVX512, 1>, VEX_W1X;
multiclass avx512_subvec_broadcast_rm<bits<8> opc, string OpcodeStr,
- SDPatternOperator OpNode,
- X86VectorVTInfo _Dst,
- X86VectorVTInfo _Src> {
+ SDPatternOperator OpNode,
+ X86VectorVTInfo _Dst,
+ X86VectorVTInfo _Src> {
defm rm : AVX512_maskable<opc, MRMSrcMem, _Dst, (outs _Dst.RC:$dst),
(ins _Src.MemOp:$src), OpcodeStr, "$src", "$src",
- (_Dst.VT (OpNode addr:$src))>,
+ (_Dst.VT (OpNode addr:$src))>,
Sched<[SchedWriteShuffle.YMM.Folded]>,
AVX5128IBase, EVEX;
}
@@ -1428,14 +1428,14 @@ multiclass avx512_subvec_broadcast_rm<bits<8> opc, string OpcodeStr,
// the unmasked patterns so that we only use the DQ instructions when masking
// is requested.
multiclass avx512_subvec_broadcast_rm_dq<bits<8> opc, string OpcodeStr,
- SDPatternOperator OpNode,
- X86VectorVTInfo _Dst,
- X86VectorVTInfo _Src> {
+ SDPatternOperator OpNode,
+ X86VectorVTInfo _Dst,
+ X86VectorVTInfo _Src> {
let hasSideEffects = 0, mayLoad = 1 in
defm rm : AVX512_maskable_split<opc, MRMSrcMem, _Dst, (outs _Dst.RC:$dst),
(ins _Src.MemOp:$src), OpcodeStr, "$src", "$src",
(null_frag),
- (_Dst.VT (OpNode addr:$src))>,
+ (_Dst.VT (OpNode addr:$src))>,
Sched<[SchedWriteShuffle.YMM.Folded]>,
AVX5128IBase, EVEX;
}
@@ -1445,194 +1445,194 @@ multiclass avx512_subvec_broadcast_rm_dq<bits<8> opc, string OpcodeStr,
//
defm VBROADCASTI32X4 : avx512_subvec_broadcast_rm<0x5a, "vbroadcasti32x4",
- X86SubVBroadcastld128, v16i32_info, v4i32x_info>,
+ X86SubVBroadcastld128, v16i32_info, v4i32x_info>,
EVEX_V512, EVEX_CD8<32, CD8VT4>;
defm VBROADCASTF32X4 : avx512_subvec_broadcast_rm<0x1a, "vbroadcastf32x4",
- X86SubVBroadcastld128, v16f32_info, v4f32x_info>,
+ X86SubVBroadcastld128, v16f32_info, v4f32x_info>,
EVEX_V512, EVEX_CD8<32, CD8VT4>;
defm VBROADCASTI64X4 : avx512_subvec_broadcast_rm<0x5b, "vbroadcasti64x4",
- X86SubVBroadcastld256, v8i64_info, v4i64x_info>, VEX_W,
+ X86SubVBroadcastld256, v8i64_info, v4i64x_info>, VEX_W,
EVEX_V512, EVEX_CD8<64, CD8VT4>;
defm VBROADCASTF64X4 : avx512_subvec_broadcast_rm<0x1b, "vbroadcastf64x4",
- X86SubVBroadcastld256, v8f64_info, v4f64x_info>, VEX_W,
+ X86SubVBroadcastld256, v8f64_info, v4f64x_info>, VEX_W,
EVEX_V512, EVEX_CD8<64, CD8VT4>;
let Predicates = [HasAVX512] in {
-def : Pat<(v8f64 (X86SubVBroadcastld256 addr:$src)),
+def : Pat<(v8f64 (X86SubVBroadcastld256 addr:$src)),
(VBROADCASTF64X4rm addr:$src)>;
-def : Pat<(v16f32 (X86SubVBroadcastld256 addr:$src)),
- (VBROADCASTF64X4rm addr:$src)>;
-def : Pat<(v8i64 (X86SubVBroadcastld256 addr:$src)),
+def : Pat<(v16f32 (X86SubVBroadcastld256 addr:$src)),
+ (VBROADCASTF64X4rm addr:$src)>;
+def : Pat<(v8i64 (X86SubVBroadcastld256 addr:$src)),
+ (VBROADCASTI64X4rm addr:$src)>;
+def : Pat<(v16i32 (X86SubVBroadcastld256 addr:$src)),
(VBROADCASTI64X4rm addr:$src)>;
-def : Pat<(v16i32 (X86SubVBroadcastld256 addr:$src)),
+def : Pat<(v32i16 (X86SubVBroadcastld256 addr:$src)),
(VBROADCASTI64X4rm addr:$src)>;
-def : Pat<(v32i16 (X86SubVBroadcastld256 addr:$src)),
+def : Pat<(v64i8 (X86SubVBroadcastld256 addr:$src)),
(VBROADCASTI64X4rm addr:$src)>;
-def : Pat<(v64i8 (X86SubVBroadcastld256 addr:$src)),
- (VBROADCASTI64X4rm addr:$src)>;
-def : Pat<(v8f64 (X86SubVBroadcastld128 addr:$src)),
+def : Pat<(v8f64 (X86SubVBroadcastld128 addr:$src)),
(VBROADCASTF32X4rm addr:$src)>;
-def : Pat<(v16f32 (X86SubVBroadcastld128 addr:$src)),
- (VBROADCASTF32X4rm addr:$src)>;
-def : Pat<(v8i64 (X86SubVBroadcastld128 addr:$src)),
+def : Pat<(v16f32 (X86SubVBroadcastld128 addr:$src)),
+ (VBROADCASTF32X4rm addr:$src)>;
+def : Pat<(v8i64 (X86SubVBroadcastld128 addr:$src)),
+ (VBROADCASTI32X4rm addr:$src)>;
+def : Pat<(v16i32 (X86SubVBroadcastld128 addr:$src)),
(VBROADCASTI32X4rm addr:$src)>;
-def : Pat<(v16i32 (X86SubVBroadcastld128 addr:$src)),
+def : Pat<(v32i16 (X86SubVBroadcastld128 addr:$src)),
(VBROADCASTI32X4rm addr:$src)>;
-def : Pat<(v32i16 (X86SubVBroadcastld128 addr:$src)),
+def : Pat<(v64i8 (X86SubVBroadcastld128 addr:$src)),
(VBROADCASTI32X4rm addr:$src)>;
-def : Pat<(v64i8 (X86SubVBroadcastld128 addr:$src)),
- (VBROADCASTI32X4rm addr:$src)>;
// Patterns for selects of bitcasted operations.
def : Pat<(vselect_mask VK16WM:$mask,
- (bc_v16f32 (v8f64 (X86SubVBroadcastld128 addr:$src))),
+ (bc_v16f32 (v8f64 (X86SubVBroadcastld128 addr:$src))),
(v16f32 immAllZerosV)),
(VBROADCASTF32X4rmkz VK16WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK16WM:$mask,
- (bc_v16f32 (v8f64 (X86SubVBroadcastld128 addr:$src))),
+ (bc_v16f32 (v8f64 (X86SubVBroadcastld128 addr:$src))),
VR512:$src0),
(VBROADCASTF32X4rmk VR512:$src0, VK16WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK16WM:$mask,
- (bc_v16i32 (v8i64 (X86SubVBroadcastld128 addr:$src))),
+ (bc_v16i32 (v8i64 (X86SubVBroadcastld128 addr:$src))),
(v16i32 immAllZerosV)),
(VBROADCASTI32X4rmkz VK16WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK16WM:$mask,
- (bc_v16i32 (v8i64 (X86SubVBroadcastld128 addr:$src))),
+ (bc_v16i32 (v8i64 (X86SubVBroadcastld128 addr:$src))),
VR512:$src0),
(VBROADCASTI32X4rmk VR512:$src0, VK16WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK8WM:$mask,
- (bc_v8f64 (v16f32 (X86SubVBroadcastld256 addr:$src))),
+ (bc_v8f64 (v16f32 (X86SubVBroadcastld256 addr:$src))),
(v8f64 immAllZerosV)),
(VBROADCASTF64X4rmkz VK8WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK8WM:$mask,
- (bc_v8f64 (v16f32 (X86SubVBroadcastld256 addr:$src))),
+ (bc_v8f64 (v16f32 (X86SubVBroadcastld256 addr:$src))),
VR512:$src0),
(VBROADCASTF64X4rmk VR512:$src0, VK8WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK8WM:$mask,
- (bc_v8i64 (v16i32 (X86SubVBroadcastld256 addr:$src))),
+ (bc_v8i64 (v16i32 (X86SubVBroadcastld256 addr:$src))),
(v8i64 immAllZerosV)),
(VBROADCASTI64X4rmkz VK8WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK8WM:$mask,
- (bc_v8i64 (v16i32 (X86SubVBroadcastld256 addr:$src))),
+ (bc_v8i64 (v16i32 (X86SubVBroadcastld256 addr:$src))),
VR512:$src0),
(VBROADCASTI64X4rmk VR512:$src0, VK8WM:$mask, addr:$src)>;
}
let Predicates = [HasVLX] in {
defm VBROADCASTI32X4Z256 : avx512_subvec_broadcast_rm<0x5a, "vbroadcasti32x4",
- X86SubVBroadcastld128, v8i32x_info, v4i32x_info>,
+ X86SubVBroadcastld128, v8i32x_info, v4i32x_info>,
EVEX_V256, EVEX_CD8<32, CD8VT4>;
defm VBROADCASTF32X4Z256 : avx512_subvec_broadcast_rm<0x1a, "vbroadcastf32x4",
- X86SubVBroadcastld128, v8f32x_info, v4f32x_info>,
+ X86SubVBroadcastld128, v8f32x_info, v4f32x_info>,
EVEX_V256, EVEX_CD8<32, CD8VT4>;
-def : Pat<(v4f64 (X86SubVBroadcastld128 addr:$src)),
+def : Pat<(v4f64 (X86SubVBroadcastld128 addr:$src)),
(VBROADCASTF32X4Z256rm addr:$src)>;
-def : Pat<(v8f32 (X86SubVBroadcastld128 addr:$src)),
- (VBROADCASTF32X4Z256rm addr:$src)>;
-def : Pat<(v4i64 (X86SubVBroadcastld128 addr:$src)),
+def : Pat<(v8f32 (X86SubVBroadcastld128 addr:$src)),
+ (VBROADCASTF32X4Z256rm addr:$src)>;
+def : Pat<(v4i64 (X86SubVBroadcastld128 addr:$src)),
+ (VBROADCASTI32X4Z256rm addr:$src)>;
+def : Pat<(v8i32 (X86SubVBroadcastld128 addr:$src)),
(VBROADCASTI32X4Z256rm addr:$src)>;
-def : Pat<(v8i32 (X86SubVBroadcastld128 addr:$src)),
+def : Pat<(v16i16 (X86SubVBroadcastld128 addr:$src)),
(VBROADCASTI32X4Z256rm addr:$src)>;
-def : Pat<(v16i16 (X86SubVBroadcastld128 addr:$src)),
+def : Pat<(v32i8 (X86SubVBroadcastld128 addr:$src)),
(VBROADCASTI32X4Z256rm addr:$src)>;
-def : Pat<(v32i8 (X86SubVBroadcastld128 addr:$src)),
- (VBROADCASTI32X4Z256rm addr:$src)>;
// Patterns for selects of bitcasted operations.
def : Pat<(vselect_mask VK8WM:$mask,
- (bc_v8f32 (v4f64 (X86SubVBroadcastld128 addr:$src))),
+ (bc_v8f32 (v4f64 (X86SubVBroadcastld128 addr:$src))),
(v8f32 immAllZerosV)),
(VBROADCASTF32X4Z256rmkz VK8WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK8WM:$mask,
- (bc_v8f32 (v4f64 (X86SubVBroadcastld128 addr:$src))),
+ (bc_v8f32 (v4f64 (X86SubVBroadcastld128 addr:$src))),
VR256X:$src0),
(VBROADCASTF32X4Z256rmk VR256X:$src0, VK8WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK8WM:$mask,
- (bc_v8i32 (v4i64 (X86SubVBroadcastld128 addr:$src))),
+ (bc_v8i32 (v4i64 (X86SubVBroadcastld128 addr:$src))),
(v8i32 immAllZerosV)),
(VBROADCASTI32X4Z256rmkz VK8WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK8WM:$mask,
- (bc_v8i32 (v4i64 (X86SubVBroadcastld128 addr:$src))),
+ (bc_v8i32 (v4i64 (X86SubVBroadcastld128 addr:$src))),
VR256X:$src0),
(VBROADCASTI32X4Z256rmk VR256X:$src0, VK8WM:$mask, addr:$src)>;
}
let Predicates = [HasVLX, HasDQI] in {
defm VBROADCASTI64X2Z128 : avx512_subvec_broadcast_rm_dq<0x5a, "vbroadcasti64x2",
- X86SubVBroadcastld128, v4i64x_info, v2i64x_info>, VEX_W1X,
+ X86SubVBroadcastld128, v4i64x_info, v2i64x_info>, VEX_W1X,
EVEX_V256, EVEX_CD8<64, CD8VT2>;
defm VBROADCASTF64X2Z128 : avx512_subvec_broadcast_rm_dq<0x1a, "vbroadcastf64x2",
- X86SubVBroadcastld128, v4f64x_info, v2f64x_info>, VEX_W1X,
+ X86SubVBroadcastld128, v4f64x_info, v2f64x_info>, VEX_W1X,
EVEX_V256, EVEX_CD8<64, CD8VT2>;
// Patterns for selects of bitcasted operations.
def : Pat<(vselect_mask VK4WM:$mask,
- (bc_v4f64 (v8f32 (X86SubVBroadcastld128 addr:$src))),
+ (bc_v4f64 (v8f32 (X86SubVBroadcastld128 addr:$src))),
(v4f64 immAllZerosV)),
(VBROADCASTF64X2Z128rmkz VK4WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK4WM:$mask,
- (bc_v4f64 (v8f32 (X86SubVBroadcastld128 addr:$src))),
+ (bc_v4f64 (v8f32 (X86SubVBroadcastld128 addr:$src))),
VR256X:$src0),
(VBROADCASTF64X2Z128rmk VR256X:$src0, VK4WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK4WM:$mask,
- (bc_v4i64 (v8i32 (X86SubVBroadcastld128 addr:$src))),
+ (bc_v4i64 (v8i32 (X86SubVBroadcastld128 addr:$src))),
(v4i64 immAllZerosV)),
(VBROADCASTI64X2Z128rmkz VK4WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK4WM:$mask,
- (bc_v4i64 (v8i32 (X86SubVBroadcastld128 addr:$src))),
+ (bc_v4i64 (v8i32 (X86SubVBroadcastld128 addr:$src))),
VR256X:$src0),
(VBROADCASTI64X2Z128rmk VR256X:$src0, VK4WM:$mask, addr:$src)>;
}
let Predicates = [HasDQI] in {
defm VBROADCASTI64X2 : avx512_subvec_broadcast_rm_dq<0x5a, "vbroadcasti64x2",
- X86SubVBroadcastld128, v8i64_info, v2i64x_info>, VEX_W,
+ X86SubVBroadcastld128, v8i64_info, v2i64x_info>, VEX_W,
EVEX_V512, EVEX_CD8<64, CD8VT2>;
defm VBROADCASTI32X8 : avx512_subvec_broadcast_rm_dq<0x5b, "vbroadcasti32x8",
- X86SubVBroadcastld256, v16i32_info, v8i32x_info>,
+ X86SubVBroadcastld256, v16i32_info, v8i32x_info>,
EVEX_V512, EVEX_CD8<32, CD8VT8>;
defm VBROADCASTF64X2 : avx512_subvec_broadcast_rm_dq<0x1a, "vbroadcastf64x2",
- X86SubVBroadcastld128, v8f64_info, v2f64x_info>, VEX_W,
+ X86SubVBroadcastld128, v8f64_info, v2f64x_info>, VEX_W,
EVEX_V512, EVEX_CD8<64, CD8VT2>;
defm VBROADCASTF32X8 : avx512_subvec_broadcast_rm_dq<0x1b, "vbroadcastf32x8",
- X86SubVBroadcastld256, v16f32_info, v8f32x_info>,
+ X86SubVBroadcastld256, v16f32_info, v8f32x_info>,
EVEX_V512, EVEX_CD8<32, CD8VT8>;
// Patterns for selects of bitcasted operations.
def : Pat<(vselect_mask VK16WM:$mask,
- (bc_v16f32 (v8f64 (X86SubVBroadcastld256 addr:$src))),
+ (bc_v16f32 (v8f64 (X86SubVBroadcastld256 addr:$src))),
(v16f32 immAllZerosV)),
(VBROADCASTF32X8rmkz VK16WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK16WM:$mask,
- (bc_v16f32 (v8f64 (X86SubVBroadcastld256 addr:$src))),
+ (bc_v16f32 (v8f64 (X86SubVBroadcastld256 addr:$src))),
VR512:$src0),
(VBROADCASTF32X8rmk VR512:$src0, VK16WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK16WM:$mask,
- (bc_v16i32 (v8i64 (X86SubVBroadcastld256 addr:$src))),
+ (bc_v16i32 (v8i64 (X86SubVBroadcastld256 addr:$src))),
(v16i32 immAllZerosV)),
(VBROADCASTI32X8rmkz VK16WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK16WM:$mask,
- (bc_v16i32 (v8i64 (X86SubVBroadcastld256 addr:$src))),
+ (bc_v16i32 (v8i64 (X86SubVBroadcastld256 addr:$src))),
VR512:$src0),
(VBROADCASTI32X8rmk VR512:$src0, VK16WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK8WM:$mask,
- (bc_v8f64 (v16f32 (X86SubVBroadcastld128 addr:$src))),
+ (bc_v8f64 (v16f32 (X86SubVBroadcastld128 addr:$src))),
(v8f64 immAllZerosV)),
(VBROADCASTF64X2rmkz VK8WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK8WM:$mask,
- (bc_v8f64 (v16f32 (X86SubVBroadcastld128 addr:$src))),
+ (bc_v8f64 (v16f32 (X86SubVBroadcastld128 addr:$src))),
VR512:$src0),
(VBROADCASTF64X2rmk VR512:$src0, VK8WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK8WM:$mask,
- (bc_v8i64 (v16i32 (X86SubVBroadcastld128 addr:$src))),
+ (bc_v8i64 (v16i32 (X86SubVBroadcastld128 addr:$src))),
(v8i64 immAllZerosV)),
(VBROADCASTI64X2rmkz VK8WM:$mask, addr:$src)>;
def : Pat<(vselect_mask VK8WM:$mask,
- (bc_v8i64 (v16i32 (X86SubVBroadcastld128 addr:$src))),
+ (bc_v8i64 (v16i32 (X86SubVBroadcastld128 addr:$src))),
VR512:$src0),
(VBROADCASTI64X2rmk VR512:$src0, VK8WM:$mask, addr:$src)>;
}
@@ -2531,71 +2531,71 @@ let Uses = [MXCSR], mayRaiseFPException = 1 in {
(!cast<Instruction>(Name#_.ZSuffix#"rmbik") _.KRCWM:$mask,
_.RC:$src1, addr:$src2,
(X86cmpm_imm_commute timm:$cc))>;
-
- // Patterns for mask intrinsics.
- def : Pat<(X86cmpmm (_.VT _.RC:$src1), (_.VT _.RC:$src2), timm:$cc,
- (_.KVT immAllOnesV)),
- (!cast<Instruction>(Name#_.ZSuffix#"rri") _.RC:$src1, _.RC:$src2, timm:$cc)>;
-
- def : Pat<(X86cmpmm (_.VT _.RC:$src1), (_.VT _.RC:$src2), timm:$cc, _.KRCWM:$mask),
- (!cast<Instruction>(Name#_.ZSuffix#"rrik") _.KRCWM:$mask, _.RC:$src1,
- _.RC:$src2, timm:$cc)>;
-
- def : Pat<(X86cmpmm (_.VT _.RC:$src1), (_.VT (_.LdFrag addr:$src2)), timm:$cc,
- (_.KVT immAllOnesV)),
- (!cast<Instruction>(Name#_.ZSuffix#"rmi") _.RC:$src1, addr:$src2, timm:$cc)>;
-
- def : Pat<(X86cmpmm (_.VT _.RC:$src1), (_.VT (_.LdFrag addr:$src2)), timm:$cc,
- _.KRCWM:$mask),
- (!cast<Instruction>(Name#_.ZSuffix#"rmik") _.KRCWM:$mask, _.RC:$src1,
- addr:$src2, timm:$cc)>;
-
- def : Pat<(X86cmpmm (_.VT _.RC:$src1), (_.VT (_.BroadcastLdFrag addr:$src2)), timm:$cc,
- (_.KVT immAllOnesV)),
- (!cast<Instruction>(Name#_.ZSuffix#"rmbi") _.RC:$src1, addr:$src2, timm:$cc)>;
-
- def : Pat<(X86cmpmm (_.VT _.RC:$src1), (_.VT (_.BroadcastLdFrag addr:$src2)), timm:$cc,
- _.KRCWM:$mask),
- (!cast<Instruction>(Name#_.ZSuffix#"rmbik") _.KRCWM:$mask, _.RC:$src1,
- addr:$src2, timm:$cc)>;
-
- // Patterns for mask intrinsics with loads in other operand.
- def : Pat<(X86cmpmm (_.VT (_.LdFrag addr:$src2)), (_.VT _.RC:$src1), timm:$cc,
- (_.KVT immAllOnesV)),
- (!cast<Instruction>(Name#_.ZSuffix#"rmi") _.RC:$src1, addr:$src2,
- (X86cmpm_imm_commute timm:$cc))>;
-
- def : Pat<(X86cmpmm (_.VT (_.LdFrag addr:$src2)), (_.VT _.RC:$src1), timm:$cc,
- _.KRCWM:$mask),
- (!cast<Instruction>(Name#_.ZSuffix#"rmik") _.KRCWM:$mask,
- _.RC:$src1, addr:$src2,
- (X86cmpm_imm_commute timm:$cc))>;
-
- def : Pat<(X86cmpmm (_.VT (_.BroadcastLdFrag addr:$src2)), (_.VT _.RC:$src1), timm:$cc,
- (_.KVT immAllOnesV)),
- (!cast<Instruction>(Name#_.ZSuffix#"rmbi") _.RC:$src1, addr:$src2,
- (X86cmpm_imm_commute timm:$cc))>;
-
- def : Pat<(X86cmpmm (_.VT (_.BroadcastLdFrag addr:$src2)), (_.VT _.RC:$src1), timm:$cc,
- _.KRCWM:$mask),
- (!cast<Instruction>(Name#_.ZSuffix#"rmbik") _.KRCWM:$mask,
- _.RC:$src1, addr:$src2,
- (X86cmpm_imm_commute timm:$cc))>;
+
+ // Patterns for mask intrinsics.
+ def : Pat<(X86cmpmm (_.VT _.RC:$src1), (_.VT _.RC:$src2), timm:$cc,
+ (_.KVT immAllOnesV)),
+ (!cast<Instruction>(Name#_.ZSuffix#"rri") _.RC:$src1, _.RC:$src2, timm:$cc)>;
+
+ def : Pat<(X86cmpmm (_.VT _.RC:$src1), (_.VT _.RC:$src2), timm:$cc, _.KRCWM:$mask),
+ (!cast<Instruction>(Name#_.ZSuffix#"rrik") _.KRCWM:$mask, _.RC:$src1,
+ _.RC:$src2, timm:$cc)>;
+
+ def : Pat<(X86cmpmm (_.VT _.RC:$src1), (_.VT (_.LdFrag addr:$src2)), timm:$cc,
+ (_.KVT immAllOnesV)),
+ (!cast<Instruction>(Name#_.ZSuffix#"rmi") _.RC:$src1, addr:$src2, timm:$cc)>;
+
+ def : Pat<(X86cmpmm (_.VT _.RC:$src1), (_.VT (_.LdFrag addr:$src2)), timm:$cc,
+ _.KRCWM:$mask),
+ (!cast<Instruction>(Name#_.ZSuffix#"rmik") _.KRCWM:$mask, _.RC:$src1,
+ addr:$src2, timm:$cc)>;
+
+ def : Pat<(X86cmpmm (_.VT _.RC:$src1), (_.VT (_.BroadcastLdFrag addr:$src2)), timm:$cc,
+ (_.KVT immAllOnesV)),
+ (!cast<Instruction>(Name#_.ZSuffix#"rmbi") _.RC:$src1, addr:$src2, timm:$cc)>;
+
+ def : Pat<(X86cmpmm (_.VT _.RC:$src1), (_.VT (_.BroadcastLdFrag addr:$src2)), timm:$cc,
+ _.KRCWM:$mask),
+ (!cast<Instruction>(Name#_.ZSuffix#"rmbik") _.KRCWM:$mask, _.RC:$src1,
+ addr:$src2, timm:$cc)>;
+
+ // Patterns for mask intrinsics with loads in other operand.
+ def : Pat<(X86cmpmm (_.VT (_.LdFrag addr:$src2)), (_.VT _.RC:$src1), timm:$cc,
+ (_.KVT immAllOnesV)),
+ (!cast<Instruction>(Name#_.ZSuffix#"rmi") _.RC:$src1, addr:$src2,
+ (X86cmpm_imm_commute timm:$cc))>;
+
+ def : Pat<(X86cmpmm (_.VT (_.LdFrag addr:$src2)), (_.VT _.RC:$src1), timm:$cc,
+ _.KRCWM:$mask),
+ (!cast<Instruction>(Name#_.ZSuffix#"rmik") _.KRCWM:$mask,
+ _.RC:$src1, addr:$src2,
+ (X86cmpm_imm_commute timm:$cc))>;
+
+ def : Pat<(X86cmpmm (_.VT (_.BroadcastLdFrag addr:$src2)), (_.VT _.RC:$src1), timm:$cc,
+ (_.KVT immAllOnesV)),
+ (!cast<Instruction>(Name#_.ZSuffix#"rmbi") _.RC:$src1, addr:$src2,
+ (X86cmpm_imm_commute timm:$cc))>;
+
+ def : Pat<(X86cmpmm (_.VT (_.BroadcastLdFrag addr:$src2)), (_.VT _.RC:$src1), timm:$cc,
+ _.KRCWM:$mask),
+ (!cast<Instruction>(Name#_.ZSuffix#"rmbik") _.KRCWM:$mask,
+ _.RC:$src1, addr:$src2,
+ (X86cmpm_imm_commute timm:$cc))>;
}
multiclass avx512_vcmp_sae<X86FoldableSchedWrite sched, X86VectorVTInfo _> {
// comparison code form (VCMP[EQ/LT/LE/...]
let Uses = [MXCSR] in
- defm rrib : AVX512_maskable_custom_cmp<0xC2, MRMSrcReg, (outs _.KRC:$dst),
- (ins _.RC:$src1, _.RC:$src2, u8imm:$cc),
- (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2, u8imm:$cc),
+ defm rrib : AVX512_maskable_custom_cmp<0xC2, MRMSrcReg, (outs _.KRC:$dst),
+ (ins _.RC:$src1, _.RC:$src2, u8imm:$cc),
+ (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2, u8imm:$cc),
"vcmp"#_.Suffix,
"$cc, {sae}, $src2, $src1",
"$src1, $src2, {sae}, $cc",
- [(set _.KRC:$dst, (X86cmpmmSAE (_.VT _.RC:$src1),
- (_.VT _.RC:$src2), timm:$cc, (_.KVT immAllOnesV)))],
- [(set _.KRC:$dst, (X86cmpmmSAE (_.VT _.RC:$src1),
- (_.VT _.RC:$src2), timm:$cc, _.KRCWM:$mask))]>,
+ [(set _.KRC:$dst, (X86cmpmmSAE (_.VT _.RC:$src1),
+ (_.VT _.RC:$src2), timm:$cc, (_.KVT immAllOnesV)))],
+ [(set _.KRC:$dst, (X86cmpmmSAE (_.VT _.RC:$src1),
+ (_.VT _.RC:$src2), timm:$cc, _.KRCWM:$mask))]>,
EVEX_B, Sched<[sched]>;
}
@@ -2855,8 +2855,8 @@ def : Pat<(v16i1 (bitconvert (i16 GR16:$src))),
(COPY_TO_REGCLASS (i32 (INSERT_SUBREG (IMPLICIT_DEF), GR16:$src, sub_16bit)), VK16)>;
def : Pat<(i16 (bitconvert (v16i1 VK16:$src))),
(EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS VK16:$src, GR32)), sub_16bit)>;
-def : Pat<(i8 (trunc (i16 (bitconvert (v16i1 VK16:$src))))),
- (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS VK16:$src, GR32)), sub_8bit)>;
+def : Pat<(i8 (trunc (i16 (bitconvert (v16i1 VK16:$src))))),
+ (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS VK16:$src, GR32)), sub_8bit)>;
def : Pat<(v8i1 (bitconvert (i8 GR8:$src))),
(COPY_TO_REGCLASS (i32 (INSERT_SUBREG (IMPLICIT_DEF), GR8:$src, sub_8bit)), VK8)>;
@@ -2937,9 +2937,9 @@ let Predicates = [HasAVX512] in {
def : Pat<(insert_subvector (v16i1 immAllZerosV),
(v1i1 (scalar_to_vector GR8:$src)), (iPTR 0)),
- (KMOVWkr (AND32ri8
- (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src, sub_8bit),
- (i32 1)))>;
+ (KMOVWkr (AND32ri8
+ (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src, sub_8bit),
+ (i32 1)))>;
}
// Mask unary operation
@@ -6504,8 +6504,8 @@ multiclass avx512_fma3p_213_f<bits<8> opc, string OpcodeStr, SDNode OpNode,
avx512vl_f64_info, "PD">, VEX_W;
}
-defm VFMADD213 : avx512_fma3p_213_f<0xA8, "vfmadd213", any_fma,
- fma, X86FmaddRnd>;
+defm VFMADD213 : avx512_fma3p_213_f<0xA8, "vfmadd213", any_fma,
+ fma, X86FmaddRnd>;
defm VFMSUB213 : avx512_fma3p_213_f<0xAA, "vfmsub213", X86any_Fmsub,
X86Fmsub, X86FmsubRnd>;
defm VFMADDSUB213 : avx512_fma3p_213_f<0xA6, "vfmaddsub213", X86Fmaddsub,
@@ -6595,8 +6595,8 @@ multiclass avx512_fma3p_231_f<bits<8> opc, string OpcodeStr, SDNode OpNode,
avx512vl_f64_info, "PD">, VEX_W;
}
-defm VFMADD231 : avx512_fma3p_231_f<0xB8, "vfmadd231", any_fma,
- fma, X86FmaddRnd>;
+defm VFMADD231 : avx512_fma3p_231_f<0xB8, "vfmadd231", any_fma,
+ fma, X86FmaddRnd>;
defm VFMSUB231 : avx512_fma3p_231_f<0xBA, "vfmsub231", X86any_Fmsub,
X86Fmsub, X86FmsubRnd>;
defm VFMADDSUB231 : avx512_fma3p_231_f<0xB6, "vfmaddsub231", X86Fmaddsub,
@@ -6687,8 +6687,8 @@ multiclass avx512_fma3p_132_f<bits<8> opc, string OpcodeStr, SDNode OpNode,
avx512vl_f64_info, "PD">, VEX_W;
}
-defm VFMADD132 : avx512_fma3p_132_f<0x98, "vfmadd132", any_fma,
- fma, X86FmaddRnd>;
+defm VFMADD132 : avx512_fma3p_132_f<0x98, "vfmadd132", any_fma,
+ fma, X86FmaddRnd>;
defm VFMSUB132 : avx512_fma3p_132_f<0x9A, "vfmsub132", X86any_Fmsub,
X86Fmsub, X86FmsubRnd>;
defm VFMADDSUB132 : avx512_fma3p_132_f<0x96, "vfmaddsub132", X86Fmaddsub,
@@ -6790,7 +6790,7 @@ multiclass avx512_fma3s<bits<8> opc213, bits<8> opc231, bits<8> opc132,
}
}
-defm VFMADD : avx512_fma3s<0xA9, 0xB9, 0x99, "vfmadd", any_fma, X86FmaddRnd>;
+defm VFMADD : avx512_fma3s<0xA9, 0xB9, 0x99, "vfmadd", any_fma, X86FmaddRnd>;
defm VFMSUB : avx512_fma3s<0xAB, 0xBB, 0x9B, "vfmsub", X86any_Fmsub, X86FmsubRnd>;
defm VFNMADD : avx512_fma3s<0xAD, 0xBD, 0x9D, "vfnmadd", X86any_Fnmadd, X86FnmaddRnd>;
defm VFNMSUB : avx512_fma3s<0xAF, 0xBF, 0x9F, "vfnmsub", X86any_Fnmsub, X86FnmsubRnd>;
@@ -6998,7 +6998,7 @@ multiclass avx512_scalar_fma_patterns<SDNode Op, SDNode MaskedOp,
}
}
-defm : avx512_scalar_fma_patterns<any_fma, fma, X86FmaddRnd, "VFMADD",
+defm : avx512_scalar_fma_patterns<any_fma, fma, X86FmaddRnd, "VFMADD",
"SS", X86Movss, v4f32x_info, fp32imm0>;
defm : avx512_scalar_fma_patterns<X86any_Fmsub, X86Fmsub, X86FmsubRnd, "VFMSUB",
"SS", X86Movss, v4f32x_info, fp32imm0>;
@@ -7007,7 +7007,7 @@ defm : avx512_scalar_fma_patterns<X86any_Fnmadd, X86Fnmadd, X86FnmaddRnd, "VFNMA
defm : avx512_scalar_fma_patterns<X86any_Fnmsub, X86Fnmsub, X86FnmsubRnd, "VFNMSUB",
"SS", X86Movss, v4f32x_info, fp32imm0>;
-defm : avx512_scalar_fma_patterns<any_fma, fma, X86FmaddRnd, "VFMADD",
+defm : avx512_scalar_fma_patterns<any_fma, fma, X86FmaddRnd, "VFMADD",
"SD", X86Movsd, v2f64x_info, fp64imm0>;
defm : avx512_scalar_fma_patterns<X86any_Fmsub, X86Fmsub, X86FmsubRnd, "VFMSUB",
"SD", X86Movsd, v2f64x_info, fp64imm0>;
@@ -7540,7 +7540,7 @@ multiclass avx512_cvt_fp_scalar_sd2ss<bits<8> opc, string OpcodeStr,
SDNode OpNode, SDNode OpNodeRnd,
X86FoldableSchedWrite sched,
X86VectorVTInfo _src, X86VectorVTInfo _dst> {
- let Predicates = [HasAVX512], ExeDomain = SSEPackedSingle in {
+ let Predicates = [HasAVX512], ExeDomain = SSEPackedSingle in {
defm Z : avx512_cvt_fp_scalar<opc, OpcodeStr, _dst, _src, OpNode, sched>,
avx512_cvt_fp_rc_scalar<opc, OpcodeStr, _dst, _src,
OpNodeRnd, sched>, VEX_W, EVEX_CD8<64, CD8VT1>, XD;
@@ -7551,7 +7551,7 @@ multiclass avx512_cvt_fp_scalar_ss2sd<bits<8> opc, string OpcodeStr,
SDNode OpNode, SDNode OpNodeSAE,
X86FoldableSchedWrite sched,
X86VectorVTInfo _src, X86VectorVTInfo _dst> {
- let Predicates = [HasAVX512], ExeDomain = SSEPackedSingle in {
+ let Predicates = [HasAVX512], ExeDomain = SSEPackedSingle in {
defm Z : avx512_cvt_fp_scalar<opc, OpcodeStr, _dst, _src, OpNode, sched>,
avx512_cvt_fp_sae_scalar<opc, OpcodeStr, _dst, _src, OpNodeSAE, sched>,
EVEX_CD8<32, CD8VT1>, XS;
@@ -10879,7 +10879,7 @@ multiclass avx512_extract_elt_bw_m<bits<8> opc, string OpcodeStr, SDNode OpNode,
def mr : AVX512Ii8<opc, MRMDestMem, (outs),
(ins _.ScalarMemOp:$dst, _.RC:$src1, u8imm:$src2),
OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
- [(store (_.EltVT (trunc (OpNode (_.VT _.RC:$src1), timm:$src2))),
+ [(store (_.EltVT (trunc (OpNode (_.VT _.RC:$src1), timm:$src2))),
addr:$dst)]>,
EVEX, EVEX_CD8<_.EltSize, CD8VT1>, Sched<[WriteVecExtractSt]>;
}
@@ -10890,7 +10890,7 @@ multiclass avx512_extract_elt_b<string OpcodeStr, X86VectorVTInfo _> {
(ins _.RC:$src1, u8imm:$src2),
OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
[(set GR32orGR64:$dst,
- (X86pextrb (_.VT _.RC:$src1), timm:$src2))]>,
+ (X86pextrb (_.VT _.RC:$src1), timm:$src2))]>,
EVEX, TAPD, Sched<[WriteVecExtract]>;
defm NAME : avx512_extract_elt_bw_m<0x14, OpcodeStr, X86pextrb, _>, TAPD;
@@ -10903,7 +10903,7 @@ multiclass avx512_extract_elt_w<string OpcodeStr, X86VectorVTInfo _> {
(ins _.RC:$src1, u8imm:$src2),
OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
[(set GR32orGR64:$dst,
- (X86pextrw (_.VT _.RC:$src1), timm:$src2))]>,
+ (X86pextrw (_.VT _.RC:$src1), timm:$src2))]>,
EVEX, PD, Sched<[WriteVecExtract]>;
let hasSideEffects = 0, isCodeGenOnly = 1, ForceDisassemble = 1 in
@@ -10943,13 +10943,13 @@ defm VPEXTRDZ : avx512_extract_elt_dq<"vpextrd", v4i32x_info, GR32>;
defm VPEXTRQZ : avx512_extract_elt_dq<"vpextrq", v2i64x_info, GR64>, VEX_W;
multiclass avx512_insert_elt_m<bits<8> opc, string OpcodeStr, SDNode OpNode,
- X86VectorVTInfo _, PatFrag LdFrag,
- SDPatternOperator immoperator> {
+ X86VectorVTInfo _, PatFrag LdFrag,
+ SDPatternOperator immoperator> {
def rm : AVX512Ii8<opc, MRMSrcMem, (outs _.RC:$dst),
(ins _.RC:$src1, _.ScalarMemOp:$src2, u8imm:$src3),
OpcodeStr#"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
[(set _.RC:$dst,
- (_.VT (OpNode _.RC:$src1, (LdFrag addr:$src2), immoperator:$src3)))]>,
+ (_.VT (OpNode _.RC:$src1, (LdFrag addr:$src2), immoperator:$src3)))]>,
EVEX_4V, EVEX_CD8<_.EltSize, CD8VT1>, Sched<[WriteVecInsert.Folded, WriteVecInsert.ReadAfterFold]>;
}
@@ -10960,10 +10960,10 @@ multiclass avx512_insert_elt_bw<bits<8> opc, string OpcodeStr, SDNode OpNode,
(ins _.RC:$src1, GR32orGR64:$src2, u8imm:$src3),
OpcodeStr#"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
[(set _.RC:$dst,
- (OpNode _.RC:$src1, GR32orGR64:$src2, timm:$src3))]>, EVEX_4V,
+ (OpNode _.RC:$src1, GR32orGR64:$src2, timm:$src3))]>, EVEX_4V,
Sched<[WriteVecInsert]>;
- defm NAME : avx512_insert_elt_m<opc, OpcodeStr, OpNode, _, LdFrag, timm>;
+ defm NAME : avx512_insert_elt_m<opc, OpcodeStr, OpNode, _, LdFrag, timm>;
}
}
@@ -10978,7 +10978,7 @@ multiclass avx512_insert_elt_dq<bits<8> opc, string OpcodeStr,
EVEX_4V, TAPD, Sched<[WriteVecInsert]>;
defm NAME : avx512_insert_elt_m<opc, OpcodeStr, insertelt, _,
- _.ScalarLdFrag, imm>, TAPD;
+ _.ScalarLdFrag, imm>, TAPD;
}
}
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrArithmetic.td b/contrib/libs/llvm12/lib/Target/X86/X86InstrArithmetic.td
index 37768af345..e83e1e74ff 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrArithmetic.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrArithmetic.td
@@ -1182,15 +1182,15 @@ defm SUB : ArithBinOp_RF<0x28, 0x2A, 0x2C, "sub", MRM5r, MRM5m,
X86sub_flag, sub, 0, 1, 0>;
}
-// Version of XOR8rr_NOREX that use GR8_NOREX. This is used by the handling of
-// __builtin_parity where the last step xors an h-register with an l-register.
-let isCodeGenOnly = 1, hasSideEffects = 0, Constraints = "$src1 = $dst",
- Defs = [EFLAGS], isCommutable = 1 in
-def XOR8rr_NOREX : I<0x30, MRMDestReg, (outs GR8_NOREX:$dst),
- (ins GR8_NOREX:$src1, GR8_NOREX:$src2),
- "xor{b}\t{$src2, $dst|$dst, $src2}", []>,
- Sched<[WriteALU]>;
-
+// Version of XOR8rr_NOREX that use GR8_NOREX. This is used by the handling of
+// __builtin_parity where the last step xors an h-register with an l-register.
+let isCodeGenOnly = 1, hasSideEffects = 0, Constraints = "$src1 = $dst",
+ Defs = [EFLAGS], isCommutable = 1 in
+def XOR8rr_NOREX : I<0x30, MRMDestReg, (outs GR8_NOREX:$dst),
+ (ins GR8_NOREX:$src1, GR8_NOREX:$src2),
+ "xor{b}\t{$src2, $dst|$dst, $src2}", []>,
+ Sched<[WriteALU]>;
+
// Arithmetic.
defm ADC : ArithBinOp_RFF<0x10, 0x12, 0x14, "adc", MRM2r, MRM2m, X86adc_flag,
1, 0>;
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrCompiler.td b/contrib/libs/llvm12/lib/Target/X86/X86InstrCompiler.td
index 49ab46522c..dc6361aecc 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrCompiler.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrCompiler.td
@@ -73,32 +73,32 @@ let usesCustomInserter = 1, Defs = [EFLAGS] in {
def VASTART_SAVE_XMM_REGS : I<0, Pseudo,
(outs),
(ins GR8:$al,
- i32imm:$regsavefi, i32imm:$offset,
+ i32imm:$regsavefi, i32imm:$offset,
variable_ops),
"#VASTART_SAVE_XMM_REGS $al, $regsavefi, $offset",
[(X86vastart_save_xmm_regs GR8:$al,
- timm:$regsavefi,
- timm:$offset),
+ timm:$regsavefi,
+ timm:$offset),
(implicit EFLAGS)]>;
-// The VAARG_64 and VAARG_X32 pseudo-instructions take the address of the
-// va_list, and place the address of the next argument into a register.
-let Defs = [EFLAGS] in {
+// The VAARG_64 and VAARG_X32 pseudo-instructions take the address of the
+// va_list, and place the address of the next argument into a register.
+let Defs = [EFLAGS] in {
def VAARG_64 : I<0, Pseudo,
(outs GR64:$dst),
(ins i8mem:$ap, i32imm:$size, i8imm:$mode, i32imm:$align),
"#VAARG_64 $dst, $ap, $size, $mode, $align",
[(set GR64:$dst,
- (X86vaarg64 addr:$ap, timm:$size, timm:$mode, timm:$align)),
- (implicit EFLAGS)]>, Requires<[In64BitMode, IsLP64]>;
-def VAARG_X32 : I<0, Pseudo,
- (outs GR32:$dst),
- (ins i8mem:$ap, i32imm:$size, i8imm:$mode, i32imm:$align),
- "#VAARG_X32 $dst, $ap, $size, $mode, $align",
- [(set GR32:$dst,
- (X86vaargx32 addr:$ap, timm:$size, timm:$mode, timm:$align)),
- (implicit EFLAGS)]>, Requires<[In64BitMode, NotLP64]>;
-}
+ (X86vaarg64 addr:$ap, timm:$size, timm:$mode, timm:$align)),
+ (implicit EFLAGS)]>, Requires<[In64BitMode, IsLP64]>;
+def VAARG_X32 : I<0, Pseudo,
+ (outs GR32:$dst),
+ (ins i8mem:$ap, i32imm:$size, i8imm:$mode, i32imm:$align),
+ "#VAARG_X32 $dst, $ap, $size, $mode, $align",
+ [(set GR32:$dst,
+ (X86vaargx32 addr:$ap, timm:$size, timm:$mode, timm:$align)),
+ (implicit EFLAGS)]>, Requires<[In64BitMode, NotLP64]>;
+}
// When using segmented stacks these are lowered into instructions which first
// check if the current stacklet has enough free memory. If it does, memory is
@@ -474,19 +474,19 @@ let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
def TLS_addr64 : I<0, Pseudo, (outs), (ins i64mem:$sym),
"# TLS_addr64",
[(X86tlsaddr tls64addr:$sym)]>,
- Requires<[In64BitMode, IsLP64]>;
+ Requires<[In64BitMode, IsLP64]>;
def TLS_base_addr64 : I<0, Pseudo, (outs), (ins i64mem:$sym),
"# TLS_base_addr64",
[(X86tlsbaseaddr tls64baseaddr:$sym)]>,
- Requires<[In64BitMode, IsLP64]>;
-def TLS_addrX32 : I<0, Pseudo, (outs), (ins i32mem:$sym),
- "# TLS_addrX32",
- [(X86tlsaddr tls32addr:$sym)]>,
- Requires<[In64BitMode, NotLP64]>;
-def TLS_base_addrX32 : I<0, Pseudo, (outs), (ins i32mem:$sym),
- "# TLS_base_addrX32",
- [(X86tlsbaseaddr tls32baseaddr:$sym)]>,
- Requires<[In64BitMode, NotLP64]>;
+ Requires<[In64BitMode, IsLP64]>;
+def TLS_addrX32 : I<0, Pseudo, (outs), (ins i32mem:$sym),
+ "# TLS_addrX32",
+ [(X86tlsaddr tls32addr:$sym)]>,
+ Requires<[In64BitMode, NotLP64]>;
+def TLS_base_addrX32 : I<0, Pseudo, (outs), (ins i32mem:$sym),
+ "# TLS_base_addrX32",
+ [(X86tlsbaseaddr tls32baseaddr:$sym)]>,
+ Requires<[In64BitMode, NotLP64]>;
}
// Darwin TLS Support
@@ -847,21 +847,21 @@ let isCodeGenOnly = 1, SchedRW = [WriteCMPXCHGRMW] in {
}
let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX],
- Predicates = [HasCmpxchg8b], SchedRW = [WriteCMPXCHGRMW],
- isCodeGenOnly = 1, usesCustomInserter = 1 in {
-def LCMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$ptr),
- "cmpxchg8b\t$ptr",
- [(X86cas8 addr:$ptr)]>, TB, LOCK;
+ Predicates = [HasCmpxchg8b], SchedRW = [WriteCMPXCHGRMW],
+ isCodeGenOnly = 1, usesCustomInserter = 1 in {
+def LCMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$ptr),
+ "cmpxchg8b\t$ptr",
+ [(X86cas8 addr:$ptr)]>, TB, LOCK;
+}
+
+let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX],
+ Predicates = [HasCmpxchg16b,In64BitMode], SchedRW = [WriteCMPXCHGRMW],
+ isCodeGenOnly = 1, mayLoad = 1, mayStore = 1, hasSideEffects = 0 in {
+def LCMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$ptr),
+ "cmpxchg16b\t$ptr",
+ []>, TB, LOCK;
}
-let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX],
- Predicates = [HasCmpxchg16b,In64BitMode], SchedRW = [WriteCMPXCHGRMW],
- isCodeGenOnly = 1, mayLoad = 1, mayStore = 1, hasSideEffects = 0 in {
-def LCMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$ptr),
- "cmpxchg16b\t$ptr",
- []>, TB, LOCK;
-}
-
// This pseudo must be used when the frame uses RBX as
// the base pointer. Indeed, in such situation RBX is a reserved
// register and the register allocator will ignore any use/def of
@@ -869,64 +869,64 @@ def LCMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$ptr),
// RBX that will happen when setting the arguments for the instrucion.
//
// Unlike the actual related instruction, we mark that this one
-// defines RBX (instead of using RBX).
+// defines RBX (instead of using RBX).
// The rationale is that we will define RBX during the expansion of
-// the pseudo. The argument feeding RBX is rbx_input.
+// the pseudo. The argument feeding RBX is rbx_input.
//
-// The additional argument, $rbx_save, is a temporary register used to
+// The additional argument, $rbx_save, is a temporary register used to
// save the value of RBX across the actual instruction.
//
-// To make sure the register assigned to $rbx_save does not interfere with
+// To make sure the register assigned to $rbx_save does not interfere with
// the definition of the actual instruction, we use a definition $dst which
// is tied to $rbx_save. That way, the live-range of $rbx_save spans across
// the instruction and we are sure we will have a valid register to restore
// the value of RBX.
-let Defs = [RAX, RDX, RBX, EFLAGS], Uses = [RAX, RCX, RDX],
- Predicates = [HasCmpxchg16b,In64BitMode], SchedRW = [WriteCMPXCHGRMW],
- isCodeGenOnly = 1, isPseudo = 1,
- mayLoad = 1, mayStore = 1, hasSideEffects = 0,
- Constraints = "$rbx_save = $dst" in {
-def LCMPXCHG16B_SAVE_RBX :
- I<0, Pseudo, (outs GR64:$dst),
- (ins i128mem:$ptr, GR64:$rbx_input, GR64:$rbx_save), "", []>;
-}
-
-// Pseudo instruction that doesn't read/write RBX. Will be turned into either
-// LCMPXCHG16B_SAVE_RBX or LCMPXCHG16B via a custom inserter.
-let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RCX, RDX],
- Predicates = [HasCmpxchg16b,In64BitMode], SchedRW = [WriteCMPXCHGRMW],
- isCodeGenOnly = 1, isPseudo = 1,
- mayLoad = 1, mayStore = 1, hasSideEffects = 0,
+let Defs = [RAX, RDX, RBX, EFLAGS], Uses = [RAX, RCX, RDX],
+ Predicates = [HasCmpxchg16b,In64BitMode], SchedRW = [WriteCMPXCHGRMW],
+ isCodeGenOnly = 1, isPseudo = 1,
+ mayLoad = 1, mayStore = 1, hasSideEffects = 0,
+ Constraints = "$rbx_save = $dst" in {
+def LCMPXCHG16B_SAVE_RBX :
+ I<0, Pseudo, (outs GR64:$dst),
+ (ins i128mem:$ptr, GR64:$rbx_input, GR64:$rbx_save), "", []>;
+}
+
+// Pseudo instruction that doesn't read/write RBX. Will be turned into either
+// LCMPXCHG16B_SAVE_RBX or LCMPXCHG16B via a custom inserter.
+let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RCX, RDX],
+ Predicates = [HasCmpxchg16b,In64BitMode], SchedRW = [WriteCMPXCHGRMW],
+ isCodeGenOnly = 1, isPseudo = 1,
+ mayLoad = 1, mayStore = 1, hasSideEffects = 0,
usesCustomInserter = 1 in {
-def LCMPXCHG16B_NO_RBX :
- I<0, Pseudo, (outs), (ins i128mem:$ptr, GR64:$rbx_input), "",
- [(X86cas16 addr:$ptr, GR64:$rbx_input)]>;
+def LCMPXCHG16B_NO_RBX :
+ I<0, Pseudo, (outs), (ins i128mem:$ptr, GR64:$rbx_input), "",
+ [(X86cas16 addr:$ptr, GR64:$rbx_input)]>;
}
-// This pseudo must be used when the frame uses RBX/EBX as
-// the base pointer.
-// cf comment for LCMPXCHG16B_SAVE_RBX.
-let Defs = [EBX], Uses = [ECX, EAX],
- Predicates = [HasMWAITX], SchedRW = [WriteSystem],
- isCodeGenOnly = 1, isPseudo = 1, Constraints = "$rbx_save = $dst" in {
-def MWAITX_SAVE_RBX :
- I<0, Pseudo, (outs GR64:$dst),
- (ins GR32:$ebx_input, GR64:$rbx_save),
- "mwaitx",
- []>;
+// This pseudo must be used when the frame uses RBX/EBX as
+// the base pointer.
+// cf comment for LCMPXCHG16B_SAVE_RBX.
+let Defs = [EBX], Uses = [ECX, EAX],
+ Predicates = [HasMWAITX], SchedRW = [WriteSystem],
+ isCodeGenOnly = 1, isPseudo = 1, Constraints = "$rbx_save = $dst" in {
+def MWAITX_SAVE_RBX :
+ I<0, Pseudo, (outs GR64:$dst),
+ (ins GR32:$ebx_input, GR64:$rbx_save),
+ "mwaitx",
+ []>;
}
-// Pseudo mwaitx instruction to use for custom insertion.
-let Predicates = [HasMWAITX], SchedRW = [WriteSystem],
- isCodeGenOnly = 1, isPseudo = 1,
+// Pseudo mwaitx instruction to use for custom insertion.
+let Predicates = [HasMWAITX], SchedRW = [WriteSystem],
+ isCodeGenOnly = 1, isPseudo = 1,
usesCustomInserter = 1 in {
-def MWAITX :
- I<0, Pseudo, (outs), (ins GR32:$ecx, GR32:$eax, GR32:$ebx),
- "mwaitx",
- [(int_x86_mwaitx GR32:$ecx, GR32:$eax, GR32:$ebx)]>;
+def MWAITX :
+ I<0, Pseudo, (outs), (ins GR32:$ecx, GR32:$eax, GR32:$ebx),
+ "mwaitx",
+ [(int_x86_mwaitx GR32:$ecx, GR32:$eax, GR32:$ebx)]>;
}
-
+
defm LCMPXCHG : LCMPXCHG_BinOp<0xB0, 0xB1, MRMDestMem, "cmpxchg", X86cas>;
// Atomic exchange and add
@@ -1213,49 +1213,49 @@ def X86tcret_6regs : PatFrag<(ops node:$ptr, node:$off),
return true;
}]>;
-def : Pat<(X86tcret ptr_rc_tailcall:$dst, timm:$off),
- (TCRETURNri ptr_rc_tailcall:$dst, timm:$off)>,
+def : Pat<(X86tcret ptr_rc_tailcall:$dst, timm:$off),
+ (TCRETURNri ptr_rc_tailcall:$dst, timm:$off)>,
Requires<[Not64BitMode, NotUseIndirectThunkCalls]>;
// FIXME: This is disabled for 32-bit PIC mode because the global base
// register which is part of the address mode may be assigned a
// callee-saved register.
-def : Pat<(X86tcret (load addr:$dst), timm:$off),
- (TCRETURNmi addr:$dst, timm:$off)>,
+def : Pat<(X86tcret (load addr:$dst), timm:$off),
+ (TCRETURNmi addr:$dst, timm:$off)>,
Requires<[Not64BitMode, IsNotPIC, NotUseIndirectThunkCalls]>;
-def : Pat<(X86tcret (i32 tglobaladdr:$dst), timm:$off),
- (TCRETURNdi tglobaladdr:$dst, timm:$off)>,
+def : Pat<(X86tcret (i32 tglobaladdr:$dst), timm:$off),
+ (TCRETURNdi tglobaladdr:$dst, timm:$off)>,
Requires<[NotLP64]>;
-def : Pat<(X86tcret (i32 texternalsym:$dst), timm:$off),
- (TCRETURNdi texternalsym:$dst, timm:$off)>,
+def : Pat<(X86tcret (i32 texternalsym:$dst), timm:$off),
+ (TCRETURNdi texternalsym:$dst, timm:$off)>,
Requires<[NotLP64]>;
-def : Pat<(X86tcret ptr_rc_tailcall:$dst, timm:$off),
- (TCRETURNri64 ptr_rc_tailcall:$dst, timm:$off)>,
+def : Pat<(X86tcret ptr_rc_tailcall:$dst, timm:$off),
+ (TCRETURNri64 ptr_rc_tailcall:$dst, timm:$off)>,
Requires<[In64BitMode, NotUseIndirectThunkCalls]>;
// Don't fold loads into X86tcret requiring more than 6 regs.
// There wouldn't be enough scratch registers for base+index.
-def : Pat<(X86tcret_6regs (load addr:$dst), timm:$off),
- (TCRETURNmi64 addr:$dst, timm:$off)>,
+def : Pat<(X86tcret_6regs (load addr:$dst), timm:$off),
+ (TCRETURNmi64 addr:$dst, timm:$off)>,
Requires<[In64BitMode, NotUseIndirectThunkCalls]>;
-def : Pat<(X86tcret ptr_rc_tailcall:$dst, timm:$off),
- (INDIRECT_THUNK_TCRETURN64 ptr_rc_tailcall:$dst, timm:$off)>,
+def : Pat<(X86tcret ptr_rc_tailcall:$dst, timm:$off),
+ (INDIRECT_THUNK_TCRETURN64 ptr_rc_tailcall:$dst, timm:$off)>,
Requires<[In64BitMode, UseIndirectThunkCalls]>;
-def : Pat<(X86tcret ptr_rc_tailcall:$dst, timm:$off),
- (INDIRECT_THUNK_TCRETURN32 ptr_rc_tailcall:$dst, timm:$off)>,
+def : Pat<(X86tcret ptr_rc_tailcall:$dst, timm:$off),
+ (INDIRECT_THUNK_TCRETURN32 ptr_rc_tailcall:$dst, timm:$off)>,
Requires<[Not64BitMode, UseIndirectThunkCalls]>;
-def : Pat<(X86tcret (i64 tglobaladdr:$dst), timm:$off),
- (TCRETURNdi64 tglobaladdr:$dst, timm:$off)>,
+def : Pat<(X86tcret (i64 tglobaladdr:$dst), timm:$off),
+ (TCRETURNdi64 tglobaladdr:$dst, timm:$off)>,
Requires<[IsLP64]>;
-def : Pat<(X86tcret (i64 texternalsym:$dst), timm:$off),
- (TCRETURNdi64 texternalsym:$dst, timm:$off)>,
+def : Pat<(X86tcret (i64 texternalsym:$dst), timm:$off),
+ (TCRETURNdi64 texternalsym:$dst, timm:$off)>,
Requires<[IsLP64]>;
// Normal calls, with various flavors of addresses.
@@ -1344,18 +1344,18 @@ def : Pat<(i32 (anyext_sdiv GR8:$src)), (MOVSX32rr8 GR8:$src)>;
// Any instruction that defines a 32-bit result leaves the high half of the
// register. Truncate can be lowered to EXTRACT_SUBREG. CopyFromReg may
-// be copying from a truncate. AssertSext/AssertZext/AssertAlign aren't saying
-// anything about the upper 32 bits, they're probably just qualifying a
-// CopyFromReg. FREEZE may be coming from a a truncate. Any other 32-bit
-// operation will zero-extend up to 64 bits.
+// be copying from a truncate. AssertSext/AssertZext/AssertAlign aren't saying
+// anything about the upper 32 bits, they're probably just qualifying a
+// CopyFromReg. FREEZE may be coming from a a truncate. Any other 32-bit
+// operation will zero-extend up to 64 bits.
def def32 : PatLeaf<(i32 GR32:$src), [{
return N->getOpcode() != ISD::TRUNCATE &&
N->getOpcode() != TargetOpcode::EXTRACT_SUBREG &&
N->getOpcode() != ISD::CopyFromReg &&
N->getOpcode() != ISD::AssertSext &&
- N->getOpcode() != ISD::AssertZext &&
- N->getOpcode() != ISD::AssertAlign &&
- N->getOpcode() != ISD::FREEZE;
+ N->getOpcode() != ISD::AssertZext &&
+ N->getOpcode() != ISD::AssertAlign &&
+ N->getOpcode() != ISD::FREEZE;
}]>;
// In the case of a 32-bit def that is known to implicitly zero-extend,
@@ -1732,16 +1732,16 @@ def : Pat<(store (i8 (trunc_su (srl_su GR16:$src, (i8 8)))), addr:$dst),
(EXTRACT_SUBREG GR16:$src, sub_8bit_hi))>,
Requires<[In64BitMode]>;
-// Special pattern to catch the last step of __builtin_parity handling. Our
-// goal is to use an xor of an h-register with the corresponding l-register.
-// The above patterns would handle this on non 64-bit targets, but for 64-bit
-// we need to be more careful. We're using a NOREX instruction here in case
-// register allocation fails to keep the two registers together. So we need to
-// make sure we can't accidentally mix R8-R15 with an h-register.
-def : Pat<(X86xor_flag (i8 (trunc GR32:$src)),
- (i8 (trunc (srl_su GR32:$src, (i8 8))))),
- (XOR8rr_NOREX (EXTRACT_SUBREG GR32:$src, sub_8bit),
- (EXTRACT_SUBREG GR32:$src, sub_8bit_hi))>;
+// Special pattern to catch the last step of __builtin_parity handling. Our
+// goal is to use an xor of an h-register with the corresponding l-register.
+// The above patterns would handle this on non 64-bit targets, but for 64-bit
+// we need to be more careful. We're using a NOREX instruction here in case
+// register allocation fails to keep the two registers together. So we need to
+// make sure we can't accidentally mix R8-R15 with an h-register.
+def : Pat<(X86xor_flag (i8 (trunc GR32:$src)),
+ (i8 (trunc (srl_su GR32:$src, (i8 8))))),
+ (XOR8rr_NOREX (EXTRACT_SUBREG GR32:$src, sub_8bit),
+ (EXTRACT_SUBREG GR32:$src, sub_8bit_hi))>;
// (shl x, 1) ==> (add x, x)
// Note that if x is undef (immediate or otherwise), we could theoretically
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrFMA.td b/contrib/libs/llvm12/lib/Target/X86/X86InstrFMA.td
index bfaa75c0ce..f9be3a7832 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrFMA.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrFMA.td
@@ -123,7 +123,7 @@ multiclass fma3p_forms<bits<8> opc132, bits<8> opc213, bits<8> opc231,
// Fused Multiply-Add
let ExeDomain = SSEPackedSingle in {
defm VFMADD : fma3p_forms<0x98, 0xA8, 0xB8, "vfmadd", "ps", "PS",
- loadv4f32, loadv8f32, any_fma, v4f32, v8f32,
+ loadv4f32, loadv8f32, any_fma, v4f32, v8f32,
SchedWriteFMA>;
defm VFMSUB : fma3p_forms<0x9A, 0xAA, 0xBA, "vfmsub", "ps", "PS",
loadv4f32, loadv8f32, X86any_Fmsub, v4f32, v8f32,
@@ -138,7 +138,7 @@ let ExeDomain = SSEPackedSingle in {
let ExeDomain = SSEPackedDouble in {
defm VFMADD : fma3p_forms<0x98, 0xA8, 0xB8, "vfmadd", "pd", "PD",
- loadv2f64, loadv4f64, any_fma, v2f64,
+ loadv2f64, loadv4f64, any_fma, v2f64,
v4f64, SchedWriteFMA>, VEX_W;
defm VFMSUB : fma3p_forms<0x9A, 0xAA, 0xBA, "vfmsub", "pd", "PD",
loadv2f64, loadv4f64, X86any_Fmsub, v2f64,
@@ -319,7 +319,7 @@ multiclass fma3s<bits<8> opc132, bits<8> opc213, bits<8> opc231,
VR128, sdmem, sched>, VEX_W;
}
-defm VFMADD : fma3s<0x99, 0xA9, 0xB9, "vfmadd", any_fma,
+defm VFMADD : fma3s<0x99, 0xA9, 0xB9, "vfmadd", any_fma,
SchedWriteFMA.Scl>, VEX_LIG;
defm VFMSUB : fma3s<0x9B, 0xAB, 0xBB, "vfmsub", X86any_Fmsub,
SchedWriteFMA.Scl>, VEX_LIG;
@@ -372,12 +372,12 @@ multiclass scalar_fma_patterns<SDNode Op, string Prefix, string Suffix,
}
}
-defm : scalar_fma_patterns<any_fma, "VFMADD", "SS", X86Movss, v4f32, f32, FR32, loadf32>;
+defm : scalar_fma_patterns<any_fma, "VFMADD", "SS", X86Movss, v4f32, f32, FR32, loadf32>;
defm : scalar_fma_patterns<X86any_Fmsub, "VFMSUB", "SS", X86Movss, v4f32, f32, FR32, loadf32>;
defm : scalar_fma_patterns<X86any_Fnmadd, "VFNMADD", "SS", X86Movss, v4f32, f32, FR32, loadf32>;
defm : scalar_fma_patterns<X86any_Fnmsub, "VFNMSUB", "SS", X86Movss, v4f32, f32, FR32, loadf32>;
-defm : scalar_fma_patterns<any_fma, "VFMADD", "SD", X86Movsd, v2f64, f64, FR64, loadf64>;
+defm : scalar_fma_patterns<any_fma, "VFMADD", "SD", X86Movsd, v2f64, f64, FR64, loadf64>;
defm : scalar_fma_patterns<X86any_Fmsub, "VFMSUB", "SD", X86Movsd, v2f64, f64, FR64, loadf64>;
defm : scalar_fma_patterns<X86any_Fnmadd, "VFNMADD", "SD", X86Movsd, v2f64, f64, FR64, loadf64>;
defm : scalar_fma_patterns<X86any_Fnmsub, "VFNMSUB", "SD", X86Movsd, v2f64, f64, FR64, loadf64>;
@@ -538,7 +538,7 @@ let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
let ExeDomain = SSEPackedSingle in {
// Scalar Instructions
- defm VFMADDSS4 : fma4s<0x6A, "vfmaddss", FR32, f32mem, f32, any_fma, loadf32,
+ defm VFMADDSS4 : fma4s<0x6A, "vfmaddss", FR32, f32mem, f32, any_fma, loadf32,
SchedWriteFMA.Scl>,
fma4s_int<0x6A, "vfmaddss", ssmem, v4f32,
SchedWriteFMA.Scl>;
@@ -555,7 +555,7 @@ let ExeDomain = SSEPackedSingle in {
fma4s_int<0x7E, "vfnmsubss", ssmem, v4f32,
SchedWriteFMA.Scl>;
// Packed Instructions
- defm VFMADDPS4 : fma4p<0x68, "vfmaddps", any_fma, v4f32, v8f32,
+ defm VFMADDPS4 : fma4p<0x68, "vfmaddps", any_fma, v4f32, v8f32,
loadv4f32, loadv8f32, SchedWriteFMA>;
defm VFMSUBPS4 : fma4p<0x6C, "vfmsubps", X86any_Fmsub, v4f32, v8f32,
loadv4f32, loadv8f32, SchedWriteFMA>;
@@ -571,7 +571,7 @@ let ExeDomain = SSEPackedSingle in {
let ExeDomain = SSEPackedDouble in {
// Scalar Instructions
- defm VFMADDSD4 : fma4s<0x6B, "vfmaddsd", FR64, f64mem, f64, any_fma, loadf64,
+ defm VFMADDSD4 : fma4s<0x6B, "vfmaddsd", FR64, f64mem, f64, any_fma, loadf64,
SchedWriteFMA.Scl>,
fma4s_int<0x6B, "vfmaddsd", sdmem, v2f64,
SchedWriteFMA.Scl>;
@@ -588,7 +588,7 @@ let ExeDomain = SSEPackedDouble in {
fma4s_int<0x7F, "vfnmsubsd", sdmem, v2f64,
SchedWriteFMA.Scl>;
// Packed Instructions
- defm VFMADDPD4 : fma4p<0x69, "vfmaddpd", any_fma, v2f64, v4f64,
+ defm VFMADDPD4 : fma4p<0x69, "vfmaddpd", any_fma, v2f64, v4f64,
loadv2f64, loadv4f64, SchedWriteFMA>;
defm VFMSUBPD4 : fma4p<0x6D, "vfmsubpd", X86any_Fmsub, v2f64, v4f64,
loadv2f64, loadv4f64, SchedWriteFMA>;
@@ -629,12 +629,12 @@ multiclass scalar_fma4_patterns<SDNode Op, string Name,
}
}
-defm : scalar_fma4_patterns<any_fma, "VFMADDSS4", v4f32, f32, FR32, loadf32>;
+defm : scalar_fma4_patterns<any_fma, "VFMADDSS4", v4f32, f32, FR32, loadf32>;
defm : scalar_fma4_patterns<X86any_Fmsub, "VFMSUBSS4", v4f32, f32, FR32, loadf32>;
defm : scalar_fma4_patterns<X86any_Fnmadd, "VFNMADDSS4", v4f32, f32, FR32, loadf32>;
defm : scalar_fma4_patterns<X86any_Fnmsub, "VFNMSUBSS4", v4f32, f32, FR32, loadf32>;
-defm : scalar_fma4_patterns<any_fma, "VFMADDSD4", v2f64, f64, FR64, loadf64>;
+defm : scalar_fma4_patterns<any_fma, "VFMADDSD4", v2f64, f64, FR64, loadf64>;
defm : scalar_fma4_patterns<X86any_Fmsub, "VFMSUBSD4", v2f64, f64, FR64, loadf64>;
defm : scalar_fma4_patterns<X86any_Fnmadd, "VFNMADDSD4", v2f64, f64, FR64, loadf64>;
defm : scalar_fma4_patterns<X86any_Fnmsub, "VFNMSUBSD4", v2f64, f64, FR64, loadf64>;
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrFPStack.td b/contrib/libs/llvm12/lib/Target/X86/X86InstrFPStack.td
index cfbfe39f88..961b4e5903 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrFPStack.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrFPStack.td
@@ -392,13 +392,13 @@ def FICOMP32m: FPI<0xDA, MRM3m, (outs), (ins i32mem:$src), "ficomp{l}\t$src">;
let SchedRW = [WriteMicrocoded] in {
let Defs = [FPSW, FPCW], mayLoad = 1 in {
-def FLDENVm : FPI<0xD9, MRM4m, (outs), (ins anymem:$src), "fldenv\t$src">;
-def FRSTORm : FPI<0xDD, MRM4m, (outs), (ins anymem:$src), "frstor\t$src">;
+def FLDENVm : FPI<0xD9, MRM4m, (outs), (ins anymem:$src), "fldenv\t$src">;
+def FRSTORm : FPI<0xDD, MRM4m, (outs), (ins anymem:$src), "frstor\t$src">;
}
let Defs = [FPSW, FPCW], Uses = [FPSW, FPCW], mayStore = 1 in {
-def FSTENVm : FPI<0xD9, MRM6m, (outs), (ins anymem:$dst), "fnstenv\t$dst">;
-def FSAVEm : FPI<0xDD, MRM6m, (outs), (ins anymem:$dst), "fnsave\t$dst">;
+def FSTENVm : FPI<0xD9, MRM6m, (outs), (ins anymem:$dst), "fnstenv\t$dst">;
+def FSAVEm : FPI<0xDD, MRM6m, (outs), (ins anymem:$dst), "fnsave\t$dst">;
}
let Uses = [FPSW], mayStore = 1 in
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrFoldTables.cpp b/contrib/libs/llvm12/lib/Target/X86/X86InstrFoldTables.cpp
index 1e3fb7f227..17fe7f0bd3 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrFoldTables.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrFoldTables.cpp
@@ -300,13 +300,13 @@ static const X86MemoryFoldTableEntry MemoryFoldTable0[] = {
{ X86::MOV32rr, X86::MOV32mr, TB_FOLDED_STORE },
{ X86::MOV64ri32, X86::MOV64mi32, TB_FOLDED_STORE },
{ X86::MOV64rr, X86::MOV64mr, TB_FOLDED_STORE },
- { X86::MOV64toSDrr, X86::MOV64mr, TB_FOLDED_STORE | TB_NO_REVERSE },
+ { X86::MOV64toSDrr, X86::MOV64mr, TB_FOLDED_STORE | TB_NO_REVERSE },
{ X86::MOV8ri, X86::MOV8mi, TB_FOLDED_STORE },
{ X86::MOV8rr, X86::MOV8mr, TB_FOLDED_STORE },
{ X86::MOV8rr_NOREX, X86::MOV8mr_NOREX, TB_FOLDED_STORE },
{ X86::MOVAPDrr, X86::MOVAPDmr, TB_FOLDED_STORE | TB_ALIGN_16 },
{ X86::MOVAPSrr, X86::MOVAPSmr, TB_FOLDED_STORE | TB_ALIGN_16 },
- { X86::MOVDI2SSrr, X86::MOV32mr, TB_FOLDED_STORE | TB_NO_REVERSE },
+ { X86::MOVDI2SSrr, X86::MOV32mr, TB_FOLDED_STORE | TB_NO_REVERSE },
{ X86::MOVDQArr, X86::MOVDQAmr, TB_FOLDED_STORE | TB_ALIGN_16 },
{ X86::MOVDQUrr, X86::MOVDQUmr, TB_FOLDED_STORE },
{ X86::MOVPDI2DIrr, X86::MOVPDI2DImr, TB_FOLDED_STORE },
@@ -359,8 +359,8 @@ static const X86MemoryFoldTableEntry MemoryFoldTable0[] = {
{ X86::VEXTRACTI64x4Zrr, X86::VEXTRACTI64x4Zmr, TB_FOLDED_STORE },
{ X86::VEXTRACTPSZrr, X86::VEXTRACTPSZmr, TB_FOLDED_STORE },
{ X86::VEXTRACTPSrr, X86::VEXTRACTPSmr, TB_FOLDED_STORE },
- { X86::VMOV64toSDZrr, X86::MOV64mr, TB_FOLDED_STORE | TB_NO_REVERSE },
- { X86::VMOV64toSDrr, X86::MOV64mr, TB_FOLDED_STORE | TB_NO_REVERSE },
+ { X86::VMOV64toSDZrr, X86::MOV64mr, TB_FOLDED_STORE | TB_NO_REVERSE },
+ { X86::VMOV64toSDrr, X86::MOV64mr, TB_FOLDED_STORE | TB_NO_REVERSE },
{ X86::VMOVAPDYrr, X86::VMOVAPDYmr, TB_FOLDED_STORE | TB_ALIGN_32 },
{ X86::VMOVAPDZ128rr, X86::VMOVAPDZ128mr, TB_FOLDED_STORE | TB_ALIGN_16 },
{ X86::VMOVAPDZ256rr, X86::VMOVAPDZ256mr, TB_FOLDED_STORE | TB_ALIGN_32 },
@@ -371,8 +371,8 @@ static const X86MemoryFoldTableEntry MemoryFoldTable0[] = {
{ X86::VMOVAPSZ256rr, X86::VMOVAPSZ256mr, TB_FOLDED_STORE | TB_ALIGN_32 },
{ X86::VMOVAPSZrr, X86::VMOVAPSZmr, TB_FOLDED_STORE | TB_ALIGN_64 },
{ X86::VMOVAPSrr, X86::VMOVAPSmr, TB_FOLDED_STORE | TB_ALIGN_16 },
- { X86::VMOVDI2SSZrr, X86::MOV32mr, TB_FOLDED_STORE | TB_NO_REVERSE },
- { X86::VMOVDI2SSrr, X86::MOV32mr, TB_FOLDED_STORE | TB_NO_REVERSE },
+ { X86::VMOVDI2SSZrr, X86::MOV32mr, TB_FOLDED_STORE | TB_NO_REVERSE },
+ { X86::VMOVDI2SSrr, X86::MOV32mr, TB_FOLDED_STORE | TB_NO_REVERSE },
{ X86::VMOVDQA32Z128rr, X86::VMOVDQA32Z128mr, TB_FOLDED_STORE | TB_ALIGN_16 },
{ X86::VMOVDQA32Z256rr, X86::VMOVDQA32Z256mr, TB_FOLDED_STORE | TB_ALIGN_32 },
{ X86::VMOVDQA32Zrr, X86::VMOVDQA32Zmr, TB_FOLDED_STORE | TB_ALIGN_64 },
@@ -3748,26 +3748,26 @@ static const X86MemoryFoldTableEntry MemoryFoldTable3[] = {
{ X86::VPCONFLICTQZ128rrk, X86::VPCONFLICTQZ128rmk, 0 },
{ X86::VPCONFLICTQZ256rrk, X86::VPCONFLICTQZ256rmk, 0 },
{ X86::VPCONFLICTQZrrk, X86::VPCONFLICTQZrmk, 0 },
- { X86::VPDPBUSDSYrr, X86::VPDPBUSDSYrm, 0 },
+ { X86::VPDPBUSDSYrr, X86::VPDPBUSDSYrm, 0 },
{ X86::VPDPBUSDSZ128r, X86::VPDPBUSDSZ128m, 0 },
{ X86::VPDPBUSDSZ256r, X86::VPDPBUSDSZ256m, 0 },
{ X86::VPDPBUSDSZr, X86::VPDPBUSDSZm, 0 },
- { X86::VPDPBUSDSrr, X86::VPDPBUSDSrm, 0 },
- { X86::VPDPBUSDYrr, X86::VPDPBUSDYrm, 0 },
+ { X86::VPDPBUSDSrr, X86::VPDPBUSDSrm, 0 },
+ { X86::VPDPBUSDYrr, X86::VPDPBUSDYrm, 0 },
{ X86::VPDPBUSDZ128r, X86::VPDPBUSDZ128m, 0 },
{ X86::VPDPBUSDZ256r, X86::VPDPBUSDZ256m, 0 },
{ X86::VPDPBUSDZr, X86::VPDPBUSDZm, 0 },
- { X86::VPDPBUSDrr, X86::VPDPBUSDrm, 0 },
- { X86::VPDPWSSDSYrr, X86::VPDPWSSDSYrm, 0 },
+ { X86::VPDPBUSDrr, X86::VPDPBUSDrm, 0 },
+ { X86::VPDPWSSDSYrr, X86::VPDPWSSDSYrm, 0 },
{ X86::VPDPWSSDSZ128r, X86::VPDPWSSDSZ128m, 0 },
{ X86::VPDPWSSDSZ256r, X86::VPDPWSSDSZ256m, 0 },
{ X86::VPDPWSSDSZr, X86::VPDPWSSDSZm, 0 },
- { X86::VPDPWSSDSrr, X86::VPDPWSSDSrm, 0 },
- { X86::VPDPWSSDYrr, X86::VPDPWSSDYrm, 0 },
+ { X86::VPDPWSSDSrr, X86::VPDPWSSDSrm, 0 },
+ { X86::VPDPWSSDYrr, X86::VPDPWSSDYrm, 0 },
{ X86::VPDPWSSDZ128r, X86::VPDPWSSDZ128m, 0 },
{ X86::VPDPWSSDZ256r, X86::VPDPWSSDZ256m, 0 },
{ X86::VPDPWSSDZr, X86::VPDPWSSDZm, 0 },
- { X86::VPDPWSSDrr, X86::VPDPWSSDrm, 0 },
+ { X86::VPDPWSSDrr, X86::VPDPWSSDrm, 0 },
{ X86::VPERMBZ128rrkz, X86::VPERMBZ128rmkz, 0 },
{ X86::VPERMBZ256rrkz, X86::VPERMBZ256rmkz, 0 },
{ X86::VPERMBZrrkz, X86::VPERMBZrmkz, 0 },
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrFormats.td b/contrib/libs/llvm12/lib/Target/X86/X86InstrFormats.td
index 23cec4e363..686b19fc0a 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrFormats.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrFormats.td
@@ -216,7 +216,7 @@ class T8XS : T8 { Prefix OpPrefix = XS; }
class TAPS : TA { Prefix OpPrefix = PS; }
class TAPD : TA { Prefix OpPrefix = PD; }
class TAXD : TA { Prefix OpPrefix = XD; }
-class TAXS : TA { Prefix OpPrefix = XS; }
+class TAXS : TA { Prefix OpPrefix = XS; }
class VEX { Encoding OpEnc = EncVEX; }
class VEX_W { bit HasVEX_W = 1; }
class VEX_WIG { bit IgnoresVEX_W = 1; }
@@ -264,9 +264,9 @@ class NotMemoryFoldable { bit isMemoryFoldable = 0; }
// Prevent EVEX->VEX conversion from considering this instruction.
class NotEVEX2VEXConvertible { bit notEVEX2VEXConvertible = 1; }
-// Force the instruction to use VEX encoding.
-class ExplicitVEXPrefix { bit ExplicitVEXPrefix = 1; }
-
+// Force the instruction to use VEX encoding.
+class ExplicitVEXPrefix { bit ExplicitVEXPrefix = 1; }
+
class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins,
string AsmStr, Domain d = GenericDomain>
: Instruction {
@@ -351,7 +351,7 @@ class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins,
bit isMemoryFoldable = 1; // Is it allowed to memory fold/unfold this instruction?
bit notEVEX2VEXConvertible = 0; // Prevent EVEX->VEX conversion.
- bit ExplicitVEXPrefix = 0; // Force the instruction to use VEX encoding.
+ bit ExplicitVEXPrefix = 0; // Force the instruction to use VEX encoding.
// TSFlags layout should be kept in sync with X86BaseInfo.h.
let TSFlags{6-0} = FormBits;
@@ -380,7 +380,7 @@ class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins,
let TSFlags{51-45} = CD8_Scale;
let TSFlags{52} = hasEVEX_RC;
let TSFlags{53} = hasNoTrackPrefix;
- let TSFlags{54} = ExplicitVEXPrefix;
+ let TSFlags{54} = ExplicitVEXPrefix;
}
class PseudoI<dag oops, dag iops, list<dag> pattern>
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrFragmentsSIMD.td b/contrib/libs/llvm12/lib/Target/X86/X86InstrFragmentsSIMD.td
index 0d9595128f..777c5a158b 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrFragmentsSIMD.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrFragmentsSIMD.td
@@ -87,16 +87,16 @@ def X86multishift : SDNode<"X86ISD::MULTISHIFT",
SDTCisSameAs<1,2>]>>;
def X86pextrb : SDNode<"X86ISD::PEXTRB",
SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisVT<1, v16i8>,
- SDTCisVT<2, i8>]>>;
+ SDTCisVT<2, i8>]>>;
def X86pextrw : SDNode<"X86ISD::PEXTRW",
SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisVT<1, v8i16>,
- SDTCisVT<2, i8>]>>;
+ SDTCisVT<2, i8>]>>;
def X86pinsrb : SDNode<"X86ISD::PINSRB",
SDTypeProfile<1, 3, [SDTCisVT<0, v16i8>, SDTCisSameAs<0,1>,
- SDTCisVT<2, i32>, SDTCisVT<3, i8>]>>;
+ SDTCisVT<2, i32>, SDTCisVT<3, i8>]>>;
def X86pinsrw : SDNode<"X86ISD::PINSRW",
SDTypeProfile<1, 3, [SDTCisVT<0, v8i16>, SDTCisSameAs<0,1>,
- SDTCisVT<2, i32>, SDTCisVT<3, i8>]>>;
+ SDTCisVT<2, i32>, SDTCisVT<3, i8>]>>;
def X86insertps : SDNode<"X86ISD::INSERTPS",
SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisSameAs<0,1>,
SDTCisVT<2, v4f32>, SDTCisVT<3, i8>]>>;
@@ -109,8 +109,8 @@ def X86vextractst : SDNode<"X86ISD::VEXTRACT_STORE", SDTStore,
[SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
def X86VBroadcastld : SDNode<"X86ISD::VBROADCAST_LOAD", SDTLoad,
[SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
-def X86SubVBroadcastld : SDNode<"X86ISD::SUBV_BROADCAST_LOAD", SDTLoad,
- [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
+def X86SubVBroadcastld : SDNode<"X86ISD::SUBV_BROADCAST_LOAD", SDTLoad,
+ [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
def SDTVtrunc : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisVec<1>,
SDTCisInt<0>, SDTCisInt<1>,
@@ -209,21 +209,21 @@ def X86CmpMaskCC :
SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCVecEltisVT<0, i1>,
SDTCisVec<1>, SDTCisSameAs<2, 1>,
SDTCisSameNumEltsAs<0, 1>, SDTCisVT<3, i8>]>;
-def X86MaskCmpMaskCC :
- SDTypeProfile<1, 4, [SDTCisVec<0>, SDTCVecEltisVT<0, i1>,
- SDTCisVec<1>, SDTCisSameAs<2, 1>,
- SDTCisSameNumEltsAs<0, 1>, SDTCisVT<3, i8>, SDTCisSameAs<4, 0>]>;
+def X86MaskCmpMaskCC :
+ SDTypeProfile<1, 4, [SDTCisVec<0>, SDTCVecEltisVT<0, i1>,
+ SDTCisVec<1>, SDTCisSameAs<2, 1>,
+ SDTCisSameNumEltsAs<0, 1>, SDTCisVT<3, i8>, SDTCisSameAs<4, 0>]>;
def X86CmpMaskCCScalar :
SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisFP<1>, SDTCisSameAs<1, 2>,
SDTCisVT<3, i8>]>;
def X86cmpm : SDNode<"X86ISD::CMPM", X86CmpMaskCC>;
-def X86cmpmm : SDNode<"X86ISD::CMPMM", X86MaskCmpMaskCC>;
+def X86cmpmm : SDNode<"X86ISD::CMPMM", X86MaskCmpMaskCC>;
def X86strict_cmpm : SDNode<"X86ISD::STRICT_CMPM", X86CmpMaskCC, [SDNPHasChain]>;
def X86any_cmpm : PatFrags<(ops node:$src1, node:$src2, node:$src3),
[(X86strict_cmpm node:$src1, node:$src2, node:$src3),
(X86cmpm node:$src1, node:$src2, node:$src3)]>;
-def X86cmpmmSAE : SDNode<"X86ISD::CMPMM_SAE", X86MaskCmpMaskCC>;
+def X86cmpmmSAE : SDNode<"X86ISD::CMPMM_SAE", X86MaskCmpMaskCC>;
def X86cmpms : SDNode<"X86ISD::FSETCCM", X86CmpMaskCCScalar>;
def X86cmpmsSAE : SDNode<"X86ISD::FSETCCM_SAE", X86CmpMaskCCScalar>;
@@ -961,16 +961,16 @@ def X86VBroadcastld64 : PatFrag<(ops node:$src),
return cast<MemIntrinsicSDNode>(N)->getMemoryVT().getStoreSize() == 8;
}]>;
-def X86SubVBroadcastld128 : PatFrag<(ops node:$src),
- (X86SubVBroadcastld node:$src), [{
- return cast<MemIntrinsicSDNode>(N)->getMemoryVT().getStoreSize() == 16;
-}]>;
-
-def X86SubVBroadcastld256 : PatFrag<(ops node:$src),
- (X86SubVBroadcastld node:$src), [{
- return cast<MemIntrinsicSDNode>(N)->getMemoryVT().getStoreSize() == 32;
-}]>;
-
+def X86SubVBroadcastld128 : PatFrag<(ops node:$src),
+ (X86SubVBroadcastld node:$src), [{
+ return cast<MemIntrinsicSDNode>(N)->getMemoryVT().getStoreSize() == 16;
+}]>;
+
+def X86SubVBroadcastld256 : PatFrag<(ops node:$src),
+ (X86SubVBroadcastld node:$src), [{
+ return cast<MemIntrinsicSDNode>(N)->getMemoryVT().getStoreSize() == 32;
+}]>;
+
// Scalar SSE intrinsic fragments to match several different types of loads.
// Used by scalar SSE intrinsic instructions which have 128 bit types, but
// only load a single element.
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrInfo.cpp b/contrib/libs/llvm12/lib/Target/X86/X86InstrInfo.cpp
index 283ca4164f..d9bab14f0c 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrInfo.cpp
@@ -28,7 +28,7 @@
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/StackMaps.h"
-#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -947,9 +947,9 @@ unsigned X86InstrInfo::isStoreToStackSlotPostFE(const MachineInstr &MI,
}
/// Return true if register is PIC base; i.e.g defined by X86::MOVPC32r.
-static bool regIsPICBase(Register BaseReg, const MachineRegisterInfo &MRI) {
+static bool regIsPICBase(Register BaseReg, const MachineRegisterInfo &MRI) {
// Don't waste compile time scanning use-def chains of physregs.
- if (!BaseReg.isVirtual())
+ if (!BaseReg.isVirtual())
return false;
bool isPICBase = false;
for (MachineRegisterInfo::def_instr_iterator I = MRI.def_instr_begin(BaseReg),
@@ -1127,8 +1127,8 @@ void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB,
const MachineInstr &Orig,
const TargetRegisterInfo &TRI) const {
bool ClobbersEFLAGS = Orig.modifiesRegister(X86::EFLAGS, &TRI);
- if (ClobbersEFLAGS && MBB.computeRegisterLiveness(&TRI, X86::EFLAGS, I) !=
- MachineBasicBlock::LQR_Dead) {
+ if (ClobbersEFLAGS && MBB.computeRegisterLiveness(&TRI, X86::EFLAGS, I) !=
+ MachineBasicBlock::LQR_Dead) {
// The instruction clobbers EFLAGS. Re-materialize as MOV32ri to avoid side
// effects.
int Value;
@@ -1206,7 +1206,7 @@ bool X86InstrInfo::classifyLEAReg(MachineInstr &MI, const MachineOperand &Src,
isKill = Src.isKill();
assert(!Src.isUndef() && "Undef op doesn't need optimization");
- if (NewSrc.isVirtual() && !MF.getRegInfo().constrainRegClass(NewSrc, RC))
+ if (NewSrc.isVirtual() && !MF.getRegInfo().constrainRegClass(NewSrc, RC))
return false;
return true;
@@ -1214,7 +1214,7 @@ bool X86InstrInfo::classifyLEAReg(MachineInstr &MI, const MachineOperand &Src,
// This is for an LEA64_32r and incoming registers are 32-bit. One way or
// another we need to add 64-bit registers to the final MI.
- if (SrcReg.isPhysical()) {
+ if (SrcReg.isPhysical()) {
ImplicitOp = Src;
ImplicitOp.setImplicit();
@@ -1409,8 +1409,8 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
if (!isTruncatedShiftCountForLEA(ShAmt)) return nullptr;
// LEA can't handle RSP.
- if (Src.getReg().isVirtual() && !MF.getRegInfo().constrainRegClass(
- Src.getReg(), &X86::GR64_NOSPRegClass))
+ if (Src.getReg().isVirtual() && !MF.getRegInfo().constrainRegClass(
+ Src.getReg(), &X86::GR64_NOSPRegClass))
return nullptr;
NewMI = BuildMI(MF, MI.getDebugLoc(), get(X86::LEA64r))
@@ -2566,10 +2566,10 @@ bool X86InstrInfo::findCommutedOpIndices(const MachineInstr &MI,
case X86::VPTERNLOGQZ256rmbikz:
case X86::VPTERNLOGQZrmbikz:
return findThreeSrcCommutedOpIndices(MI, SrcOpIdx1, SrcOpIdx2);
- case X86::VPDPWSSDYrr:
- case X86::VPDPWSSDrr:
- case X86::VPDPWSSDSYrr:
- case X86::VPDPWSSDSrr:
+ case X86::VPDPWSSDYrr:
+ case X86::VPDPWSSDrr:
+ case X86::VPDPWSSDSYrr:
+ case X86::VPDPWSSDSrr:
case X86::VPDPWSSDZ128r:
case X86::VPDPWSSDZ128rk:
case X86::VPDPWSSDZ128rkz:
@@ -3530,10 +3530,10 @@ X86InstrInfo::isCopyInstrImpl(const MachineInstr &MI) const {
return None;
}
-static unsigned getLoadStoreRegOpcode(Register Reg,
+static unsigned getLoadStoreRegOpcode(Register Reg,
const TargetRegisterClass *RC,
- bool IsStackAligned,
- const X86Subtarget &STI, bool load) {
+ bool IsStackAligned,
+ const X86Subtarget &STI, bool load) {
bool HasAVX = STI.hasAVX();
bool HasAVX512 = STI.hasAVX512();
bool HasVLX = STI.hasVLX();
@@ -3606,7 +3606,7 @@ static unsigned getLoadStoreRegOpcode(Register Reg,
case 16: {
if (X86::VR128XRegClass.hasSubClassEq(RC)) {
// If stack is realigned we can use aligned stores.
- if (IsStackAligned)
+ if (IsStackAligned)
return load ?
(HasVLX ? X86::VMOVAPSZ128rm :
HasAVX512 ? X86::VMOVAPSZ128rm_NOVLX :
@@ -3638,7 +3638,7 @@ static unsigned getLoadStoreRegOpcode(Register Reg,
case 32:
assert(X86::VR256XRegClass.hasSubClassEq(RC) && "Unknown 32-byte regclass");
// If stack is realigned we can use aligned stores.
- if (IsStackAligned)
+ if (IsStackAligned)
return load ?
(HasVLX ? X86::VMOVAPSZ256rm :
HasAVX512 ? X86::VMOVAPSZ256rm_NOVLX :
@@ -3657,80 +3657,80 @@ static unsigned getLoadStoreRegOpcode(Register Reg,
case 64:
assert(X86::VR512RegClass.hasSubClassEq(RC) && "Unknown 64-byte regclass");
assert(STI.hasAVX512() && "Using 512-bit register requires AVX512");
- if (IsStackAligned)
+ if (IsStackAligned)
return load ? X86::VMOVAPSZrm : X86::VMOVAPSZmr;
else
return load ? X86::VMOVUPSZrm : X86::VMOVUPSZmr;
}
}
-Optional<ExtAddrMode>
-X86InstrInfo::getAddrModeFromMemoryOp(const MachineInstr &MemI,
- const TargetRegisterInfo *TRI) const {
- const MCInstrDesc &Desc = MemI.getDesc();
- int MemRefBegin = X86II::getMemoryOperandNo(Desc.TSFlags);
- if (MemRefBegin < 0)
- return None;
-
- MemRefBegin += X86II::getOperandBias(Desc);
-
- auto &BaseOp = MemI.getOperand(MemRefBegin + X86::AddrBaseReg);
- if (!BaseOp.isReg()) // Can be an MO_FrameIndex
- return None;
-
- const MachineOperand &DispMO = MemI.getOperand(MemRefBegin + X86::AddrDisp);
- // Displacement can be symbolic
- if (!DispMO.isImm())
- return None;
-
- ExtAddrMode AM;
- AM.BaseReg = BaseOp.getReg();
- AM.ScaledReg = MemI.getOperand(MemRefBegin + X86::AddrIndexReg).getReg();
- AM.Scale = MemI.getOperand(MemRefBegin + X86::AddrScaleAmt).getImm();
- AM.Displacement = DispMO.getImm();
- return AM;
-}
-
-bool X86InstrInfo::getConstValDefinedInReg(const MachineInstr &MI,
- const Register Reg,
- int64_t &ImmVal) const {
- if (MI.getOpcode() != X86::MOV32ri && MI.getOpcode() != X86::MOV64ri)
- return false;
- // Mov Src can be a global address.
- if (!MI.getOperand(1).isImm() || MI.getOperand(0).getReg() != Reg)
- return false;
- ImmVal = MI.getOperand(1).getImm();
- return true;
-}
-
-bool X86InstrInfo::preservesZeroValueInReg(
- const MachineInstr *MI, const Register NullValueReg,
- const TargetRegisterInfo *TRI) const {
- if (!MI->modifiesRegister(NullValueReg, TRI))
- return true;
- switch (MI->getOpcode()) {
- // Shift right/left of a null unto itself is still a null, i.e. rax = shl rax
- // X.
- case X86::SHR64ri:
- case X86::SHR32ri:
- case X86::SHL64ri:
- case X86::SHL32ri:
- assert(MI->getOperand(0).isDef() && MI->getOperand(1).isUse() &&
- "expected for shift opcode!");
- return MI->getOperand(0).getReg() == NullValueReg &&
- MI->getOperand(1).getReg() == NullValueReg;
- // Zero extend of a sub-reg of NullValueReg into itself does not change the
- // null value.
- case X86::MOV32rr:
- return llvm::all_of(MI->operands(), [&](const MachineOperand &MO) {
- return TRI->isSubRegisterEq(NullValueReg, MO.getReg());
- });
- default:
- return false;
- }
- llvm_unreachable("Should be handled above!");
-}
-
+Optional<ExtAddrMode>
+X86InstrInfo::getAddrModeFromMemoryOp(const MachineInstr &MemI,
+ const TargetRegisterInfo *TRI) const {
+ const MCInstrDesc &Desc = MemI.getDesc();
+ int MemRefBegin = X86II::getMemoryOperandNo(Desc.TSFlags);
+ if (MemRefBegin < 0)
+ return None;
+
+ MemRefBegin += X86II::getOperandBias(Desc);
+
+ auto &BaseOp = MemI.getOperand(MemRefBegin + X86::AddrBaseReg);
+ if (!BaseOp.isReg()) // Can be an MO_FrameIndex
+ return None;
+
+ const MachineOperand &DispMO = MemI.getOperand(MemRefBegin + X86::AddrDisp);
+ // Displacement can be symbolic
+ if (!DispMO.isImm())
+ return None;
+
+ ExtAddrMode AM;
+ AM.BaseReg = BaseOp.getReg();
+ AM.ScaledReg = MemI.getOperand(MemRefBegin + X86::AddrIndexReg).getReg();
+ AM.Scale = MemI.getOperand(MemRefBegin + X86::AddrScaleAmt).getImm();
+ AM.Displacement = DispMO.getImm();
+ return AM;
+}
+
+bool X86InstrInfo::getConstValDefinedInReg(const MachineInstr &MI,
+ const Register Reg,
+ int64_t &ImmVal) const {
+ if (MI.getOpcode() != X86::MOV32ri && MI.getOpcode() != X86::MOV64ri)
+ return false;
+ // Mov Src can be a global address.
+ if (!MI.getOperand(1).isImm() || MI.getOperand(0).getReg() != Reg)
+ return false;
+ ImmVal = MI.getOperand(1).getImm();
+ return true;
+}
+
+bool X86InstrInfo::preservesZeroValueInReg(
+ const MachineInstr *MI, const Register NullValueReg,
+ const TargetRegisterInfo *TRI) const {
+ if (!MI->modifiesRegister(NullValueReg, TRI))
+ return true;
+ switch (MI->getOpcode()) {
+ // Shift right/left of a null unto itself is still a null, i.e. rax = shl rax
+ // X.
+ case X86::SHR64ri:
+ case X86::SHR32ri:
+ case X86::SHL64ri:
+ case X86::SHL32ri:
+ assert(MI->getOperand(0).isDef() && MI->getOperand(1).isUse() &&
+ "expected for shift opcode!");
+ return MI->getOperand(0).getReg() == NullValueReg &&
+ MI->getOperand(1).getReg() == NullValueReg;
+ // Zero extend of a sub-reg of NullValueReg into itself does not change the
+ // null value.
+ case X86::MOV32rr:
+ return llvm::all_of(MI->operands(), [&](const MachineOperand &MO) {
+ return TRI->isSubRegisterEq(NullValueReg, MO.getReg());
+ });
+ default:
+ return false;
+ }
+ llvm_unreachable("Should be handled above!");
+}
+
bool X86InstrInfo::getMemOperandsWithOffsetWidth(
const MachineInstr &MemOp, SmallVectorImpl<const MachineOperand *> &BaseOps,
int64_t &Offset, bool &OffsetIsScalable, unsigned &Width,
@@ -3775,17 +3775,17 @@ bool X86InstrInfo::getMemOperandsWithOffsetWidth(
return true;
}
-static unsigned getStoreRegOpcode(Register SrcReg,
+static unsigned getStoreRegOpcode(Register SrcReg,
const TargetRegisterClass *RC,
- bool IsStackAligned,
+ bool IsStackAligned,
const X86Subtarget &STI) {
- return getLoadStoreRegOpcode(SrcReg, RC, IsStackAligned, STI, false);
+ return getLoadStoreRegOpcode(SrcReg, RC, IsStackAligned, STI, false);
}
-static unsigned getLoadRegOpcode(Register DestReg,
+static unsigned getLoadRegOpcode(Register DestReg,
const TargetRegisterClass *RC,
- bool IsStackAligned, const X86Subtarget &STI) {
- return getLoadStoreRegOpcode(DestReg, RC, IsStackAligned, STI, true);
+ bool IsStackAligned, const X86Subtarget &STI) {
+ return getLoadStoreRegOpcode(DestReg, RC, IsStackAligned, STI, true);
}
void X86InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
@@ -3796,31 +3796,31 @@ void X86InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
const MachineFunction &MF = *MBB.getParent();
assert(MF.getFrameInfo().getObjectSize(FrameIdx) >= TRI->getSpillSize(*RC) &&
"Stack slot too small for store");
- if (RC->getID() == X86::TILERegClassID) {
- unsigned Opc = X86::TILESTORED;
- // tilestored %tmm, (%sp, %idx)
- MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
- Register VirtReg = RegInfo.createVirtualRegister(&X86::GR64_NOSPRegClass);
- BuildMI(MBB, MI, DebugLoc(), get(X86::MOV64ri), VirtReg).addImm(64);
- MachineInstr *NewMI =
- addFrameReference(BuildMI(MBB, MI, DebugLoc(), get(Opc)), FrameIdx)
- .addReg(SrcReg, getKillRegState(isKill));
- MachineOperand &MO = NewMI->getOperand(2);
- MO.setReg(VirtReg);
- MO.setIsKill(true);
- } else if (RC->getID() == X86::TILECFGRegClassID) {
- unsigned Opc = X86::PSTTILECFG;
- addFrameReference(BuildMI(MBB, MI, DebugLoc(), get(Opc)), FrameIdx)
- .addReg(SrcReg, getKillRegState(isKill));
- } else {
- unsigned Alignment = std::max<uint32_t>(TRI->getSpillSize(*RC), 16);
- bool isAligned =
- (Subtarget.getFrameLowering()->getStackAlign() >= Alignment) ||
- RI.canRealignStack(MF);
- unsigned Opc = getStoreRegOpcode(SrcReg, RC, isAligned, Subtarget);
- addFrameReference(BuildMI(MBB, MI, DebugLoc(), get(Opc)), FrameIdx)
- .addReg(SrcReg, getKillRegState(isKill));
- }
+ if (RC->getID() == X86::TILERegClassID) {
+ unsigned Opc = X86::TILESTORED;
+ // tilestored %tmm, (%sp, %idx)
+ MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
+ Register VirtReg = RegInfo.createVirtualRegister(&X86::GR64_NOSPRegClass);
+ BuildMI(MBB, MI, DebugLoc(), get(X86::MOV64ri), VirtReg).addImm(64);
+ MachineInstr *NewMI =
+ addFrameReference(BuildMI(MBB, MI, DebugLoc(), get(Opc)), FrameIdx)
+ .addReg(SrcReg, getKillRegState(isKill));
+ MachineOperand &MO = NewMI->getOperand(2);
+ MO.setReg(VirtReg);
+ MO.setIsKill(true);
+ } else if (RC->getID() == X86::TILECFGRegClassID) {
+ unsigned Opc = X86::PSTTILECFG;
+ addFrameReference(BuildMI(MBB, MI, DebugLoc(), get(Opc)), FrameIdx)
+ .addReg(SrcReg, getKillRegState(isKill));
+ } else {
+ unsigned Alignment = std::max<uint32_t>(TRI->getSpillSize(*RC), 16);
+ bool isAligned =
+ (Subtarget.getFrameLowering()->getStackAlign() >= Alignment) ||
+ RI.canRealignStack(MF);
+ unsigned Opc = getStoreRegOpcode(SrcReg, RC, isAligned, Subtarget);
+ addFrameReference(BuildMI(MBB, MI, DebugLoc(), get(Opc)), FrameIdx)
+ .addReg(SrcReg, getKillRegState(isKill));
+ }
}
void X86InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
@@ -3828,32 +3828,32 @@ void X86InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
Register DestReg, int FrameIdx,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const {
- if (RC->getID() == X86::TILERegClassID) {
- unsigned Opc = X86::TILELOADD;
- // tileloadd (%sp, %idx), %tmm
- MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
- Register VirtReg = RegInfo.createVirtualRegister(&X86::GR64_NOSPRegClass);
- MachineInstr *NewMI =
- BuildMI(MBB, MI, DebugLoc(), get(X86::MOV64ri), VirtReg).addImm(64);
- NewMI = addFrameReference(BuildMI(MBB, MI, DebugLoc(), get(Opc), DestReg),
- FrameIdx);
- MachineOperand &MO = NewMI->getOperand(3);
- MO.setReg(VirtReg);
- MO.setIsKill(true);
- } else if (RC->getID() == X86::TILECFGRegClassID) {
- unsigned Opc = X86::PLDTILECFG;
- addFrameReference(BuildMI(MBB, MI, DebugLoc(), get(Opc), DestReg),
- FrameIdx);
- } else {
- const MachineFunction &MF = *MBB.getParent();
- unsigned Alignment = std::max<uint32_t>(TRI->getSpillSize(*RC), 16);
- bool isAligned =
- (Subtarget.getFrameLowering()->getStackAlign() >= Alignment) ||
- RI.canRealignStack(MF);
- unsigned Opc = getLoadRegOpcode(DestReg, RC, isAligned, Subtarget);
- addFrameReference(BuildMI(MBB, MI, DebugLoc(), get(Opc), DestReg),
- FrameIdx);
- }
+ if (RC->getID() == X86::TILERegClassID) {
+ unsigned Opc = X86::TILELOADD;
+ // tileloadd (%sp, %idx), %tmm
+ MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
+ Register VirtReg = RegInfo.createVirtualRegister(&X86::GR64_NOSPRegClass);
+ MachineInstr *NewMI =
+ BuildMI(MBB, MI, DebugLoc(), get(X86::MOV64ri), VirtReg).addImm(64);
+ NewMI = addFrameReference(BuildMI(MBB, MI, DebugLoc(), get(Opc), DestReg),
+ FrameIdx);
+ MachineOperand &MO = NewMI->getOperand(3);
+ MO.setReg(VirtReg);
+ MO.setIsKill(true);
+ } else if (RC->getID() == X86::TILECFGRegClassID) {
+ unsigned Opc = X86::PLDTILECFG;
+ addFrameReference(BuildMI(MBB, MI, DebugLoc(), get(Opc), DestReg),
+ FrameIdx);
+ } else {
+ const MachineFunction &MF = *MBB.getParent();
+ unsigned Alignment = std::max<uint32_t>(TRI->getSpillSize(*RC), 16);
+ bool isAligned =
+ (Subtarget.getFrameLowering()->getStackAlign() >= Alignment) ||
+ RI.canRealignStack(MF);
+ unsigned Opc = getLoadRegOpcode(DestReg, RC, isAligned, Subtarget);
+ addFrameReference(BuildMI(MBB, MI, DebugLoc(), get(Opc), DestReg),
+ FrameIdx);
+ }
}
bool X86InstrInfo::analyzeCompare(const MachineInstr &MI, Register &SrcReg,
@@ -4416,7 +4416,7 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
/// instructions in-between do not load or store, and have no side effects.
MachineInstr *X86InstrInfo::optimizeLoadInstr(MachineInstr &MI,
const MachineRegisterInfo *MRI,
- Register &FoldAsLoadDefReg,
+ Register &FoldAsLoadDefReg,
MachineInstr *&DefMI) const {
// Check whether we can move DefMI here.
DefMI = MRI->getVRegDef(FoldAsLoadDefReg);
@@ -4479,8 +4479,8 @@ static bool Expand2AddrUndef(MachineInstrBuilder &MIB,
/// %k4 = K_SET1
/// to:
/// %k4 = KXNORrr %k0, %k0
-static bool Expand2AddrKreg(MachineInstrBuilder &MIB, const MCInstrDesc &Desc,
- Register Reg) {
+static bool Expand2AddrKreg(MachineInstrBuilder &MIB, const MCInstrDesc &Desc,
+ Register Reg) {
assert(Desc.getNumOperands() == 3 && "Expected two-addr instruction.");
MIB->setDesc(Desc);
MIB.addReg(Reg, RegState::Undef).addReg(Reg, RegState::Undef);
@@ -4926,7 +4926,7 @@ unsigned X86InstrInfo::getPartialRegUpdateClearance(
// If MI is marked as reading Reg, the partial register update is wanted.
const MachineOperand &MO = MI.getOperand(0);
Register Reg = MO.getReg();
- if (Reg.isVirtual()) {
+ if (Reg.isVirtual()) {
if (MO.readsReg() || MI.readsVirtualRegister(Reg))
return 0;
} else {
@@ -5224,12 +5224,12 @@ static bool hasUndefRegUpdate(unsigned Opcode, unsigned OpNum,
/// Like getPartialRegUpdateClearance, this makes a strong assumption that the
/// high bits that are passed-through are not live.
unsigned
-X86InstrInfo::getUndefRegClearance(const MachineInstr &MI, unsigned OpNum,
+X86InstrInfo::getUndefRegClearance(const MachineInstr &MI, unsigned OpNum,
const TargetRegisterInfo *TRI) const {
- const MachineOperand &MO = MI.getOperand(OpNum);
- if (Register::isPhysicalRegister(MO.getReg()) &&
- hasUndefRegUpdate(MI.getOpcode(), OpNum))
- return UndefRegClearance;
+ const MachineOperand &MO = MI.getOperand(OpNum);
+ if (Register::isPhysicalRegister(MO.getReg()) &&
+ hasUndefRegUpdate(MI.getOpcode(), OpNum))
+ return UndefRegClearance;
return 0;
}
@@ -5311,7 +5311,7 @@ static void updateOperandRegConstraints(MachineFunction &MF,
if (!MO.isReg())
continue;
Register Reg = MO.getReg();
- if (!Reg.isVirtual())
+ if (!Reg.isVirtual())
continue;
auto *NewRC = MRI.constrainRegClass(
@@ -5562,10 +5562,10 @@ MachineInstr *X86InstrInfo::foldMemoryOperandImpl(
if (I != nullptr) {
unsigned Opcode = I->DstOp;
- bool FoldedLoad =
- isTwoAddrFold || (OpNum == 0 && I->Flags & TB_FOLDED_LOAD) || OpNum > 0;
- bool FoldedStore =
- isTwoAddrFold || (OpNum == 0 && I->Flags & TB_FOLDED_STORE);
+ bool FoldedLoad =
+ isTwoAddrFold || (OpNum == 0 && I->Flags & TB_FOLDED_LOAD) || OpNum > 0;
+ bool FoldedStore =
+ isTwoAddrFold || (OpNum == 0 && I->Flags & TB_FOLDED_STORE);
MaybeAlign MinAlign =
decodeMaybeAlign((I->Flags & TB_ALIGN_MASK) >> TB_ALIGN_SHIFT);
if (MinAlign && Alignment < *MinAlign)
@@ -5576,25 +5576,25 @@ MachineInstr *X86InstrInfo::foldMemoryOperandImpl(
const TargetRegisterClass *RC = getRegClass(MI.getDesc(), OpNum,
&RI, MF);
unsigned RCSize = TRI.getRegSizeInBits(*RC) / 8;
- // Check if it's safe to fold the load. If the size of the object is
- // narrower than the load width, then it's not.
- // FIXME: Allow scalar intrinsic instructions like ADDSSrm_Int.
- if (FoldedLoad && Size < RCSize) {
+ // Check if it's safe to fold the load. If the size of the object is
+ // narrower than the load width, then it's not.
+ // FIXME: Allow scalar intrinsic instructions like ADDSSrm_Int.
+ if (FoldedLoad && Size < RCSize) {
// If this is a 64-bit load, but the spill slot is 32, then we can do
// a 32-bit load which is implicitly zero-extended. This likely is
// due to live interval analysis remat'ing a load from stack slot.
- if (Opcode != X86::MOV64rm || RCSize != 8 || Size != 4)
- return nullptr;
+ if (Opcode != X86::MOV64rm || RCSize != 8 || Size != 4)
+ return nullptr;
if (MI.getOperand(0).getSubReg() || MI.getOperand(1).getSubReg())
return nullptr;
Opcode = X86::MOV32rm;
NarrowToMOV32rm = true;
}
- // For stores, make sure the size of the object is equal to the size of
- // the store. If the object is larger, the extra bits would be garbage. If
- // the object is smaller we might overwrite another object or fault.
- if (FoldedStore && Size != RCSize)
- return nullptr;
+ // For stores, make sure the size of the object is equal to the size of
+ // the store. If the object is larger, the extra bits would be garbage. If
+ // the object is smaller we might overwrite another object or fault.
+ if (FoldedStore && Size != RCSize)
+ return nullptr;
}
if (isTwoAddrFold)
@@ -5607,7 +5607,7 @@ MachineInstr *X86InstrInfo::foldMemoryOperandImpl(
// value and zero-extend the top bits. Change the destination register
// to a 32-bit one.
Register DstReg = NewMI->getOperand(0).getReg();
- if (DstReg.isPhysical())
+ if (DstReg.isPhysical())
NewMI->getOperand(0).setReg(RI.getSubReg(DstReg, X86::sub_32bit));
else
NewMI->getOperand(0).setSubReg(X86::sub_32bit);
@@ -6464,7 +6464,7 @@ X86InstrInfo::unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N,
}
if (Load)
BeforeOps.push_back(SDValue(Load, 0));
- llvm::append_range(BeforeOps, AfterOps);
+ llvm::append_range(BeforeOps, AfterOps);
// Change CMP32ri r, 0 back to TEST32rr r, r, etc.
switch (Opc) {
default: break;
@@ -6782,18 +6782,18 @@ bool X86InstrInfo::shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
return true;
}
-bool X86InstrInfo::isSchedulingBoundary(const MachineInstr &MI,
- const MachineBasicBlock *MBB,
- const MachineFunction &MF) const {
-
- // ENDBR instructions should not be scheduled around.
- unsigned Opcode = MI.getOpcode();
- if (Opcode == X86::ENDBR64 || Opcode == X86::ENDBR32)
- return true;
-
- return TargetInstrInfo::isSchedulingBoundary(MI, MBB, MF);
-}
-
+bool X86InstrInfo::isSchedulingBoundary(const MachineInstr &MI,
+ const MachineBasicBlock *MBB,
+ const MachineFunction &MF) const {
+
+ // ENDBR instructions should not be scheduled around.
+ unsigned Opcode = MI.getOpcode();
+ if (Opcode == X86::ENDBR64 || Opcode == X86::ENDBR32)
+ return true;
+
+ return TargetInstrInfo::isSchedulingBoundary(MI, MBB, MF);
+}
+
bool X86InstrInfo::
reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
assert(Cond.size() == 1 && "Invalid X86 branch condition!");
@@ -6824,7 +6824,7 @@ unsigned X86InstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
"X86-64 PIC uses RIP relative addressing");
X86MachineFunctionInfo *X86FI = MF->getInfo<X86MachineFunctionInfo>();
- Register GlobalBaseReg = X86FI->getGlobalBaseReg();
+ Register GlobalBaseReg = X86FI->getGlobalBaseReg();
if (GlobalBaseReg != 0)
return GlobalBaseReg;
@@ -8380,7 +8380,7 @@ describeMOVrrLoadedValue(const MachineInstr &MI, Register DescribedReg,
// If the described register is a sub-register of the destination register,
// then pick out the source register's corresponding sub-register.
if (unsigned SubRegIdx = TRI->getSubRegIndex(DestReg, DescribedReg)) {
- Register SrcSubReg = TRI->getSubReg(SrcReg, SubRegIdx);
+ Register SrcSubReg = TRI->getSubReg(SrcReg, SubRegIdx);
return ParamLoadedValue(MachineOperand::CreateReg(SrcSubReg, false), Expr);
}
@@ -8644,7 +8644,7 @@ namespace {
return false;
X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
- Register GlobalBaseReg = X86FI->getGlobalBaseReg();
+ Register GlobalBaseReg = X86FI->getGlobalBaseReg();
// If we didn't need a GlobalBaseReg, don't insert code.
if (GlobalBaseReg == 0)
@@ -8657,7 +8657,7 @@ namespace {
MachineRegisterInfo &RegInfo = MF.getRegInfo();
const X86InstrInfo *TII = STI.getInstrInfo();
- Register PC;
+ Register PC;
if (STI.isPICStyleGOT())
PC = RegInfo.createVirtualRegister(&X86::GR32RegClass);
else
@@ -8727,7 +8727,7 @@ namespace {
MachineFunctionPass::getAnalysisUsage(AU);
}
};
-} // namespace
+} // namespace
char CGBR::ID = 0;
FunctionPass*
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrInfo.h b/contrib/libs/llvm12/lib/Target/X86/X86InstrInfo.h
index 6b0f1a9f14..d7d2370c6f 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrInfo.h
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrInfo.h
@@ -317,17 +317,17 @@ public:
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const override;
- Optional<ExtAddrMode>
- getAddrModeFromMemoryOp(const MachineInstr &MemI,
- const TargetRegisterInfo *TRI) const override;
-
- bool getConstValDefinedInReg(const MachineInstr &MI, const Register Reg,
- int64_t &ImmVal) const override;
-
- bool preservesZeroValueInReg(const MachineInstr *MI,
- const Register NullValueReg,
- const TargetRegisterInfo *TRI) const override;
-
+ Optional<ExtAddrMode>
+ getAddrModeFromMemoryOp(const MachineInstr &MemI,
+ const TargetRegisterInfo *TRI) const override;
+
+ bool getConstValDefinedInReg(const MachineInstr &MI, const Register Reg,
+ int64_t &ImmVal) const override;
+
+ bool preservesZeroValueInReg(const MachineInstr *MI,
+ const Register NullValueReg,
+ const TargetRegisterInfo *TRI) const override;
+
bool getMemOperandsWithOffsetWidth(
const MachineInstr &LdSt,
SmallVectorImpl<const MachineOperand *> &BaseOps, int64_t &Offset,
@@ -420,13 +420,13 @@ public:
bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, int64_t &Offset1,
int64_t &Offset2) const override;
- /// isSchedulingBoundary - Overrides the isSchedulingBoundary from
- /// Codegen/TargetInstrInfo.cpp to make it capable of identifying ENDBR
- /// intructions and prevent it from being re-scheduled.
- bool isSchedulingBoundary(const MachineInstr &MI,
- const MachineBasicBlock *MBB,
- const MachineFunction &MF) const override;
-
+ /// isSchedulingBoundary - Overrides the isSchedulingBoundary from
+ /// Codegen/TargetInstrInfo.cpp to make it capable of identifying ENDBR
+ /// intructions and prevent it from being re-scheduled.
+ bool isSchedulingBoundary(const MachineInstr &MI,
+ const MachineBasicBlock *MBB,
+ const MachineFunction &MF) const override;
+
/// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to
/// determine (in conjunction with areLoadsFromSameBasePtr) if two loads
/// should be scheduled togther. On some targets if two loads are loading from
@@ -470,7 +470,7 @@ public:
unsigned
getPartialRegUpdateClearance(const MachineInstr &MI, unsigned OpNum,
const TargetRegisterInfo *TRI) const override;
- unsigned getUndefRegClearance(const MachineInstr &MI, unsigned OpNum,
+ unsigned getUndefRegClearance(const MachineInstr &MI, unsigned OpNum,
const TargetRegisterInfo *TRI) const override;
void breakPartialRegDependency(MachineInstr &MI, unsigned OpNum,
const TargetRegisterInfo *TRI) const override;
@@ -525,7 +525,7 @@ public:
/// the machine instruction generated due to folding.
MachineInstr *optimizeLoadInstr(MachineInstr &MI,
const MachineRegisterInfo *MRI,
- Register &FoldAsLoadDefReg,
+ Register &FoldAsLoadDefReg,
MachineInstr *&DefMI) const override;
std::pair<unsigned, unsigned>
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrInfo.td b/contrib/libs/llvm12/lib/Target/X86/X86InstrInfo.td
index 94e85df086..b006d1d9aa 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrInfo.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrInfo.td
@@ -69,8 +69,8 @@ def SDTX86wrpkru : SDTypeProfile<0, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
def SDTX86cas : SDTypeProfile<0, 3, [SDTCisPtrTy<0>, SDTCisInt<1>,
SDTCisVT<2, i8>]>;
-def SDTX86cas8pair : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
-def SDTX86cas16pair : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i64>]>;
+def SDTX86cas8pair : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
+def SDTX86cas16pair : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i64>]>;
def SDTLockBinaryArithWithFlags : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
SDTCisPtrTy<1>,
@@ -94,11 +94,11 @@ def SDT_X86VASTART_SAVE_XMM_REGS : SDTypeProfile<0, -1, [SDTCisVT<0, i8>,
SDTCisVT<1, iPTR>,
SDTCisVT<2, iPTR>]>;
-def SDT_X86VAARG : SDTypeProfile<1, -1, [SDTCisPtrTy<0>,
- SDTCisPtrTy<1>,
- SDTCisVT<2, i32>,
- SDTCisVT<3, i8>,
- SDTCisVT<4, i32>]>;
+def SDT_X86VAARG : SDTypeProfile<1, -1, [SDTCisPtrTy<0>,
+ SDTCisPtrTy<1>,
+ SDTCisVT<2, i32>,
+ SDTCisVT<3, i8>,
+ SDTCisVT<4, i32>]>;
def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
@@ -127,11 +127,11 @@ def SDT_X86MEMBARRIER : SDTypeProfile<0, 0, []>;
def SDT_X86ENQCMD : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
SDTCisPtrTy<1>, SDTCisSameAs<1, 2>]>;
-def SDT_X86AESENCDECKL : SDTypeProfile<2, 2, [SDTCisVT<0, v2i64>,
- SDTCisVT<1, i32>,
- SDTCisVT<2, v2i64>,
- SDTCisPtrTy<3>]>;
-
+def SDT_X86AESENCDECKL : SDTypeProfile<2, 2, [SDTCisVT<0, v2i64>,
+ SDTCisVT<1, i32>,
+ SDTCisVT<2, v2i64>,
+ SDTCisPtrTy<3>]>;
+
def X86MemBarrier : SDNode<"X86ISD::MEMBARRIER", SDT_X86MEMBARRIER,
[SDNPHasChain,SDNPSideEffect]>;
def X86MFence : SDNode<"X86ISD::MFENCE", SDT_X86MEMBARRIER,
@@ -169,10 +169,10 @@ def X86wrpkru : SDNode<"X86ISD::WRPKRU", SDTX86wrpkru,
def X86cas : SDNode<"X86ISD::LCMPXCHG_DAG", SDTX86cas,
[SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
SDNPMayLoad, SDNPMemOperand]>;
-def X86cas8 : SDNode<"X86ISD::LCMPXCHG8_DAG", SDTX86cas8pair,
+def X86cas8 : SDNode<"X86ISD::LCMPXCHG8_DAG", SDTX86cas8pair,
[SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
SDNPMayLoad, SDNPMemOperand]>;
-def X86cas16 : SDNode<"X86ISD::LCMPXCHG16_DAG", SDTX86cas16pair,
+def X86cas16 : SDNode<"X86ISD::LCMPXCHG16_DAG", SDTX86cas16pair,
[SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
SDNPMayLoad, SDNPMemOperand]>;
@@ -186,13 +186,13 @@ def X86vastart_save_xmm_regs :
SDT_X86VASTART_SAVE_XMM_REGS,
[SDNPHasChain, SDNPVariadic]>;
def X86vaarg64 :
- SDNode<"X86ISD::VAARG_64", SDT_X86VAARG,
+ SDNode<"X86ISD::VAARG_64", SDT_X86VAARG,
+ [SDNPHasChain, SDNPMayLoad, SDNPMayStore,
+ SDNPMemOperand]>;
+def X86vaargx32 :
+ SDNode<"X86ISD::VAARG_X32", SDT_X86VAARG,
[SDNPHasChain, SDNPMayLoad, SDNPMayStore,
SDNPMemOperand]>;
-def X86vaargx32 :
- SDNode<"X86ISD::VAARG_X32", SDT_X86VAARG,
- [SDNPHasChain, SDNPMayLoad, SDNPMayStore,
- SDNPMemOperand]>;
def X86callseq_start :
SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart,
[SDNPHasChain, SDNPOutGlue]>;
@@ -280,7 +280,7 @@ def X86lock_and : SDNode<"X86ISD::LAND", SDTLockBinaryArithWithFlags,
SDNPMemOperand]>;
def X86bextr : SDNode<"X86ISD::BEXTR", SDTIntBinOp>;
-def X86bextri : SDNode<"X86ISD::BEXTRI", SDTIntBinOp>;
+def X86bextri : SDNode<"X86ISD::BEXTRI", SDTIntBinOp>;
def X86bzhi : SDNode<"X86ISD::BZHI", SDTIntBinOp>;
@@ -320,23 +320,23 @@ def X86enqcmd : SDNode<"X86ISD::ENQCMD", SDT_X86ENQCMD,
[SDNPHasChain, SDNPSideEffect]>;
def X86enqcmds : SDNode<"X86ISD::ENQCMDS", SDT_X86ENQCMD,
[SDNPHasChain, SDNPSideEffect]>;
-def X86testui : SDNode<"X86ISD::TESTUI",
- SDTypeProfile<1, 0, [SDTCisVT<0, i32>]>,
- [SDNPHasChain, SDNPSideEffect]>;
-
-def X86aesenc128kl : SDNode<"X86ISD::AESENC128KL", SDT_X86AESENCDECKL,
- [SDNPHasChain, SDNPMayLoad, SDNPSideEffect,
- SDNPMemOperand]>;
-def X86aesdec128kl : SDNode<"X86ISD::AESDEC128KL", SDT_X86AESENCDECKL,
- [SDNPHasChain, SDNPMayLoad, SDNPSideEffect,
- SDNPMemOperand]>;
-def X86aesenc256kl : SDNode<"X86ISD::AESENC256KL", SDT_X86AESENCDECKL,
- [SDNPHasChain, SDNPMayLoad, SDNPSideEffect,
- SDNPMemOperand]>;
-def X86aesdec256kl : SDNode<"X86ISD::AESDEC256KL", SDT_X86AESENCDECKL,
- [SDNPHasChain, SDNPMayLoad, SDNPSideEffect,
- SDNPMemOperand]>;
-
+def X86testui : SDNode<"X86ISD::TESTUI",
+ SDTypeProfile<1, 0, [SDTCisVT<0, i32>]>,
+ [SDNPHasChain, SDNPSideEffect]>;
+
+def X86aesenc128kl : SDNode<"X86ISD::AESENC128KL", SDT_X86AESENCDECKL,
+ [SDNPHasChain, SDNPMayLoad, SDNPSideEffect,
+ SDNPMemOperand]>;
+def X86aesdec128kl : SDNode<"X86ISD::AESDEC128KL", SDT_X86AESENCDECKL,
+ [SDNPHasChain, SDNPMayLoad, SDNPSideEffect,
+ SDNPMemOperand]>;
+def X86aesenc256kl : SDNode<"X86ISD::AESENC256KL", SDT_X86AESENCDECKL,
+ [SDNPHasChain, SDNPMayLoad, SDNPSideEffect,
+ SDNPMemOperand]>;
+def X86aesdec256kl : SDNode<"X86ISD::AESDEC256KL", SDT_X86AESENCDECKL,
+ [SDNPHasChain, SDNPMayLoad, SDNPSideEffect,
+ SDNPMemOperand]>;
+
//===----------------------------------------------------------------------===//
// X86 Operand Definitions.
//
@@ -914,8 +914,8 @@ def PKU : Predicate<"Subtarget->hasPKU()">;
def HasVNNI : Predicate<"Subtarget->hasVNNI()">;
def HasVP2INTERSECT : Predicate<"Subtarget->hasVP2INTERSECT()">;
def HasBF16 : Predicate<"Subtarget->hasBF16()">;
-def HasAVXVNNI : Predicate <"Subtarget->hasAVXVNNI()">;
-def NoVLX_Or_NoVNNI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVNNI()">;
+def HasAVXVNNI : Predicate <"Subtarget->hasAVXVNNI()">;
+def NoVLX_Or_NoVNNI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVNNI()">;
def HasBITALG : Predicate<"Subtarget->hasBITALG()">;
def HasPOPCNT : Predicate<"Subtarget->hasPOPCNT()">;
@@ -979,15 +979,15 @@ def HasCmpxchg8b : Predicate<"Subtarget->hasCmpxchg8b()">;
def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">;
def HasPCONFIG : Predicate<"Subtarget->hasPCONFIG()">;
def HasENQCMD : Predicate<"Subtarget->hasENQCMD()">;
-def HasKL : Predicate<"Subtarget->hasKL()">;
-def HasWIDEKL : Predicate<"Subtarget->hasWIDEKL()">;
-def HasHRESET : Predicate<"Subtarget->hasHRESET()">;
+def HasKL : Predicate<"Subtarget->hasKL()">;
+def HasWIDEKL : Predicate<"Subtarget->hasWIDEKL()">;
+def HasHRESET : Predicate<"Subtarget->hasHRESET()">;
def HasSERIALIZE : Predicate<"Subtarget->hasSERIALIZE()">;
def HasTSXLDTRK : Predicate<"Subtarget->hasTSXLDTRK()">;
def HasAMXTILE : Predicate<"Subtarget->hasAMXTILE()">;
def HasAMXBF16 : Predicate<"Subtarget->hasAMXBF16()">;
def HasAMXINT8 : Predicate<"Subtarget->hasAMXINT8()">;
-def HasUINTR : Predicate<"Subtarget->hasUINTR()">;
+def HasUINTR : Predicate<"Subtarget->hasUINTR()">;
def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
AssemblerPredicate<(all_of (not Mode64Bit)), "Not 64-bit mode">;
def In64BitMode : Predicate<"Subtarget->is64Bit()">,
@@ -1035,7 +1035,7 @@ def HasFastMem32 : Predicate<"!Subtarget->isUnalignedMem32Slow()">;
def HasFastLZCNT : Predicate<"Subtarget->hasFastLZCNT()">;
def HasFastSHLDRotate : Predicate<"Subtarget->hasFastSHLDRotate()">;
def HasERMSB : Predicate<"Subtarget->hasERMSB()">;
-def HasFSRM : Predicate<"Subtarget->hasFSRM()">;
+def HasFSRM : Predicate<"Subtarget->hasFSRM()">;
def HasMFence : Predicate<"Subtarget->hasMFence()">;
def UseIndirectThunkCalls : Predicate<"Subtarget->useIndirectThunkCalls()">;
def NotUseIndirectThunkCalls : Predicate<"!Subtarget->useIndirectThunkCalls()">;
@@ -1073,7 +1073,7 @@ def i16immSExt8 : ImmLeaf<i16, [{ return isInt<8>(Imm); }]>;
def i32immSExt8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>;
def i64immSExt8 : ImmLeaf<i64, [{ return isInt<8>(Imm); }]>;
def i64immSExt32 : ImmLeaf<i64, [{ return isInt<32>(Imm); }]>;
-def i64timmSExt32 : TImmLeaf<i64, [{ return isInt<32>(Imm); }]>;
+def i64timmSExt32 : TImmLeaf<i64, [{ return isInt<32>(Imm); }]>;
def i16relocImmSExt8 : PatLeaf<(i16 relocImm), [{
return isSExtAbsoluteSymbolRef(8, N);
@@ -2679,11 +2679,11 @@ let Predicates = [HasBMI2] in {
//
let Predicates = [HasTBM], Defs = [EFLAGS] in {
-multiclass tbm_bextri<bits<8> opc, RegisterClass RC, string OpcodeStr,
- X86MemOperand x86memop, PatFrag ld_frag,
- SDNode OpNode, Operand immtype,
- SDPatternOperator immoperator,
- X86FoldableSchedWrite Sched> {
+multiclass tbm_bextri<bits<8> opc, RegisterClass RC, string OpcodeStr,
+ X86MemOperand x86memop, PatFrag ld_frag,
+ SDNode OpNode, Operand immtype,
+ SDPatternOperator immoperator,
+ X86FoldableSchedWrite Sched> {
def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl),
!strconcat(OpcodeStr,
"\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
@@ -2697,12 +2697,12 @@ multiclass tbm_bextri<bits<8> opc, RegisterClass RC, string OpcodeStr,
XOP, XOPA, Sched<[Sched.Folded]>;
}
-defm BEXTRI32 : tbm_bextri<0x10, GR32, "bextr{l}", i32mem, loadi32,
- X86bextri, i32imm, timm, WriteBEXTR>;
+defm BEXTRI32 : tbm_bextri<0x10, GR32, "bextr{l}", i32mem, loadi32,
+ X86bextri, i32imm, timm, WriteBEXTR>;
let ImmT = Imm32S in
-defm BEXTRI64 : tbm_bextri<0x10, GR64, "bextr{q}", i64mem, loadi64,
- X86bextri, i64i32imm,
- i64timmSExt32, WriteBEXTR>, VEX_W;
+defm BEXTRI64 : tbm_bextri<0x10, GR64, "bextr{q}", i64mem, loadi64,
+ X86bextri, i64i32imm,
+ i64timmSExt32, WriteBEXTR>, VEX_W;
multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem,
RegisterClass RC, string OpcodeStr,
@@ -2808,7 +2808,7 @@ let SchedRW = [ WriteSystem ] in {
let Uses = [ ECX, EAX, EBX ] in {
def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx",
- []>, TB, Requires<[ HasMWAITX ]>;
+ []>, TB, Requires<[ HasMWAITX ]>;
}
} // SchedRW
@@ -2925,41 +2925,41 @@ def : InstAlias<"clzero\t{%eax|eax}", (CLZERO32r)>, Requires<[Not64BitMode]>;
def : InstAlias<"clzero\t{%rax|rax}", (CLZERO64r)>, Requires<[In64BitMode]>;
//===----------------------------------------------------------------------===//
-// INVLPGB Instruction
-// OPCODE 0F 01 FE
-//
-let SchedRW = [WriteSystem] in {
- let Uses = [EAX, EDX] in
- def INVLPGB32 : I<0x01, MRM_FE, (outs), (ins),
- "invlpgb}", []>,
- PS, Requires<[Not64BitMode]>;
- let Uses = [RAX, EDX] in
- def INVLPGB64 : I<0x01, MRM_FE, (outs), (ins),
- "invlpgb", []>,
- PS, Requires<[In64BitMode]>;
-} // SchedRW
-
-def : InstAlias<"invlpgb\t{%eax, %edx|eax, edx}", (INVLPGB32)>, Requires<[Not64BitMode]>;
-def : InstAlias<"invlpgb\t{%rax, %edx|rax, edx}", (INVLPGB64)>, Requires<[In64BitMode]>;
-
-//===----------------------------------------------------------------------===//
-// TLBSYNC Instruction
-// OPCODE 0F 01 FF
-//
-let SchedRW = [WriteSystem] in {
- def TLBSYNC : I<0x01, MRM_FF, (outs), (ins),
- "tlbsync", []>,
- PS, Requires<[]>;
-} // SchedRW
-
-//===----------------------------------------------------------------------===//
-// HRESET Instruction
-//
-let Uses = [EAX], SchedRW = [WriteSystem] in
- def HRESET : Ii8<0xF0, MRM_C0, (outs), (ins i32u8imm:$imm), "hreset\t$imm", []>,
- Requires<[HasHRESET]>, TAXS;
-
-//===----------------------------------------------------------------------===//
+// INVLPGB Instruction
+// OPCODE 0F 01 FE
+//
+let SchedRW = [WriteSystem] in {
+ let Uses = [EAX, EDX] in
+ def INVLPGB32 : I<0x01, MRM_FE, (outs), (ins),
+ "invlpgb}", []>,
+ PS, Requires<[Not64BitMode]>;
+ let Uses = [RAX, EDX] in
+ def INVLPGB64 : I<0x01, MRM_FE, (outs), (ins),
+ "invlpgb", []>,
+ PS, Requires<[In64BitMode]>;
+} // SchedRW
+
+def : InstAlias<"invlpgb\t{%eax, %edx|eax, edx}", (INVLPGB32)>, Requires<[Not64BitMode]>;
+def : InstAlias<"invlpgb\t{%rax, %edx|rax, edx}", (INVLPGB64)>, Requires<[In64BitMode]>;
+
+//===----------------------------------------------------------------------===//
+// TLBSYNC Instruction
+// OPCODE 0F 01 FF
+//
+let SchedRW = [WriteSystem] in {
+ def TLBSYNC : I<0x01, MRM_FF, (outs), (ins),
+ "tlbsync", []>,
+ PS, Requires<[]>;
+} // SchedRW
+
+//===----------------------------------------------------------------------===//
+// HRESET Instruction
+//
+let Uses = [EAX], SchedRW = [WriteSystem] in
+ def HRESET : Ii8<0xF0, MRM_C0, (outs), (ins i32u8imm:$imm), "hreset\t$imm", []>,
+ Requires<[HasHRESET]>, TAXS;
+
+//===----------------------------------------------------------------------===//
// SERIALIZE Instruction
//
def SERIALIZE : I<0x01, MRM_E8, (outs), (ins), "serialize",
@@ -2977,25 +2977,25 @@ let Predicates = [HasTSXLDTRK] in {
}
//===----------------------------------------------------------------------===//
-// UINTR Instructions
-//
-let Predicates = [HasUINTR, In64BitMode] in {
- def UIRET : I<0x01, MRM_EC, (outs), (ins), "uiret",
- []>, XS;
- def CLUI : I<0x01, MRM_EE, (outs), (ins), "clui",
- [(int_x86_clui)]>, XS;
- def STUI : I<0x01, MRM_EF, (outs), (ins), "stui",
- [(int_x86_stui)]>, XS;
-
- def SENDUIPI : I<0xC7, MRM6r, (outs), (ins GR64:$arg), "senduipi\t$arg",
- [(int_x86_senduipi GR64:$arg)]>, XS;
-
- let Defs = [EFLAGS] in
- def TESTUI : I<0x01, MRM_ED, (outs), (ins), "testui",
- [(set EFLAGS, (X86testui))]>, XS;
-}
-
-//===----------------------------------------------------------------------===//
+// UINTR Instructions
+//
+let Predicates = [HasUINTR, In64BitMode] in {
+ def UIRET : I<0x01, MRM_EC, (outs), (ins), "uiret",
+ []>, XS;
+ def CLUI : I<0x01, MRM_EE, (outs), (ins), "clui",
+ [(int_x86_clui)]>, XS;
+ def STUI : I<0x01, MRM_EF, (outs), (ins), "stui",
+ [(int_x86_stui)]>, XS;
+
+ def SENDUIPI : I<0xC7, MRM6r, (outs), (ins GR64:$arg), "senduipi\t$arg",
+ [(int_x86_senduipi GR64:$arg)]>, XS;
+
+ let Defs = [EFLAGS] in
+ def TESTUI : I<0x01, MRM_ED, (outs), (ins), "testui",
+ [(set EFLAGS, (X86testui))]>, XS;
+}
+
+//===----------------------------------------------------------------------===//
// Pattern fragments to auto generate TBM instructions.
//===----------------------------------------------------------------------===//
@@ -3154,16 +3154,16 @@ include "X86InstrMPX.td"
include "X86InstrVMX.td"
include "X86InstrSVM.td"
-include "X86InstrSNP.td"
+include "X86InstrSNP.td"
include "X86InstrTSX.td"
include "X86InstrSGX.td"
-include "X86InstrTDX.td"
-
-// Key Locker instructions
-include "X86InstrKL.td"
-
+include "X86InstrTDX.td"
+
+// Key Locker instructions
+include "X86InstrKL.td"
+
// AMX instructions
include "X86InstrAMX.td"
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrKL.td b/contrib/libs/llvm12/lib/Target/X86/X86InstrKL.td
index 6f2fbb56e1..b91e563a15 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrKL.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrKL.td
@@ -1,86 +1,86 @@
-//===---------------------------*-tablegen-*-------------------------------===//
-//===------------- X86InstrKL.td - KL Instruction Set Extension -----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file describes the instructions that make up the Intel key locker
-// instruction set.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-// Key Locker instructions
-
-let SchedRW = [WriteSystem], Predicates = [HasKL] in {
- let Uses = [XMM0, EAX], Defs = [EFLAGS] in {
- def LOADIWKEY : I<0xDC, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
- "loadiwkey\t{$src2, $src1|$src1, $src2}",
- [(int_x86_loadiwkey XMM0, VR128:$src1, VR128:$src2, EAX)]>, T8XS,
- NotMemoryFoldable;
- }
-
- let Uses = [XMM0], Defs = [XMM0, XMM1, XMM2, XMM4, XMM5, XMM6, EFLAGS] in {
- def ENCODEKEY128 : I<0xFA, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
- "encodekey128\t{$src, $dst|$dst, $src}", []>, T8XS,
- NotMemoryFoldable;
- }
-
- let Uses = [XMM0, XMM1], Defs = [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, EFLAGS] in {
- def ENCODEKEY256 : I<0xFB, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
- "encodekey256\t{$src, $dst|$dst, $src}", []>, T8XS,
- NotMemoryFoldable;
- }
-
- let Constraints = "$src1 = $dst",
- Defs = [EFLAGS] in {
- def AESENC128KL : I<0xDC, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, opaquemem:$src2),
- "aesenc128kl\t{$src2, $src1|$src1, $src2}",
- [(set VR128:$dst, EFLAGS,
- (X86aesenc128kl VR128:$src1, addr:$src2))]>, T8XS,
- NotMemoryFoldable;
-
- def AESDEC128KL : I<0xDD, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, opaquemem:$src2),
- "aesdec128kl\t{$src2, $src1|$src1, $src2}",
- [(set VR128:$dst, EFLAGS,
- (X86aesdec128kl VR128:$src1, addr:$src2))]>, T8XS,
- NotMemoryFoldable;
-
- def AESENC256KL : I<0xDE, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, opaquemem:$src2),
- "aesenc256kl\t{$src2, $src1|$src1, $src2}",
- [(set VR128:$dst, EFLAGS,
- (X86aesenc256kl VR128:$src1, addr:$src2))]>, T8XS,
- NotMemoryFoldable;
-
- def AESDEC256KL : I<0xDF, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, opaquemem:$src2),
- "aesdec256kl\t{$src2, $src1|$src1, $src2}",
- [(set VR128:$dst, EFLAGS,
- (X86aesdec256kl VR128:$src1, addr:$src2))]>, T8XS,
- NotMemoryFoldable;
- }
-
-} // SchedRW, Predicates
-
-let SchedRW = [WriteSystem], Predicates = [HasWIDEKL] in {
- let Uses = [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7],
- Defs = [EFLAGS, XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7],
- mayLoad = 1 in {
- def AESENCWIDE128KL : I<0xD8, MRM0m, (outs), (ins opaquemem:$src),
- "aesencwide128kl\t$src", []>, T8XS,
- NotMemoryFoldable;
- def AESDECWIDE128KL : I<0xD8, MRM1m, (outs), (ins opaquemem:$src),
- "aesdecwide128kl\t$src", []>, T8XS,
- NotMemoryFoldable;
- def AESENCWIDE256KL : I<0xD8, MRM2m, (outs), (ins opaquemem:$src),
- "aesencwide256kl\t$src", []>, T8XS,
- NotMemoryFoldable;
- def AESDECWIDE256KL : I<0xD8, MRM3m, (outs), (ins opaquemem:$src),
- "aesdecwide256kl\t$src", []>, T8XS,
- NotMemoryFoldable;
- }
-
-} // SchedRW, Predicates
+//===---------------------------*-tablegen-*-------------------------------===//
+//===------------- X86InstrKL.td - KL Instruction Set Extension -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the instructions that make up the Intel key locker
+// instruction set.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Key Locker instructions
+
+let SchedRW = [WriteSystem], Predicates = [HasKL] in {
+ let Uses = [XMM0, EAX], Defs = [EFLAGS] in {
+ def LOADIWKEY : I<0xDC, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
+ "loadiwkey\t{$src2, $src1|$src1, $src2}",
+ [(int_x86_loadiwkey XMM0, VR128:$src1, VR128:$src2, EAX)]>, T8XS,
+ NotMemoryFoldable;
+ }
+
+ let Uses = [XMM0], Defs = [XMM0, XMM1, XMM2, XMM4, XMM5, XMM6, EFLAGS] in {
+ def ENCODEKEY128 : I<0xFA, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
+ "encodekey128\t{$src, $dst|$dst, $src}", []>, T8XS,
+ NotMemoryFoldable;
+ }
+
+ let Uses = [XMM0, XMM1], Defs = [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, EFLAGS] in {
+ def ENCODEKEY256 : I<0xFB, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
+ "encodekey256\t{$src, $dst|$dst, $src}", []>, T8XS,
+ NotMemoryFoldable;
+ }
+
+ let Constraints = "$src1 = $dst",
+ Defs = [EFLAGS] in {
+ def AESENC128KL : I<0xDC, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, opaquemem:$src2),
+ "aesenc128kl\t{$src2, $src1|$src1, $src2}",
+ [(set VR128:$dst, EFLAGS,
+ (X86aesenc128kl VR128:$src1, addr:$src2))]>, T8XS,
+ NotMemoryFoldable;
+
+ def AESDEC128KL : I<0xDD, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, opaquemem:$src2),
+ "aesdec128kl\t{$src2, $src1|$src1, $src2}",
+ [(set VR128:$dst, EFLAGS,
+ (X86aesdec128kl VR128:$src1, addr:$src2))]>, T8XS,
+ NotMemoryFoldable;
+
+ def AESENC256KL : I<0xDE, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, opaquemem:$src2),
+ "aesenc256kl\t{$src2, $src1|$src1, $src2}",
+ [(set VR128:$dst, EFLAGS,
+ (X86aesenc256kl VR128:$src1, addr:$src2))]>, T8XS,
+ NotMemoryFoldable;
+
+ def AESDEC256KL : I<0xDF, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, opaquemem:$src2),
+ "aesdec256kl\t{$src2, $src1|$src1, $src2}",
+ [(set VR128:$dst, EFLAGS,
+ (X86aesdec256kl VR128:$src1, addr:$src2))]>, T8XS,
+ NotMemoryFoldable;
+ }
+
+} // SchedRW, Predicates
+
+let SchedRW = [WriteSystem], Predicates = [HasWIDEKL] in {
+ let Uses = [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7],
+ Defs = [EFLAGS, XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7],
+ mayLoad = 1 in {
+ def AESENCWIDE128KL : I<0xD8, MRM0m, (outs), (ins opaquemem:$src),
+ "aesencwide128kl\t$src", []>, T8XS,
+ NotMemoryFoldable;
+ def AESDECWIDE128KL : I<0xD8, MRM1m, (outs), (ins opaquemem:$src),
+ "aesdecwide128kl\t$src", []>, T8XS,
+ NotMemoryFoldable;
+ def AESENCWIDE256KL : I<0xD8, MRM2m, (outs), (ins opaquemem:$src),
+ "aesencwide256kl\t$src", []>, T8XS,
+ NotMemoryFoldable;
+ def AESDECWIDE256KL : I<0xD8, MRM3m, (outs), (ins opaquemem:$src),
+ "aesdecwide256kl\t$src", []>, T8XS,
+ NotMemoryFoldable;
+ }
+
+} // SchedRW, Predicates
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrMMX.td b/contrib/libs/llvm12/lib/Target/X86/X86InstrMMX.td
index cb18a9b59a..bb3e6df3bf 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrMMX.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrMMX.td
@@ -472,7 +472,7 @@ defm MMX_PACKUSWB : MMXI_binop_rm_int<0x67, "packuswb", int_x86_mmx_packuswb,
defm MMX_PSHUFB : SS3I_binop_rm_int_mm<0x00, "pshufb", int_x86_ssse3_pshuf_b,
SchedWriteVarShuffle.MMX>;
-let Predicates = [HasMMX, HasSSE1] in {
+let Predicates = [HasMMX, HasSSE1] in {
def MMX_PSHUFWri : MMXIi8<0x70, MRMSrcReg,
(outs VR64:$dst), (ins VR64:$src1, u8imm:$src2),
"pshufw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
@@ -486,7 +486,7 @@ def MMX_PSHUFWmi : MMXIi8<0x70, MRMSrcMem,
(int_x86_sse_pshuf_w (load_mmx addr:$src1),
timm:$src2))]>,
Sched<[SchedWriteShuffle.MMX.Folded]>;
-}
+}
// -- Conversion Instructions
defm MMX_CVTPS2PI : sse12_cvt_pint<0x2D, VR128, VR64, int_x86_sse_cvtps2pi,
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrSNP.td b/contrib/libs/llvm12/lib/Target/X86/X86InstrSNP.td
index be95d70282..de59f3fe27 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrSNP.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrSNP.td
@@ -1,47 +1,47 @@
-//===-- X86InstrSNP.td - SNP Instruction Set Extension -----*- tablegen -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file describes the instructions that make up the AMD Secure Nested
-// Paging (SNP) instruction set.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-// SNP instructions
-
-let SchedRW = [WriteSystem] in {
-// F3 0F 01 FF
-let Uses = [RAX] in
-def PSMASH: I<0x01, MRM_FF, (outs), (ins), "psmash", []>, XS,
- Requires<[In64BitMode]>;
-
-// F2 0F 01 FF
-let Uses = [RAX] in
-def PVALIDATE64: I<0x01, MRM_FF, (outs), (ins), "pvalidate",[]>,
- XD, Requires<[In64BitMode]>;
-
-let Uses = [EAX] in
-def PVALIDATE32: I<0x01, MRM_FF, (outs), (ins), "pvalidate",[]>,
- XD, Requires<[Not64BitMode]>;
-
-// F2 0F 01 FE
-let Uses = [RAX] in
-def RMPUPDATE: I<0x01, MRM_FE, (outs), (ins), "rmpupdate", []>, XD,
- Requires<[In64BitMode]>;
-
-// F3 0F 01 FE
-let Uses = [RAX] in
-def RMPADJUST: I<0x01, MRM_FE, (outs), (ins), "rmpadjust", []>, XS,
- Requires<[In64BitMode]>;
-} // SchedRW
-
-def : InstAlias<"psmash\t{%rax|rax}", (PSMASH)>, Requires<[In64BitMode]>;
-def : InstAlias<"pvalidate\t{%rax|rax}", (PVALIDATE64)>, Requires<[In64BitMode]>;
-def : InstAlias<"pvalidate\t{%eax|eax}", (PVALIDATE32)>, Requires<[Not64BitMode]>;
-def : InstAlias<"rmpupdate\t{%rax|rax}", (RMPUPDATE)>, Requires<[In64BitMode]>;
-def : InstAlias<"rmpadjust\t{%rax|rax}", (RMPADJUST)>, Requires<[In64BitMode]>;
+//===-- X86InstrSNP.td - SNP Instruction Set Extension -----*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the instructions that make up the AMD Secure Nested
+// Paging (SNP) instruction set.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// SNP instructions
+
+let SchedRW = [WriteSystem] in {
+// F3 0F 01 FF
+let Uses = [RAX] in
+def PSMASH: I<0x01, MRM_FF, (outs), (ins), "psmash", []>, XS,
+ Requires<[In64BitMode]>;
+
+// F2 0F 01 FF
+let Uses = [RAX] in
+def PVALIDATE64: I<0x01, MRM_FF, (outs), (ins), "pvalidate",[]>,
+ XD, Requires<[In64BitMode]>;
+
+let Uses = [EAX] in
+def PVALIDATE32: I<0x01, MRM_FF, (outs), (ins), "pvalidate",[]>,
+ XD, Requires<[Not64BitMode]>;
+
+// F2 0F 01 FE
+let Uses = [RAX] in
+def RMPUPDATE: I<0x01, MRM_FE, (outs), (ins), "rmpupdate", []>, XD,
+ Requires<[In64BitMode]>;
+
+// F3 0F 01 FE
+let Uses = [RAX] in
+def RMPADJUST: I<0x01, MRM_FE, (outs), (ins), "rmpadjust", []>, XS,
+ Requires<[In64BitMode]>;
+} // SchedRW
+
+def : InstAlias<"psmash\t{%rax|rax}", (PSMASH)>, Requires<[In64BitMode]>;
+def : InstAlias<"pvalidate\t{%rax|rax}", (PVALIDATE64)>, Requires<[In64BitMode]>;
+def : InstAlias<"pvalidate\t{%eax|eax}", (PVALIDATE32)>, Requires<[Not64BitMode]>;
+def : InstAlias<"rmpupdate\t{%rax|rax}", (RMPUPDATE)>, Requires<[In64BitMode]>;
+def : InstAlias<"rmpadjust\t{%rax|rax}", (RMPADJUST)>, Requires<[In64BitMode]>;
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrSSE.td b/contrib/libs/llvm12/lib/Target/X86/X86InstrSSE.td
index 29ac01b143..a185a2007b 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrSSE.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrSSE.td
@@ -1242,8 +1242,8 @@ def : InstAlias<"cvtsd2si{q}\t{$src, $dst|$dst, $src}",
/// SSE 2 Only
// Convert scalar double to scalar single
-let isCodeGenOnly = 1, hasSideEffects = 0, Predicates = [UseAVX],
- ExeDomain = SSEPackedSingle in {
+let isCodeGenOnly = 1, hasSideEffects = 0, Predicates = [UseAVX],
+ ExeDomain = SSEPackedSingle in {
def VCVTSD2SSrr : VSDI<0x5A, MRMSrcReg, (outs FR32:$dst),
(ins FR32:$src1, FR64:$src2),
"cvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
@@ -1261,7 +1261,7 @@ def : Pat<(f32 (any_fpround FR64:$src)),
(VCVTSD2SSrr (f32 (IMPLICIT_DEF)), FR64:$src)>,
Requires<[UseAVX]>;
-let isCodeGenOnly = 1, ExeDomain = SSEPackedSingle in {
+let isCodeGenOnly = 1, ExeDomain = SSEPackedSingle in {
def CVTSD2SSrr : SDI<0x5A, MRMSrcReg, (outs FR32:$dst), (ins FR64:$src),
"cvtsd2ss\t{$src, $dst|$dst, $src}",
[(set FR32:$dst, (any_fpround FR64:$src))]>,
@@ -1273,7 +1273,7 @@ def CVTSD2SSrm : I<0x5A, MRMSrcMem, (outs FR32:$dst), (ins f64mem:$src),
Sched<[WriteCvtSD2SS.Folded]>, SIMD_EXC;
}
-let Uses = [MXCSR], mayRaiseFPException = 1, ExeDomain = SSEPackedSingle in {
+let Uses = [MXCSR], mayRaiseFPException = 1, ExeDomain = SSEPackedSingle in {
def VCVTSD2SSrr_Int: I<0x5A, MRMSrcReg,
(outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
"vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
@@ -1307,7 +1307,7 @@ def CVTSD2SSrm_Int: I<0x5A, MRMSrcMem,
// Convert scalar single to scalar double
// SSE2 instructions with XS prefix
-let isCodeGenOnly = 1, hasSideEffects = 0, ExeDomain = SSEPackedSingle in {
+let isCodeGenOnly = 1, hasSideEffects = 0, ExeDomain = SSEPackedSingle in {
def VCVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst),
(ins FR64:$src1, FR32:$src2),
"vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
@@ -1327,7 +1327,7 @@ def : Pat<(f64 (any_fpextend FR32:$src)),
def : Pat<(any_fpextend (loadf32 addr:$src)),
(VCVTSS2SDrm (f64 (IMPLICIT_DEF)), addr:$src)>, Requires<[UseAVX, OptForSize]>;
-let isCodeGenOnly = 1, ExeDomain = SSEPackedSingle in {
+let isCodeGenOnly = 1, ExeDomain = SSEPackedSingle in {
def CVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst), (ins FR32:$src),
"cvtss2sd\t{$src, $dst|$dst, $src}",
[(set FR64:$dst, (any_fpextend FR32:$src))]>,
@@ -1339,8 +1339,8 @@ def CVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst), (ins f32mem:$src),
Sched<[WriteCvtSS2SD.Folded]>, SIMD_EXC;
} // isCodeGenOnly = 1
-let hasSideEffects = 0, Uses = [MXCSR], mayRaiseFPException = 1,
- ExeDomain = SSEPackedSingle in {
+let hasSideEffects = 0, Uses = [MXCSR], mayRaiseFPException = 1,
+ ExeDomain = SSEPackedSingle in {
def VCVTSS2SDrr_Int: I<0x5A, MRMSrcReg,
(outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
"vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
@@ -3778,7 +3778,7 @@ let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
VEX_4V, VEX_WIG;
defm VPACKUSDW : sse4_pack<0x2B, "vpackusdw", v8i16, v4i32, X86Packus, VR128,
i128mem, SchedWriteShuffle.XMM, load, 0>,
- VEX_4V, VEX_WIG;
+ VEX_4V, VEX_WIG;
}
let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
@@ -3794,7 +3794,7 @@ let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
VEX_4V, VEX_L, VEX_WIG;
defm VPACKUSDWY : sse4_pack<0x2B, "vpackusdw", v16i16, v8i32, X86Packus, VR256,
i256mem, SchedWriteShuffle.YMM, load, 0>,
- VEX_4V, VEX_L, VEX_WIG;
+ VEX_4V, VEX_L, VEX_WIG;
}
let Constraints = "$src1 = $dst" in {
@@ -3930,7 +3930,7 @@ multiclass sse2_pinsrw<bit Is2Addr = 1> {
"pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
"vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
[(set VR128:$dst,
- (X86pinsrw VR128:$src1, GR32orGR64:$src2, timm:$src3))]>,
+ (X86pinsrw VR128:$src1, GR32orGR64:$src2, timm:$src3))]>,
Sched<[WriteVecInsert, ReadDefault, ReadInt2Fpu]>;
def rm : Ii8<0xC4, MRMSrcMem,
(outs VR128:$dst), (ins VR128:$src1,
@@ -3940,7 +3940,7 @@ multiclass sse2_pinsrw<bit Is2Addr = 1> {
"vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
[(set VR128:$dst,
(X86pinsrw VR128:$src1, (extloadi16 addr:$src2),
- timm:$src3))]>,
+ timm:$src3))]>,
Sched<[WriteVecInsert.Folded, WriteVecInsert.ReadAfterFold]>;
}
@@ -3950,13 +3950,13 @@ def VPEXTRWrr : Ii8<0xC5, MRMSrcReg,
(outs GR32orGR64:$dst), (ins VR128:$src1, u8imm:$src2),
"vpextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
[(set GR32orGR64:$dst, (X86pextrw (v8i16 VR128:$src1),
- timm:$src2))]>,
+ timm:$src2))]>,
PD, VEX, VEX_WIG, Sched<[WriteVecExtract]>;
def PEXTRWrr : PDIi8<0xC5, MRMSrcReg,
(outs GR32orGR64:$dst), (ins VR128:$src1, u8imm:$src2),
"pextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
[(set GR32orGR64:$dst, (X86pextrw (v8i16 VR128:$src1),
- timm:$src2))]>,
+ timm:$src2))]>,
Sched<[WriteVecExtract]>;
// Insert
@@ -4756,7 +4756,7 @@ let isCommutable = 0 in {
SchedWritePHAdd.XMM, 0>, VEX_4V, VEX_WIG;
defm VPHSUBD : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v4i32, v4i32, VR128,
load, i128mem,
- SchedWritePHAdd.XMM, 0>, VEX_4V, VEX_WIG;
+ SchedWritePHAdd.XMM, 0>, VEX_4V, VEX_WIG;
defm VPSIGNB : SS3I_binop_rm_int<0x08, "vpsignb",
int_x86_ssse3_psign_b_128,
SchedWriteVecALU.XMM, load, 0>, VEX_4V, VEX_WIG;
@@ -4802,7 +4802,7 @@ let isCommutable = 0 in {
SchedWritePHAdd.YMM, 0>, VEX_4V, VEX_L, VEX_WIG;
defm VPHSUBDY : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v8i32, v8i32, VR256,
load, i256mem,
- SchedWritePHAdd.YMM, 0>, VEX_4V, VEX_L, VEX_WIG;
+ SchedWritePHAdd.YMM, 0>, VEX_4V, VEX_L, VEX_WIG;
defm VPSIGNB : SS3I_binop_rm_int_y<0x08, "vpsignb", int_x86_avx2_psign_b,
SchedWriteVecALU.YMM>, VEX_4V, VEX_L, VEX_WIG;
defm VPSIGNW : SS3I_binop_rm_int_y<0x09, "vpsignw", int_x86_avx2_psign_w,
@@ -5153,14 +5153,14 @@ multiclass SS41I_extract8<bits<8> opc, string OpcodeStr> {
!strconcat(OpcodeStr,
"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
[(set GR32orGR64:$dst, (X86pextrb (v16i8 VR128:$src1),
- timm:$src2))]>,
+ timm:$src2))]>,
Sched<[WriteVecExtract]>;
let hasSideEffects = 0, mayStore = 1 in
def mr : SS4AIi8<opc, MRMDestMem, (outs),
(ins i8mem:$dst, VR128:$src1, u8imm:$src2),
!strconcat(OpcodeStr,
"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
- [(store (i8 (trunc (X86pextrb (v16i8 VR128:$src1), timm:$src2))),
+ [(store (i8 (trunc (X86pextrb (v16i8 VR128:$src1), timm:$src2))),
addr:$dst)]>, Sched<[WriteVecExtractSt]>;
}
@@ -5184,7 +5184,7 @@ multiclass SS41I_extract16<bits<8> opc, string OpcodeStr> {
(ins i16mem:$dst, VR128:$src1, u8imm:$src2),
!strconcat(OpcodeStr,
"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
- [(store (i16 (trunc (X86pextrw (v8i16 VR128:$src1), timm:$src2))),
+ [(store (i16 (trunc (X86pextrw (v8i16 VR128:$src1), timm:$src2))),
addr:$dst)]>, Sched<[WriteVecExtractSt]>;
}
@@ -5274,7 +5274,7 @@ multiclass SS41I_insert8<bits<8> opc, string asm, bit Is2Addr = 1> {
!strconcat(asm,
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
[(set VR128:$dst,
- (X86pinsrb VR128:$src1, GR32orGR64:$src2, timm:$src3))]>,
+ (X86pinsrb VR128:$src1, GR32orGR64:$src2, timm:$src3))]>,
Sched<[WriteVecInsert, ReadDefault, ReadInt2Fpu]>;
def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
(ins VR128:$src1, i8mem:$src2, u8imm:$src3),
@@ -5283,7 +5283,7 @@ multiclass SS41I_insert8<bits<8> opc, string asm, bit Is2Addr = 1> {
!strconcat(asm,
"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
[(set VR128:$dst,
- (X86pinsrb VR128:$src1, (extloadi8 addr:$src2), timm:$src3))]>,
+ (X86pinsrb VR128:$src1, (extloadi8 addr:$src2), timm:$src3))]>,
Sched<[WriteVecInsert.Folded, WriteVecInsert.ReadAfterFold]>;
}
@@ -6503,7 +6503,7 @@ multiclass pcmpistrm_SS42AI<string asm> {
let Defs = [XMM0, EFLAGS], hasSideEffects = 0 in {
let Predicates = [HasAVX] in
- defm VPCMPISTRM : pcmpistrm_SS42AI<"vpcmpistrm">, VEX, VEX_WIG;
+ defm VPCMPISTRM : pcmpistrm_SS42AI<"vpcmpistrm">, VEX, VEX_WIG;
defm PCMPISTRM : pcmpistrm_SS42AI<"pcmpistrm"> ;
}
@@ -6521,7 +6521,7 @@ multiclass SS42AI_pcmpestrm<string asm> {
let Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], hasSideEffects = 0 in {
let Predicates = [HasAVX] in
- defm VPCMPESTRM : SS42AI_pcmpestrm<"vpcmpestrm">, VEX, VEX_WIG;
+ defm VPCMPESTRM : SS42AI_pcmpestrm<"vpcmpestrm">, VEX, VEX_WIG;
defm PCMPESTRM : SS42AI_pcmpestrm<"pcmpestrm">;
}
@@ -6539,7 +6539,7 @@ multiclass SS42AI_pcmpistri<string asm> {
let Defs = [ECX, EFLAGS], hasSideEffects = 0 in {
let Predicates = [HasAVX] in
- defm VPCMPISTRI : SS42AI_pcmpistri<"vpcmpistri">, VEX, VEX_WIG;
+ defm VPCMPISTRI : SS42AI_pcmpistri<"vpcmpistri">, VEX, VEX_WIG;
defm PCMPISTRI : SS42AI_pcmpistri<"pcmpistri">;
}
@@ -6557,7 +6557,7 @@ multiclass SS42AI_pcmpestri<string asm> {
let Defs = [ECX, EFLAGS], Uses = [EAX, EDX], hasSideEffects = 0 in {
let Predicates = [HasAVX] in
- defm VPCMPESTRI : SS42AI_pcmpestri<"vpcmpestri">, VEX, VEX_WIG;
+ defm VPCMPESTRI : SS42AI_pcmpestri<"vpcmpestri">, VEX, VEX_WIG;
defm PCMPESTRI : SS42AI_pcmpestri<"pcmpestri">;
}
@@ -7016,19 +7016,19 @@ def VBROADCASTF128 : AVX8I<0x1A, MRMSrcMem, (outs VR256:$dst),
Sched<[SchedWriteFShuffle.XMM.Folded]>, VEX, VEX_L;
let Predicates = [HasAVX, NoVLX] in {
-def : Pat<(v4f64 (X86SubVBroadcastld128 addr:$src)),
+def : Pat<(v4f64 (X86SubVBroadcastld128 addr:$src)),
(VBROADCASTF128 addr:$src)>;
-def : Pat<(v8f32 (X86SubVBroadcastld128 addr:$src)),
+def : Pat<(v8f32 (X86SubVBroadcastld128 addr:$src)),
(VBROADCASTF128 addr:$src)>;
// NOTE: We're using FP instructions here, but execution domain fixing can
// convert to integer when profitable.
-def : Pat<(v4i64 (X86SubVBroadcastld128 addr:$src)),
+def : Pat<(v4i64 (X86SubVBroadcastld128 addr:$src)),
(VBROADCASTF128 addr:$src)>;
-def : Pat<(v8i32 (X86SubVBroadcastld128 addr:$src)),
+def : Pat<(v8i32 (X86SubVBroadcastld128 addr:$src)),
(VBROADCASTF128 addr:$src)>;
-def : Pat<(v16i16 (X86SubVBroadcastld128 addr:$src)),
+def : Pat<(v16i16 (X86SubVBroadcastld128 addr:$src)),
(VBROADCASTF128 addr:$src)>;
-def : Pat<(v32i8 (X86SubVBroadcastld128 addr:$src)),
+def : Pat<(v32i8 (X86SubVBroadcastld128 addr:$src)),
(VBROADCASTF128 addr:$src)>;
}
@@ -7164,68 +7164,68 @@ defm VMASKMOVPD : avx_movmask_rm<0x2D, 0x2F, "vmaskmovpd",
WriteFMaskMove64, WriteFMaskMove64Y>;
//===----------------------------------------------------------------------===//
-// AVX_VNNI
-//===----------------------------------------------------------------------===//
-let Predicates = [HasAVXVNNI, NoVLX_Or_NoVNNI], Constraints = "$src1 = $dst" in
-multiclass avx_vnni_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
- bit IsCommutable> {
- let isCommutable = IsCommutable in
- def rr : AVX8I<opc, MRMSrcReg, (outs VR128:$dst),
- (ins VR128:$src1, VR128:$src2, VR128:$src3),
- !strconcat(OpcodeStr, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
- [(set VR128:$dst, (v4i32 (OpNode VR128:$src1,
- VR128:$src2, VR128:$src3)))]>,
- VEX_4V, Sched<[SchedWriteVecIMul.XMM]>;
-
- def rm : AVX8I<opc, MRMSrcMem, (outs VR128:$dst),
- (ins VR128:$src1, VR128:$src2, i128mem:$src3),
- !strconcat(OpcodeStr, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
- [(set VR128:$dst, (v4i32 (OpNode VR128:$src1, VR128:$src2,
- (loadv4i32 addr:$src3))))]>,
- VEX_4V, Sched<[SchedWriteVecIMul.XMM]>;
-
- let isCommutable = IsCommutable in
- def Yrr : AVX8I<opc, MRMSrcReg, (outs VR256:$dst),
- (ins VR256:$src1, VR256:$src2, VR256:$src3),
- !strconcat(OpcodeStr, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
- [(set VR256:$dst, (v8i32 (OpNode VR256:$src1,
- VR256:$src2, VR256:$src3)))]>,
- VEX_4V, VEX_L, Sched<[SchedWriteVecIMul.XMM]>;
-
- def Yrm : AVX8I<opc, MRMSrcMem, (outs VR256:$dst),
- (ins VR256:$src1, VR256:$src2, i256mem:$src3),
- !strconcat(OpcodeStr, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
- [(set VR256:$dst, (v8i32 (OpNode VR256:$src1, VR256:$src2,
- (loadv8i32 addr:$src3))))]>,
- VEX_4V, VEX_L, Sched<[SchedWriteVecIMul.XMM]>;
-}
-
-defm VPDPBUSD : avx_vnni_rm<0x50, "vpdpbusd", X86Vpdpbusd, 0>, ExplicitVEXPrefix;
-defm VPDPBUSDS : avx_vnni_rm<0x51, "vpdpbusds", X86Vpdpbusds, 0>, ExplicitVEXPrefix;
-defm VPDPWSSD : avx_vnni_rm<0x52, "vpdpwssd", X86Vpdpwssd, 1>, ExplicitVEXPrefix;
-defm VPDPWSSDS : avx_vnni_rm<0x53, "vpdpwssds", X86Vpdpwssds, 1>, ExplicitVEXPrefix;
-
-def X86vpmaddwd_su : PatFrag<(ops node:$lhs, node:$rhs),
- (X86vpmaddwd node:$lhs, node:$rhs), [{
- return N->hasOneUse();
-}]>;
-
-let Predicates = [HasAVXVNNI, NoVLX_Or_NoVNNI] in {
- def : Pat<(v8i32 (add VR256:$src1,
- (X86vpmaddwd_su VR256:$src2, VR256:$src3))),
- (VPDPWSSDYrr VR256:$src1, VR256:$src2, VR256:$src3)>;
- def : Pat<(v8i32 (add VR256:$src1,
- (X86vpmaddwd_su VR256:$src2, (load addr:$src3)))),
- (VPDPWSSDYrm VR256:$src1, VR256:$src2, addr:$src3)>;
- def : Pat<(v4i32 (add VR128:$src1,
- (X86vpmaddwd_su VR128:$src2, VR128:$src3))),
- (VPDPWSSDrr VR128:$src1, VR128:$src2, VR128:$src3)>;
- def : Pat<(v4i32 (add VR128:$src1,
- (X86vpmaddwd_su VR128:$src2, (load addr:$src3)))),
- (VPDPWSSDrm VR128:$src1, VR128:$src2, addr:$src3)>;
-}
-
-//===----------------------------------------------------------------------===//
+// AVX_VNNI
+//===----------------------------------------------------------------------===//
+let Predicates = [HasAVXVNNI, NoVLX_Or_NoVNNI], Constraints = "$src1 = $dst" in
+multiclass avx_vnni_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
+ bit IsCommutable> {
+ let isCommutable = IsCommutable in
+ def rr : AVX8I<opc, MRMSrcReg, (outs VR128:$dst),
+ (ins VR128:$src1, VR128:$src2, VR128:$src3),
+ !strconcat(OpcodeStr, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
+ [(set VR128:$dst, (v4i32 (OpNode VR128:$src1,
+ VR128:$src2, VR128:$src3)))]>,
+ VEX_4V, Sched<[SchedWriteVecIMul.XMM]>;
+
+ def rm : AVX8I<opc, MRMSrcMem, (outs VR128:$dst),
+ (ins VR128:$src1, VR128:$src2, i128mem:$src3),
+ !strconcat(OpcodeStr, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
+ [(set VR128:$dst, (v4i32 (OpNode VR128:$src1, VR128:$src2,
+ (loadv4i32 addr:$src3))))]>,
+ VEX_4V, Sched<[SchedWriteVecIMul.XMM]>;
+
+ let isCommutable = IsCommutable in
+ def Yrr : AVX8I<opc, MRMSrcReg, (outs VR256:$dst),
+ (ins VR256:$src1, VR256:$src2, VR256:$src3),
+ !strconcat(OpcodeStr, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
+ [(set VR256:$dst, (v8i32 (OpNode VR256:$src1,
+ VR256:$src2, VR256:$src3)))]>,
+ VEX_4V, VEX_L, Sched<[SchedWriteVecIMul.XMM]>;
+
+ def Yrm : AVX8I<opc, MRMSrcMem, (outs VR256:$dst),
+ (ins VR256:$src1, VR256:$src2, i256mem:$src3),
+ !strconcat(OpcodeStr, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
+ [(set VR256:$dst, (v8i32 (OpNode VR256:$src1, VR256:$src2,
+ (loadv8i32 addr:$src3))))]>,
+ VEX_4V, VEX_L, Sched<[SchedWriteVecIMul.XMM]>;
+}
+
+defm VPDPBUSD : avx_vnni_rm<0x50, "vpdpbusd", X86Vpdpbusd, 0>, ExplicitVEXPrefix;
+defm VPDPBUSDS : avx_vnni_rm<0x51, "vpdpbusds", X86Vpdpbusds, 0>, ExplicitVEXPrefix;
+defm VPDPWSSD : avx_vnni_rm<0x52, "vpdpwssd", X86Vpdpwssd, 1>, ExplicitVEXPrefix;
+defm VPDPWSSDS : avx_vnni_rm<0x53, "vpdpwssds", X86Vpdpwssds, 1>, ExplicitVEXPrefix;
+
+def X86vpmaddwd_su : PatFrag<(ops node:$lhs, node:$rhs),
+ (X86vpmaddwd node:$lhs, node:$rhs), [{
+ return N->hasOneUse();
+}]>;
+
+let Predicates = [HasAVXVNNI, NoVLX_Or_NoVNNI] in {
+ def : Pat<(v8i32 (add VR256:$src1,
+ (X86vpmaddwd_su VR256:$src2, VR256:$src3))),
+ (VPDPWSSDYrr VR256:$src1, VR256:$src2, VR256:$src3)>;
+ def : Pat<(v8i32 (add VR256:$src1,
+ (X86vpmaddwd_su VR256:$src2, (load addr:$src3)))),
+ (VPDPWSSDYrm VR256:$src1, VR256:$src2, addr:$src3)>;
+ def : Pat<(v4i32 (add VR128:$src1,
+ (X86vpmaddwd_su VR128:$src2, VR128:$src3))),
+ (VPDPWSSDrr VR128:$src1, VR128:$src2, VR128:$src3)>;
+ def : Pat<(v4i32 (add VR128:$src1,
+ (X86vpmaddwd_su VR128:$src2, (load addr:$src3)))),
+ (VPDPWSSDrm VR128:$src1, VR128:$src2, addr:$src3)>;
+}
+
+//===----------------------------------------------------------------------===//
// VPERMIL - Permute Single and Double Floating-Point Values
//
@@ -7287,12 +7287,12 @@ let ExeDomain = SSEPackedSingle in {
let isCommutable = 1 in
def VPERM2F128rr : AVXAIi8<0x06, MRMSrcReg, (outs VR256:$dst),
(ins VR256:$src1, VR256:$src2, u8imm:$src3),
- "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}", []>,
- VEX_4V, VEX_L, Sched<[WriteFShuffle256]>;
+ "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}", []>,
+ VEX_4V, VEX_L, Sched<[WriteFShuffle256]>;
def VPERM2F128rm : AVXAIi8<0x06, MRMSrcMem, (outs VR256:$dst),
(ins VR256:$src1, f256mem:$src2, u8imm:$src3),
- "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}", []>,
- VEX_4V, VEX_L, Sched<[WriteFShuffle256.Folded, WriteFShuffle256.ReadAfterFold]>;
+ "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}", []>,
+ VEX_4V, VEX_L, Sched<[WriteFShuffle256.Folded, WriteFShuffle256.ReadAfterFold]>;
}
// Immediate transform to help with commuting.
@@ -7300,27 +7300,27 @@ def Perm2XCommuteImm : SDNodeXForm<timm, [{
return getI8Imm(N->getZExtValue() ^ 0x22, SDLoc(N));
}]>;
-multiclass vperm2x128_lowering<string InstrStr, ValueType VT, PatFrag memop_frag> {
- def : Pat<(VT (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 timm:$imm))),
- (!cast<Instruction>(InstrStr#rr) VR256:$src1, VR256:$src2, timm:$imm)>;
- def : Pat<(VT (X86VPerm2x128 VR256:$src1, (memop_frag addr:$src2), (i8 timm:$imm))),
- (!cast<Instruction>(InstrStr#rm) VR256:$src1, addr:$src2, timm:$imm)>;
- // Pattern with load in other operand.
- def : Pat<(VT (X86VPerm2x128 (memop_frag addr:$src2), VR256:$src1, (i8 timm:$imm))),
- (!cast<Instruction>(InstrStr#rm) VR256:$src1, addr:$src2,
- (Perm2XCommuteImm timm:$imm))>;
-}
-
+multiclass vperm2x128_lowering<string InstrStr, ValueType VT, PatFrag memop_frag> {
+ def : Pat<(VT (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 timm:$imm))),
+ (!cast<Instruction>(InstrStr#rr) VR256:$src1, VR256:$src2, timm:$imm)>;
+ def : Pat<(VT (X86VPerm2x128 VR256:$src1, (memop_frag addr:$src2), (i8 timm:$imm))),
+ (!cast<Instruction>(InstrStr#rm) VR256:$src1, addr:$src2, timm:$imm)>;
+ // Pattern with load in other operand.
+ def : Pat<(VT (X86VPerm2x128 (memop_frag addr:$src2), VR256:$src1, (i8 timm:$imm))),
+ (!cast<Instruction>(InstrStr#rm) VR256:$src1, addr:$src2,
+ (Perm2XCommuteImm timm:$imm))>;
+}
+
let Predicates = [HasAVX] in {
- defm : vperm2x128_lowering<"VPERM2F128", v4f64, loadv4f64>;
- defm : vperm2x128_lowering<"VPERM2F128", v8f32, loadv8f32>;
+ defm : vperm2x128_lowering<"VPERM2F128", v4f64, loadv4f64>;
+ defm : vperm2x128_lowering<"VPERM2F128", v8f32, loadv8f32>;
}
let Predicates = [HasAVX1Only] in {
- defm : vperm2x128_lowering<"VPERM2F128", v4i64, loadv4i64>;
- defm : vperm2x128_lowering<"VPERM2F128", v8i32, loadv8i32>;
- defm : vperm2x128_lowering<"VPERM2F128", v16i16, loadv16i16>;
- defm : vperm2x128_lowering<"VPERM2F128", v32i8, loadv32i8>;
+ defm : vperm2x128_lowering<"VPERM2F128", v4i64, loadv4i64>;
+ defm : vperm2x128_lowering<"VPERM2F128", v8i32, loadv8i32>;
+ defm : vperm2x128_lowering<"VPERM2F128", v16i16, loadv16i16>;
+ defm : vperm2x128_lowering<"VPERM2F128", v32i8, loadv32i8>;
}
//===----------------------------------------------------------------------===//
@@ -7689,24 +7689,24 @@ defm VPERMPD : avx2_perm_imm<0x01, "vpermpd", loadv4f64, v4f64,
WriteFShuffle256, f256mem>, VEX_W;
//===----------------------------------------------------------------------===//
-// VPERM2I128 - Permute Integer vector Values in 128-bit chunks
+// VPERM2I128 - Permute Integer vector Values in 128-bit chunks
//
let isCommutable = 1 in
def VPERM2I128rr : AVX2AIi8<0x46, MRMSrcReg, (outs VR256:$dst),
(ins VR256:$src1, VR256:$src2, u8imm:$src3),
- "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}", []>,
- Sched<[WriteShuffle256]>, VEX_4V, VEX_L;
+ "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}", []>,
+ Sched<[WriteShuffle256]>, VEX_4V, VEX_L;
def VPERM2I128rm : AVX2AIi8<0x46, MRMSrcMem, (outs VR256:$dst),
(ins VR256:$src1, f256mem:$src2, u8imm:$src3),
- "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}", []>,
+ "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}", []>,
Sched<[WriteShuffle256.Folded, WriteShuffle256.ReadAfterFold]>, VEX_4V, VEX_L;
-let Predicates = [HasAVX2] in {
- defm : vperm2x128_lowering<"VPERM2I128", v4i64, loadv4i64>;
- defm : vperm2x128_lowering<"VPERM2I128", v8i32, loadv8i32>;
- defm : vperm2x128_lowering<"VPERM2I128", v16i16, loadv16i16>;
- defm : vperm2x128_lowering<"VPERM2I128", v32i8, loadv32i8>;
-}
+let Predicates = [HasAVX2] in {
+ defm : vperm2x128_lowering<"VPERM2I128", v4i64, loadv4i64>;
+ defm : vperm2x128_lowering<"VPERM2I128", v8i32, loadv8i32>;
+ defm : vperm2x128_lowering<"VPERM2I128", v16i16, loadv16i16>;
+ defm : vperm2x128_lowering<"VPERM2I128", v32i8, loadv32i8>;
+}
//===----------------------------------------------------------------------===//
// VINSERTI128 - Insert packed integer values
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrSVM.td b/contrib/libs/llvm12/lib/Target/X86/X86InstrSVM.td
index 2bc32910a6..d8f70b016c 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrSVM.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrSVM.td
@@ -26,47 +26,47 @@ def CLGI : I<0x01, MRM_DD, (outs), (ins), "clgi", []>, TB;
// 0F 01 DE
let Uses = [EAX] in
-def SKINIT : I<0x01, MRM_DE, (outs), (ins), "skinit", []>, TB;
+def SKINIT : I<0x01, MRM_DE, (outs), (ins), "skinit", []>, TB;
// 0F 01 D8
let Uses = [EAX] in
-def VMRUN32 : I<0x01, MRM_D8, (outs), (ins), "vmrun", []>, TB,
+def VMRUN32 : I<0x01, MRM_D8, (outs), (ins), "vmrun", []>, TB,
Requires<[Not64BitMode]>;
let Uses = [RAX] in
-def VMRUN64 : I<0x01, MRM_D8, (outs), (ins), "vmrun", []>, TB,
+def VMRUN64 : I<0x01, MRM_D8, (outs), (ins), "vmrun", []>, TB,
Requires<[In64BitMode]>;
// 0F 01 DA
let Uses = [EAX] in
-def VMLOAD32 : I<0x01, MRM_DA, (outs), (ins), "vmload", []>, TB,
+def VMLOAD32 : I<0x01, MRM_DA, (outs), (ins), "vmload", []>, TB,
Requires<[Not64BitMode]>;
let Uses = [RAX] in
-def VMLOAD64 : I<0x01, MRM_DA, (outs), (ins), "vmload", []>, TB,
+def VMLOAD64 : I<0x01, MRM_DA, (outs), (ins), "vmload", []>, TB,
Requires<[In64BitMode]>;
// 0F 01 DB
let Uses = [EAX] in
-def VMSAVE32 : I<0x01, MRM_DB, (outs), (ins), "vmsave", []>, TB,
+def VMSAVE32 : I<0x01, MRM_DB, (outs), (ins), "vmsave", []>, TB,
Requires<[Not64BitMode]>;
let Uses = [RAX] in
-def VMSAVE64 : I<0x01, MRM_DB, (outs), (ins), "vmsave", []>, TB,
+def VMSAVE64 : I<0x01, MRM_DB, (outs), (ins), "vmsave", []>, TB,
Requires<[In64BitMode]>;
// 0F 01 DF
let Uses = [EAX, ECX] in
def INVLPGA32 : I<0x01, MRM_DF, (outs), (ins),
- "invlpga", []>, TB, Requires<[Not64BitMode]>;
+ "invlpga", []>, TB, Requires<[Not64BitMode]>;
let Uses = [RAX, ECX] in
def INVLPGA64 : I<0x01, MRM_DF, (outs), (ins),
- "invlpga", []>, TB, Requires<[In64BitMode]>;
+ "invlpga", []>, TB, Requires<[In64BitMode]>;
} // SchedRW
-
-def : InstAlias<"skinit\t{%eax|eax}", (SKINIT), 0>;
-def : InstAlias<"vmrun\t{%eax|eax}", (VMRUN32), 0>, Requires<[Not64BitMode]>;
-def : InstAlias<"vmrun\t{%rax|rax}", (VMRUN64), 0>, Requires<[In64BitMode]>;
-def : InstAlias<"vmload\t{%eax|eax}", (VMLOAD32), 0>, Requires<[Not64BitMode]>;
-def : InstAlias<"vmload\t{%rax|rax}", (VMLOAD64), 0>, Requires<[In64BitMode]>;
-def : InstAlias<"vmsave\t{%eax|eax}", (VMSAVE32), 0>, Requires<[Not64BitMode]>;
-def : InstAlias<"vmsave\t{%rax|rax}", (VMSAVE64), 0>, Requires<[In64BitMode]>;
-def : InstAlias<"invlpga\t{%eax, %ecx|eax, ecx}", (INVLPGA32), 0>, Requires<[Not64BitMode]>;
-def : InstAlias<"invlpga\t{%rax, %ecx|rax, ecx}", (INVLPGA64), 0>, Requires<[In64BitMode]>;
+
+def : InstAlias<"skinit\t{%eax|eax}", (SKINIT), 0>;
+def : InstAlias<"vmrun\t{%eax|eax}", (VMRUN32), 0>, Requires<[Not64BitMode]>;
+def : InstAlias<"vmrun\t{%rax|rax}", (VMRUN64), 0>, Requires<[In64BitMode]>;
+def : InstAlias<"vmload\t{%eax|eax}", (VMLOAD32), 0>, Requires<[Not64BitMode]>;
+def : InstAlias<"vmload\t{%rax|rax}", (VMLOAD64), 0>, Requires<[In64BitMode]>;
+def : InstAlias<"vmsave\t{%eax|eax}", (VMSAVE32), 0>, Requires<[Not64BitMode]>;
+def : InstAlias<"vmsave\t{%rax|rax}", (VMSAVE64), 0>, Requires<[In64BitMode]>;
+def : InstAlias<"invlpga\t{%eax, %ecx|eax, ecx}", (INVLPGA32), 0>, Requires<[Not64BitMode]>;
+def : InstAlias<"invlpga\t{%rax, %ecx|rax, ecx}", (INVLPGA64), 0>, Requires<[In64BitMode]>;
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrSystem.td b/contrib/libs/llvm12/lib/Target/X86/X86InstrSystem.td
index 3b105cedb3..eb8740896e 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrSystem.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrSystem.td
@@ -49,7 +49,7 @@ let Uses = [EFLAGS] in
def INT3 : I<0xcc, RawFrm, (outs), (ins), "int3", [(int_x86_int (i8 3))]>;
} // SchedRW
-def UBSAN_UD1 : PseudoI<(outs), (ins i32imm:$kind), [(ubsantrap (i32 timm:$kind))]>;
+def UBSAN_UD1 : PseudoI<(outs), (ins i32imm:$kind), [(ubsantrap (i32 timm:$kind))]>;
// The long form of "int $3" turns into int3 as a size optimization.
// FIXME: This doesn't work because InstAlias can't match immediate constants.
//def : InstAlias<"int\t$3", (INT3)>;
@@ -172,17 +172,17 @@ def GS_PREFIX : I<0x65, PrefixByte, (outs), (ins), "gs", []>;
} // SchedRW
//===----------------------------------------------------------------------===//
-// Address-size override prefixes.
-//
-
-let SchedRW = [WriteNop] in {
-def ADDR16_PREFIX : I<0x67, PrefixByte, (outs), (ins), "addr16", []>,
- Requires<[In32BitMode]>;
-def ADDR32_PREFIX : I<0x67, PrefixByte, (outs), (ins), "addr32", []>,
- Requires<[In64BitMode]>;
-} // SchedRW
-
-//===----------------------------------------------------------------------===//
+// Address-size override prefixes.
+//
+
+let SchedRW = [WriteNop] in {
+def ADDR16_PREFIX : I<0x67, PrefixByte, (outs), (ins), "addr16", []>,
+ Requires<[In32BitMode]>;
+def ADDR32_PREFIX : I<0x67, PrefixByte, (outs), (ins), "addr32", []>,
+ Requires<[In64BitMode]>;
+} // SchedRW
+
+//===----------------------------------------------------------------------===//
// Moves to and from segment registers.
//
@@ -459,7 +459,7 @@ let Defs = [EAX, EBX, ECX, EDX], Uses = [EAX, ECX] in
// Cache instructions
let SchedRW = [WriteSystem] in {
def INVD : I<0x08, RawFrm, (outs), (ins), "invd", []>, TB;
-def WBINVD : I<0x09, RawFrm, (outs), (ins), "wbinvd", [(int_x86_wbinvd)]>, PS;
+def WBINVD : I<0x09, RawFrm, (outs), (ins), "wbinvd", [(int_x86_wbinvd)]>, PS;
// wbnoinvd is like wbinvd, except without invalidation
// encoding: like wbinvd + an 0xF3 prefix
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstrTDX.td b/contrib/libs/llvm12/lib/Target/X86/X86InstrTDX.td
index e21028c8a3..8d7cd60820 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstrTDX.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstrTDX.td
@@ -1,39 +1,39 @@
-//===- X86InstrTDX.td - TDX Instruction Set Extension -*- tablegen -*===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file describes the instructions that make up the Intel TDX instruction
-// set.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-// TDX instructions
-
-// 64-bit only instructions
-let SchedRW = [WriteSystem], Predicates = [In64BitMode] in {
-// SEAMCALL - Call to SEAM VMX-root Operation Module
-def SEAMCALL : I<0x01, MRM_CF, (outs), (ins),
- "seamcall", []>, PD;
-
-// SEAMRET - Return to Legacy VMX-root Operation
-def SEAMRET : I<0x01, MRM_CD, (outs), (ins),
- "seamret", []>, PD;
-
-// SEAMOPS - SEAM Operations
-def SEAMOPS : I<0x01, MRM_CE, (outs), (ins),
- "seamops", []>, PD;
-
-} // SchedRW
-
-// common instructions
-let SchedRW = [WriteSystem] in {
-// TDCALL - Call SEAM Module Functions
-def TDCALL : I<0x01, MRM_CC, (outs), (ins),
- "tdcall", []>, PD;
-
-} // SchedRW
+//===- X86InstrTDX.td - TDX Instruction Set Extension -*- tablegen -*===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the instructions that make up the Intel TDX instruction
+// set.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// TDX instructions
+
+// 64-bit only instructions
+let SchedRW = [WriteSystem], Predicates = [In64BitMode] in {
+// SEAMCALL - Call to SEAM VMX-root Operation Module
+def SEAMCALL : I<0x01, MRM_CF, (outs), (ins),
+ "seamcall", []>, PD;
+
+// SEAMRET - Return to Legacy VMX-root Operation
+def SEAMRET : I<0x01, MRM_CD, (outs), (ins),
+ "seamret", []>, PD;
+
+// SEAMOPS - SEAM Operations
+def SEAMOPS : I<0x01, MRM_CE, (outs), (ins),
+ "seamops", []>, PD;
+
+} // SchedRW
+
+// common instructions
+let SchedRW = [WriteSystem] in {
+// TDCALL - Call SEAM Module Functions
+def TDCALL : I<0x01, MRM_CC, (outs), (ins),
+ "tdcall", []>, PD;
+
+} // SchedRW
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InstructionSelector.cpp b/contrib/libs/llvm12/lib/Target/X86/X86InstructionSelector.cpp
index 8a3091af28..ff53171303 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InstructionSelector.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InstructionSelector.cpp
@@ -214,8 +214,8 @@ static unsigned getSubRegIndex(const TargetRegisterClass *RC) {
return SubIdx;
}
-static const TargetRegisterClass *getRegClassFromGRPhysReg(Register Reg) {
- assert(Reg.isPhysical());
+static const TargetRegisterClass *getRegClassFromGRPhysReg(Register Reg) {
+ assert(Reg.isPhysical());
if (X86::GR64RegClass.contains(Reg))
return &X86::GR64RegClass;
if (X86::GR32RegClass.contains(Reg))
@@ -239,7 +239,7 @@ bool X86InstructionSelector::selectCopy(MachineInstr &I,
const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
const RegisterBank &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
- if (DstReg.isPhysical()) {
+ if (DstReg.isPhysical()) {
assert(I.isCopy() && "Generic operators do not allow physical registers");
if (DstSize > SrcSize && SrcRegBank.getID() == X86::GPRRegBankID &&
@@ -266,12 +266,12 @@ bool X86InstructionSelector::selectCopy(MachineInstr &I,
return true;
}
- assert((!SrcReg.isPhysical() || I.isCopy()) &&
+ assert((!SrcReg.isPhysical() || I.isCopy()) &&
"No phys reg on generic operators");
assert((DstSize == SrcSize ||
// Copies are a mean to setup initial types, the number of
// bits may not exactly match.
- (SrcReg.isPhysical() &&
+ (SrcReg.isPhysical() &&
DstSize <= RBI.getSizeInBits(SrcReg, MRI, TRI))) &&
"Copy with different width?!");
@@ -280,7 +280,7 @@ bool X86InstructionSelector::selectCopy(MachineInstr &I,
if (SrcRegBank.getID() == X86::GPRRegBankID &&
DstRegBank.getID() == X86::GPRRegBankID && SrcSize > DstSize &&
- SrcReg.isPhysical()) {
+ SrcReg.isPhysical()) {
// Change the physical register to performe truncate.
const TargetRegisterClass *SrcRC = getRegClassFromGRPhysReg(SrcReg);
@@ -479,7 +479,7 @@ static void X86SelectAddress(const MachineInstr &I,
"unsupported type.");
if (I.getOpcode() == TargetOpcode::G_PTR_ADD) {
- if (auto COff = getConstantVRegSExtVal(I.getOperand(2).getReg(), MRI)) {
+ if (auto COff = getConstantVRegSExtVal(I.getOperand(2).getReg(), MRI)) {
int64_t Imm = *COff;
if (isInt<32>(Imm)) { // Check for displacement overflow.
AM.Disp = static_cast<int32_t>(Imm);
@@ -780,18 +780,18 @@ bool X86InstructionSelector::selectZext(MachineInstr &I,
const LLT DstTy = MRI.getType(DstReg);
const LLT SrcTy = MRI.getType(SrcReg);
- assert(!(SrcTy == LLT::scalar(8) && DstTy == LLT::scalar(16)) &&
- "8=>16 Zext is handled by tablegen");
+ assert(!(SrcTy == LLT::scalar(8) && DstTy == LLT::scalar(16)) &&
+ "8=>16 Zext is handled by tablegen");
assert(!(SrcTy == LLT::scalar(8) && DstTy == LLT::scalar(32)) &&
"8=>32 Zext is handled by tablegen");
assert(!(SrcTy == LLT::scalar(16) && DstTy == LLT::scalar(32)) &&
"16=>32 Zext is handled by tablegen");
- assert(!(SrcTy == LLT::scalar(8) && DstTy == LLT::scalar(64)) &&
- "8=>64 Zext is handled by tablegen");
- assert(!(SrcTy == LLT::scalar(16) && DstTy == LLT::scalar(64)) &&
- "16=>64 Zext is handled by tablegen");
- assert(!(SrcTy == LLT::scalar(32) && DstTy == LLT::scalar(64)) &&
- "32=>64 Zext is handled by tablegen");
+ assert(!(SrcTy == LLT::scalar(8) && DstTy == LLT::scalar(64)) &&
+ "8=>64 Zext is handled by tablegen");
+ assert(!(SrcTy == LLT::scalar(16) && DstTy == LLT::scalar(64)) &&
+ "16=>64 Zext is handled by tablegen");
+ assert(!(SrcTy == LLT::scalar(32) && DstTy == LLT::scalar(64)) &&
+ "32=>64 Zext is handled by tablegen");
if (SrcTy != LLT::scalar(1))
return false;
@@ -808,17 +808,17 @@ bool X86InstructionSelector::selectZext(MachineInstr &I,
else
return false;
- Register DefReg = SrcReg;
+ Register DefReg = SrcReg;
if (DstTy != LLT::scalar(8)) {
- Register ImpDefReg =
- MRI.createVirtualRegister(getRegClass(DstTy, DstReg, MRI));
- BuildMI(*I.getParent(), I, I.getDebugLoc(),
- TII.get(TargetOpcode::IMPLICIT_DEF), ImpDefReg);
-
+ Register ImpDefReg =
+ MRI.createVirtualRegister(getRegClass(DstTy, DstReg, MRI));
+ BuildMI(*I.getParent(), I, I.getDebugLoc(),
+ TII.get(TargetOpcode::IMPLICIT_DEF), ImpDefReg);
+
DefReg = MRI.createVirtualRegister(getRegClass(DstTy, DstReg, MRI));
BuildMI(*I.getParent(), I, I.getDebugLoc(),
- TII.get(TargetOpcode::INSERT_SUBREG), DefReg)
- .addReg(ImpDefReg)
+ TII.get(TargetOpcode::INSERT_SUBREG), DefReg)
+ .addReg(ImpDefReg)
.addReg(SrcReg)
.addImm(X86::sub_8bit);
}
@@ -1559,9 +1559,9 @@ bool X86InstructionSelector::selectDivRem(MachineInstr &I,
}}, // i64
};
- auto OpEntryIt = llvm::find_if(OpTable, [RegTy](const DivRemEntry &El) {
- return El.SizeInBits == RegTy.getSizeInBits();
- });
+ auto OpEntryIt = llvm::find_if(OpTable, [RegTy](const DivRemEntry &El) {
+ return El.SizeInBits == RegTy.getSizeInBits();
+ });
if (OpEntryIt == std::end(OpTable))
return false;
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86InterleavedAccess.cpp b/contrib/libs/llvm12/lib/Target/X86/X86InterleavedAccess.cpp
index 83829e0b82..95655dd472 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86InterleavedAccess.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86InterleavedAccess.cpp
@@ -44,8 +44,8 @@ namespace {
/// E.g. A group of interleaving access loads (Factor = 2; accessing every
/// other element)
/// %wide.vec = load <8 x i32>, <8 x i32>* %ptr
-/// %v0 = shuffle <8 x i32> %wide.vec, <8 x i32> poison, <0, 2, 4, 6>
-/// %v1 = shuffle <8 x i32> %wide.vec, <8 x i32> poison, <1, 3, 5, 7>
+/// %v0 = shuffle <8 x i32> %wide.vec, <8 x i32> poison, <0, 2, 4, 6>
+/// %v1 = shuffle <8 x i32> %wide.vec, <8 x i32> poison, <1, 3, 5, 7>
class X86InterleavedAccessGroup {
/// Reference to the wide-load instruction of an interleaved access
/// group.
@@ -211,7 +211,7 @@ void X86InterleavedAccessGroup::decompose(
VecBasePtr = Builder.CreateBitCast(LI->getPointerOperand(), VecBasePtrTy);
}
// Generate N loads of T type.
- assert(VecBaseTy->getPrimitiveSizeInBits().isKnownMultipleOf(8) &&
+ assert(VecBaseTy->getPrimitiveSizeInBits().isKnownMultipleOf(8) &&
"VecBaseTy's size must be a multiple of 8");
const Align FirstAlignment = LI->getAlign();
const Align SubsequentAlignment = commonAlignment(
@@ -295,7 +295,7 @@ static void reorderSubVector(MVT VT, SmallVectorImpl<Value *> &TransposedMatrix,
if (VecElems == 16) {
for (unsigned i = 0; i < Stride; i++)
- TransposedMatrix[i] = Builder.CreateShuffleVector(Vec[i], VPShuf);
+ TransposedMatrix[i] = Builder.CreateShuffleVector(Vec[i], VPShuf);
return;
}
@@ -576,7 +576,7 @@ void X86InterleavedAccessGroup::deinterleave8bitStride3(
// Vec[2]= b5 b6 b7 c5 c6 c7 a6 a7
for (int i = 0; i < 3; i++)
- Vec[i] = Builder.CreateShuffleVector(Vec[i], VPShuf);
+ Vec[i] = Builder.CreateShuffleVector(Vec[i], VPShuf);
// TempVector[0]= a6 a7 a0 a1 a2 b0 b1 b2
// TempVector[1]= c0 c1 c2 c3 c4 a3 a4 a5
@@ -598,8 +598,8 @@ void X86InterleavedAccessGroup::deinterleave8bitStride3(
// TransposedMatrix[1]= b0 b1 b2 b3 b4 b5 b6 b7
// TransposedMatrix[2]= c0 c1 c2 c3 c4 c5 c6 c7
- Value *TempVec = Builder.CreateShuffleVector(Vec[1], VPAlign3);
- TransposedMatrix[0] = Builder.CreateShuffleVector(Vec[0], VPAlign2);
+ Value *TempVec = Builder.CreateShuffleVector(Vec[1], VPAlign3);
+ TransposedMatrix[0] = Builder.CreateShuffleVector(Vec[0], VPAlign2);
TransposedMatrix[1] = VecElems == 8 ? Vec[2] : TempVec;
TransposedMatrix[2] = VecElems == 8 ? TempVec : Vec[2];
}
@@ -656,8 +656,8 @@ void X86InterleavedAccessGroup::interleave8bitStride3(
// Vec[1]= c5 c6 c7 c0 c1 c2 c3 c4
// Vec[2]= b0 b1 b2 b3 b4 b5 b6 b7
- Vec[0] = Builder.CreateShuffleVector(InVec[0], VPAlign2);
- Vec[1] = Builder.CreateShuffleVector(InVec[1], VPAlign3);
+ Vec[0] = Builder.CreateShuffleVector(InVec[0], VPAlign2);
+ Vec[1] = Builder.CreateShuffleVector(InVec[1], VPAlign3);
Vec[2] = InVec[2];
// Vec[0]= a6 a7 a0 a1 a2 b0 b1 b2
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86IntrinsicsInfo.h b/contrib/libs/llvm12/lib/Target/X86/X86IntrinsicsInfo.h
index 233ac1a3e3..72ab3e9cf7 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86IntrinsicsInfo.h
+++ b/contrib/libs/llvm12/lib/Target/X86/X86IntrinsicsInfo.h
@@ -22,7 +22,7 @@ namespace llvm {
enum IntrinsicType : uint16_t {
CVTNEPS2BF16_MASK,
GATHER, SCATTER, PREFETCH, RDSEED, RDRAND, RDPMC, RDTSC, XTEST, XGETBV, ADX, FPCLASSS,
- INTR_TYPE_1OP, INTR_TYPE_2OP, INTR_TYPE_3OP, INTR_TYPE_4OP_IMM8,
+ INTR_TYPE_1OP, INTR_TYPE_2OP, INTR_TYPE_3OP, INTR_TYPE_4OP_IMM8,
INTR_TYPE_3OP_IMM8,
CMP_MASK_CC,CMP_MASK_SCALAR_CC, VSHIFT, COMI, COMI_RM, BLENDV, BEXTRI,
CVTPD2PS_MASK,
@@ -458,12 +458,12 @@ static const IntrinsicData IntrinsicsWithoutChain[] = {
X86ISD::FADDS, X86ISD::FADDS_RND),
X86_INTRINSIC_DATA(avx512_mask_add_ss_round, INTR_TYPE_SCALAR_MASK,
X86ISD::FADDS, X86ISD::FADDS_RND),
- X86_INTRINSIC_DATA(avx512_mask_cmp_pd_128, CMP_MASK_CC, X86ISD::CMPMM, 0),
- X86_INTRINSIC_DATA(avx512_mask_cmp_pd_256, CMP_MASK_CC, X86ISD::CMPMM, 0),
- X86_INTRINSIC_DATA(avx512_mask_cmp_pd_512, CMP_MASK_CC, X86ISD::CMPMM, X86ISD::CMPMM_SAE),
- X86_INTRINSIC_DATA(avx512_mask_cmp_ps_128, CMP_MASK_CC, X86ISD::CMPMM, 0),
- X86_INTRINSIC_DATA(avx512_mask_cmp_ps_256, CMP_MASK_CC, X86ISD::CMPMM, 0),
- X86_INTRINSIC_DATA(avx512_mask_cmp_ps_512, CMP_MASK_CC, X86ISD::CMPMM, X86ISD::CMPMM_SAE),
+ X86_INTRINSIC_DATA(avx512_mask_cmp_pd_128, CMP_MASK_CC, X86ISD::CMPMM, 0),
+ X86_INTRINSIC_DATA(avx512_mask_cmp_pd_256, CMP_MASK_CC, X86ISD::CMPMM, 0),
+ X86_INTRINSIC_DATA(avx512_mask_cmp_pd_512, CMP_MASK_CC, X86ISD::CMPMM, X86ISD::CMPMM_SAE),
+ X86_INTRINSIC_DATA(avx512_mask_cmp_ps_128, CMP_MASK_CC, X86ISD::CMPMM, 0),
+ X86_INTRINSIC_DATA(avx512_mask_cmp_ps_256, CMP_MASK_CC, X86ISD::CMPMM, 0),
+ X86_INTRINSIC_DATA(avx512_mask_cmp_ps_512, CMP_MASK_CC, X86ISD::CMPMM, X86ISD::CMPMM_SAE),
X86_INTRINSIC_DATA(avx512_mask_cmp_sd, CMP_MASK_SCALAR_CC,
X86ISD::FSETCCM, X86ISD::FSETCCM_SAE),
X86_INTRINSIC_DATA(avx512_mask_cmp_ss, CMP_MASK_SCALAR_CC,
@@ -882,12 +882,12 @@ static const IntrinsicData IntrinsicsWithoutChain[] = {
X86_INTRINSIC_DATA(avx512_psrlv_w_128, INTR_TYPE_2OP, X86ISD::VSRLV, 0),
X86_INTRINSIC_DATA(avx512_psrlv_w_256, INTR_TYPE_2OP, X86ISD::VSRLV, 0),
X86_INTRINSIC_DATA(avx512_psrlv_w_512, INTR_TYPE_2OP, X86ISD::VSRLV, 0),
- X86_INTRINSIC_DATA(avx512_pternlog_d_128, INTR_TYPE_4OP_IMM8, X86ISD::VPTERNLOG, 0),
- X86_INTRINSIC_DATA(avx512_pternlog_d_256, INTR_TYPE_4OP_IMM8, X86ISD::VPTERNLOG, 0),
- X86_INTRINSIC_DATA(avx512_pternlog_d_512, INTR_TYPE_4OP_IMM8, X86ISD::VPTERNLOG, 0),
- X86_INTRINSIC_DATA(avx512_pternlog_q_128, INTR_TYPE_4OP_IMM8, X86ISD::VPTERNLOG, 0),
- X86_INTRINSIC_DATA(avx512_pternlog_q_256, INTR_TYPE_4OP_IMM8, X86ISD::VPTERNLOG, 0),
- X86_INTRINSIC_DATA(avx512_pternlog_q_512, INTR_TYPE_4OP_IMM8, X86ISD::VPTERNLOG, 0),
+ X86_INTRINSIC_DATA(avx512_pternlog_d_128, INTR_TYPE_4OP_IMM8, X86ISD::VPTERNLOG, 0),
+ X86_INTRINSIC_DATA(avx512_pternlog_d_256, INTR_TYPE_4OP_IMM8, X86ISD::VPTERNLOG, 0),
+ X86_INTRINSIC_DATA(avx512_pternlog_d_512, INTR_TYPE_4OP_IMM8, X86ISD::VPTERNLOG, 0),
+ X86_INTRINSIC_DATA(avx512_pternlog_q_128, INTR_TYPE_4OP_IMM8, X86ISD::VPTERNLOG, 0),
+ X86_INTRINSIC_DATA(avx512_pternlog_q_256, INTR_TYPE_4OP_IMM8, X86ISD::VPTERNLOG, 0),
+ X86_INTRINSIC_DATA(avx512_pternlog_q_512, INTR_TYPE_4OP_IMM8, X86ISD::VPTERNLOG, 0),
X86_INTRINSIC_DATA(avx512_rcp14_pd_128, INTR_TYPE_1OP_MASK, X86ISD::RCP14, 0),
X86_INTRINSIC_DATA(avx512_rcp14_pd_256, INTR_TYPE_1OP_MASK, X86ISD::RCP14, 0),
X86_INTRINSIC_DATA(avx512_rcp14_pd_512, INTR_TYPE_1OP_MASK, X86ISD::RCP14, 0),
@@ -1098,7 +1098,7 @@ static const IntrinsicData IntrinsicsWithoutChain[] = {
X86_INTRINSIC_DATA(sse41_round_sd, ROUNDS, X86ISD::VRNDSCALES, 0),
X86_INTRINSIC_DATA(sse41_round_ss, ROUNDS, X86ISD::VRNDSCALES, 0),
X86_INTRINSIC_DATA(sse4a_extrqi, INTR_TYPE_3OP, X86ISD::EXTRQI, 0),
- X86_INTRINSIC_DATA(sse4a_insertqi, INTR_TYPE_4OP_IMM8, X86ISD::INSERTQI, 0),
+ X86_INTRINSIC_DATA(sse4a_insertqi, INTR_TYPE_4OP_IMM8, X86ISD::INSERTQI, 0),
X86_INTRINSIC_DATA(ssse3_phadd_d_128, INTR_TYPE_2OP, X86ISD::HADD, 0),
X86_INTRINSIC_DATA(ssse3_phadd_w_128, INTR_TYPE_2OP, X86ISD::HADD, 0),
X86_INTRINSIC_DATA(ssse3_phsub_d_128, INTR_TYPE_2OP, X86ISD::HSUB, 0),
@@ -1108,8 +1108,8 @@ static const IntrinsicData IntrinsicsWithoutChain[] = {
X86_INTRINSIC_DATA(ssse3_pshuf_b_128, INTR_TYPE_2OP, X86ISD::PSHUFB, 0),
X86_INTRINSIC_DATA(subborrow_32, ADX, X86ISD::SBB, X86ISD::SUB),
X86_INTRINSIC_DATA(subborrow_64, ADX, X86ISD::SBB, X86ISD::SUB),
- X86_INTRINSIC_DATA(tbm_bextri_u32, BEXTRI, X86ISD::BEXTRI, 0),
- X86_INTRINSIC_DATA(tbm_bextri_u64, BEXTRI, X86ISD::BEXTRI, 0),
+ X86_INTRINSIC_DATA(tbm_bextri_u32, BEXTRI, X86ISD::BEXTRI, 0),
+ X86_INTRINSIC_DATA(tbm_bextri_u64, BEXTRI, X86ISD::BEXTRI, 0),
X86_INTRINSIC_DATA(vcvtps2ph_128, INTR_TYPE_2OP, X86ISD::CVTPS2PH, 0),
X86_INTRINSIC_DATA(vcvtps2ph_256, INTR_TYPE_2OP, X86ISD::CVTPS2PH, 0),
@@ -1132,10 +1132,10 @@ static const IntrinsicData IntrinsicsWithoutChain[] = {
X86_INTRINSIC_DATA(vgf2p8mulb_512, INTR_TYPE_2OP,
X86ISD::GF2P8MULB, 0),
- X86_INTRINSIC_DATA(xop_vpermil2pd, INTR_TYPE_4OP_IMM8, X86ISD::VPERMIL2, 0),
- X86_INTRINSIC_DATA(xop_vpermil2pd_256, INTR_TYPE_4OP_IMM8, X86ISD::VPERMIL2, 0),
- X86_INTRINSIC_DATA(xop_vpermil2ps, INTR_TYPE_4OP_IMM8, X86ISD::VPERMIL2, 0),
- X86_INTRINSIC_DATA(xop_vpermil2ps_256, INTR_TYPE_4OP_IMM8, X86ISD::VPERMIL2, 0),
+ X86_INTRINSIC_DATA(xop_vpermil2pd, INTR_TYPE_4OP_IMM8, X86ISD::VPERMIL2, 0),
+ X86_INTRINSIC_DATA(xop_vpermil2pd_256, INTR_TYPE_4OP_IMM8, X86ISD::VPERMIL2, 0),
+ X86_INTRINSIC_DATA(xop_vpermil2ps, INTR_TYPE_4OP_IMM8, X86ISD::VPERMIL2, 0),
+ X86_INTRINSIC_DATA(xop_vpermil2ps_256, INTR_TYPE_4OP_IMM8, X86ISD::VPERMIL2, 0),
X86_INTRINSIC_DATA(xop_vpperm, INTR_TYPE_3OP, X86ISD::VPPERM, 0),
X86_INTRINSIC_DATA(xop_vpshab, INTR_TYPE_2OP, X86ISD::VPSHA, 0),
X86_INTRINSIC_DATA(xop_vpshad, INTR_TYPE_2OP, X86ISD::VPSHA, 0),
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86LegalizerInfo.cpp b/contrib/libs/llvm12/lib/Target/X86/X86LegalizerInfo.cpp
index 9f51fa4f4c..1b371ac2a1 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86LegalizerInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86LegalizerInfo.cpp
@@ -70,11 +70,11 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
setLegalizerInfoAVX512DQ();
setLegalizerInfoAVX512BW();
- getActionDefinitionsBuilder(G_INTRINSIC_ROUNDEVEN)
- .scalarize(0)
- .minScalar(0, LLT::scalar(32))
- .libcall();
-
+ getActionDefinitionsBuilder(G_INTRINSIC_ROUNDEVEN)
+ .scalarize(0)
+ .minScalar(0, LLT::scalar(32))
+ .libcall();
+
setLegalizeScalarToDifferentSizeStrategy(G_PHI, 0, widen_1);
for (unsigned BinOp : {G_SUB, G_MUL, G_AND, G_OR, G_XOR})
setLegalizeScalarToDifferentSizeStrategy(BinOp, 0, widen_1);
@@ -86,8 +86,8 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
setLegalizeScalarToDifferentSizeStrategy(
G_CONSTANT, 0, widenToLargerTypesAndNarrowToLargest);
- getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE, G_MEMSET}).libcall();
-
+ getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE, G_MEMSET}).libcall();
+
computeTables();
verify(*STI.getInstrInfo());
}
@@ -155,11 +155,11 @@ void X86LegalizerInfo::setLegalizerInfo32bit() {
.legalFor({{s8, s8}, {s16, s8}, {s32, s8}})
.clampScalar(0, s8, s32)
.clampScalar(1, s8, s8);
-
- // Comparison
- getActionDefinitionsBuilder(G_ICMP)
- .legalForCartesianProduct({s8}, {s8, s16, s32, p0})
- .clampScalar(0, s8, s8);
+
+ // Comparison
+ getActionDefinitionsBuilder(G_ICMP)
+ .legalForCartesianProduct({s8}, {s8, s16, s32, p0})
+ .clampScalar(0, s8, s8);
}
// Control-flow
@@ -246,9 +246,9 @@ void X86LegalizerInfo::setLegalizerInfo64bit() {
.widenScalarToNextPow2(1);
// Comparison
- getActionDefinitionsBuilder(G_ICMP)
- .legalForCartesianProduct({s8}, {s8, s16, s32, s64, p0})
- .clampScalar(0, s8, s8);
+ getActionDefinitionsBuilder(G_ICMP)
+ .legalForCartesianProduct({s8}, {s8, s16, s32, s64, p0})
+ .clampScalar(0, s8, s8);
getActionDefinitionsBuilder(G_FCMP)
.legalForCartesianProduct({s8}, {s32, s64})
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp b/contrib/libs/llvm12/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp
index e419f45405..810fee052b 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp
@@ -42,7 +42,7 @@
#include "X86TargetMachine.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
@@ -105,9 +105,9 @@ static cl::opt<bool> EmitDotVerify(
cl::init(false), cl::Hidden);
static llvm::sys::DynamicLibrary OptimizeDL;
-typedef int (*OptimizeCutT)(unsigned int *Nodes, unsigned int NodesSize,
- unsigned int *Edges, int *EdgeValues,
- int *CutEdges /* out */, unsigned int EdgesSize);
+typedef int (*OptimizeCutT)(unsigned int *Nodes, unsigned int NodesSize,
+ unsigned int *Edges, int *EdgeValues,
+ int *CutEdges /* out */, unsigned int EdgesSize);
static OptimizeCutT OptimizeCut = nullptr;
namespace {
@@ -149,8 +149,8 @@ public:
private:
using GraphBuilder = ImmutableGraphBuilder<MachineGadgetGraph>;
- using Edge = MachineGadgetGraph::Edge;
- using Node = MachineGadgetGraph::Node;
+ using Edge = MachineGadgetGraph::Edge;
+ using Node = MachineGadgetGraph::Node;
using EdgeSet = MachineGadgetGraph::EdgeSet;
using NodeSet = MachineGadgetGraph::NodeSet;
@@ -164,8 +164,8 @@ private:
const MachineDominanceFrontier &MDF) const;
int hardenLoadsWithPlugin(MachineFunction &MF,
std::unique_ptr<MachineGadgetGraph> Graph) const;
- int hardenLoadsWithHeuristic(MachineFunction &MF,
- std::unique_ptr<MachineGadgetGraph> Graph) const;
+ int hardenLoadsWithHeuristic(MachineFunction &MF,
+ std::unique_ptr<MachineGadgetGraph> Graph) const;
int elimMitigatedEdgesAndNodes(MachineGadgetGraph &G,
EdgeSet &ElimEdges /* in, out */,
NodeSet &ElimNodes /* in, out */) const;
@@ -198,7 +198,7 @@ struct DOTGraphTraits<MachineGadgetGraph *> : DefaultDOTGraphTraits {
using ChildIteratorType = typename Traits::ChildIteratorType;
using ChildEdgeIteratorType = typename Traits::ChildEdgeIteratorType;
- DOTGraphTraits(bool IsSimple = false) : DefaultDOTGraphTraits(IsSimple) {}
+ DOTGraphTraits(bool IsSimple = false) : DefaultDOTGraphTraits(IsSimple) {}
std::string getNodeLabel(NodeRef Node, GraphType *) {
if (Node->getValue() == MachineGadgetGraph::ArgNodeSentinel)
@@ -243,7 +243,7 @@ void X86LoadValueInjectionLoadHardeningPass::getAnalysisUsage(
AU.setPreservesCFG();
}
-static void writeGadgetGraph(raw_ostream &OS, MachineFunction &MF,
+static void writeGadgetGraph(raw_ostream &OS, MachineFunction &MF,
MachineGadgetGraph *G) {
WriteGraph(OS, G, /*ShortNames*/ false,
"Speculative gadgets for \"" + MF.getName() + "\" function");
@@ -279,7 +279,7 @@ bool X86LoadValueInjectionLoadHardeningPass::runOnMachineFunction(
return false; // didn't find any gadgets
if (EmitDotVerify) {
- writeGadgetGraph(outs(), MF, Graph.get());
+ writeGadgetGraph(outs(), MF, Graph.get());
return false;
}
@@ -292,7 +292,7 @@ bool X86LoadValueInjectionLoadHardeningPass::runOnMachineFunction(
raw_fd_ostream FileOut(FileName, FileError);
if (FileError)
errs() << FileError.message();
- writeGadgetGraph(FileOut, MF, Graph.get());
+ writeGadgetGraph(FileOut, MF, Graph.get());
FileOut.close();
LLVM_DEBUG(dbgs() << "Emitting gadget graph... Done\n");
if (EmitDotOnly)
@@ -313,7 +313,7 @@ bool X86LoadValueInjectionLoadHardeningPass::runOnMachineFunction(
}
FencesInserted = hardenLoadsWithPlugin(MF, std::move(Graph));
} else { // Use the default greedy heuristic
- FencesInserted = hardenLoadsWithHeuristic(MF, std::move(Graph));
+ FencesInserted = hardenLoadsWithHeuristic(MF, std::move(Graph));
}
if (FencesInserted > 0)
@@ -367,7 +367,7 @@ X86LoadValueInjectionLoadHardeningPass::getGadgetGraph(
// Use RDF to find all the uses of `Def`
rdf::NodeSet Uses;
- RegisterRef DefReg = Def.Addr->getRegRef(DFG);
+ RegisterRef DefReg = Def.Addr->getRegRef(DFG);
for (auto UseID : L.getAllReachedUses(DefReg, Def)) {
auto Use = DFG.addr<UseNode *>(UseID);
if (Use.Addr->getFlags() & NodeAttrs::PhiRef) { // phi node
@@ -540,17 +540,17 @@ X86LoadValueInjectionLoadHardeningPass::getGadgetGraph(
// Returns the number of remaining gadget edges that could not be eliminated
int X86LoadValueInjectionLoadHardeningPass::elimMitigatedEdgesAndNodes(
- MachineGadgetGraph &G, EdgeSet &ElimEdges /* in, out */,
- NodeSet &ElimNodes /* in, out */) const {
+ MachineGadgetGraph &G, EdgeSet &ElimEdges /* in, out */,
+ NodeSet &ElimNodes /* in, out */) const {
if (G.NumFences > 0) {
// Eliminate fences and CFG edges that ingress and egress the fence, as
// they are trivially mitigated.
- for (const Edge &E : G.edges()) {
- const Node *Dest = E.getDest();
+ for (const Edge &E : G.edges()) {
+ const Node *Dest = E.getDest();
if (isFence(Dest->getValue())) {
ElimNodes.insert(*Dest);
ElimEdges.insert(E);
- for (const Edge &DE : Dest->edges())
+ for (const Edge &DE : Dest->edges())
ElimEdges.insert(DE);
}
}
@@ -558,28 +558,28 @@ int X86LoadValueInjectionLoadHardeningPass::elimMitigatedEdgesAndNodes(
// Find and eliminate gadget edges that have been mitigated.
int MitigatedGadgets = 0, RemainingGadgets = 0;
- NodeSet ReachableNodes{G};
- for (const Node &RootN : G.nodes()) {
+ NodeSet ReachableNodes{G};
+ for (const Node &RootN : G.nodes()) {
if (llvm::none_of(RootN.edges(), MachineGadgetGraph::isGadgetEdge))
continue; // skip this node if it isn't a gadget source
// Find all of the nodes that are CFG-reachable from RootN using DFS
ReachableNodes.clear();
- std::function<void(const Node *, bool)> FindReachableNodes =
- [&](const Node *N, bool FirstNode) {
- if (!FirstNode)
- ReachableNodes.insert(*N);
- for (const Edge &E : N->edges()) {
- const Node *Dest = E.getDest();
- if (MachineGadgetGraph::isCFGEdge(E) && !ElimEdges.contains(E) &&
- !ReachableNodes.contains(*Dest))
- FindReachableNodes(Dest, false);
- }
- };
+ std::function<void(const Node *, bool)> FindReachableNodes =
+ [&](const Node *N, bool FirstNode) {
+ if (!FirstNode)
+ ReachableNodes.insert(*N);
+ for (const Edge &E : N->edges()) {
+ const Node *Dest = E.getDest();
+ if (MachineGadgetGraph::isCFGEdge(E) && !ElimEdges.contains(E) &&
+ !ReachableNodes.contains(*Dest))
+ FindReachableNodes(Dest, false);
+ }
+ };
FindReachableNodes(&RootN, true);
// Any gadget whose sink is unreachable has been mitigated
- for (const Edge &E : RootN.edges()) {
+ for (const Edge &E : RootN.edges()) {
if (MachineGadgetGraph::isGadgetEdge(E)) {
if (ReachableNodes.contains(*E.getDest())) {
// This gadget's sink is reachable
@@ -597,8 +597,8 @@ int X86LoadValueInjectionLoadHardeningPass::elimMitigatedEdgesAndNodes(
std::unique_ptr<MachineGadgetGraph>
X86LoadValueInjectionLoadHardeningPass::trimMitigatedEdges(
std::unique_ptr<MachineGadgetGraph> Graph) const {
- NodeSet ElimNodes{*Graph};
- EdgeSet ElimEdges{*Graph};
+ NodeSet ElimNodes{*Graph};
+ EdgeSet ElimEdges{*Graph};
int RemainingGadgets =
elimMitigatedEdgesAndNodes(*Graph, ElimEdges, ElimNodes);
if (ElimEdges.empty() && ElimNodes.empty()) {
@@ -629,11 +629,11 @@ int X86LoadValueInjectionLoadHardeningPass::hardenLoadsWithPlugin(
auto Edges = std::make_unique<unsigned int[]>(Graph->edges_size());
auto EdgeCuts = std::make_unique<int[]>(Graph->edges_size());
auto EdgeValues = std::make_unique<int[]>(Graph->edges_size());
- for (const Node &N : Graph->nodes()) {
+ for (const Node &N : Graph->nodes()) {
Nodes[Graph->getNodeIndex(N)] = Graph->getEdgeIndex(*N.edges_begin());
}
Nodes[Graph->nodes_size()] = Graph->edges_size(); // terminator node
- for (const Edge &E : Graph->edges()) {
+ for (const Edge &E : Graph->edges()) {
Edges[Graph->getEdgeIndex(E)] = Graph->getNodeIndex(*E.getDest());
EdgeValues[Graph->getEdgeIndex(E)] = E.getValue();
}
@@ -650,67 +650,67 @@ int X86LoadValueInjectionLoadHardeningPass::hardenLoadsWithPlugin(
LLVM_DEBUG(dbgs() << "Inserting LFENCEs... Done\n");
LLVM_DEBUG(dbgs() << "Inserted " << FencesInserted << " fences\n");
- Graph = GraphBuilder::trim(*Graph, NodeSet{*Graph}, CutEdges);
+ Graph = GraphBuilder::trim(*Graph, NodeSet{*Graph}, CutEdges);
} while (true);
return FencesInserted;
}
-int X86LoadValueInjectionLoadHardeningPass::hardenLoadsWithHeuristic(
+int X86LoadValueInjectionLoadHardeningPass::hardenLoadsWithHeuristic(
MachineFunction &MF, std::unique_ptr<MachineGadgetGraph> Graph) const {
- // If `MF` does not have any fences, then no gadgets would have been
- // mitigated at this point.
- if (Graph->NumFences > 0) {
- LLVM_DEBUG(dbgs() << "Eliminating mitigated paths...\n");
- Graph = trimMitigatedEdges(std::move(Graph));
- LLVM_DEBUG(dbgs() << "Eliminating mitigated paths... Done\n");
- }
-
+ // If `MF` does not have any fences, then no gadgets would have been
+ // mitigated at this point.
+ if (Graph->NumFences > 0) {
+ LLVM_DEBUG(dbgs() << "Eliminating mitigated paths...\n");
+ Graph = trimMitigatedEdges(std::move(Graph));
+ LLVM_DEBUG(dbgs() << "Eliminating mitigated paths... Done\n");
+ }
+
if (Graph->NumGadgets == 0)
return 0;
LLVM_DEBUG(dbgs() << "Cutting edges...\n");
- EdgeSet CutEdges{*Graph};
-
- // Begin by collecting all ingress CFG edges for each node
- DenseMap<const Node *, SmallVector<const Edge *, 2>> IngressEdgeMap;
- for (const Edge &E : Graph->edges())
- if (MachineGadgetGraph::isCFGEdge(E))
- IngressEdgeMap[E.getDest()].push_back(&E);
-
- // For each gadget edge, make cuts that guarantee the gadget will be
- // mitigated. A computationally efficient way to achieve this is to either:
- // (a) cut all egress CFG edges from the gadget source, or
- // (b) cut all ingress CFG edges to the gadget sink.
- //
- // Moreover, the algorithm tries not to make a cut into a loop by preferring
- // to make a (b)-type cut if the gadget source resides at a greater loop depth
- // than the gadget sink, or an (a)-type cut otherwise.
- for (const Node &N : Graph->nodes()) {
- for (const Edge &E : N.edges()) {
- if (!MachineGadgetGraph::isGadgetEdge(E))
+ EdgeSet CutEdges{*Graph};
+
+ // Begin by collecting all ingress CFG edges for each node
+ DenseMap<const Node *, SmallVector<const Edge *, 2>> IngressEdgeMap;
+ for (const Edge &E : Graph->edges())
+ if (MachineGadgetGraph::isCFGEdge(E))
+ IngressEdgeMap[E.getDest()].push_back(&E);
+
+ // For each gadget edge, make cuts that guarantee the gadget will be
+ // mitigated. A computationally efficient way to achieve this is to either:
+ // (a) cut all egress CFG edges from the gadget source, or
+ // (b) cut all ingress CFG edges to the gadget sink.
+ //
+ // Moreover, the algorithm tries not to make a cut into a loop by preferring
+ // to make a (b)-type cut if the gadget source resides at a greater loop depth
+ // than the gadget sink, or an (a)-type cut otherwise.
+ for (const Node &N : Graph->nodes()) {
+ for (const Edge &E : N.edges()) {
+ if (!MachineGadgetGraph::isGadgetEdge(E))
continue;
- SmallVector<const Edge *, 2> EgressEdges;
- SmallVector<const Edge *, 2> &IngressEdges = IngressEdgeMap[E.getDest()];
- for (const Edge &EgressEdge : N.edges())
- if (MachineGadgetGraph::isCFGEdge(EgressEdge))
- EgressEdges.push_back(&EgressEdge);
-
- int EgressCutCost = 0, IngressCutCost = 0;
- for (const Edge *EgressEdge : EgressEdges)
- if (!CutEdges.contains(*EgressEdge))
- EgressCutCost += EgressEdge->getValue();
- for (const Edge *IngressEdge : IngressEdges)
- if (!CutEdges.contains(*IngressEdge))
- IngressCutCost += IngressEdge->getValue();
-
- auto &EdgesToCut =
- IngressCutCost < EgressCutCost ? IngressEdges : EgressEdges;
- for (const Edge *E : EdgesToCut)
- CutEdges.insert(*E);
+ SmallVector<const Edge *, 2> EgressEdges;
+ SmallVector<const Edge *, 2> &IngressEdges = IngressEdgeMap[E.getDest()];
+ for (const Edge &EgressEdge : N.edges())
+ if (MachineGadgetGraph::isCFGEdge(EgressEdge))
+ EgressEdges.push_back(&EgressEdge);
+
+ int EgressCutCost = 0, IngressCutCost = 0;
+ for (const Edge *EgressEdge : EgressEdges)
+ if (!CutEdges.contains(*EgressEdge))
+ EgressCutCost += EgressEdge->getValue();
+ for (const Edge *IngressEdge : IngressEdges)
+ if (!CutEdges.contains(*IngressEdge))
+ IngressCutCost += IngressEdge->getValue();
+
+ auto &EdgesToCut =
+ IngressCutCost < EgressCutCost ? IngressEdges : EgressEdges;
+ for (const Edge *E : EdgesToCut)
+ CutEdges.insert(*E);
}
- }
+ }
LLVM_DEBUG(dbgs() << "Cutting edges... Done\n");
LLVM_DEBUG(dbgs() << "Cut " << CutEdges.count() << " edges\n");
@@ -726,8 +726,8 @@ int X86LoadValueInjectionLoadHardeningPass::insertFences(
MachineFunction &MF, MachineGadgetGraph &G,
EdgeSet &CutEdges /* in, out */) const {
int FencesInserted = 0;
- for (const Node &N : G.nodes()) {
- for (const Edge &E : N.edges()) {
+ for (const Node &N : G.nodes()) {
+ for (const Edge &E : N.edges()) {
if (CutEdges.contains(E)) {
MachineInstr *MI = N.getValue(), *Prev;
MachineBasicBlock *MBB; // Insert an LFENCE in this MBB
@@ -743,7 +743,7 @@ int X86LoadValueInjectionLoadHardeningPass::insertFences(
Prev = MI->getPrevNode();
// Remove all egress CFG edges from this branch because the inserted
// LFENCE prevents gadgets from crossing the branch.
- for (const Edge &E : N.edges()) {
+ for (const Edge &E : N.edges()) {
if (MachineGadgetGraph::isCFGEdge(E))
CutEdges.insert(E);
}
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86LoadValueInjectionRetHardening.cpp b/contrib/libs/llvm12/lib/Target/X86/X86LoadValueInjectionRetHardening.cpp
index 4562c1aee2..7b6276c1d8 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86LoadValueInjectionRetHardening.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86LoadValueInjectionRetHardening.cpp
@@ -75,35 +75,35 @@ bool X86LoadValueInjectionRetHardeningPass::runOnMachineFunction(
bool Modified = false;
for (auto &MBB : MF) {
- for (auto MBBI = MBB.begin(); MBBI != MBB.end(); ++MBBI) {
- if (MBBI->getOpcode() != X86::RETQ)
- continue;
-
- unsigned ClobberReg = TRI->findDeadCallerSavedReg(MBB, MBBI);
- if (ClobberReg != X86::NoRegister) {
- BuildMI(MBB, MBBI, DebugLoc(), TII->get(X86::POP64r))
- .addReg(ClobberReg, RegState::Define)
- .setMIFlag(MachineInstr::FrameDestroy);
- BuildMI(MBB, MBBI, DebugLoc(), TII->get(X86::LFENCE));
- BuildMI(MBB, MBBI, DebugLoc(), TII->get(X86::JMP64r))
- .addReg(ClobberReg);
- MBB.erase(MBBI);
- } else {
- // In case there is no available scratch register, we can still read
- // from RSP to assert that RSP points to a valid page. The write to RSP
- // is also helpful because it verifies that the stack's write
- // permissions are intact.
- MachineInstr *Fence =
- BuildMI(MBB, MBBI, DebugLoc(), TII->get(X86::LFENCE));
- addRegOffset(BuildMI(MBB, Fence, DebugLoc(), TII->get(X86::SHL64mi)),
- X86::RSP, false, 0)
- .addImm(0)
- ->addRegisterDead(X86::EFLAGS, TRI);
- }
-
- ++NumFences;
- Modified = true;
- break;
+ for (auto MBBI = MBB.begin(); MBBI != MBB.end(); ++MBBI) {
+ if (MBBI->getOpcode() != X86::RETQ)
+ continue;
+
+ unsigned ClobberReg = TRI->findDeadCallerSavedReg(MBB, MBBI);
+ if (ClobberReg != X86::NoRegister) {
+ BuildMI(MBB, MBBI, DebugLoc(), TII->get(X86::POP64r))
+ .addReg(ClobberReg, RegState::Define)
+ .setMIFlag(MachineInstr::FrameDestroy);
+ BuildMI(MBB, MBBI, DebugLoc(), TII->get(X86::LFENCE));
+ BuildMI(MBB, MBBI, DebugLoc(), TII->get(X86::JMP64r))
+ .addReg(ClobberReg);
+ MBB.erase(MBBI);
+ } else {
+ // In case there is no available scratch register, we can still read
+ // from RSP to assert that RSP points to a valid page. The write to RSP
+ // is also helpful because it verifies that the stack's write
+ // permissions are intact.
+ MachineInstr *Fence =
+ BuildMI(MBB, MBBI, DebugLoc(), TII->get(X86::LFENCE));
+ addRegOffset(BuildMI(MBB, Fence, DebugLoc(), TII->get(X86::SHL64mi)),
+ X86::RSP, false, 0)
+ .addImm(0)
+ ->addRegisterDead(X86::EFLAGS, TRI);
+ }
+
+ ++NumFences;
+ Modified = true;
+ break;
}
}
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86LowerAMXType.cpp b/contrib/libs/llvm12/lib/Target/X86/X86LowerAMXType.cpp
index 4c7eb5862f..85166decd8 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86LowerAMXType.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86LowerAMXType.cpp
@@ -1,351 +1,351 @@
-//===- llvm/CodeGen/TileShapeInfo.h - ---------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file Pass to transform <256 x i32> load/store
-/// <256 x i32> is bitcasted to x86_amx on X86, and AMX instruction set only
-/// provides simple operation on x86_amx. The basic elementwise operation
-/// is not supported by AMX. Since x86_amx is bitcasted from vector <256 x i32>
-/// and only AMX intrinsics can operate on the type, we need transform
-/// load/store <256 x i32> instruction to AMX load/store. If the bitcast can
-/// not be combined with load/store, we transform the bitcast to amx load/store
-/// and <256 x i32> store/load.
-//
-//===----------------------------------------------------------------------===//
-//
-#include "X86.h"
-#include "llvm/ADT/PostOrderIterator.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/Analysis/OptimizationRemarkEmitter.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/ValueTypes.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/IntrinsicsX86.h"
-#include "llvm/IR/PatternMatch.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Pass.h"
-
-using namespace llvm;
-using namespace PatternMatch;
-
-#define DEBUG_TYPE "lower-amx-type"
-
-static AllocaInst *CreateAllocaInst(IRBuilder<> &Builder, BasicBlock *BB) {
- Function &F = *BB->getParent();
- Module *M = BB->getModule();
- const DataLayout &DL = M->getDataLayout();
-
- Type *V256I32Ty = VectorType::get(Builder.getInt32Ty(), 256, false);
- LLVMContext &Ctx = Builder.getContext();
- auto AllocaAlignment = DL.getPrefTypeAlign(Type::getX86_AMXTy(Ctx));
- unsigned AllocaAS = DL.getAllocaAddrSpace();
- AllocaInst *AllocaRes =
- new AllocaInst(V256I32Ty, AllocaAS, "", &F.getEntryBlock().front());
- AllocaRes->setAlignment(AllocaAlignment);
- return AllocaRes;
-}
-
-static std::pair<Value *, Value *> getShape(IntrinsicInst *II, unsigned OpNo) {
- Value *Row = nullptr, *Col = nullptr;
- switch (II->getIntrinsicID()) {
- default:
- llvm_unreachable("Expect amx intrinsics");
- case Intrinsic::x86_tileloadd64_internal:
- case Intrinsic::x86_tilestored64_internal: {
- Row = II->getArgOperand(0);
- Col = II->getArgOperand(1);
- break;
- }
- // a * b + c
- // The shape depends on which operand.
- case Intrinsic::x86_tdpbssd_internal: {
- switch (OpNo) {
- case 3:
- Row = II->getArgOperand(0);
- Col = II->getArgOperand(1);
- break;
- case 4:
- Row = II->getArgOperand(0);
- Col = II->getArgOperand(2);
- break;
- case 5:
- Row = II->getArgOperand(2);
- Col = II->getArgOperand(1);
- break;
- }
- break;
- }
- }
-
- return std::make_pair(Row, Col);
-}
-
-// %src = load <256 x i32>, <256 x i32>* %addr, align 64
-// %2 = bitcast <256 x i32> %src to x86_amx
-// -->
-// %2 = call x86_amx @llvm.x86.tileloadd64.internal(i16 %row, i16 %col,
-// i8* %addr, i64 %stride64)
-static void combineLoadBitcast(LoadInst *LD, BitCastInst *Bitcast) {
- Value *Row = nullptr, *Col = nullptr;
- Use &U = *(Bitcast->use_begin());
- unsigned OpNo = U.getOperandNo();
- auto *II = cast<IntrinsicInst>(U.getUser());
- std::tie(Row, Col) = getShape(II, OpNo);
- IRBuilder<> Builder(Bitcast);
- // Use the maximun column as stride.
- Value *Stride = Builder.getInt64(64);
- Value *I8Ptr =
- Builder.CreateBitCast(LD->getOperand(0), Builder.getInt8PtrTy());
- std::array<Value *, 4> Args = {Row, Col, I8Ptr, Stride};
-
- Value *NewInst =
- Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, None, Args);
- Bitcast->replaceAllUsesWith(NewInst);
-}
-
-// %src = call x86_amx @llvm.x86.tileloadd64.internal(%row, %col, %addr,
-// %stride);
-// %13 = bitcast x86_amx %src to <256 x i32>
-// store <256 x i32> %13, <256 x i32>* %addr, align 64
-// -->
-// call void @llvm.x86.tilestored64.internal(%row, %col, %addr,
-// %stride64, %13)
-static void combineBitcastStore(BitCastInst *Bitcast, StoreInst *ST) {
-
- Value *Tile = Bitcast->getOperand(0);
- auto *II = cast<IntrinsicInst>(Tile);
- // Tile is output from AMX intrinsic. The first operand of the
- // intrinsic is row, the second operand of the intrinsic is column.
- Value *Row = II->getOperand(0);
- Value *Col = II->getOperand(1);
- IRBuilder<> Builder(ST);
- // Use the maximum column as stride. It must be the same with load
- // stride.
- Value *Stride = Builder.getInt64(64);
- Value *I8Ptr =
- Builder.CreateBitCast(ST->getOperand(1), Builder.getInt8PtrTy());
- std::array<Value *, 5> Args = {Row, Col, I8Ptr, Stride, Tile};
- Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, None, Args);
- if (Bitcast->hasOneUse())
- return;
- // %13 = bitcast x86_amx %src to <256 x i32>
- // store <256 x i32> %13, <256 x i32>* %addr, align 64
- // %add = <256 x i32> %13, <256 x i32> %src2
- // -->
- // %13 = bitcast x86_amx %src to <256 x i32>
- // call void @llvm.x86.tilestored64.internal(%row, %col, %addr,
- // %stride64, %13)
- // %14 = load <256 x i32>, %addr
- // %add = <256 x i32> %14, <256 x i32> %src2
- Value *Vec = Builder.CreateLoad(Bitcast->getType(), ST->getOperand(1));
- Bitcast->replaceAllUsesWith(Vec);
-}
-
-// transform bitcast to <store, load> instructions.
-static bool transformBitcast(BitCastInst *Bitcast) {
- IRBuilder<> Builder(Bitcast);
- AllocaInst *AllocaAddr;
- Value *I8Ptr, *Stride;
- auto *Src = Bitcast->getOperand(0);
-
- auto Prepare = [&]() {
- AllocaAddr = CreateAllocaInst(Builder, Bitcast->getParent());
- I8Ptr = Builder.CreateBitCast(AllocaAddr, Builder.getInt8PtrTy());
- Stride = Builder.getInt64(64);
- };
-
- if (Bitcast->getType()->isX86_AMXTy()) {
- // %2 = bitcast <256 x i32> %src to x86_amx
- // -->
- // %addr = alloca <256 x i32>, align 64
- // store <256 x i32> %src, <256 x i32>* %addr, align 64
- // %addr2 = bitcast <256 x i32>* to i8*
- // %2 = call x86_amx @llvm.x86.tileloadd64.internal(i16 %row, i16 %col,
- // i8* %addr2,
- // i64 64)
- Use &U = *(Bitcast->use_begin());
- unsigned OpNo = U.getOperandNo();
- auto *II = dyn_cast<IntrinsicInst>(U.getUser());
- if (!II)
- return false; // May be bitcast from x86amx to <256 x i32>.
- Prepare();
- Builder.CreateStore(Src, AllocaAddr);
- // TODO we can pick an constant operand for the shape.
- Value *Row = nullptr, *Col = nullptr;
- std::tie(Row, Col) = getShape(II, OpNo);
- std::array<Value *, 4> Args = {Row, Col, I8Ptr, Stride};
- Value *NewInst = Builder.CreateIntrinsic(
- Intrinsic::x86_tileloadd64_internal, None, Args);
- Bitcast->replaceAllUsesWith(NewInst);
- } else {
- // %2 = bitcast x86_amx %src to <256 x i32>
- // -->
- // %addr = alloca <256 x i32>, align 64
- // %addr2 = bitcast <256 x i32>* to i8*
- // call void @llvm.x86.tilestored64.internal(i16 %row, i16 %col,
- // i8* %addr2, i64 %stride)
- // %2 = load <256 x i32>, <256 x i32>* %addr, align 64
- auto *II = dyn_cast<IntrinsicInst>(Src);
- if (!II)
- return false; // May be bitcast from <256 x i32> to x86amx.
- Prepare();
- Value *Row = II->getOperand(0);
- Value *Col = II->getOperand(1);
- std::array<Value *, 5> Args = {Row, Col, I8Ptr, Stride, Src};
- Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, None, Args);
- Value *NewInst = Builder.CreateLoad(Bitcast->getType(), AllocaAddr);
- Bitcast->replaceAllUsesWith(NewInst);
- }
-
- return true;
-}
-
-namespace {
-class X86LowerAMXType {
- Function &Func;
-
-public:
- X86LowerAMXType(Function &F) : Func(F) {}
- bool visit();
-};
-
-bool X86LowerAMXType::visit() {
- SmallVector<Instruction *, 8> DeadInsts;
-
- for (BasicBlock *BB : post_order(&Func)) {
- for (BasicBlock::reverse_iterator II = BB->rbegin(), IE = BB->rend();
- II != IE;) {
- Instruction &Inst = *II++;
- auto *Bitcast = dyn_cast<BitCastInst>(&Inst);
- if (!Bitcast)
- continue;
-
- Value *Src = Bitcast->getOperand(0);
- if (Bitcast->getType()->isX86_AMXTy()) {
- if (Bitcast->user_empty()) {
- DeadInsts.push_back(Bitcast);
- continue;
- }
- LoadInst *LD = dyn_cast<LoadInst>(Src);
- if (!LD) {
- if (transformBitcast(Bitcast))
- DeadInsts.push_back(Bitcast);
- continue;
- }
- // If load has mutli-user, duplicate a vector load.
- // %src = load <256 x i32>, <256 x i32>* %addr, align 64
- // %2 = bitcast <256 x i32> %src to x86_amx
- // %add = add <256 x i32> %src, <256 x i32> %src2
- // -->
- // %src = load <256 x i32>, <256 x i32>* %addr, align 64
- // %2 = call x86_amx @llvm.x86.tileloadd64.internal(i16 %row, i16 %col,
- // i8* %addr, i64 %stride64)
- // %add = add <256 x i32> %src, <256 x i32> %src2
-
- // If load has one user, the load will be eliminated in DAG ISel.
- // %src = load <256 x i32>, <256 x i32>* %addr, align 64
- // %2 = bitcast <256 x i32> %src to x86_amx
- // -->
- // %2 = call x86_amx @llvm.x86.tileloadd64.internal(i16 %row, i16 %col,
- // i8* %addr, i64 %stride64)
- combineLoadBitcast(LD, Bitcast);
- DeadInsts.push_back(Bitcast);
- if (LD->hasOneUse())
- DeadInsts.push_back(LD);
- } else if (Src->getType()->isX86_AMXTy()) {
- if (Bitcast->user_empty()) {
- DeadInsts.push_back(Bitcast);
- continue;
- }
- StoreInst *ST = nullptr;
- for (auto UI = Bitcast->use_begin(), UE = Bitcast->use_end();
- UI != UE;) {
- Value *I = (UI++)->getUser();
- ST = dyn_cast<StoreInst>(I);
- if (ST)
- break;
- }
- if (!ST) {
- if (transformBitcast(Bitcast))
- DeadInsts.push_back(Bitcast);
- continue;
- }
- // If bitcast (%13) has one use, combine bitcast and store to amx store.
- // %src = call x86_amx @llvm.x86.tileloadd64.internal(%row, %col, %addr,
- // %stride);
- // %13 = bitcast x86_amx %src to <256 x i32>
- // store <256 x i32> %13, <256 x i32>* %addr, align 64
- // -->
- // call void @llvm.x86.tilestored64.internal(%row, %col, %addr,
- // %stride64, %13)
- //
- // If bitcast (%13) has multi-use, transform as below.
- // %13 = bitcast x86_amx %src to <256 x i32>
- // store <256 x i32> %13, <256 x i32>* %addr, align 64
- // %add = <256 x i32> %13, <256 x i32> %src2
- // -->
- // %13 = bitcast x86_amx %src to <256 x i32>
- // call void @llvm.x86.tilestored64.internal(%row, %col, %addr,
- // %stride64, %13)
- // %14 = load <256 x i32>, %addr
- // %add = <256 x i32> %14, <256 x i32> %src2
- //
- combineBitcastStore(Bitcast, ST);
- // Delete user first.
- DeadInsts.push_back(ST);
- DeadInsts.push_back(Bitcast);
- }
- }
- }
-
- bool C = !DeadInsts.empty();
-
- for (auto *Inst : DeadInsts)
- Inst->eraseFromParent();
-
- return C;
-}
-} // anonymous namespace
-
-namespace {
-
-class X86LowerAMXTypeLegacyPass : public FunctionPass {
-public:
- static char ID;
-
- X86LowerAMXTypeLegacyPass() : FunctionPass(ID) {
- initializeX86LowerAMXTypeLegacyPassPass(*PassRegistry::getPassRegistry());
- }
-
- bool runOnFunction(Function &F) override {
- X86LowerAMXType LAT(F);
- bool C = LAT.visit();
- return C;
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesCFG();
- }
-};
-
-} // anonymous namespace
-
-static const char PassName[] = "Lower AMX type for load/store";
-char X86LowerAMXTypeLegacyPass::ID = 0;
-INITIALIZE_PASS_BEGIN(X86LowerAMXTypeLegacyPass, DEBUG_TYPE, PassName, false,
- false)
-INITIALIZE_PASS_END(X86LowerAMXTypeLegacyPass, DEBUG_TYPE, PassName, false,
- false)
-
-FunctionPass *llvm::createX86LowerAMXTypePass() {
- return new X86LowerAMXTypeLegacyPass();
-}
+//===- llvm/CodeGen/TileShapeInfo.h - ---------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file Pass to transform <256 x i32> load/store
+/// <256 x i32> is bitcasted to x86_amx on X86, and AMX instruction set only
+/// provides simple operation on x86_amx. The basic elementwise operation
+/// is not supported by AMX. Since x86_amx is bitcasted from vector <256 x i32>
+/// and only AMX intrinsics can operate on the type, we need transform
+/// load/store <256 x i32> instruction to AMX load/store. If the bitcast can
+/// not be combined with load/store, we transform the bitcast to amx load/store
+/// and <256 x i32> store/load.
+//
+//===----------------------------------------------------------------------===//
+//
+#include "X86.h"
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/Analysis/OptimizationRemarkEmitter.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/IntrinsicsX86.h"
+#include "llvm/IR/PatternMatch.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+
+using namespace llvm;
+using namespace PatternMatch;
+
+#define DEBUG_TYPE "lower-amx-type"
+
+static AllocaInst *CreateAllocaInst(IRBuilder<> &Builder, BasicBlock *BB) {
+ Function &F = *BB->getParent();
+ Module *M = BB->getModule();
+ const DataLayout &DL = M->getDataLayout();
+
+ Type *V256I32Ty = VectorType::get(Builder.getInt32Ty(), 256, false);
+ LLVMContext &Ctx = Builder.getContext();
+ auto AllocaAlignment = DL.getPrefTypeAlign(Type::getX86_AMXTy(Ctx));
+ unsigned AllocaAS = DL.getAllocaAddrSpace();
+ AllocaInst *AllocaRes =
+ new AllocaInst(V256I32Ty, AllocaAS, "", &F.getEntryBlock().front());
+ AllocaRes->setAlignment(AllocaAlignment);
+ return AllocaRes;
+}
+
+static std::pair<Value *, Value *> getShape(IntrinsicInst *II, unsigned OpNo) {
+ Value *Row = nullptr, *Col = nullptr;
+ switch (II->getIntrinsicID()) {
+ default:
+ llvm_unreachable("Expect amx intrinsics");
+ case Intrinsic::x86_tileloadd64_internal:
+ case Intrinsic::x86_tilestored64_internal: {
+ Row = II->getArgOperand(0);
+ Col = II->getArgOperand(1);
+ break;
+ }
+ // a * b + c
+ // The shape depends on which operand.
+ case Intrinsic::x86_tdpbssd_internal: {
+ switch (OpNo) {
+ case 3:
+ Row = II->getArgOperand(0);
+ Col = II->getArgOperand(1);
+ break;
+ case 4:
+ Row = II->getArgOperand(0);
+ Col = II->getArgOperand(2);
+ break;
+ case 5:
+ Row = II->getArgOperand(2);
+ Col = II->getArgOperand(1);
+ break;
+ }
+ break;
+ }
+ }
+
+ return std::make_pair(Row, Col);
+}
+
+// %src = load <256 x i32>, <256 x i32>* %addr, align 64
+// %2 = bitcast <256 x i32> %src to x86_amx
+// -->
+// %2 = call x86_amx @llvm.x86.tileloadd64.internal(i16 %row, i16 %col,
+// i8* %addr, i64 %stride64)
+static void combineLoadBitcast(LoadInst *LD, BitCastInst *Bitcast) {
+ Value *Row = nullptr, *Col = nullptr;
+ Use &U = *(Bitcast->use_begin());
+ unsigned OpNo = U.getOperandNo();
+ auto *II = cast<IntrinsicInst>(U.getUser());
+ std::tie(Row, Col) = getShape(II, OpNo);
+ IRBuilder<> Builder(Bitcast);
+ // Use the maximun column as stride.
+ Value *Stride = Builder.getInt64(64);
+ Value *I8Ptr =
+ Builder.CreateBitCast(LD->getOperand(0), Builder.getInt8PtrTy());
+ std::array<Value *, 4> Args = {Row, Col, I8Ptr, Stride};
+
+ Value *NewInst =
+ Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, None, Args);
+ Bitcast->replaceAllUsesWith(NewInst);
+}
+
+// %src = call x86_amx @llvm.x86.tileloadd64.internal(%row, %col, %addr,
+// %stride);
+// %13 = bitcast x86_amx %src to <256 x i32>
+// store <256 x i32> %13, <256 x i32>* %addr, align 64
+// -->
+// call void @llvm.x86.tilestored64.internal(%row, %col, %addr,
+// %stride64, %13)
+static void combineBitcastStore(BitCastInst *Bitcast, StoreInst *ST) {
+
+ Value *Tile = Bitcast->getOperand(0);
+ auto *II = cast<IntrinsicInst>(Tile);
+ // Tile is output from AMX intrinsic. The first operand of the
+ // intrinsic is row, the second operand of the intrinsic is column.
+ Value *Row = II->getOperand(0);
+ Value *Col = II->getOperand(1);
+ IRBuilder<> Builder(ST);
+ // Use the maximum column as stride. It must be the same with load
+ // stride.
+ Value *Stride = Builder.getInt64(64);
+ Value *I8Ptr =
+ Builder.CreateBitCast(ST->getOperand(1), Builder.getInt8PtrTy());
+ std::array<Value *, 5> Args = {Row, Col, I8Ptr, Stride, Tile};
+ Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, None, Args);
+ if (Bitcast->hasOneUse())
+ return;
+ // %13 = bitcast x86_amx %src to <256 x i32>
+ // store <256 x i32> %13, <256 x i32>* %addr, align 64
+ // %add = <256 x i32> %13, <256 x i32> %src2
+ // -->
+ // %13 = bitcast x86_amx %src to <256 x i32>
+ // call void @llvm.x86.tilestored64.internal(%row, %col, %addr,
+ // %stride64, %13)
+ // %14 = load <256 x i32>, %addr
+ // %add = <256 x i32> %14, <256 x i32> %src2
+ Value *Vec = Builder.CreateLoad(Bitcast->getType(), ST->getOperand(1));
+ Bitcast->replaceAllUsesWith(Vec);
+}
+
+// transform bitcast to <store, load> instructions.
+static bool transformBitcast(BitCastInst *Bitcast) {
+ IRBuilder<> Builder(Bitcast);
+ AllocaInst *AllocaAddr;
+ Value *I8Ptr, *Stride;
+ auto *Src = Bitcast->getOperand(0);
+
+ auto Prepare = [&]() {
+ AllocaAddr = CreateAllocaInst(Builder, Bitcast->getParent());
+ I8Ptr = Builder.CreateBitCast(AllocaAddr, Builder.getInt8PtrTy());
+ Stride = Builder.getInt64(64);
+ };
+
+ if (Bitcast->getType()->isX86_AMXTy()) {
+ // %2 = bitcast <256 x i32> %src to x86_amx
+ // -->
+ // %addr = alloca <256 x i32>, align 64
+ // store <256 x i32> %src, <256 x i32>* %addr, align 64
+ // %addr2 = bitcast <256 x i32>* to i8*
+ // %2 = call x86_amx @llvm.x86.tileloadd64.internal(i16 %row, i16 %col,
+ // i8* %addr2,
+ // i64 64)
+ Use &U = *(Bitcast->use_begin());
+ unsigned OpNo = U.getOperandNo();
+ auto *II = dyn_cast<IntrinsicInst>(U.getUser());
+ if (!II)
+ return false; // May be bitcast from x86amx to <256 x i32>.
+ Prepare();
+ Builder.CreateStore(Src, AllocaAddr);
+ // TODO we can pick an constant operand for the shape.
+ Value *Row = nullptr, *Col = nullptr;
+ std::tie(Row, Col) = getShape(II, OpNo);
+ std::array<Value *, 4> Args = {Row, Col, I8Ptr, Stride};
+ Value *NewInst = Builder.CreateIntrinsic(
+ Intrinsic::x86_tileloadd64_internal, None, Args);
+ Bitcast->replaceAllUsesWith(NewInst);
+ } else {
+ // %2 = bitcast x86_amx %src to <256 x i32>
+ // -->
+ // %addr = alloca <256 x i32>, align 64
+ // %addr2 = bitcast <256 x i32>* to i8*
+ // call void @llvm.x86.tilestored64.internal(i16 %row, i16 %col,
+ // i8* %addr2, i64 %stride)
+ // %2 = load <256 x i32>, <256 x i32>* %addr, align 64
+ auto *II = dyn_cast<IntrinsicInst>(Src);
+ if (!II)
+ return false; // May be bitcast from <256 x i32> to x86amx.
+ Prepare();
+ Value *Row = II->getOperand(0);
+ Value *Col = II->getOperand(1);
+ std::array<Value *, 5> Args = {Row, Col, I8Ptr, Stride, Src};
+ Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, None, Args);
+ Value *NewInst = Builder.CreateLoad(Bitcast->getType(), AllocaAddr);
+ Bitcast->replaceAllUsesWith(NewInst);
+ }
+
+ return true;
+}
+
+namespace {
+class X86LowerAMXType {
+ Function &Func;
+
+public:
+ X86LowerAMXType(Function &F) : Func(F) {}
+ bool visit();
+};
+
+bool X86LowerAMXType::visit() {
+ SmallVector<Instruction *, 8> DeadInsts;
+
+ for (BasicBlock *BB : post_order(&Func)) {
+ for (BasicBlock::reverse_iterator II = BB->rbegin(), IE = BB->rend();
+ II != IE;) {
+ Instruction &Inst = *II++;
+ auto *Bitcast = dyn_cast<BitCastInst>(&Inst);
+ if (!Bitcast)
+ continue;
+
+ Value *Src = Bitcast->getOperand(0);
+ if (Bitcast->getType()->isX86_AMXTy()) {
+ if (Bitcast->user_empty()) {
+ DeadInsts.push_back(Bitcast);
+ continue;
+ }
+ LoadInst *LD = dyn_cast<LoadInst>(Src);
+ if (!LD) {
+ if (transformBitcast(Bitcast))
+ DeadInsts.push_back(Bitcast);
+ continue;
+ }
+ // If load has mutli-user, duplicate a vector load.
+ // %src = load <256 x i32>, <256 x i32>* %addr, align 64
+ // %2 = bitcast <256 x i32> %src to x86_amx
+ // %add = add <256 x i32> %src, <256 x i32> %src2
+ // -->
+ // %src = load <256 x i32>, <256 x i32>* %addr, align 64
+ // %2 = call x86_amx @llvm.x86.tileloadd64.internal(i16 %row, i16 %col,
+ // i8* %addr, i64 %stride64)
+ // %add = add <256 x i32> %src, <256 x i32> %src2
+
+ // If load has one user, the load will be eliminated in DAG ISel.
+ // %src = load <256 x i32>, <256 x i32>* %addr, align 64
+ // %2 = bitcast <256 x i32> %src to x86_amx
+ // -->
+ // %2 = call x86_amx @llvm.x86.tileloadd64.internal(i16 %row, i16 %col,
+ // i8* %addr, i64 %stride64)
+ combineLoadBitcast(LD, Bitcast);
+ DeadInsts.push_back(Bitcast);
+ if (LD->hasOneUse())
+ DeadInsts.push_back(LD);
+ } else if (Src->getType()->isX86_AMXTy()) {
+ if (Bitcast->user_empty()) {
+ DeadInsts.push_back(Bitcast);
+ continue;
+ }
+ StoreInst *ST = nullptr;
+ for (auto UI = Bitcast->use_begin(), UE = Bitcast->use_end();
+ UI != UE;) {
+ Value *I = (UI++)->getUser();
+ ST = dyn_cast<StoreInst>(I);
+ if (ST)
+ break;
+ }
+ if (!ST) {
+ if (transformBitcast(Bitcast))
+ DeadInsts.push_back(Bitcast);
+ continue;
+ }
+ // If bitcast (%13) has one use, combine bitcast and store to amx store.
+ // %src = call x86_amx @llvm.x86.tileloadd64.internal(%row, %col, %addr,
+ // %stride);
+ // %13 = bitcast x86_amx %src to <256 x i32>
+ // store <256 x i32> %13, <256 x i32>* %addr, align 64
+ // -->
+ // call void @llvm.x86.tilestored64.internal(%row, %col, %addr,
+ // %stride64, %13)
+ //
+ // If bitcast (%13) has multi-use, transform as below.
+ // %13 = bitcast x86_amx %src to <256 x i32>
+ // store <256 x i32> %13, <256 x i32>* %addr, align 64
+ // %add = <256 x i32> %13, <256 x i32> %src2
+ // -->
+ // %13 = bitcast x86_amx %src to <256 x i32>
+ // call void @llvm.x86.tilestored64.internal(%row, %col, %addr,
+ // %stride64, %13)
+ // %14 = load <256 x i32>, %addr
+ // %add = <256 x i32> %14, <256 x i32> %src2
+ //
+ combineBitcastStore(Bitcast, ST);
+ // Delete user first.
+ DeadInsts.push_back(ST);
+ DeadInsts.push_back(Bitcast);
+ }
+ }
+ }
+
+ bool C = !DeadInsts.empty();
+
+ for (auto *Inst : DeadInsts)
+ Inst->eraseFromParent();
+
+ return C;
+}
+} // anonymous namespace
+
+namespace {
+
+class X86LowerAMXTypeLegacyPass : public FunctionPass {
+public:
+ static char ID;
+
+ X86LowerAMXTypeLegacyPass() : FunctionPass(ID) {
+ initializeX86LowerAMXTypeLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool runOnFunction(Function &F) override {
+ X86LowerAMXType LAT(F);
+ bool C = LAT.visit();
+ return C;
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesCFG();
+ }
+};
+
+} // anonymous namespace
+
+static const char PassName[] = "Lower AMX type for load/store";
+char X86LowerAMXTypeLegacyPass::ID = 0;
+INITIALIZE_PASS_BEGIN(X86LowerAMXTypeLegacyPass, DEBUG_TYPE, PassName, false,
+ false)
+INITIALIZE_PASS_END(X86LowerAMXTypeLegacyPass, DEBUG_TYPE, PassName, false,
+ false)
+
+FunctionPass *llvm::createX86LowerAMXTypePass() {
+ return new X86LowerAMXTypeLegacyPass();
+}
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86MCInstLower.cpp b/contrib/libs/llvm12/lib/Target/X86/X86MCInstLower.cpp
index 6de5c84db3..89fa3ae3a3 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86MCInstLower.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86MCInstLower.cpp
@@ -977,24 +977,24 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
void X86AsmPrinter::LowerTlsAddr(X86MCInstLower &MCInstLowering,
const MachineInstr &MI) {
NoAutoPaddingScope NoPadScope(*OutStreamer);
- bool Is64Bits = MI.getOpcode() != X86::TLS_addr32 &&
- MI.getOpcode() != X86::TLS_base_addr32;
- bool Is64BitsLP64 = MI.getOpcode() == X86::TLS_addr64 ||
- MI.getOpcode() == X86::TLS_base_addr64;
+ bool Is64Bits = MI.getOpcode() != X86::TLS_addr32 &&
+ MI.getOpcode() != X86::TLS_base_addr32;
+ bool Is64BitsLP64 = MI.getOpcode() == X86::TLS_addr64 ||
+ MI.getOpcode() == X86::TLS_base_addr64;
MCContext &Ctx = OutStreamer->getContext();
MCSymbolRefExpr::VariantKind SRVK;
switch (MI.getOpcode()) {
case X86::TLS_addr32:
case X86::TLS_addr64:
- case X86::TLS_addrX32:
+ case X86::TLS_addrX32:
SRVK = MCSymbolRefExpr::VK_TLSGD;
break;
case X86::TLS_base_addr32:
SRVK = MCSymbolRefExpr::VK_TLSLDM;
break;
case X86::TLS_base_addr64:
- case X86::TLS_base_addrX32:
+ case X86::TLS_base_addrX32:
SRVK = MCSymbolRefExpr::VK_TLSLD;
break;
default:
@@ -1014,7 +1014,7 @@ void X86AsmPrinter::LowerTlsAddr(X86MCInstLower &MCInstLowering,
if (Is64Bits) {
bool NeedsPadding = SRVK == MCSymbolRefExpr::VK_TLSGD;
- if (NeedsPadding && Is64BitsLP64)
+ if (NeedsPadding && Is64BitsLP64)
EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));
EmitAndCountInstruction(MCInstBuilder(X86::LEA64r)
.addReg(X86::RDI)
@@ -1087,26 +1087,26 @@ void X86AsmPrinter::LowerTlsAddr(X86MCInstLower &MCInstLowering,
/// bytes. Return the size of nop emitted.
static unsigned emitNop(MCStreamer &OS, unsigned NumBytes,
const X86Subtarget *Subtarget) {
- // Determine the longest nop which can be efficiently decoded for the given
- // target cpu. 15-bytes is the longest single NOP instruction, but some
- // platforms can't decode the longest forms efficiently.
- unsigned MaxNopLength = 1;
- if (Subtarget->is64Bit()) {
- // FIXME: We can use NOOPL on 32-bit targets with FeatureNOPL, but the
- // IndexReg/BaseReg below need to be updated.
- if (Subtarget->hasFeature(X86::FeatureFast7ByteNOP))
- MaxNopLength = 7;
- else if (Subtarget->hasFeature(X86::FeatureFast15ByteNOP))
- MaxNopLength = 15;
- else if (Subtarget->hasFeature(X86::FeatureFast11ByteNOP))
- MaxNopLength = 11;
- else
- MaxNopLength = 10;
- } if (Subtarget->is32Bit())
- MaxNopLength = 2;
-
+ // Determine the longest nop which can be efficiently decoded for the given
+ // target cpu. 15-bytes is the longest single NOP instruction, but some
+ // platforms can't decode the longest forms efficiently.
+ unsigned MaxNopLength = 1;
+ if (Subtarget->is64Bit()) {
+ // FIXME: We can use NOOPL on 32-bit targets with FeatureNOPL, but the
+ // IndexReg/BaseReg below need to be updated.
+ if (Subtarget->hasFeature(X86::FeatureFast7ByteNOP))
+ MaxNopLength = 7;
+ else if (Subtarget->hasFeature(X86::FeatureFast15ByteNOP))
+ MaxNopLength = 15;
+ else if (Subtarget->hasFeature(X86::FeatureFast11ByteNOP))
+ MaxNopLength = 11;
+ else
+ MaxNopLength = 10;
+ } if (Subtarget->is32Bit())
+ MaxNopLength = 2;
+
// Cap a single nop emission at the profitable value for the target
- NumBytes = std::min(NumBytes, MaxNopLength);
+ NumBytes = std::min(NumBytes, MaxNopLength);
unsigned NopSize;
unsigned Opc, BaseReg, ScaleVal, IndexReg, Displacement, SegmentReg;
@@ -1334,7 +1334,7 @@ void X86AsmPrinter::LowerPATCHABLE_OP(const MachineInstr &MI,
MCInst MCI;
MCI.setOpcode(Opcode);
- for (auto &MO : drop_begin(MI.operands(), 2))
+ for (auto &MO : drop_begin(MI.operands(), 2))
if (auto MaybeOperand = MCIL.LowerMachineOperand(&MI, MO))
MCI.addOperand(MaybeOperand.getValue());
@@ -1710,7 +1710,7 @@ void X86AsmPrinter::LowerPATCHABLE_RET(const MachineInstr &MI,
unsigned OpCode = MI.getOperand(0).getImm();
MCInst Ret;
Ret.setOpcode(OpCode);
- for (auto &MO : drop_begin(MI.operands()))
+ for (auto &MO : drop_begin(MI.operands()))
if (auto MaybeOperand = MCIL.LowerMachineOperand(&MI, MO))
Ret.addOperand(MaybeOperand.getValue());
OutStreamer->emitInstruction(Ret, getSubtargetInfo());
@@ -1749,7 +1749,7 @@ void X86AsmPrinter::LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI,
// Before emitting the instruction, add a comment to indicate that this is
// indeed a tail call.
OutStreamer->AddComment("TAILCALL");
- for (auto &MO : drop_begin(MI.operands()))
+ for (auto &MO : drop_begin(MI.operands()))
if (auto MaybeOperand = MCIL.LowerMachineOperand(&MI, MO))
TC.addOperand(MaybeOperand.getValue());
OutStreamer->emitInstruction(TC, getSubtargetInfo());
@@ -1784,7 +1784,7 @@ static const Constant *getConstantFromPool(const MachineInstr &MI,
if (ConstantEntry.isMachineConstantPoolEntry())
return nullptr;
- return ConstantEntry.Val.ConstVal;
+ return ConstantEntry.Val.ConstVal;
}
static std::string getShuffleComment(const MachineInstr *MI, unsigned SrcOp1Idx,
@@ -2446,10 +2446,10 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
case X86::TLS_addr32:
case X86::TLS_addr64:
- case X86::TLS_addrX32:
+ case X86::TLS_addrX32:
case X86::TLS_base_addr32:
case X86::TLS_base_addr64:
- case X86::TLS_base_addrX32:
+ case X86::TLS_base_addrX32:
return LowerTlsAddr(MCInstLowering, *MI);
case X86::MOVPC32r: {
@@ -2598,15 +2598,15 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
}
return;
}
- case X86::UBSAN_UD1:
- EmitAndCountInstruction(MCInstBuilder(X86::UD1Lm)
- .addReg(X86::EAX)
- .addReg(X86::EAX)
- .addImm(1)
- .addReg(X86::NoRegister)
- .addImm(MI->getOperand(0).getImm())
- .addReg(X86::NoRegister));
- return;
+ case X86::UBSAN_UD1:
+ EmitAndCountInstruction(MCInstBuilder(X86::UD1Lm)
+ .addReg(X86::EAX)
+ .addReg(X86::EAX)
+ .addImm(1)
+ .addReg(X86::NoRegister)
+ .addImm(MI->getOperand(0).getImm())
+ .addReg(X86::NoRegister));
+ return;
}
MCInst TmpInst;
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86PartialReduction.cpp b/contrib/libs/llvm12/lib/Target/X86/X86PartialReduction.cpp
index db4203d314..babd923e74 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86PartialReduction.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86PartialReduction.cpp
@@ -392,7 +392,7 @@ static void collectLeaves(Value *Root, SmallVectorImpl<Instruction *> &Leaves) {
break;
// Push incoming values to the worklist.
- append_range(Worklist, PN->incoming_values());
+ append_range(Worklist, PN->incoming_values());
continue;
}
@@ -401,7 +401,7 @@ static void collectLeaves(Value *Root, SmallVectorImpl<Instruction *> &Leaves) {
if (BO->getOpcode() == Instruction::Add) {
// Simple case. Single use, just push its operands to the worklist.
if (BO->hasNUses(BO == Root ? 2 : 1)) {
- append_range(Worklist, BO->operands());
+ append_range(Worklist, BO->operands());
continue;
}
@@ -424,7 +424,7 @@ static void collectLeaves(Value *Root, SmallVectorImpl<Instruction *> &Leaves) {
continue;
// The phi forms a loop with this Add, push its operands.
- append_range(Worklist, BO->operands());
+ append_range(Worklist, BO->operands());
}
}
}
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86PreTileConfig.cpp b/contrib/libs/llvm12/lib/Target/X86/X86PreTileConfig.cpp
index b2f6d0604d..05ee6c6c83 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86PreTileConfig.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86PreTileConfig.cpp
@@ -1,265 +1,265 @@
-//===-- X86PreTileConfig.cpp - Tile Register Configure---------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file Pass to pre-config the shape of AMX register
-/// AMX register need to be configured before use. The shape of AMX register
-/// is encoded in the 1st and 2nd machine operand of AMX pseudo instructions.
-/// The pldtilecfg is to config tile registers. It should dominator all AMX
-/// instructions. The pldtilecfg produce a virtual cfg register and the cfg
-/// register is used by all AMX instructions.
-/// This pass is to find the common dominator of all AMX instructions and
-/// insert the pldtilecfg instruction. Besides the cfg register that pldtilecfg
-/// produces is inserted as the last operand of each AMX instruction. We use
-/// this scheme to model the def-use relationship between AMX config instruction
-/// and other AMX instructions. Below is an example.
-///
-/// ----B1----
-/// / \
-/// / \
-/// B2 B3
-/// %1:tile = PTILELOADDV %2:tile = PTILELOADDV
-///
-/// is transformed to
-///
-/// B1
-/// %25:tilecfg = PLDTILECFG
-/// / \
-/// / \
-/// %1:tile = PTILELOADDV %25 %2:tile = PTILELOADDV %25
-//
-//===----------------------------------------------------------------------===//
-
-#include "X86.h"
-#include "X86InstrBuilder.h"
-#include "X86RegisterInfo.h"
-#include "X86Subtarget.h"
-#include "llvm/CodeGen/MachineDominators.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/TargetInstrInfo.h"
-#include "llvm/CodeGen/TargetRegisterInfo.h"
-#include "llvm/CodeGen/TileShapeInfo.h"
-#include "llvm/InitializePasses.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "tile-pre-config"
-
-namespace {
-
-class X86PreTileConfig : public MachineFunctionPass {
- // context
- MachineFunction *MF = nullptr;
- const X86Subtarget *ST = nullptr;
- const TargetRegisterInfo *TRI;
- const TargetInstrInfo *TII;
- MachineDominatorTree *DomTree = nullptr;
- MachineRegisterInfo *MRI = nullptr;
-
- MachineInstr *getTileConfigPoint();
-
-public:
- X86PreTileConfig() : MachineFunctionPass(ID) {}
-
- /// Return the pass name.
- StringRef getPassName() const override {
- return "Tile Register Pre-configure";
- }
-
- /// X86PreTileConfig analysis usage.
- void getAnalysisUsage(AnalysisUsage &AU) const override;
-
- /// Perform register allocation.
- bool runOnMachineFunction(MachineFunction &mf) override;
-
- static char ID;
-};
-
-} // end anonymous namespace
-
-char X86PreTileConfig::ID = 0;
-
-INITIALIZE_PASS_BEGIN(X86PreTileConfig, "tilepreconfig",
- "Tile Register Configure", false, false)
-INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
-INITIALIZE_PASS_END(X86PreTileConfig, "tilepreconfig",
- "Tile Register Configure", false, false)
-
-void X86PreTileConfig::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AU.addRequired<MachineDominatorTree>();
- MachineFunctionPass::getAnalysisUsage(AU);
-}
-
-static Register buildConfigMI(MachineBasicBlock::iterator MI, int FrameIdx,
- const TargetInstrInfo *TII,
- MachineRegisterInfo *MRI,
- const X86Subtarget *ST) {
- auto *MBB = MI->getParent();
-
- // FIXME: AMX should assume AVX512 enabled.
- if (ST->hasAVX512()) {
- // Zero stack slot.
- Register Zmm = MRI->createVirtualRegister(&X86::VR512RegClass);
- BuildMI(*MBB, MI, DebugLoc(), TII->get(X86::VPXORDZrr), Zmm)
- .addReg(Zmm, RegState::Undef)
- .addReg(Zmm, RegState::Undef);
- addFrameReference(BuildMI(*MBB, MI, DebugLoc(), TII->get(X86::VMOVUPSZmr)),
- FrameIdx)
- .addReg(Zmm);
- }
-
- // build psuedo ldtilecfg
- Register VReg = MRI->createVirtualRegister(&X86::TILECFGRegClass);
-
- addFrameReference(
- BuildMI(*MBB, MI, DebugLoc(), TII->get(X86::PLDTILECFG), VReg), FrameIdx);
-
- return VReg;
-}
-
-static ShapeT getShape(const MachineInstr &MI, MachineRegisterInfo *MRI) {
- unsigned Opcode = MI.getOpcode();
- switch (Opcode) {
- default:
- llvm_unreachable("Unexpected machine instruction on tile");
- case X86::PTILELOADDV:
- case X86::PTDPBSSDV:
- case X86::PTILEZEROV:
- MachineOperand &MO1 = const_cast<MachineOperand &>(MI.getOperand(1));
- MachineOperand &MO2 = const_cast<MachineOperand &>(MI.getOperand(2));
- ShapeT Shape(&MO1, &MO2, MRI);
- return Shape;
- }
-}
-
-MachineInstr *X86PreTileConfig::getTileConfigPoint() {
- DenseMap<Register, ShapeT> PhysShapeInfo;
- MachineBasicBlock *MBB = nullptr;
- DenseSet<const MachineInstr *> MIs;
- for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
- Register VirtReg = Register::index2VirtReg(i);
- if (MRI->reg_nodbg_empty(VirtReg))
- continue;
- const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg);
- if (RC.getID() != X86::TILERegClassID)
- continue;
-
- // Find the common dominator for all MI that define tile register.
- for (const MachineOperand &MO : MRI->def_operands(VirtReg)) {
- if (MO.isUndef())
- continue;
- const auto *MI = MO.getParent();
- // PHI or IMPLICIT_DEF instructiion.
- // There must be a input tile before PHI instruction.
- if (MI->isTransient())
- continue;
- if (!MBB)
- MBB = const_cast<MachineBasicBlock *>(MI->getParent());
- MBB = DomTree->findNearestCommonDominator(
- MBB, const_cast<MachineBasicBlock *>(MI->getParent()));
-
- // Collect the instructions that define shape.
- ShapeT Shape = getShape(*MI, MRI);
- std::array<MachineOperand *, 2> ShapeMOs = {Shape.getRow(),
- Shape.getCol()};
- for (auto *ShapeMO : ShapeMOs) {
- Register ShapeReg = ShapeMO->getReg();
- for (const MachineOperand &MO : MRI->def_operands(ShapeReg)) {
- const auto *ShapeMI = MO.getParent();
- MIs.insert(ShapeMI);
- }
- }
- }
- }
- if (!MBB)
- return nullptr;
- // This pass is before the pass of eliminating PHI node, so it
- // is in SSA form.
- assert(MRI->isSSA() && "Not SSA form in pre-tile config");
- // Shape def should dominate tile config MBB.
- // def s s1 s2
- // / \ \ /
- // / \ \ /
- // conf s3=phi(s1,s2)
- // |
- // c
- //
- for (const auto *MI : MIs) {
- const MachineBasicBlock *ShapeMBB = MI->getParent();
- if (DomTree->dominates(ShapeMBB, MBB))
- continue;
- if (MI->isMoveImmediate())
- continue;
- report_fatal_error(MF->getName() + ": Failed to config tile register, "
- "please define the shape earlier");
- }
-
- // ldtilecfg should be inserted after the MI that define the shape.
- MachineBasicBlock::reverse_instr_iterator I, E;
- for (I = MBB->instr_rbegin(), E = MBB->instr_rend(); I != E; ++I) {
- auto *MI = &*I;
- if (MIs.count(MI) && (!MI->isMoveImmediate()))
- break;
- }
- MachineBasicBlock::iterator MII;
- if (I == E)
- MII = MBB->getFirstNonPHI();
- else {
- MII = MachineBasicBlock::iterator(&*I);
- MII++;
- }
- return &*MII;
-}
-
-static void addTileCFGUse(MachineFunction &MF, Register CFG) {
- for (MachineBasicBlock &MBB : MF) {
-
- // Traverse the basic block.
- for (MachineInstr &MI : MBB) {
- unsigned Opcode = MI.getOpcode();
- switch (Opcode) {
- default:
- break;
- case X86::PTILELOADDV:
- case X86::PTILESTOREDV:
- case X86::PTDPBSSDV:
- case X86::PTILEZEROV:
- unsigned NumOperands = MI.getNumOperands();
- MI.RemoveOperand(NumOperands - 1);
- MI.addOperand(MF, MachineOperand::CreateReg(CFG, false));
- break;
- }
- }
- }
-}
-
-bool X86PreTileConfig::runOnMachineFunction(MachineFunction &mf) {
- MF = &mf;
- MRI = &mf.getRegInfo();
- ST = &mf.getSubtarget<X86Subtarget>();
- TRI = ST->getRegisterInfo();
- TII = mf.getSubtarget().getInstrInfo();
- DomTree = &getAnalysis<MachineDominatorTree>();
-
- MachineInstr *MI = getTileConfigPoint();
- if (!MI)
- return false;
- unsigned Size = ST->getTileConfigSize();
- Align Alignment = ST->getTileConfigAlignment();
- int SS = mf.getFrameInfo().CreateStackObject(Size, Alignment, false);
- Register CFG = buildConfigMI(MI, SS, TII, MRI, ST);
- addTileCFGUse(mf, CFG);
- return true;
-}
-
-FunctionPass *llvm::createX86PreTileConfigPass() {
- return new X86PreTileConfig();
-}
+//===-- X86PreTileConfig.cpp - Tile Register Configure---------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file Pass to pre-config the shape of AMX register
+/// AMX register need to be configured before use. The shape of AMX register
+/// is encoded in the 1st and 2nd machine operand of AMX pseudo instructions.
+/// The pldtilecfg is to config tile registers. It should dominator all AMX
+/// instructions. The pldtilecfg produce a virtual cfg register and the cfg
+/// register is used by all AMX instructions.
+/// This pass is to find the common dominator of all AMX instructions and
+/// insert the pldtilecfg instruction. Besides the cfg register that pldtilecfg
+/// produces is inserted as the last operand of each AMX instruction. We use
+/// this scheme to model the def-use relationship between AMX config instruction
+/// and other AMX instructions. Below is an example.
+///
+/// ----B1----
+/// / \
+/// / \
+/// B2 B3
+/// %1:tile = PTILELOADDV %2:tile = PTILELOADDV
+///
+/// is transformed to
+///
+/// B1
+/// %25:tilecfg = PLDTILECFG
+/// / \
+/// / \
+/// %1:tile = PTILELOADDV %25 %2:tile = PTILELOADDV %25
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86.h"
+#include "X86InstrBuilder.h"
+#include "X86RegisterInfo.h"
+#include "X86Subtarget.h"
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TileShapeInfo.h"
+#include "llvm/InitializePasses.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "tile-pre-config"
+
+namespace {
+
+class X86PreTileConfig : public MachineFunctionPass {
+ // context
+ MachineFunction *MF = nullptr;
+ const X86Subtarget *ST = nullptr;
+ const TargetRegisterInfo *TRI;
+ const TargetInstrInfo *TII;
+ MachineDominatorTree *DomTree = nullptr;
+ MachineRegisterInfo *MRI = nullptr;
+
+ MachineInstr *getTileConfigPoint();
+
+public:
+ X86PreTileConfig() : MachineFunctionPass(ID) {}
+
+ /// Return the pass name.
+ StringRef getPassName() const override {
+ return "Tile Register Pre-configure";
+ }
+
+ /// X86PreTileConfig analysis usage.
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+ /// Perform register allocation.
+ bool runOnMachineFunction(MachineFunction &mf) override;
+
+ static char ID;
+};
+
+} // end anonymous namespace
+
+char X86PreTileConfig::ID = 0;
+
+INITIALIZE_PASS_BEGIN(X86PreTileConfig, "tilepreconfig",
+ "Tile Register Configure", false, false)
+INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
+INITIALIZE_PASS_END(X86PreTileConfig, "tilepreconfig",
+ "Tile Register Configure", false, false)
+
+void X86PreTileConfig::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<MachineDominatorTree>();
+ MachineFunctionPass::getAnalysisUsage(AU);
+}
+
+static Register buildConfigMI(MachineBasicBlock::iterator MI, int FrameIdx,
+ const TargetInstrInfo *TII,
+ MachineRegisterInfo *MRI,
+ const X86Subtarget *ST) {
+ auto *MBB = MI->getParent();
+
+ // FIXME: AMX should assume AVX512 enabled.
+ if (ST->hasAVX512()) {
+ // Zero stack slot.
+ Register Zmm = MRI->createVirtualRegister(&X86::VR512RegClass);
+ BuildMI(*MBB, MI, DebugLoc(), TII->get(X86::VPXORDZrr), Zmm)
+ .addReg(Zmm, RegState::Undef)
+ .addReg(Zmm, RegState::Undef);
+ addFrameReference(BuildMI(*MBB, MI, DebugLoc(), TII->get(X86::VMOVUPSZmr)),
+ FrameIdx)
+ .addReg(Zmm);
+ }
+
+ // build psuedo ldtilecfg
+ Register VReg = MRI->createVirtualRegister(&X86::TILECFGRegClass);
+
+ addFrameReference(
+ BuildMI(*MBB, MI, DebugLoc(), TII->get(X86::PLDTILECFG), VReg), FrameIdx);
+
+ return VReg;
+}
+
+static ShapeT getShape(const MachineInstr &MI, MachineRegisterInfo *MRI) {
+ unsigned Opcode = MI.getOpcode();
+ switch (Opcode) {
+ default:
+ llvm_unreachable("Unexpected machine instruction on tile");
+ case X86::PTILELOADDV:
+ case X86::PTDPBSSDV:
+ case X86::PTILEZEROV:
+ MachineOperand &MO1 = const_cast<MachineOperand &>(MI.getOperand(1));
+ MachineOperand &MO2 = const_cast<MachineOperand &>(MI.getOperand(2));
+ ShapeT Shape(&MO1, &MO2, MRI);
+ return Shape;
+ }
+}
+
+MachineInstr *X86PreTileConfig::getTileConfigPoint() {
+ DenseMap<Register, ShapeT> PhysShapeInfo;
+ MachineBasicBlock *MBB = nullptr;
+ DenseSet<const MachineInstr *> MIs;
+ for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
+ Register VirtReg = Register::index2VirtReg(i);
+ if (MRI->reg_nodbg_empty(VirtReg))
+ continue;
+ const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg);
+ if (RC.getID() != X86::TILERegClassID)
+ continue;
+
+ // Find the common dominator for all MI that define tile register.
+ for (const MachineOperand &MO : MRI->def_operands(VirtReg)) {
+ if (MO.isUndef())
+ continue;
+ const auto *MI = MO.getParent();
+ // PHI or IMPLICIT_DEF instructiion.
+ // There must be a input tile before PHI instruction.
+ if (MI->isTransient())
+ continue;
+ if (!MBB)
+ MBB = const_cast<MachineBasicBlock *>(MI->getParent());
+ MBB = DomTree->findNearestCommonDominator(
+ MBB, const_cast<MachineBasicBlock *>(MI->getParent()));
+
+ // Collect the instructions that define shape.
+ ShapeT Shape = getShape(*MI, MRI);
+ std::array<MachineOperand *, 2> ShapeMOs = {Shape.getRow(),
+ Shape.getCol()};
+ for (auto *ShapeMO : ShapeMOs) {
+ Register ShapeReg = ShapeMO->getReg();
+ for (const MachineOperand &MO : MRI->def_operands(ShapeReg)) {
+ const auto *ShapeMI = MO.getParent();
+ MIs.insert(ShapeMI);
+ }
+ }
+ }
+ }
+ if (!MBB)
+ return nullptr;
+ // This pass is before the pass of eliminating PHI node, so it
+ // is in SSA form.
+ assert(MRI->isSSA() && "Not SSA form in pre-tile config");
+ // Shape def should dominate tile config MBB.
+ // def s s1 s2
+ // / \ \ /
+ // / \ \ /
+ // conf s3=phi(s1,s2)
+ // |
+ // c
+ //
+ for (const auto *MI : MIs) {
+ const MachineBasicBlock *ShapeMBB = MI->getParent();
+ if (DomTree->dominates(ShapeMBB, MBB))
+ continue;
+ if (MI->isMoveImmediate())
+ continue;
+ report_fatal_error(MF->getName() + ": Failed to config tile register, "
+ "please define the shape earlier");
+ }
+
+ // ldtilecfg should be inserted after the MI that define the shape.
+ MachineBasicBlock::reverse_instr_iterator I, E;
+ for (I = MBB->instr_rbegin(), E = MBB->instr_rend(); I != E; ++I) {
+ auto *MI = &*I;
+ if (MIs.count(MI) && (!MI->isMoveImmediate()))
+ break;
+ }
+ MachineBasicBlock::iterator MII;
+ if (I == E)
+ MII = MBB->getFirstNonPHI();
+ else {
+ MII = MachineBasicBlock::iterator(&*I);
+ MII++;
+ }
+ return &*MII;
+}
+
+static void addTileCFGUse(MachineFunction &MF, Register CFG) {
+ for (MachineBasicBlock &MBB : MF) {
+
+ // Traverse the basic block.
+ for (MachineInstr &MI : MBB) {
+ unsigned Opcode = MI.getOpcode();
+ switch (Opcode) {
+ default:
+ break;
+ case X86::PTILELOADDV:
+ case X86::PTILESTOREDV:
+ case X86::PTDPBSSDV:
+ case X86::PTILEZEROV:
+ unsigned NumOperands = MI.getNumOperands();
+ MI.RemoveOperand(NumOperands - 1);
+ MI.addOperand(MF, MachineOperand::CreateReg(CFG, false));
+ break;
+ }
+ }
+ }
+}
+
+bool X86PreTileConfig::runOnMachineFunction(MachineFunction &mf) {
+ MF = &mf;
+ MRI = &mf.getRegInfo();
+ ST = &mf.getSubtarget<X86Subtarget>();
+ TRI = ST->getRegisterInfo();
+ TII = mf.getSubtarget().getInstrInfo();
+ DomTree = &getAnalysis<MachineDominatorTree>();
+
+ MachineInstr *MI = getTileConfigPoint();
+ if (!MI)
+ return false;
+ unsigned Size = ST->getTileConfigSize();
+ Align Alignment = ST->getTileConfigAlignment();
+ int SS = mf.getFrameInfo().CreateStackObject(Size, Alignment, false);
+ Register CFG = buildConfigMI(MI, SS, TII, MRI, ST);
+ addTileCFGUse(mf, CFG);
+ return true;
+}
+
+FunctionPass *llvm::createX86PreTileConfigPass() {
+ return new X86PreTileConfig();
+}
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86RegisterInfo.cpp b/contrib/libs/llvm12/lib/Target/X86/X86RegisterInfo.cpp
index eb919a0146..d90b4e7bdc 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86RegisterInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86RegisterInfo.cpp
@@ -18,8 +18,8 @@
#include "X86Subtarget.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/CodeGen/LiveRegMatrix.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/CodeGen/LiveRegMatrix.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
@@ -726,12 +726,12 @@ X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
assert((!needsStackRealignment(MF) ||
MF.getFrameInfo().isFixedObjectIndex(FrameIndex)) &&
"Return instruction can only reference SP relative frame objects");
- FIOffset =
- TFI->getFrameIndexReferenceSP(MF, FrameIndex, BasePtr, 0).getFixed();
+ FIOffset =
+ TFI->getFrameIndexReferenceSP(MF, FrameIndex, BasePtr, 0).getFixed();
} else if (TFI->Is64Bit && (MBB.isEHFuncletEntry() || IsEHFuncletEpilogue)) {
FIOffset = TFI->getWin64EHFrameIndexRef(MF, FrameIndex, BasePtr);
} else {
- FIOffset = TFI->getFrameIndexReference(MF, FrameIndex, BasePtr).getFixed();
+ FIOffset = TFI->getFrameIndexReference(MF, FrameIndex, BasePtr).getFixed();
}
// LOCAL_ESCAPE uses a single offset, with no register. It only works in the
@@ -786,55 +786,55 @@ X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
}
}
-unsigned X86RegisterInfo::findDeadCallerSavedReg(
- MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI) const {
- const MachineFunction *MF = MBB.getParent();
- if (MF->callsEHReturn())
- return 0;
-
- const TargetRegisterClass &AvailableRegs = *getGPRsForTailCall(*MF);
-
- if (MBBI == MBB.end())
- return 0;
-
- switch (MBBI->getOpcode()) {
- default:
- return 0;
- case TargetOpcode::PATCHABLE_RET:
- case X86::RET:
- case X86::RETL:
- case X86::RETQ:
- case X86::RETIL:
- case X86::RETIQ:
- case X86::TCRETURNdi:
- case X86::TCRETURNri:
- case X86::TCRETURNmi:
- case X86::TCRETURNdi64:
- case X86::TCRETURNri64:
- case X86::TCRETURNmi64:
- case X86::EH_RETURN:
- case X86::EH_RETURN64: {
- SmallSet<uint16_t, 8> Uses;
- for (unsigned I = 0, E = MBBI->getNumOperands(); I != E; ++I) {
- MachineOperand &MO = MBBI->getOperand(I);
- if (!MO.isReg() || MO.isDef())
- continue;
- Register Reg = MO.getReg();
- if (!Reg)
- continue;
- for (MCRegAliasIterator AI(Reg, this, true); AI.isValid(); ++AI)
- Uses.insert(*AI);
- }
-
- for (auto CS : AvailableRegs)
- if (!Uses.count(CS) && CS != X86::RIP && CS != X86::RSP && CS != X86::ESP)
- return CS;
- }
- }
-
- return 0;
-}
-
+unsigned X86RegisterInfo::findDeadCallerSavedReg(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI) const {
+ const MachineFunction *MF = MBB.getParent();
+ if (MF->callsEHReturn())
+ return 0;
+
+ const TargetRegisterClass &AvailableRegs = *getGPRsForTailCall(*MF);
+
+ if (MBBI == MBB.end())
+ return 0;
+
+ switch (MBBI->getOpcode()) {
+ default:
+ return 0;
+ case TargetOpcode::PATCHABLE_RET:
+ case X86::RET:
+ case X86::RETL:
+ case X86::RETQ:
+ case X86::RETIL:
+ case X86::RETIQ:
+ case X86::TCRETURNdi:
+ case X86::TCRETURNri:
+ case X86::TCRETURNmi:
+ case X86::TCRETURNdi64:
+ case X86::TCRETURNri64:
+ case X86::TCRETURNmi64:
+ case X86::EH_RETURN:
+ case X86::EH_RETURN64: {
+ SmallSet<uint16_t, 8> Uses;
+ for (unsigned I = 0, E = MBBI->getNumOperands(); I != E; ++I) {
+ MachineOperand &MO = MBBI->getOperand(I);
+ if (!MO.isReg() || MO.isDef())
+ continue;
+ Register Reg = MO.getReg();
+ if (!Reg)
+ continue;
+ for (MCRegAliasIterator AI(Reg, this, true); AI.isValid(); ++AI)
+ Uses.insert(*AI);
+ }
+
+ for (auto CS : AvailableRegs)
+ if (!Uses.count(CS) && CS != X86::RIP && CS != X86::RSP && CS != X86::ESP)
+ return CS;
+ }
+ }
+
+ return 0;
+}
+
Register X86RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
const X86FrameLowering *TFI = getFrameLowering(MF);
return TFI->hasFP(MF) ? FramePtr : StackPtr;
@@ -857,79 +857,79 @@ X86RegisterInfo::getPtrSizedStackRegister(const MachineFunction &MF) const {
StackReg = getX86SubSuperRegister(StackReg, 32);
return StackReg;
}
-
-static ShapeT getTileShape(Register VirtReg, VirtRegMap *VRM,
- const MachineRegisterInfo *MRI) {
- if (VRM->hasShape(VirtReg))
- return VRM->getShape(VirtReg);
-
- const MachineOperand &Def = *MRI->def_begin(VirtReg);
- MachineInstr *MI = const_cast<MachineInstr *>(Def.getParent());
- unsigned OpCode = MI->getOpcode();
- switch (OpCode) {
- default:
- llvm_unreachable("Unexpected machine instruction on tile register!");
- break;
- // We only collect the tile shape that is defined.
- case X86::PTILELOADDV:
- case X86::PTDPBSSDV:
- case X86::PTILEZEROV:
- MachineOperand &MO1 = MI->getOperand(1);
- MachineOperand &MO2 = MI->getOperand(2);
- ShapeT Shape(&MO1, &MO2, MRI);
- VRM->assignVirt2Shape(VirtReg, Shape);
- return Shape;
- }
-}
-
-bool X86RegisterInfo::getRegAllocationHints(Register VirtReg,
- ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints,
- const MachineFunction &MF,
- const VirtRegMap *VRM,
- const LiveRegMatrix *Matrix) const {
- const MachineRegisterInfo *MRI = &MF.getRegInfo();
- const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg);
- bool BaseImplRetVal = TargetRegisterInfo::getRegAllocationHints(
- VirtReg, Order, Hints, MF, VRM, Matrix);
-
- if (RC.getID() != X86::TILERegClassID)
- return BaseImplRetVal;
-
- ShapeT VirtShape = getTileShape(VirtReg, const_cast<VirtRegMap *>(VRM), MRI);
- auto AddHint = [&](MCPhysReg PhysReg) {
- Register VReg = Matrix->getOneVReg(PhysReg);
- if (VReg == MCRegister::NoRegister) { // Not allocated yet
- Hints.push_back(PhysReg);
- return;
- }
- ShapeT PhysShape = getTileShape(VReg, const_cast<VirtRegMap *>(VRM), MRI);
- if (PhysShape == VirtShape)
- Hints.push_back(PhysReg);
- };
-
- SmallSet<MCPhysReg, 4> CopyHints;
- CopyHints.insert(Hints.begin(), Hints.end());
- Hints.clear();
- for (auto Hint : CopyHints) {
- if (RC.contains(Hint) && !MRI->isReserved(Hint))
- AddHint(Hint);
- }
- for (MCPhysReg PhysReg : Order) {
- if (!CopyHints.count(PhysReg) && RC.contains(PhysReg) &&
- !MRI->isReserved(PhysReg))
- AddHint(PhysReg);
- }
-
-#define DEBUG_TYPE "tile-hint"
- LLVM_DEBUG({
- dbgs() << "Hints for virtual register " << format_hex(VirtReg, 8) << "\n";
- for (auto Hint : Hints) {
- dbgs() << "tmm" << Hint << ",";
- }
- dbgs() << "\n";
- });
-#undef DEBUG_TYPE
-
- return true;
-}
+
+static ShapeT getTileShape(Register VirtReg, VirtRegMap *VRM,
+ const MachineRegisterInfo *MRI) {
+ if (VRM->hasShape(VirtReg))
+ return VRM->getShape(VirtReg);
+
+ const MachineOperand &Def = *MRI->def_begin(VirtReg);
+ MachineInstr *MI = const_cast<MachineInstr *>(Def.getParent());
+ unsigned OpCode = MI->getOpcode();
+ switch (OpCode) {
+ default:
+ llvm_unreachable("Unexpected machine instruction on tile register!");
+ break;
+ // We only collect the tile shape that is defined.
+ case X86::PTILELOADDV:
+ case X86::PTDPBSSDV:
+ case X86::PTILEZEROV:
+ MachineOperand &MO1 = MI->getOperand(1);
+ MachineOperand &MO2 = MI->getOperand(2);
+ ShapeT Shape(&MO1, &MO2, MRI);
+ VRM->assignVirt2Shape(VirtReg, Shape);
+ return Shape;
+ }
+}
+
+bool X86RegisterInfo::getRegAllocationHints(Register VirtReg,
+ ArrayRef<MCPhysReg> Order,
+ SmallVectorImpl<MCPhysReg> &Hints,
+ const MachineFunction &MF,
+ const VirtRegMap *VRM,
+ const LiveRegMatrix *Matrix) const {
+ const MachineRegisterInfo *MRI = &MF.getRegInfo();
+ const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg);
+ bool BaseImplRetVal = TargetRegisterInfo::getRegAllocationHints(
+ VirtReg, Order, Hints, MF, VRM, Matrix);
+
+ if (RC.getID() != X86::TILERegClassID)
+ return BaseImplRetVal;
+
+ ShapeT VirtShape = getTileShape(VirtReg, const_cast<VirtRegMap *>(VRM), MRI);
+ auto AddHint = [&](MCPhysReg PhysReg) {
+ Register VReg = Matrix->getOneVReg(PhysReg);
+ if (VReg == MCRegister::NoRegister) { // Not allocated yet
+ Hints.push_back(PhysReg);
+ return;
+ }
+ ShapeT PhysShape = getTileShape(VReg, const_cast<VirtRegMap *>(VRM), MRI);
+ if (PhysShape == VirtShape)
+ Hints.push_back(PhysReg);
+ };
+
+ SmallSet<MCPhysReg, 4> CopyHints;
+ CopyHints.insert(Hints.begin(), Hints.end());
+ Hints.clear();
+ for (auto Hint : CopyHints) {
+ if (RC.contains(Hint) && !MRI->isReserved(Hint))
+ AddHint(Hint);
+ }
+ for (MCPhysReg PhysReg : Order) {
+ if (!CopyHints.count(PhysReg) && RC.contains(PhysReg) &&
+ !MRI->isReserved(PhysReg))
+ AddHint(PhysReg);
+ }
+
+#define DEBUG_TYPE "tile-hint"
+ LLVM_DEBUG({
+ dbgs() << "Hints for virtual register " << format_hex(VirtReg, 8) << "\n";
+ for (auto Hint : Hints) {
+ dbgs() << "tmm" << Hint << ",";
+ }
+ dbgs() << "\n";
+ });
+#undef DEBUG_TYPE
+
+ return true;
+}
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86RegisterInfo.h b/contrib/libs/llvm12/lib/Target/X86/X86RegisterInfo.h
index 4e4fb3f368..7fd10ddd1a 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86RegisterInfo.h
+++ b/contrib/libs/llvm12/lib/Target/X86/X86RegisterInfo.h
@@ -125,12 +125,12 @@ public:
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS = nullptr) const override;
- /// findDeadCallerSavedReg - Return a caller-saved register that isn't live
- /// when it reaches the "return" instruction. We can then pop a stack object
- /// to this register without worry about clobbering it.
- unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator &MBBI) const;
-
+ /// findDeadCallerSavedReg - Return a caller-saved register that isn't live
+ /// when it reaches the "return" instruction. We can then pop a stack object
+ /// to this register without worry about clobbering it.
+ unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator &MBBI) const;
+
// Debug information queries.
Register getFrameRegister(const MachineFunction &MF) const override;
unsigned getPtrSizedFrameRegister(const MachineFunction &MF) const;
@@ -144,11 +144,11 @@ public:
Register getFramePtr() const { return FramePtr; }
// FIXME: Move to FrameInfok
unsigned getSlotSize() const { return SlotSize; }
-
- bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints,
- const MachineFunction &MF, const VirtRegMap *VRM,
- const LiveRegMatrix *Matrix) const override;
+
+ bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order,
+ SmallVectorImpl<MCPhysReg> &Hints,
+ const MachineFunction &MF, const VirtRegMap *VRM,
+ const LiveRegMatrix *Matrix) const override;
};
} // End llvm namespace
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86RegisterInfo.td b/contrib/libs/llvm12/lib/Target/X86/X86RegisterInfo.td
index 29aa2bc252..75cbd4e1cf 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86RegisterInfo.td
+++ b/contrib/libs/llvm12/lib/Target/X86/X86RegisterInfo.td
@@ -265,9 +265,9 @@ let SubRegIndices = [sub_ymm] in {
}
}
-// Tile config registers.
-def TMMCFG: X86Reg<"tmmcfg", 0>;
-
+// Tile config registers.
+def TMMCFG: X86Reg<"tmmcfg", 0>;
+
// Tile "registers".
def TMM0: X86Reg<"tmm0", 0>;
def TMM1: X86Reg<"tmm1", 1>;
@@ -636,11 +636,11 @@ def VK64WM : RegisterClass<"X86", [v64i1], 64, (add VK32WM)> {let Size = 64;}
def BNDR : RegisterClass<"X86", [v2i64], 128, (sequence "BND%u", 0, 3)>;
// Tiles
-let CopyCost = -1 in // Don't allow copying of tile registers
-def TILE : RegisterClass<"X86", [x86amx], 8192,
+let CopyCost = -1 in // Don't allow copying of tile registers
+def TILE : RegisterClass<"X86", [x86amx], 8192,
(sequence "TMM%u", 0, 7)> {let Size = 8192;}
-def TILECFG : RegisterClass<"X86", [untyped], 512, (add TMMCFG)> {
- let CopyCost = -1; // Don't allow copying of tile config registers.
- let isAllocatable = 1;
- let Size = 512;
-}
+def TILECFG : RegisterClass<"X86", [untyped], 512, (add TMMCFG)> {
+ let CopyCost = -1; // Don't allow copying of tile config registers.
+ let isAllocatable = 1;
+ let Size = 512;
+}
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86SelectionDAGInfo.cpp b/contrib/libs/llvm12/lib/Target/X86/X86SelectionDAGInfo.cpp
index 8cfdeea3d1..e76908ef4b 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86SelectionDAGInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86SelectionDAGInfo.cpp
@@ -24,10 +24,10 @@ using namespace llvm;
#define DEBUG_TYPE "x86-selectiondag-info"
-static cl::opt<bool>
- UseFSRMForMemcpy("x86-use-fsrm-for-memcpy", cl::Hidden, cl::init(false),
- cl::desc("Use fast short rep mov in memcpy lowering"));
-
+static cl::opt<bool>
+ UseFSRMForMemcpy("x86-use-fsrm-for-memcpy", cl::Hidden, cl::init(false),
+ cl::desc("Use fast short rep mov in memcpy lowering"));
+
bool X86SelectionDAGInfo::isBaseRegConflictPossible(
SelectionDAG &DAG, ArrayRef<MCPhysReg> ClobberSet) const {
// We cannot use TRI->hasBasePointer() until *after* we select all basic
@@ -310,10 +310,10 @@ SDValue X86SelectionDAGInfo::EmitTargetCodeForMemcpy(
const X86Subtarget &Subtarget =
DAG.getMachineFunction().getSubtarget<X86Subtarget>();
- // If enabled and available, use fast short rep mov.
- if (UseFSRMForMemcpy && Subtarget.hasFSRM())
- return emitRepmovs(Subtarget, DAG, dl, Chain, Dst, Src, Size, MVT::i8);
-
+ // If enabled and available, use fast short rep mov.
+ if (UseFSRMForMemcpy && Subtarget.hasFSRM())
+ return emitRepmovs(Subtarget, DAG, dl, Chain, Dst, Src, Size, MVT::i8);
+
/// Handle constant sizes,
if (ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size))
return emitConstantSizeRepmov(
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp b/contrib/libs/llvm12/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp
index c3ed77fcae..14a3fea240 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp
@@ -293,4 +293,4 @@ void DecodeVPPERMMask(const Constant *C, unsigned Width,
}
}
-} // namespace llvm
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86SpeculativeExecutionSideEffectSuppression.cpp b/contrib/libs/llvm12/lib/Target/X86/X86SpeculativeExecutionSideEffectSuppression.cpp
index 5746c91c0b..d57871130b 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86SpeculativeExecutionSideEffectSuppression.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86SpeculativeExecutionSideEffectSuppression.cpp
@@ -161,7 +161,7 @@ bool X86SpeculativeExecutionSideEffectSuppression::runOnMachineFunction(
// This branch requires adding an LFENCE.
if (!PrevInstIsLFENCE) {
- assert(FirstTerminator && "Unknown terminator instruction");
+ assert(FirstTerminator && "Unknown terminator instruction");
BuildMI(MBB, FirstTerminator, DebugLoc(), TII->get(X86::LFENCE));
NumLFENCEsInserted++;
Modified = true;
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86SpeculativeLoadHardening.cpp b/contrib/libs/llvm12/lib/Target/X86/X86SpeculativeLoadHardening.cpp
index 0edb63589a..aa73d4bce6 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86SpeculativeLoadHardening.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86SpeculativeLoadHardening.cpp
@@ -184,7 +184,7 @@ private:
MachineBasicBlock::iterator InsertPt, DebugLoc Loc);
void restoreEFLAGS(MachineBasicBlock &MBB,
MachineBasicBlock::iterator InsertPt, DebugLoc Loc,
- Register Reg);
+ Register Reg);
void mergePredStateIntoSP(MachineBasicBlock &MBB,
MachineBasicBlock::iterator InsertPt, DebugLoc Loc,
@@ -200,8 +200,8 @@ private:
MachineInstr *
sinkPostLoadHardenedInst(MachineInstr &MI,
SmallPtrSetImpl<MachineInstr *> &HardenedInstrs);
- bool canHardenRegister(Register Reg);
- unsigned hardenValueInRegister(Register Reg, MachineBasicBlock &MBB,
+ bool canHardenRegister(Register Reg);
+ unsigned hardenValueInRegister(Register Reg, MachineBasicBlock &MBB,
MachineBasicBlock::iterator InsertPt,
DebugLoc Loc);
unsigned hardenPostLoad(MachineInstr &MI);
@@ -1520,7 +1520,7 @@ unsigned X86SpeculativeLoadHardeningPass::saveEFLAGS(
/// reliably lower.
void X86SpeculativeLoadHardeningPass::restoreEFLAGS(
MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertPt, DebugLoc Loc,
- Register Reg) {
+ Register Reg) {
BuildMI(MBB, InsertPt, Loc, TII->get(X86::COPY), X86::EFLAGS).addReg(Reg);
++NumInstsInserted;
}
@@ -1842,7 +1842,7 @@ MachineInstr *X86SpeculativeLoadHardeningPass::sinkPostLoadHardenedInst(
// just bail. Also check that its register class is one of the ones we
// can harden.
Register UseDefReg = UseMI.getOperand(0).getReg();
- if (!UseDefReg.isVirtual() || !canHardenRegister(UseDefReg))
+ if (!UseDefReg.isVirtual() || !canHardenRegister(UseDefReg))
return {};
SingleUseMI = &UseMI;
@@ -1864,7 +1864,7 @@ MachineInstr *X86SpeculativeLoadHardeningPass::sinkPostLoadHardenedInst(
return MI;
}
-bool X86SpeculativeLoadHardeningPass::canHardenRegister(Register Reg) {
+bool X86SpeculativeLoadHardeningPass::canHardenRegister(Register Reg) {
auto *RC = MRI->getRegClass(Reg);
int RegBytes = TRI->getRegSizeInBits(*RC) / 8;
if (RegBytes > 8)
@@ -1908,10 +1908,10 @@ bool X86SpeculativeLoadHardeningPass::canHardenRegister(Register Reg) {
/// The new, hardened virtual register is returned. It will have the same
/// register class as `Reg`.
unsigned X86SpeculativeLoadHardeningPass::hardenValueInRegister(
- Register Reg, MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertPt,
+ Register Reg, MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertPt,
DebugLoc Loc) {
assert(canHardenRegister(Reg) && "Cannot harden this register!");
- assert(Reg.isVirtual() && "Cannot harden a physical register!");
+ assert(Reg.isVirtual() && "Cannot harden a physical register!");
auto *RC = MRI->getRegClass(Reg);
int Bytes = TRI->getRegSizeInBits(*RC) / 8;
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86Subtarget.cpp b/contrib/libs/llvm12/lib/Target/X86/X86Subtarget.cpp
index e0a96938be..c95213c353 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86Subtarget.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86Subtarget.cpp
@@ -166,10 +166,10 @@ unsigned char X86Subtarget::classifyGlobalReference(const GlobalValue *GV,
return X86II::MO_DARWIN_NONLAZY_PIC_BASE;
}
- // 32-bit ELF references GlobalAddress directly in static relocation model.
- // We cannot use MO_GOT because EBX may not be set up.
- if (TM.getRelocationModel() == Reloc::Static)
- return X86II::MO_NO_FLAG;
+ // 32-bit ELF references GlobalAddress directly in static relocation model.
+ // We cannot use MO_GOT because EBX may not be set up.
+ if (TM.getRelocationModel() == Reloc::Static)
+ return X86II::MO_NO_FLAG;
return X86II::MO_GOT;
}
@@ -206,9 +206,9 @@ X86Subtarget::classifyGlobalFunctionReference(const GlobalValue *GV,
(!F && M.getRtLibUseGOT())) &&
is64Bit())
return X86II::MO_GOTPCREL;
- // Reference ExternalSymbol directly in static relocation model.
- if (!is64Bit() && !GV && TM.getRelocationModel() == Reloc::Static)
- return X86II::MO_NO_FLAG;
+ // Reference ExternalSymbol directly in static relocation model.
+ if (!is64Bit() && !GV && TM.getRelocationModel() == Reloc::Static)
+ return X86II::MO_NO_FLAG;
return X86II::MO_PLT;
}
@@ -234,22 +234,22 @@ bool X86Subtarget::isLegalToCallImmediateAddr() const {
return isTargetELF() || TM.getRelocationModel() == Reloc::Static;
}
-void X86Subtarget::initSubtargetFeatures(StringRef CPU, StringRef TuneCPU,
- StringRef FS) {
- if (CPU.empty())
- CPU = "generic";
+void X86Subtarget::initSubtargetFeatures(StringRef CPU, StringRef TuneCPU,
+ StringRef FS) {
+ if (CPU.empty())
+ CPU = "generic";
- if (TuneCPU.empty())
- TuneCPU = "i586"; // FIXME: "generic" is more modern than llc tests expect.
+ if (TuneCPU.empty())
+ TuneCPU = "i586"; // FIXME: "generic" is more modern than llc tests expect.
- std::string FullFS = X86_MC::ParseX86Triple(TargetTriple);
- assert(!FullFS.empty() && "Failed to parse X86 triple");
+ std::string FullFS = X86_MC::ParseX86Triple(TargetTriple);
+ assert(!FullFS.empty() && "Failed to parse X86 triple");
- if (!FS.empty())
- FullFS = (Twine(FullFS) + "," + FS).str();
+ if (!FS.empty())
+ FullFS = (Twine(FullFS) + "," + FS).str();
// Parse features string and set the CPU.
- ParseSubtargetFeatures(CPU, TuneCPU, FullFS);
+ ParseSubtargetFeatures(CPU, TuneCPU, FullFS);
// All CPUs that implement SSE4.2 or SSE4A support unaligned accesses of
// 16-bytes and under that are reasonably fast. These features were
@@ -265,13 +265,13 @@ void X86Subtarget::initSubtargetFeatures(StringRef CPU, StringRef TuneCPU,
report_fatal_error("64-bit code requested on a subtarget that doesn't "
"support it!");
- // Stack alignment is 16 bytes on Darwin, Linux, kFreeBSD and for all
- // 64-bit targets. On Solaris (32-bit), stack alignment is 4 bytes
- // following the i386 psABI, while on Illumos it is always 16 bytes.
+ // Stack alignment is 16 bytes on Darwin, Linux, kFreeBSD and for all
+ // 64-bit targets. On Solaris (32-bit), stack alignment is 4 bytes
+ // following the i386 psABI, while on Illumos it is always 16 bytes.
if (StackAlignOverride)
stackAlignment = *StackAlignOverride;
- else if (isTargetDarwin() || isTargetLinux() || isTargetKFreeBSD() ||
- In64BitMode)
+ else if (isTargetDarwin() || isTargetLinux() || isTargetKFreeBSD() ||
+ In64BitMode)
stackAlignment = Align(16);
// Consume the vector width attribute or apply any target specific limit.
@@ -284,24 +284,24 @@ void X86Subtarget::initSubtargetFeatures(StringRef CPU, StringRef TuneCPU,
}
X86Subtarget &X86Subtarget::initializeSubtargetDependencies(StringRef CPU,
- StringRef TuneCPU,
+ StringRef TuneCPU,
StringRef FS) {
- initSubtargetFeatures(CPU, TuneCPU, FS);
+ initSubtargetFeatures(CPU, TuneCPU, FS);
return *this;
}
-X86Subtarget::X86Subtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
- StringRef FS, const X86TargetMachine &TM,
+X86Subtarget::X86Subtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
+ StringRef FS, const X86TargetMachine &TM,
MaybeAlign StackAlignOverride,
unsigned PreferVectorWidthOverride,
unsigned RequiredVectorWidth)
- : X86GenSubtargetInfo(TT, CPU, TuneCPU, FS),
- PICStyle(PICStyles::Style::None), TM(TM), TargetTriple(TT),
- StackAlignOverride(StackAlignOverride),
+ : X86GenSubtargetInfo(TT, CPU, TuneCPU, FS),
+ PICStyle(PICStyles::Style::None), TM(TM), TargetTriple(TT),
+ StackAlignOverride(StackAlignOverride),
PreferVectorWidthOverride(PreferVectorWidthOverride),
RequiredVectorWidth(RequiredVectorWidth),
- InstrInfo(initializeSubtargetDependencies(CPU, TuneCPU, FS)),
- TLInfo(TM, *this), FrameLowering(*this, getStackAlignment()) {
+ InstrInfo(initializeSubtargetDependencies(CPU, TuneCPU, FS)),
+ TLInfo(TM, *this), FrameLowering(*this, getStackAlignment()) {
// Determine the PICStyle based on the target selected.
if (!isPositionIndependent())
setPICStyle(PICStyles::Style::None);
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86Subtarget.h b/contrib/libs/llvm12/lib/Target/X86/X86Subtarget.h
index 3bd6599215..fa2622333d 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86Subtarget.h
+++ b/contrib/libs/llvm12/lib/Target/X86/X86Subtarget.h
@@ -189,8 +189,8 @@ class X86Subtarget final : public X86GenSubtargetInfo {
/// Processor has RDSEED instructions.
bool HasRDSEED = false;
- /// Processor has LAHF/SAHF instructions in 64-bit mode.
- bool HasLAHFSAHF64 = false;
+ /// Processor has LAHF/SAHF instructions in 64-bit mode.
+ bool HasLAHFSAHF64 = false;
/// Processor has MONITORX/MWAITX instructions.
bool HasMWAITX = false;
@@ -302,9 +302,9 @@ class X86Subtarget final : public X86GenSubtargetInfo {
/// True if the processor has enhanced REP MOVSB/STOSB.
bool HasERMSB = false;
- /// True if the processor has fast short REP MOV.
- bool HasFSRM = false;
-
+ /// True if the processor has fast short REP MOV.
+ bool HasFSRM = false;
+
/// True if the short functions should be padded to prevent
/// a stall when returning too early.
bool PadShortFunctions = false;
@@ -355,9 +355,9 @@ class X86Subtarget final : public X86GenSubtargetInfo {
/// Processor has AVX-512 Vector Neural Network Instructions
bool HasVNNI = false;
- /// Processor has AVX Vector Neural Network Instructions
- bool HasAVXVNNI = false;
-
+ /// Processor has AVX Vector Neural Network Instructions
+ bool HasAVXVNNI = false;
+
/// Processor has AVX-512 bfloat16 floating-point extensions
bool HasBF16 = false;
@@ -398,15 +398,15 @@ class X86Subtarget final : public X86GenSubtargetInfo {
/// Processor supports PCONFIG instruction
bool HasPCONFIG = false;
- /// Processor support key locker instructions
- bool HasKL = false;
-
- /// Processor support key locker wide instructions
- bool HasWIDEKL = false;
-
- /// Processor supports HRESET instruction
- bool HasHRESET = false;
-
+ /// Processor support key locker instructions
+ bool HasKL = false;
+
+ /// Processor support key locker wide instructions
+ bool HasWIDEKL = false;
+
+ /// Processor supports HRESET instruction
+ bool HasHRESET = false;
+
/// Processor supports SERIALIZE instruction
bool HasSERIALIZE = false;
@@ -418,9 +418,9 @@ class X86Subtarget final : public X86GenSubtargetInfo {
bool HasAMXBF16 = false;
bool HasAMXINT8 = false;
- /// Processor supports User Level Interrupt instructions
- bool HasUINTR = false;
-
+ /// Processor supports User Level Interrupt instructions
+ bool HasUINTR = false;
+
/// Processor has a single uop BEXTR implementation.
bool HasFastBEXTR = false;
@@ -472,8 +472,8 @@ class X86Subtarget final : public X86GenSubtargetInfo {
/// entry to the function and which must be maintained by every function.
Align stackAlignment = Align(4);
- Align TileConfigAlignment = Align(4);
-
+ Align TileConfigAlignment = Align(4);
+
/// Max. memset / memcpy size that is turned into rep/movs, rep/stos ops.
///
// FIXME: this is a known good value for Yonah. How about others?
@@ -515,13 +515,13 @@ private:
unsigned RequiredVectorWidth;
/// True if compiling for 64-bit, false for 16-bit or 32-bit.
- bool In64BitMode = false;
+ bool In64BitMode = false;
/// True if compiling for 32-bit, false for 16-bit or 64-bit.
- bool In32BitMode = false;
+ bool In32BitMode = false;
/// True if compiling for 16-bit, false for 32-bit or 64-bit.
- bool In16BitMode = false;
+ bool In16BitMode = false;
X86SelectionDAGInfo TSInfo;
// Ordering here is important. X86InstrInfo initializes X86RegisterInfo which
@@ -534,7 +534,7 @@ public:
/// This constructor initializes the data members to match that
/// of the specified triple.
///
- X86Subtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU, StringRef FS,
+ X86Subtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU, StringRef FS,
const X86TargetMachine &TM, MaybeAlign StackAlignOverride,
unsigned PreferVectorWidthOverride,
unsigned RequiredVectorWidth);
@@ -557,9 +557,9 @@ public:
return &getInstrInfo()->getRegisterInfo();
}
- unsigned getTileConfigSize() const { return 64; }
- Align getTileConfigAlignment() const { return TileConfigAlignment; }
-
+ unsigned getTileConfigSize() const { return 64; }
+ Align getTileConfigAlignment() const { return TileConfigAlignment; }
+
/// Returns the minimum alignment known to hold of the
/// stack frame on entry to the function and which must be maintained by every
/// function for this subtarget.
@@ -571,7 +571,7 @@ public:
/// ParseSubtargetFeatures - Parses features string setting specified
/// subtarget options. Definition of function is auto generated by tblgen.
- void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
+ void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
/// Methods used by Global ISel
const CallLowering *getCallLowering() const override;
@@ -582,10 +582,10 @@ public:
private:
/// Initialize the full set of dependencies so we can use an initializer
/// list for X86Subtarget.
- X86Subtarget &initializeSubtargetDependencies(StringRef CPU,
- StringRef TuneCPU,
- StringRef FS);
- void initSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
+ X86Subtarget &initializeSubtargetDependencies(StringRef CPU,
+ StringRef TuneCPU,
+ StringRef FS);
+ void initSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
public:
/// Is this x86_64? (disregarding specific ABI / programming model)
@@ -684,7 +684,7 @@ public:
return hasSSE1() || (hasPRFCHW() && !has3DNow()) || hasPREFETCHWT1();
}
bool hasRDSEED() const { return HasRDSEED; }
- bool hasLAHFSAHF() const { return HasLAHFSAHF64 || !is64Bit(); }
+ bool hasLAHFSAHF() const { return HasLAHFSAHF64 || !is64Bit(); }
bool hasMWAITX() const { return HasMWAITX; }
bool hasCLZERO() const { return HasCLZERO; }
bool hasCLDEMOTE() const { return HasCLDEMOTE; }
@@ -717,7 +717,7 @@ public:
bool hasMacroFusion() const { return HasMacroFusion; }
bool hasBranchFusion() const { return HasBranchFusion; }
bool hasERMSB() const { return HasERMSB; }
- bool hasFSRM() const { return HasFSRM; }
+ bool hasFSRM() const { return HasFSRM; }
bool hasSlowDivide32() const { return HasSlowDivide32; }
bool hasSlowDivide64() const { return HasSlowDivide64; }
bool padShortFunctions() const { return PadShortFunctions; }
@@ -748,17 +748,17 @@ public:
bool hasSGX() const { return HasSGX; }
bool hasINVPCID() const { return HasINVPCID; }
bool hasENQCMD() const { return HasENQCMD; }
- bool hasKL() const { return HasKL; }
- bool hasWIDEKL() const { return HasWIDEKL; }
- bool hasHRESET() const { return HasHRESET; }
+ bool hasKL() const { return HasKL; }
+ bool hasWIDEKL() const { return HasWIDEKL; }
+ bool hasHRESET() const { return HasHRESET; }
bool hasSERIALIZE() const { return HasSERIALIZE; }
bool hasTSXLDTRK() const { return HasTSXLDTRK; }
- bool hasUINTR() const { return HasUINTR; }
+ bool hasUINTR() const { return HasUINTR; }
bool useRetpolineIndirectCalls() const { return UseRetpolineIndirectCalls; }
bool useRetpolineIndirectBranches() const {
return UseRetpolineIndirectBranches;
}
- bool hasAVXVNNI() const { return HasAVXVNNI; }
+ bool hasAVXVNNI() const { return HasAVXVNNI; }
bool hasAMXTILE() const { return HasAMXTILE; }
bool hasAMXBF16() const { return HasAMXBF16; }
bool hasAMXINT8() const { return HasAMXINT8; }
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86TargetMachine.cpp b/contrib/libs/llvm12/lib/Target/X86/X86TargetMachine.cpp
index 762ea5bc6e..c8f76c210a 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86TargetMachine.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86TargetMachine.cpp
@@ -62,7 +62,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeX86Target() {
RegisterTargetMachine<X86TargetMachine> Y(getTheX86_64Target());
PassRegistry &PR = *PassRegistry::getPassRegistry();
- initializeX86LowerAMXTypeLegacyPassPass(PR);
+ initializeX86LowerAMXTypeLegacyPassPass(PR);
initializeGlobalISel(PR);
initializeWinEHStatePassPass(PR);
initializeFixupBWInstPassPass(PR);
@@ -72,7 +72,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeX86Target() {
initializeX86FixupSetCCPassPass(PR);
initializeX86CallFrameOptimizationPass(PR);
initializeX86CmovConverterPassPass(PR);
- initializeX86TileConfigPass(PR);
+ initializeX86TileConfigPass(PR);
initializeX86ExpandPseudoPass(PR);
initializeX86ExecutionDomainFixPass(PR);
initializeX86DomainReassignmentPass(PR);
@@ -85,7 +85,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeX86Target() {
initializeX86LoadValueInjectionRetHardeningPassPass(PR);
initializeX86OptimizeLEAPassPass(PR);
initializeX86PartialReductionPass(PR);
- initializePseudoProbeInserterPass(PR);
+ initializePseudoProbeInserterPass(PR);
}
static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
@@ -236,30 +236,30 @@ X86TargetMachine::~X86TargetMachine() = default;
const X86Subtarget *
X86TargetMachine::getSubtargetImpl(const Function &F) const {
Attribute CPUAttr = F.getFnAttribute("target-cpu");
- Attribute TuneAttr = F.getFnAttribute("tune-cpu");
+ Attribute TuneAttr = F.getFnAttribute("tune-cpu");
Attribute FSAttr = F.getFnAttribute("target-features");
- StringRef CPU =
- CPUAttr.isValid() ? CPUAttr.getValueAsString() : (StringRef)TargetCPU;
- StringRef TuneCPU =
- TuneAttr.isValid() ? TuneAttr.getValueAsString() : (StringRef)CPU;
- StringRef FS =
- FSAttr.isValid() ? FSAttr.getValueAsString() : (StringRef)TargetFS;
+ StringRef CPU =
+ CPUAttr.isValid() ? CPUAttr.getValueAsString() : (StringRef)TargetCPU;
+ StringRef TuneCPU =
+ TuneAttr.isValid() ? TuneAttr.getValueAsString() : (StringRef)CPU;
+ StringRef FS =
+ FSAttr.isValid() ? FSAttr.getValueAsString() : (StringRef)TargetFS;
SmallString<512> Key;
- // The additions here are ordered so that the definitely short strings are
- // added first so we won't exceed the small size. We append the
- // much longer FS string at the end so that we only heap allocate at most
- // one time.
+ // The additions here are ordered so that the definitely short strings are
+ // added first so we won't exceed the small size. We append the
+ // much longer FS string at the end so that we only heap allocate at most
+ // one time.
// Extract prefer-vector-width attribute.
unsigned PreferVectorWidthOverride = 0;
- Attribute PreferVecWidthAttr = F.getFnAttribute("prefer-vector-width");
- if (PreferVecWidthAttr.isValid()) {
- StringRef Val = PreferVecWidthAttr.getValueAsString();
+ Attribute PreferVecWidthAttr = F.getFnAttribute("prefer-vector-width");
+ if (PreferVecWidthAttr.isValid()) {
+ StringRef Val = PreferVecWidthAttr.getValueAsString();
unsigned Width;
if (!Val.getAsInteger(0, Width)) {
- Key += "prefer-vector-width=";
+ Key += "prefer-vector-width=";
Key += Val;
PreferVectorWidthOverride = Width;
}
@@ -267,45 +267,45 @@ X86TargetMachine::getSubtargetImpl(const Function &F) const {
// Extract min-legal-vector-width attribute.
unsigned RequiredVectorWidth = UINT32_MAX;
- Attribute MinLegalVecWidthAttr = F.getFnAttribute("min-legal-vector-width");
- if (MinLegalVecWidthAttr.isValid()) {
- StringRef Val = MinLegalVecWidthAttr.getValueAsString();
+ Attribute MinLegalVecWidthAttr = F.getFnAttribute("min-legal-vector-width");
+ if (MinLegalVecWidthAttr.isValid()) {
+ StringRef Val = MinLegalVecWidthAttr.getValueAsString();
unsigned Width;
if (!Val.getAsInteger(0, Width)) {
- Key += "min-legal-vector-width=";
+ Key += "min-legal-vector-width=";
Key += Val;
RequiredVectorWidth = Width;
}
}
- // Add CPU to the Key.
- Key += CPU;
-
- // Add tune CPU to the Key.
- Key += "tune=";
- Key += TuneCPU;
-
- // Keep track of the start of the feature portion of the string.
- unsigned FSStart = Key.size();
-
- // FIXME: This is related to the code below to reset the target options,
- // we need to know whether or not the soft float flag is set on the
- // function before we can generate a subtarget. We also need to use
- // it as a key for the subtarget since that can be the only difference
- // between two functions.
- bool SoftFloat =
- F.getFnAttribute("use-soft-float").getValueAsString() == "true";
- // If the soft float attribute is set on the function turn on the soft float
- // subtarget feature.
- if (SoftFloat)
- Key += FS.empty() ? "+soft-float" : "+soft-float,";
-
- Key += FS;
-
- // We may have added +soft-float to the features so move the StringRef to
- // point to the full string in the Key.
- FS = Key.substr(FSStart);
-
+ // Add CPU to the Key.
+ Key += CPU;
+
+ // Add tune CPU to the Key.
+ Key += "tune=";
+ Key += TuneCPU;
+
+ // Keep track of the start of the feature portion of the string.
+ unsigned FSStart = Key.size();
+
+ // FIXME: This is related to the code below to reset the target options,
+ // we need to know whether or not the soft float flag is set on the
+ // function before we can generate a subtarget. We also need to use
+ // it as a key for the subtarget since that can be the only difference
+ // between two functions.
+ bool SoftFloat =
+ F.getFnAttribute("use-soft-float").getValueAsString() == "true";
+ // If the soft float attribute is set on the function turn on the soft float
+ // subtarget feature.
+ if (SoftFloat)
+ Key += FS.empty() ? "+soft-float" : "+soft-float,";
+
+ Key += FS;
+
+ // We may have added +soft-float to the features so move the StringRef to
+ // point to the full string in the Key.
+ FS = Key.substr(FSStart);
+
auto &I = SubtargetMap[Key];
if (!I) {
// This needs to be done before we create a new subtarget since any
@@ -313,21 +313,21 @@ X86TargetMachine::getSubtargetImpl(const Function &F) const {
// function that reside in TargetOptions.
resetTargetOptions(F);
I = std::make_unique<X86Subtarget>(
- TargetTriple, CPU, TuneCPU, FS, *this,
+ TargetTriple, CPU, TuneCPU, FS, *this,
MaybeAlign(Options.StackAlignmentOverride), PreferVectorWidthOverride,
RequiredVectorWidth);
}
return I.get();
}
-bool X86TargetMachine::isNoopAddrSpaceCast(unsigned SrcAS,
- unsigned DestAS) const {
- assert(SrcAS != DestAS && "Expected different address spaces!");
- if (getPointerSize(SrcAS) != getPointerSize(DestAS))
- return false;
- return SrcAS < 256 && DestAS < 256;
-}
-
+bool X86TargetMachine::isNoopAddrSpaceCast(unsigned SrcAS,
+ unsigned DestAS) const {
+ assert(SrcAS != DestAS && "Expected different address spaces!");
+ if (getPointerSize(SrcAS) != getPointerSize(DestAS))
+ return false;
+ return SrcAS < 256 && DestAS < 256;
+}
+
//===----------------------------------------------------------------------===//
// X86 TTI query.
//===----------------------------------------------------------------------===//
@@ -381,7 +381,7 @@ public:
void addPreEmitPass() override;
void addPreEmitPass2() override;
void addPreSched2() override;
- bool addPreRewrite() override;
+ bool addPreRewrite() override;
std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
};
@@ -410,7 +410,7 @@ TargetPassConfig *X86TargetMachine::createPassConfig(PassManagerBase &PM) {
void X86PassConfig::addIRPasses() {
addPass(createAtomicExpandPass());
- addPass(createX86LowerAMXTypePass());
+ addPass(createX86LowerAMXTypePass());
TargetPassConfig::addIRPasses();
@@ -449,7 +449,7 @@ bool X86PassConfig::addInstSelector() {
}
bool X86PassConfig::addIRTranslator() {
- addPass(new IRTranslator(getOptLevel()));
+ addPass(new IRTranslator(getOptLevel()));
return false;
}
@@ -496,12 +496,12 @@ void X86PassConfig::addPreRegAlloc() {
addPass(createX86SpeculativeLoadHardeningPass());
addPass(createX86FlagsCopyLoweringPass());
addPass(createX86WinAllocaExpander());
-
- if (getOptLevel() != CodeGenOpt::None) {
- addPass(createX86PreTileConfigPass());
- }
+
+ if (getOptLevel() != CodeGenOpt::None) {
+ addPass(createX86PreTileConfigPass());
+ }
}
-
+
void X86PassConfig::addMachineSSAOptimization() {
addPass(createX86DomainReassignmentPass());
TargetPassConfig::addMachineSSAOptimization();
@@ -574,11 +574,11 @@ void X86PassConfig::addPreEmitPass2() {
addPass(createX86LoadValueInjectionRetHardeningPass());
}
-bool X86PassConfig::addPreRewrite() {
- addPass(createX86TileConfigPass());
- return true;
-}
-
+bool X86PassConfig::addPreRewrite() {
+ addPass(createX86TileConfigPass());
+ return true;
+}
+
std::unique_ptr<CSEConfigBase> X86PassConfig::getCSEConfig() const {
return getStandardCSEConfigForOpt(TM->getOptLevel());
}
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86TargetMachine.h b/contrib/libs/llvm12/lib/Target/X86/X86TargetMachine.h
index 3c77581146..69d7e48b89 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86TargetMachine.h
+++ b/contrib/libs/llvm12/lib/Target/X86/X86TargetMachine.h
@@ -54,8 +54,8 @@ public:
}
bool isJIT() const { return IsJIT; }
-
- bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override;
+
+ bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override;
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86TargetObjectFile.h b/contrib/libs/llvm12/lib/Target/X86/X86TargetObjectFile.h
index dbed7df9c6..f4bf52c837 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86TargetObjectFile.h
+++ b/contrib/libs/llvm12/lib/Target/X86/X86TargetObjectFile.h
@@ -36,7 +36,7 @@ namespace llvm {
MCStreamer &Streamer) const override;
};
- /// This implementation is used for X86 ELF targets that don't
+ /// This implementation is used for X86 ELF targets that don't
/// have a further specialization.
class X86ELFTargetObjectFile : public TargetLoweringObjectFileELF {
public:
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86TargetTransformInfo.cpp b/contrib/libs/llvm12/lib/Target/X86/X86TargetTransformInfo.cpp
index 0741fa9ad3..71455237fb 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86TargetTransformInfo.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86TargetTransformInfo.cpp
@@ -232,16 +232,16 @@ int X86TTIImpl::getArithmeticInstrCost(unsigned Opcode, Type *Ty,
bool Op2Signed = false;
unsigned Op2MinSize = BaseT::minRequiredElementSize(Args[1], Op2Signed);
- bool SignedMode = Op1Signed || Op2Signed;
+ bool SignedMode = Op1Signed || Op2Signed;
unsigned OpMinSize = std::max(Op1MinSize, Op2MinSize);
if (OpMinSize <= 7)
return LT.first * 3; // pmullw/sext
- if (!SignedMode && OpMinSize <= 8)
+ if (!SignedMode && OpMinSize <= 8)
return LT.first * 3; // pmullw/zext
if (OpMinSize <= 15)
return LT.first * 5; // pmullw/pmulhw/pshuf
- if (!SignedMode && OpMinSize <= 16)
+ if (!SignedMode && OpMinSize <= 16)
return LT.first * 5; // pmullw/pmulhw/pshuf
}
@@ -321,11 +321,11 @@ int X86TTIImpl::getArithmeticInstrCost(unsigned Opcode, Type *Ty,
{ ISD::SHL, MVT::v64i8, 4 }, // psllw + pand.
{ ISD::SRL, MVT::v64i8, 4 }, // psrlw + pand.
{ ISD::SRA, MVT::v64i8, 8 }, // psrlw, pand, pxor, psubb.
-
- { ISD::SDIV, MVT::v16i32, 6 }, // pmuludq sequence
- { ISD::SREM, MVT::v16i32, 8 }, // pmuludq+mul+sub sequence
- { ISD::UDIV, MVT::v16i32, 5 }, // pmuludq sequence
- { ISD::UREM, MVT::v16i32, 7 }, // pmuludq+mul+sub sequence
+
+ { ISD::SDIV, MVT::v16i32, 6 }, // pmuludq sequence
+ { ISD::SREM, MVT::v16i32, 8 }, // pmuludq+mul+sub sequence
+ { ISD::UDIV, MVT::v16i32, 5 }, // pmuludq sequence
+ { ISD::UREM, MVT::v16i32, 7 }, // pmuludq+mul+sub sequence
};
if (Op2Info == TargetTransformInfo::OK_UniformConstantValue &&
@@ -341,11 +341,11 @@ int X86TTIImpl::getArithmeticInstrCost(unsigned Opcode, Type *Ty,
{ ISD::SRA, MVT::v32i8, 4 }, // psrlw, pand, pxor, psubb.
{ ISD::SRA, MVT::v4i64, 4 }, // 2 x psrad + shuffle.
-
- { ISD::SDIV, MVT::v8i32, 6 }, // pmuludq sequence
- { ISD::SREM, MVT::v8i32, 8 }, // pmuludq+mul+sub sequence
- { ISD::UDIV, MVT::v8i32, 5 }, // pmuludq sequence
- { ISD::UREM, MVT::v8i32, 7 }, // pmuludq+mul+sub sequence
+
+ { ISD::SDIV, MVT::v8i32, 6 }, // pmuludq sequence
+ { ISD::SREM, MVT::v8i32, 8 }, // pmuludq+mul+sub sequence
+ { ISD::UDIV, MVT::v8i32, 5 }, // pmuludq sequence
+ { ISD::UREM, MVT::v8i32, 7 }, // pmuludq+mul+sub sequence
};
if (Op2Info == TargetTransformInfo::OK_UniformConstantValue &&
@@ -363,15 +363,15 @@ int X86TTIImpl::getArithmeticInstrCost(unsigned Opcode, Type *Ty,
{ ISD::SHL, MVT::v32i8, 4+2 }, // 2*(psllw + pand) + split.
{ ISD::SRL, MVT::v32i8, 4+2 }, // 2*(psrlw + pand) + split.
{ ISD::SRA, MVT::v32i8, 8+2 }, // 2*(psrlw, pand, pxor, psubb) + split.
-
- { ISD::SDIV, MVT::v8i32, 12+2 }, // 2*pmuludq sequence + split.
- { ISD::SREM, MVT::v8i32, 16+2 }, // 2*pmuludq+mul+sub sequence + split.
- { ISD::SDIV, MVT::v4i32, 6 }, // pmuludq sequence
- { ISD::SREM, MVT::v4i32, 8 }, // pmuludq+mul+sub sequence
- { ISD::UDIV, MVT::v8i32, 10+2 }, // 2*pmuludq sequence + split.
- { ISD::UREM, MVT::v8i32, 14+2 }, // 2*pmuludq+mul+sub sequence + split.
- { ISD::UDIV, MVT::v4i32, 5 }, // pmuludq sequence
- { ISD::UREM, MVT::v4i32, 7 }, // pmuludq+mul+sub sequence
+
+ { ISD::SDIV, MVT::v8i32, 12+2 }, // 2*pmuludq sequence + split.
+ { ISD::SREM, MVT::v8i32, 16+2 }, // 2*pmuludq+mul+sub sequence + split.
+ { ISD::SDIV, MVT::v4i32, 6 }, // pmuludq sequence
+ { ISD::SREM, MVT::v4i32, 8 }, // pmuludq+mul+sub sequence
+ { ISD::UDIV, MVT::v8i32, 10+2 }, // 2*pmuludq sequence + split.
+ { ISD::UREM, MVT::v8i32, 14+2 }, // 2*pmuludq+mul+sub sequence + split.
+ { ISD::UDIV, MVT::v4i32, 5 }, // pmuludq sequence
+ { ISD::UREM, MVT::v4i32, 7 }, // pmuludq+mul+sub sequence
};
// XOP has faster vXi8 shifts.
@@ -1128,9 +1128,9 @@ int X86TTIImpl::getShuffleCost(TTI::ShuffleKind Kind, VectorType *BaseTp,
{TTI::SK_PermuteTwoSrc, MVT::v16i16, 2}, // vpermt2w
{TTI::SK_PermuteTwoSrc, MVT::v8i16, 2}, // vpermt2w
{TTI::SK_PermuteTwoSrc, MVT::v64i8, 19}, // 6 * v32i8 + 1
-
- {TTI::SK_Select, MVT::v32i16, 1}, // vblendmw
- {TTI::SK_Select, MVT::v64i8, 1}, // vblendmb
+
+ {TTI::SK_Select, MVT::v32i16, 1}, // vblendmw
+ {TTI::SK_Select, MVT::v64i8, 1}, // vblendmb
};
if (ST->hasBWI())
@@ -1184,13 +1184,13 @@ int X86TTIImpl::getShuffleCost(TTI::ShuffleKind Kind, VectorType *BaseTp,
{TTI::SK_PermuteSingleSrc, MVT::v64i8, 14},
{TTI::SK_PermuteTwoSrc, MVT::v32i16, 42},
{TTI::SK_PermuteTwoSrc, MVT::v64i8, 42},
-
- {TTI::SK_Select, MVT::v32i16, 1}, // vpternlogq
- {TTI::SK_Select, MVT::v64i8, 1}, // vpternlogq
- {TTI::SK_Select, MVT::v8f64, 1}, // vblendmpd
- {TTI::SK_Select, MVT::v16f32, 1}, // vblendmps
- {TTI::SK_Select, MVT::v8i64, 1}, // vblendmq
- {TTI::SK_Select, MVT::v16i32, 1}, // vblendmd
+
+ {TTI::SK_Select, MVT::v32i16, 1}, // vpternlogq
+ {TTI::SK_Select, MVT::v64i8, 1}, // vpternlogq
+ {TTI::SK_Select, MVT::v8f64, 1}, // vblendmpd
+ {TTI::SK_Select, MVT::v16f32, 1}, // vblendmps
+ {TTI::SK_Select, MVT::v8i64, 1}, // vblendmq
+ {TTI::SK_Select, MVT::v16i32, 1}, // vblendmd
};
if (ST->hasAVX512())
@@ -1396,7 +1396,7 @@ int X86TTIImpl::getShuffleCost(TTI::ShuffleKind Kind, VectorType *BaseTp,
}
int X86TTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
- TTI::CastContextHint CCH,
+ TTI::CastContextHint CCH,
TTI::TargetCostKind CostKind,
const Instruction *I) {
int ISD = TLI->InstructionOpcodeToISD(Opcode);
@@ -2018,7 +2018,7 @@ int X86TTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
// The function getSimpleVT only handles simple value types.
if (!SrcTy.isSimple() || !DstTy.isSimple())
- return AdjustCost(BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind));
+ return AdjustCost(BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind));
MVT SimpleSrcTy = SrcTy.getSimpleVT();
MVT SimpleDstTy = DstTy.getSimpleVT();
@@ -2079,18 +2079,18 @@ int X86TTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
return AdjustCost(Entry->Cost);
}
- return AdjustCost(
- BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I));
+ return AdjustCost(
+ BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I));
}
int X86TTIImpl::getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
- CmpInst::Predicate VecPred,
+ CmpInst::Predicate VecPred,
TTI::TargetCostKind CostKind,
const Instruction *I) {
// TODO: Handle other cost kinds.
if (CostKind != TTI::TCK_RecipThroughput)
- return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
- I);
+ return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
+ I);
// Legalize the type.
std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, ValTy);
@@ -2274,7 +2274,7 @@ int X86TTIImpl::getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy))
return LT.first * (ExtraCost + Entry->Cost);
- return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind, I);
+ return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind, I);
}
unsigned X86TTIImpl::getAtomicMemIntrinsicMaxElementSize() const { return 16; }
@@ -2288,9 +2288,9 @@ int X86TTIImpl::getTypeBasedIntrinsicInstrCost(
// CTLZ: llvm\test\CodeGen\X86\vector-lzcnt-*.ll
// CTPOP: llvm\test\CodeGen\X86\vector-popcnt-*.ll
// CTTZ: llvm\test\CodeGen\X86\vector-tzcnt-*.ll
-
- // TODO: Overflow intrinsics (*ADDO, *SUBO, *MULO) with vector types are not
- // specialized in these tables yet.
+
+ // TODO: Overflow intrinsics (*ADDO, *SUBO, *MULO) with vector types are not
+ // specialized in these tables yet.
static const CostTblEntry AVX512CDCostTbl[] = {
{ ISD::CTLZ, MVT::v8i64, 1 },
{ ISD::CTLZ, MVT::v16i32, 1 },
@@ -2306,8 +2306,8 @@ int X86TTIImpl::getTypeBasedIntrinsicInstrCost(
{ ISD::CTLZ, MVT::v16i8, 4 },
};
static const CostTblEntry AVX512BWCostTbl[] = {
- { ISD::ABS, MVT::v32i16, 1 },
- { ISD::ABS, MVT::v64i8, 1 },
+ { ISD::ABS, MVT::v32i16, 1 },
+ { ISD::ABS, MVT::v64i8, 1 },
{ ISD::BITREVERSE, MVT::v8i64, 5 },
{ ISD::BITREVERSE, MVT::v16i32, 5 },
{ ISD::BITREVERSE, MVT::v32i16, 5 },
@@ -2326,28 +2326,28 @@ int X86TTIImpl::getTypeBasedIntrinsicInstrCost(
{ ISD::CTTZ, MVT::v64i8, 9 },
{ ISD::SADDSAT, MVT::v32i16, 1 },
{ ISD::SADDSAT, MVT::v64i8, 1 },
- { ISD::SMAX, MVT::v32i16, 1 },
- { ISD::SMAX, MVT::v64i8, 1 },
- { ISD::SMIN, MVT::v32i16, 1 },
- { ISD::SMIN, MVT::v64i8, 1 },
+ { ISD::SMAX, MVT::v32i16, 1 },
+ { ISD::SMAX, MVT::v64i8, 1 },
+ { ISD::SMIN, MVT::v32i16, 1 },
+ { ISD::SMIN, MVT::v64i8, 1 },
{ ISD::SSUBSAT, MVT::v32i16, 1 },
{ ISD::SSUBSAT, MVT::v64i8, 1 },
{ ISD::UADDSAT, MVT::v32i16, 1 },
{ ISD::UADDSAT, MVT::v64i8, 1 },
- { ISD::UMAX, MVT::v32i16, 1 },
- { ISD::UMAX, MVT::v64i8, 1 },
- { ISD::UMIN, MVT::v32i16, 1 },
- { ISD::UMIN, MVT::v64i8, 1 },
+ { ISD::UMAX, MVT::v32i16, 1 },
+ { ISD::UMAX, MVT::v64i8, 1 },
+ { ISD::UMIN, MVT::v32i16, 1 },
+ { ISD::UMIN, MVT::v64i8, 1 },
{ ISD::USUBSAT, MVT::v32i16, 1 },
{ ISD::USUBSAT, MVT::v64i8, 1 },
};
static const CostTblEntry AVX512CostTbl[] = {
- { ISD::ABS, MVT::v8i64, 1 },
- { ISD::ABS, MVT::v16i32, 1 },
- { ISD::ABS, MVT::v32i16, 2 }, // FIXME: include split
- { ISD::ABS, MVT::v64i8, 2 }, // FIXME: include split
- { ISD::ABS, MVT::v4i64, 1 },
- { ISD::ABS, MVT::v2i64, 1 },
+ { ISD::ABS, MVT::v8i64, 1 },
+ { ISD::ABS, MVT::v16i32, 1 },
+ { ISD::ABS, MVT::v32i16, 2 }, // FIXME: include split
+ { ISD::ABS, MVT::v64i8, 2 }, // FIXME: include split
+ { ISD::ABS, MVT::v4i64, 1 },
+ { ISD::ABS, MVT::v2i64, 1 },
{ ISD::BITREVERSE, MVT::v8i64, 36 },
{ ISD::BITREVERSE, MVT::v16i32, 24 },
{ ISD::BITREVERSE, MVT::v32i16, 10 },
@@ -2364,30 +2364,30 @@ int X86TTIImpl::getTypeBasedIntrinsicInstrCost(
{ ISD::CTTZ, MVT::v16i32, 28 },
{ ISD::CTTZ, MVT::v32i16, 24 },
{ ISD::CTTZ, MVT::v64i8, 18 },
- { ISD::SMAX, MVT::v8i64, 1 },
- { ISD::SMAX, MVT::v16i32, 1 },
- { ISD::SMAX, MVT::v32i16, 2 }, // FIXME: include split
- { ISD::SMAX, MVT::v64i8, 2 }, // FIXME: include split
- { ISD::SMAX, MVT::v4i64, 1 },
- { ISD::SMAX, MVT::v2i64, 1 },
- { ISD::SMIN, MVT::v8i64, 1 },
- { ISD::SMIN, MVT::v16i32, 1 },
- { ISD::SMIN, MVT::v32i16, 2 }, // FIXME: include split
- { ISD::SMIN, MVT::v64i8, 2 }, // FIXME: include split
- { ISD::SMIN, MVT::v4i64, 1 },
- { ISD::SMIN, MVT::v2i64, 1 },
- { ISD::UMAX, MVT::v8i64, 1 },
- { ISD::UMAX, MVT::v16i32, 1 },
- { ISD::UMAX, MVT::v32i16, 2 }, // FIXME: include split
- { ISD::UMAX, MVT::v64i8, 2 }, // FIXME: include split
- { ISD::UMAX, MVT::v4i64, 1 },
- { ISD::UMAX, MVT::v2i64, 1 },
- { ISD::UMIN, MVT::v8i64, 1 },
- { ISD::UMIN, MVT::v16i32, 1 },
- { ISD::UMIN, MVT::v32i16, 2 }, // FIXME: include split
- { ISD::UMIN, MVT::v64i8, 2 }, // FIXME: include split
- { ISD::UMIN, MVT::v4i64, 1 },
- { ISD::UMIN, MVT::v2i64, 1 },
+ { ISD::SMAX, MVT::v8i64, 1 },
+ { ISD::SMAX, MVT::v16i32, 1 },
+ { ISD::SMAX, MVT::v32i16, 2 }, // FIXME: include split
+ { ISD::SMAX, MVT::v64i8, 2 }, // FIXME: include split
+ { ISD::SMAX, MVT::v4i64, 1 },
+ { ISD::SMAX, MVT::v2i64, 1 },
+ { ISD::SMIN, MVT::v8i64, 1 },
+ { ISD::SMIN, MVT::v16i32, 1 },
+ { ISD::SMIN, MVT::v32i16, 2 }, // FIXME: include split
+ { ISD::SMIN, MVT::v64i8, 2 }, // FIXME: include split
+ { ISD::SMIN, MVT::v4i64, 1 },
+ { ISD::SMIN, MVT::v2i64, 1 },
+ { ISD::UMAX, MVT::v8i64, 1 },
+ { ISD::UMAX, MVT::v16i32, 1 },
+ { ISD::UMAX, MVT::v32i16, 2 }, // FIXME: include split
+ { ISD::UMAX, MVT::v64i8, 2 }, // FIXME: include split
+ { ISD::UMAX, MVT::v4i64, 1 },
+ { ISD::UMAX, MVT::v2i64, 1 },
+ { ISD::UMIN, MVT::v8i64, 1 },
+ { ISD::UMIN, MVT::v16i32, 1 },
+ { ISD::UMIN, MVT::v32i16, 2 }, // FIXME: include split
+ { ISD::UMIN, MVT::v64i8, 2 }, // FIXME: include split
+ { ISD::UMIN, MVT::v4i64, 1 },
+ { ISD::UMIN, MVT::v2i64, 1 },
{ ISD::USUBSAT, MVT::v16i32, 2 }, // pmaxud + psubd
{ ISD::USUBSAT, MVT::v2i64, 2 }, // pmaxuq + psubq
{ ISD::USUBSAT, MVT::v4i64, 2 }, // pmaxuq + psubq
@@ -2428,10 +2428,10 @@ int X86TTIImpl::getTypeBasedIntrinsicInstrCost(
{ ISD::BITREVERSE, MVT::i8, 3 }
};
static const CostTblEntry AVX2CostTbl[] = {
- { ISD::ABS, MVT::v4i64, 2 }, // VBLENDVPD(X,VPSUBQ(0,X),X)
- { ISD::ABS, MVT::v8i32, 1 },
- { ISD::ABS, MVT::v16i16, 1 },
- { ISD::ABS, MVT::v32i8, 1 },
+ { ISD::ABS, MVT::v4i64, 2 }, // VBLENDVPD(X,VPSUBQ(0,X),X)
+ { ISD::ABS, MVT::v8i32, 1 },
+ { ISD::ABS, MVT::v16i16, 1 },
+ { ISD::ABS, MVT::v32i8, 1 },
{ ISD::BITREVERSE, MVT::v4i64, 5 },
{ ISD::BITREVERSE, MVT::v8i32, 5 },
{ ISD::BITREVERSE, MVT::v16i16, 5 },
@@ -2453,28 +2453,28 @@ int X86TTIImpl::getTypeBasedIntrinsicInstrCost(
{ ISD::CTTZ, MVT::v32i8, 9 },
{ ISD::SADDSAT, MVT::v16i16, 1 },
{ ISD::SADDSAT, MVT::v32i8, 1 },
- { ISD::SMAX, MVT::v8i32, 1 },
- { ISD::SMAX, MVT::v16i16, 1 },
- { ISD::SMAX, MVT::v32i8, 1 },
- { ISD::SMIN, MVT::v8i32, 1 },
- { ISD::SMIN, MVT::v16i16, 1 },
- { ISD::SMIN, MVT::v32i8, 1 },
+ { ISD::SMAX, MVT::v8i32, 1 },
+ { ISD::SMAX, MVT::v16i16, 1 },
+ { ISD::SMAX, MVT::v32i8, 1 },
+ { ISD::SMIN, MVT::v8i32, 1 },
+ { ISD::SMIN, MVT::v16i16, 1 },
+ { ISD::SMIN, MVT::v32i8, 1 },
{ ISD::SSUBSAT, MVT::v16i16, 1 },
{ ISD::SSUBSAT, MVT::v32i8, 1 },
{ ISD::UADDSAT, MVT::v16i16, 1 },
{ ISD::UADDSAT, MVT::v32i8, 1 },
{ ISD::UADDSAT, MVT::v8i32, 3 }, // not + pminud + paddd
- { ISD::UMAX, MVT::v8i32, 1 },
- { ISD::UMAX, MVT::v16i16, 1 },
- { ISD::UMAX, MVT::v32i8, 1 },
- { ISD::UMIN, MVT::v8i32, 1 },
- { ISD::UMIN, MVT::v16i16, 1 },
- { ISD::UMIN, MVT::v32i8, 1 },
+ { ISD::UMAX, MVT::v8i32, 1 },
+ { ISD::UMAX, MVT::v16i16, 1 },
+ { ISD::UMAX, MVT::v32i8, 1 },
+ { ISD::UMIN, MVT::v8i32, 1 },
+ { ISD::UMIN, MVT::v16i16, 1 },
+ { ISD::UMIN, MVT::v32i8, 1 },
{ ISD::USUBSAT, MVT::v16i16, 1 },
{ ISD::USUBSAT, MVT::v32i8, 1 },
{ ISD::USUBSAT, MVT::v8i32, 2 }, // pmaxud + psubd
- { ISD::FMAXNUM, MVT::v8f32, 3 }, // MAXPS + CMPUNORDPS + BLENDVPS
- { ISD::FMAXNUM, MVT::v4f64, 3 }, // MAXPD + CMPUNORDPD + BLENDVPD
+ { ISD::FMAXNUM, MVT::v8f32, 3 }, // MAXPS + CMPUNORDPS + BLENDVPS
+ { ISD::FMAXNUM, MVT::v4f64, 3 }, // MAXPD + CMPUNORDPD + BLENDVPD
{ ISD::FSQRT, MVT::f32, 7 }, // Haswell from http://www.agner.org/
{ ISD::FSQRT, MVT::v4f32, 7 }, // Haswell from http://www.agner.org/
{ ISD::FSQRT, MVT::v8f32, 14 }, // Haswell from http://www.agner.org/
@@ -2483,10 +2483,10 @@ int X86TTIImpl::getTypeBasedIntrinsicInstrCost(
{ ISD::FSQRT, MVT::v4f64, 28 }, // Haswell from http://www.agner.org/
};
static const CostTblEntry AVX1CostTbl[] = {
- { ISD::ABS, MVT::v4i64, 5 }, // VBLENDVPD(X,VPSUBQ(0,X),X)
- { ISD::ABS, MVT::v8i32, 3 },
- { ISD::ABS, MVT::v16i16, 3 },
- { ISD::ABS, MVT::v32i8, 3 },
+ { ISD::ABS, MVT::v4i64, 5 }, // VBLENDVPD(X,VPSUBQ(0,X),X)
+ { ISD::ABS, MVT::v8i32, 3 },
+ { ISD::ABS, MVT::v16i16, 3 },
+ { ISD::ABS, MVT::v32i8, 3 },
{ ISD::BITREVERSE, MVT::v4i64, 12 }, // 2 x 128-bit Op + extract/insert
{ ISD::BITREVERSE, MVT::v8i32, 12 }, // 2 x 128-bit Op + extract/insert
{ ISD::BITREVERSE, MVT::v16i16, 12 }, // 2 x 128-bit Op + extract/insert
@@ -2508,32 +2508,32 @@ int X86TTIImpl::getTypeBasedIntrinsicInstrCost(
{ ISD::CTTZ, MVT::v32i8, 20 }, // 2 x 128-bit Op + extract/insert
{ ISD::SADDSAT, MVT::v16i16, 4 }, // 2 x 128-bit Op + extract/insert
{ ISD::SADDSAT, MVT::v32i8, 4 }, // 2 x 128-bit Op + extract/insert
- { ISD::SMAX, MVT::v8i32, 4 }, // 2 x 128-bit Op + extract/insert
- { ISD::SMAX, MVT::v16i16, 4 }, // 2 x 128-bit Op + extract/insert
- { ISD::SMAX, MVT::v32i8, 4 }, // 2 x 128-bit Op + extract/insert
- { ISD::SMIN, MVT::v8i32, 4 }, // 2 x 128-bit Op + extract/insert
- { ISD::SMIN, MVT::v16i16, 4 }, // 2 x 128-bit Op + extract/insert
- { ISD::SMIN, MVT::v32i8, 4 }, // 2 x 128-bit Op + extract/insert
+ { ISD::SMAX, MVT::v8i32, 4 }, // 2 x 128-bit Op + extract/insert
+ { ISD::SMAX, MVT::v16i16, 4 }, // 2 x 128-bit Op + extract/insert
+ { ISD::SMAX, MVT::v32i8, 4 }, // 2 x 128-bit Op + extract/insert
+ { ISD::SMIN, MVT::v8i32, 4 }, // 2 x 128-bit Op + extract/insert
+ { ISD::SMIN, MVT::v16i16, 4 }, // 2 x 128-bit Op + extract/insert
+ { ISD::SMIN, MVT::v32i8, 4 }, // 2 x 128-bit Op + extract/insert
{ ISD::SSUBSAT, MVT::v16i16, 4 }, // 2 x 128-bit Op + extract/insert
{ ISD::SSUBSAT, MVT::v32i8, 4 }, // 2 x 128-bit Op + extract/insert
{ ISD::UADDSAT, MVT::v16i16, 4 }, // 2 x 128-bit Op + extract/insert
{ ISD::UADDSAT, MVT::v32i8, 4 }, // 2 x 128-bit Op + extract/insert
{ ISD::UADDSAT, MVT::v8i32, 8 }, // 2 x 128-bit Op + extract/insert
- { ISD::UMAX, MVT::v8i32, 4 }, // 2 x 128-bit Op + extract/insert
- { ISD::UMAX, MVT::v16i16, 4 }, // 2 x 128-bit Op + extract/insert
- { ISD::UMAX, MVT::v32i8, 4 }, // 2 x 128-bit Op + extract/insert
- { ISD::UMIN, MVT::v8i32, 4 }, // 2 x 128-bit Op + extract/insert
- { ISD::UMIN, MVT::v16i16, 4 }, // 2 x 128-bit Op + extract/insert
- { ISD::UMIN, MVT::v32i8, 4 }, // 2 x 128-bit Op + extract/insert
+ { ISD::UMAX, MVT::v8i32, 4 }, // 2 x 128-bit Op + extract/insert
+ { ISD::UMAX, MVT::v16i16, 4 }, // 2 x 128-bit Op + extract/insert
+ { ISD::UMAX, MVT::v32i8, 4 }, // 2 x 128-bit Op + extract/insert
+ { ISD::UMIN, MVT::v8i32, 4 }, // 2 x 128-bit Op + extract/insert
+ { ISD::UMIN, MVT::v16i16, 4 }, // 2 x 128-bit Op + extract/insert
+ { ISD::UMIN, MVT::v32i8, 4 }, // 2 x 128-bit Op + extract/insert
{ ISD::USUBSAT, MVT::v16i16, 4 }, // 2 x 128-bit Op + extract/insert
{ ISD::USUBSAT, MVT::v32i8, 4 }, // 2 x 128-bit Op + extract/insert
{ ISD::USUBSAT, MVT::v8i32, 6 }, // 2 x 128-bit Op + extract/insert
- { ISD::FMAXNUM, MVT::f32, 3 }, // MAXSS + CMPUNORDSS + BLENDVPS
- { ISD::FMAXNUM, MVT::v4f32, 3 }, // MAXPS + CMPUNORDPS + BLENDVPS
- { ISD::FMAXNUM, MVT::v8f32, 5 }, // MAXPS + CMPUNORDPS + BLENDVPS + ?
- { ISD::FMAXNUM, MVT::f64, 3 }, // MAXSD + CMPUNORDSD + BLENDVPD
- { ISD::FMAXNUM, MVT::v2f64, 3 }, // MAXPD + CMPUNORDPD + BLENDVPD
- { ISD::FMAXNUM, MVT::v4f64, 5 }, // MAXPD + CMPUNORDPD + BLENDVPD + ?
+ { ISD::FMAXNUM, MVT::f32, 3 }, // MAXSS + CMPUNORDSS + BLENDVPS
+ { ISD::FMAXNUM, MVT::v4f32, 3 }, // MAXPS + CMPUNORDPS + BLENDVPS
+ { ISD::FMAXNUM, MVT::v8f32, 5 }, // MAXPS + CMPUNORDPS + BLENDVPS + ?
+ { ISD::FMAXNUM, MVT::f64, 3 }, // MAXSD + CMPUNORDSD + BLENDVPD
+ { ISD::FMAXNUM, MVT::v2f64, 3 }, // MAXPD + CMPUNORDPD + BLENDVPD
+ { ISD::FMAXNUM, MVT::v4f64, 5 }, // MAXPD + CMPUNORDPD + BLENDVPD + ?
{ ISD::FSQRT, MVT::f32, 14 }, // SNB from http://www.agner.org/
{ ISD::FSQRT, MVT::v4f32, 14 }, // SNB from http://www.agner.org/
{ ISD::FSQRT, MVT::v8f32, 28 }, // SNB from http://www.agner.org/
@@ -2559,21 +2559,21 @@ int X86TTIImpl::getTypeBasedIntrinsicInstrCost(
{ ISD::FSQRT, MVT::f32, 18 }, // Nehalem from http://www.agner.org/
{ ISD::FSQRT, MVT::v4f32, 18 }, // Nehalem from http://www.agner.org/
};
- static const CostTblEntry SSE41CostTbl[] = {
- { ISD::ABS, MVT::v2i64, 2 }, // BLENDVPD(X,PSUBQ(0,X),X)
- { ISD::SMAX, MVT::v4i32, 1 },
- { ISD::SMAX, MVT::v16i8, 1 },
- { ISD::SMIN, MVT::v4i32, 1 },
- { ISD::SMIN, MVT::v16i8, 1 },
- { ISD::UMAX, MVT::v4i32, 1 },
- { ISD::UMAX, MVT::v8i16, 1 },
- { ISD::UMIN, MVT::v4i32, 1 },
- { ISD::UMIN, MVT::v8i16, 1 },
- };
+ static const CostTblEntry SSE41CostTbl[] = {
+ { ISD::ABS, MVT::v2i64, 2 }, // BLENDVPD(X,PSUBQ(0,X),X)
+ { ISD::SMAX, MVT::v4i32, 1 },
+ { ISD::SMAX, MVT::v16i8, 1 },
+ { ISD::SMIN, MVT::v4i32, 1 },
+ { ISD::SMIN, MVT::v16i8, 1 },
+ { ISD::UMAX, MVT::v4i32, 1 },
+ { ISD::UMAX, MVT::v8i16, 1 },
+ { ISD::UMIN, MVT::v4i32, 1 },
+ { ISD::UMIN, MVT::v8i16, 1 },
+ };
static const CostTblEntry SSSE3CostTbl[] = {
- { ISD::ABS, MVT::v4i32, 1 },
- { ISD::ABS, MVT::v8i16, 1 },
- { ISD::ABS, MVT::v16i8, 1 },
+ { ISD::ABS, MVT::v4i32, 1 },
+ { ISD::ABS, MVT::v8i16, 1 },
+ { ISD::ABS, MVT::v16i8, 1 },
{ ISD::BITREVERSE, MVT::v2i64, 5 },
{ ISD::BITREVERSE, MVT::v4i32, 5 },
{ ISD::BITREVERSE, MVT::v8i16, 5 },
@@ -2595,10 +2595,10 @@ int X86TTIImpl::getTypeBasedIntrinsicInstrCost(
{ ISD::CTTZ, MVT::v16i8, 9 }
};
static const CostTblEntry SSE2CostTbl[] = {
- { ISD::ABS, MVT::v2i64, 4 },
- { ISD::ABS, MVT::v4i32, 3 },
- { ISD::ABS, MVT::v8i16, 2 },
- { ISD::ABS, MVT::v16i8, 2 },
+ { ISD::ABS, MVT::v2i64, 4 },
+ { ISD::ABS, MVT::v4i32, 3 },
+ { ISD::ABS, MVT::v8i16, 2 },
+ { ISD::ABS, MVT::v16i8, 2 },
{ ISD::BITREVERSE, MVT::v2i64, 29 },
{ ISD::BITREVERSE, MVT::v4i32, 27 },
{ ISD::BITREVERSE, MVT::v8i16, 27 },
@@ -2620,16 +2620,16 @@ int X86TTIImpl::getTypeBasedIntrinsicInstrCost(
{ ISD::CTTZ, MVT::v16i8, 13 },
{ ISD::SADDSAT, MVT::v8i16, 1 },
{ ISD::SADDSAT, MVT::v16i8, 1 },
- { ISD::SMAX, MVT::v8i16, 1 },
- { ISD::SMIN, MVT::v8i16, 1 },
+ { ISD::SMAX, MVT::v8i16, 1 },
+ { ISD::SMIN, MVT::v8i16, 1 },
{ ISD::SSUBSAT, MVT::v8i16, 1 },
{ ISD::SSUBSAT, MVT::v16i8, 1 },
{ ISD::UADDSAT, MVT::v8i16, 1 },
{ ISD::UADDSAT, MVT::v16i8, 1 },
- { ISD::UMAX, MVT::v8i16, 2 },
- { ISD::UMAX, MVT::v16i8, 1 },
- { ISD::UMIN, MVT::v8i16, 2 },
- { ISD::UMIN, MVT::v16i8, 1 },
+ { ISD::UMAX, MVT::v8i16, 2 },
+ { ISD::UMAX, MVT::v16i8, 1 },
+ { ISD::UMIN, MVT::v8i16, 2 },
+ { ISD::UMIN, MVT::v16i8, 1 },
{ ISD::USUBSAT, MVT::v8i16, 1 },
{ ISD::USUBSAT, MVT::v16i8, 1 },
{ ISD::FMAXNUM, MVT::f64, 4 },
@@ -2668,18 +2668,18 @@ int X86TTIImpl::getTypeBasedIntrinsicInstrCost(
{ ISD::CTPOP, MVT::i8, 1 },
};
static const CostTblEntry X64CostTbl[] = { // 64-bit targets
- { ISD::ABS, MVT::i64, 2 }, // SUB+CMOV
+ { ISD::ABS, MVT::i64, 2 }, // SUB+CMOV
{ ISD::BITREVERSE, MVT::i64, 14 },
{ ISD::CTLZ, MVT::i64, 4 }, // BSR+XOR or BSR+XOR+CMOV
{ ISD::CTTZ, MVT::i64, 3 }, // TEST+BSF+CMOV/BRANCH
{ ISD::CTPOP, MVT::i64, 10 },
{ ISD::SADDO, MVT::i64, 1 },
{ ISD::UADDO, MVT::i64, 1 },
- { ISD::UMULO, MVT::i64, 2 }, // mulq + seto
+ { ISD::UMULO, MVT::i64, 2 }, // mulq + seto
};
static const CostTblEntry X86CostTbl[] = { // 32 or 64-bit targets
- { ISD::ABS, MVT::i32, 2 }, // SUB+CMOV
- { ISD::ABS, MVT::i16, 2 }, // SUB+CMOV
+ { ISD::ABS, MVT::i32, 2 }, // SUB+CMOV
+ { ISD::ABS, MVT::i16, 2 }, // SUB+CMOV
{ ISD::BITREVERSE, MVT::i32, 14 },
{ ISD::BITREVERSE, MVT::i16, 14 },
{ ISD::BITREVERSE, MVT::i8, 11 },
@@ -2698,9 +2698,9 @@ int X86TTIImpl::getTypeBasedIntrinsicInstrCost(
{ ISD::UADDO, MVT::i32, 1 },
{ ISD::UADDO, MVT::i16, 1 },
{ ISD::UADDO, MVT::i8, 1 },
- { ISD::UMULO, MVT::i32, 2 }, // mul + seto
- { ISD::UMULO, MVT::i16, 2 },
- { ISD::UMULO, MVT::i8, 2 },
+ { ISD::UMULO, MVT::i32, 2 }, // mul + seto
+ { ISD::UMULO, MVT::i16, 2 },
+ { ISD::UMULO, MVT::i8, 2 },
};
Type *RetTy = ICA.getReturnType();
@@ -2710,9 +2710,9 @@ int X86TTIImpl::getTypeBasedIntrinsicInstrCost(
switch (IID) {
default:
break;
- case Intrinsic::abs:
- ISD = ISD::ABS;
- break;
+ case Intrinsic::abs:
+ ISD = ISD::ABS;
+ break;
case Intrinsic::bitreverse:
ISD = ISD::BITREVERSE;
break;
@@ -2736,24 +2736,24 @@ int X86TTIImpl::getTypeBasedIntrinsicInstrCost(
case Intrinsic::sadd_sat:
ISD = ISD::SADDSAT;
break;
- case Intrinsic::smax:
- ISD = ISD::SMAX;
- break;
- case Intrinsic::smin:
- ISD = ISD::SMIN;
- break;
+ case Intrinsic::smax:
+ ISD = ISD::SMAX;
+ break;
+ case Intrinsic::smin:
+ ISD = ISD::SMIN;
+ break;
case Intrinsic::ssub_sat:
ISD = ISD::SSUBSAT;
break;
case Intrinsic::uadd_sat:
ISD = ISD::UADDSAT;
break;
- case Intrinsic::umax:
- ISD = ISD::UMAX;
- break;
- case Intrinsic::umin:
- ISD = ISD::UMIN;
- break;
+ case Intrinsic::umax:
+ ISD = ISD::UMAX;
+ break;
+ case Intrinsic::umin:
+ ISD = ISD::UMIN;
+ break;
case Intrinsic::usub_sat:
ISD = ISD::USUBSAT;
break;
@@ -2772,12 +2772,12 @@ int X86TTIImpl::getTypeBasedIntrinsicInstrCost(
ISD = ISD::UADDO;
OpTy = RetTy->getContainedType(0);
break;
- case Intrinsic::umul_with_overflow:
- case Intrinsic::smul_with_overflow:
- // SMULO has same costs so don't duplicate.
- ISD = ISD::UMULO;
- OpTy = RetTy->getContainedType(0);
- break;
+ case Intrinsic::umul_with_overflow:
+ case Intrinsic::smul_with_overflow:
+ // SMULO has same costs so don't duplicate.
+ ISD = ISD::UMULO;
+ OpTy = RetTy->getContainedType(0);
+ break;
}
if (ISD != ISD::DELETED_NODE) {
@@ -2786,121 +2786,121 @@ int X86TTIImpl::getTypeBasedIntrinsicInstrCost(
MVT MTy = LT.second;
// Attempt to lookup cost.
- if (ISD == ISD::BITREVERSE && ST->hasGFNI() && ST->hasSSSE3() &&
- MTy.isVector()) {
- // With PSHUFB the code is very similar for all types. If we have integer
- // byte operations, we just need a GF2P8AFFINEQB for vXi8. For other types
- // we also need a PSHUFB.
- unsigned Cost = MTy.getVectorElementType() == MVT::i8 ? 1 : 2;
-
- // Without byte operations, we need twice as many GF2P8AFFINEQB and PSHUFB
- // instructions. We also need an extract and an insert.
- if (!(MTy.is128BitVector() || (ST->hasAVX2() && MTy.is256BitVector()) ||
- (ST->hasBWI() && MTy.is512BitVector())))
- Cost = Cost * 2 + 2;
-
- return LT.first * Cost;
- }
-
- auto adjustTableCost = [](const CostTblEntry &Entry, int LegalizationCost,
- FastMathFlags FMF) {
- // If there are no NANs to deal with, then these are reduced to a
- // single MIN** or MAX** instruction instead of the MIN/CMP/SELECT that we
- // assume is used in the non-fast case.
- if (Entry.ISD == ISD::FMAXNUM || Entry.ISD == ISD::FMINNUM) {
- if (FMF.noNaNs())
- return LegalizationCost * 1;
- }
- return LegalizationCost * (int)Entry.Cost;
- };
-
+ if (ISD == ISD::BITREVERSE && ST->hasGFNI() && ST->hasSSSE3() &&
+ MTy.isVector()) {
+ // With PSHUFB the code is very similar for all types. If we have integer
+ // byte operations, we just need a GF2P8AFFINEQB for vXi8. For other types
+ // we also need a PSHUFB.
+ unsigned Cost = MTy.getVectorElementType() == MVT::i8 ? 1 : 2;
+
+ // Without byte operations, we need twice as many GF2P8AFFINEQB and PSHUFB
+ // instructions. We also need an extract and an insert.
+ if (!(MTy.is128BitVector() || (ST->hasAVX2() && MTy.is256BitVector()) ||
+ (ST->hasBWI() && MTy.is512BitVector())))
+ Cost = Cost * 2 + 2;
+
+ return LT.first * Cost;
+ }
+
+ auto adjustTableCost = [](const CostTblEntry &Entry, int LegalizationCost,
+ FastMathFlags FMF) {
+ // If there are no NANs to deal with, then these are reduced to a
+ // single MIN** or MAX** instruction instead of the MIN/CMP/SELECT that we
+ // assume is used in the non-fast case.
+ if (Entry.ISD == ISD::FMAXNUM || Entry.ISD == ISD::FMINNUM) {
+ if (FMF.noNaNs())
+ return LegalizationCost * 1;
+ }
+ return LegalizationCost * (int)Entry.Cost;
+ };
+
if (ST->useGLMDivSqrtCosts())
if (const auto *Entry = CostTableLookup(GLMCostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
if (ST->isSLM())
if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
if (ST->hasCDI())
if (const auto *Entry = CostTableLookup(AVX512CDCostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
if (ST->hasBWI())
if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
if (ST->hasAVX512())
if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
if (ST->hasXOP())
if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
if (ST->hasAVX2())
if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
if (ST->hasAVX())
if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
if (ST->hasSSE42())
if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+
+ if (ST->hasSSE41())
+ if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
- if (ST->hasSSE41())
- if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
-
if (ST->hasSSSE3())
if (const auto *Entry = CostTableLookup(SSSE3CostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
if (ST->hasSSE2())
if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
if (ST->hasSSE1())
if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
if (ST->hasBMI()) {
if (ST->is64Bit())
if (const auto *Entry = CostTableLookup(BMI64CostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
if (const auto *Entry = CostTableLookup(BMI32CostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
}
if (ST->hasLZCNT()) {
if (ST->is64Bit())
if (const auto *Entry = CostTableLookup(LZCNT64CostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
if (const auto *Entry = CostTableLookup(LZCNT32CostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
}
if (ST->hasPOPCNT()) {
if (ST->is64Bit())
if (const auto *Entry = CostTableLookup(POPCNT64CostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
if (const auto *Entry = CostTableLookup(POPCNT32CostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
}
// TODO - add BMI (TZCNT) scalar handling
if (ST->is64Bit())
if (const auto *Entry = CostTableLookup(X64CostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
if (const auto *Entry = CostTableLookup(X86CostTbl, ISD, MTy))
- return adjustTableCost(*Entry, LT.first, ICA.getFlags());
+ return adjustTableCost(*Entry, LT.first, ICA.getFlags());
}
return BaseT::getIntrinsicInstrCost(ICA, CostKind);
@@ -3119,32 +3119,32 @@ unsigned X86TTIImpl::getScalarizationOverhead(VectorType *Ty,
Cost +=
BaseT::getScalarizationOverhead(Ty, DemandedElts, Insert, false);
} else {
- // In each 128-lane, if at least one index is demanded but not all
- // indices are demanded and this 128-lane is not the first 128-lane of
- // the legalized-vector, then this 128-lane needs a extracti128; If in
- // each 128-lane, there is at least one demanded index, this 128-lane
- // needs a inserti128.
-
- // The following cases will help you build a better understanding:
- // Assume we insert several elements into a v8i32 vector in avx2,
- // Case#1: inserting into 1th index needs vpinsrd + inserti128.
- // Case#2: inserting into 5th index needs extracti128 + vpinsrd +
- // inserti128.
- // Case#3: inserting into 4,5,6,7 index needs 4*vpinsrd + inserti128.
- unsigned Num128Lanes = LT.second.getSizeInBits() / 128 * LT.first;
- unsigned NumElts = LT.second.getVectorNumElements() * LT.first;
- APInt WidenedDemandedElts = DemandedElts.zextOrSelf(NumElts);
- unsigned Scale = NumElts / Num128Lanes;
- // We iterate each 128-lane, and check if we need a
- // extracti128/inserti128 for this 128-lane.
- for (unsigned I = 0; I < NumElts; I += Scale) {
- APInt Mask = WidenedDemandedElts.getBitsSet(NumElts, I, I + Scale);
- APInt MaskedDE = Mask & WidenedDemandedElts;
- unsigned Population = MaskedDE.countPopulation();
- Cost += (Population > 0 && Population != Scale &&
- I % LT.second.getVectorNumElements() != 0);
- Cost += Population > 0;
- }
+ // In each 128-lane, if at least one index is demanded but not all
+ // indices are demanded and this 128-lane is not the first 128-lane of
+ // the legalized-vector, then this 128-lane needs a extracti128; If in
+ // each 128-lane, there is at least one demanded index, this 128-lane
+ // needs a inserti128.
+
+ // The following cases will help you build a better understanding:
+ // Assume we insert several elements into a v8i32 vector in avx2,
+ // Case#1: inserting into 1th index needs vpinsrd + inserti128.
+ // Case#2: inserting into 5th index needs extracti128 + vpinsrd +
+ // inserti128.
+ // Case#3: inserting into 4,5,6,7 index needs 4*vpinsrd + inserti128.
+ unsigned Num128Lanes = LT.second.getSizeInBits() / 128 * LT.first;
+ unsigned NumElts = LT.second.getVectorNumElements() * LT.first;
+ APInt WidenedDemandedElts = DemandedElts.zextOrSelf(NumElts);
+ unsigned Scale = NumElts / Num128Lanes;
+ // We iterate each 128-lane, and check if we need a
+ // extracti128/inserti128 for this 128-lane.
+ for (unsigned I = 0; I < NumElts; I += Scale) {
+ APInt Mask = WidenedDemandedElts.getBitsSet(NumElts, I, I + Scale);
+ APInt MaskedDE = Mask & WidenedDemandedElts;
+ unsigned Population = MaskedDE.countPopulation();
+ Cost += (Population > 0 && Population != Scale &&
+ I % LT.second.getVectorNumElements() != 0);
+ Cost += Population > 0;
+ }
Cost += DemandedElts.countPopulation();
// For vXf32 cases, insertion into the 0'th index in each v4f32
@@ -3188,10 +3188,10 @@ int X86TTIImpl::getMemoryOpCost(unsigned Opcode, Type *Src,
const Instruction *I) {
// TODO: Handle other cost kinds.
if (CostKind != TTI::TCK_RecipThroughput) {
- if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
+ if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
// Store instruction with index and scale costs 2 Uops.
// Check the preceding GEP to identify non-const indices.
- if (auto *GEP = dyn_cast<GetElementPtrInst>(SI->getPointerOperand())) {
+ if (auto *GEP = dyn_cast<GetElementPtrInst>(SI->getPointerOperand())) {
if (!all_of(GEP->indices(), [](Value *V) { return isa<Constant>(V); }))
return TTI::TCC_Basic * 2;
}
@@ -3270,7 +3270,7 @@ int X86TTIImpl::getMaskedMemoryOpCost(unsigned Opcode, Type *SrcTy,
getScalarizationOverhead(MaskTy, DemandedElts, false, true);
int ScalarCompareCost = getCmpSelInstrCost(
Instruction::ICmp, Type::getInt8Ty(SrcVTy->getContext()), nullptr,
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
int BranchCost = getCFInstrCost(Instruction::Br, CostKind);
int MaskCmpCost = NumElem * (BranchCost + ScalarCompareCost);
int ValueSplitCost =
@@ -3691,10 +3691,10 @@ int X86TTIImpl::getMinMaxCost(Type *Ty, Type *CondTy, bool IsUnsigned) {
TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput;
// Otherwise fall back to cmp+select.
- return getCmpSelInstrCost(CmpOpcode, Ty, CondTy, CmpInst::BAD_ICMP_PREDICATE,
- CostKind) +
- getCmpSelInstrCost(Instruction::Select, Ty, CondTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ return getCmpSelInstrCost(CmpOpcode, Ty, CondTy, CmpInst::BAD_ICMP_PREDICATE,
+ CostKind) +
+ getCmpSelInstrCost(Instruction::Select, Ty, CondTy,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
}
int X86TTIImpl::getMinMaxReductionCost(VectorType *ValTy, VectorType *CondTy,
@@ -3923,10 +3923,10 @@ int X86TTIImpl::getIntImmCost(const APInt &Imm, Type *Ty,
return std::max(1, Cost);
}
-int X86TTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx,
- const APInt &Imm, Type *Ty,
- TTI::TargetCostKind CostKind,
- Instruction *Inst) {
+int X86TTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx,
+ const APInt &Imm, Type *Ty,
+ TTI::TargetCostKind CostKind,
+ Instruction *Inst) {
assert(Ty->isIntegerTy());
unsigned BitSize = Ty->getPrimitiveSizeInBits();
@@ -4066,28 +4066,28 @@ X86TTIImpl::getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind) {
return CostKind == TTI::TCK_RecipThroughput ? 0 : 1;
}
-int X86TTIImpl::getGatherOverhead() const {
- // Some CPUs have more overhead for gather. The specified overhead is relative
- // to the Load operation. "2" is the number provided by Intel architects. This
- // parameter is used for cost estimation of Gather Op and comparison with
- // other alternatives.
- // TODO: Remove the explicit hasAVX512()?, That would mean we would only
- // enable gather with a -march.
- if (ST->hasAVX512() || (ST->hasAVX2() && ST->hasFastGather()))
- return 2;
-
- return 1024;
-}
-
-int X86TTIImpl::getScatterOverhead() const {
- if (ST->hasAVX512())
- return 2;
-
- return 1024;
-}
-
-// Return an average cost of Gather / Scatter instruction, maybe improved later.
-// FIXME: Add TargetCostKind support.
+int X86TTIImpl::getGatherOverhead() const {
+ // Some CPUs have more overhead for gather. The specified overhead is relative
+ // to the Load operation. "2" is the number provided by Intel architects. This
+ // parameter is used for cost estimation of Gather Op and comparison with
+ // other alternatives.
+ // TODO: Remove the explicit hasAVX512()?, That would mean we would only
+ // enable gather with a -march.
+ if (ST->hasAVX512() || (ST->hasAVX2() && ST->hasFastGather()))
+ return 2;
+
+ return 1024;
+}
+
+int X86TTIImpl::getScatterOverhead() const {
+ if (ST->hasAVX512())
+ return 2;
+
+ return 1024;
+}
+
+// Return an average cost of Gather / Scatter instruction, maybe improved later.
+// FIXME: Add TargetCostKind support.
int X86TTIImpl::getGSVectorCost(unsigned Opcode, Type *SrcVTy, const Value *Ptr,
Align Alignment, unsigned AddressSpace) {
@@ -4145,8 +4145,8 @@ int X86TTIImpl::getGSVectorCost(unsigned Opcode, Type *SrcVTy, const Value *Ptr,
// The gather / scatter cost is given by Intel architects. It is a rough
// number since we are looking at one instruction in a time.
const int GSOverhead = (Opcode == Instruction::Load)
- ? getGatherOverhead()
- : getScatterOverhead();
+ ? getGatherOverhead()
+ : getScatterOverhead();
return GSOverhead + VF * getMemoryOpCost(Opcode, SrcVTy->getScalarType(),
MaybeAlign(Alignment), AddressSpace,
TTI::TCK_RecipThroughput);
@@ -4160,7 +4160,7 @@ int X86TTIImpl::getGSVectorCost(unsigned Opcode, Type *SrcVTy, const Value *Ptr,
/// Alignment - Alignment for one element.
/// AddressSpace - pointer[s] address space.
///
-/// FIXME: Add TargetCostKind support.
+/// FIXME: Add TargetCostKind support.
int X86TTIImpl::getGSScalarCost(unsigned Opcode, Type *SrcVTy,
bool VariableMask, Align Alignment,
unsigned AddressSpace) {
@@ -4174,9 +4174,9 @@ int X86TTIImpl::getGSScalarCost(unsigned Opcode, Type *SrcVTy,
FixedVectorType::get(Type::getInt1Ty(SrcVTy->getContext()), VF);
MaskUnpackCost =
getScalarizationOverhead(MaskTy, DemandedElts, false, true);
- int ScalarCompareCost = getCmpSelInstrCost(
- Instruction::ICmp, Type::getInt1Ty(SrcVTy->getContext()), nullptr,
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ int ScalarCompareCost = getCmpSelInstrCost(
+ Instruction::ICmp, Type::getInt1Ty(SrcVTy->getContext()), nullptr,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
int BranchCost = getCFInstrCost(Instruction::Br, CostKind);
MaskUnpackCost += VF * (BranchCost + ScalarCompareCost);
}
@@ -4207,15 +4207,15 @@ int X86TTIImpl::getGatherScatterOpCost(unsigned Opcode, Type *SrcVTy,
Align Alignment,
TTI::TargetCostKind CostKind,
const Instruction *I = nullptr) {
- if (CostKind != TTI::TCK_RecipThroughput) {
- if ((Opcode == Instruction::Load &&
- isLegalMaskedGather(SrcVTy, Align(Alignment))) ||
- (Opcode == Instruction::Store &&
- isLegalMaskedScatter(SrcVTy, Align(Alignment))))
- return 1;
- return BaseT::getGatherScatterOpCost(Opcode, SrcVTy, Ptr, VariableMask,
- Alignment, CostKind, I);
- }
+ if (CostKind != TTI::TCK_RecipThroughput) {
+ if ((Opcode == Instruction::Load &&
+ isLegalMaskedGather(SrcVTy, Align(Alignment))) ||
+ (Opcode == Instruction::Store &&
+ isLegalMaskedScatter(SrcVTy, Align(Alignment))))
+ return 1;
+ return BaseT::getGatherScatterOpCost(Opcode, SrcVTy, Ptr, VariableMask,
+ Alignment, CostKind, I);
+ }
assert(SrcVTy->isVectorTy() && "Unexpected data type for Gather/Scatter");
unsigned VF = cast<FixedVectorType>(SrcVTy)->getNumElements();
@@ -4375,7 +4375,7 @@ bool X86TTIImpl::isLegalMaskedGather(Type *DataTy, Align Alignment) {
// scalarize it.
if (auto *DataVTy = dyn_cast<FixedVectorType>(DataTy)) {
unsigned NumElts = DataVTy->getNumElements();
- if (NumElts == 1)
+ if (NumElts == 1)
return false;
}
Type *ScalarTy = DataTy->getScalarType();
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86TargetTransformInfo.h b/contrib/libs/llvm12/lib/Target/X86/X86TargetTransformInfo.h
index 3ebfef5d65..17570f1c04 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86TargetTransformInfo.h
+++ b/contrib/libs/llvm12/lib/Target/X86/X86TargetTransformInfo.h
@@ -22,8 +22,8 @@
namespace llvm {
-class InstCombiner;
-
+class InstCombiner;
+
class X86TTIImpl : public BasicTTIImplBase<X86TTIImpl> {
typedef BasicTTIImplBase<X86TTIImpl> BaseT;
typedef TargetTransformInfo TTI;
@@ -130,10 +130,10 @@ public:
int getShuffleCost(TTI::ShuffleKind Kind, VectorType *Tp, int Index,
VectorType *SubTp);
int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
- TTI::CastContextHint CCH, TTI::TargetCostKind CostKind,
+ TTI::CastContextHint CCH, TTI::TargetCostKind CostKind,
const Instruction *I = nullptr);
int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
- CmpInst::Predicate VecPred,
+ CmpInst::Predicate VecPred,
TTI::TargetCostKind CostKind,
const Instruction *I = nullptr);
int getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index);
@@ -153,18 +153,18 @@ public:
int getAddressComputationCost(Type *PtrTy, ScalarEvolution *SE,
const SCEV *Ptr);
- Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
- IntrinsicInst &II) const;
- Optional<Value *>
- simplifyDemandedUseBitsIntrinsic(InstCombiner &IC, IntrinsicInst &II,
- APInt DemandedMask, KnownBits &Known,
- bool &KnownBitsComputed) const;
- Optional<Value *> simplifyDemandedVectorEltsIntrinsic(
- InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
- APInt &UndefElts2, APInt &UndefElts3,
- std::function<void(Instruction *, unsigned, APInt, APInt &)>
- SimplifyAndSetOp) const;
-
+ Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
+ IntrinsicInst &II) const;
+ Optional<Value *>
+ simplifyDemandedUseBitsIntrinsic(InstCombiner &IC, IntrinsicInst &II,
+ APInt DemandedMask, KnownBits &Known,
+ bool &KnownBitsComputed) const;
+ Optional<Value *> simplifyDemandedVectorEltsIntrinsic(
+ InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
+ APInt &UndefElts2, APInt &UndefElts3,
+ std::function<void(Instruction *, unsigned, APInt, APInt &)>
+ SimplifyAndSetOp) const;
+
unsigned getAtomicMemIntrinsicMaxElementSize() const;
int getTypeBasedIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
@@ -204,9 +204,9 @@ public:
unsigned getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind);
- int getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm,
- Type *Ty, TTI::TargetCostKind CostKind,
- Instruction *Inst = nullptr);
+ int getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm,
+ Type *Ty, TTI::TargetCostKind CostKind,
+ Instruction *Inst = nullptr);
int getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
Type *Ty, TTI::TargetCostKind CostKind);
bool isLSRCostLess(TargetTransformInfo::LSRCost &C1,
@@ -245,9 +245,9 @@ private:
int getGSVectorCost(unsigned Opcode, Type *DataTy, const Value *Ptr,
Align Alignment, unsigned AddressSpace);
- int getGatherOverhead() const;
- int getScatterOverhead() const;
-
+ int getGatherOverhead() const;
+ int getScatterOverhead() const;
+
/// @}
};
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86TileConfig.cpp b/contrib/libs/llvm12/lib/Target/X86/X86TileConfig.cpp
index 6164a84c73..ef010bcd38 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86TileConfig.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86TileConfig.cpp
@@ -1,248 +1,248 @@
-//===-- X86TileConfig.cpp - Tile Register Configure----------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file Pass to config the shape of AMX physical registers
-/// AMX register need to be configured before use. In X86PreTileConfig pass
-/// the pldtilecfg instruction is inserted, however at that time we don't
-/// know the shape of each physical tile registers, because the register
-/// allocation is not done yet. This pass runs after egister allocation
-/// pass. It collects the shape information of each physical tile register
-/// and store the shape in the stack slot that is allocated for load config
-/// to tile config register.
-//
-//===----------------------------------------------------------------------===//
-
-#include "X86.h"
-#include "X86InstrBuilder.h"
-#include "X86MachineFunctionInfo.h"
-#include "X86RegisterInfo.h"
-#include "X86Subtarget.h"
-#include "llvm/CodeGen/LiveIntervals.h"
-#include "llvm/CodeGen/MachineDominators.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/TargetInstrInfo.h"
-#include "llvm/CodeGen/TargetRegisterInfo.h"
-#include "llvm/CodeGen/TileShapeInfo.h"
-#include "llvm/CodeGen/VirtRegMap.h"
-#include "llvm/InitializePasses.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "tile-config"
-
-namespace {
-
-class X86TileConfig : public MachineFunctionPass {
- // context
- MachineFunction *MF = nullptr;
- const X86Subtarget *ST = nullptr;
- const TargetRegisterInfo *TRI;
- const TargetInstrInfo *TII;
- MachineDominatorTree *DomTree = nullptr;
- MachineRegisterInfo *MRI = nullptr;
- VirtRegMap *VRM = nullptr;
- LiveIntervals *LIS = nullptr;
-
- MachineInstr *getTileConfigPoint();
- void tileConfig();
-
-public:
- X86TileConfig() : MachineFunctionPass(ID) {}
-
- /// Return the pass name.
- StringRef getPassName() const override { return "Tile Register Configure"; }
-
- /// X86TileConfig analysis usage.
- void getAnalysisUsage(AnalysisUsage &AU) const override;
-
- /// Perform register allocation.
- bool runOnMachineFunction(MachineFunction &mf) override;
-
- MachineFunctionProperties getRequiredProperties() const override {
- return MachineFunctionProperties().set(
- MachineFunctionProperties::Property::NoPHIs);
- }
-
- static char ID;
-};
-
-} // end anonymous namespace
-
-char X86TileConfig::ID = 0;
-
-INITIALIZE_PASS_BEGIN(X86TileConfig, "tileconfig", "Tile Register Configure",
- false, false)
-INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
-INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
-INITIALIZE_PASS_END(X86TileConfig, "tileconfig", "Tile Register Configure",
- false, false)
-
-void X86TileConfig::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<MachineDominatorTree>();
- AU.addRequired<LiveIntervals>();
- AU.addPreserved<SlotIndexes>();
- AU.addRequired<VirtRegMap>();
- AU.setPreservesAll();
- MachineFunctionPass::getAnalysisUsage(AU);
-}
-
-static unsigned getTilePhysRegIndex(Register PhysReg) {
- assert((PhysReg >= X86::TMM0 && X86::TMM0 <= X86::TMM7) &&
- "Tile register number is invalid");
- return (PhysReg - X86::TMM0);
-}
-
-static MachineInstr *
-storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
- Register SrcReg, unsigned BitSize, int FrameIdx, int Offset,
- const TargetInstrInfo *TII, const TargetRegisterClass *RC,
- const TargetRegisterInfo *TRI) {
-
- unsigned SubIdx = (BitSize == 8) ? X86::sub_8bit : X86::sub_16bit;
- unsigned Opc = (BitSize == 8) ? X86::MOV8mr : X86::MOV16mr;
- if (BitSize == TRI->getRegSizeInBits(*RC))
- SubIdx = 0;
- MachineInstr *NewMI =
- addFrameReference(BuildMI(MBB, MI, DebugLoc(), TII->get(Opc)), FrameIdx,
- Offset)
- .addReg(SrcReg, 0, SubIdx);
- return NewMI;
-}
-
-static MachineInstr *storeImmToStackSlot(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI,
- int64_t Imm, unsigned BitSize,
- int FrameIdx, int Offset,
- const TargetInstrInfo *TII) {
- unsigned Opc = (BitSize == 8) ? X86::MOV8mi : X86::MOV16mi;
- return addFrameReference(BuildMI(MBB, MI, DebugLoc(), TII->get(Opc)),
- FrameIdx, Offset)
- .addImm(Imm);
-}
-
-MachineInstr *X86TileConfig::getTileConfigPoint() {
- for (MachineBasicBlock &MBB : *MF) {
-
- // Traverse the basic block.
- for (MachineInstr &MI : MBB)
- // Refer X86PreTileConfig.cpp.
- // We only support one tile config for now.
- if (MI.getOpcode() == X86::PLDTILECFG)
- return &MI;
- }
-
- return nullptr;
-}
-
-void X86TileConfig::tileConfig() {
- MachineInstr *MI = getTileConfigPoint();
- if (!MI)
- return;
- MachineBasicBlock *MBB = MI->getParent();
- int SS = MI->getOperand(1).getIndex();
- BitVector PhysRegs(TRI->getNumRegs());
-
- // Fill in the palette first.
- auto *NewMI = storeImmToStackSlot(*MBB, *MI, 1, 8, SS, 0, TII);
- LIS->InsertMachineInstrInMaps(*NewMI);
- // Fill in the shape of each tile physical register.
- for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
- Register VirtReg = Register::index2VirtReg(i);
- if (MRI->reg_nodbg_empty(VirtReg))
- continue;
- const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg);
- if (RC.getID() != X86::TILERegClassID)
- continue;
- Register PhysReg = VRM->getPhys(VirtReg);
- if (PhysRegs.test(PhysReg))
- continue;
- PhysRegs.set(PhysReg);
- ShapeT Shape = VRM->getShape(VirtReg);
- Register RowReg = Shape.getRow()->getReg();
- Register ColReg = Shape.getCol()->getReg();
-
- // Here is the data format for the tile config.
- // 0 palette
- // 1 start_row
- // 2-15 reserved, must be zero
- // 16-17 tile0.colsb Tile 0 bytes per row.
- // 18-19 tile1.colsb Tile 1 bytes per row.
- // 20-21 tile2.colsb Tile 2 bytes per row.
- // ... (sequence continues)
- // 30-31 tile7.colsb Tile 7 bytes per row.
- // 32-47 reserved, must be zero
- // 48 tile0.rows Tile 0 rows.
- // 49 tile1.rows Tile 1 rows.
- // 50 tile2.rows Tile 2 rows.
- // ... (sequence continues)
- // 55 tile7.rows Tile 7 rows.
- // 56-63 reserved, must be zero
- unsigned Index = getTilePhysRegIndex(PhysReg);
- int RowOffset = 48 + Index;
- int ColOffset = 16 + Index * 2;
-
- unsigned BitSize = 8;
- for (const auto &Pair : {std::make_pair(RowReg, RowOffset),
- std::make_pair(ColReg, ColOffset)}) {
- int64_t Imm;
- int ImmCount = 0;
- // All def must be the same value, otherwise it is invalid MIs.
- // Immediate is prefered.
- for (const MachineOperand &MO : MRI->def_operands(Pair.first)) {
- const auto *Inst = MO.getParent();
- if (Inst->isMoveImmediate()) {
- ImmCount++;
- Imm = Inst->getOperand(1).getImm();
- break;
- }
- }
- auto StoreConfig = [&](int Offset) {
- MachineInstr *NewMI = nullptr;
- if (ImmCount)
- NewMI = storeImmToStackSlot(*MBB, *MI, Imm, BitSize, SS, Offset, TII);
- else {
- const TargetRegisterClass *RC = MRI->getRegClass(Pair.first);
- NewMI = storeRegToStackSlot(*MBB, *MI, Pair.first, BitSize, SS,
- Offset, TII, RC, TRI);
- }
- SlotIndex SIdx = LIS->InsertMachineInstrInMaps(*NewMI);
- if (!ImmCount) {
- // Extend the live interval.
- SmallVector<SlotIndex, 8> EndPoints = {SIdx.getRegSlot()};
- LiveInterval &Int = LIS->getInterval(Pair.first);
- LIS->extendToIndices(Int, EndPoints);
- }
- };
- StoreConfig(Pair.second);
- BitSize += 8;
- }
- }
-}
-
-bool X86TileConfig::runOnMachineFunction(MachineFunction &mf) {
- MF = &mf;
- MRI = &mf.getRegInfo();
- ST = &mf.getSubtarget<X86Subtarget>();
- TRI = ST->getRegisterInfo();
- TII = mf.getSubtarget().getInstrInfo();
- DomTree = &getAnalysis<MachineDominatorTree>();
- VRM = &getAnalysis<VirtRegMap>();
- LIS = &getAnalysis<LiveIntervals>();
-
- if (VRM->isShapeMapEmpty())
- return false;
-
- tileConfig();
- return true;
-}
-
-FunctionPass *llvm::createX86TileConfigPass() { return new X86TileConfig(); }
+//===-- X86TileConfig.cpp - Tile Register Configure----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file Pass to config the shape of AMX physical registers
+/// AMX register need to be configured before use. In X86PreTileConfig pass
+/// the pldtilecfg instruction is inserted, however at that time we don't
+/// know the shape of each physical tile registers, because the register
+/// allocation is not done yet. This pass runs after egister allocation
+/// pass. It collects the shape information of each physical tile register
+/// and store the shape in the stack slot that is allocated for load config
+/// to tile config register.
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86.h"
+#include "X86InstrBuilder.h"
+#include "X86MachineFunctionInfo.h"
+#include "X86RegisterInfo.h"
+#include "X86Subtarget.h"
+#include "llvm/CodeGen/LiveIntervals.h"
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TileShapeInfo.h"
+#include "llvm/CodeGen/VirtRegMap.h"
+#include "llvm/InitializePasses.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "tile-config"
+
+namespace {
+
+class X86TileConfig : public MachineFunctionPass {
+ // context
+ MachineFunction *MF = nullptr;
+ const X86Subtarget *ST = nullptr;
+ const TargetRegisterInfo *TRI;
+ const TargetInstrInfo *TII;
+ MachineDominatorTree *DomTree = nullptr;
+ MachineRegisterInfo *MRI = nullptr;
+ VirtRegMap *VRM = nullptr;
+ LiveIntervals *LIS = nullptr;
+
+ MachineInstr *getTileConfigPoint();
+ void tileConfig();
+
+public:
+ X86TileConfig() : MachineFunctionPass(ID) {}
+
+ /// Return the pass name.
+ StringRef getPassName() const override { return "Tile Register Configure"; }
+
+ /// X86TileConfig analysis usage.
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+ /// Perform register allocation.
+ bool runOnMachineFunction(MachineFunction &mf) override;
+
+ MachineFunctionProperties getRequiredProperties() const override {
+ return MachineFunctionProperties().set(
+ MachineFunctionProperties::Property::NoPHIs);
+ }
+
+ static char ID;
+};
+
+} // end anonymous namespace
+
+char X86TileConfig::ID = 0;
+
+INITIALIZE_PASS_BEGIN(X86TileConfig, "tileconfig", "Tile Register Configure",
+ false, false)
+INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
+INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
+INITIALIZE_PASS_END(X86TileConfig, "tileconfig", "Tile Register Configure",
+ false, false)
+
+void X86TileConfig::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<MachineDominatorTree>();
+ AU.addRequired<LiveIntervals>();
+ AU.addPreserved<SlotIndexes>();
+ AU.addRequired<VirtRegMap>();
+ AU.setPreservesAll();
+ MachineFunctionPass::getAnalysisUsage(AU);
+}
+
+static unsigned getTilePhysRegIndex(Register PhysReg) {
+ assert((PhysReg >= X86::TMM0 && X86::TMM0 <= X86::TMM7) &&
+ "Tile register number is invalid");
+ return (PhysReg - X86::TMM0);
+}
+
+static MachineInstr *
+storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
+ Register SrcReg, unsigned BitSize, int FrameIdx, int Offset,
+ const TargetInstrInfo *TII, const TargetRegisterClass *RC,
+ const TargetRegisterInfo *TRI) {
+
+ unsigned SubIdx = (BitSize == 8) ? X86::sub_8bit : X86::sub_16bit;
+ unsigned Opc = (BitSize == 8) ? X86::MOV8mr : X86::MOV16mr;
+ if (BitSize == TRI->getRegSizeInBits(*RC))
+ SubIdx = 0;
+ MachineInstr *NewMI =
+ addFrameReference(BuildMI(MBB, MI, DebugLoc(), TII->get(Opc)), FrameIdx,
+ Offset)
+ .addReg(SrcReg, 0, SubIdx);
+ return NewMI;
+}
+
+static MachineInstr *storeImmToStackSlot(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ int64_t Imm, unsigned BitSize,
+ int FrameIdx, int Offset,
+ const TargetInstrInfo *TII) {
+ unsigned Opc = (BitSize == 8) ? X86::MOV8mi : X86::MOV16mi;
+ return addFrameReference(BuildMI(MBB, MI, DebugLoc(), TII->get(Opc)),
+ FrameIdx, Offset)
+ .addImm(Imm);
+}
+
+MachineInstr *X86TileConfig::getTileConfigPoint() {
+ for (MachineBasicBlock &MBB : *MF) {
+
+ // Traverse the basic block.
+ for (MachineInstr &MI : MBB)
+ // Refer X86PreTileConfig.cpp.
+ // We only support one tile config for now.
+ if (MI.getOpcode() == X86::PLDTILECFG)
+ return &MI;
+ }
+
+ return nullptr;
+}
+
+void X86TileConfig::tileConfig() {
+ MachineInstr *MI = getTileConfigPoint();
+ if (!MI)
+ return;
+ MachineBasicBlock *MBB = MI->getParent();
+ int SS = MI->getOperand(1).getIndex();
+ BitVector PhysRegs(TRI->getNumRegs());
+
+ // Fill in the palette first.
+ auto *NewMI = storeImmToStackSlot(*MBB, *MI, 1, 8, SS, 0, TII);
+ LIS->InsertMachineInstrInMaps(*NewMI);
+ // Fill in the shape of each tile physical register.
+ for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
+ Register VirtReg = Register::index2VirtReg(i);
+ if (MRI->reg_nodbg_empty(VirtReg))
+ continue;
+ const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg);
+ if (RC.getID() != X86::TILERegClassID)
+ continue;
+ Register PhysReg = VRM->getPhys(VirtReg);
+ if (PhysRegs.test(PhysReg))
+ continue;
+ PhysRegs.set(PhysReg);
+ ShapeT Shape = VRM->getShape(VirtReg);
+ Register RowReg = Shape.getRow()->getReg();
+ Register ColReg = Shape.getCol()->getReg();
+
+ // Here is the data format for the tile config.
+ // 0 palette
+ // 1 start_row
+ // 2-15 reserved, must be zero
+ // 16-17 tile0.colsb Tile 0 bytes per row.
+ // 18-19 tile1.colsb Tile 1 bytes per row.
+ // 20-21 tile2.colsb Tile 2 bytes per row.
+ // ... (sequence continues)
+ // 30-31 tile7.colsb Tile 7 bytes per row.
+ // 32-47 reserved, must be zero
+ // 48 tile0.rows Tile 0 rows.
+ // 49 tile1.rows Tile 1 rows.
+ // 50 tile2.rows Tile 2 rows.
+ // ... (sequence continues)
+ // 55 tile7.rows Tile 7 rows.
+ // 56-63 reserved, must be zero
+ unsigned Index = getTilePhysRegIndex(PhysReg);
+ int RowOffset = 48 + Index;
+ int ColOffset = 16 + Index * 2;
+
+ unsigned BitSize = 8;
+ for (const auto &Pair : {std::make_pair(RowReg, RowOffset),
+ std::make_pair(ColReg, ColOffset)}) {
+ int64_t Imm;
+ int ImmCount = 0;
+ // All def must be the same value, otherwise it is invalid MIs.
+ // Immediate is prefered.
+ for (const MachineOperand &MO : MRI->def_operands(Pair.first)) {
+ const auto *Inst = MO.getParent();
+ if (Inst->isMoveImmediate()) {
+ ImmCount++;
+ Imm = Inst->getOperand(1).getImm();
+ break;
+ }
+ }
+ auto StoreConfig = [&](int Offset) {
+ MachineInstr *NewMI = nullptr;
+ if (ImmCount)
+ NewMI = storeImmToStackSlot(*MBB, *MI, Imm, BitSize, SS, Offset, TII);
+ else {
+ const TargetRegisterClass *RC = MRI->getRegClass(Pair.first);
+ NewMI = storeRegToStackSlot(*MBB, *MI, Pair.first, BitSize, SS,
+ Offset, TII, RC, TRI);
+ }
+ SlotIndex SIdx = LIS->InsertMachineInstrInMaps(*NewMI);
+ if (!ImmCount) {
+ // Extend the live interval.
+ SmallVector<SlotIndex, 8> EndPoints = {SIdx.getRegSlot()};
+ LiveInterval &Int = LIS->getInterval(Pair.first);
+ LIS->extendToIndices(Int, EndPoints);
+ }
+ };
+ StoreConfig(Pair.second);
+ BitSize += 8;
+ }
+ }
+}
+
+bool X86TileConfig::runOnMachineFunction(MachineFunction &mf) {
+ MF = &mf;
+ MRI = &mf.getRegInfo();
+ ST = &mf.getSubtarget<X86Subtarget>();
+ TRI = ST->getRegisterInfo();
+ TII = mf.getSubtarget().getInstrInfo();
+ DomTree = &getAnalysis<MachineDominatorTree>();
+ VRM = &getAnalysis<VirtRegMap>();
+ LIS = &getAnalysis<LiveIntervals>();
+
+ if (VRM->isShapeMapEmpty())
+ return false;
+
+ tileConfig();
+ return true;
+}
+
+FunctionPass *llvm::createX86TileConfigPass() { return new X86TileConfig(); }
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86WinEHState.cpp b/contrib/libs/llvm12/lib/Target/X86/X86WinEHState.cpp
index 0122a5e83f..8d8bd5e6b3 100644
--- a/contrib/libs/llvm12/lib/Target/X86/X86WinEHState.cpp
+++ b/contrib/libs/llvm12/lib/Target/X86/X86WinEHState.cpp
@@ -109,7 +109,7 @@ private:
/// The linked list node subobject inside of RegNode.
Value *Link = nullptr;
};
-} // namespace
+} // namespace
FunctionPass *llvm::createX86WinEHStatePass() { return new WinEHStatePass(); }
diff --git a/contrib/libs/llvm12/lib/Target/X86/ya.make b/contrib/libs/llvm12/lib/Target/X86/ya.make
index efb9cc5da8..1df03a55e7 100644
--- a/contrib/libs/llvm12/lib/Target/X86/ya.make
+++ b/contrib/libs/llvm12/lib/Target/X86/ya.make
@@ -15,26 +15,26 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/CodeGen
- contrib/libs/llvm12/lib/CodeGen/AsmPrinter
- contrib/libs/llvm12/lib/CodeGen/GlobalISel
- contrib/libs/llvm12/lib/CodeGen/SelectionDAG
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/ProfileData
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target
- contrib/libs/llvm12/lib/Target/X86/MCTargetDesc
- contrib/libs/llvm12/lib/Target/X86/TargetInfo
- contrib/libs/llvm12/lib/Transforms/CFGuard
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/CodeGen
+ contrib/libs/llvm12/lib/CodeGen/AsmPrinter
+ contrib/libs/llvm12/lib/CodeGen/GlobalISel
+ contrib/libs/llvm12/lib/CodeGen/SelectionDAG
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/ProfileData
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target
+ contrib/libs/llvm12/lib/Target/X86/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/X86/TargetInfo
+ contrib/libs/llvm12/lib/Transforms/CFGuard
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86
- contrib/libs/llvm12/lib/Target/X86
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/X86
+ contrib/libs/llvm12/lib/Target/X86
)
NO_CLANG_COVERAGE()
@@ -68,7 +68,7 @@ SRCS(
X86IndirectThunks.cpp
X86InsertPrefetch.cpp
X86InsertWait.cpp
- X86InstCombineIntrinsic.cpp
+ X86InstCombineIntrinsic.cpp
X86InstrFMA3Info.cpp
X86InstrFoldTables.cpp
X86InstrInfo.cpp
@@ -77,14 +77,14 @@ SRCS(
X86LegalizerInfo.cpp
X86LoadValueInjectionLoadHardening.cpp
X86LoadValueInjectionRetHardening.cpp
- X86LowerAMXType.cpp
+ X86LowerAMXType.cpp
X86MCInstLower.cpp
X86MachineFunctionInfo.cpp
X86MacroFusion.cpp
X86OptimizeLEAs.cpp
X86PadShortFunction.cpp
X86PartialReduction.cpp
- X86PreTileConfig.cpp
+ X86PreTileConfig.cpp
X86RegisterBankInfo.cpp
X86RegisterInfo.cpp
X86SelectionDAGInfo.cpp
@@ -95,7 +95,7 @@ SRCS(
X86TargetMachine.cpp
X86TargetObjectFile.cpp
X86TargetTransformInfo.cpp
- X86TileConfig.cpp
+ X86TileConfig.cpp
X86VZeroUpper.cpp
X86WinAllocaExpander.cpp
X86WinEHState.cpp
diff --git a/contrib/libs/llvm12/lib/Target/ya.make b/contrib/libs/llvm12/lib/Target/ya.make
index e3f05f05db..8401456429 100644
--- a/contrib/libs/llvm12/lib/Target/ya.make
+++ b/contrib/libs/llvm12/lib/Target/ya.make
@@ -12,12 +12,12 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/TextAPI/MachO/Platform.cpp b/contrib/libs/llvm12/lib/TextAPI/MachO/Platform.cpp
index 0d65d2f0cf..f454c1cb6b 100644
--- a/contrib/libs/llvm12/lib/TextAPI/MachO/Platform.cpp
+++ b/contrib/libs/llvm12/lib/TextAPI/MachO/Platform.cpp
@@ -49,7 +49,7 @@ PlatformKind mapToPlatformKind(const Triple &Target) {
case Triple::WatchOS:
return Target.isSimulatorEnvironment() ? PlatformKind::watchOSSimulator
: PlatformKind::watchOS;
- // TODO: add bridgeOS & driverKit once in llvm::Triple
+ // TODO: add bridgeOS & driverKit once in llvm::Triple
}
llvm_unreachable("Unknown Target Triple");
}
@@ -83,8 +83,8 @@ StringRef getPlatformName(PlatformKind Platform) {
return "tvOS Simulator";
case PlatformKind::watchOSSimulator:
return "watchOS Simulator";
- case PlatformKind::driverKit:
- return "DriverKit";
+ case PlatformKind::driverKit:
+ return "DriverKit";
}
llvm_unreachable("Unknown llvm.MachO.PlatformKind enum");
}
diff --git a/contrib/libs/llvm12/lib/TextAPI/MachO/Target.cpp b/contrib/libs/llvm12/lib/TextAPI/MachO/Target.cpp
index 4edfdf0640..6f8d9bb4e1 100644
--- a/contrib/libs/llvm12/lib/TextAPI/MachO/Target.cpp
+++ b/contrib/libs/llvm12/lib/TextAPI/MachO/Target.cpp
@@ -33,7 +33,7 @@ Expected<Target> Target::create(StringRef TargetValue) {
.Case("ios-simulator", PlatformKind::iOSSimulator)
.Case("tvos-simulator", PlatformKind::tvOSSimulator)
.Case("watchos-simulator", PlatformKind::watchOSSimulator)
- .Case("driverkit", PlatformKind::driverKit)
+ .Case("driverkit", PlatformKind::driverKit)
.Default(PlatformKind::unknown);
if (Platform == PlatformKind::unknown) {
diff --git a/contrib/libs/llvm12/lib/TextAPI/MachO/TextStub.cpp b/contrib/libs/llvm12/lib/TextAPI/MachO/TextStub.cpp
index 24227bef24..1d6352b2e1 100644
--- a/contrib/libs/llvm12/lib/TextAPI/MachO/TextStub.cpp
+++ b/contrib/libs/llvm12/lib/TextAPI/MachO/TextStub.cpp
@@ -407,9 +407,9 @@ template <> struct ScalarTraits<Target> {
case PlatformKind::watchOSSimulator:
OS << "watchos-simulator";
break;
- case PlatformKind::driverKit:
- OS << "driverkit";
- break;
+ case PlatformKind::driverKit:
+ OS << "driverkit";
+ break;
}
}
@@ -521,12 +521,12 @@ template <> struct MappingTraits<const InterfaceFile *> {
break;
}
}
- llvm::sort(Section.Symbols);
- llvm::sort(Section.Classes);
- llvm::sort(Section.ClassEHs);
- llvm::sort(Section.IVars);
- llvm::sort(Section.WeakDefSymbols);
- llvm::sort(Section.TLVSymbols);
+ llvm::sort(Section.Symbols);
+ llvm::sort(Section.Classes);
+ llvm::sort(Section.ClassEHs);
+ llvm::sort(Section.IVars);
+ llvm::sort(Section.WeakDefSymbols);
+ llvm::sort(Section.TLVSymbols);
Exports.emplace_back(std::move(Section));
}
@@ -578,11 +578,11 @@ template <> struct MappingTraits<const InterfaceFile *> {
break;
}
}
- llvm::sort(Section.Symbols);
- llvm::sort(Section.Classes);
- llvm::sort(Section.ClassEHs);
- llvm::sort(Section.IVars);
- llvm::sort(Section.WeakRefSymbols);
+ llvm::sort(Section.Symbols);
+ llvm::sort(Section.Classes);
+ llvm::sort(Section.ClassEHs);
+ llvm::sort(Section.IVars);
+ llvm::sort(Section.WeakRefSymbols);
Undefineds.emplace_back(std::move(Section));
}
}
diff --git a/contrib/libs/llvm12/lib/TextAPI/MachO/TextStubCommon.cpp b/contrib/libs/llvm12/lib/TextAPI/MachO/TextStubCommon.cpp
index d3dbafdfb2..0d3614b0a2 100644
--- a/contrib/libs/llvm12/lib/TextAPI/MachO/TextStubCommon.cpp
+++ b/contrib/libs/llvm12/lib/TextAPI/MachO/TextStubCommon.cpp
@@ -84,9 +84,9 @@ void ScalarTraits<PlatformSet>::output(const PlatformSet &Values, void *IO,
case PlatformKind::macCatalyst:
OS << "iosmac";
break;
- case PlatformKind::driverKit:
- OS << "driverkit";
- break;
+ case PlatformKind::driverKit:
+ OS << "driverkit";
+ break;
}
}
diff --git a/contrib/libs/llvm12/lib/TextAPI/MachO/ya.make b/contrib/libs/llvm12/lib/TextAPI/MachO/ya.make
index dc22b94e93..4631a5ed63 100644
--- a/contrib/libs/llvm12/lib/TextAPI/MachO/ya.make
+++ b/contrib/libs/llvm12/lib/TextAPI/MachO/ya.make
@@ -1,40 +1,40 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
OWNER(
orivej
g:cpp-contrib
)
-
+
LICENSE(Apache-2.0 WITH LLVM-exception)
-
+
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/Support
-)
-
+PEERDIR(
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/Support
+)
+
ADDINCL(
contrib/libs/llvm12/lib/TextAPI
)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
-SRCS(
- Architecture.cpp
- ArchitectureSet.cpp
- InterfaceFile.cpp
- PackedVersion.cpp
- Platform.cpp
- Symbol.cpp
- Target.cpp
- TextStub.cpp
- TextStubCommon.cpp
-)
-
-END()
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
+SRCS(
+ Architecture.cpp
+ ArchitectureSet.cpp
+ InterfaceFile.cpp
+ PackedVersion.cpp
+ Platform.cpp
+ Symbol.cpp
+ Target.cpp
+ TextStub.cpp
+ TextStubCommon.cpp
+)
+
+END()
diff --git a/contrib/libs/llvm12/lib/ToolDrivers/llvm-dlltool/ya.make b/contrib/libs/llvm12/lib/ToolDrivers/llvm-dlltool/ya.make
index 87b6a373a2..3de52a0add 100644
--- a/contrib/libs/llvm12/lib/ToolDrivers/llvm-dlltool/ya.make
+++ b/contrib/libs/llvm12/lib/ToolDrivers/llvm-dlltool/ya.make
@@ -12,16 +12,16 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/Option
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/Option
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/ToolDrivers/llvm-dlltool
- contrib/libs/llvm12/lib/ToolDrivers/llvm-dlltool
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/ToolDrivers/llvm-dlltool
+ contrib/libs/llvm12/lib/ToolDrivers/llvm-dlltool
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/ToolDrivers/llvm-lib/LibDriver.cpp b/contrib/libs/llvm12/lib/ToolDrivers/llvm-lib/LibDriver.cpp
index 6a8977ad84..f3904b921e 100644
--- a/contrib/libs/llvm12/lib/ToolDrivers/llvm-lib/LibDriver.cpp
+++ b/contrib/libs/llvm12/lib/ToolDrivers/llvm-lib/LibDriver.cpp
@@ -139,28 +139,28 @@ static void doList(opt::InputArgList& Args) {
fatalOpenError(std::move(Err), B->getBufferIdentifier());
}
-static Expected<COFF::MachineTypes> getCOFFFileMachine(MemoryBufferRef MB) {
+static Expected<COFF::MachineTypes> getCOFFFileMachine(MemoryBufferRef MB) {
std::error_code EC;
auto Obj = object::COFFObjectFile::create(MB);
- if (!Obj)
- return Obj.takeError();
+ if (!Obj)
+ return Obj.takeError();
uint16_t Machine = (*Obj)->getMachine();
if (Machine != COFF::IMAGE_FILE_MACHINE_I386 &&
Machine != COFF::IMAGE_FILE_MACHINE_AMD64 &&
Machine != COFF::IMAGE_FILE_MACHINE_ARMNT &&
Machine != COFF::IMAGE_FILE_MACHINE_ARM64) {
- return createStringError(inconvertibleErrorCode(),
- "unknown machine: " + std::to_string(Machine));
+ return createStringError(inconvertibleErrorCode(),
+ "unknown machine: " + std::to_string(Machine));
}
return static_cast<COFF::MachineTypes>(Machine);
}
-static Expected<COFF::MachineTypes> getBitcodeFileMachine(MemoryBufferRef MB) {
+static Expected<COFF::MachineTypes> getBitcodeFileMachine(MemoryBufferRef MB) {
Expected<std::string> TripleStr = getBitcodeTargetTriple(MB);
- if (!TripleStr)
- return TripleStr.takeError();
+ if (!TripleStr)
+ return TripleStr.takeError();
switch (Triple(*TripleStr).getArch()) {
case Triple::x86:
@@ -172,8 +172,8 @@ static Expected<COFF::MachineTypes> getBitcodeFileMachine(MemoryBufferRef MB) {
case Triple::aarch64:
return COFF::IMAGE_FILE_MACHINE_ARM64;
default:
- return createStringError(inconvertibleErrorCode(),
- "unknown arch in target triple: " + *TripleStr);
+ return createStringError(inconvertibleErrorCode(),
+ "unknown arch in target triple: " + *TripleStr);
}
}
@@ -193,7 +193,7 @@ static void appendFile(std::vector<NewArchiveMember> &Members,
// If a user attempts to add an archive to another archive, llvm-lib doesn't
// handle the first archive file as a single file. Instead, it extracts all
- // members from the archive and add them to the second archive. This behavior
+ // members from the archive and add them to the second archive. This behavior
// is for compatibility with Microsoft's lib command.
if (Magic == file_magic::archive) {
Error Err = Error::success();
@@ -225,17 +225,17 @@ static void appendFile(std::vector<NewArchiveMember> &Members,
// in writeArchive() which needs to support many tools, can't assume the
// input is COFF, and doesn't have a good way to report errors.
if (Magic == file_magic::coff_object || Magic == file_magic::bitcode) {
- Expected<COFF::MachineTypes> MaybeFileMachine =
- (Magic == file_magic::coff_object) ? getCOFFFileMachine(MB)
- : getBitcodeFileMachine(MB);
- if (!MaybeFileMachine) {
- handleAllErrors(MaybeFileMachine.takeError(), [&](const ErrorInfoBase &EIB) {
- llvm::errs() << MB.getBufferIdentifier() << ": " << EIB.message()
- << "\n";
- });
- exit(1);
- }
- COFF::MachineTypes FileMachine = *MaybeFileMachine;
+ Expected<COFF::MachineTypes> MaybeFileMachine =
+ (Magic == file_magic::coff_object) ? getCOFFFileMachine(MB)
+ : getBitcodeFileMachine(MB);
+ if (!MaybeFileMachine) {
+ handleAllErrors(MaybeFileMachine.takeError(), [&](const ErrorInfoBase &EIB) {
+ llvm::errs() << MB.getBufferIdentifier() << ": " << EIB.message()
+ << "\n";
+ });
+ exit(1);
+ }
+ COFF::MachineTypes FileMachine = *MaybeFileMachine;
// FIXME: Once lld-link rejects multiple resource .obj files:
// Call convertResToCOFF() on .res files and add the resulting
diff --git a/contrib/libs/llvm12/lib/ToolDrivers/llvm-lib/ya.make b/contrib/libs/llvm12/lib/ToolDrivers/llvm-lib/ya.make
index 9ec00a6abd..cbe474770c 100644
--- a/contrib/libs/llvm12/lib/ToolDrivers/llvm-lib/ya.make
+++ b/contrib/libs/llvm12/lib/ToolDrivers/llvm-lib/ya.make
@@ -12,18 +12,18 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/Bitcode/Reader
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/Option
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/Bitcode/Reader
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/Option
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/ToolDrivers/llvm-lib
- contrib/libs/llvm12/lib/ToolDrivers/llvm-lib
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/ToolDrivers/llvm-lib
+ contrib/libs/llvm12/lib/ToolDrivers/llvm-lib
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index c088631352..a7ae10d156 100644
--- a/contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -21,10 +21,10 @@
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Function.h"
+#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/PatternMatch.h"
@@ -40,8 +40,8 @@ using namespace PatternMatch;
STATISTIC(NumAnyOrAllBitsSet, "Number of any/all-bits-set patterns folded");
STATISTIC(NumGuardedRotates,
"Number of guarded rotates transformed into funnel shifts");
-STATISTIC(NumGuardedFunnelShifts,
- "Number of guarded funnel shifts transformed into funnel shifts");
+STATISTIC(NumGuardedFunnelShifts,
+ "Number of guarded funnel shifts transformed into funnel shifts");
STATISTIC(NumPopCountRecognized, "Number of popcount idioms recognized");
namespace {
@@ -70,127 +70,127 @@ public:
};
} // namespace
-/// Match a pattern for a bitwise funnel/rotate operation that partially guards
-/// against undefined behavior by branching around the funnel-shift/rotation
-/// when the shift amount is 0.
-static bool foldGuardedFunnelShift(Instruction &I, const DominatorTree &DT) {
+/// Match a pattern for a bitwise funnel/rotate operation that partially guards
+/// against undefined behavior by branching around the funnel-shift/rotation
+/// when the shift amount is 0.
+static bool foldGuardedFunnelShift(Instruction &I, const DominatorTree &DT) {
if (I.getOpcode() != Instruction::PHI || I.getNumOperands() != 2)
return false;
// As with the one-use checks below, this is not strictly necessary, but we
// are being cautious to avoid potential perf regressions on targets that
- // do not actually have a funnel/rotate instruction (where the funnel shift
- // would be expanded back into math/shift/logic ops).
+ // do not actually have a funnel/rotate instruction (where the funnel shift
+ // would be expanded back into math/shift/logic ops).
if (!isPowerOf2_32(I.getType()->getScalarSizeInBits()))
return false;
- // Match V to funnel shift left/right and capture the source operands and
- // shift amount.
- auto matchFunnelShift = [](Value *V, Value *&ShVal0, Value *&ShVal1,
- Value *&ShAmt) {
- Value *SubAmt;
+ // Match V to funnel shift left/right and capture the source operands and
+ // shift amount.
+ auto matchFunnelShift = [](Value *V, Value *&ShVal0, Value *&ShVal1,
+ Value *&ShAmt) {
+ Value *SubAmt;
unsigned Width = V->getType()->getScalarSizeInBits();
- // fshl(ShVal0, ShVal1, ShAmt)
- // == (ShVal0 << ShAmt) | (ShVal1 >> (Width -ShAmt))
- if (match(V, m_OneUse(m_c_Or(
- m_Shl(m_Value(ShVal0), m_Value(ShAmt)),
- m_LShr(m_Value(ShVal1),
- m_Sub(m_SpecificInt(Width), m_Value(SubAmt))))))) {
- if (ShAmt == SubAmt) // TODO: Use m_Specific
- return Intrinsic::fshl;
+ // fshl(ShVal0, ShVal1, ShAmt)
+ // == (ShVal0 << ShAmt) | (ShVal1 >> (Width -ShAmt))
+ if (match(V, m_OneUse(m_c_Or(
+ m_Shl(m_Value(ShVal0), m_Value(ShAmt)),
+ m_LShr(m_Value(ShVal1),
+ m_Sub(m_SpecificInt(Width), m_Value(SubAmt))))))) {
+ if (ShAmt == SubAmt) // TODO: Use m_Specific
+ return Intrinsic::fshl;
}
- // fshr(ShVal0, ShVal1, ShAmt)
- // == (ShVal0 >> ShAmt) | (ShVal1 << (Width - ShAmt))
- if (match(V,
- m_OneUse(m_c_Or(m_Shl(m_Value(ShVal0), m_Sub(m_SpecificInt(Width),
- m_Value(SubAmt))),
- m_LShr(m_Value(ShVal1), m_Value(ShAmt)))))) {
- if (ShAmt == SubAmt) // TODO: Use m_Specific
- return Intrinsic::fshr;
+ // fshr(ShVal0, ShVal1, ShAmt)
+ // == (ShVal0 >> ShAmt) | (ShVal1 << (Width - ShAmt))
+ if (match(V,
+ m_OneUse(m_c_Or(m_Shl(m_Value(ShVal0), m_Sub(m_SpecificInt(Width),
+ m_Value(SubAmt))),
+ m_LShr(m_Value(ShVal1), m_Value(ShAmt)))))) {
+ if (ShAmt == SubAmt) // TODO: Use m_Specific
+ return Intrinsic::fshr;
}
return Intrinsic::not_intrinsic;
};
- // One phi operand must be a funnel/rotate operation, and the other phi
- // operand must be the source value of that funnel/rotate operation:
- // phi [ rotate(RotSrc, ShAmt), FunnelBB ], [ RotSrc, GuardBB ]
- // phi [ fshl(ShVal0, ShVal1, ShAmt), FunnelBB ], [ ShVal0, GuardBB ]
- // phi [ fshr(ShVal0, ShVal1, ShAmt), FunnelBB ], [ ShVal1, GuardBB ]
+ // One phi operand must be a funnel/rotate operation, and the other phi
+ // operand must be the source value of that funnel/rotate operation:
+ // phi [ rotate(RotSrc, ShAmt), FunnelBB ], [ RotSrc, GuardBB ]
+ // phi [ fshl(ShVal0, ShVal1, ShAmt), FunnelBB ], [ ShVal0, GuardBB ]
+ // phi [ fshr(ShVal0, ShVal1, ShAmt), FunnelBB ], [ ShVal1, GuardBB ]
PHINode &Phi = cast<PHINode>(I);
- unsigned FunnelOp = 0, GuardOp = 1;
+ unsigned FunnelOp = 0, GuardOp = 1;
Value *P0 = Phi.getOperand(0), *P1 = Phi.getOperand(1);
- Value *ShVal0, *ShVal1, *ShAmt;
- Intrinsic::ID IID = matchFunnelShift(P0, ShVal0, ShVal1, ShAmt);
- if (IID == Intrinsic::not_intrinsic ||
- (IID == Intrinsic::fshl && ShVal0 != P1) ||
- (IID == Intrinsic::fshr && ShVal1 != P1)) {
- IID = matchFunnelShift(P1, ShVal0, ShVal1, ShAmt);
- if (IID == Intrinsic::not_intrinsic ||
- (IID == Intrinsic::fshl && ShVal0 != P0) ||
- (IID == Intrinsic::fshr && ShVal1 != P0))
+ Value *ShVal0, *ShVal1, *ShAmt;
+ Intrinsic::ID IID = matchFunnelShift(P0, ShVal0, ShVal1, ShAmt);
+ if (IID == Intrinsic::not_intrinsic ||
+ (IID == Intrinsic::fshl && ShVal0 != P1) ||
+ (IID == Intrinsic::fshr && ShVal1 != P1)) {
+ IID = matchFunnelShift(P1, ShVal0, ShVal1, ShAmt);
+ if (IID == Intrinsic::not_intrinsic ||
+ (IID == Intrinsic::fshl && ShVal0 != P0) ||
+ (IID == Intrinsic::fshr && ShVal1 != P0))
return false;
assert((IID == Intrinsic::fshl || IID == Intrinsic::fshr) &&
"Pattern must match funnel shift left or right");
- std::swap(FunnelOp, GuardOp);
+ std::swap(FunnelOp, GuardOp);
}
// The incoming block with our source operand must be the "guard" block.
- // That must contain a cmp+branch to avoid the funnel/rotate when the shift
- // amount is equal to 0. The other incoming block is the block with the
- // funnel/rotate.
- BasicBlock *GuardBB = Phi.getIncomingBlock(GuardOp);
- BasicBlock *FunnelBB = Phi.getIncomingBlock(FunnelOp);
+ // That must contain a cmp+branch to avoid the funnel/rotate when the shift
+ // amount is equal to 0. The other incoming block is the block with the
+ // funnel/rotate.
+ BasicBlock *GuardBB = Phi.getIncomingBlock(GuardOp);
+ BasicBlock *FunnelBB = Phi.getIncomingBlock(FunnelOp);
Instruction *TermI = GuardBB->getTerminator();
-
- // Ensure that the shift values dominate each block.
- if (!DT.dominates(ShVal0, TermI) || !DT.dominates(ShVal1, TermI))
- return false;
-
+
+ // Ensure that the shift values dominate each block.
+ if (!DT.dominates(ShVal0, TermI) || !DT.dominates(ShVal1, TermI))
+ return false;
+
ICmpInst::Predicate Pred;
BasicBlock *PhiBB = Phi.getParent();
- if (!match(TermI, m_Br(m_ICmp(Pred, m_Specific(ShAmt), m_ZeroInt()),
- m_SpecificBB(PhiBB), m_SpecificBB(FunnelBB))))
+ if (!match(TermI, m_Br(m_ICmp(Pred, m_Specific(ShAmt), m_ZeroInt()),
+ m_SpecificBB(PhiBB), m_SpecificBB(FunnelBB))))
return false;
if (Pred != CmpInst::ICMP_EQ)
return false;
- IRBuilder<> Builder(PhiBB, PhiBB->getFirstInsertionPt());
-
- if (ShVal0 == ShVal1)
- ++NumGuardedRotates;
- else
- ++NumGuardedFunnelShifts;
-
- // If this is not a rotate then the select was blocking poison from the
- // 'shift-by-zero' non-TVal, but a funnel shift won't - so freeze it.
- bool IsFshl = IID == Intrinsic::fshl;
- if (ShVal0 != ShVal1) {
- if (IsFshl && !llvm::isGuaranteedNotToBePoison(ShVal1))
- ShVal1 = Builder.CreateFreeze(ShVal1);
- else if (!IsFshl && !llvm::isGuaranteedNotToBePoison(ShVal0))
- ShVal0 = Builder.CreateFreeze(ShVal0);
- }
-
+ IRBuilder<> Builder(PhiBB, PhiBB->getFirstInsertionPt());
+
+ if (ShVal0 == ShVal1)
+ ++NumGuardedRotates;
+ else
+ ++NumGuardedFunnelShifts;
+
+ // If this is not a rotate then the select was blocking poison from the
+ // 'shift-by-zero' non-TVal, but a funnel shift won't - so freeze it.
+ bool IsFshl = IID == Intrinsic::fshl;
+ if (ShVal0 != ShVal1) {
+ if (IsFshl && !llvm::isGuaranteedNotToBePoison(ShVal1))
+ ShVal1 = Builder.CreateFreeze(ShVal1);
+ else if (!IsFshl && !llvm::isGuaranteedNotToBePoison(ShVal0))
+ ShVal0 = Builder.CreateFreeze(ShVal0);
+ }
+
// We matched a variation of this IR pattern:
// GuardBB:
- // %cmp = icmp eq i32 %ShAmt, 0
- // br i1 %cmp, label %PhiBB, label %FunnelBB
- // FunnelBB:
- // %sub = sub i32 32, %ShAmt
- // %shr = lshr i32 %ShVal1, %sub
- // %shl = shl i32 %ShVal0, %ShAmt
- // %fsh = or i32 %shr, %shl
+ // %cmp = icmp eq i32 %ShAmt, 0
+ // br i1 %cmp, label %PhiBB, label %FunnelBB
+ // FunnelBB:
+ // %sub = sub i32 32, %ShAmt
+ // %shr = lshr i32 %ShVal1, %sub
+ // %shl = shl i32 %ShVal0, %ShAmt
+ // %fsh = or i32 %shr, %shl
// br label %PhiBB
// PhiBB:
- // %cond = phi i32 [ %fsh, %FunnelBB ], [ %ShVal0, %GuardBB ]
+ // %cond = phi i32 [ %fsh, %FunnelBB ], [ %ShVal0, %GuardBB ]
// -->
- // llvm.fshl.i32(i32 %ShVal0, i32 %ShVal1, i32 %ShAmt)
+ // llvm.fshl.i32(i32 %ShVal0, i32 %ShVal1, i32 %ShAmt)
Function *F = Intrinsic::getDeclaration(Phi.getModule(), IID, Phi.getType());
- Phi.replaceAllUsesWith(Builder.CreateCall(F, {ShVal0, ShVal1, ShAmt}));
+ Phi.replaceAllUsesWith(Builder.CreateCall(F, {ShVal0, ShVal1, ShAmt}));
return true;
}
@@ -237,8 +237,8 @@ static bool matchAndOrChain(Value *V, MaskOps &MOps) {
// We need a shift-right or a bare value representing a compare of bit 0 of
// the original source operand.
Value *Candidate;
- const APInt *BitIndex = nullptr;
- if (!match(V, m_LShr(m_Value(Candidate), m_APInt(BitIndex))))
+ const APInt *BitIndex = nullptr;
+ if (!match(V, m_LShr(m_Value(Candidate), m_APInt(BitIndex))))
Candidate = V;
// Initialize result source operand.
@@ -246,11 +246,11 @@ static bool matchAndOrChain(Value *V, MaskOps &MOps) {
MOps.Root = Candidate;
// The shift constant is out-of-range? This code hasn't been simplified.
- if (BitIndex && BitIndex->uge(MOps.Mask.getBitWidth()))
+ if (BitIndex && BitIndex->uge(MOps.Mask.getBitWidth()))
return false;
// Fill in the mask bit derived from the shift constant.
- MOps.Mask.setBit(BitIndex ? BitIndex->getZExtValue() : 0);
+ MOps.Mask.setBit(BitIndex ? BitIndex->getZExtValue() : 0);
return MOps.Root == Candidate;
}
@@ -379,7 +379,7 @@ static bool foldUnusualPatterns(Function &F, DominatorTree &DT) {
// iteratively in this loop rather than waiting until the end.
for (Instruction &I : make_range(BB.rbegin(), BB.rend())) {
MadeChange |= foldAnyOrAllBitsSet(I);
- MadeChange |= foldGuardedFunnelShift(I, DT);
+ MadeChange |= foldGuardedFunnelShift(I, DT);
MadeChange |= tryToRecognizePopCount(I);
}
}
diff --git a/contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp b/contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp
index 858907eed4..16b82219e8 100644
--- a/contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp
@@ -31,7 +31,7 @@
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
-#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instruction.h"
using namespace llvm;
@@ -130,7 +130,7 @@ bool TruncInstCombine::buildTruncExpressionDag() {
case Instruction::Select: {
SmallVector<Value *, 2> Operands;
getRelevantOperands(I, Operands);
- append_range(Worklist, Operands);
+ append_range(Worklist, Operands);
break;
}
default:
@@ -288,8 +288,8 @@ Type *TruncInstCombine::getBestTruncatedType() {
/// version of \p Ty, otherwise return \p Ty.
static Type *getReducedType(Value *V, Type *Ty) {
assert(Ty && !Ty->isVectorTy() && "Expect Scalar Type");
- if (auto *VTy = dyn_cast<VectorType>(V->getType()))
- return VectorType::get(Ty, VTy->getElementCount());
+ if (auto *VTy = dyn_cast<VectorType>(V->getType()))
+ return VectorType::get(Ty, VTy->getElementCount());
return Ty;
}
@@ -341,7 +341,7 @@ void TruncInstCombine::ReduceExpressionDag(Type *SclTy) {
// 1. Update Old-TruncInst -> New-TruncInst.
// 2. Remove Old-TruncInst (if New node is not TruncInst).
// 3. Add New-TruncInst (if Old node was not TruncInst).
- auto *Entry = find(Worklist, I);
+ auto *Entry = find(Worklist, I);
if (Entry != Worklist.end()) {
if (auto *NewCI = dyn_cast<TruncInst>(Res))
*Entry = NewCI;
diff --git a/contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine/ya.make b/contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine/ya.make
index 2885ad1ddf..c472a2054a 100644
--- a/contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine/ya.make
+++ b/contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine/ya.make
@@ -12,12 +12,12 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Transforms/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Transforms/Utils
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/Transforms/CFGuard/ya.make b/contrib/libs/llvm12/lib/Transforms/CFGuard/ya.make
index ac833cec12..37fe9ccc94 100644
--- a/contrib/libs/llvm12/lib/Transforms/CFGuard/ya.make
+++ b/contrib/libs/llvm12/lib/Transforms/CFGuard/ya.make
@@ -12,10 +12,10 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/AlwaysInliner.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/AlwaysInliner.cpp
index 29ae893836..532599b42e 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/AlwaysInliner.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/AlwaysInliner.cpp
@@ -13,10 +13,10 @@
#include "llvm/Transforms/IPO/AlwaysInliner.h"
#include "llvm/ADT/SetVector.h"
-#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/InlineCost.h"
-#include "llvm/Analysis/ProfileSummaryInfo.h"
+#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/DataLayout.h"
@@ -41,19 +41,19 @@ PreservedAnalyses AlwaysInlinerPass::run(Module &M,
auto GetAssumptionCache = [&](Function &F) -> AssumptionCache & {
return FAM.getResult<AssumptionAnalysis>(F);
};
- auto &PSI = MAM.getResult<ProfileSummaryAnalysis>(M);
+ auto &PSI = MAM.getResult<ProfileSummaryAnalysis>(M);
SmallSetVector<CallBase *, 16> Calls;
bool Changed = false;
SmallVector<Function *, 16> InlinedFunctions;
- for (Function &F : M) {
- // When callee coroutine function is inlined into caller coroutine function
- // before coro-split pass,
- // coro-early pass can not handle this quiet well.
- // So we won't inline the coroutine function if it have not been unsplited
- if (F.isPresplitCoroutine())
- continue;
-
+ for (Function &F : M) {
+ // When callee coroutine function is inlined into caller coroutine function
+ // before coro-split pass,
+ // coro-early pass can not handle this quiet well.
+ // So we won't inline the coroutine function if it have not been unsplited
+ if (F.isPresplitCoroutine())
+ continue;
+
if (!F.isDeclaration() && F.hasFnAttribute(Attribute::AlwaysInline) &&
isInlineViable(F).isSuccess()) {
Calls.clear();
@@ -63,41 +63,41 @@ PreservedAnalyses AlwaysInlinerPass::run(Module &M,
if (CB->getCalledFunction() == &F)
Calls.insert(CB);
- for (CallBase *CB : Calls) {
- Function *Caller = CB->getCaller();
- OptimizationRemarkEmitter ORE(Caller);
- auto OIC = shouldInline(
- *CB,
- [&](CallBase &CB) {
- return InlineCost::getAlways("always inline attribute");
- },
- ORE);
- assert(OIC);
- emitInlinedInto(ORE, CB->getDebugLoc(), CB->getParent(), F, *Caller,
- *OIC, false, DEBUG_TYPE);
-
- InlineFunctionInfo IFI(
- /*cg=*/nullptr, GetAssumptionCache, &PSI,
- &FAM.getResult<BlockFrequencyAnalysis>(*(CB->getCaller())),
- &FAM.getResult<BlockFrequencyAnalysis>(F));
-
- InlineResult Res = InlineFunction(
- *CB, IFI, &FAM.getResult<AAManager>(F), InsertLifetime);
- assert(Res.isSuccess() && "unexpected failure to inline");
- (void)Res;
-
- // Merge the attributes based on the inlining.
- AttributeFuncs::mergeAttributesForInlining(*Caller, F);
-
- Changed = true;
- }
-
+ for (CallBase *CB : Calls) {
+ Function *Caller = CB->getCaller();
+ OptimizationRemarkEmitter ORE(Caller);
+ auto OIC = shouldInline(
+ *CB,
+ [&](CallBase &CB) {
+ return InlineCost::getAlways("always inline attribute");
+ },
+ ORE);
+ assert(OIC);
+ emitInlinedInto(ORE, CB->getDebugLoc(), CB->getParent(), F, *Caller,
+ *OIC, false, DEBUG_TYPE);
+
+ InlineFunctionInfo IFI(
+ /*cg=*/nullptr, GetAssumptionCache, &PSI,
+ &FAM.getResult<BlockFrequencyAnalysis>(*(CB->getCaller())),
+ &FAM.getResult<BlockFrequencyAnalysis>(F));
+
+ InlineResult Res = InlineFunction(
+ *CB, IFI, &FAM.getResult<AAManager>(F), InsertLifetime);
+ assert(Res.isSuccess() && "unexpected failure to inline");
+ (void)Res;
+
+ // Merge the attributes based on the inlining.
+ AttributeFuncs::mergeAttributesForInlining(*Caller, F);
+
+ Changed = true;
+ }
+
// Remember to try and delete this function afterward. This both avoids
// re-walking the rest of the module and avoids dealing with any iterator
// invalidation issues while deleting functions.
InlinedFunctions.push_back(&F);
}
- }
+ }
// Remove any live functions.
erase_if(InlinedFunctions, [&](Function *F) {
@@ -190,13 +190,13 @@ InlineCost AlwaysInlinerLegacyPass::getInlineCost(CallBase &CB) {
if (!Callee)
return InlineCost::getNever("indirect call");
- // When callee coroutine function is inlined into caller coroutine function
- // before coro-split pass,
- // coro-early pass can not handle this quiet well.
- // So we won't inline the coroutine function if it have not been unsplited
- if (Callee->isPresplitCoroutine())
- return InlineCost::getNever("unsplited coroutine call");
-
+ // When callee coroutine function is inlined into caller coroutine function
+ // before coro-split pass,
+ // coro-early pass can not handle this quiet well.
+ // So we won't inline the coroutine function if it have not been unsplited
+ if (Callee->isPresplitCoroutine())
+ return InlineCost::getNever("unsplited coroutine call");
+
// FIXME: We shouldn't even get here for declarations.
if (Callee->isDeclaration())
return InlineCost::getNever("no definition");
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/Annotation2Metadata.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/Annotation2Metadata.cpp
index f2ad05676f..5ca4e24df8 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/Annotation2Metadata.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/Annotation2Metadata.cpp
@@ -1,106 +1,106 @@
-//===-- Annotation2Metadata.cpp - Add !annotation metadata. ---------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Add !annotation metadata for entries in @llvm.global.anotations, generated
-// using __attribute__((annotate("_name"))) on functions in Clang.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/IPO/Annotation2Metadata.h"
-#include "llvm/Analysis/OptimizationRemarkEmitter.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/InstIterator.h"
-#include "llvm/IR/Module.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Pass.h"
-#include "llvm/Transforms/IPO.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "annotation2metadata"
-
-static bool convertAnnotation2Metadata(Module &M) {
- // Only add !annotation metadata if the corresponding remarks pass is also
- // enabled.
- if (!OptimizationRemarkEmitter::allowExtraAnalysis(M.getContext(),
- "annotation-remarks"))
- return false;
-
- auto *Annotations = M.getGlobalVariable("llvm.global.annotations");
- auto *C = dyn_cast_or_null<Constant>(Annotations);
- if (!C || C->getNumOperands() != 1)
- return false;
-
- C = cast<Constant>(C->getOperand(0));
-
- // Iterate over all entries in C and attach !annotation metadata to suitable
- // entries.
- for (auto &Op : C->operands()) {
- // Look at the operands to check if we can use the entry to generate
- // !annotation metadata.
- auto *OpC = dyn_cast<ConstantStruct>(&Op);
- if (!OpC || OpC->getNumOperands() != 4)
- continue;
- auto *StrGEP = dyn_cast<ConstantExpr>(OpC->getOperand(1));
- if (!StrGEP || StrGEP->getNumOperands() < 2)
- continue;
- auto *StrC = dyn_cast<GlobalValue>(StrGEP->getOperand(0));
- if (!StrC)
- continue;
- auto *StrData = dyn_cast<ConstantDataSequential>(StrC->getOperand(0));
- if (!StrData)
- continue;
- // Look through bitcast.
- auto *Bitcast = dyn_cast<ConstantExpr>(OpC->getOperand(0));
- if (!Bitcast || Bitcast->getOpcode() != Instruction::BitCast)
- continue;
- auto *Fn = dyn_cast<Function>(Bitcast->getOperand(0));
- if (!Fn)
- continue;
-
- // Add annotation to all instructions in the function.
- for (auto &I : instructions(Fn))
- I.addAnnotationMetadata(StrData->getAsCString());
- }
- return true;
-}
-
-namespace {
-struct Annotation2MetadataLegacy : public ModulePass {
- static char ID;
-
- Annotation2MetadataLegacy() : ModulePass(ID) {
- initializeAnnotation2MetadataLegacyPass(*PassRegistry::getPassRegistry());
- }
-
- bool runOnModule(Module &M) override { return convertAnnotation2Metadata(M); }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- }
-};
-
-} // end anonymous namespace
-
-char Annotation2MetadataLegacy::ID = 0;
-
-INITIALIZE_PASS_BEGIN(Annotation2MetadataLegacy, DEBUG_TYPE,
- "Annotation2Metadata", false, false)
-INITIALIZE_PASS_END(Annotation2MetadataLegacy, DEBUG_TYPE,
- "Annotation2Metadata", false, false)
-
-ModulePass *llvm::createAnnotation2MetadataLegacyPass() {
- return new Annotation2MetadataLegacy();
-}
-
-PreservedAnalyses Annotation2MetadataPass::run(Module &M,
- ModuleAnalysisManager &AM) {
- convertAnnotation2Metadata(M);
- return PreservedAnalyses::all();
-}
+//===-- Annotation2Metadata.cpp - Add !annotation metadata. ---------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Add !annotation metadata for entries in @llvm.global.anotations, generated
+// using __attribute__((annotate("_name"))) on functions in Clang.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/IPO/Annotation2Metadata.h"
+#include "llvm/Analysis/OptimizationRemarkEmitter.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Transforms/IPO.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "annotation2metadata"
+
+static bool convertAnnotation2Metadata(Module &M) {
+ // Only add !annotation metadata if the corresponding remarks pass is also
+ // enabled.
+ if (!OptimizationRemarkEmitter::allowExtraAnalysis(M.getContext(),
+ "annotation-remarks"))
+ return false;
+
+ auto *Annotations = M.getGlobalVariable("llvm.global.annotations");
+ auto *C = dyn_cast_or_null<Constant>(Annotations);
+ if (!C || C->getNumOperands() != 1)
+ return false;
+
+ C = cast<Constant>(C->getOperand(0));
+
+ // Iterate over all entries in C and attach !annotation metadata to suitable
+ // entries.
+ for (auto &Op : C->operands()) {
+ // Look at the operands to check if we can use the entry to generate
+ // !annotation metadata.
+ auto *OpC = dyn_cast<ConstantStruct>(&Op);
+ if (!OpC || OpC->getNumOperands() != 4)
+ continue;
+ auto *StrGEP = dyn_cast<ConstantExpr>(OpC->getOperand(1));
+ if (!StrGEP || StrGEP->getNumOperands() < 2)
+ continue;
+ auto *StrC = dyn_cast<GlobalValue>(StrGEP->getOperand(0));
+ if (!StrC)
+ continue;
+ auto *StrData = dyn_cast<ConstantDataSequential>(StrC->getOperand(0));
+ if (!StrData)
+ continue;
+ // Look through bitcast.
+ auto *Bitcast = dyn_cast<ConstantExpr>(OpC->getOperand(0));
+ if (!Bitcast || Bitcast->getOpcode() != Instruction::BitCast)
+ continue;
+ auto *Fn = dyn_cast<Function>(Bitcast->getOperand(0));
+ if (!Fn)
+ continue;
+
+ // Add annotation to all instructions in the function.
+ for (auto &I : instructions(Fn))
+ I.addAnnotationMetadata(StrData->getAsCString());
+ }
+ return true;
+}
+
+namespace {
+struct Annotation2MetadataLegacy : public ModulePass {
+ static char ID;
+
+ Annotation2MetadataLegacy() : ModulePass(ID) {
+ initializeAnnotation2MetadataLegacyPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool runOnModule(Module &M) override { return convertAnnotation2Metadata(M); }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ }
+};
+
+} // end anonymous namespace
+
+char Annotation2MetadataLegacy::ID = 0;
+
+INITIALIZE_PASS_BEGIN(Annotation2MetadataLegacy, DEBUG_TYPE,
+ "Annotation2Metadata", false, false)
+INITIALIZE_PASS_END(Annotation2MetadataLegacy, DEBUG_TYPE,
+ "Annotation2Metadata", false, false)
+
+ModulePass *llvm::createAnnotation2MetadataLegacyPass() {
+ return new Annotation2MetadataLegacy();
+}
+
+PreservedAnalyses Annotation2MetadataPass::run(Module &M,
+ ModuleAnalysisManager &AM) {
+ convertAnnotation2Metadata(M);
+ return PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/ArgumentPromotion.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/ArgumentPromotion.cpp
index 2044b7d37c..7998a1ae5c 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -33,7 +33,7 @@
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
@@ -142,7 +142,7 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
// Simple byval argument? Just add all the struct element types.
Type *AgTy = cast<PointerType>(I->getType())->getElementType();
StructType *STy = cast<StructType>(AgTy);
- llvm::append_range(Params, STy->elements());
+ llvm::append_range(Params, STy->elements());
ArgAttrVec.insert(ArgAttrVec.end(), STy->getNumElements(),
AttributeSet());
++NumByValArgsPromoted;
@@ -160,19 +160,19 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
// In this table, we will track which indices are loaded from the argument
// (where direct loads are tracked as no indices).
ScalarizeTable &ArgIndices = ScalarizedElements[&*I];
- for (User *U : make_early_inc_range(I->users())) {
+ for (User *U : make_early_inc_range(I->users())) {
Instruction *UI = cast<Instruction>(U);
Type *SrcTy;
if (LoadInst *L = dyn_cast<LoadInst>(UI))
SrcTy = L->getType();
else
SrcTy = cast<GetElementPtrInst>(UI)->getSourceElementType();
- // Skip dead GEPs and remove them.
- if (isa<GetElementPtrInst>(UI) && UI->use_empty()) {
- UI->eraseFromParent();
- continue;
- }
-
+ // Skip dead GEPs and remove them.
+ if (isa<GetElementPtrInst>(UI) && UI->use_empty()) {
+ UI->eraseFromParent();
+ continue;
+ }
+
IndicesVector Indices;
Indices.reserve(UI->getNumOperands() - 1);
// Since loads will only have a single operand, and GEPs only a single
@@ -220,11 +220,11 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
Function *NF = Function::Create(NFTy, F->getLinkage(), F->getAddressSpace(),
F->getName());
NF->copyAttributesFrom(F);
- NF->copyMetadata(F, 0);
+ NF->copyMetadata(F, 0);
- // The new function will have the !dbg metadata copied from the original
- // function. The original function may not be deleted, and dbg metadata need
- // to be unique so we need to drop it.
+ // The new function will have the !dbg metadata copied from the original
+ // function. The original function may not be deleted, and dbg metadata need
+ // to be unique so we need to drop it.
F->setSubprogram(nullptr);
LLVM_DEBUG(dbgs() << "ARG PROMOTION: Promoting to:" << *NF << "\n"
@@ -418,11 +418,11 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
continue;
}
- // There potentially are metadata uses for things like llvm.dbg.value.
- // Replace them with undef, after handling the other regular uses.
- auto RauwUndefMetadata = make_scope_exit(
- [&]() { I->replaceAllUsesWith(UndefValue::get(I->getType())); });
-
+ // There potentially are metadata uses for things like llvm.dbg.value.
+ // Replace them with undef, after handling the other regular uses.
+ auto RauwUndefMetadata = make_scope_exit(
+ [&]() { I->replaceAllUsesWith(UndefValue::get(I->getType())); });
+
if (I->use_empty())
continue;
@@ -442,8 +442,8 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
<< "' in function '" << F->getName() << "'\n");
} else {
GetElementPtrInst *GEP = cast<GetElementPtrInst>(I->user_back());
- assert(!GEP->use_empty() &&
- "GEPs without uses should be cleaned up already");
+ assert(!GEP->use_empty() &&
+ "GEPs without uses should be cleaned up already");
IndicesVector Operands;
Operands.reserve(GEP->getNumIndices());
for (User::op_iterator II = GEP->idx_begin(), IE = GEP->idx_end();
@@ -682,7 +682,7 @@ static bool isSafeToPromoteArgument(Argument *Arg, Type *ByValTy, AAResults &AAR
if (GEP->use_empty()) {
// Dead GEP's cause trouble later. Just remove them if we run into
// them.
- continue;
+ continue;
}
if (!UpdateBaseTy(GEP->getSourceElementType()))
@@ -822,12 +822,12 @@ static bool canPaddingBeAccessed(Argument *arg) {
// Scan through the uses recursively to make sure the pointer is always used
// sanely.
- SmallVector<Value *, 16> WorkList(arg->users());
+ SmallVector<Value *, 16> WorkList(arg->users());
while (!WorkList.empty()) {
- Value *V = WorkList.pop_back_val();
+ Value *V = WorkList.pop_back_val();
if (isa<GetElementPtrInst>(V) || isa<PHINode>(V)) {
if (PtrValues.insert(V).second)
- llvm::append_range(WorkList, V->users());
+ llvm::append_range(WorkList, V->users());
} else if (StoreInst *Store = dyn_cast<StoreInst>(V)) {
Stores.push_back(Store);
} else if (!isa<LoadInst>(V)) {
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/Attributor.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/Attributor.cpp
index 4a8934bc24..03ad451350 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/Attributor.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/Attributor.cpp
@@ -15,47 +15,47 @@
#include "llvm/Transforms/IPO/Attributor.h"
-#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/Analysis/InlineCost.h"
+#include "llvm/ADT/TinyPtrVector.h"
+#include "llvm/Analysis/InlineCost.h"
#include "llvm/Analysis/LazyValueInfo.h"
-#include "llvm/Analysis/MemorySSAUpdater.h"
+#include "llvm/Analysis/MemorySSAUpdater.h"
#include "llvm/Analysis/MustExecute.h"
#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/NoFolder.h"
#include "llvm/IR/Verifier.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/DebugCounter.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/GraphWriter.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/DebugCounter.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/GraphWriter.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/Local.h"
#include <cassert>
-#include <string>
+#include <string>
using namespace llvm;
#define DEBUG_TYPE "attributor"
-DEBUG_COUNTER(ManifestDBGCounter, "attributor-manifest",
- "Determine what attributes are manifested in the IR");
-
+DEBUG_COUNTER(ManifestDBGCounter, "attributor-manifest",
+ "Determine what attributes are manifested in the IR");
+
STATISTIC(NumFnDeleted, "Number of function deleted");
STATISTIC(NumFnWithExactDefinition,
"Number of functions with exact definitions");
STATISTIC(NumFnWithoutExactDefinition,
"Number of functions without exact definitions");
-STATISTIC(NumFnShallowWrappersCreated, "Number of shallow wrappers created");
+STATISTIC(NumFnShallowWrappersCreated, "Number of shallow wrappers created");
STATISTIC(NumAttributesTimedOut,
"Number of abstract attributes timed out before fixpoint");
STATISTIC(NumAttributesValidFixpoint,
@@ -77,14 +77,14 @@ static cl::opt<unsigned>
MaxFixpointIterations("attributor-max-iterations", cl::Hidden,
cl::desc("Maximal number of fixpoint iterations."),
cl::init(32));
-
-static cl::opt<unsigned, true> MaxInitializationChainLengthX(
- "attributor-max-initialization-chain-length", cl::Hidden,
- cl::desc(
- "Maximal number of chained initializations (to avoid stack overflows)"),
- cl::location(MaxInitializationChainLength), cl::init(1024));
-unsigned llvm::MaxInitializationChainLength;
-
+
+static cl::opt<unsigned, true> MaxInitializationChainLengthX(
+ "attributor-max-initialization-chain-length", cl::Hidden,
+ cl::desc(
+ "Maximal number of chained initializations (to avoid stack overflows)"),
+ cl::location(MaxInitializationChainLength), cl::init(1024));
+unsigned llvm::MaxInitializationChainLength;
+
static cl::opt<bool> VerifyMaxFixpointIterations(
"attributor-max-iterations-verify", cl::Hidden,
cl::desc("Verify that max-iterations is a tight bound for a fixpoint"),
@@ -103,52 +103,52 @@ static cl::opt<bool>
"wrappers for non-exact definitions."),
cl::init(false));
-static cl::opt<bool>
- AllowDeepWrapper("attributor-allow-deep-wrappers", cl::Hidden,
- cl::desc("Allow the Attributor to use IP information "
- "derived from non-exact functions via cloning"),
- cl::init(false));
-
-// These options can only used for debug builds.
-#ifndef NDEBUG
+static cl::opt<bool>
+ AllowDeepWrapper("attributor-allow-deep-wrappers", cl::Hidden,
+ cl::desc("Allow the Attributor to use IP information "
+ "derived from non-exact functions via cloning"),
+ cl::init(false));
+
+// These options can only used for debug builds.
+#ifndef NDEBUG
static cl::list<std::string>
SeedAllowList("attributor-seed-allow-list", cl::Hidden,
- cl::desc("Comma seperated list of attribute names that are "
+ cl::desc("Comma seperated list of attribute names that are "
"allowed to be seeded."),
cl::ZeroOrMore, cl::CommaSeparated);
-static cl::list<std::string> FunctionSeedAllowList(
- "attributor-function-seed-allow-list", cl::Hidden,
- cl::desc("Comma seperated list of function names that are "
- "allowed to be seeded."),
- cl::ZeroOrMore, cl::CommaSeparated);
-#endif
-
-static cl::opt<bool>
- DumpDepGraph("attributor-dump-dep-graph", cl::Hidden,
- cl::desc("Dump the dependency graph to dot files."),
- cl::init(false));
-
-static cl::opt<std::string> DepGraphDotFileNamePrefix(
- "attributor-depgraph-dot-filename-prefix", cl::Hidden,
- cl::desc("The prefix used for the CallGraph dot file names."));
-
-static cl::opt<bool> ViewDepGraph("attributor-view-dep-graph", cl::Hidden,
- cl::desc("View the dependency graph."),
- cl::init(false));
-
-static cl::opt<bool> PrintDependencies("attributor-print-dep", cl::Hidden,
- cl::desc("Print attribute dependencies"),
- cl::init(false));
-
+static cl::list<std::string> FunctionSeedAllowList(
+ "attributor-function-seed-allow-list", cl::Hidden,
+ cl::desc("Comma seperated list of function names that are "
+ "allowed to be seeded."),
+ cl::ZeroOrMore, cl::CommaSeparated);
+#endif
+
+static cl::opt<bool>
+ DumpDepGraph("attributor-dump-dep-graph", cl::Hidden,
+ cl::desc("Dump the dependency graph to dot files."),
+ cl::init(false));
+
+static cl::opt<std::string> DepGraphDotFileNamePrefix(
+ "attributor-depgraph-dot-filename-prefix", cl::Hidden,
+ cl::desc("The prefix used for the CallGraph dot file names."));
+
+static cl::opt<bool> ViewDepGraph("attributor-view-dep-graph", cl::Hidden,
+ cl::desc("View the dependency graph."),
+ cl::init(false));
+
+static cl::opt<bool> PrintDependencies("attributor-print-dep", cl::Hidden,
+ cl::desc("Print attribute dependencies"),
+ cl::init(false));
+
/// Logic operators for the change status enum class.
///
///{
-ChangeStatus llvm::operator|(ChangeStatus L, ChangeStatus R) {
- return L == ChangeStatus::CHANGED ? L : R;
+ChangeStatus llvm::operator|(ChangeStatus L, ChangeStatus R) {
+ return L == ChangeStatus::CHANGED ? L : R;
}
-ChangeStatus llvm::operator&(ChangeStatus L, ChangeStatus R) {
- return L == ChangeStatus::UNCHANGED ? L : R;
+ChangeStatus llvm::operator&(ChangeStatus L, ChangeStatus R) {
+ return L == ChangeStatus::UNCHANGED ? L : R;
}
///}
@@ -201,7 +201,7 @@ Argument *IRPosition::getAssociatedArgument() const {
// Not an Argument and no argument number means this is not a call site
// argument, thus we cannot find a callback argument to return.
- int ArgNo = getCallSiteArgNo();
+ int ArgNo = getCallSiteArgNo();
if (ArgNo < 0)
return nullptr;
@@ -329,13 +329,13 @@ const IRPosition
SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
IRPositions.emplace_back(IRP);
- // Helper to determine if operand bundles on a call site are benin or
- // potentially problematic. We handle only llvm.assume for now.
- auto CanIgnoreOperandBundles = [](const CallBase &CB) {
- return (isa<IntrinsicInst>(CB) &&
- cast<IntrinsicInst>(CB).getIntrinsicID() == Intrinsic ::assume);
- };
-
+ // Helper to determine if operand bundles on a call site are benin or
+ // potentially problematic. We handle only llvm.assume for now.
+ auto CanIgnoreOperandBundles = [](const CallBase &CB) {
+ return (isa<IntrinsicInst>(CB) &&
+ cast<IntrinsicInst>(CB).getIntrinsicID() == Intrinsic ::assume);
+ };
+
const auto *CB = dyn_cast<CallBase>(&IRP.getAnchorValue());
switch (IRP.getPositionKind()) {
case IRPosition::IRP_INVALID:
@@ -350,7 +350,7 @@ SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
assert(CB && "Expected call site!");
// TODO: We need to look at the operand bundles similar to the redirection
// in CallBase.
- if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB))
+ if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB))
if (const Function *Callee = CB->getCalledFunction())
IRPositions.emplace_back(IRPosition::function(*Callee));
return;
@@ -358,7 +358,7 @@ SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
assert(CB && "Expected call site!");
// TODO: We need to look at the operand bundles similar to the redirection
// in CallBase.
- if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {
+ if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {
if (const Function *Callee = CB->getCalledFunction()) {
IRPositions.emplace_back(IRPosition::returned(*Callee));
IRPositions.emplace_back(IRPosition::function(*Callee));
@@ -375,16 +375,16 @@ SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
IRPositions.emplace_back(IRPosition::callsite_function(*CB));
return;
case IRPosition::IRP_CALL_SITE_ARGUMENT: {
- assert(CB && "Expected call site!");
+ assert(CB && "Expected call site!");
// TODO: We need to look at the operand bundles similar to the redirection
// in CallBase.
- if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {
+ if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {
const Function *Callee = CB->getCalledFunction();
- if (Callee) {
- if (Argument *Arg = IRP.getAssociatedArgument())
- IRPositions.emplace_back(IRPosition::argument(*Arg));
+ if (Callee) {
+ if (Argument *Arg = IRP.getAssociatedArgument())
+ IRPositions.emplace_back(IRPosition::argument(*Arg));
IRPositions.emplace_back(IRPosition::function(*Callee));
- }
+ }
}
IRPositions.emplace_back(IRPosition::value(IRP.getAssociatedValue()));
return;
@@ -522,7 +522,7 @@ void IRPosition::verify() {
"Expected call base argument operand for a 'call site argument' "
"position");
assert(cast<CallBase>(U->getUser())->getArgOperandNo(U) ==
- unsigned(getCallSiteArgNo()) &&
+ unsigned(getCallSiteArgNo()) &&
"Argument number mismatch!");
assert(U->get() == &getAssociatedValue() && "Associated value mismatch!");
return;
@@ -561,10 +561,10 @@ Attributor::getAssumedConstant(const Value &V, const AbstractAttribute &AA,
Attributor::~Attributor() {
// The abstract attributes are allocated via the BumpPtrAllocator Allocator,
// thus we cannot delete them. We can, and want to, destruct them though.
- for (auto &DepAA : DG.SyntheticRoot.Deps) {
- AbstractAttribute *AA = cast<AbstractAttribute>(DepAA.getPointer());
+ for (auto &DepAA : DG.SyntheticRoot.Deps) {
+ AbstractAttribute *AA = cast<AbstractAttribute>(DepAA.getPointer());
AA->~AbstractAttribute();
- }
+ }
}
bool Attributor::isAssumedDead(const AbstractAttribute &AA,
@@ -929,15 +929,15 @@ bool Attributor::checkForAllInstructions(function_ref<bool(Instruction &)> Pred,
// TODO: use the function scope once we have call site AAReturnedValues.
const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
- const auto *LivenessAA =
- CheckBBLivenessOnly ? nullptr
- : &(getAAFor<AAIsDead>(QueryingAA, QueryIRP,
- /* TrackDependence */ false));
+ const auto *LivenessAA =
+ CheckBBLivenessOnly ? nullptr
+ : &(getAAFor<AAIsDead>(QueryingAA, QueryIRP,
+ /* TrackDependence */ false));
auto &OpcodeInstMap =
InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
if (!checkForAllInstructionsImpl(this, OpcodeInstMap, Pred, &QueryingAA,
- LivenessAA, Opcodes, CheckBBLivenessOnly))
+ LivenessAA, Opcodes, CheckBBLivenessOnly))
return false;
return true;
@@ -970,9 +970,9 @@ bool Attributor::checkForAllReadWriteInstructions(
}
void Attributor::runTillFixpoint() {
- TimeTraceScope TimeScope("Attributor::runTillFixpoint");
+ TimeTraceScope TimeScope("Attributor::runTillFixpoint");
LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
- << DG.SyntheticRoot.Deps.size()
+ << DG.SyntheticRoot.Deps.size()
<< " abstract attributes.\n");
// Now that all abstract attributes are collected and initialized we start
@@ -982,11 +982,11 @@ void Attributor::runTillFixpoint() {
SmallVector<AbstractAttribute *, 32> ChangedAAs;
SetVector<AbstractAttribute *> Worklist, InvalidAAs;
- Worklist.insert(DG.SyntheticRoot.begin(), DG.SyntheticRoot.end());
+ Worklist.insert(DG.SyntheticRoot.begin(), DG.SyntheticRoot.end());
do {
// Remember the size to determine new attributes.
- size_t NumAAs = DG.SyntheticRoot.Deps.size();
+ size_t NumAAs = DG.SyntheticRoot.Deps.size();
LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
<< ", Worklist size: " << Worklist.size() << "\n");
@@ -1003,7 +1003,7 @@ void Attributor::runTillFixpoint() {
while (!InvalidAA->Deps.empty()) {
const auto &Dep = InvalidAA->Deps.back();
InvalidAA->Deps.pop_back();
- AbstractAttribute *DepAA = cast<AbstractAttribute>(Dep.getPointer());
+ AbstractAttribute *DepAA = cast<AbstractAttribute>(Dep.getPointer());
if (Dep.getInt() == unsigned(DepClassTy::OPTIONAL)) {
Worklist.insert(DepAA);
continue;
@@ -1021,8 +1021,8 @@ void Attributor::runTillFixpoint() {
// changed to the work list.
for (AbstractAttribute *ChangedAA : ChangedAAs)
while (!ChangedAA->Deps.empty()) {
- Worklist.insert(
- cast<AbstractAttribute>(ChangedAA->Deps.back().getPointer()));
+ Worklist.insert(
+ cast<AbstractAttribute>(ChangedAA->Deps.back().getPointer()));
ChangedAA->Deps.pop_back();
}
@@ -1050,8 +1050,8 @@ void Attributor::runTillFixpoint() {
// Add attributes to the changed set if they have been created in the last
// iteration.
- ChangedAAs.append(DG.SyntheticRoot.begin() + NumAAs,
- DG.SyntheticRoot.end());
+ ChangedAAs.append(DG.SyntheticRoot.begin() + NumAAs,
+ DG.SyntheticRoot.end());
// Reset the work list and repopulate with the changed abstract attributes.
// Note that dependent ones are added above.
@@ -1084,8 +1084,8 @@ void Attributor::runTillFixpoint() {
}
while (!ChangedAA->Deps.empty()) {
- ChangedAAs.push_back(
- cast<AbstractAttribute>(ChangedAA->Deps.back().getPointer()));
+ ChangedAAs.push_back(
+ cast<AbstractAttribute>(ChangedAA->Deps.back().getPointer()));
ChangedAA->Deps.pop_back();
}
}
@@ -1107,14 +1107,14 @@ void Attributor::runTillFixpoint() {
}
ChangeStatus Attributor::manifestAttributes() {
- TimeTraceScope TimeScope("Attributor::manifestAttributes");
- size_t NumFinalAAs = DG.SyntheticRoot.Deps.size();
+ TimeTraceScope TimeScope("Attributor::manifestAttributes");
+ size_t NumFinalAAs = DG.SyntheticRoot.Deps.size();
unsigned NumManifested = 0;
unsigned NumAtFixpoint = 0;
ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
- for (auto &DepAA : DG.SyntheticRoot.Deps) {
- AbstractAttribute *AA = cast<AbstractAttribute>(DepAA.getPointer());
+ for (auto &DepAA : DG.SyntheticRoot.Deps) {
+ AbstractAttribute *AA = cast<AbstractAttribute>(DepAA.getPointer());
AbstractState &State = AA->getState();
// If there is not already a fixpoint reached, we can now take the
@@ -1131,10 +1131,10 @@ ChangeStatus Attributor::manifestAttributes() {
// Skip dead code.
if (isAssumedDead(*AA, nullptr, /* CheckBBLivenessOnly */ true))
continue;
- // Check if the manifest debug counter that allows skipping manifestation of
- // AAs
- if (!DebugCounter::shouldExecute(ManifestDBGCounter))
- continue;
+ // Check if the manifest debug counter that allows skipping manifestation of
+ // AAs
+ if (!DebugCounter::shouldExecute(ManifestDBGCounter))
+ continue;
// Manifest the state and record if we changed the IR.
ChangeStatus LocalChange = AA->manifest(*this);
if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
@@ -1158,14 +1158,14 @@ ChangeStatus Attributor::manifestAttributes() {
NumAttributesValidFixpoint += NumAtFixpoint;
(void)NumFinalAAs;
- if (NumFinalAAs != DG.SyntheticRoot.Deps.size()) {
- for (unsigned u = NumFinalAAs; u < DG.SyntheticRoot.Deps.size(); ++u)
- errs() << "Unexpected abstract attribute: "
- << cast<AbstractAttribute>(DG.SyntheticRoot.Deps[u].getPointer())
+ if (NumFinalAAs != DG.SyntheticRoot.Deps.size()) {
+ for (unsigned u = NumFinalAAs; u < DG.SyntheticRoot.Deps.size(); ++u)
+ errs() << "Unexpected abstract attribute: "
+ << cast<AbstractAttribute>(DG.SyntheticRoot.Deps[u].getPointer())
<< " :: "
- << cast<AbstractAttribute>(DG.SyntheticRoot.Deps[u].getPointer())
- ->getIRPosition()
- .getAssociatedValue()
+ << cast<AbstractAttribute>(DG.SyntheticRoot.Deps[u].getPointer())
+ ->getIRPosition()
+ .getAssociatedValue()
<< "\n";
llvm_unreachable("Expected the final number of abstract attributes to "
"remain unchanged!");
@@ -1173,50 +1173,50 @@ ChangeStatus Attributor::manifestAttributes() {
return ManifestChange;
}
-void Attributor::identifyDeadInternalFunctions() {
- // Identify dead internal functions and delete them. This happens outside
- // the other fixpoint analysis as we might treat potentially dead functions
- // as live to lower the number of iterations. If they happen to be dead, the
- // below fixpoint loop will identify and eliminate them.
- SmallVector<Function *, 8> InternalFns;
- for (Function *F : Functions)
- if (F->hasLocalLinkage())
- InternalFns.push_back(F);
-
- SmallPtrSet<Function *, 8> LiveInternalFns;
- bool FoundLiveInternal = true;
- while (FoundLiveInternal) {
- FoundLiveInternal = false;
- for (unsigned u = 0, e = InternalFns.size(); u < e; ++u) {
- Function *F = InternalFns[u];
- if (!F)
- continue;
-
- bool AllCallSitesKnown;
- if (checkForAllCallSites(
- [&](AbstractCallSite ACS) {
- Function *Callee = ACS.getInstruction()->getFunction();
- return ToBeDeletedFunctions.count(Callee) ||
- (Functions.count(Callee) && Callee->hasLocalLinkage() &&
- !LiveInternalFns.count(Callee));
- },
- *F, true, nullptr, AllCallSitesKnown)) {
- continue;
- }
-
- LiveInternalFns.insert(F);
- InternalFns[u] = nullptr;
- FoundLiveInternal = true;
- }
- }
-
- for (unsigned u = 0, e = InternalFns.size(); u < e; ++u)
- if (Function *F = InternalFns[u])
- ToBeDeletedFunctions.insert(F);
-}
-
+void Attributor::identifyDeadInternalFunctions() {
+ // Identify dead internal functions and delete them. This happens outside
+ // the other fixpoint analysis as we might treat potentially dead functions
+ // as live to lower the number of iterations. If they happen to be dead, the
+ // below fixpoint loop will identify and eliminate them.
+ SmallVector<Function *, 8> InternalFns;
+ for (Function *F : Functions)
+ if (F->hasLocalLinkage())
+ InternalFns.push_back(F);
+
+ SmallPtrSet<Function *, 8> LiveInternalFns;
+ bool FoundLiveInternal = true;
+ while (FoundLiveInternal) {
+ FoundLiveInternal = false;
+ for (unsigned u = 0, e = InternalFns.size(); u < e; ++u) {
+ Function *F = InternalFns[u];
+ if (!F)
+ continue;
+
+ bool AllCallSitesKnown;
+ if (checkForAllCallSites(
+ [&](AbstractCallSite ACS) {
+ Function *Callee = ACS.getInstruction()->getFunction();
+ return ToBeDeletedFunctions.count(Callee) ||
+ (Functions.count(Callee) && Callee->hasLocalLinkage() &&
+ !LiveInternalFns.count(Callee));
+ },
+ *F, true, nullptr, AllCallSitesKnown)) {
+ continue;
+ }
+
+ LiveInternalFns.insert(F);
+ InternalFns[u] = nullptr;
+ FoundLiveInternal = true;
+ }
+ }
+
+ for (unsigned u = 0, e = InternalFns.size(); u < e; ++u)
+ if (Function *F = InternalFns[u])
+ ToBeDeletedFunctions.insert(F);
+}
+
ChangeStatus Attributor::cleanupIR() {
- TimeTraceScope TimeScope("Attributor::cleanupIR");
+ TimeTraceScope TimeScope("Attributor::cleanupIR");
// Delete stuff at the end to avoid invalid references and a nice order.
LLVM_DEBUG(dbgs() << "\n[Attributor] Delete at least "
<< ToBeDeletedFunctions.size() << " functions and "
@@ -1327,45 +1327,45 @@ ChangeStatus Attributor::cleanupIR() {
DetatchDeadBlocks(ToBeDeletedBBs, nullptr);
}
- identifyDeadInternalFunctions();
+ identifyDeadInternalFunctions();
// Rewrite the functions as requested during manifest.
ChangeStatus ManifestChange = rewriteFunctionSignatures(CGModifiedFunctions);
for (Function *Fn : CGModifiedFunctions)
- if (!ToBeDeletedFunctions.count(Fn))
- CGUpdater.reanalyzeFunction(*Fn);
+ if (!ToBeDeletedFunctions.count(Fn))
+ CGUpdater.reanalyzeFunction(*Fn);
- for (Function *Fn : ToBeDeletedFunctions) {
- if (!Functions.count(Fn))
- continue;
+ for (Function *Fn : ToBeDeletedFunctions) {
+ if (!Functions.count(Fn))
+ continue;
CGUpdater.removeFunction(*Fn);
- }
-
- if (!ToBeChangedUses.empty())
- ManifestChange = ChangeStatus::CHANGED;
-
- if (!ToBeChangedToUnreachableInsts.empty())
- ManifestChange = ChangeStatus::CHANGED;
-
- if (!ToBeDeletedFunctions.empty())
- ManifestChange = ChangeStatus::CHANGED;
-
- if (!ToBeDeletedBlocks.empty())
- ManifestChange = ChangeStatus::CHANGED;
-
- if (!ToBeDeletedInsts.empty())
- ManifestChange = ChangeStatus::CHANGED;
-
- if (!InvokeWithDeadSuccessor.empty())
- ManifestChange = ChangeStatus::CHANGED;
-
- if (!DeadInsts.empty())
- ManifestChange = ChangeStatus::CHANGED;
-
+ }
+
+ if (!ToBeChangedUses.empty())
+ ManifestChange = ChangeStatus::CHANGED;
+
+ if (!ToBeChangedToUnreachableInsts.empty())
+ ManifestChange = ChangeStatus::CHANGED;
+
+ if (!ToBeDeletedFunctions.empty())
+ ManifestChange = ChangeStatus::CHANGED;
+
+ if (!ToBeDeletedBlocks.empty())
+ ManifestChange = ChangeStatus::CHANGED;
+
+ if (!ToBeDeletedInsts.empty())
+ ManifestChange = ChangeStatus::CHANGED;
+
+ if (!InvokeWithDeadSuccessor.empty())
+ ManifestChange = ChangeStatus::CHANGED;
+
+ if (!DeadInsts.empty())
+ ManifestChange = ChangeStatus::CHANGED;
+
NumFnDeleted += ToBeDeletedFunctions.size();
- LLVM_DEBUG(dbgs() << "[Attributor] Deleted " << ToBeDeletedFunctions.size()
+ LLVM_DEBUG(dbgs() << "[Attributor] Deleted " << ToBeDeletedFunctions.size()
<< " functions after manifest.\n");
#ifdef EXPENSIVE_CHECKS
@@ -1380,37 +1380,37 @@ ChangeStatus Attributor::cleanupIR() {
}
ChangeStatus Attributor::run() {
- TimeTraceScope TimeScope("Attributor::run");
-
- Phase = AttributorPhase::UPDATE;
+ TimeTraceScope TimeScope("Attributor::run");
+
+ Phase = AttributorPhase::UPDATE;
runTillFixpoint();
-
- // dump graphs on demand
- if (DumpDepGraph)
- DG.dumpGraph();
-
- if (ViewDepGraph)
- DG.viewGraph();
-
- if (PrintDependencies)
- DG.print();
-
- Phase = AttributorPhase::MANIFEST;
+
+ // dump graphs on demand
+ if (DumpDepGraph)
+ DG.dumpGraph();
+
+ if (ViewDepGraph)
+ DG.viewGraph();
+
+ if (PrintDependencies)
+ DG.print();
+
+ Phase = AttributorPhase::MANIFEST;
ChangeStatus ManifestChange = manifestAttributes();
-
- Phase = AttributorPhase::CLEANUP;
+
+ Phase = AttributorPhase::CLEANUP;
ChangeStatus CleanupChange = cleanupIR();
-
+
return ManifestChange | CleanupChange;
}
ChangeStatus Attributor::updateAA(AbstractAttribute &AA) {
- TimeTraceScope TimeScope(
- AA.getName() + std::to_string(AA.getIRPosition().getPositionKind()) +
- "::updateAA");
- assert(Phase == AttributorPhase::UPDATE &&
- "We can update AA only in the update stage!");
-
+ TimeTraceScope TimeScope(
+ AA.getName() + std::to_string(AA.getIRPosition().getPositionKind()) +
+ "::updateAA");
+ assert(Phase == AttributorPhase::UPDATE &&
+ "We can update AA only in the update stage!");
+
// Use a new dependence vector for this update.
DependenceVector DV;
DependenceStack.push_back(&DV);
@@ -1438,7 +1438,7 @@ ChangeStatus Attributor::updateAA(AbstractAttribute &AA) {
return CS;
}
-void Attributor::createShallowWrapper(Function &F) {
+void Attributor::createShallowWrapper(Function &F) {
assert(!F.isDeclaration() && "Cannot create a wrapper around a declaration!");
Module &M = *F.getParent();
@@ -1471,7 +1471,7 @@ void Attributor::createShallowWrapper(Function &F) {
BasicBlock *EntryBB = BasicBlock::Create(Ctx, "entry", Wrapper);
SmallVector<Value *, 8> Args;
- Argument *FArgIt = F.arg_begin();
+ Argument *FArgIt = F.arg_begin();
for (Argument &Arg : Wrapper->args()) {
Args.push_back(&Arg);
Arg.setName((FArgIt++)->getName());
@@ -1482,59 +1482,59 @@ void Attributor::createShallowWrapper(Function &F) {
CI->addAttribute(AttributeList::FunctionIndex, Attribute::NoInline);
ReturnInst::Create(Ctx, CI->getType()->isVoidTy() ? nullptr : CI, EntryBB);
- NumFnShallowWrappersCreated++;
+ NumFnShallowWrappersCreated++;
+}
+
+/// Make another copy of the function \p F such that the copied version has
+/// internal linkage afterwards and can be analysed. Then we replace all uses
+/// of the original function to the copied one
+///
+/// Only non-exactly defined functions that have `linkonce_odr` or `weak_odr`
+/// linkage can be internalized because these linkages guarantee that other
+/// definitions with the same name have the same semantics as this one
+///
+static Function *internalizeFunction(Function &F) {
+ assert(AllowDeepWrapper && "Cannot create a copy if not allowed.");
+ assert(!F.isDeclaration() && !F.hasExactDefinition() &&
+ !GlobalValue::isInterposableLinkage(F.getLinkage()) &&
+ "Trying to internalize function which cannot be internalized.");
+
+ Module &M = *F.getParent();
+ FunctionType *FnTy = F.getFunctionType();
+
+ // create a copy of the current function
+ Function *Copied = Function::Create(FnTy, F.getLinkage(), F.getAddressSpace(),
+ F.getName() + ".internalized");
+ ValueToValueMapTy VMap;
+ auto *NewFArgIt = Copied->arg_begin();
+ for (auto &Arg : F.args()) {
+ auto ArgName = Arg.getName();
+ NewFArgIt->setName(ArgName);
+ VMap[&Arg] = &(*NewFArgIt++);
+ }
+ SmallVector<ReturnInst *, 8> Returns;
+
+ // Copy the body of the original function to the new one
+ CloneFunctionInto(Copied, &F, VMap, /* ModuleLevelChanges */ false, Returns);
+
+ // Set the linakage and visibility late as CloneFunctionInto has some implicit
+ // requirements.
+ Copied->setVisibility(GlobalValue::DefaultVisibility);
+ Copied->setLinkage(GlobalValue::PrivateLinkage);
+
+ // Copy metadata
+ SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
+ F.getAllMetadata(MDs);
+ for (auto MDIt : MDs)
+ Copied->addMetadata(MDIt.first, *MDIt.second);
+
+ M.getFunctionList().insert(F.getIterator(), Copied);
+ F.replaceAllUsesWith(Copied);
+ Copied->setDSOLocal(true);
+
+ return Copied;
}
-/// Make another copy of the function \p F such that the copied version has
-/// internal linkage afterwards and can be analysed. Then we replace all uses
-/// of the original function to the copied one
-///
-/// Only non-exactly defined functions that have `linkonce_odr` or `weak_odr`
-/// linkage can be internalized because these linkages guarantee that other
-/// definitions with the same name have the same semantics as this one
-///
-static Function *internalizeFunction(Function &F) {
- assert(AllowDeepWrapper && "Cannot create a copy if not allowed.");
- assert(!F.isDeclaration() && !F.hasExactDefinition() &&
- !GlobalValue::isInterposableLinkage(F.getLinkage()) &&
- "Trying to internalize function which cannot be internalized.");
-
- Module &M = *F.getParent();
- FunctionType *FnTy = F.getFunctionType();
-
- // create a copy of the current function
- Function *Copied = Function::Create(FnTy, F.getLinkage(), F.getAddressSpace(),
- F.getName() + ".internalized");
- ValueToValueMapTy VMap;
- auto *NewFArgIt = Copied->arg_begin();
- for (auto &Arg : F.args()) {
- auto ArgName = Arg.getName();
- NewFArgIt->setName(ArgName);
- VMap[&Arg] = &(*NewFArgIt++);
- }
- SmallVector<ReturnInst *, 8> Returns;
-
- // Copy the body of the original function to the new one
- CloneFunctionInto(Copied, &F, VMap, /* ModuleLevelChanges */ false, Returns);
-
- // Set the linakage and visibility late as CloneFunctionInto has some implicit
- // requirements.
- Copied->setVisibility(GlobalValue::DefaultVisibility);
- Copied->setLinkage(GlobalValue::PrivateLinkage);
-
- // Copy metadata
- SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
- F.getAllMetadata(MDs);
- for (auto MDIt : MDs)
- Copied->addMetadata(MDIt.first, *MDIt.second);
-
- M.getFunctionList().insert(F.getIterator(), Copied);
- F.replaceAllUsesWith(Copied);
- Copied->setDSOLocal(true);
-
- return Copied;
-}
-
bool Attributor::isValidFunctionSignatureRewrite(
Argument &Arg, ArrayRef<Type *> ReplacementTypes) {
@@ -1635,17 +1635,17 @@ bool Attributor::registerFunctionSignatureRewrite(
}
bool Attributor::shouldSeedAttribute(AbstractAttribute &AA) {
- bool Result = true;
-#ifndef NDEBUG
- if (SeedAllowList.size() != 0)
- Result =
- std::count(SeedAllowList.begin(), SeedAllowList.end(), AA.getName());
- Function *Fn = AA.getAnchorScope();
- if (FunctionSeedAllowList.size() != 0 && Fn)
- Result &= std::count(FunctionSeedAllowList.begin(),
- FunctionSeedAllowList.end(), Fn->getName());
-#endif
- return Result;
+ bool Result = true;
+#ifndef NDEBUG
+ if (SeedAllowList.size() != 0)
+ Result =
+ std::count(SeedAllowList.begin(), SeedAllowList.end(), AA.getName());
+ Function *Fn = AA.getAnchorScope();
+ if (FunctionSeedAllowList.size() != 0 && Fn)
+ Result &= std::count(FunctionSeedAllowList.begin(),
+ FunctionSeedAllowList.end(), Fn->getName());
+#endif
+ return Result;
}
ChangeStatus Attributor::rewriteFunctionSignatures(
@@ -1656,7 +1656,7 @@ ChangeStatus Attributor::rewriteFunctionSignatures(
Function *OldFn = It.getFirst();
// Deleted functions do not require rewrites.
- if (!Functions.count(OldFn) || ToBeDeletedFunctions.count(OldFn))
+ if (!Functions.count(OldFn) || ToBeDeletedFunctions.count(OldFn))
continue;
const SmallVectorImpl<std::unique_ptr<ArgumentReplacementInfo>> &ARIs =
@@ -1799,8 +1799,8 @@ ChangeStatus Attributor::rewriteFunctionSignatures(
assert(Success && "Assumed call site replacement to succeed!");
// Rewire the arguments.
- Argument *OldFnArgIt = OldFn->arg_begin();
- Argument *NewFnArgIt = NewFn->arg_begin();
+ Argument *OldFnArgIt = OldFn->arg_begin();
+ Argument *NewFnArgIt = NewFn->arg_begin();
for (unsigned OldArgNum = 0; OldArgNum < ARIs.size();
++OldArgNum, ++OldFnArgIt) {
if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =
@@ -1909,10 +1909,10 @@ void InformationCache::initializeInformationCache(const Function &CF,
InlineableFunctions.insert(&F);
}
-AAResults *InformationCache::getAAResultsForFunction(const Function &F) {
- return AG.getAnalysis<AAManager>(F);
-}
-
+AAResults *InformationCache::getAAResultsForFunction(const Function &F) {
+ return AG.getAnalysis<AAManager>(F);
+}
+
InformationCache::FunctionInfo::~FunctionInfo() {
// The instruction vectors are allocated using a BumpPtrAllocator, we need to
// manually destroy them.
@@ -2013,9 +2013,9 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
// Every function might be simplified.
getOrCreateAAFor<AAValueSimplify>(RetPos);
- // Every returned value might be marked noundef.
- getOrCreateAAFor<AANoUndef>(RetPos);
-
+ // Every returned value might be marked noundef.
+ getOrCreateAAFor<AANoUndef>(RetPos);
+
if (ReturnType->isPointerTy()) {
// Every function with pointer return type might be marked align.
@@ -2042,9 +2042,9 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
// Every argument might be dead.
getOrCreateAAFor<AAIsDead>(ArgPos);
- // Every argument might be marked noundef.
- getOrCreateAAFor<AANoUndef>(ArgPos);
-
+ // Every argument might be marked noundef.
+ getOrCreateAAFor<AANoUndef>(ArgPos);
+
if (Arg.getType()->isPointerTy()) {
// Every argument with pointer type might be marked nonnull.
getOrCreateAAFor<AANonNull>(ArgPos);
@@ -2112,9 +2112,9 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
// Call site argument might be simplified.
getOrCreateAAFor<AAValueSimplify>(CBArgPos);
- // Every call site argument might be marked "noundef".
- getOrCreateAAFor<AANoUndef>(CBArgPos);
-
+ // Every call site argument might be marked "noundef".
+ getOrCreateAAFor<AANoUndef>(CBArgPos);
+
if (!CB.getArgOperand(I)->getType()->isPointerTy())
continue;
@@ -2200,8 +2200,8 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {
raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {
const Value &AV = Pos.getAssociatedValue();
return OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
- << Pos.getAnchorValue().getName() << "@" << Pos.getCallSiteArgNo()
- << "]}";
+ << Pos.getAnchorValue().getName() << "@" << Pos.getCallSiteArgNo()
+ << "]}";
}
raw_ostream &llvm::operator<<(raw_ostream &OS, const IntegerRangeState &S) {
@@ -2223,49 +2223,49 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {
return OS;
}
-raw_ostream &llvm::operator<<(raw_ostream &OS,
- const PotentialConstantIntValuesState &S) {
- OS << "set-state(< {";
- if (!S.isValidState())
- OS << "full-set";
- else {
- for (auto &it : S.getAssumedSet())
- OS << it << ", ";
- if (S.undefIsContained())
- OS << "undef ";
- }
- OS << "} >)";
-
- return OS;
-}
-
+raw_ostream &llvm::operator<<(raw_ostream &OS,
+ const PotentialConstantIntValuesState &S) {
+ OS << "set-state(< {";
+ if (!S.isValidState())
+ OS << "full-set";
+ else {
+ for (auto &it : S.getAssumedSet())
+ OS << it << ", ";
+ if (S.undefIsContained())
+ OS << "undef ";
+ }
+ OS << "} >)";
+
+ return OS;
+}
+
void AbstractAttribute::print(raw_ostream &OS) const {
- OS << "[";
- OS << getName();
- OS << "] for CtxI ";
-
- if (auto *I = getCtxI()) {
- OS << "'";
- I->print(OS);
- OS << "'";
- } else
- OS << "<<null inst>>";
-
- OS << " at position " << getIRPosition() << " with state " << getAsStr()
- << '\n';
+ OS << "[";
+ OS << getName();
+ OS << "] for CtxI ";
+
+ if (auto *I = getCtxI()) {
+ OS << "'";
+ I->print(OS);
+ OS << "'";
+ } else
+ OS << "<<null inst>>";
+
+ OS << " at position " << getIRPosition() << " with state " << getAsStr()
+ << '\n';
+}
+
+void AbstractAttribute::printWithDeps(raw_ostream &OS) const {
+ print(OS);
+
+ for (const auto &DepAA : Deps) {
+ auto *AA = DepAA.getPointer();
+ OS << " updates ";
+ AA->print(OS);
+ }
+
+ OS << '\n';
}
-
-void AbstractAttribute::printWithDeps(raw_ostream &OS) const {
- print(OS);
-
- for (const auto &DepAA : Deps) {
- auto *AA = DepAA.getPointer();
- OS << " updates ";
- AA->print(OS);
- }
-
- OS << '\n';
-}
///}
/// ----------------------------------------------------------------------------
@@ -2290,32 +2290,32 @@ static bool runAttributorOnFunctions(InformationCache &InfoCache,
if (AllowShallowWrappers)
for (Function *F : Functions)
if (!A.isFunctionIPOAmendable(*F))
- Attributor::createShallowWrapper(*F);
-
- // Internalize non-exact functions
- // TODO: for now we eagerly internalize functions without calculating the
- // cost, we need a cost interface to determine whether internalizing
- // a function is "benefitial"
- if (AllowDeepWrapper) {
- unsigned FunSize = Functions.size();
- for (unsigned u = 0; u < FunSize; u++) {
- Function *F = Functions[u];
- if (!F->isDeclaration() && !F->isDefinitionExact() && F->getNumUses() &&
- !GlobalValue::isInterposableLinkage(F->getLinkage())) {
- Function *NewF = internalizeFunction(*F);
- Functions.insert(NewF);
-
- // Update call graph
- CGUpdater.replaceFunctionWith(*F, *NewF);
- for (const Use &U : NewF->uses())
- if (CallBase *CB = dyn_cast<CallBase>(U.getUser())) {
- auto *CallerF = CB->getCaller();
- CGUpdater.reanalyzeFunction(*CallerF);
- }
- }
- }
- }
-
+ Attributor::createShallowWrapper(*F);
+
+ // Internalize non-exact functions
+ // TODO: for now we eagerly internalize functions without calculating the
+ // cost, we need a cost interface to determine whether internalizing
+ // a function is "benefitial"
+ if (AllowDeepWrapper) {
+ unsigned FunSize = Functions.size();
+ for (unsigned u = 0; u < FunSize; u++) {
+ Function *F = Functions[u];
+ if (!F->isDeclaration() && !F->isDefinitionExact() && F->getNumUses() &&
+ !GlobalValue::isInterposableLinkage(F->getLinkage())) {
+ Function *NewF = internalizeFunction(*F);
+ Functions.insert(NewF);
+
+ // Update call graph
+ CGUpdater.replaceFunctionWith(*F, *NewF);
+ for (const Use &U : NewF->uses())
+ if (CallBase *CB = dyn_cast<CallBase>(U.getUser())) {
+ auto *CallerF = CB->getCaller();
+ CGUpdater.reanalyzeFunction(*CallerF);
+ }
+ }
+ }
+ }
+
for (Function *F : Functions) {
if (F->hasExactDefinition())
NumFnWithExactDefinition++;
@@ -2323,8 +2323,8 @@ static bool runAttributorOnFunctions(InformationCache &InfoCache,
NumFnWithoutExactDefinition++;
// We look at internal functions only on-demand but if any use is not a
- // direct call or outside the current set of analyzed functions, we have
- // to do it eagerly.
+ // direct call or outside the current set of analyzed functions, we have
+ // to do it eagerly.
if (F->hasLocalLinkage()) {
if (llvm::all_of(F->uses(), [&Functions](const Use &U) {
const auto *CB = dyn_cast<CallBase>(U.getUser());
@@ -2340,41 +2340,41 @@ static bool runAttributorOnFunctions(InformationCache &InfoCache,
}
ChangeStatus Changed = A.run();
-
+
LLVM_DEBUG(dbgs() << "[Attributor] Done with " << Functions.size()
<< " functions, result: " << Changed << ".\n");
return Changed == ChangeStatus::CHANGED;
}
-void AADepGraph::viewGraph() { llvm::ViewGraph(this, "Dependency Graph"); }
-
-void AADepGraph::dumpGraph() {
- static std::atomic<int> CallTimes;
- std::string Prefix;
-
- if (!DepGraphDotFileNamePrefix.empty())
- Prefix = DepGraphDotFileNamePrefix;
- else
- Prefix = "dep_graph";
- std::string Filename =
- Prefix + "_" + std::to_string(CallTimes.load()) + ".dot";
-
- outs() << "Dependency graph dump to " << Filename << ".\n";
-
- std::error_code EC;
-
- raw_fd_ostream File(Filename, EC, sys::fs::OF_Text);
- if (!EC)
- llvm::WriteGraph(File, this);
-
- CallTimes++;
-}
-
-void AADepGraph::print() {
- for (auto DepAA : SyntheticRoot.Deps)
- cast<AbstractAttribute>(DepAA.getPointer())->printWithDeps(outs());
-}
-
+void AADepGraph::viewGraph() { llvm::ViewGraph(this, "Dependency Graph"); }
+
+void AADepGraph::dumpGraph() {
+ static std::atomic<int> CallTimes;
+ std::string Prefix;
+
+ if (!DepGraphDotFileNamePrefix.empty())
+ Prefix = DepGraphDotFileNamePrefix;
+ else
+ Prefix = "dep_graph";
+ std::string Filename =
+ Prefix + "_" + std::to_string(CallTimes.load()) + ".dot";
+
+ outs() << "Dependency graph dump to " << Filename << ".\n";
+
+ std::error_code EC;
+
+ raw_fd_ostream File(Filename, EC, sys::fs::OF_Text);
+ if (!EC)
+ llvm::WriteGraph(File, this);
+
+ CallTimes++;
+}
+
+void AADepGraph::print() {
+ for (auto DepAA : SyntheticRoot.Deps)
+ cast<AbstractAttribute>(DepAA.getPointer())->printWithDeps(outs());
+}
+
PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
FunctionAnalysisManager &FAM =
AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
@@ -2416,58 +2416,58 @@ PreservedAnalyses AttributorCGSCCPass::run(LazyCallGraph::SCC &C,
InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ &Functions);
if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater)) {
// FIXME: Think about passes we will preserve and add them here.
- PreservedAnalyses PA;
- PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
- return PA;
+ PreservedAnalyses PA;
+ PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
+ return PA;
}
return PreservedAnalyses::all();
}
-namespace llvm {
-
-template <> struct GraphTraits<AADepGraphNode *> {
- using NodeRef = AADepGraphNode *;
- using DepTy = PointerIntPair<AADepGraphNode *, 1>;
- using EdgeRef = PointerIntPair<AADepGraphNode *, 1>;
-
- static NodeRef getEntryNode(AADepGraphNode *DGN) { return DGN; }
- static NodeRef DepGetVal(DepTy &DT) { return DT.getPointer(); }
-
- using ChildIteratorType =
- mapped_iterator<TinyPtrVector<DepTy>::iterator, decltype(&DepGetVal)>;
- using ChildEdgeIteratorType = TinyPtrVector<DepTy>::iterator;
-
- static ChildIteratorType child_begin(NodeRef N) { return N->child_begin(); }
-
- static ChildIteratorType child_end(NodeRef N) { return N->child_end(); }
-};
-
-template <>
-struct GraphTraits<AADepGraph *> : public GraphTraits<AADepGraphNode *> {
- static NodeRef getEntryNode(AADepGraph *DG) { return DG->GetEntryNode(); }
-
- using nodes_iterator =
- mapped_iterator<TinyPtrVector<DepTy>::iterator, decltype(&DepGetVal)>;
-
- static nodes_iterator nodes_begin(AADepGraph *DG) { return DG->begin(); }
-
- static nodes_iterator nodes_end(AADepGraph *DG) { return DG->end(); }
-};
-
-template <> struct DOTGraphTraits<AADepGraph *> : public DefaultDOTGraphTraits {
- DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
-
- static std::string getNodeLabel(const AADepGraphNode *Node,
- const AADepGraph *DG) {
- std::string AAString;
- raw_string_ostream O(AAString);
- Node->print(O);
- return AAString;
- }
-};
-
-} // end namespace llvm
-
+namespace llvm {
+
+template <> struct GraphTraits<AADepGraphNode *> {
+ using NodeRef = AADepGraphNode *;
+ using DepTy = PointerIntPair<AADepGraphNode *, 1>;
+ using EdgeRef = PointerIntPair<AADepGraphNode *, 1>;
+
+ static NodeRef getEntryNode(AADepGraphNode *DGN) { return DGN; }
+ static NodeRef DepGetVal(DepTy &DT) { return DT.getPointer(); }
+
+ using ChildIteratorType =
+ mapped_iterator<TinyPtrVector<DepTy>::iterator, decltype(&DepGetVal)>;
+ using ChildEdgeIteratorType = TinyPtrVector<DepTy>::iterator;
+
+ static ChildIteratorType child_begin(NodeRef N) { return N->child_begin(); }
+
+ static ChildIteratorType child_end(NodeRef N) { return N->child_end(); }
+};
+
+template <>
+struct GraphTraits<AADepGraph *> : public GraphTraits<AADepGraphNode *> {
+ static NodeRef getEntryNode(AADepGraph *DG) { return DG->GetEntryNode(); }
+
+ using nodes_iterator =
+ mapped_iterator<TinyPtrVector<DepTy>::iterator, decltype(&DepGetVal)>;
+
+ static nodes_iterator nodes_begin(AADepGraph *DG) { return DG->begin(); }
+
+ static nodes_iterator nodes_end(AADepGraph *DG) { return DG->end(); }
+};
+
+template <> struct DOTGraphTraits<AADepGraph *> : public DefaultDOTGraphTraits {
+ DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
+
+ static std::string getNodeLabel(const AADepGraphNode *Node,
+ const AADepGraph *DG) {
+ std::string AAString;
+ raw_string_ostream O(AAString);
+ Node->print(O);
+ return AAString;
+ }
+};
+
+} // end namespace llvm
+
namespace {
struct AttributorLegacyPass : public ModulePass {
@@ -2520,7 +2520,7 @@ struct AttributorCGSCCLegacyPass : public CallGraphSCCPass {
AnalysisGetter AG;
CallGraph &CG = const_cast<CallGraph &>(SCC.getCallGraph());
- CallGraphUpdater CGUpdater;
+ CallGraphUpdater CGUpdater;
CGUpdater.initialize(CG, SCC);
Module &M = *Functions.back()->getParent();
BumpPtrAllocator Allocator;
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/AttributorAttributes.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/AttributorAttributes.cpp
index f8bb9cc5b7..d6127a8df6 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -13,20 +13,20 @@
#include "llvm/Transforms/IPO/Attributor.h"
-#include "llvm/ADT/SCCIterator.h"
+#include "llvm/ADT/SCCIterator.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumeBundleQueries.h"
-#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/Analysis/LazyValueInfo.h"
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instruction.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/NoFolder.h"
#include "llvm/Support/CommandLine.h"
@@ -47,16 +47,16 @@ static cl::opt<bool> ManifestInternal(
static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
cl::Hidden);
-template <>
-unsigned llvm::PotentialConstantIntValuesState::MaxPotentialValues = 0;
-
-static cl::opt<unsigned, true> MaxPotentialValues(
- "attributor-max-potential-values", cl::Hidden,
- cl::desc("Maximum number of potential values to be "
- "tracked for each position."),
- cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues),
- cl::init(7));
-
+template <>
+unsigned llvm::PotentialConstantIntValuesState::MaxPotentialValues = 0;
+
+static cl::opt<unsigned, true> MaxPotentialValues(
+ "attributor-max-potential-values", cl::Hidden,
+ cl::desc("Maximum number of potential values to be "
+ "tracked for each position."),
+ cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues),
+ cl::init(7));
+
STATISTIC(NumAAs, "Number of abstract attributes created");
// Some helper macros to deal with statistics tracking.
@@ -132,8 +132,8 @@ PIPE_OPERATOR(AAMemoryLocation)
PIPE_OPERATOR(AAValueConstantRange)
PIPE_OPERATOR(AAPrivatizablePtr)
PIPE_OPERATOR(AAUndefinedBehavior)
-PIPE_OPERATOR(AAPotentialValues)
-PIPE_OPERATOR(AANoUndef)
+PIPE_OPERATOR(AAPotentialValues)
+PIPE_OPERATOR(AANoUndef)
#undef PIPE_OPERATOR
} // namespace llvm
@@ -452,7 +452,7 @@ static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA,
const AAType &AA = A.getAAFor<AAType>(QueryingAA, RVPos);
LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV << " AA: " << AA.getAsStr()
<< " @ " << RVPos << "\n");
- const StateType &AAS = AA.getState();
+ const StateType &AAS = AA.getState();
if (T.hasValue())
*T &= AAS;
else
@@ -502,7 +502,7 @@ static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
Optional<StateType> T;
// The argument number which is also the call site argument number.
- unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo();
+ unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo();
auto CallSiteCheck = [&](AbstractCallSite ACS) {
const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
@@ -514,7 +514,7 @@ static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
const AAType &AA = A.getAAFor<AAType>(QueryingAA, ACSArgPos);
LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
<< " AA: " << AA.getAsStr() << " @" << ACSArgPos << "\n");
- const StateType &AAS = AA.getState();
+ const StateType &AAS = AA.getState();
if (T.hasValue())
*T &= AAS;
else
@@ -571,7 +571,7 @@ struct AACallSiteReturnedFromReturned : public BaseType {
IRPosition FnPos = IRPosition::returned(*AssociatedFunction);
const AAType &AA = A.getAAFor<AAType>(*this, FnPos);
- return clampStateAndIndicateChange(S, AA.getState());
+ return clampStateAndIndicateChange(S, AA.getState());
}
};
@@ -738,7 +738,7 @@ struct AANoUnwindCallSite final : AANoUnwindImpl {
void initialize(Attributor &A) override {
AANoUnwindImpl::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || F->isDeclaration())
+ if (!F || F->isDeclaration())
indicatePessimisticFixpoint();
}
@@ -751,7 +751,7 @@ struct AANoUnwindCallSite final : AANoUnwindImpl {
Function *F = getAssociatedFunction();
const IRPosition &FnPos = IRPosition::function(*F);
auto &FnAA = A.getAAFor<AANoUnwind>(*this, FnPos);
- return clampStateAndIndicateChange(getState(), FnAA.getState());
+ return clampStateAndIndicateChange(getState(), FnAA.getState());
}
/// See AbstractAttribute::trackStatistics()
@@ -797,7 +797,7 @@ public:
ReturnedValues.clear();
Function *F = getAssociatedFunction();
- if (!F || F->isDeclaration()) {
+ if (!F || F->isDeclaration()) {
indicatePessimisticFixpoint();
return;
}
@@ -1066,10 +1066,10 @@ ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
// map, NewRVsMap.
decltype(ReturnedValues) NewRVsMap;
- auto HandleReturnValue = [&](Value *RV,
- SmallSetVector<ReturnInst *, 4> &RIs) {
- LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *RV << " by #"
- << RIs.size() << " RIs\n");
+ auto HandleReturnValue = [&](Value *RV,
+ SmallSetVector<ReturnInst *, 4> &RIs) {
+ LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *RV << " by #"
+ << RIs.size() << " RIs\n");
CallBase *CB = dyn_cast<CallBase>(RV);
if (!CB || UnresolvedCalls.count(CB))
return;
@@ -1143,13 +1143,13 @@ ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
RVState RVS({NewRVsMap, Unused, RetValAAIt.second});
VisitReturnedValue(*CB->getArgOperand(Arg->getArgNo()), RVS, CB);
continue;
- }
- if (isa<CallBase>(RetVal)) {
+ }
+ if (isa<CallBase>(RetVal)) {
// Call sites are resolved by the callee attribute over time, no need to
// do anything for us.
continue;
- }
- if (isa<Constant>(RetVal)) {
+ }
+ if (isa<Constant>(RetVal)) {
// Constants are valid everywhere, we can simply take them.
NewRVsMap[RetVal].insert(RIs.begin(), RIs.end());
continue;
@@ -1390,7 +1390,7 @@ struct AANoSyncCallSite final : AANoSyncImpl {
void initialize(Attributor &A) override {
AANoSyncImpl::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || F->isDeclaration())
+ if (!F || F->isDeclaration())
indicatePessimisticFixpoint();
}
@@ -1403,7 +1403,7 @@ struct AANoSyncCallSite final : AANoSyncImpl {
Function *F = getAssociatedFunction();
const IRPosition &FnPos = IRPosition::function(*F);
auto &FnAA = A.getAAFor<AANoSync>(*this, FnPos);
- return clampStateAndIndicateChange(getState(), FnAA.getState());
+ return clampStateAndIndicateChange(getState(), FnAA.getState());
}
/// See AbstractAttribute::trackStatistics()
@@ -1455,7 +1455,7 @@ struct AANoFreeCallSite final : AANoFreeImpl {
void initialize(Attributor &A) override {
AANoFreeImpl::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || F->isDeclaration())
+ if (!F || F->isDeclaration())
indicatePessimisticFixpoint();
}
@@ -1468,7 +1468,7 @@ struct AANoFreeCallSite final : AANoFreeImpl {
Function *F = getAssociatedFunction();
const IRPosition &FnPos = IRPosition::function(*F);
auto &FnAA = A.getAAFor<AANoFree>(*this, FnPos);
- return clampStateAndIndicateChange(getState(), FnAA.getState());
+ return clampStateAndIndicateChange(getState(), FnAA.getState());
}
/// See AbstractAttribute::trackStatistics()
@@ -1550,7 +1550,7 @@ struct AANoFreeCallSiteArgument final : AANoFreeFloating {
return indicatePessimisticFixpoint();
const IRPosition &ArgPos = IRPosition::argument(*Arg);
auto &ArgAA = A.getAAFor<AANoFree>(*this, ArgPos);
- return clampStateAndIndicateChange(getState(), ArgAA.getState());
+ return clampStateAndIndicateChange(getState(), ArgAA.getState());
}
/// See AbstractAttribute::trackStatistics()
@@ -1686,33 +1686,33 @@ struct AANonNullImpl : AANonNull {
Value &V = getAssociatedValue();
if (!NullIsDefined &&
hasAttr({Attribute::NonNull, Attribute::Dereferenceable},
- /* IgnoreSubsumingPositions */ false, &A)) {
+ /* IgnoreSubsumingPositions */ false, &A)) {
indicateOptimisticFixpoint();
- return;
- }
-
- if (isa<ConstantPointerNull>(V)) {
+ return;
+ }
+
+ if (isa<ConstantPointerNull>(V)) {
indicatePessimisticFixpoint();
- return;
- }
+ return;
+ }
+
+ AANonNull::initialize(A);
- AANonNull::initialize(A);
-
bool CanBeNull = true;
- if (V.getPointerDereferenceableBytes(A.getDataLayout(), CanBeNull)) {
- if (!CanBeNull) {
+ if (V.getPointerDereferenceableBytes(A.getDataLayout(), CanBeNull)) {
+ if (!CanBeNull) {
indicateOptimisticFixpoint();
- return;
- }
- }
+ return;
+ }
+ }
- if (isa<GlobalValue>(&getAssociatedValue())) {
- indicatePessimisticFixpoint();
- return;
- }
-
- if (Instruction *CtxI = getCtxI())
- followUsesInMBEC(*this, A, getState(), *CtxI);
+ if (isa<GlobalValue>(&getAssociatedValue())) {
+ indicatePessimisticFixpoint();
+ return;
+ }
+
+ if (Instruction *CtxI = getCtxI())
+ followUsesInMBEC(*this, A, getState(), *CtxI);
}
/// See followUsesInMBEC
@@ -1761,7 +1761,7 @@ struct AANonNullFloating : public AANonNullImpl {
T.indicatePessimisticFixpoint();
} else {
// Use abstract attribute information.
- const AANonNull::StateType &NS = AA.getState();
+ const AANonNull::StateType &NS = AA.getState();
T ^= NS;
}
return T.isValidState();
@@ -1781,15 +1781,15 @@ struct AANonNullFloating : public AANonNullImpl {
/// NonNull attribute for function return value.
struct AANonNullReturned final
- : AAReturnedFromReturnedValues<AANonNull, AANonNull> {
+ : AAReturnedFromReturnedValues<AANonNull, AANonNull> {
AANonNullReturned(const IRPosition &IRP, Attributor &A)
- : AAReturnedFromReturnedValues<AANonNull, AANonNull>(IRP, A) {}
+ : AAReturnedFromReturnedValues<AANonNull, AANonNull>(IRP, A) {}
+
+ /// See AbstractAttribute::getAsStr().
+ const std::string getAsStr() const override {
+ return getAssumed() ? "nonnull" : "may-null";
+ }
- /// See AbstractAttribute::getAsStr().
- const std::string getAsStr() const override {
- return getAssumed() ? "nonnull" : "may-null";
- }
-
/// See AbstractAttribute::trackStatistics()
void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
};
@@ -1902,7 +1902,7 @@ struct AANoRecurseCallSite final : AANoRecurseImpl {
void initialize(Attributor &A) override {
AANoRecurseImpl::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || F->isDeclaration())
+ if (!F || F->isDeclaration())
indicatePessimisticFixpoint();
}
@@ -1915,7 +1915,7 @@ struct AANoRecurseCallSite final : AANoRecurseImpl {
Function *F = getAssociatedFunction();
const IRPosition &FnPos = IRPosition::function(*F);
auto &FnAA = A.getAAFor<AANoRecurse>(*this, FnPos);
- return clampStateAndIndicateChange(getState(), FnAA.getState());
+ return clampStateAndIndicateChange(getState(), FnAA.getState());
}
/// See AbstractAttribute::trackStatistics()
@@ -2000,98 +2000,98 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
return true;
};
- auto InspectCallSiteForUB = [&](Instruction &I) {
- // Check whether a callsite always cause UB or not
-
- // Skip instructions that are already saved.
- if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
- return true;
-
- // Check nonnull and noundef argument attribute violation for each
- // callsite.
- CallBase &CB = cast<CallBase>(I);
- Function *Callee = CB.getCalledFunction();
- if (!Callee)
- return true;
- for (unsigned idx = 0; idx < CB.getNumArgOperands(); idx++) {
- // If current argument is known to be simplified to null pointer and the
- // corresponding argument position is known to have nonnull attribute,
- // the argument is poison. Furthermore, if the argument is poison and
- // the position is known to have noundef attriubte, this callsite is
- // considered UB.
- if (idx >= Callee->arg_size())
- break;
- Value *ArgVal = CB.getArgOperand(idx);
- if (!ArgVal)
- continue;
- // Here, we handle three cases.
- // (1) Not having a value means it is dead. (we can replace the value
- // with undef)
- // (2) Simplified to undef. The argument violate noundef attriubte.
- // (3) Simplified to null pointer where known to be nonnull.
- // The argument is a poison value and violate noundef attribute.
- IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
- auto &NoUndefAA = A.getAAFor<AANoUndef>(*this, CalleeArgumentIRP,
- /* TrackDependence */ false);
- if (!NoUndefAA.isKnownNoUndef())
- continue;
- auto &ValueSimplifyAA = A.getAAFor<AAValueSimplify>(
- *this, IRPosition::value(*ArgVal), /* TrackDependence */ false);
- if (!ValueSimplifyAA.isKnown())
- continue;
- Optional<Value *> SimplifiedVal =
- ValueSimplifyAA.getAssumedSimplifiedValue(A);
- if (!SimplifiedVal.hasValue() ||
- isa<UndefValue>(*SimplifiedVal.getValue())) {
- KnownUBInsts.insert(&I);
- continue;
- }
- if (!ArgVal->getType()->isPointerTy() ||
- !isa<ConstantPointerNull>(*SimplifiedVal.getValue()))
- continue;
- auto &NonNullAA = A.getAAFor<AANonNull>(*this, CalleeArgumentIRP,
- /* TrackDependence */ false);
- if (NonNullAA.isKnownNonNull())
- KnownUBInsts.insert(&I);
- }
- return true;
- };
-
- auto InspectReturnInstForUB =
- [&](Value &V, const SmallSetVector<ReturnInst *, 4> RetInsts) {
- // Check if a return instruction always cause UB or not
- // Note: It is guaranteed that the returned position of the anchor
- // scope has noundef attribute when this is called.
- // We also ensure the return position is not "assumed dead"
- // because the returned value was then potentially simplified to
- // `undef` in AAReturnedValues without removing the `noundef`
- // attribute yet.
-
- // When the returned position has noundef attriubte, UB occur in the
- // following cases.
- // (1) Returned value is known to be undef.
- // (2) The value is known to be a null pointer and the returned
- // position has nonnull attribute (because the returned value is
- // poison).
- bool FoundUB = false;
- if (isa<UndefValue>(V)) {
- FoundUB = true;
- } else {
- if (isa<ConstantPointerNull>(V)) {
- auto &NonNullAA = A.getAAFor<AANonNull>(
- *this, IRPosition::returned(*getAnchorScope()),
- /* TrackDependence */ false);
- if (NonNullAA.isKnownNonNull())
- FoundUB = true;
- }
- }
-
- if (FoundUB)
- for (ReturnInst *RI : RetInsts)
- KnownUBInsts.insert(RI);
- return true;
- };
-
+ auto InspectCallSiteForUB = [&](Instruction &I) {
+ // Check whether a callsite always cause UB or not
+
+ // Skip instructions that are already saved.
+ if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
+ return true;
+
+ // Check nonnull and noundef argument attribute violation for each
+ // callsite.
+ CallBase &CB = cast<CallBase>(I);
+ Function *Callee = CB.getCalledFunction();
+ if (!Callee)
+ return true;
+ for (unsigned idx = 0; idx < CB.getNumArgOperands(); idx++) {
+ // If current argument is known to be simplified to null pointer and the
+ // corresponding argument position is known to have nonnull attribute,
+ // the argument is poison. Furthermore, if the argument is poison and
+ // the position is known to have noundef attriubte, this callsite is
+ // considered UB.
+ if (idx >= Callee->arg_size())
+ break;
+ Value *ArgVal = CB.getArgOperand(idx);
+ if (!ArgVal)
+ continue;
+ // Here, we handle three cases.
+ // (1) Not having a value means it is dead. (we can replace the value
+ // with undef)
+ // (2) Simplified to undef. The argument violate noundef attriubte.
+ // (3) Simplified to null pointer where known to be nonnull.
+ // The argument is a poison value and violate noundef attribute.
+ IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
+ auto &NoUndefAA = A.getAAFor<AANoUndef>(*this, CalleeArgumentIRP,
+ /* TrackDependence */ false);
+ if (!NoUndefAA.isKnownNoUndef())
+ continue;
+ auto &ValueSimplifyAA = A.getAAFor<AAValueSimplify>(
+ *this, IRPosition::value(*ArgVal), /* TrackDependence */ false);
+ if (!ValueSimplifyAA.isKnown())
+ continue;
+ Optional<Value *> SimplifiedVal =
+ ValueSimplifyAA.getAssumedSimplifiedValue(A);
+ if (!SimplifiedVal.hasValue() ||
+ isa<UndefValue>(*SimplifiedVal.getValue())) {
+ KnownUBInsts.insert(&I);
+ continue;
+ }
+ if (!ArgVal->getType()->isPointerTy() ||
+ !isa<ConstantPointerNull>(*SimplifiedVal.getValue()))
+ continue;
+ auto &NonNullAA = A.getAAFor<AANonNull>(*this, CalleeArgumentIRP,
+ /* TrackDependence */ false);
+ if (NonNullAA.isKnownNonNull())
+ KnownUBInsts.insert(&I);
+ }
+ return true;
+ };
+
+ auto InspectReturnInstForUB =
+ [&](Value &V, const SmallSetVector<ReturnInst *, 4> RetInsts) {
+ // Check if a return instruction always cause UB or not
+ // Note: It is guaranteed that the returned position of the anchor
+ // scope has noundef attribute when this is called.
+ // We also ensure the return position is not "assumed dead"
+ // because the returned value was then potentially simplified to
+ // `undef` in AAReturnedValues without removing the `noundef`
+ // attribute yet.
+
+ // When the returned position has noundef attriubte, UB occur in the
+ // following cases.
+ // (1) Returned value is known to be undef.
+ // (2) The value is known to be a null pointer and the returned
+ // position has nonnull attribute (because the returned value is
+ // poison).
+ bool FoundUB = false;
+ if (isa<UndefValue>(V)) {
+ FoundUB = true;
+ } else {
+ if (isa<ConstantPointerNull>(V)) {
+ auto &NonNullAA = A.getAAFor<AANonNull>(
+ *this, IRPosition::returned(*getAnchorScope()),
+ /* TrackDependence */ false);
+ if (NonNullAA.isKnownNonNull())
+ FoundUB = true;
+ }
+ }
+
+ if (FoundUB)
+ for (ReturnInst *RI : RetInsts)
+ KnownUBInsts.insert(RI);
+ return true;
+ };
+
A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
{Instruction::Load, Instruction::Store,
Instruction::AtomicCmpXchg,
@@ -2099,22 +2099,22 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
/* CheckBBLivenessOnly */ true);
A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br},
/* CheckBBLivenessOnly */ true);
- A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this);
-
- // If the returned position of the anchor scope has noundef attriubte, check
- // all returned instructions.
- if (!getAnchorScope()->getReturnType()->isVoidTy()) {
- const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
- if (!A.isAssumedDead(ReturnIRP, this, nullptr)) {
- auto &RetPosNoUndefAA =
- A.getAAFor<AANoUndef>(*this, ReturnIRP,
- /* TrackDependence */ false);
- if (RetPosNoUndefAA.isKnownNoUndef())
- A.checkForAllReturnedValuesAndReturnInsts(InspectReturnInstForUB,
- *this);
- }
- }
-
+ A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this);
+
+ // If the returned position of the anchor scope has noundef attriubte, check
+ // all returned instructions.
+ if (!getAnchorScope()->getReturnType()->isVoidTy()) {
+ const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
+ if (!A.isAssumedDead(ReturnIRP, this, nullptr)) {
+ auto &RetPosNoUndefAA =
+ A.getAAFor<AANoUndef>(*this, ReturnIRP,
+ /* TrackDependence */ false);
+ if (RetPosNoUndefAA.isKnownNoUndef())
+ A.checkForAllReturnedValuesAndReturnInsts(InspectReturnInstForUB,
+ *this);
+ }
+ }
+
if (NoUBPrevSize != AssumedNoUBInsts.size() ||
UBPrevSize != KnownUBInsts.size())
return ChangeStatus::CHANGED;
@@ -2282,7 +2282,7 @@ struct AAWillReturnImpl : public AAWillReturn {
AAWillReturn::initialize(A);
Function *F = getAnchorScope();
- if (!F || F->isDeclaration() || mayContainUnboundedCycle(*F, A))
+ if (!F || F->isDeclaration() || mayContainUnboundedCycle(*F, A))
indicatePessimisticFixpoint();
}
@@ -2326,9 +2326,9 @@ struct AAWillReturnCallSite final : AAWillReturnImpl {
/// See AbstractAttribute::initialize(...).
void initialize(Attributor &A) override {
- AAWillReturn::initialize(A);
+ AAWillReturn::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || !A.isFunctionIPOAmendable(*F))
+ if (!F || !A.isFunctionIPOAmendable(*F))
indicatePessimisticFixpoint();
}
@@ -2341,7 +2341,7 @@ struct AAWillReturnCallSite final : AAWillReturnImpl {
Function *F = getAssociatedFunction();
const IRPosition &FnPos = IRPosition::function(*F);
auto &FnAA = A.getAAFor<AAWillReturn>(*this, FnPos);
- return clampStateAndIndicateChange(getState(), FnAA.getState());
+ return clampStateAndIndicateChange(getState(), FnAA.getState());
}
/// See AbstractAttribute::trackStatistics()
@@ -2501,7 +2501,7 @@ struct AANoAliasCallSiteArgument final : AANoAliasImpl {
void initialize(Attributor &A) override {
// See callsite argument attribute and callee argument attribute.
const auto &CB = cast<CallBase>(getAnchorValue());
- if (CB.paramHasAttr(getCallSiteArgNo(), Attribute::NoAlias))
+ if (CB.paramHasAttr(getCallSiteArgNo(), Attribute::NoAlias))
indicateOptimisticFixpoint();
Value &Val = getAssociatedValue();
if (isa<ConstantPointerNull>(Val) &&
@@ -2516,7 +2516,7 @@ struct AANoAliasCallSiteArgument final : AANoAliasImpl {
const AAMemoryBehavior &MemBehaviorAA,
const CallBase &CB, unsigned OtherArgNo) {
// We do not need to worry about aliasing with the underlying IRP.
- if (this->getCalleeArgNo() == (int)OtherArgNo)
+ if (this->getCalleeArgNo() == (int)OtherArgNo)
return false;
// If it is not a pointer or pointer vector we do not alias.
@@ -2578,7 +2578,7 @@ struct AANoAliasCallSiteArgument final : AANoAliasImpl {
A.recordDependence(NoAliasAA, *this, DepClassTy::OPTIONAL);
const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
- const Function *ScopeFn = VIRP.getAnchorScope();
+ const Function *ScopeFn = VIRP.getAnchorScope();
auto &NoCaptureAA =
A.getAAFor<AANoCapture>(*this, VIRP, /* TrackDependence */ false);
// Check whether the value is captured in the scope using AANoCapture.
@@ -2587,18 +2587,18 @@ struct AANoAliasCallSiteArgument final : AANoAliasImpl {
auto UsePred = [&](const Use &U, bool &Follow) -> bool {
Instruction *UserI = cast<Instruction>(U.getUser());
- // If UserI is the curr instruction and there is a single potential use of
- // the value in UserI we allow the use.
- // TODO: We should inspect the operands and allow those that cannot alias
- // with the value.
- if (UserI == getCtxI() && UserI->getNumOperands() == 1)
+ // If UserI is the curr instruction and there is a single potential use of
+ // the value in UserI we allow the use.
+ // TODO: We should inspect the operands and allow those that cannot alias
+ // with the value.
+ if (UserI == getCtxI() && UserI->getNumOperands() == 1)
return true;
if (ScopeFn) {
const auto &ReachabilityAA =
A.getAAFor<AAReachability>(*this, IRPosition::function(*ScopeFn));
- if (!ReachabilityAA.isAssumedReachable(A, *UserI, *getCtxI()))
+ if (!ReachabilityAA.isAssumedReachable(A, *UserI, *getCtxI()))
return true;
if (auto *CB = dyn_cast<CallBase>(UserI)) {
@@ -2684,14 +2684,14 @@ struct AANoAliasReturned final : AANoAliasImpl {
AANoAliasReturned(const IRPosition &IRP, Attributor &A)
: AANoAliasImpl(IRP, A) {}
- /// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override {
- AANoAliasImpl::initialize(A);
- Function *F = getAssociatedFunction();
- if (!F || F->isDeclaration())
- indicatePessimisticFixpoint();
- }
-
+ /// See AbstractAttribute::initialize(...).
+ void initialize(Attributor &A) override {
+ AANoAliasImpl::initialize(A);
+ Function *F = getAssociatedFunction();
+ if (!F || F->isDeclaration())
+ indicatePessimisticFixpoint();
+ }
+
/// See AbstractAttribute::updateImpl(...).
virtual ChangeStatus updateImpl(Attributor &A) override {
@@ -2733,7 +2733,7 @@ struct AANoAliasCallSiteReturned final : AANoAliasImpl {
void initialize(Attributor &A) override {
AANoAliasImpl::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || F->isDeclaration())
+ if (!F || F->isDeclaration())
indicatePessimisticFixpoint();
}
@@ -2746,7 +2746,7 @@ struct AANoAliasCallSiteReturned final : AANoAliasImpl {
Function *F = getAssociatedFunction();
const IRPosition &FnPos = IRPosition::returned(*F);
auto &FnAA = A.getAAFor<AANoAlias>(*this, FnPos);
- return clampStateAndIndicateChange(getState(), FnAA.getState());
+ return clampStateAndIndicateChange(getState(), FnAA.getState());
}
/// See AbstractAttribute::trackStatistics()
@@ -2936,13 +2936,13 @@ struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
return indicatePessimisticFixpoint();
const IRPosition &ArgPos = IRPosition::argument(*Arg);
auto &ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos);
- return clampStateAndIndicateChange(getState(), ArgAA.getState());
+ return clampStateAndIndicateChange(getState(), ArgAA.getState());
}
/// See AbstractAttribute::manifest(...).
ChangeStatus manifest(Attributor &A) override {
CallBase &CB = cast<CallBase>(getAnchorValue());
- Use &U = CB.getArgOperandUse(getCallSiteArgNo());
+ Use &U = CB.getArgOperandUse(getCallSiteArgNo());
assert(!isa<UndefValue>(U.get()) &&
"Expected undef values to be filtered out!");
UndefValue &UV = *UndefValue::get(U->getType());
@@ -3057,14 +3057,14 @@ struct AAIsDeadFunction : public AAIsDead {
void initialize(Attributor &A) override {
const Function *F = getAnchorScope();
if (F && !F->isDeclaration()) {
- // We only want to compute liveness once. If the function is not part of
- // the SCC, skip it.
- if (A.isRunOn(*const_cast<Function *>(F))) {
- ToBeExploredFrom.insert(&F->getEntryBlock().front());
- assumeLive(A, F->getEntryBlock());
- } else {
- indicatePessimisticFixpoint();
- }
+ // We only want to compute liveness once. If the function is not part of
+ // the SCC, skip it.
+ if (A.isRunOn(*const_cast<Function *>(F))) {
+ ToBeExploredFrom.insert(&F->getEntryBlock().front());
+ assumeLive(A, F->getEntryBlock());
+ } else {
+ indicatePessimisticFixpoint();
+ }
}
}
@@ -3127,10 +3127,10 @@ struct AAIsDeadFunction : public AAIsDead {
/// See AbstractAttribute::updateImpl(...).
ChangeStatus updateImpl(Attributor &A) override;
- bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
- return !AssumedLiveEdges.count(std::make_pair(From, To));
- }
-
+ bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
+ return !AssumedLiveEdges.count(std::make_pair(From, To));
+ }
+
/// See AbstractAttribute::trackStatistics()
void trackStatistics() const override {}
@@ -3208,9 +3208,9 @@ struct AAIsDeadFunction : public AAIsDead {
/// Collection of instructions that are known to not transfer control.
SmallSetVector<const Instruction *, 8> KnownDeadEnds;
- /// Collection of all assumed live edges
- DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges;
-
+ /// Collection of all assumed live edges
+ DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges;
+
/// Collection of all assumed live BasicBlocks.
DenseSet<const BasicBlock *> AssumedLiveBlocks;
};
@@ -3326,23 +3326,23 @@ ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
const Instruction *I = Worklist.pop_back_val();
LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
- // Fast forward for uninteresting instructions. We could look for UB here
- // though.
- while (!I->isTerminator() && !isa<CallBase>(I)) {
- Change = ChangeStatus::CHANGED;
- I = I->getNextNode();
- }
-
+ // Fast forward for uninteresting instructions. We could look for UB here
+ // though.
+ while (!I->isTerminator() && !isa<CallBase>(I)) {
+ Change = ChangeStatus::CHANGED;
+ I = I->getNextNode();
+ }
+
AliveSuccessors.clear();
bool UsedAssumedInformation = false;
switch (I->getOpcode()) {
// TODO: look for (assumed) UB to backwards propagate "deadness".
default:
- assert(I->isTerminator() &&
- "Expected non-terminators to be handled already!");
- for (const BasicBlock *SuccBB : successors(I->getParent()))
- AliveSuccessors.push_back(&SuccBB->front());
+ assert(I->isTerminator() &&
+ "Expected non-terminators to be handled already!");
+ for (const BasicBlock *SuccBB : successors(I->getParent()))
+ AliveSuccessors.push_back(&SuccBB->front());
break;
case Instruction::Call:
UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
@@ -3381,9 +3381,9 @@ ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
"Non-terminator expected to have a single successor!");
Worklist.push_back(AliveSuccessor);
} else {
- // record the assumed live edge
- AssumedLiveEdges.insert(
- std::make_pair(I->getParent(), AliveSuccessor->getParent()));
+ // record the assumed live edge
+ AssumedLiveEdges.insert(
+ std::make_pair(I->getParent(), AliveSuccessor->getParent()));
if (assumeLive(A, *AliveSuccessor->getParent()))
Worklist.push_back(AliveSuccessor);
}
@@ -3576,7 +3576,7 @@ struct AADereferenceableFloating : AADereferenceableImpl {
DerefBytes = Base->getPointerDereferenceableBytes(DL, CanBeNull);
T.GlobalState.indicatePessimisticFixpoint();
} else {
- const DerefState &DS = AA.getState();
+ const DerefState &DS = AA.getState();
DerefBytes = DS.DerefBytesState.getAssumed();
T.GlobalState &= DS.GlobalState;
}
@@ -3852,27 +3852,27 @@ struct AAAlignFloating : AAAlignImpl {
AAAlign::StateType &T, bool Stripped) -> bool {
const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V));
if (!Stripped && this == &AA) {
- int64_t Offset;
- unsigned Alignment = 1;
- if (const Value *Base =
- GetPointerBaseWithConstantOffset(&V, Offset, DL)) {
- Align PA = Base->getPointerAlignment(DL);
- // BasePointerAddr + Offset = Alignment * Q for some integer Q.
- // So we can say that the maximum power of two which is a divisor of
- // gcd(Offset, Alignment) is an alignment.
-
- uint32_t gcd = greatestCommonDivisor(uint32_t(abs((int32_t)Offset)),
- uint32_t(PA.value()));
- Alignment = llvm::PowerOf2Floor(gcd);
- } else {
- Alignment = V.getPointerAlignment(DL).value();
- }
+ int64_t Offset;
+ unsigned Alignment = 1;
+ if (const Value *Base =
+ GetPointerBaseWithConstantOffset(&V, Offset, DL)) {
+ Align PA = Base->getPointerAlignment(DL);
+ // BasePointerAddr + Offset = Alignment * Q for some integer Q.
+ // So we can say that the maximum power of two which is a divisor of
+ // gcd(Offset, Alignment) is an alignment.
+
+ uint32_t gcd = greatestCommonDivisor(uint32_t(abs((int32_t)Offset)),
+ uint32_t(PA.value()));
+ Alignment = llvm::PowerOf2Floor(gcd);
+ } else {
+ Alignment = V.getPointerAlignment(DL).value();
+ }
// Use only IR information if we did not strip anything.
- T.takeKnownMaximum(Alignment);
+ T.takeKnownMaximum(Alignment);
T.indicatePessimisticFixpoint();
} else {
// Use abstract attribute information.
- const AAAlign::StateType &DS = AA.getState();
+ const AAAlign::StateType &DS = AA.getState();
T ^= DS;
}
return T.isValidState();
@@ -3895,17 +3895,17 @@ struct AAAlignFloating : AAAlignImpl {
/// Align attribute for function return value.
struct AAAlignReturned final
: AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
- using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>;
- AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
-
- /// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override {
- Base::initialize(A);
- Function *F = getAssociatedFunction();
- if (!F || F->isDeclaration())
- indicatePessimisticFixpoint();
- }
-
+ using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>;
+ AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
+
+ /// See AbstractAttribute::initialize(...).
+ void initialize(Attributor &A) override {
+ Base::initialize(A);
+ Function *F = getAssociatedFunction();
+ if (!F || F->isDeclaration())
+ indicatePessimisticFixpoint();
+ }
+
/// See AbstractAttribute::trackStatistics()
void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
};
@@ -3978,7 +3978,7 @@ struct AAAlignCallSiteReturned final
void initialize(Attributor &A) override {
Base::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || F->isDeclaration())
+ if (!F || F->isDeclaration())
indicatePessimisticFixpoint();
}
@@ -3994,7 +3994,7 @@ struct AANoReturnImpl : public AANoReturn {
void initialize(Attributor &A) override {
AANoReturn::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || F->isDeclaration())
+ if (!F || F->isDeclaration())
indicatePessimisticFixpoint();
}
@@ -4026,17 +4026,17 @@ struct AANoReturnCallSite final : AANoReturnImpl {
AANoReturnCallSite(const IRPosition &IRP, Attributor &A)
: AANoReturnImpl(IRP, A) {}
- /// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override {
- AANoReturnImpl::initialize(A);
- if (Function *F = getAssociatedFunction()) {
- const IRPosition &FnPos = IRPosition::function(*F);
- auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
- if (!FnAA.isAssumedNoReturn())
- indicatePessimisticFixpoint();
- }
- }
-
+ /// See AbstractAttribute::initialize(...).
+ void initialize(Attributor &A) override {
+ AANoReturnImpl::initialize(A);
+ if (Function *F = getAssociatedFunction()) {
+ const IRPosition &FnPos = IRPosition::function(*F);
+ auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
+ if (!FnAA.isAssumedNoReturn())
+ indicatePessimisticFixpoint();
+ }
+ }
+
/// See AbstractAttribute::updateImpl(...).
ChangeStatus updateImpl(Attributor &A) override {
// TODO: Once we have call site specific value information we can provide
@@ -4046,7 +4046,7 @@ struct AANoReturnCallSite final : AANoReturnImpl {
Function *F = getAssociatedFunction();
const IRPosition &FnPos = IRPosition::function(*F);
auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
- return clampStateAndIndicateChange(getState(), FnAA.getState());
+ return clampStateAndIndicateChange(getState(), FnAA.getState());
}
/// See AbstractAttribute::trackStatistics()
@@ -4079,8 +4079,8 @@ struct AANoCaptureImpl : public AANoCapture {
return;
}
- const Function *F =
- isArgumentPosition() ? getAssociatedFunction() : AnchorScope;
+ const Function *F =
+ isArgumentPosition() ? getAssociatedFunction() : AnchorScope;
// Check what state the associated function can actually capture.
if (F)
@@ -4099,7 +4099,7 @@ struct AANoCaptureImpl : public AANoCapture {
if (!isAssumedNoCaptureMaybeReturned())
return;
- if (isArgumentPosition()) {
+ if (isArgumentPosition()) {
if (isAssumedNoCapture())
Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture));
else if (ManifestInternal)
@@ -4135,7 +4135,7 @@ struct AANoCaptureImpl : public AANoCapture {
State.addKnownBits(NOT_CAPTURED_IN_RET);
// Check existing "returned" attributes.
- int ArgNo = IRP.getCalleeArgNo();
+ int ArgNo = IRP.getCalleeArgNo();
if (F.doesNotThrow() && ArgNo >= 0) {
for (unsigned u = 0, e = F.arg_size(); u < e; ++u)
if (F.hasParamAttribute(u, Attribute::Returned)) {
@@ -4311,13 +4311,13 @@ private:
ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
const IRPosition &IRP = getIRPosition();
- const Value *V = isArgumentPosition() ? IRP.getAssociatedArgument()
- : &IRP.getAssociatedValue();
+ const Value *V = isArgumentPosition() ? IRP.getAssociatedArgument()
+ : &IRP.getAssociatedValue();
if (!V)
return indicatePessimisticFixpoint();
const Function *F =
- isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
+ isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
assert(F && "Expected a function!");
const IRPosition &FnPos = IRPosition::function(*F);
const auto &IsDeadAA =
@@ -4434,7 +4434,7 @@ struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
return indicatePessimisticFixpoint();
const IRPosition &ArgPos = IRPosition::argument(*Arg);
auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos);
- return clampStateAndIndicateChange(getState(), ArgAA.getState());
+ return clampStateAndIndicateChange(getState(), ArgAA.getState());
}
/// See AbstractAttribute::trackStatistics()
@@ -4550,37 +4550,37 @@ struct AAValueSimplifyImpl : AAValueSimplify {
return true;
}
- /// Returns a candidate is found or not
- template <typename AAType> bool askSimplifiedValueFor(Attributor &A) {
+ /// Returns a candidate is found or not
+ template <typename AAType> bool askSimplifiedValueFor(Attributor &A) {
if (!getAssociatedValue().getType()->isIntegerTy())
return false;
- const auto &AA =
- A.getAAFor<AAType>(*this, getIRPosition(), /* TrackDependence */ false);
+ const auto &AA =
+ A.getAAFor<AAType>(*this, getIRPosition(), /* TrackDependence */ false);
+
+ Optional<ConstantInt *> COpt = AA.getAssumedConstantInt(A);
- Optional<ConstantInt *> COpt = AA.getAssumedConstantInt(A);
-
- if (!COpt.hasValue()) {
+ if (!COpt.hasValue()) {
SimplifiedAssociatedValue = llvm::None;
- A.recordDependence(AA, *this, DepClassTy::OPTIONAL);
- return true;
- }
- if (auto *C = COpt.getValue()) {
- SimplifiedAssociatedValue = C;
- A.recordDependence(AA, *this, DepClassTy::OPTIONAL);
- return true;
- }
- return false;
- }
-
- bool askSimplifiedValueForOtherAAs(Attributor &A) {
- if (askSimplifiedValueFor<AAValueConstantRange>(A))
- return true;
- if (askSimplifiedValueFor<AAPotentialValues>(A))
- return true;
- return false;
- }
-
+ A.recordDependence(AA, *this, DepClassTy::OPTIONAL);
+ return true;
+ }
+ if (auto *C = COpt.getValue()) {
+ SimplifiedAssociatedValue = C;
+ A.recordDependence(AA, *this, DepClassTy::OPTIONAL);
+ return true;
+ }
+ return false;
+ }
+
+ bool askSimplifiedValueForOtherAAs(Attributor &A) {
+ if (askSimplifiedValueFor<AAValueConstantRange>(A))
+ return true;
+ if (askSimplifiedValueFor<AAPotentialValues>(A))
+ return true;
+ return false;
+ }
+
/// See AbstractAttribute::manifest(...).
ChangeStatus manifest(Attributor &A) override {
ChangeStatus Changed = ChangeStatus::UNCHANGED;
@@ -4663,7 +4663,7 @@ struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
auto PredForCallSite = [&](AbstractCallSite ACS) {
const IRPosition &ACSArgPos =
- IRPosition::callsite_argument(ACS, getCallSiteArgNo());
+ IRPosition::callsite_argument(ACS, getCallSiteArgNo());
// Check if a coresponding argument was found or if it is on not
// associated (which can happen for callback calls).
if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
@@ -4685,7 +4685,7 @@ struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
bool AllCallSitesKnown;
if (!A.checkForAllCallSites(PredForCallSite, *this, true,
AllCallSitesKnown))
- if (!askSimplifiedValueForOtherAAs(A))
+ if (!askSimplifiedValueForOtherAAs(A))
return indicatePessimisticFixpoint();
// If a candicate was found in this update, return CHANGED.
@@ -4713,7 +4713,7 @@ struct AAValueSimplifyReturned : AAValueSimplifyImpl {
};
if (!A.checkForAllReturnedValues(PredForReturned, *this))
- if (!askSimplifiedValueForOtherAAs(A))
+ if (!askSimplifiedValueForOtherAAs(A))
return indicatePessimisticFixpoint();
// If a candicate was found in this update, return CHANGED.
@@ -4782,76 +4782,76 @@ struct AAValueSimplifyFloating : AAValueSimplifyImpl {
indicatePessimisticFixpoint();
}
- /// Check if \p ICmp is an equality comparison (==/!=) with at least one
- /// nullptr. If so, try to simplify it using AANonNull on the other operand.
- /// Return true if successful, in that case SimplifiedAssociatedValue will be
- /// updated and \p Changed is set appropriately.
- bool checkForNullPtrCompare(Attributor &A, ICmpInst *ICmp,
- ChangeStatus &Changed) {
- if (!ICmp)
- return false;
- if (!ICmp->isEquality())
- return false;
-
- // This is a comparison with == or !-. We check for nullptr now.
- bool Op0IsNull = isa<ConstantPointerNull>(ICmp->getOperand(0));
- bool Op1IsNull = isa<ConstantPointerNull>(ICmp->getOperand(1));
- if (!Op0IsNull && !Op1IsNull)
- return false;
-
- LLVMContext &Ctx = ICmp->getContext();
- // Check for `nullptr ==/!= nullptr` first:
- if (Op0IsNull && Op1IsNull) {
- Value *NewVal = ConstantInt::get(
- Type::getInt1Ty(Ctx), ICmp->getPredicate() == CmpInst::ICMP_EQ);
- assert(!SimplifiedAssociatedValue.hasValue() &&
- "Did not expect non-fixed value for constant comparison");
- SimplifiedAssociatedValue = NewVal;
- indicateOptimisticFixpoint();
- Changed = ChangeStatus::CHANGED;
- return true;
- }
-
- // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
- // non-nullptr operand and if we assume it's non-null we can conclude the
- // result of the comparison.
- assert((Op0IsNull || Op1IsNull) &&
- "Expected nullptr versus non-nullptr comparison at this point");
-
- // The index is the operand that we assume is not null.
- unsigned PtrIdx = Op0IsNull;
- auto &PtrNonNullAA = A.getAAFor<AANonNull>(
- *this, IRPosition::value(*ICmp->getOperand(PtrIdx)));
- if (!PtrNonNullAA.isAssumedNonNull())
- return false;
-
- // The new value depends on the predicate, true for != and false for ==.
- Value *NewVal = ConstantInt::get(Type::getInt1Ty(Ctx),
- ICmp->getPredicate() == CmpInst::ICMP_NE);
-
- assert((!SimplifiedAssociatedValue.hasValue() ||
- SimplifiedAssociatedValue == NewVal) &&
- "Did not expect to change value for zero-comparison");
-
- bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
- SimplifiedAssociatedValue = NewVal;
-
- if (PtrNonNullAA.isKnownNonNull())
- indicateOptimisticFixpoint();
-
- Changed = HasValueBefore ? ChangeStatus::UNCHANGED : ChangeStatus ::CHANGED;
- return true;
- }
-
+ /// Check if \p ICmp is an equality comparison (==/!=) with at least one
+ /// nullptr. If so, try to simplify it using AANonNull on the other operand.
+ /// Return true if successful, in that case SimplifiedAssociatedValue will be
+ /// updated and \p Changed is set appropriately.
+ bool checkForNullPtrCompare(Attributor &A, ICmpInst *ICmp,
+ ChangeStatus &Changed) {
+ if (!ICmp)
+ return false;
+ if (!ICmp->isEquality())
+ return false;
+
+ // This is a comparison with == or !-. We check for nullptr now.
+ bool Op0IsNull = isa<ConstantPointerNull>(ICmp->getOperand(0));
+ bool Op1IsNull = isa<ConstantPointerNull>(ICmp->getOperand(1));
+ if (!Op0IsNull && !Op1IsNull)
+ return false;
+
+ LLVMContext &Ctx = ICmp->getContext();
+ // Check for `nullptr ==/!= nullptr` first:
+ if (Op0IsNull && Op1IsNull) {
+ Value *NewVal = ConstantInt::get(
+ Type::getInt1Ty(Ctx), ICmp->getPredicate() == CmpInst::ICMP_EQ);
+ assert(!SimplifiedAssociatedValue.hasValue() &&
+ "Did not expect non-fixed value for constant comparison");
+ SimplifiedAssociatedValue = NewVal;
+ indicateOptimisticFixpoint();
+ Changed = ChangeStatus::CHANGED;
+ return true;
+ }
+
+ // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
+ // non-nullptr operand and if we assume it's non-null we can conclude the
+ // result of the comparison.
+ assert((Op0IsNull || Op1IsNull) &&
+ "Expected nullptr versus non-nullptr comparison at this point");
+
+ // The index is the operand that we assume is not null.
+ unsigned PtrIdx = Op0IsNull;
+ auto &PtrNonNullAA = A.getAAFor<AANonNull>(
+ *this, IRPosition::value(*ICmp->getOperand(PtrIdx)));
+ if (!PtrNonNullAA.isAssumedNonNull())
+ return false;
+
+ // The new value depends on the predicate, true for != and false for ==.
+ Value *NewVal = ConstantInt::get(Type::getInt1Ty(Ctx),
+ ICmp->getPredicate() == CmpInst::ICMP_NE);
+
+ assert((!SimplifiedAssociatedValue.hasValue() ||
+ SimplifiedAssociatedValue == NewVal) &&
+ "Did not expect to change value for zero-comparison");
+
+ bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
+ SimplifiedAssociatedValue = NewVal;
+
+ if (PtrNonNullAA.isKnownNonNull())
+ indicateOptimisticFixpoint();
+
+ Changed = HasValueBefore ? ChangeStatus::UNCHANGED : ChangeStatus ::CHANGED;
+ return true;
+ }
+
/// See AbstractAttribute::updateImpl(...).
ChangeStatus updateImpl(Attributor &A) override {
bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
- ChangeStatus Changed;
- if (checkForNullPtrCompare(A, dyn_cast<ICmpInst>(&getAnchorValue()),
- Changed))
- return Changed;
-
+ ChangeStatus Changed;
+ if (checkForNullPtrCompare(A, dyn_cast<ICmpInst>(&getAnchorValue()),
+ Changed))
+ return Changed;
+
auto VisitValueCB = [&](Value &V, const Instruction *CtxI, bool &,
bool Stripped) -> bool {
auto &AA = A.getAAFor<AAValueSimplify>(*this, IRPosition::value(V));
@@ -4869,7 +4869,7 @@ struct AAValueSimplifyFloating : AAValueSimplifyImpl {
if (!genericValueTraversal<AAValueSimplify, bool>(
A, getIRPosition(), *this, Dummy, VisitValueCB, getCtxI(),
/* UseValueSimplify */ false))
- if (!askSimplifiedValueForOtherAAs(A))
+ if (!askSimplifiedValueForOtherAAs(A))
return indicatePessimisticFixpoint();
// If a candicate was found in this update, return CHANGED.
@@ -4944,8 +4944,8 @@ struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
? dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())
: UndefValue::get(V.getType());
if (C) {
- Use &U = cast<CallBase>(&getAnchorValue())
- ->getArgOperandUse(getCallSiteArgNo());
+ Use &U = cast<CallBase>(&getAnchorValue())
+ ->getArgOperandUse(getCallSiteArgNo());
// We can replace the AssociatedValue with the constant.
if (&V != C && V.getType() == C->getType()) {
if (A.changeUseAfterManifest(U, *C))
@@ -5264,7 +5264,7 @@ struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
return getAssociatedValue().getType()->getPointerElementType();
Optional<Type *> Ty;
- unsigned ArgNo = getIRPosition().getCallSiteArgNo();
+ unsigned ArgNo = getIRPosition().getCallSiteArgNo();
// Make sure the associated call site argument has the same type at all call
// sites and it is an allocation we know is safe to privatize, for now that
@@ -5527,9 +5527,9 @@ struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
new StoreInst(F.getArg(ArgNo + u), Ptr, &IP);
}
} else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
- Type *PointeeTy = PrivArrayType->getElementType();
- Type *PointeePtrTy = PointeeTy->getPointerTo();
- uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
+ Type *PointeeTy = PrivArrayType->getElementType();
+ Type *PointeePtrTy = PointeeTy->getPointerTo();
+ uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
Value *Ptr =
constructPointer(PointeePtrTy, &Base, u * PointeeTySize, IRB, DL);
@@ -5575,7 +5575,7 @@ struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
Value *Ptr =
constructPointer(PointeePtrTy, Base, u * PointeeTySize, IRB, DL);
- LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP);
+ LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP);
L->setAlignment(Alignment);
ReplacementValues.push_back(L);
}
@@ -5619,14 +5619,14 @@ struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
Function &ReplacementFn, Function::arg_iterator ArgIt) {
BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
Instruction *IP = &*EntryBB.getFirstInsertionPt();
- Instruction *AI = new AllocaInst(PrivatizableType.getValue(), 0,
- Arg->getName() + ".priv", IP);
+ Instruction *AI = new AllocaInst(PrivatizableType.getValue(), 0,
+ Arg->getName() + ".priv", IP);
createInitialization(PrivatizableType.getValue(), *AI, ReplacementFn,
ArgIt->getArgNo(), *IP);
-
- if (AI->getType() != Arg->getType())
- AI =
- BitCastInst::CreateBitOrPointerCast(AI, Arg->getType(), "", IP);
+
+ if (AI->getType() != Arg->getType())
+ AI =
+ BitCastInst::CreateBitOrPointerCast(AI, Arg->getType(), "", IP);
Arg->replaceAllUsesWith(AI);
for (CallInst *CI : TailCalls)
@@ -5685,7 +5685,7 @@ struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
/// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
Optional<Type *> identifyPrivatizableType(Attributor &A) override {
- Value *Obj = getUnderlyingObject(&getAssociatedValue());
+ Value *Obj = getUnderlyingObject(&getAssociatedValue());
if (!Obj) {
LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
return nullptr;
@@ -5805,7 +5805,7 @@ struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
void initialize(Attributor &A) override {
intersectAssumedBits(BEST_STATE);
getKnownStateFromValue(getIRPosition(), getState());
- AAMemoryBehavior::initialize(A);
+ AAMemoryBehavior::initialize(A);
}
/// Return the memory behavior information encoded in the IR for \p IRP.
@@ -5900,7 +5900,7 @@ struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
/// See AbstractAttribute::initialize(...).
void initialize(Attributor &A) override {
AAMemoryBehaviorImpl::initialize(A);
- addUsesOf(A, getAssociatedValue());
+ addUsesOf(A, getAssociatedValue());
}
/// See AbstractAttribute::updateImpl(...).
@@ -5926,14 +5926,14 @@ private:
void analyzeUseIn(Attributor &A, const Use *U, const Instruction *UserI);
protected:
- /// Add the uses of \p V to the `Uses` set we look at during the update step.
- void addUsesOf(Attributor &A, const Value &V);
-
+ /// Add the uses of \p V to the `Uses` set we look at during the update step.
+ void addUsesOf(Attributor &A, const Value &V);
+
/// Container for (transitive) uses of the associated argument.
- SmallVector<const Use *, 8> Uses;
-
- /// Set to remember the uses we already traversed.
- SmallPtrSet<const Use *, 8> Visited;
+ SmallVector<const Use *, 8> Uses;
+
+ /// Set to remember the uses we already traversed.
+ SmallPtrSet<const Use *, 8> Visited;
};
/// Memory behavior attribute for function argument.
@@ -5958,7 +5958,7 @@ struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
if (!Arg || !A.isFunctionIPOAmendable(*(Arg->getParent()))) {
indicatePessimisticFixpoint();
} else {
- addUsesOf(A, *Arg);
+ addUsesOf(A, *Arg);
}
}
@@ -5993,21 +5993,21 @@ struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
/// See AbstractAttribute::initialize(...).
void initialize(Attributor &A) override {
- // If we don't have an associated attribute this is either a variadic call
- // or an indirect call, either way, nothing to do here.
- Argument *Arg = getAssociatedArgument();
- if (!Arg) {
- indicatePessimisticFixpoint();
- return;
- }
- if (Arg->hasByValAttr()) {
- addKnownBits(NO_WRITES);
- removeKnownBits(NO_READS);
- removeAssumedBits(NO_READS);
- }
+ // If we don't have an associated attribute this is either a variadic call
+ // or an indirect call, either way, nothing to do here.
+ Argument *Arg = getAssociatedArgument();
+ if (!Arg) {
+ indicatePessimisticFixpoint();
+ return;
+ }
+ if (Arg->hasByValAttr()) {
+ addKnownBits(NO_WRITES);
+ removeKnownBits(NO_READS);
+ removeAssumedBits(NO_READS);
+ }
AAMemoryBehaviorArgument::initialize(A);
- if (getAssociatedFunction()->isDeclaration())
- indicatePessimisticFixpoint();
+ if (getAssociatedFunction()->isDeclaration())
+ indicatePessimisticFixpoint();
}
/// See AbstractAttribute::updateImpl(...).
@@ -6019,7 +6019,7 @@ struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
Argument *Arg = getAssociatedArgument();
const IRPosition &ArgPos = IRPosition::argument(*Arg);
auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
- return clampStateAndIndicateChange(getState(), ArgAA.getState());
+ return clampStateAndIndicateChange(getState(), ArgAA.getState());
}
/// See AbstractAttribute::trackStatistics()
@@ -6038,14 +6038,14 @@ struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A)
: AAMemoryBehaviorFloating(IRP, A) {}
- /// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override {
- AAMemoryBehaviorImpl::initialize(A);
- Function *F = getAssociatedFunction();
- if (!F || F->isDeclaration())
- indicatePessimisticFixpoint();
- }
-
+ /// See AbstractAttribute::initialize(...).
+ void initialize(Attributor &A) override {
+ AAMemoryBehaviorImpl::initialize(A);
+ Function *F = getAssociatedFunction();
+ if (!F || F->isDeclaration())
+ indicatePessimisticFixpoint();
+ }
+
/// See AbstractAttribute::manifest(...).
ChangeStatus manifest(Attributor &A) override {
// We do not annotate returned values.
@@ -6095,7 +6095,7 @@ struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl {
void initialize(Attributor &A) override {
AAMemoryBehaviorImpl::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || F->isDeclaration())
+ if (!F || F->isDeclaration())
indicatePessimisticFixpoint();
}
@@ -6108,7 +6108,7 @@ struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl {
Function *F = getAssociatedFunction();
const IRPosition &FnPos = IRPosition::function(*F);
auto &FnAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
- return clampStateAndIndicateChange(getState(), FnAA.getState());
+ return clampStateAndIndicateChange(getState(), FnAA.getState());
}
/// See AbstractAttribute::trackStatistics()
@@ -6210,7 +6210,7 @@ ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
// Check if the users of UserI should also be visited.
if (followUsersOfUseIn(A, U, UserI))
- addUsesOf(A, *UserI);
+ addUsesOf(A, *UserI);
// If UserI might touch memory we analyze the use in detail.
if (UserI->mayReadOrWriteMemory())
@@ -6221,28 +6221,28 @@ ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
: ChangeStatus::UNCHANGED;
}
-void AAMemoryBehaviorFloating::addUsesOf(Attributor &A, const Value &V) {
- SmallVector<const Use *, 8> WL;
- for (const Use &U : V.uses())
- WL.push_back(&U);
-
- while (!WL.empty()) {
- const Use *U = WL.pop_back_val();
- if (!Visited.insert(U).second)
- continue;
-
- const Instruction *UserI = cast<Instruction>(U->getUser());
- if (UserI->mayReadOrWriteMemory()) {
- Uses.push_back(U);
- continue;
- }
- if (!followUsersOfUseIn(A, U, UserI))
- continue;
- for (const Use &UU : UserI->uses())
- WL.push_back(&UU);
- }
-}
-
+void AAMemoryBehaviorFloating::addUsesOf(Attributor &A, const Value &V) {
+ SmallVector<const Use *, 8> WL;
+ for (const Use &U : V.uses())
+ WL.push_back(&U);
+
+ while (!WL.empty()) {
+ const Use *U = WL.pop_back_val();
+ if (!Visited.insert(U).second)
+ continue;
+
+ const Instruction *UserI = cast<Instruction>(U->getUser());
+ if (UserI->mayReadOrWriteMemory()) {
+ Uses.push_back(U);
+ continue;
+ }
+ if (!followUsersOfUseIn(A, U, UserI))
+ continue;
+ for (const Use &UU : UserI->uses())
+ WL.push_back(&UU);
+ }
+}
+
bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use *U,
const Instruction *UserI) {
// The loaded value is unrelated to the pointer argument, no need to
@@ -6394,7 +6394,7 @@ struct AAMemoryLocationImpl : public AAMemoryLocation {
void initialize(Attributor &A) override {
intersectAssumedBits(BEST_STATE);
getKnownStateFromValue(A, getIRPosition(), getState());
- AAMemoryLocation::initialize(A);
+ AAMemoryLocation::initialize(A);
}
/// Return the memory behavior information encoded in the IR for \p IRP.
@@ -6557,13 +6557,13 @@ protected:
using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>;
AccessSet *AccessKind2Accesses[llvm::CTLog2<VALID_STATE>()];
- /// Categorize the pointer arguments of CB that might access memory in
- /// AccessedLoc and update the state and access map accordingly.
- void
- categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
- AAMemoryLocation::StateType &AccessedLocs,
- bool &Changed);
-
+ /// Categorize the pointer arguments of CB that might access memory in
+ /// AccessedLoc and update the state and access map accordingly.
+ void
+ categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
+ AAMemoryLocation::StateType &AccessedLocs,
+ bool &Changed);
+
/// Return the kind(s) of location that may be accessed by \p V.
AAMemoryLocation::MemoryLocationsKind
categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
@@ -6629,7 +6629,7 @@ void AAMemoryLocationImpl::categorizePtrValue(
auto VisitValueCB = [&](Value &V, const Instruction *,
AAMemoryLocation::StateType &T,
bool Stripped) -> bool {
- // TODO: recognize the TBAA used for constant accesses.
+ // TODO: recognize the TBAA used for constant accesses.
MemoryLocationsKind MLK = NO_LOCATIONS;
assert(!isa<GEPOperator>(V) && "GEPs should have been stripped.");
if (isa<UndefValue>(V))
@@ -6640,13 +6640,13 @@ void AAMemoryLocationImpl::categorizePtrValue(
else
MLK = NO_ARGUMENT_MEM;
} else if (auto *GV = dyn_cast<GlobalValue>(&V)) {
- // Reading constant memory is not treated as a read "effect" by the
- // function attr pass so we won't neither. Constants defined by TBAA are
- // similar. (We know we do not write it because it is constant.)
- if (auto *GVar = dyn_cast<GlobalVariable>(GV))
- if (GVar->isConstant())
- return true;
-
+ // Reading constant memory is not treated as a read "effect" by the
+ // function attr pass so we won't neither. Constants defined by TBAA are
+ // similar. (We know we do not write it because it is constant.)
+ if (auto *GVar = dyn_cast<GlobalVariable>(GV))
+ if (GVar->isConstant())
+ return true;
+
if (GV->hasLocalLinkage())
MLK = NO_GLOBAL_INTERNAL_MEM;
else
@@ -6693,30 +6693,30 @@ void AAMemoryLocationImpl::categorizePtrValue(
}
}
-void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
- Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs,
- bool &Changed) {
- for (unsigned ArgNo = 0, E = CB.getNumArgOperands(); ArgNo < E; ++ArgNo) {
-
- // Skip non-pointer arguments.
- const Value *ArgOp = CB.getArgOperand(ArgNo);
- if (!ArgOp->getType()->isPtrOrPtrVectorTy())
- continue;
-
- // Skip readnone arguments.
- const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo);
- const auto &ArgOpMemLocationAA = A.getAAFor<AAMemoryBehavior>(
- *this, ArgOpIRP, /* TrackDependence */ true, DepClassTy::OPTIONAL);
-
- if (ArgOpMemLocationAA.isAssumedReadNone())
- continue;
-
- // Categorize potentially accessed pointer arguments as if there was an
- // access instruction with them as pointer.
- categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed);
- }
-}
-
+void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
+ Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs,
+ bool &Changed) {
+ for (unsigned ArgNo = 0, E = CB.getNumArgOperands(); ArgNo < E; ++ArgNo) {
+
+ // Skip non-pointer arguments.
+ const Value *ArgOp = CB.getArgOperand(ArgNo);
+ if (!ArgOp->getType()->isPtrOrPtrVectorTy())
+ continue;
+
+ // Skip readnone arguments.
+ const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo);
+ const auto &ArgOpMemLocationAA = A.getAAFor<AAMemoryBehavior>(
+ *this, ArgOpIRP, /* TrackDependence */ true, DepClassTy::OPTIONAL);
+
+ if (ArgOpMemLocationAA.isAssumedReadNone())
+ continue;
+
+ // Categorize potentially accessed pointer arguments as if there was an
+ // access instruction with them as pointer.
+ categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed);
+ }
+}
+
AAMemoryLocation::MemoryLocationsKind
AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
bool &Changed) {
@@ -6778,8 +6778,8 @@ AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
// Now handle argument memory if it might be accessed.
bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM);
- if (HasArgAccesses)
- categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
+ if (HasArgAccesses)
+ categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
LLVM_DEBUG(
dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
@@ -6831,9 +6831,9 @@ struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
<< ": " << getMemoryLocationsAsStr(MLK) << "\n");
removeAssumedBits(inverseLocation(MLK, false, false));
- // Stop once only the valid bit set in the *not assumed location*, thus
- // once we don't actually exclude any memory locations in the state.
- return getAssumedNotAccessedLocation() != VALID_STATE;
+ // Stop once only the valid bit set in the *not assumed location*, thus
+ // once we don't actually exclude any memory locations in the state.
+ return getAssumedNotAccessedLocation() != VALID_STATE;
};
if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
@@ -6865,7 +6865,7 @@ struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
void initialize(Attributor &A) override {
AAMemoryLocationImpl::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || F->isDeclaration())
+ if (!F || F->isDeclaration())
indicatePessimisticFixpoint();
}
@@ -7075,13 +7075,13 @@ struct AAValueConstantRangeImpl : AAValueConstantRange {
auto &V = getAssociatedValue();
if (!AssumedConstantRange.isEmptySet() &&
!AssumedConstantRange.isSingleElement()) {
- if (Instruction *I = dyn_cast<Instruction>(&V)) {
- assert(I == getCtxI() && "Should not annotate an instruction which is "
- "not the context instruction");
+ if (Instruction *I = dyn_cast<Instruction>(&V)) {
+ assert(I == getCtxI() && "Should not annotate an instruction which is "
+ "not the context instruction");
if (isa<CallInst>(I) || isa<LoadInst>(I))
if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
Changed = ChangeStatus::CHANGED;
- }
+ }
}
return Changed;
@@ -7150,9 +7150,9 @@ struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
return;
}
- if (isa<CallBase>(&V))
- return;
-
+ if (isa<CallBase>(&V))
+ return;
+
if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
return;
// If it is a load instruction with range metadata, use it.
@@ -7390,641 +7390,641 @@ struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A)
: AAValueConstantRangeFloating(IRP, A) {}
- /// See AbstractAttribute::manifest()
- ChangeStatus manifest(Attributor &A) override {
- return ChangeStatus::UNCHANGED;
- }
-
+ /// See AbstractAttribute::manifest()
+ ChangeStatus manifest(Attributor &A) override {
+ return ChangeStatus::UNCHANGED;
+ }
+
/// See AbstractAttribute::trackStatistics()
void trackStatistics() const override {
STATS_DECLTRACK_CSARG_ATTR(value_range)
}
};
-
-/// ------------------ Potential Values Attribute -------------------------
-
-struct AAPotentialValuesImpl : AAPotentialValues {
- using StateType = PotentialConstantIntValuesState;
-
- AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A)
- : AAPotentialValues(IRP, A) {}
-
- /// See AbstractAttribute::getAsStr().
- const std::string getAsStr() const override {
- std::string Str;
- llvm::raw_string_ostream OS(Str);
- OS << getState();
- return OS.str();
- }
-
- /// See AbstractAttribute::updateImpl(...).
- ChangeStatus updateImpl(Attributor &A) override {
- return indicatePessimisticFixpoint();
- }
-};
-
-struct AAPotentialValuesArgument final
- : AAArgumentFromCallSiteArguments<AAPotentialValues, AAPotentialValuesImpl,
- PotentialConstantIntValuesState> {
- using Base =
- AAArgumentFromCallSiteArguments<AAPotentialValues, AAPotentialValuesImpl,
- PotentialConstantIntValuesState>;
- AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A)
- : Base(IRP, A) {}
-
- /// See AbstractAttribute::initialize(..).
- void initialize(Attributor &A) override {
- if (!getAnchorScope() || getAnchorScope()->isDeclaration()) {
- indicatePessimisticFixpoint();
- } else {
- Base::initialize(A);
- }
- }
-
- /// See AbstractAttribute::trackStatistics()
- void trackStatistics() const override {
- STATS_DECLTRACK_ARG_ATTR(potential_values)
- }
-};
-
-struct AAPotentialValuesReturned
- : AAReturnedFromReturnedValues<AAPotentialValues, AAPotentialValuesImpl> {
- using Base =
- AAReturnedFromReturnedValues<AAPotentialValues, AAPotentialValuesImpl>;
- AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A)
- : Base(IRP, A) {}
-
- /// See AbstractAttribute::trackStatistics()
- void trackStatistics() const override {
- STATS_DECLTRACK_FNRET_ATTR(potential_values)
- }
-};
-
-struct AAPotentialValuesFloating : AAPotentialValuesImpl {
- AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A)
- : AAPotentialValuesImpl(IRP, A) {}
-
- /// See AbstractAttribute::initialize(..).
- void initialize(Attributor &A) override {
- Value &V = getAssociatedValue();
-
- if (auto *C = dyn_cast<ConstantInt>(&V)) {
- unionAssumed(C->getValue());
- indicateOptimisticFixpoint();
- return;
- }
-
- if (isa<UndefValue>(&V)) {
- unionAssumedWithUndef();
- indicateOptimisticFixpoint();
- return;
- }
-
- if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
- return;
-
- if (isa<SelectInst>(V) || isa<PHINode>(V))
- return;
-
- indicatePessimisticFixpoint();
-
- LLVM_DEBUG(dbgs() << "[AAPotentialValues] We give up: "
- << getAssociatedValue() << "\n");
- }
-
- static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
- const APInt &RHS) {
- ICmpInst::Predicate Pred = ICI->getPredicate();
- switch (Pred) {
- case ICmpInst::ICMP_UGT:
- return LHS.ugt(RHS);
- case ICmpInst::ICMP_SGT:
- return LHS.sgt(RHS);
- case ICmpInst::ICMP_EQ:
- return LHS.eq(RHS);
- case ICmpInst::ICMP_UGE:
- return LHS.uge(RHS);
- case ICmpInst::ICMP_SGE:
- return LHS.sge(RHS);
- case ICmpInst::ICMP_ULT:
- return LHS.ult(RHS);
- case ICmpInst::ICMP_SLT:
- return LHS.slt(RHS);
- case ICmpInst::ICMP_NE:
- return LHS.ne(RHS);
- case ICmpInst::ICMP_ULE:
- return LHS.ule(RHS);
- case ICmpInst::ICMP_SLE:
- return LHS.sle(RHS);
- default:
- llvm_unreachable("Invalid ICmp predicate!");
- }
- }
-
- static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
- uint32_t ResultBitWidth) {
- Instruction::CastOps CastOp = CI->getOpcode();
- switch (CastOp) {
- default:
- llvm_unreachable("unsupported or not integer cast");
- case Instruction::Trunc:
- return Src.trunc(ResultBitWidth);
- case Instruction::SExt:
- return Src.sext(ResultBitWidth);
- case Instruction::ZExt:
- return Src.zext(ResultBitWidth);
- case Instruction::BitCast:
- return Src;
- }
- }
-
- static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
- const APInt &LHS, const APInt &RHS,
- bool &SkipOperation, bool &Unsupported) {
- Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
- // Unsupported is set to true when the binary operator is not supported.
- // SkipOperation is set to true when UB occur with the given operand pair
- // (LHS, RHS).
- // TODO: we should look at nsw and nuw keywords to handle operations
- // that create poison or undef value.
- switch (BinOpcode) {
- default:
- Unsupported = true;
- return LHS;
- case Instruction::Add:
- return LHS + RHS;
- case Instruction::Sub:
- return LHS - RHS;
- case Instruction::Mul:
- return LHS * RHS;
- case Instruction::UDiv:
- if (RHS.isNullValue()) {
- SkipOperation = true;
- return LHS;
- }
- return LHS.udiv(RHS);
- case Instruction::SDiv:
- if (RHS.isNullValue()) {
- SkipOperation = true;
- return LHS;
- }
- return LHS.sdiv(RHS);
- case Instruction::URem:
- if (RHS.isNullValue()) {
- SkipOperation = true;
- return LHS;
- }
- return LHS.urem(RHS);
- case Instruction::SRem:
- if (RHS.isNullValue()) {
- SkipOperation = true;
- return LHS;
- }
- return LHS.srem(RHS);
- case Instruction::Shl:
- return LHS.shl(RHS);
- case Instruction::LShr:
- return LHS.lshr(RHS);
- case Instruction::AShr:
- return LHS.ashr(RHS);
- case Instruction::And:
- return LHS & RHS;
- case Instruction::Or:
- return LHS | RHS;
- case Instruction::Xor:
- return LHS ^ RHS;
- }
- }
-
- bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
- const APInt &LHS, const APInt &RHS) {
- bool SkipOperation = false;
- bool Unsupported = false;
- APInt Result =
- calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
- if (Unsupported)
- return false;
- // If SkipOperation is true, we can ignore this operand pair (L, R).
- if (!SkipOperation)
- unionAssumed(Result);
- return isValidState();
- }
-
- ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
- auto AssumedBefore = getAssumed();
- Value *LHS = ICI->getOperand(0);
- Value *RHS = ICI->getOperand(1);
- if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
- return indicatePessimisticFixpoint();
-
- auto &LHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*LHS));
- if (!LHSAA.isValidState())
- return indicatePessimisticFixpoint();
-
- auto &RHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*RHS));
- if (!RHSAA.isValidState())
- return indicatePessimisticFixpoint();
-
- const DenseSet<APInt> &LHSAAPVS = LHSAA.getAssumedSet();
- const DenseSet<APInt> &RHSAAPVS = RHSAA.getAssumedSet();
-
- // TODO: make use of undef flag to limit potential values aggressively.
- bool MaybeTrue = false, MaybeFalse = false;
- const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0);
- if (LHSAA.undefIsContained() && RHSAA.undefIsContained()) {
- // The result of any comparison between undefs can be soundly replaced
- // with undef.
- unionAssumedWithUndef();
- } else if (LHSAA.undefIsContained()) {
- bool MaybeTrue = false, MaybeFalse = false;
- for (const APInt &R : RHSAAPVS) {
- bool CmpResult = calculateICmpInst(ICI, Zero, R);
- MaybeTrue |= CmpResult;
- MaybeFalse |= !CmpResult;
- if (MaybeTrue & MaybeFalse)
- return indicatePessimisticFixpoint();
- }
- } else if (RHSAA.undefIsContained()) {
- for (const APInt &L : LHSAAPVS) {
- bool CmpResult = calculateICmpInst(ICI, L, Zero);
- MaybeTrue |= CmpResult;
- MaybeFalse |= !CmpResult;
- if (MaybeTrue & MaybeFalse)
- return indicatePessimisticFixpoint();
- }
- } else {
- for (const APInt &L : LHSAAPVS) {
- for (const APInt &R : RHSAAPVS) {
- bool CmpResult = calculateICmpInst(ICI, L, R);
- MaybeTrue |= CmpResult;
- MaybeFalse |= !CmpResult;
- if (MaybeTrue & MaybeFalse)
- return indicatePessimisticFixpoint();
- }
- }
- }
- if (MaybeTrue)
- unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
- if (MaybeFalse)
- unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
- return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
- : ChangeStatus::CHANGED;
- }
-
- ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
- auto AssumedBefore = getAssumed();
- Value *LHS = SI->getTrueValue();
- Value *RHS = SI->getFalseValue();
- if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
- return indicatePessimisticFixpoint();
-
- // TODO: Use assumed simplified condition value
- auto &LHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*LHS));
- if (!LHSAA.isValidState())
- return indicatePessimisticFixpoint();
-
- auto &RHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*RHS));
- if (!RHSAA.isValidState())
- return indicatePessimisticFixpoint();
-
- if (LHSAA.undefIsContained() && RHSAA.undefIsContained())
- // select i1 *, undef , undef => undef
- unionAssumedWithUndef();
- else {
- unionAssumed(LHSAA);
- unionAssumed(RHSAA);
- }
- return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
- : ChangeStatus::CHANGED;
- }
-
- ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
- auto AssumedBefore = getAssumed();
- if (!CI->isIntegerCast())
- return indicatePessimisticFixpoint();
- assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
- uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
- Value *Src = CI->getOperand(0);
- auto &SrcAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*Src));
- if (!SrcAA.isValidState())
- return indicatePessimisticFixpoint();
- const DenseSet<APInt> &SrcAAPVS = SrcAA.getAssumedSet();
- if (SrcAA.undefIsContained())
- unionAssumedWithUndef();
- else {
- for (const APInt &S : SrcAAPVS) {
- APInt T = calculateCastInst(CI, S, ResultBitWidth);
- unionAssumed(T);
- }
- }
- return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
- : ChangeStatus::CHANGED;
- }
-
- ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
- auto AssumedBefore = getAssumed();
- Value *LHS = BinOp->getOperand(0);
- Value *RHS = BinOp->getOperand(1);
- if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
- return indicatePessimisticFixpoint();
-
- auto &LHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*LHS));
- if (!LHSAA.isValidState())
- return indicatePessimisticFixpoint();
-
- auto &RHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*RHS));
- if (!RHSAA.isValidState())
- return indicatePessimisticFixpoint();
-
- const DenseSet<APInt> &LHSAAPVS = LHSAA.getAssumedSet();
- const DenseSet<APInt> &RHSAAPVS = RHSAA.getAssumedSet();
- const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0);
-
- // TODO: make use of undef flag to limit potential values aggressively.
- if (LHSAA.undefIsContained() && RHSAA.undefIsContained()) {
- if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero))
- return indicatePessimisticFixpoint();
- } else if (LHSAA.undefIsContained()) {
- for (const APInt &R : RHSAAPVS) {
- if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R))
- return indicatePessimisticFixpoint();
- }
- } else if (RHSAA.undefIsContained()) {
- for (const APInt &L : LHSAAPVS) {
- if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero))
- return indicatePessimisticFixpoint();
- }
- } else {
- for (const APInt &L : LHSAAPVS) {
- for (const APInt &R : RHSAAPVS) {
- if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R))
- return indicatePessimisticFixpoint();
- }
- }
- }
- return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
- : ChangeStatus::CHANGED;
- }
-
- ChangeStatus updateWithPHINode(Attributor &A, PHINode *PHI) {
- auto AssumedBefore = getAssumed();
- for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
- Value *IncomingValue = PHI->getIncomingValue(u);
- auto &PotentialValuesAA = A.getAAFor<AAPotentialValues>(
- *this, IRPosition::value(*IncomingValue));
- if (!PotentialValuesAA.isValidState())
- return indicatePessimisticFixpoint();
- if (PotentialValuesAA.undefIsContained())
- unionAssumedWithUndef();
- else
- unionAssumed(PotentialValuesAA.getAssumed());
- }
- return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
- : ChangeStatus::CHANGED;
- }
-
- /// See AbstractAttribute::updateImpl(...).
- ChangeStatus updateImpl(Attributor &A) override {
- Value &V = getAssociatedValue();
- Instruction *I = dyn_cast<Instruction>(&V);
-
- if (auto *ICI = dyn_cast<ICmpInst>(I))
- return updateWithICmpInst(A, ICI);
-
- if (auto *SI = dyn_cast<SelectInst>(I))
- return updateWithSelectInst(A, SI);
-
- if (auto *CI = dyn_cast<CastInst>(I))
- return updateWithCastInst(A, CI);
-
- if (auto *BinOp = dyn_cast<BinaryOperator>(I))
- return updateWithBinaryOperator(A, BinOp);
-
- if (auto *PHI = dyn_cast<PHINode>(I))
- return updateWithPHINode(A, PHI);
-
- return indicatePessimisticFixpoint();
- }
-
- /// See AbstractAttribute::trackStatistics()
- void trackStatistics() const override {
- STATS_DECLTRACK_FLOATING_ATTR(potential_values)
- }
-};
-
-struct AAPotentialValuesFunction : AAPotentialValuesImpl {
- AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A)
- : AAPotentialValuesImpl(IRP, A) {}
-
- /// See AbstractAttribute::initialize(...).
- ChangeStatus updateImpl(Attributor &A) override {
- llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
- "not be called");
- }
-
- /// See AbstractAttribute::trackStatistics()
- void trackStatistics() const override {
- STATS_DECLTRACK_FN_ATTR(potential_values)
- }
-};
-
-struct AAPotentialValuesCallSite : AAPotentialValuesFunction {
- AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A)
- : AAPotentialValuesFunction(IRP, A) {}
-
- /// See AbstractAttribute::trackStatistics()
- void trackStatistics() const override {
- STATS_DECLTRACK_CS_ATTR(potential_values)
- }
-};
-
-struct AAPotentialValuesCallSiteReturned
- : AACallSiteReturnedFromReturned<AAPotentialValues, AAPotentialValuesImpl> {
- AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A)
- : AACallSiteReturnedFromReturned<AAPotentialValues,
- AAPotentialValuesImpl>(IRP, A) {}
-
- /// See AbstractAttribute::trackStatistics()
- void trackStatistics() const override {
- STATS_DECLTRACK_CSRET_ATTR(potential_values)
- }
-};
-
-struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
- AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
- : AAPotentialValuesFloating(IRP, A) {}
-
- /// See AbstractAttribute::initialize(..).
- void initialize(Attributor &A) override {
- Value &V = getAssociatedValue();
-
- if (auto *C = dyn_cast<ConstantInt>(&V)) {
- unionAssumed(C->getValue());
- indicateOptimisticFixpoint();
- return;
- }
-
- if (isa<UndefValue>(&V)) {
- unionAssumedWithUndef();
- indicateOptimisticFixpoint();
- return;
- }
- }
-
- /// See AbstractAttribute::updateImpl(...).
- ChangeStatus updateImpl(Attributor &A) override {
- Value &V = getAssociatedValue();
- auto AssumedBefore = getAssumed();
- auto &AA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(V));
- const auto &S = AA.getAssumed();
- unionAssumed(S);
- return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
- : ChangeStatus::CHANGED;
- }
-
- /// See AbstractAttribute::trackStatistics()
- void trackStatistics() const override {
- STATS_DECLTRACK_CSARG_ATTR(potential_values)
- }
-};
-
-/// ------------------------ NoUndef Attribute ---------------------------------
-struct AANoUndefImpl : AANoUndef {
- AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}
-
- /// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override {
- if (getIRPosition().hasAttr({Attribute::NoUndef})) {
- indicateOptimisticFixpoint();
- return;
- }
- Value &V = getAssociatedValue();
- if (isa<UndefValue>(V))
- indicatePessimisticFixpoint();
- else if (isa<FreezeInst>(V))
- indicateOptimisticFixpoint();
- else if (getPositionKind() != IRPosition::IRP_RETURNED &&
- isGuaranteedNotToBeUndefOrPoison(&V))
- indicateOptimisticFixpoint();
- else
- AANoUndef::initialize(A);
- }
-
- /// See followUsesInMBEC
- bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
- AANoUndef::StateType &State) {
- const Value *UseV = U->get();
- const DominatorTree *DT = nullptr;
- AssumptionCache *AC = nullptr;
- InformationCache &InfoCache = A.getInfoCache();
- if (Function *F = getAnchorScope()) {
- DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
- AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
- }
- State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT));
- bool TrackUse = false;
- // Track use for instructions which must produce undef or poison bits when
- // at least one operand contains such bits.
- if (isa<CastInst>(*I) || isa<GetElementPtrInst>(*I))
- TrackUse = true;
- return TrackUse;
- }
-
- /// See AbstractAttribute::getAsStr().
- const std::string getAsStr() const override {
- return getAssumed() ? "noundef" : "may-undef-or-poison";
- }
-
- ChangeStatus manifest(Attributor &A) override {
- // We don't manifest noundef attribute for dead positions because the
- // associated values with dead positions would be replaced with undef
- // values.
- if (A.isAssumedDead(getIRPosition(), nullptr, nullptr))
- return ChangeStatus::UNCHANGED;
- // A position whose simplified value does not have any value is
- // considered to be dead. We don't manifest noundef in such positions for
- // the same reason above.
- auto &ValueSimplifyAA = A.getAAFor<AAValueSimplify>(
- *this, getIRPosition(), /* TrackDependence */ false);
- if (!ValueSimplifyAA.getAssumedSimplifiedValue(A).hasValue())
- return ChangeStatus::UNCHANGED;
- return AANoUndef::manifest(A);
- }
-};
-
-struct AANoUndefFloating : public AANoUndefImpl {
- AANoUndefFloating(const IRPosition &IRP, Attributor &A)
- : AANoUndefImpl(IRP, A) {}
-
- /// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override {
- AANoUndefImpl::initialize(A);
- if (!getState().isAtFixpoint())
- if (Instruction *CtxI = getCtxI())
- followUsesInMBEC(*this, A, getState(), *CtxI);
- }
-
- /// See AbstractAttribute::updateImpl(...).
- ChangeStatus updateImpl(Attributor &A) override {
- auto VisitValueCB = [&](Value &V, const Instruction *CtxI,
- AANoUndef::StateType &T, bool Stripped) -> bool {
- const auto &AA = A.getAAFor<AANoUndef>(*this, IRPosition::value(V));
- if (!Stripped && this == &AA) {
- T.indicatePessimisticFixpoint();
- } else {
- const AANoUndef::StateType &S =
- static_cast<const AANoUndef::StateType &>(AA.getState());
- T ^= S;
- }
- return T.isValidState();
- };
-
- StateType T;
- if (!genericValueTraversal<AANoUndef, StateType>(
- A, getIRPosition(), *this, T, VisitValueCB, getCtxI()))
- return indicatePessimisticFixpoint();
-
- return clampStateAndIndicateChange(getState(), T);
- }
-
- /// See AbstractAttribute::trackStatistics()
- void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
-};
-
-struct AANoUndefReturned final
- : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
- AANoUndefReturned(const IRPosition &IRP, Attributor &A)
- : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
-
- /// See AbstractAttribute::trackStatistics()
- void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
-};
-
-struct AANoUndefArgument final
- : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
- AANoUndefArgument(const IRPosition &IRP, Attributor &A)
- : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
-
- /// See AbstractAttribute::trackStatistics()
- void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
-};
-
-struct AANoUndefCallSiteArgument final : AANoUndefFloating {
- AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A)
- : AANoUndefFloating(IRP, A) {}
-
- /// See AbstractAttribute::trackStatistics()
- void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) }
-};
-
-struct AANoUndefCallSiteReturned final
- : AACallSiteReturnedFromReturned<AANoUndef, AANoUndefImpl> {
- AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
- : AACallSiteReturnedFromReturned<AANoUndef, AANoUndefImpl>(IRP, A) {}
-
- /// See AbstractAttribute::trackStatistics()
- void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
-};
+
+/// ------------------ Potential Values Attribute -------------------------
+
+struct AAPotentialValuesImpl : AAPotentialValues {
+ using StateType = PotentialConstantIntValuesState;
+
+ AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A)
+ : AAPotentialValues(IRP, A) {}
+
+ /// See AbstractAttribute::getAsStr().
+ const std::string getAsStr() const override {
+ std::string Str;
+ llvm::raw_string_ostream OS(Str);
+ OS << getState();
+ return OS.str();
+ }
+
+ /// See AbstractAttribute::updateImpl(...).
+ ChangeStatus updateImpl(Attributor &A) override {
+ return indicatePessimisticFixpoint();
+ }
+};
+
+struct AAPotentialValuesArgument final
+ : AAArgumentFromCallSiteArguments<AAPotentialValues, AAPotentialValuesImpl,
+ PotentialConstantIntValuesState> {
+ using Base =
+ AAArgumentFromCallSiteArguments<AAPotentialValues, AAPotentialValuesImpl,
+ PotentialConstantIntValuesState>;
+ AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A)
+ : Base(IRP, A) {}
+
+ /// See AbstractAttribute::initialize(..).
+ void initialize(Attributor &A) override {
+ if (!getAnchorScope() || getAnchorScope()->isDeclaration()) {
+ indicatePessimisticFixpoint();
+ } else {
+ Base::initialize(A);
+ }
+ }
+
+ /// See AbstractAttribute::trackStatistics()
+ void trackStatistics() const override {
+ STATS_DECLTRACK_ARG_ATTR(potential_values)
+ }
+};
+
+struct AAPotentialValuesReturned
+ : AAReturnedFromReturnedValues<AAPotentialValues, AAPotentialValuesImpl> {
+ using Base =
+ AAReturnedFromReturnedValues<AAPotentialValues, AAPotentialValuesImpl>;
+ AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A)
+ : Base(IRP, A) {}
+
+ /// See AbstractAttribute::trackStatistics()
+ void trackStatistics() const override {
+ STATS_DECLTRACK_FNRET_ATTR(potential_values)
+ }
+};
+
+struct AAPotentialValuesFloating : AAPotentialValuesImpl {
+ AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A)
+ : AAPotentialValuesImpl(IRP, A) {}
+
+ /// See AbstractAttribute::initialize(..).
+ void initialize(Attributor &A) override {
+ Value &V = getAssociatedValue();
+
+ if (auto *C = dyn_cast<ConstantInt>(&V)) {
+ unionAssumed(C->getValue());
+ indicateOptimisticFixpoint();
+ return;
+ }
+
+ if (isa<UndefValue>(&V)) {
+ unionAssumedWithUndef();
+ indicateOptimisticFixpoint();
+ return;
+ }
+
+ if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
+ return;
+
+ if (isa<SelectInst>(V) || isa<PHINode>(V))
+ return;
+
+ indicatePessimisticFixpoint();
+
+ LLVM_DEBUG(dbgs() << "[AAPotentialValues] We give up: "
+ << getAssociatedValue() << "\n");
+ }
+
+ static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
+ const APInt &RHS) {
+ ICmpInst::Predicate Pred = ICI->getPredicate();
+ switch (Pred) {
+ case ICmpInst::ICMP_UGT:
+ return LHS.ugt(RHS);
+ case ICmpInst::ICMP_SGT:
+ return LHS.sgt(RHS);
+ case ICmpInst::ICMP_EQ:
+ return LHS.eq(RHS);
+ case ICmpInst::ICMP_UGE:
+ return LHS.uge(RHS);
+ case ICmpInst::ICMP_SGE:
+ return LHS.sge(RHS);
+ case ICmpInst::ICMP_ULT:
+ return LHS.ult(RHS);
+ case ICmpInst::ICMP_SLT:
+ return LHS.slt(RHS);
+ case ICmpInst::ICMP_NE:
+ return LHS.ne(RHS);
+ case ICmpInst::ICMP_ULE:
+ return LHS.ule(RHS);
+ case ICmpInst::ICMP_SLE:
+ return LHS.sle(RHS);
+ default:
+ llvm_unreachable("Invalid ICmp predicate!");
+ }
+ }
+
+ static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
+ uint32_t ResultBitWidth) {
+ Instruction::CastOps CastOp = CI->getOpcode();
+ switch (CastOp) {
+ default:
+ llvm_unreachable("unsupported or not integer cast");
+ case Instruction::Trunc:
+ return Src.trunc(ResultBitWidth);
+ case Instruction::SExt:
+ return Src.sext(ResultBitWidth);
+ case Instruction::ZExt:
+ return Src.zext(ResultBitWidth);
+ case Instruction::BitCast:
+ return Src;
+ }
+ }
+
+ static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
+ const APInt &LHS, const APInt &RHS,
+ bool &SkipOperation, bool &Unsupported) {
+ Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
+ // Unsupported is set to true when the binary operator is not supported.
+ // SkipOperation is set to true when UB occur with the given operand pair
+ // (LHS, RHS).
+ // TODO: we should look at nsw and nuw keywords to handle operations
+ // that create poison or undef value.
+ switch (BinOpcode) {
+ default:
+ Unsupported = true;
+ return LHS;
+ case Instruction::Add:
+ return LHS + RHS;
+ case Instruction::Sub:
+ return LHS - RHS;
+ case Instruction::Mul:
+ return LHS * RHS;
+ case Instruction::UDiv:
+ if (RHS.isNullValue()) {
+ SkipOperation = true;
+ return LHS;
+ }
+ return LHS.udiv(RHS);
+ case Instruction::SDiv:
+ if (RHS.isNullValue()) {
+ SkipOperation = true;
+ return LHS;
+ }
+ return LHS.sdiv(RHS);
+ case Instruction::URem:
+ if (RHS.isNullValue()) {
+ SkipOperation = true;
+ return LHS;
+ }
+ return LHS.urem(RHS);
+ case Instruction::SRem:
+ if (RHS.isNullValue()) {
+ SkipOperation = true;
+ return LHS;
+ }
+ return LHS.srem(RHS);
+ case Instruction::Shl:
+ return LHS.shl(RHS);
+ case Instruction::LShr:
+ return LHS.lshr(RHS);
+ case Instruction::AShr:
+ return LHS.ashr(RHS);
+ case Instruction::And:
+ return LHS & RHS;
+ case Instruction::Or:
+ return LHS | RHS;
+ case Instruction::Xor:
+ return LHS ^ RHS;
+ }
+ }
+
+ bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
+ const APInt &LHS, const APInt &RHS) {
+ bool SkipOperation = false;
+ bool Unsupported = false;
+ APInt Result =
+ calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
+ if (Unsupported)
+ return false;
+ // If SkipOperation is true, we can ignore this operand pair (L, R).
+ if (!SkipOperation)
+ unionAssumed(Result);
+ return isValidState();
+ }
+
+ ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
+ auto AssumedBefore = getAssumed();
+ Value *LHS = ICI->getOperand(0);
+ Value *RHS = ICI->getOperand(1);
+ if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
+ return indicatePessimisticFixpoint();
+
+ auto &LHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*LHS));
+ if (!LHSAA.isValidState())
+ return indicatePessimisticFixpoint();
+
+ auto &RHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*RHS));
+ if (!RHSAA.isValidState())
+ return indicatePessimisticFixpoint();
+
+ const DenseSet<APInt> &LHSAAPVS = LHSAA.getAssumedSet();
+ const DenseSet<APInt> &RHSAAPVS = RHSAA.getAssumedSet();
+
+ // TODO: make use of undef flag to limit potential values aggressively.
+ bool MaybeTrue = false, MaybeFalse = false;
+ const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0);
+ if (LHSAA.undefIsContained() && RHSAA.undefIsContained()) {
+ // The result of any comparison between undefs can be soundly replaced
+ // with undef.
+ unionAssumedWithUndef();
+ } else if (LHSAA.undefIsContained()) {
+ bool MaybeTrue = false, MaybeFalse = false;
+ for (const APInt &R : RHSAAPVS) {
+ bool CmpResult = calculateICmpInst(ICI, Zero, R);
+ MaybeTrue |= CmpResult;
+ MaybeFalse |= !CmpResult;
+ if (MaybeTrue & MaybeFalse)
+ return indicatePessimisticFixpoint();
+ }
+ } else if (RHSAA.undefIsContained()) {
+ for (const APInt &L : LHSAAPVS) {
+ bool CmpResult = calculateICmpInst(ICI, L, Zero);
+ MaybeTrue |= CmpResult;
+ MaybeFalse |= !CmpResult;
+ if (MaybeTrue & MaybeFalse)
+ return indicatePessimisticFixpoint();
+ }
+ } else {
+ for (const APInt &L : LHSAAPVS) {
+ for (const APInt &R : RHSAAPVS) {
+ bool CmpResult = calculateICmpInst(ICI, L, R);
+ MaybeTrue |= CmpResult;
+ MaybeFalse |= !CmpResult;
+ if (MaybeTrue & MaybeFalse)
+ return indicatePessimisticFixpoint();
+ }
+ }
+ }
+ if (MaybeTrue)
+ unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
+ if (MaybeFalse)
+ unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
+ return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
+ : ChangeStatus::CHANGED;
+ }
+
+ ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
+ auto AssumedBefore = getAssumed();
+ Value *LHS = SI->getTrueValue();
+ Value *RHS = SI->getFalseValue();
+ if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
+ return indicatePessimisticFixpoint();
+
+ // TODO: Use assumed simplified condition value
+ auto &LHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*LHS));
+ if (!LHSAA.isValidState())
+ return indicatePessimisticFixpoint();
+
+ auto &RHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*RHS));
+ if (!RHSAA.isValidState())
+ return indicatePessimisticFixpoint();
+
+ if (LHSAA.undefIsContained() && RHSAA.undefIsContained())
+ // select i1 *, undef , undef => undef
+ unionAssumedWithUndef();
+ else {
+ unionAssumed(LHSAA);
+ unionAssumed(RHSAA);
+ }
+ return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
+ : ChangeStatus::CHANGED;
+ }
+
+ ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
+ auto AssumedBefore = getAssumed();
+ if (!CI->isIntegerCast())
+ return indicatePessimisticFixpoint();
+ assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
+ uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
+ Value *Src = CI->getOperand(0);
+ auto &SrcAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*Src));
+ if (!SrcAA.isValidState())
+ return indicatePessimisticFixpoint();
+ const DenseSet<APInt> &SrcAAPVS = SrcAA.getAssumedSet();
+ if (SrcAA.undefIsContained())
+ unionAssumedWithUndef();
+ else {
+ for (const APInt &S : SrcAAPVS) {
+ APInt T = calculateCastInst(CI, S, ResultBitWidth);
+ unionAssumed(T);
+ }
+ }
+ return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
+ : ChangeStatus::CHANGED;
+ }
+
+ ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
+ auto AssumedBefore = getAssumed();
+ Value *LHS = BinOp->getOperand(0);
+ Value *RHS = BinOp->getOperand(1);
+ if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
+ return indicatePessimisticFixpoint();
+
+ auto &LHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*LHS));
+ if (!LHSAA.isValidState())
+ return indicatePessimisticFixpoint();
+
+ auto &RHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*RHS));
+ if (!RHSAA.isValidState())
+ return indicatePessimisticFixpoint();
+
+ const DenseSet<APInt> &LHSAAPVS = LHSAA.getAssumedSet();
+ const DenseSet<APInt> &RHSAAPVS = RHSAA.getAssumedSet();
+ const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0);
+
+ // TODO: make use of undef flag to limit potential values aggressively.
+ if (LHSAA.undefIsContained() && RHSAA.undefIsContained()) {
+ if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero))
+ return indicatePessimisticFixpoint();
+ } else if (LHSAA.undefIsContained()) {
+ for (const APInt &R : RHSAAPVS) {
+ if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R))
+ return indicatePessimisticFixpoint();
+ }
+ } else if (RHSAA.undefIsContained()) {
+ for (const APInt &L : LHSAAPVS) {
+ if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero))
+ return indicatePessimisticFixpoint();
+ }
+ } else {
+ for (const APInt &L : LHSAAPVS) {
+ for (const APInt &R : RHSAAPVS) {
+ if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R))
+ return indicatePessimisticFixpoint();
+ }
+ }
+ }
+ return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
+ : ChangeStatus::CHANGED;
+ }
+
+ ChangeStatus updateWithPHINode(Attributor &A, PHINode *PHI) {
+ auto AssumedBefore = getAssumed();
+ for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
+ Value *IncomingValue = PHI->getIncomingValue(u);
+ auto &PotentialValuesAA = A.getAAFor<AAPotentialValues>(
+ *this, IRPosition::value(*IncomingValue));
+ if (!PotentialValuesAA.isValidState())
+ return indicatePessimisticFixpoint();
+ if (PotentialValuesAA.undefIsContained())
+ unionAssumedWithUndef();
+ else
+ unionAssumed(PotentialValuesAA.getAssumed());
+ }
+ return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
+ : ChangeStatus::CHANGED;
+ }
+
+ /// See AbstractAttribute::updateImpl(...).
+ ChangeStatus updateImpl(Attributor &A) override {
+ Value &V = getAssociatedValue();
+ Instruction *I = dyn_cast<Instruction>(&V);
+
+ if (auto *ICI = dyn_cast<ICmpInst>(I))
+ return updateWithICmpInst(A, ICI);
+
+ if (auto *SI = dyn_cast<SelectInst>(I))
+ return updateWithSelectInst(A, SI);
+
+ if (auto *CI = dyn_cast<CastInst>(I))
+ return updateWithCastInst(A, CI);
+
+ if (auto *BinOp = dyn_cast<BinaryOperator>(I))
+ return updateWithBinaryOperator(A, BinOp);
+
+ if (auto *PHI = dyn_cast<PHINode>(I))
+ return updateWithPHINode(A, PHI);
+
+ return indicatePessimisticFixpoint();
+ }
+
+ /// See AbstractAttribute::trackStatistics()
+ void trackStatistics() const override {
+ STATS_DECLTRACK_FLOATING_ATTR(potential_values)
+ }
+};
+
+struct AAPotentialValuesFunction : AAPotentialValuesImpl {
+ AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A)
+ : AAPotentialValuesImpl(IRP, A) {}
+
+ /// See AbstractAttribute::initialize(...).
+ ChangeStatus updateImpl(Attributor &A) override {
+ llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
+ "not be called");
+ }
+
+ /// See AbstractAttribute::trackStatistics()
+ void trackStatistics() const override {
+ STATS_DECLTRACK_FN_ATTR(potential_values)
+ }
+};
+
+struct AAPotentialValuesCallSite : AAPotentialValuesFunction {
+ AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A)
+ : AAPotentialValuesFunction(IRP, A) {}
+
+ /// See AbstractAttribute::trackStatistics()
+ void trackStatistics() const override {
+ STATS_DECLTRACK_CS_ATTR(potential_values)
+ }
+};
+
+struct AAPotentialValuesCallSiteReturned
+ : AACallSiteReturnedFromReturned<AAPotentialValues, AAPotentialValuesImpl> {
+ AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A)
+ : AACallSiteReturnedFromReturned<AAPotentialValues,
+ AAPotentialValuesImpl>(IRP, A) {}
+
+ /// See AbstractAttribute::trackStatistics()
+ void trackStatistics() const override {
+ STATS_DECLTRACK_CSRET_ATTR(potential_values)
+ }
+};
+
+struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
+ AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
+ : AAPotentialValuesFloating(IRP, A) {}
+
+ /// See AbstractAttribute::initialize(..).
+ void initialize(Attributor &A) override {
+ Value &V = getAssociatedValue();
+
+ if (auto *C = dyn_cast<ConstantInt>(&V)) {
+ unionAssumed(C->getValue());
+ indicateOptimisticFixpoint();
+ return;
+ }
+
+ if (isa<UndefValue>(&V)) {
+ unionAssumedWithUndef();
+ indicateOptimisticFixpoint();
+ return;
+ }
+ }
+
+ /// See AbstractAttribute::updateImpl(...).
+ ChangeStatus updateImpl(Attributor &A) override {
+ Value &V = getAssociatedValue();
+ auto AssumedBefore = getAssumed();
+ auto &AA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(V));
+ const auto &S = AA.getAssumed();
+ unionAssumed(S);
+ return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
+ : ChangeStatus::CHANGED;
+ }
+
+ /// See AbstractAttribute::trackStatistics()
+ void trackStatistics() const override {
+ STATS_DECLTRACK_CSARG_ATTR(potential_values)
+ }
+};
+
+/// ------------------------ NoUndef Attribute ---------------------------------
+struct AANoUndefImpl : AANoUndef {
+ AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}
+
+ /// See AbstractAttribute::initialize(...).
+ void initialize(Attributor &A) override {
+ if (getIRPosition().hasAttr({Attribute::NoUndef})) {
+ indicateOptimisticFixpoint();
+ return;
+ }
+ Value &V = getAssociatedValue();
+ if (isa<UndefValue>(V))
+ indicatePessimisticFixpoint();
+ else if (isa<FreezeInst>(V))
+ indicateOptimisticFixpoint();
+ else if (getPositionKind() != IRPosition::IRP_RETURNED &&
+ isGuaranteedNotToBeUndefOrPoison(&V))
+ indicateOptimisticFixpoint();
+ else
+ AANoUndef::initialize(A);
+ }
+
+ /// See followUsesInMBEC
+ bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
+ AANoUndef::StateType &State) {
+ const Value *UseV = U->get();
+ const DominatorTree *DT = nullptr;
+ AssumptionCache *AC = nullptr;
+ InformationCache &InfoCache = A.getInfoCache();
+ if (Function *F = getAnchorScope()) {
+ DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
+ AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
+ }
+ State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT));
+ bool TrackUse = false;
+ // Track use for instructions which must produce undef or poison bits when
+ // at least one operand contains such bits.
+ if (isa<CastInst>(*I) || isa<GetElementPtrInst>(*I))
+ TrackUse = true;
+ return TrackUse;
+ }
+
+ /// See AbstractAttribute::getAsStr().
+ const std::string getAsStr() const override {
+ return getAssumed() ? "noundef" : "may-undef-or-poison";
+ }
+
+ ChangeStatus manifest(Attributor &A) override {
+ // We don't manifest noundef attribute for dead positions because the
+ // associated values with dead positions would be replaced with undef
+ // values.
+ if (A.isAssumedDead(getIRPosition(), nullptr, nullptr))
+ return ChangeStatus::UNCHANGED;
+ // A position whose simplified value does not have any value is
+ // considered to be dead. We don't manifest noundef in such positions for
+ // the same reason above.
+ auto &ValueSimplifyAA = A.getAAFor<AAValueSimplify>(
+ *this, getIRPosition(), /* TrackDependence */ false);
+ if (!ValueSimplifyAA.getAssumedSimplifiedValue(A).hasValue())
+ return ChangeStatus::UNCHANGED;
+ return AANoUndef::manifest(A);
+ }
+};
+
+struct AANoUndefFloating : public AANoUndefImpl {
+ AANoUndefFloating(const IRPosition &IRP, Attributor &A)
+ : AANoUndefImpl(IRP, A) {}
+
+ /// See AbstractAttribute::initialize(...).
+ void initialize(Attributor &A) override {
+ AANoUndefImpl::initialize(A);
+ if (!getState().isAtFixpoint())
+ if (Instruction *CtxI = getCtxI())
+ followUsesInMBEC(*this, A, getState(), *CtxI);
+ }
+
+ /// See AbstractAttribute::updateImpl(...).
+ ChangeStatus updateImpl(Attributor &A) override {
+ auto VisitValueCB = [&](Value &V, const Instruction *CtxI,
+ AANoUndef::StateType &T, bool Stripped) -> bool {
+ const auto &AA = A.getAAFor<AANoUndef>(*this, IRPosition::value(V));
+ if (!Stripped && this == &AA) {
+ T.indicatePessimisticFixpoint();
+ } else {
+ const AANoUndef::StateType &S =
+ static_cast<const AANoUndef::StateType &>(AA.getState());
+ T ^= S;
+ }
+ return T.isValidState();
+ };
+
+ StateType T;
+ if (!genericValueTraversal<AANoUndef, StateType>(
+ A, getIRPosition(), *this, T, VisitValueCB, getCtxI()))
+ return indicatePessimisticFixpoint();
+
+ return clampStateAndIndicateChange(getState(), T);
+ }
+
+ /// See AbstractAttribute::trackStatistics()
+ void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
+};
+
+struct AANoUndefReturned final
+ : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
+ AANoUndefReturned(const IRPosition &IRP, Attributor &A)
+ : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
+
+ /// See AbstractAttribute::trackStatistics()
+ void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
+};
+
+struct AANoUndefArgument final
+ : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
+ AANoUndefArgument(const IRPosition &IRP, Attributor &A)
+ : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
+
+ /// See AbstractAttribute::trackStatistics()
+ void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
+};
+
+struct AANoUndefCallSiteArgument final : AANoUndefFloating {
+ AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A)
+ : AANoUndefFloating(IRP, A) {}
+
+ /// See AbstractAttribute::trackStatistics()
+ void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) }
+};
+
+struct AANoUndefCallSiteReturned final
+ : AACallSiteReturnedFromReturned<AANoUndef, AANoUndefImpl> {
+ AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
+ : AACallSiteReturnedFromReturned<AANoUndef, AANoUndefImpl>(IRP, A) {}
+
+ /// See AbstractAttribute::trackStatistics()
+ void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
+};
} // namespace
const char AAReturnedValues::ID = 0;
@@ -8048,8 +8048,8 @@ const char AAPrivatizablePtr::ID = 0;
const char AAMemoryBehavior::ID = 0;
const char AAMemoryLocation::ID = 0;
const char AAValueConstantRange::ID = 0;
-const char AAPotentialValues::ID = 0;
-const char AANoUndef::ID = 0;
+const char AAPotentialValues::ID = 0;
+const char AANoUndef::ID = 0;
// Macro magic to create the static generator function for attributes that
// follow the naming scheme.
@@ -8159,8 +8159,8 @@ CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable)
CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign)
CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture)
CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueConstantRange)
-CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPotentialValues)
-CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUndef)
+CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPotentialValues)
+CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUndef)
CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify)
CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead)
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/BlockExtractor.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/BlockExtractor.cpp
index 084a7af446..c6e222a096 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/BlockExtractor.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/BlockExtractor.cpp
@@ -11,12 +11,12 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/IPO/BlockExtractor.h"
+#include "llvm/Transforms/IPO/BlockExtractor.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
@@ -40,10 +40,10 @@ cl::opt<bool> BlockExtractorEraseFuncs("extract-blocks-erase-funcs",
cl::desc("Erase the existing functions"),
cl::Hidden);
namespace {
-class BlockExtractor {
-public:
- BlockExtractor(bool EraseFunctions) : EraseFunctions(EraseFunctions) {}
- bool runOnModule(Module &M);
+class BlockExtractor {
+public:
+ BlockExtractor(bool EraseFunctions) : EraseFunctions(EraseFunctions) {}
+ bool runOnModule(Module &M);
void init(const SmallVectorImpl<SmallVector<BasicBlock *, 16>>
&GroupsOfBlocksToExtract) {
for (const SmallVectorImpl<BasicBlock *> &GroupOfBlocks :
@@ -56,26 +56,26 @@ public:
loadFile();
}
-private:
- SmallVector<SmallVector<BasicBlock *, 16>, 4> GroupsOfBlocks;
- bool EraseFunctions;
- /// Map a function name to groups of blocks.
- SmallVector<std::pair<std::string, SmallVector<std::string, 4>>, 4>
- BlocksByName;
-
- void loadFile();
- void splitLandingPadPreds(Function &F);
-};
-
-class BlockExtractorLegacyPass : public ModulePass {
- BlockExtractor BE;
- bool runOnModule(Module &M) override;
-
+private:
+ SmallVector<SmallVector<BasicBlock *, 16>, 4> GroupsOfBlocks;
+ bool EraseFunctions;
+ /// Map a function name to groups of blocks.
+ SmallVector<std::pair<std::string, SmallVector<std::string, 4>>, 4>
+ BlocksByName;
+
+ void loadFile();
+ void splitLandingPadPreds(Function &F);
+};
+
+class BlockExtractorLegacyPass : public ModulePass {
+ BlockExtractor BE;
+ bool runOnModule(Module &M) override;
+
public:
static char ID;
- BlockExtractorLegacyPass(const SmallVectorImpl<BasicBlock *> &BlocksToExtract,
- bool EraseFunctions)
- : ModulePass(ID), BE(EraseFunctions) {
+ BlockExtractorLegacyPass(const SmallVectorImpl<BasicBlock *> &BlocksToExtract,
+ bool EraseFunctions)
+ : ModulePass(ID), BE(EraseFunctions) {
// We want one group per element of the input list.
SmallVector<SmallVector<BasicBlock *, 16>, 4> MassagedGroupsOfBlocks;
for (BasicBlock *BB : BlocksToExtract) {
@@ -83,38 +83,38 @@ public:
NewGroup.push_back(BB);
MassagedGroupsOfBlocks.push_back(NewGroup);
}
- BE.init(MassagedGroupsOfBlocks);
+ BE.init(MassagedGroupsOfBlocks);
}
- BlockExtractorLegacyPass(const SmallVectorImpl<SmallVector<BasicBlock *, 16>>
- &GroupsOfBlocksToExtract,
- bool EraseFunctions)
- : ModulePass(ID), BE(EraseFunctions) {
- BE.init(GroupsOfBlocksToExtract);
+ BlockExtractorLegacyPass(const SmallVectorImpl<SmallVector<BasicBlock *, 16>>
+ &GroupsOfBlocksToExtract,
+ bool EraseFunctions)
+ : ModulePass(ID), BE(EraseFunctions) {
+ BE.init(GroupsOfBlocksToExtract);
}
- BlockExtractorLegacyPass()
- : BlockExtractorLegacyPass(SmallVector<BasicBlock *, 0>(), false) {}
-};
+ BlockExtractorLegacyPass()
+ : BlockExtractorLegacyPass(SmallVector<BasicBlock *, 0>(), false) {}
+};
} // end anonymous namespace
-char BlockExtractorLegacyPass::ID = 0;
-INITIALIZE_PASS(BlockExtractorLegacyPass, "extract-blocks",
+char BlockExtractorLegacyPass::ID = 0;
+INITIALIZE_PASS(BlockExtractorLegacyPass, "extract-blocks",
"Extract basic blocks from module", false, false)
-ModulePass *llvm::createBlockExtractorPass() {
- return new BlockExtractorLegacyPass();
-}
+ModulePass *llvm::createBlockExtractorPass() {
+ return new BlockExtractorLegacyPass();
+}
ModulePass *llvm::createBlockExtractorPass(
const SmallVectorImpl<BasicBlock *> &BlocksToExtract, bool EraseFunctions) {
- return new BlockExtractorLegacyPass(BlocksToExtract, EraseFunctions);
+ return new BlockExtractorLegacyPass(BlocksToExtract, EraseFunctions);
}
ModulePass *llvm::createBlockExtractorPass(
const SmallVectorImpl<SmallVector<BasicBlock *, 16>>
&GroupsOfBlocksToExtract,
bool EraseFunctions) {
- return new BlockExtractorLegacyPass(GroupsOfBlocksToExtract, EraseFunctions);
+ return new BlockExtractorLegacyPass(GroupsOfBlocksToExtract, EraseFunctions);
}
/// Gets all of the blocks specified in the input file.
@@ -246,15 +246,15 @@ bool BlockExtractor::runOnModule(Module &M) {
return Changed;
}
-
-bool BlockExtractorLegacyPass::runOnModule(Module &M) {
- return BE.runOnModule(M);
-}
-
-PreservedAnalyses BlockExtractorPass::run(Module &M,
- ModuleAnalysisManager &AM) {
- BlockExtractor BE(false);
- BE.init(SmallVector<SmallVector<BasicBlock *, 16>, 0>());
- return BE.runOnModule(M) ? PreservedAnalyses::none()
- : PreservedAnalyses::all();
-}
+
+bool BlockExtractorLegacyPass::runOnModule(Module &M) {
+ return BE.runOnModule(M);
+}
+
+PreservedAnalyses BlockExtractorPass::run(Module &M,
+ ModuleAnalysisManager &AM) {
+ BlockExtractor BE(false);
+ BE.init(SmallVector<SmallVector<BasicBlock *, 16>, 0>());
+ return BE.runOnModule(M) ? PreservedAnalyses::none()
+ : PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/ConstantMerge.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/ConstantMerge.cpp
index 60e611dab8..8e81f4bad4 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/ConstantMerge.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/ConstantMerge.cpp
@@ -95,8 +95,8 @@ isUnmergeableGlobal(GlobalVariable *GV,
// Only process constants with initializers in the default address space.
return !GV->isConstant() || !GV->hasDefinitiveInitializer() ||
GV->getType()->getAddressSpace() != 0 || GV->hasSection() ||
- // Don't touch thread-local variables.
- GV->isThreadLocal() ||
+ // Don't touch thread-local variables.
+ GV->isThreadLocal() ||
// Don't touch values marked with attribute(used).
UsedGlobals.count(GV);
}
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/DeadArgumentElimination.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/DeadArgumentElimination.cpp
index 8eaff1862d..0b763e423f 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/DeadArgumentElimination.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/DeadArgumentElimination.cpp
@@ -289,7 +289,7 @@ bool DeadArgumentEliminationPass::RemoveDeadArgumentsFromCallers(Function &Fn) {
for (Argument &Arg : Fn.args()) {
if (!Arg.hasSwiftErrorAttr() && Arg.use_empty() &&
- !Arg.hasPassPointeeByValueCopyAttr()) {
+ !Arg.hasPassPointeeByValueCopyAttr()) {
if (Arg.isUsedByMetadata()) {
Arg.replaceAllUsesWith(UndefValue::get(Arg.getType()));
Changed = true;
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/ForceFunctionAttrs.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/ForceFunctionAttrs.cpp
index 39f643632e..1a8bb225a6 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/ForceFunctionAttrs.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/ForceFunctionAttrs.cpp
@@ -26,13 +26,13 @@ static cl::list<std::string>
"example -force-attribute=foo:noinline. This "
"option can be specified multiple times."));
-static cl::list<std::string> ForceRemoveAttributes(
- "force-remove-attribute", cl::Hidden,
- cl::desc("Remove an attribute from a function. This should be a "
- "pair of 'function-name:attribute-name', for "
- "example -force-remove-attribute=foo:noinline. This "
- "option can be specified multiple times."));
-
+static cl::list<std::string> ForceRemoveAttributes(
+ "force-remove-attribute", cl::Hidden,
+ cl::desc("Remove an attribute from a function. This should be a "
+ "pair of 'function-name:attribute-name', for "
+ "example -force-remove-attribute=foo:noinline. This "
+ "option can be specified multiple times."));
+
static Attribute::AttrKind parseAttrKind(StringRef Kind) {
return StringSwitch<Attribute::AttrKind>(Kind)
.Case("alwaysinline", Attribute::AlwaysInline)
@@ -77,49 +77,49 @@ static Attribute::AttrKind parseAttrKind(StringRef Kind) {
}
/// If F has any forced attributes given on the command line, add them.
-/// If F has any forced remove attributes given on the command line, remove
-/// them. When both force and force-remove are given to a function, the latter
-/// takes precedence.
-static void forceAttributes(Function &F) {
- auto ParseFunctionAndAttr = [&](StringRef S) {
- auto Kind = Attribute::None;
+/// If F has any forced remove attributes given on the command line, remove
+/// them. When both force and force-remove are given to a function, the latter
+/// takes precedence.
+static void forceAttributes(Function &F) {
+ auto ParseFunctionAndAttr = [&](StringRef S) {
+ auto Kind = Attribute::None;
auto KV = StringRef(S).split(':');
if (KV.first != F.getName())
- return Kind;
- Kind = parseAttrKind(KV.second);
+ return Kind;
+ Kind = parseAttrKind(KV.second);
if (Kind == Attribute::None) {
LLVM_DEBUG(dbgs() << "ForcedAttribute: " << KV.second
<< " unknown or not handled!\n");
}
- return Kind;
- };
-
- for (auto &S : ForceAttributes) {
- auto Kind = ParseFunctionAndAttr(S);
- if (Kind == Attribute::None || F.hasFnAttribute(Kind))
+ return Kind;
+ };
+
+ for (auto &S : ForceAttributes) {
+ auto Kind = ParseFunctionAndAttr(S);
+ if (Kind == Attribute::None || F.hasFnAttribute(Kind))
continue;
F.addFnAttr(Kind);
}
-
- for (auto &S : ForceRemoveAttributes) {
- auto Kind = ParseFunctionAndAttr(S);
- if (Kind == Attribute::None || !F.hasFnAttribute(Kind))
- continue;
- F.removeFnAttr(Kind);
- }
+
+ for (auto &S : ForceRemoveAttributes) {
+ auto Kind = ParseFunctionAndAttr(S);
+ if (Kind == Attribute::None || !F.hasFnAttribute(Kind))
+ continue;
+ F.removeFnAttr(Kind);
+ }
+}
+
+static bool hasForceAttributes() {
+ return !ForceAttributes.empty() || !ForceRemoveAttributes.empty();
}
-static bool hasForceAttributes() {
- return !ForceAttributes.empty() || !ForceRemoveAttributes.empty();
-}
-
PreservedAnalyses ForceFunctionAttrsPass::run(Module &M,
ModuleAnalysisManager &) {
- if (!hasForceAttributes())
+ if (!hasForceAttributes())
return PreservedAnalyses::all();
for (Function &F : M.functions())
- forceAttributes(F);
+ forceAttributes(F);
// Just conservatively invalidate analyses, this isn't likely to be important.
return PreservedAnalyses::none();
@@ -134,11 +134,11 @@ struct ForceFunctionAttrsLegacyPass : public ModulePass {
}
bool runOnModule(Module &M) override {
- if (!hasForceAttributes())
+ if (!hasForceAttributes())
return false;
for (Function &F : M.functions())
- forceAttributes(F);
+ forceAttributes(F);
// Conservatively assume we changed something.
return true;
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/FunctionAttrs.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/FunctionAttrs.cpp
index c8f19378cb..6730824e86 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -13,7 +13,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/IPO/FunctionAttrs.h"
-#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SCCIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
@@ -22,7 +22,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
-#include "llvm/Analysis/CFG.h"
+#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/CGSCCPassManager.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/CallGraphSCCPass.h"
@@ -64,7 +64,7 @@
using namespace llvm;
-#define DEBUG_TYPE "function-attrs"
+#define DEBUG_TYPE "function-attrs"
STATISTIC(NumReadNone, "Number of functions marked readnone");
STATISTIC(NumReadOnly, "Number of functions marked readonly");
@@ -78,7 +78,7 @@ STATISTIC(NumNonNullReturn, "Number of function returns marked nonnull");
STATISTIC(NumNoRecurse, "Number of functions marked as norecurse");
STATISTIC(NumNoUnwind, "Number of functions marked as nounwind");
STATISTIC(NumNoFree, "Number of functions marked as nofree");
-STATISTIC(NumWillReturn, "Number of functions marked as willreturn");
+STATISTIC(NumWillReturn, "Number of functions marked as willreturn");
static cl::opt<bool> EnableNonnullArgPropagation(
"enable-nonnull-arg-prop", cl::init(true), cl::Hidden,
@@ -149,13 +149,13 @@ static MemoryAccessKind checkFunctionMemoryAccess(Function &F, bool ThisBody,
if (isNoModRef(MRI))
continue;
- // A pseudo probe call shouldn't change any function attribute since it
- // doesn't translate to a real instruction. It comes with a memory access
- // tag to prevent itself being removed by optimizations and not block
- // other instructions being optimized.
- if (isa<PseudoProbeInst>(I))
- continue;
-
+ // A pseudo probe call shouldn't change any function attribute since it
+ // doesn't translate to a real instruction. It comes with a memory access
+ // tag to prevent itself being removed by optimizations and not block
+ // other instructions being optimized.
+ if (isa<PseudoProbeInst>(I))
+ continue;
+
if (!AliasAnalysis::onlyAccessesArgPointees(MRB)) {
// The call could access any memory. If that includes writes, note it.
if (isModSet(MRI))
@@ -175,7 +175,7 @@ static MemoryAccessKind checkFunctionMemoryAccess(Function &F, bool ThisBody,
AAMDNodes AAInfo;
I->getAAMetadata(AAInfo);
- MemoryLocation Loc = MemoryLocation::getBeforeOrAfter(Arg, AAInfo);
+ MemoryLocation Loc = MemoryLocation::getBeforeOrAfter(Arg, AAInfo);
// Skip accesses to local or constant memory as they don't impact the
// externally visible mod/ref behavior.
@@ -290,18 +290,18 @@ static bool addReadAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter) {
MadeChange = true;
// Clear out any existing attributes.
- AttrBuilder AttrsToRemove;
- AttrsToRemove.addAttribute(Attribute::ReadOnly);
- AttrsToRemove.addAttribute(Attribute::ReadNone);
- AttrsToRemove.addAttribute(Attribute::WriteOnly);
+ AttrBuilder AttrsToRemove;
+ AttrsToRemove.addAttribute(Attribute::ReadOnly);
+ AttrsToRemove.addAttribute(Attribute::ReadNone);
+ AttrsToRemove.addAttribute(Attribute::WriteOnly);
if (!WritesMemory && !ReadsMemory) {
// Clear out any "access range attributes" if readnone was deduced.
- AttrsToRemove.addAttribute(Attribute::ArgMemOnly);
- AttrsToRemove.addAttribute(Attribute::InaccessibleMemOnly);
- AttrsToRemove.addAttribute(Attribute::InaccessibleMemOrArgMemOnly);
+ AttrsToRemove.addAttribute(Attribute::ArgMemOnly);
+ AttrsToRemove.addAttribute(Attribute::InaccessibleMemOnly);
+ AttrsToRemove.addAttribute(Attribute::InaccessibleMemOrArgMemOnly);
}
- F->removeAttributes(AttributeList::FunctionIndex, AttrsToRemove);
+ F->removeAttributes(AttributeList::FunctionIndex, AttrsToRemove);
// Add in the new attribute.
if (WritesMemory && !ReadsMemory)
@@ -650,7 +650,7 @@ static bool addArgumentAttrsFromCallsites(Function &F) {
if (auto *CB = dyn_cast<CallBase>(&I)) {
if (auto *CalledFunc = CB->getCalledFunction()) {
for (auto &CSArg : CalledFunc->args()) {
- if (!CSArg.hasNonNullAttr(/* AllowUndefOrPoison */ false))
+ if (!CSArg.hasNonNullAttr(/* AllowUndefOrPoison */ false))
continue;
// If the non-null callsite argument operand is an argument to 'F'
@@ -1227,11 +1227,11 @@ bool AttributeInferer::run(const SCCNodeSet &SCCNodes) {
return Changed;
}
-struct SCCNodesResult {
- SCCNodeSet SCCNodes;
- bool HasUnknownCall;
-};
-
+struct SCCNodesResult {
+ SCCNodeSet SCCNodes;
+ bool HasUnknownCall;
+};
+
} // end anonymous namespace
/// Helper for non-Convergent inference predicate InstrBreaksAttribute.
@@ -1253,7 +1253,7 @@ static bool InstrBreaksNonThrowing(Instruction &I, const SCCNodeSet &SCCNodes) {
// I is a may-throw call to a function inside our SCC. This doesn't
// invalidate our current working assumption that the SCC is no-throw; we
// just have to scan that other function.
- if (SCCNodes.contains(Callee))
+ if (SCCNodes.contains(Callee))
return false;
}
}
@@ -1273,16 +1273,16 @@ static bool InstrBreaksNoFree(Instruction &I, const SCCNodeSet &SCCNodes) {
if (Callee->doesNotFreeMemory())
return false;
- if (SCCNodes.contains(Callee))
+ if (SCCNodes.contains(Callee))
return false;
return true;
}
-/// Attempt to remove convergent function attribute when possible.
+/// Attempt to remove convergent function attribute when possible.
///
/// Returns true if any changes to function attributes were made.
-static bool inferConvergent(const SCCNodeSet &SCCNodes) {
+static bool inferConvergent(const SCCNodeSet &SCCNodes) {
AttributeInferer AI;
// Request to remove the convergent attribute from all functions in the SCC
@@ -1304,19 +1304,19 @@ static bool inferConvergent(const SCCNodeSet &SCCNodes) {
F.setNotConvergent();
},
/* RequiresExactDefinition= */ false});
- // Perform all the requested attribute inference actions.
- return AI.run(SCCNodes);
-}
-
-/// Infer attributes from all functions in the SCC by scanning every
-/// instruction for compliance to the attribute assumptions. Currently it
-/// does:
-/// - addition of NoUnwind attribute
-///
-/// Returns true if any changes to function attributes were made.
-static bool inferAttrsFromFunctionBodies(const SCCNodeSet &SCCNodes) {
- AttributeInferer AI;
-
+ // Perform all the requested attribute inference actions.
+ return AI.run(SCCNodes);
+}
+
+/// Infer attributes from all functions in the SCC by scanning every
+/// instruction for compliance to the attribute assumptions. Currently it
+/// does:
+/// - addition of NoUnwind attribute
+///
+/// Returns true if any changes to function attributes were made.
+static bool inferAttrsFromFunctionBodies(const SCCNodeSet &SCCNodes) {
+ AttributeInferer AI;
+
if (!DisableNoUnwindInference)
// Request to infer nounwind attribute for all the functions in the SCC if
// every callsite within the SCC is not throwing (except for calls to
@@ -1392,139 +1392,139 @@ static bool addNoRecurseAttrs(const SCCNodeSet &SCCNodes) {
// Every call was to a non-recursive function other than this function, and
// we have no indirect recursion as the SCC size is one. This function cannot
// recurse.
- F->setDoesNotRecurse();
- ++NumNoRecurse;
- return true;
+ F->setDoesNotRecurse();
+ ++NumNoRecurse;
+ return true;
+}
+
+static bool instructionDoesNotReturn(Instruction &I) {
+ if (auto *CB = dyn_cast<CallBase>(&I)) {
+ Function *Callee = CB->getCalledFunction();
+ return Callee && Callee->doesNotReturn();
+ }
+ return false;
+}
+
+// A basic block can only return if it terminates with a ReturnInst and does not
+// contain calls to noreturn functions.
+static bool basicBlockCanReturn(BasicBlock &BB) {
+ if (!isa<ReturnInst>(BB.getTerminator()))
+ return false;
+ return none_of(BB, instructionDoesNotReturn);
+}
+
+// Set the noreturn function attribute if possible.
+static bool addNoReturnAttrs(const SCCNodeSet &SCCNodes) {
+ bool Changed = false;
+
+ for (Function *F : SCCNodes) {
+ if (!F || !F->hasExactDefinition() || F->hasFnAttribute(Attribute::Naked) ||
+ F->doesNotReturn())
+ continue;
+
+ // The function can return if any basic blocks can return.
+ // FIXME: this doesn't handle recursion or unreachable blocks.
+ if (none_of(*F, basicBlockCanReturn)) {
+ F->setDoesNotReturn();
+ Changed = true;
+ }
+ }
+
+ return Changed;
+}
+
+static bool functionWillReturn(const Function &F) {
+ // Must-progress function without side-effects must return.
+ if (F.mustProgress() && F.onlyReadsMemory())
+ return true;
+
+ // Can only analyze functions with a definition.
+ if (F.isDeclaration())
+ return false;
+
+ // Functions with loops require more sophisticated analysis, as the loop
+ // may be infinite. For now, don't try to handle them.
+ SmallVector<std::pair<const BasicBlock *, const BasicBlock *>> Backedges;
+ FindFunctionBackedges(F, Backedges);
+ if (!Backedges.empty())
+ return false;
+
+ // If there are no loops, then the function is willreturn if all calls in
+ // it are willreturn.
+ return all_of(instructions(F), [](const Instruction &I) {
+ return I.willReturn();
+ });
+}
+
+// Set the willreturn function attribute if possible.
+static bool addWillReturn(const SCCNodeSet &SCCNodes) {
+ bool Changed = false;
+
+ for (Function *F : SCCNodes) {
+ if (!F || F->willReturn() || !functionWillReturn(*F))
+ continue;
+
+ F->setWillReturn();
+ NumWillReturn++;
+ Changed = true;
+ }
+
+ return Changed;
+}
+
+static SCCNodesResult createSCCNodeSet(ArrayRef<Function *> Functions) {
+ SCCNodesResult Res;
+ Res.HasUnknownCall = false;
+ for (Function *F : Functions) {
+ if (!F || F->hasOptNone() || F->hasFnAttribute(Attribute::Naked)) {
+ // Treat any function we're trying not to optimize as if it were an
+ // indirect call and omit it from the node set used below.
+ Res.HasUnknownCall = true;
+ continue;
+ }
+ // Track whether any functions in this SCC have an unknown call edge.
+ // Note: if this is ever a performance hit, we can common it with
+ // subsequent routines which also do scans over the instructions of the
+ // function.
+ if (!Res.HasUnknownCall) {
+ for (Instruction &I : instructions(*F)) {
+ if (auto *CB = dyn_cast<CallBase>(&I)) {
+ if (!CB->getCalledFunction()) {
+ Res.HasUnknownCall = true;
+ break;
+ }
+ }
+ }
+ }
+ Res.SCCNodes.insert(F);
+ }
+ return Res;
}
-static bool instructionDoesNotReturn(Instruction &I) {
- if (auto *CB = dyn_cast<CallBase>(&I)) {
- Function *Callee = CB->getCalledFunction();
- return Callee && Callee->doesNotReturn();
- }
- return false;
-}
-
-// A basic block can only return if it terminates with a ReturnInst and does not
-// contain calls to noreturn functions.
-static bool basicBlockCanReturn(BasicBlock &BB) {
- if (!isa<ReturnInst>(BB.getTerminator()))
- return false;
- return none_of(BB, instructionDoesNotReturn);
-}
-
-// Set the noreturn function attribute if possible.
-static bool addNoReturnAttrs(const SCCNodeSet &SCCNodes) {
- bool Changed = false;
-
- for (Function *F : SCCNodes) {
- if (!F || !F->hasExactDefinition() || F->hasFnAttribute(Attribute::Naked) ||
- F->doesNotReturn())
- continue;
-
- // The function can return if any basic blocks can return.
- // FIXME: this doesn't handle recursion or unreachable blocks.
- if (none_of(*F, basicBlockCanReturn)) {
- F->setDoesNotReturn();
- Changed = true;
- }
- }
-
- return Changed;
-}
-
-static bool functionWillReturn(const Function &F) {
- // Must-progress function without side-effects must return.
- if (F.mustProgress() && F.onlyReadsMemory())
- return true;
-
- // Can only analyze functions with a definition.
- if (F.isDeclaration())
- return false;
-
- // Functions with loops require more sophisticated analysis, as the loop
- // may be infinite. For now, don't try to handle them.
- SmallVector<std::pair<const BasicBlock *, const BasicBlock *>> Backedges;
- FindFunctionBackedges(F, Backedges);
- if (!Backedges.empty())
- return false;
-
- // If there are no loops, then the function is willreturn if all calls in
- // it are willreturn.
- return all_of(instructions(F), [](const Instruction &I) {
- return I.willReturn();
- });
-}
-
-// Set the willreturn function attribute if possible.
-static bool addWillReturn(const SCCNodeSet &SCCNodes) {
- bool Changed = false;
-
- for (Function *F : SCCNodes) {
- if (!F || F->willReturn() || !functionWillReturn(*F))
- continue;
-
- F->setWillReturn();
- NumWillReturn++;
- Changed = true;
- }
-
- return Changed;
-}
-
-static SCCNodesResult createSCCNodeSet(ArrayRef<Function *> Functions) {
- SCCNodesResult Res;
- Res.HasUnknownCall = false;
- for (Function *F : Functions) {
- if (!F || F->hasOptNone() || F->hasFnAttribute(Attribute::Naked)) {
- // Treat any function we're trying not to optimize as if it were an
- // indirect call and omit it from the node set used below.
- Res.HasUnknownCall = true;
- continue;
- }
- // Track whether any functions in this SCC have an unknown call edge.
- // Note: if this is ever a performance hit, we can common it with
- // subsequent routines which also do scans over the instructions of the
- // function.
- if (!Res.HasUnknownCall) {
- for (Instruction &I : instructions(*F)) {
- if (auto *CB = dyn_cast<CallBase>(&I)) {
- if (!CB->getCalledFunction()) {
- Res.HasUnknownCall = true;
- break;
- }
- }
- }
- }
- Res.SCCNodes.insert(F);
- }
- return Res;
-}
-
template <typename AARGetterT>
-static bool deriveAttrsInPostOrder(ArrayRef<Function *> Functions,
- AARGetterT &&AARGetter) {
- SCCNodesResult Nodes = createSCCNodeSet(Functions);
+static bool deriveAttrsInPostOrder(ArrayRef<Function *> Functions,
+ AARGetterT &&AARGetter) {
+ SCCNodesResult Nodes = createSCCNodeSet(Functions);
bool Changed = false;
// Bail if the SCC only contains optnone functions.
- if (Nodes.SCCNodes.empty())
+ if (Nodes.SCCNodes.empty())
return Changed;
- Changed |= addArgumentReturnedAttrs(Nodes.SCCNodes);
- Changed |= addReadAttrs(Nodes.SCCNodes, AARGetter);
- Changed |= addArgumentAttrs(Nodes.SCCNodes);
- Changed |= inferConvergent(Nodes.SCCNodes);
- Changed |= addNoReturnAttrs(Nodes.SCCNodes);
- Changed |= addWillReturn(Nodes.SCCNodes);
+ Changed |= addArgumentReturnedAttrs(Nodes.SCCNodes);
+ Changed |= addReadAttrs(Nodes.SCCNodes, AARGetter);
+ Changed |= addArgumentAttrs(Nodes.SCCNodes);
+ Changed |= inferConvergent(Nodes.SCCNodes);
+ Changed |= addNoReturnAttrs(Nodes.SCCNodes);
+ Changed |= addWillReturn(Nodes.SCCNodes);
// If we have no external nodes participating in the SCC, we can deduce some
// more precise attributes as well.
- if (!Nodes.HasUnknownCall) {
- Changed |= addNoAliasAttrs(Nodes.SCCNodes);
- Changed |= addNonNullAttrs(Nodes.SCCNodes);
- Changed |= inferAttrsFromFunctionBodies(Nodes.SCCNodes);
- Changed |= addNoRecurseAttrs(Nodes.SCCNodes);
+ if (!Nodes.HasUnknownCall) {
+ Changed |= addNoAliasAttrs(Nodes.SCCNodes);
+ Changed |= addNonNullAttrs(Nodes.SCCNodes);
+ Changed |= inferAttrsFromFunctionBodies(Nodes.SCCNodes);
+ Changed |= addNoRecurseAttrs(Nodes.SCCNodes);
}
return Changed;
@@ -1543,12 +1543,12 @@ PreservedAnalyses PostOrderFunctionAttrsPass::run(LazyCallGraph::SCC &C,
return FAM.getResult<AAManager>(F);
};
- SmallVector<Function *, 8> Functions;
+ SmallVector<Function *, 8> Functions;
for (LazyCallGraph::Node &N : C) {
- Functions.push_back(&N.getFunction());
+ Functions.push_back(&N.getFunction());
}
- if (deriveAttrsInPostOrder(Functions, AARGetter))
+ if (deriveAttrsInPostOrder(Functions, AARGetter))
return PreservedAnalyses::none();
return PreservedAnalyses::all();
@@ -1578,11 +1578,11 @@ struct PostOrderFunctionAttrsLegacyPass : public CallGraphSCCPass {
} // end anonymous namespace
char PostOrderFunctionAttrsLegacyPass::ID = 0;
-INITIALIZE_PASS_BEGIN(PostOrderFunctionAttrsLegacyPass, "function-attrs",
+INITIALIZE_PASS_BEGIN(PostOrderFunctionAttrsLegacyPass, "function-attrs",
"Deduce function attributes", false, false)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
-INITIALIZE_PASS_END(PostOrderFunctionAttrsLegacyPass, "function-attrs",
+INITIALIZE_PASS_END(PostOrderFunctionAttrsLegacyPass, "function-attrs",
"Deduce function attributes", false, false)
Pass *llvm::createPostOrderFunctionAttrsLegacyPass() {
@@ -1591,12 +1591,12 @@ Pass *llvm::createPostOrderFunctionAttrsLegacyPass() {
template <typename AARGetterT>
static bool runImpl(CallGraphSCC &SCC, AARGetterT AARGetter) {
- SmallVector<Function *, 8> Functions;
+ SmallVector<Function *, 8> Functions;
for (CallGraphNode *I : SCC) {
- Functions.push_back(I->getFunction());
+ Functions.push_back(I->getFunction());
}
- return deriveAttrsInPostOrder(Functions, AARGetter);
+ return deriveAttrsInPostOrder(Functions, AARGetter);
}
bool PostOrderFunctionAttrsLegacyPass::runOnSCC(CallGraphSCC &SCC) {
@@ -1629,13 +1629,13 @@ struct ReversePostOrderFunctionAttrsLegacyPass : public ModulePass {
char ReversePostOrderFunctionAttrsLegacyPass::ID = 0;
-INITIALIZE_PASS_BEGIN(ReversePostOrderFunctionAttrsLegacyPass,
- "rpo-function-attrs", "Deduce function attributes in RPO",
- false, false)
+INITIALIZE_PASS_BEGIN(ReversePostOrderFunctionAttrsLegacyPass,
+ "rpo-function-attrs", "Deduce function attributes in RPO",
+ false, false)
INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
-INITIALIZE_PASS_END(ReversePostOrderFunctionAttrsLegacyPass,
- "rpo-function-attrs", "Deduce function attributes in RPO",
- false, false)
+INITIALIZE_PASS_END(ReversePostOrderFunctionAttrsLegacyPass,
+ "rpo-function-attrs", "Deduce function attributes in RPO",
+ false, false)
Pass *llvm::createReversePostOrderFunctionAttrsPass() {
return new ReversePostOrderFunctionAttrsLegacyPass();
@@ -1667,9 +1667,9 @@ static bool addNoRecurseAttrsTopDown(Function &F) {
if (!CB || !CB->getParent()->getParent()->doesNotRecurse())
return false;
}
- F.setDoesNotRecurse();
- ++NumNoRecurse;
- return true;
+ F.setDoesNotRecurse();
+ ++NumNoRecurse;
+ return true;
}
static bool deduceFunctionAttributeInRPO(Module &M, CallGraph &CG) {
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/FunctionImport.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/FunctionImport.cpp
index 4c5a295f5b..18343030bc 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/FunctionImport.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/FunctionImport.cpp
@@ -124,8 +124,8 @@ static cl::opt<bool> ComputeDead("compute-dead", cl::init(true), cl::Hidden,
cl::desc("Compute dead symbols"));
static cl::opt<bool> EnableImportMetadata(
- "enable-import-metadata", cl::init(false), cl::Hidden,
- cl::desc("Enable import metadata like 'thinlto_src_module'"));
+ "enable-import-metadata", cl::init(false), cl::Hidden,
+ cl::desc("Enable import metadata like 'thinlto_src_module'"));
/// Summary file to use for function importing when using -function-import from
/// the command line.
@@ -255,8 +255,8 @@ selectCallee(const ModuleSummaryIndex &Index,
namespace {
-using EdgeInfo =
- std::tuple<const GlobalValueSummary *, unsigned /* Threshold */>;
+using EdgeInfo =
+ std::tuple<const GlobalValueSummary *, unsigned /* Threshold */>;
} // anonymous namespace
@@ -276,9 +276,9 @@ updateValueInfoForIndirectCalls(const ModuleSummaryIndex &Index, ValueInfo VI) {
}
static void computeImportForReferencedGlobals(
- const GlobalValueSummary &Summary, const ModuleSummaryIndex &Index,
+ const GlobalValueSummary &Summary, const ModuleSummaryIndex &Index,
const GVSummaryMapTy &DefinedGVSummaries,
- SmallVectorImpl<EdgeInfo> &Worklist,
+ SmallVectorImpl<EdgeInfo> &Worklist,
FunctionImporter::ImportMapTy &ImportList,
StringMap<FunctionImporter::ExportSetTy> *ExportLists) {
for (auto &VI : Summary.refs()) {
@@ -316,11 +316,11 @@ static void computeImportForReferencedGlobals(
// which is more efficient than adding them here.
if (ExportLists)
(*ExportLists)[RefSummary->modulePath()].insert(VI);
-
- // If variable is not writeonly we attempt to recursively analyze
- // its references in order to import referenced constants.
- if (!Index.isWriteOnly(cast<GlobalVarSummary>(RefSummary.get())))
- Worklist.emplace_back(RefSummary.get(), 0);
+
+ // If variable is not writeonly we attempt to recursively analyze
+ // its references in order to import referenced constants.
+ if (!Index.isWriteOnly(cast<GlobalVarSummary>(RefSummary.get())))
+ Worklist.emplace_back(RefSummary.get(), 0);
break;
}
}
@@ -360,7 +360,7 @@ static void computeImportForFunction(
StringMap<FunctionImporter::ExportSetTy> *ExportLists,
FunctionImporter::ImportThresholdsTy &ImportThresholds) {
computeImportForReferencedGlobals(Summary, Index, DefinedGVSummaries,
- Worklist, ImportList, ExportLists);
+ Worklist, ImportList, ExportLists);
static int ImportCount = 0;
for (auto &Edge : Summary.calls()) {
ValueInfo VI = Edge.first;
@@ -508,7 +508,7 @@ static void computeImportForFunction(
ImportCount++;
// Insert the newly imported function to the worklist.
- Worklist.emplace_back(ResolvedCalleeSummary, AdjThreshold);
+ Worklist.emplace_back(ResolvedCalleeSummary, AdjThreshold);
}
}
@@ -549,17 +549,17 @@ static void ComputeImportForModule(
// Process the newly imported functions and add callees to the worklist.
while (!Worklist.empty()) {
- auto GVInfo = Worklist.pop_back_val();
- auto *Summary = std::get<0>(GVInfo);
- auto Threshold = std::get<1>(GVInfo);
-
- if (auto *FS = dyn_cast<FunctionSummary>(Summary))
- computeImportForFunction(*FS, Index, Threshold, DefinedGVSummaries,
- Worklist, ImportList, ExportLists,
- ImportThresholds);
- else
- computeImportForReferencedGlobals(*Summary, Index, DefinedGVSummaries,
- Worklist, ImportList, ExportLists);
+ auto GVInfo = Worklist.pop_back_val();
+ auto *Summary = std::get<0>(GVInfo);
+ auto Threshold = std::get<1>(GVInfo);
+
+ if (auto *FS = dyn_cast<FunctionSummary>(Summary))
+ computeImportForFunction(*FS, Index, Threshold, DefinedGVSummaries,
+ Worklist, ImportList, ExportLists,
+ ImportThresholds);
+ else
+ computeImportForReferencedGlobals(*Summary, Index, DefinedGVSummaries,
+ Worklist, ImportList, ExportLists);
}
// Print stats about functions considered but rejected for importing
@@ -888,7 +888,7 @@ void llvm::computeDeadSymbols(
while (!Worklist.empty()) {
auto VI = Worklist.pop_back_val();
for (auto &Summary : VI.getSummaryList()) {
- Summary->setLive(true);
+ Summary->setLive(true);
if (auto *AS = dyn_cast<AliasSummary>(Summary.get())) {
// If this is an alias, visit the aliasee VI to ensure that all copies
// are marked live and it is added to the worklist for further
@@ -1314,7 +1314,7 @@ static bool doImportingForModule(Module &M) {
// Next we need to promote to global scope and rename any local values that
// are potentially exported to other modules.
- if (renameModuleForThinLTO(M, *Index, /*ClearDSOLocalOnDeclarations=*/false,
+ if (renameModuleForThinLTO(M, *Index, /*ClearDSOLocalOnDeclarations=*/false,
/*GlobalsToImport=*/nullptr)) {
errs() << "Error renaming module\n";
return false;
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/GlobalOpt.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/GlobalOpt.cpp
index b06fc36b72..223a05e8ea 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/GlobalOpt.cpp
@@ -268,7 +268,7 @@ CleanupPointerRootUsers(GlobalVariable *GV,
I = J;
} while (true);
I->eraseFromParent();
- Changed = true;
+ Changed = true;
}
}
@@ -286,7 +286,7 @@ static bool CleanupConstantGlobalUsers(
// we delete a constant array, we may also be holding pointer to one of its
// elements (or an element of one of its elements if we're dealing with an
// array of arrays) in the worklist.
- SmallVector<WeakTrackingVH, 8> WorkList(V->users());
+ SmallVector<WeakTrackingVH, 8> WorkList(V->users());
while (!WorkList.empty()) {
Value *UV = WorkList.pop_back_val();
if (!UV)
@@ -1880,8 +1880,8 @@ static bool isPointerValueDeadOnEntryToFunction(
// and the number of bits loaded in L is less than or equal to
// the number of bits stored in S.
return DT.dominates(S, L) &&
- DL.getTypeStoreSize(LTy).getFixedSize() <=
- DL.getTypeStoreSize(STy).getFixedSize();
+ DL.getTypeStoreSize(LTy).getFixedSize() <=
+ DL.getTypeStoreSize(STy).getFixedSize();
}))
return false;
}
@@ -1933,7 +1933,7 @@ static void makeAllConstantUsesInstructions(Constant *C) {
SmallVector<Value*,4> UUsers;
for (auto *U : Users) {
UUsers.clear();
- append_range(UUsers, U->users());
+ append_range(UUsers, U->users());
for (auto *UU : UUsers) {
Instruction *UI = cast<Instruction>(UU);
Instruction *NewU = U->getAsInstruction();
@@ -1990,8 +1990,8 @@ processInternalGlobal(GlobalVariable *GV, const GlobalStatus &GS,
return true;
}
- bool Changed = false;
-
+ bool Changed = false;
+
// If the global is never loaded (but may be stored to), it is dead.
// Delete it now.
if (!GS.IsLoaded) {
@@ -2022,14 +2022,14 @@ processInternalGlobal(GlobalVariable *GV, const GlobalStatus &GS,
// Don't actually mark a global constant if it's atomic because atomic loads
// are implemented by a trivial cmpxchg in some edge-cases and that usually
// requires write access to the variable even if it's not actually changed.
- if (GS.Ordering == AtomicOrdering::NotAtomic) {
- assert(!GV->isConstant() && "Expected a non-constant global");
+ if (GS.Ordering == AtomicOrdering::NotAtomic) {
+ assert(!GV->isConstant() && "Expected a non-constant global");
GV->setConstant(true);
- Changed = true;
- }
+ Changed = true;
+ }
// Clean up any obviously simplifiable users now.
- Changed |= CleanupConstantGlobalUsers(GV, GV->getInitializer(), DL, GetTLI);
+ Changed |= CleanupConstantGlobalUsers(GV, GV->getInitializer(), DL, GetTLI);
// If the global is dead now, just nuke it.
if (GV->use_empty()) {
@@ -2089,7 +2089,7 @@ processInternalGlobal(GlobalVariable *GV, const GlobalStatus &GS,
}
}
- return Changed;
+ return Changed;
}
/// Analyze the specified global variable and optimize it if possible. If we
@@ -2224,7 +2224,7 @@ isValidCandidateForColdCC(Function &F,
BlockFrequencyInfo &CallerBFI = GetBFI(*CallerFunc);
if (!isColdCallSite(CB, CallerBFI))
return false;
- if (!llvm::is_contained(AllCallsCold, CallerFunc))
+ if (!llvm::is_contained(AllCallsCold, CallerFunc))
return false;
}
return true;
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/HotColdSplitting.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/HotColdSplitting.cpp
index 0f91173aab..aa708ee520 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/HotColdSplitting.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/HotColdSplitting.cpp
@@ -67,9 +67,9 @@
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include <algorithm>
-#include <limits>
+#include <limits>
#include <cassert>
-#include <string>
+#include <string>
#define DEBUG_TYPE "hotcoldsplit"
@@ -78,29 +78,29 @@ STATISTIC(NumColdRegionsOutlined, "Number of cold regions outlined.");
using namespace llvm;
-static cl::opt<bool> EnableStaticAnalysis("hot-cold-static-analysis",
- cl::init(true), cl::Hidden);
+static cl::opt<bool> EnableStaticAnalysis("hot-cold-static-analysis",
+ cl::init(true), cl::Hidden);
static cl::opt<int>
SplittingThreshold("hotcoldsplit-threshold", cl::init(2), cl::Hidden,
cl::desc("Base penalty for splitting cold code (as a "
"multiple of TCC_Basic)"));
-static cl::opt<bool> EnableColdSection(
- "enable-cold-section", cl::init(false), cl::Hidden,
- cl::desc("Enable placement of extracted cold functions"
- " into a separate section after hot-cold splitting."));
-
-static cl::opt<std::string>
- ColdSectionName("hotcoldsplit-cold-section-name", cl::init("__llvm_cold"),
- cl::Hidden,
- cl::desc("Name for the section containing cold functions "
- "extracted by hot-cold splitting."));
-
-static cl::opt<int> MaxParametersForSplit(
- "hotcoldsplit-max-params", cl::init(4), cl::Hidden,
- cl::desc("Maximum number of parameters for a split function"));
-
+static cl::opt<bool> EnableColdSection(
+ "enable-cold-section", cl::init(false), cl::Hidden,
+ cl::desc("Enable placement of extracted cold functions"
+ " into a separate section after hot-cold splitting."));
+
+static cl::opt<std::string>
+ ColdSectionName("hotcoldsplit-cold-section-name", cl::init("__llvm_cold"),
+ cl::Hidden,
+ cl::desc("Name for the section containing cold functions "
+ "extracted by hot-cold splitting."));
+
+static cl::opt<int> MaxParametersForSplit(
+ "hotcoldsplit-max-params", cl::init(4), cl::Hidden,
+ cl::desc("Maximum number of parameters for a split function"));
+
namespace {
// Same as blockEndsInUnreachable in CodeGen/BranchFolding.cpp. Do not modify
// this function unless you modify the MBB version as well.
@@ -237,11 +237,11 @@ bool HotColdSplitting::shouldOutlineFrom(const Function &F) const {
}
/// Get the benefit score of outlining \p Region.
-static InstructionCost getOutliningBenefit(ArrayRef<BasicBlock *> Region,
- TargetTransformInfo &TTI) {
+static InstructionCost getOutliningBenefit(ArrayRef<BasicBlock *> Region,
+ TargetTransformInfo &TTI) {
// Sum up the code size costs of non-terminator instructions. Tight coupling
// with \ref getOutliningPenalty is needed to model the costs of terminators.
- InstructionCost Benefit = 0;
+ InstructionCost Benefit = 0;
for (BasicBlock *BB : Region)
for (Instruction &I : BB->instructionsWithoutDebug())
if (&I != BB->getTerminator())
@@ -275,55 +275,55 @@ static int getOutliningPenalty(ArrayRef<BasicBlock *> Region,
}
for (BasicBlock *SuccBB : successors(BB)) {
- if (!is_contained(Region, SuccBB)) {
+ if (!is_contained(Region, SuccBB)) {
NoBlocksReturn = false;
SuccsOutsideRegion.insert(SuccBB);
}
}
}
- // Count the number of phis in exit blocks with >= 2 incoming values from the
- // outlining region. These phis are split (\ref severSplitPHINodesOfExits),
- // and new outputs are created to supply the split phis. CodeExtractor can't
- // report these new outputs until extraction begins, but it's important to
- // factor the cost of the outputs into the cost calculation.
- unsigned NumSplitExitPhis = 0;
- for (BasicBlock *ExitBB : SuccsOutsideRegion) {
- for (PHINode &PN : ExitBB->phis()) {
- // Find all incoming values from the outlining region.
- int NumIncomingVals = 0;
- for (unsigned i = 0; i < PN.getNumIncomingValues(); ++i)
- if (find(Region, PN.getIncomingBlock(i)) != Region.end()) {
- ++NumIncomingVals;
- if (NumIncomingVals > 1) {
- ++NumSplitExitPhis;
- break;
- }
- }
- }
- }
-
- // Apply a penalty for calling the split function. Factor in the cost of
- // materializing all of the parameters.
- int NumOutputsAndSplitPhis = NumOutputs + NumSplitExitPhis;
- int NumParams = NumInputs + NumOutputsAndSplitPhis;
- if (NumParams > MaxParametersForSplit) {
- LLVM_DEBUG(dbgs() << NumInputs << " inputs and " << NumOutputsAndSplitPhis
- << " outputs exceeds parameter limit ("
- << MaxParametersForSplit << ")\n");
- return std::numeric_limits<int>::max();
- }
- const int CostForArgMaterialization = 2 * TargetTransformInfo::TCC_Basic;
- LLVM_DEBUG(dbgs() << "Applying penalty for: " << NumParams << " params\n");
- Penalty += CostForArgMaterialization * NumParams;
-
- // Apply the typical code size cost for an output alloca and its associated
- // reload in the caller. Also penalize the associated store in the callee.
- LLVM_DEBUG(dbgs() << "Applying penalty for: " << NumOutputsAndSplitPhis
- << " outputs/split phis\n");
- const int CostForRegionOutput = 3 * TargetTransformInfo::TCC_Basic;
- Penalty += CostForRegionOutput * NumOutputsAndSplitPhis;
-
+ // Count the number of phis in exit blocks with >= 2 incoming values from the
+ // outlining region. These phis are split (\ref severSplitPHINodesOfExits),
+ // and new outputs are created to supply the split phis. CodeExtractor can't
+ // report these new outputs until extraction begins, but it's important to
+ // factor the cost of the outputs into the cost calculation.
+ unsigned NumSplitExitPhis = 0;
+ for (BasicBlock *ExitBB : SuccsOutsideRegion) {
+ for (PHINode &PN : ExitBB->phis()) {
+ // Find all incoming values from the outlining region.
+ int NumIncomingVals = 0;
+ for (unsigned i = 0; i < PN.getNumIncomingValues(); ++i)
+ if (find(Region, PN.getIncomingBlock(i)) != Region.end()) {
+ ++NumIncomingVals;
+ if (NumIncomingVals > 1) {
+ ++NumSplitExitPhis;
+ break;
+ }
+ }
+ }
+ }
+
+ // Apply a penalty for calling the split function. Factor in the cost of
+ // materializing all of the parameters.
+ int NumOutputsAndSplitPhis = NumOutputs + NumSplitExitPhis;
+ int NumParams = NumInputs + NumOutputsAndSplitPhis;
+ if (NumParams > MaxParametersForSplit) {
+ LLVM_DEBUG(dbgs() << NumInputs << " inputs and " << NumOutputsAndSplitPhis
+ << " outputs exceeds parameter limit ("
+ << MaxParametersForSplit << ")\n");
+ return std::numeric_limits<int>::max();
+ }
+ const int CostForArgMaterialization = 2 * TargetTransformInfo::TCC_Basic;
+ LLVM_DEBUG(dbgs() << "Applying penalty for: " << NumParams << " params\n");
+ Penalty += CostForArgMaterialization * NumParams;
+
+ // Apply the typical code size cost for an output alloca and its associated
+ // reload in the caller. Also penalize the associated store in the callee.
+ LLVM_DEBUG(dbgs() << "Applying penalty for: " << NumOutputsAndSplitPhis
+ << " outputs/split phis\n");
+ const int CostForRegionOutput = 3 * TargetTransformInfo::TCC_Basic;
+ Penalty += CostForRegionOutput * NumOutputsAndSplitPhis;
+
// Apply a `noreturn` bonus.
if (NoBlocksReturn) {
LLVM_DEBUG(dbgs() << "Applying bonus for: " << Region.size()
@@ -333,7 +333,7 @@ static int getOutliningPenalty(ArrayRef<BasicBlock *> Region,
// Apply a penalty for having more than one successor outside of the region.
// This penalty accounts for the switch needed in the caller.
- if (SuccsOutsideRegion.size() > 1) {
+ if (SuccsOutsideRegion.size() > 1) {
LLVM_DEBUG(dbgs() << "Applying penalty for: " << SuccsOutsideRegion.size()
<< " non-region successors\n");
Penalty += (SuccsOutsideRegion.size() - 1) * TargetTransformInfo::TCC_Basic;
@@ -358,12 +358,12 @@ Function *HotColdSplitting::extractColdRegion(
// splitting.
SetVector<Value *> Inputs, Outputs, Sinks;
CE.findInputsOutputs(Inputs, Outputs, Sinks);
- InstructionCost OutliningBenefit = getOutliningBenefit(Region, TTI);
+ InstructionCost OutliningBenefit = getOutliningBenefit(Region, TTI);
int OutliningPenalty =
getOutliningPenalty(Region, Inputs.size(), Outputs.size());
LLVM_DEBUG(dbgs() << "Split profitability: benefit = " << OutliningBenefit
<< ", penalty = " << OutliningPenalty << "\n");
- if (!OutliningBenefit.isValid() || OutliningBenefit <= OutliningPenalty)
+ if (!OutliningBenefit.isValid() || OutliningBenefit <= OutliningPenalty)
return nullptr;
Function *OrigF = Region[0]->getParent();
@@ -377,12 +377,12 @@ Function *HotColdSplitting::extractColdRegion(
}
CI->setIsNoInline();
- if (EnableColdSection)
- OutF->setSection(ColdSectionName);
- else {
- if (OrigF->hasSection())
- OutF->setSection(OrigF->getSection());
- }
+ if (EnableColdSection)
+ OutF->setSection(ColdSectionName);
+ else {
+ if (OrigF->hasSection())
+ OutF->setSection(OrigF->getSection());
+ }
markFunctionCold(*OutF, BFI != nullptr);
@@ -625,7 +625,7 @@ bool HotColdSplitting::outlineColdRegions(Function &F, bool HasProfileSummary) {
continue;
bool Cold = (BFI && PSI->isColdBlock(BB, BFI)) ||
- (EnableStaticAnalysis && unlikelyExecuted(*BB));
+ (EnableStaticAnalysis && unlikelyExecuted(*BB));
if (!Cold)
continue;
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/IPO.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/IPO.cpp
index 30a47e3fce..f4c12dd7f4 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/IPO.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/IPO.cpp
@@ -25,7 +25,7 @@ using namespace llvm;
void llvm::initializeIPO(PassRegistry &Registry) {
initializeOpenMPOptLegacyPassPass(Registry);
initializeArgPromotionPass(Registry);
- initializeAnnotation2MetadataLegacyPass(Registry);
+ initializeAnnotation2MetadataLegacyPass(Registry);
initializeCalledValuePropagationLegacyPassPass(Registry);
initializeConstantMergeLegacyPassPass(Registry);
initializeCrossDSOCFIPass(Registry);
@@ -36,13 +36,13 @@ void llvm::initializeIPO(PassRegistry &Registry) {
initializeGlobalOptLegacyPassPass(Registry);
initializeGlobalSplitPass(Registry);
initializeHotColdSplittingLegacyPassPass(Registry);
- initializeIROutlinerLegacyPassPass(Registry);
+ initializeIROutlinerLegacyPassPass(Registry);
initializeAlwaysInlinerLegacyPassPass(Registry);
initializeSimpleInlinerPass(Registry);
initializeInferFunctionAttrsLegacyPassPass(Registry);
initializeInternalizeLegacyPassPass(Registry);
- initializeLoopExtractorLegacyPassPass(Registry);
- initializeBlockExtractorLegacyPassPass(Registry);
+ initializeLoopExtractorLegacyPassPass(Registry);
+ initializeBlockExtractorLegacyPassPass(Registry);
initializeSingleLoopExtractorPass(Registry);
initializeLowerTypeTestsPass(Registry);
initializeMergeFunctionsLegacyPassPass(Registry);
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/IROutliner.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/IROutliner.cpp
index 20ab22d119..4b6a4f3d8f 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/IROutliner.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/IROutliner.cpp
@@ -1,1764 +1,1764 @@
-//===- IROutliner.cpp -- Outline Similar Regions ----------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-// Implementation for the IROutliner which is used by the IROutliner Pass.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/IPO/IROutliner.h"
-#include "llvm/Analysis/IRSimilarityIdentifier.h"
-#include "llvm/Analysis/OptimizationRemarkEmitter.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/IR/Attributes.h"
-#include "llvm/IR/PassManager.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Transforms/IPO.h"
-#include <map>
-#include <set>
-#include <vector>
-
-#define DEBUG_TYPE "iroutliner"
-
-using namespace llvm;
-using namespace IRSimilarity;
-
-// Set to true if the user wants the ir outliner to run on linkonceodr linkage
-// functions. This is false by default because the linker can dedupe linkonceodr
-// functions. Since the outliner is confined to a single module (modulo LTO),
-// this is off by default. It should, however, be the default behavior in
-// LTO.
-static cl::opt<bool> EnableLinkOnceODRIROutlining(
- "enable-linkonceodr-ir-outlining", cl::Hidden,
- cl::desc("Enable the IR outliner on linkonceodr functions"),
- cl::init(false));
-
-// This is a debug option to test small pieces of code to ensure that outlining
-// works correctly.
-static cl::opt<bool> NoCostModel(
- "ir-outlining-no-cost", cl::init(false), cl::ReallyHidden,
- cl::desc("Debug option to outline greedily, without restriction that "
- "calculated benefit outweighs cost"));
-
-/// The OutlinableGroup holds all the overarching information for outlining
-/// a set of regions that are structurally similar to one another, such as the
-/// types of the overall function, the output blocks, the sets of stores needed
-/// and a list of the different regions. This information is used in the
-/// deduplication of extracted regions with the same structure.
-struct OutlinableGroup {
- /// The sections that could be outlined
- std::vector<OutlinableRegion *> Regions;
-
- /// The argument types for the function created as the overall function to
- /// replace the extracted function for each region.
- std::vector<Type *> ArgumentTypes;
- /// The FunctionType for the overall function.
- FunctionType *OutlinedFunctionType = nullptr;
- /// The Function for the collective overall function.
- Function *OutlinedFunction = nullptr;
-
- /// Flag for whether we should not consider this group of OutlinableRegions
- /// for extraction.
- bool IgnoreGroup = false;
-
- /// The return block for the overall function.
- BasicBlock *EndBB = nullptr;
-
- /// A set containing the different GVN store sets needed. Each array contains
- /// a sorted list of the different values that need to be stored into output
- /// registers.
- DenseSet<ArrayRef<unsigned>> OutputGVNCombinations;
-
- /// Flag for whether the \ref ArgumentTypes have been defined after the
- /// extraction of the first region.
- bool InputTypesSet = false;
-
- /// The number of input values in \ref ArgumentTypes. Anything after this
- /// index in ArgumentTypes is an output argument.
- unsigned NumAggregateInputs = 0;
-
- /// The number of instructions that will be outlined by extracting \ref
- /// Regions.
- InstructionCost Benefit = 0;
- /// The number of added instructions needed for the outlining of the \ref
- /// Regions.
- InstructionCost Cost = 0;
-
- /// The argument that needs to be marked with the swifterr attribute. If not
- /// needed, there is no value.
- Optional<unsigned> SwiftErrorArgument;
-
- /// For the \ref Regions, we look at every Value. If it is a constant,
- /// we check whether it is the same in Region.
- ///
- /// \param [in,out] NotSame contains the global value numbers where the
- /// constant is not always the same, and must be passed in as an argument.
- void findSameConstants(DenseSet<unsigned> &NotSame);
-
- /// For the regions, look at each set of GVN stores needed and account for
- /// each combination. Add an argument to the argument types if there is
- /// more than one combination.
- ///
- /// \param [in] M - The module we are outlining from.
- void collectGVNStoreSets(Module &M);
-};
-
-/// Move the contents of \p SourceBB to before the last instruction of \p
-/// TargetBB.
-/// \param SourceBB - the BasicBlock to pull Instructions from.
-/// \param TargetBB - the BasicBlock to put Instruction into.
-static void moveBBContents(BasicBlock &SourceBB, BasicBlock &TargetBB) {
- BasicBlock::iterator BBCurr, BBEnd, BBNext;
- for (BBCurr = SourceBB.begin(), BBEnd = SourceBB.end(); BBCurr != BBEnd;
- BBCurr = BBNext) {
- BBNext = std::next(BBCurr);
- BBCurr->moveBefore(TargetBB, TargetBB.end());
- }
-}
-
-void OutlinableRegion::splitCandidate() {
- assert(!CandidateSplit && "Candidate already split!");
-
- Instruction *StartInst = (*Candidate->begin()).Inst;
- Instruction *EndInst = (*Candidate->end()).Inst;
- assert(StartInst && EndInst && "Expected a start and end instruction?");
- StartBB = StartInst->getParent();
- PrevBB = StartBB;
-
- // The basic block gets split like so:
- // block: block:
- // inst1 inst1
- // inst2 inst2
- // region1 br block_to_outline
- // region2 block_to_outline:
- // region3 -> region1
- // region4 region2
- // inst3 region3
- // inst4 region4
- // br block_after_outline
- // block_after_outline:
- // inst3
- // inst4
-
- std::string OriginalName = PrevBB->getName().str();
-
- StartBB = PrevBB->splitBasicBlock(StartInst, OriginalName + "_to_outline");
-
- // This is the case for the inner block since we do not have to include
- // multiple blocks.
- EndBB = StartBB;
- FollowBB = EndBB->splitBasicBlock(EndInst, OriginalName + "_after_outline");
-
- CandidateSplit = true;
-}
-
-void OutlinableRegion::reattachCandidate() {
- assert(CandidateSplit && "Candidate is not split!");
-
- // The basic block gets reattached like so:
- // block: block:
- // inst1 inst1
- // inst2 inst2
- // br block_to_outline region1
- // block_to_outline: -> region2
- // region1 region3
- // region2 region4
- // region3 inst3
- // region4 inst4
- // br block_after_outline
- // block_after_outline:
- // inst3
- // inst4
- assert(StartBB != nullptr && "StartBB for Candidate is not defined!");
- assert(FollowBB != nullptr && "StartBB for Candidate is not defined!");
-
- // StartBB should only have one predecessor since we put an unconditional
- // branch at the end of PrevBB when we split the BasicBlock.
- PrevBB = StartBB->getSinglePredecessor();
- assert(PrevBB != nullptr &&
- "No Predecessor for the region start basic block!");
-
- assert(PrevBB->getTerminator() && "Terminator removed from PrevBB!");
- assert(EndBB->getTerminator() && "Terminator removed from EndBB!");
- PrevBB->getTerminator()->eraseFromParent();
- EndBB->getTerminator()->eraseFromParent();
-
- moveBBContents(*StartBB, *PrevBB);
-
- BasicBlock *PlacementBB = PrevBB;
- if (StartBB != EndBB)
- PlacementBB = EndBB;
- moveBBContents(*FollowBB, *PlacementBB);
-
- PrevBB->replaceSuccessorsPhiUsesWith(StartBB, PrevBB);
- PrevBB->replaceSuccessorsPhiUsesWith(FollowBB, PlacementBB);
- StartBB->eraseFromParent();
- FollowBB->eraseFromParent();
-
- // Make sure to save changes back to the StartBB.
- StartBB = PrevBB;
- EndBB = nullptr;
- PrevBB = nullptr;
- FollowBB = nullptr;
-
- CandidateSplit = false;
-}
-
-/// Find whether \p V matches the Constants previously found for the \p GVN.
-///
-/// \param V - The value to check for consistency.
-/// \param GVN - The global value number assigned to \p V.
-/// \param GVNToConstant - The mapping of global value number to Constants.
-/// \returns true if the Value matches the Constant mapped to by V and false if
-/// it \p V is a Constant but does not match.
-/// \returns None if \p V is not a Constant.
-static Optional<bool>
-constantMatches(Value *V, unsigned GVN,
- DenseMap<unsigned, Constant *> &GVNToConstant) {
- // See if we have a constants
- Constant *CST = dyn_cast<Constant>(V);
- if (!CST)
- return None;
-
- // Holds a mapping from a global value number to a Constant.
- DenseMap<unsigned, Constant *>::iterator GVNToConstantIt;
- bool Inserted;
-
-
- // If we have a constant, try to make a new entry in the GVNToConstant.
- std::tie(GVNToConstantIt, Inserted) =
- GVNToConstant.insert(std::make_pair(GVN, CST));
- // If it was found and is not equal, it is not the same. We do not
- // handle this case yet, and exit early.
- if (Inserted || (GVNToConstantIt->second == CST))
- return true;
-
- return false;
-}
-
-InstructionCost OutlinableRegion::getBenefit(TargetTransformInfo &TTI) {
- InstructionCost Benefit = 0;
-
- // Estimate the benefit of outlining a specific sections of the program. We
- // delegate mostly this task to the TargetTransformInfo so that if the target
- // has specific changes, we can have a more accurate estimate.
-
- // However, getInstructionCost delegates the code size calculation for
- // arithmetic instructions to getArithmeticInstrCost in
- // include/Analysis/TargetTransformImpl.h, where it always estimates that the
- // code size for a division and remainder instruction to be equal to 4, and
- // everything else to 1. This is not an accurate representation of the
- // division instruction for targets that have a native division instruction.
- // To be overly conservative, we only add 1 to the number of instructions for
- // each division instruction.
- for (Instruction &I : *StartBB) {
- switch (I.getOpcode()) {
- case Instruction::FDiv:
- case Instruction::FRem:
- case Instruction::SDiv:
- case Instruction::SRem:
- case Instruction::UDiv:
- case Instruction::URem:
- Benefit += 1;
- break;
- default:
- Benefit += TTI.getInstructionCost(&I, TargetTransformInfo::TCK_CodeSize);
- break;
- }
- }
-
- return Benefit;
-}
-
-/// Find whether \p Region matches the global value numbering to Constant
-/// mapping found so far.
-///
-/// \param Region - The OutlinableRegion we are checking for constants
-/// \param GVNToConstant - The mapping of global value number to Constants.
-/// \param NotSame - The set of global value numbers that do not have the same
-/// constant in each region.
-/// \returns true if all Constants are the same in every use of a Constant in \p
-/// Region and false if not
-static bool
-collectRegionsConstants(OutlinableRegion &Region,
- DenseMap<unsigned, Constant *> &GVNToConstant,
- DenseSet<unsigned> &NotSame) {
- bool ConstantsTheSame = true;
-
- IRSimilarityCandidate &C = *Region.Candidate;
- for (IRInstructionData &ID : C) {
-
- // Iterate over the operands in an instruction. If the global value number,
- // assigned by the IRSimilarityCandidate, has been seen before, we check if
- // the the number has been found to be not the same value in each instance.
- for (Value *V : ID.OperVals) {
- Optional<unsigned> GVNOpt = C.getGVN(V);
- assert(GVNOpt.hasValue() && "Expected a GVN for operand?");
- unsigned GVN = GVNOpt.getValue();
-
- // Check if this global value has been found to not be the same already.
- if (NotSame.contains(GVN)) {
- if (isa<Constant>(V))
- ConstantsTheSame = false;
- continue;
- }
-
- // If it has been the same so far, we check the value for if the
- // associated Constant value match the previous instances of the same
- // global value number. If the global value does not map to a Constant,
- // it is considered to not be the same value.
- Optional<bool> ConstantMatches = constantMatches(V, GVN, GVNToConstant);
- if (ConstantMatches.hasValue()) {
- if (ConstantMatches.getValue())
- continue;
- else
- ConstantsTheSame = false;
- }
-
- // While this value is a register, it might not have been previously,
- // make sure we don't already have a constant mapped to this global value
- // number.
- if (GVNToConstant.find(GVN) != GVNToConstant.end())
- ConstantsTheSame = false;
-
- NotSame.insert(GVN);
- }
- }
-
- return ConstantsTheSame;
-}
-
-void OutlinableGroup::findSameConstants(DenseSet<unsigned> &NotSame) {
- DenseMap<unsigned, Constant *> GVNToConstant;
-
- for (OutlinableRegion *Region : Regions)
- collectRegionsConstants(*Region, GVNToConstant, NotSame);
-}
-
-void OutlinableGroup::collectGVNStoreSets(Module &M) {
- for (OutlinableRegion *OS : Regions)
- OutputGVNCombinations.insert(OS->GVNStores);
-
- // We are adding an extracted argument to decide between which output path
- // to use in the basic block. It is used in a switch statement and only
- // needs to be an integer.
- if (OutputGVNCombinations.size() > 1)
- ArgumentTypes.push_back(Type::getInt32Ty(M.getContext()));
-}
-
-Function *IROutliner::createFunction(Module &M, OutlinableGroup &Group,
- unsigned FunctionNameSuffix) {
- assert(!Group.OutlinedFunction && "Function is already defined!");
-
- Group.OutlinedFunctionType = FunctionType::get(
- Type::getVoidTy(M.getContext()), Group.ArgumentTypes, false);
-
- // These functions will only be called from within the same module, so
- // we can set an internal linkage.
- Group.OutlinedFunction = Function::Create(
- Group.OutlinedFunctionType, GlobalValue::InternalLinkage,
- "outlined_ir_func_" + std::to_string(FunctionNameSuffix), M);
-
- // Transfer the swifterr attribute to the correct function parameter.
- if (Group.SwiftErrorArgument.hasValue())
- Group.OutlinedFunction->addParamAttr(Group.SwiftErrorArgument.getValue(),
- Attribute::SwiftError);
-
- Group.OutlinedFunction->addFnAttr(Attribute::OptimizeForSize);
- Group.OutlinedFunction->addFnAttr(Attribute::MinSize);
-
- return Group.OutlinedFunction;
-}
-
-/// Move each BasicBlock in \p Old to \p New.
-///
-/// \param [in] Old - the function to move the basic blocks from.
-/// \param [in] New - The function to move the basic blocks to.
-/// \returns the first return block for the function in New.
-static BasicBlock *moveFunctionData(Function &Old, Function &New) {
- Function::iterator CurrBB, NextBB, FinalBB;
- BasicBlock *NewEnd = nullptr;
- std::vector<Instruction *> DebugInsts;
- for (CurrBB = Old.begin(), FinalBB = Old.end(); CurrBB != FinalBB;
- CurrBB = NextBB) {
- NextBB = std::next(CurrBB);
- CurrBB->removeFromParent();
- CurrBB->insertInto(&New);
- Instruction *I = CurrBB->getTerminator();
- if (isa<ReturnInst>(I))
- NewEnd = &(*CurrBB);
- }
-
- assert(NewEnd && "No return instruction for new function?");
- return NewEnd;
-}
-
-/// Find the the constants that will need to be lifted into arguments
-/// as they are not the same in each instance of the region.
-///
-/// \param [in] C - The IRSimilarityCandidate containing the region we are
-/// analyzing.
-/// \param [in] NotSame - The set of global value numbers that do not have a
-/// single Constant across all OutlinableRegions similar to \p C.
-/// \param [out] Inputs - The list containing the global value numbers of the
-/// arguments needed for the region of code.
-static void findConstants(IRSimilarityCandidate &C, DenseSet<unsigned> &NotSame,
- std::vector<unsigned> &Inputs) {
- DenseSet<unsigned> Seen;
- // Iterate over the instructions, and find what constants will need to be
- // extracted into arguments.
- for (IRInstructionDataList::iterator IDIt = C.begin(), EndIDIt = C.end();
- IDIt != EndIDIt; IDIt++) {
- for (Value *V : (*IDIt).OperVals) {
- // Since these are stored before any outlining, they will be in the
- // global value numbering.
- unsigned GVN = C.getGVN(V).getValue();
- if (isa<Constant>(V))
- if (NotSame.contains(GVN) && !Seen.contains(GVN)) {
- Inputs.push_back(GVN);
- Seen.insert(GVN);
- }
- }
- }
-}
-
-/// Find the GVN for the inputs that have been found by the CodeExtractor.
-///
-/// \param [in] C - The IRSimilarityCandidate containing the region we are
-/// analyzing.
-/// \param [in] CurrentInputs - The set of inputs found by the
-/// CodeExtractor.
-/// \param [out] EndInputNumbers - The global value numbers for the extracted
-/// arguments.
-/// \param [in] OutputMappings - The mapping of values that have been replaced
-/// by a new output value.
-/// \param [out] EndInputs - The global value numbers for the extracted
-/// arguments.
-static void mapInputsToGVNs(IRSimilarityCandidate &C,
- SetVector<Value *> &CurrentInputs,
- const DenseMap<Value *, Value *> &OutputMappings,
- std::vector<unsigned> &EndInputNumbers) {
- // Get the Global Value Number for each input. We check if the Value has been
- // replaced by a different value at output, and use the original value before
- // replacement.
- for (Value *Input : CurrentInputs) {
- assert(Input && "Have a nullptr as an input");
- if (OutputMappings.find(Input) != OutputMappings.end())
- Input = OutputMappings.find(Input)->second;
- assert(C.getGVN(Input).hasValue() &&
- "Could not find a numbering for the given input");
- EndInputNumbers.push_back(C.getGVN(Input).getValue());
- }
-}
-
-/// Find the original value for the \p ArgInput values if any one of them was
-/// replaced during a previous extraction.
-///
-/// \param [in] ArgInputs - The inputs to be extracted by the code extractor.
-/// \param [in] OutputMappings - The mapping of values that have been replaced
-/// by a new output value.
-/// \param [out] RemappedArgInputs - The remapped values according to
-/// \p OutputMappings that will be extracted.
-static void
-remapExtractedInputs(const ArrayRef<Value *> ArgInputs,
- const DenseMap<Value *, Value *> &OutputMappings,
- SetVector<Value *> &RemappedArgInputs) {
- // Get the global value number for each input that will be extracted as an
- // argument by the code extractor, remapping if needed for reloaded values.
- for (Value *Input : ArgInputs) {
- if (OutputMappings.find(Input) != OutputMappings.end())
- Input = OutputMappings.find(Input)->second;
- RemappedArgInputs.insert(Input);
- }
-}
-
-/// Find the input GVNs and the output values for a region of Instructions.
-/// Using the code extractor, we collect the inputs to the extracted function.
-///
-/// The \p Region can be identified as needing to be ignored in this function.
-/// It should be checked whether it should be ignored after a call to this
-/// function.
-///
-/// \param [in,out] Region - The region of code to be analyzed.
-/// \param [out] InputGVNs - The global value numbers for the extracted
-/// arguments.
-/// \param [in] NotSame - The global value numbers in the region that do not
-/// have the same constant value in the regions structurally similar to
-/// \p Region.
-/// \param [in] OutputMappings - The mapping of values that have been replaced
-/// by a new output value after extraction.
-/// \param [out] ArgInputs - The values of the inputs to the extracted function.
-/// \param [out] Outputs - The set of values extracted by the CodeExtractor
-/// as outputs.
-static void getCodeExtractorArguments(
- OutlinableRegion &Region, std::vector<unsigned> &InputGVNs,
- DenseSet<unsigned> &NotSame, DenseMap<Value *, Value *> &OutputMappings,
- SetVector<Value *> &ArgInputs, SetVector<Value *> &Outputs) {
- IRSimilarityCandidate &C = *Region.Candidate;
-
- // OverallInputs are the inputs to the region found by the CodeExtractor,
- // SinkCands and HoistCands are used by the CodeExtractor to find sunken
- // allocas of values whose lifetimes are contained completely within the
- // outlined region. PremappedInputs are the arguments found by the
- // CodeExtractor, removing conditions such as sunken allocas, but that
- // may need to be remapped due to the extracted output values replacing
- // the original values. We use DummyOutputs for this first run of finding
- // inputs and outputs since the outputs could change during findAllocas,
- // the correct set of extracted outputs will be in the final Outputs ValueSet.
- SetVector<Value *> OverallInputs, PremappedInputs, SinkCands, HoistCands,
- DummyOutputs;
-
- // Use the code extractor to get the inputs and outputs, without sunken
- // allocas or removing llvm.assumes.
- CodeExtractor *CE = Region.CE;
- CE->findInputsOutputs(OverallInputs, DummyOutputs, SinkCands);
- assert(Region.StartBB && "Region must have a start BasicBlock!");
- Function *OrigF = Region.StartBB->getParent();
- CodeExtractorAnalysisCache CEAC(*OrigF);
- BasicBlock *Dummy = nullptr;
-
- // The region may be ineligible due to VarArgs in the parent function. In this
- // case we ignore the region.
- if (!CE->isEligible()) {
- Region.IgnoreRegion = true;
- return;
- }
-
- // Find if any values are going to be sunk into the function when extracted
- CE->findAllocas(CEAC, SinkCands, HoistCands, Dummy);
- CE->findInputsOutputs(PremappedInputs, Outputs, SinkCands);
-
- // TODO: Support regions with sunken allocas: values whose lifetimes are
- // contained completely within the outlined region. These are not guaranteed
- // to be the same in every region, so we must elevate them all to arguments
- // when they appear. If these values are not equal, it means there is some
- // Input in OverallInputs that was removed for ArgInputs.
- if (OverallInputs.size() != PremappedInputs.size()) {
- Region.IgnoreRegion = true;
- return;
- }
-
- findConstants(C, NotSame, InputGVNs);
-
- mapInputsToGVNs(C, OverallInputs, OutputMappings, InputGVNs);
-
- remapExtractedInputs(PremappedInputs.getArrayRef(), OutputMappings,
- ArgInputs);
-
- // Sort the GVNs, since we now have constants included in the \ref InputGVNs
- // we need to make sure they are in a deterministic order.
- stable_sort(InputGVNs);
-}
-
-/// Look over the inputs and map each input argument to an argument in the
-/// overall function for the OutlinableRegions. This creates a way to replace
-/// the arguments of the extracted function with the arguments of the new
-/// overall function.
-///
-/// \param [in,out] Region - The region of code to be analyzed.
-/// \param [in] InputsGVNs - The global value numbering of the input values
-/// collected.
-/// \param [in] ArgInputs - The values of the arguments to the extracted
-/// function.
-static void
-findExtractedInputToOverallInputMapping(OutlinableRegion &Region,
- std::vector<unsigned> &InputGVNs,
- SetVector<Value *> &ArgInputs) {
-
- IRSimilarityCandidate &C = *Region.Candidate;
- OutlinableGroup &Group = *Region.Parent;
-
- // This counts the argument number in the overall function.
- unsigned TypeIndex = 0;
-
- // This counts the argument number in the extracted function.
- unsigned OriginalIndex = 0;
-
- // Find the mapping of the extracted arguments to the arguments for the
- // overall function. Since there may be extra arguments in the overall
- // function to account for the extracted constants, we have two different
- // counters as we find extracted arguments, and as we come across overall
- // arguments.
- for (unsigned InputVal : InputGVNs) {
- Optional<Value *> InputOpt = C.fromGVN(InputVal);
- assert(InputOpt.hasValue() && "Global value number not found?");
- Value *Input = InputOpt.getValue();
-
- if (!Group.InputTypesSet) {
- Group.ArgumentTypes.push_back(Input->getType());
- // If the input value has a swifterr attribute, make sure to mark the
- // argument in the overall function.
- if (Input->isSwiftError()) {
- assert(
- !Group.SwiftErrorArgument.hasValue() &&
- "Argument already marked with swifterr for this OutlinableGroup!");
- Group.SwiftErrorArgument = TypeIndex;
- }
- }
-
- // Check if we have a constant. If we do add it to the overall argument
- // number to Constant map for the region, and continue to the next input.
- if (Constant *CST = dyn_cast<Constant>(Input)) {
- Region.AggArgToConstant.insert(std::make_pair(TypeIndex, CST));
- TypeIndex++;
- continue;
- }
-
- // It is not a constant, we create the mapping from extracted argument list
- // to the overall argument list.
- assert(ArgInputs.count(Input) && "Input cannot be found!");
-
- Region.ExtractedArgToAgg.insert(std::make_pair(OriginalIndex, TypeIndex));
- Region.AggArgToExtracted.insert(std::make_pair(TypeIndex, OriginalIndex));
- OriginalIndex++;
- TypeIndex++;
- }
-
- // If the function type definitions for the OutlinableGroup holding the region
- // have not been set, set the length of the inputs here. We should have the
- // same inputs for all of the different regions contained in the
- // OutlinableGroup since they are all structurally similar to one another.
- if (!Group.InputTypesSet) {
- Group.NumAggregateInputs = TypeIndex;
- Group.InputTypesSet = true;
- }
-
- Region.NumExtractedInputs = OriginalIndex;
-}
-
-/// Create a mapping of the output arguments for the \p Region to the output
-/// arguments of the overall outlined function.
-///
-/// \param [in,out] Region - The region of code to be analyzed.
-/// \param [in] Outputs - The values found by the code extractor.
-static void
-findExtractedOutputToOverallOutputMapping(OutlinableRegion &Region,
- ArrayRef<Value *> Outputs) {
- OutlinableGroup &Group = *Region.Parent;
- IRSimilarityCandidate &C = *Region.Candidate;
-
- // This counts the argument number in the extracted function.
- unsigned OriginalIndex = Region.NumExtractedInputs;
-
- // This counts the argument number in the overall function.
- unsigned TypeIndex = Group.NumAggregateInputs;
- bool TypeFound;
- DenseSet<unsigned> AggArgsUsed;
-
- // Iterate over the output types and identify if there is an aggregate pointer
- // type whose base type matches the current output type. If there is, we mark
- // that we will use this output register for this value. If not we add another
- // type to the overall argument type list. We also store the GVNs used for
- // stores to identify which values will need to be moved into an special
- // block that holds the stores to the output registers.
- for (Value *Output : Outputs) {
- TypeFound = false;
- // We can do this since it is a result value, and will have a number
- // that is necessarily the same. BUT if in the future, the instructions
- // do not have to be in same order, but are functionally the same, we will
- // have to use a different scheme, as one-to-one correspondence is not
- // guaranteed.
- unsigned GlobalValue = C.getGVN(Output).getValue();
- unsigned ArgumentSize = Group.ArgumentTypes.size();
-
- for (unsigned Jdx = TypeIndex; Jdx < ArgumentSize; Jdx++) {
- if (Group.ArgumentTypes[Jdx] != PointerType::getUnqual(Output->getType()))
- continue;
-
- if (AggArgsUsed.contains(Jdx))
- continue;
-
- TypeFound = true;
- AggArgsUsed.insert(Jdx);
- Region.ExtractedArgToAgg.insert(std::make_pair(OriginalIndex, Jdx));
- Region.AggArgToExtracted.insert(std::make_pair(Jdx, OriginalIndex));
- Region.GVNStores.push_back(GlobalValue);
- break;
- }
-
- // We were unable to find an unused type in the output type set that matches
- // the output, so we add a pointer type to the argument types of the overall
- // function to handle this output and create a mapping to it.
- if (!TypeFound) {
- Group.ArgumentTypes.push_back(PointerType::getUnqual(Output->getType()));
- AggArgsUsed.insert(Group.ArgumentTypes.size() - 1);
- Region.ExtractedArgToAgg.insert(
- std::make_pair(OriginalIndex, Group.ArgumentTypes.size() - 1));
- Region.AggArgToExtracted.insert(
- std::make_pair(Group.ArgumentTypes.size() - 1, OriginalIndex));
- Region.GVNStores.push_back(GlobalValue);
- }
-
- stable_sort(Region.GVNStores);
- OriginalIndex++;
- TypeIndex++;
- }
-}
-
-void IROutliner::findAddInputsOutputs(Module &M, OutlinableRegion &Region,
- DenseSet<unsigned> &NotSame) {
- std::vector<unsigned> Inputs;
- SetVector<Value *> ArgInputs, Outputs;
-
- getCodeExtractorArguments(Region, Inputs, NotSame, OutputMappings, ArgInputs,
- Outputs);
-
- if (Region.IgnoreRegion)
- return;
-
- // Map the inputs found by the CodeExtractor to the arguments found for
- // the overall function.
- findExtractedInputToOverallInputMapping(Region, Inputs, ArgInputs);
-
- // Map the outputs found by the CodeExtractor to the arguments found for
- // the overall function.
- findExtractedOutputToOverallOutputMapping(Region, Outputs.getArrayRef());
-}
-
-/// Replace the extracted function in the Region with a call to the overall
-/// function constructed from the deduplicated similar regions, replacing and
-/// remapping the values passed to the extracted function as arguments to the
-/// new arguments of the overall function.
-///
-/// \param [in] M - The module to outline from.
-/// \param [in] Region - The regions of extracted code to be replaced with a new
-/// function.
-/// \returns a call instruction with the replaced function.
-CallInst *replaceCalledFunction(Module &M, OutlinableRegion &Region) {
- std::vector<Value *> NewCallArgs;
- DenseMap<unsigned, unsigned>::iterator ArgPair;
-
- OutlinableGroup &Group = *Region.Parent;
- CallInst *Call = Region.Call;
- assert(Call && "Call to replace is nullptr?");
- Function *AggFunc = Group.OutlinedFunction;
- assert(AggFunc && "Function to replace with is nullptr?");
-
- // If the arguments are the same size, there are not values that need to be
- // made argument, or different output registers to handle. We can simply
- // replace the called function in this case.
- if (AggFunc->arg_size() == Call->arg_size()) {
- LLVM_DEBUG(dbgs() << "Replace call to " << *Call << " with call to "
- << *AggFunc << " with same number of arguments\n");
- Call->setCalledFunction(AggFunc);
- return Call;
- }
-
- // We have a different number of arguments than the new function, so
- // we need to use our previously mappings off extracted argument to overall
- // function argument, and constants to overall function argument to create the
- // new argument list.
- for (unsigned AggArgIdx = 0; AggArgIdx < AggFunc->arg_size(); AggArgIdx++) {
-
- if (AggArgIdx == AggFunc->arg_size() - 1 &&
- Group.OutputGVNCombinations.size() > 1) {
- // If we are on the last argument, and we need to differentiate between
- // output blocks, add an integer to the argument list to determine
- // what block to take
- LLVM_DEBUG(dbgs() << "Set switch block argument to "
- << Region.OutputBlockNum << "\n");
- NewCallArgs.push_back(ConstantInt::get(Type::getInt32Ty(M.getContext()),
- Region.OutputBlockNum));
- continue;
- }
-
- ArgPair = Region.AggArgToExtracted.find(AggArgIdx);
- if (ArgPair != Region.AggArgToExtracted.end()) {
- Value *ArgumentValue = Call->getArgOperand(ArgPair->second);
- // If we found the mapping from the extracted function to the overall
- // function, we simply add it to the argument list. We use the same
- // value, it just needs to honor the new order of arguments.
- LLVM_DEBUG(dbgs() << "Setting argument " << AggArgIdx << " to value "
- << *ArgumentValue << "\n");
- NewCallArgs.push_back(ArgumentValue);
- continue;
- }
-
- // If it is a constant, we simply add it to the argument list as a value.
- if (Region.AggArgToConstant.find(AggArgIdx) !=
- Region.AggArgToConstant.end()) {
- Constant *CST = Region.AggArgToConstant.find(AggArgIdx)->second;
- LLVM_DEBUG(dbgs() << "Setting argument " << AggArgIdx << " to value "
- << *CST << "\n");
- NewCallArgs.push_back(CST);
- continue;
- }
-
- // Add a nullptr value if the argument is not found in the extracted
- // function. If we cannot find a value, it means it is not in use
- // for the region, so we should not pass anything to it.
- LLVM_DEBUG(dbgs() << "Setting argument " << AggArgIdx << " to nullptr\n");
- NewCallArgs.push_back(ConstantPointerNull::get(
- static_cast<PointerType *>(AggFunc->getArg(AggArgIdx)->getType())));
- }
-
- LLVM_DEBUG(dbgs() << "Replace call to " << *Call << " with call to "
- << *AggFunc << " with new set of arguments\n");
- // Create the new call instruction and erase the old one.
- Call = CallInst::Create(AggFunc->getFunctionType(), AggFunc, NewCallArgs, "",
- Call);
-
- // It is possible that the call to the outlined function is either the first
- // instruction is in the new block, the last instruction, or both. If either
- // of these is the case, we need to make sure that we replace the instruction
- // in the IRInstructionData struct with the new call.
- CallInst *OldCall = Region.Call;
- if (Region.NewFront->Inst == OldCall)
- Region.NewFront->Inst = Call;
- if (Region.NewBack->Inst == OldCall)
- Region.NewBack->Inst = Call;
-
- // Transfer any debug information.
- Call->setDebugLoc(Region.Call->getDebugLoc());
-
- // Remove the old instruction.
- OldCall->eraseFromParent();
- Region.Call = Call;
-
- // Make sure that the argument in the new function has the SwiftError
- // argument.
- if (Group.SwiftErrorArgument.hasValue())
- Call->addParamAttr(Group.SwiftErrorArgument.getValue(),
- Attribute::SwiftError);
-
- return Call;
-}
-
-// Within an extracted function, replace the argument uses of the extracted
-// region with the arguments of the function for an OutlinableGroup.
-//
-/// \param [in] Region - The region of extracted code to be changed.
-/// \param [in,out] OutputBB - The BasicBlock for the output stores for this
-/// region.
-static void replaceArgumentUses(OutlinableRegion &Region,
- BasicBlock *OutputBB) {
- OutlinableGroup &Group = *Region.Parent;
- assert(Region.ExtractedFunction && "Region has no extracted function?");
-
- for (unsigned ArgIdx = 0; ArgIdx < Region.ExtractedFunction->arg_size();
- ArgIdx++) {
- assert(Region.ExtractedArgToAgg.find(ArgIdx) !=
- Region.ExtractedArgToAgg.end() &&
- "No mapping from extracted to outlined?");
- unsigned AggArgIdx = Region.ExtractedArgToAgg.find(ArgIdx)->second;
- Argument *AggArg = Group.OutlinedFunction->getArg(AggArgIdx);
- Argument *Arg = Region.ExtractedFunction->getArg(ArgIdx);
- // The argument is an input, so we can simply replace it with the overall
- // argument value
- if (ArgIdx < Region.NumExtractedInputs) {
- LLVM_DEBUG(dbgs() << "Replacing uses of input " << *Arg << " in function "
- << *Region.ExtractedFunction << " with " << *AggArg
- << " in function " << *Group.OutlinedFunction << "\n");
- Arg->replaceAllUsesWith(AggArg);
- continue;
- }
-
- // If we are replacing an output, we place the store value in its own
- // block inside the overall function before replacing the use of the output
- // in the function.
- assert(Arg->hasOneUse() && "Output argument can only have one use");
- User *InstAsUser = Arg->user_back();
- assert(InstAsUser && "User is nullptr!");
-
- Instruction *I = cast<Instruction>(InstAsUser);
- I->setDebugLoc(DebugLoc());
- LLVM_DEBUG(dbgs() << "Move store for instruction " << *I << " to "
- << *OutputBB << "\n");
-
- I->moveBefore(*OutputBB, OutputBB->end());
-
- LLVM_DEBUG(dbgs() << "Replacing uses of output " << *Arg << " in function "
- << *Region.ExtractedFunction << " with " << *AggArg
- << " in function " << *Group.OutlinedFunction << "\n");
- Arg->replaceAllUsesWith(AggArg);
- }
-}
-
-/// Within an extracted function, replace the constants that need to be lifted
-/// into arguments with the actual argument.
-///
-/// \param Region [in] - The region of extracted code to be changed.
-void replaceConstants(OutlinableRegion &Region) {
- OutlinableGroup &Group = *Region.Parent;
- // Iterate over the constants that need to be elevated into arguments
- for (std::pair<unsigned, Constant *> &Const : Region.AggArgToConstant) {
- unsigned AggArgIdx = Const.first;
- Function *OutlinedFunction = Group.OutlinedFunction;
- assert(OutlinedFunction && "Overall Function is not defined?");
- Constant *CST = Const.second;
- Argument *Arg = Group.OutlinedFunction->getArg(AggArgIdx);
- // Identify the argument it will be elevated to, and replace instances of
- // that constant in the function.
-
- // TODO: If in the future constants do not have one global value number,
- // i.e. a constant 1 could be mapped to several values, this check will
- // have to be more strict. It cannot be using only replaceUsesWithIf.
-
- LLVM_DEBUG(dbgs() << "Replacing uses of constant " << *CST
- << " in function " << *OutlinedFunction << " with "
- << *Arg << "\n");
- CST->replaceUsesWithIf(Arg, [OutlinedFunction](Use &U) {
- if (Instruction *I = dyn_cast<Instruction>(U.getUser()))
- return I->getFunction() == OutlinedFunction;
- return false;
- });
- }
-}
-
-/// For the given function, find all the nondebug or lifetime instructions,
-/// and return them as a vector. Exclude any blocks in \p ExludeBlocks.
-///
-/// \param [in] F - The function we collect the instructions from.
-/// \param [in] ExcludeBlocks - BasicBlocks to ignore.
-/// \returns the list of instructions extracted.
-static std::vector<Instruction *>
-collectRelevantInstructions(Function &F,
- DenseSet<BasicBlock *> &ExcludeBlocks) {
- std::vector<Instruction *> RelevantInstructions;
-
- for (BasicBlock &BB : F) {
- if (ExcludeBlocks.contains(&BB))
- continue;
-
- for (Instruction &Inst : BB) {
- if (Inst.isLifetimeStartOrEnd())
- continue;
- if (isa<DbgInfoIntrinsic>(Inst))
- continue;
-
- RelevantInstructions.push_back(&Inst);
- }
- }
-
- return RelevantInstructions;
-}
-
-/// It is possible that there is a basic block that already performs the same
-/// stores. This returns a duplicate block, if it exists
-///
-/// \param OutputBB [in] the block we are looking for a duplicate of.
-/// \param OutputStoreBBs [in] The existing output blocks.
-/// \returns an optional value with the number output block if there is a match.
-Optional<unsigned>
-findDuplicateOutputBlock(BasicBlock *OutputBB,
- ArrayRef<BasicBlock *> OutputStoreBBs) {
-
- bool WrongInst = false;
- bool WrongSize = false;
- unsigned MatchingNum = 0;
- for (BasicBlock *CompBB : OutputStoreBBs) {
- WrongInst = false;
- if (CompBB->size() - 1 != OutputBB->size()) {
- WrongSize = true;
- MatchingNum++;
- continue;
- }
-
- WrongSize = false;
- BasicBlock::iterator NIt = OutputBB->begin();
- for (Instruction &I : *CompBB) {
- if (isa<BranchInst>(&I))
- continue;
-
- if (!I.isIdenticalTo(&(*NIt))) {
- WrongInst = true;
- break;
- }
-
- NIt++;
- }
- if (!WrongInst && !WrongSize)
- return MatchingNum;
-
- MatchingNum++;
- }
-
- return None;
-}
-
-/// For the outlined section, move needed the StoreInsts for the output
-/// registers into their own block. Then, determine if there is a duplicate
-/// output block already created.
-///
-/// \param [in] OG - The OutlinableGroup of regions to be outlined.
-/// \param [in] Region - The OutlinableRegion that is being analyzed.
-/// \param [in,out] OutputBB - the block that stores for this region will be
-/// placed in.
-/// \param [in] EndBB - the final block of the extracted function.
-/// \param [in] OutputMappings - OutputMappings the mapping of values that have
-/// been replaced by a new output value.
-/// \param [in,out] OutputStoreBBs - The existing output blocks.
-static void
-alignOutputBlockWithAggFunc(OutlinableGroup &OG, OutlinableRegion &Region,
- BasicBlock *OutputBB, BasicBlock *EndBB,
- const DenseMap<Value *, Value *> &OutputMappings,
- std::vector<BasicBlock *> &OutputStoreBBs) {
- DenseSet<unsigned> ValuesToFind(Region.GVNStores.begin(),
- Region.GVNStores.end());
-
- // We iterate over the instructions in the extracted function, and find the
- // global value number of the instructions. If we find a value that should
- // be contained in a store, we replace the uses of the value with the value
- // from the overall function, so that the store is storing the correct
- // value from the overall function.
- DenseSet<BasicBlock *> ExcludeBBs(OutputStoreBBs.begin(),
- OutputStoreBBs.end());
- ExcludeBBs.insert(OutputBB);
- std::vector<Instruction *> ExtractedFunctionInsts =
- collectRelevantInstructions(*(Region.ExtractedFunction), ExcludeBBs);
- std::vector<Instruction *> OverallFunctionInsts =
- collectRelevantInstructions(*OG.OutlinedFunction, ExcludeBBs);
-
- assert(ExtractedFunctionInsts.size() == OverallFunctionInsts.size() &&
- "Number of relevant instructions not equal!");
-
- unsigned NumInstructions = ExtractedFunctionInsts.size();
- for (unsigned Idx = 0; Idx < NumInstructions; Idx++) {
- Value *V = ExtractedFunctionInsts[Idx];
-
- if (OutputMappings.find(V) != OutputMappings.end())
- V = OutputMappings.find(V)->second;
- Optional<unsigned> GVN = Region.Candidate->getGVN(V);
-
- // If we have found one of the stored values for output, replace the value
- // with the corresponding one from the overall function.
- if (GVN.hasValue() && ValuesToFind.erase(GVN.getValue())) {
- V->replaceAllUsesWith(OverallFunctionInsts[Idx]);
- if (ValuesToFind.size() == 0)
- break;
- }
-
- if (ValuesToFind.size() == 0)
- break;
- }
-
- assert(ValuesToFind.size() == 0 && "Not all store values were handled!");
-
- // If the size of the block is 0, then there are no stores, and we do not
- // need to save this block.
- if (OutputBB->size() == 0) {
- Region.OutputBlockNum = -1;
- OutputBB->eraseFromParent();
- return;
- }
-
- // Determine is there is a duplicate block.
- Optional<unsigned> MatchingBB =
- findDuplicateOutputBlock(OutputBB, OutputStoreBBs);
-
- // If there is, we remove the new output block. If it does not,
- // we add it to our list of output blocks.
- if (MatchingBB.hasValue()) {
- LLVM_DEBUG(dbgs() << "Set output block for region in function"
- << Region.ExtractedFunction << " to "
- << MatchingBB.getValue());
-
- Region.OutputBlockNum = MatchingBB.getValue();
- OutputBB->eraseFromParent();
- return;
- }
-
- Region.OutputBlockNum = OutputStoreBBs.size();
-
- LLVM_DEBUG(dbgs() << "Create output block for region in"
- << Region.ExtractedFunction << " to "
- << *OutputBB);
- OutputStoreBBs.push_back(OutputBB);
- BranchInst::Create(EndBB, OutputBB);
-}
-
-/// Create the switch statement for outlined function to differentiate between
-/// all the output blocks.
-///
-/// For the outlined section, determine if an outlined block already exists that
-/// matches the needed stores for the extracted section.
-/// \param [in] M - The module we are outlining from.
-/// \param [in] OG - The group of regions to be outlined.
-/// \param [in] OS - The region that is being analyzed.
-/// \param [in] EndBB - The final block of the extracted function.
-/// \param [in,out] OutputStoreBBs - The existing output blocks.
-void createSwitchStatement(Module &M, OutlinableGroup &OG, BasicBlock *EndBB,
- ArrayRef<BasicBlock *> OutputStoreBBs) {
- // We only need the switch statement if there is more than one store
- // combination.
- if (OG.OutputGVNCombinations.size() > 1) {
- Function *AggFunc = OG.OutlinedFunction;
- // Create a final block
- BasicBlock *ReturnBlock =
- BasicBlock::Create(M.getContext(), "final_block", AggFunc);
- Instruction *Term = EndBB->getTerminator();
- Term->moveBefore(*ReturnBlock, ReturnBlock->end());
- // Put the switch statement in the old end basic block for the function with
- // a fall through to the new return block
- LLVM_DEBUG(dbgs() << "Create switch statement in " << *AggFunc << " for "
- << OutputStoreBBs.size() << "\n");
- SwitchInst *SwitchI =
- SwitchInst::Create(AggFunc->getArg(AggFunc->arg_size() - 1),
- ReturnBlock, OutputStoreBBs.size(), EndBB);
-
- unsigned Idx = 0;
- for (BasicBlock *BB : OutputStoreBBs) {
- SwitchI->addCase(ConstantInt::get(Type::getInt32Ty(M.getContext()), Idx),
- BB);
- Term = BB->getTerminator();
- Term->setSuccessor(0, ReturnBlock);
- Idx++;
- }
- return;
- }
-
- // If there needs to be stores, move them from the output block to the end
- // block to save on branching instructions.
- if (OutputStoreBBs.size() == 1) {
- LLVM_DEBUG(dbgs() << "Move store instructions to the end block in "
- << *OG.OutlinedFunction << "\n");
- BasicBlock *OutputBlock = OutputStoreBBs[0];
- Instruction *Term = OutputBlock->getTerminator();
- Term->eraseFromParent();
- Term = EndBB->getTerminator();
- moveBBContents(*OutputBlock, *EndBB);
- Term->moveBefore(*EndBB, EndBB->end());
- OutputBlock->eraseFromParent();
- }
-}
-
-/// Fill the new function that will serve as the replacement function for all of
-/// the extracted regions of a certain structure from the first region in the
-/// list of regions. Replace this first region's extracted function with the
-/// new overall function.
-///
-/// \param [in] M - The module we are outlining from.
-/// \param [in] CurrentGroup - The group of regions to be outlined.
-/// \param [in,out] OutputStoreBBs - The output blocks for each different
-/// set of stores needed for the different functions.
-/// \param [in,out] FuncsToRemove - Extracted functions to erase from module
-/// once outlining is complete.
-static void fillOverallFunction(Module &M, OutlinableGroup &CurrentGroup,
- std::vector<BasicBlock *> &OutputStoreBBs,
- std::vector<Function *> &FuncsToRemove) {
- OutlinableRegion *CurrentOS = CurrentGroup.Regions[0];
-
- // Move first extracted function's instructions into new function.
- LLVM_DEBUG(dbgs() << "Move instructions from "
- << *CurrentOS->ExtractedFunction << " to instruction "
- << *CurrentGroup.OutlinedFunction << "\n");
-
- CurrentGroup.EndBB = moveFunctionData(*CurrentOS->ExtractedFunction,
- *CurrentGroup.OutlinedFunction);
-
- // Transfer the attributes from the function to the new function.
- for (Attribute A :
- CurrentOS->ExtractedFunction->getAttributes().getFnAttributes())
- CurrentGroup.OutlinedFunction->addFnAttr(A);
-
- // Create an output block for the first extracted function.
- BasicBlock *NewBB = BasicBlock::Create(
- M.getContext(), Twine("output_block_") + Twine(static_cast<unsigned>(0)),
- CurrentGroup.OutlinedFunction);
- CurrentOS->OutputBlockNum = 0;
-
- replaceArgumentUses(*CurrentOS, NewBB);
- replaceConstants(*CurrentOS);
-
- // If the new basic block has no new stores, we can erase it from the module.
- // It it does, we create a branch instruction to the last basic block from the
- // new one.
- if (NewBB->size() == 0) {
- CurrentOS->OutputBlockNum = -1;
- NewBB->eraseFromParent();
- } else {
- BranchInst::Create(CurrentGroup.EndBB, NewBB);
- OutputStoreBBs.push_back(NewBB);
- }
-
- // Replace the call to the extracted function with the outlined function.
- CurrentOS->Call = replaceCalledFunction(M, *CurrentOS);
-
- // We only delete the extracted functions at the end since we may need to
- // reference instructions contained in them for mapping purposes.
- FuncsToRemove.push_back(CurrentOS->ExtractedFunction);
-}
-
-void IROutliner::deduplicateExtractedSections(
- Module &M, OutlinableGroup &CurrentGroup,
- std::vector<Function *> &FuncsToRemove, unsigned &OutlinedFunctionNum) {
- createFunction(M, CurrentGroup, OutlinedFunctionNum);
-
- std::vector<BasicBlock *> OutputStoreBBs;
-
- OutlinableRegion *CurrentOS;
-
- fillOverallFunction(M, CurrentGroup, OutputStoreBBs, FuncsToRemove);
-
- for (unsigned Idx = 1; Idx < CurrentGroup.Regions.size(); Idx++) {
- CurrentOS = CurrentGroup.Regions[Idx];
- AttributeFuncs::mergeAttributesForOutlining(*CurrentGroup.OutlinedFunction,
- *CurrentOS->ExtractedFunction);
-
- // Create a new BasicBlock to hold the needed store instructions.
- BasicBlock *NewBB = BasicBlock::Create(
- M.getContext(), "output_block_" + std::to_string(Idx),
- CurrentGroup.OutlinedFunction);
- replaceArgumentUses(*CurrentOS, NewBB);
-
- alignOutputBlockWithAggFunc(CurrentGroup, *CurrentOS, NewBB,
- CurrentGroup.EndBB, OutputMappings,
- OutputStoreBBs);
-
- CurrentOS->Call = replaceCalledFunction(M, *CurrentOS);
- FuncsToRemove.push_back(CurrentOS->ExtractedFunction);
- }
-
- // Create a switch statement to handle the different output schemes.
- createSwitchStatement(M, CurrentGroup, CurrentGroup.EndBB, OutputStoreBBs);
-
- OutlinedFunctionNum++;
-}
-
-void IROutliner::pruneIncompatibleRegions(
- std::vector<IRSimilarityCandidate> &CandidateVec,
- OutlinableGroup &CurrentGroup) {
- bool PreviouslyOutlined;
-
- // Sort from beginning to end, so the IRSimilarityCandidates are in order.
- stable_sort(CandidateVec, [](const IRSimilarityCandidate &LHS,
- const IRSimilarityCandidate &RHS) {
- return LHS.getStartIdx() < RHS.getStartIdx();
- });
-
- unsigned CurrentEndIdx = 0;
- for (IRSimilarityCandidate &IRSC : CandidateVec) {
- PreviouslyOutlined = false;
- unsigned StartIdx = IRSC.getStartIdx();
- unsigned EndIdx = IRSC.getEndIdx();
-
- for (unsigned Idx = StartIdx; Idx <= EndIdx; Idx++)
- if (Outlined.contains(Idx)) {
- PreviouslyOutlined = true;
- break;
- }
-
- if (PreviouslyOutlined)
- continue;
-
- // TODO: If in the future we can outline across BasicBlocks, we will need to
- // check all BasicBlocks contained in the region.
- if (IRSC.getStartBB()->hasAddressTaken())
- continue;
-
- if (IRSC.front()->Inst->getFunction()->hasLinkOnceODRLinkage() &&
- !OutlineFromLinkODRs)
- continue;
-
- // Greedily prune out any regions that will overlap with already chosen
- // regions.
- if (CurrentEndIdx != 0 && StartIdx <= CurrentEndIdx)
- continue;
-
- bool BadInst = any_of(IRSC, [this](IRInstructionData &ID) {
- // We check if there is a discrepancy between the InstructionDataList
- // and the actual next instruction in the module. If there is, it means
- // that an extra instruction was added, likely by the CodeExtractor.
-
- // Since we do not have any similarity data about this particular
- // instruction, we cannot confidently outline it, and must discard this
- // candidate.
- if (std::next(ID.getIterator())->Inst !=
- ID.Inst->getNextNonDebugInstruction())
- return true;
- return !this->InstructionClassifier.visit(ID.Inst);
- });
-
- if (BadInst)
- continue;
-
- OutlinableRegion *OS = new (RegionAllocator.Allocate())
- OutlinableRegion(IRSC, CurrentGroup);
- CurrentGroup.Regions.push_back(OS);
-
- CurrentEndIdx = EndIdx;
- }
-}
-
-InstructionCost
-IROutliner::findBenefitFromAllRegions(OutlinableGroup &CurrentGroup) {
- InstructionCost RegionBenefit = 0;
- for (OutlinableRegion *Region : CurrentGroup.Regions) {
- TargetTransformInfo &TTI = getTTI(*Region->StartBB->getParent());
- // We add the number of instructions in the region to the benefit as an
- // estimate as to how much will be removed.
- RegionBenefit += Region->getBenefit(TTI);
- LLVM_DEBUG(dbgs() << "Adding: " << RegionBenefit
- << " saved instructions to overfall benefit.\n");
- }
-
- return RegionBenefit;
-}
-
-InstructionCost
-IROutliner::findCostOutputReloads(OutlinableGroup &CurrentGroup) {
- InstructionCost OverallCost = 0;
- for (OutlinableRegion *Region : CurrentGroup.Regions) {
- TargetTransformInfo &TTI = getTTI(*Region->StartBB->getParent());
-
- // Each output incurs a load after the call, so we add that to the cost.
- for (unsigned OutputGVN : Region->GVNStores) {
- Optional<Value *> OV = Region->Candidate->fromGVN(OutputGVN);
- assert(OV.hasValue() && "Could not find value for GVN?");
- Value *V = OV.getValue();
- InstructionCost LoadCost =
- TTI.getMemoryOpCost(Instruction::Load, V->getType(), Align(1), 0,
- TargetTransformInfo::TCK_CodeSize);
-
- LLVM_DEBUG(dbgs() << "Adding: " << LoadCost
- << " instructions to cost for output of type "
- << *V->getType() << "\n");
- OverallCost += LoadCost;
- }
- }
-
- return OverallCost;
-}
-
-/// Find the extra instructions needed to handle any output values for the
-/// region.
-///
-/// \param [in] M - The Module to outline from.
-/// \param [in] CurrentGroup - The collection of OutlinableRegions to analyze.
-/// \param [in] TTI - The TargetTransformInfo used to collect information for
-/// new instruction costs.
-/// \returns the additional cost to handle the outputs.
-static InstructionCost findCostForOutputBlocks(Module &M,
- OutlinableGroup &CurrentGroup,
- TargetTransformInfo &TTI) {
- InstructionCost OutputCost = 0;
-
- for (const ArrayRef<unsigned> &OutputUse :
- CurrentGroup.OutputGVNCombinations) {
- IRSimilarityCandidate &Candidate = *CurrentGroup.Regions[0]->Candidate;
- for (unsigned GVN : OutputUse) {
- Optional<Value *> OV = Candidate.fromGVN(GVN);
- assert(OV.hasValue() && "Could not find value for GVN?");
- Value *V = OV.getValue();
- InstructionCost StoreCost =
- TTI.getMemoryOpCost(Instruction::Load, V->getType(), Align(1), 0,
- TargetTransformInfo::TCK_CodeSize);
-
- // An instruction cost is added for each store set that needs to occur for
- // various output combinations inside the function, plus a branch to
- // return to the exit block.
- LLVM_DEBUG(dbgs() << "Adding: " << StoreCost
- << " instructions to cost for output of type "
- << *V->getType() << "\n");
- OutputCost += StoreCost;
- }
-
- InstructionCost BranchCost =
- TTI.getCFInstrCost(Instruction::Br, TargetTransformInfo::TCK_CodeSize);
- LLVM_DEBUG(dbgs() << "Adding " << BranchCost << " to the current cost for"
- << " a branch instruction\n");
- OutputCost += BranchCost;
- }
-
- // If there is more than one output scheme, we must have a comparison and
- // branch for each different item in the switch statement.
- if (CurrentGroup.OutputGVNCombinations.size() > 1) {
- InstructionCost ComparisonCost = TTI.getCmpSelInstrCost(
- Instruction::ICmp, Type::getInt32Ty(M.getContext()),
- Type::getInt32Ty(M.getContext()), CmpInst::BAD_ICMP_PREDICATE,
- TargetTransformInfo::TCK_CodeSize);
- InstructionCost BranchCost =
- TTI.getCFInstrCost(Instruction::Br, TargetTransformInfo::TCK_CodeSize);
-
- unsigned DifferentBlocks = CurrentGroup.OutputGVNCombinations.size();
- InstructionCost TotalCost = ComparisonCost * BranchCost * DifferentBlocks;
-
- LLVM_DEBUG(dbgs() << "Adding: " << TotalCost
- << " instructions for each switch case for each different"
- << " output path in a function\n");
- OutputCost += TotalCost;
- }
-
- return OutputCost;
-}
-
-void IROutliner::findCostBenefit(Module &M, OutlinableGroup &CurrentGroup) {
- InstructionCost RegionBenefit = findBenefitFromAllRegions(CurrentGroup);
- CurrentGroup.Benefit += RegionBenefit;
- LLVM_DEBUG(dbgs() << "Current Benefit: " << CurrentGroup.Benefit << "\n");
-
- InstructionCost OutputReloadCost = findCostOutputReloads(CurrentGroup);
- CurrentGroup.Cost += OutputReloadCost;
- LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
-
- InstructionCost AverageRegionBenefit =
- RegionBenefit / CurrentGroup.Regions.size();
- unsigned OverallArgumentNum = CurrentGroup.ArgumentTypes.size();
- unsigned NumRegions = CurrentGroup.Regions.size();
- TargetTransformInfo &TTI =
- getTTI(*CurrentGroup.Regions[0]->Candidate->getFunction());
-
- // We add one region to the cost once, to account for the instructions added
- // inside of the newly created function.
- LLVM_DEBUG(dbgs() << "Adding: " << AverageRegionBenefit
- << " instructions to cost for body of new function.\n");
- CurrentGroup.Cost += AverageRegionBenefit;
- LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
-
- // For each argument, we must add an instruction for loading the argument
- // out of the register and into a value inside of the newly outlined function.
- LLVM_DEBUG(dbgs() << "Adding: " << OverallArgumentNum
- << " instructions to cost for each argument in the new"
- << " function.\n");
- CurrentGroup.Cost +=
- OverallArgumentNum * TargetTransformInfo::TCC_Basic;
- LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
-
- // Each argument needs to either be loaded into a register or onto the stack.
- // Some arguments will only be loaded into the stack once the argument
- // registers are filled.
- LLVM_DEBUG(dbgs() << "Adding: " << OverallArgumentNum
- << " instructions to cost for each argument in the new"
- << " function " << NumRegions << " times for the "
- << "needed argument handling at the call site.\n");
- CurrentGroup.Cost +=
- 2 * OverallArgumentNum * TargetTransformInfo::TCC_Basic * NumRegions;
- LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
-
- CurrentGroup.Cost += findCostForOutputBlocks(M, CurrentGroup, TTI);
- LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
-}
-
-void IROutliner::updateOutputMapping(OutlinableRegion &Region,
- ArrayRef<Value *> Outputs,
- LoadInst *LI) {
- // For and load instructions following the call
- Value *Operand = LI->getPointerOperand();
- Optional<unsigned> OutputIdx = None;
- // Find if the operand it is an output register.
- for (unsigned ArgIdx = Region.NumExtractedInputs;
- ArgIdx < Region.Call->arg_size(); ArgIdx++) {
- if (Operand == Region.Call->getArgOperand(ArgIdx)) {
- OutputIdx = ArgIdx - Region.NumExtractedInputs;
- break;
- }
- }
-
- // If we found an output register, place a mapping of the new value
- // to the original in the mapping.
- if (!OutputIdx.hasValue())
- return;
-
- if (OutputMappings.find(Outputs[OutputIdx.getValue()]) ==
- OutputMappings.end()) {
- LLVM_DEBUG(dbgs() << "Mapping extracted output " << *LI << " to "
- << *Outputs[OutputIdx.getValue()] << "\n");
- OutputMappings.insert(std::make_pair(LI, Outputs[OutputIdx.getValue()]));
- } else {
- Value *Orig = OutputMappings.find(Outputs[OutputIdx.getValue()])->second;
- LLVM_DEBUG(dbgs() << "Mapping extracted output " << *Orig << " to "
- << *Outputs[OutputIdx.getValue()] << "\n");
- OutputMappings.insert(std::make_pair(LI, Orig));
- }
-}
-
-bool IROutliner::extractSection(OutlinableRegion &Region) {
- SetVector<Value *> ArgInputs, Outputs, SinkCands;
- Region.CE->findInputsOutputs(ArgInputs, Outputs, SinkCands);
-
- assert(Region.StartBB && "StartBB for the OutlinableRegion is nullptr!");
- assert(Region.FollowBB && "FollowBB for the OutlinableRegion is nullptr!");
- Function *OrigF = Region.StartBB->getParent();
- CodeExtractorAnalysisCache CEAC(*OrigF);
- Region.ExtractedFunction = Region.CE->extractCodeRegion(CEAC);
-
- // If the extraction was successful, find the BasicBlock, and reassign the
- // OutlinableRegion blocks
- if (!Region.ExtractedFunction) {
- LLVM_DEBUG(dbgs() << "CodeExtractor failed to outline " << Region.StartBB
- << "\n");
- Region.reattachCandidate();
- return false;
- }
-
- BasicBlock *RewrittenBB = Region.FollowBB->getSinglePredecessor();
- Region.StartBB = RewrittenBB;
- Region.EndBB = RewrittenBB;
-
- // The sequences of outlinable regions has now changed. We must fix the
- // IRInstructionDataList for consistency. Although they may not be illegal
- // instructions, they should not be compared with anything else as they
- // should not be outlined in this round. So marking these as illegal is
- // allowed.
- IRInstructionDataList *IDL = Region.Candidate->front()->IDL;
- Instruction *BeginRewritten = &*RewrittenBB->begin();
- Instruction *EndRewritten = &*RewrittenBB->begin();
- Region.NewFront = new (InstDataAllocator.Allocate()) IRInstructionData(
- *BeginRewritten, InstructionClassifier.visit(*BeginRewritten), *IDL);
- Region.NewBack = new (InstDataAllocator.Allocate()) IRInstructionData(
- *EndRewritten, InstructionClassifier.visit(*EndRewritten), *IDL);
-
- // Insert the first IRInstructionData of the new region in front of the
- // first IRInstructionData of the IRSimilarityCandidate.
- IDL->insert(Region.Candidate->begin(), *Region.NewFront);
- // Insert the first IRInstructionData of the new region after the
- // last IRInstructionData of the IRSimilarityCandidate.
- IDL->insert(Region.Candidate->end(), *Region.NewBack);
- // Remove the IRInstructionData from the IRSimilarityCandidate.
- IDL->erase(Region.Candidate->begin(), std::prev(Region.Candidate->end()));
-
- assert(RewrittenBB != nullptr &&
- "Could not find a predecessor after extraction!");
-
- // Iterate over the new set of instructions to find the new call
- // instruction.
- for (Instruction &I : *RewrittenBB)
- if (CallInst *CI = dyn_cast<CallInst>(&I)) {
- if (Region.ExtractedFunction == CI->getCalledFunction())
- Region.Call = CI;
- } else if (LoadInst *LI = dyn_cast<LoadInst>(&I))
- updateOutputMapping(Region, Outputs.getArrayRef(), LI);
- Region.reattachCandidate();
- return true;
-}
-
-unsigned IROutliner::doOutline(Module &M) {
- // Find the possible similarity sections.
- IRSimilarityIdentifier &Identifier = getIRSI(M);
- SimilarityGroupList &SimilarityCandidates = *Identifier.getSimilarity();
-
- // Sort them by size of extracted sections
- unsigned OutlinedFunctionNum = 0;
- // If we only have one SimilarityGroup in SimilarityCandidates, we do not have
- // to sort them by the potential number of instructions to be outlined
- if (SimilarityCandidates.size() > 1)
- llvm::stable_sort(SimilarityCandidates,
- [](const std::vector<IRSimilarityCandidate> &LHS,
- const std::vector<IRSimilarityCandidate> &RHS) {
- return LHS[0].getLength() * LHS.size() >
- RHS[0].getLength() * RHS.size();
- });
-
- DenseSet<unsigned> NotSame;
- std::vector<Function *> FuncsToRemove;
- // Iterate over the possible sets of similarity.
- for (SimilarityGroup &CandidateVec : SimilarityCandidates) {
- OutlinableGroup CurrentGroup;
-
- // Remove entries that were previously outlined
- pruneIncompatibleRegions(CandidateVec, CurrentGroup);
-
- // We pruned the number of regions to 0 to 1, meaning that it's not worth
- // trying to outlined since there is no compatible similar instance of this
- // code.
- if (CurrentGroup.Regions.size() < 2)
- continue;
-
- // Determine if there are any values that are the same constant throughout
- // each section in the set.
- NotSame.clear();
- CurrentGroup.findSameConstants(NotSame);
-
- if (CurrentGroup.IgnoreGroup)
- continue;
-
- // Create a CodeExtractor for each outlinable region. Identify inputs and
- // outputs for each section using the code extractor and create the argument
- // types for the Aggregate Outlining Function.
- std::vector<OutlinableRegion *> OutlinedRegions;
- for (OutlinableRegion *OS : CurrentGroup.Regions) {
- // Break the outlinable region out of its parent BasicBlock into its own
- // BasicBlocks (see function implementation).
- OS->splitCandidate();
- std::vector<BasicBlock *> BE = {OS->StartBB};
- OS->CE = new (ExtractorAllocator.Allocate())
- CodeExtractor(BE, nullptr, false, nullptr, nullptr, nullptr, false,
- false, "outlined");
- findAddInputsOutputs(M, *OS, NotSame);
- if (!OS->IgnoreRegion)
- OutlinedRegions.push_back(OS);
- else
- OS->reattachCandidate();
- }
-
- CurrentGroup.Regions = std::move(OutlinedRegions);
-
- if (CurrentGroup.Regions.empty())
- continue;
-
- CurrentGroup.collectGVNStoreSets(M);
-
- if (CostModel)
- findCostBenefit(M, CurrentGroup);
-
- // If we are adhering to the cost model, reattach all the candidates
- if (CurrentGroup.Cost >= CurrentGroup.Benefit && CostModel) {
- for (OutlinableRegion *OS : CurrentGroup.Regions)
- OS->reattachCandidate();
- OptimizationRemarkEmitter &ORE = getORE(
- *CurrentGroup.Regions[0]->Candidate->getFunction());
- ORE.emit([&]() {
- IRSimilarityCandidate *C = CurrentGroup.Regions[0]->Candidate;
- OptimizationRemarkMissed R(DEBUG_TYPE, "WouldNotDecreaseSize",
- C->frontInstruction());
- R << "did not outline "
- << ore::NV(std::to_string(CurrentGroup.Regions.size()))
- << " regions due to estimated increase of "
- << ore::NV("InstructionIncrease",
- CurrentGroup.Cost - CurrentGroup.Benefit)
- << " instructions at locations ";
- interleave(
- CurrentGroup.Regions.begin(), CurrentGroup.Regions.end(),
- [&R](OutlinableRegion *Region) {
- R << ore::NV(
- "DebugLoc",
- Region->Candidate->frontInstruction()->getDebugLoc());
- },
- [&R]() { R << " "; });
- return R;
- });
- continue;
- }
-
- LLVM_DEBUG(dbgs() << "Outlining regions with cost " << CurrentGroup.Cost
- << " and benefit " << CurrentGroup.Benefit << "\n");
-
- // Create functions out of all the sections, and mark them as outlined.
- OutlinedRegions.clear();
- for (OutlinableRegion *OS : CurrentGroup.Regions) {
- bool FunctionOutlined = extractSection(*OS);
- if (FunctionOutlined) {
- unsigned StartIdx = OS->Candidate->getStartIdx();
- unsigned EndIdx = OS->Candidate->getEndIdx();
- for (unsigned Idx = StartIdx; Idx <= EndIdx; Idx++)
- Outlined.insert(Idx);
-
- OutlinedRegions.push_back(OS);
- }
- }
-
- LLVM_DEBUG(dbgs() << "Outlined " << OutlinedRegions.size()
- << " with benefit " << CurrentGroup.Benefit
- << " and cost " << CurrentGroup.Cost << "\n");
-
- CurrentGroup.Regions = std::move(OutlinedRegions);
-
- if (CurrentGroup.Regions.empty())
- continue;
-
- OptimizationRemarkEmitter &ORE =
- getORE(*CurrentGroup.Regions[0]->Call->getFunction());
- ORE.emit([&]() {
- IRSimilarityCandidate *C = CurrentGroup.Regions[0]->Candidate;
- OptimizationRemark R(DEBUG_TYPE, "Outlined", C->front()->Inst);
- R << "outlined " << ore::NV(std::to_string(CurrentGroup.Regions.size()))
- << " regions with decrease of "
- << ore::NV("Benefit", CurrentGroup.Benefit - CurrentGroup.Cost)
- << " instructions at locations ";
- interleave(
- CurrentGroup.Regions.begin(), CurrentGroup.Regions.end(),
- [&R](OutlinableRegion *Region) {
- R << ore::NV("DebugLoc",
- Region->Candidate->frontInstruction()->getDebugLoc());
- },
- [&R]() { R << " "; });
- return R;
- });
-
- deduplicateExtractedSections(M, CurrentGroup, FuncsToRemove,
- OutlinedFunctionNum);
- }
-
- for (Function *F : FuncsToRemove)
- F->eraseFromParent();
-
- return OutlinedFunctionNum;
-}
-
-bool IROutliner::run(Module &M) {
- CostModel = !NoCostModel;
- OutlineFromLinkODRs = EnableLinkOnceODRIROutlining;
-
- return doOutline(M) > 0;
-}
-
-// Pass Manager Boilerplate
-class IROutlinerLegacyPass : public ModulePass {
-public:
- static char ID;
- IROutlinerLegacyPass() : ModulePass(ID) {
- initializeIROutlinerLegacyPassPass(*PassRegistry::getPassRegistry());
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
- AU.addRequired<TargetTransformInfoWrapperPass>();
- AU.addRequired<IRSimilarityIdentifierWrapperPass>();
- }
-
- bool runOnModule(Module &M) override;
-};
-
-bool IROutlinerLegacyPass::runOnModule(Module &M) {
- if (skipModule(M))
- return false;
-
- std::unique_ptr<OptimizationRemarkEmitter> ORE;
- auto GORE = [&ORE](Function &F) -> OptimizationRemarkEmitter & {
- ORE.reset(new OptimizationRemarkEmitter(&F));
- return *ORE.get();
- };
-
- auto GTTI = [this](Function &F) -> TargetTransformInfo & {
- return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
- };
-
- auto GIRSI = [this](Module &) -> IRSimilarityIdentifier & {
- return this->getAnalysis<IRSimilarityIdentifierWrapperPass>().getIRSI();
- };
-
- return IROutliner(GTTI, GIRSI, GORE).run(M);
-}
-
-PreservedAnalyses IROutlinerPass::run(Module &M, ModuleAnalysisManager &AM) {
- auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
-
- std::function<TargetTransformInfo &(Function &)> GTTI =
- [&FAM](Function &F) -> TargetTransformInfo & {
- return FAM.getResult<TargetIRAnalysis>(F);
- };
-
- std::function<IRSimilarityIdentifier &(Module &)> GIRSI =
- [&AM](Module &M) -> IRSimilarityIdentifier & {
- return AM.getResult<IRSimilarityAnalysis>(M);
- };
-
- std::unique_ptr<OptimizationRemarkEmitter> ORE;
- std::function<OptimizationRemarkEmitter &(Function &)> GORE =
- [&ORE](Function &F) -> OptimizationRemarkEmitter & {
- ORE.reset(new OptimizationRemarkEmitter(&F));
- return *ORE.get();
- };
-
- if (IROutliner(GTTI, GIRSI, GORE).run(M))
- return PreservedAnalyses::none();
- return PreservedAnalyses::all();
-}
-
-char IROutlinerLegacyPass::ID = 0;
-INITIALIZE_PASS_BEGIN(IROutlinerLegacyPass, "iroutliner", "IR Outliner", false,
- false)
-INITIALIZE_PASS_DEPENDENCY(IRSimilarityIdentifierWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
-INITIALIZE_PASS_END(IROutlinerLegacyPass, "iroutliner", "IR Outliner", false,
- false)
-
-ModulePass *llvm::createIROutlinerPass() { return new IROutlinerLegacyPass(); }
+//===- IROutliner.cpp -- Outline Similar Regions ----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+// Implementation for the IROutliner which is used by the IROutliner Pass.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/IPO/IROutliner.h"
+#include "llvm/Analysis/IRSimilarityIdentifier.h"
+#include "llvm/Analysis/OptimizationRemarkEmitter.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/IPO.h"
+#include <map>
+#include <set>
+#include <vector>
+
+#define DEBUG_TYPE "iroutliner"
+
+using namespace llvm;
+using namespace IRSimilarity;
+
+// Set to true if the user wants the ir outliner to run on linkonceodr linkage
+// functions. This is false by default because the linker can dedupe linkonceodr
+// functions. Since the outliner is confined to a single module (modulo LTO),
+// this is off by default. It should, however, be the default behavior in
+// LTO.
+static cl::opt<bool> EnableLinkOnceODRIROutlining(
+ "enable-linkonceodr-ir-outlining", cl::Hidden,
+ cl::desc("Enable the IR outliner on linkonceodr functions"),
+ cl::init(false));
+
+// This is a debug option to test small pieces of code to ensure that outlining
+// works correctly.
+static cl::opt<bool> NoCostModel(
+ "ir-outlining-no-cost", cl::init(false), cl::ReallyHidden,
+ cl::desc("Debug option to outline greedily, without restriction that "
+ "calculated benefit outweighs cost"));
+
+/// The OutlinableGroup holds all the overarching information for outlining
+/// a set of regions that are structurally similar to one another, such as the
+/// types of the overall function, the output blocks, the sets of stores needed
+/// and a list of the different regions. This information is used in the
+/// deduplication of extracted regions with the same structure.
+struct OutlinableGroup {
+ /// The sections that could be outlined
+ std::vector<OutlinableRegion *> Regions;
+
+ /// The argument types for the function created as the overall function to
+ /// replace the extracted function for each region.
+ std::vector<Type *> ArgumentTypes;
+ /// The FunctionType for the overall function.
+ FunctionType *OutlinedFunctionType = nullptr;
+ /// The Function for the collective overall function.
+ Function *OutlinedFunction = nullptr;
+
+ /// Flag for whether we should not consider this group of OutlinableRegions
+ /// for extraction.
+ bool IgnoreGroup = false;
+
+ /// The return block for the overall function.
+ BasicBlock *EndBB = nullptr;
+
+ /// A set containing the different GVN store sets needed. Each array contains
+ /// a sorted list of the different values that need to be stored into output
+ /// registers.
+ DenseSet<ArrayRef<unsigned>> OutputGVNCombinations;
+
+ /// Flag for whether the \ref ArgumentTypes have been defined after the
+ /// extraction of the first region.
+ bool InputTypesSet = false;
+
+ /// The number of input values in \ref ArgumentTypes. Anything after this
+ /// index in ArgumentTypes is an output argument.
+ unsigned NumAggregateInputs = 0;
+
+ /// The number of instructions that will be outlined by extracting \ref
+ /// Regions.
+ InstructionCost Benefit = 0;
+ /// The number of added instructions needed for the outlining of the \ref
+ /// Regions.
+ InstructionCost Cost = 0;
+
+ /// The argument that needs to be marked with the swifterr attribute. If not
+ /// needed, there is no value.
+ Optional<unsigned> SwiftErrorArgument;
+
+ /// For the \ref Regions, we look at every Value. If it is a constant,
+ /// we check whether it is the same in Region.
+ ///
+ /// \param [in,out] NotSame contains the global value numbers where the
+ /// constant is not always the same, and must be passed in as an argument.
+ void findSameConstants(DenseSet<unsigned> &NotSame);
+
+ /// For the regions, look at each set of GVN stores needed and account for
+ /// each combination. Add an argument to the argument types if there is
+ /// more than one combination.
+ ///
+ /// \param [in] M - The module we are outlining from.
+ void collectGVNStoreSets(Module &M);
+};
+
+/// Move the contents of \p SourceBB to before the last instruction of \p
+/// TargetBB.
+/// \param SourceBB - the BasicBlock to pull Instructions from.
+/// \param TargetBB - the BasicBlock to put Instruction into.
+static void moveBBContents(BasicBlock &SourceBB, BasicBlock &TargetBB) {
+ BasicBlock::iterator BBCurr, BBEnd, BBNext;
+ for (BBCurr = SourceBB.begin(), BBEnd = SourceBB.end(); BBCurr != BBEnd;
+ BBCurr = BBNext) {
+ BBNext = std::next(BBCurr);
+ BBCurr->moveBefore(TargetBB, TargetBB.end());
+ }
+}
+
+void OutlinableRegion::splitCandidate() {
+ assert(!CandidateSplit && "Candidate already split!");
+
+ Instruction *StartInst = (*Candidate->begin()).Inst;
+ Instruction *EndInst = (*Candidate->end()).Inst;
+ assert(StartInst && EndInst && "Expected a start and end instruction?");
+ StartBB = StartInst->getParent();
+ PrevBB = StartBB;
+
+ // The basic block gets split like so:
+ // block: block:
+ // inst1 inst1
+ // inst2 inst2
+ // region1 br block_to_outline
+ // region2 block_to_outline:
+ // region3 -> region1
+ // region4 region2
+ // inst3 region3
+ // inst4 region4
+ // br block_after_outline
+ // block_after_outline:
+ // inst3
+ // inst4
+
+ std::string OriginalName = PrevBB->getName().str();
+
+ StartBB = PrevBB->splitBasicBlock(StartInst, OriginalName + "_to_outline");
+
+ // This is the case for the inner block since we do not have to include
+ // multiple blocks.
+ EndBB = StartBB;
+ FollowBB = EndBB->splitBasicBlock(EndInst, OriginalName + "_after_outline");
+
+ CandidateSplit = true;
+}
+
+void OutlinableRegion::reattachCandidate() {
+ assert(CandidateSplit && "Candidate is not split!");
+
+ // The basic block gets reattached like so:
+ // block: block:
+ // inst1 inst1
+ // inst2 inst2
+ // br block_to_outline region1
+ // block_to_outline: -> region2
+ // region1 region3
+ // region2 region4
+ // region3 inst3
+ // region4 inst4
+ // br block_after_outline
+ // block_after_outline:
+ // inst3
+ // inst4
+ assert(StartBB != nullptr && "StartBB for Candidate is not defined!");
+ assert(FollowBB != nullptr && "StartBB for Candidate is not defined!");
+
+ // StartBB should only have one predecessor since we put an unconditional
+ // branch at the end of PrevBB when we split the BasicBlock.
+ PrevBB = StartBB->getSinglePredecessor();
+ assert(PrevBB != nullptr &&
+ "No Predecessor for the region start basic block!");
+
+ assert(PrevBB->getTerminator() && "Terminator removed from PrevBB!");
+ assert(EndBB->getTerminator() && "Terminator removed from EndBB!");
+ PrevBB->getTerminator()->eraseFromParent();
+ EndBB->getTerminator()->eraseFromParent();
+
+ moveBBContents(*StartBB, *PrevBB);
+
+ BasicBlock *PlacementBB = PrevBB;
+ if (StartBB != EndBB)
+ PlacementBB = EndBB;
+ moveBBContents(*FollowBB, *PlacementBB);
+
+ PrevBB->replaceSuccessorsPhiUsesWith(StartBB, PrevBB);
+ PrevBB->replaceSuccessorsPhiUsesWith(FollowBB, PlacementBB);
+ StartBB->eraseFromParent();
+ FollowBB->eraseFromParent();
+
+ // Make sure to save changes back to the StartBB.
+ StartBB = PrevBB;
+ EndBB = nullptr;
+ PrevBB = nullptr;
+ FollowBB = nullptr;
+
+ CandidateSplit = false;
+}
+
+/// Find whether \p V matches the Constants previously found for the \p GVN.
+///
+/// \param V - The value to check for consistency.
+/// \param GVN - The global value number assigned to \p V.
+/// \param GVNToConstant - The mapping of global value number to Constants.
+/// \returns true if the Value matches the Constant mapped to by V and false if
+/// it \p V is a Constant but does not match.
+/// \returns None if \p V is not a Constant.
+static Optional<bool>
+constantMatches(Value *V, unsigned GVN,
+ DenseMap<unsigned, Constant *> &GVNToConstant) {
+ // See if we have a constants
+ Constant *CST = dyn_cast<Constant>(V);
+ if (!CST)
+ return None;
+
+ // Holds a mapping from a global value number to a Constant.
+ DenseMap<unsigned, Constant *>::iterator GVNToConstantIt;
+ bool Inserted;
+
+
+ // If we have a constant, try to make a new entry in the GVNToConstant.
+ std::tie(GVNToConstantIt, Inserted) =
+ GVNToConstant.insert(std::make_pair(GVN, CST));
+ // If it was found and is not equal, it is not the same. We do not
+ // handle this case yet, and exit early.
+ if (Inserted || (GVNToConstantIt->second == CST))
+ return true;
+
+ return false;
+}
+
+InstructionCost OutlinableRegion::getBenefit(TargetTransformInfo &TTI) {
+ InstructionCost Benefit = 0;
+
+ // Estimate the benefit of outlining a specific sections of the program. We
+ // delegate mostly this task to the TargetTransformInfo so that if the target
+ // has specific changes, we can have a more accurate estimate.
+
+ // However, getInstructionCost delegates the code size calculation for
+ // arithmetic instructions to getArithmeticInstrCost in
+ // include/Analysis/TargetTransformImpl.h, where it always estimates that the
+ // code size for a division and remainder instruction to be equal to 4, and
+ // everything else to 1. This is not an accurate representation of the
+ // division instruction for targets that have a native division instruction.
+ // To be overly conservative, we only add 1 to the number of instructions for
+ // each division instruction.
+ for (Instruction &I : *StartBB) {
+ switch (I.getOpcode()) {
+ case Instruction::FDiv:
+ case Instruction::FRem:
+ case Instruction::SDiv:
+ case Instruction::SRem:
+ case Instruction::UDiv:
+ case Instruction::URem:
+ Benefit += 1;
+ break;
+ default:
+ Benefit += TTI.getInstructionCost(&I, TargetTransformInfo::TCK_CodeSize);
+ break;
+ }
+ }
+
+ return Benefit;
+}
+
+/// Find whether \p Region matches the global value numbering to Constant
+/// mapping found so far.
+///
+/// \param Region - The OutlinableRegion we are checking for constants
+/// \param GVNToConstant - The mapping of global value number to Constants.
+/// \param NotSame - The set of global value numbers that do not have the same
+/// constant in each region.
+/// \returns true if all Constants are the same in every use of a Constant in \p
+/// Region and false if not
+static bool
+collectRegionsConstants(OutlinableRegion &Region,
+ DenseMap<unsigned, Constant *> &GVNToConstant,
+ DenseSet<unsigned> &NotSame) {
+ bool ConstantsTheSame = true;
+
+ IRSimilarityCandidate &C = *Region.Candidate;
+ for (IRInstructionData &ID : C) {
+
+ // Iterate over the operands in an instruction. If the global value number,
+ // assigned by the IRSimilarityCandidate, has been seen before, we check if
+ // the the number has been found to be not the same value in each instance.
+ for (Value *V : ID.OperVals) {
+ Optional<unsigned> GVNOpt = C.getGVN(V);
+ assert(GVNOpt.hasValue() && "Expected a GVN for operand?");
+ unsigned GVN = GVNOpt.getValue();
+
+ // Check if this global value has been found to not be the same already.
+ if (NotSame.contains(GVN)) {
+ if (isa<Constant>(V))
+ ConstantsTheSame = false;
+ continue;
+ }
+
+ // If it has been the same so far, we check the value for if the
+ // associated Constant value match the previous instances of the same
+ // global value number. If the global value does not map to a Constant,
+ // it is considered to not be the same value.
+ Optional<bool> ConstantMatches = constantMatches(V, GVN, GVNToConstant);
+ if (ConstantMatches.hasValue()) {
+ if (ConstantMatches.getValue())
+ continue;
+ else
+ ConstantsTheSame = false;
+ }
+
+ // While this value is a register, it might not have been previously,
+ // make sure we don't already have a constant mapped to this global value
+ // number.
+ if (GVNToConstant.find(GVN) != GVNToConstant.end())
+ ConstantsTheSame = false;
+
+ NotSame.insert(GVN);
+ }
+ }
+
+ return ConstantsTheSame;
+}
+
+void OutlinableGroup::findSameConstants(DenseSet<unsigned> &NotSame) {
+ DenseMap<unsigned, Constant *> GVNToConstant;
+
+ for (OutlinableRegion *Region : Regions)
+ collectRegionsConstants(*Region, GVNToConstant, NotSame);
+}
+
+void OutlinableGroup::collectGVNStoreSets(Module &M) {
+ for (OutlinableRegion *OS : Regions)
+ OutputGVNCombinations.insert(OS->GVNStores);
+
+ // We are adding an extracted argument to decide between which output path
+ // to use in the basic block. It is used in a switch statement and only
+ // needs to be an integer.
+ if (OutputGVNCombinations.size() > 1)
+ ArgumentTypes.push_back(Type::getInt32Ty(M.getContext()));
+}
+
+Function *IROutliner::createFunction(Module &M, OutlinableGroup &Group,
+ unsigned FunctionNameSuffix) {
+ assert(!Group.OutlinedFunction && "Function is already defined!");
+
+ Group.OutlinedFunctionType = FunctionType::get(
+ Type::getVoidTy(M.getContext()), Group.ArgumentTypes, false);
+
+ // These functions will only be called from within the same module, so
+ // we can set an internal linkage.
+ Group.OutlinedFunction = Function::Create(
+ Group.OutlinedFunctionType, GlobalValue::InternalLinkage,
+ "outlined_ir_func_" + std::to_string(FunctionNameSuffix), M);
+
+ // Transfer the swifterr attribute to the correct function parameter.
+ if (Group.SwiftErrorArgument.hasValue())
+ Group.OutlinedFunction->addParamAttr(Group.SwiftErrorArgument.getValue(),
+ Attribute::SwiftError);
+
+ Group.OutlinedFunction->addFnAttr(Attribute::OptimizeForSize);
+ Group.OutlinedFunction->addFnAttr(Attribute::MinSize);
+
+ return Group.OutlinedFunction;
+}
+
+/// Move each BasicBlock in \p Old to \p New.
+///
+/// \param [in] Old - the function to move the basic blocks from.
+/// \param [in] New - The function to move the basic blocks to.
+/// \returns the first return block for the function in New.
+static BasicBlock *moveFunctionData(Function &Old, Function &New) {
+ Function::iterator CurrBB, NextBB, FinalBB;
+ BasicBlock *NewEnd = nullptr;
+ std::vector<Instruction *> DebugInsts;
+ for (CurrBB = Old.begin(), FinalBB = Old.end(); CurrBB != FinalBB;
+ CurrBB = NextBB) {
+ NextBB = std::next(CurrBB);
+ CurrBB->removeFromParent();
+ CurrBB->insertInto(&New);
+ Instruction *I = CurrBB->getTerminator();
+ if (isa<ReturnInst>(I))
+ NewEnd = &(*CurrBB);
+ }
+
+ assert(NewEnd && "No return instruction for new function?");
+ return NewEnd;
+}
+
+/// Find the the constants that will need to be lifted into arguments
+/// as they are not the same in each instance of the region.
+///
+/// \param [in] C - The IRSimilarityCandidate containing the region we are
+/// analyzing.
+/// \param [in] NotSame - The set of global value numbers that do not have a
+/// single Constant across all OutlinableRegions similar to \p C.
+/// \param [out] Inputs - The list containing the global value numbers of the
+/// arguments needed for the region of code.
+static void findConstants(IRSimilarityCandidate &C, DenseSet<unsigned> &NotSame,
+ std::vector<unsigned> &Inputs) {
+ DenseSet<unsigned> Seen;
+ // Iterate over the instructions, and find what constants will need to be
+ // extracted into arguments.
+ for (IRInstructionDataList::iterator IDIt = C.begin(), EndIDIt = C.end();
+ IDIt != EndIDIt; IDIt++) {
+ for (Value *V : (*IDIt).OperVals) {
+ // Since these are stored before any outlining, they will be in the
+ // global value numbering.
+ unsigned GVN = C.getGVN(V).getValue();
+ if (isa<Constant>(V))
+ if (NotSame.contains(GVN) && !Seen.contains(GVN)) {
+ Inputs.push_back(GVN);
+ Seen.insert(GVN);
+ }
+ }
+ }
+}
+
+/// Find the GVN for the inputs that have been found by the CodeExtractor.
+///
+/// \param [in] C - The IRSimilarityCandidate containing the region we are
+/// analyzing.
+/// \param [in] CurrentInputs - The set of inputs found by the
+/// CodeExtractor.
+/// \param [out] EndInputNumbers - The global value numbers for the extracted
+/// arguments.
+/// \param [in] OutputMappings - The mapping of values that have been replaced
+/// by a new output value.
+/// \param [out] EndInputs - The global value numbers for the extracted
+/// arguments.
+static void mapInputsToGVNs(IRSimilarityCandidate &C,
+ SetVector<Value *> &CurrentInputs,
+ const DenseMap<Value *, Value *> &OutputMappings,
+ std::vector<unsigned> &EndInputNumbers) {
+ // Get the Global Value Number for each input. We check if the Value has been
+ // replaced by a different value at output, and use the original value before
+ // replacement.
+ for (Value *Input : CurrentInputs) {
+ assert(Input && "Have a nullptr as an input");
+ if (OutputMappings.find(Input) != OutputMappings.end())
+ Input = OutputMappings.find(Input)->second;
+ assert(C.getGVN(Input).hasValue() &&
+ "Could not find a numbering for the given input");
+ EndInputNumbers.push_back(C.getGVN(Input).getValue());
+ }
+}
+
+/// Find the original value for the \p ArgInput values if any one of them was
+/// replaced during a previous extraction.
+///
+/// \param [in] ArgInputs - The inputs to be extracted by the code extractor.
+/// \param [in] OutputMappings - The mapping of values that have been replaced
+/// by a new output value.
+/// \param [out] RemappedArgInputs - The remapped values according to
+/// \p OutputMappings that will be extracted.
+static void
+remapExtractedInputs(const ArrayRef<Value *> ArgInputs,
+ const DenseMap<Value *, Value *> &OutputMappings,
+ SetVector<Value *> &RemappedArgInputs) {
+ // Get the global value number for each input that will be extracted as an
+ // argument by the code extractor, remapping if needed for reloaded values.
+ for (Value *Input : ArgInputs) {
+ if (OutputMappings.find(Input) != OutputMappings.end())
+ Input = OutputMappings.find(Input)->second;
+ RemappedArgInputs.insert(Input);
+ }
+}
+
+/// Find the input GVNs and the output values for a region of Instructions.
+/// Using the code extractor, we collect the inputs to the extracted function.
+///
+/// The \p Region can be identified as needing to be ignored in this function.
+/// It should be checked whether it should be ignored after a call to this
+/// function.
+///
+/// \param [in,out] Region - The region of code to be analyzed.
+/// \param [out] InputGVNs - The global value numbers for the extracted
+/// arguments.
+/// \param [in] NotSame - The global value numbers in the region that do not
+/// have the same constant value in the regions structurally similar to
+/// \p Region.
+/// \param [in] OutputMappings - The mapping of values that have been replaced
+/// by a new output value after extraction.
+/// \param [out] ArgInputs - The values of the inputs to the extracted function.
+/// \param [out] Outputs - The set of values extracted by the CodeExtractor
+/// as outputs.
+static void getCodeExtractorArguments(
+ OutlinableRegion &Region, std::vector<unsigned> &InputGVNs,
+ DenseSet<unsigned> &NotSame, DenseMap<Value *, Value *> &OutputMappings,
+ SetVector<Value *> &ArgInputs, SetVector<Value *> &Outputs) {
+ IRSimilarityCandidate &C = *Region.Candidate;
+
+ // OverallInputs are the inputs to the region found by the CodeExtractor,
+ // SinkCands and HoistCands are used by the CodeExtractor to find sunken
+ // allocas of values whose lifetimes are contained completely within the
+ // outlined region. PremappedInputs are the arguments found by the
+ // CodeExtractor, removing conditions such as sunken allocas, but that
+ // may need to be remapped due to the extracted output values replacing
+ // the original values. We use DummyOutputs for this first run of finding
+ // inputs and outputs since the outputs could change during findAllocas,
+ // the correct set of extracted outputs will be in the final Outputs ValueSet.
+ SetVector<Value *> OverallInputs, PremappedInputs, SinkCands, HoistCands,
+ DummyOutputs;
+
+ // Use the code extractor to get the inputs and outputs, without sunken
+ // allocas or removing llvm.assumes.
+ CodeExtractor *CE = Region.CE;
+ CE->findInputsOutputs(OverallInputs, DummyOutputs, SinkCands);
+ assert(Region.StartBB && "Region must have a start BasicBlock!");
+ Function *OrigF = Region.StartBB->getParent();
+ CodeExtractorAnalysisCache CEAC(*OrigF);
+ BasicBlock *Dummy = nullptr;
+
+ // The region may be ineligible due to VarArgs in the parent function. In this
+ // case we ignore the region.
+ if (!CE->isEligible()) {
+ Region.IgnoreRegion = true;
+ return;
+ }
+
+ // Find if any values are going to be sunk into the function when extracted
+ CE->findAllocas(CEAC, SinkCands, HoistCands, Dummy);
+ CE->findInputsOutputs(PremappedInputs, Outputs, SinkCands);
+
+ // TODO: Support regions with sunken allocas: values whose lifetimes are
+ // contained completely within the outlined region. These are not guaranteed
+ // to be the same in every region, so we must elevate them all to arguments
+ // when they appear. If these values are not equal, it means there is some
+ // Input in OverallInputs that was removed for ArgInputs.
+ if (OverallInputs.size() != PremappedInputs.size()) {
+ Region.IgnoreRegion = true;
+ return;
+ }
+
+ findConstants(C, NotSame, InputGVNs);
+
+ mapInputsToGVNs(C, OverallInputs, OutputMappings, InputGVNs);
+
+ remapExtractedInputs(PremappedInputs.getArrayRef(), OutputMappings,
+ ArgInputs);
+
+ // Sort the GVNs, since we now have constants included in the \ref InputGVNs
+ // we need to make sure they are in a deterministic order.
+ stable_sort(InputGVNs);
+}
+
+/// Look over the inputs and map each input argument to an argument in the
+/// overall function for the OutlinableRegions. This creates a way to replace
+/// the arguments of the extracted function with the arguments of the new
+/// overall function.
+///
+/// \param [in,out] Region - The region of code to be analyzed.
+/// \param [in] InputsGVNs - The global value numbering of the input values
+/// collected.
+/// \param [in] ArgInputs - The values of the arguments to the extracted
+/// function.
+static void
+findExtractedInputToOverallInputMapping(OutlinableRegion &Region,
+ std::vector<unsigned> &InputGVNs,
+ SetVector<Value *> &ArgInputs) {
+
+ IRSimilarityCandidate &C = *Region.Candidate;
+ OutlinableGroup &Group = *Region.Parent;
+
+ // This counts the argument number in the overall function.
+ unsigned TypeIndex = 0;
+
+ // This counts the argument number in the extracted function.
+ unsigned OriginalIndex = 0;
+
+ // Find the mapping of the extracted arguments to the arguments for the
+ // overall function. Since there may be extra arguments in the overall
+ // function to account for the extracted constants, we have two different
+ // counters as we find extracted arguments, and as we come across overall
+ // arguments.
+ for (unsigned InputVal : InputGVNs) {
+ Optional<Value *> InputOpt = C.fromGVN(InputVal);
+ assert(InputOpt.hasValue() && "Global value number not found?");
+ Value *Input = InputOpt.getValue();
+
+ if (!Group.InputTypesSet) {
+ Group.ArgumentTypes.push_back(Input->getType());
+ // If the input value has a swifterr attribute, make sure to mark the
+ // argument in the overall function.
+ if (Input->isSwiftError()) {
+ assert(
+ !Group.SwiftErrorArgument.hasValue() &&
+ "Argument already marked with swifterr for this OutlinableGroup!");
+ Group.SwiftErrorArgument = TypeIndex;
+ }
+ }
+
+ // Check if we have a constant. If we do add it to the overall argument
+ // number to Constant map for the region, and continue to the next input.
+ if (Constant *CST = dyn_cast<Constant>(Input)) {
+ Region.AggArgToConstant.insert(std::make_pair(TypeIndex, CST));
+ TypeIndex++;
+ continue;
+ }
+
+ // It is not a constant, we create the mapping from extracted argument list
+ // to the overall argument list.
+ assert(ArgInputs.count(Input) && "Input cannot be found!");
+
+ Region.ExtractedArgToAgg.insert(std::make_pair(OriginalIndex, TypeIndex));
+ Region.AggArgToExtracted.insert(std::make_pair(TypeIndex, OriginalIndex));
+ OriginalIndex++;
+ TypeIndex++;
+ }
+
+ // If the function type definitions for the OutlinableGroup holding the region
+ // have not been set, set the length of the inputs here. We should have the
+ // same inputs for all of the different regions contained in the
+ // OutlinableGroup since they are all structurally similar to one another.
+ if (!Group.InputTypesSet) {
+ Group.NumAggregateInputs = TypeIndex;
+ Group.InputTypesSet = true;
+ }
+
+ Region.NumExtractedInputs = OriginalIndex;
+}
+
+/// Create a mapping of the output arguments for the \p Region to the output
+/// arguments of the overall outlined function.
+///
+/// \param [in,out] Region - The region of code to be analyzed.
+/// \param [in] Outputs - The values found by the code extractor.
+static void
+findExtractedOutputToOverallOutputMapping(OutlinableRegion &Region,
+ ArrayRef<Value *> Outputs) {
+ OutlinableGroup &Group = *Region.Parent;
+ IRSimilarityCandidate &C = *Region.Candidate;
+
+ // This counts the argument number in the extracted function.
+ unsigned OriginalIndex = Region.NumExtractedInputs;
+
+ // This counts the argument number in the overall function.
+ unsigned TypeIndex = Group.NumAggregateInputs;
+ bool TypeFound;
+ DenseSet<unsigned> AggArgsUsed;
+
+ // Iterate over the output types and identify if there is an aggregate pointer
+ // type whose base type matches the current output type. If there is, we mark
+ // that we will use this output register for this value. If not we add another
+ // type to the overall argument type list. We also store the GVNs used for
+ // stores to identify which values will need to be moved into an special
+ // block that holds the stores to the output registers.
+ for (Value *Output : Outputs) {
+ TypeFound = false;
+ // We can do this since it is a result value, and will have a number
+ // that is necessarily the same. BUT if in the future, the instructions
+ // do not have to be in same order, but are functionally the same, we will
+ // have to use a different scheme, as one-to-one correspondence is not
+ // guaranteed.
+ unsigned GlobalValue = C.getGVN(Output).getValue();
+ unsigned ArgumentSize = Group.ArgumentTypes.size();
+
+ for (unsigned Jdx = TypeIndex; Jdx < ArgumentSize; Jdx++) {
+ if (Group.ArgumentTypes[Jdx] != PointerType::getUnqual(Output->getType()))
+ continue;
+
+ if (AggArgsUsed.contains(Jdx))
+ continue;
+
+ TypeFound = true;
+ AggArgsUsed.insert(Jdx);
+ Region.ExtractedArgToAgg.insert(std::make_pair(OriginalIndex, Jdx));
+ Region.AggArgToExtracted.insert(std::make_pair(Jdx, OriginalIndex));
+ Region.GVNStores.push_back(GlobalValue);
+ break;
+ }
+
+ // We were unable to find an unused type in the output type set that matches
+ // the output, so we add a pointer type to the argument types of the overall
+ // function to handle this output and create a mapping to it.
+ if (!TypeFound) {
+ Group.ArgumentTypes.push_back(PointerType::getUnqual(Output->getType()));
+ AggArgsUsed.insert(Group.ArgumentTypes.size() - 1);
+ Region.ExtractedArgToAgg.insert(
+ std::make_pair(OriginalIndex, Group.ArgumentTypes.size() - 1));
+ Region.AggArgToExtracted.insert(
+ std::make_pair(Group.ArgumentTypes.size() - 1, OriginalIndex));
+ Region.GVNStores.push_back(GlobalValue);
+ }
+
+ stable_sort(Region.GVNStores);
+ OriginalIndex++;
+ TypeIndex++;
+ }
+}
+
+void IROutliner::findAddInputsOutputs(Module &M, OutlinableRegion &Region,
+ DenseSet<unsigned> &NotSame) {
+ std::vector<unsigned> Inputs;
+ SetVector<Value *> ArgInputs, Outputs;
+
+ getCodeExtractorArguments(Region, Inputs, NotSame, OutputMappings, ArgInputs,
+ Outputs);
+
+ if (Region.IgnoreRegion)
+ return;
+
+ // Map the inputs found by the CodeExtractor to the arguments found for
+ // the overall function.
+ findExtractedInputToOverallInputMapping(Region, Inputs, ArgInputs);
+
+ // Map the outputs found by the CodeExtractor to the arguments found for
+ // the overall function.
+ findExtractedOutputToOverallOutputMapping(Region, Outputs.getArrayRef());
+}
+
+/// Replace the extracted function in the Region with a call to the overall
+/// function constructed from the deduplicated similar regions, replacing and
+/// remapping the values passed to the extracted function as arguments to the
+/// new arguments of the overall function.
+///
+/// \param [in] M - The module to outline from.
+/// \param [in] Region - The regions of extracted code to be replaced with a new
+/// function.
+/// \returns a call instruction with the replaced function.
+CallInst *replaceCalledFunction(Module &M, OutlinableRegion &Region) {
+ std::vector<Value *> NewCallArgs;
+ DenseMap<unsigned, unsigned>::iterator ArgPair;
+
+ OutlinableGroup &Group = *Region.Parent;
+ CallInst *Call = Region.Call;
+ assert(Call && "Call to replace is nullptr?");
+ Function *AggFunc = Group.OutlinedFunction;
+ assert(AggFunc && "Function to replace with is nullptr?");
+
+ // If the arguments are the same size, there are not values that need to be
+ // made argument, or different output registers to handle. We can simply
+ // replace the called function in this case.
+ if (AggFunc->arg_size() == Call->arg_size()) {
+ LLVM_DEBUG(dbgs() << "Replace call to " << *Call << " with call to "
+ << *AggFunc << " with same number of arguments\n");
+ Call->setCalledFunction(AggFunc);
+ return Call;
+ }
+
+ // We have a different number of arguments than the new function, so
+ // we need to use our previously mappings off extracted argument to overall
+ // function argument, and constants to overall function argument to create the
+ // new argument list.
+ for (unsigned AggArgIdx = 0; AggArgIdx < AggFunc->arg_size(); AggArgIdx++) {
+
+ if (AggArgIdx == AggFunc->arg_size() - 1 &&
+ Group.OutputGVNCombinations.size() > 1) {
+ // If we are on the last argument, and we need to differentiate between
+ // output blocks, add an integer to the argument list to determine
+ // what block to take
+ LLVM_DEBUG(dbgs() << "Set switch block argument to "
+ << Region.OutputBlockNum << "\n");
+ NewCallArgs.push_back(ConstantInt::get(Type::getInt32Ty(M.getContext()),
+ Region.OutputBlockNum));
+ continue;
+ }
+
+ ArgPair = Region.AggArgToExtracted.find(AggArgIdx);
+ if (ArgPair != Region.AggArgToExtracted.end()) {
+ Value *ArgumentValue = Call->getArgOperand(ArgPair->second);
+ // If we found the mapping from the extracted function to the overall
+ // function, we simply add it to the argument list. We use the same
+ // value, it just needs to honor the new order of arguments.
+ LLVM_DEBUG(dbgs() << "Setting argument " << AggArgIdx << " to value "
+ << *ArgumentValue << "\n");
+ NewCallArgs.push_back(ArgumentValue);
+ continue;
+ }
+
+ // If it is a constant, we simply add it to the argument list as a value.
+ if (Region.AggArgToConstant.find(AggArgIdx) !=
+ Region.AggArgToConstant.end()) {
+ Constant *CST = Region.AggArgToConstant.find(AggArgIdx)->second;
+ LLVM_DEBUG(dbgs() << "Setting argument " << AggArgIdx << " to value "
+ << *CST << "\n");
+ NewCallArgs.push_back(CST);
+ continue;
+ }
+
+ // Add a nullptr value if the argument is not found in the extracted
+ // function. If we cannot find a value, it means it is not in use
+ // for the region, so we should not pass anything to it.
+ LLVM_DEBUG(dbgs() << "Setting argument " << AggArgIdx << " to nullptr\n");
+ NewCallArgs.push_back(ConstantPointerNull::get(
+ static_cast<PointerType *>(AggFunc->getArg(AggArgIdx)->getType())));
+ }
+
+ LLVM_DEBUG(dbgs() << "Replace call to " << *Call << " with call to "
+ << *AggFunc << " with new set of arguments\n");
+ // Create the new call instruction and erase the old one.
+ Call = CallInst::Create(AggFunc->getFunctionType(), AggFunc, NewCallArgs, "",
+ Call);
+
+ // It is possible that the call to the outlined function is either the first
+ // instruction is in the new block, the last instruction, or both. If either
+ // of these is the case, we need to make sure that we replace the instruction
+ // in the IRInstructionData struct with the new call.
+ CallInst *OldCall = Region.Call;
+ if (Region.NewFront->Inst == OldCall)
+ Region.NewFront->Inst = Call;
+ if (Region.NewBack->Inst == OldCall)
+ Region.NewBack->Inst = Call;
+
+ // Transfer any debug information.
+ Call->setDebugLoc(Region.Call->getDebugLoc());
+
+ // Remove the old instruction.
+ OldCall->eraseFromParent();
+ Region.Call = Call;
+
+ // Make sure that the argument in the new function has the SwiftError
+ // argument.
+ if (Group.SwiftErrorArgument.hasValue())
+ Call->addParamAttr(Group.SwiftErrorArgument.getValue(),
+ Attribute::SwiftError);
+
+ return Call;
+}
+
+// Within an extracted function, replace the argument uses of the extracted
+// region with the arguments of the function for an OutlinableGroup.
+//
+/// \param [in] Region - The region of extracted code to be changed.
+/// \param [in,out] OutputBB - The BasicBlock for the output stores for this
+/// region.
+static void replaceArgumentUses(OutlinableRegion &Region,
+ BasicBlock *OutputBB) {
+ OutlinableGroup &Group = *Region.Parent;
+ assert(Region.ExtractedFunction && "Region has no extracted function?");
+
+ for (unsigned ArgIdx = 0; ArgIdx < Region.ExtractedFunction->arg_size();
+ ArgIdx++) {
+ assert(Region.ExtractedArgToAgg.find(ArgIdx) !=
+ Region.ExtractedArgToAgg.end() &&
+ "No mapping from extracted to outlined?");
+ unsigned AggArgIdx = Region.ExtractedArgToAgg.find(ArgIdx)->second;
+ Argument *AggArg = Group.OutlinedFunction->getArg(AggArgIdx);
+ Argument *Arg = Region.ExtractedFunction->getArg(ArgIdx);
+ // The argument is an input, so we can simply replace it with the overall
+ // argument value
+ if (ArgIdx < Region.NumExtractedInputs) {
+ LLVM_DEBUG(dbgs() << "Replacing uses of input " << *Arg << " in function "
+ << *Region.ExtractedFunction << " with " << *AggArg
+ << " in function " << *Group.OutlinedFunction << "\n");
+ Arg->replaceAllUsesWith(AggArg);
+ continue;
+ }
+
+ // If we are replacing an output, we place the store value in its own
+ // block inside the overall function before replacing the use of the output
+ // in the function.
+ assert(Arg->hasOneUse() && "Output argument can only have one use");
+ User *InstAsUser = Arg->user_back();
+ assert(InstAsUser && "User is nullptr!");
+
+ Instruction *I = cast<Instruction>(InstAsUser);
+ I->setDebugLoc(DebugLoc());
+ LLVM_DEBUG(dbgs() << "Move store for instruction " << *I << " to "
+ << *OutputBB << "\n");
+
+ I->moveBefore(*OutputBB, OutputBB->end());
+
+ LLVM_DEBUG(dbgs() << "Replacing uses of output " << *Arg << " in function "
+ << *Region.ExtractedFunction << " with " << *AggArg
+ << " in function " << *Group.OutlinedFunction << "\n");
+ Arg->replaceAllUsesWith(AggArg);
+ }
+}
+
+/// Within an extracted function, replace the constants that need to be lifted
+/// into arguments with the actual argument.
+///
+/// \param Region [in] - The region of extracted code to be changed.
+void replaceConstants(OutlinableRegion &Region) {
+ OutlinableGroup &Group = *Region.Parent;
+ // Iterate over the constants that need to be elevated into arguments
+ for (std::pair<unsigned, Constant *> &Const : Region.AggArgToConstant) {
+ unsigned AggArgIdx = Const.first;
+ Function *OutlinedFunction = Group.OutlinedFunction;
+ assert(OutlinedFunction && "Overall Function is not defined?");
+ Constant *CST = Const.second;
+ Argument *Arg = Group.OutlinedFunction->getArg(AggArgIdx);
+ // Identify the argument it will be elevated to, and replace instances of
+ // that constant in the function.
+
+ // TODO: If in the future constants do not have one global value number,
+ // i.e. a constant 1 could be mapped to several values, this check will
+ // have to be more strict. It cannot be using only replaceUsesWithIf.
+
+ LLVM_DEBUG(dbgs() << "Replacing uses of constant " << *CST
+ << " in function " << *OutlinedFunction << " with "
+ << *Arg << "\n");
+ CST->replaceUsesWithIf(Arg, [OutlinedFunction](Use &U) {
+ if (Instruction *I = dyn_cast<Instruction>(U.getUser()))
+ return I->getFunction() == OutlinedFunction;
+ return false;
+ });
+ }
+}
+
+/// For the given function, find all the nondebug or lifetime instructions,
+/// and return them as a vector. Exclude any blocks in \p ExludeBlocks.
+///
+/// \param [in] F - The function we collect the instructions from.
+/// \param [in] ExcludeBlocks - BasicBlocks to ignore.
+/// \returns the list of instructions extracted.
+static std::vector<Instruction *>
+collectRelevantInstructions(Function &F,
+ DenseSet<BasicBlock *> &ExcludeBlocks) {
+ std::vector<Instruction *> RelevantInstructions;
+
+ for (BasicBlock &BB : F) {
+ if (ExcludeBlocks.contains(&BB))
+ continue;
+
+ for (Instruction &Inst : BB) {
+ if (Inst.isLifetimeStartOrEnd())
+ continue;
+ if (isa<DbgInfoIntrinsic>(Inst))
+ continue;
+
+ RelevantInstructions.push_back(&Inst);
+ }
+ }
+
+ return RelevantInstructions;
+}
+
+/// It is possible that there is a basic block that already performs the same
+/// stores. This returns a duplicate block, if it exists
+///
+/// \param OutputBB [in] the block we are looking for a duplicate of.
+/// \param OutputStoreBBs [in] The existing output blocks.
+/// \returns an optional value with the number output block if there is a match.
+Optional<unsigned>
+findDuplicateOutputBlock(BasicBlock *OutputBB,
+ ArrayRef<BasicBlock *> OutputStoreBBs) {
+
+ bool WrongInst = false;
+ bool WrongSize = false;
+ unsigned MatchingNum = 0;
+ for (BasicBlock *CompBB : OutputStoreBBs) {
+ WrongInst = false;
+ if (CompBB->size() - 1 != OutputBB->size()) {
+ WrongSize = true;
+ MatchingNum++;
+ continue;
+ }
+
+ WrongSize = false;
+ BasicBlock::iterator NIt = OutputBB->begin();
+ for (Instruction &I : *CompBB) {
+ if (isa<BranchInst>(&I))
+ continue;
+
+ if (!I.isIdenticalTo(&(*NIt))) {
+ WrongInst = true;
+ break;
+ }
+
+ NIt++;
+ }
+ if (!WrongInst && !WrongSize)
+ return MatchingNum;
+
+ MatchingNum++;
+ }
+
+ return None;
+}
+
+/// For the outlined section, move needed the StoreInsts for the output
+/// registers into their own block. Then, determine if there is a duplicate
+/// output block already created.
+///
+/// \param [in] OG - The OutlinableGroup of regions to be outlined.
+/// \param [in] Region - The OutlinableRegion that is being analyzed.
+/// \param [in,out] OutputBB - the block that stores for this region will be
+/// placed in.
+/// \param [in] EndBB - the final block of the extracted function.
+/// \param [in] OutputMappings - OutputMappings the mapping of values that have
+/// been replaced by a new output value.
+/// \param [in,out] OutputStoreBBs - The existing output blocks.
+static void
+alignOutputBlockWithAggFunc(OutlinableGroup &OG, OutlinableRegion &Region,
+ BasicBlock *OutputBB, BasicBlock *EndBB,
+ const DenseMap<Value *, Value *> &OutputMappings,
+ std::vector<BasicBlock *> &OutputStoreBBs) {
+ DenseSet<unsigned> ValuesToFind(Region.GVNStores.begin(),
+ Region.GVNStores.end());
+
+ // We iterate over the instructions in the extracted function, and find the
+ // global value number of the instructions. If we find a value that should
+ // be contained in a store, we replace the uses of the value with the value
+ // from the overall function, so that the store is storing the correct
+ // value from the overall function.
+ DenseSet<BasicBlock *> ExcludeBBs(OutputStoreBBs.begin(),
+ OutputStoreBBs.end());
+ ExcludeBBs.insert(OutputBB);
+ std::vector<Instruction *> ExtractedFunctionInsts =
+ collectRelevantInstructions(*(Region.ExtractedFunction), ExcludeBBs);
+ std::vector<Instruction *> OverallFunctionInsts =
+ collectRelevantInstructions(*OG.OutlinedFunction, ExcludeBBs);
+
+ assert(ExtractedFunctionInsts.size() == OverallFunctionInsts.size() &&
+ "Number of relevant instructions not equal!");
+
+ unsigned NumInstructions = ExtractedFunctionInsts.size();
+ for (unsigned Idx = 0; Idx < NumInstructions; Idx++) {
+ Value *V = ExtractedFunctionInsts[Idx];
+
+ if (OutputMappings.find(V) != OutputMappings.end())
+ V = OutputMappings.find(V)->second;
+ Optional<unsigned> GVN = Region.Candidate->getGVN(V);
+
+ // If we have found one of the stored values for output, replace the value
+ // with the corresponding one from the overall function.
+ if (GVN.hasValue() && ValuesToFind.erase(GVN.getValue())) {
+ V->replaceAllUsesWith(OverallFunctionInsts[Idx]);
+ if (ValuesToFind.size() == 0)
+ break;
+ }
+
+ if (ValuesToFind.size() == 0)
+ break;
+ }
+
+ assert(ValuesToFind.size() == 0 && "Not all store values were handled!");
+
+ // If the size of the block is 0, then there are no stores, and we do not
+ // need to save this block.
+ if (OutputBB->size() == 0) {
+ Region.OutputBlockNum = -1;
+ OutputBB->eraseFromParent();
+ return;
+ }
+
+ // Determine is there is a duplicate block.
+ Optional<unsigned> MatchingBB =
+ findDuplicateOutputBlock(OutputBB, OutputStoreBBs);
+
+ // If there is, we remove the new output block. If it does not,
+ // we add it to our list of output blocks.
+ if (MatchingBB.hasValue()) {
+ LLVM_DEBUG(dbgs() << "Set output block for region in function"
+ << Region.ExtractedFunction << " to "
+ << MatchingBB.getValue());
+
+ Region.OutputBlockNum = MatchingBB.getValue();
+ OutputBB->eraseFromParent();
+ return;
+ }
+
+ Region.OutputBlockNum = OutputStoreBBs.size();
+
+ LLVM_DEBUG(dbgs() << "Create output block for region in"
+ << Region.ExtractedFunction << " to "
+ << *OutputBB);
+ OutputStoreBBs.push_back(OutputBB);
+ BranchInst::Create(EndBB, OutputBB);
+}
+
+/// Create the switch statement for outlined function to differentiate between
+/// all the output blocks.
+///
+/// For the outlined section, determine if an outlined block already exists that
+/// matches the needed stores for the extracted section.
+/// \param [in] M - The module we are outlining from.
+/// \param [in] OG - The group of regions to be outlined.
+/// \param [in] OS - The region that is being analyzed.
+/// \param [in] EndBB - The final block of the extracted function.
+/// \param [in,out] OutputStoreBBs - The existing output blocks.
+void createSwitchStatement(Module &M, OutlinableGroup &OG, BasicBlock *EndBB,
+ ArrayRef<BasicBlock *> OutputStoreBBs) {
+ // We only need the switch statement if there is more than one store
+ // combination.
+ if (OG.OutputGVNCombinations.size() > 1) {
+ Function *AggFunc = OG.OutlinedFunction;
+ // Create a final block
+ BasicBlock *ReturnBlock =
+ BasicBlock::Create(M.getContext(), "final_block", AggFunc);
+ Instruction *Term = EndBB->getTerminator();
+ Term->moveBefore(*ReturnBlock, ReturnBlock->end());
+ // Put the switch statement in the old end basic block for the function with
+ // a fall through to the new return block
+ LLVM_DEBUG(dbgs() << "Create switch statement in " << *AggFunc << " for "
+ << OutputStoreBBs.size() << "\n");
+ SwitchInst *SwitchI =
+ SwitchInst::Create(AggFunc->getArg(AggFunc->arg_size() - 1),
+ ReturnBlock, OutputStoreBBs.size(), EndBB);
+
+ unsigned Idx = 0;
+ for (BasicBlock *BB : OutputStoreBBs) {
+ SwitchI->addCase(ConstantInt::get(Type::getInt32Ty(M.getContext()), Idx),
+ BB);
+ Term = BB->getTerminator();
+ Term->setSuccessor(0, ReturnBlock);
+ Idx++;
+ }
+ return;
+ }
+
+ // If there needs to be stores, move them from the output block to the end
+ // block to save on branching instructions.
+ if (OutputStoreBBs.size() == 1) {
+ LLVM_DEBUG(dbgs() << "Move store instructions to the end block in "
+ << *OG.OutlinedFunction << "\n");
+ BasicBlock *OutputBlock = OutputStoreBBs[0];
+ Instruction *Term = OutputBlock->getTerminator();
+ Term->eraseFromParent();
+ Term = EndBB->getTerminator();
+ moveBBContents(*OutputBlock, *EndBB);
+ Term->moveBefore(*EndBB, EndBB->end());
+ OutputBlock->eraseFromParent();
+ }
+}
+
+/// Fill the new function that will serve as the replacement function for all of
+/// the extracted regions of a certain structure from the first region in the
+/// list of regions. Replace this first region's extracted function with the
+/// new overall function.
+///
+/// \param [in] M - The module we are outlining from.
+/// \param [in] CurrentGroup - The group of regions to be outlined.
+/// \param [in,out] OutputStoreBBs - The output blocks for each different
+/// set of stores needed for the different functions.
+/// \param [in,out] FuncsToRemove - Extracted functions to erase from module
+/// once outlining is complete.
+static void fillOverallFunction(Module &M, OutlinableGroup &CurrentGroup,
+ std::vector<BasicBlock *> &OutputStoreBBs,
+ std::vector<Function *> &FuncsToRemove) {
+ OutlinableRegion *CurrentOS = CurrentGroup.Regions[0];
+
+ // Move first extracted function's instructions into new function.
+ LLVM_DEBUG(dbgs() << "Move instructions from "
+ << *CurrentOS->ExtractedFunction << " to instruction "
+ << *CurrentGroup.OutlinedFunction << "\n");
+
+ CurrentGroup.EndBB = moveFunctionData(*CurrentOS->ExtractedFunction,
+ *CurrentGroup.OutlinedFunction);
+
+ // Transfer the attributes from the function to the new function.
+ for (Attribute A :
+ CurrentOS->ExtractedFunction->getAttributes().getFnAttributes())
+ CurrentGroup.OutlinedFunction->addFnAttr(A);
+
+ // Create an output block for the first extracted function.
+ BasicBlock *NewBB = BasicBlock::Create(
+ M.getContext(), Twine("output_block_") + Twine(static_cast<unsigned>(0)),
+ CurrentGroup.OutlinedFunction);
+ CurrentOS->OutputBlockNum = 0;
+
+ replaceArgumentUses(*CurrentOS, NewBB);
+ replaceConstants(*CurrentOS);
+
+ // If the new basic block has no new stores, we can erase it from the module.
+ // It it does, we create a branch instruction to the last basic block from the
+ // new one.
+ if (NewBB->size() == 0) {
+ CurrentOS->OutputBlockNum = -1;
+ NewBB->eraseFromParent();
+ } else {
+ BranchInst::Create(CurrentGroup.EndBB, NewBB);
+ OutputStoreBBs.push_back(NewBB);
+ }
+
+ // Replace the call to the extracted function with the outlined function.
+ CurrentOS->Call = replaceCalledFunction(M, *CurrentOS);
+
+ // We only delete the extracted functions at the end since we may need to
+ // reference instructions contained in them for mapping purposes.
+ FuncsToRemove.push_back(CurrentOS->ExtractedFunction);
+}
+
+void IROutliner::deduplicateExtractedSections(
+ Module &M, OutlinableGroup &CurrentGroup,
+ std::vector<Function *> &FuncsToRemove, unsigned &OutlinedFunctionNum) {
+ createFunction(M, CurrentGroup, OutlinedFunctionNum);
+
+ std::vector<BasicBlock *> OutputStoreBBs;
+
+ OutlinableRegion *CurrentOS;
+
+ fillOverallFunction(M, CurrentGroup, OutputStoreBBs, FuncsToRemove);
+
+ for (unsigned Idx = 1; Idx < CurrentGroup.Regions.size(); Idx++) {
+ CurrentOS = CurrentGroup.Regions[Idx];
+ AttributeFuncs::mergeAttributesForOutlining(*CurrentGroup.OutlinedFunction,
+ *CurrentOS->ExtractedFunction);
+
+ // Create a new BasicBlock to hold the needed store instructions.
+ BasicBlock *NewBB = BasicBlock::Create(
+ M.getContext(), "output_block_" + std::to_string(Idx),
+ CurrentGroup.OutlinedFunction);
+ replaceArgumentUses(*CurrentOS, NewBB);
+
+ alignOutputBlockWithAggFunc(CurrentGroup, *CurrentOS, NewBB,
+ CurrentGroup.EndBB, OutputMappings,
+ OutputStoreBBs);
+
+ CurrentOS->Call = replaceCalledFunction(M, *CurrentOS);
+ FuncsToRemove.push_back(CurrentOS->ExtractedFunction);
+ }
+
+ // Create a switch statement to handle the different output schemes.
+ createSwitchStatement(M, CurrentGroup, CurrentGroup.EndBB, OutputStoreBBs);
+
+ OutlinedFunctionNum++;
+}
+
+void IROutliner::pruneIncompatibleRegions(
+ std::vector<IRSimilarityCandidate> &CandidateVec,
+ OutlinableGroup &CurrentGroup) {
+ bool PreviouslyOutlined;
+
+ // Sort from beginning to end, so the IRSimilarityCandidates are in order.
+ stable_sort(CandidateVec, [](const IRSimilarityCandidate &LHS,
+ const IRSimilarityCandidate &RHS) {
+ return LHS.getStartIdx() < RHS.getStartIdx();
+ });
+
+ unsigned CurrentEndIdx = 0;
+ for (IRSimilarityCandidate &IRSC : CandidateVec) {
+ PreviouslyOutlined = false;
+ unsigned StartIdx = IRSC.getStartIdx();
+ unsigned EndIdx = IRSC.getEndIdx();
+
+ for (unsigned Idx = StartIdx; Idx <= EndIdx; Idx++)
+ if (Outlined.contains(Idx)) {
+ PreviouslyOutlined = true;
+ break;
+ }
+
+ if (PreviouslyOutlined)
+ continue;
+
+ // TODO: If in the future we can outline across BasicBlocks, we will need to
+ // check all BasicBlocks contained in the region.
+ if (IRSC.getStartBB()->hasAddressTaken())
+ continue;
+
+ if (IRSC.front()->Inst->getFunction()->hasLinkOnceODRLinkage() &&
+ !OutlineFromLinkODRs)
+ continue;
+
+ // Greedily prune out any regions that will overlap with already chosen
+ // regions.
+ if (CurrentEndIdx != 0 && StartIdx <= CurrentEndIdx)
+ continue;
+
+ bool BadInst = any_of(IRSC, [this](IRInstructionData &ID) {
+ // We check if there is a discrepancy between the InstructionDataList
+ // and the actual next instruction in the module. If there is, it means
+ // that an extra instruction was added, likely by the CodeExtractor.
+
+ // Since we do not have any similarity data about this particular
+ // instruction, we cannot confidently outline it, and must discard this
+ // candidate.
+ if (std::next(ID.getIterator())->Inst !=
+ ID.Inst->getNextNonDebugInstruction())
+ return true;
+ return !this->InstructionClassifier.visit(ID.Inst);
+ });
+
+ if (BadInst)
+ continue;
+
+ OutlinableRegion *OS = new (RegionAllocator.Allocate())
+ OutlinableRegion(IRSC, CurrentGroup);
+ CurrentGroup.Regions.push_back(OS);
+
+ CurrentEndIdx = EndIdx;
+ }
+}
+
+InstructionCost
+IROutliner::findBenefitFromAllRegions(OutlinableGroup &CurrentGroup) {
+ InstructionCost RegionBenefit = 0;
+ for (OutlinableRegion *Region : CurrentGroup.Regions) {
+ TargetTransformInfo &TTI = getTTI(*Region->StartBB->getParent());
+ // We add the number of instructions in the region to the benefit as an
+ // estimate as to how much will be removed.
+ RegionBenefit += Region->getBenefit(TTI);
+ LLVM_DEBUG(dbgs() << "Adding: " << RegionBenefit
+ << " saved instructions to overfall benefit.\n");
+ }
+
+ return RegionBenefit;
+}
+
+InstructionCost
+IROutliner::findCostOutputReloads(OutlinableGroup &CurrentGroup) {
+ InstructionCost OverallCost = 0;
+ for (OutlinableRegion *Region : CurrentGroup.Regions) {
+ TargetTransformInfo &TTI = getTTI(*Region->StartBB->getParent());
+
+ // Each output incurs a load after the call, so we add that to the cost.
+ for (unsigned OutputGVN : Region->GVNStores) {
+ Optional<Value *> OV = Region->Candidate->fromGVN(OutputGVN);
+ assert(OV.hasValue() && "Could not find value for GVN?");
+ Value *V = OV.getValue();
+ InstructionCost LoadCost =
+ TTI.getMemoryOpCost(Instruction::Load, V->getType(), Align(1), 0,
+ TargetTransformInfo::TCK_CodeSize);
+
+ LLVM_DEBUG(dbgs() << "Adding: " << LoadCost
+ << " instructions to cost for output of type "
+ << *V->getType() << "\n");
+ OverallCost += LoadCost;
+ }
+ }
+
+ return OverallCost;
+}
+
+/// Find the extra instructions needed to handle any output values for the
+/// region.
+///
+/// \param [in] M - The Module to outline from.
+/// \param [in] CurrentGroup - The collection of OutlinableRegions to analyze.
+/// \param [in] TTI - The TargetTransformInfo used to collect information for
+/// new instruction costs.
+/// \returns the additional cost to handle the outputs.
+static InstructionCost findCostForOutputBlocks(Module &M,
+ OutlinableGroup &CurrentGroup,
+ TargetTransformInfo &TTI) {
+ InstructionCost OutputCost = 0;
+
+ for (const ArrayRef<unsigned> &OutputUse :
+ CurrentGroup.OutputGVNCombinations) {
+ IRSimilarityCandidate &Candidate = *CurrentGroup.Regions[0]->Candidate;
+ for (unsigned GVN : OutputUse) {
+ Optional<Value *> OV = Candidate.fromGVN(GVN);
+ assert(OV.hasValue() && "Could not find value for GVN?");
+ Value *V = OV.getValue();
+ InstructionCost StoreCost =
+ TTI.getMemoryOpCost(Instruction::Load, V->getType(), Align(1), 0,
+ TargetTransformInfo::TCK_CodeSize);
+
+ // An instruction cost is added for each store set that needs to occur for
+ // various output combinations inside the function, plus a branch to
+ // return to the exit block.
+ LLVM_DEBUG(dbgs() << "Adding: " << StoreCost
+ << " instructions to cost for output of type "
+ << *V->getType() << "\n");
+ OutputCost += StoreCost;
+ }
+
+ InstructionCost BranchCost =
+ TTI.getCFInstrCost(Instruction::Br, TargetTransformInfo::TCK_CodeSize);
+ LLVM_DEBUG(dbgs() << "Adding " << BranchCost << " to the current cost for"
+ << " a branch instruction\n");
+ OutputCost += BranchCost;
+ }
+
+ // If there is more than one output scheme, we must have a comparison and
+ // branch for each different item in the switch statement.
+ if (CurrentGroup.OutputGVNCombinations.size() > 1) {
+ InstructionCost ComparisonCost = TTI.getCmpSelInstrCost(
+ Instruction::ICmp, Type::getInt32Ty(M.getContext()),
+ Type::getInt32Ty(M.getContext()), CmpInst::BAD_ICMP_PREDICATE,
+ TargetTransformInfo::TCK_CodeSize);
+ InstructionCost BranchCost =
+ TTI.getCFInstrCost(Instruction::Br, TargetTransformInfo::TCK_CodeSize);
+
+ unsigned DifferentBlocks = CurrentGroup.OutputGVNCombinations.size();
+ InstructionCost TotalCost = ComparisonCost * BranchCost * DifferentBlocks;
+
+ LLVM_DEBUG(dbgs() << "Adding: " << TotalCost
+ << " instructions for each switch case for each different"
+ << " output path in a function\n");
+ OutputCost += TotalCost;
+ }
+
+ return OutputCost;
+}
+
+void IROutliner::findCostBenefit(Module &M, OutlinableGroup &CurrentGroup) {
+ InstructionCost RegionBenefit = findBenefitFromAllRegions(CurrentGroup);
+ CurrentGroup.Benefit += RegionBenefit;
+ LLVM_DEBUG(dbgs() << "Current Benefit: " << CurrentGroup.Benefit << "\n");
+
+ InstructionCost OutputReloadCost = findCostOutputReloads(CurrentGroup);
+ CurrentGroup.Cost += OutputReloadCost;
+ LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
+
+ InstructionCost AverageRegionBenefit =
+ RegionBenefit / CurrentGroup.Regions.size();
+ unsigned OverallArgumentNum = CurrentGroup.ArgumentTypes.size();
+ unsigned NumRegions = CurrentGroup.Regions.size();
+ TargetTransformInfo &TTI =
+ getTTI(*CurrentGroup.Regions[0]->Candidate->getFunction());
+
+ // We add one region to the cost once, to account for the instructions added
+ // inside of the newly created function.
+ LLVM_DEBUG(dbgs() << "Adding: " << AverageRegionBenefit
+ << " instructions to cost for body of new function.\n");
+ CurrentGroup.Cost += AverageRegionBenefit;
+ LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
+
+ // For each argument, we must add an instruction for loading the argument
+ // out of the register and into a value inside of the newly outlined function.
+ LLVM_DEBUG(dbgs() << "Adding: " << OverallArgumentNum
+ << " instructions to cost for each argument in the new"
+ << " function.\n");
+ CurrentGroup.Cost +=
+ OverallArgumentNum * TargetTransformInfo::TCC_Basic;
+ LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
+
+ // Each argument needs to either be loaded into a register or onto the stack.
+ // Some arguments will only be loaded into the stack once the argument
+ // registers are filled.
+ LLVM_DEBUG(dbgs() << "Adding: " << OverallArgumentNum
+ << " instructions to cost for each argument in the new"
+ << " function " << NumRegions << " times for the "
+ << "needed argument handling at the call site.\n");
+ CurrentGroup.Cost +=
+ 2 * OverallArgumentNum * TargetTransformInfo::TCC_Basic * NumRegions;
+ LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
+
+ CurrentGroup.Cost += findCostForOutputBlocks(M, CurrentGroup, TTI);
+ LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
+}
+
+void IROutliner::updateOutputMapping(OutlinableRegion &Region,
+ ArrayRef<Value *> Outputs,
+ LoadInst *LI) {
+ // For and load instructions following the call
+ Value *Operand = LI->getPointerOperand();
+ Optional<unsigned> OutputIdx = None;
+ // Find if the operand it is an output register.
+ for (unsigned ArgIdx = Region.NumExtractedInputs;
+ ArgIdx < Region.Call->arg_size(); ArgIdx++) {
+ if (Operand == Region.Call->getArgOperand(ArgIdx)) {
+ OutputIdx = ArgIdx - Region.NumExtractedInputs;
+ break;
+ }
+ }
+
+ // If we found an output register, place a mapping of the new value
+ // to the original in the mapping.
+ if (!OutputIdx.hasValue())
+ return;
+
+ if (OutputMappings.find(Outputs[OutputIdx.getValue()]) ==
+ OutputMappings.end()) {
+ LLVM_DEBUG(dbgs() << "Mapping extracted output " << *LI << " to "
+ << *Outputs[OutputIdx.getValue()] << "\n");
+ OutputMappings.insert(std::make_pair(LI, Outputs[OutputIdx.getValue()]));
+ } else {
+ Value *Orig = OutputMappings.find(Outputs[OutputIdx.getValue()])->second;
+ LLVM_DEBUG(dbgs() << "Mapping extracted output " << *Orig << " to "
+ << *Outputs[OutputIdx.getValue()] << "\n");
+ OutputMappings.insert(std::make_pair(LI, Orig));
+ }
+}
+
+bool IROutliner::extractSection(OutlinableRegion &Region) {
+ SetVector<Value *> ArgInputs, Outputs, SinkCands;
+ Region.CE->findInputsOutputs(ArgInputs, Outputs, SinkCands);
+
+ assert(Region.StartBB && "StartBB for the OutlinableRegion is nullptr!");
+ assert(Region.FollowBB && "FollowBB for the OutlinableRegion is nullptr!");
+ Function *OrigF = Region.StartBB->getParent();
+ CodeExtractorAnalysisCache CEAC(*OrigF);
+ Region.ExtractedFunction = Region.CE->extractCodeRegion(CEAC);
+
+ // If the extraction was successful, find the BasicBlock, and reassign the
+ // OutlinableRegion blocks
+ if (!Region.ExtractedFunction) {
+ LLVM_DEBUG(dbgs() << "CodeExtractor failed to outline " << Region.StartBB
+ << "\n");
+ Region.reattachCandidate();
+ return false;
+ }
+
+ BasicBlock *RewrittenBB = Region.FollowBB->getSinglePredecessor();
+ Region.StartBB = RewrittenBB;
+ Region.EndBB = RewrittenBB;
+
+ // The sequences of outlinable regions has now changed. We must fix the
+ // IRInstructionDataList for consistency. Although they may not be illegal
+ // instructions, they should not be compared with anything else as they
+ // should not be outlined in this round. So marking these as illegal is
+ // allowed.
+ IRInstructionDataList *IDL = Region.Candidate->front()->IDL;
+ Instruction *BeginRewritten = &*RewrittenBB->begin();
+ Instruction *EndRewritten = &*RewrittenBB->begin();
+ Region.NewFront = new (InstDataAllocator.Allocate()) IRInstructionData(
+ *BeginRewritten, InstructionClassifier.visit(*BeginRewritten), *IDL);
+ Region.NewBack = new (InstDataAllocator.Allocate()) IRInstructionData(
+ *EndRewritten, InstructionClassifier.visit(*EndRewritten), *IDL);
+
+ // Insert the first IRInstructionData of the new region in front of the
+ // first IRInstructionData of the IRSimilarityCandidate.
+ IDL->insert(Region.Candidate->begin(), *Region.NewFront);
+ // Insert the first IRInstructionData of the new region after the
+ // last IRInstructionData of the IRSimilarityCandidate.
+ IDL->insert(Region.Candidate->end(), *Region.NewBack);
+ // Remove the IRInstructionData from the IRSimilarityCandidate.
+ IDL->erase(Region.Candidate->begin(), std::prev(Region.Candidate->end()));
+
+ assert(RewrittenBB != nullptr &&
+ "Could not find a predecessor after extraction!");
+
+ // Iterate over the new set of instructions to find the new call
+ // instruction.
+ for (Instruction &I : *RewrittenBB)
+ if (CallInst *CI = dyn_cast<CallInst>(&I)) {
+ if (Region.ExtractedFunction == CI->getCalledFunction())
+ Region.Call = CI;
+ } else if (LoadInst *LI = dyn_cast<LoadInst>(&I))
+ updateOutputMapping(Region, Outputs.getArrayRef(), LI);
+ Region.reattachCandidate();
+ return true;
+}
+
+unsigned IROutliner::doOutline(Module &M) {
+ // Find the possible similarity sections.
+ IRSimilarityIdentifier &Identifier = getIRSI(M);
+ SimilarityGroupList &SimilarityCandidates = *Identifier.getSimilarity();
+
+ // Sort them by size of extracted sections
+ unsigned OutlinedFunctionNum = 0;
+ // If we only have one SimilarityGroup in SimilarityCandidates, we do not have
+ // to sort them by the potential number of instructions to be outlined
+ if (SimilarityCandidates.size() > 1)
+ llvm::stable_sort(SimilarityCandidates,
+ [](const std::vector<IRSimilarityCandidate> &LHS,
+ const std::vector<IRSimilarityCandidate> &RHS) {
+ return LHS[0].getLength() * LHS.size() >
+ RHS[0].getLength() * RHS.size();
+ });
+
+ DenseSet<unsigned> NotSame;
+ std::vector<Function *> FuncsToRemove;
+ // Iterate over the possible sets of similarity.
+ for (SimilarityGroup &CandidateVec : SimilarityCandidates) {
+ OutlinableGroup CurrentGroup;
+
+ // Remove entries that were previously outlined
+ pruneIncompatibleRegions(CandidateVec, CurrentGroup);
+
+ // We pruned the number of regions to 0 to 1, meaning that it's not worth
+ // trying to outlined since there is no compatible similar instance of this
+ // code.
+ if (CurrentGroup.Regions.size() < 2)
+ continue;
+
+ // Determine if there are any values that are the same constant throughout
+ // each section in the set.
+ NotSame.clear();
+ CurrentGroup.findSameConstants(NotSame);
+
+ if (CurrentGroup.IgnoreGroup)
+ continue;
+
+ // Create a CodeExtractor for each outlinable region. Identify inputs and
+ // outputs for each section using the code extractor and create the argument
+ // types for the Aggregate Outlining Function.
+ std::vector<OutlinableRegion *> OutlinedRegions;
+ for (OutlinableRegion *OS : CurrentGroup.Regions) {
+ // Break the outlinable region out of its parent BasicBlock into its own
+ // BasicBlocks (see function implementation).
+ OS->splitCandidate();
+ std::vector<BasicBlock *> BE = {OS->StartBB};
+ OS->CE = new (ExtractorAllocator.Allocate())
+ CodeExtractor(BE, nullptr, false, nullptr, nullptr, nullptr, false,
+ false, "outlined");
+ findAddInputsOutputs(M, *OS, NotSame);
+ if (!OS->IgnoreRegion)
+ OutlinedRegions.push_back(OS);
+ else
+ OS->reattachCandidate();
+ }
+
+ CurrentGroup.Regions = std::move(OutlinedRegions);
+
+ if (CurrentGroup.Regions.empty())
+ continue;
+
+ CurrentGroup.collectGVNStoreSets(M);
+
+ if (CostModel)
+ findCostBenefit(M, CurrentGroup);
+
+ // If we are adhering to the cost model, reattach all the candidates
+ if (CurrentGroup.Cost >= CurrentGroup.Benefit && CostModel) {
+ for (OutlinableRegion *OS : CurrentGroup.Regions)
+ OS->reattachCandidate();
+ OptimizationRemarkEmitter &ORE = getORE(
+ *CurrentGroup.Regions[0]->Candidate->getFunction());
+ ORE.emit([&]() {
+ IRSimilarityCandidate *C = CurrentGroup.Regions[0]->Candidate;
+ OptimizationRemarkMissed R(DEBUG_TYPE, "WouldNotDecreaseSize",
+ C->frontInstruction());
+ R << "did not outline "
+ << ore::NV(std::to_string(CurrentGroup.Regions.size()))
+ << " regions due to estimated increase of "
+ << ore::NV("InstructionIncrease",
+ CurrentGroup.Cost - CurrentGroup.Benefit)
+ << " instructions at locations ";
+ interleave(
+ CurrentGroup.Regions.begin(), CurrentGroup.Regions.end(),
+ [&R](OutlinableRegion *Region) {
+ R << ore::NV(
+ "DebugLoc",
+ Region->Candidate->frontInstruction()->getDebugLoc());
+ },
+ [&R]() { R << " "; });
+ return R;
+ });
+ continue;
+ }
+
+ LLVM_DEBUG(dbgs() << "Outlining regions with cost " << CurrentGroup.Cost
+ << " and benefit " << CurrentGroup.Benefit << "\n");
+
+ // Create functions out of all the sections, and mark them as outlined.
+ OutlinedRegions.clear();
+ for (OutlinableRegion *OS : CurrentGroup.Regions) {
+ bool FunctionOutlined = extractSection(*OS);
+ if (FunctionOutlined) {
+ unsigned StartIdx = OS->Candidate->getStartIdx();
+ unsigned EndIdx = OS->Candidate->getEndIdx();
+ for (unsigned Idx = StartIdx; Idx <= EndIdx; Idx++)
+ Outlined.insert(Idx);
+
+ OutlinedRegions.push_back(OS);
+ }
+ }
+
+ LLVM_DEBUG(dbgs() << "Outlined " << OutlinedRegions.size()
+ << " with benefit " << CurrentGroup.Benefit
+ << " and cost " << CurrentGroup.Cost << "\n");
+
+ CurrentGroup.Regions = std::move(OutlinedRegions);
+
+ if (CurrentGroup.Regions.empty())
+ continue;
+
+ OptimizationRemarkEmitter &ORE =
+ getORE(*CurrentGroup.Regions[0]->Call->getFunction());
+ ORE.emit([&]() {
+ IRSimilarityCandidate *C = CurrentGroup.Regions[0]->Candidate;
+ OptimizationRemark R(DEBUG_TYPE, "Outlined", C->front()->Inst);
+ R << "outlined " << ore::NV(std::to_string(CurrentGroup.Regions.size()))
+ << " regions with decrease of "
+ << ore::NV("Benefit", CurrentGroup.Benefit - CurrentGroup.Cost)
+ << " instructions at locations ";
+ interleave(
+ CurrentGroup.Regions.begin(), CurrentGroup.Regions.end(),
+ [&R](OutlinableRegion *Region) {
+ R << ore::NV("DebugLoc",
+ Region->Candidate->frontInstruction()->getDebugLoc());
+ },
+ [&R]() { R << " "; });
+ return R;
+ });
+
+ deduplicateExtractedSections(M, CurrentGroup, FuncsToRemove,
+ OutlinedFunctionNum);
+ }
+
+ for (Function *F : FuncsToRemove)
+ F->eraseFromParent();
+
+ return OutlinedFunctionNum;
+}
+
+bool IROutliner::run(Module &M) {
+ CostModel = !NoCostModel;
+ OutlineFromLinkODRs = EnableLinkOnceODRIROutlining;
+
+ return doOutline(M) > 0;
+}
+
+// Pass Manager Boilerplate
+class IROutlinerLegacyPass : public ModulePass {
+public:
+ static char ID;
+ IROutlinerLegacyPass() : ModulePass(ID) {
+ initializeIROutlinerLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
+ AU.addRequired<TargetTransformInfoWrapperPass>();
+ AU.addRequired<IRSimilarityIdentifierWrapperPass>();
+ }
+
+ bool runOnModule(Module &M) override;
+};
+
+bool IROutlinerLegacyPass::runOnModule(Module &M) {
+ if (skipModule(M))
+ return false;
+
+ std::unique_ptr<OptimizationRemarkEmitter> ORE;
+ auto GORE = [&ORE](Function &F) -> OptimizationRemarkEmitter & {
+ ORE.reset(new OptimizationRemarkEmitter(&F));
+ return *ORE.get();
+ };
+
+ auto GTTI = [this](Function &F) -> TargetTransformInfo & {
+ return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
+ };
+
+ auto GIRSI = [this](Module &) -> IRSimilarityIdentifier & {
+ return this->getAnalysis<IRSimilarityIdentifierWrapperPass>().getIRSI();
+ };
+
+ return IROutliner(GTTI, GIRSI, GORE).run(M);
+}
+
+PreservedAnalyses IROutlinerPass::run(Module &M, ModuleAnalysisManager &AM) {
+ auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+
+ std::function<TargetTransformInfo &(Function &)> GTTI =
+ [&FAM](Function &F) -> TargetTransformInfo & {
+ return FAM.getResult<TargetIRAnalysis>(F);
+ };
+
+ std::function<IRSimilarityIdentifier &(Module &)> GIRSI =
+ [&AM](Module &M) -> IRSimilarityIdentifier & {
+ return AM.getResult<IRSimilarityAnalysis>(M);
+ };
+
+ std::unique_ptr<OptimizationRemarkEmitter> ORE;
+ std::function<OptimizationRemarkEmitter &(Function &)> GORE =
+ [&ORE](Function &F) -> OptimizationRemarkEmitter & {
+ ORE.reset(new OptimizationRemarkEmitter(&F));
+ return *ORE.get();
+ };
+
+ if (IROutliner(GTTI, GIRSI, GORE).run(M))
+ return PreservedAnalyses::none();
+ return PreservedAnalyses::all();
+}
+
+char IROutlinerLegacyPass::ID = 0;
+INITIALIZE_PASS_BEGIN(IROutlinerLegacyPass, "iroutliner", "IR Outliner", false,
+ false)
+INITIALIZE_PASS_DEPENDENCY(IRSimilarityIdentifierWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
+INITIALIZE_PASS_END(IROutlinerLegacyPass, "iroutliner", "IR Outliner", false,
+ false)
+
+ModulePass *llvm::createIROutlinerPass() { return new IROutlinerLegacyPass(); }
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/Inliner.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/Inliner.cpp
index 7dfc611b74..e91b6c9b1d 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/Inliner.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/Inliner.cpp
@@ -36,7 +36,7 @@
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h"
+#include "llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DataLayout.h"
@@ -90,14 +90,14 @@ static cl::opt<bool>
DisableInlinedAllocaMerging("disable-inlined-alloca-merging",
cl::init(false), cl::Hidden);
-extern cl::opt<InlinerFunctionImportStatsOpts> InlinerFunctionImportStats;
+extern cl::opt<InlinerFunctionImportStatsOpts> InlinerFunctionImportStats;
-static cl::opt<std::string> CGSCCInlineReplayFile(
- "cgscc-inline-replay", cl::init(""), cl::value_desc("filename"),
- cl::desc(
- "Optimization remarks file containing inline remarks to be replayed "
- "by inlining from cgscc inline remarks."),
- cl::Hidden);
+static cl::opt<std::string> CGSCCInlineReplayFile(
+ "cgscc-inline-replay", cl::init(""), cl::value_desc("filename"),
+ cl::desc(
+ "Optimization remarks file containing inline remarks to be replayed "
+ "by inlining from cgscc inline remarks."),
+ cl::Hidden);
LegacyInlinerBase::LegacyInlinerBase(char &ID) : CallGraphSCCPass(ID) {}
@@ -640,9 +640,9 @@ bool LegacyInlinerBase::removeDeadFunctions(CallGraph &CG,
InlineAdvisor &
InlinerPass::getAdvisor(const ModuleAnalysisManagerCGSCCProxy::Result &MAM,
FunctionAnalysisManager &FAM, Module &M) {
- if (OwnedAdvisor)
- return *OwnedAdvisor;
-
+ if (OwnedAdvisor)
+ return *OwnedAdvisor;
+
auto *IAA = MAM.getCachedResult<InlineAdvisorAnalysis>(M);
if (!IAA) {
// It should still be possible to run the inliner as a stand-alone SCC pass,
@@ -653,16 +653,16 @@ InlinerPass::getAdvisor(const ModuleAnalysisManagerCGSCCProxy::Result &MAM,
// duration of the inliner pass, and thus the lifetime of the owned advisor.
// The one we would get from the MAM can be invalidated as a result of the
// inliner's activity.
- OwnedAdvisor =
- std::make_unique<DefaultInlineAdvisor>(M, FAM, getInlineParams());
-
- if (!CGSCCInlineReplayFile.empty())
- OwnedAdvisor = std::make_unique<ReplayInlineAdvisor>(
- M, FAM, M.getContext(), std::move(OwnedAdvisor),
- CGSCCInlineReplayFile,
- /*EmitRemarks=*/true);
-
- return *OwnedAdvisor;
+ OwnedAdvisor =
+ std::make_unique<DefaultInlineAdvisor>(M, FAM, getInlineParams());
+
+ if (!CGSCCInlineReplayFile.empty())
+ OwnedAdvisor = std::make_unique<ReplayInlineAdvisor>(
+ M, FAM, M.getContext(), std::move(OwnedAdvisor),
+ CGSCCInlineReplayFile,
+ /*EmitRemarks=*/true);
+
+ return *OwnedAdvisor;
}
assert(IAA->getAdvisor() &&
"Expected a present InlineAdvisorAnalysis also have an "
@@ -696,7 +696,7 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
//
// Note that this particular order of processing is actually critical to
// avoid very bad behaviors. Consider *highly connected* call graphs where
- // each function contains a small amount of code and a couple of calls to
+ // each function contains a small amount of code and a couple of calls to
// other functions. Because the LLVM inliner is fundamentally a bottom-up
// inliner, it can handle gracefully the fact that these all appear to be
// reasonable inlining candidates as it will flatten things until they become
@@ -746,7 +746,7 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
if (Calls.empty())
return PreservedAnalyses::all();
- // Capture updatable variable for the current SCC.
+ // Capture updatable variable for the current SCC.
auto *C = &InitialC;
// When inlining a callee produces new call sites, we want to keep track of
@@ -812,7 +812,7 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
continue;
}
- auto Advice = Advisor.getAdvice(*CB, OnlyMandatory);
+ auto Advice = Advisor.getAdvice(*CB, OnlyMandatory);
// Check whether we want to inline this callsite.
if (!Advice->isInliningRecommended()) {
Advice->recordUnattemptedInlining();
@@ -826,8 +826,8 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
&FAM.getResult<BlockFrequencyAnalysis>(*(CB->getCaller())),
&FAM.getResult<BlockFrequencyAnalysis>(Callee));
- InlineResult IR =
- InlineFunction(*CB, IFI, &FAM.getResult<AAManager>(*CB->getCaller()));
+ InlineResult IR =
+ InlineFunction(*CB, IFI, &FAM.getResult<AAManager>(*CB->getCaller()));
if (!IR.isSuccess()) {
Advice->recordUnsuccessfulInlining(IR);
continue;
@@ -882,7 +882,7 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
// Note that after this point, it is an error to do anything other
// than use the callee's address or delete it.
Callee.dropAllReferences();
- assert(!is_contained(DeadFunctions, &Callee) &&
+ assert(!is_contained(DeadFunctions, &Callee) &&
"Cannot put cause a function to become dead twice!");
DeadFunctions.push_back(&Callee);
CalleeWasDeleted = true;
@@ -914,7 +914,7 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
// as we're going to mutate this particular function we want to make sure
// the proxy is in place to forward any invalidation events.
LazyCallGraph::SCC *OldC = C;
- C = &updateCGAndAnalysisManagerForCGSCCPass(CG, *C, N, AM, UR, FAM);
+ C = &updateCGAndAnalysisManagerForCGSCCPass(CG, *C, N, AM, UR, FAM);
LLVM_DEBUG(dbgs() << "Updated inlining SCC: " << *C << "\n");
// If this causes an SCC to split apart into multiple smaller SCCs, there
@@ -994,7 +994,7 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
ModuleInlinerWrapperPass::ModuleInlinerWrapperPass(InlineParams Params,
bool Debugging,
- bool MandatoryFirst,
+ bool MandatoryFirst,
InliningAdvisorMode Mode,
unsigned MaxDevirtIterations)
: Params(Params), Mode(Mode), MaxDevirtIterations(MaxDevirtIterations),
@@ -1004,15 +1004,15 @@ ModuleInlinerWrapperPass::ModuleInlinerWrapperPass(InlineParams Params,
// into the callers so that our optimizations can reflect that.
// For PreLinkThinLTO pass, we disable hot-caller heuristic for sample PGO
// because it makes profile annotation in the backend inaccurate.
- if (MandatoryFirst)
- PM.addPass(InlinerPass(/*OnlyMandatory*/ true));
+ if (MandatoryFirst)
+ PM.addPass(InlinerPass(/*OnlyMandatory*/ true));
PM.addPass(InlinerPass());
}
PreservedAnalyses ModuleInlinerWrapperPass::run(Module &M,
ModuleAnalysisManager &MAM) {
auto &IAA = MAM.getResult<InlineAdvisorAnalysis>(M);
- if (!IAA.tryCreate(Params, Mode, CGSCCInlineReplayFile)) {
+ if (!IAA.tryCreate(Params, Mode, CGSCCInlineReplayFile)) {
M.getContext().emitError(
"Could not setup Inlining Advisor for the requested "
"mode and/or options");
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/LoopExtractor.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/LoopExtractor.cpp
index cbbc5f8882..a497c0390b 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/LoopExtractor.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/LoopExtractor.cpp
@@ -13,14 +13,14 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/IPO/LoopExtractor.h"
+#include "llvm/Transforms/IPO/LoopExtractor.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
@@ -38,71 +38,71 @@ using namespace llvm;
STATISTIC(NumExtracted, "Number of loops extracted");
namespace {
-struct LoopExtractorLegacyPass : public ModulePass {
- static char ID; // Pass identification, replacement for typeid
-
- unsigned NumLoops;
-
- explicit LoopExtractorLegacyPass(unsigned NumLoops = ~0)
- : ModulePass(ID), NumLoops(NumLoops) {
- initializeLoopExtractorLegacyPassPass(*PassRegistry::getPassRegistry());
- }
-
- bool runOnModule(Module &M) override;
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequiredID(BreakCriticalEdgesID);
- AU.addRequired<DominatorTreeWrapperPass>();
- AU.addRequired<LoopInfoWrapperPass>();
- AU.addPreserved<LoopInfoWrapperPass>();
- AU.addRequiredID(LoopSimplifyID);
- AU.addUsedIfAvailable<AssumptionCacheTracker>();
- }
-};
-
-struct LoopExtractor {
- explicit LoopExtractor(
- unsigned NumLoops,
- function_ref<DominatorTree &(Function &)> LookupDomTree,
- function_ref<LoopInfo &(Function &)> LookupLoopInfo,
- function_ref<AssumptionCache *(Function &)> LookupAssumptionCache)
- : NumLoops(NumLoops), LookupDomTree(LookupDomTree),
- LookupLoopInfo(LookupLoopInfo),
- LookupAssumptionCache(LookupAssumptionCache) {}
- bool runOnModule(Module &M);
-
-private:
- // The number of natural loops to extract from the program into functions.
- unsigned NumLoops;
-
- function_ref<DominatorTree &(Function &)> LookupDomTree;
- function_ref<LoopInfo &(Function &)> LookupLoopInfo;
- function_ref<AssumptionCache *(Function &)> LookupAssumptionCache;
-
- bool runOnFunction(Function &F);
-
- bool extractLoops(Loop::iterator From, Loop::iterator To, LoopInfo &LI,
- DominatorTree &DT);
- bool extractLoop(Loop *L, LoopInfo &LI, DominatorTree &DT);
-};
-} // namespace
-
-char LoopExtractorLegacyPass::ID = 0;
-INITIALIZE_PASS_BEGIN(LoopExtractorLegacyPass, "loop-extract",
+struct LoopExtractorLegacyPass : public ModulePass {
+ static char ID; // Pass identification, replacement for typeid
+
+ unsigned NumLoops;
+
+ explicit LoopExtractorLegacyPass(unsigned NumLoops = ~0)
+ : ModulePass(ID), NumLoops(NumLoops) {
+ initializeLoopExtractorLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool runOnModule(Module &M) override;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequiredID(BreakCriticalEdgesID);
+ AU.addRequired<DominatorTreeWrapperPass>();
+ AU.addRequired<LoopInfoWrapperPass>();
+ AU.addPreserved<LoopInfoWrapperPass>();
+ AU.addRequiredID(LoopSimplifyID);
+ AU.addUsedIfAvailable<AssumptionCacheTracker>();
+ }
+};
+
+struct LoopExtractor {
+ explicit LoopExtractor(
+ unsigned NumLoops,
+ function_ref<DominatorTree &(Function &)> LookupDomTree,
+ function_ref<LoopInfo &(Function &)> LookupLoopInfo,
+ function_ref<AssumptionCache *(Function &)> LookupAssumptionCache)
+ : NumLoops(NumLoops), LookupDomTree(LookupDomTree),
+ LookupLoopInfo(LookupLoopInfo),
+ LookupAssumptionCache(LookupAssumptionCache) {}
+ bool runOnModule(Module &M);
+
+private:
+ // The number of natural loops to extract from the program into functions.
+ unsigned NumLoops;
+
+ function_ref<DominatorTree &(Function &)> LookupDomTree;
+ function_ref<LoopInfo &(Function &)> LookupLoopInfo;
+ function_ref<AssumptionCache *(Function &)> LookupAssumptionCache;
+
+ bool runOnFunction(Function &F);
+
+ bool extractLoops(Loop::iterator From, Loop::iterator To, LoopInfo &LI,
+ DominatorTree &DT);
+ bool extractLoop(Loop *L, LoopInfo &LI, DominatorTree &DT);
+};
+} // namespace
+
+char LoopExtractorLegacyPass::ID = 0;
+INITIALIZE_PASS_BEGIN(LoopExtractorLegacyPass, "loop-extract",
"Extract loops into new functions", false, false)
INITIALIZE_PASS_DEPENDENCY(BreakCriticalEdges)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
-INITIALIZE_PASS_END(LoopExtractorLegacyPass, "loop-extract",
+INITIALIZE_PASS_END(LoopExtractorLegacyPass, "loop-extract",
"Extract loops into new functions", false, false)
namespace {
/// SingleLoopExtractor - For bugpoint.
-struct SingleLoopExtractor : public LoopExtractorLegacyPass {
- static char ID; // Pass identification, replacement for typeid
- SingleLoopExtractor() : LoopExtractorLegacyPass(1) {}
-};
+struct SingleLoopExtractor : public LoopExtractorLegacyPass {
+ static char ID; // Pass identification, replacement for typeid
+ SingleLoopExtractor() : LoopExtractorLegacyPass(1) {}
+};
} // End anonymous namespace
char SingleLoopExtractor::ID = 0;
@@ -112,30 +112,30 @@ INITIALIZE_PASS(SingleLoopExtractor, "loop-extract-single",
// createLoopExtractorPass - This pass extracts all natural loops from the
// program into a function if it can.
//
-Pass *llvm::createLoopExtractorPass() { return new LoopExtractorLegacyPass(); }
+Pass *llvm::createLoopExtractorPass() { return new LoopExtractorLegacyPass(); }
-bool LoopExtractorLegacyPass::runOnModule(Module &M) {
+bool LoopExtractorLegacyPass::runOnModule(Module &M) {
if (skipModule(M))
return false;
- bool Changed = false;
- auto LookupDomTree = [this](Function &F) -> DominatorTree & {
- return this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
- };
- auto LookupLoopInfo = [this, &Changed](Function &F) -> LoopInfo & {
- return this->getAnalysis<LoopInfoWrapperPass>(F, &Changed).getLoopInfo();
- };
- auto LookupACT = [this](Function &F) -> AssumptionCache * {
- if (auto *ACT = this->getAnalysisIfAvailable<AssumptionCacheTracker>())
- return ACT->lookupAssumptionCache(F);
- return nullptr;
- };
- return LoopExtractor(NumLoops, LookupDomTree, LookupLoopInfo, LookupACT)
- .runOnModule(M) ||
- Changed;
-}
-
-bool LoopExtractor::runOnModule(Module &M) {
+ bool Changed = false;
+ auto LookupDomTree = [this](Function &F) -> DominatorTree & {
+ return this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
+ };
+ auto LookupLoopInfo = [this, &Changed](Function &F) -> LoopInfo & {
+ return this->getAnalysis<LoopInfoWrapperPass>(F, &Changed).getLoopInfo();
+ };
+ auto LookupACT = [this](Function &F) -> AssumptionCache * {
+ if (auto *ACT = this->getAnalysisIfAvailable<AssumptionCacheTracker>())
+ return ACT->lookupAssumptionCache(F);
+ return nullptr;
+ };
+ return LoopExtractor(NumLoops, LookupDomTree, LookupLoopInfo, LookupACT)
+ .runOnModule(M) ||
+ Changed;
+}
+
+bool LoopExtractor::runOnModule(Module &M) {
if (M.empty())
return false;
@@ -172,13 +172,13 @@ bool LoopExtractor::runOnFunction(Function &F) {
return false;
bool Changed = false;
- LoopInfo &LI = LookupLoopInfo(F);
+ LoopInfo &LI = LookupLoopInfo(F);
// If there are no loops in the function.
if (LI.empty())
return Changed;
- DominatorTree &DT = LookupDomTree(F);
+ DominatorTree &DT = LookupDomTree(F);
// If there is more than one top-level loop in this function, extract all of
// the loops.
@@ -244,7 +244,7 @@ bool LoopExtractor::extractLoops(Loop::iterator From, Loop::iterator To,
bool LoopExtractor::extractLoop(Loop *L, LoopInfo &LI, DominatorTree &DT) {
assert(NumLoops != 0);
Function &Func = *L->getHeader()->getParent();
- AssumptionCache *AC = LookupAssumptionCache(Func);
+ AssumptionCache *AC = LookupAssumptionCache(Func);
CodeExtractorAnalysisCache CEAC(Func);
CodeExtractor Extractor(DT, *L, false, nullptr, nullptr, AC);
if (Extractor.extractCodeRegion(CEAC)) {
@@ -262,24 +262,24 @@ bool LoopExtractor::extractLoop(Loop *L, LoopInfo &LI, DominatorTree &DT) {
Pass *llvm::createSingleLoopExtractorPass() {
return new SingleLoopExtractor();
}
-
-PreservedAnalyses LoopExtractorPass::run(Module &M, ModuleAnalysisManager &AM) {
- auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
- auto LookupDomTree = [&FAM](Function &F) -> DominatorTree & {
- return FAM.getResult<DominatorTreeAnalysis>(F);
- };
- auto LookupLoopInfo = [&FAM](Function &F) -> LoopInfo & {
- return FAM.getResult<LoopAnalysis>(F);
- };
- auto LookupAssumptionCache = [&FAM](Function &F) -> AssumptionCache * {
- return FAM.getCachedResult<AssumptionAnalysis>(F);
- };
- if (!LoopExtractor(NumLoops, LookupDomTree, LookupLoopInfo,
- LookupAssumptionCache)
- .runOnModule(M))
- return PreservedAnalyses::all();
-
- PreservedAnalyses PA;
- PA.preserve<LoopAnalysis>();
- return PA;
-}
+
+PreservedAnalyses LoopExtractorPass::run(Module &M, ModuleAnalysisManager &AM) {
+ auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+ auto LookupDomTree = [&FAM](Function &F) -> DominatorTree & {
+ return FAM.getResult<DominatorTreeAnalysis>(F);
+ };
+ auto LookupLoopInfo = [&FAM](Function &F) -> LoopInfo & {
+ return FAM.getResult<LoopAnalysis>(F);
+ };
+ auto LookupAssumptionCache = [&FAM](Function &F) -> AssumptionCache * {
+ return FAM.getCachedResult<AssumptionAnalysis>(F);
+ };
+ if (!LoopExtractor(NumLoops, LookupDomTree, LookupLoopInfo,
+ LookupAssumptionCache)
+ .runOnModule(M))
+ return PreservedAnalyses::all();
+
+ PreservedAnalyses PA;
+ PA.preserve<LoopAnalysis>();
+ return PA;
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/LowerTypeTests.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/LowerTypeTests.cpp
index 33e232b0b9..8bd3036f1f 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/LowerTypeTests.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -198,7 +198,7 @@ void GlobalLayoutBuilder::addFragment(const std::set<uint64_t> &F) {
// indices from the old fragment in this fragment do not insert any more
// indices.
std::vector<uint64_t> &OldFragment = Fragments[OldFragmentIndex];
- llvm::append_range(Fragment, OldFragment);
+ llvm::append_range(Fragment, OldFragment);
OldFragment.clear();
}
}
@@ -1205,7 +1205,7 @@ void LowerTypeTestsModule::verifyTypeMDNode(GlobalObject *GO, MDNode *Type) {
static const unsigned kX86JumpTableEntrySize = 8;
static const unsigned kARMJumpTableEntrySize = 4;
-static const unsigned kARMBTIJumpTableEntrySize = 8;
+static const unsigned kARMBTIJumpTableEntrySize = 8;
unsigned LowerTypeTestsModule::getJumpTableEntrySize() {
switch (Arch) {
@@ -1214,12 +1214,12 @@ unsigned LowerTypeTestsModule::getJumpTableEntrySize() {
return kX86JumpTableEntrySize;
case Triple::arm:
case Triple::thumb:
- return kARMJumpTableEntrySize;
+ return kARMJumpTableEntrySize;
case Triple::aarch64:
- if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
- M.getModuleFlag("branch-target-enforcement")))
- if (BTE->getZExtValue())
- return kARMBTIJumpTableEntrySize;
+ if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
+ M.getModuleFlag("branch-target-enforcement")))
+ if (BTE->getZExtValue())
+ return kARMBTIJumpTableEntrySize;
return kARMJumpTableEntrySize;
default:
report_fatal_error("Unsupported architecture for jump tables");
@@ -1238,14 +1238,14 @@ void LowerTypeTestsModule::createJumpTableEntry(
if (JumpTableArch == Triple::x86 || JumpTableArch == Triple::x86_64) {
AsmOS << "jmp ${" << ArgIndex << ":c}@plt\n";
AsmOS << "int3\nint3\nint3\n";
- } else if (JumpTableArch == Triple::arm) {
+ } else if (JumpTableArch == Triple::arm) {
+ AsmOS << "b $" << ArgIndex << "\n";
+ } else if (JumpTableArch == Triple::aarch64) {
+ if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
+ Dest->getParent()->getModuleFlag("branch-target-enforcement")))
+ if (BTE->getZExtValue())
+ AsmOS << "bti c\n";
AsmOS << "b $" << ArgIndex << "\n";
- } else if (JumpTableArch == Triple::aarch64) {
- if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
- Dest->getParent()->getModuleFlag("branch-target-enforcement")))
- if (BTE->getZExtValue())
- AsmOS << "bti c\n";
- AsmOS << "b $" << ArgIndex << "\n";
} else if (JumpTableArch == Triple::thumb) {
AsmOS << "b.w $" << ArgIndex << "\n";
} else {
@@ -1338,7 +1338,7 @@ void LowerTypeTestsModule::replaceWeakDeclarationWithJumpTablePtr(
static bool isThumbFunction(Function *F, Triple::ArchType ModuleArch) {
Attribute TFAttr = F->getFnAttribute("target-features");
- if (TFAttr.isValid()) {
+ if (TFAttr.isValid()) {
SmallVector<StringRef, 6> Features;
TFAttr.getValueAsString().split(Features, ',');
for (StringRef Feature : Features) {
@@ -1406,10 +1406,10 @@ void LowerTypeTestsModule::createJumpTable(
// by Clang for -march=armv7.
F->addFnAttr("target-cpu", "cortex-a8");
}
- if (JumpTableArch == Triple::aarch64) {
- F->addFnAttr("branch-target-enforcement", "false");
- F->addFnAttr("sign-return-address", "none");
- }
+ if (JumpTableArch == Triple::aarch64) {
+ F->addFnAttr("branch-target-enforcement", "false");
+ F->addFnAttr("sign-return-address", "none");
+ }
// Make sure we don't emit .eh_frame for this function.
F->addFnAttr(Attribute::NoUnwind);
@@ -2255,13 +2255,13 @@ bool LowerTypeTestsModule::lower() {
PreservedAnalyses LowerTypeTestsPass::run(Module &M,
ModuleAnalysisManager &AM) {
- bool Changed;
- if (UseCommandLine)
- Changed = LowerTypeTestsModule::runForTesting(M);
- else
- Changed =
- LowerTypeTestsModule(M, ExportSummary, ImportSummary, DropTypeTests)
- .lower();
+ bool Changed;
+ if (UseCommandLine)
+ Changed = LowerTypeTestsModule::runForTesting(M);
+ else
+ Changed =
+ LowerTypeTestsModule(M, ExportSummary, ImportSummary, DropTypeTests)
+ .lower();
if (!Changed)
return PreservedAnalyses::all();
return PreservedAnalyses::none();
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/MergeFunctions.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/MergeFunctions.cpp
index aa4de3d122..ec5d86b72a 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/MergeFunctions.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/MergeFunctions.cpp
@@ -725,10 +725,10 @@ void MergeFunctions::writeThunk(Function *F, Function *G) {
if (MergeFunctionsPDI) {
DISubprogram *DIS = G->getSubprogram();
if (DIS) {
- DebugLoc CIDbgLoc =
- DILocation::get(DIS->getContext(), DIS->getScopeLine(), 0, DIS);
- DebugLoc RIDbgLoc =
- DILocation::get(DIS->getContext(), DIS->getScopeLine(), 0, DIS);
+ DebugLoc CIDbgLoc =
+ DILocation::get(DIS->getContext(), DIS->getScopeLine(), 0, DIS);
+ DebugLoc RIDbgLoc =
+ DILocation::get(DIS->getContext(), DIS->getScopeLine(), 0, DIS);
CI->setDebugLoc(CIDbgLoc);
RI->setDebugLoc(RIDbgLoc);
} else {
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/OpenMPOpt.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/OpenMPOpt.cpp
index bc15d5e0c0..a5ba6edb9a 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/OpenMPOpt.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/OpenMPOpt.cpp
@@ -19,16 +19,16 @@
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
-#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/Attributor.h"
-#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/CallGraphUpdater.h"
-#include "llvm/Transforms/Utils/CodeExtractor.h"
+#include "llvm/Transforms/Utils/CodeExtractor.h"
using namespace llvm;
using namespace omp;
@@ -40,22 +40,22 @@ static cl::opt<bool> DisableOpenMPOptimizations(
cl::desc("Disable OpenMP specific optimizations."), cl::Hidden,
cl::init(false));
-static cl::opt<bool> EnableParallelRegionMerging(
- "openmp-opt-enable-merging", cl::ZeroOrMore,
- cl::desc("Enable the OpenMP region merging optimization."), cl::Hidden,
- cl::init(false));
-
+static cl::opt<bool> EnableParallelRegionMerging(
+ "openmp-opt-enable-merging", cl::ZeroOrMore,
+ cl::desc("Enable the OpenMP region merging optimization."), cl::Hidden,
+ cl::init(false));
+
static cl::opt<bool> PrintICVValues("openmp-print-icv-values", cl::init(false),
cl::Hidden);
static cl::opt<bool> PrintOpenMPKernels("openmp-print-gpu-kernels",
cl::init(false), cl::Hidden);
-static cl::opt<bool> HideMemoryTransferLatency(
- "openmp-hide-memory-transfer-latency",
- cl::desc("[WIP] Tries to hide the latency of host to device memory"
- " transfers"),
- cl::Hidden, cl::init(false));
-
+static cl::opt<bool> HideMemoryTransferLatency(
+ "openmp-hide-memory-transfer-latency",
+ cl::desc("[WIP] Tries to hide the latency of host to device memory"
+ " transfers"),
+ cl::Hidden, cl::init(false));
+
STATISTIC(NumOpenMPRuntimeCallsDeduplicated,
"Number of OpenMP runtime calls deduplicated");
STATISTIC(NumOpenMPParallelRegionsDeleted,
@@ -69,8 +69,8 @@ STATISTIC(NumOpenMPTargetRegionKernels,
STATISTIC(
NumOpenMPParallelRegionsReplacedInGPUStateMachine,
"Number of OpenMP parallel regions replaced with ID in GPU state machines");
-STATISTIC(NumOpenMPParallelRegionsMerged,
- "Number of OpenMP parallel regions merged");
+STATISTIC(NumOpenMPParallelRegionsMerged,
+ "Number of OpenMP parallel regions merged");
#if !defined(NDEBUG)
static constexpr auto TAG = "[" DEBUG_TYPE "]";
@@ -318,17 +318,17 @@ struct OMPInformationCache : public InformationCache {
return NumUses;
}
- // Helper function to recollect uses of a runtime function.
- void recollectUsesForFunction(RuntimeFunction RTF) {
- auto &RFI = RFIs[RTF];
- RFI.clearUsesMap();
- collectUses(RFI, /*CollectStats*/ false);
- }
-
+ // Helper function to recollect uses of a runtime function.
+ void recollectUsesForFunction(RuntimeFunction RTF) {
+ auto &RFI = RFIs[RTF];
+ RFI.clearUsesMap();
+ collectUses(RFI, /*CollectStats*/ false);
+ }
+
// Helper function to recollect uses of all runtime functions.
void recollectUses() {
- for (int Idx = 0; Idx < RFIs.size(); ++Idx)
- recollectUsesForFunction(static_cast<RuntimeFunction>(Idx));
+ for (int Idx = 0; Idx < RFIs.size(); ++Idx)
+ recollectUsesForFunction(static_cast<RuntimeFunction>(Idx));
}
/// Helper to initialize all runtime function information for those defined
@@ -392,91 +392,91 @@ struct OMPInformationCache : public InformationCache {
SmallPtrSetImpl<Kernel> &Kernels;
};
-/// Used to map the values physically (in the IR) stored in an offload
-/// array, to a vector in memory.
-struct OffloadArray {
- /// Physical array (in the IR).
- AllocaInst *Array = nullptr;
- /// Mapped values.
- SmallVector<Value *, 8> StoredValues;
- /// Last stores made in the offload array.
- SmallVector<StoreInst *, 8> LastAccesses;
-
- OffloadArray() = default;
-
- /// Initializes the OffloadArray with the values stored in \p Array before
- /// instruction \p Before is reached. Returns false if the initialization
- /// fails.
- /// This MUST be used immediately after the construction of the object.
- bool initialize(AllocaInst &Array, Instruction &Before) {
- if (!Array.getAllocatedType()->isArrayTy())
- return false;
-
- if (!getValues(Array, Before))
- return false;
-
- this->Array = &Array;
- return true;
- }
-
- static const unsigned DeviceIDArgNum = 1;
- static const unsigned BasePtrsArgNum = 3;
- static const unsigned PtrsArgNum = 4;
- static const unsigned SizesArgNum = 5;
-
-private:
- /// Traverses the BasicBlock where \p Array is, collecting the stores made to
- /// \p Array, leaving StoredValues with the values stored before the
- /// instruction \p Before is reached.
- bool getValues(AllocaInst &Array, Instruction &Before) {
- // Initialize container.
- const uint64_t NumValues = Array.getAllocatedType()->getArrayNumElements();
- StoredValues.assign(NumValues, nullptr);
- LastAccesses.assign(NumValues, nullptr);
-
- // TODO: This assumes the instruction \p Before is in the same
- // BasicBlock as Array. Make it general, for any control flow graph.
- BasicBlock *BB = Array.getParent();
- if (BB != Before.getParent())
- return false;
-
- const DataLayout &DL = Array.getModule()->getDataLayout();
- const unsigned int PointerSize = DL.getPointerSize();
-
- for (Instruction &I : *BB) {
- if (&I == &Before)
- break;
-
- if (!isa<StoreInst>(&I))
- continue;
-
- auto *S = cast<StoreInst>(&I);
- int64_t Offset = -1;
- auto *Dst =
- GetPointerBaseWithConstantOffset(S->getPointerOperand(), Offset, DL);
- if (Dst == &Array) {
- int64_t Idx = Offset / PointerSize;
- StoredValues[Idx] = getUnderlyingObject(S->getValueOperand());
- LastAccesses[Idx] = S;
- }
- }
-
- return isFilled();
- }
-
- /// Returns true if all values in StoredValues and
- /// LastAccesses are not nullptrs.
- bool isFilled() {
- const unsigned NumValues = StoredValues.size();
- for (unsigned I = 0; I < NumValues; ++I) {
- if (!StoredValues[I] || !LastAccesses[I])
- return false;
- }
-
- return true;
- }
-};
-
+/// Used to map the values physically (in the IR) stored in an offload
+/// array, to a vector in memory.
+struct OffloadArray {
+ /// Physical array (in the IR).
+ AllocaInst *Array = nullptr;
+ /// Mapped values.
+ SmallVector<Value *, 8> StoredValues;
+ /// Last stores made in the offload array.
+ SmallVector<StoreInst *, 8> LastAccesses;
+
+ OffloadArray() = default;
+
+ /// Initializes the OffloadArray with the values stored in \p Array before
+ /// instruction \p Before is reached. Returns false if the initialization
+ /// fails.
+ /// This MUST be used immediately after the construction of the object.
+ bool initialize(AllocaInst &Array, Instruction &Before) {
+ if (!Array.getAllocatedType()->isArrayTy())
+ return false;
+
+ if (!getValues(Array, Before))
+ return false;
+
+ this->Array = &Array;
+ return true;
+ }
+
+ static const unsigned DeviceIDArgNum = 1;
+ static const unsigned BasePtrsArgNum = 3;
+ static const unsigned PtrsArgNum = 4;
+ static const unsigned SizesArgNum = 5;
+
+private:
+ /// Traverses the BasicBlock where \p Array is, collecting the stores made to
+ /// \p Array, leaving StoredValues with the values stored before the
+ /// instruction \p Before is reached.
+ bool getValues(AllocaInst &Array, Instruction &Before) {
+ // Initialize container.
+ const uint64_t NumValues = Array.getAllocatedType()->getArrayNumElements();
+ StoredValues.assign(NumValues, nullptr);
+ LastAccesses.assign(NumValues, nullptr);
+
+ // TODO: This assumes the instruction \p Before is in the same
+ // BasicBlock as Array. Make it general, for any control flow graph.
+ BasicBlock *BB = Array.getParent();
+ if (BB != Before.getParent())
+ return false;
+
+ const DataLayout &DL = Array.getModule()->getDataLayout();
+ const unsigned int PointerSize = DL.getPointerSize();
+
+ for (Instruction &I : *BB) {
+ if (&I == &Before)
+ break;
+
+ if (!isa<StoreInst>(&I))
+ continue;
+
+ auto *S = cast<StoreInst>(&I);
+ int64_t Offset = -1;
+ auto *Dst =
+ GetPointerBaseWithConstantOffset(S->getPointerOperand(), Offset, DL);
+ if (Dst == &Array) {
+ int64_t Idx = Offset / PointerSize;
+ StoredValues[Idx] = getUnderlyingObject(S->getValueOperand());
+ LastAccesses[Idx] = S;
+ }
+ }
+
+ return isFilled();
+ }
+
+ /// Returns true if all values in StoredValues and
+ /// LastAccesses are not nullptrs.
+ bool isFilled() {
+ const unsigned NumValues = StoredValues.size();
+ for (unsigned I = 0; I < NumValues; ++I) {
+ if (!StoredValues[I] || !LastAccesses[I])
+ return false;
+ }
+
+ return true;
+ }
+};
+
struct OpenMPOpt {
using OptimizationRemarkGetter =
@@ -488,12 +488,12 @@ struct OpenMPOpt {
: M(*(*SCC.begin())->getParent()), SCC(SCC), CGUpdater(CGUpdater),
OREGetter(OREGetter), OMPInfoCache(OMPInfoCache), A(A) {}
- /// Check if any remarks are enabled for openmp-opt
- bool remarksEnabled() {
- auto &Ctx = M.getContext();
- return Ctx.getDiagHandlerPtr()->isAnyRemarkEnabled(DEBUG_TYPE);
- }
-
+ /// Check if any remarks are enabled for openmp-opt
+ bool remarksEnabled() {
+ auto &Ctx = M.getContext();
+ return Ctx.getDiagHandlerPtr()->isAnyRemarkEnabled(DEBUG_TYPE);
+ }
+
/// Run all OpenMP optimizations on the underlying SCC/ModuleSlice.
bool run() {
if (SCC.empty())
@@ -517,18 +517,18 @@ struct OpenMPOpt {
// Recollect uses, in case Attributor deleted any.
OMPInfoCache.recollectUses();
- Changed |= deleteParallelRegions();
- if (HideMemoryTransferLatency)
- Changed |= hideMemTransfersLatency();
- if (remarksEnabled())
- analysisGlobalization();
+ Changed |= deleteParallelRegions();
+ if (HideMemoryTransferLatency)
+ Changed |= hideMemTransfersLatency();
+ if (remarksEnabled())
+ analysisGlobalization();
Changed |= deduplicateRuntimeCalls();
- if (EnableParallelRegionMerging) {
- if (mergeParallelRegions()) {
- deduplicateRuntimeCalls();
- Changed = true;
- }
- }
+ if (EnableParallelRegionMerging) {
+ if (mergeParallelRegions()) {
+ deduplicateRuntimeCalls();
+ Changed = true;
+ }
+ }
return Changed;
}
@@ -536,8 +536,8 @@ struct OpenMPOpt {
/// Print initial ICV values for testing.
/// FIXME: This should be done from the Attributor once it is added.
void printICVs() const {
- InternalControlVar ICVs[] = {ICV_nthreads, ICV_active_levels, ICV_cancel,
- ICV_proc_bind};
+ InternalControlVar ICVs[] = {ICV_nthreads, ICV_active_levels, ICV_cancel,
+ ICV_proc_bind};
for (Function *F : OMPInfoCache.ModuleSlice) {
for (auto ICV : ICVs) {
@@ -593,394 +593,394 @@ struct OpenMPOpt {
}
private:
- /// Merge parallel regions when it is safe.
- bool mergeParallelRegions() {
- const unsigned CallbackCalleeOperand = 2;
- const unsigned CallbackFirstArgOperand = 3;
- using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
-
- // Check if there are any __kmpc_fork_call calls to merge.
- OMPInformationCache::RuntimeFunctionInfo &RFI =
- OMPInfoCache.RFIs[OMPRTL___kmpc_fork_call];
-
- if (!RFI.Declaration)
- return false;
-
- // Unmergable calls that prevent merging a parallel region.
- OMPInformationCache::RuntimeFunctionInfo UnmergableCallsInfo[] = {
- OMPInfoCache.RFIs[OMPRTL___kmpc_push_proc_bind],
- OMPInfoCache.RFIs[OMPRTL___kmpc_push_num_threads],
- };
-
- bool Changed = false;
- LoopInfo *LI = nullptr;
- DominatorTree *DT = nullptr;
-
- SmallDenseMap<BasicBlock *, SmallPtrSet<Instruction *, 4>> BB2PRMap;
-
- BasicBlock *StartBB = nullptr, *EndBB = nullptr;
- auto BodyGenCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
- BasicBlock &ContinuationIP) {
- BasicBlock *CGStartBB = CodeGenIP.getBlock();
- BasicBlock *CGEndBB =
- SplitBlock(CGStartBB, &*CodeGenIP.getPoint(), DT, LI);
- assert(StartBB != nullptr && "StartBB should not be null");
- CGStartBB->getTerminator()->setSuccessor(0, StartBB);
- assert(EndBB != nullptr && "EndBB should not be null");
- EndBB->getTerminator()->setSuccessor(0, CGEndBB);
- };
-
- auto PrivCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP, Value &,
- Value &Inner, Value *&ReplacementValue) -> InsertPointTy {
- ReplacementValue = &Inner;
- return CodeGenIP;
- };
-
- auto FiniCB = [&](InsertPointTy CodeGenIP) {};
-
- /// Create a sequential execution region within a merged parallel region,
- /// encapsulated in a master construct with a barrier for synchronization.
- auto CreateSequentialRegion = [&](Function *OuterFn,
- BasicBlock *OuterPredBB,
- Instruction *SeqStartI,
- Instruction *SeqEndI) {
- // Isolate the instructions of the sequential region to a separate
- // block.
- BasicBlock *ParentBB = SeqStartI->getParent();
- BasicBlock *SeqEndBB =
- SplitBlock(ParentBB, SeqEndI->getNextNode(), DT, LI);
- BasicBlock *SeqAfterBB =
- SplitBlock(SeqEndBB, &*SeqEndBB->getFirstInsertionPt(), DT, LI);
- BasicBlock *SeqStartBB =
- SplitBlock(ParentBB, SeqStartI, DT, LI, nullptr, "seq.par.merged");
-
- assert(ParentBB->getUniqueSuccessor() == SeqStartBB &&
- "Expected a different CFG");
- const DebugLoc DL = ParentBB->getTerminator()->getDebugLoc();
- ParentBB->getTerminator()->eraseFromParent();
-
- auto BodyGenCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
- BasicBlock &ContinuationIP) {
- BasicBlock *CGStartBB = CodeGenIP.getBlock();
- BasicBlock *CGEndBB =
- SplitBlock(CGStartBB, &*CodeGenIP.getPoint(), DT, LI);
- assert(SeqStartBB != nullptr && "SeqStartBB should not be null");
- CGStartBB->getTerminator()->setSuccessor(0, SeqStartBB);
- assert(SeqEndBB != nullptr && "SeqEndBB should not be null");
- SeqEndBB->getTerminator()->setSuccessor(0, CGEndBB);
- };
- auto FiniCB = [&](InsertPointTy CodeGenIP) {};
-
- // Find outputs from the sequential region to outside users and
- // broadcast their values to them.
- for (Instruction &I : *SeqStartBB) {
- SmallPtrSet<Instruction *, 4> OutsideUsers;
- for (User *Usr : I.users()) {
- Instruction &UsrI = *cast<Instruction>(Usr);
- // Ignore outputs to LT intrinsics, code extraction for the merged
- // parallel region will fix them.
- if (UsrI.isLifetimeStartOrEnd())
- continue;
-
- if (UsrI.getParent() != SeqStartBB)
- OutsideUsers.insert(&UsrI);
- }
-
- if (OutsideUsers.empty())
- continue;
-
- // Emit an alloca in the outer region to store the broadcasted
- // value.
- const DataLayout &DL = M.getDataLayout();
- AllocaInst *AllocaI = new AllocaInst(
- I.getType(), DL.getAllocaAddrSpace(), nullptr,
- I.getName() + ".seq.output.alloc", &OuterFn->front().front());
-
- // Emit a store instruction in the sequential BB to update the
- // value.
- new StoreInst(&I, AllocaI, SeqStartBB->getTerminator());
-
- // Emit a load instruction and replace the use of the output value
- // with it.
- for (Instruction *UsrI : OutsideUsers) {
- LoadInst *LoadI = new LoadInst(I.getType(), AllocaI,
- I.getName() + ".seq.output.load", UsrI);
- UsrI->replaceUsesOfWith(&I, LoadI);
- }
- }
-
- OpenMPIRBuilder::LocationDescription Loc(
- InsertPointTy(ParentBB, ParentBB->end()), DL);
- InsertPointTy SeqAfterIP =
- OMPInfoCache.OMPBuilder.createMaster(Loc, BodyGenCB, FiniCB);
-
- OMPInfoCache.OMPBuilder.createBarrier(SeqAfterIP, OMPD_parallel);
-
- BranchInst::Create(SeqAfterBB, SeqAfterIP.getBlock());
-
- LLVM_DEBUG(dbgs() << TAG << "After sequential inlining " << *OuterFn
- << "\n");
- };
-
- // Helper to merge the __kmpc_fork_call calls in MergableCIs. They are all
- // contained in BB and only separated by instructions that can be
- // redundantly executed in parallel. The block BB is split before the first
- // call (in MergableCIs) and after the last so the entire region we merge
- // into a single parallel region is contained in a single basic block
- // without any other instructions. We use the OpenMPIRBuilder to outline
- // that block and call the resulting function via __kmpc_fork_call.
- auto Merge = [&](SmallVectorImpl<CallInst *> &MergableCIs, BasicBlock *BB) {
- // TODO: Change the interface to allow single CIs expanded, e.g, to
- // include an outer loop.
- assert(MergableCIs.size() > 1 && "Assumed multiple mergable CIs");
-
- auto Remark = [&](OptimizationRemark OR) {
- OR << "Parallel region at "
- << ore::NV("OpenMPParallelMergeFront",
- MergableCIs.front()->getDebugLoc())
- << " merged with parallel regions at ";
- for (auto *CI : llvm::drop_begin(MergableCIs)) {
- OR << ore::NV("OpenMPParallelMerge", CI->getDebugLoc());
- if (CI != MergableCIs.back())
- OR << ", ";
- }
- return OR;
- };
-
- emitRemark<OptimizationRemark>(MergableCIs.front(),
- "OpenMPParallelRegionMerging", Remark);
-
- Function *OriginalFn = BB->getParent();
- LLVM_DEBUG(dbgs() << TAG << "Merge " << MergableCIs.size()
- << " parallel regions in " << OriginalFn->getName()
- << "\n");
-
- // Isolate the calls to merge in a separate block.
- EndBB = SplitBlock(BB, MergableCIs.back()->getNextNode(), DT, LI);
- BasicBlock *AfterBB =
- SplitBlock(EndBB, &*EndBB->getFirstInsertionPt(), DT, LI);
- StartBB = SplitBlock(BB, MergableCIs.front(), DT, LI, nullptr,
- "omp.par.merged");
-
- assert(BB->getUniqueSuccessor() == StartBB && "Expected a different CFG");
- const DebugLoc DL = BB->getTerminator()->getDebugLoc();
- BB->getTerminator()->eraseFromParent();
-
- // Create sequential regions for sequential instructions that are
- // in-between mergable parallel regions.
- for (auto *It = MergableCIs.begin(), *End = MergableCIs.end() - 1;
- It != End; ++It) {
- Instruction *ForkCI = *It;
- Instruction *NextForkCI = *(It + 1);
-
- // Continue if there are not in-between instructions.
- if (ForkCI->getNextNode() == NextForkCI)
- continue;
-
- CreateSequentialRegion(OriginalFn, BB, ForkCI->getNextNode(),
- NextForkCI->getPrevNode());
- }
-
- OpenMPIRBuilder::LocationDescription Loc(InsertPointTy(BB, BB->end()),
- DL);
- IRBuilder<>::InsertPoint AllocaIP(
- &OriginalFn->getEntryBlock(),
- OriginalFn->getEntryBlock().getFirstInsertionPt());
- // Create the merged parallel region with default proc binding, to
- // avoid overriding binding settings, and without explicit cancellation.
- InsertPointTy AfterIP = OMPInfoCache.OMPBuilder.createParallel(
- Loc, AllocaIP, BodyGenCB, PrivCB, FiniCB, nullptr, nullptr,
- OMP_PROC_BIND_default, /* IsCancellable */ false);
- BranchInst::Create(AfterBB, AfterIP.getBlock());
-
- // Perform the actual outlining.
- OMPInfoCache.OMPBuilder.finalize(/* AllowExtractorSinking */ true);
-
- Function *OutlinedFn = MergableCIs.front()->getCaller();
-
- // Replace the __kmpc_fork_call calls with direct calls to the outlined
- // callbacks.
- SmallVector<Value *, 8> Args;
- for (auto *CI : MergableCIs) {
- Value *Callee =
- CI->getArgOperand(CallbackCalleeOperand)->stripPointerCasts();
- FunctionType *FT =
- cast<FunctionType>(Callee->getType()->getPointerElementType());
- Args.clear();
- Args.push_back(OutlinedFn->getArg(0));
- Args.push_back(OutlinedFn->getArg(1));
- for (unsigned U = CallbackFirstArgOperand, E = CI->getNumArgOperands();
- U < E; ++U)
- Args.push_back(CI->getArgOperand(U));
-
- CallInst *NewCI = CallInst::Create(FT, Callee, Args, "", CI);
- if (CI->getDebugLoc())
- NewCI->setDebugLoc(CI->getDebugLoc());
-
- // Forward parameter attributes from the callback to the callee.
- for (unsigned U = CallbackFirstArgOperand, E = CI->getNumArgOperands();
- U < E; ++U)
- for (const Attribute &A : CI->getAttributes().getParamAttributes(U))
- NewCI->addParamAttr(
- U - (CallbackFirstArgOperand - CallbackCalleeOperand), A);
-
- // Emit an explicit barrier to replace the implicit fork-join barrier.
- if (CI != MergableCIs.back()) {
- // TODO: Remove barrier if the merged parallel region includes the
- // 'nowait' clause.
- OMPInfoCache.OMPBuilder.createBarrier(
- InsertPointTy(NewCI->getParent(),
- NewCI->getNextNode()->getIterator()),
- OMPD_parallel);
- }
-
- auto Remark = [&](OptimizationRemark OR) {
- return OR << "Parallel region at "
- << ore::NV("OpenMPParallelMerge", CI->getDebugLoc())
- << " merged with "
- << ore::NV("OpenMPParallelMergeFront",
- MergableCIs.front()->getDebugLoc());
- };
- if (CI != MergableCIs.front())
- emitRemark<OptimizationRemark>(CI, "OpenMPParallelRegionMerging",
- Remark);
-
- CI->eraseFromParent();
- }
-
- assert(OutlinedFn != OriginalFn && "Outlining failed");
- CGUpdater.registerOutlinedFunction(*OriginalFn, *OutlinedFn);
- CGUpdater.reanalyzeFunction(*OriginalFn);
-
- NumOpenMPParallelRegionsMerged += MergableCIs.size();
-
- return true;
- };
-
- // Helper function that identifes sequences of
- // __kmpc_fork_call uses in a basic block.
- auto DetectPRsCB = [&](Use &U, Function &F) {
- CallInst *CI = getCallIfRegularCall(U, &RFI);
- BB2PRMap[CI->getParent()].insert(CI);
-
- return false;
- };
-
- BB2PRMap.clear();
- RFI.foreachUse(SCC, DetectPRsCB);
- SmallVector<SmallVector<CallInst *, 4>, 4> MergableCIsVector;
- // Find mergable parallel regions within a basic block that are
- // safe to merge, that is any in-between instructions can safely
- // execute in parallel after merging.
- // TODO: support merging across basic-blocks.
- for (auto &It : BB2PRMap) {
- auto &CIs = It.getSecond();
- if (CIs.size() < 2)
- continue;
-
- BasicBlock *BB = It.getFirst();
- SmallVector<CallInst *, 4> MergableCIs;
-
- /// Returns true if the instruction is mergable, false otherwise.
- /// A terminator instruction is unmergable by definition since merging
- /// works within a BB. Instructions before the mergable region are
- /// mergable if they are not calls to OpenMP runtime functions that may
- /// set different execution parameters for subsequent parallel regions.
- /// Instructions in-between parallel regions are mergable if they are not
- /// calls to any non-intrinsic function since that may call a non-mergable
- /// OpenMP runtime function.
- auto IsMergable = [&](Instruction &I, bool IsBeforeMergableRegion) {
- // We do not merge across BBs, hence return false (unmergable) if the
- // instruction is a terminator.
- if (I.isTerminator())
- return false;
-
- if (!isa<CallInst>(&I))
- return true;
-
- CallInst *CI = cast<CallInst>(&I);
- if (IsBeforeMergableRegion) {
- Function *CalledFunction = CI->getCalledFunction();
- if (!CalledFunction)
- return false;
- // Return false (unmergable) if the call before the parallel
- // region calls an explicit affinity (proc_bind) or number of
- // threads (num_threads) compiler-generated function. Those settings
- // may be incompatible with following parallel regions.
- // TODO: ICV tracking to detect compatibility.
- for (const auto &RFI : UnmergableCallsInfo) {
- if (CalledFunction == RFI.Declaration)
- return false;
- }
- } else {
- // Return false (unmergable) if there is a call instruction
- // in-between parallel regions when it is not an intrinsic. It
- // may call an unmergable OpenMP runtime function in its callpath.
- // TODO: Keep track of possible OpenMP calls in the callpath.
- if (!isa<IntrinsicInst>(CI))
- return false;
- }
-
- return true;
- };
- // Find maximal number of parallel region CIs that are safe to merge.
- for (auto It = BB->begin(), End = BB->end(); It != End;) {
- Instruction &I = *It;
- ++It;
-
- if (CIs.count(&I)) {
- MergableCIs.push_back(cast<CallInst>(&I));
- continue;
- }
-
- // Continue expanding if the instruction is mergable.
- if (IsMergable(I, MergableCIs.empty()))
- continue;
-
- // Forward the instruction iterator to skip the next parallel region
- // since there is an unmergable instruction which can affect it.
- for (; It != End; ++It) {
- Instruction &SkipI = *It;
- if (CIs.count(&SkipI)) {
- LLVM_DEBUG(dbgs() << TAG << "Skip parallel region " << SkipI
- << " due to " << I << "\n");
- ++It;
- break;
- }
- }
-
- // Store mergable regions found.
- if (MergableCIs.size() > 1) {
- MergableCIsVector.push_back(MergableCIs);
- LLVM_DEBUG(dbgs() << TAG << "Found " << MergableCIs.size()
- << " parallel regions in block " << BB->getName()
- << " of function " << BB->getParent()->getName()
- << "\n";);
- }
-
- MergableCIs.clear();
- }
-
- if (!MergableCIsVector.empty()) {
- Changed = true;
-
- for (auto &MergableCIs : MergableCIsVector)
- Merge(MergableCIs, BB);
- }
- }
-
- if (Changed) {
- /// Re-collect use for fork calls, emitted barrier calls, and
- /// any emitted master/end_master calls.
- OMPInfoCache.recollectUsesForFunction(OMPRTL___kmpc_fork_call);
- OMPInfoCache.recollectUsesForFunction(OMPRTL___kmpc_barrier);
- OMPInfoCache.recollectUsesForFunction(OMPRTL___kmpc_master);
- OMPInfoCache.recollectUsesForFunction(OMPRTL___kmpc_end_master);
- }
-
- return Changed;
- }
-
+ /// Merge parallel regions when it is safe.
+ bool mergeParallelRegions() {
+ const unsigned CallbackCalleeOperand = 2;
+ const unsigned CallbackFirstArgOperand = 3;
+ using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
+
+ // Check if there are any __kmpc_fork_call calls to merge.
+ OMPInformationCache::RuntimeFunctionInfo &RFI =
+ OMPInfoCache.RFIs[OMPRTL___kmpc_fork_call];
+
+ if (!RFI.Declaration)
+ return false;
+
+ // Unmergable calls that prevent merging a parallel region.
+ OMPInformationCache::RuntimeFunctionInfo UnmergableCallsInfo[] = {
+ OMPInfoCache.RFIs[OMPRTL___kmpc_push_proc_bind],
+ OMPInfoCache.RFIs[OMPRTL___kmpc_push_num_threads],
+ };
+
+ bool Changed = false;
+ LoopInfo *LI = nullptr;
+ DominatorTree *DT = nullptr;
+
+ SmallDenseMap<BasicBlock *, SmallPtrSet<Instruction *, 4>> BB2PRMap;
+
+ BasicBlock *StartBB = nullptr, *EndBB = nullptr;
+ auto BodyGenCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
+ BasicBlock &ContinuationIP) {
+ BasicBlock *CGStartBB = CodeGenIP.getBlock();
+ BasicBlock *CGEndBB =
+ SplitBlock(CGStartBB, &*CodeGenIP.getPoint(), DT, LI);
+ assert(StartBB != nullptr && "StartBB should not be null");
+ CGStartBB->getTerminator()->setSuccessor(0, StartBB);
+ assert(EndBB != nullptr && "EndBB should not be null");
+ EndBB->getTerminator()->setSuccessor(0, CGEndBB);
+ };
+
+ auto PrivCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP, Value &,
+ Value &Inner, Value *&ReplacementValue) -> InsertPointTy {
+ ReplacementValue = &Inner;
+ return CodeGenIP;
+ };
+
+ auto FiniCB = [&](InsertPointTy CodeGenIP) {};
+
+ /// Create a sequential execution region within a merged parallel region,
+ /// encapsulated in a master construct with a barrier for synchronization.
+ auto CreateSequentialRegion = [&](Function *OuterFn,
+ BasicBlock *OuterPredBB,
+ Instruction *SeqStartI,
+ Instruction *SeqEndI) {
+ // Isolate the instructions of the sequential region to a separate
+ // block.
+ BasicBlock *ParentBB = SeqStartI->getParent();
+ BasicBlock *SeqEndBB =
+ SplitBlock(ParentBB, SeqEndI->getNextNode(), DT, LI);
+ BasicBlock *SeqAfterBB =
+ SplitBlock(SeqEndBB, &*SeqEndBB->getFirstInsertionPt(), DT, LI);
+ BasicBlock *SeqStartBB =
+ SplitBlock(ParentBB, SeqStartI, DT, LI, nullptr, "seq.par.merged");
+
+ assert(ParentBB->getUniqueSuccessor() == SeqStartBB &&
+ "Expected a different CFG");
+ const DebugLoc DL = ParentBB->getTerminator()->getDebugLoc();
+ ParentBB->getTerminator()->eraseFromParent();
+
+ auto BodyGenCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
+ BasicBlock &ContinuationIP) {
+ BasicBlock *CGStartBB = CodeGenIP.getBlock();
+ BasicBlock *CGEndBB =
+ SplitBlock(CGStartBB, &*CodeGenIP.getPoint(), DT, LI);
+ assert(SeqStartBB != nullptr && "SeqStartBB should not be null");
+ CGStartBB->getTerminator()->setSuccessor(0, SeqStartBB);
+ assert(SeqEndBB != nullptr && "SeqEndBB should not be null");
+ SeqEndBB->getTerminator()->setSuccessor(0, CGEndBB);
+ };
+ auto FiniCB = [&](InsertPointTy CodeGenIP) {};
+
+ // Find outputs from the sequential region to outside users and
+ // broadcast their values to them.
+ for (Instruction &I : *SeqStartBB) {
+ SmallPtrSet<Instruction *, 4> OutsideUsers;
+ for (User *Usr : I.users()) {
+ Instruction &UsrI = *cast<Instruction>(Usr);
+ // Ignore outputs to LT intrinsics, code extraction for the merged
+ // parallel region will fix them.
+ if (UsrI.isLifetimeStartOrEnd())
+ continue;
+
+ if (UsrI.getParent() != SeqStartBB)
+ OutsideUsers.insert(&UsrI);
+ }
+
+ if (OutsideUsers.empty())
+ continue;
+
+ // Emit an alloca in the outer region to store the broadcasted
+ // value.
+ const DataLayout &DL = M.getDataLayout();
+ AllocaInst *AllocaI = new AllocaInst(
+ I.getType(), DL.getAllocaAddrSpace(), nullptr,
+ I.getName() + ".seq.output.alloc", &OuterFn->front().front());
+
+ // Emit a store instruction in the sequential BB to update the
+ // value.
+ new StoreInst(&I, AllocaI, SeqStartBB->getTerminator());
+
+ // Emit a load instruction and replace the use of the output value
+ // with it.
+ for (Instruction *UsrI : OutsideUsers) {
+ LoadInst *LoadI = new LoadInst(I.getType(), AllocaI,
+ I.getName() + ".seq.output.load", UsrI);
+ UsrI->replaceUsesOfWith(&I, LoadI);
+ }
+ }
+
+ OpenMPIRBuilder::LocationDescription Loc(
+ InsertPointTy(ParentBB, ParentBB->end()), DL);
+ InsertPointTy SeqAfterIP =
+ OMPInfoCache.OMPBuilder.createMaster(Loc, BodyGenCB, FiniCB);
+
+ OMPInfoCache.OMPBuilder.createBarrier(SeqAfterIP, OMPD_parallel);
+
+ BranchInst::Create(SeqAfterBB, SeqAfterIP.getBlock());
+
+ LLVM_DEBUG(dbgs() << TAG << "After sequential inlining " << *OuterFn
+ << "\n");
+ };
+
+ // Helper to merge the __kmpc_fork_call calls in MergableCIs. They are all
+ // contained in BB and only separated by instructions that can be
+ // redundantly executed in parallel. The block BB is split before the first
+ // call (in MergableCIs) and after the last so the entire region we merge
+ // into a single parallel region is contained in a single basic block
+ // without any other instructions. We use the OpenMPIRBuilder to outline
+ // that block and call the resulting function via __kmpc_fork_call.
+ auto Merge = [&](SmallVectorImpl<CallInst *> &MergableCIs, BasicBlock *BB) {
+ // TODO: Change the interface to allow single CIs expanded, e.g, to
+ // include an outer loop.
+ assert(MergableCIs.size() > 1 && "Assumed multiple mergable CIs");
+
+ auto Remark = [&](OptimizationRemark OR) {
+ OR << "Parallel region at "
+ << ore::NV("OpenMPParallelMergeFront",
+ MergableCIs.front()->getDebugLoc())
+ << " merged with parallel regions at ";
+ for (auto *CI : llvm::drop_begin(MergableCIs)) {
+ OR << ore::NV("OpenMPParallelMerge", CI->getDebugLoc());
+ if (CI != MergableCIs.back())
+ OR << ", ";
+ }
+ return OR;
+ };
+
+ emitRemark<OptimizationRemark>(MergableCIs.front(),
+ "OpenMPParallelRegionMerging", Remark);
+
+ Function *OriginalFn = BB->getParent();
+ LLVM_DEBUG(dbgs() << TAG << "Merge " << MergableCIs.size()
+ << " parallel regions in " << OriginalFn->getName()
+ << "\n");
+
+ // Isolate the calls to merge in a separate block.
+ EndBB = SplitBlock(BB, MergableCIs.back()->getNextNode(), DT, LI);
+ BasicBlock *AfterBB =
+ SplitBlock(EndBB, &*EndBB->getFirstInsertionPt(), DT, LI);
+ StartBB = SplitBlock(BB, MergableCIs.front(), DT, LI, nullptr,
+ "omp.par.merged");
+
+ assert(BB->getUniqueSuccessor() == StartBB && "Expected a different CFG");
+ const DebugLoc DL = BB->getTerminator()->getDebugLoc();
+ BB->getTerminator()->eraseFromParent();
+
+ // Create sequential regions for sequential instructions that are
+ // in-between mergable parallel regions.
+ for (auto *It = MergableCIs.begin(), *End = MergableCIs.end() - 1;
+ It != End; ++It) {
+ Instruction *ForkCI = *It;
+ Instruction *NextForkCI = *(It + 1);
+
+ // Continue if there are not in-between instructions.
+ if (ForkCI->getNextNode() == NextForkCI)
+ continue;
+
+ CreateSequentialRegion(OriginalFn, BB, ForkCI->getNextNode(),
+ NextForkCI->getPrevNode());
+ }
+
+ OpenMPIRBuilder::LocationDescription Loc(InsertPointTy(BB, BB->end()),
+ DL);
+ IRBuilder<>::InsertPoint AllocaIP(
+ &OriginalFn->getEntryBlock(),
+ OriginalFn->getEntryBlock().getFirstInsertionPt());
+ // Create the merged parallel region with default proc binding, to
+ // avoid overriding binding settings, and without explicit cancellation.
+ InsertPointTy AfterIP = OMPInfoCache.OMPBuilder.createParallel(
+ Loc, AllocaIP, BodyGenCB, PrivCB, FiniCB, nullptr, nullptr,
+ OMP_PROC_BIND_default, /* IsCancellable */ false);
+ BranchInst::Create(AfterBB, AfterIP.getBlock());
+
+ // Perform the actual outlining.
+ OMPInfoCache.OMPBuilder.finalize(/* AllowExtractorSinking */ true);
+
+ Function *OutlinedFn = MergableCIs.front()->getCaller();
+
+ // Replace the __kmpc_fork_call calls with direct calls to the outlined
+ // callbacks.
+ SmallVector<Value *, 8> Args;
+ for (auto *CI : MergableCIs) {
+ Value *Callee =
+ CI->getArgOperand(CallbackCalleeOperand)->stripPointerCasts();
+ FunctionType *FT =
+ cast<FunctionType>(Callee->getType()->getPointerElementType());
+ Args.clear();
+ Args.push_back(OutlinedFn->getArg(0));
+ Args.push_back(OutlinedFn->getArg(1));
+ for (unsigned U = CallbackFirstArgOperand, E = CI->getNumArgOperands();
+ U < E; ++U)
+ Args.push_back(CI->getArgOperand(U));
+
+ CallInst *NewCI = CallInst::Create(FT, Callee, Args, "", CI);
+ if (CI->getDebugLoc())
+ NewCI->setDebugLoc(CI->getDebugLoc());
+
+ // Forward parameter attributes from the callback to the callee.
+ for (unsigned U = CallbackFirstArgOperand, E = CI->getNumArgOperands();
+ U < E; ++U)
+ for (const Attribute &A : CI->getAttributes().getParamAttributes(U))
+ NewCI->addParamAttr(
+ U - (CallbackFirstArgOperand - CallbackCalleeOperand), A);
+
+ // Emit an explicit barrier to replace the implicit fork-join barrier.
+ if (CI != MergableCIs.back()) {
+ // TODO: Remove barrier if the merged parallel region includes the
+ // 'nowait' clause.
+ OMPInfoCache.OMPBuilder.createBarrier(
+ InsertPointTy(NewCI->getParent(),
+ NewCI->getNextNode()->getIterator()),
+ OMPD_parallel);
+ }
+
+ auto Remark = [&](OptimizationRemark OR) {
+ return OR << "Parallel region at "
+ << ore::NV("OpenMPParallelMerge", CI->getDebugLoc())
+ << " merged with "
+ << ore::NV("OpenMPParallelMergeFront",
+ MergableCIs.front()->getDebugLoc());
+ };
+ if (CI != MergableCIs.front())
+ emitRemark<OptimizationRemark>(CI, "OpenMPParallelRegionMerging",
+ Remark);
+
+ CI->eraseFromParent();
+ }
+
+ assert(OutlinedFn != OriginalFn && "Outlining failed");
+ CGUpdater.registerOutlinedFunction(*OriginalFn, *OutlinedFn);
+ CGUpdater.reanalyzeFunction(*OriginalFn);
+
+ NumOpenMPParallelRegionsMerged += MergableCIs.size();
+
+ return true;
+ };
+
+ // Helper function that identifes sequences of
+ // __kmpc_fork_call uses in a basic block.
+ auto DetectPRsCB = [&](Use &U, Function &F) {
+ CallInst *CI = getCallIfRegularCall(U, &RFI);
+ BB2PRMap[CI->getParent()].insert(CI);
+
+ return false;
+ };
+
+ BB2PRMap.clear();
+ RFI.foreachUse(SCC, DetectPRsCB);
+ SmallVector<SmallVector<CallInst *, 4>, 4> MergableCIsVector;
+ // Find mergable parallel regions within a basic block that are
+ // safe to merge, that is any in-between instructions can safely
+ // execute in parallel after merging.
+ // TODO: support merging across basic-blocks.
+ for (auto &It : BB2PRMap) {
+ auto &CIs = It.getSecond();
+ if (CIs.size() < 2)
+ continue;
+
+ BasicBlock *BB = It.getFirst();
+ SmallVector<CallInst *, 4> MergableCIs;
+
+ /// Returns true if the instruction is mergable, false otherwise.
+ /// A terminator instruction is unmergable by definition since merging
+ /// works within a BB. Instructions before the mergable region are
+ /// mergable if they are not calls to OpenMP runtime functions that may
+ /// set different execution parameters for subsequent parallel regions.
+ /// Instructions in-between parallel regions are mergable if they are not
+ /// calls to any non-intrinsic function since that may call a non-mergable
+ /// OpenMP runtime function.
+ auto IsMergable = [&](Instruction &I, bool IsBeforeMergableRegion) {
+ // We do not merge across BBs, hence return false (unmergable) if the
+ // instruction is a terminator.
+ if (I.isTerminator())
+ return false;
+
+ if (!isa<CallInst>(&I))
+ return true;
+
+ CallInst *CI = cast<CallInst>(&I);
+ if (IsBeforeMergableRegion) {
+ Function *CalledFunction = CI->getCalledFunction();
+ if (!CalledFunction)
+ return false;
+ // Return false (unmergable) if the call before the parallel
+ // region calls an explicit affinity (proc_bind) or number of
+ // threads (num_threads) compiler-generated function. Those settings
+ // may be incompatible with following parallel regions.
+ // TODO: ICV tracking to detect compatibility.
+ for (const auto &RFI : UnmergableCallsInfo) {
+ if (CalledFunction == RFI.Declaration)
+ return false;
+ }
+ } else {
+ // Return false (unmergable) if there is a call instruction
+ // in-between parallel regions when it is not an intrinsic. It
+ // may call an unmergable OpenMP runtime function in its callpath.
+ // TODO: Keep track of possible OpenMP calls in the callpath.
+ if (!isa<IntrinsicInst>(CI))
+ return false;
+ }
+
+ return true;
+ };
+ // Find maximal number of parallel region CIs that are safe to merge.
+ for (auto It = BB->begin(), End = BB->end(); It != End;) {
+ Instruction &I = *It;
+ ++It;
+
+ if (CIs.count(&I)) {
+ MergableCIs.push_back(cast<CallInst>(&I));
+ continue;
+ }
+
+ // Continue expanding if the instruction is mergable.
+ if (IsMergable(I, MergableCIs.empty()))
+ continue;
+
+ // Forward the instruction iterator to skip the next parallel region
+ // since there is an unmergable instruction which can affect it.
+ for (; It != End; ++It) {
+ Instruction &SkipI = *It;
+ if (CIs.count(&SkipI)) {
+ LLVM_DEBUG(dbgs() << TAG << "Skip parallel region " << SkipI
+ << " due to " << I << "\n");
+ ++It;
+ break;
+ }
+ }
+
+ // Store mergable regions found.
+ if (MergableCIs.size() > 1) {
+ MergableCIsVector.push_back(MergableCIs);
+ LLVM_DEBUG(dbgs() << TAG << "Found " << MergableCIs.size()
+ << " parallel regions in block " << BB->getName()
+ << " of function " << BB->getParent()->getName()
+ << "\n";);
+ }
+
+ MergableCIs.clear();
+ }
+
+ if (!MergableCIsVector.empty()) {
+ Changed = true;
+
+ for (auto &MergableCIs : MergableCIsVector)
+ Merge(MergableCIs, BB);
+ }
+ }
+
+ if (Changed) {
+ /// Re-collect use for fork calls, emitted barrier calls, and
+ /// any emitted master/end_master calls.
+ OMPInfoCache.recollectUsesForFunction(OMPRTL___kmpc_fork_call);
+ OMPInfoCache.recollectUsesForFunction(OMPRTL___kmpc_barrier);
+ OMPInfoCache.recollectUsesForFunction(OMPRTL___kmpc_master);
+ OMPInfoCache.recollectUsesForFunction(OMPRTL___kmpc_end_master);
+ }
+
+ return Changed;
+ }
+
/// Try to delete parallel regions if possible.
bool deleteParallelRegions() {
const unsigned CallbackCalleeOperand = 2;
@@ -1058,8 +1058,8 @@ private:
for (Function *F : SCC) {
for (auto DeduplicableRuntimeCallID : DeduplicableRuntimeCallIDs)
- Changed |= deduplicateRuntimeCalls(
- *F, OMPInfoCache.RFIs[DeduplicableRuntimeCallID]);
+ Changed |= deduplicateRuntimeCalls(
+ *F, OMPInfoCache.RFIs[DeduplicableRuntimeCallID]);
// __kmpc_global_thread_num is special as we can replace it with an
// argument in enough cases to make it worth trying.
@@ -1076,223 +1076,223 @@ private:
return Changed;
}
- /// Tries to hide the latency of runtime calls that involve host to
- /// device memory transfers by splitting them into their "issue" and "wait"
- /// versions. The "issue" is moved upwards as much as possible. The "wait" is
- /// moved downards as much as possible. The "issue" issues the memory transfer
- /// asynchronously, returning a handle. The "wait" waits in the returned
- /// handle for the memory transfer to finish.
- bool hideMemTransfersLatency() {
- auto &RFI = OMPInfoCache.RFIs[OMPRTL___tgt_target_data_begin_mapper];
- bool Changed = false;
- auto SplitMemTransfers = [&](Use &U, Function &Decl) {
- auto *RTCall = getCallIfRegularCall(U, &RFI);
- if (!RTCall)
- return false;
-
- OffloadArray OffloadArrays[3];
- if (!getValuesInOffloadArrays(*RTCall, OffloadArrays))
- return false;
-
- LLVM_DEBUG(dumpValuesInOffloadArrays(OffloadArrays));
-
- // TODO: Check if can be moved upwards.
- bool WasSplit = false;
- Instruction *WaitMovementPoint = canBeMovedDownwards(*RTCall);
- if (WaitMovementPoint)
- WasSplit = splitTargetDataBeginRTC(*RTCall, *WaitMovementPoint);
-
- Changed |= WasSplit;
- return WasSplit;
- };
- RFI.foreachUse(SCC, SplitMemTransfers);
-
- return Changed;
- }
-
- void analysisGlobalization() {
- RuntimeFunction GlobalizationRuntimeIDs[] = {
- OMPRTL___kmpc_data_sharing_coalesced_push_stack,
- OMPRTL___kmpc_data_sharing_push_stack};
-
- for (const auto GlobalizationCallID : GlobalizationRuntimeIDs) {
- auto &RFI = OMPInfoCache.RFIs[GlobalizationCallID];
-
- auto CheckGlobalization = [&](Use &U, Function &Decl) {
- if (CallInst *CI = getCallIfRegularCall(U, &RFI)) {
- auto Remark = [&](OptimizationRemarkAnalysis ORA) {
- return ORA
- << "Found thread data sharing on the GPU. "
- << "Expect degraded performance due to data globalization.";
- };
- emitRemark<OptimizationRemarkAnalysis>(CI, "OpenMPGlobalization",
- Remark);
- }
-
- return false;
- };
-
- RFI.foreachUse(SCC, CheckGlobalization);
- }
- }
-
- /// Maps the values stored in the offload arrays passed as arguments to
- /// \p RuntimeCall into the offload arrays in \p OAs.
- bool getValuesInOffloadArrays(CallInst &RuntimeCall,
- MutableArrayRef<OffloadArray> OAs) {
- assert(OAs.size() == 3 && "Need space for three offload arrays!");
-
- // A runtime call that involves memory offloading looks something like:
- // call void @__tgt_target_data_begin_mapper(arg0, arg1,
- // i8** %offload_baseptrs, i8** %offload_ptrs, i64* %offload_sizes,
- // ...)
- // So, the idea is to access the allocas that allocate space for these
- // offload arrays, offload_baseptrs, offload_ptrs, offload_sizes.
- // Therefore:
- // i8** %offload_baseptrs.
- Value *BasePtrsArg =
- RuntimeCall.getArgOperand(OffloadArray::BasePtrsArgNum);
- // i8** %offload_ptrs.
- Value *PtrsArg = RuntimeCall.getArgOperand(OffloadArray::PtrsArgNum);
- // i8** %offload_sizes.
- Value *SizesArg = RuntimeCall.getArgOperand(OffloadArray::SizesArgNum);
-
- // Get values stored in **offload_baseptrs.
- auto *V = getUnderlyingObject(BasePtrsArg);
- if (!isa<AllocaInst>(V))
- return false;
- auto *BasePtrsArray = cast<AllocaInst>(V);
- if (!OAs[0].initialize(*BasePtrsArray, RuntimeCall))
- return false;
-
- // Get values stored in **offload_baseptrs.
- V = getUnderlyingObject(PtrsArg);
- if (!isa<AllocaInst>(V))
- return false;
- auto *PtrsArray = cast<AllocaInst>(V);
- if (!OAs[1].initialize(*PtrsArray, RuntimeCall))
- return false;
-
- // Get values stored in **offload_sizes.
- V = getUnderlyingObject(SizesArg);
- // If it's a [constant] global array don't analyze it.
- if (isa<GlobalValue>(V))
- return isa<Constant>(V);
- if (!isa<AllocaInst>(V))
- return false;
-
- auto *SizesArray = cast<AllocaInst>(V);
- if (!OAs[2].initialize(*SizesArray, RuntimeCall))
- return false;
-
- return true;
- }
-
- /// Prints the values in the OffloadArrays \p OAs using LLVM_DEBUG.
- /// For now this is a way to test that the function getValuesInOffloadArrays
- /// is working properly.
- /// TODO: Move this to a unittest when unittests are available for OpenMPOpt.
- void dumpValuesInOffloadArrays(ArrayRef<OffloadArray> OAs) {
- assert(OAs.size() == 3 && "There are three offload arrays to debug!");
-
- LLVM_DEBUG(dbgs() << TAG << " Successfully got offload values:\n");
- std::string ValuesStr;
- raw_string_ostream Printer(ValuesStr);
- std::string Separator = " --- ";
-
- for (auto *BP : OAs[0].StoredValues) {
- BP->print(Printer);
- Printer << Separator;
- }
- LLVM_DEBUG(dbgs() << "\t\toffload_baseptrs: " << Printer.str() << "\n");
- ValuesStr.clear();
-
- for (auto *P : OAs[1].StoredValues) {
- P->print(Printer);
- Printer << Separator;
- }
- LLVM_DEBUG(dbgs() << "\t\toffload_ptrs: " << Printer.str() << "\n");
- ValuesStr.clear();
-
- for (auto *S : OAs[2].StoredValues) {
- S->print(Printer);
- Printer << Separator;
- }
- LLVM_DEBUG(dbgs() << "\t\toffload_sizes: " << Printer.str() << "\n");
- }
-
- /// Returns the instruction where the "wait" counterpart \p RuntimeCall can be
- /// moved. Returns nullptr if the movement is not possible, or not worth it.
- Instruction *canBeMovedDownwards(CallInst &RuntimeCall) {
- // FIXME: This traverses only the BasicBlock where RuntimeCall is.
- // Make it traverse the CFG.
-
- Instruction *CurrentI = &RuntimeCall;
- bool IsWorthIt = false;
- while ((CurrentI = CurrentI->getNextNode())) {
-
- // TODO: Once we detect the regions to be offloaded we should use the
- // alias analysis manager to check if CurrentI may modify one of
- // the offloaded regions.
- if (CurrentI->mayHaveSideEffects() || CurrentI->mayReadFromMemory()) {
- if (IsWorthIt)
- return CurrentI;
-
- return nullptr;
- }
-
- // FIXME: For now if we move it over anything without side effect
- // is worth it.
- IsWorthIt = true;
- }
-
- // Return end of BasicBlock.
- return RuntimeCall.getParent()->getTerminator();
- }
-
- /// Splits \p RuntimeCall into its "issue" and "wait" counterparts.
- bool splitTargetDataBeginRTC(CallInst &RuntimeCall,
- Instruction &WaitMovementPoint) {
- // Create stack allocated handle (__tgt_async_info) at the beginning of the
- // function. Used for storing information of the async transfer, allowing to
- // wait on it later.
- auto &IRBuilder = OMPInfoCache.OMPBuilder;
- auto *F = RuntimeCall.getCaller();
- Instruction *FirstInst = &(F->getEntryBlock().front());
- AllocaInst *Handle = new AllocaInst(
- IRBuilder.AsyncInfo, F->getAddressSpace(), "handle", FirstInst);
-
- // Add "issue" runtime call declaration:
- // declare %struct.tgt_async_info @__tgt_target_data_begin_issue(i64, i32,
- // i8**, i8**, i64*, i64*)
- FunctionCallee IssueDecl = IRBuilder.getOrCreateRuntimeFunction(
- M, OMPRTL___tgt_target_data_begin_mapper_issue);
-
- // Change RuntimeCall call site for its asynchronous version.
- SmallVector<Value *, 16> Args;
- for (auto &Arg : RuntimeCall.args())
- Args.push_back(Arg.get());
- Args.push_back(Handle);
-
- CallInst *IssueCallsite =
- CallInst::Create(IssueDecl, Args, /*NameStr=*/"", &RuntimeCall);
- RuntimeCall.eraseFromParent();
-
- // Add "wait" runtime call declaration:
- // declare void @__tgt_target_data_begin_wait(i64, %struct.__tgt_async_info)
- FunctionCallee WaitDecl = IRBuilder.getOrCreateRuntimeFunction(
- M, OMPRTL___tgt_target_data_begin_mapper_wait);
-
- Value *WaitParams[2] = {
- IssueCallsite->getArgOperand(
- OffloadArray::DeviceIDArgNum), // device_id.
- Handle // handle to wait on.
- };
- CallInst::Create(WaitDecl, WaitParams, /*NameStr=*/"", &WaitMovementPoint);
-
- return true;
- }
-
+ /// Tries to hide the latency of runtime calls that involve host to
+ /// device memory transfers by splitting them into their "issue" and "wait"
+ /// versions. The "issue" is moved upwards as much as possible. The "wait" is
+ /// moved downards as much as possible. The "issue" issues the memory transfer
+ /// asynchronously, returning a handle. The "wait" waits in the returned
+ /// handle for the memory transfer to finish.
+ bool hideMemTransfersLatency() {
+ auto &RFI = OMPInfoCache.RFIs[OMPRTL___tgt_target_data_begin_mapper];
+ bool Changed = false;
+ auto SplitMemTransfers = [&](Use &U, Function &Decl) {
+ auto *RTCall = getCallIfRegularCall(U, &RFI);
+ if (!RTCall)
+ return false;
+
+ OffloadArray OffloadArrays[3];
+ if (!getValuesInOffloadArrays(*RTCall, OffloadArrays))
+ return false;
+
+ LLVM_DEBUG(dumpValuesInOffloadArrays(OffloadArrays));
+
+ // TODO: Check if can be moved upwards.
+ bool WasSplit = false;
+ Instruction *WaitMovementPoint = canBeMovedDownwards(*RTCall);
+ if (WaitMovementPoint)
+ WasSplit = splitTargetDataBeginRTC(*RTCall, *WaitMovementPoint);
+
+ Changed |= WasSplit;
+ return WasSplit;
+ };
+ RFI.foreachUse(SCC, SplitMemTransfers);
+
+ return Changed;
+ }
+
+ void analysisGlobalization() {
+ RuntimeFunction GlobalizationRuntimeIDs[] = {
+ OMPRTL___kmpc_data_sharing_coalesced_push_stack,
+ OMPRTL___kmpc_data_sharing_push_stack};
+
+ for (const auto GlobalizationCallID : GlobalizationRuntimeIDs) {
+ auto &RFI = OMPInfoCache.RFIs[GlobalizationCallID];
+
+ auto CheckGlobalization = [&](Use &U, Function &Decl) {
+ if (CallInst *CI = getCallIfRegularCall(U, &RFI)) {
+ auto Remark = [&](OptimizationRemarkAnalysis ORA) {
+ return ORA
+ << "Found thread data sharing on the GPU. "
+ << "Expect degraded performance due to data globalization.";
+ };
+ emitRemark<OptimizationRemarkAnalysis>(CI, "OpenMPGlobalization",
+ Remark);
+ }
+
+ return false;
+ };
+
+ RFI.foreachUse(SCC, CheckGlobalization);
+ }
+ }
+
+ /// Maps the values stored in the offload arrays passed as arguments to
+ /// \p RuntimeCall into the offload arrays in \p OAs.
+ bool getValuesInOffloadArrays(CallInst &RuntimeCall,
+ MutableArrayRef<OffloadArray> OAs) {
+ assert(OAs.size() == 3 && "Need space for three offload arrays!");
+
+ // A runtime call that involves memory offloading looks something like:
+ // call void @__tgt_target_data_begin_mapper(arg0, arg1,
+ // i8** %offload_baseptrs, i8** %offload_ptrs, i64* %offload_sizes,
+ // ...)
+ // So, the idea is to access the allocas that allocate space for these
+ // offload arrays, offload_baseptrs, offload_ptrs, offload_sizes.
+ // Therefore:
+ // i8** %offload_baseptrs.
+ Value *BasePtrsArg =
+ RuntimeCall.getArgOperand(OffloadArray::BasePtrsArgNum);
+ // i8** %offload_ptrs.
+ Value *PtrsArg = RuntimeCall.getArgOperand(OffloadArray::PtrsArgNum);
+ // i8** %offload_sizes.
+ Value *SizesArg = RuntimeCall.getArgOperand(OffloadArray::SizesArgNum);
+
+ // Get values stored in **offload_baseptrs.
+ auto *V = getUnderlyingObject(BasePtrsArg);
+ if (!isa<AllocaInst>(V))
+ return false;
+ auto *BasePtrsArray = cast<AllocaInst>(V);
+ if (!OAs[0].initialize(*BasePtrsArray, RuntimeCall))
+ return false;
+
+ // Get values stored in **offload_baseptrs.
+ V = getUnderlyingObject(PtrsArg);
+ if (!isa<AllocaInst>(V))
+ return false;
+ auto *PtrsArray = cast<AllocaInst>(V);
+ if (!OAs[1].initialize(*PtrsArray, RuntimeCall))
+ return false;
+
+ // Get values stored in **offload_sizes.
+ V = getUnderlyingObject(SizesArg);
+ // If it's a [constant] global array don't analyze it.
+ if (isa<GlobalValue>(V))
+ return isa<Constant>(V);
+ if (!isa<AllocaInst>(V))
+ return false;
+
+ auto *SizesArray = cast<AllocaInst>(V);
+ if (!OAs[2].initialize(*SizesArray, RuntimeCall))
+ return false;
+
+ return true;
+ }
+
+ /// Prints the values in the OffloadArrays \p OAs using LLVM_DEBUG.
+ /// For now this is a way to test that the function getValuesInOffloadArrays
+ /// is working properly.
+ /// TODO: Move this to a unittest when unittests are available for OpenMPOpt.
+ void dumpValuesInOffloadArrays(ArrayRef<OffloadArray> OAs) {
+ assert(OAs.size() == 3 && "There are three offload arrays to debug!");
+
+ LLVM_DEBUG(dbgs() << TAG << " Successfully got offload values:\n");
+ std::string ValuesStr;
+ raw_string_ostream Printer(ValuesStr);
+ std::string Separator = " --- ";
+
+ for (auto *BP : OAs[0].StoredValues) {
+ BP->print(Printer);
+ Printer << Separator;
+ }
+ LLVM_DEBUG(dbgs() << "\t\toffload_baseptrs: " << Printer.str() << "\n");
+ ValuesStr.clear();
+
+ for (auto *P : OAs[1].StoredValues) {
+ P->print(Printer);
+ Printer << Separator;
+ }
+ LLVM_DEBUG(dbgs() << "\t\toffload_ptrs: " << Printer.str() << "\n");
+ ValuesStr.clear();
+
+ for (auto *S : OAs[2].StoredValues) {
+ S->print(Printer);
+ Printer << Separator;
+ }
+ LLVM_DEBUG(dbgs() << "\t\toffload_sizes: " << Printer.str() << "\n");
+ }
+
+ /// Returns the instruction where the "wait" counterpart \p RuntimeCall can be
+ /// moved. Returns nullptr if the movement is not possible, or not worth it.
+ Instruction *canBeMovedDownwards(CallInst &RuntimeCall) {
+ // FIXME: This traverses only the BasicBlock where RuntimeCall is.
+ // Make it traverse the CFG.
+
+ Instruction *CurrentI = &RuntimeCall;
+ bool IsWorthIt = false;
+ while ((CurrentI = CurrentI->getNextNode())) {
+
+ // TODO: Once we detect the regions to be offloaded we should use the
+ // alias analysis manager to check if CurrentI may modify one of
+ // the offloaded regions.
+ if (CurrentI->mayHaveSideEffects() || CurrentI->mayReadFromMemory()) {
+ if (IsWorthIt)
+ return CurrentI;
+
+ return nullptr;
+ }
+
+ // FIXME: For now if we move it over anything without side effect
+ // is worth it.
+ IsWorthIt = true;
+ }
+
+ // Return end of BasicBlock.
+ return RuntimeCall.getParent()->getTerminator();
+ }
+
+ /// Splits \p RuntimeCall into its "issue" and "wait" counterparts.
+ bool splitTargetDataBeginRTC(CallInst &RuntimeCall,
+ Instruction &WaitMovementPoint) {
+ // Create stack allocated handle (__tgt_async_info) at the beginning of the
+ // function. Used for storing information of the async transfer, allowing to
+ // wait on it later.
+ auto &IRBuilder = OMPInfoCache.OMPBuilder;
+ auto *F = RuntimeCall.getCaller();
+ Instruction *FirstInst = &(F->getEntryBlock().front());
+ AllocaInst *Handle = new AllocaInst(
+ IRBuilder.AsyncInfo, F->getAddressSpace(), "handle", FirstInst);
+
+ // Add "issue" runtime call declaration:
+ // declare %struct.tgt_async_info @__tgt_target_data_begin_issue(i64, i32,
+ // i8**, i8**, i64*, i64*)
+ FunctionCallee IssueDecl = IRBuilder.getOrCreateRuntimeFunction(
+ M, OMPRTL___tgt_target_data_begin_mapper_issue);
+
+ // Change RuntimeCall call site for its asynchronous version.
+ SmallVector<Value *, 16> Args;
+ for (auto &Arg : RuntimeCall.args())
+ Args.push_back(Arg.get());
+ Args.push_back(Handle);
+
+ CallInst *IssueCallsite =
+ CallInst::Create(IssueDecl, Args, /*NameStr=*/"", &RuntimeCall);
+ RuntimeCall.eraseFromParent();
+
+ // Add "wait" runtime call declaration:
+ // declare void @__tgt_target_data_begin_wait(i64, %struct.__tgt_async_info)
+ FunctionCallee WaitDecl = IRBuilder.getOrCreateRuntimeFunction(
+ M, OMPRTL___tgt_target_data_begin_mapper_wait);
+
+ Value *WaitParams[2] = {
+ IssueCallsite->getArgOperand(
+ OffloadArray::DeviceIDArgNum), // device_id.
+ Handle // handle to wait on.
+ };
+ CallInst::Create(WaitDecl, WaitParams, /*NameStr=*/"", &WaitMovementPoint);
+
+ return true;
+ }
+
static Value *combinedIdentStruct(Value *CurrentIdent, Value *NextIdent,
bool GlobalOnly, bool &SingleChoice) {
if (CurrentIdent == NextIdent)
@@ -1578,28 +1578,28 @@ private:
/// Populate the Attributor with abstract attribute opportunities in the
/// function.
void registerAAs() {
- if (SCC.empty())
- return;
-
- // Create CallSite AA for all Getters.
- for (int Idx = 0; Idx < OMPInfoCache.ICVs.size() - 1; ++Idx) {
- auto ICVInfo = OMPInfoCache.ICVs[static_cast<InternalControlVar>(Idx)];
-
- auto &GetterRFI = OMPInfoCache.RFIs[ICVInfo.Getter];
-
- auto CreateAA = [&](Use &U, Function &Caller) {
- CallInst *CI = OpenMPOpt::getCallIfRegularCall(U, &GetterRFI);
- if (!CI)
- return false;
-
- auto &CB = cast<CallBase>(*CI);
-
- IRPosition CBPos = IRPosition::callsite_function(CB);
- A.getOrCreateAAFor<AAICVTracker>(CBPos);
- return false;
- };
-
- GetterRFI.foreachUse(SCC, CreateAA);
+ if (SCC.empty())
+ return;
+
+ // Create CallSite AA for all Getters.
+ for (int Idx = 0; Idx < OMPInfoCache.ICVs.size() - 1; ++Idx) {
+ auto ICVInfo = OMPInfoCache.ICVs[static_cast<InternalControlVar>(Idx)];
+
+ auto &GetterRFI = OMPInfoCache.RFIs[ICVInfo.Getter];
+
+ auto CreateAA = [&](Use &U, Function &Caller) {
+ CallInst *CI = OpenMPOpt::getCallIfRegularCall(U, &GetterRFI);
+ if (!CI)
+ return false;
+
+ auto &CB = cast<CallBase>(*CI);
+
+ IRPosition CBPos = IRPosition::callsite_function(CB);
+ A.getOrCreateAAFor<AAICVTracker>(CBPos);
+ return false;
+ };
+
+ GetterRFI.foreachUse(SCC, CreateAA);
}
}
};
@@ -1623,16 +1623,16 @@ Kernel OpenMPOpt::getUniqueKernelFor(Function &F) {
}
CachedKernel = nullptr;
- if (!F.hasLocalLinkage()) {
-
- // See https://openmp.llvm.org/remarks/OptimizationRemarks.html
- auto Remark = [&](OptimizationRemark OR) {
- return OR << "[OMP100] Potentially unknown OpenMP target region caller";
- };
- emitRemarkOnFunction(&F, "OMP100", Remark);
-
+ if (!F.hasLocalLinkage()) {
+
+ // See https://openmp.llvm.org/remarks/OptimizationRemarks.html
+ auto Remark = [&](OptimizationRemark OR) {
+ return OR << "[OMP100] Potentially unknown OpenMP target region caller";
+ };
+ emitRemarkOnFunction(&F, "OMP100", Remark);
+
return nullptr;
- }
+ }
}
auto GetUniqueKernelForUse = [&](const Use &U) -> Kernel {
@@ -1658,7 +1658,7 @@ Kernel OpenMPOpt::getUniqueKernelFor(Function &F) {
// TODO: In the future we want to track more than just a unique kernel.
SmallPtrSet<Kernel, 2> PotentialKernels;
- OMPInformationCache::foreachUse(F, [&](const Use &U) {
+ OMPInformationCache::foreachUse(F, [&](const Use &U) {
PotentialKernels.insert(GetUniqueKernelForUse(U));
});
@@ -1689,7 +1689,7 @@ bool OpenMPOpt::rewriteDeviceCodeStateMachine() {
unsigned NumDirectCalls = 0;
SmallVector<Use *, 2> ToBeReplacedStateMachineUses;
- OMPInformationCache::foreachUse(*F, [&](Use &U) {
+ OMPInformationCache::foreachUse(*F, [&](Use &U) {
if (auto *CB = dyn_cast<CallBase>(U.getUser()))
if (CB->isCallee(&U)) {
++NumDirectCalls;
@@ -1809,12 +1809,12 @@ struct AAICVTracker : public StateWrapper<BooleanState, AbstractAttribute> {
using Base = StateWrapper<BooleanState, AbstractAttribute>;
AAICVTracker(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
- void initialize(Attributor &A) override {
- Function *F = getAnchorScope();
- if (!F || !A.isFunctionIPOAmendable(*F))
- indicatePessimisticFixpoint();
- }
-
+ void initialize(Attributor &A) override {
+ Function *F = getAnchorScope();
+ if (!F || !A.isFunctionIPOAmendable(*F))
+ indicatePessimisticFixpoint();
+ }
+
/// Returns true if value is assumed to be tracked.
bool isAssumedTracked() const { return getAssumed(); }
@@ -1825,22 +1825,22 @@ struct AAICVTracker : public StateWrapper<BooleanState, AbstractAttribute> {
static AAICVTracker &createForPosition(const IRPosition &IRP, Attributor &A);
/// Return the value with which \p I can be replaced for specific \p ICV.
- virtual Optional<Value *> getReplacementValue(InternalControlVar ICV,
- const Instruction *I,
- Attributor &A) const {
- return None;
- }
-
- /// Return an assumed unique ICV value if a single candidate is found. If
- /// there cannot be one, return a nullptr. If it is not clear yet, return the
- /// Optional::NoneType.
- virtual Optional<Value *>
- getUniqueReplacementValue(InternalControlVar ICV) const = 0;
-
- // Currently only nthreads is being tracked.
- // this array will only grow with time.
- InternalControlVar TrackableICVs[1] = {ICV_nthreads};
-
+ virtual Optional<Value *> getReplacementValue(InternalControlVar ICV,
+ const Instruction *I,
+ Attributor &A) const {
+ return None;
+ }
+
+ /// Return an assumed unique ICV value if a single candidate is found. If
+ /// there cannot be one, return a nullptr. If it is not clear yet, return the
+ /// Optional::NoneType.
+ virtual Optional<Value *>
+ getUniqueReplacementValue(InternalControlVar ICV) const = 0;
+
+ // Currently only nthreads is being tracked.
+ // this array will only grow with time.
+ InternalControlVar TrackableICVs[1] = {ICV_nthreads};
+
/// See AbstractAttribute::getName()
const std::string getName() const override { return "AAICVTracker"; }
@@ -1860,20 +1860,20 @@ struct AAICVTrackerFunction : public AAICVTracker {
: AAICVTracker(IRP, A) {}
// FIXME: come up with better string.
- const std::string getAsStr() const override { return "ICVTrackerFunction"; }
+ const std::string getAsStr() const override { return "ICVTrackerFunction"; }
// FIXME: come up with some stats.
void trackStatistics() const override {}
- /// We don't manifest anything for this AA.
+ /// We don't manifest anything for this AA.
ChangeStatus manifest(Attributor &A) override {
- return ChangeStatus::UNCHANGED;
+ return ChangeStatus::UNCHANGED;
}
// Map of ICV to their values at specific program point.
- EnumeratedArray<DenseMap<Instruction *, Value *>, InternalControlVar,
+ EnumeratedArray<DenseMap<Instruction *, Value *>, InternalControlVar,
InternalControlVar::ICV___last>
- ICVReplacementValuesMap;
+ ICVReplacementValuesMap;
ChangeStatus updateImpl(Attributor &A) override {
ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
@@ -1885,7 +1885,7 @@ struct AAICVTrackerFunction : public AAICVTracker {
for (InternalControlVar ICV : TrackableICVs) {
auto &SetterRFI = OMPInfoCache.RFIs[OMPInfoCache.ICVs[ICV].Setter];
- auto &ValuesMap = ICVReplacementValuesMap[ICV];
+ auto &ValuesMap = ICVReplacementValuesMap[ICV];
auto TrackValues = [&](Use &U, Function &) {
CallInst *CI = OpenMPOpt::getCallIfRegularCall(U);
if (!CI)
@@ -1893,344 +1893,344 @@ struct AAICVTrackerFunction : public AAICVTracker {
// FIXME: handle setters with more that 1 arguments.
/// Track new value.
- if (ValuesMap.insert(std::make_pair(CI, CI->getArgOperand(0))).second)
+ if (ValuesMap.insert(std::make_pair(CI, CI->getArgOperand(0))).second)
HasChanged = ChangeStatus::CHANGED;
return false;
};
- auto CallCheck = [&](Instruction &I) {
- Optional<Value *> ReplVal = getValueForCall(A, &I, ICV);
- if (ReplVal.hasValue() &&
- ValuesMap.insert(std::make_pair(&I, *ReplVal)).second)
- HasChanged = ChangeStatus::CHANGED;
-
- return true;
- };
-
- // Track all changes of an ICV.
+ auto CallCheck = [&](Instruction &I) {
+ Optional<Value *> ReplVal = getValueForCall(A, &I, ICV);
+ if (ReplVal.hasValue() &&
+ ValuesMap.insert(std::make_pair(&I, *ReplVal)).second)
+ HasChanged = ChangeStatus::CHANGED;
+
+ return true;
+ };
+
+ // Track all changes of an ICV.
SetterRFI.foreachUse(TrackValues, F);
-
- A.checkForAllInstructions(CallCheck, *this, {Instruction::Call},
- /* CheckBBLivenessOnly */ true);
-
- /// TODO: Figure out a way to avoid adding entry in
- /// ICVReplacementValuesMap
- Instruction *Entry = &F->getEntryBlock().front();
- if (HasChanged == ChangeStatus::CHANGED && !ValuesMap.count(Entry))
- ValuesMap.insert(std::make_pair(Entry, nullptr));
+
+ A.checkForAllInstructions(CallCheck, *this, {Instruction::Call},
+ /* CheckBBLivenessOnly */ true);
+
+ /// TODO: Figure out a way to avoid adding entry in
+ /// ICVReplacementValuesMap
+ Instruction *Entry = &F->getEntryBlock().front();
+ if (HasChanged == ChangeStatus::CHANGED && !ValuesMap.count(Entry))
+ ValuesMap.insert(std::make_pair(Entry, nullptr));
}
return HasChanged;
}
- /// Hepler to check if \p I is a call and get the value for it if it is
- /// unique.
- Optional<Value *> getValueForCall(Attributor &A, const Instruction *I,
- InternalControlVar &ICV) const {
+ /// Hepler to check if \p I is a call and get the value for it if it is
+ /// unique.
+ Optional<Value *> getValueForCall(Attributor &A, const Instruction *I,
+ InternalControlVar &ICV) const {
+
+ const auto *CB = dyn_cast<CallBase>(I);
+ if (!CB || CB->hasFnAttr("no_openmp") ||
+ CB->hasFnAttr("no_openmp_routines"))
+ return None;
- const auto *CB = dyn_cast<CallBase>(I);
- if (!CB || CB->hasFnAttr("no_openmp") ||
- CB->hasFnAttr("no_openmp_routines"))
- return None;
-
auto &OMPInfoCache = static_cast<OMPInformationCache &>(A.getInfoCache());
auto &GetterRFI = OMPInfoCache.RFIs[OMPInfoCache.ICVs[ICV].Getter];
- auto &SetterRFI = OMPInfoCache.RFIs[OMPInfoCache.ICVs[ICV].Setter];
- Function *CalledFunction = CB->getCalledFunction();
-
- // Indirect call, assume ICV changes.
- if (CalledFunction == nullptr)
- return nullptr;
- if (CalledFunction == GetterRFI.Declaration)
- return None;
- if (CalledFunction == SetterRFI.Declaration) {
- if (ICVReplacementValuesMap[ICV].count(I))
- return ICVReplacementValuesMap[ICV].lookup(I);
-
- return nullptr;
- }
-
- // Since we don't know, assume it changes the ICV.
- if (CalledFunction->isDeclaration())
- return nullptr;
-
- const auto &ICVTrackingAA =
- A.getAAFor<AAICVTracker>(*this, IRPosition::callsite_returned(*CB));
-
- if (ICVTrackingAA.isAssumedTracked())
- return ICVTrackingAA.getUniqueReplacementValue(ICV);
-
- // If we don't know, assume it changes.
- return nullptr;
- }
-
- // We don't check unique value for a function, so return None.
- Optional<Value *>
- getUniqueReplacementValue(InternalControlVar ICV) const override {
- return None;
- }
-
- /// Return the value with which \p I can be replaced for specific \p ICV.
- Optional<Value *> getReplacementValue(InternalControlVar ICV,
- const Instruction *I,
- Attributor &A) const override {
- const auto &ValuesMap = ICVReplacementValuesMap[ICV];
- if (ValuesMap.count(I))
- return ValuesMap.lookup(I);
-
- SmallVector<const Instruction *, 16> Worklist;
- SmallPtrSet<const Instruction *, 16> Visited;
- Worklist.push_back(I);
-
- Optional<Value *> ReplVal;
-
- while (!Worklist.empty()) {
- const Instruction *CurrInst = Worklist.pop_back_val();
- if (!Visited.insert(CurrInst).second)
- continue;
-
- const BasicBlock *CurrBB = CurrInst->getParent();
-
- // Go up and look for all potential setters/calls that might change the
- // ICV.
- while ((CurrInst = CurrInst->getPrevNode())) {
- if (ValuesMap.count(CurrInst)) {
- Optional<Value *> NewReplVal = ValuesMap.lookup(CurrInst);
- // Unknown value, track new.
- if (!ReplVal.hasValue()) {
- ReplVal = NewReplVal;
- break;
- }
-
- // If we found a new value, we can't know the icv value anymore.
- if (NewReplVal.hasValue())
- if (ReplVal != NewReplVal)
+ auto &SetterRFI = OMPInfoCache.RFIs[OMPInfoCache.ICVs[ICV].Setter];
+ Function *CalledFunction = CB->getCalledFunction();
+
+ // Indirect call, assume ICV changes.
+ if (CalledFunction == nullptr)
+ return nullptr;
+ if (CalledFunction == GetterRFI.Declaration)
+ return None;
+ if (CalledFunction == SetterRFI.Declaration) {
+ if (ICVReplacementValuesMap[ICV].count(I))
+ return ICVReplacementValuesMap[ICV].lookup(I);
+
+ return nullptr;
+ }
+
+ // Since we don't know, assume it changes the ICV.
+ if (CalledFunction->isDeclaration())
+ return nullptr;
+
+ const auto &ICVTrackingAA =
+ A.getAAFor<AAICVTracker>(*this, IRPosition::callsite_returned(*CB));
+
+ if (ICVTrackingAA.isAssumedTracked())
+ return ICVTrackingAA.getUniqueReplacementValue(ICV);
+
+ // If we don't know, assume it changes.
+ return nullptr;
+ }
+
+ // We don't check unique value for a function, so return None.
+ Optional<Value *>
+ getUniqueReplacementValue(InternalControlVar ICV) const override {
+ return None;
+ }
+
+ /// Return the value with which \p I can be replaced for specific \p ICV.
+ Optional<Value *> getReplacementValue(InternalControlVar ICV,
+ const Instruction *I,
+ Attributor &A) const override {
+ const auto &ValuesMap = ICVReplacementValuesMap[ICV];
+ if (ValuesMap.count(I))
+ return ValuesMap.lookup(I);
+
+ SmallVector<const Instruction *, 16> Worklist;
+ SmallPtrSet<const Instruction *, 16> Visited;
+ Worklist.push_back(I);
+
+ Optional<Value *> ReplVal;
+
+ while (!Worklist.empty()) {
+ const Instruction *CurrInst = Worklist.pop_back_val();
+ if (!Visited.insert(CurrInst).second)
+ continue;
+
+ const BasicBlock *CurrBB = CurrInst->getParent();
+
+ // Go up and look for all potential setters/calls that might change the
+ // ICV.
+ while ((CurrInst = CurrInst->getPrevNode())) {
+ if (ValuesMap.count(CurrInst)) {
+ Optional<Value *> NewReplVal = ValuesMap.lookup(CurrInst);
+ // Unknown value, track new.
+ if (!ReplVal.hasValue()) {
+ ReplVal = NewReplVal;
+ break;
+ }
+
+ // If we found a new value, we can't know the icv value anymore.
+ if (NewReplVal.hasValue())
+ if (ReplVal != NewReplVal)
return nullptr;
- break;
+ break;
}
- Optional<Value *> NewReplVal = getValueForCall(A, CurrInst, ICV);
- if (!NewReplVal.hasValue())
- continue;
-
- // Unknown value, track new.
- if (!ReplVal.hasValue()) {
- ReplVal = NewReplVal;
- break;
- }
-
- // if (NewReplVal.hasValue())
- // We found a new value, we can't know the icv value anymore.
- if (ReplVal != NewReplVal)
- return nullptr;
+ Optional<Value *> NewReplVal = getValueForCall(A, CurrInst, ICV);
+ if (!NewReplVal.hasValue())
+ continue;
+
+ // Unknown value, track new.
+ if (!ReplVal.hasValue()) {
+ ReplVal = NewReplVal;
+ break;
+ }
+
+ // if (NewReplVal.hasValue())
+ // We found a new value, we can't know the icv value anymore.
+ if (ReplVal != NewReplVal)
+ return nullptr;
}
-
- // If we are in the same BB and we have a value, we are done.
- if (CurrBB == I->getParent() && ReplVal.hasValue())
- return ReplVal;
-
- // Go through all predecessors and add terminators for analysis.
- for (const BasicBlock *Pred : predecessors(CurrBB))
- if (const Instruction *Terminator = Pred->getTerminator())
- Worklist.push_back(Terminator);
+
+ // If we are in the same BB and we have a value, we are done.
+ if (CurrBB == I->getParent() && ReplVal.hasValue())
+ return ReplVal;
+
+ // Go through all predecessors and add terminators for analysis.
+ for (const BasicBlock *Pred : predecessors(CurrBB))
+ if (const Instruction *Terminator = Pred->getTerminator())
+ Worklist.push_back(Terminator);
}
- return ReplVal;
+ return ReplVal;
+ }
+};
+
+struct AAICVTrackerFunctionReturned : AAICVTracker {
+ AAICVTrackerFunctionReturned(const IRPosition &IRP, Attributor &A)
+ : AAICVTracker(IRP, A) {}
+
+ // FIXME: come up with better string.
+ const std::string getAsStr() const override {
+ return "ICVTrackerFunctionReturned";
+ }
+
+ // FIXME: come up with some stats.
+ void trackStatistics() const override {}
+
+ /// We don't manifest anything for this AA.
+ ChangeStatus manifest(Attributor &A) override {
+ return ChangeStatus::UNCHANGED;
+ }
+
+ // Map of ICV to their values at specific program point.
+ EnumeratedArray<Optional<Value *>, InternalControlVar,
+ InternalControlVar::ICV___last>
+ ICVReplacementValuesMap;
+
+ /// Return the value with which \p I can be replaced for specific \p ICV.
+ Optional<Value *>
+ getUniqueReplacementValue(InternalControlVar ICV) const override {
+ return ICVReplacementValuesMap[ICV];
+ }
+
+ ChangeStatus updateImpl(Attributor &A) override {
+ ChangeStatus Changed = ChangeStatus::UNCHANGED;
+ const auto &ICVTrackingAA = A.getAAFor<AAICVTracker>(
+ *this, IRPosition::function(*getAnchorScope()));
+
+ if (!ICVTrackingAA.isAssumedTracked())
+ return indicatePessimisticFixpoint();
+
+ for (InternalControlVar ICV : TrackableICVs) {
+ Optional<Value *> &ReplVal = ICVReplacementValuesMap[ICV];
+ Optional<Value *> UniqueICVValue;
+
+ auto CheckReturnInst = [&](Instruction &I) {
+ Optional<Value *> NewReplVal =
+ ICVTrackingAA.getReplacementValue(ICV, &I, A);
+
+ // If we found a second ICV value there is no unique returned value.
+ if (UniqueICVValue.hasValue() && UniqueICVValue != NewReplVal)
+ return false;
+
+ UniqueICVValue = NewReplVal;
+
+ return true;
+ };
+
+ if (!A.checkForAllInstructions(CheckReturnInst, *this, {Instruction::Ret},
+ /* CheckBBLivenessOnly */ true))
+ UniqueICVValue = nullptr;
+
+ if (UniqueICVValue == ReplVal)
+ continue;
+
+ ReplVal = UniqueICVValue;
+ Changed = ChangeStatus::CHANGED;
+ }
+
+ return Changed;
+ }
+};
+
+struct AAICVTrackerCallSite : AAICVTracker {
+ AAICVTrackerCallSite(const IRPosition &IRP, Attributor &A)
+ : AAICVTracker(IRP, A) {}
+
+ void initialize(Attributor &A) override {
+ Function *F = getAnchorScope();
+ if (!F || !A.isFunctionIPOAmendable(*F))
+ indicatePessimisticFixpoint();
+
+ // We only initialize this AA for getters, so we need to know which ICV it
+ // gets.
+ auto &OMPInfoCache = static_cast<OMPInformationCache &>(A.getInfoCache());
+ for (InternalControlVar ICV : TrackableICVs) {
+ auto ICVInfo = OMPInfoCache.ICVs[ICV];
+ auto &Getter = OMPInfoCache.RFIs[ICVInfo.Getter];
+ if (Getter.Declaration == getAssociatedFunction()) {
+ AssociatedICV = ICVInfo.Kind;
+ return;
+ }
+ }
+
+ /// Unknown ICV.
+ indicatePessimisticFixpoint();
+ }
+
+ ChangeStatus manifest(Attributor &A) override {
+ if (!ReplVal.hasValue() || !ReplVal.getValue())
+ return ChangeStatus::UNCHANGED;
+
+ A.changeValueAfterManifest(*getCtxI(), **ReplVal);
+ A.deleteAfterManifest(*getCtxI());
+
+ return ChangeStatus::CHANGED;
+ }
+
+ // FIXME: come up with better string.
+ const std::string getAsStr() const override { return "ICVTrackerCallSite"; }
+
+ // FIXME: come up with some stats.
+ void trackStatistics() const override {}
+
+ InternalControlVar AssociatedICV;
+ Optional<Value *> ReplVal;
+
+ ChangeStatus updateImpl(Attributor &A) override {
+ const auto &ICVTrackingAA = A.getAAFor<AAICVTracker>(
+ *this, IRPosition::function(*getAnchorScope()));
+
+ // We don't have any information, so we assume it changes the ICV.
+ if (!ICVTrackingAA.isAssumedTracked())
+ return indicatePessimisticFixpoint();
+
+ Optional<Value *> NewReplVal =
+ ICVTrackingAA.getReplacementValue(AssociatedICV, getCtxI(), A);
+
+ if (ReplVal == NewReplVal)
+ return ChangeStatus::UNCHANGED;
+
+ ReplVal = NewReplVal;
+ return ChangeStatus::CHANGED;
+ }
+
+ // Return the value with which associated value can be replaced for specific
+ // \p ICV.
+ Optional<Value *>
+ getUniqueReplacementValue(InternalControlVar ICV) const override {
+ return ReplVal;
+ }
+};
+
+struct AAICVTrackerCallSiteReturned : AAICVTracker {
+ AAICVTrackerCallSiteReturned(const IRPosition &IRP, Attributor &A)
+ : AAICVTracker(IRP, A) {}
+
+ // FIXME: come up with better string.
+ const std::string getAsStr() const override {
+ return "ICVTrackerCallSiteReturned";
+ }
+
+ // FIXME: come up with some stats.
+ void trackStatistics() const override {}
+
+ /// We don't manifest anything for this AA.
+ ChangeStatus manifest(Attributor &A) override {
+ return ChangeStatus::UNCHANGED;
+ }
+
+ // Map of ICV to their values at specific program point.
+ EnumeratedArray<Optional<Value *>, InternalControlVar,
+ InternalControlVar::ICV___last>
+ ICVReplacementValuesMap;
+
+ /// Return the value with which associated value can be replaced for specific
+ /// \p ICV.
+ Optional<Value *>
+ getUniqueReplacementValue(InternalControlVar ICV) const override {
+ return ICVReplacementValuesMap[ICV];
+ }
+
+ ChangeStatus updateImpl(Attributor &A) override {
+ ChangeStatus Changed = ChangeStatus::UNCHANGED;
+ const auto &ICVTrackingAA = A.getAAFor<AAICVTracker>(
+ *this, IRPosition::returned(*getAssociatedFunction()));
+
+ // We don't have any information, so we assume it changes the ICV.
+ if (!ICVTrackingAA.isAssumedTracked())
+ return indicatePessimisticFixpoint();
+
+ for (InternalControlVar ICV : TrackableICVs) {
+ Optional<Value *> &ReplVal = ICVReplacementValuesMap[ICV];
+ Optional<Value *> NewReplVal =
+ ICVTrackingAA.getUniqueReplacementValue(ICV);
+
+ if (ReplVal == NewReplVal)
+ continue;
+
+ ReplVal = NewReplVal;
+ Changed = ChangeStatus::CHANGED;
+ }
+ return Changed;
}
};
-
-struct AAICVTrackerFunctionReturned : AAICVTracker {
- AAICVTrackerFunctionReturned(const IRPosition &IRP, Attributor &A)
- : AAICVTracker(IRP, A) {}
-
- // FIXME: come up with better string.
- const std::string getAsStr() const override {
- return "ICVTrackerFunctionReturned";
- }
-
- // FIXME: come up with some stats.
- void trackStatistics() const override {}
-
- /// We don't manifest anything for this AA.
- ChangeStatus manifest(Attributor &A) override {
- return ChangeStatus::UNCHANGED;
- }
-
- // Map of ICV to their values at specific program point.
- EnumeratedArray<Optional<Value *>, InternalControlVar,
- InternalControlVar::ICV___last>
- ICVReplacementValuesMap;
-
- /// Return the value with which \p I can be replaced for specific \p ICV.
- Optional<Value *>
- getUniqueReplacementValue(InternalControlVar ICV) const override {
- return ICVReplacementValuesMap[ICV];
- }
-
- ChangeStatus updateImpl(Attributor &A) override {
- ChangeStatus Changed = ChangeStatus::UNCHANGED;
- const auto &ICVTrackingAA = A.getAAFor<AAICVTracker>(
- *this, IRPosition::function(*getAnchorScope()));
-
- if (!ICVTrackingAA.isAssumedTracked())
- return indicatePessimisticFixpoint();
-
- for (InternalControlVar ICV : TrackableICVs) {
- Optional<Value *> &ReplVal = ICVReplacementValuesMap[ICV];
- Optional<Value *> UniqueICVValue;
-
- auto CheckReturnInst = [&](Instruction &I) {
- Optional<Value *> NewReplVal =
- ICVTrackingAA.getReplacementValue(ICV, &I, A);
-
- // If we found a second ICV value there is no unique returned value.
- if (UniqueICVValue.hasValue() && UniqueICVValue != NewReplVal)
- return false;
-
- UniqueICVValue = NewReplVal;
-
- return true;
- };
-
- if (!A.checkForAllInstructions(CheckReturnInst, *this, {Instruction::Ret},
- /* CheckBBLivenessOnly */ true))
- UniqueICVValue = nullptr;
-
- if (UniqueICVValue == ReplVal)
- continue;
-
- ReplVal = UniqueICVValue;
- Changed = ChangeStatus::CHANGED;
- }
-
- return Changed;
- }
-};
-
-struct AAICVTrackerCallSite : AAICVTracker {
- AAICVTrackerCallSite(const IRPosition &IRP, Attributor &A)
- : AAICVTracker(IRP, A) {}
-
- void initialize(Attributor &A) override {
- Function *F = getAnchorScope();
- if (!F || !A.isFunctionIPOAmendable(*F))
- indicatePessimisticFixpoint();
-
- // We only initialize this AA for getters, so we need to know which ICV it
- // gets.
- auto &OMPInfoCache = static_cast<OMPInformationCache &>(A.getInfoCache());
- for (InternalControlVar ICV : TrackableICVs) {
- auto ICVInfo = OMPInfoCache.ICVs[ICV];
- auto &Getter = OMPInfoCache.RFIs[ICVInfo.Getter];
- if (Getter.Declaration == getAssociatedFunction()) {
- AssociatedICV = ICVInfo.Kind;
- return;
- }
- }
-
- /// Unknown ICV.
- indicatePessimisticFixpoint();
- }
-
- ChangeStatus manifest(Attributor &A) override {
- if (!ReplVal.hasValue() || !ReplVal.getValue())
- return ChangeStatus::UNCHANGED;
-
- A.changeValueAfterManifest(*getCtxI(), **ReplVal);
- A.deleteAfterManifest(*getCtxI());
-
- return ChangeStatus::CHANGED;
- }
-
- // FIXME: come up with better string.
- const std::string getAsStr() const override { return "ICVTrackerCallSite"; }
-
- // FIXME: come up with some stats.
- void trackStatistics() const override {}
-
- InternalControlVar AssociatedICV;
- Optional<Value *> ReplVal;
-
- ChangeStatus updateImpl(Attributor &A) override {
- const auto &ICVTrackingAA = A.getAAFor<AAICVTracker>(
- *this, IRPosition::function(*getAnchorScope()));
-
- // We don't have any information, so we assume it changes the ICV.
- if (!ICVTrackingAA.isAssumedTracked())
- return indicatePessimisticFixpoint();
-
- Optional<Value *> NewReplVal =
- ICVTrackingAA.getReplacementValue(AssociatedICV, getCtxI(), A);
-
- if (ReplVal == NewReplVal)
- return ChangeStatus::UNCHANGED;
-
- ReplVal = NewReplVal;
- return ChangeStatus::CHANGED;
- }
-
- // Return the value with which associated value can be replaced for specific
- // \p ICV.
- Optional<Value *>
- getUniqueReplacementValue(InternalControlVar ICV) const override {
- return ReplVal;
- }
-};
-
-struct AAICVTrackerCallSiteReturned : AAICVTracker {
- AAICVTrackerCallSiteReturned(const IRPosition &IRP, Attributor &A)
- : AAICVTracker(IRP, A) {}
-
- // FIXME: come up with better string.
- const std::string getAsStr() const override {
- return "ICVTrackerCallSiteReturned";
- }
-
- // FIXME: come up with some stats.
- void trackStatistics() const override {}
-
- /// We don't manifest anything for this AA.
- ChangeStatus manifest(Attributor &A) override {
- return ChangeStatus::UNCHANGED;
- }
-
- // Map of ICV to their values at specific program point.
- EnumeratedArray<Optional<Value *>, InternalControlVar,
- InternalControlVar::ICV___last>
- ICVReplacementValuesMap;
-
- /// Return the value with which associated value can be replaced for specific
- /// \p ICV.
- Optional<Value *>
- getUniqueReplacementValue(InternalControlVar ICV) const override {
- return ICVReplacementValuesMap[ICV];
- }
-
- ChangeStatus updateImpl(Attributor &A) override {
- ChangeStatus Changed = ChangeStatus::UNCHANGED;
- const auto &ICVTrackingAA = A.getAAFor<AAICVTracker>(
- *this, IRPosition::returned(*getAssociatedFunction()));
-
- // We don't have any information, so we assume it changes the ICV.
- if (!ICVTrackingAA.isAssumedTracked())
- return indicatePessimisticFixpoint();
-
- for (InternalControlVar ICV : TrackableICVs) {
- Optional<Value *> &ReplVal = ICVReplacementValuesMap[ICV];
- Optional<Value *> NewReplVal =
- ICVTrackingAA.getUniqueReplacementValue(ICV);
-
- if (ReplVal == NewReplVal)
- continue;
-
- ReplVal = NewReplVal;
- Changed = ChangeStatus::CHANGED;
- }
- return Changed;
- }
-};
} // namespace
const char AAICVTracker::ID = 0;
@@ -2242,17 +2242,17 @@ AAICVTracker &AAICVTracker::createForPosition(const IRPosition &IRP,
case IRPosition::IRP_INVALID:
case IRPosition::IRP_FLOAT:
case IRPosition::IRP_ARGUMENT:
- case IRPosition::IRP_CALL_SITE_ARGUMENT:
- llvm_unreachable("ICVTracker can only be created for function position!");
+ case IRPosition::IRP_CALL_SITE_ARGUMENT:
+ llvm_unreachable("ICVTracker can only be created for function position!");
case IRPosition::IRP_RETURNED:
- AA = new (A.Allocator) AAICVTrackerFunctionReturned(IRP, A);
- break;
+ AA = new (A.Allocator) AAICVTrackerFunctionReturned(IRP, A);
+ break;
case IRPosition::IRP_CALL_SITE_RETURNED:
- AA = new (A.Allocator) AAICVTrackerCallSiteReturned(IRP, A);
- break;
+ AA = new (A.Allocator) AAICVTrackerCallSiteReturned(IRP, A);
+ break;
case IRPosition::IRP_CALL_SITE:
- AA = new (A.Allocator) AAICVTrackerCallSite(IRP, A);
- break;
+ AA = new (A.Allocator) AAICVTrackerCallSite(IRP, A);
+ break;
case IRPosition::IRP_FUNCTION:
AA = new (A.Allocator) AAICVTrackerFunction(IRP, A);
break;
@@ -2271,21 +2271,21 @@ PreservedAnalyses OpenMPOptPass::run(LazyCallGraph::SCC &C,
return PreservedAnalyses::all();
SmallVector<Function *, 16> SCC;
- // If there are kernels in the module, we have to run on all SCC's.
- bool SCCIsInteresting = !OMPInModule.getKernels().empty();
- for (LazyCallGraph::Node &N : C) {
- Function *Fn = &N.getFunction();
- SCC.push_back(Fn);
-
- // Do we already know that the SCC contains kernels,
- // or that OpenMP functions are called from this SCC?
- if (SCCIsInteresting)
- continue;
- // If not, let's check that.
- SCCIsInteresting |= OMPInModule.containsOMPRuntimeCalls(Fn);
- }
-
- if (!SCCIsInteresting || SCC.empty())
+ // If there are kernels in the module, we have to run on all SCC's.
+ bool SCCIsInteresting = !OMPInModule.getKernels().empty();
+ for (LazyCallGraph::Node &N : C) {
+ Function *Fn = &N.getFunction();
+ SCC.push_back(Fn);
+
+ // Do we already know that the SCC contains kernels,
+ // or that OpenMP functions are called from this SCC?
+ if (SCCIsInteresting)
+ continue;
+ // If not, let's check that.
+ SCCIsInteresting |= OMPInModule.containsOMPRuntimeCalls(Fn);
+ }
+
+ if (!SCCIsInteresting || SCC.empty())
return PreservedAnalyses::all();
FunctionAnalysisManager &FAM =
@@ -2343,23 +2343,23 @@ struct OpenMPOptLegacyPass : public CallGraphSCCPass {
return false;
SmallVector<Function *, 16> SCC;
- // If there are kernels in the module, we have to run on all SCC's.
- bool SCCIsInteresting = !OMPInModule.getKernels().empty();
- for (CallGraphNode *CGN : CGSCC) {
- Function *Fn = CGN->getFunction();
- if (!Fn || Fn->isDeclaration())
- continue;
- SCC.push_back(Fn);
-
- // Do we already know that the SCC contains kernels,
- // or that OpenMP functions are called from this SCC?
- if (SCCIsInteresting)
- continue;
- // If not, let's check that.
- SCCIsInteresting |= OMPInModule.containsOMPRuntimeCalls(Fn);
- }
-
- if (!SCCIsInteresting || SCC.empty())
+ // If there are kernels in the module, we have to run on all SCC's.
+ bool SCCIsInteresting = !OMPInModule.getKernels().empty();
+ for (CallGraphNode *CGN : CGSCC) {
+ Function *Fn = CGN->getFunction();
+ if (!Fn || Fn->isDeclaration())
+ continue;
+ SCC.push_back(Fn);
+
+ // Do we already know that the SCC contains kernels,
+ // or that OpenMP functions are called from this SCC?
+ if (SCCIsInteresting)
+ continue;
+ // If not, let's check that.
+ SCCIsInteresting |= OMPInModule.containsOMPRuntimeCalls(Fn);
+ }
+
+ if (!SCCIsInteresting || SCC.empty())
return false;
CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
@@ -2420,18 +2420,18 @@ bool llvm::omp::containsOpenMP(Module &M, OpenMPInModule &OMPInModule) {
if (OMPInModule.isKnown())
return OMPInModule;
- auto RecordFunctionsContainingUsesOf = [&](Function *F) {
- for (User *U : F->users())
- if (auto *I = dyn_cast<Instruction>(U))
- OMPInModule.FuncsWithOMPRuntimeCalls.insert(I->getFunction());
- };
-
+ auto RecordFunctionsContainingUsesOf = [&](Function *F) {
+ for (User *U : F->users())
+ if (auto *I = dyn_cast<Instruction>(U))
+ OMPInModule.FuncsWithOMPRuntimeCalls.insert(I->getFunction());
+ };
+
// MSVC doesn't like long if-else chains for some reason and instead just
// issues an error. Work around it..
do {
#define OMP_RTL(_Enum, _Name, ...) \
- if (Function *F = M.getFunction(_Name)) { \
- RecordFunctionsContainingUsesOf(F); \
+ if (Function *F = M.getFunction(_Name)) { \
+ RecordFunctionsContainingUsesOf(F); \
OMPInModule = true; \
}
#include "llvm/Frontend/OpenMP/OMPKinds.def"
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/PartialInlining.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/PartialInlining.cpp
index 2c93760385..2bbf4bf110 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/PartialInlining.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/PartialInlining.cpp
@@ -152,7 +152,7 @@ struct FunctionOutliningInfo {
// Returns the number of blocks to be inlined including all blocks
// in Entries and one return block.
- unsigned getNumInlinedBlocks() const { return Entries.size() + 1; }
+ unsigned getNumInlinedBlocks() const { return Entries.size() + 1; }
// A set of blocks including the function entry that guard
// the region to be outlined.
@@ -208,7 +208,7 @@ struct PartialInlinerImpl {
// function (only if we partially inlined early returns) as there is a
// possibility to further "peel" early return statements that were left in the
// outline function due to code size.
- std::pair<bool, Function *> unswitchFunction(Function &F);
+ std::pair<bool, Function *> unswitchFunction(Function &F);
// This class speculatively clones the function to be partial inlined.
// At the end of partial inlining, the remaining callsites to the cloned
@@ -219,19 +219,19 @@ struct PartialInlinerImpl {
// multi-region outlining.
FunctionCloner(Function *F, FunctionOutliningInfo *OI,
OptimizationRemarkEmitter &ORE,
- function_ref<AssumptionCache *(Function &)> LookupAC,
- function_ref<TargetTransformInfo &(Function &)> GetTTI);
+ function_ref<AssumptionCache *(Function &)> LookupAC,
+ function_ref<TargetTransformInfo &(Function &)> GetTTI);
FunctionCloner(Function *F, FunctionOutliningMultiRegionInfo *OMRI,
OptimizationRemarkEmitter &ORE,
- function_ref<AssumptionCache *(Function &)> LookupAC,
- function_ref<TargetTransformInfo &(Function &)> GetTTI);
-
+ function_ref<AssumptionCache *(Function &)> LookupAC,
+ function_ref<TargetTransformInfo &(Function &)> GetTTI);
+
~FunctionCloner();
// Prepare for function outlining: making sure there is only
// one incoming edge from the extracted/outlined region to
// the return block.
- void normalizeReturnBlock() const;
+ void normalizeReturnBlock() const;
// Do function outlining for cold regions.
bool doMultiRegionFunctionOutlining();
@@ -262,7 +262,7 @@ struct PartialInlinerImpl {
std::unique_ptr<BlockFrequencyInfo> ClonedFuncBFI = nullptr;
OptimizationRemarkEmitter &ORE;
function_ref<AssumptionCache *(Function &)> LookupAC;
- function_ref<TargetTransformInfo &(Function &)> GetTTI;
+ function_ref<TargetTransformInfo &(Function &)> GetTTI;
};
private:
@@ -278,14 +278,14 @@ private:
// The result is no larger than 1 and is represented using BP.
// (Note that the outlined region's 'head' block can only have incoming
// edges from the guarding entry blocks).
- BranchProbability
- getOutliningCallBBRelativeFreq(FunctionCloner &Cloner) const;
+ BranchProbability
+ getOutliningCallBBRelativeFreq(FunctionCloner &Cloner) const;
// Return true if the callee of CB should be partially inlined with
// profit.
bool shouldPartialInline(CallBase &CB, FunctionCloner &Cloner,
BlockFrequency WeightedOutliningRcost,
- OptimizationRemarkEmitter &ORE) const;
+ OptimizationRemarkEmitter &ORE) const;
// Try to inline DuplicateFunction (cloned from F with call to
// the OutlinedFunction into its callers. Return true
@@ -294,11 +294,11 @@ private:
// Compute the mapping from use site of DuplicationFunction to the enclosing
// BB's profile count.
- void
- computeCallsiteToProfCountMap(Function *DuplicateFunction,
- DenseMap<User *, uint64_t> &SiteCountMap) const;
+ void
+ computeCallsiteToProfCountMap(Function *DuplicateFunction,
+ DenseMap<User *, uint64_t> &SiteCountMap) const;
- bool isLimitReached() const {
+ bool isLimitReached() const {
return (MaxNumPartialInlining != -1 &&
NumPartialInlining >= MaxNumPartialInlining);
}
@@ -310,12 +310,12 @@ private:
return nullptr;
}
- static CallBase *getOneCallSiteTo(Function &F) {
- User *User = *F.user_begin();
+ static CallBase *getOneCallSiteTo(Function &F) {
+ User *User = *F.user_begin();
return getSupportedCallBase(User);
}
- std::tuple<DebugLoc, BasicBlock *> getOneDebugLoc(Function &F) const {
+ std::tuple<DebugLoc, BasicBlock *> getOneDebugLoc(Function &F) const {
CallBase *CB = getOneCallSiteTo(F);
DebugLoc DLoc = CB->getDebugLoc();
BasicBlock *Block = CB->getParent();
@@ -328,19 +328,19 @@ private:
// outlined function itself;
// - The second value is the estimated size of the new call sequence in
// basic block Cloner.OutliningCallBB;
- std::tuple<int, int> computeOutliningCosts(FunctionCloner &Cloner) const;
+ std::tuple<int, int> computeOutliningCosts(FunctionCloner &Cloner) const;
// Compute the 'InlineCost' of block BB. InlineCost is a proxy used to
// approximate both the size and runtime cost (Note that in the current
// inline cost analysis, there is no clear distinction there either).
- static int computeBBInlineCost(BasicBlock *BB, TargetTransformInfo *TTI);
+ static int computeBBInlineCost(BasicBlock *BB, TargetTransformInfo *TTI);
+
+ std::unique_ptr<FunctionOutliningInfo>
+ computeOutliningInfo(Function &F) const;
- std::unique_ptr<FunctionOutliningInfo>
- computeOutliningInfo(Function &F) const;
-
std::unique_ptr<FunctionOutliningMultiRegionInfo>
- computeOutliningColdRegionsInfo(Function &F,
- OptimizationRemarkEmitter &ORE) const;
+ computeOutliningColdRegionsInfo(Function &F,
+ OptimizationRemarkEmitter &ORE) const;
};
struct PartialInlinerLegacyPass : public ModulePass {
@@ -392,20 +392,20 @@ struct PartialInlinerLegacyPass : public ModulePass {
} // end anonymous namespace
std::unique_ptr<FunctionOutliningMultiRegionInfo>
-PartialInlinerImpl::computeOutliningColdRegionsInfo(
- Function &F, OptimizationRemarkEmitter &ORE) const {
- BasicBlock *EntryBlock = &F.front();
+PartialInlinerImpl::computeOutliningColdRegionsInfo(
+ Function &F, OptimizationRemarkEmitter &ORE) const {
+ BasicBlock *EntryBlock = &F.front();
- DominatorTree DT(F);
+ DominatorTree DT(F);
LoopInfo LI(DT);
- BranchProbabilityInfo BPI(F, LI);
+ BranchProbabilityInfo BPI(F, LI);
std::unique_ptr<BlockFrequencyInfo> ScopedBFI;
BlockFrequencyInfo *BFI;
if (!GetBFI) {
- ScopedBFI.reset(new BlockFrequencyInfo(F, BPI, LI));
+ ScopedBFI.reset(new BlockFrequencyInfo(F, BPI, LI));
BFI = ScopedBFI.get();
} else
- BFI = &(GetBFI(F));
+ BFI = &(GetBFI(F));
// Return if we don't have profiling information.
if (!PSI.hasInstrumentationProfile())
@@ -429,9 +429,9 @@ PartialInlinerImpl::computeOutliningColdRegionsInfo(
<< " has more than one region exit edge.";
});
return nullptr;
- }
-
- ExitBlock = Block;
+ }
+
+ ExitBlock = Block;
}
}
}
@@ -446,14 +446,14 @@ PartialInlinerImpl::computeOutliningColdRegionsInfo(
// Use the same computeBBInlineCost function to compute the cost savings of
// the outlining the candidate region.
- TargetTransformInfo *FTTI = &GetTTI(F);
+ TargetTransformInfo *FTTI = &GetTTI(F);
int OverallFunctionCost = 0;
- for (auto &BB : F)
- OverallFunctionCost += computeBBInlineCost(&BB, FTTI);
+ for (auto &BB : F)
+ OverallFunctionCost += computeBBInlineCost(&BB, FTTI);
+
+ LLVM_DEBUG(dbgs() << "OverallFunctionCost = " << OverallFunctionCost
+ << "\n";);
- LLVM_DEBUG(dbgs() << "OverallFunctionCost = " << OverallFunctionCost
- << "\n";);
-
int MinOutlineRegionCost =
static_cast<int>(OverallFunctionCost * MinRegionSizeRatio);
BranchProbability MinBranchProbability(
@@ -465,7 +465,7 @@ PartialInlinerImpl::computeOutliningColdRegionsInfo(
DenseMap<BasicBlock *, bool> VisitedMap;
DFS.push_back(CurrEntry);
VisitedMap[CurrEntry] = true;
-
+
// Use Depth First Search on the basic blocks to find CFG edges that are
// considered cold.
// Cold regions considered must also have its inline cost compared to the
@@ -473,98 +473,98 @@ PartialInlinerImpl::computeOutliningColdRegionsInfo(
// if it reduced the inline cost of the function by 'MinOutlineRegionCost' or
// more.
while (!DFS.empty()) {
- auto *ThisBB = DFS.back();
+ auto *ThisBB = DFS.back();
DFS.pop_back();
// Only consider regions with predecessor blocks that are considered
// not-cold (default: part of the top 99.99% of all block counters)
// AND greater than our minimum block execution count (default: 100).
- if (PSI.isColdBlock(ThisBB, BFI) ||
- BBProfileCount(ThisBB) < MinBlockCounterExecution)
+ if (PSI.isColdBlock(ThisBB, BFI) ||
+ BBProfileCount(ThisBB) < MinBlockCounterExecution)
continue;
- for (auto SI = succ_begin(ThisBB); SI != succ_end(ThisBB); ++SI) {
+ for (auto SI = succ_begin(ThisBB); SI != succ_end(ThisBB); ++SI) {
if (VisitedMap[*SI])
continue;
VisitedMap[*SI] = true;
DFS.push_back(*SI);
// If branch isn't cold, we skip to the next one.
- BranchProbability SuccProb = BPI.getEdgeProbability(ThisBB, *SI);
+ BranchProbability SuccProb = BPI.getEdgeProbability(ThisBB, *SI);
if (SuccProb > MinBranchProbability)
continue;
-
- LLVM_DEBUG(dbgs() << "Found cold edge: " << ThisBB->getName() << "->"
- << SI->getName()
- << "\nBranch Probability = " << SuccProb << "\n";);
-
+
+ LLVM_DEBUG(dbgs() << "Found cold edge: " << ThisBB->getName() << "->"
+ << SI->getName()
+ << "\nBranch Probability = " << SuccProb << "\n";);
+
SmallVector<BasicBlock *, 8> DominateVector;
DT.getDescendants(*SI, DominateVector);
- assert(!DominateVector.empty() &&
- "SI should be reachable and have at least itself as descendant");
-
+ assert(!DominateVector.empty() &&
+ "SI should be reachable and have at least itself as descendant");
+
// We can only outline single entry regions (for now).
- if (!DominateVector.front()->hasNPredecessors(1)) {
- LLVM_DEBUG(dbgs() << "ABORT: Block " << SI->getName()
- << " doesn't have a single predecessor in the "
- "dominator tree\n";);
+ if (!DominateVector.front()->hasNPredecessors(1)) {
+ LLVM_DEBUG(dbgs() << "ABORT: Block " << SI->getName()
+ << " doesn't have a single predecessor in the "
+ "dominator tree\n";);
continue;
- }
-
+ }
+
BasicBlock *ExitBlock = nullptr;
// We can only outline single exit regions (for now).
- if (!(ExitBlock = IsSingleExit(DominateVector))) {
- LLVM_DEBUG(dbgs() << "ABORT: Block " << SI->getName()
- << " doesn't have a unique successor\n";);
+ if (!(ExitBlock = IsSingleExit(DominateVector))) {
+ LLVM_DEBUG(dbgs() << "ABORT: Block " << SI->getName()
+ << " doesn't have a unique successor\n";);
continue;
- }
-
+ }
+
int OutlineRegionCost = 0;
for (auto *BB : DominateVector)
- OutlineRegionCost += computeBBInlineCost(BB, &GetTTI(*BB->getParent()));
+ OutlineRegionCost += computeBBInlineCost(BB, &GetTTI(*BB->getParent()));
- LLVM_DEBUG(dbgs() << "OutlineRegionCost = " << OutlineRegionCost
- << "\n";);
+ LLVM_DEBUG(dbgs() << "OutlineRegionCost = " << OutlineRegionCost
+ << "\n";);
- if (!SkipCostAnalysis && OutlineRegionCost < MinOutlineRegionCost) {
+ if (!SkipCostAnalysis && OutlineRegionCost < MinOutlineRegionCost) {
ORE.emit([&]() {
return OptimizationRemarkAnalysis(DEBUG_TYPE, "TooCostly",
&SI->front())
- << ore::NV("Callee", &F)
- << " inline cost-savings smaller than "
+ << ore::NV("Callee", &F)
+ << " inline cost-savings smaller than "
<< ore::NV("Cost", MinOutlineRegionCost);
});
-
- LLVM_DEBUG(dbgs() << "ABORT: Outline region cost is smaller than "
- << MinOutlineRegionCost << "\n";);
+
+ LLVM_DEBUG(dbgs() << "ABORT: Outline region cost is smaller than "
+ << MinOutlineRegionCost << "\n";);
continue;
}
-
+
// For now, ignore blocks that belong to a SISE region that is a
// candidate for outlining. In the future, we may want to look
// at inner regions because the outer region may have live-exit
// variables.
for (auto *BB : DominateVector)
VisitedMap[BB] = true;
-
+
// ReturnBlock here means the block after the outline call
BasicBlock *ReturnBlock = ExitBlock->getSingleSuccessor();
FunctionOutliningMultiRegionInfo::OutlineRegionInfo RegInfo(
DominateVector, DominateVector.front(), ExitBlock, ReturnBlock);
OutliningInfo->ORI.push_back(RegInfo);
- LLVM_DEBUG(dbgs() << "Found Cold Candidate starting at block: "
- << DominateVector.front()->getName() << "\n";);
+ LLVM_DEBUG(dbgs() << "Found Cold Candidate starting at block: "
+ << DominateVector.front()->getName() << "\n";);
ColdCandidateFound = true;
NumColdRegionsFound++;
}
}
-
+
if (ColdCandidateFound)
return OutliningInfo;
-
- return std::unique_ptr<FunctionOutliningMultiRegionInfo>();
+
+ return std::unique_ptr<FunctionOutliningMultiRegionInfo>();
}
std::unique_ptr<FunctionOutliningInfo>
-PartialInlinerImpl::computeOutliningInfo(Function &F) const {
- BasicBlock *EntryBlock = &F.front();
+PartialInlinerImpl::computeOutliningInfo(Function &F) const {
+ BasicBlock *EntryBlock = &F.front();
BranchInst *BR = dyn_cast<BranchInst>(EntryBlock->getTerminator());
if (!BR || BR->isUnconditional())
return std::unique_ptr<FunctionOutliningInfo>();
@@ -607,7 +607,7 @@ PartialInlinerImpl::computeOutliningInfo(Function &F) const {
// The number of blocks to be inlined has already reached
// the limit. When MaxNumInlineBlocks is set to 0 or 1, this
// disables partial inlining for the function.
- if (OutliningInfo->getNumInlinedBlocks() >= MaxNumInlineBlocks)
+ if (OutliningInfo->getNumInlinedBlocks() >= MaxNumInlineBlocks)
break;
if (succ_size(CurrEntry) != 2)
@@ -627,7 +627,7 @@ PartialInlinerImpl::computeOutliningInfo(Function &F) const {
break;
}
- BasicBlock *CommSucc, *OtherSucc;
+ BasicBlock *CommSucc, *OtherSucc;
std::tie(CommSucc, OtherSucc) = GetCommonSucc(Succ1, Succ2);
if (!CommSucc)
@@ -643,7 +643,7 @@ PartialInlinerImpl::computeOutliningInfo(Function &F) const {
// Do sanity check of the entries: threre should not
// be any successors (not in the entry set) other than
// {ReturnBlock, NonReturnBlock}
- assert(OutliningInfo->Entries[0] == &F.front() &&
+ assert(OutliningInfo->Entries[0] == &F.front() &&
"Function Entry must be the first in Entries vector");
DenseSet<BasicBlock *> Entries;
for (BasicBlock *E : OutliningInfo->Entries)
@@ -652,7 +652,7 @@ PartialInlinerImpl::computeOutliningInfo(Function &F) const {
// Returns true of BB has Predecessor which is not
// in Entries set.
auto HasNonEntryPred = [Entries](BasicBlock *BB) {
- for (auto *Pred : predecessors(BB)) {
+ for (auto *Pred : predecessors(BB)) {
if (!Entries.count(Pred))
return true;
}
@@ -661,7 +661,7 @@ PartialInlinerImpl::computeOutliningInfo(Function &F) const {
auto CheckAndNormalizeCandidate =
[Entries, HasNonEntryPred](FunctionOutliningInfo *OutliningInfo) {
for (BasicBlock *E : OutliningInfo->Entries) {
- for (auto *Succ : successors(E)) {
+ for (auto *Succ : successors(E)) {
if (Entries.count(Succ))
continue;
if (Succ == OutliningInfo->ReturnBlock)
@@ -681,7 +681,7 @@ PartialInlinerImpl::computeOutliningInfo(Function &F) const {
// Now further growing the candidate's inlining region by
// peeling off dominating blocks from the outlining region:
- while (OutliningInfo->getNumInlinedBlocks() < MaxNumInlineBlocks) {
+ while (OutliningInfo->getNumInlinedBlocks() < MaxNumInlineBlocks) {
BasicBlock *Cand = OutliningInfo->NonReturnBlock;
if (succ_size(Cand) != 2)
break;
@@ -711,11 +711,11 @@ PartialInlinerImpl::computeOutliningInfo(Function &F) const {
}
// Check if there is PGO data or user annotated branch data:
-static bool hasProfileData(const Function &F, const FunctionOutliningInfo &OI) {
- if (F.hasProfileData())
+static bool hasProfileData(const Function &F, const FunctionOutliningInfo &OI) {
+ if (F.hasProfileData())
return true;
// Now check if any of the entry block has MD_prof data:
- for (auto *E : OI.Entries) {
+ for (auto *E : OI.Entries) {
BranchInst *BR = dyn_cast<BranchInst>(E->getTerminator());
if (!BR || BR->isUnconditional())
continue;
@@ -726,8 +726,8 @@ static bool hasProfileData(const Function &F, const FunctionOutliningInfo &OI) {
return false;
}
-BranchProbability PartialInlinerImpl::getOutliningCallBBRelativeFreq(
- FunctionCloner &Cloner) const {
+BranchProbability PartialInlinerImpl::getOutliningCallBBRelativeFreq(
+ FunctionCloner &Cloner) const {
BasicBlock *OutliningCallBB = Cloner.OutlinedFunctions.back().second;
auto EntryFreq =
Cloner.ClonedFuncBFI->getBlockFreq(&Cloner.ClonedFunc->getEntryBlock());
@@ -736,13 +736,13 @@ BranchProbability PartialInlinerImpl::getOutliningCallBBRelativeFreq(
// FIXME Hackery needed because ClonedFuncBFI is based on the function BEFORE
// we outlined any regions, so we may encounter situations where the
// OutliningCallFreq is *slightly* bigger than the EntryFreq.
- if (OutliningCallFreq.getFrequency() > EntryFreq.getFrequency())
+ if (OutliningCallFreq.getFrequency() > EntryFreq.getFrequency())
OutliningCallFreq = EntryFreq;
-
+
auto OutlineRegionRelFreq = BranchProbability::getBranchProbability(
OutliningCallFreq.getFrequency(), EntryFreq.getFrequency());
- if (hasProfileData(*Cloner.OrigFunc, *Cloner.ClonedOI.get()))
+ if (hasProfileData(*Cloner.OrigFunc, *Cloner.ClonedOI.get()))
return OutlineRegionRelFreq;
// When profile data is not available, we need to be conservative in
@@ -768,7 +768,7 @@ BranchProbability PartialInlinerImpl::getOutliningCallBBRelativeFreq(
bool PartialInlinerImpl::shouldPartialInline(
CallBase &CB, FunctionCloner &Cloner, BlockFrequency WeightedOutliningRcost,
- OptimizationRemarkEmitter &ORE) const {
+ OptimizationRemarkEmitter &ORE) const {
using namespace ore;
Function *Callee = CB.getCalledFunction();
@@ -851,8 +851,8 @@ bool PartialInlinerImpl::shouldPartialInline(
// TODO: Ideally we should share Inliner's InlineCost Analysis code.
// For now use a simplified version. The returned 'InlineCost' will be used
// to esimate the size cost as well as runtime cost of the BB.
-int PartialInlinerImpl::computeBBInlineCost(BasicBlock *BB,
- TargetTransformInfo *TTI) {
+int PartialInlinerImpl::computeBBInlineCost(BasicBlock *BB,
+ TargetTransformInfo *TTI) {
int InlineCost = 0;
const DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
for (Instruction &I : BB->instructionsWithoutDebug()) {
@@ -875,21 +875,21 @@ int PartialInlinerImpl::computeBBInlineCost(BasicBlock *BB,
if (I.isLifetimeStartOrEnd())
continue;
- if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
- Intrinsic::ID IID = II->getIntrinsicID();
- SmallVector<Type *, 4> Tys;
- FastMathFlags FMF;
- for (Value *Val : II->args())
- Tys.push_back(Val->getType());
-
- if (auto *FPMO = dyn_cast<FPMathOperator>(II))
- FMF = FPMO->getFastMathFlags();
-
- IntrinsicCostAttributes ICA(IID, II->getType(), Tys, FMF);
- InlineCost += TTI->getIntrinsicInstrCost(ICA, TTI::TCK_SizeAndLatency);
- continue;
- }
-
+ if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
+ Intrinsic::ID IID = II->getIntrinsicID();
+ SmallVector<Type *, 4> Tys;
+ FastMathFlags FMF;
+ for (Value *Val : II->args())
+ Tys.push_back(Val->getType());
+
+ if (auto *FPMO = dyn_cast<FPMathOperator>(II))
+ FMF = FPMO->getFastMathFlags();
+
+ IntrinsicCostAttributes ICA(IID, II->getType(), Tys, FMF);
+ InlineCost += TTI->getIntrinsicInstrCost(ICA, TTI::TCK_SizeAndLatency);
+ continue;
+ }
+
if (CallInst *CI = dyn_cast<CallInst>(&I)) {
InlineCost += getCallsiteCost(*CI, DL);
continue;
@@ -910,20 +910,20 @@ int PartialInlinerImpl::computeBBInlineCost(BasicBlock *BB,
}
std::tuple<int, int>
-PartialInlinerImpl::computeOutliningCosts(FunctionCloner &Cloner) const {
+PartialInlinerImpl::computeOutliningCosts(FunctionCloner &Cloner) const {
int OutliningFuncCallCost = 0, OutlinedFunctionCost = 0;
for (auto FuncBBPair : Cloner.OutlinedFunctions) {
Function *OutlinedFunc = FuncBBPair.first;
BasicBlock* OutliningCallBB = FuncBBPair.second;
// Now compute the cost of the call sequence to the outlined function
// 'OutlinedFunction' in BB 'OutliningCallBB':
- auto *OutlinedFuncTTI = &GetTTI(*OutlinedFunc);
- OutliningFuncCallCost +=
- computeBBInlineCost(OutliningCallBB, OutlinedFuncTTI);
+ auto *OutlinedFuncTTI = &GetTTI(*OutlinedFunc);
+ OutliningFuncCallCost +=
+ computeBBInlineCost(OutliningCallBB, OutlinedFuncTTI);
// Now compute the cost of the extracted/outlined function itself:
for (BasicBlock &BB : *OutlinedFunc)
- OutlinedFunctionCost += computeBBInlineCost(&BB, OutlinedFuncTTI);
+ OutlinedFunctionCost += computeBBInlineCost(&BB, OutlinedFuncTTI);
}
assert(OutlinedFunctionCost >= Cloner.OutlinedRegionCost &&
"Outlined function cost should be no less than the outlined region");
@@ -947,7 +947,7 @@ PartialInlinerImpl::computeOutliningCosts(FunctionCloner &Cloner) const {
// after the function is partially inlined into the callsite.
void PartialInlinerImpl::computeCallsiteToProfCountMap(
Function *DuplicateFunction,
- DenseMap<User *, uint64_t> &CallSiteToProfCountMap) const {
+ DenseMap<User *, uint64_t> &CallSiteToProfCountMap) const {
std::vector<User *> Users(DuplicateFunction->user_begin(),
DuplicateFunction->user_end());
Function *CurrentCaller = nullptr;
@@ -988,9 +988,9 @@ void PartialInlinerImpl::computeCallsiteToProfCountMap(
PartialInlinerImpl::FunctionCloner::FunctionCloner(
Function *F, FunctionOutliningInfo *OI, OptimizationRemarkEmitter &ORE,
- function_ref<AssumptionCache *(Function &)> LookupAC,
- function_ref<TargetTransformInfo &(Function &)> GetTTI)
- : OrigFunc(F), ORE(ORE), LookupAC(LookupAC), GetTTI(GetTTI) {
+ function_ref<AssumptionCache *(Function &)> LookupAC,
+ function_ref<TargetTransformInfo &(Function &)> GetTTI)
+ : OrigFunc(F), ORE(ORE), LookupAC(LookupAC), GetTTI(GetTTI) {
ClonedOI = std::make_unique<FunctionOutliningInfo>();
// Clone the function, so that we can hack away on it.
@@ -999,9 +999,9 @@ PartialInlinerImpl::FunctionCloner::FunctionCloner(
ClonedOI->ReturnBlock = cast<BasicBlock>(VMap[OI->ReturnBlock]);
ClonedOI->NonReturnBlock = cast<BasicBlock>(VMap[OI->NonReturnBlock]);
- for (BasicBlock *BB : OI->Entries)
+ for (BasicBlock *BB : OI->Entries)
ClonedOI->Entries.push_back(cast<BasicBlock>(VMap[BB]));
-
+
for (BasicBlock *E : OI->ReturnBlockPreds) {
BasicBlock *NewE = cast<BasicBlock>(VMap[E]);
ClonedOI->ReturnBlockPreds.push_back(NewE);
@@ -1014,9 +1014,9 @@ PartialInlinerImpl::FunctionCloner::FunctionCloner(
PartialInlinerImpl::FunctionCloner::FunctionCloner(
Function *F, FunctionOutliningMultiRegionInfo *OI,
OptimizationRemarkEmitter &ORE,
- function_ref<AssumptionCache *(Function &)> LookupAC,
- function_ref<TargetTransformInfo &(Function &)> GetTTI)
- : OrigFunc(F), ORE(ORE), LookupAC(LookupAC), GetTTI(GetTTI) {
+ function_ref<AssumptionCache *(Function &)> LookupAC,
+ function_ref<TargetTransformInfo &(Function &)> GetTTI)
+ : OrigFunc(F), ORE(ORE), LookupAC(LookupAC), GetTTI(GetTTI) {
ClonedOMRI = std::make_unique<FunctionOutliningMultiRegionInfo>();
// Clone the function, so that we can hack away on it.
@@ -1028,9 +1028,9 @@ PartialInlinerImpl::FunctionCloner::FunctionCloner(
for (FunctionOutliningMultiRegionInfo::OutlineRegionInfo RegionInfo :
OI->ORI) {
SmallVector<BasicBlock *, 8> Region;
- for (BasicBlock *BB : RegionInfo.Region)
+ for (BasicBlock *BB : RegionInfo.Region)
Region.push_back(cast<BasicBlock>(VMap[BB]));
-
+
BasicBlock *NewEntryBlock = cast<BasicBlock>(VMap[RegionInfo.EntryBlock]);
BasicBlock *NewExitBlock = cast<BasicBlock>(VMap[RegionInfo.ExitBlock]);
BasicBlock *NewReturnBlock = nullptr;
@@ -1045,8 +1045,8 @@ PartialInlinerImpl::FunctionCloner::FunctionCloner(
F->replaceAllUsesWith(ClonedFunc);
}
-void PartialInlinerImpl::FunctionCloner::normalizeReturnBlock() const {
- auto GetFirstPHI = [](BasicBlock *BB) {
+void PartialInlinerImpl::FunctionCloner::normalizeReturnBlock() const {
+ auto GetFirstPHI = [](BasicBlock *BB) {
BasicBlock::iterator I = BB->begin();
PHINode *FirstPhi = nullptr;
while (I != BB->end()) {
@@ -1072,7 +1072,7 @@ void PartialInlinerImpl::FunctionCloner::normalizeReturnBlock() const {
// of which will go outside.
BasicBlock *PreReturn = ClonedOI->ReturnBlock;
// only split block when necessary:
- PHINode *FirstPhi = GetFirstPHI(PreReturn);
+ PHINode *FirstPhi = GetFirstPHI(PreReturn);
unsigned NumPredsFromEntries = ClonedOI->ReturnBlockPreds.size();
if (!FirstPhi || FirstPhi->getNumIncomingValues() <= NumPredsFromEntries + 1)
@@ -1120,16 +1120,16 @@ void PartialInlinerImpl::FunctionCloner::normalizeReturnBlock() const {
for (auto *DP : DeadPhis)
DP->eraseFromParent();
- for (auto *E : ClonedOI->ReturnBlockPreds)
+ for (auto *E : ClonedOI->ReturnBlockPreds)
E->getTerminator()->replaceUsesOfWith(PreReturn, ClonedOI->ReturnBlock);
}
bool PartialInlinerImpl::FunctionCloner::doMultiRegionFunctionOutlining() {
- auto ComputeRegionCost = [&](SmallVectorImpl<BasicBlock *> &Region) {
+ auto ComputeRegionCost = [&](SmallVectorImpl<BasicBlock *> &Region) {
int Cost = 0;
for (BasicBlock* BB : Region)
- Cost += computeBBInlineCost(BB, &GetTTI(*BB->getParent()));
+ Cost += computeBBInlineCost(BB, &GetTTI(*BB->getParent()));
return Cost;
};
@@ -1162,21 +1162,21 @@ bool PartialInlinerImpl::FunctionCloner::doMultiRegionFunctionOutlining() {
CE.findInputsOutputs(Inputs, Outputs, Sinks);
- LLVM_DEBUG({
+ LLVM_DEBUG({
dbgs() << "inputs: " << Inputs.size() << "\n";
dbgs() << "outputs: " << Outputs.size() << "\n";
for (Value *value : Inputs)
dbgs() << "value used in func: " << *value << "\n";
for (Value *output : Outputs)
dbgs() << "instr used in func: " << *output << "\n";
- });
-
+ });
+
// Do not extract regions that have live exit variables.
if (Outputs.size() > 0 && !ForceLiveExit)
continue;
- if (Function *OutlinedFunc = CE.extractCodeRegion(CEAC)) {
- CallBase *OCS = PartialInlinerImpl::getOneCallSiteTo(*OutlinedFunc);
+ if (Function *OutlinedFunc = CE.extractCodeRegion(CEAC)) {
+ CallBase *OCS = PartialInlinerImpl::getOneCallSiteTo(*OutlinedFunc);
BasicBlock *OutliningCallBB = OCS->getParent();
assert(OutliningCallBB->getParent() == ClonedFunc);
OutlinedFunctions.push_back(std::make_pair(OutlinedFunc,OutliningCallBB));
@@ -1205,7 +1205,7 @@ PartialInlinerImpl::FunctionCloner::doSingleRegionFunctionOutlining() {
// (i.e. not to be extracted to the out of line function)
auto ToBeInlined = [&, this](BasicBlock *BB) {
return BB == ClonedOI->ReturnBlock ||
- llvm::is_contained(ClonedOI->Entries, BB);
+ llvm::is_contained(ClonedOI->Entries, BB);
};
assert(ClonedOI && "Expecting OutlineInfo for single region outline");
@@ -1220,10 +1220,10 @@ PartialInlinerImpl::FunctionCloner::doSingleRegionFunctionOutlining() {
// Gather up the blocks that we're going to extract.
std::vector<BasicBlock *> ToExtract;
- auto *ClonedFuncTTI = &GetTTI(*ClonedFunc);
+ auto *ClonedFuncTTI = &GetTTI(*ClonedFunc);
ToExtract.push_back(ClonedOI->NonReturnBlock);
- OutlinedRegionCost += PartialInlinerImpl::computeBBInlineCost(
- ClonedOI->NonReturnBlock, ClonedFuncTTI);
+ OutlinedRegionCost += PartialInlinerImpl::computeBBInlineCost(
+ ClonedOI->NonReturnBlock, ClonedFuncTTI);
for (BasicBlock &BB : *ClonedFunc)
if (!ToBeInlined(&BB) && &BB != ClonedOI->NonReturnBlock) {
ToExtract.push_back(&BB);
@@ -1231,7 +1231,7 @@ PartialInlinerImpl::FunctionCloner::doSingleRegionFunctionOutlining() {
// into the outlined function which may make the outlining
// overhead (the difference of the outlined function cost
// and OutliningRegionCost) look larger.
- OutlinedRegionCost += computeBBInlineCost(&BB, ClonedFuncTTI);
+ OutlinedRegionCost += computeBBInlineCost(&BB, ClonedFuncTTI);
}
// Extract the body of the if.
@@ -1244,7 +1244,7 @@ PartialInlinerImpl::FunctionCloner::doSingleRegionFunctionOutlining() {
if (OutlinedFunc) {
BasicBlock *OutliningCallBB =
- PartialInlinerImpl::getOneCallSiteTo(*OutlinedFunc)->getParent();
+ PartialInlinerImpl::getOneCallSiteTo(*OutlinedFunc)->getParent();
assert(OutliningCallBB->getParent() == ClonedFunc);
OutlinedFunctions.push_back(std::make_pair(OutlinedFunc, OutliningCallBB));
} else
@@ -1273,48 +1273,48 @@ PartialInlinerImpl::FunctionCloner::~FunctionCloner() {
}
}
-std::pair<bool, Function *> PartialInlinerImpl::unswitchFunction(Function &F) {
- if (F.hasAddressTaken())
+std::pair<bool, Function *> PartialInlinerImpl::unswitchFunction(Function &F) {
+ if (F.hasAddressTaken())
return {false, nullptr};
// Let inliner handle it
- if (F.hasFnAttribute(Attribute::AlwaysInline))
+ if (F.hasFnAttribute(Attribute::AlwaysInline))
return {false, nullptr};
- if (F.hasFnAttribute(Attribute::NoInline))
+ if (F.hasFnAttribute(Attribute::NoInline))
return {false, nullptr};
- if (PSI.isFunctionEntryCold(&F))
+ if (PSI.isFunctionEntryCold(&F))
return {false, nullptr};
- if (F.users().empty())
+ if (F.users().empty())
return {false, nullptr};
- OptimizationRemarkEmitter ORE(&F);
+ OptimizationRemarkEmitter ORE(&F);
// Only try to outline cold regions if we have a profile summary, which
// implies we have profiling information.
- if (PSI.hasProfileSummary() && F.hasProfileData() &&
+ if (PSI.hasProfileSummary() && F.hasProfileData() &&
!DisableMultiRegionPartialInline) {
std::unique_ptr<FunctionOutliningMultiRegionInfo> OMRI =
computeOutliningColdRegionsInfo(F, ORE);
if (OMRI) {
- FunctionCloner Cloner(&F, OMRI.get(), ORE, LookupAssumptionCache, GetTTI);
+ FunctionCloner Cloner(&F, OMRI.get(), ORE, LookupAssumptionCache, GetTTI);
- LLVM_DEBUG({
+ LLVM_DEBUG({
dbgs() << "HotCountThreshold = " << PSI.getHotCountThreshold() << "\n";
dbgs() << "ColdCountThreshold = " << PSI.getColdCountThreshold()
<< "\n";
- });
-
+ });
+
bool DidOutline = Cloner.doMultiRegionFunctionOutlining();
if (DidOutline) {
- LLVM_DEBUG({
+ LLVM_DEBUG({
dbgs() << ">>>>>> Outlined (Cloned) Function >>>>>>\n";
Cloner.ClonedFunc->print(dbgs());
dbgs() << "<<<<<< Outlined (Cloned) Function <<<<<<\n";
- });
+ });
if (tryPartialInline(Cloner))
return {true, nullptr};
@@ -1329,15 +1329,15 @@ std::pair<bool, Function *> PartialInlinerImpl::unswitchFunction(Function &F) {
if (!OI)
return {false, nullptr};
- FunctionCloner Cloner(&F, OI.get(), ORE, LookupAssumptionCache, GetTTI);
- Cloner.normalizeReturnBlock();
+ FunctionCloner Cloner(&F, OI.get(), ORE, LookupAssumptionCache, GetTTI);
+ Cloner.normalizeReturnBlock();
Function *OutlinedFunction = Cloner.doSingleRegionFunctionOutlining();
if (!OutlinedFunction)
return {false, nullptr};
- if (tryPartialInline(Cloner))
+ if (tryPartialInline(Cloner))
return {true, OutlinedFunction};
return {false, nullptr};
@@ -1355,9 +1355,9 @@ bool PartialInlinerImpl::tryPartialInline(FunctionCloner &Cloner) {
// Only calculate RelativeToEntryFreq when we are doing single region
// outlining.
BranchProbability RelativeToEntryFreq;
- if (Cloner.ClonedOI)
+ if (Cloner.ClonedOI)
RelativeToEntryFreq = getOutliningCallBBRelativeFreq(Cloner);
- else
+ else
// RelativeToEntryFreq doesn't make sense when we have more than one
// outlined call because each call will have a different relative frequency
// to the entry block. We can consider using the average, but the
@@ -1375,7 +1375,7 @@ bool PartialInlinerImpl::tryPartialInline(FunctionCloner &Cloner) {
OptimizationRemarkEmitter OrigFuncORE(Cloner.OrigFunc);
DebugLoc DLoc;
BasicBlock *Block;
- std::tie(DLoc, Block) = getOneDebugLoc(*Cloner.ClonedFunc);
+ std::tie(DLoc, Block) = getOneDebugLoc(*Cloner.ClonedFunc);
OrigFuncORE.emit([&]() {
return OptimizationRemarkAnalysis(DEBUG_TYPE, "OutlineRegionTooSmall",
DLoc, Block)
@@ -1406,7 +1406,7 @@ bool PartialInlinerImpl::tryPartialInline(FunctionCloner &Cloner) {
for (User *User : Users) {
CallBase *CB = getSupportedCallBase(User);
- if (isLimitReached())
+ if (isLimitReached())
continue;
OptimizationRemarkEmitter CallerORE(CB->getCaller());
@@ -1488,7 +1488,7 @@ bool PartialInlinerImpl::run(Module &M) {
if (Recursive)
continue;
- std::pair<bool, Function *> Result = unswitchFunction(*CurrFunc);
+ std::pair<bool, Function *> Result = unswitchFunction(*CurrFunc);
if (Result.second)
Worklist.push_back(Result.second);
Changed |= Result.first;
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/PassManagerBuilder.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/PassManagerBuilder.cpp
index 2d8f1e0a20..068328391d 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/PassManagerBuilder.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/PassManagerBuilder.cpp
@@ -51,16 +51,16 @@
using namespace llvm;
-cl::opt<bool> RunPartialInlining("enable-partial-inlining", cl::init(false),
- cl::Hidden, cl::ZeroOrMore,
- cl::desc("Run Partial inlinining pass"));
+cl::opt<bool> RunPartialInlining("enable-partial-inlining", cl::init(false),
+ cl::Hidden, cl::ZeroOrMore,
+ cl::desc("Run Partial inlinining pass"));
static cl::opt<bool>
UseGVNAfterVectorization("use-gvn-after-vectorization",
cl::init(false), cl::Hidden,
cl::desc("Run GVN instead of Early CSE after vectorization passes"));
-cl::opt<bool> ExtraVectorizerPasses(
+cl::opt<bool> ExtraVectorizerPasses(
"extra-vectorizer-passes", cl::init(false), cl::Hidden,
cl::desc("Run cleanup optimization passes after vectorization."));
@@ -68,34 +68,34 @@ static cl::opt<bool>
RunLoopRerolling("reroll-loops", cl::Hidden,
cl::desc("Run the loop rerolling pass"));
-cl::opt<bool> RunNewGVN("enable-newgvn", cl::init(false), cl::Hidden,
- cl::desc("Run the NewGVN pass"));
+cl::opt<bool> RunNewGVN("enable-newgvn", cl::init(false), cl::Hidden,
+ cl::desc("Run the NewGVN pass"));
// Experimental option to use CFL-AA
enum class CFLAAType { None, Steensgaard, Andersen, Both };
-static cl::opt<::CFLAAType>
- UseCFLAA("use-cfl-aa", cl::init(::CFLAAType::None), cl::Hidden,
+static cl::opt<::CFLAAType>
+ UseCFLAA("use-cfl-aa", cl::init(::CFLAAType::None), cl::Hidden,
cl::desc("Enable the new, experimental CFL alias analysis"),
- cl::values(clEnumValN(::CFLAAType::None, "none", "Disable CFL-AA"),
- clEnumValN(::CFLAAType::Steensgaard, "steens",
+ cl::values(clEnumValN(::CFLAAType::None, "none", "Disable CFL-AA"),
+ clEnumValN(::CFLAAType::Steensgaard, "steens",
"Enable unification-based CFL-AA"),
- clEnumValN(::CFLAAType::Andersen, "anders",
+ clEnumValN(::CFLAAType::Andersen, "anders",
"Enable inclusion-based CFL-AA"),
- clEnumValN(::CFLAAType::Both, "both",
+ clEnumValN(::CFLAAType::Both, "both",
"Enable both variants of CFL-AA")));
static cl::opt<bool> EnableLoopInterchange(
"enable-loopinterchange", cl::init(false), cl::Hidden,
cl::desc("Enable the new, experimental LoopInterchange Pass"));
-cl::opt<bool> EnableUnrollAndJam("enable-unroll-and-jam", cl::init(false),
- cl::Hidden,
- cl::desc("Enable Unroll And Jam Pass"));
+cl::opt<bool> EnableUnrollAndJam("enable-unroll-and-jam", cl::init(false),
+ cl::Hidden,
+ cl::desc("Enable Unroll And Jam Pass"));
+
+cl::opt<bool> EnableLoopFlatten("enable-loop-flatten", cl::init(false),
+ cl::Hidden,
+ cl::desc("Enable the LoopFlatten Pass"));
-cl::opt<bool> EnableLoopFlatten("enable-loop-flatten", cl::init(false),
- cl::Hidden,
- cl::desc("Enable the LoopFlatten Pass"));
-
static cl::opt<bool>
EnablePrepareForThinLTO("prepare-for-thinlto", cl::init(false), cl::Hidden,
cl::desc("Enable preparation for ThinLTO."));
@@ -107,25 +107,25 @@ static cl::opt<bool>
cl::opt<bool> EnableHotColdSplit("hot-cold-split", cl::init(false),
cl::ZeroOrMore, cl::desc("Enable hot-cold splitting pass"));
-cl::opt<bool> EnableIROutliner("ir-outliner", cl::init(false), cl::Hidden,
- cl::desc("Enable ir outliner pass"));
-
+cl::opt<bool> EnableIROutliner("ir-outliner", cl::init(false), cl::Hidden,
+ cl::desc("Enable ir outliner pass"));
+
static cl::opt<bool> UseLoopVersioningLICM(
"enable-loop-versioning-licm", cl::init(false), cl::Hidden,
cl::desc("Enable the experimental Loop Versioning LICM pass"));
-cl::opt<bool>
+cl::opt<bool>
DisablePreInliner("disable-preinline", cl::init(false), cl::Hidden,
cl::desc("Disable pre-instrumentation inliner"));
-cl::opt<int> PreInlineThreshold(
+cl::opt<int> PreInlineThreshold(
"preinline-threshold", cl::Hidden, cl::init(75), cl::ZeroOrMore,
cl::desc("Control the amount of inlining in pre-instrumentation inliner "
"(default = 75)"));
-cl::opt<bool>
- EnableGVNHoist("enable-gvn-hoist", cl::init(false), cl::ZeroOrMore,
- cl::desc("Enable the GVN hoisting pass (default = off)"));
+cl::opt<bool>
+ EnableGVNHoist("enable-gvn-hoist", cl::init(false), cl::ZeroOrMore,
+ cl::desc("Enable the GVN hoisting pass (default = off)"));
static cl::opt<bool>
DisableLibCallsShrinkWrap("disable-libcalls-shrinkwrap", cl::init(false),
@@ -137,13 +137,13 @@ static cl::opt<bool> EnableSimpleLoopUnswitch(
cl::desc("Enable the simple loop unswitch pass. Also enables independent "
"cleanup passes integrated into the loop pass manager pipeline."));
-cl::opt<bool>
- EnableGVNSink("enable-gvn-sink", cl::init(false), cl::ZeroOrMore,
- cl::desc("Enable the GVN sinking pass (default = off)"));
+cl::opt<bool>
+ EnableGVNSink("enable-gvn-sink", cl::init(false), cl::ZeroOrMore,
+ cl::desc("Enable the GVN sinking pass (default = off)"));
// This option is used in simplifying testing SampleFDO optimizations for
// profile loading.
-cl::opt<bool>
+cl::opt<bool>
EnableCHR("enable-chr", cl::init(true), cl::Hidden,
cl::desc("Enable control height reduction optimization (CHR)"));
@@ -156,15 +156,15 @@ cl::opt<bool> EnableOrderFileInstrumentation(
"enable-order-file-instrumentation", cl::init(false), cl::Hidden,
cl::desc("Enable order file instrumentation (default = off)"));
-cl::opt<bool> EnableMatrix(
- "enable-matrix", cl::init(false), cl::Hidden,
- cl::desc("Enable lowering of the matrix intrinsics"));
+cl::opt<bool> EnableMatrix(
+ "enable-matrix", cl::init(false), cl::Hidden,
+ cl::desc("Enable lowering of the matrix intrinsics"));
+
+cl::opt<bool> EnableConstraintElimination(
+ "enable-constraint-elimination", cl::init(false), cl::Hidden,
+ cl::desc(
+ "Enable pass to eliminate conditions based on linear constraints."));
-cl::opt<bool> EnableConstraintElimination(
- "enable-constraint-elimination", cl::init(false), cl::Hidden,
- cl::desc(
- "Enable pass to eliminate conditions based on linear constraints."));
-
cl::opt<AttributorRunOption> AttributorRun(
"attributor-enable", cl::Hidden, cl::init(AttributorRunOption::NONE),
cl::desc("Enable the attributor inter-procedural deduction pass."),
@@ -276,13 +276,13 @@ void PassManagerBuilder::addExtensionsToPM(ExtensionPointTy ETy,
void PassManagerBuilder::addInitialAliasAnalysisPasses(
legacy::PassManagerBase &PM) const {
switch (UseCFLAA) {
- case ::CFLAAType::Steensgaard:
+ case ::CFLAAType::Steensgaard:
PM.add(createCFLSteensAAWrapperPass());
break;
- case ::CFLAAType::Andersen:
+ case ::CFLAAType::Andersen:
PM.add(createCFLAndersAAWrapperPass());
break;
- case ::CFLAAType::Both:
+ case ::CFLAAType::Both:
PM.add(createCFLSteensAAWrapperPass());
PM.add(createCFLAndersAAWrapperPass());
break;
@@ -306,13 +306,13 @@ void PassManagerBuilder::populateFunctionPassManager(
if (LibraryInfo)
FPM.add(new TargetLibraryInfoWrapperPass(*LibraryInfo));
- // The backends do not handle matrix intrinsics currently.
- // Make sure they are also lowered in O0.
- // FIXME: A lightweight version of the pass should run in the backend
- // pipeline on demand.
- if (EnableMatrix && OptLevel == 0)
- FPM.add(createLowerMatrixIntrinsicsMinimalPass());
-
+ // The backends do not handle matrix intrinsics currently.
+ // Make sure they are also lowered in O0.
+ // FIXME: A lightweight version of the pass should run in the backend
+ // pipeline on demand.
+ if (EnableMatrix && OptLevel == 0)
+ FPM.add(createLowerMatrixIntrinsicsMinimalPass());
+
if (OptLevel == 0) return;
addInitialAliasAnalysisPasses(FPM);
@@ -334,20 +334,20 @@ void PassManagerBuilder::addPGOInstrPasses(legacy::PassManagerBase &MPM,
// Perform the preinline and cleanup passes for O1 and above.
// We will not do this inline for context sensitive PGO (when IsCS is true).
- if (OptLevel > 0 && !DisablePreInliner && PGOSampleUse.empty() && !IsCS) {
+ if (OptLevel > 0 && !DisablePreInliner && PGOSampleUse.empty() && !IsCS) {
// Create preinline pass. We construct an InlineParams object and specify
// the threshold here to avoid the command line options of the regular
// inliner to influence pre-inlining. The only fields of InlineParams we
// care about are DefaultThreshold and HintThreshold.
InlineParams IP;
IP.DefaultThreshold = PreInlineThreshold;
- // FIXME: The hint threshold has the same value used by the regular inliner
- // when not optimzing for size. This should probably be lowered after
- // performance testing.
- // Use PreInlineThreshold for both -Os and -Oz. Not running preinliner makes
- // the instrumented binary unusably large. Even if PreInlineThreshold is not
- // correct thresold for -Oz, it is better than not running preinliner.
- IP.HintThreshold = SizeLevel > 0 ? PreInlineThreshold : 325;
+ // FIXME: The hint threshold has the same value used by the regular inliner
+ // when not optimzing for size. This should probably be lowered after
+ // performance testing.
+ // Use PreInlineThreshold for both -Os and -Oz. Not running preinliner makes
+ // the instrumented binary unusably large. Even if PreInlineThreshold is not
+ // correct thresold for -Oz, it is better than not running preinliner.
+ IP.HintThreshold = SizeLevel > 0 ? PreInlineThreshold : 325;
MPM.add(createFunctionInliningPass(IP));
MPM.add(createSROAPass());
@@ -395,9 +395,9 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
}
}
- if (EnableConstraintElimination)
- MPM.add(createConstraintEliminationPass());
-
+ if (EnableConstraintElimination)
+ MPM.add(createConstraintEliminationPass());
+
if (OptLevel > 1) {
// Speculative execution if the target has divergent branches; otherwise nop.
MPM.add(createSpeculativeExecutionIfHasBranchDivergencePass());
@@ -433,7 +433,7 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
MPM.add(createLoopSimplifyCFGPass());
}
// Rotate Loop - disable header duplication at -Oz
- MPM.add(createLoopRotatePass(SizeLevel == 2 ? 0 : -1, PrepareForLTO));
+ MPM.add(createLoopRotatePass(SizeLevel == 2 ? 0 : -1, PrepareForLTO));
// TODO: Investigate promotion cap for O1.
MPM.add(createLICMPass(LicmMssaOptCap, LicmMssaNoAccForPromotionCap));
if (EnableSimpleLoopUnswitch)
@@ -446,11 +446,11 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
MPM.add(createCFGSimplificationPass());
MPM.add(createInstructionCombiningPass());
// We resume loop passes creating a second loop pipeline here.
- if (EnableLoopFlatten) {
- MPM.add(createLoopFlattenPass()); // Flatten loops
- MPM.add(createLoopSimplifyCFGPass());
- }
- MPM.add(createLoopIdiomPass()); // Recognize idioms like memset.
+ if (EnableLoopFlatten) {
+ MPM.add(createLoopFlattenPass()); // Flatten loops
+ MPM.add(createLoopSimplifyCFGPass());
+ }
+ MPM.add(createLoopIdiomPass()); // Recognize idioms like memset.
MPM.add(createIndVarSimplifyPass()); // Canonicalize indvars
addExtensionsToPM(EP_LateLoopOptimizations, MPM);
MPM.add(createLoopDeletionPass()); // Delete dead loops
@@ -458,15 +458,15 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
if (EnableLoopInterchange)
MPM.add(createLoopInterchangePass()); // Interchange loops
- // Unroll small loops and perform peeling.
+ // Unroll small loops and perform peeling.
MPM.add(createSimpleLoopUnrollPass(OptLevel, DisableUnrollLoops,
ForgetAllSCEVInLoopUnroll));
addExtensionsToPM(EP_LoopOptimizerEnd, MPM);
// This ends the loop pass pipelines.
- // Break up allocas that may now be splittable after loop unrolling.
- MPM.add(createSROAPass());
-
+ // Break up allocas that may now be splittable after loop unrolling.
+ MPM.add(createSROAPass());
+
if (OptLevel > 1) {
MPM.add(createMergedLoadStoreMotionPass()); // Merge ld/st in diamonds
MPM.add(NewGVN ? createNewGVNPass()
@@ -475,9 +475,9 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
MPM.add(createMemCpyOptPass()); // Remove memcpy / form memset
MPM.add(createSCCPPass()); // Constant prop with SCCP
- if (EnableConstraintElimination)
- MPM.add(createConstraintEliminationPass());
-
+ if (EnableConstraintElimination)
+ MPM.add(createConstraintEliminationPass());
+
// Delete dead bit computations (instcombine runs after to fold away the dead
// computations, and then ADCE will run later to exploit any new DCE
// opportunities that creates).
@@ -490,11 +490,11 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
if (OptLevel > 1) {
MPM.add(createJumpThreadingPass()); // Thread jumps
MPM.add(createCorrelatedValuePropagationPass());
- }
- MPM.add(createAggressiveDCEPass()); // Delete dead instructions
-
- // TODO: Investigate if this is too expensive at O1.
- if (OptLevel > 1) {
+ }
+ MPM.add(createAggressiveDCEPass()); // Delete dead instructions
+
+ // TODO: Investigate if this is too expensive at O1.
+ if (OptLevel > 1) {
MPM.add(createDeadStoreEliminationPass()); // Delete dead stores
MPM.add(createLICMPass(LicmMssaOptCap, LicmMssaNoAccForPromotionCap));
}
@@ -520,8 +520,8 @@ void PassManagerBuilder::populateModulePassManager(
// is handled separately, so just check this is not the ThinLTO post-link.
bool DefaultOrPreLinkPipeline = !PerformThinLTO;
- MPM.add(createAnnotation2MetadataLegacyPass());
-
+ MPM.add(createAnnotation2MetadataLegacyPass());
+
if (!PGOSampleUse.empty()) {
MPM.add(createPruneEHPass());
// In ThinLTO mode, when flattened profile is used, all the available
@@ -572,8 +572,8 @@ void PassManagerBuilder::populateModulePassManager(
// new unnamed globals.
MPM.add(createNameAnonGlobalPass());
}
-
- MPM.add(createAnnotationRemarksLegacyPass());
+
+ MPM.add(createAnnotationRemarksLegacyPass());
return;
}
@@ -777,7 +777,7 @@ void PassManagerBuilder::populateModulePassManager(
// Re-rotate loops in all our loop nests. These may have fallout out of
// rotated form due to GVN or other transformations, and the vectorizer relies
// on the rotated form. Disable header duplication at -Oz.
- MPM.add(createLoopRotatePass(SizeLevel == 2 ? 0 : -1, PrepareForLTO));
+ MPM.add(createLoopRotatePass(SizeLevel == 2 ? 0 : -1, PrepareForLTO));
// Distribute loops to allow partial vectorization. I.e. isolate dependences
// into separate loop that would otherwise inhibit vectorization. This is
@@ -818,14 +818,14 @@ void PassManagerBuilder::populateModulePassManager(
// convert to more optimized IR using more aggressive simplify CFG options.
// The extra sinking transform can create larger basic blocks, so do this
// before SLP vectorization.
- // FIXME: study whether hoisting and/or sinking of common instructions should
- // be delayed until after SLP vectorizer.
- MPM.add(createCFGSimplificationPass(SimplifyCFGOptions()
- .forwardSwitchCondToPhi(true)
- .convertSwitchToLookupTable(true)
- .needCanonicalLoops(false)
- .hoistCommonInsts(true)
- .sinkCommonInsts(true)));
+ // FIXME: study whether hoisting and/or sinking of common instructions should
+ // be delayed until after SLP vectorizer.
+ MPM.add(createCFGSimplificationPass(SimplifyCFGOptions()
+ .forwardSwitchCondToPhi(true)
+ .convertSwitchToLookupTable(true)
+ .needCanonicalLoops(false)
+ .hoistCommonInsts(true)
+ .sinkCommonInsts(true)));
if (SLPVectorize) {
MPM.add(createSLPVectorizerPass()); // Vectorize parallel scalar chains.
@@ -883,9 +883,9 @@ void PassManagerBuilder::populateModulePassManager(
if (EnableHotColdSplit && !(PrepareForLTO || PrepareForThinLTO))
MPM.add(createHotColdSplittingPass());
- if (EnableIROutliner)
- MPM.add(createIROutlinerPass());
-
+ if (EnableIROutliner)
+ MPM.add(createIROutlinerPass());
+
if (MergeFunctions)
MPM.add(createMergeFunctionsPass());
@@ -917,8 +917,8 @@ void PassManagerBuilder::populateModulePassManager(
// Rename anon globals to be able to handle them in the summary
MPM.add(createNameAnonGlobalPass());
}
-
- MPM.add(createAnnotationRemarksLegacyPass());
+
+ MPM.add(createAnnotationRemarksLegacyPass());
}
void PassManagerBuilder::addLTOOptimizationPasses(legacy::PassManagerBase &PM) {
@@ -1037,7 +1037,7 @@ void PassManagerBuilder::addLTOOptimizationPasses(legacy::PassManagerBase &PM) {
// The IPO passes may leave cruft around. Clean up after them.
PM.add(createInstructionCombiningPass());
addExtensionsToPM(EP_Peephole, PM);
- PM.add(createJumpThreadingPass(/*FreezeSelectCond*/ true));
+ PM.add(createJumpThreadingPass(/*FreezeSelectCond*/ true));
// Break up allocas
PM.add(createSROAPass());
@@ -1059,23 +1059,23 @@ void PassManagerBuilder::addLTOOptimizationPasses(legacy::PassManagerBase &PM) {
// Nuke dead stores.
PM.add(createDeadStoreEliminationPass());
- PM.add(createMergedLoadStoreMotionPass()); // Merge ld/st in diamonds.
+ PM.add(createMergedLoadStoreMotionPass()); // Merge ld/st in diamonds.
// More loops are countable; try to optimize them.
- if (EnableLoopFlatten)
- PM.add(createLoopFlattenPass());
+ if (EnableLoopFlatten)
+ PM.add(createLoopFlattenPass());
PM.add(createIndVarSimplifyPass());
PM.add(createLoopDeletionPass());
if (EnableLoopInterchange)
PM.add(createLoopInterchangePass());
- if (EnableConstraintElimination)
- PM.add(createConstraintEliminationPass());
-
- // Unroll small loops and perform peeling.
+ if (EnableConstraintElimination)
+ PM.add(createConstraintEliminationPass());
+
+ // Unroll small loops and perform peeling.
PM.add(createSimpleLoopUnrollPass(OptLevel, DisableUnrollLoops,
ForgetAllSCEVInLoopUnroll));
- PM.add(createLoopDistributePass());
+ PM.add(createLoopDistributePass());
PM.add(createLoopVectorizePass(true, !LoopVectorize));
// The vectorizer may have significantly shortened a loop body; unroll again.
PM.add(createLoopUnrollPass(OptLevel, DisableUnrollLoops,
@@ -1087,8 +1087,8 @@ void PassManagerBuilder::addLTOOptimizationPasses(legacy::PassManagerBase &PM) {
// we may have exposed more scalar opportunities. Run parts of the scalar
// optimizer again at this point.
PM.add(createInstructionCombiningPass()); // Initial cleanup
- PM.add(createCFGSimplificationPass(SimplifyCFGOptions() // if-convert
- .hoistCommonInsts(true)));
+ PM.add(createCFGSimplificationPass(SimplifyCFGOptions() // if-convert
+ .hoistCommonInsts(true)));
PM.add(createSCCPPass()); // Propagate exposed constants
PM.add(createInstructionCombiningPass()); // Clean up again
PM.add(createBitTrackingDCEPass());
@@ -1107,7 +1107,7 @@ void PassManagerBuilder::addLTOOptimizationPasses(legacy::PassManagerBase &PM) {
PM.add(createInstructionCombiningPass());
addExtensionsToPM(EP_Peephole, PM);
- PM.add(createJumpThreadingPass(/*FreezeSelectCond*/ true));
+ PM.add(createJumpThreadingPass(/*FreezeSelectCond*/ true));
}
void PassManagerBuilder::addLateLTOOptimizationPasses(
@@ -1118,8 +1118,8 @@ void PassManagerBuilder::addLateLTOOptimizationPasses(
PM.add(createHotColdSplittingPass());
// Delete basic blocks, which optimization passes may have killed.
- PM.add(
- createCFGSimplificationPass(SimplifyCFGOptions().hoistCommonInsts(true)));
+ PM.add(
+ createCFGSimplificationPass(SimplifyCFGOptions().hoistCommonInsts(true)));
// Drop bodies of available externally objects to improve GlobalDCE.
PM.add(createEliminateAvailableExternallyPass());
@@ -1201,8 +1201,8 @@ void PassManagerBuilder::populateLTOPassManager(legacy::PassManagerBase &PM) {
addExtensionsToPM(EP_FullLinkTimeOptimizationLast, PM);
- PM.add(createAnnotationRemarksLegacyPass());
-
+ PM.add(createAnnotationRemarksLegacyPass());
+
if (VerifyOutput)
PM.add(createVerifierPass());
}
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/PruneEH.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/PruneEH.cpp
index 3143f3abfc..3f3b18771c 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/PruneEH.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/PruneEH.cpp
@@ -13,7 +13,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/CallGraph.h"
@@ -28,10 +28,10 @@
#include "llvm/InitializePasses.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/IPO.h"
-#include "llvm/Transforms/Utils/CallGraphUpdater.h"
+#include "llvm/Transforms/Utils/CallGraphUpdater.h"
#include "llvm/Transforms/Utils/Local.h"
#include <algorithm>
-
+
using namespace llvm;
#define DEBUG_TYPE "prune-eh"
@@ -50,8 +50,8 @@ namespace {
bool runOnSCC(CallGraphSCC &SCC) override;
};
}
-static bool SimplifyFunction(Function *F, CallGraphUpdater &CGU);
-static void DeleteBasicBlock(BasicBlock *BB, CallGraphUpdater &CGU);
+static bool SimplifyFunction(Function *F, CallGraphUpdater &CGU);
+static void DeleteBasicBlock(BasicBlock *BB, CallGraphUpdater &CGU);
char PruneEH::ID = 0;
INITIALIZE_PASS_BEGIN(PruneEH, "prune-eh",
@@ -62,17 +62,17 @@ INITIALIZE_PASS_END(PruneEH, "prune-eh",
Pass *llvm::createPruneEHPass() { return new PruneEH(); }
-static bool runImpl(CallGraphUpdater &CGU, SetVector<Function *> &Functions) {
-#ifndef NDEBUG
- for (auto *F : Functions)
- assert(F && "null Function");
-#endif
+static bool runImpl(CallGraphUpdater &CGU, SetVector<Function *> &Functions) {
+#ifndef NDEBUG
+ for (auto *F : Functions)
+ assert(F && "null Function");
+#endif
bool MadeChange = false;
// First pass, scan all of the functions in the SCC, simplifying them
// according to what we know.
- for (Function *F : Functions)
- MadeChange |= SimplifyFunction(F, CGU);
+ for (Function *F : Functions)
+ MadeChange |= SimplifyFunction(F, CGU);
// Next, check to see if any callees might throw or if there are any external
// functions in this SCC: if so, we cannot prune any functions in this SCC.
@@ -82,8 +82,8 @@ static bool runImpl(CallGraphUpdater &CGU, SetVector<Function *> &Functions) {
// obviously the SCC might throw.
//
bool SCCMightUnwind = false, SCCMightReturn = false;
- for (Function *F : Functions) {
- if (!F->hasExactDefinition()) {
+ for (Function *F : Functions) {
+ if (!F->hasExactDefinition()) {
SCCMightUnwind |= !F->doesNotThrow();
SCCMightReturn |= !F->doesNotReturn();
} else {
@@ -121,7 +121,7 @@ static bool runImpl(CallGraphUpdater &CGU, SetVector<Function *> &Functions) {
if (Function *Callee = CI->getCalledFunction()) {
// If the callee is outside our current SCC then we may throw
// because it might. If it is inside, do nothing.
- if (Functions.contains(Callee))
+ if (Functions.contains(Callee))
InstMightUnwind = false;
}
}
@@ -133,7 +133,7 @@ static bool runImpl(CallGraphUpdater &CGU, SetVector<Function *> &Functions) {
if (IA->hasSideEffects())
SCCMightReturn = true;
}
- }
+ }
if (SCCMightUnwind && SCCMightReturn)
break;
}
@@ -141,7 +141,7 @@ static bool runImpl(CallGraphUpdater &CGU, SetVector<Function *> &Functions) {
// If the SCC doesn't unwind or doesn't throw, note this fact.
if (!SCCMightUnwind || !SCCMightReturn)
- for (Function *F : Functions) {
+ for (Function *F : Functions) {
if (!SCCMightUnwind && !F->hasFnAttribute(Attribute::NoUnwind)) {
F->addFnAttr(Attribute::NoUnwind);
MadeChange = true;
@@ -153,11 +153,11 @@ static bool runImpl(CallGraphUpdater &CGU, SetVector<Function *> &Functions) {
}
}
- for (Function *F : Functions) {
+ for (Function *F : Functions) {
// Convert any invoke instructions to non-throwing functions in this node
// into call instructions with a branch. This makes the exception blocks
// dead.
- MadeChange |= SimplifyFunction(F, CGU);
+ MadeChange |= SimplifyFunction(F, CGU);
}
return MadeChange;
@@ -166,22 +166,22 @@ static bool runImpl(CallGraphUpdater &CGU, SetVector<Function *> &Functions) {
bool PruneEH::runOnSCC(CallGraphSCC &SCC) {
if (skipSCC(SCC))
return false;
- SetVector<Function *> Functions;
- for (auto &N : SCC) {
- if (auto *F = N->getFunction())
- Functions.insert(F);
- }
+ SetVector<Function *> Functions;
+ for (auto &N : SCC) {
+ if (auto *F = N->getFunction())
+ Functions.insert(F);
+ }
CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
- CallGraphUpdater CGU;
- CGU.initialize(CG, SCC);
- return runImpl(CGU, Functions);
+ CallGraphUpdater CGU;
+ CGU.initialize(CG, SCC);
+ return runImpl(CGU, Functions);
}
// SimplifyFunction - Given information about callees, simplify the specified
// function if we have invokes to non-unwinding functions or code after calls to
// no-return functions.
-static bool SimplifyFunction(Function *F, CallGraphUpdater &CGU) {
+static bool SimplifyFunction(Function *F, CallGraphUpdater &CGU) {
bool MadeChange = false;
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator()))
@@ -191,7 +191,7 @@ static bool SimplifyFunction(Function *F, CallGraphUpdater &CGU) {
// If the unwind block is now dead, nuke it.
if (pred_empty(UnwindBlock))
- DeleteBasicBlock(UnwindBlock, CGU); // Delete the new BB.
+ DeleteBasicBlock(UnwindBlock, CGU); // Delete the new BB.
++NumRemoved;
MadeChange = true;
@@ -211,7 +211,7 @@ static bool SimplifyFunction(Function *F, CallGraphUpdater &CGU) {
BB->getInstList().pop_back();
new UnreachableInst(BB->getContext(), &*BB);
- DeleteBasicBlock(New, CGU); // Delete the new BB.
+ DeleteBasicBlock(New, CGU); // Delete the new BB.
MadeChange = true;
++NumUnreach;
break;
@@ -224,7 +224,7 @@ static bool SimplifyFunction(Function *F, CallGraphUpdater &CGU) {
/// DeleteBasicBlock - remove the specified basic block from the program,
/// updating the callgraph to reflect any now-obsolete edges due to calls that
/// exist in the BB.
-static void DeleteBasicBlock(BasicBlock *BB, CallGraphUpdater &CGU) {
+static void DeleteBasicBlock(BasicBlock *BB, CallGraphUpdater &CGU) {
assert(pred_empty(BB) && "BB is not dead!");
Instruction *TokenInst = nullptr;
@@ -240,9 +240,9 @@ static void DeleteBasicBlock(BasicBlock *BB, CallGraphUpdater &CGU) {
if (auto *Call = dyn_cast<CallBase>(&*I)) {
const Function *Callee = Call->getCalledFunction();
if (!Callee || !Intrinsic::isLeaf(Callee->getIntrinsicID()))
- CGU.removeCallSite(*Call);
+ CGU.removeCallSite(*Call);
else if (!Callee->isIntrinsic())
- CGU.removeCallSite(*Call);
+ CGU.removeCallSite(*Call);
}
if (!I->use_empty())
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/SampleContextTracker.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/SampleContextTracker.cpp
index 37dcc0feae..158fa0771c 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/SampleContextTracker.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/SampleContextTracker.cpp
@@ -1,585 +1,585 @@
-//===- SampleContextTracker.cpp - Context-sensitive Profile Tracker -------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the SampleContextTracker used by CSSPGO.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/IPO/SampleContextTracker.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/ProfileData/SampleProf.h"
-#include <map>
-#include <queue>
-#include <vector>
-
-using namespace llvm;
-using namespace sampleprof;
-
-#define DEBUG_TYPE "sample-context-tracker"
-
-namespace llvm {
-
-ContextTrieNode *ContextTrieNode::getChildContext(const LineLocation &CallSite,
- StringRef CalleeName) {
- if (CalleeName.empty())
- return getHottestChildContext(CallSite);
-
- uint32_t Hash = nodeHash(CalleeName, CallSite);
- auto It = AllChildContext.find(Hash);
- if (It != AllChildContext.end())
- return &It->second;
- return nullptr;
-}
-
-ContextTrieNode *
-ContextTrieNode::getHottestChildContext(const LineLocation &CallSite) {
- // CSFDO-TODO: This could be slow, change AllChildContext so we can
- // do point look up for child node by call site alone.
- // Retrieve the child node with max count for indirect call
- ContextTrieNode *ChildNodeRet = nullptr;
- uint64_t MaxCalleeSamples = 0;
- for (auto &It : AllChildContext) {
- ContextTrieNode &ChildNode = It.second;
- if (ChildNode.CallSiteLoc != CallSite)
- continue;
- FunctionSamples *Samples = ChildNode.getFunctionSamples();
- if (!Samples)
- continue;
- if (Samples->getTotalSamples() > MaxCalleeSamples) {
- ChildNodeRet = &ChildNode;
- MaxCalleeSamples = Samples->getTotalSamples();
- }
- }
-
- return ChildNodeRet;
-}
-
-ContextTrieNode &ContextTrieNode::moveToChildContext(
- const LineLocation &CallSite, ContextTrieNode &&NodeToMove,
- StringRef ContextStrToRemove, bool DeleteNode) {
- uint32_t Hash = nodeHash(NodeToMove.getFuncName(), CallSite);
- assert(!AllChildContext.count(Hash) && "Node to remove must exist");
- LineLocation OldCallSite = NodeToMove.CallSiteLoc;
- ContextTrieNode &OldParentContext = *NodeToMove.getParentContext();
- AllChildContext[Hash] = NodeToMove;
- ContextTrieNode &NewNode = AllChildContext[Hash];
- NewNode.CallSiteLoc = CallSite;
-
- // Walk through nodes in the moved the subtree, and update
- // FunctionSamples' context as for the context promotion.
- // We also need to set new parant link for all children.
- std::queue<ContextTrieNode *> NodeToUpdate;
- NewNode.setParentContext(this);
- NodeToUpdate.push(&NewNode);
-
- while (!NodeToUpdate.empty()) {
- ContextTrieNode *Node = NodeToUpdate.front();
- NodeToUpdate.pop();
- FunctionSamples *FSamples = Node->getFunctionSamples();
-
- if (FSamples) {
- FSamples->getContext().promoteOnPath(ContextStrToRemove);
- FSamples->getContext().setState(SyntheticContext);
- LLVM_DEBUG(dbgs() << " Context promoted to: " << FSamples->getContext()
- << "\n");
- }
-
- for (auto &It : Node->getAllChildContext()) {
- ContextTrieNode *ChildNode = &It.second;
- ChildNode->setParentContext(Node);
- NodeToUpdate.push(ChildNode);
- }
- }
-
- // Original context no longer needed, destroy if requested.
- if (DeleteNode)
- OldParentContext.removeChildContext(OldCallSite, NewNode.getFuncName());
-
- return NewNode;
-}
-
-void ContextTrieNode::removeChildContext(const LineLocation &CallSite,
- StringRef CalleeName) {
- uint32_t Hash = nodeHash(CalleeName, CallSite);
- // Note this essentially calls dtor and destroys that child context
- AllChildContext.erase(Hash);
-}
-
-std::map<uint32_t, ContextTrieNode> &ContextTrieNode::getAllChildContext() {
- return AllChildContext;
-}
-
-const StringRef ContextTrieNode::getFuncName() const { return FuncName; }
-
-FunctionSamples *ContextTrieNode::getFunctionSamples() const {
- return FuncSamples;
-}
-
-void ContextTrieNode::setFunctionSamples(FunctionSamples *FSamples) {
- FuncSamples = FSamples;
-}
-
-LineLocation ContextTrieNode::getCallSiteLoc() const { return CallSiteLoc; }
-
-ContextTrieNode *ContextTrieNode::getParentContext() const {
- return ParentContext;
-}
-
-void ContextTrieNode::setParentContext(ContextTrieNode *Parent) {
- ParentContext = Parent;
-}
-
-void ContextTrieNode::dump() {
- dbgs() << "Node: " << FuncName << "\n"
- << " Callsite: " << CallSiteLoc << "\n"
- << " Children:\n";
-
- for (auto &It : AllChildContext) {
- dbgs() << " Node: " << It.second.getFuncName() << "\n";
- }
-}
-
-uint32_t ContextTrieNode::nodeHash(StringRef ChildName,
- const LineLocation &Callsite) {
- // We still use child's name for child hash, this is
- // because for children of root node, we don't have
- // different line/discriminator, and we'll rely on name
- // to differentiate children.
- uint32_t NameHash = std::hash<std::string>{}(ChildName.str());
- uint32_t LocId = (Callsite.LineOffset << 16) | Callsite.Discriminator;
- return NameHash + (LocId << 5) + LocId;
-}
-
-ContextTrieNode *ContextTrieNode::getOrCreateChildContext(
- const LineLocation &CallSite, StringRef CalleeName, bool AllowCreate) {
- uint32_t Hash = nodeHash(CalleeName, CallSite);
- auto It = AllChildContext.find(Hash);
- if (It != AllChildContext.end()) {
- assert(It->second.getFuncName() == CalleeName &&
- "Hash collision for child context node");
- return &It->second;
- }
-
- if (!AllowCreate)
- return nullptr;
-
- AllChildContext[Hash] = ContextTrieNode(this, CalleeName, nullptr, CallSite);
- return &AllChildContext[Hash];
-}
-
-// Profiler tracker than manages profiles and its associated context
-SampleContextTracker::SampleContextTracker(
- StringMap<FunctionSamples> &Profiles) {
- for (auto &FuncSample : Profiles) {
- FunctionSamples *FSamples = &FuncSample.second;
- SampleContext Context(FuncSample.first(), RawContext);
- LLVM_DEBUG(dbgs() << "Tracking Context for function: " << Context << "\n");
- if (!Context.isBaseContext())
- FuncToCtxtProfileSet[Context.getNameWithoutContext()].insert(FSamples);
- ContextTrieNode *NewNode = getOrCreateContextPath(Context, true);
- assert(!NewNode->getFunctionSamples() &&
- "New node can't have sample profile");
- NewNode->setFunctionSamples(FSamples);
- }
-}
-
-FunctionSamples *
-SampleContextTracker::getCalleeContextSamplesFor(const CallBase &Inst,
- StringRef CalleeName) {
- LLVM_DEBUG(dbgs() << "Getting callee context for instr: " << Inst << "\n");
- DILocation *DIL = Inst.getDebugLoc();
- if (!DIL)
- return nullptr;
-
- // For indirect call, CalleeName will be empty, in which case the context
- // profile for callee with largest total samples will be returned.
- ContextTrieNode *CalleeContext = getCalleeContextFor(DIL, CalleeName);
- if (CalleeContext) {
- FunctionSamples *FSamples = CalleeContext->getFunctionSamples();
- LLVM_DEBUG(if (FSamples) {
- dbgs() << " Callee context found: " << FSamples->getContext() << "\n";
- });
- return FSamples;
- }
-
- return nullptr;
-}
-
-std::vector<const FunctionSamples *>
-SampleContextTracker::getIndirectCalleeContextSamplesFor(
- const DILocation *DIL) {
- std::vector<const FunctionSamples *> R;
- if (!DIL)
- return R;
-
- ContextTrieNode *CallerNode = getContextFor(DIL);
- LineLocation CallSite = FunctionSamples::getCallSiteIdentifier(DIL);
- for (auto &It : CallerNode->getAllChildContext()) {
- ContextTrieNode &ChildNode = It.second;
- if (ChildNode.getCallSiteLoc() != CallSite)
- continue;
- if (FunctionSamples *CalleeSamples = ChildNode.getFunctionSamples())
- R.push_back(CalleeSamples);
- }
-
- return R;
-}
-
-FunctionSamples *
-SampleContextTracker::getContextSamplesFor(const DILocation *DIL) {
- assert(DIL && "Expect non-null location");
-
- ContextTrieNode *ContextNode = getContextFor(DIL);
- if (!ContextNode)
- return nullptr;
-
- // We may have inlined callees during pre-LTO compilation, in which case
- // we need to rely on the inline stack from !dbg to mark context profile
- // as inlined, instead of `MarkContextSamplesInlined` during inlining.
- // Sample profile loader walks through all instructions to get profile,
- // which calls this function. So once that is done, all previously inlined
- // context profile should be marked properly.
- FunctionSamples *Samples = ContextNode->getFunctionSamples();
- if (Samples && ContextNode->getParentContext() != &RootContext)
- Samples->getContext().setState(InlinedContext);
-
- return Samples;
-}
-
-FunctionSamples *
-SampleContextTracker::getContextSamplesFor(const SampleContext &Context) {
- ContextTrieNode *Node = getContextFor(Context);
- if (!Node)
- return nullptr;
-
- return Node->getFunctionSamples();
-}
-
-SampleContextTracker::ContextSamplesTy &
-SampleContextTracker::getAllContextSamplesFor(const Function &Func) {
- StringRef CanonName = FunctionSamples::getCanonicalFnName(Func);
- return FuncToCtxtProfileSet[CanonName];
-}
-
-SampleContextTracker::ContextSamplesTy &
-SampleContextTracker::getAllContextSamplesFor(StringRef Name) {
- return FuncToCtxtProfileSet[Name];
-}
-
-FunctionSamples *SampleContextTracker::getBaseSamplesFor(const Function &Func,
- bool MergeContext) {
- StringRef CanonName = FunctionSamples::getCanonicalFnName(Func);
- return getBaseSamplesFor(CanonName, MergeContext);
-}
-
-FunctionSamples *SampleContextTracker::getBaseSamplesFor(StringRef Name,
- bool MergeContext) {
- LLVM_DEBUG(dbgs() << "Getting base profile for function: " << Name << "\n");
- // Base profile is top-level node (child of root node), so try to retrieve
- // existing top-level node for given function first. If it exists, it could be
- // that we've merged base profile before, or there's actually context-less
- // profile from the input (e.g. due to unreliable stack walking).
- ContextTrieNode *Node = getTopLevelContextNode(Name);
- if (MergeContext) {
- LLVM_DEBUG(dbgs() << " Merging context profile into base profile: " << Name
- << "\n");
-
- // We have profile for function under different contexts,
- // create synthetic base profile and merge context profiles
- // into base profile.
- for (auto *CSamples : FuncToCtxtProfileSet[Name]) {
- SampleContext &Context = CSamples->getContext();
- ContextTrieNode *FromNode = getContextFor(Context);
- if (FromNode == Node)
- continue;
-
- // Skip inlined context profile and also don't re-merge any context
- if (Context.hasState(InlinedContext) || Context.hasState(MergedContext))
- continue;
-
- ContextTrieNode &ToNode = promoteMergeContextSamplesTree(*FromNode);
- assert((!Node || Node == &ToNode) && "Expect only one base profile");
- Node = &ToNode;
- }
- }
-
- // Still no profile even after merge/promotion (if allowed)
- if (!Node)
- return nullptr;
-
- return Node->getFunctionSamples();
-}
-
-void SampleContextTracker::markContextSamplesInlined(
- const FunctionSamples *InlinedSamples) {
- assert(InlinedSamples && "Expect non-null inlined samples");
- LLVM_DEBUG(dbgs() << "Marking context profile as inlined: "
- << InlinedSamples->getContext() << "\n");
- InlinedSamples->getContext().setState(InlinedContext);
-}
-
-void SampleContextTracker::promoteMergeContextSamplesTree(
- const Instruction &Inst, StringRef CalleeName) {
- LLVM_DEBUG(dbgs() << "Promoting and merging context tree for instr: \n"
- << Inst << "\n");
- // Get the caller context for the call instruction, we don't use callee
- // name from call because there can be context from indirect calls too.
- DILocation *DIL = Inst.getDebugLoc();
- ContextTrieNode *CallerNode = getContextFor(DIL);
- if (!CallerNode)
- return;
-
- // Get the context that needs to be promoted
- LineLocation CallSite = FunctionSamples::getCallSiteIdentifier(DIL);
- // For indirect call, CalleeName will be empty, in which case we need to
- // promote all non-inlined child context profiles.
- if (CalleeName.empty()) {
- for (auto &It : CallerNode->getAllChildContext()) {
- ContextTrieNode *NodeToPromo = &It.second;
- if (CallSite != NodeToPromo->getCallSiteLoc())
- continue;
- FunctionSamples *FromSamples = NodeToPromo->getFunctionSamples();
- if (FromSamples && FromSamples->getContext().hasState(InlinedContext))
- continue;
- promoteMergeContextSamplesTree(*NodeToPromo);
- }
- return;
- }
-
- // Get the context for the given callee that needs to be promoted
- ContextTrieNode *NodeToPromo =
- CallerNode->getChildContext(CallSite, CalleeName);
- if (!NodeToPromo)
- return;
-
- promoteMergeContextSamplesTree(*NodeToPromo);
-}
-
-ContextTrieNode &SampleContextTracker::promoteMergeContextSamplesTree(
- ContextTrieNode &NodeToPromo) {
- // Promote the input node to be directly under root. This can happen
- // when we decided to not inline a function under context represented
- // by the input node. The promote and merge is then needed to reflect
- // the context profile in the base (context-less) profile.
- FunctionSamples *FromSamples = NodeToPromo.getFunctionSamples();
- assert(FromSamples && "Shouldn't promote a context without profile");
- LLVM_DEBUG(dbgs() << " Found context tree root to promote: "
- << FromSamples->getContext() << "\n");
-
- assert(!FromSamples->getContext().hasState(InlinedContext) &&
- "Shouldn't promote inlined context profile");
- StringRef ContextStrToRemove = FromSamples->getContext().getCallingContext();
- return promoteMergeContextSamplesTree(NodeToPromo, RootContext,
- ContextStrToRemove);
-}
-
-void SampleContextTracker::dump() {
- dbgs() << "Context Profile Tree:\n";
- std::queue<ContextTrieNode *> NodeQueue;
- NodeQueue.push(&RootContext);
-
- while (!NodeQueue.empty()) {
- ContextTrieNode *Node = NodeQueue.front();
- NodeQueue.pop();
- Node->dump();
-
- for (auto &It : Node->getAllChildContext()) {
- ContextTrieNode *ChildNode = &It.second;
- NodeQueue.push(ChildNode);
- }
- }
-}
-
-ContextTrieNode *
-SampleContextTracker::getContextFor(const SampleContext &Context) {
- return getOrCreateContextPath(Context, false);
-}
-
-ContextTrieNode *
-SampleContextTracker::getCalleeContextFor(const DILocation *DIL,
- StringRef CalleeName) {
- assert(DIL && "Expect non-null location");
-
- ContextTrieNode *CallContext = getContextFor(DIL);
- if (!CallContext)
- return nullptr;
-
- // When CalleeName is empty, the child context profile with max
- // total samples will be returned.
- return CallContext->getChildContext(
- FunctionSamples::getCallSiteIdentifier(DIL), CalleeName);
-}
-
-ContextTrieNode *SampleContextTracker::getContextFor(const DILocation *DIL) {
- assert(DIL && "Expect non-null location");
- SmallVector<std::pair<LineLocation, StringRef>, 10> S;
-
- // Use C++ linkage name if possible.
- const DILocation *PrevDIL = DIL;
- for (DIL = DIL->getInlinedAt(); DIL; DIL = DIL->getInlinedAt()) {
- StringRef Name = PrevDIL->getScope()->getSubprogram()->getLinkageName();
- if (Name.empty())
- Name = PrevDIL->getScope()->getSubprogram()->getName();
- S.push_back(
- std::make_pair(FunctionSamples::getCallSiteIdentifier(DIL),
- PrevDIL->getScope()->getSubprogram()->getLinkageName()));
- PrevDIL = DIL;
- }
-
- // Push root node, note that root node like main may only
- // a name, but not linkage name.
- StringRef RootName = PrevDIL->getScope()->getSubprogram()->getLinkageName();
- if (RootName.empty())
- RootName = PrevDIL->getScope()->getSubprogram()->getName();
- S.push_back(std::make_pair(LineLocation(0, 0), RootName));
-
- ContextTrieNode *ContextNode = &RootContext;
- int I = S.size();
- while (--I >= 0 && ContextNode) {
- LineLocation &CallSite = S[I].first;
- StringRef &CalleeName = S[I].second;
- ContextNode = ContextNode->getChildContext(CallSite, CalleeName);
- }
-
- if (I < 0)
- return ContextNode;
-
- return nullptr;
-}
-
-ContextTrieNode *
-SampleContextTracker::getOrCreateContextPath(const SampleContext &Context,
- bool AllowCreate) {
- ContextTrieNode *ContextNode = &RootContext;
- StringRef ContextRemain = Context;
- StringRef ChildContext;
- StringRef CalleeName;
- LineLocation CallSiteLoc(0, 0);
-
- while (ContextNode && !ContextRemain.empty()) {
- auto ContextSplit = SampleContext::splitContextString(ContextRemain);
- ChildContext = ContextSplit.first;
- ContextRemain = ContextSplit.second;
- LineLocation NextCallSiteLoc(0, 0);
- SampleContext::decodeContextString(ChildContext, CalleeName,
- NextCallSiteLoc);
-
- // Create child node at parent line/disc location
- if (AllowCreate) {
- ContextNode =
- ContextNode->getOrCreateChildContext(CallSiteLoc, CalleeName);
- } else {
- ContextNode = ContextNode->getChildContext(CallSiteLoc, CalleeName);
- }
- CallSiteLoc = NextCallSiteLoc;
- }
-
- assert((!AllowCreate || ContextNode) &&
- "Node must exist if creation is allowed");
- return ContextNode;
-}
-
-ContextTrieNode *SampleContextTracker::getTopLevelContextNode(StringRef FName) {
- return RootContext.getChildContext(LineLocation(0, 0), FName);
-}
-
-ContextTrieNode &SampleContextTracker::addTopLevelContextNode(StringRef FName) {
- assert(!getTopLevelContextNode(FName) && "Node to add must not exist");
- return *RootContext.getOrCreateChildContext(LineLocation(0, 0), FName);
-}
-
-void SampleContextTracker::mergeContextNode(ContextTrieNode &FromNode,
- ContextTrieNode &ToNode,
- StringRef ContextStrToRemove) {
- FunctionSamples *FromSamples = FromNode.getFunctionSamples();
- FunctionSamples *ToSamples = ToNode.getFunctionSamples();
- if (FromSamples && ToSamples) {
- // Merge/duplicate FromSamples into ToSamples
- ToSamples->merge(*FromSamples);
- ToSamples->getContext().setState(SyntheticContext);
- FromSamples->getContext().setState(MergedContext);
- } else if (FromSamples) {
- // Transfer FromSamples from FromNode to ToNode
- ToNode.setFunctionSamples(FromSamples);
- FromSamples->getContext().setState(SyntheticContext);
- FromSamples->getContext().promoteOnPath(ContextStrToRemove);
- FromNode.setFunctionSamples(nullptr);
- }
-}
-
-ContextTrieNode &SampleContextTracker::promoteMergeContextSamplesTree(
- ContextTrieNode &FromNode, ContextTrieNode &ToNodeParent,
- StringRef ContextStrToRemove) {
- assert(!ContextStrToRemove.empty() && "Context to remove can't be empty");
-
- // Ignore call site location if destination is top level under root
- LineLocation NewCallSiteLoc = LineLocation(0, 0);
- LineLocation OldCallSiteLoc = FromNode.getCallSiteLoc();
- ContextTrieNode &FromNodeParent = *FromNode.getParentContext();
- ContextTrieNode *ToNode = nullptr;
- bool MoveToRoot = (&ToNodeParent == &RootContext);
- if (!MoveToRoot) {
- NewCallSiteLoc = OldCallSiteLoc;
- }
-
- // Locate destination node, create/move if not existing
- ToNode = ToNodeParent.getChildContext(NewCallSiteLoc, FromNode.getFuncName());
- if (!ToNode) {
- // Do not delete node to move from its parent here because
- // caller is iterating over children of that parent node.
- ToNode = &ToNodeParent.moveToChildContext(
- NewCallSiteLoc, std::move(FromNode), ContextStrToRemove, false);
- } else {
- // Destination node exists, merge samples for the context tree
- mergeContextNode(FromNode, *ToNode, ContextStrToRemove);
- LLVM_DEBUG(dbgs() << " Context promoted and merged to: "
- << ToNode->getFunctionSamples()->getContext() << "\n");
-
- // Recursively promote and merge children
- for (auto &It : FromNode.getAllChildContext()) {
- ContextTrieNode &FromChildNode = It.second;
- promoteMergeContextSamplesTree(FromChildNode, *ToNode,
- ContextStrToRemove);
- }
-
- // Remove children once they're all merged
- FromNode.getAllChildContext().clear();
- }
-
- // For root of subtree, remove itself from old parent too
- if (MoveToRoot)
- FromNodeParent.removeChildContext(OldCallSiteLoc, ToNode->getFuncName());
-
- return *ToNode;
-}
-
-// Replace call graph edges with dynamic call edges from the profile.
-void SampleContextTracker::addCallGraphEdges(CallGraph &CG,
- StringMap<Function *> &SymbolMap) {
- // Add profile call edges to the call graph.
- std::queue<ContextTrieNode *> NodeQueue;
- NodeQueue.push(&RootContext);
- while (!NodeQueue.empty()) {
- ContextTrieNode *Node = NodeQueue.front();
- NodeQueue.pop();
- Function *F = SymbolMap.lookup(Node->getFuncName());
- for (auto &I : Node->getAllChildContext()) {
- ContextTrieNode *ChildNode = &I.second;
- NodeQueue.push(ChildNode);
- if (F && !F->isDeclaration()) {
- Function *Callee = SymbolMap.lookup(ChildNode->getFuncName());
- if (Callee && !Callee->isDeclaration())
- CG[F]->addCalledFunction(nullptr, CG[Callee]);
- }
- }
- }
-}
-} // namespace llvm
+//===- SampleContextTracker.cpp - Context-sensitive Profile Tracker -------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the SampleContextTracker used by CSSPGO.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/IPO/SampleContextTracker.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/ProfileData/SampleProf.h"
+#include <map>
+#include <queue>
+#include <vector>
+
+using namespace llvm;
+using namespace sampleprof;
+
+#define DEBUG_TYPE "sample-context-tracker"
+
+namespace llvm {
+
+ContextTrieNode *ContextTrieNode::getChildContext(const LineLocation &CallSite,
+ StringRef CalleeName) {
+ if (CalleeName.empty())
+ return getHottestChildContext(CallSite);
+
+ uint32_t Hash = nodeHash(CalleeName, CallSite);
+ auto It = AllChildContext.find(Hash);
+ if (It != AllChildContext.end())
+ return &It->second;
+ return nullptr;
+}
+
+ContextTrieNode *
+ContextTrieNode::getHottestChildContext(const LineLocation &CallSite) {
+ // CSFDO-TODO: This could be slow, change AllChildContext so we can
+ // do point look up for child node by call site alone.
+ // Retrieve the child node with max count for indirect call
+ ContextTrieNode *ChildNodeRet = nullptr;
+ uint64_t MaxCalleeSamples = 0;
+ for (auto &It : AllChildContext) {
+ ContextTrieNode &ChildNode = It.second;
+ if (ChildNode.CallSiteLoc != CallSite)
+ continue;
+ FunctionSamples *Samples = ChildNode.getFunctionSamples();
+ if (!Samples)
+ continue;
+ if (Samples->getTotalSamples() > MaxCalleeSamples) {
+ ChildNodeRet = &ChildNode;
+ MaxCalleeSamples = Samples->getTotalSamples();
+ }
+ }
+
+ return ChildNodeRet;
+}
+
+ContextTrieNode &ContextTrieNode::moveToChildContext(
+ const LineLocation &CallSite, ContextTrieNode &&NodeToMove,
+ StringRef ContextStrToRemove, bool DeleteNode) {
+ uint32_t Hash = nodeHash(NodeToMove.getFuncName(), CallSite);
+ assert(!AllChildContext.count(Hash) && "Node to remove must exist");
+ LineLocation OldCallSite = NodeToMove.CallSiteLoc;
+ ContextTrieNode &OldParentContext = *NodeToMove.getParentContext();
+ AllChildContext[Hash] = NodeToMove;
+ ContextTrieNode &NewNode = AllChildContext[Hash];
+ NewNode.CallSiteLoc = CallSite;
+
+ // Walk through nodes in the moved the subtree, and update
+ // FunctionSamples' context as for the context promotion.
+ // We also need to set new parant link for all children.
+ std::queue<ContextTrieNode *> NodeToUpdate;
+ NewNode.setParentContext(this);
+ NodeToUpdate.push(&NewNode);
+
+ while (!NodeToUpdate.empty()) {
+ ContextTrieNode *Node = NodeToUpdate.front();
+ NodeToUpdate.pop();
+ FunctionSamples *FSamples = Node->getFunctionSamples();
+
+ if (FSamples) {
+ FSamples->getContext().promoteOnPath(ContextStrToRemove);
+ FSamples->getContext().setState(SyntheticContext);
+ LLVM_DEBUG(dbgs() << " Context promoted to: " << FSamples->getContext()
+ << "\n");
+ }
+
+ for (auto &It : Node->getAllChildContext()) {
+ ContextTrieNode *ChildNode = &It.second;
+ ChildNode->setParentContext(Node);
+ NodeToUpdate.push(ChildNode);
+ }
+ }
+
+ // Original context no longer needed, destroy if requested.
+ if (DeleteNode)
+ OldParentContext.removeChildContext(OldCallSite, NewNode.getFuncName());
+
+ return NewNode;
+}
+
+void ContextTrieNode::removeChildContext(const LineLocation &CallSite,
+ StringRef CalleeName) {
+ uint32_t Hash = nodeHash(CalleeName, CallSite);
+ // Note this essentially calls dtor and destroys that child context
+ AllChildContext.erase(Hash);
+}
+
+std::map<uint32_t, ContextTrieNode> &ContextTrieNode::getAllChildContext() {
+ return AllChildContext;
+}
+
+const StringRef ContextTrieNode::getFuncName() const { return FuncName; }
+
+FunctionSamples *ContextTrieNode::getFunctionSamples() const {
+ return FuncSamples;
+}
+
+void ContextTrieNode::setFunctionSamples(FunctionSamples *FSamples) {
+ FuncSamples = FSamples;
+}
+
+LineLocation ContextTrieNode::getCallSiteLoc() const { return CallSiteLoc; }
+
+ContextTrieNode *ContextTrieNode::getParentContext() const {
+ return ParentContext;
+}
+
+void ContextTrieNode::setParentContext(ContextTrieNode *Parent) {
+ ParentContext = Parent;
+}
+
+void ContextTrieNode::dump() {
+ dbgs() << "Node: " << FuncName << "\n"
+ << " Callsite: " << CallSiteLoc << "\n"
+ << " Children:\n";
+
+ for (auto &It : AllChildContext) {
+ dbgs() << " Node: " << It.second.getFuncName() << "\n";
+ }
+}
+
+uint32_t ContextTrieNode::nodeHash(StringRef ChildName,
+ const LineLocation &Callsite) {
+ // We still use child's name for child hash, this is
+ // because for children of root node, we don't have
+ // different line/discriminator, and we'll rely on name
+ // to differentiate children.
+ uint32_t NameHash = std::hash<std::string>{}(ChildName.str());
+ uint32_t LocId = (Callsite.LineOffset << 16) | Callsite.Discriminator;
+ return NameHash + (LocId << 5) + LocId;
+}
+
+ContextTrieNode *ContextTrieNode::getOrCreateChildContext(
+ const LineLocation &CallSite, StringRef CalleeName, bool AllowCreate) {
+ uint32_t Hash = nodeHash(CalleeName, CallSite);
+ auto It = AllChildContext.find(Hash);
+ if (It != AllChildContext.end()) {
+ assert(It->second.getFuncName() == CalleeName &&
+ "Hash collision for child context node");
+ return &It->second;
+ }
+
+ if (!AllowCreate)
+ return nullptr;
+
+ AllChildContext[Hash] = ContextTrieNode(this, CalleeName, nullptr, CallSite);
+ return &AllChildContext[Hash];
+}
+
+// Profiler tracker than manages profiles and its associated context
+SampleContextTracker::SampleContextTracker(
+ StringMap<FunctionSamples> &Profiles) {
+ for (auto &FuncSample : Profiles) {
+ FunctionSamples *FSamples = &FuncSample.second;
+ SampleContext Context(FuncSample.first(), RawContext);
+ LLVM_DEBUG(dbgs() << "Tracking Context for function: " << Context << "\n");
+ if (!Context.isBaseContext())
+ FuncToCtxtProfileSet[Context.getNameWithoutContext()].insert(FSamples);
+ ContextTrieNode *NewNode = getOrCreateContextPath(Context, true);
+ assert(!NewNode->getFunctionSamples() &&
+ "New node can't have sample profile");
+ NewNode->setFunctionSamples(FSamples);
+ }
+}
+
+FunctionSamples *
+SampleContextTracker::getCalleeContextSamplesFor(const CallBase &Inst,
+ StringRef CalleeName) {
+ LLVM_DEBUG(dbgs() << "Getting callee context for instr: " << Inst << "\n");
+ DILocation *DIL = Inst.getDebugLoc();
+ if (!DIL)
+ return nullptr;
+
+ // For indirect call, CalleeName will be empty, in which case the context
+ // profile for callee with largest total samples will be returned.
+ ContextTrieNode *CalleeContext = getCalleeContextFor(DIL, CalleeName);
+ if (CalleeContext) {
+ FunctionSamples *FSamples = CalleeContext->getFunctionSamples();
+ LLVM_DEBUG(if (FSamples) {
+ dbgs() << " Callee context found: " << FSamples->getContext() << "\n";
+ });
+ return FSamples;
+ }
+
+ return nullptr;
+}
+
+std::vector<const FunctionSamples *>
+SampleContextTracker::getIndirectCalleeContextSamplesFor(
+ const DILocation *DIL) {
+ std::vector<const FunctionSamples *> R;
+ if (!DIL)
+ return R;
+
+ ContextTrieNode *CallerNode = getContextFor(DIL);
+ LineLocation CallSite = FunctionSamples::getCallSiteIdentifier(DIL);
+ for (auto &It : CallerNode->getAllChildContext()) {
+ ContextTrieNode &ChildNode = It.second;
+ if (ChildNode.getCallSiteLoc() != CallSite)
+ continue;
+ if (FunctionSamples *CalleeSamples = ChildNode.getFunctionSamples())
+ R.push_back(CalleeSamples);
+ }
+
+ return R;
+}
+
+FunctionSamples *
+SampleContextTracker::getContextSamplesFor(const DILocation *DIL) {
+ assert(DIL && "Expect non-null location");
+
+ ContextTrieNode *ContextNode = getContextFor(DIL);
+ if (!ContextNode)
+ return nullptr;
+
+ // We may have inlined callees during pre-LTO compilation, in which case
+ // we need to rely on the inline stack from !dbg to mark context profile
+ // as inlined, instead of `MarkContextSamplesInlined` during inlining.
+ // Sample profile loader walks through all instructions to get profile,
+ // which calls this function. So once that is done, all previously inlined
+ // context profile should be marked properly.
+ FunctionSamples *Samples = ContextNode->getFunctionSamples();
+ if (Samples && ContextNode->getParentContext() != &RootContext)
+ Samples->getContext().setState(InlinedContext);
+
+ return Samples;
+}
+
+FunctionSamples *
+SampleContextTracker::getContextSamplesFor(const SampleContext &Context) {
+ ContextTrieNode *Node = getContextFor(Context);
+ if (!Node)
+ return nullptr;
+
+ return Node->getFunctionSamples();
+}
+
+SampleContextTracker::ContextSamplesTy &
+SampleContextTracker::getAllContextSamplesFor(const Function &Func) {
+ StringRef CanonName = FunctionSamples::getCanonicalFnName(Func);
+ return FuncToCtxtProfileSet[CanonName];
+}
+
+SampleContextTracker::ContextSamplesTy &
+SampleContextTracker::getAllContextSamplesFor(StringRef Name) {
+ return FuncToCtxtProfileSet[Name];
+}
+
+FunctionSamples *SampleContextTracker::getBaseSamplesFor(const Function &Func,
+ bool MergeContext) {
+ StringRef CanonName = FunctionSamples::getCanonicalFnName(Func);
+ return getBaseSamplesFor(CanonName, MergeContext);
+}
+
+FunctionSamples *SampleContextTracker::getBaseSamplesFor(StringRef Name,
+ bool MergeContext) {
+ LLVM_DEBUG(dbgs() << "Getting base profile for function: " << Name << "\n");
+ // Base profile is top-level node (child of root node), so try to retrieve
+ // existing top-level node for given function first. If it exists, it could be
+ // that we've merged base profile before, or there's actually context-less
+ // profile from the input (e.g. due to unreliable stack walking).
+ ContextTrieNode *Node = getTopLevelContextNode(Name);
+ if (MergeContext) {
+ LLVM_DEBUG(dbgs() << " Merging context profile into base profile: " << Name
+ << "\n");
+
+ // We have profile for function under different contexts,
+ // create synthetic base profile and merge context profiles
+ // into base profile.
+ for (auto *CSamples : FuncToCtxtProfileSet[Name]) {
+ SampleContext &Context = CSamples->getContext();
+ ContextTrieNode *FromNode = getContextFor(Context);
+ if (FromNode == Node)
+ continue;
+
+ // Skip inlined context profile and also don't re-merge any context
+ if (Context.hasState(InlinedContext) || Context.hasState(MergedContext))
+ continue;
+
+ ContextTrieNode &ToNode = promoteMergeContextSamplesTree(*FromNode);
+ assert((!Node || Node == &ToNode) && "Expect only one base profile");
+ Node = &ToNode;
+ }
+ }
+
+ // Still no profile even after merge/promotion (if allowed)
+ if (!Node)
+ return nullptr;
+
+ return Node->getFunctionSamples();
+}
+
+void SampleContextTracker::markContextSamplesInlined(
+ const FunctionSamples *InlinedSamples) {
+ assert(InlinedSamples && "Expect non-null inlined samples");
+ LLVM_DEBUG(dbgs() << "Marking context profile as inlined: "
+ << InlinedSamples->getContext() << "\n");
+ InlinedSamples->getContext().setState(InlinedContext);
+}
+
+void SampleContextTracker::promoteMergeContextSamplesTree(
+ const Instruction &Inst, StringRef CalleeName) {
+ LLVM_DEBUG(dbgs() << "Promoting and merging context tree for instr: \n"
+ << Inst << "\n");
+ // Get the caller context for the call instruction, we don't use callee
+ // name from call because there can be context from indirect calls too.
+ DILocation *DIL = Inst.getDebugLoc();
+ ContextTrieNode *CallerNode = getContextFor(DIL);
+ if (!CallerNode)
+ return;
+
+ // Get the context that needs to be promoted
+ LineLocation CallSite = FunctionSamples::getCallSiteIdentifier(DIL);
+ // For indirect call, CalleeName will be empty, in which case we need to
+ // promote all non-inlined child context profiles.
+ if (CalleeName.empty()) {
+ for (auto &It : CallerNode->getAllChildContext()) {
+ ContextTrieNode *NodeToPromo = &It.second;
+ if (CallSite != NodeToPromo->getCallSiteLoc())
+ continue;
+ FunctionSamples *FromSamples = NodeToPromo->getFunctionSamples();
+ if (FromSamples && FromSamples->getContext().hasState(InlinedContext))
+ continue;
+ promoteMergeContextSamplesTree(*NodeToPromo);
+ }
+ return;
+ }
+
+ // Get the context for the given callee that needs to be promoted
+ ContextTrieNode *NodeToPromo =
+ CallerNode->getChildContext(CallSite, CalleeName);
+ if (!NodeToPromo)
+ return;
+
+ promoteMergeContextSamplesTree(*NodeToPromo);
+}
+
+ContextTrieNode &SampleContextTracker::promoteMergeContextSamplesTree(
+ ContextTrieNode &NodeToPromo) {
+ // Promote the input node to be directly under root. This can happen
+ // when we decided to not inline a function under context represented
+ // by the input node. The promote and merge is then needed to reflect
+ // the context profile in the base (context-less) profile.
+ FunctionSamples *FromSamples = NodeToPromo.getFunctionSamples();
+ assert(FromSamples && "Shouldn't promote a context without profile");
+ LLVM_DEBUG(dbgs() << " Found context tree root to promote: "
+ << FromSamples->getContext() << "\n");
+
+ assert(!FromSamples->getContext().hasState(InlinedContext) &&
+ "Shouldn't promote inlined context profile");
+ StringRef ContextStrToRemove = FromSamples->getContext().getCallingContext();
+ return promoteMergeContextSamplesTree(NodeToPromo, RootContext,
+ ContextStrToRemove);
+}
+
+void SampleContextTracker::dump() {
+ dbgs() << "Context Profile Tree:\n";
+ std::queue<ContextTrieNode *> NodeQueue;
+ NodeQueue.push(&RootContext);
+
+ while (!NodeQueue.empty()) {
+ ContextTrieNode *Node = NodeQueue.front();
+ NodeQueue.pop();
+ Node->dump();
+
+ for (auto &It : Node->getAllChildContext()) {
+ ContextTrieNode *ChildNode = &It.second;
+ NodeQueue.push(ChildNode);
+ }
+ }
+}
+
+ContextTrieNode *
+SampleContextTracker::getContextFor(const SampleContext &Context) {
+ return getOrCreateContextPath(Context, false);
+}
+
+ContextTrieNode *
+SampleContextTracker::getCalleeContextFor(const DILocation *DIL,
+ StringRef CalleeName) {
+ assert(DIL && "Expect non-null location");
+
+ ContextTrieNode *CallContext = getContextFor(DIL);
+ if (!CallContext)
+ return nullptr;
+
+ // When CalleeName is empty, the child context profile with max
+ // total samples will be returned.
+ return CallContext->getChildContext(
+ FunctionSamples::getCallSiteIdentifier(DIL), CalleeName);
+}
+
+ContextTrieNode *SampleContextTracker::getContextFor(const DILocation *DIL) {
+ assert(DIL && "Expect non-null location");
+ SmallVector<std::pair<LineLocation, StringRef>, 10> S;
+
+ // Use C++ linkage name if possible.
+ const DILocation *PrevDIL = DIL;
+ for (DIL = DIL->getInlinedAt(); DIL; DIL = DIL->getInlinedAt()) {
+ StringRef Name = PrevDIL->getScope()->getSubprogram()->getLinkageName();
+ if (Name.empty())
+ Name = PrevDIL->getScope()->getSubprogram()->getName();
+ S.push_back(
+ std::make_pair(FunctionSamples::getCallSiteIdentifier(DIL),
+ PrevDIL->getScope()->getSubprogram()->getLinkageName()));
+ PrevDIL = DIL;
+ }
+
+ // Push root node, note that root node like main may only
+ // a name, but not linkage name.
+ StringRef RootName = PrevDIL->getScope()->getSubprogram()->getLinkageName();
+ if (RootName.empty())
+ RootName = PrevDIL->getScope()->getSubprogram()->getName();
+ S.push_back(std::make_pair(LineLocation(0, 0), RootName));
+
+ ContextTrieNode *ContextNode = &RootContext;
+ int I = S.size();
+ while (--I >= 0 && ContextNode) {
+ LineLocation &CallSite = S[I].first;
+ StringRef &CalleeName = S[I].second;
+ ContextNode = ContextNode->getChildContext(CallSite, CalleeName);
+ }
+
+ if (I < 0)
+ return ContextNode;
+
+ return nullptr;
+}
+
+ContextTrieNode *
+SampleContextTracker::getOrCreateContextPath(const SampleContext &Context,
+ bool AllowCreate) {
+ ContextTrieNode *ContextNode = &RootContext;
+ StringRef ContextRemain = Context;
+ StringRef ChildContext;
+ StringRef CalleeName;
+ LineLocation CallSiteLoc(0, 0);
+
+ while (ContextNode && !ContextRemain.empty()) {
+ auto ContextSplit = SampleContext::splitContextString(ContextRemain);
+ ChildContext = ContextSplit.first;
+ ContextRemain = ContextSplit.second;
+ LineLocation NextCallSiteLoc(0, 0);
+ SampleContext::decodeContextString(ChildContext, CalleeName,
+ NextCallSiteLoc);
+
+ // Create child node at parent line/disc location
+ if (AllowCreate) {
+ ContextNode =
+ ContextNode->getOrCreateChildContext(CallSiteLoc, CalleeName);
+ } else {
+ ContextNode = ContextNode->getChildContext(CallSiteLoc, CalleeName);
+ }
+ CallSiteLoc = NextCallSiteLoc;
+ }
+
+ assert((!AllowCreate || ContextNode) &&
+ "Node must exist if creation is allowed");
+ return ContextNode;
+}
+
+ContextTrieNode *SampleContextTracker::getTopLevelContextNode(StringRef FName) {
+ return RootContext.getChildContext(LineLocation(0, 0), FName);
+}
+
+ContextTrieNode &SampleContextTracker::addTopLevelContextNode(StringRef FName) {
+ assert(!getTopLevelContextNode(FName) && "Node to add must not exist");
+ return *RootContext.getOrCreateChildContext(LineLocation(0, 0), FName);
+}
+
+void SampleContextTracker::mergeContextNode(ContextTrieNode &FromNode,
+ ContextTrieNode &ToNode,
+ StringRef ContextStrToRemove) {
+ FunctionSamples *FromSamples = FromNode.getFunctionSamples();
+ FunctionSamples *ToSamples = ToNode.getFunctionSamples();
+ if (FromSamples && ToSamples) {
+ // Merge/duplicate FromSamples into ToSamples
+ ToSamples->merge(*FromSamples);
+ ToSamples->getContext().setState(SyntheticContext);
+ FromSamples->getContext().setState(MergedContext);
+ } else if (FromSamples) {
+ // Transfer FromSamples from FromNode to ToNode
+ ToNode.setFunctionSamples(FromSamples);
+ FromSamples->getContext().setState(SyntheticContext);
+ FromSamples->getContext().promoteOnPath(ContextStrToRemove);
+ FromNode.setFunctionSamples(nullptr);
+ }
+}
+
+ContextTrieNode &SampleContextTracker::promoteMergeContextSamplesTree(
+ ContextTrieNode &FromNode, ContextTrieNode &ToNodeParent,
+ StringRef ContextStrToRemove) {
+ assert(!ContextStrToRemove.empty() && "Context to remove can't be empty");
+
+ // Ignore call site location if destination is top level under root
+ LineLocation NewCallSiteLoc = LineLocation(0, 0);
+ LineLocation OldCallSiteLoc = FromNode.getCallSiteLoc();
+ ContextTrieNode &FromNodeParent = *FromNode.getParentContext();
+ ContextTrieNode *ToNode = nullptr;
+ bool MoveToRoot = (&ToNodeParent == &RootContext);
+ if (!MoveToRoot) {
+ NewCallSiteLoc = OldCallSiteLoc;
+ }
+
+ // Locate destination node, create/move if not existing
+ ToNode = ToNodeParent.getChildContext(NewCallSiteLoc, FromNode.getFuncName());
+ if (!ToNode) {
+ // Do not delete node to move from its parent here because
+ // caller is iterating over children of that parent node.
+ ToNode = &ToNodeParent.moveToChildContext(
+ NewCallSiteLoc, std::move(FromNode), ContextStrToRemove, false);
+ } else {
+ // Destination node exists, merge samples for the context tree
+ mergeContextNode(FromNode, *ToNode, ContextStrToRemove);
+ LLVM_DEBUG(dbgs() << " Context promoted and merged to: "
+ << ToNode->getFunctionSamples()->getContext() << "\n");
+
+ // Recursively promote and merge children
+ for (auto &It : FromNode.getAllChildContext()) {
+ ContextTrieNode &FromChildNode = It.second;
+ promoteMergeContextSamplesTree(FromChildNode, *ToNode,
+ ContextStrToRemove);
+ }
+
+ // Remove children once they're all merged
+ FromNode.getAllChildContext().clear();
+ }
+
+ // For root of subtree, remove itself from old parent too
+ if (MoveToRoot)
+ FromNodeParent.removeChildContext(OldCallSiteLoc, ToNode->getFuncName());
+
+ return *ToNode;
+}
+
+// Replace call graph edges with dynamic call edges from the profile.
+void SampleContextTracker::addCallGraphEdges(CallGraph &CG,
+ StringMap<Function *> &SymbolMap) {
+ // Add profile call edges to the call graph.
+ std::queue<ContextTrieNode *> NodeQueue;
+ NodeQueue.push(&RootContext);
+ while (!NodeQueue.empty()) {
+ ContextTrieNode *Node = NodeQueue.front();
+ NodeQueue.pop();
+ Function *F = SymbolMap.lookup(Node->getFuncName());
+ for (auto &I : Node->getAllChildContext()) {
+ ContextTrieNode *ChildNode = &I.second;
+ NodeQueue.push(ChildNode);
+ if (F && !F->isDeclaration()) {
+ Function *Callee = SymbolMap.lookup(ChildNode->getFuncName());
+ if (Callee && !Callee->isDeclaration())
+ CG[F]->addCalledFunction(nullptr, CG[Callee]);
+ }
+ }
+ }
+}
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/SampleProfile.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/SampleProfile.cpp
index 1dbaaa2be7..a6a419bfe7 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/SampleProfile.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/SampleProfile.cpp
@@ -26,7 +26,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/None.h"
-#include "llvm/ADT/PriorityQueue.h"
+#include "llvm/ADT/PriorityQueue.h"
#include "llvm/ADT/SCCIterator.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
@@ -44,7 +44,7 @@
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
-#include "llvm/Analysis/ReplayInlineAdvisor.h"
+#include "llvm/Analysis/ReplayInlineAdvisor.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/BasicBlock.h"
@@ -77,8 +77,8 @@
#include "llvm/Support/GenericDomTree.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/IPO.h"
-#include "llvm/Transforms/IPO/SampleContextTracker.h"
-#include "llvm/Transforms/IPO/SampleProfileProbe.h"
+#include "llvm/Transforms/IPO/SampleContextTracker.h"
+#include "llvm/Transforms/IPO/SampleProfileProbe.h"
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Utils/CallPromotionUtils.h"
#include "llvm/Transforms/Utils/Cloning.h"
@@ -105,20 +105,20 @@ STATISTIC(NumCSInlined,
"Number of functions inlined with context sensitive profile");
STATISTIC(NumCSNotInlined,
"Number of functions not inlined with context sensitive profile");
-STATISTIC(NumMismatchedProfile,
- "Number of functions with CFG mismatched profile");
-STATISTIC(NumMatchedProfile, "Number of functions with CFG matched profile");
-STATISTIC(NumDuplicatedInlinesite,
- "Number of inlined callsites with a partial distribution factor");
-
-STATISTIC(NumCSInlinedHitMinLimit,
- "Number of functions with FDO inline stopped due to min size limit");
-STATISTIC(NumCSInlinedHitMaxLimit,
- "Number of functions with FDO inline stopped due to max size limit");
-STATISTIC(
- NumCSInlinedHitGrowthLimit,
- "Number of functions with FDO inline stopped due to growth size limit");
-
+STATISTIC(NumMismatchedProfile,
+ "Number of functions with CFG mismatched profile");
+STATISTIC(NumMatchedProfile, "Number of functions with CFG matched profile");
+STATISTIC(NumDuplicatedInlinesite,
+ "Number of inlined callsites with a partial distribution factor");
+
+STATISTIC(NumCSInlinedHitMinLimit,
+ "Number of functions with FDO inline stopped due to min size limit");
+STATISTIC(NumCSInlinedHitMaxLimit,
+ "Number of functions with FDO inline stopped due to max size limit");
+STATISTIC(
+ NumCSInlinedHitGrowthLimit,
+ "Number of functions with FDO inline stopped due to growth size limit");
+
// Command line option to specify the file to read samples from. This is
// mainly used for debugging.
static cl::opt<std::string> SampleProfileFile(
@@ -177,64 +177,64 @@ static cl::opt<bool> ProfileTopDownLoad(
"order of call graph during sample profile loading. It only "
"works for new pass manager. "));
-static cl::opt<bool> UseProfileIndirectCallEdges(
- "use-profile-indirect-call-edges", cl::init(true), cl::Hidden,
- cl::desc("Considering indirect call samples from profile when top-down "
- "processing functions. Only CSSPGO is supported."));
-
-static cl::opt<bool> UseProfileTopDownOrder(
- "use-profile-top-down-order", cl::init(false), cl::Hidden,
- cl::desc("Process functions in one SCC in a top-down order "
- "based on the input profile."));
-
+static cl::opt<bool> UseProfileIndirectCallEdges(
+ "use-profile-indirect-call-edges", cl::init(true), cl::Hidden,
+ cl::desc("Considering indirect call samples from profile when top-down "
+ "processing functions. Only CSSPGO is supported."));
+
+static cl::opt<bool> UseProfileTopDownOrder(
+ "use-profile-top-down-order", cl::init(false), cl::Hidden,
+ cl::desc("Process functions in one SCC in a top-down order "
+ "based on the input profile."));
+
static cl::opt<bool> ProfileSizeInline(
"sample-profile-inline-size", cl::Hidden, cl::init(false),
cl::desc("Inline cold call sites in profile loader if it's beneficial "
"for code size."));
-static cl::opt<int> ProfileInlineGrowthLimit(
- "sample-profile-inline-growth-limit", cl::Hidden, cl::init(12),
- cl::desc("The size growth ratio limit for proirity-based sample profile "
- "loader inlining."));
-
-static cl::opt<int> ProfileInlineLimitMin(
- "sample-profile-inline-limit-min", cl::Hidden, cl::init(100),
- cl::desc("The lower bound of size growth limit for "
- "proirity-based sample profile loader inlining."));
-
-static cl::opt<int> ProfileInlineLimitMax(
- "sample-profile-inline-limit-max", cl::Hidden, cl::init(10000),
- cl::desc("The upper bound of size growth limit for "
- "proirity-based sample profile loader inlining."));
-
-static cl::opt<int> ProfileICPThreshold(
- "sample-profile-icp-threshold", cl::Hidden, cl::init(5),
- cl::desc(
- "Relative hotness threshold for indirect "
- "call promotion in proirity-based sample profile loader inlining."));
-
-static cl::opt<int> SampleHotCallSiteThreshold(
- "sample-profile-hot-inline-threshold", cl::Hidden, cl::init(3000),
- cl::desc("Hot callsite threshold for proirity-based sample profile loader "
- "inlining."));
-
-static cl::opt<bool> CallsitePrioritizedInline(
- "sample-profile-prioritized-inline", cl::Hidden, cl::ZeroOrMore,
- cl::init(false),
- cl::desc("Use call site prioritized inlining for sample profile loader."
- "Currently only CSSPGO is supported."));
-
+static cl::opt<int> ProfileInlineGrowthLimit(
+ "sample-profile-inline-growth-limit", cl::Hidden, cl::init(12),
+ cl::desc("The size growth ratio limit for proirity-based sample profile "
+ "loader inlining."));
+
+static cl::opt<int> ProfileInlineLimitMin(
+ "sample-profile-inline-limit-min", cl::Hidden, cl::init(100),
+ cl::desc("The lower bound of size growth limit for "
+ "proirity-based sample profile loader inlining."));
+
+static cl::opt<int> ProfileInlineLimitMax(
+ "sample-profile-inline-limit-max", cl::Hidden, cl::init(10000),
+ cl::desc("The upper bound of size growth limit for "
+ "proirity-based sample profile loader inlining."));
+
+static cl::opt<int> ProfileICPThreshold(
+ "sample-profile-icp-threshold", cl::Hidden, cl::init(5),
+ cl::desc(
+ "Relative hotness threshold for indirect "
+ "call promotion in proirity-based sample profile loader inlining."));
+
+static cl::opt<int> SampleHotCallSiteThreshold(
+ "sample-profile-hot-inline-threshold", cl::Hidden, cl::init(3000),
+ cl::desc("Hot callsite threshold for proirity-based sample profile loader "
+ "inlining."));
+
+static cl::opt<bool> CallsitePrioritizedInline(
+ "sample-profile-prioritized-inline", cl::Hidden, cl::ZeroOrMore,
+ cl::init(false),
+ cl::desc("Use call site prioritized inlining for sample profile loader."
+ "Currently only CSSPGO is supported."));
+
static cl::opt<int> SampleColdCallSiteThreshold(
"sample-profile-cold-inline-threshold", cl::Hidden, cl::init(45),
cl::desc("Threshold for inlining cold callsites"));
-static cl::opt<std::string> ProfileInlineReplayFile(
- "sample-profile-inline-replay", cl::init(""), cl::value_desc("filename"),
- cl::desc(
- "Optimization remarks file containing inline remarks to be replayed "
- "by inlining from sample profile loader."),
- cl::Hidden);
-
+static cl::opt<std::string> ProfileInlineReplayFile(
+ "sample-profile-inline-replay", cl::init(""), cl::value_desc("filename"),
+ cl::desc(
+ "Optimization remarks file containing inline remarks to be replayed "
+ "by inlining from sample profile loader."),
+ cl::Hidden);
+
namespace {
using BlockWeightMap = DenseMap<const BasicBlock *, uint64_t>;
@@ -366,38 +366,38 @@ private:
DenseMap<uint64_t, StringRef> &CurrentGUIDToFuncNameMap;
};
-// Inline candidate used by iterative callsite prioritized inliner
-struct InlineCandidate {
- CallBase *CallInstr;
- const FunctionSamples *CalleeSamples;
- // Prorated callsite count, which will be used to guide inlining. For example,
- // if a callsite is duplicated in LTO prelink, then in LTO postlink the two
- // copies will get their own distribution factors and their prorated counts
- // will be used to decide if they should be inlined independently.
- uint64_t CallsiteCount;
- // Call site distribution factor to prorate the profile samples for a
- // duplicated callsite. Default value is 1.0.
- float CallsiteDistribution;
-};
-
-// Inline candidate comparer using call site weight
-struct CandidateComparer {
- bool operator()(const InlineCandidate &LHS, const InlineCandidate &RHS) {
- if (LHS.CallsiteCount != RHS.CallsiteCount)
- return LHS.CallsiteCount < RHS.CallsiteCount;
-
- // Tie breaker using GUID so we have stable/deterministic inlining order
- assert(LHS.CalleeSamples && RHS.CalleeSamples &&
- "Expect non-null FunctionSamples");
- return LHS.CalleeSamples->getGUID(LHS.CalleeSamples->getName()) <
- RHS.CalleeSamples->getGUID(RHS.CalleeSamples->getName());
- }
-};
-
-using CandidateQueue =
- PriorityQueue<InlineCandidate, std::vector<InlineCandidate>,
- CandidateComparer>;
-
+// Inline candidate used by iterative callsite prioritized inliner
+struct InlineCandidate {
+ CallBase *CallInstr;
+ const FunctionSamples *CalleeSamples;
+ // Prorated callsite count, which will be used to guide inlining. For example,
+ // if a callsite is duplicated in LTO prelink, then in LTO postlink the two
+ // copies will get their own distribution factors and their prorated counts
+ // will be used to decide if they should be inlined independently.
+ uint64_t CallsiteCount;
+ // Call site distribution factor to prorate the profile samples for a
+ // duplicated callsite. Default value is 1.0.
+ float CallsiteDistribution;
+};
+
+// Inline candidate comparer using call site weight
+struct CandidateComparer {
+ bool operator()(const InlineCandidate &LHS, const InlineCandidate &RHS) {
+ if (LHS.CallsiteCount != RHS.CallsiteCount)
+ return LHS.CallsiteCount < RHS.CallsiteCount;
+
+ // Tie breaker using GUID so we have stable/deterministic inlining order
+ assert(LHS.CalleeSamples && RHS.CalleeSamples &&
+ "Expect non-null FunctionSamples");
+ return LHS.CalleeSamples->getGUID(LHS.CalleeSamples->getName()) <
+ RHS.CalleeSamples->getGUID(RHS.CalleeSamples->getName());
+ }
+};
+
+using CandidateQueue =
+ PriorityQueue<InlineCandidate, std::vector<InlineCandidate>,
+ CandidateComparer>;
+
/// Sample profile pass.
///
/// This pass reads profile data from the file specified by
@@ -406,16 +406,16 @@ using CandidateQueue =
class SampleProfileLoader {
public:
SampleProfileLoader(
- StringRef Name, StringRef RemapName, ThinOrFullLTOPhase LTOPhase,
+ StringRef Name, StringRef RemapName, ThinOrFullLTOPhase LTOPhase,
std::function<AssumptionCache &(Function &)> GetAssumptionCache,
std::function<TargetTransformInfo &(Function &)> GetTargetTransformInfo,
std::function<const TargetLibraryInfo &(Function &)> GetTLI)
: GetAC(std::move(GetAssumptionCache)),
GetTTI(std::move(GetTargetTransformInfo)), GetTLI(std::move(GetTLI)),
CoverageTracker(*this), Filename(std::string(Name)),
- RemappingFilename(std::string(RemapName)), LTOPhase(LTOPhase) {}
+ RemappingFilename(std::string(RemapName)), LTOPhase(LTOPhase) {}
- bool doInitialization(Module &M, FunctionAnalysisManager *FAM = nullptr);
+ bool doInitialization(Module &M, FunctionAnalysisManager *FAM = nullptr);
bool runOnModule(Module &M, ModuleAnalysisManager *AM,
ProfileSummaryInfo *_PSI, CallGraph *CG);
@@ -428,28 +428,28 @@ protected:
unsigned getFunctionLoc(Function &F);
bool emitAnnotations(Function &F);
ErrorOr<uint64_t> getInstWeight(const Instruction &I);
- ErrorOr<uint64_t> getProbeWeight(const Instruction &I);
+ ErrorOr<uint64_t> getProbeWeight(const Instruction &I);
ErrorOr<uint64_t> getBlockWeight(const BasicBlock *BB);
const FunctionSamples *findCalleeFunctionSamples(const CallBase &I) const;
std::vector<const FunctionSamples *>
findIndirectCallFunctionSamples(const Instruction &I, uint64_t &Sum) const;
mutable DenseMap<const DILocation *, const FunctionSamples *> DILocation2SampleMap;
const FunctionSamples *findFunctionSamples(const Instruction &I) const;
- // Attempt to promote indirect call and also inline the promoted call
- bool tryPromoteAndInlineCandidate(
- Function &F, InlineCandidate &Candidate, uint64_t SumOrigin,
- uint64_t &Sum, DenseSet<Instruction *> &PromotedInsns,
- SmallVector<CallBase *, 8> *InlinedCallSites = nullptr);
+ // Attempt to promote indirect call and also inline the promoted call
+ bool tryPromoteAndInlineCandidate(
+ Function &F, InlineCandidate &Candidate, uint64_t SumOrigin,
+ uint64_t &Sum, DenseSet<Instruction *> &PromotedInsns,
+ SmallVector<CallBase *, 8> *InlinedCallSites = nullptr);
bool inlineHotFunctions(Function &F,
DenseSet<GlobalValue::GUID> &InlinedGUIDs);
- InlineCost shouldInlineCandidate(InlineCandidate &Candidate);
- bool getInlineCandidate(InlineCandidate *NewCandidate, CallBase *CB);
- bool
- tryInlineCandidate(InlineCandidate &Candidate,
- SmallVector<CallBase *, 8> *InlinedCallSites = nullptr);
- bool
- inlineHotFunctionsWithPriority(Function &F,
- DenseSet<GlobalValue::GUID> &InlinedGUIDs);
+ InlineCost shouldInlineCandidate(InlineCandidate &Candidate);
+ bool getInlineCandidate(InlineCandidate *NewCandidate, CallBase *CB);
+ bool
+ tryInlineCandidate(InlineCandidate &Candidate,
+ SmallVector<CallBase *, 8> *InlinedCallSites = nullptr);
+ bool
+ inlineHotFunctionsWithPriority(Function &F,
+ DenseSet<GlobalValue::GUID> &InlinedGUIDs);
// Inline cold/small functions in addition to hot ones
bool shouldInlineColdCallee(CallBase &CallInst);
void emitOptimizationRemarksForInlineCandidates(
@@ -468,8 +468,8 @@ protected:
uint64_t visitEdge(Edge E, unsigned *NumUnknownEdges, Edge *UnknownEdge);
void buildEdges(Function &F);
std::vector<Function *> buildFunctionOrder(Module &M, CallGraph *CG);
- void addCallGraphEdges(CallGraph &CG, const FunctionSamples &Samples);
- void replaceCallGraphEdges(CallGraph &CG, StringMap<Function *> &SymbolMap);
+ void addCallGraphEdges(CallGraph &CG, const FunctionSamples &Samples);
+ void replaceCallGraphEdges(CallGraph &CG, StringMap<Function *> &SymbolMap);
bool propagateThroughEdges(Function &F, bool UpdateBlockCount);
void computeDominanceAndLoopInfo(Function &F);
void clearFunctionData();
@@ -528,9 +528,9 @@ protected:
/// Profile reader object.
std::unique_ptr<SampleProfileReader> Reader;
- /// Profile tracker for different context.
- std::unique_ptr<SampleContextTracker> ContextTracker;
-
+ /// Profile tracker for different context.
+ std::unique_ptr<SampleContextTracker> ContextTracker;
+
/// Samples collected for the body of this function.
FunctionSamples *Samples = nullptr;
@@ -543,15 +543,15 @@ protected:
/// Flag indicating whether the profile input loaded successfully.
bool ProfileIsValid = false;
- /// Flag indicating whether input profile is context-sensitive
- bool ProfileIsCS = false;
-
- /// Flag indicating which LTO/ThinLTO phase the pass is invoked in.
+ /// Flag indicating whether input profile is context-sensitive
+ bool ProfileIsCS = false;
+
+ /// Flag indicating which LTO/ThinLTO phase the pass is invoked in.
///
- /// We need to know the LTO phase because for example in ThinLTOPrelink
- /// phase, in annotation, we should not promote indirect calls. Instead,
- /// we will mark GUIDs that needs to be annotated to the function.
- ThinOrFullLTOPhase LTOPhase;
+ /// We need to know the LTO phase because for example in ThinLTOPrelink
+ /// phase, in annotation, we should not promote indirect calls. Instead,
+ /// we will mark GUIDs that needs to be annotated to the function.
+ ThinOrFullLTOPhase LTOPhase;
/// Profile Summary Info computed from sample profile.
ProfileSummaryInfo *PSI = nullptr;
@@ -591,12 +591,12 @@ protected:
// overriden by -profile-sample-accurate or profile-sample-accurate
// attribute.
bool ProfAccForSymsInList;
-
- // External inline advisor used to replay inline decision from remarks.
- std::unique_ptr<ReplayInlineAdvisor> ExternalInlineAdvisor;
-
- // A pseudo probe helper to correlate the imported sample counts.
- std::unique_ptr<PseudoProbeManager> ProbeManager;
+
+ // External inline advisor used to replay inline decision from remarks.
+ std::unique_ptr<ReplayInlineAdvisor> ExternalInlineAdvisor;
+
+ // A pseudo probe helper to correlate the imported sample counts.
+ std::unique_ptr<PseudoProbeManager> ProbeManager;
};
class SampleProfileLoaderLegacyPass : public ModulePass {
@@ -604,11 +604,11 @@ public:
// Class identification, replacement for typeinfo
static char ID;
- SampleProfileLoaderLegacyPass(
- StringRef Name = SampleProfileFile,
- ThinOrFullLTOPhase LTOPhase = ThinOrFullLTOPhase::None)
+ SampleProfileLoaderLegacyPass(
+ StringRef Name = SampleProfileFile,
+ ThinOrFullLTOPhase LTOPhase = ThinOrFullLTOPhase::None)
: ModulePass(ID), SampleLoader(
- Name, SampleProfileRemappingFile, LTOPhase,
+ Name, SampleProfileRemappingFile, LTOPhase,
[&](Function &F) -> AssumptionCache & {
return ACT->getAssumptionCache(F);
},
@@ -830,9 +830,9 @@ void SampleProfileLoader::printBlockWeight(raw_ostream &OS,
///
/// \returns the weight of \p Inst.
ErrorOr<uint64_t> SampleProfileLoader::getInstWeight(const Instruction &Inst) {
- if (FunctionSamples::ProfileIsProbeBased)
- return getProbeWeight(Inst);
-
+ if (FunctionSamples::ProfileIsProbeBased)
+ return getProbeWeight(Inst);
+
const DebugLoc &DLoc = Inst.getDebugLoc();
if (!DLoc)
return std::error_code();
@@ -851,10 +851,10 @@ ErrorOr<uint64_t> SampleProfileLoader::getInstWeight(const Instruction &Inst) {
// (findCalleeFunctionSamples returns non-empty result), but not inlined here,
// it means that the inlined callsite has no sample, thus the call
// instruction should have 0 count.
- if (!ProfileIsCS)
- if (const auto *CB = dyn_cast<CallBase>(&Inst))
- if (!CB->isIndirectCall() && findCalleeFunctionSamples(*CB))
- return 0;
+ if (!ProfileIsCS)
+ if (const auto *CB = dyn_cast<CallBase>(&Inst))
+ if (!CB->isIndirectCall() && findCalleeFunctionSamples(*CB))
+ return 0;
const DILocation *DIL = DLoc;
uint32_t LineOffset = FunctionSamples::getOffset(DIL);
@@ -886,51 +886,51 @@ ErrorOr<uint64_t> SampleProfileLoader::getInstWeight(const Instruction &Inst) {
return R;
}
-ErrorOr<uint64_t> SampleProfileLoader::getProbeWeight(const Instruction &Inst) {
- assert(FunctionSamples::ProfileIsProbeBased &&
- "Profile is not pseudo probe based");
- Optional<PseudoProbe> Probe = extractProbe(Inst);
- if (!Probe)
- return std::error_code();
-
- const FunctionSamples *FS = findFunctionSamples(Inst);
- if (!FS)
- return std::error_code();
-
- // If a direct call/invoke instruction is inlined in profile
- // (findCalleeFunctionSamples returns non-empty result), but not inlined here,
- // it means that the inlined callsite has no sample, thus the call
- // instruction should have 0 count.
- if (const auto *CB = dyn_cast<CallBase>(&Inst))
- if (!CB->isIndirectCall() && findCalleeFunctionSamples(*CB))
- return 0;
-
- const ErrorOr<uint64_t> &R = FS->findSamplesAt(Probe->Id, 0);
- if (R) {
- uint64_t Samples = R.get() * Probe->Factor;
- bool FirstMark = CoverageTracker.markSamplesUsed(FS, Probe->Id, 0, Samples);
- if (FirstMark) {
- ORE->emit([&]() {
- OptimizationRemarkAnalysis Remark(DEBUG_TYPE, "AppliedSamples", &Inst);
- Remark << "Applied " << ore::NV("NumSamples", Samples);
- Remark << " samples from profile (ProbeId=";
- Remark << ore::NV("ProbeId", Probe->Id);
- Remark << ", Factor=";
- Remark << ore::NV("Factor", Probe->Factor);
- Remark << ", OriginalSamples=";
- Remark << ore::NV("OriginalSamples", R.get());
- Remark << ")";
- return Remark;
- });
- }
- LLVM_DEBUG(dbgs() << " " << Probe->Id << ":" << Inst
- << " - weight: " << R.get() << " - factor: "
- << format("%0.2f", Probe->Factor) << ")\n");
- return Samples;
- }
- return R;
-}
-
+ErrorOr<uint64_t> SampleProfileLoader::getProbeWeight(const Instruction &Inst) {
+ assert(FunctionSamples::ProfileIsProbeBased &&
+ "Profile is not pseudo probe based");
+ Optional<PseudoProbe> Probe = extractProbe(Inst);
+ if (!Probe)
+ return std::error_code();
+
+ const FunctionSamples *FS = findFunctionSamples(Inst);
+ if (!FS)
+ return std::error_code();
+
+ // If a direct call/invoke instruction is inlined in profile
+ // (findCalleeFunctionSamples returns non-empty result), but not inlined here,
+ // it means that the inlined callsite has no sample, thus the call
+ // instruction should have 0 count.
+ if (const auto *CB = dyn_cast<CallBase>(&Inst))
+ if (!CB->isIndirectCall() && findCalleeFunctionSamples(*CB))
+ return 0;
+
+ const ErrorOr<uint64_t> &R = FS->findSamplesAt(Probe->Id, 0);
+ if (R) {
+ uint64_t Samples = R.get() * Probe->Factor;
+ bool FirstMark = CoverageTracker.markSamplesUsed(FS, Probe->Id, 0, Samples);
+ if (FirstMark) {
+ ORE->emit([&]() {
+ OptimizationRemarkAnalysis Remark(DEBUG_TYPE, "AppliedSamples", &Inst);
+ Remark << "Applied " << ore::NV("NumSamples", Samples);
+ Remark << " samples from profile (ProbeId=";
+ Remark << ore::NV("ProbeId", Probe->Id);
+ Remark << ", Factor=";
+ Remark << ore::NV("Factor", Probe->Factor);
+ Remark << ", OriginalSamples=";
+ Remark << ore::NV("OriginalSamples", R.get());
+ Remark << ")";
+ return Remark;
+ });
+ }
+ LLVM_DEBUG(dbgs() << " " << Probe->Id << ":" << Inst
+ << " - weight: " << R.get() << " - factor: "
+ << format("%0.2f", Probe->Factor) << ")\n");
+ return Samples;
+ }
+ return R;
+}
+
/// Compute the weight of a basic block.
///
/// The weight of basic block \p BB is the maximum weight of all the
@@ -994,18 +994,18 @@ SampleProfileLoader::findCalleeFunctionSamples(const CallBase &Inst) const {
}
StringRef CalleeName;
- if (Function *Callee = Inst.getCalledFunction())
- CalleeName = FunctionSamples::getCanonicalFnName(*Callee);
+ if (Function *Callee = Inst.getCalledFunction())
+ CalleeName = FunctionSamples::getCanonicalFnName(*Callee);
+
+ if (ProfileIsCS)
+ return ContextTracker->getCalleeContextSamplesFor(Inst, CalleeName);
- if (ProfileIsCS)
- return ContextTracker->getCalleeContextSamplesFor(Inst, CalleeName);
-
const FunctionSamples *FS = findFunctionSamples(Inst);
if (FS == nullptr)
return nullptr;
- return FS->findFunctionSamplesAt(FunctionSamples::getCallSiteIdentifier(DIL),
- CalleeName, Reader->getRemapper());
+ return FS->findFunctionSamplesAt(FunctionSamples::getCallSiteIdentifier(DIL),
+ CalleeName, Reader->getRemapper());
}
/// Returns a vector of FunctionSamples that are the indirect call targets
@@ -1021,49 +1021,49 @@ SampleProfileLoader::findIndirectCallFunctionSamples(
return R;
}
- auto FSCompare = [](const FunctionSamples *L, const FunctionSamples *R) {
- assert(L && R && "Expect non-null FunctionSamples");
- if (L->getEntrySamples() != R->getEntrySamples())
- return L->getEntrySamples() > R->getEntrySamples();
- return FunctionSamples::getGUID(L->getName()) <
- FunctionSamples::getGUID(R->getName());
- };
-
- if (ProfileIsCS) {
- auto CalleeSamples =
- ContextTracker->getIndirectCalleeContextSamplesFor(DIL);
- if (CalleeSamples.empty())
- return R;
-
- // For CSSPGO, we only use target context profile's entry count
- // as that already includes both inlined callee and non-inlined ones..
- Sum = 0;
- for (const auto *const FS : CalleeSamples) {
- Sum += FS->getEntrySamples();
- R.push_back(FS);
- }
- llvm::sort(R, FSCompare);
- return R;
- }
-
+ auto FSCompare = [](const FunctionSamples *L, const FunctionSamples *R) {
+ assert(L && R && "Expect non-null FunctionSamples");
+ if (L->getEntrySamples() != R->getEntrySamples())
+ return L->getEntrySamples() > R->getEntrySamples();
+ return FunctionSamples::getGUID(L->getName()) <
+ FunctionSamples::getGUID(R->getName());
+ };
+
+ if (ProfileIsCS) {
+ auto CalleeSamples =
+ ContextTracker->getIndirectCalleeContextSamplesFor(DIL);
+ if (CalleeSamples.empty())
+ return R;
+
+ // For CSSPGO, we only use target context profile's entry count
+ // as that already includes both inlined callee and non-inlined ones..
+ Sum = 0;
+ for (const auto *const FS : CalleeSamples) {
+ Sum += FS->getEntrySamples();
+ R.push_back(FS);
+ }
+ llvm::sort(R, FSCompare);
+ return R;
+ }
+
const FunctionSamples *FS = findFunctionSamples(Inst);
if (FS == nullptr)
return R;
- auto CallSite = FunctionSamples::getCallSiteIdentifier(DIL);
- auto T = FS->findCallTargetMapAt(CallSite);
+ auto CallSite = FunctionSamples::getCallSiteIdentifier(DIL);
+ auto T = FS->findCallTargetMapAt(CallSite);
Sum = 0;
if (T)
for (const auto &T_C : T.get())
Sum += T_C.second;
- if (const FunctionSamplesMap *M = FS->findFunctionSamplesMapAt(CallSite)) {
+ if (const FunctionSamplesMap *M = FS->findFunctionSamplesMapAt(CallSite)) {
if (M->empty())
return R;
for (const auto &NameFS : *M) {
Sum += NameFS.second.getEntrySamples();
R.push_back(&NameFS.second);
}
- llvm::sort(R, FSCompare);
+ llvm::sort(R, FSCompare);
}
return R;
}
@@ -1079,85 +1079,85 @@ SampleProfileLoader::findIndirectCallFunctionSamples(
/// \returns the FunctionSamples pointer to the inlined instance.
const FunctionSamples *
SampleProfileLoader::findFunctionSamples(const Instruction &Inst) const {
- if (FunctionSamples::ProfileIsProbeBased) {
- Optional<PseudoProbe> Probe = extractProbe(Inst);
- if (!Probe)
- return nullptr;
- }
-
+ if (FunctionSamples::ProfileIsProbeBased) {
+ Optional<PseudoProbe> Probe = extractProbe(Inst);
+ if (!Probe)
+ return nullptr;
+ }
+
const DILocation *DIL = Inst.getDebugLoc();
if (!DIL)
return Samples;
auto it = DILocation2SampleMap.try_emplace(DIL,nullptr);
- if (it.second) {
- if (ProfileIsCS)
- it.first->second = ContextTracker->getContextSamplesFor(DIL);
- else
- it.first->second =
- Samples->findFunctionSamples(DIL, Reader->getRemapper());
- }
+ if (it.second) {
+ if (ProfileIsCS)
+ it.first->second = ContextTracker->getContextSamplesFor(DIL);
+ else
+ it.first->second =
+ Samples->findFunctionSamples(DIL, Reader->getRemapper());
+ }
return it.first->second;
}
-/// Attempt to promote indirect call and also inline the promoted call.
-///
-/// \param F Caller function.
-/// \param Candidate ICP and inline candidate.
-/// \param Sum Sum of target counts for indirect call.
-/// \param PromotedInsns Map to keep track of indirect call already processed.
-/// \param Candidate ICP and inline candidate.
-/// \param InlinedCallSite Output vector for new call sites exposed after
-/// inlining.
-bool SampleProfileLoader::tryPromoteAndInlineCandidate(
- Function &F, InlineCandidate &Candidate, uint64_t SumOrigin, uint64_t &Sum,
- DenseSet<Instruction *> &PromotedInsns,
- SmallVector<CallBase *, 8> *InlinedCallSite) {
- const char *Reason = "Callee function not available";
- // R->getValue() != &F is to prevent promoting a recursive call.
- // If it is a recursive call, we do not inline it as it could bloat
- // the code exponentially. There is way to better handle this, e.g.
- // clone the caller first, and inline the cloned caller if it is
- // recursive. As llvm does not inline recursive calls, we will
- // simply ignore it instead of handling it explicitly.
- auto R = SymbolMap.find(Candidate.CalleeSamples->getFuncName());
- if (R != SymbolMap.end() && R->getValue() &&
- !R->getValue()->isDeclaration() && R->getValue()->getSubprogram() &&
- R->getValue()->hasFnAttribute("use-sample-profile") &&
- R->getValue() != &F &&
- isLegalToPromote(*Candidate.CallInstr, R->getValue(), &Reason)) {
- auto *DI =
- &pgo::promoteIndirectCall(*Candidate.CallInstr, R->getValue(),
- Candidate.CallsiteCount, Sum, false, ORE);
- if (DI) {
- Sum -= Candidate.CallsiteCount;
- // Prorate the indirect callsite distribution.
- // Do not update the promoted direct callsite distribution at this
- // point since the original distribution combined with the callee
- // profile will be used to prorate callsites from the callee if
- // inlined. Once not inlined, the direct callsite distribution should
- // be prorated so that the it will reflect the real callsite counts.
- setProbeDistributionFactor(*Candidate.CallInstr,
- Candidate.CallsiteDistribution * Sum /
- SumOrigin);
- PromotedInsns.insert(Candidate.CallInstr);
- Candidate.CallInstr = DI;
- if (isa<CallInst>(DI) || isa<InvokeInst>(DI)) {
- bool Inlined = tryInlineCandidate(Candidate, InlinedCallSite);
- if (!Inlined) {
- // Prorate the direct callsite distribution so that it reflects real
- // callsite counts.
- setProbeDistributionFactor(*DI, Candidate.CallsiteDistribution *
- Candidate.CallsiteCount /
- SumOrigin);
- }
- return Inlined;
- }
- }
- } else {
- LLVM_DEBUG(dbgs() << "\nFailed to promote indirect call to "
- << Candidate.CalleeSamples->getFuncName() << " because "
- << Reason << "\n");
+/// Attempt to promote indirect call and also inline the promoted call.
+///
+/// \param F Caller function.
+/// \param Candidate ICP and inline candidate.
+/// \param Sum Sum of target counts for indirect call.
+/// \param PromotedInsns Map to keep track of indirect call already processed.
+/// \param Candidate ICP and inline candidate.
+/// \param InlinedCallSite Output vector for new call sites exposed after
+/// inlining.
+bool SampleProfileLoader::tryPromoteAndInlineCandidate(
+ Function &F, InlineCandidate &Candidate, uint64_t SumOrigin, uint64_t &Sum,
+ DenseSet<Instruction *> &PromotedInsns,
+ SmallVector<CallBase *, 8> *InlinedCallSite) {
+ const char *Reason = "Callee function not available";
+ // R->getValue() != &F is to prevent promoting a recursive call.
+ // If it is a recursive call, we do not inline it as it could bloat
+ // the code exponentially. There is way to better handle this, e.g.
+ // clone the caller first, and inline the cloned caller if it is
+ // recursive. As llvm does not inline recursive calls, we will
+ // simply ignore it instead of handling it explicitly.
+ auto R = SymbolMap.find(Candidate.CalleeSamples->getFuncName());
+ if (R != SymbolMap.end() && R->getValue() &&
+ !R->getValue()->isDeclaration() && R->getValue()->getSubprogram() &&
+ R->getValue()->hasFnAttribute("use-sample-profile") &&
+ R->getValue() != &F &&
+ isLegalToPromote(*Candidate.CallInstr, R->getValue(), &Reason)) {
+ auto *DI =
+ &pgo::promoteIndirectCall(*Candidate.CallInstr, R->getValue(),
+ Candidate.CallsiteCount, Sum, false, ORE);
+ if (DI) {
+ Sum -= Candidate.CallsiteCount;
+ // Prorate the indirect callsite distribution.
+ // Do not update the promoted direct callsite distribution at this
+ // point since the original distribution combined with the callee
+ // profile will be used to prorate callsites from the callee if
+ // inlined. Once not inlined, the direct callsite distribution should
+ // be prorated so that the it will reflect the real callsite counts.
+ setProbeDistributionFactor(*Candidate.CallInstr,
+ Candidate.CallsiteDistribution * Sum /
+ SumOrigin);
+ PromotedInsns.insert(Candidate.CallInstr);
+ Candidate.CallInstr = DI;
+ if (isa<CallInst>(DI) || isa<InvokeInst>(DI)) {
+ bool Inlined = tryInlineCandidate(Candidate, InlinedCallSite);
+ if (!Inlined) {
+ // Prorate the direct callsite distribution so that it reflects real
+ // callsite counts.
+ setProbeDistributionFactor(*DI, Candidate.CallsiteDistribution *
+ Candidate.CallsiteCount /
+ SumOrigin);
+ }
+ return Inlined;
+ }
+ }
+ } else {
+ LLVM_DEBUG(dbgs() << "\nFailed to promote indirect call to "
+ << Candidate.CalleeSamples->getFuncName() << " because "
+ << Reason << "\n");
}
return false;
}
@@ -1173,12 +1173,12 @@ bool SampleProfileLoader::shouldInlineColdCallee(CallBase &CallInst) {
InlineCost Cost = getInlineCost(CallInst, getInlineParams(), GetTTI(*Callee),
GetAC, GetTLI);
- if (Cost.isNever())
- return false;
-
- if (Cost.isAlways())
- return true;
-
+ if (Cost.isNever())
+ return false;
+
+ if (Cost.isAlways())
+ return true;
+
return Cost.getCost() <= SampleColdCallSiteThreshold;
}
@@ -1223,11 +1223,11 @@ bool SampleProfileLoader::inlineHotFunctions(
"ProfAccForSymsInList should be false when profile-sample-accurate "
"is enabled");
- DenseMap<CallBase *, const FunctionSamples *> LocalNotInlinedCallSites;
+ DenseMap<CallBase *, const FunctionSamples *> LocalNotInlinedCallSites;
bool Changed = false;
- bool LocalChanged = true;
- while (LocalChanged) {
- LocalChanged = false;
+ bool LocalChanged = true;
+ while (LocalChanged) {
+ LocalChanged = false;
SmallVector<CallBase *, 10> CIS;
for (auto &BB : F) {
bool Hot = false;
@@ -1237,11 +1237,11 @@ bool SampleProfileLoader::inlineHotFunctions(
const FunctionSamples *FS = nullptr;
if (auto *CB = dyn_cast<CallBase>(&I)) {
if (!isa<IntrinsicInst>(I) && (FS = findCalleeFunctionSamples(*CB))) {
- assert((!FunctionSamples::UseMD5 || FS->GUIDToFuncNameMap) &&
- "GUIDToFuncNameMap has to be populated");
+ assert((!FunctionSamples::UseMD5 || FS->GUIDToFuncNameMap) &&
+ "GUIDToFuncNameMap has to be populated");
AllCandidates.push_back(CB);
- if (FS->getEntrySamples() > 0 || ProfileIsCS)
- LocalNotInlinedCallSites.try_emplace(CB, FS);
+ if (FS->getEntrySamples() > 0 || ProfileIsCS)
+ LocalNotInlinedCallSites.try_emplace(CB, FS);
if (callsiteIsHot(FS, PSI))
Hot = true;
else if (shouldInlineColdCallee(*CB))
@@ -1249,7 +1249,7 @@ bool SampleProfileLoader::inlineHotFunctions(
}
}
}
- if (Hot || ExternalInlineAdvisor) {
+ if (Hot || ExternalInlineAdvisor) {
CIS.insert(CIS.begin(), AllCandidates.begin(), AllCandidates.end());
emitOptimizationRemarksForInlineCandidates(AllCandidates, F, true);
} else {
@@ -1259,11 +1259,11 @@ bool SampleProfileLoader::inlineHotFunctions(
}
for (CallBase *I : CIS) {
Function *CalledFunction = I->getCalledFunction();
- InlineCandidate Candidate = {
- I,
- LocalNotInlinedCallSites.count(I) ? LocalNotInlinedCallSites[I]
- : nullptr,
- 0 /* dummy count */, 1.0 /* dummy distribution factor */};
+ InlineCandidate Candidate = {
+ I,
+ LocalNotInlinedCallSites.count(I) ? LocalNotInlinedCallSites[I]
+ : nullptr,
+ 0 /* dummy count */, 1.0 /* dummy distribution factor */};
// Do not inline recursive calls.
if (CalledFunction == &F)
continue;
@@ -1272,8 +1272,8 @@ bool SampleProfileLoader::inlineHotFunctions(
continue;
uint64_t Sum;
for (const auto *FS : findIndirectCallFunctionSamples(*I, Sum)) {
- uint64_t SumOrigin = Sum;
- if (LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink) {
+ uint64_t SumOrigin = Sum;
+ if (LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink) {
FS->findInlinedFunctions(InlinedGUIDs, F.getParent(),
PSI->getOrCompHotCountThreshold());
continue;
@@ -1281,34 +1281,34 @@ bool SampleProfileLoader::inlineHotFunctions(
if (!callsiteIsHot(FS, PSI))
continue;
- Candidate = {I, FS, FS->getEntrySamples(), 1.0};
- if (tryPromoteAndInlineCandidate(F, Candidate, SumOrigin, Sum,
- PromotedInsns)) {
- LocalNotInlinedCallSites.erase(I);
- LocalChanged = true;
+ Candidate = {I, FS, FS->getEntrySamples(), 1.0};
+ if (tryPromoteAndInlineCandidate(F, Candidate, SumOrigin, Sum,
+ PromotedInsns)) {
+ LocalNotInlinedCallSites.erase(I);
+ LocalChanged = true;
}
}
} else if (CalledFunction && CalledFunction->getSubprogram() &&
!CalledFunction->isDeclaration()) {
- if (tryInlineCandidate(Candidate)) {
- LocalNotInlinedCallSites.erase(I);
+ if (tryInlineCandidate(Candidate)) {
+ LocalNotInlinedCallSites.erase(I);
LocalChanged = true;
}
- } else if (LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink) {
+ } else if (LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink) {
findCalleeFunctionSamples(*I)->findInlinedFunctions(
InlinedGUIDs, F.getParent(), PSI->getOrCompHotCountThreshold());
}
}
- Changed |= LocalChanged;
+ Changed |= LocalChanged;
}
- // For CS profile, profile for not inlined context will be merged when
- // base profile is being trieved
- if (ProfileIsCS)
- return Changed;
-
+ // For CS profile, profile for not inlined context will be merged when
+ // base profile is being trieved
+ if (ProfileIsCS)
+ return Changed;
+
// Accumulate not inlined callsite information into notInlinedSamples
- for (const auto &Pair : LocalNotInlinedCallSites) {
+ for (const auto &Pair : LocalNotInlinedCallSites) {
CallBase *I = Pair.getFirst();
Function *Callee = I->getCalledFunction();
if (!Callee || Callee->isDeclaration())
@@ -1327,23 +1327,23 @@ bool SampleProfileLoader::inlineHotFunctions(
}
if (ProfileMergeInlinee) {
- // A function call can be replicated by optimizations like callsite
- // splitting or jump threading and the replicates end up sharing the
- // sample nested callee profile instead of slicing the original inlinee's
- // profile. We want to do merge exactly once by filtering out callee
- // profiles with a non-zero head sample count.
- if (FS->getHeadSamples() == 0) {
- // Use entry samples as head samples during the merge, as inlinees
- // don't have head samples.
- const_cast<FunctionSamples *>(FS)->addHeadSamples(
- FS->getEntrySamples());
-
- // Note that we have to do the merge right after processing function.
- // This allows OutlineFS's profile to be used for annotation during
- // top-down processing of functions' annotation.
- FunctionSamples *OutlineFS = Reader->getOrCreateSamplesFor(*Callee);
- OutlineFS->merge(*FS);
- }
+ // A function call can be replicated by optimizations like callsite
+ // splitting or jump threading and the replicates end up sharing the
+ // sample nested callee profile instead of slicing the original inlinee's
+ // profile. We want to do merge exactly once by filtering out callee
+ // profiles with a non-zero head sample count.
+ if (FS->getHeadSamples() == 0) {
+ // Use entry samples as head samples during the merge, as inlinees
+ // don't have head samples.
+ const_cast<FunctionSamples *>(FS)->addHeadSamples(
+ FS->getEntrySamples());
+
+ // Note that we have to do the merge right after processing function.
+ // This allows OutlineFS's profile to be used for annotation during
+ // top-down processing of functions' annotation.
+ FunctionSamples *OutlineFS = Reader->getOrCreateSamplesFor(*Callee);
+ OutlineFS->merge(*FS);
+ }
} else {
auto pair =
notInlinedCallInfo.try_emplace(Callee, NotInlinedProfileInfo{0});
@@ -1353,266 +1353,266 @@ bool SampleProfileLoader::inlineHotFunctions(
return Changed;
}
-bool SampleProfileLoader::tryInlineCandidate(
- InlineCandidate &Candidate, SmallVector<CallBase *, 8> *InlinedCallSites) {
-
- CallBase &CB = *Candidate.CallInstr;
- Function *CalledFunction = CB.getCalledFunction();
- assert(CalledFunction && "Expect a callee with definition");
- DebugLoc DLoc = CB.getDebugLoc();
- BasicBlock *BB = CB.getParent();
-
- InlineCost Cost = shouldInlineCandidate(Candidate);
- if (Cost.isNever()) {
- ORE->emit(OptimizationRemarkAnalysis(CSINLINE_DEBUG, "InlineFail", DLoc, BB)
- << "incompatible inlining");
- return false;
- }
-
- if (!Cost)
- return false;
-
- InlineFunctionInfo IFI(nullptr, GetAC);
- if (InlineFunction(CB, IFI).isSuccess()) {
- // The call to InlineFunction erases I, so we can't pass it here.
- emitInlinedInto(*ORE, DLoc, BB, *CalledFunction, *BB->getParent(), Cost,
- true, CSINLINE_DEBUG);
-
- // Now populate the list of newly exposed call sites.
- if (InlinedCallSites) {
- InlinedCallSites->clear();
- for (auto &I : IFI.InlinedCallSites)
- InlinedCallSites->push_back(I);
- }
-
- if (ProfileIsCS)
- ContextTracker->markContextSamplesInlined(Candidate.CalleeSamples);
- ++NumCSInlined;
-
- // Prorate inlined probes for a duplicated inlining callsite which probably
- // has a distribution less than 100%. Samples for an inlinee should be
- // distributed among the copies of the original callsite based on each
- // callsite's distribution factor for counts accuracy. Note that an inlined
- // probe may come with its own distribution factor if it has been duplicated
- // in the inlinee body. The two factor are multiplied to reflect the
- // aggregation of duplication.
- if (Candidate.CallsiteDistribution < 1) {
- for (auto &I : IFI.InlinedCallSites) {
- if (Optional<PseudoProbe> Probe = extractProbe(*I))
- setProbeDistributionFactor(*I, Probe->Factor *
- Candidate.CallsiteDistribution);
- }
- NumDuplicatedInlinesite++;
- }
-
- return true;
- }
- return false;
-}
-
-bool SampleProfileLoader::getInlineCandidate(InlineCandidate *NewCandidate,
- CallBase *CB) {
- assert(CB && "Expect non-null call instruction");
-
- if (isa<IntrinsicInst>(CB))
- return false;
-
- // Find the callee's profile. For indirect call, find hottest target profile.
- const FunctionSamples *CalleeSamples = findCalleeFunctionSamples(*CB);
- if (!CalleeSamples)
- return false;
-
- float Factor = 1.0;
- if (Optional<PseudoProbe> Probe = extractProbe(*CB))
- Factor = Probe->Factor;
-
- uint64_t CallsiteCount = 0;
- ErrorOr<uint64_t> Weight = getBlockWeight(CB->getParent());
- if (Weight)
- CallsiteCount = Weight.get();
- if (CalleeSamples)
- CallsiteCount = std::max(
- CallsiteCount, uint64_t(CalleeSamples->getEntrySamples() * Factor));
-
- *NewCandidate = {CB, CalleeSamples, CallsiteCount, Factor};
- return true;
-}
-
-InlineCost
-SampleProfileLoader::shouldInlineCandidate(InlineCandidate &Candidate) {
- std::unique_ptr<InlineAdvice> Advice = nullptr;
- if (ExternalInlineAdvisor) {
- Advice = ExternalInlineAdvisor->getAdvice(*Candidate.CallInstr);
- if (!Advice->isInliningRecommended()) {
- Advice->recordUnattemptedInlining();
- return InlineCost::getNever("not previously inlined");
- }
- Advice->recordInlining();
- return InlineCost::getAlways("previously inlined");
- }
-
- // Adjust threshold based on call site hotness, only do this for callsite
- // prioritized inliner because otherwise cost-benefit check is done earlier.
- int SampleThreshold = SampleColdCallSiteThreshold;
- if (CallsitePrioritizedInline) {
- if (Candidate.CallsiteCount > PSI->getHotCountThreshold())
- SampleThreshold = SampleHotCallSiteThreshold;
- else if (!ProfileSizeInline)
- return InlineCost::getNever("cold callsite");
- }
-
- Function *Callee = Candidate.CallInstr->getCalledFunction();
- assert(Callee && "Expect a definition for inline candidate of direct call");
-
- InlineParams Params = getInlineParams();
- Params.ComputeFullInlineCost = true;
- // Checks if there is anything in the reachable portion of the callee at
- // this callsite that makes this inlining potentially illegal. Need to
- // set ComputeFullInlineCost, otherwise getInlineCost may return early
- // when cost exceeds threshold without checking all IRs in the callee.
- // The acutal cost does not matter because we only checks isNever() to
- // see if it is legal to inline the callsite.
- InlineCost Cost = getInlineCost(*Candidate.CallInstr, Callee, Params,
- GetTTI(*Callee), GetAC, GetTLI);
-
- // Honor always inline and never inline from call analyzer
- if (Cost.isNever() || Cost.isAlways())
- return Cost;
-
- // For old FDO inliner, we inline the call site as long as cost is not
- // "Never". The cost-benefit check is done earlier.
- if (!CallsitePrioritizedInline) {
- return InlineCost::get(Cost.getCost(), INT_MAX);
- }
-
- // Otherwise only use the cost from call analyzer, but overwite threshold with
- // Sample PGO threshold.
- return InlineCost::get(Cost.getCost(), SampleThreshold);
-}
-
-bool SampleProfileLoader::inlineHotFunctionsWithPriority(
- Function &F, DenseSet<GlobalValue::GUID> &InlinedGUIDs) {
- DenseSet<Instruction *> PromotedInsns;
- assert(ProfileIsCS && "Prioritiy based inliner only works with CSSPGO now");
-
- // ProfAccForSymsInList is used in callsiteIsHot. The assertion makes sure
- // Profile symbol list is ignored when profile-sample-accurate is on.
- assert((!ProfAccForSymsInList ||
- (!ProfileSampleAccurate &&
- !F.hasFnAttribute("profile-sample-accurate"))) &&
- "ProfAccForSymsInList should be false when profile-sample-accurate "
- "is enabled");
-
- // Populating worklist with initial call sites from root inliner, along
- // with call site weights.
- CandidateQueue CQueue;
- InlineCandidate NewCandidate;
- for (auto &BB : F) {
- for (auto &I : BB.getInstList()) {
- auto *CB = dyn_cast<CallBase>(&I);
- if (!CB)
- continue;
- if (getInlineCandidate(&NewCandidate, CB))
- CQueue.push(NewCandidate);
- }
- }
-
- // Cap the size growth from profile guided inlining. This is needed even
- // though cost of each inline candidate already accounts for callee size,
- // because with top-down inlining, we can grow inliner size significantly
- // with large number of smaller inlinees each pass the cost check.
- assert(ProfileInlineLimitMax >= ProfileInlineLimitMin &&
- "Max inline size limit should not be smaller than min inline size "
- "limit.");
- unsigned SizeLimit = F.getInstructionCount() * ProfileInlineGrowthLimit;
- SizeLimit = std::min(SizeLimit, (unsigned)ProfileInlineLimitMax);
- SizeLimit = std::max(SizeLimit, (unsigned)ProfileInlineLimitMin);
- if (ExternalInlineAdvisor)
- SizeLimit = std::numeric_limits<unsigned>::max();
-
- // Perform iterative BFS call site prioritized inlining
- bool Changed = false;
- while (!CQueue.empty() && F.getInstructionCount() < SizeLimit) {
- InlineCandidate Candidate = CQueue.top();
- CQueue.pop();
- CallBase *I = Candidate.CallInstr;
- Function *CalledFunction = I->getCalledFunction();
-
- if (CalledFunction == &F)
- continue;
- if (I->isIndirectCall()) {
- if (PromotedInsns.count(I))
- continue;
- uint64_t Sum;
- auto CalleeSamples = findIndirectCallFunctionSamples(*I, Sum);
- uint64_t SumOrigin = Sum;
- Sum *= Candidate.CallsiteDistribution;
- for (const auto *FS : CalleeSamples) {
- // TODO: Consider disable pre-lTO ICP for MonoLTO as well
- if (LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink) {
- FS->findInlinedFunctions(InlinedGUIDs, F.getParent(),
- PSI->getOrCompHotCountThreshold());
- continue;
- }
- uint64_t EntryCountDistributed =
- FS->getEntrySamples() * Candidate.CallsiteDistribution;
- // In addition to regular inline cost check, we also need to make sure
- // ICP isn't introducing excessive speculative checks even if individual
- // target looks beneficial to promote and inline. That means we should
- // only do ICP when there's a small number dominant targets.
- if (EntryCountDistributed < SumOrigin / ProfileICPThreshold)
- break;
- // TODO: Fix CallAnalyzer to handle all indirect calls.
- // For indirect call, we don't run CallAnalyzer to get InlineCost
- // before actual inlining. This is because we could see two different
- // types from the same definition, which makes CallAnalyzer choke as
- // it's expecting matching parameter type on both caller and callee
- // side. See example from PR18962 for the triggering cases (the bug was
- // fixed, but we generate different types).
- if (!PSI->isHotCount(EntryCountDistributed))
- break;
- SmallVector<CallBase *, 8> InlinedCallSites;
- // Attach function profile for promoted indirect callee, and update
- // call site count for the promoted inline candidate too.
- Candidate = {I, FS, EntryCountDistributed,
- Candidate.CallsiteDistribution};
- if (tryPromoteAndInlineCandidate(F, Candidate, SumOrigin, Sum,
- PromotedInsns, &InlinedCallSites)) {
- for (auto *CB : InlinedCallSites) {
- if (getInlineCandidate(&NewCandidate, CB))
- CQueue.emplace(NewCandidate);
- }
- Changed = true;
- }
- }
- } else if (CalledFunction && CalledFunction->getSubprogram() &&
- !CalledFunction->isDeclaration()) {
- SmallVector<CallBase *, 8> InlinedCallSites;
- if (tryInlineCandidate(Candidate, &InlinedCallSites)) {
- for (auto *CB : InlinedCallSites) {
- if (getInlineCandidate(&NewCandidate, CB))
- CQueue.emplace(NewCandidate);
- }
- Changed = true;
- }
- } else if (LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink) {
- findCalleeFunctionSamples(*I)->findInlinedFunctions(
- InlinedGUIDs, F.getParent(), PSI->getOrCompHotCountThreshold());
- }
- }
-
- if (!CQueue.empty()) {
- if (SizeLimit == (unsigned)ProfileInlineLimitMax)
- ++NumCSInlinedHitMaxLimit;
- else if (SizeLimit == (unsigned)ProfileInlineLimitMin)
- ++NumCSInlinedHitMinLimit;
- else
- ++NumCSInlinedHitGrowthLimit;
- }
-
- return Changed;
-}
-
+bool SampleProfileLoader::tryInlineCandidate(
+ InlineCandidate &Candidate, SmallVector<CallBase *, 8> *InlinedCallSites) {
+
+ CallBase &CB = *Candidate.CallInstr;
+ Function *CalledFunction = CB.getCalledFunction();
+ assert(CalledFunction && "Expect a callee with definition");
+ DebugLoc DLoc = CB.getDebugLoc();
+ BasicBlock *BB = CB.getParent();
+
+ InlineCost Cost = shouldInlineCandidate(Candidate);
+ if (Cost.isNever()) {
+ ORE->emit(OptimizationRemarkAnalysis(CSINLINE_DEBUG, "InlineFail", DLoc, BB)
+ << "incompatible inlining");
+ return false;
+ }
+
+ if (!Cost)
+ return false;
+
+ InlineFunctionInfo IFI(nullptr, GetAC);
+ if (InlineFunction(CB, IFI).isSuccess()) {
+ // The call to InlineFunction erases I, so we can't pass it here.
+ emitInlinedInto(*ORE, DLoc, BB, *CalledFunction, *BB->getParent(), Cost,
+ true, CSINLINE_DEBUG);
+
+ // Now populate the list of newly exposed call sites.
+ if (InlinedCallSites) {
+ InlinedCallSites->clear();
+ for (auto &I : IFI.InlinedCallSites)
+ InlinedCallSites->push_back(I);
+ }
+
+ if (ProfileIsCS)
+ ContextTracker->markContextSamplesInlined(Candidate.CalleeSamples);
+ ++NumCSInlined;
+
+ // Prorate inlined probes for a duplicated inlining callsite which probably
+ // has a distribution less than 100%. Samples for an inlinee should be
+ // distributed among the copies of the original callsite based on each
+ // callsite's distribution factor for counts accuracy. Note that an inlined
+ // probe may come with its own distribution factor if it has been duplicated
+ // in the inlinee body. The two factor are multiplied to reflect the
+ // aggregation of duplication.
+ if (Candidate.CallsiteDistribution < 1) {
+ for (auto &I : IFI.InlinedCallSites) {
+ if (Optional<PseudoProbe> Probe = extractProbe(*I))
+ setProbeDistributionFactor(*I, Probe->Factor *
+ Candidate.CallsiteDistribution);
+ }
+ NumDuplicatedInlinesite++;
+ }
+
+ return true;
+ }
+ return false;
+}
+
+bool SampleProfileLoader::getInlineCandidate(InlineCandidate *NewCandidate,
+ CallBase *CB) {
+ assert(CB && "Expect non-null call instruction");
+
+ if (isa<IntrinsicInst>(CB))
+ return false;
+
+ // Find the callee's profile. For indirect call, find hottest target profile.
+ const FunctionSamples *CalleeSamples = findCalleeFunctionSamples(*CB);
+ if (!CalleeSamples)
+ return false;
+
+ float Factor = 1.0;
+ if (Optional<PseudoProbe> Probe = extractProbe(*CB))
+ Factor = Probe->Factor;
+
+ uint64_t CallsiteCount = 0;
+ ErrorOr<uint64_t> Weight = getBlockWeight(CB->getParent());
+ if (Weight)
+ CallsiteCount = Weight.get();
+ if (CalleeSamples)
+ CallsiteCount = std::max(
+ CallsiteCount, uint64_t(CalleeSamples->getEntrySamples() * Factor));
+
+ *NewCandidate = {CB, CalleeSamples, CallsiteCount, Factor};
+ return true;
+}
+
+InlineCost
+SampleProfileLoader::shouldInlineCandidate(InlineCandidate &Candidate) {
+ std::unique_ptr<InlineAdvice> Advice = nullptr;
+ if (ExternalInlineAdvisor) {
+ Advice = ExternalInlineAdvisor->getAdvice(*Candidate.CallInstr);
+ if (!Advice->isInliningRecommended()) {
+ Advice->recordUnattemptedInlining();
+ return InlineCost::getNever("not previously inlined");
+ }
+ Advice->recordInlining();
+ return InlineCost::getAlways("previously inlined");
+ }
+
+ // Adjust threshold based on call site hotness, only do this for callsite
+ // prioritized inliner because otherwise cost-benefit check is done earlier.
+ int SampleThreshold = SampleColdCallSiteThreshold;
+ if (CallsitePrioritizedInline) {
+ if (Candidate.CallsiteCount > PSI->getHotCountThreshold())
+ SampleThreshold = SampleHotCallSiteThreshold;
+ else if (!ProfileSizeInline)
+ return InlineCost::getNever("cold callsite");
+ }
+
+ Function *Callee = Candidate.CallInstr->getCalledFunction();
+ assert(Callee && "Expect a definition for inline candidate of direct call");
+
+ InlineParams Params = getInlineParams();
+ Params.ComputeFullInlineCost = true;
+ // Checks if there is anything in the reachable portion of the callee at
+ // this callsite that makes this inlining potentially illegal. Need to
+ // set ComputeFullInlineCost, otherwise getInlineCost may return early
+ // when cost exceeds threshold without checking all IRs in the callee.
+ // The acutal cost does not matter because we only checks isNever() to
+ // see if it is legal to inline the callsite.
+ InlineCost Cost = getInlineCost(*Candidate.CallInstr, Callee, Params,
+ GetTTI(*Callee), GetAC, GetTLI);
+
+ // Honor always inline and never inline from call analyzer
+ if (Cost.isNever() || Cost.isAlways())
+ return Cost;
+
+ // For old FDO inliner, we inline the call site as long as cost is not
+ // "Never". The cost-benefit check is done earlier.
+ if (!CallsitePrioritizedInline) {
+ return InlineCost::get(Cost.getCost(), INT_MAX);
+ }
+
+ // Otherwise only use the cost from call analyzer, but overwite threshold with
+ // Sample PGO threshold.
+ return InlineCost::get(Cost.getCost(), SampleThreshold);
+}
+
+bool SampleProfileLoader::inlineHotFunctionsWithPriority(
+ Function &F, DenseSet<GlobalValue::GUID> &InlinedGUIDs) {
+ DenseSet<Instruction *> PromotedInsns;
+ assert(ProfileIsCS && "Prioritiy based inliner only works with CSSPGO now");
+
+ // ProfAccForSymsInList is used in callsiteIsHot. The assertion makes sure
+ // Profile symbol list is ignored when profile-sample-accurate is on.
+ assert((!ProfAccForSymsInList ||
+ (!ProfileSampleAccurate &&
+ !F.hasFnAttribute("profile-sample-accurate"))) &&
+ "ProfAccForSymsInList should be false when profile-sample-accurate "
+ "is enabled");
+
+ // Populating worklist with initial call sites from root inliner, along
+ // with call site weights.
+ CandidateQueue CQueue;
+ InlineCandidate NewCandidate;
+ for (auto &BB : F) {
+ for (auto &I : BB.getInstList()) {
+ auto *CB = dyn_cast<CallBase>(&I);
+ if (!CB)
+ continue;
+ if (getInlineCandidate(&NewCandidate, CB))
+ CQueue.push(NewCandidate);
+ }
+ }
+
+ // Cap the size growth from profile guided inlining. This is needed even
+ // though cost of each inline candidate already accounts for callee size,
+ // because with top-down inlining, we can grow inliner size significantly
+ // with large number of smaller inlinees each pass the cost check.
+ assert(ProfileInlineLimitMax >= ProfileInlineLimitMin &&
+ "Max inline size limit should not be smaller than min inline size "
+ "limit.");
+ unsigned SizeLimit = F.getInstructionCount() * ProfileInlineGrowthLimit;
+ SizeLimit = std::min(SizeLimit, (unsigned)ProfileInlineLimitMax);
+ SizeLimit = std::max(SizeLimit, (unsigned)ProfileInlineLimitMin);
+ if (ExternalInlineAdvisor)
+ SizeLimit = std::numeric_limits<unsigned>::max();
+
+ // Perform iterative BFS call site prioritized inlining
+ bool Changed = false;
+ while (!CQueue.empty() && F.getInstructionCount() < SizeLimit) {
+ InlineCandidate Candidate = CQueue.top();
+ CQueue.pop();
+ CallBase *I = Candidate.CallInstr;
+ Function *CalledFunction = I->getCalledFunction();
+
+ if (CalledFunction == &F)
+ continue;
+ if (I->isIndirectCall()) {
+ if (PromotedInsns.count(I))
+ continue;
+ uint64_t Sum;
+ auto CalleeSamples = findIndirectCallFunctionSamples(*I, Sum);
+ uint64_t SumOrigin = Sum;
+ Sum *= Candidate.CallsiteDistribution;
+ for (const auto *FS : CalleeSamples) {
+ // TODO: Consider disable pre-lTO ICP for MonoLTO as well
+ if (LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink) {
+ FS->findInlinedFunctions(InlinedGUIDs, F.getParent(),
+ PSI->getOrCompHotCountThreshold());
+ continue;
+ }
+ uint64_t EntryCountDistributed =
+ FS->getEntrySamples() * Candidate.CallsiteDistribution;
+ // In addition to regular inline cost check, we also need to make sure
+ // ICP isn't introducing excessive speculative checks even if individual
+ // target looks beneficial to promote and inline. That means we should
+ // only do ICP when there's a small number dominant targets.
+ if (EntryCountDistributed < SumOrigin / ProfileICPThreshold)
+ break;
+ // TODO: Fix CallAnalyzer to handle all indirect calls.
+ // For indirect call, we don't run CallAnalyzer to get InlineCost
+ // before actual inlining. This is because we could see two different
+ // types from the same definition, which makes CallAnalyzer choke as
+ // it's expecting matching parameter type on both caller and callee
+ // side. See example from PR18962 for the triggering cases (the bug was
+ // fixed, but we generate different types).
+ if (!PSI->isHotCount(EntryCountDistributed))
+ break;
+ SmallVector<CallBase *, 8> InlinedCallSites;
+ // Attach function profile for promoted indirect callee, and update
+ // call site count for the promoted inline candidate too.
+ Candidate = {I, FS, EntryCountDistributed,
+ Candidate.CallsiteDistribution};
+ if (tryPromoteAndInlineCandidate(F, Candidate, SumOrigin, Sum,
+ PromotedInsns, &InlinedCallSites)) {
+ for (auto *CB : InlinedCallSites) {
+ if (getInlineCandidate(&NewCandidate, CB))
+ CQueue.emplace(NewCandidate);
+ }
+ Changed = true;
+ }
+ }
+ } else if (CalledFunction && CalledFunction->getSubprogram() &&
+ !CalledFunction->isDeclaration()) {
+ SmallVector<CallBase *, 8> InlinedCallSites;
+ if (tryInlineCandidate(Candidate, &InlinedCallSites)) {
+ for (auto *CB : InlinedCallSites) {
+ if (getInlineCandidate(&NewCandidate, CB))
+ CQueue.emplace(NewCandidate);
+ }
+ Changed = true;
+ }
+ } else if (LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink) {
+ findCalleeFunctionSamples(*I)->findInlinedFunctions(
+ InlinedGUIDs, F.getParent(), PSI->getOrCompHotCountThreshold());
+ }
+ }
+
+ if (!CQueue.empty()) {
+ if (SizeLimit == (unsigned)ProfileInlineLimitMax)
+ ++NumCSInlinedHitMaxLimit;
+ else if (SizeLimit == (unsigned)ProfileInlineLimitMin)
+ ++NumCSInlinedHitMinLimit;
+ else
+ ++NumCSInlinedHitGrowthLimit;
+ }
+
+ return Changed;
+}
+
/// Find equivalence classes for the given block.
///
/// This finds all the blocks that are guaranteed to execute the same
@@ -2031,18 +2031,18 @@ void SampleProfileLoader::propagateWeights(Function &F) {
const FunctionSamples *FS = findFunctionSamples(I);
if (!FS)
continue;
- auto CallSite = FunctionSamples::getCallSiteIdentifier(DIL);
- auto T = FS->findCallTargetMapAt(CallSite);
+ auto CallSite = FunctionSamples::getCallSiteIdentifier(DIL);
+ auto T = FS->findCallTargetMapAt(CallSite);
if (!T || T.get().empty())
continue;
- // Prorate the callsite counts to reflect what is already done to the
- // callsite, such as ICP or calliste cloning.
- if (FunctionSamples::ProfileIsProbeBased) {
- if (Optional<PseudoProbe> Probe = extractProbe(I)) {
- if (Probe->Factor < 1)
- T = SampleRecord::adjustCallTargets(T.get(), Probe->Factor);
- }
- }
+ // Prorate the callsite counts to reflect what is already done to the
+ // callsite, such as ICP or calliste cloning.
+ if (FunctionSamples::ProfileIsProbeBased) {
+ if (Optional<PseudoProbe> Probe = extractProbe(I)) {
+ if (Probe->Factor < 1)
+ T = SampleRecord::adjustCallTargets(T.get(), Probe->Factor);
+ }
+ }
SmallVector<InstrProfValueData, 2> SortedCallTargets =
GetSortedValueDataFromCallTargets(T.get());
uint64_t Sum;
@@ -2204,28 +2204,28 @@ void SampleProfileLoader::computeDominanceAndLoopInfo(Function &F) {
bool SampleProfileLoader::emitAnnotations(Function &F) {
bool Changed = false;
- if (FunctionSamples::ProfileIsProbeBased) {
- if (!ProbeManager->profileIsValid(F, *Samples)) {
- LLVM_DEBUG(
- dbgs() << "Profile is invalid due to CFG mismatch for Function "
- << F.getName());
- ++NumMismatchedProfile;
- return false;
- }
- ++NumMatchedProfile;
- } else {
- if (getFunctionLoc(F) == 0)
- return false;
-
- LLVM_DEBUG(dbgs() << "Line number for the first instruction in "
- << F.getName() << ": " << getFunctionLoc(F) << "\n");
- }
+ if (FunctionSamples::ProfileIsProbeBased) {
+ if (!ProbeManager->profileIsValid(F, *Samples)) {
+ LLVM_DEBUG(
+ dbgs() << "Profile is invalid due to CFG mismatch for Function "
+ << F.getName());
+ ++NumMismatchedProfile;
+ return false;
+ }
+ ++NumMatchedProfile;
+ } else {
+ if (getFunctionLoc(F) == 0)
+ return false;
+
+ LLVM_DEBUG(dbgs() << "Line number for the first instruction in "
+ << F.getName() << ": " << getFunctionLoc(F) << "\n");
+ }
DenseSet<GlobalValue::GUID> InlinedGUIDs;
- if (ProfileIsCS && CallsitePrioritizedInline)
- Changed |= inlineHotFunctionsWithPriority(F, InlinedGUIDs);
- else
- Changed |= inlineHotFunctions(F, InlinedGUIDs);
+ if (ProfileIsCS && CallsitePrioritizedInline)
+ Changed |= inlineHotFunctionsWithPriority(F, InlinedGUIDs);
+ else
+ Changed |= inlineHotFunctions(F, InlinedGUIDs);
// Compute basic block weights.
Changed |= computeBlockWeights(F);
@@ -2290,45 +2290,45 @@ INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
INITIALIZE_PASS_END(SampleProfileLoaderLegacyPass, "sample-profile",
"Sample Profile loader", false, false)
-// Add inlined profile call edges to the call graph.
-void SampleProfileLoader::addCallGraphEdges(CallGraph &CG,
- const FunctionSamples &Samples) {
- Function *Caller = SymbolMap.lookup(Samples.getFuncName());
- if (!Caller || Caller->isDeclaration())
- return;
-
- // Skip non-inlined call edges which are not important since top down inlining
- // for non-CS profile is to get more precise profile matching, not to enable
- // more inlining.
-
- for (const auto &CallsiteSamples : Samples.getCallsiteSamples()) {
- for (const auto &InlinedSamples : CallsiteSamples.second) {
- Function *Callee = SymbolMap.lookup(InlinedSamples.first);
- if (Callee && !Callee->isDeclaration())
- CG[Caller]->addCalledFunction(nullptr, CG[Callee]);
- addCallGraphEdges(CG, InlinedSamples.second);
- }
- }
-}
-
-// Replace call graph edges with dynamic call edges from the profile.
-void SampleProfileLoader::replaceCallGraphEdges(
- CallGraph &CG, StringMap<Function *> &SymbolMap) {
- // Remove static call edges from the call graph except for the ones from the
- // root which make the call graph connected.
- for (const auto &Node : CG)
- if (Node.second.get() != CG.getExternalCallingNode())
- Node.second->removeAllCalledFunctions();
-
- // Add profile call edges to the call graph.
- if (ProfileIsCS) {
- ContextTracker->addCallGraphEdges(CG, SymbolMap);
- } else {
- for (const auto &Samples : Reader->getProfiles())
- addCallGraphEdges(CG, Samples.second);
- }
-}
-
+// Add inlined profile call edges to the call graph.
+void SampleProfileLoader::addCallGraphEdges(CallGraph &CG,
+ const FunctionSamples &Samples) {
+ Function *Caller = SymbolMap.lookup(Samples.getFuncName());
+ if (!Caller || Caller->isDeclaration())
+ return;
+
+ // Skip non-inlined call edges which are not important since top down inlining
+ // for non-CS profile is to get more precise profile matching, not to enable
+ // more inlining.
+
+ for (const auto &CallsiteSamples : Samples.getCallsiteSamples()) {
+ for (const auto &InlinedSamples : CallsiteSamples.second) {
+ Function *Callee = SymbolMap.lookup(InlinedSamples.first);
+ if (Callee && !Callee->isDeclaration())
+ CG[Caller]->addCalledFunction(nullptr, CG[Callee]);
+ addCallGraphEdges(CG, InlinedSamples.second);
+ }
+ }
+}
+
+// Replace call graph edges with dynamic call edges from the profile.
+void SampleProfileLoader::replaceCallGraphEdges(
+ CallGraph &CG, StringMap<Function *> &SymbolMap) {
+ // Remove static call edges from the call graph except for the ones from the
+ // root which make the call graph connected.
+ for (const auto &Node : CG)
+ if (Node.second.get() != CG.getExternalCallingNode())
+ Node.second->removeAllCalledFunctions();
+
+ // Add profile call edges to the call graph.
+ if (ProfileIsCS) {
+ ContextTracker->addCallGraphEdges(CG, SymbolMap);
+ } else {
+ for (const auto &Samples : Reader->getProfiles())
+ addCallGraphEdges(CG, Samples.second);
+ }
+}
+
std::vector<Function *>
SampleProfileLoader::buildFunctionOrder(Module &M, CallGraph *CG) {
std::vector<Function *> FunctionOrderList;
@@ -2351,103 +2351,103 @@ SampleProfileLoader::buildFunctionOrder(Module &M, CallGraph *CG) {
}
assert(&CG->getModule() == &M);
-
- // Add indirect call edges from profile to augment the static call graph.
- // Functions will be processed in a top-down order defined by the static call
- // graph. Adjusting the order by considering indirect call edges from the
- // profile (which don't exist in the static call graph) can enable the
- // inlining of indirect call targets by processing the caller before them.
- // TODO: enable this for non-CS profile and fix the counts returning logic to
- // have a full support for indirect calls.
- if (UseProfileIndirectCallEdges && ProfileIsCS) {
- for (auto &Entry : *CG) {
- const auto *F = Entry.first;
- if (!F || F->isDeclaration() || !F->hasFnAttribute("use-sample-profile"))
- continue;
- auto &AllContexts = ContextTracker->getAllContextSamplesFor(F->getName());
- if (AllContexts.empty())
- continue;
-
- for (const auto &BB : *F) {
- for (const auto &I : BB.getInstList()) {
- const auto *CB = dyn_cast<CallBase>(&I);
- if (!CB || !CB->isIndirectCall())
- continue;
- const DebugLoc &DLoc = I.getDebugLoc();
- if (!DLoc)
- continue;
- auto CallSite = FunctionSamples::getCallSiteIdentifier(DLoc);
- for (FunctionSamples *Samples : AllContexts) {
- if (auto CallTargets = Samples->findCallTargetMapAt(CallSite)) {
- for (const auto &Target : CallTargets.get()) {
- Function *Callee = SymbolMap.lookup(Target.first());
- if (Callee && !Callee->isDeclaration())
- Entry.second->addCalledFunction(nullptr, (*CG)[Callee]);
- }
- }
- }
- }
- }
- }
- }
-
- // Compute a top-down order the profile which is used to sort functions in
- // one SCC later. The static processing order computed for an SCC may not
- // reflect the call contexts in the context-sensitive profile, thus may cause
- // potential inlining to be overlooked. The function order in one SCC is being
- // adjusted to a top-down order based on the profile to favor more inlining.
- DenseMap<Function *, uint64_t> ProfileOrderMap;
- if (UseProfileTopDownOrder ||
- (ProfileIsCS && !UseProfileTopDownOrder.getNumOccurrences())) {
- // Create a static call graph. The call edges are not important since they
- // will be replaced by dynamic edges from the profile.
- CallGraph ProfileCG(M);
- replaceCallGraphEdges(ProfileCG, SymbolMap);
- scc_iterator<CallGraph *> CGI = scc_begin(&ProfileCG);
- uint64_t I = 0;
- while (!CGI.isAtEnd()) {
- for (CallGraphNode *Node : *CGI) {
- if (auto *F = Node->getFunction())
- ProfileOrderMap[F] = ++I;
- }
- ++CGI;
- }
- }
-
+
+ // Add indirect call edges from profile to augment the static call graph.
+ // Functions will be processed in a top-down order defined by the static call
+ // graph. Adjusting the order by considering indirect call edges from the
+ // profile (which don't exist in the static call graph) can enable the
+ // inlining of indirect call targets by processing the caller before them.
+ // TODO: enable this for non-CS profile and fix the counts returning logic to
+ // have a full support for indirect calls.
+ if (UseProfileIndirectCallEdges && ProfileIsCS) {
+ for (auto &Entry : *CG) {
+ const auto *F = Entry.first;
+ if (!F || F->isDeclaration() || !F->hasFnAttribute("use-sample-profile"))
+ continue;
+ auto &AllContexts = ContextTracker->getAllContextSamplesFor(F->getName());
+ if (AllContexts.empty())
+ continue;
+
+ for (const auto &BB : *F) {
+ for (const auto &I : BB.getInstList()) {
+ const auto *CB = dyn_cast<CallBase>(&I);
+ if (!CB || !CB->isIndirectCall())
+ continue;
+ const DebugLoc &DLoc = I.getDebugLoc();
+ if (!DLoc)
+ continue;
+ auto CallSite = FunctionSamples::getCallSiteIdentifier(DLoc);
+ for (FunctionSamples *Samples : AllContexts) {
+ if (auto CallTargets = Samples->findCallTargetMapAt(CallSite)) {
+ for (const auto &Target : CallTargets.get()) {
+ Function *Callee = SymbolMap.lookup(Target.first());
+ if (Callee && !Callee->isDeclaration())
+ Entry.second->addCalledFunction(nullptr, (*CG)[Callee]);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Compute a top-down order the profile which is used to sort functions in
+ // one SCC later. The static processing order computed for an SCC may not
+ // reflect the call contexts in the context-sensitive profile, thus may cause
+ // potential inlining to be overlooked. The function order in one SCC is being
+ // adjusted to a top-down order based on the profile to favor more inlining.
+ DenseMap<Function *, uint64_t> ProfileOrderMap;
+ if (UseProfileTopDownOrder ||
+ (ProfileIsCS && !UseProfileTopDownOrder.getNumOccurrences())) {
+ // Create a static call graph. The call edges are not important since they
+ // will be replaced by dynamic edges from the profile.
+ CallGraph ProfileCG(M);
+ replaceCallGraphEdges(ProfileCG, SymbolMap);
+ scc_iterator<CallGraph *> CGI = scc_begin(&ProfileCG);
+ uint64_t I = 0;
+ while (!CGI.isAtEnd()) {
+ for (CallGraphNode *Node : *CGI) {
+ if (auto *F = Node->getFunction())
+ ProfileOrderMap[F] = ++I;
+ }
+ ++CGI;
+ }
+ }
+
scc_iterator<CallGraph *> CGI = scc_begin(CG);
while (!CGI.isAtEnd()) {
- uint64_t Start = FunctionOrderList.size();
- for (CallGraphNode *Node : *CGI) {
- auto *F = Node->getFunction();
+ uint64_t Start = FunctionOrderList.size();
+ for (CallGraphNode *Node : *CGI) {
+ auto *F = Node->getFunction();
if (F && !F->isDeclaration() && F->hasFnAttribute("use-sample-profile"))
FunctionOrderList.push_back(F);
}
-
- // Sort nodes in SCC based on the profile top-down order.
- if (!ProfileOrderMap.empty()) {
- std::stable_sort(FunctionOrderList.begin() + Start,
- FunctionOrderList.end(),
- [&ProfileOrderMap](Function *Left, Function *Right) {
- return ProfileOrderMap[Left] < ProfileOrderMap[Right];
- });
- }
-
+
+ // Sort nodes in SCC based on the profile top-down order.
+ if (!ProfileOrderMap.empty()) {
+ std::stable_sort(FunctionOrderList.begin() + Start,
+ FunctionOrderList.end(),
+ [&ProfileOrderMap](Function *Left, Function *Right) {
+ return ProfileOrderMap[Left] < ProfileOrderMap[Right];
+ });
+ }
+
++CGI;
}
- LLVM_DEBUG({
- dbgs() << "Function processing order:\n";
- for (auto F : reverse(FunctionOrderList)) {
- dbgs() << F->getName() << "\n";
- }
- });
-
+ LLVM_DEBUG({
+ dbgs() << "Function processing order:\n";
+ for (auto F : reverse(FunctionOrderList)) {
+ dbgs() << F->getName() << "\n";
+ }
+ });
+
std::reverse(FunctionOrderList.begin(), FunctionOrderList.end());
return FunctionOrderList;
}
-bool SampleProfileLoader::doInitialization(Module &M,
- FunctionAnalysisManager *FAM) {
+bool SampleProfileLoader::doInitialization(Module &M,
+ FunctionAnalysisManager *FAM) {
auto &Ctx = M.getContext();
auto ReaderOrErr =
@@ -2458,14 +2458,14 @@ bool SampleProfileLoader::doInitialization(Module &M,
return false;
}
Reader = std::move(ReaderOrErr.get());
- Reader->setSkipFlatProf(LTOPhase == ThinOrFullLTOPhase::ThinLTOPostLink);
+ Reader->setSkipFlatProf(LTOPhase == ThinOrFullLTOPhase::ThinLTOPostLink);
Reader->collectFuncsFrom(M);
- if (std::error_code EC = Reader->read()) {
- std::string Msg = "profile reading failed: " + EC.message();
- Ctx.diagnose(DiagnosticInfoSampleProfile(Filename, Msg));
- return false;
- }
-
+ if (std::error_code EC = Reader->read()) {
+ std::string Msg = "profile reading failed: " + EC.message();
+ Ctx.diagnose(DiagnosticInfoSampleProfile(Filename, Msg));
+ return false;
+ }
+
PSL = Reader->getProfileSymbolList();
// While profile-sample-accurate is on, ignore symbol list.
@@ -2477,41 +2477,41 @@ bool SampleProfileLoader::doInitialization(Module &M,
NamesInProfile.insert(NameTable->begin(), NameTable->end());
}
- if (FAM && !ProfileInlineReplayFile.empty()) {
- ExternalInlineAdvisor = std::make_unique<ReplayInlineAdvisor>(
- M, *FAM, Ctx, /*OriginalAdvisor=*/nullptr, ProfileInlineReplayFile,
- /*EmitRemarks=*/false);
- if (!ExternalInlineAdvisor->areReplayRemarksLoaded())
- ExternalInlineAdvisor.reset();
- }
-
- // Apply tweaks if context-sensitive profile is available.
- if (Reader->profileIsCS()) {
- ProfileIsCS = true;
- FunctionSamples::ProfileIsCS = true;
-
- // Enable priority-base inliner and size inline by default for CSSPGO.
- if (!ProfileSizeInline.getNumOccurrences())
- ProfileSizeInline = true;
- if (!CallsitePrioritizedInline.getNumOccurrences())
- CallsitePrioritizedInline = true;
-
- // Tracker for profiles under different context
- ContextTracker =
- std::make_unique<SampleContextTracker>(Reader->getProfiles());
- }
-
- // Load pseudo probe descriptors for probe-based function samples.
- if (Reader->profileIsProbeBased()) {
- ProbeManager = std::make_unique<PseudoProbeManager>(M);
- if (!ProbeManager->moduleIsProbed(M)) {
- const char *Msg =
- "Pseudo-probe-based profile requires SampleProfileProbePass";
- Ctx.diagnose(DiagnosticInfoSampleProfile(Filename, Msg));
- return false;
- }
- }
-
+ if (FAM && !ProfileInlineReplayFile.empty()) {
+ ExternalInlineAdvisor = std::make_unique<ReplayInlineAdvisor>(
+ M, *FAM, Ctx, /*OriginalAdvisor=*/nullptr, ProfileInlineReplayFile,
+ /*EmitRemarks=*/false);
+ if (!ExternalInlineAdvisor->areReplayRemarksLoaded())
+ ExternalInlineAdvisor.reset();
+ }
+
+ // Apply tweaks if context-sensitive profile is available.
+ if (Reader->profileIsCS()) {
+ ProfileIsCS = true;
+ FunctionSamples::ProfileIsCS = true;
+
+ // Enable priority-base inliner and size inline by default for CSSPGO.
+ if (!ProfileSizeInline.getNumOccurrences())
+ ProfileSizeInline = true;
+ if (!CallsitePrioritizedInline.getNumOccurrences())
+ CallsitePrioritizedInline = true;
+
+ // Tracker for profiles under different context
+ ContextTracker =
+ std::make_unique<SampleContextTracker>(Reader->getProfiles());
+ }
+
+ // Load pseudo probe descriptors for probe-based function samples.
+ if (Reader->profileIsProbeBased()) {
+ ProbeManager = std::make_unique<PseudoProbeManager>(M);
+ if (!ProbeManager->moduleIsProbed(M)) {
+ const char *Msg =
+ "Pseudo-probe-based profile requires SampleProfileProbePass";
+ Ctx.diagnose(DiagnosticInfoSampleProfile(Filename, Msg));
+ return false;
+ }
+ }
+
return true;
}
@@ -2537,7 +2537,7 @@ bool SampleProfileLoader::runOnModule(Module &M, ModuleAnalysisManager *AM,
for (const auto &I : Reader->getProfiles())
TotalCollectedSamples += I.second.getTotalSamples();
- auto Remapper = Reader->getRemapper();
+ auto Remapper = Reader->getRemapper();
// Populate the symbol map.
for (const auto &N_F : M.getValueSymbolTable()) {
StringRef OrigName = N_F.getKey();
@@ -2555,16 +2555,16 @@ bool SampleProfileLoader::runOnModule(Module &M, ModuleAnalysisManager *AM,
// to nullptr to avoid confusion.
if (!r.second)
r.first->second = nullptr;
- OrigName = NewName;
+ OrigName = NewName;
+ }
+ // Insert the remapped names into SymbolMap.
+ if (Remapper) {
+ if (auto MapName = Remapper->lookUpNameInProfile(OrigName)) {
+ if (*MapName == OrigName)
+ continue;
+ SymbolMap.insert(std::make_pair(*MapName, F));
+ }
}
- // Insert the remapped names into SymbolMap.
- if (Remapper) {
- if (auto MapName = Remapper->lookUpNameInProfile(OrigName)) {
- if (*MapName == OrigName)
- continue;
- SymbolMap.insert(std::make_pair(*MapName, F));
- }
- }
}
bool retval = false;
@@ -2575,10 +2575,10 @@ bool SampleProfileLoader::runOnModule(Module &M, ModuleAnalysisManager *AM,
}
// Account for cold calls not inlined....
- if (!ProfileIsCS)
- for (const std::pair<Function *, NotInlinedProfileInfo> &pair :
- notInlinedCallInfo)
- updateProfileCallee(pair.first, pair.second.entryCount);
+ if (!ProfileIsCS)
+ for (const std::pair<Function *, NotInlinedProfileInfo> &pair :
+ notInlinedCallInfo)
+ updateProfileCallee(pair.first, pair.second.entryCount);
return retval;
}
@@ -2593,7 +2593,7 @@ bool SampleProfileLoaderLegacyPass::runOnModule(Module &M) {
}
bool SampleProfileLoader::runOnFunction(Function &F, ModuleAnalysisManager *AM) {
- LLVM_DEBUG(dbgs() << "\n\nProcessing Function " << F.getName() << "\n");
+ LLVM_DEBUG(dbgs() << "\n\nProcessing Function " << F.getName() << "\n");
DILocation2SampleMap.clear();
// By default the entry count is initialized to -1, which will be treated
// conservatively by getEntryCount as the same as unknown (None). This is
@@ -2635,10 +2635,10 @@ bool SampleProfileLoader::runOnFunction(Function &F, ModuleAnalysisManager *AM)
initialEntryCount = -1;
}
- // Initialize entry count when the function has no existing entry
- // count value.
- if (!F.getEntryCount().hasValue())
- F.setEntryCount(ProfileCount(initialEntryCount, Function::PCT_Real));
+ // Initialize entry count when the function has no existing entry
+ // count value.
+ if (!F.getEntryCount().hasValue())
+ F.setEntryCount(ProfileCount(initialEntryCount, Function::PCT_Real));
std::unique_ptr<OptimizationRemarkEmitter> OwnedORE;
if (AM) {
auto &FAM =
@@ -2649,12 +2649,12 @@ bool SampleProfileLoader::runOnFunction(Function &F, ModuleAnalysisManager *AM)
OwnedORE = std::make_unique<OptimizationRemarkEmitter>(&F);
ORE = OwnedORE.get();
}
-
- if (ProfileIsCS)
- Samples = ContextTracker->getBaseSamplesFor(F);
- else
- Samples = Reader->getSamplesFor(F);
-
+
+ if (ProfileIsCS)
+ Samples = ContextTracker->getBaseSamplesFor(F);
+ else
+ Samples = Reader->getSamplesFor(F);
+
if (Samples && !Samples->empty())
return emitAnnotations(F);
return false;
@@ -2679,9 +2679,9 @@ PreservedAnalyses SampleProfileLoaderPass::run(Module &M,
ProfileFileName.empty() ? SampleProfileFile : ProfileFileName,
ProfileRemappingFileName.empty() ? SampleProfileRemappingFile
: ProfileRemappingFileName,
- LTOPhase, GetAssumptionCache, GetTTI, GetTLI);
+ LTOPhase, GetAssumptionCache, GetTTI, GetTLI);
- if (!SampleLoader.doInitialization(M, &FAM))
+ if (!SampleLoader.doInitialization(M, &FAM))
return PreservedAnalyses::all();
ProfileSummaryInfo *PSI = &AM.getResult<ProfileSummaryAnalysis>(M);
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/SampleProfileProbe.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/SampleProfileProbe.cpp
index 0e7aec676b..a885c3ee4d 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/SampleProfileProbe.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/SampleProfileProbe.cpp
@@ -1,434 +1,434 @@
-//===- SampleProfileProbe.cpp - Pseudo probe Instrumentation -------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the SampleProfileProber transformation.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/IPO/SampleProfileProbe.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/BlockFrequencyInfo.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/CFG.h"
-#include "llvm/IR/Constant.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/GlobalValue.h"
-#include "llvm/IR/GlobalVariable.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/MDBuilder.h"
-#include "llvm/ProfileData/SampleProf.h"
-#include "llvm/Support/CRC.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Transforms/Instrumentation.h"
-#include "llvm/Transforms/Utils/ModuleUtils.h"
-#include <unordered_set>
-#include <vector>
-
-using namespace llvm;
-#define DEBUG_TYPE "sample-profile-probe"
-
-STATISTIC(ArtificialDbgLine,
- "Number of probes that have an artificial debug line");
-
-static cl::opt<bool>
- VerifyPseudoProbe("verify-pseudo-probe", cl::init(false), cl::Hidden,
- cl::desc("Do pseudo probe verification"));
-
-static cl::list<std::string> VerifyPseudoProbeFuncList(
- "verify-pseudo-probe-funcs", cl::Hidden,
- cl::desc("The option to specify the name of the functions to verify."));
-
-static cl::opt<bool>
- UpdatePseudoProbe("update-pseudo-probe", cl::init(true), cl::Hidden,
- cl::desc("Update pseudo probe distribution factor"));
-
-bool PseudoProbeVerifier::shouldVerifyFunction(const Function *F) {
- // Skip function declaration.
- if (F->isDeclaration())
- return false;
- // Skip function that will not be emitted into object file. The prevailing
- // defintion will be verified instead.
- if (F->hasAvailableExternallyLinkage())
- return false;
- // Do a name matching.
- static std::unordered_set<std::string> VerifyFuncNames(
- VerifyPseudoProbeFuncList.begin(), VerifyPseudoProbeFuncList.end());
- return VerifyFuncNames.empty() || VerifyFuncNames.count(F->getName().str());
-}
-
-void PseudoProbeVerifier::registerCallbacks(PassInstrumentationCallbacks &PIC) {
- if (VerifyPseudoProbe) {
- PIC.registerAfterPassCallback(
- [this](StringRef P, Any IR, const PreservedAnalyses &) {
- this->runAfterPass(P, IR);
- });
- }
-}
-
-// Callback to run after each transformation for the new pass manager.
-void PseudoProbeVerifier::runAfterPass(StringRef PassID, Any IR) {
- std::string Banner =
- "\n*** Pseudo Probe Verification After " + PassID.str() + " ***\n";
- dbgs() << Banner;
- if (any_isa<const Module *>(IR))
- runAfterPass(any_cast<const Module *>(IR));
- else if (any_isa<const Function *>(IR))
- runAfterPass(any_cast<const Function *>(IR));
- else if (any_isa<const LazyCallGraph::SCC *>(IR))
- runAfterPass(any_cast<const LazyCallGraph::SCC *>(IR));
- else if (any_isa<const Loop *>(IR))
- runAfterPass(any_cast<const Loop *>(IR));
- else
- llvm_unreachable("Unknown IR unit");
-}
-
-void PseudoProbeVerifier::runAfterPass(const Module *M) {
- for (const Function &F : *M)
- runAfterPass(&F);
-}
-
-void PseudoProbeVerifier::runAfterPass(const LazyCallGraph::SCC *C) {
- for (const LazyCallGraph::Node &N : *C)
- runAfterPass(&N.getFunction());
-}
-
-void PseudoProbeVerifier::runAfterPass(const Function *F) {
- if (!shouldVerifyFunction(F))
- return;
- ProbeFactorMap ProbeFactors;
- for (const auto &BB : *F)
- collectProbeFactors(&BB, ProbeFactors);
- verifyProbeFactors(F, ProbeFactors);
-}
-
-void PseudoProbeVerifier::runAfterPass(const Loop *L) {
- const Function *F = L->getHeader()->getParent();
- runAfterPass(F);
-}
-
-void PseudoProbeVerifier::collectProbeFactors(const BasicBlock *Block,
- ProbeFactorMap &ProbeFactors) {
- for (const auto &I : *Block) {
- if (Optional<PseudoProbe> Probe = extractProbe(I))
- ProbeFactors[Probe->Id] += Probe->Factor;
- }
-}
-
-void PseudoProbeVerifier::verifyProbeFactors(
- const Function *F, const ProbeFactorMap &ProbeFactors) {
- bool BannerPrinted = false;
- auto &PrevProbeFactors = FunctionProbeFactors[F->getName()];
- for (const auto &I : ProbeFactors) {
- float CurProbeFactor = I.second;
- if (PrevProbeFactors.count(I.first)) {
- float PrevProbeFactor = PrevProbeFactors[I.first];
- if (std::abs(CurProbeFactor - PrevProbeFactor) >
- DistributionFactorVariance) {
- if (!BannerPrinted) {
- dbgs() << "Function " << F->getName() << ":\n";
- BannerPrinted = true;
- }
- dbgs() << "Probe " << I.first << "\tprevious factor "
- << format("%0.2f", PrevProbeFactor) << "\tcurrent factor "
- << format("%0.2f", CurProbeFactor) << "\n";
- }
- }
-
- // Update
- PrevProbeFactors[I.first] = I.second;
- }
-}
-
-PseudoProbeManager::PseudoProbeManager(const Module &M) {
- if (NamedMDNode *FuncInfo = M.getNamedMetadata(PseudoProbeDescMetadataName)) {
- for (const auto *Operand : FuncInfo->operands()) {
- const auto *MD = cast<MDNode>(Operand);
- auto GUID =
- mdconst::dyn_extract<ConstantInt>(MD->getOperand(0))->getZExtValue();
- auto Hash =
- mdconst::dyn_extract<ConstantInt>(MD->getOperand(1))->getZExtValue();
- GUIDToProbeDescMap.try_emplace(GUID, PseudoProbeDescriptor(GUID, Hash));
- }
- }
-}
-
-const PseudoProbeDescriptor *
-PseudoProbeManager::getDesc(const Function &F) const {
- auto I = GUIDToProbeDescMap.find(
- Function::getGUID(FunctionSamples::getCanonicalFnName(F)));
- return I == GUIDToProbeDescMap.end() ? nullptr : &I->second;
-}
-
-bool PseudoProbeManager::moduleIsProbed(const Module &M) const {
- return M.getNamedMetadata(PseudoProbeDescMetadataName);
-}
-
-bool PseudoProbeManager::profileIsValid(const Function &F,
- const FunctionSamples &Samples) const {
- const auto *Desc = getDesc(F);
- if (!Desc) {
- LLVM_DEBUG(dbgs() << "Probe descriptor missing for Function " << F.getName()
- << "\n");
- return false;
- } else {
- if (Desc->getFunctionHash() != Samples.getFunctionHash()) {
- LLVM_DEBUG(dbgs() << "Hash mismatch for Function " << F.getName()
- << "\n");
- return false;
- }
- }
- return true;
-}
-
-SampleProfileProber::SampleProfileProber(Function &Func,
- const std::string &CurModuleUniqueId)
- : F(&Func), CurModuleUniqueId(CurModuleUniqueId) {
- BlockProbeIds.clear();
- CallProbeIds.clear();
- LastProbeId = (uint32_t)PseudoProbeReservedId::Last;
- computeProbeIdForBlocks();
- computeProbeIdForCallsites();
- computeCFGHash();
-}
-
-// Compute Hash value for the CFG: the lower 32 bits are CRC32 of the index
-// value of each BB in the CFG. The higher 32 bits record the number of edges
-// preceded by the number of indirect calls.
-// This is derived from FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash().
-void SampleProfileProber::computeCFGHash() {
- std::vector<uint8_t> Indexes;
- JamCRC JC;
- for (auto &BB : *F) {
- auto *TI = BB.getTerminator();
- for (unsigned I = 0, E = TI->getNumSuccessors(); I != E; ++I) {
- auto *Succ = TI->getSuccessor(I);
- auto Index = getBlockId(Succ);
- for (int J = 0; J < 4; J++)
- Indexes.push_back((uint8_t)(Index >> (J * 8)));
- }
- }
-
- JC.update(Indexes);
-
- FunctionHash = (uint64_t)CallProbeIds.size() << 48 |
- (uint64_t)Indexes.size() << 32 | JC.getCRC();
- // Reserve bit 60-63 for other information purpose.
- FunctionHash &= 0x0FFFFFFFFFFFFFFF;
- assert(FunctionHash && "Function checksum should not be zero");
- LLVM_DEBUG(dbgs() << "\nFunction Hash Computation for " << F->getName()
- << ":\n"
- << " CRC = " << JC.getCRC() << ", Edges = "
- << Indexes.size() << ", ICSites = " << CallProbeIds.size()
- << ", Hash = " << FunctionHash << "\n");
-}
-
-void SampleProfileProber::computeProbeIdForBlocks() {
- for (auto &BB : *F) {
- BlockProbeIds[&BB] = ++LastProbeId;
- }
-}
-
-void SampleProfileProber::computeProbeIdForCallsites() {
- for (auto &BB : *F) {
- for (auto &I : BB) {
- if (!isa<CallBase>(I))
- continue;
- if (isa<IntrinsicInst>(&I))
- continue;
- CallProbeIds[&I] = ++LastProbeId;
- }
- }
-}
-
-uint32_t SampleProfileProber::getBlockId(const BasicBlock *BB) const {
- auto I = BlockProbeIds.find(const_cast<BasicBlock *>(BB));
- return I == BlockProbeIds.end() ? 0 : I->second;
-}
-
-uint32_t SampleProfileProber::getCallsiteId(const Instruction *Call) const {
- auto Iter = CallProbeIds.find(const_cast<Instruction *>(Call));
- return Iter == CallProbeIds.end() ? 0 : Iter->second;
-}
-
-void SampleProfileProber::instrumentOneFunc(Function &F, TargetMachine *TM) {
- Module *M = F.getParent();
- MDBuilder MDB(F.getContext());
- // Compute a GUID without considering the function's linkage type. This is
- // fine since function name is the only key in the profile database.
- uint64_t Guid = Function::getGUID(F.getName());
-
- // Assign an artificial debug line to a probe that doesn't come with a real
- // line. A probe not having a debug line will get an incomplete inline
- // context. This will cause samples collected on the probe to be counted
- // into the base profile instead of a context profile. The line number
- // itself is not important though.
- auto AssignDebugLoc = [&](Instruction *I) {
- assert((isa<PseudoProbeInst>(I) || isa<CallBase>(I)) &&
- "Expecting pseudo probe or call instructions");
- if (!I->getDebugLoc()) {
- if (auto *SP = F.getSubprogram()) {
- auto DIL = DILocation::get(SP->getContext(), 0, 0, SP);
- I->setDebugLoc(DIL);
- ArtificialDbgLine++;
- LLVM_DEBUG({
- dbgs() << "\nIn Function " << F.getName()
- << " Probe gets an artificial debug line\n";
- I->dump();
- });
- }
- }
- };
-
- // Probe basic blocks.
- for (auto &I : BlockProbeIds) {
- BasicBlock *BB = I.first;
- uint32_t Index = I.second;
- // Insert a probe before an instruction with a valid debug line number which
- // will be assigned to the probe. The line number will be used later to
- // model the inline context when the probe is inlined into other functions.
- // Debug instructions, phi nodes and lifetime markers do not have an valid
- // line number. Real instructions generated by optimizations may not come
- // with a line number either.
- auto HasValidDbgLine = [](Instruction *J) {
- return !isa<PHINode>(J) && !isa<DbgInfoIntrinsic>(J) &&
- !J->isLifetimeStartOrEnd() && J->getDebugLoc();
- };
-
- Instruction *J = &*BB->getFirstInsertionPt();
- while (J != BB->getTerminator() && !HasValidDbgLine(J)) {
- J = J->getNextNode();
- }
-
- IRBuilder<> Builder(J);
- assert(Builder.GetInsertPoint() != BB->end() &&
- "Cannot get the probing point");
- Function *ProbeFn =
- llvm::Intrinsic::getDeclaration(M, Intrinsic::pseudoprobe);
- Value *Args[] = {Builder.getInt64(Guid), Builder.getInt64(Index),
- Builder.getInt32(0),
- Builder.getInt64(PseudoProbeFullDistributionFactor)};
- auto *Probe = Builder.CreateCall(ProbeFn, Args);
- AssignDebugLoc(Probe);
- }
-
- // Probe both direct calls and indirect calls. Direct calls are probed so that
- // their probe ID can be used as an call site identifier to represent a
- // calling context.
- for (auto &I : CallProbeIds) {
- auto *Call = I.first;
- uint32_t Index = I.second;
- uint32_t Type = cast<CallBase>(Call)->getCalledFunction()
- ? (uint32_t)PseudoProbeType::DirectCall
- : (uint32_t)PseudoProbeType::IndirectCall;
- AssignDebugLoc(Call);
- // Levarge the 32-bit discriminator field of debug data to store the ID and
- // type of a callsite probe. This gets rid of the dependency on plumbing a
- // customized metadata through the codegen pipeline.
- uint32_t V = PseudoProbeDwarfDiscriminator::packProbeData(
- Index, Type, 0, PseudoProbeDwarfDiscriminator::FullDistributionFactor);
- if (auto DIL = Call->getDebugLoc()) {
- DIL = DIL->cloneWithDiscriminator(V);
- Call->setDebugLoc(DIL);
- }
- }
-
- // Create module-level metadata that contains function info necessary to
- // synthesize probe-based sample counts, which are
- // - FunctionGUID
- // - FunctionHash.
- // - FunctionName
- auto Hash = getFunctionHash();
- auto *MD = MDB.createPseudoProbeDesc(Guid, Hash, &F);
- auto *NMD = M->getNamedMetadata(PseudoProbeDescMetadataName);
- assert(NMD && "llvm.pseudo_probe_desc should be pre-created");
- NMD->addOperand(MD);
-
- // Preserve a comdat group to hold all probes materialized later. This
- // allows that when the function is considered dead and removed, the
- // materialized probes are disposed too.
- // Imported functions are defined in another module. They do not need
- // the following handling since same care will be taken for them in their
- // original module. The pseudo probes inserted into an imported functions
- // above will naturally not be emitted since the imported function is free
- // from object emission. However they will be emitted together with the
- // inliner functions that the imported function is inlined into. We are not
- // creating a comdat group for an import function since it's useless anyway.
- if (!F.isDeclarationForLinker()) {
- if (TM) {
- auto Triple = TM->getTargetTriple();
- if (Triple.supportsCOMDAT() && TM->getFunctionSections()) {
- GetOrCreateFunctionComdat(F, Triple, CurModuleUniqueId);
- }
- }
- }
-}
-
-PreservedAnalyses SampleProfileProbePass::run(Module &M,
- ModuleAnalysisManager &AM) {
- auto ModuleId = getUniqueModuleId(&M);
- // Create the pseudo probe desc metadata beforehand.
- // Note that modules with only data but no functions will require this to
- // be set up so that they will be known as probed later.
- M.getOrInsertNamedMetadata(PseudoProbeDescMetadataName);
-
- for (auto &F : M) {
- if (F.isDeclaration())
- continue;
- SampleProfileProber ProbeManager(F, ModuleId);
- ProbeManager.instrumentOneFunc(F, TM);
- }
-
- return PreservedAnalyses::none();
-}
-
-void PseudoProbeUpdatePass::runOnFunction(Function &F,
- FunctionAnalysisManager &FAM) {
- BlockFrequencyInfo &BFI = FAM.getResult<BlockFrequencyAnalysis>(F);
- auto BBProfileCount = [&BFI](BasicBlock *BB) {
- return BFI.getBlockProfileCount(BB)
- ? BFI.getBlockProfileCount(BB).getValue()
- : 0;
- };
-
- // Collect the sum of execution weight for each probe.
- ProbeFactorMap ProbeFactors;
- for (auto &Block : F) {
- for (auto &I : Block) {
- if (Optional<PseudoProbe> Probe = extractProbe(I))
- ProbeFactors[Probe->Id] += BBProfileCount(&Block);
- }
- }
-
- // Fix up over-counted probes.
- for (auto &Block : F) {
- for (auto &I : Block) {
- if (Optional<PseudoProbe> Probe = extractProbe(I)) {
- float Sum = ProbeFactors[Probe->Id];
- if (Sum != 0)
- setProbeDistributionFactor(I, BBProfileCount(&Block) / Sum);
- }
- }
- }
-}
-
-PreservedAnalyses PseudoProbeUpdatePass::run(Module &M,
- ModuleAnalysisManager &AM) {
- if (UpdatePseudoProbe) {
- for (auto &F : M) {
- if (F.isDeclaration())
- continue;
- FunctionAnalysisManager &FAM =
- AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
- runOnFunction(F, FAM);
- }
- }
- return PreservedAnalyses::none();
-}
+//===- SampleProfileProbe.cpp - Pseudo probe Instrumentation -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the SampleProfileProber transformation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/IPO/SampleProfileProbe.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/BlockFrequencyInfo.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/MDBuilder.h"
+#include "llvm/ProfileData/SampleProf.h"
+#include "llvm/Support/CRC.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+#include <unordered_set>
+#include <vector>
+
+using namespace llvm;
+#define DEBUG_TYPE "sample-profile-probe"
+
+STATISTIC(ArtificialDbgLine,
+ "Number of probes that have an artificial debug line");
+
+static cl::opt<bool>
+ VerifyPseudoProbe("verify-pseudo-probe", cl::init(false), cl::Hidden,
+ cl::desc("Do pseudo probe verification"));
+
+static cl::list<std::string> VerifyPseudoProbeFuncList(
+ "verify-pseudo-probe-funcs", cl::Hidden,
+ cl::desc("The option to specify the name of the functions to verify."));
+
+static cl::opt<bool>
+ UpdatePseudoProbe("update-pseudo-probe", cl::init(true), cl::Hidden,
+ cl::desc("Update pseudo probe distribution factor"));
+
+bool PseudoProbeVerifier::shouldVerifyFunction(const Function *F) {
+ // Skip function declaration.
+ if (F->isDeclaration())
+ return false;
+ // Skip function that will not be emitted into object file. The prevailing
+ // defintion will be verified instead.
+ if (F->hasAvailableExternallyLinkage())
+ return false;
+ // Do a name matching.
+ static std::unordered_set<std::string> VerifyFuncNames(
+ VerifyPseudoProbeFuncList.begin(), VerifyPseudoProbeFuncList.end());
+ return VerifyFuncNames.empty() || VerifyFuncNames.count(F->getName().str());
+}
+
+void PseudoProbeVerifier::registerCallbacks(PassInstrumentationCallbacks &PIC) {
+ if (VerifyPseudoProbe) {
+ PIC.registerAfterPassCallback(
+ [this](StringRef P, Any IR, const PreservedAnalyses &) {
+ this->runAfterPass(P, IR);
+ });
+ }
+}
+
+// Callback to run after each transformation for the new pass manager.
+void PseudoProbeVerifier::runAfterPass(StringRef PassID, Any IR) {
+ std::string Banner =
+ "\n*** Pseudo Probe Verification After " + PassID.str() + " ***\n";
+ dbgs() << Banner;
+ if (any_isa<const Module *>(IR))
+ runAfterPass(any_cast<const Module *>(IR));
+ else if (any_isa<const Function *>(IR))
+ runAfterPass(any_cast<const Function *>(IR));
+ else if (any_isa<const LazyCallGraph::SCC *>(IR))
+ runAfterPass(any_cast<const LazyCallGraph::SCC *>(IR));
+ else if (any_isa<const Loop *>(IR))
+ runAfterPass(any_cast<const Loop *>(IR));
+ else
+ llvm_unreachable("Unknown IR unit");
+}
+
+void PseudoProbeVerifier::runAfterPass(const Module *M) {
+ for (const Function &F : *M)
+ runAfterPass(&F);
+}
+
+void PseudoProbeVerifier::runAfterPass(const LazyCallGraph::SCC *C) {
+ for (const LazyCallGraph::Node &N : *C)
+ runAfterPass(&N.getFunction());
+}
+
+void PseudoProbeVerifier::runAfterPass(const Function *F) {
+ if (!shouldVerifyFunction(F))
+ return;
+ ProbeFactorMap ProbeFactors;
+ for (const auto &BB : *F)
+ collectProbeFactors(&BB, ProbeFactors);
+ verifyProbeFactors(F, ProbeFactors);
+}
+
+void PseudoProbeVerifier::runAfterPass(const Loop *L) {
+ const Function *F = L->getHeader()->getParent();
+ runAfterPass(F);
+}
+
+void PseudoProbeVerifier::collectProbeFactors(const BasicBlock *Block,
+ ProbeFactorMap &ProbeFactors) {
+ for (const auto &I : *Block) {
+ if (Optional<PseudoProbe> Probe = extractProbe(I))
+ ProbeFactors[Probe->Id] += Probe->Factor;
+ }
+}
+
+void PseudoProbeVerifier::verifyProbeFactors(
+ const Function *F, const ProbeFactorMap &ProbeFactors) {
+ bool BannerPrinted = false;
+ auto &PrevProbeFactors = FunctionProbeFactors[F->getName()];
+ for (const auto &I : ProbeFactors) {
+ float CurProbeFactor = I.second;
+ if (PrevProbeFactors.count(I.first)) {
+ float PrevProbeFactor = PrevProbeFactors[I.first];
+ if (std::abs(CurProbeFactor - PrevProbeFactor) >
+ DistributionFactorVariance) {
+ if (!BannerPrinted) {
+ dbgs() << "Function " << F->getName() << ":\n";
+ BannerPrinted = true;
+ }
+ dbgs() << "Probe " << I.first << "\tprevious factor "
+ << format("%0.2f", PrevProbeFactor) << "\tcurrent factor "
+ << format("%0.2f", CurProbeFactor) << "\n";
+ }
+ }
+
+ // Update
+ PrevProbeFactors[I.first] = I.second;
+ }
+}
+
+PseudoProbeManager::PseudoProbeManager(const Module &M) {
+ if (NamedMDNode *FuncInfo = M.getNamedMetadata(PseudoProbeDescMetadataName)) {
+ for (const auto *Operand : FuncInfo->operands()) {
+ const auto *MD = cast<MDNode>(Operand);
+ auto GUID =
+ mdconst::dyn_extract<ConstantInt>(MD->getOperand(0))->getZExtValue();
+ auto Hash =
+ mdconst::dyn_extract<ConstantInt>(MD->getOperand(1))->getZExtValue();
+ GUIDToProbeDescMap.try_emplace(GUID, PseudoProbeDescriptor(GUID, Hash));
+ }
+ }
+}
+
+const PseudoProbeDescriptor *
+PseudoProbeManager::getDesc(const Function &F) const {
+ auto I = GUIDToProbeDescMap.find(
+ Function::getGUID(FunctionSamples::getCanonicalFnName(F)));
+ return I == GUIDToProbeDescMap.end() ? nullptr : &I->second;
+}
+
+bool PseudoProbeManager::moduleIsProbed(const Module &M) const {
+ return M.getNamedMetadata(PseudoProbeDescMetadataName);
+}
+
+bool PseudoProbeManager::profileIsValid(const Function &F,
+ const FunctionSamples &Samples) const {
+ const auto *Desc = getDesc(F);
+ if (!Desc) {
+ LLVM_DEBUG(dbgs() << "Probe descriptor missing for Function " << F.getName()
+ << "\n");
+ return false;
+ } else {
+ if (Desc->getFunctionHash() != Samples.getFunctionHash()) {
+ LLVM_DEBUG(dbgs() << "Hash mismatch for Function " << F.getName()
+ << "\n");
+ return false;
+ }
+ }
+ return true;
+}
+
+SampleProfileProber::SampleProfileProber(Function &Func,
+ const std::string &CurModuleUniqueId)
+ : F(&Func), CurModuleUniqueId(CurModuleUniqueId) {
+ BlockProbeIds.clear();
+ CallProbeIds.clear();
+ LastProbeId = (uint32_t)PseudoProbeReservedId::Last;
+ computeProbeIdForBlocks();
+ computeProbeIdForCallsites();
+ computeCFGHash();
+}
+
+// Compute Hash value for the CFG: the lower 32 bits are CRC32 of the index
+// value of each BB in the CFG. The higher 32 bits record the number of edges
+// preceded by the number of indirect calls.
+// This is derived from FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash().
+void SampleProfileProber::computeCFGHash() {
+ std::vector<uint8_t> Indexes;
+ JamCRC JC;
+ for (auto &BB : *F) {
+ auto *TI = BB.getTerminator();
+ for (unsigned I = 0, E = TI->getNumSuccessors(); I != E; ++I) {
+ auto *Succ = TI->getSuccessor(I);
+ auto Index = getBlockId(Succ);
+ for (int J = 0; J < 4; J++)
+ Indexes.push_back((uint8_t)(Index >> (J * 8)));
+ }
+ }
+
+ JC.update(Indexes);
+
+ FunctionHash = (uint64_t)CallProbeIds.size() << 48 |
+ (uint64_t)Indexes.size() << 32 | JC.getCRC();
+ // Reserve bit 60-63 for other information purpose.
+ FunctionHash &= 0x0FFFFFFFFFFFFFFF;
+ assert(FunctionHash && "Function checksum should not be zero");
+ LLVM_DEBUG(dbgs() << "\nFunction Hash Computation for " << F->getName()
+ << ":\n"
+ << " CRC = " << JC.getCRC() << ", Edges = "
+ << Indexes.size() << ", ICSites = " << CallProbeIds.size()
+ << ", Hash = " << FunctionHash << "\n");
+}
+
+void SampleProfileProber::computeProbeIdForBlocks() {
+ for (auto &BB : *F) {
+ BlockProbeIds[&BB] = ++LastProbeId;
+ }
+}
+
+void SampleProfileProber::computeProbeIdForCallsites() {
+ for (auto &BB : *F) {
+ for (auto &I : BB) {
+ if (!isa<CallBase>(I))
+ continue;
+ if (isa<IntrinsicInst>(&I))
+ continue;
+ CallProbeIds[&I] = ++LastProbeId;
+ }
+ }
+}
+
+uint32_t SampleProfileProber::getBlockId(const BasicBlock *BB) const {
+ auto I = BlockProbeIds.find(const_cast<BasicBlock *>(BB));
+ return I == BlockProbeIds.end() ? 0 : I->second;
+}
+
+uint32_t SampleProfileProber::getCallsiteId(const Instruction *Call) const {
+ auto Iter = CallProbeIds.find(const_cast<Instruction *>(Call));
+ return Iter == CallProbeIds.end() ? 0 : Iter->second;
+}
+
+void SampleProfileProber::instrumentOneFunc(Function &F, TargetMachine *TM) {
+ Module *M = F.getParent();
+ MDBuilder MDB(F.getContext());
+ // Compute a GUID without considering the function's linkage type. This is
+ // fine since function name is the only key in the profile database.
+ uint64_t Guid = Function::getGUID(F.getName());
+
+ // Assign an artificial debug line to a probe that doesn't come with a real
+ // line. A probe not having a debug line will get an incomplete inline
+ // context. This will cause samples collected on the probe to be counted
+ // into the base profile instead of a context profile. The line number
+ // itself is not important though.
+ auto AssignDebugLoc = [&](Instruction *I) {
+ assert((isa<PseudoProbeInst>(I) || isa<CallBase>(I)) &&
+ "Expecting pseudo probe or call instructions");
+ if (!I->getDebugLoc()) {
+ if (auto *SP = F.getSubprogram()) {
+ auto DIL = DILocation::get(SP->getContext(), 0, 0, SP);
+ I->setDebugLoc(DIL);
+ ArtificialDbgLine++;
+ LLVM_DEBUG({
+ dbgs() << "\nIn Function " << F.getName()
+ << " Probe gets an artificial debug line\n";
+ I->dump();
+ });
+ }
+ }
+ };
+
+ // Probe basic blocks.
+ for (auto &I : BlockProbeIds) {
+ BasicBlock *BB = I.first;
+ uint32_t Index = I.second;
+ // Insert a probe before an instruction with a valid debug line number which
+ // will be assigned to the probe. The line number will be used later to
+ // model the inline context when the probe is inlined into other functions.
+ // Debug instructions, phi nodes and lifetime markers do not have an valid
+ // line number. Real instructions generated by optimizations may not come
+ // with a line number either.
+ auto HasValidDbgLine = [](Instruction *J) {
+ return !isa<PHINode>(J) && !isa<DbgInfoIntrinsic>(J) &&
+ !J->isLifetimeStartOrEnd() && J->getDebugLoc();
+ };
+
+ Instruction *J = &*BB->getFirstInsertionPt();
+ while (J != BB->getTerminator() && !HasValidDbgLine(J)) {
+ J = J->getNextNode();
+ }
+
+ IRBuilder<> Builder(J);
+ assert(Builder.GetInsertPoint() != BB->end() &&
+ "Cannot get the probing point");
+ Function *ProbeFn =
+ llvm::Intrinsic::getDeclaration(M, Intrinsic::pseudoprobe);
+ Value *Args[] = {Builder.getInt64(Guid), Builder.getInt64(Index),
+ Builder.getInt32(0),
+ Builder.getInt64(PseudoProbeFullDistributionFactor)};
+ auto *Probe = Builder.CreateCall(ProbeFn, Args);
+ AssignDebugLoc(Probe);
+ }
+
+ // Probe both direct calls and indirect calls. Direct calls are probed so that
+ // their probe ID can be used as an call site identifier to represent a
+ // calling context.
+ for (auto &I : CallProbeIds) {
+ auto *Call = I.first;
+ uint32_t Index = I.second;
+ uint32_t Type = cast<CallBase>(Call)->getCalledFunction()
+ ? (uint32_t)PseudoProbeType::DirectCall
+ : (uint32_t)PseudoProbeType::IndirectCall;
+ AssignDebugLoc(Call);
+ // Levarge the 32-bit discriminator field of debug data to store the ID and
+ // type of a callsite probe. This gets rid of the dependency on plumbing a
+ // customized metadata through the codegen pipeline.
+ uint32_t V = PseudoProbeDwarfDiscriminator::packProbeData(
+ Index, Type, 0, PseudoProbeDwarfDiscriminator::FullDistributionFactor);
+ if (auto DIL = Call->getDebugLoc()) {
+ DIL = DIL->cloneWithDiscriminator(V);
+ Call->setDebugLoc(DIL);
+ }
+ }
+
+ // Create module-level metadata that contains function info necessary to
+ // synthesize probe-based sample counts, which are
+ // - FunctionGUID
+ // - FunctionHash.
+ // - FunctionName
+ auto Hash = getFunctionHash();
+ auto *MD = MDB.createPseudoProbeDesc(Guid, Hash, &F);
+ auto *NMD = M->getNamedMetadata(PseudoProbeDescMetadataName);
+ assert(NMD && "llvm.pseudo_probe_desc should be pre-created");
+ NMD->addOperand(MD);
+
+ // Preserve a comdat group to hold all probes materialized later. This
+ // allows that when the function is considered dead and removed, the
+ // materialized probes are disposed too.
+ // Imported functions are defined in another module. They do not need
+ // the following handling since same care will be taken for them in their
+ // original module. The pseudo probes inserted into an imported functions
+ // above will naturally not be emitted since the imported function is free
+ // from object emission. However they will be emitted together with the
+ // inliner functions that the imported function is inlined into. We are not
+ // creating a comdat group for an import function since it's useless anyway.
+ if (!F.isDeclarationForLinker()) {
+ if (TM) {
+ auto Triple = TM->getTargetTriple();
+ if (Triple.supportsCOMDAT() && TM->getFunctionSections()) {
+ GetOrCreateFunctionComdat(F, Triple, CurModuleUniqueId);
+ }
+ }
+ }
+}
+
+PreservedAnalyses SampleProfileProbePass::run(Module &M,
+ ModuleAnalysisManager &AM) {
+ auto ModuleId = getUniqueModuleId(&M);
+ // Create the pseudo probe desc metadata beforehand.
+ // Note that modules with only data but no functions will require this to
+ // be set up so that they will be known as probed later.
+ M.getOrInsertNamedMetadata(PseudoProbeDescMetadataName);
+
+ for (auto &F : M) {
+ if (F.isDeclaration())
+ continue;
+ SampleProfileProber ProbeManager(F, ModuleId);
+ ProbeManager.instrumentOneFunc(F, TM);
+ }
+
+ return PreservedAnalyses::none();
+}
+
+void PseudoProbeUpdatePass::runOnFunction(Function &F,
+ FunctionAnalysisManager &FAM) {
+ BlockFrequencyInfo &BFI = FAM.getResult<BlockFrequencyAnalysis>(F);
+ auto BBProfileCount = [&BFI](BasicBlock *BB) {
+ return BFI.getBlockProfileCount(BB)
+ ? BFI.getBlockProfileCount(BB).getValue()
+ : 0;
+ };
+
+ // Collect the sum of execution weight for each probe.
+ ProbeFactorMap ProbeFactors;
+ for (auto &Block : F) {
+ for (auto &I : Block) {
+ if (Optional<PseudoProbe> Probe = extractProbe(I))
+ ProbeFactors[Probe->Id] += BBProfileCount(&Block);
+ }
+ }
+
+ // Fix up over-counted probes.
+ for (auto &Block : F) {
+ for (auto &I : Block) {
+ if (Optional<PseudoProbe> Probe = extractProbe(I)) {
+ float Sum = ProbeFactors[Probe->Id];
+ if (Sum != 0)
+ setProbeDistributionFactor(I, BBProfileCount(&Block) / Sum);
+ }
+ }
+ }
+}
+
+PreservedAnalyses PseudoProbeUpdatePass::run(Module &M,
+ ModuleAnalysisManager &AM) {
+ if (UpdatePseudoProbe) {
+ for (auto &F : M) {
+ if (F.isDeclaration())
+ continue;
+ FunctionAnalysisManager &FAM =
+ AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+ runOnFunction(F, FAM);
+ }
+ }
+ return PreservedAnalyses::none();
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/StripSymbols.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/StripSymbols.cpp
index 7fc7ab71cb..4fc71847a0 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/StripSymbols.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/StripSymbols.cpp
@@ -19,21 +19,21 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/IPO/StripSymbols.h"
+#include "llvm/Transforms/IPO/StripSymbols.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/TypeFinder.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Utils/Local.h"
-
+
using namespace llvm;
namespace {
@@ -252,7 +252,7 @@ bool StripNonDebugSymbols::runOnModule(Module &M) {
return StripSymbolNames(M, true);
}
-static bool stripDebugDeclareImpl(Module &M) {
+static bool stripDebugDeclareImpl(Module &M) {
Function *Declare = M.getFunction("llvm.dbg.declare");
std::vector<Constant*> DeadConstants;
@@ -290,13 +290,13 @@ static bool stripDebugDeclareImpl(Module &M) {
return true;
}
-bool StripDebugDeclare::runOnModule(Module &M) {
+bool StripDebugDeclare::runOnModule(Module &M) {
if (skipModule(M))
return false;
- return stripDebugDeclareImpl(M);
-}
+ return stripDebugDeclareImpl(M);
+}
-static bool stripDeadDebugInfoImpl(Module &M) {
+static bool stripDeadDebugInfoImpl(Module &M) {
bool Changed = false;
LLVMContext &C = M.getContext();
@@ -377,40 +377,40 @@ static bool stripDeadDebugInfoImpl(Module &M) {
return Changed;
}
-
-/// Remove any debug info for global variables/functions in the given module for
-/// which said global variable/function no longer exists (i.e. is null).
-///
-/// Debugging information is encoded in llvm IR using metadata. This is designed
-/// such a way that debug info for symbols preserved even if symbols are
-/// optimized away by the optimizer. This special pass removes debug info for
-/// such symbols.
-bool StripDeadDebugInfo::runOnModule(Module &M) {
- if (skipModule(M))
- return false;
- return stripDeadDebugInfoImpl(M);
-}
-
-PreservedAnalyses StripSymbolsPass::run(Module &M, ModuleAnalysisManager &AM) {
- StripDebugInfo(M);
- StripSymbolNames(M, false);
- return PreservedAnalyses::all();
-}
-
-PreservedAnalyses StripNonDebugSymbolsPass::run(Module &M,
- ModuleAnalysisManager &AM) {
- StripSymbolNames(M, true);
- return PreservedAnalyses::all();
-}
-
-PreservedAnalyses StripDebugDeclarePass::run(Module &M,
- ModuleAnalysisManager &AM) {
- stripDebugDeclareImpl(M);
- return PreservedAnalyses::all();
-}
-
-PreservedAnalyses StripDeadDebugInfoPass::run(Module &M,
- ModuleAnalysisManager &AM) {
- stripDeadDebugInfoImpl(M);
- return PreservedAnalyses::all();
-}
+
+/// Remove any debug info for global variables/functions in the given module for
+/// which said global variable/function no longer exists (i.e. is null).
+///
+/// Debugging information is encoded in llvm IR using metadata. This is designed
+/// such a way that debug info for symbols preserved even if symbols are
+/// optimized away by the optimizer. This special pass removes debug info for
+/// such symbols.
+bool StripDeadDebugInfo::runOnModule(Module &M) {
+ if (skipModule(M))
+ return false;
+ return stripDeadDebugInfoImpl(M);
+}
+
+PreservedAnalyses StripSymbolsPass::run(Module &M, ModuleAnalysisManager &AM) {
+ StripDebugInfo(M);
+ StripSymbolNames(M, false);
+ return PreservedAnalyses::all();
+}
+
+PreservedAnalyses StripNonDebugSymbolsPass::run(Module &M,
+ ModuleAnalysisManager &AM) {
+ StripSymbolNames(M, true);
+ return PreservedAnalyses::all();
+}
+
+PreservedAnalyses StripDebugDeclarePass::run(Module &M,
+ ModuleAnalysisManager &AM) {
+ stripDebugDeclareImpl(M);
+ return PreservedAnalyses::all();
+}
+
+PreservedAnalyses StripDeadDebugInfoPass::run(Module &M,
+ ModuleAnalysisManager &AM) {
+ stripDeadDebugInfoImpl(M);
+ return PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
index 82de762f23..225b4fe95f 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
@@ -14,7 +14,7 @@
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
-#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
@@ -261,7 +261,7 @@ void splitAndWriteThinLTOBitcode(
if (!RT || RT->getBitWidth() > 64 || F->arg_empty() ||
!F->arg_begin()->use_empty())
return;
- for (auto &Arg : drop_begin(F->args())) {
+ for (auto &Arg : drop_begin(F->args())) {
auto *ArgT = dyn_cast<IntegerType>(Arg.getType());
if (!ArgT || ArgT->getBitWidth() > 64)
return;
@@ -334,7 +334,7 @@ void splitAndWriteThinLTOBitcode(
Linkage = CFL_Declaration;
Elts.push_back(ConstantAsMetadata::get(
llvm::ConstantInt::get(Type::getInt8Ty(Ctx), Linkage)));
- append_range(Elts, Types);
+ append_range(Elts, Types);
CfiFunctionMDs.push_back(MDTuple::get(Ctx, Elts));
}
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/WholeProgramDevirt.cpp b/contrib/libs/llvm12/lib/Transforms/IPO/WholeProgramDevirt.cpp
index 1c851975bb..cf1ff405c4 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/WholeProgramDevirt.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/WholeProgramDevirt.cpp
@@ -59,7 +59,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/iterator_range.h"
-#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/TypeMetadataUtils.h"
@@ -470,7 +470,7 @@ CallSiteInfo &VTableSlotInfo::findCallSiteInfo(CallBase &CB) {
auto *CBType = dyn_cast<IntegerType>(CB.getType());
if (!CBType || CBType->getBitWidth() > 64 || CB.arg_empty())
return CSInfo;
- for (auto &&Arg : drop_begin(CB.args())) {
+ for (auto &&Arg : drop_begin(CB.args())) {
auto *CI = dyn_cast<ConstantInt>(Arg);
if (!CI || CI->getBitWidth() > 64)
return CSInfo;
@@ -753,11 +753,11 @@ PreservedAnalyses WholeProgramDevirtPass::run(Module &M,
auto LookupDomTree = [&FAM](Function &F) -> DominatorTree & {
return FAM.getResult<DominatorTreeAnalysis>(F);
};
- if (UseCommandLine) {
- if (DevirtModule::runForTesting(M, AARGetter, OREGetter, LookupDomTree))
- return PreservedAnalyses::all();
- return PreservedAnalyses::none();
- }
+ if (UseCommandLine) {
+ if (DevirtModule::runForTesting(M, AARGetter, OREGetter, LookupDomTree))
+ return PreservedAnalyses::all();
+ return PreservedAnalyses::none();
+ }
if (!DevirtModule(M, AARGetter, OREGetter, LookupDomTree, ExportSummary,
ImportSummary)
.run())
@@ -1030,10 +1030,10 @@ bool DevirtIndex::tryFindVirtualCallTargets(
void DevirtModule::applySingleImplDevirt(VTableSlotInfo &SlotInfo,
Constant *TheFn, bool &IsExported) {
- // Don't devirtualize function if we're told to skip it
- // in -wholeprogramdevirt-skip.
- if (FunctionsToSkip.match(TheFn->stripPointerCasts()->getName()))
- return;
+ // Don't devirtualize function if we're told to skip it
+ // in -wholeprogramdevirt-skip.
+ if (FunctionsToSkip.match(TheFn->stripPointerCasts()->getName()))
+ return;
auto Apply = [&](CallSiteInfo &CSInfo) {
for (auto &&VCallSite : CSInfo.CallSites) {
if (RemarksEnabled)
@@ -1267,7 +1267,7 @@ void DevirtModule::applyICallBranchFunnel(VTableSlotInfo &SlotInfo,
// Jump tables are only profitable if the retpoline mitigation is enabled.
Attribute FSAttr = CB.getCaller()->getFnAttribute("target-features");
- if (!FSAttr.isValid() ||
+ if (!FSAttr.isValid() ||
!FSAttr.getValueAsString().contains("+retpoline"))
continue;
@@ -1279,7 +1279,7 @@ void DevirtModule::applyICallBranchFunnel(VTableSlotInfo &SlotInfo,
// x86_64.
std::vector<Type *> NewArgs;
NewArgs.push_back(Int8PtrTy);
- append_range(NewArgs, CB.getFunctionType()->params());
+ append_range(NewArgs, CB.getFunctionType()->params());
FunctionType *NewFT =
FunctionType::get(CB.getFunctionType()->getReturnType(), NewArgs,
CB.getFunctionType()->isVarArg());
@@ -1288,7 +1288,7 @@ void DevirtModule::applyICallBranchFunnel(VTableSlotInfo &SlotInfo,
IRBuilder<> IRB(&CB);
std::vector<Value *> Args;
Args.push_back(IRB.CreateBitCast(VCallSite.VTable, Int8PtrTy));
- llvm::append_range(Args, CB.args());
+ llvm::append_range(Args, CB.args());
CallBase *NewCS = nullptr;
if (isa<CallInst>(CB))
diff --git a/contrib/libs/llvm12/lib/Transforms/IPO/ya.make b/contrib/libs/llvm12/lib/Transforms/IPO/ya.make
index ab6721253b..5b078050fe 100644
--- a/contrib/libs/llvm12/lib/Transforms/IPO/ya.make
+++ b/contrib/libs/llvm12/lib/Transforms/IPO/ya.make
@@ -12,24 +12,24 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/Bitcode/Reader
- contrib/libs/llvm12/lib/Bitcode/Writer
- contrib/libs/llvm12/lib/Frontend/OpenMP
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/IRReader
- contrib/libs/llvm12/lib/Linker
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/ProfileData
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine
- contrib/libs/llvm12/lib/Transforms/InstCombine
- contrib/libs/llvm12/lib/Transforms/Instrumentation
- contrib/libs/llvm12/lib/Transforms/Scalar
- contrib/libs/llvm12/lib/Transforms/Utils
- contrib/libs/llvm12/lib/Transforms/Vectorize
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/Bitcode/Reader
+ contrib/libs/llvm12/lib/Bitcode/Writer
+ contrib/libs/llvm12/lib/Frontend/OpenMP
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/IRReader
+ contrib/libs/llvm12/lib/Linker
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/ProfileData
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine
+ contrib/libs/llvm12/lib/Transforms/InstCombine
+ contrib/libs/llvm12/lib/Transforms/Instrumentation
+ contrib/libs/llvm12/lib/Transforms/Scalar
+ contrib/libs/llvm12/lib/Transforms/Utils
+ contrib/libs/llvm12/lib/Transforms/Vectorize
)
ADDINCL(
@@ -42,7 +42,7 @@ NO_UTIL()
SRCS(
AlwaysInliner.cpp
- Annotation2Metadata.cpp
+ Annotation2Metadata.cpp
ArgumentPromotion.cpp
Attributor.cpp
AttributorAttributes.cpp
@@ -62,7 +62,7 @@ SRCS(
GlobalSplit.cpp
HotColdSplitting.cpp
IPO.cpp
- IROutliner.cpp
+ IROutliner.cpp
InferFunctionAttrs.cpp
InlineSimple.cpp
Inliner.cpp
@@ -75,9 +75,9 @@ SRCS(
PassManagerBuilder.cpp
PruneEH.cpp
SCCP.cpp
- SampleContextTracker.cpp
+ SampleContextTracker.cpp
SampleProfile.cpp
- SampleProfileProbe.cpp
+ SampleProfileProbe.cpp
StripDeadPrototypes.cpp
StripSymbols.cpp
SyntheticCountsPropagation.cpp
diff --git a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index e289e69efd..bacb868989 100644
--- a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -29,7 +29,7 @@
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/KnownBits.h"
-#include "llvm/Transforms/InstCombine/InstCombiner.h"
+#include "llvm/Transforms/InstCombine/InstCombiner.h"
#include <cassert>
#include <utility>
@@ -82,11 +82,11 @@ namespace {
private:
bool insaneIntVal(int V) { return V > 4 || V < -4; }
- APFloat *getFpValPtr() { return reinterpret_cast<APFloat *>(&FpValBuf); }
+ APFloat *getFpValPtr() { return reinterpret_cast<APFloat *>(&FpValBuf); }
- const APFloat *getFpValPtr() const {
- return reinterpret_cast<const APFloat *>(&FpValBuf);
- }
+ const APFloat *getFpValPtr() const {
+ return reinterpret_cast<const APFloat *>(&FpValBuf);
+ }
const APFloat &getFpVal() const {
assert(IsFp && BufHasFpVal && "Incorret state");
@@ -861,7 +861,7 @@ static Instruction *foldNoWrapAdd(BinaryOperator &Add,
return nullptr;
}
-Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) {
+Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) {
Value *Op0 = Add.getOperand(0), *Op1 = Add.getOperand(1);
Constant *Op1C;
if (!match(Op1, m_Constant(Op1C)))
@@ -887,15 +887,15 @@ Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) {
// zext(bool) + C -> bool ? C + 1 : C
if (match(Op0, m_ZExt(m_Value(X))) &&
X->getType()->getScalarSizeInBits() == 1)
- return SelectInst::Create(X, InstCombiner::AddOne(Op1C), Op1);
+ return SelectInst::Create(X, InstCombiner::AddOne(Op1C), Op1);
// sext(bool) + C -> bool ? C - 1 : C
if (match(Op0, m_SExt(m_Value(X))) &&
X->getType()->getScalarSizeInBits() == 1)
- return SelectInst::Create(X, InstCombiner::SubOne(Op1C), Op1);
+ return SelectInst::Create(X, InstCombiner::SubOne(Op1C), Op1);
// ~X + C --> (C-1) - X
if (match(Op0, m_Not(m_Value(X))))
- return BinaryOperator::CreateSub(InstCombiner::SubOne(Op1C), X);
+ return BinaryOperator::CreateSub(InstCombiner::SubOne(Op1C), X);
const APInt *C;
if (!match(Op1, m_APInt(C)))
@@ -924,39 +924,39 @@ Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) {
C2->isMinSignedValue() && C2->sext(Ty->getScalarSizeInBits()) == *C)
return CastInst::Create(Instruction::SExt, X, Ty);
- if (match(Op0, m_Xor(m_Value(X), m_APInt(C2)))) {
- // (X ^ signmask) + C --> (X + (signmask ^ C))
- if (C2->isSignMask())
- return BinaryOperator::CreateAdd(X, ConstantInt::get(Ty, *C2 ^ *C));
-
- // If X has no high-bits set above an xor mask:
- // add (xor X, LowMaskC), C --> sub (LowMaskC + C), X
- if (C2->isMask()) {
- KnownBits LHSKnown = computeKnownBits(X, 0, &Add);
- if ((*C2 | LHSKnown.Zero).isAllOnesValue())
- return BinaryOperator::CreateSub(ConstantInt::get(Ty, *C2 + *C), X);
- }
-
- // Look for a math+logic pattern that corresponds to sext-in-register of a
- // value with cleared high bits. Convert that into a pair of shifts:
- // add (xor X, 0x80), 0xF..F80 --> (X << ShAmtC) >>s ShAmtC
- // add (xor X, 0xF..F80), 0x80 --> (X << ShAmtC) >>s ShAmtC
- if (Op0->hasOneUse() && *C2 == -(*C)) {
- unsigned BitWidth = Ty->getScalarSizeInBits();
- unsigned ShAmt = 0;
- if (C->isPowerOf2())
- ShAmt = BitWidth - C->logBase2() - 1;
- else if (C2->isPowerOf2())
- ShAmt = BitWidth - C2->logBase2() - 1;
- if (ShAmt && MaskedValueIsZero(X, APInt::getHighBitsSet(BitWidth, ShAmt),
- 0, &Add)) {
- Constant *ShAmtC = ConstantInt::get(Ty, ShAmt);
- Value *NewShl = Builder.CreateShl(X, ShAmtC, "sext");
- return BinaryOperator::CreateAShr(NewShl, ShAmtC);
- }
- }
- }
-
+ if (match(Op0, m_Xor(m_Value(X), m_APInt(C2)))) {
+ // (X ^ signmask) + C --> (X + (signmask ^ C))
+ if (C2->isSignMask())
+ return BinaryOperator::CreateAdd(X, ConstantInt::get(Ty, *C2 ^ *C));
+
+ // If X has no high-bits set above an xor mask:
+ // add (xor X, LowMaskC), C --> sub (LowMaskC + C), X
+ if (C2->isMask()) {
+ KnownBits LHSKnown = computeKnownBits(X, 0, &Add);
+ if ((*C2 | LHSKnown.Zero).isAllOnesValue())
+ return BinaryOperator::CreateSub(ConstantInt::get(Ty, *C2 + *C), X);
+ }
+
+ // Look for a math+logic pattern that corresponds to sext-in-register of a
+ // value with cleared high bits. Convert that into a pair of shifts:
+ // add (xor X, 0x80), 0xF..F80 --> (X << ShAmtC) >>s ShAmtC
+ // add (xor X, 0xF..F80), 0x80 --> (X << ShAmtC) >>s ShAmtC
+ if (Op0->hasOneUse() && *C2 == -(*C)) {
+ unsigned BitWidth = Ty->getScalarSizeInBits();
+ unsigned ShAmt = 0;
+ if (C->isPowerOf2())
+ ShAmt = BitWidth - C->logBase2() - 1;
+ else if (C2->isPowerOf2())
+ ShAmt = BitWidth - C2->logBase2() - 1;
+ if (ShAmt && MaskedValueIsZero(X, APInt::getHighBitsSet(BitWidth, ShAmt),
+ 0, &Add)) {
+ Constant *ShAmtC = ConstantInt::get(Ty, ShAmt);
+ Value *NewShl = Builder.CreateShl(X, ShAmtC, "sext");
+ return BinaryOperator::CreateAShr(NewShl, ShAmtC);
+ }
+ }
+ }
+
if (C->isOneValue() && Op0->hasOneUse()) {
// add (sext i1 X), 1 --> zext (not X)
// TODO: The smallest IR representation is (select X, 0, 1), and that would
@@ -977,15 +977,15 @@ Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) {
}
}
- // If all bits affected by the add are included in a high-bit-mask, do the
- // add before the mask op:
- // (X & 0xFF00) + xx00 --> (X + xx00) & 0xFF00
- if (match(Op0, m_OneUse(m_And(m_Value(X), m_APInt(C2)))) &&
- C2->isNegative() && C2->isShiftedMask() && *C == (*C & *C2)) {
- Value *NewAdd = Builder.CreateAdd(X, ConstantInt::get(Ty, *C));
- return BinaryOperator::CreateAnd(NewAdd, ConstantInt::get(Ty, *C2));
- }
-
+ // If all bits affected by the add are included in a high-bit-mask, do the
+ // add before the mask op:
+ // (X & 0xFF00) + xx00 --> (X + xx00) & 0xFF00
+ if (match(Op0, m_OneUse(m_And(m_Value(X), m_APInt(C2)))) &&
+ C2->isNegative() && C2->isShiftedMask() && *C == (*C & *C2)) {
+ Value *NewAdd = Builder.CreateAdd(X, ConstantInt::get(Ty, *C));
+ return BinaryOperator::CreateAnd(NewAdd, ConstantInt::get(Ty, *C2));
+ }
+
return nullptr;
}
@@ -1064,7 +1064,7 @@ static bool MulWillOverflow(APInt &C0, APInt &C1, bool IsSigned) {
// Simplifies X % C0 + (( X / C0 ) % C1) * C0 to X % (C0 * C1), where (C0 * C1)
// does not overflow.
-Value *InstCombinerImpl::SimplifyAddWithRemainder(BinaryOperator &I) {
+Value *InstCombinerImpl::SimplifyAddWithRemainder(BinaryOperator &I) {
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
Value *X, *MulOpV;
APInt C0, MulOpC;
@@ -1140,9 +1140,9 @@ static Instruction *foldToUnsignedSaturatedAdd(BinaryOperator &I) {
return nullptr;
}
-Instruction *InstCombinerImpl::
- canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(
- BinaryOperator &I) {
+Instruction *InstCombinerImpl::
+ canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(
+ BinaryOperator &I) {
assert((I.getOpcode() == Instruction::Add ||
I.getOpcode() == Instruction::Or ||
I.getOpcode() == Instruction::Sub) &&
@@ -1241,44 +1241,44 @@ Instruction *InstCombinerImpl::
return TruncInst::CreateTruncOrBitCast(NewAShr, I.getType());
}
-/// This is a specialization of a more general transform from
-/// SimplifyUsingDistributiveLaws. If that code can be made to work optimally
-/// for multi-use cases or propagating nsw/nuw, then we would not need this.
-static Instruction *factorizeMathWithShlOps(BinaryOperator &I,
- InstCombiner::BuilderTy &Builder) {
- // TODO: Also handle mul by doubling the shift amount?
- assert((I.getOpcode() == Instruction::Add ||
- I.getOpcode() == Instruction::Sub) &&
- "Expected add/sub");
- auto *Op0 = dyn_cast<BinaryOperator>(I.getOperand(0));
- auto *Op1 = dyn_cast<BinaryOperator>(I.getOperand(1));
- if (!Op0 || !Op1 || !(Op0->hasOneUse() || Op1->hasOneUse()))
- return nullptr;
-
- Value *X, *Y, *ShAmt;
- if (!match(Op0, m_Shl(m_Value(X), m_Value(ShAmt))) ||
- !match(Op1, m_Shl(m_Value(Y), m_Specific(ShAmt))))
- return nullptr;
-
- // No-wrap propagates only when all ops have no-wrap.
- bool HasNSW = I.hasNoSignedWrap() && Op0->hasNoSignedWrap() &&
- Op1->hasNoSignedWrap();
- bool HasNUW = I.hasNoUnsignedWrap() && Op0->hasNoUnsignedWrap() &&
- Op1->hasNoUnsignedWrap();
-
- // add/sub (X << ShAmt), (Y << ShAmt) --> (add/sub X, Y) << ShAmt
- Value *NewMath = Builder.CreateBinOp(I.getOpcode(), X, Y);
- if (auto *NewI = dyn_cast<BinaryOperator>(NewMath)) {
- NewI->setHasNoSignedWrap(HasNSW);
- NewI->setHasNoUnsignedWrap(HasNUW);
- }
- auto *NewShl = BinaryOperator::CreateShl(NewMath, ShAmt);
- NewShl->setHasNoSignedWrap(HasNSW);
- NewShl->setHasNoUnsignedWrap(HasNUW);
- return NewShl;
-}
-
-Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
+/// This is a specialization of a more general transform from
+/// SimplifyUsingDistributiveLaws. If that code can be made to work optimally
+/// for multi-use cases or propagating nsw/nuw, then we would not need this.
+static Instruction *factorizeMathWithShlOps(BinaryOperator &I,
+ InstCombiner::BuilderTy &Builder) {
+ // TODO: Also handle mul by doubling the shift amount?
+ assert((I.getOpcode() == Instruction::Add ||
+ I.getOpcode() == Instruction::Sub) &&
+ "Expected add/sub");
+ auto *Op0 = dyn_cast<BinaryOperator>(I.getOperand(0));
+ auto *Op1 = dyn_cast<BinaryOperator>(I.getOperand(1));
+ if (!Op0 || !Op1 || !(Op0->hasOneUse() || Op1->hasOneUse()))
+ return nullptr;
+
+ Value *X, *Y, *ShAmt;
+ if (!match(Op0, m_Shl(m_Value(X), m_Value(ShAmt))) ||
+ !match(Op1, m_Shl(m_Value(Y), m_Specific(ShAmt))))
+ return nullptr;
+
+ // No-wrap propagates only when all ops have no-wrap.
+ bool HasNSW = I.hasNoSignedWrap() && Op0->hasNoSignedWrap() &&
+ Op1->hasNoSignedWrap();
+ bool HasNUW = I.hasNoUnsignedWrap() && Op0->hasNoUnsignedWrap() &&
+ Op1->hasNoUnsignedWrap();
+
+ // add/sub (X << ShAmt), (Y << ShAmt) --> (add/sub X, Y) << ShAmt
+ Value *NewMath = Builder.CreateBinOp(I.getOpcode(), X, Y);
+ if (auto *NewI = dyn_cast<BinaryOperator>(NewMath)) {
+ NewI->setHasNoSignedWrap(HasNSW);
+ NewI->setHasNoUnsignedWrap(HasNUW);
+ }
+ auto *NewShl = BinaryOperator::CreateShl(NewMath, ShAmt);
+ NewShl->setHasNoSignedWrap(HasNSW);
+ NewShl->setHasNoUnsignedWrap(HasNUW);
+ return NewShl;
+}
+
+Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
if (Value *V = SimplifyAddInst(I.getOperand(0), I.getOperand(1),
I.hasNoSignedWrap(), I.hasNoUnsignedWrap(),
SQ.getWithInstruction(&I)))
@@ -1294,9 +1294,9 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
if (Value *V = SimplifyUsingDistributiveLaws(I))
return replaceInstUsesWith(I, V);
- if (Instruction *R = factorizeMathWithShlOps(I, Builder))
- return R;
-
+ if (Instruction *R = factorizeMathWithShlOps(I, Builder))
+ return R;
+
if (Instruction *X = foldAddWithConstant(I))
return X;
@@ -1434,14 +1434,14 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
if (Instruction *SatAdd = foldToUnsignedSaturatedAdd(I))
return SatAdd;
- // usub.sat(A, B) + B => umax(A, B)
- if (match(&I, m_c_BinOp(
- m_OneUse(m_Intrinsic<Intrinsic::usub_sat>(m_Value(A), m_Value(B))),
- m_Deferred(B)))) {
- return replaceInstUsesWith(I,
- Builder.CreateIntrinsic(Intrinsic::umax, {I.getType()}, {A, B}));
- }
-
+ // usub.sat(A, B) + B => umax(A, B)
+ if (match(&I, m_c_BinOp(
+ m_OneUse(m_Intrinsic<Intrinsic::usub_sat>(m_Value(A), m_Value(B))),
+ m_Deferred(B)))) {
+ return replaceInstUsesWith(I,
+ Builder.CreateIntrinsic(Intrinsic::umax, {I.getType()}, {A, B}));
+ }
+
return Changed ? &I : nullptr;
}
@@ -1504,7 +1504,7 @@ static Instruction *factorizeFAddFSub(BinaryOperator &I,
: BinaryOperator::CreateFDivFMF(XY, Z, &I);
}
-Instruction *InstCombinerImpl::visitFAdd(BinaryOperator &I) {
+Instruction *InstCombinerImpl::visitFAdd(BinaryOperator &I) {
if (Value *V = SimplifyFAddInst(I.getOperand(0), I.getOperand(1),
I.getFastMathFlags(),
SQ.getWithInstruction(&I)))
@@ -1618,27 +1618,27 @@ Instruction *InstCombinerImpl::visitFAdd(BinaryOperator &I) {
/// Optimize pointer differences into the same array into a size. Consider:
/// &A[10] - &A[0]: we should compile this to "10". LHS/RHS are the pointer
/// operands to the ptrtoint instructions for the LHS/RHS of the subtract.
-Value *InstCombinerImpl::OptimizePointerDifference(Value *LHS, Value *RHS,
- Type *Ty, bool IsNUW) {
+Value *InstCombinerImpl::OptimizePointerDifference(Value *LHS, Value *RHS,
+ Type *Ty, bool IsNUW) {
// If LHS is a gep based on RHS or RHS is a gep based on LHS, we can optimize
// this.
bool Swapped = false;
GEPOperator *GEP1 = nullptr, *GEP2 = nullptr;
- if (!isa<GEPOperator>(LHS) && isa<GEPOperator>(RHS)) {
- std::swap(LHS, RHS);
- Swapped = true;
- }
+ if (!isa<GEPOperator>(LHS) && isa<GEPOperator>(RHS)) {
+ std::swap(LHS, RHS);
+ Swapped = true;
+ }
- // Require at least one GEP with a common base pointer on both sides.
- if (auto *LHSGEP = dyn_cast<GEPOperator>(LHS)) {
+ // Require at least one GEP with a common base pointer on both sides.
+ if (auto *LHSGEP = dyn_cast<GEPOperator>(LHS)) {
// (gep X, ...) - X
if (LHSGEP->getOperand(0) == RHS) {
GEP1 = LHSGEP;
- } else if (auto *RHSGEP = dyn_cast<GEPOperator>(RHS)) {
+ } else if (auto *RHSGEP = dyn_cast<GEPOperator>(RHS)) {
// (gep X, ...) - (gep X, ...)
if (LHSGEP->getOperand(0)->stripPointerCasts() ==
- RHSGEP->getOperand(0)->stripPointerCasts()) {
- GEP1 = LHSGEP;
+ RHSGEP->getOperand(0)->stripPointerCasts()) {
+ GEP1 = LHSGEP;
GEP2 = RHSGEP;
}
}
@@ -1672,18 +1672,18 @@ Value *InstCombinerImpl::OptimizePointerDifference(Value *LHS, Value *RHS,
Value *Result = EmitGEPOffset(GEP1);
// If this is a single inbounds GEP and the original sub was nuw,
- // then the final multiplication is also nuw.
- if (auto *I = dyn_cast<Instruction>(Result))
- if (IsNUW && !GEP2 && !Swapped && GEP1->isInBounds() &&
- I->getOpcode() == Instruction::Mul)
- I->setHasNoUnsignedWrap();
-
- // If we have a 2nd GEP of the same base pointer, subtract the offsets.
- // If both GEPs are inbounds, then the subtract does not have signed overflow.
+ // then the final multiplication is also nuw.
+ if (auto *I = dyn_cast<Instruction>(Result))
+ if (IsNUW && !GEP2 && !Swapped && GEP1->isInBounds() &&
+ I->getOpcode() == Instruction::Mul)
+ I->setHasNoUnsignedWrap();
+
+ // If we have a 2nd GEP of the same base pointer, subtract the offsets.
+ // If both GEPs are inbounds, then the subtract does not have signed overflow.
if (GEP2) {
Value *Offset = EmitGEPOffset(GEP2);
- Result = Builder.CreateSub(Result, Offset, "gepdiff", /* NUW */ false,
- GEP1->isInBounds() && GEP2->isInBounds());
+ Result = Builder.CreateSub(Result, Offset, "gepdiff", /* NUW */ false,
+ GEP1->isInBounds() && GEP2->isInBounds());
}
// If we have p - gep(p, ...) then we have to negate the result.
@@ -1693,7 +1693,7 @@ Value *InstCombinerImpl::OptimizePointerDifference(Value *LHS, Value *RHS,
return Builder.CreateIntCast(Result, Ty, true);
}
-Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
+Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
if (Value *V = SimplifySubInst(I.getOperand(0), I.getOperand(1),
I.hasNoSignedWrap(), I.hasNoUnsignedWrap(),
SQ.getWithInstruction(&I)))
@@ -1722,19 +1722,19 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
return Res;
}
- // Try this before Negator to preserve NSW flag.
- if (Instruction *R = factorizeMathWithShlOps(I, Builder))
- return R;
-
- if (Constant *C = dyn_cast<Constant>(Op0)) {
- Value *X;
- Constant *C2;
-
- // C-(X+C2) --> (C-C2)-X
- if (match(Op1, m_Add(m_Value(X), m_Constant(C2))))
- return BinaryOperator::CreateSub(ConstantExpr::getSub(C, C2), X);
- }
-
+ // Try this before Negator to preserve NSW flag.
+ if (Instruction *R = factorizeMathWithShlOps(I, Builder))
+ return R;
+
+ if (Constant *C = dyn_cast<Constant>(Op0)) {
+ Value *X;
+ Constant *C2;
+
+ // C-(X+C2) --> (C-C2)-X
+ if (match(Op1, m_Add(m_Value(X), m_Constant(C2))))
+ return BinaryOperator::CreateSub(ConstantExpr::getSub(C, C2), X);
+ }
+
auto TryToNarrowDeduceFlags = [this, &I, &Op0, &Op1]() -> Instruction * {
if (Instruction *Ext = narrowMathIfNoOverflow(I))
return Ext;
@@ -1802,7 +1802,7 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
}
auto m_AddRdx = [](Value *&Vec) {
- return m_OneUse(m_Intrinsic<Intrinsic::vector_reduce_add>(m_Value(Vec)));
+ return m_OneUse(m_Intrinsic<Intrinsic::vector_reduce_add>(m_Value(Vec)));
};
Value *V0, *V1;
if (match(Op0, m_AddRdx(V0)) && match(Op1, m_AddRdx(V1)) &&
@@ -1810,8 +1810,8 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
// Difference of sums is sum of differences:
// add_rdx(V0) - add_rdx(V1) --> add_rdx(V0 - V1)
Value *Sub = Builder.CreateSub(V0, V1);
- Value *Rdx = Builder.CreateIntrinsic(Intrinsic::vector_reduce_add,
- {Sub->getType()}, {Sub});
+ Value *Rdx = Builder.CreateIntrinsic(Intrinsic::vector_reduce_add,
+ {Sub->getType()}, {Sub});
return replaceInstUsesWith(I, Rdx);
}
@@ -1819,14 +1819,14 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
Value *X;
if (match(Op1, m_ZExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1))
// C - (zext bool) --> bool ? C - 1 : C
- return SelectInst::Create(X, InstCombiner::SubOne(C), C);
+ return SelectInst::Create(X, InstCombiner::SubOne(C), C);
if (match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1))
// C - (sext bool) --> bool ? C + 1 : C
- return SelectInst::Create(X, InstCombiner::AddOne(C), C);
+ return SelectInst::Create(X, InstCombiner::AddOne(C), C);
// C - ~X == X + (1+C)
if (match(Op1, m_Not(m_Value(X))))
- return BinaryOperator::CreateAdd(X, InstCombiner::AddOne(C));
+ return BinaryOperator::CreateAdd(X, InstCombiner::AddOne(C));
// Try to fold constant sub into select arguments.
if (SelectInst *SI = dyn_cast<SelectInst>(Op1))
@@ -1841,7 +1841,7 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
Constant *C2;
// C-(C2-X) --> X+(C-C2)
- if (match(Op1, m_Sub(m_ImmConstant(C2), m_Value(X))))
+ if (match(Op1, m_Sub(m_ImmConstant(C2), m_Value(X))))
return BinaryOperator::CreateAdd(X, ConstantExpr::getSub(C, C2));
}
@@ -1873,22 +1873,22 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
return BinaryOperator::CreateXor(A, B);
}
- // (sub (add A, B) (or A, B)) --> (and A, B)
- {
- Value *A, *B;
- if (match(Op0, m_Add(m_Value(A), m_Value(B))) &&
- match(Op1, m_c_Or(m_Specific(A), m_Specific(B))))
- return BinaryOperator::CreateAnd(A, B);
- }
-
- // (sub (add A, B) (and A, B)) --> (or A, B)
- {
- Value *A, *B;
- if (match(Op0, m_Add(m_Value(A), m_Value(B))) &&
- match(Op1, m_c_And(m_Specific(A), m_Specific(B))))
- return BinaryOperator::CreateOr(A, B);
- }
-
+ // (sub (add A, B) (or A, B)) --> (and A, B)
+ {
+ Value *A, *B;
+ if (match(Op0, m_Add(m_Value(A), m_Value(B))) &&
+ match(Op1, m_c_Or(m_Specific(A), m_Specific(B))))
+ return BinaryOperator::CreateAnd(A, B);
+ }
+
+ // (sub (add A, B) (and A, B)) --> (or A, B)
+ {
+ Value *A, *B;
+ if (match(Op0, m_Add(m_Value(A), m_Value(B))) &&
+ match(Op1, m_c_And(m_Specific(A), m_Specific(B))))
+ return BinaryOperator::CreateOr(A, B);
+ }
+
// (sub (and A, B) (or A, B)) --> neg (xor A, B)
{
Value *A, *B;
@@ -2067,20 +2067,20 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
return SelectInst::Create(Cmp, Neg, A);
}
- // If we are subtracting a low-bit masked subset of some value from an add
- // of that same value with no low bits changed, that is clearing some low bits
- // of the sum:
- // sub (X + AddC), (X & AndC) --> and (X + AddC), ~AndC
- const APInt *AddC, *AndC;
- if (match(Op0, m_Add(m_Value(X), m_APInt(AddC))) &&
- match(Op1, m_And(m_Specific(X), m_APInt(AndC)))) {
- unsigned BitWidth = Ty->getScalarSizeInBits();
- unsigned Cttz = AddC->countTrailingZeros();
- APInt HighMask(APInt::getHighBitsSet(BitWidth, BitWidth - Cttz));
- if ((HighMask & *AndC).isNullValue())
- return BinaryOperator::CreateAnd(Op0, ConstantInt::get(Ty, ~(*AndC)));
- }
-
+ // If we are subtracting a low-bit masked subset of some value from an add
+ // of that same value with no low bits changed, that is clearing some low bits
+ // of the sum:
+ // sub (X + AddC), (X & AndC) --> and (X + AddC), ~AndC
+ const APInt *AddC, *AndC;
+ if (match(Op0, m_Add(m_Value(X), m_APInt(AddC))) &&
+ match(Op1, m_And(m_Specific(X), m_APInt(AndC)))) {
+ unsigned BitWidth = Ty->getScalarSizeInBits();
+ unsigned Cttz = AddC->countTrailingZeros();
+ APInt HighMask(APInt::getHighBitsSet(BitWidth, BitWidth - Cttz));
+ if ((HighMask & *AndC).isNullValue())
+ return BinaryOperator::CreateAnd(Op0, ConstantInt::get(Ty, ~(*AndC)));
+ }
+
if (Instruction *V =
canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(I))
return V;
@@ -2133,11 +2133,11 @@ static Instruction *hoistFNegAboveFMulFDiv(Instruction &I,
return nullptr;
}
-Instruction *InstCombinerImpl::visitFNeg(UnaryOperator &I) {
+Instruction *InstCombinerImpl::visitFNeg(UnaryOperator &I) {
Value *Op = I.getOperand(0);
if (Value *V = SimplifyFNegInst(Op, I.getFastMathFlags(),
- getSimplifyQuery().getWithInstruction(&I)))
+ getSimplifyQuery().getWithInstruction(&I)))
return replaceInstUsesWith(I, V);
if (Instruction *X = foldFNegIntoConstant(I))
@@ -2156,10 +2156,10 @@ Instruction *InstCombinerImpl::visitFNeg(UnaryOperator &I) {
return nullptr;
}
-Instruction *InstCombinerImpl::visitFSub(BinaryOperator &I) {
+Instruction *InstCombinerImpl::visitFSub(BinaryOperator &I) {
if (Value *V = SimplifyFSubInst(I.getOperand(0), I.getOperand(1),
I.getFastMathFlags(),
- getSimplifyQuery().getWithInstruction(&I)))
+ getSimplifyQuery().getWithInstruction(&I)))
return replaceInstUsesWith(I, V);
if (Instruction *X = foldVectorBinop(I))
@@ -2214,7 +2214,7 @@ Instruction *InstCombinerImpl::visitFSub(BinaryOperator &I) {
// X - C --> X + (-C)
// But don't transform constant expressions because there's an inverse fold
// for X + (-Y) --> X - Y.
- if (match(Op1, m_ImmConstant(C)))
+ if (match(Op1, m_ImmConstant(C)))
return BinaryOperator::CreateFAddFMF(Op0, ConstantExpr::getFNeg(C), &I);
// X - (-Y) --> X + Y
@@ -2283,8 +2283,8 @@ Instruction *InstCombinerImpl::visitFSub(BinaryOperator &I) {
}
auto m_FaddRdx = [](Value *&Sum, Value *&Vec) {
- return m_OneUse(m_Intrinsic<Intrinsic::vector_reduce_fadd>(m_Value(Sum),
- m_Value(Vec)));
+ return m_OneUse(m_Intrinsic<Intrinsic::vector_reduce_fadd>(m_Value(Sum),
+ m_Value(Vec)));
};
Value *A0, *A1, *V0, *V1;
if (match(Op0, m_FaddRdx(A0, V0)) && match(Op1, m_FaddRdx(A1, V1)) &&
@@ -2292,8 +2292,8 @@ Instruction *InstCombinerImpl::visitFSub(BinaryOperator &I) {
// Difference of sums is sum of differences:
// add_rdx(A0, V0) - add_rdx(A1, V1) --> add_rdx(A0, V0 - V1) - A1
Value *Sub = Builder.CreateFSubFMF(V0, V1, &I);
- Value *Rdx = Builder.CreateIntrinsic(Intrinsic::vector_reduce_fadd,
- {Sub->getType()}, {A0, Sub}, &I);
+ Value *Rdx = Builder.CreateIntrinsic(Intrinsic::vector_reduce_fadd,
+ {Sub->getType()}, {A0, Sub}, &I);
return BinaryOperator::CreateFSubFMF(Rdx, A1, &I);
}
diff --git a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 7dea2acbf4..85a7abe211 100644
--- a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -16,9 +16,9 @@
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/PatternMatch.h"
-#include "llvm/Transforms/InstCombine/InstCombiner.h"
-#include "llvm/Transforms/Utils/Local.h"
-
+#include "llvm/Transforms/InstCombine/InstCombiner.h"
+#include "llvm/Transforms/Utils/Local.h"
+
using namespace llvm;
using namespace PatternMatch;
@@ -117,9 +117,9 @@ static Value *SimplifyBSwap(BinaryOperator &I,
/// Emit a computation of: (V >= Lo && V < Hi) if Inside is true, otherwise
/// (V < Lo || V >= Hi). This method expects that Lo < Hi. IsSigned indicates
/// whether to treat V, Lo, and Hi as signed or not.
-Value *InstCombinerImpl::insertRangeTest(Value *V, const APInt &Lo,
- const APInt &Hi, bool isSigned,
- bool Inside) {
+Value *InstCombinerImpl::insertRangeTest(Value *V, const APInt &Lo,
+ const APInt &Hi, bool isSigned,
+ bool Inside) {
assert((isSigned ? Lo.slt(Hi) : Lo.ult(Hi)) &&
"Lo is not < Hi in range emission code!");
@@ -394,10 +394,10 @@ getMaskedTypeForICmpPair(Value *&A, Value *&B, Value *&C,
/// (icmp(A & X) ==/!= Y), where the left-hand side is of type Mask_NotAllZeros
/// and the right hand side is of type BMask_Mixed. For example,
/// (icmp (A & 12) != 0) & (icmp (A & 15) == 8) -> (icmp (A & 15) == 8).
-static Value *foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(
- ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, Value *A, Value *B, Value *C,
- Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR,
- InstCombiner::BuilderTy &Builder) {
+static Value *foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(
+ ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, Value *A, Value *B, Value *C,
+ Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR,
+ InstCombiner::BuilderTy &Builder) {
// We are given the canonical form:
// (icmp ne (A & B), 0) & (icmp eq (A & D), E).
// where D & E == E.
@@ -408,9 +408,9 @@ static Value *foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(
//
// We currently handle the case of B, C, D, E are constant.
//
- ConstantInt *BCst, *CCst, *DCst, *ECst;
- if (!match(B, m_ConstantInt(BCst)) || !match(C, m_ConstantInt(CCst)) ||
- !match(D, m_ConstantInt(DCst)) || !match(E, m_ConstantInt(ECst)))
+ ConstantInt *BCst, *CCst, *DCst, *ECst;
+ if (!match(B, m_ConstantInt(BCst)) || !match(C, m_ConstantInt(CCst)) ||
+ !match(D, m_ConstantInt(DCst)) || !match(E, m_ConstantInt(ECst)))
return nullptr;
ICmpInst::Predicate NewCC = IsAnd ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE;
@@ -516,9 +516,9 @@ static Value *foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(
/// (icmp(A & X) ==/!= Y), where the left-hand side and the right hand side
/// aren't of the common mask pattern type.
static Value *foldLogOpOfMaskedICmpsAsymmetric(
- ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, Value *A, Value *B, Value *C,
- Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR,
- unsigned LHSMask, unsigned RHSMask, InstCombiner::BuilderTy &Builder) {
+ ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, Value *A, Value *B, Value *C,
+ Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR,
+ unsigned LHSMask, unsigned RHSMask, InstCombiner::BuilderTy &Builder) {
assert(ICmpInst::isEquality(PredL) && ICmpInst::isEquality(PredR) &&
"Expected equality predicates for masked type of icmps.");
// Handle Mask_NotAllZeros-BMask_Mixed cases.
@@ -549,7 +549,7 @@ static Value *foldLogOpOfMaskedICmpsAsymmetric(
/// Try to fold (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E)
/// into a single (icmp(A & X) ==/!= Y).
static Value *foldLogOpOfMaskedICmps(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd,
- InstCombiner::BuilderTy &Builder) {
+ InstCombiner::BuilderTy &Builder) {
Value *A = nullptr, *B = nullptr, *C = nullptr, *D = nullptr, *E = nullptr;
ICmpInst::Predicate PredL = LHS->getPredicate(), PredR = RHS->getPredicate();
Optional<std::pair<unsigned, unsigned>> MaskPair =
@@ -619,8 +619,8 @@ static Value *foldLogOpOfMaskedICmps(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd,
// Remaining cases assume at least that B and D are constant, and depend on
// their actual values. This isn't strictly necessary, just a "handle the
// easy cases for now" decision.
- ConstantInt *BCst, *DCst;
- if (!match(B, m_ConstantInt(BCst)) || !match(D, m_ConstantInt(DCst)))
+ ConstantInt *BCst, *DCst;
+ if (!match(B, m_ConstantInt(BCst)) || !match(D, m_ConstantInt(DCst)))
return nullptr;
if (Mask & (Mask_NotAllZeros | BMask_NotAllOnes)) {
@@ -661,8 +661,8 @@ static Value *foldLogOpOfMaskedICmps(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd,
// We can't simply use C and E because we might actually handle
// (icmp ne (A & B), B) & (icmp eq (A & D), D)
// with B and D, having a single bit set.
- ConstantInt *CCst, *ECst;
- if (!match(C, m_ConstantInt(CCst)) || !match(E, m_ConstantInt(ECst)))
+ ConstantInt *CCst, *ECst;
+ if (!match(C, m_ConstantInt(CCst)) || !match(E, m_ConstantInt(ECst)))
return nullptr;
if (PredL != NewCC)
CCst = cast<ConstantInt>(ConstantExpr::getXor(BCst, CCst));
@@ -688,8 +688,8 @@ static Value *foldLogOpOfMaskedICmps(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd,
/// Example: (icmp sge x, 0) & (icmp slt x, n) --> icmp ult x, n
/// If \p Inverted is true then the check is for the inverted range, e.g.
/// (icmp slt x, 0) | (icmp sgt x, n) --> icmp ugt x, n
-Value *InstCombinerImpl::simplifyRangeCheck(ICmpInst *Cmp0, ICmpInst *Cmp1,
- bool Inverted) {
+Value *InstCombinerImpl::simplifyRangeCheck(ICmpInst *Cmp0, ICmpInst *Cmp1,
+ bool Inverted) {
// Check the lower range comparison, e.g. x >= 0
// InstCombine already ensured that if there is a constant it's on the RHS.
ConstantInt *RangeStart = dyn_cast<ConstantInt>(Cmp0->getOperand(1));
@@ -796,9 +796,9 @@ foldAndOrOfEqualityCmpsWithConstants(ICmpInst *LHS, ICmpInst *RHS,
// Fold (iszero(A & K1) | iszero(A & K2)) -> (A & (K1 | K2)) != (K1 | K2)
// Fold (!iszero(A & K1) & !iszero(A & K2)) -> (A & (K1 | K2)) == (K1 | K2)
-Value *InstCombinerImpl::foldAndOrOfICmpsOfAndWithPow2(ICmpInst *LHS,
- ICmpInst *RHS,
- BinaryOperator &Logic) {
+Value *InstCombinerImpl::foldAndOrOfICmpsOfAndWithPow2(ICmpInst *LHS,
+ ICmpInst *RHS,
+ BinaryOperator &Logic) {
bool JoinedByAnd = Logic.getOpcode() == Instruction::And;
assert((JoinedByAnd || Logic.getOpcode() == Instruction::Or) &&
"Wrong opcode");
@@ -810,8 +810,8 @@ Value *InstCombinerImpl::foldAndOrOfICmpsOfAndWithPow2(ICmpInst *LHS,
if (!JoinedByAnd && Pred != ICmpInst::ICMP_EQ)
return nullptr;
- if (!match(LHS->getOperand(1), m_Zero()) ||
- !match(RHS->getOperand(1), m_Zero()))
+ if (!match(LHS->getOperand(1), m_Zero()) ||
+ !match(RHS->getOperand(1), m_Zero()))
return nullptr;
Value *A, *B, *C, *D;
@@ -1123,8 +1123,8 @@ static Value *foldAndOrOfICmpsWithConstEq(ICmpInst *Cmp0, ICmpInst *Cmp1,
}
/// Fold (icmp)&(icmp) if possible.
-Value *InstCombinerImpl::foldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS,
- BinaryOperator &And) {
+Value *InstCombinerImpl::foldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS,
+ BinaryOperator &And) {
const SimplifyQuery Q = SQ.getWithInstruction(&And);
// Fold (!iszero(A & K1) & !iszero(A & K2)) -> (A & (K1 | K2)) == (K1 | K2)
@@ -1183,10 +1183,10 @@ Value *InstCombinerImpl::foldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS,
// This only handles icmp of constants: (icmp1 A, C1) & (icmp2 B, C2).
Value *LHS0 = LHS->getOperand(0), *RHS0 = RHS->getOperand(0);
-
- ConstantInt *LHSC, *RHSC;
- if (!match(LHS->getOperand(1), m_ConstantInt(LHSC)) ||
- !match(RHS->getOperand(1), m_ConstantInt(RHSC)))
+
+ ConstantInt *LHSC, *RHSC;
+ if (!match(LHS->getOperand(1), m_ConstantInt(LHSC)) ||
+ !match(RHS->getOperand(1), m_ConstantInt(RHSC)))
return nullptr;
if (LHSC == RHSC && PredL == PredR) {
@@ -1344,8 +1344,8 @@ Value *InstCombinerImpl::foldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS,
return nullptr;
}
-Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
- bool IsAnd) {
+Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
+ bool IsAnd) {
Value *LHS0 = LHS->getOperand(0), *LHS1 = LHS->getOperand(1);
Value *RHS0 = RHS->getOperand(0), *RHS1 = RHS->getOperand(1);
FCmpInst::Predicate PredL = LHS->getPredicate(), PredR = RHS->getPredicate();
@@ -1455,8 +1455,8 @@ static Instruction *matchDeMorgansLaws(BinaryOperator &I,
Value *A, *B;
if (match(I.getOperand(0), m_OneUse(m_Not(m_Value(A)))) &&
match(I.getOperand(1), m_OneUse(m_Not(m_Value(B)))) &&
- !InstCombiner::isFreeToInvert(A, A->hasOneUse()) &&
- !InstCombiner::isFreeToInvert(B, B->hasOneUse())) {
+ !InstCombiner::isFreeToInvert(A, A->hasOneUse()) &&
+ !InstCombiner::isFreeToInvert(B, B->hasOneUse())) {
Value *AndOr = Builder.CreateBinOp(Opcode, A, B, I.getName() + ".demorgan");
return BinaryOperator::CreateNot(AndOr);
}
@@ -1464,7 +1464,7 @@ static Instruction *matchDeMorgansLaws(BinaryOperator &I,
return nullptr;
}
-bool InstCombinerImpl::shouldOptimizeCast(CastInst *CI) {
+bool InstCombinerImpl::shouldOptimizeCast(CastInst *CI) {
Value *CastSrc = CI->getOperand(0);
// Noop casts and casts of constants should be eliminated trivially.
@@ -1520,7 +1520,7 @@ static Instruction *foldLogicCastConstant(BinaryOperator &Logic, CastInst *Cast,
}
/// Fold {and,or,xor} (cast X), Y.
-Instruction *InstCombinerImpl::foldCastedBitwiseLogic(BinaryOperator &I) {
+Instruction *InstCombinerImpl::foldCastedBitwiseLogic(BinaryOperator &I) {
auto LogicOpc = I.getOpcode();
assert(I.isBitwiseLogicOp() && "Unexpected opcode for bitwise logic folding");
@@ -1627,14 +1627,14 @@ static Instruction *foldOrToXor(BinaryOperator &I,
match(Op1, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))))
return BinaryOperator::CreateNot(Builder.CreateXor(A, B));
- // Operand complexity canonicalization guarantees that the 'xor' is Op0.
- // (A ^ B) | ~(A | B) --> ~(A & B)
- // (A ^ B) | ~(B | A) --> ~(A & B)
- if (Op0->hasOneUse() || Op1->hasOneUse())
- if (match(Op0, m_Xor(m_Value(A), m_Value(B))) &&
- match(Op1, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))))
- return BinaryOperator::CreateNot(Builder.CreateAnd(A, B));
-
+ // Operand complexity canonicalization guarantees that the 'xor' is Op0.
+ // (A ^ B) | ~(A | B) --> ~(A & B)
+ // (A ^ B) | ~(B | A) --> ~(A & B)
+ if (Op0->hasOneUse() || Op1->hasOneUse())
+ if (match(Op0, m_Xor(m_Value(A), m_Value(B))) &&
+ match(Op1, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))))
+ return BinaryOperator::CreateNot(Builder.CreateAnd(A, B));
+
// (A & ~B) | (~A & B) --> A ^ B
// (A & ~B) | (B & ~A) --> A ^ B
// (~B & A) | (~A & B) --> A ^ B
@@ -1649,13 +1649,13 @@ static Instruction *foldOrToXor(BinaryOperator &I,
/// Return true if a constant shift amount is always less than the specified
/// bit-width. If not, the shift could create poison in the narrower type.
static bool canNarrowShiftAmt(Constant *C, unsigned BitWidth) {
- APInt Threshold(C->getType()->getScalarSizeInBits(), BitWidth);
- return match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, Threshold));
+ APInt Threshold(C->getType()->getScalarSizeInBits(), BitWidth);
+ return match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, Threshold));
}
/// Try to use narrower ops (sink zext ops) for an 'and' with binop operand and
/// a common zext operand: and (binop (zext X), C), (zext X).
-Instruction *InstCombinerImpl::narrowMaskedBinOp(BinaryOperator &And) {
+Instruction *InstCombinerImpl::narrowMaskedBinOp(BinaryOperator &And) {
// This transform could also apply to {or, and, xor}, but there are better
// folds for those cases, so we don't expect those patterns here. AShr is not
// handled because it should always be transformed to LShr in this sequence.
@@ -1697,9 +1697,9 @@ Instruction *InstCombinerImpl::narrowMaskedBinOp(BinaryOperator &And) {
// FIXME: We use commutative matchers (m_c_*) for some, but not all, matches
// here. We should standardize that construct where it is needed or choose some
// other way to ensure that commutated variants of patterns are not missed.
-Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
- Type *Ty = I.getType();
-
+Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
+ Type *Ty = I.getType();
+
if (Value *V = SimplifyAndInst(I.getOperand(0), I.getOperand(1),
SQ.getWithInstruction(&I)))
return replaceInstUsesWith(I, V);
@@ -1727,22 +1727,22 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
return replaceInstUsesWith(I, V);
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
-
- Value *X, *Y;
- if (match(Op0, m_OneUse(m_LogicalShift(m_One(), m_Value(X)))) &&
- match(Op1, m_One())) {
- // (1 << X) & 1 --> zext(X == 0)
- // (1 >> X) & 1 --> zext(X == 0)
- Value *IsZero = Builder.CreateICmpEQ(X, ConstantInt::get(Ty, 0));
- return new ZExtInst(IsZero, Ty);
- }
-
+
+ Value *X, *Y;
+ if (match(Op0, m_OneUse(m_LogicalShift(m_One(), m_Value(X)))) &&
+ match(Op1, m_One())) {
+ // (1 << X) & 1 --> zext(X == 0)
+ // (1 >> X) & 1 --> zext(X == 0)
+ Value *IsZero = Builder.CreateICmpEQ(X, ConstantInt::get(Ty, 0));
+ return new ZExtInst(IsZero, Ty);
+ }
+
const APInt *C;
if (match(Op1, m_APInt(C))) {
const APInt *XorC;
if (match(Op0, m_OneUse(m_Xor(m_Value(X), m_APInt(XorC))))) {
// (X ^ C1) & C2 --> (X & C2) ^ (C1&C2)
- Constant *NewC = ConstantInt::get(Ty, *C & *XorC);
+ Constant *NewC = ConstantInt::get(Ty, *C & *XorC);
Value *And = Builder.CreateAnd(X, Op1);
And->takeName(Op0);
return BinaryOperator::CreateXor(And, NewC);
@@ -1757,9 +1757,9 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
// that aren't set in C2. Meaning we can replace (C1&C2) with C1 in
// above, but this feels safer.
APInt Together = *C & *OrC;
- Value *And = Builder.CreateAnd(X, ConstantInt::get(Ty, Together ^ *C));
+ Value *And = Builder.CreateAnd(X, ConstantInt::get(Ty, Together ^ *C));
And->takeName(Op0);
- return BinaryOperator::CreateOr(And, ConstantInt::get(Ty, Together));
+ return BinaryOperator::CreateOr(And, ConstantInt::get(Ty, Together));
}
// If the mask is only needed on one incoming arm, push the 'and' op up.
@@ -1780,49 +1780,49 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
return BinaryOperator::Create(BinOp, NewLHS, Y);
}
}
-
- unsigned Width = Ty->getScalarSizeInBits();
+
+ unsigned Width = Ty->getScalarSizeInBits();
const APInt *ShiftC;
if (match(Op0, m_OneUse(m_SExt(m_AShr(m_Value(X), m_APInt(ShiftC)))))) {
if (*C == APInt::getLowBitsSet(Width, Width - ShiftC->getZExtValue())) {
// We are clearing high bits that were potentially set by sext+ashr:
// and (sext (ashr X, ShiftC)), C --> lshr (sext X), ShiftC
- Value *Sext = Builder.CreateSExt(X, Ty);
- Constant *ShAmtC = ConstantInt::get(Ty, ShiftC->zext(Width));
+ Value *Sext = Builder.CreateSExt(X, Ty);
+ Constant *ShAmtC = ConstantInt::get(Ty, ShiftC->zext(Width));
return BinaryOperator::CreateLShr(Sext, ShAmtC);
}
}
-
- const APInt *AddC;
- if (match(Op0, m_Add(m_Value(X), m_APInt(AddC)))) {
- // If we add zeros to every bit below a mask, the add has no effect:
- // (X + AddC) & LowMaskC --> X & LowMaskC
- unsigned Ctlz = C->countLeadingZeros();
- APInt LowMask(APInt::getLowBitsSet(Width, Width - Ctlz));
- if ((*AddC & LowMask).isNullValue())
- return BinaryOperator::CreateAnd(X, Op1);
-
- // If we are masking the result of the add down to exactly one bit and
- // the constant we are adding has no bits set below that bit, then the
- // add is flipping a single bit. Example:
- // (X + 4) & 4 --> (X & 4) ^ 4
- if (Op0->hasOneUse() && C->isPowerOf2() && (*AddC & (*C - 1)) == 0) {
- assert((*C & *AddC) != 0 && "Expected common bit");
- Value *NewAnd = Builder.CreateAnd(X, Op1);
- return BinaryOperator::CreateXor(NewAnd, Op1);
- }
- }
- }
-
- ConstantInt *AndRHS;
- if (match(Op1, m_ConstantInt(AndRHS))) {
+
+ const APInt *AddC;
+ if (match(Op0, m_Add(m_Value(X), m_APInt(AddC)))) {
+ // If we add zeros to every bit below a mask, the add has no effect:
+ // (X + AddC) & LowMaskC --> X & LowMaskC
+ unsigned Ctlz = C->countLeadingZeros();
+ APInt LowMask(APInt::getLowBitsSet(Width, Width - Ctlz));
+ if ((*AddC & LowMask).isNullValue())
+ return BinaryOperator::CreateAnd(X, Op1);
+
+ // If we are masking the result of the add down to exactly one bit and
+ // the constant we are adding has no bits set below that bit, then the
+ // add is flipping a single bit. Example:
+ // (X + 4) & 4 --> (X & 4) ^ 4
+ if (Op0->hasOneUse() && C->isPowerOf2() && (*AddC & (*C - 1)) == 0) {
+ assert((*C & *AddC) != 0 && "Expected common bit");
+ Value *NewAnd = Builder.CreateAnd(X, Op1);
+ return BinaryOperator::CreateXor(NewAnd, Op1);
+ }
+ }
+ }
+
+ ConstantInt *AndRHS;
+ if (match(Op1, m_ConstantInt(AndRHS))) {
const APInt &AndRHSMask = AndRHS->getValue();
// Optimize a variety of ((val OP C1) & C2) combinations...
if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) {
// ((C1 OP zext(X)) & C2) -> zext((C1-X) & C2) if C2 fits in the bitwidth
// of X and OP behaves well when given trunc(C1) and X.
- // TODO: Do this for vectors by using m_APInt instead of m_ConstantInt.
+ // TODO: Do this for vectors by using m_APInt instead of m_ConstantInt.
switch (Op0I->getOpcode()) {
default:
break;
@@ -1847,30 +1847,30 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
BinOp = Builder.CreateBinOp(Op0I->getOpcode(), TruncC1, X);
auto *TruncC2 = ConstantExpr::getTrunc(AndRHS, X->getType());
auto *And = Builder.CreateAnd(BinOp, TruncC2);
- return new ZExtInst(And, Ty);
+ return new ZExtInst(And, Ty);
}
}
}
}
- }
-
- if (match(&I, m_And(m_OneUse(m_Shl(m_ZExt(m_Value(X)), m_Value(Y))),
- m_SignMask())) &&
- match(Y, m_SpecificInt_ICMP(
- ICmpInst::Predicate::ICMP_EQ,
- APInt(Ty->getScalarSizeInBits(),
- Ty->getScalarSizeInBits() -
- X->getType()->getScalarSizeInBits())))) {
- auto *SExt = Builder.CreateSExt(X, Ty, X->getName() + ".signext");
- auto *SanitizedSignMask = cast<Constant>(Op1);
- // We must be careful with the undef elements of the sign bit mask, however:
- // the mask elt can be undef iff the shift amount for that lane was undef,
- // otherwise we need to sanitize undef masks to zero.
- SanitizedSignMask = Constant::replaceUndefsWith(
- SanitizedSignMask, ConstantInt::getNullValue(Ty->getScalarType()));
- SanitizedSignMask =
- Constant::mergeUndefsWith(SanitizedSignMask, cast<Constant>(Y));
- return BinaryOperator::CreateAnd(SExt, SanitizedSignMask);
+ }
+
+ if (match(&I, m_And(m_OneUse(m_Shl(m_ZExt(m_Value(X)), m_Value(Y))),
+ m_SignMask())) &&
+ match(Y, m_SpecificInt_ICMP(
+ ICmpInst::Predicate::ICMP_EQ,
+ APInt(Ty->getScalarSizeInBits(),
+ Ty->getScalarSizeInBits() -
+ X->getType()->getScalarSizeInBits())))) {
+ auto *SExt = Builder.CreateSExt(X, Ty, X->getName() + ".signext");
+ auto *SanitizedSignMask = cast<Constant>(Op1);
+ // We must be careful with the undef elements of the sign bit mask, however:
+ // the mask elt can be undef iff the shift amount for that lane was undef,
+ // otherwise we need to sanitize undef masks to zero.
+ SanitizedSignMask = Constant::replaceUndefsWith(
+ SanitizedSignMask, ConstantInt::getNullValue(Ty->getScalarType()));
+ SanitizedSignMask =
+ Constant::mergeUndefsWith(SanitizedSignMask, cast<Constant>(Y));
+ return BinaryOperator::CreateAnd(SExt, SanitizedSignMask);
}
if (Instruction *Z = narrowMaskedBinOp(I))
@@ -1891,13 +1891,13 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
if (match(Op0, m_OneUse(m_c_Xor(m_Specific(Op1), m_Value(B)))))
return BinaryOperator::CreateAnd(Op1, Builder.CreateNot(B));
- // A & ~(A ^ B) --> A & B
- if (match(Op1, m_Not(m_c_Xor(m_Specific(Op0), m_Value(B)))))
- return BinaryOperator::CreateAnd(Op0, B);
- // ~(A ^ B) & A --> A & B
- if (match(Op0, m_Not(m_c_Xor(m_Specific(Op1), m_Value(B)))))
- return BinaryOperator::CreateAnd(Op1, B);
-
+ // A & ~(A ^ B) --> A & B
+ if (match(Op1, m_Not(m_c_Xor(m_Specific(Op0), m_Value(B)))))
+ return BinaryOperator::CreateAnd(Op0, B);
+ // ~(A ^ B) & A --> A & B
+ if (match(Op0, m_Not(m_c_Xor(m_Specific(Op1), m_Value(B)))))
+ return BinaryOperator::CreateAnd(Op1, B);
+
// (A ^ B) & ((B ^ C) ^ A) -> (A ^ B) & ~C
if (match(Op0, m_Xor(m_Value(A), m_Value(B))))
if (match(Op1, m_Xor(m_Xor(m_Specific(B), m_Value(C)), m_Specific(A))))
@@ -1969,30 +1969,30 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
Value *A;
if (match(Op0, m_OneUse(m_SExt(m_Value(A)))) &&
A->getType()->isIntOrIntVectorTy(1))
- return SelectInst::Create(A, Op1, Constant::getNullValue(Ty));
+ return SelectInst::Create(A, Op1, Constant::getNullValue(Ty));
if (match(Op1, m_OneUse(m_SExt(m_Value(A)))) &&
A->getType()->isIntOrIntVectorTy(1))
- return SelectInst::Create(A, Op0, Constant::getNullValue(Ty));
+ return SelectInst::Create(A, Op0, Constant::getNullValue(Ty));
// and(ashr(subNSW(Y, X), ScalarSizeInBits(Y)-1), X) --> X s> Y ? X : 0.
- if (match(&I, m_c_And(m_OneUse(m_AShr(
- m_NSWSub(m_Value(Y), m_Value(X)),
- m_SpecificInt(Ty->getScalarSizeInBits() - 1))),
- m_Deferred(X)))) {
- Value *NewICmpInst = Builder.CreateICmpSGT(X, Y);
- return SelectInst::Create(NewICmpInst, X, ConstantInt::getNullValue(Ty));
- }
-
- // (~x) & y --> ~(x | (~y)) iff that gets rid of inversions
- if (sinkNotIntoOtherHandOfAndOrOr(I))
- return &I;
-
+ if (match(&I, m_c_And(m_OneUse(m_AShr(
+ m_NSWSub(m_Value(Y), m_Value(X)),
+ m_SpecificInt(Ty->getScalarSizeInBits() - 1))),
+ m_Deferred(X)))) {
+ Value *NewICmpInst = Builder.CreateICmpSGT(X, Y);
+ return SelectInst::Create(NewICmpInst, X, ConstantInt::getNullValue(Ty));
+ }
+
+ // (~x) & y --> ~(x | (~y)) iff that gets rid of inversions
+ if (sinkNotIntoOtherHandOfAndOrOr(I))
+ return &I;
+
return nullptr;
}
-Instruction *InstCombinerImpl::matchBSwapOrBitReverse(BinaryOperator &Or,
- bool MatchBSwaps,
- bool MatchBitReversals) {
+Instruction *InstCombinerImpl::matchBSwapOrBitReverse(BinaryOperator &Or,
+ bool MatchBSwaps,
+ bool MatchBitReversals) {
assert(Or.getOpcode() == Instruction::Or && "bswap requires an 'or'");
Value *Op0 = Or.getOperand(0), *Op1 = Or.getOperand(1);
@@ -2004,32 +2004,32 @@ Instruction *InstCombinerImpl::matchBSwapOrBitReverse(BinaryOperator &Or,
Op1 = Ext->getOperand(0);
// (A | B) | C and A | (B | C) -> bswap if possible.
- bool OrWithOrs = match(Op0, m_Or(m_Value(), m_Value())) ||
- match(Op1, m_Or(m_Value(), m_Value()));
+ bool OrWithOrs = match(Op0, m_Or(m_Value(), m_Value())) ||
+ match(Op1, m_Or(m_Value(), m_Value()));
- // (A >> B) | C and (A << B) | C -> bswap if possible.
- bool OrWithShifts = match(Op0, m_LogicalShift(m_Value(), m_Value())) ||
- match(Op1, m_LogicalShift(m_Value(), m_Value()));
+ // (A >> B) | C and (A << B) | C -> bswap if possible.
+ bool OrWithShifts = match(Op0, m_LogicalShift(m_Value(), m_Value())) ||
+ match(Op1, m_LogicalShift(m_Value(), m_Value()));
- // (A & B) | C and A | (B & C) -> bswap if possible.
- bool OrWithAnds = match(Op0, m_And(m_Value(), m_Value())) ||
- match(Op1, m_And(m_Value(), m_Value()));
+ // (A & B) | C and A | (B & C) -> bswap if possible.
+ bool OrWithAnds = match(Op0, m_And(m_Value(), m_Value())) ||
+ match(Op1, m_And(m_Value(), m_Value()));
- // fshl(A,B,C) | D and A | fshl(B,C,D) -> bswap if possible.
- // fshr(A,B,C) | D and A | fshr(B,C,D) -> bswap if possible.
- bool OrWithFunnels = match(Op0, m_FShl(m_Value(), m_Value(), m_Value())) ||
- match(Op0, m_FShr(m_Value(), m_Value(), m_Value())) ||
- match(Op0, m_FShl(m_Value(), m_Value(), m_Value())) ||
- match(Op0, m_FShr(m_Value(), m_Value(), m_Value()));
+ // fshl(A,B,C) | D and A | fshl(B,C,D) -> bswap if possible.
+ // fshr(A,B,C) | D and A | fshr(B,C,D) -> bswap if possible.
+ bool OrWithFunnels = match(Op0, m_FShl(m_Value(), m_Value(), m_Value())) ||
+ match(Op0, m_FShr(m_Value(), m_Value(), m_Value())) ||
+ match(Op0, m_FShl(m_Value(), m_Value(), m_Value())) ||
+ match(Op0, m_FShr(m_Value(), m_Value(), m_Value()));
- // TODO: Do we need all these filtering checks or should we just rely on
- // recognizeBSwapOrBitReverseIdiom + collectBitParts to reject them quickly?
- if (!OrWithOrs && !OrWithShifts && !OrWithAnds && !OrWithFunnels)
+ // TODO: Do we need all these filtering checks or should we just rely on
+ // recognizeBSwapOrBitReverseIdiom + collectBitParts to reject them quickly?
+ if (!OrWithOrs && !OrWithShifts && !OrWithAnds && !OrWithFunnels)
return nullptr;
- SmallVector<Instruction *, 4> Insts;
- if (!recognizeBSwapOrBitReverseIdiom(&Or, MatchBSwaps, MatchBitReversals,
- Insts))
+ SmallVector<Instruction *, 4> Insts;
+ if (!recognizeBSwapOrBitReverseIdiom(&Or, MatchBSwaps, MatchBitReversals,
+ Insts))
return nullptr;
Instruction *LastInst = Insts.pop_back_val();
LastInst->removeFromParent();
@@ -2039,72 +2039,72 @@ Instruction *InstCombinerImpl::matchBSwapOrBitReverse(BinaryOperator &Or,
return LastInst;
}
-/// Match UB-safe variants of the funnel shift intrinsic.
-static Instruction *matchFunnelShift(Instruction &Or, InstCombinerImpl &IC) {
+/// Match UB-safe variants of the funnel shift intrinsic.
+static Instruction *matchFunnelShift(Instruction &Or, InstCombinerImpl &IC) {
// TODO: Can we reduce the code duplication between this and the related
// rotate matching code under visitSelect and visitTrunc?
unsigned Width = Or.getType()->getScalarSizeInBits();
- // First, find an or'd pair of opposite shifts:
- // or (lshr ShVal0, ShAmt0), (shl ShVal1, ShAmt1)
+ // First, find an or'd pair of opposite shifts:
+ // or (lshr ShVal0, ShAmt0), (shl ShVal1, ShAmt1)
BinaryOperator *Or0, *Or1;
if (!match(Or.getOperand(0), m_BinOp(Or0)) ||
!match(Or.getOperand(1), m_BinOp(Or1)))
return nullptr;
- Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
- if (!match(Or0, m_OneUse(m_LogicalShift(m_Value(ShVal0), m_Value(ShAmt0)))) ||
- !match(Or1, m_OneUse(m_LogicalShift(m_Value(ShVal1), m_Value(ShAmt1)))) ||
- Or0->getOpcode() == Or1->getOpcode())
- return nullptr;
-
- // Canonicalize to or(shl(ShVal0, ShAmt0), lshr(ShVal1, ShAmt1)).
- if (Or0->getOpcode() == BinaryOperator::LShr) {
- std::swap(Or0, Or1);
- std::swap(ShVal0, ShVal1);
- std::swap(ShAmt0, ShAmt1);
- }
- assert(Or0->getOpcode() == BinaryOperator::Shl &&
- Or1->getOpcode() == BinaryOperator::LShr &&
- "Illegal or(shift,shift) pair");
-
- // Match the shift amount operands for a funnel shift pattern. This always
- // matches a subtraction on the R operand.
- auto matchShiftAmount = [&](Value *L, Value *R, unsigned Width) -> Value * {
- // Check for constant shift amounts that sum to the bitwidth.
- const APInt *LI, *RI;
- if (match(L, m_APIntAllowUndef(LI)) && match(R, m_APIntAllowUndef(RI)))
- if (LI->ult(Width) && RI->ult(Width) && (*LI + *RI) == Width)
- return ConstantInt::get(L->getType(), *LI);
-
- Constant *LC, *RC;
- if (match(L, m_Constant(LC)) && match(R, m_Constant(RC)) &&
- match(L, m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, APInt(Width, Width))) &&
- match(R, m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, APInt(Width, Width))) &&
- match(ConstantExpr::getAdd(LC, RC), m_SpecificIntAllowUndef(Width)))
- return ConstantExpr::mergeUndefsWith(LC, RC);
-
- // (shl ShVal, X) | (lshr ShVal, (Width - x)) iff X < Width.
- // We limit this to X < Width in case the backend re-expands the intrinsic,
- // and has to reintroduce a shift modulo operation (InstCombine might remove
- // it after this fold). This still doesn't guarantee that the final codegen
- // will match this original pattern.
- if (match(R, m_OneUse(m_Sub(m_SpecificInt(Width), m_Specific(L))))) {
- KnownBits KnownL = IC.computeKnownBits(L, /*Depth*/ 0, &Or);
- return KnownL.getMaxValue().ult(Width) ? L : nullptr;
- }
-
- // For non-constant cases, the following patterns currently only work for
- // rotation patterns.
- // TODO: Add general funnel-shift compatible patterns.
- if (ShVal0 != ShVal1)
- return nullptr;
-
- // For non-constant cases we don't support non-pow2 shift masks.
- // TODO: Is it worth matching urem as well?
- if (!isPowerOf2_32(Width))
- return nullptr;
-
+ Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
+ if (!match(Or0, m_OneUse(m_LogicalShift(m_Value(ShVal0), m_Value(ShAmt0)))) ||
+ !match(Or1, m_OneUse(m_LogicalShift(m_Value(ShVal1), m_Value(ShAmt1)))) ||
+ Or0->getOpcode() == Or1->getOpcode())
+ return nullptr;
+
+ // Canonicalize to or(shl(ShVal0, ShAmt0), lshr(ShVal1, ShAmt1)).
+ if (Or0->getOpcode() == BinaryOperator::LShr) {
+ std::swap(Or0, Or1);
+ std::swap(ShVal0, ShVal1);
+ std::swap(ShAmt0, ShAmt1);
+ }
+ assert(Or0->getOpcode() == BinaryOperator::Shl &&
+ Or1->getOpcode() == BinaryOperator::LShr &&
+ "Illegal or(shift,shift) pair");
+
+ // Match the shift amount operands for a funnel shift pattern. This always
+ // matches a subtraction on the R operand.
+ auto matchShiftAmount = [&](Value *L, Value *R, unsigned Width) -> Value * {
+ // Check for constant shift amounts that sum to the bitwidth.
+ const APInt *LI, *RI;
+ if (match(L, m_APIntAllowUndef(LI)) && match(R, m_APIntAllowUndef(RI)))
+ if (LI->ult(Width) && RI->ult(Width) && (*LI + *RI) == Width)
+ return ConstantInt::get(L->getType(), *LI);
+
+ Constant *LC, *RC;
+ if (match(L, m_Constant(LC)) && match(R, m_Constant(RC)) &&
+ match(L, m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, APInt(Width, Width))) &&
+ match(R, m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, APInt(Width, Width))) &&
+ match(ConstantExpr::getAdd(LC, RC), m_SpecificIntAllowUndef(Width)))
+ return ConstantExpr::mergeUndefsWith(LC, RC);
+
+ // (shl ShVal, X) | (lshr ShVal, (Width - x)) iff X < Width.
+ // We limit this to X < Width in case the backend re-expands the intrinsic,
+ // and has to reintroduce a shift modulo operation (InstCombine might remove
+ // it after this fold). This still doesn't guarantee that the final codegen
+ // will match this original pattern.
+ if (match(R, m_OneUse(m_Sub(m_SpecificInt(Width), m_Specific(L))))) {
+ KnownBits KnownL = IC.computeKnownBits(L, /*Depth*/ 0, &Or);
+ return KnownL.getMaxValue().ult(Width) ? L : nullptr;
+ }
+
+ // For non-constant cases, the following patterns currently only work for
+ // rotation patterns.
+ // TODO: Add general funnel-shift compatible patterns.
+ if (ShVal0 != ShVal1)
+ return nullptr;
+
+ // For non-constant cases we don't support non-pow2 shift masks.
+ // TODO: Is it worth matching urem as well?
+ if (!isPowerOf2_32(Width))
+ return nullptr;
+
// The shift amount may be masked with negation:
// (shl ShVal, (X & (Width - 1))) | (lshr ShVal, ((-X) & (Width - 1)))
Value *X;
@@ -2120,25 +2120,25 @@ static Instruction *matchFunnelShift(Instruction &Or, InstCombinerImpl &IC) {
m_SpecificInt(Mask))))
return L;
- if (match(L, m_ZExt(m_And(m_Value(X), m_SpecificInt(Mask)))) &&
- match(R, m_ZExt(m_And(m_Neg(m_Specific(X)), m_SpecificInt(Mask)))))
- return L;
-
+ if (match(L, m_ZExt(m_And(m_Value(X), m_SpecificInt(Mask)))) &&
+ match(R, m_ZExt(m_And(m_Neg(m_Specific(X)), m_SpecificInt(Mask)))))
+ return L;
+
return nullptr;
};
Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, Width);
- bool IsFshl = true; // Sub on LSHR.
+ bool IsFshl = true; // Sub on LSHR.
if (!ShAmt) {
ShAmt = matchShiftAmount(ShAmt1, ShAmt0, Width);
- IsFshl = false; // Sub on SHL.
+ IsFshl = false; // Sub on SHL.
}
if (!ShAmt)
return nullptr;
Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
Function *F = Intrinsic::getDeclaration(Or.getModule(), IID, Or.getType());
- return IntrinsicInst::Create(F, {ShVal0, ShVal1, ShAmt});
+ return IntrinsicInst::Create(F, {ShVal0, ShVal1, ShAmt});
}
/// Attempt to combine or(zext(x),shl(zext(y),bw/2) concat packing patterns.
@@ -2196,7 +2196,7 @@ static Instruction *matchOrConcat(Instruction &Or,
/// If all elements of two constant vectors are 0/-1 and inverses, return true.
static bool areInverseVectorBitmasks(Constant *C1, Constant *C2) {
- unsigned NumElts = cast<FixedVectorType>(C1->getType())->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(C1->getType())->getNumElements();
for (unsigned i = 0; i != NumElts; ++i) {
Constant *EltC1 = C1->getAggregateElement(i);
Constant *EltC2 = C2->getAggregateElement(i);
@@ -2214,7 +2214,7 @@ static bool areInverseVectorBitmasks(Constant *C1, Constant *C2) {
/// We have an expression of the form (A & C) | (B & D). If A is a scalar or
/// vector composed of all-zeros or all-ones values and is the bitwise 'not' of
/// B, it can be used as the condition operand of a select instruction.
-Value *InstCombinerImpl::getSelectCondition(Value *A, Value *B) {
+Value *InstCombinerImpl::getSelectCondition(Value *A, Value *B) {
// Step 1: We may have peeked through bitcasts in the caller.
// Exit immediately if we don't have (vector) integer types.
Type *Ty = A->getType();
@@ -2271,8 +2271,8 @@ Value *InstCombinerImpl::getSelectCondition(Value *A, Value *B) {
/// We have an expression of the form (A & C) | (B & D). Try to simplify this
/// to "A' ? C : D", where A' is a boolean or vector of booleans.
-Value *InstCombinerImpl::matchSelectFromAndOr(Value *A, Value *C, Value *B,
- Value *D) {
+Value *InstCombinerImpl::matchSelectFromAndOr(Value *A, Value *C, Value *B,
+ Value *D) {
// The potential condition of the select may be bitcasted. In that case, look
// through its bitcast and the corresponding bitcast of the 'not' condition.
Type *OrigType = A->getType();
@@ -2292,8 +2292,8 @@ Value *InstCombinerImpl::matchSelectFromAndOr(Value *A, Value *C, Value *B,
}
/// Fold (icmp)|(icmp) if possible.
-Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
- BinaryOperator &Or) {
+Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
+ BinaryOperator &Or) {
const SimplifyQuery Q = SQ.getWithInstruction(&Or);
// Fold (iszero(A & K1) | iszero(A & K2)) -> (A & (K1 | K2)) != (K1 | K2)
@@ -2302,10 +2302,10 @@ Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
return V;
ICmpInst::Predicate PredL = LHS->getPredicate(), PredR = RHS->getPredicate();
- Value *LHS0 = LHS->getOperand(0), *RHS0 = RHS->getOperand(0);
- Value *LHS1 = LHS->getOperand(1), *RHS1 = RHS->getOperand(1);
- auto *LHSC = dyn_cast<ConstantInt>(LHS1);
- auto *RHSC = dyn_cast<ConstantInt>(RHS1);
+ Value *LHS0 = LHS->getOperand(0), *RHS0 = RHS->getOperand(0);
+ Value *LHS1 = LHS->getOperand(1), *RHS1 = RHS->getOperand(1);
+ auto *LHSC = dyn_cast<ConstantInt>(LHS1);
+ auto *RHSC = dyn_cast<ConstantInt>(RHS1);
// Fold (icmp ult/ule (A + C1), C3) | (icmp ult/ule (A + C2), C3)
// --> (icmp ult/ule ((A & ~(C1 ^ C2)) + max(C1, C2)), C3)
@@ -2322,15 +2322,15 @@ Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
LHSC->getType() == RHSC->getType() &&
LHSC->getValue() == (RHSC->getValue())) {
- Value *AddOpnd;
+ Value *AddOpnd;
ConstantInt *LAddC, *RAddC;
- if (match(LHS0, m_Add(m_Value(AddOpnd), m_ConstantInt(LAddC))) &&
- match(RHS0, m_Add(m_Specific(AddOpnd), m_ConstantInt(RAddC))) &&
+ if (match(LHS0, m_Add(m_Value(AddOpnd), m_ConstantInt(LAddC))) &&
+ match(RHS0, m_Add(m_Specific(AddOpnd), m_ConstantInt(RAddC))) &&
LAddC->getValue().ugt(LHSC->getValue()) &&
RAddC->getValue().ugt(LHSC->getValue())) {
APInt DiffC = LAddC->getValue() ^ RAddC->getValue();
- if (DiffC.isPowerOf2()) {
+ if (DiffC.isPowerOf2()) {
ConstantInt *MaxAddC = nullptr;
if (LAddC->getValue().ult(RAddC->getValue()))
MaxAddC = RAddC;
@@ -2350,7 +2350,7 @@ Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
RangeDiff.ugt(LHSC->getValue())) {
Value *MaskC = ConstantInt::get(LAddC->getType(), ~DiffC);
- Value *NewAnd = Builder.CreateAnd(AddOpnd, MaskC);
+ Value *NewAnd = Builder.CreateAnd(AddOpnd, MaskC);
Value *NewAdd = Builder.CreateAdd(NewAnd, MaxAddC);
return Builder.CreateICmp(LHS->getPredicate(), NewAdd, LHSC);
}
@@ -2360,12 +2360,12 @@ Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
// (icmp1 A, B) | (icmp2 A, B) --> (icmp3 A, B)
if (predicatesFoldable(PredL, PredR)) {
- if (LHS0 == RHS1 && LHS1 == RHS0)
+ if (LHS0 == RHS1 && LHS1 == RHS0)
LHS->swapOperands();
- if (LHS0 == RHS0 && LHS1 == RHS1) {
+ if (LHS0 == RHS0 && LHS1 == RHS1) {
unsigned Code = getICmpCode(LHS) | getICmpCode(RHS);
bool IsSigned = LHS->isSigned() || RHS->isSigned();
- return getNewICmpValue(Code, IsSigned, LHS0, LHS1, Builder);
+ return getNewICmpValue(Code, IsSigned, LHS0, LHS1, Builder);
}
}
@@ -2378,26 +2378,26 @@ Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
// (icmp eq B, 0) | (icmp ult A, B) -> (icmp ule A, B-1)
// (icmp eq B, 0) | (icmp ugt B, A) -> (icmp ule A, B-1)
Value *A = nullptr, *B = nullptr;
- if (PredL == ICmpInst::ICMP_EQ && match(LHS1, m_Zero())) {
+ if (PredL == ICmpInst::ICMP_EQ && match(LHS1, m_Zero())) {
B = LHS0;
- if (PredR == ICmpInst::ICMP_ULT && LHS0 == RHS1)
+ if (PredR == ICmpInst::ICMP_ULT && LHS0 == RHS1)
A = RHS0;
else if (PredR == ICmpInst::ICMP_UGT && LHS0 == RHS0)
- A = RHS1;
+ A = RHS1;
}
// (icmp ult A, B) | (icmp eq B, 0) -> (icmp ule A, B-1)
// (icmp ugt B, A) | (icmp eq B, 0) -> (icmp ule A, B-1)
- else if (PredR == ICmpInst::ICMP_EQ && match(RHS1, m_Zero())) {
+ else if (PredR == ICmpInst::ICMP_EQ && match(RHS1, m_Zero())) {
B = RHS0;
- if (PredL == ICmpInst::ICMP_ULT && RHS0 == LHS1)
+ if (PredL == ICmpInst::ICMP_ULT && RHS0 == LHS1)
A = LHS0;
- else if (PredL == ICmpInst::ICMP_UGT && RHS0 == LHS0)
- A = LHS1;
+ else if (PredL == ICmpInst::ICMP_UGT && RHS0 == LHS0)
+ A = LHS1;
}
- if (A && B && B->getType()->isIntOrIntVectorTy())
+ if (A && B && B->getType()->isIntOrIntVectorTy())
return Builder.CreateICmp(
ICmpInst::ICMP_UGE,
- Builder.CreateAdd(B, Constant::getAllOnesValue(B->getType())), A);
+ Builder.CreateAdd(B, Constant::getAllOnesValue(B->getType())), A);
}
if (Value *V = foldAndOrOfICmpsWithConstEq(LHS, RHS, Or, Builder, Q))
@@ -2426,17 +2426,17 @@ Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
foldUnsignedUnderflowCheck(RHS, LHS, /*IsAnd=*/false, Q, Builder))
return X;
- // (icmp ne A, 0) | (icmp ne B, 0) --> (icmp ne (A|B), 0)
- // TODO: Remove this when foldLogOpOfMaskedICmps can handle vectors.
- if (PredL == ICmpInst::ICMP_NE && match(LHS1, m_Zero()) &&
- PredR == ICmpInst::ICMP_NE && match(RHS1, m_Zero()) &&
- LHS0->getType()->isIntOrIntVectorTy() &&
- LHS0->getType() == RHS0->getType()) {
- Value *NewOr = Builder.CreateOr(LHS0, RHS0);
- return Builder.CreateICmp(PredL, NewOr,
- Constant::getNullValue(NewOr->getType()));
- }
-
+ // (icmp ne A, 0) | (icmp ne B, 0) --> (icmp ne (A|B), 0)
+ // TODO: Remove this when foldLogOpOfMaskedICmps can handle vectors.
+ if (PredL == ICmpInst::ICMP_NE && match(LHS1, m_Zero()) &&
+ PredR == ICmpInst::ICMP_NE && match(RHS1, m_Zero()) &&
+ LHS0->getType()->isIntOrIntVectorTy() &&
+ LHS0->getType() == RHS0->getType()) {
+ Value *NewOr = Builder.CreateOr(LHS0, RHS0);
+ return Builder.CreateICmp(PredL, NewOr,
+ Constant::getNullValue(NewOr->getType()));
+ }
+
// This only handles icmp of constants: (icmp1 A, C1) | (icmp2 B, C2).
if (!LHSC || !RHSC)
return nullptr;
@@ -2554,7 +2554,7 @@ Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
// FIXME: We use commutative matchers (m_c_*) for some, but not all, matches
// here. We should standardize that construct where it is needed or choose some
// other way to ensure that commutated variants of patterns are not missed.
-Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
+Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
if (Value *V = SimplifyOrInst(I.getOperand(0), I.getOperand(1),
SQ.getWithInstruction(&I)))
return replaceInstUsesWith(I, V);
@@ -2584,12 +2584,12 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
if (Instruction *FoldedLogic = foldBinOpIntoSelectOrPhi(I))
return FoldedLogic;
- if (Instruction *BSwap = matchBSwapOrBitReverse(I, /*MatchBSwaps*/ true,
- /*MatchBitReversals*/ false))
+ if (Instruction *BSwap = matchBSwapOrBitReverse(I, /*MatchBSwaps*/ true,
+ /*MatchBitReversals*/ false))
return BSwap;
- if (Instruction *Funnel = matchFunnelShift(I, *this))
- return Funnel;
+ if (Instruction *Funnel = matchFunnelShift(I, *this))
+ return Funnel;
if (Instruction *Concat = matchOrConcat(I, Builder))
return replaceInstUsesWith(I, Concat);
@@ -2609,9 +2609,9 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
Value *A, *B, *C, *D;
if (match(Op0, m_And(m_Value(A), m_Value(C))) &&
match(Op1, m_And(m_Value(B), m_Value(D)))) {
- // (A & C1)|(B & C2)
- ConstantInt *C1, *C2;
- if (match(C, m_ConstantInt(C1)) && match(D, m_ConstantInt(C2))) {
+ // (A & C1)|(B & C2)
+ ConstantInt *C1, *C2;
+ if (match(C, m_ConstantInt(C1)) && match(D, m_ConstantInt(C2))) {
Value *V1 = nullptr, *V2 = nullptr;
if ((C1->getValue() & C2->getValue()).isNullValue()) {
// ((V | N) & C1) | (V & C2) --> (V|N) & (C1|C2)
@@ -2802,7 +2802,7 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
// ORs in the hopes that we'll be able to simplify it this way.
// (X|C) | V --> (X|V) | C
ConstantInt *CI;
- if (Op0->hasOneUse() && !match(Op1, m_ConstantInt()) &&
+ if (Op0->hasOneUse() && !match(Op1, m_ConstantInt()) &&
match(Op0, m_Or(m_Value(A), m_ConstantInt(CI)))) {
Value *Inner = Builder.CreateOr(A, Op1);
Inner->takeName(Op0);
@@ -2823,17 +2823,17 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
}
}
- // or(ashr(subNSW(Y, X), ScalarSizeInBits(Y) - 1), X) --> X s> Y ? -1 : X.
+ // or(ashr(subNSW(Y, X), ScalarSizeInBits(Y) - 1), X) --> X s> Y ? -1 : X.
{
Value *X, *Y;
Type *Ty = I.getType();
- if (match(&I, m_c_Or(m_OneUse(m_AShr(
- m_NSWSub(m_Value(Y), m_Value(X)),
- m_SpecificInt(Ty->getScalarSizeInBits() - 1))),
- m_Deferred(X)))) {
+ if (match(&I, m_c_Or(m_OneUse(m_AShr(
+ m_NSWSub(m_Value(Y), m_Value(X)),
+ m_SpecificInt(Ty->getScalarSizeInBits() - 1))),
+ m_Deferred(X)))) {
Value *NewICmpInst = Builder.CreateICmpSGT(X, Y);
- Value *AllOnes = ConstantInt::getAllOnesValue(Ty);
- return SelectInst::Create(NewICmpInst, AllOnes, X);
+ Value *AllOnes = ConstantInt::getAllOnesValue(Ty);
+ return SelectInst::Create(NewICmpInst, AllOnes, X);
}
}
@@ -2867,10 +2867,10 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
}
}
- // (~x) | y --> ~(x & (~y)) iff that gets rid of inversions
- if (sinkNotIntoOtherHandOfAndOrOr(I))
- return &I;
-
+ // (~x) | y --> ~(x & (~y)) iff that gets rid of inversions
+ if (sinkNotIntoOtherHandOfAndOrOr(I))
+ return &I;
+
return nullptr;
}
@@ -2927,8 +2927,8 @@ static Instruction *foldXorToXor(BinaryOperator &I,
return nullptr;
}
-Value *InstCombinerImpl::foldXorOfICmps(ICmpInst *LHS, ICmpInst *RHS,
- BinaryOperator &I) {
+Value *InstCombinerImpl::foldXorOfICmps(ICmpInst *LHS, ICmpInst *RHS,
+ BinaryOperator &I) {
assert(I.getOpcode() == Instruction::Xor && I.getOperand(0) == LHS &&
I.getOperand(1) == RHS && "Should be 'xor' with these operands");
@@ -3086,9 +3086,9 @@ static Instruction *sinkNotIntoXor(BinaryOperator &I,
return nullptr;
// We only want to do the transform if it is free to do.
- if (InstCombiner::isFreeToInvert(X, X->hasOneUse())) {
+ if (InstCombiner::isFreeToInvert(X, X->hasOneUse())) {
// Ok, good.
- } else if (InstCombiner::isFreeToInvert(Y, Y->hasOneUse())) {
+ } else if (InstCombiner::isFreeToInvert(Y, Y->hasOneUse())) {
std::swap(X, Y);
} else
return nullptr;
@@ -3097,52 +3097,52 @@ static Instruction *sinkNotIntoXor(BinaryOperator &I,
return BinaryOperator::CreateXor(NotX, Y, I.getName() + ".demorgan");
}
-// Transform
-// z = (~x) &/| y
-// into:
-// z = ~(x |/& (~y))
-// iff y is free to invert and all uses of z can be freely updated.
-bool InstCombinerImpl::sinkNotIntoOtherHandOfAndOrOr(BinaryOperator &I) {
- Instruction::BinaryOps NewOpc;
- switch (I.getOpcode()) {
- case Instruction::And:
- NewOpc = Instruction::Or;
- break;
- case Instruction::Or:
- NewOpc = Instruction::And;
- break;
- default:
- return false;
- };
-
- Value *X, *Y;
- if (!match(&I, m_c_BinOp(m_Not(m_Value(X)), m_Value(Y))))
- return false;
-
- // Will we be able to fold the `not` into Y eventually?
- if (!InstCombiner::isFreeToInvert(Y, Y->hasOneUse()))
- return false;
-
- // And can our users be adapted?
- if (!InstCombiner::canFreelyInvertAllUsersOf(&I, /*IgnoredUser=*/nullptr))
- return false;
-
- Value *NotY = Builder.CreateNot(Y, Y->getName() + ".not");
- Value *NewBinOp =
- BinaryOperator::Create(NewOpc, X, NotY, I.getName() + ".not");
- Builder.Insert(NewBinOp);
- replaceInstUsesWith(I, NewBinOp);
- // We can not just create an outer `not`, it will most likely be immediately
- // folded back, reconstructing our initial pattern, and causing an
- // infinite combine loop, so immediately manually fold it away.
- freelyInvertAllUsersOf(NewBinOp);
- return true;
-}
-
+// Transform
+// z = (~x) &/| y
+// into:
+// z = ~(x |/& (~y))
+// iff y is free to invert and all uses of z can be freely updated.
+bool InstCombinerImpl::sinkNotIntoOtherHandOfAndOrOr(BinaryOperator &I) {
+ Instruction::BinaryOps NewOpc;
+ switch (I.getOpcode()) {
+ case Instruction::And:
+ NewOpc = Instruction::Or;
+ break;
+ case Instruction::Or:
+ NewOpc = Instruction::And;
+ break;
+ default:
+ return false;
+ };
+
+ Value *X, *Y;
+ if (!match(&I, m_c_BinOp(m_Not(m_Value(X)), m_Value(Y))))
+ return false;
+
+ // Will we be able to fold the `not` into Y eventually?
+ if (!InstCombiner::isFreeToInvert(Y, Y->hasOneUse()))
+ return false;
+
+ // And can our users be adapted?
+ if (!InstCombiner::canFreelyInvertAllUsersOf(&I, /*IgnoredUser=*/nullptr))
+ return false;
+
+ Value *NotY = Builder.CreateNot(Y, Y->getName() + ".not");
+ Value *NewBinOp =
+ BinaryOperator::Create(NewOpc, X, NotY, I.getName() + ".not");
+ Builder.Insert(NewBinOp);
+ replaceInstUsesWith(I, NewBinOp);
+ // We can not just create an outer `not`, it will most likely be immediately
+ // folded back, reconstructing our initial pattern, and causing an
+ // infinite combine loop, so immediately manually fold it away.
+ freelyInvertAllUsersOf(NewBinOp);
+ return true;
+}
+
// FIXME: We use commutative matchers (m_c_*) for some, but not all, matches
// here. We should standardize that construct where it is needed or choose some
// other way to ensure that commutated variants of patterns are not missed.
-Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
+Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
if (Value *V = SimplifyXorInst(I.getOperand(0), I.getOperand(1),
SQ.getWithInstruction(&I)))
return replaceInstUsesWith(I, V);
@@ -3169,7 +3169,7 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
return replaceInstUsesWith(I, V);
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
- Type *Ty = I.getType();
+ Type *Ty = I.getType();
// Fold (X & M) ^ (Y & ~M) -> (X & M) | (Y & ~M)
// This it a special case in haveNoCommonBitsSet, but the computeKnownBits
@@ -3236,7 +3236,7 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
match(C, m_Negative())) {
// We matched a negative constant, so propagating undef is unsafe.
// Clamp undef elements to -1.
- Type *EltTy = Ty->getScalarType();
+ Type *EltTy = Ty->getScalarType();
C = Constant::replaceUndefsWith(C, ConstantInt::getAllOnesValue(EltTy));
return BinaryOperator::CreateLShr(ConstantExpr::getNot(C), Y);
}
@@ -3246,25 +3246,25 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
match(C, m_NonNegative())) {
// We matched a non-negative constant, so propagating undef is unsafe.
// Clamp undef elements to 0.
- Type *EltTy = Ty->getScalarType();
+ Type *EltTy = Ty->getScalarType();
C = Constant::replaceUndefsWith(C, ConstantInt::getNullValue(EltTy));
return BinaryOperator::CreateAShr(ConstantExpr::getNot(C), Y);
}
- // ~(X + C) --> ~C - X
- if (match(NotVal, m_c_Add(m_Value(X), m_ImmConstant(C))))
- return BinaryOperator::CreateSub(ConstantExpr::getNot(C), X);
-
- // ~(X - Y) --> ~X + Y
- // FIXME: is it really beneficial to sink the `not` here?
- if (match(NotVal, m_Sub(m_Value(X), m_Value(Y))))
- if (isa<Constant>(X) || NotVal->hasOneUse())
- return BinaryOperator::CreateAdd(Builder.CreateNot(X), Y);
-
- // ~(~X + Y) --> X - Y
- if (match(NotVal, m_c_Add(m_Not(m_Value(X)), m_Value(Y))))
- return BinaryOperator::CreateWithCopiedFlags(Instruction::Sub, X, Y,
- NotVal);
+ // ~(X + C) --> ~C - X
+ if (match(NotVal, m_c_Add(m_Value(X), m_ImmConstant(C))))
+ return BinaryOperator::CreateSub(ConstantExpr::getNot(C), X);
+
+ // ~(X - Y) --> ~X + Y
+ // FIXME: is it really beneficial to sink the `not` here?
+ if (match(NotVal, m_Sub(m_Value(X), m_Value(Y))))
+ if (isa<Constant>(X) || NotVal->hasOneUse())
+ return BinaryOperator::CreateAdd(Builder.CreateNot(X), Y);
+
+ // ~(~X + Y) --> X - Y
+ if (match(NotVal, m_c_Add(m_Not(m_Value(X)), m_Value(Y))))
+ return BinaryOperator::CreateWithCopiedFlags(Instruction::Sub, X, Y,
+ NotVal);
}
// Use DeMorgan and reassociation to eliminate a 'not' op.
@@ -3295,56 +3295,56 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
if (match(Op1, m_APInt(RHSC))) {
Value *X;
const APInt *C;
- // (C - X) ^ signmaskC --> (C + signmaskC) - X
- if (RHSC->isSignMask() && match(Op0, m_Sub(m_APInt(C), m_Value(X))))
- return BinaryOperator::CreateSub(ConstantInt::get(Ty, *C + *RHSC), X);
-
- // (X + C) ^ signmaskC --> X + (C + signmaskC)
- if (RHSC->isSignMask() && match(Op0, m_Add(m_Value(X), m_APInt(C))))
- return BinaryOperator::CreateAdd(X, ConstantInt::get(Ty, *C + *RHSC));
-
- // (X | C) ^ RHSC --> X ^ (C ^ RHSC) iff X & C == 0
+ // (C - X) ^ signmaskC --> (C + signmaskC) - X
+ if (RHSC->isSignMask() && match(Op0, m_Sub(m_APInt(C), m_Value(X))))
+ return BinaryOperator::CreateSub(ConstantInt::get(Ty, *C + *RHSC), X);
+
+ // (X + C) ^ signmaskC --> X + (C + signmaskC)
+ if (RHSC->isSignMask() && match(Op0, m_Add(m_Value(X), m_APInt(C))))
+ return BinaryOperator::CreateAdd(X, ConstantInt::get(Ty, *C + *RHSC));
+
+ // (X | C) ^ RHSC --> X ^ (C ^ RHSC) iff X & C == 0
if (match(Op0, m_Or(m_Value(X), m_APInt(C))) &&
- MaskedValueIsZero(X, *C, 0, &I))
- return BinaryOperator::CreateXor(X, ConstantInt::get(Ty, *C ^ *RHSC));
-
- // If RHSC is inverting the remaining bits of shifted X,
- // canonicalize to a 'not' before the shift to help SCEV and codegen:
- // (X << C) ^ RHSC --> ~X << C
- if (match(Op0, m_OneUse(m_Shl(m_Value(X), m_APInt(C)))) &&
- *RHSC == APInt::getAllOnesValue(Ty->getScalarSizeInBits()).shl(*C)) {
- Value *NotX = Builder.CreateNot(X);
- return BinaryOperator::CreateShl(NotX, ConstantInt::get(Ty, *C));
+ MaskedValueIsZero(X, *C, 0, &I))
+ return BinaryOperator::CreateXor(X, ConstantInt::get(Ty, *C ^ *RHSC));
+
+ // If RHSC is inverting the remaining bits of shifted X,
+ // canonicalize to a 'not' before the shift to help SCEV and codegen:
+ // (X << C) ^ RHSC --> ~X << C
+ if (match(Op0, m_OneUse(m_Shl(m_Value(X), m_APInt(C)))) &&
+ *RHSC == APInt::getAllOnesValue(Ty->getScalarSizeInBits()).shl(*C)) {
+ Value *NotX = Builder.CreateNot(X);
+ return BinaryOperator::CreateShl(NotX, ConstantInt::get(Ty, *C));
}
- // (X >>u C) ^ RHSC --> ~X >>u C
- if (match(Op0, m_OneUse(m_LShr(m_Value(X), m_APInt(C)))) &&
- *RHSC == APInt::getAllOnesValue(Ty->getScalarSizeInBits()).lshr(*C)) {
- Value *NotX = Builder.CreateNot(X);
- return BinaryOperator::CreateLShr(NotX, ConstantInt::get(Ty, *C));
- }
- // TODO: We could handle 'ashr' here as well. That would be matching
- // a 'not' op and moving it before the shift. Doing that requires
- // preventing the inverse fold in canShiftBinOpWithConstantRHS().
+ // (X >>u C) ^ RHSC --> ~X >>u C
+ if (match(Op0, m_OneUse(m_LShr(m_Value(X), m_APInt(C)))) &&
+ *RHSC == APInt::getAllOnesValue(Ty->getScalarSizeInBits()).lshr(*C)) {
+ Value *NotX = Builder.CreateNot(X);
+ return BinaryOperator::CreateLShr(NotX, ConstantInt::get(Ty, *C));
+ }
+ // TODO: We could handle 'ashr' here as well. That would be matching
+ // a 'not' op and moving it before the shift. Doing that requires
+ // preventing the inverse fold in canShiftBinOpWithConstantRHS().
}
}
- // FIXME: This should not be limited to scalar (pull into APInt match above).
- {
- Value *X;
- ConstantInt *C1, *C2, *C3;
- // ((X^C1) >> C2) ^ C3 -> (X>>C2) ^ ((C1>>C2)^C3)
- if (match(Op1, m_ConstantInt(C3)) &&
- match(Op0, m_LShr(m_Xor(m_Value(X), m_ConstantInt(C1)),
- m_ConstantInt(C2))) &&
- Op0->hasOneUse()) {
- // fold (C1 >> C2) ^ C3
- APInt FoldConst = C1->getValue().lshr(C2->getValue());
- FoldConst ^= C3->getValue();
- // Prepare the two operands.
- auto *Opnd0 = cast<Instruction>(Builder.CreateLShr(X, C2));
- Opnd0->takeName(cast<Instruction>(Op0));
- Opnd0->setDebugLoc(I.getDebugLoc());
- return BinaryOperator::CreateXor(Opnd0, ConstantInt::get(Ty, FoldConst));
+ // FIXME: This should not be limited to scalar (pull into APInt match above).
+ {
+ Value *X;
+ ConstantInt *C1, *C2, *C3;
+ // ((X^C1) >> C2) ^ C3 -> (X>>C2) ^ ((C1>>C2)^C3)
+ if (match(Op1, m_ConstantInt(C3)) &&
+ match(Op0, m_LShr(m_Xor(m_Value(X), m_ConstantInt(C1)),
+ m_ConstantInt(C2))) &&
+ Op0->hasOneUse()) {
+ // fold (C1 >> C2) ^ C3
+ APInt FoldConst = C1->getValue().lshr(C2->getValue());
+ FoldConst ^= C3->getValue();
+ // Prepare the two operands.
+ auto *Opnd0 = cast<Instruction>(Builder.CreateLShr(X, C2));
+ Opnd0->takeName(cast<Instruction>(Op0));
+ Opnd0->setDebugLoc(I.getDebugLoc());
+ return BinaryOperator::CreateXor(Opnd0, ConstantInt::get(Ty, FoldConst));
}
}
@@ -3401,25 +3401,25 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
match(Op1, m_Not(m_Specific(A))))
return BinaryOperator::CreateNot(Builder.CreateAnd(A, B));
- // (~A & B) ^ A --> A | B -- There are 4 commuted variants.
- if (match(&I, m_c_Xor(m_c_And(m_Not(m_Value(A)), m_Value(B)), m_Deferred(A))))
- return BinaryOperator::CreateOr(A, B);
-
- // (A | B) ^ (A | C) --> (B ^ C) & ~A -- There are 4 commuted variants.
- // TODO: Loosen one-use restriction if common operand is a constant.
- Value *D;
- if (match(Op0, m_OneUse(m_Or(m_Value(A), m_Value(B)))) &&
- match(Op1, m_OneUse(m_Or(m_Value(C), m_Value(D))))) {
- if (B == C || B == D)
- std::swap(A, B);
- if (A == C)
- std::swap(C, D);
- if (A == D) {
- Value *NotA = Builder.CreateNot(A);
- return BinaryOperator::CreateAnd(Builder.CreateXor(B, C), NotA);
- }
- }
-
+ // (~A & B) ^ A --> A | B -- There are 4 commuted variants.
+ if (match(&I, m_c_Xor(m_c_And(m_Not(m_Value(A)), m_Value(B)), m_Deferred(A))))
+ return BinaryOperator::CreateOr(A, B);
+
+ // (A | B) ^ (A | C) --> (B ^ C) & ~A -- There are 4 commuted variants.
+ // TODO: Loosen one-use restriction if common operand is a constant.
+ Value *D;
+ if (match(Op0, m_OneUse(m_Or(m_Value(A), m_Value(B)))) &&
+ match(Op1, m_OneUse(m_Or(m_Value(C), m_Value(D))))) {
+ if (B == C || B == D)
+ std::swap(A, B);
+ if (A == C)
+ std::swap(C, D);
+ if (A == D) {
+ Value *NotA = Builder.CreateNot(A);
+ return BinaryOperator::CreateAnd(Builder.CreateXor(B, C), NotA);
+ }
+ }
+
if (auto *LHS = dyn_cast<ICmpInst>(I.getOperand(0)))
if (auto *RHS = dyn_cast<ICmpInst>(I.getOperand(1)))
if (Value *V = foldXorOfICmps(LHS, RHS, I))
@@ -3495,30 +3495,30 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
}
}
- // Pull 'not' into operands of select if both operands are one-use compares
- // or one is one-use compare and the other one is a constant.
+ // Pull 'not' into operands of select if both operands are one-use compares
+ // or one is one-use compare and the other one is a constant.
// Inverting the predicates eliminates the 'not' operation.
// Example:
- // not (select ?, (cmp TPred, ?, ?), (cmp FPred, ?, ?) -->
+ // not (select ?, (cmp TPred, ?, ?), (cmp FPred, ?, ?) -->
// select ?, (cmp InvTPred, ?, ?), (cmp InvFPred, ?, ?)
- // not (select ?, (cmp TPred, ?, ?), true -->
- // select ?, (cmp InvTPred, ?, ?), false
+ // not (select ?, (cmp TPred, ?, ?), true -->
+ // select ?, (cmp InvTPred, ?, ?), false
if (auto *Sel = dyn_cast<SelectInst>(Op0)) {
- Value *TV = Sel->getTrueValue();
- Value *FV = Sel->getFalseValue();
- auto *CmpT = dyn_cast<CmpInst>(TV);
- auto *CmpF = dyn_cast<CmpInst>(FV);
- bool InvertibleT = (CmpT && CmpT->hasOneUse()) || isa<Constant>(TV);
- bool InvertibleF = (CmpF && CmpF->hasOneUse()) || isa<Constant>(FV);
- if (InvertibleT && InvertibleF) {
- if (CmpT)
- CmpT->setPredicate(CmpT->getInversePredicate());
- else
- Sel->setTrueValue(ConstantExpr::getNot(cast<Constant>(TV)));
- if (CmpF)
- CmpF->setPredicate(CmpF->getInversePredicate());
- else
- Sel->setFalseValue(ConstantExpr::getNot(cast<Constant>(FV)));
+ Value *TV = Sel->getTrueValue();
+ Value *FV = Sel->getFalseValue();
+ auto *CmpT = dyn_cast<CmpInst>(TV);
+ auto *CmpF = dyn_cast<CmpInst>(FV);
+ bool InvertibleT = (CmpT && CmpT->hasOneUse()) || isa<Constant>(TV);
+ bool InvertibleF = (CmpF && CmpF->hasOneUse()) || isa<Constant>(FV);
+ if (InvertibleT && InvertibleF) {
+ if (CmpT)
+ CmpT->setPredicate(CmpT->getInversePredicate());
+ else
+ Sel->setTrueValue(ConstantExpr::getNot(cast<Constant>(TV)));
+ if (CmpF)
+ CmpF->setPredicate(CmpF->getInversePredicate());
+ else
+ Sel->setFalseValue(ConstantExpr::getNot(cast<Constant>(FV)));
return replaceInstUsesWith(I, Sel);
}
}
@@ -3527,15 +3527,15 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
if (Instruction *NewXor = sinkNotIntoXor(I, Builder))
return NewXor;
- // Otherwise, if all else failed, try to hoist the xor-by-constant:
- // (X ^ C) ^ Y --> (X ^ Y) ^ C
- // Just like we do in other places, we completely avoid the fold
- // for constantexprs, at least to avoid endless combine loop.
- if (match(&I, m_c_Xor(m_OneUse(m_Xor(m_CombineAnd(m_Value(X),
- m_Unless(m_ConstantExpr())),
- m_ImmConstant(C1))),
- m_Value(Y))))
- return BinaryOperator::CreateXor(Builder.CreateXor(X, Y), C1);
-
+ // Otherwise, if all else failed, try to hoist the xor-by-constant:
+ // (X ^ C) ^ Y --> (X ^ Y) ^ C
+ // Just like we do in other places, we completely avoid the fold
+ // for constantexprs, at least to avoid endless combine loop.
+ if (match(&I, m_c_Xor(m_OneUse(m_Xor(m_CombineAnd(m_Value(X),
+ m_Unless(m_ConstantExpr())),
+ m_ImmConstant(C1))),
+ m_Value(Y))))
+ return BinaryOperator::CreateXor(Builder.CreateXor(X, Y), C1);
+
return nullptr;
}
diff --git a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp
index 494cb04049..495493aab4 100644
--- a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp
@@ -9,10 +9,10 @@
// This file implements the visit functions for atomic rmw instructions.
//
//===----------------------------------------------------------------------===//
-
+
#include "InstCombineInternal.h"
#include "llvm/IR/Instructions.h"
-#include "llvm/Transforms/InstCombine/InstCombiner.h"
+#include "llvm/Transforms/InstCombine/InstCombiner.h"
using namespace llvm;
@@ -32,7 +32,7 @@ bool isIdempotentRMW(AtomicRMWInst& RMWI) {
default:
return false;
};
-
+
auto C = dyn_cast<ConstantInt>(RMWI.getValOperand());
if(!C)
return false;
@@ -93,13 +93,13 @@ bool isSaturating(AtomicRMWInst& RMWI) {
return C->isMaxValue(false);
};
}
-} // namespace
+} // namespace
-Instruction *InstCombinerImpl::visitAtomicRMWInst(AtomicRMWInst &RMWI) {
+Instruction *InstCombinerImpl::visitAtomicRMWInst(AtomicRMWInst &RMWI) {
// Volatile RMWs perform a load and a store, we cannot replace this by just a
// load or just a store. We chose not to canonicalize out of general paranoia
- // about user expectations around volatile.
+ // about user expectations around volatile.
if (RMWI.isVolatile())
return nullptr;
@@ -117,7 +117,7 @@ Instruction *InstCombinerImpl::visitAtomicRMWInst(AtomicRMWInst &RMWI) {
"AtomicRMWs don't make sense with Unordered or NotAtomic");
// Any atomicrmw xchg with no uses can be converted to a atomic store if the
- // ordering is compatible.
+ // ordering is compatible.
if (RMWI.getOperation() == AtomicRMWInst::Xchg &&
RMWI.use_empty()) {
if (Ordering != AtomicOrdering::Release &&
@@ -129,14 +129,14 @@ Instruction *InstCombinerImpl::visitAtomicRMWInst(AtomicRMWInst &RMWI) {
SI->setAlignment(DL.getABITypeAlign(RMWI.getType()));
return eraseInstFromFunction(RMWI);
}
-
+
if (!isIdempotentRMW(RMWI))
return nullptr;
// We chose to canonicalize all idempotent operations to an single
// operation code and constant. This makes it easier for the rest of the
// optimizer to match easily. The choices of or w/0 and fadd w/-0.0 are
- // arbitrary.
+ // arbitrary.
if (RMWI.getType()->isIntegerTy() &&
RMWI.getOperation() != AtomicRMWInst::Or) {
RMWI.setOperation(AtomicRMWInst::Or);
@@ -151,7 +151,7 @@ Instruction *InstCombinerImpl::visitAtomicRMWInst(AtomicRMWInst &RMWI) {
if (Ordering != AtomicOrdering::Acquire &&
Ordering != AtomicOrdering::Monotonic)
return nullptr;
-
+
LoadInst *Load = new LoadInst(RMWI.getType(), RMWI.getPointerOperand(), "",
false, DL.getABITypeAlign(RMWI.getType()),
Ordering, RMWI.getSyncScopeID());
diff --git a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCalls.cpp b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCalls.cpp
index a50dc72c72..5482b944e3 100644
--- a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -28,7 +28,7 @@
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/MemoryBuiltins.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/Attributes.h"
@@ -66,7 +66,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/InstCombine/InstCombineWorklist.h"
-#include "llvm/Transforms/InstCombine/InstCombiner.h"
+#include "llvm/Transforms/InstCombine/InstCombiner.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/SimplifyLibCalls.h"
#include <algorithm>
@@ -99,7 +99,7 @@ static Type *getPromotedType(Type *Ty) {
return Ty;
}
-Instruction *InstCombinerImpl::SimplifyAnyMemTransfer(AnyMemTransferInst *MI) {
+Instruction *InstCombinerImpl::SimplifyAnyMemTransfer(AnyMemTransferInst *MI) {
Align DstAlign = getKnownAlignment(MI->getRawDest(), DL, MI, &AC, &DT);
MaybeAlign CopyDstAlign = MI->getDestAlign();
if (!CopyDstAlign || *CopyDstAlign < DstAlign) {
@@ -214,7 +214,7 @@ Instruction *InstCombinerImpl::SimplifyAnyMemTransfer(AnyMemTransferInst *MI) {
return MI;
}
-Instruction *InstCombinerImpl::SimplifyAnyMemSet(AnyMemSetInst *MI) {
+Instruction *InstCombinerImpl::SimplifyAnyMemSet(AnyMemSetInst *MI) {
const Align KnownAlignment =
getKnownAlignment(MI->getDest(), DL, MI, &AC, &DT);
MaybeAlign MemSetAlign = MI->getDestAlign();
@@ -276,7 +276,7 @@ Instruction *InstCombinerImpl::SimplifyAnyMemSet(AnyMemSetInst *MI) {
// TODO, Obvious Missing Transforms:
// * Narrow width by halfs excluding zero/undef lanes
-Value *InstCombinerImpl::simplifyMaskedLoad(IntrinsicInst &II) {
+Value *InstCombinerImpl::simplifyMaskedLoad(IntrinsicInst &II) {
Value *LoadPtr = II.getArgOperand(0);
const Align Alignment =
cast<ConstantInt>(II.getArgOperand(1))->getAlignValue();
@@ -289,8 +289,8 @@ Value *InstCombinerImpl::simplifyMaskedLoad(IntrinsicInst &II) {
// If we can unconditionally load from this address, replace with a
// load/select idiom. TODO: use DT for context sensitive query
- if (isDereferenceablePointer(LoadPtr, II.getType(),
- II.getModule()->getDataLayout(), &II, nullptr)) {
+ if (isDereferenceablePointer(LoadPtr, II.getType(),
+ II.getModule()->getDataLayout(), &II, nullptr)) {
Value *LI = Builder.CreateAlignedLoad(II.getType(), LoadPtr, Alignment,
"unmaskedload");
return Builder.CreateSelect(II.getArgOperand(2), LI, II.getArgOperand(3));
@@ -302,7 +302,7 @@ Value *InstCombinerImpl::simplifyMaskedLoad(IntrinsicInst &II) {
// TODO, Obvious Missing Transforms:
// * Single constant active lane -> store
// * Narrow width by halfs excluding zero/undef lanes
-Instruction *InstCombinerImpl::simplifyMaskedStore(IntrinsicInst &II) {
+Instruction *InstCombinerImpl::simplifyMaskedStore(IntrinsicInst &II) {
auto *ConstMask = dyn_cast<Constant>(II.getArgOperand(3));
if (!ConstMask)
return nullptr;
@@ -318,14 +318,14 @@ Instruction *InstCombinerImpl::simplifyMaskedStore(IntrinsicInst &II) {
return new StoreInst(II.getArgOperand(0), StorePtr, false, Alignment);
}
- if (isa<ScalableVectorType>(ConstMask->getType()))
- return nullptr;
-
+ if (isa<ScalableVectorType>(ConstMask->getType()))
+ return nullptr;
+
// Use masked off lanes to simplify operands via SimplifyDemandedVectorElts
APInt DemandedElts = possiblyDemandedEltsInMask(ConstMask);
APInt UndefElts(DemandedElts.getBitWidth(), 0);
- if (Value *V =
- SimplifyDemandedVectorElts(II.getOperand(0), DemandedElts, UndefElts))
+ if (Value *V =
+ SimplifyDemandedVectorElts(II.getOperand(0), DemandedElts, UndefElts))
return replaceOperand(II, 0, V);
return nullptr;
@@ -338,7 +338,7 @@ Instruction *InstCombinerImpl::simplifyMaskedStore(IntrinsicInst &II) {
// * Narrow width by halfs excluding zero/undef lanes
// * Vector splat address w/known mask -> scalar load
// * Vector incrementing address -> vector masked load
-Instruction *InstCombinerImpl::simplifyMaskedGather(IntrinsicInst &II) {
+Instruction *InstCombinerImpl::simplifyMaskedGather(IntrinsicInst &II) {
return nullptr;
}
@@ -348,7 +348,7 @@ Instruction *InstCombinerImpl::simplifyMaskedGather(IntrinsicInst &II) {
// * Narrow store width by halfs excluding zero/undef lanes
// * Vector splat address w/known mask -> scalar store
// * Vector incrementing address -> vector masked store
-Instruction *InstCombinerImpl::simplifyMaskedScatter(IntrinsicInst &II) {
+Instruction *InstCombinerImpl::simplifyMaskedScatter(IntrinsicInst &II) {
auto *ConstMask = dyn_cast<Constant>(II.getArgOperand(3));
if (!ConstMask)
return nullptr;
@@ -357,17 +357,17 @@ Instruction *InstCombinerImpl::simplifyMaskedScatter(IntrinsicInst &II) {
if (ConstMask->isNullValue())
return eraseInstFromFunction(II);
- if (isa<ScalableVectorType>(ConstMask->getType()))
- return nullptr;
-
+ if (isa<ScalableVectorType>(ConstMask->getType()))
+ return nullptr;
+
// Use masked off lanes to simplify operands via SimplifyDemandedVectorElts
APInt DemandedElts = possiblyDemandedEltsInMask(ConstMask);
APInt UndefElts(DemandedElts.getBitWidth(), 0);
- if (Value *V =
- SimplifyDemandedVectorElts(II.getOperand(0), DemandedElts, UndefElts))
+ if (Value *V =
+ SimplifyDemandedVectorElts(II.getOperand(0), DemandedElts, UndefElts))
return replaceOperand(II, 0, V);
- if (Value *V =
- SimplifyDemandedVectorElts(II.getOperand(1), DemandedElts, UndefElts))
+ if (Value *V =
+ SimplifyDemandedVectorElts(II.getOperand(1), DemandedElts, UndefElts))
return replaceOperand(II, 1, V);
return nullptr;
@@ -382,7 +382,7 @@ Instruction *InstCombinerImpl::simplifyMaskedScatter(IntrinsicInst &II) {
/// This is legal because it preserves the most recent information about
/// the presence or absence of invariant.group.
static Instruction *simplifyInvariantGroupIntrinsic(IntrinsicInst &II,
- InstCombinerImpl &IC) {
+ InstCombinerImpl &IC) {
auto *Arg = II.getArgOperand(0);
auto *StrippedArg = Arg->stripPointerCasts();
auto *StrippedInvariantGroupsArg = Arg->stripPointerCastsAndInvariantGroups();
@@ -407,7 +407,7 @@ static Instruction *simplifyInvariantGroupIntrinsic(IntrinsicInst &II,
return cast<Instruction>(Result);
}
-static Instruction *foldCttzCtlz(IntrinsicInst &II, InstCombinerImpl &IC) {
+static Instruction *foldCttzCtlz(IntrinsicInst &II, InstCombinerImpl &IC) {
assert((II.getIntrinsicID() == Intrinsic::cttz ||
II.getIntrinsicID() == Intrinsic::ctlz) &&
"Expected cttz or ctlz intrinsic");
@@ -433,9 +433,9 @@ static Instruction *foldCttzCtlz(IntrinsicInst &II, InstCombinerImpl &IC) {
SelectPatternFlavor SPF = matchSelectPattern(Op0, X, Y).Flavor;
if (SPF == SPF_ABS || SPF == SPF_NABS)
return IC.replaceOperand(II, 0, X);
-
- if (match(Op0, m_Intrinsic<Intrinsic::abs>(m_Value(X))))
- return IC.replaceOperand(II, 0, X);
+
+ if (match(Op0, m_Intrinsic<Intrinsic::abs>(m_Value(X))))
+ return IC.replaceOperand(II, 0, X);
}
KnownBits Known = IC.computeKnownBits(Op0, 0, &II);
@@ -480,7 +480,7 @@ static Instruction *foldCttzCtlz(IntrinsicInst &II, InstCombinerImpl &IC) {
return nullptr;
}
-static Instruction *foldCtpop(IntrinsicInst &II, InstCombinerImpl &IC) {
+static Instruction *foldCtpop(IntrinsicInst &II, InstCombinerImpl &IC) {
assert(II.getIntrinsicID() == Intrinsic::ctpop &&
"Expected ctpop intrinsic");
Type *Ty = II.getType();
@@ -546,7 +546,7 @@ static Value *simplifyNeonTbl1(const IntrinsicInst &II,
if (!C)
return nullptr;
- auto *VecTy = cast<FixedVectorType>(II.getType());
+ auto *VecTy = cast<FixedVectorType>(II.getType());
unsigned NumElts = VecTy->getNumElements();
// Only perform this transformation for <8 x i8> vector types.
@@ -594,9 +594,9 @@ static bool haveSameOperands(const IntrinsicInst &I, const IntrinsicInst &E,
// call @llvm.foo.start(i1 0) ; This one won't be skipped: it will be removed
// call @llvm.foo.end(i1 0)
// call @llvm.foo.end(i1 0) ; &I
-static bool
-removeTriviallyEmptyRange(IntrinsicInst &EndI, InstCombinerImpl &IC,
- std::function<bool(const IntrinsicInst &)> IsStart) {
+static bool
+removeTriviallyEmptyRange(IntrinsicInst &EndI, InstCombinerImpl &IC,
+ std::function<bool(const IntrinsicInst &)> IsStart) {
// We start from the end intrinsic and scan backwards, so that InstCombine
// has already processed (and potentially removed) all the instructions
// before the end intrinsic.
@@ -622,7 +622,7 @@ removeTriviallyEmptyRange(IntrinsicInst &EndI, InstCombinerImpl &IC,
return false;
}
-Instruction *InstCombinerImpl::visitVAEndInst(VAEndInst &I) {
+Instruction *InstCombinerImpl::visitVAEndInst(VAEndInst &I) {
removeTriviallyEmptyRange(I, *this, [](const IntrinsicInst &I) {
return I.getIntrinsicID() == Intrinsic::vastart ||
I.getIntrinsicID() == Intrinsic::vacopy;
@@ -630,7 +630,7 @@ Instruction *InstCombinerImpl::visitVAEndInst(VAEndInst &I) {
return nullptr;
}
-static CallInst *canonicalizeConstantArg0ToArg1(CallInst &Call) {
+static CallInst *canonicalizeConstantArg0ToArg1(CallInst &Call) {
assert(Call.getNumArgOperands() > 1 && "Need at least 2 args to swap");
Value *Arg0 = Call.getArgOperand(0), *Arg1 = Call.getArgOperand(1);
if (isa<Constant>(Arg0) && !isa<Constant>(Arg1)) {
@@ -641,44 +641,44 @@ static CallInst *canonicalizeConstantArg0ToArg1(CallInst &Call) {
return nullptr;
}
-/// Creates a result tuple for an overflow intrinsic \p II with a given
-/// \p Result and a constant \p Overflow value.
-static Instruction *createOverflowTuple(IntrinsicInst *II, Value *Result,
- Constant *Overflow) {
- Constant *V[] = {UndefValue::get(Result->getType()), Overflow};
- StructType *ST = cast<StructType>(II->getType());
- Constant *Struct = ConstantStruct::get(ST, V);
- return InsertValueInst::Create(Struct, Result, 0);
-}
-
-Instruction *
-InstCombinerImpl::foldIntrinsicWithOverflowCommon(IntrinsicInst *II) {
+/// Creates a result tuple for an overflow intrinsic \p II with a given
+/// \p Result and a constant \p Overflow value.
+static Instruction *createOverflowTuple(IntrinsicInst *II, Value *Result,
+ Constant *Overflow) {
+ Constant *V[] = {UndefValue::get(Result->getType()), Overflow};
+ StructType *ST = cast<StructType>(II->getType());
+ Constant *Struct = ConstantStruct::get(ST, V);
+ return InsertValueInst::Create(Struct, Result, 0);
+}
+
+Instruction *
+InstCombinerImpl::foldIntrinsicWithOverflowCommon(IntrinsicInst *II) {
WithOverflowInst *WO = cast<WithOverflowInst>(II);
Value *OperationResult = nullptr;
Constant *OverflowResult = nullptr;
if (OptimizeOverflowCheck(WO->getBinaryOp(), WO->isSigned(), WO->getLHS(),
WO->getRHS(), *WO, OperationResult, OverflowResult))
- return createOverflowTuple(WO, OperationResult, OverflowResult);
+ return createOverflowTuple(WO, OperationResult, OverflowResult);
return nullptr;
}
-static Optional<bool> getKnownSign(Value *Op, Instruction *CxtI,
- const DataLayout &DL, AssumptionCache *AC,
- DominatorTree *DT) {
- KnownBits Known = computeKnownBits(Op, DL, 0, AC, CxtI, DT);
- if (Known.isNonNegative())
- return false;
- if (Known.isNegative())
- return true;
-
- return isImpliedByDomCondition(
- ICmpInst::ICMP_SLT, Op, Constant::getNullValue(Op->getType()), CxtI, DL);
-}
-
+static Optional<bool> getKnownSign(Value *Op, Instruction *CxtI,
+ const DataLayout &DL, AssumptionCache *AC,
+ DominatorTree *DT) {
+ KnownBits Known = computeKnownBits(Op, DL, 0, AC, CxtI, DT);
+ if (Known.isNonNegative())
+ return false;
+ if (Known.isNegative())
+ return true;
+
+ return isImpliedByDomCondition(
+ ICmpInst::ICMP_SLT, Op, Constant::getNullValue(Op->getType()), CxtI, DL);
+}
+
/// CallInst simplification. This mostly only handles folding of intrinsic
/// instructions. For normal calls, it allows visitCallBase to do the heavy
/// lifting.
-Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
+Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
// Don't try to simplify calls without uses. It will not do anything useful,
// but will result in the following folds being skipped.
if (!CI.use_empty())
@@ -784,10 +784,10 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
}
}
- if (II->isCommutative()) {
- if (CallInst *NewCall = canonicalizeConstantArg0ToArg1(CI))
- return NewCall;
- }
+ if (II->isCommutative()) {
+ if (CallInst *NewCall = canonicalizeConstantArg0ToArg1(CI))
+ return NewCall;
+ }
Intrinsic::ID IID = II->getIntrinsicID();
switch (IID) {
@@ -795,73 +795,73 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
if (Value *V = lowerObjectSizeCall(II, DL, &TLI, /*MustSucceed=*/false))
return replaceInstUsesWith(CI, V);
return nullptr;
- case Intrinsic::abs: {
- Value *IIOperand = II->getArgOperand(0);
- bool IntMinIsPoison = cast<Constant>(II->getArgOperand(1))->isOneValue();
-
- // abs(-x) -> abs(x)
- // TODO: Copy nsw if it was present on the neg?
- Value *X;
- if (match(IIOperand, m_Neg(m_Value(X))))
- return replaceOperand(*II, 0, X);
- if (match(IIOperand, m_Select(m_Value(), m_Value(X), m_Neg(m_Deferred(X)))))
- return replaceOperand(*II, 0, X);
- if (match(IIOperand, m_Select(m_Value(), m_Neg(m_Value(X)), m_Deferred(X))))
- return replaceOperand(*II, 0, X);
-
- if (Optional<bool> Sign = getKnownSign(IIOperand, II, DL, &AC, &DT)) {
- // abs(x) -> x if x >= 0
- if (!*Sign)
- return replaceInstUsesWith(*II, IIOperand);
-
- // abs(x) -> -x if x < 0
- if (IntMinIsPoison)
- return BinaryOperator::CreateNSWNeg(IIOperand);
- return BinaryOperator::CreateNeg(IIOperand);
- }
-
- // abs (sext X) --> zext (abs X*)
- // Clear the IsIntMin (nsw) bit on the abs to allow narrowing.
- if (match(IIOperand, m_OneUse(m_SExt(m_Value(X))))) {
- Value *NarrowAbs =
- Builder.CreateBinaryIntrinsic(Intrinsic::abs, X, Builder.getFalse());
- return CastInst::Create(Instruction::ZExt, NarrowAbs, II->getType());
- }
-
- break;
- }
- case Intrinsic::umax:
- case Intrinsic::umin: {
- Value *I0 = II->getArgOperand(0), *I1 = II->getArgOperand(1);
- Value *X, *Y;
- if (match(I0, m_ZExt(m_Value(X))) && match(I1, m_ZExt(m_Value(Y))) &&
- (I0->hasOneUse() || I1->hasOneUse()) && X->getType() == Y->getType()) {
- Value *NarrowMaxMin = Builder.CreateBinaryIntrinsic(IID, X, Y);
- return CastInst::Create(Instruction::ZExt, NarrowMaxMin, II->getType());
- }
- // If both operands of unsigned min/max are sign-extended, it is still ok
- // to narrow the operation.
- LLVM_FALLTHROUGH;
- }
- case Intrinsic::smax:
- case Intrinsic::smin: {
- Value *I0 = II->getArgOperand(0), *I1 = II->getArgOperand(1);
- Value *X, *Y;
- if (match(I0, m_SExt(m_Value(X))) && match(I1, m_SExt(m_Value(Y))) &&
- (I0->hasOneUse() || I1->hasOneUse()) && X->getType() == Y->getType()) {
- Value *NarrowMaxMin = Builder.CreateBinaryIntrinsic(IID, X, Y);
- return CastInst::Create(Instruction::SExt, NarrowMaxMin, II->getType());
- }
- break;
- }
+ case Intrinsic::abs: {
+ Value *IIOperand = II->getArgOperand(0);
+ bool IntMinIsPoison = cast<Constant>(II->getArgOperand(1))->isOneValue();
+
+ // abs(-x) -> abs(x)
+ // TODO: Copy nsw if it was present on the neg?
+ Value *X;
+ if (match(IIOperand, m_Neg(m_Value(X))))
+ return replaceOperand(*II, 0, X);
+ if (match(IIOperand, m_Select(m_Value(), m_Value(X), m_Neg(m_Deferred(X)))))
+ return replaceOperand(*II, 0, X);
+ if (match(IIOperand, m_Select(m_Value(), m_Neg(m_Value(X)), m_Deferred(X))))
+ return replaceOperand(*II, 0, X);
+
+ if (Optional<bool> Sign = getKnownSign(IIOperand, II, DL, &AC, &DT)) {
+ // abs(x) -> x if x >= 0
+ if (!*Sign)
+ return replaceInstUsesWith(*II, IIOperand);
+
+ // abs(x) -> -x if x < 0
+ if (IntMinIsPoison)
+ return BinaryOperator::CreateNSWNeg(IIOperand);
+ return BinaryOperator::CreateNeg(IIOperand);
+ }
+
+ // abs (sext X) --> zext (abs X*)
+ // Clear the IsIntMin (nsw) bit on the abs to allow narrowing.
+ if (match(IIOperand, m_OneUse(m_SExt(m_Value(X))))) {
+ Value *NarrowAbs =
+ Builder.CreateBinaryIntrinsic(Intrinsic::abs, X, Builder.getFalse());
+ return CastInst::Create(Instruction::ZExt, NarrowAbs, II->getType());
+ }
+
+ break;
+ }
+ case Intrinsic::umax:
+ case Intrinsic::umin: {
+ Value *I0 = II->getArgOperand(0), *I1 = II->getArgOperand(1);
+ Value *X, *Y;
+ if (match(I0, m_ZExt(m_Value(X))) && match(I1, m_ZExt(m_Value(Y))) &&
+ (I0->hasOneUse() || I1->hasOneUse()) && X->getType() == Y->getType()) {
+ Value *NarrowMaxMin = Builder.CreateBinaryIntrinsic(IID, X, Y);
+ return CastInst::Create(Instruction::ZExt, NarrowMaxMin, II->getType());
+ }
+ // If both operands of unsigned min/max are sign-extended, it is still ok
+ // to narrow the operation.
+ LLVM_FALLTHROUGH;
+ }
+ case Intrinsic::smax:
+ case Intrinsic::smin: {
+ Value *I0 = II->getArgOperand(0), *I1 = II->getArgOperand(1);
+ Value *X, *Y;
+ if (match(I0, m_SExt(m_Value(X))) && match(I1, m_SExt(m_Value(Y))) &&
+ (I0->hasOneUse() || I1->hasOneUse()) && X->getType() == Y->getType()) {
+ Value *NarrowMaxMin = Builder.CreateBinaryIntrinsic(IID, X, Y);
+ return CastInst::Create(Instruction::SExt, NarrowMaxMin, II->getType());
+ }
+ break;
+ }
case Intrinsic::bswap: {
Value *IIOperand = II->getArgOperand(0);
Value *X = nullptr;
// bswap(trunc(bswap(x))) -> trunc(lshr(x, c))
if (match(IIOperand, m_Trunc(m_BSwap(m_Value(X))))) {
- unsigned C = X->getType()->getScalarSizeInBits() -
- IIOperand->getType()->getScalarSizeInBits();
+ unsigned C = X->getType()->getScalarSizeInBits() -
+ IIOperand->getType()->getScalarSizeInBits();
Value *CV = ConstantInt::get(X->getType(), C);
Value *V = Builder.CreateLShr(X, CV);
return new TruncInst(V, IIOperand->getType());
@@ -888,12 +888,12 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
// 0 and 1 are handled in instsimplify
// powi(x, -1) -> 1/x
if (Power->isMinusOne())
- return BinaryOperator::CreateFDivFMF(ConstantFP::get(CI.getType(), 1.0),
- II->getArgOperand(0), II);
+ return BinaryOperator::CreateFDivFMF(ConstantFP::get(CI.getType(), 1.0),
+ II->getArgOperand(0), II);
// powi(x, 2) -> x*x
if (Power->equalsInt(2))
- return BinaryOperator::CreateFMulFMF(II->getArgOperand(0),
- II->getArgOperand(0), II);
+ return BinaryOperator::CreateFMulFMF(II->getArgOperand(0),
+ II->getArgOperand(0), II);
}
break;
@@ -914,8 +914,8 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
Type *Ty = II->getType();
unsigned BitWidth = Ty->getScalarSizeInBits();
Constant *ShAmtC;
- if (match(II->getArgOperand(2), m_ImmConstant(ShAmtC)) &&
- !ShAmtC->containsConstantExpression()) {
+ if (match(II->getArgOperand(2), m_ImmConstant(ShAmtC)) &&
+ !ShAmtC->containsConstantExpression()) {
// Canonicalize a shift amount constant operand to modulo the bit-width.
Constant *WidthC = ConstantInt::get(Ty, BitWidth);
Constant *ModuloC = ConstantExpr::getURem(ShAmtC, WidthC);
@@ -1259,52 +1259,52 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
break;
}
case Intrinsic::copysign: {
- Value *Mag = II->getArgOperand(0), *Sign = II->getArgOperand(1);
- if (SignBitMustBeZero(Sign, &TLI)) {
+ Value *Mag = II->getArgOperand(0), *Sign = II->getArgOperand(1);
+ if (SignBitMustBeZero(Sign, &TLI)) {
// If we know that the sign argument is positive, reduce to FABS:
- // copysign Mag, +Sign --> fabs Mag
- Value *Fabs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, Mag, II);
+ // copysign Mag, +Sign --> fabs Mag
+ Value *Fabs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, Mag, II);
return replaceInstUsesWith(*II, Fabs);
}
// TODO: There should be a ValueTracking sibling like SignBitMustBeOne.
const APFloat *C;
- if (match(Sign, m_APFloat(C)) && C->isNegative()) {
+ if (match(Sign, m_APFloat(C)) && C->isNegative()) {
// If we know that the sign argument is negative, reduce to FNABS:
- // copysign Mag, -Sign --> fneg (fabs Mag)
- Value *Fabs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, Mag, II);
+ // copysign Mag, -Sign --> fneg (fabs Mag)
+ Value *Fabs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, Mag, II);
return replaceInstUsesWith(*II, Builder.CreateFNegFMF(Fabs, II));
}
// Propagate sign argument through nested calls:
- // copysign Mag, (copysign ?, X) --> copysign Mag, X
- Value *X;
- if (match(Sign, m_Intrinsic<Intrinsic::copysign>(m_Value(), m_Value(X))))
- return replaceOperand(*II, 1, X);
-
- // Peek through changes of magnitude's sign-bit. This call rewrites those:
- // copysign (fabs X), Sign --> copysign X, Sign
- // copysign (fneg X), Sign --> copysign X, Sign
- if (match(Mag, m_FAbs(m_Value(X))) || match(Mag, m_FNeg(m_Value(X))))
- return replaceOperand(*II, 0, X);
-
+ // copysign Mag, (copysign ?, X) --> copysign Mag, X
+ Value *X;
+ if (match(Sign, m_Intrinsic<Intrinsic::copysign>(m_Value(), m_Value(X))))
+ return replaceOperand(*II, 1, X);
+
+ // Peek through changes of magnitude's sign-bit. This call rewrites those:
+ // copysign (fabs X), Sign --> copysign X, Sign
+ // copysign (fneg X), Sign --> copysign X, Sign
+ if (match(Mag, m_FAbs(m_Value(X))) || match(Mag, m_FNeg(m_Value(X))))
+ return replaceOperand(*II, 0, X);
+
break;
}
case Intrinsic::fabs: {
- Value *Cond, *TVal, *FVal;
+ Value *Cond, *TVal, *FVal;
if (match(II->getArgOperand(0),
- m_Select(m_Value(Cond), m_Value(TVal), m_Value(FVal)))) {
- // fabs (select Cond, TrueC, FalseC) --> select Cond, AbsT, AbsF
- if (isa<Constant>(TVal) && isa<Constant>(FVal)) {
- CallInst *AbsT = Builder.CreateCall(II->getCalledFunction(), {TVal});
- CallInst *AbsF = Builder.CreateCall(II->getCalledFunction(), {FVal});
- return SelectInst::Create(Cond, AbsT, AbsF);
- }
- // fabs (select Cond, -FVal, FVal) --> fabs FVal
- if (match(TVal, m_FNeg(m_Specific(FVal))))
- return replaceOperand(*II, 0, FVal);
- // fabs (select Cond, TVal, -TVal) --> fabs TVal
- if (match(FVal, m_FNeg(m_Specific(TVal))))
- return replaceOperand(*II, 0, TVal);
+ m_Select(m_Value(Cond), m_Value(TVal), m_Value(FVal)))) {
+ // fabs (select Cond, TrueC, FalseC) --> select Cond, AbsT, AbsF
+ if (isa<Constant>(TVal) && isa<Constant>(FVal)) {
+ CallInst *AbsT = Builder.CreateCall(II->getCalledFunction(), {TVal});
+ CallInst *AbsF = Builder.CreateCall(II->getCalledFunction(), {FVal});
+ return SelectInst::Create(Cond, AbsT, AbsF);
+ }
+ // fabs (select Cond, -FVal, FVal) --> fabs FVal
+ if (match(TVal, m_FNeg(m_Specific(FVal))))
+ return replaceOperand(*II, 0, FVal);
+ // fabs (select Cond, TVal, -TVal) --> fabs TVal
+ if (match(FVal, m_FNeg(m_Specific(TVal))))
+ return replaceOperand(*II, 0, TVal);
}
LLVM_FALLTHROUGH;
@@ -1491,16 +1491,16 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
break;
case Intrinsic::assume: {
Value *IIOperand = II->getArgOperand(0);
- SmallVector<OperandBundleDef, 4> OpBundles;
- II->getOperandBundlesAsDefs(OpBundles);
- bool HasOpBundles = !OpBundles.empty();
+ SmallVector<OperandBundleDef, 4> OpBundles;
+ II->getOperandBundlesAsDefs(OpBundles);
+ bool HasOpBundles = !OpBundles.empty();
// Remove an assume if it is followed by an identical assume.
// TODO: Do we need this? Unless there are conflicting assumptions, the
// computeKnownBits(IIOperand) below here eliminates redundant assumes.
Instruction *Next = II->getNextNonDebugInstruction();
- if (HasOpBundles &&
- match(Next, m_Intrinsic<Intrinsic::assume>(m_Specific(IIOperand))) &&
- !cast<IntrinsicInst>(Next)->hasOperandBundles())
+ if (HasOpBundles &&
+ match(Next, m_Intrinsic<Intrinsic::assume>(m_Specific(IIOperand))) &&
+ !cast<IntrinsicInst>(Next)->hasOperandBundles())
return eraseInstFromFunction(CI);
// Canonicalize assume(a && b) -> assume(a); assume(b);
@@ -1509,16 +1509,16 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
FunctionType *AssumeIntrinsicTy = II->getFunctionType();
Value *AssumeIntrinsic = II->getCalledOperand();
Value *A, *B;
- if (match(IIOperand, m_LogicalAnd(m_Value(A), m_Value(B)))) {
- Builder.CreateCall(AssumeIntrinsicTy, AssumeIntrinsic, A, OpBundles,
- II->getName());
+ if (match(IIOperand, m_LogicalAnd(m_Value(A), m_Value(B)))) {
+ Builder.CreateCall(AssumeIntrinsicTy, AssumeIntrinsic, A, OpBundles,
+ II->getName());
Builder.CreateCall(AssumeIntrinsicTy, AssumeIntrinsic, B, II->getName());
return eraseInstFromFunction(*II);
}
// assume(!(a || b)) -> assume(!a); assume(!b);
- if (match(IIOperand, m_Not(m_LogicalOr(m_Value(A), m_Value(B))))) {
+ if (match(IIOperand, m_Not(m_LogicalOr(m_Value(A), m_Value(B))))) {
Builder.CreateCall(AssumeIntrinsicTy, AssumeIntrinsic,
- Builder.CreateNot(A), OpBundles, II->getName());
+ Builder.CreateNot(A), OpBundles, II->getName());
Builder.CreateCall(AssumeIntrinsicTy, AssumeIntrinsic,
Builder.CreateNot(B), II->getName());
return eraseInstFromFunction(*II);
@@ -1534,8 +1534,8 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
isValidAssumeForContext(II, LHS, &DT)) {
MDNode *MD = MDNode::get(II->getContext(), None);
LHS->setMetadata(LLVMContext::MD_nonnull, MD);
- if (!HasOpBundles)
- return eraseInstFromFunction(*II);
+ if (!HasOpBundles)
+ return eraseInstFromFunction(*II);
// TODO: apply nonnull return attributes to calls and invokes
// TODO: apply range metadata for range check patterns?
@@ -1553,102 +1553,102 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
AC.updateAffectedValues(II);
break;
}
- case Intrinsic::experimental_gc_statepoint: {
- GCStatepointInst &GCSP = *cast<GCStatepointInst>(II);
- SmallPtrSet<Value *, 32> LiveGcValues;
- for (const GCRelocateInst *Reloc : GCSP.getGCRelocates()) {
- GCRelocateInst &GCR = *const_cast<GCRelocateInst *>(Reloc);
-
- // Remove the relocation if unused.
- if (GCR.use_empty()) {
- eraseInstFromFunction(GCR);
- continue;
- }
-
- Value *DerivedPtr = GCR.getDerivedPtr();
- Value *BasePtr = GCR.getBasePtr();
-
- // Undef is undef, even after relocation.
- if (isa<UndefValue>(DerivedPtr) || isa<UndefValue>(BasePtr)) {
- replaceInstUsesWith(GCR, UndefValue::get(GCR.getType()));
- eraseInstFromFunction(GCR);
- continue;
- }
-
- if (auto *PT = dyn_cast<PointerType>(GCR.getType())) {
- // The relocation of null will be null for most any collector.
- // TODO: provide a hook for this in GCStrategy. There might be some
- // weird collector this property does not hold for.
- if (isa<ConstantPointerNull>(DerivedPtr)) {
- // Use null-pointer of gc_relocate's type to replace it.
- replaceInstUsesWith(GCR, ConstantPointerNull::get(PT));
- eraseInstFromFunction(GCR);
- continue;
- }
-
- // isKnownNonNull -> nonnull attribute
- if (!GCR.hasRetAttr(Attribute::NonNull) &&
- isKnownNonZero(DerivedPtr, DL, 0, &AC, II, &DT)) {
- GCR.addAttribute(AttributeList::ReturnIndex, Attribute::NonNull);
- // We discovered new fact, re-check users.
- Worklist.pushUsersToWorkList(GCR);
- }
- }
-
- // If we have two copies of the same pointer in the statepoint argument
- // list, canonicalize to one. This may let us common gc.relocates.
- if (GCR.getBasePtr() == GCR.getDerivedPtr() &&
- GCR.getBasePtrIndex() != GCR.getDerivedPtrIndex()) {
- auto *OpIntTy = GCR.getOperand(2)->getType();
- GCR.setOperand(2, ConstantInt::get(OpIntTy, GCR.getBasePtrIndex()));
+ case Intrinsic::experimental_gc_statepoint: {
+ GCStatepointInst &GCSP = *cast<GCStatepointInst>(II);
+ SmallPtrSet<Value *, 32> LiveGcValues;
+ for (const GCRelocateInst *Reloc : GCSP.getGCRelocates()) {
+ GCRelocateInst &GCR = *const_cast<GCRelocateInst *>(Reloc);
+
+ // Remove the relocation if unused.
+ if (GCR.use_empty()) {
+ eraseInstFromFunction(GCR);
+ continue;
}
- // TODO: bitcast(relocate(p)) -> relocate(bitcast(p))
- // Canonicalize on the type from the uses to the defs
-
- // TODO: relocate((gep p, C, C2, ...)) -> gep(relocate(p), C, C2, ...)
- LiveGcValues.insert(BasePtr);
- LiveGcValues.insert(DerivedPtr);
- }
- Optional<OperandBundleUse> Bundle =
- GCSP.getOperandBundle(LLVMContext::OB_gc_live);
- unsigned NumOfGCLives = LiveGcValues.size();
- if (!Bundle.hasValue() || NumOfGCLives == Bundle->Inputs.size())
- break;
- // We can reduce the size of gc live bundle.
- DenseMap<Value *, unsigned> Val2Idx;
- std::vector<Value *> NewLiveGc;
- for (unsigned I = 0, E = Bundle->Inputs.size(); I < E; ++I) {
- Value *V = Bundle->Inputs[I];
- if (Val2Idx.count(V))
- continue;
- if (LiveGcValues.count(V)) {
- Val2Idx[V] = NewLiveGc.size();
- NewLiveGc.push_back(V);
- } else
- Val2Idx[V] = NumOfGCLives;
- }
- // Update all gc.relocates
- for (const GCRelocateInst *Reloc : GCSP.getGCRelocates()) {
- GCRelocateInst &GCR = *const_cast<GCRelocateInst *>(Reloc);
- Value *BasePtr = GCR.getBasePtr();
- assert(Val2Idx.count(BasePtr) && Val2Idx[BasePtr] != NumOfGCLives &&
- "Missed live gc for base pointer");
- auto *OpIntTy1 = GCR.getOperand(1)->getType();
- GCR.setOperand(1, ConstantInt::get(OpIntTy1, Val2Idx[BasePtr]));
- Value *DerivedPtr = GCR.getDerivedPtr();
- assert(Val2Idx.count(DerivedPtr) && Val2Idx[DerivedPtr] != NumOfGCLives &&
- "Missed live gc for derived pointer");
- auto *OpIntTy2 = GCR.getOperand(2)->getType();
- GCR.setOperand(2, ConstantInt::get(OpIntTy2, Val2Idx[DerivedPtr]));
- }
- // Create new statepoint instruction.
- OperandBundleDef NewBundle("gc-live", NewLiveGc);
- if (isa<CallInst>(II))
- return CallInst::CreateWithReplacedBundle(cast<CallInst>(II), NewBundle);
- else
- return InvokeInst::CreateWithReplacedBundle(cast<InvokeInst>(II),
- NewBundle);
+ Value *DerivedPtr = GCR.getDerivedPtr();
+ Value *BasePtr = GCR.getBasePtr();
+
+ // Undef is undef, even after relocation.
+ if (isa<UndefValue>(DerivedPtr) || isa<UndefValue>(BasePtr)) {
+ replaceInstUsesWith(GCR, UndefValue::get(GCR.getType()));
+ eraseInstFromFunction(GCR);
+ continue;
+ }
+
+ if (auto *PT = dyn_cast<PointerType>(GCR.getType())) {
+ // The relocation of null will be null for most any collector.
+ // TODO: provide a hook for this in GCStrategy. There might be some
+ // weird collector this property does not hold for.
+ if (isa<ConstantPointerNull>(DerivedPtr)) {
+ // Use null-pointer of gc_relocate's type to replace it.
+ replaceInstUsesWith(GCR, ConstantPointerNull::get(PT));
+ eraseInstFromFunction(GCR);
+ continue;
+ }
+
+ // isKnownNonNull -> nonnull attribute
+ if (!GCR.hasRetAttr(Attribute::NonNull) &&
+ isKnownNonZero(DerivedPtr, DL, 0, &AC, II, &DT)) {
+ GCR.addAttribute(AttributeList::ReturnIndex, Attribute::NonNull);
+ // We discovered new fact, re-check users.
+ Worklist.pushUsersToWorkList(GCR);
+ }
+ }
+
+ // If we have two copies of the same pointer in the statepoint argument
+ // list, canonicalize to one. This may let us common gc.relocates.
+ if (GCR.getBasePtr() == GCR.getDerivedPtr() &&
+ GCR.getBasePtrIndex() != GCR.getDerivedPtrIndex()) {
+ auto *OpIntTy = GCR.getOperand(2)->getType();
+ GCR.setOperand(2, ConstantInt::get(OpIntTy, GCR.getBasePtrIndex()));
+ }
+
+ // TODO: bitcast(relocate(p)) -> relocate(bitcast(p))
+ // Canonicalize on the type from the uses to the defs
+
+ // TODO: relocate((gep p, C, C2, ...)) -> gep(relocate(p), C, C2, ...)
+ LiveGcValues.insert(BasePtr);
+ LiveGcValues.insert(DerivedPtr);
+ }
+ Optional<OperandBundleUse> Bundle =
+ GCSP.getOperandBundle(LLVMContext::OB_gc_live);
+ unsigned NumOfGCLives = LiveGcValues.size();
+ if (!Bundle.hasValue() || NumOfGCLives == Bundle->Inputs.size())
+ break;
+ // We can reduce the size of gc live bundle.
+ DenseMap<Value *, unsigned> Val2Idx;
+ std::vector<Value *> NewLiveGc;
+ for (unsigned I = 0, E = Bundle->Inputs.size(); I < E; ++I) {
+ Value *V = Bundle->Inputs[I];
+ if (Val2Idx.count(V))
+ continue;
+ if (LiveGcValues.count(V)) {
+ Val2Idx[V] = NewLiveGc.size();
+ NewLiveGc.push_back(V);
+ } else
+ Val2Idx[V] = NumOfGCLives;
+ }
+ // Update all gc.relocates
+ for (const GCRelocateInst *Reloc : GCSP.getGCRelocates()) {
+ GCRelocateInst &GCR = *const_cast<GCRelocateInst *>(Reloc);
+ Value *BasePtr = GCR.getBasePtr();
+ assert(Val2Idx.count(BasePtr) && Val2Idx[BasePtr] != NumOfGCLives &&
+ "Missed live gc for base pointer");
+ auto *OpIntTy1 = GCR.getOperand(1)->getType();
+ GCR.setOperand(1, ConstantInt::get(OpIntTy1, Val2Idx[BasePtr]));
+ Value *DerivedPtr = GCR.getDerivedPtr();
+ assert(Val2Idx.count(DerivedPtr) && Val2Idx[DerivedPtr] != NumOfGCLives &&
+ "Missed live gc for derived pointer");
+ auto *OpIntTy2 = GCR.getOperand(2)->getType();
+ GCR.setOperand(2, ConstantInt::get(OpIntTy2, Val2Idx[DerivedPtr]));
+ }
+ // Create new statepoint instruction.
+ OperandBundleDef NewBundle("gc-live", NewLiveGc);
+ if (isa<CallInst>(II))
+ return CallInst::CreateWithReplacedBundle(cast<CallInst>(II), NewBundle);
+ else
+ return InvokeInst::CreateWithReplacedBundle(cast<InvokeInst>(II),
+ NewBundle);
break;
}
case Intrinsic::experimental_guard: {
@@ -1683,114 +1683,114 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
}
break;
}
- case Intrinsic::experimental_vector_insert: {
- Value *Vec = II->getArgOperand(0);
- Value *SubVec = II->getArgOperand(1);
- Value *Idx = II->getArgOperand(2);
- auto *DstTy = dyn_cast<FixedVectorType>(II->getType());
- auto *VecTy = dyn_cast<FixedVectorType>(Vec->getType());
- auto *SubVecTy = dyn_cast<FixedVectorType>(SubVec->getType());
-
- // Only canonicalize if the destination vector, Vec, and SubVec are all
- // fixed vectors.
- if (DstTy && VecTy && SubVecTy) {
- unsigned DstNumElts = DstTy->getNumElements();
- unsigned VecNumElts = VecTy->getNumElements();
- unsigned SubVecNumElts = SubVecTy->getNumElements();
- unsigned IdxN = cast<ConstantInt>(Idx)->getZExtValue();
-
- // The result of this call is undefined if IdxN is not a constant multiple
- // of the SubVec's minimum vector length OR the insertion overruns Vec.
- if (IdxN % SubVecNumElts != 0 || IdxN + SubVecNumElts > VecNumElts) {
- replaceInstUsesWith(CI, UndefValue::get(CI.getType()));
- return eraseInstFromFunction(CI);
- }
-
- // An insert that entirely overwrites Vec with SubVec is a nop.
- if (VecNumElts == SubVecNumElts) {
- replaceInstUsesWith(CI, SubVec);
- return eraseInstFromFunction(CI);
- }
-
- // Widen SubVec into a vector of the same width as Vec, since
- // shufflevector requires the two input vectors to be the same width.
- // Elements beyond the bounds of SubVec within the widened vector are
- // undefined.
- SmallVector<int, 8> WidenMask;
- unsigned i;
- for (i = 0; i != SubVecNumElts; ++i)
- WidenMask.push_back(i);
- for (; i != VecNumElts; ++i)
- WidenMask.push_back(UndefMaskElem);
-
- Value *WidenShuffle = Builder.CreateShuffleVector(SubVec, WidenMask);
-
- SmallVector<int, 8> Mask;
- for (unsigned i = 0; i != IdxN; ++i)
- Mask.push_back(i);
- for (unsigned i = DstNumElts; i != DstNumElts + SubVecNumElts; ++i)
- Mask.push_back(i);
- for (unsigned i = IdxN + SubVecNumElts; i != DstNumElts; ++i)
- Mask.push_back(i);
-
- Value *Shuffle = Builder.CreateShuffleVector(Vec, WidenShuffle, Mask);
- replaceInstUsesWith(CI, Shuffle);
- return eraseInstFromFunction(CI);
- }
- break;
- }
- case Intrinsic::experimental_vector_extract: {
- Value *Vec = II->getArgOperand(0);
- Value *Idx = II->getArgOperand(1);
-
- auto *DstTy = dyn_cast<FixedVectorType>(II->getType());
- auto *VecTy = dyn_cast<FixedVectorType>(Vec->getType());
-
- // Only canonicalize if the the destination vector and Vec are fixed
- // vectors.
- if (DstTy && VecTy) {
- unsigned DstNumElts = DstTy->getNumElements();
- unsigned VecNumElts = VecTy->getNumElements();
- unsigned IdxN = cast<ConstantInt>(Idx)->getZExtValue();
-
- // The result of this call is undefined if IdxN is not a constant multiple
- // of the result type's minimum vector length OR the extraction overruns
- // Vec.
- if (IdxN % DstNumElts != 0 || IdxN + DstNumElts > VecNumElts) {
- replaceInstUsesWith(CI, UndefValue::get(CI.getType()));
- return eraseInstFromFunction(CI);
- }
-
- // Extracting the entirety of Vec is a nop.
- if (VecNumElts == DstNumElts) {
- replaceInstUsesWith(CI, Vec);
- return eraseInstFromFunction(CI);
- }
-
- SmallVector<int, 8> Mask;
- for (unsigned i = 0; i != DstNumElts; ++i)
- Mask.push_back(IdxN + i);
-
- Value *Shuffle =
- Builder.CreateShuffleVector(Vec, UndefValue::get(VecTy), Mask);
- replaceInstUsesWith(CI, Shuffle);
- return eraseInstFromFunction(CI);
- }
- break;
- }
- default: {
- // Handle target specific intrinsics
- Optional<Instruction *> V = targetInstCombineIntrinsic(*II);
- if (V.hasValue())
- return V.getValue();
- break;
- }
- }
+ case Intrinsic::experimental_vector_insert: {
+ Value *Vec = II->getArgOperand(0);
+ Value *SubVec = II->getArgOperand(1);
+ Value *Idx = II->getArgOperand(2);
+ auto *DstTy = dyn_cast<FixedVectorType>(II->getType());
+ auto *VecTy = dyn_cast<FixedVectorType>(Vec->getType());
+ auto *SubVecTy = dyn_cast<FixedVectorType>(SubVec->getType());
+
+ // Only canonicalize if the destination vector, Vec, and SubVec are all
+ // fixed vectors.
+ if (DstTy && VecTy && SubVecTy) {
+ unsigned DstNumElts = DstTy->getNumElements();
+ unsigned VecNumElts = VecTy->getNumElements();
+ unsigned SubVecNumElts = SubVecTy->getNumElements();
+ unsigned IdxN = cast<ConstantInt>(Idx)->getZExtValue();
+
+ // The result of this call is undefined if IdxN is not a constant multiple
+ // of the SubVec's minimum vector length OR the insertion overruns Vec.
+ if (IdxN % SubVecNumElts != 0 || IdxN + SubVecNumElts > VecNumElts) {
+ replaceInstUsesWith(CI, UndefValue::get(CI.getType()));
+ return eraseInstFromFunction(CI);
+ }
+
+ // An insert that entirely overwrites Vec with SubVec is a nop.
+ if (VecNumElts == SubVecNumElts) {
+ replaceInstUsesWith(CI, SubVec);
+ return eraseInstFromFunction(CI);
+ }
+
+ // Widen SubVec into a vector of the same width as Vec, since
+ // shufflevector requires the two input vectors to be the same width.
+ // Elements beyond the bounds of SubVec within the widened vector are
+ // undefined.
+ SmallVector<int, 8> WidenMask;
+ unsigned i;
+ for (i = 0; i != SubVecNumElts; ++i)
+ WidenMask.push_back(i);
+ for (; i != VecNumElts; ++i)
+ WidenMask.push_back(UndefMaskElem);
+
+ Value *WidenShuffle = Builder.CreateShuffleVector(SubVec, WidenMask);
+
+ SmallVector<int, 8> Mask;
+ for (unsigned i = 0; i != IdxN; ++i)
+ Mask.push_back(i);
+ for (unsigned i = DstNumElts; i != DstNumElts + SubVecNumElts; ++i)
+ Mask.push_back(i);
+ for (unsigned i = IdxN + SubVecNumElts; i != DstNumElts; ++i)
+ Mask.push_back(i);
+
+ Value *Shuffle = Builder.CreateShuffleVector(Vec, WidenShuffle, Mask);
+ replaceInstUsesWith(CI, Shuffle);
+ return eraseInstFromFunction(CI);
+ }
+ break;
+ }
+ case Intrinsic::experimental_vector_extract: {
+ Value *Vec = II->getArgOperand(0);
+ Value *Idx = II->getArgOperand(1);
+
+ auto *DstTy = dyn_cast<FixedVectorType>(II->getType());
+ auto *VecTy = dyn_cast<FixedVectorType>(Vec->getType());
+
+ // Only canonicalize if the the destination vector and Vec are fixed
+ // vectors.
+ if (DstTy && VecTy) {
+ unsigned DstNumElts = DstTy->getNumElements();
+ unsigned VecNumElts = VecTy->getNumElements();
+ unsigned IdxN = cast<ConstantInt>(Idx)->getZExtValue();
+
+ // The result of this call is undefined if IdxN is not a constant multiple
+ // of the result type's minimum vector length OR the extraction overruns
+ // Vec.
+ if (IdxN % DstNumElts != 0 || IdxN + DstNumElts > VecNumElts) {
+ replaceInstUsesWith(CI, UndefValue::get(CI.getType()));
+ return eraseInstFromFunction(CI);
+ }
+
+ // Extracting the entirety of Vec is a nop.
+ if (VecNumElts == DstNumElts) {
+ replaceInstUsesWith(CI, Vec);
+ return eraseInstFromFunction(CI);
+ }
+
+ SmallVector<int, 8> Mask;
+ for (unsigned i = 0; i != DstNumElts; ++i)
+ Mask.push_back(IdxN + i);
+
+ Value *Shuffle =
+ Builder.CreateShuffleVector(Vec, UndefValue::get(VecTy), Mask);
+ replaceInstUsesWith(CI, Shuffle);
+ return eraseInstFromFunction(CI);
+ }
+ break;
+ }
+ default: {
+ // Handle target specific intrinsics
+ Optional<Instruction *> V = targetInstCombineIntrinsic(*II);
+ if (V.hasValue())
+ return V.getValue();
+ break;
+ }
+ }
return visitCallBase(*II);
}
// Fence instruction simplification
-Instruction *InstCombinerImpl::visitFenceInst(FenceInst &FI) {
+Instruction *InstCombinerImpl::visitFenceInst(FenceInst &FI) {
// Remove identical consecutive fences.
Instruction *Next = FI.getNextNonDebugInstruction();
if (auto *NFI = dyn_cast<FenceInst>(Next))
@@ -1800,12 +1800,12 @@ Instruction *InstCombinerImpl::visitFenceInst(FenceInst &FI) {
}
// InvokeInst simplification
-Instruction *InstCombinerImpl::visitInvokeInst(InvokeInst &II) {
+Instruction *InstCombinerImpl::visitInvokeInst(InvokeInst &II) {
return visitCallBase(II);
}
// CallBrInst simplification
-Instruction *InstCombinerImpl::visitCallBrInst(CallBrInst &CBI) {
+Instruction *InstCombinerImpl::visitCallBrInst(CallBrInst &CBI) {
return visitCallBase(CBI);
}
@@ -1845,7 +1845,7 @@ static bool isSafeToEliminateVarargsCast(const CallBase &Call,
return true;
}
-Instruction *InstCombinerImpl::tryOptimizeCall(CallInst *CI) {
+Instruction *InstCombinerImpl::tryOptimizeCall(CallInst *CI) {
if (!CI->getCalledFunction()) return nullptr;
auto InstCombineRAUW = [this](Instruction *From, Value *With) {
@@ -2002,7 +2002,7 @@ static void annotateAnyAllocSite(CallBase &Call, const TargetLibraryInfo *TLI) {
}
/// Improvements for call, callbr and invoke instructions.
-Instruction *InstCombinerImpl::visitCallBase(CallBase &Call) {
+Instruction *InstCombinerImpl::visitCallBase(CallBase &Call) {
if (isAllocationFn(&Call, &TLI))
annotateAnyAllocSite(Call, &TLI);
@@ -2058,7 +2058,7 @@ Instruction *InstCombinerImpl::visitCallBase(CallBase &Call) {
!CalleeF->isDeclaration()) {
Instruction *OldCall = &Call;
CreateNonTerminatorUnreachable(OldCall);
- // If OldCall does not return void then replaceInstUsesWith undef.
+ // If OldCall does not return void then replaceInstUsesWith undef.
// This allows ValueHandlers and custom metadata to adjust itself.
if (!OldCall->getType()->isVoidTy())
replaceInstUsesWith(*OldCall, UndefValue::get(OldCall->getType()));
@@ -2077,7 +2077,7 @@ Instruction *InstCombinerImpl::visitCallBase(CallBase &Call) {
if ((isa<ConstantPointerNull>(Callee) &&
!NullPointerIsDefined(Call.getFunction())) ||
isa<UndefValue>(Callee)) {
- // If Call does not return void then replaceInstUsesWith undef.
+ // If Call does not return void then replaceInstUsesWith undef.
// This allows ValueHandlers and custom metadata to adjust itself.
if (!Call.getType()->isVoidTy())
replaceInstUsesWith(Call, UndefValue::get(Call.getType()));
@@ -2153,7 +2153,7 @@ Instruction *InstCombinerImpl::visitCallBase(CallBase &Call) {
/// If the callee is a constexpr cast of a function, attempt to move the cast to
/// the arguments of the call/callbr/invoke.
-bool InstCombinerImpl::transformConstExprCastCall(CallBase &Call) {
+bool InstCombinerImpl::transformConstExprCastCall(CallBase &Call) {
auto *Callee =
dyn_cast<Function>(Call.getCalledOperand()->stripPointerCasts());
if (!Callee)
@@ -2252,9 +2252,9 @@ bool InstCombinerImpl::transformConstExprCastCall(CallBase &Call) {
if (Call.isInAllocaArgument(i))
return false; // Cannot transform to and from inalloca.
- if (CallerPAL.hasParamAttribute(i, Attribute::SwiftError))
- return false;
-
+ if (CallerPAL.hasParamAttribute(i, Attribute::SwiftError))
+ return false;
+
// If the parameter is passed as a byval argument, then we have to have a
// sized type and the sized type has to have the same size as the old type.
if (ParamTy != ActTy && CallerPAL.hasParamAttribute(i, Attribute::ByVal)) {
@@ -2440,8 +2440,8 @@ bool InstCombinerImpl::transformConstExprCastCall(CallBase &Call) {
/// Turn a call to a function created by init_trampoline / adjust_trampoline
/// intrinsic pair into a direct call to the underlying function.
Instruction *
-InstCombinerImpl::transformCallThroughTrampoline(CallBase &Call,
- IntrinsicInst &Tramp) {
+InstCombinerImpl::transformCallThroughTrampoline(CallBase &Call,
+ IntrinsicInst &Tramp) {
Value *Callee = Call.getCalledOperand();
Type *CalleeTy = Callee->getType();
FunctionType *FTy = Call.getFunctionType();
diff --git a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCasts.cpp b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 2b490d5084..07e68c4441 100644
--- a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -14,11 +14,11 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/IR/DIBuilder.h"
+#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/Support/KnownBits.h"
-#include "llvm/Transforms/InstCombine/InstCombiner.h"
+#include "llvm/Transforms/InstCombine/InstCombiner.h"
#include <numeric>
using namespace llvm;
using namespace PatternMatch;
@@ -82,8 +82,8 @@ static Value *decomposeSimpleLinearExpr(Value *Val, unsigned &Scale,
/// If we find a cast of an allocation instruction, try to eliminate the cast by
/// moving the type information into the alloc.
-Instruction *InstCombinerImpl::PromoteCastOfAllocation(BitCastInst &CI,
- AllocaInst &AI) {
+Instruction *InstCombinerImpl::PromoteCastOfAllocation(BitCastInst &CI,
+ AllocaInst &AI) {
PointerType *PTy = cast<PointerType>(CI.getType());
IRBuilderBase::InsertPointGuard Guard(Builder);
@@ -94,18 +94,18 @@ Instruction *InstCombinerImpl::PromoteCastOfAllocation(BitCastInst &CI,
Type *CastElTy = PTy->getElementType();
if (!AllocElTy->isSized() || !CastElTy->isSized()) return nullptr;
- // This optimisation does not work for cases where the cast type
- // is scalable and the allocated type is not. This because we need to
- // know how many times the casted type fits into the allocated type.
- // For the opposite case where the allocated type is scalable and the
- // cast type is not this leads to poor code quality due to the
- // introduction of 'vscale' into the calculations. It seems better to
- // bail out for this case too until we've done a proper cost-benefit
- // analysis.
- bool AllocIsScalable = isa<ScalableVectorType>(AllocElTy);
- bool CastIsScalable = isa<ScalableVectorType>(CastElTy);
- if (AllocIsScalable != CastIsScalable) return nullptr;
-
+ // This optimisation does not work for cases where the cast type
+ // is scalable and the allocated type is not. This because we need to
+ // know how many times the casted type fits into the allocated type.
+ // For the opposite case where the allocated type is scalable and the
+ // cast type is not this leads to poor code quality due to the
+ // introduction of 'vscale' into the calculations. It seems better to
+ // bail out for this case too until we've done a proper cost-benefit
+ // analysis.
+ bool AllocIsScalable = isa<ScalableVectorType>(AllocElTy);
+ bool CastIsScalable = isa<ScalableVectorType>(CastElTy);
+ if (AllocIsScalable != CastIsScalable) return nullptr;
+
Align AllocElTyAlign = DL.getABITypeAlign(AllocElTy);
Align CastElTyAlign = DL.getABITypeAlign(CastElTy);
if (CastElTyAlign < AllocElTyAlign) return nullptr;
@@ -115,15 +115,15 @@ Instruction *InstCombinerImpl::PromoteCastOfAllocation(BitCastInst &CI,
// same, we open the door to infinite loops of various kinds.
if (!AI.hasOneUse() && CastElTyAlign == AllocElTyAlign) return nullptr;
- // The alloc and cast types should be either both fixed or both scalable.
- uint64_t AllocElTySize = DL.getTypeAllocSize(AllocElTy).getKnownMinSize();
- uint64_t CastElTySize = DL.getTypeAllocSize(CastElTy).getKnownMinSize();
+ // The alloc and cast types should be either both fixed or both scalable.
+ uint64_t AllocElTySize = DL.getTypeAllocSize(AllocElTy).getKnownMinSize();
+ uint64_t CastElTySize = DL.getTypeAllocSize(CastElTy).getKnownMinSize();
if (CastElTySize == 0 || AllocElTySize == 0) return nullptr;
// If the allocation has multiple uses, only promote it if we're not
// shrinking the amount of memory being allocated.
- uint64_t AllocElTyStoreSize = DL.getTypeStoreSize(AllocElTy).getKnownMinSize();
- uint64_t CastElTyStoreSize = DL.getTypeStoreSize(CastElTy).getKnownMinSize();
+ uint64_t AllocElTyStoreSize = DL.getTypeStoreSize(AllocElTy).getKnownMinSize();
+ uint64_t CastElTyStoreSize = DL.getTypeStoreSize(CastElTy).getKnownMinSize();
if (!AI.hasOneUse() && CastElTyStoreSize < AllocElTyStoreSize) return nullptr;
// See if we can satisfy the modulus by pulling a scale out of the array
@@ -138,9 +138,9 @@ Instruction *InstCombinerImpl::PromoteCastOfAllocation(BitCastInst &CI,
if ((AllocElTySize*ArraySizeScale) % CastElTySize != 0 ||
(AllocElTySize*ArrayOffset ) % CastElTySize != 0) return nullptr;
- // We don't currently support arrays of scalable types.
- assert(!AllocIsScalable || (ArrayOffset == 1 && ArraySizeScale == 0));
-
+ // We don't currently support arrays of scalable types.
+ assert(!AllocIsScalable || (ArrayOffset == 1 && ArraySizeScale == 0));
+
unsigned Scale = (AllocElTySize*ArraySizeScale)/CastElTySize;
Value *Amt = nullptr;
if (Scale == 1) {
@@ -177,8 +177,8 @@ Instruction *InstCombinerImpl::PromoteCastOfAllocation(BitCastInst &CI,
/// Given an expression that CanEvaluateTruncated or CanEvaluateSExtd returns
/// true for, actually insert the code to evaluate the expression.
-Value *InstCombinerImpl::EvaluateInDifferentType(Value *V, Type *Ty,
- bool isSigned) {
+Value *InstCombinerImpl::EvaluateInDifferentType(Value *V, Type *Ty,
+ bool isSigned) {
if (Constant *C = dyn_cast<Constant>(V)) {
C = ConstantExpr::getIntegerCast(C, Ty, isSigned /*Sext or ZExt*/);
// If we got a constantexpr back, try to simplify it with DL info.
@@ -246,9 +246,9 @@ Value *InstCombinerImpl::EvaluateInDifferentType(Value *V, Type *Ty,
return InsertNewInstWith(Res, *I);
}
-Instruction::CastOps
-InstCombinerImpl::isEliminableCastPair(const CastInst *CI1,
- const CastInst *CI2) {
+Instruction::CastOps
+InstCombinerImpl::isEliminableCastPair(const CastInst *CI1,
+ const CastInst *CI2) {
Type *SrcTy = CI1->getSrcTy();
Type *MidTy = CI1->getDestTy();
Type *DstTy = CI2->getDestTy();
@@ -275,7 +275,7 @@ InstCombinerImpl::isEliminableCastPair(const CastInst *CI1,
}
/// Implement the transforms common to all CastInst visitors.
-Instruction *InstCombinerImpl::commonCastTransforms(CastInst &CI) {
+Instruction *InstCombinerImpl::commonCastTransforms(CastInst &CI) {
Value *Src = CI.getOperand(0);
// Try to eliminate a cast of a cast.
@@ -360,7 +360,7 @@ static bool canNotEvaluateInType(Value *V, Type *Ty) {
///
/// This function works on both vectors and scalars.
///
-static bool canEvaluateTruncated(Value *V, Type *Ty, InstCombinerImpl &IC,
+static bool canEvaluateTruncated(Value *V, Type *Ty, InstCombinerImpl &IC,
Instruction *CxtI) {
if (canAlwaysEvaluateInType(V, Ty))
return true;
@@ -477,8 +477,8 @@ static bool canEvaluateTruncated(Value *V, Type *Ty, InstCombinerImpl &IC,
/// trunc (lshr (bitcast <4 x i32> %X to i128), 32) to i32
/// --->
/// extractelement <4 x i32> %X, 1
-static Instruction *foldVecTruncToExtElt(TruncInst &Trunc,
- InstCombinerImpl &IC) {
+static Instruction *foldVecTruncToExtElt(TruncInst &Trunc,
+ InstCombinerImpl &IC) {
Value *TruncOp = Trunc.getOperand(0);
Type *DestType = Trunc.getType();
if (!TruncOp->hasOneUse() || !isa<IntegerType>(DestType))
@@ -515,9 +515,9 @@ static Instruction *foldVecTruncToExtElt(TruncInst &Trunc,
return ExtractElementInst::Create(VecInput, IC.Builder.getInt32(Elt));
}
-/// Funnel/Rotate left/right may occur in a wider type than necessary because of
-/// type promotion rules. Try to narrow the inputs and convert to funnel shift.
-Instruction *InstCombinerImpl::narrowFunnelShift(TruncInst &Trunc) {
+/// Funnel/Rotate left/right may occur in a wider type than necessary because of
+/// type promotion rules. Try to narrow the inputs and convert to funnel shift.
+Instruction *InstCombinerImpl::narrowFunnelShift(TruncInst &Trunc) {
assert((isa<VectorType>(Trunc.getSrcTy()) ||
shouldChangeType(Trunc.getSrcTy(), Trunc.getType())) &&
"Don't narrow to an illegal scalar type");
@@ -529,43 +529,43 @@ Instruction *InstCombinerImpl::narrowFunnelShift(TruncInst &Trunc) {
if (!isPowerOf2_32(NarrowWidth))
return nullptr;
- // First, find an or'd pair of opposite shifts:
- // trunc (or (lshr ShVal0, ShAmt0), (shl ShVal1, ShAmt1))
- BinaryOperator *Or0, *Or1;
- if (!match(Trunc.getOperand(0), m_OneUse(m_Or(m_BinOp(Or0), m_BinOp(Or1)))))
+ // First, find an or'd pair of opposite shifts:
+ // trunc (or (lshr ShVal0, ShAmt0), (shl ShVal1, ShAmt1))
+ BinaryOperator *Or0, *Or1;
+ if (!match(Trunc.getOperand(0), m_OneUse(m_Or(m_BinOp(Or0), m_BinOp(Or1)))))
return nullptr;
- Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
- if (!match(Or0, m_OneUse(m_LogicalShift(m_Value(ShVal0), m_Value(ShAmt0)))) ||
- !match(Or1, m_OneUse(m_LogicalShift(m_Value(ShVal1), m_Value(ShAmt1)))) ||
- Or0->getOpcode() == Or1->getOpcode())
+ Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
+ if (!match(Or0, m_OneUse(m_LogicalShift(m_Value(ShVal0), m_Value(ShAmt0)))) ||
+ !match(Or1, m_OneUse(m_LogicalShift(m_Value(ShVal1), m_Value(ShAmt1)))) ||
+ Or0->getOpcode() == Or1->getOpcode())
return nullptr;
- // Canonicalize to or(shl(ShVal0, ShAmt0), lshr(ShVal1, ShAmt1)).
- if (Or0->getOpcode() == BinaryOperator::LShr) {
- std::swap(Or0, Or1);
- std::swap(ShVal0, ShVal1);
- std::swap(ShAmt0, ShAmt1);
- }
- assert(Or0->getOpcode() == BinaryOperator::Shl &&
- Or1->getOpcode() == BinaryOperator::LShr &&
- "Illegal or(shift,shift) pair");
-
- // Match the shift amount operands for a funnel/rotate pattern. This always
- // matches a subtraction on the R operand.
- auto matchShiftAmount = [&](Value *L, Value *R, unsigned Width) -> Value * {
+ // Canonicalize to or(shl(ShVal0, ShAmt0), lshr(ShVal1, ShAmt1)).
+ if (Or0->getOpcode() == BinaryOperator::LShr) {
+ std::swap(Or0, Or1);
+ std::swap(ShVal0, ShVal1);
+ std::swap(ShAmt0, ShAmt1);
+ }
+ assert(Or0->getOpcode() == BinaryOperator::Shl &&
+ Or1->getOpcode() == BinaryOperator::LShr &&
+ "Illegal or(shift,shift) pair");
+
+ // Match the shift amount operands for a funnel/rotate pattern. This always
+ // matches a subtraction on the R operand.
+ auto matchShiftAmount = [&](Value *L, Value *R, unsigned Width) -> Value * {
// The shift amounts may add up to the narrow bit width:
- // (shl ShVal0, L) | (lshr ShVal1, Width - L)
+ // (shl ShVal0, L) | (lshr ShVal1, Width - L)
if (match(R, m_OneUse(m_Sub(m_SpecificInt(Width), m_Specific(L)))))
return L;
- // The following patterns currently only work for rotation patterns.
- // TODO: Add more general funnel-shift compatible patterns.
- if (ShVal0 != ShVal1)
- return nullptr;
-
+ // The following patterns currently only work for rotation patterns.
+ // TODO: Add more general funnel-shift compatible patterns.
+ if (ShVal0 != ShVal1)
+ return nullptr;
+
// The shift amount may be masked with negation:
- // (shl ShVal0, (X & (Width - 1))) | (lshr ShVal1, ((-X) & (Width - 1)))
+ // (shl ShVal0, (X & (Width - 1))) | (lshr ShVal1, ((-X) & (Width - 1)))
Value *X;
unsigned Mask = Width - 1;
if (match(L, m_And(m_Value(X), m_SpecificInt(Mask))) &&
@@ -581,10 +581,10 @@ Instruction *InstCombinerImpl::narrowFunnelShift(TruncInst &Trunc) {
};
Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, NarrowWidth);
- bool IsFshl = true; // Sub on LSHR.
+ bool IsFshl = true; // Sub on LSHR.
if (!ShAmt) {
ShAmt = matchShiftAmount(ShAmt1, ShAmt0, NarrowWidth);
- IsFshl = false; // Sub on SHL.
+ IsFshl = false; // Sub on SHL.
}
if (!ShAmt)
return nullptr;
@@ -593,28 +593,28 @@ Instruction *InstCombinerImpl::narrowFunnelShift(TruncInst &Trunc) {
// will be a zext, but it could also be the result of an 'and' or 'shift'.
unsigned WideWidth = Trunc.getSrcTy()->getScalarSizeInBits();
APInt HiBitMask = APInt::getHighBitsSet(WideWidth, WideWidth - NarrowWidth);
- if (!MaskedValueIsZero(ShVal0, HiBitMask, 0, &Trunc) ||
- !MaskedValueIsZero(ShVal1, HiBitMask, 0, &Trunc))
+ if (!MaskedValueIsZero(ShVal0, HiBitMask, 0, &Trunc) ||
+ !MaskedValueIsZero(ShVal1, HiBitMask, 0, &Trunc))
return nullptr;
// We have an unnecessarily wide rotate!
- // trunc (or (lshr ShVal0, ShAmt), (shl ShVal1, BitWidth - ShAmt))
+ // trunc (or (lshr ShVal0, ShAmt), (shl ShVal1, BitWidth - ShAmt))
// Narrow the inputs and convert to funnel shift intrinsic:
// llvm.fshl.i8(trunc(ShVal), trunc(ShVal), trunc(ShAmt))
Value *NarrowShAmt = Builder.CreateTrunc(ShAmt, DestTy);
- Value *X, *Y;
- X = Y = Builder.CreateTrunc(ShVal0, DestTy);
- if (ShVal0 != ShVal1)
- Y = Builder.CreateTrunc(ShVal1, DestTy);
+ Value *X, *Y;
+ X = Y = Builder.CreateTrunc(ShVal0, DestTy);
+ if (ShVal0 != ShVal1)
+ Y = Builder.CreateTrunc(ShVal1, DestTy);
Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
Function *F = Intrinsic::getDeclaration(Trunc.getModule(), IID, DestTy);
- return IntrinsicInst::Create(F, {X, Y, NarrowShAmt});
+ return IntrinsicInst::Create(F, {X, Y, NarrowShAmt});
}
/// Try to narrow the width of math or bitwise logic instructions by pulling a
/// truncate ahead of binary operators.
/// TODO: Transforms for truncated shifts should be moved into here.
-Instruction *InstCombinerImpl::narrowBinOp(TruncInst &Trunc) {
+Instruction *InstCombinerImpl::narrowBinOp(TruncInst &Trunc) {
Type *SrcTy = Trunc.getSrcTy();
Type *DestTy = Trunc.getType();
if (!isa<VectorType>(SrcTy) && !shouldChangeType(SrcTy, DestTy))
@@ -663,7 +663,7 @@ Instruction *InstCombinerImpl::narrowBinOp(TruncInst &Trunc) {
default: break;
}
- if (Instruction *NarrowOr = narrowFunnelShift(Trunc))
+ if (Instruction *NarrowOr = narrowFunnelShift(Trunc))
return NarrowOr;
return nullptr;
@@ -719,7 +719,7 @@ static Instruction *shrinkInsertElt(CastInst &Trunc,
return nullptr;
}
-Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
+Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
if (Instruction *Result = commonCastTransforms(Trunc))
return Result;
@@ -813,60 +813,60 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
}
}
- Value *A;
- Constant *C;
- if (match(Src, m_LShr(m_SExt(m_Value(A)), m_Constant(C)))) {
+ Value *A;
+ Constant *C;
+ if (match(Src, m_LShr(m_SExt(m_Value(A)), m_Constant(C)))) {
unsigned AWidth = A->getType()->getScalarSizeInBits();
unsigned MaxShiftAmt = SrcWidth - std::max(DestWidth, AWidth);
- auto *OldSh = cast<Instruction>(Src);
- bool IsExact = OldSh->isExact();
+ auto *OldSh = cast<Instruction>(Src);
+ bool IsExact = OldSh->isExact();
// If the shift is small enough, all zero bits created by the shift are
// removed by the trunc.
- if (match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULE,
- APInt(SrcWidth, MaxShiftAmt)))) {
+ if (match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULE,
+ APInt(SrcWidth, MaxShiftAmt)))) {
// trunc (lshr (sext A), C) --> ashr A, C
if (A->getType() == DestTy) {
- Constant *MaxAmt = ConstantInt::get(SrcTy, DestWidth - 1, false);
- Constant *ShAmt = ConstantExpr::getUMin(C, MaxAmt);
- ShAmt = ConstantExpr::getTrunc(ShAmt, A->getType());
- ShAmt = Constant::mergeUndefsWith(ShAmt, C);
- return IsExact ? BinaryOperator::CreateExactAShr(A, ShAmt)
- : BinaryOperator::CreateAShr(A, ShAmt);
+ Constant *MaxAmt = ConstantInt::get(SrcTy, DestWidth - 1, false);
+ Constant *ShAmt = ConstantExpr::getUMin(C, MaxAmt);
+ ShAmt = ConstantExpr::getTrunc(ShAmt, A->getType());
+ ShAmt = Constant::mergeUndefsWith(ShAmt, C);
+ return IsExact ? BinaryOperator::CreateExactAShr(A, ShAmt)
+ : BinaryOperator::CreateAShr(A, ShAmt);
}
// The types are mismatched, so create a cast after shifting:
// trunc (lshr (sext A), C) --> sext/trunc (ashr A, C)
if (Src->hasOneUse()) {
- Constant *MaxAmt = ConstantInt::get(SrcTy, AWidth - 1, false);
- Constant *ShAmt = ConstantExpr::getUMin(C, MaxAmt);
- ShAmt = ConstantExpr::getTrunc(ShAmt, A->getType());
- Value *Shift = Builder.CreateAShr(A, ShAmt, "", IsExact);
+ Constant *MaxAmt = ConstantInt::get(SrcTy, AWidth - 1, false);
+ Constant *ShAmt = ConstantExpr::getUMin(C, MaxAmt);
+ ShAmt = ConstantExpr::getTrunc(ShAmt, A->getType());
+ Value *Shift = Builder.CreateAShr(A, ShAmt, "", IsExact);
return CastInst::CreateIntegerCast(Shift, DestTy, true);
}
}
// TODO: Mask high bits with 'and'.
}
- // trunc (*shr (trunc A), C) --> trunc(*shr A, C)
- if (match(Src, m_OneUse(m_Shr(m_Trunc(m_Value(A)), m_Constant(C))))) {
- unsigned MaxShiftAmt = SrcWidth - DestWidth;
-
- // If the shift is small enough, all zero/sign bits created by the shift are
- // removed by the trunc.
- if (match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULE,
- APInt(SrcWidth, MaxShiftAmt)))) {
- auto *OldShift = cast<Instruction>(Src);
- bool IsExact = OldShift->isExact();
- auto *ShAmt = ConstantExpr::getIntegerCast(C, A->getType(), true);
- ShAmt = Constant::mergeUndefsWith(ShAmt, C);
- Value *Shift =
- OldShift->getOpcode() == Instruction::AShr
- ? Builder.CreateAShr(A, ShAmt, OldShift->getName(), IsExact)
- : Builder.CreateLShr(A, ShAmt, OldShift->getName(), IsExact);
- return CastInst::CreateTruncOrBitCast(Shift, DestTy);
- }
- }
-
+ // trunc (*shr (trunc A), C) --> trunc(*shr A, C)
+ if (match(Src, m_OneUse(m_Shr(m_Trunc(m_Value(A)), m_Constant(C))))) {
+ unsigned MaxShiftAmt = SrcWidth - DestWidth;
+
+ // If the shift is small enough, all zero/sign bits created by the shift are
+ // removed by the trunc.
+ if (match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULE,
+ APInt(SrcWidth, MaxShiftAmt)))) {
+ auto *OldShift = cast<Instruction>(Src);
+ bool IsExact = OldShift->isExact();
+ auto *ShAmt = ConstantExpr::getIntegerCast(C, A->getType(), true);
+ ShAmt = Constant::mergeUndefsWith(ShAmt, C);
+ Value *Shift =
+ OldShift->getOpcode() == Instruction::AShr
+ ? Builder.CreateAShr(A, ShAmt, OldShift->getName(), IsExact)
+ : Builder.CreateLShr(A, ShAmt, OldShift->getName(), IsExact);
+ return CastInst::CreateTruncOrBitCast(Shift, DestTy);
+ }
+ }
+
if (Instruction *I = narrowBinOp(Trunc))
return I;
@@ -876,19 +876,19 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
if (Instruction *I = shrinkInsertElt(Trunc, Builder))
return I;
- if (Src->hasOneUse() &&
- (isa<VectorType>(SrcTy) || shouldChangeType(SrcTy, DestTy))) {
+ if (Src->hasOneUse() &&
+ (isa<VectorType>(SrcTy) || shouldChangeType(SrcTy, DestTy))) {
// Transform "trunc (shl X, cst)" -> "shl (trunc X), cst" so long as the
// dest type is native and cst < dest size.
- if (match(Src, m_Shl(m_Value(A), m_Constant(C))) &&
+ if (match(Src, m_Shl(m_Value(A), m_Constant(C))) &&
!match(A, m_Shr(m_Value(), m_Constant()))) {
// Skip shifts of shift by constants. It undoes a combine in
// FoldShiftByConstant and is the extend in reg pattern.
- APInt Threshold = APInt(C->getType()->getScalarSizeInBits(), DestWidth);
- if (match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, Threshold))) {
+ APInt Threshold = APInt(C->getType()->getScalarSizeInBits(), DestWidth);
+ if (match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, Threshold))) {
Value *NewTrunc = Builder.CreateTrunc(A, DestTy, A->getName() + ".tr");
- return BinaryOperator::Create(Instruction::Shl, NewTrunc,
- ConstantExpr::getTrunc(C, DestTy));
+ return BinaryOperator::Create(Instruction::Shl, NewTrunc,
+ ConstantExpr::getTrunc(C, DestTy));
}
}
}
@@ -905,23 +905,23 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
// --->
// extractelement <8 x i32> (bitcast <4 x i64> %X to <8 x i32>), i32 0
Value *VecOp;
- ConstantInt *Cst;
+ ConstantInt *Cst;
if (match(Src, m_OneUse(m_ExtractElt(m_Value(VecOp), m_ConstantInt(Cst))))) {
auto *VecOpTy = cast<VectorType>(VecOp->getType());
- auto VecElts = VecOpTy->getElementCount();
+ auto VecElts = VecOpTy->getElementCount();
// A badly fit destination size would result in an invalid cast.
if (SrcWidth % DestWidth == 0) {
uint64_t TruncRatio = SrcWidth / DestWidth;
- uint64_t BitCastNumElts = VecElts.getKnownMinValue() * TruncRatio;
+ uint64_t BitCastNumElts = VecElts.getKnownMinValue() * TruncRatio;
uint64_t VecOpIdx = Cst->getZExtValue();
uint64_t NewIdx = DL.isBigEndian() ? (VecOpIdx + 1) * TruncRatio - 1
: VecOpIdx * TruncRatio;
assert(BitCastNumElts <= std::numeric_limits<uint32_t>::max() &&
"overflow 32-bits");
- auto *BitCastTo =
- VectorType::get(DestTy, BitCastNumElts, VecElts.isScalable());
+ auto *BitCastTo =
+ VectorType::get(DestTy, BitCastNumElts, VecElts.isScalable());
Value *BitCast = Builder.CreateBitCast(VecOp, BitCastTo);
return ExtractElementInst::Create(BitCast, Builder.getInt32(NewIdx));
}
@@ -930,8 +930,8 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
return nullptr;
}
-Instruction *InstCombinerImpl::transformZExtICmp(ICmpInst *Cmp, ZExtInst &Zext,
- bool DoTransform) {
+Instruction *InstCombinerImpl::transformZExtICmp(ICmpInst *Cmp, ZExtInst &Zext,
+ bool DoTransform) {
// If we are just checking for a icmp eq of a single bit and zext'ing it
// to an integer, then shift the bit to the appropriate place and then
// cast to integer to avoid the comparison.
@@ -1067,7 +1067,7 @@ Instruction *InstCombinerImpl::transformZExtICmp(ICmpInst *Cmp, ZExtInst &Zext,
///
/// This function works on both vectors and scalars.
static bool canEvaluateZExtd(Value *V, Type *Ty, unsigned &BitsToClear,
- InstCombinerImpl &IC, Instruction *CxtI) {
+ InstCombinerImpl &IC, Instruction *CxtI) {
BitsToClear = 0;
if (canAlwaysEvaluateInType(V, Ty))
return true;
@@ -1172,7 +1172,7 @@ static bool canEvaluateZExtd(Value *V, Type *Ty, unsigned &BitsToClear,
}
}
-Instruction *InstCombinerImpl::visitZExt(ZExtInst &CI) {
+Instruction *InstCombinerImpl::visitZExt(ZExtInst &CI) {
// If this zero extend is only used by a truncate, let the truncate be
// eliminated before we try to optimize this zext.
if (CI.hasOneUse() && isa<TruncInst>(CI.user_back()))
@@ -1270,7 +1270,7 @@ Instruction *InstCombinerImpl::visitZExt(ZExtInst &CI) {
ICmpInst *LHS = dyn_cast<ICmpInst>(SrcI->getOperand(0));
ICmpInst *RHS = dyn_cast<ICmpInst>(SrcI->getOperand(1));
if (LHS && RHS && LHS->hasOneUse() && RHS->hasOneUse() &&
- LHS->getOperand(0)->getType() == RHS->getOperand(0)->getType() &&
+ LHS->getOperand(0)->getType() == RHS->getOperand(0)->getType() &&
(transformZExtICmp(LHS, CI, false) ||
transformZExtICmp(RHS, CI, false))) {
// zext (or icmp, icmp) -> or (zext icmp), (zext icmp)
@@ -1311,8 +1311,8 @@ Instruction *InstCombinerImpl::visitZExt(ZExtInst &CI) {
}
/// Transform (sext icmp) to bitwise / integer operations to eliminate the icmp.
-Instruction *InstCombinerImpl::transformSExtICmp(ICmpInst *ICI,
- Instruction &CI) {
+Instruction *InstCombinerImpl::transformSExtICmp(ICmpInst *ICI,
+ Instruction &CI) {
Value *Op0 = ICI->getOperand(0), *Op1 = ICI->getOperand(1);
ICmpInst::Predicate Pred = ICI->getPredicate();
@@ -1448,7 +1448,7 @@ static bool canEvaluateSExtd(Value *V, Type *Ty) {
return false;
}
-Instruction *InstCombinerImpl::visitSExt(SExtInst &CI) {
+Instruction *InstCombinerImpl::visitSExt(SExtInst &CI) {
// If this sign extend is only used by a truncate, let the truncate be
// eliminated before we try to optimize this sext.
if (CI.hasOneUse() && isa<TruncInst>(CI.user_back()))
@@ -1511,28 +1511,28 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &CI) {
// for a truncate. If the source and dest are the same type, eliminate the
// trunc and extend and just do shifts. For example, turn:
// %a = trunc i32 %i to i8
- // %b = shl i8 %a, C
- // %c = ashr i8 %b, C
+ // %b = shl i8 %a, C
+ // %c = ashr i8 %b, C
// %d = sext i8 %c to i32
// into:
- // %a = shl i32 %i, 32-(8-C)
- // %d = ashr i32 %a, 32-(8-C)
+ // %a = shl i32 %i, 32-(8-C)
+ // %d = ashr i32 %a, 32-(8-C)
Value *A = nullptr;
// TODO: Eventually this could be subsumed by EvaluateInDifferentType.
Constant *BA = nullptr, *CA = nullptr;
if (match(Src, m_AShr(m_Shl(m_Trunc(m_Value(A)), m_Constant(BA)),
m_Constant(CA))) &&
- BA->isElementWiseEqual(CA) && A->getType() == DestTy) {
- Constant *WideCurrShAmt = ConstantExpr::getSExt(CA, DestTy);
- Constant *NumLowbitsLeft = ConstantExpr::getSub(
- ConstantInt::get(DestTy, SrcTy->getScalarSizeInBits()), WideCurrShAmt);
- Constant *NewShAmt = ConstantExpr::getSub(
- ConstantInt::get(DestTy, DestTy->getScalarSizeInBits()),
- NumLowbitsLeft);
- NewShAmt =
- Constant::mergeUndefsWith(Constant::mergeUndefsWith(NewShAmt, BA), CA);
- A = Builder.CreateShl(A, NewShAmt, CI.getName());
- return BinaryOperator::CreateAShr(A, NewShAmt);
+ BA->isElementWiseEqual(CA) && A->getType() == DestTy) {
+ Constant *WideCurrShAmt = ConstantExpr::getSExt(CA, DestTy);
+ Constant *NumLowbitsLeft = ConstantExpr::getSub(
+ ConstantInt::get(DestTy, SrcTy->getScalarSizeInBits()), WideCurrShAmt);
+ Constant *NewShAmt = ConstantExpr::getSub(
+ ConstantInt::get(DestTy, DestTy->getScalarSizeInBits()),
+ NumLowbitsLeft);
+ NewShAmt =
+ Constant::mergeUndefsWith(Constant::mergeUndefsWith(NewShAmt, BA), CA);
+ A = Builder.CreateShl(A, NewShAmt, CI.getName());
+ return BinaryOperator::CreateAShr(A, NewShAmt);
}
return nullptr;
@@ -1575,7 +1575,7 @@ static Type *shrinkFPConstantVector(Value *V) {
Type *MinType = nullptr;
- unsigned NumElts = cast<FixedVectorType>(CVVTy)->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(CVVTy)->getNumElements();
for (unsigned i = 0; i != NumElts; ++i) {
auto *CFP = dyn_cast_or_null<ConstantFP>(CV->getAggregateElement(i));
if (!CFP)
@@ -1656,7 +1656,7 @@ static bool isKnownExactCastIntToFP(CastInst &I) {
return false;
}
-Instruction *InstCombinerImpl::visitFPTrunc(FPTruncInst &FPT) {
+Instruction *InstCombinerImpl::visitFPTrunc(FPTruncInst &FPT) {
if (Instruction *I = commonCastTransforms(FPT))
return I;
@@ -1840,7 +1840,7 @@ Instruction *InstCombinerImpl::visitFPTrunc(FPTruncInst &FPT) {
return nullptr;
}
-Instruction *InstCombinerImpl::visitFPExt(CastInst &FPExt) {
+Instruction *InstCombinerImpl::visitFPExt(CastInst &FPExt) {
// If the source operand is a cast from integer to FP and known exact, then
// cast the integer operand directly to the destination type.
Type *Ty = FPExt.getType();
@@ -1858,7 +1858,7 @@ Instruction *InstCombinerImpl::visitFPExt(CastInst &FPExt) {
/// This is safe if the intermediate type has enough bits in its mantissa to
/// accurately represent all values of X. For example, this won't work with
/// i64 -> float -> i64.
-Instruction *InstCombinerImpl::foldItoFPtoI(CastInst &FI) {
+Instruction *InstCombinerImpl::foldItoFPtoI(CastInst &FI) {
if (!isa<UIToFPInst>(FI.getOperand(0)) && !isa<SIToFPInst>(FI.getOperand(0)))
return nullptr;
@@ -1898,29 +1898,29 @@ Instruction *InstCombinerImpl::foldItoFPtoI(CastInst &FI) {
return replaceInstUsesWith(FI, X);
}
-Instruction *InstCombinerImpl::visitFPToUI(FPToUIInst &FI) {
+Instruction *InstCombinerImpl::visitFPToUI(FPToUIInst &FI) {
if (Instruction *I = foldItoFPtoI(FI))
return I;
return commonCastTransforms(FI);
}
-Instruction *InstCombinerImpl::visitFPToSI(FPToSIInst &FI) {
+Instruction *InstCombinerImpl::visitFPToSI(FPToSIInst &FI) {
if (Instruction *I = foldItoFPtoI(FI))
return I;
return commonCastTransforms(FI);
}
-Instruction *InstCombinerImpl::visitUIToFP(CastInst &CI) {
+Instruction *InstCombinerImpl::visitUIToFP(CastInst &CI) {
return commonCastTransforms(CI);
}
-Instruction *InstCombinerImpl::visitSIToFP(CastInst &CI) {
+Instruction *InstCombinerImpl::visitSIToFP(CastInst &CI) {
return commonCastTransforms(CI);
}
-Instruction *InstCombinerImpl::visitIntToPtr(IntToPtrInst &CI) {
+Instruction *InstCombinerImpl::visitIntToPtr(IntToPtrInst &CI) {
// If the source integer type is not the intptr_t type for this target, do a
// trunc or zext to the intptr_t type, then inttoptr of it. This allows the
// cast to be exposed to other transforms.
@@ -1943,7 +1943,7 @@ Instruction *InstCombinerImpl::visitIntToPtr(IntToPtrInst &CI) {
}
/// Implement the transforms for cast of pointer (bitcast/ptrtoint)
-Instruction *InstCombinerImpl::commonPointerCastTransforms(CastInst &CI) {
+Instruction *InstCombinerImpl::commonPointerCastTransforms(CastInst &CI) {
Value *Src = CI.getOperand(0);
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Src)) {
@@ -1965,37 +1965,37 @@ Instruction *InstCombinerImpl::commonPointerCastTransforms(CastInst &CI) {
return commonCastTransforms(CI);
}
-Instruction *InstCombinerImpl::visitPtrToInt(PtrToIntInst &CI) {
+Instruction *InstCombinerImpl::visitPtrToInt(PtrToIntInst &CI) {
// If the destination integer type is not the intptr_t type for this target,
// do a ptrtoint to intptr_t then do a trunc or zext. This allows the cast
// to be exposed to other transforms.
- Value *SrcOp = CI.getPointerOperand();
+ Value *SrcOp = CI.getPointerOperand();
Type *Ty = CI.getType();
unsigned AS = CI.getPointerAddressSpace();
- unsigned TySize = Ty->getScalarSizeInBits();
- unsigned PtrSize = DL.getPointerSizeInBits(AS);
- if (TySize != PtrSize) {
- Type *IntPtrTy = DL.getIntPtrType(CI.getContext(), AS);
- // Handle vectors of pointers.
- if (auto *VecTy = dyn_cast<VectorType>(Ty))
- IntPtrTy = VectorType::get(IntPtrTy, VecTy->getElementCount());
-
- Value *P = Builder.CreatePtrToInt(SrcOp, IntPtrTy);
- return CastInst::CreateIntegerCast(P, Ty, /*isSigned=*/false);
- }
-
- Value *Vec, *Scalar, *Index;
- if (match(SrcOp, m_OneUse(m_InsertElt(m_IntToPtr(m_Value(Vec)),
- m_Value(Scalar), m_Value(Index)))) &&
- Vec->getType() == Ty) {
- assert(Vec->getType()->getScalarSizeInBits() == PtrSize && "Wrong type");
- // Convert the scalar to int followed by insert to eliminate one cast:
- // p2i (ins (i2p Vec), Scalar, Index --> ins Vec, (p2i Scalar), Index
- Value *NewCast = Builder.CreatePtrToInt(Scalar, Ty->getScalarType());
- return InsertElementInst::Create(Vec, NewCast, Index);
- }
-
- return commonPointerCastTransforms(CI);
+ unsigned TySize = Ty->getScalarSizeInBits();
+ unsigned PtrSize = DL.getPointerSizeInBits(AS);
+ if (TySize != PtrSize) {
+ Type *IntPtrTy = DL.getIntPtrType(CI.getContext(), AS);
+ // Handle vectors of pointers.
+ if (auto *VecTy = dyn_cast<VectorType>(Ty))
+ IntPtrTy = VectorType::get(IntPtrTy, VecTy->getElementCount());
+
+ Value *P = Builder.CreatePtrToInt(SrcOp, IntPtrTy);
+ return CastInst::CreateIntegerCast(P, Ty, /*isSigned=*/false);
+ }
+
+ Value *Vec, *Scalar, *Index;
+ if (match(SrcOp, m_OneUse(m_InsertElt(m_IntToPtr(m_Value(Vec)),
+ m_Value(Scalar), m_Value(Index)))) &&
+ Vec->getType() == Ty) {
+ assert(Vec->getType()->getScalarSizeInBits() == PtrSize && "Wrong type");
+ // Convert the scalar to int followed by insert to eliminate one cast:
+ // p2i (ins (i2p Vec), Scalar, Index --> ins Vec, (p2i Scalar), Index
+ Value *NewCast = Builder.CreatePtrToInt(Scalar, Ty->getScalarType());
+ return InsertElementInst::Create(Vec, NewCast, Index);
+ }
+
+ return commonPointerCastTransforms(CI);
}
/// This input value (which is known to have vector type) is being zero extended
@@ -2014,9 +2014,9 @@ Instruction *InstCombinerImpl::visitPtrToInt(PtrToIntInst &CI) {
/// Try to replace it with a shuffle (and vector/vector bitcast) if possible.
///
/// The source and destination vector types may have different element types.
-static Instruction *
-optimizeVectorResizeWithIntegerBitCasts(Value *InVal, VectorType *DestTy,
- InstCombinerImpl &IC) {
+static Instruction *
+optimizeVectorResizeWithIntegerBitCasts(Value *InVal, VectorType *DestTy,
+ InstCombinerImpl &IC) {
// We can only do this optimization if the output is a multiple of the input
// element size, or the input is a multiple of the output element size.
// Convert the input type to have the same element type as the output.
@@ -2032,14 +2032,14 @@ optimizeVectorResizeWithIntegerBitCasts(Value *InVal, VectorType *DestTy,
return nullptr;
SrcTy =
- FixedVectorType::get(DestTy->getElementType(),
- cast<FixedVectorType>(SrcTy)->getNumElements());
+ FixedVectorType::get(DestTy->getElementType(),
+ cast<FixedVectorType>(SrcTy)->getNumElements());
InVal = IC.Builder.CreateBitCast(InVal, SrcTy);
}
bool IsBigEndian = IC.getDataLayout().isBigEndian();
- unsigned SrcElts = cast<FixedVectorType>(SrcTy)->getNumElements();
- unsigned DestElts = cast<FixedVectorType>(DestTy)->getNumElements();
+ unsigned SrcElts = cast<FixedVectorType>(SrcTy)->getNumElements();
+ unsigned DestElts = cast<FixedVectorType>(DestTy)->getNumElements();
assert(SrcElts != DestElts && "Element counts should be different.");
@@ -2217,8 +2217,8 @@ static bool collectInsertionElements(Value *V, unsigned Shift,
///
/// Into two insertelements that do "buildvector{%inc, %inc5}".
static Value *optimizeIntegerToVectorInsertions(BitCastInst &CI,
- InstCombinerImpl &IC) {
- auto *DestVecTy = cast<FixedVectorType>(CI.getType());
+ InstCombinerImpl &IC) {
+ auto *DestVecTy = cast<FixedVectorType>(CI.getType());
Value *IntInput = CI.getOperand(0);
SmallVector<Value*, 8> Elements(DestVecTy->getNumElements());
@@ -2246,7 +2246,7 @@ static Value *optimizeIntegerToVectorInsertions(BitCastInst &CI,
/// vectors better than bitcasts of scalars because vector registers are
/// usually not type-specific like scalar integer or scalar floating-point.
static Instruction *canonicalizeBitCastExtElt(BitCastInst &BitCast,
- InstCombinerImpl &IC) {
+ InstCombinerImpl &IC) {
// TODO: Create and use a pattern matcher for ExtractElementInst.
auto *ExtElt = dyn_cast<ExtractElementInst>(BitCast.getOperand(0));
if (!ExtElt || !ExtElt->hasOneUse())
@@ -2258,7 +2258,7 @@ static Instruction *canonicalizeBitCastExtElt(BitCastInst &BitCast,
if (!VectorType::isValidElementType(DestType))
return nullptr;
- auto *NewVecType = VectorType::get(DestType, ExtElt->getVectorOperandType());
+ auto *NewVecType = VectorType::get(DestType, ExtElt->getVectorOperandType());
auto *NewBC = IC.Builder.CreateBitCast(ExtElt->getVectorOperand(),
NewVecType, "bc");
return ExtractElementInst::Create(NewBC, ExtElt->getIndexOperand());
@@ -2321,10 +2321,10 @@ static Instruction *foldBitCastSelect(BitCastInst &BitCast,
// A vector select must maintain the same number of elements in its operands.
Type *CondTy = Cond->getType();
Type *DestTy = BitCast.getType();
- if (auto *CondVTy = dyn_cast<VectorType>(CondTy))
- if (!DestTy->isVectorTy() ||
- CondVTy->getElementCount() !=
- cast<VectorType>(DestTy)->getElementCount())
+ if (auto *CondVTy = dyn_cast<VectorType>(CondTy))
+ if (!DestTy->isVectorTy() ||
+ CondVTy->getElementCount() !=
+ cast<VectorType>(DestTy)->getElementCount())
return nullptr;
// FIXME: This transform is restricted from changing the select between
@@ -2370,8 +2370,8 @@ static bool hasStoreUsersOnly(CastInst &CI) {
///
/// All the related PHI nodes can be replaced by new PHI nodes with type A.
/// The uses of \p CI can be changed to the new PHI node corresponding to \p PN.
-Instruction *InstCombinerImpl::optimizeBitCastFromPhi(CastInst &CI,
- PHINode *PN) {
+Instruction *InstCombinerImpl::optimizeBitCastFromPhi(CastInst &CI,
+ PHINode *PN) {
// BitCast used by Store can be handled in InstCombineLoadStoreAlloca.cpp.
if (hasStoreUsersOnly(CI))
return nullptr;
@@ -2501,7 +2501,7 @@ Instruction *InstCombinerImpl::optimizeBitCastFromPhi(CastInst &CI,
Instruction *RetVal = nullptr;
for (auto *OldPN : OldPhiNodes) {
PHINode *NewPN = NewPNodes[OldPN];
- for (User *V : make_early_inc_range(OldPN->users())) {
+ for (User *V : make_early_inc_range(OldPN->users())) {
if (auto *SI = dyn_cast<StoreInst>(V)) {
assert(SI->isSimple() && SI->getOperand(0) == OldPN);
Builder.SetInsertPoint(SI);
@@ -2521,7 +2521,7 @@ Instruction *InstCombinerImpl::optimizeBitCastFromPhi(CastInst &CI,
if (BCI == &CI)
RetVal = I;
} else if (auto *PHI = dyn_cast<PHINode>(V)) {
- assert(OldPhiNodes.contains(PHI));
+ assert(OldPhiNodes.contains(PHI));
(void) PHI;
} else {
llvm_unreachable("all uses should be handled");
@@ -2532,7 +2532,7 @@ Instruction *InstCombinerImpl::optimizeBitCastFromPhi(CastInst &CI,
return RetVal;
}
-Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) {
+Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) {
// If the operands are integer typed then apply the integer transforms,
// otherwise just apply the common ones.
Value *Src = CI.getOperand(0);
@@ -2656,11 +2656,11 @@ Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) {
// a bitcast to a vector with the same # elts.
Value *ShufOp0 = Shuf->getOperand(0);
Value *ShufOp1 = Shuf->getOperand(1);
- auto ShufElts = cast<VectorType>(Shuf->getType())->getElementCount();
- auto SrcVecElts = cast<VectorType>(ShufOp0->getType())->getElementCount();
+ auto ShufElts = cast<VectorType>(Shuf->getType())->getElementCount();
+ auto SrcVecElts = cast<VectorType>(ShufOp0->getType())->getElementCount();
if (Shuf->hasOneUse() && DestTy->isVectorTy() &&
- cast<VectorType>(DestTy)->getElementCount() == ShufElts &&
- ShufElts == SrcVecElts) {
+ cast<VectorType>(DestTy)->getElementCount() == ShufElts &&
+ ShufElts == SrcVecElts) {
BitCastInst *Tmp;
// If either of the operands is a cast from CI.getType(), then
// evaluating the shuffle in the casted destination's type will allow
@@ -2683,9 +2683,9 @@ Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) {
// TODO: We should match the related pattern for bitreverse.
if (DestTy->isIntegerTy() &&
DL.isLegalInteger(DestTy->getScalarSizeInBits()) &&
- SrcTy->getScalarSizeInBits() == 8 &&
- ShufElts.getKnownMinValue() % 2 == 0 && Shuf->hasOneUse() &&
- Shuf->isReverse()) {
+ SrcTy->getScalarSizeInBits() == 8 &&
+ ShufElts.getKnownMinValue() % 2 == 0 && Shuf->hasOneUse() &&
+ Shuf->isReverse()) {
assert(ShufOp0->getType() == SrcTy && "Unexpected shuffle mask");
assert(isa<UndefValue>(ShufOp1) && "Unexpected shuffle op");
Function *Bswap =
@@ -2714,7 +2714,7 @@ Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) {
return commonCastTransforms(CI);
}
-Instruction *InstCombinerImpl::visitAddrSpaceCast(AddrSpaceCastInst &CI) {
+Instruction *InstCombinerImpl::visitAddrSpaceCast(AddrSpaceCastInst &CI) {
// If the destination pointer element type is not the same as the source's
// first do a bitcast to the destination type, and then the addrspacecast.
// This allows the cast to be exposed to other transforms.
@@ -2725,9 +2725,9 @@ Instruction *InstCombinerImpl::visitAddrSpaceCast(AddrSpaceCastInst &CI) {
Type *DestElemTy = DestTy->getElementType();
if (SrcTy->getElementType() != DestElemTy) {
Type *MidTy = PointerType::get(DestElemTy, SrcTy->getAddressSpace());
- // Handle vectors of pointers.
- if (VectorType *VT = dyn_cast<VectorType>(CI.getType()))
- MidTy = VectorType::get(MidTy, VT->getElementCount());
+ // Handle vectors of pointers.
+ if (VectorType *VT = dyn_cast<VectorType>(CI.getType()))
+ MidTy = VectorType::get(MidTy, VT->getElementCount());
Value *NewBitCast = Builder.CreateBitCast(Src, MidTy);
return new AddrSpaceCastInst(NewBitCast, CI.getType());
diff --git a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCompares.cpp b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 50bdd66103..cd9a036179 100644
--- a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -24,7 +24,7 @@
#include "llvm/IR/PatternMatch.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/KnownBits.h"
-#include "llvm/Transforms/InstCombine/InstCombiner.h"
+#include "llvm/Transforms/InstCombine/InstCombiner.h"
using namespace llvm;
using namespace PatternMatch;
@@ -104,10 +104,10 @@ static bool isSignTest(ICmpInst::Predicate &Pred, const APInt &C) {
///
/// If AndCst is non-null, then the loaded value is masked with that constant
/// before doing the comparison. This handles cases like "A[i]&4 == 0".
-Instruction *
-InstCombinerImpl::foldCmpLoadFromIndexedGlobal(GetElementPtrInst *GEP,
- GlobalVariable *GV, CmpInst &ICI,
- ConstantInt *AndCst) {
+Instruction *
+InstCombinerImpl::foldCmpLoadFromIndexedGlobal(GetElementPtrInst *GEP,
+ GlobalVariable *GV, CmpInst &ICI,
+ ConstantInt *AndCst) {
Constant *Init = GV->getInitializer();
if (!isa<ConstantArray>(Init) && !isa<ConstantDataArray>(Init))
return nullptr;
@@ -275,7 +275,7 @@ InstCombinerImpl::foldCmpLoadFromIndexedGlobal(GetElementPtrInst *GEP,
if (!GEP->isInBounds()) {
Type *IntPtrTy = DL.getIntPtrType(GEP->getType());
unsigned PtrSize = IntPtrTy->getIntegerBitWidth();
- if (Idx->getType()->getPrimitiveSizeInBits().getFixedSize() > PtrSize)
+ if (Idx->getType()->getPrimitiveSizeInBits().getFixedSize() > PtrSize)
Idx = Builder.CreateTrunc(Idx, IntPtrTy);
}
@@ -384,7 +384,7 @@ InstCombinerImpl::foldCmpLoadFromIndexedGlobal(GetElementPtrInst *GEP,
///
/// If we can't emit an optimized form for this expression, this returns null.
///
-static Value *evaluateGEPOffsetExpression(User *GEP, InstCombinerImpl &IC,
+static Value *evaluateGEPOffsetExpression(User *GEP, InstCombinerImpl &IC,
const DataLayout &DL) {
gep_type_iterator GTI = gep_type_begin(GEP);
@@ -448,8 +448,8 @@ static Value *evaluateGEPOffsetExpression(User *GEP, InstCombinerImpl &IC,
// Cast to intptrty in case a truncation occurs. If an extension is needed,
// we don't need to bother extending: the extension won't affect where the
// computation crosses zero.
- if (VariableIdx->getType()->getPrimitiveSizeInBits().getFixedSize() >
- IntPtrWidth) {
+ if (VariableIdx->getType()->getPrimitiveSizeInBits().getFixedSize() >
+ IntPtrWidth) {
VariableIdx = IC.Builder.CreateTrunc(VariableIdx, IntPtrTy);
}
return VariableIdx;
@@ -502,7 +502,7 @@ static bool canRewriteGEPAsOffset(Value *Start, Value *Base,
Value *V = WorkList.back();
- if (Explored.contains(V)) {
+ if (Explored.contains(V)) {
WorkList.pop_back();
continue;
}
@@ -514,7 +514,7 @@ static bool canRewriteGEPAsOffset(Value *Start, Value *Base,
return false;
if (isa<IntToPtrInst>(V) || isa<PtrToIntInst>(V)) {
- auto *CI = cast<CastInst>(V);
+ auto *CI = cast<CastInst>(V);
if (!CI->isNoopCast(DL))
return false;
@@ -804,9 +804,9 @@ static Instruction *transformToIndexedCompare(GEPOperator *GEPLHS, Value *RHS,
/// Fold comparisons between a GEP instruction and something else. At this point
/// we know that the GEP is on the LHS of the comparison.
-Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
- ICmpInst::Predicate Cond,
- Instruction &I) {
+Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
+ ICmpInst::Predicate Cond,
+ Instruction &I) {
// Don't transform signed compares of GEPs into index compares. Even if the
// GEP is inbounds, the final add of the base pointer can have signed overflow
// and would change the result of the icmp.
@@ -860,8 +860,8 @@ Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
// For vectors, we apply the same reasoning on a per-lane basis.
auto *Base = GEPLHS->getPointerOperand();
if (GEPLHS->getType()->isVectorTy() && Base->getType()->isPointerTy()) {
- auto EC = cast<VectorType>(GEPLHS->getType())->getElementCount();
- Base = Builder.CreateVectorSplat(EC, Base);
+ auto EC = cast<VectorType>(GEPLHS->getType())->getElementCount();
+ Base = Builder.CreateVectorSplat(EC, Base);
}
return new ICmpInst(Cond, Base,
ConstantExpr::getPointerBitCastOrAddrSpaceCast(
@@ -904,8 +904,8 @@ Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
Type *LHSIndexTy = LOffset->getType();
Type *RHSIndexTy = ROffset->getType();
if (LHSIndexTy != RHSIndexTy) {
- if (LHSIndexTy->getPrimitiveSizeInBits().getFixedSize() <
- RHSIndexTy->getPrimitiveSizeInBits().getFixedSize()) {
+ if (LHSIndexTy->getPrimitiveSizeInBits().getFixedSize() <
+ RHSIndexTy->getPrimitiveSizeInBits().getFixedSize()) {
ROffset = Builder.CreateTrunc(ROffset, LHSIndexTy);
} else
LOffset = Builder.CreateTrunc(LOffset, RHSIndexTy);
@@ -984,9 +984,9 @@ Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
return transformToIndexedCompare(GEPLHS, RHS, Cond, DL);
}
-Instruction *InstCombinerImpl::foldAllocaCmp(ICmpInst &ICI,
- const AllocaInst *Alloca,
- const Value *Other) {
+Instruction *InstCombinerImpl::foldAllocaCmp(ICmpInst &ICI,
+ const AllocaInst *Alloca,
+ const Value *Other) {
assert(ICI.isEquality() && "Cannot fold non-equality comparison.");
// It would be tempting to fold away comparisons between allocas and any
@@ -1062,8 +1062,8 @@ Instruction *InstCombinerImpl::foldAllocaCmp(ICmpInst &ICI,
}
/// Fold "icmp pred (X+C), X".
-Instruction *InstCombinerImpl::foldICmpAddOpConst(Value *X, const APInt &C,
- ICmpInst::Predicate Pred) {
+Instruction *InstCombinerImpl::foldICmpAddOpConst(Value *X, const APInt &C,
+ ICmpInst::Predicate Pred) {
// From this point on, we know that (X+C <= X) --> (X+C < X) because C != 0,
// so the values can never be equal. Similarly for all other "or equals"
// operators.
@@ -1112,9 +1112,9 @@ Instruction *InstCombinerImpl::foldICmpAddOpConst(Value *X, const APInt &C,
/// Handle "(icmp eq/ne (ashr/lshr AP2, A), AP1)" ->
/// (icmp eq/ne A, Log2(AP2/AP1)) ->
/// (icmp eq/ne A, Log2(AP2) - Log2(AP1)).
-Instruction *InstCombinerImpl::foldICmpShrConstConst(ICmpInst &I, Value *A,
- const APInt &AP1,
- const APInt &AP2) {
+Instruction *InstCombinerImpl::foldICmpShrConstConst(ICmpInst &I, Value *A,
+ const APInt &AP1,
+ const APInt &AP2) {
assert(I.isEquality() && "Cannot fold icmp gt/lt");
auto getICmp = [&I](CmpInst::Predicate Pred, Value *LHS, Value *RHS) {
@@ -1171,9 +1171,9 @@ Instruction *InstCombinerImpl::foldICmpShrConstConst(ICmpInst &I, Value *A,
/// Handle "(icmp eq/ne (shl AP2, A), AP1)" ->
/// (icmp eq/ne A, TrailingZeros(AP1) - TrailingZeros(AP2)).
-Instruction *InstCombinerImpl::foldICmpShlConstConst(ICmpInst &I, Value *A,
- const APInt &AP1,
- const APInt &AP2) {
+Instruction *InstCombinerImpl::foldICmpShlConstConst(ICmpInst &I, Value *A,
+ const APInt &AP1,
+ const APInt &AP2) {
assert(I.isEquality() && "Cannot fold icmp gt/lt");
auto getICmp = [&I](CmpInst::Predicate Pred, Value *LHS, Value *RHS) {
@@ -1217,7 +1217,7 @@ Instruction *InstCombinerImpl::foldICmpShlConstConst(ICmpInst &I, Value *A,
///
static Instruction *processUGT_ADDCST_ADD(ICmpInst &I, Value *A, Value *B,
ConstantInt *CI2, ConstantInt *CI1,
- InstCombinerImpl &IC) {
+ InstCombinerImpl &IC) {
// The transformation we're trying to do here is to transform this into an
// llvm.sadd.with.overflow. To do this, we have to replace the original add
// with a narrower add, and discard the add-with-constant that is part of the
@@ -1303,7 +1303,7 @@ static Instruction *processUGT_ADDCST_ADD(ICmpInst &I, Value *A, Value *B,
/// icmp eq/ne (urem/srem %x, %y), 0
/// iff %y is a power-of-two, we can replace this with a bit test:
/// icmp eq/ne (and %x, (add %y, -1)), 0
-Instruction *InstCombinerImpl::foldIRemByPowerOfTwoToBitTest(ICmpInst &I) {
+Instruction *InstCombinerImpl::foldIRemByPowerOfTwoToBitTest(ICmpInst &I) {
// This fold is only valid for equality predicates.
if (!I.isEquality())
return nullptr;
@@ -1322,7 +1322,7 @@ Instruction *InstCombinerImpl::foldIRemByPowerOfTwoToBitTest(ICmpInst &I) {
/// Fold equality-comparison between zero and any (maybe truncated) right-shift
/// by one-less-than-bitwidth into a sign test on the original value.
-Instruction *InstCombinerImpl::foldSignBitTest(ICmpInst &I) {
+Instruction *InstCombinerImpl::foldSignBitTest(ICmpInst &I) {
Instruction *Val;
ICmpInst::Predicate Pred;
if (!I.isEquality() || !match(&I, m_ICmp(Pred, m_Instruction(Val), m_Zero())))
@@ -1353,7 +1353,7 @@ Instruction *InstCombinerImpl::foldSignBitTest(ICmpInst &I) {
}
// Handle icmp pred X, 0
-Instruction *InstCombinerImpl::foldICmpWithZero(ICmpInst &Cmp) {
+Instruction *InstCombinerImpl::foldICmpWithZero(ICmpInst &Cmp) {
CmpInst::Predicate Pred = Cmp.getPredicate();
if (!match(Cmp.getOperand(1), m_Zero()))
return nullptr;
@@ -1394,7 +1394,7 @@ Instruction *InstCombinerImpl::foldICmpWithZero(ICmpInst &Cmp) {
/// should be moved to some other helper and extended as noted below (it is also
/// possible that code has been made unnecessary - do we canonicalize IR to
/// overflow/saturating intrinsics or not?).
-Instruction *InstCombinerImpl::foldICmpWithConstant(ICmpInst &Cmp) {
+Instruction *InstCombinerImpl::foldICmpWithConstant(ICmpInst &Cmp) {
// Match the following pattern, which is a common idiom when writing
// overflow-safe integer arithmetic functions. The source performs an addition
// in wider type and explicitly checks for overflow using comparisons against
@@ -1440,7 +1440,7 @@ Instruction *InstCombinerImpl::foldICmpWithConstant(ICmpInst &Cmp) {
}
/// Canonicalize icmp instructions based on dominating conditions.
-Instruction *InstCombinerImpl::foldICmpWithDominatingICmp(ICmpInst &Cmp) {
+Instruction *InstCombinerImpl::foldICmpWithDominatingICmp(ICmpInst &Cmp) {
// This is a cheap/incomplete check for dominance - just match a single
// predecessor with a conditional branch.
BasicBlock *CmpBB = Cmp.getParent();
@@ -1510,9 +1510,9 @@ Instruction *InstCombinerImpl::foldICmpWithDominatingICmp(ICmpInst &Cmp) {
}
/// Fold icmp (trunc X, Y), C.
-Instruction *InstCombinerImpl::foldICmpTruncConstant(ICmpInst &Cmp,
- TruncInst *Trunc,
- const APInt &C) {
+Instruction *InstCombinerImpl::foldICmpTruncConstant(ICmpInst &Cmp,
+ TruncInst *Trunc,
+ const APInt &C) {
ICmpInst::Predicate Pred = Cmp.getPredicate();
Value *X = Trunc->getOperand(0);
if (C.isOneValue() && C.getBitWidth() > 1) {
@@ -1543,9 +1543,9 @@ Instruction *InstCombinerImpl::foldICmpTruncConstant(ICmpInst &Cmp,
}
/// Fold icmp (xor X, Y), C.
-Instruction *InstCombinerImpl::foldICmpXorConstant(ICmpInst &Cmp,
- BinaryOperator *Xor,
- const APInt &C) {
+Instruction *InstCombinerImpl::foldICmpXorConstant(ICmpInst &Cmp,
+ BinaryOperator *Xor,
+ const APInt &C) {
Value *X = Xor->getOperand(0);
Value *Y = Xor->getOperand(1);
const APInt *XorC;
@@ -1575,13 +1575,13 @@ Instruction *InstCombinerImpl::foldICmpXorConstant(ICmpInst &Cmp,
if (Xor->hasOneUse()) {
// (icmp u/s (xor X SignMask), C) -> (icmp s/u X, (xor C SignMask))
if (!Cmp.isEquality() && XorC->isSignMask()) {
- Pred = Cmp.getFlippedSignednessPredicate();
+ Pred = Cmp.getFlippedSignednessPredicate();
return new ICmpInst(Pred, X, ConstantInt::get(X->getType(), C ^ *XorC));
}
// (icmp u/s (xor X ~SignMask), C) -> (icmp s/u X, (xor C ~SignMask))
if (!Cmp.isEquality() && XorC->isMaxSignedValue()) {
- Pred = Cmp.getFlippedSignednessPredicate();
+ Pred = Cmp.getFlippedSignednessPredicate();
Pred = Cmp.getSwappedPredicate(Pred);
return new ICmpInst(Pred, X, ConstantInt::get(X->getType(), C ^ *XorC));
}
@@ -1610,10 +1610,10 @@ Instruction *InstCombinerImpl::foldICmpXorConstant(ICmpInst &Cmp,
}
/// Fold icmp (and (sh X, Y), C2), C1.
-Instruction *InstCombinerImpl::foldICmpAndShift(ICmpInst &Cmp,
- BinaryOperator *And,
- const APInt &C1,
- const APInt &C2) {
+Instruction *InstCombinerImpl::foldICmpAndShift(ICmpInst &Cmp,
+ BinaryOperator *And,
+ const APInt &C1,
+ const APInt &C2) {
BinaryOperator *Shift = dyn_cast<BinaryOperator>(And->getOperand(0));
if (!Shift || !Shift->isShift())
return nullptr;
@@ -1696,9 +1696,9 @@ Instruction *InstCombinerImpl::foldICmpAndShift(ICmpInst &Cmp,
}
/// Fold icmp (and X, C2), C1.
-Instruction *InstCombinerImpl::foldICmpAndConstConst(ICmpInst &Cmp,
- BinaryOperator *And,
- const APInt &C1) {
+Instruction *InstCombinerImpl::foldICmpAndConstConst(ICmpInst &Cmp,
+ BinaryOperator *And,
+ const APInt &C1) {
bool isICMP_NE = Cmp.getPredicate() == ICmpInst::ICMP_NE;
// For vectors: icmp ne (and X, 1), 0 --> trunc X to N x i1
@@ -1804,9 +1804,9 @@ Instruction *InstCombinerImpl::foldICmpAndConstConst(ICmpInst &Cmp,
}
/// Fold icmp (and X, Y), C.
-Instruction *InstCombinerImpl::foldICmpAndConstant(ICmpInst &Cmp,
- BinaryOperator *And,
- const APInt &C) {
+Instruction *InstCombinerImpl::foldICmpAndConstant(ICmpInst &Cmp,
+ BinaryOperator *And,
+ const APInt &C) {
if (Instruction *I = foldICmpAndConstConst(Cmp, And, C))
return I;
@@ -1846,7 +1846,7 @@ Instruction *InstCombinerImpl::foldICmpAndConstant(ICmpInst &Cmp,
if (ExactLogBase2 != -1 && DL.isLegalInteger(ExactLogBase2 + 1)) {
Type *NTy = IntegerType::get(Cmp.getContext(), ExactLogBase2 + 1);
if (auto *AndVTy = dyn_cast<VectorType>(And->getType()))
- NTy = VectorType::get(NTy, AndVTy->getElementCount());
+ NTy = VectorType::get(NTy, AndVTy->getElementCount());
Value *Trunc = Builder.CreateTrunc(X, NTy);
auto NewPred = Cmp.getPredicate() == CmpInst::ICMP_EQ ? CmpInst::ICMP_SGE
: CmpInst::ICMP_SLT;
@@ -1858,9 +1858,9 @@ Instruction *InstCombinerImpl::foldICmpAndConstant(ICmpInst &Cmp,
}
/// Fold icmp (or X, Y), C.
-Instruction *InstCombinerImpl::foldICmpOrConstant(ICmpInst &Cmp,
- BinaryOperator *Or,
- const APInt &C) {
+Instruction *InstCombinerImpl::foldICmpOrConstant(ICmpInst &Cmp,
+ BinaryOperator *Or,
+ const APInt &C) {
ICmpInst::Predicate Pred = Cmp.getPredicate();
if (C.isOneValue()) {
// icmp slt signum(V) 1 --> icmp slt V, 1
@@ -1924,9 +1924,9 @@ Instruction *InstCombinerImpl::foldICmpOrConstant(ICmpInst &Cmp,
}
/// Fold icmp (mul X, Y), C.
-Instruction *InstCombinerImpl::foldICmpMulConstant(ICmpInst &Cmp,
- BinaryOperator *Mul,
- const APInt &C) {
+Instruction *InstCombinerImpl::foldICmpMulConstant(ICmpInst &Cmp,
+ BinaryOperator *Mul,
+ const APInt &C) {
const APInt *MulC;
if (!match(Mul->getOperand(1), m_APInt(MulC)))
return nullptr;
@@ -1941,21 +1941,21 @@ Instruction *InstCombinerImpl::foldICmpMulConstant(ICmpInst &Cmp,
Constant::getNullValue(Mul->getType()));
}
- // If the multiply does not wrap, try to divide the compare constant by the
- // multiplication factor.
- if (Cmp.isEquality() && !MulC->isNullValue()) {
- // (mul nsw X, MulC) == C --> X == C /s MulC
- if (Mul->hasNoSignedWrap() && C.srem(*MulC).isNullValue()) {
- Constant *NewC = ConstantInt::get(Mul->getType(), C.sdiv(*MulC));
- return new ICmpInst(Pred, Mul->getOperand(0), NewC);
- }
- // (mul nuw X, MulC) == C --> X == C /u MulC
- if (Mul->hasNoUnsignedWrap() && C.urem(*MulC).isNullValue()) {
- Constant *NewC = ConstantInt::get(Mul->getType(), C.udiv(*MulC));
- return new ICmpInst(Pred, Mul->getOperand(0), NewC);
- }
- }
-
+ // If the multiply does not wrap, try to divide the compare constant by the
+ // multiplication factor.
+ if (Cmp.isEquality() && !MulC->isNullValue()) {
+ // (mul nsw X, MulC) == C --> X == C /s MulC
+ if (Mul->hasNoSignedWrap() && C.srem(*MulC).isNullValue()) {
+ Constant *NewC = ConstantInt::get(Mul->getType(), C.sdiv(*MulC));
+ return new ICmpInst(Pred, Mul->getOperand(0), NewC);
+ }
+ // (mul nuw X, MulC) == C --> X == C /u MulC
+ if (Mul->hasNoUnsignedWrap() && C.urem(*MulC).isNullValue()) {
+ Constant *NewC = ConstantInt::get(Mul->getType(), C.udiv(*MulC));
+ return new ICmpInst(Pred, Mul->getOperand(0), NewC);
+ }
+ }
+
return nullptr;
}
@@ -2022,9 +2022,9 @@ static Instruction *foldICmpShlOne(ICmpInst &Cmp, Instruction *Shl,
}
/// Fold icmp (shl X, Y), C.
-Instruction *InstCombinerImpl::foldICmpShlConstant(ICmpInst &Cmp,
- BinaryOperator *Shl,
- const APInt &C) {
+Instruction *InstCombinerImpl::foldICmpShlConstant(ICmpInst &Cmp,
+ BinaryOperator *Shl,
+ const APInt &C) {
const APInt *ShiftVal;
if (Cmp.isEquality() && match(Shl->getOperand(0), m_APInt(ShiftVal)))
return foldICmpShlConstConst(Cmp, Shl->getOperand(1), C, *ShiftVal);
@@ -2152,7 +2152,7 @@ Instruction *InstCombinerImpl::foldICmpShlConstant(ICmpInst &Cmp,
DL.isLegalInteger(TypeBits - Amt)) {
Type *TruncTy = IntegerType::get(Cmp.getContext(), TypeBits - Amt);
if (auto *ShVTy = dyn_cast<VectorType>(ShType))
- TruncTy = VectorType::get(TruncTy, ShVTy->getElementCount());
+ TruncTy = VectorType::get(TruncTy, ShVTy->getElementCount());
Constant *NewC =
ConstantInt::get(TruncTy, C.ashr(*ShiftAmt).trunc(TypeBits - Amt));
return new ICmpInst(Pred, Builder.CreateTrunc(X, TruncTy), NewC);
@@ -2162,9 +2162,9 @@ Instruction *InstCombinerImpl::foldICmpShlConstant(ICmpInst &Cmp,
}
/// Fold icmp ({al}shr X, Y), C.
-Instruction *InstCombinerImpl::foldICmpShrConstant(ICmpInst &Cmp,
- BinaryOperator *Shr,
- const APInt &C) {
+Instruction *InstCombinerImpl::foldICmpShrConstant(ICmpInst &Cmp,
+ BinaryOperator *Shr,
+ const APInt &C) {
// An exact shr only shifts out zero bits, so:
// icmp eq/ne (shr X, Y), 0 --> icmp eq/ne X, 0
Value *X = Shr->getOperand(0);
@@ -2210,21 +2210,21 @@ Instruction *InstCombinerImpl::foldICmpShrConstant(ICmpInst &Cmp,
(ShiftedC + 1).ashr(ShAmtVal) == (C + 1))
return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC));
}
-
- // If the compare constant has significant bits above the lowest sign-bit,
- // then convert an unsigned cmp to a test of the sign-bit:
- // (ashr X, ShiftC) u> C --> X s< 0
- // (ashr X, ShiftC) u< C --> X s> -1
- if (C.getBitWidth() > 2 && C.getNumSignBits() <= ShAmtVal) {
- if (Pred == CmpInst::ICMP_UGT) {
- return new ICmpInst(CmpInst::ICMP_SLT, X,
- ConstantInt::getNullValue(ShrTy));
- }
- if (Pred == CmpInst::ICMP_ULT) {
- return new ICmpInst(CmpInst::ICMP_SGT, X,
- ConstantInt::getAllOnesValue(ShrTy));
- }
- }
+
+ // If the compare constant has significant bits above the lowest sign-bit,
+ // then convert an unsigned cmp to a test of the sign-bit:
+ // (ashr X, ShiftC) u> C --> X s< 0
+ // (ashr X, ShiftC) u< C --> X s> -1
+ if (C.getBitWidth() > 2 && C.getNumSignBits() <= ShAmtVal) {
+ if (Pred == CmpInst::ICMP_UGT) {
+ return new ICmpInst(CmpInst::ICMP_SLT, X,
+ ConstantInt::getNullValue(ShrTy));
+ }
+ if (Pred == CmpInst::ICMP_ULT) {
+ return new ICmpInst(CmpInst::ICMP_SGT, X,
+ ConstantInt::getAllOnesValue(ShrTy));
+ }
+ }
} else {
if (Pred == CmpInst::ICMP_ULT || (Pred == CmpInst::ICMP_UGT && IsExact)) {
// icmp ult (lshr X, ShAmtC), C --> icmp ult X, (C << ShAmtC)
@@ -2270,9 +2270,9 @@ Instruction *InstCombinerImpl::foldICmpShrConstant(ICmpInst &Cmp,
return nullptr;
}
-Instruction *InstCombinerImpl::foldICmpSRemConstant(ICmpInst &Cmp,
- BinaryOperator *SRem,
- const APInt &C) {
+Instruction *InstCombinerImpl::foldICmpSRemConstant(ICmpInst &Cmp,
+ BinaryOperator *SRem,
+ const APInt &C) {
// Match an 'is positive' or 'is negative' comparison of remainder by a
// constant power-of-2 value:
// (X % pow2C) sgt/slt 0
@@ -2309,9 +2309,9 @@ Instruction *InstCombinerImpl::foldICmpSRemConstant(ICmpInst &Cmp,
}
/// Fold icmp (udiv X, Y), C.
-Instruction *InstCombinerImpl::foldICmpUDivConstant(ICmpInst &Cmp,
- BinaryOperator *UDiv,
- const APInt &C) {
+Instruction *InstCombinerImpl::foldICmpUDivConstant(ICmpInst &Cmp,
+ BinaryOperator *UDiv,
+ const APInt &C) {
const APInt *C2;
if (!match(UDiv->getOperand(0), m_APInt(C2)))
return nullptr;
@@ -2338,9 +2338,9 @@ Instruction *InstCombinerImpl::foldICmpUDivConstant(ICmpInst &Cmp,
}
/// Fold icmp ({su}div X, Y), C.
-Instruction *InstCombinerImpl::foldICmpDivConstant(ICmpInst &Cmp,
- BinaryOperator *Div,
- const APInt &C) {
+Instruction *InstCombinerImpl::foldICmpDivConstant(ICmpInst &Cmp,
+ BinaryOperator *Div,
+ const APInt &C) {
// Fold: icmp pred ([us]div X, C2), C -> range test
// Fold this div into the comparison, producing a range check.
// Determine, based on the divide type, what the range is being
@@ -2508,9 +2508,9 @@ Instruction *InstCombinerImpl::foldICmpDivConstant(ICmpInst &Cmp,
}
/// Fold icmp (sub X, Y), C.
-Instruction *InstCombinerImpl::foldICmpSubConstant(ICmpInst &Cmp,
- BinaryOperator *Sub,
- const APInt &C) {
+Instruction *InstCombinerImpl::foldICmpSubConstant(ICmpInst &Cmp,
+ BinaryOperator *Sub,
+ const APInt &C) {
Value *X = Sub->getOperand(0), *Y = Sub->getOperand(1);
ICmpInst::Predicate Pred = Cmp.getPredicate();
const APInt *C2;
@@ -2570,9 +2570,9 @@ Instruction *InstCombinerImpl::foldICmpSubConstant(ICmpInst &Cmp,
}
/// Fold icmp (add X, Y), C.
-Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
- BinaryOperator *Add,
- const APInt &C) {
+Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
+ BinaryOperator *Add,
+ const APInt &C) {
Value *Y = Add->getOperand(1);
const APInt *C2;
if (Cmp.isEquality() || !match(Y, m_APInt(C2)))
@@ -2636,10 +2636,10 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
return nullptr;
}
-bool InstCombinerImpl::matchThreeWayIntCompare(SelectInst *SI, Value *&LHS,
- Value *&RHS, ConstantInt *&Less,
- ConstantInt *&Equal,
- ConstantInt *&Greater) {
+bool InstCombinerImpl::matchThreeWayIntCompare(SelectInst *SI, Value *&LHS,
+ Value *&RHS, ConstantInt *&Less,
+ ConstantInt *&Equal,
+ ConstantInt *&Greater) {
// TODO: Generalize this to work with other comparison idioms or ensure
// they get canonicalized into this form.
@@ -2676,8 +2676,8 @@ bool InstCombinerImpl::matchThreeWayIntCompare(SelectInst *SI, Value *&LHS,
if (PredB == ICmpInst::ICMP_SGT && isa<Constant>(RHS2)) {
// x sgt C-1 <--> x sge C <--> not(x slt C)
auto FlippedStrictness =
- InstCombiner::getFlippedStrictnessPredicateAndConstant(
- PredB, cast<Constant>(RHS2));
+ InstCombiner::getFlippedStrictnessPredicateAndConstant(
+ PredB, cast<Constant>(RHS2));
if (!FlippedStrictness)
return false;
assert(FlippedStrictness->first == ICmpInst::ICMP_SGE && "Sanity check");
@@ -2689,9 +2689,9 @@ bool InstCombinerImpl::matchThreeWayIntCompare(SelectInst *SI, Value *&LHS,
return PredB == ICmpInst::ICMP_SLT && RHS == RHS2;
}
-Instruction *InstCombinerImpl::foldICmpSelectConstant(ICmpInst &Cmp,
- SelectInst *Select,
- ConstantInt *C) {
+Instruction *InstCombinerImpl::foldICmpSelectConstant(ICmpInst &Cmp,
+ SelectInst *Select,
+ ConstantInt *C) {
assert(C && "Cmp RHS should be a constant int!");
// If we're testing a constant value against the result of a three way
@@ -2789,7 +2789,7 @@ static Instruction *foldICmpBitCast(ICmpInst &Cmp,
const APInt *C;
bool TrueIfSigned;
if (match(Op1, m_APInt(C)) && Bitcast->hasOneUse() &&
- InstCombiner::isSignBitCheck(Pred, *C, TrueIfSigned)) {
+ InstCombiner::isSignBitCheck(Pred, *C, TrueIfSigned)) {
if (match(BCSrcOp, m_FPExt(m_Value(X))) ||
match(BCSrcOp, m_FPTrunc(m_Value(X)))) {
// (bitcast (fpext/fptrunc X)) to iX) < 0 --> (bitcast X to iY) < 0
@@ -2801,7 +2801,7 @@ static Instruction *foldICmpBitCast(ICmpInst &Cmp,
Type *NewType = Builder.getIntNTy(XType->getScalarSizeInBits());
if (auto *XVTy = dyn_cast<VectorType>(XType))
- NewType = VectorType::get(NewType, XVTy->getElementCount());
+ NewType = VectorType::get(NewType, XVTy->getElementCount());
Value *NewBitcast = Builder.CreateBitCast(X, NewType);
if (TrueIfSigned)
return new ICmpInst(ICmpInst::ICMP_SLT, NewBitcast,
@@ -2865,7 +2865,7 @@ static Instruction *foldICmpBitCast(ICmpInst &Cmp,
/// Try to fold integer comparisons with a constant operand: icmp Pred X, C
/// where X is some kind of instruction.
-Instruction *InstCombinerImpl::foldICmpInstWithConstant(ICmpInst &Cmp) {
+Instruction *InstCombinerImpl::foldICmpInstWithConstant(ICmpInst &Cmp) {
const APInt *C;
if (!match(Cmp.getOperand(1), m_APInt(C)))
return nullptr;
@@ -2950,8 +2950,8 @@ Instruction *InstCombinerImpl::foldICmpInstWithConstant(ICmpInst &Cmp) {
/// Fold an icmp equality instruction with binary operator LHS and constant RHS:
/// icmp eq/ne BO, C.
-Instruction *InstCombinerImpl::foldICmpBinOpEqualityWithConstant(
- ICmpInst &Cmp, BinaryOperator *BO, const APInt &C) {
+Instruction *InstCombinerImpl::foldICmpBinOpEqualityWithConstant(
+ ICmpInst &Cmp, BinaryOperator *BO, const APInt &C) {
// TODO: Some of these folds could work with arbitrary constants, but this
// function is limited to scalar and vector splat constants.
if (!Cmp.isEquality())
@@ -3055,19 +3055,19 @@ Instruction *InstCombinerImpl::foldICmpBinOpEqualityWithConstant(
}
/// Fold an equality icmp with LLVM intrinsic and constant operand.
-Instruction *InstCombinerImpl::foldICmpEqIntrinsicWithConstant(
- ICmpInst &Cmp, IntrinsicInst *II, const APInt &C) {
+Instruction *InstCombinerImpl::foldICmpEqIntrinsicWithConstant(
+ ICmpInst &Cmp, IntrinsicInst *II, const APInt &C) {
Type *Ty = II->getType();
unsigned BitWidth = C.getBitWidth();
switch (II->getIntrinsicID()) {
- case Intrinsic::abs:
- // abs(A) == 0 -> A == 0
- // abs(A) == INT_MIN -> A == INT_MIN
- if (C.isNullValue() || C.isMinSignedValue())
- return new ICmpInst(Cmp.getPredicate(), II->getArgOperand(0),
- ConstantInt::get(Ty, C));
- break;
-
+ case Intrinsic::abs:
+ // abs(A) == 0 -> A == 0
+ // abs(A) == INT_MIN -> A == INT_MIN
+ if (C.isNullValue() || C.isMinSignedValue())
+ return new ICmpInst(Cmp.getPredicate(), II->getArgOperand(0),
+ ConstantInt::get(Ty, C));
+ break;
+
case Intrinsic::bswap:
// bswap(A) == C -> A == bswap(C)
return new ICmpInst(Cmp.getPredicate(), II->getArgOperand(0),
@@ -3135,31 +3135,31 @@ Instruction *InstCombinerImpl::foldICmpEqIntrinsicWithConstant(
}
/// Fold an icmp with LLVM intrinsic and constant operand: icmp Pred II, C.
-Instruction *InstCombinerImpl::foldICmpIntrinsicWithConstant(ICmpInst &Cmp,
- IntrinsicInst *II,
- const APInt &C) {
+Instruction *InstCombinerImpl::foldICmpIntrinsicWithConstant(ICmpInst &Cmp,
+ IntrinsicInst *II,
+ const APInt &C) {
if (Cmp.isEquality())
return foldICmpEqIntrinsicWithConstant(Cmp, II, C);
Type *Ty = II->getType();
unsigned BitWidth = C.getBitWidth();
- ICmpInst::Predicate Pred = Cmp.getPredicate();
+ ICmpInst::Predicate Pred = Cmp.getPredicate();
switch (II->getIntrinsicID()) {
- case Intrinsic::ctpop: {
- // (ctpop X > BitWidth - 1) --> X == -1
- Value *X = II->getArgOperand(0);
- if (C == BitWidth - 1 && Pred == ICmpInst::ICMP_UGT)
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, X,
- ConstantInt::getAllOnesValue(Ty));
- // (ctpop X < BitWidth) --> X != -1
- if (C == BitWidth && Pred == ICmpInst::ICMP_ULT)
- return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, X,
- ConstantInt::getAllOnesValue(Ty));
- break;
- }
+ case Intrinsic::ctpop: {
+ // (ctpop X > BitWidth - 1) --> X == -1
+ Value *X = II->getArgOperand(0);
+ if (C == BitWidth - 1 && Pred == ICmpInst::ICMP_UGT)
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, X,
+ ConstantInt::getAllOnesValue(Ty));
+ // (ctpop X < BitWidth) --> X != -1
+ if (C == BitWidth && Pred == ICmpInst::ICMP_ULT)
+ return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, X,
+ ConstantInt::getAllOnesValue(Ty));
+ break;
+ }
case Intrinsic::ctlz: {
// ctlz(0bXXXXXXXX) > 3 -> 0bXXXXXXXX < 0b00010000
- if (Pred == ICmpInst::ICMP_UGT && C.ult(BitWidth)) {
+ if (Pred == ICmpInst::ICMP_UGT && C.ult(BitWidth)) {
unsigned Num = C.getLimitedValue();
APInt Limit = APInt::getOneBitSet(BitWidth, BitWidth - Num - 1);
return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_ULT,
@@ -3167,7 +3167,7 @@ Instruction *InstCombinerImpl::foldICmpIntrinsicWithConstant(ICmpInst &Cmp,
}
// ctlz(0bXXXXXXXX) < 3 -> 0bXXXXXXXX > 0b00011111
- if (Pred == ICmpInst::ICMP_ULT && C.uge(1) && C.ule(BitWidth)) {
+ if (Pred == ICmpInst::ICMP_ULT && C.uge(1) && C.ule(BitWidth)) {
unsigned Num = C.getLimitedValue();
APInt Limit = APInt::getLowBitsSet(BitWidth, BitWidth - Num);
return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT,
@@ -3181,7 +3181,7 @@ Instruction *InstCombinerImpl::foldICmpIntrinsicWithConstant(ICmpInst &Cmp,
return nullptr;
// cttz(0bXXXXXXXX) > 3 -> 0bXXXXXXXX & 0b00001111 == 0
- if (Pred == ICmpInst::ICMP_UGT && C.ult(BitWidth)) {
+ if (Pred == ICmpInst::ICMP_UGT && C.ult(BitWidth)) {
APInt Mask = APInt::getLowBitsSet(BitWidth, C.getLimitedValue() + 1);
return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ,
Builder.CreateAnd(II->getArgOperand(0), Mask),
@@ -3189,7 +3189,7 @@ Instruction *InstCombinerImpl::foldICmpIntrinsicWithConstant(ICmpInst &Cmp,
}
// cttz(0bXXXXXXXX) < 3 -> 0bXXXXXXXX & 0b00000111 != 0
- if (Pred == ICmpInst::ICMP_ULT && C.uge(1) && C.ule(BitWidth)) {
+ if (Pred == ICmpInst::ICMP_ULT && C.uge(1) && C.ule(BitWidth)) {
APInt Mask = APInt::getLowBitsSet(BitWidth, C.getLimitedValue());
return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE,
Builder.CreateAnd(II->getArgOperand(0), Mask),
@@ -3205,7 +3205,7 @@ Instruction *InstCombinerImpl::foldICmpIntrinsicWithConstant(ICmpInst &Cmp,
}
/// Handle icmp with constant (but not simple integer constant) RHS.
-Instruction *InstCombinerImpl::foldICmpInstWithConstantNotInt(ICmpInst &I) {
+Instruction *InstCombinerImpl::foldICmpInstWithConstantNotInt(ICmpInst &I) {
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
Constant *RHSC = dyn_cast<Constant>(Op1);
Instruction *LHSI = dyn_cast<Instruction>(Op0);
@@ -3384,8 +3384,8 @@ static Value *foldICmpWithLowBitMaskedVal(ICmpInst &I,
// those elements by copying an existing, defined, and safe scalar constant.
Type *OpTy = M->getType();
auto *VecC = dyn_cast<Constant>(M);
- auto *OpVTy = dyn_cast<FixedVectorType>(OpTy);
- if (OpVTy && VecC && VecC->containsUndefOrPoisonElement()) {
+ auto *OpVTy = dyn_cast<FixedVectorType>(OpTy);
+ if (OpVTy && VecC && VecC->containsUndefOrPoisonElement()) {
Constant *SafeReplacementConstant = nullptr;
for (unsigned i = 0, e = OpVTy->getNumElements(); i != e; ++i) {
if (!isa<UndefValue>(VecC->getAggregateElement(i))) {
@@ -3651,7 +3651,7 @@ foldShiftIntoShiftInAnotherHandOfAndInICmp(ICmpInst &I, const SimplifyQuery SQ,
/// @llvm.umul.with.overflow(x, y) plus extraction of overflow bit
/// Note that the comparison is commutative, while inverted (u>=, ==) predicate
/// will mean that we are looking for the opposite answer.
-Value *InstCombinerImpl::foldUnsignedMultiplicationOverflowCheck(ICmpInst &I) {
+Value *InstCombinerImpl::foldUnsignedMultiplicationOverflowCheck(ICmpInst &I) {
ICmpInst::Predicate Pred;
Value *X, *Y;
Instruction *Mul;
@@ -3713,28 +3713,28 @@ Value *InstCombinerImpl::foldUnsignedMultiplicationOverflowCheck(ICmpInst &I) {
return Res;
}
-static Instruction *foldICmpXNegX(ICmpInst &I) {
- CmpInst::Predicate Pred;
- Value *X;
- if (!match(&I, m_c_ICmp(Pred, m_NSWNeg(m_Value(X)), m_Deferred(X))))
- return nullptr;
-
- if (ICmpInst::isSigned(Pred))
- Pred = ICmpInst::getSwappedPredicate(Pred);
- else if (ICmpInst::isUnsigned(Pred))
- Pred = ICmpInst::getSignedPredicate(Pred);
- // else for equality-comparisons just keep the predicate.
-
- return ICmpInst::Create(Instruction::ICmp, Pred, X,
- Constant::getNullValue(X->getType()), I.getName());
-}
-
+static Instruction *foldICmpXNegX(ICmpInst &I) {
+ CmpInst::Predicate Pred;
+ Value *X;
+ if (!match(&I, m_c_ICmp(Pred, m_NSWNeg(m_Value(X)), m_Deferred(X))))
+ return nullptr;
+
+ if (ICmpInst::isSigned(Pred))
+ Pred = ICmpInst::getSwappedPredicate(Pred);
+ else if (ICmpInst::isUnsigned(Pred))
+ Pred = ICmpInst::getSignedPredicate(Pred);
+ // else for equality-comparisons just keep the predicate.
+
+ return ICmpInst::Create(Instruction::ICmp, Pred, X,
+ Constant::getNullValue(X->getType()), I.getName());
+}
+
/// Try to fold icmp (binop), X or icmp X, (binop).
/// TODO: A large part of this logic is duplicated in InstSimplify's
/// simplifyICmpWithBinOp(). We should be able to share that and avoid the code
/// duplication.
-Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I,
- const SimplifyQuery &SQ) {
+Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I,
+ const SimplifyQuery &SQ) {
const SimplifyQuery Q = SQ.getWithInstruction(&I);
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
@@ -3744,9 +3744,9 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I,
if (!BO0 && !BO1)
return nullptr;
- if (Instruction *NewICmp = foldICmpXNegX(I))
- return NewICmp;
-
+ if (Instruction *NewICmp = foldICmpXNegX(I))
+ return NewICmp;
+
const CmpInst::Predicate Pred = I.getPredicate();
Value *X;
@@ -3967,19 +3967,19 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I,
ConstantExpr::getNeg(RHSC));
}
- {
- // Try to remove shared constant multiplier from equality comparison:
- // X * C == Y * C (with no overflowing/aliasing) --> X == Y
- Value *X, *Y;
- const APInt *C;
- if (match(Op0, m_Mul(m_Value(X), m_APInt(C))) && *C != 0 &&
- match(Op1, m_Mul(m_Value(Y), m_SpecificInt(*C))) && I.isEquality())
- if (!C->countTrailingZeros() ||
- (BO0->hasNoSignedWrap() && BO1->hasNoSignedWrap()) ||
- (BO0->hasNoUnsignedWrap() && BO1->hasNoUnsignedWrap()))
- return new ICmpInst(Pred, X, Y);
- }
-
+ {
+ // Try to remove shared constant multiplier from equality comparison:
+ // X * C == Y * C (with no overflowing/aliasing) --> X == Y
+ Value *X, *Y;
+ const APInt *C;
+ if (match(Op0, m_Mul(m_Value(X), m_APInt(C))) && *C != 0 &&
+ match(Op1, m_Mul(m_Value(Y), m_SpecificInt(*C))) && I.isEquality())
+ if (!C->countTrailingZeros() ||
+ (BO0->hasNoSignedWrap() && BO1->hasNoSignedWrap()) ||
+ (BO0->hasNoUnsignedWrap() && BO1->hasNoUnsignedWrap()))
+ return new ICmpInst(Pred, X, Y);
+ }
+
BinaryOperator *SRem = nullptr;
// icmp (srem X, Y), Y
if (BO0 && BO0->getOpcode() == Instruction::SRem && Op1 == BO0->getOperand(1))
@@ -4024,13 +4024,13 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I,
if (match(BO0->getOperand(1), m_APInt(C))) {
// icmp u/s (a ^ signmask), (b ^ signmask) --> icmp s/u a, b
if (C->isSignMask()) {
- ICmpInst::Predicate NewPred = I.getFlippedSignednessPredicate();
+ ICmpInst::Predicate NewPred = I.getFlippedSignednessPredicate();
return new ICmpInst(NewPred, BO0->getOperand(0), BO1->getOperand(0));
}
// icmp u/s (a ^ maxsignval), (b ^ maxsignval) --> icmp s/u' a, b
if (BO0->getOpcode() == Instruction::Xor && C->isMaxSignedValue()) {
- ICmpInst::Predicate NewPred = I.getFlippedSignednessPredicate();
+ ICmpInst::Predicate NewPred = I.getFlippedSignednessPredicate();
NewPred = I.getSwappedPredicate(NewPred);
return new ICmpInst(NewPred, BO0->getOperand(0), BO1->getOperand(0));
}
@@ -4198,7 +4198,7 @@ static Instruction *foldICmpWithMinMax(ICmpInst &Cmp) {
return nullptr;
}
-Instruction *InstCombinerImpl::foldICmpEquality(ICmpInst &I) {
+Instruction *InstCombinerImpl::foldICmpEquality(ICmpInst &I) {
if (!I.isEquality())
return nullptr;
@@ -4466,7 +4466,7 @@ static Instruction *foldICmpWithZextOrSext(ICmpInst &ICmp,
}
/// Handle icmp (cast x), (cast or constant).
-Instruction *InstCombinerImpl::foldICmpWithCastOp(ICmpInst &ICmp) {
+Instruction *InstCombinerImpl::foldICmpWithCastOp(ICmpInst &ICmp) {
auto *CastOp0 = dyn_cast<CastInst>(ICmp.getOperand(0));
if (!CastOp0)
return nullptr;
@@ -4521,10 +4521,10 @@ static bool isNeutralValue(Instruction::BinaryOps BinaryOp, Value *RHS) {
}
}
-OverflowResult
-InstCombinerImpl::computeOverflow(Instruction::BinaryOps BinaryOp,
- bool IsSigned, Value *LHS, Value *RHS,
- Instruction *CxtI) const {
+OverflowResult
+InstCombinerImpl::computeOverflow(Instruction::BinaryOps BinaryOp,
+ bool IsSigned, Value *LHS, Value *RHS,
+ Instruction *CxtI) const {
switch (BinaryOp) {
default:
llvm_unreachable("Unsupported binary op");
@@ -4546,11 +4546,11 @@ InstCombinerImpl::computeOverflow(Instruction::BinaryOps BinaryOp,
}
}
-bool InstCombinerImpl::OptimizeOverflowCheck(Instruction::BinaryOps BinaryOp,
- bool IsSigned, Value *LHS,
- Value *RHS, Instruction &OrigI,
- Value *&Result,
- Constant *&Overflow) {
+bool InstCombinerImpl::OptimizeOverflowCheck(Instruction::BinaryOps BinaryOp,
+ bool IsSigned, Value *LHS,
+ Value *RHS, Instruction &OrigI,
+ Value *&Result,
+ Constant *&Overflow) {
if (OrigI.isCommutative() && isa<Constant>(LHS) && !isa<Constant>(RHS))
std::swap(LHS, RHS);
@@ -4560,13 +4560,13 @@ bool InstCombinerImpl::OptimizeOverflowCheck(Instruction::BinaryOps BinaryOp,
// compare.
Builder.SetInsertPoint(&OrigI);
- Type *OverflowTy = Type::getInt1Ty(LHS->getContext());
- if (auto *LHSTy = dyn_cast<VectorType>(LHS->getType()))
- OverflowTy = VectorType::get(OverflowTy, LHSTy->getElementCount());
-
+ Type *OverflowTy = Type::getInt1Ty(LHS->getContext());
+ if (auto *LHSTy = dyn_cast<VectorType>(LHS->getType()))
+ OverflowTy = VectorType::get(OverflowTy, LHSTy->getElementCount());
+
if (isNeutralValue(BinaryOp, RHS)) {
Result = LHS;
- Overflow = ConstantInt::getFalse(OverflowTy);
+ Overflow = ConstantInt::getFalse(OverflowTy);
return true;
}
@@ -4577,12 +4577,12 @@ bool InstCombinerImpl::OptimizeOverflowCheck(Instruction::BinaryOps BinaryOp,
case OverflowResult::AlwaysOverflowsHigh:
Result = Builder.CreateBinOp(BinaryOp, LHS, RHS);
Result->takeName(&OrigI);
- Overflow = ConstantInt::getTrue(OverflowTy);
+ Overflow = ConstantInt::getTrue(OverflowTy);
return true;
case OverflowResult::NeverOverflows:
Result = Builder.CreateBinOp(BinaryOp, LHS, RHS);
Result->takeName(&OrigI);
- Overflow = ConstantInt::getFalse(OverflowTy);
+ Overflow = ConstantInt::getFalse(OverflowTy);
if (auto *Inst = dyn_cast<Instruction>(Result)) {
if (IsSigned)
Inst->setHasNoSignedWrap();
@@ -4610,8 +4610,8 @@ bool InstCombinerImpl::OptimizeOverflowCheck(Instruction::BinaryOps BinaryOp,
/// \returns Instruction which must replace the compare instruction, NULL if no
/// replacement required.
static Instruction *processUMulZExtIdiom(ICmpInst &I, Value *MulVal,
- Value *OtherVal,
- InstCombinerImpl &IC) {
+ Value *OtherVal,
+ InstCombinerImpl &IC) {
// Don't bother doing this transformation for pointers, don't do it for
// vectors.
if (!isa<IntegerType>(MulVal->getType()))
@@ -4759,14 +4759,14 @@ static Instruction *processUMulZExtIdiom(ICmpInst &I, Value *MulVal,
Function *F = Intrinsic::getDeclaration(
I.getModule(), Intrinsic::umul_with_overflow, MulType);
CallInst *Call = Builder.CreateCall(F, {MulA, MulB}, "umul");
- IC.addToWorklist(MulInstr);
+ IC.addToWorklist(MulInstr);
// If there are uses of mul result other than the comparison, we know that
// they are truncation or binary AND. Change them to use result of
// mul.with.overflow and adjust properly mask/size.
if (MulVal->hasNUsesOrMore(2)) {
Value *Mul = Builder.CreateExtractValue(Call, 0, "umul.value");
- for (User *U : make_early_inc_range(MulVal->users())) {
+ for (User *U : make_early_inc_range(MulVal->users())) {
if (U == &I || U == OtherVal)
continue;
if (TruncInst *TI = dyn_cast<TruncInst>(U)) {
@@ -4785,11 +4785,11 @@ static Instruction *processUMulZExtIdiom(ICmpInst &I, Value *MulVal,
} else {
llvm_unreachable("Unexpected Binary operation");
}
- IC.addToWorklist(cast<Instruction>(U));
+ IC.addToWorklist(cast<Instruction>(U));
}
}
if (isa<Instruction>(OtherVal))
- IC.addToWorklist(cast<Instruction>(OtherVal));
+ IC.addToWorklist(cast<Instruction>(OtherVal));
// The original icmp gets replaced with the overflow value, maybe inverted
// depending on predicate.
@@ -4834,7 +4834,7 @@ static APInt getDemandedBitsLHSMask(ICmpInst &I, unsigned BitWidth) {
// If this is a normal comparison, it demands all bits. If it is a sign bit
// comparison, it only demands the sign bit.
bool UnusedBit;
- if (InstCombiner::isSignBitCheck(I.getPredicate(), *RHS, UnusedBit))
+ if (InstCombiner::isSignBitCheck(I.getPredicate(), *RHS, UnusedBit))
return APInt::getSignMask(BitWidth);
switch (I.getPredicate()) {
@@ -4891,9 +4891,9 @@ static bool swapMayExposeCSEOpportunities(const Value *Op0, const Value *Op1) {
/// \return true when \p UI is the only use of \p DI in the parent block
/// and all other uses of \p DI are in blocks dominated by \p DB.
///
-bool InstCombinerImpl::dominatesAllUses(const Instruction *DI,
- const Instruction *UI,
- const BasicBlock *DB) const {
+bool InstCombinerImpl::dominatesAllUses(const Instruction *DI,
+ const Instruction *UI,
+ const BasicBlock *DB) const {
assert(DI && UI && "Instruction not defined\n");
// Ignore incomplete definitions.
if (!DI->getParent())
@@ -4966,9 +4966,9 @@ static bool isChainSelectCmpBranch(const SelectInst *SI) {
/// major restriction since a NE compare should be 'normalized' to an equal
/// compare, which usually happens in the combiner and test case
/// select-cmp-br.ll checks for it.
-bool InstCombinerImpl::replacedSelectWithOperand(SelectInst *SI,
- const ICmpInst *Icmp,
- const unsigned SIOpd) {
+bool InstCombinerImpl::replacedSelectWithOperand(SelectInst *SI,
+ const ICmpInst *Icmp,
+ const unsigned SIOpd) {
assert((SIOpd == 1 || SIOpd == 2) && "Invalid select operand!");
if (isChainSelectCmpBranch(SI) && Icmp->getPredicate() == ICmpInst::ICMP_EQ) {
BasicBlock *Succ = SI->getParent()->getTerminator()->getSuccessor(1);
@@ -4994,7 +4994,7 @@ bool InstCombinerImpl::replacedSelectWithOperand(SelectInst *SI,
/// Try to fold the comparison based on range information we can get by checking
/// whether bits are known to be zero or one in the inputs.
-Instruction *InstCombinerImpl::foldICmpUsingKnownBits(ICmpInst &I) {
+Instruction *InstCombinerImpl::foldICmpUsingKnownBits(ICmpInst &I) {
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
Type *Ty = Op0->getType();
ICmpInst::Predicate Pred = I.getPredicate();
@@ -5025,15 +5025,15 @@ Instruction *InstCombinerImpl::foldICmpUsingKnownBits(ICmpInst &I) {
APInt Op0Min(BitWidth, 0), Op0Max(BitWidth, 0);
APInt Op1Min(BitWidth, 0), Op1Max(BitWidth, 0);
if (I.isSigned()) {
- Op0Min = Op0Known.getSignedMinValue();
- Op0Max = Op0Known.getSignedMaxValue();
- Op1Min = Op1Known.getSignedMinValue();
- Op1Max = Op1Known.getSignedMaxValue();
+ Op0Min = Op0Known.getSignedMinValue();
+ Op0Max = Op0Known.getSignedMaxValue();
+ Op1Min = Op1Known.getSignedMinValue();
+ Op1Max = Op1Known.getSignedMaxValue();
} else {
- Op0Min = Op0Known.getMinValue();
- Op0Max = Op0Known.getMaxValue();
- Op1Min = Op1Known.getMinValue();
- Op1Max = Op1Known.getMaxValue();
+ Op0Min = Op0Known.getMinValue();
+ Op0Max = Op0Known.getMaxValue();
+ Op1Min = Op1Known.getMinValue();
+ Op1Max = Op1Known.getMaxValue();
}
// If Min and Max are known to be the same, then SimplifyDemandedBits figured
@@ -5051,9 +5051,9 @@ Instruction *InstCombinerImpl::foldICmpUsingKnownBits(ICmpInst &I) {
llvm_unreachable("Unknown icmp opcode!");
case ICmpInst::ICMP_EQ:
case ICmpInst::ICMP_NE: {
- if (Op0Max.ult(Op1Min) || Op0Min.ugt(Op1Max))
- return replaceInstUsesWith(
- I, ConstantInt::getBool(I.getType(), Pred == CmpInst::ICMP_NE));
+ if (Op0Max.ult(Op1Min) || Op0Min.ugt(Op1Max))
+ return replaceInstUsesWith(
+ I, ConstantInt::getBool(I.getType(), Pred == CmpInst::ICMP_NE));
// If all bits are known zero except for one, then we know at most one bit
// is set. If the comparison is against zero, then this is a check to see if
@@ -5223,8 +5223,8 @@ Instruction *InstCombinerImpl::foldICmpUsingKnownBits(ICmpInst &I) {
}
llvm::Optional<std::pair<CmpInst::Predicate, Constant *>>
-InstCombiner::getFlippedStrictnessPredicateAndConstant(CmpInst::Predicate Pred,
- Constant *C) {
+InstCombiner::getFlippedStrictnessPredicateAndConstant(CmpInst::Predicate Pred,
+ Constant *C) {
assert(ICmpInst::isRelational(Pred) && ICmpInst::isIntPredicate(Pred) &&
"Only for relational integer predicates.");
@@ -5246,8 +5246,8 @@ InstCombiner::getFlippedStrictnessPredicateAndConstant(CmpInst::Predicate Pred,
// Bail out if the constant can't be safely incremented/decremented.
if (!ConstantIsOk(CI))
return llvm::None;
- } else if (auto *FVTy = dyn_cast<FixedVectorType>(Type)) {
- unsigned NumElts = FVTy->getNumElements();
+ } else if (auto *FVTy = dyn_cast<FixedVectorType>(Type)) {
+ unsigned NumElts = FVTy->getNumElements();
for (unsigned i = 0; i != NumElts; ++i) {
Constant *Elt = C->getAggregateElement(i);
if (!Elt)
@@ -5273,8 +5273,8 @@ InstCombiner::getFlippedStrictnessPredicateAndConstant(CmpInst::Predicate Pred,
// It may not be safe to change a compare predicate in the presence of
// undefined elements, so replace those elements with the first safe constant
// that we found.
- // TODO: in case of poison, it is safe; let's replace undefs only.
- if (C->containsUndefOrPoisonElement()) {
+ // TODO: in case of poison, it is safe; let's replace undefs only.
+ if (C->containsUndefOrPoisonElement()) {
assert(SafeReplacementConstant && "Replacement constant not set");
C = Constant::replaceUndefsWith(C, SafeReplacementConstant);
}
@@ -5294,7 +5294,7 @@ InstCombiner::getFlippedStrictnessPredicateAndConstant(CmpInst::Predicate Pred,
static ICmpInst *canonicalizeCmpWithConstant(ICmpInst &I) {
ICmpInst::Predicate Pred = I.getPredicate();
if (ICmpInst::isEquality(Pred) || !ICmpInst::isIntPredicate(Pred) ||
- InstCombiner::isCanonicalPredicate(Pred))
+ InstCombiner::isCanonicalPredicate(Pred))
return nullptr;
Value *Op0 = I.getOperand(0);
@@ -5303,8 +5303,8 @@ static ICmpInst *canonicalizeCmpWithConstant(ICmpInst &I) {
if (!Op1C)
return nullptr;
- auto FlippedStrictness =
- InstCombiner::getFlippedStrictnessPredicateAndConstant(Pred, Op1C);
+ auto FlippedStrictness =
+ InstCombiner::getFlippedStrictnessPredicateAndConstant(Pred, Op1C);
if (!FlippedStrictness)
return nullptr;
@@ -5313,14 +5313,14 @@ static ICmpInst *canonicalizeCmpWithConstant(ICmpInst &I) {
/// If we have a comparison with a non-canonical predicate, if we can update
/// all the users, invert the predicate and adjust all the users.
-CmpInst *InstCombinerImpl::canonicalizeICmpPredicate(CmpInst &I) {
+CmpInst *InstCombinerImpl::canonicalizeICmpPredicate(CmpInst &I) {
// Is the predicate already canonical?
CmpInst::Predicate Pred = I.getPredicate();
- if (InstCombiner::isCanonicalPredicate(Pred))
+ if (InstCombiner::isCanonicalPredicate(Pred))
return nullptr;
// Can all users be adjusted to predicate inversion?
- if (!InstCombiner::canFreelyInvertAllUsersOf(&I, /*IgnoredUser=*/nullptr))
+ if (!InstCombiner::canFreelyInvertAllUsersOf(&I, /*IgnoredUser=*/nullptr))
return nullptr;
// Ok, we can canonicalize comparison!
@@ -5328,8 +5328,8 @@ CmpInst *InstCombinerImpl::canonicalizeICmpPredicate(CmpInst &I) {
I.setPredicate(CmpInst::getInversePredicate(Pred));
I.setName(I.getName() + ".not");
- // And, adapt users.
- freelyInvertAllUsersOf(&I);
+ // And, adapt users.
+ freelyInvertAllUsersOf(&I);
return &I;
}
@@ -5531,7 +5531,7 @@ static Instruction *foldICmpOfUAddOv(ICmpInst &I) {
return ExtractValueInst::Create(UAddOv, 1);
}
-Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
+Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
bool Changed = false;
const SimplifyQuery Q = SQ.getWithInstruction(&I);
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
@@ -5655,10 +5655,10 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
// Try to optimize equality comparisons against alloca-based pointers.
if (Op0->getType()->isPointerTy() && I.isEquality()) {
assert(Op1->getType()->isPointerTy() && "Comparing pointer with non-pointer?");
- if (auto *Alloca = dyn_cast<AllocaInst>(getUnderlyingObject(Op0)))
+ if (auto *Alloca = dyn_cast<AllocaInst>(getUnderlyingObject(Op0)))
if (Instruction *New = foldAllocaCmp(I, Alloca, Op1))
return New;
- if (auto *Alloca = dyn_cast<AllocaInst>(getUnderlyingObject(Op1)))
+ if (auto *Alloca = dyn_cast<AllocaInst>(getUnderlyingObject(Op1)))
if (Instruction *New = foldAllocaCmp(I, Alloca, Op0))
return New;
}
@@ -5769,9 +5769,9 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
}
/// Fold fcmp ([us]itofp x, cst) if possible.
-Instruction *InstCombinerImpl::foldFCmpIntToFPConst(FCmpInst &I,
- Instruction *LHSI,
- Constant *RHSC) {
+Instruction *InstCombinerImpl::foldFCmpIntToFPConst(FCmpInst &I,
+ Instruction *LHSI,
+ Constant *RHSC) {
if (!isa<ConstantFP>(RHSC)) return nullptr;
const APFloat &RHS = cast<ConstantFP>(RHSC)->getValueAPF();
@@ -6056,9 +6056,9 @@ static Instruction *foldFCmpReciprocalAndZero(FCmpInst &I, Instruction *LHSI,
}
/// Optimize fabs(X) compared with zero.
-static Instruction *foldFabsWithFcmpZero(FCmpInst &I, InstCombinerImpl &IC) {
+static Instruction *foldFabsWithFcmpZero(FCmpInst &I, InstCombinerImpl &IC) {
Value *X;
- if (!match(I.getOperand(0), m_FAbs(m_Value(X))) ||
+ if (!match(I.getOperand(0), m_FAbs(m_Value(X))) ||
!match(I.getOperand(1), m_PosZeroFP()))
return nullptr;
@@ -6118,7 +6118,7 @@ static Instruction *foldFabsWithFcmpZero(FCmpInst &I, InstCombinerImpl &IC) {
}
}
-Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
+Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
bool Changed = false;
/// Orders the operands of the compare so that they are listed from most
diff --git a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineInternal.h b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineInternal.h
index 04ae8f0b19..79e9d5c46c 100644
--- a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -25,7 +25,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Transforms/InstCombine/InstCombineWorklist.h"
-#include "llvm/Transforms/InstCombine/InstCombiner.h"
+#include "llvm/Transforms/InstCombine/InstCombiner.h"
#include "llvm/Transforms/Utils/Local.h"
#include <cassert>
@@ -33,14 +33,14 @@
using namespace llvm::PatternMatch;
-// As a default, let's assume that we want to be aggressive,
-// and attempt to traverse with no limits in attempt to sink negation.
-static constexpr unsigned NegatorDefaultMaxDepth = ~0U;
-
-// Let's guesstimate that most often we will end up visiting/producing
-// fairly small number of new instructions.
-static constexpr unsigned NegatorMaxNodesSSO = 16;
-
+// As a default, let's assume that we want to be aggressive,
+// and attempt to traverse with no limits in attempt to sink negation.
+static constexpr unsigned NegatorDefaultMaxDepth = ~0U;
+
+// Let's guesstimate that most often we will end up visiting/producing
+// fairly small number of new instructions.
+static constexpr unsigned NegatorMaxNodesSSO = 16;
+
namespace llvm {
class AAResults;
@@ -57,20 +57,20 @@ class ProfileSummaryInfo;
class TargetLibraryInfo;
class User;
-class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
- : public InstCombiner,
- public InstVisitor<InstCombinerImpl, Instruction *> {
+class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
+ : public InstCombiner,
+ public InstVisitor<InstCombinerImpl, Instruction *> {
public:
- InstCombinerImpl(InstCombineWorklist &Worklist, BuilderTy &Builder,
- bool MinimizeSize, AAResults *AA, AssumptionCache &AC,
- TargetLibraryInfo &TLI, TargetTransformInfo &TTI,
- DominatorTree &DT, OptimizationRemarkEmitter &ORE,
- BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI,
- const DataLayout &DL, LoopInfo *LI)
- : InstCombiner(Worklist, Builder, MinimizeSize, AA, AC, TLI, TTI, DT, ORE,
- BFI, PSI, DL, LI) {}
+ InstCombinerImpl(InstCombineWorklist &Worklist, BuilderTy &Builder,
+ bool MinimizeSize, AAResults *AA, AssumptionCache &AC,
+ TargetLibraryInfo &TLI, TargetTransformInfo &TTI,
+ DominatorTree &DT, OptimizationRemarkEmitter &ORE,
+ BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI,
+ const DataLayout &DL, LoopInfo *LI)
+ : InstCombiner(Worklist, Builder, MinimizeSize, AA, AC, TLI, TTI, DT, ORE,
+ BFI, PSI, DL, LI) {}
- virtual ~InstCombinerImpl() {}
+ virtual ~InstCombinerImpl() {}
/// Run the combiner over the entire worklist until it is empty.
///
@@ -105,7 +105,7 @@ public:
Value *simplifyRangeCheck(ICmpInst *Cmp0, ICmpInst *Cmp1, bool Inverted);
Instruction *visitAnd(BinaryOperator &I);
Instruction *visitOr(BinaryOperator &I);
- bool sinkNotIntoOtherHandOfAndOrOr(BinaryOperator &I);
+ bool sinkNotIntoOtherHandOfAndOrOr(BinaryOperator &I);
Instruction *visitXor(BinaryOperator &I);
Instruction *visitShl(BinaryOperator &I);
Value *reassociateShiftAmtsOfTwoSameDirectionShifts(
@@ -119,7 +119,7 @@ public:
Instruction *visitLShr(BinaryOperator &I);
Instruction *commonShiftTransforms(BinaryOperator &I);
Instruction *visitFCmpInst(FCmpInst &I);
- CmpInst *canonicalizeICmpPredicate(CmpInst &I);
+ CmpInst *canonicalizeICmpPredicate(CmpInst &I);
Instruction *visitICmpInst(ICmpInst &I);
Instruction *FoldShiftByConstant(Value *Op0, Constant *Op1,
BinaryOperator &I);
@@ -158,9 +158,9 @@ public:
Instruction *visitFenceInst(FenceInst &FI);
Instruction *visitSwitchInst(SwitchInst &SI);
Instruction *visitReturnInst(ReturnInst &RI);
- Instruction *visitUnreachableInst(UnreachableInst &I);
- Instruction *
- foldAggregateConstructionIntoAggregateReuse(InsertValueInst &OrigIVI);
+ Instruction *visitUnreachableInst(UnreachableInst &I);
+ Instruction *
+ foldAggregateConstructionIntoAggregateReuse(InsertValueInst &OrigIVI);
Instruction *visitInsertValueInst(InsertValueInst &IV);
Instruction *visitInsertElementInst(InsertElementInst &IE);
Instruction *visitExtractElementInst(ExtractElementInst &EI);
@@ -320,12 +320,12 @@ private:
Instruction *narrowBinOp(TruncInst &Trunc);
Instruction *narrowMaskedBinOp(BinaryOperator &And);
Instruction *narrowMathIfNoOverflow(BinaryOperator &I);
- Instruction *narrowFunnelShift(TruncInst &Trunc);
+ Instruction *narrowFunnelShift(TruncInst &Trunc);
Instruction *optimizeBitCastFromPhi(CastInst &CI, PHINode *PN);
Instruction *matchSAddSubSat(SelectInst &MinMax1);
- void freelyInvertAllUsersOf(Value *V);
-
+ void freelyInvertAllUsersOf(Value *V);
+
/// Determine if a pair of casts can be replaced by a single cast.
///
/// \param CI1 The first of a pair of casts.
@@ -398,7 +398,7 @@ public:
<< " with " << *V << '\n');
I.replaceAllUsesWith(V);
- MadeIRChange = true;
+ MadeIRChange = true;
return &I;
}
@@ -440,7 +440,7 @@ public:
/// When dealing with an instruction that has side effects or produces a void
/// value, we can't rely on DCE to delete the instruction. Instead, visit
/// methods should return the value returned by this function.
- Instruction *eraseInstFromFunction(Instruction &I) override {
+ Instruction *eraseInstFromFunction(Instruction &I) override {
LLVM_DEBUG(dbgs() << "IC: ERASE " << I << '\n');
assert(I.use_empty() && "Cannot erase instruction that is used!");
salvageDebugInfo(I);
@@ -567,7 +567,7 @@ public:
unsigned Depth, Instruction *CxtI);
bool SimplifyDemandedBits(Instruction *I, unsigned Op,
const APInt &DemandedMask, KnownBits &Known,
- unsigned Depth = 0) override;
+ unsigned Depth = 0) override;
/// Helper routine of SimplifyDemandedUseBits. It computes KnownZero/KnownOne
/// bits. It also tries to handle simplifications that can be done based on
@@ -587,10 +587,10 @@ public:
/// demanded bits.
bool SimplifyDemandedInstructionBits(Instruction &Inst);
- virtual Value *
- SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, APInt &UndefElts,
- unsigned Depth = 0,
- bool AllowMultipleUsers = false) override;
+ virtual Value *
+ SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, APInt &UndefElts,
+ unsigned Depth = 0,
+ bool AllowMultipleUsers = false) override;
/// Canonicalize the position of binops relative to shufflevector.
Instruction *foldVectorBinop(BinaryOperator &Inst);
@@ -614,18 +614,18 @@ public:
/// Try to rotate an operation below a PHI node, using PHI nodes for
/// its operands.
- Instruction *foldPHIArgOpIntoPHI(PHINode &PN);
- Instruction *foldPHIArgBinOpIntoPHI(PHINode &PN);
- Instruction *foldPHIArgInsertValueInstructionIntoPHI(PHINode &PN);
- Instruction *foldPHIArgExtractValueInstructionIntoPHI(PHINode &PN);
- Instruction *foldPHIArgGEPIntoPHI(PHINode &PN);
- Instruction *foldPHIArgLoadIntoPHI(PHINode &PN);
- Instruction *foldPHIArgZextsIntoPHI(PHINode &PN);
+ Instruction *foldPHIArgOpIntoPHI(PHINode &PN);
+ Instruction *foldPHIArgBinOpIntoPHI(PHINode &PN);
+ Instruction *foldPHIArgInsertValueInstructionIntoPHI(PHINode &PN);
+ Instruction *foldPHIArgExtractValueInstructionIntoPHI(PHINode &PN);
+ Instruction *foldPHIArgGEPIntoPHI(PHINode &PN);
+ Instruction *foldPHIArgLoadIntoPHI(PHINode &PN);
+ Instruction *foldPHIArgZextsIntoPHI(PHINode &PN);
/// If an integer typed PHI has only one use which is an IntToPtr operation,
/// replace the PHI with an existing pointer typed PHI if it exists. Otherwise
/// insert a new pointer typed PHI and replace the original one.
- Instruction *foldIntegerTypedPHI(PHINode &PN);
+ Instruction *foldIntegerTypedPHI(PHINode &PN);
/// Helper function for FoldPHIArgXIntoPHI() to set debug location for the
/// folded operation.
@@ -708,18 +708,18 @@ public:
Value *A, Value *B, Instruction &Outer,
SelectPatternFlavor SPF2, Value *C);
Instruction *foldSelectInstWithICmp(SelectInst &SI, ICmpInst *ICI);
- Instruction *foldSelectValueEquivalence(SelectInst &SI, ICmpInst &ICI);
+ Instruction *foldSelectValueEquivalence(SelectInst &SI, ICmpInst &ICI);
Value *insertRangeTest(Value *V, const APInt &Lo, const APInt &Hi,
bool isSigned, bool Inside);
Instruction *PromoteCastOfAllocation(BitCastInst &CI, AllocaInst &AI);
bool mergeStoreIntoSuccessor(StoreInst &SI);
- /// Given an 'or' instruction, check to see if it is part of a
- /// bswap/bitreverse idiom. If so, return the equivalent bswap/bitreverse
- /// intrinsic.
- Instruction *matchBSwapOrBitReverse(BinaryOperator &Or, bool MatchBSwaps,
- bool MatchBitReversals);
+ /// Given an 'or' instruction, check to see if it is part of a
+ /// bswap/bitreverse idiom. If so, return the equivalent bswap/bitreverse
+ /// intrinsic.
+ Instruction *matchBSwapOrBitReverse(BinaryOperator &Or, bool MatchBSwaps,
+ bool MatchBitReversals);
Instruction *SimplifyAnyMemTransfer(AnyMemTransferInst *MI);
Instruction *SimplifyAnyMemSet(AnyMemSetInst *MI);
@@ -758,8 +758,8 @@ class Negator final {
using Result = std::pair<ArrayRef<Instruction *> /*NewInstructions*/,
Value * /*NegatedRoot*/>;
- std::array<Value *, 2> getSortedOperandsOfBinOp(Instruction *I);
-
+ std::array<Value *, 2> getSortedOperandsOfBinOp(Instruction *I);
+
LLVM_NODISCARD Value *visitImpl(Value *V, unsigned Depth);
LLVM_NODISCARD Value *negate(Value *V, unsigned Depth);
@@ -777,7 +777,7 @@ public:
/// Attempt to negate \p Root. Retuns nullptr if negation can't be performed,
/// otherwise returns negated value.
LLVM_NODISCARD static Value *Negate(bool LHSIsZero, Value *Root,
- InstCombinerImpl &IC);
+ InstCombinerImpl &IC);
};
} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
index f2c7e46163..c7b5f6f780 100644
--- a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -23,7 +23,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/PatternMatch.h"
-#include "llvm/Transforms/InstCombine/InstCombiner.h"
+#include "llvm/Transforms/InstCombine/InstCombiner.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
using namespace llvm;
@@ -167,8 +167,8 @@ static bool isDereferenceableForAllocaSize(const Value *V, const AllocaInst *AI,
APInt(64, AllocaSize), DL);
}
-static Instruction *simplifyAllocaArraySize(InstCombinerImpl &IC,
- AllocaInst &AI) {
+static Instruction *simplifyAllocaArraySize(InstCombinerImpl &IC,
+ AllocaInst &AI) {
// Check for array size of 1 (scalar allocation).
if (!AI.isArrayAllocation()) {
// i32 1 is the canonical array size for scalar allocations.
@@ -236,45 +236,45 @@ namespace {
// instruction.
class PointerReplacer {
public:
- PointerReplacer(InstCombinerImpl &IC) : IC(IC) {}
-
- bool collectUsers(Instruction &I);
+ PointerReplacer(InstCombinerImpl &IC) : IC(IC) {}
+
+ bool collectUsers(Instruction &I);
void replacePointer(Instruction &I, Value *V);
private:
void replace(Instruction *I);
Value *getReplacement(Value *I);
- SmallSetVector<Instruction *, 4> Worklist;
+ SmallSetVector<Instruction *, 4> Worklist;
MapVector<Value *, Value *> WorkMap;
- InstCombinerImpl &IC;
+ InstCombinerImpl &IC;
};
} // end anonymous namespace
-bool PointerReplacer::collectUsers(Instruction &I) {
+bool PointerReplacer::collectUsers(Instruction &I) {
for (auto U : I.users()) {
- Instruction *Inst = cast<Instruction>(&*U);
- if (LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
- if (Load->isVolatile())
- return false;
- Worklist.insert(Load);
+ Instruction *Inst = cast<Instruction>(&*U);
+ if (LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
+ if (Load->isVolatile())
+ return false;
+ Worklist.insert(Load);
} else if (isa<GetElementPtrInst>(Inst) || isa<BitCastInst>(Inst)) {
- Worklist.insert(Inst);
- if (!collectUsers(*Inst))
- return false;
- } else if (isa<MemTransferInst>(Inst)) {
- Worklist.insert(Inst);
+ Worklist.insert(Inst);
+ if (!collectUsers(*Inst))
+ return false;
+ } else if (isa<MemTransferInst>(Inst)) {
+ Worklist.insert(Inst);
} else {
- LLVM_DEBUG(dbgs() << "Cannot handle pointer user: " << *U << '\n');
- return false;
+ LLVM_DEBUG(dbgs() << "Cannot handle pointer user: " << *U << '\n');
+ return false;
}
}
- return true;
+ return true;
}
-Value *PointerReplacer::getReplacement(Value *V) { return WorkMap.lookup(V); }
-
+Value *PointerReplacer::getReplacement(Value *V) { return WorkMap.lookup(V); }
+
void PointerReplacer::replace(Instruction *I) {
if (getReplacement(I))
return;
@@ -282,12 +282,12 @@ void PointerReplacer::replace(Instruction *I) {
if (auto *LT = dyn_cast<LoadInst>(I)) {
auto *V = getReplacement(LT->getPointerOperand());
assert(V && "Operand not replaced");
- auto *NewI = new LoadInst(LT->getType(), V, "", LT->isVolatile(),
- LT->getAlign(), LT->getOrdering(),
- LT->getSyncScopeID());
+ auto *NewI = new LoadInst(LT->getType(), V, "", LT->isVolatile(),
+ LT->getAlign(), LT->getOrdering(),
+ LT->getSyncScopeID());
NewI->takeName(LT);
- copyMetadataForLoad(*NewI, *LT);
-
+ copyMetadataForLoad(*NewI, *LT);
+
IC.InsertNewInstWith(NewI, *LT);
IC.replaceInstUsesWith(*LT, NewI);
WorkMap[LT] = NewI;
@@ -310,28 +310,28 @@ void PointerReplacer::replace(Instruction *I) {
IC.InsertNewInstWith(NewI, *BC);
NewI->takeName(BC);
WorkMap[BC] = NewI;
- } else if (auto *MemCpy = dyn_cast<MemTransferInst>(I)) {
- auto *SrcV = getReplacement(MemCpy->getRawSource());
- // The pointer may appear in the destination of a copy, but we don't want to
- // replace it.
- if (!SrcV) {
- assert(getReplacement(MemCpy->getRawDest()) &&
- "destination not in replace list");
- return;
- }
-
- IC.Builder.SetInsertPoint(MemCpy);
- auto *NewI = IC.Builder.CreateMemTransferInst(
- MemCpy->getIntrinsicID(), MemCpy->getRawDest(), MemCpy->getDestAlign(),
- SrcV, MemCpy->getSourceAlign(), MemCpy->getLength(),
- MemCpy->isVolatile());
- AAMDNodes AAMD;
- MemCpy->getAAMetadata(AAMD);
- if (AAMD)
- NewI->setAAMetadata(AAMD);
-
- IC.eraseInstFromFunction(*MemCpy);
- WorkMap[MemCpy] = NewI;
+ } else if (auto *MemCpy = dyn_cast<MemTransferInst>(I)) {
+ auto *SrcV = getReplacement(MemCpy->getRawSource());
+ // The pointer may appear in the destination of a copy, but we don't want to
+ // replace it.
+ if (!SrcV) {
+ assert(getReplacement(MemCpy->getRawDest()) &&
+ "destination not in replace list");
+ return;
+ }
+
+ IC.Builder.SetInsertPoint(MemCpy);
+ auto *NewI = IC.Builder.CreateMemTransferInst(
+ MemCpy->getIntrinsicID(), MemCpy->getRawDest(), MemCpy->getDestAlign(),
+ SrcV, MemCpy->getSourceAlign(), MemCpy->getLength(),
+ MemCpy->isVolatile());
+ AAMDNodes AAMD;
+ MemCpy->getAAMetadata(AAMD);
+ if (AAMD)
+ NewI->setAAMetadata(AAMD);
+
+ IC.eraseInstFromFunction(*MemCpy);
+ WorkMap[MemCpy] = NewI;
} else {
llvm_unreachable("should never reach here");
}
@@ -345,12 +345,12 @@ void PointerReplacer::replacePointer(Instruction &I, Value *V) {
"Invalid usage");
#endif
WorkMap[&I] = V;
-
- for (Instruction *Workitem : Worklist)
- replace(Workitem);
+
+ for (Instruction *Workitem : Worklist)
+ replace(Workitem);
}
-Instruction *InstCombinerImpl::visitAllocaInst(AllocaInst &AI) {
+Instruction *InstCombinerImpl::visitAllocaInst(AllocaInst &AI) {
if (auto *I = simplifyAllocaArraySize(*this, AI))
return I;
@@ -401,21 +401,21 @@ Instruction *InstCombinerImpl::visitAllocaInst(AllocaInst &AI) {
// read.
SmallVector<Instruction *, 4> ToDelete;
if (MemTransferInst *Copy = isOnlyCopiedFromConstantMemory(AA, &AI, ToDelete)) {
- Value *TheSrc = Copy->getSource();
+ Value *TheSrc = Copy->getSource();
Align AllocaAlign = AI.getAlign();
Align SourceAlign = getOrEnforceKnownAlignment(
- TheSrc, AllocaAlign, DL, &AI, &AC, &DT);
+ TheSrc, AllocaAlign, DL, &AI, &AC, &DT);
if (AllocaAlign <= SourceAlign &&
- isDereferenceableForAllocaSize(TheSrc, &AI, DL)) {
+ isDereferenceableForAllocaSize(TheSrc, &AI, DL)) {
LLVM_DEBUG(dbgs() << "Found alloca equal to global: " << AI << '\n');
LLVM_DEBUG(dbgs() << " memcpy = " << *Copy << '\n');
- unsigned SrcAddrSpace = TheSrc->getType()->getPointerAddressSpace();
- auto *DestTy = PointerType::get(AI.getAllocatedType(), SrcAddrSpace);
- if (AI.getType()->getAddressSpace() == SrcAddrSpace) {
- for (Instruction *Delete : ToDelete)
- eraseInstFromFunction(*Delete);
-
- Value *Cast = Builder.CreateBitCast(TheSrc, DestTy);
+ unsigned SrcAddrSpace = TheSrc->getType()->getPointerAddressSpace();
+ auto *DestTy = PointerType::get(AI.getAllocatedType(), SrcAddrSpace);
+ if (AI.getType()->getAddressSpace() == SrcAddrSpace) {
+ for (Instruction *Delete : ToDelete)
+ eraseInstFromFunction(*Delete);
+
+ Value *Cast = Builder.CreateBitCast(TheSrc, DestTy);
Instruction *NewI = replaceInstUsesWith(AI, Cast);
eraseInstFromFunction(*Copy);
++NumGlobalCopies;
@@ -423,14 +423,14 @@ Instruction *InstCombinerImpl::visitAllocaInst(AllocaInst &AI) {
}
PointerReplacer PtrReplacer(*this);
- if (PtrReplacer.collectUsers(AI)) {
- for (Instruction *Delete : ToDelete)
- eraseInstFromFunction(*Delete);
-
- Value *Cast = Builder.CreateBitCast(TheSrc, DestTy);
- PtrReplacer.replacePointer(AI, Cast);
- ++NumGlobalCopies;
- }
+ if (PtrReplacer.collectUsers(AI)) {
+ for (Instruction *Delete : ToDelete)
+ eraseInstFromFunction(*Delete);
+
+ Value *Cast = Builder.CreateBitCast(TheSrc, DestTy);
+ PtrReplacer.replacePointer(AI, Cast);
+ ++NumGlobalCopies;
+ }
}
}
@@ -452,9 +452,9 @@ static bool isSupportedAtomicType(Type *Ty) {
/// that pointer type, load it, etc.
///
/// Note that this will create all of the instructions with whatever insert
-/// point the \c InstCombinerImpl currently is using.
-LoadInst *InstCombinerImpl::combineLoadToNewType(LoadInst &LI, Type *NewTy,
- const Twine &Suffix) {
+/// point the \c InstCombinerImpl currently is using.
+LoadInst *InstCombinerImpl::combineLoadToNewType(LoadInst &LI, Type *NewTy,
+ const Twine &Suffix) {
assert((!LI.isAtomic() || isSupportedAtomicType(NewTy)) &&
"can't fold an atomic load to requested type");
@@ -476,8 +476,8 @@ LoadInst *InstCombinerImpl::combineLoadToNewType(LoadInst &LI, Type *NewTy,
/// Combine a store to a new type.
///
/// Returns the newly created store instruction.
-static StoreInst *combineStoreToNewValue(InstCombinerImpl &IC, StoreInst &SI,
- Value *V) {
+static StoreInst *combineStoreToNewValue(InstCombinerImpl &IC, StoreInst &SI,
+ Value *V) {
assert((!SI.isAtomic() || isSupportedAtomicType(V->getType())) &&
"can't fold an atomic store of requested type");
@@ -517,7 +517,7 @@ static StoreInst *combineStoreToNewValue(InstCombinerImpl &IC, StoreInst &SI,
break;
case LLVMContext::MD_invariant_load:
case LLVMContext::MD_nonnull:
- case LLVMContext::MD_noundef:
+ case LLVMContext::MD_noundef:
case LLVMContext::MD_range:
case LLVMContext::MD_align:
case LLVMContext::MD_dereferenceable:
@@ -535,7 +535,7 @@ static StoreInst *combineStoreToNewValue(InstCombinerImpl &IC, StoreInst &SI,
static bool isMinMaxWithLoads(Value *V, Type *&LoadTy) {
assert(V->getType()->isPointerTy() && "Expected pointer type.");
// Ignore possible ty* to ixx* bitcast.
- V = InstCombiner::peekThroughBitcast(V);
+ V = InstCombiner::peekThroughBitcast(V);
// Check that select is select ((cmp load V1, load V2), V1, V2) - minmax
// pattern.
CmpInst::Predicate Pred;
@@ -570,8 +570,8 @@ static bool isMinMaxWithLoads(Value *V, Type *&LoadTy) {
/// or a volatile load. This is debatable, and might be reasonable to change
/// later. However, it is risky in case some backend or other part of LLVM is
/// relying on the exact type loaded to select appropriate atomic operations.
-static Instruction *combineLoadToOperationType(InstCombinerImpl &IC,
- LoadInst &LI) {
+static Instruction *combineLoadToOperationType(InstCombinerImpl &IC,
+ LoadInst &LI) {
// FIXME: We could probably with some care handle both volatile and ordered
// atomic loads here but it isn't clear that this is important.
if (!LI.isUnordered())
@@ -586,36 +586,36 @@ static Instruction *combineLoadToOperationType(InstCombinerImpl &IC,
const DataLayout &DL = IC.getDataLayout();
- // Fold away bit casts of the loaded value by loading the desired type.
- // Note that we should not do this for pointer<->integer casts,
- // because that would result in type punning.
- if (LI.hasOneUse()) {
- // Don't transform when the type is x86_amx, it makes the pass that lower
- // x86_amx type happy.
- if (auto *BC = dyn_cast<BitCastInst>(LI.user_back())) {
- assert(!LI.getType()->isX86_AMXTy() &&
- "load from x86_amx* should not happen!");
- if (BC->getType()->isX86_AMXTy())
- return nullptr;
+ // Fold away bit casts of the loaded value by loading the desired type.
+ // Note that we should not do this for pointer<->integer casts,
+ // because that would result in type punning.
+ if (LI.hasOneUse()) {
+ // Don't transform when the type is x86_amx, it makes the pass that lower
+ // x86_amx type happy.
+ if (auto *BC = dyn_cast<BitCastInst>(LI.user_back())) {
+ assert(!LI.getType()->isX86_AMXTy() &&
+ "load from x86_amx* should not happen!");
+ if (BC->getType()->isX86_AMXTy())
+ return nullptr;
}
if (auto* CI = dyn_cast<CastInst>(LI.user_back()))
- if (CI->isNoopCast(DL) && LI.getType()->isPtrOrPtrVectorTy() ==
- CI->getDestTy()->isPtrOrPtrVectorTy())
+ if (CI->isNoopCast(DL) && LI.getType()->isPtrOrPtrVectorTy() ==
+ CI->getDestTy()->isPtrOrPtrVectorTy())
if (!LI.isAtomic() || isSupportedAtomicType(CI->getDestTy())) {
LoadInst *NewLoad = IC.combineLoadToNewType(LI, CI->getDestTy());
CI->replaceAllUsesWith(NewLoad);
IC.eraseInstFromFunction(*CI);
return &LI;
}
- }
+ }
// FIXME: We should also canonicalize loads of vectors when their elements are
// cast to other types.
return nullptr;
}
-static Instruction *unpackLoadToAggregate(InstCombinerImpl &IC, LoadInst &LI) {
+static Instruction *unpackLoadToAggregate(InstCombinerImpl &IC, LoadInst &LI) {
// FIXME: We could probably with some care handle both volatile and atomic
// stores here but it isn't clear that this is important.
if (!LI.isSimple())
@@ -753,7 +753,7 @@ static bool isObjectSizeLessThanOrEq(Value *V, uint64_t MaxSize,
}
if (PHINode *PN = dyn_cast<PHINode>(P)) {
- append_range(Worklist, PN->incoming_values());
+ append_range(Worklist, PN->incoming_values());
continue;
}
@@ -813,9 +813,9 @@ static bool isObjectSizeLessThanOrEq(Value *V, uint64_t MaxSize,
// not zero. Currently, we only handle the first such index. Also, we could
// also search through non-zero constant indices if we kept track of the
// offsets those indices implied.
-static bool canReplaceGEPIdxWithZero(InstCombinerImpl &IC,
- GetElementPtrInst *GEPI, Instruction *MemI,
- unsigned &Idx) {
+static bool canReplaceGEPIdxWithZero(InstCombinerImpl &IC,
+ GetElementPtrInst *GEPI, Instruction *MemI,
+ unsigned &Idx) {
if (GEPI->getNumOperands() < 2)
return false;
@@ -844,17 +844,17 @@ static bool canReplaceGEPIdxWithZero(InstCombinerImpl &IC,
return false;
SmallVector<Value *, 4> Ops(GEPI->idx_begin(), GEPI->idx_begin() + Idx);
- Type *SourceElementType = GEPI->getSourceElementType();
- // Size information about scalable vectors is not available, so we cannot
- // deduce whether indexing at n is undefined behaviour or not. Bail out.
- if (isa<ScalableVectorType>(SourceElementType))
- return false;
-
- Type *AllocTy = GetElementPtrInst::getIndexedType(SourceElementType, Ops);
+ Type *SourceElementType = GEPI->getSourceElementType();
+ // Size information about scalable vectors is not available, so we cannot
+ // deduce whether indexing at n is undefined behaviour or not. Bail out.
+ if (isa<ScalableVectorType>(SourceElementType))
+ return false;
+
+ Type *AllocTy = GetElementPtrInst::getIndexedType(SourceElementType, Ops);
if (!AllocTy || !AllocTy->isSized())
return false;
const DataLayout &DL = IC.getDataLayout();
- uint64_t TyAllocSize = DL.getTypeAllocSize(AllocTy).getFixedSize();
+ uint64_t TyAllocSize = DL.getTypeAllocSize(AllocTy).getFixedSize();
// If there are more indices after the one we might replace with a zero, make
// sure they're all non-negative. If any of them are negative, the overall
@@ -889,7 +889,7 @@ static bool canReplaceGEPIdxWithZero(InstCombinerImpl &IC,
// access, but the object has only one element, we can assume that the index
// will always be zero. If we replace the GEP, return it.
template <typename T>
-static Instruction *replaceGEPIdxWithZero(InstCombinerImpl &IC, Value *Ptr,
+static Instruction *replaceGEPIdxWithZero(InstCombinerImpl &IC, Value *Ptr,
T &MemI) {
if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(Ptr)) {
unsigned Idx;
@@ -931,7 +931,7 @@ static bool canSimplifyNullLoadOrGEP(LoadInst &LI, Value *Op) {
return false;
}
-Instruction *InstCombinerImpl::visitLoadInst(LoadInst &LI) {
+Instruction *InstCombinerImpl::visitLoadInst(LoadInst &LI) {
Value *Op = LI.getOperand(0);
// Try to canonicalize the loaded type.
@@ -1048,7 +1048,7 @@ Instruction *InstCombinerImpl::visitLoadInst(LoadInst &LI) {
/// and the layout of a <2 x double> is isomorphic to a [2 x double],
/// then %V1 can be safely approximated by a conceptual "bitcast" of %U.
/// Note that %U may contain non-undef values where %V1 has undef.
-static Value *likeBitCastFromVector(InstCombinerImpl &IC, Value *V) {
+static Value *likeBitCastFromVector(InstCombinerImpl &IC, Value *V) {
Value *U = nullptr;
while (auto *IV = dyn_cast<InsertValueInst>(V)) {
auto *E = dyn_cast<ExtractElementInst>(IV->getInsertedValueOperand());
@@ -1075,11 +1075,11 @@ static Value *likeBitCastFromVector(InstCombinerImpl &IC, Value *V) {
return nullptr;
}
if (auto *AT = dyn_cast<ArrayType>(VT)) {
- if (AT->getNumElements() != cast<FixedVectorType>(UT)->getNumElements())
+ if (AT->getNumElements() != cast<FixedVectorType>(UT)->getNumElements())
return nullptr;
} else {
auto *ST = cast<StructType>(VT);
- if (ST->getNumElements() != cast<FixedVectorType>(UT)->getNumElements())
+ if (ST->getNumElements() != cast<FixedVectorType>(UT)->getNumElements())
return nullptr;
for (const auto *EltT : ST->elements()) {
if (EltT != UT->getElementType())
@@ -1109,7 +1109,7 @@ static Value *likeBitCastFromVector(InstCombinerImpl &IC, Value *V) {
/// the caller must erase the store instruction. We have to let the caller erase
/// the store instruction as otherwise there is no way to signal whether it was
/// combined or not: IC.EraseInstFromFunction returns a null pointer.
-static bool combineStoreToValueType(InstCombinerImpl &IC, StoreInst &SI) {
+static bool combineStoreToValueType(InstCombinerImpl &IC, StoreInst &SI) {
// FIXME: We could probably with some care handle both volatile and ordered
// atomic stores here but it isn't clear that this is important.
if (!SI.isUnordered())
@@ -1123,13 +1123,13 @@ static bool combineStoreToValueType(InstCombinerImpl &IC, StoreInst &SI) {
// Fold away bit casts of the stored value by storing the original type.
if (auto *BC = dyn_cast<BitCastInst>(V)) {
- assert(!BC->getType()->isX86_AMXTy() &&
- "store to x86_amx* should not happen!");
+ assert(!BC->getType()->isX86_AMXTy() &&
+ "store to x86_amx* should not happen!");
V = BC->getOperand(0);
- // Don't transform when the type is x86_amx, it makes the pass that lower
- // x86_amx type happy.
- if (V->getType()->isX86_AMXTy())
- return false;
+ // Don't transform when the type is x86_amx, it makes the pass that lower
+ // x86_amx type happy.
+ if (V->getType()->isX86_AMXTy())
+ return false;
if (!SI.isAtomic() || isSupportedAtomicType(V->getType())) {
combineStoreToNewValue(IC, SI, V);
return true;
@@ -1147,7 +1147,7 @@ static bool combineStoreToValueType(InstCombinerImpl &IC, StoreInst &SI) {
return false;
}
-static bool unpackStoreToAggregate(InstCombinerImpl &IC, StoreInst &SI) {
+static bool unpackStoreToAggregate(InstCombinerImpl &IC, StoreInst &SI) {
// FIXME: We could probably with some care handle both volatile and atomic
// stores here but it isn't clear that this is important.
if (!SI.isSimple())
@@ -1287,7 +1287,7 @@ static bool equivalentAddressValues(Value *A, Value *B) {
/// Converts store (bitcast (load (bitcast (select ...)))) to
/// store (load (select ...)), where select is minmax:
/// select ((cmp load V1, load V2), V1, V2).
-static bool removeBitcastsFromLoadStoreOnMinMax(InstCombinerImpl &IC,
+static bool removeBitcastsFromLoadStoreOnMinMax(InstCombinerImpl &IC,
StoreInst &SI) {
// bitcast?
if (!match(SI.getPointerOperand(), m_BitCast(m_Value())))
@@ -1317,8 +1317,8 @@ static bool removeBitcastsFromLoadStoreOnMinMax(InstCombinerImpl &IC,
if (!all_of(LI->users(), [LI, LoadAddr](User *U) {
auto *SI = dyn_cast<StoreInst>(U);
return SI && SI->getPointerOperand() != LI &&
- InstCombiner::peekThroughBitcast(SI->getPointerOperand()) !=
- LoadAddr &&
+ InstCombiner::peekThroughBitcast(SI->getPointerOperand()) !=
+ LoadAddr &&
!SI->getPointerOperand()->isSwiftError();
}))
return false;
@@ -1336,7 +1336,7 @@ static bool removeBitcastsFromLoadStoreOnMinMax(InstCombinerImpl &IC,
return true;
}
-Instruction *InstCombinerImpl::visitStoreInst(StoreInst &SI) {
+Instruction *InstCombinerImpl::visitStoreInst(StoreInst &SI) {
Value *Val = SI.getOperand(0);
Value *Ptr = SI.getOperand(1);
@@ -1455,7 +1455,7 @@ Instruction *InstCombinerImpl::visitStoreInst(StoreInst &SI) {
/// or:
/// *P = v1; if () { *P = v2; }
/// into a phi node with a store in the successor.
-bool InstCombinerImpl::mergeStoreIntoSuccessor(StoreInst &SI) {
+bool InstCombinerImpl::mergeStoreIntoSuccessor(StoreInst &SI) {
if (!SI.isUnordered())
return false; // This code has not been audited for volatile/ordered case.
diff --git a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 22cb22b49a..4b485a0ad8 100644
--- a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -32,7 +32,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Transforms/InstCombine/InstCombineWorklist.h"
-#include "llvm/Transforms/InstCombine/InstCombiner.h"
+#include "llvm/Transforms/InstCombine/InstCombiner.h"
#include "llvm/Transforms/Utils/BuildLibCalls.h"
#include <cassert>
#include <cstddef>
@@ -47,7 +47,7 @@ using namespace PatternMatch;
/// The specific integer value is used in a context where it is known to be
/// non-zero. If this allows us to simplify the computation, do so and return
/// the new operand, otherwise return null.
-static Value *simplifyValueKnownNonZero(Value *V, InstCombinerImpl &IC,
+static Value *simplifyValueKnownNonZero(Value *V, InstCombinerImpl &IC,
Instruction &CxtI) {
// If V has multiple uses, then we would have to do more analysis to determine
// if this is safe. For example, the use could be in dynamically unreached
@@ -139,7 +139,7 @@ static Value *foldMulSelectToNegate(BinaryOperator &I,
return nullptr;
}
-Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
+Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
if (Value *V = SimplifyMulInst(I.getOperand(0), I.getOperand(1),
SQ.getWithInstruction(&I)))
return replaceInstUsesWith(I, V);
@@ -153,9 +153,9 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
if (Value *V = SimplifyUsingDistributiveLaws(I))
return replaceInstUsesWith(I, V);
- Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
- unsigned BitWidth = I.getType()->getScalarSizeInBits();
-
+ Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+ unsigned BitWidth = I.getType()->getScalarSizeInBits();
+
// X * -1 == 0 - X
if (match(Op1, m_AllOnes())) {
BinaryOperator *BO = BinaryOperator::CreateNeg(Op0, I.getName());
@@ -186,7 +186,7 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
if (match(&I, m_Mul(m_Value(NewOp), m_Constant(C1)))) {
// Replace X*(2^C) with X << C, where C is either a scalar or a vector.
- if (Constant *NewCst = ConstantExpr::getExactLogBase2(C1)) {
+ if (Constant *NewCst = ConstantExpr::getExactLogBase2(C1)) {
BinaryOperator *Shl = BinaryOperator::CreateShl(NewOp, NewCst);
if (I.hasNoUnsignedWrap())
@@ -202,12 +202,12 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
}
}
- if (Op0->hasOneUse() && match(Op1, m_NegatedPower2())) {
- // Interpret X * (-1<<C) as (-X) * (1<<C) and try to sink the negation.
- // The "* (1<<C)" thus becomes a potential shifting opportunity.
- if (Value *NegOp0 = Negator::Negate(/*IsNegation*/ true, Op0, *this))
- return BinaryOperator::CreateMul(
- NegOp0, ConstantExpr::getNeg(cast<Constant>(Op1)), I.getName());
+ if (Op0->hasOneUse() && match(Op1, m_NegatedPower2())) {
+ // Interpret X * (-1<<C) as (-X) * (1<<C) and try to sink the negation.
+ // The "* (1<<C)" thus becomes a potential shifting opportunity.
+ if (Value *NegOp0 = Negator::Negate(/*IsNegation*/ true, Op0, *this))
+ return BinaryOperator::CreateMul(
+ NegOp0, ConstantExpr::getNeg(cast<Constant>(Op1)), I.getName());
}
if (Instruction *FoldedMul = foldBinOpIntoSelectOrPhi(I))
@@ -237,9 +237,9 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
SelectPatternFlavor SPF = matchSelectPattern(Op0, X, Y).Flavor;
if (SPF == SPF_ABS || SPF == SPF_NABS)
return BinaryOperator::CreateMul(X, X);
-
- if (match(Op0, m_Intrinsic<Intrinsic::abs>(m_Value(X))))
- return BinaryOperator::CreateMul(X, X);
+
+ if (match(Op0, m_Intrinsic<Intrinsic::abs>(m_Value(X))))
+ return BinaryOperator::CreateMul(X, X);
}
// -X * C --> X * -C
@@ -362,19 +362,19 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
if (match(Op1, m_LShr(m_Value(X), m_APInt(C))) && *C == C->getBitWidth() - 1)
return BinaryOperator::CreateAnd(Builder.CreateAShr(X, *C), Op0);
- // ((ashr X, 31) | 1) * X --> abs(X)
- // X * ((ashr X, 31) | 1) --> abs(X)
- if (match(&I, m_c_BinOp(m_Or(m_AShr(m_Value(X),
- m_SpecificIntAllowUndef(BitWidth - 1)),
- m_One()),
- m_Deferred(X)))) {
- Value *Abs = Builder.CreateBinaryIntrinsic(
- Intrinsic::abs, X,
- ConstantInt::getBool(I.getContext(), I.hasNoSignedWrap()));
- Abs->takeName(&I);
- return replaceInstUsesWith(I, Abs);
- }
-
+ // ((ashr X, 31) | 1) * X --> abs(X)
+ // X * ((ashr X, 31) | 1) --> abs(X)
+ if (match(&I, m_c_BinOp(m_Or(m_AShr(m_Value(X),
+ m_SpecificIntAllowUndef(BitWidth - 1)),
+ m_One()),
+ m_Deferred(X)))) {
+ Value *Abs = Builder.CreateBinaryIntrinsic(
+ Intrinsic::abs, X,
+ ConstantInt::getBool(I.getContext(), I.hasNoSignedWrap()));
+ Abs->takeName(&I);
+ return replaceInstUsesWith(I, Abs);
+ }
+
if (Instruction *Ext = narrowMathIfNoOverflow(I))
return Ext;
@@ -392,7 +392,7 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
return Changed ? &I : nullptr;
}
-Instruction *InstCombinerImpl::foldFPSignBitOps(BinaryOperator &I) {
+Instruction *InstCombinerImpl::foldFPSignBitOps(BinaryOperator &I) {
BinaryOperator::BinaryOps Opcode = I.getOpcode();
assert((Opcode == Instruction::FMul || Opcode == Instruction::FDiv) &&
"Expected fmul or fdiv");
@@ -407,12 +407,12 @@ Instruction *InstCombinerImpl::foldFPSignBitOps(BinaryOperator &I) {
// fabs(X) * fabs(X) -> X * X
// fabs(X) / fabs(X) -> X / X
- if (Op0 == Op1 && match(Op0, m_FAbs(m_Value(X))))
+ if (Op0 == Op1 && match(Op0, m_FAbs(m_Value(X))))
return BinaryOperator::CreateWithCopiedFlags(Opcode, X, X, &I);
// fabs(X) * fabs(Y) --> fabs(X * Y)
// fabs(X) / fabs(Y) --> fabs(X / Y)
- if (match(Op0, m_FAbs(m_Value(X))) && match(Op1, m_FAbs(m_Value(Y))) &&
+ if (match(Op0, m_FAbs(m_Value(X))) && match(Op1, m_FAbs(m_Value(Y))) &&
(Op0->hasOneUse() || Op1->hasOneUse())) {
IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
Builder.setFastMathFlags(I.getFastMathFlags());
@@ -425,7 +425,7 @@ Instruction *InstCombinerImpl::foldFPSignBitOps(BinaryOperator &I) {
return nullptr;
}
-Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) {
+Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) {
if (Value *V = SimplifyFMulInst(I.getOperand(0), I.getOperand(1),
I.getFastMathFlags(),
SQ.getWithInstruction(&I)))
@@ -521,21 +521,21 @@ Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) {
return replaceInstUsesWith(I, Sqrt);
}
- // The following transforms are done irrespective of the number of uses
- // for the expression "1.0/sqrt(X)".
- // 1) 1.0/sqrt(X) * X -> X/sqrt(X)
- // 2) X * 1.0/sqrt(X) -> X/sqrt(X)
- // We always expect the backend to reduce X/sqrt(X) to sqrt(X), if it
- // has the necessary (reassoc) fast-math-flags.
- if (I.hasNoSignedZeros() &&
- match(Op0, (m_FDiv(m_SpecificFP(1.0), m_Value(Y)))) &&
- match(Y, m_Intrinsic<Intrinsic::sqrt>(m_Value(X))) && Op1 == X)
- return BinaryOperator::CreateFDivFMF(X, Y, &I);
- if (I.hasNoSignedZeros() &&
- match(Op1, (m_FDiv(m_SpecificFP(1.0), m_Value(Y)))) &&
- match(Y, m_Intrinsic<Intrinsic::sqrt>(m_Value(X))) && Op0 == X)
- return BinaryOperator::CreateFDivFMF(X, Y, &I);
-
+ // The following transforms are done irrespective of the number of uses
+ // for the expression "1.0/sqrt(X)".
+ // 1) 1.0/sqrt(X) * X -> X/sqrt(X)
+ // 2) X * 1.0/sqrt(X) -> X/sqrt(X)
+ // We always expect the backend to reduce X/sqrt(X) to sqrt(X), if it
+ // has the necessary (reassoc) fast-math-flags.
+ if (I.hasNoSignedZeros() &&
+ match(Op0, (m_FDiv(m_SpecificFP(1.0), m_Value(Y)))) &&
+ match(Y, m_Intrinsic<Intrinsic::sqrt>(m_Value(X))) && Op1 == X)
+ return BinaryOperator::CreateFDivFMF(X, Y, &I);
+ if (I.hasNoSignedZeros() &&
+ match(Op1, (m_FDiv(m_SpecificFP(1.0), m_Value(Y)))) &&
+ match(Y, m_Intrinsic<Intrinsic::sqrt>(m_Value(X))) && Op0 == X)
+ return BinaryOperator::CreateFDivFMF(X, Y, &I);
+
// Like the similar transform in instsimplify, this requires 'nsz' because
// sqrt(-0.0) = -0.0, and -0.0 * -0.0 does not simplify to -0.0.
if (I.hasNoNaNs() && I.hasNoSignedZeros() && Op0 == Op1 &&
@@ -620,7 +620,7 @@ Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) {
/// Fold a divide or remainder with a select instruction divisor when one of the
/// select operands is zero. In that case, we can use the other select operand
/// because div/rem by zero is undefined.
-bool InstCombinerImpl::simplifyDivRemOfSelectWithZeroOp(BinaryOperator &I) {
+bool InstCombinerImpl::simplifyDivRemOfSelectWithZeroOp(BinaryOperator &I) {
SelectInst *SI = dyn_cast<SelectInst>(I.getOperand(1));
if (!SI)
return false;
@@ -721,7 +721,7 @@ static bool isMultiple(const APInt &C1, const APInt &C2, APInt &Quotient,
/// instructions (udiv and sdiv). It is called by the visitors to those integer
/// division instructions.
/// Common integer divide transforms
-Instruction *InstCombinerImpl::commonIDivTransforms(BinaryOperator &I) {
+Instruction *InstCombinerImpl::commonIDivTransforms(BinaryOperator &I) {
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
bool IsSigned = I.getOpcode() == Instruction::SDiv;
Type *Ty = I.getType();
@@ -857,7 +857,7 @@ namespace {
using FoldUDivOperandCb = Instruction *(*)(Value *Op0, Value *Op1,
const BinaryOperator &I,
- InstCombinerImpl &IC);
+ InstCombinerImpl &IC);
/// Used to maintain state for visitUDivOperand().
struct UDivFoldAction {
@@ -886,9 +886,9 @@ struct UDivFoldAction {
// X udiv 2^C -> X >> C
static Instruction *foldUDivPow2Cst(Value *Op0, Value *Op1,
- const BinaryOperator &I,
- InstCombinerImpl &IC) {
- Constant *C1 = ConstantExpr::getExactLogBase2(cast<Constant>(Op1));
+ const BinaryOperator &I,
+ InstCombinerImpl &IC) {
+ Constant *C1 = ConstantExpr::getExactLogBase2(cast<Constant>(Op1));
if (!C1)
llvm_unreachable("Failed to constant fold udiv -> logbase2");
BinaryOperator *LShr = BinaryOperator::CreateLShr(Op0, C1);
@@ -900,7 +900,7 @@ static Instruction *foldUDivPow2Cst(Value *Op0, Value *Op1,
// X udiv (C1 << N), where C1 is "1<<C2" --> X >> (N+C2)
// X udiv (zext (C1 << N)), where C1 is "1<<C2" --> X >> (N+C2)
static Instruction *foldUDivShl(Value *Op0, Value *Op1, const BinaryOperator &I,
- InstCombinerImpl &IC) {
+ InstCombinerImpl &IC) {
Value *ShiftLeft;
if (!match(Op1, m_ZExt(m_Value(ShiftLeft))))
ShiftLeft = Op1;
@@ -909,7 +909,7 @@ static Instruction *foldUDivShl(Value *Op0, Value *Op1, const BinaryOperator &I,
Value *N;
if (!match(ShiftLeft, m_Shl(m_Constant(CI), m_Value(N))))
llvm_unreachable("match should never fail here!");
- Constant *Log2Base = ConstantExpr::getExactLogBase2(CI);
+ Constant *Log2Base = ConstantExpr::getExactLogBase2(CI);
if (!Log2Base)
llvm_unreachable("getLogBase2 should never fail here!");
N = IC.Builder.CreateAdd(N, Log2Base);
@@ -928,8 +928,8 @@ static Instruction *foldUDivShl(Value *Op0, Value *Op1, const BinaryOperator &I,
static size_t visitUDivOperand(Value *Op0, Value *Op1, const BinaryOperator &I,
SmallVectorImpl<UDivFoldAction> &Actions,
unsigned Depth = 0) {
- // FIXME: assert that Op1 isn't/doesn't contain undef.
-
+ // FIXME: assert that Op1 isn't/doesn't contain undef.
+
// Check to see if this is an unsigned division with an exact power of 2,
// if so, convert to a right shift.
if (match(Op1, m_Power2())) {
@@ -949,9 +949,9 @@ static size_t visitUDivOperand(Value *Op0, Value *Op1, const BinaryOperator &I,
return 0;
if (SelectInst *SI = dyn_cast<SelectInst>(Op1))
- // FIXME: missed optimization: if one of the hands of select is/contains
- // undef, just directly pick the other one.
- // FIXME: can both hands contain undef?
+ // FIXME: missed optimization: if one of the hands of select is/contains
+ // undef, just directly pick the other one.
+ // FIXME: can both hands contain undef?
if (size_t LHSIdx =
visitUDivOperand(Op0, SI->getOperand(1), I, Actions, Depth))
if (visitUDivOperand(Op0, SI->getOperand(2), I, Actions, Depth)) {
@@ -999,7 +999,7 @@ static Instruction *narrowUDivURem(BinaryOperator &I,
return nullptr;
}
-Instruction *InstCombinerImpl::visitUDiv(BinaryOperator &I) {
+Instruction *InstCombinerImpl::visitUDiv(BinaryOperator &I) {
if (Value *V = SimplifyUDivInst(I.getOperand(0), I.getOperand(1),
SQ.getWithInstruction(&I)))
return replaceInstUsesWith(I, V);
@@ -1093,7 +1093,7 @@ Instruction *InstCombinerImpl::visitUDiv(BinaryOperator &I) {
return nullptr;
}
-Instruction *InstCombinerImpl::visitSDiv(BinaryOperator &I) {
+Instruction *InstCombinerImpl::visitSDiv(BinaryOperator &I) {
if (Value *V = SimplifySDivInst(I.getOperand(0), I.getOperand(1),
SQ.getWithInstruction(&I)))
return replaceInstUsesWith(I, V);
@@ -1106,7 +1106,7 @@ Instruction *InstCombinerImpl::visitSDiv(BinaryOperator &I) {
return Common;
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
- Type *Ty = I.getType();
+ Type *Ty = I.getType();
Value *X;
// sdiv Op0, -1 --> -Op0
// sdiv Op0, (sext i1 X) --> -Op0 (because if X is 0, the op is undefined)
@@ -1116,24 +1116,24 @@ Instruction *InstCombinerImpl::visitSDiv(BinaryOperator &I) {
// X / INT_MIN --> X == INT_MIN
if (match(Op1, m_SignMask()))
- return new ZExtInst(Builder.CreateICmpEQ(Op0, Op1), Ty);
-
- // sdiv exact X, 1<<C --> ashr exact X, C iff 1<<C is non-negative
- // sdiv exact X, -1<<C --> -(ashr exact X, C)
- if (I.isExact() && ((match(Op1, m_Power2()) && match(Op1, m_NonNegative())) ||
- match(Op1, m_NegatedPower2()))) {
- bool DivisorWasNegative = match(Op1, m_NegatedPower2());
- if (DivisorWasNegative)
- Op1 = ConstantExpr::getNeg(cast<Constant>(Op1));
- auto *AShr = BinaryOperator::CreateExactAShr(
- Op0, ConstantExpr::getExactLogBase2(cast<Constant>(Op1)), I.getName());
- if (!DivisorWasNegative)
- return AShr;
- Builder.Insert(AShr);
- AShr->setName(I.getName() + ".neg");
- return BinaryOperator::CreateNeg(AShr, I.getName());
- }
-
+ return new ZExtInst(Builder.CreateICmpEQ(Op0, Op1), Ty);
+
+ // sdiv exact X, 1<<C --> ashr exact X, C iff 1<<C is non-negative
+ // sdiv exact X, -1<<C --> -(ashr exact X, C)
+ if (I.isExact() && ((match(Op1, m_Power2()) && match(Op1, m_NonNegative())) ||
+ match(Op1, m_NegatedPower2()))) {
+ bool DivisorWasNegative = match(Op1, m_NegatedPower2());
+ if (DivisorWasNegative)
+ Op1 = ConstantExpr::getNeg(cast<Constant>(Op1));
+ auto *AShr = BinaryOperator::CreateExactAShr(
+ Op0, ConstantExpr::getExactLogBase2(cast<Constant>(Op1)), I.getName());
+ if (!DivisorWasNegative)
+ return AShr;
+ Builder.Insert(AShr);
+ AShr->setName(I.getName() + ".neg");
+ return BinaryOperator::CreateNeg(AShr, I.getName());
+ }
+
const APInt *Op1C;
if (match(Op1, m_APInt(Op1C))) {
// If the dividend is sign-extended and the constant divisor is small enough
@@ -1150,7 +1150,7 @@ Instruction *InstCombinerImpl::visitSDiv(BinaryOperator &I) {
Constant *NarrowDivisor =
ConstantExpr::getTrunc(cast<Constant>(Op1), Op0Src->getType());
Value *NarrowOp = Builder.CreateSDiv(Op0Src, NarrowDivisor);
- return new SExtInst(NarrowOp, Ty);
+ return new SExtInst(NarrowOp, Ty);
}
// -X / C --> X / -C (if the negation doesn't overflow).
@@ -1158,7 +1158,7 @@ Instruction *InstCombinerImpl::visitSDiv(BinaryOperator &I) {
// checking if all elements are not the min-signed-val.
if (!Op1C->isMinSignedValue() &&
match(Op0, m_NSWSub(m_Zero(), m_Value(X)))) {
- Constant *NegC = ConstantInt::get(Ty, -(*Op1C));
+ Constant *NegC = ConstantInt::get(Ty, -(*Op1C));
Instruction *BO = BinaryOperator::CreateSDiv(X, NegC);
BO->setIsExact(I.isExact());
return BO;
@@ -1171,19 +1171,19 @@ Instruction *InstCombinerImpl::visitSDiv(BinaryOperator &I) {
return BinaryOperator::CreateNSWNeg(
Builder.CreateSDiv(X, Y, I.getName(), I.isExact()));
- // abs(X) / X --> X > -1 ? 1 : -1
- // X / abs(X) --> X > -1 ? 1 : -1
- if (match(&I, m_c_BinOp(
- m_OneUse(m_Intrinsic<Intrinsic::abs>(m_Value(X), m_One())),
- m_Deferred(X)))) {
- Constant *NegOne = ConstantInt::getAllOnesValue(Ty);
- Value *Cond = Builder.CreateICmpSGT(X, NegOne);
- return SelectInst::Create(Cond, ConstantInt::get(Ty, 1), NegOne);
- }
-
+ // abs(X) / X --> X > -1 ? 1 : -1
+ // X / abs(X) --> X > -1 ? 1 : -1
+ if (match(&I, m_c_BinOp(
+ m_OneUse(m_Intrinsic<Intrinsic::abs>(m_Value(X), m_One())),
+ m_Deferred(X)))) {
+ Constant *NegOne = ConstantInt::getAllOnesValue(Ty);
+ Value *Cond = Builder.CreateICmpSGT(X, NegOne);
+ return SelectInst::Create(Cond, ConstantInt::get(Ty, 1), NegOne);
+ }
+
// If the sign bits of both operands are zero (i.e. we can prove they are
// unsigned inputs), turn this into a udiv.
- APInt Mask(APInt::getSignMask(Ty->getScalarSizeInBits()));
+ APInt Mask(APInt::getSignMask(Ty->getScalarSizeInBits()));
if (MaskedValueIsZero(Op0, Mask, 0, &I)) {
if (MaskedValueIsZero(Op1, Mask, 0, &I)) {
// X sdiv Y -> X udiv Y, iff X and Y don't have sign bit set
@@ -1192,13 +1192,13 @@ Instruction *InstCombinerImpl::visitSDiv(BinaryOperator &I) {
return BO;
}
- if (match(Op1, m_NegatedPower2())) {
- // X sdiv (-(1 << C)) -> -(X sdiv (1 << C)) ->
- // -> -(X udiv (1 << C)) -> -(X u>> C)
- return BinaryOperator::CreateNeg(Builder.Insert(foldUDivPow2Cst(
- Op0, ConstantExpr::getNeg(cast<Constant>(Op1)), I, *this)));
- }
-
+ if (match(Op1, m_NegatedPower2())) {
+ // X sdiv (-(1 << C)) -> -(X sdiv (1 << C)) ->
+ // -> -(X udiv (1 << C)) -> -(X u>> C)
+ return BinaryOperator::CreateNeg(Builder.Insert(foldUDivPow2Cst(
+ Op0, ConstantExpr::getNeg(cast<Constant>(Op1)), I, *this)));
+ }
+
if (isKnownToBeAPowerOfTwo(Op1, /*OrZero*/ true, 0, &I)) {
// X sdiv (1 << Y) -> X udiv (1 << Y) ( -> X u>> Y)
// Safe because the only negative value (1 << Y) can take on is
@@ -1275,7 +1275,7 @@ static Instruction *foldFDivConstantDividend(BinaryOperator &I) {
return BinaryOperator::CreateFDivFMF(NewC, X, &I);
}
-Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
+Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
if (Value *V = SimplifyFDivInst(I.getOperand(0), I.getOperand(1),
I.getFastMathFlags(),
SQ.getWithInstruction(&I)))
@@ -1367,8 +1367,8 @@ Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
// X / fabs(X) -> copysign(1.0, X)
// fabs(X) / X -> copysign(1.0, X)
if (I.hasNoNaNs() && I.hasNoInfs() &&
- (match(&I, m_FDiv(m_Value(X), m_FAbs(m_Deferred(X)))) ||
- match(&I, m_FDiv(m_FAbs(m_Value(X)), m_Deferred(X))))) {
+ (match(&I, m_FDiv(m_Value(X), m_FAbs(m_Deferred(X)))) ||
+ match(&I, m_FDiv(m_FAbs(m_Value(X)), m_Deferred(X))))) {
Value *V = Builder.CreateBinaryIntrinsic(
Intrinsic::copysign, ConstantFP::get(I.getType(), 1.0), X, &I);
return replaceInstUsesWith(I, V);
@@ -1380,7 +1380,7 @@ Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
/// instructions (urem and srem). It is called by the visitors to those integer
/// remainder instructions.
/// Common integer remainder transforms
-Instruction *InstCombinerImpl::commonIRemTransforms(BinaryOperator &I) {
+Instruction *InstCombinerImpl::commonIRemTransforms(BinaryOperator &I) {
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
// The RHS is known non-zero.
@@ -1418,7 +1418,7 @@ Instruction *InstCombinerImpl::commonIRemTransforms(BinaryOperator &I) {
return nullptr;
}
-Instruction *InstCombinerImpl::visitURem(BinaryOperator &I) {
+Instruction *InstCombinerImpl::visitURem(BinaryOperator &I) {
if (Value *V = SimplifyURemInst(I.getOperand(0), I.getOperand(1),
SQ.getWithInstruction(&I)))
return replaceInstUsesWith(I, V);
@@ -1469,7 +1469,7 @@ Instruction *InstCombinerImpl::visitURem(BinaryOperator &I) {
return nullptr;
}
-Instruction *InstCombinerImpl::visitSRem(BinaryOperator &I) {
+Instruction *InstCombinerImpl::visitSRem(BinaryOperator &I) {
if (Value *V = SimplifySRemInst(I.getOperand(0), I.getOperand(1),
SQ.getWithInstruction(&I)))
return replaceInstUsesWith(I, V);
@@ -1492,7 +1492,7 @@ Instruction *InstCombinerImpl::visitSRem(BinaryOperator &I) {
// -X srem Y --> -(X srem Y)
Value *X, *Y;
if (match(&I, m_SRem(m_OneUse(m_NSWSub(m_Zero(), m_Value(X))), m_Value(Y))))
- return BinaryOperator::CreateNSWNeg(Builder.CreateSRem(X, Y));
+ return BinaryOperator::CreateNSWNeg(Builder.CreateSRem(X, Y));
// If the sign bits of both operands are zero (i.e. we can prove they are
// unsigned inputs), turn this into a urem.
@@ -1506,7 +1506,7 @@ Instruction *InstCombinerImpl::visitSRem(BinaryOperator &I) {
// If it's a constant vector, flip any negative values positive.
if (isa<ConstantVector>(Op1) || isa<ConstantDataVector>(Op1)) {
Constant *C = cast<Constant>(Op1);
- unsigned VWidth = cast<FixedVectorType>(C->getType())->getNumElements();
+ unsigned VWidth = cast<FixedVectorType>(C->getType())->getNumElements();
bool hasNegative = false;
bool hasMissing = false;
@@ -1541,7 +1541,7 @@ Instruction *InstCombinerImpl::visitSRem(BinaryOperator &I) {
return nullptr;
}
-Instruction *InstCombinerImpl::visitFRem(BinaryOperator &I) {
+Instruction *InstCombinerImpl::visitFRem(BinaryOperator &I) {
if (Value *V = SimplifyFRemInst(I.getOperand(0), I.getOperand(1),
I.getFastMathFlags(),
SQ.getWithInstruction(&I)))
diff --git a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineNegator.cpp b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineNegator.cpp
index d5c83dd0ba..7718c8b0ee 100644
--- a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineNegator.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineNegator.cpp
@@ -42,9 +42,9 @@
#include "llvm/Support/DebugCounter.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/InstCombine/InstCombiner.h"
-#include <cassert>
-#include <cstdint>
+#include "llvm/Transforms/InstCombine/InstCombiner.h"
+#include <cassert>
+#include <cstdint>
#include <functional>
#include <tuple>
#include <type_traits>
@@ -115,19 +115,19 @@ Negator::~Negator() {
}
#endif
-// Due to the InstCombine's worklist management, there are no guarantees that
-// each instruction we'll encounter has been visited by InstCombine already.
-// In particular, most importantly for us, that means we have to canonicalize
-// constants to RHS ourselves, since that is helpful sometimes.
-std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
- assert(I->getNumOperands() == 2 && "Only for binops!");
- std::array<Value *, 2> Ops{I->getOperand(0), I->getOperand(1)};
- if (I->isCommutative() && InstCombiner::getComplexity(I->getOperand(0)) <
- InstCombiner::getComplexity(I->getOperand(1)))
- std::swap(Ops[0], Ops[1]);
- return Ops;
-}
-
+// Due to the InstCombine's worklist management, there are no guarantees that
+// each instruction we'll encounter has been visited by InstCombine already.
+// In particular, most importantly for us, that means we have to canonicalize
+// constants to RHS ourselves, since that is helpful sometimes.
+std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
+ assert(I->getNumOperands() == 2 && "Only for binops!");
+ std::array<Value *, 2> Ops{I->getOperand(0), I->getOperand(1)};
+ if (I->isCommutative() && InstCombiner::getComplexity(I->getOperand(0)) <
+ InstCombiner::getComplexity(I->getOperand(1)))
+ std::swap(Ops[0], Ops[1]);
+ return Ops;
+}
+
// FIXME: can this be reworked into a worklist-based algorithm while preserving
// the depth-first, early bailout traversal?
LLVM_NODISCARD Value *Negator::visitImpl(Value *V, unsigned Depth) {
@@ -172,13 +172,13 @@ LLVM_NODISCARD Value *Negator::visitImpl(Value *V, unsigned Depth) {
// In some cases we can give the answer without further recursion.
switch (I->getOpcode()) {
- case Instruction::Add: {
- std::array<Value *, 2> Ops = getSortedOperandsOfBinOp(I);
+ case Instruction::Add: {
+ std::array<Value *, 2> Ops = getSortedOperandsOfBinOp(I);
// `inc` is always negatible.
- if (match(Ops[1], m_One()))
- return Builder.CreateNot(Ops[0], I->getName() + ".neg");
+ if (match(Ops[1], m_One()))
+ return Builder.CreateNot(Ops[0], I->getName() + ".neg");
break;
- }
+ }
case Instruction::Xor:
// `not` is always negatible.
if (match(I, m_Not(m_Value(X))))
@@ -199,10 +199,10 @@ LLVM_NODISCARD Value *Negator::visitImpl(Value *V, unsigned Depth) {
}
return BO;
}
- // While we could negate exact arithmetic shift:
- // ashr exact %x, C --> sdiv exact i8 %x, -1<<C
- // iff C != 0 and C u< bitwidth(%x), we don't want to,
- // because division is *THAT* much worse than a shift.
+ // While we could negate exact arithmetic shift:
+ // ashr exact %x, C --> sdiv exact i8 %x, -1<<C
+ // iff C != 0 and C u< bitwidth(%x), we don't want to,
+ // because division is *THAT* much worse than a shift.
break;
}
case Instruction::SExt:
@@ -219,15 +219,15 @@ LLVM_NODISCARD Value *Negator::visitImpl(Value *V, unsigned Depth) {
break; // Other instructions require recursive reasoning.
}
- if (I->getOpcode() == Instruction::Sub &&
- (I->hasOneUse() || match(I->getOperand(0), m_ImmConstant()))) {
- // `sub` is always negatible.
- // However, only do this either if the old `sub` doesn't stick around, or
- // it was subtracting from a constant. Otherwise, this isn't profitable.
- return Builder.CreateSub(I->getOperand(1), I->getOperand(0),
- I->getName() + ".neg");
- }
-
+ if (I->getOpcode() == Instruction::Sub &&
+ (I->hasOneUse() || match(I->getOperand(0), m_ImmConstant()))) {
+ // `sub` is always negatible.
+ // However, only do this either if the old `sub` doesn't stick around, or
+ // it was subtracting from a constant. Otherwise, this isn't profitable.
+ return Builder.CreateSub(I->getOperand(1), I->getOperand(0),
+ I->getName() + ".neg");
+ }
+
// Some other cases, while still don't require recursion,
// are restricted to the one-use case.
if (!V->hasOneUse())
@@ -239,8 +239,8 @@ LLVM_NODISCARD Value *Negator::visitImpl(Value *V, unsigned Depth) {
// While this is normally not behind a use-check,
// let's consider division to be special since it's costly.
if (auto *Op1C = dyn_cast<Constant>(I->getOperand(1))) {
- if (!Op1C->containsUndefOrPoisonElement() &&
- Op1C->isNotMinSignedValue() && Op1C->isNotOneValue()) {
+ if (!Op1C->containsUndefOrPoisonElement() &&
+ Op1C->isNotMinSignedValue() && Op1C->isNotOneValue()) {
Value *BO =
Builder.CreateSDiv(I->getOperand(0), ConstantExpr::getNeg(Op1C),
I->getName() + ".neg");
@@ -261,13 +261,13 @@ LLVM_NODISCARD Value *Negator::visitImpl(Value *V, unsigned Depth) {
}
switch (I->getOpcode()) {
- case Instruction::Freeze: {
- // `freeze` is negatible if its operand is negatible.
- Value *NegOp = negate(I->getOperand(0), Depth + 1);
- if (!NegOp) // Early return.
- return nullptr;
- return Builder.CreateFreeze(NegOp, I->getName() + ".neg");
- }
+ case Instruction::Freeze: {
+ // `freeze` is negatible if its operand is negatible.
+ Value *NegOp = negate(I->getOperand(0), Depth + 1);
+ if (!NegOp) // Early return.
+ return nullptr;
+ return Builder.CreateFreeze(NegOp, I->getName() + ".neg");
+ }
case Instruction::PHI: {
// `phi` is negatible if all the incoming values are negatible.
auto *PHI = cast<PHINode>(I);
@@ -285,16 +285,16 @@ LLVM_NODISCARD Value *Negator::visitImpl(Value *V, unsigned Depth) {
return NegatedPHI;
}
case Instruction::Select: {
- if (isKnownNegation(I->getOperand(1), I->getOperand(2))) {
- // Of one hand of select is known to be negation of another hand,
- // just swap the hands around.
- auto *NewSelect = cast<SelectInst>(I->clone());
- // Just swap the operands of the select.
- NewSelect->swapValues();
- // Don't swap prof metadata, we didn't change the branch behavior.
- NewSelect->setName(I->getName() + ".neg");
- Builder.Insert(NewSelect);
- return NewSelect;
+ if (isKnownNegation(I->getOperand(1), I->getOperand(2))) {
+ // Of one hand of select is known to be negation of another hand,
+ // just swap the hands around.
+ auto *NewSelect = cast<SelectInst>(I->clone());
+ // Just swap the operands of the select.
+ NewSelect->swapValues();
+ // Don't swap prof metadata, we didn't change the branch behavior.
+ NewSelect->setName(I->getName() + ".neg");
+ Builder.Insert(NewSelect);
+ return NewSelect;
}
// `select` is negatible if both hands of `select` are negatible.
Value *NegOp1 = negate(I->getOperand(1), Depth + 1);
@@ -350,81 +350,81 @@ LLVM_NODISCARD Value *Negator::visitImpl(Value *V, unsigned Depth) {
}
case Instruction::Shl: {
// `shl` is negatible if the first operand is negatible.
- if (Value *NegOp0 = negate(I->getOperand(0), Depth + 1))
- return Builder.CreateShl(NegOp0, I->getOperand(1), I->getName() + ".neg");
- // Otherwise, `shl %x, C` can be interpreted as `mul %x, 1<<C`.
- auto *Op1C = dyn_cast<Constant>(I->getOperand(1));
- if (!Op1C) // Early return.
+ if (Value *NegOp0 = negate(I->getOperand(0), Depth + 1))
+ return Builder.CreateShl(NegOp0, I->getOperand(1), I->getName() + ".neg");
+ // Otherwise, `shl %x, C` can be interpreted as `mul %x, 1<<C`.
+ auto *Op1C = dyn_cast<Constant>(I->getOperand(1));
+ if (!Op1C) // Early return.
return nullptr;
- return Builder.CreateMul(
- I->getOperand(0),
- ConstantExpr::getShl(Constant::getAllOnesValue(Op1C->getType()), Op1C),
- I->getName() + ".neg");
+ return Builder.CreateMul(
+ I->getOperand(0),
+ ConstantExpr::getShl(Constant::getAllOnesValue(Op1C->getType()), Op1C),
+ I->getName() + ".neg");
}
- case Instruction::Or: {
+ case Instruction::Or: {
if (!haveNoCommonBitsSet(I->getOperand(0), I->getOperand(1), DL, &AC, I,
&DT))
return nullptr; // Don't know how to handle `or` in general.
- std::array<Value *, 2> Ops = getSortedOperandsOfBinOp(I);
+ std::array<Value *, 2> Ops = getSortedOperandsOfBinOp(I);
// `or`/`add` are interchangeable when operands have no common bits set.
// `inc` is always negatible.
- if (match(Ops[1], m_One()))
- return Builder.CreateNot(Ops[0], I->getName() + ".neg");
+ if (match(Ops[1], m_One()))
+ return Builder.CreateNot(Ops[0], I->getName() + ".neg");
// Else, just defer to Instruction::Add handling.
LLVM_FALLTHROUGH;
- }
+ }
case Instruction::Add: {
// `add` is negatible if both of its operands are negatible.
- SmallVector<Value *, 2> NegatedOps, NonNegatedOps;
- for (Value *Op : I->operands()) {
- // Can we sink the negation into this operand?
- if (Value *NegOp = negate(Op, Depth + 1)) {
- NegatedOps.emplace_back(NegOp); // Successfully negated operand!
- continue;
- }
- // Failed to sink negation into this operand. IFF we started from negation
- // and we manage to sink negation into one operand, we can still do this.
- if (!IsTrulyNegation)
- return nullptr;
- NonNegatedOps.emplace_back(Op); // Just record which operand that was.
- }
- assert((NegatedOps.size() + NonNegatedOps.size()) == 2 &&
- "Internal consistency sanity check.");
- // Did we manage to sink negation into both of the operands?
- if (NegatedOps.size() == 2) // Then we get to keep the `add`!
- return Builder.CreateAdd(NegatedOps[0], NegatedOps[1],
- I->getName() + ".neg");
- assert(IsTrulyNegation && "We should have early-exited then.");
- // Completely failed to sink negation?
- if (NonNegatedOps.size() == 2)
+ SmallVector<Value *, 2> NegatedOps, NonNegatedOps;
+ for (Value *Op : I->operands()) {
+ // Can we sink the negation into this operand?
+ if (Value *NegOp = negate(Op, Depth + 1)) {
+ NegatedOps.emplace_back(NegOp); // Successfully negated operand!
+ continue;
+ }
+ // Failed to sink negation into this operand. IFF we started from negation
+ // and we manage to sink negation into one operand, we can still do this.
+ if (!IsTrulyNegation)
+ return nullptr;
+ NonNegatedOps.emplace_back(Op); // Just record which operand that was.
+ }
+ assert((NegatedOps.size() + NonNegatedOps.size()) == 2 &&
+ "Internal consistency sanity check.");
+ // Did we manage to sink negation into both of the operands?
+ if (NegatedOps.size() == 2) // Then we get to keep the `add`!
+ return Builder.CreateAdd(NegatedOps[0], NegatedOps[1],
+ I->getName() + ".neg");
+ assert(IsTrulyNegation && "We should have early-exited then.");
+ // Completely failed to sink negation?
+ if (NonNegatedOps.size() == 2)
return nullptr;
- // 0-(a+b) --> (-a)-b
- return Builder.CreateSub(NegatedOps[0], NonNegatedOps[0],
- I->getName() + ".neg");
+ // 0-(a+b) --> (-a)-b
+ return Builder.CreateSub(NegatedOps[0], NonNegatedOps[0],
+ I->getName() + ".neg");
}
- case Instruction::Xor: {
- std::array<Value *, 2> Ops = getSortedOperandsOfBinOp(I);
+ case Instruction::Xor: {
+ std::array<Value *, 2> Ops = getSortedOperandsOfBinOp(I);
// `xor` is negatible if one of its operands is invertible.
// FIXME: InstCombineInverter? But how to connect Inverter and Negator?
- if (auto *C = dyn_cast<Constant>(Ops[1])) {
- Value *Xor = Builder.CreateXor(Ops[0], ConstantExpr::getNot(C));
+ if (auto *C = dyn_cast<Constant>(Ops[1])) {
+ Value *Xor = Builder.CreateXor(Ops[0], ConstantExpr::getNot(C));
return Builder.CreateAdd(Xor, ConstantInt::get(Xor->getType(), 1),
I->getName() + ".neg");
}
return nullptr;
- }
+ }
case Instruction::Mul: {
- std::array<Value *, 2> Ops = getSortedOperandsOfBinOp(I);
+ std::array<Value *, 2> Ops = getSortedOperandsOfBinOp(I);
// `mul` is negatible if one of its operands is negatible.
Value *NegatedOp, *OtherOp;
// First try the second operand, in case it's a constant it will be best to
// just invert it instead of sinking the `neg` deeper.
- if (Value *NegOp1 = negate(Ops[1], Depth + 1)) {
+ if (Value *NegOp1 = negate(Ops[1], Depth + 1)) {
NegatedOp = NegOp1;
- OtherOp = Ops[0];
- } else if (Value *NegOp0 = negate(Ops[0], Depth + 1)) {
+ OtherOp = Ops[0];
+ } else if (Value *NegOp0 = negate(Ops[0], Depth + 1)) {
NegatedOp = NegOp0;
- OtherOp = Ops[1];
+ OtherOp = Ops[1];
} else
// Can't negate either of them.
return nullptr;
@@ -487,7 +487,7 @@ LLVM_NODISCARD Optional<Negator::Result> Negator::run(Value *Root) {
}
LLVM_NODISCARD Value *Negator::Negate(bool LHSIsZero, Value *Root,
- InstCombinerImpl &IC) {
+ InstCombinerImpl &IC) {
++NegatorTotalNegationsAttempted;
LLVM_DEBUG(dbgs() << "Negator: attempting to sink negation into " << *Root
<< "\n");
diff --git a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombinePHI.cpp b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombinePHI.cpp
index e05dda3670..b211b08136 100644
--- a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -13,14 +13,14 @@
#include "InstCombineInternal.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Transforms/InstCombine/InstCombiner.h"
+#include "llvm/Transforms/InstCombine/InstCombiner.h"
#include "llvm/Transforms/Utils/Local.h"
-
+
using namespace llvm;
using namespace llvm::PatternMatch;
@@ -30,16 +30,16 @@ static cl::opt<unsigned>
MaxNumPhis("instcombine-max-num-phis", cl::init(512),
cl::desc("Maximum number phis to handle in intptr/ptrint folding"));
-STATISTIC(NumPHIsOfInsertValues,
- "Number of phi-of-insertvalue turned into insertvalue-of-phis");
-STATISTIC(NumPHIsOfExtractValues,
- "Number of phi-of-extractvalue turned into extractvalue-of-phi");
-STATISTIC(NumPHICSEs, "Number of PHI's that got CSE'd");
-
+STATISTIC(NumPHIsOfInsertValues,
+ "Number of phi-of-insertvalue turned into insertvalue-of-phis");
+STATISTIC(NumPHIsOfExtractValues,
+ "Number of phi-of-extractvalue turned into extractvalue-of-phi");
+STATISTIC(NumPHICSEs, "Number of PHI's that got CSE'd");
+
/// The PHI arguments will be folded into a single operation with a PHI node
/// as input. The debug location of the single operation will be the merged
/// locations of the original PHI node arguments.
-void InstCombinerImpl::PHIArgMergedDebugLoc(Instruction *Inst, PHINode &PN) {
+void InstCombinerImpl::PHIArgMergedDebugLoc(Instruction *Inst, PHINode &PN) {
auto *FirstInst = cast<Instruction>(PN.getIncomingValue(0));
Inst->setDebugLoc(FirstInst->getDebugLoc());
// We do not expect a CallInst here, otherwise, N-way merging of DebugLoc
@@ -102,7 +102,7 @@ void InstCombinerImpl::PHIArgMergedDebugLoc(Instruction *Inst, PHINode &PN) {
// ptr_val_inc = ...
// ...
//
-Instruction *InstCombinerImpl::foldIntegerTypedPHI(PHINode &PN) {
+Instruction *InstCombinerImpl::foldIntegerTypedPHI(PHINode &PN) {
if (!PN.getType()->isIntegerTy())
return nullptr;
if (!PN.hasOneUse())
@@ -299,86 +299,86 @@ Instruction *InstCombinerImpl::foldIntegerTypedPHI(PHINode &PN) {
IntToPtr->getOperand(0)->getType());
}
-/// If we have something like phi [insertvalue(a,b,0), insertvalue(c,d,0)],
-/// turn this into a phi[a,c] and phi[b,d] and a single insertvalue.
-Instruction *
-InstCombinerImpl::foldPHIArgInsertValueInstructionIntoPHI(PHINode &PN) {
- auto *FirstIVI = cast<InsertValueInst>(PN.getIncomingValue(0));
-
- // Scan to see if all operands are `insertvalue`'s with the same indicies,
- // and all have a single use.
- for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) {
- auto *I = dyn_cast<InsertValueInst>(PN.getIncomingValue(i));
- if (!I || !I->hasOneUser() || I->getIndices() != FirstIVI->getIndices())
- return nullptr;
- }
-
- // For each operand of an `insertvalue`
- std::array<PHINode *, 2> NewOperands;
- for (int OpIdx : {0, 1}) {
- auto *&NewOperand = NewOperands[OpIdx];
- // Create a new PHI node to receive the values the operand has in each
- // incoming basic block.
- NewOperand = PHINode::Create(
- FirstIVI->getOperand(OpIdx)->getType(), PN.getNumIncomingValues(),
- FirstIVI->getOperand(OpIdx)->getName() + ".pn");
- // And populate each operand's PHI with said values.
- for (auto Incoming : zip(PN.blocks(), PN.incoming_values()))
- NewOperand->addIncoming(
- cast<InsertValueInst>(std::get<1>(Incoming))->getOperand(OpIdx),
- std::get<0>(Incoming));
- InsertNewInstBefore(NewOperand, PN);
- }
-
- // And finally, create `insertvalue` over the newly-formed PHI nodes.
- auto *NewIVI = InsertValueInst::Create(NewOperands[0], NewOperands[1],
- FirstIVI->getIndices(), PN.getName());
-
- PHIArgMergedDebugLoc(NewIVI, PN);
- ++NumPHIsOfInsertValues;
- return NewIVI;
-}
-
-/// If we have something like phi [extractvalue(a,0), extractvalue(b,0)],
-/// turn this into a phi[a,b] and a single extractvalue.
-Instruction *
-InstCombinerImpl::foldPHIArgExtractValueInstructionIntoPHI(PHINode &PN) {
- auto *FirstEVI = cast<ExtractValueInst>(PN.getIncomingValue(0));
-
- // Scan to see if all operands are `extractvalue`'s with the same indicies,
- // and all have a single use.
- for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) {
- auto *I = dyn_cast<ExtractValueInst>(PN.getIncomingValue(i));
- if (!I || !I->hasOneUser() || I->getIndices() != FirstEVI->getIndices() ||
- I->getAggregateOperand()->getType() !=
- FirstEVI->getAggregateOperand()->getType())
- return nullptr;
- }
-
- // Create a new PHI node to receive the values the aggregate operand has
- // in each incoming basic block.
- auto *NewAggregateOperand = PHINode::Create(
- FirstEVI->getAggregateOperand()->getType(), PN.getNumIncomingValues(),
- FirstEVI->getAggregateOperand()->getName() + ".pn");
- // And populate the PHI with said values.
- for (auto Incoming : zip(PN.blocks(), PN.incoming_values()))
- NewAggregateOperand->addIncoming(
- cast<ExtractValueInst>(std::get<1>(Incoming))->getAggregateOperand(),
- std::get<0>(Incoming));
- InsertNewInstBefore(NewAggregateOperand, PN);
-
- // And finally, create `extractvalue` over the newly-formed PHI nodes.
- auto *NewEVI = ExtractValueInst::Create(NewAggregateOperand,
- FirstEVI->getIndices(), PN.getName());
-
- PHIArgMergedDebugLoc(NewEVI, PN);
- ++NumPHIsOfExtractValues;
- return NewEVI;
-}
-
+/// If we have something like phi [insertvalue(a,b,0), insertvalue(c,d,0)],
+/// turn this into a phi[a,c] and phi[b,d] and a single insertvalue.
+Instruction *
+InstCombinerImpl::foldPHIArgInsertValueInstructionIntoPHI(PHINode &PN) {
+ auto *FirstIVI = cast<InsertValueInst>(PN.getIncomingValue(0));
+
+ // Scan to see if all operands are `insertvalue`'s with the same indicies,
+ // and all have a single use.
+ for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) {
+ auto *I = dyn_cast<InsertValueInst>(PN.getIncomingValue(i));
+ if (!I || !I->hasOneUser() || I->getIndices() != FirstIVI->getIndices())
+ return nullptr;
+ }
+
+ // For each operand of an `insertvalue`
+ std::array<PHINode *, 2> NewOperands;
+ for (int OpIdx : {0, 1}) {
+ auto *&NewOperand = NewOperands[OpIdx];
+ // Create a new PHI node to receive the values the operand has in each
+ // incoming basic block.
+ NewOperand = PHINode::Create(
+ FirstIVI->getOperand(OpIdx)->getType(), PN.getNumIncomingValues(),
+ FirstIVI->getOperand(OpIdx)->getName() + ".pn");
+ // And populate each operand's PHI with said values.
+ for (auto Incoming : zip(PN.blocks(), PN.incoming_values()))
+ NewOperand->addIncoming(
+ cast<InsertValueInst>(std::get<1>(Incoming))->getOperand(OpIdx),
+ std::get<0>(Incoming));
+ InsertNewInstBefore(NewOperand, PN);
+ }
+
+ // And finally, create `insertvalue` over the newly-formed PHI nodes.
+ auto *NewIVI = InsertValueInst::Create(NewOperands[0], NewOperands[1],
+ FirstIVI->getIndices(), PN.getName());
+
+ PHIArgMergedDebugLoc(NewIVI, PN);
+ ++NumPHIsOfInsertValues;
+ return NewIVI;
+}
+
+/// If we have something like phi [extractvalue(a,0), extractvalue(b,0)],
+/// turn this into a phi[a,b] and a single extractvalue.
+Instruction *
+InstCombinerImpl::foldPHIArgExtractValueInstructionIntoPHI(PHINode &PN) {
+ auto *FirstEVI = cast<ExtractValueInst>(PN.getIncomingValue(0));
+
+ // Scan to see if all operands are `extractvalue`'s with the same indicies,
+ // and all have a single use.
+ for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) {
+ auto *I = dyn_cast<ExtractValueInst>(PN.getIncomingValue(i));
+ if (!I || !I->hasOneUser() || I->getIndices() != FirstEVI->getIndices() ||
+ I->getAggregateOperand()->getType() !=
+ FirstEVI->getAggregateOperand()->getType())
+ return nullptr;
+ }
+
+ // Create a new PHI node to receive the values the aggregate operand has
+ // in each incoming basic block.
+ auto *NewAggregateOperand = PHINode::Create(
+ FirstEVI->getAggregateOperand()->getType(), PN.getNumIncomingValues(),
+ FirstEVI->getAggregateOperand()->getName() + ".pn");
+ // And populate the PHI with said values.
+ for (auto Incoming : zip(PN.blocks(), PN.incoming_values()))
+ NewAggregateOperand->addIncoming(
+ cast<ExtractValueInst>(std::get<1>(Incoming))->getAggregateOperand(),
+ std::get<0>(Incoming));
+ InsertNewInstBefore(NewAggregateOperand, PN);
+
+ // And finally, create `extractvalue` over the newly-formed PHI nodes.
+ auto *NewEVI = ExtractValueInst::Create(NewAggregateOperand,
+ FirstEVI->getIndices(), PN.getName());
+
+ PHIArgMergedDebugLoc(NewEVI, PN);
+ ++NumPHIsOfExtractValues;
+ return NewEVI;
+}
+
/// If we have something like phi [add (a,b), add(a,c)] and if a/b/c and the
-/// adds all have a single user, turn this into a phi and a single binop.
-Instruction *InstCombinerImpl::foldPHIArgBinOpIntoPHI(PHINode &PN) {
+/// adds all have a single user, turn this into a phi and a single binop.
+Instruction *InstCombinerImpl::foldPHIArgBinOpIntoPHI(PHINode &PN) {
Instruction *FirstInst = cast<Instruction>(PN.getIncomingValue(0));
assert(isa<BinaryOperator>(FirstInst) || isa<CmpInst>(FirstInst));
unsigned Opc = FirstInst->getOpcode();
@@ -388,10 +388,10 @@ Instruction *InstCombinerImpl::foldPHIArgBinOpIntoPHI(PHINode &PN) {
Type *LHSType = LHSVal->getType();
Type *RHSType = RHSVal->getType();
- // Scan to see if all operands are the same opcode, and all have one user.
+ // Scan to see if all operands are the same opcode, and all have one user.
for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) {
Instruction *I = dyn_cast<Instruction>(PN.getIncomingValue(i));
- if (!I || I->getOpcode() != Opc || !I->hasOneUser() ||
+ if (!I || I->getOpcode() != Opc || !I->hasOneUser() ||
// Verify type of the LHS matches so we don't fold cmp's of different
// types.
I->getOperand(0)->getType() != LHSType ||
@@ -471,7 +471,7 @@ Instruction *InstCombinerImpl::foldPHIArgBinOpIntoPHI(PHINode &PN) {
return NewBinOp;
}
-Instruction *InstCombinerImpl::foldPHIArgGEPIntoPHI(PHINode &PN) {
+Instruction *InstCombinerImpl::foldPHIArgGEPIntoPHI(PHINode &PN) {
GetElementPtrInst *FirstInst =cast<GetElementPtrInst>(PN.getIncomingValue(0));
SmallVector<Value*, 16> FixedOperands(FirstInst->op_begin(),
@@ -487,12 +487,12 @@ Instruction *InstCombinerImpl::foldPHIArgGEPIntoPHI(PHINode &PN) {
bool AllInBounds = true;
- // Scan to see if all operands are the same opcode, and all have one user.
+ // Scan to see if all operands are the same opcode, and all have one user.
for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) {
- GetElementPtrInst *GEP =
- dyn_cast<GetElementPtrInst>(PN.getIncomingValue(i));
- if (!GEP || !GEP->hasOneUser() || GEP->getType() != FirstInst->getType() ||
- GEP->getNumOperands() != FirstInst->getNumOperands())
+ GetElementPtrInst *GEP =
+ dyn_cast<GetElementPtrInst>(PN.getIncomingValue(i));
+ if (!GEP || !GEP->hasOneUser() || GEP->getType() != FirstInst->getType() ||
+ GEP->getNumOperands() != FirstInst->getNumOperands())
return nullptr;
AllInBounds &= GEP->isInBounds();
@@ -592,14 +592,14 @@ static bool isSafeAndProfitableToSinkLoad(LoadInst *L) {
BasicBlock::iterator BBI = L->getIterator(), E = L->getParent()->end();
for (++BBI; BBI != E; ++BBI)
- if (BBI->mayWriteToMemory()) {
- // Calls that only access inaccessible memory do not block sinking the
- // load.
- if (auto *CB = dyn_cast<CallBase>(BBI))
- if (CB->onlyAccessesInaccessibleMemory())
- continue;
+ if (BBI->mayWriteToMemory()) {
+ // Calls that only access inaccessible memory do not block sinking the
+ // load.
+ if (auto *CB = dyn_cast<CallBase>(BBI))
+ if (CB->onlyAccessesInaccessibleMemory())
+ continue;
return false;
- }
+ }
// Check for non-address taken alloca. If not address-taken already, it isn't
// profitable to do this xform.
@@ -632,7 +632,7 @@ static bool isSafeAndProfitableToSinkLoad(LoadInst *L) {
return true;
}
-Instruction *InstCombinerImpl::foldPHIArgLoadIntoPHI(PHINode &PN) {
+Instruction *InstCombinerImpl::foldPHIArgLoadIntoPHI(PHINode &PN) {
LoadInst *FirstLI = cast<LoadInst>(PN.getIncomingValue(0));
// FIXME: This is overconservative; this transform is allowed in some cases
@@ -665,7 +665,7 @@ Instruction *InstCombinerImpl::foldPHIArgLoadIntoPHI(PHINode &PN) {
// Check to see if all arguments are the same operation.
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
LoadInst *LI = dyn_cast<LoadInst>(PN.getIncomingValue(i));
- if (!LI || !LI->hasOneUser())
+ if (!LI || !LI->hasOneUser())
return nullptr;
// We can't sink the load if the loaded value could be modified between
@@ -746,7 +746,7 @@ Instruction *InstCombinerImpl::foldPHIArgLoadIntoPHI(PHINode &PN) {
/// TODO: This function could handle other cast types, but then it might
/// require special-casing a cast from the 'i1' type. See the comment in
/// FoldPHIArgOpIntoPHI() about pessimizing illegal integer types.
-Instruction *InstCombinerImpl::foldPHIArgZextsIntoPHI(PHINode &Phi) {
+Instruction *InstCombinerImpl::foldPHIArgZextsIntoPHI(PHINode &Phi) {
// We cannot create a new instruction after the PHI if the terminator is an
// EHPad because there is no valid insertion point.
if (Instruction *TI = Phi.getParent()->getTerminator())
@@ -778,8 +778,8 @@ Instruction *InstCombinerImpl::foldPHIArgZextsIntoPHI(PHINode &Phi) {
unsigned NumConsts = 0;
for (Value *V : Phi.incoming_values()) {
if (auto *Zext = dyn_cast<ZExtInst>(V)) {
- // All zexts must be identical and have one user.
- if (Zext->getSrcTy() != NarrowType || !Zext->hasOneUser())
+ // All zexts must be identical and have one user.
+ if (Zext->getSrcTy() != NarrowType || !Zext->hasOneUser())
return nullptr;
NewIncoming.push_back(Zext->getOperand(0));
NumZexts++;
@@ -820,7 +820,7 @@ Instruction *InstCombinerImpl::foldPHIArgZextsIntoPHI(PHINode &Phi) {
/// If all operands to a PHI node are the same "unary" operator and they all are
/// only used by the PHI, PHI together their inputs, and do the operation once,
/// to the result of the PHI.
-Instruction *InstCombinerImpl::foldPHIArgOpIntoPHI(PHINode &PN) {
+Instruction *InstCombinerImpl::foldPHIArgOpIntoPHI(PHINode &PN) {
// We cannot create a new instruction after the PHI if the terminator is an
// EHPad because there is no valid insertion point.
if (Instruction *TI = PN.getParent()->getTerminator())
@@ -830,13 +830,13 @@ Instruction *InstCombinerImpl::foldPHIArgOpIntoPHI(PHINode &PN) {
Instruction *FirstInst = cast<Instruction>(PN.getIncomingValue(0));
if (isa<GetElementPtrInst>(FirstInst))
- return foldPHIArgGEPIntoPHI(PN);
+ return foldPHIArgGEPIntoPHI(PN);
if (isa<LoadInst>(FirstInst))
- return foldPHIArgLoadIntoPHI(PN);
- if (isa<InsertValueInst>(FirstInst))
- return foldPHIArgInsertValueInstructionIntoPHI(PN);
- if (isa<ExtractValueInst>(FirstInst))
- return foldPHIArgExtractValueInstructionIntoPHI(PN);
+ return foldPHIArgLoadIntoPHI(PN);
+ if (isa<InsertValueInst>(FirstInst))
+ return foldPHIArgInsertValueInstructionIntoPHI(PN);
+ if (isa<ExtractValueInst>(FirstInst))
+ return foldPHIArgExtractValueInstructionIntoPHI(PN);
// Scan the instruction, looking for input operations that can be folded away.
// If all input operands to the phi are the same instruction (e.g. a cast from
@@ -859,7 +859,7 @@ Instruction *InstCombinerImpl::foldPHIArgOpIntoPHI(PHINode &PN) {
// otherwise call FoldPHIArgBinOpIntoPHI.
ConstantOp = dyn_cast<Constant>(FirstInst->getOperand(1));
if (!ConstantOp)
- return foldPHIArgBinOpIntoPHI(PN);
+ return foldPHIArgBinOpIntoPHI(PN);
} else {
return nullptr; // Cannot fold this operation.
}
@@ -867,7 +867,7 @@ Instruction *InstCombinerImpl::foldPHIArgOpIntoPHI(PHINode &PN) {
// Check to see if all arguments are the same operation.
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
Instruction *I = dyn_cast<Instruction>(PN.getIncomingValue(i));
- if (!I || !I->hasOneUser() || !I->isSameOperationAs(FirstInst))
+ if (!I || !I->hasOneUser() || !I->isSameOperationAs(FirstInst))
return nullptr;
if (CastSrcTy) {
if (I->getOperand(0)->getType() != CastSrcTy)
@@ -1019,7 +1019,7 @@ struct LoweredPHIRecord {
LoweredPHIRecord(PHINode *pn, unsigned Sh)
: PN(pn), Shift(Sh), Width(0) {}
};
-} // namespace
+} // namespace
namespace llvm {
template<>
@@ -1040,7 +1040,7 @@ namespace llvm {
LHS.Width == RHS.Width;
}
};
-} // namespace llvm
+} // namespace llvm
/// This is an integer PHI and we know that it has an illegal type: see if it is
@@ -1051,7 +1051,7 @@ namespace llvm {
/// TODO: The user of the trunc may be an bitcast to float/double/vector or an
/// inttoptr. We should produce new PHIs in the right type.
///
-Instruction *InstCombinerImpl::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {
+Instruction *InstCombinerImpl::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {
// PHIUsers - Keep track of all of the truncated values extracted from a set
// of PHIs, along with their offset. These are the things we want to rewrite.
SmallVector<PHIUsageRecord, 16> PHIUsers;
@@ -1225,85 +1225,85 @@ Instruction *InstCombinerImpl::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {
return replaceInstUsesWith(FirstPhi, Undef);
}
-static Value *SimplifyUsingControlFlow(InstCombiner &Self, PHINode &PN,
- const DominatorTree &DT) {
- // Simplify the following patterns:
- // if (cond)
- // / \
- // ... ...
- // \ /
- // phi [true] [false]
- if (!PN.getType()->isIntegerTy(1))
- return nullptr;
-
- if (PN.getNumOperands() != 2)
- return nullptr;
-
- // Make sure all inputs are constants.
- if (!all_of(PN.operands(), [](Value *V) { return isa<ConstantInt>(V); }))
- return nullptr;
-
- BasicBlock *BB = PN.getParent();
- // Do not bother with unreachable instructions.
- if (!DT.isReachableFromEntry(BB))
- return nullptr;
-
- // Same inputs.
- if (PN.getOperand(0) == PN.getOperand(1))
- return PN.getOperand(0);
-
- BasicBlock *TruePred = nullptr, *FalsePred = nullptr;
- for (auto *Pred : predecessors(BB)) {
- auto *Input = cast<ConstantInt>(PN.getIncomingValueForBlock(Pred));
- if (Input->isAllOnesValue())
- TruePred = Pred;
- else
- FalsePred = Pred;
- }
- assert(TruePred && FalsePred && "Must be!");
-
- // Check which edge of the dominator dominates the true input. If it is the
- // false edge, we should invert the condition.
- auto *IDom = DT.getNode(BB)->getIDom()->getBlock();
- auto *BI = dyn_cast<BranchInst>(IDom->getTerminator());
- if (!BI || BI->isUnconditional())
- return nullptr;
-
- // Check that edges outgoing from the idom's terminators dominate respective
- // inputs of the Phi.
- BasicBlockEdge TrueOutEdge(IDom, BI->getSuccessor(0));
- BasicBlockEdge FalseOutEdge(IDom, BI->getSuccessor(1));
-
- BasicBlockEdge TrueIncEdge(TruePred, BB);
- BasicBlockEdge FalseIncEdge(FalsePred, BB);
-
- auto *Cond = BI->getCondition();
- if (DT.dominates(TrueOutEdge, TrueIncEdge) &&
- DT.dominates(FalseOutEdge, FalseIncEdge))
- // This Phi is actually equivalent to branching condition of IDom.
- return Cond;
- else if (DT.dominates(TrueOutEdge, FalseIncEdge) &&
- DT.dominates(FalseOutEdge, TrueIncEdge)) {
- // This Phi is actually opposite to branching condition of IDom. We invert
- // the condition that will potentially open up some opportunities for
- // sinking.
- auto InsertPt = BB->getFirstInsertionPt();
- if (InsertPt != BB->end()) {
- Self.Builder.SetInsertPoint(&*InsertPt);
- return Self.Builder.CreateNot(Cond);
- }
- }
-
- return nullptr;
-}
-
+static Value *SimplifyUsingControlFlow(InstCombiner &Self, PHINode &PN,
+ const DominatorTree &DT) {
+ // Simplify the following patterns:
+ // if (cond)
+ // / \
+ // ... ...
+ // \ /
+ // phi [true] [false]
+ if (!PN.getType()->isIntegerTy(1))
+ return nullptr;
+
+ if (PN.getNumOperands() != 2)
+ return nullptr;
+
+ // Make sure all inputs are constants.
+ if (!all_of(PN.operands(), [](Value *V) { return isa<ConstantInt>(V); }))
+ return nullptr;
+
+ BasicBlock *BB = PN.getParent();
+ // Do not bother with unreachable instructions.
+ if (!DT.isReachableFromEntry(BB))
+ return nullptr;
+
+ // Same inputs.
+ if (PN.getOperand(0) == PN.getOperand(1))
+ return PN.getOperand(0);
+
+ BasicBlock *TruePred = nullptr, *FalsePred = nullptr;
+ for (auto *Pred : predecessors(BB)) {
+ auto *Input = cast<ConstantInt>(PN.getIncomingValueForBlock(Pred));
+ if (Input->isAllOnesValue())
+ TruePred = Pred;
+ else
+ FalsePred = Pred;
+ }
+ assert(TruePred && FalsePred && "Must be!");
+
+ // Check which edge of the dominator dominates the true input. If it is the
+ // false edge, we should invert the condition.
+ auto *IDom = DT.getNode(BB)->getIDom()->getBlock();
+ auto *BI = dyn_cast<BranchInst>(IDom->getTerminator());
+ if (!BI || BI->isUnconditional())
+ return nullptr;
+
+ // Check that edges outgoing from the idom's terminators dominate respective
+ // inputs of the Phi.
+ BasicBlockEdge TrueOutEdge(IDom, BI->getSuccessor(0));
+ BasicBlockEdge FalseOutEdge(IDom, BI->getSuccessor(1));
+
+ BasicBlockEdge TrueIncEdge(TruePred, BB);
+ BasicBlockEdge FalseIncEdge(FalsePred, BB);
+
+ auto *Cond = BI->getCondition();
+ if (DT.dominates(TrueOutEdge, TrueIncEdge) &&
+ DT.dominates(FalseOutEdge, FalseIncEdge))
+ // This Phi is actually equivalent to branching condition of IDom.
+ return Cond;
+ else if (DT.dominates(TrueOutEdge, FalseIncEdge) &&
+ DT.dominates(FalseOutEdge, TrueIncEdge)) {
+ // This Phi is actually opposite to branching condition of IDom. We invert
+ // the condition that will potentially open up some opportunities for
+ // sinking.
+ auto InsertPt = BB->getFirstInsertionPt();
+ if (InsertPt != BB->end()) {
+ Self.Builder.SetInsertPoint(&*InsertPt);
+ return Self.Builder.CreateNot(Cond);
+ }
+ }
+
+ return nullptr;
+}
+
// PHINode simplification
//
-Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) {
+Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) {
if (Value *V = SimplifyInstruction(&PN, SQ.getWithInstruction(&PN)))
return replaceInstUsesWith(PN, V);
- if (Instruction *Result = foldPHIArgZextsIntoPHI(PN))
+ if (Instruction *Result = foldPHIArgZextsIntoPHI(PN))
return Result;
// If all PHI operands are the same operation, pull them through the PHI,
@@ -1311,16 +1311,16 @@ Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) {
if (isa<Instruction>(PN.getIncomingValue(0)) &&
isa<Instruction>(PN.getIncomingValue(1)) &&
cast<Instruction>(PN.getIncomingValue(0))->getOpcode() ==
- cast<Instruction>(PN.getIncomingValue(1))->getOpcode() &&
- PN.getIncomingValue(0)->hasOneUser())
- if (Instruction *Result = foldPHIArgOpIntoPHI(PN))
+ cast<Instruction>(PN.getIncomingValue(1))->getOpcode() &&
+ PN.getIncomingValue(0)->hasOneUser())
+ if (Instruction *Result = foldPHIArgOpIntoPHI(PN))
return Result;
// If this is a trivial cycle in the PHI node graph, remove it. Basically, if
// this PHI only has a single use (a PHI), and if that PHI only has one use (a
// PHI)... break the cycle.
if (PN.hasOneUse()) {
- if (Instruction *Result = foldIntegerTypedPHI(PN))
+ if (Instruction *Result = foldIntegerTypedPHI(PN))
return Result;
Instruction *PHIUser = cast<Instruction>(PN.user_back());
@@ -1433,21 +1433,21 @@ Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) {
}
}
- // Is there an identical PHI node in this basic block?
- for (PHINode &IdenticalPN : PN.getParent()->phis()) {
- // Ignore the PHI node itself.
- if (&IdenticalPN == &PN)
- continue;
- // Note that even though we've just canonicalized this PHI, due to the
- // worklist visitation order, there are no guarantess that *every* PHI
- // has been canonicalized, so we can't just compare operands ranges.
- if (!PN.isIdenticalToWhenDefined(&IdenticalPN))
- continue;
- // Just use that PHI instead then.
- ++NumPHICSEs;
- return replaceInstUsesWith(PN, &IdenticalPN);
- }
-
+ // Is there an identical PHI node in this basic block?
+ for (PHINode &IdenticalPN : PN.getParent()->phis()) {
+ // Ignore the PHI node itself.
+ if (&IdenticalPN == &PN)
+ continue;
+ // Note that even though we've just canonicalized this PHI, due to the
+ // worklist visitation order, there are no guarantess that *every* PHI
+ // has been canonicalized, so we can't just compare operands ranges.
+ if (!PN.isIdenticalToWhenDefined(&IdenticalPN))
+ continue;
+ // Just use that PHI instead then.
+ ++NumPHICSEs;
+ return replaceInstUsesWith(PN, &IdenticalPN);
+ }
+
// If this is an integer PHI and we know that it has an illegal type, see if
// it is only used by trunc or trunc(lshr) operations. If so, we split the
// PHI into the various pieces being extracted. This sort of thing is
@@ -1457,9 +1457,9 @@ Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) {
if (Instruction *Res = SliceUpIllegalIntegerPHI(PN))
return Res;
- // Ultimately, try to replace this Phi with a dominating condition.
- if (auto *V = SimplifyUsingControlFlow(*this, PN, DT))
- return replaceInstUsesWith(PN, V);
-
+ // Ultimately, try to replace this Phi with a dominating condition.
+ if (auto *V = SimplifyUsingControlFlow(*this, PN, DT))
+ return replaceInstUsesWith(PN, V);
+
return nullptr;
}
diff --git a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineSelect.cpp b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineSelect.cpp
index af4f67dee0..5f174aae09 100644
--- a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -38,7 +38,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Transforms/InstCombine/InstCombineWorklist.h"
-#include "llvm/Transforms/InstCombine/InstCombiner.h"
+#include "llvm/Transforms/InstCombine/InstCombiner.h"
#include <cassert>
#include <utility>
@@ -47,11 +47,11 @@ using namespace PatternMatch;
#define DEBUG_TYPE "instcombine"
-/// FIXME: Enabled by default until the pattern is supported well.
-static cl::opt<bool> EnableUnsafeSelectTransform(
- "instcombine-unsafe-select-transform", cl::init(true),
- cl::desc("Enable poison-unsafe select to and/or transform"));
-
+/// FIXME: Enabled by default until the pattern is supported well.
+static cl::opt<bool> EnableUnsafeSelectTransform(
+ "instcombine-unsafe-select-transform", cl::init(true),
+ cl::desc("Enable poison-unsafe select to and/or transform"));
+
static Value *createMinMax(InstCombiner::BuilderTy &Builder,
SelectPatternFlavor SPF, Value *A, Value *B) {
CmpInst::Predicate Pred = getMinMaxPred(SPF);
@@ -63,7 +63,7 @@ static Value *createMinMax(InstCombiner::BuilderTy &Builder,
/// constant of a binop.
static Instruction *foldSelectBinOpIdentity(SelectInst &Sel,
const TargetLibraryInfo &TLI,
- InstCombinerImpl &IC) {
+ InstCombinerImpl &IC) {
// The select condition must be an equality compare with a constant operand.
Value *X;
Constant *C;
@@ -265,8 +265,8 @@ static unsigned getSelectFoldableOperands(BinaryOperator *I) {
}
/// We have (select c, TI, FI), and we know that TI and FI have the same opcode.
-Instruction *InstCombinerImpl::foldSelectOpOp(SelectInst &SI, Instruction *TI,
- Instruction *FI) {
+Instruction *InstCombinerImpl::foldSelectOpOp(SelectInst &SI, Instruction *TI,
+ Instruction *FI) {
// Don't break up min/max patterns. The hasOneUse checks below prevent that
// for most cases, but vector min/max with bitcasts can be transformed. If the
// one-use restrictions are eased for other patterns, we still don't want to
@@ -288,9 +288,9 @@ Instruction *InstCombinerImpl::foldSelectOpOp(SelectInst &SI, Instruction *TI,
// The select condition may be a vector. We may only change the operand
// type if the vector width remains the same (and matches the condition).
if (auto *CondVTy = dyn_cast<VectorType>(CondTy)) {
- if (!FIOpndTy->isVectorTy() ||
- CondVTy->getElementCount() !=
- cast<VectorType>(FIOpndTy)->getElementCount())
+ if (!FIOpndTy->isVectorTy() ||
+ CondVTy->getElementCount() !=
+ cast<VectorType>(FIOpndTy)->getElementCount())
return nullptr;
// TODO: If the backend knew how to deal with casts better, we could
@@ -403,8 +403,8 @@ static bool isSelect01(const APInt &C1I, const APInt &C2I) {
/// Try to fold the select into one of the operands to allow further
/// optimization.
-Instruction *InstCombinerImpl::foldSelectIntoOp(SelectInst &SI, Value *TrueVal,
- Value *FalseVal) {
+Instruction *InstCombinerImpl::foldSelectIntoOp(SelectInst &SI, Value *TrueVal,
+ Value *FalseVal) {
// See the comment above GetSelectFoldableOperands for a description of the
// transformation we are doing here.
if (auto *TVI = dyn_cast<BinaryOperator>(TrueVal)) {
@@ -418,15 +418,15 @@ Instruction *InstCombinerImpl::foldSelectIntoOp(SelectInst &SI, Value *TrueVal,
}
if (OpToFold) {
- Constant *C = ConstantExpr::getBinOpIdentity(TVI->getOpcode(),
- TVI->getType(), true);
+ Constant *C = ConstantExpr::getBinOpIdentity(TVI->getOpcode(),
+ TVI->getType(), true);
Value *OOp = TVI->getOperand(2-OpToFold);
// Avoid creating select between 2 constants unless it's selecting
// between 0, 1 and -1.
const APInt *OOpC;
bool OOpIsAPInt = match(OOp, m_APInt(OOpC));
- if (!isa<Constant>(OOp) ||
- (OOpIsAPInt && isSelect01(C->getUniqueInteger(), *OOpC))) {
+ if (!isa<Constant>(OOp) ||
+ (OOpIsAPInt && isSelect01(C->getUniqueInteger(), *OOpC))) {
Value *NewSel = Builder.CreateSelect(SI.getCondition(), OOp, C);
NewSel->takeName(TVI);
BinaryOperator *BO = BinaryOperator::Create(TVI->getOpcode(),
@@ -450,15 +450,15 @@ Instruction *InstCombinerImpl::foldSelectIntoOp(SelectInst &SI, Value *TrueVal,
}
if (OpToFold) {
- Constant *C = ConstantExpr::getBinOpIdentity(FVI->getOpcode(),
- FVI->getType(), true);
+ Constant *C = ConstantExpr::getBinOpIdentity(FVI->getOpcode(),
+ FVI->getType(), true);
Value *OOp = FVI->getOperand(2-OpToFold);
// Avoid creating select between 2 constants unless it's selecting
// between 0, 1 and -1.
const APInt *OOpC;
bool OOpIsAPInt = match(OOp, m_APInt(OOpC));
- if (!isa<Constant>(OOp) ||
- (OOpIsAPInt && isSelect01(C->getUniqueInteger(), *OOpC))) {
+ if (!isa<Constant>(OOp) ||
+ (OOpIsAPInt && isSelect01(C->getUniqueInteger(), *OOpC))) {
Value *NewSel = Builder.CreateSelect(SI.getCondition(), C, OOp);
NewSel->takeName(FVI);
BinaryOperator *BO = BinaryOperator::Create(FVI->getOpcode(),
@@ -1013,9 +1013,9 @@ static bool adjustMinMax(SelectInst &Sel, ICmpInst &Cmp) {
/// select (icmp Pred X, C1), C2, X --> select (icmp Pred' X, C2), X, C2
/// Note: if C1 != C2, this will change the icmp constant to the existing
/// constant operand of the select.
-static Instruction *canonicalizeMinMaxWithConstant(SelectInst &Sel,
- ICmpInst &Cmp,
- InstCombinerImpl &IC) {
+static Instruction *canonicalizeMinMaxWithConstant(SelectInst &Sel,
+ ICmpInst &Cmp,
+ InstCombinerImpl &IC) {
if (!Cmp.hasOneUse() || !isa<Constant>(Cmp.getOperand(1)))
return nullptr;
@@ -1053,7 +1053,7 @@ static Instruction *canonicalizeMinMaxWithConstant(SelectInst &Sel,
}
static Instruction *canonicalizeAbsNabs(SelectInst &Sel, ICmpInst &Cmp,
- InstCombinerImpl &IC) {
+ InstCombinerImpl &IC) {
if (!Cmp.hasOneUse() || !isa<Constant>(Cmp.getOperand(1)))
return nullptr;
@@ -1063,18 +1063,18 @@ static Instruction *canonicalizeAbsNabs(SelectInst &Sel, ICmpInst &Cmp,
SPF != SelectPatternFlavor::SPF_NABS)
return nullptr;
- // Note that NSW flag can only be propagated for normal, non-negated abs!
- bool IntMinIsPoison = SPF == SelectPatternFlavor::SPF_ABS &&
- match(RHS, m_NSWNeg(m_Specific(LHS)));
- Constant *IntMinIsPoisonC =
- ConstantInt::get(Type::getInt1Ty(Sel.getContext()), IntMinIsPoison);
- Instruction *Abs =
- IC.Builder.CreateBinaryIntrinsic(Intrinsic::abs, LHS, IntMinIsPoisonC);
+ // Note that NSW flag can only be propagated for normal, non-negated abs!
+ bool IntMinIsPoison = SPF == SelectPatternFlavor::SPF_ABS &&
+ match(RHS, m_NSWNeg(m_Specific(LHS)));
+ Constant *IntMinIsPoisonC =
+ ConstantInt::get(Type::getInt1Ty(Sel.getContext()), IntMinIsPoison);
+ Instruction *Abs =
+ IC.Builder.CreateBinaryIntrinsic(Intrinsic::abs, LHS, IntMinIsPoisonC);
- if (SPF == SelectPatternFlavor::SPF_NABS)
- return BinaryOperator::CreateNeg(Abs); // Always without NSW flag!
+ if (SPF == SelectPatternFlavor::SPF_NABS)
+ return BinaryOperator::CreateNeg(Abs); // Always without NSW flag!
- return IC.replaceInstUsesWith(Sel, Abs);
+ return IC.replaceInstUsesWith(Sel, Abs);
}
/// If we have a select with an equality comparison, then we know the value in
@@ -1093,56 +1093,56 @@ static Instruction *canonicalizeAbsNabs(SelectInst &Sel, ICmpInst &Cmp,
///
/// We can't replace %sel with %add unless we strip away the flags.
/// TODO: Wrapping flags could be preserved in some cases with better analysis.
-Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
- ICmpInst &Cmp) {
- // Value equivalence substitution requires an all-or-nothing replacement.
- // It does not make sense for a vector compare where each lane is chosen
- // independently.
- if (!Cmp.isEquality() || Cmp.getType()->isVectorTy())
+Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
+ ICmpInst &Cmp) {
+ // Value equivalence substitution requires an all-or-nothing replacement.
+ // It does not make sense for a vector compare where each lane is chosen
+ // independently.
+ if (!Cmp.isEquality() || Cmp.getType()->isVectorTy())
return nullptr;
// Canonicalize the pattern to ICMP_EQ by swapping the select operands.
Value *TrueVal = Sel.getTrueValue(), *FalseVal = Sel.getFalseValue();
- bool Swapped = false;
- if (Cmp.getPredicate() == ICmpInst::ICMP_NE) {
+ bool Swapped = false;
+ if (Cmp.getPredicate() == ICmpInst::ICMP_NE) {
std::swap(TrueVal, FalseVal);
- Swapped = true;
- }
-
- // In X == Y ? f(X) : Z, try to evaluate f(Y) and replace the operand.
- // Make sure Y cannot be undef though, as we might pick different values for
- // undef in the icmp and in f(Y). Additionally, take care to avoid replacing
- // X == Y ? X : Z with X == Y ? Y : Z, as that would lead to an infinite
- // replacement cycle.
- Value *CmpLHS = Cmp.getOperand(0), *CmpRHS = Cmp.getOperand(1);
- if (TrueVal != CmpLHS &&
- isGuaranteedNotToBeUndefOrPoison(CmpRHS, SQ.AC, &Sel, &DT)) {
- if (Value *V = SimplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, SQ,
- /* AllowRefinement */ true))
- return replaceOperand(Sel, Swapped ? 2 : 1, V);
-
- // Even if TrueVal does not simplify, we can directly replace a use of
- // CmpLHS with CmpRHS, as long as the instruction is not used anywhere
- // else and is safe to speculatively execute (we may end up executing it
- // with different operands, which should not cause side-effects or trigger
- // undefined behavior). Only do this if CmpRHS is a constant, as
- // profitability is not clear for other cases.
- // FIXME: The replacement could be performed recursively.
- if (match(CmpRHS, m_ImmConstant()) && !match(CmpLHS, m_ImmConstant()))
- if (auto *I = dyn_cast<Instruction>(TrueVal))
- if (I->hasOneUse() && isSafeToSpeculativelyExecute(I))
- for (Use &U : I->operands())
- if (U == CmpLHS) {
- replaceUse(U, CmpRHS);
- return &Sel;
- }
- }
- if (TrueVal != CmpRHS &&
- isGuaranteedNotToBeUndefOrPoison(CmpLHS, SQ.AC, &Sel, &DT))
- if (Value *V = SimplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, SQ,
- /* AllowRefinement */ true))
- return replaceOperand(Sel, Swapped ? 2 : 1, V);
-
+ Swapped = true;
+ }
+
+ // In X == Y ? f(X) : Z, try to evaluate f(Y) and replace the operand.
+ // Make sure Y cannot be undef though, as we might pick different values for
+ // undef in the icmp and in f(Y). Additionally, take care to avoid replacing
+ // X == Y ? X : Z with X == Y ? Y : Z, as that would lead to an infinite
+ // replacement cycle.
+ Value *CmpLHS = Cmp.getOperand(0), *CmpRHS = Cmp.getOperand(1);
+ if (TrueVal != CmpLHS &&
+ isGuaranteedNotToBeUndefOrPoison(CmpRHS, SQ.AC, &Sel, &DT)) {
+ if (Value *V = SimplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, SQ,
+ /* AllowRefinement */ true))
+ return replaceOperand(Sel, Swapped ? 2 : 1, V);
+
+ // Even if TrueVal does not simplify, we can directly replace a use of
+ // CmpLHS with CmpRHS, as long as the instruction is not used anywhere
+ // else and is safe to speculatively execute (we may end up executing it
+ // with different operands, which should not cause side-effects or trigger
+ // undefined behavior). Only do this if CmpRHS is a constant, as
+ // profitability is not clear for other cases.
+ // FIXME: The replacement could be performed recursively.
+ if (match(CmpRHS, m_ImmConstant()) && !match(CmpLHS, m_ImmConstant()))
+ if (auto *I = dyn_cast<Instruction>(TrueVal))
+ if (I->hasOneUse() && isSafeToSpeculativelyExecute(I))
+ for (Use &U : I->operands())
+ if (U == CmpLHS) {
+ replaceUse(U, CmpRHS);
+ return &Sel;
+ }
+ }
+ if (TrueVal != CmpRHS &&
+ isGuaranteedNotToBeUndefOrPoison(CmpLHS, SQ.AC, &Sel, &DT))
+ if (Value *V = SimplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, SQ,
+ /* AllowRefinement */ true))
+ return replaceOperand(Sel, Swapped ? 2 : 1, V);
+
auto *FalseInst = dyn_cast<Instruction>(FalseVal);
if (!FalseInst)
return nullptr;
@@ -1150,7 +1150,7 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
// InstSimplify already performed this fold if it was possible subject to
// current poison-generating flags. Try the transform again with
// poison-generating flags temporarily dropped.
- bool WasNUW = false, WasNSW = false, WasExact = false, WasInBounds = false;
+ bool WasNUW = false, WasNSW = false, WasExact = false, WasInBounds = false;
if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(FalseVal)) {
WasNUW = OBO->hasNoUnsignedWrap();
WasNSW = OBO->hasNoSignedWrap();
@@ -1161,20 +1161,20 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
WasExact = PEO->isExact();
FalseInst->setIsExact(false);
}
- if (auto *GEP = dyn_cast<GetElementPtrInst>(FalseVal)) {
- WasInBounds = GEP->isInBounds();
- GEP->setIsInBounds(false);
- }
+ if (auto *GEP = dyn_cast<GetElementPtrInst>(FalseVal)) {
+ WasInBounds = GEP->isInBounds();
+ GEP->setIsInBounds(false);
+ }
// Try each equivalence substitution possibility.
// We have an 'EQ' comparison, so the select's false value will propagate.
// Example:
// (X == 42) ? 43 : (X + 1) --> (X == 42) ? (X + 1) : (X + 1) --> X + 1
- if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, SQ,
+ if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, SQ,
/* AllowRefinement */ false) == TrueVal ||
- SimplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, SQ,
+ SimplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, SQ,
/* AllowRefinement */ false) == TrueVal) {
- return replaceInstUsesWith(Sel, FalseVal);
+ return replaceInstUsesWith(Sel, FalseVal);
}
// Restore poison-generating flags if the transform did not apply.
@@ -1184,8 +1184,8 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
FalseInst->setHasNoSignedWrap();
if (WasExact)
FalseInst->setIsExact();
- if (WasInBounds)
- cast<GetElementPtrInst>(FalseInst)->setIsInBounds();
+ if (WasInBounds)
+ cast<GetElementPtrInst>(FalseInst)->setIsInBounds();
return nullptr;
}
@@ -1236,7 +1236,7 @@ static Instruction *canonicalizeClampLike(SelectInst &Sel0, ICmpInst &Cmp0,
APInt::getAllOnesValue(
C0->getType()->getScalarSizeInBits()))))
return nullptr; // Can't do, have all-ones element[s].
- C0 = InstCombiner::AddOne(C0);
+ C0 = InstCombiner::AddOne(C0);
std::swap(X, Sel1);
break;
case ICmpInst::Predicate::ICMP_UGE:
@@ -1296,7 +1296,7 @@ static Instruction *canonicalizeClampLike(SelectInst &Sel0, ICmpInst &Cmp0,
APInt::getSignedMaxValue(
C2->getType()->getScalarSizeInBits()))))
return nullptr; // Can't do, have signed max element[s].
- C2 = InstCombiner::AddOne(C2);
+ C2 = InstCombiner::AddOne(C2);
LLVM_FALLTHROUGH;
case ICmpInst::Predicate::ICMP_SGE:
// Also non-canonical, but here we don't need to change C2,
@@ -1343,7 +1343,7 @@ static Instruction *canonicalizeClampLike(SelectInst &Sel0, ICmpInst &Cmp0,
// and swap the hands of select.
static Instruction *
tryToReuseConstantFromSelectInComparison(SelectInst &Sel, ICmpInst &Cmp,
- InstCombinerImpl &IC) {
+ InstCombinerImpl &IC) {
ICmpInst::Predicate Pred;
Value *X;
Constant *C0;
@@ -1358,7 +1358,7 @@ tryToReuseConstantFromSelectInComparison(SelectInst &Sel, ICmpInst &Cmp,
// If comparison predicate is non-canonical, then we certainly won't be able
// to make it canonical; canonicalizeCmpWithConstant() already tried.
- if (!InstCombiner::isCanonicalPredicate(Pred))
+ if (!InstCombiner::isCanonicalPredicate(Pred))
return nullptr;
// If the [input] type of comparison and select type are different, lets abort
@@ -1386,8 +1386,8 @@ tryToReuseConstantFromSelectInComparison(SelectInst &Sel, ICmpInst &Cmp,
return nullptr;
// Check the constant we'd have with flipped-strictness predicate.
- auto FlippedStrictness =
- InstCombiner::getFlippedStrictnessPredicateAndConstant(Pred, C0);
+ auto FlippedStrictness =
+ InstCombiner::getFlippedStrictnessPredicateAndConstant(Pred, C0);
if (!FlippedStrictness)
return nullptr;
@@ -1410,10 +1410,10 @@ tryToReuseConstantFromSelectInComparison(SelectInst &Sel, ICmpInst &Cmp,
}
/// Visit a SelectInst that has an ICmpInst as its first operand.
-Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI,
- ICmpInst *ICI) {
- if (Instruction *NewSel = foldSelectValueEquivalence(SI, *ICI))
- return NewSel;
+Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI,
+ ICmpInst *ICI) {
+ if (Instruction *NewSel = foldSelectValueEquivalence(SI, *ICI))
+ return NewSel;
if (Instruction *NewSel = canonicalizeMinMaxWithConstant(SI, *ICI, *this))
return NewSel;
@@ -1563,11 +1563,11 @@ static bool canSelectOperandBeMappingIntoPredBlock(const Value *V,
/// We have an SPF (e.g. a min or max) of an SPF of the form:
/// SPF2(SPF1(A, B), C)
-Instruction *InstCombinerImpl::foldSPFofSPF(Instruction *Inner,
- SelectPatternFlavor SPF1, Value *A,
- Value *B, Instruction &Outer,
- SelectPatternFlavor SPF2,
- Value *C) {
+Instruction *InstCombinerImpl::foldSPFofSPF(Instruction *Inner,
+ SelectPatternFlavor SPF1, Value *A,
+ Value *B, Instruction &Outer,
+ SelectPatternFlavor SPF2,
+ Value *C) {
if (Outer.getType() != Inner->getType())
return nullptr;
@@ -1884,7 +1884,7 @@ foldOverflowingAddSubSelect(SelectInst &SI, InstCombiner::BuilderTy &Builder) {
return CallInst::Create(F, {X, Y});
}
-Instruction *InstCombinerImpl::foldSelectExtConst(SelectInst &Sel) {
+Instruction *InstCombinerImpl::foldSelectExtConst(SelectInst &Sel) {
Constant *C;
if (!match(Sel.getTrueValue(), m_Constant(C)) &&
!match(Sel.getFalseValue(), m_Constant(C)))
@@ -1950,11 +1950,11 @@ Instruction *InstCombinerImpl::foldSelectExtConst(SelectInst &Sel) {
static Instruction *canonicalizeSelectToShuffle(SelectInst &SI) {
Value *CondVal = SI.getCondition();
Constant *CondC;
- auto *CondValTy = dyn_cast<FixedVectorType>(CondVal->getType());
- if (!CondValTy || !match(CondVal, m_Constant(CondC)))
+ auto *CondValTy = dyn_cast<FixedVectorType>(CondVal->getType());
+ if (!CondValTy || !match(CondVal, m_Constant(CondC)))
return nullptr;
- unsigned NumElts = CondValTy->getNumElements();
+ unsigned NumElts = CondValTy->getNumElements();
SmallVector<int, 16> Mask;
Mask.reserve(NumElts);
for (unsigned i = 0; i != NumElts; ++i) {
@@ -1986,8 +1986,8 @@ static Instruction *canonicalizeSelectToShuffle(SelectInst &SI) {
/// to a vector select by splatting the condition. A splat may get folded with
/// other operations in IR and having all operands of a select be vector types
/// is likely better for vector codegen.
-static Instruction *canonicalizeScalarSelectOfVecs(SelectInst &Sel,
- InstCombinerImpl &IC) {
+static Instruction *canonicalizeScalarSelectOfVecs(SelectInst &Sel,
+ InstCombinerImpl &IC) {
auto *Ty = dyn_cast<VectorType>(Sel.getType());
if (!Ty)
return nullptr;
@@ -2000,8 +2000,8 @@ static Instruction *canonicalizeScalarSelectOfVecs(SelectInst &Sel,
// select (extelt V, Index), T, F --> select (splat V, Index), T, F
// Splatting the extracted condition reduces code (we could directly create a
// splat shuffle of the source vector to eliminate the intermediate step).
- return IC.replaceOperand(
- Sel, 0, IC.Builder.CreateVectorSplat(Ty->getElementCount(), Cond));
+ return IC.replaceOperand(
+ Sel, 0, IC.Builder.CreateVectorSplat(Ty->getElementCount(), Cond));
}
/// Reuse bitcasted operands between a compare and select:
@@ -2157,7 +2157,7 @@ static Instruction *moveAddAfterMinMax(SelectPatternFlavor SPF, Value *X,
}
/// Match a sadd_sat or ssub_sat which is using min/max to clamp the value.
-Instruction *InstCombinerImpl::matchSAddSubSat(SelectInst &MinMax1) {
+Instruction *InstCombinerImpl::matchSAddSubSat(SelectInst &MinMax1) {
Type *Ty = MinMax1.getType();
// We are looking for a tree of:
@@ -2278,42 +2278,42 @@ static Instruction *factorizeMinMaxTree(SelectPatternFlavor SPF, Value *LHS,
return SelectInst::Create(CmpABC, MinMaxOp, ThirdOp);
}
-/// Try to reduce a funnel/rotate pattern that includes a compare and select
-/// into a funnel shift intrinsic. Example:
+/// Try to reduce a funnel/rotate pattern that includes a compare and select
+/// into a funnel shift intrinsic. Example:
/// rotl32(a, b) --> (b == 0 ? a : ((a >> (32 - b)) | (a << b)))
/// --> call llvm.fshl.i32(a, a, b)
-/// fshl32(a, b, c) --> (c == 0 ? a : ((b >> (32 - c)) | (a << c)))
-/// --> call llvm.fshl.i32(a, b, c)
-/// fshr32(a, b, c) --> (c == 0 ? b : ((a >> (32 - c)) | (b << c)))
-/// --> call llvm.fshr.i32(a, b, c)
-static Instruction *foldSelectFunnelShift(SelectInst &Sel,
- InstCombiner::BuilderTy &Builder) {
- // This must be a power-of-2 type for a bitmasking transform to be valid.
- unsigned Width = Sel.getType()->getScalarSizeInBits();
- if (!isPowerOf2_32(Width))
- return nullptr;
-
- BinaryOperator *Or0, *Or1;
- if (!match(Sel.getFalseValue(), m_OneUse(m_Or(m_BinOp(Or0), m_BinOp(Or1)))))
- return nullptr;
-
- Value *SV0, *SV1, *SA0, *SA1;
- if (!match(Or0, m_OneUse(m_LogicalShift(m_Value(SV0),
- m_ZExtOrSelf(m_Value(SA0))))) ||
- !match(Or1, m_OneUse(m_LogicalShift(m_Value(SV1),
- m_ZExtOrSelf(m_Value(SA1))))) ||
- Or0->getOpcode() == Or1->getOpcode())
- return nullptr;
-
- // Canonicalize to or(shl(SV0, SA0), lshr(SV1, SA1)).
- if (Or0->getOpcode() == BinaryOperator::LShr) {
- std::swap(Or0, Or1);
- std::swap(SV0, SV1);
- std::swap(SA0, SA1);
- }
- assert(Or0->getOpcode() == BinaryOperator::Shl &&
- Or1->getOpcode() == BinaryOperator::LShr &&
- "Illegal or(shift,shift) pair");
+/// fshl32(a, b, c) --> (c == 0 ? a : ((b >> (32 - c)) | (a << c)))
+/// --> call llvm.fshl.i32(a, b, c)
+/// fshr32(a, b, c) --> (c == 0 ? b : ((a >> (32 - c)) | (b << c)))
+/// --> call llvm.fshr.i32(a, b, c)
+static Instruction *foldSelectFunnelShift(SelectInst &Sel,
+ InstCombiner::BuilderTy &Builder) {
+ // This must be a power-of-2 type for a bitmasking transform to be valid.
+ unsigned Width = Sel.getType()->getScalarSizeInBits();
+ if (!isPowerOf2_32(Width))
+ return nullptr;
+
+ BinaryOperator *Or0, *Or1;
+ if (!match(Sel.getFalseValue(), m_OneUse(m_Or(m_BinOp(Or0), m_BinOp(Or1)))))
+ return nullptr;
+
+ Value *SV0, *SV1, *SA0, *SA1;
+ if (!match(Or0, m_OneUse(m_LogicalShift(m_Value(SV0),
+ m_ZExtOrSelf(m_Value(SA0))))) ||
+ !match(Or1, m_OneUse(m_LogicalShift(m_Value(SV1),
+ m_ZExtOrSelf(m_Value(SA1))))) ||
+ Or0->getOpcode() == Or1->getOpcode())
+ return nullptr;
+
+ // Canonicalize to or(shl(SV0, SA0), lshr(SV1, SA1)).
+ if (Or0->getOpcode() == BinaryOperator::LShr) {
+ std::swap(Or0, Or1);
+ std::swap(SV0, SV1);
+ std::swap(SA0, SA1);
+ }
+ assert(Or0->getOpcode() == BinaryOperator::Shl &&
+ Or1->getOpcode() == BinaryOperator::LShr &&
+ "Illegal or(shift,shift) pair");
// Check the shift amounts to see if they are an opposite pair.
Value *ShAmt;
@@ -2324,15 +2324,15 @@ static Instruction *foldSelectFunnelShift(SelectInst &Sel,
else
return nullptr;
- // We should now have this pattern:
- // select ?, TVal, (or (shl SV0, SA0), (lshr SV1, SA1))
- // The false value of the select must be a funnel-shift of the true value:
- // IsFShl -> TVal must be SV0 else TVal must be SV1.
- bool IsFshl = (ShAmt == SA0);
- Value *TVal = Sel.getTrueValue();
- if ((IsFshl && TVal != SV0) || (!IsFshl && TVal != SV1))
- return nullptr;
-
+ // We should now have this pattern:
+ // select ?, TVal, (or (shl SV0, SA0), (lshr SV1, SA1))
+ // The false value of the select must be a funnel-shift of the true value:
+ // IsFShl -> TVal must be SV0 else TVal must be SV1.
+ bool IsFshl = (ShAmt == SA0);
+ Value *TVal = Sel.getTrueValue();
+ if ((IsFshl && TVal != SV0) || (!IsFshl && TVal != SV1))
+ return nullptr;
+
// Finally, see if the select is filtering out a shift-by-zero.
Value *Cond = Sel.getCondition();
ICmpInst::Predicate Pred;
@@ -2340,21 +2340,21 @@ static Instruction *foldSelectFunnelShift(SelectInst &Sel,
Pred != ICmpInst::ICMP_EQ)
return nullptr;
- // If this is not a rotate then the select was blocking poison from the
- // 'shift-by-zero' non-TVal, but a funnel shift won't - so freeze it.
- if (SV0 != SV1) {
- if (IsFshl && !llvm::isGuaranteedNotToBePoison(SV1))
- SV1 = Builder.CreateFreeze(SV1);
- else if (!IsFshl && !llvm::isGuaranteedNotToBePoison(SV0))
- SV0 = Builder.CreateFreeze(SV0);
- }
-
- // This is a funnel/rotate that avoids shift-by-bitwidth UB in a suboptimal way.
+ // If this is not a rotate then the select was blocking poison from the
+ // 'shift-by-zero' non-TVal, but a funnel shift won't - so freeze it.
+ if (SV0 != SV1) {
+ if (IsFshl && !llvm::isGuaranteedNotToBePoison(SV1))
+ SV1 = Builder.CreateFreeze(SV1);
+ else if (!IsFshl && !llvm::isGuaranteedNotToBePoison(SV0))
+ SV0 = Builder.CreateFreeze(SV0);
+ }
+
+ // This is a funnel/rotate that avoids shift-by-bitwidth UB in a suboptimal way.
// Convert to funnel shift intrinsic.
Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
Function *F = Intrinsic::getDeclaration(Sel.getModule(), IID, Sel.getType());
- ShAmt = Builder.CreateZExt(ShAmt, Sel.getType());
- return IntrinsicInst::Create(F, { SV0, SV1, ShAmt });
+ ShAmt = Builder.CreateZExt(ShAmt, Sel.getType());
+ return IntrinsicInst::Create(F, { SV0, SV1, ShAmt });
}
static Instruction *foldSelectToCopysign(SelectInst &Sel,
@@ -2378,8 +2378,8 @@ static Instruction *foldSelectToCopysign(SelectInst &Sel,
bool IsTrueIfSignSet;
ICmpInst::Predicate Pred;
if (!match(Cond, m_OneUse(m_ICmp(Pred, m_BitCast(m_Value(X)), m_APInt(C)))) ||
- !InstCombiner::isSignBitCheck(Pred, *C, IsTrueIfSignSet) ||
- X->getType() != SelType)
+ !InstCombiner::isSignBitCheck(Pred, *C, IsTrueIfSignSet) ||
+ X->getType() != SelType)
return nullptr;
// If needed, negate the value that will be the sign argument of the copysign:
@@ -2400,7 +2400,7 @@ static Instruction *foldSelectToCopysign(SelectInst &Sel,
return CopySign;
}
-Instruction *InstCombinerImpl::foldVectorSelect(SelectInst &Sel) {
+Instruction *InstCombinerImpl::foldVectorSelect(SelectInst &Sel) {
auto *VecTy = dyn_cast<FixedVectorType>(Sel.getType());
if (!VecTy)
return nullptr;
@@ -2530,33 +2530,33 @@ static Instruction *foldSelectToPhi(SelectInst &Sel, const DominatorTree &DT,
return nullptr;
}
-static Value *foldSelectWithFrozenICmp(SelectInst &Sel, InstCombiner::BuilderTy &Builder) {
- FreezeInst *FI = dyn_cast<FreezeInst>(Sel.getCondition());
- if (!FI)
- return nullptr;
-
- Value *Cond = FI->getOperand(0);
- Value *TrueVal = Sel.getTrueValue(), *FalseVal = Sel.getFalseValue();
-
- // select (freeze(x == y)), x, y --> y
- // select (freeze(x != y)), x, y --> x
- // The freeze should be only used by this select. Otherwise, remaining uses of
- // the freeze can observe a contradictory value.
- // c = freeze(x == y) ; Let's assume that y = poison & x = 42; c is 0 or 1
- // a = select c, x, y ;
- // f(a, c) ; f(poison, 1) cannot happen, but if a is folded
- // ; to y, this can happen.
- CmpInst::Predicate Pred;
- if (FI->hasOneUse() &&
- match(Cond, m_c_ICmp(Pred, m_Specific(TrueVal), m_Specific(FalseVal))) &&
- (Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE)) {
- return Pred == ICmpInst::ICMP_EQ ? FalseVal : TrueVal;
- }
-
- return nullptr;
-}
-
-Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
+static Value *foldSelectWithFrozenICmp(SelectInst &Sel, InstCombiner::BuilderTy &Builder) {
+ FreezeInst *FI = dyn_cast<FreezeInst>(Sel.getCondition());
+ if (!FI)
+ return nullptr;
+
+ Value *Cond = FI->getOperand(0);
+ Value *TrueVal = Sel.getTrueValue(), *FalseVal = Sel.getFalseValue();
+
+ // select (freeze(x == y)), x, y --> y
+ // select (freeze(x != y)), x, y --> x
+ // The freeze should be only used by this select. Otherwise, remaining uses of
+ // the freeze can observe a contradictory value.
+ // c = freeze(x == y) ; Let's assume that y = poison & x = 42; c is 0 or 1
+ // a = select c, x, y ;
+ // f(a, c) ; f(poison, 1) cannot happen, but if a is folded
+ // ; to y, this can happen.
+ CmpInst::Predicate Pred;
+ if (FI->hasOneUse() &&
+ match(Cond, m_c_ICmp(Pred, m_Specific(TrueVal), m_Specific(FalseVal))) &&
+ (Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE)) {
+ return Pred == ICmpInst::ICMP_EQ ? FalseVal : TrueVal;
+ }
+
+ return nullptr;
+}
+
+Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
Value *CondVal = SI.getCondition();
Value *TrueVal = SI.getTrueValue();
Value *FalseVal = SI.getFalseValue();
@@ -2592,45 +2592,45 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
if (SelType->isIntOrIntVectorTy(1) &&
TrueVal->getType() == CondVal->getType()) {
- if (match(TrueVal, m_One()) &&
- (EnableUnsafeSelectTransform || impliesPoison(FalseVal, CondVal))) {
+ if (match(TrueVal, m_One()) &&
+ (EnableUnsafeSelectTransform || impliesPoison(FalseVal, CondVal))) {
// Change: A = select B, true, C --> A = or B, C
return BinaryOperator::CreateOr(CondVal, FalseVal);
}
- if (match(FalseVal, m_Zero()) &&
- (EnableUnsafeSelectTransform || impliesPoison(TrueVal, CondVal))) {
- // Change: A = select B, C, false --> A = and B, C
- return BinaryOperator::CreateAnd(CondVal, TrueVal);
- }
-
- // select a, false, b -> select !a, b, false
+ if (match(FalseVal, m_Zero()) &&
+ (EnableUnsafeSelectTransform || impliesPoison(TrueVal, CondVal))) {
+ // Change: A = select B, C, false --> A = and B, C
+ return BinaryOperator::CreateAnd(CondVal, TrueVal);
+ }
+
+ // select a, false, b -> select !a, b, false
if (match(TrueVal, m_Zero())) {
Value *NotCond = Builder.CreateNot(CondVal, "not." + CondVal->getName());
- return SelectInst::Create(NotCond, FalseVal,
- ConstantInt::getFalse(SelType));
+ return SelectInst::Create(NotCond, FalseVal,
+ ConstantInt::getFalse(SelType));
}
- // select a, b, true -> select !a, true, b
+ // select a, b, true -> select !a, true, b
if (match(FalseVal, m_One())) {
Value *NotCond = Builder.CreateNot(CondVal, "not." + CondVal->getName());
- return SelectInst::Create(NotCond, ConstantInt::getTrue(SelType),
- TrueVal);
+ return SelectInst::Create(NotCond, ConstantInt::getTrue(SelType),
+ TrueVal);
}
- // select a, a, b -> select a, true, b
+ // select a, a, b -> select a, true, b
if (CondVal == TrueVal)
- return replaceOperand(SI, 1, ConstantInt::getTrue(SelType));
- // select a, b, a -> select a, b, false
+ return replaceOperand(SI, 1, ConstantInt::getTrue(SelType));
+ // select a, b, a -> select a, b, false
if (CondVal == FalseVal)
- return replaceOperand(SI, 2, ConstantInt::getFalse(SelType));
+ return replaceOperand(SI, 2, ConstantInt::getFalse(SelType));
- // select a, !a, b -> select !a, b, false
+ // select a, !a, b -> select !a, b, false
if (match(TrueVal, m_Not(m_Specific(CondVal))))
- return SelectInst::Create(TrueVal, FalseVal,
- ConstantInt::getFalse(SelType));
- // select a, b, !a -> select !a, true, b
+ return SelectInst::Create(TrueVal, FalseVal,
+ ConstantInt::getFalse(SelType));
+ // select a, b, !a -> select !a, true, b
if (match(FalseVal, m_Not(m_Specific(CondVal))))
- return SelectInst::Create(FalseVal, ConstantInt::getTrue(SelType),
- TrueVal);
+ return SelectInst::Create(FalseVal, ConstantInt::getTrue(SelType),
+ TrueVal);
}
// Selecting between two integer or vector splat integer constants?
@@ -2639,10 +2639,10 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
// select i1 %c, <2 x i8> <1, 1>, <2 x i8> <0, 0>
// because that may need 3 instructions to splat the condition value:
// extend, insertelement, shufflevector.
- //
- // Do not handle i1 TrueVal and FalseVal otherwise would result in
- // zext/sext i1 to i1.
- if (SelType->isIntOrIntVectorTy() && !SelType->isIntOrIntVectorTy(1) &&
+ //
+ // Do not handle i1 TrueVal and FalseVal otherwise would result in
+ // zext/sext i1 to i1.
+ if (SelType->isIntOrIntVectorTy() && !SelType->isIntOrIntVectorTy(1) &&
CondVal->getType()->isVectorTy() == SelType->isVectorTy()) {
// select C, 1, 0 -> zext C to int
if (match(TrueVal, m_One()) && match(FalseVal, m_Zero()))
@@ -2889,9 +2889,9 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
return replaceOperand(SI, 1, TrueSI->getTrueValue());
}
// select(C0, select(C1, a, b), b) -> select(C0&C1, a, b)
- // We choose this as normal form to enable folding on the And and
- // shortening paths for the values (this helps getUnderlyingObjects() for
- // example).
+ // We choose this as normal form to enable folding on the And and
+ // shortening paths for the values (this helps getUnderlyingObjects() for
+ // example).
if (TrueSI->getFalseValue() == FalseVal && TrueSI->hasOneUse()) {
Value *And = Builder.CreateAnd(CondVal, TrueSI->getCondition());
replaceOperand(SI, 0, And);
@@ -2974,8 +2974,8 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
}
Value *NotCond;
- if (match(CondVal, m_Not(m_Value(NotCond))) &&
- !InstCombiner::shouldAvoidAbsorbingNotIntoSelect(SI)) {
+ if (match(CondVal, m_Not(m_Value(NotCond))) &&
+ !InstCombiner::shouldAvoidAbsorbingNotIntoSelect(SI)) {
replaceOperand(SI, 0, NotCond);
SI.swapValues();
SI.swapProfMetadata();
@@ -3009,8 +3009,8 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
if (Instruction *Select = foldSelectBinOpIdentity(SI, TLI, *this))
return Select;
- if (Instruction *Funnel = foldSelectFunnelShift(SI, Builder))
- return Funnel;
+ if (Instruction *Funnel = foldSelectFunnelShift(SI, Builder))
+ return Funnel;
if (Instruction *Copysign = foldSelectToCopysign(SI, Builder))
return Copysign;
@@ -3018,8 +3018,8 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
if (Instruction *PN = foldSelectToPhi(SI, DT, Builder))
return replaceInstUsesWith(SI, PN);
- if (Value *Fr = foldSelectWithFrozenICmp(SI, Builder))
- return replaceInstUsesWith(SI, Fr);
-
+ if (Value *Fr = foldSelectWithFrozenICmp(SI, Builder))
+ return replaceInstUsesWith(SI, Fr);
+
return nullptr;
}
diff --git a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineShifts.cpp b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 185c1d04ee..127bf80809 100644
--- a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -15,36 +15,36 @@
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PatternMatch.h"
-#include "llvm/Transforms/InstCombine/InstCombiner.h"
+#include "llvm/Transforms/InstCombine/InstCombiner.h"
using namespace llvm;
using namespace PatternMatch;
#define DEBUG_TYPE "instcombine"
-bool canTryToConstantAddTwoShiftAmounts(Value *Sh0, Value *ShAmt0, Value *Sh1,
- Value *ShAmt1) {
- // We have two shift amounts from two different shifts. The types of those
- // shift amounts may not match. If that's the case let's bailout now..
- if (ShAmt0->getType() != ShAmt1->getType())
- return false;
-
- // As input, we have the following pattern:
- // Sh0 (Sh1 X, Q), K
- // We want to rewrite that as:
- // Sh x, (Q+K) iff (Q+K) u< bitwidth(x)
- // While we know that originally (Q+K) would not overflow
- // (because 2 * (N-1) u<= iN -1), we have looked past extensions of
- // shift amounts. so it may now overflow in smaller bitwidth.
- // To ensure that does not happen, we need to ensure that the total maximal
- // shift amount is still representable in that smaller bit width.
- unsigned MaximalPossibleTotalShiftAmount =
- (Sh0->getType()->getScalarSizeInBits() - 1) +
- (Sh1->getType()->getScalarSizeInBits() - 1);
- APInt MaximalRepresentableShiftAmount =
- APInt::getAllOnesValue(ShAmt0->getType()->getScalarSizeInBits());
- return MaximalRepresentableShiftAmount.uge(MaximalPossibleTotalShiftAmount);
-}
-
+bool canTryToConstantAddTwoShiftAmounts(Value *Sh0, Value *ShAmt0, Value *Sh1,
+ Value *ShAmt1) {
+ // We have two shift amounts from two different shifts. The types of those
+ // shift amounts may not match. If that's the case let's bailout now..
+ if (ShAmt0->getType() != ShAmt1->getType())
+ return false;
+
+ // As input, we have the following pattern:
+ // Sh0 (Sh1 X, Q), K
+ // We want to rewrite that as:
+ // Sh x, (Q+K) iff (Q+K) u< bitwidth(x)
+ // While we know that originally (Q+K) would not overflow
+ // (because 2 * (N-1) u<= iN -1), we have looked past extensions of
+ // shift amounts. so it may now overflow in smaller bitwidth.
+ // To ensure that does not happen, we need to ensure that the total maximal
+ // shift amount is still representable in that smaller bit width.
+ unsigned MaximalPossibleTotalShiftAmount =
+ (Sh0->getType()->getScalarSizeInBits() - 1) +
+ (Sh1->getType()->getScalarSizeInBits() - 1);
+ APInt MaximalRepresentableShiftAmount =
+ APInt::getAllOnesValue(ShAmt0->getType()->getScalarSizeInBits());
+ return MaximalRepresentableShiftAmount.uge(MaximalPossibleTotalShiftAmount);
+}
+
// Given pattern:
// (x shiftopcode Q) shiftopcode K
// we should rewrite it as
@@ -56,7 +56,7 @@ bool canTryToConstantAddTwoShiftAmounts(Value *Sh0, Value *ShAmt0, Value *Sh1,
//
// AnalyzeForSignBitExtraction indicates that we will only analyze whether this
// pattern has any 2 right-shifts that sum to 1 less than original bit width.
-Value *InstCombinerImpl::reassociateShiftAmtsOfTwoSameDirectionShifts(
+Value *InstCombinerImpl::reassociateShiftAmtsOfTwoSameDirectionShifts(
BinaryOperator *Sh0, const SimplifyQuery &SQ,
bool AnalyzeForSignBitExtraction) {
// Look for a shift of some instruction, ignore zext of shift amount if any.
@@ -81,8 +81,8 @@ Value *InstCombinerImpl::reassociateShiftAmtsOfTwoSameDirectionShifts(
if (!match(Sh1, m_Shift(m_Value(X), m_ZExtOrSelf(m_Value(ShAmt1)))))
return nullptr;
- // Verify that it would be safe to try to add those two shift amounts.
- if (!canTryToConstantAddTwoShiftAmounts(Sh0, ShAmt0, Sh1, ShAmt1))
+ // Verify that it would be safe to try to add those two shift amounts.
+ if (!canTryToConstantAddTwoShiftAmounts(Sh0, ShAmt0, Sh1, ShAmt1))
return nullptr;
// We are only looking for signbit extraction if we have two right shifts.
@@ -226,9 +226,9 @@ dropRedundantMaskingOfLeftShiftInput(BinaryOperator *OuterShift,
// Peek through an optional zext of the shift amount.
match(MaskShAmt, m_ZExtOrSelf(m_Value(MaskShAmt)));
- // Verify that it would be safe to try to add those two shift amounts.
- if (!canTryToConstantAddTwoShiftAmounts(OuterShift, ShiftShAmt, Masked,
- MaskShAmt))
+ // Verify that it would be safe to try to add those two shift amounts.
+ if (!canTryToConstantAddTwoShiftAmounts(OuterShift, ShiftShAmt, Masked,
+ MaskShAmt))
return nullptr;
// Can we simplify (MaskShAmt+ShiftShAmt) ?
@@ -258,9 +258,9 @@ dropRedundantMaskingOfLeftShiftInput(BinaryOperator *OuterShift,
// Peek through an optional zext of the shift amount.
match(MaskShAmt, m_ZExtOrSelf(m_Value(MaskShAmt)));
- // Verify that it would be safe to try to add those two shift amounts.
- if (!canTryToConstantAddTwoShiftAmounts(OuterShift, ShiftShAmt, Masked,
- MaskShAmt))
+ // Verify that it would be safe to try to add those two shift amounts.
+ if (!canTryToConstantAddTwoShiftAmounts(OuterShift, ShiftShAmt, Masked,
+ MaskShAmt))
return nullptr;
// Can we simplify (ShiftShAmt-MaskShAmt) ?
@@ -334,8 +334,8 @@ static Instruction *foldShiftOfShiftedLogic(BinaryOperator &I,
if (!LogicInst || !LogicInst->isBitwiseLogicOp() || !LogicInst->hasOneUse())
return nullptr;
- Constant *C0, *C1;
- if (!match(I.getOperand(1), m_Constant(C1)))
+ Constant *C0, *C1;
+ if (!match(I.getOperand(1), m_Constant(C1)))
return nullptr;
Instruction::BinaryOps ShiftOpcode = I.getOpcode();
@@ -346,12 +346,12 @@ static Instruction *foldShiftOfShiftedLogic(BinaryOperator &I,
// TODO: Remove the one-use check if the other logic operand (Y) is constant.
Value *X, *Y;
auto matchFirstShift = [&](Value *V) {
- BinaryOperator *BO;
- APInt Threshold(Ty->getScalarSizeInBits(), Ty->getScalarSizeInBits());
- return match(V, m_BinOp(BO)) && BO->getOpcode() == ShiftOpcode &&
- match(V, m_OneUse(m_Shift(m_Value(X), m_Constant(C0)))) &&
- match(ConstantExpr::getAdd(C0, C1),
- m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, Threshold));
+ BinaryOperator *BO;
+ APInt Threshold(Ty->getScalarSizeInBits(), Ty->getScalarSizeInBits());
+ return match(V, m_BinOp(BO)) && BO->getOpcode() == ShiftOpcode &&
+ match(V, m_OneUse(m_Shift(m_Value(X), m_Constant(C0)))) &&
+ match(ConstantExpr::getAdd(C0, C1),
+ m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, Threshold));
};
// Logic ops are commutative, so check each operand for a match.
@@ -363,13 +363,13 @@ static Instruction *foldShiftOfShiftedLogic(BinaryOperator &I,
return nullptr;
// shift (logic (shift X, C0), Y), C1 -> logic (shift X, C0+C1), (shift Y, C1)
- Constant *ShiftSumC = ConstantExpr::getAdd(C0, C1);
+ Constant *ShiftSumC = ConstantExpr::getAdd(C0, C1);
Value *NewShift1 = Builder.CreateBinOp(ShiftOpcode, X, ShiftSumC);
Value *NewShift2 = Builder.CreateBinOp(ShiftOpcode, Y, I.getOperand(1));
return BinaryOperator::Create(LogicInst->getOpcode(), NewShift1, NewShift2);
}
-Instruction *InstCombinerImpl::commonShiftTransforms(BinaryOperator &I) {
+Instruction *InstCombinerImpl::commonShiftTransforms(BinaryOperator &I) {
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
assert(Op0->getType() == Op1->getType());
@@ -408,15 +408,15 @@ Instruction *InstCombinerImpl::commonShiftTransforms(BinaryOperator &I) {
return BinaryOperator::Create(
I.getOpcode(), Builder.CreateBinOp(I.getOpcode(), Op0, C), A);
- // X shift (A srem C) -> X shift (A and (C - 1)) iff C is a power of 2.
+ // X shift (A srem C) -> X shift (A and (C - 1)) iff C is a power of 2.
// Because shifts by negative values (which could occur if A were negative)
// are undefined.
- if (Op1->hasOneUse() && match(Op1, m_SRem(m_Value(A), m_Constant(C))) &&
- match(C, m_Power2())) {
+ if (Op1->hasOneUse() && match(Op1, m_SRem(m_Value(A), m_Constant(C))) &&
+ match(C, m_Power2())) {
// FIXME: Should this get moved into SimplifyDemandedBits by saying we don't
// demand the sign bit (and many others) here??
- Constant *Mask = ConstantExpr::getSub(C, ConstantInt::get(I.getType(), 1));
- Value *Rem = Builder.CreateAnd(A, Mask, Op1->getName());
+ Constant *Mask = ConstantExpr::getSub(C, ConstantInt::get(I.getType(), 1));
+ Value *Rem = Builder.CreateAnd(A, Mask, Op1->getName());
return replaceOperand(I, 1, Rem);
}
@@ -429,8 +429,8 @@ Instruction *InstCombinerImpl::commonShiftTransforms(BinaryOperator &I) {
/// Return true if we can simplify two logical (either left or right) shifts
/// that have constant shift amounts: OuterShift (InnerShift X, C1), C2.
static bool canEvaluateShiftedShift(unsigned OuterShAmt, bool IsOuterShl,
- Instruction *InnerShift,
- InstCombinerImpl &IC, Instruction *CxtI) {
+ Instruction *InnerShift,
+ InstCombinerImpl &IC, Instruction *CxtI) {
assert(InnerShift->isLogicalShift() && "Unexpected instruction type");
// We need constant scalar or constant splat shifts.
@@ -481,7 +481,7 @@ static bool canEvaluateShiftedShift(unsigned OuterShAmt, bool IsOuterShl,
/// where the client will ask if E can be computed shifted right by 64-bits. If
/// this succeeds, getShiftedValue() will be called to produce the value.
static bool canEvaluateShifted(Value *V, unsigned NumBits, bool IsLeftShift,
- InstCombinerImpl &IC, Instruction *CxtI) {
+ InstCombinerImpl &IC, Instruction *CxtI) {
// We can always evaluate constants shifted.
if (isa<Constant>(V))
return true;
@@ -592,7 +592,7 @@ static Value *foldShiftedShift(BinaryOperator *InnerShift, unsigned OuterShAmt,
/// When canEvaluateShifted() returns true for an expression, this function
/// inserts the new computation that produces the shifted value.
static Value *getShiftedValue(Value *V, unsigned NumBits, bool isLeftShift,
- InstCombinerImpl &IC, const DataLayout &DL) {
+ InstCombinerImpl &IC, const DataLayout &DL) {
// We can always evaluate constants shifted.
if (Constant *C = dyn_cast<Constant>(V)) {
if (isLeftShift)
@@ -602,7 +602,7 @@ static Value *getShiftedValue(Value *V, unsigned NumBits, bool isLeftShift,
}
Instruction *I = cast<Instruction>(V);
- IC.addToWorklist(I);
+ IC.addToWorklist(I);
switch (I->getOpcode()) {
default: llvm_unreachable("Inconsistency with CanEvaluateShifted");
@@ -652,15 +652,15 @@ static bool canShiftBinOpWithConstantRHS(BinaryOperator &Shift,
case Instruction::Or:
case Instruction::And:
return true;
- case Instruction::Xor:
- // Do not change a 'not' of logical shift because that would create a normal
- // 'xor'. The 'not' is likely better for analysis, SCEV, and codegen.
- return !(Shift.isLogicalShift() && match(BO, m_Not(m_Value())));
+ case Instruction::Xor:
+ // Do not change a 'not' of logical shift because that would create a normal
+ // 'xor'. The 'not' is likely better for analysis, SCEV, and codegen.
+ return !(Shift.isLogicalShift() && match(BO, m_Not(m_Value())));
}
}
-Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
- BinaryOperator &I) {
+Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
+ BinaryOperator &I) {
bool isLeftShift = I.getOpcode() == Instruction::Shl;
const APInt *Op1C;
@@ -682,8 +682,8 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
// See if we can simplify any instructions used by the instruction whose sole
// purpose is to compute bits we don't care about.
- Type *Ty = I.getType();
- unsigned TypeBits = Ty->getScalarSizeInBits();
+ Type *Ty = I.getType();
+ unsigned TypeBits = Ty->getScalarSizeInBits();
assert(!Op1C->uge(TypeBits) &&
"Shift over the type width should have been removed already");
@@ -691,20 +691,20 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
return FoldedShift;
// Fold shift2(trunc(shift1(x,c1)), c2) -> trunc(shift2(shift1(x,c1),c2))
- if (auto *TI = dyn_cast<TruncInst>(Op0)) {
+ if (auto *TI = dyn_cast<TruncInst>(Op0)) {
// If 'shift2' is an ashr, we would have to get the sign bit into a funny
// place. Don't try to do this transformation in this case. Also, we
// require that the input operand is a shift-by-constant so that we have
// confidence that the shifts will get folded together. We could do this
// xform in more cases, but it is unlikely to be profitable.
- const APInt *TrShiftAmt;
- if (I.isLogicalShift() &&
- match(TI->getOperand(0), m_Shift(m_Value(), m_APInt(TrShiftAmt)))) {
- auto *TrOp = cast<Instruction>(TI->getOperand(0));
- Type *SrcTy = TrOp->getType();
-
+ const APInt *TrShiftAmt;
+ if (I.isLogicalShift() &&
+ match(TI->getOperand(0), m_Shift(m_Value(), m_APInt(TrShiftAmt)))) {
+ auto *TrOp = cast<Instruction>(TI->getOperand(0));
+ Type *SrcTy = TrOp->getType();
+
// Okay, we'll do this xform. Make the shift of shift.
- Constant *ShAmt = ConstantExpr::getZExt(Op1, SrcTy);
+ Constant *ShAmt = ConstantExpr::getZExt(Op1, SrcTy);
// (shift2 (shift1 & 0x00FF), c2)
Value *NSh = Builder.CreateBinOp(I.getOpcode(), TrOp, ShAmt, I.getName());
@@ -712,27 +712,27 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
// part of the register be zeros. Emulate this by inserting an AND to
// clear the top bits as needed. This 'and' will usually be zapped by
// other xforms later if dead.
- unsigned SrcSize = SrcTy->getScalarSizeInBits();
- Constant *MaskV =
- ConstantInt::get(SrcTy, APInt::getLowBitsSet(SrcSize, TypeBits));
+ unsigned SrcSize = SrcTy->getScalarSizeInBits();
+ Constant *MaskV =
+ ConstantInt::get(SrcTy, APInt::getLowBitsSet(SrcSize, TypeBits));
// The mask we constructed says what the trunc would do if occurring
// between the shifts. We want to know the effect *after* the second
// shift. We know that it is a logical shift by a constant, so adjust the
// mask as appropriate.
- MaskV = ConstantExpr::get(I.getOpcode(), MaskV, ShAmt);
+ MaskV = ConstantExpr::get(I.getOpcode(), MaskV, ShAmt);
// shift1 & 0x00FF
- Value *And = Builder.CreateAnd(NSh, MaskV, TI->getName());
+ Value *And = Builder.CreateAnd(NSh, MaskV, TI->getName());
// Return the value truncated to the interesting size.
- return new TruncInst(And, Ty);
+ return new TruncInst(And, Ty);
}
}
if (Op0->hasOneUse()) {
if (BinaryOperator *Op0BO = dyn_cast<BinaryOperator>(Op0)) {
// Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C)
- Value *V1;
- const APInt *CC;
+ Value *V1;
+ const APInt *CC;
switch (Op0BO->getOpcode()) {
default: break;
case Instruction::Add:
@@ -751,21 +751,21 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
Op0BO->getOperand(1)->getName());
unsigned Op1Val = Op1C->getLimitedValue(TypeBits);
APInt Bits = APInt::getHighBitsSet(TypeBits, TypeBits - Op1Val);
- Constant *Mask = ConstantInt::get(Ty, Bits);
+ Constant *Mask = ConstantInt::get(Ty, Bits);
return BinaryOperator::CreateAnd(X, Mask);
}
// Turn (Y + ((X >> C) & CC)) << C -> ((X & (CC << C)) + (Y << C))
Value *Op0BOOp1 = Op0BO->getOperand(1);
if (isLeftShift && Op0BOOp1->hasOneUse() &&
- match(Op0BOOp1, m_And(m_OneUse(m_Shr(m_Value(V1), m_Specific(Op1))),
- m_APInt(CC)))) {
- Value *YS = // (Y << C)
- Builder.CreateShl(Op0BO->getOperand(0), Op1, Op0BO->getName());
+ match(Op0BOOp1, m_And(m_OneUse(m_Shr(m_Value(V1), m_Specific(Op1))),
+ m_APInt(CC)))) {
+ Value *YS = // (Y << C)
+ Builder.CreateShl(Op0BO->getOperand(0), Op1, Op0BO->getName());
// X & (CC << C)
- Value *XM = Builder.CreateAnd(
- V1, ConstantExpr::getShl(ConstantInt::get(Ty, *CC), Op1),
- V1->getName() + ".mask");
+ Value *XM = Builder.CreateAnd(
+ V1, ConstantExpr::getShl(ConstantInt::get(Ty, *CC), Op1),
+ V1->getName() + ".mask");
return BinaryOperator::Create(Op0BO->getOpcode(), YS, XM);
}
LLVM_FALLTHROUGH;
@@ -783,21 +783,21 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
Op0BO->getOperand(0)->getName());
unsigned Op1Val = Op1C->getLimitedValue(TypeBits);
APInt Bits = APInt::getHighBitsSet(TypeBits, TypeBits - Op1Val);
- Constant *Mask = ConstantInt::get(Ty, Bits);
+ Constant *Mask = ConstantInt::get(Ty, Bits);
return BinaryOperator::CreateAnd(X, Mask);
}
// Turn (((X >> C)&CC) + Y) << C -> (X + (Y << C)) & (CC << C)
if (isLeftShift && Op0BO->getOperand(0)->hasOneUse() &&
match(Op0BO->getOperand(0),
- m_And(m_OneUse(m_Shr(m_Value(V1), m_Specific(Op1))),
- m_APInt(CC)))) {
+ m_And(m_OneUse(m_Shr(m_Value(V1), m_Specific(Op1))),
+ m_APInt(CC)))) {
Value *YS = // (Y << C)
- Builder.CreateShl(Op0BO->getOperand(1), Op1, Op0BO->getName());
+ Builder.CreateShl(Op0BO->getOperand(1), Op1, Op0BO->getName());
// X & (CC << C)
- Value *XM = Builder.CreateAnd(
- V1, ConstantExpr::getShl(ConstantInt::get(Ty, *CC), Op1),
- V1->getName() + ".mask");
+ Value *XM = Builder.CreateAnd(
+ V1, ConstantExpr::getShl(ConstantInt::get(Ty, *CC), Op1),
+ V1->getName() + ".mask");
return BinaryOperator::Create(Op0BO->getOpcode(), XM, YS);
}
@@ -888,7 +888,7 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
return nullptr;
}
-Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) {
+Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) {
const SimplifyQuery Q = SQ.getWithInstruction(&I);
if (Value *V = SimplifyShlInst(I.getOperand(0), I.getOperand(1),
@@ -929,8 +929,8 @@ Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) {
}
const APInt *ShOp1;
- if (match(Op0, m_Exact(m_Shr(m_Value(X), m_APInt(ShOp1)))) &&
- ShOp1->ult(BitWidth)) {
+ if (match(Op0, m_Exact(m_Shr(m_Value(X), m_APInt(ShOp1)))) &&
+ ShOp1->ult(BitWidth)) {
unsigned ShrAmt = ShOp1->getZExtValue();
if (ShrAmt < ShAmt) {
// If C1 < C2: (X >>?,exact C1) << C2 --> X << (C2 - C1)
@@ -950,33 +950,33 @@ Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) {
}
}
- if (match(Op0, m_OneUse(m_Shr(m_Value(X), m_APInt(ShOp1)))) &&
- ShOp1->ult(BitWidth)) {
- unsigned ShrAmt = ShOp1->getZExtValue();
- if (ShrAmt < ShAmt) {
- // If C1 < C2: (X >>? C1) << C2 --> X << (C2 - C1) & (-1 << C2)
- Constant *ShiftDiff = ConstantInt::get(Ty, ShAmt - ShrAmt);
- auto *NewShl = BinaryOperator::CreateShl(X, ShiftDiff);
- NewShl->setHasNoUnsignedWrap(I.hasNoUnsignedWrap());
- NewShl->setHasNoSignedWrap(I.hasNoSignedWrap());
- Builder.Insert(NewShl);
- APInt Mask(APInt::getHighBitsSet(BitWidth, BitWidth - ShAmt));
- return BinaryOperator::CreateAnd(NewShl, ConstantInt::get(Ty, Mask));
- }
- if (ShrAmt > ShAmt) {
- // If C1 > C2: (X >>? C1) << C2 --> X >>? (C1 - C2) & (-1 << C2)
- Constant *ShiftDiff = ConstantInt::get(Ty, ShrAmt - ShAmt);
- auto *OldShr = cast<BinaryOperator>(Op0);
- auto *NewShr =
- BinaryOperator::Create(OldShr->getOpcode(), X, ShiftDiff);
- NewShr->setIsExact(OldShr->isExact());
- Builder.Insert(NewShr);
- APInt Mask(APInt::getHighBitsSet(BitWidth, BitWidth - ShAmt));
- return BinaryOperator::CreateAnd(NewShr, ConstantInt::get(Ty, Mask));
- }
- }
-
- if (match(Op0, m_Shl(m_Value(X), m_APInt(ShOp1))) && ShOp1->ult(BitWidth)) {
+ if (match(Op0, m_OneUse(m_Shr(m_Value(X), m_APInt(ShOp1)))) &&
+ ShOp1->ult(BitWidth)) {
+ unsigned ShrAmt = ShOp1->getZExtValue();
+ if (ShrAmt < ShAmt) {
+ // If C1 < C2: (X >>? C1) << C2 --> X << (C2 - C1) & (-1 << C2)
+ Constant *ShiftDiff = ConstantInt::get(Ty, ShAmt - ShrAmt);
+ auto *NewShl = BinaryOperator::CreateShl(X, ShiftDiff);
+ NewShl->setHasNoUnsignedWrap(I.hasNoUnsignedWrap());
+ NewShl->setHasNoSignedWrap(I.hasNoSignedWrap());
+ Builder.Insert(NewShl);
+ APInt Mask(APInt::getHighBitsSet(BitWidth, BitWidth - ShAmt));
+ return BinaryOperator::CreateAnd(NewShl, ConstantInt::get(Ty, Mask));
+ }
+ if (ShrAmt > ShAmt) {
+ // If C1 > C2: (X >>? C1) << C2 --> X >>? (C1 - C2) & (-1 << C2)
+ Constant *ShiftDiff = ConstantInt::get(Ty, ShrAmt - ShAmt);
+ auto *OldShr = cast<BinaryOperator>(Op0);
+ auto *NewShr =
+ BinaryOperator::Create(OldShr->getOpcode(), X, ShiftDiff);
+ NewShr->setIsExact(OldShr->isExact());
+ Builder.Insert(NewShr);
+ APInt Mask(APInt::getHighBitsSet(BitWidth, BitWidth - ShAmt));
+ return BinaryOperator::CreateAnd(NewShr, ConstantInt::get(Ty, Mask));
+ }
+ }
+
+ if (match(Op0, m_Shl(m_Value(X), m_APInt(ShOp1))) && ShOp1->ult(BitWidth)) {
unsigned AmtSum = ShAmt + ShOp1->getZExtValue();
// Oversized shifts are simplified to zero in InstSimplify.
if (AmtSum < BitWidth)
@@ -1035,7 +1035,7 @@ Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) {
return nullptr;
}
-Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {
+Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {
if (Value *V = SimplifyLShrInst(I.getOperand(0), I.getOperand(1), I.isExact(),
SQ.getWithInstruction(&I)))
return replaceInstUsesWith(I, V);
@@ -1137,12 +1137,12 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {
}
}
- // lshr i32 (X -nsw Y), 31 --> zext (X < Y)
- Value *Y;
- if (ShAmt == BitWidth - 1 &&
- match(Op0, m_OneUse(m_NSWSub(m_Value(X), m_Value(Y)))))
- return new ZExtInst(Builder.CreateICmpSLT(X, Y), Ty);
-
+ // lshr i32 (X -nsw Y), 31 --> zext (X < Y)
+ Value *Y;
+ if (ShAmt == BitWidth - 1 &&
+ match(Op0, m_OneUse(m_NSWSub(m_Value(X), m_Value(Y)))))
+ return new ZExtInst(Builder.CreateICmpSLT(X, Y), Ty);
+
if (match(Op0, m_LShr(m_Value(X), m_APInt(ShOp1)))) {
unsigned AmtSum = ShAmt + ShOp1->getZExtValue();
// Oversized shifts are simplified to zero in InstSimplify.
@@ -1171,7 +1171,7 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {
}
Instruction *
-InstCombinerImpl::foldVariableSignZeroExtensionOfVariableHighBitExtract(
+InstCombinerImpl::foldVariableSignZeroExtensionOfVariableHighBitExtract(
BinaryOperator &OldAShr) {
assert(OldAShr.getOpcode() == Instruction::AShr &&
"Must be called with arithmetic right-shift instruction only.");
@@ -1239,7 +1239,7 @@ InstCombinerImpl::foldVariableSignZeroExtensionOfVariableHighBitExtract(
return TruncInst::CreateTruncOrBitCast(NewAShr, OldAShr.getType());
}
-Instruction *InstCombinerImpl::visitAShr(BinaryOperator &I) {
+Instruction *InstCombinerImpl::visitAShr(BinaryOperator &I) {
if (Value *V = SimplifyAShrInst(I.getOperand(0), I.getOperand(1), I.isExact(),
SQ.getWithInstruction(&I)))
return replaceInstUsesWith(I, V);
@@ -1305,12 +1305,12 @@ Instruction *InstCombinerImpl::visitAShr(BinaryOperator &I) {
return new SExtInst(NewSh, Ty);
}
- // ashr i32 (X -nsw Y), 31 --> sext (X < Y)
- Value *Y;
- if (ShAmt == BitWidth - 1 &&
- match(Op0, m_OneUse(m_NSWSub(m_Value(X), m_Value(Y)))))
- return new SExtInst(Builder.CreateICmpSLT(X, Y), Ty);
-
+ // ashr i32 (X -nsw Y), 31 --> sext (X < Y)
+ Value *Y;
+ if (ShAmt == BitWidth - 1 &&
+ match(Op0, m_OneUse(m_NSWSub(m_Value(X), m_Value(Y)))))
+ return new SExtInst(Builder.CreateICmpSLT(X, Y), Ty);
+
// If the shifted-out value is known-zero, then this is an exact shift.
if (!I.isExact() &&
MaskedValueIsZero(Op0, APInt::getLowBitsSet(BitWidth, ShAmt), 0, &I)) {
diff --git a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 5380bf728c..16efe86377 100644
--- a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -12,12 +12,12 @@
//===----------------------------------------------------------------------===//
#include "InstCombineInternal.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/Support/KnownBits.h"
-#include "llvm/Transforms/InstCombine/InstCombiner.h"
+#include "llvm/Transforms/InstCombine/InstCombiner.h"
using namespace llvm;
using namespace llvm::PatternMatch;
@@ -52,7 +52,7 @@ static bool ShrinkDemandedConstant(Instruction *I, unsigned OpNo,
/// Inst is an integer instruction that SimplifyDemandedBits knows about. See if
/// the instruction has any properties that allow us to simplify its operands.
-bool InstCombinerImpl::SimplifyDemandedInstructionBits(Instruction &Inst) {
+bool InstCombinerImpl::SimplifyDemandedInstructionBits(Instruction &Inst) {
unsigned BitWidth = Inst.getType()->getScalarSizeInBits();
KnownBits Known(BitWidth);
APInt DemandedMask(APInt::getAllOnesValue(BitWidth));
@@ -68,16 +68,16 @@ bool InstCombinerImpl::SimplifyDemandedInstructionBits(Instruction &Inst) {
/// This form of SimplifyDemandedBits simplifies the specified instruction
/// operand if possible, updating it in place. It returns true if it made any
/// change and false otherwise.
-bool InstCombinerImpl::SimplifyDemandedBits(Instruction *I, unsigned OpNo,
- const APInt &DemandedMask,
- KnownBits &Known, unsigned Depth) {
+bool InstCombinerImpl::SimplifyDemandedBits(Instruction *I, unsigned OpNo,
+ const APInt &DemandedMask,
+ KnownBits &Known, unsigned Depth) {
Use &U = I->getOperandUse(OpNo);
Value *NewVal = SimplifyDemandedUseBits(U.get(), DemandedMask, Known,
Depth, I);
if (!NewVal) return false;
if (Instruction* OpInst = dyn_cast<Instruction>(U))
salvageDebugInfo(*OpInst);
-
+
replaceUse(U, NewVal);
return true;
}
@@ -105,12 +105,12 @@ bool InstCombinerImpl::SimplifyDemandedBits(Instruction *I, unsigned OpNo,
/// operands based on the information about what bits are demanded. This returns
/// some other non-null value if it found out that V is equal to another value
/// in the context where the specified bits are demanded, but not for all users.
-Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
- KnownBits &Known,
- unsigned Depth,
- Instruction *CxtI) {
+Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
+ KnownBits &Known,
+ unsigned Depth,
+ Instruction *CxtI) {
assert(V != nullptr && "Null pointer of Value???");
- assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
+ assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
uint32_t BitWidth = DemandedMask.getBitWidth();
Type *VTy = V->getType();
assert(
@@ -127,12 +127,12 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
if (DemandedMask.isNullValue()) // Not demanding any bits from V.
return UndefValue::get(VTy);
- if (Depth == MaxAnalysisRecursionDepth)
+ if (Depth == MaxAnalysisRecursionDepth)
+ return nullptr;
+
+ if (isa<ScalableVectorType>(VTy))
return nullptr;
- if (isa<ScalableVectorType>(VTy))
- return nullptr;
-
Instruction *I = dyn_cast<Instruction>(V);
if (!I) {
computeKnownBits(V, Known, Depth, CxtI);
@@ -259,44 +259,44 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
return InsertNewInstWith(And, *I);
}
- // If the RHS is a constant, see if we can change it. Don't alter a -1
- // constant because that's a canonical 'not' op, and that is better for
- // combining, SCEV, and codegen.
- const APInt *C;
- if (match(I->getOperand(1), m_APInt(C)) && !C->isAllOnesValue()) {
- if ((*C | ~DemandedMask).isAllOnesValue()) {
- // Force bits to 1 to create a 'not' op.
- I->setOperand(1, ConstantInt::getAllOnesValue(VTy));
- return I;
- }
- // If we can't turn this into a 'not', try to shrink the constant.
- if (ShrinkDemandedConstant(I, 1, DemandedMask))
- return I;
- }
+ // If the RHS is a constant, see if we can change it. Don't alter a -1
+ // constant because that's a canonical 'not' op, and that is better for
+ // combining, SCEV, and codegen.
+ const APInt *C;
+ if (match(I->getOperand(1), m_APInt(C)) && !C->isAllOnesValue()) {
+ if ((*C | ~DemandedMask).isAllOnesValue()) {
+ // Force bits to 1 to create a 'not' op.
+ I->setOperand(1, ConstantInt::getAllOnesValue(VTy));
+ return I;
+ }
+ // If we can't turn this into a 'not', try to shrink the constant.
+ if (ShrinkDemandedConstant(I, 1, DemandedMask))
+ return I;
+ }
// If our LHS is an 'and' and if it has one use, and if any of the bits we
// are flipping are known to be set, then the xor is just resetting those
// bits to zero. We can just knock out bits from the 'and' and the 'xor',
// simplifying both of them.
- if (Instruction *LHSInst = dyn_cast<Instruction>(I->getOperand(0))) {
- ConstantInt *AndRHS, *XorRHS;
+ if (Instruction *LHSInst = dyn_cast<Instruction>(I->getOperand(0))) {
+ ConstantInt *AndRHS, *XorRHS;
if (LHSInst->getOpcode() == Instruction::And && LHSInst->hasOneUse() &&
- match(I->getOperand(1), m_ConstantInt(XorRHS)) &&
- match(LHSInst->getOperand(1), m_ConstantInt(AndRHS)) &&
+ match(I->getOperand(1), m_ConstantInt(XorRHS)) &&
+ match(LHSInst->getOperand(1), m_ConstantInt(AndRHS)) &&
(LHSKnown.One & RHSKnown.One & DemandedMask) != 0) {
APInt NewMask = ~(LHSKnown.One & RHSKnown.One & DemandedMask);
Constant *AndC =
- ConstantInt::get(I->getType(), NewMask & AndRHS->getValue());
+ ConstantInt::get(I->getType(), NewMask & AndRHS->getValue());
Instruction *NewAnd = BinaryOperator::CreateAnd(I->getOperand(0), AndC);
InsertNewInstWith(NewAnd, *I);
Constant *XorC =
- ConstantInt::get(I->getType(), NewMask & XorRHS->getValue());
+ ConstantInt::get(I->getType(), NewMask & XorRHS->getValue());
Instruction *NewXor = BinaryOperator::CreateXor(NewAnd, XorC);
return InsertNewInstWith(NewXor, *I);
}
- }
+ }
break;
}
case Instruction::Select: {
@@ -339,20 +339,20 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
// we can. This helps not break apart (or helps put back together)
// canonical patterns like min and max.
auto CanonicalizeSelectConstant = [](Instruction *I, unsigned OpNo,
- const APInt &DemandedMask) {
+ const APInt &DemandedMask) {
const APInt *SelC;
if (!match(I->getOperand(OpNo), m_APInt(SelC)))
return false;
// Get the constant out of the ICmp, if there is one.
- // Only try this when exactly 1 operand is a constant (if both operands
- // are constant, the icmp should eventually simplify). Otherwise, we may
- // invert the transform that reduces set bits and infinite-loop.
- Value *X;
+ // Only try this when exactly 1 operand is a constant (if both operands
+ // are constant, the icmp should eventually simplify). Otherwise, we may
+ // invert the transform that reduces set bits and infinite-loop.
+ Value *X;
const APInt *CmpC;
ICmpInst::Predicate Pred;
- if (!match(I->getOperand(0), m_ICmp(Pred, m_Value(X), m_APInt(CmpC))) ||
- isa<Constant>(X) || CmpC->getBitWidth() != SelC->getBitWidth())
+ if (!match(I->getOperand(0), m_ICmp(Pred, m_Value(X), m_APInt(CmpC))) ||
+ isa<Constant>(X) || CmpC->getBitWidth() != SelC->getBitWidth())
return ShrinkDemandedConstant(I, OpNo, DemandedMask);
// If the constant is already the same as the ICmp, leave it as-is.
@@ -371,7 +371,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
return I;
// Only known if known in both the LHS and RHS.
- Known = KnownBits::commonBits(LHSKnown, RHSKnown);
+ Known = KnownBits::commonBits(LHSKnown, RHSKnown);
break;
}
case Instruction::ZExt:
@@ -394,8 +394,8 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
if (VectorType *DstVTy = dyn_cast<VectorType>(I->getType())) {
if (VectorType *SrcVTy =
dyn_cast<VectorType>(I->getOperand(0)->getType())) {
- if (cast<FixedVectorType>(DstVTy)->getNumElements() !=
- cast<FixedVectorType>(SrcVTy)->getNumElements())
+ if (cast<FixedVectorType>(DstVTy)->getNumElements() !=
+ cast<FixedVectorType>(SrcVTy)->getNumElements())
// Don't touch a bitcast between vectors of different element counts.
return nullptr;
} else
@@ -673,9 +673,9 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
}
break;
}
- case Instruction::SRem: {
- ConstantInt *Rem;
- if (match(I->getOperand(1), m_ConstantInt(Rem))) {
+ case Instruction::SRem: {
+ ConstantInt *Rem;
+ if (match(I->getOperand(1), m_ConstantInt(Rem))) {
// X % -1 demands all the bits because we don't want to introduce
// INT_MIN % -1 (== undef) by accident.
if (Rem->isMinusOne())
@@ -718,7 +718,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
Known.makeNonNegative();
}
break;
- }
+ }
case Instruction::URem: {
KnownBits Known2(BitWidth);
APInt AllOnes = APInt::getAllOnesValue(BitWidth);
@@ -789,12 +789,12 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
KnownBitsComputed = true;
break;
}
- default: {
- // Handle target specific intrinsics
- Optional<Value *> V = targetSimplifyDemandedUseBitsIntrinsic(
- *II, DemandedMask, Known, KnownBitsComputed);
- if (V.hasValue())
- return V.getValue();
+ default: {
+ // Handle target specific intrinsics
+ Optional<Value *> V = targetSimplifyDemandedUseBitsIntrinsic(
+ *II, DemandedMask, Known, KnownBitsComputed);
+ if (V.hasValue())
+ return V.getValue();
break;
}
}
@@ -816,9 +816,9 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
/// Helper routine of SimplifyDemandedUseBits. It computes Known
/// bits. It also tries to handle simplifications that can be done based on
/// DemandedMask, but without modifying the Instruction.
-Value *InstCombinerImpl::SimplifyMultipleUseDemandedBits(
- Instruction *I, const APInt &DemandedMask, KnownBits &Known, unsigned Depth,
- Instruction *CxtI) {
+Value *InstCombinerImpl::SimplifyMultipleUseDemandedBits(
+ Instruction *I, const APInt &DemandedMask, KnownBits &Known, unsigned Depth,
+ Instruction *CxtI) {
unsigned BitWidth = DemandedMask.getBitWidth();
Type *ITy = I->getType();
@@ -903,33 +903,33 @@ Value *InstCombinerImpl::SimplifyMultipleUseDemandedBits(
break;
}
- case Instruction::AShr: {
- // Compute the Known bits to simplify things downstream.
- computeKnownBits(I, Known, Depth, CxtI);
-
- // If this user is only demanding bits that we know, return the known
- // constant.
- if (DemandedMask.isSubsetOf(Known.Zero | Known.One))
- return Constant::getIntegerValue(ITy, Known.One);
-
- // If the right shift operand 0 is a result of a left shift by the same
- // amount, this is probably a zero/sign extension, which may be unnecessary,
- // if we do not demand any of the new sign bits. So, return the original
- // operand instead.
- const APInt *ShiftRC;
- const APInt *ShiftLC;
- Value *X;
- unsigned BitWidth = DemandedMask.getBitWidth();
- if (match(I,
- m_AShr(m_Shl(m_Value(X), m_APInt(ShiftLC)), m_APInt(ShiftRC))) &&
- ShiftLC == ShiftRC &&
- DemandedMask.isSubsetOf(APInt::getLowBitsSet(
- BitWidth, BitWidth - ShiftRC->getZExtValue()))) {
- return X;
- }
-
- break;
- }
+ case Instruction::AShr: {
+ // Compute the Known bits to simplify things downstream.
+ computeKnownBits(I, Known, Depth, CxtI);
+
+ // If this user is only demanding bits that we know, return the known
+ // constant.
+ if (DemandedMask.isSubsetOf(Known.Zero | Known.One))
+ return Constant::getIntegerValue(ITy, Known.One);
+
+ // If the right shift operand 0 is a result of a left shift by the same
+ // amount, this is probably a zero/sign extension, which may be unnecessary,
+ // if we do not demand any of the new sign bits. So, return the original
+ // operand instead.
+ const APInt *ShiftRC;
+ const APInt *ShiftLC;
+ Value *X;
+ unsigned BitWidth = DemandedMask.getBitWidth();
+ if (match(I,
+ m_AShr(m_Shl(m_Value(X), m_APInt(ShiftLC)), m_APInt(ShiftRC))) &&
+ ShiftLC == ShiftRC &&
+ DemandedMask.isSubsetOf(APInt::getLowBitsSet(
+ BitWidth, BitWidth - ShiftRC->getZExtValue()))) {
+ return X;
+ }
+
+ break;
+ }
default:
// Compute the Known bits to simplify things downstream.
computeKnownBits(I, Known, Depth, CxtI);
@@ -962,9 +962,9 @@ Value *InstCombinerImpl::SimplifyMultipleUseDemandedBits(
///
/// As with SimplifyDemandedUseBits, it returns NULL if the simplification was
/// not successful.
-Value *InstCombinerImpl::simplifyShrShlDemandedBits(
- Instruction *Shr, const APInt &ShrOp1, Instruction *Shl,
- const APInt &ShlOp1, const APInt &DemandedMask, KnownBits &Known) {
+Value *InstCombinerImpl::simplifyShrShlDemandedBits(
+ Instruction *Shr, const APInt &ShrOp1, Instruction *Shl,
+ const APInt &ShlOp1, const APInt &DemandedMask, KnownBits &Known) {
if (!ShlOp1 || !ShrOp1)
return nullptr; // No-op.
@@ -1025,8 +1025,8 @@ Value *InstCombinerImpl::simplifyShrShlDemandedBits(
}
/// The specified value produces a vector with any number of elements.
-/// This method analyzes which elements of the operand are undef or poison and
-/// returns that information in UndefElts.
+/// This method analyzes which elements of the operand are undef or poison and
+/// returns that information in UndefElts.
///
/// DemandedElts contains the set of elements that are actually used by the
/// caller, and by default (AllowMultipleUsers equals false) the value is
@@ -1037,11 +1037,11 @@ Value *InstCombinerImpl::simplifyShrShlDemandedBits(
/// If the information about demanded elements can be used to simplify the
/// operation, the operation is simplified, then the resultant value is
/// returned. This returns null if no change was made.
-Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
- APInt DemandedElts,
- APInt &UndefElts,
- unsigned Depth,
- bool AllowMultipleUsers) {
+Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
+ APInt DemandedElts,
+ APInt &UndefElts,
+ unsigned Depth,
+ bool AllowMultipleUsers) {
// Cannot analyze scalable type. The number of vector elements is not a
// compile-time constant.
if (isa<ScalableVectorType>(V->getType()))
@@ -1052,14 +1052,14 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
assert((DemandedElts & ~EltMask) == 0 && "Invalid DemandedElts!");
if (isa<UndefValue>(V)) {
- // If the entire vector is undef or poison, just return this info.
+ // If the entire vector is undef or poison, just return this info.
UndefElts = EltMask;
return nullptr;
}
- if (DemandedElts.isNullValue()) { // If nothing is demanded, provide poison.
+ if (DemandedElts.isNullValue()) { // If nothing is demanded, provide poison.
UndefElts = EltMask;
- return PoisonValue::get(V->getType());
+ return PoisonValue::get(V->getType());
}
UndefElts = 0;
@@ -1071,11 +1071,11 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
return nullptr;
Type *EltTy = cast<VectorType>(V->getType())->getElementType();
- Constant *Poison = PoisonValue::get(EltTy);
+ Constant *Poison = PoisonValue::get(EltTy);
SmallVector<Constant*, 16> Elts;
for (unsigned i = 0; i != VWidth; ++i) {
- if (!DemandedElts[i]) { // If not demanded, set to poison.
- Elts.push_back(Poison);
+ if (!DemandedElts[i]) { // If not demanded, set to poison.
+ Elts.push_back(Poison);
UndefElts.setBit(i);
continue;
}
@@ -1083,8 +1083,8 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
Constant *Elt = C->getAggregateElement(i);
if (!Elt) return nullptr;
- Elts.push_back(Elt);
- if (isa<UndefValue>(Elt)) // Already undef or poison.
+ Elts.push_back(Elt);
+ if (isa<UndefValue>(Elt)) // Already undef or poison.
UndefElts.setBit(i);
}
@@ -1145,12 +1145,12 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
};
if (mayIndexStructType(cast<GetElementPtrInst>(*I)))
break;
-
+
// Conservatively track the demanded elements back through any vector
// operands we may have. We know there must be at least one, or we
// wouldn't have a vector result to get here. Note that we intentionally
// merge the undef bits here since gepping with either an undef base or
- // index results in undef.
+ // index results in undef.
for (unsigned i = 0; i < I->getNumOperands(); i++) {
if (isa<UndefValue>(I->getOperand(i))) {
// If the entire vector is undefined, just return this info.
@@ -1184,19 +1184,19 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
if (IdxNo < VWidth)
PreInsertDemandedElts.clearBit(IdxNo);
- // If we only demand the element that is being inserted and that element
- // was extracted from the same index in another vector with the same type,
- // replace this insert with that other vector.
- // Note: This is attempted before the call to simplifyAndSetOp because that
- // may change UndefElts to a value that does not match with Vec.
- Value *Vec;
- if (PreInsertDemandedElts == 0 &&
- match(I->getOperand(1),
- m_ExtractElt(m_Value(Vec), m_SpecificInt(IdxNo))) &&
- Vec->getType() == I->getType()) {
- return Vec;
- }
-
+ // If we only demand the element that is being inserted and that element
+ // was extracted from the same index in another vector with the same type,
+ // replace this insert with that other vector.
+ // Note: This is attempted before the call to simplifyAndSetOp because that
+ // may change UndefElts to a value that does not match with Vec.
+ Value *Vec;
+ if (PreInsertDemandedElts == 0 &&
+ match(I->getOperand(1),
+ m_ExtractElt(m_Value(Vec), m_SpecificInt(IdxNo))) &&
+ Vec->getType() == I->getType()) {
+ return Vec;
+ }
+
simplifyAndSetOp(I, 0, PreInsertDemandedElts, UndefElts);
// If this is inserting an element that isn't demanded, remove this
@@ -1215,8 +1215,8 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
assert(Shuffle->getOperand(0)->getType() ==
Shuffle->getOperand(1)->getType() &&
"Expected shuffle operands to have same type");
- unsigned OpWidth = cast<FixedVectorType>(Shuffle->getOperand(0)->getType())
- ->getNumElements();
+ unsigned OpWidth = cast<FixedVectorType>(Shuffle->getOperand(0)->getType())
+ ->getNumElements();
// Handle trivial case of a splat. Only check the first element of LHS
// operand.
if (all_of(Shuffle->getShuffleMask(), [](int Elt) { return Elt == 0; }) &&
@@ -1317,8 +1317,8 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
// this constant vector to single insertelement instruction.
// shufflevector V, C, <v1, v2, .., ci, .., vm> ->
// insertelement V, C[ci], ci-n
- if (OpWidth ==
- cast<FixedVectorType>(Shuffle->getType())->getNumElements()) {
+ if (OpWidth ==
+ cast<FixedVectorType>(Shuffle->getType())->getNumElements()) {
Value *Op = nullptr;
Constant *Value = nullptr;
unsigned Idx = -1u;
@@ -1405,7 +1405,7 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
// Vector->vector casts only.
VectorType *VTy = dyn_cast<VectorType>(I->getOperand(0)->getType());
if (!VTy) break;
- unsigned InVWidth = cast<FixedVectorType>(VTy)->getNumElements();
+ unsigned InVWidth = cast<FixedVectorType>(VTy)->getNumElements();
APInt InputDemandedElts(InVWidth, 0);
UndefElts2 = APInt(InVWidth, 0);
unsigned Ratio;
@@ -1488,19 +1488,19 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
if (II->getIntrinsicID() == Intrinsic::masked_gather)
simplifyAndSetOp(II, 0, DemandedPtrs, UndefElts2);
simplifyAndSetOp(II, 3, DemandedPassThrough, UndefElts3);
-
+
// Output elements are undefined if the element from both sources are.
// TODO: can strengthen via mask as well.
UndefElts = UndefElts2 & UndefElts3;
break;
}
default: {
- // Handle target specific intrinsics
- Optional<Value *> V = targetSimplifyDemandedVectorEltsIntrinsic(
- *II, DemandedElts, UndefElts, UndefElts2, UndefElts3,
- simplifyAndSetOp);
- if (V.hasValue())
- return V.getValue();
+ // Handle target specific intrinsics
+ Optional<Value *> V = targetSimplifyDemandedVectorEltsIntrinsic(
+ *II, DemandedElts, UndefElts, UndefElts2, UndefElts3,
+ simplifyAndSetOp);
+ if (V.hasValue())
+ return V.getValue();
break;
}
} // switch on IntrinsicID
diff --git a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index c1791dc17e..06f22cdfb6 100644
--- a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -18,7 +18,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/BasicBlock.h"
@@ -36,7 +36,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Transforms/InstCombine/InstCombineWorklist.h"
-#include "llvm/Transforms/InstCombine/InstCombiner.h"
+#include "llvm/Transforms/InstCombine/InstCombiner.h"
#include <cassert>
#include <cstdint>
#include <iterator>
@@ -47,10 +47,10 @@ using namespace PatternMatch;
#define DEBUG_TYPE "instcombine"
-STATISTIC(NumAggregateReconstructionsSimplified,
- "Number of aggregate reconstructions turned into reuse of the "
- "original aggregate");
-
+STATISTIC(NumAggregateReconstructionsSimplified,
+ "Number of aggregate reconstructions turned into reuse of the "
+ "original aggregate");
+
/// Return true if the value is cheaper to scalarize than it is to leave as a
/// vector operation. IsConstantExtractIndex indicates whether we are extracting
/// one known element from a vector constant.
@@ -91,8 +91,8 @@ static bool cheapToScalarize(Value *V, bool IsConstantExtractIndex) {
// If we have a PHI node with a vector type that is only used to feed
// itself and be an operand of extractelement at a constant location,
// try to replace the PHI of the vector type with a PHI of a scalar type.
-Instruction *InstCombinerImpl::scalarizePHI(ExtractElementInst &EI,
- PHINode *PN) {
+Instruction *InstCombinerImpl::scalarizePHI(ExtractElementInst &EI,
+ PHINode *PN) {
SmallVector<Instruction *, 2> Extracts;
// The users we want the PHI to have are:
// 1) The EI ExtractElement (we already know this)
@@ -185,19 +185,19 @@ static Instruction *foldBitcastExtElt(ExtractElementInst &Ext,
// extelt (bitcast VecX), IndexC --> bitcast X[IndexC]
auto *SrcTy = cast<VectorType>(X->getType());
Type *DestTy = Ext.getType();
- ElementCount NumSrcElts = SrcTy->getElementCount();
- ElementCount NumElts =
- cast<VectorType>(Ext.getVectorOperandType())->getElementCount();
+ ElementCount NumSrcElts = SrcTy->getElementCount();
+ ElementCount NumElts =
+ cast<VectorType>(Ext.getVectorOperandType())->getElementCount();
if (NumSrcElts == NumElts)
if (Value *Elt = findScalarElement(X, ExtIndexC))
return new BitCastInst(Elt, DestTy);
- assert(NumSrcElts.isScalable() == NumElts.isScalable() &&
- "Src and Dst must be the same sort of vector type");
-
+ assert(NumSrcElts.isScalable() == NumElts.isScalable() &&
+ "Src and Dst must be the same sort of vector type");
+
// If the source elements are wider than the destination, try to shift and
// truncate a subset of scalar bits of an insert op.
- if (NumSrcElts.getKnownMinValue() < NumElts.getKnownMinValue()) {
+ if (NumSrcElts.getKnownMinValue() < NumElts.getKnownMinValue()) {
Value *Scalar;
uint64_t InsIndexC;
if (!match(X, m_InsertElt(m_Value(), m_Value(Scalar),
@@ -208,8 +208,8 @@ static Instruction *foldBitcastExtElt(ExtractElementInst &Ext,
// into. Example: if we inserted element 1 of a <2 x i64> and we are
// extracting an i16 (narrowing ratio = 4), then this extract must be from 1
// of elements 4-7 of the bitcasted vector.
- unsigned NarrowingRatio =
- NumElts.getKnownMinValue() / NumSrcElts.getKnownMinValue();
+ unsigned NarrowingRatio =
+ NumElts.getKnownMinValue() / NumSrcElts.getKnownMinValue();
if (ExtIndexC / NarrowingRatio != InsIndexC)
return nullptr;
@@ -271,7 +271,7 @@ static Instruction *foldBitcastExtElt(ExtractElementInst &Ext,
/// Find elements of V demanded by UserInstr.
static APInt findDemandedEltsBySingleUser(Value *V, Instruction *UserInstr) {
- unsigned VWidth = cast<FixedVectorType>(V->getType())->getNumElements();
+ unsigned VWidth = cast<FixedVectorType>(V->getType())->getNumElements();
// Conservatively assume that all elements are needed.
APInt UsedElts(APInt::getAllOnesValue(VWidth));
@@ -289,7 +289,7 @@ static APInt findDemandedEltsBySingleUser(Value *V, Instruction *UserInstr) {
case Instruction::ShuffleVector: {
ShuffleVectorInst *Shuffle = cast<ShuffleVectorInst>(UserInstr);
unsigned MaskNumElts =
- cast<FixedVectorType>(UserInstr->getType())->getNumElements();
+ cast<FixedVectorType>(UserInstr->getType())->getNumElements();
UsedElts = APInt(VWidth, 0);
for (unsigned i = 0; i < MaskNumElts; i++) {
@@ -315,7 +315,7 @@ static APInt findDemandedEltsBySingleUser(Value *V, Instruction *UserInstr) {
/// no user demands an element of V, then the corresponding bit
/// remains unset in the returned value.
static APInt findDemandedEltsByAllUsers(Value *V) {
- unsigned VWidth = cast<FixedVectorType>(V->getType())->getNumElements();
+ unsigned VWidth = cast<FixedVectorType>(V->getType())->getNumElements();
APInt UnionUsedElts(VWidth, 0);
for (const Use &U : V->uses()) {
@@ -333,7 +333,7 @@ static APInt findDemandedEltsByAllUsers(Value *V) {
return UnionUsedElts;
}
-Instruction *InstCombinerImpl::visitExtractElementInst(ExtractElementInst &EI) {
+Instruction *InstCombinerImpl::visitExtractElementInst(ExtractElementInst &EI) {
Value *SrcVec = EI.getVectorOperand();
Value *Index = EI.getIndexOperand();
if (Value *V = SimplifyExtractElementInst(SrcVec, Index,
@@ -345,17 +345,17 @@ Instruction *InstCombinerImpl::visitExtractElementInst(ExtractElementInst &EI) {
auto *IndexC = dyn_cast<ConstantInt>(Index);
if (IndexC) {
ElementCount EC = EI.getVectorOperandType()->getElementCount();
- unsigned NumElts = EC.getKnownMinValue();
+ unsigned NumElts = EC.getKnownMinValue();
// InstSimplify should handle cases where the index is invalid.
// For fixed-length vector, it's invalid to extract out-of-range element.
- if (!EC.isScalable() && IndexC->getValue().uge(NumElts))
+ if (!EC.isScalable() && IndexC->getValue().uge(NumElts))
return nullptr;
// This instruction only demands the single element from the input vector.
// Skip for scalable type, the number of elements is unknown at
// compile-time.
- if (!EC.isScalable() && NumElts != 1) {
+ if (!EC.isScalable() && NumElts != 1) {
// If the input vector has a single use, simplify it based on this use
// property.
if (SrcVec->hasOneUse()) {
@@ -472,7 +472,7 @@ static bool collectSingleShuffleElements(Value *V, Value *LHS, Value *RHS,
SmallVectorImpl<int> &Mask) {
assert(LHS->getType() == RHS->getType() &&
"Invalid CollectSingleShuffleElements");
- unsigned NumElts = cast<FixedVectorType>(V->getType())->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(V->getType())->getNumElements();
if (isa<UndefValue>(V)) {
Mask.assign(NumElts, -1);
@@ -514,7 +514,7 @@ static bool collectSingleShuffleElements(Value *V, Value *LHS, Value *RHS,
unsigned ExtractedIdx =
cast<ConstantInt>(EI->getOperand(1))->getZExtValue();
unsigned NumLHSElts =
- cast<FixedVectorType>(LHS->getType())->getNumElements();
+ cast<FixedVectorType>(LHS->getType())->getNumElements();
// This must be extracting from either LHS or RHS.
if (EI->getOperand(0) == LHS || EI->getOperand(0) == RHS) {
@@ -543,9 +543,9 @@ static bool collectSingleShuffleElements(Value *V, Value *LHS, Value *RHS,
/// shufflevector to replace one or more insert/extract pairs.
static void replaceExtractElements(InsertElementInst *InsElt,
ExtractElementInst *ExtElt,
- InstCombinerImpl &IC) {
- auto *InsVecType = cast<FixedVectorType>(InsElt->getType());
- auto *ExtVecType = cast<FixedVectorType>(ExtElt->getVectorOperandType());
+ InstCombinerImpl &IC) {
+ auto *InsVecType = cast<FixedVectorType>(InsElt->getType());
+ auto *ExtVecType = cast<FixedVectorType>(ExtElt->getVectorOperandType());
unsigned NumInsElts = InsVecType->getNumElements();
unsigned NumExtElts = ExtVecType->getNumElements();
@@ -626,7 +626,7 @@ using ShuffleOps = std::pair<Value *, Value *>;
static ShuffleOps collectShuffleElements(Value *V, SmallVectorImpl<int> &Mask,
Value *PermittedRHS,
- InstCombinerImpl &IC) {
+ InstCombinerImpl &IC) {
assert(V->getType()->isVectorTy() && "Invalid shuffle!");
unsigned NumElts = cast<FixedVectorType>(V->getType())->getNumElements();
@@ -673,7 +673,7 @@ static ShuffleOps collectShuffleElements(Value *V, SmallVectorImpl<int> &Mask,
}
unsigned NumLHSElts =
- cast<FixedVectorType>(RHS->getType())->getNumElements();
+ cast<FixedVectorType>(RHS->getType())->getNumElements();
Mask[InsertedIdx % NumElts] = NumLHSElts + ExtractedIdx;
return std::make_pair(LR.first, RHS);
}
@@ -682,8 +682,8 @@ static ShuffleOps collectShuffleElements(Value *V, SmallVectorImpl<int> &Mask,
// We've gone as far as we can: anything on the other side of the
// extractelement will already have been converted into a shuffle.
unsigned NumLHSElts =
- cast<FixedVectorType>(EI->getOperand(0)->getType())
- ->getNumElements();
+ cast<FixedVectorType>(EI->getOperand(0)->getType())
+ ->getNumElements();
for (unsigned i = 0; i != NumElts; ++i)
Mask.push_back(i == InsertedIdx ? ExtractedIdx : NumLHSElts + i);
return std::make_pair(EI->getOperand(0), PermittedRHS);
@@ -705,285 +705,285 @@ static ShuffleOps collectShuffleElements(Value *V, SmallVectorImpl<int> &Mask,
return std::make_pair(V, nullptr);
}
-/// Look for chain of insertvalue's that fully define an aggregate, and trace
-/// back the values inserted, see if they are all were extractvalue'd from
-/// the same source aggregate from the exact same element indexes.
-/// If they were, just reuse the source aggregate.
-/// This potentially deals with PHI indirections.
-Instruction *InstCombinerImpl::foldAggregateConstructionIntoAggregateReuse(
- InsertValueInst &OrigIVI) {
- Type *AggTy = OrigIVI.getType();
- unsigned NumAggElts;
- switch (AggTy->getTypeID()) {
- case Type::StructTyID:
- NumAggElts = AggTy->getStructNumElements();
- break;
- case Type::ArrayTyID:
- NumAggElts = AggTy->getArrayNumElements();
- break;
- default:
- llvm_unreachable("Unhandled aggregate type?");
- }
-
- // Arbitrary aggregate size cut-off. Motivation for limit of 2 is to be able
- // to handle clang C++ exception struct (which is hardcoded as {i8*, i32}),
- // FIXME: any interesting patterns to be caught with larger limit?
- assert(NumAggElts > 0 && "Aggregate should have elements.");
- if (NumAggElts > 2)
- return nullptr;
-
- static constexpr auto NotFound = None;
- static constexpr auto FoundMismatch = nullptr;
-
- // Try to find a value of each element of an aggregate.
- // FIXME: deal with more complex, not one-dimensional, aggregate types
- SmallVector<Optional<Value *>, 2> AggElts(NumAggElts, NotFound);
-
- // Do we know values for each element of the aggregate?
- auto KnowAllElts = [&AggElts]() {
- return all_of(AggElts,
- [](Optional<Value *> Elt) { return Elt != NotFound; });
- };
-
- int Depth = 0;
-
- // Arbitrary `insertvalue` visitation depth limit. Let's be okay with
- // every element being overwritten twice, which should never happen.
- static const int DepthLimit = 2 * NumAggElts;
-
- // Recurse up the chain of `insertvalue` aggregate operands until either we've
- // reconstructed full initializer or can't visit any more `insertvalue`'s.
- for (InsertValueInst *CurrIVI = &OrigIVI;
- Depth < DepthLimit && CurrIVI && !KnowAllElts();
- CurrIVI = dyn_cast<InsertValueInst>(CurrIVI->getAggregateOperand()),
- ++Depth) {
- Value *InsertedValue = CurrIVI->getInsertedValueOperand();
- ArrayRef<unsigned int> Indices = CurrIVI->getIndices();
-
- // Don't bother with more than single-level aggregates.
- if (Indices.size() != 1)
- return nullptr; // FIXME: deal with more complex aggregates?
-
- // Now, we may have already previously recorded the value for this element
- // of an aggregate. If we did, that means the CurrIVI will later be
- // overwritten with the already-recorded value. But if not, let's record it!
- Optional<Value *> &Elt = AggElts[Indices.front()];
- Elt = Elt.getValueOr(InsertedValue);
-
- // FIXME: should we handle chain-terminating undef base operand?
- }
-
- // Was that sufficient to deduce the full initializer for the aggregate?
- if (!KnowAllElts())
- return nullptr; // Give up then.
-
- // We now want to find the source[s] of the aggregate elements we've found.
- // And with "source" we mean the original aggregate[s] from which
- // the inserted elements were extracted. This may require PHI translation.
-
- enum class AggregateDescription {
- /// When analyzing the value that was inserted into an aggregate, we did
- /// not manage to find defining `extractvalue` instruction to analyze.
- NotFound,
- /// When analyzing the value that was inserted into an aggregate, we did
- /// manage to find defining `extractvalue` instruction[s], and everything
- /// matched perfectly - aggregate type, element insertion/extraction index.
- Found,
- /// When analyzing the value that was inserted into an aggregate, we did
- /// manage to find defining `extractvalue` instruction, but there was
- /// a mismatch: either the source type from which the extraction was didn't
- /// match the aggregate type into which the insertion was,
- /// or the extraction/insertion channels mismatched,
- /// or different elements had different source aggregates.
- FoundMismatch
- };
- auto Describe = [](Optional<Value *> SourceAggregate) {
- if (SourceAggregate == NotFound)
- return AggregateDescription::NotFound;
- if (*SourceAggregate == FoundMismatch)
- return AggregateDescription::FoundMismatch;
- return AggregateDescription::Found;
- };
-
- // Given the value \p Elt that was being inserted into element \p EltIdx of an
- // aggregate AggTy, see if \p Elt was originally defined by an
- // appropriate extractvalue (same element index, same aggregate type).
- // If found, return the source aggregate from which the extraction was.
- // If \p PredBB is provided, does PHI translation of an \p Elt first.
- auto FindSourceAggregate =
- [&](Value *Elt, unsigned EltIdx, Optional<BasicBlock *> UseBB,
- Optional<BasicBlock *> PredBB) -> Optional<Value *> {
- // For now(?), only deal with, at most, a single level of PHI indirection.
- if (UseBB && PredBB)
- Elt = Elt->DoPHITranslation(*UseBB, *PredBB);
- // FIXME: deal with multiple levels of PHI indirection?
-
- // Did we find an extraction?
- auto *EVI = dyn_cast<ExtractValueInst>(Elt);
- if (!EVI)
- return NotFound;
-
- Value *SourceAggregate = EVI->getAggregateOperand();
-
- // Is the extraction from the same type into which the insertion was?
- if (SourceAggregate->getType() != AggTy)
- return FoundMismatch;
- // And the element index doesn't change between extraction and insertion?
- if (EVI->getNumIndices() != 1 || EltIdx != EVI->getIndices().front())
- return FoundMismatch;
-
- return SourceAggregate; // AggregateDescription::Found
- };
-
- // Given elements AggElts that were constructing an aggregate OrigIVI,
- // see if we can find appropriate source aggregate for each of the elements,
- // and see it's the same aggregate for each element. If so, return it.
- auto FindCommonSourceAggregate =
- [&](Optional<BasicBlock *> UseBB,
- Optional<BasicBlock *> PredBB) -> Optional<Value *> {
- Optional<Value *> SourceAggregate;
-
- for (auto I : enumerate(AggElts)) {
- assert(Describe(SourceAggregate) != AggregateDescription::FoundMismatch &&
- "We don't store nullptr in SourceAggregate!");
- assert((Describe(SourceAggregate) == AggregateDescription::Found) ==
- (I.index() != 0) &&
- "SourceAggregate should be valid after the the first element,");
-
- // For this element, is there a plausible source aggregate?
- // FIXME: we could special-case undef element, IFF we know that in the
- // source aggregate said element isn't poison.
- Optional<Value *> SourceAggregateForElement =
- FindSourceAggregate(*I.value(), I.index(), UseBB, PredBB);
-
- // Okay, what have we found? Does that correlate with previous findings?
-
- // Regardless of whether or not we have previously found source
- // aggregate for previous elements (if any), if we didn't find one for
- // this element, passthrough whatever we have just found.
- if (Describe(SourceAggregateForElement) != AggregateDescription::Found)
- return SourceAggregateForElement;
-
- // Okay, we have found source aggregate for this element.
- // Let's see what we already know from previous elements, if any.
- switch (Describe(SourceAggregate)) {
- case AggregateDescription::NotFound:
- // This is apparently the first element that we have examined.
- SourceAggregate = SourceAggregateForElement; // Record the aggregate!
- continue; // Great, now look at next element.
- case AggregateDescription::Found:
- // We have previously already successfully examined other elements.
- // Is this the same source aggregate we've found for other elements?
- if (*SourceAggregateForElement != *SourceAggregate)
- return FoundMismatch;
- continue; // Still the same aggregate, look at next element.
- case AggregateDescription::FoundMismatch:
- llvm_unreachable("Can't happen. We would have early-exited then.");
- };
- }
-
- assert(Describe(SourceAggregate) == AggregateDescription::Found &&
- "Must be a valid Value");
- return *SourceAggregate;
- };
-
- Optional<Value *> SourceAggregate;
-
- // Can we find the source aggregate without looking at predecessors?
- SourceAggregate = FindCommonSourceAggregate(/*UseBB=*/None, /*PredBB=*/None);
- if (Describe(SourceAggregate) != AggregateDescription::NotFound) {
- if (Describe(SourceAggregate) == AggregateDescription::FoundMismatch)
- return nullptr; // Conflicting source aggregates!
- ++NumAggregateReconstructionsSimplified;
- return replaceInstUsesWith(OrigIVI, *SourceAggregate);
- }
-
- // Okay, apparently we need to look at predecessors.
-
- // We should be smart about picking the "use" basic block, which will be the
- // merge point for aggregate, where we'll insert the final PHI that will be
- // used instead of OrigIVI. Basic block of OrigIVI is *not* the right choice.
- // We should look in which blocks each of the AggElts is being defined,
- // they all should be defined in the same basic block.
- BasicBlock *UseBB = nullptr;
-
- for (const Optional<Value *> &Elt : AggElts) {
- // If this element's value was not defined by an instruction, ignore it.
- auto *I = dyn_cast<Instruction>(*Elt);
- if (!I)
- continue;
- // Otherwise, in which basic block is this instruction located?
- BasicBlock *BB = I->getParent();
- // If it's the first instruction we've encountered, record the basic block.
- if (!UseBB) {
- UseBB = BB;
- continue;
- }
- // Otherwise, this must be the same basic block we've seen previously.
- if (UseBB != BB)
- return nullptr;
- }
-
- // If *all* of the elements are basic-block-independent, meaning they are
- // either function arguments, or constant expressions, then if we didn't
- // handle them without predecessor-aware handling, we won't handle them now.
- if (!UseBB)
- return nullptr;
-
- // If we didn't manage to find source aggregate without looking at
- // predecessors, and there are no predecessors to look at, then we're done.
- if (pred_empty(UseBB))
- return nullptr;
-
- // Arbitrary predecessor count limit.
- static const int PredCountLimit = 64;
-
- // Cache the (non-uniqified!) list of predecessors in a vector,
- // checking the limit at the same time for efficiency.
- SmallVector<BasicBlock *, 4> Preds; // May have duplicates!
- for (BasicBlock *Pred : predecessors(UseBB)) {
- // Don't bother if there are too many predecessors.
- if (Preds.size() >= PredCountLimit) // FIXME: only count duplicates once?
- return nullptr;
- Preds.emplace_back(Pred);
- }
-
- // For each predecessor, what is the source aggregate,
- // from which all the elements were originally extracted from?
- // Note that we want for the map to have stable iteration order!
- SmallDenseMap<BasicBlock *, Value *, 4> SourceAggregates;
- for (BasicBlock *Pred : Preds) {
- std::pair<decltype(SourceAggregates)::iterator, bool> IV =
- SourceAggregates.insert({Pred, nullptr});
- // Did we already evaluate this predecessor?
- if (!IV.second)
- continue;
-
- // Let's hope that when coming from predecessor Pred, all elements of the
- // aggregate produced by OrigIVI must have been originally extracted from
- // the same aggregate. Is that so? Can we find said original aggregate?
- SourceAggregate = FindCommonSourceAggregate(UseBB, Pred);
- if (Describe(SourceAggregate) != AggregateDescription::Found)
- return nullptr; // Give up.
- IV.first->second = *SourceAggregate;
- }
-
- // All good! Now we just need to thread the source aggregates here.
- // Note that we have to insert the new PHI here, ourselves, because we can't
- // rely on InstCombinerImpl::run() inserting it into the right basic block.
- // Note that the same block can be a predecessor more than once,
- // and we need to preserve that invariant for the PHI node.
- BuilderTy::InsertPointGuard Guard(Builder);
- Builder.SetInsertPoint(UseBB->getFirstNonPHI());
- auto *PHI =
- Builder.CreatePHI(AggTy, Preds.size(), OrigIVI.getName() + ".merged");
- for (BasicBlock *Pred : Preds)
- PHI->addIncoming(SourceAggregates[Pred], Pred);
-
- ++NumAggregateReconstructionsSimplified;
- return replaceInstUsesWith(OrigIVI, PHI);
-}
-
+/// Look for chain of insertvalue's that fully define an aggregate, and trace
+/// back the values inserted, see if they are all were extractvalue'd from
+/// the same source aggregate from the exact same element indexes.
+/// If they were, just reuse the source aggregate.
+/// This potentially deals with PHI indirections.
+Instruction *InstCombinerImpl::foldAggregateConstructionIntoAggregateReuse(
+ InsertValueInst &OrigIVI) {
+ Type *AggTy = OrigIVI.getType();
+ unsigned NumAggElts;
+ switch (AggTy->getTypeID()) {
+ case Type::StructTyID:
+ NumAggElts = AggTy->getStructNumElements();
+ break;
+ case Type::ArrayTyID:
+ NumAggElts = AggTy->getArrayNumElements();
+ break;
+ default:
+ llvm_unreachable("Unhandled aggregate type?");
+ }
+
+ // Arbitrary aggregate size cut-off. Motivation for limit of 2 is to be able
+ // to handle clang C++ exception struct (which is hardcoded as {i8*, i32}),
+ // FIXME: any interesting patterns to be caught with larger limit?
+ assert(NumAggElts > 0 && "Aggregate should have elements.");
+ if (NumAggElts > 2)
+ return nullptr;
+
+ static constexpr auto NotFound = None;
+ static constexpr auto FoundMismatch = nullptr;
+
+ // Try to find a value of each element of an aggregate.
+ // FIXME: deal with more complex, not one-dimensional, aggregate types
+ SmallVector<Optional<Value *>, 2> AggElts(NumAggElts, NotFound);
+
+ // Do we know values for each element of the aggregate?
+ auto KnowAllElts = [&AggElts]() {
+ return all_of(AggElts,
+ [](Optional<Value *> Elt) { return Elt != NotFound; });
+ };
+
+ int Depth = 0;
+
+ // Arbitrary `insertvalue` visitation depth limit. Let's be okay with
+ // every element being overwritten twice, which should never happen.
+ static const int DepthLimit = 2 * NumAggElts;
+
+ // Recurse up the chain of `insertvalue` aggregate operands until either we've
+ // reconstructed full initializer or can't visit any more `insertvalue`'s.
+ for (InsertValueInst *CurrIVI = &OrigIVI;
+ Depth < DepthLimit && CurrIVI && !KnowAllElts();
+ CurrIVI = dyn_cast<InsertValueInst>(CurrIVI->getAggregateOperand()),
+ ++Depth) {
+ Value *InsertedValue = CurrIVI->getInsertedValueOperand();
+ ArrayRef<unsigned int> Indices = CurrIVI->getIndices();
+
+ // Don't bother with more than single-level aggregates.
+ if (Indices.size() != 1)
+ return nullptr; // FIXME: deal with more complex aggregates?
+
+ // Now, we may have already previously recorded the value for this element
+ // of an aggregate. If we did, that means the CurrIVI will later be
+ // overwritten with the already-recorded value. But if not, let's record it!
+ Optional<Value *> &Elt = AggElts[Indices.front()];
+ Elt = Elt.getValueOr(InsertedValue);
+
+ // FIXME: should we handle chain-terminating undef base operand?
+ }
+
+ // Was that sufficient to deduce the full initializer for the aggregate?
+ if (!KnowAllElts())
+ return nullptr; // Give up then.
+
+ // We now want to find the source[s] of the aggregate elements we've found.
+ // And with "source" we mean the original aggregate[s] from which
+ // the inserted elements were extracted. This may require PHI translation.
+
+ enum class AggregateDescription {
+ /// When analyzing the value that was inserted into an aggregate, we did
+ /// not manage to find defining `extractvalue` instruction to analyze.
+ NotFound,
+ /// When analyzing the value that was inserted into an aggregate, we did
+ /// manage to find defining `extractvalue` instruction[s], and everything
+ /// matched perfectly - aggregate type, element insertion/extraction index.
+ Found,
+ /// When analyzing the value that was inserted into an aggregate, we did
+ /// manage to find defining `extractvalue` instruction, but there was
+ /// a mismatch: either the source type from which the extraction was didn't
+ /// match the aggregate type into which the insertion was,
+ /// or the extraction/insertion channels mismatched,
+ /// or different elements had different source aggregates.
+ FoundMismatch
+ };
+ auto Describe = [](Optional<Value *> SourceAggregate) {
+ if (SourceAggregate == NotFound)
+ return AggregateDescription::NotFound;
+ if (*SourceAggregate == FoundMismatch)
+ return AggregateDescription::FoundMismatch;
+ return AggregateDescription::Found;
+ };
+
+ // Given the value \p Elt that was being inserted into element \p EltIdx of an
+ // aggregate AggTy, see if \p Elt was originally defined by an
+ // appropriate extractvalue (same element index, same aggregate type).
+ // If found, return the source aggregate from which the extraction was.
+ // If \p PredBB is provided, does PHI translation of an \p Elt first.
+ auto FindSourceAggregate =
+ [&](Value *Elt, unsigned EltIdx, Optional<BasicBlock *> UseBB,
+ Optional<BasicBlock *> PredBB) -> Optional<Value *> {
+ // For now(?), only deal with, at most, a single level of PHI indirection.
+ if (UseBB && PredBB)
+ Elt = Elt->DoPHITranslation(*UseBB, *PredBB);
+ // FIXME: deal with multiple levels of PHI indirection?
+
+ // Did we find an extraction?
+ auto *EVI = dyn_cast<ExtractValueInst>(Elt);
+ if (!EVI)
+ return NotFound;
+
+ Value *SourceAggregate = EVI->getAggregateOperand();
+
+ // Is the extraction from the same type into which the insertion was?
+ if (SourceAggregate->getType() != AggTy)
+ return FoundMismatch;
+ // And the element index doesn't change between extraction and insertion?
+ if (EVI->getNumIndices() != 1 || EltIdx != EVI->getIndices().front())
+ return FoundMismatch;
+
+ return SourceAggregate; // AggregateDescription::Found
+ };
+
+ // Given elements AggElts that were constructing an aggregate OrigIVI,
+ // see if we can find appropriate source aggregate for each of the elements,
+ // and see it's the same aggregate for each element. If so, return it.
+ auto FindCommonSourceAggregate =
+ [&](Optional<BasicBlock *> UseBB,
+ Optional<BasicBlock *> PredBB) -> Optional<Value *> {
+ Optional<Value *> SourceAggregate;
+
+ for (auto I : enumerate(AggElts)) {
+ assert(Describe(SourceAggregate) != AggregateDescription::FoundMismatch &&
+ "We don't store nullptr in SourceAggregate!");
+ assert((Describe(SourceAggregate) == AggregateDescription::Found) ==
+ (I.index() != 0) &&
+ "SourceAggregate should be valid after the the first element,");
+
+ // For this element, is there a plausible source aggregate?
+ // FIXME: we could special-case undef element, IFF we know that in the
+ // source aggregate said element isn't poison.
+ Optional<Value *> SourceAggregateForElement =
+ FindSourceAggregate(*I.value(), I.index(), UseBB, PredBB);
+
+ // Okay, what have we found? Does that correlate with previous findings?
+
+ // Regardless of whether or not we have previously found source
+ // aggregate for previous elements (if any), if we didn't find one for
+ // this element, passthrough whatever we have just found.
+ if (Describe(SourceAggregateForElement) != AggregateDescription::Found)
+ return SourceAggregateForElement;
+
+ // Okay, we have found source aggregate for this element.
+ // Let's see what we already know from previous elements, if any.
+ switch (Describe(SourceAggregate)) {
+ case AggregateDescription::NotFound:
+ // This is apparently the first element that we have examined.
+ SourceAggregate = SourceAggregateForElement; // Record the aggregate!
+ continue; // Great, now look at next element.
+ case AggregateDescription::Found:
+ // We have previously already successfully examined other elements.
+ // Is this the same source aggregate we've found for other elements?
+ if (*SourceAggregateForElement != *SourceAggregate)
+ return FoundMismatch;
+ continue; // Still the same aggregate, look at next element.
+ case AggregateDescription::FoundMismatch:
+ llvm_unreachable("Can't happen. We would have early-exited then.");
+ };
+ }
+
+ assert(Describe(SourceAggregate) == AggregateDescription::Found &&
+ "Must be a valid Value");
+ return *SourceAggregate;
+ };
+
+ Optional<Value *> SourceAggregate;
+
+ // Can we find the source aggregate without looking at predecessors?
+ SourceAggregate = FindCommonSourceAggregate(/*UseBB=*/None, /*PredBB=*/None);
+ if (Describe(SourceAggregate) != AggregateDescription::NotFound) {
+ if (Describe(SourceAggregate) == AggregateDescription::FoundMismatch)
+ return nullptr; // Conflicting source aggregates!
+ ++NumAggregateReconstructionsSimplified;
+ return replaceInstUsesWith(OrigIVI, *SourceAggregate);
+ }
+
+ // Okay, apparently we need to look at predecessors.
+
+ // We should be smart about picking the "use" basic block, which will be the
+ // merge point for aggregate, where we'll insert the final PHI that will be
+ // used instead of OrigIVI. Basic block of OrigIVI is *not* the right choice.
+ // We should look in which blocks each of the AggElts is being defined,
+ // they all should be defined in the same basic block.
+ BasicBlock *UseBB = nullptr;
+
+ for (const Optional<Value *> &Elt : AggElts) {
+ // If this element's value was not defined by an instruction, ignore it.
+ auto *I = dyn_cast<Instruction>(*Elt);
+ if (!I)
+ continue;
+ // Otherwise, in which basic block is this instruction located?
+ BasicBlock *BB = I->getParent();
+ // If it's the first instruction we've encountered, record the basic block.
+ if (!UseBB) {
+ UseBB = BB;
+ continue;
+ }
+ // Otherwise, this must be the same basic block we've seen previously.
+ if (UseBB != BB)
+ return nullptr;
+ }
+
+ // If *all* of the elements are basic-block-independent, meaning they are
+ // either function arguments, or constant expressions, then if we didn't
+ // handle them without predecessor-aware handling, we won't handle them now.
+ if (!UseBB)
+ return nullptr;
+
+ // If we didn't manage to find source aggregate without looking at
+ // predecessors, and there are no predecessors to look at, then we're done.
+ if (pred_empty(UseBB))
+ return nullptr;
+
+ // Arbitrary predecessor count limit.
+ static const int PredCountLimit = 64;
+
+ // Cache the (non-uniqified!) list of predecessors in a vector,
+ // checking the limit at the same time for efficiency.
+ SmallVector<BasicBlock *, 4> Preds; // May have duplicates!
+ for (BasicBlock *Pred : predecessors(UseBB)) {
+ // Don't bother if there are too many predecessors.
+ if (Preds.size() >= PredCountLimit) // FIXME: only count duplicates once?
+ return nullptr;
+ Preds.emplace_back(Pred);
+ }
+
+ // For each predecessor, what is the source aggregate,
+ // from which all the elements were originally extracted from?
+ // Note that we want for the map to have stable iteration order!
+ SmallDenseMap<BasicBlock *, Value *, 4> SourceAggregates;
+ for (BasicBlock *Pred : Preds) {
+ std::pair<decltype(SourceAggregates)::iterator, bool> IV =
+ SourceAggregates.insert({Pred, nullptr});
+ // Did we already evaluate this predecessor?
+ if (!IV.second)
+ continue;
+
+ // Let's hope that when coming from predecessor Pred, all elements of the
+ // aggregate produced by OrigIVI must have been originally extracted from
+ // the same aggregate. Is that so? Can we find said original aggregate?
+ SourceAggregate = FindCommonSourceAggregate(UseBB, Pred);
+ if (Describe(SourceAggregate) != AggregateDescription::Found)
+ return nullptr; // Give up.
+ IV.first->second = *SourceAggregate;
+ }
+
+ // All good! Now we just need to thread the source aggregates here.
+ // Note that we have to insert the new PHI here, ourselves, because we can't
+ // rely on InstCombinerImpl::run() inserting it into the right basic block.
+ // Note that the same block can be a predecessor more than once,
+ // and we need to preserve that invariant for the PHI node.
+ BuilderTy::InsertPointGuard Guard(Builder);
+ Builder.SetInsertPoint(UseBB->getFirstNonPHI());
+ auto *PHI =
+ Builder.CreatePHI(AggTy, Preds.size(), OrigIVI.getName() + ".merged");
+ for (BasicBlock *Pred : Preds)
+ PHI->addIncoming(SourceAggregates[Pred], Pred);
+
+ ++NumAggregateReconstructionsSimplified;
+ return replaceInstUsesWith(OrigIVI, PHI);
+}
+
/// Try to find redundant insertvalue instructions, like the following ones:
/// %0 = insertvalue { i8, i32 } undef, i8 %x, 0
/// %1 = insertvalue { i8, i32 } %0, i8 %y, 0
@@ -991,7 +991,7 @@ Instruction *InstCombinerImpl::foldAggregateConstructionIntoAggregateReuse(
/// first one, making the first one redundant.
/// It should be transformed to:
/// %0 = insertvalue { i8, i32 } undef, i8 %y, 0
-Instruction *InstCombinerImpl::visitInsertValueInst(InsertValueInst &I) {
+Instruction *InstCombinerImpl::visitInsertValueInst(InsertValueInst &I) {
bool IsRedundant = false;
ArrayRef<unsigned int> FirstIndices = I.getIndices();
@@ -1016,10 +1016,10 @@ Instruction *InstCombinerImpl::visitInsertValueInst(InsertValueInst &I) {
if (IsRedundant)
return replaceInstUsesWith(I, I.getOperand(0));
-
- if (Instruction *NewI = foldAggregateConstructionIntoAggregateReuse(I))
- return NewI;
-
+
+ if (Instruction *NewI = foldAggregateConstructionIntoAggregateReuse(I))
+ return NewI;
+
return nullptr;
}
@@ -1150,8 +1150,8 @@ static Instruction *foldInsEltIntoSplat(InsertElementInst &InsElt) {
// For example:
// inselt (shuf (inselt undef, X, 0), undef, <0,undef,0,undef>), X, 1
// --> shuf (inselt undef, X, 0), undef, <0,0,0,undef>
- unsigned NumMaskElts =
- cast<FixedVectorType>(Shuf->getType())->getNumElements();
+ unsigned NumMaskElts =
+ cast<FixedVectorType>(Shuf->getType())->getNumElements();
SmallVector<int, 16> NewMask(NumMaskElts);
for (unsigned i = 0; i != NumMaskElts; ++i)
NewMask[i] = i == IdxC ? 0 : Shuf->getMaskValue(i);
@@ -1189,8 +1189,8 @@ static Instruction *foldInsEltIntoIdentityShuffle(InsertElementInst &InsElt) {
// that same index value.
// For example:
// inselt (shuf X, IdMask), (extelt X, IdxC), IdxC --> shuf X, IdMask'
- unsigned NumMaskElts =
- cast<FixedVectorType>(Shuf->getType())->getNumElements();
+ unsigned NumMaskElts =
+ cast<FixedVectorType>(Shuf->getType())->getNumElements();
SmallVector<int, 16> NewMask(NumMaskElts);
ArrayRef<int> OldMask = Shuf->getShuffleMask();
for (unsigned i = 0; i != NumMaskElts; ++i) {
@@ -1339,7 +1339,7 @@ static Instruction *foldConstantInsEltIntoShuffle(InsertElementInst &InsElt) {
return nullptr;
}
-Instruction *InstCombinerImpl::visitInsertElementInst(InsertElementInst &IE) {
+Instruction *InstCombinerImpl::visitInsertElementInst(InsertElementInst &IE) {
Value *VecOp = IE.getOperand(0);
Value *ScalarOp = IE.getOperand(1);
Value *IdxOp = IE.getOperand(2);
@@ -1487,7 +1487,7 @@ static bool canEvaluateShuffled(Value *V, ArrayRef<int> Mask,
// Propagating an undefined shuffle mask element to integer div/rem is not
// allowed because those opcodes can create immediate undefined behavior
// from an undefined element in an operand.
- if (llvm::is_contained(Mask, -1))
+ if (llvm::is_contained(Mask, -1))
return false;
LLVM_FALLTHROUGH;
case Instruction::Add:
@@ -1520,7 +1520,7 @@ static bool canEvaluateShuffled(Value *V, ArrayRef<int> Mask,
// longer vector ops, but that may result in more expensive codegen.
Type *ITy = I->getType();
if (ITy->isVectorTy() &&
- Mask.size() > cast<FixedVectorType>(ITy)->getNumElements())
+ Mask.size() > cast<FixedVectorType>(ITy)->getNumElements())
return false;
for (Value *Operand : I->operands()) {
if (!canEvaluateShuffled(Operand, Mask, Depth - 1))
@@ -1678,8 +1678,8 @@ static Value *evaluateInDifferentElementOrder(Value *V, ArrayRef<int> Mask) {
case Instruction::GetElementPtr: {
SmallVector<Value*, 8> NewOps;
bool NeedsRebuild =
- (Mask.size() !=
- cast<FixedVectorType>(I->getType())->getNumElements());
+ (Mask.size() !=
+ cast<FixedVectorType>(I->getType())->getNumElements());
for (int i = 0, e = I->getNumOperands(); i != e; ++i) {
Value *V;
// Recursively call evaluateInDifferentElementOrder on vector arguments
@@ -1734,7 +1734,7 @@ static Value *evaluateInDifferentElementOrder(Value *V, ArrayRef<int> Mask) {
static bool isShuffleExtractingFromLHS(ShuffleVectorInst &SVI,
ArrayRef<int> Mask) {
unsigned LHSElems =
- cast<FixedVectorType>(SVI.getOperand(0)->getType())->getNumElements();
+ cast<FixedVectorType>(SVI.getOperand(0)->getType())->getNumElements();
unsigned MaskElems = Mask.size();
unsigned BegIdx = Mask.front();
unsigned EndIdx = Mask.back();
@@ -1824,7 +1824,7 @@ static Instruction *foldSelectShuffleWith1Binop(ShuffleVectorInst &Shuf) {
is_contained(Mask, UndefMaskElem) &&
(Instruction::isIntDivRem(BOpcode) || Instruction::isShift(BOpcode));
if (MightCreatePoisonOrUB)
- NewC = InstCombiner::getSafeVectorConstantForBinop(BOpcode, NewC, true);
+ NewC = InstCombiner::getSafeVectorConstantForBinop(BOpcode, NewC, true);
// shuf (bop X, C), X, M --> bop X, C'
// shuf X, (bop X, C), M --> bop X, C'
@@ -1866,8 +1866,8 @@ static Instruction *canonicalizeInsertSplat(ShuffleVectorInst &Shuf,
// For example:
// shuf (inselt undef, X, 2), undef, <2,2,undef>
// --> shuf (inselt undef, X, 0), undef, <0,0,undef>
- unsigned NumMaskElts =
- cast<FixedVectorType>(Shuf.getType())->getNumElements();
+ unsigned NumMaskElts =
+ cast<FixedVectorType>(Shuf.getType())->getNumElements();
SmallVector<int, 16> NewMask(NumMaskElts, 0);
for (unsigned i = 0; i != NumMaskElts; ++i)
if (Mask[i] == UndefMaskElem)
@@ -1885,7 +1885,7 @@ static Instruction *foldSelectShuffle(ShuffleVectorInst &Shuf,
// Canonicalize to choose from operand 0 first unless operand 1 is undefined.
// Commuting undef to operand 0 conflicts with another canonicalization.
- unsigned NumElts = cast<FixedVectorType>(Shuf.getType())->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(Shuf.getType())->getNumElements();
if (!isa<UndefValue>(Shuf.getOperand(1)) &&
Shuf.getMaskValue(0) >= (int)NumElts) {
// TODO: Can we assert that both operands of a shuffle-select are not undef
@@ -1952,8 +1952,8 @@ static Instruction *foldSelectShuffle(ShuffleVectorInst &Shuf,
is_contained(Mask, UndefMaskElem) &&
(Instruction::isIntDivRem(BOpc) || Instruction::isShift(BOpc));
if (MightCreatePoisonOrUB)
- NewC = InstCombiner::getSafeVectorConstantForBinop(BOpc, NewC,
- ConstantsAreOp1);
+ NewC = InstCombiner::getSafeVectorConstantForBinop(BOpc, NewC,
+ ConstantsAreOp1);
Value *V;
if (X == Y) {
@@ -2020,8 +2020,8 @@ static Instruction *foldTruncShuffle(ShuffleVectorInst &Shuf,
// and the source element type must be larger than the shuffle element type.
Type *SrcType = X->getType();
if (!SrcType->isVectorTy() || !SrcType->isIntOrIntVectorTy() ||
- cast<FixedVectorType>(SrcType)->getNumElements() !=
- cast<FixedVectorType>(DestType)->getNumElements() ||
+ cast<FixedVectorType>(SrcType)->getNumElements() !=
+ cast<FixedVectorType>(DestType)->getNumElements() ||
SrcType->getScalarSizeInBits() % DestType->getScalarSizeInBits() != 0)
return nullptr;
@@ -2037,7 +2037,7 @@ static Instruction *foldTruncShuffle(ShuffleVectorInst &Shuf,
if (Mask[i] == UndefMaskElem)
continue;
uint64_t LSBIndex = IsBigEndian ? (i + 1) * TruncRatio - 1 : i * TruncRatio;
- assert(LSBIndex <= INT32_MAX && "Overflowed 32-bits");
+ assert(LSBIndex <= INT32_MAX && "Overflowed 32-bits");
if (Mask[i] != (int)LSBIndex)
return nullptr;
}
@@ -2064,19 +2064,19 @@ static Instruction *narrowVectorSelect(ShuffleVectorInst &Shuf,
// We need a narrow condition value. It must be extended with undef elements
// and have the same number of elements as this shuffle.
- unsigned NarrowNumElts =
- cast<FixedVectorType>(Shuf.getType())->getNumElements();
+ unsigned NarrowNumElts =
+ cast<FixedVectorType>(Shuf.getType())->getNumElements();
Value *NarrowCond;
if (!match(Cond, m_OneUse(m_Shuffle(m_Value(NarrowCond), m_Undef()))) ||
- cast<FixedVectorType>(NarrowCond->getType())->getNumElements() !=
+ cast<FixedVectorType>(NarrowCond->getType())->getNumElements() !=
NarrowNumElts ||
!cast<ShuffleVectorInst>(Cond)->isIdentityWithPadding())
return nullptr;
// shuf (sel (shuf NarrowCond, undef, WideMask), X, Y), undef, NarrowMask) -->
// sel NarrowCond, (shuf X, undef, NarrowMask), (shuf Y, undef, NarrowMask)
- Value *NarrowX = Builder.CreateShuffleVector(X, Shuf.getShuffleMask());
- Value *NarrowY = Builder.CreateShuffleVector(Y, Shuf.getShuffleMask());
+ Value *NarrowX = Builder.CreateShuffleVector(X, Shuf.getShuffleMask());
+ Value *NarrowY = Builder.CreateShuffleVector(Y, Shuf.getShuffleMask());
return SelectInst::Create(NarrowCond, NarrowX, NarrowY);
}
@@ -2107,7 +2107,7 @@ static Instruction *foldIdentityExtractShuffle(ShuffleVectorInst &Shuf) {
// new shuffle mask. Otherwise, copy the original mask element. Example:
// shuf (shuf X, Y, <C0, C1, C2, undef, C4>), undef, <0, undef, 2, 3> -->
// shuf X, Y, <C0, undef, C2, undef>
- unsigned NumElts = cast<FixedVectorType>(Shuf.getType())->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(Shuf.getType())->getNumElements();
SmallVector<int, 16> NewMask(NumElts);
assert(NumElts < Mask.size() &&
"Identity with extract must have less elements than its inputs");
@@ -2123,7 +2123,7 @@ static Instruction *foldIdentityExtractShuffle(ShuffleVectorInst &Shuf) {
/// Try to replace a shuffle with an insertelement or try to replace a shuffle
/// operand with the operand of an insertelement.
static Instruction *foldShuffleWithInsert(ShuffleVectorInst &Shuf,
- InstCombinerImpl &IC) {
+ InstCombinerImpl &IC) {
Value *V0 = Shuf.getOperand(0), *V1 = Shuf.getOperand(1);
SmallVector<int, 16> Mask;
Shuf.getShuffleMask(Mask);
@@ -2132,7 +2132,7 @@ static Instruction *foldShuffleWithInsert(ShuffleVectorInst &Shuf,
// TODO: This restriction could be removed if the insert has only one use
// (because the transform would require a new length-changing shuffle).
int NumElts = Mask.size();
- if (NumElts != (int)(cast<FixedVectorType>(V0->getType())->getNumElements()))
+ if (NumElts != (int)(cast<FixedVectorType>(V0->getType())->getNumElements()))
return nullptr;
// This is a specialization of a fold in SimplifyDemandedVectorElts. We may
@@ -2144,7 +2144,7 @@ static Instruction *foldShuffleWithInsert(ShuffleVectorInst &Shuf,
uint64_t IdxC;
if (match(V0, m_InsertElt(m_Value(X), m_Value(), m_ConstantInt(IdxC)))) {
// shuf (inselt X, ?, IdxC), ?, Mask --> shuf X, ?, Mask
- if (!is_contained(Mask, (int)IdxC))
+ if (!is_contained(Mask, (int)IdxC))
return IC.replaceOperand(Shuf, 0, X);
}
if (match(V1, m_InsertElt(m_Value(X), m_Value(), m_ConstantInt(IdxC)))) {
@@ -2152,7 +2152,7 @@ static Instruction *foldShuffleWithInsert(ShuffleVectorInst &Shuf,
// accesses to the 2nd vector input of the shuffle.
IdxC += NumElts;
// shuf ?, (inselt X, ?, IdxC), Mask --> shuf ?, X, Mask
- if (!is_contained(Mask, (int)IdxC))
+ if (!is_contained(Mask, (int)IdxC))
return IC.replaceOperand(Shuf, 1, X);
}
@@ -2227,10 +2227,10 @@ static Instruction *foldIdentityPaddedShuffles(ShuffleVectorInst &Shuf) {
Value *X = Shuffle0->getOperand(0);
Value *Y = Shuffle1->getOperand(0);
if (X->getType() != Y->getType() ||
- !isPowerOf2_32(cast<FixedVectorType>(Shuf.getType())->getNumElements()) ||
- !isPowerOf2_32(
- cast<FixedVectorType>(Shuffle0->getType())->getNumElements()) ||
- !isPowerOf2_32(cast<FixedVectorType>(X->getType())->getNumElements()) ||
+ !isPowerOf2_32(cast<FixedVectorType>(Shuf.getType())->getNumElements()) ||
+ !isPowerOf2_32(
+ cast<FixedVectorType>(Shuffle0->getType())->getNumElements()) ||
+ !isPowerOf2_32(cast<FixedVectorType>(X->getType())->getNumElements()) ||
isa<UndefValue>(X) || isa<UndefValue>(Y))
return nullptr;
assert(isa<UndefValue>(Shuffle0->getOperand(1)) &&
@@ -2241,8 +2241,8 @@ static Instruction *foldIdentityPaddedShuffles(ShuffleVectorInst &Shuf) {
// operands directly by adjusting the shuffle mask to account for the narrower
// types:
// shuf (widen X), (widen Y), Mask --> shuf X, Y, Mask'
- int NarrowElts = cast<FixedVectorType>(X->getType())->getNumElements();
- int WideElts = cast<FixedVectorType>(Shuffle0->getType())->getNumElements();
+ int NarrowElts = cast<FixedVectorType>(X->getType())->getNumElements();
+ int WideElts = cast<FixedVectorType>(Shuffle0->getType())->getNumElements();
assert(WideElts > NarrowElts && "Unexpected types for identity with padding");
ArrayRef<int> Mask = Shuf.getShuffleMask();
@@ -2275,7 +2275,7 @@ static Instruction *foldIdentityPaddedShuffles(ShuffleVectorInst &Shuf) {
return new ShuffleVectorInst(X, Y, NewMask);
}
-Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
+Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
Value *LHS = SVI.getOperand(0);
Value *RHS = SVI.getOperand(1);
SimplifyQuery ShufQuery = SQ.getWithInstruction(&SVI);
@@ -2283,13 +2283,13 @@ Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
SVI.getType(), ShufQuery))
return replaceInstUsesWith(SVI, V);
- // Bail out for scalable vectors
- if (isa<ScalableVectorType>(LHS->getType()))
- return nullptr;
-
+ // Bail out for scalable vectors
+ if (isa<ScalableVectorType>(LHS->getType()))
+ return nullptr;
+
// shuffle x, x, mask --> shuffle x, undef, mask'
- unsigned VWidth = cast<FixedVectorType>(SVI.getType())->getNumElements();
- unsigned LHSWidth = cast<FixedVectorType>(LHS->getType())->getNumElements();
+ unsigned VWidth = cast<FixedVectorType>(SVI.getType())->getNumElements();
+ unsigned LHSWidth = cast<FixedVectorType>(LHS->getType())->getNumElements();
ArrayRef<int> Mask = SVI.getShuffleMask();
Type *Int32Ty = Type::getInt32Ty(SVI.getContext());
@@ -2303,7 +2303,7 @@ Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
if (match(LHS, m_BitCast(m_Value(X))) && match(RHS, m_Undef()) &&
X->getType()->isVectorTy() && VWidth == LHSWidth) {
// Try to create a scaled mask constant.
- auto *XType = cast<FixedVectorType>(X->getType());
+ auto *XType = cast<FixedVectorType>(X->getType());
unsigned XNumElts = XType->getNumElements();
SmallVector<int, 16> ScaledMask;
if (XNumElts >= VWidth) {
@@ -2411,7 +2411,7 @@ Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
if (isShuffleExtractingFromLHS(SVI, Mask)) {
Value *V = LHS;
unsigned MaskElems = Mask.size();
- auto *SrcTy = cast<FixedVectorType>(V->getType());
+ auto *SrcTy = cast<FixedVectorType>(V->getType());
unsigned VecBitWidth = SrcTy->getPrimitiveSizeInBits().getFixedSize();
unsigned SrcElemBitWidth = DL.getTypeSizeInBits(SrcTy->getElementType());
assert(SrcElemBitWidth && "vector elements must have a bitwidth");
@@ -2443,7 +2443,7 @@ Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
SmallVector<int, 16> ShuffleMask(SrcNumElems, -1);
for (unsigned I = 0, E = MaskElems, Idx = BegIdx; I != E; ++Idx, ++I)
ShuffleMask[I] = Idx;
- V = Builder.CreateShuffleVector(V, ShuffleMask,
+ V = Builder.CreateShuffleVector(V, ShuffleMask,
SVI.getName() + ".extract");
BegIdx = 0;
}
@@ -2528,11 +2528,11 @@ Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
if (LHSShuffle) {
LHSOp0 = LHSShuffle->getOperand(0);
LHSOp1 = LHSShuffle->getOperand(1);
- LHSOp0Width = cast<FixedVectorType>(LHSOp0->getType())->getNumElements();
+ LHSOp0Width = cast<FixedVectorType>(LHSOp0->getType())->getNumElements();
}
if (RHSShuffle) {
RHSOp0 = RHSShuffle->getOperand(0);
- RHSOp0Width = cast<FixedVectorType>(RHSOp0->getType())->getNumElements();
+ RHSOp0Width = cast<FixedVectorType>(RHSOp0->getType())->getNumElements();
}
Value* newLHS = LHS;
Value* newRHS = RHS;
@@ -2637,7 +2637,7 @@ Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
if (isSplat || newMask == LHSMask || newMask == RHSMask || newMask == Mask) {
if (!newRHS)
newRHS = UndefValue::get(newLHS->getType());
- return new ShuffleVectorInst(newLHS, newRHS, newMask);
+ return new ShuffleVectorInst(newLHS, newRHS, newMask);
}
return MadeChange ? &SVI : nullptr;
diff --git a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstructionCombining.cpp b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstructionCombining.cpp
index 5e2c9a3e54..828fd49524 100644
--- a/contrib/libs/llvm12/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -59,7 +59,7 @@
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/TargetFolder.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/BasicBlock.h"
@@ -114,9 +114,9 @@ using namespace llvm::PatternMatch;
#define DEBUG_TYPE "instcombine"
-STATISTIC(NumWorklistIterations,
- "Number of instruction combining iterations performed");
-
+STATISTIC(NumWorklistIterations,
+ "Number of instruction combining iterations performed");
+
STATISTIC(NumCombined , "Number of insts combined");
STATISTIC(NumConstProp, "Number of constant folds");
STATISTIC(NumDeadInst , "Number of dead inst eliminated");
@@ -127,13 +127,13 @@ STATISTIC(NumReassoc , "Number of reassociations");
DEBUG_COUNTER(VisitCounter, "instcombine-visit",
"Controls which instructions are visited");
-// FIXME: these limits eventually should be as low as 2.
+// FIXME: these limits eventually should be as low as 2.
static constexpr unsigned InstCombineDefaultMaxIterations = 1000;
-#ifndef NDEBUG
-static constexpr unsigned InstCombineDefaultInfiniteLoopThreshold = 100;
-#else
+#ifndef NDEBUG
+static constexpr unsigned InstCombineDefaultInfiniteLoopThreshold = 100;
+#else
static constexpr unsigned InstCombineDefaultInfiniteLoopThreshold = 1000;
-#endif
+#endif
static cl::opt<bool>
EnableCodeSinking("instcombine-code-sinking", cl::desc("Enable code sinking"),
@@ -164,41 +164,41 @@ MaxArraySize("instcombine-maxarray-size", cl::init(1024),
static cl::opt<unsigned> ShouldLowerDbgDeclare("instcombine-lower-dbg-declare",
cl::Hidden, cl::init(true));
-Optional<Instruction *>
-InstCombiner::targetInstCombineIntrinsic(IntrinsicInst &II) {
- // Handle target specific intrinsics
- if (II.getCalledFunction()->isTargetIntrinsic()) {
- return TTI.instCombineIntrinsic(*this, II);
- }
- return None;
-}
-
-Optional<Value *> InstCombiner::targetSimplifyDemandedUseBitsIntrinsic(
- IntrinsicInst &II, APInt DemandedMask, KnownBits &Known,
- bool &KnownBitsComputed) {
- // Handle target specific intrinsics
- if (II.getCalledFunction()->isTargetIntrinsic()) {
- return TTI.simplifyDemandedUseBitsIntrinsic(*this, II, DemandedMask, Known,
- KnownBitsComputed);
- }
- return None;
-}
-
-Optional<Value *> InstCombiner::targetSimplifyDemandedVectorEltsIntrinsic(
- IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts, APInt &UndefElts2,
- APInt &UndefElts3,
- std::function<void(Instruction *, unsigned, APInt, APInt &)>
- SimplifyAndSetOp) {
- // Handle target specific intrinsics
- if (II.getCalledFunction()->isTargetIntrinsic()) {
- return TTI.simplifyDemandedVectorEltsIntrinsic(
- *this, II, DemandedElts, UndefElts, UndefElts2, UndefElts3,
- SimplifyAndSetOp);
- }
- return None;
-}
-
-Value *InstCombinerImpl::EmitGEPOffset(User *GEP) {
+Optional<Instruction *>
+InstCombiner::targetInstCombineIntrinsic(IntrinsicInst &II) {
+ // Handle target specific intrinsics
+ if (II.getCalledFunction()->isTargetIntrinsic()) {
+ return TTI.instCombineIntrinsic(*this, II);
+ }
+ return None;
+}
+
+Optional<Value *> InstCombiner::targetSimplifyDemandedUseBitsIntrinsic(
+ IntrinsicInst &II, APInt DemandedMask, KnownBits &Known,
+ bool &KnownBitsComputed) {
+ // Handle target specific intrinsics
+ if (II.getCalledFunction()->isTargetIntrinsic()) {
+ return TTI.simplifyDemandedUseBitsIntrinsic(*this, II, DemandedMask, Known,
+ KnownBitsComputed);
+ }
+ return None;
+}
+
+Optional<Value *> InstCombiner::targetSimplifyDemandedVectorEltsIntrinsic(
+ IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts, APInt &UndefElts2,
+ APInt &UndefElts3,
+ std::function<void(Instruction *, unsigned, APInt, APInt &)>
+ SimplifyAndSetOp) {
+ // Handle target specific intrinsics
+ if (II.getCalledFunction()->isTargetIntrinsic()) {
+ return TTI.simplifyDemandedVectorEltsIntrinsic(
+ *this, II, DemandedElts, UndefElts, UndefElts2, UndefElts3,
+ SimplifyAndSetOp);
+ }
+ return None;
+}
+
+Value *InstCombinerImpl::EmitGEPOffset(User *GEP) {
return llvm::EmitGEPOffset(&Builder, DL, GEP);
}
@@ -211,8 +211,8 @@ Value *InstCombinerImpl::EmitGEPOffset(User *GEP) {
/// legal to convert to, in order to open up more combining opportunities.
/// NOTE: this treats i8, i16 and i32 specially, due to them being so common
/// from frontend languages.
-bool InstCombinerImpl::shouldChangeType(unsigned FromWidth,
- unsigned ToWidth) const {
+bool InstCombinerImpl::shouldChangeType(unsigned FromWidth,
+ unsigned ToWidth) const {
bool FromLegal = FromWidth == 1 || DL.isLegalInteger(FromWidth);
bool ToLegal = ToWidth == 1 || DL.isLegalInteger(ToWidth);
@@ -239,7 +239,7 @@ bool InstCombinerImpl::shouldChangeType(unsigned FromWidth,
/// to a larger illegal type. i1 is always treated as a legal type because it is
/// a fundamental type in IR, and there are many specialized optimizations for
/// i1 types.
-bool InstCombinerImpl::shouldChangeType(Type *From, Type *To) const {
+bool InstCombinerImpl::shouldChangeType(Type *From, Type *To) const {
// TODO: This could be extended to allow vectors. Datalayout changes might be
// needed to properly support that.
if (!From->isIntegerTy() || !To->isIntegerTy())
@@ -307,8 +307,8 @@ static void ClearSubclassDataAfterReassociation(BinaryOperator &I) {
/// cast to eliminate one of the associative operations:
/// (op (cast (op X, C2)), C1) --> (cast (op X, op (C1, C2)))
/// (op (cast (op X, C2)), C1) --> (op (cast X), op (C1, C2))
-static bool simplifyAssocCastAssoc(BinaryOperator *BinOp1,
- InstCombinerImpl &IC) {
+static bool simplifyAssocCastAssoc(BinaryOperator *BinOp1,
+ InstCombinerImpl &IC) {
auto *Cast = dyn_cast<CastInst>(BinOp1->getOperand(0));
if (!Cast || !Cast->hasOneUse())
return false;
@@ -366,7 +366,7 @@ static bool simplifyAssocCastAssoc(BinaryOperator *BinOp1,
/// 5. Transform: "A op (B op C)" ==> "B op (C op A)" if "C op A" simplifies.
/// 6. Transform: "(A op C1) op (B op C2)" ==> "(A op B) op (C1 op C2)"
/// if C1 and C2 are constants.
-bool InstCombinerImpl::SimplifyAssociativeOrCommutative(BinaryOperator &I) {
+bool InstCombinerImpl::SimplifyAssociativeOrCommutative(BinaryOperator &I) {
Instruction::BinaryOps Opcode = I.getOpcode();
bool Changed = false;
@@ -594,10 +594,10 @@ getBinOpsForFactorization(Instruction::BinaryOps TopOpcode, BinaryOperator *Op,
/// This tries to simplify binary operations by factorizing out common terms
/// (e. g. "(A*B)+(A*C)" -> "A*(B+C)").
-Value *InstCombinerImpl::tryFactorization(BinaryOperator &I,
- Instruction::BinaryOps InnerOpcode,
- Value *A, Value *B, Value *C,
- Value *D) {
+Value *InstCombinerImpl::tryFactorization(BinaryOperator &I,
+ Instruction::BinaryOps InnerOpcode,
+ Value *A, Value *B, Value *C,
+ Value *D) {
assert(A && B && C && D && "All values must be provided");
Value *V = nullptr;
@@ -700,7 +700,7 @@ Value *InstCombinerImpl::tryFactorization(BinaryOperator &I,
/// (eg "(A*B)+(A*C)" -> "A*(B+C)") or expanding out if this results in
/// simplifications (eg: "A & (B | C) -> (A&B) | (A&C)" if this is a win).
/// Returns the simplified value, or null if it didn't simplify.
-Value *InstCombinerImpl::SimplifyUsingDistributiveLaws(BinaryOperator &I) {
+Value *InstCombinerImpl::SimplifyUsingDistributiveLaws(BinaryOperator &I) {
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
BinaryOperator *Op0 = dyn_cast<BinaryOperator>(LHS);
BinaryOperator *Op1 = dyn_cast<BinaryOperator>(RHS);
@@ -743,10 +743,10 @@ Value *InstCombinerImpl::SimplifyUsingDistributiveLaws(BinaryOperator &I) {
Value *A = Op0->getOperand(0), *B = Op0->getOperand(1), *C = RHS;
Instruction::BinaryOps InnerOpcode = Op0->getOpcode(); // op'
- // Disable the use of undef because it's not safe to distribute undef.
- auto SQDistributive = SQ.getWithInstruction(&I).getWithoutUndef();
- Value *L = SimplifyBinOp(TopLevelOpcode, A, C, SQDistributive);
- Value *R = SimplifyBinOp(TopLevelOpcode, B, C, SQDistributive);
+ // Disable the use of undef because it's not safe to distribute undef.
+ auto SQDistributive = SQ.getWithInstruction(&I).getWithoutUndef();
+ Value *L = SimplifyBinOp(TopLevelOpcode, A, C, SQDistributive);
+ Value *R = SimplifyBinOp(TopLevelOpcode, B, C, SQDistributive);
// Do "A op C" and "B op C" both simplify?
if (L && R) {
@@ -782,10 +782,10 @@ Value *InstCombinerImpl::SimplifyUsingDistributiveLaws(BinaryOperator &I) {
Value *A = LHS, *B = Op1->getOperand(0), *C = Op1->getOperand(1);
Instruction::BinaryOps InnerOpcode = Op1->getOpcode(); // op'
- // Disable the use of undef because it's not safe to distribute undef.
- auto SQDistributive = SQ.getWithInstruction(&I).getWithoutUndef();
- Value *L = SimplifyBinOp(TopLevelOpcode, A, B, SQDistributive);
- Value *R = SimplifyBinOp(TopLevelOpcode, A, C, SQDistributive);
+ // Disable the use of undef because it's not safe to distribute undef.
+ auto SQDistributive = SQ.getWithInstruction(&I).getWithoutUndef();
+ Value *L = SimplifyBinOp(TopLevelOpcode, A, B, SQDistributive);
+ Value *R = SimplifyBinOp(TopLevelOpcode, A, C, SQDistributive);
// Do "A op B" and "A op C" both simplify?
if (L && R) {
@@ -818,9 +818,9 @@ Value *InstCombinerImpl::SimplifyUsingDistributiveLaws(BinaryOperator &I) {
return SimplifySelectsFeedingBinaryOp(I, LHS, RHS);
}
-Value *InstCombinerImpl::SimplifySelectsFeedingBinaryOp(BinaryOperator &I,
- Value *LHS,
- Value *RHS) {
+Value *InstCombinerImpl::SimplifySelectsFeedingBinaryOp(BinaryOperator &I,
+ Value *LHS,
+ Value *RHS) {
Value *A, *B, *C, *D, *E, *F;
bool LHSIsSelect = match(LHS, m_Select(m_Value(A), m_Value(B), m_Value(C)));
bool RHSIsSelect = match(RHS, m_Select(m_Value(D), m_Value(E), m_Value(F)));
@@ -870,33 +870,33 @@ Value *InstCombinerImpl::SimplifySelectsFeedingBinaryOp(BinaryOperator &I,
return SI;
}
-/// Freely adapt every user of V as-if V was changed to !V.
-/// WARNING: only if canFreelyInvertAllUsersOf() said this can be done.
-void InstCombinerImpl::freelyInvertAllUsersOf(Value *I) {
- for (User *U : I->users()) {
- switch (cast<Instruction>(U)->getOpcode()) {
- case Instruction::Select: {
- auto *SI = cast<SelectInst>(U);
- SI->swapValues();
- SI->swapProfMetadata();
- break;
- }
- case Instruction::Br:
- cast<BranchInst>(U)->swapSuccessors(); // swaps prof metadata too
- break;
- case Instruction::Xor:
- replaceInstUsesWith(cast<Instruction>(*U), I);
- break;
- default:
- llvm_unreachable("Got unexpected user - out of sync with "
- "canFreelyInvertAllUsersOf() ?");
- }
- }
-}
-
+/// Freely adapt every user of V as-if V was changed to !V.
+/// WARNING: only if canFreelyInvertAllUsersOf() said this can be done.
+void InstCombinerImpl::freelyInvertAllUsersOf(Value *I) {
+ for (User *U : I->users()) {
+ switch (cast<Instruction>(U)->getOpcode()) {
+ case Instruction::Select: {
+ auto *SI = cast<SelectInst>(U);
+ SI->swapValues();
+ SI->swapProfMetadata();
+ break;
+ }
+ case Instruction::Br:
+ cast<BranchInst>(U)->swapSuccessors(); // swaps prof metadata too
+ break;
+ case Instruction::Xor:
+ replaceInstUsesWith(cast<Instruction>(*U), I);
+ break;
+ default:
+ llvm_unreachable("Got unexpected user - out of sync with "
+ "canFreelyInvertAllUsersOf() ?");
+ }
+ }
+}
+
/// Given a 'sub' instruction, return the RHS of the instruction if the LHS is a
/// constant zero (which is the 'negate' form).
-Value *InstCombinerImpl::dyn_castNegVal(Value *V) const {
+Value *InstCombinerImpl::dyn_castNegVal(Value *V) const {
Value *NegV;
if (match(V, m_Neg(m_Value(NegV))))
return NegV;
@@ -957,8 +957,8 @@ static Value *foldOperationIntoSelectOperand(Instruction &I, Value *SO,
return RI;
}
-Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op,
- SelectInst *SI) {
+Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op,
+ SelectInst *SI) {
// Don't modify shared select instructions.
if (!SI->hasOneUse())
return nullptr;
@@ -983,7 +983,7 @@ Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op,
return nullptr;
// If vectors, verify that they have the same number of elements.
- if (SrcTy && SrcTy->getElementCount() != DestTy->getElementCount())
+ if (SrcTy && SrcTy->getElementCount() != DestTy->getElementCount())
return nullptr;
}
@@ -1053,7 +1053,7 @@ static Value *foldOperationIntoPhiValue(BinaryOperator *I, Value *InV,
return RI;
}
-Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
+Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
unsigned NumPHIValues = PN->getNumIncomingValues();
if (NumPHIValues == 0)
return nullptr;
@@ -1079,9 +1079,9 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
BasicBlock *NonConstBB = nullptr;
for (unsigned i = 0; i != NumPHIValues; ++i) {
Value *InVal = PN->getIncomingValue(i);
- // If I is a freeze instruction, count undef as a non-constant.
- if (match(InVal, m_ImmConstant()) &&
- (!isa<FreezeInst>(I) || isGuaranteedNotToBeUndefOrPoison(InVal)))
+ // If I is a freeze instruction, count undef as a non-constant.
+ if (match(InVal, m_ImmConstant()) &&
+ (!isa<FreezeInst>(I) || isGuaranteedNotToBeUndefOrPoison(InVal)))
continue;
if (isa<PHINode>(InVal)) return nullptr; // Itself a phi.
@@ -1106,11 +1106,11 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
// operation in that block. However, if this is a critical edge, we would be
// inserting the computation on some other paths (e.g. inside a loop). Only
// do this if the pred block is unconditionally branching into the phi block.
- // Also, make sure that the pred block is not dead code.
+ // Also, make sure that the pred block is not dead code.
if (NonConstBB != nullptr) {
BranchInst *BI = dyn_cast<BranchInst>(NonConstBB->getTerminator());
- if (!BI || !BI->isUnconditional() || !DT.isReachableFromEntry(NonConstBB))
- return nullptr;
+ if (!BI || !BI->isUnconditional() || !DT.isReachableFromEntry(NonConstBB))
+ return nullptr;
}
// Okay, we can do the transformation: create the new PHI node.
@@ -1142,7 +1142,7 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
// FalseVInPred versus TrueVInPred. When we have individual nonzero
// elements in the vector, we will incorrectly fold InC to
// `TrueVInPred`.
- if (InC && isa<ConstantInt>(InC))
+ if (InC && isa<ConstantInt>(InC))
InV = InC->isNullValue() ? FalseVInPred : TrueVInPred;
else {
// Generate the select in the same block as PN's current incoming block.
@@ -1176,15 +1176,15 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
Builder);
NewPN->addIncoming(InV, PN->getIncomingBlock(i));
}
- } else if (isa<FreezeInst>(&I)) {
- for (unsigned i = 0; i != NumPHIValues; ++i) {
- Value *InV;
- if (NonConstBB == PN->getIncomingBlock(i))
- InV = Builder.CreateFreeze(PN->getIncomingValue(i), "phi.fr");
- else
- InV = PN->getIncomingValue(i);
- NewPN->addIncoming(InV, PN->getIncomingBlock(i));
- }
+ } else if (isa<FreezeInst>(&I)) {
+ for (unsigned i = 0; i != NumPHIValues; ++i) {
+ Value *InV;
+ if (NonConstBB == PN->getIncomingBlock(i))
+ InV = Builder.CreateFreeze(PN->getIncomingValue(i), "phi.fr");
+ else
+ InV = PN->getIncomingValue(i);
+ NewPN->addIncoming(InV, PN->getIncomingBlock(i));
+ }
} else {
CastInst *CI = cast<CastInst>(&I);
Type *RetTy = CI->getType();
@@ -1199,8 +1199,8 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
}
}
- for (User *U : make_early_inc_range(PN->users())) {
- Instruction *User = cast<Instruction>(U);
+ for (User *U : make_early_inc_range(PN->users())) {
+ Instruction *User = cast<Instruction>(U);
if (User == &I) continue;
replaceInstUsesWith(*User, NewPN);
eraseInstFromFunction(*User);
@@ -1208,7 +1208,7 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
return replaceInstUsesWith(I, NewPN);
}
-Instruction *InstCombinerImpl::foldBinOpIntoSelectOrPhi(BinaryOperator &I) {
+Instruction *InstCombinerImpl::foldBinOpIntoSelectOrPhi(BinaryOperator &I) {
if (!isa<Constant>(I.getOperand(1)))
return nullptr;
@@ -1226,9 +1226,9 @@ Instruction *InstCombinerImpl::foldBinOpIntoSelectOrPhi(BinaryOperator &I) {
/// is a sequence of GEP indices into the pointed type that will land us at the
/// specified offset. If so, fill them into NewIndices and return the resultant
/// element type, otherwise return null.
-Type *
-InstCombinerImpl::FindElementAtOffset(PointerType *PtrTy, int64_t Offset,
- SmallVectorImpl<Value *> &NewIndices) {
+Type *
+InstCombinerImpl::FindElementAtOffset(PointerType *PtrTy, int64_t Offset,
+ SmallVectorImpl<Value *> &NewIndices) {
Type *Ty = PtrTy->getElementType();
if (!Ty->isSized())
return nullptr;
@@ -1297,7 +1297,7 @@ static bool shouldMergeGEPs(GEPOperator &GEP, GEPOperator &Src) {
/// Return a value X such that Val = X * Scale, or null if none.
/// If the multiplication is known not to overflow, then NoSignedWrap is set.
-Value *InstCombinerImpl::Descale(Value *Val, APInt Scale, bool &NoSignedWrap) {
+Value *InstCombinerImpl::Descale(Value *Val, APInt Scale, bool &NoSignedWrap) {
assert(isa<IntegerType>(Val->getType()) && "Can only descale integers!");
assert(cast<IntegerType>(Val->getType())->getBitWidth() ==
Scale.getBitWidth() && "Scale not compatible with value!");
@@ -1537,8 +1537,8 @@ Value *InstCombinerImpl::Descale(Value *Val, APInt Scale, bool &NoSignedWrap) {
} while (true);
}
-Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) {
- if (!isa<VectorType>(Inst.getType()))
+Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) {
+ if (!isa<VectorType>(Inst.getType()))
return nullptr;
BinaryOperator::BinaryOps Opcode = Inst.getOpcode();
@@ -1628,14 +1628,14 @@ Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) {
// other binops, so they can be folded. It may also enable demanded elements
// transforms.
Constant *C;
- auto *InstVTy = dyn_cast<FixedVectorType>(Inst.getType());
- if (InstVTy &&
- match(&Inst,
+ auto *InstVTy = dyn_cast<FixedVectorType>(Inst.getType());
+ if (InstVTy &&
+ match(&Inst,
m_c_BinOp(m_OneUse(m_Shuffle(m_Value(V1), m_Undef(), m_Mask(Mask))),
- m_ImmConstant(C))) &&
- cast<FixedVectorType>(V1->getType())->getNumElements() <=
- InstVTy->getNumElements()) {
- assert(InstVTy->getScalarType() == V1->getType()->getScalarType() &&
+ m_ImmConstant(C))) &&
+ cast<FixedVectorType>(V1->getType())->getNumElements() <=
+ InstVTy->getNumElements()) {
+ assert(InstVTy->getScalarType() == V1->getType()->getScalarType() &&
"Shuffle should not change scalar type");
// Find constant NewC that has property:
@@ -1650,7 +1650,7 @@ Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) {
UndefValue *UndefScalar = UndefValue::get(C->getType()->getScalarType());
SmallVector<Constant *, 16> NewVecC(SrcVecNumElts, UndefScalar);
bool MayChange = true;
- unsigned NumElts = InstVTy->getNumElements();
+ unsigned NumElts = InstVTy->getNumElements();
for (unsigned I = 0; I < NumElts; ++I) {
Constant *CElt = C->getAggregateElement(I);
if (ShMask[I] >= 0) {
@@ -1740,7 +1740,7 @@ Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) {
// bo (splat X), (bo Y, OtherOp) --> bo (splat (bo X, Y)), OtherOp
Value *NewBO = Builder.CreateBinOp(Opcode, X, Y);
SmallVector<int, 8> NewMask(MaskC.size(), SplatIndex);
- Value *NewSplat = Builder.CreateShuffleVector(NewBO, NewMask);
+ Value *NewSplat = Builder.CreateShuffleVector(NewBO, NewMask);
Instruction *R = BinaryOperator::Create(Opcode, NewSplat, OtherOp);
// Intersect FMF on both new binops. Other (poison-generating) flags are
@@ -1760,7 +1760,7 @@ Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) {
/// Try to narrow the width of a binop if at least 1 operand is an extend of
/// of a value. This requires a potentially expensive known bits check to make
/// sure the narrow op does not overflow.
-Instruction *InstCombinerImpl::narrowMathIfNoOverflow(BinaryOperator &BO) {
+Instruction *InstCombinerImpl::narrowMathIfNoOverflow(BinaryOperator &BO) {
// We need at least one extended operand.
Value *Op0 = BO.getOperand(0), *Op1 = BO.getOperand(1);
@@ -1840,7 +1840,7 @@ static Instruction *foldSelectGEP(GetElementPtrInst &GEP,
// gep (select Cond, TrueC, FalseC), IndexC --> select Cond, TrueC', FalseC'
// Propagate 'inbounds' and metadata from existing instructions.
// Note: using IRBuilder to create the constants for efficiency.
- SmallVector<Value *, 4> IndexC(GEP.indices());
+ SmallVector<Value *, 4> IndexC(GEP.indices());
bool IsInBounds = GEP.isInBounds();
Value *NewTrueC = IsInBounds ? Builder.CreateInBoundsGEP(TrueC, IndexC)
: Builder.CreateGEP(TrueC, IndexC);
@@ -1849,8 +1849,8 @@ static Instruction *foldSelectGEP(GetElementPtrInst &GEP,
return SelectInst::Create(Cond, NewTrueC, NewFalseC, "", nullptr, Sel);
}
-Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
- SmallVector<Value *, 8> Ops(GEP.operands());
+Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
+ SmallVector<Value *, 8> Ops(GEP.operands());
Type *GEPType = GEP.getType();
Type *GEPEltType = GEP.getSourceElementType();
bool IsGEPSrcEleScalable = isa<ScalableVectorType>(GEPEltType);
@@ -2220,7 +2220,7 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
// GEP (bitcast i8* X to [0 x i8]*), i32 0, ... ?
if (CATy->getElementType() == StrippedPtrEltTy) {
// -> GEP i8* X, ...
- SmallVector<Value *, 8> Idx(drop_begin(GEP.indices()));
+ SmallVector<Value *, 8> Idx(drop_begin(GEP.indices()));
GetElementPtrInst *Res = GetElementPtrInst::Create(
StrippedPtrEltTy, StrippedPtr, Idx, GEP.getName());
Res->setIsInBounds(GEP.isInBounds());
@@ -2256,7 +2256,7 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
// ->
// %0 = GEP [10 x i8] addrspace(1)* X, ...
// addrspacecast i8 addrspace(1)* %0 to i8*
- SmallVector<Value *, 8> Idx(GEP.indices());
+ SmallVector<Value *, 8> Idx(GEP.indices());
Value *NewGEP =
GEP.isInBounds()
? Builder.CreateInBoundsGEP(StrippedPtrEltTy, StrippedPtr,
@@ -2398,15 +2398,15 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
// gep (bitcast [c x ty]* X to <c x ty>*), Y, Z --> gep X, Y, Z
auto areMatchingArrayAndVecTypes = [](Type *ArrTy, Type *VecTy,
const DataLayout &DL) {
- auto *VecVTy = cast<FixedVectorType>(VecTy);
+ auto *VecVTy = cast<FixedVectorType>(VecTy);
return ArrTy->getArrayElementType() == VecVTy->getElementType() &&
ArrTy->getArrayNumElements() == VecVTy->getNumElements() &&
DL.getTypeAllocSize(ArrTy) == DL.getTypeAllocSize(VecTy);
};
if (GEP.getNumOperands() == 3 &&
- ((GEPEltType->isArrayTy() && isa<FixedVectorType>(SrcEltType) &&
+ ((GEPEltType->isArrayTy() && isa<FixedVectorType>(SrcEltType) &&
areMatchingArrayAndVecTypes(GEPEltType, SrcEltType, DL)) ||
- (isa<FixedVectorType>(GEPEltType) && SrcEltType->isArrayTy() &&
+ (isa<FixedVectorType>(GEPEltType) && SrcEltType->isArrayTy() &&
areMatchingArrayAndVecTypes(SrcEltType, GEPEltType, DL)))) {
// Create a new GEP here, as using `setOperand()` followed by
@@ -2601,7 +2601,7 @@ static bool isAllocSiteRemovable(Instruction *AI,
return true;
}
-Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
+Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
// If we have a malloc call which is only used in any amount of comparisons to
// null and free calls, delete the calls and replace the comparisons with true
// or false as appropriate.
@@ -2616,10 +2616,10 @@ Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
// If we are removing an alloca with a dbg.declare, insert dbg.value calls
// before each store.
- SmallVector<DbgVariableIntrinsic *, 8> DVIs;
+ SmallVector<DbgVariableIntrinsic *, 8> DVIs;
std::unique_ptr<DIBuilder> DIB;
if (isa<AllocaInst>(MI)) {
- findDbgUsers(DVIs, &MI);
+ findDbgUsers(DVIs, &MI);
DIB.reset(new DIBuilder(*MI.getModule(), /*AllowUnresolved=*/false));
}
@@ -2653,9 +2653,9 @@ Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
ConstantInt::get(Type::getInt1Ty(C->getContext()),
C->isFalseWhenEqual()));
} else if (auto *SI = dyn_cast<StoreInst>(I)) {
- for (auto *DVI : DVIs)
- if (DVI->isAddressOfVariable())
- ConvertDebugDeclareToDebugValue(DVI, SI, *DIB);
+ for (auto *DVI : DVIs)
+ if (DVI->isAddressOfVariable())
+ ConvertDebugDeclareToDebugValue(DVI, SI, *DIB);
} else {
// Casts, GEP, or anything else: we're about to delete this instruction,
// so it can not have any valid uses.
@@ -2672,31 +2672,31 @@ Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
None, "", II->getParent());
}
- // Remove debug intrinsics which describe the value contained within the
- // alloca. In addition to removing dbg.{declare,addr} which simply point to
- // the alloca, remove dbg.value(<alloca>, ..., DW_OP_deref)'s as well, e.g.:
- //
- // ```
- // define void @foo(i32 %0) {
- // %a = alloca i32 ; Deleted.
- // store i32 %0, i32* %a
- // dbg.value(i32 %0, "arg0") ; Not deleted.
- // dbg.value(i32* %a, "arg0", DW_OP_deref) ; Deleted.
- // call void @trivially_inlinable_no_op(i32* %a)
- // ret void
- // }
- // ```
- //
- // This may not be required if we stop describing the contents of allocas
- // using dbg.value(<alloca>, ..., DW_OP_deref), but we currently do this in
- // the LowerDbgDeclare utility.
- //
- // If there is a dead store to `%a` in @trivially_inlinable_no_op, the
- // "arg0" dbg.value may be stale after the call. However, failing to remove
- // the DW_OP_deref dbg.value causes large gaps in location coverage.
- for (auto *DVI : DVIs)
- if (DVI->isAddressOfVariable() || DVI->getExpression()->startsWithDeref())
- DVI->eraseFromParent();
+ // Remove debug intrinsics which describe the value contained within the
+ // alloca. In addition to removing dbg.{declare,addr} which simply point to
+ // the alloca, remove dbg.value(<alloca>, ..., DW_OP_deref)'s as well, e.g.:
+ //
+ // ```
+ // define void @foo(i32 %0) {
+ // %a = alloca i32 ; Deleted.
+ // store i32 %0, i32* %a
+ // dbg.value(i32 %0, "arg0") ; Not deleted.
+ // dbg.value(i32* %a, "arg0", DW_OP_deref) ; Deleted.
+ // call void @trivially_inlinable_no_op(i32* %a)
+ // ret void
+ // }
+ // ```
+ //
+ // This may not be required if we stop describing the contents of allocas
+ // using dbg.value(<alloca>, ..., DW_OP_deref), but we currently do this in
+ // the LowerDbgDeclare utility.
+ //
+ // If there is a dead store to `%a` in @trivially_inlinable_no_op, the
+ // "arg0" dbg.value may be stale after the call. However, failing to remove
+ // the DW_OP_deref dbg.value causes large gaps in location coverage.
+ for (auto *DVI : DVIs)
+ if (DVI->isAddressOfVariable() || DVI->getExpression()->startsWithDeref())
+ DVI->eraseFromParent();
return eraseInstFromFunction(MI);
}
@@ -2784,7 +2784,7 @@ static Instruction *tryToMoveFreeBeforeNullTest(CallInst &FI,
return &FI;
}
-Instruction *InstCombinerImpl::visitFree(CallInst &FI) {
+Instruction *InstCombinerImpl::visitFree(CallInst &FI) {
Value *Op = FI.getArgOperand(0);
// free undef -> unreachable.
@@ -2825,7 +2825,7 @@ static bool isMustTailCall(Value *V) {
return false;
}
-Instruction *InstCombinerImpl::visitReturnInst(ReturnInst &RI) {
+Instruction *InstCombinerImpl::visitReturnInst(ReturnInst &RI) {
if (RI.getNumOperands() == 0) // ret void
return nullptr;
@@ -2848,31 +2848,31 @@ Instruction *InstCombinerImpl::visitReturnInst(ReturnInst &RI) {
return nullptr;
}
-Instruction *InstCombinerImpl::visitUnreachableInst(UnreachableInst &I) {
- // Try to remove the previous instruction if it must lead to unreachable.
- // This includes instructions like stores and "llvm.assume" that may not get
- // removed by simple dead code elimination.
- Instruction *Prev = I.getPrevNonDebugInstruction();
- if (Prev && !Prev->isEHPad() &&
- isGuaranteedToTransferExecutionToSuccessor(Prev)) {
- // Temporarily disable removal of volatile stores preceding unreachable,
- // pending a potential LangRef change permitting volatile stores to trap.
- // TODO: Either remove this code, or properly integrate the check into
- // isGuaranteedToTransferExecutionToSuccessor().
- if (auto *SI = dyn_cast<StoreInst>(Prev))
- if (SI->isVolatile())
- return nullptr;
-
- // A value may still have uses before we process it here (for example, in
- // another unreachable block), so convert those to undef.
- replaceInstUsesWith(*Prev, UndefValue::get(Prev->getType()));
- eraseInstFromFunction(*Prev);
- return &I;
- }
- return nullptr;
-}
-
-Instruction *InstCombinerImpl::visitUnconditionalBranchInst(BranchInst &BI) {
+Instruction *InstCombinerImpl::visitUnreachableInst(UnreachableInst &I) {
+ // Try to remove the previous instruction if it must lead to unreachable.
+ // This includes instructions like stores and "llvm.assume" that may not get
+ // removed by simple dead code elimination.
+ Instruction *Prev = I.getPrevNonDebugInstruction();
+ if (Prev && !Prev->isEHPad() &&
+ isGuaranteedToTransferExecutionToSuccessor(Prev)) {
+ // Temporarily disable removal of volatile stores preceding unreachable,
+ // pending a potential LangRef change permitting volatile stores to trap.
+ // TODO: Either remove this code, or properly integrate the check into
+ // isGuaranteedToTransferExecutionToSuccessor().
+ if (auto *SI = dyn_cast<StoreInst>(Prev))
+ if (SI->isVolatile())
+ return nullptr;
+
+ // A value may still have uses before we process it here (for example, in
+ // another unreachable block), so convert those to undef.
+ replaceInstUsesWith(*Prev, UndefValue::get(Prev->getType()));
+ eraseInstFromFunction(*Prev);
+ return &I;
+ }
+ return nullptr;
+}
+
+Instruction *InstCombinerImpl::visitUnconditionalBranchInst(BranchInst &BI) {
assert(BI.isUnconditional() && "Only for unconditional branches.");
// If this store is the second-to-last instruction in the basic block
@@ -2901,7 +2901,7 @@ Instruction *InstCombinerImpl::visitUnconditionalBranchInst(BranchInst &BI) {
return nullptr;
}
-Instruction *InstCombinerImpl::visitBranchInst(BranchInst &BI) {
+Instruction *InstCombinerImpl::visitBranchInst(BranchInst &BI) {
if (BI.isUnconditional())
return visitUnconditionalBranchInst(BI);
@@ -2937,7 +2937,7 @@ Instruction *InstCombinerImpl::visitBranchInst(BranchInst &BI) {
return nullptr;
}
-Instruction *InstCombinerImpl::visitSwitchInst(SwitchInst &SI) {
+Instruction *InstCombinerImpl::visitSwitchInst(SwitchInst &SI) {
Value *Cond = SI.getCondition();
Value *Op0;
ConstantInt *AddRHS;
@@ -2968,7 +2968,7 @@ Instruction *InstCombinerImpl::visitSwitchInst(SwitchInst &SI) {
unsigned NewWidth = Known.getBitWidth() - std::max(LeadingKnownZeros, LeadingKnownOnes);
// Shrink the condition operand if the new type is smaller than the old type.
- // But do not shrink to a non-standard type, because backend can't generate
+ // But do not shrink to a non-standard type, because backend can't generate
// good code for that yet.
// TODO: We can make it aggressive again after fixing PR39569.
if (NewWidth > 0 && NewWidth < Known.getBitWidth() &&
@@ -2987,7 +2987,7 @@ Instruction *InstCombinerImpl::visitSwitchInst(SwitchInst &SI) {
return nullptr;
}
-Instruction *InstCombinerImpl::visitExtractValueInst(ExtractValueInst &EV) {
+Instruction *InstCombinerImpl::visitExtractValueInst(ExtractValueInst &EV) {
Value *Agg = EV.getAggregateOperand();
if (!EV.hasIndices())
@@ -3132,11 +3132,11 @@ static bool isCatchAll(EHPersonality Personality, Constant *TypeInfo) {
case EHPersonality::GNU_CXX_SjLj:
case EHPersonality::GNU_ObjC:
case EHPersonality::MSVC_X86SEH:
- case EHPersonality::MSVC_TableSEH:
+ case EHPersonality::MSVC_TableSEH:
case EHPersonality::MSVC_CXX:
case EHPersonality::CoreCLR:
case EHPersonality::Wasm_CXX:
- case EHPersonality::XL_CXX:
+ case EHPersonality::XL_CXX:
return TypeInfo->isNullValue();
}
llvm_unreachable("invalid enum");
@@ -3149,7 +3149,7 @@ static bool shorter_filter(const Value *LHS, const Value *RHS) {
cast<ArrayType>(RHS->getType())->getNumElements();
}
-Instruction *InstCombinerImpl::visitLandingPadInst(LandingPadInst &LI) {
+Instruction *InstCombinerImpl::visitLandingPadInst(LandingPadInst &LI) {
// The logic here should be correct for any real-world personality function.
// However if that turns out not to be true, the offending logic can always
// be conditioned on the personality function, like the catch-all logic is.
@@ -3458,46 +3458,46 @@ Instruction *InstCombinerImpl::visitLandingPadInst(LandingPadInst &LI) {
return nullptr;
}
-Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
+Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
Value *Op0 = I.getOperand(0);
if (Value *V = SimplifyFreezeInst(Op0, SQ.getWithInstruction(&I)))
return replaceInstUsesWith(I, V);
- // freeze (phi const, x) --> phi const, (freeze x)
- if (auto *PN = dyn_cast<PHINode>(Op0)) {
- if (Instruction *NV = foldOpIntoPhi(I, PN))
- return NV;
- }
-
- if (match(Op0, m_Undef())) {
- // If I is freeze(undef), see its uses and fold it to the best constant.
- // - or: pick -1
- // - select's condition: pick the value that leads to choosing a constant
- // - other ops: pick 0
- Constant *BestValue = nullptr;
- Constant *NullValue = Constant::getNullValue(I.getType());
- for (const auto *U : I.users()) {
- Constant *C = NullValue;
-
- if (match(U, m_Or(m_Value(), m_Value())))
- C = Constant::getAllOnesValue(I.getType());
- else if (const auto *SI = dyn_cast<SelectInst>(U)) {
- if (SI->getCondition() == &I) {
- APInt CondVal(1, isa<Constant>(SI->getFalseValue()) ? 0 : 1);
- C = Constant::getIntegerValue(I.getType(), CondVal);
- }
- }
-
- if (!BestValue)
- BestValue = C;
- else if (BestValue != C)
- BestValue = NullValue;
- }
-
- return replaceInstUsesWith(I, BestValue);
- }
-
+ // freeze (phi const, x) --> phi const, (freeze x)
+ if (auto *PN = dyn_cast<PHINode>(Op0)) {
+ if (Instruction *NV = foldOpIntoPhi(I, PN))
+ return NV;
+ }
+
+ if (match(Op0, m_Undef())) {
+ // If I is freeze(undef), see its uses and fold it to the best constant.
+ // - or: pick -1
+ // - select's condition: pick the value that leads to choosing a constant
+ // - other ops: pick 0
+ Constant *BestValue = nullptr;
+ Constant *NullValue = Constant::getNullValue(I.getType());
+ for (const auto *U : I.users()) {
+ Constant *C = NullValue;
+
+ if (match(U, m_Or(m_Value(), m_Value())))
+ C = Constant::getAllOnesValue(I.getType());
+ else if (const auto *SI = dyn_cast<SelectInst>(U)) {
+ if (SI->getCondition() == &I) {
+ APInt CondVal(1, isa<Constant>(SI->getFalseValue()) ? 0 : 1);
+ C = Constant::getIntegerValue(I.getType(), CondVal);
+ }
+ }
+
+ if (!BestValue)
+ BestValue = C;
+ else if (BestValue != C)
+ BestValue = NullValue;
+ }
+
+ return replaceInstUsesWith(I, BestValue);
+ }
+
return nullptr;
}
@@ -3603,7 +3603,7 @@ static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock) {
return true;
}
-bool InstCombinerImpl::run() {
+bool InstCombinerImpl::run() {
while (!Worklist.isEmpty()) {
// Walk deferred instructions in reverse order, and push them to the
// worklist, which means they'll end up popped from the worklist in-order.
@@ -3665,9 +3665,9 @@ bool InstCombinerImpl::run() {
else
UserParent = UserInst->getParent();
- // Try sinking to another block. If that block is unreachable, then do
- // not bother. SimplifyCFG should handle it.
- if (UserParent != BB && DT.isReachableFromEntry(UserParent)) {
+ // Try sinking to another block. If that block is unreachable, then do
+ // not bother. SimplifyCFG should handle it.
+ if (UserParent != BB && DT.isReachableFromEntry(UserParent)) {
// See if the user is one of our successors that has only one
// predecessor, so that we don't have to split the critical edge.
bool ShouldSink = UserParent->getUniquePredecessor() == BB;
@@ -3701,8 +3701,8 @@ bool InstCombinerImpl::run() {
// Now that we have an instruction, try combining it to simplify it.
Builder.SetInsertPoint(I);
- Builder.CollectMetadataToCopy(
- I, {LLVMContext::MD_dbg, LLVMContext::MD_annotation});
+ Builder.CollectMetadataToCopy(
+ I, {LLVMContext::MD_dbg, LLVMContext::MD_annotation});
#ifndef NDEBUG
std::string OrigI;
@@ -3717,8 +3717,8 @@ bool InstCombinerImpl::run() {
LLVM_DEBUG(dbgs() << "IC: Old = " << *I << '\n'
<< " New = " << *Result << '\n');
- Result->copyMetadata(*I,
- {LLVMContext::MD_dbg, LLVMContext::MD_annotation});
+ Result->copyMetadata(*I,
+ {LLVMContext::MD_dbg, LLVMContext::MD_annotation});
// Everything uses the new instruction now.
I->replaceAllUsesWith(Result);
@@ -3729,14 +3729,14 @@ bool InstCombinerImpl::run() {
BasicBlock *InstParent = I->getParent();
BasicBlock::iterator InsertPos = I->getIterator();
- // Are we replace a PHI with something that isn't a PHI, or vice versa?
- if (isa<PHINode>(Result) != isa<PHINode>(I)) {
- // We need to fix up the insertion point.
- if (isa<PHINode>(I)) // PHI -> Non-PHI
- InsertPos = InstParent->getFirstInsertionPt();
- else // Non-PHI -> PHI
- InsertPos = InstParent->getFirstNonPHI()->getIterator();
- }
+ // Are we replace a PHI with something that isn't a PHI, or vice versa?
+ if (isa<PHINode>(Result) != isa<PHINode>(I)) {
+ // We need to fix up the insertion point.
+ if (isa<PHINode>(I)) // PHI -> Non-PHI
+ InsertPos = InstParent->getFirstInsertionPt();
+ else // Non-PHI -> PHI
+ InsertPos = InstParent->getFirstNonPHI()->getIterator();
+ }
InstParent->getInstList().insert(InsertPos, Result);
@@ -3766,55 +3766,55 @@ bool InstCombinerImpl::run() {
return MadeIRChange;
}
-// Track the scopes used by !alias.scope and !noalias. In a function, a
-// @llvm.experimental.noalias.scope.decl is only useful if that scope is used
-// by both sets. If not, the declaration of the scope can be safely omitted.
-// The MDNode of the scope can be omitted as well for the instructions that are
-// part of this function. We do not do that at this point, as this might become
-// too time consuming to do.
-class AliasScopeTracker {
- SmallPtrSet<const MDNode *, 8> UsedAliasScopesAndLists;
- SmallPtrSet<const MDNode *, 8> UsedNoAliasScopesAndLists;
-
-public:
- void analyse(Instruction *I) {
- // This seems to be faster than checking 'mayReadOrWriteMemory()'.
- if (!I->hasMetadataOtherThanDebugLoc())
- return;
-
- auto Track = [](Metadata *ScopeList, auto &Container) {
- const auto *MDScopeList = dyn_cast_or_null<MDNode>(ScopeList);
- if (!MDScopeList || !Container.insert(MDScopeList).second)
- return;
- for (auto &MDOperand : MDScopeList->operands())
- if (auto *MDScope = dyn_cast<MDNode>(MDOperand))
- Container.insert(MDScope);
- };
-
- Track(I->getMetadata(LLVMContext::MD_alias_scope), UsedAliasScopesAndLists);
- Track(I->getMetadata(LLVMContext::MD_noalias), UsedNoAliasScopesAndLists);
- }
-
- bool isNoAliasScopeDeclDead(Instruction *Inst) {
- NoAliasScopeDeclInst *Decl = dyn_cast<NoAliasScopeDeclInst>(Inst);
- if (!Decl)
- return false;
-
- assert(Decl->use_empty() &&
- "llvm.experimental.noalias.scope.decl in use ?");
- const MDNode *MDSL = Decl->getScopeList();
- assert(MDSL->getNumOperands() == 1 &&
- "llvm.experimental.noalias.scope should refer to a single scope");
- auto &MDOperand = MDSL->getOperand(0);
- if (auto *MD = dyn_cast<MDNode>(MDOperand))
- return !UsedAliasScopesAndLists.contains(MD) ||
- !UsedNoAliasScopesAndLists.contains(MD);
-
- // Not an MDNode ? throw away.
- return true;
- }
-};
-
+// Track the scopes used by !alias.scope and !noalias. In a function, a
+// @llvm.experimental.noalias.scope.decl is only useful if that scope is used
+// by both sets. If not, the declaration of the scope can be safely omitted.
+// The MDNode of the scope can be omitted as well for the instructions that are
+// part of this function. We do not do that at this point, as this might become
+// too time consuming to do.
+class AliasScopeTracker {
+ SmallPtrSet<const MDNode *, 8> UsedAliasScopesAndLists;
+ SmallPtrSet<const MDNode *, 8> UsedNoAliasScopesAndLists;
+
+public:
+ void analyse(Instruction *I) {
+ // This seems to be faster than checking 'mayReadOrWriteMemory()'.
+ if (!I->hasMetadataOtherThanDebugLoc())
+ return;
+
+ auto Track = [](Metadata *ScopeList, auto &Container) {
+ const auto *MDScopeList = dyn_cast_or_null<MDNode>(ScopeList);
+ if (!MDScopeList || !Container.insert(MDScopeList).second)
+ return;
+ for (auto &MDOperand : MDScopeList->operands())
+ if (auto *MDScope = dyn_cast<MDNode>(MDOperand))
+ Container.insert(MDScope);
+ };
+
+ Track(I->getMetadata(LLVMContext::MD_alias_scope), UsedAliasScopesAndLists);
+ Track(I->getMetadata(LLVMContext::MD_noalias), UsedNoAliasScopesAndLists);
+ }
+
+ bool isNoAliasScopeDeclDead(Instruction *Inst) {
+ NoAliasScopeDeclInst *Decl = dyn_cast<NoAliasScopeDeclInst>(Inst);
+ if (!Decl)
+ return false;
+
+ assert(Decl->use_empty() &&
+ "llvm.experimental.noalias.scope.decl in use ?");
+ const MDNode *MDSL = Decl->getScopeList();
+ assert(MDSL->getNumOperands() == 1 &&
+ "llvm.experimental.noalias.scope should refer to a single scope");
+ auto &MDOperand = MDSL->getOperand(0);
+ if (auto *MD = dyn_cast<MDNode>(MDOperand))
+ return !UsedAliasScopesAndLists.contains(MD) ||
+ !UsedNoAliasScopesAndLists.contains(MD);
+
+ // Not an MDNode ? throw away.
+ return true;
+ }
+};
+
/// Populate the IC worklist from a function, by walking it in depth-first
/// order and adding all reachable code to the worklist.
///
@@ -3833,7 +3833,7 @@ static bool prepareICWorklistFromFunction(Function &F, const DataLayout &DL,
SmallVector<Instruction*, 128> InstrsForInstCombineWorklist;
DenseMap<Constant *, Constant *> FoldedConstants;
- AliasScopeTracker SeenAliasScopes;
+ AliasScopeTracker SeenAliasScopes;
do {
BasicBlock *BB = Worklist.pop_back_val();
@@ -3878,13 +3878,13 @@ static bool prepareICWorklistFromFunction(Function &F, const DataLayout &DL,
}
}
- // Skip processing debug and pseudo intrinsics in InstCombine. Processing
- // these call instructions consumes non-trivial amount of time and
- // provides no value for the optimization.
- if (!Inst->isDebugOrPseudoInst()) {
+ // Skip processing debug and pseudo intrinsics in InstCombine. Processing
+ // these call instructions consumes non-trivial amount of time and
+ // provides no value for the optimization.
+ if (!Inst->isDebugOrPseudoInst()) {
InstrsForInstCombineWorklist.push_back(Inst);
- SeenAliasScopes.analyse(Inst);
- }
+ SeenAliasScopes.analyse(Inst);
+ }
}
// Recursively visit successors. If this is a branch or switch on a
@@ -3904,7 +3904,7 @@ static bool prepareICWorklistFromFunction(Function &F, const DataLayout &DL,
}
}
- append_range(Worklist, successors(TI));
+ append_range(Worklist, successors(TI));
} while (!Worklist.empty());
// Remove instructions inside unreachable blocks. This prevents the
@@ -3914,12 +3914,12 @@ static bool prepareICWorklistFromFunction(Function &F, const DataLayout &DL,
if (Visited.count(&BB))
continue;
- unsigned NumDeadInstInBB;
- unsigned NumDeadDbgInstInBB;
- std::tie(NumDeadInstInBB, NumDeadDbgInstInBB) =
- removeAllNonTerminatorAndEHPadInstructions(&BB);
-
- MadeIRChange |= NumDeadInstInBB + NumDeadDbgInstInBB > 0;
+ unsigned NumDeadInstInBB;
+ unsigned NumDeadDbgInstInBB;
+ std::tie(NumDeadInstInBB, NumDeadDbgInstInBB) =
+ removeAllNonTerminatorAndEHPadInstructions(&BB);
+
+ MadeIRChange |= NumDeadInstInBB + NumDeadDbgInstInBB > 0;
NumDeadInst += NumDeadInstInBB;
}
@@ -3932,8 +3932,8 @@ static bool prepareICWorklistFromFunction(Function &F, const DataLayout &DL,
for (Instruction *Inst : reverse(InstrsForInstCombineWorklist)) {
// DCE instruction if trivially dead. As we iterate in reverse program
// order here, we will clean up whole chains of dead instructions.
- if (isInstructionTriviallyDead(Inst, TLI) ||
- SeenAliasScopes.isNoAliasScopeDeclDead(Inst)) {
+ if (isInstructionTriviallyDead(Inst, TLI) ||
+ SeenAliasScopes.isNoAliasScopeDeclDead(Inst)) {
++NumDeadInst;
LLVM_DEBUG(dbgs() << "IC: DCE: " << *Inst << '\n');
salvageDebugInfo(*Inst);
@@ -3950,8 +3950,8 @@ static bool prepareICWorklistFromFunction(Function &F, const DataLayout &DL,
static bool combineInstructionsOverFunction(
Function &F, InstCombineWorklist &Worklist, AliasAnalysis *AA,
- AssumptionCache &AC, TargetLibraryInfo &TLI, TargetTransformInfo &TTI,
- DominatorTree &DT, OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI,
+ AssumptionCache &AC, TargetLibraryInfo &TLI, TargetTransformInfo &TTI,
+ DominatorTree &DT, OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI,
ProfileSummaryInfo *PSI, unsigned MaxIterations, LoopInfo *LI) {
auto &DL = F.getParent()->getDataLayout();
MaxIterations = std::min(MaxIterations, LimitMaxIterations.getValue());
@@ -3975,7 +3975,7 @@ static bool combineInstructionsOverFunction(
// Iterate while there is work to do.
unsigned Iteration = 0;
while (true) {
- ++NumWorklistIterations;
+ ++NumWorklistIterations;
++Iteration;
if (Iteration > InfiniteLoopDetectionThreshold) {
@@ -3996,8 +3996,8 @@ static bool combineInstructionsOverFunction(
MadeIRChange |= prepareICWorklistFromFunction(F, DL, &TLI, Worklist);
- InstCombinerImpl IC(Worklist, Builder, F.hasMinSize(), AA, AC, TLI, TTI, DT,
- ORE, BFI, PSI, DL, LI);
+ InstCombinerImpl IC(Worklist, Builder, F.hasMinSize(), AA, AC, TLI, TTI, DT,
+ ORE, BFI, PSI, DL, LI);
IC.MaxArraySizeForCombine = MaxArraySize;
if (!IC.run())
@@ -4020,7 +4020,7 @@ PreservedAnalyses InstCombinePass::run(Function &F,
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
- auto &TTI = AM.getResult<TargetIRAnalysis>(F);
+ auto &TTI = AM.getResult<TargetIRAnalysis>(F);
auto *LI = AM.getCachedResult<LoopAnalysis>(F);
@@ -4031,8 +4031,8 @@ PreservedAnalyses InstCombinePass::run(Function &F,
auto *BFI = (PSI && PSI->hasProfileSummary()) ?
&AM.getResult<BlockFrequencyAnalysis>(F) : nullptr;
- if (!combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, TTI, DT, ORE,
- BFI, PSI, MaxIterations, LI))
+ if (!combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, TTI, DT, ORE,
+ BFI, PSI, MaxIterations, LI))
// No changes, all analyses are preserved.
return PreservedAnalyses::all();
@@ -4050,7 +4050,7 @@ void InstructionCombiningPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<AAResultsWrapperPass>();
AU.addRequired<AssumptionCacheTracker>();
AU.addRequired<TargetLibraryInfoWrapperPass>();
- AU.addRequired<TargetTransformInfoWrapperPass>();
+ AU.addRequired<TargetTransformInfoWrapperPass>();
AU.addRequired<DominatorTreeWrapperPass>();
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
AU.addPreserved<DominatorTreeWrapperPass>();
@@ -4069,7 +4069,7 @@ bool InstructionCombiningPass::runOnFunction(Function &F) {
auto AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
- auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
+ auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
@@ -4083,8 +4083,8 @@ bool InstructionCombiningPass::runOnFunction(Function &F) {
&getAnalysis<LazyBlockFrequencyInfoPass>().getBFI() :
nullptr;
- return combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, TTI, DT, ORE,
- BFI, PSI, MaxIterations, LI);
+ return combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, TTI, DT, ORE,
+ BFI, PSI, MaxIterations, LI);
}
char InstructionCombiningPass::ID = 0;
@@ -4103,7 +4103,7 @@ INITIALIZE_PASS_BEGIN(InstructionCombiningPass, "instcombine",
"Combine redundant instructions", false, false)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
diff --git a/contrib/libs/llvm12/lib/Transforms/InstCombine/ya.make b/contrib/libs/llvm12/lib/Transforms/InstCombine/ya.make
index ac05d9b16a..3f74e68d16 100644
--- a/contrib/libs/llvm12/lib/Transforms/InstCombine/ya.make
+++ b/contrib/libs/llvm12/lib/Transforms/InstCombine/ya.make
@@ -12,12 +12,12 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Transforms/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Transforms/Utils
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/contrib/libs/llvm12/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index bb82bf2337..f4e471706d 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -105,7 +105,7 @@ static const uint64_t kSystemZ_ShadowOffset64 = 1ULL << 52;
static const uint64_t kMIPS32_ShadowOffset32 = 0x0aaa0000;
static const uint64_t kMIPS64_ShadowOffset64 = 1ULL << 37;
static const uint64_t kAArch64_ShadowOffset64 = 1ULL << 36;
-static const uint64_t kRISCV64_ShadowOffset64 = 0x20000000;
+static const uint64_t kRISCV64_ShadowOffset64 = 0x20000000;
static const uint64_t kFreeBSD_ShadowOffset32 = 1ULL << 30;
static const uint64_t kFreeBSD_ShadowOffset64 = 1ULL << 46;
static const uint64_t kNetBSD_ShadowOffset32 = 1ULL << 30;
@@ -130,48 +130,48 @@ static const size_t kMaxStackMallocSize = 1 << 16; // 64K
static const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3;
static const uintptr_t kRetiredStackFrameMagic = 0x45E0360E;
-const char kAsanModuleCtorName[] = "asan.module_ctor";
-const char kAsanModuleDtorName[] = "asan.module_dtor";
+const char kAsanModuleCtorName[] = "asan.module_ctor";
+const char kAsanModuleDtorName[] = "asan.module_dtor";
static const uint64_t kAsanCtorAndDtorPriority = 1;
// On Emscripten, the system needs more than one priorities for constructors.
static const uint64_t kAsanEmscriptenCtorAndDtorPriority = 50;
-const char kAsanReportErrorTemplate[] = "__asan_report_";
-const char kAsanRegisterGlobalsName[] = "__asan_register_globals";
-const char kAsanUnregisterGlobalsName[] = "__asan_unregister_globals";
-const char kAsanRegisterImageGlobalsName[] = "__asan_register_image_globals";
-const char kAsanUnregisterImageGlobalsName[] =
- "__asan_unregister_image_globals";
-const char kAsanRegisterElfGlobalsName[] = "__asan_register_elf_globals";
-const char kAsanUnregisterElfGlobalsName[] = "__asan_unregister_elf_globals";
-const char kAsanPoisonGlobalsName[] = "__asan_before_dynamic_init";
-const char kAsanUnpoisonGlobalsName[] = "__asan_after_dynamic_init";
-const char kAsanInitName[] = "__asan_init";
-const char kAsanVersionCheckNamePrefix[] = "__asan_version_mismatch_check_v";
-const char kAsanPtrCmp[] = "__sanitizer_ptr_cmp";
-const char kAsanPtrSub[] = "__sanitizer_ptr_sub";
-const char kAsanHandleNoReturnName[] = "__asan_handle_no_return";
+const char kAsanReportErrorTemplate[] = "__asan_report_";
+const char kAsanRegisterGlobalsName[] = "__asan_register_globals";
+const char kAsanUnregisterGlobalsName[] = "__asan_unregister_globals";
+const char kAsanRegisterImageGlobalsName[] = "__asan_register_image_globals";
+const char kAsanUnregisterImageGlobalsName[] =
+ "__asan_unregister_image_globals";
+const char kAsanRegisterElfGlobalsName[] = "__asan_register_elf_globals";
+const char kAsanUnregisterElfGlobalsName[] = "__asan_unregister_elf_globals";
+const char kAsanPoisonGlobalsName[] = "__asan_before_dynamic_init";
+const char kAsanUnpoisonGlobalsName[] = "__asan_after_dynamic_init";
+const char kAsanInitName[] = "__asan_init";
+const char kAsanVersionCheckNamePrefix[] = "__asan_version_mismatch_check_v";
+const char kAsanPtrCmp[] = "__sanitizer_ptr_cmp";
+const char kAsanPtrSub[] = "__sanitizer_ptr_sub";
+const char kAsanHandleNoReturnName[] = "__asan_handle_no_return";
static const int kMaxAsanStackMallocSizeClass = 10;
-const char kAsanStackMallocNameTemplate[] = "__asan_stack_malloc_";
-const char kAsanStackFreeNameTemplate[] = "__asan_stack_free_";
-const char kAsanGenPrefix[] = "___asan_gen_";
-const char kODRGenPrefix[] = "__odr_asan_gen_";
-const char kSanCovGenPrefix[] = "__sancov_gen_";
-const char kAsanSetShadowPrefix[] = "__asan_set_shadow_";
-const char kAsanPoisonStackMemoryName[] = "__asan_poison_stack_memory";
-const char kAsanUnpoisonStackMemoryName[] = "__asan_unpoison_stack_memory";
+const char kAsanStackMallocNameTemplate[] = "__asan_stack_malloc_";
+const char kAsanStackFreeNameTemplate[] = "__asan_stack_free_";
+const char kAsanGenPrefix[] = "___asan_gen_";
+const char kODRGenPrefix[] = "__odr_asan_gen_";
+const char kSanCovGenPrefix[] = "__sancov_gen_";
+const char kAsanSetShadowPrefix[] = "__asan_set_shadow_";
+const char kAsanPoisonStackMemoryName[] = "__asan_poison_stack_memory";
+const char kAsanUnpoisonStackMemoryName[] = "__asan_unpoison_stack_memory";
// ASan version script has __asan_* wildcard. Triple underscore prevents a
// linker (gold) warning about attempting to export a local symbol.
-const char kAsanGlobalsRegisteredFlagName[] = "___asan_globals_registered";
+const char kAsanGlobalsRegisteredFlagName[] = "___asan_globals_registered";
-const char kAsanOptionDetectUseAfterReturn[] =
+const char kAsanOptionDetectUseAfterReturn[] =
"__asan_option_detect_stack_use_after_return";
-const char kAsanShadowMemoryDynamicAddress[] =
+const char kAsanShadowMemoryDynamicAddress[] =
"__asan_shadow_memory_dynamic_address";
-const char kAsanAllocaPoison[] = "__asan_alloca_poison";
-const char kAsanAllocasUnpoison[] = "__asan_allocas_unpoison";
+const char kAsanAllocaPoison[] = "__asan_alloca_poison";
+const char kAsanAllocasUnpoison[] = "__asan_allocas_unpoison";
// Accesses sizes are powers of two: 1, 2, 4, 8, 16.
static const size_t kNumberOfAccessSizes = 5;
@@ -427,7 +427,7 @@ static ShadowMapping getShadowMapping(Triple &TargetTriple, int LongSize,
bool IsKasan) {
bool IsAndroid = TargetTriple.isAndroid();
bool IsIOS = TargetTriple.isiOS() || TargetTriple.isWatchOS();
- bool IsMacOS = TargetTriple.isMacOSX();
+ bool IsMacOS = TargetTriple.isMacOSX();
bool IsFreeBSD = TargetTriple.isOSFreeBSD();
bool IsNetBSD = TargetTriple.isOSNetBSD();
bool IsPS4CPU = TargetTriple.isPS4CPU();
@@ -440,7 +440,7 @@ static ShadowMapping getShadowMapping(Triple &TargetTriple, int LongSize,
bool IsMIPS64 = TargetTriple.isMIPS64();
bool IsArmOrThumb = TargetTriple.isARM() || TargetTriple.isThumb();
bool IsAArch64 = TargetTriple.getArch() == Triple::aarch64;
- bool IsRISCV64 = TargetTriple.getArch() == Triple::riscv64;
+ bool IsRISCV64 = TargetTriple.getArch() == Triple::riscv64;
bool IsWindows = TargetTriple.isOSWindows();
bool IsFuchsia = TargetTriple.isOSFuchsia();
bool IsMyriad = TargetTriple.getVendor() == llvm::Triple::Myriad;
@@ -505,12 +505,12 @@ static ShadowMapping getShadowMapping(Triple &TargetTriple, int LongSize,
Mapping.Offset = kMIPS64_ShadowOffset64;
else if (IsIOS)
Mapping.Offset = kDynamicShadowSentinel;
- else if (IsMacOS && IsAArch64)
- Mapping.Offset = kDynamicShadowSentinel;
+ else if (IsMacOS && IsAArch64)
+ Mapping.Offset = kDynamicShadowSentinel;
else if (IsAArch64)
Mapping.Offset = kAArch64_ShadowOffset64;
- else if (IsRISCV64)
- Mapping.Offset = kRISCV64_ShadowOffset64;
+ else if (IsRISCV64)
+ Mapping.Offset = kRISCV64_ShadowOffset64;
else
Mapping.Offset = kDefaultShadowOffset64;
}
@@ -529,7 +529,7 @@ static ShadowMapping getShadowMapping(Triple &TargetTriple, int LongSize,
// we could OR the constant in a single instruction, but it's more
// efficient to load it once and use indexed addressing.
Mapping.OrShadowOffset = !IsAArch64 && !IsPPC64 && !IsSystemZ && !IsPS4CPU &&
- !IsRISCV64 &&
+ !IsRISCV64 &&
!(Mapping.Offset & (Mapping.Offset - 1)) &&
Mapping.Offset != kDynamicShadowSentinel;
bool IsAndroidWithIfuncSupport =
@@ -961,14 +961,14 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {
void createDynamicAllocasInitStorage();
// ----------------------- Visitors.
- /// Collect all Ret instructions, or the musttail call instruction if it
- /// precedes the return instruction.
- void visitReturnInst(ReturnInst &RI) {
- if (CallInst *CI = RI.getParent()->getTerminatingMustTailCall())
- RetVec.push_back(CI);
- else
- RetVec.push_back(&RI);
- }
+ /// Collect all Ret instructions, or the musttail call instruction if it
+ /// precedes the return instruction.
+ void visitReturnInst(ReturnInst &RI) {
+ if (CallInst *CI = RI.getParent()->getTerminatingMustTailCall())
+ RetVec.push_back(CI);
+ else
+ RetVec.push_back(&RI);
+ }
/// Collect all Resume instructions.
void visitResumeInst(ResumeInst &RI) { RetVec.push_back(&RI); }
@@ -1002,10 +1002,10 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {
// Unpoison dynamic allocas redzones.
void unpoisonDynamicAllocas() {
- for (Instruction *Ret : RetVec)
+ for (Instruction *Ret : RetVec)
unpoisonDynamicAllocasBeforeInst(Ret, DynamicAllocaLayout);
- for (Instruction *StackRestoreInst : StackRestoreVec)
+ for (Instruction *StackRestoreInst : StackRestoreVec)
unpoisonDynamicAllocasBeforeInst(StackRestoreInst,
StackRestoreInst->getOperand(0));
}
@@ -1064,9 +1064,9 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {
!ConstantInt::isValueValidForType(IntptrTy, SizeValue))
return;
// Find alloca instruction that corresponds to llvm.lifetime argument.
- // Currently we can only handle lifetime markers pointing to the
- // beginning of the alloca.
- AllocaInst *AI = findAllocaForValue(II.getArgOperand(1), true);
+ // Currently we can only handle lifetime markers pointing to the
+ // beginning of the alloca.
+ AllocaInst *AI = findAllocaForValue(II.getArgOperand(1), true);
if (!AI) {
HasUntracedLifetimeIntrinsic = true;
return;
@@ -1561,7 +1561,7 @@ void AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
if (ClOpt && ClOptGlobals) {
// If initialization order checking is disabled, a simple access to a
// dynamically initialized global is always valid.
- GlobalVariable *G = dyn_cast<GlobalVariable>(getUnderlyingObject(Addr));
+ GlobalVariable *G = dyn_cast<GlobalVariable>(getUnderlyingObject(Addr));
if (G && (!ClInitializers || GlobalIsLinkerInitialized(G)) &&
isSafeAccess(ObjSizeVis, Addr, O.TypeSize)) {
NumOptimizedAccessesToGlobalVar++;
@@ -1571,7 +1571,7 @@ void AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
if (ClOpt && ClOptStack) {
// A direct inbounds access to a stack variable is always valid.
- if (isa<AllocaInst>(getUnderlyingObject(Addr)) &&
+ if (isa<AllocaInst>(getUnderlyingObject(Addr)) &&
isSafeAccess(ObjSizeVis, Addr, O.TypeSize)) {
NumOptimizedAccessesToStackVar++;
return;
@@ -1873,14 +1873,14 @@ bool ModuleAddressSanitizer::shouldInstrumentGlobal(GlobalVariable *G) const {
return false;
}
- // Do not instrument user-defined sections (with names resembling
- // valid C identifiers)
- if (TargetTriple.isOSBinFormatELF()) {
- if (llvm::all_of(Section,
- [](char c) { return llvm::isAlnum(c) || c == '_'; }))
- return false;
- }
-
+ // Do not instrument user-defined sections (with names resembling
+ // valid C identifiers)
+ if (TargetTriple.isOSBinFormatELF()) {
+ if (llvm::all_of(Section,
+ [](char c) { return llvm::isAlnum(c) || c == '_'; }))
+ return false;
+ }
+
// On COFF, if the section name contains '$', it is highly likely that the
// user is using section sorting to create an array of globals similar to
// the way initialization callbacks are registered in .init_array and
@@ -1965,10 +1965,10 @@ StringRef ModuleAddressSanitizer::getGlobalMetadataSection() const {
case Triple::ELF: return "asan_globals";
case Triple::MachO: return "__DATA,__asan_globals,regular";
case Triple::Wasm:
- case Triple::GOFF:
+ case Triple::GOFF:
case Triple::XCOFF:
report_fatal_error(
- "ModuleAddressSanitizer not implemented for object file format");
+ "ModuleAddressSanitizer not implemented for object file format");
case Triple::UnknownObjectFormat:
break;
}
@@ -2119,8 +2119,8 @@ void ModuleAddressSanitizer::InstrumentGlobalsELF(
// Update llvm.compiler.used, adding the new metadata globals. This is
// needed so that during LTO these variables stay alive.
- if (!MetadataGlobals.empty())
- appendToCompilerUsed(M, MetadataGlobals);
+ if (!MetadataGlobals.empty())
+ appendToCompilerUsed(M, MetadataGlobals);
// RegisteredFlag serves two purposes. First, we can pass it to dladdr()
// to look up the loaded image that contains it. Second, we can store in it
@@ -2133,15 +2133,15 @@ void ModuleAddressSanitizer::InstrumentGlobalsELF(
ConstantInt::get(IntptrTy, 0), kAsanGlobalsRegisteredFlagName);
RegisteredFlag->setVisibility(GlobalVariable::HiddenVisibility);
- // Create start and stop symbols.
- GlobalVariable *StartELFMetadata = new GlobalVariable(
- M, IntptrTy, false, GlobalVariable::ExternalWeakLinkage, nullptr,
- "__start_" + getGlobalMetadataSection());
- StartELFMetadata->setVisibility(GlobalVariable::HiddenVisibility);
- GlobalVariable *StopELFMetadata = new GlobalVariable(
- M, IntptrTy, false, GlobalVariable::ExternalWeakLinkage, nullptr,
- "__stop_" + getGlobalMetadataSection());
- StopELFMetadata->setVisibility(GlobalVariable::HiddenVisibility);
+ // Create start and stop symbols.
+ GlobalVariable *StartELFMetadata = new GlobalVariable(
+ M, IntptrTy, false, GlobalVariable::ExternalWeakLinkage, nullptr,
+ "__start_" + getGlobalMetadataSection());
+ StartELFMetadata->setVisibility(GlobalVariable::HiddenVisibility);
+ GlobalVariable *StopELFMetadata = new GlobalVariable(
+ M, IntptrTy, false, GlobalVariable::ExternalWeakLinkage, nullptr,
+ "__stop_" + getGlobalMetadataSection());
+ StopELFMetadata->setVisibility(GlobalVariable::HiddenVisibility);
// Create a call to register the globals with the runtime.
IRB.CreateCall(AsanRegisterElfGlobals,
@@ -2345,9 +2345,9 @@ bool ModuleAddressSanitizer::InstrumentGlobals(IRBuilder<> &IRB, Module &M,
NewGlobal->setSection("__TEXT,__asan_cstring,regular");
}
- // Transfer the debug info and type metadata. The payload starts at offset
- // zero so we can copy the metadata over as is.
- NewGlobal->copyMetadata(G, 0);
+ // Transfer the debug info and type metadata. The payload starts at offset
+ // zero so we can copy the metadata over as is.
+ NewGlobal->copyMetadata(G, 0);
Value *Indices2[2];
Indices2[0] = IRB.getInt32(0);
@@ -3105,8 +3105,8 @@ void FunctionStackPoisoner::processStaticAllocas() {
int StackMallocIdx = -1;
DebugLoc EntryDebugLocation;
if (auto SP = F.getSubprogram())
- EntryDebugLocation =
- DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
+ EntryDebugLocation =
+ DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
Instruction *InsBefore = AllocaVec[0];
IRBuilder<> IRB(InsBefore);
@@ -3314,7 +3314,7 @@ void FunctionStackPoisoner::processStaticAllocas() {
SmallVector<uint8_t, 64> ShadowAfterReturn;
// (Un)poison the stack before all ret instructions.
- for (Instruction *Ret : RetVec) {
+ for (Instruction *Ret : RetVec) {
IRBuilder<> IRBRet(Ret);
// Mark the current frame as retired.
IRBRet.CreateStore(ConstantInt::get(IntptrTy, kRetiredStackFrameMagic),
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/CFGMST.h b/contrib/libs/llvm12/lib/Transforms/Instrumentation/CFGMST.h
index 77f525c020..6580b6d7d7 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/CFGMST.h
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/CFGMST.h
@@ -103,7 +103,7 @@ public:
const BasicBlock *Entry = &(F.getEntryBlock());
uint64_t EntryWeight = (BFI != nullptr ? BFI->getEntryFreq() : 2);
// If we want to instrument the entry count, lower the weight to 0.
- if (InstrumentFuncEntry)
+ if (InstrumentFuncEntry)
EntryWeight = 0;
Edge *EntryIncoming = nullptr, *EntryOutgoing = nullptr,
*ExitOutgoing = nullptr, *ExitIncoming = nullptr;
@@ -278,19 +278,19 @@ public:
BranchProbabilityInfo *BPI;
BlockFrequencyInfo *BFI;
- // If function entry will be always instrumented.
- bool InstrumentFuncEntry;
-
+ // If function entry will be always instrumented.
+ bool InstrumentFuncEntry;
+
public:
- CFGMST(Function &Func, bool InstrumentFuncEntry_,
- BranchProbabilityInfo *BPI_ = nullptr,
+ CFGMST(Function &Func, bool InstrumentFuncEntry_,
+ BranchProbabilityInfo *BPI_ = nullptr,
BlockFrequencyInfo *BFI_ = nullptr)
- : F(Func), BPI(BPI_), BFI(BFI_),
- InstrumentFuncEntry(InstrumentFuncEntry_) {
+ : F(Func), BPI(BPI_), BFI(BFI_),
+ InstrumentFuncEntry(InstrumentFuncEntry_) {
buildEdges();
sortEdgesByWeight();
computeMinimumSpanningTree();
- if (AllEdges.size() > 1 && InstrumentFuncEntry)
+ if (AllEdges.size() > 1 && InstrumentFuncEntry)
std::iter_swap(std::move(AllEdges.begin()),
std::move(AllEdges.begin() + AllEdges.size() - 1));
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/CGProfile.cpp b/contrib/libs/llvm12/lib/Transforms/Instrumentation/CGProfile.cpp
index 80ad16c631..9acd82c005 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/CGProfile.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/CGProfile.cpp
@@ -53,8 +53,8 @@ static bool runCGProfilePass(
InstrProfSymtab Symtab;
auto UpdateCounts = [&](TargetTransformInfo &TTI, Function *F,
Function *CalledF, uint64_t NewCount) {
- if (!CalledF || !TTI.isLoweredToCall(CalledF) ||
- CalledF->hasDLLImportStorageClass())
+ if (!CalledF || !TTI.isLoweredToCall(CalledF) ||
+ CalledF->hasDLLImportStorageClass())
return;
uint64_t &Count = Counts[std::make_pair(F, CalledF)];
Count = SaturatingAdd(Count, NewCount);
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/ControlHeightReduction.cpp b/contrib/libs/llvm12/lib/Transforms/Instrumentation/ControlHeightReduction.cpp
index 13e82eee95..927c34180d 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/ControlHeightReduction.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/ControlHeightReduction.cpp
@@ -260,9 +260,9 @@ class CHRScope {
if (TailRegionSet.count(Parent))
return false;
- assert(llvm::any_of(
- RegInfos,
- [&Parent](const RegInfo &RI) { return Parent == RI.R; }) &&
+ assert(llvm::any_of(
+ RegInfos,
+ [&Parent](const RegInfo &RI) { return Parent == RI.R; }) &&
"Must be in head");
return true;
});
@@ -731,7 +731,7 @@ static Instruction* getBranchInsertPoint(RegInfo &RI) {
}
}
for (Instruction &I : *EntryBB) {
- if (EntryBlockSelectSet.contains(&I)) {
+ if (EntryBlockSelectSet.contains(&I)) {
assert(&I == HoistPoint &&
"HoistPoint must be the first one in Selects");
break;
@@ -949,9 +949,9 @@ void CHR::checkScopeHoistable(CHRScope *Scope) {
<< "Dropped select due to unhoistable branch";
});
}
- llvm::erase_if(Selects, [EntryBB](SelectInst *SI) {
- return SI->getParent() == EntryBB;
- });
+ llvm::erase_if(Selects, [EntryBB](SelectInst *SI) {
+ return SI->getParent() == EntryBB;
+ });
Unhoistables.clear();
InsertPoint = Branch;
}
@@ -1247,7 +1247,7 @@ SmallVector<CHRScope *, 8> CHR::splitScope(
SmallVector<CHRScope *, 8> SubSplits = splitScope(
Sub, Split, &SplitConditionValues, SplitInsertPoint, Output,
SplitUnhoistables);
- llvm::append_range(NewSubs, SubSplits);
+ llvm::append_range(NewSubs, SubSplits);
}
Split->Subs = NewSubs;
}
@@ -1304,17 +1304,17 @@ void CHR::classifyBiasedScopes(CHRScope *Scope, CHRScope *OutermostScope) {
for (RegInfo &RI : Scope->RegInfos) {
if (RI.HasBranch) {
Region *R = RI.R;
- if (TrueBiasedRegionsGlobal.contains(R))
+ if (TrueBiasedRegionsGlobal.contains(R))
OutermostScope->TrueBiasedRegions.insert(R);
- else if (FalseBiasedRegionsGlobal.contains(R))
+ else if (FalseBiasedRegionsGlobal.contains(R))
OutermostScope->FalseBiasedRegions.insert(R);
else
llvm_unreachable("Must be biased");
}
for (SelectInst *SI : RI.Selects) {
- if (TrueBiasedSelectsGlobal.contains(SI))
+ if (TrueBiasedSelectsGlobal.contains(SI))
OutermostScope->TrueBiasedSelects.insert(SI);
- else if (FalseBiasedSelectsGlobal.contains(SI))
+ else if (FalseBiasedSelectsGlobal.contains(SI))
OutermostScope->FalseBiasedSelects.insert(SI);
else
llvm_unreachable("Must be biased");
@@ -1397,8 +1397,8 @@ void CHR::setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope) {
DenseSet<Instruction *> HoistStops;
bool IsHoisted = false;
if (RI.HasBranch) {
- assert((OutermostScope->TrueBiasedRegions.contains(R) ||
- OutermostScope->FalseBiasedRegions.contains(R)) &&
+ assert((OutermostScope->TrueBiasedRegions.contains(R) ||
+ OutermostScope->FalseBiasedRegions.contains(R)) &&
"Must be truthy or falsy");
auto *BI = cast<BranchInst>(R->getEntry()->getTerminator());
// Note checkHoistValue fills in HoistStops.
@@ -1410,8 +1410,8 @@ void CHR::setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope) {
IsHoisted = true;
}
for (SelectInst *SI : RI.Selects) {
- assert((OutermostScope->TrueBiasedSelects.contains(SI) ||
- OutermostScope->FalseBiasedSelects.contains(SI)) &&
+ assert((OutermostScope->TrueBiasedSelects.contains(SI) ||
+ OutermostScope->FalseBiasedSelects.contains(SI)) &&
"Must be true or false biased");
// Note checkHoistValue fills in HoistStops.
DenseMap<Instruction *, bool> Visited;
@@ -1607,7 +1607,7 @@ static void insertTrivialPHIs(CHRScope *Scope,
// Insert a trivial phi for I (phi [&I, P0], [&I, P1], ...) at
// ExitBlock. Replace I with the new phi in UI unless UI is another
// phi at ExitBlock.
- PHINode *PN = PHINode::Create(I.getType(), pred_size(ExitBlock), "",
+ PHINode *PN = PHINode::Create(I.getType(), pred_size(ExitBlock), "",
&ExitBlock->front());
for (BasicBlock *Pred : predecessors(ExitBlock)) {
PN->addIncoming(&I, Pred);
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/contrib/libs/llvm12/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index 6112174f3c..1b14b8d569 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -46,7 +46,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h"
+#include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/DepthFirstIterator.h"
@@ -79,7 +79,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
@@ -106,18 +106,18 @@
using namespace llvm;
-// This must be consistent with ShadowWidthBits.
-static const Align kShadowTLSAlignment = Align(2);
-
-// The size of TLS variables. These constants must be kept in sync with the ones
-// in dfsan.cpp.
-static const unsigned kArgTLSSize = 800;
-static const unsigned kRetvalTLSSize = 800;
-
+// This must be consistent with ShadowWidthBits.
+static const Align kShadowTLSAlignment = Align(2);
+
+// The size of TLS variables. These constants must be kept in sync with the ones
+// in dfsan.cpp.
+static const unsigned kArgTLSSize = 800;
+static const unsigned kRetvalTLSSize = 800;
+
// External symbol to be used when generating the shadow address for
// architectures with multiple VMAs. Instead of using a constant integer
// the runtime will set the external mask based on the VMA range.
-const char kDFSanExternShadowPtrMask[] = "__dfsan_shadow_ptr_mask";
+const char kDFSanExternShadowPtrMask[] = "__dfsan_shadow_ptr_mask";
// The -dfsan-preserve-alignment flag controls whether this pass assumes that
// alignment requirements provided by the input IR are correct. For example,
@@ -177,8 +177,8 @@ static cl::opt<bool> ClDebugNonzeroLabels(
//
// If this flag is set to true, the user must provide definitions for the
// following callback functions:
-// void __dfsan_load_callback(dfsan_label Label, void* addr);
-// void __dfsan_store_callback(dfsan_label Label, void* addr);
+// void __dfsan_load_callback(dfsan_label Label, void* addr);
+// void __dfsan_store_callback(dfsan_label Label, void* addr);
// void __dfsan_mem_transfer_callback(dfsan_label *Start, size_t Len);
// void __dfsan_cmp_callback(dfsan_label CombinedLabel);
static cl::opt<bool> ClEventCallbacks(
@@ -186,21 +186,21 @@ static cl::opt<bool> ClEventCallbacks(
cl::desc("Insert calls to __dfsan_*_callback functions on data events."),
cl::Hidden, cl::init(false));
-// Use a distinct bit for each base label, enabling faster unions with less
-// instrumentation. Limits the max number of base labels to 16.
-static cl::opt<bool> ClFast16Labels(
- "dfsan-fast-16-labels",
- cl::desc("Use more efficient instrumentation, limiting the number of "
- "labels to 16."),
- cl::Hidden, cl::init(false));
-
-// Controls whether the pass tracks the control flow of select instructions.
-static cl::opt<bool> ClTrackSelectControlFlow(
- "dfsan-track-select-control-flow",
- cl::desc("Propagate labels from condition values of select instructions "
- "to results."),
- cl::Hidden, cl::init(true));
-
+// Use a distinct bit for each base label, enabling faster unions with less
+// instrumentation. Limits the max number of base labels to 16.
+static cl::opt<bool> ClFast16Labels(
+ "dfsan-fast-16-labels",
+ cl::desc("Use more efficient instrumentation, limiting the number of "
+ "labels to 16."),
+ cl::Hidden, cl::init(false));
+
+// Controls whether the pass tracks the control flow of select instructions.
+static cl::opt<bool> ClTrackSelectControlFlow(
+ "dfsan-track-select-control-flow",
+ cl::desc("Propagate labels from condition values of select instructions "
+ "to results."),
+ cl::Hidden, cl::init(true));
+
static StringRef GetGlobalTypeString(const GlobalValue &G) {
// Types of GlobalVariables are always pointer types.
Type *GType = G.getValueType();
@@ -317,7 +317,7 @@ AttributeList TransformFunctionAttributes(
llvm::makeArrayRef(ArgumentAttributes));
}
-class DataFlowSanitizer {
+class DataFlowSanitizer {
friend struct DFSanFunction;
friend class DFSanVisitor;
@@ -361,12 +361,12 @@ class DataFlowSanitizer {
Module *Mod;
LLVMContext *Ctx;
- Type *Int8Ptr;
- /// The shadow type for all primitive types and vector types.
- IntegerType *PrimitiveShadowTy;
- PointerType *PrimitiveShadowPtrTy;
+ Type *Int8Ptr;
+ /// The shadow type for all primitive types and vector types.
+ IntegerType *PrimitiveShadowTy;
+ PointerType *PrimitiveShadowPtrTy;
IntegerType *IntptrTy;
- ConstantInt *ZeroPrimitiveShadow;
+ ConstantInt *ZeroPrimitiveShadow;
ConstantInt *ShadowPtrMask;
ConstantInt *ShadowPtrMul;
Constant *ArgTLS;
@@ -378,13 +378,13 @@ class DataFlowSanitizer {
FunctionType *DFSanSetLabelFnTy;
FunctionType *DFSanNonzeroLabelFnTy;
FunctionType *DFSanVarargWrapperFnTy;
- FunctionType *DFSanCmpCallbackFnTy;
- FunctionType *DFSanLoadStoreCallbackFnTy;
+ FunctionType *DFSanCmpCallbackFnTy;
+ FunctionType *DFSanLoadStoreCallbackFnTy;
FunctionType *DFSanMemTransferCallbackFnTy;
FunctionCallee DFSanUnionFn;
FunctionCallee DFSanCheckedUnionFn;
FunctionCallee DFSanUnionLoadFn;
- FunctionCallee DFSanUnionLoadFast16LabelsFn;
+ FunctionCallee DFSanUnionLoadFast16LabelsFn;
FunctionCallee DFSanUnimplementedFn;
FunctionCallee DFSanSetLabelFn;
FunctionCallee DFSanNonzeroLabelFn;
@@ -415,43 +415,43 @@ class DataFlowSanitizer {
void initializeCallbackFunctions(Module &M);
void initializeRuntimeFunctions(Module &M);
- bool init(Module &M);
-
- /// Returns whether the pass tracks labels for struct fields and array
- /// indices. Support only fast16 mode in TLS ABI mode.
- bool shouldTrackFieldsAndIndices();
-
- /// Returns a zero constant with the shadow type of OrigTy.
- ///
- /// getZeroShadow({T1,T2,...}) = {getZeroShadow(T1),getZeroShadow(T2,...}
- /// getZeroShadow([n x T]) = [n x getZeroShadow(T)]
- /// getZeroShadow(other type) = i16(0)
- ///
- /// Note that a zero shadow is always i16(0) when shouldTrackFieldsAndIndices
- /// returns false.
- Constant *getZeroShadow(Type *OrigTy);
- /// Returns a zero constant with the shadow type of V's type.
- Constant *getZeroShadow(Value *V);
-
- /// Checks if V is a zero shadow.
- bool isZeroShadow(Value *V);
-
- /// Returns the shadow type of OrigTy.
- ///
- /// getShadowTy({T1,T2,...}) = {getShadowTy(T1),getShadowTy(T2),...}
- /// getShadowTy([n x T]) = [n x getShadowTy(T)]
- /// getShadowTy(other type) = i16
- ///
- /// Note that a shadow type is always i16 when shouldTrackFieldsAndIndices
- /// returns false.
- Type *getShadowTy(Type *OrigTy);
- /// Returns the shadow type of of V's type.
- Type *getShadowTy(Value *V);
-
+ bool init(Module &M);
+
+ /// Returns whether the pass tracks labels for struct fields and array
+ /// indices. Support only fast16 mode in TLS ABI mode.
+ bool shouldTrackFieldsAndIndices();
+
+ /// Returns a zero constant with the shadow type of OrigTy.
+ ///
+ /// getZeroShadow({T1,T2,...}) = {getZeroShadow(T1),getZeroShadow(T2,...}
+ /// getZeroShadow([n x T]) = [n x getZeroShadow(T)]
+ /// getZeroShadow(other type) = i16(0)
+ ///
+ /// Note that a zero shadow is always i16(0) when shouldTrackFieldsAndIndices
+ /// returns false.
+ Constant *getZeroShadow(Type *OrigTy);
+ /// Returns a zero constant with the shadow type of V's type.
+ Constant *getZeroShadow(Value *V);
+
+ /// Checks if V is a zero shadow.
+ bool isZeroShadow(Value *V);
+
+ /// Returns the shadow type of OrigTy.
+ ///
+ /// getShadowTy({T1,T2,...}) = {getShadowTy(T1),getShadowTy(T2),...}
+ /// getShadowTy([n x T]) = [n x getShadowTy(T)]
+ /// getShadowTy(other type) = i16
+ ///
+ /// Note that a shadow type is always i16 when shouldTrackFieldsAndIndices
+ /// returns false.
+ Type *getShadowTy(Type *OrigTy);
+ /// Returns the shadow type of of V's type.
+ Type *getShadowTy(Value *V);
+
public:
- DataFlowSanitizer(const std::vector<std::string> &ABIListFiles);
+ DataFlowSanitizer(const std::vector<std::string> &ABIListFiles);
- bool runImpl(Module &M);
+ bool runImpl(Module &M);
};
struct DFSanFunction {
@@ -468,17 +468,17 @@ struct DFSanFunction {
std::vector<Value *> NonZeroChecks;
bool AvoidNewBlocks;
- struct CachedShadow {
- BasicBlock *Block; // The block where Shadow is defined.
+ struct CachedShadow {
+ BasicBlock *Block; // The block where Shadow is defined.
Value *Shadow;
};
- /// Maps a value to its latest shadow value in terms of domination tree.
- DenseMap<std::pair<Value *, Value *>, CachedShadow> CachedShadows;
- /// Maps a value to its latest collapsed shadow value it was converted to in
- /// terms of domination tree. When ClDebugNonzeroLabels is on, this cache is
- /// used at a post process where CFG blocks are split. So it does not cache
- /// BasicBlock like CachedShadows, but uses domination between values.
- DenseMap<Value *, Value *> CachedCollapsedShadows;
+ /// Maps a value to its latest shadow value in terms of domination tree.
+ DenseMap<std::pair<Value *, Value *>, CachedShadow> CachedShadows;
+ /// Maps a value to its latest collapsed shadow value it was converted to in
+ /// terms of domination tree. When ClDebugNonzeroLabels is on, this cache is
+ /// used at a post process where CFG blocks are split. So it does not cache
+ /// BasicBlock like CachedShadows, but uses domination between values.
+ DenseMap<Value *, Value *> CachedCollapsedShadows;
DenseMap<Value *, std::set<Value *>> ShadowElements;
DFSanFunction(DataFlowSanitizer &DFS, Function *F, bool IsNativeABI)
@@ -489,56 +489,56 @@ struct DFSanFunction {
AvoidNewBlocks = F->size() > 1000;
}
- /// Computes the shadow address for a given function argument.
- ///
- /// Shadow = ArgTLS+ArgOffset.
- Value *getArgTLS(Type *T, unsigned ArgOffset, IRBuilder<> &IRB);
-
- /// Computes the shadow address for a retval.
- Value *getRetvalTLS(Type *T, IRBuilder<> &IRB);
-
+ /// Computes the shadow address for a given function argument.
+ ///
+ /// Shadow = ArgTLS+ArgOffset.
+ Value *getArgTLS(Type *T, unsigned ArgOffset, IRBuilder<> &IRB);
+
+ /// Computes the shadow address for a retval.
+ Value *getRetvalTLS(Type *T, IRBuilder<> &IRB);
+
Value *getShadow(Value *V);
void setShadow(Instruction *I, Value *Shadow);
- /// Generates IR to compute the union of the two given shadows, inserting it
- /// before Pos. The combined value is with primitive type.
+ /// Generates IR to compute the union of the two given shadows, inserting it
+ /// before Pos. The combined value is with primitive type.
Value *combineShadows(Value *V1, Value *V2, Instruction *Pos);
- /// Combines the shadow values of V1 and V2, then converts the combined value
- /// with primitive type into a shadow value with the original type T.
- Value *combineShadowsThenConvert(Type *T, Value *V1, Value *V2,
- Instruction *Pos);
+ /// Combines the shadow values of V1 and V2, then converts the combined value
+ /// with primitive type into a shadow value with the original type T.
+ Value *combineShadowsThenConvert(Type *T, Value *V1, Value *V2,
+ Instruction *Pos);
Value *combineOperandShadows(Instruction *Inst);
Value *loadShadow(Value *ShadowAddr, uint64_t Size, uint64_t Align,
Instruction *Pos);
- void storePrimitiveShadow(Value *Addr, uint64_t Size, Align Alignment,
- Value *PrimitiveShadow, Instruction *Pos);
- /// Applies PrimitiveShadow to all primitive subtypes of T, returning
- /// the expanded shadow value.
- ///
- /// EFP({T1,T2, ...}, PS) = {EFP(T1,PS),EFP(T2,PS),...}
- /// EFP([n x T], PS) = [n x EFP(T,PS)]
- /// EFP(other types, PS) = PS
- Value *expandFromPrimitiveShadow(Type *T, Value *PrimitiveShadow,
- Instruction *Pos);
- /// Collapses Shadow into a single primitive shadow value, unioning all
- /// primitive shadow values in the process. Returns the final primitive
- /// shadow value.
- ///
- /// CTP({V1,V2, ...}) = UNION(CFP(V1,PS),CFP(V2,PS),...)
- /// CTP([V1,V2,...]) = UNION(CFP(V1,PS),CFP(V2,PS),...)
- /// CTP(other types, PS) = PS
- Value *collapseToPrimitiveShadow(Value *Shadow, Instruction *Pos);
-
-private:
- /// Collapses the shadow with aggregate type into a single primitive shadow
- /// value.
- template <class AggregateType>
- Value *collapseAggregateShadow(AggregateType *AT, Value *Shadow,
- IRBuilder<> &IRB);
-
- Value *collapseToPrimitiveShadow(Value *Shadow, IRBuilder<> &IRB);
-
- /// Returns the shadow value of an argument A.
- Value *getShadowForTLSArgument(Argument *A);
+ void storePrimitiveShadow(Value *Addr, uint64_t Size, Align Alignment,
+ Value *PrimitiveShadow, Instruction *Pos);
+ /// Applies PrimitiveShadow to all primitive subtypes of T, returning
+ /// the expanded shadow value.
+ ///
+ /// EFP({T1,T2, ...}, PS) = {EFP(T1,PS),EFP(T2,PS),...}
+ /// EFP([n x T], PS) = [n x EFP(T,PS)]
+ /// EFP(other types, PS) = PS
+ Value *expandFromPrimitiveShadow(Type *T, Value *PrimitiveShadow,
+ Instruction *Pos);
+ /// Collapses Shadow into a single primitive shadow value, unioning all
+ /// primitive shadow values in the process. Returns the final primitive
+ /// shadow value.
+ ///
+ /// CTP({V1,V2, ...}) = UNION(CFP(V1,PS),CFP(V2,PS),...)
+ /// CTP([V1,V2,...]) = UNION(CFP(V1,PS),CFP(V2,PS),...)
+ /// CTP(other types, PS) = PS
+ Value *collapseToPrimitiveShadow(Value *Shadow, Instruction *Pos);
+
+private:
+ /// Collapses the shadow with aggregate type into a single primitive shadow
+ /// value.
+ template <class AggregateType>
+ Value *collapseAggregateShadow(AggregateType *AT, Value *Shadow,
+ IRBuilder<> &IRB);
+
+ Value *collapseToPrimitiveShadow(Value *Shadow, IRBuilder<> &IRB);
+
+ /// Returns the shadow value of an argument A.
+ Value *getShadowForTLSArgument(Argument *A);
};
class DFSanVisitor : public InstVisitor<DFSanVisitor> {
@@ -579,9 +579,9 @@ public:
} // end anonymous namespace
DataFlowSanitizer::DataFlowSanitizer(
- const std::vector<std::string> &ABIListFiles) {
+ const std::vector<std::string> &ABIListFiles) {
std::vector<std::string> AllABIListFiles(std::move(ABIListFiles));
- llvm::append_range(AllABIListFiles, ClABIListFiles);
+ llvm::append_range(AllABIListFiles, ClABIListFiles);
// FIXME: should we propagate vfs::FileSystem to this constructor?
ABIList.set(
SpecialCaseList::createOrDie(AllABIListFiles, *vfs::getRealFileSystem()));
@@ -589,12 +589,12 @@ DataFlowSanitizer::DataFlowSanitizer(
FunctionType *DataFlowSanitizer::getArgsFunctionType(FunctionType *T) {
SmallVector<Type *, 4> ArgTypes(T->param_begin(), T->param_end());
- ArgTypes.append(T->getNumParams(), PrimitiveShadowTy);
+ ArgTypes.append(T->getNumParams(), PrimitiveShadowTy);
if (T->isVarArg())
- ArgTypes.push_back(PrimitiveShadowPtrTy);
+ ArgTypes.push_back(PrimitiveShadowPtrTy);
Type *RetType = T->getReturnType();
if (!RetType->isVoidTy())
- RetType = StructType::get(RetType, PrimitiveShadowTy);
+ RetType = StructType::get(RetType, PrimitiveShadowTy);
return FunctionType::get(RetType, ArgTypes, T->isVarArg());
}
@@ -603,10 +603,10 @@ FunctionType *DataFlowSanitizer::getTrampolineFunctionType(FunctionType *T) {
SmallVector<Type *, 4> ArgTypes;
ArgTypes.push_back(T->getPointerTo());
ArgTypes.append(T->param_begin(), T->param_end());
- ArgTypes.append(T->getNumParams(), PrimitiveShadowTy);
+ ArgTypes.append(T->getNumParams(), PrimitiveShadowTy);
Type *RetType = T->getReturnType();
if (!RetType->isVoidTy())
- ArgTypes.push_back(PrimitiveShadowPtrTy);
+ ArgTypes.push_back(PrimitiveShadowPtrTy);
return FunctionType::get(T->getReturnType(), ArgTypes, false);
}
@@ -632,174 +632,174 @@ TransformedFunction DataFlowSanitizer::getCustomFunctionType(FunctionType *T) {
}
}
for (unsigned i = 0, e = T->getNumParams(); i != e; ++i)
- ArgTypes.push_back(PrimitiveShadowTy);
+ ArgTypes.push_back(PrimitiveShadowTy);
if (T->isVarArg())
- ArgTypes.push_back(PrimitiveShadowPtrTy);
+ ArgTypes.push_back(PrimitiveShadowPtrTy);
Type *RetType = T->getReturnType();
if (!RetType->isVoidTy())
- ArgTypes.push_back(PrimitiveShadowPtrTy);
+ ArgTypes.push_back(PrimitiveShadowPtrTy);
return TransformedFunction(
T, FunctionType::get(T->getReturnType(), ArgTypes, T->isVarArg()),
ArgumentIndexMapping);
}
-bool DataFlowSanitizer::isZeroShadow(Value *V) {
- if (!shouldTrackFieldsAndIndices())
- return ZeroPrimitiveShadow == V;
-
- Type *T = V->getType();
- if (!isa<ArrayType>(T) && !isa<StructType>(T)) {
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
- return CI->isZero();
- return false;
- }
-
- return isa<ConstantAggregateZero>(V);
-}
-
-bool DataFlowSanitizer::shouldTrackFieldsAndIndices() {
- return getInstrumentedABI() == DataFlowSanitizer::IA_TLS && ClFast16Labels;
-}
-
-Constant *DataFlowSanitizer::getZeroShadow(Type *OrigTy) {
- if (!shouldTrackFieldsAndIndices())
- return ZeroPrimitiveShadow;
-
- if (!isa<ArrayType>(OrigTy) && !isa<StructType>(OrigTy))
- return ZeroPrimitiveShadow;
- Type *ShadowTy = getShadowTy(OrigTy);
- return ConstantAggregateZero::get(ShadowTy);
-}
-
-Constant *DataFlowSanitizer::getZeroShadow(Value *V) {
- return getZeroShadow(V->getType());
-}
-
-static Value *expandFromPrimitiveShadowRecursive(
- Value *Shadow, SmallVector<unsigned, 4> &Indices, Type *SubShadowTy,
- Value *PrimitiveShadow, IRBuilder<> &IRB) {
- if (!isa<ArrayType>(SubShadowTy) && !isa<StructType>(SubShadowTy))
- return IRB.CreateInsertValue(Shadow, PrimitiveShadow, Indices);
-
- if (ArrayType *AT = dyn_cast<ArrayType>(SubShadowTy)) {
- for (unsigned Idx = 0; Idx < AT->getNumElements(); Idx++) {
- Indices.push_back(Idx);
- Shadow = expandFromPrimitiveShadowRecursive(
- Shadow, Indices, AT->getElementType(), PrimitiveShadow, IRB);
- Indices.pop_back();
- }
- return Shadow;
- }
-
- if (StructType *ST = dyn_cast<StructType>(SubShadowTy)) {
- for (unsigned Idx = 0; Idx < ST->getNumElements(); Idx++) {
- Indices.push_back(Idx);
- Shadow = expandFromPrimitiveShadowRecursive(
- Shadow, Indices, ST->getElementType(Idx), PrimitiveShadow, IRB);
- Indices.pop_back();
- }
- return Shadow;
- }
- llvm_unreachable("Unexpected shadow type");
-}
-
-Value *DFSanFunction::expandFromPrimitiveShadow(Type *T, Value *PrimitiveShadow,
- Instruction *Pos) {
- Type *ShadowTy = DFS.getShadowTy(T);
-
- if (!isa<ArrayType>(ShadowTy) && !isa<StructType>(ShadowTy))
- return PrimitiveShadow;
-
- if (DFS.isZeroShadow(PrimitiveShadow))
- return DFS.getZeroShadow(ShadowTy);
-
- IRBuilder<> IRB(Pos);
- SmallVector<unsigned, 4> Indices;
- Value *Shadow = UndefValue::get(ShadowTy);
- Shadow = expandFromPrimitiveShadowRecursive(Shadow, Indices, ShadowTy,
- PrimitiveShadow, IRB);
-
- // Caches the primitive shadow value that built the shadow value.
- CachedCollapsedShadows[Shadow] = PrimitiveShadow;
- return Shadow;
-}
-
-template <class AggregateType>
-Value *DFSanFunction::collapseAggregateShadow(AggregateType *AT, Value *Shadow,
- IRBuilder<> &IRB) {
- if (!AT->getNumElements())
- return DFS.ZeroPrimitiveShadow;
-
- Value *FirstItem = IRB.CreateExtractValue(Shadow, 0);
- Value *Aggregator = collapseToPrimitiveShadow(FirstItem, IRB);
-
- for (unsigned Idx = 1; Idx < AT->getNumElements(); Idx++) {
- Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
- Value *ShadowInner = collapseToPrimitiveShadow(ShadowItem, IRB);
- Aggregator = IRB.CreateOr(Aggregator, ShadowInner);
- }
- return Aggregator;
-}
-
-Value *DFSanFunction::collapseToPrimitiveShadow(Value *Shadow,
- IRBuilder<> &IRB) {
- Type *ShadowTy = Shadow->getType();
- if (!isa<ArrayType>(ShadowTy) && !isa<StructType>(ShadowTy))
- return Shadow;
- if (ArrayType *AT = dyn_cast<ArrayType>(ShadowTy))
- return collapseAggregateShadow<>(AT, Shadow, IRB);
- if (StructType *ST = dyn_cast<StructType>(ShadowTy))
- return collapseAggregateShadow<>(ST, Shadow, IRB);
- llvm_unreachable("Unexpected shadow type");
-}
-
-Value *DFSanFunction::collapseToPrimitiveShadow(Value *Shadow,
- Instruction *Pos) {
- Type *ShadowTy = Shadow->getType();
- if (!isa<ArrayType>(ShadowTy) && !isa<StructType>(ShadowTy))
- return Shadow;
-
- assert(DFS.shouldTrackFieldsAndIndices());
-
- // Checks if the cached collapsed shadow value dominates Pos.
- Value *&CS = CachedCollapsedShadows[Shadow];
- if (CS && DT.dominates(CS, Pos))
- return CS;
-
- IRBuilder<> IRB(Pos);
- Value *PrimitiveShadow = collapseToPrimitiveShadow(Shadow, IRB);
- // Caches the converted primitive shadow value.
- CS = PrimitiveShadow;
- return PrimitiveShadow;
-}
-
-Type *DataFlowSanitizer::getShadowTy(Type *OrigTy) {
- if (!shouldTrackFieldsAndIndices())
- return PrimitiveShadowTy;
-
- if (!OrigTy->isSized())
- return PrimitiveShadowTy;
- if (isa<IntegerType>(OrigTy))
- return PrimitiveShadowTy;
- if (isa<VectorType>(OrigTy))
- return PrimitiveShadowTy;
- if (ArrayType *AT = dyn_cast<ArrayType>(OrigTy))
- return ArrayType::get(getShadowTy(AT->getElementType()),
- AT->getNumElements());
- if (StructType *ST = dyn_cast<StructType>(OrigTy)) {
- SmallVector<Type *, 4> Elements;
- for (unsigned I = 0, N = ST->getNumElements(); I < N; ++I)
- Elements.push_back(getShadowTy(ST->getElementType(I)));
- return StructType::get(*Ctx, Elements);
- }
- return PrimitiveShadowTy;
-}
-
-Type *DataFlowSanitizer::getShadowTy(Value *V) {
- return getShadowTy(V->getType());
-}
-
-bool DataFlowSanitizer::init(Module &M) {
+bool DataFlowSanitizer::isZeroShadow(Value *V) {
+ if (!shouldTrackFieldsAndIndices())
+ return ZeroPrimitiveShadow == V;
+
+ Type *T = V->getType();
+ if (!isa<ArrayType>(T) && !isa<StructType>(T)) {
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
+ return CI->isZero();
+ return false;
+ }
+
+ return isa<ConstantAggregateZero>(V);
+}
+
+bool DataFlowSanitizer::shouldTrackFieldsAndIndices() {
+ return getInstrumentedABI() == DataFlowSanitizer::IA_TLS && ClFast16Labels;
+}
+
+Constant *DataFlowSanitizer::getZeroShadow(Type *OrigTy) {
+ if (!shouldTrackFieldsAndIndices())
+ return ZeroPrimitiveShadow;
+
+ if (!isa<ArrayType>(OrigTy) && !isa<StructType>(OrigTy))
+ return ZeroPrimitiveShadow;
+ Type *ShadowTy = getShadowTy(OrigTy);
+ return ConstantAggregateZero::get(ShadowTy);
+}
+
+Constant *DataFlowSanitizer::getZeroShadow(Value *V) {
+ return getZeroShadow(V->getType());
+}
+
+static Value *expandFromPrimitiveShadowRecursive(
+ Value *Shadow, SmallVector<unsigned, 4> &Indices, Type *SubShadowTy,
+ Value *PrimitiveShadow, IRBuilder<> &IRB) {
+ if (!isa<ArrayType>(SubShadowTy) && !isa<StructType>(SubShadowTy))
+ return IRB.CreateInsertValue(Shadow, PrimitiveShadow, Indices);
+
+ if (ArrayType *AT = dyn_cast<ArrayType>(SubShadowTy)) {
+ for (unsigned Idx = 0; Idx < AT->getNumElements(); Idx++) {
+ Indices.push_back(Idx);
+ Shadow = expandFromPrimitiveShadowRecursive(
+ Shadow, Indices, AT->getElementType(), PrimitiveShadow, IRB);
+ Indices.pop_back();
+ }
+ return Shadow;
+ }
+
+ if (StructType *ST = dyn_cast<StructType>(SubShadowTy)) {
+ for (unsigned Idx = 0; Idx < ST->getNumElements(); Idx++) {
+ Indices.push_back(Idx);
+ Shadow = expandFromPrimitiveShadowRecursive(
+ Shadow, Indices, ST->getElementType(Idx), PrimitiveShadow, IRB);
+ Indices.pop_back();
+ }
+ return Shadow;
+ }
+ llvm_unreachable("Unexpected shadow type");
+}
+
+Value *DFSanFunction::expandFromPrimitiveShadow(Type *T, Value *PrimitiveShadow,
+ Instruction *Pos) {
+ Type *ShadowTy = DFS.getShadowTy(T);
+
+ if (!isa<ArrayType>(ShadowTy) && !isa<StructType>(ShadowTy))
+ return PrimitiveShadow;
+
+ if (DFS.isZeroShadow(PrimitiveShadow))
+ return DFS.getZeroShadow(ShadowTy);
+
+ IRBuilder<> IRB(Pos);
+ SmallVector<unsigned, 4> Indices;
+ Value *Shadow = UndefValue::get(ShadowTy);
+ Shadow = expandFromPrimitiveShadowRecursive(Shadow, Indices, ShadowTy,
+ PrimitiveShadow, IRB);
+
+ // Caches the primitive shadow value that built the shadow value.
+ CachedCollapsedShadows[Shadow] = PrimitiveShadow;
+ return Shadow;
+}
+
+template <class AggregateType>
+Value *DFSanFunction::collapseAggregateShadow(AggregateType *AT, Value *Shadow,
+ IRBuilder<> &IRB) {
+ if (!AT->getNumElements())
+ return DFS.ZeroPrimitiveShadow;
+
+ Value *FirstItem = IRB.CreateExtractValue(Shadow, 0);
+ Value *Aggregator = collapseToPrimitiveShadow(FirstItem, IRB);
+
+ for (unsigned Idx = 1; Idx < AT->getNumElements(); Idx++) {
+ Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
+ Value *ShadowInner = collapseToPrimitiveShadow(ShadowItem, IRB);
+ Aggregator = IRB.CreateOr(Aggregator, ShadowInner);
+ }
+ return Aggregator;
+}
+
+Value *DFSanFunction::collapseToPrimitiveShadow(Value *Shadow,
+ IRBuilder<> &IRB) {
+ Type *ShadowTy = Shadow->getType();
+ if (!isa<ArrayType>(ShadowTy) && !isa<StructType>(ShadowTy))
+ return Shadow;
+ if (ArrayType *AT = dyn_cast<ArrayType>(ShadowTy))
+ return collapseAggregateShadow<>(AT, Shadow, IRB);
+ if (StructType *ST = dyn_cast<StructType>(ShadowTy))
+ return collapseAggregateShadow<>(ST, Shadow, IRB);
+ llvm_unreachable("Unexpected shadow type");
+}
+
+Value *DFSanFunction::collapseToPrimitiveShadow(Value *Shadow,
+ Instruction *Pos) {
+ Type *ShadowTy = Shadow->getType();
+ if (!isa<ArrayType>(ShadowTy) && !isa<StructType>(ShadowTy))
+ return Shadow;
+
+ assert(DFS.shouldTrackFieldsAndIndices());
+
+ // Checks if the cached collapsed shadow value dominates Pos.
+ Value *&CS = CachedCollapsedShadows[Shadow];
+ if (CS && DT.dominates(CS, Pos))
+ return CS;
+
+ IRBuilder<> IRB(Pos);
+ Value *PrimitiveShadow = collapseToPrimitiveShadow(Shadow, IRB);
+ // Caches the converted primitive shadow value.
+ CS = PrimitiveShadow;
+ return PrimitiveShadow;
+}
+
+Type *DataFlowSanitizer::getShadowTy(Type *OrigTy) {
+ if (!shouldTrackFieldsAndIndices())
+ return PrimitiveShadowTy;
+
+ if (!OrigTy->isSized())
+ return PrimitiveShadowTy;
+ if (isa<IntegerType>(OrigTy))
+ return PrimitiveShadowTy;
+ if (isa<VectorType>(OrigTy))
+ return PrimitiveShadowTy;
+ if (ArrayType *AT = dyn_cast<ArrayType>(OrigTy))
+ return ArrayType::get(getShadowTy(AT->getElementType()),
+ AT->getNumElements());
+ if (StructType *ST = dyn_cast<StructType>(OrigTy)) {
+ SmallVector<Type *, 4> Elements;
+ for (unsigned I = 0, N = ST->getNumElements(); I < N; ++I)
+ Elements.push_back(getShadowTy(ST->getElementType(I)));
+ return StructType::get(*Ctx, Elements);
+ }
+ return PrimitiveShadowTy;
+}
+
+Type *DataFlowSanitizer::getShadowTy(Value *V) {
+ return getShadowTy(V->getType());
+}
+
+bool DataFlowSanitizer::init(Module &M) {
Triple TargetTriple(M.getTargetTriple());
bool IsX86_64 = TargetTriple.getArch() == Triple::x86_64;
bool IsMIPS64 = TargetTriple.isMIPS64();
@@ -810,11 +810,11 @@ bool DataFlowSanitizer::init(Module &M) {
Mod = &M;
Ctx = &M.getContext();
- Int8Ptr = Type::getInt8PtrTy(*Ctx);
- PrimitiveShadowTy = IntegerType::get(*Ctx, ShadowWidthBits);
- PrimitiveShadowPtrTy = PointerType::getUnqual(PrimitiveShadowTy);
+ Int8Ptr = Type::getInt8PtrTy(*Ctx);
+ PrimitiveShadowTy = IntegerType::get(*Ctx, ShadowWidthBits);
+ PrimitiveShadowPtrTy = PointerType::getUnqual(PrimitiveShadowTy);
IntptrTy = DL.getIntPtrType(*Ctx);
- ZeroPrimitiveShadow = ConstantInt::getSigned(PrimitiveShadowTy, 0);
+ ZeroPrimitiveShadow = ConstantInt::getSigned(PrimitiveShadowTy, 0);
ShadowPtrMul = ConstantInt::getSigned(IntptrTy, ShadowWidthBytes);
if (IsX86_64)
ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x700000000000LL);
@@ -826,30 +826,30 @@ bool DataFlowSanitizer::init(Module &M) {
else
report_fatal_error("unsupported triple");
- Type *DFSanUnionArgs[2] = {PrimitiveShadowTy, PrimitiveShadowTy};
+ Type *DFSanUnionArgs[2] = {PrimitiveShadowTy, PrimitiveShadowTy};
DFSanUnionFnTy =
- FunctionType::get(PrimitiveShadowTy, DFSanUnionArgs, /*isVarArg=*/false);
- Type *DFSanUnionLoadArgs[2] = {PrimitiveShadowPtrTy, IntptrTy};
- DFSanUnionLoadFnTy = FunctionType::get(PrimitiveShadowTy, DFSanUnionLoadArgs,
- /*isVarArg=*/false);
+ FunctionType::get(PrimitiveShadowTy, DFSanUnionArgs, /*isVarArg=*/false);
+ Type *DFSanUnionLoadArgs[2] = {PrimitiveShadowPtrTy, IntptrTy};
+ DFSanUnionLoadFnTy = FunctionType::get(PrimitiveShadowTy, DFSanUnionLoadArgs,
+ /*isVarArg=*/false);
DFSanUnimplementedFnTy = FunctionType::get(
Type::getVoidTy(*Ctx), Type::getInt8PtrTy(*Ctx), /*isVarArg=*/false);
- Type *DFSanSetLabelArgs[3] = {PrimitiveShadowTy, Type::getInt8PtrTy(*Ctx),
- IntptrTy};
+ Type *DFSanSetLabelArgs[3] = {PrimitiveShadowTy, Type::getInt8PtrTy(*Ctx),
+ IntptrTy};
DFSanSetLabelFnTy = FunctionType::get(Type::getVoidTy(*Ctx),
DFSanSetLabelArgs, /*isVarArg=*/false);
- DFSanNonzeroLabelFnTy =
- FunctionType::get(Type::getVoidTy(*Ctx), None, /*isVarArg=*/false);
+ DFSanNonzeroLabelFnTy =
+ FunctionType::get(Type::getVoidTy(*Ctx), None, /*isVarArg=*/false);
DFSanVarargWrapperFnTy = FunctionType::get(
Type::getVoidTy(*Ctx), Type::getInt8PtrTy(*Ctx), /*isVarArg=*/false);
- DFSanCmpCallbackFnTy =
- FunctionType::get(Type::getVoidTy(*Ctx), PrimitiveShadowTy,
- /*isVarArg=*/false);
- Type *DFSanLoadStoreCallbackArgs[2] = {PrimitiveShadowTy, Int8Ptr};
- DFSanLoadStoreCallbackFnTy =
- FunctionType::get(Type::getVoidTy(*Ctx), DFSanLoadStoreCallbackArgs,
- /*isVarArg=*/false);
- Type *DFSanMemTransferCallbackArgs[2] = {PrimitiveShadowPtrTy, IntptrTy};
+ DFSanCmpCallbackFnTy =
+ FunctionType::get(Type::getVoidTy(*Ctx), PrimitiveShadowTy,
+ /*isVarArg=*/false);
+ Type *DFSanLoadStoreCallbackArgs[2] = {PrimitiveShadowTy, Int8Ptr};
+ DFSanLoadStoreCallbackFnTy =
+ FunctionType::get(Type::getVoidTy(*Ctx), DFSanLoadStoreCallbackArgs,
+ /*isVarArg=*/false);
+ Type *DFSanMemTransferCallbackArgs[2] = {PrimitiveShadowPtrTy, IntptrTy};
DFSanMemTransferCallbackFnTy =
FunctionType::get(Type::getVoidTy(*Ctx), DFSanMemTransferCallbackArgs,
/*isVarArg=*/false);
@@ -954,21 +954,21 @@ Constant *DataFlowSanitizer::getOrBuildTrampolineFunction(FunctionType *FT,
else
RI = ReturnInst::Create(*Ctx, CI, BB);
- // F is called by a wrapped custom function with primitive shadows. So
- // its arguments and return value need conversion.
+ // F is called by a wrapped custom function with primitive shadows. So
+ // its arguments and return value need conversion.
DFSanFunction DFSF(*this, F, /*IsNativeABI=*/true);
Function::arg_iterator ValAI = F->arg_begin(), ShadowAI = AI; ++ValAI;
- for (unsigned N = FT->getNumParams(); N != 0; ++ValAI, ++ShadowAI, --N) {
- Value *Shadow =
- DFSF.expandFromPrimitiveShadow(ValAI->getType(), &*ShadowAI, CI);
- DFSF.ValShadowMap[&*ValAI] = Shadow;
- }
+ for (unsigned N = FT->getNumParams(); N != 0; ++ValAI, ++ShadowAI, --N) {
+ Value *Shadow =
+ DFSF.expandFromPrimitiveShadow(ValAI->getType(), &*ShadowAI, CI);
+ DFSF.ValShadowMap[&*ValAI] = Shadow;
+ }
DFSanVisitor(DFSF).visitCallInst(*CI);
- if (!FT->getReturnType()->isVoidTy()) {
- Value *PrimitiveShadow = DFSF.collapseToPrimitiveShadow(
- DFSF.getShadow(RI->getReturnValue()), RI);
- new StoreInst(PrimitiveShadow, &*std::prev(F->arg_end()), RI);
- }
+ if (!FT->getReturnType()->isVoidTy()) {
+ Value *PrimitiveShadow = DFSF.collapseToPrimitiveShadow(
+ DFSF.getShadow(RI->getReturnValue()), RI);
+ new StoreInst(PrimitiveShadow, &*std::prev(F->arg_end()), RI);
+ }
}
return cast<Constant>(C.getCallee());
@@ -1013,17 +1013,17 @@ void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
DFSanUnionLoadFn =
Mod->getOrInsertFunction("__dfsan_union_load", DFSanUnionLoadFnTy, AL);
}
- {
- AttributeList AL;
- AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex,
- Attribute::NoUnwind);
- AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex,
- Attribute::ReadOnly);
- AL = AL.addAttribute(M.getContext(), AttributeList::ReturnIndex,
- Attribute::ZExt);
- DFSanUnionLoadFast16LabelsFn = Mod->getOrInsertFunction(
- "__dfsan_union_load_fast16labels", DFSanUnionLoadFnTy, AL);
- }
+ {
+ AttributeList AL;
+ AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex,
+ Attribute::NoUnwind);
+ AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex,
+ Attribute::ReadOnly);
+ AL = AL.addAttribute(M.getContext(), AttributeList::ReturnIndex,
+ Attribute::ZExt);
+ DFSanUnionLoadFast16LabelsFn = Mod->getOrInsertFunction(
+ "__dfsan_union_load_fast16labels", DFSanUnionLoadFnTy, AL);
+ }
DFSanUnimplementedFn =
Mod->getOrInsertFunction("__dfsan_unimplemented", DFSanUnimplementedFnTy);
{
@@ -1041,18 +1041,18 @@ void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
// Initializes event callback functions and declare them in the module
void DataFlowSanitizer::initializeCallbackFunctions(Module &M) {
DFSanLoadCallbackFn = Mod->getOrInsertFunction("__dfsan_load_callback",
- DFSanLoadStoreCallbackFnTy);
- DFSanStoreCallbackFn = Mod->getOrInsertFunction("__dfsan_store_callback",
- DFSanLoadStoreCallbackFnTy);
+ DFSanLoadStoreCallbackFnTy);
+ DFSanStoreCallbackFn = Mod->getOrInsertFunction("__dfsan_store_callback",
+ DFSanLoadStoreCallbackFnTy);
DFSanMemTransferCallbackFn = Mod->getOrInsertFunction(
"__dfsan_mem_transfer_callback", DFSanMemTransferCallbackFnTy);
- DFSanCmpCallbackFn =
- Mod->getOrInsertFunction("__dfsan_cmp_callback", DFSanCmpCallbackFnTy);
+ DFSanCmpCallbackFn =
+ Mod->getOrInsertFunction("__dfsan_cmp_callback", DFSanCmpCallbackFnTy);
}
-bool DataFlowSanitizer::runImpl(Module &M) {
- init(M);
-
+bool DataFlowSanitizer::runImpl(Module &M) {
+ init(M);
+
if (ABIList.isIn(M, "skip"))
return false;
@@ -1061,18 +1061,18 @@ bool DataFlowSanitizer::runImpl(Module &M) {
bool Changed = false;
- Type *ArgTLSTy = ArrayType::get(Type::getInt64Ty(*Ctx), kArgTLSSize / 8);
- ArgTLS = Mod->getOrInsertGlobal("__dfsan_arg_tls", ArgTLSTy);
- if (GlobalVariable *G = dyn_cast<GlobalVariable>(ArgTLS)) {
- Changed |= G->getThreadLocalMode() != GlobalVariable::InitialExecTLSModel;
- G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
+ Type *ArgTLSTy = ArrayType::get(Type::getInt64Ty(*Ctx), kArgTLSSize / 8);
+ ArgTLS = Mod->getOrInsertGlobal("__dfsan_arg_tls", ArgTLSTy);
+ if (GlobalVariable *G = dyn_cast<GlobalVariable>(ArgTLS)) {
+ Changed |= G->getThreadLocalMode() != GlobalVariable::InitialExecTLSModel;
+ G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
}
- Type *RetvalTLSTy =
- ArrayType::get(Type::getInt64Ty(*Ctx), kRetvalTLSSize / 8);
- RetvalTLS = Mod->getOrInsertGlobal("__dfsan_retval_tls", RetvalTLSTy);
- if (GlobalVariable *G = dyn_cast<GlobalVariable>(RetvalTLS)) {
- Changed |= G->getThreadLocalMode() != GlobalVariable::InitialExecTLSModel;
- G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
+ Type *RetvalTLSTy =
+ ArrayType::get(Type::getInt64Ty(*Ctx), kRetvalTLSSize / 8);
+ RetvalTLS = Mod->getOrInsertGlobal("__dfsan_retval_tls", RetvalTLSTy);
+ if (GlobalVariable *G = dyn_cast<GlobalVariable>(RetvalTLS)) {
+ Changed |= G->getThreadLocalMode() != GlobalVariable::InitialExecTLSModel;
+ G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
}
ExternalShadowMask =
@@ -1088,7 +1088,7 @@ bool DataFlowSanitizer::runImpl(Module &M) {
&i != DFSanUnionFn.getCallee()->stripPointerCasts() &&
&i != DFSanCheckedUnionFn.getCallee()->stripPointerCasts() &&
&i != DFSanUnionLoadFn.getCallee()->stripPointerCasts() &&
- &i != DFSanUnionLoadFast16LabelsFn.getCallee()->stripPointerCasts() &&
+ &i != DFSanUnionLoadFast16LabelsFn.getCallee()->stripPointerCasts() &&
&i != DFSanUnimplementedFn.getCallee()->stripPointerCasts() &&
&i != DFSanSetLabelFn.getCallee()->stripPointerCasts() &&
&i != DFSanNonzeroLabelFn.getCallee()->stripPointerCasts() &&
@@ -1288,9 +1288,9 @@ bool DataFlowSanitizer::runImpl(Module &M) {
while (isa<PHINode>(Pos) || isa<AllocaInst>(Pos))
Pos = Pos->getNextNode();
IRBuilder<> IRB(Pos);
- Value *PrimitiveShadow = DFSF.collapseToPrimitiveShadow(V, Pos);
- Value *Ne =
- IRB.CreateICmpNE(PrimitiveShadow, DFSF.DFS.ZeroPrimitiveShadow);
+ Value *PrimitiveShadow = DFSF.collapseToPrimitiveShadow(V, Pos);
+ Value *Ne =
+ IRB.CreateICmpNE(PrimitiveShadow, DFSF.DFS.ZeroPrimitiveShadow);
BranchInst *BI = cast<BranchInst>(SplitBlockAndInsertIfThen(
Ne, Pos, /*Unreachable=*/false, ColdCallWeights));
IRBuilder<> ThenIRB(BI);
@@ -1303,61 +1303,61 @@ bool DataFlowSanitizer::runImpl(Module &M) {
M.global_size() != InitialGlobalSize || M.size() != InitialModuleSize;
}
-Value *DFSanFunction::getArgTLS(Type *T, unsigned ArgOffset, IRBuilder<> &IRB) {
- Value *Base = IRB.CreatePointerCast(DFS.ArgTLS, DFS.IntptrTy);
- if (ArgOffset)
- Base = IRB.CreateAdd(Base, ConstantInt::get(DFS.IntptrTy, ArgOffset));
- return IRB.CreateIntToPtr(Base, PointerType::get(DFS.getShadowTy(T), 0),
- "_dfsarg");
-}
-
-Value *DFSanFunction::getRetvalTLS(Type *T, IRBuilder<> &IRB) {
- return IRB.CreatePointerCast(
- DFS.RetvalTLS, PointerType::get(DFS.getShadowTy(T), 0), "_dfsret");
+Value *DFSanFunction::getArgTLS(Type *T, unsigned ArgOffset, IRBuilder<> &IRB) {
+ Value *Base = IRB.CreatePointerCast(DFS.ArgTLS, DFS.IntptrTy);
+ if (ArgOffset)
+ Base = IRB.CreateAdd(Base, ConstantInt::get(DFS.IntptrTy, ArgOffset));
+ return IRB.CreateIntToPtr(Base, PointerType::get(DFS.getShadowTy(T), 0),
+ "_dfsarg");
}
-Value *DFSanFunction::getShadowForTLSArgument(Argument *A) {
- unsigned ArgOffset = 0;
- const DataLayout &DL = F->getParent()->getDataLayout();
- for (auto &FArg : F->args()) {
- if (!FArg.getType()->isSized()) {
- if (A == &FArg)
- break;
- continue;
- }
-
- unsigned Size = DL.getTypeAllocSize(DFS.getShadowTy(&FArg));
- if (A != &FArg) {
- ArgOffset += alignTo(Size, kShadowTLSAlignment);
- if (ArgOffset > kArgTLSSize)
- break; // ArgTLS overflows, uses a zero shadow.
- continue;
- }
-
- if (ArgOffset + Size > kArgTLSSize)
- break; // ArgTLS overflows, uses a zero shadow.
-
- Instruction *ArgTLSPos = &*F->getEntryBlock().begin();
- IRBuilder<> IRB(ArgTLSPos);
- Value *ArgShadowPtr = getArgTLS(FArg.getType(), ArgOffset, IRB);
- return IRB.CreateAlignedLoad(DFS.getShadowTy(&FArg), ArgShadowPtr,
- kShadowTLSAlignment);
- }
-
- return DFS.getZeroShadow(A);
+Value *DFSanFunction::getRetvalTLS(Type *T, IRBuilder<> &IRB) {
+ return IRB.CreatePointerCast(
+ DFS.RetvalTLS, PointerType::get(DFS.getShadowTy(T), 0), "_dfsret");
+}
+
+Value *DFSanFunction::getShadowForTLSArgument(Argument *A) {
+ unsigned ArgOffset = 0;
+ const DataLayout &DL = F->getParent()->getDataLayout();
+ for (auto &FArg : F->args()) {
+ if (!FArg.getType()->isSized()) {
+ if (A == &FArg)
+ break;
+ continue;
+ }
+
+ unsigned Size = DL.getTypeAllocSize(DFS.getShadowTy(&FArg));
+ if (A != &FArg) {
+ ArgOffset += alignTo(Size, kShadowTLSAlignment);
+ if (ArgOffset > kArgTLSSize)
+ break; // ArgTLS overflows, uses a zero shadow.
+ continue;
+ }
+
+ if (ArgOffset + Size > kArgTLSSize)
+ break; // ArgTLS overflows, uses a zero shadow.
+
+ Instruction *ArgTLSPos = &*F->getEntryBlock().begin();
+ IRBuilder<> IRB(ArgTLSPos);
+ Value *ArgShadowPtr = getArgTLS(FArg.getType(), ArgOffset, IRB);
+ return IRB.CreateAlignedLoad(DFS.getShadowTy(&FArg), ArgShadowPtr,
+ kShadowTLSAlignment);
+ }
+
+ return DFS.getZeroShadow(A);
}
Value *DFSanFunction::getShadow(Value *V) {
if (!isa<Argument>(V) && !isa<Instruction>(V))
- return DFS.getZeroShadow(V);
+ return DFS.getZeroShadow(V);
Value *&Shadow = ValShadowMap[V];
if (!Shadow) {
if (Argument *A = dyn_cast<Argument>(V)) {
if (IsNativeABI)
- return DFS.getZeroShadow(V);
+ return DFS.getZeroShadow(V);
switch (IA) {
case DataFlowSanitizer::IA_TLS: {
- Shadow = getShadowForTLSArgument(A);
+ Shadow = getShadowForTLSArgument(A);
break;
}
case DataFlowSanitizer::IA_Args: {
@@ -1366,13 +1366,13 @@ Value *DFSanFunction::getShadow(Value *V) {
while (ArgIdx--)
++i;
Shadow = &*i;
- assert(Shadow->getType() == DFS.PrimitiveShadowTy);
+ assert(Shadow->getType() == DFS.PrimitiveShadowTy);
break;
}
}
NonZeroChecks.push_back(Shadow);
} else {
- Shadow = DFS.getZeroShadow(V);
+ Shadow = DFS.getZeroShadow(V);
}
}
return Shadow;
@@ -1380,8 +1380,8 @@ Value *DFSanFunction::getShadow(Value *V) {
void DFSanFunction::setShadow(Instruction *I, Value *Shadow) {
assert(!ValShadowMap.count(I));
- assert(DFS.shouldTrackFieldsAndIndices() ||
- Shadow->getType() == DFS.PrimitiveShadowTy);
+ assert(DFS.shouldTrackFieldsAndIndices() ||
+ Shadow->getType() == DFS.PrimitiveShadowTy);
ValShadowMap[I] = Shadow;
}
@@ -1398,60 +1398,60 @@ Value *DataFlowSanitizer::getShadowAddress(Value *Addr, Instruction *Pos) {
IRB.CreateAnd(IRB.CreatePtrToInt(Addr, IntptrTy),
IRB.CreatePtrToInt(ShadowPtrMaskValue, IntptrTy)),
ShadowPtrMul),
- PrimitiveShadowPtrTy);
+ PrimitiveShadowPtrTy);
+}
+
+Value *DFSanFunction::combineShadowsThenConvert(Type *T, Value *V1, Value *V2,
+ Instruction *Pos) {
+ Value *PrimitiveValue = combineShadows(V1, V2, Pos);
+ return expandFromPrimitiveShadow(T, PrimitiveValue, Pos);
}
-Value *DFSanFunction::combineShadowsThenConvert(Type *T, Value *V1, Value *V2,
- Instruction *Pos) {
- Value *PrimitiveValue = combineShadows(V1, V2, Pos);
- return expandFromPrimitiveShadow(T, PrimitiveValue, Pos);
-}
-
// Generates IR to compute the union of the two given shadows, inserting it
-// before Pos. The combined value is with primitive type.
+// before Pos. The combined value is with primitive type.
Value *DFSanFunction::combineShadows(Value *V1, Value *V2, Instruction *Pos) {
- if (DFS.isZeroShadow(V1))
- return collapseToPrimitiveShadow(V2, Pos);
- if (DFS.isZeroShadow(V2))
- return collapseToPrimitiveShadow(V1, Pos);
+ if (DFS.isZeroShadow(V1))
+ return collapseToPrimitiveShadow(V2, Pos);
+ if (DFS.isZeroShadow(V2))
+ return collapseToPrimitiveShadow(V1, Pos);
if (V1 == V2)
- return collapseToPrimitiveShadow(V1, Pos);
+ return collapseToPrimitiveShadow(V1, Pos);
auto V1Elems = ShadowElements.find(V1);
auto V2Elems = ShadowElements.find(V2);
if (V1Elems != ShadowElements.end() && V2Elems != ShadowElements.end()) {
if (std::includes(V1Elems->second.begin(), V1Elems->second.end(),
V2Elems->second.begin(), V2Elems->second.end())) {
- return collapseToPrimitiveShadow(V1, Pos);
+ return collapseToPrimitiveShadow(V1, Pos);
} else if (std::includes(V2Elems->second.begin(), V2Elems->second.end(),
V1Elems->second.begin(), V1Elems->second.end())) {
- return collapseToPrimitiveShadow(V2, Pos);
+ return collapseToPrimitiveShadow(V2, Pos);
}
} else if (V1Elems != ShadowElements.end()) {
if (V1Elems->second.count(V2))
- return collapseToPrimitiveShadow(V1, Pos);
+ return collapseToPrimitiveShadow(V1, Pos);
} else if (V2Elems != ShadowElements.end()) {
if (V2Elems->second.count(V1))
- return collapseToPrimitiveShadow(V2, Pos);
+ return collapseToPrimitiveShadow(V2, Pos);
}
auto Key = std::make_pair(V1, V2);
if (V1 > V2)
std::swap(Key.first, Key.second);
- CachedShadow &CCS = CachedShadows[Key];
+ CachedShadow &CCS = CachedShadows[Key];
if (CCS.Block && DT.dominates(CCS.Block, Pos->getParent()))
return CCS.Shadow;
- // Converts inputs shadows to shadows with primitive types.
- Value *PV1 = collapseToPrimitiveShadow(V1, Pos);
- Value *PV2 = collapseToPrimitiveShadow(V2, Pos);
-
+ // Converts inputs shadows to shadows with primitive types.
+ Value *PV1 = collapseToPrimitiveShadow(V1, Pos);
+ Value *PV2 = collapseToPrimitiveShadow(V2, Pos);
+
IRBuilder<> IRB(Pos);
- if (ClFast16Labels) {
- CCS.Block = Pos->getParent();
- CCS.Shadow = IRB.CreateOr(PV1, PV2);
- } else if (AvoidNewBlocks) {
- CallInst *Call = IRB.CreateCall(DFS.DFSanCheckedUnionFn, {PV1, PV2});
+ if (ClFast16Labels) {
+ CCS.Block = Pos->getParent();
+ CCS.Shadow = IRB.CreateOr(PV1, PV2);
+ } else if (AvoidNewBlocks) {
+ CallInst *Call = IRB.CreateCall(DFS.DFSanCheckedUnionFn, {PV1, PV2});
Call->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt);
Call->addParamAttr(0, Attribute::ZExt);
Call->addParamAttr(1, Attribute::ZExt);
@@ -1460,20 +1460,20 @@ Value *DFSanFunction::combineShadows(Value *V1, Value *V2, Instruction *Pos) {
CCS.Shadow = Call;
} else {
BasicBlock *Head = Pos->getParent();
- Value *Ne = IRB.CreateICmpNE(PV1, PV2);
+ Value *Ne = IRB.CreateICmpNE(PV1, PV2);
BranchInst *BI = cast<BranchInst>(SplitBlockAndInsertIfThen(
Ne, Pos, /*Unreachable=*/false, DFS.ColdCallWeights, &DT));
IRBuilder<> ThenIRB(BI);
- CallInst *Call = ThenIRB.CreateCall(DFS.DFSanUnionFn, {PV1, PV2});
+ CallInst *Call = ThenIRB.CreateCall(DFS.DFSanUnionFn, {PV1, PV2});
Call->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt);
Call->addParamAttr(0, Attribute::ZExt);
Call->addParamAttr(1, Attribute::ZExt);
BasicBlock *Tail = BI->getSuccessor(0);
- PHINode *Phi =
- PHINode::Create(DFS.PrimitiveShadowTy, 2, "", &Tail->front());
+ PHINode *Phi =
+ PHINode::Create(DFS.PrimitiveShadowTy, 2, "", &Tail->front());
Phi->addIncoming(Call, Call->getParent());
- Phi->addIncoming(PV1, Head);
+ Phi->addIncoming(PV1, Head);
CCS.Block = Tail;
CCS.Shadow = Phi;
@@ -1500,13 +1500,13 @@ Value *DFSanFunction::combineShadows(Value *V1, Value *V2, Instruction *Pos) {
// the computed union Value.
Value *DFSanFunction::combineOperandShadows(Instruction *Inst) {
if (Inst->getNumOperands() == 0)
- return DFS.getZeroShadow(Inst);
+ return DFS.getZeroShadow(Inst);
Value *Shadow = getShadow(Inst->getOperand(0));
for (unsigned i = 1, n = Inst->getNumOperands(); i != n; ++i) {
Shadow = combineShadows(Shadow, getShadow(Inst->getOperand(i)), Inst);
}
- return expandFromPrimitiveShadow(Inst->getType(), Shadow, Inst);
+ return expandFromPrimitiveShadow(Inst->getType(), Shadow, Inst);
}
Value *DFSanVisitor::visitOperandShadowInst(Instruction &I) {
@@ -1516,21 +1516,21 @@ Value *DFSanVisitor::visitOperandShadowInst(Instruction &I) {
}
// Generates IR to load shadow corresponding to bytes [Addr, Addr+Size), where
-// Addr has alignment Align, and take the union of each of those shadows. The
-// returned shadow always has primitive type.
+// Addr has alignment Align, and take the union of each of those shadows. The
+// returned shadow always has primitive type.
Value *DFSanFunction::loadShadow(Value *Addr, uint64_t Size, uint64_t Align,
Instruction *Pos) {
if (AllocaInst *AI = dyn_cast<AllocaInst>(Addr)) {
const auto i = AllocaShadowMap.find(AI);
if (i != AllocaShadowMap.end()) {
IRBuilder<> IRB(Pos);
- return IRB.CreateLoad(DFS.PrimitiveShadowTy, i->second);
+ return IRB.CreateLoad(DFS.PrimitiveShadowTy, i->second);
}
}
const llvm::Align ShadowAlign(Align * DFS.ShadowWidthBytes);
SmallVector<const Value *, 2> Objs;
- getUnderlyingObjects(Addr, Objs);
+ getUnderlyingObjects(Addr, Objs);
bool AllConstants = true;
for (const Value *Obj : Objs) {
if (isa<Function>(Obj) || isa<BlockAddress>(Obj))
@@ -1542,51 +1542,51 @@ Value *DFSanFunction::loadShadow(Value *Addr, uint64_t Size, uint64_t Align,
break;
}
if (AllConstants)
- return DFS.ZeroPrimitiveShadow;
+ return DFS.ZeroPrimitiveShadow;
Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
switch (Size) {
case 0:
- return DFS.ZeroPrimitiveShadow;
+ return DFS.ZeroPrimitiveShadow;
case 1: {
- LoadInst *LI = new LoadInst(DFS.PrimitiveShadowTy, ShadowAddr, "", Pos);
+ LoadInst *LI = new LoadInst(DFS.PrimitiveShadowTy, ShadowAddr, "", Pos);
LI->setAlignment(ShadowAlign);
return LI;
}
case 2: {
IRBuilder<> IRB(Pos);
- Value *ShadowAddr1 = IRB.CreateGEP(DFS.PrimitiveShadowTy, ShadowAddr,
+ Value *ShadowAddr1 = IRB.CreateGEP(DFS.PrimitiveShadowTy, ShadowAddr,
ConstantInt::get(DFS.IntptrTy, 1));
return combineShadows(
- IRB.CreateAlignedLoad(DFS.PrimitiveShadowTy, ShadowAddr, ShadowAlign),
- IRB.CreateAlignedLoad(DFS.PrimitiveShadowTy, ShadowAddr1, ShadowAlign),
- Pos);
- }
- }
-
- if (ClFast16Labels && Size % (64 / DFS.ShadowWidthBits) == 0) {
- // First OR all the WideShadows, then OR individual shadows within the
- // combined WideShadow. This is fewer instructions than ORing shadows
- // individually.
- IRBuilder<> IRB(Pos);
- Value *WideAddr =
- IRB.CreateBitCast(ShadowAddr, Type::getInt64PtrTy(*DFS.Ctx));
- Value *CombinedWideShadow =
- IRB.CreateAlignedLoad(IRB.getInt64Ty(), WideAddr, ShadowAlign);
- for (uint64_t Ofs = 64 / DFS.ShadowWidthBits; Ofs != Size;
- Ofs += 64 / DFS.ShadowWidthBits) {
- WideAddr = IRB.CreateGEP(Type::getInt64Ty(*DFS.Ctx), WideAddr,
- ConstantInt::get(DFS.IntptrTy, 1));
- Value *NextWideShadow =
- IRB.CreateAlignedLoad(IRB.getInt64Ty(), WideAddr, ShadowAlign);
- CombinedWideShadow = IRB.CreateOr(CombinedWideShadow, NextWideShadow);
- }
- for (unsigned Width = 32; Width >= DFS.ShadowWidthBits; Width >>= 1) {
- Value *ShrShadow = IRB.CreateLShr(CombinedWideShadow, Width);
- CombinedWideShadow = IRB.CreateOr(CombinedWideShadow, ShrShadow);
- }
- return IRB.CreateTrunc(CombinedWideShadow, DFS.PrimitiveShadowTy);
- }
+ IRB.CreateAlignedLoad(DFS.PrimitiveShadowTy, ShadowAddr, ShadowAlign),
+ IRB.CreateAlignedLoad(DFS.PrimitiveShadowTy, ShadowAddr1, ShadowAlign),
+ Pos);
+ }
+ }
+
+ if (ClFast16Labels && Size % (64 / DFS.ShadowWidthBits) == 0) {
+ // First OR all the WideShadows, then OR individual shadows within the
+ // combined WideShadow. This is fewer instructions than ORing shadows
+ // individually.
+ IRBuilder<> IRB(Pos);
+ Value *WideAddr =
+ IRB.CreateBitCast(ShadowAddr, Type::getInt64PtrTy(*DFS.Ctx));
+ Value *CombinedWideShadow =
+ IRB.CreateAlignedLoad(IRB.getInt64Ty(), WideAddr, ShadowAlign);
+ for (uint64_t Ofs = 64 / DFS.ShadowWidthBits; Ofs != Size;
+ Ofs += 64 / DFS.ShadowWidthBits) {
+ WideAddr = IRB.CreateGEP(Type::getInt64Ty(*DFS.Ctx), WideAddr,
+ ConstantInt::get(DFS.IntptrTy, 1));
+ Value *NextWideShadow =
+ IRB.CreateAlignedLoad(IRB.getInt64Ty(), WideAddr, ShadowAlign);
+ CombinedWideShadow = IRB.CreateOr(CombinedWideShadow, NextWideShadow);
+ }
+ for (unsigned Width = 32; Width >= DFS.ShadowWidthBits; Width >>= 1) {
+ Value *ShrShadow = IRB.CreateLShr(CombinedWideShadow, Width);
+ CombinedWideShadow = IRB.CreateOr(CombinedWideShadow, ShrShadow);
+ }
+ return IRB.CreateTrunc(CombinedWideShadow, DFS.PrimitiveShadowTy);
+ }
if (!AvoidNewBlocks && Size % (64 / DFS.ShadowWidthBits) == 0) {
// Fast path for the common case where each byte has identical shadow: load
// shadow 64 bits at a time, fall out to a __dfsan_union_load call if any
@@ -1605,7 +1605,7 @@ Value *DFSanFunction::loadShadow(Value *Addr, uint64_t Size, uint64_t Align,
IRB.CreateBitCast(ShadowAddr, Type::getInt64PtrTy(*DFS.Ctx));
Value *WideShadow =
IRB.CreateAlignedLoad(IRB.getInt64Ty(), WideAddr, ShadowAlign);
- Value *TruncShadow = IRB.CreateTrunc(WideShadow, DFS.PrimitiveShadowTy);
+ Value *TruncShadow = IRB.CreateTrunc(WideShadow, DFS.PrimitiveShadowTy);
Value *ShlShadow = IRB.CreateShl(WideShadow, DFS.ShadowWidthBits);
Value *ShrShadow = IRB.CreateLShr(WideShadow, 64 - DFS.ShadowWidthBits);
Value *RotShadow = IRB.CreateOr(ShlShadow, ShrShadow);
@@ -1646,18 +1646,18 @@ Value *DFSanFunction::loadShadow(Value *Addr, uint64_t Size, uint64_t Align,
LastBr->setSuccessor(0, Tail);
FallbackIRB.CreateBr(Tail);
- PHINode *Shadow =
- PHINode::Create(DFS.PrimitiveShadowTy, 2, "", &Tail->front());
+ PHINode *Shadow =
+ PHINode::Create(DFS.PrimitiveShadowTy, 2, "", &Tail->front());
Shadow->addIncoming(FallbackCall, FallbackBB);
Shadow->addIncoming(TruncShadow, LastBr->getParent());
return Shadow;
}
IRBuilder<> IRB(Pos);
- FunctionCallee &UnionLoadFn =
- ClFast16Labels ? DFS.DFSanUnionLoadFast16LabelsFn : DFS.DFSanUnionLoadFn;
+ FunctionCallee &UnionLoadFn =
+ ClFast16Labels ? DFS.DFSanUnionLoadFast16LabelsFn : DFS.DFSanUnionLoadFn;
CallInst *FallbackCall = IRB.CreateCall(
- UnionLoadFn, {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
+ UnionLoadFn, {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
FallbackCall->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt);
return FallbackCall;
}
@@ -1666,39 +1666,39 @@ void DFSanVisitor::visitLoadInst(LoadInst &LI) {
auto &DL = LI.getModule()->getDataLayout();
uint64_t Size = DL.getTypeStoreSize(LI.getType());
if (Size == 0) {
- DFSF.setShadow(&LI, DFSF.DFS.getZeroShadow(&LI));
+ DFSF.setShadow(&LI, DFSF.DFS.getZeroShadow(&LI));
return;
}
Align Alignment = ClPreserveAlignment ? LI.getAlign() : Align(1);
- Value *PrimitiveShadow =
+ Value *PrimitiveShadow =
DFSF.loadShadow(LI.getPointerOperand(), Size, Alignment.value(), &LI);
if (ClCombinePointerLabelsOnLoad) {
Value *PtrShadow = DFSF.getShadow(LI.getPointerOperand());
- PrimitiveShadow = DFSF.combineShadows(PrimitiveShadow, PtrShadow, &LI);
+ PrimitiveShadow = DFSF.combineShadows(PrimitiveShadow, PtrShadow, &LI);
}
- if (!DFSF.DFS.isZeroShadow(PrimitiveShadow))
- DFSF.NonZeroChecks.push_back(PrimitiveShadow);
+ if (!DFSF.DFS.isZeroShadow(PrimitiveShadow))
+ DFSF.NonZeroChecks.push_back(PrimitiveShadow);
- Value *Shadow =
- DFSF.expandFromPrimitiveShadow(LI.getType(), PrimitiveShadow, &LI);
+ Value *Shadow =
+ DFSF.expandFromPrimitiveShadow(LI.getType(), PrimitiveShadow, &LI);
DFSF.setShadow(&LI, Shadow);
if (ClEventCallbacks) {
IRBuilder<> IRB(&LI);
- Value *Addr8 = IRB.CreateBitCast(LI.getPointerOperand(), DFSF.DFS.Int8Ptr);
- IRB.CreateCall(DFSF.DFS.DFSanLoadCallbackFn, {PrimitiveShadow, Addr8});
+ Value *Addr8 = IRB.CreateBitCast(LI.getPointerOperand(), DFSF.DFS.Int8Ptr);
+ IRB.CreateCall(DFSF.DFS.DFSanLoadCallbackFn, {PrimitiveShadow, Addr8});
}
}
-void DFSanFunction::storePrimitiveShadow(Value *Addr, uint64_t Size,
- Align Alignment,
- Value *PrimitiveShadow,
- Instruction *Pos) {
+void DFSanFunction::storePrimitiveShadow(Value *Addr, uint64_t Size,
+ Align Alignment,
+ Value *PrimitiveShadow,
+ Instruction *Pos) {
if (AllocaInst *AI = dyn_cast<AllocaInst>(Addr)) {
const auto i = AllocaShadowMap.find(AI);
if (i != AllocaShadowMap.end()) {
IRBuilder<> IRB(Pos);
- IRB.CreateStore(PrimitiveShadow, i->second);
+ IRB.CreateStore(PrimitiveShadow, i->second);
return;
}
}
@@ -1706,7 +1706,7 @@ void DFSanFunction::storePrimitiveShadow(Value *Addr, uint64_t Size,
const Align ShadowAlign(Alignment.value() * DFS.ShadowWidthBytes);
IRBuilder<> IRB(Pos);
Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
- if (DFS.isZeroShadow(PrimitiveShadow)) {
+ if (DFS.isZeroShadow(PrimitiveShadow)) {
IntegerType *ShadowTy =
IntegerType::get(*DFS.Ctx, Size * DFS.ShadowWidthBits);
Value *ExtZeroShadow = ConstantInt::get(ShadowTy, 0);
@@ -1719,13 +1719,13 @@ void DFSanFunction::storePrimitiveShadow(Value *Addr, uint64_t Size,
const unsigned ShadowVecSize = 128 / DFS.ShadowWidthBits;
uint64_t Offset = 0;
if (Size >= ShadowVecSize) {
- auto *ShadowVecTy =
- FixedVectorType::get(DFS.PrimitiveShadowTy, ShadowVecSize);
+ auto *ShadowVecTy =
+ FixedVectorType::get(DFS.PrimitiveShadowTy, ShadowVecSize);
Value *ShadowVec = UndefValue::get(ShadowVecTy);
for (unsigned i = 0; i != ShadowVecSize; ++i) {
ShadowVec = IRB.CreateInsertElement(
- ShadowVec, PrimitiveShadow,
- ConstantInt::get(Type::getInt32Ty(*DFS.Ctx), i));
+ ShadowVec, PrimitiveShadow,
+ ConstantInt::get(Type::getInt32Ty(*DFS.Ctx), i));
}
Value *ShadowVecAddr =
IRB.CreateBitCast(ShadowAddr, PointerType::getUnqual(ShadowVecTy));
@@ -1740,8 +1740,8 @@ void DFSanFunction::storePrimitiveShadow(Value *Addr, uint64_t Size,
}
while (Size > 0) {
Value *CurShadowAddr =
- IRB.CreateConstGEP1_32(DFS.PrimitiveShadowTy, ShadowAddr, Offset);
- IRB.CreateAlignedStore(PrimitiveShadow, CurShadowAddr, ShadowAlign);
+ IRB.CreateConstGEP1_32(DFS.PrimitiveShadowTy, ShadowAddr, Offset);
+ IRB.CreateAlignedStore(PrimitiveShadow, CurShadowAddr, ShadowAlign);
--Size;
++Offset;
}
@@ -1756,19 +1756,19 @@ void DFSanVisitor::visitStoreInst(StoreInst &SI) {
const Align Alignment = ClPreserveAlignment ? SI.getAlign() : Align(1);
Value* Shadow = DFSF.getShadow(SI.getValueOperand());
- Value *PrimitiveShadow;
+ Value *PrimitiveShadow;
if (ClCombinePointerLabelsOnStore) {
Value *PtrShadow = DFSF.getShadow(SI.getPointerOperand());
- PrimitiveShadow = DFSF.combineShadows(Shadow, PtrShadow, &SI);
- } else {
- PrimitiveShadow = DFSF.collapseToPrimitiveShadow(Shadow, &SI);
+ PrimitiveShadow = DFSF.combineShadows(Shadow, PtrShadow, &SI);
+ } else {
+ PrimitiveShadow = DFSF.collapseToPrimitiveShadow(Shadow, &SI);
}
- DFSF.storePrimitiveShadow(SI.getPointerOperand(), Size, Alignment,
- PrimitiveShadow, &SI);
+ DFSF.storePrimitiveShadow(SI.getPointerOperand(), Size, Alignment,
+ PrimitiveShadow, &SI);
if (ClEventCallbacks) {
IRBuilder<> IRB(&SI);
- Value *Addr8 = IRB.CreateBitCast(SI.getPointerOperand(), DFSF.DFS.Int8Ptr);
- IRB.CreateCall(DFSF.DFS.DFSanStoreCallbackFn, {PrimitiveShadow, Addr8});
+ Value *Addr8 = IRB.CreateBitCast(SI.getPointerOperand(), DFSF.DFS.Int8Ptr);
+ IRB.CreateCall(DFSF.DFS.DFSanStoreCallbackFn, {PrimitiveShadow, Addr8});
}
}
@@ -1807,29 +1807,29 @@ void DFSanVisitor::visitShuffleVectorInst(ShuffleVectorInst &I) {
}
void DFSanVisitor::visitExtractValueInst(ExtractValueInst &I) {
- if (!DFSF.DFS.shouldTrackFieldsAndIndices()) {
- visitOperandShadowInst(I);
- return;
- }
-
- IRBuilder<> IRB(&I);
- Value *Agg = I.getAggregateOperand();
- Value *AggShadow = DFSF.getShadow(Agg);
- Value *ResShadow = IRB.CreateExtractValue(AggShadow, I.getIndices());
- DFSF.setShadow(&I, ResShadow);
+ if (!DFSF.DFS.shouldTrackFieldsAndIndices()) {
+ visitOperandShadowInst(I);
+ return;
+ }
+
+ IRBuilder<> IRB(&I);
+ Value *Agg = I.getAggregateOperand();
+ Value *AggShadow = DFSF.getShadow(Agg);
+ Value *ResShadow = IRB.CreateExtractValue(AggShadow, I.getIndices());
+ DFSF.setShadow(&I, ResShadow);
}
void DFSanVisitor::visitInsertValueInst(InsertValueInst &I) {
- if (!DFSF.DFS.shouldTrackFieldsAndIndices()) {
- visitOperandShadowInst(I);
- return;
- }
-
- IRBuilder<> IRB(&I);
- Value *AggShadow = DFSF.getShadow(I.getAggregateOperand());
- Value *InsShadow = DFSF.getShadow(I.getInsertedValueOperand());
- Value *Res = IRB.CreateInsertValue(AggShadow, InsShadow, I.getIndices());
- DFSF.setShadow(&I, Res);
+ if (!DFSF.DFS.shouldTrackFieldsAndIndices()) {
+ visitOperandShadowInst(I);
+ return;
+ }
+
+ IRBuilder<> IRB(&I);
+ Value *AggShadow = DFSF.getShadow(I.getAggregateOperand());
+ Value *InsShadow = DFSF.getShadow(I.getInsertedValueOperand());
+ Value *Res = IRB.CreateInsertValue(AggShadow, InsShadow, I.getIndices());
+ DFSF.setShadow(&I, Res);
}
void DFSanVisitor::visitAllocaInst(AllocaInst &I) {
@@ -1848,20 +1848,20 @@ void DFSanVisitor::visitAllocaInst(AllocaInst &I) {
}
if (AllLoadsStores) {
IRBuilder<> IRB(&I);
- DFSF.AllocaShadowMap[&I] = IRB.CreateAlloca(DFSF.DFS.PrimitiveShadowTy);
+ DFSF.AllocaShadowMap[&I] = IRB.CreateAlloca(DFSF.DFS.PrimitiveShadowTy);
}
- DFSF.setShadow(&I, DFSF.DFS.ZeroPrimitiveShadow);
+ DFSF.setShadow(&I, DFSF.DFS.ZeroPrimitiveShadow);
}
void DFSanVisitor::visitSelectInst(SelectInst &I) {
Value *CondShadow = DFSF.getShadow(I.getCondition());
Value *TrueShadow = DFSF.getShadow(I.getTrueValue());
Value *FalseShadow = DFSF.getShadow(I.getFalseValue());
- Value *ShadowSel = nullptr;
+ Value *ShadowSel = nullptr;
if (isa<VectorType>(I.getCondition()->getType())) {
- ShadowSel = DFSF.combineShadowsThenConvert(I.getType(), TrueShadow,
- FalseShadow, &I);
+ ShadowSel = DFSF.combineShadowsThenConvert(I.getType(), TrueShadow,
+ FalseShadow, &I);
} else {
if (TrueShadow == FalseShadow) {
ShadowSel = TrueShadow;
@@ -1870,10 +1870,10 @@ void DFSanVisitor::visitSelectInst(SelectInst &I) {
SelectInst::Create(I.getCondition(), TrueShadow, FalseShadow, "", &I);
}
}
- DFSF.setShadow(&I, ClTrackSelectControlFlow
- ? DFSF.combineShadowsThenConvert(
- I.getType(), CondShadow, ShadowSel, &I)
- : ShadowSel);
+ DFSF.setShadow(&I, ClTrackSelectControlFlow
+ ? DFSF.combineShadowsThenConvert(
+ I.getType(), CondShadow, ShadowSel, &I)
+ : ShadowSel);
}
void DFSanVisitor::visitMemSetInst(MemSetInst &I) {
@@ -1917,15 +1917,15 @@ void DFSanVisitor::visitReturnInst(ReturnInst &RI) {
case DataFlowSanitizer::IA_TLS: {
Value *S = DFSF.getShadow(RI.getReturnValue());
IRBuilder<> IRB(&RI);
- Type *RT = DFSF.F->getFunctionType()->getReturnType();
- unsigned Size =
- getDataLayout().getTypeAllocSize(DFSF.DFS.getShadowTy(RT));
- if (Size <= kRetvalTLSSize) {
- // If the size overflows, stores nothing. At callsite, oversized return
- // shadows are set to zero.
- IRB.CreateAlignedStore(S, DFSF.getRetvalTLS(RT, IRB),
- kShadowTLSAlignment);
- }
+ Type *RT = DFSF.F->getFunctionType()->getReturnType();
+ unsigned Size =
+ getDataLayout().getTypeAllocSize(DFSF.DFS.getShadowTy(RT));
+ if (Size <= kRetvalTLSSize) {
+ // If the size overflows, stores nothing. At callsite, oversized return
+ // shadows are set to zero.
+ IRB.CreateAlignedStore(S, DFSF.getRetvalTLS(RT, IRB),
+ kShadowTLSAlignment);
+ }
break;
}
case DataFlowSanitizer::IA_Args: {
@@ -1965,11 +1965,11 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
CB.setCalledFunction(F);
IRB.CreateCall(DFSF.DFS.DFSanUnimplementedFn,
IRB.CreateGlobalStringPtr(F->getName()));
- DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
+ DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
return;
case DataFlowSanitizer::WK_Discard:
CB.setCalledFunction(F);
- DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
+ DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
return;
case DataFlowSanitizer::WK_Functional:
CB.setCalledFunction(F);
@@ -2021,11 +2021,11 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
i = CB.arg_begin();
const unsigned ShadowArgStart = Args.size();
for (unsigned n = FT->getNumParams(); n != 0; ++i, --n)
- Args.push_back(
- DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*i), &CB));
+ Args.push_back(
+ DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*i), &CB));
if (FT->isVarArg()) {
- auto *LabelVATy = ArrayType::get(DFSF.DFS.PrimitiveShadowTy,
+ auto *LabelVATy = ArrayType::get(DFSF.DFS.PrimitiveShadowTy,
CB.arg_size() - FT->getNumParams());
auto *LabelVAAlloca = new AllocaInst(
LabelVATy, getDataLayout().getAllocaAddrSpace(),
@@ -2033,9 +2033,9 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
for (unsigned n = 0; i != CB.arg_end(); ++i, ++n) {
auto LabelVAPtr = IRB.CreateStructGEP(LabelVATy, LabelVAAlloca, n);
- IRB.CreateStore(
- DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*i), &CB),
- LabelVAPtr);
+ IRB.CreateStore(
+ DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*i), &CB),
+ LabelVAPtr);
}
Args.push_back(IRB.CreateStructGEP(LabelVATy, LabelVAAlloca, 0));
@@ -2044,9 +2044,9 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
if (!FT->getReturnType()->isVoidTy()) {
if (!DFSF.LabelReturnAlloca) {
DFSF.LabelReturnAlloca =
- new AllocaInst(DFSF.DFS.PrimitiveShadowTy,
- getDataLayout().getAllocaAddrSpace(),
- "labelreturn", &DFSF.F->getEntryBlock().front());
+ new AllocaInst(DFSF.DFS.PrimitiveShadowTy,
+ getDataLayout().getAllocaAddrSpace(),
+ "labelreturn", &DFSF.F->getEntryBlock().front());
}
Args.push_back(DFSF.LabelReturnAlloca);
}
@@ -2061,19 +2061,19 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
// Update the parameter attributes of the custom call instruction to
// zero extend the shadow parameters. This is required for targets
- // which consider PrimitiveShadowTy an illegal type.
+ // which consider PrimitiveShadowTy an illegal type.
for (unsigned n = 0; n < FT->getNumParams(); n++) {
const unsigned ArgNo = ShadowArgStart + n;
- if (CustomCI->getArgOperand(ArgNo)->getType() ==
- DFSF.DFS.PrimitiveShadowTy)
+ if (CustomCI->getArgOperand(ArgNo)->getType() ==
+ DFSF.DFS.PrimitiveShadowTy)
CustomCI->addParamAttr(ArgNo, Attribute::ZExt);
}
if (!FT->getReturnType()->isVoidTy()) {
- LoadInst *LabelLoad = IRB.CreateLoad(DFSF.DFS.PrimitiveShadowTy,
- DFSF.LabelReturnAlloca);
- DFSF.setShadow(CustomCI, DFSF.expandFromPrimitiveShadow(
- FT->getReturnType(), LabelLoad, &CB));
+ LoadInst *LabelLoad = IRB.CreateLoad(DFSF.DFS.PrimitiveShadowTy,
+ DFSF.LabelReturnAlloca);
+ DFSF.setShadow(CustomCI, DFSF.expandFromPrimitiveShadow(
+ FT->getReturnType(), LabelLoad, &CB));
}
CI->replaceAllUsesWith(CustomCI);
@@ -2086,20 +2086,20 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
FunctionType *FT = CB.getFunctionType();
if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) {
- unsigned ArgOffset = 0;
- const DataLayout &DL = getDataLayout();
- for (unsigned I = 0, N = FT->getNumParams(); I != N; ++I) {
- unsigned Size =
- DL.getTypeAllocSize(DFSF.DFS.getShadowTy(FT->getParamType(I)));
- // Stop storing if arguments' size overflows. Inside a function, arguments
- // after overflow have zero shadow values.
- if (ArgOffset + Size > kArgTLSSize)
- break;
- IRB.CreateAlignedStore(
- DFSF.getShadow(CB.getArgOperand(I)),
- DFSF.getArgTLS(FT->getParamType(I), ArgOffset, IRB),
- kShadowTLSAlignment);
- ArgOffset += alignTo(Size, kShadowTLSAlignment);
+ unsigned ArgOffset = 0;
+ const DataLayout &DL = getDataLayout();
+ for (unsigned I = 0, N = FT->getNumParams(); I != N; ++I) {
+ unsigned Size =
+ DL.getTypeAllocSize(DFSF.DFS.getShadowTy(FT->getParamType(I)));
+ // Stop storing if arguments' size overflows. Inside a function, arguments
+ // after overflow have zero shadow values.
+ if (ArgOffset + Size > kArgTLSSize)
+ break;
+ IRB.CreateAlignedStore(
+ DFSF.getShadow(CB.getArgOperand(I)),
+ DFSF.getArgTLS(FT->getParamType(I), ArgOffset, IRB),
+ kShadowTLSAlignment);
+ ArgOffset += alignTo(Size, kShadowTLSAlignment);
}
}
@@ -2120,19 +2120,19 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) {
IRBuilder<> NextIRB(Next);
- const DataLayout &DL = getDataLayout();
- unsigned Size = DL.getTypeAllocSize(DFSF.DFS.getShadowTy(&CB));
- if (Size > kRetvalTLSSize) {
- // Set overflowed return shadow to be zero.
- DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
- } else {
- LoadInst *LI = NextIRB.CreateAlignedLoad(
- DFSF.DFS.getShadowTy(&CB), DFSF.getRetvalTLS(CB.getType(), NextIRB),
- kShadowTLSAlignment, "_dfsret");
- DFSF.SkipInsts.insert(LI);
- DFSF.setShadow(&CB, LI);
- DFSF.NonZeroChecks.push_back(LI);
- }
+ const DataLayout &DL = getDataLayout();
+ unsigned Size = DL.getTypeAllocSize(DFSF.DFS.getShadowTy(&CB));
+ if (Size > kRetvalTLSSize) {
+ // Set overflowed return shadow to be zero.
+ DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
+ } else {
+ LoadInst *LI = NextIRB.CreateAlignedLoad(
+ DFSF.DFS.getShadowTy(&CB), DFSF.getRetvalTLS(CB.getType(), NextIRB),
+ kShadowTLSAlignment, "_dfsret");
+ DFSF.SkipInsts.insert(LI);
+ DFSF.setShadow(&CB, LI);
+ DFSF.NonZeroChecks.push_back(LI);
+ }
}
}
@@ -2154,8 +2154,8 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
if (FT->isVarArg()) {
unsigned VarArgSize = CB.arg_size() - FT->getNumParams();
- ArrayType *VarArgArrayTy =
- ArrayType::get(DFSF.DFS.PrimitiveShadowTy, VarArgSize);
+ ArrayType *VarArgArrayTy =
+ ArrayType::get(DFSF.DFS.PrimitiveShadowTy, VarArgSize);
AllocaInst *VarArgShadow =
new AllocaInst(VarArgArrayTy, getDataLayout().getAllocaAddrSpace(),
"", &DFSF.F->getEntryBlock().front());
@@ -2196,12 +2196,12 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
}
void DFSanVisitor::visitPHINode(PHINode &PN) {
- Type *ShadowTy = DFSF.DFS.getShadowTy(&PN);
+ Type *ShadowTy = DFSF.DFS.getShadowTy(&PN);
PHINode *ShadowPN =
- PHINode::Create(ShadowTy, PN.getNumIncomingValues(), "", &PN);
+ PHINode::Create(ShadowTy, PN.getNumIncomingValues(), "", &PN);
// Give the shadow phi node valid predecessors to fool SplitEdge into working.
- Value *UndefShadow = UndefValue::get(ShadowTy);
+ Value *UndefShadow = UndefValue::get(ShadowTy);
for (PHINode::block_iterator i = PN.block_begin(), e = PN.block_end(); i != e;
++i) {
ShadowPN->addIncoming(UndefShadow, *i);
@@ -2210,39 +2210,39 @@ void DFSanVisitor::visitPHINode(PHINode &PN) {
DFSF.PHIFixups.push_back(std::make_pair(&PN, ShadowPN));
DFSF.setShadow(&PN, ShadowPN);
}
-
-namespace {
-class DataFlowSanitizerLegacyPass : public ModulePass {
-private:
- std::vector<std::string> ABIListFiles;
-
-public:
- static char ID;
-
- DataFlowSanitizerLegacyPass(
- const std::vector<std::string> &ABIListFiles = std::vector<std::string>())
- : ModulePass(ID), ABIListFiles(ABIListFiles) {}
-
- bool runOnModule(Module &M) override {
- return DataFlowSanitizer(ABIListFiles).runImpl(M);
- }
-};
-} // namespace
-
-char DataFlowSanitizerLegacyPass::ID;
-
-INITIALIZE_PASS(DataFlowSanitizerLegacyPass, "dfsan",
- "DataFlowSanitizer: dynamic data flow analysis.", false, false)
-
-ModulePass *llvm::createDataFlowSanitizerLegacyPassPass(
- const std::vector<std::string> &ABIListFiles) {
- return new DataFlowSanitizerLegacyPass(ABIListFiles);
-}
-
-PreservedAnalyses DataFlowSanitizerPass::run(Module &M,
- ModuleAnalysisManager &AM) {
- if (DataFlowSanitizer(ABIListFiles).runImpl(M)) {
- return PreservedAnalyses::none();
- }
- return PreservedAnalyses::all();
-}
+
+namespace {
+class DataFlowSanitizerLegacyPass : public ModulePass {
+private:
+ std::vector<std::string> ABIListFiles;
+
+public:
+ static char ID;
+
+ DataFlowSanitizerLegacyPass(
+ const std::vector<std::string> &ABIListFiles = std::vector<std::string>())
+ : ModulePass(ID), ABIListFiles(ABIListFiles) {}
+
+ bool runOnModule(Module &M) override {
+ return DataFlowSanitizer(ABIListFiles).runImpl(M);
+ }
+};
+} // namespace
+
+char DataFlowSanitizerLegacyPass::ID;
+
+INITIALIZE_PASS(DataFlowSanitizerLegacyPass, "dfsan",
+ "DataFlowSanitizer: dynamic data flow analysis.", false, false)
+
+ModulePass *llvm::createDataFlowSanitizerLegacyPassPass(
+ const std::vector<std::string> &ABIListFiles) {
+ return new DataFlowSanitizerLegacyPass(ABIListFiles);
+}
+
+PreservedAnalyses DataFlowSanitizerPass::run(Module &M,
+ ModuleAnalysisManager &AM) {
+ if (DataFlowSanitizer(ABIListFiles).runImpl(M)) {
+ return PreservedAnalyses::none();
+ }
+ return PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/contrib/libs/llvm12/lib/Transforms/Instrumentation/GCOVProfiling.cpp
index 2d52317d0d..527644a69d 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -13,17 +13,17 @@
//
//===----------------------------------------------------------------------===//
-#include "CFGMST.h"
+#include "CFGMST.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Hashing.h"
-#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/Analysis/BlockFrequencyInfo.h"
-#include "llvm/Analysis/BranchProbabilityInfo.h"
+#include "llvm/Analysis/BlockFrequencyInfo.h"
+#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/CFG.h"
@@ -36,7 +36,7 @@
#include "llvm/IR/Module.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
-#include "llvm/Support/CRC.h"
+#include "llvm/Support/CRC.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
@@ -57,8 +57,8 @@ namespace endian = llvm::support::endian;
#define DEBUG_TYPE "insert-gcov-profiling"
enum : uint32_t {
- GCOV_ARC_ON_TREE = 1 << 0,
-
+ GCOV_ARC_ON_TREE = 1 << 0,
+
GCOV_TAG_FUNCTION = 0x01000000,
GCOV_TAG_BLOCKS = 0x01410000,
GCOV_TAG_ARCS = 0x01430000,
@@ -69,9 +69,9 @@ static cl::opt<std::string> DefaultGCOVVersion("default-gcov-version",
cl::init("408*"), cl::Hidden,
cl::ValueRequired);
-static cl::opt<bool> AtomicCounter("gcov-atomic-counter", cl::Hidden,
- cl::desc("Make counter updates atomic"));
-
+static cl::opt<bool> AtomicCounter("gcov-atomic-counter", cl::Hidden,
+ cl::desc("Make counter updates atomic"));
+
// Returns the number of words which will be used to represent this string.
static unsigned wordsOfString(StringRef s) {
// Length + NUL-terminated string + 0~3 padding NULs.
@@ -83,7 +83,7 @@ GCOVOptions GCOVOptions::getDefault() {
Options.EmitNotes = true;
Options.EmitData = true;
Options.NoRedZone = false;
- Options.Atomic = AtomicCounter;
+ Options.Atomic = AtomicCounter;
if (DefaultGCOVVersion.size() != 4) {
llvm::report_fatal_error(std::string("Invalid -default-gcov-version: ") +
@@ -101,8 +101,8 @@ public:
GCOVProfiler() : GCOVProfiler(GCOVOptions::getDefault()) {}
GCOVProfiler(const GCOVOptions &Opts) : Options(Opts) {}
bool
- runOnModule(Module &M, function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
- function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
+ runOnModule(Module &M, function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
+ function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
std::function<const TargetLibraryInfo &(Function &F)> GetTLI);
void write(uint32_t i) {
@@ -119,14 +119,14 @@ public:
private:
// Create the .gcno files for the Module based on DebugInfo.
- bool
- emitProfileNotes(NamedMDNode *CUNode, bool HasExecOrFork,
- function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
- function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
- function_ref<const TargetLibraryInfo &(Function &F)> GetTLI);
+ bool
+ emitProfileNotes(NamedMDNode *CUNode, bool HasExecOrFork,
+ function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
+ function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
+ function_ref<const TargetLibraryInfo &(Function &F)> GetTLI);
- void emitGlobalConstructor(
- SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP);
+ void emitGlobalConstructor(
+ SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP);
bool isFunctionInstrumented(const Function &F);
std::vector<Regex> createRegexesFromString(StringRef RegexesStr);
@@ -164,7 +164,7 @@ private:
SmallVector<std::unique_ptr<GCOVFunction>, 16> Funcs;
std::vector<Regex> FilterRe;
std::vector<Regex> ExcludeRe;
- DenseSet<const BasicBlock *> ExecBlocks;
+ DenseSet<const BasicBlock *> ExecBlocks;
StringMap<bool> InstrumentedFiles;
};
@@ -180,68 +180,68 @@ public:
StringRef getPassName() const override { return "GCOV Profiler"; }
bool runOnModule(Module &M) override {
- auto GetBFI = [this](Function &F) {
- return &this->getAnalysis<BlockFrequencyInfoWrapperPass>(F).getBFI();
- };
- auto GetBPI = [this](Function &F) {
- return &this->getAnalysis<BranchProbabilityInfoWrapperPass>(F).getBPI();
- };
- auto GetTLI = [this](Function &F) -> const TargetLibraryInfo & {
- return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
- };
- return Profiler.runOnModule(M, GetBFI, GetBPI, GetTLI);
+ auto GetBFI = [this](Function &F) {
+ return &this->getAnalysis<BlockFrequencyInfoWrapperPass>(F).getBFI();
+ };
+ auto GetBPI = [this](Function &F) {
+ return &this->getAnalysis<BranchProbabilityInfoWrapperPass>(F).getBPI();
+ };
+ auto GetTLI = [this](Function &F) -> const TargetLibraryInfo & {
+ return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
+ };
+ return Profiler.runOnModule(M, GetBFI, GetBPI, GetTLI);
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<BlockFrequencyInfoWrapperPass>();
+ AU.addRequired<BlockFrequencyInfoWrapperPass>();
AU.addRequired<TargetLibraryInfoWrapperPass>();
}
private:
GCOVProfiler Profiler;
};
-
-struct BBInfo {
- BBInfo *Group;
- uint32_t Index;
- uint32_t Rank = 0;
-
- BBInfo(unsigned Index) : Group(this), Index(Index) {}
- const std::string infoString() const {
- return (Twine("Index=") + Twine(Index)).str();
- }
-};
-
-struct Edge {
- // This class implements the CFG edges. Note the CFG can be a multi-graph.
- // So there might be multiple edges with same SrcBB and DestBB.
- const BasicBlock *SrcBB;
- const BasicBlock *DestBB;
- uint64_t Weight;
- BasicBlock *Place = nullptr;
- uint32_t SrcNumber, DstNumber;
- bool InMST = false;
- bool Removed = false;
- bool IsCritical = false;
-
- Edge(const BasicBlock *Src, const BasicBlock *Dest, uint64_t W = 1)
- : SrcBB(Src), DestBB(Dest), Weight(W) {}
-
- // Return the information string of an edge.
- const std::string infoString() const {
- return (Twine(Removed ? "-" : " ") + (InMST ? " " : "*") +
- (IsCritical ? "c" : " ") + " W=" + Twine(Weight))
- .str();
- }
-};
+
+struct BBInfo {
+ BBInfo *Group;
+ uint32_t Index;
+ uint32_t Rank = 0;
+
+ BBInfo(unsigned Index) : Group(this), Index(Index) {}
+ const std::string infoString() const {
+ return (Twine("Index=") + Twine(Index)).str();
+ }
+};
+
+struct Edge {
+ // This class implements the CFG edges. Note the CFG can be a multi-graph.
+ // So there might be multiple edges with same SrcBB and DestBB.
+ const BasicBlock *SrcBB;
+ const BasicBlock *DestBB;
+ uint64_t Weight;
+ BasicBlock *Place = nullptr;
+ uint32_t SrcNumber, DstNumber;
+ bool InMST = false;
+ bool Removed = false;
+ bool IsCritical = false;
+
+ Edge(const BasicBlock *Src, const BasicBlock *Dest, uint64_t W = 1)
+ : SrcBB(Src), DestBB(Dest), Weight(W) {}
+
+ // Return the information string of an edge.
+ const std::string infoString() const {
+ return (Twine(Removed ? "-" : " ") + (InMST ? " " : "*") +
+ (IsCritical ? "c" : " ") + " W=" + Twine(Weight))
+ .str();
+ }
+};
}
char GCOVProfilerLegacyPass::ID = 0;
INITIALIZE_PASS_BEGIN(
GCOVProfilerLegacyPass, "insert-gcov-profiling",
"Insert instrumentation for GCOV profiling", false, false)
-INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_END(
GCOVProfilerLegacyPass, "insert-gcov-profiling",
@@ -326,8 +326,8 @@ namespace {
return LinesByFile.try_emplace(Filename, P, Filename).first->second;
}
- void addEdge(GCOVBlock &Successor, uint32_t Flags) {
- OutEdges.emplace_back(&Successor, Flags);
+ void addEdge(GCOVBlock &Successor, uint32_t Flags) {
+ OutEdges.emplace_back(&Successor, Flags);
}
void writeOut() {
@@ -360,10 +360,10 @@ namespace {
assert(OutEdges.empty());
}
- uint32_t Number;
- SmallVector<std::pair<GCOVBlock *, uint32_t>, 4> OutEdges;
-
- private:
+ uint32_t Number;
+ SmallVector<std::pair<GCOVBlock *, uint32_t>, 4> OutEdges;
+
+ private:
friend class GCOVFunction;
GCOVBlock(GCOVProfiler *P, uint32_t Number)
@@ -380,11 +380,11 @@ namespace {
GCOVFunction(GCOVProfiler *P, Function *F, const DISubprogram *SP,
unsigned EndLine, uint32_t Ident, int Version)
: GCOVRecord(P), SP(SP), EndLine(EndLine), Ident(Ident),
- Version(Version), EntryBlock(P, 0), ReturnBlock(P, 1) {
+ Version(Version), EntryBlock(P, 0), ReturnBlock(P, 1) {
LLVM_DEBUG(dbgs() << "Function: " << getFunctionName(SP) << "\n");
bool ExitBlockBeforeBody = Version >= 48;
- uint32_t i = ExitBlockBeforeBody ? 2 : 1;
- for (BasicBlock &BB : *F)
+ uint32_t i = ExitBlockBeforeBody ? 2 : 1;
+ for (BasicBlock &BB : *F)
Blocks.insert(std::make_pair(&BB, GCOVBlock(P, i++)));
if (!ExitBlockBeforeBody)
ReturnBlock.Number = i;
@@ -396,11 +396,11 @@ namespace {
FuncChecksum = hash_value(FunctionNameAndLine);
}
- GCOVBlock &getBlock(const BasicBlock *BB) {
- return Blocks.find(const_cast<BasicBlock *>(BB))->second;
+ GCOVBlock &getBlock(const BasicBlock *BB) {
+ return Blocks.find(const_cast<BasicBlock *>(BB))->second;
}
- GCOVBlock &getEntryBlock() { return EntryBlock; }
+ GCOVBlock &getEntryBlock() { return EntryBlock; }
GCOVBlock &getReturnBlock() {
return ReturnBlock;
}
@@ -443,52 +443,52 @@ namespace {
// Emit count of blocks.
write(GCOV_TAG_BLOCKS);
if (Version < 80) {
- write(Blocks.size() + 2);
- for (int i = Blocks.size() + 2; i; --i)
+ write(Blocks.size() + 2);
+ for (int i = Blocks.size() + 2; i; --i)
write(0);
} else {
write(1);
- write(Blocks.size() + 2);
+ write(Blocks.size() + 2);
}
LLVM_DEBUG(dbgs() << (Blocks.size() + 1) << " blocks\n");
// Emit edges between blocks.
- const uint32_t Outgoing = EntryBlock.OutEdges.size();
- if (Outgoing) {
- write(GCOV_TAG_ARCS);
- write(Outgoing * 2 + 1);
- write(EntryBlock.Number);
- for (const auto &E : EntryBlock.OutEdges) {
- write(E.first->Number);
- write(E.second);
- }
- }
- for (auto &It : Blocks) {
- const GCOVBlock &Block = It.second;
+ const uint32_t Outgoing = EntryBlock.OutEdges.size();
+ if (Outgoing) {
+ write(GCOV_TAG_ARCS);
+ write(Outgoing * 2 + 1);
+ write(EntryBlock.Number);
+ for (const auto &E : EntryBlock.OutEdges) {
+ write(E.first->Number);
+ write(E.second);
+ }
+ }
+ for (auto &It : Blocks) {
+ const GCOVBlock &Block = It.second;
if (Block.OutEdges.empty()) continue;
write(GCOV_TAG_ARCS);
write(Block.OutEdges.size() * 2 + 1);
write(Block.Number);
- for (const auto &E : Block.OutEdges) {
- write(E.first->Number);
- write(E.second);
+ for (const auto &E : Block.OutEdges) {
+ write(E.first->Number);
+ write(E.second);
}
}
// Emit lines for each block.
- for (auto &It : Blocks)
- It.second.writeOut();
+ for (auto &It : Blocks)
+ It.second.writeOut();
}
- public:
+ public:
const DISubprogram *SP;
unsigned EndLine;
uint32_t Ident;
uint32_t FuncChecksum;
int Version;
- MapVector<BasicBlock *, GCOVBlock> Blocks;
- GCOVBlock EntryBlock;
+ MapVector<BasicBlock *, GCOVBlock> Blocks;
+ GCOVBlock EntryBlock;
GCOVBlock ReturnBlock;
};
}
@@ -602,23 +602,23 @@ std::string GCOVProfiler::mangleName(const DICompileUnit *CU,
}
bool GCOVProfiler::runOnModule(
- Module &M, function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
- function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
- std::function<const TargetLibraryInfo &(Function &F)> GetTLI) {
+ Module &M, function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
+ function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
+ std::function<const TargetLibraryInfo &(Function &F)> GetTLI) {
this->M = &M;
this->GetTLI = std::move(GetTLI);
Ctx = &M.getContext();
- NamedMDNode *CUNode = M.getNamedMetadata("llvm.dbg.cu");
- if (!CUNode || (!Options.EmitNotes && !Options.EmitData))
- return false;
+ NamedMDNode *CUNode = M.getNamedMetadata("llvm.dbg.cu");
+ if (!CUNode || (!Options.EmitNotes && !Options.EmitData))
+ return false;
+
+ bool HasExecOrFork = AddFlushBeforeForkAndExec();
- bool HasExecOrFork = AddFlushBeforeForkAndExec();
-
FilterRe = createRegexesFromString(Options.Filter);
ExcludeRe = createRegexesFromString(Options.Exclude);
- emitProfileNotes(CUNode, HasExecOrFork, GetBFI, GetBPI, this->GetTLI);
- return true;
+ emitProfileNotes(CUNode, HasExecOrFork, GetBFI, GetBPI, this->GetTLI);
+ return true;
}
PreservedAnalyses GCOVProfilerPass::run(Module &M,
@@ -628,17 +628,17 @@ PreservedAnalyses GCOVProfilerPass::run(Module &M,
FunctionAnalysisManager &FAM =
AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
- auto GetBFI = [&FAM](Function &F) {
- return &FAM.getResult<BlockFrequencyAnalysis>(F);
- };
- auto GetBPI = [&FAM](Function &F) {
- return &FAM.getResult<BranchProbabilityAnalysis>(F);
- };
- auto GetTLI = [&FAM](Function &F) -> const TargetLibraryInfo & {
- return FAM.getResult<TargetLibraryAnalysis>(F);
- };
-
- if (!Profiler.runOnModule(M, GetBFI, GetBPI, GetTLI))
+ auto GetBFI = [&FAM](Function &F) {
+ return &FAM.getResult<BlockFrequencyAnalysis>(F);
+ };
+ auto GetBPI = [&FAM](Function &F) {
+ return &FAM.getResult<BranchProbabilityAnalysis>(F);
+ };
+ auto GetTLI = [&FAM](Function &F) -> const TargetLibraryInfo & {
+ return FAM.getResult<TargetLibraryAnalysis>(F);
+ };
+
+ if (!Profiler.runOnModule(M, GetBFI, GetBPI, GetTLI))
return PreservedAnalyses::all();
return PreservedAnalyses::none();
@@ -744,7 +744,7 @@ bool GCOVProfiler::AddFlushBeforeForkAndExec() {
// dumped
FunctionCallee ResetF = M->getOrInsertFunction("llvm_reset_counters", FTy);
Builder.CreateCall(ResetF)->setDebugLoc(Loc);
- ExecBlocks.insert(Parent);
+ ExecBlocks.insert(Parent);
Parent->splitBasicBlock(NextInst);
Parent->back().setDebugLoc(Loc);
}
@@ -752,67 +752,67 @@ bool GCOVProfiler::AddFlushBeforeForkAndExec() {
return !Forks.empty() || !Execs.empty();
}
-static BasicBlock *getInstrBB(CFGMST<Edge, BBInfo> &MST, Edge &E,
- const DenseSet<const BasicBlock *> &ExecBlocks) {
- if (E.InMST || E.Removed)
- return nullptr;
-
- BasicBlock *SrcBB = const_cast<BasicBlock *>(E.SrcBB);
- BasicBlock *DestBB = const_cast<BasicBlock *>(E.DestBB);
- // For a fake edge, instrument the real BB.
- if (SrcBB == nullptr)
- return DestBB;
- if (DestBB == nullptr)
- return SrcBB;
-
- auto CanInstrument = [](BasicBlock *BB) -> BasicBlock * {
- // There are basic blocks (such as catchswitch) cannot be instrumented.
- // If the returned first insertion point is the end of BB, skip this BB.
- if (BB->getFirstInsertionPt() == BB->end())
- return nullptr;
- return BB;
- };
-
- // Instrument the SrcBB if it has a single successor,
- // otherwise, the DestBB if this is not a critical edge.
- Instruction *TI = SrcBB->getTerminator();
- if (TI->getNumSuccessors() <= 1 && !ExecBlocks.count(SrcBB))
- return CanInstrument(SrcBB);
- if (!E.IsCritical)
- return CanInstrument(DestBB);
-
- // Some IndirectBr critical edges cannot be split by the previous
- // SplitIndirectBrCriticalEdges call. Bail out.
- const unsigned SuccNum = GetSuccessorNumber(SrcBB, DestBB);
- BasicBlock *InstrBB =
- isa<IndirectBrInst>(TI) ? nullptr : SplitCriticalEdge(TI, SuccNum);
- if (!InstrBB)
- return nullptr;
-
- MST.addEdge(SrcBB, InstrBB, 0);
- MST.addEdge(InstrBB, DestBB, 0).InMST = true;
- E.Removed = true;
-
- return CanInstrument(InstrBB);
-}
-
-#ifndef NDEBUG
-static void dumpEdges(CFGMST<Edge, BBInfo> &MST, GCOVFunction &GF) {
- size_t ID = 0;
- for (auto &E : make_pointee_range(MST.AllEdges)) {
- GCOVBlock &Src = E.SrcBB ? GF.getBlock(E.SrcBB) : GF.getEntryBlock();
- GCOVBlock &Dst = E.DestBB ? GF.getBlock(E.DestBB) : GF.getReturnBlock();
- dbgs() << " Edge " << ID++ << ": " << Src.Number << "->" << Dst.Number
- << E.infoString() << "\n";
- }
-}
-#endif
-
-bool GCOVProfiler::emitProfileNotes(
- NamedMDNode *CUNode, bool HasExecOrFork,
- function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
- function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
- function_ref<const TargetLibraryInfo &(Function &F)> GetTLI) {
+static BasicBlock *getInstrBB(CFGMST<Edge, BBInfo> &MST, Edge &E,
+ const DenseSet<const BasicBlock *> &ExecBlocks) {
+ if (E.InMST || E.Removed)
+ return nullptr;
+
+ BasicBlock *SrcBB = const_cast<BasicBlock *>(E.SrcBB);
+ BasicBlock *DestBB = const_cast<BasicBlock *>(E.DestBB);
+ // For a fake edge, instrument the real BB.
+ if (SrcBB == nullptr)
+ return DestBB;
+ if (DestBB == nullptr)
+ return SrcBB;
+
+ auto CanInstrument = [](BasicBlock *BB) -> BasicBlock * {
+ // There are basic blocks (such as catchswitch) cannot be instrumented.
+ // If the returned first insertion point is the end of BB, skip this BB.
+ if (BB->getFirstInsertionPt() == BB->end())
+ return nullptr;
+ return BB;
+ };
+
+ // Instrument the SrcBB if it has a single successor,
+ // otherwise, the DestBB if this is not a critical edge.
+ Instruction *TI = SrcBB->getTerminator();
+ if (TI->getNumSuccessors() <= 1 && !ExecBlocks.count(SrcBB))
+ return CanInstrument(SrcBB);
+ if (!E.IsCritical)
+ return CanInstrument(DestBB);
+
+ // Some IndirectBr critical edges cannot be split by the previous
+ // SplitIndirectBrCriticalEdges call. Bail out.
+ const unsigned SuccNum = GetSuccessorNumber(SrcBB, DestBB);
+ BasicBlock *InstrBB =
+ isa<IndirectBrInst>(TI) ? nullptr : SplitCriticalEdge(TI, SuccNum);
+ if (!InstrBB)
+ return nullptr;
+
+ MST.addEdge(SrcBB, InstrBB, 0);
+ MST.addEdge(InstrBB, DestBB, 0).InMST = true;
+ E.Removed = true;
+
+ return CanInstrument(InstrBB);
+}
+
+#ifndef NDEBUG
+static void dumpEdges(CFGMST<Edge, BBInfo> &MST, GCOVFunction &GF) {
+ size_t ID = 0;
+ for (auto &E : make_pointee_range(MST.AllEdges)) {
+ GCOVBlock &Src = E.SrcBB ? GF.getBlock(E.SrcBB) : GF.getEntryBlock();
+ GCOVBlock &Dst = E.DestBB ? GF.getBlock(E.DestBB) : GF.getReturnBlock();
+ dbgs() << " Edge " << ID++ << ": " << Src.Number << "->" << Dst.Number
+ << E.infoString() << "\n";
+ }
+}
+#endif
+
+bool GCOVProfiler::emitProfileNotes(
+ NamedMDNode *CUNode, bool HasExecOrFork,
+ function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
+ function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
+ function_ref<const TargetLibraryInfo &(Function &F)> GetTLI) {
int Version;
{
uint8_t c3 = Options.Version[0];
@@ -822,20 +822,20 @@ bool GCOVProfiler::emitProfileNotes(
: (c3 - '0') * 10 + c1 - '0';
}
- bool EmitGCDA = Options.EmitData;
- for (unsigned i = 0, e = CUNode->getNumOperands(); i != e; ++i) {
+ bool EmitGCDA = Options.EmitData;
+ for (unsigned i = 0, e = CUNode->getNumOperands(); i != e; ++i) {
// Each compile unit gets its own .gcno file. This means that whether we run
// this pass over the original .o's as they're produced, or run it after
// LTO, we'll generate the same .gcno files.
- auto *CU = cast<DICompileUnit>(CUNode->getOperand(i));
+ auto *CU = cast<DICompileUnit>(CUNode->getOperand(i));
// Skip module skeleton (and module) CUs.
if (CU->getDWOId())
continue;
- std::vector<uint8_t> EdgeDestinations;
- SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP;
+ std::vector<uint8_t> EdgeDestinations;
+ SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP;
Endian = M->getDataLayout().isLittleEndian() ? support::endianness::little
: support::endianness::big;
@@ -849,82 +849,82 @@ bool GCOVProfiler::emitProfileNotes(
// TODO: Functions using scope-based EH are currently not supported.
if (isUsingScopeBasedEH(F)) continue;
- // Add the function line number to the lines of the entry block
- // to have a counter for the function definition.
- uint32_t Line = SP->getLine();
- auto Filename = getFilename(SP);
-
- BranchProbabilityInfo *BPI = GetBPI(F);
- BlockFrequencyInfo *BFI = GetBFI(F);
-
- // Split indirectbr critical edges here before computing the MST rather
- // than later in getInstrBB() to avoid invalidating it.
- SplitIndirectBrCriticalEdges(F, BPI, BFI);
-
- CFGMST<Edge, BBInfo> MST(F, /*InstrumentFuncEntry_=*/false, BPI, BFI);
-
- // getInstrBB can split basic blocks and push elements to AllEdges.
- for (size_t I : llvm::seq<size_t>(0, MST.AllEdges.size())) {
- auto &E = *MST.AllEdges[I];
- // For now, disable spanning tree optimization when fork or exec* is
- // used.
- if (HasExecOrFork)
- E.InMST = false;
- E.Place = getInstrBB(MST, E, ExecBlocks);
- }
- // Basic blocks in F are finalized at this point.
+ // Add the function line number to the lines of the entry block
+ // to have a counter for the function definition.
+ uint32_t Line = SP->getLine();
+ auto Filename = getFilename(SP);
+
+ BranchProbabilityInfo *BPI = GetBPI(F);
+ BlockFrequencyInfo *BFI = GetBFI(F);
+
+ // Split indirectbr critical edges here before computing the MST rather
+ // than later in getInstrBB() to avoid invalidating it.
+ SplitIndirectBrCriticalEdges(F, BPI, BFI);
+
+ CFGMST<Edge, BBInfo> MST(F, /*InstrumentFuncEntry_=*/false, BPI, BFI);
+
+ // getInstrBB can split basic blocks and push elements to AllEdges.
+ for (size_t I : llvm::seq<size_t>(0, MST.AllEdges.size())) {
+ auto &E = *MST.AllEdges[I];
+ // For now, disable spanning tree optimization when fork or exec* is
+ // used.
+ if (HasExecOrFork)
+ E.InMST = false;
+ E.Place = getInstrBB(MST, E, ExecBlocks);
+ }
+ // Basic blocks in F are finalized at this point.
BasicBlock &EntryBlock = F.getEntryBlock();
Funcs.push_back(std::make_unique<GCOVFunction>(this, &F, SP, EndLine,
FunctionIdent++, Version));
GCOVFunction &Func = *Funcs.back();
- // Some non-tree edges are IndirectBr which cannot be split. Ignore them
- // as well.
- llvm::erase_if(MST.AllEdges, [](std::unique_ptr<Edge> &E) {
- return E->Removed || (!E->InMST && !E->Place);
- });
- const size_t Measured =
- std::stable_partition(
- MST.AllEdges.begin(), MST.AllEdges.end(),
- [](std::unique_ptr<Edge> &E) { return E->Place; }) -
- MST.AllEdges.begin();
- for (size_t I : llvm::seq<size_t>(0, Measured)) {
- Edge &E = *MST.AllEdges[I];
- GCOVBlock &Src =
- E.SrcBB ? Func.getBlock(E.SrcBB) : Func.getEntryBlock();
- GCOVBlock &Dst =
- E.DestBB ? Func.getBlock(E.DestBB) : Func.getReturnBlock();
- E.SrcNumber = Src.Number;
- E.DstNumber = Dst.Number;
- }
- std::stable_sort(
- MST.AllEdges.begin(), MST.AllEdges.begin() + Measured,
- [](const std::unique_ptr<Edge> &L, const std::unique_ptr<Edge> &R) {
- return L->SrcNumber != R->SrcNumber ? L->SrcNumber < R->SrcNumber
- : L->DstNumber < R->DstNumber;
- });
-
- for (const Edge &E : make_pointee_range(MST.AllEdges)) {
- GCOVBlock &Src =
- E.SrcBB ? Func.getBlock(E.SrcBB) : Func.getEntryBlock();
- GCOVBlock &Dst =
- E.DestBB ? Func.getBlock(E.DestBB) : Func.getReturnBlock();
- Src.addEdge(Dst, E.Place ? 0 : uint32_t(GCOV_ARC_ON_TREE));
- }
-
+ // Some non-tree edges are IndirectBr which cannot be split. Ignore them
+ // as well.
+ llvm::erase_if(MST.AllEdges, [](std::unique_ptr<Edge> &E) {
+ return E->Removed || (!E->InMST && !E->Place);
+ });
+ const size_t Measured =
+ std::stable_partition(
+ MST.AllEdges.begin(), MST.AllEdges.end(),
+ [](std::unique_ptr<Edge> &E) { return E->Place; }) -
+ MST.AllEdges.begin();
+ for (size_t I : llvm::seq<size_t>(0, Measured)) {
+ Edge &E = *MST.AllEdges[I];
+ GCOVBlock &Src =
+ E.SrcBB ? Func.getBlock(E.SrcBB) : Func.getEntryBlock();
+ GCOVBlock &Dst =
+ E.DestBB ? Func.getBlock(E.DestBB) : Func.getReturnBlock();
+ E.SrcNumber = Src.Number;
+ E.DstNumber = Dst.Number;
+ }
+ std::stable_sort(
+ MST.AllEdges.begin(), MST.AllEdges.begin() + Measured,
+ [](const std::unique_ptr<Edge> &L, const std::unique_ptr<Edge> &R) {
+ return L->SrcNumber != R->SrcNumber ? L->SrcNumber < R->SrcNumber
+ : L->DstNumber < R->DstNumber;
+ });
+
+ for (const Edge &E : make_pointee_range(MST.AllEdges)) {
+ GCOVBlock &Src =
+ E.SrcBB ? Func.getBlock(E.SrcBB) : Func.getEntryBlock();
+ GCOVBlock &Dst =
+ E.DestBB ? Func.getBlock(E.DestBB) : Func.getReturnBlock();
+ Src.addEdge(Dst, E.Place ? 0 : uint32_t(GCOV_ARC_ON_TREE));
+ }
+
// Artificial functions such as global initializers
if (!SP->isArtificial())
Func.getBlock(&EntryBlock).getFile(Filename).addLine(Line);
- LLVM_DEBUG(dumpEdges(MST, Func));
-
- for (auto &GB : Func.Blocks) {
- const BasicBlock &BB = *GB.first;
- auto &Block = GB.second;
- for (auto Succ : Block.OutEdges) {
- uint32_t Idx = Succ.first->Number;
- do EdgeDestinations.push_back(Idx & 255);
- while ((Idx >>= 8) > 0);
+ LLVM_DEBUG(dumpEdges(MST, Func));
+
+ for (auto &GB : Func.Blocks) {
+ const BasicBlock &BB = *GB.first;
+ auto &Block = GB.second;
+ for (auto Succ : Block.OutEdges) {
+ uint32_t Idx = Succ.first->Number;
+ do EdgeDestinations.push_back(Idx & 255);
+ while ((Idx >>= 8) > 0);
}
for (auto &I : BB) {
@@ -950,110 +950,110 @@ bool GCOVProfiler::emitProfileNotes(
}
Line = 0;
}
- if (EmitGCDA) {
- DISubprogram *SP = F.getSubprogram();
- ArrayType *CounterTy = ArrayType::get(Type::getInt64Ty(*Ctx), Measured);
- GlobalVariable *Counters = new GlobalVariable(
- *M, CounterTy, false, GlobalValue::InternalLinkage,
- Constant::getNullValue(CounterTy), "__llvm_gcov_ctr");
- CountersBySP.emplace_back(Counters, SP);
-
- for (size_t I : llvm::seq<size_t>(0, Measured)) {
- const Edge &E = *MST.AllEdges[I];
- IRBuilder<> Builder(E.Place, E.Place->getFirstInsertionPt());
- Value *V = Builder.CreateConstInBoundsGEP2_64(
- Counters->getValueType(), Counters, 0, I);
- if (Options.Atomic) {
- Builder.CreateAtomicRMW(AtomicRMWInst::Add, V, Builder.getInt64(1),
- AtomicOrdering::Monotonic);
- } else {
- Value *Count =
- Builder.CreateLoad(Builder.getInt64Ty(), V, "gcov_ctr");
- Count = Builder.CreateAdd(Count, Builder.getInt64(1));
- Builder.CreateStore(Count, V);
- }
- }
- }
+ if (EmitGCDA) {
+ DISubprogram *SP = F.getSubprogram();
+ ArrayType *CounterTy = ArrayType::get(Type::getInt64Ty(*Ctx), Measured);
+ GlobalVariable *Counters = new GlobalVariable(
+ *M, CounterTy, false, GlobalValue::InternalLinkage,
+ Constant::getNullValue(CounterTy), "__llvm_gcov_ctr");
+ CountersBySP.emplace_back(Counters, SP);
+
+ for (size_t I : llvm::seq<size_t>(0, Measured)) {
+ const Edge &E = *MST.AllEdges[I];
+ IRBuilder<> Builder(E.Place, E.Place->getFirstInsertionPt());
+ Value *V = Builder.CreateConstInBoundsGEP2_64(
+ Counters->getValueType(), Counters, 0, I);
+ if (Options.Atomic) {
+ Builder.CreateAtomicRMW(AtomicRMWInst::Add, V, Builder.getInt64(1),
+ AtomicOrdering::Monotonic);
+ } else {
+ Value *Count =
+ Builder.CreateLoad(Builder.getInt64Ty(), V, "gcov_ctr");
+ Count = Builder.CreateAdd(Count, Builder.getInt64(1));
+ Builder.CreateStore(Count, V);
+ }
+ }
+ }
}
char Tmp[4];
- JamCRC JC;
- JC.update(EdgeDestinations);
- uint32_t Stamp = JC.getCRC();
+ JamCRC JC;
+ JC.update(EdgeDestinations);
+ uint32_t Stamp = JC.getCRC();
FileChecksums.push_back(Stamp);
- if (Options.EmitNotes) {
- std::error_code EC;
- raw_fd_ostream out(mangleName(CU, GCovFileType::GCNO), EC,
- sys::fs::OF_None);
- if (EC) {
- Ctx->emitError(
- Twine("failed to open coverage notes file for writing: ") +
- EC.message());
+ if (Options.EmitNotes) {
+ std::error_code EC;
+ raw_fd_ostream out(mangleName(CU, GCovFileType::GCNO), EC,
+ sys::fs::OF_None);
+ if (EC) {
+ Ctx->emitError(
+ Twine("failed to open coverage notes file for writing: ") +
+ EC.message());
continue;
}
- os = &out;
- if (Endian == support::endianness::big) {
- out.write("gcno", 4);
- out.write(Options.Version, 4);
- } else {
- out.write("oncg", 4);
- std::reverse_copy(Options.Version, Options.Version + 4, Tmp);
- out.write(Tmp, 4);
- }
- write(Stamp);
- if (Version >= 90)
- writeString(""); // unuseful current_working_directory
- if (Version >= 80)
- write(0); // unuseful has_unexecuted_blocks
-
- for (auto &Func : Funcs)
- Func->writeOut(Stamp);
-
- write(0);
- write(0);
- out.close();
- }
-
- if (EmitGCDA) {
- emitGlobalConstructor(CountersBySP);
- EmitGCDA = false;
+ os = &out;
+ if (Endian == support::endianness::big) {
+ out.write("gcno", 4);
+ out.write(Options.Version, 4);
+ } else {
+ out.write("oncg", 4);
+ std::reverse_copy(Options.Version, Options.Version + 4, Tmp);
+ out.write(Tmp, 4);
+ }
+ write(Stamp);
+ if (Version >= 90)
+ writeString(""); // unuseful current_working_directory
+ if (Version >= 80)
+ write(0); // unuseful has_unexecuted_blocks
+
+ for (auto &Func : Funcs)
+ Func->writeOut(Stamp);
+
+ write(0);
+ write(0);
+ out.close();
+ }
+
+ if (EmitGCDA) {
+ emitGlobalConstructor(CountersBySP);
+ EmitGCDA = false;
}
- }
- return true;
-}
-
-void GCOVProfiler::emitGlobalConstructor(
- SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP) {
- Function *WriteoutF = insertCounterWriteout(CountersBySP);
- Function *ResetF = insertReset(CountersBySP);
-
- // Create a small bit of code that registers the "__llvm_gcov_writeout" to
- // be executed at exit and the "__llvm_gcov_flush" function to be executed
- // when "__gcov_flush" is called.
- FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
- Function *F = Function::Create(FTy, GlobalValue::InternalLinkage,
- "__llvm_gcov_init", M);
- F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
- F->setLinkage(GlobalValue::InternalLinkage);
- F->addFnAttr(Attribute::NoInline);
- if (Options.NoRedZone)
- F->addFnAttr(Attribute::NoRedZone);
-
- BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F);
- IRBuilder<> Builder(BB);
-
- FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
- auto *PFTy = PointerType::get(FTy, 0);
- FTy = FunctionType::get(Builder.getVoidTy(), {PFTy, PFTy}, false);
-
- // Initialize the environment and register the local writeout, flush and
- // reset functions.
- FunctionCallee GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy);
- Builder.CreateCall(GCOVInit, {WriteoutF, ResetF});
- Builder.CreateRetVoid();
-
- appendToGlobalCtors(*M, F, 0);
+ }
+ return true;
+}
+
+void GCOVProfiler::emitGlobalConstructor(
+ SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP) {
+ Function *WriteoutF = insertCounterWriteout(CountersBySP);
+ Function *ResetF = insertReset(CountersBySP);
+
+ // Create a small bit of code that registers the "__llvm_gcov_writeout" to
+ // be executed at exit and the "__llvm_gcov_flush" function to be executed
+ // when "__gcov_flush" is called.
+ FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
+ Function *F = Function::Create(FTy, GlobalValue::InternalLinkage,
+ "__llvm_gcov_init", M);
+ F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
+ F->setLinkage(GlobalValue::InternalLinkage);
+ F->addFnAttr(Attribute::NoInline);
+ if (Options.NoRedZone)
+ F->addFnAttr(Attribute::NoRedZone);
+
+ BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F);
+ IRBuilder<> Builder(BB);
+
+ FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
+ auto *PFTy = PointerType::get(FTy, 0);
+ FTy = FunctionType::get(Builder.getVoidTy(), {PFTy, PFTy}, false);
+
+ // Initialize the environment and register the local writeout, flush and
+ // reset functions.
+ FunctionCallee GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy);
+ Builder.CreateCall(GCOVInit, {WriteoutF, ResetF});
+ Builder.CreateRetVoid();
+
+ appendToGlobalCtors(*M, F, 0);
}
FunctionCallee GCOVProfiler::getStartFileFunc(const TargetLibraryInfo *TLI) {
@@ -1140,19 +1140,19 @@ Function *GCOVProfiler::insertCounterWriteout(
// Collect the relevant data into a large constant data structure that we can
// walk to write out everything.
StructType *StartFileCallArgsTy = StructType::create(
- {Builder.getInt8PtrTy(), Builder.getInt32Ty(), Builder.getInt32Ty()},
- "start_file_args_ty");
+ {Builder.getInt8PtrTy(), Builder.getInt32Ty(), Builder.getInt32Ty()},
+ "start_file_args_ty");
StructType *EmitFunctionCallArgsTy = StructType::create(
- {Builder.getInt32Ty(), Builder.getInt32Ty(), Builder.getInt32Ty()},
- "emit_function_args_ty");
+ {Builder.getInt32Ty(), Builder.getInt32Ty(), Builder.getInt32Ty()},
+ "emit_function_args_ty");
StructType *EmitArcsCallArgsTy = StructType::create(
- {Builder.getInt32Ty(), Builder.getInt64Ty()->getPointerTo()},
- "emit_arcs_args_ty");
+ {Builder.getInt32Ty(), Builder.getInt64Ty()->getPointerTo()},
+ "emit_arcs_args_ty");
StructType *FileInfoTy =
StructType::create({StartFileCallArgsTy, Builder.getInt32Ty(),
EmitFunctionCallArgsTy->getPointerTo(),
- EmitArcsCallArgsTy->getPointerTo()},
- "file_info");
+ EmitArcsCallArgsTy->getPointerTo()},
+ "file_info");
Constant *Zero32 = Builder.getInt32(0);
// Build an explicit array of two zeros for use in ConstantExpr GEP building.
@@ -1262,46 +1262,46 @@ Function *GCOVProfiler::insertCounterWriteout(
// The index into the files structure is our loop induction variable.
Builder.SetInsertPoint(FileLoopHeader);
- PHINode *IV = Builder.CreatePHI(Builder.getInt32Ty(), /*NumReservedValues*/ 2,
- "file_idx");
+ PHINode *IV = Builder.CreatePHI(Builder.getInt32Ty(), /*NumReservedValues*/ 2,
+ "file_idx");
IV->addIncoming(Builder.getInt32(0), BB);
auto *FileInfoPtr = Builder.CreateInBoundsGEP(
FileInfoArrayTy, FileInfoArrayGV, {Builder.getInt32(0), IV});
auto *StartFileCallArgsPtr =
- Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 0, "start_file_args");
+ Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 0, "start_file_args");
auto *StartFileCall = Builder.CreateCall(
StartFile,
{Builder.CreateLoad(StartFileCallArgsTy->getElementType(0),
Builder.CreateStructGEP(StartFileCallArgsTy,
- StartFileCallArgsPtr, 0),
- "filename"),
+ StartFileCallArgsPtr, 0),
+ "filename"),
Builder.CreateLoad(StartFileCallArgsTy->getElementType(1),
Builder.CreateStructGEP(StartFileCallArgsTy,
- StartFileCallArgsPtr, 1),
- "version"),
+ StartFileCallArgsPtr, 1),
+ "version"),
Builder.CreateLoad(StartFileCallArgsTy->getElementType(2),
Builder.CreateStructGEP(StartFileCallArgsTy,
- StartFileCallArgsPtr, 2),
- "stamp")});
+ StartFileCallArgsPtr, 2),
+ "stamp")});
if (auto AK = TLI->getExtAttrForI32Param(false))
StartFileCall->addParamAttr(2, AK);
- auto *NumCounters = Builder.CreateLoad(
- FileInfoTy->getElementType(1),
- Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 1), "num_ctrs");
+ auto *NumCounters = Builder.CreateLoad(
+ FileInfoTy->getElementType(1),
+ Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 1), "num_ctrs");
auto *EmitFunctionCallArgsArray =
Builder.CreateLoad(FileInfoTy->getElementType(2),
- Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 2),
- "emit_function_args");
- auto *EmitArcsCallArgsArray = Builder.CreateLoad(
- FileInfoTy->getElementType(3),
- Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 3), "emit_arcs_args");
+ Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 2),
+ "emit_function_args");
+ auto *EmitArcsCallArgsArray = Builder.CreateLoad(
+ FileInfoTy->getElementType(3),
+ Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 3), "emit_arcs_args");
auto *EnterCounterLoopCond =
Builder.CreateICmpSLT(Builder.getInt32(0), NumCounters);
Builder.CreateCondBr(EnterCounterLoopCond, CounterLoopHeader, FileLoopLatch);
Builder.SetInsertPoint(CounterLoopHeader);
- auto *JV = Builder.CreatePHI(Builder.getInt32Ty(), /*NumReservedValues*/ 2,
- "ctr_idx");
+ auto *JV = Builder.CreatePHI(Builder.getInt32Ty(), /*NumReservedValues*/ 2,
+ "ctr_idx");
JV->addIncoming(Builder.getInt32(0), FileLoopHeader);
auto *EmitFunctionCallArgsPtr = Builder.CreateInBoundsGEP(
EmitFunctionCallArgsTy, EmitFunctionCallArgsArray, JV);
@@ -1309,16 +1309,16 @@ Function *GCOVProfiler::insertCounterWriteout(
EmitFunction,
{Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(0),
Builder.CreateStructGEP(EmitFunctionCallArgsTy,
- EmitFunctionCallArgsPtr, 0),
- "ident"),
+ EmitFunctionCallArgsPtr, 0),
+ "ident"),
Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(1),
Builder.CreateStructGEP(EmitFunctionCallArgsTy,
- EmitFunctionCallArgsPtr, 1),
- "func_checkssum"),
+ EmitFunctionCallArgsPtr, 1),
+ "func_checkssum"),
Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(2),
Builder.CreateStructGEP(EmitFunctionCallArgsTy,
- EmitFunctionCallArgsPtr, 2),
- "cfg_checksum")});
+ EmitFunctionCallArgsPtr, 2),
+ "cfg_checksum")});
if (auto AK = TLI->getExtAttrForI32Param(false)) {
EmitFunctionCall->addParamAttr(0, AK);
EmitFunctionCall->addParamAttr(1, AK);
@@ -1330,12 +1330,12 @@ Function *GCOVProfiler::insertCounterWriteout(
EmitArcs,
{Builder.CreateLoad(
EmitArcsCallArgsTy->getElementType(0),
- Builder.CreateStructGEP(EmitArcsCallArgsTy, EmitArcsCallArgsPtr, 0),
- "num_counters"),
- Builder.CreateLoad(
- EmitArcsCallArgsTy->getElementType(1),
- Builder.CreateStructGEP(EmitArcsCallArgsTy, EmitArcsCallArgsPtr, 1),
- "counters")});
+ Builder.CreateStructGEP(EmitArcsCallArgsTy, EmitArcsCallArgsPtr, 0),
+ "num_counters"),
+ Builder.CreateLoad(
+ EmitArcsCallArgsTy->getElementType(1),
+ Builder.CreateStructGEP(EmitArcsCallArgsTy, EmitArcsCallArgsPtr, 1),
+ "counters")});
if (auto AK = TLI->getExtAttrForI32Param(false))
EmitArcsCall->addParamAttr(0, AK);
auto *NextJV = Builder.CreateAdd(JV, Builder.getInt32(1));
@@ -1346,7 +1346,7 @@ Function *GCOVProfiler::insertCounterWriteout(
Builder.SetInsertPoint(FileLoopLatch);
Builder.CreateCall(SummaryInfo, {});
Builder.CreateCall(EndFile, {});
- auto *NextIV = Builder.CreateAdd(IV, Builder.getInt32(1), "next_file_idx");
+ auto *NextIV = Builder.CreateAdd(IV, Builder.getInt32(1), "next_file_idx");
auto *FileLoopCond =
Builder.CreateICmpSLT(NextIV, Builder.getInt32(FileInfos.size()));
Builder.CreateCondBr(FileLoopCond, FileLoopHeader, ExitBB);
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/contrib/libs/llvm12/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index d668193c02..fedd9bfc97 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -55,12 +55,12 @@ using namespace llvm;
#define DEBUG_TYPE "hwasan"
-const char kHwasanModuleCtorName[] = "hwasan.module_ctor";
-const char kHwasanNoteName[] = "hwasan.note";
-const char kHwasanInitName[] = "__hwasan_init";
-const char kHwasanPersonalityThunkName[] = "__hwasan_personality_thunk";
+const char kHwasanModuleCtorName[] = "hwasan.module_ctor";
+const char kHwasanNoteName[] = "hwasan.note";
+const char kHwasanInitName[] = "__hwasan_init";
+const char kHwasanPersonalityThunkName[] = "__hwasan_personality_thunk";
-const char kHwasanShadowMemoryDynamicAddress[] =
+const char kHwasanShadowMemoryDynamicAddress[] =
"__hwasan_shadow_memory_dynamic_address";
// Accesses sizes are powers of two: 1, 2, 4, 8, 16.
@@ -202,14 +202,14 @@ public:
bool sanitizeFunction(Function &F);
void initializeModule();
- void createHwasanCtorComdat();
+ void createHwasanCtorComdat();
void initializeCallbacks(Module &M);
- Value *getOpaqueNoopCast(IRBuilder<> &IRB, Value *Val);
-
+ Value *getOpaqueNoopCast(IRBuilder<> &IRB, Value *Val);
+
Value *getDynamicShadowIfunc(IRBuilder<> &IRB);
- Value *getShadowNonTls(IRBuilder<> &IRB);
+ Value *getShadowNonTls(IRBuilder<> &IRB);
void untagPointerOperand(Instruction *I, Value *Addr);
Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
@@ -281,13 +281,13 @@ private:
bool CompileKernel;
bool Recover;
- bool OutlinedChecks;
+ bool OutlinedChecks;
bool UseShortGranules;
bool InstrumentLandingPads;
- bool HasMatchAllTag = false;
- uint8_t MatchAllTag = 0;
-
+ bool HasMatchAllTag = false;
+ uint8_t MatchAllTag = 0;
+
Function *HwasanCtorFunction;
FunctionCallee HwasanMemoryAccessCallback[2][kNumberOfAccessSizes];
@@ -298,7 +298,7 @@ private:
Constant *ShadowGlobal;
- Value *ShadowBase = nullptr;
+ Value *ShadowBase = nullptr;
Value *StackBaseTag = nullptr;
GlobalValue *ThreadPtrGlobal = nullptr;
};
@@ -370,106 +370,106 @@ PreservedAnalyses HWAddressSanitizerPass::run(Module &M,
return PreservedAnalyses::all();
}
-void HWAddressSanitizer::createHwasanCtorComdat() {
- std::tie(HwasanCtorFunction, std::ignore) =
- getOrCreateSanitizerCtorAndInitFunctions(
- M, kHwasanModuleCtorName, kHwasanInitName,
- /*InitArgTypes=*/{},
- /*InitArgs=*/{},
- // This callback is invoked when the functions are created the first
- // time. Hook them into the global ctors list in that case:
- [&](Function *Ctor, FunctionCallee) {
- Comdat *CtorComdat = M.getOrInsertComdat(kHwasanModuleCtorName);
- Ctor->setComdat(CtorComdat);
- appendToGlobalCtors(M, Ctor, 0, Ctor);
- });
-
- // Create a note that contains pointers to the list of global
- // descriptors. Adding a note to the output file will cause the linker to
- // create a PT_NOTE program header pointing to the note that we can use to
- // find the descriptor list starting from the program headers. A function
- // provided by the runtime initializes the shadow memory for the globals by
- // accessing the descriptor list via the note. The dynamic loader needs to
- // call this function whenever a library is loaded.
- //
- // The reason why we use a note for this instead of a more conventional
- // approach of having a global constructor pass a descriptor list pointer to
- // the runtime is because of an order of initialization problem. With
- // constructors we can encounter the following problematic scenario:
- //
- // 1) library A depends on library B and also interposes one of B's symbols
- // 2) B's constructors are called before A's (as required for correctness)
- // 3) during construction, B accesses one of its "own" globals (actually
- // interposed by A) and triggers a HWASAN failure due to the initialization
- // for A not having happened yet
- //
- // Even without interposition it is possible to run into similar situations in
- // cases where two libraries mutually depend on each other.
- //
- // We only need one note per binary, so put everything for the note in a
- // comdat. This needs to be a comdat with an .init_array section to prevent
- // newer versions of lld from discarding the note.
- //
- // Create the note even if we aren't instrumenting globals. This ensures that
- // binaries linked from object files with both instrumented and
- // non-instrumented globals will end up with a note, even if a comdat from an
- // object file with non-instrumented globals is selected. The note is harmless
- // if the runtime doesn't support it, since it will just be ignored.
- Comdat *NoteComdat = M.getOrInsertComdat(kHwasanModuleCtorName);
-
- Type *Int8Arr0Ty = ArrayType::get(Int8Ty, 0);
- auto Start =
- new GlobalVariable(M, Int8Arr0Ty, true, GlobalVariable::ExternalLinkage,
- nullptr, "__start_hwasan_globals");
- Start->setVisibility(GlobalValue::HiddenVisibility);
- Start->setDSOLocal(true);
- auto Stop =
- new GlobalVariable(M, Int8Arr0Ty, true, GlobalVariable::ExternalLinkage,
- nullptr, "__stop_hwasan_globals");
- Stop->setVisibility(GlobalValue::HiddenVisibility);
- Stop->setDSOLocal(true);
-
- // Null-terminated so actually 8 bytes, which are required in order to align
- // the note properly.
- auto *Name = ConstantDataArray::get(*C, "LLVM\0\0\0");
-
- auto *NoteTy = StructType::get(Int32Ty, Int32Ty, Int32Ty, Name->getType(),
- Int32Ty, Int32Ty);
- auto *Note =
- new GlobalVariable(M, NoteTy, /*isConstant=*/true,
- GlobalValue::PrivateLinkage, nullptr, kHwasanNoteName);
- Note->setSection(".note.hwasan.globals");
- Note->setComdat(NoteComdat);
- Note->setAlignment(Align(4));
- Note->setDSOLocal(true);
-
- // The pointers in the note need to be relative so that the note ends up being
- // placed in rodata, which is the standard location for notes.
- auto CreateRelPtr = [&](Constant *Ptr) {
- return ConstantExpr::getTrunc(
- ConstantExpr::getSub(ConstantExpr::getPtrToInt(Ptr, Int64Ty),
- ConstantExpr::getPtrToInt(Note, Int64Ty)),
- Int32Ty);
- };
- Note->setInitializer(ConstantStruct::getAnon(
- {ConstantInt::get(Int32Ty, 8), // n_namesz
- ConstantInt::get(Int32Ty, 8), // n_descsz
- ConstantInt::get(Int32Ty, ELF::NT_LLVM_HWASAN_GLOBALS), // n_type
- Name, CreateRelPtr(Start), CreateRelPtr(Stop)}));
- appendToCompilerUsed(M, Note);
-
- // Create a zero-length global in hwasan_globals so that the linker will
- // always create start and stop symbols.
- auto Dummy = new GlobalVariable(
- M, Int8Arr0Ty, /*isConstantGlobal*/ true, GlobalVariable::PrivateLinkage,
- Constant::getNullValue(Int8Arr0Ty), "hwasan.dummy.global");
- Dummy->setSection("hwasan_globals");
- Dummy->setComdat(NoteComdat);
- Dummy->setMetadata(LLVMContext::MD_associated,
- MDNode::get(*C, ValueAsMetadata::get(Note)));
- appendToCompilerUsed(M, Dummy);
-}
-
+void HWAddressSanitizer::createHwasanCtorComdat() {
+ std::tie(HwasanCtorFunction, std::ignore) =
+ getOrCreateSanitizerCtorAndInitFunctions(
+ M, kHwasanModuleCtorName, kHwasanInitName,
+ /*InitArgTypes=*/{},
+ /*InitArgs=*/{},
+ // This callback is invoked when the functions are created the first
+ // time. Hook them into the global ctors list in that case:
+ [&](Function *Ctor, FunctionCallee) {
+ Comdat *CtorComdat = M.getOrInsertComdat(kHwasanModuleCtorName);
+ Ctor->setComdat(CtorComdat);
+ appendToGlobalCtors(M, Ctor, 0, Ctor);
+ });
+
+ // Create a note that contains pointers to the list of global
+ // descriptors. Adding a note to the output file will cause the linker to
+ // create a PT_NOTE program header pointing to the note that we can use to
+ // find the descriptor list starting from the program headers. A function
+ // provided by the runtime initializes the shadow memory for the globals by
+ // accessing the descriptor list via the note. The dynamic loader needs to
+ // call this function whenever a library is loaded.
+ //
+ // The reason why we use a note for this instead of a more conventional
+ // approach of having a global constructor pass a descriptor list pointer to
+ // the runtime is because of an order of initialization problem. With
+ // constructors we can encounter the following problematic scenario:
+ //
+ // 1) library A depends on library B and also interposes one of B's symbols
+ // 2) B's constructors are called before A's (as required for correctness)
+ // 3) during construction, B accesses one of its "own" globals (actually
+ // interposed by A) and triggers a HWASAN failure due to the initialization
+ // for A not having happened yet
+ //
+ // Even without interposition it is possible to run into similar situations in
+ // cases where two libraries mutually depend on each other.
+ //
+ // We only need one note per binary, so put everything for the note in a
+ // comdat. This needs to be a comdat with an .init_array section to prevent
+ // newer versions of lld from discarding the note.
+ //
+ // Create the note even if we aren't instrumenting globals. This ensures that
+ // binaries linked from object files with both instrumented and
+ // non-instrumented globals will end up with a note, even if a comdat from an
+ // object file with non-instrumented globals is selected. The note is harmless
+ // if the runtime doesn't support it, since it will just be ignored.
+ Comdat *NoteComdat = M.getOrInsertComdat(kHwasanModuleCtorName);
+
+ Type *Int8Arr0Ty = ArrayType::get(Int8Ty, 0);
+ auto Start =
+ new GlobalVariable(M, Int8Arr0Ty, true, GlobalVariable::ExternalLinkage,
+ nullptr, "__start_hwasan_globals");
+ Start->setVisibility(GlobalValue::HiddenVisibility);
+ Start->setDSOLocal(true);
+ auto Stop =
+ new GlobalVariable(M, Int8Arr0Ty, true, GlobalVariable::ExternalLinkage,
+ nullptr, "__stop_hwasan_globals");
+ Stop->setVisibility(GlobalValue::HiddenVisibility);
+ Stop->setDSOLocal(true);
+
+ // Null-terminated so actually 8 bytes, which are required in order to align
+ // the note properly.
+ auto *Name = ConstantDataArray::get(*C, "LLVM\0\0\0");
+
+ auto *NoteTy = StructType::get(Int32Ty, Int32Ty, Int32Ty, Name->getType(),
+ Int32Ty, Int32Ty);
+ auto *Note =
+ new GlobalVariable(M, NoteTy, /*isConstant=*/true,
+ GlobalValue::PrivateLinkage, nullptr, kHwasanNoteName);
+ Note->setSection(".note.hwasan.globals");
+ Note->setComdat(NoteComdat);
+ Note->setAlignment(Align(4));
+ Note->setDSOLocal(true);
+
+ // The pointers in the note need to be relative so that the note ends up being
+ // placed in rodata, which is the standard location for notes.
+ auto CreateRelPtr = [&](Constant *Ptr) {
+ return ConstantExpr::getTrunc(
+ ConstantExpr::getSub(ConstantExpr::getPtrToInt(Ptr, Int64Ty),
+ ConstantExpr::getPtrToInt(Note, Int64Ty)),
+ Int32Ty);
+ };
+ Note->setInitializer(ConstantStruct::getAnon(
+ {ConstantInt::get(Int32Ty, 8), // n_namesz
+ ConstantInt::get(Int32Ty, 8), // n_descsz
+ ConstantInt::get(Int32Ty, ELF::NT_LLVM_HWASAN_GLOBALS), // n_type
+ Name, CreateRelPtr(Start), CreateRelPtr(Stop)}));
+ appendToCompilerUsed(M, Note);
+
+ // Create a zero-length global in hwasan_globals so that the linker will
+ // always create start and stop symbols.
+ auto Dummy = new GlobalVariable(
+ M, Int8Arr0Ty, /*isConstantGlobal*/ true, GlobalVariable::PrivateLinkage,
+ Constant::getNullValue(Int8Arr0Ty), "hwasan.dummy.global");
+ Dummy->setSection("hwasan_globals");
+ Dummy->setComdat(NoteComdat);
+ Dummy->setMetadata(LLVMContext::MD_associated,
+ MDNode::get(*C, ValueAsMetadata::get(Note)));
+ appendToCompilerUsed(M, Dummy);
+}
+
/// Module-level initialization.
///
/// inserts a call to __hwasan_init to the module's constructor list.
@@ -498,27 +498,27 @@ void HWAddressSanitizer::initializeModule() {
UseShortGranules =
ClUseShortGranules.getNumOccurrences() ? ClUseShortGranules : NewRuntime;
- OutlinedChecks =
- TargetTriple.isAArch64() && TargetTriple.isOSBinFormatELF() &&
- (ClInlineAllChecks.getNumOccurrences() ? !ClInlineAllChecks : !Recover);
-
- if (ClMatchAllTag.getNumOccurrences()) {
- if (ClMatchAllTag != -1) {
- HasMatchAllTag = true;
- MatchAllTag = ClMatchAllTag & 0xFF;
- }
- } else if (CompileKernel) {
- HasMatchAllTag = true;
- MatchAllTag = 0xFF;
- }
-
+ OutlinedChecks =
+ TargetTriple.isAArch64() && TargetTriple.isOSBinFormatELF() &&
+ (ClInlineAllChecks.getNumOccurrences() ? !ClInlineAllChecks : !Recover);
+
+ if (ClMatchAllTag.getNumOccurrences()) {
+ if (ClMatchAllTag != -1) {
+ HasMatchAllTag = true;
+ MatchAllTag = ClMatchAllTag & 0xFF;
+ }
+ } else if (CompileKernel) {
+ HasMatchAllTag = true;
+ MatchAllTag = 0xFF;
+ }
+
// If we don't have personality function support, fall back to landing pads.
InstrumentLandingPads = ClInstrumentLandingPads.getNumOccurrences()
? ClInstrumentLandingPads
: !NewRuntime;
if (!CompileKernel) {
- createHwasanCtorComdat();
+ createHwasanCtorComdat();
bool InstrumentGlobals =
ClGlobals.getNumOccurrences() ? ClGlobals : NewRuntime;
if (InstrumentGlobals)
@@ -589,27 +589,27 @@ void HWAddressSanitizer::initializeCallbacks(Module &M) {
M.getOrInsertFunction("__hwasan_handle_vfork", IRB.getVoidTy(), IntptrTy);
}
-Value *HWAddressSanitizer::getOpaqueNoopCast(IRBuilder<> &IRB, Value *Val) {
+Value *HWAddressSanitizer::getOpaqueNoopCast(IRBuilder<> &IRB, Value *Val) {
// An empty inline asm with input reg == output reg.
// An opaque no-op cast, basically.
- // This prevents code bloat as a result of rematerializing trivial definitions
- // such as constants or global addresses at every load and store.
- InlineAsm *Asm =
- InlineAsm::get(FunctionType::get(Int8PtrTy, {Val->getType()}, false),
- StringRef(""), StringRef("=r,0"),
- /*hasSideEffects=*/false);
- return IRB.CreateCall(Asm, {Val}, ".hwasan.shadow");
+ // This prevents code bloat as a result of rematerializing trivial definitions
+ // such as constants or global addresses at every load and store.
+ InlineAsm *Asm =
+ InlineAsm::get(FunctionType::get(Int8PtrTy, {Val->getType()}, false),
+ StringRef(""), StringRef("=r,0"),
+ /*hasSideEffects=*/false);
+ return IRB.CreateCall(Asm, {Val}, ".hwasan.shadow");
+}
+
+Value *HWAddressSanitizer::getDynamicShadowIfunc(IRBuilder<> &IRB) {
+ return getOpaqueNoopCast(IRB, ShadowGlobal);
}
-Value *HWAddressSanitizer::getDynamicShadowIfunc(IRBuilder<> &IRB) {
- return getOpaqueNoopCast(IRB, ShadowGlobal);
-}
-
-Value *HWAddressSanitizer::getShadowNonTls(IRBuilder<> &IRB) {
+Value *HWAddressSanitizer::getShadowNonTls(IRBuilder<> &IRB) {
if (Mapping.Offset != kDynamicShadowSentinel)
- return getOpaqueNoopCast(
- IRB, ConstantExpr::getIntToPtr(
- ConstantInt::get(IntptrTy, Mapping.Offset), Int8PtrTy));
+ return getOpaqueNoopCast(
+ IRB, ConstantExpr::getIntToPtr(
+ ConstantInt::get(IntptrTy, Mapping.Offset), Int8PtrTy));
if (Mapping.InGlobal) {
return getDynamicShadowIfunc(IRB);
@@ -645,7 +645,7 @@ void HWAddressSanitizer::getInterestingMemoryOperands(
return;
// Do not instrument the load fetching the dynamic shadow address.
- if (ShadowBase == I)
+ if (ShadowBase == I)
return;
if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
@@ -715,29 +715,29 @@ Value *HWAddressSanitizer::memToShadow(Value *Mem, IRBuilder<> &IRB) {
if (Mapping.Offset == 0)
return IRB.CreateIntToPtr(Shadow, Int8PtrTy);
// (Mem >> Scale) + Offset
- return IRB.CreateGEP(Int8Ty, ShadowBase, Shadow);
+ return IRB.CreateGEP(Int8Ty, ShadowBase, Shadow);
}
void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite,
unsigned AccessSizeIndex,
Instruction *InsertBefore) {
- const int64_t AccessInfo =
- (CompileKernel << HWASanAccessInfo::CompileKernelShift) +
- (HasMatchAllTag << HWASanAccessInfo::HasMatchAllShift) +
- (MatchAllTag << HWASanAccessInfo::MatchAllShift) +
- (Recover << HWASanAccessInfo::RecoverShift) +
- (IsWrite << HWASanAccessInfo::IsWriteShift) +
- (AccessSizeIndex << HWASanAccessInfo::AccessSizeShift);
+ const int64_t AccessInfo =
+ (CompileKernel << HWASanAccessInfo::CompileKernelShift) +
+ (HasMatchAllTag << HWASanAccessInfo::HasMatchAllShift) +
+ (MatchAllTag << HWASanAccessInfo::MatchAllShift) +
+ (Recover << HWASanAccessInfo::RecoverShift) +
+ (IsWrite << HWASanAccessInfo::IsWriteShift) +
+ (AccessSizeIndex << HWASanAccessInfo::AccessSizeShift);
IRBuilder<> IRB(InsertBefore);
- if (OutlinedChecks) {
+ if (OutlinedChecks) {
Module *M = IRB.GetInsertBlock()->getParent()->getParent();
Ptr = IRB.CreateBitCast(Ptr, Int8PtrTy);
IRB.CreateCall(Intrinsic::getDeclaration(
M, UseShortGranules
? Intrinsic::hwasan_check_memaccess_shortgranules
: Intrinsic::hwasan_check_memaccess),
- {ShadowBase, Ptr, ConstantInt::get(Int32Ty, AccessInfo)});
+ {ShadowBase, Ptr, ConstantInt::get(Int32Ty, AccessInfo)});
return;
}
@@ -749,9 +749,9 @@ void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite,
Value *MemTag = IRB.CreateLoad(Int8Ty, Shadow);
Value *TagMismatch = IRB.CreateICmpNE(PtrTag, MemTag);
- if (HasMatchAllTag) {
- Value *TagNotIgnored = IRB.CreateICmpNE(
- PtrTag, ConstantInt::get(PtrTag->getType(), MatchAllTag));
+ if (HasMatchAllTag) {
+ Value *TagNotIgnored = IRB.CreateICmpNE(
+ PtrTag, ConstantInt::get(PtrTag->getType(), MatchAllTag));
TagMismatch = IRB.CreateAnd(TagMismatch, TagNotIgnored);
}
@@ -773,8 +773,8 @@ void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite,
Value *PtrLowBitsOOB = IRB.CreateICmpUGE(PtrLowBits, MemTag);
SplitBlockAndInsertIfThen(PtrLowBitsOOB, CheckTerm, false,
MDBuilder(*C).createBranchWeights(1, 100000),
- (DomTreeUpdater *)nullptr, nullptr,
- CheckFailTerm->getParent());
+ (DomTreeUpdater *)nullptr, nullptr,
+ CheckFailTerm->getParent());
IRB.SetInsertPoint(CheckTerm);
Value *InlineTagAddr = IRB.CreateOr(AddrLong, 15);
@@ -783,8 +783,8 @@ void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite,
Value *InlineTagMismatch = IRB.CreateICmpNE(PtrTag, InlineTag);
SplitBlockAndInsertIfThen(InlineTagMismatch, CheckTerm, false,
MDBuilder(*C).createBranchWeights(1, 100000),
- (DomTreeUpdater *)nullptr, nullptr,
- CheckFailTerm->getParent());
+ (DomTreeUpdater *)nullptr, nullptr,
+ CheckFailTerm->getParent());
IRB.SetInsertPoint(CheckFailTerm);
InlineAsm *Asm;
@@ -793,9 +793,9 @@ void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite,
// The signal handler will find the data address in rdi.
Asm = InlineAsm::get(
FunctionType::get(IRB.getVoidTy(), {PtrLong->getType()}, false),
- "int3\nnopl " +
- itostr(0x40 + (AccessInfo & HWASanAccessInfo::RuntimeMask)) +
- "(%rax)",
+ "int3\nnopl " +
+ itostr(0x40 + (AccessInfo & HWASanAccessInfo::RuntimeMask)) +
+ "(%rax)",
"{rdi}",
/*hasSideEffects=*/true);
break;
@@ -804,8 +804,8 @@ void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite,
// The signal handler will find the data address in x0.
Asm = InlineAsm::get(
FunctionType::get(IRB.getVoidTy(), {PtrLong->getType()}, false),
- "brk #" +
- itostr(0x900 + (AccessInfo & HWASanAccessInfo::RuntimeMask)),
+ "brk #" +
+ itostr(0x900 + (AccessInfo & HWASanAccessInfo::RuntimeMask)),
"{x0}",
/*hasSideEffects=*/true);
break;
@@ -1028,12 +1028,12 @@ Value *HWAddressSanitizer::getHwasanThreadSlotPtr(IRBuilder<> &IRB, Type *Ty) {
void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) {
if (!Mapping.InTls) {
- ShadowBase = getShadowNonTls(IRB);
+ ShadowBase = getShadowNonTls(IRB);
return;
}
if (!WithFrameRecord && TargetTriple.isAndroid()) {
- ShadowBase = getDynamicShadowIfunc(IRB);
+ ShadowBase = getDynamicShadowIfunc(IRB);
return;
}
@@ -1094,12 +1094,12 @@ void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) {
// Get shadow base address by aligning RecordPtr up.
// Note: this is not correct if the pointer is already aligned.
// Runtime library will make sure this never happens.
- ShadowBase = IRB.CreateAdd(
+ ShadowBase = IRB.CreateAdd(
IRB.CreateOr(
ThreadLongMaybeUntagged,
ConstantInt::get(IntptrTy, (1ULL << kShadowBaseAlignment) - 1)),
ConstantInt::get(IntptrTy, 1), "hwasan.shadow");
- ShadowBase = IRB.CreateIntToPtr(ShadowBase, Int8PtrTy);
+ ShadowBase = IRB.CreateIntToPtr(ShadowBase, Int8PtrTy);
}
Value *HWAddressSanitizer::readRegister(IRBuilder<> &IRB, StringRef Name) {
@@ -1251,7 +1251,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) {
IntrinToInstrument.empty())
return Changed;
- assert(!ShadowBase);
+ assert(!ShadowBase);
Instruction *InsertPt = &*F.getEntryBlock().begin();
IRBuilder<> EntryIRB(InsertPt);
@@ -1331,7 +1331,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) {
instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
}
- ShadowBase = nullptr;
+ ShadowBase = nullptr;
StackBaseTag = nullptr;
return true;
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp b/contrib/libs/llvm12/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp
index 068cf578dd..5b9557a9b3 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp
@@ -263,15 +263,15 @@ ICallPromotionFunc::getPromotionCandidatesForCallSite(
break;
}
- // Don't promote if the symbol is not defined in the module. This avoids
- // creating a reference to a symbol that doesn't exist in the module
- // This can happen when we compile with a sample profile collected from
- // one binary but used for another, which may have profiled targets that
- // aren't used in the new binary. We might have a declaration initially in
- // the case where the symbol is globally dead in the binary and removed by
- // ThinLTO.
+ // Don't promote if the symbol is not defined in the module. This avoids
+ // creating a reference to a symbol that doesn't exist in the module
+ // This can happen when we compile with a sample profile collected from
+ // one binary but used for another, which may have profiled targets that
+ // aren't used in the new binary. We might have a declaration initially in
+ // the case where the symbol is globally dead in the binary and removed by
+ // ThinLTO.
Function *TargetFunction = Symtab->getFunction(Target);
- if (TargetFunction == nullptr || TargetFunction->isDeclaration()) {
+ if (TargetFunction == nullptr || TargetFunction->isDeclaration()) {
LLVM_DEBUG(dbgs() << " Not promote: Cannot find the target\n");
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "UnableToFindTarget", &CB)
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/InstrProfiling.cpp b/contrib/libs/llvm12/lib/Transforms/Instrumentation/InstrProfiling.cpp
index 83e048d010..9efc7d1ac5 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -135,10 +135,10 @@ cl::opt<bool> IterativeCounterPromotion(
cl::ZeroOrMore, "iterative-counter-promotion", cl::init(true),
cl::desc("Allow counter promotion across the whole loop nest."));
-cl::opt<bool> SkipRetExitBlock(
- cl::ZeroOrMore, "skip-ret-exit-block", cl::init(true),
- cl::desc("Suppress counter promotion if exit blocks contain ret."));
-
+cl::opt<bool> SkipRetExitBlock(
+ cl::ZeroOrMore, "skip-ret-exit-block", cl::init(true),
+ cl::desc("Suppress counter promotion if exit blocks contain ret."));
+
class InstrProfilingLegacyPass : public ModulePass {
InstrProfiling InstrProf;
@@ -261,18 +261,18 @@ public:
// Skip 'infinite' loops:
if (ExitBlocks.size() == 0)
return false;
-
- // Skip if any of the ExitBlocks contains a ret instruction.
- // This is to prevent dumping of incomplete profile -- if the
- // the loop is a long running loop and dump is called in the middle
- // of the loop, the result profile is incomplete.
- // FIXME: add other heuristics to detect long running loops.
- if (SkipRetExitBlock) {
- for (auto BB : ExitBlocks)
- if (isa<ReturnInst>(BB->getTerminator()))
- return false;
- }
-
+
+ // Skip if any of the ExitBlocks contains a ret instruction.
+ // This is to prevent dumping of incomplete profile -- if the
+ // the loop is a long running loop and dump is called in the middle
+ // of the loop, the result profile is incomplete.
+ // FIXME: add other heuristics to detect long running loops.
+ if (SkipRetExitBlock) {
+ for (auto BB : ExitBlocks)
+ if (isa<ReturnInst>(BB->getTerminator()))
+ return false;
+ }
+
unsigned MaxProm = getMaxNumOfPromotionsInLoop(&L);
if (MaxProm == 0)
return false;
@@ -396,15 +396,15 @@ private:
BlockFrequencyInfo *BFI;
};
-enum class ValueProfilingCallType {
- // Individual values are tracked. Currently used for indiret call target
- // profiling.
- Default,
-
- // MemOp: the memop size value profiling.
- MemOp
-};
-
+enum class ValueProfilingCallType {
+ // Individual values are tracked. Currently used for indiret call target
+ // profiling.
+ Default,
+
+ // MemOp: the memop size value profiling.
+ MemOp
+};
+
} // end anonymous namespace
PreservedAnalyses InstrProfiling::run(Module &M, ModuleAnalysisManager &AM) {
@@ -587,9 +587,9 @@ bool InstrProfiling::run(
return true;
}
-static FunctionCallee getOrInsertValueProfilingCall(
- Module &M, const TargetLibraryInfo &TLI,
- ValueProfilingCallType CallType = ValueProfilingCallType::Default) {
+static FunctionCallee getOrInsertValueProfilingCall(
+ Module &M, const TargetLibraryInfo &TLI,
+ ValueProfilingCallType CallType = ValueProfilingCallType::Default) {
LLVMContext &Ctx = M.getContext();
auto *ReturnTy = Type::getVoidTy(M.getContext());
@@ -597,19 +597,19 @@ static FunctionCallee getOrInsertValueProfilingCall(
if (auto AK = TLI.getExtAttrForI32Param(false))
AL = AL.addParamAttribute(M.getContext(), 2, AK);
- assert((CallType == ValueProfilingCallType::Default ||
- CallType == ValueProfilingCallType::MemOp) &&
- "Must be Default or MemOp");
- Type *ParamTypes[] = {
+ assert((CallType == ValueProfilingCallType::Default ||
+ CallType == ValueProfilingCallType::MemOp) &&
+ "Must be Default or MemOp");
+ Type *ParamTypes[] = {
#define VALUE_PROF_FUNC_PARAM(ParamType, ParamName, ParamLLVMType) ParamLLVMType
#include "llvm/ProfileData/InstrProfData.inc"
- };
- auto *ValueProfilingCallTy =
- FunctionType::get(ReturnTy, makeArrayRef(ParamTypes), false);
- StringRef FuncName = CallType == ValueProfilingCallType::Default
- ? getInstrProfValueProfFuncName()
- : getInstrProfValueProfMemOpFuncName();
- return M.getOrInsertFunction(FuncName, ValueProfilingCallTy, AL);
+ };
+ auto *ValueProfilingCallTy =
+ FunctionType::get(ReturnTy, makeArrayRef(ParamTypes), false);
+ StringRef FuncName = CallType == ValueProfilingCallType::Default
+ ? getInstrProfValueProfFuncName()
+ : getInstrProfValueProfMemOpFuncName();
+ return M.getOrInsertFunction(FuncName, ValueProfilingCallTy, AL);
}
void InstrProfiling::computeNumValueSiteCounts(InstrProfValueProfileInst *Ind) {
@@ -638,8 +638,8 @@ void InstrProfiling::lowerValueProfileInst(InstrProfValueProfileInst *Ind) {
Index += It->second.NumValueSites[Kind];
IRBuilder<> Builder(Ind);
- bool IsMemOpSize = (Ind->getValueKind()->getZExtValue() ==
- llvm::InstrProfValueKind::IPVK_MemOPSize);
+ bool IsMemOpSize = (Ind->getValueKind()->getZExtValue() ==
+ llvm::InstrProfValueKind::IPVK_MemOPSize);
CallInst *Call = nullptr;
auto *TLI = &GetTLI(*Ind->getFunction());
@@ -649,19 +649,19 @@ void InstrProfiling::lowerValueProfileInst(InstrProfValueProfileInst *Ind) {
// WinEHPrepare pass.
SmallVector<OperandBundleDef, 1> OpBundles;
Ind->getOperandBundlesAsDefs(OpBundles);
- if (!IsMemOpSize) {
+ if (!IsMemOpSize) {
Value *Args[3] = {Ind->getTargetValue(),
Builder.CreateBitCast(DataVar, Builder.getInt8PtrTy()),
Builder.getInt32(Index)};
Call = Builder.CreateCall(getOrInsertValueProfilingCall(*M, *TLI), Args,
OpBundles);
} else {
- Value *Args[3] = {Ind->getTargetValue(),
- Builder.CreateBitCast(DataVar, Builder.getInt8PtrTy()),
- Builder.getInt32(Index)};
- Call = Builder.CreateCall(
- getOrInsertValueProfilingCall(*M, *TLI, ValueProfilingCallType::MemOp),
- Args, OpBundles);
+ Value *Args[3] = {Ind->getTargetValue(),
+ Builder.CreateBitCast(DataVar, Builder.getInt8PtrTy()),
+ Builder.getInt32(Index)};
+ Call = Builder.CreateCall(
+ getOrInsertValueProfilingCall(*M, *TLI, ValueProfilingCallType::MemOp),
+ Args, OpBundles);
}
if (auto AK = TLI->getExtAttrForI32Param(false))
Call->addParamAttr(2, AK);
@@ -828,11 +828,11 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
Visibility = GlobalValue::HiddenVisibility;
}
}
- std::string DataVarName = getVarName(Inc, getInstrProfDataVarPrefix());
+ std::string DataVarName = getVarName(Inc, getInstrProfDataVarPrefix());
auto MaybeSetComdat = [=](GlobalVariable *GV) {
if (NeedComdat)
- GV->setComdat(M->getOrInsertComdat(TT.isOSBinFormatCOFF() ? GV->getName()
- : DataVarName));
+ GV->setComdat(M->getOrInsertComdat(TT.isOSBinFormatCOFF() ? GV->getName()
+ : DataVarName));
};
uint64_t NumCounters = Inc->getNumCounters()->getZExtValue();
@@ -897,9 +897,9 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
#define INSTR_PROF_DATA(Type, LLVMType, Name, Init) Init,
#include "llvm/ProfileData/InstrProfData.inc"
};
- auto *Data =
- new GlobalVariable(*M, DataTy, false, Linkage,
- ConstantStruct::get(DataTy, DataVals), DataVarName);
+ auto *Data =
+ new GlobalVariable(*M, DataTy, false, Linkage,
+ ConstantStruct::get(DataTy, DataVals), DataVarName);
Data->setVisibility(Visibility);
Data->setSection(getInstrProfSectionName(IPSK_data, TT.getObjectFormat()));
Data->setAlignment(Align(INSTR_PROF_DATA_ALIGNMENT));
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/Instrumentation.cpp b/contrib/libs/llvm12/lib/Transforms/Instrumentation/Instrumentation.cpp
index ff4a00fcb7..cfdf3cad97 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/Instrumentation.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/Instrumentation.cpp
@@ -105,8 +105,8 @@ Comdat *llvm::GetOrCreateFunctionComdat(Function &F, Triple &T,
void llvm::initializeInstrumentation(PassRegistry &Registry) {
initializeAddressSanitizerLegacyPassPass(Registry);
initializeModuleAddressSanitizerLegacyPassPass(Registry);
- initializeMemProfilerLegacyPassPass(Registry);
- initializeModuleMemProfilerLegacyPassPass(Registry);
+ initializeMemProfilerLegacyPassPass(Registry);
+ initializeModuleMemProfilerLegacyPassPass(Registry);
initializeBoundsCheckingLegacyPassPass(Registry);
initializeControlHeightReductionLegacyPassPass(Registry);
initializeGCOVProfilerLegacyPassPass(Registry);
@@ -121,7 +121,7 @@ void llvm::initializeInstrumentation(PassRegistry &Registry) {
initializeHWAddressSanitizerLegacyPassPass(Registry);
initializeThreadSanitizerLegacyPassPass(Registry);
initializeModuleSanitizerCoverageLegacyPassPass(Registry);
- initializeDataFlowSanitizerLegacyPassPass(Registry);
+ initializeDataFlowSanitizerLegacyPassPass(Registry);
}
/// LLVMInitializeInstrumentation - C binding for
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/MemProfiler.cpp b/contrib/libs/llvm12/lib/Transforms/Instrumentation/MemProfiler.cpp
index fa2edf52a2..0e6a404a9e 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/MemProfiler.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/MemProfiler.cpp
@@ -1,638 +1,638 @@
-//===- MemProfiler.cpp - memory allocation and access profiler ------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of MemProfiler. Memory accesses are instrumented
-// to increment the access count held in a shadow memory location, or
-// alternatively to call into the runtime. Memory intrinsic calls (memmove,
-// memcpy, memset) are changed to call the memory profiling runtime version
-// instead.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Instrumentation/MemProfiler.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/IR/Constant.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/GlobalValue.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/Type.h"
-#include "llvm/IR/Value.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Transforms/Instrumentation.h"
-#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "llvm/Transforms/Utils/ModuleUtils.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "memprof"
-
-constexpr int LLVM_MEM_PROFILER_VERSION = 1;
-
-// Size of memory mapped to a single shadow location.
-constexpr uint64_t DefaultShadowGranularity = 64;
-
-// Scale from granularity down to shadow size.
-constexpr uint64_t DefaultShadowScale = 3;
-
-constexpr char MemProfModuleCtorName[] = "memprof.module_ctor";
-constexpr uint64_t MemProfCtorAndDtorPriority = 1;
-// On Emscripten, the system needs more than one priorities for constructors.
-constexpr uint64_t MemProfEmscriptenCtorAndDtorPriority = 50;
-constexpr char MemProfInitName[] = "__memprof_init";
-constexpr char MemProfVersionCheckNamePrefix[] =
- "__memprof_version_mismatch_check_v";
-
-constexpr char MemProfShadowMemoryDynamicAddress[] =
- "__memprof_shadow_memory_dynamic_address";
-
-constexpr char MemProfFilenameVar[] = "__memprof_profile_filename";
-
-// Command-line flags.
-
-static cl::opt<bool> ClInsertVersionCheck(
- "memprof-guard-against-version-mismatch",
- cl::desc("Guard against compiler/runtime version mismatch."), cl::Hidden,
- cl::init(true));
-
-// This flag may need to be replaced with -f[no-]memprof-reads.
-static cl::opt<bool> ClInstrumentReads("memprof-instrument-reads",
- cl::desc("instrument read instructions"),
- cl::Hidden, cl::init(true));
-
-static cl::opt<bool>
- ClInstrumentWrites("memprof-instrument-writes",
- cl::desc("instrument write instructions"), cl::Hidden,
- cl::init(true));
-
-static cl::opt<bool> ClInstrumentAtomics(
- "memprof-instrument-atomics",
- cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden,
- cl::init(true));
-
-static cl::opt<bool> ClUseCalls(
- "memprof-use-callbacks",
- cl::desc("Use callbacks instead of inline instrumentation sequences."),
- cl::Hidden, cl::init(false));
-
-static cl::opt<std::string>
- ClMemoryAccessCallbackPrefix("memprof-memory-access-callback-prefix",
- cl::desc("Prefix for memory access callbacks"),
- cl::Hidden, cl::init("__memprof_"));
-
-// These flags allow to change the shadow mapping.
-// The shadow mapping looks like
-// Shadow = ((Mem & mask) >> scale) + offset
-
-static cl::opt<int> ClMappingScale("memprof-mapping-scale",
- cl::desc("scale of memprof shadow mapping"),
- cl::Hidden, cl::init(DefaultShadowScale));
-
-static cl::opt<int>
- ClMappingGranularity("memprof-mapping-granularity",
- cl::desc("granularity of memprof shadow mapping"),
- cl::Hidden, cl::init(DefaultShadowGranularity));
-
-// Debug flags.
-
-static cl::opt<int> ClDebug("memprof-debug", cl::desc("debug"), cl::Hidden,
- cl::init(0));
-
-static cl::opt<std::string> ClDebugFunc("memprof-debug-func", cl::Hidden,
- cl::desc("Debug func"));
-
-static cl::opt<int> ClDebugMin("memprof-debug-min", cl::desc("Debug min inst"),
- cl::Hidden, cl::init(-1));
-
-static cl::opt<int> ClDebugMax("memprof-debug-max", cl::desc("Debug max inst"),
- cl::Hidden, cl::init(-1));
-
-STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
-STATISTIC(NumInstrumentedWrites, "Number of instrumented writes");
-
-namespace {
-
-/// This struct defines the shadow mapping using the rule:
-/// shadow = ((mem & mask) >> Scale) ADD DynamicShadowOffset.
-struct ShadowMapping {
- ShadowMapping() {
- Scale = ClMappingScale;
- Granularity = ClMappingGranularity;
- Mask = ~(Granularity - 1);
- }
-
- int Scale;
- int Granularity;
- uint64_t Mask; // Computed as ~(Granularity-1)
-};
-
-static uint64_t getCtorAndDtorPriority(Triple &TargetTriple) {
- return TargetTriple.isOSEmscripten() ? MemProfEmscriptenCtorAndDtorPriority
- : MemProfCtorAndDtorPriority;
-}
-
-struct InterestingMemoryAccess {
- Value *Addr = nullptr;
- bool IsWrite;
- unsigned Alignment;
- uint64_t TypeSize;
- Value *MaybeMask = nullptr;
-};
-
-/// Instrument the code in module to profile memory accesses.
-class MemProfiler {
-public:
- MemProfiler(Module &M) {
- C = &(M.getContext());
- LongSize = M.getDataLayout().getPointerSizeInBits();
- IntptrTy = Type::getIntNTy(*C, LongSize);
- }
-
- /// If it is an interesting memory access, populate information
- /// about the access and return a InterestingMemoryAccess struct.
- /// Otherwise return None.
- Optional<InterestingMemoryAccess>
- isInterestingMemoryAccess(Instruction *I) const;
-
- void instrumentMop(Instruction *I, const DataLayout &DL,
- InterestingMemoryAccess &Access);
- void instrumentAddress(Instruction *OrigIns, Instruction *InsertBefore,
- Value *Addr, uint32_t TypeSize, bool IsWrite);
- void instrumentMaskedLoadOrStore(const DataLayout &DL, Value *Mask,
- Instruction *I, Value *Addr,
- unsigned Alignment, uint32_t TypeSize,
- bool IsWrite);
- void instrumentMemIntrinsic(MemIntrinsic *MI);
- Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
- bool instrumentFunction(Function &F);
- bool maybeInsertMemProfInitAtFunctionEntry(Function &F);
- bool insertDynamicShadowAtFunctionEntry(Function &F);
-
-private:
- void initializeCallbacks(Module &M);
-
- LLVMContext *C;
- int LongSize;
- Type *IntptrTy;
- ShadowMapping Mapping;
-
- // These arrays is indexed by AccessIsWrite
- FunctionCallee MemProfMemoryAccessCallback[2];
- FunctionCallee MemProfMemoryAccessCallbackSized[2];
-
- FunctionCallee MemProfMemmove, MemProfMemcpy, MemProfMemset;
- Value *DynamicShadowOffset = nullptr;
-};
-
-class MemProfilerLegacyPass : public FunctionPass {
-public:
- static char ID;
-
- explicit MemProfilerLegacyPass() : FunctionPass(ID) {
- initializeMemProfilerLegacyPassPass(*PassRegistry::getPassRegistry());
- }
-
- StringRef getPassName() const override { return "MemProfilerFunctionPass"; }
-
- bool runOnFunction(Function &F) override {
- MemProfiler Profiler(*F.getParent());
- return Profiler.instrumentFunction(F);
- }
-};
-
-class ModuleMemProfiler {
-public:
- ModuleMemProfiler(Module &M) { TargetTriple = Triple(M.getTargetTriple()); }
-
- bool instrumentModule(Module &);
-
-private:
- Triple TargetTriple;
- ShadowMapping Mapping;
- Function *MemProfCtorFunction = nullptr;
-};
-
-class ModuleMemProfilerLegacyPass : public ModulePass {
-public:
- static char ID;
-
- explicit ModuleMemProfilerLegacyPass() : ModulePass(ID) {
- initializeModuleMemProfilerLegacyPassPass(*PassRegistry::getPassRegistry());
- }
-
- StringRef getPassName() const override { return "ModuleMemProfiler"; }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {}
-
- bool runOnModule(Module &M) override {
- ModuleMemProfiler MemProfiler(M);
- return MemProfiler.instrumentModule(M);
- }
-};
-
-} // end anonymous namespace
-
-MemProfilerPass::MemProfilerPass() {}
-
-PreservedAnalyses MemProfilerPass::run(Function &F,
- AnalysisManager<Function> &AM) {
- Module &M = *F.getParent();
- MemProfiler Profiler(M);
- if (Profiler.instrumentFunction(F))
- return PreservedAnalyses::none();
- return PreservedAnalyses::all();
-
- return PreservedAnalyses::all();
-}
-
-ModuleMemProfilerPass::ModuleMemProfilerPass() {}
-
-PreservedAnalyses ModuleMemProfilerPass::run(Module &M,
- AnalysisManager<Module> &AM) {
- ModuleMemProfiler Profiler(M);
- if (Profiler.instrumentModule(M))
- return PreservedAnalyses::none();
- return PreservedAnalyses::all();
-}
-
-char MemProfilerLegacyPass::ID = 0;
-
-INITIALIZE_PASS_BEGIN(MemProfilerLegacyPass, "memprof",
- "MemProfiler: profile memory allocations and accesses.",
- false, false)
-INITIALIZE_PASS_END(MemProfilerLegacyPass, "memprof",
- "MemProfiler: profile memory allocations and accesses.",
- false, false)
-
-FunctionPass *llvm::createMemProfilerFunctionPass() {
- return new MemProfilerLegacyPass();
-}
-
-char ModuleMemProfilerLegacyPass::ID = 0;
-
-INITIALIZE_PASS(ModuleMemProfilerLegacyPass, "memprof-module",
- "MemProfiler: profile memory allocations and accesses."
- "ModulePass",
- false, false)
-
-ModulePass *llvm::createModuleMemProfilerLegacyPassPass() {
- return new ModuleMemProfilerLegacyPass();
-}
-
-Value *MemProfiler::memToShadow(Value *Shadow, IRBuilder<> &IRB) {
- // (Shadow & mask) >> scale
- Shadow = IRB.CreateAnd(Shadow, Mapping.Mask);
- Shadow = IRB.CreateLShr(Shadow, Mapping.Scale);
- // (Shadow >> scale) | offset
- assert(DynamicShadowOffset);
- return IRB.CreateAdd(Shadow, DynamicShadowOffset);
-}
-
-// Instrument memset/memmove/memcpy
-void MemProfiler::instrumentMemIntrinsic(MemIntrinsic *MI) {
- IRBuilder<> IRB(MI);
- if (isa<MemTransferInst>(MI)) {
- IRB.CreateCall(
- isa<MemMoveInst>(MI) ? MemProfMemmove : MemProfMemcpy,
- {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()),
- IRB.CreatePointerCast(MI->getOperand(1), IRB.getInt8PtrTy()),
- IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
- } else if (isa<MemSetInst>(MI)) {
- IRB.CreateCall(
- MemProfMemset,
- {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()),
- IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false),
- IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
- }
- MI->eraseFromParent();
-}
-
-Optional<InterestingMemoryAccess>
-MemProfiler::isInterestingMemoryAccess(Instruction *I) const {
- // Do not instrument the load fetching the dynamic shadow address.
- if (DynamicShadowOffset == I)
- return None;
-
- InterestingMemoryAccess Access;
-
- const DataLayout &DL = I->getModule()->getDataLayout();
- if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
- if (!ClInstrumentReads)
- return None;
- Access.IsWrite = false;
- Access.TypeSize = DL.getTypeStoreSizeInBits(LI->getType());
- Access.Alignment = LI->getAlignment();
- Access.Addr = LI->getPointerOperand();
- } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
- if (!ClInstrumentWrites)
- return None;
- Access.IsWrite = true;
- Access.TypeSize =
- DL.getTypeStoreSizeInBits(SI->getValueOperand()->getType());
- Access.Alignment = SI->getAlignment();
- Access.Addr = SI->getPointerOperand();
- } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
- if (!ClInstrumentAtomics)
- return None;
- Access.IsWrite = true;
- Access.TypeSize =
- DL.getTypeStoreSizeInBits(RMW->getValOperand()->getType());
- Access.Alignment = 0;
- Access.Addr = RMW->getPointerOperand();
- } else if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) {
- if (!ClInstrumentAtomics)
- return None;
- Access.IsWrite = true;
- Access.TypeSize =
- DL.getTypeStoreSizeInBits(XCHG->getCompareOperand()->getType());
- Access.Alignment = 0;
- Access.Addr = XCHG->getPointerOperand();
- } else if (auto *CI = dyn_cast<CallInst>(I)) {
- auto *F = CI->getCalledFunction();
- if (F && (F->getIntrinsicID() == Intrinsic::masked_load ||
- F->getIntrinsicID() == Intrinsic::masked_store)) {
- unsigned OpOffset = 0;
- if (F->getIntrinsicID() == Intrinsic::masked_store) {
- if (!ClInstrumentWrites)
- return None;
- // Masked store has an initial operand for the value.
- OpOffset = 1;
- Access.IsWrite = true;
- } else {
- if (!ClInstrumentReads)
- return None;
- Access.IsWrite = false;
- }
-
- auto *BasePtr = CI->getOperand(0 + OpOffset);
- auto *Ty = cast<PointerType>(BasePtr->getType())->getElementType();
- Access.TypeSize = DL.getTypeStoreSizeInBits(Ty);
- if (auto *AlignmentConstant =
- dyn_cast<ConstantInt>(CI->getOperand(1 + OpOffset)))
- Access.Alignment = (unsigned)AlignmentConstant->getZExtValue();
- else
- Access.Alignment = 1; // No alignment guarantees. We probably got Undef
- Access.MaybeMask = CI->getOperand(2 + OpOffset);
- Access.Addr = BasePtr;
- }
- }
-
- if (!Access.Addr)
- return None;
-
- // Do not instrument acesses from different address spaces; we cannot deal
- // with them.
- Type *PtrTy = cast<PointerType>(Access.Addr->getType()->getScalarType());
- if (PtrTy->getPointerAddressSpace() != 0)
- return None;
-
- // Ignore swifterror addresses.
- // swifterror memory addresses are mem2reg promoted by instruction
- // selection. As such they cannot have regular uses like an instrumentation
- // function and it makes no sense to track them as memory.
- if (Access.Addr->isSwiftError())
- return None;
-
- return Access;
-}
-
-void MemProfiler::instrumentMaskedLoadOrStore(const DataLayout &DL, Value *Mask,
- Instruction *I, Value *Addr,
- unsigned Alignment,
- uint32_t TypeSize, bool IsWrite) {
- auto *VTy = cast<FixedVectorType>(
- cast<PointerType>(Addr->getType())->getElementType());
- uint64_t ElemTypeSize = DL.getTypeStoreSizeInBits(VTy->getScalarType());
- unsigned Num = VTy->getNumElements();
- auto *Zero = ConstantInt::get(IntptrTy, 0);
- for (unsigned Idx = 0; Idx < Num; ++Idx) {
- Value *InstrumentedAddress = nullptr;
- Instruction *InsertBefore = I;
- if (auto *Vector = dyn_cast<ConstantVector>(Mask)) {
- // dyn_cast as we might get UndefValue
- if (auto *Masked = dyn_cast<ConstantInt>(Vector->getOperand(Idx))) {
- if (Masked->isZero())
- // Mask is constant false, so no instrumentation needed.
- continue;
- // If we have a true or undef value, fall through to instrumentAddress.
- // with InsertBefore == I
- }
- } else {
- IRBuilder<> IRB(I);
- Value *MaskElem = IRB.CreateExtractElement(Mask, Idx);
- Instruction *ThenTerm = SplitBlockAndInsertIfThen(MaskElem, I, false);
- InsertBefore = ThenTerm;
- }
-
- IRBuilder<> IRB(InsertBefore);
- InstrumentedAddress =
- IRB.CreateGEP(VTy, Addr, {Zero, ConstantInt::get(IntptrTy, Idx)});
- instrumentAddress(I, InsertBefore, InstrumentedAddress, ElemTypeSize,
- IsWrite);
- }
-}
-
-void MemProfiler::instrumentMop(Instruction *I, const DataLayout &DL,
- InterestingMemoryAccess &Access) {
- if (Access.IsWrite)
- NumInstrumentedWrites++;
- else
- NumInstrumentedReads++;
-
- if (Access.MaybeMask) {
- instrumentMaskedLoadOrStore(DL, Access.MaybeMask, I, Access.Addr,
- Access.Alignment, Access.TypeSize,
- Access.IsWrite);
- } else {
- // Since the access counts will be accumulated across the entire allocation,
- // we only update the shadow access count for the first location and thus
- // don't need to worry about alignment and type size.
- instrumentAddress(I, I, Access.Addr, Access.TypeSize, Access.IsWrite);
- }
-}
-
-void MemProfiler::instrumentAddress(Instruction *OrigIns,
- Instruction *InsertBefore, Value *Addr,
- uint32_t TypeSize, bool IsWrite) {
- IRBuilder<> IRB(InsertBefore);
- Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
-
- if (ClUseCalls) {
- IRB.CreateCall(MemProfMemoryAccessCallback[IsWrite], AddrLong);
- return;
- }
-
- // Create an inline sequence to compute shadow location, and increment the
- // value by one.
- Type *ShadowTy = Type::getInt64Ty(*C);
- Type *ShadowPtrTy = PointerType::get(ShadowTy, 0);
- Value *ShadowPtr = memToShadow(AddrLong, IRB);
- Value *ShadowAddr = IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy);
- Value *ShadowValue = IRB.CreateLoad(ShadowTy, ShadowAddr);
- Value *Inc = ConstantInt::get(Type::getInt64Ty(*C), 1);
- ShadowValue = IRB.CreateAdd(ShadowValue, Inc);
- IRB.CreateStore(ShadowValue, ShadowAddr);
-}
-
-// Create the variable for the profile file name.
-void createProfileFileNameVar(Module &M) {
- const MDString *MemProfFilename =
- dyn_cast_or_null<MDString>(M.getModuleFlag("MemProfProfileFilename"));
- if (!MemProfFilename)
- return;
- assert(!MemProfFilename->getString().empty() &&
- "Unexpected MemProfProfileFilename metadata with empty string");
- Constant *ProfileNameConst = ConstantDataArray::getString(
- M.getContext(), MemProfFilename->getString(), true);
- GlobalVariable *ProfileNameVar = new GlobalVariable(
- M, ProfileNameConst->getType(), /*isConstant=*/true,
- GlobalValue::WeakAnyLinkage, ProfileNameConst, MemProfFilenameVar);
- Triple TT(M.getTargetTriple());
- if (TT.supportsCOMDAT()) {
- ProfileNameVar->setLinkage(GlobalValue::ExternalLinkage);
- ProfileNameVar->setComdat(M.getOrInsertComdat(MemProfFilenameVar));
- }
-}
-
-bool ModuleMemProfiler::instrumentModule(Module &M) {
- // Create a module constructor.
- std::string MemProfVersion = std::to_string(LLVM_MEM_PROFILER_VERSION);
- std::string VersionCheckName =
- ClInsertVersionCheck ? (MemProfVersionCheckNamePrefix + MemProfVersion)
- : "";
- std::tie(MemProfCtorFunction, std::ignore) =
- createSanitizerCtorAndInitFunctions(M, MemProfModuleCtorName,
- MemProfInitName, /*InitArgTypes=*/{},
- /*InitArgs=*/{}, VersionCheckName);
-
- const uint64_t Priority = getCtorAndDtorPriority(TargetTriple);
- appendToGlobalCtors(M, MemProfCtorFunction, Priority);
-
- createProfileFileNameVar(M);
-
- return true;
-}
-
-void MemProfiler::initializeCallbacks(Module &M) {
- IRBuilder<> IRB(*C);
-
- for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
- const std::string TypeStr = AccessIsWrite ? "store" : "load";
-
- SmallVector<Type *, 3> Args2 = {IntptrTy, IntptrTy};
- SmallVector<Type *, 2> Args1{1, IntptrTy};
- MemProfMemoryAccessCallbackSized[AccessIsWrite] =
- M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + TypeStr + "N",
- FunctionType::get(IRB.getVoidTy(), Args2, false));
-
- MemProfMemoryAccessCallback[AccessIsWrite] =
- M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + TypeStr,
- FunctionType::get(IRB.getVoidTy(), Args1, false));
- }
- MemProfMemmove = M.getOrInsertFunction(
- ClMemoryAccessCallbackPrefix + "memmove", IRB.getInt8PtrTy(),
- IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy);
- MemProfMemcpy = M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + "memcpy",
- IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
- IRB.getInt8PtrTy(), IntptrTy);
- MemProfMemset = M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + "memset",
- IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
- IRB.getInt32Ty(), IntptrTy);
-}
-
-bool MemProfiler::maybeInsertMemProfInitAtFunctionEntry(Function &F) {
- // For each NSObject descendant having a +load method, this method is invoked
- // by the ObjC runtime before any of the static constructors is called.
- // Therefore we need to instrument such methods with a call to __memprof_init
- // at the beginning in order to initialize our runtime before any access to
- // the shadow memory.
- // We cannot just ignore these methods, because they may call other
- // instrumented functions.
- if (F.getName().find(" load]") != std::string::npos) {
- FunctionCallee MemProfInitFunction =
- declareSanitizerInitFunction(*F.getParent(), MemProfInitName, {});
- IRBuilder<> IRB(&F.front(), F.front().begin());
- IRB.CreateCall(MemProfInitFunction, {});
- return true;
- }
- return false;
-}
-
-bool MemProfiler::insertDynamicShadowAtFunctionEntry(Function &F) {
- IRBuilder<> IRB(&F.front().front());
- Value *GlobalDynamicAddress = F.getParent()->getOrInsertGlobal(
- MemProfShadowMemoryDynamicAddress, IntptrTy);
- if (F.getParent()->getPICLevel() == PICLevel::NotPIC)
- cast<GlobalVariable>(GlobalDynamicAddress)->setDSOLocal(true);
- DynamicShadowOffset = IRB.CreateLoad(IntptrTy, GlobalDynamicAddress);
- return true;
-}
-
-bool MemProfiler::instrumentFunction(Function &F) {
- if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage)
- return false;
- if (ClDebugFunc == F.getName())
- return false;
- if (F.getName().startswith("__memprof_"))
- return false;
-
- bool FunctionModified = false;
-
- // If needed, insert __memprof_init.
- // This function needs to be called even if the function body is not
- // instrumented.
- if (maybeInsertMemProfInitAtFunctionEntry(F))
- FunctionModified = true;
-
- LLVM_DEBUG(dbgs() << "MEMPROF instrumenting:\n" << F << "\n");
-
- initializeCallbacks(*F.getParent());
-
- FunctionModified |= insertDynamicShadowAtFunctionEntry(F);
-
- SmallVector<Instruction *, 16> ToInstrument;
-
- // Fill the set of memory operations to instrument.
- for (auto &BB : F) {
- for (auto &Inst : BB) {
- if (isInterestingMemoryAccess(&Inst) || isa<MemIntrinsic>(Inst))
- ToInstrument.push_back(&Inst);
- }
- }
-
- int NumInstrumented = 0;
- for (auto *Inst : ToInstrument) {
- if (ClDebugMin < 0 || ClDebugMax < 0 ||
- (NumInstrumented >= ClDebugMin && NumInstrumented <= ClDebugMax)) {
- Optional<InterestingMemoryAccess> Access =
- isInterestingMemoryAccess(Inst);
- if (Access)
- instrumentMop(Inst, F.getParent()->getDataLayout(), *Access);
- else
- instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
- }
- NumInstrumented++;
- }
-
- if (NumInstrumented > 0)
- FunctionModified = true;
-
- LLVM_DEBUG(dbgs() << "MEMPROF done instrumenting: " << FunctionModified << " "
- << F << "\n");
-
- return FunctionModified;
-}
+//===- MemProfiler.cpp - memory allocation and access profiler ------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of MemProfiler. Memory accesses are instrumented
+// to increment the access count held in a shadow memory location, or
+// alternatively to call into the runtime. Memory intrinsic calls (memmove,
+// memcpy, memset) are changed to call the memory profiling runtime version
+// instead.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Instrumentation/MemProfiler.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Value.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "memprof"
+
+constexpr int LLVM_MEM_PROFILER_VERSION = 1;
+
+// Size of memory mapped to a single shadow location.
+constexpr uint64_t DefaultShadowGranularity = 64;
+
+// Scale from granularity down to shadow size.
+constexpr uint64_t DefaultShadowScale = 3;
+
+constexpr char MemProfModuleCtorName[] = "memprof.module_ctor";
+constexpr uint64_t MemProfCtorAndDtorPriority = 1;
+// On Emscripten, the system needs more than one priorities for constructors.
+constexpr uint64_t MemProfEmscriptenCtorAndDtorPriority = 50;
+constexpr char MemProfInitName[] = "__memprof_init";
+constexpr char MemProfVersionCheckNamePrefix[] =
+ "__memprof_version_mismatch_check_v";
+
+constexpr char MemProfShadowMemoryDynamicAddress[] =
+ "__memprof_shadow_memory_dynamic_address";
+
+constexpr char MemProfFilenameVar[] = "__memprof_profile_filename";
+
+// Command-line flags.
+
+static cl::opt<bool> ClInsertVersionCheck(
+ "memprof-guard-against-version-mismatch",
+ cl::desc("Guard against compiler/runtime version mismatch."), cl::Hidden,
+ cl::init(true));
+
+// This flag may need to be replaced with -f[no-]memprof-reads.
+static cl::opt<bool> ClInstrumentReads("memprof-instrument-reads",
+ cl::desc("instrument read instructions"),
+ cl::Hidden, cl::init(true));
+
+static cl::opt<bool>
+ ClInstrumentWrites("memprof-instrument-writes",
+ cl::desc("instrument write instructions"), cl::Hidden,
+ cl::init(true));
+
+static cl::opt<bool> ClInstrumentAtomics(
+ "memprof-instrument-atomics",
+ cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden,
+ cl::init(true));
+
+static cl::opt<bool> ClUseCalls(
+ "memprof-use-callbacks",
+ cl::desc("Use callbacks instead of inline instrumentation sequences."),
+ cl::Hidden, cl::init(false));
+
+static cl::opt<std::string>
+ ClMemoryAccessCallbackPrefix("memprof-memory-access-callback-prefix",
+ cl::desc("Prefix for memory access callbacks"),
+ cl::Hidden, cl::init("__memprof_"));
+
+// These flags allow to change the shadow mapping.
+// The shadow mapping looks like
+// Shadow = ((Mem & mask) >> scale) + offset
+
+static cl::opt<int> ClMappingScale("memprof-mapping-scale",
+ cl::desc("scale of memprof shadow mapping"),
+ cl::Hidden, cl::init(DefaultShadowScale));
+
+static cl::opt<int>
+ ClMappingGranularity("memprof-mapping-granularity",
+ cl::desc("granularity of memprof shadow mapping"),
+ cl::Hidden, cl::init(DefaultShadowGranularity));
+
+// Debug flags.
+
+static cl::opt<int> ClDebug("memprof-debug", cl::desc("debug"), cl::Hidden,
+ cl::init(0));
+
+static cl::opt<std::string> ClDebugFunc("memprof-debug-func", cl::Hidden,
+ cl::desc("Debug func"));
+
+static cl::opt<int> ClDebugMin("memprof-debug-min", cl::desc("Debug min inst"),
+ cl::Hidden, cl::init(-1));
+
+static cl::opt<int> ClDebugMax("memprof-debug-max", cl::desc("Debug max inst"),
+ cl::Hidden, cl::init(-1));
+
+STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
+STATISTIC(NumInstrumentedWrites, "Number of instrumented writes");
+
+namespace {
+
+/// This struct defines the shadow mapping using the rule:
+/// shadow = ((mem & mask) >> Scale) ADD DynamicShadowOffset.
+struct ShadowMapping {
+ ShadowMapping() {
+ Scale = ClMappingScale;
+ Granularity = ClMappingGranularity;
+ Mask = ~(Granularity - 1);
+ }
+
+ int Scale;
+ int Granularity;
+ uint64_t Mask; // Computed as ~(Granularity-1)
+};
+
+static uint64_t getCtorAndDtorPriority(Triple &TargetTriple) {
+ return TargetTriple.isOSEmscripten() ? MemProfEmscriptenCtorAndDtorPriority
+ : MemProfCtorAndDtorPriority;
+}
+
+struct InterestingMemoryAccess {
+ Value *Addr = nullptr;
+ bool IsWrite;
+ unsigned Alignment;
+ uint64_t TypeSize;
+ Value *MaybeMask = nullptr;
+};
+
+/// Instrument the code in module to profile memory accesses.
+class MemProfiler {
+public:
+ MemProfiler(Module &M) {
+ C = &(M.getContext());
+ LongSize = M.getDataLayout().getPointerSizeInBits();
+ IntptrTy = Type::getIntNTy(*C, LongSize);
+ }
+
+ /// If it is an interesting memory access, populate information
+ /// about the access and return a InterestingMemoryAccess struct.
+ /// Otherwise return None.
+ Optional<InterestingMemoryAccess>
+ isInterestingMemoryAccess(Instruction *I) const;
+
+ void instrumentMop(Instruction *I, const DataLayout &DL,
+ InterestingMemoryAccess &Access);
+ void instrumentAddress(Instruction *OrigIns, Instruction *InsertBefore,
+ Value *Addr, uint32_t TypeSize, bool IsWrite);
+ void instrumentMaskedLoadOrStore(const DataLayout &DL, Value *Mask,
+ Instruction *I, Value *Addr,
+ unsigned Alignment, uint32_t TypeSize,
+ bool IsWrite);
+ void instrumentMemIntrinsic(MemIntrinsic *MI);
+ Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
+ bool instrumentFunction(Function &F);
+ bool maybeInsertMemProfInitAtFunctionEntry(Function &F);
+ bool insertDynamicShadowAtFunctionEntry(Function &F);
+
+private:
+ void initializeCallbacks(Module &M);
+
+ LLVMContext *C;
+ int LongSize;
+ Type *IntptrTy;
+ ShadowMapping Mapping;
+
+ // These arrays is indexed by AccessIsWrite
+ FunctionCallee MemProfMemoryAccessCallback[2];
+ FunctionCallee MemProfMemoryAccessCallbackSized[2];
+
+ FunctionCallee MemProfMemmove, MemProfMemcpy, MemProfMemset;
+ Value *DynamicShadowOffset = nullptr;
+};
+
+class MemProfilerLegacyPass : public FunctionPass {
+public:
+ static char ID;
+
+ explicit MemProfilerLegacyPass() : FunctionPass(ID) {
+ initializeMemProfilerLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+
+ StringRef getPassName() const override { return "MemProfilerFunctionPass"; }
+
+ bool runOnFunction(Function &F) override {
+ MemProfiler Profiler(*F.getParent());
+ return Profiler.instrumentFunction(F);
+ }
+};
+
+class ModuleMemProfiler {
+public:
+ ModuleMemProfiler(Module &M) { TargetTriple = Triple(M.getTargetTriple()); }
+
+ bool instrumentModule(Module &);
+
+private:
+ Triple TargetTriple;
+ ShadowMapping Mapping;
+ Function *MemProfCtorFunction = nullptr;
+};
+
+class ModuleMemProfilerLegacyPass : public ModulePass {
+public:
+ static char ID;
+
+ explicit ModuleMemProfilerLegacyPass() : ModulePass(ID) {
+ initializeModuleMemProfilerLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+
+ StringRef getPassName() const override { return "ModuleMemProfiler"; }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {}
+
+ bool runOnModule(Module &M) override {
+ ModuleMemProfiler MemProfiler(M);
+ return MemProfiler.instrumentModule(M);
+ }
+};
+
+} // end anonymous namespace
+
+MemProfilerPass::MemProfilerPass() {}
+
+PreservedAnalyses MemProfilerPass::run(Function &F,
+ AnalysisManager<Function> &AM) {
+ Module &M = *F.getParent();
+ MemProfiler Profiler(M);
+ if (Profiler.instrumentFunction(F))
+ return PreservedAnalyses::none();
+ return PreservedAnalyses::all();
+
+ return PreservedAnalyses::all();
+}
+
+ModuleMemProfilerPass::ModuleMemProfilerPass() {}
+
+PreservedAnalyses ModuleMemProfilerPass::run(Module &M,
+ AnalysisManager<Module> &AM) {
+ ModuleMemProfiler Profiler(M);
+ if (Profiler.instrumentModule(M))
+ return PreservedAnalyses::none();
+ return PreservedAnalyses::all();
+}
+
+char MemProfilerLegacyPass::ID = 0;
+
+INITIALIZE_PASS_BEGIN(MemProfilerLegacyPass, "memprof",
+ "MemProfiler: profile memory allocations and accesses.",
+ false, false)
+INITIALIZE_PASS_END(MemProfilerLegacyPass, "memprof",
+ "MemProfiler: profile memory allocations and accesses.",
+ false, false)
+
+FunctionPass *llvm::createMemProfilerFunctionPass() {
+ return new MemProfilerLegacyPass();
+}
+
+char ModuleMemProfilerLegacyPass::ID = 0;
+
+INITIALIZE_PASS(ModuleMemProfilerLegacyPass, "memprof-module",
+ "MemProfiler: profile memory allocations and accesses."
+ "ModulePass",
+ false, false)
+
+ModulePass *llvm::createModuleMemProfilerLegacyPassPass() {
+ return new ModuleMemProfilerLegacyPass();
+}
+
+Value *MemProfiler::memToShadow(Value *Shadow, IRBuilder<> &IRB) {
+ // (Shadow & mask) >> scale
+ Shadow = IRB.CreateAnd(Shadow, Mapping.Mask);
+ Shadow = IRB.CreateLShr(Shadow, Mapping.Scale);
+ // (Shadow >> scale) | offset
+ assert(DynamicShadowOffset);
+ return IRB.CreateAdd(Shadow, DynamicShadowOffset);
+}
+
+// Instrument memset/memmove/memcpy
+void MemProfiler::instrumentMemIntrinsic(MemIntrinsic *MI) {
+ IRBuilder<> IRB(MI);
+ if (isa<MemTransferInst>(MI)) {
+ IRB.CreateCall(
+ isa<MemMoveInst>(MI) ? MemProfMemmove : MemProfMemcpy,
+ {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()),
+ IRB.CreatePointerCast(MI->getOperand(1), IRB.getInt8PtrTy()),
+ IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
+ } else if (isa<MemSetInst>(MI)) {
+ IRB.CreateCall(
+ MemProfMemset,
+ {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()),
+ IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false),
+ IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
+ }
+ MI->eraseFromParent();
+}
+
+Optional<InterestingMemoryAccess>
+MemProfiler::isInterestingMemoryAccess(Instruction *I) const {
+ // Do not instrument the load fetching the dynamic shadow address.
+ if (DynamicShadowOffset == I)
+ return None;
+
+ InterestingMemoryAccess Access;
+
+ const DataLayout &DL = I->getModule()->getDataLayout();
+ if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
+ if (!ClInstrumentReads)
+ return None;
+ Access.IsWrite = false;
+ Access.TypeSize = DL.getTypeStoreSizeInBits(LI->getType());
+ Access.Alignment = LI->getAlignment();
+ Access.Addr = LI->getPointerOperand();
+ } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
+ if (!ClInstrumentWrites)
+ return None;
+ Access.IsWrite = true;
+ Access.TypeSize =
+ DL.getTypeStoreSizeInBits(SI->getValueOperand()->getType());
+ Access.Alignment = SI->getAlignment();
+ Access.Addr = SI->getPointerOperand();
+ } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
+ if (!ClInstrumentAtomics)
+ return None;
+ Access.IsWrite = true;
+ Access.TypeSize =
+ DL.getTypeStoreSizeInBits(RMW->getValOperand()->getType());
+ Access.Alignment = 0;
+ Access.Addr = RMW->getPointerOperand();
+ } else if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) {
+ if (!ClInstrumentAtomics)
+ return None;
+ Access.IsWrite = true;
+ Access.TypeSize =
+ DL.getTypeStoreSizeInBits(XCHG->getCompareOperand()->getType());
+ Access.Alignment = 0;
+ Access.Addr = XCHG->getPointerOperand();
+ } else if (auto *CI = dyn_cast<CallInst>(I)) {
+ auto *F = CI->getCalledFunction();
+ if (F && (F->getIntrinsicID() == Intrinsic::masked_load ||
+ F->getIntrinsicID() == Intrinsic::masked_store)) {
+ unsigned OpOffset = 0;
+ if (F->getIntrinsicID() == Intrinsic::masked_store) {
+ if (!ClInstrumentWrites)
+ return None;
+ // Masked store has an initial operand for the value.
+ OpOffset = 1;
+ Access.IsWrite = true;
+ } else {
+ if (!ClInstrumentReads)
+ return None;
+ Access.IsWrite = false;
+ }
+
+ auto *BasePtr = CI->getOperand(0 + OpOffset);
+ auto *Ty = cast<PointerType>(BasePtr->getType())->getElementType();
+ Access.TypeSize = DL.getTypeStoreSizeInBits(Ty);
+ if (auto *AlignmentConstant =
+ dyn_cast<ConstantInt>(CI->getOperand(1 + OpOffset)))
+ Access.Alignment = (unsigned)AlignmentConstant->getZExtValue();
+ else
+ Access.Alignment = 1; // No alignment guarantees. We probably got Undef
+ Access.MaybeMask = CI->getOperand(2 + OpOffset);
+ Access.Addr = BasePtr;
+ }
+ }
+
+ if (!Access.Addr)
+ return None;
+
+ // Do not instrument acesses from different address spaces; we cannot deal
+ // with them.
+ Type *PtrTy = cast<PointerType>(Access.Addr->getType()->getScalarType());
+ if (PtrTy->getPointerAddressSpace() != 0)
+ return None;
+
+ // Ignore swifterror addresses.
+ // swifterror memory addresses are mem2reg promoted by instruction
+ // selection. As such they cannot have regular uses like an instrumentation
+ // function and it makes no sense to track them as memory.
+ if (Access.Addr->isSwiftError())
+ return None;
+
+ return Access;
+}
+
+void MemProfiler::instrumentMaskedLoadOrStore(const DataLayout &DL, Value *Mask,
+ Instruction *I, Value *Addr,
+ unsigned Alignment,
+ uint32_t TypeSize, bool IsWrite) {
+ auto *VTy = cast<FixedVectorType>(
+ cast<PointerType>(Addr->getType())->getElementType());
+ uint64_t ElemTypeSize = DL.getTypeStoreSizeInBits(VTy->getScalarType());
+ unsigned Num = VTy->getNumElements();
+ auto *Zero = ConstantInt::get(IntptrTy, 0);
+ for (unsigned Idx = 0; Idx < Num; ++Idx) {
+ Value *InstrumentedAddress = nullptr;
+ Instruction *InsertBefore = I;
+ if (auto *Vector = dyn_cast<ConstantVector>(Mask)) {
+ // dyn_cast as we might get UndefValue
+ if (auto *Masked = dyn_cast<ConstantInt>(Vector->getOperand(Idx))) {
+ if (Masked->isZero())
+ // Mask is constant false, so no instrumentation needed.
+ continue;
+ // If we have a true or undef value, fall through to instrumentAddress.
+ // with InsertBefore == I
+ }
+ } else {
+ IRBuilder<> IRB(I);
+ Value *MaskElem = IRB.CreateExtractElement(Mask, Idx);
+ Instruction *ThenTerm = SplitBlockAndInsertIfThen(MaskElem, I, false);
+ InsertBefore = ThenTerm;
+ }
+
+ IRBuilder<> IRB(InsertBefore);
+ InstrumentedAddress =
+ IRB.CreateGEP(VTy, Addr, {Zero, ConstantInt::get(IntptrTy, Idx)});
+ instrumentAddress(I, InsertBefore, InstrumentedAddress, ElemTypeSize,
+ IsWrite);
+ }
+}
+
+void MemProfiler::instrumentMop(Instruction *I, const DataLayout &DL,
+ InterestingMemoryAccess &Access) {
+ if (Access.IsWrite)
+ NumInstrumentedWrites++;
+ else
+ NumInstrumentedReads++;
+
+ if (Access.MaybeMask) {
+ instrumentMaskedLoadOrStore(DL, Access.MaybeMask, I, Access.Addr,
+ Access.Alignment, Access.TypeSize,
+ Access.IsWrite);
+ } else {
+ // Since the access counts will be accumulated across the entire allocation,
+ // we only update the shadow access count for the first location and thus
+ // don't need to worry about alignment and type size.
+ instrumentAddress(I, I, Access.Addr, Access.TypeSize, Access.IsWrite);
+ }
+}
+
+void MemProfiler::instrumentAddress(Instruction *OrigIns,
+ Instruction *InsertBefore, Value *Addr,
+ uint32_t TypeSize, bool IsWrite) {
+ IRBuilder<> IRB(InsertBefore);
+ Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
+
+ if (ClUseCalls) {
+ IRB.CreateCall(MemProfMemoryAccessCallback[IsWrite], AddrLong);
+ return;
+ }
+
+ // Create an inline sequence to compute shadow location, and increment the
+ // value by one.
+ Type *ShadowTy = Type::getInt64Ty(*C);
+ Type *ShadowPtrTy = PointerType::get(ShadowTy, 0);
+ Value *ShadowPtr = memToShadow(AddrLong, IRB);
+ Value *ShadowAddr = IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy);
+ Value *ShadowValue = IRB.CreateLoad(ShadowTy, ShadowAddr);
+ Value *Inc = ConstantInt::get(Type::getInt64Ty(*C), 1);
+ ShadowValue = IRB.CreateAdd(ShadowValue, Inc);
+ IRB.CreateStore(ShadowValue, ShadowAddr);
+}
+
+// Create the variable for the profile file name.
+void createProfileFileNameVar(Module &M) {
+ const MDString *MemProfFilename =
+ dyn_cast_or_null<MDString>(M.getModuleFlag("MemProfProfileFilename"));
+ if (!MemProfFilename)
+ return;
+ assert(!MemProfFilename->getString().empty() &&
+ "Unexpected MemProfProfileFilename metadata with empty string");
+ Constant *ProfileNameConst = ConstantDataArray::getString(
+ M.getContext(), MemProfFilename->getString(), true);
+ GlobalVariable *ProfileNameVar = new GlobalVariable(
+ M, ProfileNameConst->getType(), /*isConstant=*/true,
+ GlobalValue::WeakAnyLinkage, ProfileNameConst, MemProfFilenameVar);
+ Triple TT(M.getTargetTriple());
+ if (TT.supportsCOMDAT()) {
+ ProfileNameVar->setLinkage(GlobalValue::ExternalLinkage);
+ ProfileNameVar->setComdat(M.getOrInsertComdat(MemProfFilenameVar));
+ }
+}
+
+bool ModuleMemProfiler::instrumentModule(Module &M) {
+ // Create a module constructor.
+ std::string MemProfVersion = std::to_string(LLVM_MEM_PROFILER_VERSION);
+ std::string VersionCheckName =
+ ClInsertVersionCheck ? (MemProfVersionCheckNamePrefix + MemProfVersion)
+ : "";
+ std::tie(MemProfCtorFunction, std::ignore) =
+ createSanitizerCtorAndInitFunctions(M, MemProfModuleCtorName,
+ MemProfInitName, /*InitArgTypes=*/{},
+ /*InitArgs=*/{}, VersionCheckName);
+
+ const uint64_t Priority = getCtorAndDtorPriority(TargetTriple);
+ appendToGlobalCtors(M, MemProfCtorFunction, Priority);
+
+ createProfileFileNameVar(M);
+
+ return true;
+}
+
+void MemProfiler::initializeCallbacks(Module &M) {
+ IRBuilder<> IRB(*C);
+
+ for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
+ const std::string TypeStr = AccessIsWrite ? "store" : "load";
+
+ SmallVector<Type *, 3> Args2 = {IntptrTy, IntptrTy};
+ SmallVector<Type *, 2> Args1{1, IntptrTy};
+ MemProfMemoryAccessCallbackSized[AccessIsWrite] =
+ M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + TypeStr + "N",
+ FunctionType::get(IRB.getVoidTy(), Args2, false));
+
+ MemProfMemoryAccessCallback[AccessIsWrite] =
+ M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + TypeStr,
+ FunctionType::get(IRB.getVoidTy(), Args1, false));
+ }
+ MemProfMemmove = M.getOrInsertFunction(
+ ClMemoryAccessCallbackPrefix + "memmove", IRB.getInt8PtrTy(),
+ IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy);
+ MemProfMemcpy = M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + "memcpy",
+ IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
+ IRB.getInt8PtrTy(), IntptrTy);
+ MemProfMemset = M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + "memset",
+ IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
+ IRB.getInt32Ty(), IntptrTy);
+}
+
+bool MemProfiler::maybeInsertMemProfInitAtFunctionEntry(Function &F) {
+ // For each NSObject descendant having a +load method, this method is invoked
+ // by the ObjC runtime before any of the static constructors is called.
+ // Therefore we need to instrument such methods with a call to __memprof_init
+ // at the beginning in order to initialize our runtime before any access to
+ // the shadow memory.
+ // We cannot just ignore these methods, because they may call other
+ // instrumented functions.
+ if (F.getName().find(" load]") != std::string::npos) {
+ FunctionCallee MemProfInitFunction =
+ declareSanitizerInitFunction(*F.getParent(), MemProfInitName, {});
+ IRBuilder<> IRB(&F.front(), F.front().begin());
+ IRB.CreateCall(MemProfInitFunction, {});
+ return true;
+ }
+ return false;
+}
+
+bool MemProfiler::insertDynamicShadowAtFunctionEntry(Function &F) {
+ IRBuilder<> IRB(&F.front().front());
+ Value *GlobalDynamicAddress = F.getParent()->getOrInsertGlobal(
+ MemProfShadowMemoryDynamicAddress, IntptrTy);
+ if (F.getParent()->getPICLevel() == PICLevel::NotPIC)
+ cast<GlobalVariable>(GlobalDynamicAddress)->setDSOLocal(true);
+ DynamicShadowOffset = IRB.CreateLoad(IntptrTy, GlobalDynamicAddress);
+ return true;
+}
+
+bool MemProfiler::instrumentFunction(Function &F) {
+ if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage)
+ return false;
+ if (ClDebugFunc == F.getName())
+ return false;
+ if (F.getName().startswith("__memprof_"))
+ return false;
+
+ bool FunctionModified = false;
+
+ // If needed, insert __memprof_init.
+ // This function needs to be called even if the function body is not
+ // instrumented.
+ if (maybeInsertMemProfInitAtFunctionEntry(F))
+ FunctionModified = true;
+
+ LLVM_DEBUG(dbgs() << "MEMPROF instrumenting:\n" << F << "\n");
+
+ initializeCallbacks(*F.getParent());
+
+ FunctionModified |= insertDynamicShadowAtFunctionEntry(F);
+
+ SmallVector<Instruction *, 16> ToInstrument;
+
+ // Fill the set of memory operations to instrument.
+ for (auto &BB : F) {
+ for (auto &Inst : BB) {
+ if (isInterestingMemoryAccess(&Inst) || isa<MemIntrinsic>(Inst))
+ ToInstrument.push_back(&Inst);
+ }
+ }
+
+ int NumInstrumented = 0;
+ for (auto *Inst : ToInstrument) {
+ if (ClDebugMin < 0 || ClDebugMax < 0 ||
+ (NumInstrumented >= ClDebugMin && NumInstrumented <= ClDebugMax)) {
+ Optional<InterestingMemoryAccess> Access =
+ isInterestingMemoryAccess(Inst);
+ if (Access)
+ instrumentMop(Inst, F.getParent()->getDataLayout(), *Access);
+ else
+ instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
+ }
+ NumInstrumented++;
+ }
+
+ if (NumInstrumented > 0)
+ FunctionModified = true;
+
+ LLVM_DEBUG(dbgs() << "MEMPROF done instrumenting: " << FunctionModified << " "
+ << F << "\n");
+
+ return FunctionModified;
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/contrib/libs/llvm12/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index affc204924..7a6874584d 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -153,7 +153,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
@@ -338,8 +338,8 @@ static cl::opt<uint64_t> ClOriginBase("msan-origin-base",
cl::desc("Define custom MSan OriginBase"),
cl::Hidden, cl::init(0));
-const char kMsanModuleCtorName[] = "msan.module_ctor";
-const char kMsanInitName[] = "__msan_init";
+const char kMsanModuleCtorName[] = "msan.module_ctor";
+const char kMsanInitName[] = "__msan_init";
namespace {
@@ -573,9 +573,9 @@ private:
/// uninitialized value and returns an updated origin id encoding this info.
FunctionCallee MsanChainOriginFn;
- /// Run-time helper that paints an origin over a region.
- FunctionCallee MsanSetOriginFn;
-
+ /// Run-time helper that paints an origin over a region.
+ FunctionCallee MsanSetOriginFn;
+
/// MSan runtime replacements for memmove, memcpy and memset.
FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
@@ -854,9 +854,9 @@ void MemorySanitizer::initializeCallbacks(Module &M) {
// instrumentation.
MsanChainOriginFn = M.getOrInsertFunction(
"__msan_chain_origin", IRB.getInt32Ty(), IRB.getInt32Ty());
- MsanSetOriginFn =
- M.getOrInsertFunction("__msan_set_origin", IRB.getVoidTy(),
- IRB.getInt8PtrTy(), IntptrTy, IRB.getInt32Ty());
+ MsanSetOriginFn =
+ M.getOrInsertFunction("__msan_set_origin", IRB.getVoidTy(),
+ IRB.getInt8PtrTy(), IntptrTy, IRB.getInt32Ty());
MemmoveFn = M.getOrInsertFunction(
"__msan_memmove", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
IRB.getInt8PtrTy(), IntptrTy);
@@ -1056,7 +1056,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
ValueMap<Value*, Value*> ShadowMap, OriginMap;
std::unique_ptr<VarArgHelper> VAHelper;
const TargetLibraryInfo *TLI;
- Instruction *FnPrologueEnd;
+ Instruction *FnPrologueEnd;
// The following flags disable parts of MSan instrumentation based on
// exclusion list contents and command-line options.
@@ -1088,31 +1088,31 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
PoisonStack = SanitizeFunction && ClPoisonStack;
PoisonUndef = SanitizeFunction && ClPoisonUndef;
- // In the presence of unreachable blocks, we may see Phi nodes with
- // incoming nodes from such blocks. Since InstVisitor skips unreachable
- // blocks, such nodes will not have any shadow value associated with them.
- // It's easier to remove unreachable blocks than deal with missing shadow.
- removeUnreachableBlocks(F);
-
+ // In the presence of unreachable blocks, we may see Phi nodes with
+ // incoming nodes from such blocks. Since InstVisitor skips unreachable
+ // blocks, such nodes will not have any shadow value associated with them.
+ // It's easier to remove unreachable blocks than deal with missing shadow.
+ removeUnreachableBlocks(F);
+
MS.initializeCallbacks(*F.getParent());
- FnPrologueEnd = IRBuilder<>(F.getEntryBlock().getFirstNonPHI())
- .CreateIntrinsic(Intrinsic::donothing, {}, {});
-
- if (MS.CompileKernel) {
- IRBuilder<> IRB(FnPrologueEnd);
- insertKmsanPrologue(IRB);
- }
-
+ FnPrologueEnd = IRBuilder<>(F.getEntryBlock().getFirstNonPHI())
+ .CreateIntrinsic(Intrinsic::donothing, {}, {});
+
+ if (MS.CompileKernel) {
+ IRBuilder<> IRB(FnPrologueEnd);
+ insertKmsanPrologue(IRB);
+ }
+
LLVM_DEBUG(if (!InsertChecks) dbgs()
<< "MemorySanitizer is not inserting checks into '"
<< F.getName() << "'\n");
}
- bool isInPrologue(Instruction &I) {
- return I.getParent() == FnPrologueEnd->getParent() &&
- (&I == FnPrologueEnd || I.comesBefore(FnPrologueEnd));
- }
-
+ bool isInPrologue(Instruction &I) {
+ return I.getParent() == FnPrologueEnd->getParent() &&
+ (&I == FnPrologueEnd || I.comesBefore(FnPrologueEnd));
+ }
+
Value *updateOrigin(Value *V, IRBuilder<> &IRB) {
if (MS.TrackOrigins <= 1) return V;
return IRB.CreateCall(MS.MsanChainOriginFn, V);
@@ -1164,31 +1164,31 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
const DataLayout &DL = F.getParent()->getDataLayout();
const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
unsigned StoreSize = DL.getTypeStoreSize(Shadow->getType());
- Value *ConvertedShadow = convertShadowToScalar(Shadow, IRB);
- if (auto *ConstantShadow = dyn_cast<Constant>(ConvertedShadow)) {
- if (ClCheckConstantShadow && !ConstantShadow->isZeroValue())
- paintOrigin(IRB, updateOrigin(Origin, IRB), OriginPtr, StoreSize,
+ Value *ConvertedShadow = convertShadowToScalar(Shadow, IRB);
+ if (auto *ConstantShadow = dyn_cast<Constant>(ConvertedShadow)) {
+ if (ClCheckConstantShadow && !ConstantShadow->isZeroValue())
+ paintOrigin(IRB, updateOrigin(Origin, IRB), OriginPtr, StoreSize,
OriginAlignment);
- return;
+ return;
+ }
+
+ unsigned TypeSizeInBits = DL.getTypeSizeInBits(ConvertedShadow->getType());
+ unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
+ if (AsCall && SizeIndex < kNumberOfAccessSizes && !MS.CompileKernel) {
+ FunctionCallee Fn = MS.MaybeStoreOriginFn[SizeIndex];
+ Value *ConvertedShadow2 =
+ IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
+ IRB.CreateCall(Fn,
+ {ConvertedShadow2,
+ IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()), Origin});
+ } else {
+ Value *Cmp = convertToBool(ConvertedShadow, IRB, "_mscmp");
+ Instruction *CheckTerm = SplitBlockAndInsertIfThen(
+ Cmp, &*IRB.GetInsertPoint(), false, MS.OriginStoreWeights);
+ IRBuilder<> IRBNew(CheckTerm);
+ paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), OriginPtr, StoreSize,
+ OriginAlignment);
}
-
- unsigned TypeSizeInBits = DL.getTypeSizeInBits(ConvertedShadow->getType());
- unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
- if (AsCall && SizeIndex < kNumberOfAccessSizes && !MS.CompileKernel) {
- FunctionCallee Fn = MS.MaybeStoreOriginFn[SizeIndex];
- Value *ConvertedShadow2 =
- IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
- IRB.CreateCall(Fn,
- {ConvertedShadow2,
- IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()), Origin});
- } else {
- Value *Cmp = convertToBool(ConvertedShadow, IRB, "_mscmp");
- Instruction *CheckTerm = SplitBlockAndInsertIfThen(
- Cmp, &*IRB.GetInsertPoint(), false, MS.OriginStoreWeights);
- IRBuilder<> IRBNew(CheckTerm);
- paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), OriginPtr, StoreSize,
- OriginAlignment);
- }
}
void materializeStores(bool InstrumentWithCalls) {
@@ -1232,7 +1232,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
bool AsCall) {
IRBuilder<> IRB(OrigIns);
LLVM_DEBUG(dbgs() << " SHAD0 : " << *Shadow << "\n");
- Value *ConvertedShadow = convertShadowToScalar(Shadow, IRB);
+ Value *ConvertedShadow = convertShadowToScalar(Shadow, IRB);
LLVM_DEBUG(dbgs() << " SHAD1 : " << *ConvertedShadow << "\n");
if (auto *ConstantShadow = dyn_cast<Constant>(ConvertedShadow)) {
@@ -1254,7 +1254,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
? Origin
: (Value *)IRB.getInt32(0)});
} else {
- Value *Cmp = convertToBool(ConvertedShadow, IRB, "_mscmp");
+ Value *Cmp = convertToBool(ConvertedShadow, IRB, "_mscmp");
Instruction *CheckTerm = SplitBlockAndInsertIfThen(
Cmp, OrigIns,
/* Unreachable */ !MS.Recover, MS.ColdCallWeights);
@@ -1275,8 +1275,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
LLVM_DEBUG(dbgs() << "DONE:\n" << F);
}
- // Returns the last instruction in the new prologue
- void insertKmsanPrologue(IRBuilder<> &IRB) {
+ // Returns the last instruction in the new prologue
+ void insertKmsanPrologue(IRBuilder<> &IRB) {
Value *ContextState = IRB.CreateCall(MS.MsanGetContextStateFn, {});
Constant *Zero = IRB.getInt32(0);
MS.ParamTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
@@ -1302,7 +1302,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
// Iterate all BBs in depth-first order and create shadow instructions
// for all instructions (where applicable).
// For PHI nodes we create dummy shadow PHIs which will be finalized later.
- for (BasicBlock *BB : depth_first(FnPrologueEnd->getParent()))
+ for (BasicBlock *BB : depth_first(FnPrologueEnd->getParent()))
visit(*BB);
// Finalize PHI nodes.
@@ -1389,68 +1389,68 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
return ty;
}
- /// Extract combined shadow of struct elements as a bool
- Value *collapseStructShadow(StructType *Struct, Value *Shadow,
- IRBuilder<> &IRB) {
- Value *FalseVal = IRB.getIntN(/* width */ 1, /* value */ 0);
- Value *Aggregator = FalseVal;
-
- for (unsigned Idx = 0; Idx < Struct->getNumElements(); Idx++) {
- // Combine by ORing together each element's bool shadow
- Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
- Value *ShadowInner = convertShadowToScalar(ShadowItem, IRB);
- Value *ShadowBool = convertToBool(ShadowInner, IRB);
-
- if (Aggregator != FalseVal)
- Aggregator = IRB.CreateOr(Aggregator, ShadowBool);
- else
- Aggregator = ShadowBool;
- }
-
- return Aggregator;
- }
-
- // Extract combined shadow of array elements
- Value *collapseArrayShadow(ArrayType *Array, Value *Shadow,
- IRBuilder<> &IRB) {
- if (!Array->getNumElements())
- return IRB.getIntN(/* width */ 1, /* value */ 0);
-
- Value *FirstItem = IRB.CreateExtractValue(Shadow, 0);
- Value *Aggregator = convertShadowToScalar(FirstItem, IRB);
-
- for (unsigned Idx = 1; Idx < Array->getNumElements(); Idx++) {
- Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
- Value *ShadowInner = convertShadowToScalar(ShadowItem, IRB);
- Aggregator = IRB.CreateOr(Aggregator, ShadowInner);
- }
- return Aggregator;
- }
-
- /// Convert a shadow value to it's flattened variant. The resulting
- /// shadow may not necessarily have the same bit width as the input
- /// value, but it will always be comparable to zero.
- Value *convertShadowToScalar(Value *V, IRBuilder<> &IRB) {
- if (StructType *Struct = dyn_cast<StructType>(V->getType()))
- return collapseStructShadow(Struct, V, IRB);
- if (ArrayType *Array = dyn_cast<ArrayType>(V->getType()))
- return collapseArrayShadow(Array, V, IRB);
+ /// Extract combined shadow of struct elements as a bool
+ Value *collapseStructShadow(StructType *Struct, Value *Shadow,
+ IRBuilder<> &IRB) {
+ Value *FalseVal = IRB.getIntN(/* width */ 1, /* value */ 0);
+ Value *Aggregator = FalseVal;
+
+ for (unsigned Idx = 0; Idx < Struct->getNumElements(); Idx++) {
+ // Combine by ORing together each element's bool shadow
+ Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
+ Value *ShadowInner = convertShadowToScalar(ShadowItem, IRB);
+ Value *ShadowBool = convertToBool(ShadowInner, IRB);
+
+ if (Aggregator != FalseVal)
+ Aggregator = IRB.CreateOr(Aggregator, ShadowBool);
+ else
+ Aggregator = ShadowBool;
+ }
+
+ return Aggregator;
+ }
+
+ // Extract combined shadow of array elements
+ Value *collapseArrayShadow(ArrayType *Array, Value *Shadow,
+ IRBuilder<> &IRB) {
+ if (!Array->getNumElements())
+ return IRB.getIntN(/* width */ 1, /* value */ 0);
+
+ Value *FirstItem = IRB.CreateExtractValue(Shadow, 0);
+ Value *Aggregator = convertShadowToScalar(FirstItem, IRB);
+
+ for (unsigned Idx = 1; Idx < Array->getNumElements(); Idx++) {
+ Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
+ Value *ShadowInner = convertShadowToScalar(ShadowItem, IRB);
+ Aggregator = IRB.CreateOr(Aggregator, ShadowInner);
+ }
+ return Aggregator;
+ }
+
+ /// Convert a shadow value to it's flattened variant. The resulting
+ /// shadow may not necessarily have the same bit width as the input
+ /// value, but it will always be comparable to zero.
+ Value *convertShadowToScalar(Value *V, IRBuilder<> &IRB) {
+ if (StructType *Struct = dyn_cast<StructType>(V->getType()))
+ return collapseStructShadow(Struct, V, IRB);
+ if (ArrayType *Array = dyn_cast<ArrayType>(V->getType()))
+ return collapseArrayShadow(Array, V, IRB);
Type *Ty = V->getType();
Type *NoVecTy = getShadowTyNoVec(Ty);
if (Ty == NoVecTy) return V;
return IRB.CreateBitCast(V, NoVecTy);
}
- // Convert a scalar value to an i1 by comparing with 0
- Value *convertToBool(Value *V, IRBuilder<> &IRB, const Twine &name = "") {
- Type *VTy = V->getType();
- assert(VTy->isIntegerTy());
- if (VTy->getIntegerBitWidth() == 1)
- // Just converting a bool to a bool, so do nothing.
- return V;
- return IRB.CreateICmpNE(V, ConstantInt::get(VTy, 0), name);
- }
-
+ // Convert a scalar value to an i1 by comparing with 0
+ Value *convertToBool(Value *V, IRBuilder<> &IRB, const Twine &name = "") {
+ Type *VTy = V->getType();
+ assert(VTy->isIntegerTy());
+ if (VTy->getIntegerBitWidth() == 1)
+ // Just converting a bool to a bool, so do nothing.
+ return V;
+ return IRB.CreateICmpNE(V, ConstantInt::get(VTy, 0), name);
+ }
+
/// Compute the integer shadow offset that corresponds to a given
/// application address.
///
@@ -1669,7 +1669,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
if (*ShadowPtr)
return *ShadowPtr;
Function *F = A->getParent();
- IRBuilder<> EntryIRB(FnPrologueEnd);
+ IRBuilder<> EntryIRB(FnPrologueEnd);
unsigned ArgOffset = 0;
const DataLayout &DL = F->getParent()->getDataLayout();
for (auto &FArg : F->args()) {
@@ -1737,8 +1737,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
} else {
setOrigin(A, getCleanOrigin());
}
-
- break;
+
+ break;
}
if (!FArgEagerCheck)
@@ -1786,10 +1786,10 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
if (!InsertChecks) return;
#ifndef NDEBUG
Type *ShadowTy = Shadow->getType();
- assert((isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy) ||
- isa<StructType>(ShadowTy) || isa<ArrayType>(ShadowTy)) &&
- "Can only insert checks for integer, vector, and aggregate shadow "
- "types");
+ assert((isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy) ||
+ isa<StructType>(ShadowTy) || isa<ArrayType>(ShadowTy)) &&
+ "Can only insert checks for integer, vector, and aggregate shadow "
+ "types");
#endif
InstrumentationList.push_back(
ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns));
@@ -1831,24 +1831,24 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
llvm_unreachable("Unknown ordering");
}
- Value *makeAddReleaseOrderingTable(IRBuilder<> &IRB) {
- constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
- uint32_t OrderingTable[NumOrderings] = {};
-
- OrderingTable[(int)AtomicOrderingCABI::relaxed] =
- OrderingTable[(int)AtomicOrderingCABI::release] =
- (int)AtomicOrderingCABI::release;
- OrderingTable[(int)AtomicOrderingCABI::consume] =
- OrderingTable[(int)AtomicOrderingCABI::acquire] =
- OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
- (int)AtomicOrderingCABI::acq_rel;
- OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
- (int)AtomicOrderingCABI::seq_cst;
-
- return ConstantDataVector::get(IRB.getContext(),
- makeArrayRef(OrderingTable, NumOrderings));
- }
-
+ Value *makeAddReleaseOrderingTable(IRBuilder<> &IRB) {
+ constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
+ uint32_t OrderingTable[NumOrderings] = {};
+
+ OrderingTable[(int)AtomicOrderingCABI::relaxed] =
+ OrderingTable[(int)AtomicOrderingCABI::release] =
+ (int)AtomicOrderingCABI::release;
+ OrderingTable[(int)AtomicOrderingCABI::consume] =
+ OrderingTable[(int)AtomicOrderingCABI::acquire] =
+ OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
+ (int)AtomicOrderingCABI::acq_rel;
+ OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
+ (int)AtomicOrderingCABI::seq_cst;
+
+ return ConstantDataVector::get(IRB.getContext(),
+ makeArrayRef(OrderingTable, NumOrderings));
+ }
+
AtomicOrdering addAcquireOrdering(AtomicOrdering a) {
switch (a) {
case AtomicOrdering::NotAtomic:
@@ -1866,33 +1866,33 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
llvm_unreachable("Unknown ordering");
}
- Value *makeAddAcquireOrderingTable(IRBuilder<> &IRB) {
- constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
- uint32_t OrderingTable[NumOrderings] = {};
-
- OrderingTable[(int)AtomicOrderingCABI::relaxed] =
- OrderingTable[(int)AtomicOrderingCABI::acquire] =
- OrderingTable[(int)AtomicOrderingCABI::consume] =
- (int)AtomicOrderingCABI::acquire;
- OrderingTable[(int)AtomicOrderingCABI::release] =
- OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
- (int)AtomicOrderingCABI::acq_rel;
- OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
- (int)AtomicOrderingCABI::seq_cst;
-
- return ConstantDataVector::get(IRB.getContext(),
- makeArrayRef(OrderingTable, NumOrderings));
- }
-
+ Value *makeAddAcquireOrderingTable(IRBuilder<> &IRB) {
+ constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
+ uint32_t OrderingTable[NumOrderings] = {};
+
+ OrderingTable[(int)AtomicOrderingCABI::relaxed] =
+ OrderingTable[(int)AtomicOrderingCABI::acquire] =
+ OrderingTable[(int)AtomicOrderingCABI::consume] =
+ (int)AtomicOrderingCABI::acquire;
+ OrderingTable[(int)AtomicOrderingCABI::release] =
+ OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
+ (int)AtomicOrderingCABI::acq_rel;
+ OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
+ (int)AtomicOrderingCABI::seq_cst;
+
+ return ConstantDataVector::get(IRB.getContext(),
+ makeArrayRef(OrderingTable, NumOrderings));
+ }
+
// ------------------- Visitors.
using InstVisitor<MemorySanitizerVisitor>::visit;
void visit(Instruction &I) {
- if (I.getMetadata("nosanitize"))
- return;
- // Don't want to visit if we're in the prologue
- if (isInPrologue(I))
- return;
- InstVisitor<MemorySanitizerVisitor>::visit(I);
+ if (I.getMetadata("nosanitize"))
+ return;
+ // Don't want to visit if we're in the prologue
+ if (isInPrologue(I))
+ return;
+ InstVisitor<MemorySanitizerVisitor>::visit(I);
}
/// Instrument LoadInst
@@ -2148,7 +2148,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
Constant *ConstOrigin = dyn_cast<Constant>(OpOrigin);
// No point in adding something that might result in 0 origin value.
if (!ConstOrigin || !ConstOrigin->isNullValue()) {
- Value *FlatShadow = MSV->convertShadowToScalar(OpShadow, IRB);
+ Value *FlatShadow = MSV->convertShadowToScalar(OpShadow, IRB);
Value *Cond =
IRB.CreateICmpNE(FlatShadow, MSV->getCleanShadow(FlatShadow));
Origin = IRB.CreateSelect(Cond, OpOrigin, Origin);
@@ -2703,7 +2703,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
void handleLifetimeStart(IntrinsicInst &I) {
if (!PoisonStack)
return;
- AllocaInst *AI = llvm::findAllocaForValue(I.getArgOperand(1));
+ AllocaInst *AI = llvm::findAllocaForValue(I.getArgOperand(1));
if (!AI)
InstrumentLifetimeStart = false;
LifetimeStartList.push_back(std::make_pair(&I, AI));
@@ -2734,16 +2734,16 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
// We copy the shadow of \p CopyOp[NumUsedElements:] to \p
// Out[NumUsedElements:]. This means that intrinsics without \p CopyOp always
// return a fully initialized value.
- void handleVectorConvertIntrinsic(IntrinsicInst &I, int NumUsedElements,
- bool HasRoundingMode = false) {
+ void handleVectorConvertIntrinsic(IntrinsicInst &I, int NumUsedElements,
+ bool HasRoundingMode = false) {
IRBuilder<> IRB(&I);
Value *CopyOp, *ConvertOp;
- assert((!HasRoundingMode ||
- isa<ConstantInt>(I.getArgOperand(I.getNumArgOperands() - 1))) &&
- "Invalid rounding mode");
-
- switch (I.getNumArgOperands() - HasRoundingMode) {
+ assert((!HasRoundingMode ||
+ isa<ConstantInt>(I.getArgOperand(I.getNumArgOperands() - 1))) &&
+ "Invalid rounding mode");
+
+ switch (I.getNumArgOperands() - HasRoundingMode) {
case 2:
CopyOp = I.getArgOperand(0);
ConvertOp = I.getArgOperand(1);
@@ -2999,7 +2999,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
setOrigin(&I, getOrigin(&I, 0));
}
- // Instrument vector.reduce.or intrinsic.
+ // Instrument vector.reduce.or intrinsic.
// Valid (non-poisoned) set bits in the operand pull low the
// corresponding shadow bits.
void handleVectorReduceOrIntrinsic(IntrinsicInst &I) {
@@ -3017,7 +3017,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
setOrigin(&I, getOrigin(&I, 0));
}
- // Instrument vector.reduce.and intrinsic.
+ // Instrument vector.reduce.and intrinsic.
// Valid (non-poisoned) unset bits in the operand pull down the
// corresponding shadow bits.
void handleVectorReduceAndIntrinsic(IntrinsicInst &I) {
@@ -3195,10 +3195,10 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
assert(isa<ConstantInt>(I.getArgOperand(2)) &&
"pclmul 3rd operand must be a constant");
unsigned Imm = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue();
- Value *Shuf0 = IRB.CreateShuffleVector(getShadow(&I, 0),
- getPclmulMask(Width, Imm & 0x01));
- Value *Shuf1 = IRB.CreateShuffleVector(getShadow(&I, 1),
- getPclmulMask(Width, Imm & 0x10));
+ Value *Shuf0 = IRB.CreateShuffleVector(getShadow(&I, 0),
+ getPclmulMask(Width, Imm & 0x01));
+ Value *Shuf1 = IRB.CreateShuffleVector(getShadow(&I, 1),
+ getPclmulMask(Width, Imm & 0x10));
ShadowAndOriginCombiner SOC(this, IRB);
SOC.Add(Shuf0, getOrigin(&I, 0));
SOC.Add(Shuf1, getOrigin(&I, 1));
@@ -3231,24 +3231,24 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
setOriginForNaryOp(I);
}
- // Instrument abs intrinsic.
- // handleUnknownIntrinsic can't handle it because of the last
- // is_int_min_poison argument which does not match the result type.
- void handleAbsIntrinsic(IntrinsicInst &I) {
- assert(I.getType()->isIntOrIntVectorTy());
- assert(I.getArgOperand(0)->getType() == I.getType());
-
- // FIXME: Handle is_int_min_poison.
- IRBuilder<> IRB(&I);
- setShadow(&I, getShadow(&I, 0));
- setOrigin(&I, getOrigin(&I, 0));
- }
-
+ // Instrument abs intrinsic.
+ // handleUnknownIntrinsic can't handle it because of the last
+ // is_int_min_poison argument which does not match the result type.
+ void handleAbsIntrinsic(IntrinsicInst &I) {
+ assert(I.getType()->isIntOrIntVectorTy());
+ assert(I.getArgOperand(0)->getType() == I.getType());
+
+ // FIXME: Handle is_int_min_poison.
+ IRBuilder<> IRB(&I);
+ setShadow(&I, getShadow(&I, 0));
+ setOrigin(&I, getOrigin(&I, 0));
+ }
+
void visitIntrinsicInst(IntrinsicInst &I) {
switch (I.getIntrinsicID()) {
- case Intrinsic::abs:
- handleAbsIntrinsic(I);
- break;
+ case Intrinsic::abs:
+ handleAbsIntrinsic(I);
+ break;
case Intrinsic::lifetime_start:
handleLifetimeStart(I);
break;
@@ -3265,15 +3265,15 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
case Intrinsic::masked_load:
handleMaskedLoad(I);
break;
- case Intrinsic::vector_reduce_and:
+ case Intrinsic::vector_reduce_and:
handleVectorReduceAndIntrinsic(I);
break;
- case Intrinsic::vector_reduce_or:
+ case Intrinsic::vector_reduce_or:
handleVectorReduceOrIntrinsic(I);
break;
- case Intrinsic::vector_reduce_add:
- case Intrinsic::vector_reduce_xor:
- case Intrinsic::vector_reduce_mul:
+ case Intrinsic::vector_reduce_add:
+ case Intrinsic::vector_reduce_xor:
+ case Intrinsic::vector_reduce_mul:
handleVectorReduceIntrinsic(I);
break;
case Intrinsic::x86_sse_stmxcsr:
@@ -3293,8 +3293,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
case Intrinsic::x86_avx512_cvtusi2ss:
case Intrinsic::x86_avx512_cvtusi642sd:
case Intrinsic::x86_avx512_cvtusi642ss:
- handleVectorConvertIntrinsic(I, 1, true);
- break;
+ handleVectorConvertIntrinsic(I, 1, true);
+ break;
case Intrinsic::x86_sse2_cvtsd2si64:
case Intrinsic::x86_sse2_cvtsd2si:
case Intrinsic::x86_sse2_cvtsd2ss:
@@ -3520,63 +3520,63 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
}
}
- void visitLibAtomicLoad(CallBase &CB) {
- // Since we use getNextNode here, we can't have CB terminate the BB.
- assert(isa<CallInst>(CB));
-
- IRBuilder<> IRB(&CB);
- Value *Size = CB.getArgOperand(0);
- Value *SrcPtr = CB.getArgOperand(1);
- Value *DstPtr = CB.getArgOperand(2);
- Value *Ordering = CB.getArgOperand(3);
- // Convert the call to have at least Acquire ordering to make sure
- // the shadow operations aren't reordered before it.
- Value *NewOrdering =
- IRB.CreateExtractElement(makeAddAcquireOrderingTable(IRB), Ordering);
- CB.setArgOperand(3, NewOrdering);
-
- IRBuilder<> NextIRB(CB.getNextNode());
- NextIRB.SetCurrentDebugLocation(CB.getDebugLoc());
-
- Value *SrcShadowPtr, *SrcOriginPtr;
- std::tie(SrcShadowPtr, SrcOriginPtr) =
- getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(), Align(1),
- /*isStore*/ false);
- Value *DstShadowPtr =
- getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(), Align(1),
- /*isStore*/ true)
- .first;
-
- NextIRB.CreateMemCpy(DstShadowPtr, Align(1), SrcShadowPtr, Align(1), Size);
- if (MS.TrackOrigins) {
- Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
- kMinOriginAlignment);
- Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
- NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
- }
- }
-
- void visitLibAtomicStore(CallBase &CB) {
- IRBuilder<> IRB(&CB);
- Value *Size = CB.getArgOperand(0);
- Value *DstPtr = CB.getArgOperand(2);
- Value *Ordering = CB.getArgOperand(3);
- // Convert the call to have at least Release ordering to make sure
- // the shadow operations aren't reordered after it.
- Value *NewOrdering =
- IRB.CreateExtractElement(makeAddReleaseOrderingTable(IRB), Ordering);
- CB.setArgOperand(3, NewOrdering);
-
- Value *DstShadowPtr =
- getShadowOriginPtr(DstPtr, IRB, IRB.getInt8Ty(), Align(1),
- /*isStore*/ true)
- .first;
-
- // Atomic store always paints clean shadow/origin. See file header.
- IRB.CreateMemSet(DstShadowPtr, getCleanShadow(IRB.getInt8Ty()), Size,
- Align(1));
- }
-
+ void visitLibAtomicLoad(CallBase &CB) {
+ // Since we use getNextNode here, we can't have CB terminate the BB.
+ assert(isa<CallInst>(CB));
+
+ IRBuilder<> IRB(&CB);
+ Value *Size = CB.getArgOperand(0);
+ Value *SrcPtr = CB.getArgOperand(1);
+ Value *DstPtr = CB.getArgOperand(2);
+ Value *Ordering = CB.getArgOperand(3);
+ // Convert the call to have at least Acquire ordering to make sure
+ // the shadow operations aren't reordered before it.
+ Value *NewOrdering =
+ IRB.CreateExtractElement(makeAddAcquireOrderingTable(IRB), Ordering);
+ CB.setArgOperand(3, NewOrdering);
+
+ IRBuilder<> NextIRB(CB.getNextNode());
+ NextIRB.SetCurrentDebugLocation(CB.getDebugLoc());
+
+ Value *SrcShadowPtr, *SrcOriginPtr;
+ std::tie(SrcShadowPtr, SrcOriginPtr) =
+ getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(), Align(1),
+ /*isStore*/ false);
+ Value *DstShadowPtr =
+ getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(), Align(1),
+ /*isStore*/ true)
+ .first;
+
+ NextIRB.CreateMemCpy(DstShadowPtr, Align(1), SrcShadowPtr, Align(1), Size);
+ if (MS.TrackOrigins) {
+ Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
+ kMinOriginAlignment);
+ Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
+ NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
+ }
+ }
+
+ void visitLibAtomicStore(CallBase &CB) {
+ IRBuilder<> IRB(&CB);
+ Value *Size = CB.getArgOperand(0);
+ Value *DstPtr = CB.getArgOperand(2);
+ Value *Ordering = CB.getArgOperand(3);
+ // Convert the call to have at least Release ordering to make sure
+ // the shadow operations aren't reordered after it.
+ Value *NewOrdering =
+ IRB.CreateExtractElement(makeAddReleaseOrderingTable(IRB), Ordering);
+ CB.setArgOperand(3, NewOrdering);
+
+ Value *DstShadowPtr =
+ getShadowOriginPtr(DstPtr, IRB, IRB.getInt8Ty(), Align(1),
+ /*isStore*/ true)
+ .first;
+
+ // Atomic store always paints clean shadow/origin. See file header.
+ IRB.CreateMemSet(DstShadowPtr, getCleanShadow(IRB.getInt8Ty()), Size,
+ Align(1));
+ }
+
void visitCallBase(CallBase &CB) {
assert(!CB.getMetadata("nosanitize"));
if (CB.isInlineAsm()) {
@@ -3590,28 +3590,28 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
visitInstruction(CB);
return;
}
- LibFunc LF;
- if (TLI->getLibFunc(CB, LF)) {
- // libatomic.a functions need to have special handling because there isn't
- // a good way to intercept them or compile the library with
- // instrumentation.
- switch (LF) {
- case LibFunc_atomic_load:
- if (!isa<CallInst>(CB)) {
- llvm::errs() << "MSAN -- cannot instrument invoke of libatomic load."
- "Ignoring!\n";
- break;
- }
- visitLibAtomicLoad(CB);
- return;
- case LibFunc_atomic_store:
- visitLibAtomicStore(CB);
- return;
- default:
- break;
- }
- }
-
+ LibFunc LF;
+ if (TLI->getLibFunc(CB, LF)) {
+ // libatomic.a functions need to have special handling because there isn't
+ // a good way to intercept them or compile the library with
+ // instrumentation.
+ switch (LF) {
+ case LibFunc_atomic_load:
+ if (!isa<CallInst>(CB)) {
+ llvm::errs() << "MSAN -- cannot instrument invoke of libatomic load."
+ "Ignoring!\n";
+ break;
+ }
+ visitLibAtomicLoad(CB);
+ return;
+ case LibFunc_atomic_store:
+ visitLibAtomicStore(CB);
+ return;
+ default:
+ break;
+ }
+ }
+
if (auto *Call = dyn_cast<CallInst>(&CB)) {
assert(!isa<IntrinsicInst>(Call) && "intrinsics are handled elsewhere");
@@ -3619,14 +3619,14 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
// will become a non-readonly function after it is instrumented by us. To
// prevent this code from being optimized out, mark that function
// non-readonly in advance.
- AttrBuilder B;
- B.addAttribute(Attribute::ReadOnly)
- .addAttribute(Attribute::ReadNone)
- .addAttribute(Attribute::WriteOnly)
- .addAttribute(Attribute::ArgMemOnly)
- .addAttribute(Attribute::Speculatable);
-
- Call->removeAttributes(AttributeList::FunctionIndex, B);
+ AttrBuilder B;
+ B.addAttribute(Attribute::ReadOnly)
+ .addAttribute(Attribute::ReadNone)
+ .addAttribute(Attribute::WriteOnly)
+ .addAttribute(Attribute::ArgMemOnly)
+ .addAttribute(Attribute::Speculatable);
+
+ Call->removeAttributes(AttributeList::FunctionIndex, B);
if (Function *Func = Call->getCalledFunction()) {
Func->removeAttributes(AttributeList::FunctionIndex, B);
}
@@ -3634,12 +3634,12 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
maybeMarkSanitizerLibraryCallNoBuiltin(Call, TLI);
}
IRBuilder<> IRB(&CB);
- bool MayCheckCall = ClEagerChecks;
- if (Function *Func = CB.getCalledFunction()) {
- // __sanitizer_unaligned_{load,store} functions may be called by users
- // and always expects shadows in the TLS. So don't check them.
- MayCheckCall &= !Func->getName().startswith("__sanitizer_unaligned_");
- }
+ bool MayCheckCall = ClEagerChecks;
+ if (Function *Func = CB.getCalledFunction()) {
+ // __sanitizer_unaligned_{load,store} functions may be called by users
+ // and always expects shadows in the TLS. So don't check them.
+ MayCheckCall &= !Func->getName().startswith("__sanitizer_unaligned_");
+ }
unsigned ArgOffset = 0;
LLVM_DEBUG(dbgs() << " CallSite: " << CB << "\n");
@@ -3665,7 +3665,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
bool ByVal = CB.paramHasAttr(i, Attribute::ByVal);
bool NoUndef = CB.paramHasAttr(i, Attribute::NoUndef);
- bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
+ bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
if (EagerCheck) {
insertShadowCheck(A, &CB);
@@ -3705,7 +3705,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
(void)Store;
assert(Size != 0 && Store != nullptr);
LLVM_DEBUG(dbgs() << " Param:" << *Store << "\n");
- ArgOffset += alignTo(Size, kShadowTLSAlignment);
+ ArgOffset += alignTo(Size, kShadowTLSAlignment);
}
LLVM_DEBUG(dbgs() << " done with call args\n");
@@ -3721,7 +3721,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
if (isa<CallInst>(CB) && cast<CallInst>(CB).isMustTailCall())
return;
- if (MayCheckCall && CB.hasRetAttr(Attribute::NoUndef)) {
+ if (MayCheckCall && CB.hasRetAttr(Attribute::NoUndef)) {
setShadow(&CB, getCleanShadow(&CB));
setOrigin(&CB, getCleanOrigin());
return;
@@ -4104,12 +4104,12 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
setOrigin(&I, getCleanOrigin());
}
- void visitFreezeInst(FreezeInst &I) {
- // Freeze always returns a fully defined value.
- setShadow(&I, getCleanShadow(&I));
- setOrigin(&I, getCleanOrigin());
- }
-
+ void visitFreezeInst(FreezeInst &I) {
+ // Freeze always returns a fully defined value.
+ setShadow(&I, getCleanShadow(&I));
+ setOrigin(&I, getCleanOrigin());
+ }
+
void visitInstruction(Instruction &I) {
// Everything else: stop propagating and check for poisoned shadow.
if (ClDumpStrictInstructions)
@@ -4333,7 +4333,7 @@ struct VarArgAMD64Helper : public VarArgHelper {
if (!VAStartInstrumentationList.empty()) {
// If there is a va_start in this function, make a backup copy of
// va_arg_tls somewhere in the function entry block.
- IRBuilder<> IRB(MSV.FnPrologueEnd);
+ IRBuilder<> IRB(MSV.FnPrologueEnd);
VAArgOverflowSize =
IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
Value *CopySize =
@@ -4479,7 +4479,7 @@ struct VarArgMIPS64Helper : public VarArgHelper {
void finalizeInstrumentation() override {
assert(!VAArgSize && !VAArgTLSCopy &&
"finalizeInstrumentation called twice");
- IRBuilder<> IRB(MSV.FnPrologueEnd);
+ IRBuilder<> IRB(MSV.FnPrologueEnd);
VAArgSize = IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
Value *CopySize = IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, 0),
VAArgSize);
@@ -4672,7 +4672,7 @@ struct VarArgAArch64Helper : public VarArgHelper {
if (!VAStartInstrumentationList.empty()) {
// If there is a va_start in this function, make a backup copy of
// va_arg_tls somewhere in the function entry block.
- IRBuilder<> IRB(MSV.FnPrologueEnd);
+ IRBuilder<> IRB(MSV.FnPrologueEnd);
VAArgOverflowSize =
IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
Value *CopySize =
@@ -4792,9 +4792,9 @@ struct VarArgPowerPC64Helper : public VarArgHelper {
// For PowerPC, we need to deal with alignment of stack arguments -
// they are mostly aligned to 8 bytes, but vectors and i128 arrays
// are aligned to 16 bytes, byvals can be aligned to 8 or 16 bytes,
- // For that reason, we compute current offset from stack pointer (which is
- // always properly aligned), and offset for the first vararg, then subtract
- // them.
+ // For that reason, we compute current offset from stack pointer (which is
+ // always properly aligned), and offset for the first vararg, then subtract
+ // them.
unsigned VAArgBase;
Triple TargetTriple(F.getParent()->getTargetTriple());
// Parameter save area starts at 48 bytes from frame pointer for ABIv1,
@@ -4917,7 +4917,7 @@ struct VarArgPowerPC64Helper : public VarArgHelper {
void finalizeInstrumentation() override {
assert(!VAArgSize && !VAArgTLSCopy &&
"finalizeInstrumentation called twice");
- IRBuilder<> IRB(MSV.FnPrologueEnd);
+ IRBuilder<> IRB(MSV.FnPrologueEnd);
VAArgSize = IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
Value *CopySize = IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, 0),
VAArgSize);
@@ -5236,7 +5236,7 @@ struct VarArgSystemZHelper : public VarArgHelper {
if (!VAStartInstrumentationList.empty()) {
// If there is a va_start in this function, make a backup copy of
// va_arg_tls somewhere in the function entry block.
- IRBuilder<> IRB(MSV.FnPrologueEnd);
+ IRBuilder<> IRB(MSV.FnPrologueEnd);
VAArgOverflowSize =
IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
Value *CopySize =
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/contrib/libs/llvm12/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
index 763fe7c656..be6c8c6310 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
@@ -248,38 +248,38 @@ static cl::opt<bool>
"optimization remarks: -{Rpass|"
"pass-remarks}=pgo-instrumentation"));
-static cl::opt<bool> PGOInstrumentEntry(
- "pgo-instrument-entry", cl::init(false), cl::Hidden,
- cl::desc("Force to instrument function entry basicblock."));
-
-static cl::opt<bool>
- PGOFixEntryCount("pgo-fix-entry-count", cl::init(true), cl::Hidden,
- cl::desc("Fix function entry count in profile use."));
-
-static cl::opt<bool> PGOVerifyHotBFI(
- "pgo-verify-hot-bfi", cl::init(false), cl::Hidden,
- cl::desc("Print out the non-match BFI count if a hot raw profile count "
- "becomes non-hot, or a cold raw profile count becomes hot. "
- "The print is enabled under -Rpass-analysis=pgo, or "
- "internal option -pass-remakrs-analysis=pgo."));
-
-static cl::opt<bool> PGOVerifyBFI(
- "pgo-verify-bfi", cl::init(false), cl::Hidden,
- cl::desc("Print out mismatched BFI counts after setting profile metadata "
- "The print is enabled under -Rpass-analysis=pgo, or "
- "internal option -pass-remakrs-analysis=pgo."));
-
-static cl::opt<unsigned> PGOVerifyBFIRatio(
- "pgo-verify-bfi-ratio", cl::init(5), cl::Hidden,
- cl::desc("Set the threshold for pgo-verify-big -- only print out "
- "mismatched BFI if the difference percentage is greater than "
- "this value (in percentage)."));
-
-static cl::opt<unsigned> PGOVerifyBFICutoff(
- "pgo-verify-bfi-cutoff", cl::init(1), cl::Hidden,
- cl::desc("Set the threshold for pgo-verify-bfi -- skip the counts whose "
- "profile count value is below."));
-
+static cl::opt<bool> PGOInstrumentEntry(
+ "pgo-instrument-entry", cl::init(false), cl::Hidden,
+ cl::desc("Force to instrument function entry basicblock."));
+
+static cl::opt<bool>
+ PGOFixEntryCount("pgo-fix-entry-count", cl::init(true), cl::Hidden,
+ cl::desc("Fix function entry count in profile use."));
+
+static cl::opt<bool> PGOVerifyHotBFI(
+ "pgo-verify-hot-bfi", cl::init(false), cl::Hidden,
+ cl::desc("Print out the non-match BFI count if a hot raw profile count "
+ "becomes non-hot, or a cold raw profile count becomes hot. "
+ "The print is enabled under -Rpass-analysis=pgo, or "
+ "internal option -pass-remakrs-analysis=pgo."));
+
+static cl::opt<bool> PGOVerifyBFI(
+ "pgo-verify-bfi", cl::init(false), cl::Hidden,
+ cl::desc("Print out mismatched BFI counts after setting profile metadata "
+ "The print is enabled under -Rpass-analysis=pgo, or "
+ "internal option -pass-remakrs-analysis=pgo."));
+
+static cl::opt<unsigned> PGOVerifyBFIRatio(
+ "pgo-verify-bfi-ratio", cl::init(5), cl::Hidden,
+ cl::desc("Set the threshold for pgo-verify-big -- only print out "
+ "mismatched BFI if the difference percentage is greater than "
+ "this value (in percentage)."));
+
+static cl::opt<unsigned> PGOVerifyBFICutoff(
+ "pgo-verify-bfi-cutoff", cl::init(1), cl::Hidden,
+ cl::desc("Set the threshold for pgo-verify-bfi -- skip the counts whose "
+ "profile count value is below."));
+
// Command line option to turn on CFG dot dump after profile annotation.
// Defined in Analysis/BlockFrequencyInfo.cpp: -pgo-view-counts
extern cl::opt<PGOViewCountsType> PGOViewCounts;
@@ -288,10 +288,10 @@ extern cl::opt<PGOViewCountsType> PGOViewCounts;
// Defined in Analysis/BlockFrequencyInfo.cpp: -view-bfi-func-name=
extern cl::opt<std::string> ViewBlockFreqFuncName;
-static cl::opt<bool>
- PGOOldCFGHashing("pgo-instr-old-cfg-hashing", cl::init(false), cl::Hidden,
- cl::desc("Use the old CFG function hashing"));
-
+static cl::opt<bool>
+ PGOOldCFGHashing("pgo-instr-old-cfg-hashing", cl::init(false), cl::Hidden,
+ cl::desc("Use the old CFG function hashing"));
+
// Return a string describing the branch condition that can be
// used in static branch probability heuristics:
static std::string getBranchCondString(Instruction *TI) {
@@ -460,7 +460,7 @@ public:
private:
bool runOnModule(Module &M) override {
createProfileFileNameVar(M, InstrProfileOutput);
- createIRLevelProfileFlagVar(M, /* IsCS */ true, PGOInstrumentEntry);
+ createIRLevelProfileFlagVar(M, /* IsCS */ true, PGOInstrumentEntry);
return false;
}
std::string InstrProfileOutput;
@@ -607,11 +607,11 @@ public:
Function &Func, TargetLibraryInfo &TLI,
std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
bool CreateGlobalVar = false, BranchProbabilityInfo *BPI = nullptr,
- BlockFrequencyInfo *BFI = nullptr, bool IsCS = false,
- bool InstrumentFuncEntry = true)
+ BlockFrequencyInfo *BFI = nullptr, bool IsCS = false,
+ bool InstrumentFuncEntry = true)
: F(Func), IsCS(IsCS), ComdatMembers(ComdatMembers), VPC(Func, TLI),
- ValueSites(IPVK_Last + 1), SIVisitor(Func),
- MST(F, InstrumentFuncEntry, BPI, BFI) {
+ ValueSites(IPVK_Last + 1), SIVisitor(Func),
+ MST(F, InstrumentFuncEntry, BPI, BFI) {
// This should be done before CFG hash computation.
SIVisitor.countSelects(Func);
ValueSites[IPVK_MemOPSize] = VPC.get(IPVK_MemOPSize);
@@ -648,8 +648,8 @@ public:
} // end anonymous namespace
// Compute Hash value for the CFG: the lower 32 bits are CRC32 of the index
-// value of each BB in the CFG. The higher 32 bits are the CRC32 of the numbers
-// of selects, indirect calls, mem ops and edges.
+// value of each BB in the CFG. The higher 32 bits are the CRC32 of the numbers
+// of selects, indirect calls, mem ops and edges.
template <class Edge, class BBInfo>
void FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash() {
std::vector<uint8_t> Indexes;
@@ -668,31 +668,31 @@ void FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash() {
}
JC.update(Indexes);
- JamCRC JCH;
- if (PGOOldCFGHashing) {
- // Hash format for context sensitive profile. Reserve 4 bits for other
- // information.
- FunctionHash = (uint64_t)SIVisitor.getNumOfSelectInsts() << 56 |
- (uint64_t)ValueSites[IPVK_IndirectCallTarget].size() << 48 |
- //(uint64_t)ValueSites[IPVK_MemOPSize].size() << 40 |
- (uint64_t)MST.AllEdges.size() << 32 | JC.getCRC();
- } else {
- // The higher 32 bits.
- auto updateJCH = [&JCH](uint64_t Num) {
- uint8_t Data[8];
- support::endian::write64le(Data, Num);
- JCH.update(Data);
- };
- updateJCH((uint64_t)SIVisitor.getNumOfSelectInsts());
- updateJCH((uint64_t)ValueSites[IPVK_IndirectCallTarget].size());
- updateJCH((uint64_t)ValueSites[IPVK_MemOPSize].size());
- updateJCH((uint64_t)MST.AllEdges.size());
-
- // Hash format for context sensitive profile. Reserve 4 bits for other
- // information.
- FunctionHash = (((uint64_t)JCH.getCRC()) << 28) + JC.getCRC();
- }
-
+ JamCRC JCH;
+ if (PGOOldCFGHashing) {
+ // Hash format for context sensitive profile. Reserve 4 bits for other
+ // information.
+ FunctionHash = (uint64_t)SIVisitor.getNumOfSelectInsts() << 56 |
+ (uint64_t)ValueSites[IPVK_IndirectCallTarget].size() << 48 |
+ //(uint64_t)ValueSites[IPVK_MemOPSize].size() << 40 |
+ (uint64_t)MST.AllEdges.size() << 32 | JC.getCRC();
+ } else {
+ // The higher 32 bits.
+ auto updateJCH = [&JCH](uint64_t Num) {
+ uint8_t Data[8];
+ support::endian::write64le(Data, Num);
+ JCH.update(Data);
+ };
+ updateJCH((uint64_t)SIVisitor.getNumOfSelectInsts());
+ updateJCH((uint64_t)ValueSites[IPVK_IndirectCallTarget].size());
+ updateJCH((uint64_t)ValueSites[IPVK_MemOPSize].size());
+ updateJCH((uint64_t)MST.AllEdges.size());
+
+ // Hash format for context sensitive profile. Reserve 4 bits for other
+ // information.
+ FunctionHash = (((uint64_t)JCH.getCRC()) << 28) + JC.getCRC();
+ }
+
// Reserve bit 60-63 for other information purpose.
FunctionHash &= 0x0FFFFFFFFFFFFFFF;
if (IsCS)
@@ -701,12 +701,12 @@ void FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash() {
<< " CRC = " << JC.getCRC()
<< ", Selects = " << SIVisitor.getNumOfSelectInsts()
<< ", Edges = " << MST.AllEdges.size() << ", ICSites = "
- << ValueSites[IPVK_IndirectCallTarget].size());
- if (!PGOOldCFGHashing) {
- LLVM_DEBUG(dbgs() << ", Memops = " << ValueSites[IPVK_MemOPSize].size()
- << ", High32 CRC = " << JCH.getCRC());
- }
- LLVM_DEBUG(dbgs() << ", Hash = " << FunctionHash << "\n";);
+ << ValueSites[IPVK_IndirectCallTarget].size());
+ if (!PGOOldCFGHashing) {
+ LLVM_DEBUG(dbgs() << ", Memops = " << ValueSites[IPVK_MemOPSize].size()
+ << ", High32 CRC = " << JCH.getCRC());
+ }
+ LLVM_DEBUG(dbgs() << ", Hash = " << FunctionHash << "\n";);
}
// Check if we can safely rename this Comdat function.
@@ -717,7 +717,7 @@ static bool canRenameComdat(
return false;
// FIXME: Current only handle those Comdat groups that only containing one
- // function.
+ // function.
// (1) For a Comdat group containing multiple functions, we need to have a
// unique postfix based on the hashes for each function. There is a
// non-trivial code refactoring to do this efficiently.
@@ -725,7 +725,7 @@ static bool canRenameComdat(
// group including global vars.
Comdat *C = F.getComdat();
for (auto &&CM : make_range(ComdatMembers.equal_range(C))) {
- assert(!isa<GlobalAlias>(CM.second));
+ assert(!isa<GlobalAlias>(CM.second));
Function *FM = dyn_cast<Function>(CM.second);
if (FM != &F)
return false;
@@ -766,7 +766,7 @@ void FuncPGOInstrumentation<Edge, BBInfo>::renameComdatFunction() {
for (auto &&CM : make_range(ComdatMembers.equal_range(OrigComdat))) {
// Must be a function.
- cast<Function>(CM.second)->setComdat(NewComdat);
+ cast<Function>(CM.second)->setComdat(NewComdat);
}
}
@@ -831,11 +831,11 @@ BasicBlock *FuncPGOInstrumentation<Edge, BBInfo>::getInstrBB(Edge *E) {
if (!E->IsCritical)
return canInstrument(DestBB);
- // Some IndirectBr critical edges cannot be split by the previous
- // SplitIndirectBrCriticalEdges call. Bail out.
+ // Some IndirectBr critical edges cannot be split by the previous
+ // SplitIndirectBrCriticalEdges call. Bail out.
unsigned SuccNum = GetSuccessorNumber(SrcBB, DestBB);
- BasicBlock *InstrBB =
- isa<IndirectBrInst>(TI) ? nullptr : SplitCriticalEdge(TI, SuccNum);
+ BasicBlock *InstrBB =
+ isa<IndirectBrInst>(TI) ? nullptr : SplitCriticalEdge(TI, SuccNum);
if (!InstrBB) {
LLVM_DEBUG(
dbgs() << "Fail to split critical edge: not instrument this edge.\n");
@@ -898,8 +898,8 @@ static void instrumentOneFunc(
// later in getInstrBB() to avoid invalidating it.
SplitIndirectBrCriticalEdges(F, BPI, BFI);
- FuncPGOInstrumentation<PGOEdge, BBInfo> FuncInfo(
- F, TLI, ComdatMembers, true, BPI, BFI, IsCS, PGOInstrumentEntry);
+ FuncPGOInstrumentation<PGOEdge, BBInfo> FuncInfo(
+ F, TLI, ComdatMembers, true, BPI, BFI, IsCS, PGOInstrumentEntry);
std::vector<BasicBlock *> InstrumentBBs;
FuncInfo.getInstrumentBBs(InstrumentBBs);
unsigned NumCounters =
@@ -1057,15 +1057,15 @@ public:
PGOUseFunc(Function &Func, Module *Modu, TargetLibraryInfo &TLI,
std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
BranchProbabilityInfo *BPI, BlockFrequencyInfo *BFIin,
- ProfileSummaryInfo *PSI, bool IsCS, bool InstrumentFuncEntry)
+ ProfileSummaryInfo *PSI, bool IsCS, bool InstrumentFuncEntry)
: F(Func), M(Modu), BFI(BFIin), PSI(PSI),
- FuncInfo(Func, TLI, ComdatMembers, false, BPI, BFIin, IsCS,
- InstrumentFuncEntry),
+ FuncInfo(Func, TLI, ComdatMembers, false, BPI, BFIin, IsCS,
+ InstrumentFuncEntry),
FreqAttr(FFA_Normal), IsCS(IsCS) {}
// Read counts for the instrumented BB from profile.
- bool readCounters(IndexedInstrProfReader *PGOReader, bool &AllZeros,
- bool &AllMinusOnes);
+ bool readCounters(IndexedInstrProfReader *PGOReader, bool &AllZeros,
+ bool &AllMinusOnes);
// Populate the counts for all BBs.
void populateCounters();
@@ -1176,18 +1176,18 @@ bool PGOUseFunc::setInstrumentedCounts(
if (NumCounters != CountFromProfile.size()) {
return false;
}
- auto *FuncEntry = &*F.begin();
-
+ auto *FuncEntry = &*F.begin();
+
// Set the profile count to the Instrumented BBs.
uint32_t I = 0;
for (BasicBlock *InstrBB : InstrumentBBs) {
uint64_t CountValue = CountFromProfile[I++];
UseBBInfo &Info = getBBInfo(InstrBB);
- // If we reach here, we know that we have some nonzero count
- // values in this function. The entry count should not be 0.
- // Fix it if necessary.
- if (InstrBB == FuncEntry && CountValue == 0)
- CountValue = 1;
+ // If we reach here, we know that we have some nonzero count
+ // values in this function. The entry count should not be 0.
+ // Fix it if necessary.
+ if (InstrBB == FuncEntry && CountValue == 0)
+ CountValue = 1;
Info.setBBInfoCount(CountValue);
}
ProfileCountSize = CountFromProfile.size();
@@ -1248,8 +1248,8 @@ void PGOUseFunc::setEdgeCount(DirectEdges &Edges, uint64_t Value) {
// Read the profile from ProfileFileName and assign the value to the
// instrumented BB and the edges. This function also updates ProgramMaxCount.
// Return true if the profile are successfully read, and false on errors.
-bool PGOUseFunc::readCounters(IndexedInstrProfReader *PGOReader, bool &AllZeros,
- bool &AllMinusOnes) {
+bool PGOUseFunc::readCounters(IndexedInstrProfReader *PGOReader, bool &AllZeros,
+ bool &AllMinusOnes) {
auto &Ctx = M->getContext();
Expected<InstrProfRecord> Result =
PGOReader->getInstrProfRecord(FuncInfo.FuncName, FuncInfo.FunctionHash);
@@ -1292,13 +1292,13 @@ bool PGOUseFunc::readCounters(IndexedInstrProfReader *PGOReader, bool &AllZeros,
IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;
LLVM_DEBUG(dbgs() << CountFromProfile.size() << " counts\n");
- AllMinusOnes = (CountFromProfile.size() > 0);
+ AllMinusOnes = (CountFromProfile.size() > 0);
uint64_t ValueSum = 0;
for (unsigned I = 0, S = CountFromProfile.size(); I < S; I++) {
LLVM_DEBUG(dbgs() << " " << I << ": " << CountFromProfile[I] << "\n");
ValueSum += CountFromProfile[I];
- if (CountFromProfile[I] != (uint64_t)-1)
- AllMinusOnes = false;
+ if (CountFromProfile[I] != (uint64_t)-1)
+ AllMinusOnes = false;
}
AllZeros = (ValueSum == 0);
@@ -1389,11 +1389,11 @@ void PGOUseFunc::populateCounters() {
continue;
FuncMaxCount = std::max(FuncMaxCount, BI->CountValue);
}
-
- // Fix the obviously inconsistent entry count.
- if (FuncMaxCount > 0 && FuncEntryCount == 0)
- FuncEntryCount = 1;
- F.setEntryCount(ProfileCount(FuncEntryCount, Function::PCT_Real));
+
+ // Fix the obviously inconsistent entry count.
+ if (FuncMaxCount > 0 && FuncEntryCount == 0)
+ FuncEntryCount = 1;
+ F.setEntryCount(ProfileCount(FuncEntryCount, Function::PCT_Real));
markFunctionAttributes(FuncEntryCount, FuncMaxCount);
// Now annotate select instructions
@@ -1584,15 +1584,15 @@ static bool InstrumentAllFunctions(
// For the context-sensitve instrumentation, we should have a separated pass
// (before LTO/ThinLTO linking) to create these variables.
if (!IsCS)
- createIRLevelProfileFlagVar(M, /* IsCS */ false, PGOInstrumentEntry);
+ createIRLevelProfileFlagVar(M, /* IsCS */ false, PGOInstrumentEntry);
std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
collectComdatMembers(M, ComdatMembers);
for (auto &F : M) {
if (F.isDeclaration())
continue;
- if (F.hasFnAttribute(llvm::Attribute::NoProfile))
- continue;
+ if (F.hasFnAttribute(llvm::Attribute::NoProfile))
+ continue;
auto &TLI = LookupTLI(F);
auto *BPI = LookupBPI(F);
auto *BFI = LookupBFI(F);
@@ -1604,7 +1604,7 @@ static bool InstrumentAllFunctions(
PreservedAnalyses
PGOInstrumentationGenCreateVar::run(Module &M, ModuleAnalysisManager &AM) {
createProfileFileNameVar(M, CSInstrName);
- createIRLevelProfileFlagVar(M, /* IsCS */ true, PGOInstrumentEntry);
+ createIRLevelProfileFlagVar(M, /* IsCS */ true, PGOInstrumentEntry);
return PreservedAnalyses::all();
}
@@ -1643,129 +1643,129 @@ PreservedAnalyses PGOInstrumentationGen::run(Module &M,
return PreservedAnalyses::none();
}
-// Using the ratio b/w sums of profile count values and BFI count values to
-// adjust the func entry count.
-static void fixFuncEntryCount(PGOUseFunc &Func, LoopInfo &LI,
- BranchProbabilityInfo &NBPI) {
- Function &F = Func.getFunc();
- BlockFrequencyInfo NBFI(F, NBPI, LI);
-#ifndef NDEBUG
- auto BFIEntryCount = F.getEntryCount();
- assert(BFIEntryCount.hasValue() && (BFIEntryCount.getCount() > 0) &&
- "Invalid BFI Entrycount");
-#endif
- auto SumCount = APFloat::getZero(APFloat::IEEEdouble());
- auto SumBFICount = APFloat::getZero(APFloat::IEEEdouble());
- for (auto &BBI : F) {
- uint64_t CountValue = 0;
- uint64_t BFICountValue = 0;
- if (!Func.findBBInfo(&BBI))
- continue;
- auto BFICount = NBFI.getBlockProfileCount(&BBI);
- CountValue = Func.getBBInfo(&BBI).CountValue;
- BFICountValue = BFICount.getValue();
- SumCount.add(APFloat(CountValue * 1.0), APFloat::rmNearestTiesToEven);
- SumBFICount.add(APFloat(BFICountValue * 1.0), APFloat::rmNearestTiesToEven);
- }
- if (SumCount.isZero())
- return;
-
- assert(SumBFICount.compare(APFloat(0.0)) == APFloat::cmpGreaterThan &&
- "Incorrect sum of BFI counts");
- if (SumBFICount.compare(SumCount) == APFloat::cmpEqual)
- return;
- double Scale = (SumCount / SumBFICount).convertToDouble();
- if (Scale < 1.001 && Scale > 0.999)
- return;
-
- uint64_t FuncEntryCount = Func.getBBInfo(&*F.begin()).CountValue;
- uint64_t NewEntryCount = 0.5 + FuncEntryCount * Scale;
- if (NewEntryCount == 0)
- NewEntryCount = 1;
- if (NewEntryCount != FuncEntryCount) {
- F.setEntryCount(ProfileCount(NewEntryCount, Function::PCT_Real));
- LLVM_DEBUG(dbgs() << "FixFuncEntryCount: in " << F.getName()
- << ", entry_count " << FuncEntryCount << " --> "
- << NewEntryCount << "\n");
- }
-}
-
-// Compare the profile count values with BFI count values, and print out
-// the non-matching ones.
-static void verifyFuncBFI(PGOUseFunc &Func, LoopInfo &LI,
- BranchProbabilityInfo &NBPI,
- uint64_t HotCountThreshold,
- uint64_t ColdCountThreshold) {
- Function &F = Func.getFunc();
- BlockFrequencyInfo NBFI(F, NBPI, LI);
- // bool PrintFunc = false;
- bool HotBBOnly = PGOVerifyHotBFI;
- std::string Msg;
- OptimizationRemarkEmitter ORE(&F);
-
- unsigned BBNum = 0, BBMisMatchNum = 0, NonZeroBBNum = 0;
- for (auto &BBI : F) {
- uint64_t CountValue = 0;
- uint64_t BFICountValue = 0;
-
- if (Func.getBBInfo(&BBI).CountValid)
- CountValue = Func.getBBInfo(&BBI).CountValue;
-
- BBNum++;
- if (CountValue)
- NonZeroBBNum++;
- auto BFICount = NBFI.getBlockProfileCount(&BBI);
- if (BFICount)
- BFICountValue = BFICount.getValue();
-
- if (HotBBOnly) {
- bool rawIsHot = CountValue >= HotCountThreshold;
- bool BFIIsHot = BFICountValue >= HotCountThreshold;
- bool rawIsCold = CountValue <= ColdCountThreshold;
- bool ShowCount = false;
- if (rawIsHot && !BFIIsHot) {
- Msg = "raw-Hot to BFI-nonHot";
- ShowCount = true;
- } else if (rawIsCold && BFIIsHot) {
- Msg = "raw-Cold to BFI-Hot";
- ShowCount = true;
- }
- if (!ShowCount)
- continue;
- } else {
- if ((CountValue < PGOVerifyBFICutoff) &&
- (BFICountValue < PGOVerifyBFICutoff))
- continue;
- uint64_t Diff = (BFICountValue >= CountValue)
- ? BFICountValue - CountValue
- : CountValue - BFICountValue;
- if (Diff < CountValue / 100 * PGOVerifyBFIRatio)
- continue;
- }
- BBMisMatchNum++;
-
- ORE.emit([&]() {
- OptimizationRemarkAnalysis Remark(DEBUG_TYPE, "bfi-verify",
- F.getSubprogram(), &BBI);
- Remark << "BB " << ore::NV("Block", BBI.getName())
- << " Count=" << ore::NV("Count", CountValue)
- << " BFI_Count=" << ore::NV("Count", BFICountValue);
- if (!Msg.empty())
- Remark << " (" << Msg << ")";
- return Remark;
- });
- }
- if (BBMisMatchNum)
- ORE.emit([&]() {
- return OptimizationRemarkAnalysis(DEBUG_TYPE, "bfi-verify",
- F.getSubprogram(), &F.getEntryBlock())
- << "In Func " << ore::NV("Function", F.getName())
- << ": Num_of_BB=" << ore::NV("Count", BBNum)
- << ", Num_of_non_zerovalue_BB=" << ore::NV("Count", NonZeroBBNum)
- << ", Num_of_mis_matching_BB=" << ore::NV("Count", BBMisMatchNum);
- });
-}
-
+// Using the ratio b/w sums of profile count values and BFI count values to
+// adjust the func entry count.
+static void fixFuncEntryCount(PGOUseFunc &Func, LoopInfo &LI,
+ BranchProbabilityInfo &NBPI) {
+ Function &F = Func.getFunc();
+ BlockFrequencyInfo NBFI(F, NBPI, LI);
+#ifndef NDEBUG
+ auto BFIEntryCount = F.getEntryCount();
+ assert(BFIEntryCount.hasValue() && (BFIEntryCount.getCount() > 0) &&
+ "Invalid BFI Entrycount");
+#endif
+ auto SumCount = APFloat::getZero(APFloat::IEEEdouble());
+ auto SumBFICount = APFloat::getZero(APFloat::IEEEdouble());
+ for (auto &BBI : F) {
+ uint64_t CountValue = 0;
+ uint64_t BFICountValue = 0;
+ if (!Func.findBBInfo(&BBI))
+ continue;
+ auto BFICount = NBFI.getBlockProfileCount(&BBI);
+ CountValue = Func.getBBInfo(&BBI).CountValue;
+ BFICountValue = BFICount.getValue();
+ SumCount.add(APFloat(CountValue * 1.0), APFloat::rmNearestTiesToEven);
+ SumBFICount.add(APFloat(BFICountValue * 1.0), APFloat::rmNearestTiesToEven);
+ }
+ if (SumCount.isZero())
+ return;
+
+ assert(SumBFICount.compare(APFloat(0.0)) == APFloat::cmpGreaterThan &&
+ "Incorrect sum of BFI counts");
+ if (SumBFICount.compare(SumCount) == APFloat::cmpEqual)
+ return;
+ double Scale = (SumCount / SumBFICount).convertToDouble();
+ if (Scale < 1.001 && Scale > 0.999)
+ return;
+
+ uint64_t FuncEntryCount = Func.getBBInfo(&*F.begin()).CountValue;
+ uint64_t NewEntryCount = 0.5 + FuncEntryCount * Scale;
+ if (NewEntryCount == 0)
+ NewEntryCount = 1;
+ if (NewEntryCount != FuncEntryCount) {
+ F.setEntryCount(ProfileCount(NewEntryCount, Function::PCT_Real));
+ LLVM_DEBUG(dbgs() << "FixFuncEntryCount: in " << F.getName()
+ << ", entry_count " << FuncEntryCount << " --> "
+ << NewEntryCount << "\n");
+ }
+}
+
+// Compare the profile count values with BFI count values, and print out
+// the non-matching ones.
+static void verifyFuncBFI(PGOUseFunc &Func, LoopInfo &LI,
+ BranchProbabilityInfo &NBPI,
+ uint64_t HotCountThreshold,
+ uint64_t ColdCountThreshold) {
+ Function &F = Func.getFunc();
+ BlockFrequencyInfo NBFI(F, NBPI, LI);
+ // bool PrintFunc = false;
+ bool HotBBOnly = PGOVerifyHotBFI;
+ std::string Msg;
+ OptimizationRemarkEmitter ORE(&F);
+
+ unsigned BBNum = 0, BBMisMatchNum = 0, NonZeroBBNum = 0;
+ for (auto &BBI : F) {
+ uint64_t CountValue = 0;
+ uint64_t BFICountValue = 0;
+
+ if (Func.getBBInfo(&BBI).CountValid)
+ CountValue = Func.getBBInfo(&BBI).CountValue;
+
+ BBNum++;
+ if (CountValue)
+ NonZeroBBNum++;
+ auto BFICount = NBFI.getBlockProfileCount(&BBI);
+ if (BFICount)
+ BFICountValue = BFICount.getValue();
+
+ if (HotBBOnly) {
+ bool rawIsHot = CountValue >= HotCountThreshold;
+ bool BFIIsHot = BFICountValue >= HotCountThreshold;
+ bool rawIsCold = CountValue <= ColdCountThreshold;
+ bool ShowCount = false;
+ if (rawIsHot && !BFIIsHot) {
+ Msg = "raw-Hot to BFI-nonHot";
+ ShowCount = true;
+ } else if (rawIsCold && BFIIsHot) {
+ Msg = "raw-Cold to BFI-Hot";
+ ShowCount = true;
+ }
+ if (!ShowCount)
+ continue;
+ } else {
+ if ((CountValue < PGOVerifyBFICutoff) &&
+ (BFICountValue < PGOVerifyBFICutoff))
+ continue;
+ uint64_t Diff = (BFICountValue >= CountValue)
+ ? BFICountValue - CountValue
+ : CountValue - BFICountValue;
+ if (Diff < CountValue / 100 * PGOVerifyBFIRatio)
+ continue;
+ }
+ BBMisMatchNum++;
+
+ ORE.emit([&]() {
+ OptimizationRemarkAnalysis Remark(DEBUG_TYPE, "bfi-verify",
+ F.getSubprogram(), &BBI);
+ Remark << "BB " << ore::NV("Block", BBI.getName())
+ << " Count=" << ore::NV("Count", CountValue)
+ << " BFI_Count=" << ore::NV("Count", BFICountValue);
+ if (!Msg.empty())
+ Remark << " (" << Msg << ")";
+ return Remark;
+ });
+ }
+ if (BBMisMatchNum)
+ ORE.emit([&]() {
+ return OptimizationRemarkAnalysis(DEBUG_TYPE, "bfi-verify",
+ F.getSubprogram(), &F.getEntryBlock())
+ << "In Func " << ore::NV("Function", F.getName())
+ << ": Num_of_BB=" << ore::NV("Count", BBNum)
+ << ", Num_of_non_zerovalue_BB=" << ore::NV("Count", NonZeroBBNum)
+ << ", Num_of_mis_matching_BB=" << ore::NV("Count", BBMisMatchNum);
+ });
+}
+
static bool annotateAllFunctions(
Module &M, StringRef ProfileFileName, StringRef ProfileRemappingFileName,
function_ref<TargetLibraryInfo &(Function &)> LookupTLI,
@@ -1814,12 +1814,12 @@ static bool annotateAllFunctions(
collectComdatMembers(M, ComdatMembers);
std::vector<Function *> HotFunctions;
std::vector<Function *> ColdFunctions;
-
- // If the profile marked as always instrument the entry BB, do the
- // same. Note this can be overwritten by the internal option in CFGMST.h
- bool InstrumentFuncEntry = PGOReader->instrEntryBBEnabled();
- if (PGOInstrumentEntry.getNumOccurrences() > 0)
- InstrumentFuncEntry = PGOInstrumentEntry;
+
+ // If the profile marked as always instrument the entry BB, do the
+ // same. Note this can be overwritten by the internal option in CFGMST.h
+ bool InstrumentFuncEntry = PGOReader->instrEntryBBEnabled();
+ if (PGOInstrumentEntry.getNumOccurrences() > 0)
+ InstrumentFuncEntry = PGOInstrumentEntry;
for (auto &F : M) {
if (F.isDeclaration())
continue;
@@ -1829,15 +1829,15 @@ static bool annotateAllFunctions(
// Split indirectbr critical edges here before computing the MST rather than
// later in getInstrBB() to avoid invalidating it.
SplitIndirectBrCriticalEdges(F, BPI, BFI);
- PGOUseFunc Func(F, &M, TLI, ComdatMembers, BPI, BFI, PSI, IsCS,
- InstrumentFuncEntry);
- // When AllMinusOnes is true, it means the profile for the function
- // is unrepresentative and this function is actually hot. Set the
- // entry count of the function to be multiple times of hot threshold
- // and drop all its internal counters.
- bool AllMinusOnes = false;
+ PGOUseFunc Func(F, &M, TLI, ComdatMembers, BPI, BFI, PSI, IsCS,
+ InstrumentFuncEntry);
+ // When AllMinusOnes is true, it means the profile for the function
+ // is unrepresentative and this function is actually hot. Set the
+ // entry count of the function to be multiple times of hot threshold
+ // and drop all its internal counters.
+ bool AllMinusOnes = false;
bool AllZeros = false;
- if (!Func.readCounters(PGOReader.get(), AllZeros, AllMinusOnes))
+ if (!Func.readCounters(PGOReader.get(), AllZeros, AllMinusOnes))
continue;
if (AllZeros) {
F.setEntryCount(ProfileCount(0, Function::PCT_Real));
@@ -1845,15 +1845,15 @@ static bool annotateAllFunctions(
ColdFunctions.push_back(&F);
continue;
}
- const unsigned MultiplyFactor = 3;
- if (AllMinusOnes) {
- uint64_t HotThreshold = PSI->getHotCountThreshold();
- if (HotThreshold)
- F.setEntryCount(
- ProfileCount(HotThreshold * MultiplyFactor, Function::PCT_Real));
- HotFunctions.push_back(&F);
- continue;
- }
+ const unsigned MultiplyFactor = 3;
+ if (AllMinusOnes) {
+ uint64_t HotThreshold = PSI->getHotCountThreshold();
+ if (HotThreshold)
+ F.setEntryCount(
+ ProfileCount(HotThreshold * MultiplyFactor, Function::PCT_Real));
+ HotFunctions.push_back(&F);
+ continue;
+ }
Func.populateCounters();
Func.setBranchWeights();
Func.annotateValueSites();
@@ -1891,23 +1891,23 @@ static bool annotateAllFunctions(
Func.dumpInfo();
}
}
-
- if (PGOVerifyBFI || PGOVerifyHotBFI || PGOFixEntryCount) {
- LoopInfo LI{DominatorTree(F)};
- BranchProbabilityInfo NBPI(F, LI);
-
- // Fix func entry count.
- if (PGOFixEntryCount)
- fixFuncEntryCount(Func, LI, NBPI);
-
- // Verify BlockFrequency information.
- uint64_t HotCountThreshold = 0, ColdCountThreshold = 0;
- if (PGOVerifyHotBFI) {
- HotCountThreshold = PSI->getOrCompHotCountThreshold();
- ColdCountThreshold = PSI->getOrCompColdCountThreshold();
- }
- verifyFuncBFI(Func, LI, NBPI, HotCountThreshold, ColdCountThreshold);
- }
+
+ if (PGOVerifyBFI || PGOVerifyHotBFI || PGOFixEntryCount) {
+ LoopInfo LI{DominatorTree(F)};
+ BranchProbabilityInfo NBPI(F, LI);
+
+ // Fix func entry count.
+ if (PGOFixEntryCount)
+ fixFuncEntryCount(Func, LI, NBPI);
+
+ // Verify BlockFrequency information.
+ uint64_t HotCountThreshold = 0, ColdCountThreshold = 0;
+ if (PGOVerifyHotBFI) {
+ HotCountThreshold = PSI->getOrCompHotCountThreshold();
+ ColdCountThreshold = PSI->getOrCompColdCountThreshold();
+ }
+ verifyFuncBFI(Func, LI, NBPI, HotCountThreshold, ColdCountThreshold);
+ }
}
// Set function hotness attribute from the profile.
@@ -1920,17 +1920,17 @@ static bool annotateAllFunctions(
<< "\n");
}
for (auto &F : ColdFunctions) {
- // Only set when there is no Attribute::Hot set by the user. For Hot
- // attribute, user's annotation has the precedence over the profile.
- if (F->hasFnAttribute(Attribute::Hot)) {
- auto &Ctx = M.getContext();
- std::string Msg = std::string("Function ") + F->getName().str() +
- std::string(" is annotated as a hot function but"
- " the profile is cold");
- Ctx.diagnose(
- DiagnosticInfoPGOProfile(M.getName().data(), Msg, DS_Warning));
- continue;
- }
+ // Only set when there is no Attribute::Hot set by the user. For Hot
+ // attribute, user's annotation has the precedence over the profile.
+ if (F->hasFnAttribute(Attribute::Hot)) {
+ auto &Ctx = M.getContext();
+ std::string Msg = std::string("Function ") + F->getName().str() +
+ std::string(" is annotated as a hot function but"
+ " the profile is cold");
+ Ctx.diagnose(
+ DiagnosticInfoPGOProfile(M.getName().data(), Msg, DS_Warning));
+ continue;
+ }
F->addFnAttr(Attribute::Cold);
LLVM_DEBUG(dbgs() << "Set cold attribute to function: " << F->getName()
<< "\n");
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/PGOMemOPSizeOpt.cpp b/contrib/libs/llvm12/lib/Transforms/Instrumentation/PGOMemOPSizeOpt.cpp
index 3f5db5380e..55a93b6152 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/PGOMemOPSizeOpt.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/PGOMemOPSizeOpt.cpp
@@ -22,7 +22,7 @@
#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
@@ -39,8 +39,8 @@
#include "llvm/Pass.h"
#include "llvm/PassRegistry.h"
#include "llvm/ProfileData/InstrProf.h"
-#define INSTR_PROF_VALUE_PROF_MEMOP_API
-#include "llvm/ProfileData/InstrProfData.inc"
+#define INSTR_PROF_VALUE_PROF_MEMOP_API
+#include "llvm/ProfileData/InstrProfData.inc"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -97,10 +97,10 @@ cl::opt<bool>
cl::Hidden,
cl::desc("Size-specialize memcmp and bcmp calls"));
-static cl::opt<unsigned>
- MemOpMaxOptSize("memop-value-prof-max-opt-size", cl::Hidden, cl::init(128),
- cl::desc("Optimize the memop size <= this value"));
-
+static cl::opt<unsigned>
+ MemOpMaxOptSize("memop-value-prof-max-opt-size", cl::Hidden, cl::init(128),
+ cl::desc("Optimize the memop size <= this value"));
+
namespace {
class PGOMemOPSizeOptLegacyPass : public FunctionPass {
public:
@@ -254,7 +254,7 @@ public:
LibFunc Func;
if (TLI.getLibFunc(CI, Func) &&
(Func == LibFunc_memcmp || Func == LibFunc_bcmp) &&
- !isa<ConstantInt>(CI.getArgOperand(2))) {
+ !isa<ConstantInt>(CI.getArgOperand(2))) {
WorkList.push_back(MemOp(&CI));
}
}
@@ -346,7 +346,7 @@ bool MemOPSizeOpt::perform(MemOp MO) {
if (MemOPScaleCount)
C = getScaledCount(C, ActualCount, SavedTotalCount);
- if (!InstrProfIsSingleValRange(V) || V > MemOpMaxOptSize)
+ if (!InstrProfIsSingleValRange(V) || V > MemOpMaxOptSize)
continue;
// ValueCounts are sorted on the count. Break at the first un-profitable
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/PoisonChecking.cpp b/contrib/libs/llvm12/lib/Transforms/Instrumentation/PoisonChecking.cpp
index 1cd36629b5..fc52672618 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/PoisonChecking.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/PoisonChecking.cpp
@@ -282,10 +282,10 @@ static bool rewrite(Function &F) {
// Note: There are many more sources of documented UB, but this pass only
// attempts to find UB triggered by propagation of poison.
- SmallPtrSet<const Value *, 4> NonPoisonOps;
- getGuaranteedNonPoisonOps(&I, NonPoisonOps);
- for (const Value *Op : NonPoisonOps)
- CreateAssertNot(B, getPoisonFor(ValToPoison, const_cast<Value *>(Op)));
+ SmallPtrSet<const Value *, 4> NonPoisonOps;
+ getGuaranteedNonPoisonOps(&I, NonPoisonOps);
+ for (const Value *Op : NonPoisonOps)
+ CreateAssertNot(B, getPoisonFor(ValToPoison, const_cast<Value *>(Op)));
if (LocalCheck)
if (auto *RI = dyn_cast<ReturnInst>(&I))
@@ -295,11 +295,11 @@ static bool rewrite(Function &F) {
}
SmallVector<Value*, 4> Checks;
- if (propagatesPoison(cast<Operator>(&I)))
+ if (propagatesPoison(cast<Operator>(&I)))
for (Value *V : I.operands())
Checks.push_back(getPoisonFor(ValToPoison, V));
- if (canCreatePoison(cast<Operator>(&I)))
+ if (canCreatePoison(cast<Operator>(&I)))
generateCreationChecks(I, Checks);
ValToPoison[&I] = buildOrChain(B, Checks);
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/contrib/libs/llvm12/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
index b840aafde7..2d4b079394 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -45,39 +45,39 @@ using namespace llvm;
#define DEBUG_TYPE "sancov"
-const char SanCovTracePCIndirName[] = "__sanitizer_cov_trace_pc_indir";
-const char SanCovTracePCName[] = "__sanitizer_cov_trace_pc";
-const char SanCovTraceCmp1[] = "__sanitizer_cov_trace_cmp1";
-const char SanCovTraceCmp2[] = "__sanitizer_cov_trace_cmp2";
-const char SanCovTraceCmp4[] = "__sanitizer_cov_trace_cmp4";
-const char SanCovTraceCmp8[] = "__sanitizer_cov_trace_cmp8";
-const char SanCovTraceConstCmp1[] = "__sanitizer_cov_trace_const_cmp1";
-const char SanCovTraceConstCmp2[] = "__sanitizer_cov_trace_const_cmp2";
-const char SanCovTraceConstCmp4[] = "__sanitizer_cov_trace_const_cmp4";
-const char SanCovTraceConstCmp8[] = "__sanitizer_cov_trace_const_cmp8";
-const char SanCovTraceDiv4[] = "__sanitizer_cov_trace_div4";
-const char SanCovTraceDiv8[] = "__sanitizer_cov_trace_div8";
-const char SanCovTraceGep[] = "__sanitizer_cov_trace_gep";
-const char SanCovTraceSwitchName[] = "__sanitizer_cov_trace_switch";
-const char SanCovModuleCtorTracePcGuardName[] =
+const char SanCovTracePCIndirName[] = "__sanitizer_cov_trace_pc_indir";
+const char SanCovTracePCName[] = "__sanitizer_cov_trace_pc";
+const char SanCovTraceCmp1[] = "__sanitizer_cov_trace_cmp1";
+const char SanCovTraceCmp2[] = "__sanitizer_cov_trace_cmp2";
+const char SanCovTraceCmp4[] = "__sanitizer_cov_trace_cmp4";
+const char SanCovTraceCmp8[] = "__sanitizer_cov_trace_cmp8";
+const char SanCovTraceConstCmp1[] = "__sanitizer_cov_trace_const_cmp1";
+const char SanCovTraceConstCmp2[] = "__sanitizer_cov_trace_const_cmp2";
+const char SanCovTraceConstCmp4[] = "__sanitizer_cov_trace_const_cmp4";
+const char SanCovTraceConstCmp8[] = "__sanitizer_cov_trace_const_cmp8";
+const char SanCovTraceDiv4[] = "__sanitizer_cov_trace_div4";
+const char SanCovTraceDiv8[] = "__sanitizer_cov_trace_div8";
+const char SanCovTraceGep[] = "__sanitizer_cov_trace_gep";
+const char SanCovTraceSwitchName[] = "__sanitizer_cov_trace_switch";
+const char SanCovModuleCtorTracePcGuardName[] =
"sancov.module_ctor_trace_pc_guard";
-const char SanCovModuleCtor8bitCountersName[] =
+const char SanCovModuleCtor8bitCountersName[] =
"sancov.module_ctor_8bit_counters";
-const char SanCovModuleCtorBoolFlagName[] = "sancov.module_ctor_bool_flag";
+const char SanCovModuleCtorBoolFlagName[] = "sancov.module_ctor_bool_flag";
static const uint64_t SanCtorAndDtorPriority = 2;
-const char SanCovTracePCGuardName[] = "__sanitizer_cov_trace_pc_guard";
-const char SanCovTracePCGuardInitName[] = "__sanitizer_cov_trace_pc_guard_init";
-const char SanCov8bitCountersInitName[] = "__sanitizer_cov_8bit_counters_init";
-const char SanCovBoolFlagInitName[] = "__sanitizer_cov_bool_flag_init";
-const char SanCovPCsInitName[] = "__sanitizer_cov_pcs_init";
+const char SanCovTracePCGuardName[] = "__sanitizer_cov_trace_pc_guard";
+const char SanCovTracePCGuardInitName[] = "__sanitizer_cov_trace_pc_guard_init";
+const char SanCov8bitCountersInitName[] = "__sanitizer_cov_8bit_counters_init";
+const char SanCovBoolFlagInitName[] = "__sanitizer_cov_bool_flag_init";
+const char SanCovPCsInitName[] = "__sanitizer_cov_pcs_init";
-const char SanCovGuardsSectionName[] = "sancov_guards";
-const char SanCovCountersSectionName[] = "sancov_cntrs";
-const char SanCovBoolFlagSectionName[] = "sancov_bools";
-const char SanCovPCsSectionName[] = "sancov_pcs";
+const char SanCovGuardsSectionName[] = "sancov_guards";
+const char SanCovCountersSectionName[] = "sancov_cntrs";
+const char SanCovBoolFlagSectionName[] = "sancov_bools";
+const char SanCovPCsSectionName[] = "sancov_pcs";
-const char SanCovLowestStackName[] = "__sancov_lowest_stack";
+const char SanCovLowestStackName[] = "__sancov_lowest_stack";
static cl::opt<int> ClCoverageLevel(
"sanitizer-coverage-level",
@@ -328,24 +328,24 @@ PreservedAnalyses ModuleSanitizerCoveragePass::run(Module &M,
std::pair<Value *, Value *>
ModuleSanitizerCoverage::CreateSecStartEnd(Module &M, const char *Section,
Type *Ty) {
- GlobalVariable *SecStart = new GlobalVariable(
- M, Ty->getPointerElementType(), false, GlobalVariable::ExternalLinkage,
- nullptr, getSectionStart(Section));
+ GlobalVariable *SecStart = new GlobalVariable(
+ M, Ty->getPointerElementType(), false, GlobalVariable::ExternalLinkage,
+ nullptr, getSectionStart(Section));
SecStart->setVisibility(GlobalValue::HiddenVisibility);
- GlobalVariable *SecEnd = new GlobalVariable(
- M, Ty->getPointerElementType(), false, GlobalVariable::ExternalLinkage,
- nullptr, getSectionEnd(Section));
+ GlobalVariable *SecEnd = new GlobalVariable(
+ M, Ty->getPointerElementType(), false, GlobalVariable::ExternalLinkage,
+ nullptr, getSectionEnd(Section));
SecEnd->setVisibility(GlobalValue::HiddenVisibility);
IRBuilder<> IRB(M.getContext());
if (!TargetTriple.isOSBinFormatCOFF())
- return std::make_pair(SecStart, SecEnd);
+ return std::make_pair(SecStart, SecEnd);
// Account for the fact that on windows-msvc __start_* symbols actually
// point to a uint64_t before the start of the array.
auto SecStartI8Ptr = IRB.CreatePointerCast(SecStart, Int8PtrTy);
auto GEP = IRB.CreateGEP(Int8Ty, SecStartI8Ptr,
ConstantInt::get(IntptrTy, sizeof(uint64_t)));
- return std::make_pair(IRB.CreatePointerCast(GEP, Ty), SecEnd);
+ return std::make_pair(IRB.CreatePointerCast(GEP, Ty), SecEnd);
}
Function *ModuleSanitizerCoverage::CreateInitCallsForSections(
@@ -415,13 +415,13 @@ bool ModuleSanitizerCoverage::instrumentModule(
SanCovTracePCIndir =
M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy);
- // Make sure smaller parameters are zero-extended to i64 if required by the
- // target ABI.
+ // Make sure smaller parameters are zero-extended to i64 if required by the
+ // target ABI.
AttributeList SanCovTraceCmpZeroExtAL;
- SanCovTraceCmpZeroExtAL =
- SanCovTraceCmpZeroExtAL.addParamAttribute(*C, 0, Attribute::ZExt);
- SanCovTraceCmpZeroExtAL =
- SanCovTraceCmpZeroExtAL.addParamAttribute(*C, 1, Attribute::ZExt);
+ SanCovTraceCmpZeroExtAL =
+ SanCovTraceCmpZeroExtAL.addParamAttribute(*C, 0, Attribute::ZExt);
+ SanCovTraceCmpZeroExtAL =
+ SanCovTraceCmpZeroExtAL.addParamAttribute(*C, 1, Attribute::ZExt);
SanCovTraceCmpFunction[0] =
M.getOrInsertFunction(SanCovTraceCmp1, SanCovTraceCmpZeroExtAL, VoidTy,
@@ -446,7 +446,7 @@ bool ModuleSanitizerCoverage::instrumentModule(
{
AttributeList AL;
- AL = AL.addParamAttribute(*C, 0, Attribute::ZExt);
+ AL = AL.addParamAttribute(*C, 0, Attribute::ZExt);
SanCovTraceDivFunction[0] =
M.getOrInsertFunction(SanCovTraceDiv4, AL, VoidTy, IRB.getInt32Ty());
}
@@ -509,23 +509,23 @@ bool ModuleSanitizerCoverage::instrumentModule(
// True if block has successors and it dominates all of them.
static bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT) {
- if (succ_empty(BB))
+ if (succ_empty(BB))
return false;
- return llvm::all_of(successors(BB), [&](const BasicBlock *SUCC) {
- return DT->dominates(BB, SUCC);
- });
+ return llvm::all_of(successors(BB), [&](const BasicBlock *SUCC) {
+ return DT->dominates(BB, SUCC);
+ });
}
// True if block has predecessors and it postdominates all of them.
static bool isFullPostDominator(const BasicBlock *BB,
const PostDominatorTree *PDT) {
- if (pred_empty(BB))
+ if (pred_empty(BB))
return false;
- return llvm::all_of(predecessors(BB), [&](const BasicBlock *PRED) {
- return PDT->dominates(BB, PRED);
- });
+ return llvm::all_of(predecessors(BB), [&](const BasicBlock *PRED) {
+ return PDT->dominates(BB, PRED);
+ });
}
static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
@@ -795,7 +795,7 @@ void ModuleSanitizerCoverage::InjectTraceForSwitch(
C = ConstantExpr::getCast(CastInst::ZExt, It.getCaseValue(), Int64Ty);
Initializers.push_back(C);
}
- llvm::sort(drop_begin(Initializers, 2),
+ llvm::sort(drop_begin(Initializers, 2),
[](const Constant *A, const Constant *B) {
return cast<ConstantInt>(A)->getLimitedValue() <
cast<ConstantInt>(B)->getLimitedValue();
@@ -883,7 +883,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
DebugLoc EntryLoc;
if (IsEntryBB) {
if (auto SP = F.getSubprogram())
- EntryLoc = DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
+ EntryLoc = DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
// Keep static allocas and llvm.localescape calls in the entry block. Even
// if we aren't splitting the block, it's nice for allocas to be before
// calls.
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/contrib/libs/llvm12/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
index 85d36a0d4f..783878cf1e 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
@@ -19,8 +19,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
@@ -53,36 +53,36 @@ using namespace llvm;
#define DEBUG_TYPE "tsan"
-static cl::opt<bool> ClInstrumentMemoryAccesses(
+static cl::opt<bool> ClInstrumentMemoryAccesses(
"tsan-instrument-memory-accesses", cl::init(true),
cl::desc("Instrument memory accesses"), cl::Hidden);
-static cl::opt<bool>
- ClInstrumentFuncEntryExit("tsan-instrument-func-entry-exit", cl::init(true),
- cl::desc("Instrument function entry and exit"),
- cl::Hidden);
-static cl::opt<bool> ClHandleCxxExceptions(
+static cl::opt<bool>
+ ClInstrumentFuncEntryExit("tsan-instrument-func-entry-exit", cl::init(true),
+ cl::desc("Instrument function entry and exit"),
+ cl::Hidden);
+static cl::opt<bool> ClHandleCxxExceptions(
"tsan-handle-cxx-exceptions", cl::init(true),
cl::desc("Handle C++ exceptions (insert cleanup blocks for unwinding)"),
cl::Hidden);
-static cl::opt<bool> ClInstrumentAtomics("tsan-instrument-atomics",
- cl::init(true),
- cl::desc("Instrument atomics"),
- cl::Hidden);
-static cl::opt<bool> ClInstrumentMemIntrinsics(
+static cl::opt<bool> ClInstrumentAtomics("tsan-instrument-atomics",
+ cl::init(true),
+ cl::desc("Instrument atomics"),
+ cl::Hidden);
+static cl::opt<bool> ClInstrumentMemIntrinsics(
"tsan-instrument-memintrinsics", cl::init(true),
cl::desc("Instrument memintrinsics (memset/memcpy/memmove)"), cl::Hidden);
-static cl::opt<bool> ClDistinguishVolatile(
+static cl::opt<bool> ClDistinguishVolatile(
"tsan-distinguish-volatile", cl::init(false),
cl::desc("Emit special instrumentation for accesses to volatiles"),
cl::Hidden);
-static cl::opt<bool> ClInstrumentReadBeforeWrite(
+static cl::opt<bool> ClInstrumentReadBeforeWrite(
"tsan-instrument-read-before-write", cl::init(false),
cl::desc("Do not eliminate read instrumentation for read-before-writes"),
cl::Hidden);
-static cl::opt<bool> ClCompoundReadBeforeWrite(
- "tsan-compound-read-before-write", cl::init(false),
- cl::desc("Emit special compound instrumentation for reads-before-writes"),
- cl::Hidden);
+static cl::opt<bool> ClCompoundReadBeforeWrite(
+ "tsan-compound-read-before-write", cl::init(false),
+ cl::desc("Emit special compound instrumentation for reads-before-writes"),
+ cl::Hidden);
STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
STATISTIC(NumInstrumentedWrites, "Number of instrumented writes");
@@ -96,8 +96,8 @@ STATISTIC(NumOmittedReadsFromConstantGlobals,
STATISTIC(NumOmittedReadsFromVtable, "Number of vtable reads");
STATISTIC(NumOmittedNonCaptured, "Number of accesses ignored due to capturing");
-const char kTsanModuleCtorName[] = "tsan.module_ctor";
-const char kTsanInitName[] = "__tsan_init";
+const char kTsanModuleCtorName[] = "tsan.module_ctor";
+const char kTsanInitName[] = "__tsan_init";
namespace {
@@ -108,37 +108,37 @@ namespace {
/// ensures the __tsan_init function is in the list of global constructors for
/// the module.
struct ThreadSanitizer {
- ThreadSanitizer() {
- // Sanity check options and warn user.
- if (ClInstrumentReadBeforeWrite && ClCompoundReadBeforeWrite) {
- errs()
- << "warning: Option -tsan-compound-read-before-write has no effect "
- "when -tsan-instrument-read-before-write is set.\n";
- }
- }
-
+ ThreadSanitizer() {
+ // Sanity check options and warn user.
+ if (ClInstrumentReadBeforeWrite && ClCompoundReadBeforeWrite) {
+ errs()
+ << "warning: Option -tsan-compound-read-before-write has no effect "
+ "when -tsan-instrument-read-before-write is set.\n";
+ }
+ }
+
bool sanitizeFunction(Function &F, const TargetLibraryInfo &TLI);
private:
- // Internal Instruction wrapper that contains more information about the
- // Instruction from prior analysis.
- struct InstructionInfo {
- // Instrumentation emitted for this instruction is for a compounded set of
- // read and write operations in the same basic block.
- static constexpr unsigned kCompoundRW = (1U << 0);
-
- explicit InstructionInfo(Instruction *Inst) : Inst(Inst) {}
-
- Instruction *Inst;
- unsigned Flags = 0;
- };
-
+ // Internal Instruction wrapper that contains more information about the
+ // Instruction from prior analysis.
+ struct InstructionInfo {
+ // Instrumentation emitted for this instruction is for a compounded set of
+ // read and write operations in the same basic block.
+ static constexpr unsigned kCompoundRW = (1U << 0);
+
+ explicit InstructionInfo(Instruction *Inst) : Inst(Inst) {}
+
+ Instruction *Inst;
+ unsigned Flags = 0;
+ };
+
void initialize(Module &M);
- bool instrumentLoadOrStore(const InstructionInfo &II, const DataLayout &DL);
+ bool instrumentLoadOrStore(const InstructionInfo &II, const DataLayout &DL);
bool instrumentAtomic(Instruction *I, const DataLayout &DL);
bool instrumentMemIntrinsic(Instruction *I);
void chooseInstructionsToInstrument(SmallVectorImpl<Instruction *> &Local,
- SmallVectorImpl<InstructionInfo> &All,
+ SmallVectorImpl<InstructionInfo> &All,
const DataLayout &DL);
bool addrPointsToConstantData(Value *Addr);
int getMemoryAccessFuncIndex(Value *Addr, const DataLayout &DL);
@@ -159,8 +159,8 @@ private:
FunctionCallee TsanVolatileWrite[kNumberOfAccessSizes];
FunctionCallee TsanUnalignedVolatileRead[kNumberOfAccessSizes];
FunctionCallee TsanUnalignedVolatileWrite[kNumberOfAccessSizes];
- FunctionCallee TsanCompoundRW[kNumberOfAccessSizes];
- FunctionCallee TsanUnalignedCompoundRW[kNumberOfAccessSizes];
+ FunctionCallee TsanCompoundRW[kNumberOfAccessSizes];
+ FunctionCallee TsanUnalignedCompoundRW[kNumberOfAccessSizes];
FunctionCallee TsanAtomicLoad[kNumberOfAccessSizes];
FunctionCallee TsanAtomicStore[kNumberOfAccessSizes];
FunctionCallee TsanAtomicRMW[AtomicRMWInst::LAST_BINOP + 1]
@@ -299,15 +299,15 @@ void ThreadSanitizer::initialize(Module &M) {
TsanUnalignedVolatileWrite[i] = M.getOrInsertFunction(
UnalignedVolatileWriteName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy());
- SmallString<64> CompoundRWName("__tsan_read_write" + ByteSizeStr);
- TsanCompoundRW[i] = M.getOrInsertFunction(
- CompoundRWName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy());
-
- SmallString<64> UnalignedCompoundRWName("__tsan_unaligned_read_write" +
- ByteSizeStr);
- TsanUnalignedCompoundRW[i] = M.getOrInsertFunction(
- UnalignedCompoundRWName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy());
-
+ SmallString<64> CompoundRWName("__tsan_read_write" + ByteSizeStr);
+ TsanCompoundRW[i] = M.getOrInsertFunction(
+ CompoundRWName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy());
+
+ SmallString<64> UnalignedCompoundRWName("__tsan_unaligned_read_write" +
+ ByteSizeStr);
+ TsanUnalignedCompoundRW[i] = M.getOrInsertFunction(
+ UnalignedCompoundRWName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy());
+
Type *Ty = Type::getIntNTy(M.getContext(), BitSize);
Type *PtrTy = Ty->getPointerTo();
SmallString<32> AtomicLoadName("__tsan_atomic" + BitSizeStr + "_load");
@@ -442,43 +442,43 @@ bool ThreadSanitizer::addrPointsToConstantData(Value *Addr) {
// 'Local' is a vector of insns within the same BB (no calls between).
// 'All' is a vector of insns that will be instrumented.
void ThreadSanitizer::chooseInstructionsToInstrument(
- SmallVectorImpl<Instruction *> &Local,
- SmallVectorImpl<InstructionInfo> &All, const DataLayout &DL) {
- DenseMap<Value *, size_t> WriteTargets; // Map of addresses to index in All
+ SmallVectorImpl<Instruction *> &Local,
+ SmallVectorImpl<InstructionInfo> &All, const DataLayout &DL) {
+ DenseMap<Value *, size_t> WriteTargets; // Map of addresses to index in All
// Iterate from the end.
for (Instruction *I : reverse(Local)) {
- const bool IsWrite = isa<StoreInst>(*I);
- Value *Addr = IsWrite ? cast<StoreInst>(I)->getPointerOperand()
- : cast<LoadInst>(I)->getPointerOperand();
-
- if (!shouldInstrumentReadWriteFromAddress(I->getModule(), Addr))
- continue;
-
- if (!IsWrite) {
- const auto WriteEntry = WriteTargets.find(Addr);
- if (!ClInstrumentReadBeforeWrite && WriteEntry != WriteTargets.end()) {
- auto &WI = All[WriteEntry->second];
- // If we distinguish volatile accesses and if either the read or write
- // is volatile, do not omit any instrumentation.
- const bool AnyVolatile =
- ClDistinguishVolatile && (cast<LoadInst>(I)->isVolatile() ||
- cast<StoreInst>(WI.Inst)->isVolatile());
- if (!AnyVolatile) {
- // We will write to this temp, so no reason to analyze the read.
- // Mark the write instruction as compound.
- WI.Flags |= InstructionInfo::kCompoundRW;
- NumOmittedReadsBeforeWrite++;
- continue;
- }
+ const bool IsWrite = isa<StoreInst>(*I);
+ Value *Addr = IsWrite ? cast<StoreInst>(I)->getPointerOperand()
+ : cast<LoadInst>(I)->getPointerOperand();
+
+ if (!shouldInstrumentReadWriteFromAddress(I->getModule(), Addr))
+ continue;
+
+ if (!IsWrite) {
+ const auto WriteEntry = WriteTargets.find(Addr);
+ if (!ClInstrumentReadBeforeWrite && WriteEntry != WriteTargets.end()) {
+ auto &WI = All[WriteEntry->second];
+ // If we distinguish volatile accesses and if either the read or write
+ // is volatile, do not omit any instrumentation.
+ const bool AnyVolatile =
+ ClDistinguishVolatile && (cast<LoadInst>(I)->isVolatile() ||
+ cast<StoreInst>(WI.Inst)->isVolatile());
+ if (!AnyVolatile) {
+ // We will write to this temp, so no reason to analyze the read.
+ // Mark the write instruction as compound.
+ WI.Flags |= InstructionInfo::kCompoundRW;
+ NumOmittedReadsBeforeWrite++;
+ continue;
+ }
}
-
+
if (addrPointsToConstantData(Addr)) {
// Addr points to some constant data -- it can not race with any writes.
continue;
}
}
-
- if (isa<AllocaInst>(getUnderlyingObject(Addr)) &&
+
+ if (isa<AllocaInst>(getUnderlyingObject(Addr)) &&
!PointerMayBeCaptured(Addr, true, true)) {
// The variable is addressable but not captured, so it cannot be
// referenced from a different thread and participate in a data race
@@ -486,14 +486,14 @@ void ThreadSanitizer::chooseInstructionsToInstrument(
NumOmittedNonCaptured++;
continue;
}
-
- // Instrument this instruction.
- All.emplace_back(I);
- if (IsWrite) {
- // For read-before-write and compound instrumentation we only need one
- // write target, and we can override any previous entry if it exists.
- WriteTargets[Addr] = All.size() - 1;
- }
+
+ // Instrument this instruction.
+ All.emplace_back(I);
+ if (IsWrite) {
+ // For read-before-write and compound instrumentation we only need one
+ // write target, and we can override any previous entry if it exists.
+ WriteTargets[Addr] = All.size() - 1;
+ }
}
Local.clear();
}
@@ -534,7 +534,7 @@ bool ThreadSanitizer::sanitizeFunction(Function &F,
if (F.hasFnAttribute(Attribute::Naked))
return false;
initialize(*F.getParent());
- SmallVector<InstructionInfo, 8> AllLoadsAndStores;
+ SmallVector<InstructionInfo, 8> AllLoadsAndStores;
SmallVector<Instruction*, 8> LocalLoadsAndStores;
SmallVector<Instruction*, 8> AtomicAccesses;
SmallVector<Instruction*, 8> MemIntrinCalls;
@@ -569,8 +569,8 @@ bool ThreadSanitizer::sanitizeFunction(Function &F,
// Instrument memory accesses only if we want to report bugs in the function.
if (ClInstrumentMemoryAccesses && SanitizeFunction)
- for (const auto &II : AllLoadsAndStores) {
- Res |= instrumentLoadOrStore(II, DL);
+ for (const auto &II : AllLoadsAndStores) {
+ Res |= instrumentLoadOrStore(II, DL);
}
// Instrument atomic memory accesses in any case (they can be used to
@@ -608,12 +608,12 @@ bool ThreadSanitizer::sanitizeFunction(Function &F,
return Res;
}
-bool ThreadSanitizer::instrumentLoadOrStore(const InstructionInfo &II,
+bool ThreadSanitizer::instrumentLoadOrStore(const InstructionInfo &II,
const DataLayout &DL) {
- IRBuilder<> IRB(II.Inst);
- const bool IsWrite = isa<StoreInst>(*II.Inst);
- Value *Addr = IsWrite ? cast<StoreInst>(II.Inst)->getPointerOperand()
- : cast<LoadInst>(II.Inst)->getPointerOperand();
+ IRBuilder<> IRB(II.Inst);
+ const bool IsWrite = isa<StoreInst>(*II.Inst);
+ Value *Addr = IsWrite ? cast<StoreInst>(II.Inst)->getPointerOperand()
+ : cast<LoadInst>(II.Inst)->getPointerOperand();
// swifterror memory addresses are mem2reg promoted by instruction selection.
// As such they cannot have regular uses like an instrumentation function and
@@ -624,9 +624,9 @@ bool ThreadSanitizer::instrumentLoadOrStore(const InstructionInfo &II,
int Idx = getMemoryAccessFuncIndex(Addr, DL);
if (Idx < 0)
return false;
- if (IsWrite && isVtableAccess(II.Inst)) {
- LLVM_DEBUG(dbgs() << " VPTR : " << *II.Inst << "\n");
- Value *StoredValue = cast<StoreInst>(II.Inst)->getValueOperand();
+ if (IsWrite && isVtableAccess(II.Inst)) {
+ LLVM_DEBUG(dbgs() << " VPTR : " << *II.Inst << "\n");
+ Value *StoredValue = cast<StoreInst>(II.Inst)->getValueOperand();
// StoredValue may be a vector type if we are storing several vptrs at once.
// In this case, just take the first element of the vector since this is
// enough to find vptr races.
@@ -642,46 +642,46 @@ bool ThreadSanitizer::instrumentLoadOrStore(const InstructionInfo &II,
NumInstrumentedVtableWrites++;
return true;
}
- if (!IsWrite && isVtableAccess(II.Inst)) {
+ if (!IsWrite && isVtableAccess(II.Inst)) {
IRB.CreateCall(TsanVptrLoad,
IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()));
NumInstrumentedVtableReads++;
return true;
}
-
- const unsigned Alignment = IsWrite ? cast<StoreInst>(II.Inst)->getAlignment()
- : cast<LoadInst>(II.Inst)->getAlignment();
- const bool IsCompoundRW =
- ClCompoundReadBeforeWrite && (II.Flags & InstructionInfo::kCompoundRW);
- const bool IsVolatile = ClDistinguishVolatile &&
- (IsWrite ? cast<StoreInst>(II.Inst)->isVolatile()
- : cast<LoadInst>(II.Inst)->isVolatile());
- assert((!IsVolatile || !IsCompoundRW) && "Compound volatile invalid!");
-
+
+ const unsigned Alignment = IsWrite ? cast<StoreInst>(II.Inst)->getAlignment()
+ : cast<LoadInst>(II.Inst)->getAlignment();
+ const bool IsCompoundRW =
+ ClCompoundReadBeforeWrite && (II.Flags & InstructionInfo::kCompoundRW);
+ const bool IsVolatile = ClDistinguishVolatile &&
+ (IsWrite ? cast<StoreInst>(II.Inst)->isVolatile()
+ : cast<LoadInst>(II.Inst)->isVolatile());
+ assert((!IsVolatile || !IsCompoundRW) && "Compound volatile invalid!");
+
Type *OrigTy = cast<PointerType>(Addr->getType())->getElementType();
const uint32_t TypeSize = DL.getTypeStoreSizeInBits(OrigTy);
FunctionCallee OnAccessFunc = nullptr;
if (Alignment == 0 || Alignment >= 8 || (Alignment % (TypeSize / 8)) == 0) {
- if (IsCompoundRW)
- OnAccessFunc = TsanCompoundRW[Idx];
- else if (IsVolatile)
+ if (IsCompoundRW)
+ OnAccessFunc = TsanCompoundRW[Idx];
+ else if (IsVolatile)
OnAccessFunc = IsWrite ? TsanVolatileWrite[Idx] : TsanVolatileRead[Idx];
else
OnAccessFunc = IsWrite ? TsanWrite[Idx] : TsanRead[Idx];
} else {
- if (IsCompoundRW)
- OnAccessFunc = TsanUnalignedCompoundRW[Idx];
- else if (IsVolatile)
+ if (IsCompoundRW)
+ OnAccessFunc = TsanUnalignedCompoundRW[Idx];
+ else if (IsVolatile)
OnAccessFunc = IsWrite ? TsanUnalignedVolatileWrite[Idx]
: TsanUnalignedVolatileRead[Idx];
else
OnAccessFunc = IsWrite ? TsanUnalignedWrite[Idx] : TsanUnalignedRead[Idx];
}
IRB.CreateCall(OnAccessFunc, IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()));
- if (IsCompoundRW || IsWrite)
- NumInstrumentedWrites++;
- if (IsCompoundRW || !IsWrite)
- NumInstrumentedReads++;
+ if (IsCompoundRW || IsWrite)
+ NumInstrumentedWrites++;
+ if (IsCompoundRW || !IsWrite)
+ NumInstrumentedReads++;
return true;
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/ValueProfileCollector.cpp b/contrib/libs/llvm12/lib/Transforms/Instrumentation/ValueProfileCollector.cpp
index e4c06b9466..fb6216bb21 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/ValueProfileCollector.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/ValueProfileCollector.cpp
@@ -11,7 +11,7 @@
//===----------------------------------------------------------------------===//
#include "ValueProfilePlugins.inc"
-#include "llvm/IR/Function.h"
+#include "llvm/IR/Function.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/InitializePasses.h"
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/ValueProfileCollector.h b/contrib/libs/llvm12/lib/Transforms/Instrumentation/ValueProfileCollector.h
index b3840d7a69..584a60ab45 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/ValueProfileCollector.h
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/ValueProfileCollector.h
@@ -18,15 +18,15 @@
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/ProfileData/InstrProf.h"
-#include <memory>
-#include <vector>
+#include <memory>
+#include <vector>
namespace llvm {
-class Function;
-class Instruction;
-class Value;
-
+class Function;
+class Instruction;
+class Value;
+
/// Utility analysis that determines what values are worth profiling.
/// The actual logic is inside the ValueProfileCollectorImpl, whose job is to
/// populate the Candidates vector.
diff --git a/contrib/libs/llvm12/lib/Transforms/Instrumentation/ya.make b/contrib/libs/llvm12/lib/Transforms/Instrumentation/ya.make
index 82f8c92dc5..39dab1eb7d 100644
--- a/contrib/libs/llvm12/lib/Transforms/Instrumentation/ya.make
+++ b/contrib/libs/llvm12/lib/Transforms/Instrumentation/ya.make
@@ -15,14 +15,14 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/ProfileData
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Transforms/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/ProfileData
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Transforms/Utils
)
ADDINCL(
@@ -45,7 +45,7 @@ SRCS(
InstrOrderFile.cpp
InstrProfiling.cpp
Instrumentation.cpp
- MemProfiler.cpp
+ MemProfiler.cpp
MemorySanitizer.cpp
PGOInstrumentation.cpp
PGOMemOPSizeOpt.cpp
diff --git a/contrib/libs/llvm12/lib/Transforms/ObjCARC/DependencyAnalysis.cpp b/contrib/libs/llvm12/lib/Transforms/ObjCARC/DependencyAnalysis.cpp
index d6f06c7c8d..7f7f2dc89b 100644
--- a/contrib/libs/llvm12/lib/Transforms/ObjCARC/DependencyAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/ObjCARC/DependencyAnalysis.cpp
@@ -22,7 +22,7 @@
#include "DependencyAnalysis.h"
#include "ObjCARC.h"
#include "ProvenanceAnalysis.h"
-#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/CFG.h"
using namespace llvm;
@@ -53,7 +53,7 @@ bool llvm::objcarc::CanAlterRefCount(const Instruction *Inst, const Value *Ptr,
return false;
if (AliasAnalysis::onlyAccessesArgPointees(MRB)) {
for (const Value *Op : Call->args()) {
- if (IsPotentialRetainableObjPtr(Op, *PA.getAA()) && PA.related(Ptr, Op))
+ if (IsPotentialRetainableObjPtr(Op, *PA.getAA()) && PA.related(Ptr, Op))
return true;
}
return false;
@@ -96,24 +96,24 @@ bool llvm::objcarc::CanUse(const Instruction *Inst, const Value *Ptr,
// For calls, just check the arguments (and not the callee operand).
for (auto OI = CS->arg_begin(), OE = CS->arg_end(); OI != OE; ++OI) {
const Value *Op = *OI;
- if (IsPotentialRetainableObjPtr(Op, *PA.getAA()) && PA.related(Ptr, Op))
+ if (IsPotentialRetainableObjPtr(Op, *PA.getAA()) && PA.related(Ptr, Op))
return true;
}
return false;
} else if (const StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
// Special-case stores, because we don't care about the stored value, just
// the store address.
- const Value *Op = GetUnderlyingObjCPtr(SI->getPointerOperand());
+ const Value *Op = GetUnderlyingObjCPtr(SI->getPointerOperand());
// If we can't tell what the underlying object was, assume there is a
// dependence.
- return IsPotentialRetainableObjPtr(Op, *PA.getAA()) && PA.related(Op, Ptr);
+ return IsPotentialRetainableObjPtr(Op, *PA.getAA()) && PA.related(Op, Ptr);
}
// Check each operand for a match.
for (User::const_op_iterator OI = Inst->op_begin(), OE = Inst->op_end();
OI != OE; ++OI) {
const Value *Op = *OI;
- if (IsPotentialRetainableObjPtr(Op, *PA.getAA()) && PA.related(Ptr, Op))
+ if (IsPotentialRetainableObjPtr(Op, *PA.getAA()) && PA.related(Ptr, Op))
return true;
}
return false;
@@ -209,13 +209,13 @@ llvm::objcarc::Depends(DependenceKind Flavor, Instruction *Inst,
/// non-local dependencies on Arg.
///
/// TODO: Cache results?
-static bool findDependencies(DependenceKind Flavor, const Value *Arg,
- BasicBlock *StartBB, Instruction *StartInst,
- SmallPtrSetImpl<Instruction *> &DependingInsts,
- ProvenanceAnalysis &PA) {
+static bool findDependencies(DependenceKind Flavor, const Value *Arg,
+ BasicBlock *StartBB, Instruction *StartInst,
+ SmallPtrSetImpl<Instruction *> &DependingInsts,
+ ProvenanceAnalysis &PA) {
BasicBlock::iterator StartPos = StartInst->getIterator();
- SmallPtrSet<const BasicBlock *, 4> Visited;
+ SmallPtrSet<const BasicBlock *, 4> Visited;
SmallVector<std::pair<BasicBlock *, BasicBlock::iterator>, 4> Worklist;
Worklist.push_back(std::make_pair(StartBB, StartPos));
do {
@@ -228,14 +228,14 @@ static bool findDependencies(DependenceKind Flavor, const Value *Arg,
if (LocalStartPos == StartBBBegin) {
pred_iterator PI(LocalStartBB), PE(LocalStartBB, false);
if (PI == PE)
- // Return if we've reached the function entry.
- return false;
- // Add the predecessors to the worklist.
- do {
- BasicBlock *PredBB = *PI;
- if (Visited.insert(PredBB).second)
- Worklist.push_back(std::make_pair(PredBB, PredBB->end()));
- } while (++PI != PE);
+ // Return if we've reached the function entry.
+ return false;
+ // Add the predecessors to the worklist.
+ do {
+ BasicBlock *PredBB = *PI;
+ if (Visited.insert(PredBB).second)
+ Worklist.push_back(std::make_pair(PredBB, PredBB->end()));
+ } while (++PI != PE);
break;
}
@@ -254,22 +254,22 @@ static bool findDependencies(DependenceKind Flavor, const Value *Arg,
if (BB == StartBB)
continue;
for (const BasicBlock *Succ : successors(BB))
- if (Succ != StartBB && !Visited.count(Succ))
- return false;
+ if (Succ != StartBB && !Visited.count(Succ))
+ return false;
}
-
- return true;
+
+ return true;
+}
+
+llvm::Instruction *llvm::objcarc::findSingleDependency(DependenceKind Flavor,
+ const Value *Arg,
+ BasicBlock *StartBB,
+ Instruction *StartInst,
+ ProvenanceAnalysis &PA) {
+ SmallPtrSet<Instruction *, 4> DependingInsts;
+
+ if (!findDependencies(Flavor, Arg, StartBB, StartInst, DependingInsts, PA) ||
+ DependingInsts.size() != 1)
+ return nullptr;
+ return *DependingInsts.begin();
}
-
-llvm::Instruction *llvm::objcarc::findSingleDependency(DependenceKind Flavor,
- const Value *Arg,
- BasicBlock *StartBB,
- Instruction *StartInst,
- ProvenanceAnalysis &PA) {
- SmallPtrSet<Instruction *, 4> DependingInsts;
-
- if (!findDependencies(Flavor, Arg, StartBB, StartInst, DependingInsts, PA) ||
- DependingInsts.size() != 1)
- return nullptr;
- return *DependingInsts.begin();
-}
diff --git a/contrib/libs/llvm12/lib/Transforms/ObjCARC/DependencyAnalysis.h b/contrib/libs/llvm12/lib/Transforms/ObjCARC/DependencyAnalysis.h
index 706099e0ee..cf4c05ebe9 100644
--- a/contrib/libs/llvm12/lib/Transforms/ObjCARC/DependencyAnalysis.h
+++ b/contrib/libs/llvm12/lib/Transforms/ObjCARC/DependencyAnalysis.h
@@ -50,12 +50,12 @@ enum DependenceKind {
RetainRVDep ///< Blocks objc_retainAutoreleasedReturnValue.
};
-/// Find dependent instructions. If there is exactly one dependent instruction,
-/// return it. Otherwise, return null.
-llvm::Instruction *findSingleDependency(DependenceKind Flavor, const Value *Arg,
- BasicBlock *StartBB,
- Instruction *StartInst,
- ProvenanceAnalysis &PA);
+/// Find dependent instructions. If there is exactly one dependent instruction,
+/// return it. Otherwise, return null.
+llvm::Instruction *findSingleDependency(DependenceKind Flavor, const Value *Arg,
+ BasicBlock *StartBB,
+ Instruction *StartInst,
+ ProvenanceAnalysis &PA);
bool
Depends(DependenceKind Flavor, Instruction *Inst, const Value *Arg,
diff --git a/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARC.cpp b/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARC.cpp
index c4350f6230..970136392f 100644
--- a/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARC.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARC.cpp
@@ -29,8 +29,8 @@ void llvm::initializeObjCARCOpts(PassRegistry &Registry) {
initializeObjCARCAAWrapperPassPass(Registry);
initializeObjCARCAPElimPass(Registry);
initializeObjCARCExpandPass(Registry);
- initializeObjCARCContractLegacyPassPass(Registry);
- initializeObjCARCOptLegacyPassPass(Registry);
+ initializeObjCARCContractLegacyPassPass(Registry);
+ initializeObjCARCOptLegacyPassPass(Registry);
initializePAEvalPass(Registry);
}
diff --git a/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCAPElim.cpp b/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCAPElim.cpp
index 579fa5a5b4..6a928f2c7f 100644
--- a/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCAPElim.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCAPElim.cpp
@@ -26,11 +26,11 @@
#include "ObjCARC.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/Constants.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/ObjCARC.h"
+#include "llvm/Transforms/ObjCARC.h"
using namespace llvm;
using namespace llvm::objcarc;
@@ -41,7 +41,7 @@ namespace {
/// Interprocedurally determine if calls made by the given call site can
/// possibly produce autoreleases.
-bool MayAutorelease(const CallBase &CB, unsigned Depth = 0) {
+bool MayAutorelease(const CallBase &CB, unsigned Depth = 0) {
if (const Function *Callee = CB.getCalledFunction()) {
if (!Callee->hasExactDefinition())
return true;
@@ -60,7 +60,7 @@ bool MayAutorelease(const CallBase &CB, unsigned Depth = 0) {
return true;
}
-bool OptimizeBB(BasicBlock *BB) {
+bool OptimizeBB(BasicBlock *BB) {
bool Changed = false;
Instruction *Push = nullptr;
@@ -98,7 +98,7 @@ bool OptimizeBB(BasicBlock *BB) {
return Changed;
}
-bool runImpl(Module &M) {
+bool runImpl(Module &M) {
if (!EnableARCOpts)
return false;
@@ -144,40 +144,40 @@ bool runImpl(Module &M) {
return Changed;
}
-
-/// Autorelease pool elimination.
-class ObjCARCAPElim : public ModulePass {
- void getAnalysisUsage(AnalysisUsage &AU) const override;
- bool runOnModule(Module &M) override;
-
-public:
- static char ID;
- ObjCARCAPElim() : ModulePass(ID) {
- initializeObjCARCAPElimPass(*PassRegistry::getPassRegistry());
- }
-};
-} // namespace
-
-char ObjCARCAPElim::ID = 0;
-INITIALIZE_PASS(ObjCARCAPElim, "objc-arc-apelim",
- "ObjC ARC autorelease pool elimination", false, false)
-
-Pass *llvm::createObjCARCAPElimPass() { return new ObjCARCAPElim(); }
-
-void ObjCARCAPElim::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesCFG();
-}
-
-bool ObjCARCAPElim::runOnModule(Module &M) {
- if (skipModule(M))
- return false;
- return runImpl(M);
-}
-
-PreservedAnalyses ObjCARCAPElimPass::run(Module &M, ModuleAnalysisManager &AM) {
- if (!runImpl(M))
- return PreservedAnalyses::all();
- PreservedAnalyses PA;
- PA.preserveSet<CFGAnalyses>();
- return PA;
-}
+
+/// Autorelease pool elimination.
+class ObjCARCAPElim : public ModulePass {
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+ bool runOnModule(Module &M) override;
+
+public:
+ static char ID;
+ ObjCARCAPElim() : ModulePass(ID) {
+ initializeObjCARCAPElimPass(*PassRegistry::getPassRegistry());
+ }
+};
+} // namespace
+
+char ObjCARCAPElim::ID = 0;
+INITIALIZE_PASS(ObjCARCAPElim, "objc-arc-apelim",
+ "ObjC ARC autorelease pool elimination", false, false)
+
+Pass *llvm::createObjCARCAPElimPass() { return new ObjCARCAPElim(); }
+
+void ObjCARCAPElim::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesCFG();
+}
+
+bool ObjCARCAPElim::runOnModule(Module &M) {
+ if (skipModule(M))
+ return false;
+ return runImpl(M);
+}
+
+PreservedAnalyses ObjCARCAPElimPass::run(Module &M, ModuleAnalysisManager &AM) {
+ if (!runImpl(M))
+ return PreservedAnalyses::all();
+ PreservedAnalyses PA;
+ PA.preserveSet<CFGAnalyses>();
+ return PA;
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCContract.cpp
index 120880ad37..86d161116e 100644
--- a/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCContract.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCContract.cpp
@@ -30,18 +30,18 @@
#include "ObjCARC.h"
#include "ProvenanceAnalysis.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Operator.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/ObjCARC.h"
+#include "llvm/Transforms/ObjCARC.h"
using namespace llvm;
using namespace llvm::objcarc;
@@ -56,63 +56,63 @@ STATISTIC(NumStoreStrongs, "Number objc_storeStrong calls formed");
//===----------------------------------------------------------------------===//
namespace {
-/// Late ARC optimizations
-///
-/// These change the IR in a way that makes it difficult to be analyzed by
-/// ObjCARCOpt, so it's run late.
-
-class ObjCARCContract {
- bool Changed;
- AAResults *AA;
- DominatorTree *DT;
- ProvenanceAnalysis PA;
- ARCRuntimeEntryPoints EP;
-
- /// A flag indicating whether this optimization pass should run.
- bool Run;
-
- /// The inline asm string to insert between calls and RetainRV calls to make
- /// the optimization work on targets which need it.
- const MDString *RVInstMarker;
-
- /// The set of inserted objc_storeStrong calls. If at the end of walking the
- /// function we have found no alloca instructions, these calls can be marked
- /// "tail".
- SmallPtrSet<CallInst *, 8> StoreStrongCalls;
-
- /// Returns true if we eliminated Inst.
- bool tryToPeepholeInstruction(
- Function &F, Instruction *Inst, inst_iterator &Iter,
- bool &TailOkForStoreStrong,
- const DenseMap<BasicBlock *, ColorVector> &BlockColors);
-
- bool optimizeRetainCall(Function &F, Instruction *Retain);
-
- bool contractAutorelease(Function &F, Instruction *Autorelease,
- ARCInstKind Class);
-
- void tryToContractReleaseIntoStoreStrong(
- Instruction *Release, inst_iterator &Iter,
- const DenseMap<BasicBlock *, ColorVector> &BlockColors);
-
-public:
- bool init(Module &M);
- bool run(Function &F, AAResults *AA, DominatorTree *DT);
-};
-
-class ObjCARCContractLegacyPass : public FunctionPass {
- ObjCARCContract OCARCC;
-
-public:
- void getAnalysisUsage(AnalysisUsage &AU) const override;
- bool doInitialization(Module &M) override;
- bool runOnFunction(Function &F) override;
-
- static char ID;
- ObjCARCContractLegacyPass() : FunctionPass(ID) {
- initializeObjCARCContractLegacyPassPass(*PassRegistry::getPassRegistry());
- }
-};
+/// Late ARC optimizations
+///
+/// These change the IR in a way that makes it difficult to be analyzed by
+/// ObjCARCOpt, so it's run late.
+
+class ObjCARCContract {
+ bool Changed;
+ AAResults *AA;
+ DominatorTree *DT;
+ ProvenanceAnalysis PA;
+ ARCRuntimeEntryPoints EP;
+
+ /// A flag indicating whether this optimization pass should run.
+ bool Run;
+
+ /// The inline asm string to insert between calls and RetainRV calls to make
+ /// the optimization work on targets which need it.
+ const MDString *RVInstMarker;
+
+ /// The set of inserted objc_storeStrong calls. If at the end of walking the
+ /// function we have found no alloca instructions, these calls can be marked
+ /// "tail".
+ SmallPtrSet<CallInst *, 8> StoreStrongCalls;
+
+ /// Returns true if we eliminated Inst.
+ bool tryToPeepholeInstruction(
+ Function &F, Instruction *Inst, inst_iterator &Iter,
+ bool &TailOkForStoreStrong,
+ const DenseMap<BasicBlock *, ColorVector> &BlockColors);
+
+ bool optimizeRetainCall(Function &F, Instruction *Retain);
+
+ bool contractAutorelease(Function &F, Instruction *Autorelease,
+ ARCInstKind Class);
+
+ void tryToContractReleaseIntoStoreStrong(
+ Instruction *Release, inst_iterator &Iter,
+ const DenseMap<BasicBlock *, ColorVector> &BlockColors);
+
+public:
+ bool init(Module &M);
+ bool run(Function &F, AAResults *AA, DominatorTree *DT);
+};
+
+class ObjCARCContractLegacyPass : public FunctionPass {
+ ObjCARCContract OCARCC;
+
+public:
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+ bool doInitialization(Module &M) override;
+ bool runOnFunction(Function &F) override;
+
+ static char ID;
+ ObjCARCContractLegacyPass() : FunctionPass(ID) {
+ initializeObjCARCContractLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+};
}
//===----------------------------------------------------------------------===//
@@ -156,17 +156,17 @@ bool ObjCARCContract::optimizeRetainCall(Function &F, Instruction *Retain) {
}
/// Merge an autorelease with a retain into a fused call.
-bool ObjCARCContract::contractAutorelease(Function &F, Instruction *Autorelease,
- ARCInstKind Class) {
+bool ObjCARCContract::contractAutorelease(Function &F, Instruction *Autorelease,
+ ARCInstKind Class) {
const Value *Arg = GetArgRCIdentityRoot(Autorelease);
// Check that there are no instructions between the retain and the autorelease
// (such as an autorelease_pop) which may change the count.
- DependenceKind DK = Class == ARCInstKind::AutoreleaseRV
- ? RetainAutoreleaseRVDep
- : RetainAutoreleaseDep;
- auto *Retain = dyn_cast_or_null<CallInst>(
- findSingleDependency(DK, Arg, Autorelease->getParent(), Autorelease, PA));
+ DependenceKind DK = Class == ARCInstKind::AutoreleaseRV
+ ? RetainAutoreleaseRVDep
+ : RetainAutoreleaseDep;
+ auto *Retain = dyn_cast_or_null<CallInst>(
+ findSingleDependency(DK, Arg, Autorelease->getParent(), Autorelease, PA));
if (!Retain || GetBasicARCInstKind(Retain) != ARCInstKind::Retain ||
GetArgRCIdentityRoot(Retain) != Arg)
@@ -196,7 +196,7 @@ bool ObjCARCContract::contractAutorelease(Function &F, Instruction *Autorelease,
static StoreInst *findSafeStoreForStoreStrongContraction(LoadInst *Load,
Instruction *Release,
ProvenanceAnalysis &PA,
- AAResults *AA) {
+ AAResults *AA) {
StoreInst *Store = nullptr;
bool SawRelease = false;
@@ -434,7 +434,7 @@ void ObjCARCContract::tryToContractReleaseIntoStoreStrong(
bool ObjCARCContract::tryToPeepholeInstruction(
Function &F, Instruction *Inst, inst_iterator &Iter,
- bool &TailOkForStoreStrongs,
+ bool &TailOkForStoreStrongs,
const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
// Only these library routines return their argument. In particular,
// objc_retainBlock does not necessarily return its argument.
@@ -445,7 +445,7 @@ bool ObjCARCContract::tryToPeepholeInstruction(
return false;
case ARCInstKind::Autorelease:
case ARCInstKind::AutoreleaseRV:
- return contractAutorelease(F, Inst, Class);
+ return contractAutorelease(F, Inst, Class);
case ARCInstKind::Retain:
// Attempt to convert retains to retainrvs if they are next to function
// calls.
@@ -476,7 +476,7 @@ bool ObjCARCContract::tryToPeepholeInstruction(
--BBI;
} while (IsNoopInstruction(&*BBI));
- if (GetRCIdentityRoot(&*BBI) == GetArgRCIdentityRoot(Inst)) {
+ if (GetRCIdentityRoot(&*BBI) == GetArgRCIdentityRoot(Inst)) {
LLVM_DEBUG(dbgs() << "Adding inline asm marker for the return value "
"optimization.\n");
Changed = true;
@@ -533,22 +533,22 @@ bool ObjCARCContract::tryToPeepholeInstruction(
// Top Level Driver
//===----------------------------------------------------------------------===//
-bool ObjCARCContract::init(Module &M) {
- // If nothing in the Module uses ARC, don't do anything.
- Run = ModuleHasARC(M);
- if (!Run)
- return false;
-
- EP.init(&M);
-
- // Initialize RVInstMarker.
- const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker";
- RVInstMarker = dyn_cast_or_null<MDString>(M.getModuleFlag(MarkerKey));
-
- return false;
-}
-
-bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
+bool ObjCARCContract::init(Module &M) {
+ // If nothing in the Module uses ARC, don't do anything.
+ Run = ModuleHasARC(M);
+ if (!Run)
+ return false;
+
+ EP.init(&M);
+
+ // Initialize RVInstMarker.
+ const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker";
+ RVInstMarker = dyn_cast_or_null<MDString>(M.getModuleFlag(MarkerKey));
+
+ return false;
+}
+
+bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
if (!EnableARCOpts)
return false;
@@ -557,9 +557,9 @@ bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
return false;
Changed = false;
- AA = A;
- DT = D;
- PA.setAA(A);
+ AA = A;
+ DT = D;
+ PA.setAA(A);
DenseMap<BasicBlock *, ColorVector> BlockColors;
if (F.hasPersonalityFn() &&
@@ -586,8 +586,8 @@ bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
// First try to peephole Inst. If there is nothing further we can do in
// terms of undoing objc-arc-expand, process the next inst.
- if (tryToPeepholeInstruction(F, Inst, I, TailOkForStoreStrongs,
- BlockColors))
+ if (tryToPeepholeInstruction(F, Inst, I, TailOkForStoreStrongs,
+ BlockColors))
continue;
// Otherwise, try to undo objc-arc-expand.
@@ -722,45 +722,45 @@ bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
// Misc Pass Manager
//===----------------------------------------------------------------------===//
-char ObjCARCContractLegacyPass::ID = 0;
-INITIALIZE_PASS_BEGIN(ObjCARCContractLegacyPass, "objc-arc-contract",
+char ObjCARCContractLegacyPass::ID = 0;
+INITIALIZE_PASS_BEGIN(ObjCARCContractLegacyPass, "objc-arc-contract",
"ObjC ARC contraction", false, false)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
-INITIALIZE_PASS_END(ObjCARCContractLegacyPass, "objc-arc-contract",
+INITIALIZE_PASS_END(ObjCARCContractLegacyPass, "objc-arc-contract",
"ObjC ARC contraction", false, false)
-void ObjCARCContractLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
+void ObjCARCContractLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<AAResultsWrapperPass>();
AU.addRequired<DominatorTreeWrapperPass>();
AU.setPreservesCFG();
}
-Pass *llvm::createObjCARCContractPass() {
- return new ObjCARCContractLegacyPass();
-}
-
-bool ObjCARCContractLegacyPass::doInitialization(Module &M) {
- return OCARCC.init(M);
-}
-
-bool ObjCARCContractLegacyPass::runOnFunction(Function &F) {
- auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
- auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- return OCARCC.run(F, AA, DT);
-}
-
-PreservedAnalyses ObjCARCContractPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- ObjCARCContract OCAC;
- OCAC.init(*F.getParent());
-
- bool Changed = OCAC.run(F, &AM.getResult<AAManager>(F),
- &AM.getResult<DominatorTreeAnalysis>(F));
- if (Changed) {
- PreservedAnalyses PA;
- PA.preserveSet<CFGAnalyses>();
- return PA;
- }
- return PreservedAnalyses::all();
+Pass *llvm::createObjCARCContractPass() {
+ return new ObjCARCContractLegacyPass();
+}
+
+bool ObjCARCContractLegacyPass::doInitialization(Module &M) {
+ return OCARCC.init(M);
+}
+
+bool ObjCARCContractLegacyPass::runOnFunction(Function &F) {
+ auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
+ auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ return OCARCC.run(F, AA, DT);
+}
+
+PreservedAnalyses ObjCARCContractPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ ObjCARCContract OCAC;
+ OCAC.init(*F.getParent());
+
+ bool Changed = OCAC.run(F, &AM.getResult<AAManager>(F),
+ &AM.getResult<DominatorTreeAnalysis>(F));
+ if (Changed) {
+ PreservedAnalyses PA;
+ PA.preserveSet<CFGAnalyses>();
+ return PA;
+ }
+ return PreservedAnalyses::all();
}
diff --git a/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCExpand.cpp b/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCExpand.cpp
index 7a8e01d5d7..d2121dcebe 100644
--- a/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCExpand.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCExpand.cpp
@@ -27,7 +27,7 @@
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/Value.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
@@ -35,7 +35,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/ObjCARC.h"
+#include "llvm/Transforms/ObjCARC.h"
#define DEBUG_TYPE "objc-arc-expand"
@@ -43,12 +43,12 @@ using namespace llvm;
using namespace llvm::objcarc;
namespace {
-static bool runImpl(Function &F) {
+static bool runImpl(Function &F) {
if (!EnableARCOpts)
return false;
// If nothing in the Module uses ARC, don't do anything.
- if (!ModuleHasARC(*F.getParent()))
+ if (!ModuleHasARC(*F.getParent()))
return false;
bool Changed = false;
@@ -90,37 +90,37 @@ static bool runImpl(Function &F) {
return Changed;
}
-
-/// Early ARC transformations.
-class ObjCARCExpand : public FunctionPass {
- void getAnalysisUsage(AnalysisUsage &AU) const override;
- bool runOnFunction(Function &F) override;
-
-public:
- static char ID;
- ObjCARCExpand() : FunctionPass(ID) {
- initializeObjCARCExpandPass(*PassRegistry::getPassRegistry());
- }
-};
-} // namespace
-
-char ObjCARCExpand::ID = 0;
-INITIALIZE_PASS(ObjCARCExpand, "objc-arc-expand", "ObjC ARC expansion", false,
- false)
-
-Pass *llvm::createObjCARCExpandPass() { return new ObjCARCExpand(); }
-
-void ObjCARCExpand::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesCFG();
-}
-
-bool ObjCARCExpand::runOnFunction(Function &F) { return runImpl(F); }
-
-PreservedAnalyses ObjCARCExpandPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- if (!runImpl(F))
- return PreservedAnalyses::all();
- PreservedAnalyses PA;
- PA.preserveSet<CFGAnalyses>();
- return PA;
-}
+
+/// Early ARC transformations.
+class ObjCARCExpand : public FunctionPass {
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+ bool runOnFunction(Function &F) override;
+
+public:
+ static char ID;
+ ObjCARCExpand() : FunctionPass(ID) {
+ initializeObjCARCExpandPass(*PassRegistry::getPassRegistry());
+ }
+};
+} // namespace
+
+char ObjCARCExpand::ID = 0;
+INITIALIZE_PASS(ObjCARCExpand, "objc-arc-expand", "ObjC ARC expansion", false,
+ false)
+
+Pass *llvm::createObjCARCExpandPass() { return new ObjCARCExpand(); }
+
+void ObjCARCExpand::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesCFG();
+}
+
+bool ObjCARCExpand::runOnFunction(Function &F) { return runImpl(F); }
+
+PreservedAnalyses ObjCARCExpandPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ if (!runImpl(F))
+ return PreservedAnalyses::all();
+ PreservedAnalyses PA;
+ PA.preserveSet<CFGAnalyses>();
+ return PA;
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
index e6761a9000..1c44749951 100644
--- a/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
@@ -65,7 +65,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/ObjCARC.h"
+#include "llvm/Transforms/ObjCARC.h"
#include <cassert>
#include <iterator>
#include <utility>
@@ -481,133 +481,133 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, BBState &BBInfo) {
namespace {
/// The main ARC optimization pass.
-class ObjCARCOpt {
- bool Changed;
- ProvenanceAnalysis PA;
-
- /// A cache of references to runtime entry point constants.
- ARCRuntimeEntryPoints EP;
-
- /// A cache of MDKinds that can be passed into other functions to propagate
- /// MDKind identifiers.
- ARCMDKindCache MDKindCache;
-
- /// A flag indicating whether this optimization pass should run.
- bool Run;
-
- /// A flag indicating whether the optimization that removes or moves
- /// retain/release pairs should be performed.
- bool DisableRetainReleasePairing = false;
-
- /// Flags which determine whether each of the interesting runtime functions
- /// is in fact used in the current function.
- unsigned UsedInThisFunction;
-
- bool OptimizeRetainRVCall(Function &F, Instruction *RetainRV);
- void OptimizeAutoreleaseRVCall(Function &F, Instruction *AutoreleaseRV,
- ARCInstKind &Class);
- void OptimizeIndividualCalls(Function &F);
-
- /// Optimize an individual call, optionally passing the
- /// GetArgRCIdentityRoot if it has already been computed.
- void OptimizeIndividualCallImpl(
- Function &F, DenseMap<BasicBlock *, ColorVector> &BlockColors,
- Instruction *Inst, ARCInstKind Class, const Value *Arg);
-
- /// Try to optimize an AutoreleaseRV with a RetainRV or ClaimRV. If the
- /// optimization occurs, returns true to indicate that the caller should
- /// assume the instructions are dead.
- bool OptimizeInlinedAutoreleaseRVCall(
- Function &F, DenseMap<BasicBlock *, ColorVector> &BlockColors,
- Instruction *Inst, const Value *&Arg, ARCInstKind Class,
- Instruction *AutoreleaseRV, const Value *&AutoreleaseRVArg);
-
- void CheckForCFGHazards(const BasicBlock *BB,
- DenseMap<const BasicBlock *, BBState> &BBStates,
- BBState &MyStates) const;
- bool VisitInstructionBottomUp(Instruction *Inst, BasicBlock *BB,
- BlotMapVector<Value *, RRInfo> &Retains,
- BBState &MyStates);
- bool VisitBottomUp(BasicBlock *BB,
- DenseMap<const BasicBlock *, BBState> &BBStates,
- BlotMapVector<Value *, RRInfo> &Retains);
- bool VisitInstructionTopDown(Instruction *Inst,
- DenseMap<Value *, RRInfo> &Releases,
- BBState &MyStates);
- bool VisitTopDown(BasicBlock *BB,
- DenseMap<const BasicBlock *, BBState> &BBStates,
- DenseMap<Value *, RRInfo> &Releases);
- bool Visit(Function &F, DenseMap<const BasicBlock *, BBState> &BBStates,
- BlotMapVector<Value *, RRInfo> &Retains,
- DenseMap<Value *, RRInfo> &Releases);
-
- void MoveCalls(Value *Arg, RRInfo &RetainsToMove, RRInfo &ReleasesToMove,
- BlotMapVector<Value *, RRInfo> &Retains,
- DenseMap<Value *, RRInfo> &Releases,
- SmallVectorImpl<Instruction *> &DeadInsts, Module *M);
-
- bool PairUpRetainsAndReleases(DenseMap<const BasicBlock *, BBState> &BBStates,
- BlotMapVector<Value *, RRInfo> &Retains,
- DenseMap<Value *, RRInfo> &Releases, Module *M,
- Instruction *Retain,
- SmallVectorImpl<Instruction *> &DeadInsts,
- RRInfo &RetainsToMove, RRInfo &ReleasesToMove,
- Value *Arg, bool KnownSafe,
- bool &AnyPairsCompletelyEliminated);
-
- bool PerformCodePlacement(DenseMap<const BasicBlock *, BBState> &BBStates,
- BlotMapVector<Value *, RRInfo> &Retains,
- DenseMap<Value *, RRInfo> &Releases, Module *M);
-
- void OptimizeWeakCalls(Function &F);
-
- bool OptimizeSequences(Function &F);
-
- void OptimizeReturns(Function &F);
+class ObjCARCOpt {
+ bool Changed;
+ ProvenanceAnalysis PA;
+
+ /// A cache of references to runtime entry point constants.
+ ARCRuntimeEntryPoints EP;
+
+ /// A cache of MDKinds that can be passed into other functions to propagate
+ /// MDKind identifiers.
+ ARCMDKindCache MDKindCache;
+
+ /// A flag indicating whether this optimization pass should run.
+ bool Run;
+
+ /// A flag indicating whether the optimization that removes or moves
+ /// retain/release pairs should be performed.
+ bool DisableRetainReleasePairing = false;
+
+ /// Flags which determine whether each of the interesting runtime functions
+ /// is in fact used in the current function.
+ unsigned UsedInThisFunction;
+
+ bool OptimizeRetainRVCall(Function &F, Instruction *RetainRV);
+ void OptimizeAutoreleaseRVCall(Function &F, Instruction *AutoreleaseRV,
+ ARCInstKind &Class);
+ void OptimizeIndividualCalls(Function &F);
+
+ /// Optimize an individual call, optionally passing the
+ /// GetArgRCIdentityRoot if it has already been computed.
+ void OptimizeIndividualCallImpl(
+ Function &F, DenseMap<BasicBlock *, ColorVector> &BlockColors,
+ Instruction *Inst, ARCInstKind Class, const Value *Arg);
+
+ /// Try to optimize an AutoreleaseRV with a RetainRV or ClaimRV. If the
+ /// optimization occurs, returns true to indicate that the caller should
+ /// assume the instructions are dead.
+ bool OptimizeInlinedAutoreleaseRVCall(
+ Function &F, DenseMap<BasicBlock *, ColorVector> &BlockColors,
+ Instruction *Inst, const Value *&Arg, ARCInstKind Class,
+ Instruction *AutoreleaseRV, const Value *&AutoreleaseRVArg);
+
+ void CheckForCFGHazards(const BasicBlock *BB,
+ DenseMap<const BasicBlock *, BBState> &BBStates,
+ BBState &MyStates) const;
+ bool VisitInstructionBottomUp(Instruction *Inst, BasicBlock *BB,
+ BlotMapVector<Value *, RRInfo> &Retains,
+ BBState &MyStates);
+ bool VisitBottomUp(BasicBlock *BB,
+ DenseMap<const BasicBlock *, BBState> &BBStates,
+ BlotMapVector<Value *, RRInfo> &Retains);
+ bool VisitInstructionTopDown(Instruction *Inst,
+ DenseMap<Value *, RRInfo> &Releases,
+ BBState &MyStates);
+ bool VisitTopDown(BasicBlock *BB,
+ DenseMap<const BasicBlock *, BBState> &BBStates,
+ DenseMap<Value *, RRInfo> &Releases);
+ bool Visit(Function &F, DenseMap<const BasicBlock *, BBState> &BBStates,
+ BlotMapVector<Value *, RRInfo> &Retains,
+ DenseMap<Value *, RRInfo> &Releases);
+
+ void MoveCalls(Value *Arg, RRInfo &RetainsToMove, RRInfo &ReleasesToMove,
+ BlotMapVector<Value *, RRInfo> &Retains,
+ DenseMap<Value *, RRInfo> &Releases,
+ SmallVectorImpl<Instruction *> &DeadInsts, Module *M);
+
+ bool PairUpRetainsAndReleases(DenseMap<const BasicBlock *, BBState> &BBStates,
+ BlotMapVector<Value *, RRInfo> &Retains,
+ DenseMap<Value *, RRInfo> &Releases, Module *M,
+ Instruction *Retain,
+ SmallVectorImpl<Instruction *> &DeadInsts,
+ RRInfo &RetainsToMove, RRInfo &ReleasesToMove,
+ Value *Arg, bool KnownSafe,
+ bool &AnyPairsCompletelyEliminated);
+
+ bool PerformCodePlacement(DenseMap<const BasicBlock *, BBState> &BBStates,
+ BlotMapVector<Value *, RRInfo> &Retains,
+ DenseMap<Value *, RRInfo> &Releases, Module *M);
+
+ void OptimizeWeakCalls(Function &F);
+
+ bool OptimizeSequences(Function &F);
+
+ void OptimizeReturns(Function &F);
#ifndef NDEBUG
- void GatherStatistics(Function &F, bool AfterOptimization = false);
+ void GatherStatistics(Function &F, bool AfterOptimization = false);
#endif
public:
- void init(Module &M);
- bool run(Function &F, AAResults &AA);
- void releaseMemory();
-};
-
-/// The main ARC optimization pass.
-class ObjCARCOptLegacyPass : public FunctionPass {
-public:
- ObjCARCOptLegacyPass() : FunctionPass(ID) {
- initializeObjCARCOptLegacyPassPass(*PassRegistry::getPassRegistry());
- }
- void getAnalysisUsage(AnalysisUsage &AU) const override;
- bool doInitialization(Module &M) override {
- OCAO.init(M);
- return false;
- }
- bool runOnFunction(Function &F) override {
- return OCAO.run(F, getAnalysis<AAResultsWrapperPass>().getAAResults());
- }
- void releaseMemory() override { OCAO.releaseMemory(); }
- static char ID;
-
-private:
- ObjCARCOpt OCAO;
-};
+ void init(Module &M);
+ bool run(Function &F, AAResults &AA);
+ void releaseMemory();
+};
+
+/// The main ARC optimization pass.
+class ObjCARCOptLegacyPass : public FunctionPass {
+public:
+ ObjCARCOptLegacyPass() : FunctionPass(ID) {
+ initializeObjCARCOptLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+ bool doInitialization(Module &M) override {
+ OCAO.init(M);
+ return false;
+ }
+ bool runOnFunction(Function &F) override {
+ return OCAO.run(F, getAnalysis<AAResultsWrapperPass>().getAAResults());
+ }
+ void releaseMemory() override { OCAO.releaseMemory(); }
+ static char ID;
+
+private:
+ ObjCARCOpt OCAO;
+};
} // end anonymous namespace
-char ObjCARCOptLegacyPass::ID = 0;
+char ObjCARCOptLegacyPass::ID = 0;
-INITIALIZE_PASS_BEGIN(ObjCARCOptLegacyPass, "objc-arc", "ObjC ARC optimization",
- false, false)
+INITIALIZE_PASS_BEGIN(ObjCARCOptLegacyPass, "objc-arc", "ObjC ARC optimization",
+ false, false)
INITIALIZE_PASS_DEPENDENCY(ObjCARCAAWrapperPass)
-INITIALIZE_PASS_END(ObjCARCOptLegacyPass, "objc-arc", "ObjC ARC optimization",
- false, false)
+INITIALIZE_PASS_END(ObjCARCOptLegacyPass, "objc-arc", "ObjC ARC optimization",
+ false, false)
-Pass *llvm::createObjCARCOptPass() { return new ObjCARCOptLegacyPass(); }
+Pass *llvm::createObjCARCOptPass() { return new ObjCARCOptLegacyPass(); }
-void ObjCARCOptLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
+void ObjCARCOptLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<ObjCARCAAWrapperPass>();
AU.addRequired<AAResultsWrapperPass>();
// ARC optimization doesn't currently split critical edges.
@@ -675,7 +675,7 @@ bool ObjCARCOpt::OptimizeInlinedAutoreleaseRVCall(
SmallVector<const Value *, 4> ArgUsers;
getEquivalentPHIs(*PN, ArgUsers);
- if (!llvm::is_contained(ArgUsers, AutoreleaseRVArg))
+ if (!llvm::is_contained(ArgUsers, AutoreleaseRVArg))
return false;
}
@@ -1125,7 +1125,7 @@ void ObjCARCOpt::OptimizeIndividualCallImpl(
if (!HasNull)
continue;
- Instruction *DepInst = nullptr;
+ Instruction *DepInst = nullptr;
// Check that there is nothing that cares about the reference
// count between the call and the phi.
@@ -1137,13 +1137,13 @@ void ObjCARCOpt::OptimizeIndividualCallImpl(
case ARCInstKind::Release:
// These can't be moved across things that care about the retain
// count.
- DepInst = findSingleDependency(NeedsPositiveRetainCount, Arg,
- Inst->getParent(), Inst, PA);
+ DepInst = findSingleDependency(NeedsPositiveRetainCount, Arg,
+ Inst->getParent(), Inst, PA);
break;
case ARCInstKind::Autorelease:
// These can't be moved across autorelease pool scope boundaries.
- DepInst = findSingleDependency(AutoreleasePoolBoundary, Arg,
- Inst->getParent(), Inst, PA);
+ DepInst = findSingleDependency(AutoreleasePoolBoundary, Arg,
+ Inst->getParent(), Inst, PA);
break;
case ARCInstKind::ClaimRV:
case ARCInstKind::RetainRV:
@@ -1157,7 +1157,7 @@ void ObjCARCOpt::OptimizeIndividualCallImpl(
llvm_unreachable("Invalid dependence flavor");
}
- if (DepInst != PN)
+ if (DepInst != PN)
continue;
Changed = true;
@@ -2231,21 +2231,21 @@ bool ObjCARCOpt::OptimizeSequences(Function &F) {
/// Check if there is a dependent call earlier that does not have anything in
/// between the Retain and the call that can affect the reference count of their
/// shared pointer argument. Note that Retain need not be in BB.
-static CallInst *HasSafePathToPredecessorCall(const Value *Arg,
- Instruction *Retain,
- ProvenanceAnalysis &PA) {
- auto *Call = dyn_cast_or_null<CallInst>(findSingleDependency(
- CanChangeRetainCount, Arg, Retain->getParent(), Retain, PA));
+static CallInst *HasSafePathToPredecessorCall(const Value *Arg,
+ Instruction *Retain,
+ ProvenanceAnalysis &PA) {
+ auto *Call = dyn_cast_or_null<CallInst>(findSingleDependency(
+ CanChangeRetainCount, Arg, Retain->getParent(), Retain, PA));
// Check that the pointer is the return value of the call.
if (!Call || Arg != Call)
- return nullptr;
+ return nullptr;
// Check that the call is a regular call.
ARCInstKind Class = GetBasicARCInstKind(Call);
- return Class == ARCInstKind::CallOrUser || Class == ARCInstKind::Call
- ? Call
- : nullptr;
+ return Class == ARCInstKind::CallOrUser || Class == ARCInstKind::Call
+ ? Call
+ : nullptr;
}
/// Find a dependent retain that precedes the given autorelease for which there
@@ -2255,8 +2255,8 @@ static CallInst *
FindPredecessorRetainWithSafePath(const Value *Arg, BasicBlock *BB,
Instruction *Autorelease,
ProvenanceAnalysis &PA) {
- auto *Retain = dyn_cast_or_null<CallInst>(
- findSingleDependency(CanChangeRetainCount, Arg, BB, Autorelease, PA));
+ auto *Retain = dyn_cast_or_null<CallInst>(
+ findSingleDependency(CanChangeRetainCount, Arg, BB, Autorelease, PA));
// Check that we found a retain with the same argument.
if (!Retain || !IsRetain(GetBasicARCInstKind(Retain)) ||
@@ -2274,9 +2274,9 @@ static CallInst *
FindPredecessorAutoreleaseWithSafePath(const Value *Arg, BasicBlock *BB,
ReturnInst *Ret,
ProvenanceAnalysis &PA) {
- SmallPtrSet<Instruction *, 4> DepInsts;
- auto *Autorelease = dyn_cast_or_null<CallInst>(
- findSingleDependency(NeedsPositiveRetainCount, Arg, BB, Ret, PA));
+ SmallPtrSet<Instruction *, 4> DepInsts;
+ auto *Autorelease = dyn_cast_or_null<CallInst>(
+ findSingleDependency(NeedsPositiveRetainCount, Arg, BB, Ret, PA));
if (!Autorelease)
return nullptr;
@@ -2315,27 +2315,27 @@ void ObjCARCOpt::OptimizeReturns(Function &F) {
// Look for an ``autorelease'' instruction that is a predecessor of Ret and
// dependent on Arg such that there are no instructions dependent on Arg
// that need a positive ref count in between the autorelease and Ret.
- CallInst *Autorelease =
- FindPredecessorAutoreleaseWithSafePath(Arg, &BB, Ret, PA);
+ CallInst *Autorelease =
+ FindPredecessorAutoreleaseWithSafePath(Arg, &BB, Ret, PA);
if (!Autorelease)
continue;
CallInst *Retain = FindPredecessorRetainWithSafePath(
- Arg, Autorelease->getParent(), Autorelease, PA);
+ Arg, Autorelease->getParent(), Autorelease, PA);
if (!Retain)
continue;
// Check that there is nothing that can affect the reference count
// between the retain and the call. Note that Retain need not be in BB.
- CallInst *Call = HasSafePathToPredecessorCall(Arg, Retain, PA);
+ CallInst *Call = HasSafePathToPredecessorCall(Arg, Retain, PA);
// Don't remove retainRV/autoreleaseRV pairs if the call isn't a tail call.
- if (!Call ||
- (!Call->isTailCall() &&
- GetBasicARCInstKind(Retain) == ARCInstKind::RetainRV &&
- GetBasicARCInstKind(Autorelease) == ARCInstKind::AutoreleaseRV))
+ if (!Call ||
+ (!Call->isTailCall() &&
+ GetBasicARCInstKind(Retain) == ARCInstKind::RetainRV &&
+ GetBasicARCInstKind(Autorelease) == ARCInstKind::AutoreleaseRV))
continue;
// If so, we can zap the retain and autorelease.
@@ -2372,14 +2372,14 @@ ObjCARCOpt::GatherStatistics(Function &F, bool AfterOptimization) {
}
#endif
-void ObjCARCOpt::init(Module &M) {
+void ObjCARCOpt::init(Module &M) {
if (!EnableARCOpts)
- return;
+ return;
// If nothing in the Module uses ARC, don't do anything.
Run = ModuleHasARC(M);
if (!Run)
- return;
+ return;
// Intuitively, objc_retain and others are nocapture, however in practice
// they are not, because they return their argument value. And objc_release
@@ -2390,7 +2390,7 @@ void ObjCARCOpt::init(Module &M) {
EP.init(&M);
}
-bool ObjCARCOpt::run(Function &F, AAResults &AA) {
+bool ObjCARCOpt::run(Function &F, AAResults &AA) {
if (!EnableARCOpts)
return false;
@@ -2404,7 +2404,7 @@ bool ObjCARCOpt::run(Function &F, AAResults &AA) {
<< " >>>"
"\n");
- PA.setAA(&AA);
+ PA.setAA(&AA);
#ifndef NDEBUG
if (AreStatisticsEnabled()) {
@@ -2461,17 +2461,17 @@ void ObjCARCOpt::releaseMemory() {
/// @}
///
-
-PreservedAnalyses ObjCARCOptPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- ObjCARCOpt OCAO;
- OCAO.init(*F.getParent());
-
- bool Changed = OCAO.run(F, AM.getResult<AAManager>(F));
- if (Changed) {
- PreservedAnalyses PA;
- PA.preserveSet<CFGAnalyses>();
- return PA;
- }
- return PreservedAnalyses::all();
-}
+
+PreservedAnalyses ObjCARCOptPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ ObjCARCOpt OCAO;
+ OCAO.init(*F.getParent());
+
+ bool Changed = OCAO.run(F, AM.getResult<AAManager>(F));
+ if (Changed) {
+ PreservedAnalyses PA;
+ PA.preserveSet<CFGAnalyses>();
+ return PA;
+ }
+ return PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/ObjCARC/ProvenanceAnalysis.cpp b/contrib/libs/llvm12/lib/Transforms/ObjCARC/ProvenanceAnalysis.cpp
index 5b57b4837e..3d59b2edc5 100644
--- a/contrib/libs/llvm12/lib/Transforms/ObjCARC/ProvenanceAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/ObjCARC/ProvenanceAnalysis.cpp
@@ -44,11 +44,11 @@ bool ProvenanceAnalysis::relatedSelect(const SelectInst *A,
// check: just check for relations between the values on corresponding arms.
if (const SelectInst *SB = dyn_cast<SelectInst>(B))
if (A->getCondition() == SB->getCondition())
- return related(A->getTrueValue(), SB->getTrueValue()) ||
- related(A->getFalseValue(), SB->getFalseValue());
+ return related(A->getTrueValue(), SB->getTrueValue()) ||
+ related(A->getFalseValue(), SB->getFalseValue());
// Check both arms of the Select node individually.
- return related(A->getTrueValue(), B) || related(A->getFalseValue(), B);
+ return related(A->getTrueValue(), B) || related(A->getFalseValue(), B);
}
bool ProvenanceAnalysis::relatedPHI(const PHINode *A,
@@ -60,7 +60,7 @@ bool ProvenanceAnalysis::relatedPHI(const PHINode *A,
if (PNB->getParent() == A->getParent()) {
for (unsigned i = 0, e = A->getNumIncomingValues(); i != e; ++i)
if (related(A->getIncomingValue(i),
- PNB->getIncomingValueForBlock(A->getIncomingBlock(i))))
+ PNB->getIncomingValueForBlock(A->getIncomingBlock(i))))
return true;
return false;
}
@@ -68,7 +68,7 @@ bool ProvenanceAnalysis::relatedPHI(const PHINode *A,
// Check each unique source of the PHI node against B.
SmallPtrSet<const Value *, 4> UniqueSrc;
for (Value *PV1 : A->incoming_values()) {
- if (UniqueSrc.insert(PV1).second && related(PV1, B))
+ if (UniqueSrc.insert(PV1).second && related(PV1, B))
return true;
}
@@ -109,7 +109,7 @@ static bool IsStoredObjCPointer(const Value *P) {
return false;
}
-bool ProvenanceAnalysis::relatedCheck(const Value *A, const Value *B) {
+bool ProvenanceAnalysis::relatedCheck(const Value *A, const Value *B) {
// Ask regular AliasAnalysis, for a first approximation.
switch (AA->alias(A, B)) {
case NoAlias:
@@ -156,9 +156,9 @@ bool ProvenanceAnalysis::relatedCheck(const Value *A, const Value *B) {
return true;
}
-bool ProvenanceAnalysis::related(const Value *A, const Value *B) {
- A = GetUnderlyingObjCPtrCached(A, UnderlyingObjCPtrCache);
- B = GetUnderlyingObjCPtrCached(B, UnderlyingObjCPtrCache);
+bool ProvenanceAnalysis::related(const Value *A, const Value *B) {
+ A = GetUnderlyingObjCPtrCached(A, UnderlyingObjCPtrCache);
+ B = GetUnderlyingObjCPtrCached(B, UnderlyingObjCPtrCache);
// Quick check.
if (A == B)
@@ -173,7 +173,7 @@ bool ProvenanceAnalysis::related(const Value *A, const Value *B) {
if (!Pair.second)
return Pair.first->second;
- bool Result = relatedCheck(A, B);
+ bool Result = relatedCheck(A, B);
CachedResults[ValuePairTy(A, B)] = Result;
return Result;
}
diff --git a/contrib/libs/llvm12/lib/Transforms/ObjCARC/ProvenanceAnalysis.h b/contrib/libs/llvm12/lib/Transforms/ObjCARC/ProvenanceAnalysis.h
index 5c3c99463e..a63e356ce1 100644
--- a/contrib/libs/llvm12/lib/Transforms/ObjCARC/ProvenanceAnalysis.h
+++ b/contrib/libs/llvm12/lib/Transforms/ObjCARC/ProvenanceAnalysis.h
@@ -31,7 +31,7 @@
namespace llvm {
-class AAResults;
+class AAResults;
class DataLayout;
class PHINode;
class SelectInst;
@@ -49,7 +49,7 @@ namespace objcarc {
/// not two pointers have the same provenance source and thus could
/// potentially be related.
class ProvenanceAnalysis {
- AAResults *AA;
+ AAResults *AA;
using ValuePairTy = std::pair<const Value *, const Value *>;
using CachedResultsTy = DenseMap<ValuePairTy, bool>;
@@ -58,7 +58,7 @@ class ProvenanceAnalysis {
DenseMap<const Value *, WeakTrackingVH> UnderlyingObjCPtrCache;
- bool relatedCheck(const Value *A, const Value *B);
+ bool relatedCheck(const Value *A, const Value *B);
bool relatedSelect(const SelectInst *A, const Value *B);
bool relatedPHI(const PHINode *A, const Value *B);
@@ -67,11 +67,11 @@ public:
ProvenanceAnalysis(const ProvenanceAnalysis &) = delete;
ProvenanceAnalysis &operator=(const ProvenanceAnalysis &) = delete;
- void setAA(AAResults *aa) { AA = aa; }
+ void setAA(AAResults *aa) { AA = aa; }
- AAResults *getAA() const { return AA; }
+ AAResults *getAA() const { return AA; }
- bool related(const Value *A, const Value *B);
+ bool related(const Value *A, const Value *B);
void clear() {
CachedResults.clear();
diff --git a/contrib/libs/llvm12/lib/Transforms/ObjCARC/ProvenanceAnalysisEvaluator.cpp b/contrib/libs/llvm12/lib/Transforms/ObjCARC/ProvenanceAnalysisEvaluator.cpp
index 5a6ef9307c..6fdfe787d4 100644
--- a/contrib/libs/llvm12/lib/Transforms/ObjCARC/ProvenanceAnalysisEvaluator.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/ObjCARC/ProvenanceAnalysisEvaluator.cpp
@@ -12,7 +12,7 @@
#include "llvm/Analysis/Passes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstIterator.h"
-#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Module.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
@@ -75,7 +75,7 @@ bool PAEval::runOnFunction(Function &F) {
if (NameV1 >= NameV2)
continue;
errs() << NameV1 << " and " << NameV2;
- if (PA.related(V1, V2))
+ if (PA.related(V1, V2))
errs() << " are related.\n";
else
errs() << " are not related.\n";
diff --git a/contrib/libs/llvm12/lib/Transforms/ObjCARC/PtrState.cpp b/contrib/libs/llvm12/lib/Transforms/ObjCARC/PtrState.cpp
index 4399ebcacc..6071ec3e4d 100644
--- a/contrib/libs/llvm12/lib/Transforms/ObjCARC/PtrState.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/ObjCARC/PtrState.cpp
@@ -232,7 +232,7 @@ bool BottomUpPtrState::HandlePotentialAlterRefCount(Instruction *Inst,
Sequence S = GetSeq();
// Check for possible releases.
- if (!CanDecrementRefCount(Inst, Ptr, PA, Class))
+ if (!CanDecrementRefCount(Inst, Ptr, PA, Class))
return false;
LLVM_DEBUG(dbgs() << " CanAlterRefCount: Seq: " << S << "; "
@@ -383,7 +383,7 @@ bool TopDownPtrState::HandlePotentialAlterRefCount(Instruction *Inst,
ARCInstKind Class) {
// Check for possible releases. Treat clang.arc.use as a releasing instruction
// to prevent sinking a retain past it.
- if (!CanDecrementRefCount(Inst, Ptr, PA, Class) &&
+ if (!CanDecrementRefCount(Inst, Ptr, PA, Class) &&
Class != ARCInstKind::IntrinsicUser)
return false;
diff --git a/contrib/libs/llvm12/lib/Transforms/ObjCARC/ya.make b/contrib/libs/llvm12/lib/Transforms/ObjCARC/ya.make
index d35523fe03..727ec42c3f 100644
--- a/contrib/libs/llvm12/lib/Transforms/ObjCARC/ya.make
+++ b/contrib/libs/llvm12/lib/Transforms/ObjCARC/ya.make
@@ -12,12 +12,12 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Transforms/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Transforms/Utils
)
ADDINCL(
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/ADCE.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/ADCE.cpp
index 5f605b8ad4..ce4e5e575f 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/ADCE.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/ADCE.cpp
@@ -325,7 +325,7 @@ void AggressiveDeadCodeElimination::initialize() {
bool AggressiveDeadCodeElimination::isAlwaysLive(Instruction &I) {
// TODO -- use llvm::isInstructionTriviallyDead
- if (I.isEHPad() || I.mayHaveSideEffects() || !I.willReturn()) {
+ if (I.isEHPad() || I.mayHaveSideEffects() || !I.willReturn()) {
// Skip any value profile instrumentation calls if they are
// instrumenting constants.
if (isInstrumentsConstant(I))
@@ -643,7 +643,7 @@ void AggressiveDeadCodeElimination::computeReversePostOrder() {
SmallPtrSet<BasicBlock*, 16> Visited;
unsigned PostOrder = 0;
for (auto &BB : F) {
- if (!succ_empty(&BB))
+ if (!succ_empty(&BB))
continue;
for (BasicBlock *Block : inverse_post_order_ext(&BB,Visited))
BlockInfo[Block].PostOrder = PostOrder++;
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
index f57ee657c2..bccf94fc21 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
@@ -15,7 +15,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/InitializePasses.h"
#define AA_NAME "alignment-from-assumptions"
#define DEBUG_TYPE AA_NAME
@@ -204,33 +204,33 @@ static Align getNewAlignment(const SCEV *AASCEV, const SCEV *AlignSCEV,
}
bool AlignmentFromAssumptionsPass::extractAlignmentInfo(CallInst *I,
- unsigned Idx,
+ unsigned Idx,
Value *&AAPtr,
const SCEV *&AlignSCEV,
const SCEV *&OffSCEV) {
- Type *Int64Ty = Type::getInt64Ty(I->getContext());
- OperandBundleUse AlignOB = I->getOperandBundleAt(Idx);
- if (AlignOB.getTagName() != "align")
+ Type *Int64Ty = Type::getInt64Ty(I->getContext());
+ OperandBundleUse AlignOB = I->getOperandBundleAt(Idx);
+ if (AlignOB.getTagName() != "align")
return false;
- assert(AlignOB.Inputs.size() >= 2);
- AAPtr = AlignOB.Inputs[0].get();
- // TODO: Consider accumulating the offset to the base.
- AAPtr = AAPtr->stripPointerCastsSameRepresentation();
- AlignSCEV = SE->getSCEV(AlignOB.Inputs[1].get());
- AlignSCEV = SE->getTruncateOrZeroExtend(AlignSCEV, Int64Ty);
- if (AlignOB.Inputs.size() == 3)
- OffSCEV = SE->getSCEV(AlignOB.Inputs[2].get());
- else
+ assert(AlignOB.Inputs.size() >= 2);
+ AAPtr = AlignOB.Inputs[0].get();
+ // TODO: Consider accumulating the offset to the base.
+ AAPtr = AAPtr->stripPointerCastsSameRepresentation();
+ AlignSCEV = SE->getSCEV(AlignOB.Inputs[1].get());
+ AlignSCEV = SE->getTruncateOrZeroExtend(AlignSCEV, Int64Ty);
+ if (AlignOB.Inputs.size() == 3)
+ OffSCEV = SE->getSCEV(AlignOB.Inputs[2].get());
+ else
OffSCEV = SE->getZero(Int64Ty);
- OffSCEV = SE->getTruncateOrZeroExtend(OffSCEV, Int64Ty);
+ OffSCEV = SE->getTruncateOrZeroExtend(OffSCEV, Int64Ty);
return true;
}
-bool AlignmentFromAssumptionsPass::processAssumption(CallInst *ACall,
- unsigned Idx) {
+bool AlignmentFromAssumptionsPass::processAssumption(CallInst *ACall,
+ unsigned Idx) {
Value *AAPtr;
const SCEV *AlignSCEV, *OffSCEV;
- if (!extractAlignmentInfo(ACall, Idx, AAPtr, AlignSCEV, OffSCEV))
+ if (!extractAlignmentInfo(ACall, Idx, AAPtr, AlignSCEV, OffSCEV))
return false;
// Skip ConstantPointerNull and UndefValue. Assumptions on these shouldn't
@@ -254,8 +254,8 @@ bool AlignmentFromAssumptionsPass::processAssumption(CallInst *ACall,
while (!WorkList.empty()) {
Instruction *J = WorkList.pop_back_val();
if (LoadInst *LI = dyn_cast<LoadInst>(J)) {
- if (!isValidAssumeForContext(ACall, J, DT))
- continue;
+ if (!isValidAssumeForContext(ACall, J, DT))
+ continue;
Align NewAlignment = getNewAlignment(AASCEV, AlignSCEV, OffSCEV,
LI->getPointerOperand(), SE);
if (NewAlignment > LI->getAlign()) {
@@ -263,8 +263,8 @@ bool AlignmentFromAssumptionsPass::processAssumption(CallInst *ACall,
++NumLoadAlignChanged;
}
} else if (StoreInst *SI = dyn_cast<StoreInst>(J)) {
- if (!isValidAssumeForContext(ACall, J, DT))
- continue;
+ if (!isValidAssumeForContext(ACall, J, DT))
+ continue;
Align NewAlignment = getNewAlignment(AASCEV, AlignSCEV, OffSCEV,
SI->getPointerOperand(), SE);
if (NewAlignment > SI->getAlign()) {
@@ -272,8 +272,8 @@ bool AlignmentFromAssumptionsPass::processAssumption(CallInst *ACall,
++NumStoreAlignChanged;
}
} else if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(J)) {
- if (!isValidAssumeForContext(ACall, J, DT))
- continue;
+ if (!isValidAssumeForContext(ACall, J, DT))
+ continue;
Align NewDestAlignment =
getNewAlignment(AASCEV, AlignSCEV, OffSCEV, MI->getDest(), SE);
@@ -305,7 +305,7 @@ bool AlignmentFromAssumptionsPass::processAssumption(CallInst *ACall,
Visited.insert(J);
for (User *UJ : J->users()) {
Instruction *K = cast<Instruction>(UJ);
- if (!Visited.count(K))
+ if (!Visited.count(K))
WorkList.push_back(K);
}
}
@@ -332,11 +332,11 @@ bool AlignmentFromAssumptionsPass::runImpl(Function &F, AssumptionCache &AC,
bool Changed = false;
for (auto &AssumeVH : AC.assumptions())
- if (AssumeVH) {
- CallInst *Call = cast<CallInst>(AssumeVH);
- for (unsigned Idx = 0; Idx < Call->getNumOperandBundles(); Idx++)
- Changed |= processAssumption(Call, Idx);
- }
+ if (AssumeVH) {
+ CallInst *Call = cast<CallInst>(AssumeVH);
+ for (unsigned Idx = 0; Idx < Call->getNumOperandBundles(); Idx++)
+ Changed |= processAssumption(Call, Idx);
+ }
return Changed;
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/AnnotationRemarks.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/AnnotationRemarks.cpp
index 360c9b542e..a02d88fe06 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/AnnotationRemarks.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/AnnotationRemarks.cpp
@@ -1,90 +1,90 @@
-//===-- AnnotationRemarks.cpp - Generate remarks for annotated instrs. ----===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Generate remarks for instructions marked with !annotation.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Scalar/AnnotationRemarks.h"
-#include "llvm/ADT/MapVector.h"
-#include "llvm/Analysis/OptimizationRemarkEmitter.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/InstIterator.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Transforms/Scalar.h"
-
-using namespace llvm;
-using namespace llvm::ore;
-
-#define DEBUG_TYPE "annotation-remarks"
-#define REMARK_PASS DEBUG_TYPE
-
-static void runImpl(Function &F) {
- if (!OptimizationRemarkEmitter::allowExtraAnalysis(F, REMARK_PASS))
- return;
-
- OptimizationRemarkEmitter ORE(&F);
- // For now, just generate a summary of the annotated instructions.
- MapVector<StringRef, unsigned> Mapping;
- for (Instruction &I : instructions(F)) {
- if (!I.hasMetadata(LLVMContext::MD_annotation))
- continue;
- for (const MDOperand &Op :
- I.getMetadata(LLVMContext::MD_annotation)->operands()) {
- auto Iter = Mapping.insert({cast<MDString>(Op.get())->getString(), 0});
- Iter.first->second++;
- }
- }
-
- Instruction *IP = &*F.begin()->begin();
- for (const auto &KV : Mapping)
- ORE.emit(OptimizationRemarkAnalysis(REMARK_PASS, "AnnotationSummary", IP)
- << "Annotated " << NV("count", KV.second) << " instructions with "
- << NV("type", KV.first));
-}
-
-namespace {
-
-struct AnnotationRemarksLegacy : public FunctionPass {
- static char ID;
-
- AnnotationRemarksLegacy() : FunctionPass(ID) {
- initializeAnnotationRemarksLegacyPass(*PassRegistry::getPassRegistry());
- }
-
- bool runOnFunction(Function &F) override {
- runImpl(F);
- return false;
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- }
-};
-
-} // end anonymous namespace
-
-char AnnotationRemarksLegacy::ID = 0;
-
-INITIALIZE_PASS_BEGIN(AnnotationRemarksLegacy, "annotation-remarks",
- "Annotation Remarks", false, false)
-INITIALIZE_PASS_END(AnnotationRemarksLegacy, "annotation-remarks",
- "Annotation Remarks", false, false)
-
-FunctionPass *llvm::createAnnotationRemarksLegacyPass() {
- return new AnnotationRemarksLegacy();
-}
-
-PreservedAnalyses AnnotationRemarksPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- runImpl(F);
- return PreservedAnalyses::all();
-}
+//===-- AnnotationRemarks.cpp - Generate remarks for annotated instrs. ----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Generate remarks for instructions marked with !annotation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Scalar/AnnotationRemarks.h"
+#include "llvm/ADT/MapVector.h"
+#include "llvm/Analysis/OptimizationRemarkEmitter.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Transforms/Scalar.h"
+
+using namespace llvm;
+using namespace llvm::ore;
+
+#define DEBUG_TYPE "annotation-remarks"
+#define REMARK_PASS DEBUG_TYPE
+
+static void runImpl(Function &F) {
+ if (!OptimizationRemarkEmitter::allowExtraAnalysis(F, REMARK_PASS))
+ return;
+
+ OptimizationRemarkEmitter ORE(&F);
+ // For now, just generate a summary of the annotated instructions.
+ MapVector<StringRef, unsigned> Mapping;
+ for (Instruction &I : instructions(F)) {
+ if (!I.hasMetadata(LLVMContext::MD_annotation))
+ continue;
+ for (const MDOperand &Op :
+ I.getMetadata(LLVMContext::MD_annotation)->operands()) {
+ auto Iter = Mapping.insert({cast<MDString>(Op.get())->getString(), 0});
+ Iter.first->second++;
+ }
+ }
+
+ Instruction *IP = &*F.begin()->begin();
+ for (const auto &KV : Mapping)
+ ORE.emit(OptimizationRemarkAnalysis(REMARK_PASS, "AnnotationSummary", IP)
+ << "Annotated " << NV("count", KV.second) << " instructions with "
+ << NV("type", KV.first));
+}
+
+namespace {
+
+struct AnnotationRemarksLegacy : public FunctionPass {
+ static char ID;
+
+ AnnotationRemarksLegacy() : FunctionPass(ID) {
+ initializeAnnotationRemarksLegacyPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool runOnFunction(Function &F) override {
+ runImpl(F);
+ return false;
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ }
+};
+
+} // end anonymous namespace
+
+char AnnotationRemarksLegacy::ID = 0;
+
+INITIALIZE_PASS_BEGIN(AnnotationRemarksLegacy, "annotation-remarks",
+ "Annotation Remarks", false, false)
+INITIALIZE_PASS_END(AnnotationRemarksLegacy, "annotation-remarks",
+ "Annotation Remarks", false, false)
+
+FunctionPass *llvm::createAnnotationRemarksLegacyPass() {
+ return new AnnotationRemarksLegacy();
+}
+
+PreservedAnalyses AnnotationRemarksPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ runImpl(F);
+ return PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/CallSiteSplitting.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/CallSiteSplitting.cpp
index a9558f3f16..2eb94b721d 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/CallSiteSplitting.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/CallSiteSplitting.cpp
@@ -208,7 +208,7 @@ static bool canSplitCallSite(CallBase &CB, TargetTransformInfo &TTI) {
// instructions before the call is less then DuplicationThreshold. The
// instructions before the call will be duplicated in the split blocks and
// corresponding uses will be updated.
- InstructionCost Cost = 0;
+ InstructionCost Cost = 0;
for (auto &InstBeforeCall :
llvm::make_range(CallSiteBB->begin(), CB.getIterator())) {
Cost += TTI.getInstructionCost(&InstBeforeCall,
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/ConstantHoisting.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/ConstantHoisting.cpp
index 29197218f2..fdab74fc94 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/ConstantHoisting.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/ConstantHoisting.cpp
@@ -366,9 +366,9 @@ void ConstantHoistingPass::collectConstantCandidates(
ConstInt->getValue(), ConstInt->getType(),
TargetTransformInfo::TCK_SizeAndLatency);
else
- Cost = TTI->getIntImmCostInst(
- Inst->getOpcode(), Idx, ConstInt->getValue(), ConstInt->getType(),
- TargetTransformInfo::TCK_SizeAndLatency, Inst);
+ Cost = TTI->getIntImmCostInst(
+ Inst->getOpcode(), Idx, ConstInt->getValue(), ConstInt->getType(),
+ TargetTransformInfo::TCK_SizeAndLatency, Inst);
// Ignore cheap integer constants.
if (Cost > TargetTransformInfo::TCC_Basic) {
@@ -418,9 +418,9 @@ void ConstantHoistingPass::collectConstantCandidates(
// usually lowered to a load from constant pool. Such operation is unlikely
// to be cheaper than compute it by <Base + Offset>, which can be lowered to
// an ADD instruction or folded into Load/Store instruction.
- int Cost =
- TTI->getIntImmCostInst(Instruction::Add, 1, Offset, PtrIntTy,
- TargetTransformInfo::TCK_SizeAndLatency, Inst);
+ int Cost =
+ TTI->getIntImmCostInst(Instruction::Add, 1, Offset, PtrIntTy,
+ TargetTransformInfo::TCK_SizeAndLatency, Inst);
ConstCandVecType &ExprCandVec = ConstGEPCandMap[BaseGV];
ConstCandMapType::iterator Itr;
bool Inserted;
@@ -951,7 +951,7 @@ bool ConstantHoistingPass::runImpl(Function &Fn, TargetTransformInfo &TTI,
// base constant.
if (!ConstIntCandVec.empty())
findBaseConstants(nullptr);
- for (const auto &MapEntry : ConstGEPCandMap)
+ for (const auto &MapEntry : ConstGEPCandMap)
if (!MapEntry.second.empty())
findBaseConstants(MapEntry.first);
@@ -960,7 +960,7 @@ bool ConstantHoistingPass::runImpl(Function &Fn, TargetTransformInfo &TTI,
bool MadeChange = false;
if (!ConstIntInfoVec.empty())
MadeChange = emitBaseConstants(nullptr);
- for (const auto &MapEntry : ConstGEPInfoMap)
+ for (const auto &MapEntry : ConstGEPInfoMap)
if (!MapEntry.second.empty())
MadeChange |= emitBaseConstants(MapEntry.first);
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/ConstraintElimination.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/ConstraintElimination.cpp
index e46462aa1f..3b8af6f21c 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -1,407 +1,407 @@
-//===-- ConstraintElimination.cpp - Eliminate conds using constraints. ----===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Eliminate conditions based on constraints collected from dominating
-// conditions.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Scalar/ConstraintElimination.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/ConstraintSystem.h"
-#include "llvm/Analysis/GlobalsModRef.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/PatternMatch.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/DebugCounter.h"
-#include "llvm/Transforms/Scalar.h"
-
-using namespace llvm;
-using namespace PatternMatch;
-
-#define DEBUG_TYPE "constraint-elimination"
-
-STATISTIC(NumCondsRemoved, "Number of instructions removed");
-DEBUG_COUNTER(EliminatedCounter, "conds-eliminated",
- "Controls which conditions are eliminated");
-
-static int64_t MaxConstraintValue = std::numeric_limits<int64_t>::max();
-
-// Decomposes \p V into a vector of pairs of the form { c, X } where c * X. The
-// sum of the pairs equals \p V. The first pair is the constant-factor and X
-// must be nullptr. If the expression cannot be decomposed, returns an empty
-// vector.
-static SmallVector<std::pair<int64_t, Value *>, 4> decompose(Value *V) {
- if (auto *CI = dyn_cast<ConstantInt>(V)) {
- if (CI->isNegative() || CI->uge(MaxConstraintValue))
- return {};
- return {{CI->getSExtValue(), nullptr}};
- }
- auto *GEP = dyn_cast<GetElementPtrInst>(V);
- if (GEP && GEP->getNumOperands() == 2) {
- if (isa<ConstantInt>(GEP->getOperand(GEP->getNumOperands() - 1))) {
- return {{cast<ConstantInt>(GEP->getOperand(GEP->getNumOperands() - 1))
- ->getSExtValue(),
- nullptr},
- {1, GEP->getPointerOperand()}};
- }
- Value *Op0;
- ConstantInt *CI;
- if (match(GEP->getOperand(GEP->getNumOperands() - 1),
- m_NUWShl(m_Value(Op0), m_ConstantInt(CI))))
- return {{0, nullptr},
- {1, GEP->getPointerOperand()},
- {std::pow(int64_t(2), CI->getSExtValue()), Op0}};
- if (match(GEP->getOperand(GEP->getNumOperands() - 1),
- m_ZExt(m_NUWShl(m_Value(Op0), m_ConstantInt(CI)))))
- return {{0, nullptr},
- {1, GEP->getPointerOperand()},
- {std::pow(int64_t(2), CI->getSExtValue()), Op0}};
-
- return {{0, nullptr},
- {1, GEP->getPointerOperand()},
- {1, GEP->getOperand(GEP->getNumOperands() - 1)}};
- }
-
- Value *Op0;
- Value *Op1;
- ConstantInt *CI;
- if (match(V, m_NUWAdd(m_Value(Op0), m_ConstantInt(CI))))
- return {{CI->getSExtValue(), nullptr}, {1, Op0}};
- if (match(V, m_NUWAdd(m_Value(Op0), m_Value(Op1))))
- return {{0, nullptr}, {1, Op0}, {1, Op1}};
-
- if (match(V, m_NUWSub(m_Value(Op0), m_ConstantInt(CI))))
- return {{-1 * CI->getSExtValue(), nullptr}, {1, Op0}};
- if (match(V, m_NUWSub(m_Value(Op0), m_Value(Op1))))
- return {{0, nullptr}, {1, Op0}, {1, Op1}};
-
- return {{0, nullptr}, {1, V}};
-}
-
-/// Turn a condition \p CmpI into a constraint vector, using indices from \p
-/// Value2Index. If \p ShouldAdd is true, new indices are added for values not
-/// yet in \p Value2Index.
-static SmallVector<int64_t, 8>
-getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
- DenseMap<Value *, unsigned> &Value2Index, bool ShouldAdd) {
- int64_t Offset1 = 0;
- int64_t Offset2 = 0;
-
- auto TryToGetIndex = [ShouldAdd,
- &Value2Index](Value *V) -> Optional<unsigned> {
- if (ShouldAdd) {
- Value2Index.insert({V, Value2Index.size() + 1});
- return Value2Index[V];
- }
- auto I = Value2Index.find(V);
- if (I == Value2Index.end())
- return None;
- return I->second;
- };
-
- if (Pred == CmpInst::ICMP_UGT || Pred == CmpInst::ICMP_UGE)
- return getConstraint(CmpInst::getSwappedPredicate(Pred), Op1, Op0,
- Value2Index, ShouldAdd);
-
- // Only ULE and ULT predicates are supported at the moment.
- if (Pred != CmpInst::ICMP_ULE && Pred != CmpInst::ICMP_ULT)
- return {};
-
- auto ADec = decompose(Op0);
- auto BDec = decompose(Op1);
- // Skip if decomposing either of the values failed.
- if (ADec.empty() || BDec.empty())
- return {};
-
- // Skip trivial constraints without any variables.
- if (ADec.size() == 1 && BDec.size() == 1)
- return {};
-
- Offset1 = ADec[0].first;
- Offset2 = BDec[0].first;
- Offset1 *= -1;
-
- // Create iterator ranges that skip the constant-factor.
- auto VariablesA = make_range(std::next(ADec.begin()), ADec.end());
- auto VariablesB = make_range(std::next(BDec.begin()), BDec.end());
-
- // Check if each referenced value in the constraint is already in the system
- // or can be added (if ShouldAdd is true).
- for (const auto &KV :
- concat<std::pair<int64_t, Value *>>(VariablesA, VariablesB))
- if (!TryToGetIndex(KV.second))
- return {};
-
- // Build result constraint, by first adding all coefficients from A and then
- // subtracting all coefficients from B.
- SmallVector<int64_t, 8> R(Value2Index.size() + 1, 0);
- for (const auto &KV : VariablesA)
- R[Value2Index[KV.second]] += KV.first;
-
- for (const auto &KV : VariablesB)
- R[Value2Index[KV.second]] -= KV.first;
-
- R[0] = Offset1 + Offset2 + (Pred == CmpInst::ICMP_ULT ? -1 : 0);
- return R;
-}
-
-static SmallVector<int64_t, 8>
-getConstraint(CmpInst *Cmp, DenseMap<Value *, unsigned> &Value2Index,
- bool ShouldAdd) {
- return getConstraint(Cmp->getPredicate(), Cmp->getOperand(0),
- Cmp->getOperand(1), Value2Index, ShouldAdd);
-}
-
-namespace {
-/// Represents either a condition that holds on entry to a block or a basic
-/// block, with their respective Dominator DFS in and out numbers.
-struct ConstraintOrBlock {
- unsigned NumIn;
- unsigned NumOut;
- bool IsBlock;
- bool Not;
- union {
- BasicBlock *BB;
- CmpInst *Condition;
- };
-
- ConstraintOrBlock(DomTreeNode *DTN)
- : NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()), IsBlock(true),
- BB(DTN->getBlock()) {}
- ConstraintOrBlock(DomTreeNode *DTN, CmpInst *Condition, bool Not)
- : NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()), IsBlock(false),
- Not(Not), Condition(Condition) {}
-};
-
-struct StackEntry {
- unsigned NumIn;
- unsigned NumOut;
- CmpInst *Condition;
- bool IsNot;
-
- StackEntry(unsigned NumIn, unsigned NumOut, CmpInst *Condition, bool IsNot)
- : NumIn(NumIn), NumOut(NumOut), Condition(Condition), IsNot(IsNot) {}
-};
-} // namespace
-
-static bool eliminateConstraints(Function &F, DominatorTree &DT) {
- bool Changed = false;
- DT.updateDFSNumbers();
- ConstraintSystem CS;
-
- SmallVector<ConstraintOrBlock, 64> WorkList;
-
- // First, collect conditions implied by branches and blocks with their
- // Dominator DFS in and out numbers.
- for (BasicBlock &BB : F) {
- if (!DT.getNode(&BB))
- continue;
- WorkList.emplace_back(DT.getNode(&BB));
-
- auto *Br = dyn_cast<BranchInst>(BB.getTerminator());
- if (!Br || !Br->isConditional())
- continue;
-
- // If the condition is an OR of 2 compares and the false successor only has
- // the current block as predecessor, queue both negated conditions for the
- // false successor.
- Value *Op0, *Op1;
- if (match(Br->getCondition(), m_LogicalOr(m_Value(Op0), m_Value(Op1))) &&
- match(Op0, m_Cmp()) && match(Op1, m_Cmp())) {
- BasicBlock *FalseSuccessor = Br->getSuccessor(1);
- if (FalseSuccessor->getSinglePredecessor()) {
- WorkList.emplace_back(DT.getNode(FalseSuccessor), cast<CmpInst>(Op0),
- true);
- WorkList.emplace_back(DT.getNode(FalseSuccessor), cast<CmpInst>(Op1),
- true);
- }
- continue;
- }
-
- // If the condition is an AND of 2 compares and the true successor only has
- // the current block as predecessor, queue both conditions for the true
- // successor.
- if (match(Br->getCondition(), m_LogicalAnd(m_Value(Op0), m_Value(Op1))) &&
- match(Op0, m_Cmp()) && match(Op1, m_Cmp())) {
- BasicBlock *TrueSuccessor = Br->getSuccessor(0);
- if (TrueSuccessor->getSinglePredecessor()) {
- WorkList.emplace_back(DT.getNode(TrueSuccessor), cast<CmpInst>(Op0),
- false);
- WorkList.emplace_back(DT.getNode(TrueSuccessor), cast<CmpInst>(Op1),
- false);
- }
- continue;
- }
-
- auto *CmpI = dyn_cast<CmpInst>(Br->getCondition());
- if (!CmpI)
- continue;
- if (Br->getSuccessor(0)->getSinglePredecessor())
- WorkList.emplace_back(DT.getNode(Br->getSuccessor(0)), CmpI, false);
- if (Br->getSuccessor(1)->getSinglePredecessor())
- WorkList.emplace_back(DT.getNode(Br->getSuccessor(1)), CmpI, true);
- }
-
- // Next, sort worklist by dominance, so that dominating blocks and conditions
- // come before blocks and conditions dominated by them. If a block and a
- // condition have the same numbers, the condition comes before the block, as
- // it holds on entry to the block.
- sort(WorkList, [](const ConstraintOrBlock &A, const ConstraintOrBlock &B) {
- return std::tie(A.NumIn, A.IsBlock) < std::tie(B.NumIn, B.IsBlock);
- });
-
- // Finally, process ordered worklist and eliminate implied conditions.
- SmallVector<StackEntry, 16> DFSInStack;
- DenseMap<Value *, unsigned> Value2Index;
- for (ConstraintOrBlock &CB : WorkList) {
- // First, pop entries from the stack that are out-of-scope for CB. Remove
- // the corresponding entry from the constraint system.
- while (!DFSInStack.empty()) {
- auto &E = DFSInStack.back();
- LLVM_DEBUG(dbgs() << "Top of stack : " << E.NumIn << " " << E.NumOut
- << "\n");
- LLVM_DEBUG(dbgs() << "CB: " << CB.NumIn << " " << CB.NumOut << "\n");
- assert(E.NumIn <= CB.NumIn);
- if (CB.NumOut <= E.NumOut)
- break;
- LLVM_DEBUG(dbgs() << "Removing " << *E.Condition << " " << E.IsNot
- << "\n");
- DFSInStack.pop_back();
- CS.popLastConstraint();
- }
-
- LLVM_DEBUG({
- dbgs() << "Processing ";
- if (CB.IsBlock)
- dbgs() << *CB.BB;
- else
- dbgs() << *CB.Condition;
- dbgs() << "\n";
- });
-
- // For a block, check if any CmpInsts become known based on the current set
- // of constraints.
- if (CB.IsBlock) {
- for (Instruction &I : *CB.BB) {
- auto *Cmp = dyn_cast<CmpInst>(&I);
- if (!Cmp)
- continue;
- auto R = getConstraint(Cmp, Value2Index, false);
- if (R.empty() || R.size() == 1)
- continue;
- if (CS.isConditionImplied(R)) {
- if (!DebugCounter::shouldExecute(EliminatedCounter))
- continue;
-
- LLVM_DEBUG(dbgs() << "Condition " << *Cmp
- << " implied by dominating constraints\n");
- LLVM_DEBUG({
- for (auto &E : reverse(DFSInStack))
- dbgs() << " C " << *E.Condition << " " << E.IsNot << "\n";
- });
- Cmp->replaceAllUsesWith(
- ConstantInt::getTrue(F.getParent()->getContext()));
- NumCondsRemoved++;
- Changed = true;
- }
- if (CS.isConditionImplied(ConstraintSystem::negate(R))) {
- if (!DebugCounter::shouldExecute(EliminatedCounter))
- continue;
-
- LLVM_DEBUG(dbgs() << "Condition !" << *Cmp
- << " implied by dominating constraints\n");
- LLVM_DEBUG({
- for (auto &E : reverse(DFSInStack))
- dbgs() << " C " << *E.Condition << " " << E.IsNot << "\n";
- });
- Cmp->replaceAllUsesWith(
- ConstantInt::getFalse(F.getParent()->getContext()));
- NumCondsRemoved++;
- Changed = true;
- }
- }
- continue;
- }
-
- // Otherwise, add the condition to the system and stack, if we can transform
- // it into a constraint.
- auto R = getConstraint(CB.Condition, Value2Index, true);
- if (R.empty())
- continue;
-
- LLVM_DEBUG(dbgs() << "Adding " << *CB.Condition << " " << CB.Not << "\n");
- if (CB.Not)
- R = ConstraintSystem::negate(R);
-
- // If R has been added to the system, queue it for removal once it goes
- // out-of-scope.
- if (CS.addVariableRowFill(R))
- DFSInStack.emplace_back(CB.NumIn, CB.NumOut, CB.Condition, CB.Not);
- }
-
- return Changed;
-}
-
-PreservedAnalyses ConstraintEliminationPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
- if (!eliminateConstraints(F, DT))
- return PreservedAnalyses::all();
-
- PreservedAnalyses PA;
- PA.preserve<DominatorTreeAnalysis>();
- PA.preserve<GlobalsAA>();
- PA.preserveSet<CFGAnalyses>();
- return PA;
-}
-
-namespace {
-
-class ConstraintElimination : public FunctionPass {
-public:
- static char ID;
-
- ConstraintElimination() : FunctionPass(ID) {
- initializeConstraintEliminationPass(*PassRegistry::getPassRegistry());
- }
-
- bool runOnFunction(Function &F) override {
- auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- return eliminateConstraints(F, DT);
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesCFG();
- AU.addRequired<DominatorTreeWrapperPass>();
- AU.addPreserved<GlobalsAAWrapperPass>();
- AU.addPreserved<DominatorTreeWrapperPass>();
- }
-};
-
-} // end anonymous namespace
-
-char ConstraintElimination::ID = 0;
-
-INITIALIZE_PASS_BEGIN(ConstraintElimination, "constraint-elimination",
- "Constraint Elimination", false, false)
-INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass)
-INITIALIZE_PASS_END(ConstraintElimination, "constraint-elimination",
- "Constraint Elimination", false, false)
-
-FunctionPass *llvm::createConstraintEliminationPass() {
- return new ConstraintElimination();
-}
+//===-- ConstraintElimination.cpp - Eliminate conds using constraints. ----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Eliminate conditions based on constraints collected from dominating
+// conditions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Scalar/ConstraintElimination.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/ConstraintSystem.h"
+#include "llvm/Analysis/GlobalsModRef.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/PatternMatch.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/DebugCounter.h"
+#include "llvm/Transforms/Scalar.h"
+
+using namespace llvm;
+using namespace PatternMatch;
+
+#define DEBUG_TYPE "constraint-elimination"
+
+STATISTIC(NumCondsRemoved, "Number of instructions removed");
+DEBUG_COUNTER(EliminatedCounter, "conds-eliminated",
+ "Controls which conditions are eliminated");
+
+static int64_t MaxConstraintValue = std::numeric_limits<int64_t>::max();
+
+// Decomposes \p V into a vector of pairs of the form { c, X } where c * X. The
+// sum of the pairs equals \p V. The first pair is the constant-factor and X
+// must be nullptr. If the expression cannot be decomposed, returns an empty
+// vector.
+static SmallVector<std::pair<int64_t, Value *>, 4> decompose(Value *V) {
+ if (auto *CI = dyn_cast<ConstantInt>(V)) {
+ if (CI->isNegative() || CI->uge(MaxConstraintValue))
+ return {};
+ return {{CI->getSExtValue(), nullptr}};
+ }
+ auto *GEP = dyn_cast<GetElementPtrInst>(V);
+ if (GEP && GEP->getNumOperands() == 2) {
+ if (isa<ConstantInt>(GEP->getOperand(GEP->getNumOperands() - 1))) {
+ return {{cast<ConstantInt>(GEP->getOperand(GEP->getNumOperands() - 1))
+ ->getSExtValue(),
+ nullptr},
+ {1, GEP->getPointerOperand()}};
+ }
+ Value *Op0;
+ ConstantInt *CI;
+ if (match(GEP->getOperand(GEP->getNumOperands() - 1),
+ m_NUWShl(m_Value(Op0), m_ConstantInt(CI))))
+ return {{0, nullptr},
+ {1, GEP->getPointerOperand()},
+ {std::pow(int64_t(2), CI->getSExtValue()), Op0}};
+ if (match(GEP->getOperand(GEP->getNumOperands() - 1),
+ m_ZExt(m_NUWShl(m_Value(Op0), m_ConstantInt(CI)))))
+ return {{0, nullptr},
+ {1, GEP->getPointerOperand()},
+ {std::pow(int64_t(2), CI->getSExtValue()), Op0}};
+
+ return {{0, nullptr},
+ {1, GEP->getPointerOperand()},
+ {1, GEP->getOperand(GEP->getNumOperands() - 1)}};
+ }
+
+ Value *Op0;
+ Value *Op1;
+ ConstantInt *CI;
+ if (match(V, m_NUWAdd(m_Value(Op0), m_ConstantInt(CI))))
+ return {{CI->getSExtValue(), nullptr}, {1, Op0}};
+ if (match(V, m_NUWAdd(m_Value(Op0), m_Value(Op1))))
+ return {{0, nullptr}, {1, Op0}, {1, Op1}};
+
+ if (match(V, m_NUWSub(m_Value(Op0), m_ConstantInt(CI))))
+ return {{-1 * CI->getSExtValue(), nullptr}, {1, Op0}};
+ if (match(V, m_NUWSub(m_Value(Op0), m_Value(Op1))))
+ return {{0, nullptr}, {1, Op0}, {1, Op1}};
+
+ return {{0, nullptr}, {1, V}};
+}
+
+/// Turn a condition \p CmpI into a constraint vector, using indices from \p
+/// Value2Index. If \p ShouldAdd is true, new indices are added for values not
+/// yet in \p Value2Index.
+static SmallVector<int64_t, 8>
+getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
+ DenseMap<Value *, unsigned> &Value2Index, bool ShouldAdd) {
+ int64_t Offset1 = 0;
+ int64_t Offset2 = 0;
+
+ auto TryToGetIndex = [ShouldAdd,
+ &Value2Index](Value *V) -> Optional<unsigned> {
+ if (ShouldAdd) {
+ Value2Index.insert({V, Value2Index.size() + 1});
+ return Value2Index[V];
+ }
+ auto I = Value2Index.find(V);
+ if (I == Value2Index.end())
+ return None;
+ return I->second;
+ };
+
+ if (Pred == CmpInst::ICMP_UGT || Pred == CmpInst::ICMP_UGE)
+ return getConstraint(CmpInst::getSwappedPredicate(Pred), Op1, Op0,
+ Value2Index, ShouldAdd);
+
+ // Only ULE and ULT predicates are supported at the moment.
+ if (Pred != CmpInst::ICMP_ULE && Pred != CmpInst::ICMP_ULT)
+ return {};
+
+ auto ADec = decompose(Op0);
+ auto BDec = decompose(Op1);
+ // Skip if decomposing either of the values failed.
+ if (ADec.empty() || BDec.empty())
+ return {};
+
+ // Skip trivial constraints without any variables.
+ if (ADec.size() == 1 && BDec.size() == 1)
+ return {};
+
+ Offset1 = ADec[0].first;
+ Offset2 = BDec[0].first;
+ Offset1 *= -1;
+
+ // Create iterator ranges that skip the constant-factor.
+ auto VariablesA = make_range(std::next(ADec.begin()), ADec.end());
+ auto VariablesB = make_range(std::next(BDec.begin()), BDec.end());
+
+ // Check if each referenced value in the constraint is already in the system
+ // or can be added (if ShouldAdd is true).
+ for (const auto &KV :
+ concat<std::pair<int64_t, Value *>>(VariablesA, VariablesB))
+ if (!TryToGetIndex(KV.second))
+ return {};
+
+ // Build result constraint, by first adding all coefficients from A and then
+ // subtracting all coefficients from B.
+ SmallVector<int64_t, 8> R(Value2Index.size() + 1, 0);
+ for (const auto &KV : VariablesA)
+ R[Value2Index[KV.second]] += KV.first;
+
+ for (const auto &KV : VariablesB)
+ R[Value2Index[KV.second]] -= KV.first;
+
+ R[0] = Offset1 + Offset2 + (Pred == CmpInst::ICMP_ULT ? -1 : 0);
+ return R;
+}
+
+static SmallVector<int64_t, 8>
+getConstraint(CmpInst *Cmp, DenseMap<Value *, unsigned> &Value2Index,
+ bool ShouldAdd) {
+ return getConstraint(Cmp->getPredicate(), Cmp->getOperand(0),
+ Cmp->getOperand(1), Value2Index, ShouldAdd);
+}
+
+namespace {
+/// Represents either a condition that holds on entry to a block or a basic
+/// block, with their respective Dominator DFS in and out numbers.
+struct ConstraintOrBlock {
+ unsigned NumIn;
+ unsigned NumOut;
+ bool IsBlock;
+ bool Not;
+ union {
+ BasicBlock *BB;
+ CmpInst *Condition;
+ };
+
+ ConstraintOrBlock(DomTreeNode *DTN)
+ : NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()), IsBlock(true),
+ BB(DTN->getBlock()) {}
+ ConstraintOrBlock(DomTreeNode *DTN, CmpInst *Condition, bool Not)
+ : NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()), IsBlock(false),
+ Not(Not), Condition(Condition) {}
+};
+
+struct StackEntry {
+ unsigned NumIn;
+ unsigned NumOut;
+ CmpInst *Condition;
+ bool IsNot;
+
+ StackEntry(unsigned NumIn, unsigned NumOut, CmpInst *Condition, bool IsNot)
+ : NumIn(NumIn), NumOut(NumOut), Condition(Condition), IsNot(IsNot) {}
+};
+} // namespace
+
+static bool eliminateConstraints(Function &F, DominatorTree &DT) {
+ bool Changed = false;
+ DT.updateDFSNumbers();
+ ConstraintSystem CS;
+
+ SmallVector<ConstraintOrBlock, 64> WorkList;
+
+ // First, collect conditions implied by branches and blocks with their
+ // Dominator DFS in and out numbers.
+ for (BasicBlock &BB : F) {
+ if (!DT.getNode(&BB))
+ continue;
+ WorkList.emplace_back(DT.getNode(&BB));
+
+ auto *Br = dyn_cast<BranchInst>(BB.getTerminator());
+ if (!Br || !Br->isConditional())
+ continue;
+
+ // If the condition is an OR of 2 compares and the false successor only has
+ // the current block as predecessor, queue both negated conditions for the
+ // false successor.
+ Value *Op0, *Op1;
+ if (match(Br->getCondition(), m_LogicalOr(m_Value(Op0), m_Value(Op1))) &&
+ match(Op0, m_Cmp()) && match(Op1, m_Cmp())) {
+ BasicBlock *FalseSuccessor = Br->getSuccessor(1);
+ if (FalseSuccessor->getSinglePredecessor()) {
+ WorkList.emplace_back(DT.getNode(FalseSuccessor), cast<CmpInst>(Op0),
+ true);
+ WorkList.emplace_back(DT.getNode(FalseSuccessor), cast<CmpInst>(Op1),
+ true);
+ }
+ continue;
+ }
+
+ // If the condition is an AND of 2 compares and the true successor only has
+ // the current block as predecessor, queue both conditions for the true
+ // successor.
+ if (match(Br->getCondition(), m_LogicalAnd(m_Value(Op0), m_Value(Op1))) &&
+ match(Op0, m_Cmp()) && match(Op1, m_Cmp())) {
+ BasicBlock *TrueSuccessor = Br->getSuccessor(0);
+ if (TrueSuccessor->getSinglePredecessor()) {
+ WorkList.emplace_back(DT.getNode(TrueSuccessor), cast<CmpInst>(Op0),
+ false);
+ WorkList.emplace_back(DT.getNode(TrueSuccessor), cast<CmpInst>(Op1),
+ false);
+ }
+ continue;
+ }
+
+ auto *CmpI = dyn_cast<CmpInst>(Br->getCondition());
+ if (!CmpI)
+ continue;
+ if (Br->getSuccessor(0)->getSinglePredecessor())
+ WorkList.emplace_back(DT.getNode(Br->getSuccessor(0)), CmpI, false);
+ if (Br->getSuccessor(1)->getSinglePredecessor())
+ WorkList.emplace_back(DT.getNode(Br->getSuccessor(1)), CmpI, true);
+ }
+
+ // Next, sort worklist by dominance, so that dominating blocks and conditions
+ // come before blocks and conditions dominated by them. If a block and a
+ // condition have the same numbers, the condition comes before the block, as
+ // it holds on entry to the block.
+ sort(WorkList, [](const ConstraintOrBlock &A, const ConstraintOrBlock &B) {
+ return std::tie(A.NumIn, A.IsBlock) < std::tie(B.NumIn, B.IsBlock);
+ });
+
+ // Finally, process ordered worklist and eliminate implied conditions.
+ SmallVector<StackEntry, 16> DFSInStack;
+ DenseMap<Value *, unsigned> Value2Index;
+ for (ConstraintOrBlock &CB : WorkList) {
+ // First, pop entries from the stack that are out-of-scope for CB. Remove
+ // the corresponding entry from the constraint system.
+ while (!DFSInStack.empty()) {
+ auto &E = DFSInStack.back();
+ LLVM_DEBUG(dbgs() << "Top of stack : " << E.NumIn << " " << E.NumOut
+ << "\n");
+ LLVM_DEBUG(dbgs() << "CB: " << CB.NumIn << " " << CB.NumOut << "\n");
+ assert(E.NumIn <= CB.NumIn);
+ if (CB.NumOut <= E.NumOut)
+ break;
+ LLVM_DEBUG(dbgs() << "Removing " << *E.Condition << " " << E.IsNot
+ << "\n");
+ DFSInStack.pop_back();
+ CS.popLastConstraint();
+ }
+
+ LLVM_DEBUG({
+ dbgs() << "Processing ";
+ if (CB.IsBlock)
+ dbgs() << *CB.BB;
+ else
+ dbgs() << *CB.Condition;
+ dbgs() << "\n";
+ });
+
+ // For a block, check if any CmpInsts become known based on the current set
+ // of constraints.
+ if (CB.IsBlock) {
+ for (Instruction &I : *CB.BB) {
+ auto *Cmp = dyn_cast<CmpInst>(&I);
+ if (!Cmp)
+ continue;
+ auto R = getConstraint(Cmp, Value2Index, false);
+ if (R.empty() || R.size() == 1)
+ continue;
+ if (CS.isConditionImplied(R)) {
+ if (!DebugCounter::shouldExecute(EliminatedCounter))
+ continue;
+
+ LLVM_DEBUG(dbgs() << "Condition " << *Cmp
+ << " implied by dominating constraints\n");
+ LLVM_DEBUG({
+ for (auto &E : reverse(DFSInStack))
+ dbgs() << " C " << *E.Condition << " " << E.IsNot << "\n";
+ });
+ Cmp->replaceAllUsesWith(
+ ConstantInt::getTrue(F.getParent()->getContext()));
+ NumCondsRemoved++;
+ Changed = true;
+ }
+ if (CS.isConditionImplied(ConstraintSystem::negate(R))) {
+ if (!DebugCounter::shouldExecute(EliminatedCounter))
+ continue;
+
+ LLVM_DEBUG(dbgs() << "Condition !" << *Cmp
+ << " implied by dominating constraints\n");
+ LLVM_DEBUG({
+ for (auto &E : reverse(DFSInStack))
+ dbgs() << " C " << *E.Condition << " " << E.IsNot << "\n";
+ });
+ Cmp->replaceAllUsesWith(
+ ConstantInt::getFalse(F.getParent()->getContext()));
+ NumCondsRemoved++;
+ Changed = true;
+ }
+ }
+ continue;
+ }
+
+ // Otherwise, add the condition to the system and stack, if we can transform
+ // it into a constraint.
+ auto R = getConstraint(CB.Condition, Value2Index, true);
+ if (R.empty())
+ continue;
+
+ LLVM_DEBUG(dbgs() << "Adding " << *CB.Condition << " " << CB.Not << "\n");
+ if (CB.Not)
+ R = ConstraintSystem::negate(R);
+
+ // If R has been added to the system, queue it for removal once it goes
+ // out-of-scope.
+ if (CS.addVariableRowFill(R))
+ DFSInStack.emplace_back(CB.NumIn, CB.NumOut, CB.Condition, CB.Not);
+ }
+
+ return Changed;
+}
+
+PreservedAnalyses ConstraintEliminationPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
+ if (!eliminateConstraints(F, DT))
+ return PreservedAnalyses::all();
+
+ PreservedAnalyses PA;
+ PA.preserve<DominatorTreeAnalysis>();
+ PA.preserve<GlobalsAA>();
+ PA.preserveSet<CFGAnalyses>();
+ return PA;
+}
+
+namespace {
+
+class ConstraintElimination : public FunctionPass {
+public:
+ static char ID;
+
+ ConstraintElimination() : FunctionPass(ID) {
+ initializeConstraintEliminationPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool runOnFunction(Function &F) override {
+ auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ return eliminateConstraints(F, DT);
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesCFG();
+ AU.addRequired<DominatorTreeWrapperPass>();
+ AU.addPreserved<GlobalsAAWrapperPass>();
+ AU.addPreserved<DominatorTreeWrapperPass>();
+ }
+};
+
+} // end anonymous namespace
+
+char ConstraintElimination::ID = 0;
+
+INITIALIZE_PASS_BEGIN(ConstraintElimination, "constraint-elimination",
+ "Constraint Elimination", false, false)
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass)
+INITIALIZE_PASS_END(ConstraintElimination, "constraint-elimination",
+ "Constraint Elimination", false, false)
+
+FunctionPass *llvm::createConstraintEliminationPass() {
+ return new ConstraintElimination();
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
index c6a0c3ee7d..b671d68031 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
@@ -58,11 +58,11 @@ STATISTIC(NumMemAccess, "Number of memory access targets propagated");
STATISTIC(NumCmps, "Number of comparisons propagated");
STATISTIC(NumReturns, "Number of return values propagated");
STATISTIC(NumDeadCases, "Number of switch cases removed");
-STATISTIC(NumSDivSRemsNarrowed,
- "Number of sdivs/srems whose width was decreased");
+STATISTIC(NumSDivSRemsNarrowed,
+ "Number of sdivs/srems whose width was decreased");
STATISTIC(NumSDivs, "Number of sdiv converted to udiv");
-STATISTIC(NumUDivURemsNarrowed,
- "Number of udivs/urems whose width was decreased");
+STATISTIC(NumUDivURemsNarrowed,
+ "Number of udivs/urems whose width was decreased");
STATISTIC(NumAShrs, "Number of ashr converted to lshr");
STATISTIC(NumSRems, "Number of srem converted to urem");
STATISTIC(NumSExt, "Number of sext converted to zext");
@@ -129,7 +129,7 @@ static bool processSelect(SelectInst *S, LazyValueInfo *LVI) {
if (S->getType()->isVectorTy()) return false;
if (isa<Constant>(S->getCondition())) return false;
- Constant *C = LVI->getConstant(S->getCondition(), S);
+ Constant *C = LVI->getConstant(S->getCondition(), S);
if (!C) return false;
ConstantInt *CI = dyn_cast<ConstantInt>(C);
@@ -286,7 +286,7 @@ static bool processMemAccess(Instruction *I, LazyValueInfo *LVI) {
if (isa<Constant>(Pointer)) return false;
- Constant *C = LVI->getConstant(Pointer, I);
+ Constant *C = LVI->getConstant(Pointer, I);
if (!C) return false;
++NumMemAccess;
@@ -305,8 +305,8 @@ static bool processCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
return false;
LazyValueInfo::Tristate Result =
- LVI->getPredicateAt(Cmp->getPredicate(), Op0, C, Cmp,
- /*UseBlockValue=*/true);
+ LVI->getPredicateAt(Cmp->getPredicate(), Op0, C, Cmp,
+ /*UseBlockValue=*/true);
if (Result == LazyValueInfo::Unknown)
return false;
@@ -342,9 +342,9 @@ static bool processSwitch(SwitchInst *I, LazyValueInfo *LVI,
for (auto CI = SI->case_begin(), CE = SI->case_end(); CI != CE;) {
ConstantInt *Case = CI->getCaseValue();
- LazyValueInfo::Tristate State =
- LVI->getPredicateAt(CmpInst::ICMP_EQ, Cond, Case, I,
- /* UseBlockValue */ true);
+ LazyValueInfo::Tristate State =
+ LVI->getPredicateAt(CmpInst::ICMP_EQ, Cond, Case, I,
+ /* UseBlockValue */ true);
if (State == LazyValueInfo::False) {
// This case never fires - remove it.
@@ -388,8 +388,8 @@ static bool processSwitch(SwitchInst *I, LazyValueInfo *LVI,
// See if we can prove that the given binary op intrinsic will not overflow.
static bool willNotOverflow(BinaryOpIntrinsic *BO, LazyValueInfo *LVI) {
- ConstantRange LRange = LVI->getConstantRange(BO->getLHS(), BO);
- ConstantRange RRange = LVI->getConstantRange(BO->getRHS(), BO);
+ ConstantRange LRange = LVI->getConstantRange(BO->getLHS(), BO);
+ ConstantRange RRange = LVI->getConstantRange(BO->getRHS(), BO);
ConstantRange NWRegion = ConstantRange::makeGuaranteedNoWrapRegion(
BO->getBinaryOp(), RRange, BO->getNoWrapKind());
return NWRegion.contains(LRange);
@@ -504,8 +504,8 @@ static bool processCallSite(CallBase &CB, LazyValueInfo *LVI) {
}
}
- bool Changed = false;
-
+ bool Changed = false;
+
// Deopt bundle operands are intended to capture state with minimal
// perturbance of the code otherwise. If we can find a constant value for
// any such operand and remove a use of the original value, that's
@@ -520,16 +520,16 @@ static bool processCallSite(CallBase &CB, LazyValueInfo *LVI) {
if (V->getType()->isVectorTy()) continue;
if (isa<Constant>(V)) continue;
- Constant *C = LVI->getConstant(V, &CB);
+ Constant *C = LVI->getConstant(V, &CB);
if (!C) continue;
U.set(C);
- Changed = true;
+ Changed = true;
}
}
- SmallVector<unsigned, 4> ArgNos;
- unsigned ArgNo = 0;
-
+ SmallVector<unsigned, 4> ArgNos;
+ unsigned ArgNo = 0;
+
for (Value *V : CB.args()) {
PointerType *Type = dyn_cast<PointerType>(V->getType());
// Try to mark pointer typed parameters as non-null. We skip the
@@ -547,7 +547,7 @@ static bool processCallSite(CallBase &CB, LazyValueInfo *LVI) {
assert(ArgNo == CB.arg_size() && "sanity check");
if (ArgNos.empty())
- return Changed;
+ return Changed;
AttributeList AS = CB.getAttributes();
LLVMContext &Ctx = CB.getContext();
@@ -558,79 +558,79 @@ static bool processCallSite(CallBase &CB, LazyValueInfo *LVI) {
return true;
}
-static bool isNonNegative(Value *V, LazyValueInfo *LVI, Instruction *CxtI) {
- Constant *Zero = ConstantInt::get(V->getType(), 0);
- auto Result = LVI->getPredicateAt(ICmpInst::ICMP_SGE, V, Zero, CxtI);
- return Result == LazyValueInfo::True;
-}
-
-static bool isNonPositive(Value *V, LazyValueInfo *LVI, Instruction *CxtI) {
- Constant *Zero = ConstantInt::get(V->getType(), 0);
- auto Result = LVI->getPredicateAt(ICmpInst::ICMP_SLE, V, Zero, CxtI);
- return Result == LazyValueInfo::True;
-}
-
-enum class Domain { NonNegative, NonPositive, Unknown };
-
-Domain getDomain(Value *V, LazyValueInfo *LVI, Instruction *CxtI) {
- if (isNonNegative(V, LVI, CxtI))
- return Domain::NonNegative;
- if (isNonPositive(V, LVI, CxtI))
- return Domain::NonPositive;
- return Domain::Unknown;
-}
-
-/// Try to shrink a sdiv/srem's width down to the smallest power of two that's
-/// sufficient to contain its operands.
-static bool narrowSDivOrSRem(BinaryOperator *Instr, LazyValueInfo *LVI) {
- assert(Instr->getOpcode() == Instruction::SDiv ||
- Instr->getOpcode() == Instruction::SRem);
- if (Instr->getType()->isVectorTy())
- return false;
-
- // Find the smallest power of two bitwidth that's sufficient to hold Instr's
- // operands.
- unsigned OrigWidth = Instr->getType()->getIntegerBitWidth();
-
- // What is the smallest bit width that can accomodate the entire value ranges
- // of both of the operands?
- std::array<Optional<ConstantRange>, 2> CRs;
- unsigned MinSignedBits = 0;
- for (auto I : zip(Instr->operands(), CRs)) {
- std::get<1>(I) = LVI->getConstantRange(std::get<0>(I), Instr);
- MinSignedBits = std::max(std::get<1>(I)->getMinSignedBits(), MinSignedBits);
+static bool isNonNegative(Value *V, LazyValueInfo *LVI, Instruction *CxtI) {
+ Constant *Zero = ConstantInt::get(V->getType(), 0);
+ auto Result = LVI->getPredicateAt(ICmpInst::ICMP_SGE, V, Zero, CxtI);
+ return Result == LazyValueInfo::True;
+}
+
+static bool isNonPositive(Value *V, LazyValueInfo *LVI, Instruction *CxtI) {
+ Constant *Zero = ConstantInt::get(V->getType(), 0);
+ auto Result = LVI->getPredicateAt(ICmpInst::ICMP_SLE, V, Zero, CxtI);
+ return Result == LazyValueInfo::True;
+}
+
+enum class Domain { NonNegative, NonPositive, Unknown };
+
+Domain getDomain(Value *V, LazyValueInfo *LVI, Instruction *CxtI) {
+ if (isNonNegative(V, LVI, CxtI))
+ return Domain::NonNegative;
+ if (isNonPositive(V, LVI, CxtI))
+ return Domain::NonPositive;
+ return Domain::Unknown;
+}
+
+/// Try to shrink a sdiv/srem's width down to the smallest power of two that's
+/// sufficient to contain its operands.
+static bool narrowSDivOrSRem(BinaryOperator *Instr, LazyValueInfo *LVI) {
+ assert(Instr->getOpcode() == Instruction::SDiv ||
+ Instr->getOpcode() == Instruction::SRem);
+ if (Instr->getType()->isVectorTy())
+ return false;
+
+ // Find the smallest power of two bitwidth that's sufficient to hold Instr's
+ // operands.
+ unsigned OrigWidth = Instr->getType()->getIntegerBitWidth();
+
+ // What is the smallest bit width that can accomodate the entire value ranges
+ // of both of the operands?
+ std::array<Optional<ConstantRange>, 2> CRs;
+ unsigned MinSignedBits = 0;
+ for (auto I : zip(Instr->operands(), CRs)) {
+ std::get<1>(I) = LVI->getConstantRange(std::get<0>(I), Instr);
+ MinSignedBits = std::max(std::get<1>(I)->getMinSignedBits(), MinSignedBits);
}
-
- // sdiv/srem is UB if divisor is -1 and divident is INT_MIN, so unless we can
- // prove that such a combination is impossible, we need to bump the bitwidth.
- if (CRs[1]->contains(APInt::getAllOnesValue(OrigWidth)) &&
- CRs[0]->contains(
- APInt::getSignedMinValue(MinSignedBits).sextOrSelf(OrigWidth)))
- ++MinSignedBits;
-
- // Don't shrink below 8 bits wide.
- unsigned NewWidth = std::max<unsigned>(PowerOf2Ceil(MinSignedBits), 8);
-
- // NewWidth might be greater than OrigWidth if OrigWidth is not a power of
- // two.
- if (NewWidth >= OrigWidth)
- return false;
-
- ++NumSDivSRemsNarrowed;
- IRBuilder<> B{Instr};
- auto *TruncTy = Type::getIntNTy(Instr->getContext(), NewWidth);
- auto *LHS = B.CreateTruncOrBitCast(Instr->getOperand(0), TruncTy,
- Instr->getName() + ".lhs.trunc");
- auto *RHS = B.CreateTruncOrBitCast(Instr->getOperand(1), TruncTy,
- Instr->getName() + ".rhs.trunc");
- auto *BO = B.CreateBinOp(Instr->getOpcode(), LHS, RHS, Instr->getName());
- auto *Sext = B.CreateSExt(BO, Instr->getType(), Instr->getName() + ".sext");
- if (auto *BinOp = dyn_cast<BinaryOperator>(BO))
- if (BinOp->getOpcode() == Instruction::SDiv)
- BinOp->setIsExact(Instr->isExact());
-
- Instr->replaceAllUsesWith(Sext);
- Instr->eraseFromParent();
+
+ // sdiv/srem is UB if divisor is -1 and divident is INT_MIN, so unless we can
+ // prove that such a combination is impossible, we need to bump the bitwidth.
+ if (CRs[1]->contains(APInt::getAllOnesValue(OrigWidth)) &&
+ CRs[0]->contains(
+ APInt::getSignedMinValue(MinSignedBits).sextOrSelf(OrigWidth)))
+ ++MinSignedBits;
+
+ // Don't shrink below 8 bits wide.
+ unsigned NewWidth = std::max<unsigned>(PowerOf2Ceil(MinSignedBits), 8);
+
+ // NewWidth might be greater than OrigWidth if OrigWidth is not a power of
+ // two.
+ if (NewWidth >= OrigWidth)
+ return false;
+
+ ++NumSDivSRemsNarrowed;
+ IRBuilder<> B{Instr};
+ auto *TruncTy = Type::getIntNTy(Instr->getContext(), NewWidth);
+ auto *LHS = B.CreateTruncOrBitCast(Instr->getOperand(0), TruncTy,
+ Instr->getName() + ".lhs.trunc");
+ auto *RHS = B.CreateTruncOrBitCast(Instr->getOperand(1), TruncTy,
+ Instr->getName() + ".rhs.trunc");
+ auto *BO = B.CreateBinOp(Instr->getOpcode(), LHS, RHS, Instr->getName());
+ auto *Sext = B.CreateSExt(BO, Instr->getType(), Instr->getName() + ".sext");
+ if (auto *BinOp = dyn_cast<BinaryOperator>(BO))
+ if (BinOp->getOpcode() == Instruction::SDiv)
+ BinOp->setIsExact(Instr->isExact());
+
+ Instr->replaceAllUsesWith(Sext);
+ Instr->eraseFromParent();
return true;
}
@@ -644,23 +644,23 @@ static bool processUDivOrURem(BinaryOperator *Instr, LazyValueInfo *LVI) {
// Find the smallest power of two bitwidth that's sufficient to hold Instr's
// operands.
-
- // What is the smallest bit width that can accomodate the entire value ranges
- // of both of the operands?
- unsigned MaxActiveBits = 0;
+
+ // What is the smallest bit width that can accomodate the entire value ranges
+ // of both of the operands?
+ unsigned MaxActiveBits = 0;
for (Value *Operand : Instr->operands()) {
- ConstantRange CR = LVI->getConstantRange(Operand, Instr);
- MaxActiveBits = std::max(CR.getActiveBits(), MaxActiveBits);
+ ConstantRange CR = LVI->getConstantRange(Operand, Instr);
+ MaxActiveBits = std::max(CR.getActiveBits(), MaxActiveBits);
}
// Don't shrink below 8 bits wide.
- unsigned NewWidth = std::max<unsigned>(PowerOf2Ceil(MaxActiveBits), 8);
-
+ unsigned NewWidth = std::max<unsigned>(PowerOf2Ceil(MaxActiveBits), 8);
+
// NewWidth might be greater than OrigWidth if OrigWidth is not a power of
// two.
- if (NewWidth >= Instr->getType()->getIntegerBitWidth())
+ if (NewWidth >= Instr->getType()->getIntegerBitWidth())
return false;
- ++NumUDivURemsNarrowed;
+ ++NumUDivURemsNarrowed;
IRBuilder<> B{Instr};
auto *TruncTy = Type::getIntNTy(Instr->getContext(), NewWidth);
auto *LHS = B.CreateTruncOrBitCast(Instr->getOperand(0), TruncTy,
@@ -679,135 +679,135 @@ static bool processUDivOrURem(BinaryOperator *Instr, LazyValueInfo *LVI) {
}
static bool processSRem(BinaryOperator *SDI, LazyValueInfo *LVI) {
- assert(SDI->getOpcode() == Instruction::SRem);
- if (SDI->getType()->isVectorTy())
+ assert(SDI->getOpcode() == Instruction::SRem);
+ if (SDI->getType()->isVectorTy())
return false;
- struct Operand {
- Value *V;
- Domain D;
- };
- std::array<Operand, 2> Ops;
-
- for (const auto I : zip(Ops, SDI->operands())) {
- Operand &Op = std::get<0>(I);
- Op.V = std::get<1>(I);
- Op.D = getDomain(Op.V, LVI, SDI);
- if (Op.D == Domain::Unknown)
- return false;
- }
-
- // We know domains of both of the operands!
+ struct Operand {
+ Value *V;
+ Domain D;
+ };
+ std::array<Operand, 2> Ops;
+
+ for (const auto I : zip(Ops, SDI->operands())) {
+ Operand &Op = std::get<0>(I);
+ Op.V = std::get<1>(I);
+ Op.D = getDomain(Op.V, LVI, SDI);
+ if (Op.D == Domain::Unknown)
+ return false;
+ }
+
+ // We know domains of both of the operands!
++NumSRems;
-
- // We need operands to be non-negative, so negate each one that isn't.
- for (Operand &Op : Ops) {
- if (Op.D == Domain::NonNegative)
- continue;
- auto *BO =
- BinaryOperator::CreateNeg(Op.V, Op.V->getName() + ".nonneg", SDI);
- BO->setDebugLoc(SDI->getDebugLoc());
- Op.V = BO;
- }
-
- auto *URem =
- BinaryOperator::CreateURem(Ops[0].V, Ops[1].V, SDI->getName(), SDI);
- URem->setDebugLoc(SDI->getDebugLoc());
-
- Value *Res = URem;
-
- // If the divident was non-positive, we need to negate the result.
- if (Ops[0].D == Domain::NonPositive)
- Res = BinaryOperator::CreateNeg(Res, Res->getName() + ".neg", SDI);
-
- SDI->replaceAllUsesWith(Res);
+
+ // We need operands to be non-negative, so negate each one that isn't.
+ for (Operand &Op : Ops) {
+ if (Op.D == Domain::NonNegative)
+ continue;
+ auto *BO =
+ BinaryOperator::CreateNeg(Op.V, Op.V->getName() + ".nonneg", SDI);
+ BO->setDebugLoc(SDI->getDebugLoc());
+ Op.V = BO;
+ }
+
+ auto *URem =
+ BinaryOperator::CreateURem(Ops[0].V, Ops[1].V, SDI->getName(), SDI);
+ URem->setDebugLoc(SDI->getDebugLoc());
+
+ Value *Res = URem;
+
+ // If the divident was non-positive, we need to negate the result.
+ if (Ops[0].D == Domain::NonPositive)
+ Res = BinaryOperator::CreateNeg(Res, Res->getName() + ".neg", SDI);
+
+ SDI->replaceAllUsesWith(Res);
SDI->eraseFromParent();
- // Try to simplify our new urem.
- processUDivOrURem(URem, LVI);
+ // Try to simplify our new urem.
+ processUDivOrURem(URem, LVI);
return true;
}
/// See if LazyValueInfo's ability to exploit edge conditions or range
-/// information is sufficient to prove the signs of both operands of this SDiv.
-/// If this is the case, replace the SDiv with a UDiv. Even for local
+/// information is sufficient to prove the signs of both operands of this SDiv.
+/// If this is the case, replace the SDiv with a UDiv. Even for local
/// conditions, this can sometimes prove conditions instcombine can't by
/// exploiting range information.
static bool processSDiv(BinaryOperator *SDI, LazyValueInfo *LVI) {
- assert(SDI->getOpcode() == Instruction::SDiv);
- if (SDI->getType()->isVectorTy())
+ assert(SDI->getOpcode() == Instruction::SDiv);
+ if (SDI->getType()->isVectorTy())
return false;
- struct Operand {
- Value *V;
- Domain D;
- };
- std::array<Operand, 2> Ops;
-
- for (const auto I : zip(Ops, SDI->operands())) {
- Operand &Op = std::get<0>(I);
- Op.V = std::get<1>(I);
- Op.D = getDomain(Op.V, LVI, SDI);
- if (Op.D == Domain::Unknown)
- return false;
- }
-
- // We know domains of both of the operands!
+ struct Operand {
+ Value *V;
+ Domain D;
+ };
+ std::array<Operand, 2> Ops;
+
+ for (const auto I : zip(Ops, SDI->operands())) {
+ Operand &Op = std::get<0>(I);
+ Op.V = std::get<1>(I);
+ Op.D = getDomain(Op.V, LVI, SDI);
+ if (Op.D == Domain::Unknown)
+ return false;
+ }
+
+ // We know domains of both of the operands!
++NumSDivs;
-
- // We need operands to be non-negative, so negate each one that isn't.
- for (Operand &Op : Ops) {
- if (Op.D == Domain::NonNegative)
- continue;
- auto *BO =
- BinaryOperator::CreateNeg(Op.V, Op.V->getName() + ".nonneg", SDI);
- BO->setDebugLoc(SDI->getDebugLoc());
- Op.V = BO;
- }
-
- auto *UDiv =
- BinaryOperator::CreateUDiv(Ops[0].V, Ops[1].V, SDI->getName(), SDI);
- UDiv->setDebugLoc(SDI->getDebugLoc());
- UDiv->setIsExact(SDI->isExact());
-
- Value *Res = UDiv;
-
- // If the operands had two different domains, we need to negate the result.
- if (Ops[0].D != Ops[1].D)
- Res = BinaryOperator::CreateNeg(Res, Res->getName() + ".neg", SDI);
-
- SDI->replaceAllUsesWith(Res);
+
+ // We need operands to be non-negative, so negate each one that isn't.
+ for (Operand &Op : Ops) {
+ if (Op.D == Domain::NonNegative)
+ continue;
+ auto *BO =
+ BinaryOperator::CreateNeg(Op.V, Op.V->getName() + ".nonneg", SDI);
+ BO->setDebugLoc(SDI->getDebugLoc());
+ Op.V = BO;
+ }
+
+ auto *UDiv =
+ BinaryOperator::CreateUDiv(Ops[0].V, Ops[1].V, SDI->getName(), SDI);
+ UDiv->setDebugLoc(SDI->getDebugLoc());
+ UDiv->setIsExact(SDI->isExact());
+
+ Value *Res = UDiv;
+
+ // If the operands had two different domains, we need to negate the result.
+ if (Ops[0].D != Ops[1].D)
+ Res = BinaryOperator::CreateNeg(Res, Res->getName() + ".neg", SDI);
+
+ SDI->replaceAllUsesWith(Res);
SDI->eraseFromParent();
// Try to simplify our new udiv.
- processUDivOrURem(UDiv, LVI);
+ processUDivOrURem(UDiv, LVI);
return true;
}
-static bool processSDivOrSRem(BinaryOperator *Instr, LazyValueInfo *LVI) {
- assert(Instr->getOpcode() == Instruction::SDiv ||
- Instr->getOpcode() == Instruction::SRem);
- if (Instr->getType()->isVectorTy())
- return false;
-
- if (Instr->getOpcode() == Instruction::SDiv)
- if (processSDiv(Instr, LVI))
- return true;
-
- if (Instr->getOpcode() == Instruction::SRem)
- if (processSRem(Instr, LVI))
- return true;
-
- return narrowSDivOrSRem(Instr, LVI);
-}
-
+static bool processSDivOrSRem(BinaryOperator *Instr, LazyValueInfo *LVI) {
+ assert(Instr->getOpcode() == Instruction::SDiv ||
+ Instr->getOpcode() == Instruction::SRem);
+ if (Instr->getType()->isVectorTy())
+ return false;
+
+ if (Instr->getOpcode() == Instruction::SDiv)
+ if (processSDiv(Instr, LVI))
+ return true;
+
+ if (Instr->getOpcode() == Instruction::SRem)
+ if (processSRem(Instr, LVI))
+ return true;
+
+ return narrowSDivOrSRem(Instr, LVI);
+}
+
static bool processAShr(BinaryOperator *SDI, LazyValueInfo *LVI) {
if (SDI->getType()->isVectorTy())
return false;
- if (!isNonNegative(SDI->getOperand(0), LVI, SDI))
+ if (!isNonNegative(SDI->getOperand(0), LVI, SDI))
return false;
++NumAShrs;
@@ -827,7 +827,7 @@ static bool processSExt(SExtInst *SDI, LazyValueInfo *LVI) {
Value *Base = SDI->getOperand(0);
- if (!isNonNegative(Base, LVI, SDI))
+ if (!isNonNegative(Base, LVI, SDI))
return false;
++NumSExt;
@@ -858,8 +858,8 @@ static bool processBinOp(BinaryOperator *BinOp, LazyValueInfo *LVI) {
Value *LHS = BinOp->getOperand(0);
Value *RHS = BinOp->getOperand(1);
- ConstantRange LRange = LVI->getConstantRange(LHS, BinOp);
- ConstantRange RRange = LVI->getConstantRange(RHS, BinOp);
+ ConstantRange LRange = LVI->getConstantRange(LHS, BinOp);
+ ConstantRange RRange = LVI->getConstantRange(RHS, BinOp);
bool Changed = false;
bool NewNUW = false, NewNSW = false;
@@ -895,7 +895,7 @@ static bool processAnd(BinaryOperator *BinOp, LazyValueInfo *LVI) {
// We can only replace the AND with LHS based on range info if the range does
// not include undef.
ConstantRange LRange =
- LVI->getConstantRange(LHS, BinOp, /*UndefAllowed=*/false);
+ LVI->getConstantRange(LHS, BinOp, /*UndefAllowed=*/false);
if (!LRange.getUnsignedMax().ule(RHS->getValue()))
return false;
@@ -907,7 +907,7 @@ static bool processAnd(BinaryOperator *BinOp, LazyValueInfo *LVI) {
static Constant *getConstantAt(Value *V, Instruction *At, LazyValueInfo *LVI) {
- if (Constant *C = LVI->getConstant(V, At))
+ if (Constant *C = LVI->getConstant(V, At))
return C;
// TODO: The following really should be sunk inside LVI's core algorithm, or
@@ -962,7 +962,7 @@ static bool runImpl(Function &F, LazyValueInfo *LVI, DominatorTree *DT,
break;
case Instruction::SRem:
case Instruction::SDiv:
- BBChanged |= processSDivOrSRem(cast<BinaryOperator>(II), LVI);
+ BBChanged |= processSDivOrSRem(cast<BinaryOperator>(II), LVI);
break;
case Instruction::UDiv:
case Instruction::URem:
@@ -1031,18 +1031,18 @@ CorrelatedValuePropagationPass::run(Function &F, FunctionAnalysisManager &AM) {
bool Changed = runImpl(F, LVI, DT, getBestSimplifyQuery(AM, F));
PreservedAnalyses PA;
- if (!Changed) {
- PA = PreservedAnalyses::all();
- } else {
- PA.preserve<GlobalsAA>();
- PA.preserve<DominatorTreeAnalysis>();
- PA.preserve<LazyValueAnalysis>();
- }
-
- // Keeping LVI alive is expensive, both because it uses a lot of memory, and
- // because invalidating values in LVI is expensive. While CVP does preserve
- // LVI, we know that passes after JumpThreading+CVP will not need the result
- // of this analysis, so we forcefully discard it early.
- PA.abandon<LazyValueAnalysis>();
+ if (!Changed) {
+ PA = PreservedAnalyses::all();
+ } else {
+ PA.preserve<GlobalsAA>();
+ PA.preserve<DominatorTreeAnalysis>();
+ PA.preserve<LazyValueAnalysis>();
+ }
+
+ // Keeping LVI alive is expensive, both because it uses a lot of memory, and
+ // because invalidating values in LVI is expensive. While CVP does preserve
+ // LVI, we know that passes after JumpThreading+CVP will not need the result
+ // of this analysis, so we forcefully discard it early.
+ PA.abandon<LazyValueAnalysis>();
return PA;
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/DCE.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/DCE.cpp
index 5826d9dc96..d55adf7c2d 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/DCE.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/DCE.cpp
@@ -69,18 +69,18 @@ Pass *llvm::createRedundantDbgInstEliminationPass() {
return new RedundantDbgInstElimination();
}
-PreservedAnalyses
-RedundantDbgInstEliminationPass::run(Function &F, FunctionAnalysisManager &AM) {
- bool Changed = false;
- for (auto &BB : F)
- Changed |= RemoveRedundantDbgInstrs(&BB);
- if (!Changed)
- return PreservedAnalyses::all();
- PreservedAnalyses PA;
- PA.preserveSet<CFGAnalyses>();
- return PA;
-}
-
+PreservedAnalyses
+RedundantDbgInstEliminationPass::run(Function &F, FunctionAnalysisManager &AM) {
+ bool Changed = false;
+ for (auto &BB : F)
+ Changed |= RemoveRedundantDbgInstrs(&BB);
+ if (!Changed)
+ return PreservedAnalyses::all();
+ PreservedAnalyses PA;
+ PA.preserveSet<CFGAnalyses>();
+ return PA;
+}
+
//===--------------------------------------------------------------------===//
// DeadCodeElimination pass implementation
//
@@ -143,7 +143,7 @@ static bool eliminateDeadCode(Function &F, TargetLibraryInfo *TLI) {
}
PreservedAnalyses DCEPass::run(Function &F, FunctionAnalysisManager &AM) {
- if (!eliminateDeadCode(F, &AM.getResult<TargetLibraryAnalysis>(F)))
+ if (!eliminateDeadCode(F, &AM.getResult<TargetLibraryAnalysis>(F)))
return PreservedAnalyses::all();
PreservedAnalyses PA;
@@ -162,14 +162,14 @@ struct DCELegacyPass : public FunctionPass {
if (skipFunction(F))
return false;
- TargetLibraryInfo *TLI =
- &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
+ TargetLibraryInfo *TLI =
+ &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
return eliminateDeadCode(F, TLI);
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<TargetLibraryInfoWrapperPass>();
+ AU.addRequired<TargetLibraryInfoWrapperPass>();
AU.setPreservesCFG();
}
};
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/DeadStoreElimination.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/DeadStoreElimination.cpp
index e57b1d974b..2979225c60 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -87,10 +87,10 @@ STATISTIC(NumModifiedStores, "Number of stores modified");
STATISTIC(NumCFGChecks, "Number of stores modified");
STATISTIC(NumCFGTries, "Number of stores modified");
STATISTIC(NumCFGSuccess, "Number of stores modified");
-STATISTIC(NumGetDomMemoryDefPassed,
- "Number of times a valid candidate is returned from getDomMemoryDef");
-STATISTIC(NumDomMemDefChecks,
- "Number iterations check for reads in getDomMemoryDef");
+STATISTIC(NumGetDomMemoryDefPassed,
+ "Number of times a valid candidate is returned from getDomMemoryDef");
+STATISTIC(NumDomMemDefChecks,
+ "Number iterations check for reads in getDomMemoryDef");
DEBUG_COUNTER(MemorySSACounter, "dse-memoryssa",
"Controls which MemoryDefs are eliminated.");
@@ -106,42 +106,42 @@ EnablePartialStoreMerging("enable-dse-partial-store-merging",
cl::desc("Enable partial store merging in DSE"));
static cl::opt<bool>
- EnableMemorySSA("enable-dse-memoryssa", cl::init(true), cl::Hidden,
+ EnableMemorySSA("enable-dse-memoryssa", cl::init(true), cl::Hidden,
cl::desc("Use the new MemorySSA-backed DSE."));
static cl::opt<unsigned>
- MemorySSAScanLimit("dse-memoryssa-scanlimit", cl::init(150), cl::Hidden,
+ MemorySSAScanLimit("dse-memoryssa-scanlimit", cl::init(150), cl::Hidden,
cl::desc("The number of memory instructions to scan for "
"dead store elimination (default = 100)"));
-static cl::opt<unsigned> MemorySSAUpwardsStepLimit(
- "dse-memoryssa-walklimit", cl::init(90), cl::Hidden,
- cl::desc("The maximum number of steps while walking upwards to find "
- "MemoryDefs that may be killed (default = 90)"));
-
-static cl::opt<unsigned> MemorySSAPartialStoreLimit(
- "dse-memoryssa-partial-store-limit", cl::init(5), cl::Hidden,
- cl::desc("The maximum number candidates that only partially overwrite the "
- "killing MemoryDef to consider"
- " (default = 5)"));
-
+static cl::opt<unsigned> MemorySSAUpwardsStepLimit(
+ "dse-memoryssa-walklimit", cl::init(90), cl::Hidden,
+ cl::desc("The maximum number of steps while walking upwards to find "
+ "MemoryDefs that may be killed (default = 90)"));
+
+static cl::opt<unsigned> MemorySSAPartialStoreLimit(
+ "dse-memoryssa-partial-store-limit", cl::init(5), cl::Hidden,
+ cl::desc("The maximum number candidates that only partially overwrite the "
+ "killing MemoryDef to consider"
+ " (default = 5)"));
+
static cl::opt<unsigned> MemorySSADefsPerBlockLimit(
"dse-memoryssa-defs-per-block-limit", cl::init(5000), cl::Hidden,
cl::desc("The number of MemoryDefs we consider as candidates to eliminated "
"other stores per basic block (default = 5000)"));
-static cl::opt<unsigned> MemorySSASameBBStepCost(
- "dse-memoryssa-samebb-cost", cl::init(1), cl::Hidden,
- cl::desc(
- "The cost of a step in the same basic block as the killing MemoryDef"
- "(default = 1)"));
-
-static cl::opt<unsigned>
- MemorySSAOtherBBStepCost("dse-memoryssa-otherbb-cost", cl::init(5),
- cl::Hidden,
- cl::desc("The cost of a step in a different basic "
- "block than the killing MemoryDef"
- "(default = 5)"));
-
+static cl::opt<unsigned> MemorySSASameBBStepCost(
+ "dse-memoryssa-samebb-cost", cl::init(1), cl::Hidden,
+ cl::desc(
+ "The cost of a step in the same basic block as the killing MemoryDef"
+ "(default = 1)"));
+
+static cl::opt<unsigned>
+ MemorySSAOtherBBStepCost("dse-memoryssa-otherbb-cost", cl::init(5),
+ cl::Hidden,
+ cl::desc("The cost of a step in a different basic "
+ "block than the killing MemoryDef"
+ "(default = 5)"));
+
static cl::opt<unsigned> MemorySSAPathCheckLimit(
"dse-memoryssa-path-check-limit", cl::init(50), cl::Hidden,
cl::desc("The maximum number of blocks to check when trying to prove that "
@@ -229,13 +229,13 @@ static bool hasAnalyzableMemoryWrite(Instruction *I,
case Intrinsic::memset:
case Intrinsic::memmove:
case Intrinsic::memcpy:
- case Intrinsic::memcpy_inline:
+ case Intrinsic::memcpy_inline:
case Intrinsic::memcpy_element_unordered_atomic:
case Intrinsic::memmove_element_unordered_atomic:
case Intrinsic::memset_element_unordered_atomic:
case Intrinsic::init_trampoline:
case Intrinsic::lifetime_end:
- case Intrinsic::masked_store:
+ case Intrinsic::masked_store:
return true;
}
}
@@ -259,23 +259,23 @@ static bool hasAnalyzableMemoryWrite(Instruction *I,
/// Return a Location stored to by the specified instruction. If isRemovable
/// returns true, this function and getLocForRead completely describe the memory
/// operations for this instruction.
-static MemoryLocation getLocForWrite(Instruction *Inst,
- const TargetLibraryInfo &TLI) {
+static MemoryLocation getLocForWrite(Instruction *Inst,
+ const TargetLibraryInfo &TLI) {
if (StoreInst *SI = dyn_cast<StoreInst>(Inst))
return MemoryLocation::get(SI);
- // memcpy/memmove/memset.
- if (auto *MI = dyn_cast<AnyMemIntrinsic>(Inst))
- return MemoryLocation::getForDest(MI);
+ // memcpy/memmove/memset.
+ if (auto *MI = dyn_cast<AnyMemIntrinsic>(Inst))
+ return MemoryLocation::getForDest(MI);
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
switch (II->getIntrinsicID()) {
default:
return MemoryLocation(); // Unhandled intrinsic.
case Intrinsic::init_trampoline:
- return MemoryLocation::getAfter(II->getArgOperand(0));
- case Intrinsic::masked_store:
- return MemoryLocation::getForArgument(II, 1, TLI);
+ return MemoryLocation::getAfter(II->getArgOperand(0));
+ case Intrinsic::masked_store:
+ return MemoryLocation::getForArgument(II, 1, TLI);
case Intrinsic::lifetime_end: {
uint64_t Len = cast<ConstantInt>(II->getArgOperand(0))->getZExtValue();
return MemoryLocation(II->getArgOperand(1), Len);
@@ -285,7 +285,7 @@ static MemoryLocation getLocForWrite(Instruction *Inst,
if (auto *CB = dyn_cast<CallBase>(Inst))
// All the supported TLI functions so far happen to have dest as their
// first argument.
- return MemoryLocation::getAfter(CB->getArgOperand(0));
+ return MemoryLocation::getAfter(CB->getArgOperand(0));
return MemoryLocation();
}
@@ -322,13 +322,13 @@ static bool isRemovable(Instruction *I) {
case Intrinsic::memset:
case Intrinsic::memmove:
case Intrinsic::memcpy:
- case Intrinsic::memcpy_inline:
+ case Intrinsic::memcpy_inline:
// Don't remove volatile memory intrinsics.
return !cast<MemIntrinsic>(II)->isVolatile();
case Intrinsic::memcpy_element_unordered_atomic:
case Intrinsic::memmove_element_unordered_atomic:
case Intrinsic::memset_element_unordered_atomic:
- case Intrinsic::masked_store:
+ case Intrinsic::masked_store:
return true;
}
}
@@ -374,10 +374,10 @@ static bool isShortenableAtTheBeginning(Instruction *I) {
}
/// Return the pointer that is being written to.
-static Value *getStoredPointerOperand(Instruction *I,
- const TargetLibraryInfo &TLI) {
+static Value *getStoredPointerOperand(Instruction *I,
+ const TargetLibraryInfo &TLI) {
//TODO: factor this to reuse getLocForWrite
- MemoryLocation Loc = getLocForWrite(I, TLI);
+ MemoryLocation Loc = getLocForWrite(I, TLI);
assert(Loc.Ptr &&
"unable to find pointer written for analyzable instruction?");
// TODO: most APIs don't expect const Value *
@@ -403,59 +403,59 @@ enum OverwriteResult {
OW_Complete,
OW_End,
OW_PartialEarlierWithFullLater,
- OW_MaybePartial,
+ OW_MaybePartial,
OW_Unknown
};
} // end anonymous namespace
-/// Check if two instruction are masked stores that completely
-/// overwrite one another. More specifically, \p Later has to
-/// overwrite \p Earlier.
-template <typename AATy>
-static OverwriteResult isMaskedStoreOverwrite(const Instruction *Later,
- const Instruction *Earlier,
- AATy &AA) {
- const auto *IIL = dyn_cast<IntrinsicInst>(Later);
- const auto *IIE = dyn_cast<IntrinsicInst>(Earlier);
- if (IIL == nullptr || IIE == nullptr)
- return OW_Unknown;
- if (IIL->getIntrinsicID() != Intrinsic::masked_store ||
- IIE->getIntrinsicID() != Intrinsic::masked_store)
- return OW_Unknown;
- // Pointers.
- Value *LP = IIL->getArgOperand(1)->stripPointerCasts();
- Value *EP = IIE->getArgOperand(1)->stripPointerCasts();
- if (LP != EP && !AA.isMustAlias(LP, EP))
- return OW_Unknown;
- // Masks.
- // TODO: check that Later's mask is a superset of the Earlier's mask.
- if (IIL->getArgOperand(3) != IIE->getArgOperand(3))
- return OW_Unknown;
- return OW_Complete;
-}
-
-/// Return 'OW_Complete' if a store to the 'Later' location (by \p LaterI
-/// instruction) completely overwrites a store to the 'Earlier' location.
-/// (by \p EarlierI instruction).
-/// Return OW_MaybePartial if \p Later does not completely overwrite
-/// \p Earlier, but they both write to the same underlying object. In that
-/// case, use isPartialOverwrite to check if \p Later partially overwrites
-/// \p Earlier. Returns 'OW_Unknown' if nothing can be determined.
-template <typename AATy>
-static OverwriteResult
-isOverwrite(const Instruction *LaterI, const Instruction *EarlierI,
- const MemoryLocation &Later, const MemoryLocation &Earlier,
- const DataLayout &DL, const TargetLibraryInfo &TLI,
- int64_t &EarlierOff, int64_t &LaterOff, AATy &AA,
- const Function *F) {
+/// Check if two instruction are masked stores that completely
+/// overwrite one another. More specifically, \p Later has to
+/// overwrite \p Earlier.
+template <typename AATy>
+static OverwriteResult isMaskedStoreOverwrite(const Instruction *Later,
+ const Instruction *Earlier,
+ AATy &AA) {
+ const auto *IIL = dyn_cast<IntrinsicInst>(Later);
+ const auto *IIE = dyn_cast<IntrinsicInst>(Earlier);
+ if (IIL == nullptr || IIE == nullptr)
+ return OW_Unknown;
+ if (IIL->getIntrinsicID() != Intrinsic::masked_store ||
+ IIE->getIntrinsicID() != Intrinsic::masked_store)
+ return OW_Unknown;
+ // Pointers.
+ Value *LP = IIL->getArgOperand(1)->stripPointerCasts();
+ Value *EP = IIE->getArgOperand(1)->stripPointerCasts();
+ if (LP != EP && !AA.isMustAlias(LP, EP))
+ return OW_Unknown;
+ // Masks.
+ // TODO: check that Later's mask is a superset of the Earlier's mask.
+ if (IIL->getArgOperand(3) != IIE->getArgOperand(3))
+ return OW_Unknown;
+ return OW_Complete;
+}
+
+/// Return 'OW_Complete' if a store to the 'Later' location (by \p LaterI
+/// instruction) completely overwrites a store to the 'Earlier' location.
+/// (by \p EarlierI instruction).
+/// Return OW_MaybePartial if \p Later does not completely overwrite
+/// \p Earlier, but they both write to the same underlying object. In that
+/// case, use isPartialOverwrite to check if \p Later partially overwrites
+/// \p Earlier. Returns 'OW_Unknown' if nothing can be determined.
+template <typename AATy>
+static OverwriteResult
+isOverwrite(const Instruction *LaterI, const Instruction *EarlierI,
+ const MemoryLocation &Later, const MemoryLocation &Earlier,
+ const DataLayout &DL, const TargetLibraryInfo &TLI,
+ int64_t &EarlierOff, int64_t &LaterOff, AATy &AA,
+ const Function *F) {
// FIXME: Vet that this works for size upper-bounds. Seems unlikely that we'll
// get imprecise values here, though (except for unknown sizes).
- if (!Later.Size.isPrecise() || !Earlier.Size.isPrecise()) {
- // Masked stores have imprecise locations, but we can reason about them
- // to some extent.
- return isMaskedStoreOverwrite(LaterI, EarlierI, AA);
- }
+ if (!Later.Size.isPrecise() || !Earlier.Size.isPrecise()) {
+ // Masked stores have imprecise locations, but we can reason about them
+ // to some extent.
+ return isMaskedStoreOverwrite(LaterI, EarlierI, AA);
+ }
const uint64_t LaterSize = Later.Size.getValue();
const uint64_t EarlierSize = Earlier.Size.getValue();
@@ -474,7 +474,7 @@ isOverwrite(const Instruction *LaterI, const Instruction *EarlierI,
// Check to see if the later store is to the entire object (either a global,
// an alloca, or a byval/inalloca argument). If so, then it clearly
// overwrites any other store to the same object.
- const Value *UO1 = getUnderlyingObject(P1), *UO2 = getUnderlyingObject(P2);
+ const Value *UO1 = getUnderlyingObject(P1), *UO2 = getUnderlyingObject(P2);
// If we can't resolve the same pointers to the same object, then we can't
// analyze them at all.
@@ -499,59 +499,59 @@ isOverwrite(const Instruction *LaterI, const Instruction *EarlierI,
if (BP1 != BP2)
return OW_Unknown;
- // The later access completely overlaps the earlier store if and only if
- // both start and end of the earlier one is "inside" the later one:
- // |<->|--earlier--|<->|
- // |-------later-------|
- // Accesses may overlap if and only if start of one of them is "inside"
- // another one:
- // |<->|--earlier--|<----->|
- // |-------later-------|
- // OR
- // |----- earlier -----|
- // |<->|---later---|<----->|
+ // The later access completely overlaps the earlier store if and only if
+ // both start and end of the earlier one is "inside" the later one:
+ // |<->|--earlier--|<->|
+ // |-------later-------|
+ // Accesses may overlap if and only if start of one of them is "inside"
+ // another one:
+ // |<->|--earlier--|<----->|
+ // |-------later-------|
+ // OR
+ // |----- earlier -----|
+ // |<->|---later---|<----->|
//
// We have to be careful here as *Off is signed while *.Size is unsigned.
- // Check if the earlier access starts "not before" the later one.
- if (EarlierOff >= LaterOff) {
- // If the earlier access ends "not after" the later access then the earlier
- // one is completely overwritten by the later one.
- if (uint64_t(EarlierOff - LaterOff) + EarlierSize <= LaterSize)
- return OW_Complete;
- // If start of the earlier access is "before" end of the later access then
- // accesses overlap.
- else if ((uint64_t)(EarlierOff - LaterOff) < LaterSize)
- return OW_MaybePartial;
- }
- // If start of the later access is "before" end of the earlier access then
- // accesses overlap.
- else if ((uint64_t)(LaterOff - EarlierOff) < EarlierSize) {
- return OW_MaybePartial;
- }
-
- // Can reach here only if accesses are known not to overlap. There is no
- // dedicated code to indicate no overlap so signal "unknown".
- return OW_Unknown;
-}
-
-/// Return 'OW_Complete' if a store to the 'Later' location completely
-/// overwrites a store to the 'Earlier' location, 'OW_End' if the end of the
-/// 'Earlier' location is completely overwritten by 'Later', 'OW_Begin' if the
-/// beginning of the 'Earlier' location is overwritten by 'Later'.
-/// 'OW_PartialEarlierWithFullLater' means that an earlier (big) store was
-/// overwritten by a latter (smaller) store which doesn't write outside the big
-/// store's memory locations. Returns 'OW_Unknown' if nothing can be determined.
-/// NOTE: This function must only be called if both \p Later and \p Earlier
-/// write to the same underlying object with valid \p EarlierOff and \p
-/// LaterOff.
-static OverwriteResult isPartialOverwrite(const MemoryLocation &Later,
- const MemoryLocation &Earlier,
- int64_t EarlierOff, int64_t LaterOff,
- Instruction *DepWrite,
- InstOverlapIntervalsTy &IOL) {
- const uint64_t LaterSize = Later.Size.getValue();
- const uint64_t EarlierSize = Earlier.Size.getValue();
+ // Check if the earlier access starts "not before" the later one.
+ if (EarlierOff >= LaterOff) {
+ // If the earlier access ends "not after" the later access then the earlier
+ // one is completely overwritten by the later one.
+ if (uint64_t(EarlierOff - LaterOff) + EarlierSize <= LaterSize)
+ return OW_Complete;
+ // If start of the earlier access is "before" end of the later access then
+ // accesses overlap.
+ else if ((uint64_t)(EarlierOff - LaterOff) < LaterSize)
+ return OW_MaybePartial;
+ }
+ // If start of the later access is "before" end of the earlier access then
+ // accesses overlap.
+ else if ((uint64_t)(LaterOff - EarlierOff) < EarlierSize) {
+ return OW_MaybePartial;
+ }
+
+ // Can reach here only if accesses are known not to overlap. There is no
+ // dedicated code to indicate no overlap so signal "unknown".
+ return OW_Unknown;
+}
+
+/// Return 'OW_Complete' if a store to the 'Later' location completely
+/// overwrites a store to the 'Earlier' location, 'OW_End' if the end of the
+/// 'Earlier' location is completely overwritten by 'Later', 'OW_Begin' if the
+/// beginning of the 'Earlier' location is overwritten by 'Later'.
+/// 'OW_PartialEarlierWithFullLater' means that an earlier (big) store was
+/// overwritten by a latter (smaller) store which doesn't write outside the big
+/// store's memory locations. Returns 'OW_Unknown' if nothing can be determined.
+/// NOTE: This function must only be called if both \p Later and \p Earlier
+/// write to the same underlying object with valid \p EarlierOff and \p
+/// LaterOff.
+static OverwriteResult isPartialOverwrite(const MemoryLocation &Later,
+ const MemoryLocation &Earlier,
+ int64_t EarlierOff, int64_t LaterOff,
+ Instruction *DepWrite,
+ InstOverlapIntervalsTy &IOL) {
+ const uint64_t LaterSize = Later.Size.getValue();
+ const uint64_t EarlierSize = Earlier.Size.getValue();
// We may now overlap, although the overlap is not complete. There might also
// be other incomplete overlaps, and together, they might cover the complete
// earlier write.
@@ -718,10 +718,10 @@ static bool isPossibleSelfRead(Instruction *Inst,
/// modified between the first and the second instruction.
/// Precondition: Second instruction must be dominated by the first
/// instruction.
-template <typename AATy>
-static bool
-memoryIsNotModifiedBetween(Instruction *FirstI, Instruction *SecondI, AATy &AA,
- const DataLayout &DL, DominatorTree *DT) {
+template <typename AATy>
+static bool
+memoryIsNotModifiedBetween(Instruction *FirstI, Instruction *SecondI, AATy &AA,
+ const DataLayout &DL, DominatorTree *DT) {
// Do a backwards scan through the CFG from SecondI to FirstI. Look for
// instructions which can modify the memory location accessed by SecondI.
//
@@ -770,7 +770,7 @@ memoryIsNotModifiedBetween(Instruction *FirstI, Instruction *SecondI, AATy &AA,
for (; BI != EI; ++BI) {
Instruction *I = &*BI;
if (I->mayWriteToMemory() && I != SecondI)
- if (isModSet(AA.getModRefInfo(I, MemLoc.getWithNewPtr(Ptr))))
+ if (isModSet(AA.getModRefInfo(I, MemLoc.getWithNewPtr(Ptr))))
return false;
}
if (B != FirstBB) {
@@ -826,7 +826,7 @@ static bool handleFree(CallInst *F, AliasAnalysis *AA,
MapVector<Instruction *, bool> &ThrowableInst) {
bool MadeChange = false;
- MemoryLocation Loc = MemoryLocation::getAfter(F->getOperand(0));
+ MemoryLocation Loc = MemoryLocation::getAfter(F->getOperand(0));
SmallVector<BasicBlock *, 16> Blocks;
Blocks.push_back(F->getParent());
@@ -844,7 +844,7 @@ static bool handleFree(CallInst *F, AliasAnalysis *AA,
break;
Value *DepPointer =
- getUnderlyingObject(getStoredPointerOperand(Dependency, *TLI));
+ getUnderlyingObject(getStoredPointerOperand(Dependency, *TLI));
// Check for aliasing.
if (!AA->isMustAlias(F->getArgOperand(0), DepPointer))
@@ -884,7 +884,7 @@ static void removeAccessedObjects(const MemoryLocation &LoadedLoc,
const DataLayout &DL, AliasAnalysis *AA,
const TargetLibraryInfo *TLI,
const Function *F) {
- const Value *UnderlyingPointer = getUnderlyingObject(LoadedLoc.Ptr);
+ const Value *UnderlyingPointer = getUnderlyingObject(LoadedLoc.Ptr);
// A constant can't be in the dead pointer set.
if (isa<Constant>(UnderlyingPointer))
@@ -937,7 +937,7 @@ static bool handleEndBlock(BasicBlock &BB, AliasAnalysis *AA,
// Treat byval or inalloca arguments the same, stores to them are dead at the
// end of the function.
for (Argument &AI : BB.getParent()->args())
- if (AI.hasPassPointeeByValueCopyAttr())
+ if (AI.hasPassPointeeByValueCopyAttr())
DeadStackObjects.insert(&AI);
const DataLayout &DL = BB.getModule()->getDataLayout();
@@ -950,7 +950,7 @@ static bool handleEndBlock(BasicBlock &BB, AliasAnalysis *AA,
if (hasAnalyzableMemoryWrite(&*BBI, *TLI) && isRemovable(&*BBI)) {
// See through pointer-to-pointer bitcasts
SmallVector<const Value *, 4> Pointers;
- getUnderlyingObjects(getStoredPointerOperand(&*BBI, *TLI), Pointers);
+ getUnderlyingObjects(getStoredPointerOperand(&*BBI, *TLI), Pointers);
// Stores to stack values are valid candidates for removal.
bool AllDead = true;
@@ -1069,8 +1069,8 @@ static bool handleEndBlock(BasicBlock &BB, AliasAnalysis *AA,
}
static bool tryToShorten(Instruction *EarlierWrite, int64_t &EarlierOffset,
- uint64_t &EarlierSize, int64_t LaterOffset,
- uint64_t LaterSize, bool IsOverwriteEnd) {
+ uint64_t &EarlierSize, int64_t LaterOffset,
+ uint64_t LaterSize, bool IsOverwriteEnd) {
// TODO: base this on the target vector size so that if the earlier
// store was too small to get vector writes anyway then its likely
// a good idea to shorten it
@@ -1125,23 +1125,23 @@ static bool tryToShorten(Instruction *EarlierWrite, int64_t &EarlierOffset,
static bool tryToShortenEnd(Instruction *EarlierWrite,
OverlapIntervalsTy &IntervalMap,
- int64_t &EarlierStart, uint64_t &EarlierSize) {
+ int64_t &EarlierStart, uint64_t &EarlierSize) {
if (IntervalMap.empty() || !isShortenableAtTheEnd(EarlierWrite))
return false;
OverlapIntervalsTy::iterator OII = --IntervalMap.end();
int64_t LaterStart = OII->second;
- uint64_t LaterSize = OII->first - LaterStart;
-
- assert(OII->first - LaterStart >= 0 && "Size expected to be positive");
-
- if (LaterStart > EarlierStart &&
- // Note: "LaterStart - EarlierStart" is known to be positive due to
- // preceding check.
- (uint64_t)(LaterStart - EarlierStart) < EarlierSize &&
- // Note: "EarlierSize - (uint64_t)(LaterStart - EarlierStart)" is known to
- // be non negative due to preceding checks.
- LaterSize >= EarlierSize - (uint64_t)(LaterStart - EarlierStart)) {
+ uint64_t LaterSize = OII->first - LaterStart;
+
+ assert(OII->first - LaterStart >= 0 && "Size expected to be positive");
+
+ if (LaterStart > EarlierStart &&
+ // Note: "LaterStart - EarlierStart" is known to be positive due to
+ // preceding check.
+ (uint64_t)(LaterStart - EarlierStart) < EarlierSize &&
+ // Note: "EarlierSize - (uint64_t)(LaterStart - EarlierStart)" is known to
+ // be non negative due to preceding checks.
+ LaterSize >= EarlierSize - (uint64_t)(LaterStart - EarlierStart)) {
if (tryToShorten(EarlierWrite, EarlierStart, EarlierSize, LaterStart,
LaterSize, true)) {
IntervalMap.erase(OII);
@@ -1153,23 +1153,23 @@ static bool tryToShortenEnd(Instruction *EarlierWrite,
static bool tryToShortenBegin(Instruction *EarlierWrite,
OverlapIntervalsTy &IntervalMap,
- int64_t &EarlierStart, uint64_t &EarlierSize) {
+ int64_t &EarlierStart, uint64_t &EarlierSize) {
if (IntervalMap.empty() || !isShortenableAtTheBeginning(EarlierWrite))
return false;
OverlapIntervalsTy::iterator OII = IntervalMap.begin();
int64_t LaterStart = OII->second;
- uint64_t LaterSize = OII->first - LaterStart;
-
- assert(OII->first - LaterStart >= 0 && "Size expected to be positive");
-
- if (LaterStart <= EarlierStart &&
- // Note: "EarlierStart - LaterStart" is known to be non negative due to
- // preceding check.
- LaterSize > (uint64_t)(EarlierStart - LaterStart)) {
- // Note: "LaterSize - (uint64_t)(EarlierStart - LaterStart)" is known to be
- // positive due to preceding checks.
- assert(LaterSize - (uint64_t)(EarlierStart - LaterStart) < EarlierSize &&
+ uint64_t LaterSize = OII->first - LaterStart;
+
+ assert(OII->first - LaterStart >= 0 && "Size expected to be positive");
+
+ if (LaterStart <= EarlierStart &&
+ // Note: "EarlierStart - LaterStart" is known to be non negative due to
+ // preceding check.
+ LaterSize > (uint64_t)(EarlierStart - LaterStart)) {
+ // Note: "LaterSize - (uint64_t)(EarlierStart - LaterStart)" is known to be
+ // positive due to preceding checks.
+ assert(LaterSize - (uint64_t)(EarlierStart - LaterStart) < EarlierSize &&
"Should have been handled as OW_Complete");
if (tryToShorten(EarlierWrite, EarlierStart, EarlierSize, LaterStart,
LaterSize, false)) {
@@ -1180,18 +1180,18 @@ static bool tryToShortenBegin(Instruction *EarlierWrite,
return false;
}
-static bool removePartiallyOverlappedStores(const DataLayout &DL,
- InstOverlapIntervalsTy &IOL,
- const TargetLibraryInfo &TLI) {
+static bool removePartiallyOverlappedStores(const DataLayout &DL,
+ InstOverlapIntervalsTy &IOL,
+ const TargetLibraryInfo &TLI) {
bool Changed = false;
for (auto OI : IOL) {
Instruction *EarlierWrite = OI.first;
- MemoryLocation Loc = getLocForWrite(EarlierWrite, TLI);
+ MemoryLocation Loc = getLocForWrite(EarlierWrite, TLI);
assert(isRemovable(EarlierWrite) && "Expect only removable instruction");
const Value *Ptr = Loc.Ptr->stripPointerCasts();
int64_t EarlierStart = 0;
- uint64_t EarlierSize = Loc.Size.getValue();
+ uint64_t EarlierSize = Loc.Size.getValue();
GetPointerBaseWithConstantOffset(Ptr, EarlierStart, DL);
OverlapIntervalsTy &IntervalMap = OI.second;
Changed |=
@@ -1221,7 +1221,7 @@ static bool eliminateNoopStore(Instruction *Inst, BasicBlock::iterator &BBI,
if (LoadInst *DepLoad = dyn_cast<LoadInst>(SI->getValueOperand())) {
if (SI->getPointerOperand() == DepLoad->getPointerOperand() &&
isRemovable(SI) &&
- memoryIsNotModifiedBetween(DepLoad, SI, *AA, DL, DT)) {
+ memoryIsNotModifiedBetween(DepLoad, SI, *AA, DL, DT)) {
LLVM_DEBUG(
dbgs() << "DSE: Remove Store Of Load from same pointer:\n LOAD: "
@@ -1237,10 +1237,10 @@ static bool eliminateNoopStore(Instruction *Inst, BasicBlock::iterator &BBI,
Constant *StoredConstant = dyn_cast<Constant>(SI->getValueOperand());
if (StoredConstant && StoredConstant->isNullValue() && isRemovable(SI)) {
Instruction *UnderlyingPointer =
- dyn_cast<Instruction>(getUnderlyingObject(SI->getPointerOperand()));
+ dyn_cast<Instruction>(getUnderlyingObject(SI->getPointerOperand()));
if (UnderlyingPointer && isCallocLikeFn(UnderlyingPointer, TLI) &&
- memoryIsNotModifiedBetween(UnderlyingPointer, SI, *AA, DL, DT)) {
+ memoryIsNotModifiedBetween(UnderlyingPointer, SI, *AA, DL, DT)) {
LLVM_DEBUG(
dbgs() << "DSE: Remove null store to the calloc'ed object:\n DEAD: "
<< *Inst << "\n OBJECT: " << *UnderlyingPointer << '\n');
@@ -1253,10 +1253,10 @@ static bool eliminateNoopStore(Instruction *Inst, BasicBlock::iterator &BBI,
return false;
}
-template <typename AATy>
-static Constant *tryToMergePartialOverlappingStores(
- StoreInst *Earlier, StoreInst *Later, int64_t InstWriteOffset,
- int64_t DepWriteOffset, const DataLayout &DL, AATy &AA, DominatorTree *DT) {
+template <typename AATy>
+static Constant *tryToMergePartialOverlappingStores(
+ StoreInst *Earlier, StoreInst *Later, int64_t InstWriteOffset,
+ int64_t DepWriteOffset, const DataLayout &DL, AATy &AA, DominatorTree *DT) {
if (Earlier && isa<ConstantInt>(Earlier->getValueOperand()) &&
DL.typeSizeEqualsStoreSize(Earlier->getValueOperand()->getType()) &&
@@ -1347,7 +1347,7 @@ static bool eliminateDeadStores(BasicBlock &BB, AliasAnalysis *AA,
continue;
// Figure out what location is being stored to.
- MemoryLocation Loc = getLocForWrite(Inst, *TLI);
+ MemoryLocation Loc = getLocForWrite(Inst, *TLI);
// If we didn't get a useful location, fail.
if (!Loc.Ptr)
@@ -1371,7 +1371,7 @@ static bool eliminateDeadStores(BasicBlock &BB, AliasAnalysis *AA,
Instruction *DepWrite = InstDep.getInst();
if (!hasAnalyzableMemoryWrite(DepWrite, *TLI))
break;
- MemoryLocation DepLoc = getLocForWrite(DepWrite, *TLI);
+ MemoryLocation DepLoc = getLocForWrite(DepWrite, *TLI);
// If we didn't get a useful location, or if it isn't a size, bail out.
if (!DepLoc.Ptr)
break;
@@ -1391,7 +1391,7 @@ static bool eliminateDeadStores(BasicBlock &BB, AliasAnalysis *AA,
// to it is dead along the unwind edge. Otherwise, we need to preserve
// the store.
if (LastThrowing && DepWrite->comesBefore(LastThrowing)) {
- const Value *Underlying = getUnderlyingObject(DepLoc.Ptr);
+ const Value *Underlying = getUnderlyingObject(DepLoc.Ptr);
bool IsStoreDeadOnUnwind = isa<AllocaInst>(Underlying);
if (!IsStoreDeadOnUnwind) {
// We're looking for a call to an allocation function
@@ -1413,13 +1413,13 @@ static bool eliminateDeadStores(BasicBlock &BB, AliasAnalysis *AA,
if (isRemovable(DepWrite) &&
!isPossibleSelfRead(Inst, Loc, DepWrite, *TLI, *AA)) {
int64_t InstWriteOffset, DepWriteOffset;
- OverwriteResult OR = isOverwrite(Inst, DepWrite, Loc, DepLoc, DL, *TLI,
- DepWriteOffset, InstWriteOffset, *AA,
+ OverwriteResult OR = isOverwrite(Inst, DepWrite, Loc, DepLoc, DL, *TLI,
+ DepWriteOffset, InstWriteOffset, *AA,
BB.getParent());
- if (OR == OW_MaybePartial)
- OR = isPartialOverwrite(Loc, DepLoc, DepWriteOffset, InstWriteOffset,
- DepWrite, IOL);
-
+ if (OR == OW_MaybePartial)
+ OR = isPartialOverwrite(Loc, DepLoc, DepWriteOffset, InstWriteOffset,
+ DepWrite, IOL);
+
if (OR == OW_Complete) {
LLVM_DEBUG(dbgs() << "DSE: Remove Dead Store:\n DEAD: " << *DepWrite
<< "\n KILLER: " << *Inst << '\n');
@@ -1440,8 +1440,8 @@ static bool eliminateDeadStores(BasicBlock &BB, AliasAnalysis *AA,
"when partial-overwrite "
"tracking is enabled");
// The overwrite result is known, so these must be known, too.
- uint64_t EarlierSize = DepLoc.Size.getValue();
- uint64_t LaterSize = Loc.Size.getValue();
+ uint64_t EarlierSize = DepLoc.Size.getValue();
+ uint64_t LaterSize = Loc.Size.getValue();
bool IsOverwriteEnd = (OR == OW_End);
MadeChange |= tryToShorten(DepWrite, DepWriteOffset, EarlierSize,
InstWriteOffset, LaterSize, IsOverwriteEnd);
@@ -1450,7 +1450,7 @@ static bool eliminateDeadStores(BasicBlock &BB, AliasAnalysis *AA,
auto *Earlier = dyn_cast<StoreInst>(DepWrite);
auto *Later = dyn_cast<StoreInst>(Inst);
if (Constant *C = tryToMergePartialOverlappingStores(
- Earlier, Later, InstWriteOffset, DepWriteOffset, DL, *AA,
+ Earlier, Later, InstWriteOffset, DepWriteOffset, DL, *AA,
DT)) {
auto *SI = new StoreInst(
C, Earlier->getPointerOperand(), false, Earlier->getAlign(),
@@ -1497,7 +1497,7 @@ static bool eliminateDeadStores(BasicBlock &BB, AliasAnalysis *AA,
}
if (EnablePartialOverwriteTracking)
- MadeChange |= removePartiallyOverlappedStores(DL, IOL, *TLI);
+ MadeChange |= removePartiallyOverlappedStores(DL, IOL, *TLI);
// If this block ends in a return, unwind, or unreachable, all allocas are
// dead at its end, which means stores to them are also dead.
@@ -1531,21 +1531,21 @@ namespace {
// in between both MemoryDefs. A bit more concretely:
//
// For all MemoryDefs StartDef:
-// 1. Get the next dominating clobbering MemoryDef (EarlierAccess) by walking
+// 1. Get the next dominating clobbering MemoryDef (EarlierAccess) by walking
// upwards.
-// 2. Check that there are no reads between EarlierAccess and the StartDef by
-// checking all uses starting at EarlierAccess and walking until we see
-// StartDef.
-// 3. For each found CurrentDef, check that:
-// 1. There are no barrier instructions between CurrentDef and StartDef (like
+// 2. Check that there are no reads between EarlierAccess and the StartDef by
+// checking all uses starting at EarlierAccess and walking until we see
+// StartDef.
+// 3. For each found CurrentDef, check that:
+// 1. There are no barrier instructions between CurrentDef and StartDef (like
// throws or stores with ordering constraints).
-// 2. StartDef is executed whenever CurrentDef is executed.
-// 3. StartDef completely overwrites CurrentDef.
-// 4. Erase CurrentDef from the function and MemorySSA.
+// 2. StartDef is executed whenever CurrentDef is executed.
+// 3. StartDef completely overwrites CurrentDef.
+// 4. Erase CurrentDef from the function and MemorySSA.
-// Returns true if \p I is an intrisnic that does not read or write memory.
-bool isNoopIntrinsic(Instruction *I) {
- if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
+// Returns true if \p I is an intrisnic that does not read or write memory.
+bool isNoopIntrinsic(Instruction *I) {
+ if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
switch (II->getIntrinsicID()) {
case Intrinsic::lifetime_start:
case Intrinsic::lifetime_end:
@@ -1588,7 +1588,7 @@ bool canSkipDef(MemoryDef *D, bool DefVisibleToCaller) {
return true;
// Skip intrinsics that do not really read or modify memory.
- if (isNoopIntrinsic(D->getMemoryInst()))
+ if (isNoopIntrinsic(D->getMemoryInst()))
return true;
return false;
@@ -1597,21 +1597,21 @@ bool canSkipDef(MemoryDef *D, bool DefVisibleToCaller) {
struct DSEState {
Function &F;
AliasAnalysis &AA;
-
- /// The single BatchAA instance that is used to cache AA queries. It will
- /// not be invalidated over the whole run. This is safe, because:
- /// 1. Only memory writes are removed, so the alias cache for memory
- /// locations remains valid.
- /// 2. No new instructions are added (only instructions removed), so cached
- /// information for a deleted value cannot be accessed by a re-used new
- /// value pointer.
- BatchAAResults BatchAA;
-
+
+ /// The single BatchAA instance that is used to cache AA queries. It will
+ /// not be invalidated over the whole run. This is safe, because:
+ /// 1. Only memory writes are removed, so the alias cache for memory
+ /// locations remains valid.
+ /// 2. No new instructions are added (only instructions removed), so cached
+ /// information for a deleted value cannot be accessed by a re-used new
+ /// value pointer.
+ BatchAAResults BatchAA;
+
MemorySSA &MSSA;
DominatorTree &DT;
PostDominatorTree &PDT;
const TargetLibraryInfo &TLI;
- const DataLayout &DL;
+ const DataLayout &DL;
// All MemoryDefs that potentially could kill other MemDefs.
SmallVector<MemoryDef *, 64> MemDefs;
@@ -1619,11 +1619,11 @@ struct DSEState {
SmallPtrSet<MemoryAccess *, 4> SkipStores;
// Keep track of all of the objects that are invisible to the caller before
// the function returns.
- // SmallPtrSet<const Value *, 16> InvisibleToCallerBeforeRet;
- DenseMap<const Value *, bool> InvisibleToCallerBeforeRet;
+ // SmallPtrSet<const Value *, 16> InvisibleToCallerBeforeRet;
+ DenseMap<const Value *, bool> InvisibleToCallerBeforeRet;
// Keep track of all of the objects that are invisible to the caller after
// the function returns.
- DenseMap<const Value *, bool> InvisibleToCallerAfterRet;
+ DenseMap<const Value *, bool> InvisibleToCallerAfterRet;
// Keep track of blocks with throwing instructions not modeled in MemorySSA.
SmallPtrSet<BasicBlock *, 16> ThrowingBlocks;
// Post-order numbers for each basic block. Used to figure out if memory
@@ -1636,8 +1636,8 @@ struct DSEState {
DSEState(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, DominatorTree &DT,
PostDominatorTree &PDT, const TargetLibraryInfo &TLI)
- : F(F), AA(AA), BatchAA(AA), MSSA(MSSA), DT(DT), PDT(PDT), TLI(TLI),
- DL(F.getParent()->getDataLayout()) {}
+ : F(F), AA(AA), BatchAA(AA), MSSA(MSSA), DT(DT), PDT(PDT), TLI(TLI),
+ DL(F.getParent()->getDataLayout()) {}
static DSEState get(Function &F, AliasAnalysis &AA, MemorySSA &MSSA,
DominatorTree &DT, PostDominatorTree &PDT,
@@ -1663,48 +1663,48 @@ struct DSEState {
// Treat byval or inalloca arguments the same as Allocas, stores to them are
// dead at the end of the function.
for (Argument &AI : F.args())
- if (AI.hasPassPointeeByValueCopyAttr()) {
+ if (AI.hasPassPointeeByValueCopyAttr()) {
// For byval, the caller doesn't know the address of the allocation.
if (AI.hasByValAttr())
- State.InvisibleToCallerBeforeRet.insert({&AI, true});
- State.InvisibleToCallerAfterRet.insert({&AI, true});
+ State.InvisibleToCallerBeforeRet.insert({&AI, true});
+ State.InvisibleToCallerAfterRet.insert({&AI, true});
}
return State;
}
- bool isInvisibleToCallerAfterRet(const Value *V) {
- if (isa<AllocaInst>(V))
- return true;
- auto I = InvisibleToCallerAfterRet.insert({V, false});
- if (I.second) {
- if (!isInvisibleToCallerBeforeRet(V)) {
- I.first->second = false;
- } else {
- auto *Inst = dyn_cast<Instruction>(V);
- if (Inst && isAllocLikeFn(Inst, &TLI))
- I.first->second = !PointerMayBeCaptured(V, true, false);
- }
- }
- return I.first->second;
- }
-
- bool isInvisibleToCallerBeforeRet(const Value *V) {
- if (isa<AllocaInst>(V))
- return true;
- auto I = InvisibleToCallerBeforeRet.insert({V, false});
- if (I.second) {
- auto *Inst = dyn_cast<Instruction>(V);
- if (Inst && isAllocLikeFn(Inst, &TLI))
- // NOTE: This could be made more precise by PointerMayBeCapturedBefore
- // with the killing MemoryDef. But we refrain from doing so for now to
- // limit compile-time and this does not cause any changes to the number
- // of stores removed on a large test set in practice.
- I.first->second = !PointerMayBeCaptured(V, false, true);
- }
- return I.first->second;
- }
-
+ bool isInvisibleToCallerAfterRet(const Value *V) {
+ if (isa<AllocaInst>(V))
+ return true;
+ auto I = InvisibleToCallerAfterRet.insert({V, false});
+ if (I.second) {
+ if (!isInvisibleToCallerBeforeRet(V)) {
+ I.first->second = false;
+ } else {
+ auto *Inst = dyn_cast<Instruction>(V);
+ if (Inst && isAllocLikeFn(Inst, &TLI))
+ I.first->second = !PointerMayBeCaptured(V, true, false);
+ }
+ }
+ return I.first->second;
+ }
+
+ bool isInvisibleToCallerBeforeRet(const Value *V) {
+ if (isa<AllocaInst>(V))
+ return true;
+ auto I = InvisibleToCallerBeforeRet.insert({V, false});
+ if (I.second) {
+ auto *Inst = dyn_cast<Instruction>(V);
+ if (Inst && isAllocLikeFn(Inst, &TLI))
+ // NOTE: This could be made more precise by PointerMayBeCapturedBefore
+ // with the killing MemoryDef. But we refrain from doing so for now to
+ // limit compile-time and this does not cause any changes to the number
+ // of stores removed on a large test set in practice.
+ I.first->second = !PointerMayBeCaptured(V, false, true);
+ }
+ return I.first->second;
+ }
+
Optional<MemoryLocation> getLocForWriteEx(Instruction *I) const {
if (!I->mayWriteToMemory())
return None;
@@ -1713,11 +1713,11 @@ struct DSEState {
return {MemoryLocation::getForDest(MTI)};
if (auto *CB = dyn_cast<CallBase>(I)) {
- // If the functions may write to memory we do not know about, bail out.
- if (!CB->onlyAccessesArgMemory() &&
- !CB->onlyAccessesInaccessibleMemOrArgMem())
- return None;
-
+ // If the functions may write to memory we do not know about, bail out.
+ if (!CB->onlyAccessesArgMemory() &&
+ !CB->onlyAccessesInaccessibleMemOrArgMem())
+ return None;
+
LibFunc LF;
if (TLI.getLibFunc(*CB, LF) && TLI.has(LF)) {
switch (LF) {
@@ -1725,29 +1725,29 @@ struct DSEState {
case LibFunc_strncpy:
case LibFunc_strcat:
case LibFunc_strncat:
- return {MemoryLocation::getAfter(CB->getArgOperand(0))};
+ return {MemoryLocation::getAfter(CB->getArgOperand(0))};
default:
break;
}
}
- switch (CB->getIntrinsicID()) {
- case Intrinsic::init_trampoline:
- return {MemoryLocation::getAfter(CB->getArgOperand(0))};
- case Intrinsic::masked_store:
- return {MemoryLocation::getForArgument(CB, 1, TLI)};
- default:
- break;
- }
+ switch (CB->getIntrinsicID()) {
+ case Intrinsic::init_trampoline:
+ return {MemoryLocation::getAfter(CB->getArgOperand(0))};
+ case Intrinsic::masked_store:
+ return {MemoryLocation::getForArgument(CB, 1, TLI)};
+ default:
+ break;
+ }
return None;
}
return MemoryLocation::getOrNone(I);
}
- /// Returns true if \p UseInst completely overwrites \p DefLoc
- /// (stored by \p DefInst).
- bool isCompleteOverwrite(const MemoryLocation &DefLoc, Instruction *DefInst,
- Instruction *UseInst) {
+ /// Returns true if \p UseInst completely overwrites \p DefLoc
+ /// (stored by \p DefInst).
+ bool isCompleteOverwrite(const MemoryLocation &DefLoc, Instruction *DefInst,
+ Instruction *UseInst) {
// UseInst has a MemoryDef associated in MemorySSA. It's possible for a
// MemoryDef to not write to memory, e.g. a volatile load is modeled as a
// MemoryDef.
@@ -1759,10 +1759,10 @@ struct DSEState {
return false;
int64_t InstWriteOffset, DepWriteOffset;
- if (auto CC = getLocForWriteEx(UseInst))
- return isOverwrite(UseInst, DefInst, *CC, DefLoc, DL, TLI, DepWriteOffset,
- InstWriteOffset, BatchAA, &F) == OW_Complete;
- return false;
+ if (auto CC = getLocForWriteEx(UseInst))
+ return isOverwrite(UseInst, DefInst, *CC, DefLoc, DL, TLI, DepWriteOffset,
+ InstWriteOffset, BatchAA, &F) == OW_Complete;
+ return false;
}
/// Returns true if \p Def is not read before returning from the function.
@@ -1793,12 +1793,12 @@ struct DSEState {
}
MemoryAccess *UseAccess = WorkList[I];
- // Simply adding the users of MemoryPhi to the worklist is not enough,
- // because we might miss read clobbers in different iterations of a loop,
- // for example.
- // TODO: Add support for phi translation to handle the loop case.
- if (isa<MemoryPhi>(UseAccess))
- return false;
+ // Simply adding the users of MemoryPhi to the worklist is not enough,
+ // because we might miss read clobbers in different iterations of a loop,
+ // for example.
+ // TODO: Add support for phi translation to handle the loop case.
+ if (isa<MemoryPhi>(UseAccess))
+ return false;
// TODO: Checking for aliasing is expensive. Consider reducing the amount
// of times this is called and/or caching it.
@@ -1827,8 +1827,8 @@ struct DSEState {
if (auto *CB = dyn_cast<CallBase>(I)) {
if (isFreeCall(I, &TLI))
- return {std::make_pair(MemoryLocation::getAfter(CB->getArgOperand(0)),
- true)};
+ return {std::make_pair(MemoryLocation::getAfter(CB->getArgOperand(0)),
+ true)};
}
return None;
@@ -1842,10 +1842,10 @@ struct DSEState {
isFreeCall(I, &TLI);
}
- /// Returns true if \p MaybeTerm is a memory terminator for \p Loc from
- /// instruction \p AccessI.
- bool isMemTerminator(const MemoryLocation &Loc, Instruction *AccessI,
- Instruction *MaybeTerm) {
+ /// Returns true if \p MaybeTerm is a memory terminator for \p Loc from
+ /// instruction \p AccessI.
+ bool isMemTerminator(const MemoryLocation &Loc, Instruction *AccessI,
+ Instruction *MaybeTerm) {
Optional<std::pair<MemoryLocation, bool>> MaybeTermLoc =
getLocForTerminator(MaybeTerm);
@@ -1854,31 +1854,31 @@ struct DSEState {
// If the terminator is a free-like call, all accesses to the underlying
// object can be considered terminated.
- if (getUnderlyingObject(Loc.Ptr) !=
- getUnderlyingObject(MaybeTermLoc->first.Ptr))
- return false;
-
- auto TermLoc = MaybeTermLoc->first;
+ if (getUnderlyingObject(Loc.Ptr) !=
+ getUnderlyingObject(MaybeTermLoc->first.Ptr))
+ return false;
+
+ auto TermLoc = MaybeTermLoc->first;
if (MaybeTermLoc->second) {
- const Value *LocUO = getUnderlyingObject(Loc.Ptr);
- return BatchAA.isMustAlias(TermLoc.Ptr, LocUO);
+ const Value *LocUO = getUnderlyingObject(Loc.Ptr);
+ return BatchAA.isMustAlias(TermLoc.Ptr, LocUO);
}
- int64_t InstWriteOffset, DepWriteOffset;
- return isOverwrite(MaybeTerm, AccessI, TermLoc, Loc, DL, TLI,
- DepWriteOffset, InstWriteOffset, BatchAA,
- &F) == OW_Complete;
+ int64_t InstWriteOffset, DepWriteOffset;
+ return isOverwrite(MaybeTerm, AccessI, TermLoc, Loc, DL, TLI,
+ DepWriteOffset, InstWriteOffset, BatchAA,
+ &F) == OW_Complete;
}
// Returns true if \p Use may read from \p DefLoc.
- bool isReadClobber(const MemoryLocation &DefLoc, Instruction *UseInst) {
- if (isNoopIntrinsic(UseInst))
- return false;
-
- // Monotonic or weaker atomic stores can be re-ordered and do not need to be
- // treated as read clobber.
- if (auto SI = dyn_cast<StoreInst>(UseInst))
- return isStrongerThan(SI->getOrdering(), AtomicOrdering::Monotonic);
-
+ bool isReadClobber(const MemoryLocation &DefLoc, Instruction *UseInst) {
+ if (isNoopIntrinsic(UseInst))
+ return false;
+
+ // Monotonic or weaker atomic stores can be re-ordered and do not need to be
+ // treated as read clobber.
+ if (auto SI = dyn_cast<StoreInst>(UseInst))
+ return isStrongerThan(SI->getOrdering(), AtomicOrdering::Monotonic);
+
if (!UseInst->mayReadFromMemory())
return false;
@@ -1886,246 +1886,246 @@ struct DSEState {
if (CB->onlyAccessesInaccessibleMemory())
return false;
- // NOTE: For calls, the number of stores removed could be slightly improved
- // by using AA.callCapturesBefore(UseInst, DefLoc, &DT), but that showed to
- // be expensive compared to the benefits in practice. For now, avoid more
- // expensive analysis to limit compile-time.
- return isRefSet(BatchAA.getModRefInfo(UseInst, DefLoc));
+ // NOTE: For calls, the number of stores removed could be slightly improved
+ // by using AA.callCapturesBefore(UseInst, DefLoc, &DT), but that showed to
+ // be expensive compared to the benefits in practice. For now, avoid more
+ // expensive analysis to limit compile-time.
+ return isRefSet(BatchAA.getModRefInfo(UseInst, DefLoc));
}
- /// Returns true if \p Ptr is guaranteed to be loop invariant for any possible
- /// loop. In particular, this guarantees that it only references a single
- /// MemoryLocation during execution of the containing function.
- bool IsGuaranteedLoopInvariant(Value *Ptr) {
- auto IsGuaranteedLoopInvariantBase = [this](Value *Ptr) {
- Ptr = Ptr->stripPointerCasts();
- if (auto *I = dyn_cast<Instruction>(Ptr)) {
- if (isa<AllocaInst>(Ptr))
- return true;
-
- if (isAllocLikeFn(I, &TLI))
- return true;
-
- return false;
- }
- return true;
- };
-
- Ptr = Ptr->stripPointerCasts();
- if (auto *GEP = dyn_cast<GEPOperator>(Ptr)) {
- return IsGuaranteedLoopInvariantBase(GEP->getPointerOperand()) &&
- GEP->hasAllConstantIndices();
- }
- return IsGuaranteedLoopInvariantBase(Ptr);
- }
-
- // Find a MemoryDef writing to \p DefLoc and dominating \p StartAccess, with
- // no read access between them or on any other path to a function exit block
- // if \p DefLoc is not accessible after the function returns. If there is no
- // such MemoryDef, return None. The returned value may not (completely)
- // overwrite \p DefLoc. Currently we bail out when we encounter an aliasing
- // MemoryUse (read).
+ /// Returns true if \p Ptr is guaranteed to be loop invariant for any possible
+ /// loop. In particular, this guarantees that it only references a single
+ /// MemoryLocation during execution of the containing function.
+ bool IsGuaranteedLoopInvariant(Value *Ptr) {
+ auto IsGuaranteedLoopInvariantBase = [this](Value *Ptr) {
+ Ptr = Ptr->stripPointerCasts();
+ if (auto *I = dyn_cast<Instruction>(Ptr)) {
+ if (isa<AllocaInst>(Ptr))
+ return true;
+
+ if (isAllocLikeFn(I, &TLI))
+ return true;
+
+ return false;
+ }
+ return true;
+ };
+
+ Ptr = Ptr->stripPointerCasts();
+ if (auto *GEP = dyn_cast<GEPOperator>(Ptr)) {
+ return IsGuaranteedLoopInvariantBase(GEP->getPointerOperand()) &&
+ GEP->hasAllConstantIndices();
+ }
+ return IsGuaranteedLoopInvariantBase(Ptr);
+ }
+
+ // Find a MemoryDef writing to \p DefLoc and dominating \p StartAccess, with
+ // no read access between them or on any other path to a function exit block
+ // if \p DefLoc is not accessible after the function returns. If there is no
+ // such MemoryDef, return None. The returned value may not (completely)
+ // overwrite \p DefLoc. Currently we bail out when we encounter an aliasing
+ // MemoryUse (read).
Optional<MemoryAccess *>
- getDomMemoryDef(MemoryDef *KillingDef, MemoryAccess *StartAccess,
- const MemoryLocation &DefLoc, const Value *DefUO,
- unsigned &ScanLimit, unsigned &WalkerStepLimit,
- bool IsMemTerm, unsigned &PartialLimit) {
- if (ScanLimit == 0 || WalkerStepLimit == 0) {
- LLVM_DEBUG(dbgs() << "\n ... hit scan limit\n");
- return None;
- }
-
- MemoryAccess *Current = StartAccess;
- Instruction *KillingI = KillingDef->getMemoryInst();
+ getDomMemoryDef(MemoryDef *KillingDef, MemoryAccess *StartAccess,
+ const MemoryLocation &DefLoc, const Value *DefUO,
+ unsigned &ScanLimit, unsigned &WalkerStepLimit,
+ bool IsMemTerm, unsigned &PartialLimit) {
+ if (ScanLimit == 0 || WalkerStepLimit == 0) {
+ LLVM_DEBUG(dbgs() << "\n ... hit scan limit\n");
+ return None;
+ }
+
+ MemoryAccess *Current = StartAccess;
+ Instruction *KillingI = KillingDef->getMemoryInst();
bool StepAgain;
- LLVM_DEBUG(dbgs() << " trying to get dominating access\n");
-
- // Find the next clobbering Mod access for DefLoc, starting at StartAccess.
- Optional<MemoryLocation> CurrentLoc;
+ LLVM_DEBUG(dbgs() << " trying to get dominating access\n");
+
+ // Find the next clobbering Mod access for DefLoc, starting at StartAccess.
+ Optional<MemoryLocation> CurrentLoc;
do {
StepAgain = false;
- LLVM_DEBUG({
- dbgs() << " visiting " << *Current;
- if (!MSSA.isLiveOnEntryDef(Current) && isa<MemoryUseOrDef>(Current))
- dbgs() << " (" << *cast<MemoryUseOrDef>(Current)->getMemoryInst()
- << ")";
- dbgs() << "\n";
- });
-
+ LLVM_DEBUG({
+ dbgs() << " visiting " << *Current;
+ if (!MSSA.isLiveOnEntryDef(Current) && isa<MemoryUseOrDef>(Current))
+ dbgs() << " (" << *cast<MemoryUseOrDef>(Current)->getMemoryInst()
+ << ")";
+ dbgs() << "\n";
+ });
+
// Reached TOP.
- if (MSSA.isLiveOnEntryDef(Current)) {
- LLVM_DEBUG(dbgs() << " ... found LiveOnEntryDef\n");
+ if (MSSA.isLiveOnEntryDef(Current)) {
+ LLVM_DEBUG(dbgs() << " ... found LiveOnEntryDef\n");
return None;
- }
-
- // Cost of a step. Accesses in the same block are more likely to be valid
- // candidates for elimination, hence consider them cheaper.
- unsigned StepCost = KillingDef->getBlock() == Current->getBlock()
- ? MemorySSASameBBStepCost
- : MemorySSAOtherBBStepCost;
- if (WalkerStepLimit <= StepCost) {
- LLVM_DEBUG(dbgs() << " ... hit walker step limit\n");
- return None;
- }
- WalkerStepLimit -= StepCost;
-
- // Return for MemoryPhis. They cannot be eliminated directly and the
- // caller is responsible for traversing them.
+ }
+
+ // Cost of a step. Accesses in the same block are more likely to be valid
+ // candidates for elimination, hence consider them cheaper.
+ unsigned StepCost = KillingDef->getBlock() == Current->getBlock()
+ ? MemorySSASameBBStepCost
+ : MemorySSAOtherBBStepCost;
+ if (WalkerStepLimit <= StepCost) {
+ LLVM_DEBUG(dbgs() << " ... hit walker step limit\n");
+ return None;
+ }
+ WalkerStepLimit -= StepCost;
+
+ // Return for MemoryPhis. They cannot be eliminated directly and the
+ // caller is responsible for traversing them.
if (isa<MemoryPhi>(Current)) {
- LLVM_DEBUG(dbgs() << " ... found MemoryPhi\n");
- return Current;
+ LLVM_DEBUG(dbgs() << " ... found MemoryPhi\n");
+ return Current;
+ }
+
+ // Below, check if CurrentDef is a valid candidate to be eliminated by
+ // KillingDef. If it is not, check the next candidate.
+ MemoryDef *CurrentDef = cast<MemoryDef>(Current);
+ Instruction *CurrentI = CurrentDef->getMemoryInst();
+
+ if (canSkipDef(CurrentDef, !isInvisibleToCallerBeforeRet(DefUO))) {
+ StepAgain = true;
+ Current = CurrentDef->getDefiningAccess();
+ continue;
+ }
+
+ // Before we try to remove anything, check for any extra throwing
+ // instructions that block us from DSEing
+ if (mayThrowBetween(KillingI, CurrentI, DefUO)) {
+ LLVM_DEBUG(dbgs() << " ... skip, may throw!\n");
+ return None;
+ }
+
+ // Check for anything that looks like it will be a barrier to further
+ // removal
+ if (isDSEBarrier(DefUO, CurrentI)) {
+ LLVM_DEBUG(dbgs() << " ... skip, barrier\n");
+ return None;
}
-
- // Below, check if CurrentDef is a valid candidate to be eliminated by
- // KillingDef. If it is not, check the next candidate.
- MemoryDef *CurrentDef = cast<MemoryDef>(Current);
- Instruction *CurrentI = CurrentDef->getMemoryInst();
-
- if (canSkipDef(CurrentDef, !isInvisibleToCallerBeforeRet(DefUO))) {
- StepAgain = true;
- Current = CurrentDef->getDefiningAccess();
- continue;
- }
-
- // Before we try to remove anything, check for any extra throwing
- // instructions that block us from DSEing
- if (mayThrowBetween(KillingI, CurrentI, DefUO)) {
- LLVM_DEBUG(dbgs() << " ... skip, may throw!\n");
+
+ // If Current is known to be on path that reads DefLoc or is a read
+ // clobber, bail out, as the path is not profitable. We skip this check
+ // for intrinsic calls, because the code knows how to handle memcpy
+ // intrinsics.
+ if (!isa<IntrinsicInst>(CurrentI) && isReadClobber(DefLoc, CurrentI))
+ return None;
+
+ // Quick check if there are direct uses that are read-clobbers.
+ if (any_of(Current->uses(), [this, &DefLoc, StartAccess](Use &U) {
+ if (auto *UseOrDef = dyn_cast<MemoryUseOrDef>(U.getUser()))
+ return !MSSA.dominates(StartAccess, UseOrDef) &&
+ isReadClobber(DefLoc, UseOrDef->getMemoryInst());
+ return false;
+ })) {
+ LLVM_DEBUG(dbgs() << " ... found a read clobber\n");
return None;
- }
-
- // Check for anything that looks like it will be a barrier to further
- // removal
- if (isDSEBarrier(DefUO, CurrentI)) {
- LLVM_DEBUG(dbgs() << " ... skip, barrier\n");
- return None;
- }
-
- // If Current is known to be on path that reads DefLoc or is a read
- // clobber, bail out, as the path is not profitable. We skip this check
- // for intrinsic calls, because the code knows how to handle memcpy
- // intrinsics.
- if (!isa<IntrinsicInst>(CurrentI) && isReadClobber(DefLoc, CurrentI))
- return None;
-
- // Quick check if there are direct uses that are read-clobbers.
- if (any_of(Current->uses(), [this, &DefLoc, StartAccess](Use &U) {
- if (auto *UseOrDef = dyn_cast<MemoryUseOrDef>(U.getUser()))
- return !MSSA.dominates(StartAccess, UseOrDef) &&
- isReadClobber(DefLoc, UseOrDef->getMemoryInst());
- return false;
- })) {
- LLVM_DEBUG(dbgs() << " ... found a read clobber\n");
- return None;
- }
-
- // If Current cannot be analyzed or is not removable, check the next
- // candidate.
- if (!hasAnalyzableMemoryWrite(CurrentI, TLI) || !isRemovable(CurrentI)) {
+ }
+
+ // If Current cannot be analyzed or is not removable, check the next
+ // candidate.
+ if (!hasAnalyzableMemoryWrite(CurrentI, TLI) || !isRemovable(CurrentI)) {
StepAgain = true;
- Current = CurrentDef->getDefiningAccess();
- continue;
+ Current = CurrentDef->getDefiningAccess();
+ continue;
}
- // If Current does not have an analyzable write location, skip it
- CurrentLoc = getLocForWriteEx(CurrentI);
- if (!CurrentLoc) {
- StepAgain = true;
- Current = CurrentDef->getDefiningAccess();
- continue;
- }
-
- // AliasAnalysis does not account for loops. Limit elimination to
- // candidates for which we can guarantee they always store to the same
- // memory location and not multiple locations in a loop.
- if (Current->getBlock() != KillingDef->getBlock() &&
- !IsGuaranteedLoopInvariant(const_cast<Value *>(CurrentLoc->Ptr))) {
- StepAgain = true;
- Current = CurrentDef->getDefiningAccess();
- WalkerStepLimit -= 1;
- continue;
- }
-
- if (IsMemTerm) {
- // If the killing def is a memory terminator (e.g. lifetime.end), check
- // the next candidate if the current Current does not write the same
- // underlying object as the terminator.
- if (!isMemTerminator(*CurrentLoc, CurrentI, KillingI)) {
- StepAgain = true;
- Current = CurrentDef->getDefiningAccess();
- }
- continue;
- } else {
- int64_t InstWriteOffset, DepWriteOffset;
- auto OR = isOverwrite(KillingI, CurrentI, DefLoc, *CurrentLoc, DL, TLI,
- DepWriteOffset, InstWriteOffset, BatchAA, &F);
- // If Current does not write to the same object as KillingDef, check
- // the next candidate.
- if (OR == OW_Unknown) {
- StepAgain = true;
- Current = CurrentDef->getDefiningAccess();
- } else if (OR == OW_MaybePartial) {
- // If KillingDef only partially overwrites Current, check the next
- // candidate if the partial step limit is exceeded. This aggressively
- // limits the number of candidates for partial store elimination,
- // which are less likely to be removable in the end.
- if (PartialLimit <= 1) {
- StepAgain = true;
- Current = CurrentDef->getDefiningAccess();
- WalkerStepLimit -= 1;
- continue;
- }
- PartialLimit -= 1;
- }
- }
+ // If Current does not have an analyzable write location, skip it
+ CurrentLoc = getLocForWriteEx(CurrentI);
+ if (!CurrentLoc) {
+ StepAgain = true;
+ Current = CurrentDef->getDefiningAccess();
+ continue;
+ }
+
+ // AliasAnalysis does not account for loops. Limit elimination to
+ // candidates for which we can guarantee they always store to the same
+ // memory location and not multiple locations in a loop.
+ if (Current->getBlock() != KillingDef->getBlock() &&
+ !IsGuaranteedLoopInvariant(const_cast<Value *>(CurrentLoc->Ptr))) {
+ StepAgain = true;
+ Current = CurrentDef->getDefiningAccess();
+ WalkerStepLimit -= 1;
+ continue;
+ }
+
+ if (IsMemTerm) {
+ // If the killing def is a memory terminator (e.g. lifetime.end), check
+ // the next candidate if the current Current does not write the same
+ // underlying object as the terminator.
+ if (!isMemTerminator(*CurrentLoc, CurrentI, KillingI)) {
+ StepAgain = true;
+ Current = CurrentDef->getDefiningAccess();
+ }
+ continue;
+ } else {
+ int64_t InstWriteOffset, DepWriteOffset;
+ auto OR = isOverwrite(KillingI, CurrentI, DefLoc, *CurrentLoc, DL, TLI,
+ DepWriteOffset, InstWriteOffset, BatchAA, &F);
+ // If Current does not write to the same object as KillingDef, check
+ // the next candidate.
+ if (OR == OW_Unknown) {
+ StepAgain = true;
+ Current = CurrentDef->getDefiningAccess();
+ } else if (OR == OW_MaybePartial) {
+ // If KillingDef only partially overwrites Current, check the next
+ // candidate if the partial step limit is exceeded. This aggressively
+ // limits the number of candidates for partial store elimination,
+ // which are less likely to be removable in the end.
+ if (PartialLimit <= 1) {
+ StepAgain = true;
+ Current = CurrentDef->getDefiningAccess();
+ WalkerStepLimit -= 1;
+ continue;
+ }
+ PartialLimit -= 1;
+ }
+ }
} while (StepAgain);
// Accesses to objects accessible after the function returns can only be
// eliminated if the access is killed along all paths to the exit. Collect
// the blocks with killing (=completely overwriting MemoryDefs) and check if
- // they cover all paths from EarlierAccess to any function exit.
- SmallPtrSet<Instruction *, 16> KillingDefs;
- KillingDefs.insert(KillingDef->getMemoryInst());
- MemoryAccess *EarlierAccess = Current;
- Instruction *EarlierMemInst =
- cast<MemoryDef>(EarlierAccess)->getMemoryInst();
- LLVM_DEBUG(dbgs() << " Checking for reads of " << *EarlierAccess << " ("
- << *EarlierMemInst << ")\n");
+ // they cover all paths from EarlierAccess to any function exit.
+ SmallPtrSet<Instruction *, 16> KillingDefs;
+ KillingDefs.insert(KillingDef->getMemoryInst());
+ MemoryAccess *EarlierAccess = Current;
+ Instruction *EarlierMemInst =
+ cast<MemoryDef>(EarlierAccess)->getMemoryInst();
+ LLVM_DEBUG(dbgs() << " Checking for reads of " << *EarlierAccess << " ("
+ << *EarlierMemInst << ")\n");
SmallSetVector<MemoryAccess *, 32> WorkList;
auto PushMemUses = [&WorkList](MemoryAccess *Acc) {
for (Use &U : Acc->uses())
WorkList.insert(cast<MemoryAccess>(U.getUser()));
};
- PushMemUses(EarlierAccess);
-
- // Optimistically collect all accesses for reads. If we do not find any
- // read clobbers, add them to the cache.
- SmallPtrSet<MemoryAccess *, 16> KnownNoReads;
- if (!EarlierMemInst->mayReadFromMemory())
- KnownNoReads.insert(EarlierAccess);
- // Check if EarlierDef may be read.
+ PushMemUses(EarlierAccess);
+
+ // Optimistically collect all accesses for reads. If we do not find any
+ // read clobbers, add them to the cache.
+ SmallPtrSet<MemoryAccess *, 16> KnownNoReads;
+ if (!EarlierMemInst->mayReadFromMemory())
+ KnownNoReads.insert(EarlierAccess);
+ // Check if EarlierDef may be read.
for (unsigned I = 0; I < WorkList.size(); I++) {
MemoryAccess *UseAccess = WorkList[I];
LLVM_DEBUG(dbgs() << " " << *UseAccess);
- // Bail out if the number of accesses to check exceeds the scan limit.
- if (ScanLimit < (WorkList.size() - I)) {
+ // Bail out if the number of accesses to check exceeds the scan limit.
+ if (ScanLimit < (WorkList.size() - I)) {
LLVM_DEBUG(dbgs() << "\n ... hit scan limit\n");
return None;
}
- --ScanLimit;
- NumDomMemDefChecks++;
- KnownNoReads.insert(UseAccess);
+ --ScanLimit;
+ NumDomMemDefChecks++;
+ KnownNoReads.insert(UseAccess);
if (isa<MemoryPhi>(UseAccess)) {
- if (any_of(KillingDefs, [this, UseAccess](Instruction *KI) {
- return DT.properlyDominates(KI->getParent(),
- UseAccess->getBlock());
- })) {
- LLVM_DEBUG(dbgs() << " ... skipping, dominated by killing block\n");
- continue;
- }
+ if (any_of(KillingDefs, [this, UseAccess](Instruction *KI) {
+ return DT.properlyDominates(KI->getParent(),
+ UseAccess->getBlock());
+ })) {
+ LLVM_DEBUG(dbgs() << " ... skipping, dominated by killing block\n");
+ continue;
+ }
LLVM_DEBUG(dbgs() << "\n ... adding PHI uses\n");
PushMemUses(UseAccess);
continue;
@@ -2134,45 +2134,45 @@ struct DSEState {
Instruction *UseInst = cast<MemoryUseOrDef>(UseAccess)->getMemoryInst();
LLVM_DEBUG(dbgs() << " (" << *UseInst << ")\n");
- if (any_of(KillingDefs, [this, UseInst](Instruction *KI) {
- return DT.dominates(KI, UseInst);
- })) {
- LLVM_DEBUG(dbgs() << " ... skipping, dominated by killing def\n");
+ if (any_of(KillingDefs, [this, UseInst](Instruction *KI) {
+ return DT.dominates(KI, UseInst);
+ })) {
+ LLVM_DEBUG(dbgs() << " ... skipping, dominated by killing def\n");
continue;
}
// A memory terminator kills all preceeding MemoryDefs and all succeeding
// MemoryAccesses. We do not have to check it's users.
- if (isMemTerminator(*CurrentLoc, EarlierMemInst, UseInst)) {
- LLVM_DEBUG(
- dbgs()
- << " ... skipping, memterminator invalidates following accesses\n");
+ if (isMemTerminator(*CurrentLoc, EarlierMemInst, UseInst)) {
+ LLVM_DEBUG(
+ dbgs()
+ << " ... skipping, memterminator invalidates following accesses\n");
continue;
- }
-
- if (isNoopIntrinsic(cast<MemoryUseOrDef>(UseAccess)->getMemoryInst())) {
- LLVM_DEBUG(dbgs() << " ... adding uses of intrinsic\n");
- PushMemUses(UseAccess);
- continue;
- }
-
- if (UseInst->mayThrow() && !isInvisibleToCallerBeforeRet(DefUO)) {
- LLVM_DEBUG(dbgs() << " ... found throwing instruction\n");
- return None;
- }
-
+ }
+
+ if (isNoopIntrinsic(cast<MemoryUseOrDef>(UseAccess)->getMemoryInst())) {
+ LLVM_DEBUG(dbgs() << " ... adding uses of intrinsic\n");
+ PushMemUses(UseAccess);
+ continue;
+ }
+
+ if (UseInst->mayThrow() && !isInvisibleToCallerBeforeRet(DefUO)) {
+ LLVM_DEBUG(dbgs() << " ... found throwing instruction\n");
+ return None;
+ }
+
// Uses which may read the original MemoryDef mean we cannot eliminate the
// original MD. Stop walk.
- if (isReadClobber(*CurrentLoc, UseInst)) {
+ if (isReadClobber(*CurrentLoc, UseInst)) {
LLVM_DEBUG(dbgs() << " ... found read clobber\n");
return None;
}
- // For the KillingDef and EarlierAccess we only have to check if it reads
- // the memory location.
+ // For the KillingDef and EarlierAccess we only have to check if it reads
+ // the memory location.
// TODO: It would probably be better to check for self-reads before
// calling the function.
- if (KillingDef == UseAccess || EarlierAccess == UseAccess) {
+ if (KillingDef == UseAccess || EarlierAccess == UseAccess) {
LLVM_DEBUG(dbgs() << " ... skipping killing def/dom access\n");
continue;
}
@@ -2181,23 +2181,23 @@ struct DSEState {
// the original location. Otherwise we have to check uses of *all*
// MemoryDefs we discover, including non-aliasing ones. Otherwise we might
// miss cases like the following
- // 1 = Def(LoE) ; <----- EarlierDef stores [0,1]
+ // 1 = Def(LoE) ; <----- EarlierDef stores [0,1]
// 2 = Def(1) ; (2, 1) = NoAlias, stores [2,3]
// Use(2) ; MayAlias 2 *and* 1, loads [0, 3].
// (The Use points to the *first* Def it may alias)
// 3 = Def(1) ; <---- Current (3, 2) = NoAlias, (3,1) = MayAlias,
// stores [0,1]
if (MemoryDef *UseDef = dyn_cast<MemoryDef>(UseAccess)) {
- if (isCompleteOverwrite(*CurrentLoc, EarlierMemInst, UseInst)) {
- if (!isInvisibleToCallerAfterRet(DefUO) &&
- UseAccess != EarlierAccess) {
+ if (isCompleteOverwrite(*CurrentLoc, EarlierMemInst, UseInst)) {
+ if (!isInvisibleToCallerAfterRet(DefUO) &&
+ UseAccess != EarlierAccess) {
BasicBlock *MaybeKillingBlock = UseInst->getParent();
if (PostOrderNumbers.find(MaybeKillingBlock)->second <
- PostOrderNumbers.find(EarlierAccess->getBlock())->second) {
+ PostOrderNumbers.find(EarlierAccess->getBlock())->second) {
- LLVM_DEBUG(dbgs()
- << " ... found killing def " << *UseInst << "\n");
- KillingDefs.insert(UseInst);
+ LLVM_DEBUG(dbgs()
+ << " ... found killing def " << *UseInst << "\n");
+ KillingDefs.insert(UseInst);
}
}
} else
@@ -2206,15 +2206,15 @@ struct DSEState {
}
// For accesses to locations visible after the function returns, make sure
- // that the location is killed (=overwritten) along all paths from
- // EarlierAccess to the exit.
- if (!isInvisibleToCallerAfterRet(DefUO)) {
- SmallPtrSet<BasicBlock *, 16> KillingBlocks;
- for (Instruction *KD : KillingDefs)
- KillingBlocks.insert(KD->getParent());
+ // that the location is killed (=overwritten) along all paths from
+ // EarlierAccess to the exit.
+ if (!isInvisibleToCallerAfterRet(DefUO)) {
+ SmallPtrSet<BasicBlock *, 16> KillingBlocks;
+ for (Instruction *KD : KillingDefs)
+ KillingBlocks.insert(KD->getParent());
assert(!KillingBlocks.empty() &&
"Expected at least a single killing block");
-
+
// Find the common post-dominator of all killing blocks.
BasicBlock *CommonPred = *KillingBlocks.begin();
for (auto I = std::next(KillingBlocks.begin()), E = KillingBlocks.end();
@@ -2225,17 +2225,17 @@ struct DSEState {
}
// If CommonPred is in the set of killing blocks, just check if it
- // post-dominates EarlierAccess.
+ // post-dominates EarlierAccess.
if (KillingBlocks.count(CommonPred)) {
- if (PDT.dominates(CommonPred, EarlierAccess->getBlock()))
- return {EarlierAccess};
+ if (PDT.dominates(CommonPred, EarlierAccess->getBlock()))
+ return {EarlierAccess};
return None;
}
- // If the common post-dominator does not post-dominate EarlierAccess,
- // there is a path from EarlierAccess to an exit not going through a
- // killing block.
- if (PDT.dominates(CommonPred, EarlierAccess->getBlock())) {
+ // If the common post-dominator does not post-dominate EarlierAccess,
+ // there is a path from EarlierAccess to an exit not going through a
+ // killing block.
+ if (PDT.dominates(CommonPred, EarlierAccess->getBlock())) {
SetVector<BasicBlock *> WorkList;
// If CommonPred is null, there are multiple exits from the function.
@@ -2248,17 +2248,17 @@ struct DSEState {
NumCFGTries++;
// Check if all paths starting from an exit node go through one of the
- // killing blocks before reaching EarlierAccess.
+ // killing blocks before reaching EarlierAccess.
for (unsigned I = 0; I < WorkList.size(); I++) {
NumCFGChecks++;
BasicBlock *Current = WorkList[I];
if (KillingBlocks.count(Current))
continue;
- if (Current == EarlierAccess->getBlock())
+ if (Current == EarlierAccess->getBlock())
return None;
- // EarlierAccess is reachable from the entry, so we don't have to
- // explore unreachable blocks further.
+ // EarlierAccess is reachable from the entry, so we don't have to
+ // explore unreachable blocks further.
if (!DT.isReachableFromEntry(Current))
continue;
@@ -2269,14 +2269,14 @@ struct DSEState {
return None;
}
NumCFGSuccess++;
- return {EarlierAccess};
+ return {EarlierAccess};
}
return None;
}
- // No aliasing MemoryUses of EarlierAccess found, EarlierAccess is
- // potentially dead.
- return {EarlierAccess};
+ // No aliasing MemoryUses of EarlierAccess found, EarlierAccess is
+ // potentially dead.
+ return {EarlierAccess};
}
// Delete dead memory defs
@@ -2321,11 +2321,11 @@ struct DSEState {
// checks extra maythrows (those that aren't MemoryDef's). MemoryDef that may
// throw are handled during the walk from one def to the next.
bool mayThrowBetween(Instruction *SI, Instruction *NI,
- const Value *SILocUnd) {
+ const Value *SILocUnd) {
// First see if we can ignore it by using the fact that SI is an
// alloca/alloca like object that is not visible to the caller during
// execution of the function.
- if (SILocUnd && isInvisibleToCallerBeforeRet(SILocUnd))
+ if (SILocUnd && isInvisibleToCallerBeforeRet(SILocUnd))
return false;
if (SI->getParent() == NI->getParent())
@@ -2338,10 +2338,10 @@ struct DSEState {
// * A memory instruction that may throw and \p SI accesses a non-stack
// object.
// * Atomic stores stronger that monotonic.
- bool isDSEBarrier(const Value *SILocUnd, Instruction *NI) {
+ bool isDSEBarrier(const Value *SILocUnd, Instruction *NI) {
// If NI may throw it acts as a barrier, unless we are to an alloca/alloca
// like object that does not escape.
- if (NI->mayThrow() && !isInvisibleToCallerBeforeRet(SILocUnd))
+ if (NI->mayThrow() && !isInvisibleToCallerBeforeRet(SILocUnd))
return true;
// If NI is an atomic load/store stronger than monotonic, do not try to
@@ -2351,11 +2351,11 @@ struct DSEState {
return isStrongerThanMonotonic(LI->getOrdering());
if (auto *SI = dyn_cast<StoreInst>(NI))
return isStrongerThanMonotonic(SI->getOrdering());
- if (auto *ARMW = dyn_cast<AtomicRMWInst>(NI))
- return isStrongerThanMonotonic(ARMW->getOrdering());
- if (auto *CmpXchg = dyn_cast<AtomicCmpXchgInst>(NI))
- return isStrongerThanMonotonic(CmpXchg->getSuccessOrdering()) ||
- isStrongerThanMonotonic(CmpXchg->getFailureOrdering());
+ if (auto *ARMW = dyn_cast<AtomicRMWInst>(NI))
+ return isStrongerThanMonotonic(ARMW->getOrdering());
+ if (auto *CmpXchg = dyn_cast<AtomicCmpXchgInst>(NI))
+ return isStrongerThanMonotonic(CmpXchg->getSuccessOrdering()) ||
+ isStrongerThanMonotonic(CmpXchg->getFailureOrdering());
llvm_unreachable("other instructions should be skipped in MemorySSA");
}
return false;
@@ -2370,31 +2370,31 @@ struct DSEState {
<< "Trying to eliminate MemoryDefs at the end of the function\n");
for (int I = MemDefs.size() - 1; I >= 0; I--) {
MemoryDef *Def = MemDefs[I];
- if (SkipStores.contains(Def) || !isRemovable(Def->getMemoryInst()))
+ if (SkipStores.contains(Def) || !isRemovable(Def->getMemoryInst()))
+ continue;
+
+ Instruction *DefI = Def->getMemoryInst();
+ SmallVector<const Value *, 4> Pointers;
+ auto DefLoc = getLocForWriteEx(DefI);
+ if (!DefLoc)
+ continue;
+
+ // NOTE: Currently eliminating writes at the end of a function is limited
+ // to MemoryDefs with a single underlying object, to save compile-time. In
+ // practice it appears the case with multiple underlying objects is very
+ // uncommon. If it turns out to be important, we can use
+ // getUnderlyingObjects here instead.
+ const Value *UO = getUnderlyingObject(DefLoc->Ptr);
+ if (!UO || !isInvisibleToCallerAfterRet(UO))
continue;
- Instruction *DefI = Def->getMemoryInst();
- SmallVector<const Value *, 4> Pointers;
- auto DefLoc = getLocForWriteEx(DefI);
- if (!DefLoc)
- continue;
-
- // NOTE: Currently eliminating writes at the end of a function is limited
- // to MemoryDefs with a single underlying object, to save compile-time. In
- // practice it appears the case with multiple underlying objects is very
- // uncommon. If it turns out to be important, we can use
- // getUnderlyingObjects here instead.
- const Value *UO = getUnderlyingObject(DefLoc->Ptr);
- if (!UO || !isInvisibleToCallerAfterRet(UO))
- continue;
-
if (isWriteAtEndOfFunction(Def)) {
// See through pointer-to-pointer bitcasts
LLVM_DEBUG(dbgs() << " ... MemoryDef is not accessed until the end "
"of the function\n");
- deleteDeadInstruction(DefI);
- ++NumFastStores;
- MadeChange = true;
+ deleteDeadInstruction(DefI);
+ ++NumFastStores;
+ MadeChange = true;
}
}
return MadeChange;
@@ -2402,53 +2402,53 @@ struct DSEState {
/// \returns true if \p Def is a no-op store, either because it
/// directly stores back a loaded value or stores zero to a calloced object.
- bool storeIsNoop(MemoryDef *Def, const MemoryLocation &DefLoc,
- const Value *DefUO) {
+ bool storeIsNoop(MemoryDef *Def, const MemoryLocation &DefLoc,
+ const Value *DefUO) {
StoreInst *Store = dyn_cast<StoreInst>(Def->getMemoryInst());
if (!Store)
return false;
if (auto *LoadI = dyn_cast<LoadInst>(Store->getOperand(0))) {
if (LoadI->getPointerOperand() == Store->getOperand(1)) {
- // Get the defining access for the load.
+ // Get the defining access for the load.
auto *LoadAccess = MSSA.getMemoryAccess(LoadI)->getDefiningAccess();
- // Fast path: the defining accesses are the same.
- if (LoadAccess == Def->getDefiningAccess())
- return true;
-
- // Look through phi accesses. Recursively scan all phi accesses by
- // adding them to a worklist. Bail when we run into a memory def that
- // does not match LoadAccess.
- SetVector<MemoryAccess *> ToCheck;
- MemoryAccess *Current =
- MSSA.getWalker()->getClobberingMemoryAccess(Def);
- // We don't want to bail when we run into the store memory def. But,
- // the phi access may point to it. So, pretend like we've already
- // checked it.
- ToCheck.insert(Def);
- ToCheck.insert(Current);
- // Start at current (1) to simulate already having checked Def.
- for (unsigned I = 1; I < ToCheck.size(); ++I) {
- Current = ToCheck[I];
- if (auto PhiAccess = dyn_cast<MemoryPhi>(Current)) {
- // Check all the operands.
- for (auto &Use : PhiAccess->incoming_values())
- ToCheck.insert(cast<MemoryAccess>(&Use));
- continue;
- }
-
- // If we found a memory def, bail. This happens when we have an
- // unrelated write in between an otherwise noop store.
- assert(isa<MemoryDef>(Current) &&
- "Only MemoryDefs should reach here.");
- // TODO: Skip no alias MemoryDefs that have no aliasing reads.
- // We are searching for the definition of the store's destination.
- // So, if that is the same definition as the load, then this is a
- // noop. Otherwise, fail.
- if (LoadAccess != Current)
- return false;
- }
- return true;
+ // Fast path: the defining accesses are the same.
+ if (LoadAccess == Def->getDefiningAccess())
+ return true;
+
+ // Look through phi accesses. Recursively scan all phi accesses by
+ // adding them to a worklist. Bail when we run into a memory def that
+ // does not match LoadAccess.
+ SetVector<MemoryAccess *> ToCheck;
+ MemoryAccess *Current =
+ MSSA.getWalker()->getClobberingMemoryAccess(Def);
+ // We don't want to bail when we run into the store memory def. But,
+ // the phi access may point to it. So, pretend like we've already
+ // checked it.
+ ToCheck.insert(Def);
+ ToCheck.insert(Current);
+ // Start at current (1) to simulate already having checked Def.
+ for (unsigned I = 1; I < ToCheck.size(); ++I) {
+ Current = ToCheck[I];
+ if (auto PhiAccess = dyn_cast<MemoryPhi>(Current)) {
+ // Check all the operands.
+ for (auto &Use : PhiAccess->incoming_values())
+ ToCheck.insert(cast<MemoryAccess>(&Use));
+ continue;
+ }
+
+ // If we found a memory def, bail. This happens when we have an
+ // unrelated write in between an otherwise noop store.
+ assert(isa<MemoryDef>(Current) &&
+ "Only MemoryDefs should reach here.");
+ // TODO: Skip no alias MemoryDefs that have no aliasing reads.
+ // We are searching for the definition of the store's destination.
+ // So, if that is the same definition as the load, then this is a
+ // noop. Otherwise, fail.
+ if (LoadAccess != Current)
+ return false;
+ }
+ return true;
}
}
@@ -2482,7 +2482,7 @@ bool eliminateDeadStoresMemorySSA(Function &F, AliasAnalysis &AA,
continue;
Instruction *SI = KillingDef->getMemoryInst();
- Optional<MemoryLocation> MaybeSILoc;
+ Optional<MemoryLocation> MaybeSILoc;
if (State.isMemTerminatorInst(SI))
MaybeSILoc = State.getLocForTerminator(SI).map(
[](const std::pair<MemoryLocation, bool> &P) { return P.first; });
@@ -2496,23 +2496,23 @@ bool eliminateDeadStoresMemorySSA(Function &F, AliasAnalysis &AA,
}
MemoryLocation SILoc = *MaybeSILoc;
assert(SILoc.Ptr && "SILoc should not be null");
- const Value *SILocUnd = getUnderlyingObject(SILoc.Ptr);
+ const Value *SILocUnd = getUnderlyingObject(SILoc.Ptr);
MemoryAccess *Current = KillingDef;
LLVM_DEBUG(dbgs() << "Trying to eliminate MemoryDefs killed by "
<< *KillingDef << " (" << *SI << ")\n");
- unsigned ScanLimit = MemorySSAScanLimit;
- unsigned WalkerStepLimit = MemorySSAUpwardsStepLimit;
- unsigned PartialLimit = MemorySSAPartialStoreLimit;
+ unsigned ScanLimit = MemorySSAScanLimit;
+ unsigned WalkerStepLimit = MemorySSAUpwardsStepLimit;
+ unsigned PartialLimit = MemorySSAPartialStoreLimit;
// Worklist of MemoryAccesses that may be killed by KillingDef.
SetVector<MemoryAccess *> ToCheck;
- if (SILocUnd)
- ToCheck.insert(KillingDef->getDefiningAccess());
-
- bool Shortend = false;
- bool IsMemTerm = State.isMemTerminatorInst(SI);
+ if (SILocUnd)
+ ToCheck.insert(KillingDef->getDefiningAccess());
+
+ bool Shortend = false;
+ bool IsMemTerm = State.isMemTerminatorInst(SI);
// Check if MemoryAccesses in the worklist are killed by KillingDef.
for (unsigned I = 0; I < ToCheck.size(); I++) {
Current = ToCheck[I];
@@ -2520,22 +2520,22 @@ bool eliminateDeadStoresMemorySSA(Function &F, AliasAnalysis &AA,
continue;
Optional<MemoryAccess *> Next = State.getDomMemoryDef(
- KillingDef, Current, SILoc, SILocUnd, ScanLimit, WalkerStepLimit,
- IsMemTerm, PartialLimit);
+ KillingDef, Current, SILoc, SILocUnd, ScanLimit, WalkerStepLimit,
+ IsMemTerm, PartialLimit);
if (!Next) {
LLVM_DEBUG(dbgs() << " finished walk\n");
continue;
}
- MemoryAccess *EarlierAccess = *Next;
- LLVM_DEBUG(dbgs() << " Checking if we can kill " << *EarlierAccess);
- if (isa<MemoryPhi>(EarlierAccess)) {
+ MemoryAccess *EarlierAccess = *Next;
+ LLVM_DEBUG(dbgs() << " Checking if we can kill " << *EarlierAccess);
+ if (isa<MemoryPhi>(EarlierAccess)) {
LLVM_DEBUG(dbgs() << "\n ... adding incoming values to worklist\n");
- for (Value *V : cast<MemoryPhi>(EarlierAccess)->incoming_values()) {
+ for (Value *V : cast<MemoryPhi>(EarlierAccess)->incoming_values()) {
MemoryAccess *IncomingAccess = cast<MemoryAccess>(V);
BasicBlock *IncomingBlock = IncomingAccess->getBlock();
- BasicBlock *PhiBlock = EarlierAccess->getBlock();
+ BasicBlock *PhiBlock = EarlierAccess->getBlock();
// We only consider incoming MemoryAccesses that come before the
// MemoryPhi. Otherwise we could discover candidates that do not
@@ -2546,20 +2546,20 @@ bool eliminateDeadStoresMemorySSA(Function &F, AliasAnalysis &AA,
}
continue;
}
- auto *NextDef = cast<MemoryDef>(EarlierAccess);
+ auto *NextDef = cast<MemoryDef>(EarlierAccess);
Instruction *NI = NextDef->getMemoryInst();
LLVM_DEBUG(dbgs() << " (" << *NI << ")\n");
ToCheck.insert(NextDef->getDefiningAccess());
- NumGetDomMemoryDefPassed++;
+ NumGetDomMemoryDefPassed++;
if (!DebugCounter::shouldExecute(MemorySSACounter))
continue;
MemoryLocation NILoc = *State.getLocForWriteEx(NI);
- if (IsMemTerm) {
- const Value *NIUnd = getUnderlyingObject(NILoc.Ptr);
- if (SILocUnd != NIUnd)
+ if (IsMemTerm) {
+ const Value *NIUnd = getUnderlyingObject(NILoc.Ptr);
+ if (SILocUnd != NIUnd)
continue;
LLVM_DEBUG(dbgs() << "DSE: Remove Dead Store:\n DEAD: " << *NI
<< "\n KILLER: " << *SI << '\n');
@@ -2569,43 +2569,43 @@ bool eliminateDeadStoresMemorySSA(Function &F, AliasAnalysis &AA,
} else {
// Check if NI overwrites SI.
int64_t InstWriteOffset, DepWriteOffset;
- OverwriteResult OR =
- isOverwrite(SI, NI, SILoc, NILoc, State.DL, TLI, DepWriteOffset,
- InstWriteOffset, State.BatchAA, &F);
- if (OR == OW_MaybePartial) {
- auto Iter = State.IOLs.insert(
- std::make_pair<BasicBlock *, InstOverlapIntervalsTy>(
- NI->getParent(), InstOverlapIntervalsTy()));
- auto &IOL = Iter.first->second;
- OR = isPartialOverwrite(SILoc, NILoc, DepWriteOffset, InstWriteOffset,
- NI, IOL);
- }
+ OverwriteResult OR =
+ isOverwrite(SI, NI, SILoc, NILoc, State.DL, TLI, DepWriteOffset,
+ InstWriteOffset, State.BatchAA, &F);
+ if (OR == OW_MaybePartial) {
+ auto Iter = State.IOLs.insert(
+ std::make_pair<BasicBlock *, InstOverlapIntervalsTy>(
+ NI->getParent(), InstOverlapIntervalsTy()));
+ auto &IOL = Iter.first->second;
+ OR = isPartialOverwrite(SILoc, NILoc, DepWriteOffset, InstWriteOffset,
+ NI, IOL);
+ }
if (EnablePartialStoreMerging && OR == OW_PartialEarlierWithFullLater) {
auto *Earlier = dyn_cast<StoreInst>(NI);
auto *Later = dyn_cast<StoreInst>(SI);
- // We are re-using tryToMergePartialOverlappingStores, which requires
- // Earlier to domiante Later.
- // TODO: implement tryToMergeParialOverlappingStores using MemorySSA.
- if (Earlier && Later && DT.dominates(Earlier, Later)) {
- if (Constant *Merged = tryToMergePartialOverlappingStores(
- Earlier, Later, InstWriteOffset, DepWriteOffset, State.DL,
- State.BatchAA, &DT)) {
-
- // Update stored value of earlier store to merged constant.
- Earlier->setOperand(0, Merged);
- ++NumModifiedStores;
- MadeChange = true;
-
- Shortend = true;
- // Remove later store and remove any outstanding overlap intervals
- // for the updated store.
- State.deleteDeadInstruction(Later);
- auto I = State.IOLs.find(Earlier->getParent());
- if (I != State.IOLs.end())
- I->second.erase(Earlier);
- break;
- }
+ // We are re-using tryToMergePartialOverlappingStores, which requires
+ // Earlier to domiante Later.
+ // TODO: implement tryToMergeParialOverlappingStores using MemorySSA.
+ if (Earlier && Later && DT.dominates(Earlier, Later)) {
+ if (Constant *Merged = tryToMergePartialOverlappingStores(
+ Earlier, Later, InstWriteOffset, DepWriteOffset, State.DL,
+ State.BatchAA, &DT)) {
+
+ // Update stored value of earlier store to merged constant.
+ Earlier->setOperand(0, Merged);
+ ++NumModifiedStores;
+ MadeChange = true;
+
+ Shortend = true;
+ // Remove later store and remove any outstanding overlap intervals
+ // for the updated store.
+ State.deleteDeadInstruction(Later);
+ auto I = State.IOLs.find(Earlier->getParent());
+ if (I != State.IOLs.end())
+ I->second.erase(Earlier);
+ break;
+ }
}
}
@@ -2618,21 +2618,21 @@ bool eliminateDeadStoresMemorySSA(Function &F, AliasAnalysis &AA,
}
}
}
-
- // Check if the store is a no-op.
- if (!Shortend && isRemovable(SI) &&
- State.storeIsNoop(KillingDef, SILoc, SILocUnd)) {
- LLVM_DEBUG(dbgs() << "DSE: Remove No-Op Store:\n DEAD: " << *SI << '\n');
- State.deleteDeadInstruction(SI);
- NumRedundantStores++;
- MadeChange = true;
- continue;
- }
+
+ // Check if the store is a no-op.
+ if (!Shortend && isRemovable(SI) &&
+ State.storeIsNoop(KillingDef, SILoc, SILocUnd)) {
+ LLVM_DEBUG(dbgs() << "DSE: Remove No-Op Store:\n DEAD: " << *SI << '\n');
+ State.deleteDeadInstruction(SI);
+ NumRedundantStores++;
+ MadeChange = true;
+ continue;
+ }
}
if (EnablePartialOverwriteTracking)
for (auto &KV : State.IOLs)
- MadeChange |= removePartiallyOverlappedStores(State.DL, KV.second, TLI);
+ MadeChange |= removePartiallyOverlappedStores(State.DL, KV.second, TLI);
MadeChange |= State.eliminateDeadWritesAtEndOfFunction();
return MadeChange;
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/DivRemPairs.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/DivRemPairs.cpp
index 10cf0580f8..3c6c444d66 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/DivRemPairs.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/DivRemPairs.cpp
@@ -151,8 +151,8 @@ static DivRemWorklistTy getWorklist(Function &F) {
// rare than division.
for (auto &RemPair : RemMap) {
// Find the matching division instruction from the division map.
- auto It = DivMap.find(RemPair.first);
- if (It == DivMap.end())
+ auto It = DivMap.find(RemPair.first);
+ if (It == DivMap.end())
continue;
// We have a matching pair of div/rem instructions.
@@ -160,7 +160,7 @@ static DivRemWorklistTy getWorklist(Function &F) {
Instruction *RemInst = RemPair.second;
// Place it in the worklist.
- Worklist.emplace_back(It->second, RemInst);
+ Worklist.emplace_back(It->second, RemInst);
}
return Worklist;
@@ -315,14 +315,14 @@ static bool optimizeDivRem(Function &F, const TargetTransformInfo &TTI,
// %rem = sub %x, %mul // %rem = undef - undef = undef
// If X is not frozen, %rem becomes undef after transformation.
// TODO: We need a undef-specific checking function in ValueTracking
- if (!isGuaranteedNotToBeUndefOrPoison(X, nullptr, DivInst, &DT)) {
+ if (!isGuaranteedNotToBeUndefOrPoison(X, nullptr, DivInst, &DT)) {
auto *FrX = new FreezeInst(X, X->getName() + ".frozen", DivInst);
DivInst->setOperand(0, FrX);
Sub->setOperand(0, FrX);
}
// Same for Y. If X = 1 and Y = (undef | 1), %rem in src is either 1 or 0,
// but %rem in tgt can be one of many integer values.
- if (!isGuaranteedNotToBeUndefOrPoison(Y, nullptr, DivInst, &DT)) {
+ if (!isGuaranteedNotToBeUndefOrPoison(Y, nullptr, DivInst, &DT)) {
auto *FrY = new FreezeInst(Y, Y->getName() + ".frozen", DivInst);
DivInst->setOperand(1, FrY);
Mul->setOperand(1, FrY);
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/EarlyCSE.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/EarlyCSE.cpp
index dc144ff173..180a82917f 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/EarlyCSE.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/EarlyCSE.cpp
@@ -154,7 +154,7 @@ static bool matchSelectWithOptionalNotCond(Value *V, Value *&Cond, Value *&A,
std::swap(A, B);
}
- // Match canonical forms of min/max. We are not using ValueTracking's
+ // Match canonical forms of min/max. We are not using ValueTracking's
// more powerful matchSelectPattern() because it may rely on instruction flags
// such as "nsw". That would be incompatible with the current hashing
// mechanism that may remove flags to increase the likelihood of CSE.
@@ -176,11 +176,11 @@ static bool matchSelectWithOptionalNotCond(Value *V, Value *&Cond, Value *&A,
case CmpInst::ICMP_ULT: Flavor = SPF_UMIN; break;
case CmpInst::ICMP_SGT: Flavor = SPF_SMAX; break;
case CmpInst::ICMP_SLT: Flavor = SPF_SMIN; break;
- // Non-strict inequalities.
- case CmpInst::ICMP_ULE: Flavor = SPF_UMIN; break;
- case CmpInst::ICMP_UGE: Flavor = SPF_UMAX; break;
- case CmpInst::ICMP_SLE: Flavor = SPF_SMIN; break;
- case CmpInst::ICMP_SGE: Flavor = SPF_SMAX; break;
+ // Non-strict inequalities.
+ case CmpInst::ICMP_ULE: Flavor = SPF_UMIN; break;
+ case CmpInst::ICMP_UGE: Flavor = SPF_UMAX; break;
+ case CmpInst::ICMP_SLE: Flavor = SPF_SMIN; break;
+ case CmpInst::ICMP_SGE: Flavor = SPF_SMAX; break;
default: break;
}
@@ -219,7 +219,7 @@ static unsigned getHashValueImpl(SimpleValue Val) {
SelectPatternFlavor SPF;
Value *Cond, *A, *B;
if (matchSelectWithOptionalNotCond(Inst, Cond, A, B, SPF)) {
- // Hash min/max (cmp + select) to allow for commuted operands.
+ // Hash min/max (cmp + select) to allow for commuted operands.
// Min/max may also have non-canonical compare predicate (eg, the compare for
// smin may use 'sgt' rather than 'slt'), and non-canonical operands in the
// compare.
@@ -269,17 +269,17 @@ static unsigned getHashValueImpl(SimpleValue Val) {
isa<FreezeInst>(Inst)) &&
"Invalid/unknown instruction");
- // Handle intrinsics with commutative operands.
- // TODO: Extend this to handle intrinsics with >2 operands where the 1st
- // 2 operands are commutative.
- auto *II = dyn_cast<IntrinsicInst>(Inst);
- if (II && II->isCommutative() && II->getNumArgOperands() == 2) {
- Value *LHS = II->getArgOperand(0), *RHS = II->getArgOperand(1);
- if (LHS > RHS)
- std::swap(LHS, RHS);
- return hash_combine(II->getOpcode(), LHS, RHS);
- }
-
+ // Handle intrinsics with commutative operands.
+ // TODO: Extend this to handle intrinsics with >2 operands where the 1st
+ // 2 operands are commutative.
+ auto *II = dyn_cast<IntrinsicInst>(Inst);
+ if (II && II->isCommutative() && II->getNumArgOperands() == 2) {
+ Value *LHS = II->getArgOperand(0), *RHS = II->getArgOperand(1);
+ if (LHS > RHS)
+ std::swap(LHS, RHS);
+ return hash_combine(II->getOpcode(), LHS, RHS);
+ }
+
// Mix in the opcode.
return hash_combine(
Inst->getOpcode(),
@@ -332,16 +332,16 @@ static bool isEqualImpl(SimpleValue LHS, SimpleValue RHS) {
LHSCmp->getSwappedPredicate() == RHSCmp->getPredicate();
}
- // TODO: Extend this for >2 args by matching the trailing N-2 args.
- auto *LII = dyn_cast<IntrinsicInst>(LHSI);
- auto *RII = dyn_cast<IntrinsicInst>(RHSI);
- if (LII && RII && LII->getIntrinsicID() == RII->getIntrinsicID() &&
- LII->isCommutative() && LII->getNumArgOperands() == 2) {
- return LII->getArgOperand(0) == RII->getArgOperand(1) &&
- LII->getArgOperand(1) == RII->getArgOperand(0);
- }
-
- // Min/max can occur with commuted operands, non-canonical predicates,
+ // TODO: Extend this for >2 args by matching the trailing N-2 args.
+ auto *LII = dyn_cast<IntrinsicInst>(LHSI);
+ auto *RII = dyn_cast<IntrinsicInst>(RHSI);
+ if (LII && RII && LII->getIntrinsicID() == RII->getIntrinsicID() &&
+ LII->isCommutative() && LII->getNumArgOperands() == 2) {
+ return LII->getArgOperand(0) == RII->getArgOperand(1) &&
+ LII->getArgOperand(1) == RII->getArgOperand(0);
+ }
+
+ // Min/max can occur with commuted operands, non-canonical predicates,
// and/or non-canonical operands.
// Selects can be non-trivially equivalent via inverted conditions and swaps.
SelectPatternFlavor LSPF, RSPF;
@@ -372,7 +372,7 @@ static bool isEqualImpl(SimpleValue LHS, SimpleValue RHS) {
// This intentionally does NOT handle patterns with a double-negation in
// the sense of not + not, because doing so could result in values
// comparing
- // as equal that hash differently in the min/max cases like:
+ // as equal that hash differently in the min/max cases like:
// select (cmp slt, X, Y), X, Y <--> select (not (not (cmp slt, X, Y))), X, Y
// ^ hashes as min ^ would not hash as min
// In the context of the EarlyCSE pass, however, such cases never reach
@@ -627,11 +627,11 @@ private:
StackNode &operator=(const StackNode &) = delete;
// Accessors.
- unsigned currentGeneration() const { return CurrentGeneration; }
- unsigned childGeneration() const { return ChildGeneration; }
+ unsigned currentGeneration() const { return CurrentGeneration; }
+ unsigned childGeneration() const { return ChildGeneration; }
void childGeneration(unsigned generation) { ChildGeneration = generation; }
DomTreeNode *node() { return Node; }
- DomTreeNode::const_iterator childIter() const { return ChildIter; }
+ DomTreeNode::const_iterator childIter() const { return ChildIter; }
DomTreeNode *nextChild() {
DomTreeNode *child = *ChildIter;
@@ -639,8 +639,8 @@ private:
return child;
}
- DomTreeNode::const_iterator end() const { return EndIter; }
- bool isProcessed() const { return Processed; }
+ DomTreeNode::const_iterator end() const { return EndIter; }
+ bool isProcessed() const { return Processed; }
void process() { Processed = true; }
private:
@@ -659,60 +659,60 @@ private:
public:
ParseMemoryInst(Instruction *Inst, const TargetTransformInfo &TTI)
: Inst(Inst) {
- if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
- IntrID = II->getIntrinsicID();
+ if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
+ IntrID = II->getIntrinsicID();
if (TTI.getTgtMemIntrinsic(II, Info))
- return;
- if (isHandledNonTargetIntrinsic(IntrID)) {
- switch (IntrID) {
- case Intrinsic::masked_load:
- Info.PtrVal = Inst->getOperand(0);
- Info.MatchingId = Intrinsic::masked_load;
- Info.ReadMem = true;
- Info.WriteMem = false;
- Info.IsVolatile = false;
- break;
- case Intrinsic::masked_store:
- Info.PtrVal = Inst->getOperand(1);
- // Use the ID of masked load as the "matching id". This will
- // prevent matching non-masked loads/stores with masked ones
- // (which could be done), but at the moment, the code here
- // does not support matching intrinsics with non-intrinsics,
- // so keep the MatchingIds specific to masked instructions
- // for now (TODO).
- Info.MatchingId = Intrinsic::masked_load;
- Info.ReadMem = false;
- Info.WriteMem = true;
- Info.IsVolatile = false;
- break;
- }
- }
- }
+ return;
+ if (isHandledNonTargetIntrinsic(IntrID)) {
+ switch (IntrID) {
+ case Intrinsic::masked_load:
+ Info.PtrVal = Inst->getOperand(0);
+ Info.MatchingId = Intrinsic::masked_load;
+ Info.ReadMem = true;
+ Info.WriteMem = false;
+ Info.IsVolatile = false;
+ break;
+ case Intrinsic::masked_store:
+ Info.PtrVal = Inst->getOperand(1);
+ // Use the ID of masked load as the "matching id". This will
+ // prevent matching non-masked loads/stores with masked ones
+ // (which could be done), but at the moment, the code here
+ // does not support matching intrinsics with non-intrinsics,
+ // so keep the MatchingIds specific to masked instructions
+ // for now (TODO).
+ Info.MatchingId = Intrinsic::masked_load;
+ Info.ReadMem = false;
+ Info.WriteMem = true;
+ Info.IsVolatile = false;
+ break;
+ }
+ }
+ }
}
- Instruction *get() { return Inst; }
- const Instruction *get() const { return Inst; }
-
+ Instruction *get() { return Inst; }
+ const Instruction *get() const { return Inst; }
+
bool isLoad() const {
- if (IntrID != 0)
- return Info.ReadMem;
+ if (IntrID != 0)
+ return Info.ReadMem;
return isa<LoadInst>(Inst);
}
bool isStore() const {
- if (IntrID != 0)
- return Info.WriteMem;
+ if (IntrID != 0)
+ return Info.WriteMem;
return isa<StoreInst>(Inst);
}
bool isAtomic() const {
- if (IntrID != 0)
+ if (IntrID != 0)
return Info.Ordering != AtomicOrdering::NotAtomic;
return Inst->isAtomic();
}
bool isUnordered() const {
- if (IntrID != 0)
+ if (IntrID != 0)
return Info.isUnordered();
if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
@@ -725,7 +725,7 @@ private:
}
bool isVolatile() const {
- if (IntrID != 0)
+ if (IntrID != 0)
return Info.IsVolatile;
if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
@@ -750,85 +750,85 @@ private:
// field in the MemIntrinsicInfo structure. That field contains
// non-negative values only.
int getMatchingId() const {
- if (IntrID != 0)
- return Info.MatchingId;
+ if (IntrID != 0)
+ return Info.MatchingId;
return -1;
}
Value *getPointerOperand() const {
- if (IntrID != 0)
- return Info.PtrVal;
+ if (IntrID != 0)
+ return Info.PtrVal;
return getLoadStorePointerOperand(Inst);
}
bool mayReadFromMemory() const {
- if (IntrID != 0)
- return Info.ReadMem;
+ if (IntrID != 0)
+ return Info.ReadMem;
return Inst->mayReadFromMemory();
}
bool mayWriteToMemory() const {
- if (IntrID != 0)
- return Info.WriteMem;
+ if (IntrID != 0)
+ return Info.WriteMem;
return Inst->mayWriteToMemory();
}
private:
- Intrinsic::ID IntrID = 0;
+ Intrinsic::ID IntrID = 0;
MemIntrinsicInfo Info;
Instruction *Inst;
};
- // This function is to prevent accidentally passing a non-target
- // intrinsic ID to TargetTransformInfo.
- static bool isHandledNonTargetIntrinsic(Intrinsic::ID ID) {
- switch (ID) {
- case Intrinsic::masked_load:
- case Intrinsic::masked_store:
- return true;
- }
- return false;
- }
- static bool isHandledNonTargetIntrinsic(const Value *V) {
- if (auto *II = dyn_cast<IntrinsicInst>(V))
- return isHandledNonTargetIntrinsic(II->getIntrinsicID());
- return false;
- }
-
+ // This function is to prevent accidentally passing a non-target
+ // intrinsic ID to TargetTransformInfo.
+ static bool isHandledNonTargetIntrinsic(Intrinsic::ID ID) {
+ switch (ID) {
+ case Intrinsic::masked_load:
+ case Intrinsic::masked_store:
+ return true;
+ }
+ return false;
+ }
+ static bool isHandledNonTargetIntrinsic(const Value *V) {
+ if (auto *II = dyn_cast<IntrinsicInst>(V))
+ return isHandledNonTargetIntrinsic(II->getIntrinsicID());
+ return false;
+ }
+
bool processNode(DomTreeNode *Node);
bool handleBranchCondition(Instruction *CondInst, const BranchInst *BI,
const BasicBlock *BB, const BasicBlock *Pred);
- Value *getMatchingValue(LoadValue &InVal, ParseMemoryInst &MemInst,
- unsigned CurrentGeneration);
-
- bool overridingStores(const ParseMemoryInst &Earlier,
- const ParseMemoryInst &Later);
-
+ Value *getMatchingValue(LoadValue &InVal, ParseMemoryInst &MemInst,
+ unsigned CurrentGeneration);
+
+ bool overridingStores(const ParseMemoryInst &Earlier,
+ const ParseMemoryInst &Later);
+
Value *getOrCreateResult(Value *Inst, Type *ExpectedType) const {
if (auto *LI = dyn_cast<LoadInst>(Inst))
return LI;
if (auto *SI = dyn_cast<StoreInst>(Inst))
return SI->getValueOperand();
assert(isa<IntrinsicInst>(Inst) && "Instruction not supported");
- auto *II = cast<IntrinsicInst>(Inst);
- if (isHandledNonTargetIntrinsic(II->getIntrinsicID()))
- return getOrCreateResultNonTargetMemIntrinsic(II, ExpectedType);
- return TTI.getOrCreateResultFromMemIntrinsic(II, ExpectedType);
+ auto *II = cast<IntrinsicInst>(Inst);
+ if (isHandledNonTargetIntrinsic(II->getIntrinsicID()))
+ return getOrCreateResultNonTargetMemIntrinsic(II, ExpectedType);
+ return TTI.getOrCreateResultFromMemIntrinsic(II, ExpectedType);
+ }
+
+ Value *getOrCreateResultNonTargetMemIntrinsic(IntrinsicInst *II,
+ Type *ExpectedType) const {
+ switch (II->getIntrinsicID()) {
+ case Intrinsic::masked_load:
+ return II;
+ case Intrinsic::masked_store:
+ return II->getOperand(0);
+ }
+ return nullptr;
}
- Value *getOrCreateResultNonTargetMemIntrinsic(IntrinsicInst *II,
- Type *ExpectedType) const {
- switch (II->getIntrinsicID()) {
- case Intrinsic::masked_load:
- return II;
- case Intrinsic::masked_store:
- return II->getOperand(0);
- }
- return nullptr;
- }
-
/// Return true if the instruction is known to only operate on memory
/// provably invariant in the given "generation".
bool isOperatingOnInvariantMemAt(Instruction *I, unsigned GenAt);
@@ -836,101 +836,101 @@ private:
bool isSameMemGeneration(unsigned EarlierGeneration, unsigned LaterGeneration,
Instruction *EarlierInst, Instruction *LaterInst);
- bool isNonTargetIntrinsicMatch(const IntrinsicInst *Earlier,
- const IntrinsicInst *Later) {
- auto IsSubmask = [](const Value *Mask0, const Value *Mask1) {
- // Is Mask0 a submask of Mask1?
- if (Mask0 == Mask1)
- return true;
- if (isa<UndefValue>(Mask0) || isa<UndefValue>(Mask1))
- return false;
- auto *Vec0 = dyn_cast<ConstantVector>(Mask0);
- auto *Vec1 = dyn_cast<ConstantVector>(Mask1);
- if (!Vec0 || !Vec1)
- return false;
- assert(Vec0->getType() == Vec1->getType() &&
- "Masks should have the same type");
- for (int i = 0, e = Vec0->getNumOperands(); i != e; ++i) {
- Constant *Elem0 = Vec0->getOperand(i);
- Constant *Elem1 = Vec1->getOperand(i);
- auto *Int0 = dyn_cast<ConstantInt>(Elem0);
- if (Int0 && Int0->isZero())
- continue;
- auto *Int1 = dyn_cast<ConstantInt>(Elem1);
- if (Int1 && !Int1->isZero())
- continue;
- if (isa<UndefValue>(Elem0) || isa<UndefValue>(Elem1))
- return false;
- if (Elem0 == Elem1)
- continue;
- return false;
- }
- return true;
- };
- auto PtrOp = [](const IntrinsicInst *II) {
- if (II->getIntrinsicID() == Intrinsic::masked_load)
- return II->getOperand(0);
- if (II->getIntrinsicID() == Intrinsic::masked_store)
- return II->getOperand(1);
- llvm_unreachable("Unexpected IntrinsicInst");
- };
- auto MaskOp = [](const IntrinsicInst *II) {
- if (II->getIntrinsicID() == Intrinsic::masked_load)
- return II->getOperand(2);
- if (II->getIntrinsicID() == Intrinsic::masked_store)
- return II->getOperand(3);
- llvm_unreachable("Unexpected IntrinsicInst");
- };
- auto ThruOp = [](const IntrinsicInst *II) {
- if (II->getIntrinsicID() == Intrinsic::masked_load)
- return II->getOperand(3);
- llvm_unreachable("Unexpected IntrinsicInst");
- };
-
- if (PtrOp(Earlier) != PtrOp(Later))
- return false;
-
- Intrinsic::ID IDE = Earlier->getIntrinsicID();
- Intrinsic::ID IDL = Later->getIntrinsicID();
- // We could really use specific intrinsic classes for masked loads
- // and stores in IntrinsicInst.h.
- if (IDE == Intrinsic::masked_load && IDL == Intrinsic::masked_load) {
- // Trying to replace later masked load with the earlier one.
- // Check that the pointers are the same, and
- // - masks and pass-throughs are the same, or
- // - replacee's pass-through is "undef" and replacer's mask is a
- // super-set of the replacee's mask.
- if (MaskOp(Earlier) == MaskOp(Later) && ThruOp(Earlier) == ThruOp(Later))
- return true;
- if (!isa<UndefValue>(ThruOp(Later)))
- return false;
- return IsSubmask(MaskOp(Later), MaskOp(Earlier));
- }
- if (IDE == Intrinsic::masked_store && IDL == Intrinsic::masked_load) {
- // Trying to replace a load of a stored value with the store's value.
- // Check that the pointers are the same, and
- // - load's mask is a subset of store's mask, and
- // - load's pass-through is "undef".
- if (!IsSubmask(MaskOp(Later), MaskOp(Earlier)))
- return false;
- return isa<UndefValue>(ThruOp(Later));
- }
- if (IDE == Intrinsic::masked_load && IDL == Intrinsic::masked_store) {
- // Trying to remove a store of the loaded value.
- // Check that the pointers are the same, and
- // - store's mask is a subset of the load's mask.
- return IsSubmask(MaskOp(Later), MaskOp(Earlier));
- }
- if (IDE == Intrinsic::masked_store && IDL == Intrinsic::masked_store) {
- // Trying to remove a dead store (earlier).
- // Check that the pointers are the same,
- // - the to-be-removed store's mask is a subset of the other store's
- // mask.
- return IsSubmask(MaskOp(Earlier), MaskOp(Later));
- }
- return false;
- }
-
+ bool isNonTargetIntrinsicMatch(const IntrinsicInst *Earlier,
+ const IntrinsicInst *Later) {
+ auto IsSubmask = [](const Value *Mask0, const Value *Mask1) {
+ // Is Mask0 a submask of Mask1?
+ if (Mask0 == Mask1)
+ return true;
+ if (isa<UndefValue>(Mask0) || isa<UndefValue>(Mask1))
+ return false;
+ auto *Vec0 = dyn_cast<ConstantVector>(Mask0);
+ auto *Vec1 = dyn_cast<ConstantVector>(Mask1);
+ if (!Vec0 || !Vec1)
+ return false;
+ assert(Vec0->getType() == Vec1->getType() &&
+ "Masks should have the same type");
+ for (int i = 0, e = Vec0->getNumOperands(); i != e; ++i) {
+ Constant *Elem0 = Vec0->getOperand(i);
+ Constant *Elem1 = Vec1->getOperand(i);
+ auto *Int0 = dyn_cast<ConstantInt>(Elem0);
+ if (Int0 && Int0->isZero())
+ continue;
+ auto *Int1 = dyn_cast<ConstantInt>(Elem1);
+ if (Int1 && !Int1->isZero())
+ continue;
+ if (isa<UndefValue>(Elem0) || isa<UndefValue>(Elem1))
+ return false;
+ if (Elem0 == Elem1)
+ continue;
+ return false;
+ }
+ return true;
+ };
+ auto PtrOp = [](const IntrinsicInst *II) {
+ if (II->getIntrinsicID() == Intrinsic::masked_load)
+ return II->getOperand(0);
+ if (II->getIntrinsicID() == Intrinsic::masked_store)
+ return II->getOperand(1);
+ llvm_unreachable("Unexpected IntrinsicInst");
+ };
+ auto MaskOp = [](const IntrinsicInst *II) {
+ if (II->getIntrinsicID() == Intrinsic::masked_load)
+ return II->getOperand(2);
+ if (II->getIntrinsicID() == Intrinsic::masked_store)
+ return II->getOperand(3);
+ llvm_unreachable("Unexpected IntrinsicInst");
+ };
+ auto ThruOp = [](const IntrinsicInst *II) {
+ if (II->getIntrinsicID() == Intrinsic::masked_load)
+ return II->getOperand(3);
+ llvm_unreachable("Unexpected IntrinsicInst");
+ };
+
+ if (PtrOp(Earlier) != PtrOp(Later))
+ return false;
+
+ Intrinsic::ID IDE = Earlier->getIntrinsicID();
+ Intrinsic::ID IDL = Later->getIntrinsicID();
+ // We could really use specific intrinsic classes for masked loads
+ // and stores in IntrinsicInst.h.
+ if (IDE == Intrinsic::masked_load && IDL == Intrinsic::masked_load) {
+ // Trying to replace later masked load with the earlier one.
+ // Check that the pointers are the same, and
+ // - masks and pass-throughs are the same, or
+ // - replacee's pass-through is "undef" and replacer's mask is a
+ // super-set of the replacee's mask.
+ if (MaskOp(Earlier) == MaskOp(Later) && ThruOp(Earlier) == ThruOp(Later))
+ return true;
+ if (!isa<UndefValue>(ThruOp(Later)))
+ return false;
+ return IsSubmask(MaskOp(Later), MaskOp(Earlier));
+ }
+ if (IDE == Intrinsic::masked_store && IDL == Intrinsic::masked_load) {
+ // Trying to replace a load of a stored value with the store's value.
+ // Check that the pointers are the same, and
+ // - load's mask is a subset of store's mask, and
+ // - load's pass-through is "undef".
+ if (!IsSubmask(MaskOp(Later), MaskOp(Earlier)))
+ return false;
+ return isa<UndefValue>(ThruOp(Later));
+ }
+ if (IDE == Intrinsic::masked_load && IDL == Intrinsic::masked_store) {
+ // Trying to remove a store of the loaded value.
+ // Check that the pointers are the same, and
+ // - store's mask is a subset of the load's mask.
+ return IsSubmask(MaskOp(Later), MaskOp(Earlier));
+ }
+ if (IDE == Intrinsic::masked_store && IDL == Intrinsic::masked_store) {
+ // Trying to remove a dead store (earlier).
+ // Check that the pointers are the same,
+ // - the to-be-removed store's mask is a subset of the other store's
+ // mask.
+ return IsSubmask(MaskOp(Earlier), MaskOp(Later));
+ }
+ return false;
+ }
+
void removeMSSA(Instruction &Inst) {
if (!MSSA)
return;
@@ -1033,14 +1033,14 @@ bool EarlyCSE::handleBranchCondition(Instruction *CondInst,
auto *TorF = (BI->getSuccessor(0) == BB)
? ConstantInt::getTrue(BB->getContext())
: ConstantInt::getFalse(BB->getContext());
- auto MatchBinOp = [](Instruction *I, unsigned Opcode, Value *&LHS,
- Value *&RHS) {
- if (Opcode == Instruction::And &&
- match(I, m_LogicalAnd(m_Value(LHS), m_Value(RHS))))
- return true;
- else if (Opcode == Instruction::Or &&
- match(I, m_LogicalOr(m_Value(LHS), m_Value(RHS))))
- return true;
+ auto MatchBinOp = [](Instruction *I, unsigned Opcode, Value *&LHS,
+ Value *&RHS) {
+ if (Opcode == Instruction::And &&
+ match(I, m_LogicalAnd(m_Value(LHS), m_Value(RHS))))
+ return true;
+ else if (Opcode == Instruction::Or &&
+ match(I, m_LogicalOr(m_Value(LHS), m_Value(RHS))))
+ return true;
return false;
};
// If the condition is AND operation, we can propagate its operands into the
@@ -1071,9 +1071,9 @@ bool EarlyCSE::handleBranchCondition(Instruction *CondInst,
}
}
- Value *LHS, *RHS;
- if (MatchBinOp(Curr, PropagateOpcode, LHS, RHS))
- for (auto &Op : { LHS, RHS })
+ Value *LHS, *RHS;
+ if (MatchBinOp(Curr, PropagateOpcode, LHS, RHS))
+ for (auto &Op : { LHS, RHS })
if (Instruction *OPI = dyn_cast<Instruction>(Op))
if (SimpleValue::canHandle(OPI) && Visited.insert(OPI).second)
WorkList.push_back(OPI);
@@ -1082,86 +1082,86 @@ bool EarlyCSE::handleBranchCondition(Instruction *CondInst,
return MadeChanges;
}
-Value *EarlyCSE::getMatchingValue(LoadValue &InVal, ParseMemoryInst &MemInst,
- unsigned CurrentGeneration) {
- if (InVal.DefInst == nullptr)
- return nullptr;
- if (InVal.MatchingId != MemInst.getMatchingId())
- return nullptr;
- // We don't yet handle removing loads with ordering of any kind.
- if (MemInst.isVolatile() || !MemInst.isUnordered())
- return nullptr;
- // We can't replace an atomic load with one which isn't also atomic.
- if (MemInst.isLoad() && !InVal.IsAtomic && MemInst.isAtomic())
- return nullptr;
- // The value V returned from this function is used differently depending
- // on whether MemInst is a load or a store. If it's a load, we will replace
- // MemInst with V, if it's a store, we will check if V is the same as the
- // available value.
- bool MemInstMatching = !MemInst.isLoad();
- Instruction *Matching = MemInstMatching ? MemInst.get() : InVal.DefInst;
- Instruction *Other = MemInstMatching ? InVal.DefInst : MemInst.get();
-
- // For stores check the result values before checking memory generation
- // (otherwise isSameMemGeneration may crash).
- Value *Result = MemInst.isStore()
- ? getOrCreateResult(Matching, Other->getType())
- : nullptr;
- if (MemInst.isStore() && InVal.DefInst != Result)
- return nullptr;
-
- // Deal with non-target memory intrinsics.
- bool MatchingNTI = isHandledNonTargetIntrinsic(Matching);
- bool OtherNTI = isHandledNonTargetIntrinsic(Other);
- if (OtherNTI != MatchingNTI)
- return nullptr;
- if (OtherNTI && MatchingNTI) {
- if (!isNonTargetIntrinsicMatch(cast<IntrinsicInst>(InVal.DefInst),
- cast<IntrinsicInst>(MemInst.get())))
- return nullptr;
- }
-
- if (!isOperatingOnInvariantMemAt(MemInst.get(), InVal.Generation) &&
- !isSameMemGeneration(InVal.Generation, CurrentGeneration, InVal.DefInst,
- MemInst.get()))
- return nullptr;
-
- if (!Result)
- Result = getOrCreateResult(Matching, Other->getType());
- return Result;
-}
-
-bool EarlyCSE::overridingStores(const ParseMemoryInst &Earlier,
- const ParseMemoryInst &Later) {
- // Can we remove Earlier store because of Later store?
-
- assert(Earlier.isUnordered() && !Earlier.isVolatile() &&
- "Violated invariant");
- if (Earlier.getPointerOperand() != Later.getPointerOperand())
- return false;
- if (Earlier.getMatchingId() != Later.getMatchingId())
- return false;
- // At the moment, we don't remove ordered stores, but do remove
- // unordered atomic stores. There's no special requirement (for
- // unordered atomics) about removing atomic stores only in favor of
- // other atomic stores since we were going to execute the non-atomic
- // one anyway and the atomic one might never have become visible.
- if (!Earlier.isUnordered() || !Later.isUnordered())
- return false;
-
- // Deal with non-target memory intrinsics.
- bool ENTI = isHandledNonTargetIntrinsic(Earlier.get());
- bool LNTI = isHandledNonTargetIntrinsic(Later.get());
- if (ENTI && LNTI)
- return isNonTargetIntrinsicMatch(cast<IntrinsicInst>(Earlier.get()),
- cast<IntrinsicInst>(Later.get()));
-
- // Because of the check above, at least one of them is false.
- // For now disallow matching intrinsics with non-intrinsics,
- // so assume that the stores match if neither is an intrinsic.
- return ENTI == LNTI;
-}
-
+Value *EarlyCSE::getMatchingValue(LoadValue &InVal, ParseMemoryInst &MemInst,
+ unsigned CurrentGeneration) {
+ if (InVal.DefInst == nullptr)
+ return nullptr;
+ if (InVal.MatchingId != MemInst.getMatchingId())
+ return nullptr;
+ // We don't yet handle removing loads with ordering of any kind.
+ if (MemInst.isVolatile() || !MemInst.isUnordered())
+ return nullptr;
+ // We can't replace an atomic load with one which isn't also atomic.
+ if (MemInst.isLoad() && !InVal.IsAtomic && MemInst.isAtomic())
+ return nullptr;
+ // The value V returned from this function is used differently depending
+ // on whether MemInst is a load or a store. If it's a load, we will replace
+ // MemInst with V, if it's a store, we will check if V is the same as the
+ // available value.
+ bool MemInstMatching = !MemInst.isLoad();
+ Instruction *Matching = MemInstMatching ? MemInst.get() : InVal.DefInst;
+ Instruction *Other = MemInstMatching ? InVal.DefInst : MemInst.get();
+
+ // For stores check the result values before checking memory generation
+ // (otherwise isSameMemGeneration may crash).
+ Value *Result = MemInst.isStore()
+ ? getOrCreateResult(Matching, Other->getType())
+ : nullptr;
+ if (MemInst.isStore() && InVal.DefInst != Result)
+ return nullptr;
+
+ // Deal with non-target memory intrinsics.
+ bool MatchingNTI = isHandledNonTargetIntrinsic(Matching);
+ bool OtherNTI = isHandledNonTargetIntrinsic(Other);
+ if (OtherNTI != MatchingNTI)
+ return nullptr;
+ if (OtherNTI && MatchingNTI) {
+ if (!isNonTargetIntrinsicMatch(cast<IntrinsicInst>(InVal.DefInst),
+ cast<IntrinsicInst>(MemInst.get())))
+ return nullptr;
+ }
+
+ if (!isOperatingOnInvariantMemAt(MemInst.get(), InVal.Generation) &&
+ !isSameMemGeneration(InVal.Generation, CurrentGeneration, InVal.DefInst,
+ MemInst.get()))
+ return nullptr;
+
+ if (!Result)
+ Result = getOrCreateResult(Matching, Other->getType());
+ return Result;
+}
+
+bool EarlyCSE::overridingStores(const ParseMemoryInst &Earlier,
+ const ParseMemoryInst &Later) {
+ // Can we remove Earlier store because of Later store?
+
+ assert(Earlier.isUnordered() && !Earlier.isVolatile() &&
+ "Violated invariant");
+ if (Earlier.getPointerOperand() != Later.getPointerOperand())
+ return false;
+ if (Earlier.getMatchingId() != Later.getMatchingId())
+ return false;
+ // At the moment, we don't remove ordered stores, but do remove
+ // unordered atomic stores. There's no special requirement (for
+ // unordered atomics) about removing atomic stores only in favor of
+ // other atomic stores since we were going to execute the non-atomic
+ // one anyway and the atomic one might never have become visible.
+ if (!Earlier.isUnordered() || !Later.isUnordered())
+ return false;
+
+ // Deal with non-target memory intrinsics.
+ bool ENTI = isHandledNonTargetIntrinsic(Earlier.get());
+ bool LNTI = isHandledNonTargetIntrinsic(Later.get());
+ if (ENTI && LNTI)
+ return isNonTargetIntrinsicMatch(cast<IntrinsicInst>(Earlier.get()),
+ cast<IntrinsicInst>(Later.get()));
+
+ // Because of the check above, at least one of them is false.
+ // For now disallow matching intrinsics with non-intrinsics,
+ // so assume that the stores match if neither is an intrinsic.
+ return ENTI == LNTI;
+}
+
bool EarlyCSE::processNode(DomTreeNode *Node) {
bool Changed = false;
BasicBlock *BB = Node->getBlock();
@@ -1232,14 +1232,14 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
continue;
}
- // Likewise, noalias intrinsics don't actually write.
- if (match(&Inst,
- m_Intrinsic<Intrinsic::experimental_noalias_scope_decl>())) {
- LLVM_DEBUG(dbgs() << "EarlyCSE skipping noalias intrinsic: " << Inst
- << '\n');
- continue;
- }
-
+ // Likewise, noalias intrinsics don't actually write.
+ if (match(&Inst,
+ m_Intrinsic<Intrinsic::experimental_noalias_scope_decl>())) {
+ LLVM_DEBUG(dbgs() << "EarlyCSE skipping noalias intrinsic: " << Inst
+ << '\n');
+ continue;
+ }
+
// Skip sideeffect intrinsics, for the same reason as assume intrinsics.
if (match(&Inst, m_Intrinsic<Intrinsic::sideeffect>())) {
LLVM_DEBUG(dbgs() << "EarlyCSE skipping sideeffect: " << Inst << '\n');
@@ -1386,21 +1386,21 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
// we can assume the current load loads the same value as the dominating
// load.
LoadValue InVal = AvailableLoads.lookup(MemInst.getPointerOperand());
- if (Value *Op = getMatchingValue(InVal, MemInst, CurrentGeneration)) {
- LLVM_DEBUG(dbgs() << "EarlyCSE CSE LOAD: " << Inst
- << " to: " << *InVal.DefInst << '\n');
- if (!DebugCounter::shouldExecute(CSECounter)) {
- LLVM_DEBUG(dbgs() << "Skipping due to debug counter\n");
+ if (Value *Op = getMatchingValue(InVal, MemInst, CurrentGeneration)) {
+ LLVM_DEBUG(dbgs() << "EarlyCSE CSE LOAD: " << Inst
+ << " to: " << *InVal.DefInst << '\n');
+ if (!DebugCounter::shouldExecute(CSECounter)) {
+ LLVM_DEBUG(dbgs() << "Skipping due to debug counter\n");
continue;
}
- if (!Inst.use_empty())
- Inst.replaceAllUsesWith(Op);
- salvageKnowledge(&Inst, &AC);
- removeMSSA(Inst);
- Inst.eraseFromParent();
- Changed = true;
- ++NumCSELoad;
- continue;
+ if (!Inst.use_empty())
+ Inst.replaceAllUsesWith(Op);
+ salvageKnowledge(&Inst, &AC);
+ removeMSSA(Inst);
+ Inst.eraseFromParent();
+ Changed = true;
+ ++NumCSELoad;
+ continue;
}
// Otherwise, remember that we have this instruction.
@@ -1470,7 +1470,7 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
if (MemInst.isValid() && MemInst.isStore()) {
LoadValue InVal = AvailableLoads.lookup(MemInst.getPointerOperand());
if (InVal.DefInst &&
- InVal.DefInst == getMatchingValue(InVal, MemInst, CurrentGeneration)) {
+ InVal.DefInst == getMatchingValue(InVal, MemInst, CurrentGeneration)) {
// It is okay to have a LastStore to a different pointer here if MemorySSA
// tells us that the load and store are from the same memory generation.
// In that case, LastStore should keep its present value since we're
@@ -1506,7 +1506,7 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
// We do a trivial form of DSE if there are two stores to the same
// location with no intervening loads. Delete the earlier store.
if (LastStore) {
- if (overridingStores(ParseMemoryInst(LastStore, TTI), MemInst)) {
+ if (overridingStores(ParseMemoryInst(LastStore, TTI), MemInst)) {
LLVM_DEBUG(dbgs() << "EarlyCSE DEAD STORE: " << *LastStore
<< " due to: " << Inst << '\n');
if (!DebugCounter::shouldExecute(CSECounter)) {
@@ -1667,7 +1667,7 @@ public:
AU.addRequired<TargetLibraryInfoWrapperPass>();
AU.addRequired<TargetTransformInfoWrapperPass>();
if (UseMemorySSA) {
- AU.addRequired<AAResultsWrapperPass>();
+ AU.addRequired<AAResultsWrapperPass>();
AU.addRequired<MemorySSAWrapperPass>();
AU.addPreserved<MemorySSAWrapperPass>();
}
@@ -1709,7 +1709,7 @@ INITIALIZE_PASS_BEGIN(EarlyCSEMemSSALegacyPass, "early-cse-memssa",
"Early CSE w/ MemorySSA", false, false)
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
-INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/FlattenCFGPass.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/FlattenCFGPass.cpp
index ab88f253c6..e54a270fb2 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/FlattenCFGPass.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/FlattenCFGPass.cpp
@@ -12,7 +12,7 @@
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/CFG.h"
-#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/GVN.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/GVN.cpp
index a0e7dec90f..c6b6d75aef 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/GVN.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/GVN.cpp
@@ -26,7 +26,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumeBundleQueries.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/CFG.h"
@@ -36,8 +36,8 @@
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
-#include "llvm/Analysis/MemorySSA.h"
-#include "llvm/Analysis/MemorySSAUpdater.h"
+#include "llvm/Analysis/MemorySSA.h"
+#include "llvm/Analysis/MemorySSAUpdater.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/PHITransAddr.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
@@ -99,33 +99,33 @@ STATISTIC(NumGVNSimpl, "Number of instructions simplified");
STATISTIC(NumGVNEqProp, "Number of equalities propagated");
STATISTIC(NumPRELoad, "Number of loads PRE'd");
-STATISTIC(IsValueFullyAvailableInBlockNumSpeculationsMax,
- "Number of blocks speculated as available in "
- "IsValueFullyAvailableInBlock(), max");
-STATISTIC(MaxBBSpeculationCutoffReachedTimes,
- "Number of times we we reached gvn-max-block-speculations cut-off "
- "preventing further exploration");
-
+STATISTIC(IsValueFullyAvailableInBlockNumSpeculationsMax,
+ "Number of blocks speculated as available in "
+ "IsValueFullyAvailableInBlock(), max");
+STATISTIC(MaxBBSpeculationCutoffReachedTimes,
+ "Number of times we we reached gvn-max-block-speculations cut-off "
+ "preventing further exploration");
+
static cl::opt<bool> GVNEnablePRE("enable-pre", cl::init(true), cl::Hidden);
static cl::opt<bool> GVNEnableLoadPRE("enable-load-pre", cl::init(true));
static cl::opt<bool> GVNEnableLoadInLoopPRE("enable-load-in-loop-pre",
cl::init(true));
-static cl::opt<bool>
-GVNEnableSplitBackedgeInLoadPRE("enable-split-backedge-in-load-pre",
- cl::init(true));
+static cl::opt<bool>
+GVNEnableSplitBackedgeInLoadPRE("enable-split-backedge-in-load-pre",
+ cl::init(true));
static cl::opt<bool> GVNEnableMemDep("enable-gvn-memdep", cl::init(true));
static cl::opt<uint32_t> MaxNumDeps(
"gvn-max-num-deps", cl::Hidden, cl::init(100), cl::ZeroOrMore,
cl::desc("Max number of dependences to attempt Load PRE (default = 100)"));
-// This is based on IsValueFullyAvailableInBlockNumSpeculationsMax stat.
-static cl::opt<uint32_t> MaxBBSpeculations(
- "gvn-max-block-speculations", cl::Hidden, cl::init(600), cl::ZeroOrMore,
- cl::desc("Max number of blocks we're willing to speculate on (and recurse "
- "into) when deducing if a value is fully available or not in GVN "
- "(default = 600)"));
-
+// This is based on IsValueFullyAvailableInBlockNumSpeculationsMax stat.
+static cl::opt<uint32_t> MaxBBSpeculations(
+ "gvn-max-block-speculations", cl::Hidden, cl::init(600), cl::ZeroOrMore,
+ cl::desc("Max number of blocks we're willing to speculate on (and recurse "
+ "into) when deducing if a value is fully available or not in GVN "
+ "(default = 600)"));
+
struct llvm::GVN::Expression {
uint32_t opcode;
bool commutative = false;
@@ -295,9 +295,9 @@ GVN::Expression GVN::ValueTable::createExpr(Instruction *I) {
if (I->isCommutative()) {
// Ensure that commutative instructions that only differ by a permutation
// of their operands get the same value number by sorting the operand value
- // numbers. Since commutative operands are the 1st two operands it is more
+ // numbers. Since commutative operands are the 1st two operands it is more
// efficient to sort by hand rather than using, say, std::sort.
- assert(I->getNumOperands() >= 2 && "Unsupported commutative instruction!");
+ assert(I->getNumOperands() >= 2 && "Unsupported commutative instruction!");
if (e.varargs[0] > e.varargs[1])
std::swap(e.varargs[0], e.varargs[1]);
e.commutative = true;
@@ -366,7 +366,7 @@ GVN::Expression GVN::ValueTable::createExtractvalueExpr(ExtractValueInst *EI) {
OI != OE; ++OI)
e.varargs.push_back(lookupOrAdd(*OI));
- append_range(e.varargs, EI->indices());
+ append_range(e.varargs, EI->indices());
return e;
}
@@ -410,12 +410,12 @@ uint32_t GVN::ValueTable::lookupOrAddCall(CallInst *C) {
}
if (local_dep.isDef()) {
- // For masked load/store intrinsics, the local_dep may actully be
- // a normal load or store instruction.
- CallInst *local_cdep = dyn_cast<CallInst>(local_dep.getInst());
+ // For masked load/store intrinsics, the local_dep may actully be
+ // a normal load or store instruction.
+ CallInst *local_cdep = dyn_cast<CallInst>(local_dep.getInst());
- if (!local_cdep ||
- local_cdep->getNumArgOperands() != C->getNumArgOperands()) {
+ if (!local_cdep ||
+ local_cdep->getNumArgOperands() != C->getNumArgOperands()) {
valueNumbering[C] = nextValueNumber;
return nextValueNumber++;
}
@@ -640,11 +640,11 @@ bool GVN::isLoadInLoopPREEnabled() const {
return Options.AllowLoadInLoopPRE.getValueOr(GVNEnableLoadInLoopPRE);
}
-bool GVN::isLoadPRESplitBackedgeEnabled() const {
- return Options.AllowLoadPRESplitBackedge.getValueOr(
- GVNEnableSplitBackedgeInLoadPRE);
-}
-
+bool GVN::isLoadPRESplitBackedgeEnabled() const {
+ return Options.AllowLoadPRESplitBackedge.getValueOr(
+ GVNEnableSplitBackedgeInLoadPRE);
+}
+
bool GVN::isMemDepEnabled() const {
return Options.AllowMemDep.getValueOr(GVNEnableMemDep);
}
@@ -661,18 +661,18 @@ PreservedAnalyses GVN::run(Function &F, FunctionAnalysisManager &AM) {
auto *MemDep =
isMemDepEnabled() ? &AM.getResult<MemoryDependenceAnalysis>(F) : nullptr;
auto *LI = AM.getCachedResult<LoopAnalysis>(F);
- auto *MSSA = AM.getCachedResult<MemorySSAAnalysis>(F);
+ auto *MSSA = AM.getCachedResult<MemorySSAAnalysis>(F);
auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
- bool Changed = runImpl(F, AC, DT, TLI, AA, MemDep, LI, &ORE,
- MSSA ? &MSSA->getMSSA() : nullptr);
+ bool Changed = runImpl(F, AC, DT, TLI, AA, MemDep, LI, &ORE,
+ MSSA ? &MSSA->getMSSA() : nullptr);
if (!Changed)
return PreservedAnalyses::all();
PreservedAnalyses PA;
PA.preserve<DominatorTreeAnalysis>();
PA.preserve<GlobalsAA>();
PA.preserve<TargetLibraryAnalysis>();
- if (MSSA)
- PA.preserve<MemorySSAAnalysis>();
+ if (MSSA)
+ PA.preserve<MemorySSAAnalysis>();
if (LI)
PA.preserve<LoopAnalysis>();
return PA;
@@ -690,18 +690,18 @@ LLVM_DUMP_METHOD void GVN::dump(DenseMap<uint32_t, Value*>& d) const {
}
#endif
-enum class AvailabilityState : char {
- /// We know the block *is not* fully available. This is a fixpoint.
- Unavailable = 0,
- /// We know the block *is* fully available. This is a fixpoint.
- Available = 1,
- /// We do not know whether the block is fully available or not,
- /// but we are currently speculating that it will be.
- /// If it would have turned out that the block was, in fact, not fully
- /// available, this would have been cleaned up into an Unavailable.
- SpeculativelyAvailable = 2,
-};
-
+enum class AvailabilityState : char {
+ /// We know the block *is not* fully available. This is a fixpoint.
+ Unavailable = 0,
+ /// We know the block *is* fully available. This is a fixpoint.
+ Available = 1,
+ /// We do not know whether the block is fully available or not,
+ /// but we are currently speculating that it will be.
+ /// If it would have turned out that the block was, in fact, not fully
+ /// available, this would have been cleaned up into an Unavailable.
+ SpeculativelyAvailable = 2,
+};
+
/// Return true if we can prove that the value
/// we're analyzing is fully available in the specified block. As we go, keep
/// track of which blocks we know are fully alive in FullyAvailableBlocks. This
@@ -710,118 +710,118 @@ enum class AvailabilityState : char {
/// 1) we know the block *is* fully available.
/// 2) we do not know whether the block is fully available or not, but we are
/// currently speculating that it will be.
-static bool IsValueFullyAvailableInBlock(
- BasicBlock *BB,
- DenseMap<BasicBlock *, AvailabilityState> &FullyAvailableBlocks) {
- SmallVector<BasicBlock *, 32> Worklist;
- Optional<BasicBlock *> UnavailableBB;
-
- // The number of times we didn't find an entry for a block in a map and
- // optimistically inserted an entry marking block as speculatively available.
- unsigned NumNewNewSpeculativelyAvailableBBs = 0;
-
-#ifndef NDEBUG
- SmallSet<BasicBlock *, 32> NewSpeculativelyAvailableBBs;
- SmallVector<BasicBlock *, 32> AvailableBBs;
-#endif
-
- Worklist.emplace_back(BB);
- while (!Worklist.empty()) {
- BasicBlock *CurrBB = Worklist.pop_back_val(); // LIFO - depth-first!
- // Optimistically assume that the block is Speculatively Available and check
- // to see if we already know about this block in one lookup.
- std::pair<DenseMap<BasicBlock *, AvailabilityState>::iterator, bool> IV =
- FullyAvailableBlocks.try_emplace(
- CurrBB, AvailabilityState::SpeculativelyAvailable);
- AvailabilityState &State = IV.first->second;
-
- // Did the entry already exist for this block?
- if (!IV.second) {
- if (State == AvailabilityState::Unavailable) {
- UnavailableBB = CurrBB;
- break; // Backpropagate unavailability info.
- }
-
-#ifndef NDEBUG
- AvailableBBs.emplace_back(CurrBB);
-#endif
- continue; // Don't recurse further, but continue processing worklist.
- }
-
- // No entry found for block.
- ++NumNewNewSpeculativelyAvailableBBs;
- bool OutOfBudget = NumNewNewSpeculativelyAvailableBBs > MaxBBSpeculations;
-
- // If we have exhausted our budget, mark this block as unavailable.
- // Also, if this block has no predecessors, the value isn't live-in here.
- if (OutOfBudget || pred_empty(CurrBB)) {
- MaxBBSpeculationCutoffReachedTimes += (int)OutOfBudget;
- State = AvailabilityState::Unavailable;
- UnavailableBB = CurrBB;
- break; // Backpropagate unavailability info.
- }
-
- // Tentatively consider this block as speculatively available.
-#ifndef NDEBUG
- NewSpeculativelyAvailableBBs.insert(CurrBB);
-#endif
- // And further recurse into block's predecessors, in depth-first order!
- Worklist.append(pred_begin(CurrBB), pred_end(CurrBB));
- }
-
-#if LLVM_ENABLE_STATS
- IsValueFullyAvailableInBlockNumSpeculationsMax.updateMax(
- NumNewNewSpeculativelyAvailableBBs);
-#endif
-
- // If the block isn't marked as fixpoint yet
- // (the Unavailable and Available states are fixpoints)
- auto MarkAsFixpointAndEnqueueSuccessors =
- [&](BasicBlock *BB, AvailabilityState FixpointState) {
- auto It = FullyAvailableBlocks.find(BB);
- if (It == FullyAvailableBlocks.end())
- return; // Never queried this block, leave as-is.
- switch (AvailabilityState &State = It->second) {
- case AvailabilityState::Unavailable:
- case AvailabilityState::Available:
- return; // Don't backpropagate further, continue processing worklist.
- case AvailabilityState::SpeculativelyAvailable: // Fix it!
- State = FixpointState;
-#ifndef NDEBUG
- assert(NewSpeculativelyAvailableBBs.erase(BB) &&
- "Found a speculatively available successor leftover?");
-#endif
- // Queue successors for further processing.
- Worklist.append(succ_begin(BB), succ_end(BB));
- return;
- }
- };
-
- if (UnavailableBB) {
- // Okay, we have encountered an unavailable block.
- // Mark speculatively available blocks reachable from UnavailableBB as
- // unavailable as well. Paths are terminated when they reach blocks not in
- // FullyAvailableBlocks or they are not marked as speculatively available.
- Worklist.clear();
- Worklist.append(succ_begin(*UnavailableBB), succ_end(*UnavailableBB));
- while (!Worklist.empty())
- MarkAsFixpointAndEnqueueSuccessors(Worklist.pop_back_val(),
- AvailabilityState::Unavailable);
- }
-
-#ifndef NDEBUG
- Worklist.clear();
- for (BasicBlock *AvailableBB : AvailableBBs)
- Worklist.append(succ_begin(AvailableBB), succ_end(AvailableBB));
- while (!Worklist.empty())
- MarkAsFixpointAndEnqueueSuccessors(Worklist.pop_back_val(),
- AvailabilityState::Available);
-
- assert(NewSpeculativelyAvailableBBs.empty() &&
- "Must have fixed all the new speculatively available blocks.");
-#endif
-
- return !UnavailableBB;
+static bool IsValueFullyAvailableInBlock(
+ BasicBlock *BB,
+ DenseMap<BasicBlock *, AvailabilityState> &FullyAvailableBlocks) {
+ SmallVector<BasicBlock *, 32> Worklist;
+ Optional<BasicBlock *> UnavailableBB;
+
+ // The number of times we didn't find an entry for a block in a map and
+ // optimistically inserted an entry marking block as speculatively available.
+ unsigned NumNewNewSpeculativelyAvailableBBs = 0;
+
+#ifndef NDEBUG
+ SmallSet<BasicBlock *, 32> NewSpeculativelyAvailableBBs;
+ SmallVector<BasicBlock *, 32> AvailableBBs;
+#endif
+
+ Worklist.emplace_back(BB);
+ while (!Worklist.empty()) {
+ BasicBlock *CurrBB = Worklist.pop_back_val(); // LIFO - depth-first!
+ // Optimistically assume that the block is Speculatively Available and check
+ // to see if we already know about this block in one lookup.
+ std::pair<DenseMap<BasicBlock *, AvailabilityState>::iterator, bool> IV =
+ FullyAvailableBlocks.try_emplace(
+ CurrBB, AvailabilityState::SpeculativelyAvailable);
+ AvailabilityState &State = IV.first->second;
+
+ // Did the entry already exist for this block?
+ if (!IV.second) {
+ if (State == AvailabilityState::Unavailable) {
+ UnavailableBB = CurrBB;
+ break; // Backpropagate unavailability info.
+ }
+
+#ifndef NDEBUG
+ AvailableBBs.emplace_back(CurrBB);
+#endif
+ continue; // Don't recurse further, but continue processing worklist.
+ }
+
+ // No entry found for block.
+ ++NumNewNewSpeculativelyAvailableBBs;
+ bool OutOfBudget = NumNewNewSpeculativelyAvailableBBs > MaxBBSpeculations;
+
+ // If we have exhausted our budget, mark this block as unavailable.
+ // Also, if this block has no predecessors, the value isn't live-in here.
+ if (OutOfBudget || pred_empty(CurrBB)) {
+ MaxBBSpeculationCutoffReachedTimes += (int)OutOfBudget;
+ State = AvailabilityState::Unavailable;
+ UnavailableBB = CurrBB;
+ break; // Backpropagate unavailability info.
+ }
+
+ // Tentatively consider this block as speculatively available.
+#ifndef NDEBUG
+ NewSpeculativelyAvailableBBs.insert(CurrBB);
+#endif
+ // And further recurse into block's predecessors, in depth-first order!
+ Worklist.append(pred_begin(CurrBB), pred_end(CurrBB));
+ }
+
+#if LLVM_ENABLE_STATS
+ IsValueFullyAvailableInBlockNumSpeculationsMax.updateMax(
+ NumNewNewSpeculativelyAvailableBBs);
+#endif
+
+ // If the block isn't marked as fixpoint yet
+ // (the Unavailable and Available states are fixpoints)
+ auto MarkAsFixpointAndEnqueueSuccessors =
+ [&](BasicBlock *BB, AvailabilityState FixpointState) {
+ auto It = FullyAvailableBlocks.find(BB);
+ if (It == FullyAvailableBlocks.end())
+ return; // Never queried this block, leave as-is.
+ switch (AvailabilityState &State = It->second) {
+ case AvailabilityState::Unavailable:
+ case AvailabilityState::Available:
+ return; // Don't backpropagate further, continue processing worklist.
+ case AvailabilityState::SpeculativelyAvailable: // Fix it!
+ State = FixpointState;
+#ifndef NDEBUG
+ assert(NewSpeculativelyAvailableBBs.erase(BB) &&
+ "Found a speculatively available successor leftover?");
+#endif
+ // Queue successors for further processing.
+ Worklist.append(succ_begin(BB), succ_end(BB));
+ return;
+ }
+ };
+
+ if (UnavailableBB) {
+ // Okay, we have encountered an unavailable block.
+ // Mark speculatively available blocks reachable from UnavailableBB as
+ // unavailable as well. Paths are terminated when they reach blocks not in
+ // FullyAvailableBlocks or they are not marked as speculatively available.
+ Worklist.clear();
+ Worklist.append(succ_begin(*UnavailableBB), succ_end(*UnavailableBB));
+ while (!Worklist.empty())
+ MarkAsFixpointAndEnqueueSuccessors(Worklist.pop_back_val(),
+ AvailabilityState::Unavailable);
+ }
+
+#ifndef NDEBUG
+ Worklist.clear();
+ for (BasicBlock *AvailableBB : AvailableBBs)
+ Worklist.append(succ_begin(AvailableBB), succ_end(AvailableBB));
+ while (!Worklist.empty())
+ MarkAsFixpointAndEnqueueSuccessors(Worklist.pop_back_val(),
+ AvailabilityState::Available);
+
+ assert(NewSpeculativelyAvailableBBs.empty() &&
+ "Must have fixed all the new speculatively available blocks.");
+#endif
+
+ return !UnavailableBB;
}
/// Given a set of loads specified by ValuesPerBlock,
@@ -1040,7 +1040,7 @@ bool GVN::AnalyzeLoadAvailability(LoadInst *LI, MemDepResult DepInfo,
if (StoreInst *S = dyn_cast<StoreInst>(DepInst)) {
// Reject loads and stores that are to the same address but are of
- // different types if we have to. If the stored value is convertable to
+ // different types if we have to. If the stored value is convertable to
// the loaded value, we can reuse it.
if (!canCoerceMustAliasedValueToLoad(S->getValueOperand(), LI->getType(),
DL))
@@ -1155,9 +1155,9 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,
// because if the index is out of bounds we should deoptimize rather than
// access the array.
// Check that there is no guard in this block above our instruction.
- bool MustEnsureSafetyOfSpeculativeExecution =
- ICF->isDominatedByICFIFromSameBlock(LI);
-
+ bool MustEnsureSafetyOfSpeculativeExecution =
+ ICF->isDominatedByICFIFromSameBlock(LI);
+
while (TmpBB->getSinglePredecessor()) {
TmpBB = TmpBB->getSinglePredecessor();
if (TmpBB == LoadBB) // Infinite (unreachable) loop.
@@ -1174,8 +1174,8 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,
return false;
// Check that there is no implicit control flow in a block above.
- MustEnsureSafetyOfSpeculativeExecution =
- MustEnsureSafetyOfSpeculativeExecution || ICF->hasICF(TmpBB);
+ MustEnsureSafetyOfSpeculativeExecution =
+ MustEnsureSafetyOfSpeculativeExecution || ICF->hasICF(TmpBB);
}
assert(TmpBB);
@@ -1184,11 +1184,11 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,
// Check to see how many predecessors have the loaded value fully
// available.
MapVector<BasicBlock *, Value *> PredLoads;
- DenseMap<BasicBlock *, AvailabilityState> FullyAvailableBlocks;
+ DenseMap<BasicBlock *, AvailabilityState> FullyAvailableBlocks;
for (const AvailableValueInBlock &AV : ValuesPerBlock)
- FullyAvailableBlocks[AV.BB] = AvailabilityState::Available;
+ FullyAvailableBlocks[AV.BB] = AvailabilityState::Available;
for (BasicBlock *UnavailableBB : UnavailableBlocks)
- FullyAvailableBlocks[UnavailableBB] = AvailabilityState::Unavailable;
+ FullyAvailableBlocks[UnavailableBB] = AvailabilityState::Unavailable;
SmallVector<BasicBlock *, 4> CriticalEdgePred;
for (BasicBlock *Pred : predecessors(LoadBB)) {
@@ -1201,7 +1201,7 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,
return false;
}
- if (IsValueFullyAvailableInBlock(Pred, FullyAvailableBlocks)) {
+ if (IsValueFullyAvailableInBlock(Pred, FullyAvailableBlocks)) {
continue;
}
@@ -1228,16 +1228,16 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,
return false;
}
- // Do not split backedge as it will break the canonical loop form.
- if (!isLoadPRESplitBackedgeEnabled())
- if (DT->dominates(LoadBB, Pred)) {
- LLVM_DEBUG(
- dbgs()
- << "COULD NOT PRE LOAD BECAUSE OF A BACKEDGE CRITICAL EDGE '"
- << Pred->getName() << "': " << *LI << '\n');
- return false;
- }
-
+ // Do not split backedge as it will break the canonical loop form.
+ if (!isLoadPRESplitBackedgeEnabled())
+ if (DT->dominates(LoadBB, Pred)) {
+ LLVM_DEBUG(
+ dbgs()
+ << "COULD NOT PRE LOAD BECAUSE OF A BACKEDGE CRITICAL EDGE '"
+ << Pred->getName() << "': " << *LI << '\n');
+ return false;
+ }
+
CriticalEdgePred.push_back(Pred);
} else {
// Only add the predecessors that will not be split for now.
@@ -1257,17 +1257,17 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,
if (NumUnavailablePreds != 1)
return false;
- // Now we know where we will insert load. We must ensure that it is safe
- // to speculatively execute the load at that points.
- if (MustEnsureSafetyOfSpeculativeExecution) {
- if (CriticalEdgePred.size())
- if (!isSafeToSpeculativelyExecute(LI, LoadBB->getFirstNonPHI(), DT))
- return false;
- for (auto &PL : PredLoads)
- if (!isSafeToSpeculativelyExecute(LI, PL.first->getTerminator(), DT))
- return false;
- }
-
+ // Now we know where we will insert load. We must ensure that it is safe
+ // to speculatively execute the load at that points.
+ if (MustEnsureSafetyOfSpeculativeExecution) {
+ if (CriticalEdgePred.size())
+ if (!isSafeToSpeculativelyExecute(LI, LoadBB->getFirstNonPHI(), DT))
+ return false;
+ for (auto &PL : PredLoads)
+ if (!isSafeToSpeculativelyExecute(LI, PL.first->getTerminator(), DT))
+ return false;
+ }
+
// Split critical edges, and update the unavailable predecessors accordingly.
for (BasicBlock *OrigPred : CriticalEdgePred) {
BasicBlock *NewPred = splitCriticalEdges(OrigPred, LoadBB);
@@ -1349,7 +1349,7 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,
// Instructions that have been inserted in predecessor(s) to materialize
// the load address do not retain their original debug locations. Doing
// so could lead to confusing (but correct) source attributions.
- I->updateLocationAfterHoist();
+ I->updateLocationAfterHoist();
// FIXME: We really _ought_ to insert these value numbers into their
// parent's availability map. However, in doing so, we risk getting into
@@ -1367,22 +1367,22 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,
LI->getAlign(), LI->getOrdering(), LI->getSyncScopeID(),
UnavailablePred->getTerminator());
NewLoad->setDebugLoc(LI->getDebugLoc());
- if (MSSAU) {
- auto *MSSA = MSSAU->getMemorySSA();
- // Get the defining access of the original load or use the load if it is a
- // MemoryDef (e.g. because it is volatile). The inserted loads are
- // guaranteed to load from the same definition.
- auto *LIAcc = MSSA->getMemoryAccess(LI);
- auto *DefiningAcc =
- isa<MemoryDef>(LIAcc) ? LIAcc : LIAcc->getDefiningAccess();
- auto *NewAccess = MSSAU->createMemoryAccessInBB(
- NewLoad, DefiningAcc, NewLoad->getParent(),
- MemorySSA::BeforeTerminator);
- if (auto *NewDef = dyn_cast<MemoryDef>(NewAccess))
- MSSAU->insertDef(NewDef, /*RenameUses=*/true);
- else
- MSSAU->insertUse(cast<MemoryUse>(NewAccess), /*RenameUses=*/true);
- }
+ if (MSSAU) {
+ auto *MSSA = MSSAU->getMemorySSA();
+ // Get the defining access of the original load or use the load if it is a
+ // MemoryDef (e.g. because it is volatile). The inserted loads are
+ // guaranteed to load from the same definition.
+ auto *LIAcc = MSSA->getMemoryAccess(LI);
+ auto *DefiningAcc =
+ isa<MemoryDef>(LIAcc) ? LIAcc : LIAcc->getDefiningAccess();
+ auto *NewAccess = MSSAU->createMemoryAccessInBB(
+ NewLoad, DefiningAcc, NewLoad->getParent(),
+ MemorySSA::BeforeTerminator);
+ if (auto *NewDef = dyn_cast<MemoryDef>(NewAccess))
+ MSSAU->insertDef(NewDef, /*RenameUses=*/true);
+ else
+ MSSAU->insertUse(cast<MemoryUse>(NewAccess), /*RenameUses=*/true);
+ }
// Transfer the old load's AA tags to the new load.
AAMDNodes Tags;
@@ -1470,14 +1470,14 @@ bool GVN::processNonLocalLoad(LoadInst *LI) {
return false;
}
- bool Changed = false;
+ bool Changed = false;
// If this load follows a GEP, see if we can PRE the indices before analyzing.
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(LI->getOperand(0))) {
for (GetElementPtrInst::op_iterator OI = GEP->idx_begin(),
OE = GEP->idx_end();
OI != OE; ++OI)
if (Instruction *I = dyn_cast<Instruction>(OI->get()))
- Changed |= performScalarPRE(I);
+ Changed |= performScalarPRE(I);
}
// Step 2: Analyze the availability of the load
@@ -1488,7 +1488,7 @@ bool GVN::processNonLocalLoad(LoadInst *LI) {
// If we have no predecessors that produce a known value for this load, exit
// early.
if (ValuesPerBlock.empty())
- return Changed;
+ return Changed;
// Step 3: Eliminate fully redundancy.
//
@@ -1520,12 +1520,12 @@ bool GVN::processNonLocalLoad(LoadInst *LI) {
// Step 4: Eliminate partial redundancy.
if (!isPREEnabled() || !isLoadPREEnabled())
- return Changed;
+ return Changed;
if (!isLoadInLoopPREEnabled() && this->LI &&
this->LI->getLoopFor(LI->getParent()))
- return Changed;
+ return Changed;
- return Changed || PerformLoadPRE(LI, ValuesPerBlock, UnavailableBlocks);
+ return Changed || PerformLoadPRE(LI, ValuesPerBlock, UnavailableBlocks);
}
static bool impliesEquivalanceIfTrue(CmpInst* Cmp) {
@@ -1600,40 +1600,40 @@ bool GVN::processAssumeIntrinsic(IntrinsicInst *IntrinsicI) {
// Insert a new store to null instruction before the load to indicate that
// this code is not reachable. FIXME: We could insert unreachable
// instruction directly because we can modify the CFG.
- auto *NewS = new StoreInst(UndefValue::get(Int8Ty),
- Constant::getNullValue(Int8Ty->getPointerTo()),
- IntrinsicI);
- if (MSSAU) {
- const MemoryUseOrDef *FirstNonDom = nullptr;
- const auto *AL =
- MSSAU->getMemorySSA()->getBlockAccesses(IntrinsicI->getParent());
-
- // If there are accesses in the current basic block, find the first one
- // that does not come before NewS. The new memory access is inserted
- // after the found access or before the terminator if no such access is
- // found.
- if (AL) {
- for (auto &Acc : *AL) {
- if (auto *Current = dyn_cast<MemoryUseOrDef>(&Acc))
- if (!Current->getMemoryInst()->comesBefore(NewS)) {
- FirstNonDom = Current;
- break;
- }
- }
- }
-
- // This added store is to null, so it will never executed and we can
- // just use the LiveOnEntry def as defining access.
- auto *NewDef =
- FirstNonDom ? MSSAU->createMemoryAccessBefore(
- NewS, MSSAU->getMemorySSA()->getLiveOnEntryDef(),
- const_cast<MemoryUseOrDef *>(FirstNonDom))
- : MSSAU->createMemoryAccessInBB(
- NewS, MSSAU->getMemorySSA()->getLiveOnEntryDef(),
- NewS->getParent(), MemorySSA::BeforeTerminator);
-
- MSSAU->insertDef(cast<MemoryDef>(NewDef), /*RenameUses=*/false);
- }
+ auto *NewS = new StoreInst(UndefValue::get(Int8Ty),
+ Constant::getNullValue(Int8Ty->getPointerTo()),
+ IntrinsicI);
+ if (MSSAU) {
+ const MemoryUseOrDef *FirstNonDom = nullptr;
+ const auto *AL =
+ MSSAU->getMemorySSA()->getBlockAccesses(IntrinsicI->getParent());
+
+ // If there are accesses in the current basic block, find the first one
+ // that does not come before NewS. The new memory access is inserted
+ // after the found access or before the terminator if no such access is
+ // found.
+ if (AL) {
+ for (auto &Acc : *AL) {
+ if (auto *Current = dyn_cast<MemoryUseOrDef>(&Acc))
+ if (!Current->getMemoryInst()->comesBefore(NewS)) {
+ FirstNonDom = Current;
+ break;
+ }
+ }
+ }
+
+ // This added store is to null, so it will never executed and we can
+ // just use the LiveOnEntry def as defining access.
+ auto *NewDef =
+ FirstNonDom ? MSSAU->createMemoryAccessBefore(
+ NewS, MSSAU->getMemorySSA()->getLiveOnEntryDef(),
+ const_cast<MemoryUseOrDef *>(FirstNonDom))
+ : MSSAU->createMemoryAccessInBB(
+ NewS, MSSAU->getMemorySSA()->getLiveOnEntryDef(),
+ NewS->getParent(), MemorySSA::BeforeTerminator);
+
+ MSSAU->insertDef(cast<MemoryDef>(NewDef), /*RenameUses=*/false);
+ }
}
if (isAssumeWithEmptyBundle(*IntrinsicI))
markInstructionForDeletion(IntrinsicI);
@@ -1661,11 +1661,11 @@ bool GVN::processAssumeIntrinsic(IntrinsicInst *IntrinsicI) {
// br i1 %cmp, label %bb1, label %bb2 ; will change %cmp to true
ReplaceOperandsWithMap[V] = True;
- // Similarly, after assume(!NotV) we know that NotV == false.
- Value *NotV;
- if (match(V, m_Not(m_Value(NotV))))
- ReplaceOperandsWithMap[NotV] = ConstantInt::getFalse(V->getContext());
-
+ // Similarly, after assume(!NotV) we know that NotV == false.
+ Value *NotV;
+ if (match(V, m_Not(m_Value(NotV))))
+ ReplaceOperandsWithMap[NotV] = ConstantInt::getFalse(V->getContext());
+
// If we find an equality fact, canonicalize all dominated uses in this block
// to one of the two values. We heuristically choice the "oldest" of the
// two where age is determined by value number. (Note that propagateEquality
@@ -1772,8 +1772,8 @@ bool GVN::processLoad(LoadInst *L) {
// Replace the load!
patchAndReplaceAllUsesWith(L, AvailableValue);
markInstructionForDeletion(L);
- if (MSSAU)
- MSSAU->removeMemoryAccess(L);
+ if (MSSAU)
+ MSSAU->removeMemoryAccess(L);
++NumGVNLoad;
reportLoadElim(L, AvailableValue, ORE);
// Tell MDA to rexamine the reused pointer since we might have more
@@ -1895,7 +1895,7 @@ uint32_t GVN::ValueTable::phiTranslateImpl(const BasicBlock *Pred,
}
if (Exp.commutative) {
- assert(Exp.varargs.size() >= 2 && "Unsupported commutative instruction!");
+ assert(Exp.varargs.size() >= 2 && "Unsupported commutative instruction!");
if (Exp.varargs[0] > Exp.varargs[1]) {
std::swap(Exp.varargs[0], Exp.varargs[1]);
uint32_t Opcode = Exp.opcode >> 8;
@@ -1918,8 +1918,8 @@ uint32_t GVN::ValueTable::phiTranslateImpl(const BasicBlock *Pred,
/// again.
void GVN::ValueTable::eraseTranslateCacheEntry(uint32_t Num,
const BasicBlock &CurrBlock) {
- for (const BasicBlock *Pred : predecessors(&CurrBlock))
- PhiTranslateTable.erase({Num, Pred});
+ for (const BasicBlock *Pred : predecessors(&CurrBlock))
+ PhiTranslateTable.erase({Num, Pred});
}
// In order to find a leader for a given value number at a
@@ -2083,8 +2083,8 @@ bool GVN::propagateEquality(Value *LHS, Value *RHS, const BasicBlockEdge &Root,
// If "A && B" is known true then both A and B are known true. If "A || B"
// is known false then both A and B are known false.
Value *A, *B;
- if ((isKnownTrue && match(LHS, m_LogicalAnd(m_Value(A), m_Value(B)))) ||
- (isKnownFalse && match(LHS, m_LogicalOr(m_Value(A), m_Value(B))))) {
+ if ((isKnownTrue && match(LHS, m_LogicalAnd(m_Value(A), m_Value(B)))) ||
+ (isKnownFalse && match(LHS, m_LogicalOr(m_Value(A), m_Value(B))))) {
Worklist.push_back(std::make_pair(A, RHS));
Worklist.push_back(std::make_pair(B, RHS));
continue;
@@ -2286,7 +2286,7 @@ bool GVN::processInstruction(Instruction *I) {
bool GVN::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
const TargetLibraryInfo &RunTLI, AAResults &RunAA,
MemoryDependenceResults *RunMD, LoopInfo *LI,
- OptimizationRemarkEmitter *RunORE, MemorySSA *MSSA) {
+ OptimizationRemarkEmitter *RunORE, MemorySSA *MSSA) {
AC = &RunAC;
DT = &RunDT;
VN.setDomTree(DT);
@@ -2299,8 +2299,8 @@ bool GVN::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
VN.setMemDep(MD);
ORE = RunORE;
InvalidBlockRPONumbers = true;
- MemorySSAUpdater Updater(MSSA);
- MSSAU = MSSA ? &Updater : nullptr;
+ MemorySSAUpdater Updater(MSSA);
+ MSSAU = MSSA ? &Updater : nullptr;
bool Changed = false;
bool ShouldContinue = true;
@@ -2311,7 +2311,7 @@ bool GVN::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ) {
BasicBlock *BB = &*FI++;
- bool removedBlock = MergeBlockIntoPredecessor(BB, &DTU, LI, MSSAU, MD);
+ bool removedBlock = MergeBlockIntoPredecessor(BB, &DTU, LI, MSSAU, MD);
if (removedBlock)
++NumGVNBlocks;
@@ -2347,9 +2347,9 @@ bool GVN::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
// iteration.
DeadBlocks.clear();
- if (MSSA && VerifyMemorySSA)
- MSSA->verifyMemorySSA();
-
+ if (MSSA && VerifyMemorySSA)
+ MSSA->verifyMemorySSA();
+
return Changed;
}
@@ -2390,8 +2390,8 @@ bool GVN::processBlock(BasicBlock *BB) {
salvageKnowledge(I, AC);
salvageDebugInfo(*I);
if (MD) MD->removeInstruction(I);
- if (MSSAU)
- MSSAU->removeMemoryAccess(I);
+ if (MSSAU)
+ MSSAU->removeMemoryAccess(I);
LLVM_DEBUG(verifyRemoved(I));
ICF->removeInstruction(I);
I->eraseFromParent();
@@ -2479,14 +2479,14 @@ bool GVN::performScalarPRE(Instruction *CurInst) {
if (isa<GetElementPtrInst>(CurInst))
return false;
- if (auto *CallB = dyn_cast<CallBase>(CurInst)) {
- // We don't currently value number ANY inline asm calls.
+ if (auto *CallB = dyn_cast<CallBase>(CurInst)) {
+ // We don't currently value number ANY inline asm calls.
if (CallB->isInlineAsm())
return false;
- // Don't do PRE on convergent calls.
- if (CallB->isConvergent())
- return false;
- }
+ // Don't do PRE on convergent calls.
+ if (CallB->isConvergent())
+ return false;
+ }
uint32_t ValNo = VN.lookup(CurInst);
@@ -2626,8 +2626,8 @@ bool GVN::performScalarPRE(Instruction *CurInst) {
LLVM_DEBUG(dbgs() << "GVN PRE removed: " << *CurInst << '\n');
if (MD)
MD->removeInstruction(CurInst);
- if (MSSAU)
- MSSAU->removeMemoryAccess(CurInst);
+ if (MSSAU)
+ MSSAU->removeMemoryAccess(CurInst);
LLVM_DEBUG(verifyRemoved(CurInst));
// FIXME: Intended to be markInstructionForDeletion(CurInst), but it causes
// some assertion failures.
@@ -2672,12 +2672,12 @@ BasicBlock *GVN::splitCriticalEdges(BasicBlock *Pred, BasicBlock *Succ) {
// possible.
BasicBlock *BB = SplitCriticalEdge(
Pred, Succ,
- CriticalEdgeSplittingOptions(DT, LI, MSSAU).unsetPreserveLoopSimplify());
- if (BB) {
- if (MD)
- MD->invalidateCachedPredecessors();
- InvalidBlockRPONumbers = true;
- }
+ CriticalEdgeSplittingOptions(DT, LI, MSSAU).unsetPreserveLoopSimplify());
+ if (BB) {
+ if (MD)
+ MD->invalidateCachedPredecessors();
+ InvalidBlockRPONumbers = true;
+ }
return BB;
}
@@ -2686,20 +2686,20 @@ BasicBlock *GVN::splitCriticalEdges(BasicBlock *Pred, BasicBlock *Succ) {
bool GVN::splitCriticalEdges() {
if (toSplit.empty())
return false;
-
- bool Changed = false;
+
+ bool Changed = false;
do {
std::pair<Instruction *, unsigned> Edge = toSplit.pop_back_val();
- Changed |= SplitCriticalEdge(Edge.first, Edge.second,
- CriticalEdgeSplittingOptions(DT, LI, MSSAU)) !=
- nullptr;
+ Changed |= SplitCriticalEdge(Edge.first, Edge.second,
+ CriticalEdgeSplittingOptions(DT, LI, MSSAU)) !=
+ nullptr;
} while (!toSplit.empty());
- if (Changed) {
- if (MD)
- MD->invalidateCachedPredecessors();
- InvalidBlockRPONumbers = true;
- }
- return Changed;
+ if (Changed) {
+ if (MD)
+ MD->invalidateCachedPredecessors();
+ InvalidBlockRPONumbers = true;
+ }
+ return Changed;
}
/// Executes one iteration of GVN
@@ -2803,12 +2803,12 @@ void GVN::addDeadBlock(BasicBlock *BB) {
// First, split the critical edges. This might also create additional blocks
// to preserve LoopSimplify form and adjust edges accordingly.
- SmallVector<BasicBlock *, 4> Preds(predecessors(B));
+ SmallVector<BasicBlock *, 4> Preds(predecessors(B));
for (BasicBlock *P : Preds) {
if (!DeadBlocks.count(P))
continue;
- if (llvm::is_contained(successors(P), B) &&
+ if (llvm::is_contained(successors(P), B) &&
isCriticalEdge(P->getTerminator(), B)) {
if (BasicBlock *S = splitCriticalEdges(P, B))
DeadBlocks.insert(P = S);
@@ -2893,7 +2893,7 @@ public:
auto *LIWP = getAnalysisIfAvailable<LoopInfoWrapperPass>();
- auto *MSSAWP = getAnalysisIfAvailable<MemorySSAWrapperPass>();
+ auto *MSSAWP = getAnalysisIfAvailable<MemorySSAWrapperPass>();
return Impl.runImpl(
F, getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F),
getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
@@ -2903,8 +2903,8 @@ public:
? &getAnalysis<MemoryDependenceWrapperPass>().getMemDep()
: nullptr,
LIWP ? &LIWP->getLoopInfo() : nullptr,
- &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE(),
- MSSAWP ? &MSSAWP->getMSSA() : nullptr);
+ &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE(),
+ MSSAWP ? &MSSAWP->getMSSA() : nullptr);
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -2920,7 +2920,7 @@ public:
AU.addPreserved<TargetLibraryInfoWrapperPass>();
AU.addPreserved<LoopInfoWrapperPass>();
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
- AU.addPreserved<MemorySSAWrapperPass>();
+ AU.addPreserved<MemorySSAWrapperPass>();
}
private:
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/GVNHoist.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/GVNHoist.cpp
index 14f438c2c8..8d0bd56749 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/GVNHoist.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/GVNHoist.cpp
@@ -242,14 +242,14 @@ public:
};
static void combineKnownMetadata(Instruction *ReplInst, Instruction *I) {
- static const unsigned KnownIDs[] = {LLVMContext::MD_tbaa,
- LLVMContext::MD_alias_scope,
- LLVMContext::MD_noalias,
- LLVMContext::MD_range,
- LLVMContext::MD_fpmath,
- LLVMContext::MD_invariant_load,
- LLVMContext::MD_invariant_group,
- LLVMContext::MD_access_group};
+ static const unsigned KnownIDs[] = {LLVMContext::MD_tbaa,
+ LLVMContext::MD_alias_scope,
+ LLVMContext::MD_noalias,
+ LLVMContext::MD_range,
+ LLVMContext::MD_fpmath,
+ LLVMContext::MD_invariant_load,
+ LLVMContext::MD_invariant_group,
+ LLVMContext::MD_access_group};
combineMetadata(ReplInst, I, KnownIDs, true);
}
@@ -263,7 +263,7 @@ public:
: DT(DT), PDT(PDT), AA(AA), MD(MD), MSSA(MSSA),
MSSAUpdater(std::make_unique<MemorySSAUpdater>(MSSA)) {}
- bool run(Function &F);
+ bool run(Function &F);
// Copied from NewGVN.cpp
// This function provides global ranking of operations so that we can place
@@ -271,7 +271,7 @@ public:
// for a complete ordering, as constants all have the same rank. However,
// generally, we will simplify an operation with all constants so that it
// doesn't matter what order they appear in.
- unsigned int rank(const Value *V) const;
+ unsigned int rank(const Value *V) const;
private:
GVN::ValueTable VN;
@@ -291,7 +291,7 @@ private:
enum InsKind { Unknown, Scalar, Load, Store };
// Return true when there are exception handling in BB.
- bool hasEH(const BasicBlock *BB);
+ bool hasEH(const BasicBlock *BB);
// Return true when I1 appears before I2 in the instructions of BB.
bool firstInBB(const Instruction *I1, const Instruction *I2) {
@@ -304,10 +304,10 @@ private:
// Return true when there are memory uses of Def in BB.
bool hasMemoryUse(const Instruction *NewPt, MemoryDef *Def,
- const BasicBlock *BB);
+ const BasicBlock *BB);
bool hasEHhelper(const BasicBlock *BB, const BasicBlock *SrcBB,
- int &NBBsOnAllPaths);
+ int &NBBsOnAllPaths);
// Return true when there are exception handling or loads of memory Def
// between Def and NewPt. This function is only called for stores: Def is
@@ -317,19 +317,19 @@ private:
// return true when the counter NBBsOnAllPaths reaces 0, except when it is
// initialized to -1 which is unlimited.
bool hasEHOrLoadsOnPath(const Instruction *NewPt, MemoryDef *Def,
- int &NBBsOnAllPaths);
+ int &NBBsOnAllPaths);
// Return true when there are exception handling between HoistPt and BB.
// Decrement by 1 NBBsOnAllPaths for each block between HoistPt and BB, and
// return true when the counter NBBsOnAllPaths reaches 0, except when it is
// initialized to -1 which is unlimited.
bool hasEHOnPath(const BasicBlock *HoistPt, const BasicBlock *SrcBB,
- int &NBBsOnAllPaths);
+ int &NBBsOnAllPaths);
// Return true when it is safe to hoist a memory load or store U from OldPt
// to NewPt.
bool safeToHoistLdSt(const Instruction *NewPt, const Instruction *OldPt,
- MemoryUseOrDef *U, InsKind K, int &NBBsOnAllPaths);
+ MemoryUseOrDef *U, InsKind K, int &NBBsOnAllPaths);
// Return true when it is safe to hoist scalar instructions from all blocks in
// WL to HoistBB.
@@ -352,21 +352,21 @@ private:
// Returns the edge via which an instruction in BB will get the values from.
// Returns true when the values are flowing out to each edge.
- bool valueAnticipable(CHIArgs C, Instruction *TI) const;
+ bool valueAnticipable(CHIArgs C, Instruction *TI) const;
// Check if it is safe to hoist values tracked by CHI in the range
// [Begin, End) and accumulate them in Safe.
void checkSafety(CHIArgs C, BasicBlock *BB, InsKind K,
- SmallVectorImpl<CHIArg> &Safe);
+ SmallVectorImpl<CHIArg> &Safe);
using RenameStackType = DenseMap<VNType, SmallVector<Instruction *, 2>>;
// Push all the VNs corresponding to BB into RenameStack.
void fillRenameStack(BasicBlock *BB, InValuesType &ValueBBs,
- RenameStackType &RenameStack);
+ RenameStackType &RenameStack);
void fillChiArgs(BasicBlock *BB, OutValuesType &CHIBBs,
- RenameStackType &RenameStack);
+ RenameStackType &RenameStack);
// Walk the post-dominator tree top-down and use a stack for each value to
// store the last value you see. When you hit a CHI from a given edge, the
@@ -396,7 +396,7 @@ private:
// they form a list of anticipable values. OutValues contains CHIs
// corresponding to each basic block.
void findHoistableCandidates(OutValuesType &CHIBBs, InsKind K,
- HoistingPointList &HPL);
+ HoistingPointList &HPL);
// Compute insertion points for each values which can be fully anticipated at
// a dominator. HPL contains all such values.
@@ -454,14 +454,14 @@ private:
}
// Insert empty CHI node for this VN. This is used to factor out
// basic blocks where the ANTIC can potentially change.
- CHIArg EmptyChi = {VN, nullptr, nullptr};
- for (auto *IDFBB : IDFBlocks) {
+ CHIArg EmptyChi = {VN, nullptr, nullptr};
+ for (auto *IDFBB : IDFBlocks) {
for (unsigned i = 0; i < V.size(); ++i) {
- // Ignore spurious PDFs.
- if (DT->properlyDominates(IDFBB, V[i]->getParent())) {
- OutValue[IDFBB].push_back(EmptyChi);
- LLVM_DEBUG(dbgs() << "\nInserting a CHI for BB: "
- << IDFBB->getName() << ", for Insn: " << *V[i]);
+ // Ignore spurious PDFs.
+ if (DT->properlyDominates(IDFBB, V[i]->getParent())) {
+ OutValue[IDFBB].push_back(EmptyChi);
+ LLVM_DEBUG(dbgs() << "\nInserting a CHI for BB: "
+ << IDFBB->getName() << ", for Insn: " << *V[i]);
}
}
}
@@ -479,755 +479,755 @@ private:
// a load without hoisting its access function. So before hoisting any
// expression, make sure that all its operands are available at insert point.
bool allOperandsAvailable(const Instruction *I,
- const BasicBlock *HoistPt) const;
+ const BasicBlock *HoistPt) const;
// Same as allOperandsAvailable with recursive check for GEP operands.
bool allGepOperandsAvailable(const Instruction *I,
- const BasicBlock *HoistPt) const;
+ const BasicBlock *HoistPt) const;
// Make all operands of the GEP available.
void makeGepsAvailable(Instruction *Repl, BasicBlock *HoistPt,
const SmallVecInsn &InstructionsToHoist,
- Instruction *Gep) const;
-
- void updateAlignment(Instruction *I, Instruction *Repl);
-
- // Remove all the instructions in Candidates and replace their usage with
- // Repl. Returns the number of instructions removed.
- unsigned rauw(const SmallVecInsn &Candidates, Instruction *Repl,
- MemoryUseOrDef *NewMemAcc);
-
- // Replace all Memory PHI usage with NewMemAcc.
- void raMPHIuw(MemoryUseOrDef *NewMemAcc);
-
- // Remove all other instructions and replace them with Repl.
- unsigned removeAndReplace(const SmallVecInsn &Candidates, Instruction *Repl,
- BasicBlock *DestBB, bool MoveAccess);
-
- // In the case Repl is a load or a store, we make all their GEPs
- // available: GEPs are not hoisted by default to avoid the address
- // computations to be hoisted without the associated load or store.
- bool makeGepOperandsAvailable(Instruction *Repl, BasicBlock *HoistPt,
- const SmallVecInsn &InstructionsToHoist) const;
-
- std::pair<unsigned, unsigned> hoist(HoistingPointList &HPL);
-
- // Hoist all expressions. Returns Number of scalars hoisted
- // and number of non-scalars hoisted.
- std::pair<unsigned, unsigned> hoistExpressions(Function &F);
-};
-
-class GVNHoistLegacyPass : public FunctionPass {
-public:
- static char ID;
-
- GVNHoistLegacyPass() : FunctionPass(ID) {
- initializeGVNHoistLegacyPassPass(*PassRegistry::getPassRegistry());
- }
-
- bool runOnFunction(Function &F) override {
- if (skipFunction(F))
- return false;
- auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- auto &PDT = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
- auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
- auto &MD = getAnalysis<MemoryDependenceWrapperPass>().getMemDep();
- auto &MSSA = getAnalysis<MemorySSAWrapperPass>().getMSSA();
-
- GVNHoist G(&DT, &PDT, &AA, &MD, &MSSA);
- return G.run(F);
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<DominatorTreeWrapperPass>();
- AU.addRequired<PostDominatorTreeWrapperPass>();
- AU.addRequired<AAResultsWrapperPass>();
- AU.addRequired<MemoryDependenceWrapperPass>();
- AU.addRequired<MemorySSAWrapperPass>();
- AU.addPreserved<DominatorTreeWrapperPass>();
- AU.addPreserved<MemorySSAWrapperPass>();
- AU.addPreserved<GlobalsAAWrapperPass>();
- }
-};
-
-bool GVNHoist::run(Function &F) {
- NumFuncArgs = F.arg_size();
- VN.setDomTree(DT);
- VN.setAliasAnalysis(AA);
- VN.setMemDep(MD);
- bool Res = false;
- // Perform DFS Numbering of instructions.
- unsigned BBI = 0;
- for (const BasicBlock *BB : depth_first(&F.getEntryBlock())) {
- DFSNumber[BB] = ++BBI;
- unsigned I = 0;
- for (auto &Inst : *BB)
- DFSNumber[&Inst] = ++I;
- }
-
- int ChainLength = 0;
-
- // FIXME: use lazy evaluation of VN to avoid the fix-point computation.
- while (true) {
- if (MaxChainLength != -1 && ++ChainLength >= MaxChainLength)
- return Res;
-
- auto HoistStat = hoistExpressions(F);
- if (HoistStat.first + HoistStat.second == 0)
- return Res;
-
- if (HoistStat.second > 0)
- // To address a limitation of the current GVN, we need to rerun the
- // hoisting after we hoisted loads or stores in order to be able to
- // hoist all scalars dependent on the hoisted ld/st.
- VN.clear();
-
- Res = true;
- }
-
- return Res;
-}
-
-unsigned int GVNHoist::rank(const Value *V) const {
- // Prefer constants to undef to anything else
- // Undef is a constant, have to check it first.
- // Prefer smaller constants to constantexprs
- if (isa<ConstantExpr>(V))
- return 2;
- if (isa<UndefValue>(V))
- return 1;
- if (isa<Constant>(V))
- return 0;
- else if (auto *A = dyn_cast<Argument>(V))
- return 3 + A->getArgNo();
-
- // Need to shift the instruction DFS by number of arguments + 3 to account
- // for the constant and argument ranking above.
- auto Result = DFSNumber.lookup(V);
- if (Result > 0)
- return 4 + NumFuncArgs + Result;
- // Unreachable or something else, just return a really large number.
- return ~0;
-}
-
-bool GVNHoist::hasEH(const BasicBlock *BB) {
- auto It = BBSideEffects.find(BB);
- if (It != BBSideEffects.end())
- return It->second;
-
- if (BB->isEHPad() || BB->hasAddressTaken()) {
- BBSideEffects[BB] = true;
- return true;
- }
-
- if (BB->getTerminator()->mayThrow()) {
- BBSideEffects[BB] = true;
- return true;
- }
-
- BBSideEffects[BB] = false;
- return false;
-}
-
-bool GVNHoist::hasMemoryUse(const Instruction *NewPt, MemoryDef *Def,
- const BasicBlock *BB) {
- const MemorySSA::AccessList *Acc = MSSA->getBlockAccesses(BB);
- if (!Acc)
- return false;
-
- Instruction *OldPt = Def->getMemoryInst();
- const BasicBlock *OldBB = OldPt->getParent();
- const BasicBlock *NewBB = NewPt->getParent();
- bool ReachedNewPt = false;
-
- for (const MemoryAccess &MA : *Acc)
- if (const MemoryUse *MU = dyn_cast<MemoryUse>(&MA)) {
- Instruction *Insn = MU->getMemoryInst();
-
- // Do not check whether MU aliases Def when MU occurs after OldPt.
- if (BB == OldBB && firstInBB(OldPt, Insn))
- break;
-
- // Do not check whether MU aliases Def when MU occurs before NewPt.
- if (BB == NewBB) {
- if (!ReachedNewPt) {
- if (firstInBB(Insn, NewPt))
- continue;
- ReachedNewPt = true;
- }
+ Instruction *Gep) const;
+
+ void updateAlignment(Instruction *I, Instruction *Repl);
+
+ // Remove all the instructions in Candidates and replace their usage with
+ // Repl. Returns the number of instructions removed.
+ unsigned rauw(const SmallVecInsn &Candidates, Instruction *Repl,
+ MemoryUseOrDef *NewMemAcc);
+
+ // Replace all Memory PHI usage with NewMemAcc.
+ void raMPHIuw(MemoryUseOrDef *NewMemAcc);
+
+ // Remove all other instructions and replace them with Repl.
+ unsigned removeAndReplace(const SmallVecInsn &Candidates, Instruction *Repl,
+ BasicBlock *DestBB, bool MoveAccess);
+
+ // In the case Repl is a load or a store, we make all their GEPs
+ // available: GEPs are not hoisted by default to avoid the address
+ // computations to be hoisted without the associated load or store.
+ bool makeGepOperandsAvailable(Instruction *Repl, BasicBlock *HoistPt,
+ const SmallVecInsn &InstructionsToHoist) const;
+
+ std::pair<unsigned, unsigned> hoist(HoistingPointList &HPL);
+
+ // Hoist all expressions. Returns Number of scalars hoisted
+ // and number of non-scalars hoisted.
+ std::pair<unsigned, unsigned> hoistExpressions(Function &F);
+};
+
+class GVNHoistLegacyPass : public FunctionPass {
+public:
+ static char ID;
+
+ GVNHoistLegacyPass() : FunctionPass(ID) {
+ initializeGVNHoistLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool runOnFunction(Function &F) override {
+ if (skipFunction(F))
+ return false;
+ auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ auto &PDT = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
+ auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
+ auto &MD = getAnalysis<MemoryDependenceWrapperPass>().getMemDep();
+ auto &MSSA = getAnalysis<MemorySSAWrapperPass>().getMSSA();
+
+ GVNHoist G(&DT, &PDT, &AA, &MD, &MSSA);
+ return G.run(F);
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<DominatorTreeWrapperPass>();
+ AU.addRequired<PostDominatorTreeWrapperPass>();
+ AU.addRequired<AAResultsWrapperPass>();
+ AU.addRequired<MemoryDependenceWrapperPass>();
+ AU.addRequired<MemorySSAWrapperPass>();
+ AU.addPreserved<DominatorTreeWrapperPass>();
+ AU.addPreserved<MemorySSAWrapperPass>();
+ AU.addPreserved<GlobalsAAWrapperPass>();
+ }
+};
+
+bool GVNHoist::run(Function &F) {
+ NumFuncArgs = F.arg_size();
+ VN.setDomTree(DT);
+ VN.setAliasAnalysis(AA);
+ VN.setMemDep(MD);
+ bool Res = false;
+ // Perform DFS Numbering of instructions.
+ unsigned BBI = 0;
+ for (const BasicBlock *BB : depth_first(&F.getEntryBlock())) {
+ DFSNumber[BB] = ++BBI;
+ unsigned I = 0;
+ for (auto &Inst : *BB)
+ DFSNumber[&Inst] = ++I;
+ }
+
+ int ChainLength = 0;
+
+ // FIXME: use lazy evaluation of VN to avoid the fix-point computation.
+ while (true) {
+ if (MaxChainLength != -1 && ++ChainLength >= MaxChainLength)
+ return Res;
+
+ auto HoistStat = hoistExpressions(F);
+ if (HoistStat.first + HoistStat.second == 0)
+ return Res;
+
+ if (HoistStat.second > 0)
+ // To address a limitation of the current GVN, we need to rerun the
+ // hoisting after we hoisted loads or stores in order to be able to
+ // hoist all scalars dependent on the hoisted ld/st.
+ VN.clear();
+
+ Res = true;
+ }
+
+ return Res;
+}
+
+unsigned int GVNHoist::rank(const Value *V) const {
+ // Prefer constants to undef to anything else
+ // Undef is a constant, have to check it first.
+ // Prefer smaller constants to constantexprs
+ if (isa<ConstantExpr>(V))
+ return 2;
+ if (isa<UndefValue>(V))
+ return 1;
+ if (isa<Constant>(V))
+ return 0;
+ else if (auto *A = dyn_cast<Argument>(V))
+ return 3 + A->getArgNo();
+
+ // Need to shift the instruction DFS by number of arguments + 3 to account
+ // for the constant and argument ranking above.
+ auto Result = DFSNumber.lookup(V);
+ if (Result > 0)
+ return 4 + NumFuncArgs + Result;
+ // Unreachable or something else, just return a really large number.
+ return ~0;
+}
+
+bool GVNHoist::hasEH(const BasicBlock *BB) {
+ auto It = BBSideEffects.find(BB);
+ if (It != BBSideEffects.end())
+ return It->second;
+
+ if (BB->isEHPad() || BB->hasAddressTaken()) {
+ BBSideEffects[BB] = true;
+ return true;
+ }
+
+ if (BB->getTerminator()->mayThrow()) {
+ BBSideEffects[BB] = true;
+ return true;
+ }
+
+ BBSideEffects[BB] = false;
+ return false;
+}
+
+bool GVNHoist::hasMemoryUse(const Instruction *NewPt, MemoryDef *Def,
+ const BasicBlock *BB) {
+ const MemorySSA::AccessList *Acc = MSSA->getBlockAccesses(BB);
+ if (!Acc)
+ return false;
+
+ Instruction *OldPt = Def->getMemoryInst();
+ const BasicBlock *OldBB = OldPt->getParent();
+ const BasicBlock *NewBB = NewPt->getParent();
+ bool ReachedNewPt = false;
+
+ for (const MemoryAccess &MA : *Acc)
+ if (const MemoryUse *MU = dyn_cast<MemoryUse>(&MA)) {
+ Instruction *Insn = MU->getMemoryInst();
+
+ // Do not check whether MU aliases Def when MU occurs after OldPt.
+ if (BB == OldBB && firstInBB(OldPt, Insn))
+ break;
+
+ // Do not check whether MU aliases Def when MU occurs before NewPt.
+ if (BB == NewBB) {
+ if (!ReachedNewPt) {
+ if (firstInBB(Insn, NewPt))
+ continue;
+ ReachedNewPt = true;
+ }
}
- if (MemorySSAUtil::defClobbersUseOrDef(Def, MU, *AA))
- return true;
- }
-
- return false;
-}
-
-bool GVNHoist::hasEHhelper(const BasicBlock *BB, const BasicBlock *SrcBB,
- int &NBBsOnAllPaths) {
- // Stop walk once the limit is reached.
- if (NBBsOnAllPaths == 0)
- return true;
-
- // Impossible to hoist with exceptions on the path.
- if (hasEH(BB))
- return true;
-
- // No such instruction after HoistBarrier in a basic block was
- // selected for hoisting so instructions selected within basic block with
- // a hoist barrier can be hoisted.
- if ((BB != SrcBB) && HoistBarrier.count(BB))
- return true;
-
- return false;
-}
-
-bool GVNHoist::hasEHOrLoadsOnPath(const Instruction *NewPt, MemoryDef *Def,
- int &NBBsOnAllPaths) {
- const BasicBlock *NewBB = NewPt->getParent();
- const BasicBlock *OldBB = Def->getBlock();
- assert(DT->dominates(NewBB, OldBB) && "invalid path");
- assert(DT->dominates(Def->getDefiningAccess()->getBlock(), NewBB) &&
- "def does not dominate new hoisting point");
-
- // Walk all basic blocks reachable in depth-first iteration on the inverse
- // CFG from OldBB to NewBB. These blocks are all the blocks that may be
- // executed between the execution of NewBB and OldBB. Hoisting an expression
- // from OldBB into NewBB has to be safe on all execution paths.
- for (auto I = idf_begin(OldBB), E = idf_end(OldBB); I != E;) {
- const BasicBlock *BB = *I;
- if (BB == NewBB) {
- // Stop traversal when reaching HoistPt.
- I.skipChildren();
- continue;
+ if (MemorySSAUtil::defClobbersUseOrDef(Def, MU, *AA))
+ return true;
}
- if (hasEHhelper(BB, OldBB, NBBsOnAllPaths))
- return true;
-
- // Check that we do not move a store past loads.
- if (hasMemoryUse(NewPt, Def, BB))
- return true;
-
- // -1 is unlimited number of blocks on all paths.
- if (NBBsOnAllPaths != -1)
- --NBBsOnAllPaths;
-
- ++I;
+ return false;
+}
+
+bool GVNHoist::hasEHhelper(const BasicBlock *BB, const BasicBlock *SrcBB,
+ int &NBBsOnAllPaths) {
+ // Stop walk once the limit is reached.
+ if (NBBsOnAllPaths == 0)
+ return true;
+
+ // Impossible to hoist with exceptions on the path.
+ if (hasEH(BB))
+ return true;
+
+ // No such instruction after HoistBarrier in a basic block was
+ // selected for hoisting so instructions selected within basic block with
+ // a hoist barrier can be hoisted.
+ if ((BB != SrcBB) && HoistBarrier.count(BB))
+ return true;
+
+ return false;
+}
+
+bool GVNHoist::hasEHOrLoadsOnPath(const Instruction *NewPt, MemoryDef *Def,
+ int &NBBsOnAllPaths) {
+ const BasicBlock *NewBB = NewPt->getParent();
+ const BasicBlock *OldBB = Def->getBlock();
+ assert(DT->dominates(NewBB, OldBB) && "invalid path");
+ assert(DT->dominates(Def->getDefiningAccess()->getBlock(), NewBB) &&
+ "def does not dominate new hoisting point");
+
+ // Walk all basic blocks reachable in depth-first iteration on the inverse
+ // CFG from OldBB to NewBB. These blocks are all the blocks that may be
+ // executed between the execution of NewBB and OldBB. Hoisting an expression
+ // from OldBB into NewBB has to be safe on all execution paths.
+ for (auto I = idf_begin(OldBB), E = idf_end(OldBB); I != E;) {
+ const BasicBlock *BB = *I;
+ if (BB == NewBB) {
+ // Stop traversal when reaching HoistPt.
+ I.skipChildren();
+ continue;
+ }
+
+ if (hasEHhelper(BB, OldBB, NBBsOnAllPaths))
+ return true;
+
+ // Check that we do not move a store past loads.
+ if (hasMemoryUse(NewPt, Def, BB))
+ return true;
+
+ // -1 is unlimited number of blocks on all paths.
+ if (NBBsOnAllPaths != -1)
+ --NBBsOnAllPaths;
+
+ ++I;
}
- return false;
-}
-
-bool GVNHoist::hasEHOnPath(const BasicBlock *HoistPt, const BasicBlock *SrcBB,
- int &NBBsOnAllPaths) {
- assert(DT->dominates(HoistPt, SrcBB) && "Invalid path");
-
- // Walk all basic blocks reachable in depth-first iteration on
- // the inverse CFG from BBInsn to NewHoistPt. These blocks are all the
- // blocks that may be executed between the execution of NewHoistPt and
- // BBInsn. Hoisting an expression from BBInsn into NewHoistPt has to be safe
- // on all execution paths.
- for (auto I = idf_begin(SrcBB), E = idf_end(SrcBB); I != E;) {
- const BasicBlock *BB = *I;
- if (BB == HoistPt) {
- // Stop traversal when reaching NewHoistPt.
- I.skipChildren();
- continue;
+ return false;
+}
+
+bool GVNHoist::hasEHOnPath(const BasicBlock *HoistPt, const BasicBlock *SrcBB,
+ int &NBBsOnAllPaths) {
+ assert(DT->dominates(HoistPt, SrcBB) && "Invalid path");
+
+ // Walk all basic blocks reachable in depth-first iteration on
+ // the inverse CFG from BBInsn to NewHoistPt. These blocks are all the
+ // blocks that may be executed between the execution of NewHoistPt and
+ // BBInsn. Hoisting an expression from BBInsn into NewHoistPt has to be safe
+ // on all execution paths.
+ for (auto I = idf_begin(SrcBB), E = idf_end(SrcBB); I != E;) {
+ const BasicBlock *BB = *I;
+ if (BB == HoistPt) {
+ // Stop traversal when reaching NewHoistPt.
+ I.skipChildren();
+ continue;
}
-
- if (hasEHhelper(BB, SrcBB, NBBsOnAllPaths))
- return true;
-
- // -1 is unlimited number of blocks on all paths.
- if (NBBsOnAllPaths != -1)
- --NBBsOnAllPaths;
-
- ++I;
+
+ if (hasEHhelper(BB, SrcBB, NBBsOnAllPaths))
+ return true;
+
+ // -1 is unlimited number of blocks on all paths.
+ if (NBBsOnAllPaths != -1)
+ --NBBsOnAllPaths;
+
+ ++I;
+ }
+
+ return false;
+}
+
+bool GVNHoist::safeToHoistLdSt(const Instruction *NewPt,
+ const Instruction *OldPt, MemoryUseOrDef *U,
+ GVNHoist::InsKind K, int &NBBsOnAllPaths) {
+ // In place hoisting is safe.
+ if (NewPt == OldPt)
+ return true;
+
+ const BasicBlock *NewBB = NewPt->getParent();
+ const BasicBlock *OldBB = OldPt->getParent();
+ const BasicBlock *UBB = U->getBlock();
+
+ // Check for dependences on the Memory SSA.
+ MemoryAccess *D = U->getDefiningAccess();
+ BasicBlock *DBB = D->getBlock();
+ if (DT->properlyDominates(NewBB, DBB))
+ // Cannot move the load or store to NewBB above its definition in DBB.
+ return false;
+
+ if (NewBB == DBB && !MSSA->isLiveOnEntryDef(D))
+ if (auto *UD = dyn_cast<MemoryUseOrDef>(D))
+ if (!firstInBB(UD->getMemoryInst(), NewPt))
+ // Cannot move the load or store to NewPt above its definition in D.
+ return false;
+
+ // Check for unsafe hoistings due to side effects.
+ if (K == InsKind::Store) {
+ if (hasEHOrLoadsOnPath(NewPt, cast<MemoryDef>(U), NBBsOnAllPaths))
+ return false;
+ } else if (hasEHOnPath(NewBB, OldBB, NBBsOnAllPaths))
+ return false;
+
+ if (UBB == NewBB) {
+ if (DT->properlyDominates(DBB, NewBB))
+ return true;
+ assert(UBB == DBB);
+ assert(MSSA->locallyDominates(D, U));
}
- return false;
-}
-
-bool GVNHoist::safeToHoistLdSt(const Instruction *NewPt,
- const Instruction *OldPt, MemoryUseOrDef *U,
- GVNHoist::InsKind K, int &NBBsOnAllPaths) {
- // In place hoisting is safe.
- if (NewPt == OldPt)
- return true;
-
- const BasicBlock *NewBB = NewPt->getParent();
- const BasicBlock *OldBB = OldPt->getParent();
- const BasicBlock *UBB = U->getBlock();
-
- // Check for dependences on the Memory SSA.
- MemoryAccess *D = U->getDefiningAccess();
- BasicBlock *DBB = D->getBlock();
- if (DT->properlyDominates(NewBB, DBB))
- // Cannot move the load or store to NewBB above its definition in DBB.
- return false;
-
- if (NewBB == DBB && !MSSA->isLiveOnEntryDef(D))
- if (auto *UD = dyn_cast<MemoryUseOrDef>(D))
- if (!firstInBB(UD->getMemoryInst(), NewPt))
- // Cannot move the load or store to NewPt above its definition in D.
- return false;
-
- // Check for unsafe hoistings due to side effects.
- if (K == InsKind::Store) {
- if (hasEHOrLoadsOnPath(NewPt, cast<MemoryDef>(U), NBBsOnAllPaths))
- return false;
- } else if (hasEHOnPath(NewBB, OldBB, NBBsOnAllPaths))
- return false;
-
- if (UBB == NewBB) {
- if (DT->properlyDominates(DBB, NewBB))
- return true;
- assert(UBB == DBB);
- assert(MSSA->locallyDominates(D, U));
+ // No side effects: it is safe to hoist.
+ return true;
+}
+
+bool GVNHoist::valueAnticipable(CHIArgs C, Instruction *TI) const {
+ if (TI->getNumSuccessors() > (unsigned)size(C))
+ return false; // Not enough args in this CHI.
+
+ for (auto CHI : C) {
+ // Find if all the edges have values flowing out of BB.
+ if (!llvm::is_contained(successors(TI), CHI.Dest))
+ return false;
}
+ return true;
+}
- // No side effects: it is safe to hoist.
- return true;
-}
-
-bool GVNHoist::valueAnticipable(CHIArgs C, Instruction *TI) const {
- if (TI->getNumSuccessors() > (unsigned)size(C))
- return false; // Not enough args in this CHI.
-
- for (auto CHI : C) {
- // Find if all the edges have values flowing out of BB.
- if (!llvm::is_contained(successors(TI), CHI.Dest))
- return false;
- }
- return true;
-}
-
-void GVNHoist::checkSafety(CHIArgs C, BasicBlock *BB, GVNHoist::InsKind K,
- SmallVectorImpl<CHIArg> &Safe) {
- int NumBBsOnAllPaths = MaxNumberOfBBSInPath;
- for (auto CHI : C) {
- Instruction *Insn = CHI.I;
- if (!Insn) // No instruction was inserted in this CHI.
- continue;
- if (K == InsKind::Scalar) {
- if (safeToHoistScalar(BB, Insn->getParent(), NumBBsOnAllPaths))
- Safe.push_back(CHI);
- } else {
- auto *T = BB->getTerminator();
- if (MemoryUseOrDef *UD = MSSA->getMemoryAccess(Insn))
- if (safeToHoistLdSt(T, Insn, UD, K, NumBBsOnAllPaths))
- Safe.push_back(CHI);
+void GVNHoist::checkSafety(CHIArgs C, BasicBlock *BB, GVNHoist::InsKind K,
+ SmallVectorImpl<CHIArg> &Safe) {
+ int NumBBsOnAllPaths = MaxNumberOfBBSInPath;
+ for (auto CHI : C) {
+ Instruction *Insn = CHI.I;
+ if (!Insn) // No instruction was inserted in this CHI.
+ continue;
+ if (K == InsKind::Scalar) {
+ if (safeToHoistScalar(BB, Insn->getParent(), NumBBsOnAllPaths))
+ Safe.push_back(CHI);
+ } else {
+ auto *T = BB->getTerminator();
+ if (MemoryUseOrDef *UD = MSSA->getMemoryAccess(Insn))
+ if (safeToHoistLdSt(T, Insn, UD, K, NumBBsOnAllPaths))
+ Safe.push_back(CHI);
}
}
-}
-
-void GVNHoist::fillRenameStack(BasicBlock *BB, InValuesType &ValueBBs,
- GVNHoist::RenameStackType &RenameStack) {
- auto it1 = ValueBBs.find(BB);
- if (it1 != ValueBBs.end()) {
- // Iterate in reverse order to keep lower ranked values on the top.
- for (std::pair<VNType, Instruction *> &VI : reverse(it1->second)) {
- // Get the value of instruction I
- LLVM_DEBUG(dbgs() << "\nPushing on stack: " << *VI.second);
- RenameStack[VI.first].push_back(VI.second);
+}
+
+void GVNHoist::fillRenameStack(BasicBlock *BB, InValuesType &ValueBBs,
+ GVNHoist::RenameStackType &RenameStack) {
+ auto it1 = ValueBBs.find(BB);
+ if (it1 != ValueBBs.end()) {
+ // Iterate in reverse order to keep lower ranked values on the top.
+ for (std::pair<VNType, Instruction *> &VI : reverse(it1->second)) {
+ // Get the value of instruction I
+ LLVM_DEBUG(dbgs() << "\nPushing on stack: " << *VI.second);
+ RenameStack[VI.first].push_back(VI.second);
}
- }
-}
-
-void GVNHoist::fillChiArgs(BasicBlock *BB, OutValuesType &CHIBBs,
- GVNHoist::RenameStackType &RenameStack) {
- // For each *predecessor* (because Post-DOM) of BB check if it has a CHI
- for (auto Pred : predecessors(BB)) {
- auto P = CHIBBs.find(Pred);
- if (P == CHIBBs.end()) {
- continue;
- }
- LLVM_DEBUG(dbgs() << "\nLooking at CHIs in: " << Pred->getName(););
- // A CHI is found (BB -> Pred is an edge in the CFG)
- // Pop the stack until Top(V) = Ve.
- auto &VCHI = P->second;
- for (auto It = VCHI.begin(), E = VCHI.end(); It != E;) {
- CHIArg &C = *It;
- if (!C.Dest) {
- auto si = RenameStack.find(C.VN);
- // The Basic Block where CHI is must dominate the value we want to
- // track in a CHI. In the PDom walk, there can be values in the
- // stack which are not control dependent e.g., nested loop.
- if (si != RenameStack.end() && si->second.size() &&
- DT->properlyDominates(Pred, si->second.back()->getParent())) {
- C.Dest = BB; // Assign the edge
- C.I = si->second.pop_back_val(); // Assign the argument
- LLVM_DEBUG(dbgs()
- << "\nCHI Inserted in BB: " << C.Dest->getName() << *C.I
- << ", VN: " << C.VN.first << ", " << C.VN.second);
- }
- // Move to next CHI of a different value
- It = std::find_if(It, VCHI.end(), [It](CHIArg &A) { return A != *It; });
- } else
- ++It;
- }
- }
-}
-
-void GVNHoist::findHoistableCandidates(OutValuesType &CHIBBs,
- GVNHoist::InsKind K,
- HoistingPointList &HPL) {
- auto cmpVN = [](const CHIArg &A, const CHIArg &B) { return A.VN < B.VN; };
-
- // CHIArgs now have the outgoing values, so check for anticipability and
- // accumulate hoistable candidates in HPL.
- for (std::pair<BasicBlock *, SmallVector<CHIArg, 2>> &A : CHIBBs) {
- BasicBlock *BB = A.first;
- SmallVectorImpl<CHIArg> &CHIs = A.second;
- // Vector of PHIs contains PHIs for different instructions.
- // Sort the args according to their VNs, such that identical
- // instructions are together.
- llvm::stable_sort(CHIs, cmpVN);
- auto TI = BB->getTerminator();
- auto B = CHIs.begin();
- // [PreIt, PHIIt) form a range of CHIs which have identical VNs.
- auto PHIIt = llvm::find_if(CHIs, [B](CHIArg &A) { return A != *B; });
- auto PrevIt = CHIs.begin();
- while (PrevIt != PHIIt) {
- // Collect values which satisfy safety checks.
- SmallVector<CHIArg, 2> Safe;
- // We check for safety first because there might be multiple values in
- // the same path, some of which are not safe to be hoisted, but overall
- // each edge has at least one value which can be hoisted, making the
- // value anticipable along that path.
- checkSafety(make_range(PrevIt, PHIIt), BB, K, Safe);
-
- // List of safe values should be anticipable at TI.
- if (valueAnticipable(make_range(Safe.begin(), Safe.end()), TI)) {
- HPL.push_back({BB, SmallVecInsn()});
- SmallVecInsn &V = HPL.back().second;
- for (auto B : Safe)
- V.push_back(B.I);
- }
-
- // Check other VNs
- PrevIt = PHIIt;
- PHIIt = std::find_if(PrevIt, CHIs.end(),
- [PrevIt](CHIArg &A) { return A != *PrevIt; });
- }
}
-}
-
-bool GVNHoist::allOperandsAvailable(const Instruction *I,
- const BasicBlock *HoistPt) const {
- for (const Use &Op : I->operands())
- if (const auto *Inst = dyn_cast<Instruction>(&Op))
- if (!DT->dominates(Inst->getParent(), HoistPt))
- return false;
-
- return true;
-}
-
-bool GVNHoist::allGepOperandsAvailable(const Instruction *I,
- const BasicBlock *HoistPt) const {
- for (const Use &Op : I->operands())
- if (const auto *Inst = dyn_cast<Instruction>(&Op))
- if (!DT->dominates(Inst->getParent(), HoistPt)) {
- if (const GetElementPtrInst *GepOp =
- dyn_cast<GetElementPtrInst>(Inst)) {
- if (!allGepOperandsAvailable(GepOp, HoistPt))
+}
+
+void GVNHoist::fillChiArgs(BasicBlock *BB, OutValuesType &CHIBBs,
+ GVNHoist::RenameStackType &RenameStack) {
+ // For each *predecessor* (because Post-DOM) of BB check if it has a CHI
+ for (auto Pred : predecessors(BB)) {
+ auto P = CHIBBs.find(Pred);
+ if (P == CHIBBs.end()) {
+ continue;
+ }
+ LLVM_DEBUG(dbgs() << "\nLooking at CHIs in: " << Pred->getName(););
+ // A CHI is found (BB -> Pred is an edge in the CFG)
+ // Pop the stack until Top(V) = Ve.
+ auto &VCHI = P->second;
+ for (auto It = VCHI.begin(), E = VCHI.end(); It != E;) {
+ CHIArg &C = *It;
+ if (!C.Dest) {
+ auto si = RenameStack.find(C.VN);
+ // The Basic Block where CHI is must dominate the value we want to
+ // track in a CHI. In the PDom walk, there can be values in the
+ // stack which are not control dependent e.g., nested loop.
+ if (si != RenameStack.end() && si->second.size() &&
+ DT->properlyDominates(Pred, si->second.back()->getParent())) {
+ C.Dest = BB; // Assign the edge
+ C.I = si->second.pop_back_val(); // Assign the argument
+ LLVM_DEBUG(dbgs()
+ << "\nCHI Inserted in BB: " << C.Dest->getName() << *C.I
+ << ", VN: " << C.VN.first << ", " << C.VN.second);
+ }
+ // Move to next CHI of a different value
+ It = std::find_if(It, VCHI.end(), [It](CHIArg &A) { return A != *It; });
+ } else
+ ++It;
+ }
+ }
+}
+
+void GVNHoist::findHoistableCandidates(OutValuesType &CHIBBs,
+ GVNHoist::InsKind K,
+ HoistingPointList &HPL) {
+ auto cmpVN = [](const CHIArg &A, const CHIArg &B) { return A.VN < B.VN; };
+
+ // CHIArgs now have the outgoing values, so check for anticipability and
+ // accumulate hoistable candidates in HPL.
+ for (std::pair<BasicBlock *, SmallVector<CHIArg, 2>> &A : CHIBBs) {
+ BasicBlock *BB = A.first;
+ SmallVectorImpl<CHIArg> &CHIs = A.second;
+ // Vector of PHIs contains PHIs for different instructions.
+ // Sort the args according to their VNs, such that identical
+ // instructions are together.
+ llvm::stable_sort(CHIs, cmpVN);
+ auto TI = BB->getTerminator();
+ auto B = CHIs.begin();
+ // [PreIt, PHIIt) form a range of CHIs which have identical VNs.
+ auto PHIIt = llvm::find_if(CHIs, [B](CHIArg &A) { return A != *B; });
+ auto PrevIt = CHIs.begin();
+ while (PrevIt != PHIIt) {
+ // Collect values which satisfy safety checks.
+ SmallVector<CHIArg, 2> Safe;
+ // We check for safety first because there might be multiple values in
+ // the same path, some of which are not safe to be hoisted, but overall
+ // each edge has at least one value which can be hoisted, making the
+ // value anticipable along that path.
+ checkSafety(make_range(PrevIt, PHIIt), BB, K, Safe);
+
+ // List of safe values should be anticipable at TI.
+ if (valueAnticipable(make_range(Safe.begin(), Safe.end()), TI)) {
+ HPL.push_back({BB, SmallVecInsn()});
+ SmallVecInsn &V = HPL.back().second;
+ for (auto B : Safe)
+ V.push_back(B.I);
+ }
+
+ // Check other VNs
+ PrevIt = PHIIt;
+ PHIIt = std::find_if(PrevIt, CHIs.end(),
+ [PrevIt](CHIArg &A) { return A != *PrevIt; });
+ }
+ }
+}
+
+bool GVNHoist::allOperandsAvailable(const Instruction *I,
+ const BasicBlock *HoistPt) const {
+ for (const Use &Op : I->operands())
+ if (const auto *Inst = dyn_cast<Instruction>(&Op))
+ if (!DT->dominates(Inst->getParent(), HoistPt))
+ return false;
+
+ return true;
+}
+
+bool GVNHoist::allGepOperandsAvailable(const Instruction *I,
+ const BasicBlock *HoistPt) const {
+ for (const Use &Op : I->operands())
+ if (const auto *Inst = dyn_cast<Instruction>(&Op))
+ if (!DT->dominates(Inst->getParent(), HoistPt)) {
+ if (const GetElementPtrInst *GepOp =
+ dyn_cast<GetElementPtrInst>(Inst)) {
+ if (!allGepOperandsAvailable(GepOp, HoistPt))
return false;
- // Gep is available if all operands of GepOp are available.
- } else {
- // Gep is not available if it has operands other than GEPs that are
- // defined in blocks not dominating HoistPt.
+ // Gep is available if all operands of GepOp are available.
+ } else {
+ // Gep is not available if it has operands other than GEPs that are
+ // defined in blocks not dominating HoistPt.
return false;
- }
+ }
}
- return true;
-}
-
-void GVNHoist::makeGepsAvailable(Instruction *Repl, BasicBlock *HoistPt,
- const SmallVecInsn &InstructionsToHoist,
- Instruction *Gep) const {
- assert(allGepOperandsAvailable(Gep, HoistPt) && "GEP operands not available");
-
- Instruction *ClonedGep = Gep->clone();
- for (unsigned i = 0, e = Gep->getNumOperands(); i != e; ++i)
- if (Instruction *Op = dyn_cast<Instruction>(Gep->getOperand(i))) {
- // Check whether the operand is already available.
- if (DT->dominates(Op->getParent(), HoistPt))
- continue;
-
- // As a GEP can refer to other GEPs, recursively make all the operands
- // of this GEP available at HoistPt.
- if (GetElementPtrInst *GepOp = dyn_cast<GetElementPtrInst>(Op))
- makeGepsAvailable(ClonedGep, HoistPt, InstructionsToHoist, GepOp);
+ return true;
+}
+
+void GVNHoist::makeGepsAvailable(Instruction *Repl, BasicBlock *HoistPt,
+ const SmallVecInsn &InstructionsToHoist,
+ Instruction *Gep) const {
+ assert(allGepOperandsAvailable(Gep, HoistPt) && "GEP operands not available");
+
+ Instruction *ClonedGep = Gep->clone();
+ for (unsigned i = 0, e = Gep->getNumOperands(); i != e; ++i)
+ if (Instruction *Op = dyn_cast<Instruction>(Gep->getOperand(i))) {
+ // Check whether the operand is already available.
+ if (DT->dominates(Op->getParent(), HoistPt))
+ continue;
+
+ // As a GEP can refer to other GEPs, recursively make all the operands
+ // of this GEP available at HoistPt.
+ if (GetElementPtrInst *GepOp = dyn_cast<GetElementPtrInst>(Op))
+ makeGepsAvailable(ClonedGep, HoistPt, InstructionsToHoist, GepOp);
}
- // Copy Gep and replace its uses in Repl with ClonedGep.
- ClonedGep->insertBefore(HoistPt->getTerminator());
-
- // Conservatively discard any optimization hints, they may differ on the
- // other paths.
- ClonedGep->dropUnknownNonDebugMetadata();
-
- // If we have optimization hints which agree with each other along different
- // paths, preserve them.
- for (const Instruction *OtherInst : InstructionsToHoist) {
- const GetElementPtrInst *OtherGep;
- if (auto *OtherLd = dyn_cast<LoadInst>(OtherInst))
- OtherGep = cast<GetElementPtrInst>(OtherLd->getPointerOperand());
- else
- OtherGep = cast<GetElementPtrInst>(
- cast<StoreInst>(OtherInst)->getPointerOperand());
- ClonedGep->andIRFlags(OtherGep);
- }
-
- // Replace uses of Gep with ClonedGep in Repl.
- Repl->replaceUsesOfWith(Gep, ClonedGep);
-}
-
-void GVNHoist::updateAlignment(Instruction *I, Instruction *Repl) {
- if (auto *ReplacementLoad = dyn_cast<LoadInst>(Repl)) {
- ReplacementLoad->setAlignment(
- std::min(ReplacementLoad->getAlign(), cast<LoadInst>(I)->getAlign()));
- ++NumLoadsRemoved;
- } else if (auto *ReplacementStore = dyn_cast<StoreInst>(Repl)) {
- ReplacementStore->setAlignment(
- std::min(ReplacementStore->getAlign(), cast<StoreInst>(I)->getAlign()));
- ++NumStoresRemoved;
- } else if (auto *ReplacementAlloca = dyn_cast<AllocaInst>(Repl)) {
- ReplacementAlloca->setAlignment(std::max(ReplacementAlloca->getAlign(),
- cast<AllocaInst>(I)->getAlign()));
- } else if (isa<CallInst>(Repl)) {
- ++NumCallsRemoved;
+ // Copy Gep and replace its uses in Repl with ClonedGep.
+ ClonedGep->insertBefore(HoistPt->getTerminator());
+
+ // Conservatively discard any optimization hints, they may differ on the
+ // other paths.
+ ClonedGep->dropUnknownNonDebugMetadata();
+
+ // If we have optimization hints which agree with each other along different
+ // paths, preserve them.
+ for (const Instruction *OtherInst : InstructionsToHoist) {
+ const GetElementPtrInst *OtherGep;
+ if (auto *OtherLd = dyn_cast<LoadInst>(OtherInst))
+ OtherGep = cast<GetElementPtrInst>(OtherLd->getPointerOperand());
+ else
+ OtherGep = cast<GetElementPtrInst>(
+ cast<StoreInst>(OtherInst)->getPointerOperand());
+ ClonedGep->andIRFlags(OtherGep);
+ }
+
+ // Replace uses of Gep with ClonedGep in Repl.
+ Repl->replaceUsesOfWith(Gep, ClonedGep);
+}
+
+void GVNHoist::updateAlignment(Instruction *I, Instruction *Repl) {
+ if (auto *ReplacementLoad = dyn_cast<LoadInst>(Repl)) {
+ ReplacementLoad->setAlignment(
+ std::min(ReplacementLoad->getAlign(), cast<LoadInst>(I)->getAlign()));
+ ++NumLoadsRemoved;
+ } else if (auto *ReplacementStore = dyn_cast<StoreInst>(Repl)) {
+ ReplacementStore->setAlignment(
+ std::min(ReplacementStore->getAlign(), cast<StoreInst>(I)->getAlign()));
+ ++NumStoresRemoved;
+ } else if (auto *ReplacementAlloca = dyn_cast<AllocaInst>(Repl)) {
+ ReplacementAlloca->setAlignment(std::max(ReplacementAlloca->getAlign(),
+ cast<AllocaInst>(I)->getAlign()));
+ } else if (isa<CallInst>(Repl)) {
+ ++NumCallsRemoved;
}
-}
-
-unsigned GVNHoist::rauw(const SmallVecInsn &Candidates, Instruction *Repl,
- MemoryUseOrDef *NewMemAcc) {
- unsigned NR = 0;
- for (Instruction *I : Candidates) {
- if (I != Repl) {
- ++NR;
- updateAlignment(I, Repl);
- if (NewMemAcc) {
- // Update the uses of the old MSSA access with NewMemAcc.
- MemoryAccess *OldMA = MSSA->getMemoryAccess(I);
- OldMA->replaceAllUsesWith(NewMemAcc);
- MSSAUpdater->removeMemoryAccess(OldMA);
- }
-
- Repl->andIRFlags(I);
- combineKnownMetadata(Repl, I);
- I->replaceAllUsesWith(Repl);
- // Also invalidate the Alias Analysis cache.
- MD->removeInstruction(I);
- I->eraseFromParent();
- }
- }
- return NR;
-}
-
-void GVNHoist::raMPHIuw(MemoryUseOrDef *NewMemAcc) {
- SmallPtrSet<MemoryPhi *, 4> UsePhis;
- for (User *U : NewMemAcc->users())
- if (MemoryPhi *Phi = dyn_cast<MemoryPhi>(U))
- UsePhis.insert(Phi);
-
- for (MemoryPhi *Phi : UsePhis) {
- auto In = Phi->incoming_values();
- if (llvm::all_of(In, [&](Use &U) { return U == NewMemAcc; })) {
- Phi->replaceAllUsesWith(NewMemAcc);
- MSSAUpdater->removeMemoryAccess(Phi);
- }
- }
-}
-
-unsigned GVNHoist::removeAndReplace(const SmallVecInsn &Candidates,
- Instruction *Repl, BasicBlock *DestBB,
- bool MoveAccess) {
- MemoryUseOrDef *NewMemAcc = MSSA->getMemoryAccess(Repl);
- if (MoveAccess && NewMemAcc) {
- // The definition of this ld/st will not change: ld/st hoisting is
- // legal when the ld/st is not moved past its current definition.
- MSSAUpdater->moveToPlace(NewMemAcc, DestBB, MemorySSA::BeforeTerminator);
- }
-
- // Replace all other instructions with Repl with memory access NewMemAcc.
- unsigned NR = rauw(Candidates, Repl, NewMemAcc);
-
- // Remove MemorySSA phi nodes with the same arguments.
- if (NewMemAcc)
- raMPHIuw(NewMemAcc);
- return NR;
-}
-
-bool GVNHoist::makeGepOperandsAvailable(
- Instruction *Repl, BasicBlock *HoistPt,
- const SmallVecInsn &InstructionsToHoist) const {
- // Check whether the GEP of a ld/st can be synthesized at HoistPt.
- GetElementPtrInst *Gep = nullptr;
- Instruction *Val = nullptr;
- if (auto *Ld = dyn_cast<LoadInst>(Repl)) {
- Gep = dyn_cast<GetElementPtrInst>(Ld->getPointerOperand());
- } else if (auto *St = dyn_cast<StoreInst>(Repl)) {
- Gep = dyn_cast<GetElementPtrInst>(St->getPointerOperand());
- Val = dyn_cast<Instruction>(St->getValueOperand());
- // Check that the stored value is available.
- if (Val) {
- if (isa<GetElementPtrInst>(Val)) {
- // Check whether we can compute the GEP at HoistPt.
- if (!allGepOperandsAvailable(Val, HoistPt))
- return false;
- } else if (!DT->dominates(Val->getParent(), HoistPt))
- return false;
+}
+
+unsigned GVNHoist::rauw(const SmallVecInsn &Candidates, Instruction *Repl,
+ MemoryUseOrDef *NewMemAcc) {
+ unsigned NR = 0;
+ for (Instruction *I : Candidates) {
+ if (I != Repl) {
+ ++NR;
+ updateAlignment(I, Repl);
+ if (NewMemAcc) {
+ // Update the uses of the old MSSA access with NewMemAcc.
+ MemoryAccess *OldMA = MSSA->getMemoryAccess(I);
+ OldMA->replaceAllUsesWith(NewMemAcc);
+ MSSAUpdater->removeMemoryAccess(OldMA);
+ }
+
+ Repl->andIRFlags(I);
+ combineKnownMetadata(Repl, I);
+ I->replaceAllUsesWith(Repl);
+ // Also invalidate the Alias Analysis cache.
+ MD->removeInstruction(I);
+ I->eraseFromParent();
}
- }
-
- // Check whether we can compute the Gep at HoistPt.
- if (!Gep || !allGepOperandsAvailable(Gep, HoistPt))
- return false;
-
- makeGepsAvailable(Repl, HoistPt, InstructionsToHoist, Gep);
-
- if (Val && isa<GetElementPtrInst>(Val))
- makeGepsAvailable(Repl, HoistPt, InstructionsToHoist, Val);
-
- return true;
-}
-
-std::pair<unsigned, unsigned> GVNHoist::hoist(HoistingPointList &HPL) {
- unsigned NI = 0, NL = 0, NS = 0, NC = 0, NR = 0;
- for (const HoistingPointInfo &HP : HPL) {
- // Find out whether we already have one of the instructions in HoistPt,
- // in which case we do not have to move it.
- BasicBlock *DestBB = HP.first;
- const SmallVecInsn &InstructionsToHoist = HP.second;
- Instruction *Repl = nullptr;
- for (Instruction *I : InstructionsToHoist)
- if (I->getParent() == DestBB)
- // If there are two instructions in HoistPt to be hoisted in place:
- // update Repl to be the first one, such that we can rename the uses
- // of the second based on the first.
- if (!Repl || firstInBB(I, Repl))
- Repl = I;
-
- // Keep track of whether we moved the instruction so we know whether we
- // should move the MemoryAccess.
- bool MoveAccess = true;
- if (Repl) {
- // Repl is already in HoistPt: it remains in place.
- assert(allOperandsAvailable(Repl, DestBB) &&
- "instruction depends on operands that are not available");
- MoveAccess = false;
- } else {
- // When we do not find Repl in HoistPt, select the first in the list
- // and move it to HoistPt.
- Repl = InstructionsToHoist.front();
-
- // We can move Repl in HoistPt only when all operands are available.
- // The order in which hoistings are done may influence the availability
- // of operands.
- if (!allOperandsAvailable(Repl, DestBB)) {
- // When HoistingGeps there is nothing more we can do to make the
- // operands available: just continue.
- if (HoistingGeps)
- continue;
-
- // When not HoistingGeps we need to copy the GEPs.
- if (!makeGepOperandsAvailable(Repl, DestBB, InstructionsToHoist))
- continue;
+ }
+ return NR;
+}
+
+void GVNHoist::raMPHIuw(MemoryUseOrDef *NewMemAcc) {
+ SmallPtrSet<MemoryPhi *, 4> UsePhis;
+ for (User *U : NewMemAcc->users())
+ if (MemoryPhi *Phi = dyn_cast<MemoryPhi>(U))
+ UsePhis.insert(Phi);
+
+ for (MemoryPhi *Phi : UsePhis) {
+ auto In = Phi->incoming_values();
+ if (llvm::all_of(In, [&](Use &U) { return U == NewMemAcc; })) {
+ Phi->replaceAllUsesWith(NewMemAcc);
+ MSSAUpdater->removeMemoryAccess(Phi);
+ }
+ }
+}
+
+unsigned GVNHoist::removeAndReplace(const SmallVecInsn &Candidates,
+ Instruction *Repl, BasicBlock *DestBB,
+ bool MoveAccess) {
+ MemoryUseOrDef *NewMemAcc = MSSA->getMemoryAccess(Repl);
+ if (MoveAccess && NewMemAcc) {
+ // The definition of this ld/st will not change: ld/st hoisting is
+ // legal when the ld/st is not moved past its current definition.
+ MSSAUpdater->moveToPlace(NewMemAcc, DestBB, MemorySSA::BeforeTerminator);
+ }
+
+ // Replace all other instructions with Repl with memory access NewMemAcc.
+ unsigned NR = rauw(Candidates, Repl, NewMemAcc);
+
+ // Remove MemorySSA phi nodes with the same arguments.
+ if (NewMemAcc)
+ raMPHIuw(NewMemAcc);
+ return NR;
+}
+
+bool GVNHoist::makeGepOperandsAvailable(
+ Instruction *Repl, BasicBlock *HoistPt,
+ const SmallVecInsn &InstructionsToHoist) const {
+ // Check whether the GEP of a ld/st can be synthesized at HoistPt.
+ GetElementPtrInst *Gep = nullptr;
+ Instruction *Val = nullptr;
+ if (auto *Ld = dyn_cast<LoadInst>(Repl)) {
+ Gep = dyn_cast<GetElementPtrInst>(Ld->getPointerOperand());
+ } else if (auto *St = dyn_cast<StoreInst>(Repl)) {
+ Gep = dyn_cast<GetElementPtrInst>(St->getPointerOperand());
+ Val = dyn_cast<Instruction>(St->getValueOperand());
+ // Check that the stored value is available.
+ if (Val) {
+ if (isa<GetElementPtrInst>(Val)) {
+ // Check whether we can compute the GEP at HoistPt.
+ if (!allGepOperandsAvailable(Val, HoistPt))
+ return false;
+ } else if (!DT->dominates(Val->getParent(), HoistPt))
+ return false;
+ }
+ }
+
+ // Check whether we can compute the Gep at HoistPt.
+ if (!Gep || !allGepOperandsAvailable(Gep, HoistPt))
+ return false;
+
+ makeGepsAvailable(Repl, HoistPt, InstructionsToHoist, Gep);
+
+ if (Val && isa<GetElementPtrInst>(Val))
+ makeGepsAvailable(Repl, HoistPt, InstructionsToHoist, Val);
+
+ return true;
+}
+
+std::pair<unsigned, unsigned> GVNHoist::hoist(HoistingPointList &HPL) {
+ unsigned NI = 0, NL = 0, NS = 0, NC = 0, NR = 0;
+ for (const HoistingPointInfo &HP : HPL) {
+ // Find out whether we already have one of the instructions in HoistPt,
+ // in which case we do not have to move it.
+ BasicBlock *DestBB = HP.first;
+ const SmallVecInsn &InstructionsToHoist = HP.second;
+ Instruction *Repl = nullptr;
+ for (Instruction *I : InstructionsToHoist)
+ if (I->getParent() == DestBB)
+ // If there are two instructions in HoistPt to be hoisted in place:
+ // update Repl to be the first one, such that we can rename the uses
+ // of the second based on the first.
+ if (!Repl || firstInBB(I, Repl))
+ Repl = I;
+
+ // Keep track of whether we moved the instruction so we know whether we
+ // should move the MemoryAccess.
+ bool MoveAccess = true;
+ if (Repl) {
+ // Repl is already in HoistPt: it remains in place.
+ assert(allOperandsAvailable(Repl, DestBB) &&
+ "instruction depends on operands that are not available");
+ MoveAccess = false;
+ } else {
+ // When we do not find Repl in HoistPt, select the first in the list
+ // and move it to HoistPt.
+ Repl = InstructionsToHoist.front();
+
+ // We can move Repl in HoistPt only when all operands are available.
+ // The order in which hoistings are done may influence the availability
+ // of operands.
+ if (!allOperandsAvailable(Repl, DestBB)) {
+ // When HoistingGeps there is nothing more we can do to make the
+ // operands available: just continue.
+ if (HoistingGeps)
+ continue;
+
+ // When not HoistingGeps we need to copy the GEPs.
+ if (!makeGepOperandsAvailable(Repl, DestBB, InstructionsToHoist))
+ continue;
}
-
- // Move the instruction at the end of HoistPt.
- Instruction *Last = DestBB->getTerminator();
- MD->removeInstruction(Repl);
- Repl->moveBefore(Last);
-
- DFSNumber[Repl] = DFSNumber[Last]++;
+
+ // Move the instruction at the end of HoistPt.
+ Instruction *Last = DestBB->getTerminator();
+ MD->removeInstruction(Repl);
+ Repl->moveBefore(Last);
+
+ DFSNumber[Repl] = DFSNumber[Last]++;
}
- NR += removeAndReplace(InstructionsToHoist, Repl, DestBB, MoveAccess);
-
- if (isa<LoadInst>(Repl))
- ++NL;
- else if (isa<StoreInst>(Repl))
- ++NS;
- else if (isa<CallInst>(Repl))
- ++NC;
- else // Scalar
- ++NI;
+ NR += removeAndReplace(InstructionsToHoist, Repl, DestBB, MoveAccess);
+
+ if (isa<LoadInst>(Repl))
+ ++NL;
+ else if (isa<StoreInst>(Repl))
+ ++NS;
+ else if (isa<CallInst>(Repl))
+ ++NC;
+ else // Scalar
+ ++NI;
}
- if (MSSA && VerifyMemorySSA)
- MSSA->verifyMemorySSA();
-
- NumHoisted += NL + NS + NC + NI;
- NumRemoved += NR;
- NumLoadsHoisted += NL;
- NumStoresHoisted += NS;
- NumCallsHoisted += NC;
- return {NI, NL + NC + NS};
-}
-
-std::pair<unsigned, unsigned> GVNHoist::hoistExpressions(Function &F) {
- InsnInfo II;
- LoadInfo LI;
- StoreInfo SI;
- CallInfo CI;
- for (BasicBlock *BB : depth_first(&F.getEntryBlock())) {
- int InstructionNb = 0;
- for (Instruction &I1 : *BB) {
- // If I1 cannot guarantee progress, subsequent instructions
- // in BB cannot be hoisted anyways.
- if (!isGuaranteedToTransferExecutionToSuccessor(&I1)) {
- HoistBarrier.insert(BB);
- break;
- }
- // Only hoist the first instructions in BB up to MaxDepthInBB. Hoisting
- // deeper may increase the register pressure and compilation time.
- if (MaxDepthInBB != -1 && InstructionNb++ >= MaxDepthInBB)
- break;
-
- // Do not value number terminator instructions.
- if (I1.isTerminator())
- break;
-
- if (auto *Load = dyn_cast<LoadInst>(&I1))
- LI.insert(Load, VN);
- else if (auto *Store = dyn_cast<StoreInst>(&I1))
- SI.insert(Store, VN);
- else if (auto *Call = dyn_cast<CallInst>(&I1)) {
- if (auto *Intr = dyn_cast<IntrinsicInst>(Call)) {
- if (isa<DbgInfoIntrinsic>(Intr) ||
- Intr->getIntrinsicID() == Intrinsic::assume ||
- Intr->getIntrinsicID() == Intrinsic::sideeffect)
- continue;
- }
- if (Call->mayHaveSideEffects())
- break;
-
- if (Call->isConvergent())
- break;
-
- CI.insert(Call, VN);
- } else if (HoistingGeps || !isa<GetElementPtrInst>(&I1))
- // Do not hoist scalars past calls that may write to memory because
- // that could result in spills later. geps are handled separately.
- // TODO: We can relax this for targets like AArch64 as they have more
- // registers than X86.
- II.insert(&I1, VN);
- }
+ if (MSSA && VerifyMemorySSA)
+ MSSA->verifyMemorySSA();
+
+ NumHoisted += NL + NS + NC + NI;
+ NumRemoved += NR;
+ NumLoadsHoisted += NL;
+ NumStoresHoisted += NS;
+ NumCallsHoisted += NC;
+ return {NI, NL + NC + NS};
+}
+
+std::pair<unsigned, unsigned> GVNHoist::hoistExpressions(Function &F) {
+ InsnInfo II;
+ LoadInfo LI;
+ StoreInfo SI;
+ CallInfo CI;
+ for (BasicBlock *BB : depth_first(&F.getEntryBlock())) {
+ int InstructionNb = 0;
+ for (Instruction &I1 : *BB) {
+ // If I1 cannot guarantee progress, subsequent instructions
+ // in BB cannot be hoisted anyways.
+ if (!isGuaranteedToTransferExecutionToSuccessor(&I1)) {
+ HoistBarrier.insert(BB);
+ break;
+ }
+ // Only hoist the first instructions in BB up to MaxDepthInBB. Hoisting
+ // deeper may increase the register pressure and compilation time.
+ if (MaxDepthInBB != -1 && InstructionNb++ >= MaxDepthInBB)
+ break;
+
+ // Do not value number terminator instructions.
+ if (I1.isTerminator())
+ break;
+
+ if (auto *Load = dyn_cast<LoadInst>(&I1))
+ LI.insert(Load, VN);
+ else if (auto *Store = dyn_cast<StoreInst>(&I1))
+ SI.insert(Store, VN);
+ else if (auto *Call = dyn_cast<CallInst>(&I1)) {
+ if (auto *Intr = dyn_cast<IntrinsicInst>(Call)) {
+ if (isa<DbgInfoIntrinsic>(Intr) ||
+ Intr->getIntrinsicID() == Intrinsic::assume ||
+ Intr->getIntrinsicID() == Intrinsic::sideeffect)
+ continue;
+ }
+ if (Call->mayHaveSideEffects())
+ break;
+
+ if (Call->isConvergent())
+ break;
+
+ CI.insert(Call, VN);
+ } else if (HoistingGeps || !isa<GetElementPtrInst>(&I1))
+ // Do not hoist scalars past calls that may write to memory because
+ // that could result in spills later. geps are handled separately.
+ // TODO: We can relax this for targets like AArch64 as they have more
+ // registers than X86.
+ II.insert(&I1, VN);
+ }
}
- HoistingPointList HPL;
- computeInsertionPoints(II.getVNTable(), HPL, InsKind::Scalar);
- computeInsertionPoints(LI.getVNTable(), HPL, InsKind::Load);
- computeInsertionPoints(SI.getVNTable(), HPL, InsKind::Store);
- computeInsertionPoints(CI.getScalarVNTable(), HPL, InsKind::Scalar);
- computeInsertionPoints(CI.getLoadVNTable(), HPL, InsKind::Load);
- computeInsertionPoints(CI.getStoreVNTable(), HPL, InsKind::Store);
- return hoist(HPL);
-}
-
+ HoistingPointList HPL;
+ computeInsertionPoints(II.getVNTable(), HPL, InsKind::Scalar);
+ computeInsertionPoints(LI.getVNTable(), HPL, InsKind::Load);
+ computeInsertionPoints(SI.getVNTable(), HPL, InsKind::Store);
+ computeInsertionPoints(CI.getScalarVNTable(), HPL, InsKind::Scalar);
+ computeInsertionPoints(CI.getLoadVNTable(), HPL, InsKind::Load);
+ computeInsertionPoints(CI.getStoreVNTable(), HPL, InsKind::Store);
+ return hoist(HPL);
+}
+
} // end namespace llvm
PreservedAnalyses GVNHoistPass::run(Function &F, FunctionAnalysisManager &AM) {
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/GVNSink.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/GVNSink.cpp
index 35ad503e23..aef927ab65 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/GVNSink.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/GVNSink.cpp
@@ -158,7 +158,7 @@ public:
void restrictToBlocks(SmallSetVector<BasicBlock *, 4> &Blocks) {
for (auto II = Insts.begin(); II != Insts.end();) {
- if (!llvm::is_contained(Blocks, (*II)->getParent())) {
+ if (!llvm::is_contained(Blocks, (*II)->getParent())) {
ActiveBlocks.remove((*II)->getParent());
II = Insts.erase(II);
} else {
@@ -276,7 +276,7 @@ public:
auto VI = Values.begin();
while (BI != Blocks.end()) {
assert(VI != Values.end());
- if (!llvm::is_contained(NewBlocks, *BI)) {
+ if (!llvm::is_contained(NewBlocks, *BI)) {
BI = Blocks.erase(BI);
VI = Values.erase(VI);
} else {
@@ -692,7 +692,7 @@ Optional<SinkingInstructionCandidate> GVNSink::analyzeInstructionForSinking(
ModelledPHI NewPHI(NewInsts, ActivePreds);
// Does sinking this instruction render previous PHIs redundant?
- if (NeededPHIs.erase(NewPHI))
+ if (NeededPHIs.erase(NewPHI))
RecomputePHIContents = true;
if (RecomputePHIContents) {
@@ -754,7 +754,7 @@ Optional<SinkingInstructionCandidate> GVNSink::analyzeInstructionForSinking(
Cand.NumMemoryInsts = MemoryInstNum;
Cand.NumBlocks = ActivePreds.size();
Cand.NumPHIs = NeededPHIs.size();
- append_range(Cand.Blocks, ActivePreds);
+ append_range(Cand.Blocks, ActivePreds);
return Cand;
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/GuardWidening.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/GuardWidening.cpp
index 80e644fc4f..61eb4ce0ed 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/GuardWidening.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/GuardWidening.cpp
@@ -347,8 +347,8 @@ bool GuardWideningImpl::eliminateInstrViaWidening(
const auto &GuardsInCurBB = GuardsInBlock.find(CurBB)->second;
auto I = GuardsInCurBB.begin();
- auto E = Instr->getParent() == CurBB ? find(GuardsInCurBB, Instr)
- : GuardsInCurBB.end();
+ auto E = Instr->getParent() == CurBB ? find(GuardsInCurBB, Instr)
+ : GuardsInCurBB.end();
#ifndef NDEBUG
{
@@ -665,12 +665,12 @@ bool GuardWideningImpl::combineRangeChecks(
};
copy_if(Checks, std::back_inserter(CurrentChecks), IsCurrentCheck);
- erase_if(Checks, IsCurrentCheck);
+ erase_if(Checks, IsCurrentCheck);
assert(CurrentChecks.size() != 0 && "We know we have at least one!");
if (CurrentChecks.size() < 3) {
- llvm::append_range(RangeChecksOut, CurrentChecks);
+ llvm::append_range(RangeChecksOut, CurrentChecks);
continue;
}
@@ -698,7 +698,7 @@ bool GuardWideningImpl::combineRangeChecks(
return (HighOffset - RC.getOffsetValue()).ult(MaxDiff);
};
- if (MaxDiff.isMinValue() || !all_of(drop_begin(CurrentChecks), OffsetOK))
+ if (MaxDiff.isMinValue() || !all_of(drop_begin(CurrentChecks), OffsetOK))
return false;
// We have a series of f+1 checks as:
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/IndVarSimplify.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/IndVarSimplify.cpp
index 29c45e83b9..ae1fff0fa8 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -131,10 +131,10 @@ static cl::opt<bool>
LoopPredication("indvars-predicate-loops", cl::Hidden, cl::init(true),
cl::desc("Predicate conditions in read only loops"));
-static cl::opt<bool>
-AllowIVWidening("indvars-widen-indvars", cl::Hidden, cl::init(true),
- cl::desc("Allow widening of indvars to eliminate s/zext"));
-
+static cl::opt<bool>
+AllowIVWidening("indvars-widen-indvars", cl::Hidden, cl::init(true),
+ cl::desc("Allow widening of indvars to eliminate s/zext"));
+
namespace {
struct RewritePhi;
@@ -149,7 +149,7 @@ class IndVarSimplify {
std::unique_ptr<MemorySSAUpdater> MSSAU;
SmallVector<WeakTrackingVH, 16> DeadInsts;
- bool WidenIndVars;
+ bool WidenIndVars;
bool handleFloatingPointIV(Loop *L, PHINode *PH);
bool rewriteNonIntegerIVs(Loop *L);
@@ -172,9 +172,9 @@ class IndVarSimplify {
public:
IndVarSimplify(LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT,
const DataLayout &DL, TargetLibraryInfo *TLI,
- TargetTransformInfo *TTI, MemorySSA *MSSA, bool WidenIndVars)
- : LI(LI), SE(SE), DT(DT), DL(DL), TLI(TLI), TTI(TTI),
- WidenIndVars(WidenIndVars) {
+ TargetTransformInfo *TTI, MemorySSA *MSSA, bool WidenIndVars)
+ : LI(LI), SE(SE), DT(DT), DL(DL), TLI(TLI), TTI(TTI),
+ WidenIndVars(WidenIndVars) {
if (MSSA)
MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
}
@@ -508,8 +508,8 @@ bool IndVarSimplify::rewriteFirstIterationLoopExitValues(Loop *L) {
/// Update information about the induction variable that is extended by this
/// sign or zero extend operation. This is used to determine the final width of
/// the IV before actually widening it.
-static void visitIVCast(CastInst *Cast, WideIVInfo &WI,
- ScalarEvolution *SE,
+static void visitIVCast(CastInst *Cast, WideIVInfo &WI,
+ ScalarEvolution *SE,
const TargetTransformInfo *TTI) {
bool IsSigned = Cast->getOpcode() == Instruction::SExt;
if (!IsSigned && Cast->getOpcode() != Instruction::ZExt)
@@ -631,18 +631,18 @@ bool IndVarSimplify::simplifyAndExtend(Loop *L,
}
} while(!LoopPhis.empty());
- // Continue if we disallowed widening.
- if (!WidenIndVars)
- continue;
-
+ // Continue if we disallowed widening.
+ if (!WidenIndVars)
+ continue;
+
for (; !WideIVs.empty(); WideIVs.pop_back()) {
- unsigned ElimExt;
- unsigned Widened;
- if (PHINode *WidePhi = createWideIV(WideIVs.back(), LI, SE, Rewriter,
- DT, DeadInsts, ElimExt, Widened,
- HasGuards, UsePostIncrementRanges)) {
- NumElimExt += ElimExt;
- NumWidened += Widened;
+ unsigned ElimExt;
+ unsigned Widened;
+ if (PHINode *WidePhi = createWideIV(WideIVs.back(), LI, SE, Rewriter,
+ DT, DeadInsts, ElimExt, Widened,
+ HasGuards, UsePostIncrementRanges)) {
+ NumElimExt += ElimExt;
+ NumWidened += Widened;
Changed = true;
LoopPhis.push_back(WidePhi);
}
@@ -785,7 +785,7 @@ static bool mustExecuteUBIfPoisonOnPathTo(Instruction *Root,
// If we can't analyze propagation through this instruction, just skip it
// and transitive users. Safe as false is a conservative result.
- if (!propagatesPoison(cast<Operator>(I)) && I != Root)
+ if (!propagatesPoison(cast<Operator>(I)) && I != Root)
continue;
if (KnownPoison.insert(I).second)
@@ -1290,116 +1290,116 @@ bool IndVarSimplify::sinkUnusedInvariants(Loop *L) {
return MadeAnyChanges;
}
-static void replaceExitCond(BranchInst *BI, Value *NewCond,
- SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
- auto *OldCond = BI->getCondition();
- BI->setCondition(NewCond);
- if (OldCond->use_empty())
- DeadInsts.emplace_back(OldCond);
-}
-
-static void foldExit(const Loop *L, BasicBlock *ExitingBB, bool IsTaken,
- SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
- BranchInst *BI = cast<BranchInst>(ExitingBB->getTerminator());
- bool ExitIfTrue = !L->contains(*succ_begin(ExitingBB));
- auto *OldCond = BI->getCondition();
- auto *NewCond =
- ConstantInt::get(OldCond->getType(), IsTaken ? ExitIfTrue : !ExitIfTrue);
- replaceExitCond(BI, NewCond, DeadInsts);
-}
-
-static void replaceWithInvariantCond(
- const Loop *L, BasicBlock *ExitingBB, ICmpInst::Predicate InvariantPred,
- const SCEV *InvariantLHS, const SCEV *InvariantRHS, SCEVExpander &Rewriter,
- SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
- BranchInst *BI = cast<BranchInst>(ExitingBB->getTerminator());
- Rewriter.setInsertPoint(BI);
- auto *LHSV = Rewriter.expandCodeFor(InvariantLHS);
- auto *RHSV = Rewriter.expandCodeFor(InvariantRHS);
- bool ExitIfTrue = !L->contains(*succ_begin(ExitingBB));
- if (ExitIfTrue)
- InvariantPred = ICmpInst::getInversePredicate(InvariantPred);
- IRBuilder<> Builder(BI);
- auto *NewCond = Builder.CreateICmp(InvariantPred, LHSV, RHSV,
- BI->getCondition()->getName());
- replaceExitCond(BI, NewCond, DeadInsts);
-}
-
-static bool optimizeLoopExitWithUnknownExitCount(
- const Loop *L, BranchInst *BI, BasicBlock *ExitingBB,
- const SCEV *MaxIter, bool Inverted, bool SkipLastIter,
- ScalarEvolution *SE, SCEVExpander &Rewriter,
- SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
- ICmpInst::Predicate Pred;
- Value *LHS, *RHS;
- using namespace PatternMatch;
- BasicBlock *TrueSucc, *FalseSucc;
- if (!match(BI, m_Br(m_ICmp(Pred, m_Value(LHS), m_Value(RHS)),
- m_BasicBlock(TrueSucc), m_BasicBlock(FalseSucc))))
- return false;
-
- assert((L->contains(TrueSucc) != L->contains(FalseSucc)) &&
- "Not a loop exit!");
-
- // 'LHS pred RHS' should now mean that we stay in loop.
- if (L->contains(FalseSucc))
- Pred = CmpInst::getInversePredicate(Pred);
-
- // If we are proving loop exit, invert the predicate.
- if (Inverted)
- Pred = CmpInst::getInversePredicate(Pred);
-
- const SCEV *LHSS = SE->getSCEVAtScope(LHS, L);
- const SCEV *RHSS = SE->getSCEVAtScope(RHS, L);
- // Can we prove it to be trivially true?
- if (SE->isKnownPredicateAt(Pred, LHSS, RHSS, BI)) {
- foldExit(L, ExitingBB, Inverted, DeadInsts);
- return true;
+static void replaceExitCond(BranchInst *BI, Value *NewCond,
+ SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
+ auto *OldCond = BI->getCondition();
+ BI->setCondition(NewCond);
+ if (OldCond->use_empty())
+ DeadInsts.emplace_back(OldCond);
+}
+
+static void foldExit(const Loop *L, BasicBlock *ExitingBB, bool IsTaken,
+ SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
+ BranchInst *BI = cast<BranchInst>(ExitingBB->getTerminator());
+ bool ExitIfTrue = !L->contains(*succ_begin(ExitingBB));
+ auto *OldCond = BI->getCondition();
+ auto *NewCond =
+ ConstantInt::get(OldCond->getType(), IsTaken ? ExitIfTrue : !ExitIfTrue);
+ replaceExitCond(BI, NewCond, DeadInsts);
+}
+
+static void replaceWithInvariantCond(
+ const Loop *L, BasicBlock *ExitingBB, ICmpInst::Predicate InvariantPred,
+ const SCEV *InvariantLHS, const SCEV *InvariantRHS, SCEVExpander &Rewriter,
+ SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
+ BranchInst *BI = cast<BranchInst>(ExitingBB->getTerminator());
+ Rewriter.setInsertPoint(BI);
+ auto *LHSV = Rewriter.expandCodeFor(InvariantLHS);
+ auto *RHSV = Rewriter.expandCodeFor(InvariantRHS);
+ bool ExitIfTrue = !L->contains(*succ_begin(ExitingBB));
+ if (ExitIfTrue)
+ InvariantPred = ICmpInst::getInversePredicate(InvariantPred);
+ IRBuilder<> Builder(BI);
+ auto *NewCond = Builder.CreateICmp(InvariantPred, LHSV, RHSV,
+ BI->getCondition()->getName());
+ replaceExitCond(BI, NewCond, DeadInsts);
+}
+
+static bool optimizeLoopExitWithUnknownExitCount(
+ const Loop *L, BranchInst *BI, BasicBlock *ExitingBB,
+ const SCEV *MaxIter, bool Inverted, bool SkipLastIter,
+ ScalarEvolution *SE, SCEVExpander &Rewriter,
+ SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
+ ICmpInst::Predicate Pred;
+ Value *LHS, *RHS;
+ using namespace PatternMatch;
+ BasicBlock *TrueSucc, *FalseSucc;
+ if (!match(BI, m_Br(m_ICmp(Pred, m_Value(LHS), m_Value(RHS)),
+ m_BasicBlock(TrueSucc), m_BasicBlock(FalseSucc))))
+ return false;
+
+ assert((L->contains(TrueSucc) != L->contains(FalseSucc)) &&
+ "Not a loop exit!");
+
+ // 'LHS pred RHS' should now mean that we stay in loop.
+ if (L->contains(FalseSucc))
+ Pred = CmpInst::getInversePredicate(Pred);
+
+ // If we are proving loop exit, invert the predicate.
+ if (Inverted)
+ Pred = CmpInst::getInversePredicate(Pred);
+
+ const SCEV *LHSS = SE->getSCEVAtScope(LHS, L);
+ const SCEV *RHSS = SE->getSCEVAtScope(RHS, L);
+ // Can we prove it to be trivially true?
+ if (SE->isKnownPredicateAt(Pred, LHSS, RHSS, BI)) {
+ foldExit(L, ExitingBB, Inverted, DeadInsts);
+ return true;
+ }
+ // Further logic works for non-inverted condition only.
+ if (Inverted)
+ return false;
+
+ auto *ARTy = LHSS->getType();
+ auto *MaxIterTy = MaxIter->getType();
+ // If possible, adjust types.
+ if (SE->getTypeSizeInBits(ARTy) > SE->getTypeSizeInBits(MaxIterTy))
+ MaxIter = SE->getZeroExtendExpr(MaxIter, ARTy);
+ else if (SE->getTypeSizeInBits(ARTy) < SE->getTypeSizeInBits(MaxIterTy)) {
+ const SCEV *MinusOne = SE->getMinusOne(ARTy);
+ auto *MaxAllowedIter = SE->getZeroExtendExpr(MinusOne, MaxIterTy);
+ if (SE->isKnownPredicateAt(ICmpInst::ICMP_ULE, MaxIter, MaxAllowedIter, BI))
+ MaxIter = SE->getTruncateExpr(MaxIter, ARTy);
+ }
+
+ if (SkipLastIter) {
+ const SCEV *One = SE->getOne(MaxIter->getType());
+ MaxIter = SE->getMinusSCEV(MaxIter, One);
}
- // Further logic works for non-inverted condition only.
- if (Inverted)
- return false;
-
- auto *ARTy = LHSS->getType();
- auto *MaxIterTy = MaxIter->getType();
- // If possible, adjust types.
- if (SE->getTypeSizeInBits(ARTy) > SE->getTypeSizeInBits(MaxIterTy))
- MaxIter = SE->getZeroExtendExpr(MaxIter, ARTy);
- else if (SE->getTypeSizeInBits(ARTy) < SE->getTypeSizeInBits(MaxIterTy)) {
- const SCEV *MinusOne = SE->getMinusOne(ARTy);
- auto *MaxAllowedIter = SE->getZeroExtendExpr(MinusOne, MaxIterTy);
- if (SE->isKnownPredicateAt(ICmpInst::ICMP_ULE, MaxIter, MaxAllowedIter, BI))
- MaxIter = SE->getTruncateExpr(MaxIter, ARTy);
- }
-
- if (SkipLastIter) {
- const SCEV *One = SE->getOne(MaxIter->getType());
- MaxIter = SE->getMinusSCEV(MaxIter, One);
- }
-
- // Check if there is a loop-invariant predicate equivalent to our check.
- auto LIP = SE->getLoopInvariantExitCondDuringFirstIterations(Pred, LHSS, RHSS,
- L, BI, MaxIter);
- if (!LIP)
- return false;
-
- // Can we prove it to be trivially true?
- if (SE->isKnownPredicateAt(LIP->Pred, LIP->LHS, LIP->RHS, BI))
- foldExit(L, ExitingBB, Inverted, DeadInsts);
- else
- replaceWithInvariantCond(L, ExitingBB, LIP->Pred, LIP->LHS, LIP->RHS,
- Rewriter, DeadInsts);
-
- return true;
+
+ // Check if there is a loop-invariant predicate equivalent to our check.
+ auto LIP = SE->getLoopInvariantExitCondDuringFirstIterations(Pred, LHSS, RHSS,
+ L, BI, MaxIter);
+ if (!LIP)
+ return false;
+
+ // Can we prove it to be trivially true?
+ if (SE->isKnownPredicateAt(LIP->Pred, LIP->LHS, LIP->RHS, BI))
+ foldExit(L, ExitingBB, Inverted, DeadInsts);
+ else
+ replaceWithInvariantCond(L, ExitingBB, LIP->Pred, LIP->LHS, LIP->RHS,
+ Rewriter, DeadInsts);
+
+ return true;
}
bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
SmallVector<BasicBlock*, 16> ExitingBlocks;
L->getExitingBlocks(ExitingBlocks);
- // Remove all exits which aren't both rewriteable and execute on every
- // iteration.
- llvm::erase_if(ExitingBlocks, [&](BasicBlock *ExitingBB) {
+ // Remove all exits which aren't both rewriteable and execute on every
+ // iteration.
+ llvm::erase_if(ExitingBlocks, [&](BasicBlock *ExitingBB) {
// If our exitting block exits multiple loops, we can only rewrite the
// innermost one. Otherwise, we're changing how many times the innermost
// loop runs before it exits.
@@ -1415,10 +1415,10 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
if (isa<Constant>(BI->getCondition()))
return true;
- // Likewise, the loop latch must be dominated by the exiting BB.
- if (!DT->dominates(ExitingBB, L->getLoopLatch()))
+ // Likewise, the loop latch must be dominated by the exiting BB.
+ if (!DT->dominates(ExitingBB, L->getLoopLatch()))
return true;
-
+
return false;
});
@@ -1426,25 +1426,25 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
return false;
// Get a symbolic upper bound on the loop backedge taken count.
- const SCEV *MaxExitCount = SE->getSymbolicMaxBackedgeTakenCount(L);
+ const SCEV *MaxExitCount = SE->getSymbolicMaxBackedgeTakenCount(L);
if (isa<SCEVCouldNotCompute>(MaxExitCount))
return false;
- // Visit our exit blocks in order of dominance. We know from the fact that
- // all exits must dominate the latch, so there is a total dominance order
- // between them.
- llvm::sort(ExitingBlocks, [&](BasicBlock *A, BasicBlock *B) {
+ // Visit our exit blocks in order of dominance. We know from the fact that
+ // all exits must dominate the latch, so there is a total dominance order
+ // between them.
+ llvm::sort(ExitingBlocks, [&](BasicBlock *A, BasicBlock *B) {
// std::sort sorts in ascending order, so we want the inverse of
// the normal dominance relation.
if (A == B) return false;
- if (DT->properlyDominates(A, B))
- return true;
- else {
- assert(DT->properlyDominates(B, A) &&
- "expected total dominance order!");
- return false;
- }
- });
+ if (DT->properlyDominates(A, B))
+ return true;
+ else {
+ assert(DT->properlyDominates(B, A) &&
+ "expected total dominance order!");
+ return false;
+ }
+ });
#ifdef ASSERT
for (unsigned i = 1; i < ExitingBlocks.size(); i++) {
assert(DT->dominates(ExitingBlocks[i-1], ExitingBlocks[i]));
@@ -1452,56 +1452,56 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
#endif
bool Changed = false;
- bool SkipLastIter = false;
+ bool SkipLastIter = false;
SmallSet<const SCEV*, 8> DominatingExitCounts;
for (BasicBlock *ExitingBB : ExitingBlocks) {
const SCEV *ExitCount = SE->getExitCount(L, ExitingBB);
- if (isa<SCEVCouldNotCompute>(ExitCount)) {
- // Okay, we do not know the exit count here. Can we at least prove that it
- // will remain the same within iteration space?
- auto *BI = cast<BranchInst>(ExitingBB->getTerminator());
- auto OptimizeCond = [&](bool Inverted, bool SkipLastIter) {
- return optimizeLoopExitWithUnknownExitCount(
- L, BI, ExitingBB, MaxExitCount, Inverted, SkipLastIter, SE,
- Rewriter, DeadInsts);
- };
-
- // TODO: We might have proved that we can skip the last iteration for
- // this check. In this case, we only want to check the condition on the
- // pre-last iteration (MaxExitCount - 1). However, there is a nasty
- // corner case:
- //
- // for (i = len; i != 0; i--) { ... check (i ult X) ... }
- //
- // If we could not prove that len != 0, then we also could not prove that
- // (len - 1) is not a UINT_MAX. If we simply query (len - 1), then
- // OptimizeCond will likely not prove anything for it, even if it could
- // prove the same fact for len.
- //
- // As a temporary solution, we query both last and pre-last iterations in
- // hope that we will be able to prove triviality for at least one of
- // them. We can stop querying MaxExitCount for this case once SCEV
- // understands that (MaxExitCount - 1) will not overflow here.
- if (OptimizeCond(false, false) || OptimizeCond(true, false))
- Changed = true;
- else if (SkipLastIter)
- if (OptimizeCond(false, true) || OptimizeCond(true, true))
- Changed = true;
- continue;
- }
-
- if (MaxExitCount == ExitCount)
- // If the loop has more than 1 iteration, all further checks will be
- // executed 1 iteration less.
- SkipLastIter = true;
-
+ if (isa<SCEVCouldNotCompute>(ExitCount)) {
+ // Okay, we do not know the exit count here. Can we at least prove that it
+ // will remain the same within iteration space?
+ auto *BI = cast<BranchInst>(ExitingBB->getTerminator());
+ auto OptimizeCond = [&](bool Inverted, bool SkipLastIter) {
+ return optimizeLoopExitWithUnknownExitCount(
+ L, BI, ExitingBB, MaxExitCount, Inverted, SkipLastIter, SE,
+ Rewriter, DeadInsts);
+ };
+
+ // TODO: We might have proved that we can skip the last iteration for
+ // this check. In this case, we only want to check the condition on the
+ // pre-last iteration (MaxExitCount - 1). However, there is a nasty
+ // corner case:
+ //
+ // for (i = len; i != 0; i--) { ... check (i ult X) ... }
+ //
+ // If we could not prove that len != 0, then we also could not prove that
+ // (len - 1) is not a UINT_MAX. If we simply query (len - 1), then
+ // OptimizeCond will likely not prove anything for it, even if it could
+ // prove the same fact for len.
+ //
+ // As a temporary solution, we query both last and pre-last iterations in
+ // hope that we will be able to prove triviality for at least one of
+ // them. We can stop querying MaxExitCount for this case once SCEV
+ // understands that (MaxExitCount - 1) will not overflow here.
+ if (OptimizeCond(false, false) || OptimizeCond(true, false))
+ Changed = true;
+ else if (SkipLastIter)
+ if (OptimizeCond(false, true) || OptimizeCond(true, true))
+ Changed = true;
+ continue;
+ }
+
+ if (MaxExitCount == ExitCount)
+ // If the loop has more than 1 iteration, all further checks will be
+ // executed 1 iteration less.
+ SkipLastIter = true;
+
// If we know we'd exit on the first iteration, rewrite the exit to
// reflect this. This does not imply the loop must exit through this
// exit; there may be an earlier one taken on the first iteration.
// TODO: Given we know the backedge can't be taken, we should go ahead
// and break it. Or at least, kill all the header phis and simplify.
if (ExitCount->isZero()) {
- foldExit(L, ExitingBB, true, DeadInsts);
+ foldExit(L, ExitingBB, true, DeadInsts);
Changed = true;
continue;
}
@@ -1523,7 +1523,7 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
// one?
if (SE->isLoopEntryGuardedByCond(L, CmpInst::ICMP_ULT,
MaxExitCount, ExitCount)) {
- foldExit(L, ExitingBB, false, DeadInsts);
+ foldExit(L, ExitingBB, false, DeadInsts);
Changed = true;
continue;
}
@@ -1533,7 +1533,7 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
// exiting iteration, but (from the visit order) strictly follows another
// which does the same and is thus dead.
if (!DominatingExitCounts.insert(ExitCount).second) {
- foldExit(L, ExitingBB, false, DeadInsts);
+ foldExit(L, ExitingBB, false, DeadInsts);
Changed = true;
continue;
}
@@ -1789,9 +1789,9 @@ bool IndVarSimplify::run(Loop *L) {
if (optimizeLoopExits(L, Rewriter)) {
Changed = true;
// Given we've changed exit counts, notify SCEV
- // Some nested loops may share same folded exit basic block,
- // thus we need to notify top most loop.
- SE->forgetTopmostLoop(L);
+ // Some nested loops may share same folded exit basic block,
+ // thus we need to notify top most loop.
+ SE->forgetTopmostLoop(L);
}
// Try to form loop invariant tests for loop exits by changing how many
@@ -1868,15 +1868,15 @@ bool IndVarSimplify::run(Loop *L) {
// Now that we're done iterating through lists, clean up any instructions
// which are now dead.
- while (!DeadInsts.empty()) {
- Value *V = DeadInsts.pop_back_val();
-
- if (PHINode *PHI = dyn_cast_or_null<PHINode>(V))
- Changed |= RecursivelyDeleteDeadPHINode(PHI, TLI, MSSAU.get());
- else if (Instruction *Inst = dyn_cast_or_null<Instruction>(V))
+ while (!DeadInsts.empty()) {
+ Value *V = DeadInsts.pop_back_val();
+
+ if (PHINode *PHI = dyn_cast_or_null<PHINode>(V))
+ Changed |= RecursivelyDeleteDeadPHINode(PHI, TLI, MSSAU.get());
+ else if (Instruction *Inst = dyn_cast_or_null<Instruction>(V))
Changed |=
RecursivelyDeleteTriviallyDeadInstructions(Inst, TLI, MSSAU.get());
- }
+ }
// The Rewriter may not be used from this point on.
@@ -1926,8 +1926,8 @@ PreservedAnalyses IndVarSimplifyPass::run(Loop &L, LoopAnalysisManager &AM,
Function *F = L.getHeader()->getParent();
const DataLayout &DL = F->getParent()->getDataLayout();
- IndVarSimplify IVS(&AR.LI, &AR.SE, &AR.DT, DL, &AR.TLI, &AR.TTI, AR.MSSA,
- WidenIndVars && AllowIVWidening);
+ IndVarSimplify IVS(&AR.LI, &AR.SE, &AR.DT, DL, &AR.TLI, &AR.TTI, AR.MSSA,
+ WidenIndVars && AllowIVWidening);
if (!IVS.run(&L))
return PreservedAnalyses::all();
@@ -1964,7 +1964,7 @@ struct IndVarSimplifyLegacyPass : public LoopPass {
if (MSSAAnalysis)
MSSA = &MSSAAnalysis->getMSSA();
- IndVarSimplify IVS(LI, SE, DT, DL, TLI, TTI, MSSA, AllowIVWidening);
+ IndVarSimplify IVS(LI, SE, DT, DL, TLI, TTI, MSSA, AllowIVWidening);
return IVS.run(L);
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
index 321f44932a..6e09dec198 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
@@ -52,7 +52,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/Analysis/BlockFrequencyInfo.h"
+#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/Analysis/LoopInfo.h"
@@ -113,9 +113,9 @@ static cl::opt<bool> PrintRangeChecks("irce-print-range-checks", cl::Hidden,
static cl::opt<bool> SkipProfitabilityChecks("irce-skip-profitability-checks",
cl::Hidden, cl::init(false));
-static cl::opt<unsigned> MinRuntimeIterations("irce-min-runtime-iterations",
- cl::Hidden, cl::init(10));
-
+static cl::opt<unsigned> MinRuntimeIterations("irce-min-runtime-iterations",
+ cl::Hidden, cl::init(10));
+
static cl::opt<bool> AllowUnsignedLatchCondition("irce-allow-unsigned-latch",
cl::Hidden, cl::init(true));
@@ -228,27 +228,27 @@ public:
SmallVectorImpl<InductiveRangeCheck> &Checks);
};
-struct LoopStructure;
-
+struct LoopStructure;
+
class InductiveRangeCheckElimination {
ScalarEvolution &SE;
BranchProbabilityInfo *BPI;
DominatorTree &DT;
LoopInfo &LI;
- using GetBFIFunc =
- llvm::Optional<llvm::function_ref<llvm::BlockFrequencyInfo &()> >;
- GetBFIFunc GetBFI;
-
- // Returns true if it is profitable to do a transform basing on estimation of
- // number of iterations.
- bool isProfitableToTransform(const Loop &L, LoopStructure &LS);
-
+ using GetBFIFunc =
+ llvm::Optional<llvm::function_ref<llvm::BlockFrequencyInfo &()> >;
+ GetBFIFunc GetBFI;
+
+ // Returns true if it is profitable to do a transform basing on estimation of
+ // number of iterations.
+ bool isProfitableToTransform(const Loop &L, LoopStructure &LS);
+
public:
InductiveRangeCheckElimination(ScalarEvolution &SE,
BranchProbabilityInfo *BPI, DominatorTree &DT,
- LoopInfo &LI, GetBFIFunc GetBFI = None)
- : SE(SE), BPI(BPI), DT(DT), LI(LI), GetBFI(GetBFI) {}
+ LoopInfo &LI, GetBFIFunc GetBFI = None)
+ : SE(SE), BPI(BPI), DT(DT), LI(LI), GetBFI(GetBFI) {}
bool run(Loop *L, function_ref<void(Loop *, bool)> LPMAddNewLoop);
};
@@ -505,8 +505,8 @@ struct LoopStructure {
return Result;
}
- static Optional<LoopStructure> parseLoopStructure(ScalarEvolution &, Loop &,
- const char *&);
+ static Optional<LoopStructure> parseLoopStructure(ScalarEvolution &, Loop &,
+ const char *&);
};
/// This class is used to constrain loops to run within a given iteration space.
@@ -750,7 +750,7 @@ static bool isSafeIncreasingBound(const SCEV *Start,
}
Optional<LoopStructure>
-LoopStructure::parseLoopStructure(ScalarEvolution &SE, Loop &L,
+LoopStructure::parseLoopStructure(ScalarEvolution &SE, Loop &L,
const char *&FailureReason) {
if (!L.isLoopSimplifyForm()) {
FailureReason = "loop not in LoopSimplify form";
@@ -1768,25 +1768,25 @@ PreservedAnalyses IRCEPass::run(Function &F, FunctionAnalysisManager &AM) {
auto &BPI = AM.getResult<BranchProbabilityAnalysis>(F);
LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
- // Get BFI analysis result on demand. Please note that modification of
- // CFG invalidates this analysis and we should handle it.
- auto getBFI = [&F, &AM ]()->BlockFrequencyInfo & {
- return AM.getResult<BlockFrequencyAnalysis>(F);
- };
- InductiveRangeCheckElimination IRCE(SE, &BPI, DT, LI, { getBFI });
+ // Get BFI analysis result on demand. Please note that modification of
+ // CFG invalidates this analysis and we should handle it.
+ auto getBFI = [&F, &AM ]()->BlockFrequencyInfo & {
+ return AM.getResult<BlockFrequencyAnalysis>(F);
+ };
+ InductiveRangeCheckElimination IRCE(SE, &BPI, DT, LI, { getBFI });
bool Changed = false;
- {
- bool CFGChanged = false;
- for (const auto &L : LI) {
- CFGChanged |= simplifyLoop(L, &DT, &LI, &SE, nullptr, nullptr,
- /*PreserveLCSSA=*/false);
- Changed |= formLCSSARecursively(*L, DT, &LI, &SE);
- }
- Changed |= CFGChanged;
-
- if (CFGChanged && !SkipProfitabilityChecks)
- AM.invalidate<BlockFrequencyAnalysis>(F);
+ {
+ bool CFGChanged = false;
+ for (const auto &L : LI) {
+ CFGChanged |= simplifyLoop(L, &DT, &LI, &SE, nullptr, nullptr,
+ /*PreserveLCSSA=*/false);
+ Changed |= formLCSSARecursively(*L, DT, &LI, &SE);
+ }
+ Changed |= CFGChanged;
+
+ if (CFGChanged && !SkipProfitabilityChecks)
+ AM.invalidate<BlockFrequencyAnalysis>(F);
}
SmallPriorityWorklist<Loop *, 4> Worklist;
@@ -1798,11 +1798,11 @@ PreservedAnalyses IRCEPass::run(Function &F, FunctionAnalysisManager &AM) {
while (!Worklist.empty()) {
Loop *L = Worklist.pop_back_val();
- if (IRCE.run(L, LPMAddNewLoop)) {
- Changed = true;
- if (!SkipProfitabilityChecks)
- AM.invalidate<BlockFrequencyAnalysis>(F);
- }
+ if (IRCE.run(L, LPMAddNewLoop)) {
+ Changed = true;
+ if (!SkipProfitabilityChecks)
+ AM.invalidate<BlockFrequencyAnalysis>(F);
+ }
}
if (!Changed)
@@ -1843,37 +1843,37 @@ bool IRCELegacyPass::runOnFunction(Function &F) {
return Changed;
}
-bool
-InductiveRangeCheckElimination::isProfitableToTransform(const Loop &L,
- LoopStructure &LS) {
- if (SkipProfitabilityChecks)
- return true;
- if (GetBFI.hasValue()) {
- BlockFrequencyInfo &BFI = (*GetBFI)();
- uint64_t hFreq = BFI.getBlockFreq(LS.Header).getFrequency();
- uint64_t phFreq = BFI.getBlockFreq(L.getLoopPreheader()).getFrequency();
- if (phFreq != 0 && hFreq != 0 && (hFreq / phFreq < MinRuntimeIterations)) {
- LLVM_DEBUG(dbgs() << "irce: could not prove profitability: "
- << "the estimated number of iterations basing on "
- "frequency info is " << (hFreq / phFreq) << "\n";);
- return false;
- }
- return true;
- }
-
- if (!BPI)
- return true;
- BranchProbability ExitProbability =
- BPI->getEdgeProbability(LS.Latch, LS.LatchBrExitIdx);
- if (ExitProbability > BranchProbability(1, MinRuntimeIterations)) {
- LLVM_DEBUG(dbgs() << "irce: could not prove profitability: "
- << "the exit probability is too big " << ExitProbability
- << "\n";);
- return false;
- }
- return true;
-}
-
+bool
+InductiveRangeCheckElimination::isProfitableToTransform(const Loop &L,
+ LoopStructure &LS) {
+ if (SkipProfitabilityChecks)
+ return true;
+ if (GetBFI.hasValue()) {
+ BlockFrequencyInfo &BFI = (*GetBFI)();
+ uint64_t hFreq = BFI.getBlockFreq(LS.Header).getFrequency();
+ uint64_t phFreq = BFI.getBlockFreq(L.getLoopPreheader()).getFrequency();
+ if (phFreq != 0 && hFreq != 0 && (hFreq / phFreq < MinRuntimeIterations)) {
+ LLVM_DEBUG(dbgs() << "irce: could not prove profitability: "
+ << "the estimated number of iterations basing on "
+ "frequency info is " << (hFreq / phFreq) << "\n";);
+ return false;
+ }
+ return true;
+ }
+
+ if (!BPI)
+ return true;
+ BranchProbability ExitProbability =
+ BPI->getEdgeProbability(LS.Latch, LS.LatchBrExitIdx);
+ if (ExitProbability > BranchProbability(1, MinRuntimeIterations)) {
+ LLVM_DEBUG(dbgs() << "irce: could not prove profitability: "
+ << "the exit probability is too big " << ExitProbability
+ << "\n";);
+ return false;
+ }
+ return true;
+}
+
bool InductiveRangeCheckElimination::run(
Loop *L, function_ref<void(Loop *, bool)> LPMAddNewLoop) {
if (L->getBlocks().size() >= LoopSizeCutoff) {
@@ -1913,15 +1913,15 @@ bool InductiveRangeCheckElimination::run(
const char *FailureReason = nullptr;
Optional<LoopStructure> MaybeLoopStructure =
- LoopStructure::parseLoopStructure(SE, *L, FailureReason);
+ LoopStructure::parseLoopStructure(SE, *L, FailureReason);
if (!MaybeLoopStructure.hasValue()) {
LLVM_DEBUG(dbgs() << "irce: could not parse loop structure: "
<< FailureReason << "\n";);
return false;
}
LoopStructure LS = MaybeLoopStructure.getValue();
- if (!isProfitableToTransform(*L, LS))
- return false;
+ if (!isProfitableToTransform(*L, LS))
+ return false;
const SCEVAddRecExpr *IndVar =
cast<SCEVAddRecExpr>(SE.getMinusSCEV(SE.getSCEV(LS.IndVarBase), SE.getSCEV(LS.IndVarStep)));
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/InferAddressSpaces.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/InferAddressSpaces.cpp
index 9127f3c2e0..332eb10ac1 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/InferAddressSpaces.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/InferAddressSpaces.cpp
@@ -88,7 +88,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/Scalar/InferAddressSpaces.h"
+#include "llvm/Transforms/Scalar/InferAddressSpaces.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
@@ -109,7 +109,7 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Operator.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
@@ -164,16 +164,16 @@ public:
}
bool runOnFunction(Function &F) override;
-};
-
-class InferAddressSpacesImpl {
- const TargetTransformInfo *TTI = nullptr;
- const DataLayout *DL = nullptr;
-
- /// Target specific address space which uses of should be replaced if
- /// possible.
- unsigned FlatAddrSpace = 0;
-
+};
+
+class InferAddressSpacesImpl {
+ const TargetTransformInfo *TTI = nullptr;
+ const DataLayout *DL = nullptr;
+
+ /// Target specific address space which uses of should be replaced if
+ /// possible.
+ unsigned FlatAddrSpace = 0;
+
// Returns the new address space of V if updated; otherwise, returns None.
Optional<unsigned>
updateAddressSpace(const Value &V,
@@ -215,11 +215,11 @@ class InferAddressSpacesImpl {
const ValueToValueMapTy &ValueWithNewAddrSpace,
SmallVectorImpl<const Use *> *UndefUsesToFix) const;
unsigned joinAddressSpaces(unsigned AS1, unsigned AS2) const;
-
-public:
- InferAddressSpacesImpl(const TargetTransformInfo *TTI, unsigned FlatAddrSpace)
- : TTI(TTI), FlatAddrSpace(FlatAddrSpace) {}
- bool run(Function &F);
+
+public:
+ InferAddressSpacesImpl(const TargetTransformInfo *TTI, unsigned FlatAddrSpace)
+ : TTI(TTI), FlatAddrSpace(FlatAddrSpace) {}
+ bool run(Function &F);
};
} // end anonymous namespace
@@ -295,8 +295,8 @@ static bool isAddressExpression(const Value &V, const DataLayout &DL,
case Instruction::IntToPtr:
return isNoopPtrIntCastPair(Op, DL, TTI);
default:
- // That value is an address expression if it has an assumed address space.
- return TTI->getAssumedAddrSpace(&V) != UninitializedAddressSpace;
+ // That value is an address expression if it has an assumed address space.
+ return TTI->getAssumedAddrSpace(&V) != UninitializedAddressSpace;
}
}
@@ -335,9 +335,9 @@ getPointerOperands(const Value &V, const DataLayout &DL,
}
}
-bool InferAddressSpacesImpl::rewriteIntrinsicOperands(IntrinsicInst *II,
- Value *OldV,
- Value *NewV) const {
+bool InferAddressSpacesImpl::rewriteIntrinsicOperands(IntrinsicInst *II,
+ Value *OldV,
+ Value *NewV) const {
Module *M = II->getParent()->getParent()->getParent();
switch (II->getIntrinsicID()) {
@@ -364,7 +364,7 @@ bool InferAddressSpacesImpl::rewriteIntrinsicOperands(IntrinsicInst *II,
}
}
-void InferAddressSpacesImpl::collectRewritableIntrinsicOperands(
+void InferAddressSpacesImpl::collectRewritableIntrinsicOperands(
IntrinsicInst *II, PostorderStackTy &PostorderStack,
DenseSet<Value *> &Visited) const {
auto IID = II->getIntrinsicID();
@@ -389,7 +389,7 @@ void InferAddressSpacesImpl::collectRewritableIntrinsicOperands(
// Returns all flat address expressions in function F. The elements are
// If V is an unvisited flat address expression, appends V to PostorderStack
// and marks it as visited.
-void InferAddressSpacesImpl::appendsFlatAddressExpressionToPostorderStack(
+void InferAddressSpacesImpl::appendsFlatAddressExpressionToPostorderStack(
Value *V, PostorderStackTy &PostorderStack,
DenseSet<Value *> &Visited) const {
assert(V->getType()->isPointerTy());
@@ -404,8 +404,8 @@ void InferAddressSpacesImpl::appendsFlatAddressExpressionToPostorderStack(
return;
}
- if (V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
- isAddressExpression(*V, *DL, TTI)) {
+ if (V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
+ isAddressExpression(*V, *DL, TTI)) {
if (Visited.insert(V).second) {
PostorderStack.emplace_back(V, false);
@@ -423,7 +423,7 @@ void InferAddressSpacesImpl::appendsFlatAddressExpressionToPostorderStack(
// Returns all flat address expressions in function F. The elements are ordered
// ordered in postorder.
std::vector<WeakTrackingVH>
-InferAddressSpacesImpl::collectFlatAddressExpressions(Function &F) const {
+InferAddressSpacesImpl::collectFlatAddressExpressions(Function &F) const {
// This function implements a non-recursive postorder traversal of a partial
// use-def graph of function F.
PostorderStackTy PostorderStack;
@@ -488,12 +488,12 @@ InferAddressSpacesImpl::collectFlatAddressExpressions(Function &F) const {
}
// Otherwise, adds its operands to the stack and explores them.
PostorderStack.back().setInt(true);
- // Skip values with an assumed address space.
- if (TTI->getAssumedAddrSpace(TopVal) == UninitializedAddressSpace) {
- for (Value *PtrOperand : getPointerOperands(*TopVal, *DL, TTI)) {
- appendsFlatAddressExpressionToPostorderStack(PtrOperand, PostorderStack,
- Visited);
- }
+ // Skip values with an assumed address space.
+ if (TTI->getAssumedAddrSpace(TopVal) == UninitializedAddressSpace) {
+ for (Value *PtrOperand : getPointerOperands(*TopVal, *DL, TTI)) {
+ appendsFlatAddressExpressionToPostorderStack(PtrOperand, PostorderStack,
+ Visited);
+ }
}
}
return Postorder;
@@ -533,7 +533,7 @@ static Value *operandWithNewAddressSpaceOrCreateUndef(
//
// This may also return nullptr in the case the instruction could not be
// rewritten.
-Value *InferAddressSpacesImpl::cloneInstructionWithNewAddressSpace(
+Value *InferAddressSpacesImpl::cloneInstructionWithNewAddressSpace(
Instruction *I, unsigned NewAddrSpace,
const ValueToValueMapTy &ValueWithNewAddrSpace,
SmallVectorImpl<const Use *> *UndefUsesToFix) const {
@@ -568,16 +568,16 @@ Value *InferAddressSpacesImpl::cloneInstructionWithNewAddressSpace(
return nullptr;
}
- unsigned AS = TTI->getAssumedAddrSpace(I);
- if (AS != UninitializedAddressSpace) {
- // For the assumed address space, insert an `addrspacecast` to make that
- // explicit.
- auto *NewPtrTy = I->getType()->getPointerElementType()->getPointerTo(AS);
- auto *NewI = new AddrSpaceCastInst(I, NewPtrTy);
- NewI->insertAfter(I);
- return NewI;
- }
-
+ unsigned AS = TTI->getAssumedAddrSpace(I);
+ if (AS != UninitializedAddressSpace) {
+ // For the assumed address space, insert an `addrspacecast` to make that
+ // explicit.
+ auto *NewPtrTy = I->getType()->getPointerElementType()->getPointerTo(AS);
+ auto *NewI = new AddrSpaceCastInst(I, NewPtrTy);
+ NewI->insertAfter(I);
+ return NewI;
+ }
+
// Computes the converted pointer operands.
SmallVector<Value *, 4> NewPointerOperands;
for (const Use &OperandUse : I->operands()) {
@@ -606,7 +606,7 @@ Value *InferAddressSpacesImpl::cloneInstructionWithNewAddressSpace(
GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
GetElementPtrInst *NewGEP = GetElementPtrInst::Create(
GEP->getSourceElementType(), NewPointerOperands[0],
- SmallVector<Value *, 4>(GEP->indices()));
+ SmallVector<Value *, 4>(GEP->indices()));
NewGEP->setIsInBounds(GEP->isInBounds());
return NewGEP;
}
@@ -718,13 +718,13 @@ static Value *cloneConstantExprWithNewAddressSpace(
// expression whose address space needs to be modified, in postorder.
//
// See cloneInstructionWithNewAddressSpace for the meaning of UndefUsesToFix.
-Value *InferAddressSpacesImpl::cloneValueWithNewAddressSpace(
- Value *V, unsigned NewAddrSpace,
- const ValueToValueMapTy &ValueWithNewAddrSpace,
- SmallVectorImpl<const Use *> *UndefUsesToFix) const {
+Value *InferAddressSpacesImpl::cloneValueWithNewAddressSpace(
+ Value *V, unsigned NewAddrSpace,
+ const ValueToValueMapTy &ValueWithNewAddrSpace,
+ SmallVectorImpl<const Use *> *UndefUsesToFix) const {
// All values in Postorder are flat address expressions.
- assert(V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
- isAddressExpression(*V, *DL, TTI));
+ assert(V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
+ isAddressExpression(*V, *DL, TTI));
if (Instruction *I = dyn_cast<Instruction>(V)) {
Value *NewV = cloneInstructionWithNewAddressSpace(
@@ -744,8 +744,8 @@ Value *InferAddressSpacesImpl::cloneValueWithNewAddressSpace(
// Defines the join operation on the address space lattice (see the file header
// comments).
-unsigned InferAddressSpacesImpl::joinAddressSpaces(unsigned AS1,
- unsigned AS2) const {
+unsigned InferAddressSpacesImpl::joinAddressSpaces(unsigned AS1,
+ unsigned AS2) const {
if (AS1 == FlatAddrSpace || AS2 == FlatAddrSpace)
return FlatAddrSpace;
@@ -758,7 +758,7 @@ unsigned InferAddressSpacesImpl::joinAddressSpaces(unsigned AS1,
return (AS1 == AS2) ? AS1 : FlatAddrSpace;
}
-bool InferAddressSpacesImpl::run(Function &F) {
+bool InferAddressSpacesImpl::run(Function &F) {
DL = &F.getParent()->getDataLayout();
if (AssumeDefaultIsFlatAddressSpace)
@@ -785,7 +785,7 @@ bool InferAddressSpacesImpl::run(Function &F) {
// Constants need to be tracked through RAUW to handle cases with nested
// constant expressions, so wrap values in WeakTrackingVH.
-void InferAddressSpacesImpl::inferAddressSpaces(
+void InferAddressSpacesImpl::inferAddressSpaces(
ArrayRef<WeakTrackingVH> Postorder,
ValueToAddrSpaceMapTy *InferredAddrSpace) const {
SetVector<Value *> Worklist(Postorder.begin(), Postorder.end());
@@ -829,7 +829,7 @@ void InferAddressSpacesImpl::inferAddressSpaces(
}
}
-Optional<unsigned> InferAddressSpacesImpl::updateAddressSpace(
+Optional<unsigned> InferAddressSpacesImpl::updateAddressSpace(
const Value &V, const ValueToAddrSpaceMapTy &InferredAddrSpace) const {
assert(InferredAddrSpace.count(&V));
@@ -867,24 +867,24 @@ Optional<unsigned> InferAddressSpacesImpl::updateAddressSpace(
else
NewAS = joinAddressSpaces(Src0AS, Src1AS);
} else {
- unsigned AS = TTI->getAssumedAddrSpace(&V);
- if (AS != UninitializedAddressSpace) {
- // Use the assumed address space directly.
- NewAS = AS;
- } else {
- // Otherwise, infer the address space from its pointer operands.
- for (Value *PtrOperand : getPointerOperands(V, *DL, TTI)) {
- auto I = InferredAddrSpace.find(PtrOperand);
- unsigned OperandAS =
- I != InferredAddrSpace.end()
- ? I->second
- : PtrOperand->getType()->getPointerAddressSpace();
-
- // join(flat, *) = flat. So we can break if NewAS is already flat.
- NewAS = joinAddressSpaces(NewAS, OperandAS);
- if (NewAS == FlatAddrSpace)
- break;
- }
+ unsigned AS = TTI->getAssumedAddrSpace(&V);
+ if (AS != UninitializedAddressSpace) {
+ // Use the assumed address space directly.
+ NewAS = AS;
+ } else {
+ // Otherwise, infer the address space from its pointer operands.
+ for (Value *PtrOperand : getPointerOperands(V, *DL, TTI)) {
+ auto I = InferredAddrSpace.find(PtrOperand);
+ unsigned OperandAS =
+ I != InferredAddrSpace.end()
+ ? I->second
+ : PtrOperand->getType()->getPointerAddressSpace();
+
+ // join(flat, *) = flat. So we can break if NewAS is already flat.
+ NewAS = joinAddressSpaces(NewAS, OperandAS);
+ if (NewAS == FlatAddrSpace)
+ break;
+ }
}
}
@@ -975,8 +975,8 @@ static bool handleMemIntrinsicPtrUse(MemIntrinsic *MI, Value *OldV,
// \p returns true if it is OK to change the address space of constant \p C with
// a ConstantExpr addrspacecast.
-bool InferAddressSpacesImpl::isSafeToCastConstAddrSpace(Constant *C,
- unsigned NewAS) const {
+bool InferAddressSpacesImpl::isSafeToCastConstAddrSpace(Constant *C,
+ unsigned NewAS) const {
assert(NewAS != UninitializedAddressSpace);
unsigned SrcAS = C->getType()->getPointerAddressSpace();
@@ -1015,7 +1015,7 @@ static Value::use_iterator skipToNextUser(Value::use_iterator I,
return I;
}
-bool InferAddressSpacesImpl::rewriteWithNewAddressSpaces(
+bool InferAddressSpacesImpl::rewriteWithNewAddressSpaces(
const TargetTransformInfo &TTI, ArrayRef<WeakTrackingVH> Postorder,
const ValueToAddrSpaceMapTy &InferredAddrSpace, Function *F) const {
// For each address expression to be modified, creates a clone of it with its
@@ -1026,12 +1026,12 @@ bool InferAddressSpacesImpl::rewriteWithNewAddressSpaces(
SmallVector<const Use *, 32> UndefUsesToFix;
for (Value* V : Postorder) {
unsigned NewAddrSpace = InferredAddrSpace.lookup(V);
-
- // In some degenerate cases (e.g. invalid IR in unreachable code), we may
- // not even infer the value to have its original address space.
- if (NewAddrSpace == UninitializedAddressSpace)
- continue;
-
+
+ // In some degenerate cases (e.g. invalid IR in unreachable code), we may
+ // not even infer the value to have its original address space.
+ if (NewAddrSpace == UninitializedAddressSpace)
+ continue;
+
if (V->getType()->getPointerAddressSpace() != NewAddrSpace) {
Value *New = cloneValueWithNewAddressSpace(
V, NewAddrSpace, ValueWithNewAddrSpace, &UndefUsesToFix);
@@ -1097,9 +1097,9 @@ bool InferAddressSpacesImpl::rewriteWithNewAddressSpaces(
}
User *CurUser = U.getUser();
- // Skip if the current user is the new value itself.
- if (CurUser == NewV)
- continue;
+ // Skip if the current user is the new value itself.
+ if (CurUser == NewV)
+ continue;
// Handle more complex cases like intrinsic that need to be remangled.
if (auto *MI = dyn_cast<MemIntrinsic>(CurUser)) {
if (!MI->isVolatile() && handleMemIntrinsicPtrUse(MI, V, NewV))
@@ -1186,34 +1186,34 @@ bool InferAddressSpacesImpl::rewriteWithNewAddressSpaces(
return true;
}
-bool InferAddressSpaces::runOnFunction(Function &F) {
- if (skipFunction(F))
- return false;
-
- return InferAddressSpacesImpl(
- &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F),
- FlatAddrSpace)
- .run(F);
-}
-
+bool InferAddressSpaces::runOnFunction(Function &F) {
+ if (skipFunction(F))
+ return false;
+
+ return InferAddressSpacesImpl(
+ &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F),
+ FlatAddrSpace)
+ .run(F);
+}
+
FunctionPass *llvm::createInferAddressSpacesPass(unsigned AddressSpace) {
return new InferAddressSpaces(AddressSpace);
}
-
-InferAddressSpacesPass::InferAddressSpacesPass()
- : FlatAddrSpace(UninitializedAddressSpace) {}
-InferAddressSpacesPass::InferAddressSpacesPass(unsigned AddressSpace)
- : FlatAddrSpace(AddressSpace) {}
-
-PreservedAnalyses InferAddressSpacesPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- bool Changed =
- InferAddressSpacesImpl(&AM.getResult<TargetIRAnalysis>(F), FlatAddrSpace)
- .run(F);
- if (Changed) {
- PreservedAnalyses PA;
- PA.preserveSet<CFGAnalyses>();
- return PA;
- }
- return PreservedAnalyses::all();
-}
+
+InferAddressSpacesPass::InferAddressSpacesPass()
+ : FlatAddrSpace(UninitializedAddressSpace) {}
+InferAddressSpacesPass::InferAddressSpacesPass(unsigned AddressSpace)
+ : FlatAddrSpace(AddressSpace) {}
+
+PreservedAnalyses InferAddressSpacesPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ bool Changed =
+ InferAddressSpacesImpl(&AM.getResult<TargetIRAnalysis>(F), FlatAddrSpace)
+ .run(F);
+ if (Changed) {
+ PreservedAnalyses PA;
+ PA.preserveSet<CFGAnalyses>();
+ return PA;
+ }
+ return PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/InstSimplifyPass.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/InstSimplifyPass.cpp
index aeb83643b6..c11d2e4c1d 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/InstSimplifyPass.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/InstSimplifyPass.cpp
@@ -20,10 +20,10 @@
#include "llvm/IR/Type.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
-#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils.h"
#include "llvm/Transforms/Utils/Local.h"
-
+
using namespace llvm;
#define DEBUG_TYPE "instsimplify"
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/JumpThreading.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/JumpThreading.cpp
index 3e86ad4c14..10b08b4e22 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/JumpThreading.cpp
@@ -32,7 +32,7 @@
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
@@ -105,11 +105,11 @@ static cl::opt<bool> PrintLVIAfterJumpThreading(
cl::desc("Print the LazyValueInfo cache after JumpThreading"), cl::init(false),
cl::Hidden);
-static cl::opt<bool> JumpThreadingFreezeSelectCond(
- "jump-threading-freeze-select-cond",
- cl::desc("Freeze the condition when unfolding select"), cl::init(false),
- cl::Hidden);
-
+static cl::opt<bool> JumpThreadingFreezeSelectCond(
+ "jump-threading-freeze-select-cond",
+ cl::desc("Freeze the condition when unfolding select"), cl::init(false),
+ cl::Hidden);
+
static cl::opt<bool> ThreadAcrossLoopHeaders(
"jump-threading-across-loop-headers",
cl::desc("Allow JumpThreading to thread across loop headers, for testing"),
@@ -139,8 +139,8 @@ namespace {
public:
static char ID; // Pass identification
- JumpThreading(bool InsertFreezeWhenUnfoldingSelect = false, int T = -1)
- : FunctionPass(ID), Impl(InsertFreezeWhenUnfoldingSelect, T) {
+ JumpThreading(bool InsertFreezeWhenUnfoldingSelect = false, int T = -1)
+ : FunctionPass(ID), Impl(InsertFreezeWhenUnfoldingSelect, T) {
initializeJumpThreadingPass(*PassRegistry::getPassRegistry());
}
@@ -154,7 +154,7 @@ namespace {
AU.addPreserved<LazyValueInfoWrapperPass>();
AU.addPreserved<GlobalsAAWrapperPass>();
AU.addRequired<TargetLibraryInfoWrapperPass>();
- AU.addRequired<TargetTransformInfoWrapperPass>();
+ AU.addRequired<TargetTransformInfoWrapperPass>();
}
void releaseMemory() override { Impl.releaseMemory(); }
@@ -174,12 +174,12 @@ INITIALIZE_PASS_END(JumpThreading, "jump-threading",
"Jump Threading", false, false)
// Public interface to the Jump Threading pass
-FunctionPass *llvm::createJumpThreadingPass(bool InsertFr, int Threshold) {
- return new JumpThreading(InsertFr, Threshold);
+FunctionPass *llvm::createJumpThreadingPass(bool InsertFr, int Threshold) {
+ return new JumpThreading(InsertFr, Threshold);
}
-JumpThreadingPass::JumpThreadingPass(bool InsertFr, int T) {
- InsertFreezeWhenUnfoldingSelect = JumpThreadingFreezeSelectCond | InsertFr;
+JumpThreadingPass::JumpThreadingPass(bool InsertFr, int T) {
+ InsertFreezeWhenUnfoldingSelect = JumpThreadingFreezeSelectCond | InsertFr;
DefaultBBDupThreshold = (T == -1) ? BBDuplicateThreshold : unsigned(T);
}
@@ -313,10 +313,10 @@ static void updatePredecessorProfileMetadata(PHINode *PN, BasicBlock *BB) {
bool JumpThreading::runOnFunction(Function &F) {
if (skipFunction(F))
return false;
- auto TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
- // Jump Threading has no sense for the targets with divergent CF
- if (TTI->hasBranchDivergence())
- return false;
+ auto TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
+ // Jump Threading has no sense for the targets with divergent CF
+ if (TTI->hasBranchDivergence())
+ return false;
auto TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
auto DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
auto LVI = &getAnalysis<LazyValueInfoWrapperPass>().getLVI();
@@ -341,10 +341,10 @@ bool JumpThreading::runOnFunction(Function &F) {
PreservedAnalyses JumpThreadingPass::run(Function &F,
FunctionAnalysisManager &AM) {
- auto &TTI = AM.getResult<TargetIRAnalysis>(F);
- // Jump Threading has no sense for the targets with divergent CF
- if (TTI.hasBranchDivergence())
- return PreservedAnalyses::all();
+ auto &TTI = AM.getResult<TargetIRAnalysis>(F);
+ // Jump Threading has no sense for the targets with divergent CF
+ if (TTI.hasBranchDivergence())
+ return PreservedAnalyses::all();
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
auto &LVI = AM.getResult<LazyValueAnalysis>(F);
@@ -362,11 +362,11 @@ PreservedAnalyses JumpThreadingPass::run(Function &F,
bool Changed = runImpl(F, &TLI, &LVI, &AA, &DTU, F.hasProfileData(),
std::move(BFI), std::move(BPI));
- if (PrintLVIAfterJumpThreading) {
- dbgs() << "LVI for function '" << F.getName() << "':\n";
- LVI.printLVI(F, DTU.getDomTree(), dbgs());
- }
-
+ if (PrintLVIAfterJumpThreading) {
+ dbgs() << "LVI for function '" << F.getName() << "':\n";
+ LVI.printLVI(F, DTU.getDomTree(), dbgs());
+ }
+
if (!Changed)
return PreservedAnalyses::all();
PreservedAnalyses PA;
@@ -419,7 +419,7 @@ bool JumpThreadingPass::runImpl(Function &F, TargetLibraryInfo *TLI_,
Unreachable.insert(&BB);
if (!ThreadAcrossLoopHeaders)
- findLoopHeaders(F);
+ findLoopHeaders(F);
bool EverChanged = false;
bool Changed;
@@ -428,7 +428,7 @@ bool JumpThreadingPass::runImpl(Function &F, TargetLibraryInfo *TLI_,
for (auto &BB : F) {
if (Unreachable.count(&BB))
continue;
- while (processBlock(&BB)) // Thread all of the branches we can over BB.
+ while (processBlock(&BB)) // Thread all of the branches we can over BB.
Changed = true;
// Jump threading may have introduced redundant debug values into BB
@@ -443,7 +443,7 @@ bool JumpThreadingPass::runImpl(Function &F, TargetLibraryInfo *TLI_,
continue;
if (pred_empty(&BB)) {
- // When processBlock makes BB unreachable it doesn't bother to fix up
+ // When processBlock makes BB unreachable it doesn't bother to fix up
// the instructions in it. We must remove BB to prevent invalid IR.
LLVM_DEBUG(dbgs() << " JT: Deleting dead block '" << BB.getName()
<< "' with terminator: " << *BB.getTerminator()
@@ -455,7 +455,7 @@ bool JumpThreadingPass::runImpl(Function &F, TargetLibraryInfo *TLI_,
continue;
}
- // processBlock doesn't thread BBs with unconditional TIs. However, if BB
+ // processBlock doesn't thread BBs with unconditional TIs. However, if BB
// is "almost empty", we attempt to merge BB with its sole successor.
auto *BI = dyn_cast<BranchInst>(BB.getTerminator());
if (BI && BI->isUnconditional()) {
@@ -489,7 +489,7 @@ bool JumpThreadingPass::runImpl(Function &F, TargetLibraryInfo *TLI_,
// at the end of block. RAUW unconditionally replaces all uses
// including the guards/assumes themselves and the uses before the
// guard/assume.
-static void replaceFoldableUses(Instruction *Cond, Value *ToVal) {
+static void replaceFoldableUses(Instruction *Cond, Value *ToVal) {
assert(Cond->getType() == ToVal->getType());
auto *BB = Cond->getParent();
// We can unconditionally replace all uses in non-local blocks (i.e. uses
@@ -553,18 +553,18 @@ static unsigned getJumpThreadDuplicationCost(BasicBlock *BB,
// Debugger intrinsics don't incur code size.
if (isa<DbgInfoIntrinsic>(I)) continue;
- // Pseudo-probes don't incur code size.
- if (isa<PseudoProbeInst>(I))
- continue;
-
+ // Pseudo-probes don't incur code size.
+ if (isa<PseudoProbeInst>(I))
+ continue;
+
// If this is a pointer->pointer bitcast, it is free.
if (isa<BitCastInst>(I) && I->getType()->isPointerTy())
continue;
- // Freeze instruction is free, too.
- if (isa<FreezeInst>(I))
- continue;
-
+ // Freeze instruction is free, too.
+ if (isa<FreezeInst>(I))
+ continue;
+
// Bail out if this instruction gives back a token type, it is not possible
// to duplicate it if it is used outside this BB.
if (I->getType()->isTokenTy() && I->isUsedOutsideOfBlock(BB))
@@ -592,7 +592,7 @@ static unsigned getJumpThreadDuplicationCost(BasicBlock *BB,
return Size > Bonus ? Size - Bonus : 0;
}
-/// findLoopHeaders - We do not want jump threading to turn proper loop
+/// findLoopHeaders - We do not want jump threading to turn proper loop
/// structures into irreducible loops. Doing this breaks up the loop nesting
/// hierarchy and pessimizes later transformations. To prevent this from
/// happening, we first have to find the loop headers. Here we approximate this
@@ -606,7 +606,7 @@ static unsigned getJumpThreadDuplicationCost(BasicBlock *BB,
/// within the loop (forming a nested loop). This simple analysis is not rich
/// enough to track all of these properties and keep it up-to-date as the CFG
/// mutates, so we don't allow any of these transformations.
-void JumpThreadingPass::findLoopHeaders(Function &F) {
+void JumpThreadingPass::findLoopHeaders(Function &F) {
SmallVector<std::pair<const BasicBlock*,const BasicBlock*>, 32> Edges;
FindFunctionBackedges(F, Edges);
@@ -633,13 +633,13 @@ static Constant *getKnownConstant(Value *Val, ConstantPreference Preference) {
return dyn_cast<ConstantInt>(Val);
}
-/// computeValueKnownInPredecessors - Given a basic block BB and a value V, see
+/// computeValueKnownInPredecessors - Given a basic block BB and a value V, see
/// if we can infer that the value is a known ConstantInt/BlockAddress or undef
/// in any of our predecessors. If so, return the known list of value and pred
/// BB in the result vector.
///
/// This returns true if there were any known values.
-bool JumpThreadingPass::computeValueKnownInPredecessorsImpl(
+bool JumpThreadingPass::computeValueKnownInPredecessorsImpl(
Value *V, BasicBlock *BB, PredValueInfo &Result,
ConstantPreference Preference, DenseSet<Value *> &RecursionSet,
Instruction *CxtI) {
@@ -704,10 +704,10 @@ bool JumpThreadingPass::computeValueKnownInPredecessorsImpl(
return !Result.empty();
}
- // Handle Cast instructions.
+ // Handle Cast instructions.
if (CastInst *CI = dyn_cast<CastInst>(I)) {
Value *Source = CI->getOperand(0);
- computeValueKnownInPredecessorsImpl(Source, BB, Result, Preference,
+ computeValueKnownInPredecessorsImpl(Source, BB, Result, Preference,
RecursionSet, CxtI);
if (Result.empty())
return false;
@@ -719,18 +719,18 @@ bool JumpThreadingPass::computeValueKnownInPredecessorsImpl(
return true;
}
- if (FreezeInst *FI = dyn_cast<FreezeInst>(I)) {
- Value *Source = FI->getOperand(0);
- computeValueKnownInPredecessorsImpl(Source, BB, Result, Preference,
- RecursionSet, CxtI);
-
- erase_if(Result, [](auto &Pair) {
- return !isGuaranteedNotToBeUndefOrPoison(Pair.first);
- });
-
- return !Result.empty();
- }
-
+ if (FreezeInst *FI = dyn_cast<FreezeInst>(I)) {
+ Value *Source = FI->getOperand(0);
+ computeValueKnownInPredecessorsImpl(Source, BB, Result, Preference,
+ RecursionSet, CxtI);
+
+ erase_if(Result, [](auto &Pair) {
+ return !isGuaranteedNotToBeUndefOrPoison(Pair.first);
+ });
+
+ return !Result.empty();
+ }
+
// Handle some boolean conditions.
if (I->getType()->getPrimitiveSizeInBits() == 1) {
assert(Preference == WantInteger && "One-bit non-integer type?");
@@ -740,9 +740,9 @@ bool JumpThreadingPass::computeValueKnownInPredecessorsImpl(
I->getOpcode() == Instruction::And) {
PredValueInfoTy LHSVals, RHSVals;
- computeValueKnownInPredecessorsImpl(I->getOperand(0), BB, LHSVals,
+ computeValueKnownInPredecessorsImpl(I->getOperand(0), BB, LHSVals,
WantInteger, RecursionSet, CxtI);
- computeValueKnownInPredecessorsImpl(I->getOperand(1), BB, RHSVals,
+ computeValueKnownInPredecessorsImpl(I->getOperand(1), BB, RHSVals,
WantInteger, RecursionSet, CxtI);
if (LHSVals.empty() && RHSVals.empty())
@@ -778,7 +778,7 @@ bool JumpThreadingPass::computeValueKnownInPredecessorsImpl(
if (I->getOpcode() == Instruction::Xor &&
isa<ConstantInt>(I->getOperand(1)) &&
cast<ConstantInt>(I->getOperand(1))->isOne()) {
- computeValueKnownInPredecessorsImpl(I->getOperand(0), BB, Result,
+ computeValueKnownInPredecessorsImpl(I->getOperand(0), BB, Result,
WantInteger, RecursionSet, CxtI);
if (Result.empty())
return false;
@@ -796,7 +796,7 @@ bool JumpThreadingPass::computeValueKnownInPredecessorsImpl(
&& "A binary operator creating a block address?");
if (ConstantInt *CI = dyn_cast<ConstantInt>(BO->getOperand(1))) {
PredValueInfoTy LHSVals;
- computeValueKnownInPredecessorsImpl(BO->getOperand(0), BB, LHSVals,
+ computeValueKnownInPredecessorsImpl(BO->getOperand(0), BB, LHSVals,
WantInteger, RecursionSet, CxtI);
// Try to use constant folding to simplify the binary operator.
@@ -930,7 +930,7 @@ bool JumpThreadingPass::computeValueKnownInPredecessorsImpl(
// Try to find a constant value for the LHS of a comparison,
// and evaluate it statically if we can.
PredValueInfoTy LHSVals;
- computeValueKnownInPredecessorsImpl(I->getOperand(0), BB, LHSVals,
+ computeValueKnownInPredecessorsImpl(I->getOperand(0), BB, LHSVals,
WantInteger, RecursionSet, CxtI);
for (const auto &LHSVal : LHSVals) {
@@ -951,7 +951,7 @@ bool JumpThreadingPass::computeValueKnownInPredecessorsImpl(
Constant *FalseVal = getKnownConstant(SI->getFalseValue(), Preference);
PredValueInfoTy Conds;
if ((TrueVal || FalseVal) &&
- computeValueKnownInPredecessorsImpl(SI->getCondition(), BB, Conds,
+ computeValueKnownInPredecessorsImpl(SI->getCondition(), BB, Conds,
WantInteger, RecursionSet, CxtI)) {
for (auto &C : Conds) {
Constant *Cond = C.first;
@@ -979,8 +979,8 @@ bool JumpThreadingPass::computeValueKnownInPredecessorsImpl(
}
// If all else fails, see if LVI can figure out a constant value for us.
- assert(CxtI->getParent() == BB && "CxtI should be in BB");
- Constant *CI = LVI->getConstant(V, CxtI);
+ assert(CxtI->getParent() == BB && "CxtI should be in BB");
+ Constant *CI = LVI->getConstant(V, CxtI);
if (Constant *KC = getKnownConstant(CI, Preference)) {
for (BasicBlock *Pred : predecessors(BB))
Result.emplace_back(KC, Pred);
@@ -994,7 +994,7 @@ bool JumpThreadingPass::computeValueKnownInPredecessorsImpl(
///
/// Since we can pick an arbitrary destination, we pick the successor with the
/// fewest predecessors. This should reduce the in-degree of the others.
-static unsigned getBestDestForJumpOnUndef(BasicBlock *BB) {
+static unsigned getBestDestForJumpOnUndef(BasicBlock *BB) {
Instruction *BBTerm = BB->getTerminator();
unsigned MinSucc = 0;
BasicBlock *TestBB = BBTerm->getSuccessor(MinSucc);
@@ -1022,9 +1022,9 @@ static bool hasAddressTakenAndUsed(BasicBlock *BB) {
return !BA->use_empty();
}
-/// processBlock - If there are any predecessors whose control can be threaded
+/// processBlock - If there are any predecessors whose control can be threaded
/// through to a successor, transform them now.
-bool JumpThreadingPass::processBlock(BasicBlock *BB) {
+bool JumpThreadingPass::processBlock(BasicBlock *BB) {
// If the block is trivially dead, just return and let the caller nuke it.
// This simplifies other transformations.
if (DTU->isBBPendingDeletion(BB) ||
@@ -1035,14 +1035,14 @@ bool JumpThreadingPass::processBlock(BasicBlock *BB) {
// successor, merge the blocks. This encourages recursive jump threading
// because now the condition in this block can be threaded through
// predecessors of our predecessor block.
- if (maybeMergeBasicBlockIntoOnlyPred(BB))
+ if (maybeMergeBasicBlockIntoOnlyPred(BB))
return true;
- if (tryToUnfoldSelectInCurrBB(BB))
+ if (tryToUnfoldSelectInCurrBB(BB))
return true;
// Look if we can propagate guards to predecessors.
- if (HasGuards && processGuards(BB))
+ if (HasGuards && processGuards(BB))
return true;
// What kind of constant we're looking for.
@@ -1067,9 +1067,9 @@ bool JumpThreadingPass::processBlock(BasicBlock *BB) {
return false; // Must be an invoke or callbr.
}
- // Keep track if we constant folded the condition in this invocation.
- bool ConstantFolded = false;
-
+ // Keep track if we constant folded the condition in this invocation.
+ bool ConstantFolded = false;
+
// Run constant folding to see if we can reduce the condition to a simple
// constant.
if (Instruction *I = dyn_cast<Instruction>(Condition)) {
@@ -1080,16 +1080,16 @@ bool JumpThreadingPass::processBlock(BasicBlock *BB) {
if (isInstructionTriviallyDead(I, TLI))
I->eraseFromParent();
Condition = SimpleVal;
- ConstantFolded = true;
+ ConstantFolded = true;
}
}
- // If the terminator is branching on an undef or freeze undef, we can pick any
- // of the successors to branch to. Let getBestDestForJumpOnUndef decide.
- auto *FI = dyn_cast<FreezeInst>(Condition);
- if (isa<UndefValue>(Condition) ||
- (FI && isa<UndefValue>(FI->getOperand(0)) && FI->hasOneUse())) {
- unsigned BestSucc = getBestDestForJumpOnUndef(BB);
+ // If the terminator is branching on an undef or freeze undef, we can pick any
+ // of the successors to branch to. Let getBestDestForJumpOnUndef decide.
+ auto *FI = dyn_cast<FreezeInst>(Condition);
+ if (isa<UndefValue>(Condition) ||
+ (FI && isa<UndefValue>(FI->getOperand(0)) && FI->hasOneUse())) {
+ unsigned BestSucc = getBestDestForJumpOnUndef(BB);
std::vector<DominatorTree::UpdateType> Updates;
// Fold the branch/switch.
@@ -1107,8 +1107,8 @@ bool JumpThreadingPass::processBlock(BasicBlock *BB) {
BranchInst::Create(BBTerm->getSuccessor(BestSucc), BBTerm);
BBTerm->eraseFromParent();
DTU->applyUpdatesPermissive(Updates);
- if (FI)
- FI->eraseFromParent();
+ if (FI)
+ FI->eraseFromParent();
return true;
}
@@ -1121,8 +1121,8 @@ bool JumpThreadingPass::processBlock(BasicBlock *BB) {
<< '\n');
++NumFolds;
ConstantFoldTerminator(BB, true, nullptr, DTU);
- if (HasProfileData)
- BPI->eraseBlock(BB);
+ if (HasProfileData)
+ BPI->eraseBlock(BB);
return true;
}
@@ -1131,9 +1131,9 @@ bool JumpThreadingPass::processBlock(BasicBlock *BB) {
// All the rest of our checks depend on the condition being an instruction.
if (!CondInst) {
// FIXME: Unify this with code below.
- if (processThreadableEdges(Condition, BB, Preference, Terminator))
+ if (processThreadableEdges(Condition, BB, Preference, Terminator))
return true;
- return ConstantFolded;
+ return ConstantFolded;
}
if (CmpInst *CondCmp = dyn_cast<CmpInst>(CondInst)) {
@@ -1174,24 +1174,24 @@ bool JumpThreadingPass::processBlock(BasicBlock *BB) {
auto *CI = Ret == LazyValueInfo::True ?
ConstantInt::getTrue(CondCmp->getType()) :
ConstantInt::getFalse(CondCmp->getType());
- replaceFoldableUses(CondCmp, CI);
+ replaceFoldableUses(CondCmp, CI);
}
DTU->applyUpdatesPermissive(
{{DominatorTree::Delete, BB, ToRemoveSucc}});
- if (HasProfileData)
- BPI->eraseBlock(BB);
+ if (HasProfileData)
+ BPI->eraseBlock(BB);
return true;
}
// We did not manage to simplify this branch, try to see whether
// CondCmp depends on a known phi-select pattern.
- if (tryToUnfoldSelect(CondCmp, BB))
+ if (tryToUnfoldSelect(CondCmp, BB))
return true;
}
}
if (SwitchInst *SI = dyn_cast<SwitchInst>(BB->getTerminator()))
- if (tryToUnfoldSelect(SI, BB))
+ if (tryToUnfoldSelect(SI, BB))
return true;
// Check for some cases that are worth simplifying. Right now we want to look
@@ -1199,11 +1199,11 @@ bool JumpThreadingPass::processBlock(BasicBlock *BB) {
// we see one, check to see if it's partially redundant. If so, insert a PHI
// which can then be used to thread the values.
Value *SimplifyValue = CondInst;
-
- if (auto *FI = dyn_cast<FreezeInst>(SimplifyValue))
- // Look into freeze's operand
- SimplifyValue = FI->getOperand(0);
-
+
+ if (auto *FI = dyn_cast<FreezeInst>(SimplifyValue))
+ // Look into freeze's operand
+ SimplifyValue = FI->getOperand(0);
+
if (CmpInst *CondCmp = dyn_cast<CmpInst>(SimplifyValue))
if (isa<Constant>(CondCmp->getOperand(1)))
SimplifyValue = CondCmp->getOperand(0);
@@ -1211,7 +1211,7 @@ bool JumpThreadingPass::processBlock(BasicBlock *BB) {
// TODO: There are other places where load PRE would be profitable, such as
// more complex comparisons.
if (LoadInst *LoadI = dyn_cast<LoadInst>(SimplifyValue))
- if (simplifyPartiallyRedundantLoad(LoadI))
+ if (simplifyPartiallyRedundantLoad(LoadI))
return true;
// Before threading, try to propagate profile data backwards:
@@ -1222,32 +1222,32 @@ bool JumpThreadingPass::processBlock(BasicBlock *BB) {
// Handle a variety of cases where we are branching on something derived from
// a PHI node in the current block. If we can prove that any predecessors
// compute a predictable value based on a PHI node, thread those predecessors.
- if (processThreadableEdges(CondInst, BB, Preference, Terminator))
+ if (processThreadableEdges(CondInst, BB, Preference, Terminator))
return true;
- // If this is an otherwise-unfoldable branch on a phi node or freeze(phi) in
- // the current block, see if we can simplify.
- PHINode *PN = dyn_cast<PHINode>(
- isa<FreezeInst>(CondInst) ? cast<FreezeInst>(CondInst)->getOperand(0)
- : CondInst);
+ // If this is an otherwise-unfoldable branch on a phi node or freeze(phi) in
+ // the current block, see if we can simplify.
+ PHINode *PN = dyn_cast<PHINode>(
+ isa<FreezeInst>(CondInst) ? cast<FreezeInst>(CondInst)->getOperand(0)
+ : CondInst);
+
+ if (PN && PN->getParent() == BB && isa<BranchInst>(BB->getTerminator()))
+ return processBranchOnPHI(PN);
- if (PN && PN->getParent() == BB && isa<BranchInst>(BB->getTerminator()))
- return processBranchOnPHI(PN);
-
// If this is an otherwise-unfoldable branch on a XOR, see if we can simplify.
if (CondInst->getOpcode() == Instruction::Xor &&
CondInst->getParent() == BB && isa<BranchInst>(BB->getTerminator()))
- return processBranchOnXOR(cast<BinaryOperator>(CondInst));
+ return processBranchOnXOR(cast<BinaryOperator>(CondInst));
// Search for a stronger dominating condition that can be used to simplify a
// conditional branch leaving BB.
- if (processImpliedCondition(BB))
+ if (processImpliedCondition(BB))
return true;
return false;
}
-bool JumpThreadingPass::processImpliedCondition(BasicBlock *BB) {
+bool JumpThreadingPass::processImpliedCondition(BasicBlock *BB) {
auto *BI = dyn_cast<BranchInst>(BB->getTerminator());
if (!BI || !BI->isConditional())
return false;
@@ -1277,8 +1277,8 @@ bool JumpThreadingPass::processImpliedCondition(BasicBlock *BB) {
UncondBI->setDebugLoc(BI->getDebugLoc());
BI->eraseFromParent();
DTU->applyUpdatesPermissive({{DominatorTree::Delete, BB, RemoveSucc}});
- if (HasProfileData)
- BPI->eraseBlock(BB);
+ if (HasProfileData)
+ BPI->eraseBlock(BB);
return true;
}
CurrentBB = CurrentPred;
@@ -1296,11 +1296,11 @@ static bool isOpDefinedInBlock(Value *Op, BasicBlock *BB) {
return false;
}
-/// simplifyPartiallyRedundantLoad - If LoadI is an obviously partially
+/// simplifyPartiallyRedundantLoad - If LoadI is an obviously partially
/// redundant load instruction, eliminate it by replacing it with a PHI node.
/// This is an important optimization that encourages jump threading, and needs
/// to be run interlaced with other jump threading tasks.
-bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
+bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
// Don't hack volatile and ordered loads.
if (!LoadI->isUnordered()) return false;
@@ -1470,7 +1470,7 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
}
// Split them out to their own block.
- UnavailablePred = splitBlockPreds(LoadBB, PredsToSplit, "thread-pre-split");
+ UnavailablePred = splitBlockPreds(LoadBB, PredsToSplit, "thread-pre-split");
}
// If the value isn't available in all predecessors, then there will be
@@ -1534,11 +1534,11 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
return true;
}
-/// findMostPopularDest - The specified list contains multiple possible
+/// findMostPopularDest - The specified list contains multiple possible
/// threadable destinations. Pick the one that occurs the most frequently in
/// the list.
static BasicBlock *
-findMostPopularDest(BasicBlock *BB,
+findMostPopularDest(BasicBlock *BB,
const SmallVectorImpl<std::pair<BasicBlock *,
BasicBlock *>> &PredToDestList) {
assert(!PredToDestList.empty());
@@ -1573,7 +1573,7 @@ findMostPopularDest(BasicBlock *BB,
// Try to evaluate the value of V when the control flows from PredPredBB to
// BB->getSinglePredecessor() and then on to BB.
-Constant *JumpThreadingPass::evaluateOnPredecessorEdge(BasicBlock *BB,
+Constant *JumpThreadingPass::evaluateOnPredecessorEdge(BasicBlock *BB,
BasicBlock *PredPredBB,
Value *V) {
BasicBlock *PredBB = BB->getSinglePredecessor();
@@ -1600,9 +1600,9 @@ Constant *JumpThreadingPass::evaluateOnPredecessorEdge(BasicBlock *BB,
if (CmpInst *CondCmp = dyn_cast<CmpInst>(V)) {
if (CondCmp->getParent() == BB) {
Constant *Op0 =
- evaluateOnPredecessorEdge(BB, PredPredBB, CondCmp->getOperand(0));
+ evaluateOnPredecessorEdge(BB, PredPredBB, CondCmp->getOperand(0));
Constant *Op1 =
- evaluateOnPredecessorEdge(BB, PredPredBB, CondCmp->getOperand(1));
+ evaluateOnPredecessorEdge(BB, PredPredBB, CondCmp->getOperand(1));
if (Op0 && Op1) {
return ConstantExpr::getCompare(CondCmp->getPredicate(), Op0, Op1);
}
@@ -1613,7 +1613,7 @@ Constant *JumpThreadingPass::evaluateOnPredecessorEdge(BasicBlock *BB,
return nullptr;
}
-bool JumpThreadingPass::processThreadableEdges(Value *Cond, BasicBlock *BB,
+bool JumpThreadingPass::processThreadableEdges(Value *Cond, BasicBlock *BB,
ConstantPreference Preference,
Instruction *CxtI) {
// If threading this would thread across a loop header, don't even try to
@@ -1622,15 +1622,15 @@ bool JumpThreadingPass::processThreadableEdges(Value *Cond, BasicBlock *BB,
return false;
PredValueInfoTy PredValues;
- if (!computeValueKnownInPredecessors(Cond, BB, PredValues, Preference,
+ if (!computeValueKnownInPredecessors(Cond, BB, PredValues, Preference,
CxtI)) {
// We don't have known values in predecessors. See if we can thread through
// BB and its sole predecessor.
- return maybethreadThroughTwoBasicBlocks(BB, Cond);
+ return maybethreadThroughTwoBasicBlocks(BB, Cond);
}
assert(!PredValues.empty() &&
- "computeValueKnownInPredecessors returned true with no values");
+ "computeValueKnownInPredecessors returned true with no values");
LLVM_DEBUG(dbgs() << "IN BB: " << *BB;
for (const auto &PredValue : PredValues) {
@@ -1722,8 +1722,8 @@ bool JumpThreadingPass::processThreadableEdges(Value *Cond, BasicBlock *BB,
BranchInst::Create(OnlyDest, Term);
Term->eraseFromParent();
DTU->applyUpdatesPermissive(Updates);
- if (HasProfileData)
- BPI->eraseBlock(BB);
+ if (HasProfileData)
+ BPI->eraseBlock(BB);
// If the condition is now dead due to the removal of the old terminator,
// erase it.
@@ -1739,7 +1739,7 @@ bool JumpThreadingPass::processThreadableEdges(Value *Cond, BasicBlock *BB,
// guard/assume.
else if (OnlyVal && OnlyVal != MultipleVal &&
CondInst->getParent() == BB)
- replaceFoldableUses(CondInst, OnlyVal);
+ replaceFoldableUses(CondInst, OnlyVal);
}
return true;
}
@@ -1752,18 +1752,18 @@ bool JumpThreadingPass::processThreadableEdges(Value *Cond, BasicBlock *BB,
BasicBlock *MostPopularDest = OnlyDest;
if (MostPopularDest == MultipleDestSentinel) {
- // Remove any loop headers from the Dest list, threadEdge conservatively
+ // Remove any loop headers from the Dest list, threadEdge conservatively
// won't process them, but we might have other destination that are eligible
// and we still want to process.
erase_if(PredToDestList,
[&](const std::pair<BasicBlock *, BasicBlock *> &PredToDest) {
- return LoopHeaders.contains(PredToDest.second);
+ return LoopHeaders.contains(PredToDest.second);
});
if (PredToDestList.empty())
return false;
- MostPopularDest = findMostPopularDest(BB, PredToDestList);
+ MostPopularDest = findMostPopularDest(BB, PredToDestList);
}
// Now that we know what the most popular destination is, factor all
@@ -1785,16 +1785,16 @@ bool JumpThreadingPass::processThreadableEdges(Value *Cond, BasicBlock *BB,
// the destination that these predecessors should get to.
if (!MostPopularDest)
MostPopularDest = BB->getTerminator()->
- getSuccessor(getBestDestForJumpOnUndef(BB));
+ getSuccessor(getBestDestForJumpOnUndef(BB));
// Ok, try to thread it!
- return tryThreadEdge(BB, PredsToFactor, MostPopularDest);
+ return tryThreadEdge(BB, PredsToFactor, MostPopularDest);
}
-/// processBranchOnPHI - We have an otherwise unthreadable conditional branch on
-/// a PHI node (or freeze PHI) in the current block. See if there are any
-/// simplifications we can do based on inputs to the phi node.
-bool JumpThreadingPass::processBranchOnPHI(PHINode *PN) {
+/// processBranchOnPHI - We have an otherwise unthreadable conditional branch on
+/// a PHI node (or freeze PHI) in the current block. See if there are any
+/// simplifications we can do based on inputs to the phi node.
+bool JumpThreadingPass::processBranchOnPHI(PHINode *PN) {
BasicBlock *BB = PN->getParent();
// TODO: We could make use of this to do it once for blocks with common PHI
@@ -1806,16 +1806,16 @@ bool JumpThreadingPass::processBranchOnPHI(PHINode *PN) {
// *duplicate* the conditional branch into that block in order to further
// encourage jump threading and to eliminate cases where we have branch on a
// phi of an icmp (branch on icmp is much better).
- // This is still beneficial when a frozen phi is used as the branch condition
- // because it allows CodeGenPrepare to further canonicalize br(freeze(icmp))
- // to br(icmp(freeze ...)).
+ // This is still beneficial when a frozen phi is used as the branch condition
+ // because it allows CodeGenPrepare to further canonicalize br(freeze(icmp))
+ // to br(icmp(freeze ...)).
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
BasicBlock *PredBB = PN->getIncomingBlock(i);
if (BranchInst *PredBr = dyn_cast<BranchInst>(PredBB->getTerminator()))
if (PredBr->isUnconditional()) {
PredBBs[0] = PredBB;
// Try to duplicate BB into PredBB.
- if (duplicateCondBranchOnPHIIntoPred(BB, PredBBs))
+ if (duplicateCondBranchOnPHIIntoPred(BB, PredBBs))
return true;
}
}
@@ -1823,10 +1823,10 @@ bool JumpThreadingPass::processBranchOnPHI(PHINode *PN) {
return false;
}
-/// processBranchOnXOR - We have an otherwise unthreadable conditional branch on
+/// processBranchOnXOR - We have an otherwise unthreadable conditional branch on
/// a xor instruction in the current block. See if there are any
/// simplifications we can do based on inputs to the xor.
-bool JumpThreadingPass::processBranchOnXOR(BinaryOperator *BO) {
+bool JumpThreadingPass::processBranchOnXOR(BinaryOperator *BO) {
BasicBlock *BB = BO->getParent();
// If either the LHS or RHS of the xor is a constant, don't do this
@@ -1864,17 +1864,17 @@ bool JumpThreadingPass::processBranchOnXOR(BinaryOperator *BO) {
PredValueInfoTy XorOpValues;
bool isLHS = true;
- if (!computeValueKnownInPredecessors(BO->getOperand(0), BB, XorOpValues,
+ if (!computeValueKnownInPredecessors(BO->getOperand(0), BB, XorOpValues,
WantInteger, BO)) {
assert(XorOpValues.empty());
- if (!computeValueKnownInPredecessors(BO->getOperand(1), BB, XorOpValues,
+ if (!computeValueKnownInPredecessors(BO->getOperand(1), BB, XorOpValues,
WantInteger, BO))
return false;
isLHS = false;
}
assert(!XorOpValues.empty() &&
- "computeValueKnownInPredecessors returned true with no values");
+ "computeValueKnownInPredecessors returned true with no values");
// Scan the information to see which is most popular: true or false. The
// predecessors can be of the set true, false, or undef.
@@ -1935,13 +1935,13 @@ bool JumpThreadingPass::processBranchOnXOR(BinaryOperator *BO) {
return false;
// Try to duplicate BB into PredBB.
- return duplicateCondBranchOnPHIIntoPred(BB, BlocksToFoldInto);
+ return duplicateCondBranchOnPHIIntoPred(BB, BlocksToFoldInto);
}
-/// addPHINodeEntriesForMappedBlock - We're adding 'NewPred' as a new
+/// addPHINodeEntriesForMappedBlock - We're adding 'NewPred' as a new
/// predecessor to the PHIBB block. If it has PHI nodes, add entries for
/// NewPred using the entries from OldPred (suitably mapped).
-static void addPHINodeEntriesForMappedBlock(BasicBlock *PHIBB,
+static void addPHINodeEntriesForMappedBlock(BasicBlock *PHIBB,
BasicBlock *OldPred,
BasicBlock *NewPred,
DenseMap<Instruction*, Value*> &ValueMap) {
@@ -1962,7 +1962,7 @@ static void addPHINodeEntriesForMappedBlock(BasicBlock *PHIBB,
}
/// Merge basic block BB into its sole predecessor if possible.
-bool JumpThreadingPass::maybeMergeBasicBlockIntoOnlyPred(BasicBlock *BB) {
+bool JumpThreadingPass::maybeMergeBasicBlockIntoOnlyPred(BasicBlock *BB) {
BasicBlock *SinglePred = BB->getSinglePredecessor();
if (!SinglePred)
return false;
@@ -2013,7 +2013,7 @@ bool JumpThreadingPass::maybeMergeBasicBlockIntoOnlyPred(BasicBlock *BB) {
/// Update the SSA form. NewBB contains instructions that are copied from BB.
/// ValueMapping maps old values in BB to new ones in NewBB.
-void JumpThreadingPass::updateSSA(
+void JumpThreadingPass::updateSSA(
BasicBlock *BB, BasicBlock *NewBB,
DenseMap<Instruction *, Value *> &ValueMapping) {
// If there were values defined in BB that are used outside the block, then we
@@ -2059,7 +2059,7 @@ void JumpThreadingPass::updateSSA(
/// arguments that come from PredBB. Return the map from the variables in the
/// source basic block to the variables in the newly created basic block.
DenseMap<Instruction *, Value *>
-JumpThreadingPass::cloneInstructions(BasicBlock::iterator BI,
+JumpThreadingPass::cloneInstructions(BasicBlock::iterator BI,
BasicBlock::iterator BE, BasicBlock *NewBB,
BasicBlock *PredBB) {
// We are going to have to map operands from the source basic block to the new
@@ -2076,15 +2076,15 @@ JumpThreadingPass::cloneInstructions(BasicBlock::iterator BI,
ValueMapping[PN] = NewPN;
}
- // Clone noalias scope declarations in the threaded block. When threading a
- // loop exit, we would otherwise end up with two idential scope declarations
- // visible at the same time.
- SmallVector<MDNode *> NoAliasScopes;
- DenseMap<MDNode *, MDNode *> ClonedScopes;
- LLVMContext &Context = PredBB->getContext();
- identifyNoAliasScopesToClone(BI, BE, NoAliasScopes);
- cloneNoAliasScopes(NoAliasScopes, ClonedScopes, "thread", Context);
-
+ // Clone noalias scope declarations in the threaded block. When threading a
+ // loop exit, we would otherwise end up with two idential scope declarations
+ // visible at the same time.
+ SmallVector<MDNode *> NoAliasScopes;
+ DenseMap<MDNode *, MDNode *> ClonedScopes;
+ LLVMContext &Context = PredBB->getContext();
+ identifyNoAliasScopesToClone(BI, BE, NoAliasScopes);
+ cloneNoAliasScopes(NoAliasScopes, ClonedScopes, "thread", Context);
+
// Clone the non-phi instructions of the source basic block into NewBB,
// keeping track of the mapping and using it to remap operands in the cloned
// instructions.
@@ -2093,7 +2093,7 @@ JumpThreadingPass::cloneInstructions(BasicBlock::iterator BI,
New->setName(BI->getName());
NewBB->getInstList().push_back(New);
ValueMapping[&*BI] = New;
- adaptNoAliasScopes(New, ClonedScopes, Context);
+ adaptNoAliasScopes(New, ClonedScopes, Context);
// Remap operands to patch up intra-block references.
for (unsigned i = 0, e = New->getNumOperands(); i != e; ++i)
@@ -2108,7 +2108,7 @@ JumpThreadingPass::cloneInstructions(BasicBlock::iterator BI,
}
/// Attempt to thread through two successive basic blocks.
-bool JumpThreadingPass::maybethreadThroughTwoBasicBlocks(BasicBlock *BB,
+bool JumpThreadingPass::maybethreadThroughTwoBasicBlocks(BasicBlock *BB,
Value *Cond) {
// Consider:
//
@@ -2177,7 +2177,7 @@ bool JumpThreadingPass::maybethreadThroughTwoBasicBlocks(BasicBlock *BB,
BasicBlock *OnePred = nullptr;
for (BasicBlock *P : predecessors(PredBB)) {
if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(
- evaluateOnPredecessorEdge(BB, P, Cond))) {
+ evaluateOnPredecessorEdge(BB, P, Cond))) {
if (CI->isZero()) {
ZeroCount++;
ZeroPred = P;
@@ -2208,7 +2208,7 @@ bool JumpThreadingPass::maybethreadThroughTwoBasicBlocks(BasicBlock *BB,
}
// If threading this would thread across a loop header, don't thread the edge.
- // See the comments above findLoopHeaders for justifications and caveats.
+ // See the comments above findLoopHeaders for justifications and caveats.
if (LoopHeaders.count(BB) || LoopHeaders.count(SuccBB)) {
LLVM_DEBUG({
bool BBIsHeader = LoopHeaders.count(BB);
@@ -2241,11 +2241,11 @@ bool JumpThreadingPass::maybethreadThroughTwoBasicBlocks(BasicBlock *BB,
}
// Now we are ready to duplicate PredBB.
- threadThroughTwoBasicBlocks(PredPredBB, PredBB, BB, SuccBB);
+ threadThroughTwoBasicBlocks(PredPredBB, PredBB, BB, SuccBB);
return true;
}
-void JumpThreadingPass::threadThroughTwoBasicBlocks(BasicBlock *PredPredBB,
+void JumpThreadingPass::threadThroughTwoBasicBlocks(BasicBlock *PredPredBB,
BasicBlock *PredBB,
BasicBlock *BB,
BasicBlock *SuccBB) {
@@ -2271,12 +2271,12 @@ void JumpThreadingPass::threadThroughTwoBasicBlocks(BasicBlock *PredPredBB,
// copy of the block 'NewBB'. If there are PHI nodes in PredBB, evaluate them
// to account for entry from PredPredBB.
DenseMap<Instruction *, Value *> ValueMapping =
- cloneInstructions(PredBB->begin(), PredBB->end(), NewBB, PredPredBB);
+ cloneInstructions(PredBB->begin(), PredBB->end(), NewBB, PredPredBB);
+
+ // Copy the edge probabilities from PredBB to NewBB.
+ if (HasProfileData)
+ BPI->copyEdgeProbabilities(PredBB, NewBB);
- // Copy the edge probabilities from PredBB to NewBB.
- if (HasProfileData)
- BPI->copyEdgeProbabilities(PredBB, NewBB);
-
// Update the terminator of PredPredBB to jump to NewBB instead of PredBB.
// This eliminates predecessors from PredPredBB, which requires us to simplify
// any PHI nodes in PredBB.
@@ -2287,9 +2287,9 @@ void JumpThreadingPass::threadThroughTwoBasicBlocks(BasicBlock *PredPredBB,
PredPredTerm->setSuccessor(i, NewBB);
}
- addPHINodeEntriesForMappedBlock(PredBBBranch->getSuccessor(0), PredBB, NewBB,
+ addPHINodeEntriesForMappedBlock(PredBBBranch->getSuccessor(0), PredBB, NewBB,
ValueMapping);
- addPHINodeEntriesForMappedBlock(PredBBBranch->getSuccessor(1), PredBB, NewBB,
+ addPHINodeEntriesForMappedBlock(PredBBBranch->getSuccessor(1), PredBB, NewBB,
ValueMapping);
DTU->applyUpdatesPermissive(
@@ -2298,7 +2298,7 @@ void JumpThreadingPass::threadThroughTwoBasicBlocks(BasicBlock *PredPredBB,
{DominatorTree::Insert, PredPredBB, NewBB},
{DominatorTree::Delete, PredPredBB, PredBB}});
- updateSSA(PredBB, NewBB, ValueMapping);
+ updateSSA(PredBB, NewBB, ValueMapping);
// Clean up things like PHI nodes with single operands, dead instructions,
// etc.
@@ -2307,11 +2307,11 @@ void JumpThreadingPass::threadThroughTwoBasicBlocks(BasicBlock *PredPredBB,
SmallVector<BasicBlock *, 1> PredsToFactor;
PredsToFactor.push_back(NewBB);
- threadEdge(BB, PredsToFactor, SuccBB);
+ threadEdge(BB, PredsToFactor, SuccBB);
}
-/// tryThreadEdge - Thread an edge if it's safe and profitable to do so.
-bool JumpThreadingPass::tryThreadEdge(
+/// tryThreadEdge - Thread an edge if it's safe and profitable to do so.
+bool JumpThreadingPass::tryThreadEdge(
BasicBlock *BB, const SmallVectorImpl<BasicBlock *> &PredBBs,
BasicBlock *SuccBB) {
// If threading to the same block as we come from, we would infinite loop.
@@ -2322,7 +2322,7 @@ bool JumpThreadingPass::tryThreadEdge(
}
// If threading this would thread across a loop header, don't thread the edge.
- // See the comments above findLoopHeaders for justifications and caveats.
+ // See the comments above findLoopHeaders for justifications and caveats.
if (LoopHeaders.count(BB) || LoopHeaders.count(SuccBB)) {
LLVM_DEBUG({
bool BBIsHeader = LoopHeaders.count(BB);
@@ -2343,14 +2343,14 @@ bool JumpThreadingPass::tryThreadEdge(
return false;
}
- threadEdge(BB, PredBBs, SuccBB);
+ threadEdge(BB, PredBBs, SuccBB);
return true;
}
-/// threadEdge - We have decided that it is safe and profitable to factor the
+/// threadEdge - We have decided that it is safe and profitable to factor the
/// blocks in PredBBs to one predecessor, then thread an edge from it to SuccBB
/// across BB. Transform the IR to reflect this change.
-void JumpThreadingPass::threadEdge(BasicBlock *BB,
+void JumpThreadingPass::threadEdge(BasicBlock *BB,
const SmallVectorImpl<BasicBlock *> &PredBBs,
BasicBlock *SuccBB) {
assert(SuccBB != BB && "Don't create an infinite loop");
@@ -2365,7 +2365,7 @@ void JumpThreadingPass::threadEdge(BasicBlock *BB,
else {
LLVM_DEBUG(dbgs() << " Factoring out " << PredBBs.size()
<< " common predecessors.\n");
- PredBB = splitBlockPreds(BB, PredBBs, ".thr_comm");
+ PredBB = splitBlockPreds(BB, PredBBs, ".thr_comm");
}
// And finally, do it!
@@ -2389,7 +2389,7 @@ void JumpThreadingPass::threadEdge(BasicBlock *BB,
// Copy all the instructions from BB to NewBB except the terminator.
DenseMap<Instruction *, Value *> ValueMapping =
- cloneInstructions(BB->begin(), std::prev(BB->end()), NewBB, PredBB);
+ cloneInstructions(BB->begin(), std::prev(BB->end()), NewBB, PredBB);
// We didn't copy the terminator from BB over to NewBB, because there is now
// an unconditional jump to SuccBB. Insert the unconditional jump.
@@ -2398,7 +2398,7 @@ void JumpThreadingPass::threadEdge(BasicBlock *BB,
// Check to see if SuccBB has PHI nodes. If so, we need to add entries to the
// PHI nodes for NewBB now.
- addPHINodeEntriesForMappedBlock(SuccBB, BB, NewBB, ValueMapping);
+ addPHINodeEntriesForMappedBlock(SuccBB, BB, NewBB, ValueMapping);
// Update the terminator of PredBB to jump to NewBB instead of BB. This
// eliminates predecessors from BB, which requires us to simplify any PHI
@@ -2415,7 +2415,7 @@ void JumpThreadingPass::threadEdge(BasicBlock *BB,
{DominatorTree::Insert, PredBB, NewBB},
{DominatorTree::Delete, PredBB, BB}});
- updateSSA(BB, NewBB, ValueMapping);
+ updateSSA(BB, NewBB, ValueMapping);
// At this point, the IR is fully up to date and consistent. Do a quick scan
// over the new instructions and zap any that are constants or dead. This
@@ -2423,7 +2423,7 @@ void JumpThreadingPass::threadEdge(BasicBlock *BB,
SimplifyInstructionsInBlock(NewBB, TLI);
// Update the edge weight from BB to SuccBB, which should be less than before.
- updateBlockFreqAndEdgeWeight(PredBB, BB, NewBB, SuccBB);
+ updateBlockFreqAndEdgeWeight(PredBB, BB, NewBB, SuccBB);
// Threaded an edge!
++NumThreads;
@@ -2432,7 +2432,7 @@ void JumpThreadingPass::threadEdge(BasicBlock *BB,
/// Create a new basic block that will be the predecessor of BB and successor of
/// all blocks in Preds. When profile data is available, update the frequency of
/// this new block.
-BasicBlock *JumpThreadingPass::splitBlockPreds(BasicBlock *BB,
+BasicBlock *JumpThreadingPass::splitBlockPreds(BasicBlock *BB,
ArrayRef<BasicBlock *> Preds,
const char *Suffix) {
SmallVector<BasicBlock *, 2> NewBBs;
@@ -2493,7 +2493,7 @@ bool JumpThreadingPass::doesBlockHaveProfileData(BasicBlock *BB) {
/// Update the block frequency of BB and branch weight and the metadata on the
/// edge BB->SuccBB. This is done by scaling the weight of BB->SuccBB by 1 -
/// Freq(PredBB->BB) / Freq(BB->SuccBB).
-void JumpThreadingPass::updateBlockFreqAndEdgeWeight(BasicBlock *PredBB,
+void JumpThreadingPass::updateBlockFreqAndEdgeWeight(BasicBlock *PredBB,
BasicBlock *BB,
BasicBlock *NewBB,
BasicBlock *SuccBB) {
@@ -2585,18 +2585,18 @@ void JumpThreadingPass::updateBlockFreqAndEdgeWeight(BasicBlock *PredBB,
}
}
-/// duplicateCondBranchOnPHIIntoPred - PredBB contains an unconditional branch
+/// duplicateCondBranchOnPHIIntoPred - PredBB contains an unconditional branch
/// to BB which contains an i1 PHI node and a conditional branch on that PHI.
/// If we can duplicate the contents of BB up into PredBB do so now, this
/// improves the odds that the branch will be on an analyzable instruction like
/// a compare.
-bool JumpThreadingPass::duplicateCondBranchOnPHIIntoPred(
+bool JumpThreadingPass::duplicateCondBranchOnPHIIntoPred(
BasicBlock *BB, const SmallVectorImpl<BasicBlock *> &PredBBs) {
assert(!PredBBs.empty() && "Can't handle an empty set");
// If BB is a loop header, then duplicating this block outside the loop would
// cause us to transform this into an irreducible loop, don't do this.
- // See the comments above findLoopHeaders for justifications and caveats.
+ // See the comments above findLoopHeaders for justifications and caveats.
if (LoopHeaders.count(BB)) {
LLVM_DEBUG(dbgs() << " Not duplicating loop header '" << BB->getName()
<< "' into predecessor block '" << PredBBs[0]->getName()
@@ -2620,7 +2620,7 @@ bool JumpThreadingPass::duplicateCondBranchOnPHIIntoPred(
else {
LLVM_DEBUG(dbgs() << " Factoring out " << PredBBs.size()
<< " common predecessors.\n");
- PredBB = splitBlockPreds(BB, PredBBs, ".thr_comm");
+ PredBB = splitBlockPreds(BB, PredBBs, ".thr_comm");
}
Updates.push_back({DominatorTree::Delete, PredBB, BB});
@@ -2692,12 +2692,12 @@ bool JumpThreadingPass::duplicateCondBranchOnPHIIntoPred(
// Check to see if the targets of the branch had PHI nodes. If so, we need to
// add entries to the PHI nodes for branch from PredBB now.
BranchInst *BBBranch = cast<BranchInst>(BB->getTerminator());
- addPHINodeEntriesForMappedBlock(BBBranch->getSuccessor(0), BB, PredBB,
+ addPHINodeEntriesForMappedBlock(BBBranch->getSuccessor(0), BB, PredBB,
ValueMapping);
- addPHINodeEntriesForMappedBlock(BBBranch->getSuccessor(1), BB, PredBB,
+ addPHINodeEntriesForMappedBlock(BBBranch->getSuccessor(1), BB, PredBB,
ValueMapping);
- updateSSA(BB, PredBB, ValueMapping);
+ updateSSA(BB, PredBB, ValueMapping);
// PredBB no longer jumps to BB, remove entries in the PHI node for the edge
// that we nuked.
@@ -2705,8 +2705,8 @@ bool JumpThreadingPass::duplicateCondBranchOnPHIIntoPred(
// Remove the unconditional branch at the end of the PredBB block.
OldPredBranch->eraseFromParent();
- if (HasProfileData)
- BPI->copyEdgeProbabilities(BB, PredBB);
+ if (HasProfileData)
+ BPI->copyEdgeProbabilities(BB, PredBB);
DTU->applyUpdatesPermissive(Updates);
++NumDupes;
@@ -2718,7 +2718,7 @@ bool JumpThreadingPass::duplicateCondBranchOnPHIIntoPred(
// a PHI node in BB. SI has no other use.
// A new basic block, NewBB, is created and SI is converted to compare and
// conditional branch. SI is erased from parent.
-void JumpThreadingPass::unfoldSelectInstr(BasicBlock *Pred, BasicBlock *BB,
+void JumpThreadingPass::unfoldSelectInstr(BasicBlock *Pred, BasicBlock *BB,
SelectInst *SI, PHINode *SIUse,
unsigned Idx) {
// Expand the select.
@@ -2753,7 +2753,7 @@ void JumpThreadingPass::unfoldSelectInstr(BasicBlock *Pred, BasicBlock *BB,
Phi->addIncoming(Phi->getIncomingValueForBlock(Pred), NewBB);
}
-bool JumpThreadingPass::tryToUnfoldSelect(SwitchInst *SI, BasicBlock *BB) {
+bool JumpThreadingPass::tryToUnfoldSelect(SwitchInst *SI, BasicBlock *BB) {
PHINode *CondPHI = dyn_cast<PHINode>(SI->getCondition());
if (!CondPHI || CondPHI->getParent() != BB)
@@ -2765,7 +2765,7 @@ bool JumpThreadingPass::tryToUnfoldSelect(SwitchInst *SI, BasicBlock *BB) {
// The second and third condition can be potentially relaxed. Currently
// the conditions help to simplify the code and allow us to reuse existing
- // code, developed for tryToUnfoldSelect(CmpInst *, BasicBlock *)
+ // code, developed for tryToUnfoldSelect(CmpInst *, BasicBlock *)
if (!PredSI || PredSI->getParent() != Pred || !PredSI->hasOneUse())
continue;
@@ -2773,13 +2773,13 @@ bool JumpThreadingPass::tryToUnfoldSelect(SwitchInst *SI, BasicBlock *BB) {
if (!PredTerm || !PredTerm->isUnconditional())
continue;
- unfoldSelectInstr(Pred, BB, PredSI, CondPHI, I);
+ unfoldSelectInstr(Pred, BB, PredSI, CondPHI, I);
return true;
}
return false;
}
-/// tryToUnfoldSelect - Look for blocks of the form
+/// tryToUnfoldSelect - Look for blocks of the form
/// bb1:
/// %a = select
/// br bb2
@@ -2791,7 +2791,7 @@ bool JumpThreadingPass::tryToUnfoldSelect(SwitchInst *SI, BasicBlock *BB) {
///
/// And expand the select into a branch structure if one of its arms allows %c
/// to be folded. This later enables threading from bb1 over bb2.
-bool JumpThreadingPass::tryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB) {
+bool JumpThreadingPass::tryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB) {
BranchInst *CondBr = dyn_cast<BranchInst>(BB->getTerminator());
PHINode *CondLHS = dyn_cast<PHINode>(CondCmp->getOperand(0));
Constant *CondRHS = cast<Constant>(CondCmp->getOperand(1));
@@ -2825,14 +2825,14 @@ bool JumpThreadingPass::tryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB) {
if ((LHSFolds != LazyValueInfo::Unknown ||
RHSFolds != LazyValueInfo::Unknown) &&
LHSFolds != RHSFolds) {
- unfoldSelectInstr(Pred, BB, SI, CondLHS, I);
+ unfoldSelectInstr(Pred, BB, SI, CondLHS, I);
return true;
}
}
return false;
}
-/// tryToUnfoldSelectInCurrBB - Look for PHI/Select or PHI/CMP/Select in the
+/// tryToUnfoldSelectInCurrBB - Look for PHI/Select or PHI/CMP/Select in the
/// same BB in the form
/// bb:
/// %p = phi [false, %bb1], [true, %bb2], [false, %bb3], [true, %bb4], ...
@@ -2852,14 +2852,14 @@ bool JumpThreadingPass::tryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB) {
/// select if the associated PHI has at least one constant. If the unfolded
/// select is not jump-threaded, it will be folded again in the later
/// optimizations.
-bool JumpThreadingPass::tryToUnfoldSelectInCurrBB(BasicBlock *BB) {
- // This transform would reduce the quality of msan diagnostics.
+bool JumpThreadingPass::tryToUnfoldSelectInCurrBB(BasicBlock *BB) {
+ // This transform would reduce the quality of msan diagnostics.
// Disable this transform under MemorySanitizer.
if (BB->getParent()->hasFnAttribute(Attribute::SanitizeMemory))
return false;
// If threading this would thread across a loop header, don't thread the edge.
- // See the comments above findLoopHeaders for justifications and caveats.
+ // See the comments above findLoopHeaders for justifications and caveats.
if (LoopHeaders.count(BB))
return false;
@@ -2902,12 +2902,12 @@ bool JumpThreadingPass::tryToUnfoldSelectInCurrBB(BasicBlock *BB) {
if (!SI)
continue;
// Expand the select.
- Value *Cond = SI->getCondition();
- if (InsertFreezeWhenUnfoldingSelect &&
- !isGuaranteedNotToBeUndefOrPoison(Cond, nullptr, SI,
- &DTU->getDomTree()))
- Cond = new FreezeInst(Cond, "cond.fr", SI);
- Instruction *Term = SplitBlockAndInsertIfThen(Cond, SI, false);
+ Value *Cond = SI->getCondition();
+ if (InsertFreezeWhenUnfoldingSelect &&
+ !isGuaranteedNotToBeUndefOrPoison(Cond, nullptr, SI,
+ &DTU->getDomTree()))
+ Cond = new FreezeInst(Cond, "cond.fr", SI);
+ Instruction *Term = SplitBlockAndInsertIfThen(Cond, SI, false);
BasicBlock *SplitBB = SI->getParent();
BasicBlock *NewBB = Term->getParent();
PHINode *NewPN = PHINode::Create(SI->getType(), 2, "", SI);
@@ -2951,7 +2951,7 @@ bool JumpThreadingPass::tryToUnfoldSelectInCurrBB(BasicBlock *BB) {
/// And cond either implies condGuard or !condGuard. In this case all the
/// instructions before the guard can be duplicated in both branches, and the
/// guard is then threaded to one of them.
-bool JumpThreadingPass::processGuards(BasicBlock *BB) {
+bool JumpThreadingPass::processGuards(BasicBlock *BB) {
using namespace PatternMatch;
// We only want to deal with two predecessors.
@@ -2976,7 +2976,7 @@ bool JumpThreadingPass::processGuards(BasicBlock *BB) {
if (auto *BI = dyn_cast<BranchInst>(Parent->getTerminator()))
for (auto &I : *BB)
- if (isGuard(&I) && threadGuard(BB, cast<IntrinsicInst>(&I), BI))
+ if (isGuard(&I) && threadGuard(BB, cast<IntrinsicInst>(&I), BI))
return true;
return false;
@@ -2985,7 +2985,7 @@ bool JumpThreadingPass::processGuards(BasicBlock *BB) {
/// Try to propagate the guard from BB which is the lower block of a diamond
/// to one of its branches, in case if diamond's condition implies guard's
/// condition.
-bool JumpThreadingPass::threadGuard(BasicBlock *BB, IntrinsicInst *Guard,
+bool JumpThreadingPass::threadGuard(BasicBlock *BB, IntrinsicInst *Guard,
BranchInst *BI) {
assert(BI->getNumSuccessors() == 2 && "Wrong number of successors?");
assert(BI->isConditional() && "Unconditional branch has 2 successors?");
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LICM.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LICM.cpp
index 6db37000d4..d2b4ba296f 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LICM.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LICM.cpp
@@ -12,13 +12,13 @@
// safe. This pass also promotes must-aliased memory locations in the loop to
// live in registers, thus hoisting and sinking "invariant" loads and stores.
//
-// Hoisting operations out of loops is a canonicalization transform. It
-// enables and simplifies subsequent optimizations in the middle-end.
-// Rematerialization of hoisted instructions to reduce register pressure is the
-// responsibility of the back-end, which has more accurate information about
-// register pressure and also handles other optimizations than LICM that
-// increase live-ranges.
-//
+// Hoisting operations out of loops is a canonicalization transform. It
+// enables and simplifies subsequent optimizations in the middle-end.
+// Rematerialization of hoisted instructions to reduce register pressure is the
+// responsibility of the back-end, which has more accurate information about
+// register pressure and also handles other optimizations than LICM that
+// increase live-ranges.
+//
// This pass uses alias analysis for two purposes:
//
// 1. Moving loop invariant loads and calls out of loops. If we can determine
@@ -42,12 +42,12 @@
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
-#include "llvm/Analysis/BlockFrequencyInfo.h"
+#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/GuardUtils.h"
-#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
+#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopIterator.h"
@@ -107,11 +107,11 @@ static cl::opt<bool> ControlFlowHoisting(
"licm-control-flow-hoisting", cl::Hidden, cl::init(false),
cl::desc("Enable control flow (and PHI) hoisting in LICM"));
-static cl::opt<unsigned> HoistSinkColdnessThreshold(
- "licm-coldness-threshold", cl::Hidden, cl::init(4),
- cl::desc("Relative coldness Threshold of hoisting/sinking destination "
- "block for LICM to be considered beneficial"));
-
+static cl::opt<unsigned> HoistSinkColdnessThreshold(
+ "licm-coldness-threshold", cl::Hidden, cl::init(4),
+ cl::desc("Relative coldness Threshold of hoisting/sinking destination "
+ "block for LICM to be considered beneficial"));
+
static cl::opt<uint32_t> MaxNumUsesTraversed(
"licm-max-num-uses-traversed", cl::Hidden, cl::init(8),
cl::desc("Max num uses visited for identifying load "
@@ -157,9 +157,9 @@ static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop,
MemorySSAUpdater *MSSAU, ScalarEvolution *SE,
OptimizationRemarkEmitter *ORE);
static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT,
- BlockFrequencyInfo *BFI, const Loop *CurLoop,
- ICFLoopSafetyInfo *SafetyInfo, MemorySSAUpdater *MSSAU,
- OptimizationRemarkEmitter *ORE);
+ BlockFrequencyInfo *BFI, const Loop *CurLoop,
+ ICFLoopSafetyInfo *SafetyInfo, MemorySSAUpdater *MSSAU,
+ OptimizationRemarkEmitter *ORE);
static bool isSafeToExecuteUnconditionally(Instruction &Inst,
const DominatorTree *DT,
const Loop *CurLoop,
@@ -170,10 +170,10 @@ static bool pointerInvalidatedByLoop(MemoryLocation MemLoc,
AliasSetTracker *CurAST, Loop *CurLoop,
AAResults *AA);
static bool pointerInvalidatedByLoopWithMSSA(MemorySSA *MSSA, MemoryUse *MU,
- Loop *CurLoop, Instruction &I,
+ Loop *CurLoop, Instruction &I,
SinkAndHoistLICMFlags &Flags);
-static bool pointerInvalidatedByBlockWithMSSA(BasicBlock &BB, MemorySSA &MSSA,
- MemoryUse &MU);
+static bool pointerInvalidatedByBlockWithMSSA(BasicBlock &BB, MemorySSA &MSSA,
+ MemoryUse &MU);
static Instruction *cloneInstructionInExitBlock(
Instruction &I, BasicBlock &ExitBlock, PHINode &PN, const LoopInfo *LI,
const LoopSafetyInfo *SafetyInfo, MemorySSAUpdater *MSSAU);
@@ -188,8 +188,8 @@ static void moveInstructionBefore(Instruction &I, Instruction &Dest,
namespace {
struct LoopInvariantCodeMotion {
bool runOnLoop(Loop *L, AAResults *AA, LoopInfo *LI, DominatorTree *DT,
- BlockFrequencyInfo *BFI, TargetLibraryInfo *TLI,
- TargetTransformInfo *TTI, ScalarEvolution *SE, MemorySSA *MSSA,
+ BlockFrequencyInfo *BFI, TargetLibraryInfo *TLI,
+ TargetTransformInfo *TTI, ScalarEvolution *SE, MemorySSA *MSSA,
OptimizationRemarkEmitter *ORE);
LoopInvariantCodeMotion(unsigned LicmMssaOptCap,
@@ -221,30 +221,30 @@ struct LegacyLICMPass : public LoopPass {
if (skipLoop(L))
return false;
- LLVM_DEBUG(dbgs() << "Perform LICM on Loop with header at block "
- << L->getHeader()->getNameOrAsOperand() << "\n");
-
+ LLVM_DEBUG(dbgs() << "Perform LICM on Loop with header at block "
+ << L->getHeader()->getNameOrAsOperand() << "\n");
+
auto *SE = getAnalysisIfAvailable<ScalarEvolutionWrapperPass>();
MemorySSA *MSSA = EnableMSSALoopDependency
? (&getAnalysis<MemorySSAWrapperPass>().getMSSA())
: nullptr;
- bool hasProfileData = L->getHeader()->getParent()->hasProfileData();
- BlockFrequencyInfo *BFI =
- hasProfileData ? &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI()
- : nullptr;
+ bool hasProfileData = L->getHeader()->getParent()->hasProfileData();
+ BlockFrequencyInfo *BFI =
+ hasProfileData ? &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI()
+ : nullptr;
// For the old PM, we can't use OptimizationRemarkEmitter as an analysis
- // pass. Function analyses need to be preserved across loop transformations
+ // pass. Function analyses need to be preserved across loop transformations
// but ORE cannot be preserved (see comment before the pass definition).
OptimizationRemarkEmitter ORE(L->getHeader()->getParent());
- return LICM.runOnLoop(
- L, &getAnalysis<AAResultsWrapperPass>().getAAResults(),
- &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(),
- &getAnalysis<DominatorTreeWrapperPass>().getDomTree(), BFI,
- &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
- *L->getHeader()->getParent()),
- &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
- *L->getHeader()->getParent()),
- SE ? &SE->getSE() : nullptr, MSSA, &ORE);
+ return LICM.runOnLoop(
+ L, &getAnalysis<AAResultsWrapperPass>().getAAResults(),
+ &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(),
+ &getAnalysis<DominatorTreeWrapperPass>().getDomTree(), BFI,
+ &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
+ *L->getHeader()->getParent()),
+ &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
+ *L->getHeader()->getParent()),
+ SE ? &SE->getSE() : nullptr, MSSA, &ORE);
}
/// This transformation requires natural loop information & requires that
@@ -260,9 +260,9 @@ struct LegacyLICMPass : public LoopPass {
}
AU.addRequired<TargetTransformInfoWrapperPass>();
getLoopAnalysisUsage(AU);
- LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
- AU.addPreserved<LazyBlockFrequencyInfoPass>();
- AU.addPreserved<LazyBranchProbabilityInfoPass>();
+ LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
+ AU.addPreserved<LazyBlockFrequencyInfoPass>();
+ AU.addPreserved<LazyBranchProbabilityInfoPass>();
}
private:
@@ -278,8 +278,8 @@ PreservedAnalyses LICMPass::run(Loop &L, LoopAnalysisManager &AM,
OptimizationRemarkEmitter ORE(L.getHeader()->getParent());
LoopInvariantCodeMotion LICM(LicmMssaOptCap, LicmMssaNoAccForPromotionCap);
- if (!LICM.runOnLoop(&L, &AR.AA, &AR.LI, &AR.DT, AR.BFI, &AR.TLI, &AR.TTI,
- &AR.SE, AR.MSSA, &ORE))
+ if (!LICM.runOnLoop(&L, &AR.AA, &AR.LI, &AR.DT, AR.BFI, &AR.TLI, &AR.TTI,
+ &AR.SE, AR.MSSA, &ORE))
return PreservedAnalyses::all();
auto PA = getLoopPassPreservedAnalyses();
@@ -299,7 +299,7 @@ INITIALIZE_PASS_DEPENDENCY(LoopPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(LazyBFIPass)
+INITIALIZE_PASS_DEPENDENCY(LazyBFIPass)
INITIALIZE_PASS_END(LegacyLICMPass, "licm", "Loop Invariant Code Motion", false,
false)
@@ -309,42 +309,42 @@ Pass *llvm::createLICMPass(unsigned LicmMssaOptCap,
return new LegacyLICMPass(LicmMssaOptCap, LicmMssaNoAccForPromotionCap);
}
-llvm::SinkAndHoistLICMFlags::SinkAndHoistLICMFlags(bool IsSink, Loop *L,
- MemorySSA *MSSA)
- : SinkAndHoistLICMFlags(SetLicmMssaOptCap, SetLicmMssaNoAccForPromotionCap,
- IsSink, L, MSSA) {}
-
-llvm::SinkAndHoistLICMFlags::SinkAndHoistLICMFlags(
- unsigned LicmMssaOptCap, unsigned LicmMssaNoAccForPromotionCap, bool IsSink,
- Loop *L, MemorySSA *MSSA)
- : LicmMssaOptCap(LicmMssaOptCap),
- LicmMssaNoAccForPromotionCap(LicmMssaNoAccForPromotionCap),
- IsSink(IsSink) {
- assert(((L != nullptr) == (MSSA != nullptr)) &&
- "Unexpected values for SinkAndHoistLICMFlags");
- if (!MSSA)
- return;
-
- unsigned AccessCapCount = 0;
- for (auto *BB : L->getBlocks())
- if (const auto *Accesses = MSSA->getBlockAccesses(BB))
- for (const auto &MA : *Accesses) {
- (void)MA;
- ++AccessCapCount;
- if (AccessCapCount > LicmMssaNoAccForPromotionCap) {
- NoOfMemAccTooLarge = true;
- return;
- }
- }
-}
-
+llvm::SinkAndHoistLICMFlags::SinkAndHoistLICMFlags(bool IsSink, Loop *L,
+ MemorySSA *MSSA)
+ : SinkAndHoistLICMFlags(SetLicmMssaOptCap, SetLicmMssaNoAccForPromotionCap,
+ IsSink, L, MSSA) {}
+
+llvm::SinkAndHoistLICMFlags::SinkAndHoistLICMFlags(
+ unsigned LicmMssaOptCap, unsigned LicmMssaNoAccForPromotionCap, bool IsSink,
+ Loop *L, MemorySSA *MSSA)
+ : LicmMssaOptCap(LicmMssaOptCap),
+ LicmMssaNoAccForPromotionCap(LicmMssaNoAccForPromotionCap),
+ IsSink(IsSink) {
+ assert(((L != nullptr) == (MSSA != nullptr)) &&
+ "Unexpected values for SinkAndHoistLICMFlags");
+ if (!MSSA)
+ return;
+
+ unsigned AccessCapCount = 0;
+ for (auto *BB : L->getBlocks())
+ if (const auto *Accesses = MSSA->getBlockAccesses(BB))
+ for (const auto &MA : *Accesses) {
+ (void)MA;
+ ++AccessCapCount;
+ if (AccessCapCount > LicmMssaNoAccForPromotionCap) {
+ NoOfMemAccTooLarge = true;
+ return;
+ }
+ }
+}
+
/// Hoist expressions out of the specified loop. Note, alias info for inner
/// loop is not preserved so it is not a good idea to run LICM multiple
/// times on one loop.
bool LoopInvariantCodeMotion::runOnLoop(
Loop *L, AAResults *AA, LoopInfo *LI, DominatorTree *DT,
- BlockFrequencyInfo *BFI, TargetLibraryInfo *TLI, TargetTransformInfo *TTI,
- ScalarEvolution *SE, MemorySSA *MSSA, OptimizationRemarkEmitter *ORE) {
+ BlockFrequencyInfo *BFI, TargetLibraryInfo *TLI, TargetTransformInfo *TTI,
+ ScalarEvolution *SE, MemorySSA *MSSA, OptimizationRemarkEmitter *ORE) {
bool Changed = false;
assert(L->isLCSSAForm(*DT) && "Loop is not in LCSSA form.");
@@ -357,18 +357,18 @@ bool LoopInvariantCodeMotion::runOnLoop(
std::unique_ptr<AliasSetTracker> CurAST;
std::unique_ptr<MemorySSAUpdater> MSSAU;
- std::unique_ptr<SinkAndHoistLICMFlags> Flags;
+ std::unique_ptr<SinkAndHoistLICMFlags> Flags;
if (!MSSA) {
LLVM_DEBUG(dbgs() << "LICM: Using Alias Set Tracker.\n");
CurAST = collectAliasInfoForLoop(L, LI, AA);
- Flags = std::make_unique<SinkAndHoistLICMFlags>(
- LicmMssaOptCap, LicmMssaNoAccForPromotionCap, /*IsSink=*/true);
+ Flags = std::make_unique<SinkAndHoistLICMFlags>(
+ LicmMssaOptCap, LicmMssaNoAccForPromotionCap, /*IsSink=*/true);
} else {
LLVM_DEBUG(dbgs() << "LICM: Using MemorySSA.\n");
MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
- Flags = std::make_unique<SinkAndHoistLICMFlags>(
- LicmMssaOptCap, LicmMssaNoAccForPromotionCap, /*IsSink=*/true, L, MSSA);
+ Flags = std::make_unique<SinkAndHoistLICMFlags>(
+ LicmMssaOptCap, LicmMssaNoAccForPromotionCap, /*IsSink=*/true, L, MSSA);
}
// Get the preheader block to move instructions into...
@@ -388,14 +388,14 @@ bool LoopInvariantCodeMotion::runOnLoop(
// us to sink instructions in one pass, without iteration. After sinking
// instructions, we perform another pass to hoist them out of the loop.
if (L->hasDedicatedExits())
- Changed |=
- sinkRegion(DT->getNode(L->getHeader()), AA, LI, DT, BFI, TLI, TTI, L,
- CurAST.get(), MSSAU.get(), &SafetyInfo, *Flags.get(), ORE);
- Flags->setIsSink(false);
+ Changed |=
+ sinkRegion(DT->getNode(L->getHeader()), AA, LI, DT, BFI, TLI, TTI, L,
+ CurAST.get(), MSSAU.get(), &SafetyInfo, *Flags.get(), ORE);
+ Flags->setIsSink(false);
if (Preheader)
- Changed |= hoistRegion(DT->getNode(L->getHeader()), AA, LI, DT, BFI, TLI, L,
- CurAST.get(), MSSAU.get(), SE, &SafetyInfo,
- *Flags.get(), ORE);
+ Changed |= hoistRegion(DT->getNode(L->getHeader()), AA, LI, DT, BFI, TLI, L,
+ CurAST.get(), MSSAU.get(), SE, &SafetyInfo,
+ *Flags.get(), ORE);
// Now that all loop invariants have been removed from the loop, promote any
// memory references to scalars that we can.
@@ -405,7 +405,7 @@ bool LoopInvariantCodeMotion::runOnLoop(
// preheader for SSA updater, so also avoid sinking when no preheader
// is available.
if (!DisablePromotion && Preheader && L->hasDedicatedExits() &&
- !Flags->tooManyMemoryAccesses()) {
+ !Flags->tooManyMemoryAccesses()) {
// Figure out the loop exits and their insertion points
SmallVector<BasicBlock *, 8> ExitBlocks;
L->getUniqueExitBlocks(ExitBlocks);
@@ -474,7 +474,7 @@ bool LoopInvariantCodeMotion::runOnLoop(
// specifically moving instructions across the loop boundary and so it is
// especially in need of sanity checking here.
assert(L->isLCSSAForm(*DT) && "Loop not left in LCSSA form after LICM!");
- assert((L->isOutermost() || L->getParentLoop()->isLCSSAForm(*DT)) &&
+ assert((L->isOutermost() || L->getParentLoop()->isLCSSAForm(*DT)) &&
"Parent loop not left in LCSSA form after LICM!");
if (MSSAU.get() && VerifyMemorySSA)
@@ -491,10 +491,10 @@ bool LoopInvariantCodeMotion::runOnLoop(
/// definitions, allowing us to sink a loop body in one pass without iteration.
///
bool llvm::sinkRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
- DominatorTree *DT, BlockFrequencyInfo *BFI,
- TargetLibraryInfo *TLI, TargetTransformInfo *TTI,
- Loop *CurLoop, AliasSetTracker *CurAST,
- MemorySSAUpdater *MSSAU, ICFLoopSafetyInfo *SafetyInfo,
+ DominatorTree *DT, BlockFrequencyInfo *BFI,
+ TargetLibraryInfo *TLI, TargetTransformInfo *TTI,
+ Loop *CurLoop, AliasSetTracker *CurAST,
+ MemorySSAUpdater *MSSAU, ICFLoopSafetyInfo *SafetyInfo,
SinkAndHoistLICMFlags &Flags,
OptimizationRemarkEmitter *ORE) {
@@ -543,7 +543,7 @@ bool llvm::sinkRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
isNotUsedOrFreeInLoop(I, CurLoop, SafetyInfo, TTI, FreeInLoop) &&
canSinkOrHoistInst(I, AA, DT, CurLoop, CurAST, MSSAU, true, &Flags,
ORE)) {
- if (sink(I, LI, DT, BFI, CurLoop, SafetyInfo, MSSAU, ORE)) {
+ if (sink(I, LI, DT, BFI, CurLoop, SafetyInfo, MSSAU, ORE)) {
if (!FreeInLoop) {
++II;
salvageDebugInfo(I);
@@ -627,7 +627,7 @@ public:
else if (!TrueDestSucc.empty()) {
Function *F = TrueDest->getParent();
auto IsSucc = [&](BasicBlock &BB) { return TrueDestSucc.count(&BB); };
- auto It = llvm::find_if(*F, IsSucc);
+ auto It = llvm::find_if(*F, IsSucc);
assert(It != F->end() && "Could not find successor in function");
CommonSucc = &*It;
}
@@ -695,15 +695,15 @@ public:
return BB != Pair.second && (Pair.first->getSuccessor(0) == BB ||
Pair.first->getSuccessor(1) == BB);
};
- auto It = llvm::find_if(HoistableBranches, HasBBAsSuccessor);
+ auto It = llvm::find_if(HoistableBranches, HasBBAsSuccessor);
// If not involved in a pending branch, hoist to preheader
BasicBlock *InitialPreheader = CurLoop->getLoopPreheader();
if (It == HoistableBranches.end()) {
- LLVM_DEBUG(dbgs() << "LICM using "
- << InitialPreheader->getNameOrAsOperand()
- << " as hoist destination for "
- << BB->getNameOrAsOperand() << "\n");
+ LLVM_DEBUG(dbgs() << "LICM using "
+ << InitialPreheader->getNameOrAsOperand()
+ << " as hoist destination for "
+ << BB->getNameOrAsOperand() << "\n");
HoistDestinationMap[BB] = InitialPreheader;
return InitialPreheader;
}
@@ -788,43 +788,43 @@ public:
};
} // namespace
-// Hoisting/sinking instruction out of a loop isn't always beneficial. It's only
-// only worthwhile if the destination block is actually colder than current
-// block.
-static bool worthSinkOrHoistInst(Instruction &I, BasicBlock *DstBlock,
- OptimizationRemarkEmitter *ORE,
- BlockFrequencyInfo *BFI) {
- // Check block frequency only when runtime profile is available
- // to avoid pathological cases. With static profile, lean towards
- // hosting because it helps canonicalize the loop for vectorizer.
- if (!DstBlock->getParent()->hasProfileData())
- return true;
-
- if (!HoistSinkColdnessThreshold || !BFI)
- return true;
-
- BasicBlock *SrcBlock = I.getParent();
- if (BFI->getBlockFreq(DstBlock).getFrequency() / HoistSinkColdnessThreshold >
- BFI->getBlockFreq(SrcBlock).getFrequency()) {
- ORE->emit([&]() {
- return OptimizationRemarkMissed(DEBUG_TYPE, "SinkHoistInst", &I)
- << "failed to sink or hoist instruction because containing block "
- "has lower frequency than destination block";
- });
- return false;
- }
-
- return true;
-}
-
+// Hoisting/sinking instruction out of a loop isn't always beneficial. It's only
+// only worthwhile if the destination block is actually colder than current
+// block.
+static bool worthSinkOrHoistInst(Instruction &I, BasicBlock *DstBlock,
+ OptimizationRemarkEmitter *ORE,
+ BlockFrequencyInfo *BFI) {
+ // Check block frequency only when runtime profile is available
+ // to avoid pathological cases. With static profile, lean towards
+ // hosting because it helps canonicalize the loop for vectorizer.
+ if (!DstBlock->getParent()->hasProfileData())
+ return true;
+
+ if (!HoistSinkColdnessThreshold || !BFI)
+ return true;
+
+ BasicBlock *SrcBlock = I.getParent();
+ if (BFI->getBlockFreq(DstBlock).getFrequency() / HoistSinkColdnessThreshold >
+ BFI->getBlockFreq(SrcBlock).getFrequency()) {
+ ORE->emit([&]() {
+ return OptimizationRemarkMissed(DEBUG_TYPE, "SinkHoistInst", &I)
+ << "failed to sink or hoist instruction because containing block "
+ "has lower frequency than destination block";
+ });
+ return false;
+ }
+
+ return true;
+}
+
/// Walk the specified region of the CFG (defined by all blocks dominated by
/// the specified block, and that are in the current loop) in depth first
/// order w.r.t the DominatorTree. This allows us to visit definitions before
/// uses, allowing us to hoist a loop body in one pass without iteration.
///
bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
- DominatorTree *DT, BlockFrequencyInfo *BFI,
- TargetLibraryInfo *TLI, Loop *CurLoop,
+ DominatorTree *DT, BlockFrequencyInfo *BFI,
+ TargetLibraryInfo *TLI, Loop *CurLoop,
AliasSetTracker *CurAST, MemorySSAUpdater *MSSAU,
ScalarEvolution *SE, ICFLoopSafetyInfo *SafetyInfo,
SinkAndHoistLICMFlags &Flags,
@@ -875,15 +875,15 @@ bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
// Try hoisting the instruction out to the preheader. We can only do
// this if all of the operands of the instruction are loop invariant and
- // if it is safe to hoist the instruction. We also check block frequency
- // to make sure instruction only gets hoisted into colder blocks.
+ // if it is safe to hoist the instruction. We also check block frequency
+ // to make sure instruction only gets hoisted into colder blocks.
// TODO: It may be safe to hoist if we are hoisting to a conditional block
// and we have accurately duplicated the control flow from the loop header
// to that block.
if (CurLoop->hasLoopInvariantOperands(&I) &&
canSinkOrHoistInst(I, AA, DT, CurLoop, CurAST, MSSAU, true, &Flags,
ORE) &&
- worthSinkOrHoistInst(I, CurLoop->getLoopPreheader(), ORE, BFI) &&
+ worthSinkOrHoistInst(I, CurLoop->getLoopPreheader(), ORE, BFI) &&
isSafeToExecuteUnconditionally(
I, DT, CurLoop, SafetyInfo, ORE,
CurLoop->getLoopPreheader()->getTerminator())) {
@@ -982,7 +982,7 @@ bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
HoistPoint = Dominator->getTerminator();
}
LLVM_DEBUG(dbgs() << "LICM rehoisting to "
- << HoistPoint->getParent()->getNameOrAsOperand()
+ << HoistPoint->getParent()->getNameOrAsOperand()
<< ": " << *I << "\n");
moveInstructionBefore(*I, *HoistPoint, *SafetyInfo, MSSAU, SE);
HoistPoint = I;
@@ -1014,20 +1014,20 @@ static bool isLoadInvariantInLoop(LoadInst *LI, DominatorTree *DT,
Loop *CurLoop) {
Value *Addr = LI->getOperand(0);
const DataLayout &DL = LI->getModule()->getDataLayout();
- const TypeSize LocSizeInBits = DL.getTypeSizeInBits(LI->getType());
-
- // It is not currently possible for clang to generate an invariant.start
- // intrinsic with scalable vector types because we don't support thread local
- // sizeless types and we don't permit sizeless types in structs or classes.
- // Furthermore, even if support is added for this in future the intrinsic
- // itself is defined to have a size of -1 for variable sized objects. This
- // makes it impossible to verify if the intrinsic envelops our region of
- // interest. For example, both <vscale x 32 x i8> and <vscale x 16 x i8>
- // types would have a -1 parameter, but the former is clearly double the size
- // of the latter.
- if (LocSizeInBits.isScalable())
- return false;
-
+ const TypeSize LocSizeInBits = DL.getTypeSizeInBits(LI->getType());
+
+ // It is not currently possible for clang to generate an invariant.start
+ // intrinsic with scalable vector types because we don't support thread local
+ // sizeless types and we don't permit sizeless types in structs or classes.
+ // Furthermore, even if support is added for this in future the intrinsic
+ // itself is defined to have a size of -1 for variable sized objects. This
+ // makes it impossible to verify if the intrinsic envelops our region of
+ // interest. For example, both <vscale x 32 x i8> and <vscale x 16 x i8>
+ // types would have a -1 parameter, but the former is clearly double the size
+ // of the latter.
+ if (LocSizeInBits.isScalable())
+ return false;
+
// if the type is i8 addrspace(x)*, we know this is the type of
// llvm.invariant.start operand
auto *PtrInt8Ty = PointerType::get(Type::getInt8Ty(LI->getContext()),
@@ -1056,17 +1056,17 @@ static bool isLoadInvariantInLoop(LoadInst *LI, DominatorTree *DT,
if (!II || II->getIntrinsicID() != Intrinsic::invariant_start ||
!II->use_empty())
continue;
- ConstantInt *InvariantSize = cast<ConstantInt>(II->getArgOperand(0));
- // The intrinsic supports having a -1 argument for variable sized objects
- // so we should check for that here.
- if (InvariantSize->isNegative())
- continue;
- uint64_t InvariantSizeInBits = InvariantSize->getSExtValue() * 8;
+ ConstantInt *InvariantSize = cast<ConstantInt>(II->getArgOperand(0));
+ // The intrinsic supports having a -1 argument for variable sized objects
+ // so we should check for that here.
+ if (InvariantSize->isNegative())
+ continue;
+ uint64_t InvariantSizeInBits = InvariantSize->getSExtValue() * 8;
// Confirm the invariant.start location size contains the load operand size
// in bits. Also, the invariant.start should dominate the load, and we
// should not hoist the load out of a loop that contains this dominating
// invariant.start.
- if (LocSizeInBits.getFixedSize() <= InvariantSizeInBits &&
+ if (LocSizeInBits.getFixedSize() <= InvariantSizeInBits &&
DT->properlyDominates(II->getParent(), CurLoop->getHeader()))
return true;
}
@@ -1131,9 +1131,9 @@ bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
bool TargetExecutesOncePerLoop,
SinkAndHoistLICMFlags *Flags,
OptimizationRemarkEmitter *ORE) {
- assert(((CurAST != nullptr) ^ (MSSAU != nullptr)) &&
- "Either AliasSetTracker or MemorySSA should be initialized.");
-
+ assert(((CurAST != nullptr) ^ (MSSAU != nullptr)) &&
+ "Either AliasSetTracker or MemorySSA should be initialized.");
+
// If we don't understand the instruction, bail early.
if (!isHoistableAndSinkableInst(I))
return false;
@@ -1167,7 +1167,7 @@ bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
CurLoop, AA);
else
Invalidated = pointerInvalidatedByLoopWithMSSA(
- MSSA, cast<MemoryUse>(MSSA->getMemoryAccess(LI)), CurLoop, I, *Flags);
+ MSSA, cast<MemoryUse>(MSSA->getMemoryAccess(LI)), CurLoop, I, *Flags);
// Check loop-invariant address because this may also be a sinkable load
// whose address is not necessarily loop-invariant.
if (ORE && Invalidated && CurLoop->isLoopInvariant(LI->getPointerOperand()))
@@ -1188,13 +1188,13 @@ bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
if (CI->mayThrow())
return false;
- // Convergent attribute has been used on operations that involve
- // inter-thread communication which results are implicitly affected by the
- // enclosing control flows. It is not safe to hoist or sink such operations
- // across control flow.
- if (CI->isConvergent())
- return false;
-
+ // Convergent attribute has been used on operations that involve
+ // inter-thread communication which results are implicitly affected by the
+ // enclosing control flows. It is not safe to hoist or sink such operations
+ // across control flow.
+ if (CI->isConvergent())
+ return false;
+
using namespace PatternMatch;
if (match(CI, m_Intrinsic<Intrinsic::assume>()))
// Assumes don't actually alias anything or throw
@@ -1219,10 +1219,10 @@ bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
bool Invalidated;
if (CurAST)
Invalidated = pointerInvalidatedByLoop(
- MemoryLocation::getBeforeOrAfter(Op), CurAST, CurLoop, AA);
+ MemoryLocation::getBeforeOrAfter(Op), CurAST, CurLoop, AA);
else
Invalidated = pointerInvalidatedByLoopWithMSSA(
- MSSA, cast<MemoryUse>(MSSA->getMemoryAccess(CI)), CurLoop, I,
+ MSSA, cast<MemoryUse>(MSSA->getMemoryAccess(CI)), CurLoop, I,
*Flags);
if (Invalidated)
return false;
@@ -1282,9 +1282,9 @@ bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
} else { // MSSAU
if (isOnlyMemoryAccess(SI, CurLoop, MSSAU))
return true;
- // If there are more accesses than the Promotion cap or no "quota" to
- // check clobber, then give up as we're not walking a list that long.
- if (Flags->tooManyMemoryAccesses() || Flags->tooManyClobberingCalls())
+ // If there are more accesses than the Promotion cap or no "quota" to
+ // check clobber, then give up as we're not walking a list that long.
+ if (Flags->tooManyMemoryAccesses() || Flags->tooManyClobberingCalls())
return false;
// If there are interfering Uses (i.e. their defining access is in the
// loop), or ordered loads (stored as Defs!), don't move this store.
@@ -1304,7 +1304,7 @@ bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
// Uses may point to an access outside the loop, as getClobbering
// checks the previous iteration when walking the backedge.
// FIXME: More precise: no Uses that alias SI.
- if (!Flags->getIsSink() && !MSSA->dominates(SIMD, MU))
+ if (!Flags->getIsSink() && !MSSA->dominates(SIMD, MU))
return false;
} else if (const auto *MD = dyn_cast<MemoryDef>(&MA)) {
if (auto *LI = dyn_cast<LoadInst>(MD->getMemoryInst())) {
@@ -1324,7 +1324,7 @@ bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
}
}
auto *Source = MSSA->getSkipSelfWalker()->getClobberingMemoryAccess(SI);
- Flags->incrementClobberingCalls();
+ Flags->incrementClobberingCalls();
// If there are no clobbering Defs in the loop, store is safe to hoist.
return MSSA->isLiveOnEntryDef(Source) ||
!CurLoop->contains(Source->getBlock());
@@ -1624,9 +1624,9 @@ static void splitPredecessorsOfLoopExit(PHINode *PN, DominatorTree *DT,
/// position, and may either delete it or move it to outside of the loop.
///
static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT,
- BlockFrequencyInfo *BFI, const Loop *CurLoop,
- ICFLoopSafetyInfo *SafetyInfo, MemorySSAUpdater *MSSAU,
- OptimizationRemarkEmitter *ORE) {
+ BlockFrequencyInfo *BFI, const Loop *CurLoop,
+ ICFLoopSafetyInfo *SafetyInfo, MemorySSAUpdater *MSSAU,
+ OptimizationRemarkEmitter *ORE) {
LLVM_DEBUG(dbgs() << "LICM sinking instruction: " << I << "\n");
ORE->emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "InstSunk", &I)
@@ -1702,10 +1702,10 @@ static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT,
// If this instruction is only used outside of the loop, then all users are
// PHI nodes in exit blocks due to LCSSA form. Just RAUW them with clones of
// the instruction.
- // First check if I is worth sinking for all uses. Sink only when it is worth
- // across all uses.
+ // First check if I is worth sinking for all uses. Sink only when it is worth
+ // across all uses.
SmallSetVector<User*, 8> Users(I.user_begin(), I.user_end());
- SmallVector<PHINode *, 8> ExitPNs;
+ SmallVector<PHINode *, 8> ExitPNs;
for (auto *UI : Users) {
auto *User = cast<Instruction>(UI);
@@ -1715,15 +1715,15 @@ static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT,
PHINode *PN = cast<PHINode>(User);
assert(ExitBlockSet.count(PN->getParent()) &&
"The LCSSA PHI is not in an exit block!");
- if (!worthSinkOrHoistInst(I, PN->getParent(), ORE, BFI)) {
- return Changed;
- }
-
- ExitPNs.push_back(PN);
- }
-
- for (auto *PN : ExitPNs) {
-
+ if (!worthSinkOrHoistInst(I, PN->getParent(), ORE, BFI)) {
+ return Changed;
+ }
+
+ ExitPNs.push_back(PN);
+ }
+
+ for (auto *PN : ExitPNs) {
+
// The PHI must be trivially replaceable.
Instruction *New = sinkThroughTriviallyReplaceablePHI(
PN, &I, LI, SunkCopies, SafetyInfo, CurLoop, MSSAU);
@@ -1741,8 +1741,8 @@ static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop,
BasicBlock *Dest, ICFLoopSafetyInfo *SafetyInfo,
MemorySSAUpdater *MSSAU, ScalarEvolution *SE,
OptimizationRemarkEmitter *ORE) {
- LLVM_DEBUG(dbgs() << "LICM hoisting to " << Dest->getNameOrAsOperand() << ": "
- << I << "\n");
+ LLVM_DEBUG(dbgs() << "LICM hoisting to " << Dest->getNameOrAsOperand() << ": "
+ << I << "\n");
ORE->emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "Hoisted", &I) << "hoisting "
<< ore::NV("Inst", &I);
@@ -1766,7 +1766,7 @@ static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop,
// Move the new node to the destination block, before its terminator.
moveInstructionBefore(I, *Dest->getTerminator(), *SafetyInfo, MSSAU, SE);
- I.updateLocationAfterHoist();
+ I.updateLocationAfterHoist();
if (isa<LoadInst>(I))
++NumMovedLoads;
@@ -1812,7 +1812,7 @@ class LoopPromoter : public LoadAndStorePromoter {
SmallVectorImpl<Instruction *> &LoopInsertPts;
SmallVectorImpl<MemoryAccess *> &MSSAInsertPts;
PredIteratorCache &PredCache;
- AliasSetTracker *AST;
+ AliasSetTracker *AST;
MemorySSAUpdater *MSSAU;
LoopInfo &LI;
DebugLoc DL;
@@ -1842,7 +1842,7 @@ public:
SmallVectorImpl<BasicBlock *> &LEB,
SmallVectorImpl<Instruction *> &LIP,
SmallVectorImpl<MemoryAccess *> &MSSAIP, PredIteratorCache &PIC,
- AliasSetTracker *ast, MemorySSAUpdater *MSSAU, LoopInfo &li,
+ AliasSetTracker *ast, MemorySSAUpdater *MSSAU, LoopInfo &li,
DebugLoc dl, int alignment, bool UnorderedAtomic,
const AAMDNodes &AATags, ICFLoopSafetyInfo &SafetyInfo)
: LoadAndStorePromoter(Insts, S), SomePtr(SP), PointerMustAliases(PMA),
@@ -1899,13 +1899,13 @@ public:
void replaceLoadWithValue(LoadInst *LI, Value *V) const override {
// Update alias analysis.
- if (AST)
- AST->copyValue(LI, V);
+ if (AST)
+ AST->copyValue(LI, V);
}
void instructionDeleted(Instruction *I) const override {
SafetyInfo.removeInstruction(I);
- if (AST)
- AST->deleteValue(I);
+ if (AST)
+ AST->deleteValue(I);
if (MSSAU)
MSSAU->removeMemoryAccess(I);
}
@@ -1951,7 +1951,7 @@ bool llvm::promoteLoopAccessesToScalars(
ICFLoopSafetyInfo *SafetyInfo, OptimizationRemarkEmitter *ORE) {
// Verify inputs.
assert(LI != nullptr && DT != nullptr && CurLoop != nullptr &&
- SafetyInfo != nullptr &&
+ SafetyInfo != nullptr &&
"Unexpected Input to promoteLoopAccessesToScalars");
Value *SomePtr = *PointerMustAliases.begin();
@@ -2016,7 +2016,7 @@ bool llvm::promoteLoopAccessesToScalars(
// we have to prove that the store is dead along the unwind edge. We do
// this by proving that the caller can't have a reference to the object
// after return and thus can't possibly load from the object.
- Value *Object = getUnderlyingObject(SomePtr);
+ Value *Object = getUnderlyingObject(SomePtr);
if (!isKnownNonEscaping(Object, TLI))
return false;
// Subtlety: Alloca's aren't visible to callers, but *are* potentially
@@ -2148,7 +2148,7 @@ bool llvm::promoteLoopAccessesToScalars(
if (IsKnownThreadLocalObject)
SafeToInsertStore = true;
else {
- Value *Object = getUnderlyingObject(SomePtr);
+ Value *Object = getUnderlyingObject(SomePtr);
SafeToInsertStore =
(isAllocLikeFn(Object, TLI) || isa<AllocaInst>(Object)) &&
!PointerMayBeCaptured(Object, true, true);
@@ -2179,7 +2179,7 @@ bool llvm::promoteLoopAccessesToScalars(
SmallVector<PHINode *, 16> NewPHIs;
SSAUpdater SSA(&NewPHIs);
LoopPromoter Promoter(SomePtr, LoopUses, SSA, PointerMustAliases, ExitBlocks,
- InsertPts, MSSAInsertPts, PIC, CurAST, MSSAU, *LI, DL,
+ InsertPts, MSSAInsertPts, PIC, CurAST, MSSAU, *LI, DL,
Alignment.value(), SawUnorderedAtomic, AATags,
*SafetyInfo);
@@ -2294,18 +2294,18 @@ static bool pointerInvalidatedByLoop(MemoryLocation MemLoc,
return false;
}
-bool pointerInvalidatedByLoopWithMSSA(MemorySSA *MSSA, MemoryUse *MU,
- Loop *CurLoop, Instruction &I,
- SinkAndHoistLICMFlags &Flags) {
+bool pointerInvalidatedByLoopWithMSSA(MemorySSA *MSSA, MemoryUse *MU,
+ Loop *CurLoop, Instruction &I,
+ SinkAndHoistLICMFlags &Flags) {
// For hoisting, use the walker to determine safety
- if (!Flags.getIsSink()) {
+ if (!Flags.getIsSink()) {
MemoryAccess *Source;
// See declaration of SetLicmMssaOptCap for usage details.
- if (Flags.tooManyClobberingCalls())
+ if (Flags.tooManyClobberingCalls())
Source = MU->getDefiningAccess();
else {
Source = MSSA->getSkipSelfWalker()->getClobberingMemoryAccess(MU);
- Flags.incrementClobberingCalls();
+ Flags.incrementClobberingCalls();
}
return !MSSA->isLiveOnEntryDef(Source) &&
CurLoop->contains(Source->getBlock());
@@ -2328,28 +2328,28 @@ bool pointerInvalidatedByLoopWithMSSA(MemorySSA *MSSA, MemoryUse *MU,
// FIXME: Increase precision: Safe to sink if Use post dominates the Def;
// needs PostDominatorTreeAnalysis.
// FIXME: More precise: no Defs that alias this Use.
- if (Flags.tooManyMemoryAccesses())
+ if (Flags.tooManyMemoryAccesses())
return true;
for (auto *BB : CurLoop->getBlocks())
- if (pointerInvalidatedByBlockWithMSSA(*BB, *MSSA, *MU))
- return true;
- // When sinking, the source block may not be part of the loop so check it.
- if (!CurLoop->contains(&I))
- return pointerInvalidatedByBlockWithMSSA(*I.getParent(), *MSSA, *MU);
-
+ if (pointerInvalidatedByBlockWithMSSA(*BB, *MSSA, *MU))
+ return true;
+ // When sinking, the source block may not be part of the loop so check it.
+ if (!CurLoop->contains(&I))
+ return pointerInvalidatedByBlockWithMSSA(*I.getParent(), *MSSA, *MU);
+
+ return false;
+}
+
+bool pointerInvalidatedByBlockWithMSSA(BasicBlock &BB, MemorySSA &MSSA,
+ MemoryUse &MU) {
+ if (const auto *Accesses = MSSA.getBlockDefs(&BB))
+ for (const auto &MA : *Accesses)
+ if (const auto *MD = dyn_cast<MemoryDef>(&MA))
+ if (MU.getBlock() != MD->getBlock() || !MSSA.locallyDominates(MD, &MU))
+ return true;
return false;
}
-bool pointerInvalidatedByBlockWithMSSA(BasicBlock &BB, MemorySSA &MSSA,
- MemoryUse &MU) {
- if (const auto *Accesses = MSSA.getBlockDefs(&BB))
- for (const auto &MA : *Accesses)
- if (const auto *MD = dyn_cast<MemoryDef>(&MA))
- if (MU.getBlock() != MD->getBlock() || !MSSA.locallyDominates(MD, &MU))
- return true;
- return false;
-}
-
/// Little predicate that returns true if the specified basic block is in
/// a subloop of the current one, not the current one itself.
///
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopDataPrefetch.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopDataPrefetch.cpp
index 1b6d3484bf..45cdcb2f37 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopDataPrefetch.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopDataPrefetch.cpp
@@ -271,7 +271,7 @@ bool LoopDataPrefetch::runOnLoop(Loop *L) {
bool MadeChange = false;
// Only prefetch in the inner-most loop
- if (!L->isInnermost())
+ if (!L->isInnermost())
return MadeChange;
SmallPtrSet<const Value *, 32> EphValues;
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopDeletion.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopDeletion.cpp
index 3f896ef191..1266c93316 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopDeletion.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopDeletion.cpp
@@ -26,7 +26,7 @@
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Scalar/LoopPassManager.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
-
+
using namespace llvm;
#define DEBUG_TYPE "loop-delete"
@@ -39,14 +39,14 @@ enum class LoopDeletionResult {
Deleted,
};
-static LoopDeletionResult merge(LoopDeletionResult A, LoopDeletionResult B) {
- if (A == LoopDeletionResult::Deleted || B == LoopDeletionResult::Deleted)
- return LoopDeletionResult::Deleted;
- if (A == LoopDeletionResult::Modified || B == LoopDeletionResult::Modified)
- return LoopDeletionResult::Modified;
- return LoopDeletionResult::Unmodified;
-}
-
+static LoopDeletionResult merge(LoopDeletionResult A, LoopDeletionResult B) {
+ if (A == LoopDeletionResult::Deleted || B == LoopDeletionResult::Deleted)
+ return LoopDeletionResult::Deleted;
+ if (A == LoopDeletionResult::Modified || B == LoopDeletionResult::Modified)
+ return LoopDeletionResult::Modified;
+ return LoopDeletionResult::Unmodified;
+}
+
/// Determines if a loop is dead.
///
/// This assumes that we've already checked for unique exit and exiting blocks,
@@ -62,28 +62,28 @@ static bool isLoopDead(Loop *L, ScalarEvolution &SE,
// of the loop.
bool AllEntriesInvariant = true;
bool AllOutgoingValuesSame = true;
- if (!L->hasNoExitBlocks()) {
- for (PHINode &P : ExitBlock->phis()) {
- Value *incoming = P.getIncomingValueForBlock(ExitingBlocks[0]);
-
- // Make sure all exiting blocks produce the same incoming value for the
- // block. If there are different incoming values for different exiting
- // blocks, then it is impossible to statically determine which value
- // should be used.
- AllOutgoingValuesSame =
- all_of(makeArrayRef(ExitingBlocks).slice(1), [&](BasicBlock *BB) {
- return incoming == P.getIncomingValueForBlock(BB);
- });
-
- if (!AllOutgoingValuesSame)
- break;
-
- if (Instruction *I = dyn_cast<Instruction>(incoming))
- if (!L->makeLoopInvariant(I, Changed, Preheader->getTerminator())) {
- AllEntriesInvariant = false;
- break;
- }
- }
+ if (!L->hasNoExitBlocks()) {
+ for (PHINode &P : ExitBlock->phis()) {
+ Value *incoming = P.getIncomingValueForBlock(ExitingBlocks[0]);
+
+ // Make sure all exiting blocks produce the same incoming value for the
+ // block. If there are different incoming values for different exiting
+ // blocks, then it is impossible to statically determine which value
+ // should be used.
+ AllOutgoingValuesSame =
+ all_of(makeArrayRef(ExitingBlocks).slice(1), [&](BasicBlock *BB) {
+ return incoming == P.getIncomingValueForBlock(BB);
+ });
+
+ if (!AllOutgoingValuesSame)
+ break;
+
+ if (Instruction *I = dyn_cast<Instruction>(incoming))
+ if (!L->makeLoopInvariant(I, Changed, Preheader->getTerminator())) {
+ AllEntriesInvariant = false;
+ break;
+ }
+ }
}
if (Changed)
@@ -96,9 +96,9 @@ static bool isLoopDead(Loop *L, ScalarEvolution &SE,
// This includes instructions that could write to memory, and loads that are
// marked volatile.
for (auto &I : L->blocks())
- if (any_of(*I, [](Instruction &I) {
- return I.mayHaveSideEffects() && !I.isDroppable();
- }))
+ if (any_of(*I, [](Instruction &I) {
+ return I.mayHaveSideEffects() && !I.isDroppable();
+ }))
return false;
return true;
}
@@ -135,33 +135,33 @@ static bool isLoopNeverExecuted(Loop *L) {
return true;
}
-/// If we can prove the backedge is untaken, remove it. This destroys the
-/// loop, but leaves the (now trivially loop invariant) control flow and
-/// side effects (if any) in place.
-static LoopDeletionResult
-breakBackedgeIfNotTaken(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
- LoopInfo &LI, MemorySSA *MSSA,
- OptimizationRemarkEmitter &ORE) {
- assert(L->isLCSSAForm(DT) && "Expected LCSSA!");
-
- if (!L->getLoopLatch())
- return LoopDeletionResult::Unmodified;
-
- auto *BTC = SE.getBackedgeTakenCount(L);
- if (!BTC->isZero())
- return LoopDeletionResult::Unmodified;
-
- breakLoopBackedge(L, DT, SE, LI, MSSA);
- return LoopDeletionResult::Deleted;
-}
-
+/// If we can prove the backedge is untaken, remove it. This destroys the
+/// loop, but leaves the (now trivially loop invariant) control flow and
+/// side effects (if any) in place.
+static LoopDeletionResult
+breakBackedgeIfNotTaken(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
+ LoopInfo &LI, MemorySSA *MSSA,
+ OptimizationRemarkEmitter &ORE) {
+ assert(L->isLCSSAForm(DT) && "Expected LCSSA!");
+
+ if (!L->getLoopLatch())
+ return LoopDeletionResult::Unmodified;
+
+ auto *BTC = SE.getBackedgeTakenCount(L);
+ if (!BTC->isZero())
+ return LoopDeletionResult::Unmodified;
+
+ breakLoopBackedge(L, DT, SE, LI, MSSA);
+ return LoopDeletionResult::Deleted;
+}
+
/// Remove a loop if it is dead.
///
-/// A loop is considered dead either if it does not impact the observable
-/// behavior of the program other than finite running time, or if it is
-/// required to make progress by an attribute such as 'mustprogress' or
-/// 'llvm.loop.mustprogress' and does not make any. This may remove
-/// infinite loops that have been required to make progress.
+/// A loop is considered dead either if it does not impact the observable
+/// behavior of the program other than finite running time, or if it is
+/// required to make progress by an attribute such as 'mustprogress' or
+/// 'llvm.loop.mustprogress' and does not make any. This may remove
+/// infinite loops that have been required to make progress.
///
/// This entire process relies pretty heavily on LoopSimplify form and LCSSA in
/// order to make various safety checks work.
@@ -190,10 +190,10 @@ static LoopDeletionResult deleteLoopIfDead(Loop *L, DominatorTree &DT,
if (ExitBlock && isLoopNeverExecuted(L)) {
LLVM_DEBUG(dbgs() << "Loop is proven to never execute, delete it!");
- // We need to forget the loop before setting the incoming values of the exit
- // phis to undef, so we properly invalidate the SCEV expressions for those
- // phis.
- SE.forgetLoop(L);
+ // We need to forget the loop before setting the incoming values of the exit
+ // phis to undef, so we properly invalidate the SCEV expressions for those
+ // phis.
+ SE.forgetLoop(L);
// Set incoming value to undef for phi nodes in the exit block.
for (PHINode &P : ExitBlock->phis()) {
std::fill(P.incoming_values().begin(), P.incoming_values().end(),
@@ -214,12 +214,12 @@ static LoopDeletionResult deleteLoopIfDead(Loop *L, DominatorTree &DT,
SmallVector<BasicBlock *, 4> ExitingBlocks;
L->getExitingBlocks(ExitingBlocks);
- // We require that the loop has at most one exit block. Otherwise, we'd be in
- // the situation of needing to be able to solve statically which exit block
- // will be branched to, or trying to preserve the branching logic in a loop
- // invariant manner.
- if (!ExitBlock && !L->hasNoExitBlocks()) {
- LLVM_DEBUG(dbgs() << "Deletion requires at most one exit block.\n");
+ // We require that the loop has at most one exit block. Otherwise, we'd be in
+ // the situation of needing to be able to solve statically which exit block
+ // will be branched to, or trying to preserve the branching logic in a loop
+ // invariant manner.
+ if (!ExitBlock && !L->hasNoExitBlocks()) {
+ LLVM_DEBUG(dbgs() << "Deletion requires at most one exit block.\n");
return LoopDeletionResult::Unmodified;
}
// Finally, we have to check that the loop really is dead.
@@ -230,13 +230,13 @@ static LoopDeletionResult deleteLoopIfDead(Loop *L, DominatorTree &DT,
: LoopDeletionResult::Unmodified;
}
- // Don't remove loops for which we can't solve the trip count unless the loop
- // was required to make progress but has been determined to be dead.
+ // Don't remove loops for which we can't solve the trip count unless the loop
+ // was required to make progress but has been determined to be dead.
const SCEV *S = SE.getConstantMaxBackedgeTakenCount(L);
- if (isa<SCEVCouldNotCompute>(S) &&
- !L->getHeader()->getParent()->mustProgress() && !hasMustProgress(L)) {
- LLVM_DEBUG(dbgs() << "Could not compute SCEV MaxBackedgeTakenCount and was "
- "not required to make progress.\n");
+ if (isa<SCEVCouldNotCompute>(S) &&
+ !L->getHeader()->getParent()->mustProgress() && !hasMustProgress(L)) {
+ LLVM_DEBUG(dbgs() << "Could not compute SCEV MaxBackedgeTakenCount and was "
+ "not required to make progress.\n");
return Changed ? LoopDeletionResult::Modified
: LoopDeletionResult::Unmodified;
}
@@ -265,14 +265,14 @@ PreservedAnalyses LoopDeletionPass::run(Loop &L, LoopAnalysisManager &AM,
// but ORE cannot be preserved (see comment before the pass definition).
OptimizationRemarkEmitter ORE(L.getHeader()->getParent());
auto Result = deleteLoopIfDead(&L, AR.DT, AR.SE, AR.LI, AR.MSSA, ORE);
-
- // If we can prove the backedge isn't taken, just break it and be done. This
- // leaves the loop structure in place which means it can handle dispatching
- // to the right exit based on whatever loop invariant structure remains.
- if (Result != LoopDeletionResult::Deleted)
- Result = merge(Result, breakBackedgeIfNotTaken(&L, AR.DT, AR.SE, AR.LI,
- AR.MSSA, ORE));
-
+
+ // If we can prove the backedge isn't taken, just break it and be done. This
+ // leaves the loop structure in place which means it can handle dispatching
+ // to the right exit based on whatever loop invariant structure remains.
+ if (Result != LoopDeletionResult::Deleted)
+ Result = merge(Result, breakBackedgeIfNotTaken(&L, AR.DT, AR.SE, AR.LI,
+ AR.MSSA, ORE));
+
if (Result == LoopDeletionResult::Unmodified)
return PreservedAnalyses::all();
@@ -332,12 +332,12 @@ bool LoopDeletionLegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) {
LoopDeletionResult Result = deleteLoopIfDead(L, DT, SE, LI, MSSA, ORE);
- // If we can prove the backedge isn't taken, just break it and be done. This
- // leaves the loop structure in place which means it can handle dispatching
- // to the right exit based on whatever loop invariant structure remains.
- if (Result != LoopDeletionResult::Deleted)
- Result = merge(Result, breakBackedgeIfNotTaken(L, DT, SE, LI, MSSA, ORE));
-
+ // If we can prove the backedge isn't taken, just break it and be done. This
+ // leaves the loop structure in place which means it can handle dispatching
+ // to the right exit based on whatever loop invariant structure remains.
+ if (Result != LoopDeletionResult::Deleted)
+ Result = merge(Result, breakBackedgeIfNotTaken(L, DT, SE, LI, MSSA, ORE));
+
if (Result == LoopDeletionResult::Deleted)
LPM.markLoopAsDeleted(*L);
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopDistribute.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopDistribute.cpp
index 0d467540e3..1bd2529891 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopDistribute.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopDistribute.cpp
@@ -663,20 +663,20 @@ public:
/// Try to distribute an inner-most loop.
bool processLoop(std::function<const LoopAccessInfo &(Loop &)> &GetLAA) {
- assert(L->isInnermost() && "Only process inner loops.");
+ assert(L->isInnermost() && "Only process inner loops.");
LLVM_DEBUG(dbgs() << "\nLDist: In \""
<< L->getHeader()->getParent()->getName()
<< "\" checking " << *L << "\n");
- // Having a single exit block implies there's also one exiting block.
+ // Having a single exit block implies there's also one exiting block.
if (!L->getExitBlock())
return fail("MultipleExitBlocks", "multiple exit blocks");
if (!L->isLoopSimplifyForm())
return fail("NotLoopSimplifyForm",
"loop is not in loop-simplify form");
- if (!L->isRotatedForm())
- return fail("NotBottomTested", "loop is not bottom tested");
+ if (!L->isRotatedForm())
+ return fail("NotBottomTested", "loop is not bottom tested");
BasicBlock *PH = L->getLoopPreheader();
@@ -815,7 +815,7 @@ public:
LLVM_DEBUG(dbgs() << "\nPointers:\n");
LLVM_DEBUG(LAI->getRuntimePointerChecking()->printChecks(dbgs(), Checks));
- LoopVersioning LVer(*LAI, Checks, L, LI, DT, SE);
+ LoopVersioning LVer(*LAI, Checks, L, LI, DT, SE);
LVer.versionLoop(DefsUsedOutside);
LVer.annotateLoopWithNoAlias();
@@ -981,7 +981,7 @@ static bool runImpl(Function &F, LoopInfo *LI, DominatorTree *DT,
for (Loop *TopLevelLoop : *LI)
for (Loop *L : depth_first(TopLevelLoop))
// We only handle inner-most loops.
- if (L->isInnermost())
+ if (L->isInnermost())
Worklist.push_back(L);
// Now walk the identified inner loops.
@@ -1057,8 +1057,8 @@ PreservedAnalyses LoopDistributePass::run(Function &F,
auto &LAM = AM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
std::function<const LoopAccessInfo &(Loop &)> GetLAA =
[&](Loop &L) -> const LoopAccessInfo & {
- LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE,
- TLI, TTI, nullptr, nullptr};
+ LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE,
+ TLI, TTI, nullptr, nullptr};
return LAM.getResult<LoopAccessAnalysis>(L, AR);
};
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopFlatten.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopFlatten.cpp
index f7639dd02e..aaff68436c 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopFlatten.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopFlatten.cpp
@@ -1,728 +1,728 @@
-//===- LoopFlatten.cpp - Loop flattening pass------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass flattens pairs nested loops into a single loop.
-//
-// The intention is to optimise loop nests like this, which together access an
-// array linearly:
-// for (int i = 0; i < N; ++i)
-// for (int j = 0; j < M; ++j)
-// f(A[i*M+j]);
-// into one loop:
-// for (int i = 0; i < (N*M); ++i)
-// f(A[i]);
-//
-// It can also flatten loops where the induction variables are not used in the
-// loop. This is only worth doing if the induction variables are only used in an
-// expression like i*M+j. If they had any other uses, we would have to insert a
-// div/mod to reconstruct the original values, so this wouldn't be profitable.
-//
-// We also need to prove that N*M will not overflow.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Scalar/LoopFlatten.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/OptimizationRemarkEmitter.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/PatternMatch.h"
-#include "llvm/IR/Verifier.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/Transforms/Utils/Local.h"
-#include "llvm/Transforms/Utils/LoopUtils.h"
-#include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
-#include "llvm/Transforms/Utils/SimplifyIndVar.h"
-
-#define DEBUG_TYPE "loop-flatten"
-
-using namespace llvm;
-using namespace llvm::PatternMatch;
-
-static cl::opt<unsigned> RepeatedInstructionThreshold(
- "loop-flatten-cost-threshold", cl::Hidden, cl::init(2),
- cl::desc("Limit on the cost of instructions that can be repeated due to "
- "loop flattening"));
-
-static cl::opt<bool>
- AssumeNoOverflow("loop-flatten-assume-no-overflow", cl::Hidden,
- cl::init(false),
- cl::desc("Assume that the product of the two iteration "
- "limits will never overflow"));
-
-static cl::opt<bool>
- WidenIV("loop-flatten-widen-iv", cl::Hidden,
- cl::init(true),
- cl::desc("Widen the loop induction variables, if possible, so "
- "overflow checks won't reject flattening"));
-
-struct FlattenInfo {
- Loop *OuterLoop = nullptr;
- Loop *InnerLoop = nullptr;
- PHINode *InnerInductionPHI = nullptr;
- PHINode *OuterInductionPHI = nullptr;
- Value *InnerLimit = nullptr;
- Value *OuterLimit = nullptr;
- BinaryOperator *InnerIncrement = nullptr;
- BinaryOperator *OuterIncrement = nullptr;
- BranchInst *InnerBranch = nullptr;
- BranchInst *OuterBranch = nullptr;
- SmallPtrSet<Value *, 4> LinearIVUses;
- SmallPtrSet<PHINode *, 4> InnerPHIsToTransform;
-
- // Whether this holds the flatten info before or after widening.
- bool Widened = false;
-
- FlattenInfo(Loop *OL, Loop *IL) : OuterLoop(OL), InnerLoop(IL) {};
-};
-
-// Finds the induction variable, increment and limit for a simple loop that we
-// can flatten.
-static bool findLoopComponents(
- Loop *L, SmallPtrSetImpl<Instruction *> &IterationInstructions,
- PHINode *&InductionPHI, Value *&Limit, BinaryOperator *&Increment,
- BranchInst *&BackBranch, ScalarEvolution *SE) {
- LLVM_DEBUG(dbgs() << "Finding components of loop: " << L->getName() << "\n");
-
- if (!L->isLoopSimplifyForm()) {
- LLVM_DEBUG(dbgs() << "Loop is not in normal form\n");
- return false;
- }
-
- // There must be exactly one exiting block, and it must be the same at the
- // latch.
- BasicBlock *Latch = L->getLoopLatch();
- if (L->getExitingBlock() != Latch) {
- LLVM_DEBUG(dbgs() << "Exiting and latch block are different\n");
- return false;
- }
- // Latch block must end in a conditional branch.
- BackBranch = dyn_cast<BranchInst>(Latch->getTerminator());
- if (!BackBranch || !BackBranch->isConditional()) {
- LLVM_DEBUG(dbgs() << "Could not find back-branch\n");
- return false;
- }
- IterationInstructions.insert(BackBranch);
- LLVM_DEBUG(dbgs() << "Found back branch: "; BackBranch->dump());
- bool ContinueOnTrue = L->contains(BackBranch->getSuccessor(0));
-
- // Find the induction PHI. If there is no induction PHI, we can't do the
- // transformation. TODO: could other variables trigger this? Do we have to
- // search for the best one?
- InductionPHI = nullptr;
- for (PHINode &PHI : L->getHeader()->phis()) {
- InductionDescriptor ID;
- if (InductionDescriptor::isInductionPHI(&PHI, L, SE, ID)) {
- InductionPHI = &PHI;
- LLVM_DEBUG(dbgs() << "Found induction PHI: "; InductionPHI->dump());
- break;
- }
- }
- if (!InductionPHI) {
- LLVM_DEBUG(dbgs() << "Could not find induction PHI\n");
- return false;
- }
-
- auto IsValidPredicate = [&](ICmpInst::Predicate Pred) {
- if (ContinueOnTrue)
- return Pred == CmpInst::ICMP_NE || Pred == CmpInst::ICMP_ULT;
- else
- return Pred == CmpInst::ICMP_EQ;
- };
-
- // Find Compare and make sure it is valid
- ICmpInst *Compare = dyn_cast<ICmpInst>(BackBranch->getCondition());
- if (!Compare || !IsValidPredicate(Compare->getUnsignedPredicate()) ||
- Compare->hasNUsesOrMore(2)) {
- LLVM_DEBUG(dbgs() << "Could not find valid comparison\n");
- return false;
- }
- IterationInstructions.insert(Compare);
- LLVM_DEBUG(dbgs() << "Found comparison: "; Compare->dump());
-
- // Find increment and limit from the compare
- Increment = nullptr;
- if (match(Compare->getOperand(0),
- m_c_Add(m_Specific(InductionPHI), m_ConstantInt<1>()))) {
- Increment = dyn_cast<BinaryOperator>(Compare->getOperand(0));
- Limit = Compare->getOperand(1);
- } else if (Compare->getUnsignedPredicate() == CmpInst::ICMP_NE &&
- match(Compare->getOperand(1),
- m_c_Add(m_Specific(InductionPHI), m_ConstantInt<1>()))) {
- Increment = dyn_cast<BinaryOperator>(Compare->getOperand(1));
- Limit = Compare->getOperand(0);
- }
- if (!Increment || Increment->hasNUsesOrMore(3)) {
- LLVM_DEBUG(dbgs() << "Cound not find valid increment\n");
- return false;
- }
- IterationInstructions.insert(Increment);
- LLVM_DEBUG(dbgs() << "Found increment: "; Increment->dump());
- LLVM_DEBUG(dbgs() << "Found limit: "; Limit->dump());
-
- assert(InductionPHI->getNumIncomingValues() == 2);
- assert(InductionPHI->getIncomingValueForBlock(Latch) == Increment &&
- "PHI value is not increment inst");
-
- auto *CI = dyn_cast<ConstantInt>(
- InductionPHI->getIncomingValueForBlock(L->getLoopPreheader()));
- if (!CI || !CI->isZero()) {
- LLVM_DEBUG(dbgs() << "PHI value is not zero: "; CI->dump());
- return false;
- }
-
- LLVM_DEBUG(dbgs() << "Successfully found all loop components\n");
- return true;
-}
-
-static bool checkPHIs(struct FlattenInfo &FI,
- const TargetTransformInfo *TTI) {
- // All PHIs in the inner and outer headers must either be:
- // - The induction PHI, which we are going to rewrite as one induction in
- // the new loop. This is already checked by findLoopComponents.
- // - An outer header PHI with all incoming values from outside the loop.
- // LoopSimplify guarantees we have a pre-header, so we don't need to
- // worry about that here.
- // - Pairs of PHIs in the inner and outer headers, which implement a
- // loop-carried dependency that will still be valid in the new loop. To
- // be valid, this variable must be modified only in the inner loop.
-
- // The set of PHI nodes in the outer loop header that we know will still be
- // valid after the transformation. These will not need to be modified (with
- // the exception of the induction variable), but we do need to check that
- // there are no unsafe PHI nodes.
- SmallPtrSet<PHINode *, 4> SafeOuterPHIs;
- SafeOuterPHIs.insert(FI.OuterInductionPHI);
-
- // Check that all PHI nodes in the inner loop header match one of the valid
- // patterns.
- for (PHINode &InnerPHI : FI.InnerLoop->getHeader()->phis()) {
- // The induction PHIs break these rules, and that's OK because we treat
- // them specially when doing the transformation.
- if (&InnerPHI == FI.InnerInductionPHI)
- continue;
-
- // Each inner loop PHI node must have two incoming values/blocks - one
- // from the pre-header, and one from the latch.
- assert(InnerPHI.getNumIncomingValues() == 2);
- Value *PreHeaderValue =
- InnerPHI.getIncomingValueForBlock(FI.InnerLoop->getLoopPreheader());
- Value *LatchValue =
- InnerPHI.getIncomingValueForBlock(FI.InnerLoop->getLoopLatch());
-
- // The incoming value from the outer loop must be the PHI node in the
- // outer loop header, with no modifications made in the top of the outer
- // loop.
- PHINode *OuterPHI = dyn_cast<PHINode>(PreHeaderValue);
- if (!OuterPHI || OuterPHI->getParent() != FI.OuterLoop->getHeader()) {
- LLVM_DEBUG(dbgs() << "value modified in top of outer loop\n");
- return false;
- }
-
- // The other incoming value must come from the inner loop, without any
- // modifications in the tail end of the outer loop. We are in LCSSA form,
- // so this will actually be a PHI in the inner loop's exit block, which
- // only uses values from inside the inner loop.
- PHINode *LCSSAPHI = dyn_cast<PHINode>(
- OuterPHI->getIncomingValueForBlock(FI.OuterLoop->getLoopLatch()));
- if (!LCSSAPHI) {
- LLVM_DEBUG(dbgs() << "could not find LCSSA PHI\n");
- return false;
- }
-
- // The value used by the LCSSA PHI must be the same one that the inner
- // loop's PHI uses.
- if (LCSSAPHI->hasConstantValue() != LatchValue) {
- LLVM_DEBUG(
- dbgs() << "LCSSA PHI incoming value does not match latch value\n");
- return false;
- }
-
- LLVM_DEBUG(dbgs() << "PHI pair is safe:\n");
- LLVM_DEBUG(dbgs() << " Inner: "; InnerPHI.dump());
- LLVM_DEBUG(dbgs() << " Outer: "; OuterPHI->dump());
- SafeOuterPHIs.insert(OuterPHI);
- FI.InnerPHIsToTransform.insert(&InnerPHI);
- }
-
- for (PHINode &OuterPHI : FI.OuterLoop->getHeader()->phis()) {
- if (!SafeOuterPHIs.count(&OuterPHI)) {
- LLVM_DEBUG(dbgs() << "found unsafe PHI in outer loop: "; OuterPHI.dump());
- return false;
- }
- }
-
- LLVM_DEBUG(dbgs() << "checkPHIs: OK\n");
- return true;
-}
-
-static bool
-checkOuterLoopInsts(struct FlattenInfo &FI,
- SmallPtrSetImpl<Instruction *> &IterationInstructions,
- const TargetTransformInfo *TTI) {
- // Check for instructions in the outer but not inner loop. If any of these
- // have side-effects then this transformation is not legal, and if there is
- // a significant amount of code here which can't be optimised out that it's
- // not profitable (as these instructions would get executed for each
- // iteration of the inner loop).
- unsigned RepeatedInstrCost = 0;
- for (auto *B : FI.OuterLoop->getBlocks()) {
- if (FI.InnerLoop->contains(B))
- continue;
-
- for (auto &I : *B) {
- if (!isa<PHINode>(&I) && !I.isTerminator() &&
- !isSafeToSpeculativelyExecute(&I)) {
- LLVM_DEBUG(dbgs() << "Cannot flatten because instruction may have "
- "side effects: ";
- I.dump());
- return false;
- }
- // The execution count of the outer loop's iteration instructions
- // (increment, compare and branch) will be increased, but the
- // equivalent instructions will be removed from the inner loop, so
- // they make a net difference of zero.
- if (IterationInstructions.count(&I))
- continue;
- // The uncoditional branch to the inner loop's header will turn into
- // a fall-through, so adds no cost.
- BranchInst *Br = dyn_cast<BranchInst>(&I);
- if (Br && Br->isUnconditional() &&
- Br->getSuccessor(0) == FI.InnerLoop->getHeader())
- continue;
- // Multiplies of the outer iteration variable and inner iteration
- // count will be optimised out.
- if (match(&I, m_c_Mul(m_Specific(FI.OuterInductionPHI),
- m_Specific(FI.InnerLimit))))
- continue;
- int Cost = TTI->getUserCost(&I, TargetTransformInfo::TCK_SizeAndLatency);
- LLVM_DEBUG(dbgs() << "Cost " << Cost << ": "; I.dump());
- RepeatedInstrCost += Cost;
- }
- }
-
- LLVM_DEBUG(dbgs() << "Cost of instructions that will be repeated: "
- << RepeatedInstrCost << "\n");
- // Bail out if flattening the loops would cause instructions in the outer
- // loop but not in the inner loop to be executed extra times.
- if (RepeatedInstrCost > RepeatedInstructionThreshold) {
- LLVM_DEBUG(dbgs() << "checkOuterLoopInsts: not profitable, bailing.\n");
- return false;
- }
-
- LLVM_DEBUG(dbgs() << "checkOuterLoopInsts: OK\n");
- return true;
-}
-
-static bool checkIVUsers(struct FlattenInfo &FI) {
- // We require all uses of both induction variables to match this pattern:
- //
- // (OuterPHI * InnerLimit) + InnerPHI
- //
- // Any uses of the induction variables not matching that pattern would
- // require a div/mod to reconstruct in the flattened loop, so the
- // transformation wouldn't be profitable.
-
- Value *InnerLimit = FI.InnerLimit;
- if (FI.Widened &&
- (isa<SExtInst>(InnerLimit) || isa<ZExtInst>(InnerLimit)))
- InnerLimit = cast<Instruction>(InnerLimit)->getOperand(0);
-
- // Check that all uses of the inner loop's induction variable match the
- // expected pattern, recording the uses of the outer IV.
- SmallPtrSet<Value *, 4> ValidOuterPHIUses;
- for (User *U : FI.InnerInductionPHI->users()) {
- if (U == FI.InnerIncrement)
- continue;
-
- // After widening the IVs, a trunc instruction might have been introduced, so
- // look through truncs.
- if (isa<TruncInst>(U)) {
- if (!U->hasOneUse())
- return false;
- U = *U->user_begin();
- }
-
- LLVM_DEBUG(dbgs() << "Found use of inner induction variable: "; U->dump());
-
- Value *MatchedMul;
- Value *MatchedItCount;
- bool IsAdd = match(U, m_c_Add(m_Specific(FI.InnerInductionPHI),
- m_Value(MatchedMul))) &&
- match(MatchedMul, m_c_Mul(m_Specific(FI.OuterInductionPHI),
- m_Value(MatchedItCount)));
-
- // Matches the same pattern as above, except it also looks for truncs
- // on the phi, which can be the result of widening the induction variables.
- bool IsAddTrunc = match(U, m_c_Add(m_Trunc(m_Specific(FI.InnerInductionPHI)),
- m_Value(MatchedMul))) &&
- match(MatchedMul,
- m_c_Mul(m_Trunc(m_Specific(FI.OuterInductionPHI)),
- m_Value(MatchedItCount)));
-
- if ((IsAdd || IsAddTrunc) && MatchedItCount == InnerLimit) {
- LLVM_DEBUG(dbgs() << "Use is optimisable\n");
- ValidOuterPHIUses.insert(MatchedMul);
- FI.LinearIVUses.insert(U);
- } else {
- LLVM_DEBUG(dbgs() << "Did not match expected pattern, bailing\n");
- return false;
- }
- }
-
- // Check that there are no uses of the outer IV other than the ones found
- // as part of the pattern above.
- for (User *U : FI.OuterInductionPHI->users()) {
- if (U == FI.OuterIncrement)
- continue;
-
- auto IsValidOuterPHIUses = [&] (User *U) -> bool {
- LLVM_DEBUG(dbgs() << "Found use of outer induction variable: "; U->dump());
- if (!ValidOuterPHIUses.count(U)) {
- LLVM_DEBUG(dbgs() << "Did not match expected pattern, bailing\n");
- return false;
- }
- LLVM_DEBUG(dbgs() << "Use is optimisable\n");
- return true;
- };
-
- if (auto *V = dyn_cast<TruncInst>(U)) {
- for (auto *K : V->users()) {
- if (!IsValidOuterPHIUses(K))
- return false;
- }
- continue;
- }
-
- if (!IsValidOuterPHIUses(U))
- return false;
- }
-
- LLVM_DEBUG(dbgs() << "checkIVUsers: OK\n";
- dbgs() << "Found " << FI.LinearIVUses.size()
- << " value(s) that can be replaced:\n";
- for (Value *V : FI.LinearIVUses) {
- dbgs() << " ";
- V->dump();
- });
- return true;
-}
-
-// Return an OverflowResult dependant on if overflow of the multiplication of
-// InnerLimit and OuterLimit can be assumed not to happen.
-static OverflowResult checkOverflow(struct FlattenInfo &FI,
- DominatorTree *DT, AssumptionCache *AC) {
- Function *F = FI.OuterLoop->getHeader()->getParent();
- const DataLayout &DL = F->getParent()->getDataLayout();
-
- // For debugging/testing.
- if (AssumeNoOverflow)
- return OverflowResult::NeverOverflows;
-
- // Check if the multiply could not overflow due to known ranges of the
- // input values.
- OverflowResult OR = computeOverflowForUnsignedMul(
- FI.InnerLimit, FI.OuterLimit, DL, AC,
- FI.OuterLoop->getLoopPreheader()->getTerminator(), DT);
- if (OR != OverflowResult::MayOverflow)
- return OR;
-
- for (Value *V : FI.LinearIVUses) {
- for (Value *U : V->users()) {
- if (auto *GEP = dyn_cast<GetElementPtrInst>(U)) {
- // The IV is used as the operand of a GEP, and the IV is at least as
- // wide as the address space of the GEP. In this case, the GEP would
- // wrap around the address space before the IV increment wraps, which
- // would be UB.
- if (GEP->isInBounds() &&
- V->getType()->getIntegerBitWidth() >=
- DL.getPointerTypeSizeInBits(GEP->getType())) {
- LLVM_DEBUG(
- dbgs() << "use of linear IV would be UB if overflow occurred: ";
- GEP->dump());
- return OverflowResult::NeverOverflows;
- }
- }
- }
- }
-
- return OverflowResult::MayOverflow;
-}
-
-static bool CanFlattenLoopPair(struct FlattenInfo &FI, DominatorTree *DT,
- LoopInfo *LI, ScalarEvolution *SE,
- AssumptionCache *AC, const TargetTransformInfo *TTI) {
- SmallPtrSet<Instruction *, 8> IterationInstructions;
- if (!findLoopComponents(FI.InnerLoop, IterationInstructions, FI.InnerInductionPHI,
- FI.InnerLimit, FI.InnerIncrement, FI.InnerBranch, SE))
- return false;
- if (!findLoopComponents(FI.OuterLoop, IterationInstructions, FI.OuterInductionPHI,
- FI.OuterLimit, FI.OuterIncrement, FI.OuterBranch, SE))
- return false;
-
- // Both of the loop limit values must be invariant in the outer loop
- // (non-instructions are all inherently invariant).
- if (!FI.OuterLoop->isLoopInvariant(FI.InnerLimit)) {
- LLVM_DEBUG(dbgs() << "inner loop limit not invariant\n");
- return false;
- }
- if (!FI.OuterLoop->isLoopInvariant(FI.OuterLimit)) {
- LLVM_DEBUG(dbgs() << "outer loop limit not invariant\n");
- return false;
- }
-
- if (!checkPHIs(FI, TTI))
- return false;
-
- // FIXME: it should be possible to handle different types correctly.
- if (FI.InnerInductionPHI->getType() != FI.OuterInductionPHI->getType())
- return false;
-
- if (!checkOuterLoopInsts(FI, IterationInstructions, TTI))
- return false;
-
- // Find the values in the loop that can be replaced with the linearized
- // induction variable, and check that there are no other uses of the inner
- // or outer induction variable. If there were, we could still do this
- // transformation, but we'd have to insert a div/mod to calculate the
- // original IVs, so it wouldn't be profitable.
- if (!checkIVUsers(FI))
- return false;
-
- LLVM_DEBUG(dbgs() << "CanFlattenLoopPair: OK\n");
- return true;
-}
-
-static bool DoFlattenLoopPair(struct FlattenInfo &FI, DominatorTree *DT,
- LoopInfo *LI, ScalarEvolution *SE,
- AssumptionCache *AC,
- const TargetTransformInfo *TTI) {
- Function *F = FI.OuterLoop->getHeader()->getParent();
- LLVM_DEBUG(dbgs() << "Checks all passed, doing the transformation\n");
- {
- using namespace ore;
- OptimizationRemark Remark(DEBUG_TYPE, "Flattened", FI.InnerLoop->getStartLoc(),
- FI.InnerLoop->getHeader());
- OptimizationRemarkEmitter ORE(F);
- Remark << "Flattened into outer loop";
- ORE.emit(Remark);
- }
-
- Value *NewTripCount =
- BinaryOperator::CreateMul(FI.InnerLimit, FI.OuterLimit, "flatten.tripcount",
- FI.OuterLoop->getLoopPreheader()->getTerminator());
- LLVM_DEBUG(dbgs() << "Created new trip count in preheader: ";
- NewTripCount->dump());
-
- // Fix up PHI nodes that take values from the inner loop back-edge, which
- // we are about to remove.
- FI.InnerInductionPHI->removeIncomingValue(FI.InnerLoop->getLoopLatch());
-
- // The old Phi will be optimised away later, but for now we can't leave
- // leave it in an invalid state, so are updating them too.
- for (PHINode *PHI : FI.InnerPHIsToTransform)
- PHI->removeIncomingValue(FI.InnerLoop->getLoopLatch());
-
- // Modify the trip count of the outer loop to be the product of the two
- // trip counts.
- cast<User>(FI.OuterBranch->getCondition())->setOperand(1, NewTripCount);
-
- // Replace the inner loop backedge with an unconditional branch to the exit.
- BasicBlock *InnerExitBlock = FI.InnerLoop->getExitBlock();
- BasicBlock *InnerExitingBlock = FI.InnerLoop->getExitingBlock();
- InnerExitingBlock->getTerminator()->eraseFromParent();
- BranchInst::Create(InnerExitBlock, InnerExitingBlock);
- DT->deleteEdge(InnerExitingBlock, FI.InnerLoop->getHeader());
-
- // Replace all uses of the polynomial calculated from the two induction
- // variables with the one new one.
- IRBuilder<> Builder(FI.OuterInductionPHI->getParent()->getTerminator());
- for (Value *V : FI.LinearIVUses) {
- Value *OuterValue = FI.OuterInductionPHI;
- if (FI.Widened)
- OuterValue = Builder.CreateTrunc(FI.OuterInductionPHI, V->getType(),
- "flatten.trunciv");
-
- LLVM_DEBUG(dbgs() << "Replacing: "; V->dump();
- dbgs() << "with: "; OuterValue->dump());
- V->replaceAllUsesWith(OuterValue);
- }
-
- // Tell LoopInfo, SCEV and the pass manager that the inner loop has been
- // deleted, and any information that have about the outer loop invalidated.
- SE->forgetLoop(FI.OuterLoop);
- SE->forgetLoop(FI.InnerLoop);
- LI->erase(FI.InnerLoop);
- return true;
-}
-
-static bool CanWidenIV(struct FlattenInfo &FI, DominatorTree *DT,
- LoopInfo *LI, ScalarEvolution *SE,
- AssumptionCache *AC, const TargetTransformInfo *TTI) {
- if (!WidenIV) {
- LLVM_DEBUG(dbgs() << "Widening the IVs is disabled\n");
- return false;
- }
-
- LLVM_DEBUG(dbgs() << "Try widening the IVs\n");
- Module *M = FI.InnerLoop->getHeader()->getParent()->getParent();
- auto &DL = M->getDataLayout();
- auto *InnerType = FI.InnerInductionPHI->getType();
- auto *OuterType = FI.OuterInductionPHI->getType();
- unsigned MaxLegalSize = DL.getLargestLegalIntTypeSizeInBits();
- auto *MaxLegalType = DL.getLargestLegalIntType(M->getContext());
-
- // If both induction types are less than the maximum legal integer width,
- // promote both to the widest type available so we know calculating
- // (OuterLimit * InnerLimit) as the new trip count is safe.
- if (InnerType != OuterType ||
- InnerType->getScalarSizeInBits() >= MaxLegalSize ||
- MaxLegalType->getScalarSizeInBits() < InnerType->getScalarSizeInBits() * 2) {
- LLVM_DEBUG(dbgs() << "Can't widen the IV\n");
- return false;
- }
-
- SCEVExpander Rewriter(*SE, DL, "loopflatten");
- SmallVector<WideIVInfo, 2> WideIVs;
- SmallVector<WeakTrackingVH, 4> DeadInsts;
- WideIVs.push_back( {FI.InnerInductionPHI, MaxLegalType, false });
- WideIVs.push_back( {FI.OuterInductionPHI, MaxLegalType, false });
- unsigned ElimExt;
- unsigned Widened;
-
- for (unsigned i = 0; i < WideIVs.size(); i++) {
- PHINode *WidePhi = createWideIV(WideIVs[i], LI, SE, Rewriter, DT, DeadInsts,
- ElimExt, Widened, true /* HasGuards */,
- true /* UsePostIncrementRanges */);
- if (!WidePhi)
- return false;
- LLVM_DEBUG(dbgs() << "Created wide phi: "; WidePhi->dump());
- LLVM_DEBUG(dbgs() << "Deleting old phi: "; WideIVs[i].NarrowIV->dump());
- RecursivelyDeleteDeadPHINode(WideIVs[i].NarrowIV);
- }
- // After widening, rediscover all the loop components.
- assert(Widened && "Widenend IV expected");
- FI.Widened = true;
- return CanFlattenLoopPair(FI, DT, LI, SE, AC, TTI);
-}
-
-static bool FlattenLoopPair(struct FlattenInfo &FI, DominatorTree *DT,
- LoopInfo *LI, ScalarEvolution *SE,
- AssumptionCache *AC,
- const TargetTransformInfo *TTI) {
- LLVM_DEBUG(
- dbgs() << "Loop flattening running on outer loop "
- << FI.OuterLoop->getHeader()->getName() << " and inner loop "
- << FI.InnerLoop->getHeader()->getName() << " in "
- << FI.OuterLoop->getHeader()->getParent()->getName() << "\n");
-
- if (!CanFlattenLoopPair(FI, DT, LI, SE, AC, TTI))
- return false;
-
- // Check if we can widen the induction variables to avoid overflow checks.
- if (CanWidenIV(FI, DT, LI, SE, AC, TTI))
- return DoFlattenLoopPair(FI, DT, LI, SE, AC, TTI);
-
- // Check if the new iteration variable might overflow. In this case, we
- // need to version the loop, and select the original version at runtime if
- // the iteration space is too large.
- // TODO: We currently don't version the loop.
- OverflowResult OR = checkOverflow(FI, DT, AC);
- if (OR == OverflowResult::AlwaysOverflowsHigh ||
- OR == OverflowResult::AlwaysOverflowsLow) {
- LLVM_DEBUG(dbgs() << "Multiply would always overflow, so not profitable\n");
- return false;
- } else if (OR == OverflowResult::MayOverflow) {
- LLVM_DEBUG(dbgs() << "Multiply might overflow, not flattening\n");
- return false;
- }
-
- LLVM_DEBUG(dbgs() << "Multiply cannot overflow, modifying loop in-place\n");
- return DoFlattenLoopPair(FI, DT, LI, SE, AC, TTI);
-}
-
-bool Flatten(DominatorTree *DT, LoopInfo *LI, ScalarEvolution *SE,
- AssumptionCache *AC, TargetTransformInfo *TTI) {
- bool Changed = false;
- for (auto *InnerLoop : LI->getLoopsInPreorder()) {
- auto *OuterLoop = InnerLoop->getParentLoop();
- if (!OuterLoop)
- continue;
- struct FlattenInfo FI(OuterLoop, InnerLoop);
- Changed |= FlattenLoopPair(FI, DT, LI, SE, AC, TTI);
- }
- return Changed;
-}
-
-PreservedAnalyses LoopFlattenPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
- auto *LI = &AM.getResult<LoopAnalysis>(F);
- auto *SE = &AM.getResult<ScalarEvolutionAnalysis>(F);
- auto *AC = &AM.getResult<AssumptionAnalysis>(F);
- auto *TTI = &AM.getResult<TargetIRAnalysis>(F);
-
- if (!Flatten(DT, LI, SE, AC, TTI))
- return PreservedAnalyses::all();
-
- PreservedAnalyses PA;
- PA.preserveSet<CFGAnalyses>();
- return PA;
-}
-
-namespace {
-class LoopFlattenLegacyPass : public FunctionPass {
-public:
- static char ID; // Pass ID, replacement for typeid
- LoopFlattenLegacyPass() : FunctionPass(ID) {
- initializeLoopFlattenLegacyPassPass(*PassRegistry::getPassRegistry());
- }
-
- // Possibly flatten loop L into its child.
- bool runOnFunction(Function &F) override;
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- getLoopAnalysisUsage(AU);
- AU.addRequired<TargetTransformInfoWrapperPass>();
- AU.addPreserved<TargetTransformInfoWrapperPass>();
- AU.addRequired<AssumptionCacheTracker>();
- AU.addPreserved<AssumptionCacheTracker>();
- }
-};
-} // namespace
-
-char LoopFlattenLegacyPass::ID = 0;
-INITIALIZE_PASS_BEGIN(LoopFlattenLegacyPass, "loop-flatten", "Flattens loops",
- false, false)
-INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
-INITIALIZE_PASS_END(LoopFlattenLegacyPass, "loop-flatten", "Flattens loops",
- false, false)
-
-FunctionPass *llvm::createLoopFlattenPass() { return new LoopFlattenLegacyPass(); }
-
-bool LoopFlattenLegacyPass::runOnFunction(Function &F) {
- ScalarEvolution *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
- LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
- DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr;
- auto &TTIP = getAnalysis<TargetTransformInfoWrapperPass>();
- auto *TTI = &TTIP.getTTI(F);
- auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
- return Flatten(DT, LI, SE, AC, TTI);
-}
+//===- LoopFlatten.cpp - Loop flattening pass------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass flattens pairs nested loops into a single loop.
+//
+// The intention is to optimise loop nests like this, which together access an
+// array linearly:
+// for (int i = 0; i < N; ++i)
+// for (int j = 0; j < M; ++j)
+// f(A[i*M+j]);
+// into one loop:
+// for (int i = 0; i < (N*M); ++i)
+// f(A[i]);
+//
+// It can also flatten loops where the induction variables are not used in the
+// loop. This is only worth doing if the induction variables are only used in an
+// expression like i*M+j. If they had any other uses, we would have to insert a
+// div/mod to reconstruct the original values, so this wouldn't be profitable.
+//
+// We also need to prove that N*M will not overflow.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Scalar/LoopFlatten.h"
+#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/OptimizationRemarkEmitter.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/LoopUtils.h"
+#include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
+#include "llvm/Transforms/Utils/SimplifyIndVar.h"
+
+#define DEBUG_TYPE "loop-flatten"
+
+using namespace llvm;
+using namespace llvm::PatternMatch;
+
+static cl::opt<unsigned> RepeatedInstructionThreshold(
+ "loop-flatten-cost-threshold", cl::Hidden, cl::init(2),
+ cl::desc("Limit on the cost of instructions that can be repeated due to "
+ "loop flattening"));
+
+static cl::opt<bool>
+ AssumeNoOverflow("loop-flatten-assume-no-overflow", cl::Hidden,
+ cl::init(false),
+ cl::desc("Assume that the product of the two iteration "
+ "limits will never overflow"));
+
+static cl::opt<bool>
+ WidenIV("loop-flatten-widen-iv", cl::Hidden,
+ cl::init(true),
+ cl::desc("Widen the loop induction variables, if possible, so "
+ "overflow checks won't reject flattening"));
+
+struct FlattenInfo {
+ Loop *OuterLoop = nullptr;
+ Loop *InnerLoop = nullptr;
+ PHINode *InnerInductionPHI = nullptr;
+ PHINode *OuterInductionPHI = nullptr;
+ Value *InnerLimit = nullptr;
+ Value *OuterLimit = nullptr;
+ BinaryOperator *InnerIncrement = nullptr;
+ BinaryOperator *OuterIncrement = nullptr;
+ BranchInst *InnerBranch = nullptr;
+ BranchInst *OuterBranch = nullptr;
+ SmallPtrSet<Value *, 4> LinearIVUses;
+ SmallPtrSet<PHINode *, 4> InnerPHIsToTransform;
+
+ // Whether this holds the flatten info before or after widening.
+ bool Widened = false;
+
+ FlattenInfo(Loop *OL, Loop *IL) : OuterLoop(OL), InnerLoop(IL) {};
+};
+
+// Finds the induction variable, increment and limit for a simple loop that we
+// can flatten.
+static bool findLoopComponents(
+ Loop *L, SmallPtrSetImpl<Instruction *> &IterationInstructions,
+ PHINode *&InductionPHI, Value *&Limit, BinaryOperator *&Increment,
+ BranchInst *&BackBranch, ScalarEvolution *SE) {
+ LLVM_DEBUG(dbgs() << "Finding components of loop: " << L->getName() << "\n");
+
+ if (!L->isLoopSimplifyForm()) {
+ LLVM_DEBUG(dbgs() << "Loop is not in normal form\n");
+ return false;
+ }
+
+ // There must be exactly one exiting block, and it must be the same at the
+ // latch.
+ BasicBlock *Latch = L->getLoopLatch();
+ if (L->getExitingBlock() != Latch) {
+ LLVM_DEBUG(dbgs() << "Exiting and latch block are different\n");
+ return false;
+ }
+ // Latch block must end in a conditional branch.
+ BackBranch = dyn_cast<BranchInst>(Latch->getTerminator());
+ if (!BackBranch || !BackBranch->isConditional()) {
+ LLVM_DEBUG(dbgs() << "Could not find back-branch\n");
+ return false;
+ }
+ IterationInstructions.insert(BackBranch);
+ LLVM_DEBUG(dbgs() << "Found back branch: "; BackBranch->dump());
+ bool ContinueOnTrue = L->contains(BackBranch->getSuccessor(0));
+
+ // Find the induction PHI. If there is no induction PHI, we can't do the
+ // transformation. TODO: could other variables trigger this? Do we have to
+ // search for the best one?
+ InductionPHI = nullptr;
+ for (PHINode &PHI : L->getHeader()->phis()) {
+ InductionDescriptor ID;
+ if (InductionDescriptor::isInductionPHI(&PHI, L, SE, ID)) {
+ InductionPHI = &PHI;
+ LLVM_DEBUG(dbgs() << "Found induction PHI: "; InductionPHI->dump());
+ break;
+ }
+ }
+ if (!InductionPHI) {
+ LLVM_DEBUG(dbgs() << "Could not find induction PHI\n");
+ return false;
+ }
+
+ auto IsValidPredicate = [&](ICmpInst::Predicate Pred) {
+ if (ContinueOnTrue)
+ return Pred == CmpInst::ICMP_NE || Pred == CmpInst::ICMP_ULT;
+ else
+ return Pred == CmpInst::ICMP_EQ;
+ };
+
+ // Find Compare and make sure it is valid
+ ICmpInst *Compare = dyn_cast<ICmpInst>(BackBranch->getCondition());
+ if (!Compare || !IsValidPredicate(Compare->getUnsignedPredicate()) ||
+ Compare->hasNUsesOrMore(2)) {
+ LLVM_DEBUG(dbgs() << "Could not find valid comparison\n");
+ return false;
+ }
+ IterationInstructions.insert(Compare);
+ LLVM_DEBUG(dbgs() << "Found comparison: "; Compare->dump());
+
+ // Find increment and limit from the compare
+ Increment = nullptr;
+ if (match(Compare->getOperand(0),
+ m_c_Add(m_Specific(InductionPHI), m_ConstantInt<1>()))) {
+ Increment = dyn_cast<BinaryOperator>(Compare->getOperand(0));
+ Limit = Compare->getOperand(1);
+ } else if (Compare->getUnsignedPredicate() == CmpInst::ICMP_NE &&
+ match(Compare->getOperand(1),
+ m_c_Add(m_Specific(InductionPHI), m_ConstantInt<1>()))) {
+ Increment = dyn_cast<BinaryOperator>(Compare->getOperand(1));
+ Limit = Compare->getOperand(0);
+ }
+ if (!Increment || Increment->hasNUsesOrMore(3)) {
+ LLVM_DEBUG(dbgs() << "Cound not find valid increment\n");
+ return false;
+ }
+ IterationInstructions.insert(Increment);
+ LLVM_DEBUG(dbgs() << "Found increment: "; Increment->dump());
+ LLVM_DEBUG(dbgs() << "Found limit: "; Limit->dump());
+
+ assert(InductionPHI->getNumIncomingValues() == 2);
+ assert(InductionPHI->getIncomingValueForBlock(Latch) == Increment &&
+ "PHI value is not increment inst");
+
+ auto *CI = dyn_cast<ConstantInt>(
+ InductionPHI->getIncomingValueForBlock(L->getLoopPreheader()));
+ if (!CI || !CI->isZero()) {
+ LLVM_DEBUG(dbgs() << "PHI value is not zero: "; CI->dump());
+ return false;
+ }
+
+ LLVM_DEBUG(dbgs() << "Successfully found all loop components\n");
+ return true;
+}
+
+static bool checkPHIs(struct FlattenInfo &FI,
+ const TargetTransformInfo *TTI) {
+ // All PHIs in the inner and outer headers must either be:
+ // - The induction PHI, which we are going to rewrite as one induction in
+ // the new loop. This is already checked by findLoopComponents.
+ // - An outer header PHI with all incoming values from outside the loop.
+ // LoopSimplify guarantees we have a pre-header, so we don't need to
+ // worry about that here.
+ // - Pairs of PHIs in the inner and outer headers, which implement a
+ // loop-carried dependency that will still be valid in the new loop. To
+ // be valid, this variable must be modified only in the inner loop.
+
+ // The set of PHI nodes in the outer loop header that we know will still be
+ // valid after the transformation. These will not need to be modified (with
+ // the exception of the induction variable), but we do need to check that
+ // there are no unsafe PHI nodes.
+ SmallPtrSet<PHINode *, 4> SafeOuterPHIs;
+ SafeOuterPHIs.insert(FI.OuterInductionPHI);
+
+ // Check that all PHI nodes in the inner loop header match one of the valid
+ // patterns.
+ for (PHINode &InnerPHI : FI.InnerLoop->getHeader()->phis()) {
+ // The induction PHIs break these rules, and that's OK because we treat
+ // them specially when doing the transformation.
+ if (&InnerPHI == FI.InnerInductionPHI)
+ continue;
+
+ // Each inner loop PHI node must have two incoming values/blocks - one
+ // from the pre-header, and one from the latch.
+ assert(InnerPHI.getNumIncomingValues() == 2);
+ Value *PreHeaderValue =
+ InnerPHI.getIncomingValueForBlock(FI.InnerLoop->getLoopPreheader());
+ Value *LatchValue =
+ InnerPHI.getIncomingValueForBlock(FI.InnerLoop->getLoopLatch());
+
+ // The incoming value from the outer loop must be the PHI node in the
+ // outer loop header, with no modifications made in the top of the outer
+ // loop.
+ PHINode *OuterPHI = dyn_cast<PHINode>(PreHeaderValue);
+ if (!OuterPHI || OuterPHI->getParent() != FI.OuterLoop->getHeader()) {
+ LLVM_DEBUG(dbgs() << "value modified in top of outer loop\n");
+ return false;
+ }
+
+ // The other incoming value must come from the inner loop, without any
+ // modifications in the tail end of the outer loop. We are in LCSSA form,
+ // so this will actually be a PHI in the inner loop's exit block, which
+ // only uses values from inside the inner loop.
+ PHINode *LCSSAPHI = dyn_cast<PHINode>(
+ OuterPHI->getIncomingValueForBlock(FI.OuterLoop->getLoopLatch()));
+ if (!LCSSAPHI) {
+ LLVM_DEBUG(dbgs() << "could not find LCSSA PHI\n");
+ return false;
+ }
+
+ // The value used by the LCSSA PHI must be the same one that the inner
+ // loop's PHI uses.
+ if (LCSSAPHI->hasConstantValue() != LatchValue) {
+ LLVM_DEBUG(
+ dbgs() << "LCSSA PHI incoming value does not match latch value\n");
+ return false;
+ }
+
+ LLVM_DEBUG(dbgs() << "PHI pair is safe:\n");
+ LLVM_DEBUG(dbgs() << " Inner: "; InnerPHI.dump());
+ LLVM_DEBUG(dbgs() << " Outer: "; OuterPHI->dump());
+ SafeOuterPHIs.insert(OuterPHI);
+ FI.InnerPHIsToTransform.insert(&InnerPHI);
+ }
+
+ for (PHINode &OuterPHI : FI.OuterLoop->getHeader()->phis()) {
+ if (!SafeOuterPHIs.count(&OuterPHI)) {
+ LLVM_DEBUG(dbgs() << "found unsafe PHI in outer loop: "; OuterPHI.dump());
+ return false;
+ }
+ }
+
+ LLVM_DEBUG(dbgs() << "checkPHIs: OK\n");
+ return true;
+}
+
+static bool
+checkOuterLoopInsts(struct FlattenInfo &FI,
+ SmallPtrSetImpl<Instruction *> &IterationInstructions,
+ const TargetTransformInfo *TTI) {
+ // Check for instructions in the outer but not inner loop. If any of these
+ // have side-effects then this transformation is not legal, and if there is
+ // a significant amount of code here which can't be optimised out that it's
+ // not profitable (as these instructions would get executed for each
+ // iteration of the inner loop).
+ unsigned RepeatedInstrCost = 0;
+ for (auto *B : FI.OuterLoop->getBlocks()) {
+ if (FI.InnerLoop->contains(B))
+ continue;
+
+ for (auto &I : *B) {
+ if (!isa<PHINode>(&I) && !I.isTerminator() &&
+ !isSafeToSpeculativelyExecute(&I)) {
+ LLVM_DEBUG(dbgs() << "Cannot flatten because instruction may have "
+ "side effects: ";
+ I.dump());
+ return false;
+ }
+ // The execution count of the outer loop's iteration instructions
+ // (increment, compare and branch) will be increased, but the
+ // equivalent instructions will be removed from the inner loop, so
+ // they make a net difference of zero.
+ if (IterationInstructions.count(&I))
+ continue;
+ // The uncoditional branch to the inner loop's header will turn into
+ // a fall-through, so adds no cost.
+ BranchInst *Br = dyn_cast<BranchInst>(&I);
+ if (Br && Br->isUnconditional() &&
+ Br->getSuccessor(0) == FI.InnerLoop->getHeader())
+ continue;
+ // Multiplies of the outer iteration variable and inner iteration
+ // count will be optimised out.
+ if (match(&I, m_c_Mul(m_Specific(FI.OuterInductionPHI),
+ m_Specific(FI.InnerLimit))))
+ continue;
+ int Cost = TTI->getUserCost(&I, TargetTransformInfo::TCK_SizeAndLatency);
+ LLVM_DEBUG(dbgs() << "Cost " << Cost << ": "; I.dump());
+ RepeatedInstrCost += Cost;
+ }
+ }
+
+ LLVM_DEBUG(dbgs() << "Cost of instructions that will be repeated: "
+ << RepeatedInstrCost << "\n");
+ // Bail out if flattening the loops would cause instructions in the outer
+ // loop but not in the inner loop to be executed extra times.
+ if (RepeatedInstrCost > RepeatedInstructionThreshold) {
+ LLVM_DEBUG(dbgs() << "checkOuterLoopInsts: not profitable, bailing.\n");
+ return false;
+ }
+
+ LLVM_DEBUG(dbgs() << "checkOuterLoopInsts: OK\n");
+ return true;
+}
+
+static bool checkIVUsers(struct FlattenInfo &FI) {
+ // We require all uses of both induction variables to match this pattern:
+ //
+ // (OuterPHI * InnerLimit) + InnerPHI
+ //
+ // Any uses of the induction variables not matching that pattern would
+ // require a div/mod to reconstruct in the flattened loop, so the
+ // transformation wouldn't be profitable.
+
+ Value *InnerLimit = FI.InnerLimit;
+ if (FI.Widened &&
+ (isa<SExtInst>(InnerLimit) || isa<ZExtInst>(InnerLimit)))
+ InnerLimit = cast<Instruction>(InnerLimit)->getOperand(0);
+
+ // Check that all uses of the inner loop's induction variable match the
+ // expected pattern, recording the uses of the outer IV.
+ SmallPtrSet<Value *, 4> ValidOuterPHIUses;
+ for (User *U : FI.InnerInductionPHI->users()) {
+ if (U == FI.InnerIncrement)
+ continue;
+
+ // After widening the IVs, a trunc instruction might have been introduced, so
+ // look through truncs.
+ if (isa<TruncInst>(U)) {
+ if (!U->hasOneUse())
+ return false;
+ U = *U->user_begin();
+ }
+
+ LLVM_DEBUG(dbgs() << "Found use of inner induction variable: "; U->dump());
+
+ Value *MatchedMul;
+ Value *MatchedItCount;
+ bool IsAdd = match(U, m_c_Add(m_Specific(FI.InnerInductionPHI),
+ m_Value(MatchedMul))) &&
+ match(MatchedMul, m_c_Mul(m_Specific(FI.OuterInductionPHI),
+ m_Value(MatchedItCount)));
+
+ // Matches the same pattern as above, except it also looks for truncs
+ // on the phi, which can be the result of widening the induction variables.
+ bool IsAddTrunc = match(U, m_c_Add(m_Trunc(m_Specific(FI.InnerInductionPHI)),
+ m_Value(MatchedMul))) &&
+ match(MatchedMul,
+ m_c_Mul(m_Trunc(m_Specific(FI.OuterInductionPHI)),
+ m_Value(MatchedItCount)));
+
+ if ((IsAdd || IsAddTrunc) && MatchedItCount == InnerLimit) {
+ LLVM_DEBUG(dbgs() << "Use is optimisable\n");
+ ValidOuterPHIUses.insert(MatchedMul);
+ FI.LinearIVUses.insert(U);
+ } else {
+ LLVM_DEBUG(dbgs() << "Did not match expected pattern, bailing\n");
+ return false;
+ }
+ }
+
+ // Check that there are no uses of the outer IV other than the ones found
+ // as part of the pattern above.
+ for (User *U : FI.OuterInductionPHI->users()) {
+ if (U == FI.OuterIncrement)
+ continue;
+
+ auto IsValidOuterPHIUses = [&] (User *U) -> bool {
+ LLVM_DEBUG(dbgs() << "Found use of outer induction variable: "; U->dump());
+ if (!ValidOuterPHIUses.count(U)) {
+ LLVM_DEBUG(dbgs() << "Did not match expected pattern, bailing\n");
+ return false;
+ }
+ LLVM_DEBUG(dbgs() << "Use is optimisable\n");
+ return true;
+ };
+
+ if (auto *V = dyn_cast<TruncInst>(U)) {
+ for (auto *K : V->users()) {
+ if (!IsValidOuterPHIUses(K))
+ return false;
+ }
+ continue;
+ }
+
+ if (!IsValidOuterPHIUses(U))
+ return false;
+ }
+
+ LLVM_DEBUG(dbgs() << "checkIVUsers: OK\n";
+ dbgs() << "Found " << FI.LinearIVUses.size()
+ << " value(s) that can be replaced:\n";
+ for (Value *V : FI.LinearIVUses) {
+ dbgs() << " ";
+ V->dump();
+ });
+ return true;
+}
+
+// Return an OverflowResult dependant on if overflow of the multiplication of
+// InnerLimit and OuterLimit can be assumed not to happen.
+static OverflowResult checkOverflow(struct FlattenInfo &FI,
+ DominatorTree *DT, AssumptionCache *AC) {
+ Function *F = FI.OuterLoop->getHeader()->getParent();
+ const DataLayout &DL = F->getParent()->getDataLayout();
+
+ // For debugging/testing.
+ if (AssumeNoOverflow)
+ return OverflowResult::NeverOverflows;
+
+ // Check if the multiply could not overflow due to known ranges of the
+ // input values.
+ OverflowResult OR = computeOverflowForUnsignedMul(
+ FI.InnerLimit, FI.OuterLimit, DL, AC,
+ FI.OuterLoop->getLoopPreheader()->getTerminator(), DT);
+ if (OR != OverflowResult::MayOverflow)
+ return OR;
+
+ for (Value *V : FI.LinearIVUses) {
+ for (Value *U : V->users()) {
+ if (auto *GEP = dyn_cast<GetElementPtrInst>(U)) {
+ // The IV is used as the operand of a GEP, and the IV is at least as
+ // wide as the address space of the GEP. In this case, the GEP would
+ // wrap around the address space before the IV increment wraps, which
+ // would be UB.
+ if (GEP->isInBounds() &&
+ V->getType()->getIntegerBitWidth() >=
+ DL.getPointerTypeSizeInBits(GEP->getType())) {
+ LLVM_DEBUG(
+ dbgs() << "use of linear IV would be UB if overflow occurred: ";
+ GEP->dump());
+ return OverflowResult::NeverOverflows;
+ }
+ }
+ }
+ }
+
+ return OverflowResult::MayOverflow;
+}
+
+static bool CanFlattenLoopPair(struct FlattenInfo &FI, DominatorTree *DT,
+ LoopInfo *LI, ScalarEvolution *SE,
+ AssumptionCache *AC, const TargetTransformInfo *TTI) {
+ SmallPtrSet<Instruction *, 8> IterationInstructions;
+ if (!findLoopComponents(FI.InnerLoop, IterationInstructions, FI.InnerInductionPHI,
+ FI.InnerLimit, FI.InnerIncrement, FI.InnerBranch, SE))
+ return false;
+ if (!findLoopComponents(FI.OuterLoop, IterationInstructions, FI.OuterInductionPHI,
+ FI.OuterLimit, FI.OuterIncrement, FI.OuterBranch, SE))
+ return false;
+
+ // Both of the loop limit values must be invariant in the outer loop
+ // (non-instructions are all inherently invariant).
+ if (!FI.OuterLoop->isLoopInvariant(FI.InnerLimit)) {
+ LLVM_DEBUG(dbgs() << "inner loop limit not invariant\n");
+ return false;
+ }
+ if (!FI.OuterLoop->isLoopInvariant(FI.OuterLimit)) {
+ LLVM_DEBUG(dbgs() << "outer loop limit not invariant\n");
+ return false;
+ }
+
+ if (!checkPHIs(FI, TTI))
+ return false;
+
+ // FIXME: it should be possible to handle different types correctly.
+ if (FI.InnerInductionPHI->getType() != FI.OuterInductionPHI->getType())
+ return false;
+
+ if (!checkOuterLoopInsts(FI, IterationInstructions, TTI))
+ return false;
+
+ // Find the values in the loop that can be replaced with the linearized
+ // induction variable, and check that there are no other uses of the inner
+ // or outer induction variable. If there were, we could still do this
+ // transformation, but we'd have to insert a div/mod to calculate the
+ // original IVs, so it wouldn't be profitable.
+ if (!checkIVUsers(FI))
+ return false;
+
+ LLVM_DEBUG(dbgs() << "CanFlattenLoopPair: OK\n");
+ return true;
+}
+
+static bool DoFlattenLoopPair(struct FlattenInfo &FI, DominatorTree *DT,
+ LoopInfo *LI, ScalarEvolution *SE,
+ AssumptionCache *AC,
+ const TargetTransformInfo *TTI) {
+ Function *F = FI.OuterLoop->getHeader()->getParent();
+ LLVM_DEBUG(dbgs() << "Checks all passed, doing the transformation\n");
+ {
+ using namespace ore;
+ OptimizationRemark Remark(DEBUG_TYPE, "Flattened", FI.InnerLoop->getStartLoc(),
+ FI.InnerLoop->getHeader());
+ OptimizationRemarkEmitter ORE(F);
+ Remark << "Flattened into outer loop";
+ ORE.emit(Remark);
+ }
+
+ Value *NewTripCount =
+ BinaryOperator::CreateMul(FI.InnerLimit, FI.OuterLimit, "flatten.tripcount",
+ FI.OuterLoop->getLoopPreheader()->getTerminator());
+ LLVM_DEBUG(dbgs() << "Created new trip count in preheader: ";
+ NewTripCount->dump());
+
+ // Fix up PHI nodes that take values from the inner loop back-edge, which
+ // we are about to remove.
+ FI.InnerInductionPHI->removeIncomingValue(FI.InnerLoop->getLoopLatch());
+
+ // The old Phi will be optimised away later, but for now we can't leave
+ // leave it in an invalid state, so are updating them too.
+ for (PHINode *PHI : FI.InnerPHIsToTransform)
+ PHI->removeIncomingValue(FI.InnerLoop->getLoopLatch());
+
+ // Modify the trip count of the outer loop to be the product of the two
+ // trip counts.
+ cast<User>(FI.OuterBranch->getCondition())->setOperand(1, NewTripCount);
+
+ // Replace the inner loop backedge with an unconditional branch to the exit.
+ BasicBlock *InnerExitBlock = FI.InnerLoop->getExitBlock();
+ BasicBlock *InnerExitingBlock = FI.InnerLoop->getExitingBlock();
+ InnerExitingBlock->getTerminator()->eraseFromParent();
+ BranchInst::Create(InnerExitBlock, InnerExitingBlock);
+ DT->deleteEdge(InnerExitingBlock, FI.InnerLoop->getHeader());
+
+ // Replace all uses of the polynomial calculated from the two induction
+ // variables with the one new one.
+ IRBuilder<> Builder(FI.OuterInductionPHI->getParent()->getTerminator());
+ for (Value *V : FI.LinearIVUses) {
+ Value *OuterValue = FI.OuterInductionPHI;
+ if (FI.Widened)
+ OuterValue = Builder.CreateTrunc(FI.OuterInductionPHI, V->getType(),
+ "flatten.trunciv");
+
+ LLVM_DEBUG(dbgs() << "Replacing: "; V->dump();
+ dbgs() << "with: "; OuterValue->dump());
+ V->replaceAllUsesWith(OuterValue);
+ }
+
+ // Tell LoopInfo, SCEV and the pass manager that the inner loop has been
+ // deleted, and any information that have about the outer loop invalidated.
+ SE->forgetLoop(FI.OuterLoop);
+ SE->forgetLoop(FI.InnerLoop);
+ LI->erase(FI.InnerLoop);
+ return true;
+}
+
+static bool CanWidenIV(struct FlattenInfo &FI, DominatorTree *DT,
+ LoopInfo *LI, ScalarEvolution *SE,
+ AssumptionCache *AC, const TargetTransformInfo *TTI) {
+ if (!WidenIV) {
+ LLVM_DEBUG(dbgs() << "Widening the IVs is disabled\n");
+ return false;
+ }
+
+ LLVM_DEBUG(dbgs() << "Try widening the IVs\n");
+ Module *M = FI.InnerLoop->getHeader()->getParent()->getParent();
+ auto &DL = M->getDataLayout();
+ auto *InnerType = FI.InnerInductionPHI->getType();
+ auto *OuterType = FI.OuterInductionPHI->getType();
+ unsigned MaxLegalSize = DL.getLargestLegalIntTypeSizeInBits();
+ auto *MaxLegalType = DL.getLargestLegalIntType(M->getContext());
+
+ // If both induction types are less than the maximum legal integer width,
+ // promote both to the widest type available so we know calculating
+ // (OuterLimit * InnerLimit) as the new trip count is safe.
+ if (InnerType != OuterType ||
+ InnerType->getScalarSizeInBits() >= MaxLegalSize ||
+ MaxLegalType->getScalarSizeInBits() < InnerType->getScalarSizeInBits() * 2) {
+ LLVM_DEBUG(dbgs() << "Can't widen the IV\n");
+ return false;
+ }
+
+ SCEVExpander Rewriter(*SE, DL, "loopflatten");
+ SmallVector<WideIVInfo, 2> WideIVs;
+ SmallVector<WeakTrackingVH, 4> DeadInsts;
+ WideIVs.push_back( {FI.InnerInductionPHI, MaxLegalType, false });
+ WideIVs.push_back( {FI.OuterInductionPHI, MaxLegalType, false });
+ unsigned ElimExt;
+ unsigned Widened;
+
+ for (unsigned i = 0; i < WideIVs.size(); i++) {
+ PHINode *WidePhi = createWideIV(WideIVs[i], LI, SE, Rewriter, DT, DeadInsts,
+ ElimExt, Widened, true /* HasGuards */,
+ true /* UsePostIncrementRanges */);
+ if (!WidePhi)
+ return false;
+ LLVM_DEBUG(dbgs() << "Created wide phi: "; WidePhi->dump());
+ LLVM_DEBUG(dbgs() << "Deleting old phi: "; WideIVs[i].NarrowIV->dump());
+ RecursivelyDeleteDeadPHINode(WideIVs[i].NarrowIV);
+ }
+ // After widening, rediscover all the loop components.
+ assert(Widened && "Widenend IV expected");
+ FI.Widened = true;
+ return CanFlattenLoopPair(FI, DT, LI, SE, AC, TTI);
+}
+
+static bool FlattenLoopPair(struct FlattenInfo &FI, DominatorTree *DT,
+ LoopInfo *LI, ScalarEvolution *SE,
+ AssumptionCache *AC,
+ const TargetTransformInfo *TTI) {
+ LLVM_DEBUG(
+ dbgs() << "Loop flattening running on outer loop "
+ << FI.OuterLoop->getHeader()->getName() << " and inner loop "
+ << FI.InnerLoop->getHeader()->getName() << " in "
+ << FI.OuterLoop->getHeader()->getParent()->getName() << "\n");
+
+ if (!CanFlattenLoopPair(FI, DT, LI, SE, AC, TTI))
+ return false;
+
+ // Check if we can widen the induction variables to avoid overflow checks.
+ if (CanWidenIV(FI, DT, LI, SE, AC, TTI))
+ return DoFlattenLoopPair(FI, DT, LI, SE, AC, TTI);
+
+ // Check if the new iteration variable might overflow. In this case, we
+ // need to version the loop, and select the original version at runtime if
+ // the iteration space is too large.
+ // TODO: We currently don't version the loop.
+ OverflowResult OR = checkOverflow(FI, DT, AC);
+ if (OR == OverflowResult::AlwaysOverflowsHigh ||
+ OR == OverflowResult::AlwaysOverflowsLow) {
+ LLVM_DEBUG(dbgs() << "Multiply would always overflow, so not profitable\n");
+ return false;
+ } else if (OR == OverflowResult::MayOverflow) {
+ LLVM_DEBUG(dbgs() << "Multiply might overflow, not flattening\n");
+ return false;
+ }
+
+ LLVM_DEBUG(dbgs() << "Multiply cannot overflow, modifying loop in-place\n");
+ return DoFlattenLoopPair(FI, DT, LI, SE, AC, TTI);
+}
+
+bool Flatten(DominatorTree *DT, LoopInfo *LI, ScalarEvolution *SE,
+ AssumptionCache *AC, TargetTransformInfo *TTI) {
+ bool Changed = false;
+ for (auto *InnerLoop : LI->getLoopsInPreorder()) {
+ auto *OuterLoop = InnerLoop->getParentLoop();
+ if (!OuterLoop)
+ continue;
+ struct FlattenInfo FI(OuterLoop, InnerLoop);
+ Changed |= FlattenLoopPair(FI, DT, LI, SE, AC, TTI);
+ }
+ return Changed;
+}
+
+PreservedAnalyses LoopFlattenPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
+ auto *LI = &AM.getResult<LoopAnalysis>(F);
+ auto *SE = &AM.getResult<ScalarEvolutionAnalysis>(F);
+ auto *AC = &AM.getResult<AssumptionAnalysis>(F);
+ auto *TTI = &AM.getResult<TargetIRAnalysis>(F);
+
+ if (!Flatten(DT, LI, SE, AC, TTI))
+ return PreservedAnalyses::all();
+
+ PreservedAnalyses PA;
+ PA.preserveSet<CFGAnalyses>();
+ return PA;
+}
+
+namespace {
+class LoopFlattenLegacyPass : public FunctionPass {
+public:
+ static char ID; // Pass ID, replacement for typeid
+ LoopFlattenLegacyPass() : FunctionPass(ID) {
+ initializeLoopFlattenLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+
+ // Possibly flatten loop L into its child.
+ bool runOnFunction(Function &F) override;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ getLoopAnalysisUsage(AU);
+ AU.addRequired<TargetTransformInfoWrapperPass>();
+ AU.addPreserved<TargetTransformInfoWrapperPass>();
+ AU.addRequired<AssumptionCacheTracker>();
+ AU.addPreserved<AssumptionCacheTracker>();
+ }
+};
+} // namespace
+
+char LoopFlattenLegacyPass::ID = 0;
+INITIALIZE_PASS_BEGIN(LoopFlattenLegacyPass, "loop-flatten", "Flattens loops",
+ false, false)
+INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
+INITIALIZE_PASS_END(LoopFlattenLegacyPass, "loop-flatten", "Flattens loops",
+ false, false)
+
+FunctionPass *llvm::createLoopFlattenPass() { return new LoopFlattenLegacyPass(); }
+
+bool LoopFlattenLegacyPass::runOnFunction(Function &F) {
+ ScalarEvolution *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
+ LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
+ auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
+ DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr;
+ auto &TTIP = getAnalysis<TargetTransformInfoWrapperPass>();
+ auto *TTI = &TTIP.getTTI(F);
+ auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
+ return Flatten(DT, LI, SE, AC, TTI);
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopFuse.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopFuse.cpp
index 8131b7060a..b5f8dfa9aa 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopFuse.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopFuse.cpp
@@ -46,7 +46,7 @@
#include "llvm/Transforms/Scalar/LoopFuse.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/DependenceAnalysis.h"
#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/LoopInfo.h"
@@ -54,7 +54,7 @@
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Verifier.h"
#include "llvm/InitializePasses.h"
@@ -66,7 +66,7 @@
#include "llvm/Transforms/Utils.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/CodeMoverUtils.h"
-#include "llvm/Transforms/Utils/LoopPeel.h"
+#include "llvm/Transforms/Utils/LoopPeel.h"
using namespace llvm;
@@ -117,11 +117,11 @@ static cl::opt<FusionDependenceAnalysisChoice> FusionDependenceAnalysis(
"Use all available analyses")),
cl::Hidden, cl::init(FUSION_DEPENDENCE_ANALYSIS_ALL), cl::ZeroOrMore);
-static cl::opt<unsigned> FusionPeelMaxCount(
- "loop-fusion-peel-max-count", cl::init(0), cl::Hidden,
- cl::desc("Max number of iterations to be peeled from a loop, such that "
- "fusion can take place"));
-
+static cl::opt<unsigned> FusionPeelMaxCount(
+ "loop-fusion-peel-max-count", cl::init(0), cl::Hidden,
+ cl::desc("Max number of iterations to be peeled from a loop, such that "
+ "fusion can take place"));
+
#ifndef NDEBUG
static cl::opt<bool>
VerboseFusionDebugging("loop-fusion-verbose-debug",
@@ -165,12 +165,12 @@ struct FusionCandidate {
bool Valid;
/// Guard branch of the loop, if it exists
BranchInst *GuardBranch;
- /// Peeling Paramaters of the Loop.
- TTI::PeelingPreferences PP;
- /// Can you Peel this Loop?
- bool AbleToPeel;
- /// Has this loop been Peeled
- bool Peeled;
+ /// Peeling Paramaters of the Loop.
+ TTI::PeelingPreferences PP;
+ /// Can you Peel this Loop?
+ bool AbleToPeel;
+ /// Has this loop been Peeled
+ bool Peeled;
/// Dominator and PostDominator trees are needed for the
/// FusionCandidateCompare function, required by FusionCandidateSet to
@@ -182,13 +182,13 @@ struct FusionCandidate {
OptimizationRemarkEmitter &ORE;
FusionCandidate(Loop *L, const DominatorTree *DT,
- const PostDominatorTree *PDT, OptimizationRemarkEmitter &ORE,
- TTI::PeelingPreferences PP)
+ const PostDominatorTree *PDT, OptimizationRemarkEmitter &ORE,
+ TTI::PeelingPreferences PP)
: Preheader(L->getLoopPreheader()), Header(L->getHeader()),
ExitingBlock(L->getExitingBlock()), ExitBlock(L->getExitBlock()),
Latch(L->getLoopLatch()), L(L), Valid(true),
- GuardBranch(L->getLoopGuardBranch()), PP(PP), AbleToPeel(canPeel(L)),
- Peeled(false), DT(DT), PDT(PDT), ORE(ORE) {
+ GuardBranch(L->getLoopGuardBranch()), PP(PP), AbleToPeel(canPeel(L)),
+ Peeled(false), DT(DT), PDT(PDT), ORE(ORE) {
// Walk over all blocks in the loop and check for conditions that may
// prevent fusion. For each block, walk over all instructions and collect
@@ -259,17 +259,17 @@ struct FusionCandidate {
return Preheader;
}
- /// After Peeling the loop is modified quite a bit, hence all of the Blocks
- /// need to be updated accordingly.
- void updateAfterPeeling() {
- Preheader = L->getLoopPreheader();
- Header = L->getHeader();
- ExitingBlock = L->getExitingBlock();
- ExitBlock = L->getExitBlock();
- Latch = L->getLoopLatch();
- verify();
- }
-
+ /// After Peeling the loop is modified quite a bit, hence all of the Blocks
+ /// need to be updated accordingly.
+ void updateAfterPeeling() {
+ Preheader = L->getLoopPreheader();
+ Header = L->getHeader();
+ ExitingBlock = L->getExitingBlock();
+ ExitBlock = L->getExitBlock();
+ Latch = L->getLoopLatch();
+ verify();
+ }
+
/// Given a guarded loop, get the successor of the guard that is not in the
/// loop.
///
@@ -281,8 +281,8 @@ struct FusionCandidate {
assert(GuardBranch && "Only valid on guarded loops.");
assert(GuardBranch->isConditional() &&
"Expecting guard to be a conditional branch.");
- if (Peeled)
- return GuardBranch->getSuccessor(1);
+ if (Peeled)
+ return GuardBranch->getSuccessor(1);
return (GuardBranch->getSuccessor(0) == Preheader)
? GuardBranch->getSuccessor(1)
: GuardBranch->getSuccessor(0);
@@ -544,17 +544,17 @@ private:
ScalarEvolution &SE;
PostDominatorTree &PDT;
OptimizationRemarkEmitter &ORE;
- AssumptionCache &AC;
+ AssumptionCache &AC;
+
+ const TargetTransformInfo &TTI;
- const TargetTransformInfo &TTI;
-
public:
LoopFuser(LoopInfo &LI, DominatorTree &DT, DependenceInfo &DI,
ScalarEvolution &SE, PostDominatorTree &PDT,
- OptimizationRemarkEmitter &ORE, const DataLayout &DL,
- AssumptionCache &AC, const TargetTransformInfo &TTI)
+ OptimizationRemarkEmitter &ORE, const DataLayout &DL,
+ AssumptionCache &AC, const TargetTransformInfo &TTI)
: LDT(LI), DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy), LI(LI),
- DT(DT), DI(DI), SE(SE), PDT(PDT), ORE(ORE), AC(AC), TTI(TTI) {}
+ DT(DT), DI(DI), SE(SE), PDT(PDT), ORE(ORE), AC(AC), TTI(TTI) {}
/// This is the main entry point for loop fusion. It will traverse the
/// specified function and collect candidate loops to fuse, starting at the
@@ -639,9 +639,9 @@ private:
/// Flow Equivalent sets, sorted by dominance.
void collectFusionCandidates(const LoopVector &LV) {
for (Loop *L : LV) {
- TTI::PeelingPreferences PP =
- gatherPeelingPreferences(L, SE, TTI, None, None);
- FusionCandidate CurrCand(L, &DT, &PDT, ORE, PP);
+ TTI::PeelingPreferences PP =
+ gatherPeelingPreferences(L, SE, TTI, None, None);
+ FusionCandidate CurrCand(L, &DT, &PDT, ORE, PP);
if (!CurrCand.isEligibleForFusion(SE))
continue;
@@ -691,135 +691,135 @@ private:
/// Determine if two fusion candidates have the same trip count (i.e., they
/// execute the same number of iterations).
///
- /// This function will return a pair of values. The first is a boolean,
- /// stating whether or not the two candidates are known at compile time to
- /// have the same TripCount. The second is the difference in the two
- /// TripCounts. This information can be used later to determine whether or not
- /// peeling can be performed on either one of the candiates.
- std::pair<bool, Optional<unsigned>>
- haveIdenticalTripCounts(const FusionCandidate &FC0,
- const FusionCandidate &FC1) const {
-
+ /// This function will return a pair of values. The first is a boolean,
+ /// stating whether or not the two candidates are known at compile time to
+ /// have the same TripCount. The second is the difference in the two
+ /// TripCounts. This information can be used later to determine whether or not
+ /// peeling can be performed on either one of the candiates.
+ std::pair<bool, Optional<unsigned>>
+ haveIdenticalTripCounts(const FusionCandidate &FC0,
+ const FusionCandidate &FC1) const {
+
const SCEV *TripCount0 = SE.getBackedgeTakenCount(FC0.L);
if (isa<SCEVCouldNotCompute>(TripCount0)) {
UncomputableTripCount++;
LLVM_DEBUG(dbgs() << "Trip count of first loop could not be computed!");
- return {false, None};
+ return {false, None};
}
const SCEV *TripCount1 = SE.getBackedgeTakenCount(FC1.L);
if (isa<SCEVCouldNotCompute>(TripCount1)) {
UncomputableTripCount++;
LLVM_DEBUG(dbgs() << "Trip count of second loop could not be computed!");
- return {false, None};
+ return {false, None};
}
-
+
LLVM_DEBUG(dbgs() << "\tTrip counts: " << *TripCount0 << " & "
<< *TripCount1 << " are "
<< (TripCount0 == TripCount1 ? "identical" : "different")
<< "\n");
- if (TripCount0 == TripCount1)
- return {true, 0};
-
- LLVM_DEBUG(dbgs() << "The loops do not have the same tripcount, "
- "determining the difference between trip counts\n");
-
- // Currently only considering loops with a single exit point
- // and a non-constant trip count.
- const unsigned TC0 = SE.getSmallConstantTripCount(FC0.L);
- const unsigned TC1 = SE.getSmallConstantTripCount(FC1.L);
-
- // If any of the tripcounts are zero that means that loop(s) do not have
- // a single exit or a constant tripcount.
- if (TC0 == 0 || TC1 == 0) {
- LLVM_DEBUG(dbgs() << "Loop(s) do not have a single exit point or do not "
- "have a constant number of iterations. Peeling "
- "is not benefical\n");
- return {false, None};
- }
-
- Optional<unsigned> Difference = None;
- int Diff = TC0 - TC1;
-
- if (Diff > 0)
- Difference = Diff;
- else {
- LLVM_DEBUG(
- dbgs() << "Difference is less than 0. FC1 (second loop) has more "
- "iterations than the first one. Currently not supported\n");
- }
-
- LLVM_DEBUG(dbgs() << "Difference in loop trip count is: " << Difference
- << "\n");
-
- return {false, Difference};
+ if (TripCount0 == TripCount1)
+ return {true, 0};
+
+ LLVM_DEBUG(dbgs() << "The loops do not have the same tripcount, "
+ "determining the difference between trip counts\n");
+
+ // Currently only considering loops with a single exit point
+ // and a non-constant trip count.
+ const unsigned TC0 = SE.getSmallConstantTripCount(FC0.L);
+ const unsigned TC1 = SE.getSmallConstantTripCount(FC1.L);
+
+ // If any of the tripcounts are zero that means that loop(s) do not have
+ // a single exit or a constant tripcount.
+ if (TC0 == 0 || TC1 == 0) {
+ LLVM_DEBUG(dbgs() << "Loop(s) do not have a single exit point or do not "
+ "have a constant number of iterations. Peeling "
+ "is not benefical\n");
+ return {false, None};
+ }
+
+ Optional<unsigned> Difference = None;
+ int Diff = TC0 - TC1;
+
+ if (Diff > 0)
+ Difference = Diff;
+ else {
+ LLVM_DEBUG(
+ dbgs() << "Difference is less than 0. FC1 (second loop) has more "
+ "iterations than the first one. Currently not supported\n");
+ }
+
+ LLVM_DEBUG(dbgs() << "Difference in loop trip count is: " << Difference
+ << "\n");
+
+ return {false, Difference};
+ }
+
+ void peelFusionCandidate(FusionCandidate &FC0, const FusionCandidate &FC1,
+ unsigned PeelCount) {
+ assert(FC0.AbleToPeel && "Should be able to peel loop");
+
+ LLVM_DEBUG(dbgs() << "Attempting to peel first " << PeelCount
+ << " iterations of the first loop. \n");
+
+ FC0.Peeled = peelLoop(FC0.L, PeelCount, &LI, &SE, &DT, &AC, true);
+ if (FC0.Peeled) {
+ LLVM_DEBUG(dbgs() << "Done Peeling\n");
+
+#ifndef NDEBUG
+ auto IdenticalTripCount = haveIdenticalTripCounts(FC0, FC1);
+
+ assert(IdenticalTripCount.first && *IdenticalTripCount.second == 0 &&
+ "Loops should have identical trip counts after peeling");
+#endif
+
+ FC0.PP.PeelCount += PeelCount;
+
+ // Peeling does not update the PDT
+ PDT.recalculate(*FC0.Preheader->getParent());
+
+ FC0.updateAfterPeeling();
+
+ // In this case the iterations of the loop are constant, so the first
+ // loop will execute completely (will not jump from one of
+ // the peeled blocks to the second loop). Here we are updating the
+ // branch conditions of each of the peeled blocks, such that it will
+ // branch to its successor which is not the preheader of the second loop
+ // in the case of unguarded loops, or the succesors of the exit block of
+ // the first loop otherwise. Doing this update will ensure that the entry
+ // block of the first loop dominates the entry block of the second loop.
+ BasicBlock *BB =
+ FC0.GuardBranch ? FC0.ExitBlock->getUniqueSuccessor() : FC1.Preheader;
+ if (BB) {
+ SmallVector<DominatorTree::UpdateType, 8> TreeUpdates;
+ SmallVector<Instruction *, 8> WorkList;
+ for (BasicBlock *Pred : predecessors(BB)) {
+ if (Pred != FC0.ExitBlock) {
+ WorkList.emplace_back(Pred->getTerminator());
+ TreeUpdates.emplace_back(
+ DominatorTree::UpdateType(DominatorTree::Delete, Pred, BB));
+ }
+ }
+ // Cannot modify the predecessors inside the above loop as it will cause
+ // the iterators to be nullptrs, causing memory errors.
+ for (Instruction *CurrentBranch: WorkList) {
+ BasicBlock *Succ = CurrentBranch->getSuccessor(0);
+ if (Succ == BB)
+ Succ = CurrentBranch->getSuccessor(1);
+ ReplaceInstWithInst(CurrentBranch, BranchInst::Create(Succ));
+ }
+
+ DTU.applyUpdates(TreeUpdates);
+ DTU.flush();
+ }
+ LLVM_DEBUG(
+ dbgs() << "Sucessfully peeled " << FC0.PP.PeelCount
+ << " iterations from the first loop.\n"
+ "Both Loops have the same number of iterations now.\n");
+ }
}
- void peelFusionCandidate(FusionCandidate &FC0, const FusionCandidate &FC1,
- unsigned PeelCount) {
- assert(FC0.AbleToPeel && "Should be able to peel loop");
-
- LLVM_DEBUG(dbgs() << "Attempting to peel first " << PeelCount
- << " iterations of the first loop. \n");
-
- FC0.Peeled = peelLoop(FC0.L, PeelCount, &LI, &SE, &DT, &AC, true);
- if (FC0.Peeled) {
- LLVM_DEBUG(dbgs() << "Done Peeling\n");
-
-#ifndef NDEBUG
- auto IdenticalTripCount = haveIdenticalTripCounts(FC0, FC1);
-
- assert(IdenticalTripCount.first && *IdenticalTripCount.second == 0 &&
- "Loops should have identical trip counts after peeling");
-#endif
-
- FC0.PP.PeelCount += PeelCount;
-
- // Peeling does not update the PDT
- PDT.recalculate(*FC0.Preheader->getParent());
-
- FC0.updateAfterPeeling();
-
- // In this case the iterations of the loop are constant, so the first
- // loop will execute completely (will not jump from one of
- // the peeled blocks to the second loop). Here we are updating the
- // branch conditions of each of the peeled blocks, such that it will
- // branch to its successor which is not the preheader of the second loop
- // in the case of unguarded loops, or the succesors of the exit block of
- // the first loop otherwise. Doing this update will ensure that the entry
- // block of the first loop dominates the entry block of the second loop.
- BasicBlock *BB =
- FC0.GuardBranch ? FC0.ExitBlock->getUniqueSuccessor() : FC1.Preheader;
- if (BB) {
- SmallVector<DominatorTree::UpdateType, 8> TreeUpdates;
- SmallVector<Instruction *, 8> WorkList;
- for (BasicBlock *Pred : predecessors(BB)) {
- if (Pred != FC0.ExitBlock) {
- WorkList.emplace_back(Pred->getTerminator());
- TreeUpdates.emplace_back(
- DominatorTree::UpdateType(DominatorTree::Delete, Pred, BB));
- }
- }
- // Cannot modify the predecessors inside the above loop as it will cause
- // the iterators to be nullptrs, causing memory errors.
- for (Instruction *CurrentBranch: WorkList) {
- BasicBlock *Succ = CurrentBranch->getSuccessor(0);
- if (Succ == BB)
- Succ = CurrentBranch->getSuccessor(1);
- ReplaceInstWithInst(CurrentBranch, BranchInst::Create(Succ));
- }
-
- DTU.applyUpdates(TreeUpdates);
- DTU.flush();
- }
- LLVM_DEBUG(
- dbgs() << "Sucessfully peeled " << FC0.PP.PeelCount
- << " iterations from the first loop.\n"
- "Both Loops have the same number of iterations now.\n");
- }
- }
-
/// Walk each set of control flow equivalent fusion candidates and attempt to
/// fuse them. This does a single linear traversal of all candidates in the
/// set. The conditions for legal fusion are checked at this point. If a pair
@@ -851,32 +851,32 @@ private:
FC0->verify();
FC1->verify();
- // Check if the candidates have identical tripcounts (first value of
- // pair), and if not check the difference in the tripcounts between
- // the loops (second value of pair). The difference is not equal to
- // None iff the loops iterate a constant number of times, and have a
- // single exit.
- std::pair<bool, Optional<unsigned>> IdenticalTripCountRes =
- haveIdenticalTripCounts(*FC0, *FC1);
- bool SameTripCount = IdenticalTripCountRes.first;
- Optional<unsigned> TCDifference = IdenticalTripCountRes.second;
-
- // Here we are checking that FC0 (the first loop) can be peeled, and
- // both loops have different tripcounts.
- if (FC0->AbleToPeel && !SameTripCount && TCDifference) {
- if (*TCDifference > FusionPeelMaxCount) {
- LLVM_DEBUG(dbgs()
- << "Difference in loop trip counts: " << *TCDifference
- << " is greater than maximum peel count specificed: "
- << FusionPeelMaxCount << "\n");
- } else {
- // Dependent on peeling being performed on the first loop, and
- // assuming all other conditions for fusion return true.
- SameTripCount = true;
- }
- }
-
- if (!SameTripCount) {
+ // Check if the candidates have identical tripcounts (first value of
+ // pair), and if not check the difference in the tripcounts between
+ // the loops (second value of pair). The difference is not equal to
+ // None iff the loops iterate a constant number of times, and have a
+ // single exit.
+ std::pair<bool, Optional<unsigned>> IdenticalTripCountRes =
+ haveIdenticalTripCounts(*FC0, *FC1);
+ bool SameTripCount = IdenticalTripCountRes.first;
+ Optional<unsigned> TCDifference = IdenticalTripCountRes.second;
+
+ // Here we are checking that FC0 (the first loop) can be peeled, and
+ // both loops have different tripcounts.
+ if (FC0->AbleToPeel && !SameTripCount && TCDifference) {
+ if (*TCDifference > FusionPeelMaxCount) {
+ LLVM_DEBUG(dbgs()
+ << "Difference in loop trip counts: " << *TCDifference
+ << " is greater than maximum peel count specificed: "
+ << FusionPeelMaxCount << "\n");
+ } else {
+ // Dependent on peeling being performed on the first loop, and
+ // assuming all other conditions for fusion return true.
+ SameTripCount = true;
+ }
+ }
+
+ if (!SameTripCount) {
LLVM_DEBUG(dbgs() << "Fusion candidates do not have identical trip "
"counts. Not fusing.\n");
reportLoopFusion<OptimizationRemarkMissed>(*FC0, *FC1,
@@ -894,7 +894,7 @@ private:
// Ensure that FC0 and FC1 have identical guards.
// If one (or both) are not guarded, this check is not necessary.
if (FC0->GuardBranch && FC1->GuardBranch &&
- !haveIdenticalGuards(*FC0, *FC1) && !TCDifference) {
+ !haveIdenticalGuards(*FC0, *FC1) && !TCDifference) {
LLVM_DEBUG(dbgs() << "Fusion candidates do not have identical "
"guards. Not Fusing.\n");
reportLoopFusion<OptimizationRemarkMissed>(*FC0, *FC1,
@@ -963,23 +963,23 @@ private:
LLVM_DEBUG(dbgs() << "\tFusion is performed: " << *FC0 << " and "
<< *FC1 << "\n");
- FusionCandidate FC0Copy = *FC0;
- // Peel the loop after determining that fusion is legal. The Loops
- // will still be safe to fuse after the peeling is performed.
- bool Peel = TCDifference && *TCDifference > 0;
- if (Peel)
- peelFusionCandidate(FC0Copy, *FC1, *TCDifference);
-
+ FusionCandidate FC0Copy = *FC0;
+ // Peel the loop after determining that fusion is legal. The Loops
+ // will still be safe to fuse after the peeling is performed.
+ bool Peel = TCDifference && *TCDifference > 0;
+ if (Peel)
+ peelFusionCandidate(FC0Copy, *FC1, *TCDifference);
+
// Report fusion to the Optimization Remarks.
// Note this needs to be done *before* performFusion because
// performFusion will change the original loops, making it not
// possible to identify them after fusion is complete.
- reportLoopFusion<OptimizationRemark>((Peel ? FC0Copy : *FC0), *FC1,
- FuseCounter);
+ reportLoopFusion<OptimizationRemark>((Peel ? FC0Copy : *FC0), *FC1,
+ FuseCounter);
- FusionCandidate FusedCand(
- performFusion((Peel ? FC0Copy : *FC0), *FC1), &DT, &PDT, ORE,
- FC0Copy.PP);
+ FusionCandidate FusedCand(
+ performFusion((Peel ? FC0Copy : *FC0), *FC1), &DT, &PDT, ORE,
+ FC0Copy.PP);
FusedCand.verify();
assert(FusedCand.isEligibleForFusion(SE) &&
"Fused candidate should be eligible for fusion!");
@@ -1256,17 +1256,17 @@ private:
return (FC1.GuardBranch->getSuccessor(1) == FC1.Preheader);
}
- /// Modify the latch branch of FC to be unconditional since successors of the
- /// branch are the same.
+ /// Modify the latch branch of FC to be unconditional since successors of the
+ /// branch are the same.
void simplifyLatchBranch(const FusionCandidate &FC) const {
BranchInst *FCLatchBranch = dyn_cast<BranchInst>(FC.Latch->getTerminator());
if (FCLatchBranch) {
assert(FCLatchBranch->isConditional() &&
FCLatchBranch->getSuccessor(0) == FCLatchBranch->getSuccessor(1) &&
"Expecting the two successors of FCLatchBranch to be the same");
- BranchInst *NewBranch =
- BranchInst::Create(FCLatchBranch->getSuccessor(0));
- ReplaceInstWithInst(FCLatchBranch, NewBranch);
+ BranchInst *NewBranch =
+ BranchInst::Create(FCLatchBranch->getSuccessor(0));
+ ReplaceInstWithInst(FCLatchBranch, NewBranch);
}
}
@@ -1326,8 +1326,8 @@ private:
if (FC0.GuardBranch)
return fuseGuardedLoops(FC0, FC1);
- assert(FC1.Preheader ==
- (FC0.Peeled ? FC0.ExitBlock->getUniqueSuccessor() : FC0.ExitBlock));
+ assert(FC1.Preheader ==
+ (FC0.Peeled ? FC0.ExitBlock->getUniqueSuccessor() : FC0.ExitBlock));
assert(FC1.Preheader->size() == 1 &&
FC1.Preheader->getSingleSuccessor() == FC1.Header);
@@ -1369,30 +1369,30 @@ private:
// to FC1.Header? I think this is basically what the three sequences are
// trying to accomplish; however, doing this directly in the CFG may mean
// the DT/PDT becomes invalid
- if (!FC0.Peeled) {
- FC0.ExitingBlock->getTerminator()->replaceUsesOfWith(FC1.Preheader,
- FC1.Header);
- TreeUpdates.emplace_back(DominatorTree::UpdateType(
- DominatorTree::Delete, FC0.ExitingBlock, FC1.Preheader));
- TreeUpdates.emplace_back(DominatorTree::UpdateType(
- DominatorTree::Insert, FC0.ExitingBlock, FC1.Header));
- } else {
- TreeUpdates.emplace_back(DominatorTree::UpdateType(
- DominatorTree::Delete, FC0.ExitBlock, FC1.Preheader));
-
- // Remove the ExitBlock of the first Loop (also not needed)
- FC0.ExitingBlock->getTerminator()->replaceUsesOfWith(FC0.ExitBlock,
- FC1.Header);
- TreeUpdates.emplace_back(DominatorTree::UpdateType(
- DominatorTree::Delete, FC0.ExitingBlock, FC0.ExitBlock));
- FC0.ExitBlock->getTerminator()->eraseFromParent();
- TreeUpdates.emplace_back(DominatorTree::UpdateType(
- DominatorTree::Insert, FC0.ExitingBlock, FC1.Header));
- new UnreachableInst(FC0.ExitBlock->getContext(), FC0.ExitBlock);
- }
-
+ if (!FC0.Peeled) {
+ FC0.ExitingBlock->getTerminator()->replaceUsesOfWith(FC1.Preheader,
+ FC1.Header);
+ TreeUpdates.emplace_back(DominatorTree::UpdateType(
+ DominatorTree::Delete, FC0.ExitingBlock, FC1.Preheader));
+ TreeUpdates.emplace_back(DominatorTree::UpdateType(
+ DominatorTree::Insert, FC0.ExitingBlock, FC1.Header));
+ } else {
+ TreeUpdates.emplace_back(DominatorTree::UpdateType(
+ DominatorTree::Delete, FC0.ExitBlock, FC1.Preheader));
+
+ // Remove the ExitBlock of the first Loop (also not needed)
+ FC0.ExitingBlock->getTerminator()->replaceUsesOfWith(FC0.ExitBlock,
+ FC1.Header);
+ TreeUpdates.emplace_back(DominatorTree::UpdateType(
+ DominatorTree::Delete, FC0.ExitingBlock, FC0.ExitBlock));
+ FC0.ExitBlock->getTerminator()->eraseFromParent();
+ TreeUpdates.emplace_back(DominatorTree::UpdateType(
+ DominatorTree::Insert, FC0.ExitingBlock, FC1.Header));
+ new UnreachableInst(FC0.ExitBlock->getContext(), FC0.ExitBlock);
+ }
+
// The pre-header of L1 is not necessary anymore.
- assert(pred_empty(FC1.Preheader));
+ assert(pred_empty(FC1.Preheader));
FC1.Preheader->getTerminator()->eraseFromParent();
new UnreachableInst(FC1.Preheader->getContext(), FC1.Preheader);
TreeUpdates.emplace_back(DominatorTree::UpdateType(
@@ -1433,7 +1433,7 @@ private:
FC0.Latch->getTerminator()->replaceUsesOfWith(FC0.Header, FC1.Header);
FC1.Latch->getTerminator()->replaceUsesOfWith(FC1.Header, FC0.Header);
- // Modify the latch branch of FC0 to be unconditional as both successors of
+ // Modify the latch branch of FC0 to be unconditional as both successors of
// the branch are the same.
simplifyLatchBranch(FC0);
@@ -1455,11 +1455,11 @@ private:
LI.removeBlock(FC1.Preheader);
DTU.deleteBB(FC1.Preheader);
- if (FC0.Peeled) {
- LI.removeBlock(FC0.ExitBlock);
- DTU.deleteBB(FC0.ExitBlock);
- }
-
+ if (FC0.Peeled) {
+ LI.removeBlock(FC0.ExitBlock);
+ DTU.deleteBB(FC0.ExitBlock);
+ }
+
DTU.flush();
// Is there a way to keep SE up-to-date so we don't need to forget the loops
@@ -1474,7 +1474,7 @@ private:
mergeLatch(FC0, FC1);
// Merge the loops.
- SmallVector<BasicBlock *, 8> Blocks(FC1.L->blocks());
+ SmallVector<BasicBlock *, 8> Blocks(FC1.L->blocks());
for (BasicBlock *BB : Blocks) {
FC0.L->addBlockEntry(BB);
FC1.L->removeBlockFromLoop(BB);
@@ -1482,7 +1482,7 @@ private:
continue;
LI.changeLoopFor(BB, FC0.L);
}
- while (!FC1.L->isInnermost()) {
+ while (!FC1.L->isInnermost()) {
const auto &ChildLoopIt = FC1.L->begin();
Loop *ChildLoop = *ChildLoopIt;
FC1.L->removeChildLoop(ChildLoopIt);
@@ -1555,15 +1555,15 @@ private:
BasicBlock *FC1GuardBlock = FC1.GuardBranch->getParent();
BasicBlock *FC0NonLoopBlock = FC0.getNonLoopBlock();
BasicBlock *FC1NonLoopBlock = FC1.getNonLoopBlock();
- BasicBlock *FC0ExitBlockSuccessor = FC0.ExitBlock->getUniqueSuccessor();
+ BasicBlock *FC0ExitBlockSuccessor = FC0.ExitBlock->getUniqueSuccessor();
// Move instructions from the exit block of FC0 to the beginning of the exit
- // block of FC1, in the case that the FC0 loop has not been peeled. In the
- // case that FC0 loop is peeled, then move the instructions of the successor
- // of the FC0 Exit block to the beginning of the exit block of FC1.
- moveInstructionsToTheBeginning(
- (FC0.Peeled ? *FC0ExitBlockSuccessor : *FC0.ExitBlock), *FC1.ExitBlock,
- DT, PDT, DI);
+ // block of FC1, in the case that the FC0 loop has not been peeled. In the
+ // case that FC0 loop is peeled, then move the instructions of the successor
+ // of the FC0 Exit block to the beginning of the exit block of FC1.
+ moveInstructionsToTheBeginning(
+ (FC0.Peeled ? *FC0ExitBlockSuccessor : *FC0.ExitBlock), *FC1.ExitBlock,
+ DT, PDT, DI);
// Move instructions from the guard block of FC1 to the end of the guard
// block of FC0.
@@ -1584,9 +1584,9 @@ private:
FC1NonLoopBlock->replacePhiUsesWith(FC1GuardBlock, FC0GuardBlock);
FC0.GuardBranch->replaceUsesOfWith(FC0NonLoopBlock, FC1NonLoopBlock);
- BasicBlock *BBToUpdate = FC0.Peeled ? FC0ExitBlockSuccessor : FC0.ExitBlock;
- BBToUpdate->getTerminator()->replaceUsesOfWith(FC1GuardBlock, FC1.Header);
-
+ BasicBlock *BBToUpdate = FC0.Peeled ? FC0ExitBlockSuccessor : FC0.ExitBlock;
+ BBToUpdate->getTerminator()->replaceUsesOfWith(FC1GuardBlock, FC1.Header);
+
// The guard of FC1 is not necessary anymore.
FC1.GuardBranch->eraseFromParent();
new UnreachableInst(FC1GuardBlock->getContext(), FC1GuardBlock);
@@ -1600,18 +1600,18 @@ private:
TreeUpdates.emplace_back(DominatorTree::UpdateType(
DominatorTree::Insert, FC0GuardBlock, FC1NonLoopBlock));
- if (FC0.Peeled) {
- // Remove the Block after the ExitBlock of FC0
- TreeUpdates.emplace_back(DominatorTree::UpdateType(
- DominatorTree::Delete, FC0ExitBlockSuccessor, FC1GuardBlock));
- FC0ExitBlockSuccessor->getTerminator()->eraseFromParent();
- new UnreachableInst(FC0ExitBlockSuccessor->getContext(),
- FC0ExitBlockSuccessor);
- }
-
- assert(pred_empty(FC1GuardBlock) &&
+ if (FC0.Peeled) {
+ // Remove the Block after the ExitBlock of FC0
+ TreeUpdates.emplace_back(DominatorTree::UpdateType(
+ DominatorTree::Delete, FC0ExitBlockSuccessor, FC1GuardBlock));
+ FC0ExitBlockSuccessor->getTerminator()->eraseFromParent();
+ new UnreachableInst(FC0ExitBlockSuccessor->getContext(),
+ FC0ExitBlockSuccessor);
+ }
+
+ assert(pred_empty(FC1GuardBlock) &&
"Expecting guard block to have no predecessors");
- assert(succ_empty(FC1GuardBlock) &&
+ assert(succ_empty(FC1GuardBlock) &&
"Expecting guard block to have no successors");
// Remember the phi nodes originally in the header of FC0 in order to rewire
@@ -1665,13 +1665,13 @@ private:
// TODO: In the future, we can handle non-empty exit blocks my merging any
// instructions from FC0 exit block into FC1 exit block prior to removing
// the block.
- assert(pred_empty(FC0.ExitBlock) && "Expecting exit block to be empty");
+ assert(pred_empty(FC0.ExitBlock) && "Expecting exit block to be empty");
FC0.ExitBlock->getTerminator()->eraseFromParent();
new UnreachableInst(FC0.ExitBlock->getContext(), FC0.ExitBlock);
// Remove FC1 Preheader
// The pre-header of L1 is not necessary anymore.
- assert(pred_empty(FC1.Preheader));
+ assert(pred_empty(FC1.Preheader));
FC1.Preheader->getTerminator()->eraseFromParent();
new UnreachableInst(FC1.Preheader->getContext(), FC1.Preheader);
TreeUpdates.emplace_back(DominatorTree::UpdateType(
@@ -1714,7 +1714,7 @@ private:
FC0.Latch->getTerminator()->replaceUsesOfWith(FC0.Header, FC1.Header);
FC1.Latch->getTerminator()->replaceUsesOfWith(FC1.Header, FC0.Header);
- // Modify the latch branch of FC0 to be unconditional as both successors of
+ // Modify the latch branch of FC0 to be unconditional as both successors of
// the branch are the same.
simplifyLatchBranch(FC0);
@@ -1734,8 +1734,8 @@ private:
// All done
// Apply the updates to the Dominator Tree and cleanup.
- assert(succ_empty(FC1GuardBlock) && "FC1GuardBlock has successors!!");
- assert(pred_empty(FC1GuardBlock) && "FC1GuardBlock has predecessors!!");
+ assert(succ_empty(FC1GuardBlock) && "FC1GuardBlock has successors!!");
+ assert(pred_empty(FC1GuardBlock) && "FC1GuardBlock has predecessors!!");
// Update DT/PDT
DTU.applyUpdates(TreeUpdates);
@@ -1743,10 +1743,10 @@ private:
LI.removeBlock(FC1GuardBlock);
LI.removeBlock(FC1.Preheader);
LI.removeBlock(FC0.ExitBlock);
- if (FC0.Peeled) {
- LI.removeBlock(FC0ExitBlockSuccessor);
- DTU.deleteBB(FC0ExitBlockSuccessor);
- }
+ if (FC0.Peeled) {
+ LI.removeBlock(FC0ExitBlockSuccessor);
+ DTU.deleteBB(FC0ExitBlockSuccessor);
+ }
DTU.deleteBB(FC1GuardBlock);
DTU.deleteBB(FC1.Preheader);
DTU.deleteBB(FC0.ExitBlock);
@@ -1764,7 +1764,7 @@ private:
mergeLatch(FC0, FC1);
// Merge the loops.
- SmallVector<BasicBlock *, 8> Blocks(FC1.L->blocks());
+ SmallVector<BasicBlock *, 8> Blocks(FC1.L->blocks());
for (BasicBlock *BB : Blocks) {
FC0.L->addBlockEntry(BB);
FC1.L->removeBlockFromLoop(BB);
@@ -1772,7 +1772,7 @@ private:
continue;
LI.changeLoopFor(BB, FC0.L);
}
- while (!FC1.L->isInnermost()) {
+ while (!FC1.L->isInnermost()) {
const auto &ChildLoopIt = FC1.L->begin();
Loop *ChildLoop = *ChildLoopIt;
FC1.L->removeChildLoop(ChildLoopIt);
@@ -1812,8 +1812,8 @@ struct LoopFuseLegacy : public FunctionPass {
AU.addRequired<PostDominatorTreeWrapperPass>();
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
AU.addRequired<DependenceAnalysisWrapperPass>();
- AU.addRequired<AssumptionCacheTracker>();
- AU.addRequired<TargetTransformInfoWrapperPass>();
+ AU.addRequired<AssumptionCacheTracker>();
+ AU.addRequired<TargetTransformInfoWrapperPass>();
AU.addPreserved<ScalarEvolutionWrapperPass>();
AU.addPreserved<LoopInfoWrapperPass>();
@@ -1830,12 +1830,12 @@ struct LoopFuseLegacy : public FunctionPass {
auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
auto &PDT = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
- auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
- const TargetTransformInfo &TTI =
- getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
- const DataLayout &DL = F.getParent()->getDataLayout();
+ auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
+ const TargetTransformInfo &TTI =
+ getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
+ const DataLayout &DL = F.getParent()->getDataLayout();
- LoopFuser LF(LI, DT, DI, SE, PDT, ORE, DL, AC, TTI);
+ LoopFuser LF(LI, DT, DI, SE, PDT, ORE, DL, AC, TTI);
return LF.fuseLoops(F);
}
};
@@ -1848,11 +1848,11 @@ PreservedAnalyses LoopFusePass::run(Function &F, FunctionAnalysisManager &AM) {
auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
auto &PDT = AM.getResult<PostDominatorTreeAnalysis>(F);
auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
- auto &AC = AM.getResult<AssumptionAnalysis>(F);
- const TargetTransformInfo &TTI = AM.getResult<TargetIRAnalysis>(F);
- const DataLayout &DL = F.getParent()->getDataLayout();
+ auto &AC = AM.getResult<AssumptionAnalysis>(F);
+ const TargetTransformInfo &TTI = AM.getResult<TargetIRAnalysis>(F);
+ const DataLayout &DL = F.getParent()->getDataLayout();
- LoopFuser LF(LI, DT, DI, SE, PDT, ORE, DL, AC, TTI);
+ LoopFuser LF(LI, DT, DI, SE, PDT, ORE, DL, AC, TTI);
bool Changed = LF.fuseLoops(F);
if (!Changed)
return PreservedAnalyses::all();
@@ -1875,8 +1875,8 @@ INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DependenceAnalysisWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
-INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
+INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_END(LoopFuseLegacy, "loop-fusion", "Loop Fusion", false, false)
FunctionPass *llvm::createLoopFusePass() { return new LoopFuseLegacy(); }
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index e60c95b7be..8064c02e2b 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -47,7 +47,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/CmpInstAnalysis.h"
+#include "llvm/Analysis/CmpInstAnalysis.h"
#include "llvm/Analysis/LoopAccessAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
@@ -80,7 +80,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
-#include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
@@ -108,33 +108,33 @@ using namespace llvm;
STATISTIC(NumMemSet, "Number of memset's formed from loop stores");
STATISTIC(NumMemCpy, "Number of memcpy's formed from loop load+stores");
-STATISTIC(
- NumShiftUntilBitTest,
- "Number of uncountable loops recognized as 'shift until bitttest' idiom");
-
-bool DisableLIRP::All;
-static cl::opt<bool, true>
- DisableLIRPAll("disable-" DEBUG_TYPE "-all",
- cl::desc("Options to disable Loop Idiom Recognize Pass."),
- cl::location(DisableLIRP::All), cl::init(false),
- cl::ReallyHidden);
-
-bool DisableLIRP::Memset;
-static cl::opt<bool, true>
- DisableLIRPMemset("disable-" DEBUG_TYPE "-memset",
- cl::desc("Proceed with loop idiom recognize pass, but do "
- "not convert loop(s) to memset."),
- cl::location(DisableLIRP::Memset), cl::init(false),
- cl::ReallyHidden);
-
-bool DisableLIRP::Memcpy;
-static cl::opt<bool, true>
- DisableLIRPMemcpy("disable-" DEBUG_TYPE "-memcpy",
- cl::desc("Proceed with loop idiom recognize pass, but do "
- "not convert loop(s) to memcpy."),
- cl::location(DisableLIRP::Memcpy), cl::init(false),
- cl::ReallyHidden);
-
+STATISTIC(
+ NumShiftUntilBitTest,
+ "Number of uncountable loops recognized as 'shift until bitttest' idiom");
+
+bool DisableLIRP::All;
+static cl::opt<bool, true>
+ DisableLIRPAll("disable-" DEBUG_TYPE "-all",
+ cl::desc("Options to disable Loop Idiom Recognize Pass."),
+ cl::location(DisableLIRP::All), cl::init(false),
+ cl::ReallyHidden);
+
+bool DisableLIRP::Memset;
+static cl::opt<bool, true>
+ DisableLIRPMemset("disable-" DEBUG_TYPE "-memset",
+ cl::desc("Proceed with loop idiom recognize pass, but do "
+ "not convert loop(s) to memset."),
+ cl::location(DisableLIRP::Memset), cl::init(false),
+ cl::ReallyHidden);
+
+bool DisableLIRP::Memcpy;
+static cl::opt<bool, true>
+ DisableLIRPMemcpy("disable-" DEBUG_TYPE "-memcpy",
+ cl::desc("Proceed with loop idiom recognize pass, but do "
+ "not convert loop(s) to memcpy."),
+ cl::location(DisableLIRP::Memcpy), cl::init(false),
+ cl::ReallyHidden);
+
static cl::opt<bool> UseLIRCodeSizeHeurs(
"use-lir-code-size-heurs",
cl::desc("Use loop idiom recognition code size heuristics when compiling"
@@ -232,8 +232,8 @@ private:
const DebugLoc &DL, bool ZeroCheck,
bool IsCntPhiUsedOutsideLoop);
- bool recognizeShiftUntilBitTest();
-
+ bool recognizeShiftUntilBitTest();
+
/// @}
};
@@ -247,9 +247,9 @@ public:
}
bool runOnLoop(Loop *L, LPPassManager &LPM) override {
- if (DisableLIRP::All)
- return false;
-
+ if (DisableLIRP::All)
+ return false;
+
if (skipLoop(L))
return false;
@@ -295,9 +295,9 @@ char LoopIdiomRecognizeLegacyPass::ID = 0;
PreservedAnalyses LoopIdiomRecognizePass::run(Loop &L, LoopAnalysisManager &AM,
LoopStandardAnalysisResults &AR,
LPMUpdater &) {
- if (DisableLIRP::All)
- return PreservedAnalyses::all();
-
+ if (DisableLIRP::All)
+ return PreservedAnalyses::all();
+
const auto *DL = &L.getHeader()->getModule()->getDataLayout();
// For the new PM, we also can't use OptimizationRemarkEmitter as an analysis
@@ -469,17 +469,17 @@ LoopIdiomRecognize::isLegalStore(StoreInst *SI) {
Value *StoredVal = SI->getValueOperand();
Value *StorePtr = SI->getPointerOperand();
- // Don't convert stores of non-integral pointer types to memsets (which stores
- // integers).
- if (DL->isNonIntegralPointerType(StoredVal->getType()->getScalarType()))
- return LegalStoreKind::None;
-
+ // Don't convert stores of non-integral pointer types to memsets (which stores
+ // integers).
+ if (DL->isNonIntegralPointerType(StoredVal->getType()->getScalarType()))
+ return LegalStoreKind::None;
+
// Reject stores that are so large that they overflow an unsigned.
- // When storing out scalable vectors we bail out for now, since the code
- // below currently only works for constant strides.
- TypeSize SizeInBits = DL->getTypeSizeInBits(StoredVal->getType());
- if (SizeInBits.isScalable() || (SizeInBits.getFixedSize() & 7) ||
- (SizeInBits.getFixedSize() >> 32) != 0)
+ // When storing out scalable vectors we bail out for now, since the code
+ // below currently only works for constant strides.
+ TypeSize SizeInBits = DL->getTypeSizeInBits(StoredVal->getType());
+ if (SizeInBits.isScalable() || (SizeInBits.getFixedSize() & 7) ||
+ (SizeInBits.getFixedSize() >> 32) != 0)
return LegalStoreKind::None;
// See if the pointer expression is an AddRec like {base,+,1} on the current
@@ -508,13 +508,13 @@ LoopIdiomRecognize::isLegalStore(StoreInst *SI) {
// If we're allowed to form a memset, and the stored value would be
// acceptable for memset, use it.
- if (!UnorderedAtomic && HasMemset && SplatValue && !DisableLIRP::Memset &&
+ if (!UnorderedAtomic && HasMemset && SplatValue && !DisableLIRP::Memset &&
// Verify that the stored value is loop invariant. If not, we can't
// promote the memset.
CurLoop->isLoopInvariant(SplatValue)) {
// It looks like we can use SplatValue.
return LegalStoreKind::Memset;
- } else if (!UnorderedAtomic && HasMemsetPattern && !DisableLIRP::Memset &&
+ } else if (!UnorderedAtomic && HasMemsetPattern && !DisableLIRP::Memset &&
// Don't create memset_pattern16s with address spaces.
StorePtr->getType()->getPointerAddressSpace() == 0 &&
(PatternValue = getMemSetPatternValue(StoredVal, DL))) {
@@ -523,7 +523,7 @@ LoopIdiomRecognize::isLegalStore(StoreInst *SI) {
}
// Otherwise, see if the store can be turned into a memcpy.
- if (HasMemcpy && !DisableLIRP::Memcpy) {
+ if (HasMemcpy && !DisableLIRP::Memcpy) {
// Check to see if the stride matches the size of the store. If so, then we
// know that every byte is touched in the loop.
APInt Stride = getStoreStride(StoreEv);
@@ -578,12 +578,12 @@ void LoopIdiomRecognize::collectStores(BasicBlock *BB) {
break;
case LegalStoreKind::Memset: {
// Find the base pointer.
- Value *Ptr = getUnderlyingObject(SI->getPointerOperand());
+ Value *Ptr = getUnderlyingObject(SI->getPointerOperand());
StoreRefsForMemset[Ptr].push_back(SI);
} break;
case LegalStoreKind::MemsetPattern: {
// Find the base pointer.
- Value *Ptr = getUnderlyingObject(SI->getPointerOperand());
+ Value *Ptr = getUnderlyingObject(SI->getPointerOperand());
StoreRefsForMemsetPattern[Ptr].push_back(SI);
} break;
case LegalStoreKind::Memcpy:
@@ -851,7 +851,7 @@ mayLoopAccessLocation(Value *Ptr, ModRefInfo Access, Loop *L,
// Get the location that may be stored across the loop. Since the access is
// strided positively through memory, we say that the modified location starts
// at the pointer and has infinite size.
- LocationSize AccessSize = LocationSize::afterPointer();
+ LocationSize AccessSize = LocationSize::afterPointer();
// If the loop iterates a fixed number of times, we can refine the access size
// to be exactly the size of the memset, which is (BECount+1)*StoreSize
@@ -903,8 +903,8 @@ static const SCEV *getNumBytes(const SCEV *BECount, Type *IntPtr,
// If we're going to need to zero extend the BE count, check if we can add
// one to it prior to zero extending without overflow. Provided this is safe,
// it allows better simplification of the +1.
- if (DL->getTypeSizeInBits(BECount->getType()).getFixedSize() <
- DL->getTypeSizeInBits(IntPtr).getFixedSize() &&
+ if (DL->getTypeSizeInBits(BECount->getType()).getFixedSize() <
+ DL->getTypeSizeInBits(IntPtr).getFixedSize() &&
SE->isLoopEntryGuardedByCond(
CurLoop, ICmpInst::ICMP_NE, BECount,
SE->getNegativeSCEV(SE->getOne(BECount->getType())))) {
@@ -947,12 +947,12 @@ bool LoopIdiomRecognize::processLoopStridedStore(
BasicBlock *Preheader = CurLoop->getLoopPreheader();
IRBuilder<> Builder(Preheader->getTerminator());
SCEVExpander Expander(*SE, *DL, "loop-idiom");
- SCEVExpanderCleaner ExpCleaner(Expander, *DT);
+ SCEVExpanderCleaner ExpCleaner(Expander, *DT);
Type *DestInt8PtrTy = Builder.getInt8PtrTy(DestAS);
Type *IntIdxTy = DL->getIndexType(DestPtr->getType());
- bool Changed = false;
+ bool Changed = false;
const SCEV *Start = Ev->getStart();
// Handle negative strided loops.
if (NegStride)
@@ -961,7 +961,7 @@ bool LoopIdiomRecognize::processLoopStridedStore(
// TODO: ideally we should still be able to generate memset if SCEV expander
// is taught to generate the dependencies at the latest point.
if (!isSafeToExpand(Start, *SE))
- return Changed;
+ return Changed;
// Okay, we have a strided store "p[i]" of a splattable value. We can turn
// this into a memset in the loop preheader now if we want. However, this
@@ -970,22 +970,22 @@ bool LoopIdiomRecognize::processLoopStridedStore(
// base pointer and checking the region.
Value *BasePtr =
Expander.expandCodeFor(Start, DestInt8PtrTy, Preheader->getTerminator());
-
- // From here on out, conservatively report to the pass manager that we've
- // changed the IR, even if we later clean up these added instructions. There
- // may be structural differences e.g. in the order of use lists not accounted
- // for in just a textual dump of the IR. This is written as a variable, even
- // though statically all the places this dominates could be replaced with
- // 'true', with the hope that anyone trying to be clever / "more precise" with
- // the return value will read this comment, and leave them alone.
- Changed = true;
-
+
+ // From here on out, conservatively report to the pass manager that we've
+ // changed the IR, even if we later clean up these added instructions. There
+ // may be structural differences e.g. in the order of use lists not accounted
+ // for in just a textual dump of the IR. This is written as a variable, even
+ // though statically all the places this dominates could be replaced with
+ // 'true', with the hope that anyone trying to be clever / "more precise" with
+ // the return value will read this comment, and leave them alone.
+ Changed = true;
+
if (mayLoopAccessLocation(BasePtr, ModRefInfo::ModRef, CurLoop, BECount,
- StoreSize, *AA, Stores))
- return Changed;
+ StoreSize, *AA, Stores))
+ return Changed;
if (avoidLIRForMultiBlockLoop(/*IsMemset=*/true, IsLoopMemset))
- return Changed;
+ return Changed;
// Okay, everything looks good, insert the memset.
@@ -995,7 +995,7 @@ bool LoopIdiomRecognize::processLoopStridedStore(
// TODO: ideally we should still be able to generate memset if SCEV expander
// is taught to generate the dependencies at the latest point.
if (!isSafeToExpand(NumBytesS, *SE))
- return Changed;
+ return Changed;
Value *NumBytes =
Expander.expandCodeFor(NumBytesS, IntIdxTy, Preheader->getTerminator());
@@ -1054,7 +1054,7 @@ bool LoopIdiomRecognize::processLoopStridedStore(
if (MSSAU && VerifyMemorySSA)
MSSAU->getMemorySSA()->verifyMemorySSA();
++NumMemSet;
- ExpCleaner.markResultUsed();
+ ExpCleaner.markResultUsed();
return true;
}
@@ -1088,9 +1088,9 @@ bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(StoreInst *SI,
IRBuilder<> Builder(Preheader->getTerminator());
SCEVExpander Expander(*SE, *DL, "loop-idiom");
- SCEVExpanderCleaner ExpCleaner(Expander, *DT);
+ SCEVExpanderCleaner ExpCleaner(Expander, *DT);
- bool Changed = false;
+ bool Changed = false;
const SCEV *StrStart = StoreEv->getStart();
unsigned StrAS = SI->getPointerAddressSpace();
Type *IntIdxTy = Builder.getIntNTy(DL->getIndexSizeInBits(StrAS));
@@ -1108,20 +1108,20 @@ bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(StoreInst *SI,
Value *StoreBasePtr = Expander.expandCodeFor(
StrStart, Builder.getInt8PtrTy(StrAS), Preheader->getTerminator());
- // From here on out, conservatively report to the pass manager that we've
- // changed the IR, even if we later clean up these added instructions. There
- // may be structural differences e.g. in the order of use lists not accounted
- // for in just a textual dump of the IR. This is written as a variable, even
- // though statically all the places this dominates could be replaced with
- // 'true', with the hope that anyone trying to be clever / "more precise" with
- // the return value will read this comment, and leave them alone.
- Changed = true;
-
+ // From here on out, conservatively report to the pass manager that we've
+ // changed the IR, even if we later clean up these added instructions. There
+ // may be structural differences e.g. in the order of use lists not accounted
+ // for in just a textual dump of the IR. This is written as a variable, even
+ // though statically all the places this dominates could be replaced with
+ // 'true', with the hope that anyone trying to be clever / "more precise" with
+ // the return value will read this comment, and leave them alone.
+ Changed = true;
+
SmallPtrSet<Instruction *, 1> Stores;
Stores.insert(SI);
if (mayLoopAccessLocation(StoreBasePtr, ModRefInfo::ModRef, CurLoop, BECount,
StoreSize, *AA, Stores))
- return Changed;
+ return Changed;
const SCEV *LdStart = LoadEv->getStart();
unsigned LdAS = LI->getPointerAddressSpace();
@@ -1137,10 +1137,10 @@ bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(StoreInst *SI,
if (mayLoopAccessLocation(LoadBasePtr, ModRefInfo::Mod, CurLoop, BECount,
StoreSize, *AA, Stores))
- return Changed;
+ return Changed;
if (avoidLIRForMultiBlockLoop())
- return Changed;
+ return Changed;
// Okay, everything is safe, we can transform this!
@@ -1163,14 +1163,14 @@ bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(StoreInst *SI,
const Align StoreAlign = SI->getAlign();
const Align LoadAlign = LI->getAlign();
if (StoreAlign < StoreSize || LoadAlign < StoreSize)
- return Changed;
+ return Changed;
// If the element.atomic memcpy is not lowered into explicit
// loads/stores later, then it will be lowered into an element-size
// specific lib call. If the lib call doesn't exist for our store size, then
// we shouldn't generate the memcpy.
if (StoreSize > TTI->getAtomicMemIntrinsicMaxElementSize())
- return Changed;
+ return Changed;
// Create the call.
// Note that unordered atomic loads/stores are *required* by the spec to
@@ -1208,7 +1208,7 @@ bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(StoreInst *SI,
if (MSSAU && VerifyMemorySSA)
MSSAU->getMemorySSA()->verifyMemorySSA();
++NumMemCpy;
- ExpCleaner.markResultUsed();
+ ExpCleaner.markResultUsed();
return true;
}
@@ -1218,7 +1218,7 @@ bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(StoreInst *SI,
bool LoopIdiomRecognize::avoidLIRForMultiBlockLoop(bool IsMemset,
bool IsLoopMemset) {
if (ApplyCodeSizeHeuristics && CurLoop->getNumBlocks() > 1) {
- if (CurLoop->isOutermost() && (!IsMemset || !IsLoopMemset)) {
+ if (CurLoop->isOutermost() && (!IsMemset || !IsLoopMemset)) {
LLVM_DEBUG(dbgs() << " " << CurLoop->getHeader()->getParent()->getName()
<< " : LIR " << (IsMemset ? "Memset" : "Memcpy")
<< " avoided: multi-block top-level loop\n");
@@ -1235,8 +1235,8 @@ bool LoopIdiomRecognize::runOnNoncountableLoop() {
<< "] Noncountable Loop %"
<< CurLoop->getHeader()->getName() << "\n");
- return recognizePopcount() || recognizeAndInsertFFS() ||
- recognizeShiftUntilBitTest();
+ return recognizePopcount() || recognizeAndInsertFFS() ||
+ recognizeShiftUntilBitTest();
}
/// Check if the given conditional branch is based on the comparison between
@@ -1483,7 +1483,7 @@ static bool detectShiftUntilZeroIdiom(Loop *CurLoop, const DataLayout &DL,
return false;
// step 4: Find the instruction which count the CTLZ: cnt.next = cnt + 1
- // or cnt.next = cnt + -1.
+ // or cnt.next = cnt + -1.
// TODO: We can skip the step. If loop trip count is known (CTLZ),
// then all uses of "cnt.next" could be optimized to the trip count
// plus "cnt0". Currently it is not optimized.
@@ -1497,7 +1497,7 @@ static bool detectShiftUntilZeroIdiom(Loop *CurLoop, const DataLayout &DL,
continue;
ConstantInt *Inc = dyn_cast<ConstantInt>(Inst->getOperand(1));
- if (!Inc || (!Inc->isOne() && !Inc->isMinusOne()))
+ if (!Inc || (!Inc->isOne() && !Inc->isMinusOne()))
continue;
PHINode *Phi = getRecurrenceVar(Inst->getOperand(0), Inst, LoopEntry);
@@ -1728,11 +1728,11 @@ void LoopIdiomRecognize::transformLoopToCountable(
Builder.SetCurrentDebugLocation(DL);
// Count = BitWidth - CTLZ(InitX);
- // NewCount = Count;
+ // NewCount = Count;
// If there are uses of CntPhi create:
- // NewCount = BitWidth - CTLZ(InitX >> 1);
- // Count = NewCount + 1;
- Value *InitXNext;
+ // NewCount = BitWidth - CTLZ(InitX >> 1);
+ // Count = NewCount + 1;
+ Value *InitXNext;
if (IsCntPhiUsedOutsideLoop) {
if (DefX->getOpcode() == Instruction::AShr)
InitXNext =
@@ -1747,31 +1747,31 @@ void LoopIdiomRecognize::transformLoopToCountable(
llvm_unreachable("Unexpected opcode!");
} else
InitXNext = InitX;
- Value *FFS = createFFSIntrinsic(Builder, InitXNext, DL, ZeroCheck, IntrinID);
- Value *Count = Builder.CreateSub(
- ConstantInt::get(FFS->getType(), FFS->getType()->getIntegerBitWidth()),
+ Value *FFS = createFFSIntrinsic(Builder, InitXNext, DL, ZeroCheck, IntrinID);
+ Value *Count = Builder.CreateSub(
+ ConstantInt::get(FFS->getType(), FFS->getType()->getIntegerBitWidth()),
FFS);
- Value *NewCount = Count;
+ Value *NewCount = Count;
if (IsCntPhiUsedOutsideLoop) {
- NewCount = Count;
- Count = Builder.CreateAdd(Count, ConstantInt::get(Count->getType(), 1));
+ NewCount = Count;
+ Count = Builder.CreateAdd(Count, ConstantInt::get(Count->getType(), 1));
}
- NewCount = Builder.CreateZExtOrTrunc(NewCount,
- cast<IntegerType>(CntInst->getType()));
+ NewCount = Builder.CreateZExtOrTrunc(NewCount,
+ cast<IntegerType>(CntInst->getType()));
Value *CntInitVal = CntPhi->getIncomingValueForBlock(Preheader);
- if (cast<ConstantInt>(CntInst->getOperand(1))->isOne()) {
- // If the counter was being incremented in the loop, add NewCount to the
- // counter's initial value, but only if the initial value is not zero.
- ConstantInt *InitConst = dyn_cast<ConstantInt>(CntInitVal);
- if (!InitConst || !InitConst->isZero())
- NewCount = Builder.CreateAdd(NewCount, CntInitVal);
- } else {
- // If the count was being decremented in the loop, subtract NewCount from
- // the counter's initial value.
- NewCount = Builder.CreateSub(CntInitVal, NewCount);
- }
+ if (cast<ConstantInt>(CntInst->getOperand(1))->isOne()) {
+ // If the counter was being incremented in the loop, add NewCount to the
+ // counter's initial value, but only if the initial value is not zero.
+ ConstantInt *InitConst = dyn_cast<ConstantInt>(CntInitVal);
+ if (!InitConst || !InitConst->isZero())
+ NewCount = Builder.CreateAdd(NewCount, CntInitVal);
+ } else {
+ // If the count was being decremented in the loop, subtract NewCount from
+ // the counter's initial value.
+ NewCount = Builder.CreateSub(CntInitVal, NewCount);
+ }
// Step 2: Insert new IV and loop condition:
// loop:
@@ -1919,343 +1919,343 @@ void LoopIdiomRecognize::transformLoopToPopcount(BasicBlock *PreCondBB,
// loop. The loop would otherwise not be deleted even if it becomes empty.
SE->forgetLoop(CurLoop);
}
-
-/// Match loop-invariant value.
-template <typename SubPattern_t> struct match_LoopInvariant {
- SubPattern_t SubPattern;
- const Loop *L;
-
- match_LoopInvariant(const SubPattern_t &SP, const Loop *L)
- : SubPattern(SP), L(L) {}
-
- template <typename ITy> bool match(ITy *V) {
- return L->isLoopInvariant(V) && SubPattern.match(V);
- }
-};
-
-/// Matches if the value is loop-invariant.
-template <typename Ty>
-inline match_LoopInvariant<Ty> m_LoopInvariant(const Ty &M, const Loop *L) {
- return match_LoopInvariant<Ty>(M, L);
-}
-
-/// Return true if the idiom is detected in the loop.
-///
-/// The core idiom we are trying to detect is:
-/// \code
-/// entry:
-/// <...>
-/// %bitmask = shl i32 1, %bitpos
-/// br label %loop
-///
-/// loop:
-/// %x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
-/// %x.curr.bitmasked = and i32 %x.curr, %bitmask
-/// %x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
-/// %x.next = shl i32 %x.curr, 1
-/// <...>
-/// br i1 %x.curr.isbitunset, label %loop, label %end
-///
-/// end:
-/// %x.curr.res = phi i32 [ %x.curr, %loop ] <...>
-/// %x.next.res = phi i32 [ %x.next, %loop ] <...>
-/// <...>
-/// \endcode
-static bool detectShiftUntilBitTestIdiom(Loop *CurLoop, Value *&BaseX,
- Value *&BitMask, Value *&BitPos,
- Value *&CurrX, Instruction *&NextX) {
- LLVM_DEBUG(dbgs() << DEBUG_TYPE
- " Performing shift-until-bittest idiom detection.\n");
-
- // Give up if the loop has multiple blocks or multiple backedges.
- if (CurLoop->getNumBlocks() != 1 || CurLoop->getNumBackEdges() != 1) {
- LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad block/backedge count.\n");
- return false;
- }
-
- BasicBlock *LoopHeaderBB = CurLoop->getHeader();
- BasicBlock *LoopPreheaderBB = CurLoop->getLoopPreheader();
- assert(LoopPreheaderBB && "There is always a loop preheader.");
-
- using namespace PatternMatch;
-
- // Step 1: Check if the loop backedge is in desirable form.
-
- ICmpInst::Predicate Pred;
- Value *CmpLHS, *CmpRHS;
- BasicBlock *TrueBB, *FalseBB;
- if (!match(LoopHeaderBB->getTerminator(),
- m_Br(m_ICmp(Pred, m_Value(CmpLHS), m_Value(CmpRHS)),
- m_BasicBlock(TrueBB), m_BasicBlock(FalseBB)))) {
- LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad backedge structure.\n");
- return false;
- }
-
- // Step 2: Check if the backedge's condition is in desirable form.
-
- auto MatchVariableBitMask = [&]() {
- return ICmpInst::isEquality(Pred) && match(CmpRHS, m_Zero()) &&
- match(CmpLHS,
- m_c_And(m_Value(CurrX),
- m_CombineAnd(
- m_Value(BitMask),
- m_LoopInvariant(m_Shl(m_One(), m_Value(BitPos)),
- CurLoop))));
- };
- auto MatchConstantBitMask = [&]() {
- return ICmpInst::isEquality(Pred) && match(CmpRHS, m_Zero()) &&
- match(CmpLHS, m_And(m_Value(CurrX),
- m_CombineAnd(m_Value(BitMask), m_Power2()))) &&
- (BitPos = ConstantExpr::getExactLogBase2(cast<Constant>(BitMask)));
- };
- auto MatchDecomposableConstantBitMask = [&]() {
- APInt Mask;
- return llvm::decomposeBitTestICmp(CmpLHS, CmpRHS, Pred, CurrX, Mask) &&
- ICmpInst::isEquality(Pred) && Mask.isPowerOf2() &&
- (BitMask = ConstantInt::get(CurrX->getType(), Mask)) &&
- (BitPos = ConstantInt::get(CurrX->getType(), Mask.logBase2()));
- };
-
- if (!MatchVariableBitMask() && !MatchConstantBitMask() &&
- !MatchDecomposableConstantBitMask()) {
- LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad backedge comparison.\n");
- return false;
- }
-
- // Step 3: Check if the recurrence is in desirable form.
- auto *CurrXPN = dyn_cast<PHINode>(CurrX);
- if (!CurrXPN || CurrXPN->getParent() != LoopHeaderBB) {
- LLVM_DEBUG(dbgs() << DEBUG_TYPE " Not an expected PHI node.\n");
- return false;
- }
-
- BaseX = CurrXPN->getIncomingValueForBlock(LoopPreheaderBB);
- NextX =
- dyn_cast<Instruction>(CurrXPN->getIncomingValueForBlock(LoopHeaderBB));
-
- if (!NextX || !match(NextX, m_Shl(m_Specific(CurrX), m_One()))) {
- // FIXME: support right-shift?
- LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad recurrence.\n");
- return false;
- }
-
- // Step 4: Check if the backedge's destinations are in desirable form.
-
- assert(ICmpInst::isEquality(Pred) &&
- "Should only get equality predicates here.");
-
- // cmp-br is commutative, so canonicalize to a single variant.
- if (Pred != ICmpInst::Predicate::ICMP_EQ) {
- Pred = ICmpInst::getInversePredicate(Pred);
- std::swap(TrueBB, FalseBB);
- }
-
- // We expect to exit loop when comparison yields false,
- // so when it yields true we should branch back to loop header.
- if (TrueBB != LoopHeaderBB) {
- LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad backedge flow.\n");
- return false;
- }
-
- // Okay, idiom checks out.
- return true;
-}
-
-/// Look for the following loop:
-/// \code
-/// entry:
-/// <...>
-/// %bitmask = shl i32 1, %bitpos
-/// br label %loop
-///
-/// loop:
-/// %x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
-/// %x.curr.bitmasked = and i32 %x.curr, %bitmask
-/// %x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
-/// %x.next = shl i32 %x.curr, 1
-/// <...>
-/// br i1 %x.curr.isbitunset, label %loop, label %end
-///
-/// end:
-/// %x.curr.res = phi i32 [ %x.curr, %loop ] <...>
-/// %x.next.res = phi i32 [ %x.next, %loop ] <...>
-/// <...>
-/// \endcode
-///
-/// And transform it into:
-/// \code
-/// entry:
-/// %bitmask = shl i32 1, %bitpos
-/// %lowbitmask = add i32 %bitmask, -1
-/// %mask = or i32 %lowbitmask, %bitmask
-/// %x.masked = and i32 %x, %mask
-/// %x.masked.numleadingzeros = call i32 @llvm.ctlz.i32(i32 %x.masked,
-/// i1 true)
-/// %x.masked.numactivebits = sub i32 32, %x.masked.numleadingzeros
-/// %x.masked.leadingonepos = add i32 %x.masked.numactivebits, -1
-/// %backedgetakencount = sub i32 %bitpos, %x.masked.leadingonepos
-/// %tripcount = add i32 %backedgetakencount, 1
-/// %x.curr = shl i32 %x, %backedgetakencount
-/// %x.next = shl i32 %x, %tripcount
-/// br label %loop
-///
-/// loop:
-/// %loop.iv = phi i32 [ 0, %entry ], [ %loop.iv.next, %loop ]
-/// %loop.iv.next = add nuw i32 %loop.iv, 1
-/// %loop.ivcheck = icmp eq i32 %loop.iv.next, %tripcount
-/// <...>
-/// br i1 %loop.ivcheck, label %end, label %loop
-///
-/// end:
-/// %x.curr.res = phi i32 [ %x.curr, %loop ] <...>
-/// %x.next.res = phi i32 [ %x.next, %loop ] <...>
-/// <...>
-/// \endcode
-bool LoopIdiomRecognize::recognizeShiftUntilBitTest() {
- bool MadeChange = false;
-
- Value *X, *BitMask, *BitPos, *XCurr;
- Instruction *XNext;
- if (!detectShiftUntilBitTestIdiom(CurLoop, X, BitMask, BitPos, XCurr,
- XNext)) {
- LLVM_DEBUG(dbgs() << DEBUG_TYPE
- " shift-until-bittest idiom detection failed.\n");
- return MadeChange;
- }
- LLVM_DEBUG(dbgs() << DEBUG_TYPE " shift-until-bittest idiom detected!\n");
-
- // Ok, it is the idiom we were looking for, we *could* transform this loop,
- // but is it profitable to transform?
-
- BasicBlock *LoopHeaderBB = CurLoop->getHeader();
- BasicBlock *LoopPreheaderBB = CurLoop->getLoopPreheader();
- assert(LoopPreheaderBB && "There is always a loop preheader.");
-
- BasicBlock *SuccessorBB = CurLoop->getExitBlock();
- assert(LoopPreheaderBB && "There is only a single successor.");
-
- IRBuilder<> Builder(LoopPreheaderBB->getTerminator());
- Builder.SetCurrentDebugLocation(cast<Instruction>(XCurr)->getDebugLoc());
-
- Intrinsic::ID IntrID = Intrinsic::ctlz;
- Type *Ty = X->getType();
-
- TargetTransformInfo::TargetCostKind CostKind =
- TargetTransformInfo::TCK_SizeAndLatency;
-
- // The rewrite is considered to be unprofitable iff and only iff the
- // intrinsic/shift we'll use are not cheap. Note that we are okay with *just*
- // making the loop countable, even if nothing else changes.
- IntrinsicCostAttributes Attrs(
- IntrID, Ty, {UndefValue::get(Ty), /*is_zero_undef=*/Builder.getTrue()});
- int Cost = TTI->getIntrinsicInstrCost(Attrs, CostKind);
- if (Cost > TargetTransformInfo::TCC_Basic) {
- LLVM_DEBUG(dbgs() << DEBUG_TYPE
- " Intrinsic is too costly, not beneficial\n");
- return MadeChange;
- }
- if (TTI->getArithmeticInstrCost(Instruction::Shl, Ty, CostKind) >
- TargetTransformInfo::TCC_Basic) {
- LLVM_DEBUG(dbgs() << DEBUG_TYPE " Shift is too costly, not beneficial\n");
- return MadeChange;
- }
-
- // Ok, transform appears worthwhile.
- MadeChange = true;
-
- // Step 1: Compute the loop trip count.
-
- Value *LowBitMask = Builder.CreateAdd(BitMask, Constant::getAllOnesValue(Ty),
- BitPos->getName() + ".lowbitmask");
- Value *Mask =
- Builder.CreateOr(LowBitMask, BitMask, BitPos->getName() + ".mask");
- Value *XMasked = Builder.CreateAnd(X, Mask, X->getName() + ".masked");
- CallInst *XMaskedNumLeadingZeros = Builder.CreateIntrinsic(
- IntrID, Ty, {XMasked, /*is_zero_undef=*/Builder.getTrue()},
- /*FMFSource=*/nullptr, XMasked->getName() + ".numleadingzeros");
- Value *XMaskedNumActiveBits = Builder.CreateSub(
- ConstantInt::get(Ty, Ty->getScalarSizeInBits()), XMaskedNumLeadingZeros,
- XMasked->getName() + ".numactivebits");
- Value *XMaskedLeadingOnePos =
- Builder.CreateAdd(XMaskedNumActiveBits, Constant::getAllOnesValue(Ty),
- XMasked->getName() + ".leadingonepos");
-
- Value *LoopBackedgeTakenCount = Builder.CreateSub(
- BitPos, XMaskedLeadingOnePos, CurLoop->getName() + ".backedgetakencount");
- // We know loop's backedge-taken count, but what's loop's trip count?
- // Note that while NUW is always safe, while NSW is only for bitwidths != 2.
- Value *LoopTripCount =
- Builder.CreateNUWAdd(LoopBackedgeTakenCount, ConstantInt::get(Ty, 1),
- CurLoop->getName() + ".tripcount");
-
- // Step 2: Compute the recurrence's final value without a loop.
-
- // NewX is always safe to compute, because `LoopBackedgeTakenCount`
- // will always be smaller than `bitwidth(X)`, i.e. we never get poison.
- Value *NewX = Builder.CreateShl(X, LoopBackedgeTakenCount);
- NewX->takeName(XCurr);
- if (auto *I = dyn_cast<Instruction>(NewX))
- I->copyIRFlags(XNext, /*IncludeWrapFlags=*/true);
-
- Value *NewXNext;
- // Rewriting XNext is more complicated, however, because `X << LoopTripCount`
- // will be poison iff `LoopTripCount == bitwidth(X)` (which will happen
- // iff `BitPos` is `bitwidth(x) - 1` and `X` is `1`). So unless we know
- // that isn't the case, we'll need to emit an alternative, safe IR.
- if (XNext->hasNoSignedWrap() || XNext->hasNoUnsignedWrap() ||
- PatternMatch::match(
- BitPos, PatternMatch::m_SpecificInt_ICMP(
- ICmpInst::ICMP_NE, APInt(Ty->getScalarSizeInBits(),
- Ty->getScalarSizeInBits() - 1))))
- NewXNext = Builder.CreateShl(X, LoopTripCount);
- else {
- // Otherwise, just additionally shift by one. It's the smallest solution,
- // alternatively, we could check that NewX is INT_MIN (or BitPos is )
- // and select 0 instead.
- NewXNext = Builder.CreateShl(NewX, ConstantInt::get(Ty, 1));
- }
-
- NewXNext->takeName(XNext);
- if (auto *I = dyn_cast<Instruction>(NewXNext))
- I->copyIRFlags(XNext, /*IncludeWrapFlags=*/true);
-
- // Step 3: Adjust the successor basic block to recieve the computed
- // recurrence's final value instead of the recurrence itself.
-
- XCurr->replaceUsesOutsideBlock(NewX, LoopHeaderBB);
- XNext->replaceUsesOutsideBlock(NewXNext, LoopHeaderBB);
-
- // Step 4: Rewrite the loop into a countable form, with canonical IV.
-
- // The new canonical induction variable.
- Builder.SetInsertPoint(&LoopHeaderBB->front());
- auto *IV = Builder.CreatePHI(Ty, 2, CurLoop->getName() + ".iv");
-
- // The induction itself.
- // Note that while NUW is always safe, while NSW is only for bitwidths != 2.
- Builder.SetInsertPoint(LoopHeaderBB->getTerminator());
- auto *IVNext = Builder.CreateNUWAdd(IV, ConstantInt::get(Ty, 1),
- IV->getName() + ".next");
-
- // The loop trip count check.
- auto *IVCheck = Builder.CreateICmpEQ(IVNext, LoopTripCount,
- CurLoop->getName() + ".ivcheck");
- Builder.CreateCondBr(IVCheck, SuccessorBB, LoopHeaderBB);
- LoopHeaderBB->getTerminator()->eraseFromParent();
-
- // Populate the IV PHI.
- IV->addIncoming(ConstantInt::get(Ty, 0), LoopPreheaderBB);
- IV->addIncoming(IVNext, LoopHeaderBB);
-
- // Step 5: Forget the "non-computable" trip-count SCEV associated with the
- // loop. The loop would otherwise not be deleted even if it becomes empty.
-
- SE->forgetLoop(CurLoop);
-
- // Other passes will take care of actually deleting the loop if possible.
-
- LLVM_DEBUG(dbgs() << DEBUG_TYPE " shift-until-bittest idiom optimized!\n");
-
- ++NumShiftUntilBitTest;
- return MadeChange;
-}
+
+/// Match loop-invariant value.
+template <typename SubPattern_t> struct match_LoopInvariant {
+ SubPattern_t SubPattern;
+ const Loop *L;
+
+ match_LoopInvariant(const SubPattern_t &SP, const Loop *L)
+ : SubPattern(SP), L(L) {}
+
+ template <typename ITy> bool match(ITy *V) {
+ return L->isLoopInvariant(V) && SubPattern.match(V);
+ }
+};
+
+/// Matches if the value is loop-invariant.
+template <typename Ty>
+inline match_LoopInvariant<Ty> m_LoopInvariant(const Ty &M, const Loop *L) {
+ return match_LoopInvariant<Ty>(M, L);
+}
+
+/// Return true if the idiom is detected in the loop.
+///
+/// The core idiom we are trying to detect is:
+/// \code
+/// entry:
+/// <...>
+/// %bitmask = shl i32 1, %bitpos
+/// br label %loop
+///
+/// loop:
+/// %x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
+/// %x.curr.bitmasked = and i32 %x.curr, %bitmask
+/// %x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
+/// %x.next = shl i32 %x.curr, 1
+/// <...>
+/// br i1 %x.curr.isbitunset, label %loop, label %end
+///
+/// end:
+/// %x.curr.res = phi i32 [ %x.curr, %loop ] <...>
+/// %x.next.res = phi i32 [ %x.next, %loop ] <...>
+/// <...>
+/// \endcode
+static bool detectShiftUntilBitTestIdiom(Loop *CurLoop, Value *&BaseX,
+ Value *&BitMask, Value *&BitPos,
+ Value *&CurrX, Instruction *&NextX) {
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE
+ " Performing shift-until-bittest idiom detection.\n");
+
+ // Give up if the loop has multiple blocks or multiple backedges.
+ if (CurLoop->getNumBlocks() != 1 || CurLoop->getNumBackEdges() != 1) {
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad block/backedge count.\n");
+ return false;
+ }
+
+ BasicBlock *LoopHeaderBB = CurLoop->getHeader();
+ BasicBlock *LoopPreheaderBB = CurLoop->getLoopPreheader();
+ assert(LoopPreheaderBB && "There is always a loop preheader.");
+
+ using namespace PatternMatch;
+
+ // Step 1: Check if the loop backedge is in desirable form.
+
+ ICmpInst::Predicate Pred;
+ Value *CmpLHS, *CmpRHS;
+ BasicBlock *TrueBB, *FalseBB;
+ if (!match(LoopHeaderBB->getTerminator(),
+ m_Br(m_ICmp(Pred, m_Value(CmpLHS), m_Value(CmpRHS)),
+ m_BasicBlock(TrueBB), m_BasicBlock(FalseBB)))) {
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad backedge structure.\n");
+ return false;
+ }
+
+ // Step 2: Check if the backedge's condition is in desirable form.
+
+ auto MatchVariableBitMask = [&]() {
+ return ICmpInst::isEquality(Pred) && match(CmpRHS, m_Zero()) &&
+ match(CmpLHS,
+ m_c_And(m_Value(CurrX),
+ m_CombineAnd(
+ m_Value(BitMask),
+ m_LoopInvariant(m_Shl(m_One(), m_Value(BitPos)),
+ CurLoop))));
+ };
+ auto MatchConstantBitMask = [&]() {
+ return ICmpInst::isEquality(Pred) && match(CmpRHS, m_Zero()) &&
+ match(CmpLHS, m_And(m_Value(CurrX),
+ m_CombineAnd(m_Value(BitMask), m_Power2()))) &&
+ (BitPos = ConstantExpr::getExactLogBase2(cast<Constant>(BitMask)));
+ };
+ auto MatchDecomposableConstantBitMask = [&]() {
+ APInt Mask;
+ return llvm::decomposeBitTestICmp(CmpLHS, CmpRHS, Pred, CurrX, Mask) &&
+ ICmpInst::isEquality(Pred) && Mask.isPowerOf2() &&
+ (BitMask = ConstantInt::get(CurrX->getType(), Mask)) &&
+ (BitPos = ConstantInt::get(CurrX->getType(), Mask.logBase2()));
+ };
+
+ if (!MatchVariableBitMask() && !MatchConstantBitMask() &&
+ !MatchDecomposableConstantBitMask()) {
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad backedge comparison.\n");
+ return false;
+ }
+
+ // Step 3: Check if the recurrence is in desirable form.
+ auto *CurrXPN = dyn_cast<PHINode>(CurrX);
+ if (!CurrXPN || CurrXPN->getParent() != LoopHeaderBB) {
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE " Not an expected PHI node.\n");
+ return false;
+ }
+
+ BaseX = CurrXPN->getIncomingValueForBlock(LoopPreheaderBB);
+ NextX =
+ dyn_cast<Instruction>(CurrXPN->getIncomingValueForBlock(LoopHeaderBB));
+
+ if (!NextX || !match(NextX, m_Shl(m_Specific(CurrX), m_One()))) {
+ // FIXME: support right-shift?
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad recurrence.\n");
+ return false;
+ }
+
+ // Step 4: Check if the backedge's destinations are in desirable form.
+
+ assert(ICmpInst::isEquality(Pred) &&
+ "Should only get equality predicates here.");
+
+ // cmp-br is commutative, so canonicalize to a single variant.
+ if (Pred != ICmpInst::Predicate::ICMP_EQ) {
+ Pred = ICmpInst::getInversePredicate(Pred);
+ std::swap(TrueBB, FalseBB);
+ }
+
+ // We expect to exit loop when comparison yields false,
+ // so when it yields true we should branch back to loop header.
+ if (TrueBB != LoopHeaderBB) {
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad backedge flow.\n");
+ return false;
+ }
+
+ // Okay, idiom checks out.
+ return true;
+}
+
+/// Look for the following loop:
+/// \code
+/// entry:
+/// <...>
+/// %bitmask = shl i32 1, %bitpos
+/// br label %loop
+///
+/// loop:
+/// %x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
+/// %x.curr.bitmasked = and i32 %x.curr, %bitmask
+/// %x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
+/// %x.next = shl i32 %x.curr, 1
+/// <...>
+/// br i1 %x.curr.isbitunset, label %loop, label %end
+///
+/// end:
+/// %x.curr.res = phi i32 [ %x.curr, %loop ] <...>
+/// %x.next.res = phi i32 [ %x.next, %loop ] <...>
+/// <...>
+/// \endcode
+///
+/// And transform it into:
+/// \code
+/// entry:
+/// %bitmask = shl i32 1, %bitpos
+/// %lowbitmask = add i32 %bitmask, -1
+/// %mask = or i32 %lowbitmask, %bitmask
+/// %x.masked = and i32 %x, %mask
+/// %x.masked.numleadingzeros = call i32 @llvm.ctlz.i32(i32 %x.masked,
+/// i1 true)
+/// %x.masked.numactivebits = sub i32 32, %x.masked.numleadingzeros
+/// %x.masked.leadingonepos = add i32 %x.masked.numactivebits, -1
+/// %backedgetakencount = sub i32 %bitpos, %x.masked.leadingonepos
+/// %tripcount = add i32 %backedgetakencount, 1
+/// %x.curr = shl i32 %x, %backedgetakencount
+/// %x.next = shl i32 %x, %tripcount
+/// br label %loop
+///
+/// loop:
+/// %loop.iv = phi i32 [ 0, %entry ], [ %loop.iv.next, %loop ]
+/// %loop.iv.next = add nuw i32 %loop.iv, 1
+/// %loop.ivcheck = icmp eq i32 %loop.iv.next, %tripcount
+/// <...>
+/// br i1 %loop.ivcheck, label %end, label %loop
+///
+/// end:
+/// %x.curr.res = phi i32 [ %x.curr, %loop ] <...>
+/// %x.next.res = phi i32 [ %x.next, %loop ] <...>
+/// <...>
+/// \endcode
+bool LoopIdiomRecognize::recognizeShiftUntilBitTest() {
+ bool MadeChange = false;
+
+ Value *X, *BitMask, *BitPos, *XCurr;
+ Instruction *XNext;
+ if (!detectShiftUntilBitTestIdiom(CurLoop, X, BitMask, BitPos, XCurr,
+ XNext)) {
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE
+ " shift-until-bittest idiom detection failed.\n");
+ return MadeChange;
+ }
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE " shift-until-bittest idiom detected!\n");
+
+ // Ok, it is the idiom we were looking for, we *could* transform this loop,
+ // but is it profitable to transform?
+
+ BasicBlock *LoopHeaderBB = CurLoop->getHeader();
+ BasicBlock *LoopPreheaderBB = CurLoop->getLoopPreheader();
+ assert(LoopPreheaderBB && "There is always a loop preheader.");
+
+ BasicBlock *SuccessorBB = CurLoop->getExitBlock();
+ assert(LoopPreheaderBB && "There is only a single successor.");
+
+ IRBuilder<> Builder(LoopPreheaderBB->getTerminator());
+ Builder.SetCurrentDebugLocation(cast<Instruction>(XCurr)->getDebugLoc());
+
+ Intrinsic::ID IntrID = Intrinsic::ctlz;
+ Type *Ty = X->getType();
+
+ TargetTransformInfo::TargetCostKind CostKind =
+ TargetTransformInfo::TCK_SizeAndLatency;
+
+ // The rewrite is considered to be unprofitable iff and only iff the
+ // intrinsic/shift we'll use are not cheap. Note that we are okay with *just*
+ // making the loop countable, even if nothing else changes.
+ IntrinsicCostAttributes Attrs(
+ IntrID, Ty, {UndefValue::get(Ty), /*is_zero_undef=*/Builder.getTrue()});
+ int Cost = TTI->getIntrinsicInstrCost(Attrs, CostKind);
+ if (Cost > TargetTransformInfo::TCC_Basic) {
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE
+ " Intrinsic is too costly, not beneficial\n");
+ return MadeChange;
+ }
+ if (TTI->getArithmeticInstrCost(Instruction::Shl, Ty, CostKind) >
+ TargetTransformInfo::TCC_Basic) {
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE " Shift is too costly, not beneficial\n");
+ return MadeChange;
+ }
+
+ // Ok, transform appears worthwhile.
+ MadeChange = true;
+
+ // Step 1: Compute the loop trip count.
+
+ Value *LowBitMask = Builder.CreateAdd(BitMask, Constant::getAllOnesValue(Ty),
+ BitPos->getName() + ".lowbitmask");
+ Value *Mask =
+ Builder.CreateOr(LowBitMask, BitMask, BitPos->getName() + ".mask");
+ Value *XMasked = Builder.CreateAnd(X, Mask, X->getName() + ".masked");
+ CallInst *XMaskedNumLeadingZeros = Builder.CreateIntrinsic(
+ IntrID, Ty, {XMasked, /*is_zero_undef=*/Builder.getTrue()},
+ /*FMFSource=*/nullptr, XMasked->getName() + ".numleadingzeros");
+ Value *XMaskedNumActiveBits = Builder.CreateSub(
+ ConstantInt::get(Ty, Ty->getScalarSizeInBits()), XMaskedNumLeadingZeros,
+ XMasked->getName() + ".numactivebits");
+ Value *XMaskedLeadingOnePos =
+ Builder.CreateAdd(XMaskedNumActiveBits, Constant::getAllOnesValue(Ty),
+ XMasked->getName() + ".leadingonepos");
+
+ Value *LoopBackedgeTakenCount = Builder.CreateSub(
+ BitPos, XMaskedLeadingOnePos, CurLoop->getName() + ".backedgetakencount");
+ // We know loop's backedge-taken count, but what's loop's trip count?
+ // Note that while NUW is always safe, while NSW is only for bitwidths != 2.
+ Value *LoopTripCount =
+ Builder.CreateNUWAdd(LoopBackedgeTakenCount, ConstantInt::get(Ty, 1),
+ CurLoop->getName() + ".tripcount");
+
+ // Step 2: Compute the recurrence's final value without a loop.
+
+ // NewX is always safe to compute, because `LoopBackedgeTakenCount`
+ // will always be smaller than `bitwidth(X)`, i.e. we never get poison.
+ Value *NewX = Builder.CreateShl(X, LoopBackedgeTakenCount);
+ NewX->takeName(XCurr);
+ if (auto *I = dyn_cast<Instruction>(NewX))
+ I->copyIRFlags(XNext, /*IncludeWrapFlags=*/true);
+
+ Value *NewXNext;
+ // Rewriting XNext is more complicated, however, because `X << LoopTripCount`
+ // will be poison iff `LoopTripCount == bitwidth(X)` (which will happen
+ // iff `BitPos` is `bitwidth(x) - 1` and `X` is `1`). So unless we know
+ // that isn't the case, we'll need to emit an alternative, safe IR.
+ if (XNext->hasNoSignedWrap() || XNext->hasNoUnsignedWrap() ||
+ PatternMatch::match(
+ BitPos, PatternMatch::m_SpecificInt_ICMP(
+ ICmpInst::ICMP_NE, APInt(Ty->getScalarSizeInBits(),
+ Ty->getScalarSizeInBits() - 1))))
+ NewXNext = Builder.CreateShl(X, LoopTripCount);
+ else {
+ // Otherwise, just additionally shift by one. It's the smallest solution,
+ // alternatively, we could check that NewX is INT_MIN (or BitPos is )
+ // and select 0 instead.
+ NewXNext = Builder.CreateShl(NewX, ConstantInt::get(Ty, 1));
+ }
+
+ NewXNext->takeName(XNext);
+ if (auto *I = dyn_cast<Instruction>(NewXNext))
+ I->copyIRFlags(XNext, /*IncludeWrapFlags=*/true);
+
+ // Step 3: Adjust the successor basic block to recieve the computed
+ // recurrence's final value instead of the recurrence itself.
+
+ XCurr->replaceUsesOutsideBlock(NewX, LoopHeaderBB);
+ XNext->replaceUsesOutsideBlock(NewXNext, LoopHeaderBB);
+
+ // Step 4: Rewrite the loop into a countable form, with canonical IV.
+
+ // The new canonical induction variable.
+ Builder.SetInsertPoint(&LoopHeaderBB->front());
+ auto *IV = Builder.CreatePHI(Ty, 2, CurLoop->getName() + ".iv");
+
+ // The induction itself.
+ // Note that while NUW is always safe, while NSW is only for bitwidths != 2.
+ Builder.SetInsertPoint(LoopHeaderBB->getTerminator());
+ auto *IVNext = Builder.CreateNUWAdd(IV, ConstantInt::get(Ty, 1),
+ IV->getName() + ".next");
+
+ // The loop trip count check.
+ auto *IVCheck = Builder.CreateICmpEQ(IVNext, LoopTripCount,
+ CurLoop->getName() + ".ivcheck");
+ Builder.CreateCondBr(IVCheck, SuccessorBB, LoopHeaderBB);
+ LoopHeaderBB->getTerminator()->eraseFromParent();
+
+ // Populate the IV PHI.
+ IV->addIncoming(ConstantInt::get(Ty, 0), LoopPreheaderBB);
+ IV->addIncoming(IVNext, LoopHeaderBB);
+
+ // Step 5: Forget the "non-computable" trip-count SCEV associated with the
+ // loop. The loop would otherwise not be deleted even if it becomes empty.
+
+ SE->forgetLoop(CurLoop);
+
+ // Other passes will take care of actually deleting the loop if possible.
+
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE " shift-until-bittest idiom optimized!\n");
+
+ ++NumShiftUntilBitTest;
+ return MadeChange;
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopInterchange.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopInterchange.cpp
index 4f8809275f..d9dbc0deb4 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopInterchange.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -12,7 +12,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/Scalar/LoopInterchange.h"
+#include "llvm/Transforms/Scalar/LoopInterchange.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
@@ -28,7 +28,7 @@
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
-#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
@@ -429,7 +429,7 @@ private:
const LoopInterchangeLegality &LIL;
};
-struct LoopInterchange {
+struct LoopInterchange {
ScalarEvolution *SE = nullptr;
LoopInfo *LI = nullptr;
DependenceInfo *DI = nullptr;
@@ -438,12 +438,12 @@ struct LoopInterchange {
/// Interface to emit optimization remarks.
OptimizationRemarkEmitter *ORE;
- LoopInterchange(ScalarEvolution *SE, LoopInfo *LI, DependenceInfo *DI,
- DominatorTree *DT, OptimizationRemarkEmitter *ORE)
- : SE(SE), LI(LI), DI(DI), DT(DT), ORE(ORE) {}
+ LoopInterchange(ScalarEvolution *SE, LoopInfo *LI, DependenceInfo *DI,
+ DominatorTree *DT, OptimizationRemarkEmitter *ORE)
+ : SE(SE), LI(LI), DI(DI), DT(DT), ORE(ORE) {}
- bool run(Loop *L) {
- if (L->getParentLoop())
+ bool run(Loop *L) {
+ if (L->getParentLoop())
return false;
return processLoopList(populateWorklist(*L));
@@ -452,7 +452,7 @@ struct LoopInterchange {
bool isComputableLoopNest(LoopVector LoopList) {
for (Loop *L : LoopList) {
const SCEV *ExitCountOuter = SE->getBackedgeTakenCount(L);
- if (isa<SCEVCouldNotCompute>(ExitCountOuter)) {
+ if (isa<SCEVCouldNotCompute>(ExitCountOuter)) {
LLVM_DEBUG(dbgs() << "Couldn't compute backedge count\n");
return false;
}
@@ -611,13 +611,13 @@ bool LoopInterchangeLegality::tightlyNested(Loop *OuterLoop, Loop *InnerLoop) {
containsUnsafeInstructions(OuterLoopLatch))
return false;
- // Also make sure the inner loop preheader does not contain any unsafe
- // instructions. Note that all instructions in the preheader will be moved to
- // the outer loop header when interchanging.
- if (InnerLoopPreHeader != OuterLoopHeader &&
- containsUnsafeInstructions(InnerLoopPreHeader))
- return false;
-
+ // Also make sure the inner loop preheader does not contain any unsafe
+ // instructions. Note that all instructions in the preheader will be moved to
+ // the outer loop header when interchanging.
+ if (InnerLoopPreHeader != OuterLoopHeader &&
+ containsUnsafeInstructions(InnerLoopPreHeader))
+ return false;
+
LLVM_DEBUG(dbgs() << "Loops are perfectly nested\n");
// We have a perfect loop nest.
return true;
@@ -661,10 +661,10 @@ static Value *followLCSSA(Value *SV) {
// Check V's users to see if it is involved in a reduction in L.
static PHINode *findInnerReductionPhi(Loop *L, Value *V) {
- // Reduction variables cannot be constants.
- if (isa<Constant>(V))
- return nullptr;
-
+ // Reduction variables cannot be constants.
+ if (isa<Constant>(V))
+ return nullptr;
+
for (Value *User : V->users()) {
if (PHINode *PHI = dyn_cast<PHINode>(User)) {
if (PHI->getNumIncomingValues() == 1)
@@ -705,7 +705,7 @@ bool LoopInterchangeLegality::findInductionAndReductions(
Value *V = followLCSSA(PHI.getIncomingValueForBlock(L->getLoopLatch()));
PHINode *InnerRedPhi = findInnerReductionPhi(InnerLoop, V);
if (!InnerRedPhi ||
- !llvm::is_contained(InnerRedPhi->incoming_values(), &PHI)) {
+ !llvm::is_contained(InnerRedPhi->incoming_values(), &PHI)) {
LLVM_DEBUG(
dbgs()
<< "Failed to recognize PHI as an induction or reduction.\n");
@@ -1042,10 +1042,10 @@ int LoopInterchangeProfitability::getInstrOrderCost() {
bool FoundInnerInduction = false;
bool FoundOuterInduction = false;
for (unsigned i = 0; i < NumOp; ++i) {
- // Skip operands that are not SCEV-able.
- if (!SE->isSCEVable(GEP->getOperand(i)->getType()))
- continue;
-
+ // Skip operands that are not SCEV-able.
+ if (!SE->isSCEVable(GEP->getOperand(i)->getType()))
+ continue;
+
const SCEV *OperandVal = SE->getSCEV(GEP->getOperand(i));
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(OperandVal);
if (!AR)
@@ -1190,7 +1190,7 @@ void LoopInterchangeTransform::restructureLoops(
removeChildLoop(NewInner, NewOuter);
LI->changeTopLevelLoop(NewInner, NewOuter);
}
- while (!NewOuter->isInnermost())
+ while (!NewOuter->isInnermost())
NewInner->addChildLoop(NewOuter->removeChildLoop(NewOuter->begin()));
NewOuter->addChildLoop(NewInner);
@@ -1306,21 +1306,21 @@ bool LoopInterchangeTransform::transform() {
LLVM_DEBUG(dbgs() << "splitting InnerLoopHeader done\n");
}
- // Instructions in the original inner loop preheader may depend on values
- // defined in the outer loop header. Move them there, because the original
- // inner loop preheader will become the entry into the interchanged loop nest.
- // Currently we move all instructions and rely on LICM to move invariant
- // instructions outside the loop nest.
- BasicBlock *InnerLoopPreHeader = InnerLoop->getLoopPreheader();
- BasicBlock *OuterLoopHeader = OuterLoop->getHeader();
- if (InnerLoopPreHeader != OuterLoopHeader) {
- SmallPtrSet<Instruction *, 4> NeedsMoving;
- for (Instruction &I :
- make_early_inc_range(make_range(InnerLoopPreHeader->begin(),
- std::prev(InnerLoopPreHeader->end()))))
- I.moveBefore(OuterLoopHeader->getTerminator());
- }
-
+ // Instructions in the original inner loop preheader may depend on values
+ // defined in the outer loop header. Move them there, because the original
+ // inner loop preheader will become the entry into the interchanged loop nest.
+ // Currently we move all instructions and rely on LICM to move invariant
+ // instructions outside the loop nest.
+ BasicBlock *InnerLoopPreHeader = InnerLoop->getLoopPreheader();
+ BasicBlock *OuterLoopHeader = OuterLoop->getHeader();
+ if (InnerLoopPreHeader != OuterLoopHeader) {
+ SmallPtrSet<Instruction *, 4> NeedsMoving;
+ for (Instruction &I :
+ make_early_inc_range(make_range(InnerLoopPreHeader->begin(),
+ std::prev(InnerLoopPreHeader->end()))))
+ I.moveBefore(OuterLoopHeader->getTerminator());
+ }
+
Transformed |= adjustLoopLinks();
if (!Transformed) {
LLVM_DEBUG(dbgs() << "adjustLoopLinks failed\n");
@@ -1537,7 +1537,7 @@ bool LoopInterchangeTransform::adjustLoopBranches() {
InnerLoopPreHeader, DTUpdates, /*MustUpdateOnce=*/false);
// The outer loop header might or might not branch to the outer latch.
// We are guaranteed to branch to the inner loop preheader.
- if (llvm::is_contained(OuterLoopHeaderBI->successors(), OuterLoopLatch))
+ if (llvm::is_contained(OuterLoopHeaderBI->successors(), OuterLoopLatch))
updateSuccessor(OuterLoopHeaderBI, OuterLoopLatch, LoopExit, DTUpdates,
/*MustUpdateOnce=*/false);
updateSuccessor(OuterLoopHeaderBI, InnerLoopPreHeader,
@@ -1584,9 +1584,9 @@ bool LoopInterchangeTransform::adjustLoopBranches() {
// Now update the reduction PHIs in the inner and outer loop headers.
SmallVector<PHINode *, 4> InnerLoopPHIs, OuterLoopPHIs;
- for (PHINode &PHI : drop_begin(InnerLoopHeader->phis()))
+ for (PHINode &PHI : drop_begin(InnerLoopHeader->phis()))
InnerLoopPHIs.push_back(cast<PHINode>(&PHI));
- for (PHINode &PHI : drop_begin(OuterLoopHeader->phis()))
+ for (PHINode &PHI : drop_begin(OuterLoopHeader->phis()))
OuterLoopPHIs.push_back(cast<PHINode>(&PHI));
auto &OuterInnerReductions = LIL.getOuterInnerReductions();
@@ -1610,17 +1610,17 @@ bool LoopInterchangeTransform::adjustLoopBranches() {
InnerLoopHeader->replacePhiUsesWith(OuterLoopPreHeader, InnerLoopPreHeader);
InnerLoopHeader->replacePhiUsesWith(OuterLoopLatch, InnerLoopLatch);
- // Values defined in the outer loop header could be used in the inner loop
- // latch. In that case, we need to create LCSSA phis for them, because after
- // interchanging they will be defined in the new inner loop and used in the
- // new outer loop.
- IRBuilder<> Builder(OuterLoopHeader->getContext());
- SmallVector<Instruction *, 4> MayNeedLCSSAPhis;
- for (Instruction &I :
- make_range(OuterLoopHeader->begin(), std::prev(OuterLoopHeader->end())))
- MayNeedLCSSAPhis.push_back(&I);
- formLCSSAForInstructions(MayNeedLCSSAPhis, *DT, *LI, SE, Builder);
-
+ // Values defined in the outer loop header could be used in the inner loop
+ // latch. In that case, we need to create LCSSA phis for them, because after
+ // interchanging they will be defined in the new inner loop and used in the
+ // new outer loop.
+ IRBuilder<> Builder(OuterLoopHeader->getContext());
+ SmallVector<Instruction *, 4> MayNeedLCSSAPhis;
+ for (Instruction &I :
+ make_range(OuterLoopHeader->begin(), std::prev(OuterLoopHeader->end())))
+ MayNeedLCSSAPhis.push_back(&I);
+ formLCSSAForInstructions(MayNeedLCSSAPhis, *DT, *LI, SE, Builder);
+
return true;
}
@@ -1638,58 +1638,58 @@ bool LoopInterchangeTransform::adjustLoopLinks() {
return Changed;
}
-/// Main LoopInterchange Pass.
-struct LoopInterchangeLegacyPass : public LoopPass {
- static char ID;
-
- LoopInterchangeLegacyPass() : LoopPass(ID) {
- initializeLoopInterchangeLegacyPassPass(*PassRegistry::getPassRegistry());
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<DependenceAnalysisWrapperPass>();
- AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
-
- getLoopAnalysisUsage(AU);
- }
-
- bool runOnLoop(Loop *L, LPPassManager &LPM) override {
- if (skipLoop(L))
- return false;
-
- auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
- auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- auto *DI = &getAnalysis<DependenceAnalysisWrapperPass>().getDI();
- auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- auto *ORE = &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
-
- return LoopInterchange(SE, LI, DI, DT, ORE).run(L);
- }
-};
-
-char LoopInterchangeLegacyPass::ID = 0;
-
-INITIALIZE_PASS_BEGIN(LoopInterchangeLegacyPass, "loop-interchange",
+/// Main LoopInterchange Pass.
+struct LoopInterchangeLegacyPass : public LoopPass {
+ static char ID;
+
+ LoopInterchangeLegacyPass() : LoopPass(ID) {
+ initializeLoopInterchangeLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<DependenceAnalysisWrapperPass>();
+ AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
+
+ getLoopAnalysisUsage(AU);
+ }
+
+ bool runOnLoop(Loop *L, LPPassManager &LPM) override {
+ if (skipLoop(L))
+ return false;
+
+ auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
+ auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
+ auto *DI = &getAnalysis<DependenceAnalysisWrapperPass>().getDI();
+ auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ auto *ORE = &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
+
+ return LoopInterchange(SE, LI, DI, DT, ORE).run(L);
+ }
+};
+
+char LoopInterchangeLegacyPass::ID = 0;
+
+INITIALIZE_PASS_BEGIN(LoopInterchangeLegacyPass, "loop-interchange",
"Interchanges loops for cache reuse", false, false)
INITIALIZE_PASS_DEPENDENCY(LoopPass)
INITIALIZE_PASS_DEPENDENCY(DependenceAnalysisWrapperPass)
INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
-INITIALIZE_PASS_END(LoopInterchangeLegacyPass, "loop-interchange",
+INITIALIZE_PASS_END(LoopInterchangeLegacyPass, "loop-interchange",
"Interchanges loops for cache reuse", false, false)
-Pass *llvm::createLoopInterchangePass() {
- return new LoopInterchangeLegacyPass();
-}
-
-PreservedAnalyses LoopInterchangePass::run(Loop &L, LoopAnalysisManager &AM,
- LoopStandardAnalysisResults &AR,
- LPMUpdater &U) {
- Function &F = *L.getHeader()->getParent();
-
- DependenceInfo DI(&F, &AR.AA, &AR.SE, &AR.LI);
- OptimizationRemarkEmitter ORE(&F);
- if (!LoopInterchange(&AR.SE, &AR.LI, &DI, &AR.DT, &ORE).run(&L))
- return PreservedAnalyses::all();
- return getLoopPassPreservedAnalyses();
-}
+Pass *llvm::createLoopInterchangePass() {
+ return new LoopInterchangeLegacyPass();
+}
+
+PreservedAnalyses LoopInterchangePass::run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR,
+ LPMUpdater &U) {
+ Function &F = *L.getHeader()->getParent();
+
+ DependenceInfo DI(&F, &AR.AA, &AR.SE, &AR.LI);
+ OptimizationRemarkEmitter ORE(&F);
+ if (!LoopInterchange(&AR.SE, &AR.LI, &DI, &AR.DT, &ORE).run(&L))
+ return PreservedAnalyses::all();
+ return getLoopPassPreservedAnalyses();
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopLoadElimination.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopLoadElimination.cpp
index 0d3f053e1e..058612149a 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopLoadElimination.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopLoadElimination.cpp
@@ -55,7 +55,7 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils.h"
-#include "llvm/Transforms/Utils/LoopSimplify.h"
+#include "llvm/Transforms/Utils/LoopSimplify.h"
#include "llvm/Transforms/Utils/LoopVersioning.h"
#include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
#include "llvm/Transforms/Utils/SizeOpts.h"
@@ -308,8 +308,8 @@ public:
/// We need a check if one is a pointer for a candidate load and the other is
/// a pointer for a possibly intervening store.
bool needsChecking(unsigned PtrIdx1, unsigned PtrIdx2,
- const SmallPtrSetImpl<Value *> &PtrsWrittenOnFwdingPath,
- const SmallPtrSetImpl<Value *> &CandLoadPtrs) {
+ const SmallPtrSetImpl<Value *> &PtrsWrittenOnFwdingPath,
+ const SmallPtrSetImpl<Value *> &CandLoadPtrs) {
Value *Ptr1 =
LAI.getRuntimePointerChecking()->getPointerInfo(PtrIdx1).PointerValue;
Value *Ptr2 =
@@ -384,9 +384,9 @@ public:
findPointersWrittenOnForwardingPath(Candidates);
// Collect the pointers of the candidate loads.
- SmallPtrSet<Value *, 4> CandLoadPtrs;
- for (const auto &Candidate : Candidates)
- CandLoadPtrs.insert(Candidate.getLoadPtr());
+ SmallPtrSet<Value *, 4> CandLoadPtrs;
+ for (const auto &Candidate : Candidates)
+ CandLoadPtrs.insert(Candidate.getLoadPtr());
const auto &AllChecks = LAI.getRuntimePointerChecking()->getChecks();
SmallVector<RuntimePointerCheck, 4> Checks;
@@ -505,16 +505,16 @@ public:
if (!Cand.isDependenceDistanceOfOne(PSE, L))
continue;
- assert(isa<SCEVAddRecExpr>(PSE.getSCEV(Cand.Load->getPointerOperand())) &&
- "Loading from something other than indvar?");
- assert(
- isa<SCEVAddRecExpr>(PSE.getSCEV(Cand.Store->getPointerOperand())) &&
- "Storing to something other than indvar?");
-
- Candidates.push_back(Cand);
+ assert(isa<SCEVAddRecExpr>(PSE.getSCEV(Cand.Load->getPointerOperand())) &&
+ "Loading from something other than indvar?");
+ assert(
+ isa<SCEVAddRecExpr>(PSE.getSCEV(Cand.Store->getPointerOperand())) &&
+ "Storing to something other than indvar?");
+
+ Candidates.push_back(Cand);
LLVM_DEBUG(
dbgs()
- << Candidates.size()
+ << Candidates.size()
<< ". Valid store-to-load forwarding across the loop backedge\n");
}
if (Candidates.empty())
@@ -563,19 +563,19 @@ public:
// Point of no-return, start the transformation. First, version the loop
// if necessary.
- LoopVersioning LV(LAI, Checks, L, LI, DT, PSE.getSE());
+ LoopVersioning LV(LAI, Checks, L, LI, DT, PSE.getSE());
LV.versionLoop();
-
- // After versioning, some of the candidates' pointers could stop being
- // SCEVAddRecs. We need to filter them out.
- auto NoLongerGoodCandidate = [this](
- const StoreToLoadForwardingCandidate &Cand) {
- return !isa<SCEVAddRecExpr>(
- PSE.getSCEV(Cand.Load->getPointerOperand())) ||
- !isa<SCEVAddRecExpr>(
- PSE.getSCEV(Cand.Store->getPointerOperand()));
- };
- llvm::erase_if(Candidates, NoLongerGoodCandidate);
+
+ // After versioning, some of the candidates' pointers could stop being
+ // SCEVAddRecs. We need to filter them out.
+ auto NoLongerGoodCandidate = [this](
+ const StoreToLoadForwardingCandidate &Cand) {
+ return !isa<SCEVAddRecExpr>(
+ PSE.getSCEV(Cand.Load->getPointerOperand())) ||
+ !isa<SCEVAddRecExpr>(
+ PSE.getSCEV(Cand.Store->getPointerOperand()));
+ };
+ llvm::erase_if(Candidates, NoLongerGoodCandidate);
}
// Next, propagate the value stored by the store to the users of the load.
@@ -584,7 +584,7 @@ public:
"storeforward");
for (const auto &Cand : Candidates)
propagateStoredValueToLoadUsers(Cand, SEE);
- NumLoopLoadEliminted += Candidates.size();
+ NumLoopLoadEliminted += Candidates.size();
return true;
}
@@ -610,7 +610,7 @@ private:
static bool
eliminateLoadsAcrossLoops(Function &F, LoopInfo &LI, DominatorTree &DT,
BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI,
- ScalarEvolution *SE, AssumptionCache *AC,
+ ScalarEvolution *SE, AssumptionCache *AC,
function_ref<const LoopAccessInfo &(Loop &)> GetLAI) {
// Build up a worklist of inner-loops to transform to avoid iterator
// invalidation.
@@ -619,21 +619,21 @@ eliminateLoadsAcrossLoops(Function &F, LoopInfo &LI, DominatorTree &DT,
// which merely optimizes the use of loads in a loop.
SmallVector<Loop *, 8> Worklist;
- bool Changed = false;
-
+ bool Changed = false;
+
for (Loop *TopLevelLoop : LI)
- for (Loop *L : depth_first(TopLevelLoop)) {
- Changed |= simplifyLoop(L, &DT, &LI, SE, AC, /*MSSAU*/ nullptr, false);
+ for (Loop *L : depth_first(TopLevelLoop)) {
+ Changed |= simplifyLoop(L, &DT, &LI, SE, AC, /*MSSAU*/ nullptr, false);
// We only handle inner-most loops.
- if (L->isInnermost())
+ if (L->isInnermost())
Worklist.push_back(L);
- }
+ }
// Now walk the identified inner loops.
for (Loop *L : Worklist) {
- // Match historical behavior
- if (!L->isRotatedForm() || !L->getExitingBlock())
- continue;
+ // Match historical behavior
+ if (!L->isRotatedForm() || !L->getExitingBlock())
+ continue;
// The actual work is performed by LoadEliminationForLoop.
LoadEliminationForLoop LEL(L, &LI, GetLAI(*L), &DT, BFI, PSI);
Changed |= LEL.processLoop();
@@ -667,7 +667,7 @@ public:
// Process each loop nest in the function.
return eliminateLoadsAcrossLoops(
- F, LI, DT, BFI, PSI, /*SE*/ nullptr, /*AC*/ nullptr,
+ F, LI, DT, BFI, PSI, /*SE*/ nullptr, /*AC*/ nullptr,
[&LAA](Loop &L) -> const LoopAccessInfo & { return LAA.getInfo(&L); });
}
@@ -724,9 +724,9 @@ PreservedAnalyses LoopLoadEliminationPass::run(Function &F,
auto &LAM = AM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
bool Changed = eliminateLoadsAcrossLoops(
- F, LI, DT, BFI, PSI, &SE, &AC, [&](Loop &L) -> const LoopAccessInfo & {
- LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE,
- TLI, TTI, nullptr, MSSA};
+ F, LI, DT, BFI, PSI, &SE, &AC, [&](Loop &L) -> const LoopAccessInfo & {
+ LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE,
+ TLI, TTI, nullptr, MSSA};
return LAM.getResult<LoopAccessAnalysis>(L, AR);
});
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopPassManager.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopPassManager.cpp
index 13330c1c80..3fe8e72591 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopPassManager.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopPassManager.cpp
@@ -6,14 +6,14 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/Scalar/LoopPassManager.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/BasicAliasAnalysis.h"
-#include "llvm/Analysis/BlockFrequencyInfo.h"
-#include "llvm/Analysis/GlobalsModRef.h"
-#include "llvm/Analysis/MemorySSA.h"
-#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
+#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/BasicAliasAnalysis.h"
+#include "llvm/Analysis/BlockFrequencyInfo.h"
+#include "llvm/Analysis/GlobalsModRef.h"
+#include "llvm/Analysis/MemorySSA.h"
+#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Support/TimeProfiler.h"
using namespace llvm;
@@ -30,133 +30,133 @@ PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
if (DebugLogging)
dbgs() << "Starting Loop pass manager run.\n";
- // Runs loop-nest passes only when the current loop is a top-level one.
- PreservedAnalyses PA = (L.isOutermost() && !LoopNestPasses.empty())
- ? runWithLoopNestPasses(L, AM, AR, U)
- : runWithoutLoopNestPasses(L, AM, AR, U);
-
- // Invalidation for the current loop should be handled above, and other loop
- // analysis results shouldn't be impacted by runs over this loop. Therefore,
- // the remaining analysis results in the AnalysisManager are preserved. We
- // mark this with a set so that we don't need to inspect each one
- // individually.
- // FIXME: This isn't correct! This loop and all nested loops' analyses should
- // be preserved, but unrolling should invalidate the parent loop's analyses.
- PA.preserveSet<AllAnalysesOn<Loop>>();
-
- if (DebugLogging)
- dbgs() << "Finished Loop pass manager run.\n";
-
- return PA;
-}
-
-// Run both loop passes and loop-nest passes on top-level loop \p L.
-PreservedAnalyses
-LoopPassManager::runWithLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
- LoopStandardAnalysisResults &AR,
- LPMUpdater &U) {
- assert(L.isOutermost() &&
- "Loop-nest passes should only run on top-level loops.");
- PreservedAnalyses PA = PreservedAnalyses::all();
-
+ // Runs loop-nest passes only when the current loop is a top-level one.
+ PreservedAnalyses PA = (L.isOutermost() && !LoopNestPasses.empty())
+ ? runWithLoopNestPasses(L, AM, AR, U)
+ : runWithoutLoopNestPasses(L, AM, AR, U);
+
+ // Invalidation for the current loop should be handled above, and other loop
+ // analysis results shouldn't be impacted by runs over this loop. Therefore,
+ // the remaining analysis results in the AnalysisManager are preserved. We
+ // mark this with a set so that we don't need to inspect each one
+ // individually.
+ // FIXME: This isn't correct! This loop and all nested loops' analyses should
+ // be preserved, but unrolling should invalidate the parent loop's analyses.
+ PA.preserveSet<AllAnalysesOn<Loop>>();
+
+ if (DebugLogging)
+ dbgs() << "Finished Loop pass manager run.\n";
+
+ return PA;
+}
+
+// Run both loop passes and loop-nest passes on top-level loop \p L.
+PreservedAnalyses
+LoopPassManager::runWithLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR,
+ LPMUpdater &U) {
+ assert(L.isOutermost() &&
+ "Loop-nest passes should only run on top-level loops.");
+ PreservedAnalyses PA = PreservedAnalyses::all();
+
// Request PassInstrumentation from analysis manager, will use it to run
// instrumenting callbacks for the passes later.
PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(L, AR);
- unsigned LoopPassIndex = 0, LoopNestPassIndex = 0;
-
- // `LoopNestPtr` points to the `LoopNest` object for the current top-level
- // loop and `IsLoopNestPtrValid` indicates whether the pointer is still valid.
- // The `LoopNest` object will have to be re-constructed if the pointer is
- // invalid when encountering a loop-nest pass.
- std::unique_ptr<LoopNest> LoopNestPtr;
- bool IsLoopNestPtrValid = false;
-
- for (size_t I = 0, E = IsLoopNestPass.size(); I != E; ++I) {
- Optional<PreservedAnalyses> PassPA;
- if (!IsLoopNestPass[I]) {
- // The `I`-th pass is a loop pass.
- auto &Pass = LoopPasses[LoopPassIndex++];
- PassPA = runSinglePass(L, Pass, AM, AR, U, PI);
- } else {
- // The `I`-th pass is a loop-nest pass.
- auto &Pass = LoopNestPasses[LoopNestPassIndex++];
-
- // If the loop-nest object calculated before is no longer valid,
- // re-calculate it here before running the loop-nest pass.
- if (!IsLoopNestPtrValid) {
- LoopNestPtr = LoopNest::getLoopNest(L, AR.SE);
- IsLoopNestPtrValid = true;
- }
- PassPA = runSinglePass(*LoopNestPtr, Pass, AM, AR, U, PI);
+ unsigned LoopPassIndex = 0, LoopNestPassIndex = 0;
+
+ // `LoopNestPtr` points to the `LoopNest` object for the current top-level
+ // loop and `IsLoopNestPtrValid` indicates whether the pointer is still valid.
+ // The `LoopNest` object will have to be re-constructed if the pointer is
+ // invalid when encountering a loop-nest pass.
+ std::unique_ptr<LoopNest> LoopNestPtr;
+ bool IsLoopNestPtrValid = false;
+
+ for (size_t I = 0, E = IsLoopNestPass.size(); I != E; ++I) {
+ Optional<PreservedAnalyses> PassPA;
+ if (!IsLoopNestPass[I]) {
+ // The `I`-th pass is a loop pass.
+ auto &Pass = LoopPasses[LoopPassIndex++];
+ PassPA = runSinglePass(L, Pass, AM, AR, U, PI);
+ } else {
+ // The `I`-th pass is a loop-nest pass.
+ auto &Pass = LoopNestPasses[LoopNestPassIndex++];
+
+ // If the loop-nest object calculated before is no longer valid,
+ // re-calculate it here before running the loop-nest pass.
+ if (!IsLoopNestPtrValid) {
+ LoopNestPtr = LoopNest::getLoopNest(L, AR.SE);
+ IsLoopNestPtrValid = true;
+ }
+ PassPA = runSinglePass(*LoopNestPtr, Pass, AM, AR, U, PI);
}
- // `PassPA` is `None` means that the before-pass callbacks in
- // `PassInstrumentation` return false. The pass does not run in this case,
- // so we can skip the following procedure.
- if (!PassPA)
- continue;
+ // `PassPA` is `None` means that the before-pass callbacks in
+ // `PassInstrumentation` return false. The pass does not run in this case,
+ // so we can skip the following procedure.
+ if (!PassPA)
+ continue;
+
+ // If the loop was deleted, abort the run and return to the outer walk.
+ if (U.skipCurrentLoop()) {
+ PA.intersect(std::move(*PassPA));
+ break;
+ }
+
+ // Update the analysis manager as each pass runs and potentially
+ // invalidates analyses.
+ AM.invalidate(L, *PassPA);
+
+ // Finally, we intersect the final preserved analyses to compute the
+ // aggregate preserved set for this pass manager.
+ PA.intersect(std::move(*PassPA));
+
+ // Check if the current pass preserved the loop-nest object or not.
+ IsLoopNestPtrValid &= PassPA->getChecker<LoopNestAnalysis>().preserved();
+
+ // FIXME: Historically, the pass managers all called the LLVM context's
+ // yield function here. We don't have a generic way to acquire the
+ // context and it isn't yet clear what the right pattern is for yielding
+ // in the new pass manager so it is currently omitted.
+ // ...getContext().yield();
+ }
+ return PA;
+}
+
+// Run all loop passes on loop \p L. Loop-nest passes don't run either because
+// \p L is not a top-level one or simply because there are no loop-nest passes
+// in the pass manager at all.
+PreservedAnalyses
+LoopPassManager::runWithoutLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR,
+ LPMUpdater &U) {
+ PreservedAnalyses PA = PreservedAnalyses::all();
+
+ // Request PassInstrumentation from analysis manager, will use it to run
+ // instrumenting callbacks for the passes later.
+ PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(L, AR);
+ for (auto &Pass : LoopPasses) {
+ Optional<PreservedAnalyses> PassPA = runSinglePass(L, Pass, AM, AR, U, PI);
+
+ // `PassPA` is `None` means that the before-pass callbacks in
+ // `PassInstrumentation` return false. The pass does not run in this case,
+ // so we can skip the following procedure.
+ if (!PassPA)
+ continue;
// If the loop was deleted, abort the run and return to the outer walk.
if (U.skipCurrentLoop()) {
- PA.intersect(std::move(*PassPA));
+ PA.intersect(std::move(*PassPA));
break;
}
- // Update the analysis manager as each pass runs and potentially
- // invalidates analyses.
- AM.invalidate(L, *PassPA);
-
- // Finally, we intersect the final preserved analyses to compute the
- // aggregate preserved set for this pass manager.
- PA.intersect(std::move(*PassPA));
-
- // Check if the current pass preserved the loop-nest object or not.
- IsLoopNestPtrValid &= PassPA->getChecker<LoopNestAnalysis>().preserved();
-
- // FIXME: Historically, the pass managers all called the LLVM context's
- // yield function here. We don't have a generic way to acquire the
- // context and it isn't yet clear what the right pattern is for yielding
- // in the new pass manager so it is currently omitted.
- // ...getContext().yield();
- }
- return PA;
-}
-
-// Run all loop passes on loop \p L. Loop-nest passes don't run either because
-// \p L is not a top-level one or simply because there are no loop-nest passes
-// in the pass manager at all.
-PreservedAnalyses
-LoopPassManager::runWithoutLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
- LoopStandardAnalysisResults &AR,
- LPMUpdater &U) {
- PreservedAnalyses PA = PreservedAnalyses::all();
-
- // Request PassInstrumentation from analysis manager, will use it to run
- // instrumenting callbacks for the passes later.
- PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(L, AR);
- for (auto &Pass : LoopPasses) {
- Optional<PreservedAnalyses> PassPA = runSinglePass(L, Pass, AM, AR, U, PI);
-
- // `PassPA` is `None` means that the before-pass callbacks in
- // `PassInstrumentation` return false. The pass does not run in this case,
- // so we can skip the following procedure.
- if (!PassPA)
- continue;
-
- // If the loop was deleted, abort the run and return to the outer walk.
- if (U.skipCurrentLoop()) {
- PA.intersect(std::move(*PassPA));
- break;
- }
-
// Update the analysis manager as each pass runs and potentially
// invalidates analyses.
- AM.invalidate(L, *PassPA);
+ AM.invalidate(L, *PassPA);
// Finally, we intersect the final preserved analyses to compute the
// aggregate preserved set for this pass manager.
- PA.intersect(std::move(*PassPA));
+ PA.intersect(std::move(*PassPA));
// FIXME: Historically, the pass managers all called the LLVM context's
// yield function here. We don't have a generic way to acquire the
@@ -164,162 +164,162 @@ LoopPassManager::runWithoutLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
// in the new pass manager so it is currently omitted.
// ...getContext().yield();
}
- return PA;
-}
-} // namespace llvm
-
-PreservedAnalyses FunctionToLoopPassAdaptor::run(Function &F,
- FunctionAnalysisManager &AM) {
- // Before we even compute any loop analyses, first run a miniature function
- // pass pipeline to put loops into their canonical form. Note that we can
- // directly build up function analyses after this as the function pass
- // manager handles all the invalidation at that layer.
- PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(F);
-
- PreservedAnalyses PA = PreservedAnalyses::all();
- // Check the PassInstrumentation's BeforePass callbacks before running the
- // canonicalization pipeline.
- if (PI.runBeforePass<Function>(LoopCanonicalizationFPM, F)) {
- PA = LoopCanonicalizationFPM.run(F, AM);
- PI.runAfterPass<Function>(LoopCanonicalizationFPM, F, PA);
- }
-
- // Get the loop structure for this function
- LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
-
- // If there are no loops, there is nothing to do here.
- if (LI.empty())
- return PA;
-
- // Get the analysis results needed by loop passes.
- MemorySSA *MSSA =
- UseMemorySSA ? (&AM.getResult<MemorySSAAnalysis>(F).getMSSA()) : nullptr;
- BlockFrequencyInfo *BFI = UseBlockFrequencyInfo && F.hasProfileData()
- ? (&AM.getResult<BlockFrequencyAnalysis>(F))
- : nullptr;
- LoopStandardAnalysisResults LAR = {AM.getResult<AAManager>(F),
- AM.getResult<AssumptionAnalysis>(F),
- AM.getResult<DominatorTreeAnalysis>(F),
- AM.getResult<LoopAnalysis>(F),
- AM.getResult<ScalarEvolutionAnalysis>(F),
- AM.getResult<TargetLibraryAnalysis>(F),
- AM.getResult<TargetIRAnalysis>(F),
- BFI,
- MSSA};
-
- // Setup the loop analysis manager from its proxy. It is important that
- // this is only done when there are loops to process and we have built the
- // LoopStandardAnalysisResults object. The loop analyses cached in this
- // manager have access to those analysis results and so it must invalidate
- // itself when they go away.
- auto &LAMFP = AM.getResult<LoopAnalysisManagerFunctionProxy>(F);
- if (UseMemorySSA)
- LAMFP.markMSSAUsed();
- LoopAnalysisManager &LAM = LAMFP.getManager();
-
- // A postorder worklist of loops to process.
- SmallPriorityWorklist<Loop *, 4> Worklist;
-
- // Register the worklist and loop analysis manager so that loop passes can
- // update them when they mutate the loop nest structure.
- LPMUpdater Updater(Worklist, LAM, LoopNestMode);
-
- // Add the loop nests in the reverse order of LoopInfo. See method
- // declaration.
- if (!LoopNestMode) {
- appendLoopsToWorklist(LI, Worklist);
- } else {
- for (Loop *L : LI)
- Worklist.insert(L);
- }
-
-#ifndef NDEBUG
- PI.pushBeforeNonSkippedPassCallback([&LAR, &LI](StringRef PassID, Any IR) {
- if (isSpecialPass(PassID, {"PassManager"}))
- return;
- assert(any_isa<const Loop *>(IR) || any_isa<const LoopNest *>(IR));
- const Loop *L = any_isa<const Loop *>(IR)
- ? any_cast<const Loop *>(IR)
- : &any_cast<const LoopNest *>(IR)->getOutermostLoop();
- assert(L && "Loop should be valid for printing");
-
- // Verify the loop structure and LCSSA form before visiting the loop.
- L->verifyLoop();
- assert(L->isRecursivelyLCSSAForm(LAR.DT, LI) &&
- "Loops must remain in LCSSA form!");
- });
-#endif
-
- do {
- Loop *L = Worklist.pop_back_val();
- assert(!(LoopNestMode && L->getParentLoop()) &&
- "L should be a top-level loop in loop-nest mode.");
-
- // Reset the update structure for this loop.
- Updater.CurrentL = L;
- Updater.SkipCurrentLoop = false;
-
-#ifndef NDEBUG
- // Save a parent loop pointer for asserts.
- Updater.ParentL = L->getParentLoop();
-#endif
- // Check the PassInstrumentation's BeforePass callbacks before running the
- // pass, skip its execution completely if asked to (callback returns
- // false).
- if (!PI.runBeforePass<Loop>(*Pass, *L))
- continue;
-
- PreservedAnalyses PassPA;
- {
- TimeTraceScope TimeScope(Pass->name());
- PassPA = Pass->run(*L, LAM, LAR, Updater);
- }
-
- // Do not pass deleted Loop into the instrumentation.
- if (Updater.skipCurrentLoop())
- PI.runAfterPassInvalidated<Loop>(*Pass, PassPA);
- else
- PI.runAfterPass<Loop>(*Pass, *L, PassPA);
-
- // FIXME: We should verify the set of analyses relevant to Loop passes
- // are preserved.
-
- // If the loop hasn't been deleted, we need to handle invalidation here.
- if (!Updater.skipCurrentLoop())
- // We know that the loop pass couldn't have invalidated any other
- // loop's analyses (that's the contract of a loop pass), so directly
- // handle the loop analysis manager's invalidation here.
- LAM.invalidate(*L, PassPA);
-
- // Then intersect the preserved set so that invalidation of module
- // analyses will eventually occur when the module pass completes.
- PA.intersect(std::move(PassPA));
- } while (!Worklist.empty());
-
-#ifndef NDEBUG
- PI.popBeforeNonSkippedPassCallback();
-#endif
-
- // By definition we preserve the proxy. We also preserve all analyses on
- // Loops. This precludes *any* invalidation of loop analyses by the proxy,
- // but that's OK because we've taken care to invalidate analyses in the
- // loop analysis manager incrementally above.
- PA.preserveSet<AllAnalysesOn<Loop>>();
- PA.preserve<LoopAnalysisManagerFunctionProxy>();
- // We also preserve the set of standard analyses.
- PA.preserve<DominatorTreeAnalysis>();
- PA.preserve<LoopAnalysis>();
- PA.preserve<ScalarEvolutionAnalysis>();
- if (UseBlockFrequencyInfo && F.hasProfileData())
- PA.preserve<BlockFrequencyAnalysis>();
- if (UseMemorySSA)
- PA.preserve<MemorySSAAnalysis>();
- // FIXME: What we really want to do here is preserve an AA category, but
- // that concept doesn't exist yet.
- PA.preserve<AAManager>();
- PA.preserve<BasicAA>();
- PA.preserve<GlobalsAA>();
- PA.preserve<SCEVAA>();
+ return PA;
+}
+} // namespace llvm
+
+PreservedAnalyses FunctionToLoopPassAdaptor::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ // Before we even compute any loop analyses, first run a miniature function
+ // pass pipeline to put loops into their canonical form. Note that we can
+ // directly build up function analyses after this as the function pass
+ // manager handles all the invalidation at that layer.
+ PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(F);
+
+ PreservedAnalyses PA = PreservedAnalyses::all();
+ // Check the PassInstrumentation's BeforePass callbacks before running the
+ // canonicalization pipeline.
+ if (PI.runBeforePass<Function>(LoopCanonicalizationFPM, F)) {
+ PA = LoopCanonicalizationFPM.run(F, AM);
+ PI.runAfterPass<Function>(LoopCanonicalizationFPM, F, PA);
+ }
+
+ // Get the loop structure for this function
+ LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
+
+ // If there are no loops, there is nothing to do here.
+ if (LI.empty())
+ return PA;
+
+ // Get the analysis results needed by loop passes.
+ MemorySSA *MSSA =
+ UseMemorySSA ? (&AM.getResult<MemorySSAAnalysis>(F).getMSSA()) : nullptr;
+ BlockFrequencyInfo *BFI = UseBlockFrequencyInfo && F.hasProfileData()
+ ? (&AM.getResult<BlockFrequencyAnalysis>(F))
+ : nullptr;
+ LoopStandardAnalysisResults LAR = {AM.getResult<AAManager>(F),
+ AM.getResult<AssumptionAnalysis>(F),
+ AM.getResult<DominatorTreeAnalysis>(F),
+ AM.getResult<LoopAnalysis>(F),
+ AM.getResult<ScalarEvolutionAnalysis>(F),
+ AM.getResult<TargetLibraryAnalysis>(F),
+ AM.getResult<TargetIRAnalysis>(F),
+ BFI,
+ MSSA};
+
+ // Setup the loop analysis manager from its proxy. It is important that
+ // this is only done when there are loops to process and we have built the
+ // LoopStandardAnalysisResults object. The loop analyses cached in this
+ // manager have access to those analysis results and so it must invalidate
+ // itself when they go away.
+ auto &LAMFP = AM.getResult<LoopAnalysisManagerFunctionProxy>(F);
+ if (UseMemorySSA)
+ LAMFP.markMSSAUsed();
+ LoopAnalysisManager &LAM = LAMFP.getManager();
+
+ // A postorder worklist of loops to process.
+ SmallPriorityWorklist<Loop *, 4> Worklist;
+
+ // Register the worklist and loop analysis manager so that loop passes can
+ // update them when they mutate the loop nest structure.
+ LPMUpdater Updater(Worklist, LAM, LoopNestMode);
+
+ // Add the loop nests in the reverse order of LoopInfo. See method
+ // declaration.
+ if (!LoopNestMode) {
+ appendLoopsToWorklist(LI, Worklist);
+ } else {
+ for (Loop *L : LI)
+ Worklist.insert(L);
+ }
+
+#ifndef NDEBUG
+ PI.pushBeforeNonSkippedPassCallback([&LAR, &LI](StringRef PassID, Any IR) {
+ if (isSpecialPass(PassID, {"PassManager"}))
+ return;
+ assert(any_isa<const Loop *>(IR) || any_isa<const LoopNest *>(IR));
+ const Loop *L = any_isa<const Loop *>(IR)
+ ? any_cast<const Loop *>(IR)
+ : &any_cast<const LoopNest *>(IR)->getOutermostLoop();
+ assert(L && "Loop should be valid for printing");
+
+ // Verify the loop structure and LCSSA form before visiting the loop.
+ L->verifyLoop();
+ assert(L->isRecursivelyLCSSAForm(LAR.DT, LI) &&
+ "Loops must remain in LCSSA form!");
+ });
+#endif
+
+ do {
+ Loop *L = Worklist.pop_back_val();
+ assert(!(LoopNestMode && L->getParentLoop()) &&
+ "L should be a top-level loop in loop-nest mode.");
+
+ // Reset the update structure for this loop.
+ Updater.CurrentL = L;
+ Updater.SkipCurrentLoop = false;
+
+#ifndef NDEBUG
+ // Save a parent loop pointer for asserts.
+ Updater.ParentL = L->getParentLoop();
+#endif
+ // Check the PassInstrumentation's BeforePass callbacks before running the
+ // pass, skip its execution completely if asked to (callback returns
+ // false).
+ if (!PI.runBeforePass<Loop>(*Pass, *L))
+ continue;
+
+ PreservedAnalyses PassPA;
+ {
+ TimeTraceScope TimeScope(Pass->name());
+ PassPA = Pass->run(*L, LAM, LAR, Updater);
+ }
+
+ // Do not pass deleted Loop into the instrumentation.
+ if (Updater.skipCurrentLoop())
+ PI.runAfterPassInvalidated<Loop>(*Pass, PassPA);
+ else
+ PI.runAfterPass<Loop>(*Pass, *L, PassPA);
+
+ // FIXME: We should verify the set of analyses relevant to Loop passes
+ // are preserved.
+
+ // If the loop hasn't been deleted, we need to handle invalidation here.
+ if (!Updater.skipCurrentLoop())
+ // We know that the loop pass couldn't have invalidated any other
+ // loop's analyses (that's the contract of a loop pass), so directly
+ // handle the loop analysis manager's invalidation here.
+ LAM.invalidate(*L, PassPA);
+
+ // Then intersect the preserved set so that invalidation of module
+ // analyses will eventually occur when the module pass completes.
+ PA.intersect(std::move(PassPA));
+ } while (!Worklist.empty());
+
+#ifndef NDEBUG
+ PI.popBeforeNonSkippedPassCallback();
+#endif
+
+ // By definition we preserve the proxy. We also preserve all analyses on
+ // Loops. This precludes *any* invalidation of loop analyses by the proxy,
+ // but that's OK because we've taken care to invalidate analyses in the
+ // loop analysis manager incrementally above.
+ PA.preserveSet<AllAnalysesOn<Loop>>();
+ PA.preserve<LoopAnalysisManagerFunctionProxy>();
+ // We also preserve the set of standard analyses.
+ PA.preserve<DominatorTreeAnalysis>();
+ PA.preserve<LoopAnalysis>();
+ PA.preserve<ScalarEvolutionAnalysis>();
+ if (UseBlockFrequencyInfo && F.hasProfileData())
+ PA.preserve<BlockFrequencyAnalysis>();
+ if (UseMemorySSA)
+ PA.preserve<MemorySSAAnalysis>();
+ // FIXME: What we really want to do here is preserve an AA category, but
+ // that concept doesn't exist yet.
+ PA.preserve<AAManager>();
+ PA.preserve<BasicAA>();
+ PA.preserve<GlobalsAA>();
+ PA.preserve<SCEVAA>();
return PA;
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopPredication.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopPredication.cpp
index e46c3d64e6..4f97641e20 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopPredication.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopPredication.cpp
@@ -362,7 +362,7 @@ PreservedAnalyses LoopPredicationPass::run(Loop &L, LoopAnalysisManager &AM,
// For the new PM, we also can't use BranchProbabilityInfo as an analysis
// pass. Function analyses need to be preserved across loop transformations
// but BPI is not preserved, hence a newly built one is needed.
- BranchProbabilityInfo BPI(*F, AR.LI, &AR.TLI, &AR.DT, nullptr);
+ BranchProbabilityInfo BPI(*F, AR.LI, &AR.TLI, &AR.DT, nullptr);
LoopPredication LP(&AR.AA, &AR.DT, &AR.SE, &AR.LI, &BPI);
if (!LP.runOnLoop(&L))
return PreservedAnalyses::all();
@@ -439,8 +439,8 @@ static bool isSafeToTruncateWideIVType(const DataLayout &DL,
Type *RangeCheckType) {
if (!EnableIVTruncation)
return false;
- assert(DL.getTypeSizeInBits(LatchCheck.IV->getType()).getFixedSize() >
- DL.getTypeSizeInBits(RangeCheckType).getFixedSize() &&
+ assert(DL.getTypeSizeInBits(LatchCheck.IV->getType()).getFixedSize() >
+ DL.getTypeSizeInBits(RangeCheckType).getFixedSize() &&
"Expected latch check IV type to be larger than range check operand "
"type!");
// The start and end values of the IV should be known. This is to guarantee
@@ -454,13 +454,13 @@ static bool isSafeToTruncateWideIVType(const DataLayout &DL,
// LatchEnd = 2, rangeCheckType = i32. If it's not a monotonic predicate, the
// IV wraps around, and the truncation of the IV would lose the range of
// iterations between 2^32 and 2^64.
- if (!SE.getMonotonicPredicateType(LatchCheck.IV, LatchCheck.Pred))
+ if (!SE.getMonotonicPredicateType(LatchCheck.IV, LatchCheck.Pred))
return false;
// The active bits should be less than the bits in the RangeCheckType. This
// guarantees that truncating the latch check to RangeCheckType is a safe
// operation.
- auto RangeCheckTypeBitSize =
- DL.getTypeSizeInBits(RangeCheckType).getFixedSize();
+ auto RangeCheckTypeBitSize =
+ DL.getTypeSizeInBits(RangeCheckType).getFixedSize();
return Start->getAPInt().getActiveBits() < RangeCheckTypeBitSize &&
Limit->getAPInt().getActiveBits() < RangeCheckTypeBitSize;
}
@@ -477,8 +477,8 @@ static Optional<LoopICmp> generateLoopLatchCheck(const DataLayout &DL,
if (RangeCheckType == LatchType)
return LatchCheck;
// For now, bail out if latch type is narrower than range type.
- if (DL.getTypeSizeInBits(LatchType).getFixedSize() <
- DL.getTypeSizeInBits(RangeCheckType).getFixedSize())
+ if (DL.getTypeSizeInBits(LatchType).getFixedSize() <
+ DL.getTypeSizeInBits(RangeCheckType).getFixedSize())
return None;
if (!isSafeToTruncateWideIVType(DL, SE, LatchCheck, RangeCheckType))
return None;
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopRerollPass.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopRerollPass.cpp
index 18caeabaca..65a6205f03 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopRerollPass.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopRerollPass.cpp
@@ -50,7 +50,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h"
-#include "llvm/Transforms/Scalar/LoopReroll.h"
+#include "llvm/Transforms/Scalar/LoopReroll.h"
#include "llvm/Transforms/Utils.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
@@ -162,12 +162,12 @@ namespace {
IL_End
};
- class LoopRerollLegacyPass : public LoopPass {
+ class LoopRerollLegacyPass : public LoopPass {
public:
static char ID; // Pass ID, replacement for typeid
- LoopRerollLegacyPass() : LoopPass(ID) {
- initializeLoopRerollLegacyPassPass(*PassRegistry::getPassRegistry());
+ LoopRerollLegacyPass() : LoopPass(ID) {
+ initializeLoopRerollLegacyPassPass(*PassRegistry::getPassRegistry());
}
bool runOnLoop(Loop *L, LPPassManager &LPM) override;
@@ -176,16 +176,16 @@ namespace {
AU.addRequired<TargetLibraryInfoWrapperPass>();
getLoopAnalysisUsage(AU);
}
- };
-
- class LoopReroll {
- public:
- LoopReroll(AliasAnalysis *AA, LoopInfo *LI, ScalarEvolution *SE,
- TargetLibraryInfo *TLI, DominatorTree *DT, bool PreserveLCSSA)
- : AA(AA), LI(LI), SE(SE), TLI(TLI), DT(DT),
- PreserveLCSSA(PreserveLCSSA) {}
- bool runOnLoop(Loop *L);
-
+ };
+
+ class LoopReroll {
+ public:
+ LoopReroll(AliasAnalysis *AA, LoopInfo *LI, ScalarEvolution *SE,
+ TargetLibraryInfo *TLI, DominatorTree *DT, bool PreserveLCSSA)
+ : AA(AA), LI(LI), SE(SE), TLI(TLI), DT(DT),
+ PreserveLCSSA(PreserveLCSSA) {}
+ bool runOnLoop(Loop *L);
+
protected:
AliasAnalysis *AA;
LoopInfo *LI;
@@ -494,16 +494,16 @@ namespace {
} // end anonymous namespace
-char LoopRerollLegacyPass::ID = 0;
+char LoopRerollLegacyPass::ID = 0;
-INITIALIZE_PASS_BEGIN(LoopRerollLegacyPass, "loop-reroll", "Reroll loops",
- false, false)
+INITIALIZE_PASS_BEGIN(LoopRerollLegacyPass, "loop-reroll", "Reroll loops",
+ false, false)
INITIALIZE_PASS_DEPENDENCY(LoopPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
-INITIALIZE_PASS_END(LoopRerollLegacyPass, "loop-reroll", "Reroll loops", false,
- false)
+INITIALIZE_PASS_END(LoopRerollLegacyPass, "loop-reroll", "Reroll loops", false,
+ false)
-Pass *llvm::createLoopRerollPass() { return new LoopRerollLegacyPass; }
+Pass *llvm::createLoopRerollPass() { return new LoopRerollLegacyPass; }
// Returns true if the provided instruction is used outside the given loop.
// This operates like Instruction::isUsedOutsideOfBlock, but considers PHIs in
@@ -1081,12 +1081,12 @@ bool LoopReroll::DAGRootTracker::collectUsedInstructions(SmallInstructionSet &Po
DenseSet<Instruction*> V;
collectInLoopUserSet(LoopIncs, Exclude, PossibleRedSet, V);
for (auto *I : V) {
- if (I->mayHaveSideEffects()) {
- LLVM_DEBUG(dbgs() << "LRR: Aborting - "
- << "An instruction which does not belong to any root "
- << "sets must not have side effects: " << *I);
- return false;
- }
+ if (I->mayHaveSideEffects()) {
+ LLVM_DEBUG(dbgs() << "LRR: Aborting - "
+ << "An instruction which does not belong to any root "
+ << "sets must not have side effects: " << *I);
+ return false;
+ }
Uses[I].set(IL_All);
}
@@ -1102,7 +1102,7 @@ LoopReroll::DAGRootTracker::nextInstr(int Val, UsesTy &In,
UsesTy::iterator *StartI) {
UsesTy::iterator I = StartI ? *StartI : In.begin();
while (I != In.end() && (I->second.test(Val) == 0 ||
- Exclude.contains(I->first)))
+ Exclude.contains(I->first)))
++I;
return I;
}
@@ -1660,7 +1660,7 @@ bool LoopReroll::reroll(Instruction *IV, Loop *L, BasicBlock *Header,
return true;
}
-bool LoopReroll::runOnLoop(Loop *L) {
+bool LoopReroll::runOnLoop(Loop *L) {
BasicBlock *Header = L->getHeader();
LLVM_DEBUG(dbgs() << "LRR: F[" << Header->getParent()->getName() << "] Loop %"
<< Header->getName() << " (" << L->getNumBlocks()
@@ -1709,26 +1709,26 @@ bool LoopReroll::runOnLoop(Loop *L) {
return Changed;
}
-
-bool LoopRerollLegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) {
- if (skipLoop(L))
- return false;
-
- auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
- auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
- auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
- *L->getHeader()->getParent());
- auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- bool PreserveLCSSA = mustPreserveAnalysisID(LCSSAID);
-
- return LoopReroll(AA, LI, SE, TLI, DT, PreserveLCSSA).runOnLoop(L);
-}
-
-PreservedAnalyses LoopRerollPass::run(Loop &L, LoopAnalysisManager &AM,
- LoopStandardAnalysisResults &AR,
- LPMUpdater &U) {
- return LoopReroll(&AR.AA, &AR.LI, &AR.SE, &AR.TLI, &AR.DT, true).runOnLoop(&L)
- ? getLoopPassPreservedAnalyses()
- : PreservedAnalyses::all();
-}
+
+bool LoopRerollLegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) {
+ if (skipLoop(L))
+ return false;
+
+ auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
+ auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
+ auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
+ auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
+ *L->getHeader()->getParent());
+ auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ bool PreserveLCSSA = mustPreserveAnalysisID(LCSSAID);
+
+ return LoopReroll(AA, LI, SE, TLI, DT, PreserveLCSSA).runOnLoop(L);
+}
+
+PreservedAnalyses LoopRerollPass::run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR,
+ LPMUpdater &U) {
+ return LoopReroll(&AR.AA, &AR.LI, &AR.SE, &AR.TLI, &AR.DT, true).runOnLoop(&L)
+ ? getLoopPassPreservedAnalyses()
+ : PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopRotation.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopRotation.cpp
index 252668e1d0..ad1cfc68ec 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopRotation.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopRotation.cpp
@@ -12,7 +12,7 @@
#include "llvm/Transforms/Scalar/LoopRotation.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/MemorySSA.h"
@@ -34,35 +34,35 @@ static cl::opt<unsigned> DefaultRotationThreshold(
"rotation-max-header-size", cl::init(16), cl::Hidden,
cl::desc("The default maximum header size for automatic loop rotation"));
-static cl::opt<bool> PrepareForLTOOption(
- "rotation-prepare-for-lto", cl::init(false), cl::Hidden,
- cl::desc("Run loop-rotation in the prepare-for-lto stage. This option "
- "should be used for testing only."));
+static cl::opt<bool> PrepareForLTOOption(
+ "rotation-prepare-for-lto", cl::init(false), cl::Hidden,
+ cl::desc("Run loop-rotation in the prepare-for-lto stage. This option "
+ "should be used for testing only."));
+
+LoopRotatePass::LoopRotatePass(bool EnableHeaderDuplication, bool PrepareForLTO)
+ : EnableHeaderDuplication(EnableHeaderDuplication),
+ PrepareForLTO(PrepareForLTO) {}
-LoopRotatePass::LoopRotatePass(bool EnableHeaderDuplication, bool PrepareForLTO)
- : EnableHeaderDuplication(EnableHeaderDuplication),
- PrepareForLTO(PrepareForLTO) {}
-
PreservedAnalyses LoopRotatePass::run(Loop &L, LoopAnalysisManager &AM,
LoopStandardAnalysisResults &AR,
LPMUpdater &) {
- // Vectorization requires loop-rotation. Use default threshold for loops the
- // user explicitly marked for vectorization, even when header duplication is
- // disabled.
- int Threshold = EnableHeaderDuplication ||
- hasVectorizeTransformation(&L) == TM_ForcedByUser
- ? DefaultRotationThreshold
- : 0;
+ // Vectorization requires loop-rotation. Use default threshold for loops the
+ // user explicitly marked for vectorization, even when header duplication is
+ // disabled.
+ int Threshold = EnableHeaderDuplication ||
+ hasVectorizeTransformation(&L) == TM_ForcedByUser
+ ? DefaultRotationThreshold
+ : 0;
const DataLayout &DL = L.getHeader()->getModule()->getDataLayout();
const SimplifyQuery SQ = getBestSimplifyQuery(AR, DL);
Optional<MemorySSAUpdater> MSSAU;
if (AR.MSSA)
MSSAU = MemorySSAUpdater(AR.MSSA);
- bool Changed =
- LoopRotation(&L, &AR.LI, &AR.TTI, &AR.AC, &AR.DT, &AR.SE,
- MSSAU.hasValue() ? MSSAU.getPointer() : nullptr, SQ, false,
- Threshold, false, PrepareForLTO || PrepareForLTOOption);
+ bool Changed =
+ LoopRotation(&L, &AR.LI, &AR.TTI, &AR.AC, &AR.DT, &AR.SE,
+ MSSAU.hasValue() ? MSSAU.getPointer() : nullptr, SQ, false,
+ Threshold, false, PrepareForLTO || PrepareForLTOOption);
if (!Changed)
return PreservedAnalyses::all();
@@ -80,13 +80,13 @@ namespace {
class LoopRotateLegacyPass : public LoopPass {
unsigned MaxHeaderSize;
- bool PrepareForLTO;
+ bool PrepareForLTO;
public:
static char ID; // Pass ID, replacement for typeid
- LoopRotateLegacyPass(int SpecifiedMaxHeaderSize = -1,
- bool PrepareForLTO = false)
- : LoopPass(ID), PrepareForLTO(PrepareForLTO) {
+ LoopRotateLegacyPass(int SpecifiedMaxHeaderSize = -1,
+ bool PrepareForLTO = false)
+ : LoopPass(ID), PrepareForLTO(PrepareForLTO) {
initializeLoopRotateLegacyPassPass(*PassRegistry::getPassRegistry());
if (SpecifiedMaxHeaderSize == -1)
MaxHeaderSize = DefaultRotationThreshold;
@@ -122,17 +122,17 @@ public:
if (MSSAA)
MSSAU = MemorySSAUpdater(&MSSAA->getMSSA());
}
- // Vectorization requires loop-rotation. Use default threshold for loops the
- // user explicitly marked for vectorization, even when header duplication is
- // disabled.
- int Threshold = hasVectorizeTransformation(L) == TM_ForcedByUser
- ? DefaultRotationThreshold
- : MaxHeaderSize;
-
+ // Vectorization requires loop-rotation. Use default threshold for loops the
+ // user explicitly marked for vectorization, even when header duplication is
+ // disabled.
+ int Threshold = hasVectorizeTransformation(L) == TM_ForcedByUser
+ ? DefaultRotationThreshold
+ : MaxHeaderSize;
+
return LoopRotation(L, LI, TTI, AC, &DT, &SE,
MSSAU.hasValue() ? MSSAU.getPointer() : nullptr, SQ,
- false, Threshold, false,
- PrepareForLTO || PrepareForLTOOption);
+ false, Threshold, false,
+ PrepareForLTO || PrepareForLTOOption);
}
};
} // end namespace
@@ -147,6 +147,6 @@ INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
INITIALIZE_PASS_END(LoopRotateLegacyPass, "loop-rotate", "Rotate Loops", false,
false)
-Pass *llvm::createLoopRotatePass(int MaxHeaderSize, bool PrepareForLTO) {
- return new LoopRotateLegacyPass(MaxHeaderSize, PrepareForLTO);
+Pass *llvm::createLoopRotatePass(int MaxHeaderSize, bool PrepareForLTO) {
+ return new LoopRotateLegacyPass(MaxHeaderSize, PrepareForLTO);
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopSimplifyCFG.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
index 17f99ff2a9..cc6d112208 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
@@ -365,20 +365,20 @@ private:
unsigned DummyIdx = 1;
for (BasicBlock *BB : DeadExitBlocks) {
- // Eliminate all Phis and LandingPads from dead exits.
- // TODO: Consider removing all instructions in this dead block.
- SmallVector<Instruction *, 4> DeadInstructions;
+ // Eliminate all Phis and LandingPads from dead exits.
+ // TODO: Consider removing all instructions in this dead block.
+ SmallVector<Instruction *, 4> DeadInstructions;
for (auto &PN : BB->phis())
- DeadInstructions.push_back(&PN);
-
- if (auto *LandingPad = dyn_cast<LandingPadInst>(BB->getFirstNonPHI()))
- DeadInstructions.emplace_back(LandingPad);
-
- for (Instruction *I : DeadInstructions) {
- I->replaceAllUsesWith(UndefValue::get(I->getType()));
- I->eraseFromParent();
+ DeadInstructions.push_back(&PN);
+
+ if (auto *LandingPad = dyn_cast<LandingPadInst>(BB->getFirstNonPHI()))
+ DeadInstructions.emplace_back(LandingPad);
+
+ for (Instruction *I : DeadInstructions) {
+ I->replaceAllUsesWith(UndefValue::get(I->getType()));
+ I->eraseFromParent();
}
-
+
assert(DummyIdx != 0 && "Too many dead exits!");
DummySwitch->addCase(Builder.getInt32(DummyIdx++), BB);
DTUpdates.push_back({DominatorTree::Insert, Preheader, BB});
@@ -415,9 +415,9 @@ private:
assert(FixLCSSALoop && "Should be a loop!");
// We need all DT updates to be done before forming LCSSA.
if (MSSAU)
- MSSAU->applyUpdates(DTUpdates, DT, /*UpdateDT=*/true);
- else
- DTU.applyUpdates(DTUpdates);
+ MSSAU->applyUpdates(DTUpdates, DT, /*UpdateDT=*/true);
+ else
+ DTU.applyUpdates(DTUpdates);
DTUpdates.clear();
formLCSSARecursively(*FixLCSSALoop, DT, &LI, &SE);
}
@@ -425,7 +425,7 @@ private:
if (MSSAU) {
// Clear all updates now. Facilitates deletes that follow.
- MSSAU->applyUpdates(DTUpdates, DT, /*UpdateDT=*/true);
+ MSSAU->applyUpdates(DTUpdates, DT, /*UpdateDT=*/true);
DTUpdates.clear();
if (VerifyMemorySSA)
MSSAU->getMemorySSA()->verifyMemorySSA();
@@ -451,7 +451,7 @@ private:
if (LI.isLoopHeader(BB)) {
assert(LI.getLoopFor(BB) != &L && "Attempt to remove current loop!");
Loop *DL = LI.getLoopFor(BB);
- if (!DL->isOutermost()) {
+ if (!DL->isOutermost()) {
for (auto *PL = DL->getParentLoop(); PL; PL = PL->getParentLoop())
for (auto *BB : DL->getBlocks())
PL->removeBlockFromLoop(BB);
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopSink.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopSink.cpp
index 0296b12878..47698fdde6 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopSink.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopSink.cpp
@@ -39,8 +39,8 @@
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
-#include "llvm/Analysis/MemorySSA.h"
-#include "llvm/Analysis/MemorySSAUpdater.h"
+#include "llvm/Analysis/MemorySSA.h"
+#include "llvm/Analysis/MemorySSAUpdater.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
#include "llvm/IR/Dominators.h"
@@ -69,14 +69,14 @@ static cl::opt<unsigned> MaxNumberOfUseBBsForSinking(
"max-uses-for-sinking", cl::Hidden, cl::init(30),
cl::desc("Do not sink instructions that have too many uses."));
-static cl::opt<bool> EnableMSSAInLoopSink(
- "enable-mssa-in-loop-sink", cl::Hidden, cl::init(true),
- cl::desc("Enable MemorySSA for LoopSink in new pass manager"));
-
-static cl::opt<bool> EnableMSSAInLegacyLoopSink(
- "enable-mssa-in-legacy-loop-sink", cl::Hidden, cl::init(false),
- cl::desc("Enable MemorySSA for LoopSink in legacy pass manager"));
-
+static cl::opt<bool> EnableMSSAInLoopSink(
+ "enable-mssa-in-loop-sink", cl::Hidden, cl::init(true),
+ cl::desc("Enable MemorySSA for LoopSink in new pass manager"));
+
+static cl::opt<bool> EnableMSSAInLegacyLoopSink(
+ "enable-mssa-in-legacy-loop-sink", cl::Hidden, cl::init(false),
+ cl::desc("Enable MemorySSA for LoopSink in legacy pass manager"));
+
/// Return adjusted total frequency of \p BBs.
///
/// * If there is only one BB, sinking instruction will not introduce code
@@ -182,10 +182,10 @@ findBBsToSinkInto(const Loop &L, const SmallPtrSetImpl<BasicBlock *> &UseBBs,
// sinking is successful.
// \p LoopBlockNumber is used to sort the insertion blocks to ensure
// determinism.
-static bool sinkInstruction(
- Loop &L, Instruction &I, const SmallVectorImpl<BasicBlock *> &ColdLoopBBs,
- const SmallDenseMap<BasicBlock *, int, 16> &LoopBlockNumber, LoopInfo &LI,
- DominatorTree &DT, BlockFrequencyInfo &BFI, MemorySSAUpdater *MSSAU) {
+static bool sinkInstruction(
+ Loop &L, Instruction &I, const SmallVectorImpl<BasicBlock *> &ColdLoopBBs,
+ const SmallDenseMap<BasicBlock *, int, 16> &LoopBlockNumber, LoopInfo &LI,
+ DominatorTree &DT, BlockFrequencyInfo &BFI, MemorySSAUpdater *MSSAU) {
// Compute the set of blocks in loop L which contain a use of I.
SmallPtrSet<BasicBlock *, 2> BBs;
for (auto &U : I.uses()) {
@@ -222,7 +222,7 @@ static bool sinkInstruction(
// of the loop block numbers as iterating the set doesn't give a useful
// order. No need to stable sort as the block numbers are a total ordering.
SmallVector<BasicBlock *, 2> SortedBBsToSinkInto;
- llvm::append_range(SortedBBsToSinkInto, BBsToSinkInto);
+ llvm::append_range(SortedBBsToSinkInto, BBsToSinkInto);
llvm::sort(SortedBBsToSinkInto, [&](BasicBlock *A, BasicBlock *B) {
return LoopBlockNumber.find(A)->second < LoopBlockNumber.find(B)->second;
});
@@ -238,21 +238,21 @@ static bool sinkInstruction(
Instruction *IC = I.clone();
IC->setName(I.getName());
IC->insertBefore(&*N->getFirstInsertionPt());
-
- if (MSSAU && MSSAU->getMemorySSA()->getMemoryAccess(&I)) {
- // Create a new MemoryAccess and let MemorySSA set its defining access.
- MemoryAccess *NewMemAcc =
- MSSAU->createMemoryAccessInBB(IC, nullptr, N, MemorySSA::Beginning);
- if (NewMemAcc) {
- if (auto *MemDef = dyn_cast<MemoryDef>(NewMemAcc))
- MSSAU->insertDef(MemDef, /*RenameUses=*/true);
- else {
- auto *MemUse = cast<MemoryUse>(NewMemAcc);
- MSSAU->insertUse(MemUse, /*RenameUses=*/true);
- }
- }
- }
-
+
+ if (MSSAU && MSSAU->getMemorySSA()->getMemoryAccess(&I)) {
+ // Create a new MemoryAccess and let MemorySSA set its defining access.
+ MemoryAccess *NewMemAcc =
+ MSSAU->createMemoryAccessInBB(IC, nullptr, N, MemorySSA::Beginning);
+ if (NewMemAcc) {
+ if (auto *MemDef = dyn_cast<MemoryDef>(NewMemAcc))
+ MSSAU->insertDef(MemDef, /*RenameUses=*/true);
+ else {
+ auto *MemUse = cast<MemoryUse>(NewMemAcc);
+ MSSAU->insertUse(MemUse, /*RenameUses=*/true);
+ }
+ }
+ }
+
// Replaces uses of I with IC in N
I.replaceUsesWithIf(IC, [N](Use &U) {
return cast<Instruction>(U.getUser())->getParent() == N;
@@ -267,11 +267,11 @@ static bool sinkInstruction(
NumLoopSunk++;
I.moveBefore(&*MoveBB->getFirstInsertionPt());
- if (MSSAU)
- if (MemoryUseOrDef *OldMemAcc = cast_or_null<MemoryUseOrDef>(
- MSSAU->getMemorySSA()->getMemoryAccess(&I)))
- MSSAU->moveToPlace(OldMemAcc, MoveBB, MemorySSA::Beginning);
-
+ if (MSSAU)
+ if (MemoryUseOrDef *OldMemAcc = cast_or_null<MemoryUseOrDef>(
+ MSSAU->getMemorySSA()->getMemoryAccess(&I)))
+ MSSAU->moveToPlace(OldMemAcc, MoveBB, MemorySSA::Beginning);
+
return true;
}
@@ -280,14 +280,14 @@ static bool sinkInstruction(
static bool sinkLoopInvariantInstructions(Loop &L, AAResults &AA, LoopInfo &LI,
DominatorTree &DT,
BlockFrequencyInfo &BFI,
- ScalarEvolution *SE,
- AliasSetTracker *CurAST,
- MemorySSA *MSSA) {
+ ScalarEvolution *SE,
+ AliasSetTracker *CurAST,
+ MemorySSA *MSSA) {
BasicBlock *Preheader = L.getLoopPreheader();
- assert(Preheader && "Expected loop to have preheader");
+ assert(Preheader && "Expected loop to have preheader");
- assert(Preheader->getParent()->hasProfileData() &&
- "Unexpected call when profile data unavailable.");
+ assert(Preheader->getParent()->hasProfileData() &&
+ "Unexpected call when profile data unavailable.");
const BlockFrequency PreheaderFreq = BFI.getBlockFreq(Preheader);
// If there are no basic blocks with lower frequency than the preheader then
@@ -298,14 +298,14 @@ static bool sinkLoopInvariantInstructions(Loop &L, AAResults &AA, LoopInfo &LI,
}))
return false;
- std::unique_ptr<MemorySSAUpdater> MSSAU;
- std::unique_ptr<SinkAndHoistLICMFlags> LICMFlags;
- if (MSSA) {
- MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
- LICMFlags =
- std::make_unique<SinkAndHoistLICMFlags>(/*IsSink=*/true, &L, MSSA);
- }
-
+ std::unique_ptr<MemorySSAUpdater> MSSAU;
+ std::unique_ptr<SinkAndHoistLICMFlags> LICMFlags;
+ if (MSSA) {
+ MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
+ LICMFlags =
+ std::make_unique<SinkAndHoistLICMFlags>(/*IsSink=*/true, &L, MSSA);
+ }
+
bool Changed = false;
// Sort loop's basic blocks by frequency
@@ -329,11 +329,11 @@ static bool sinkLoopInvariantInstructions(Loop &L, AAResults &AA, LoopInfo &LI,
// No need to check for instruction's operands are loop invariant.
assert(L.hasLoopInvariantOperands(I) &&
"Insts in a loop's preheader should have loop invariant operands!");
- if (!canSinkOrHoistInst(*I, &AA, &DT, &L, CurAST, MSSAU.get(), false,
- LICMFlags.get()))
+ if (!canSinkOrHoistInst(*I, &AA, &DT, &L, CurAST, MSSAU.get(), false,
+ LICMFlags.get()))
continue;
- if (sinkInstruction(L, *I, ColdLoopBBs, LoopBlockNumber, LI, DT, BFI,
- MSSAU.get()))
+ if (sinkInstruction(L, *I, ColdLoopBBs, LoopBlockNumber, LI, DT, BFI,
+ MSSAU.get()))
Changed = true;
}
@@ -342,13 +342,13 @@ static bool sinkLoopInvariantInstructions(Loop &L, AAResults &AA, LoopInfo &LI,
return Changed;
}
-static void computeAliasSet(Loop &L, BasicBlock &Preheader,
- AliasSetTracker &CurAST) {
- for (BasicBlock *BB : L.blocks())
- CurAST.add(*BB);
- CurAST.add(Preheader);
-}
-
+static void computeAliasSet(Loop &L, BasicBlock &Preheader,
+ AliasSetTracker &CurAST) {
+ for (BasicBlock *BB : L.blocks())
+ CurAST.add(*BB);
+ CurAST.add(Preheader);
+}
+
PreservedAnalyses LoopSinkPass::run(Function &F, FunctionAnalysisManager &FAM) {
LoopInfo &LI = FAM.getResult<LoopAnalysis>(F);
// Nothing to do if there are no loops.
@@ -359,10 +359,10 @@ PreservedAnalyses LoopSinkPass::run(Function &F, FunctionAnalysisManager &FAM) {
DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
BlockFrequencyInfo &BFI = FAM.getResult<BlockFrequencyAnalysis>(F);
- MemorySSA *MSSA = EnableMSSAInLoopSink
- ? &FAM.getResult<MemorySSAAnalysis>(F).getMSSA()
- : nullptr;
-
+ MemorySSA *MSSA = EnableMSSAInLoopSink
+ ? &FAM.getResult<MemorySSAAnalysis>(F).getMSSA()
+ : nullptr;
+
// We want to do a postorder walk over the loops. Since loops are a tree this
// is equivalent to a reversed preorder walk and preorder is easy to compute
// without recursion. Since we reverse the preorder, we will visit siblings
@@ -374,27 +374,27 @@ PreservedAnalyses LoopSinkPass::run(Function &F, FunctionAnalysisManager &FAM) {
do {
Loop &L = *PreorderLoops.pop_back_val();
- BasicBlock *Preheader = L.getLoopPreheader();
- if (!Preheader)
- continue;
-
- // Enable LoopSink only when runtime profile is available.
- // With static profile, the sinking decision may be sub-optimal.
- if (!Preheader->getParent()->hasProfileData())
- continue;
-
- std::unique_ptr<AliasSetTracker> CurAST;
- if (!EnableMSSAInLoopSink) {
- CurAST = std::make_unique<AliasSetTracker>(AA);
- computeAliasSet(L, *Preheader, *CurAST.get());
- }
-
+ BasicBlock *Preheader = L.getLoopPreheader();
+ if (!Preheader)
+ continue;
+
+ // Enable LoopSink only when runtime profile is available.
+ // With static profile, the sinking decision may be sub-optimal.
+ if (!Preheader->getParent()->hasProfileData())
+ continue;
+
+ std::unique_ptr<AliasSetTracker> CurAST;
+ if (!EnableMSSAInLoopSink) {
+ CurAST = std::make_unique<AliasSetTracker>(AA);
+ computeAliasSet(L, *Preheader, *CurAST.get());
+ }
+
// Note that we don't pass SCEV here because it is only used to invalidate
// loops in SCEV and we don't preserve (or request) SCEV at all making that
// unnecessary.
Changed |= sinkLoopInvariantInstructions(L, AA, LI, DT, BFI,
- /*ScalarEvolution*/ nullptr,
- CurAST.get(), MSSA);
+ /*ScalarEvolution*/ nullptr,
+ CurAST.get(), MSSA);
} while (!PreorderLoops.empty());
if (!Changed)
@@ -402,14 +402,14 @@ PreservedAnalyses LoopSinkPass::run(Function &F, FunctionAnalysisManager &FAM) {
PreservedAnalyses PA;
PA.preserveSet<CFGAnalyses>();
-
- if (MSSA) {
- PA.preserve<MemorySSAAnalysis>();
-
- if (VerifyMemorySSA)
- MSSA->verifyMemorySSA();
- }
-
+
+ if (MSSA) {
+ PA.preserve<MemorySSAAnalysis>();
+
+ if (VerifyMemorySSA)
+ MSSA->verifyMemorySSA();
+ }
+
return PA;
}
@@ -424,46 +424,46 @@ struct LegacyLoopSinkPass : public LoopPass {
if (skipLoop(L))
return false;
- BasicBlock *Preheader = L->getLoopPreheader();
- if (!Preheader)
- return false;
-
- // Enable LoopSink only when runtime profile is available.
- // With static profile, the sinking decision may be sub-optimal.
- if (!Preheader->getParent()->hasProfileData())
- return false;
-
- AAResults &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
+ BasicBlock *Preheader = L->getLoopPreheader();
+ if (!Preheader)
+ return false;
+
+ // Enable LoopSink only when runtime profile is available.
+ // With static profile, the sinking decision may be sub-optimal.
+ if (!Preheader->getParent()->hasProfileData())
+ return false;
+
+ AAResults &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
auto *SE = getAnalysisIfAvailable<ScalarEvolutionWrapperPass>();
- std::unique_ptr<AliasSetTracker> CurAST;
- MemorySSA *MSSA = nullptr;
- if (EnableMSSAInLegacyLoopSink)
- MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA();
- else {
- CurAST = std::make_unique<AliasSetTracker>(AA);
- computeAliasSet(*L, *Preheader, *CurAST.get());
- }
-
- bool Changed = sinkLoopInvariantInstructions(
- *L, AA, getAnalysis<LoopInfoWrapperPass>().getLoopInfo(),
+ std::unique_ptr<AliasSetTracker> CurAST;
+ MemorySSA *MSSA = nullptr;
+ if (EnableMSSAInLegacyLoopSink)
+ MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA();
+ else {
+ CurAST = std::make_unique<AliasSetTracker>(AA);
+ computeAliasSet(*L, *Preheader, *CurAST.get());
+ }
+
+ bool Changed = sinkLoopInvariantInstructions(
+ *L, AA, getAnalysis<LoopInfoWrapperPass>().getLoopInfo(),
getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI(),
- SE ? &SE->getSE() : nullptr, CurAST.get(), MSSA);
-
- if (MSSA && VerifyMemorySSA)
- MSSA->verifyMemorySSA();
-
- return Changed;
+ SE ? &SE->getSE() : nullptr, CurAST.get(), MSSA);
+
+ if (MSSA && VerifyMemorySSA)
+ MSSA->verifyMemorySSA();
+
+ return Changed;
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesCFG();
AU.addRequired<BlockFrequencyInfoWrapperPass>();
getLoopAnalysisUsage(AU);
- if (EnableMSSAInLegacyLoopSink) {
- AU.addRequired<MemorySSAWrapperPass>();
- AU.addPreserved<MemorySSAWrapperPass>();
- }
+ if (EnableMSSAInLegacyLoopSink) {
+ AU.addRequired<MemorySSAWrapperPass>();
+ AU.addPreserved<MemorySSAWrapperPass>();
+ }
}
};
}
@@ -473,7 +473,7 @@ INITIALIZE_PASS_BEGIN(LegacyLoopSinkPass, "loop-sink", "Loop Sink", false,
false)
INITIALIZE_PASS_DEPENDENCY(LoopPass)
INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
INITIALIZE_PASS_END(LegacyLoopSinkPass, "loop-sink", "Loop Sink", false, false)
Pass *llvm::createLoopSinkPass() { return new LegacyLoopSinkPass(); }
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index 2b2f30340a..5dec9b5420 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -75,13 +75,13 @@
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
-#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/GlobalValue.h"
@@ -424,7 +424,7 @@ static void DoInitialMatch(const SCEV *S, Loop *L,
// Handle a multiplication by -1 (negation) if it didn't fold.
if (const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(S))
if (Mul->getOperand(0)->isAllOnesValue()) {
- SmallVector<const SCEV *, 4> Ops(drop_begin(Mul->operands()));
+ SmallVector<const SCEV *, 4> Ops(drop_begin(Mul->operands()));
const SCEV *NewMul = SE.getMulExpr(Ops);
SmallVector<const SCEV *, 4> MyGood;
@@ -485,10 +485,10 @@ bool Formula::isCanonical(const Loop &L) const {
// If ScaledReg is not a recurrent expr, or it is but its loop is not current
// loop, meanwhile BaseRegs contains a recurrent expr reg related with current
// loop, we want to swap the reg in BaseRegs with ScaledReg.
- auto I = find_if(BaseRegs, [&](const SCEV *S) {
- return isa<const SCEVAddRecExpr>(S) &&
- (cast<SCEVAddRecExpr>(S)->getLoop() == &L);
- });
+ auto I = find_if(BaseRegs, [&](const SCEV *S) {
+ return isa<const SCEVAddRecExpr>(S) &&
+ (cast<SCEVAddRecExpr>(S)->getLoop() == &L);
+ });
return I == BaseRegs.end();
}
@@ -507,7 +507,7 @@ void Formula::canonicalize(const Loop &L) {
// Keep the invariant sum in BaseRegs and one of the variant sum in ScaledReg.
if (!ScaledReg) {
- ScaledReg = BaseRegs.pop_back_val();
+ ScaledReg = BaseRegs.pop_back_val();
Scale = 1;
}
@@ -516,10 +516,10 @@ void Formula::canonicalize(const Loop &L) {
// reg with ScaledReg.
const SCEVAddRecExpr *SAR = dyn_cast<const SCEVAddRecExpr>(ScaledReg);
if (!SAR || SAR->getLoop() != &L) {
- auto I = find_if(BaseRegs, [&](const SCEV *S) {
- return isa<const SCEVAddRecExpr>(S) &&
- (cast<SCEVAddRecExpr>(S)->getLoop() == &L);
- });
+ auto I = find_if(BaseRegs, [&](const SCEV *S) {
+ return isa<const SCEVAddRecExpr>(S) &&
+ (cast<SCEVAddRecExpr>(S)->getLoop() == &L);
+ });
if (I != BaseRegs.end())
std::swap(ScaledReg, *I);
}
@@ -752,13 +752,13 @@ static int64_t ExtractImmediate(const SCEV *&S, ScalarEvolution &SE) {
return C->getValue()->getSExtValue();
}
} else if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
- SmallVector<const SCEV *, 8> NewOps(Add->operands());
+ SmallVector<const SCEV *, 8> NewOps(Add->operands());
int64_t Result = ExtractImmediate(NewOps.front(), SE);
if (Result != 0)
S = SE.getAddExpr(NewOps);
return Result;
} else if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
- SmallVector<const SCEV *, 8> NewOps(AR->operands());
+ SmallVector<const SCEV *, 8> NewOps(AR->operands());
int64_t Result = ExtractImmediate(NewOps.front(), SE);
if (Result != 0)
S = SE.getAddRecExpr(NewOps, AR->getLoop(),
@@ -778,13 +778,13 @@ static GlobalValue *ExtractSymbol(const SCEV *&S, ScalarEvolution &SE) {
return GV;
}
} else if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
- SmallVector<const SCEV *, 8> NewOps(Add->operands());
+ SmallVector<const SCEV *, 8> NewOps(Add->operands());
GlobalValue *Result = ExtractSymbol(NewOps.back(), SE);
if (Result)
S = SE.getAddExpr(NewOps);
return Result;
} else if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
- SmallVector<const SCEV *, 8> NewOps(AR->operands());
+ SmallVector<const SCEV *, 8> NewOps(AR->operands());
GlobalValue *Result = ExtractSymbol(NewOps.front(), SE);
if (Result)
S = SE.getAddRecExpr(NewOps, AR->getLoop(),
@@ -934,8 +934,8 @@ static bool isHighCostExpansion(const SCEV *S,
case scSignExtend:
return isHighCostExpansion(cast<SCEVSignExtendExpr>(S)->getOperand(),
Processed, SE);
- default:
- break;
+ default:
+ break;
}
if (!Processed.insert(S).second)
@@ -1211,7 +1211,7 @@ static unsigned getSetupCost(const SCEV *Reg, unsigned Depth) {
return 0;
if (const auto *S = dyn_cast<SCEVAddRecExpr>(Reg))
return getSetupCost(S->getStart(), Depth - 1);
- if (auto S = dyn_cast<SCEVIntegralCastExpr>(Reg))
+ if (auto S = dyn_cast<SCEVIntegralCastExpr>(Reg))
return getSetupCost(S->getOperand(), Depth - 1);
if (auto S = dyn_cast<SCEVNAryExpr>(Reg))
return std::accumulate(S->op_begin(), S->op_end(), 0,
@@ -2787,7 +2787,7 @@ static const SCEV *getExprBase(const SCEV *S) {
case scAddRecExpr:
return getExprBase(cast<SCEVAddRecExpr>(S)->getStart());
}
- llvm_unreachable("Unknown SCEV kind!");
+ llvm_unreachable("Unknown SCEV kind!");
}
/// Return true if the chain increment is profitable to expand into a loop
@@ -3402,7 +3402,7 @@ LSRInstance::CollectLoopInvariantFixupsAndFormulae() {
if (const SCEVNAryExpr *N = dyn_cast<SCEVNAryExpr>(S))
Worklist.append(N->op_begin(), N->op_end());
- else if (const SCEVIntegralCastExpr *C = dyn_cast<SCEVIntegralCastExpr>(S))
+ else if (const SCEVIntegralCastExpr *C = dyn_cast<SCEVIntegralCastExpr>(S))
Worklist.push_back(C->getOperand());
else if (const SCEVUDivExpr *D = dyn_cast<SCEVUDivExpr>(S)) {
Worklist.push_back(D->getLHS());
@@ -3835,14 +3835,14 @@ void LSRInstance::GenerateConstantOffsetsImpl(
F.BaseOffset = (uint64_t)F.BaseOffset + Imm;
if (!isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy, F))
return;
- if (IsScaledReg) {
+ if (IsScaledReg) {
F.ScaledReg = G;
- } else {
+ } else {
F.BaseRegs[Idx] = G;
- // We may generate non canonical Formula if G is a recurrent expr reg
- // related with current loop while F.ScaledReg is not.
- F.canonicalize(*L);
- }
+ // We may generate non canonical Formula if G is a recurrent expr reg
+ // related with current loop while F.ScaledReg is not.
+ F.canonicalize(*L);
+ }
(void)InsertFormula(LU, LUIdx, F);
}
@@ -5383,11 +5383,11 @@ void LSRInstance::RewriteForPHI(
// Split the critical edge.
BasicBlock *NewBB = nullptr;
if (!Parent->isLandingPad()) {
- NewBB =
- SplitCriticalEdge(BB, Parent,
- CriticalEdgeSplittingOptions(&DT, &LI, MSSAU)
- .setMergeIdenticalEdges()
- .setKeepOneInputPHIs());
+ NewBB =
+ SplitCriticalEdge(BB, Parent,
+ CriticalEdgeSplittingOptions(&DT, &LI, MSSAU)
+ .setMergeIdenticalEdges()
+ .setKeepOneInputPHIs());
} else {
SmallVector<BasicBlock*, 2> NewBBs;
SplitLandingPadPredecessors(Parent, BB, "", "", NewBBs, &DT, &LI);
@@ -5520,8 +5520,8 @@ void LSRInstance::ImplementSolution(
// we can remove them after we are done working.
SmallVector<WeakTrackingVH, 16> DeadInsts;
- SCEVExpander Rewriter(SE, L->getHeader()->getModule()->getDataLayout(), "lsr",
- false);
+ SCEVExpander Rewriter(SE, L->getHeader()->getModule()->getDataLayout(), "lsr",
+ false);
#ifndef NDEBUG
Rewriter.setDebugType(DEBUG_TYPE);
#endif
@@ -5620,19 +5620,19 @@ LSRInstance::LSRInstance(Loop *L, IVUsers &IU, ScalarEvolution &SE,
if (IU.empty()) return;
// Skip nested loops until we can model them better with formulae.
- if (!L->isInnermost()) {
+ if (!L->isInnermost()) {
LLVM_DEBUG(dbgs() << "LSR skipping outer loop " << *L << "\n");
return;
}
// Start collecting data and preparing for the solver.
- // If number of registers is not the major cost, we cannot benefit from the
- // current profitable chain optimization which is based on number of
- // registers.
- // FIXME: add profitable chain optimization for other kinds major cost, for
- // example number of instructions.
- if (TTI.isNumRegsMajorCostOfLSR() || StressIVChain)
- CollectChains();
+ // If number of registers is not the major cost, we cannot benefit from the
+ // current profitable chain optimization which is based on number of
+ // registers.
+ // FIXME: add profitable chain optimization for other kinds major cost, for
+ // example number of instructions.
+ if (TTI.isNumRegsMajorCostOfLSR() || StressIVChain)
+ CollectChains();
CollectInterestingTypesAndFactors();
CollectFixupsAndInitialFormulae();
CollectLoopInvariantFixupsAndFormulae();
@@ -5772,63 +5772,63 @@ void LoopStrengthReduce::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addPreserved<MemorySSAWrapperPass>();
}
-using EqualValues = SmallVector<std::tuple<WeakVH, int64_t, DIExpression *>, 4>;
-using EqualValuesMap = DenseMap<DbgValueInst *, EqualValues>;
-
-static void DbgGatherEqualValues(Loop *L, ScalarEvolution &SE,
- EqualValuesMap &DbgValueToEqualSet) {
- for (auto &B : L->getBlocks()) {
- for (auto &I : *B) {
- auto DVI = dyn_cast<DbgValueInst>(&I);
- if (!DVI)
- continue;
- auto V = DVI->getVariableLocation();
- if (!V || !SE.isSCEVable(V->getType()))
- continue;
- auto DbgValueSCEV = SE.getSCEV(V);
- EqualValues EqSet;
- for (PHINode &Phi : L->getHeader()->phis()) {
- if (V->getType() != Phi.getType())
- continue;
- if (!SE.isSCEVable(Phi.getType()))
- continue;
- auto PhiSCEV = SE.getSCEV(&Phi);
- Optional<APInt> Offset =
- SE.computeConstantDifference(DbgValueSCEV, PhiSCEV);
- if (Offset && Offset->getMinSignedBits() <= 64)
- EqSet.emplace_back(std::make_tuple(
- &Phi, Offset.getValue().getSExtValue(), DVI->getExpression()));
- }
- DbgValueToEqualSet[DVI] = std::move(EqSet);
- }
- }
-}
-
-static void DbgApplyEqualValues(EqualValuesMap &DbgValueToEqualSet) {
- for (auto A : DbgValueToEqualSet) {
- auto DVI = A.first;
- // Only update those that are now undef.
- if (!isa_and_nonnull<UndefValue>(DVI->getVariableLocation()))
- continue;
- for (auto EV : A.second) {
- auto V = std::get<WeakVH>(EV);
- if (!V)
- continue;
- auto DbgDIExpr = std::get<DIExpression *>(EV);
- auto Offset = std::get<int64_t>(EV);
- auto &Ctx = DVI->getContext();
- DVI->setOperand(0, MetadataAsValue::get(Ctx, ValueAsMetadata::get(V)));
- if (Offset) {
- SmallVector<uint64_t, 8> Ops;
- DIExpression::appendOffset(Ops, Offset);
- DbgDIExpr = DIExpression::prependOpcodes(DbgDIExpr, Ops, true);
- }
- DVI->setOperand(2, MetadataAsValue::get(Ctx, DbgDIExpr));
- break;
- }
- }
-}
-
+using EqualValues = SmallVector<std::tuple<WeakVH, int64_t, DIExpression *>, 4>;
+using EqualValuesMap = DenseMap<DbgValueInst *, EqualValues>;
+
+static void DbgGatherEqualValues(Loop *L, ScalarEvolution &SE,
+ EqualValuesMap &DbgValueToEqualSet) {
+ for (auto &B : L->getBlocks()) {
+ for (auto &I : *B) {
+ auto DVI = dyn_cast<DbgValueInst>(&I);
+ if (!DVI)
+ continue;
+ auto V = DVI->getVariableLocation();
+ if (!V || !SE.isSCEVable(V->getType()))
+ continue;
+ auto DbgValueSCEV = SE.getSCEV(V);
+ EqualValues EqSet;
+ for (PHINode &Phi : L->getHeader()->phis()) {
+ if (V->getType() != Phi.getType())
+ continue;
+ if (!SE.isSCEVable(Phi.getType()))
+ continue;
+ auto PhiSCEV = SE.getSCEV(&Phi);
+ Optional<APInt> Offset =
+ SE.computeConstantDifference(DbgValueSCEV, PhiSCEV);
+ if (Offset && Offset->getMinSignedBits() <= 64)
+ EqSet.emplace_back(std::make_tuple(
+ &Phi, Offset.getValue().getSExtValue(), DVI->getExpression()));
+ }
+ DbgValueToEqualSet[DVI] = std::move(EqSet);
+ }
+ }
+}
+
+static void DbgApplyEqualValues(EqualValuesMap &DbgValueToEqualSet) {
+ for (auto A : DbgValueToEqualSet) {
+ auto DVI = A.first;
+ // Only update those that are now undef.
+ if (!isa_and_nonnull<UndefValue>(DVI->getVariableLocation()))
+ continue;
+ for (auto EV : A.second) {
+ auto V = std::get<WeakVH>(EV);
+ if (!V)
+ continue;
+ auto DbgDIExpr = std::get<DIExpression *>(EV);
+ auto Offset = std::get<int64_t>(EV);
+ auto &Ctx = DVI->getContext();
+ DVI->setOperand(0, MetadataAsValue::get(Ctx, ValueAsMetadata::get(V)));
+ if (Offset) {
+ SmallVector<uint64_t, 8> Ops;
+ DIExpression::appendOffset(Ops, Offset);
+ DbgDIExpr = DIExpression::prependOpcodes(DbgDIExpr, Ops, true);
+ }
+ DVI->setOperand(2, MetadataAsValue::get(Ctx, DbgDIExpr));
+ break;
+ }
+ }
+}
+
static bool ReduceLoopStrength(Loop *L, IVUsers &IU, ScalarEvolution &SE,
DominatorTree &DT, LoopInfo &LI,
const TargetTransformInfo &TTI,
@@ -5844,17 +5844,17 @@ static bool ReduceLoopStrength(Loop *L, IVUsers &IU, ScalarEvolution &SE,
Changed |=
LSRInstance(L, IU, SE, DT, LI, TTI, AC, TLI, MSSAU.get()).getChanged();
- // Debug preservation - before we start removing anything create equivalence
- // sets for the llvm.dbg.value intrinsics.
- EqualValuesMap DbgValueToEqualSet;
- DbgGatherEqualValues(L, SE, DbgValueToEqualSet);
-
+ // Debug preservation - before we start removing anything create equivalence
+ // sets for the llvm.dbg.value intrinsics.
+ EqualValuesMap DbgValueToEqualSet;
+ DbgGatherEqualValues(L, SE, DbgValueToEqualSet);
+
// Remove any extra phis created by processing inner loops.
Changed |= DeleteDeadPHIs(L->getHeader(), &TLI, MSSAU.get());
if (EnablePhiElim && L->isLoopSimplifyForm()) {
SmallVector<WeakTrackingVH, 16> DeadInsts;
const DataLayout &DL = L->getHeader()->getModule()->getDataLayout();
- SCEVExpander Rewriter(SE, DL, "lsr", false);
+ SCEVExpander Rewriter(SE, DL, "lsr", false);
#ifndef NDEBUG
Rewriter.setDebugType(DEBUG_TYPE);
#endif
@@ -5866,9 +5866,9 @@ static bool ReduceLoopStrength(Loop *L, IVUsers &IU, ScalarEvolution &SE,
DeleteDeadPHIs(L->getHeader(), &TLI, MSSAU.get());
}
}
-
- DbgApplyEqualValues(DbgValueToEqualSet);
-
+
+ DbgApplyEqualValues(DbgValueToEqualSet);
+
return Changed;
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopUnrollAndJamPass.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopUnrollAndJamPass.cpp
index d65e9dd059..495906e1a7 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopUnrollAndJamPass.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopUnrollAndJamPass.cpp
@@ -41,7 +41,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h"
-#include "llvm/Transforms/Utils/LoopPeel.h"
+#include "llvm/Transforms/Utils/LoopPeel.h"
#include "llvm/Transforms/Utils/LoopSimplify.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
#include "llvm/Transforms/Utils/UnrollLoop.h"
@@ -288,13 +288,13 @@ tryToUnrollAndJamLoop(Loop *L, DominatorTree &DT, LoopInfo *LI,
None, None, None, None, None);
TargetTransformInfo::PeelingPreferences PP =
gatherPeelingPreferences(L, SE, TTI, None, None);
-
- TransformationMode EnableMode = hasUnrollAndJamTransformation(L);
- if (EnableMode & TM_Disable)
- return LoopUnrollResult::Unmodified;
- if (EnableMode & TM_ForcedByUser)
- UP.UnrollAndJam = true;
-
+
+ TransformationMode EnableMode = hasUnrollAndJamTransformation(L);
+ if (EnableMode & TM_Disable)
+ return LoopUnrollResult::Unmodified;
+ if (EnableMode & TM_ForcedByUser)
+ UP.UnrollAndJam = true;
+
if (AllowUnrollAndJam.getNumOccurrences() > 0)
UP.UnrollAndJam = AllowUnrollAndJam;
if (UnrollAndJamThreshold.getNumOccurrences() > 0)
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopUnrollPass.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopUnrollPass.cpp
index de36dce3a0..1b974576a3 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopUnrollPass.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopUnrollPass.cpp
@@ -56,7 +56,7 @@
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Scalar/LoopPassManager.h"
#include "llvm/Transforms/Utils.h"
-#include "llvm/Transforms/Utils/LoopPeel.h"
+#include "llvm/Transforms/Utils/LoopPeel.h"
#include "llvm/Transforms/Utils/LoopSimplify.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
#include "llvm/Transforms/Utils/SizeOpts.h"
@@ -76,19 +76,19 @@ using namespace llvm;
cl::opt<bool> llvm::ForgetSCEVInLoopUnroll(
"forget-scev-loop-unroll", cl::init(false), cl::Hidden,
cl::desc("Forget everything in SCEV when doing LoopUnroll, instead of just"
- " the current top-most loop. This is sometimes preferred to reduce"
+ " the current top-most loop. This is sometimes preferred to reduce"
" compile time."));
static cl::opt<unsigned>
UnrollThreshold("unroll-threshold", cl::Hidden,
cl::desc("The cost threshold for loop unrolling"));
-static cl::opt<unsigned>
- UnrollOptSizeThreshold(
- "unroll-optsize-threshold", cl::init(0), cl::Hidden,
- cl::desc("The cost threshold for loop unrolling when optimizing for "
- "size"));
-
+static cl::opt<unsigned>
+ UnrollOptSizeThreshold(
+ "unroll-optsize-threshold", cl::init(0), cl::Hidden,
+ cl::desc("The cost threshold for loop unrolling when optimizing for "
+ "size"));
+
static cl::opt<unsigned> UnrollPartialThreshold(
"unroll-partial-threshold", cl::Hidden,
cl::desc("The cost threshold for partial loop unrolling"));
@@ -194,9 +194,9 @@ TargetTransformInfo::UnrollingPreferences llvm::gatherUnrollingPreferences(
UP.Threshold =
OptLevel > 2 ? UnrollThresholdAggressive : UnrollThresholdDefault;
UP.MaxPercentThresholdBoost = 400;
- UP.OptSizeThreshold = UnrollOptSizeThreshold;
+ UP.OptSizeThreshold = UnrollOptSizeThreshold;
UP.PartialThreshold = 150;
- UP.PartialOptSizeThreshold = UnrollOptSizeThreshold;
+ UP.PartialOptSizeThreshold = UnrollOptSizeThreshold;
UP.Count = 0;
UP.DefaultUnrollRuntimeCount = 8;
UP.MaxCount = std::numeric_limits<unsigned>::max();
@@ -218,10 +218,10 @@ TargetTransformInfo::UnrollingPreferences llvm::gatherUnrollingPreferences(
// Apply size attributes
bool OptForSize = L->getHeader()->getParent()->hasOptSize() ||
- // Let unroll hints / pragmas take precedence over PGSO.
- (hasUnrollTransformation(L) != TM_ForcedByUser &&
- llvm::shouldOptimizeForSize(L->getHeader(), PSI, BFI,
- PGSOQueryType::IRPass));
+ // Let unroll hints / pragmas take precedence over PGSO.
+ (hasUnrollTransformation(L) != TM_ForcedByUser &&
+ llvm::shouldOptimizeForSize(L->getHeader(), PSI, BFI,
+ PGSOQueryType::IRPass));
if (OptForSize) {
UP.Threshold = UP.OptSizeThreshold;
UP.PartialThreshold = UP.PartialOptSizeThreshold;
@@ -347,7 +347,7 @@ static Optional<EstimatedUnrollCost> analyzeLoopUnrollCost(
// Only analyze inner loops. We can't properly estimate cost of nested loops
// and we won't visit inner loops again anyway.
- if (!L->isInnermost())
+ if (!L->isInnermost())
return None;
// Don't simulate loops with a big or unknown tripcount
@@ -389,10 +389,10 @@ static Optional<EstimatedUnrollCost> analyzeLoopUnrollCost(
assert(CostWorklist.empty() && "Must start with an empty cost list");
assert(PHIUsedList.empty() && "Must start with an empty phi used list");
CostWorklist.push_back(&RootI);
- TargetTransformInfo::TargetCostKind CostKind =
- RootI.getFunction()->hasMinSize() ?
- TargetTransformInfo::TCK_CodeSize :
- TargetTransformInfo::TCK_SizeAndLatency;
+ TargetTransformInfo::TargetCostKind CostKind =
+ RootI.getFunction()->hasMinSize() ?
+ TargetTransformInfo::TCK_CodeSize :
+ TargetTransformInfo::TCK_SizeAndLatency;
for (;; --Iteration) {
do {
Instruction *I = CostWorklist.pop_back_val();
@@ -433,7 +433,7 @@ static Optional<EstimatedUnrollCost> analyzeLoopUnrollCost(
// First accumulate the cost of this instruction.
if (!Cost.IsFree) {
- UnrolledCost += TTI.getUserCost(I, CostKind);
+ UnrolledCost += TTI.getUserCost(I, CostKind);
LLVM_DEBUG(dbgs() << "Adding cost of instruction (iteration "
<< Iteration << "): ");
LLVM_DEBUG(I->dump());
@@ -473,9 +473,9 @@ static Optional<EstimatedUnrollCost> analyzeLoopUnrollCost(
LLVM_DEBUG(dbgs() << "Starting LoopUnroll profitability analysis...\n");
- TargetTransformInfo::TargetCostKind CostKind =
- L->getHeader()->getParent()->hasMinSize() ?
- TargetTransformInfo::TCK_CodeSize : TargetTransformInfo::TCK_SizeAndLatency;
+ TargetTransformInfo::TargetCostKind CostKind =
+ L->getHeader()->getParent()->hasMinSize() ?
+ TargetTransformInfo::TCK_CodeSize : TargetTransformInfo::TCK_SizeAndLatency;
// Simulate execution of each iteration of the loop counting instructions,
// which would be simplified.
// Since the same load will take different values on different iterations,
@@ -529,7 +529,7 @@ static Optional<EstimatedUnrollCost> analyzeLoopUnrollCost(
// Track this instruction's expected baseline cost when executing the
// rolled loop form.
- RolledDynamicCost += TTI.getUserCost(&I, CostKind);
+ RolledDynamicCost += TTI.getUserCost(&I, CostKind);
// Visit the instruction to analyze its loop cost after unrolling,
// and if the visitor returns true, mark the instruction as free after
@@ -851,7 +851,7 @@ bool llvm::computeUnrollCount(
}
// 4th priority is loop peeling.
- computePeelCount(L, LoopSize, PP, TripCount, SE, UP.Threshold);
+ computePeelCount(L, LoopSize, PP, TripCount, SE, UP.Threshold);
if (PP.PeelCount) {
UP.Runtime = false;
UP.Count = 1;
@@ -1043,7 +1043,7 @@ static LoopUnrollResult tryToUnrollLoop(
return LoopUnrollResult::Unmodified;
}
- // When automatic unrolling is disabled, do not unroll unless overridden for
+ // When automatic unrolling is disabled, do not unroll unless overridden for
// this loop.
if (OnlyWhenForced && !(TM & TM_Enable))
return LoopUnrollResult::Unmodified;
@@ -1057,7 +1057,7 @@ static LoopUnrollResult tryToUnrollLoop(
ProvidedAllowPartial, ProvidedRuntime, ProvidedUpperBound,
ProvidedFullUnrollMaxCount);
TargetTransformInfo::PeelingPreferences PP = gatherPeelingPreferences(
- L, SE, TTI, ProvidedAllowPeeling, ProvidedAllowProfileBasedPeeling, true);
+ L, SE, TTI, ProvidedAllowPeeling, ProvidedAllowProfileBasedPeeling, true);
// Exit early if unrolling is disabled. For OptForSize, we pick the loop size
// as threshold later on.
@@ -1105,7 +1105,7 @@ static LoopUnrollResult tryToUnrollLoop(
// If the loop contains a convergent operation, the prelude we'd add
// to do the first few instructions before we hit the unrolled loop
// is unsafe -- it adds a control-flow dependency to the convergent
- // operation. Therefore restrict remainder loop (try unrolling without).
+ // operation. Therefore restrict remainder loop (try unrolling without).
//
// TODO: This is quite conservative. In practice, convergent_op()
// is likely to be called unconditionally in the loop. In this
@@ -1301,7 +1301,7 @@ Pass *llvm::createLoopUnrollPass(int OptLevel, bool OnlyWhenForced,
Pass *llvm::createSimpleLoopUnrollPass(int OptLevel, bool OnlyWhenForced,
bool ForgetAllSCEV) {
return createLoopUnrollPass(OptLevel, OnlyWhenForced, ForgetAllSCEV, -1, -1,
- 0, 0, 0, 1);
+ 0, 0, 0, 1);
}
PreservedAnalyses LoopFullUnrollPass::run(Loop &L, LoopAnalysisManager &AM,
@@ -1329,7 +1329,7 @@ PreservedAnalyses LoopFullUnrollPass::run(Loop &L, LoopAnalysisManager &AM,
OnlyWhenForced, ForgetSCEV, /*Count*/ None,
/*Threshold*/ None, /*AllowPartial*/ false,
/*Runtime*/ false, /*UpperBound*/ false,
- /*AllowPeeling*/ true,
+ /*AllowPeeling*/ true,
/*AllowProfileBasedPeeling*/ false,
/*FullUnrollMaxCount*/ None) !=
LoopUnrollResult::Unmodified;
@@ -1371,7 +1371,7 @@ PreservedAnalyses LoopFullUnrollPass::run(Loop &L, LoopAnalysisManager &AM,
}
// Otherwise erase the loop from the list if it was in the old loops.
- return OldLoops.contains(SibLoop);
+ return OldLoops.contains(SibLoop);
});
Updater.addSiblingLoops(SibLoops);
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopUnswitch.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopUnswitch.cpp
index 843be6cbb9..822a786fc7 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopUnswitch.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopUnswitch.cpp
@@ -32,7 +32,7 @@
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/CodeMetrics.h"
#include "llvm/Analysis/InstructionSimplify.h"
-#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
+#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
#include "llvm/Analysis/LegacyDivergenceAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopIterator.h"
@@ -99,12 +99,12 @@ static cl::opt<unsigned>
Threshold("loop-unswitch-threshold", cl::desc("Max loop size to unswitch"),
cl::init(100), cl::Hidden);
-static cl::opt<unsigned>
- MSSAThreshold("loop-unswitch-memoryssa-threshold",
- cl::desc("Max number of memory uses to explore during "
- "partial unswitching analysis"),
- cl::init(100), cl::Hidden);
-
+static cl::opt<unsigned>
+ MSSAThreshold("loop-unswitch-memoryssa-threshold",
+ cl::desc("Max number of memory uses to explore during "
+ "partial unswitching analysis"),
+ cl::init(100), cl::Hidden);
+
namespace {
class LUAnalysisCache {
@@ -191,7 +191,7 @@ namespace {
Loop *CurrentLoop = nullptr;
DominatorTree *DT = nullptr;
MemorySSA *MSSA = nullptr;
- AAResults *AA = nullptr;
+ AAResults *AA = nullptr;
std::unique_ptr<MemorySSAUpdater> MSSAU;
BasicBlock *LoopHeader = nullptr;
BasicBlock *LoopPreheader = nullptr;
@@ -225,10 +225,10 @@ namespace {
/// loop preheaders be inserted into the CFG.
///
void getAnalysisUsage(AnalysisUsage &AU) const override {
- // Lazy BFI and BPI are marked as preserved here so Loop Unswitching
- // can remain part of the same loop pass as LICM
- AU.addPreserved<LazyBlockFrequencyInfoPass>();
- AU.addPreserved<LazyBranchProbabilityInfoPass>();
+ // Lazy BFI and BPI are marked as preserved here so Loop Unswitching
+ // can remain part of the same loop pass as LICM
+ AU.addPreserved<LazyBlockFrequencyInfoPass>();
+ AU.addPreserved<LazyBranchProbabilityInfoPass>();
AU.addRequired<AssumptionCacheTracker>();
AU.addRequired<TargetTransformInfoWrapperPass>();
if (EnableMSSALoopDependency) {
@@ -256,22 +256,22 @@ namespace {
bool tryTrivialLoopUnswitch(bool &Changed);
bool unswitchIfProfitable(Value *LoopCond, Constant *Val,
- Instruction *TI = nullptr,
- ArrayRef<Instruction *> ToDuplicate = {});
+ Instruction *TI = nullptr,
+ ArrayRef<Instruction *> ToDuplicate = {});
void unswitchTrivialCondition(Loop *L, Value *Cond, Constant *Val,
BasicBlock *ExitBlock, Instruction *TI);
void unswitchNontrivialCondition(Value *LIC, Constant *OnVal, Loop *L,
- Instruction *TI,
- ArrayRef<Instruction *> ToDuplicate = {});
+ Instruction *TI,
+ ArrayRef<Instruction *> ToDuplicate = {});
void rewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
Constant *Val, bool IsEqual);
- void
- emitPreheaderBranchOnCondition(Value *LIC, Constant *Val,
- BasicBlock *TrueDest, BasicBlock *FalseDest,
- BranchInst *OldBranch, Instruction *TI,
- ArrayRef<Instruction *> ToDuplicate = {});
+ void
+ emitPreheaderBranchOnCondition(Value *LIC, Constant *Val,
+ BasicBlock *TrueDest, BasicBlock *FalseDest,
+ BranchInst *OldBranch, Instruction *TI,
+ ArrayRef<Instruction *> ToDuplicate = {});
void simplifyCode(std::vector<Instruction *> &Worklist, Loop *L);
@@ -538,7 +538,7 @@ bool LoopUnswitch::runOnLoop(Loop *L, LPPassManager &LPMRef) {
LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
LPM = &LPMRef;
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
+ AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
if (EnableMSSALoopDependency) {
MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA();
MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
@@ -640,145 +640,145 @@ static bool equalityPropUnSafe(Value &LoopCond) {
return false;
}
-/// Check if the loop header has a conditional branch that is not
-/// loop-invariant, because it involves load instructions. If all paths from
-/// either the true or false successor to the header or loop exists do not
-/// modify the memory feeding the condition, perform 'partial unswitching'. That
-/// is, duplicate the instructions feeding the condition in the pre-header. Then
-/// unswitch on the duplicated condition. The condition is now known in the
-/// unswitched version for the 'invariant' path through the original loop.
-///
-/// If the branch condition of the header is partially invariant, return a pair
-/// containing the instructions to duplicate and a boolean Constant to update
-/// the condition in the loops created for the true or false successors.
-static std::pair<SmallVector<Instruction *, 4>, Constant *>
-hasPartialIVCondition(Loop *L, MemorySSA &MSSA, AAResults *AA) {
- SmallVector<Instruction *, 4> ToDuplicate;
-
- auto *TI = dyn_cast<BranchInst>(L->getHeader()->getTerminator());
- if (!TI || !TI->isConditional())
- return {};
-
- auto *CondI = dyn_cast<CmpInst>(TI->getCondition());
- // The case with the condition outside the loop should already be handled
- // earlier.
- if (!CondI || !L->contains(CondI))
- return {};
-
- ToDuplicate.push_back(CondI);
-
- SmallVector<Value *, 4> WorkList;
- WorkList.append(CondI->op_begin(), CondI->op_end());
-
- SmallVector<MemoryAccess *, 4> AccessesToCheck;
- SmallVector<MemoryLocation, 4> AccessedLocs;
- while (!WorkList.empty()) {
- Instruction *I = dyn_cast<Instruction>(WorkList.pop_back_val());
- if (!I || !L->contains(I))
- continue;
-
- // TODO: support additional instructions.
- if (!isa<LoadInst>(I) && !isa<GetElementPtrInst>(I))
- return {};
-
- // Do not duplicate volatile and atomic loads.
- if (auto *LI = dyn_cast<LoadInst>(I))
- if (LI->isVolatile() || LI->isAtomic())
- return {};
-
- ToDuplicate.push_back(I);
- if (MemoryAccess *MA = MSSA.getMemoryAccess(I)) {
- if (auto *MemUse = dyn_cast_or_null<MemoryUse>(MA)) {
- // Queue the defining access to check for alias checks.
- AccessesToCheck.push_back(MemUse->getDefiningAccess());
- AccessedLocs.push_back(MemoryLocation::get(I));
- } else {
- // MemoryDefs may clobber the location or may be atomic memory
- // operations. Bail out.
- return {};
- }
- }
- WorkList.append(I->op_begin(), I->op_end());
- }
-
- if (ToDuplicate.size() <= 1)
- return {};
-
- auto HasNoClobbersOnPath =
- [L, AA, &AccessedLocs](BasicBlock *Succ, BasicBlock *Header,
- SmallVector<MemoryAccess *, 4> AccessesToCheck) {
- // First, collect all blocks in the loop that are on a patch from Succ
- // to the header.
- SmallVector<BasicBlock *, 4> WorkList;
- WorkList.push_back(Succ);
- WorkList.push_back(Header);
- SmallPtrSet<BasicBlock *, 4> Seen;
- Seen.insert(Header);
- while (!WorkList.empty()) {
- BasicBlock *Current = WorkList.pop_back_val();
- if (!L->contains(Current))
- continue;
- const auto &SeenIns = Seen.insert(Current);
- if (!SeenIns.second)
- continue;
-
- WorkList.append(succ_begin(Current), succ_end(Current));
- }
-
- // Require at least 2 blocks on a path through the loop. This skips
- // paths that directly exit the loop.
- if (Seen.size() < 2)
- return false;
-
- // Next, check if there are any MemoryDefs that are on the path through
- // the loop (in the Seen set) and they may-alias any of the locations in
- // AccessedLocs. If that is the case, they may modify the condition and
- // partial unswitching is not possible.
- SmallPtrSet<MemoryAccess *, 4> SeenAccesses;
- while (!AccessesToCheck.empty()) {
- MemoryAccess *Current = AccessesToCheck.pop_back_val();
- auto SeenI = SeenAccesses.insert(Current);
- if (!SeenI.second || !Seen.contains(Current->getBlock()))
- continue;
-
- // Bail out if exceeded the threshold.
- if (SeenAccesses.size() >= MSSAThreshold)
- return false;
-
- // MemoryUse are read-only accesses.
- if (isa<MemoryUse>(Current))
- continue;
-
- // For a MemoryDef, check if is aliases any of the location feeding
- // the original condition.
- if (auto *CurrentDef = dyn_cast<MemoryDef>(Current)) {
- if (any_of(AccessedLocs, [AA, CurrentDef](MemoryLocation &Loc) {
- return isModSet(
- AA->getModRefInfo(CurrentDef->getMemoryInst(), Loc));
- }))
- return false;
- }
-
- for (Use &U : Current->uses())
- AccessesToCheck.push_back(cast<MemoryAccess>(U.getUser()));
- }
-
- return true;
- };
-
- // If we branch to the same successor, partial unswitching will not be
- // beneficial.
- if (TI->getSuccessor(0) == TI->getSuccessor(1))
- return {};
-
- if (HasNoClobbersOnPath(TI->getSuccessor(0), L->getHeader(), AccessesToCheck))
- return {ToDuplicate, ConstantInt::getTrue(TI->getContext())};
- if (HasNoClobbersOnPath(TI->getSuccessor(1), L->getHeader(), AccessesToCheck))
- return {ToDuplicate, ConstantInt::getFalse(TI->getContext())};
-
- return {};
-}
-
+/// Check if the loop header has a conditional branch that is not
+/// loop-invariant, because it involves load instructions. If all paths from
+/// either the true or false successor to the header or loop exists do not
+/// modify the memory feeding the condition, perform 'partial unswitching'. That
+/// is, duplicate the instructions feeding the condition in the pre-header. Then
+/// unswitch on the duplicated condition. The condition is now known in the
+/// unswitched version for the 'invariant' path through the original loop.
+///
+/// If the branch condition of the header is partially invariant, return a pair
+/// containing the instructions to duplicate and a boolean Constant to update
+/// the condition in the loops created for the true or false successors.
+static std::pair<SmallVector<Instruction *, 4>, Constant *>
+hasPartialIVCondition(Loop *L, MemorySSA &MSSA, AAResults *AA) {
+ SmallVector<Instruction *, 4> ToDuplicate;
+
+ auto *TI = dyn_cast<BranchInst>(L->getHeader()->getTerminator());
+ if (!TI || !TI->isConditional())
+ return {};
+
+ auto *CondI = dyn_cast<CmpInst>(TI->getCondition());
+ // The case with the condition outside the loop should already be handled
+ // earlier.
+ if (!CondI || !L->contains(CondI))
+ return {};
+
+ ToDuplicate.push_back(CondI);
+
+ SmallVector<Value *, 4> WorkList;
+ WorkList.append(CondI->op_begin(), CondI->op_end());
+
+ SmallVector<MemoryAccess *, 4> AccessesToCheck;
+ SmallVector<MemoryLocation, 4> AccessedLocs;
+ while (!WorkList.empty()) {
+ Instruction *I = dyn_cast<Instruction>(WorkList.pop_back_val());
+ if (!I || !L->contains(I))
+ continue;
+
+ // TODO: support additional instructions.
+ if (!isa<LoadInst>(I) && !isa<GetElementPtrInst>(I))
+ return {};
+
+ // Do not duplicate volatile and atomic loads.
+ if (auto *LI = dyn_cast<LoadInst>(I))
+ if (LI->isVolatile() || LI->isAtomic())
+ return {};
+
+ ToDuplicate.push_back(I);
+ if (MemoryAccess *MA = MSSA.getMemoryAccess(I)) {
+ if (auto *MemUse = dyn_cast_or_null<MemoryUse>(MA)) {
+ // Queue the defining access to check for alias checks.
+ AccessesToCheck.push_back(MemUse->getDefiningAccess());
+ AccessedLocs.push_back(MemoryLocation::get(I));
+ } else {
+ // MemoryDefs may clobber the location or may be atomic memory
+ // operations. Bail out.
+ return {};
+ }
+ }
+ WorkList.append(I->op_begin(), I->op_end());
+ }
+
+ if (ToDuplicate.size() <= 1)
+ return {};
+
+ auto HasNoClobbersOnPath =
+ [L, AA, &AccessedLocs](BasicBlock *Succ, BasicBlock *Header,
+ SmallVector<MemoryAccess *, 4> AccessesToCheck) {
+ // First, collect all blocks in the loop that are on a patch from Succ
+ // to the header.
+ SmallVector<BasicBlock *, 4> WorkList;
+ WorkList.push_back(Succ);
+ WorkList.push_back(Header);
+ SmallPtrSet<BasicBlock *, 4> Seen;
+ Seen.insert(Header);
+ while (!WorkList.empty()) {
+ BasicBlock *Current = WorkList.pop_back_val();
+ if (!L->contains(Current))
+ continue;
+ const auto &SeenIns = Seen.insert(Current);
+ if (!SeenIns.second)
+ continue;
+
+ WorkList.append(succ_begin(Current), succ_end(Current));
+ }
+
+ // Require at least 2 blocks on a path through the loop. This skips
+ // paths that directly exit the loop.
+ if (Seen.size() < 2)
+ return false;
+
+ // Next, check if there are any MemoryDefs that are on the path through
+ // the loop (in the Seen set) and they may-alias any of the locations in
+ // AccessedLocs. If that is the case, they may modify the condition and
+ // partial unswitching is not possible.
+ SmallPtrSet<MemoryAccess *, 4> SeenAccesses;
+ while (!AccessesToCheck.empty()) {
+ MemoryAccess *Current = AccessesToCheck.pop_back_val();
+ auto SeenI = SeenAccesses.insert(Current);
+ if (!SeenI.second || !Seen.contains(Current->getBlock()))
+ continue;
+
+ // Bail out if exceeded the threshold.
+ if (SeenAccesses.size() >= MSSAThreshold)
+ return false;
+
+ // MemoryUse are read-only accesses.
+ if (isa<MemoryUse>(Current))
+ continue;
+
+ // For a MemoryDef, check if is aliases any of the location feeding
+ // the original condition.
+ if (auto *CurrentDef = dyn_cast<MemoryDef>(Current)) {
+ if (any_of(AccessedLocs, [AA, CurrentDef](MemoryLocation &Loc) {
+ return isModSet(
+ AA->getModRefInfo(CurrentDef->getMemoryInst(), Loc));
+ }))
+ return false;
+ }
+
+ for (Use &U : Current->uses())
+ AccessesToCheck.push_back(cast<MemoryAccess>(U.getUser()));
+ }
+
+ return true;
+ };
+
+ // If we branch to the same successor, partial unswitching will not be
+ // beneficial.
+ if (TI->getSuccessor(0) == TI->getSuccessor(1))
+ return {};
+
+ if (HasNoClobbersOnPath(TI->getSuccessor(0), L->getHeader(), AccessesToCheck))
+ return {ToDuplicate, ConstantInt::getTrue(TI->getContext())};
+ if (HasNoClobbersOnPath(TI->getSuccessor(1), L->getHeader(), AccessesToCheck))
+ return {ToDuplicate, ConstantInt::getFalse(TI->getContext())};
+
+ return {};
+}
+
/// Do actual work and unswitch loop if possible and profitable.
bool LoopUnswitch::processCurrentLoop() {
bool Changed = false;
@@ -816,7 +816,7 @@ bool LoopUnswitch::processCurrentLoop() {
// FIXME: Use Function::hasOptSize().
if (OptimizeForSize ||
LoopHeader->getParent()->hasFnAttribute(Attribute::OptimizeForSize))
- return Changed;
+ return Changed;
// Run through the instructions in the loop, keeping track of three things:
//
@@ -840,10 +840,10 @@ bool LoopUnswitch::processCurrentLoop() {
if (!CB)
continue;
if (CB->isConvergent())
- return Changed;
+ return Changed;
if (auto *II = dyn_cast<InvokeInst>(&I))
if (!II->getUnwindDest()->canSplitPredecessors())
- return Changed;
+ return Changed;
if (auto *II = dyn_cast<IntrinsicInst>(&I))
if (II->getIntrinsicID() == Intrinsic::experimental_guard)
Guards.push_back(II);
@@ -978,28 +978,28 @@ bool LoopUnswitch::processCurrentLoop() {
}
}
}
-
- // Check if there is a header condition that is invariant along the patch from
- // either the true or false successors to the header. This allows unswitching
- // conditions depending on memory accesses, if there's a path not clobbering
- // the memory locations. Check if this transform has been disabled using
- // metadata, to avoid unswitching the same loop multiple times.
- if (MSSA &&
- !findOptionMDForLoop(CurrentLoop, "llvm.loop.unswitch.partial.disable")) {
- auto ToDuplicate = hasPartialIVCondition(CurrentLoop, *MSSA, AA);
- if (!ToDuplicate.first.empty()) {
- LLVM_DEBUG(dbgs() << "loop-unswitch: Found partially invariant condition "
- << *ToDuplicate.first[0] << "\n");
- ++NumBranches;
- unswitchIfProfitable(ToDuplicate.first[0], ToDuplicate.second,
- CurrentLoop->getHeader()->getTerminator(),
- ToDuplicate.first);
-
- RedoLoop = false;
- return true;
- }
- }
-
+
+ // Check if there is a header condition that is invariant along the patch from
+ // either the true or false successors to the header. This allows unswitching
+ // conditions depending on memory accesses, if there's a path not clobbering
+ // the memory locations. Check if this transform has been disabled using
+ // metadata, to avoid unswitching the same loop multiple times.
+ if (MSSA &&
+ !findOptionMDForLoop(CurrentLoop, "llvm.loop.unswitch.partial.disable")) {
+ auto ToDuplicate = hasPartialIVCondition(CurrentLoop, *MSSA, AA);
+ if (!ToDuplicate.first.empty()) {
+ LLVM_DEBUG(dbgs() << "loop-unswitch: Found partially invariant condition "
+ << *ToDuplicate.first[0] << "\n");
+ ++NumBranches;
+ unswitchIfProfitable(ToDuplicate.first[0], ToDuplicate.second,
+ CurrentLoop->getHeader()->getTerminator(),
+ ToDuplicate.first);
+
+ RedoLoop = false;
+ return true;
+ }
+ }
+
return Changed;
}
@@ -1057,8 +1057,8 @@ static BasicBlock *isTrivialLoopExitBlock(Loop *L, BasicBlock *BB) {
/// simplify the loop. If we decide that this is profitable,
/// unswitch the loop, reprocess the pieces, then return true.
bool LoopUnswitch::unswitchIfProfitable(Value *LoopCond, Constant *Val,
- Instruction *TI,
- ArrayRef<Instruction *> ToDuplicate) {
+ Instruction *TI,
+ ArrayRef<Instruction *> ToDuplicate) {
// Check to see if it would be profitable to unswitch current loop.
if (!BranchesInfo.costAllowsUnswitching()) {
LLVM_DEBUG(dbgs() << "NOT unswitching loop %"
@@ -1078,69 +1078,69 @@ bool LoopUnswitch::unswitchIfProfitable(Value *LoopCond, Constant *Val,
return false;
}
- unswitchNontrivialCondition(LoopCond, Val, CurrentLoop, TI, ToDuplicate);
+ unswitchNontrivialCondition(LoopCond, Val, CurrentLoop, TI, ToDuplicate);
return true;
}
/// Emit a conditional branch on two values if LIC == Val, branch to TrueDst,
/// otherwise branch to FalseDest. Insert the code immediately before OldBranch
/// and remove (but not erase!) it from the function.
-void LoopUnswitch::emitPreheaderBranchOnCondition(
- Value *LIC, Constant *Val, BasicBlock *TrueDest, BasicBlock *FalseDest,
- BranchInst *OldBranch, Instruction *TI,
- ArrayRef<Instruction *> ToDuplicate) {
+void LoopUnswitch::emitPreheaderBranchOnCondition(
+ Value *LIC, Constant *Val, BasicBlock *TrueDest, BasicBlock *FalseDest,
+ BranchInst *OldBranch, Instruction *TI,
+ ArrayRef<Instruction *> ToDuplicate) {
assert(OldBranch->isUnconditional() && "Preheader is not split correctly");
assert(TrueDest != FalseDest && "Branch targets should be different");
-
+
// Insert a conditional branch on LIC to the two preheaders. The original
// code is the true version and the new code is the false version.
Value *BranchVal = LIC;
bool Swapped = false;
-
- if (!ToDuplicate.empty()) {
- ValueToValueMapTy Old2New;
- for (Instruction *I : reverse(ToDuplicate)) {
- auto *New = I->clone();
- New->insertBefore(OldBranch);
- RemapInstruction(New, Old2New,
- RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
- Old2New[I] = New;
-
- if (MSSAU) {
- MemorySSA *MSSA = MSSAU->getMemorySSA();
- auto *MemA = dyn_cast_or_null<MemoryUse>(MSSA->getMemoryAccess(I));
- if (!MemA)
- continue;
-
- Loop *L = LI->getLoopFor(I->getParent());
- auto *DefiningAccess = MemA->getDefiningAccess();
- // Get the first defining access before the loop.
- while (L->contains(DefiningAccess->getBlock())) {
- // If the defining access is a MemoryPhi, get the incoming
- // value for the pre-header as defining access.
- if (auto *MemPhi = dyn_cast<MemoryPhi>(DefiningAccess)) {
- DefiningAccess =
- MemPhi->getIncomingValueForBlock(L->getLoopPreheader());
- } else {
- DefiningAccess =
- cast<MemoryDef>(DefiningAccess)->getDefiningAccess();
- }
- }
- MSSAU->createMemoryAccessInBB(New, DefiningAccess, New->getParent(),
- MemorySSA::BeforeTerminator);
- }
- }
- BranchVal = Old2New[ToDuplicate[0]];
- } else {
-
- if (!isa<ConstantInt>(Val) ||
- Val->getType() != Type::getInt1Ty(LIC->getContext()))
- BranchVal = new ICmpInst(OldBranch, ICmpInst::ICMP_EQ, LIC, Val);
- else if (Val != ConstantInt::getTrue(Val->getContext())) {
- // We want to enter the new loop when the condition is true.
- std::swap(TrueDest, FalseDest);
- Swapped = true;
- }
+
+ if (!ToDuplicate.empty()) {
+ ValueToValueMapTy Old2New;
+ for (Instruction *I : reverse(ToDuplicate)) {
+ auto *New = I->clone();
+ New->insertBefore(OldBranch);
+ RemapInstruction(New, Old2New,
+ RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
+ Old2New[I] = New;
+
+ if (MSSAU) {
+ MemorySSA *MSSA = MSSAU->getMemorySSA();
+ auto *MemA = dyn_cast_or_null<MemoryUse>(MSSA->getMemoryAccess(I));
+ if (!MemA)
+ continue;
+
+ Loop *L = LI->getLoopFor(I->getParent());
+ auto *DefiningAccess = MemA->getDefiningAccess();
+ // Get the first defining access before the loop.
+ while (L->contains(DefiningAccess->getBlock())) {
+ // If the defining access is a MemoryPhi, get the incoming
+ // value for the pre-header as defining access.
+ if (auto *MemPhi = dyn_cast<MemoryPhi>(DefiningAccess)) {
+ DefiningAccess =
+ MemPhi->getIncomingValueForBlock(L->getLoopPreheader());
+ } else {
+ DefiningAccess =
+ cast<MemoryDef>(DefiningAccess)->getDefiningAccess();
+ }
+ }
+ MSSAU->createMemoryAccessInBB(New, DefiningAccess, New->getParent(),
+ MemorySSA::BeforeTerminator);
+ }
+ }
+ BranchVal = Old2New[ToDuplicate[0]];
+ } else {
+
+ if (!isa<ConstantInt>(Val) ||
+ Val->getType() != Type::getInt1Ty(LIC->getContext()))
+ BranchVal = new ICmpInst(OldBranch, ICmpInst::ICMP_EQ, LIC, Val);
+ else if (Val != ConstantInt::getTrue(Val->getContext())) {
+ // We want to enter the new loop when the condition is true.
+ std::swap(TrueDest, FalseDest);
+ Swapped = true;
+ }
}
// Old branch will be removed, so save its parent and successor to update the
@@ -1173,9 +1173,9 @@ void LoopUnswitch::emitPreheaderBranchOnCondition(
}
if (MSSAU)
- MSSAU->applyUpdates(Updates, *DT, /*UpdateDT=*/true);
- else
- DT->applyUpdates(Updates);
+ MSSAU->applyUpdates(Updates, *DT, /*UpdateDT=*/true);
+ else
+ DT->applyUpdates(Updates);
}
// If either edge is critical, split it. This helps preserve LoopSimplify
@@ -1424,9 +1424,9 @@ void LoopUnswitch::splitExitEdges(
/// We determined that the loop is profitable to unswitch when LIC equal Val.
/// Split it into loop versions and test the condition outside of either loop.
/// Return the loops created as Out1/Out2.
-void LoopUnswitch::unswitchNontrivialCondition(
- Value *LIC, Constant *Val, Loop *L, Instruction *TI,
- ArrayRef<Instruction *> ToDuplicate) {
+void LoopUnswitch::unswitchNontrivialCondition(
+ Value *LIC, Constant *Val, Loop *L, Instruction *TI,
+ ArrayRef<Instruction *> ToDuplicate) {
Function *F = LoopHeader->getParent();
LLVM_DEBUG(dbgs() << "loop-unswitch: Unswitching loop %"
<< LoopHeader->getName() << " [" << L->getBlocks().size()
@@ -1451,7 +1451,7 @@ void LoopUnswitch::unswitchNontrivialCondition(
LoopBlocks.push_back(NewPreheader);
// We want the loop to come after the preheader, but before the exit blocks.
- llvm::append_range(LoopBlocks, L->blocks());
+ llvm::append_range(LoopBlocks, L->blocks());
SmallVector<BasicBlock*, 8> ExitBlocks;
L->getUniqueExitBlocks(ExitBlocks);
@@ -1465,7 +1465,7 @@ void LoopUnswitch::unswitchNontrivialCondition(
L->getUniqueExitBlocks(ExitBlocks);
// Add exit blocks to the loop blocks.
- llvm::append_range(LoopBlocks, ExitBlocks);
+ llvm::append_range(LoopBlocks, ExitBlocks);
// Next step, clone all of the basic blocks that make up the loop (including
// the loop preheader and exit blocks), keeping track of the mapping between
@@ -1558,7 +1558,7 @@ void LoopUnswitch::unswitchNontrivialCondition(
// Emit the new branch that selects between the two versions of this loop.
emitPreheaderBranchOnCondition(LIC, Val, NewBlocks[0], LoopBlocks[0], OldBR,
- TI, ToDuplicate);
+ TI, ToDuplicate);
if (MSSAU) {
// Update MemoryPhis in Exit blocks.
MSSAU->updateExitBlocksForClonedLoop(ExitBlocks, VMap, *DT);
@@ -1580,39 +1580,39 @@ void LoopUnswitch::unswitchNontrivialCondition(
// iteration.
WeakTrackingVH LICHandle(LIC);
- if (ToDuplicate.empty()) {
- // Now we rewrite the original code to know that the condition is true and
- // the new code to know that the condition is false.
- rewriteLoopBodyWithConditionConstant(L, LIC, Val, /*IsEqual=*/false);
-
- // It's possible that simplifying one loop could cause the other to be
- // changed to another value or a constant. If its a constant, don't
- // simplify it.
- if (!LoopProcessWorklist.empty() && LoopProcessWorklist.back() == NewLoop &&
- LICHandle && !isa<Constant>(LICHandle))
- rewriteLoopBodyWithConditionConstant(NewLoop, LICHandle, Val,
- /*IsEqual=*/true);
- } else {
- // Partial unswitching. Update the condition in the right loop with the
- // constant.
- auto *CC = cast<ConstantInt>(Val);
- if (CC->isOneValue()) {
- rewriteLoopBodyWithConditionConstant(NewLoop, VMap[LIC], Val,
- /*IsEqual=*/true);
- } else
- rewriteLoopBodyWithConditionConstant(L, LIC, Val, /*IsEqual=*/true);
-
- // Mark the new loop as partially unswitched, to avoid unswitching on the
- // same condition again.
- auto &Context = NewLoop->getHeader()->getContext();
- MDNode *DisableUnswitchMD = MDNode::get(
- Context, MDString::get(Context, "llvm.loop.unswitch.partial.disable"));
- MDNode *NewLoopID = makePostTransformationMetadata(
- Context, L->getLoopID(), {"llvm.loop.unswitch.partial"},
- {DisableUnswitchMD});
- NewLoop->setLoopID(NewLoopID);
- }
-
+ if (ToDuplicate.empty()) {
+ // Now we rewrite the original code to know that the condition is true and
+ // the new code to know that the condition is false.
+ rewriteLoopBodyWithConditionConstant(L, LIC, Val, /*IsEqual=*/false);
+
+ // It's possible that simplifying one loop could cause the other to be
+ // changed to another value or a constant. If its a constant, don't
+ // simplify it.
+ if (!LoopProcessWorklist.empty() && LoopProcessWorklist.back() == NewLoop &&
+ LICHandle && !isa<Constant>(LICHandle))
+ rewriteLoopBodyWithConditionConstant(NewLoop, LICHandle, Val,
+ /*IsEqual=*/true);
+ } else {
+ // Partial unswitching. Update the condition in the right loop with the
+ // constant.
+ auto *CC = cast<ConstantInt>(Val);
+ if (CC->isOneValue()) {
+ rewriteLoopBodyWithConditionConstant(NewLoop, VMap[LIC], Val,
+ /*IsEqual=*/true);
+ } else
+ rewriteLoopBodyWithConditionConstant(L, LIC, Val, /*IsEqual=*/true);
+
+ // Mark the new loop as partially unswitched, to avoid unswitching on the
+ // same condition again.
+ auto &Context = NewLoop->getHeader()->getContext();
+ MDNode *DisableUnswitchMD = MDNode::get(
+ Context, MDString::get(Context, "llvm.loop.unswitch.partial.disable"));
+ MDNode *NewLoopID = makePostTransformationMetadata(
+ Context, L->getLoopID(), {"llvm.loop.unswitch.partial"},
+ {DisableUnswitchMD});
+ NewLoop->setLoopID(NewLoopID);
+ }
+
if (MSSA && VerifyMemorySSA)
MSSA->verifyMemorySSA();
}
@@ -1620,7 +1620,7 @@ void LoopUnswitch::unswitchNontrivialCondition(
/// Remove all instances of I from the worklist vector specified.
static void removeFromWorklist(Instruction *I,
std::vector<Instruction *> &Worklist) {
- llvm::erase_value(Worklist, I);
+ llvm::erase_value(Worklist, I);
}
/// When we find that I really equals V, remove I from the
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopVersioningLICM.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopVersioningLICM.cpp
index b1a41e0c9d..2ff1e84807 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LoopVersioningLICM.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LoopVersioningLICM.cpp
@@ -59,7 +59,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/Scalar/LoopVersioningLICM.h"
+#include "llvm/Transforms/Scalar/LoopVersioningLICM.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/AliasAnalysis.h"
@@ -115,18 +115,18 @@ static cl::opt<unsigned> LVLoopDepthThreshold(
namespace {
-struct LoopVersioningLICMLegacyPass : public LoopPass {
+struct LoopVersioningLICMLegacyPass : public LoopPass {
static char ID;
- LoopVersioningLICMLegacyPass() : LoopPass(ID) {
- initializeLoopVersioningLICMLegacyPassPass(
- *PassRegistry::getPassRegistry());
+ LoopVersioningLICMLegacyPass() : LoopPass(ID) {
+ initializeLoopVersioningLICMLegacyPassPass(
+ *PassRegistry::getPassRegistry());
}
bool runOnLoop(Loop *L, LPPassManager &LPM) override;
- StringRef getPassName() const override { return "Loop Versioning for LICM"; }
-
+ StringRef getPassName() const override { return "Loop Versioning for LICM"; }
+
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesCFG();
AU.addRequired<AAResultsWrapperPass>();
@@ -140,22 +140,22 @@ struct LoopVersioningLICMLegacyPass : public LoopPass {
AU.addPreserved<GlobalsAAWrapperPass>();
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
}
-};
-
-struct LoopVersioningLICM {
- // We don't explicitly pass in LoopAccessInfo to the constructor since the
- // loop versioning might return early due to instructions that are not safe
- // for versioning. By passing the proxy instead the construction of
- // LoopAccessInfo will take place only when it's necessary.
- LoopVersioningLICM(AliasAnalysis *AA, ScalarEvolution *SE,
- OptimizationRemarkEmitter *ORE,
- function_ref<const LoopAccessInfo &(Loop *)> GetLAI)
- : AA(AA), SE(SE), GetLAI(GetLAI),
- LoopDepthThreshold(LVLoopDepthThreshold),
- InvariantThreshold(LVInvarThreshold), ORE(ORE) {}
-
- bool runOnLoop(Loop *L, LoopInfo *LI, DominatorTree *DT);
-
+};
+
+struct LoopVersioningLICM {
+ // We don't explicitly pass in LoopAccessInfo to the constructor since the
+ // loop versioning might return early due to instructions that are not safe
+ // for versioning. By passing the proxy instead the construction of
+ // LoopAccessInfo will take place only when it's necessary.
+ LoopVersioningLICM(AliasAnalysis *AA, ScalarEvolution *SE,
+ OptimizationRemarkEmitter *ORE,
+ function_ref<const LoopAccessInfo &(Loop *)> GetLAI)
+ : AA(AA), SE(SE), GetLAI(GetLAI),
+ LoopDepthThreshold(LVLoopDepthThreshold),
+ InvariantThreshold(LVInvarThreshold), ORE(ORE) {}
+
+ bool runOnLoop(Loop *L, LoopInfo *LI, DominatorTree *DT);
+
void reset() {
AA = nullptr;
SE = nullptr;
@@ -186,9 +186,9 @@ private:
// Current Loop's LoopAccessInfo
const LoopAccessInfo *LAI = nullptr;
- // Proxy for retrieving LoopAccessInfo.
- function_ref<const LoopAccessInfo &(Loop *)> GetLAI;
-
+ // Proxy for retrieving LoopAccessInfo.
+ function_ref<const LoopAccessInfo &(Loop *)> GetLAI;
+
// The current loop we are working on.
Loop *CurLoop = nullptr;
@@ -267,7 +267,7 @@ bool LoopVersioningLICM::legalLoopStructure() {
// We need to be able to compute the loop trip count in order
// to generate the bound checks.
const SCEV *ExitCount = SE->getBackedgeTakenCount(CurLoop);
- if (isa<SCEVCouldNotCompute>(ExitCount)) {
+ if (isa<SCEVCouldNotCompute>(ExitCount)) {
LLVM_DEBUG(dbgs() << " loop does not has trip count\n");
return false;
}
@@ -414,8 +414,8 @@ bool LoopVersioningLICM::legalLoopInstructions() {
return false;
}
}
- // Get LoopAccessInfo from current loop via the proxy.
- LAI = &GetLAI(CurLoop);
+ // Get LoopAccessInfo from current loop via the proxy.
+ LAI = &GetLAI(CurLoop);
// Check LoopAccessInfo for need of runtime check.
if (LAI->getRuntimePointerChecking()->getChecks().empty()) {
LLVM_DEBUG(dbgs() << " LAA: Runtime check not found !!\n");
@@ -554,7 +554,7 @@ void LoopVersioningLICM::setNoAliasToLoop(Loop *VerLoop) {
MDNode *NewDomain = MDB.createAnonymousAliasScopeDomain("LVDomain");
StringRef Name = "LVAliasScope";
MDNode *NewScope = MDB.createAnonymousAliasScope(NewDomain, Name);
- SmallVector<Metadata *, 4> Scopes{NewScope}, NoAliases{NewScope};
+ SmallVector<Metadata *, 4> Scopes{NewScope}, NoAliases{NewScope};
// Iterate over each instruction of loop.
// set no-alias for all load & store instructions.
for (auto *Block : CurLoop->getBlocks()) {
@@ -576,25 +576,25 @@ void LoopVersioningLICM::setNoAliasToLoop(Loop *VerLoop) {
}
}
-bool LoopVersioningLICMLegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) {
- if (skipLoop(L))
- return false;
-
- AliasAnalysis *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
- ScalarEvolution *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
- OptimizationRemarkEmitter *ORE =
- &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
- LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
-
- auto GetLAI = [&](Loop *L) -> const LoopAccessInfo & {
- return getAnalysis<LoopAccessLegacyAnalysis>().getInfo(L);
- };
-
- return LoopVersioningLICM(AA, SE, ORE, GetLAI).runOnLoop(L, LI, DT);
-}
-
-bool LoopVersioningLICM::runOnLoop(Loop *L, LoopInfo *LI, DominatorTree *DT) {
+bool LoopVersioningLICMLegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) {
+ if (skipLoop(L))
+ return false;
+
+ AliasAnalysis *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
+ ScalarEvolution *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
+ OptimizationRemarkEmitter *ORE =
+ &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
+ LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
+ DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+
+ auto GetLAI = [&](Loop *L) -> const LoopAccessInfo & {
+ return getAnalysis<LoopAccessLegacyAnalysis>().getInfo(L);
+ };
+
+ return LoopVersioningLICM(AA, SE, ORE, GetLAI).runOnLoop(L, LI, DT);
+}
+
+bool LoopVersioningLICM::runOnLoop(Loop *L, LoopInfo *LI, DominatorTree *DT) {
// This will automatically release all resources hold by the current
// LoopVersioningLICM object.
AutoResetter Resetter(*this);
@@ -622,8 +622,8 @@ bool LoopVersioningLICM::runOnLoop(Loop *L, LoopInfo *LI, DominatorTree *DT) {
// Do loop versioning.
// Create memcheck for memory accessed inside loop.
// Clone original loop, and set blocks properly.
- LoopVersioning LVer(*LAI, LAI->getRuntimePointerChecking()->getChecks(),
- CurLoop, LI, DT, SE);
+ LoopVersioning LVer(*LAI, LAI->getRuntimePointerChecking()->getChecks(),
+ CurLoop, LI, DT, SE);
LVer.versionLoop();
// Set Loop Versioning metaData for original loop.
addStringMetadataToLoop(LVer.getNonVersionedLoop(), LICMVersioningMetaData);
@@ -641,9 +641,9 @@ bool LoopVersioningLICM::runOnLoop(Loop *L, LoopInfo *LI, DominatorTree *DT) {
return Changed;
}
-char LoopVersioningLICMLegacyPass::ID = 0;
+char LoopVersioningLICMLegacyPass::ID = 0;
-INITIALIZE_PASS_BEGIN(LoopVersioningLICMLegacyPass, "loop-versioning-licm",
+INITIALIZE_PASS_BEGIN(LoopVersioningLICMLegacyPass, "loop-versioning-licm",
"Loop Versioning For LICM", false, false)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
@@ -654,31 +654,31 @@ INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
-INITIALIZE_PASS_END(LoopVersioningLICMLegacyPass, "loop-versioning-licm",
+INITIALIZE_PASS_END(LoopVersioningLICMLegacyPass, "loop-versioning-licm",
"Loop Versioning For LICM", false, false)
-Pass *llvm::createLoopVersioningLICMPass() {
- return new LoopVersioningLICMLegacyPass();
-}
-
-namespace llvm {
-
-PreservedAnalyses LoopVersioningLICMPass::run(Loop &L, LoopAnalysisManager &AM,
- LoopStandardAnalysisResults &LAR,
- LPMUpdater &U) {
- AliasAnalysis *AA = &LAR.AA;
- ScalarEvolution *SE = &LAR.SE;
- DominatorTree *DT = &LAR.DT;
- LoopInfo *LI = &LAR.LI;
- const Function *F = L.getHeader()->getParent();
- OptimizationRemarkEmitter ORE(F);
-
- auto GetLAI = [&](Loop *L) -> const LoopAccessInfo & {
- return AM.getResult<LoopAccessAnalysis>(*L, LAR);
- };
-
- if (!LoopVersioningLICM(AA, SE, &ORE, GetLAI).runOnLoop(&L, LI, DT))
- return PreservedAnalyses::all();
- return getLoopPassPreservedAnalyses();
-}
-} // namespace llvm
+Pass *llvm::createLoopVersioningLICMPass() {
+ return new LoopVersioningLICMLegacyPass();
+}
+
+namespace llvm {
+
+PreservedAnalyses LoopVersioningLICMPass::run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &LAR,
+ LPMUpdater &U) {
+ AliasAnalysis *AA = &LAR.AA;
+ ScalarEvolution *SE = &LAR.SE;
+ DominatorTree *DT = &LAR.DT;
+ LoopInfo *LI = &LAR.LI;
+ const Function *F = L.getHeader()->getParent();
+ OptimizationRemarkEmitter ORE(F);
+
+ auto GetLAI = [&](Loop *L) -> const LoopAccessInfo & {
+ return AM.getResult<LoopAccessAnalysis>(*L, LAR);
+ };
+
+ if (!LoopVersioningLICM(AA, SE, &ORE, GetLAI).runOnLoop(&L, LI, DT))
+ return PreservedAnalyses::all();
+ return getLoopPassPreservedAnalyses();
+}
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp
index c17c903dd2..bb30c48127 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp
@@ -43,10 +43,10 @@ STATISTIC(ObjectSizeIntrinsicsHandled,
"Number of 'objectsize' intrinsic calls handled");
static Value *lowerIsConstantIntrinsic(IntrinsicInst *II) {
- if (auto *C = dyn_cast<Constant>(II->getOperand(0)))
- if (C->isManifestConstant())
- return ConstantInt::getTrue(II->getType());
- return ConstantInt::getFalse(II->getType());
+ if (auto *C = dyn_cast<Constant>(II->getOperand(0)))
+ if (C->isManifestConstant())
+ return ConstantInt::getTrue(II->getType());
+ return ConstantInt::getFalse(II->getType());
}
static bool replaceConditionalBranchesOnConstant(Instruction *II,
@@ -78,7 +78,7 @@ static bool replaceConditionalBranchesOnConstant(Instruction *II,
Other->removePredecessor(Source);
BI->eraseFromParent();
BranchInst::Create(Target, Source);
- if (pred_empty(Other))
+ if (pred_empty(Other))
HasDeadBlocks = true;
}
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp
index 98b6adee87..da13075dfe 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp
@@ -46,10 +46,10 @@ STATISTIC(ExpectIntrinsicsHandled,
// 'select' instructions. It may be worthwhile to hoist these values to some
// shared space, so they can be used directly by other passes.
-cl::opt<uint32_t> llvm::LikelyBranchWeight(
+cl::opt<uint32_t> llvm::LikelyBranchWeight(
"likely-branch-weight", cl::Hidden, cl::init(2000),
cl::desc("Weight of the branch likely to be taken (default = 2000)"));
-cl::opt<uint32_t> llvm::UnlikelyBranchWeight(
+cl::opt<uint32_t> llvm::UnlikelyBranchWeight(
"unlikely-branch-weight", cl::Hidden, cl::init(1),
cl::desc("Weight of the branch unlikely to be taken (default = 1)"));
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp
index d9f8c9f83d..8e251ca940 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp
@@ -42,8 +42,8 @@
#include "llvm/Support/Debug.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "llvm/Transforms/Utils/LoopUtils.h"
-#include "llvm/Transforms/Utils/MatrixUtils.h"
+#include "llvm/Transforms/Utils/LoopUtils.h"
+#include "llvm/Transforms/Utils/MatrixUtils.h"
using namespace llvm;
using namespace PatternMatch;
@@ -63,9 +63,9 @@ static cl::opt<unsigned> TileSize(
"fuse-matrix-tile-size", cl::init(4), cl::Hidden,
cl::desc(
"Tile size for matrix instruction fusion using square-shaped tiles."));
-static cl::opt<bool> TileUseLoops("fuse-matrix-use-loops", cl::init(false),
- cl::Hidden,
- cl::desc("Generate loop nest for tiling."));
+static cl::opt<bool> TileUseLoops("fuse-matrix-use-loops", cl::init(false),
+ cl::Hidden,
+ cl::desc("Generate loop nest for tiling."));
static cl::opt<bool> ForceFusion(
"force-fuse-matrix", cl::init(false), cl::Hidden,
cl::desc("Force matrix instruction fusion even if not profitable."));
@@ -187,10 +187,10 @@ class LowerMatrixIntrinsics {
Function &Func;
const DataLayout &DL;
const TargetTransformInfo &TTI;
- AliasAnalysis *AA;
- DominatorTree *DT;
- LoopInfo *LI;
- OptimizationRemarkEmitter *ORE;
+ AliasAnalysis *AA;
+ DominatorTree *DT;
+ LoopInfo *LI;
+ OptimizationRemarkEmitter *ORE;
/// Contains estimates of the number of operations (loads, stores, compute) required to lower a matrix operation.
struct OpInfoTy {
@@ -246,7 +246,7 @@ class LowerMatrixIntrinsics {
void setVector(unsigned i, Value *V) { Vectors[i] = V; }
- Type *getElementType() const { return getVectorTy()->getElementType(); }
+ Type *getElementType() const { return getVectorTy()->getElementType(); }
unsigned getNumVectors() const {
if (isColumnMajor())
@@ -276,7 +276,7 @@ class LowerMatrixIntrinsics {
return getVectorTy();
}
- VectorType *getVectorTy() const {
+ VectorType *getVectorTy() const {
return cast<VectorType>(Vectors[0]->getType());
}
@@ -335,7 +335,7 @@ class LowerMatrixIntrinsics {
IRBuilder<> &Builder) const {
Value *Vec = isColumnMajor() ? getColumn(J) : getRow(I);
return Builder.CreateShuffleVector(
- Vec, createSequentialMask(isColumnMajor() ? I : J, NumElts, 0),
+ Vec, createSequentialMask(isColumnMajor() ? I : J, NumElts, 0),
"block");
}
};
@@ -397,8 +397,8 @@ class LowerMatrixIntrinsics {
public:
LowerMatrixIntrinsics(Function &F, TargetTransformInfo &TTI,
- AliasAnalysis *AA, DominatorTree *DT, LoopInfo *LI,
- OptimizationRemarkEmitter *ORE)
+ AliasAnalysis *AA, DominatorTree *DT, LoopInfo *LI,
+ OptimizationRemarkEmitter *ORE)
: Func(F), DL(F.getParent()->getDataLayout()), TTI(TTI), AA(AA), DT(DT),
LI(LI), ORE(ORE) {}
@@ -450,7 +450,7 @@ public:
MaskStart < cast<FixedVectorType>(VType)->getNumElements();
MaskStart += SI.getStride()) {
Value *V = Builder.CreateShuffleVector(
- MatrixVal, createSequentialMask(MaskStart, SI.getStride(), 0),
+ MatrixVal, createSequentialMask(MaskStart, SI.getStride(), 0),
"split");
SplitVecs.push_back(V);
}
@@ -488,7 +488,7 @@ public:
case Instruction::FAdd:
case Instruction::FSub:
case Instruction::FMul: // Scalar multiply.
- case Instruction::FNeg:
+ case Instruction::FNeg:
case Instruction::Add:
case Instruction::Mul:
case Instruction::Sub:
@@ -531,7 +531,7 @@ public:
// list.
LLVM_DEBUG(dbgs() << "Forward-propagate shapes:\n");
while (!WorkList.empty()) {
- Instruction *Inst = WorkList.pop_back_val();
+ Instruction *Inst = WorkList.pop_back_val();
// New entry, set the value and insert operands
bool Propagate = false;
@@ -601,7 +601,7 @@ public:
// worklist.
LLVM_DEBUG(dbgs() << "Backward-propagate shapes:\n");
while (!WorkList.empty()) {
- Value *V = WorkList.pop_back_val();
+ Value *V = WorkList.pop_back_val();
size_t BeforeProcessingV = WorkList.size();
if (!isa<Instruction>(V))
@@ -723,18 +723,18 @@ public:
Value *Op2;
if (auto *BinOp = dyn_cast<BinaryOperator>(Inst))
Changed |= VisitBinaryOperator(BinOp);
- if (auto *UnOp = dyn_cast<UnaryOperator>(Inst))
- Changed |= VisitUnaryOperator(UnOp);
+ if (auto *UnOp = dyn_cast<UnaryOperator>(Inst))
+ Changed |= VisitUnaryOperator(UnOp);
if (match(Inst, m_Load(m_Value(Op1))))
Changed |= VisitLoad(cast<LoadInst>(Inst), Op1, Builder);
else if (match(Inst, m_Store(m_Value(Op1), m_Value(Op2))))
Changed |= VisitStore(cast<StoreInst>(Inst), Op1, Op2, Builder);
}
- if (ORE) {
- RemarkGenerator RemarkGen(Inst2ColumnMatrix, *ORE, Func);
- RemarkGen.emitRemarks();
- }
+ if (ORE) {
+ RemarkGenerator RemarkGen(Inst2ColumnMatrix, *ORE, Func);
+ RemarkGen.emitRemarks();
+ }
for (Instruction *Inst : reverse(ToRemove))
Inst->eraseFromParent();
@@ -941,7 +941,7 @@ public:
assert(NumElts >= BlockNumElts && "Too few elements for current block");
Block = Builder.CreateShuffleVector(
- Block, createSequentialMask(0, BlockNumElts, NumElts - BlockNumElts));
+ Block, createSequentialMask(0, BlockNumElts, NumElts - BlockNumElts));
// If Col is 7 long and I is 2 and BlockNumElts is 2 the mask is: 0, 1, 7,
// 8, 4, 5, 6
@@ -1089,7 +1089,7 @@ public:
MemoryLocation StoreLoc = MemoryLocation::get(Store);
MemoryLocation LoadLoc = MemoryLocation::get(Load);
- AliasResult LdAliased = AA->alias(LoadLoc, StoreLoc);
+ AliasResult LdAliased = AA->alias(LoadLoc, StoreLoc);
// If we can statically determine noalias we're good.
if (!LdAliased)
@@ -1105,17 +1105,17 @@ public:
// as we adjust Check0 and Check1's branches.
SmallVector<DominatorTree::UpdateType, 4> DTUpdates;
for (BasicBlock *Succ : successors(Check0))
- DTUpdates.push_back({DT->Delete, Check0, Succ});
+ DTUpdates.push_back({DT->Delete, Check0, Succ});
- BasicBlock *Check1 =
- SplitBlock(MatMul->getParent(), MatMul, (DomTreeUpdater *)nullptr, LI,
- nullptr, "alias_cont");
+ BasicBlock *Check1 =
+ SplitBlock(MatMul->getParent(), MatMul, (DomTreeUpdater *)nullptr, LI,
+ nullptr, "alias_cont");
BasicBlock *Copy =
- SplitBlock(MatMul->getParent(), MatMul, (DomTreeUpdater *)nullptr, LI,
- nullptr, "copy");
- BasicBlock *Fusion =
- SplitBlock(MatMul->getParent(), MatMul, (DomTreeUpdater *)nullptr, LI,
- nullptr, "no_alias");
+ SplitBlock(MatMul->getParent(), MatMul, (DomTreeUpdater *)nullptr, LI,
+ nullptr, "copy");
+ BasicBlock *Fusion =
+ SplitBlock(MatMul->getParent(), MatMul, (DomTreeUpdater *)nullptr, LI,
+ nullptr, "no_alias");
// Check if the loaded memory location begins before the end of the store
// location. If the condition holds, they might overlap, otherwise they are
@@ -1159,11 +1159,11 @@ public:
PHI->addIncoming(NewLd, Copy);
// Adjust DT.
- DTUpdates.push_back({DT->Insert, Check0, Check1});
- DTUpdates.push_back({DT->Insert, Check0, Fusion});
- DTUpdates.push_back({DT->Insert, Check1, Copy});
- DTUpdates.push_back({DT->Insert, Check1, Fusion});
- DT->applyUpdates(DTUpdates);
+ DTUpdates.push_back({DT->Insert, Check0, Check1});
+ DTUpdates.push_back({DT->Insert, Check0, Fusion});
+ DTUpdates.push_back({DT->Insert, Check1, Copy});
+ DTUpdates.push_back({DT->Insert, Check1, Fusion});
+ DT->applyUpdates(DTUpdates);
return PHI;
}
@@ -1209,63 +1209,63 @@ public:
return Res;
}
- void createTiledLoops(CallInst *MatMul, Value *LPtr, ShapeInfo LShape,
- Value *RPtr, ShapeInfo RShape, StoreInst *Store,
- bool AllowContract) {
- auto *EltType = cast<VectorType>(MatMul->getType())->getElementType();
-
- // Create the main tiling loop nest.
- TileInfo TI(LShape.NumRows, RShape.NumColumns, LShape.NumColumns, TileSize);
- DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
- Instruction *InsertI = cast<Instruction>(MatMul);
- BasicBlock *Start = InsertI->getParent();
- BasicBlock *End =
- SplitBlock(InsertI->getParent(), InsertI, DT, LI, nullptr, "continue");
- IRBuilder<> Builder(MatMul);
- BasicBlock *InnerBody = TI.CreateTiledLoops(Start, End, Builder, DTU, *LI);
-
- Type *TileVecTy =
- FixedVectorType::get(MatMul->getType()->getScalarType(), TileSize);
- MatrixTy TileResult;
- // Insert in the inner loop header.
- Builder.SetInsertPoint(TI.InnerLoopHeader->getTerminator());
- // Create PHI nodes for the result columns to accumulate across iterations.
- SmallVector<PHINode *, 4> ColumnPhis;
- for (unsigned I = 0; I < TileSize; I++) {
- auto *Phi = Builder.CreatePHI(TileVecTy, 2, "result.vec." + Twine(I));
- Phi->addIncoming(ConstantAggregateZero::get(TileVecTy),
- TI.RowLoopHeader->getSingleSuccessor());
- TileResult.addVector(Phi);
- ColumnPhis.push_back(Phi);
- }
-
- // Insert in the inner loop body, which computes
- // Res += Load(CurrentRow, K) * Load(K, CurrentColumn)
- Builder.SetInsertPoint(InnerBody->getTerminator());
- // Load tiles of the operands.
- MatrixTy A = loadMatrix(LPtr, {}, false, LShape, TI.CurrentRow, TI.CurrentK,
- {TileSize, TileSize}, EltType, Builder);
- MatrixTy B = loadMatrix(RPtr, {}, false, RShape, TI.CurrentK, TI.CurrentCol,
- {TileSize, TileSize}, EltType, Builder);
- emitMatrixMultiply(TileResult, A, B, AllowContract, Builder, true);
- // Store result after the inner loop is done.
- Builder.SetInsertPoint(TI.RowLoopLatch->getTerminator());
- storeMatrix(TileResult, Store->getPointerOperand(), Store->getAlign(),
- Store->isVolatile(), {LShape.NumRows, RShape.NumColumns},
- TI.CurrentRow, TI.CurrentCol, EltType, Builder);
-
- for (unsigned I = 0; I < TileResult.getNumVectors(); I++)
- ColumnPhis[I]->addIncoming(TileResult.getVector(I), TI.InnerLoopLatch);
-
- // Force unrolling of a few iterations of the inner loop, to make sure there
- // is enough work per iteration.
- // FIXME: The unroller should make this decision directly instead, but
- // currently the cost-model is not up to the task.
- unsigned InnerLoopUnrollCount = std::min(10u, LShape.NumColumns / TileSize);
- addStringMetadataToLoop(LI->getLoopFor(TI.InnerLoopHeader),
- "llvm.loop.unroll.count", InnerLoopUnrollCount);
- }
-
+ void createTiledLoops(CallInst *MatMul, Value *LPtr, ShapeInfo LShape,
+ Value *RPtr, ShapeInfo RShape, StoreInst *Store,
+ bool AllowContract) {
+ auto *EltType = cast<VectorType>(MatMul->getType())->getElementType();
+
+ // Create the main tiling loop nest.
+ TileInfo TI(LShape.NumRows, RShape.NumColumns, LShape.NumColumns, TileSize);
+ DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
+ Instruction *InsertI = cast<Instruction>(MatMul);
+ BasicBlock *Start = InsertI->getParent();
+ BasicBlock *End =
+ SplitBlock(InsertI->getParent(), InsertI, DT, LI, nullptr, "continue");
+ IRBuilder<> Builder(MatMul);
+ BasicBlock *InnerBody = TI.CreateTiledLoops(Start, End, Builder, DTU, *LI);
+
+ Type *TileVecTy =
+ FixedVectorType::get(MatMul->getType()->getScalarType(), TileSize);
+ MatrixTy TileResult;
+ // Insert in the inner loop header.
+ Builder.SetInsertPoint(TI.InnerLoopHeader->getTerminator());
+ // Create PHI nodes for the result columns to accumulate across iterations.
+ SmallVector<PHINode *, 4> ColumnPhis;
+ for (unsigned I = 0; I < TileSize; I++) {
+ auto *Phi = Builder.CreatePHI(TileVecTy, 2, "result.vec." + Twine(I));
+ Phi->addIncoming(ConstantAggregateZero::get(TileVecTy),
+ TI.RowLoopHeader->getSingleSuccessor());
+ TileResult.addVector(Phi);
+ ColumnPhis.push_back(Phi);
+ }
+
+ // Insert in the inner loop body, which computes
+ // Res += Load(CurrentRow, K) * Load(K, CurrentColumn)
+ Builder.SetInsertPoint(InnerBody->getTerminator());
+ // Load tiles of the operands.
+ MatrixTy A = loadMatrix(LPtr, {}, false, LShape, TI.CurrentRow, TI.CurrentK,
+ {TileSize, TileSize}, EltType, Builder);
+ MatrixTy B = loadMatrix(RPtr, {}, false, RShape, TI.CurrentK, TI.CurrentCol,
+ {TileSize, TileSize}, EltType, Builder);
+ emitMatrixMultiply(TileResult, A, B, AllowContract, Builder, true);
+ // Store result after the inner loop is done.
+ Builder.SetInsertPoint(TI.RowLoopLatch->getTerminator());
+ storeMatrix(TileResult, Store->getPointerOperand(), Store->getAlign(),
+ Store->isVolatile(), {LShape.NumRows, RShape.NumColumns},
+ TI.CurrentRow, TI.CurrentCol, EltType, Builder);
+
+ for (unsigned I = 0; I < TileResult.getNumVectors(); I++)
+ ColumnPhis[I]->addIncoming(TileResult.getVector(I), TI.InnerLoopLatch);
+
+ // Force unrolling of a few iterations of the inner loop, to make sure there
+ // is enough work per iteration.
+ // FIXME: The unroller should make this decision directly instead, but
+ // currently the cost-model is not up to the task.
+ unsigned InnerLoopUnrollCount = std::min(10u, LShape.NumColumns / TileSize);
+ addStringMetadataToLoop(LI->getLoopFor(TI.InnerLoopHeader),
+ "llvm.loop.unroll.count", InnerLoopUnrollCount);
+ }
+
void emitSIMDTiling(CallInst *MatMul, LoadInst *LoadOp0, LoadInst *LoadOp1,
StoreInst *Store,
SmallPtrSetImpl<Instruction *> &FusedInsts) {
@@ -1288,34 +1288,34 @@ public:
bool AllowContract = AllowContractEnabled || (isa<FPMathOperator>(MatMul) &&
MatMul->hasAllowContract());
- if (TileUseLoops && (R % TileSize == 0 && C % TileSize == 0))
- createTiledLoops(MatMul, APtr, LShape, BPtr, RShape, Store,
- AllowContract);
- else {
- IRBuilder<> Builder(Store);
- for (unsigned J = 0; J < C; J += TileSize)
- for (unsigned I = 0; I < R; I += TileSize) {
- const unsigned TileR = std::min(R - I, unsigned(TileSize));
- const unsigned TileC = std::min(C - J, unsigned(TileSize));
- MatrixTy Res = getZeroMatrix(EltType, TileR, TileC);
-
- for (unsigned K = 0; K < M; K += TileSize) {
- const unsigned TileM = std::min(M - K, unsigned(TileSize));
- MatrixTy A =
- loadMatrix(APtr, LoadOp0->getAlign(), LoadOp0->isVolatile(),
- LShape, Builder.getInt64(I), Builder.getInt64(K),
- {TileR, TileM}, EltType, Builder);
- MatrixTy B =
- loadMatrix(BPtr, LoadOp1->getAlign(), LoadOp1->isVolatile(),
- RShape, Builder.getInt64(K), Builder.getInt64(J),
- {TileM, TileC}, EltType, Builder);
- emitMatrixMultiply(Res, A, B, AllowContract, Builder, true);
- }
- storeMatrix(Res, CPtr, Store->getAlign(), Store->isVolatile(), {R, M},
- Builder.getInt64(I), Builder.getInt64(J), EltType,
- Builder);
+ if (TileUseLoops && (R % TileSize == 0 && C % TileSize == 0))
+ createTiledLoops(MatMul, APtr, LShape, BPtr, RShape, Store,
+ AllowContract);
+ else {
+ IRBuilder<> Builder(Store);
+ for (unsigned J = 0; J < C; J += TileSize)
+ for (unsigned I = 0; I < R; I += TileSize) {
+ const unsigned TileR = std::min(R - I, unsigned(TileSize));
+ const unsigned TileC = std::min(C - J, unsigned(TileSize));
+ MatrixTy Res = getZeroMatrix(EltType, TileR, TileC);
+
+ for (unsigned K = 0; K < M; K += TileSize) {
+ const unsigned TileM = std::min(M - K, unsigned(TileSize));
+ MatrixTy A =
+ loadMatrix(APtr, LoadOp0->getAlign(), LoadOp0->isVolatile(),
+ LShape, Builder.getInt64(I), Builder.getInt64(K),
+ {TileR, TileM}, EltType, Builder);
+ MatrixTy B =
+ loadMatrix(BPtr, LoadOp1->getAlign(), LoadOp1->isVolatile(),
+ RShape, Builder.getInt64(K), Builder.getInt64(J),
+ {TileM, TileC}, EltType, Builder);
+ emitMatrixMultiply(Res, A, B, AllowContract, Builder, true);
+ }
+ storeMatrix(Res, CPtr, Store->getAlign(), Store->isVolatile(), {R, M},
+ Builder.getInt64(I), Builder.getInt64(J), EltType,
+ Builder);
}
- }
+ }
// Mark eliminated instructions as fused and remove them.
FusedInsts.insert(Store);
@@ -1342,11 +1342,11 @@ public:
void LowerMatrixMultiplyFused(CallInst *MatMul,
SmallPtrSetImpl<Instruction *> &FusedInsts) {
if (!FuseMatrix || !MatMul->hasOneUse() ||
- MatrixLayout != MatrixLayoutTy::ColumnMajor || !DT)
+ MatrixLayout != MatrixLayoutTy::ColumnMajor || !DT)
return;
- assert(AA && LI && "Analyses should be available");
-
+ assert(AA && LI && "Analyses should be available");
+
auto *LoadOp0 = dyn_cast<LoadInst>(MatMul->getOperand(0));
auto *LoadOp1 = dyn_cast<LoadInst>(MatMul->getOperand(1));
auto *Store = dyn_cast<StoreInst>(*MatMul->user_begin());
@@ -1355,7 +1355,7 @@ public:
// we create invalid IR.
// FIXME: See if we can hoist the store address computation.
auto *AddrI = dyn_cast<Instruction>(Store->getOperand(1));
- if (AddrI && (!DT->dominates(AddrI, MatMul)))
+ if (AddrI && (!DT->dominates(AddrI, MatMul)))
return;
emitSIMDTiling(MatMul, LoadOp0, LoadOp1, Store, FusedInsts);
@@ -1372,8 +1372,8 @@ public:
const MatrixTy &Lhs = getMatrix(MatMul->getArgOperand(0), LShape, Builder);
const MatrixTy &Rhs = getMatrix(MatMul->getArgOperand(1), RShape, Builder);
- assert(Lhs.getElementType() == Rhs.getElementType() &&
- "Matrix multiply argument element types do not match.");
+ assert(Lhs.getElementType() == Rhs.getElementType() &&
+ "Matrix multiply argument element types do not match.");
const unsigned R = LShape.NumRows;
const unsigned C = RShape.NumColumns;
@@ -1381,8 +1381,8 @@ public:
// Initialize the output
MatrixTy Result(R, C, EltType);
- assert(Lhs.getElementType() == Result.getElementType() &&
- "Matrix multiply result element type does not match arguments.");
+ assert(Lhs.getElementType() == Result.getElementType() &&
+ "Matrix multiply result element type does not match arguments.");
bool AllowContract = AllowContractEnabled || (isa<FPMathOperator>(MatMul) &&
MatMul->hasAllowContract());
@@ -1500,40 +1500,40 @@ public:
return true;
}
- /// Lower unary operators, if shape information is available.
- bool VisitUnaryOperator(UnaryOperator *Inst) {
- auto I = ShapeMap.find(Inst);
- if (I == ShapeMap.end())
- return false;
-
- Value *Op = Inst->getOperand(0);
-
- IRBuilder<> Builder(Inst);
- ShapeInfo &Shape = I->second;
-
- MatrixTy Result;
- MatrixTy M = getMatrix(Op, Shape, Builder);
-
- // Helper to perform unary op on vectors.
- auto BuildVectorOp = [&Builder, Inst](Value *Op) {
- switch (Inst->getOpcode()) {
- case Instruction::FNeg:
- return Builder.CreateFNeg(Op);
- default:
- llvm_unreachable("Unsupported unary operator for matrix");
- }
- };
-
- for (unsigned I = 0; I < Shape.getNumVectors(); ++I)
- Result.addVector(BuildVectorOp(M.getVector(I)));
-
- finalizeLowering(Inst,
- Result.addNumComputeOps(getNumOps(Result.getVectorTy()) *
- Result.getNumVectors()),
- Builder);
- return true;
- }
-
+ /// Lower unary operators, if shape information is available.
+ bool VisitUnaryOperator(UnaryOperator *Inst) {
+ auto I = ShapeMap.find(Inst);
+ if (I == ShapeMap.end())
+ return false;
+
+ Value *Op = Inst->getOperand(0);
+
+ IRBuilder<> Builder(Inst);
+ ShapeInfo &Shape = I->second;
+
+ MatrixTy Result;
+ MatrixTy M = getMatrix(Op, Shape, Builder);
+
+ // Helper to perform unary op on vectors.
+ auto BuildVectorOp = [&Builder, Inst](Value *Op) {
+ switch (Inst->getOpcode()) {
+ case Instruction::FNeg:
+ return Builder.CreateFNeg(Op);
+ default:
+ llvm_unreachable("Unsupported unary operator for matrix");
+ }
+ };
+
+ for (unsigned I = 0; I < Shape.getNumVectors(); ++I)
+ Result.addVector(BuildVectorOp(M.getVector(I)));
+
+ finalizeLowering(Inst,
+ Result.addNumComputeOps(getNumOps(Result.getVectorTy()) *
+ Result.getNumVectors()),
+ Builder);
+ return true;
+ }
+
/// Helper to linearize a matrix expression tree into a string. Currently
/// matrix expressions are linarized by starting at an expression leaf and
/// linearizing bottom up.
@@ -1598,7 +1598,7 @@ public:
if (Value *Ptr = getPointerOperand(V))
return getUnderlyingObjectThroughLoads(Ptr);
else if (V->getType()->isPointerTy())
- return getUnderlyingObject(V);
+ return getUnderlyingObject(V);
return V;
}
@@ -1634,7 +1634,7 @@ public:
write(StringRef(Intrinsic::getName(II->getIntrinsicID(), {}))
.drop_front(StringRef("llvm.matrix.").size()));
write(".");
- std::string Tmp;
+ std::string Tmp;
raw_string_ostream SS(Tmp);
switch (II->getIntrinsicID()) {
@@ -1972,25 +1972,25 @@ public:
PreservedAnalyses LowerMatrixIntrinsicsPass::run(Function &F,
FunctionAnalysisManager &AM) {
auto &TTI = AM.getResult<TargetIRAnalysis>(F);
- OptimizationRemarkEmitter *ORE = nullptr;
- AAResults *AA = nullptr;
- DominatorTree *DT = nullptr;
- LoopInfo *LI = nullptr;
-
- if (!Minimal) {
- ORE = &AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
- AA = &AM.getResult<AAManager>(F);
- DT = &AM.getResult<DominatorTreeAnalysis>(F);
- LI = &AM.getResult<LoopAnalysis>(F);
- }
-
+ OptimizationRemarkEmitter *ORE = nullptr;
+ AAResults *AA = nullptr;
+ DominatorTree *DT = nullptr;
+ LoopInfo *LI = nullptr;
+
+ if (!Minimal) {
+ ORE = &AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
+ AA = &AM.getResult<AAManager>(F);
+ DT = &AM.getResult<DominatorTreeAnalysis>(F);
+ LI = &AM.getResult<LoopAnalysis>(F);
+ }
+
LowerMatrixIntrinsics LMT(F, TTI, AA, DT, LI, ORE);
if (LMT.Visit()) {
PreservedAnalyses PA;
- if (!Minimal) {
- PA.preserve<LoopAnalysis>();
- PA.preserve<DominatorTreeAnalysis>();
- }
+ if (!Minimal) {
+ PA.preserve<LoopAnalysis>();
+ PA.preserve<DominatorTreeAnalysis>();
+ }
return PA;
}
return PreservedAnalyses::all();
@@ -2013,7 +2013,7 @@ public:
auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- LowerMatrixIntrinsics LMT(F, TTI, &AA, &DT, &LI, &ORE);
+ LowerMatrixIntrinsics LMT(F, TTI, &AA, &DT, &LI, &ORE);
bool C = LMT.Visit();
return C;
}
@@ -2044,45 +2044,45 @@ INITIALIZE_PASS_END(LowerMatrixIntrinsicsLegacyPass, DEBUG_TYPE, pass_name,
Pass *llvm::createLowerMatrixIntrinsicsPass() {
return new LowerMatrixIntrinsicsLegacyPass();
}
-
-namespace {
-
-/// A lightweight version of the matrix lowering pass that only requires TTI.
-/// Advanced features that require DT, AA or ORE like tiling are disabled. This
-/// is used to lower matrix intrinsics if the main lowering pass is not run, for
-/// example with -O0.
-class LowerMatrixIntrinsicsMinimalLegacyPass : public FunctionPass {
-public:
- static char ID;
-
- LowerMatrixIntrinsicsMinimalLegacyPass() : FunctionPass(ID) {
- initializeLowerMatrixIntrinsicsMinimalLegacyPassPass(
- *PassRegistry::getPassRegistry());
- }
-
- bool runOnFunction(Function &F) override {
- auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
- LowerMatrixIntrinsics LMT(F, TTI, nullptr, nullptr, nullptr, nullptr);
- bool C = LMT.Visit();
- return C;
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<TargetTransformInfoWrapperPass>();
- AU.setPreservesCFG();
- }
-};
-} // namespace
-
-static const char pass_name_minimal[] = "Lower the matrix intrinsics (minimal)";
-char LowerMatrixIntrinsicsMinimalLegacyPass::ID = 0;
-INITIALIZE_PASS_BEGIN(LowerMatrixIntrinsicsMinimalLegacyPass,
- "lower-matrix-intrinsics-minimal", pass_name_minimal,
- false, false)
-INITIALIZE_PASS_END(LowerMatrixIntrinsicsMinimalLegacyPass,
- "lower-matrix-intrinsics-minimal", pass_name_minimal, false,
- false)
-
-Pass *llvm::createLowerMatrixIntrinsicsMinimalPass() {
- return new LowerMatrixIntrinsicsMinimalLegacyPass();
-}
+
+namespace {
+
+/// A lightweight version of the matrix lowering pass that only requires TTI.
+/// Advanced features that require DT, AA or ORE like tiling are disabled. This
+/// is used to lower matrix intrinsics if the main lowering pass is not run, for
+/// example with -O0.
+class LowerMatrixIntrinsicsMinimalLegacyPass : public FunctionPass {
+public:
+ static char ID;
+
+ LowerMatrixIntrinsicsMinimalLegacyPass() : FunctionPass(ID) {
+ initializeLowerMatrixIntrinsicsMinimalLegacyPassPass(
+ *PassRegistry::getPassRegistry());
+ }
+
+ bool runOnFunction(Function &F) override {
+ auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
+ LowerMatrixIntrinsics LMT(F, TTI, nullptr, nullptr, nullptr, nullptr);
+ bool C = LMT.Visit();
+ return C;
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<TargetTransformInfoWrapperPass>();
+ AU.setPreservesCFG();
+ }
+};
+} // namespace
+
+static const char pass_name_minimal[] = "Lower the matrix intrinsics (minimal)";
+char LowerMatrixIntrinsicsMinimalLegacyPass::ID = 0;
+INITIALIZE_PASS_BEGIN(LowerMatrixIntrinsicsMinimalLegacyPass,
+ "lower-matrix-intrinsics-minimal", pass_name_minimal,
+ false, false)
+INITIALIZE_PASS_END(LowerMatrixIntrinsicsMinimalLegacyPass,
+ "lower-matrix-intrinsics-minimal", pass_name_minimal, false,
+ false)
+
+Pass *llvm::createLowerMatrixIntrinsicsMinimalPass() {
+ return new LowerMatrixIntrinsicsMinimalLegacyPass();
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index c5ef74e869..a4e695497f 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -21,11 +21,11 @@
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/GlobalsModRef.h"
-#include "llvm/Analysis/Loads.h"
+#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/Analysis/MemoryLocation.h"
-#include "llvm/Analysis/MemorySSA.h"
-#include "llvm/Analysis/MemorySSAUpdater.h"
+#include "llvm/Analysis/MemorySSA.h"
+#include "llvm/Analysis/MemorySSAUpdater.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Argument.h"
@@ -67,15 +67,15 @@ using namespace llvm;
#define DEBUG_TYPE "memcpyopt"
-static cl::opt<bool>
- EnableMemorySSA("enable-memcpyopt-memoryssa", cl::init(false), cl::Hidden,
- cl::desc("Use MemorySSA-backed MemCpyOpt."));
-
+static cl::opt<bool>
+ EnableMemorySSA("enable-memcpyopt-memoryssa", cl::init(false), cl::Hidden,
+ cl::desc("Use MemorySSA-backed MemCpyOpt."));
+
STATISTIC(NumMemCpyInstr, "Number of memcpy instructions deleted");
STATISTIC(NumMemSetInfer, "Number of memsets inferred");
STATISTIC(NumMoveToCpy, "Number of memmoves converted to memcpy");
STATISTIC(NumCpyToSet, "Number of memcpys converted to memset");
-STATISTIC(NumCallSlot, "Number of call slot optimizations performed");
+STATISTIC(NumCallSlot, "Number of call slot optimizations performed");
namespace {
@@ -279,17 +279,17 @@ private:
AU.setPreservesCFG();
AU.addRequired<AssumptionCacheTracker>();
AU.addRequired<DominatorTreeWrapperPass>();
- AU.addPreserved<DominatorTreeWrapperPass>();
- AU.addPreserved<GlobalsAAWrapperPass>();
+ AU.addPreserved<DominatorTreeWrapperPass>();
+ AU.addPreserved<GlobalsAAWrapperPass>();
AU.addRequired<TargetLibraryInfoWrapperPass>();
- if (!EnableMemorySSA)
- AU.addRequired<MemoryDependenceWrapperPass>();
+ if (!EnableMemorySSA)
+ AU.addRequired<MemoryDependenceWrapperPass>();
AU.addPreserved<MemoryDependenceWrapperPass>();
- AU.addRequired<AAResultsWrapperPass>();
- AU.addPreserved<AAResultsWrapperPass>();
- if (EnableMemorySSA)
- AU.addRequired<MemorySSAWrapperPass>();
- AU.addPreserved<MemorySSAWrapperPass>();
+ AU.addRequired<AAResultsWrapperPass>();
+ AU.addPreserved<AAResultsWrapperPass>();
+ if (EnableMemorySSA)
+ AU.addRequired<MemorySSAWrapperPass>();
+ AU.addPreserved<MemorySSAWrapperPass>();
}
};
@@ -311,56 +311,56 @@ INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
INITIALIZE_PASS_END(MemCpyOptLegacyPass, "memcpyopt", "MemCpy Optimization",
false, false)
-// Check that V is either not accessible by the caller, or unwinding cannot
-// occur between Start and End.
-static bool mayBeVisibleThroughUnwinding(Value *V, Instruction *Start,
- Instruction *End) {
- assert(Start->getParent() == End->getParent() && "Must be in same block");
- if (!Start->getFunction()->doesNotThrow() &&
- !isa<AllocaInst>(getUnderlyingObject(V))) {
- for (const Instruction &I :
- make_range(Start->getIterator(), End->getIterator())) {
- if (I.mayThrow())
- return true;
- }
- }
- return false;
-}
-
-void MemCpyOptPass::eraseInstruction(Instruction *I) {
- if (MSSAU)
- MSSAU->removeMemoryAccess(I);
- if (MD)
- MD->removeInstruction(I);
- I->eraseFromParent();
-}
-
-// Check for mod or ref of Loc between Start and End, excluding both boundaries.
-// Start and End must be in the same block
-static bool accessedBetween(AliasAnalysis &AA, MemoryLocation Loc,
- const MemoryUseOrDef *Start,
- const MemoryUseOrDef *End) {
- assert(Start->getBlock() == End->getBlock() && "Only local supported");
- for (const MemoryAccess &MA :
- make_range(++Start->getIterator(), End->getIterator())) {
- if (isModOrRefSet(AA.getModRefInfo(cast<MemoryUseOrDef>(MA).getMemoryInst(),
- Loc)))
- return true;
- }
- return false;
-}
-
-// Check for mod of Loc between Start and End, excluding both boundaries.
-// Start and End can be in different blocks.
-static bool writtenBetween(MemorySSA *MSSA, MemoryLocation Loc,
- const MemoryUseOrDef *Start,
- const MemoryUseOrDef *End) {
- // TODO: Only walk until we hit Start.
- MemoryAccess *Clobber = MSSA->getWalker()->getClobberingMemoryAccess(
- End->getDefiningAccess(), Loc);
- return !MSSA->dominates(Clobber, Start);
-}
-
+// Check that V is either not accessible by the caller, or unwinding cannot
+// occur between Start and End.
+static bool mayBeVisibleThroughUnwinding(Value *V, Instruction *Start,
+ Instruction *End) {
+ assert(Start->getParent() == End->getParent() && "Must be in same block");
+ if (!Start->getFunction()->doesNotThrow() &&
+ !isa<AllocaInst>(getUnderlyingObject(V))) {
+ for (const Instruction &I :
+ make_range(Start->getIterator(), End->getIterator())) {
+ if (I.mayThrow())
+ return true;
+ }
+ }
+ return false;
+}
+
+void MemCpyOptPass::eraseInstruction(Instruction *I) {
+ if (MSSAU)
+ MSSAU->removeMemoryAccess(I);
+ if (MD)
+ MD->removeInstruction(I);
+ I->eraseFromParent();
+}
+
+// Check for mod or ref of Loc between Start and End, excluding both boundaries.
+// Start and End must be in the same block
+static bool accessedBetween(AliasAnalysis &AA, MemoryLocation Loc,
+ const MemoryUseOrDef *Start,
+ const MemoryUseOrDef *End) {
+ assert(Start->getBlock() == End->getBlock() && "Only local supported");
+ for (const MemoryAccess &MA :
+ make_range(++Start->getIterator(), End->getIterator())) {
+ if (isModOrRefSet(AA.getModRefInfo(cast<MemoryUseOrDef>(MA).getMemoryInst(),
+ Loc)))
+ return true;
+ }
+ return false;
+}
+
+// Check for mod of Loc between Start and End, excluding both boundaries.
+// Start and End can be in different blocks.
+static bool writtenBetween(MemorySSA *MSSA, MemoryLocation Loc,
+ const MemoryUseOrDef *Start,
+ const MemoryUseOrDef *End) {
+ // TODO: Only walk until we hit Start.
+ MemoryAccess *Clobber = MSSA->getWalker()->getClobberingMemoryAccess(
+ End->getDefiningAccess(), Loc);
+ return !MSSA->dominates(Clobber, Start);
+}
+
/// When scanning forward over instructions, we look for some other patterns to
/// fold away. In particular, this looks for stores to neighboring locations of
/// memory. If it sees enough consecutive ones, it attempts to merge them
@@ -377,27 +377,27 @@ Instruction *MemCpyOptPass::tryMergingIntoMemset(Instruction *StartInst,
MemsetRanges Ranges(DL);
BasicBlock::iterator BI(StartInst);
-
- // Keeps track of the last memory use or def before the insertion point for
- // the new memset. The new MemoryDef for the inserted memsets will be inserted
- // after MemInsertPoint. It points to either LastMemDef or to the last user
- // before the insertion point of the memset, if there are any such users.
- MemoryUseOrDef *MemInsertPoint = nullptr;
- // Keeps track of the last MemoryDef between StartInst and the insertion point
- // for the new memset. This will become the defining access of the inserted
- // memsets.
- MemoryDef *LastMemDef = nullptr;
+
+ // Keeps track of the last memory use or def before the insertion point for
+ // the new memset. The new MemoryDef for the inserted memsets will be inserted
+ // after MemInsertPoint. It points to either LastMemDef or to the last user
+ // before the insertion point of the memset, if there are any such users.
+ MemoryUseOrDef *MemInsertPoint = nullptr;
+ // Keeps track of the last MemoryDef between StartInst and the insertion point
+ // for the new memset. This will become the defining access of the inserted
+ // memsets.
+ MemoryDef *LastMemDef = nullptr;
for (++BI; !BI->isTerminator(); ++BI) {
- if (MSSAU) {
- auto *CurrentAcc = cast_or_null<MemoryUseOrDef>(
- MSSAU->getMemorySSA()->getMemoryAccess(&*BI));
- if (CurrentAcc) {
- MemInsertPoint = CurrentAcc;
- if (auto *CurrentDef = dyn_cast<MemoryDef>(CurrentAcc))
- LastMemDef = CurrentDef;
- }
- }
-
+ if (MSSAU) {
+ auto *CurrentAcc = cast_or_null<MemoryUseOrDef>(
+ MSSAU->getMemorySSA()->getMemoryAccess(&*BI));
+ if (CurrentAcc) {
+ MemInsertPoint = CurrentAcc;
+ if (auto *CurrentDef = dyn_cast<MemoryDef>(CurrentAcc))
+ LastMemDef = CurrentDef;
+ }
+ }
+
if (!isa<StoreInst>(BI) && !isa<MemSetInst>(BI)) {
// If the instruction is readnone, ignore it, otherwise bail out. We
// don't even allow readonly here because we don't want something like:
@@ -411,15 +411,15 @@ Instruction *MemCpyOptPass::tryMergingIntoMemset(Instruction *StartInst,
// If this is a store, see if we can merge it in.
if (!NextStore->isSimple()) break;
- Value *StoredVal = NextStore->getValueOperand();
-
- // Don't convert stores of non-integral pointer types to memsets (which
- // stores integers).
- if (DL.isNonIntegralPointerType(StoredVal->getType()->getScalarType()))
- break;
-
+ Value *StoredVal = NextStore->getValueOperand();
+
+ // Don't convert stores of non-integral pointer types to memsets (which
+ // stores integers).
+ if (DL.isNonIntegralPointerType(StoredVal->getType()->getScalarType()))
+ break;
+
// Check to see if this stored value is of the same byte-splattable value.
- Value *StoredByte = isBytewiseValue(StoredVal, DL);
+ Value *StoredByte = isBytewiseValue(StoredVal, DL);
if (isa<UndefValue>(ByteVal) && StoredByte)
ByteVal = StoredByte;
if (ByteVal != StoredByte)
@@ -486,24 +486,24 @@ Instruction *MemCpyOptPass::tryMergingIntoMemset(Instruction *StartInst,
if (!Range.TheStores.empty())
AMemSet->setDebugLoc(Range.TheStores[0]->getDebugLoc());
- if (MSSAU) {
- assert(LastMemDef && MemInsertPoint &&
- "Both LastMemDef and MemInsertPoint need to be set");
- auto *NewDef =
- cast<MemoryDef>(MemInsertPoint->getMemoryInst() == &*BI
- ? MSSAU->createMemoryAccessBefore(
- AMemSet, LastMemDef, MemInsertPoint)
- : MSSAU->createMemoryAccessAfter(
- AMemSet, LastMemDef, MemInsertPoint));
- MSSAU->insertDef(NewDef, /*RenameUses=*/true);
- LastMemDef = NewDef;
- MemInsertPoint = NewDef;
- }
-
+ if (MSSAU) {
+ assert(LastMemDef && MemInsertPoint &&
+ "Both LastMemDef and MemInsertPoint need to be set");
+ auto *NewDef =
+ cast<MemoryDef>(MemInsertPoint->getMemoryInst() == &*BI
+ ? MSSAU->createMemoryAccessBefore(
+ AMemSet, LastMemDef, MemInsertPoint)
+ : MSSAU->createMemoryAccessAfter(
+ AMemSet, LastMemDef, MemInsertPoint));
+ MSSAU->insertDef(NewDef, /*RenameUses=*/true);
+ LastMemDef = NewDef;
+ MemInsertPoint = NewDef;
+ }
+
// Zap all the stores.
- for (Instruction *SI : Range.TheStores)
- eraseInstruction(SI);
-
+ for (Instruction *SI : Range.TheStores)
+ eraseInstruction(SI);
+
++NumMemSetInfer;
}
@@ -514,10 +514,10 @@ Instruction *MemCpyOptPass::tryMergingIntoMemset(Instruction *StartInst,
// It will lift the store and its argument + that anything that
// may alias with these.
// The method returns true if it was successful.
-bool MemCpyOptPass::moveUp(StoreInst *SI, Instruction *P, const LoadInst *LI) {
+bool MemCpyOptPass::moveUp(StoreInst *SI, Instruction *P, const LoadInst *LI) {
// If the store alias this position, early bail out.
MemoryLocation StoreLoc = MemoryLocation::get(SI);
- if (isModOrRefSet(AA->getModRefInfo(P, StoreLoc)))
+ if (isModOrRefSet(AA->getModRefInfo(P, StoreLoc)))
return false;
// Keep track of the arguments of all instruction we plan to lift
@@ -528,7 +528,7 @@ bool MemCpyOptPass::moveUp(StoreInst *SI, Instruction *P, const LoadInst *LI) {
Args.insert(Ptr);
// Instruction to lift before P.
- SmallVector<Instruction *, 8> ToLift{SI};
+ SmallVector<Instruction *, 8> ToLift{SI};
// Memory locations of lifted instructions.
SmallVector<MemoryLocation, 8> MemLocs{StoreLoc};
@@ -541,24 +541,24 @@ bool MemCpyOptPass::moveUp(StoreInst *SI, Instruction *P, const LoadInst *LI) {
for (auto I = --SI->getIterator(), E = P->getIterator(); I != E; --I) {
auto *C = &*I;
- // Make sure hoisting does not perform a store that was not guaranteed to
- // happen.
- if (!isGuaranteedToTransferExecutionToSuccessor(C))
- return false;
+ // Make sure hoisting does not perform a store that was not guaranteed to
+ // happen.
+ if (!isGuaranteedToTransferExecutionToSuccessor(C))
+ return false;
+
+ bool MayAlias = isModOrRefSet(AA->getModRefInfo(C, None));
- bool MayAlias = isModOrRefSet(AA->getModRefInfo(C, None));
-
bool NeedLift = false;
if (Args.erase(C))
NeedLift = true;
else if (MayAlias) {
- NeedLift = llvm::any_of(MemLocs, [C, this](const MemoryLocation &ML) {
- return isModOrRefSet(AA->getModRefInfo(C, ML));
+ NeedLift = llvm::any_of(MemLocs, [C, this](const MemoryLocation &ML) {
+ return isModOrRefSet(AA->getModRefInfo(C, ML));
});
if (!NeedLift)
- NeedLift = llvm::any_of(Calls, [C, this](const CallBase *Call) {
- return isModOrRefSet(AA->getModRefInfo(C, Call));
+ NeedLift = llvm::any_of(Calls, [C, this](const CallBase *Call) {
+ return isModOrRefSet(AA->getModRefInfo(C, Call));
});
}
@@ -568,18 +568,18 @@ bool MemCpyOptPass::moveUp(StoreInst *SI, Instruction *P, const LoadInst *LI) {
if (MayAlias) {
// Since LI is implicitly moved downwards past the lifted instructions,
// none of them may modify its source.
- if (isModSet(AA->getModRefInfo(C, LoadLoc)))
+ if (isModSet(AA->getModRefInfo(C, LoadLoc)))
return false;
else if (const auto *Call = dyn_cast<CallBase>(C)) {
// If we can't lift this before P, it's game over.
- if (isModOrRefSet(AA->getModRefInfo(P, Call)))
+ if (isModOrRefSet(AA->getModRefInfo(P, Call)))
return false;
Calls.push_back(Call);
} else if (isa<LoadInst>(C) || isa<StoreInst>(C) || isa<VAArgInst>(C)) {
// If we can't lift this before P, it's game over.
auto ML = MemoryLocation::get(C);
- if (isModOrRefSet(AA->getModRefInfo(P, ML)))
+ if (isModOrRefSet(AA->getModRefInfo(P, ML)))
return false;
MemLocs.push_back(ML);
@@ -599,40 +599,40 @@ bool MemCpyOptPass::moveUp(StoreInst *SI, Instruction *P, const LoadInst *LI) {
}
}
- // Find MSSA insertion point. Normally P will always have a corresponding
- // memory access before which we can insert. However, with non-standard AA
- // pipelines, there may be a mismatch between AA and MSSA, in which case we
- // will scan for a memory access before P. In either case, we know for sure
- // that at least the load will have a memory access.
- // TODO: Simplify this once P will be determined by MSSA, in which case the
- // discrepancy can no longer occur.
- MemoryUseOrDef *MemInsertPoint = nullptr;
- if (MSSAU) {
- if (MemoryUseOrDef *MA = MSSAU->getMemorySSA()->getMemoryAccess(P)) {
- MemInsertPoint = cast<MemoryUseOrDef>(--MA->getIterator());
- } else {
- const Instruction *ConstP = P;
- for (const Instruction &I : make_range(++ConstP->getReverseIterator(),
- ++LI->getReverseIterator())) {
- if (MemoryUseOrDef *MA = MSSAU->getMemorySSA()->getMemoryAccess(&I)) {
- MemInsertPoint = MA;
- break;
- }
- }
- }
- }
-
- // We made it, we need to lift.
+ // Find MSSA insertion point. Normally P will always have a corresponding
+ // memory access before which we can insert. However, with non-standard AA
+ // pipelines, there may be a mismatch between AA and MSSA, in which case we
+ // will scan for a memory access before P. In either case, we know for sure
+ // that at least the load will have a memory access.
+ // TODO: Simplify this once P will be determined by MSSA, in which case the
+ // discrepancy can no longer occur.
+ MemoryUseOrDef *MemInsertPoint = nullptr;
+ if (MSSAU) {
+ if (MemoryUseOrDef *MA = MSSAU->getMemorySSA()->getMemoryAccess(P)) {
+ MemInsertPoint = cast<MemoryUseOrDef>(--MA->getIterator());
+ } else {
+ const Instruction *ConstP = P;
+ for (const Instruction &I : make_range(++ConstP->getReverseIterator(),
+ ++LI->getReverseIterator())) {
+ if (MemoryUseOrDef *MA = MSSAU->getMemorySSA()->getMemoryAccess(&I)) {
+ MemInsertPoint = MA;
+ break;
+ }
+ }
+ }
+ }
+
+ // We made it, we need to lift.
for (auto *I : llvm::reverse(ToLift)) {
LLVM_DEBUG(dbgs() << "Lifting " << *I << " before " << *P << "\n");
I->moveBefore(P);
- if (MSSAU) {
- assert(MemInsertPoint && "Must have found insert point");
- if (MemoryUseOrDef *MA = MSSAU->getMemorySSA()->getMemoryAccess(I)) {
- MSSAU->moveAfter(MA, MemInsertPoint);
- MemInsertPoint = MA;
- }
- }
+ if (MSSAU) {
+ assert(MemInsertPoint && "Must have found insert point");
+ if (MemoryUseOrDef *MA = MSSAU->getMemorySSA()->getMemoryAccess(I)) {
+ MSSAU->moveAfter(MA, MemInsertPoint);
+ MemInsertPoint = MA;
+ }
+ }
}
return true;
@@ -652,15 +652,15 @@ bool MemCpyOptPass::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
const DataLayout &DL = SI->getModule()->getDataLayout();
- Value *StoredVal = SI->getValueOperand();
-
- // Not all the transforms below are correct for non-integral pointers, bail
- // until we've audited the individual pieces.
- if (DL.isNonIntegralPointerType(StoredVal->getType()->getScalarType()))
- return false;
-
+ Value *StoredVal = SI->getValueOperand();
+
+ // Not all the transforms below are correct for non-integral pointers, bail
+ // until we've audited the individual pieces.
+ if (DL.isNonIntegralPointerType(StoredVal->getType()->getScalarType()))
+ return false;
+
// Load to store forwarding can be interpreted as memcpy.
- if (LoadInst *LI = dyn_cast<LoadInst>(StoredVal)) {
+ if (LoadInst *LI = dyn_cast<LoadInst>(StoredVal)) {
if (LI->isSimple() && LI->hasOneUse() &&
LI->getParent() == SI->getParent()) {
@@ -672,10 +672,10 @@ bool MemCpyOptPass::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
// the memory we load from in between the load and the store. If
// such an instruction is found, we try to promote there instead
// of at the store position.
- // TODO: Can use MSSA for this.
+ // TODO: Can use MSSA for this.
Instruction *P = SI;
for (auto &I : make_range(++LI->getIterator(), SI->getIterator())) {
- if (isModSet(AA->getModRefInfo(&I, LoadLoc))) {
+ if (isModSet(AA->getModRefInfo(&I, LoadLoc))) {
P = &I;
break;
}
@@ -686,7 +686,7 @@ bool MemCpyOptPass::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
// position if nothing alias the store memory after this and the store
// destination is not in the range.
if (P && P != SI) {
- if (!moveUp(SI, P, LI))
+ if (!moveUp(SI, P, LI))
P = nullptr;
}
@@ -697,7 +697,7 @@ bool MemCpyOptPass::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
// memmove must be used to preserve semantic. If not, memcpy can
// be used.
bool UseMemMove = false;
- if (!AA->isNoAlias(MemoryLocation::get(SI), LoadLoc))
+ if (!AA->isNoAlias(MemoryLocation::get(SI), LoadLoc))
UseMemMove = true;
uint64_t Size = DL.getTypeStoreSize(T);
@@ -716,16 +716,16 @@ bool MemCpyOptPass::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
LLVM_DEBUG(dbgs() << "Promoting " << *LI << " to " << *SI << " => "
<< *M << "\n");
- if (MSSAU) {
- auto *LastDef =
- cast<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(SI));
- auto *NewAccess =
- MSSAU->createMemoryAccessAfter(M, LastDef, LastDef);
- MSSAU->insertDef(cast<MemoryDef>(NewAccess), /*RenameUses=*/true);
- }
-
- eraseInstruction(SI);
- eraseInstruction(LI);
+ if (MSSAU) {
+ auto *LastDef =
+ cast<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(SI));
+ auto *NewAccess =
+ MSSAU->createMemoryAccessAfter(M, LastDef, LastDef);
+ MSSAU->insertDef(cast<MemoryDef>(NewAccess), /*RenameUses=*/true);
+ }
+
+ eraseInstruction(SI);
+ eraseInstruction(LI);
++NumMemCpyInstr;
// Make sure we do not invalidate the iterator.
@@ -738,49 +738,49 @@ bool MemCpyOptPass::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
// happen to be using a load-store pair to implement it, rather than
// a memcpy.
CallInst *C = nullptr;
- if (EnableMemorySSA) {
- if (auto *LoadClobber = dyn_cast<MemoryUseOrDef>(
- MSSA->getWalker()->getClobberingMemoryAccess(LI))) {
- // The load most post-dom the call. Limit to the same block for now.
- // TODO: Support non-local call-slot optimization?
- if (LoadClobber->getBlock() == SI->getParent())
- C = dyn_cast_or_null<CallInst>(LoadClobber->getMemoryInst());
- }
- } else {
- MemDepResult ldep = MD->getDependency(LI);
- if (ldep.isClobber() && !isa<MemCpyInst>(ldep.getInst()))
- C = dyn_cast<CallInst>(ldep.getInst());
- }
+ if (EnableMemorySSA) {
+ if (auto *LoadClobber = dyn_cast<MemoryUseOrDef>(
+ MSSA->getWalker()->getClobberingMemoryAccess(LI))) {
+ // The load most post-dom the call. Limit to the same block for now.
+ // TODO: Support non-local call-slot optimization?
+ if (LoadClobber->getBlock() == SI->getParent())
+ C = dyn_cast_or_null<CallInst>(LoadClobber->getMemoryInst());
+ }
+ } else {
+ MemDepResult ldep = MD->getDependency(LI);
+ if (ldep.isClobber() && !isa<MemCpyInst>(ldep.getInst()))
+ C = dyn_cast<CallInst>(ldep.getInst());
+ }
if (C) {
// Check that nothing touches the dest of the "copy" between
// the call and the store.
MemoryLocation StoreLoc = MemoryLocation::get(SI);
- if (EnableMemorySSA) {
- if (accessedBetween(*AA, StoreLoc, MSSA->getMemoryAccess(C),
- MSSA->getMemoryAccess(SI)))
+ if (EnableMemorySSA) {
+ if (accessedBetween(*AA, StoreLoc, MSSA->getMemoryAccess(C),
+ MSSA->getMemoryAccess(SI)))
C = nullptr;
- } else {
- for (BasicBlock::iterator I = --SI->getIterator(),
- E = C->getIterator();
- I != E; --I) {
- if (isModOrRefSet(AA->getModRefInfo(&*I, StoreLoc))) {
- C = nullptr;
- break;
- }
+ } else {
+ for (BasicBlock::iterator I = --SI->getIterator(),
+ E = C->getIterator();
+ I != E; --I) {
+ if (isModOrRefSet(AA->getModRefInfo(&*I, StoreLoc))) {
+ C = nullptr;
+ break;
+ }
}
}
}
if (C) {
bool changed = performCallSlotOptzn(
- LI, SI, SI->getPointerOperand()->stripPointerCasts(),
+ LI, SI, SI->getPointerOperand()->stripPointerCasts(),
LI->getPointerOperand()->stripPointerCasts(),
DL.getTypeStoreSize(SI->getOperand(0)->getType()),
commonAlignment(SI->getAlign(), LI->getAlign()), C);
if (changed) {
- eraseInstruction(SI);
- eraseInstruction(LI);
+ eraseInstruction(SI);
+ eraseInstruction(LI);
++NumMemCpyInstr;
return true;
}
@@ -814,15 +814,15 @@ bool MemCpyOptPass::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
LLVM_DEBUG(dbgs() << "Promoting " << *SI << " to " << *M << "\n");
- if (MSSAU) {
- assert(isa<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(SI)));
- auto *LastDef =
- cast<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(SI));
- auto *NewAccess = MSSAU->createMemoryAccessAfter(M, LastDef, LastDef);
- MSSAU->insertDef(cast<MemoryDef>(NewAccess), /*RenameUses=*/true);
- }
-
- eraseInstruction(SI);
+ if (MSSAU) {
+ assert(isa<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(SI)));
+ auto *LastDef =
+ cast<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(SI));
+ auto *NewAccess = MSSAU->createMemoryAccessAfter(M, LastDef, LastDef);
+ MSSAU->insertDef(cast<MemoryDef>(NewAccess), /*RenameUses=*/true);
+ }
+
+ eraseInstruction(SI);
NumMemSetInfer++;
// Make sure we do not invalidate the iterator.
@@ -849,8 +849,8 @@ bool MemCpyOptPass::processMemSet(MemSetInst *MSI, BasicBlock::iterator &BBI) {
/// Takes a memcpy and a call that it depends on,
/// and checks for the possibility of a call slot optimization by having
/// the call write its result directly into the destination of the memcpy.
-bool MemCpyOptPass::performCallSlotOptzn(Instruction *cpyLoad,
- Instruction *cpyStore, Value *cpyDest,
+bool MemCpyOptPass::performCallSlotOptzn(Instruction *cpyLoad,
+ Instruction *cpyStore, Value *cpyDest,
Value *cpySrc, uint64_t cpyLen,
Align cpyAlign, CallInst *C) {
// The general transformation to keep in mind is
@@ -881,7 +881,7 @@ bool MemCpyOptPass::performCallSlotOptzn(Instruction *cpyLoad,
if (!srcArraySize)
return false;
- const DataLayout &DL = cpyLoad->getModule()->getDataLayout();
+ const DataLayout &DL = cpyLoad->getModule()->getDataLayout();
uint64_t srcSize = DL.getTypeAllocSize(srcAlloca->getAllocatedType()) *
srcArraySize->getZExtValue();
@@ -891,25 +891,25 @@ bool MemCpyOptPass::performCallSlotOptzn(Instruction *cpyLoad,
// Check that accessing the first srcSize bytes of dest will not cause a
// trap. Otherwise the transform is invalid since it might cause a trap
// to occur earlier than it otherwise would.
- if (!isDereferenceableAndAlignedPointer(cpyDest, Align(1), APInt(64, cpyLen),
- DL, C, DT))
- return false;
-
- // Make sure that nothing can observe cpyDest being written early. There are
- // a number of cases to consider:
- // 1. cpyDest cannot be accessed between C and cpyStore as a precondition of
- // the transform.
- // 2. C itself may not access cpyDest (prior to the transform). This is
- // checked further below.
- // 3. If cpyDest is accessible to the caller of this function (potentially
- // captured and not based on an alloca), we need to ensure that we cannot
- // unwind between C and cpyStore. This is checked here.
- // 4. If cpyDest is potentially captured, there may be accesses to it from
- // another thread. In this case, we need to check that cpyStore is
- // guaranteed to be executed if C is. As it is a non-atomic access, it
- // renders accesses from other threads undefined.
- // TODO: This is currently not checked.
- if (mayBeVisibleThroughUnwinding(cpyDest, C, cpyStore))
+ if (!isDereferenceableAndAlignedPointer(cpyDest, Align(1), APInt(64, cpyLen),
+ DL, C, DT))
+ return false;
+
+ // Make sure that nothing can observe cpyDest being written early. There are
+ // a number of cases to consider:
+ // 1. cpyDest cannot be accessed between C and cpyStore as a precondition of
+ // the transform.
+ // 2. C itself may not access cpyDest (prior to the transform). This is
+ // checked further below.
+ // 3. If cpyDest is accessible to the caller of this function (potentially
+ // captured and not based on an alloca), we need to ensure that we cannot
+ // unwind between C and cpyStore. This is checked here.
+ // 4. If cpyDest is potentially captured, there may be accesses to it from
+ // another thread. In this case, we need to check that cpyStore is
+ // guaranteed to be executed if C is. As it is a non-atomic access, it
+ // renders accesses from other threads undefined.
+ // TODO: This is currently not checked.
+ if (mayBeVisibleThroughUnwinding(cpyDest, C, cpyStore))
return false;
// Check that dest points to memory that is at least as aligned as src.
@@ -924,26 +924,26 @@ bool MemCpyOptPass::performCallSlotOptzn(Instruction *cpyLoad,
// guarantees that it holds only undefined values when passed in (so the final
// memcpy can be dropped), that it is not read or written between the call and
// the memcpy, and that writing beyond the end of it is undefined.
- SmallVector<User *, 8> srcUseList(srcAlloca->users());
+ SmallVector<User *, 8> srcUseList(srcAlloca->users());
while (!srcUseList.empty()) {
User *U = srcUseList.pop_back_val();
if (isa<BitCastInst>(U) || isa<AddrSpaceCastInst>(U)) {
- append_range(srcUseList, U->users());
+ append_range(srcUseList, U->users());
continue;
}
if (GetElementPtrInst *G = dyn_cast<GetElementPtrInst>(U)) {
if (!G->hasAllZeroIndices())
return false;
- append_range(srcUseList, U->users());
+ append_range(srcUseList, U->users());
continue;
}
if (const IntrinsicInst *IT = dyn_cast<IntrinsicInst>(U))
if (IT->isLifetimeStartOrEnd())
continue;
- if (U != C && U != cpyLoad)
+ if (U != C && U != cpyLoad)
return false;
}
@@ -955,24 +955,24 @@ bool MemCpyOptPass::performCallSlotOptzn(Instruction *cpyLoad,
// Since we're changing the parameter to the callsite, we need to make sure
// that what would be the new parameter dominates the callsite.
- if (!DT->dominates(cpyDest, C)) {
- // Support moving a constant index GEP before the call.
- auto *GEP = dyn_cast<GetElementPtrInst>(cpyDest);
- if (GEP && GEP->hasAllConstantIndices() &&
- DT->dominates(GEP->getPointerOperand(), C))
- GEP->moveBefore(C);
- else
+ if (!DT->dominates(cpyDest, C)) {
+ // Support moving a constant index GEP before the call.
+ auto *GEP = dyn_cast<GetElementPtrInst>(cpyDest);
+ if (GEP && GEP->hasAllConstantIndices() &&
+ DT->dominates(GEP->getPointerOperand(), C))
+ GEP->moveBefore(C);
+ else
return false;
- }
+ }
// In addition to knowing that the call does not access src in some
// unexpected manner, for example via a global, which we deduce from
// the use analysis, we also need to know that it does not sneakily
// access dest. We rely on AA to figure this out for us.
- ModRefInfo MR = AA->getModRefInfo(C, cpyDest, LocationSize::precise(srcSize));
+ ModRefInfo MR = AA->getModRefInfo(C, cpyDest, LocationSize::precise(srcSize));
// If necessary, perform additional analysis.
if (isModOrRefSet(MR))
- MR = AA->callCapturesBefore(C, cpyDest, LocationSize::precise(srcSize), DT);
+ MR = AA->callCapturesBefore(C, cpyDest, LocationSize::precise(srcSize), DT);
if (isModOrRefSet(MR))
return false;
@@ -1014,8 +1014,8 @@ bool MemCpyOptPass::performCallSlotOptzn(Instruction *cpyLoad,
// Drop any cached information about the call, because we may have changed
// its dependence information by changing its parameter.
- if (MD)
- MD->removeInstruction(C);
+ if (MD)
+ MD->removeInstruction(C);
// Update AA metadata
// FIXME: MD_tbaa_struct and MD_mem_parallel_loop_access should also be
@@ -1024,9 +1024,9 @@ bool MemCpyOptPass::performCallSlotOptzn(Instruction *cpyLoad,
LLVMContext::MD_noalias,
LLVMContext::MD_invariant_group,
LLVMContext::MD_access_group};
- combineMetadata(C, cpyLoad, KnownIDs, true);
+ combineMetadata(C, cpyLoad, KnownIDs, true);
- ++NumCallSlot;
+ ++NumCallSlot;
return true;
}
@@ -1063,28 +1063,28 @@ bool MemCpyOptPass::processMemCpyMemCpyDependence(MemCpyInst *M,
//
// TODO: If the code between M and MDep is transparent to the destination "c",
// then we could still perform the xform by moving M up to the first memcpy.
- if (EnableMemorySSA) {
- // TODO: It would be sufficient to check the MDep source up to the memcpy
- // size of M, rather than MDep.
- if (writtenBetween(MSSA, MemoryLocation::getForSource(MDep),
- MSSA->getMemoryAccess(MDep), MSSA->getMemoryAccess(M)))
- return false;
- } else {
- // NOTE: This is conservative, it will stop on any read from the source loc,
- // not just the defining memcpy.
- MemDepResult SourceDep =
- MD->getPointerDependencyFrom(MemoryLocation::getForSource(MDep), false,
- M->getIterator(), M->getParent());
- if (!SourceDep.isClobber() || SourceDep.getInst() != MDep)
- return false;
- }
+ if (EnableMemorySSA) {
+ // TODO: It would be sufficient to check the MDep source up to the memcpy
+ // size of M, rather than MDep.
+ if (writtenBetween(MSSA, MemoryLocation::getForSource(MDep),
+ MSSA->getMemoryAccess(MDep), MSSA->getMemoryAccess(M)))
+ return false;
+ } else {
+ // NOTE: This is conservative, it will stop on any read from the source loc,
+ // not just the defining memcpy.
+ MemDepResult SourceDep =
+ MD->getPointerDependencyFrom(MemoryLocation::getForSource(MDep), false,
+ M->getIterator(), M->getParent());
+ if (!SourceDep.isClobber() || SourceDep.getInst() != MDep)
+ return false;
+ }
// If the dest of the second might alias the source of the first, then the
// source and dest might overlap. We still want to eliminate the intermediate
// value, but we have to generate a memmove instead of memcpy.
bool UseMemMove = false;
- if (!AA->isNoAlias(MemoryLocation::getForDest(M),
- MemoryLocation::getForSource(MDep)))
+ if (!AA->isNoAlias(MemoryLocation::getForDest(M),
+ MemoryLocation::getForSource(MDep)))
UseMemMove = true;
// If all checks passed, then we can transform M.
@@ -1094,25 +1094,25 @@ bool MemCpyOptPass::processMemCpyMemCpyDependence(MemCpyInst *M,
// TODO: Is this worth it if we're creating a less aligned memcpy? For
// example we could be moving from movaps -> movq on x86.
IRBuilder<> Builder(M);
- Instruction *NewM;
+ Instruction *NewM;
if (UseMemMove)
- NewM = Builder.CreateMemMove(M->getRawDest(), M->getDestAlign(),
- MDep->getRawSource(), MDep->getSourceAlign(),
- M->getLength(), M->isVolatile());
+ NewM = Builder.CreateMemMove(M->getRawDest(), M->getDestAlign(),
+ MDep->getRawSource(), MDep->getSourceAlign(),
+ M->getLength(), M->isVolatile());
else
- NewM = Builder.CreateMemCpy(M->getRawDest(), M->getDestAlign(),
- MDep->getRawSource(), MDep->getSourceAlign(),
- M->getLength(), M->isVolatile());
-
- if (MSSAU) {
- assert(isa<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(M)));
- auto *LastDef = cast<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(M));
- auto *NewAccess = MSSAU->createMemoryAccessAfter(NewM, LastDef, LastDef);
- MSSAU->insertDef(cast<MemoryDef>(NewAccess), /*RenameUses=*/true);
- }
-
+ NewM = Builder.CreateMemCpy(M->getRawDest(), M->getDestAlign(),
+ MDep->getRawSource(), MDep->getSourceAlign(),
+ M->getLength(), M->isVolatile());
+
+ if (MSSAU) {
+ assert(isa<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(M)));
+ auto *LastDef = cast<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(M));
+ auto *NewAccess = MSSAU->createMemoryAccessAfter(NewM, LastDef, LastDef);
+ MSSAU->insertDef(cast<MemoryDef>(NewAccess), /*RenameUses=*/true);
+ }
+
// Remove the instruction we're replacing.
- eraseInstruction(M);
+ eraseInstruction(M);
++NumMemCpyInstr;
return true;
}
@@ -1137,41 +1137,41 @@ bool MemCpyOptPass::processMemSetMemCpyDependence(MemCpyInst *MemCpy,
if (MemSet->getDest() != MemCpy->getDest())
return false;
- // Check that src and dst of the memcpy aren't the same. While memcpy
- // operands cannot partially overlap, exact equality is allowed.
- if (!AA->isNoAlias(MemoryLocation(MemCpy->getSource(),
- LocationSize::precise(1)),
- MemoryLocation(MemCpy->getDest(),
- LocationSize::precise(1))))
+ // Check that src and dst of the memcpy aren't the same. While memcpy
+ // operands cannot partially overlap, exact equality is allowed.
+ if (!AA->isNoAlias(MemoryLocation(MemCpy->getSource(),
+ LocationSize::precise(1)),
+ MemoryLocation(MemCpy->getDest(),
+ LocationSize::precise(1))))
return false;
- if (EnableMemorySSA) {
- // We know that dst up to src_size is not written. We now need to make sure
- // that dst up to dst_size is not accessed. (If we did not move the memset,
- // checking for reads would be sufficient.)
- if (accessedBetween(*AA, MemoryLocation::getForDest(MemSet),
- MSSA->getMemoryAccess(MemSet),
- MSSA->getMemoryAccess(MemCpy))) {
- return false;
- }
- } else {
- // We have already checked that dst up to src_size is not accessed. We
- // need to make sure that there are no accesses up to dst_size either.
- MemDepResult DstDepInfo = MD->getPointerDependencyFrom(
- MemoryLocation::getForDest(MemSet), false, MemCpy->getIterator(),
- MemCpy->getParent());
- if (DstDepInfo.getInst() != MemSet)
- return false;
- }
-
+ if (EnableMemorySSA) {
+ // We know that dst up to src_size is not written. We now need to make sure
+ // that dst up to dst_size is not accessed. (If we did not move the memset,
+ // checking for reads would be sufficient.)
+ if (accessedBetween(*AA, MemoryLocation::getForDest(MemSet),
+ MSSA->getMemoryAccess(MemSet),
+ MSSA->getMemoryAccess(MemCpy))) {
+ return false;
+ }
+ } else {
+ // We have already checked that dst up to src_size is not accessed. We
+ // need to make sure that there are no accesses up to dst_size either.
+ MemDepResult DstDepInfo = MD->getPointerDependencyFrom(
+ MemoryLocation::getForDest(MemSet), false, MemCpy->getIterator(),
+ MemCpy->getParent());
+ if (DstDepInfo.getInst() != MemSet)
+ return false;
+ }
+
// Use the same i8* dest as the memcpy, killing the memset dest if different.
Value *Dest = MemCpy->getRawDest();
Value *DestSize = MemSet->getLength();
Value *SrcSize = MemCpy->getLength();
- if (mayBeVisibleThroughUnwinding(Dest, MemSet, MemCpy))
- return false;
-
+ if (mayBeVisibleThroughUnwinding(Dest, MemSet, MemCpy))
+ return false;
+
// By default, create an unaligned memset.
unsigned Align = 1;
// If Dest is aligned, and SrcSize is constant, use the minimum alignment
@@ -1197,25 +1197,25 @@ bool MemCpyOptPass::processMemSetMemCpyDependence(MemCpyInst *MemCpy,
Value *SizeDiff = Builder.CreateSub(DestSize, SrcSize);
Value *MemsetLen = Builder.CreateSelect(
Ule, ConstantInt::getNullValue(DestSize->getType()), SizeDiff);
- Instruction *NewMemSet = Builder.CreateMemSet(
+ Instruction *NewMemSet = Builder.CreateMemSet(
Builder.CreateGEP(Dest->getType()->getPointerElementType(), Dest,
SrcSize),
MemSet->getOperand(1), MemsetLen, MaybeAlign(Align));
- if (MSSAU) {
- assert(isa<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(MemCpy)) &&
- "MemCpy must be a MemoryDef");
- // The new memset is inserted after the memcpy, but it is known that its
- // defining access is the memset about to be removed which immediately
- // precedes the memcpy.
- auto *LastDef =
- cast<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(MemCpy));
- auto *NewAccess = MSSAU->createMemoryAccessBefore(
- NewMemSet, LastDef->getDefiningAccess(), LastDef);
- MSSAU->insertDef(cast<MemoryDef>(NewAccess), /*RenameUses=*/true);
- }
-
- eraseInstruction(MemSet);
+ if (MSSAU) {
+ assert(isa<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(MemCpy)) &&
+ "MemCpy must be a MemoryDef");
+ // The new memset is inserted after the memcpy, but it is known that its
+ // defining access is the memset about to be removed which immediately
+ // precedes the memcpy.
+ auto *LastDef =
+ cast<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(MemCpy));
+ auto *NewAccess = MSSAU->createMemoryAccessBefore(
+ NewMemSet, LastDef->getDefiningAccess(), LastDef);
+ MSSAU->insertDef(cast<MemoryDef>(NewAccess), /*RenameUses=*/true);
+ }
+
+ eraseInstruction(MemSet);
return true;
}
@@ -1234,24 +1234,24 @@ static bool hasUndefContents(Instruction *I, ConstantInt *Size) {
return false;
}
-static bool hasUndefContentsMSSA(MemorySSA *MSSA, AliasAnalysis *AA, Value *V,
- MemoryDef *Def, ConstantInt *Size) {
- if (MSSA->isLiveOnEntryDef(Def))
- return isa<AllocaInst>(getUnderlyingObject(V));
-
- if (IntrinsicInst *II =
- dyn_cast_or_null<IntrinsicInst>(Def->getMemoryInst())) {
- if (II->getIntrinsicID() == Intrinsic::lifetime_start) {
- ConstantInt *LTSize = cast<ConstantInt>(II->getArgOperand(0));
- if (AA->isMustAlias(V, II->getArgOperand(1)) &&
- LTSize->getZExtValue() >= Size->getZExtValue())
- return true;
- }
- }
-
- return false;
-}
-
+static bool hasUndefContentsMSSA(MemorySSA *MSSA, AliasAnalysis *AA, Value *V,
+ MemoryDef *Def, ConstantInt *Size) {
+ if (MSSA->isLiveOnEntryDef(Def))
+ return isa<AllocaInst>(getUnderlyingObject(V));
+
+ if (IntrinsicInst *II =
+ dyn_cast_or_null<IntrinsicInst>(Def->getMemoryInst())) {
+ if (II->getIntrinsicID() == Intrinsic::lifetime_start) {
+ ConstantInt *LTSize = cast<ConstantInt>(II->getArgOperand(0));
+ if (AA->isMustAlias(V, II->getArgOperand(1)) &&
+ LTSize->getZExtValue() >= Size->getZExtValue())
+ return true;
+ }
+ }
+
+ return false;
+}
+
/// Transform memcpy to memset when its source was just memset.
/// In other words, turn:
/// \code
@@ -1270,7 +1270,7 @@ bool MemCpyOptPass::performMemCpyToMemSetOptzn(MemCpyInst *MemCpy,
MemSetInst *MemSet) {
// Make sure that memcpy(..., memset(...), ...), that is we are memsetting and
// memcpying from the same address. Otherwise it is hard to reason about.
- if (!AA->isMustAlias(MemSet->getRawDest(), MemCpy->getRawSource()))
+ if (!AA->isMustAlias(MemSet->getRawDest(), MemCpy->getRawSource()))
return false;
// A known memset size is required.
@@ -1287,37 +1287,37 @@ bool MemCpyOptPass::performMemCpyToMemSetOptzn(MemCpyInst *MemCpy,
// interested in the bytes from MemSetSize..CopySize here, but as we can't
// easily represent this location, we use the full 0..CopySize range.
MemoryLocation MemCpyLoc = MemoryLocation::getForSource(MemCpy);
- bool CanReduceSize = false;
- if (EnableMemorySSA) {
- MemoryUseOrDef *MemSetAccess = MSSA->getMemoryAccess(MemSet);
- MemoryAccess *Clobber = MSSA->getWalker()->getClobberingMemoryAccess(
- MemSetAccess->getDefiningAccess(), MemCpyLoc);
- if (auto *MD = dyn_cast<MemoryDef>(Clobber))
- if (hasUndefContentsMSSA(MSSA, AA, MemCpy->getSource(), MD, CopySize))
- CanReduceSize = true;
- } else {
- MemDepResult DepInfo = MD->getPointerDependencyFrom(
- MemCpyLoc, true, MemSet->getIterator(), MemSet->getParent());
- if (DepInfo.isDef() && hasUndefContents(DepInfo.getInst(), CopySize))
- CanReduceSize = true;
- }
-
- if (!CanReduceSize)
+ bool CanReduceSize = false;
+ if (EnableMemorySSA) {
+ MemoryUseOrDef *MemSetAccess = MSSA->getMemoryAccess(MemSet);
+ MemoryAccess *Clobber = MSSA->getWalker()->getClobberingMemoryAccess(
+ MemSetAccess->getDefiningAccess(), MemCpyLoc);
+ if (auto *MD = dyn_cast<MemoryDef>(Clobber))
+ if (hasUndefContentsMSSA(MSSA, AA, MemCpy->getSource(), MD, CopySize))
+ CanReduceSize = true;
+ } else {
+ MemDepResult DepInfo = MD->getPointerDependencyFrom(
+ MemCpyLoc, true, MemSet->getIterator(), MemSet->getParent());
+ if (DepInfo.isDef() && hasUndefContents(DepInfo.getInst(), CopySize))
+ CanReduceSize = true;
+ }
+
+ if (!CanReduceSize)
return false;
- CopySize = MemSetSize;
+ CopySize = MemSetSize;
}
IRBuilder<> Builder(MemCpy);
- Instruction *NewM =
- Builder.CreateMemSet(MemCpy->getRawDest(), MemSet->getOperand(1),
- CopySize, MaybeAlign(MemCpy->getDestAlignment()));
- if (MSSAU) {
- auto *LastDef =
- cast<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(MemCpy));
- auto *NewAccess = MSSAU->createMemoryAccessAfter(NewM, LastDef, LastDef);
- MSSAU->insertDef(cast<MemoryDef>(NewAccess), /*RenameUses=*/true);
- }
-
+ Instruction *NewM =
+ Builder.CreateMemSet(MemCpy->getRawDest(), MemSet->getOperand(1),
+ CopySize, MaybeAlign(MemCpy->getDestAlignment()));
+ if (MSSAU) {
+ auto *LastDef =
+ cast<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(MemCpy));
+ auto *NewAccess = MSSAU->createMemoryAccessAfter(NewM, LastDef, LastDef);
+ MSSAU->insertDef(cast<MemoryDef>(NewAccess), /*RenameUses=*/true);
+ }
+
return true;
}
@@ -1333,7 +1333,7 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI) {
// If the source and destination of the memcpy are the same, then zap it.
if (M->getSource() == M->getDest()) {
++BBI;
- eraseInstruction(M);
+ eraseInstruction(M);
return true;
}
@@ -1343,157 +1343,157 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI) {
if (Value *ByteVal = isBytewiseValue(GV->getInitializer(),
M->getModule()->getDataLayout())) {
IRBuilder<> Builder(M);
- Instruction *NewM =
- Builder.CreateMemSet(M->getRawDest(), ByteVal, M->getLength(),
- MaybeAlign(M->getDestAlignment()), false);
- if (MSSAU) {
- auto *LastDef =
- cast<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(M));
- auto *NewAccess =
- MSSAU->createMemoryAccessAfter(NewM, LastDef, LastDef);
- MSSAU->insertDef(cast<MemoryDef>(NewAccess), /*RenameUses=*/true);
- }
-
- eraseInstruction(M);
+ Instruction *NewM =
+ Builder.CreateMemSet(M->getRawDest(), ByteVal, M->getLength(),
+ MaybeAlign(M->getDestAlignment()), false);
+ if (MSSAU) {
+ auto *LastDef =
+ cast<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(M));
+ auto *NewAccess =
+ MSSAU->createMemoryAccessAfter(NewM, LastDef, LastDef);
+ MSSAU->insertDef(cast<MemoryDef>(NewAccess), /*RenameUses=*/true);
+ }
+
+ eraseInstruction(M);
++NumCpyToSet;
return true;
}
- if (EnableMemorySSA) {
- MemoryUseOrDef *MA = MSSA->getMemoryAccess(M);
- MemoryAccess *AnyClobber = MSSA->getWalker()->getClobberingMemoryAccess(MA);
- MemoryLocation DestLoc = MemoryLocation::getForDest(M);
- const MemoryAccess *DestClobber =
- MSSA->getWalker()->getClobberingMemoryAccess(AnyClobber, DestLoc);
-
- // Try to turn a partially redundant memset + memcpy into
- // memcpy + smaller memset. We don't need the memcpy size for this.
- // The memcpy most post-dom the memset, so limit this to the same basic
- // block. A non-local generalization is likely not worthwhile.
- if (auto *MD = dyn_cast<MemoryDef>(DestClobber))
- if (auto *MDep = dyn_cast_or_null<MemSetInst>(MD->getMemoryInst()))
- if (DestClobber->getBlock() == M->getParent())
- if (processMemSetMemCpyDependence(M, MDep))
- return true;
-
- // The optimizations after this point require the memcpy size.
- ConstantInt *CopySize = dyn_cast<ConstantInt>(M->getLength());
- if (!CopySize) return false;
-
- MemoryAccess *SrcClobber = MSSA->getWalker()->getClobberingMemoryAccess(
- AnyClobber, MemoryLocation::getForSource(M));
-
- // There are four possible optimizations we can do for memcpy:
- // a) memcpy-memcpy xform which exposes redundance for DSE.
- // b) call-memcpy xform for return slot optimization.
- // c) memcpy from freshly alloca'd space or space that has just started
- // its lifetime copies undefined data, and we can therefore eliminate
- // the memcpy in favor of the data that was already at the destination.
- // d) memcpy from a just-memset'd source can be turned into memset.
- if (auto *MD = dyn_cast<MemoryDef>(SrcClobber)) {
- if (Instruction *MI = MD->getMemoryInst()) {
- if (auto *C = dyn_cast<CallInst>(MI)) {
- // The memcpy must post-dom the call. Limit to the same block for now.
- // Additionally, we need to ensure that there are no accesses to dest
- // between the call and the memcpy. Accesses to src will be checked
- // by performCallSlotOptzn().
- // TODO: Support non-local call-slot optimization?
- if (C->getParent() == M->getParent() &&
- !accessedBetween(*AA, DestLoc, MD, MA)) {
- // FIXME: Can we pass in either of dest/src alignment here instead
- // of conservatively taking the minimum?
- Align Alignment = std::min(M->getDestAlign().valueOrOne(),
- M->getSourceAlign().valueOrOne());
- if (performCallSlotOptzn(M, M, M->getDest(), M->getSource(),
- CopySize->getZExtValue(), Alignment, C)) {
- LLVM_DEBUG(dbgs() << "Performed call slot optimization:\n"
- << " call: " << *C << "\n"
- << " memcpy: " << *M << "\n");
- eraseInstruction(M);
- ++NumMemCpyInstr;
- return true;
- }
- }
- }
- if (auto *MDep = dyn_cast<MemCpyInst>(MI))
- return processMemCpyMemCpyDependence(M, MDep);
- if (auto *MDep = dyn_cast<MemSetInst>(MI)) {
- if (performMemCpyToMemSetOptzn(M, MDep)) {
- LLVM_DEBUG(dbgs() << "Converted memcpy to memset\n");
- eraseInstruction(M);
- ++NumCpyToSet;
- return true;
- }
- }
- }
-
- if (hasUndefContentsMSSA(MSSA, AA, M->getSource(), MD, CopySize)) {
- LLVM_DEBUG(dbgs() << "Removed memcpy from undef\n");
- eraseInstruction(M);
- ++NumMemCpyInstr;
+ if (EnableMemorySSA) {
+ MemoryUseOrDef *MA = MSSA->getMemoryAccess(M);
+ MemoryAccess *AnyClobber = MSSA->getWalker()->getClobberingMemoryAccess(MA);
+ MemoryLocation DestLoc = MemoryLocation::getForDest(M);
+ const MemoryAccess *DestClobber =
+ MSSA->getWalker()->getClobberingMemoryAccess(AnyClobber, DestLoc);
+
+ // Try to turn a partially redundant memset + memcpy into
+ // memcpy + smaller memset. We don't need the memcpy size for this.
+ // The memcpy most post-dom the memset, so limit this to the same basic
+ // block. A non-local generalization is likely not worthwhile.
+ if (auto *MD = dyn_cast<MemoryDef>(DestClobber))
+ if (auto *MDep = dyn_cast_or_null<MemSetInst>(MD->getMemoryInst()))
+ if (DestClobber->getBlock() == M->getParent())
+ if (processMemSetMemCpyDependence(M, MDep))
+ return true;
+
+ // The optimizations after this point require the memcpy size.
+ ConstantInt *CopySize = dyn_cast<ConstantInt>(M->getLength());
+ if (!CopySize) return false;
+
+ MemoryAccess *SrcClobber = MSSA->getWalker()->getClobberingMemoryAccess(
+ AnyClobber, MemoryLocation::getForSource(M));
+
+ // There are four possible optimizations we can do for memcpy:
+ // a) memcpy-memcpy xform which exposes redundance for DSE.
+ // b) call-memcpy xform for return slot optimization.
+ // c) memcpy from freshly alloca'd space or space that has just started
+ // its lifetime copies undefined data, and we can therefore eliminate
+ // the memcpy in favor of the data that was already at the destination.
+ // d) memcpy from a just-memset'd source can be turned into memset.
+ if (auto *MD = dyn_cast<MemoryDef>(SrcClobber)) {
+ if (Instruction *MI = MD->getMemoryInst()) {
+ if (auto *C = dyn_cast<CallInst>(MI)) {
+ // The memcpy must post-dom the call. Limit to the same block for now.
+ // Additionally, we need to ensure that there are no accesses to dest
+ // between the call and the memcpy. Accesses to src will be checked
+ // by performCallSlotOptzn().
+ // TODO: Support non-local call-slot optimization?
+ if (C->getParent() == M->getParent() &&
+ !accessedBetween(*AA, DestLoc, MD, MA)) {
+ // FIXME: Can we pass in either of dest/src alignment here instead
+ // of conservatively taking the minimum?
+ Align Alignment = std::min(M->getDestAlign().valueOrOne(),
+ M->getSourceAlign().valueOrOne());
+ if (performCallSlotOptzn(M, M, M->getDest(), M->getSource(),
+ CopySize->getZExtValue(), Alignment, C)) {
+ LLVM_DEBUG(dbgs() << "Performed call slot optimization:\n"
+ << " call: " << *C << "\n"
+ << " memcpy: " << *M << "\n");
+ eraseInstruction(M);
+ ++NumMemCpyInstr;
+ return true;
+ }
+ }
+ }
+ if (auto *MDep = dyn_cast<MemCpyInst>(MI))
+ return processMemCpyMemCpyDependence(M, MDep);
+ if (auto *MDep = dyn_cast<MemSetInst>(MI)) {
+ if (performMemCpyToMemSetOptzn(M, MDep)) {
+ LLVM_DEBUG(dbgs() << "Converted memcpy to memset\n");
+ eraseInstruction(M);
+ ++NumCpyToSet;
+ return true;
+ }
+ }
+ }
+
+ if (hasUndefContentsMSSA(MSSA, AA, M->getSource(), MD, CopySize)) {
+ LLVM_DEBUG(dbgs() << "Removed memcpy from undef\n");
+ eraseInstruction(M);
+ ++NumMemCpyInstr;
return true;
}
}
- } else {
- MemDepResult DepInfo = MD->getDependency(M);
-
- // Try to turn a partially redundant memset + memcpy into
- // memcpy + smaller memset. We don't need the memcpy size for this.
- if (DepInfo.isClobber())
- if (MemSetInst *MDep = dyn_cast<MemSetInst>(DepInfo.getInst()))
- if (processMemSetMemCpyDependence(M, MDep))
- return true;
-
- // The optimizations after this point require the memcpy size.
- ConstantInt *CopySize = dyn_cast<ConstantInt>(M->getLength());
- if (!CopySize) return false;
-
- // There are four possible optimizations we can do for memcpy:
- // a) memcpy-memcpy xform which exposes redundance for DSE.
- // b) call-memcpy xform for return slot optimization.
- // c) memcpy from freshly alloca'd space or space that has just started
- // its lifetime copies undefined data, and we can therefore eliminate
- // the memcpy in favor of the data that was already at the destination.
- // d) memcpy from a just-memset'd source can be turned into memset.
- if (DepInfo.isClobber()) {
- if (CallInst *C = dyn_cast<CallInst>(DepInfo.getInst())) {
- // FIXME: Can we pass in either of dest/src alignment here instead
- // of conservatively taking the minimum?
- Align Alignment = std::min(M->getDestAlign().valueOrOne(),
- M->getSourceAlign().valueOrOne());
- if (performCallSlotOptzn(M, M, M->getDest(), M->getSource(),
- CopySize->getZExtValue(), Alignment, C)) {
- eraseInstruction(M);
- ++NumMemCpyInstr;
- return true;
- }
- }
+ } else {
+ MemDepResult DepInfo = MD->getDependency(M);
+
+ // Try to turn a partially redundant memset + memcpy into
+ // memcpy + smaller memset. We don't need the memcpy size for this.
+ if (DepInfo.isClobber())
+ if (MemSetInst *MDep = dyn_cast<MemSetInst>(DepInfo.getInst()))
+ if (processMemSetMemCpyDependence(M, MDep))
+ return true;
+
+ // The optimizations after this point require the memcpy size.
+ ConstantInt *CopySize = dyn_cast<ConstantInt>(M->getLength());
+ if (!CopySize) return false;
+
+ // There are four possible optimizations we can do for memcpy:
+ // a) memcpy-memcpy xform which exposes redundance for DSE.
+ // b) call-memcpy xform for return slot optimization.
+ // c) memcpy from freshly alloca'd space or space that has just started
+ // its lifetime copies undefined data, and we can therefore eliminate
+ // the memcpy in favor of the data that was already at the destination.
+ // d) memcpy from a just-memset'd source can be turned into memset.
+ if (DepInfo.isClobber()) {
+ if (CallInst *C = dyn_cast<CallInst>(DepInfo.getInst())) {
+ // FIXME: Can we pass in either of dest/src alignment here instead
+ // of conservatively taking the minimum?
+ Align Alignment = std::min(M->getDestAlign().valueOrOne(),
+ M->getSourceAlign().valueOrOne());
+ if (performCallSlotOptzn(M, M, M->getDest(), M->getSource(),
+ CopySize->getZExtValue(), Alignment, C)) {
+ eraseInstruction(M);
+ ++NumMemCpyInstr;
+ return true;
+ }
+ }
}
- MemoryLocation SrcLoc = MemoryLocation::getForSource(M);
- MemDepResult SrcDepInfo = MD->getPointerDependencyFrom(
- SrcLoc, true, M->getIterator(), M->getParent());
-
- if (SrcDepInfo.isClobber()) {
- if (MemCpyInst *MDep = dyn_cast<MemCpyInst>(SrcDepInfo.getInst()))
- return processMemCpyMemCpyDependence(M, MDep);
- } else if (SrcDepInfo.isDef()) {
- if (hasUndefContents(SrcDepInfo.getInst(), CopySize)) {
- eraseInstruction(M);
- ++NumMemCpyInstr;
+ MemoryLocation SrcLoc = MemoryLocation::getForSource(M);
+ MemDepResult SrcDepInfo = MD->getPointerDependencyFrom(
+ SrcLoc, true, M->getIterator(), M->getParent());
+
+ if (SrcDepInfo.isClobber()) {
+ if (MemCpyInst *MDep = dyn_cast<MemCpyInst>(SrcDepInfo.getInst()))
+ return processMemCpyMemCpyDependence(M, MDep);
+ } else if (SrcDepInfo.isDef()) {
+ if (hasUndefContents(SrcDepInfo.getInst(), CopySize)) {
+ eraseInstruction(M);
+ ++NumMemCpyInstr;
return true;
}
- }
-
- if (SrcDepInfo.isClobber())
- if (MemSetInst *MDep = dyn_cast<MemSetInst>(SrcDepInfo.getInst()))
- if (performMemCpyToMemSetOptzn(M, MDep)) {
- eraseInstruction(M);
- ++NumCpyToSet;
- return true;
- }
- }
-
+ }
+
+ if (SrcDepInfo.isClobber())
+ if (MemSetInst *MDep = dyn_cast<MemSetInst>(SrcDepInfo.getInst()))
+ if (performMemCpyToMemSetOptzn(M, MDep)) {
+ eraseInstruction(M);
+ ++NumCpyToSet;
+ return true;
+ }
+ }
+
return false;
}
@@ -1504,8 +1504,8 @@ bool MemCpyOptPass::processMemMove(MemMoveInst *M) {
return false;
// See if the pointers alias.
- if (!AA->isNoAlias(MemoryLocation::getForDest(M),
- MemoryLocation::getForSource(M)))
+ if (!AA->isNoAlias(MemoryLocation::getForDest(M),
+ MemoryLocation::getForSource(M)))
return false;
LLVM_DEBUG(dbgs() << "MemCpyOptPass: Optimizing memmove -> memcpy: " << *M
@@ -1518,13 +1518,13 @@ bool MemCpyOptPass::processMemMove(MemMoveInst *M) {
M->setCalledFunction(Intrinsic::getDeclaration(M->getModule(),
Intrinsic::memcpy, ArgTys));
- // For MemorySSA nothing really changes (except that memcpy may imply stricter
- // aliasing guarantees).
-
+ // For MemorySSA nothing really changes (except that memcpy may imply stricter
+ // aliasing guarantees).
+
// MemDep may have over conservative information about this instruction, just
// conservatively flush it from the cache.
- if (MD)
- MD->removeInstruction(M);
+ if (MD)
+ MD->removeInstruction(M);
++NumMoveToCpy;
return true;
@@ -1537,21 +1537,21 @@ bool MemCpyOptPass::processByValArgument(CallBase &CB, unsigned ArgNo) {
Value *ByValArg = CB.getArgOperand(ArgNo);
Type *ByValTy = cast<PointerType>(ByValArg->getType())->getElementType();
uint64_t ByValSize = DL.getTypeAllocSize(ByValTy);
- MemoryLocation Loc(ByValArg, LocationSize::precise(ByValSize));
- MemCpyInst *MDep = nullptr;
- if (EnableMemorySSA) {
- MemoryUseOrDef *CallAccess = MSSA->getMemoryAccess(&CB);
- MemoryAccess *Clobber = MSSA->getWalker()->getClobberingMemoryAccess(
- CallAccess->getDefiningAccess(), Loc);
- if (auto *MD = dyn_cast<MemoryDef>(Clobber))
- MDep = dyn_cast_or_null<MemCpyInst>(MD->getMemoryInst());
- } else {
- MemDepResult DepInfo = MD->getPointerDependencyFrom(
- Loc, true, CB.getIterator(), CB.getParent());
- if (!DepInfo.isClobber())
- return false;
- MDep = dyn_cast<MemCpyInst>(DepInfo.getInst());
- }
+ MemoryLocation Loc(ByValArg, LocationSize::precise(ByValSize));
+ MemCpyInst *MDep = nullptr;
+ if (EnableMemorySSA) {
+ MemoryUseOrDef *CallAccess = MSSA->getMemoryAccess(&CB);
+ MemoryAccess *Clobber = MSSA->getWalker()->getClobberingMemoryAccess(
+ CallAccess->getDefiningAccess(), Loc);
+ if (auto *MD = dyn_cast<MemoryDef>(Clobber))
+ MDep = dyn_cast_or_null<MemCpyInst>(MD->getMemoryInst());
+ } else {
+ MemDepResult DepInfo = MD->getPointerDependencyFrom(
+ Loc, true, CB.getIterator(), CB.getParent());
+ if (!DepInfo.isClobber())
+ return false;
+ MDep = dyn_cast<MemCpyInst>(DepInfo.getInst());
+ }
// If the byval argument isn't fed by a memcpy, ignore it. If it is fed by
// a memcpy, see if we can byval from the source of the memcpy instead of the
@@ -1574,8 +1574,8 @@ bool MemCpyOptPass::processByValArgument(CallBase &CB, unsigned ArgNo) {
// source of the memcpy to the alignment we need. If we fail, we bail out.
MaybeAlign MemDepAlign = MDep->getSourceAlign();
if ((!MemDepAlign || *MemDepAlign < *ByValAlign) &&
- getOrEnforceKnownAlignment(MDep->getSource(), ByValAlign, DL, &CB, AC,
- DT) < *ByValAlign)
+ getOrEnforceKnownAlignment(MDep->getSource(), ByValAlign, DL, &CB, AC,
+ DT) < *ByValAlign)
return false;
// The address space of the memcpy source must match the byval argument
@@ -1589,19 +1589,19 @@ bool MemCpyOptPass::processByValArgument(CallBase &CB, unsigned ArgNo) {
// *b = 42;
// foo(*a)
// It would be invalid to transform the second memcpy into foo(*b).
- if (EnableMemorySSA) {
- if (writtenBetween(MSSA, MemoryLocation::getForSource(MDep),
- MSSA->getMemoryAccess(MDep), MSSA->getMemoryAccess(&CB)))
- return false;
- } else {
- // NOTE: This is conservative, it will stop on any read from the source loc,
- // not just the defining memcpy.
- MemDepResult SourceDep = MD->getPointerDependencyFrom(
- MemoryLocation::getForSource(MDep), false,
- CB.getIterator(), MDep->getParent());
- if (!SourceDep.isClobber() || SourceDep.getInst() != MDep)
- return false;
- }
+ if (EnableMemorySSA) {
+ if (writtenBetween(MSSA, MemoryLocation::getForSource(MDep),
+ MSSA->getMemoryAccess(MDep), MSSA->getMemoryAccess(&CB)))
+ return false;
+ } else {
+ // NOTE: This is conservative, it will stop on any read from the source loc,
+ // not just the defining memcpy.
+ MemDepResult SourceDep = MD->getPointerDependencyFrom(
+ MemoryLocation::getForSource(MDep), false,
+ CB.getIterator(), MDep->getParent());
+ if (!SourceDep.isClobber() || SourceDep.getInst() != MDep)
+ return false;
+ }
Value *TmpCast = MDep->getSource();
if (MDep->getSource()->getType() != ByValArg->getType()) {
@@ -1632,7 +1632,7 @@ bool MemCpyOptPass::iterateOnFunction(Function &F) {
// instruction in a BB can't be dominated by a later instruction in the
// same BB (which is a scenario that can happen for an unreachable BB that
// has itself as a predecessor).
- if (!DT->isReachableFromEntry(&BB))
+ if (!DT->isReachableFromEntry(&BB))
continue;
for (BasicBlock::iterator BI = BB.begin(), BE = BB.end(); BI != BE;) {
@@ -1668,43 +1668,43 @@ bool MemCpyOptPass::iterateOnFunction(Function &F) {
}
PreservedAnalyses MemCpyOptPass::run(Function &F, FunctionAnalysisManager &AM) {
- auto *MD = !EnableMemorySSA ? &AM.getResult<MemoryDependenceAnalysis>(F)
- : AM.getCachedResult<MemoryDependenceAnalysis>(F);
+ auto *MD = !EnableMemorySSA ? &AM.getResult<MemoryDependenceAnalysis>(F)
+ : AM.getCachedResult<MemoryDependenceAnalysis>(F);
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
- auto *AA = &AM.getResult<AAManager>(F);
- auto *AC = &AM.getResult<AssumptionAnalysis>(F);
- auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
- auto *MSSA = EnableMemorySSA ? &AM.getResult<MemorySSAAnalysis>(F)
- : AM.getCachedResult<MemorySSAAnalysis>(F);
-
- bool MadeChange =
- runImpl(F, MD, &TLI, AA, AC, DT, MSSA ? &MSSA->getMSSA() : nullptr);
+ auto *AA = &AM.getResult<AAManager>(F);
+ auto *AC = &AM.getResult<AssumptionAnalysis>(F);
+ auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
+ auto *MSSA = EnableMemorySSA ? &AM.getResult<MemorySSAAnalysis>(F)
+ : AM.getCachedResult<MemorySSAAnalysis>(F);
+
+ bool MadeChange =
+ runImpl(F, MD, &TLI, AA, AC, DT, MSSA ? &MSSA->getMSSA() : nullptr);
if (!MadeChange)
return PreservedAnalyses::all();
PreservedAnalyses PA;
PA.preserveSet<CFGAnalyses>();
PA.preserve<GlobalsAA>();
- if (MD)
- PA.preserve<MemoryDependenceAnalysis>();
- if (MSSA)
- PA.preserve<MemorySSAAnalysis>();
+ if (MD)
+ PA.preserve<MemoryDependenceAnalysis>();
+ if (MSSA)
+ PA.preserve<MemorySSAAnalysis>();
return PA;
}
-bool MemCpyOptPass::runImpl(Function &F, MemoryDependenceResults *MD_,
- TargetLibraryInfo *TLI_, AliasAnalysis *AA_,
- AssumptionCache *AC_, DominatorTree *DT_,
- MemorySSA *MSSA_) {
+bool MemCpyOptPass::runImpl(Function &F, MemoryDependenceResults *MD_,
+ TargetLibraryInfo *TLI_, AliasAnalysis *AA_,
+ AssumptionCache *AC_, DominatorTree *DT_,
+ MemorySSA *MSSA_) {
bool MadeChange = false;
MD = MD_;
TLI = TLI_;
- AA = AA_;
- AC = AC_;
- DT = DT_;
- MSSA = MSSA_;
- MemorySSAUpdater MSSAU_(MSSA_);
- MSSAU = MSSA_ ? &MSSAU_ : nullptr;
+ AA = AA_;
+ AC = AC_;
+ DT = DT_;
+ MSSA = MSSA_;
+ MemorySSAUpdater MSSAU_(MSSA_);
+ MSSAU = MSSA_ ? &MSSAU_ : nullptr;
// If we don't have at least memset and memcpy, there is little point of doing
// anything here. These are required by a freestanding implementation, so if
// even they are disabled, there is no point in trying hard.
@@ -1717,9 +1717,9 @@ bool MemCpyOptPass::runImpl(Function &F, MemoryDependenceResults *MD_,
MadeChange = true;
}
- if (MSSA_ && VerifyMemorySSA)
- MSSA_->verifyMemorySSA();
-
+ if (MSSA_ && VerifyMemorySSA)
+ MSSA_->verifyMemorySSA();
+
MD = nullptr;
return MadeChange;
}
@@ -1729,17 +1729,17 @@ bool MemCpyOptLegacyPass::runOnFunction(Function &F) {
if (skipFunction(F))
return false;
- auto *MDWP = !EnableMemorySSA
- ? &getAnalysis<MemoryDependenceWrapperPass>()
- : getAnalysisIfAvailable<MemoryDependenceWrapperPass>();
+ auto *MDWP = !EnableMemorySSA
+ ? &getAnalysis<MemoryDependenceWrapperPass>()
+ : getAnalysisIfAvailable<MemoryDependenceWrapperPass>();
auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
- auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
- auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
- auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- auto *MSSAWP = EnableMemorySSA
- ? &getAnalysis<MemorySSAWrapperPass>()
- : getAnalysisIfAvailable<MemorySSAWrapperPass>();
-
- return Impl.runImpl(F, MDWP ? & MDWP->getMemDep() : nullptr, TLI, AA, AC, DT,
- MSSAWP ? &MSSAWP->getMSSA() : nullptr);
+ auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
+ auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
+ auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ auto *MSSAWP = EnableMemorySSA
+ ? &getAnalysis<MemorySSAWrapperPass>()
+ : getAnalysisIfAvailable<MemorySSAWrapperPass>();
+
+ return Impl.runImpl(F, MDWP ? & MDWP->getMemDep() : nullptr, TLI, AA, AC, DT,
+ MSSAWP ? &MSSAWP->getMSSA() : nullptr);
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/MergeICmps.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/MergeICmps.cpp
index 5389d41e62..7f8b75ac88 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/MergeICmps.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/MergeICmps.cpp
@@ -372,7 +372,7 @@ BCECmpBlock visitCmpBlock(Value *const Val, BasicBlock *const Block,
} else {
// In this case, we expect a constant incoming value (the comparison is
// chained).
- const auto *const Const = cast<ConstantInt>(Val);
+ const auto *const Const = cast<ConstantInt>(Val);
LLVM_DEBUG(dbgs() << "const\n");
if (!Const->isZero()) return {};
LLVM_DEBUG(dbgs() << "false\n");
@@ -624,17 +624,17 @@ static BasicBlock *mergeComparisons(ArrayRef<BCECmpBlock> Comparisons,
Value *IsEqual = nullptr;
LLVM_DEBUG(dbgs() << "Merging " << Comparisons.size() << " comparisons -> "
<< BB->getName() << "\n");
-
- // If there is one block that requires splitting, we do it now, i.e.
- // just before we know we will collapse the chain. The instructions
- // can be executed before any of the instructions in the chain.
- const auto ToSplit = llvm::find_if(
- Comparisons, [](const BCECmpBlock &B) { return B.RequireSplit; });
- if (ToSplit != Comparisons.end()) {
- LLVM_DEBUG(dbgs() << "Splitting non_BCE work to header\n");
- ToSplit->split(BB, AA);
- }
-
+
+ // If there is one block that requires splitting, we do it now, i.e.
+ // just before we know we will collapse the chain. The instructions
+ // can be executed before any of the instructions in the chain.
+ const auto ToSplit = llvm::find_if(
+ Comparisons, [](const BCECmpBlock &B) { return B.RequireSplit; });
+ if (ToSplit != Comparisons.end()) {
+ LLVM_DEBUG(dbgs() << "Splitting non_BCE work to header\n");
+ ToSplit->split(BB, AA);
+ }
+
if (Comparisons.size() == 1) {
LLVM_DEBUG(dbgs() << "Only one comparison, updating branches\n");
Value *const LhsLoad =
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/NaryReassociate.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/NaryReassociate.cpp
index dd2830026c..32bb62129e 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/NaryReassociate.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/NaryReassociate.cpp
@@ -219,27 +219,27 @@ bool NaryReassociatePass::doOneIteration(Function &F) {
// Process the basic blocks in a depth first traversal of the dominator
// tree. This order ensures that all bases of a candidate are in Candidates
// when we process it.
- SmallVector<WeakTrackingVH, 16> DeadInsts;
+ SmallVector<WeakTrackingVH, 16> DeadInsts;
for (const auto Node : depth_first(DT)) {
BasicBlock *BB = Node->getBlock();
for (auto I = BB->begin(); I != BB->end(); ++I) {
- Instruction *OrigI = &*I;
- const SCEV *OrigSCEV = nullptr;
- if (Instruction *NewI = tryReassociate(OrigI, OrigSCEV)) {
- Changed = true;
- OrigI->replaceAllUsesWith(NewI);
-
- // Add 'OrigI' to the list of dead instructions.
- DeadInsts.push_back(WeakTrackingVH(OrigI));
- // Add the rewritten instruction to SeenExprs; the original
- // instruction is deleted.
- const SCEV *NewSCEV = SE->getSCEV(NewI);
- SeenExprs[NewSCEV].push_back(WeakTrackingVH(NewI));
-
+ Instruction *OrigI = &*I;
+ const SCEV *OrigSCEV = nullptr;
+ if (Instruction *NewI = tryReassociate(OrigI, OrigSCEV)) {
+ Changed = true;
+ OrigI->replaceAllUsesWith(NewI);
+
+ // Add 'OrigI' to the list of dead instructions.
+ DeadInsts.push_back(WeakTrackingVH(OrigI));
+ // Add the rewritten instruction to SeenExprs; the original
+ // instruction is deleted.
+ const SCEV *NewSCEV = SE->getSCEV(NewI);
+ SeenExprs[NewSCEV].push_back(WeakTrackingVH(NewI));
+
// Ideally, NewSCEV should equal OldSCEV because tryReassociate(I)
// is equivalent to I. However, ScalarEvolution::getSCEV may
- // weaken nsw causing NewSCEV not to equal OldSCEV. For example,
- // suppose we reassociate
+ // weaken nsw causing NewSCEV not to equal OldSCEV. For example,
+ // suppose we reassociate
// I = &a[sext(i +nsw j)] // assuming sizeof(a[0]) = 4
// to
// NewI = &a[sext(i)] + sext(j).
@@ -253,47 +253,47 @@ bool NaryReassociatePass::doOneIteration(Function &F) {
// equivalence, we add I to SeenExprs[OldSCEV] as well so that we can
// map both SCEV before and after tryReassociate(I) to I.
//
- // This improvement is exercised in @reassociate_gep_nsw in
- // nary-gep.ll.
- if (NewSCEV != OrigSCEV)
- SeenExprs[OrigSCEV].push_back(WeakTrackingVH(NewI));
- } else if (OrigSCEV)
- SeenExprs[OrigSCEV].push_back(WeakTrackingVH(OrigI));
+ // This improvement is exercised in @reassociate_gep_nsw in
+ // nary-gep.ll.
+ if (NewSCEV != OrigSCEV)
+ SeenExprs[OrigSCEV].push_back(WeakTrackingVH(NewI));
+ } else if (OrigSCEV)
+ SeenExprs[OrigSCEV].push_back(WeakTrackingVH(OrigI));
}
}
- // Delete all dead instructions from 'DeadInsts'.
- // Please note ScalarEvolution is updated along the way.
- RecursivelyDeleteTriviallyDeadInstructionsPermissive(
- DeadInsts, TLI, nullptr, [this](Value *V) { SE->forgetValue(V); });
-
+ // Delete all dead instructions from 'DeadInsts'.
+ // Please note ScalarEvolution is updated along the way.
+ RecursivelyDeleteTriviallyDeadInstructionsPermissive(
+ DeadInsts, TLI, nullptr, [this](Value *V) { SE->forgetValue(V); });
+
return Changed;
}
-Instruction *NaryReassociatePass::tryReassociate(Instruction * I,
- const SCEV *&OrigSCEV) {
-
- if (!SE->isSCEVable(I->getType()))
- return nullptr;
-
+Instruction *NaryReassociatePass::tryReassociate(Instruction * I,
+ const SCEV *&OrigSCEV) {
+
+ if (!SE->isSCEVable(I->getType()))
+ return nullptr;
+
switch (I->getOpcode()) {
case Instruction::Add:
case Instruction::Mul:
- OrigSCEV = SE->getSCEV(I);
+ OrigSCEV = SE->getSCEV(I);
return tryReassociateBinaryOp(cast<BinaryOperator>(I));
case Instruction::GetElementPtr:
- OrigSCEV = SE->getSCEV(I);
+ OrigSCEV = SE->getSCEV(I);
return tryReassociateGEP(cast<GetElementPtrInst>(I));
default:
- return nullptr;
+ return nullptr;
}
-
- llvm_unreachable("should not be reached");
- return nullptr;
+
+ llvm_unreachable("should not be reached");
+ return nullptr;
}
static bool isGEPFoldable(GetElementPtrInst *GEP,
const TargetTransformInfo *TTI) {
- SmallVector<const Value *, 4> Indices(GEP->indices());
+ SmallVector<const Value *, 4> Indices(GEP->indices());
return TTI->getGEPCost(GEP->getSourceElementType(), GEP->getPointerOperand(),
Indices) == TargetTransformInfo::TCC_Free;
}
@@ -369,8 +369,8 @@ NaryReassociatePass::tryReassociateGEPAtIndex(GetElementPtrInst *GEP,
// Replace the I-th index with LHS.
IndexExprs[I] = SE->getSCEV(LHS);
if (isKnownNonNegative(LHS, *DL, 0, AC, GEP, DT) &&
- DL->getTypeSizeInBits(LHS->getType()).getFixedSize() <
- DL->getTypeSizeInBits(GEP->getOperand(I)->getType()).getFixedSize()) {
+ DL->getTypeSizeInBits(LHS->getType()).getFixedSize() <
+ DL->getTypeSizeInBits(GEP->getOperand(I)->getType()).getFixedSize()) {
// Zero-extend LHS if it is non-negative. InstCombine canonicalizes sext to
// zext if the source operand is proved non-negative. We should do that
// consistently so that CandidateExpr more likely appears before. See
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/NewGVN.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/NewGVN.cpp
index 7638b0fba4..281d47c862 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/NewGVN.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/NewGVN.cpp
@@ -662,8 +662,8 @@ public:
const DataLayout &DL)
: F(F), DT(DT), TLI(TLI), AA(AA), MSSA(MSSA), AC(AC), DL(DL),
PredInfo(std::make_unique<PredicateInfo>(F, *DT, *AC)),
- SQ(DL, TLI, DT, AC, /*CtxI=*/nullptr, /*UseInstrInfo=*/false,
- /*CanUseUndef=*/false) {}
+ SQ(DL, TLI, DT, AC, /*CtxI=*/nullptr, /*UseInstrInfo=*/false,
+ /*CanUseUndef=*/false) {}
bool runGVN();
@@ -1248,7 +1248,7 @@ const UnknownExpression *NewGVN::createUnknownExpression(Instruction *I) const {
const CallExpression *
NewGVN::createCallExpression(CallInst *CI, const MemoryAccess *MA) const {
// FIXME: Add operand bundles for calls.
- // FIXME: Allow commutative matching for intrinsics.
+ // FIXME: Allow commutative matching for intrinsics.
auto *E =
new (ExpressionAllocator) CallExpression(CI->getNumOperands(), CI, MA);
setBasicExpressionInfo(CI, E);
@@ -1535,39 +1535,39 @@ NewGVN::performSymbolicPredicateInfoEvaluation(Instruction *I) const {
LLVM_DEBUG(dbgs() << "Found predicate info from instruction !\n");
- const Optional<PredicateConstraint> &Constraint = PI->getConstraint();
- if (!Constraint)
+ const Optional<PredicateConstraint> &Constraint = PI->getConstraint();
+ if (!Constraint)
return nullptr;
- CmpInst::Predicate Predicate = Constraint->Predicate;
- Value *CmpOp0 = I->getOperand(0);
- Value *CmpOp1 = Constraint->OtherOp;
+ CmpInst::Predicate Predicate = Constraint->Predicate;
+ Value *CmpOp0 = I->getOperand(0);
+ Value *CmpOp1 = Constraint->OtherOp;
- Value *FirstOp = lookupOperandLeader(CmpOp0);
- Value *SecondOp = lookupOperandLeader(CmpOp1);
- Value *AdditionallyUsedValue = CmpOp0;
+ Value *FirstOp = lookupOperandLeader(CmpOp0);
+ Value *SecondOp = lookupOperandLeader(CmpOp1);
+ Value *AdditionallyUsedValue = CmpOp0;
// Sort the ops.
if (shouldSwapOperands(FirstOp, SecondOp)) {
std::swap(FirstOp, SecondOp);
- Predicate = CmpInst::getSwappedPredicate(Predicate);
- AdditionallyUsedValue = CmpOp1;
+ Predicate = CmpInst::getSwappedPredicate(Predicate);
+ AdditionallyUsedValue = CmpOp1;
}
- if (Predicate == CmpInst::ICMP_EQ) {
- addPredicateUsers(PI, I);
- addAdditionalUsers(AdditionallyUsedValue, I);
- return createVariableOrConstant(FirstOp);
+ if (Predicate == CmpInst::ICMP_EQ) {
+ addPredicateUsers(PI, I);
+ addAdditionalUsers(AdditionallyUsedValue, I);
+ return createVariableOrConstant(FirstOp);
}
-
- // Handle the special case of floating point.
- if (Predicate == CmpInst::FCMP_OEQ && isa<ConstantFP>(FirstOp) &&
- !cast<ConstantFP>(FirstOp)->isZero()) {
- addPredicateUsers(PI, I);
- addAdditionalUsers(AdditionallyUsedValue, I);
- return createConstantExpression(cast<Constant>(FirstOp));
+
+ // Handle the special case of floating point.
+ if (Predicate == CmpInst::FCMP_OEQ && isa<ConstantFP>(FirstOp) &&
+ !cast<ConstantFP>(FirstOp)->isZero()) {
+ addPredicateUsers(PI, I);
+ addAdditionalUsers(AdditionallyUsedValue, I);
+ return createConstantExpression(cast<Constant>(FirstOp));
}
-
+
return nullptr;
}
@@ -2876,7 +2876,7 @@ void NewGVN::cleanupTables() {
}
while (!TempInst.empty()) {
- auto *I = TempInst.pop_back_val();
+ auto *I = TempInst.pop_back_val();
I->deleteValue();
}
@@ -3371,9 +3371,9 @@ bool NewGVN::runGVN() {
for (auto &B : RPOT) {
auto *Node = DT->getNode(B);
if (Node->getNumChildren() > 1)
- llvm::sort(*Node, [&](const DomTreeNode *A, const DomTreeNode *B) {
- return RPOOrdering[A] < RPOOrdering[B];
- });
+ llvm::sort(*Node, [&](const DomTreeNode *A, const DomTreeNode *B) {
+ return RPOOrdering[A] < RPOOrdering[B];
+ });
}
// Now a standard depth first ordering of the domtree is equivalent to RPO.
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/PlaceSafepoints.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/PlaceSafepoints.cpp
index 9ee2e77af0..a110f7d5c2 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/PlaceSafepoints.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/PlaceSafepoints.cpp
@@ -243,7 +243,7 @@ static bool mustBeFiniteCountedLoop(Loop *L, ScalarEvolution *SE,
BasicBlock *Pred) {
// A conservative bound on the loop as a whole.
const SCEV *MaxTrips = SE->getConstantMaxBackedgeTakenCount(L);
- if (!isa<SCEVCouldNotCompute>(MaxTrips) &&
+ if (!isa<SCEVCouldNotCompute>(MaxTrips) &&
SE->getUnsignedRange(MaxTrips).getUnsignedMax().isIntN(
CountedLoopTripWidth))
return true;
@@ -255,7 +255,7 @@ static bool mustBeFiniteCountedLoop(Loop *L, ScalarEvolution *SE,
// This returns an exact expression only. TODO: We really only need an
// upper bound here, but SE doesn't expose that.
const SCEV *MaxExec = SE->getExitCount(L, Pred);
- if (!isa<SCEVCouldNotCompute>(MaxExec) &&
+ if (!isa<SCEVCouldNotCompute>(MaxExec) &&
SE->getUnsignedRange(MaxExec).getUnsignedMax().isIntN(
CountedLoopTripWidth))
return true;
@@ -435,7 +435,7 @@ static Instruction *findLocationForEntrySafepoint(Function &F,
return Cursor;
}
-const char GCSafepointPollName[] = "gc.safepoint_poll";
+const char GCSafepointPollName[] = "gc.safepoint_poll";
static bool isGCSafepointPoll(Function &F) {
return F.getName().equals(GCSafepointPollName);
@@ -589,7 +589,7 @@ bool PlaceSafepoints::runOnFunction(Function &F) {
for (Instruction *PollLocation : PollsNeeded) {
std::vector<CallBase *> RuntimeCalls;
InsertSafepointPoll(PollLocation, RuntimeCalls, TLI);
- llvm::append_range(ParsePointNeeded, RuntimeCalls);
+ llvm::append_range(ParsePointNeeded, RuntimeCalls);
}
return Modified;
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/Reassociate.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/Reassociate.cpp
index e4c9424aee..dffeb7cc22 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/Reassociate.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/Reassociate.cpp
@@ -920,100 +920,100 @@ static Value *NegateValue(Value *V, Instruction *BI,
return NewNeg;
}
-// See if this `or` looks like an load widening reduction, i.e. that it
-// consists of an `or`/`shl`/`zext`/`load` nodes only. Note that we don't
-// ensure that the pattern is *really* a load widening reduction,
-// we do not ensure that it can really be replaced with a widened load,
-// only that it mostly looks like one.
-static bool isLoadCombineCandidate(Instruction *Or) {
- SmallVector<Instruction *, 8> Worklist;
- SmallSet<Instruction *, 8> Visited;
-
- auto Enqueue = [&](Value *V) {
- auto *I = dyn_cast<Instruction>(V);
- // Each node of an `or` reduction must be an instruction,
- if (!I)
- return false; // Node is certainly not part of an `or` load reduction.
- // Only process instructions we have never processed before.
- if (Visited.insert(I).second)
- Worklist.emplace_back(I);
- return true; // Will need to look at parent nodes.
- };
-
- if (!Enqueue(Or))
- return false; // Not an `or` reduction pattern.
-
- while (!Worklist.empty()) {
- auto *I = Worklist.pop_back_val();
-
- // Okay, which instruction is this node?
- switch (I->getOpcode()) {
- case Instruction::Or:
- // Got an `or` node. That's fine, just recurse into it's operands.
- for (Value *Op : I->operands())
- if (!Enqueue(Op))
- return false; // Not an `or` reduction pattern.
- continue;
-
- case Instruction::Shl:
- case Instruction::ZExt:
- // `shl`/`zext` nodes are fine, just recurse into their base operand.
- if (!Enqueue(I->getOperand(0)))
- return false; // Not an `or` reduction pattern.
- continue;
-
- case Instruction::Load:
- // Perfect, `load` node means we've reached an edge of the graph.
- continue;
-
- default: // Unknown node.
- return false; // Not an `or` reduction pattern.
- }
- }
-
- return true;
-}
-
-/// Return true if it may be profitable to convert this (X|Y) into (X+Y).
-static bool ShouldConvertOrWithNoCommonBitsToAdd(Instruction *Or) {
- // Don't bother to convert this up unless either the LHS is an associable add
- // or subtract or mul or if this is only used by one of the above.
- // This is only a compile-time improvement, it is not needed for correctness!
- auto isInteresting = [](Value *V) {
- for (auto Op : {Instruction::Add, Instruction::Sub, Instruction::Mul})
- if (isReassociableOp(V, Op))
- return true;
- return false;
- };
-
- if (any_of(Or->operands(), isInteresting))
- return true;
-
- Value *VB = Or->user_back();
- if (Or->hasOneUse() && isInteresting(VB))
- return true;
-
- return false;
-}
-
-/// If we have (X|Y), and iff X and Y have no common bits set,
-/// transform this into (X+Y) to allow arithmetics reassociation.
-static BinaryOperator *ConvertOrWithNoCommonBitsToAdd(Instruction *Or) {
- // Convert an or into an add.
- BinaryOperator *New =
- CreateAdd(Or->getOperand(0), Or->getOperand(1), "", Or, Or);
- New->setHasNoSignedWrap();
- New->setHasNoUnsignedWrap();
- New->takeName(Or);
-
- // Everyone now refers to the add instruction.
- Or->replaceAllUsesWith(New);
- New->setDebugLoc(Or->getDebugLoc());
-
- LLVM_DEBUG(dbgs() << "Converted or into an add: " << *New << '\n');
- return New;
-}
-
+// See if this `or` looks like an load widening reduction, i.e. that it
+// consists of an `or`/`shl`/`zext`/`load` nodes only. Note that we don't
+// ensure that the pattern is *really* a load widening reduction,
+// we do not ensure that it can really be replaced with a widened load,
+// only that it mostly looks like one.
+static bool isLoadCombineCandidate(Instruction *Or) {
+ SmallVector<Instruction *, 8> Worklist;
+ SmallSet<Instruction *, 8> Visited;
+
+ auto Enqueue = [&](Value *V) {
+ auto *I = dyn_cast<Instruction>(V);
+ // Each node of an `or` reduction must be an instruction,
+ if (!I)
+ return false; // Node is certainly not part of an `or` load reduction.
+ // Only process instructions we have never processed before.
+ if (Visited.insert(I).second)
+ Worklist.emplace_back(I);
+ return true; // Will need to look at parent nodes.
+ };
+
+ if (!Enqueue(Or))
+ return false; // Not an `or` reduction pattern.
+
+ while (!Worklist.empty()) {
+ auto *I = Worklist.pop_back_val();
+
+ // Okay, which instruction is this node?
+ switch (I->getOpcode()) {
+ case Instruction::Or:
+ // Got an `or` node. That's fine, just recurse into it's operands.
+ for (Value *Op : I->operands())
+ if (!Enqueue(Op))
+ return false; // Not an `or` reduction pattern.
+ continue;
+
+ case Instruction::Shl:
+ case Instruction::ZExt:
+ // `shl`/`zext` nodes are fine, just recurse into their base operand.
+ if (!Enqueue(I->getOperand(0)))
+ return false; // Not an `or` reduction pattern.
+ continue;
+
+ case Instruction::Load:
+ // Perfect, `load` node means we've reached an edge of the graph.
+ continue;
+
+ default: // Unknown node.
+ return false; // Not an `or` reduction pattern.
+ }
+ }
+
+ return true;
+}
+
+/// Return true if it may be profitable to convert this (X|Y) into (X+Y).
+static bool ShouldConvertOrWithNoCommonBitsToAdd(Instruction *Or) {
+ // Don't bother to convert this up unless either the LHS is an associable add
+ // or subtract or mul or if this is only used by one of the above.
+ // This is only a compile-time improvement, it is not needed for correctness!
+ auto isInteresting = [](Value *V) {
+ for (auto Op : {Instruction::Add, Instruction::Sub, Instruction::Mul})
+ if (isReassociableOp(V, Op))
+ return true;
+ return false;
+ };
+
+ if (any_of(Or->operands(), isInteresting))
+ return true;
+
+ Value *VB = Or->user_back();
+ if (Or->hasOneUse() && isInteresting(VB))
+ return true;
+
+ return false;
+}
+
+/// If we have (X|Y), and iff X and Y have no common bits set,
+/// transform this into (X+Y) to allow arithmetics reassociation.
+static BinaryOperator *ConvertOrWithNoCommonBitsToAdd(Instruction *Or) {
+ // Convert an or into an add.
+ BinaryOperator *New =
+ CreateAdd(Or->getOperand(0), Or->getOperand(1), "", Or, Or);
+ New->setHasNoSignedWrap();
+ New->setHasNoUnsignedWrap();
+ New->takeName(Or);
+
+ // Everyone now refers to the add instruction.
+ Or->replaceAllUsesWith(New);
+ New->setDebugLoc(Or->getDebugLoc());
+
+ LLVM_DEBUG(dbgs() << "Converted or into an add: " << *New << '\n');
+ return New;
+}
+
/// Return true if we should break up this subtract of X-Y into (X + -Y).
static bool ShouldBreakUpSubtract(Instruction *Sub) {
// If this is a negation, we can't split it up!
@@ -1128,7 +1128,7 @@ static Value *EmitAddTreeOfValues(Instruction *I,
SmallVectorImpl<WeakTrackingVH> &Ops) {
if (Ops.size() == 1) return Ops.back();
- Value *V1 = Ops.pop_back_val();
+ Value *V1 = Ops.pop_back_val();
Value *V2 = EmitAddTreeOfValues(I, Ops);
return CreateAdd(V2, V1, "reass.add", I, I);
}
@@ -1992,7 +1992,7 @@ Value *ReassociatePass::OptimizeExpression(BinaryOperator *I,
void ReassociatePass::RecursivelyEraseDeadInsts(Instruction *I,
OrderedSet &Insts) {
assert(isInstructionTriviallyDead(I) && "Trivially dead instructions only!");
- SmallVector<Value *, 4> Ops(I->operands());
+ SmallVector<Value *, 4> Ops(I->operands());
ValueRankMap.erase(I);
Insts.remove(I);
RedoInsts.remove(I);
@@ -2009,7 +2009,7 @@ void ReassociatePass::EraseInst(Instruction *I) {
assert(isInstructionTriviallyDead(I) && "Trivially dead instructions only!");
LLVM_DEBUG(dbgs() << "Erasing dead inst: "; I->dump());
- SmallVector<Value *, 8> Ops(I->operands());
+ SmallVector<Value *, 8> Ops(I->operands());
// Erase the dead instruction.
ValueRankMap.erase(I);
RedoInsts.remove(I);
@@ -2209,19 +2209,19 @@ void ReassociatePass::OptimizeInst(Instruction *I) {
if (I->getType()->isIntegerTy(1))
return;
- // If this is a bitwise or instruction of operands
- // with no common bits set, convert it to X+Y.
- if (I->getOpcode() == Instruction::Or &&
- ShouldConvertOrWithNoCommonBitsToAdd(I) && !isLoadCombineCandidate(I) &&
- haveNoCommonBitsSet(I->getOperand(0), I->getOperand(1),
- I->getModule()->getDataLayout(), /*AC=*/nullptr, I,
- /*DT=*/nullptr)) {
- Instruction *NI = ConvertOrWithNoCommonBitsToAdd(I);
- RedoInsts.insert(I);
- MadeChange = true;
- I = NI;
- }
-
+ // If this is a bitwise or instruction of operands
+ // with no common bits set, convert it to X+Y.
+ if (I->getOpcode() == Instruction::Or &&
+ ShouldConvertOrWithNoCommonBitsToAdd(I) && !isLoadCombineCandidate(I) &&
+ haveNoCommonBitsSet(I->getOperand(0), I->getOperand(1),
+ I->getModule()->getDataLayout(), /*AC=*/nullptr, I,
+ /*DT=*/nullptr)) {
+ Instruction *NI = ConvertOrWithNoCommonBitsToAdd(I);
+ RedoInsts.insert(I);
+ MadeChange = true;
+ I = NI;
+ }
+
// If this is a subtract instruction which is not already in negate form,
// see if we can convert it to X+-Y.
if (I->getOpcode() == Instruction::Sub) {
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/Reg2Mem.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/Reg2Mem.cpp
index fef2f84a63..a49b9ad3f6 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/Reg2Mem.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/Reg2Mem.cpp
@@ -15,23 +15,23 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/Scalar/Reg2Mem.h"
+#include "llvm/Transforms/Scalar/Reg2Mem.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
-#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
-#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils.h"
-#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
#include <list>
using namespace llvm;
@@ -41,17 +41,17 @@ using namespace llvm;
STATISTIC(NumRegsDemoted, "Number of registers demoted");
STATISTIC(NumPhisDemoted, "Number of phi-nodes demoted");
-static bool valueEscapes(const Instruction &Inst) {
- const BasicBlock *BB = Inst.getParent();
- for (const User *U : Inst.users()) {
- const Instruction *UI = cast<Instruction>(U);
- if (UI->getParent() != BB || isa<PHINode>(UI))
- return true;
- }
- return false;
+static bool valueEscapes(const Instruction &Inst) {
+ const BasicBlock *BB = Inst.getParent();
+ for (const User *U : Inst.users()) {
+ const Instruction *UI = cast<Instruction>(U);
+ if (UI->getParent() != BB || isa<PHINode>(UI))
+ return true;
+ }
+ return false;
}
-static bool runPass(Function &F) {
+static bool runPass(Function &F) {
// Insert all new allocas into entry block.
BasicBlock *BBEntry = &F.getEntryBlock();
assert(pred_empty(BBEntry) &&
@@ -70,72 +70,72 @@ static bool runPass(Function &F) {
// Find the escaped instructions. But don't create stack slots for
// allocas in entry block.
std::list<Instruction*> WorkList;
- for (Instruction &I : instructions(F))
- if (!(isa<AllocaInst>(I) && I.getParent() == BBEntry) && valueEscapes(I))
- WorkList.push_front(&I);
+ for (Instruction &I : instructions(F))
+ if (!(isa<AllocaInst>(I) && I.getParent() == BBEntry) && valueEscapes(I))
+ WorkList.push_front(&I);
// Demote escaped instructions
NumRegsDemoted += WorkList.size();
- for (Instruction *I : WorkList)
- DemoteRegToStack(*I, false, AllocaInsertionPoint);
+ for (Instruction *I : WorkList)
+ DemoteRegToStack(*I, false, AllocaInsertionPoint);
WorkList.clear();
// Find all phi's
- for (BasicBlock &BB : F)
- for (auto &Phi : BB.phis())
- WorkList.push_front(&Phi);
+ for (BasicBlock &BB : F)
+ for (auto &Phi : BB.phis())
+ WorkList.push_front(&Phi);
// Demote phi nodes
NumPhisDemoted += WorkList.size();
- for (Instruction *I : WorkList)
- DemotePHIToStack(cast<PHINode>(I), AllocaInsertionPoint);
+ for (Instruction *I : WorkList)
+ DemotePHIToStack(cast<PHINode>(I), AllocaInsertionPoint);
return true;
}
-PreservedAnalyses RegToMemPass::run(Function &F, FunctionAnalysisManager &AM) {
- auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
- auto *LI = &AM.getResult<LoopAnalysis>(F);
- unsigned N = SplitAllCriticalEdges(F, CriticalEdgeSplittingOptions(DT, LI));
- bool Changed = runPass(F);
- if (N == 0 && !Changed)
- return PreservedAnalyses::all();
- PreservedAnalyses PA;
- PA.preserve<DominatorTreeAnalysis>();
- PA.preserve<LoopAnalysis>();
- return PA;
-}
-
-namespace {
-struct RegToMemLegacy : public FunctionPass {
- static char ID; // Pass identification, replacement for typeid
- RegToMemLegacy() : FunctionPass(ID) {
- initializeRegToMemLegacyPass(*PassRegistry::getPassRegistry());
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequiredID(BreakCriticalEdgesID);
- AU.addPreservedID(BreakCriticalEdgesID);
- }
-
- bool runOnFunction(Function &F) override {
- if (F.isDeclaration() || skipFunction(F))
- return false;
- return runPass(F);
- }
-};
-} // namespace
-
-char RegToMemLegacy::ID = 0;
-INITIALIZE_PASS_BEGIN(RegToMemLegacy, "reg2mem",
- "Demote all values to stack slots", false, false)
-INITIALIZE_PASS_DEPENDENCY(BreakCriticalEdges)
-INITIALIZE_PASS_END(RegToMemLegacy, "reg2mem",
- "Demote all values to stack slots", false, false)
-
+PreservedAnalyses RegToMemPass::run(Function &F, FunctionAnalysisManager &AM) {
+ auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
+ auto *LI = &AM.getResult<LoopAnalysis>(F);
+ unsigned N = SplitAllCriticalEdges(F, CriticalEdgeSplittingOptions(DT, LI));
+ bool Changed = runPass(F);
+ if (N == 0 && !Changed)
+ return PreservedAnalyses::all();
+ PreservedAnalyses PA;
+ PA.preserve<DominatorTreeAnalysis>();
+ PA.preserve<LoopAnalysis>();
+ return PA;
+}
+
+namespace {
+struct RegToMemLegacy : public FunctionPass {
+ static char ID; // Pass identification, replacement for typeid
+ RegToMemLegacy() : FunctionPass(ID) {
+ initializeRegToMemLegacyPass(*PassRegistry::getPassRegistry());
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequiredID(BreakCriticalEdgesID);
+ AU.addPreservedID(BreakCriticalEdgesID);
+ }
+
+ bool runOnFunction(Function &F) override {
+ if (F.isDeclaration() || skipFunction(F))
+ return false;
+ return runPass(F);
+ }
+};
+} // namespace
+
+char RegToMemLegacy::ID = 0;
+INITIALIZE_PASS_BEGIN(RegToMemLegacy, "reg2mem",
+ "Demote all values to stack slots", false, false)
+INITIALIZE_PASS_DEPENDENCY(BreakCriticalEdges)
+INITIALIZE_PASS_END(RegToMemLegacy, "reg2mem",
+ "Demote all values to stack slots", false, false)
+
// createDemoteRegisterToMemory - Provide an entry point to create this pass.
-char &llvm::DemoteRegisterToMemoryID = RegToMemLegacy::ID;
+char &llvm::DemoteRegisterToMemoryID = RegToMemLegacy::ID;
FunctionPass *llvm::createDemoteRegisterToMemoryPass() {
- return new RegToMemLegacy();
+ return new RegToMemLegacy();
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
index ee39ffa000..b7830555bf 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
@@ -1487,7 +1487,7 @@ makeStatepointExplicitImpl(CallBase *Call, /* to replace */
uint32_t NumPatchBytes = 0;
uint32_t Flags = uint32_t(StatepointFlags::None);
- SmallVector<Value *, 8> CallArgs(Call->args());
+ SmallVector<Value *, 8> CallArgs(Call->args());
Optional<ArrayRef<Use>> DeoptArgs;
if (auto Bundle = Call->getOperandBundle(LLVMContext::OB_deopt))
DeoptArgs = Bundle->Inputs;
@@ -1520,8 +1520,8 @@ makeStatepointExplicitImpl(CallBase *Call, /* to replace */
Value *CallTarget = Call->getCalledOperand();
if (Function *F = dyn_cast<Function>(CallTarget)) {
- auto IID = F->getIntrinsicID();
- if (IID == Intrinsic::experimental_deoptimize) {
+ auto IID = F->getIntrinsicID();
+ if (IID == Intrinsic::experimental_deoptimize) {
// Calls to llvm.experimental.deoptimize are lowered to calls to the
// __llvm_deoptimize symbol. We want to resolve this now, since the
// verifier does not allow taking the address of an intrinsic function.
@@ -1541,101 +1541,101 @@ makeStatepointExplicitImpl(CallBase *Call, /* to replace */
.getCallee();
IsDeoptimize = true;
- } else if (IID == Intrinsic::memcpy_element_unordered_atomic ||
- IID == Intrinsic::memmove_element_unordered_atomic) {
- // Unordered atomic memcpy and memmove intrinsics which are not explicitly
- // marked as "gc-leaf-function" should be lowered in a GC parseable way.
- // Specifically, these calls should be lowered to the
- // __llvm_{memcpy|memmove}_element_unordered_atomic_safepoint symbols.
- // Similarly to __llvm_deoptimize we want to resolve this now, since the
- // verifier does not allow taking the address of an intrinsic function.
- //
- // Moreover we need to shuffle the arguments for the call in order to
- // accommodate GC. The underlying source and destination objects might be
- // relocated during copy operation should the GC occur. To relocate the
- // derived source and destination pointers the implementation of the
- // intrinsic should know the corresponding base pointers.
- //
- // To make the base pointers available pass them explicitly as arguments:
- // memcpy(dest_derived, source_derived, ...) =>
- // memcpy(dest_base, dest_offset, source_base, source_offset, ...)
- auto &Context = Call->getContext();
- auto &DL = Call->getModule()->getDataLayout();
- auto GetBaseAndOffset = [&](Value *Derived) {
- assert(Result.PointerToBase.count(Derived));
- unsigned AddressSpace = Derived->getType()->getPointerAddressSpace();
- unsigned IntPtrSize = DL.getPointerSizeInBits(AddressSpace);
- Value *Base = Result.PointerToBase.find(Derived)->second;
- Value *Base_int = Builder.CreatePtrToInt(
- Base, Type::getIntNTy(Context, IntPtrSize));
- Value *Derived_int = Builder.CreatePtrToInt(
- Derived, Type::getIntNTy(Context, IntPtrSize));
- return std::make_pair(Base, Builder.CreateSub(Derived_int, Base_int));
- };
-
- auto *Dest = CallArgs[0];
- Value *DestBase, *DestOffset;
- std::tie(DestBase, DestOffset) = GetBaseAndOffset(Dest);
-
- auto *Source = CallArgs[1];
- Value *SourceBase, *SourceOffset;
- std::tie(SourceBase, SourceOffset) = GetBaseAndOffset(Source);
-
- auto *LengthInBytes = CallArgs[2];
- auto *ElementSizeCI = cast<ConstantInt>(CallArgs[3]);
-
- CallArgs.clear();
- CallArgs.push_back(DestBase);
- CallArgs.push_back(DestOffset);
- CallArgs.push_back(SourceBase);
- CallArgs.push_back(SourceOffset);
- CallArgs.push_back(LengthInBytes);
-
- SmallVector<Type *, 8> DomainTy;
- for (Value *Arg : CallArgs)
- DomainTy.push_back(Arg->getType());
- auto *FTy = FunctionType::get(Type::getVoidTy(F->getContext()), DomainTy,
- /* isVarArg = */ false);
-
- auto GetFunctionName = [](Intrinsic::ID IID, ConstantInt *ElementSizeCI) {
- uint64_t ElementSize = ElementSizeCI->getZExtValue();
- if (IID == Intrinsic::memcpy_element_unordered_atomic) {
- switch (ElementSize) {
- case 1:
- return "__llvm_memcpy_element_unordered_atomic_safepoint_1";
- case 2:
- return "__llvm_memcpy_element_unordered_atomic_safepoint_2";
- case 4:
- return "__llvm_memcpy_element_unordered_atomic_safepoint_4";
- case 8:
- return "__llvm_memcpy_element_unordered_atomic_safepoint_8";
- case 16:
- return "__llvm_memcpy_element_unordered_atomic_safepoint_16";
- default:
- llvm_unreachable("unexpected element size!");
- }
- }
- assert(IID == Intrinsic::memmove_element_unordered_atomic);
- switch (ElementSize) {
- case 1:
- return "__llvm_memmove_element_unordered_atomic_safepoint_1";
- case 2:
- return "__llvm_memmove_element_unordered_atomic_safepoint_2";
- case 4:
- return "__llvm_memmove_element_unordered_atomic_safepoint_4";
- case 8:
- return "__llvm_memmove_element_unordered_atomic_safepoint_8";
- case 16:
- return "__llvm_memmove_element_unordered_atomic_safepoint_16";
- default:
- llvm_unreachable("unexpected element size!");
- }
- };
-
- CallTarget =
- F->getParent()
- ->getOrInsertFunction(GetFunctionName(IID, ElementSizeCI), FTy)
- .getCallee();
+ } else if (IID == Intrinsic::memcpy_element_unordered_atomic ||
+ IID == Intrinsic::memmove_element_unordered_atomic) {
+ // Unordered atomic memcpy and memmove intrinsics which are not explicitly
+ // marked as "gc-leaf-function" should be lowered in a GC parseable way.
+ // Specifically, these calls should be lowered to the
+ // __llvm_{memcpy|memmove}_element_unordered_atomic_safepoint symbols.
+ // Similarly to __llvm_deoptimize we want to resolve this now, since the
+ // verifier does not allow taking the address of an intrinsic function.
+ //
+ // Moreover we need to shuffle the arguments for the call in order to
+ // accommodate GC. The underlying source and destination objects might be
+ // relocated during copy operation should the GC occur. To relocate the
+ // derived source and destination pointers the implementation of the
+ // intrinsic should know the corresponding base pointers.
+ //
+ // To make the base pointers available pass them explicitly as arguments:
+ // memcpy(dest_derived, source_derived, ...) =>
+ // memcpy(dest_base, dest_offset, source_base, source_offset, ...)
+ auto &Context = Call->getContext();
+ auto &DL = Call->getModule()->getDataLayout();
+ auto GetBaseAndOffset = [&](Value *Derived) {
+ assert(Result.PointerToBase.count(Derived));
+ unsigned AddressSpace = Derived->getType()->getPointerAddressSpace();
+ unsigned IntPtrSize = DL.getPointerSizeInBits(AddressSpace);
+ Value *Base = Result.PointerToBase.find(Derived)->second;
+ Value *Base_int = Builder.CreatePtrToInt(
+ Base, Type::getIntNTy(Context, IntPtrSize));
+ Value *Derived_int = Builder.CreatePtrToInt(
+ Derived, Type::getIntNTy(Context, IntPtrSize));
+ return std::make_pair(Base, Builder.CreateSub(Derived_int, Base_int));
+ };
+
+ auto *Dest = CallArgs[0];
+ Value *DestBase, *DestOffset;
+ std::tie(DestBase, DestOffset) = GetBaseAndOffset(Dest);
+
+ auto *Source = CallArgs[1];
+ Value *SourceBase, *SourceOffset;
+ std::tie(SourceBase, SourceOffset) = GetBaseAndOffset(Source);
+
+ auto *LengthInBytes = CallArgs[2];
+ auto *ElementSizeCI = cast<ConstantInt>(CallArgs[3]);
+
+ CallArgs.clear();
+ CallArgs.push_back(DestBase);
+ CallArgs.push_back(DestOffset);
+ CallArgs.push_back(SourceBase);
+ CallArgs.push_back(SourceOffset);
+ CallArgs.push_back(LengthInBytes);
+
+ SmallVector<Type *, 8> DomainTy;
+ for (Value *Arg : CallArgs)
+ DomainTy.push_back(Arg->getType());
+ auto *FTy = FunctionType::get(Type::getVoidTy(F->getContext()), DomainTy,
+ /* isVarArg = */ false);
+
+ auto GetFunctionName = [](Intrinsic::ID IID, ConstantInt *ElementSizeCI) {
+ uint64_t ElementSize = ElementSizeCI->getZExtValue();
+ if (IID == Intrinsic::memcpy_element_unordered_atomic) {
+ switch (ElementSize) {
+ case 1:
+ return "__llvm_memcpy_element_unordered_atomic_safepoint_1";
+ case 2:
+ return "__llvm_memcpy_element_unordered_atomic_safepoint_2";
+ case 4:
+ return "__llvm_memcpy_element_unordered_atomic_safepoint_4";
+ case 8:
+ return "__llvm_memcpy_element_unordered_atomic_safepoint_8";
+ case 16:
+ return "__llvm_memcpy_element_unordered_atomic_safepoint_16";
+ default:
+ llvm_unreachable("unexpected element size!");
+ }
+ }
+ assert(IID == Intrinsic::memmove_element_unordered_atomic);
+ switch (ElementSize) {
+ case 1:
+ return "__llvm_memmove_element_unordered_atomic_safepoint_1";
+ case 2:
+ return "__llvm_memmove_element_unordered_atomic_safepoint_2";
+ case 4:
+ return "__llvm_memmove_element_unordered_atomic_safepoint_4";
+ case 8:
+ return "__llvm_memmove_element_unordered_atomic_safepoint_8";
+ case 16:
+ return "__llvm_memmove_element_unordered_atomic_safepoint_16";
+ default:
+ llvm_unreachable("unexpected element size!");
+ }
+ };
+
+ CallTarget =
+ F->getParent()
+ ->getOrInsertFunction(GetFunctionName(IID, ElementSizeCI), FTy)
+ .getCallee();
}
}
@@ -2036,7 +2036,7 @@ static void relocationViaAlloca(
/// tests in ways which make them less useful in testing fused safepoints.
template <typename T> static void unique_unsorted(SmallVectorImpl<T> &Vec) {
SmallSet<T, 8> Seen;
- erase_if(Vec, [&](const T &V) { return !Seen.insert(V).second; });
+ erase_if(Vec, [&](const T &V) { return !Seen.insert(V).second; });
}
/// Insert holders so that each Value is obviously live through the entire
@@ -2108,10 +2108,10 @@ static Value* findRematerializableChainToBasePointer(
// Helper function for the "rematerializeLiveValues". Compute cost of the use
// chain we are going to rematerialize.
-static InstructionCost
-chainToBasePointerCost(SmallVectorImpl<Instruction *> &Chain,
+static InstructionCost
+chainToBasePointerCost(SmallVectorImpl<Instruction *> &Chain,
TargetTransformInfo &TTI) {
- InstructionCost Cost = 0;
+ InstructionCost Cost = 0;
for (Instruction *Instr : Chain) {
if (CastInst *CI = dyn_cast<CastInst>(Instr)) {
@@ -2120,8 +2120,8 @@ chainToBasePointerCost(SmallVectorImpl<Instruction *> &Chain,
Type *SrcTy = CI->getOperand(0)->getType();
Cost += TTI.getCastInstrCost(CI->getOpcode(), CI->getType(), SrcTy,
- TTI::getCastContextHint(CI),
- TargetTransformInfo::TCK_SizeAndLatency, CI);
+ TTI::getCastContextHint(CI),
+ TargetTransformInfo::TCK_SizeAndLatency, CI);
} else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Instr)) {
// Cost of the address calculation
@@ -2218,7 +2218,7 @@ static void rematerializeLiveValues(CallBase *Call,
assert(Info.LiveSet.count(AlternateRootPhi));
}
// Compute cost of this chain
- InstructionCost Cost = chainToBasePointerCost(ChainToBase, TTI);
+ InstructionCost Cost = chainToBasePointerCost(ChainToBase, TTI);
// TODO: We can also account for cases when we will be able to remove some
// of the rematerialized values by later optimization passes. I.e if
// we rematerialized several intersecting chains. Or if original values
@@ -2499,7 +2499,7 @@ static bool insertParsePoints(Function &F, DominatorTree &DT,
// That Value* no longer exists and we need to use the new gc_result.
// Thankfully, the live set is embedded in the statepoint (and updated), so
// we just grab that.
- llvm::append_range(Live, Info.StatepointToken->gc_args());
+ llvm::append_range(Live, Info.StatepointToken->gc_args());
#ifndef NDEBUG
// Do some basic sanity checks on our liveness results before performing
// relocation. Relocation can and will turn mistakes in liveness results
@@ -2675,27 +2675,27 @@ bool RewriteStatepointsForGC::runOnFunction(Function &F, DominatorTree &DT,
assert(shouldRewriteStatepointsIn(F) && "mismatch in rewrite decision");
auto NeedsRewrite = [&TLI](Instruction &I) {
- if (const auto *Call = dyn_cast<CallBase>(&I)) {
- if (isa<GCStatepointInst>(Call))
- return false;
- if (callsGCLeafFunction(Call, TLI))
- return false;
-
- // Normally it's up to the frontend to make sure that non-leaf calls also
- // have proper deopt state if it is required. We make an exception for
- // element atomic memcpy/memmove intrinsics here. Unlike other intrinsics
- // these are non-leaf by default. They might be generated by the optimizer
- // which doesn't know how to produce a proper deopt state. So if we see a
- // non-leaf memcpy/memmove without deopt state just treat it as a leaf
- // copy and don't produce a statepoint.
- if (!AllowStatepointWithNoDeoptInfo &&
- !Call->getOperandBundle(LLVMContext::OB_deopt)) {
- assert((isa<AtomicMemCpyInst>(Call) || isa<AtomicMemMoveInst>(Call)) &&
- "Don't expect any other calls here!");
- return false;
- }
- return true;
- }
+ if (const auto *Call = dyn_cast<CallBase>(&I)) {
+ if (isa<GCStatepointInst>(Call))
+ return false;
+ if (callsGCLeafFunction(Call, TLI))
+ return false;
+
+ // Normally it's up to the frontend to make sure that non-leaf calls also
+ // have proper deopt state if it is required. We make an exception for
+ // element atomic memcpy/memmove intrinsics here. Unlike other intrinsics
+ // these are non-leaf by default. They might be generated by the optimizer
+ // which doesn't know how to produce a proper deopt state. So if we see a
+ // non-leaf memcpy/memmove without deopt state just treat it as a leaf
+ // copy and don't produce a statepoint.
+ if (!AllowStatepointWithNoDeoptInfo &&
+ !Call->getOperandBundle(LLVMContext::OB_deopt)) {
+ assert((isa<AtomicMemCpyInst>(Call) || isa<AtomicMemMoveInst>(Call)) &&
+ "Don't expect any other calls here!");
+ return false;
+ }
+ return true;
+ }
return false;
};
@@ -2733,8 +2733,8 @@ bool RewriteStatepointsForGC::runOnFunction(Function &F, DominatorTree &DT,
// of liveness sets for no good reason. It may be harder to do this post
// insertion since relocations and base phis can confuse things.
for (BasicBlock &BB : F)
- if (BB.getUniquePredecessor())
- MadeChange |= FoldSingleEntryPHINodes(&BB);
+ if (BB.getUniquePredecessor())
+ MadeChange |= FoldSingleEntryPHINodes(&BB);
// Before we start introducing relocations, we want to tweak the IR a bit to
// avoid unfortunate code generation effects. The main example is that we
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/SCCP.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/SCCP.cpp
index 97a5040300..8feed9e9eb 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/SCCP.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/SCCP.cpp
@@ -23,7 +23,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
@@ -34,7 +34,7 @@
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueLattice.h"
#include "llvm/Analysis/ValueLatticeUtils.h"
-#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
@@ -105,7 +105,7 @@ bool isConstant(const ValueLatticeElement &LV) {
// ValueLatticeElement::isOverdefined() and is intended to be used in the
// transition to ValueLatticeElement.
bool isOverdefined(const ValueLatticeElement &LV) {
- return !LV.isUnknownOrUndef() && !isConstant(LV);
+ return !LV.isUnknownOrUndef() && !isConstant(LV);
}
//===----------------------------------------------------------------------===//
@@ -234,7 +234,7 @@ public:
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
TrackedMultipleRetVals.insert(
std::make_pair(std::make_pair(F, i), ValueLatticeElement()));
- } else if (!F->getReturnType()->isVoidTy())
+ } else if (!F->getReturnType()->isVoidTy())
TrackedRetVals.insert(std::make_pair(F, ValueLatticeElement()));
}
@@ -276,7 +276,7 @@ public:
// isEdgeFeasible - Return true if the control flow edge from the 'From' basic
// block to the 'To' basic block is currently feasible.
- bool isEdgeFeasible(BasicBlock *From, BasicBlock *To) const;
+ bool isEdgeFeasible(BasicBlock *From, BasicBlock *To) const;
std::vector<ValueLatticeElement> getStructLatticeValueFor(Value *V) const {
std::vector<ValueLatticeElement> StructValues;
@@ -542,14 +542,14 @@ private:
auto Iter = AdditionalUsers.find(I);
if (Iter != AdditionalUsers.end()) {
- // Copy additional users before notifying them of changes, because new
- // users may be added, potentially invalidating the iterator.
- SmallVector<Instruction *, 2> ToNotify;
+ // Copy additional users before notifying them of changes, because new
+ // users may be added, potentially invalidating the iterator.
+ SmallVector<Instruction *, 2> ToNotify;
for (User *U : Iter->second)
if (auto *UI = dyn_cast<Instruction>(U))
- ToNotify.push_back(UI);
- for (Instruction *UI : ToNotify)
- OperandChangedState(UI);
+ ToNotify.push_back(UI);
+ for (Instruction *UI : ToNotify)
+ OperandChangedState(UI);
}
}
void handleCallOverdefined(CallBase &CB);
@@ -654,30 +654,30 @@ void SCCPSolver::getFeasibleSuccessors(Instruction &TI,
Succs[0] = true;
return;
}
- const ValueLatticeElement &SCValue = getValueState(SI->getCondition());
- if (ConstantInt *CI = getConstantInt(SCValue)) {
- Succs[SI->findCaseValue(CI)->getSuccessorIndex()] = true;
- return;
- }
-
- // TODO: Switch on undef is UB. Stop passing false once the rest of LLVM
- // is ready.
- if (SCValue.isConstantRange(/*UndefAllowed=*/false)) {
- const ConstantRange &Range = SCValue.getConstantRange();
- for (const auto &Case : SI->cases()) {
- const APInt &CaseValue = Case.getCaseValue()->getValue();
- if (Range.contains(CaseValue))
- Succs[Case.getSuccessorIndex()] = true;
- }
-
- // TODO: Determine whether default case is reachable.
- Succs[SI->case_default()->getSuccessorIndex()] = true;
+ const ValueLatticeElement &SCValue = getValueState(SI->getCondition());
+ if (ConstantInt *CI = getConstantInt(SCValue)) {
+ Succs[SI->findCaseValue(CI)->getSuccessorIndex()] = true;
return;
}
- // Overdefined or unknown condition? All destinations are executable!
- if (!SCValue.isUnknownOrUndef())
- Succs.assign(TI.getNumSuccessors(), true);
+ // TODO: Switch on undef is UB. Stop passing false once the rest of LLVM
+ // is ready.
+ if (SCValue.isConstantRange(/*UndefAllowed=*/false)) {
+ const ConstantRange &Range = SCValue.getConstantRange();
+ for (const auto &Case : SI->cases()) {
+ const APInt &CaseValue = Case.getCaseValue()->getValue();
+ if (Range.contains(CaseValue))
+ Succs[Case.getSuccessorIndex()] = true;
+ }
+
+ // TODO: Determine whether default case is reachable.
+ Succs[SI->case_default()->getSuccessorIndex()] = true;
+ return;
+ }
+
+ // Overdefined or unknown condition? All destinations are executable!
+ if (!SCValue.isUnknownOrUndef())
+ Succs.assign(TI.getNumSuccessors(), true);
return;
}
@@ -723,7 +723,7 @@ void SCCPSolver::getFeasibleSuccessors(Instruction &TI,
// isEdgeFeasible - Return true if the control flow edge from the 'From' basic
// block to the 'To' basic block is currently feasible.
-bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) const {
+bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) const {
// Check if we've called markEdgeExecutable on the edge yet. (We could
// be more aggressive and try to consider edges which haven't been marked
// yet, but there isn't any need.)
@@ -848,16 +848,16 @@ void SCCPSolver::visitCastInst(CastInst &I) {
auto &LV = getValueState(&I);
ConstantRange OpRange = OpSt.getConstantRange();
Type *DestTy = I.getDestTy();
- // Vectors where all elements have the same known constant range are treated
- // as a single constant range in the lattice. When bitcasting such vectors,
- // there is a mis-match between the width of the lattice value (single
- // constant range) and the original operands (vector). Go to overdefined in
- // that case.
- if (I.getOpcode() == Instruction::BitCast &&
- I.getOperand(0)->getType()->isVectorTy() &&
- OpRange.getBitWidth() < DL.getTypeSizeInBits(DestTy))
- return (void)markOverdefined(&I);
-
+ // Vectors where all elements have the same known constant range are treated
+ // as a single constant range in the lattice. When bitcasting such vectors,
+ // there is a mis-match between the width of the lattice value (single
+ // constant range) and the original operands (vector). Go to overdefined in
+ // that case.
+ if (I.getOpcode() == Instruction::BitCast &&
+ I.getOperand(0)->getType()->isVectorTy() &&
+ OpRange.getBitWidth() < DL.getTypeSizeInBits(DestTy))
+ return (void)markOverdefined(&I);
+
ConstantRange Res =
OpRange.castOp(I.getOpcode(), DL.getTypeSizeInBits(DestTy));
mergeInValue(LV, &I, ValueLatticeElement::getRange(Res));
@@ -1138,9 +1138,9 @@ static ValueLatticeElement getValueFromMetadata(const Instruction *I) {
if (I->getType()->isIntegerTy())
return ValueLatticeElement::getRange(
getConstantRangeFromMetadata(*Ranges));
- if (I->hasMetadata(LLVMContext::MD_nonnull))
- return ValueLatticeElement::getNot(
- ConstantPointerNull::get(cast<PointerType>(I->getType())));
+ if (I->hasMetadata(LLVMContext::MD_nonnull))
+ return ValueLatticeElement::getNot(
+ ConstantPointerNull::get(cast<PointerType>(I->getType())));
return ValueLatticeElement::getOverdefined();
}
@@ -1293,33 +1293,33 @@ void SCCPSolver::handleCallResult(CallBase &CB) {
auto *PI = getPredicateInfoFor(&CB);
assert(PI && "Missing predicate info for ssa.copy");
- const Optional<PredicateConstraint> &Constraint = PI->getConstraint();
- if (!Constraint) {
+ const Optional<PredicateConstraint> &Constraint = PI->getConstraint();
+ if (!Constraint) {
mergeInValue(ValueState[&CB], &CB, CopyOfVal);
return;
}
- CmpInst::Predicate Pred = Constraint->Predicate;
- Value *OtherOp = Constraint->OtherOp;
+ CmpInst::Predicate Pred = Constraint->Predicate;
+ Value *OtherOp = Constraint->OtherOp;
- // Wait until OtherOp is resolved.
- if (getValueState(OtherOp).isUnknown()) {
- addAdditionalUser(OtherOp, &CB);
+ // Wait until OtherOp is resolved.
+ if (getValueState(OtherOp).isUnknown()) {
+ addAdditionalUser(OtherOp, &CB);
return;
}
- // TODO: Actually filp MayIncludeUndef for the created range to false,
- // once most places in the optimizer respect the branches on
- // undef/poison are UB rule. The reason why the new range cannot be
- // undef is as follows below:
- // The new range is based on a branch condition. That guarantees that
- // neither of the compare operands can be undef in the branch targets,
- // unless we have conditions that are always true/false (e.g. icmp ule
- // i32, %a, i32_max). For the latter overdefined/empty range will be
- // inferred, but the branch will get folded accordingly anyways.
- bool MayIncludeUndef = !isa<PredicateAssume>(PI);
-
- ValueLatticeElement CondVal = getValueState(OtherOp);
+ // TODO: Actually filp MayIncludeUndef for the created range to false,
+ // once most places in the optimizer respect the branches on
+ // undef/poison are UB rule. The reason why the new range cannot be
+ // undef is as follows below:
+ // The new range is based on a branch condition. That guarantees that
+ // neither of the compare operands can be undef in the branch targets,
+ // unless we have conditions that are always true/false (e.g. icmp ule
+ // i32, %a, i32_max). For the latter overdefined/empty range will be
+ // inferred, but the branch will get folded accordingly anyways.
+ bool MayIncludeUndef = !isa<PredicateAssume>(PI);
+
+ ValueLatticeElement CondVal = getValueState(OtherOp);
ValueLatticeElement &IV = ValueState[&CB];
if (CondVal.isConstantRange() || CopyOfVal.isConstantRange()) {
auto ImposedCR =
@@ -1343,47 +1343,47 @@ void SCCPSolver::handleCallResult(CallBase &CB) {
if (!CopyOfCR.contains(NewCR) && CopyOfCR.getSingleMissingElement())
NewCR = CopyOfCR;
- addAdditionalUser(OtherOp, &CB);
+ addAdditionalUser(OtherOp, &CB);
mergeInValue(
IV, &CB,
- ValueLatticeElement::getRange(NewCR, MayIncludeUndef));
+ ValueLatticeElement::getRange(NewCR, MayIncludeUndef));
return;
} else if (Pred == CmpInst::ICMP_EQ && CondVal.isConstant()) {
// For non-integer values or integer constant expressions, only
// propagate equal constants.
- addAdditionalUser(OtherOp, &CB);
+ addAdditionalUser(OtherOp, &CB);
mergeInValue(IV, &CB, CondVal);
return;
- } else if (Pred == CmpInst::ICMP_NE && CondVal.isConstant() &&
- !MayIncludeUndef) {
- // Propagate inequalities.
- addAdditionalUser(OtherOp, &CB);
- mergeInValue(IV, &CB,
- ValueLatticeElement::getNot(CondVal.getConstant()));
- return;
+ } else if (Pred == CmpInst::ICMP_NE && CondVal.isConstant() &&
+ !MayIncludeUndef) {
+ // Propagate inequalities.
+ addAdditionalUser(OtherOp, &CB);
+ mergeInValue(IV, &CB,
+ ValueLatticeElement::getNot(CondVal.getConstant()));
+ return;
}
return (void)mergeInValue(IV, &CB, CopyOfVal);
}
-
- if (ConstantRange::isIntrinsicSupported(II->getIntrinsicID())) {
- // Compute result range for intrinsics supported by ConstantRange.
- // Do this even if we don't know a range for all operands, as we may
- // still know something about the result range, e.g. of abs(x).
- SmallVector<ConstantRange, 2> OpRanges;
- for (Value *Op : II->args()) {
- const ValueLatticeElement &State = getValueState(Op);
- if (State.isConstantRange())
- OpRanges.push_back(State.getConstantRange());
- else
- OpRanges.push_back(
- ConstantRange::getFull(Op->getType()->getScalarSizeInBits()));
- }
-
- ConstantRange Result =
- ConstantRange::intrinsic(II->getIntrinsicID(), OpRanges);
- return (void)mergeInValue(II, ValueLatticeElement::getRange(Result));
- }
+
+ if (ConstantRange::isIntrinsicSupported(II->getIntrinsicID())) {
+ // Compute result range for intrinsics supported by ConstantRange.
+ // Do this even if we don't know a range for all operands, as we may
+ // still know something about the result range, e.g. of abs(x).
+ SmallVector<ConstantRange, 2> OpRanges;
+ for (Value *Op : II->args()) {
+ const ValueLatticeElement &State = getValueState(Op);
+ if (State.isConstantRange())
+ OpRanges.push_back(State.getConstantRange());
+ else
+ OpRanges.push_back(
+ ConstantRange::getFull(Op->getType()->getScalarSizeInBits()));
+ }
+
+ ConstantRange Result =
+ ConstantRange::intrinsic(II->getIntrinsicID(), OpRanges);
+ return (void)mergeInValue(II, ValueLatticeElement::getRange(Result));
+ }
}
// The common case is that we aren't tracking the callee, either because we
@@ -1453,7 +1453,7 @@ void SCCPSolver::Solve() {
// Process the basic block work list.
while (!BBWorkList.empty()) {
- BasicBlock *BB = BBWorkList.pop_back_val();
+ BasicBlock *BB = BBWorkList.pop_back_val();
LLVM_DEBUG(dbgs() << "\nPopped off BBWL: " << *BB << '\n');
@@ -1481,7 +1481,7 @@ void SCCPSolver::Solve() {
/// This scan also checks for values that use undefs. It conservatively marks
/// them as overdefined.
bool SCCPSolver::ResolvedUndefsIn(Function &F) {
- bool MadeChange = false;
+ bool MadeChange = false;
for (BasicBlock &BB : F) {
if (!BBExecutable.count(&BB))
continue;
@@ -1507,10 +1507,10 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
// more precise than this but it isn't worth bothering.
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
ValueLatticeElement &LV = getStructValueState(&I, i);
- if (LV.isUnknownOrUndef()) {
+ if (LV.isUnknownOrUndef()) {
markOverdefined(LV, &I);
- MadeChange = true;
- }
+ MadeChange = true;
+ }
}
continue;
}
@@ -1537,7 +1537,7 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
}
markOverdefined(&I);
- MadeChange = true;
+ MadeChange = true;
}
// Check to see if we have a branch or switch on an undefined value. If so
@@ -1554,8 +1554,8 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
if (isa<UndefValue>(BI->getCondition())) {
BI->setCondition(ConstantInt::getFalse(BI->getContext()));
markEdgeExecutable(&BB, TI->getSuccessor(1));
- MadeChange = true;
- continue;
+ MadeChange = true;
+ continue;
}
// Otherwise, it is a branch on a symbolic value which is currently
@@ -1564,7 +1564,7 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
// FIXME: Distinguish between dead code and an LLVM "undef" value.
BasicBlock *DefaultSuccessor = TI->getSuccessor(1);
if (markEdgeExecutable(&BB, DefaultSuccessor))
- MadeChange = true;
+ MadeChange = true;
continue;
}
@@ -1583,8 +1583,8 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
if (isa<UndefValue>(IBR->getAddress())) {
IBR->setAddress(BlockAddress::get(IBR->getSuccessor(0)));
markEdgeExecutable(&BB, IBR->getSuccessor(0));
- MadeChange = true;
- continue;
+ MadeChange = true;
+ continue;
}
// Otherwise, it is a branch on a symbolic value which is currently
@@ -1594,7 +1594,7 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
// we can assume the branch has undefined behavior instead.
BasicBlock *DefaultSuccessor = IBR->getSuccessor(0);
if (markEdgeExecutable(&BB, DefaultSuccessor))
- MadeChange = true;
+ MadeChange = true;
continue;
}
@@ -1609,8 +1609,8 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
if (isa<UndefValue>(SI->getCondition())) {
SI->setCondition(SI->case_begin()->getCaseValue());
markEdgeExecutable(&BB, SI->case_begin()->getCaseSuccessor());
- MadeChange = true;
- continue;
+ MadeChange = true;
+ continue;
}
// Otherwise, it is a branch on a symbolic value which is currently
@@ -1619,13 +1619,13 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
// FIXME: Distinguish between dead code and an LLVM "undef" value.
BasicBlock *DefaultSuccessor = SI->case_begin()->getCaseSuccessor();
if (markEdgeExecutable(&BB, DefaultSuccessor))
- MadeChange = true;
+ MadeChange = true;
continue;
}
}
- return MadeChange;
+ return MadeChange;
}
static bool tryToReplaceWithConstant(SCCPSolver &Solver, Value *V) {
@@ -1747,7 +1747,7 @@ static bool runSCCP(Function &F, const DataLayout &DL,
LLVM_DEBUG(dbgs() << " BasicBlock Dead:" << BB);
++NumDeadBlocks;
- NumInstRemoved += removeAllNonTerminatorAndEHPadInstructions(&BB).first;
+ NumInstRemoved += removeAllNonTerminatorAndEHPadInstructions(&BB).first;
MadeChanges = true;
continue;
@@ -1870,68 +1870,68 @@ static void findReturnsToZap(Function &F,
}
}
-static bool removeNonFeasibleEdges(const SCCPSolver &Solver, BasicBlock *BB,
- DomTreeUpdater &DTU) {
- SmallPtrSet<BasicBlock *, 8> FeasibleSuccessors;
- bool HasNonFeasibleEdges = false;
- for (BasicBlock *Succ : successors(BB)) {
- if (Solver.isEdgeFeasible(BB, Succ))
- FeasibleSuccessors.insert(Succ);
- else
- HasNonFeasibleEdges = true;
- }
-
- // All edges feasible, nothing to do.
- if (!HasNonFeasibleEdges)
- return false;
-
- // SCCP can only determine non-feasible edges for br, switch and indirectbr.
- Instruction *TI = BB->getTerminator();
- assert((isa<BranchInst>(TI) || isa<SwitchInst>(TI) ||
- isa<IndirectBrInst>(TI)) &&
- "Terminator must be a br, switch or indirectbr");
-
- if (FeasibleSuccessors.size() == 1) {
- // Replace with an unconditional branch to the only feasible successor.
- BasicBlock *OnlyFeasibleSuccessor = *FeasibleSuccessors.begin();
- SmallVector<DominatorTree::UpdateType, 8> Updates;
- bool HaveSeenOnlyFeasibleSuccessor = false;
- for (BasicBlock *Succ : successors(BB)) {
- if (Succ == OnlyFeasibleSuccessor && !HaveSeenOnlyFeasibleSuccessor) {
- // Don't remove the edge to the only feasible successor the first time
- // we see it. We still do need to remove any multi-edges to it though.
- HaveSeenOnlyFeasibleSuccessor = true;
- continue;
- }
-
- Succ->removePredecessor(BB);
- Updates.push_back({DominatorTree::Delete, BB, Succ});
+static bool removeNonFeasibleEdges(const SCCPSolver &Solver, BasicBlock *BB,
+ DomTreeUpdater &DTU) {
+ SmallPtrSet<BasicBlock *, 8> FeasibleSuccessors;
+ bool HasNonFeasibleEdges = false;
+ for (BasicBlock *Succ : successors(BB)) {
+ if (Solver.isEdgeFeasible(BB, Succ))
+ FeasibleSuccessors.insert(Succ);
+ else
+ HasNonFeasibleEdges = true;
+ }
+
+ // All edges feasible, nothing to do.
+ if (!HasNonFeasibleEdges)
+ return false;
+
+ // SCCP can only determine non-feasible edges for br, switch and indirectbr.
+ Instruction *TI = BB->getTerminator();
+ assert((isa<BranchInst>(TI) || isa<SwitchInst>(TI) ||
+ isa<IndirectBrInst>(TI)) &&
+ "Terminator must be a br, switch or indirectbr");
+
+ if (FeasibleSuccessors.size() == 1) {
+ // Replace with an unconditional branch to the only feasible successor.
+ BasicBlock *OnlyFeasibleSuccessor = *FeasibleSuccessors.begin();
+ SmallVector<DominatorTree::UpdateType, 8> Updates;
+ bool HaveSeenOnlyFeasibleSuccessor = false;
+ for (BasicBlock *Succ : successors(BB)) {
+ if (Succ == OnlyFeasibleSuccessor && !HaveSeenOnlyFeasibleSuccessor) {
+ // Don't remove the edge to the only feasible successor the first time
+ // we see it. We still do need to remove any multi-edges to it though.
+ HaveSeenOnlyFeasibleSuccessor = true;
+ continue;
+ }
+
+ Succ->removePredecessor(BB);
+ Updates.push_back({DominatorTree::Delete, BB, Succ});
}
-
- BranchInst::Create(OnlyFeasibleSuccessor, BB);
- TI->eraseFromParent();
- DTU.applyUpdatesPermissive(Updates);
- } else if (FeasibleSuccessors.size() > 1) {
- SwitchInstProfUpdateWrapper SI(*cast<SwitchInst>(TI));
- SmallVector<DominatorTree::UpdateType, 8> Updates;
- for (auto CI = SI->case_begin(); CI != SI->case_end();) {
- if (FeasibleSuccessors.contains(CI->getCaseSuccessor())) {
- ++CI;
- continue;
- }
-
- BasicBlock *Succ = CI->getCaseSuccessor();
- Succ->removePredecessor(BB);
- Updates.push_back({DominatorTree::Delete, BB, Succ});
- SI.removeCase(CI);
- // Don't increment CI, as we removed a case.
+
+ BranchInst::Create(OnlyFeasibleSuccessor, BB);
+ TI->eraseFromParent();
+ DTU.applyUpdatesPermissive(Updates);
+ } else if (FeasibleSuccessors.size() > 1) {
+ SwitchInstProfUpdateWrapper SI(*cast<SwitchInst>(TI));
+ SmallVector<DominatorTree::UpdateType, 8> Updates;
+ for (auto CI = SI->case_begin(); CI != SI->case_end();) {
+ if (FeasibleSuccessors.contains(CI->getCaseSuccessor())) {
+ ++CI;
+ continue;
+ }
+
+ BasicBlock *Succ = CI->getCaseSuccessor();
+ Succ->removePredecessor(BB);
+ Updates.push_back({DominatorTree::Delete, BB, Succ});
+ SI.removeCase(CI);
+ // Don't increment CI, as we removed a case.
}
-
- DTU.applyUpdatesPermissive(Updates);
+
+ DTU.applyUpdatesPermissive(Updates);
} else {
- llvm_unreachable("Must have at least one feasible successor");
+ llvm_unreachable("Must have at least one feasible successor");
}
- return true;
+ return true;
}
bool llvm::runIPSCCP(
@@ -1983,12 +1983,12 @@ bool llvm::runIPSCCP(
while (ResolvedUndefs) {
LLVM_DEBUG(dbgs() << "RESOLVING UNDEFS\n");
ResolvedUndefs = false;
- for (Function &F : M) {
- if (Solver.ResolvedUndefsIn(F))
+ for (Function &F : M) {
+ if (Solver.ResolvedUndefsIn(F))
ResolvedUndefs = true;
- }
- if (ResolvedUndefs)
- Solver.Solve();
+ }
+ if (ResolvedUndefs)
+ Solver.Solve();
}
bool MadeChanges = false;
@@ -2002,35 +2002,35 @@ bool llvm::runIPSCCP(
SmallVector<BasicBlock *, 512> BlocksToErase;
- if (Solver.isBlockExecutable(&F.front())) {
- bool ReplacedPointerArg = false;
- for (Argument &Arg : F.args()) {
- if (!Arg.use_empty() && tryToReplaceWithConstant(Solver, &Arg)) {
- ReplacedPointerArg |= Arg.getType()->isPointerTy();
+ if (Solver.isBlockExecutable(&F.front())) {
+ bool ReplacedPointerArg = false;
+ for (Argument &Arg : F.args()) {
+ if (!Arg.use_empty() && tryToReplaceWithConstant(Solver, &Arg)) {
+ ReplacedPointerArg |= Arg.getType()->isPointerTy();
++IPNumArgsElimed;
}
}
- // If we replaced an argument, the argmemonly and
- // inaccessiblemem_or_argmemonly attributes do not hold any longer. Remove
- // them from both the function and callsites.
- if (ReplacedPointerArg) {
- AttrBuilder AttributesToRemove;
- AttributesToRemove.addAttribute(Attribute::ArgMemOnly);
- AttributesToRemove.addAttribute(Attribute::InaccessibleMemOrArgMemOnly);
- F.removeAttributes(AttributeList::FunctionIndex, AttributesToRemove);
-
- for (User *U : F.users()) {
- auto *CB = dyn_cast<CallBase>(U);
- if (!CB || CB->getCalledFunction() != &F)
- continue;
-
- CB->removeAttributes(AttributeList::FunctionIndex,
- AttributesToRemove);
- }
- }
- }
-
+ // If we replaced an argument, the argmemonly and
+ // inaccessiblemem_or_argmemonly attributes do not hold any longer. Remove
+ // them from both the function and callsites.
+ if (ReplacedPointerArg) {
+ AttrBuilder AttributesToRemove;
+ AttributesToRemove.addAttribute(Attribute::ArgMemOnly);
+ AttributesToRemove.addAttribute(Attribute::InaccessibleMemOrArgMemOnly);
+ F.removeAttributes(AttributeList::FunctionIndex, AttributesToRemove);
+
+ for (User *U : F.users()) {
+ auto *CB = dyn_cast<CallBase>(U);
+ if (!CB || CB->getCalledFunction() != &F)
+ continue;
+
+ CB->removeAttributes(AttributeList::FunctionIndex,
+ AttributesToRemove);
+ }
+ }
+ }
+
SmallPtrSet<Value *, 32> InsertedValues;
for (BasicBlock &BB : F) {
if (!Solver.isBlockExecutable(&BB)) {
@@ -2063,10 +2063,10 @@ bool llvm::runIPSCCP(
/*UseLLVMTrap=*/false,
/*PreserveLCSSA=*/false, &DTU);
- for (BasicBlock &BB : F)
- MadeChanges |= removeNonFeasibleEdges(Solver, &BB, DTU);
+ for (BasicBlock &BB : F)
+ MadeChanges |= removeNonFeasibleEdges(Solver, &BB, DTU);
- for (BasicBlock *DeadBB : BlocksToErase)
+ for (BasicBlock *DeadBB : BlocksToErase)
DTU.deleteBB(DeadBB);
for (BasicBlock &BB : F) {
@@ -2099,47 +2099,47 @@ bool llvm::runIPSCCP(
for (const auto &I : Solver.getTrackedRetVals()) {
Function *F = I.first;
- const ValueLatticeElement &ReturnValue = I.second;
-
- // If there is a known constant range for the return value, add !range
- // metadata to the function's call sites.
- if (ReturnValue.isConstantRange() &&
- !ReturnValue.getConstantRange().isSingleElement()) {
- // Do not add range metadata if the return value may include undef.
- if (ReturnValue.isConstantRangeIncludingUndef())
- continue;
-
- auto &CR = ReturnValue.getConstantRange();
- for (User *User : F->users()) {
- auto *CB = dyn_cast<CallBase>(User);
- if (!CB || CB->getCalledFunction() != F)
- continue;
-
- // Limit to cases where the return value is guaranteed to be neither
- // poison nor undef. Poison will be outside any range and currently
- // values outside of the specified range cause immediate undefined
- // behavior.
- if (!isGuaranteedNotToBeUndefOrPoison(CB, nullptr, CB))
- continue;
-
- // Do not touch existing metadata for now.
- // TODO: We should be able to take the intersection of the existing
- // metadata and the inferred range.
- if (CB->getMetadata(LLVMContext::MD_range))
- continue;
-
- LLVMContext &Context = CB->getParent()->getContext();
- Metadata *RangeMD[] = {
- ConstantAsMetadata::get(ConstantInt::get(Context, CR.getLower())),
- ConstantAsMetadata::get(ConstantInt::get(Context, CR.getUpper()))};
- CB->setMetadata(LLVMContext::MD_range, MDNode::get(Context, RangeMD));
- }
+ const ValueLatticeElement &ReturnValue = I.second;
+
+ // If there is a known constant range for the return value, add !range
+ // metadata to the function's call sites.
+ if (ReturnValue.isConstantRange() &&
+ !ReturnValue.getConstantRange().isSingleElement()) {
+ // Do not add range metadata if the return value may include undef.
+ if (ReturnValue.isConstantRangeIncludingUndef())
+ continue;
+
+ auto &CR = ReturnValue.getConstantRange();
+ for (User *User : F->users()) {
+ auto *CB = dyn_cast<CallBase>(User);
+ if (!CB || CB->getCalledFunction() != F)
+ continue;
+
+ // Limit to cases where the return value is guaranteed to be neither
+ // poison nor undef. Poison will be outside any range and currently
+ // values outside of the specified range cause immediate undefined
+ // behavior.
+ if (!isGuaranteedNotToBeUndefOrPoison(CB, nullptr, CB))
+ continue;
+
+ // Do not touch existing metadata for now.
+ // TODO: We should be able to take the intersection of the existing
+ // metadata and the inferred range.
+ if (CB->getMetadata(LLVMContext::MD_range))
+ continue;
+
+ LLVMContext &Context = CB->getParent()->getContext();
+ Metadata *RangeMD[] = {
+ ConstantAsMetadata::get(ConstantInt::get(Context, CR.getLower())),
+ ConstantAsMetadata::get(ConstantInt::get(Context, CR.getUpper()))};
+ CB->setMetadata(LLVMContext::MD_range, MDNode::get(Context, RangeMD));
+ }
continue;
- }
- if (F->getReturnType()->isVoidTy())
- continue;
- if (isConstant(ReturnValue) || ReturnValue.isUnknownOrUndef())
- findReturnsToZap(*F, ReturnsToZap, Solver);
+ }
+ if (F->getReturnType()->isVoidTy())
+ continue;
+ if (isConstant(ReturnValue) || ReturnValue.isUnknownOrUndef())
+ findReturnsToZap(*F, ReturnsToZap, Solver);
}
for (auto F : Solver.getMRVFunctionsTracked()) {
@@ -2151,29 +2151,29 @@ bool llvm::runIPSCCP(
}
// Zap all returns which we've identified as zap to change.
- SmallSetVector<Function *, 8> FuncZappedReturn;
+ SmallSetVector<Function *, 8> FuncZappedReturn;
for (unsigned i = 0, e = ReturnsToZap.size(); i != e; ++i) {
Function *F = ReturnsToZap[i]->getParent()->getParent();
ReturnsToZap[i]->setOperand(0, UndefValue::get(F->getReturnType()));
- // Record all functions that are zapped.
- FuncZappedReturn.insert(F);
- }
-
- // Remove the returned attribute for zapped functions and the
- // corresponding call sites.
- for (Function *F : FuncZappedReturn) {
- for (Argument &A : F->args())
- F->removeParamAttr(A.getArgNo(), Attribute::Returned);
- for (Use &U : F->uses()) {
- // Skip over blockaddr users.
- if (isa<BlockAddress>(U.getUser()))
- continue;
- CallBase *CB = cast<CallBase>(U.getUser());
- for (Use &Arg : CB->args())
- CB->removeParamAttr(CB->getArgOperandNo(&Arg), Attribute::Returned);
- }
- }
-
+ // Record all functions that are zapped.
+ FuncZappedReturn.insert(F);
+ }
+
+ // Remove the returned attribute for zapped functions and the
+ // corresponding call sites.
+ for (Function *F : FuncZappedReturn) {
+ for (Argument &A : F->args())
+ F->removeParamAttr(A.getArgNo(), Attribute::Returned);
+ for (Use &U : F->uses()) {
+ // Skip over blockaddr users.
+ if (isa<BlockAddress>(U.getUser()))
+ continue;
+ CallBase *CB = cast<CallBase>(U.getUser());
+ for (Use &Arg : CB->args())
+ CB->removeParamAttr(CB->getArgOperandNo(&Arg), Attribute::Returned);
+ }
+ }
+
// If we inferred constant or undef values for globals variables, we can
// delete the global and any stores that remain to it.
for (auto &I : make_early_inc_range(Solver.getTrackedGlobals())) {
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/SROA.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/SROA.cpp
index 587c9e89d3..af510f1a84 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/SROA.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/SROA.cpp
@@ -268,11 +268,11 @@ public:
/// Access the dead users for this alloca.
ArrayRef<Instruction *> getDeadUsers() const { return DeadUsers; }
- /// Access Uses that should be dropped if the alloca is promotable.
- ArrayRef<Use *> getDeadUsesIfPromotable() const {
- return DeadUseIfPromotable;
- }
-
+ /// Access Uses that should be dropped if the alloca is promotable.
+ ArrayRef<Use *> getDeadUsesIfPromotable() const {
+ return DeadUseIfPromotable;
+ }
+
/// Access the dead operands referring to this alloca.
///
/// These are operands which have cannot actually be used to refer to the
@@ -327,9 +327,9 @@ private:
/// they come from outside of the allocated space.
SmallVector<Instruction *, 8> DeadUsers;
- /// Uses which will become dead if can promote the alloca.
- SmallVector<Use *, 8> DeadUseIfPromotable;
-
+ /// Uses which will become dead if can promote the alloca.
+ SmallVector<Use *, 8> DeadUseIfPromotable;
+
/// Operands which will become dead if we rewrite the alloca.
///
/// These are operands that in their particular use can be replaced with
@@ -467,8 +467,8 @@ class AllocaSlices::partition_iterator
// Remove the uses which have ended in the prior partition. This
// cannot change the max split slice end because we just checked that
// the prior partition ended prior to that max.
- llvm::erase_if(P.SplitTails,
- [&](Slice *S) { return S->endOffset() <= P.EndOffset; });
+ llvm::erase_if(P.SplitTails,
+ [&](Slice *S) { return S->endOffset() <= P.EndOffset; });
assert(llvm::any_of(P.SplitTails,
[&](Slice *S) {
return S->endOffset() == MaxSplitSliceEndOffset;
@@ -784,9 +784,9 @@ private:
LI.getPointerAddressSpace() != DL.getAllocaAddrSpace())
return PI.setAborted(&LI);
- if (isa<ScalableVectorType>(LI.getType()))
- return PI.setAborted(&LI);
-
+ if (isa<ScalableVectorType>(LI.getType()))
+ return PI.setAborted(&LI);
+
uint64_t Size = DL.getTypeStoreSize(LI.getType()).getFixedSize();
return handleLoadOrStore(LI.getType(), LI, Offset, Size, LI.isVolatile());
}
@@ -802,9 +802,9 @@ private:
SI.getPointerAddressSpace() != DL.getAllocaAddrSpace())
return PI.setAborted(&SI);
- if (isa<ScalableVectorType>(ValOp->getType()))
- return PI.setAborted(&SI);
-
+ if (isa<ScalableVectorType>(ValOp->getType()))
+ return PI.setAborted(&SI);
+
uint64_t Size = DL.getTypeStoreSize(ValOp->getType()).getFixedSize();
// If this memory access can be shown to *statically* extend outside the
@@ -930,11 +930,11 @@ private:
// FIXME: What about debug intrinsics? This matches old behavior, but
// doesn't make sense.
void visitIntrinsicInst(IntrinsicInst &II) {
- if (II.isDroppable()) {
- AS.DeadUseIfPromotable.push_back(U);
- return;
- }
-
+ if (II.isDroppable()) {
+ AS.DeadUseIfPromotable.push_back(U);
+ return;
+ }
+
if (!IsOffsetKnown)
return PI.setAborted(&II);
@@ -1072,11 +1072,11 @@ AllocaSlices::AllocaSlices(const DataLayout &DL, AllocaInst &AI)
return;
}
- llvm::erase_if(Slices, [](const Slice &S) { return S.isDead(); });
+ llvm::erase_if(Slices, [](const Slice &S) { return S.isDead(); });
// Sort the uses. This arranges for the offsets to be in ascending order,
// and the sizes to be in descending order.
- llvm::stable_sort(Slices);
+ llvm::stable_sort(Slices);
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
@@ -1122,9 +1122,9 @@ LLVM_DUMP_METHOD void AllocaSlices::dump() const { print(dbgs()); }
/// Walk the range of a partitioning looking for a common type to cover this
/// sequence of slices.
-static std::pair<Type *, IntegerType *>
-findCommonType(AllocaSlices::const_iterator B, AllocaSlices::const_iterator E,
- uint64_t EndOffset) {
+static std::pair<Type *, IntegerType *>
+findCommonType(AllocaSlices::const_iterator B, AllocaSlices::const_iterator E,
+ uint64_t EndOffset) {
Type *Ty = nullptr;
bool TyIsCommon = true;
IntegerType *ITy = nullptr;
@@ -1168,7 +1168,7 @@ findCommonType(AllocaSlices::const_iterator B, AllocaSlices::const_iterator E,
Ty = UserTy;
}
- return {TyIsCommon ? Ty : nullptr, ITy};
+ return {TyIsCommon ? Ty : nullptr, ITy};
}
/// PHI instructions that use an alloca and are subsequently loaded can be
@@ -1392,8 +1392,8 @@ static void speculateSelectInstLoads(SelectInst &SI) {
/// This will return the BasePtr if that is valid, or build a new GEP
/// instruction using the IRBuilder if GEP-ing is needed.
static Value *buildGEP(IRBuilderTy &IRB, Value *BasePtr,
- SmallVectorImpl<Value *> &Indices,
- const Twine &NamePrefix) {
+ SmallVectorImpl<Value *> &Indices,
+ const Twine &NamePrefix) {
if (Indices.empty())
return BasePtr;
@@ -1418,7 +1418,7 @@ static Value *buildGEP(IRBuilderTy &IRB, Value *BasePtr,
static Value *getNaturalGEPWithType(IRBuilderTy &IRB, const DataLayout &DL,
Value *BasePtr, Type *Ty, Type *TargetTy,
SmallVectorImpl<Value *> &Indices,
- const Twine &NamePrefix) {
+ const Twine &NamePrefix) {
if (Ty == TargetTy)
return buildGEP(IRB, BasePtr, Indices, NamePrefix);
@@ -1463,7 +1463,7 @@ static Value *getNaturalGEPRecursively(IRBuilderTy &IRB, const DataLayout &DL,
Value *Ptr, Type *Ty, APInt &Offset,
Type *TargetTy,
SmallVectorImpl<Value *> &Indices,
- const Twine &NamePrefix) {
+ const Twine &NamePrefix) {
if (Offset == 0)
return getNaturalGEPWithType(IRB, DL, Ptr, Ty, TargetTy, Indices,
NamePrefix);
@@ -1538,7 +1538,7 @@ static Value *getNaturalGEPRecursively(IRBuilderTy &IRB, const DataLayout &DL,
static Value *getNaturalGEPWithOffset(IRBuilderTy &IRB, const DataLayout &DL,
Value *Ptr, APInt Offset, Type *TargetTy,
SmallVectorImpl<Value *> &Indices,
- const Twine &NamePrefix) {
+ const Twine &NamePrefix) {
PointerType *Ty = cast<PointerType>(Ptr->getType());
// Don't consider any GEPs through an i8* as natural unless the TargetTy is
@@ -1549,8 +1549,8 @@ static Value *getNaturalGEPWithOffset(IRBuilderTy &IRB, const DataLayout &DL,
Type *ElementTy = Ty->getElementType();
if (!ElementTy->isSized())
return nullptr; // We can't GEP through an unsized element.
- if (isa<ScalableVectorType>(ElementTy))
- return nullptr;
+ if (isa<ScalableVectorType>(ElementTy))
+ return nullptr;
APInt ElementSize(Offset.getBitWidth(),
DL.getTypeAllocSize(ElementTy).getFixedSize());
if (ElementSize == 0)
@@ -1579,8 +1579,8 @@ static Value *getNaturalGEPWithOffset(IRBuilderTy &IRB, const DataLayout &DL,
/// a single GEP as possible, thus making each GEP more independent of the
/// surrounding code.
static Value *getAdjustedPtr(IRBuilderTy &IRB, const DataLayout &DL, Value *Ptr,
- APInt Offset, Type *PointerTy,
- const Twine &NamePrefix) {
+ APInt Offset, Type *PointerTy,
+ const Twine &NamePrefix) {
// Even though we don't look through PHI nodes, we could be called on an
// instruction in an unreachable block, which may be on a cycle.
SmallPtrSet<Value *, 4> Visited;
@@ -1842,7 +1842,7 @@ static bool isVectorPromotionViableForSlice(Partition &P, const Slice &S,
if (!S.isSplittable())
return false; // Skip any unsplittable intrinsics.
} else if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(U->getUser())) {
- if (!II->isLifetimeStartOrEnd() && !II->isDroppable())
+ if (!II->isLifetimeStartOrEnd() && !II->isDroppable())
return false;
} else if (U->get()->getType()->getPointerElementType()->isStructTy()) {
// Disable vector promotion when there are loads or stores of an FCA.
@@ -1926,9 +1926,9 @@ static VectorType *isVectorPromotionViable(Partition &P, const DataLayout &DL) {
// do that until all the backends are known to produce good code for all
// integer vector types.
if (!HaveCommonEltTy) {
- llvm::erase_if(CandidateTys, [](VectorType *VTy) {
- return !VTy->getElementType()->isIntegerTy();
- });
+ llvm::erase_if(CandidateTys, [](VectorType *VTy) {
+ return !VTy->getElementType()->isIntegerTy();
+ });
// If there were no integer vector types, give up.
if (CandidateTys.empty())
@@ -2072,7 +2072,7 @@ static bool isIntegerWideningViableForSlice(const Slice &S,
if (!S.isSplittable())
return false; // Skip any unsplittable intrinsics.
} else if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(U->getUser())) {
- if (!II->isLifetimeStartOrEnd() && !II->isDroppable())
+ if (!II->isLifetimeStartOrEnd() && !II->isDroppable())
return false;
} else {
return false;
@@ -2113,7 +2113,7 @@ static bool isIntegerWideningViable(Partition &P, Type *AllocaTy,
// that we cover the alloca.
// FIXME: We shouldn't consider split slices that happen to start in the
// partition here...
- bool WholeAllocaOp = P.empty() && DL.isLegalInteger(SizeInBits);
+ bool WholeAllocaOp = P.empty() && DL.isLegalInteger(SizeInBits);
for (const Slice &S : P)
if (!isIntegerWideningViableForSlice(S, P.beginOffset(), AllocaTy, DL,
@@ -2206,7 +2206,7 @@ static Value *extractVector(IRBuilderTy &IRB, Value *V, unsigned BeginIndex,
Mask.reserve(NumElements);
for (unsigned i = BeginIndex; i != EndIndex; ++i)
Mask.push_back(i);
- V = IRB.CreateShuffleVector(V, Mask, Name + ".extract");
+ V = IRB.CreateShuffleVector(V, Mask, Name + ".extract");
LLVM_DEBUG(dbgs() << " shuffle: " << *V << "\n");
return V;
}
@@ -2239,22 +2239,22 @@ static Value *insertVector(IRBuilderTy &IRB, Value *Old, Value *V,
// use a shuffle vector to widen it with undef elements, and then
// a second shuffle vector to select between the loaded vector and the
// incoming vector.
- SmallVector<int, 8> Mask;
+ SmallVector<int, 8> Mask;
Mask.reserve(cast<FixedVectorType>(VecTy)->getNumElements());
for (unsigned i = 0; i != cast<FixedVectorType>(VecTy)->getNumElements(); ++i)
if (i >= BeginIndex && i < EndIndex)
- Mask.push_back(i - BeginIndex);
+ Mask.push_back(i - BeginIndex);
else
- Mask.push_back(-1);
- V = IRB.CreateShuffleVector(V, Mask, Name + ".expand");
+ Mask.push_back(-1);
+ V = IRB.CreateShuffleVector(V, Mask, Name + ".expand");
LLVM_DEBUG(dbgs() << " shuffle: " << *V << "\n");
- SmallVector<Constant *, 8> Mask2;
- Mask2.reserve(cast<FixedVectorType>(VecTy)->getNumElements());
+ SmallVector<Constant *, 8> Mask2;
+ Mask2.reserve(cast<FixedVectorType>(VecTy)->getNumElements());
for (unsigned i = 0; i != cast<FixedVectorType>(VecTy)->getNumElements(); ++i)
- Mask2.push_back(IRB.getInt1(i >= BeginIndex && i < EndIndex));
+ Mask2.push_back(IRB.getInt1(i >= BeginIndex && i < EndIndex));
- V = IRB.CreateSelect(ConstantVector::get(Mask2), V, Old, Name + "blend");
+ V = IRB.CreateSelect(ConstantVector::get(Mask2), V, Old, Name + "blend");
LLVM_DEBUG(dbgs() << " blend: " << *V << "\n");
return V;
@@ -2458,7 +2458,7 @@ private:
void deleteIfTriviallyDead(Value *V) {
Instruction *I = cast<Instruction>(V);
if (isInstructionTriviallyDead(I))
- Pass.DeadInsts.push_back(I);
+ Pass.DeadInsts.push_back(I);
}
Value *rewriteVectorizedLoadInst() {
@@ -2524,7 +2524,7 @@ private:
NewAI.getAlign(), LI.isVolatile(),
LI.getName());
if (AATags)
- NewLI->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
+ NewLI->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
if (LI.isVolatile())
NewLI->setAtomic(LI.getOrdering(), LI.getSyncScopeID());
if (NewLI->isAtomic())
@@ -2563,7 +2563,7 @@ private:
IRB.CreateAlignedLoad(TargetTy, getNewAllocaSlicePtr(IRB, LTy),
getSliceAlign(), LI.isVolatile(), LI.getName());
if (AATags)
- NewLI->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
+ NewLI->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
if (LI.isVolatile())
NewLI->setAtomic(LI.getOrdering(), LI.getSyncScopeID());
@@ -2598,7 +2598,7 @@ private:
LI.replaceAllUsesWith(V);
}
- Pass.DeadInsts.push_back(&LI);
+ Pass.DeadInsts.push_back(&LI);
deleteIfTriviallyDead(OldOp);
LLVM_DEBUG(dbgs() << " to: " << *V << "\n");
return !LI.isVolatile() && !IsPtrAdjusted;
@@ -2626,8 +2626,8 @@ private:
}
StoreInst *Store = IRB.CreateAlignedStore(V, &NewAI, NewAI.getAlign());
if (AATags)
- Store->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
- Pass.DeadInsts.push_back(&SI);
+ Store->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
+ Pass.DeadInsts.push_back(&SI);
LLVM_DEBUG(dbgs() << " to: " << *Store << "\n");
return true;
@@ -2650,8 +2650,8 @@ private:
Store->copyMetadata(SI, {LLVMContext::MD_mem_parallel_loop_access,
LLVMContext::MD_access_group});
if (AATags)
- Store->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
- Pass.DeadInsts.push_back(&SI);
+ Store->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
+ Pass.DeadInsts.push_back(&SI);
LLVM_DEBUG(dbgs() << " to: " << *Store << "\n");
return true;
}
@@ -2720,12 +2720,12 @@ private:
NewSI->copyMetadata(SI, {LLVMContext::MD_mem_parallel_loop_access,
LLVMContext::MD_access_group});
if (AATags)
- NewSI->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
+ NewSI->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
if (SI.isVolatile())
NewSI->setAtomic(SI.getOrdering(), SI.getSyncScopeID());
if (NewSI->isAtomic())
NewSI->setAlignment(SI.getAlign());
- Pass.DeadInsts.push_back(&SI);
+ Pass.DeadInsts.push_back(&SI);
deleteIfTriviallyDead(OldOp);
LLVM_DEBUG(dbgs() << " to: " << *NewSI << "\n");
@@ -2786,11 +2786,11 @@ private:
}
// Record this instruction for deletion.
- Pass.DeadInsts.push_back(&II);
+ Pass.DeadInsts.push_back(&II);
Type *AllocaTy = NewAI.getAllocatedType();
Type *ScalarTy = AllocaTy->getScalarType();
-
+
const bool CanContinue = [&]() {
if (VecTy || IntTy)
return true;
@@ -2816,7 +2816,7 @@ private:
getNewAllocaSlicePtr(IRB, OldPtr->getType()), II.getValue(), Size,
MaybeAlign(getSliceAlign()), II.isVolatile());
if (AATags)
- New->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
+ New->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
LLVM_DEBUG(dbgs() << " to: " << *New << "\n");
return false;
}
@@ -2885,7 +2885,7 @@ private:
StoreInst *New =
IRB.CreateAlignedStore(V, &NewAI, NewAI.getAlign(), II.isVolatile());
if (AATags)
- New->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
+ New->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
LLVM_DEBUG(dbgs() << " to: " << *New << "\n");
return !II.isVolatile();
}
@@ -2956,7 +2956,7 @@ private:
return false;
}
// Record this instruction for deletion.
- Pass.DeadInsts.push_back(&II);
+ Pass.DeadInsts.push_back(&II);
// Strip all inbounds GEPs and pointer casts to try to dig out any root
// alloca that should be re-examined after rewriting this instruction.
@@ -3006,7 +3006,7 @@ private:
CallInst *New = IRB.CreateMemCpy(DestPtr, DestAlign, SrcPtr, SrcAlign,
Size, II.isVolatile());
if (AATags)
- New->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
+ New->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
LLVM_DEBUG(dbgs() << " to: " << *New << "\n");
return false;
}
@@ -3060,7 +3060,7 @@ private:
LoadInst *Load = IRB.CreateAlignedLoad(OtherTy, SrcPtr, SrcAlign,
II.isVolatile(), "copyload");
if (AATags)
- Load->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
+ Load->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
Src = Load;
}
@@ -3080,27 +3080,27 @@ private:
StoreInst *Store = cast<StoreInst>(
IRB.CreateAlignedStore(Src, DstPtr, DstAlign, II.isVolatile()));
if (AATags)
- Store->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
+ Store->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset));
LLVM_DEBUG(dbgs() << " to: " << *Store << "\n");
return !II.isVolatile();
}
bool visitIntrinsicInst(IntrinsicInst &II) {
- assert((II.isLifetimeStartOrEnd() || II.isDroppable()) &&
- "Unexpected intrinsic!");
+ assert((II.isLifetimeStartOrEnd() || II.isDroppable()) &&
+ "Unexpected intrinsic!");
LLVM_DEBUG(dbgs() << " original: " << II << "\n");
// Record this instruction for deletion.
- Pass.DeadInsts.push_back(&II);
-
- if (II.isDroppable()) {
- assert(II.getIntrinsicID() == Intrinsic::assume && "Expected assume");
- // TODO For now we forget assumed information, this can be improved.
- OldPtr->dropDroppableUsesIn(II);
- return true;
- }
-
- assert(II.getArgOperand(1) == OldPtr);
+ Pass.DeadInsts.push_back(&II);
+
+ if (II.isDroppable()) {
+ assert(II.getIntrinsicID() == Intrinsic::assume && "Expected assume");
+ // TODO For now we forget assumed information, this can be improved.
+ OldPtr->dropDroppableUsesIn(II);
+ return true;
+ }
+
+ assert(II.getArgOperand(1) == OldPtr);
// Lifetime intrinsics are only promotable if they cover the whole alloca.
// Therefore, we drop lifetime intrinsics which don't cover the whole
// alloca.
@@ -3381,13 +3381,13 @@ private:
IRB.CreateInBoundsGEP(BaseTy, Ptr, GEPIndices, Name + ".gep");
LoadInst *Load =
IRB.CreateAlignedLoad(Ty, GEP, Alignment, Name + ".load");
-
- APInt Offset(
- DL.getIndexSizeInBits(Ptr->getType()->getPointerAddressSpace()), 0);
- if (AATags &&
- GEPOperator::accumulateConstantOffset(BaseTy, GEPIndices, DL, Offset))
- Load->setAAMetadata(AATags.shift(Offset.getZExtValue()));
-
+
+ APInt Offset(
+ DL.getIndexSizeInBits(Ptr->getType()->getPointerAddressSpace()), 0);
+ if (AATags &&
+ GEPOperator::accumulateConstantOffset(BaseTy, GEPIndices, DL, Offset))
+ Load->setAAMetadata(AATags.shift(Offset.getZExtValue()));
+
Agg = IRB.CreateInsertValue(Agg, Load, Indices, Name + ".insert");
LLVM_DEBUG(dbgs() << " to: " << *Load << "\n");
}
@@ -3433,13 +3433,13 @@ private:
IRB.CreateInBoundsGEP(BaseTy, Ptr, GEPIndices, Name + ".gep");
StoreInst *Store =
IRB.CreateAlignedStore(ExtractValue, InBoundsGEP, Alignment);
-
- APInt Offset(
- DL.getIndexSizeInBits(Ptr->getType()->getPointerAddressSpace()), 0);
- if (AATags &&
- GEPOperator::accumulateConstantOffset(BaseTy, GEPIndices, DL, Offset))
- Store->setAAMetadata(AATags.shift(Offset.getZExtValue()));
-
+
+ APInt Offset(
+ DL.getIndexSizeInBits(Ptr->getType()->getPointerAddressSpace()), 0);
+ if (AATags &&
+ GEPOperator::accumulateConstantOffset(BaseTy, GEPIndices, DL, Offset))
+ Store->setAAMetadata(AATags.shift(Offset.getZExtValue()));
+
LLVM_DEBUG(dbgs() << " to: " << *Store << "\n");
}
};
@@ -3485,7 +3485,7 @@ private:
<< "\n " << GEPI);
IRBuilderTy Builder(&GEPI);
- SmallVector<Value *, 4> Index(GEPI.indices());
+ SmallVector<Value *, 4> Index(GEPI.indices());
bool IsInBounds = GEPI.isInBounds();
Value *True = Sel->getTrueValue();
@@ -3539,27 +3539,27 @@ private:
<< "\n " << GEPI
<< "\n to: ");
- SmallVector<Value *, 4> Index(GEPI.indices());
+ SmallVector<Value *, 4> Index(GEPI.indices());
bool IsInBounds = GEPI.isInBounds();
IRBuilderTy PHIBuilder(GEPI.getParent()->getFirstNonPHI());
PHINode *NewPN = PHIBuilder.CreatePHI(GEPI.getType(),
PHI->getNumIncomingValues(),
PHI->getName() + ".sroa.phi");
for (unsigned I = 0, E = PHI->getNumIncomingValues(); I != E; ++I) {
- BasicBlock *B = PHI->getIncomingBlock(I);
- Value *NewVal = nullptr;
- int Idx = NewPN->getBasicBlockIndex(B);
- if (Idx >= 0) {
- NewVal = NewPN->getIncomingValue(Idx);
- } else {
- Instruction *In = cast<Instruction>(PHI->getIncomingValue(I));
-
- IRBuilderTy B(In->getParent(), std::next(In->getIterator()));
- NewVal = IsInBounds
- ? B.CreateInBoundsGEP(In, Index, In->getName() + ".sroa.gep")
- : B.CreateGEP(In, Index, In->getName() + ".sroa.gep");
- }
- NewPN->addIncoming(NewVal, B);
+ BasicBlock *B = PHI->getIncomingBlock(I);
+ Value *NewVal = nullptr;
+ int Idx = NewPN->getBasicBlockIndex(B);
+ if (Idx >= 0) {
+ NewVal = NewPN->getIncomingValue(Idx);
+ } else {
+ Instruction *In = cast<Instruction>(PHI->getIncomingValue(I));
+
+ IRBuilderTy B(In->getParent(), std::next(In->getIterator()));
+ NewVal = IsInBounds
+ ? B.CreateInBoundsGEP(In, Index, In->getName() + ".sroa.gep")
+ : B.CreateGEP(In, Index, In->getName() + ".sroa.gep");
+ }
+ NewPN->addIncoming(NewVal, B);
}
Visited.erase(&GEPI);
@@ -3901,53 +3901,53 @@ bool SROA::presplitLoadsAndStores(AllocaInst &AI, AllocaSlices &AS) {
// such loads and stores, we can only pre-split them if their splits exactly
// match relative to their starting offset. We have to verify this prior to
// any rewriting.
- llvm::erase_if(Stores, [&UnsplittableLoads, &SplitOffsetsMap](StoreInst *SI) {
- // Lookup the load we are storing in our map of split
- // offsets.
- auto *LI = cast<LoadInst>(SI->getValueOperand());
- // If it was completely unsplittable, then we're done,
- // and this store can't be pre-split.
- if (UnsplittableLoads.count(LI))
- return true;
-
- auto LoadOffsetsI = SplitOffsetsMap.find(LI);
- if (LoadOffsetsI == SplitOffsetsMap.end())
- return false; // Unrelated loads are definitely safe.
- auto &LoadOffsets = LoadOffsetsI->second;
-
- // Now lookup the store's offsets.
- auto &StoreOffsets = SplitOffsetsMap[SI];
-
- // If the relative offsets of each split in the load and
- // store match exactly, then we can split them and we
- // don't need to remove them here.
- if (LoadOffsets.Splits == StoreOffsets.Splits)
- return false;
-
- LLVM_DEBUG(dbgs() << " Mismatched splits for load and store:\n"
- << " " << *LI << "\n"
- << " " << *SI << "\n");
-
- // We've found a store and load that we need to split
- // with mismatched relative splits. Just give up on them
- // and remove both instructions from our list of
- // candidates.
- UnsplittableLoads.insert(LI);
- return true;
- });
+ llvm::erase_if(Stores, [&UnsplittableLoads, &SplitOffsetsMap](StoreInst *SI) {
+ // Lookup the load we are storing in our map of split
+ // offsets.
+ auto *LI = cast<LoadInst>(SI->getValueOperand());
+ // If it was completely unsplittable, then we're done,
+ // and this store can't be pre-split.
+ if (UnsplittableLoads.count(LI))
+ return true;
+
+ auto LoadOffsetsI = SplitOffsetsMap.find(LI);
+ if (LoadOffsetsI == SplitOffsetsMap.end())
+ return false; // Unrelated loads are definitely safe.
+ auto &LoadOffsets = LoadOffsetsI->second;
+
+ // Now lookup the store's offsets.
+ auto &StoreOffsets = SplitOffsetsMap[SI];
+
+ // If the relative offsets of each split in the load and
+ // store match exactly, then we can split them and we
+ // don't need to remove them here.
+ if (LoadOffsets.Splits == StoreOffsets.Splits)
+ return false;
+
+ LLVM_DEBUG(dbgs() << " Mismatched splits for load and store:\n"
+ << " " << *LI << "\n"
+ << " " << *SI << "\n");
+
+ // We've found a store and load that we need to split
+ // with mismatched relative splits. Just give up on them
+ // and remove both instructions from our list of
+ // candidates.
+ UnsplittableLoads.insert(LI);
+ return true;
+ });
// Now we have to go *back* through all the stores, because a later store may
// have caused an earlier store's load to become unsplittable and if it is
// unsplittable for the later store, then we can't rely on it being split in
// the earlier store either.
- llvm::erase_if(Stores, [&UnsplittableLoads](StoreInst *SI) {
- auto *LI = cast<LoadInst>(SI->getValueOperand());
- return UnsplittableLoads.count(LI);
- });
+ llvm::erase_if(Stores, [&UnsplittableLoads](StoreInst *SI) {
+ auto *LI = cast<LoadInst>(SI->getValueOperand());
+ return UnsplittableLoads.count(LI);
+ });
// Once we've established all the loads that can't be split for some reason,
// filter any that made it into our list out.
- llvm::erase_if(Loads, [&UnsplittableLoads](LoadInst *LI) {
- return UnsplittableLoads.count(LI);
- });
+ llvm::erase_if(Loads, [&UnsplittableLoads](LoadInst *LI) {
+ return UnsplittableLoads.count(LI);
+ });
// If no loads or stores are left, there is no pre-splitting to be done for
// this alloca.
@@ -4084,7 +4084,7 @@ bool SROA::presplitLoadsAndStores(AllocaInst &AI, AllocaSlices &AS) {
}
// Mark the original store as dead.
- DeadInsts.push_back(SI);
+ DeadInsts.push_back(SI);
}
// Save the split loads if there are deferred stores among the users.
@@ -4092,7 +4092,7 @@ bool SROA::presplitLoadsAndStores(AllocaInst &AI, AllocaSlices &AS) {
SplitLoadsMap.insert(std::make_pair(LI, std::move(SplitLoads)));
// Mark the original load as dead and kill the original slice.
- DeadInsts.push_back(LI);
+ DeadInsts.push_back(LI);
Offsets.S->kill();
}
@@ -4214,14 +4214,14 @@ bool SROA::presplitLoadsAndStores(AllocaInst &AI, AllocaSlices &AS) {
// trivial CSE, including instcombine.
if (LI->hasOneUse()) {
assert(*LI->user_begin() == SI && "Single use isn't this store!");
- DeadInsts.push_back(LI);
+ DeadInsts.push_back(LI);
}
- DeadInsts.push_back(SI);
+ DeadInsts.push_back(SI);
Offsets.S->kill();
}
// Remove the killed slices that have ben pre-split.
- llvm::erase_if(AS, [](const Slice &S) { return S.isDead(); });
+ llvm::erase_if(AS, [](const Slice &S) { return S.isDead(); });
// Insert our new slices. This will sort and merge them into the sorted
// sequence.
@@ -4235,9 +4235,9 @@ bool SROA::presplitLoadsAndStores(AllocaInst &AI, AllocaSlices &AS) {
// Finally, don't try to promote any allocas that new require re-splitting.
// They have already been added to the worklist above.
- llvm::erase_if(PromotableAllocas, [&](AllocaInst *AI) {
- return ResplitPromotableAllocas.count(AI);
- });
+ llvm::erase_if(PromotableAllocas, [&](AllocaInst *AI) {
+ return ResplitPromotableAllocas.count(AI);
+ });
return true;
}
@@ -4259,21 +4259,21 @@ AllocaInst *SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS,
// or an i8 array of an appropriate size.
Type *SliceTy = nullptr;
const DataLayout &DL = AI.getModule()->getDataLayout();
- std::pair<Type *, IntegerType *> CommonUseTy =
- findCommonType(P.begin(), P.end(), P.endOffset());
- // Do all uses operate on the same type?
- if (CommonUseTy.first)
- if (DL.getTypeAllocSize(CommonUseTy.first).getFixedSize() >= P.size())
- SliceTy = CommonUseTy.first;
- // If not, can we find an appropriate subtype in the original allocated type?
+ std::pair<Type *, IntegerType *> CommonUseTy =
+ findCommonType(P.begin(), P.end(), P.endOffset());
+ // Do all uses operate on the same type?
+ if (CommonUseTy.first)
+ if (DL.getTypeAllocSize(CommonUseTy.first).getFixedSize() >= P.size())
+ SliceTy = CommonUseTy.first;
+ // If not, can we find an appropriate subtype in the original allocated type?
if (!SliceTy)
if (Type *TypePartitionTy = getTypePartition(DL, AI.getAllocatedType(),
P.beginOffset(), P.size()))
SliceTy = TypePartitionTy;
- // If still not, can we use the largest bitwidth integer type used?
- if (!SliceTy && CommonUseTy.second)
- if (DL.getTypeAllocSize(CommonUseTy.second).getFixedSize() >= P.size())
- SliceTy = CommonUseTy.second;
+ // If still not, can we use the largest bitwidth integer type used?
+ if (!SliceTy && CommonUseTy.second)
+ if (DL.getTypeAllocSize(CommonUseTy.second).getFixedSize() >= P.size())
+ SliceTy = CommonUseTy.second;
if ((!SliceTy || (SliceTy->isArrayTy() &&
SliceTy->getArrayElementType()->isIntegerTy())) &&
DL.isLegalInteger(P.size() * 8))
@@ -4363,13 +4363,13 @@ AllocaInst *SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS,
}
if (Promotable) {
- for (Use *U : AS.getDeadUsesIfPromotable()) {
- auto *OldInst = dyn_cast<Instruction>(U->get());
- Value::dropDroppableUse(*U);
- if (OldInst)
- if (isInstructionTriviallyDead(OldInst))
- DeadInsts.push_back(OldInst);
- }
+ for (Use *U : AS.getDeadUsesIfPromotable()) {
+ auto *OldInst = dyn_cast<Instruction>(U->get());
+ Value::dropDroppableUse(*U);
+ if (OldInst)
+ if (isInstructionTriviallyDead(OldInst))
+ DeadInsts.push_back(OldInst);
+ }
if (PHIUsers.empty() && SelectUsers.empty()) {
// Promote the alloca.
PromotableAllocas.push_back(NewAI);
@@ -4504,8 +4504,8 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
// Migrate debug information from the old alloca to the new alloca(s)
// and the individual partitions.
TinyPtrVector<DbgVariableIntrinsic *> DbgDeclares = FindDbgAddrUses(&AI);
- for (DbgVariableIntrinsic *DbgDeclare : DbgDeclares) {
- auto *Expr = DbgDeclare->getExpression();
+ for (DbgVariableIntrinsic *DbgDeclare : DbgDeclares) {
+ auto *Expr = DbgDeclare->getExpression();
DIBuilder DIB(*AI.getModule(), /*AllowUnresolved*/ false);
uint64_t AllocaSize =
DL.getTypeSizeInBits(AI.getAllocatedType()).getFixedSize();
@@ -4536,7 +4536,7 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
}
// The alloca may be larger than the variable.
- auto VarSize = DbgDeclare->getVariable()->getSizeInBits();
+ auto VarSize = DbgDeclare->getVariable()->getSizeInBits();
if (VarSize) {
if (Size > *VarSize)
Size = *VarSize;
@@ -4554,21 +4554,21 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
}
}
- // Remove any existing intrinsics on the new alloca describing
- // the variable fragment.
- for (DbgVariableIntrinsic *OldDII : FindDbgAddrUses(Fragment.Alloca)) {
- auto SameVariableFragment = [](const DbgVariableIntrinsic *LHS,
- const DbgVariableIntrinsic *RHS) {
- return LHS->getVariable() == RHS->getVariable() &&
- LHS->getDebugLoc()->getInlinedAt() ==
- RHS->getDebugLoc()->getInlinedAt();
- };
- if (SameVariableFragment(OldDII, DbgDeclare))
- OldDII->eraseFromParent();
- }
-
- DIB.insertDeclare(Fragment.Alloca, DbgDeclare->getVariable(), FragmentExpr,
- DbgDeclare->getDebugLoc(), &AI);
+ // Remove any existing intrinsics on the new alloca describing
+ // the variable fragment.
+ for (DbgVariableIntrinsic *OldDII : FindDbgAddrUses(Fragment.Alloca)) {
+ auto SameVariableFragment = [](const DbgVariableIntrinsic *LHS,
+ const DbgVariableIntrinsic *RHS) {
+ return LHS->getVariable() == RHS->getVariable() &&
+ LHS->getDebugLoc()->getInlinedAt() ==
+ RHS->getDebugLoc()->getInlinedAt();
+ };
+ if (SameVariableFragment(OldDII, DbgDeclare))
+ OldDII->eraseFromParent();
+ }
+
+ DIB.insertDeclare(Fragment.Alloca, DbgDeclare->getVariable(), FragmentExpr,
+ DbgDeclare->getDebugLoc(), &AI);
}
}
return Changed;
@@ -4585,7 +4585,7 @@ void SROA::clobberUse(Use &U) {
// minimal.
if (Instruction *OldI = dyn_cast<Instruction>(OldV))
if (isInstructionTriviallyDead(OldI)) {
- DeadInsts.push_back(OldI);
+ DeadInsts.push_back(OldI);
}
}
@@ -4634,7 +4634,7 @@ bool SROA::runOnAlloca(AllocaInst &AI) {
DeadUser->replaceAllUsesWith(UndefValue::get(DeadUser->getType()));
// And mark it for deletion.
- DeadInsts.push_back(DeadUser);
+ DeadInsts.push_back(DeadUser);
Changed = true;
}
for (Use *DeadOp : AS.getDeadOperands()) {
@@ -4672,8 +4672,8 @@ bool SROA::deleteDeadInstructions(
SmallPtrSetImpl<AllocaInst *> &DeletedAllocas) {
bool Changed = false;
while (!DeadInsts.empty()) {
- Instruction *I = dyn_cast_or_null<Instruction>(DeadInsts.pop_back_val());
- if (!I) continue;
+ Instruction *I = dyn_cast_or_null<Instruction>(DeadInsts.pop_back_val());
+ if (!I) continue;
LLVM_DEBUG(dbgs() << "Deleting dead instruction: " << *I << "\n");
// If the instruction is an alloca, find the possible dbg.declare connected
@@ -4692,7 +4692,7 @@ bool SROA::deleteDeadInstructions(
// Zero out the operand and see if it becomes trivially dead.
Operand = nullptr;
if (isInstructionTriviallyDead(U))
- DeadInsts.push_back(U);
+ DeadInsts.push_back(U);
}
++NumDeleted;
@@ -4755,7 +4755,7 @@ PreservedAnalyses SROA::runImpl(Function &F, DominatorTree &RunDT,
auto IsInSet = [&](AllocaInst *AI) { return DeletedAllocas.count(AI); };
Worklist.remove_if(IsInSet);
PostPromotionWorklist.remove_if(IsInSet);
- llvm::erase_if(PromotableAllocas, IsInSet);
+ llvm::erase_if(PromotableAllocas, IsInSet);
DeletedAllocas.clear();
}
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/Scalar.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/Scalar.cpp
index c897888295..dba3dba24e 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/Scalar.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/Scalar.cpp
@@ -34,12 +34,12 @@ using namespace llvm;
/// ScalarOpts library.
void llvm::initializeScalarOpts(PassRegistry &Registry) {
initializeADCELegacyPassPass(Registry);
- initializeAnnotationRemarksLegacyPass(Registry);
+ initializeAnnotationRemarksLegacyPass(Registry);
initializeBDCELegacyPassPass(Registry);
initializeAlignmentFromAssumptionsPass(Registry);
initializeCallSiteSplittingLegacyPassPass(Registry);
initializeConstantHoistingLegacyPassPass(Registry);
- initializeConstraintEliminationPass(Registry);
+ initializeConstraintEliminationPass(Registry);
initializeCorrelatedValuePropagationPass(Registry);
initializeDCELegacyPassPass(Registry);
initializeDivRemPairsLegacyPassPass(Registry);
@@ -67,24 +67,24 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) {
initializeLoopDeletionLegacyPassPass(Registry);
initializeLoopAccessLegacyAnalysisPass(Registry);
initializeLoopInstSimplifyLegacyPassPass(Registry);
- initializeLoopInterchangeLegacyPassPass(Registry);
- initializeLoopFlattenLegacyPassPass(Registry);
+ initializeLoopInterchangeLegacyPassPass(Registry);
+ initializeLoopFlattenLegacyPassPass(Registry);
initializeLoopPredicationLegacyPassPass(Registry);
initializeLoopRotateLegacyPassPass(Registry);
initializeLoopStrengthReducePass(Registry);
- initializeLoopRerollLegacyPassPass(Registry);
+ initializeLoopRerollLegacyPassPass(Registry);
initializeLoopUnrollPass(Registry);
initializeLoopUnrollAndJamPass(Registry);
initializeLoopUnswitchPass(Registry);
initializeWarnMissedTransformationsLegacyPass(Registry);
- initializeLoopVersioningLICMLegacyPassPass(Registry);
+ initializeLoopVersioningLICMLegacyPassPass(Registry);
initializeLoopIdiomRecognizeLegacyPassPass(Registry);
initializeLowerAtomicLegacyPassPass(Registry);
initializeLowerConstantIntrinsicsPass(Registry);
initializeLowerExpectIntrinsicPass(Registry);
initializeLowerGuardIntrinsicLegacyPassPass(Registry);
initializeLowerMatrixIntrinsicsLegacyPassPass(Registry);
- initializeLowerMatrixIntrinsicsMinimalLegacyPassPass(Registry);
+ initializeLowerMatrixIntrinsicsMinimalLegacyPassPass(Registry);
initializeLowerWidenableConditionLegacyPassPass(Registry);
initializeMemCpyOptLegacyPassPass(Registry);
initializeMergeICmpsLegacyPassPass(Registry);
@@ -93,26 +93,26 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) {
initializePartiallyInlineLibCallsLegacyPassPass(Registry);
initializeReassociateLegacyPassPass(Registry);
initializeRedundantDbgInstEliminationPass(Registry);
- initializeRegToMemLegacyPass(Registry);
+ initializeRegToMemLegacyPass(Registry);
initializeRewriteStatepointsForGCLegacyPassPass(Registry);
- initializeScalarizeMaskedMemIntrinLegacyPassPass(Registry);
+ initializeScalarizeMaskedMemIntrinLegacyPassPass(Registry);
initializeSCCPLegacyPassPass(Registry);
initializeSROALegacyPassPass(Registry);
initializeCFGSimplifyPassPass(Registry);
- initializeStructurizeCFGLegacyPassPass(Registry);
+ initializeStructurizeCFGLegacyPassPass(Registry);
initializeSimpleLoopUnswitchLegacyPassPass(Registry);
initializeSinkingLegacyPassPass(Registry);
initializeTailCallElimPass(Registry);
- initializeSeparateConstOffsetFromGEPLegacyPassPass(Registry);
+ initializeSeparateConstOffsetFromGEPLegacyPassPass(Registry);
initializeSpeculativeExecutionLegacyPassPass(Registry);
- initializeStraightLineStrengthReduceLegacyPassPass(Registry);
+ initializeStraightLineStrengthReduceLegacyPassPass(Registry);
initializePlaceBackedgeSafepointsImplPass(Registry);
initializePlaceSafepointsPass(Registry);
initializeFloat2IntLegacyPassPass(Registry);
initializeLoopDistributeLegacyPass(Registry);
initializeLoopLoadEliminationPass(Registry);
initializeLoopSimplifyCFGLegacyPassPass(Registry);
- initializeLoopVersioningLegacyPassPass(Registry);
+ initializeLoopVersioningLegacyPassPass(Registry);
initializeEntryExitInstrumenterPass(Registry);
initializePostInlineEntryExitInstrumenterPass(Registry);
}
@@ -142,7 +142,7 @@ void LLVMAddAlignmentFromAssumptionsPass(LLVMPassManagerRef PM) {
}
void LLVMAddCFGSimplificationPass(LLVMPassManagerRef PM) {
- unwrap(PM)->add(createCFGSimplificationPass());
+ unwrap(PM)->add(createCFGSimplificationPass());
}
void LLVMAddDeadStoreEliminationPass(LLVMPassManagerRef PM) {
@@ -169,10 +169,10 @@ void LLVMAddIndVarSimplifyPass(LLVMPassManagerRef PM) {
unwrap(PM)->add(createIndVarSimplifyPass());
}
-void LLVMAddInstructionSimplifyPass(LLVMPassManagerRef PM) {
- unwrap(PM)->add(createInstSimplifyLegacyPass());
-}
-
+void LLVMAddInstructionSimplifyPass(LLVMPassManagerRef PM) {
+ unwrap(PM)->add(createInstSimplifyLegacyPass());
+}
+
void LLVMAddJumpThreadingPass(LLVMPassManagerRef PM) {
unwrap(PM)->add(createJumpThreadingPass());
}
@@ -189,10 +189,10 @@ void LLVMAddLoopDeletionPass(LLVMPassManagerRef PM) {
unwrap(PM)->add(createLoopDeletionPass());
}
-void LLVMAddLoopFlattenPass(LLVMPassManagerRef PM) {
- unwrap(PM)->add(createLoopFlattenPass());
-}
-
+void LLVMAddLoopFlattenPass(LLVMPassManagerRef PM) {
+ unwrap(PM)->add(createLoopFlattenPass());
+}
+
void LLVMAddLoopIdiomPass(LLVMPassManagerRef PM) {
unwrap(PM)->add(createLoopIdiomPass());
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/ScalarizeMaskedMemIntrin.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/ScalarizeMaskedMemIntrin.cpp
index c8da464a3b..afa2d1bc79 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/ScalarizeMaskedMemIntrin.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/ScalarizeMaskedMemIntrin.cpp
@@ -1,948 +1,948 @@
-//===- ScalarizeMaskedMemIntrin.cpp - Scalarize unsupported masked mem ----===//
-// instrinsics
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass replaces masked memory intrinsics - when unsupported by the target
-// - with a chain of basic blocks, that deal with the elements one-by-one if the
-// appropriate mask bit is set.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Constant.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/InstrTypes.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/Intrinsics.h"
-#include "llvm/IR/Type.h"
-#include "llvm/IR/Value.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Transforms/Scalar.h"
-#include <algorithm>
-#include <cassert>
-
-using namespace llvm;
-
-#define DEBUG_TYPE "scalarize-masked-mem-intrin"
-
-namespace {
-
-class ScalarizeMaskedMemIntrinLegacyPass : public FunctionPass {
-public:
- static char ID; // Pass identification, replacement for typeid
-
- explicit ScalarizeMaskedMemIntrinLegacyPass() : FunctionPass(ID) {
- initializeScalarizeMaskedMemIntrinLegacyPassPass(
- *PassRegistry::getPassRegistry());
- }
-
- bool runOnFunction(Function &F) override;
-
- StringRef getPassName() const override {
- return "Scalarize Masked Memory Intrinsics";
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<TargetTransformInfoWrapperPass>();
- }
-};
-
-} // end anonymous namespace
-
-static bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT,
- const TargetTransformInfo &TTI, const DataLayout &DL);
-static bool optimizeCallInst(CallInst *CI, bool &ModifiedDT,
- const TargetTransformInfo &TTI,
- const DataLayout &DL);
-
-char ScalarizeMaskedMemIntrinLegacyPass::ID = 0;
-
-INITIALIZE_PASS_BEGIN(ScalarizeMaskedMemIntrinLegacyPass, DEBUG_TYPE,
- "Scalarize unsupported masked memory intrinsics", false,
- false)
-INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
-INITIALIZE_PASS_END(ScalarizeMaskedMemIntrinLegacyPass, DEBUG_TYPE,
- "Scalarize unsupported masked memory intrinsics", false,
- false)
-
-FunctionPass *llvm::createScalarizeMaskedMemIntrinLegacyPass() {
- return new ScalarizeMaskedMemIntrinLegacyPass();
-}
-
-static bool isConstantIntVector(Value *Mask) {
- Constant *C = dyn_cast<Constant>(Mask);
- if (!C)
- return false;
-
- unsigned NumElts = cast<FixedVectorType>(Mask->getType())->getNumElements();
- for (unsigned i = 0; i != NumElts; ++i) {
- Constant *CElt = C->getAggregateElement(i);
- if (!CElt || !isa<ConstantInt>(CElt))
- return false;
- }
-
- return true;
-}
-
-// Translate a masked load intrinsic like
-// <16 x i32 > @llvm.masked.load( <16 x i32>* %addr, i32 align,
-// <16 x i1> %mask, <16 x i32> %passthru)
-// to a chain of basic blocks, with loading element one-by-one if
-// the appropriate mask bit is set
-//
-// %1 = bitcast i8* %addr to i32*
-// %2 = extractelement <16 x i1> %mask, i32 0
-// br i1 %2, label %cond.load, label %else
-//
-// cond.load: ; preds = %0
-// %3 = getelementptr i32* %1, i32 0
-// %4 = load i32* %3
-// %5 = insertelement <16 x i32> %passthru, i32 %4, i32 0
-// br label %else
-//
-// else: ; preds = %0, %cond.load
-// %res.phi.else = phi <16 x i32> [ %5, %cond.load ], [ undef, %0 ]
-// %6 = extractelement <16 x i1> %mask, i32 1
-// br i1 %6, label %cond.load1, label %else2
-//
-// cond.load1: ; preds = %else
-// %7 = getelementptr i32* %1, i32 1
-// %8 = load i32* %7
-// %9 = insertelement <16 x i32> %res.phi.else, i32 %8, i32 1
-// br label %else2
-//
-// else2: ; preds = %else, %cond.load1
-// %res.phi.else3 = phi <16 x i32> [ %9, %cond.load1 ], [ %res.phi.else, %else ]
-// %10 = extractelement <16 x i1> %mask, i32 2
-// br i1 %10, label %cond.load4, label %else5
-//
-static void scalarizeMaskedLoad(CallInst *CI, bool &ModifiedDT) {
- Value *Ptr = CI->getArgOperand(0);
- Value *Alignment = CI->getArgOperand(1);
- Value *Mask = CI->getArgOperand(2);
- Value *Src0 = CI->getArgOperand(3);
-
- const Align AlignVal = cast<ConstantInt>(Alignment)->getAlignValue();
- VectorType *VecType = cast<FixedVectorType>(CI->getType());
-
- Type *EltTy = VecType->getElementType();
-
- IRBuilder<> Builder(CI->getContext());
- Instruction *InsertPt = CI;
- BasicBlock *IfBlock = CI->getParent();
-
- Builder.SetInsertPoint(InsertPt);
- Builder.SetCurrentDebugLocation(CI->getDebugLoc());
-
- // Short-cut if the mask is all-true.
- if (isa<Constant>(Mask) && cast<Constant>(Mask)->isAllOnesValue()) {
- Value *NewI = Builder.CreateAlignedLoad(VecType, Ptr, AlignVal);
- CI->replaceAllUsesWith(NewI);
- CI->eraseFromParent();
- return;
- }
-
- // Adjust alignment for the scalar instruction.
- const Align AdjustedAlignVal =
- commonAlignment(AlignVal, EltTy->getPrimitiveSizeInBits() / 8);
- // Bitcast %addr from i8* to EltTy*
- Type *NewPtrType =
- EltTy->getPointerTo(Ptr->getType()->getPointerAddressSpace());
- Value *FirstEltPtr = Builder.CreateBitCast(Ptr, NewPtrType);
- unsigned VectorWidth = cast<FixedVectorType>(VecType)->getNumElements();
-
- // The result vector
- Value *VResult = Src0;
-
- if (isConstantIntVector(Mask)) {
- for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
- if (cast<Constant>(Mask)->getAggregateElement(Idx)->isNullValue())
- continue;
- Value *Gep = Builder.CreateConstInBoundsGEP1_32(EltTy, FirstEltPtr, Idx);
- LoadInst *Load = Builder.CreateAlignedLoad(EltTy, Gep, AdjustedAlignVal);
- VResult = Builder.CreateInsertElement(VResult, Load, Idx);
- }
- CI->replaceAllUsesWith(VResult);
- CI->eraseFromParent();
- return;
- }
-
- // If the mask is not v1i1, use scalar bit test operations. This generates
- // better results on X86 at least.
- Value *SclrMask;
- if (VectorWidth != 1) {
- Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);
- SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");
- }
-
- for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
- // Fill the "else" block, created in the previous iteration
- //
- // %res.phi.else3 = phi <16 x i32> [ %11, %cond.load1 ], [ %res.phi.else, %else ]
- // %mask_1 = and i16 %scalar_mask, i32 1 << Idx
- // %cond = icmp ne i16 %mask_1, 0
- // br i1 %mask_1, label %cond.load, label %else
- //
- Value *Predicate;
- if (VectorWidth != 1) {
- Value *Mask = Builder.getInt(APInt::getOneBitSet(VectorWidth, Idx));
- Predicate = Builder.CreateICmpNE(Builder.CreateAnd(SclrMask, Mask),
- Builder.getIntN(VectorWidth, 0));
- } else {
- Predicate = Builder.CreateExtractElement(Mask, Idx);
- }
-
- // Create "cond" block
- //
- // %EltAddr = getelementptr i32* %1, i32 0
- // %Elt = load i32* %EltAddr
- // VResult = insertelement <16 x i32> VResult, i32 %Elt, i32 Idx
- //
- BasicBlock *CondBlock = IfBlock->splitBasicBlock(InsertPt->getIterator(),
- "cond.load");
- Builder.SetInsertPoint(InsertPt);
-
- Value *Gep = Builder.CreateConstInBoundsGEP1_32(EltTy, FirstEltPtr, Idx);
- LoadInst *Load = Builder.CreateAlignedLoad(EltTy, Gep, AdjustedAlignVal);
- Value *NewVResult = Builder.CreateInsertElement(VResult, Load, Idx);
-
- // Create "else" block, fill it in the next iteration
- BasicBlock *NewIfBlock =
- CondBlock->splitBasicBlock(InsertPt->getIterator(), "else");
- Builder.SetInsertPoint(InsertPt);
- Instruction *OldBr = IfBlock->getTerminator();
- BranchInst::Create(CondBlock, NewIfBlock, Predicate, OldBr);
- OldBr->eraseFromParent();
- BasicBlock *PrevIfBlock = IfBlock;
- IfBlock = NewIfBlock;
-
- // Create the phi to join the new and previous value.
- PHINode *Phi = Builder.CreatePHI(VecType, 2, "res.phi.else");
- Phi->addIncoming(NewVResult, CondBlock);
- Phi->addIncoming(VResult, PrevIfBlock);
- VResult = Phi;
- }
-
- CI->replaceAllUsesWith(VResult);
- CI->eraseFromParent();
-
- ModifiedDT = true;
-}
-
-// Translate a masked store intrinsic, like
-// void @llvm.masked.store(<16 x i32> %src, <16 x i32>* %addr, i32 align,
-// <16 x i1> %mask)
-// to a chain of basic blocks, that stores element one-by-one if
-// the appropriate mask bit is set
-//
-// %1 = bitcast i8* %addr to i32*
-// %2 = extractelement <16 x i1> %mask, i32 0
-// br i1 %2, label %cond.store, label %else
-//
-// cond.store: ; preds = %0
-// %3 = extractelement <16 x i32> %val, i32 0
-// %4 = getelementptr i32* %1, i32 0
-// store i32 %3, i32* %4
-// br label %else
-//
-// else: ; preds = %0, %cond.store
-// %5 = extractelement <16 x i1> %mask, i32 1
-// br i1 %5, label %cond.store1, label %else2
-//
-// cond.store1: ; preds = %else
-// %6 = extractelement <16 x i32> %val, i32 1
-// %7 = getelementptr i32* %1, i32 1
-// store i32 %6, i32* %7
-// br label %else2
-// . . .
-static void scalarizeMaskedStore(CallInst *CI, bool &ModifiedDT) {
- Value *Src = CI->getArgOperand(0);
- Value *Ptr = CI->getArgOperand(1);
- Value *Alignment = CI->getArgOperand(2);
- Value *Mask = CI->getArgOperand(3);
-
- const Align AlignVal = cast<ConstantInt>(Alignment)->getAlignValue();
- auto *VecType = cast<VectorType>(Src->getType());
-
- Type *EltTy = VecType->getElementType();
-
- IRBuilder<> Builder(CI->getContext());
- Instruction *InsertPt = CI;
- BasicBlock *IfBlock = CI->getParent();
- Builder.SetInsertPoint(InsertPt);
- Builder.SetCurrentDebugLocation(CI->getDebugLoc());
-
- // Short-cut if the mask is all-true.
- if (isa<Constant>(Mask) && cast<Constant>(Mask)->isAllOnesValue()) {
- Builder.CreateAlignedStore(Src, Ptr, AlignVal);
- CI->eraseFromParent();
- return;
- }
-
- // Adjust alignment for the scalar instruction.
- const Align AdjustedAlignVal =
- commonAlignment(AlignVal, EltTy->getPrimitiveSizeInBits() / 8);
- // Bitcast %addr from i8* to EltTy*
- Type *NewPtrType =
- EltTy->getPointerTo(Ptr->getType()->getPointerAddressSpace());
- Value *FirstEltPtr = Builder.CreateBitCast(Ptr, NewPtrType);
- unsigned VectorWidth = cast<FixedVectorType>(VecType)->getNumElements();
-
- if (isConstantIntVector(Mask)) {
- for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
- if (cast<Constant>(Mask)->getAggregateElement(Idx)->isNullValue())
- continue;
- Value *OneElt = Builder.CreateExtractElement(Src, Idx);
- Value *Gep = Builder.CreateConstInBoundsGEP1_32(EltTy, FirstEltPtr, Idx);
- Builder.CreateAlignedStore(OneElt, Gep, AdjustedAlignVal);
- }
- CI->eraseFromParent();
- return;
- }
-
- // If the mask is not v1i1, use scalar bit test operations. This generates
- // better results on X86 at least.
- Value *SclrMask;
- if (VectorWidth != 1) {
- Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);
- SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");
- }
-
- for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
- // Fill the "else" block, created in the previous iteration
- //
- // %mask_1 = and i16 %scalar_mask, i32 1 << Idx
- // %cond = icmp ne i16 %mask_1, 0
- // br i1 %mask_1, label %cond.store, label %else
- //
- Value *Predicate;
- if (VectorWidth != 1) {
- Value *Mask = Builder.getInt(APInt::getOneBitSet(VectorWidth, Idx));
- Predicate = Builder.CreateICmpNE(Builder.CreateAnd(SclrMask, Mask),
- Builder.getIntN(VectorWidth, 0));
- } else {
- Predicate = Builder.CreateExtractElement(Mask, Idx);
- }
-
- // Create "cond" block
- //
- // %OneElt = extractelement <16 x i32> %Src, i32 Idx
- // %EltAddr = getelementptr i32* %1, i32 0
- // %store i32 %OneElt, i32* %EltAddr
- //
- BasicBlock *CondBlock =
- IfBlock->splitBasicBlock(InsertPt->getIterator(), "cond.store");
- Builder.SetInsertPoint(InsertPt);
-
- Value *OneElt = Builder.CreateExtractElement(Src, Idx);
- Value *Gep = Builder.CreateConstInBoundsGEP1_32(EltTy, FirstEltPtr, Idx);
- Builder.CreateAlignedStore(OneElt, Gep, AdjustedAlignVal);
-
- // Create "else" block, fill it in the next iteration
- BasicBlock *NewIfBlock =
- CondBlock->splitBasicBlock(InsertPt->getIterator(), "else");
- Builder.SetInsertPoint(InsertPt);
- Instruction *OldBr = IfBlock->getTerminator();
- BranchInst::Create(CondBlock, NewIfBlock, Predicate, OldBr);
- OldBr->eraseFromParent();
- IfBlock = NewIfBlock;
- }
- CI->eraseFromParent();
-
- ModifiedDT = true;
-}
-
-// Translate a masked gather intrinsic like
-// <16 x i32 > @llvm.masked.gather.v16i32( <16 x i32*> %Ptrs, i32 4,
-// <16 x i1> %Mask, <16 x i32> %Src)
-// to a chain of basic blocks, with loading element one-by-one if
-// the appropriate mask bit is set
-//
-// %Ptrs = getelementptr i32, i32* %base, <16 x i64> %ind
-// %Mask0 = extractelement <16 x i1> %Mask, i32 0
-// br i1 %Mask0, label %cond.load, label %else
-//
-// cond.load:
-// %Ptr0 = extractelement <16 x i32*> %Ptrs, i32 0
-// %Load0 = load i32, i32* %Ptr0, align 4
-// %Res0 = insertelement <16 x i32> undef, i32 %Load0, i32 0
-// br label %else
-//
-// else:
-// %res.phi.else = phi <16 x i32>[%Res0, %cond.load], [undef, %0]
-// %Mask1 = extractelement <16 x i1> %Mask, i32 1
-// br i1 %Mask1, label %cond.load1, label %else2
-//
-// cond.load1:
-// %Ptr1 = extractelement <16 x i32*> %Ptrs, i32 1
-// %Load1 = load i32, i32* %Ptr1, align 4
-// %Res1 = insertelement <16 x i32> %res.phi.else, i32 %Load1, i32 1
-// br label %else2
-// . . .
-// %Result = select <16 x i1> %Mask, <16 x i32> %res.phi.select, <16 x i32> %Src
-// ret <16 x i32> %Result
-static void scalarizeMaskedGather(CallInst *CI, bool &ModifiedDT) {
- Value *Ptrs = CI->getArgOperand(0);
- Value *Alignment = CI->getArgOperand(1);
- Value *Mask = CI->getArgOperand(2);
- Value *Src0 = CI->getArgOperand(3);
-
- auto *VecType = cast<FixedVectorType>(CI->getType());
- Type *EltTy = VecType->getElementType();
-
- IRBuilder<> Builder(CI->getContext());
- Instruction *InsertPt = CI;
- BasicBlock *IfBlock = CI->getParent();
- Builder.SetInsertPoint(InsertPt);
- MaybeAlign AlignVal = cast<ConstantInt>(Alignment)->getMaybeAlignValue();
-
- Builder.SetCurrentDebugLocation(CI->getDebugLoc());
-
- // The result vector
- Value *VResult = Src0;
- unsigned VectorWidth = VecType->getNumElements();
-
- // Shorten the way if the mask is a vector of constants.
- if (isConstantIntVector(Mask)) {
- for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
- if (cast<Constant>(Mask)->getAggregateElement(Idx)->isNullValue())
- continue;
- Value *Ptr = Builder.CreateExtractElement(Ptrs, Idx, "Ptr" + Twine(Idx));
- LoadInst *Load =
- Builder.CreateAlignedLoad(EltTy, Ptr, AlignVal, "Load" + Twine(Idx));
- VResult =
- Builder.CreateInsertElement(VResult, Load, Idx, "Res" + Twine(Idx));
- }
- CI->replaceAllUsesWith(VResult);
- CI->eraseFromParent();
- return;
- }
-
- // If the mask is not v1i1, use scalar bit test operations. This generates
- // better results on X86 at least.
- Value *SclrMask;
- if (VectorWidth != 1) {
- Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);
- SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");
- }
-
- for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
- // Fill the "else" block, created in the previous iteration
- //
- // %Mask1 = and i16 %scalar_mask, i32 1 << Idx
- // %cond = icmp ne i16 %mask_1, 0
- // br i1 %Mask1, label %cond.load, label %else
- //
-
- Value *Predicate;
- if (VectorWidth != 1) {
- Value *Mask = Builder.getInt(APInt::getOneBitSet(VectorWidth, Idx));
- Predicate = Builder.CreateICmpNE(Builder.CreateAnd(SclrMask, Mask),
- Builder.getIntN(VectorWidth, 0));
- } else {
- Predicate = Builder.CreateExtractElement(Mask, Idx, "Mask" + Twine(Idx));
- }
-
- // Create "cond" block
- //
- // %EltAddr = getelementptr i32* %1, i32 0
- // %Elt = load i32* %EltAddr
- // VResult = insertelement <16 x i32> VResult, i32 %Elt, i32 Idx
- //
- BasicBlock *CondBlock = IfBlock->splitBasicBlock(InsertPt, "cond.load");
- Builder.SetInsertPoint(InsertPt);
-
- Value *Ptr = Builder.CreateExtractElement(Ptrs, Idx, "Ptr" + Twine(Idx));
- LoadInst *Load =
- Builder.CreateAlignedLoad(EltTy, Ptr, AlignVal, "Load" + Twine(Idx));
- Value *NewVResult =
- Builder.CreateInsertElement(VResult, Load, Idx, "Res" + Twine(Idx));
-
- // Create "else" block, fill it in the next iteration
- BasicBlock *NewIfBlock = CondBlock->splitBasicBlock(InsertPt, "else");
- Builder.SetInsertPoint(InsertPt);
- Instruction *OldBr = IfBlock->getTerminator();
- BranchInst::Create(CondBlock, NewIfBlock, Predicate, OldBr);
- OldBr->eraseFromParent();
- BasicBlock *PrevIfBlock = IfBlock;
- IfBlock = NewIfBlock;
-
- PHINode *Phi = Builder.CreatePHI(VecType, 2, "res.phi.else");
- Phi->addIncoming(NewVResult, CondBlock);
- Phi->addIncoming(VResult, PrevIfBlock);
- VResult = Phi;
- }
-
- CI->replaceAllUsesWith(VResult);
- CI->eraseFromParent();
-
- ModifiedDT = true;
-}
-
-// Translate a masked scatter intrinsic, like
-// void @llvm.masked.scatter.v16i32(<16 x i32> %Src, <16 x i32*>* %Ptrs, i32 4,
-// <16 x i1> %Mask)
-// to a chain of basic blocks, that stores element one-by-one if
-// the appropriate mask bit is set.
-//
-// %Ptrs = getelementptr i32, i32* %ptr, <16 x i64> %ind
-// %Mask0 = extractelement <16 x i1> %Mask, i32 0
-// br i1 %Mask0, label %cond.store, label %else
-//
-// cond.store:
-// %Elt0 = extractelement <16 x i32> %Src, i32 0
-// %Ptr0 = extractelement <16 x i32*> %Ptrs, i32 0
-// store i32 %Elt0, i32* %Ptr0, align 4
-// br label %else
-//
-// else:
-// %Mask1 = extractelement <16 x i1> %Mask, i32 1
-// br i1 %Mask1, label %cond.store1, label %else2
-//
-// cond.store1:
-// %Elt1 = extractelement <16 x i32> %Src, i32 1
-// %Ptr1 = extractelement <16 x i32*> %Ptrs, i32 1
-// store i32 %Elt1, i32* %Ptr1, align 4
-// br label %else2
-// . . .
-static void scalarizeMaskedScatter(CallInst *CI, bool &ModifiedDT) {
- Value *Src = CI->getArgOperand(0);
- Value *Ptrs = CI->getArgOperand(1);
- Value *Alignment = CI->getArgOperand(2);
- Value *Mask = CI->getArgOperand(3);
-
- auto *SrcFVTy = cast<FixedVectorType>(Src->getType());
-
- assert(
- isa<VectorType>(Ptrs->getType()) &&
- isa<PointerType>(cast<VectorType>(Ptrs->getType())->getElementType()) &&
- "Vector of pointers is expected in masked scatter intrinsic");
-
- IRBuilder<> Builder(CI->getContext());
- Instruction *InsertPt = CI;
- BasicBlock *IfBlock = CI->getParent();
- Builder.SetInsertPoint(InsertPt);
- Builder.SetCurrentDebugLocation(CI->getDebugLoc());
-
- MaybeAlign AlignVal = cast<ConstantInt>(Alignment)->getMaybeAlignValue();
- unsigned VectorWidth = SrcFVTy->getNumElements();
-
- // Shorten the way if the mask is a vector of constants.
- if (isConstantIntVector(Mask)) {
- for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
- if (cast<Constant>(Mask)->getAggregateElement(Idx)->isNullValue())
- continue;
- Value *OneElt =
- Builder.CreateExtractElement(Src, Idx, "Elt" + Twine(Idx));
- Value *Ptr = Builder.CreateExtractElement(Ptrs, Idx, "Ptr" + Twine(Idx));
- Builder.CreateAlignedStore(OneElt, Ptr, AlignVal);
- }
- CI->eraseFromParent();
- return;
- }
-
- // If the mask is not v1i1, use scalar bit test operations. This generates
- // better results on X86 at least.
- Value *SclrMask;
- if (VectorWidth != 1) {
- Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);
- SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");
- }
-
- for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
- // Fill the "else" block, created in the previous iteration
- //
- // %Mask1 = and i16 %scalar_mask, i32 1 << Idx
- // %cond = icmp ne i16 %mask_1, 0
- // br i1 %Mask1, label %cond.store, label %else
- //
- Value *Predicate;
- if (VectorWidth != 1) {
- Value *Mask = Builder.getInt(APInt::getOneBitSet(VectorWidth, Idx));
- Predicate = Builder.CreateICmpNE(Builder.CreateAnd(SclrMask, Mask),
- Builder.getIntN(VectorWidth, 0));
- } else {
- Predicate = Builder.CreateExtractElement(Mask, Idx, "Mask" + Twine(Idx));
- }
-
- // Create "cond" block
- //
- // %Elt1 = extractelement <16 x i32> %Src, i32 1
- // %Ptr1 = extractelement <16 x i32*> %Ptrs, i32 1
- // %store i32 %Elt1, i32* %Ptr1
- //
- BasicBlock *CondBlock = IfBlock->splitBasicBlock(InsertPt, "cond.store");
- Builder.SetInsertPoint(InsertPt);
-
- Value *OneElt = Builder.CreateExtractElement(Src, Idx, "Elt" + Twine(Idx));
- Value *Ptr = Builder.CreateExtractElement(Ptrs, Idx, "Ptr" + Twine(Idx));
- Builder.CreateAlignedStore(OneElt, Ptr, AlignVal);
-
- // Create "else" block, fill it in the next iteration
- BasicBlock *NewIfBlock = CondBlock->splitBasicBlock(InsertPt, "else");
- Builder.SetInsertPoint(InsertPt);
- Instruction *OldBr = IfBlock->getTerminator();
- BranchInst::Create(CondBlock, NewIfBlock, Predicate, OldBr);
- OldBr->eraseFromParent();
- IfBlock = NewIfBlock;
- }
- CI->eraseFromParent();
-
- ModifiedDT = true;
-}
-
-static void scalarizeMaskedExpandLoad(CallInst *CI, bool &ModifiedDT) {
- Value *Ptr = CI->getArgOperand(0);
- Value *Mask = CI->getArgOperand(1);
- Value *PassThru = CI->getArgOperand(2);
-
- auto *VecType = cast<FixedVectorType>(CI->getType());
-
- Type *EltTy = VecType->getElementType();
-
- IRBuilder<> Builder(CI->getContext());
- Instruction *InsertPt = CI;
- BasicBlock *IfBlock = CI->getParent();
-
- Builder.SetInsertPoint(InsertPt);
- Builder.SetCurrentDebugLocation(CI->getDebugLoc());
-
- unsigned VectorWidth = VecType->getNumElements();
-
- // The result vector
- Value *VResult = PassThru;
-
- // Shorten the way if the mask is a vector of constants.
- // Create a build_vector pattern, with loads/undefs as necessary and then
- // shuffle blend with the pass through value.
- if (isConstantIntVector(Mask)) {
- unsigned MemIndex = 0;
- VResult = UndefValue::get(VecType);
- SmallVector<int, 16> ShuffleMask(VectorWidth, UndefMaskElem);
- for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
- Value *InsertElt;
- if (cast<Constant>(Mask)->getAggregateElement(Idx)->isNullValue()) {
- InsertElt = UndefValue::get(EltTy);
- ShuffleMask[Idx] = Idx + VectorWidth;
- } else {
- Value *NewPtr =
- Builder.CreateConstInBoundsGEP1_32(EltTy, Ptr, MemIndex);
- InsertElt = Builder.CreateAlignedLoad(EltTy, NewPtr, Align(1),
- "Load" + Twine(Idx));
- ShuffleMask[Idx] = Idx;
- ++MemIndex;
- }
- VResult = Builder.CreateInsertElement(VResult, InsertElt, Idx,
- "Res" + Twine(Idx));
- }
- VResult = Builder.CreateShuffleVector(VResult, PassThru, ShuffleMask);
- CI->replaceAllUsesWith(VResult);
- CI->eraseFromParent();
- return;
- }
-
- // If the mask is not v1i1, use scalar bit test operations. This generates
- // better results on X86 at least.
- Value *SclrMask;
- if (VectorWidth != 1) {
- Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);
- SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");
- }
-
- for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
- // Fill the "else" block, created in the previous iteration
- //
- // %res.phi.else3 = phi <16 x i32> [ %11, %cond.load1 ], [ %res.phi.else, %else ]
- // %mask_1 = extractelement <16 x i1> %mask, i32 Idx
- // br i1 %mask_1, label %cond.load, label %else
- //
-
- Value *Predicate;
- if (VectorWidth != 1) {
- Value *Mask = Builder.getInt(APInt::getOneBitSet(VectorWidth, Idx));
- Predicate = Builder.CreateICmpNE(Builder.CreateAnd(SclrMask, Mask),
- Builder.getIntN(VectorWidth, 0));
- } else {
- Predicate = Builder.CreateExtractElement(Mask, Idx, "Mask" + Twine(Idx));
- }
-
- // Create "cond" block
- //
- // %EltAddr = getelementptr i32* %1, i32 0
- // %Elt = load i32* %EltAddr
- // VResult = insertelement <16 x i32> VResult, i32 %Elt, i32 Idx
- //
- BasicBlock *CondBlock = IfBlock->splitBasicBlock(InsertPt->getIterator(),
- "cond.load");
- Builder.SetInsertPoint(InsertPt);
-
- LoadInst *Load = Builder.CreateAlignedLoad(EltTy, Ptr, Align(1));
- Value *NewVResult = Builder.CreateInsertElement(VResult, Load, Idx);
-
- // Move the pointer if there are more blocks to come.
- Value *NewPtr;
- if ((Idx + 1) != VectorWidth)
- NewPtr = Builder.CreateConstInBoundsGEP1_32(EltTy, Ptr, 1);
-
- // Create "else" block, fill it in the next iteration
- BasicBlock *NewIfBlock =
- CondBlock->splitBasicBlock(InsertPt->getIterator(), "else");
- Builder.SetInsertPoint(InsertPt);
- Instruction *OldBr = IfBlock->getTerminator();
- BranchInst::Create(CondBlock, NewIfBlock, Predicate, OldBr);
- OldBr->eraseFromParent();
- BasicBlock *PrevIfBlock = IfBlock;
- IfBlock = NewIfBlock;
-
- // Create the phi to join the new and previous value.
- PHINode *ResultPhi = Builder.CreatePHI(VecType, 2, "res.phi.else");
- ResultPhi->addIncoming(NewVResult, CondBlock);
- ResultPhi->addIncoming(VResult, PrevIfBlock);
- VResult = ResultPhi;
-
- // Add a PHI for the pointer if this isn't the last iteration.
- if ((Idx + 1) != VectorWidth) {
- PHINode *PtrPhi = Builder.CreatePHI(Ptr->getType(), 2, "ptr.phi.else");
- PtrPhi->addIncoming(NewPtr, CondBlock);
- PtrPhi->addIncoming(Ptr, PrevIfBlock);
- Ptr = PtrPhi;
- }
- }
-
- CI->replaceAllUsesWith(VResult);
- CI->eraseFromParent();
-
- ModifiedDT = true;
-}
-
-static void scalarizeMaskedCompressStore(CallInst *CI, bool &ModifiedDT) {
- Value *Src = CI->getArgOperand(0);
- Value *Ptr = CI->getArgOperand(1);
- Value *Mask = CI->getArgOperand(2);
-
- auto *VecType = cast<FixedVectorType>(Src->getType());
-
- IRBuilder<> Builder(CI->getContext());
- Instruction *InsertPt = CI;
- BasicBlock *IfBlock = CI->getParent();
-
- Builder.SetInsertPoint(InsertPt);
- Builder.SetCurrentDebugLocation(CI->getDebugLoc());
-
- Type *EltTy = VecType->getElementType();
-
- unsigned VectorWidth = VecType->getNumElements();
-
- // Shorten the way if the mask is a vector of constants.
- if (isConstantIntVector(Mask)) {
- unsigned MemIndex = 0;
- for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
- if (cast<Constant>(Mask)->getAggregateElement(Idx)->isNullValue())
- continue;
- Value *OneElt =
- Builder.CreateExtractElement(Src, Idx, "Elt" + Twine(Idx));
- Value *NewPtr = Builder.CreateConstInBoundsGEP1_32(EltTy, Ptr, MemIndex);
- Builder.CreateAlignedStore(OneElt, NewPtr, Align(1));
- ++MemIndex;
- }
- CI->eraseFromParent();
- return;
- }
-
- // If the mask is not v1i1, use scalar bit test operations. This generates
- // better results on X86 at least.
- Value *SclrMask;
- if (VectorWidth != 1) {
- Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);
- SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");
- }
-
- for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
- // Fill the "else" block, created in the previous iteration
- //
- // %mask_1 = extractelement <16 x i1> %mask, i32 Idx
- // br i1 %mask_1, label %cond.store, label %else
- //
- Value *Predicate;
- if (VectorWidth != 1) {
- Value *Mask = Builder.getInt(APInt::getOneBitSet(VectorWidth, Idx));
- Predicate = Builder.CreateICmpNE(Builder.CreateAnd(SclrMask, Mask),
- Builder.getIntN(VectorWidth, 0));
- } else {
- Predicate = Builder.CreateExtractElement(Mask, Idx, "Mask" + Twine(Idx));
- }
-
- // Create "cond" block
- //
- // %OneElt = extractelement <16 x i32> %Src, i32 Idx
- // %EltAddr = getelementptr i32* %1, i32 0
- // %store i32 %OneElt, i32* %EltAddr
- //
- BasicBlock *CondBlock =
- IfBlock->splitBasicBlock(InsertPt->getIterator(), "cond.store");
- Builder.SetInsertPoint(InsertPt);
-
- Value *OneElt = Builder.CreateExtractElement(Src, Idx);
- Builder.CreateAlignedStore(OneElt, Ptr, Align(1));
-
- // Move the pointer if there are more blocks to come.
- Value *NewPtr;
- if ((Idx + 1) != VectorWidth)
- NewPtr = Builder.CreateConstInBoundsGEP1_32(EltTy, Ptr, 1);
-
- // Create "else" block, fill it in the next iteration
- BasicBlock *NewIfBlock =
- CondBlock->splitBasicBlock(InsertPt->getIterator(), "else");
- Builder.SetInsertPoint(InsertPt);
- Instruction *OldBr = IfBlock->getTerminator();
- BranchInst::Create(CondBlock, NewIfBlock, Predicate, OldBr);
- OldBr->eraseFromParent();
- BasicBlock *PrevIfBlock = IfBlock;
- IfBlock = NewIfBlock;
-
- // Add a PHI for the pointer if this isn't the last iteration.
- if ((Idx + 1) != VectorWidth) {
- PHINode *PtrPhi = Builder.CreatePHI(Ptr->getType(), 2, "ptr.phi.else");
- PtrPhi->addIncoming(NewPtr, CondBlock);
- PtrPhi->addIncoming(Ptr, PrevIfBlock);
- Ptr = PtrPhi;
- }
- }
- CI->eraseFromParent();
-
- ModifiedDT = true;
-}
-
-static bool runImpl(Function &F, const TargetTransformInfo &TTI) {
- bool EverMadeChange = false;
- bool MadeChange = true;
- auto &DL = F.getParent()->getDataLayout();
- while (MadeChange) {
- MadeChange = false;
- for (Function::iterator I = F.begin(); I != F.end();) {
- BasicBlock *BB = &*I++;
- bool ModifiedDTOnIteration = false;
- MadeChange |= optimizeBlock(*BB, ModifiedDTOnIteration, TTI, DL);
-
- // Restart BB iteration if the dominator tree of the Function was changed
- if (ModifiedDTOnIteration)
- break;
- }
-
- EverMadeChange |= MadeChange;
- }
- return EverMadeChange;
-}
-
-bool ScalarizeMaskedMemIntrinLegacyPass::runOnFunction(Function &F) {
- auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
- return runImpl(F, TTI);
-}
-
-PreservedAnalyses
-ScalarizeMaskedMemIntrinPass::run(Function &F, FunctionAnalysisManager &AM) {
- auto &TTI = AM.getResult<TargetIRAnalysis>(F);
- if (!runImpl(F, TTI))
- return PreservedAnalyses::all();
- PreservedAnalyses PA;
- PA.preserve<TargetIRAnalysis>();
- return PA;
-}
-
-static bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT,
- const TargetTransformInfo &TTI,
- const DataLayout &DL) {
- bool MadeChange = false;
-
- BasicBlock::iterator CurInstIterator = BB.begin();
- while (CurInstIterator != BB.end()) {
- if (CallInst *CI = dyn_cast<CallInst>(&*CurInstIterator++))
- MadeChange |= optimizeCallInst(CI, ModifiedDT, TTI, DL);
- if (ModifiedDT)
- return true;
- }
-
- return MadeChange;
-}
-
-static bool optimizeCallInst(CallInst *CI, bool &ModifiedDT,
- const TargetTransformInfo &TTI,
- const DataLayout &DL) {
- IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI);
- if (II) {
- // The scalarization code below does not work for scalable vectors.
- if (isa<ScalableVectorType>(II->getType()) ||
- any_of(II->arg_operands(),
- [](Value *V) { return isa<ScalableVectorType>(V->getType()); }))
- return false;
-
- switch (II->getIntrinsicID()) {
- default:
- break;
- case Intrinsic::masked_load:
- // Scalarize unsupported vector masked load
- if (TTI.isLegalMaskedLoad(
- CI->getType(),
- cast<ConstantInt>(CI->getArgOperand(1))->getAlignValue()))
- return false;
- scalarizeMaskedLoad(CI, ModifiedDT);
- return true;
- case Intrinsic::masked_store:
- if (TTI.isLegalMaskedStore(
- CI->getArgOperand(0)->getType(),
- cast<ConstantInt>(CI->getArgOperand(2))->getAlignValue()))
- return false;
- scalarizeMaskedStore(CI, ModifiedDT);
- return true;
- case Intrinsic::masked_gather: {
- unsigned AlignmentInt =
- cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
- Type *LoadTy = CI->getType();
- Align Alignment =
- DL.getValueOrABITypeAlignment(MaybeAlign(AlignmentInt), LoadTy);
- if (TTI.isLegalMaskedGather(LoadTy, Alignment))
- return false;
- scalarizeMaskedGather(CI, ModifiedDT);
- return true;
- }
- case Intrinsic::masked_scatter: {
- unsigned AlignmentInt =
- cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
- Type *StoreTy = CI->getArgOperand(0)->getType();
- Align Alignment =
- DL.getValueOrABITypeAlignment(MaybeAlign(AlignmentInt), StoreTy);
- if (TTI.isLegalMaskedScatter(StoreTy, Alignment))
- return false;
- scalarizeMaskedScatter(CI, ModifiedDT);
- return true;
- }
- case Intrinsic::masked_expandload:
- if (TTI.isLegalMaskedExpandLoad(CI->getType()))
- return false;
- scalarizeMaskedExpandLoad(CI, ModifiedDT);
- return true;
- case Intrinsic::masked_compressstore:
- if (TTI.isLegalMaskedCompressStore(CI->getArgOperand(0)->getType()))
- return false;
- scalarizeMaskedCompressStore(CI, ModifiedDT);
- return true;
- }
- }
-
- return false;
-}
+//===- ScalarizeMaskedMemIntrin.cpp - Scalarize unsupported masked mem ----===//
+// instrinsics
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass replaces masked memory intrinsics - when unsupported by the target
+// - with a chain of basic blocks, that deal with the elements one-by-one if the
+// appropriate mask bit is set.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Value.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Transforms/Scalar.h"
+#include <algorithm>
+#include <cassert>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "scalarize-masked-mem-intrin"
+
+namespace {
+
+class ScalarizeMaskedMemIntrinLegacyPass : public FunctionPass {
+public:
+ static char ID; // Pass identification, replacement for typeid
+
+ explicit ScalarizeMaskedMemIntrinLegacyPass() : FunctionPass(ID) {
+ initializeScalarizeMaskedMemIntrinLegacyPassPass(
+ *PassRegistry::getPassRegistry());
+ }
+
+ bool runOnFunction(Function &F) override;
+
+ StringRef getPassName() const override {
+ return "Scalarize Masked Memory Intrinsics";
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<TargetTransformInfoWrapperPass>();
+ }
+};
+
+} // end anonymous namespace
+
+static bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT,
+ const TargetTransformInfo &TTI, const DataLayout &DL);
+static bool optimizeCallInst(CallInst *CI, bool &ModifiedDT,
+ const TargetTransformInfo &TTI,
+ const DataLayout &DL);
+
+char ScalarizeMaskedMemIntrinLegacyPass::ID = 0;
+
+INITIALIZE_PASS_BEGIN(ScalarizeMaskedMemIntrinLegacyPass, DEBUG_TYPE,
+ "Scalarize unsupported masked memory intrinsics", false,
+ false)
+INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
+INITIALIZE_PASS_END(ScalarizeMaskedMemIntrinLegacyPass, DEBUG_TYPE,
+ "Scalarize unsupported masked memory intrinsics", false,
+ false)
+
+FunctionPass *llvm::createScalarizeMaskedMemIntrinLegacyPass() {
+ return new ScalarizeMaskedMemIntrinLegacyPass();
+}
+
+static bool isConstantIntVector(Value *Mask) {
+ Constant *C = dyn_cast<Constant>(Mask);
+ if (!C)
+ return false;
+
+ unsigned NumElts = cast<FixedVectorType>(Mask->getType())->getNumElements();
+ for (unsigned i = 0; i != NumElts; ++i) {
+ Constant *CElt = C->getAggregateElement(i);
+ if (!CElt || !isa<ConstantInt>(CElt))
+ return false;
+ }
+
+ return true;
+}
+
+// Translate a masked load intrinsic like
+// <16 x i32 > @llvm.masked.load( <16 x i32>* %addr, i32 align,
+// <16 x i1> %mask, <16 x i32> %passthru)
+// to a chain of basic blocks, with loading element one-by-one if
+// the appropriate mask bit is set
+//
+// %1 = bitcast i8* %addr to i32*
+// %2 = extractelement <16 x i1> %mask, i32 0
+// br i1 %2, label %cond.load, label %else
+//
+// cond.load: ; preds = %0
+// %3 = getelementptr i32* %1, i32 0
+// %4 = load i32* %3
+// %5 = insertelement <16 x i32> %passthru, i32 %4, i32 0
+// br label %else
+//
+// else: ; preds = %0, %cond.load
+// %res.phi.else = phi <16 x i32> [ %5, %cond.load ], [ undef, %0 ]
+// %6 = extractelement <16 x i1> %mask, i32 1
+// br i1 %6, label %cond.load1, label %else2
+//
+// cond.load1: ; preds = %else
+// %7 = getelementptr i32* %1, i32 1
+// %8 = load i32* %7
+// %9 = insertelement <16 x i32> %res.phi.else, i32 %8, i32 1
+// br label %else2
+//
+// else2: ; preds = %else, %cond.load1
+// %res.phi.else3 = phi <16 x i32> [ %9, %cond.load1 ], [ %res.phi.else, %else ]
+// %10 = extractelement <16 x i1> %mask, i32 2
+// br i1 %10, label %cond.load4, label %else5
+//
+static void scalarizeMaskedLoad(CallInst *CI, bool &ModifiedDT) {
+ Value *Ptr = CI->getArgOperand(0);
+ Value *Alignment = CI->getArgOperand(1);
+ Value *Mask = CI->getArgOperand(2);
+ Value *Src0 = CI->getArgOperand(3);
+
+ const Align AlignVal = cast<ConstantInt>(Alignment)->getAlignValue();
+ VectorType *VecType = cast<FixedVectorType>(CI->getType());
+
+ Type *EltTy = VecType->getElementType();
+
+ IRBuilder<> Builder(CI->getContext());
+ Instruction *InsertPt = CI;
+ BasicBlock *IfBlock = CI->getParent();
+
+ Builder.SetInsertPoint(InsertPt);
+ Builder.SetCurrentDebugLocation(CI->getDebugLoc());
+
+ // Short-cut if the mask is all-true.
+ if (isa<Constant>(Mask) && cast<Constant>(Mask)->isAllOnesValue()) {
+ Value *NewI = Builder.CreateAlignedLoad(VecType, Ptr, AlignVal);
+ CI->replaceAllUsesWith(NewI);
+ CI->eraseFromParent();
+ return;
+ }
+
+ // Adjust alignment for the scalar instruction.
+ const Align AdjustedAlignVal =
+ commonAlignment(AlignVal, EltTy->getPrimitiveSizeInBits() / 8);
+ // Bitcast %addr from i8* to EltTy*
+ Type *NewPtrType =
+ EltTy->getPointerTo(Ptr->getType()->getPointerAddressSpace());
+ Value *FirstEltPtr = Builder.CreateBitCast(Ptr, NewPtrType);
+ unsigned VectorWidth = cast<FixedVectorType>(VecType)->getNumElements();
+
+ // The result vector
+ Value *VResult = Src0;
+
+ if (isConstantIntVector(Mask)) {
+ for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
+ if (cast<Constant>(Mask)->getAggregateElement(Idx)->isNullValue())
+ continue;
+ Value *Gep = Builder.CreateConstInBoundsGEP1_32(EltTy, FirstEltPtr, Idx);
+ LoadInst *Load = Builder.CreateAlignedLoad(EltTy, Gep, AdjustedAlignVal);
+ VResult = Builder.CreateInsertElement(VResult, Load, Idx);
+ }
+ CI->replaceAllUsesWith(VResult);
+ CI->eraseFromParent();
+ return;
+ }
+
+ // If the mask is not v1i1, use scalar bit test operations. This generates
+ // better results on X86 at least.
+ Value *SclrMask;
+ if (VectorWidth != 1) {
+ Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);
+ SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");
+ }
+
+ for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
+ // Fill the "else" block, created in the previous iteration
+ //
+ // %res.phi.else3 = phi <16 x i32> [ %11, %cond.load1 ], [ %res.phi.else, %else ]
+ // %mask_1 = and i16 %scalar_mask, i32 1 << Idx
+ // %cond = icmp ne i16 %mask_1, 0
+ // br i1 %mask_1, label %cond.load, label %else
+ //
+ Value *Predicate;
+ if (VectorWidth != 1) {
+ Value *Mask = Builder.getInt(APInt::getOneBitSet(VectorWidth, Idx));
+ Predicate = Builder.CreateICmpNE(Builder.CreateAnd(SclrMask, Mask),
+ Builder.getIntN(VectorWidth, 0));
+ } else {
+ Predicate = Builder.CreateExtractElement(Mask, Idx);
+ }
+
+ // Create "cond" block
+ //
+ // %EltAddr = getelementptr i32* %1, i32 0
+ // %Elt = load i32* %EltAddr
+ // VResult = insertelement <16 x i32> VResult, i32 %Elt, i32 Idx
+ //
+ BasicBlock *CondBlock = IfBlock->splitBasicBlock(InsertPt->getIterator(),
+ "cond.load");
+ Builder.SetInsertPoint(InsertPt);
+
+ Value *Gep = Builder.CreateConstInBoundsGEP1_32(EltTy, FirstEltPtr, Idx);
+ LoadInst *Load = Builder.CreateAlignedLoad(EltTy, Gep, AdjustedAlignVal);
+ Value *NewVResult = Builder.CreateInsertElement(VResult, Load, Idx);
+
+ // Create "else" block, fill it in the next iteration
+ BasicBlock *NewIfBlock =
+ CondBlock->splitBasicBlock(InsertPt->getIterator(), "else");
+ Builder.SetInsertPoint(InsertPt);
+ Instruction *OldBr = IfBlock->getTerminator();
+ BranchInst::Create(CondBlock, NewIfBlock, Predicate, OldBr);
+ OldBr->eraseFromParent();
+ BasicBlock *PrevIfBlock = IfBlock;
+ IfBlock = NewIfBlock;
+
+ // Create the phi to join the new and previous value.
+ PHINode *Phi = Builder.CreatePHI(VecType, 2, "res.phi.else");
+ Phi->addIncoming(NewVResult, CondBlock);
+ Phi->addIncoming(VResult, PrevIfBlock);
+ VResult = Phi;
+ }
+
+ CI->replaceAllUsesWith(VResult);
+ CI->eraseFromParent();
+
+ ModifiedDT = true;
+}
+
+// Translate a masked store intrinsic, like
+// void @llvm.masked.store(<16 x i32> %src, <16 x i32>* %addr, i32 align,
+// <16 x i1> %mask)
+// to a chain of basic blocks, that stores element one-by-one if
+// the appropriate mask bit is set
+//
+// %1 = bitcast i8* %addr to i32*
+// %2 = extractelement <16 x i1> %mask, i32 0
+// br i1 %2, label %cond.store, label %else
+//
+// cond.store: ; preds = %0
+// %3 = extractelement <16 x i32> %val, i32 0
+// %4 = getelementptr i32* %1, i32 0
+// store i32 %3, i32* %4
+// br label %else
+//
+// else: ; preds = %0, %cond.store
+// %5 = extractelement <16 x i1> %mask, i32 1
+// br i1 %5, label %cond.store1, label %else2
+//
+// cond.store1: ; preds = %else
+// %6 = extractelement <16 x i32> %val, i32 1
+// %7 = getelementptr i32* %1, i32 1
+// store i32 %6, i32* %7
+// br label %else2
+// . . .
+static void scalarizeMaskedStore(CallInst *CI, bool &ModifiedDT) {
+ Value *Src = CI->getArgOperand(0);
+ Value *Ptr = CI->getArgOperand(1);
+ Value *Alignment = CI->getArgOperand(2);
+ Value *Mask = CI->getArgOperand(3);
+
+ const Align AlignVal = cast<ConstantInt>(Alignment)->getAlignValue();
+ auto *VecType = cast<VectorType>(Src->getType());
+
+ Type *EltTy = VecType->getElementType();
+
+ IRBuilder<> Builder(CI->getContext());
+ Instruction *InsertPt = CI;
+ BasicBlock *IfBlock = CI->getParent();
+ Builder.SetInsertPoint(InsertPt);
+ Builder.SetCurrentDebugLocation(CI->getDebugLoc());
+
+ // Short-cut if the mask is all-true.
+ if (isa<Constant>(Mask) && cast<Constant>(Mask)->isAllOnesValue()) {
+ Builder.CreateAlignedStore(Src, Ptr, AlignVal);
+ CI->eraseFromParent();
+ return;
+ }
+
+ // Adjust alignment for the scalar instruction.
+ const Align AdjustedAlignVal =
+ commonAlignment(AlignVal, EltTy->getPrimitiveSizeInBits() / 8);
+ // Bitcast %addr from i8* to EltTy*
+ Type *NewPtrType =
+ EltTy->getPointerTo(Ptr->getType()->getPointerAddressSpace());
+ Value *FirstEltPtr = Builder.CreateBitCast(Ptr, NewPtrType);
+ unsigned VectorWidth = cast<FixedVectorType>(VecType)->getNumElements();
+
+ if (isConstantIntVector(Mask)) {
+ for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
+ if (cast<Constant>(Mask)->getAggregateElement(Idx)->isNullValue())
+ continue;
+ Value *OneElt = Builder.CreateExtractElement(Src, Idx);
+ Value *Gep = Builder.CreateConstInBoundsGEP1_32(EltTy, FirstEltPtr, Idx);
+ Builder.CreateAlignedStore(OneElt, Gep, AdjustedAlignVal);
+ }
+ CI->eraseFromParent();
+ return;
+ }
+
+ // If the mask is not v1i1, use scalar bit test operations. This generates
+ // better results on X86 at least.
+ Value *SclrMask;
+ if (VectorWidth != 1) {
+ Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);
+ SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");
+ }
+
+ for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
+ // Fill the "else" block, created in the previous iteration
+ //
+ // %mask_1 = and i16 %scalar_mask, i32 1 << Idx
+ // %cond = icmp ne i16 %mask_1, 0
+ // br i1 %mask_1, label %cond.store, label %else
+ //
+ Value *Predicate;
+ if (VectorWidth != 1) {
+ Value *Mask = Builder.getInt(APInt::getOneBitSet(VectorWidth, Idx));
+ Predicate = Builder.CreateICmpNE(Builder.CreateAnd(SclrMask, Mask),
+ Builder.getIntN(VectorWidth, 0));
+ } else {
+ Predicate = Builder.CreateExtractElement(Mask, Idx);
+ }
+
+ // Create "cond" block
+ //
+ // %OneElt = extractelement <16 x i32> %Src, i32 Idx
+ // %EltAddr = getelementptr i32* %1, i32 0
+ // %store i32 %OneElt, i32* %EltAddr
+ //
+ BasicBlock *CondBlock =
+ IfBlock->splitBasicBlock(InsertPt->getIterator(), "cond.store");
+ Builder.SetInsertPoint(InsertPt);
+
+ Value *OneElt = Builder.CreateExtractElement(Src, Idx);
+ Value *Gep = Builder.CreateConstInBoundsGEP1_32(EltTy, FirstEltPtr, Idx);
+ Builder.CreateAlignedStore(OneElt, Gep, AdjustedAlignVal);
+
+ // Create "else" block, fill it in the next iteration
+ BasicBlock *NewIfBlock =
+ CondBlock->splitBasicBlock(InsertPt->getIterator(), "else");
+ Builder.SetInsertPoint(InsertPt);
+ Instruction *OldBr = IfBlock->getTerminator();
+ BranchInst::Create(CondBlock, NewIfBlock, Predicate, OldBr);
+ OldBr->eraseFromParent();
+ IfBlock = NewIfBlock;
+ }
+ CI->eraseFromParent();
+
+ ModifiedDT = true;
+}
+
+// Translate a masked gather intrinsic like
+// <16 x i32 > @llvm.masked.gather.v16i32( <16 x i32*> %Ptrs, i32 4,
+// <16 x i1> %Mask, <16 x i32> %Src)
+// to a chain of basic blocks, with loading element one-by-one if
+// the appropriate mask bit is set
+//
+// %Ptrs = getelementptr i32, i32* %base, <16 x i64> %ind
+// %Mask0 = extractelement <16 x i1> %Mask, i32 0
+// br i1 %Mask0, label %cond.load, label %else
+//
+// cond.load:
+// %Ptr0 = extractelement <16 x i32*> %Ptrs, i32 0
+// %Load0 = load i32, i32* %Ptr0, align 4
+// %Res0 = insertelement <16 x i32> undef, i32 %Load0, i32 0
+// br label %else
+//
+// else:
+// %res.phi.else = phi <16 x i32>[%Res0, %cond.load], [undef, %0]
+// %Mask1 = extractelement <16 x i1> %Mask, i32 1
+// br i1 %Mask1, label %cond.load1, label %else2
+//
+// cond.load1:
+// %Ptr1 = extractelement <16 x i32*> %Ptrs, i32 1
+// %Load1 = load i32, i32* %Ptr1, align 4
+// %Res1 = insertelement <16 x i32> %res.phi.else, i32 %Load1, i32 1
+// br label %else2
+// . . .
+// %Result = select <16 x i1> %Mask, <16 x i32> %res.phi.select, <16 x i32> %Src
+// ret <16 x i32> %Result
+static void scalarizeMaskedGather(CallInst *CI, bool &ModifiedDT) {
+ Value *Ptrs = CI->getArgOperand(0);
+ Value *Alignment = CI->getArgOperand(1);
+ Value *Mask = CI->getArgOperand(2);
+ Value *Src0 = CI->getArgOperand(3);
+
+ auto *VecType = cast<FixedVectorType>(CI->getType());
+ Type *EltTy = VecType->getElementType();
+
+ IRBuilder<> Builder(CI->getContext());
+ Instruction *InsertPt = CI;
+ BasicBlock *IfBlock = CI->getParent();
+ Builder.SetInsertPoint(InsertPt);
+ MaybeAlign AlignVal = cast<ConstantInt>(Alignment)->getMaybeAlignValue();
+
+ Builder.SetCurrentDebugLocation(CI->getDebugLoc());
+
+ // The result vector
+ Value *VResult = Src0;
+ unsigned VectorWidth = VecType->getNumElements();
+
+ // Shorten the way if the mask is a vector of constants.
+ if (isConstantIntVector(Mask)) {
+ for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
+ if (cast<Constant>(Mask)->getAggregateElement(Idx)->isNullValue())
+ continue;
+ Value *Ptr = Builder.CreateExtractElement(Ptrs, Idx, "Ptr" + Twine(Idx));
+ LoadInst *Load =
+ Builder.CreateAlignedLoad(EltTy, Ptr, AlignVal, "Load" + Twine(Idx));
+ VResult =
+ Builder.CreateInsertElement(VResult, Load, Idx, "Res" + Twine(Idx));
+ }
+ CI->replaceAllUsesWith(VResult);
+ CI->eraseFromParent();
+ return;
+ }
+
+ // If the mask is not v1i1, use scalar bit test operations. This generates
+ // better results on X86 at least.
+ Value *SclrMask;
+ if (VectorWidth != 1) {
+ Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);
+ SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");
+ }
+
+ for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
+ // Fill the "else" block, created in the previous iteration
+ //
+ // %Mask1 = and i16 %scalar_mask, i32 1 << Idx
+ // %cond = icmp ne i16 %mask_1, 0
+ // br i1 %Mask1, label %cond.load, label %else
+ //
+
+ Value *Predicate;
+ if (VectorWidth != 1) {
+ Value *Mask = Builder.getInt(APInt::getOneBitSet(VectorWidth, Idx));
+ Predicate = Builder.CreateICmpNE(Builder.CreateAnd(SclrMask, Mask),
+ Builder.getIntN(VectorWidth, 0));
+ } else {
+ Predicate = Builder.CreateExtractElement(Mask, Idx, "Mask" + Twine(Idx));
+ }
+
+ // Create "cond" block
+ //
+ // %EltAddr = getelementptr i32* %1, i32 0
+ // %Elt = load i32* %EltAddr
+ // VResult = insertelement <16 x i32> VResult, i32 %Elt, i32 Idx
+ //
+ BasicBlock *CondBlock = IfBlock->splitBasicBlock(InsertPt, "cond.load");
+ Builder.SetInsertPoint(InsertPt);
+
+ Value *Ptr = Builder.CreateExtractElement(Ptrs, Idx, "Ptr" + Twine(Idx));
+ LoadInst *Load =
+ Builder.CreateAlignedLoad(EltTy, Ptr, AlignVal, "Load" + Twine(Idx));
+ Value *NewVResult =
+ Builder.CreateInsertElement(VResult, Load, Idx, "Res" + Twine(Idx));
+
+ // Create "else" block, fill it in the next iteration
+ BasicBlock *NewIfBlock = CondBlock->splitBasicBlock(InsertPt, "else");
+ Builder.SetInsertPoint(InsertPt);
+ Instruction *OldBr = IfBlock->getTerminator();
+ BranchInst::Create(CondBlock, NewIfBlock, Predicate, OldBr);
+ OldBr->eraseFromParent();
+ BasicBlock *PrevIfBlock = IfBlock;
+ IfBlock = NewIfBlock;
+
+ PHINode *Phi = Builder.CreatePHI(VecType, 2, "res.phi.else");
+ Phi->addIncoming(NewVResult, CondBlock);
+ Phi->addIncoming(VResult, PrevIfBlock);
+ VResult = Phi;
+ }
+
+ CI->replaceAllUsesWith(VResult);
+ CI->eraseFromParent();
+
+ ModifiedDT = true;
+}
+
+// Translate a masked scatter intrinsic, like
+// void @llvm.masked.scatter.v16i32(<16 x i32> %Src, <16 x i32*>* %Ptrs, i32 4,
+// <16 x i1> %Mask)
+// to a chain of basic blocks, that stores element one-by-one if
+// the appropriate mask bit is set.
+//
+// %Ptrs = getelementptr i32, i32* %ptr, <16 x i64> %ind
+// %Mask0 = extractelement <16 x i1> %Mask, i32 0
+// br i1 %Mask0, label %cond.store, label %else
+//
+// cond.store:
+// %Elt0 = extractelement <16 x i32> %Src, i32 0
+// %Ptr0 = extractelement <16 x i32*> %Ptrs, i32 0
+// store i32 %Elt0, i32* %Ptr0, align 4
+// br label %else
+//
+// else:
+// %Mask1 = extractelement <16 x i1> %Mask, i32 1
+// br i1 %Mask1, label %cond.store1, label %else2
+//
+// cond.store1:
+// %Elt1 = extractelement <16 x i32> %Src, i32 1
+// %Ptr1 = extractelement <16 x i32*> %Ptrs, i32 1
+// store i32 %Elt1, i32* %Ptr1, align 4
+// br label %else2
+// . . .
+static void scalarizeMaskedScatter(CallInst *CI, bool &ModifiedDT) {
+ Value *Src = CI->getArgOperand(0);
+ Value *Ptrs = CI->getArgOperand(1);
+ Value *Alignment = CI->getArgOperand(2);
+ Value *Mask = CI->getArgOperand(3);
+
+ auto *SrcFVTy = cast<FixedVectorType>(Src->getType());
+
+ assert(
+ isa<VectorType>(Ptrs->getType()) &&
+ isa<PointerType>(cast<VectorType>(Ptrs->getType())->getElementType()) &&
+ "Vector of pointers is expected in masked scatter intrinsic");
+
+ IRBuilder<> Builder(CI->getContext());
+ Instruction *InsertPt = CI;
+ BasicBlock *IfBlock = CI->getParent();
+ Builder.SetInsertPoint(InsertPt);
+ Builder.SetCurrentDebugLocation(CI->getDebugLoc());
+
+ MaybeAlign AlignVal = cast<ConstantInt>(Alignment)->getMaybeAlignValue();
+ unsigned VectorWidth = SrcFVTy->getNumElements();
+
+ // Shorten the way if the mask is a vector of constants.
+ if (isConstantIntVector(Mask)) {
+ for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
+ if (cast<Constant>(Mask)->getAggregateElement(Idx)->isNullValue())
+ continue;
+ Value *OneElt =
+ Builder.CreateExtractElement(Src, Idx, "Elt" + Twine(Idx));
+ Value *Ptr = Builder.CreateExtractElement(Ptrs, Idx, "Ptr" + Twine(Idx));
+ Builder.CreateAlignedStore(OneElt, Ptr, AlignVal);
+ }
+ CI->eraseFromParent();
+ return;
+ }
+
+ // If the mask is not v1i1, use scalar bit test operations. This generates
+ // better results on X86 at least.
+ Value *SclrMask;
+ if (VectorWidth != 1) {
+ Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);
+ SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");
+ }
+
+ for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
+ // Fill the "else" block, created in the previous iteration
+ //
+ // %Mask1 = and i16 %scalar_mask, i32 1 << Idx
+ // %cond = icmp ne i16 %mask_1, 0
+ // br i1 %Mask1, label %cond.store, label %else
+ //
+ Value *Predicate;
+ if (VectorWidth != 1) {
+ Value *Mask = Builder.getInt(APInt::getOneBitSet(VectorWidth, Idx));
+ Predicate = Builder.CreateICmpNE(Builder.CreateAnd(SclrMask, Mask),
+ Builder.getIntN(VectorWidth, 0));
+ } else {
+ Predicate = Builder.CreateExtractElement(Mask, Idx, "Mask" + Twine(Idx));
+ }
+
+ // Create "cond" block
+ //
+ // %Elt1 = extractelement <16 x i32> %Src, i32 1
+ // %Ptr1 = extractelement <16 x i32*> %Ptrs, i32 1
+ // %store i32 %Elt1, i32* %Ptr1
+ //
+ BasicBlock *CondBlock = IfBlock->splitBasicBlock(InsertPt, "cond.store");
+ Builder.SetInsertPoint(InsertPt);
+
+ Value *OneElt = Builder.CreateExtractElement(Src, Idx, "Elt" + Twine(Idx));
+ Value *Ptr = Builder.CreateExtractElement(Ptrs, Idx, "Ptr" + Twine(Idx));
+ Builder.CreateAlignedStore(OneElt, Ptr, AlignVal);
+
+ // Create "else" block, fill it in the next iteration
+ BasicBlock *NewIfBlock = CondBlock->splitBasicBlock(InsertPt, "else");
+ Builder.SetInsertPoint(InsertPt);
+ Instruction *OldBr = IfBlock->getTerminator();
+ BranchInst::Create(CondBlock, NewIfBlock, Predicate, OldBr);
+ OldBr->eraseFromParent();
+ IfBlock = NewIfBlock;
+ }
+ CI->eraseFromParent();
+
+ ModifiedDT = true;
+}
+
+static void scalarizeMaskedExpandLoad(CallInst *CI, bool &ModifiedDT) {
+ Value *Ptr = CI->getArgOperand(0);
+ Value *Mask = CI->getArgOperand(1);
+ Value *PassThru = CI->getArgOperand(2);
+
+ auto *VecType = cast<FixedVectorType>(CI->getType());
+
+ Type *EltTy = VecType->getElementType();
+
+ IRBuilder<> Builder(CI->getContext());
+ Instruction *InsertPt = CI;
+ BasicBlock *IfBlock = CI->getParent();
+
+ Builder.SetInsertPoint(InsertPt);
+ Builder.SetCurrentDebugLocation(CI->getDebugLoc());
+
+ unsigned VectorWidth = VecType->getNumElements();
+
+ // The result vector
+ Value *VResult = PassThru;
+
+ // Shorten the way if the mask is a vector of constants.
+ // Create a build_vector pattern, with loads/undefs as necessary and then
+ // shuffle blend with the pass through value.
+ if (isConstantIntVector(Mask)) {
+ unsigned MemIndex = 0;
+ VResult = UndefValue::get(VecType);
+ SmallVector<int, 16> ShuffleMask(VectorWidth, UndefMaskElem);
+ for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
+ Value *InsertElt;
+ if (cast<Constant>(Mask)->getAggregateElement(Idx)->isNullValue()) {
+ InsertElt = UndefValue::get(EltTy);
+ ShuffleMask[Idx] = Idx + VectorWidth;
+ } else {
+ Value *NewPtr =
+ Builder.CreateConstInBoundsGEP1_32(EltTy, Ptr, MemIndex);
+ InsertElt = Builder.CreateAlignedLoad(EltTy, NewPtr, Align(1),
+ "Load" + Twine(Idx));
+ ShuffleMask[Idx] = Idx;
+ ++MemIndex;
+ }
+ VResult = Builder.CreateInsertElement(VResult, InsertElt, Idx,
+ "Res" + Twine(Idx));
+ }
+ VResult = Builder.CreateShuffleVector(VResult, PassThru, ShuffleMask);
+ CI->replaceAllUsesWith(VResult);
+ CI->eraseFromParent();
+ return;
+ }
+
+ // If the mask is not v1i1, use scalar bit test operations. This generates
+ // better results on X86 at least.
+ Value *SclrMask;
+ if (VectorWidth != 1) {
+ Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);
+ SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");
+ }
+
+ for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
+ // Fill the "else" block, created in the previous iteration
+ //
+ // %res.phi.else3 = phi <16 x i32> [ %11, %cond.load1 ], [ %res.phi.else, %else ]
+ // %mask_1 = extractelement <16 x i1> %mask, i32 Idx
+ // br i1 %mask_1, label %cond.load, label %else
+ //
+
+ Value *Predicate;
+ if (VectorWidth != 1) {
+ Value *Mask = Builder.getInt(APInt::getOneBitSet(VectorWidth, Idx));
+ Predicate = Builder.CreateICmpNE(Builder.CreateAnd(SclrMask, Mask),
+ Builder.getIntN(VectorWidth, 0));
+ } else {
+ Predicate = Builder.CreateExtractElement(Mask, Idx, "Mask" + Twine(Idx));
+ }
+
+ // Create "cond" block
+ //
+ // %EltAddr = getelementptr i32* %1, i32 0
+ // %Elt = load i32* %EltAddr
+ // VResult = insertelement <16 x i32> VResult, i32 %Elt, i32 Idx
+ //
+ BasicBlock *CondBlock = IfBlock->splitBasicBlock(InsertPt->getIterator(),
+ "cond.load");
+ Builder.SetInsertPoint(InsertPt);
+
+ LoadInst *Load = Builder.CreateAlignedLoad(EltTy, Ptr, Align(1));
+ Value *NewVResult = Builder.CreateInsertElement(VResult, Load, Idx);
+
+ // Move the pointer if there are more blocks to come.
+ Value *NewPtr;
+ if ((Idx + 1) != VectorWidth)
+ NewPtr = Builder.CreateConstInBoundsGEP1_32(EltTy, Ptr, 1);
+
+ // Create "else" block, fill it in the next iteration
+ BasicBlock *NewIfBlock =
+ CondBlock->splitBasicBlock(InsertPt->getIterator(), "else");
+ Builder.SetInsertPoint(InsertPt);
+ Instruction *OldBr = IfBlock->getTerminator();
+ BranchInst::Create(CondBlock, NewIfBlock, Predicate, OldBr);
+ OldBr->eraseFromParent();
+ BasicBlock *PrevIfBlock = IfBlock;
+ IfBlock = NewIfBlock;
+
+ // Create the phi to join the new and previous value.
+ PHINode *ResultPhi = Builder.CreatePHI(VecType, 2, "res.phi.else");
+ ResultPhi->addIncoming(NewVResult, CondBlock);
+ ResultPhi->addIncoming(VResult, PrevIfBlock);
+ VResult = ResultPhi;
+
+ // Add a PHI for the pointer if this isn't the last iteration.
+ if ((Idx + 1) != VectorWidth) {
+ PHINode *PtrPhi = Builder.CreatePHI(Ptr->getType(), 2, "ptr.phi.else");
+ PtrPhi->addIncoming(NewPtr, CondBlock);
+ PtrPhi->addIncoming(Ptr, PrevIfBlock);
+ Ptr = PtrPhi;
+ }
+ }
+
+ CI->replaceAllUsesWith(VResult);
+ CI->eraseFromParent();
+
+ ModifiedDT = true;
+}
+
+static void scalarizeMaskedCompressStore(CallInst *CI, bool &ModifiedDT) {
+ Value *Src = CI->getArgOperand(0);
+ Value *Ptr = CI->getArgOperand(1);
+ Value *Mask = CI->getArgOperand(2);
+
+ auto *VecType = cast<FixedVectorType>(Src->getType());
+
+ IRBuilder<> Builder(CI->getContext());
+ Instruction *InsertPt = CI;
+ BasicBlock *IfBlock = CI->getParent();
+
+ Builder.SetInsertPoint(InsertPt);
+ Builder.SetCurrentDebugLocation(CI->getDebugLoc());
+
+ Type *EltTy = VecType->getElementType();
+
+ unsigned VectorWidth = VecType->getNumElements();
+
+ // Shorten the way if the mask is a vector of constants.
+ if (isConstantIntVector(Mask)) {
+ unsigned MemIndex = 0;
+ for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
+ if (cast<Constant>(Mask)->getAggregateElement(Idx)->isNullValue())
+ continue;
+ Value *OneElt =
+ Builder.CreateExtractElement(Src, Idx, "Elt" + Twine(Idx));
+ Value *NewPtr = Builder.CreateConstInBoundsGEP1_32(EltTy, Ptr, MemIndex);
+ Builder.CreateAlignedStore(OneElt, NewPtr, Align(1));
+ ++MemIndex;
+ }
+ CI->eraseFromParent();
+ return;
+ }
+
+ // If the mask is not v1i1, use scalar bit test operations. This generates
+ // better results on X86 at least.
+ Value *SclrMask;
+ if (VectorWidth != 1) {
+ Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);
+ SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");
+ }
+
+ for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
+ // Fill the "else" block, created in the previous iteration
+ //
+ // %mask_1 = extractelement <16 x i1> %mask, i32 Idx
+ // br i1 %mask_1, label %cond.store, label %else
+ //
+ Value *Predicate;
+ if (VectorWidth != 1) {
+ Value *Mask = Builder.getInt(APInt::getOneBitSet(VectorWidth, Idx));
+ Predicate = Builder.CreateICmpNE(Builder.CreateAnd(SclrMask, Mask),
+ Builder.getIntN(VectorWidth, 0));
+ } else {
+ Predicate = Builder.CreateExtractElement(Mask, Idx, "Mask" + Twine(Idx));
+ }
+
+ // Create "cond" block
+ //
+ // %OneElt = extractelement <16 x i32> %Src, i32 Idx
+ // %EltAddr = getelementptr i32* %1, i32 0
+ // %store i32 %OneElt, i32* %EltAddr
+ //
+ BasicBlock *CondBlock =
+ IfBlock->splitBasicBlock(InsertPt->getIterator(), "cond.store");
+ Builder.SetInsertPoint(InsertPt);
+
+ Value *OneElt = Builder.CreateExtractElement(Src, Idx);
+ Builder.CreateAlignedStore(OneElt, Ptr, Align(1));
+
+ // Move the pointer if there are more blocks to come.
+ Value *NewPtr;
+ if ((Idx + 1) != VectorWidth)
+ NewPtr = Builder.CreateConstInBoundsGEP1_32(EltTy, Ptr, 1);
+
+ // Create "else" block, fill it in the next iteration
+ BasicBlock *NewIfBlock =
+ CondBlock->splitBasicBlock(InsertPt->getIterator(), "else");
+ Builder.SetInsertPoint(InsertPt);
+ Instruction *OldBr = IfBlock->getTerminator();
+ BranchInst::Create(CondBlock, NewIfBlock, Predicate, OldBr);
+ OldBr->eraseFromParent();
+ BasicBlock *PrevIfBlock = IfBlock;
+ IfBlock = NewIfBlock;
+
+ // Add a PHI for the pointer if this isn't the last iteration.
+ if ((Idx + 1) != VectorWidth) {
+ PHINode *PtrPhi = Builder.CreatePHI(Ptr->getType(), 2, "ptr.phi.else");
+ PtrPhi->addIncoming(NewPtr, CondBlock);
+ PtrPhi->addIncoming(Ptr, PrevIfBlock);
+ Ptr = PtrPhi;
+ }
+ }
+ CI->eraseFromParent();
+
+ ModifiedDT = true;
+}
+
+static bool runImpl(Function &F, const TargetTransformInfo &TTI) {
+ bool EverMadeChange = false;
+ bool MadeChange = true;
+ auto &DL = F.getParent()->getDataLayout();
+ while (MadeChange) {
+ MadeChange = false;
+ for (Function::iterator I = F.begin(); I != F.end();) {
+ BasicBlock *BB = &*I++;
+ bool ModifiedDTOnIteration = false;
+ MadeChange |= optimizeBlock(*BB, ModifiedDTOnIteration, TTI, DL);
+
+ // Restart BB iteration if the dominator tree of the Function was changed
+ if (ModifiedDTOnIteration)
+ break;
+ }
+
+ EverMadeChange |= MadeChange;
+ }
+ return EverMadeChange;
+}
+
+bool ScalarizeMaskedMemIntrinLegacyPass::runOnFunction(Function &F) {
+ auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
+ return runImpl(F, TTI);
+}
+
+PreservedAnalyses
+ScalarizeMaskedMemIntrinPass::run(Function &F, FunctionAnalysisManager &AM) {
+ auto &TTI = AM.getResult<TargetIRAnalysis>(F);
+ if (!runImpl(F, TTI))
+ return PreservedAnalyses::all();
+ PreservedAnalyses PA;
+ PA.preserve<TargetIRAnalysis>();
+ return PA;
+}
+
+static bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT,
+ const TargetTransformInfo &TTI,
+ const DataLayout &DL) {
+ bool MadeChange = false;
+
+ BasicBlock::iterator CurInstIterator = BB.begin();
+ while (CurInstIterator != BB.end()) {
+ if (CallInst *CI = dyn_cast<CallInst>(&*CurInstIterator++))
+ MadeChange |= optimizeCallInst(CI, ModifiedDT, TTI, DL);
+ if (ModifiedDT)
+ return true;
+ }
+
+ return MadeChange;
+}
+
+static bool optimizeCallInst(CallInst *CI, bool &ModifiedDT,
+ const TargetTransformInfo &TTI,
+ const DataLayout &DL) {
+ IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI);
+ if (II) {
+ // The scalarization code below does not work for scalable vectors.
+ if (isa<ScalableVectorType>(II->getType()) ||
+ any_of(II->arg_operands(),
+ [](Value *V) { return isa<ScalableVectorType>(V->getType()); }))
+ return false;
+
+ switch (II->getIntrinsicID()) {
+ default:
+ break;
+ case Intrinsic::masked_load:
+ // Scalarize unsupported vector masked load
+ if (TTI.isLegalMaskedLoad(
+ CI->getType(),
+ cast<ConstantInt>(CI->getArgOperand(1))->getAlignValue()))
+ return false;
+ scalarizeMaskedLoad(CI, ModifiedDT);
+ return true;
+ case Intrinsic::masked_store:
+ if (TTI.isLegalMaskedStore(
+ CI->getArgOperand(0)->getType(),
+ cast<ConstantInt>(CI->getArgOperand(2))->getAlignValue()))
+ return false;
+ scalarizeMaskedStore(CI, ModifiedDT);
+ return true;
+ case Intrinsic::masked_gather: {
+ unsigned AlignmentInt =
+ cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
+ Type *LoadTy = CI->getType();
+ Align Alignment =
+ DL.getValueOrABITypeAlignment(MaybeAlign(AlignmentInt), LoadTy);
+ if (TTI.isLegalMaskedGather(LoadTy, Alignment))
+ return false;
+ scalarizeMaskedGather(CI, ModifiedDT);
+ return true;
+ }
+ case Intrinsic::masked_scatter: {
+ unsigned AlignmentInt =
+ cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
+ Type *StoreTy = CI->getArgOperand(0)->getType();
+ Align Alignment =
+ DL.getValueOrABITypeAlignment(MaybeAlign(AlignmentInt), StoreTy);
+ if (TTI.isLegalMaskedScatter(StoreTy, Alignment))
+ return false;
+ scalarizeMaskedScatter(CI, ModifiedDT);
+ return true;
+ }
+ case Intrinsic::masked_expandload:
+ if (TTI.isLegalMaskedExpandLoad(CI->getType()))
+ return false;
+ scalarizeMaskedExpandLoad(CI, ModifiedDT);
+ return true;
+ case Intrinsic::masked_compressstore:
+ if (TTI.isLegalMaskedCompressStore(CI->getArgOperand(0)->getType()))
+ return false;
+ scalarizeMaskedCompressStore(CI, ModifiedDT);
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/Scalarizer.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/Scalarizer.cpp
index 130793abff..c95984fe19 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/Scalarizer.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/Scalarizer.cpp
@@ -398,8 +398,8 @@ void ScalarizerVisitor::gather(Instruction *Op, const ValueVector &CV) {
continue;
Instruction *Old = cast<Instruction>(V);
- if (isa<Instruction>(CV[I]))
- CV[I]->takeName(Old);
+ if (isa<Instruction>(CV[I]))
+ CV[I]->takeName(Old);
Old->replaceAllUsesWith(CV[I]);
PotentiallyDeadInstrs.emplace_back(Old);
}
@@ -733,7 +733,7 @@ bool ScalarizerVisitor::visitBitCastInst(BitCastInst &BCI) {
auto *MidTy = FixedVectorType::get(SrcVT->getElementType(), FanIn);
unsigned Op0I = 0;
for (unsigned ResI = 0; ResI < DstNumElems; ++ResI) {
- Value *V = PoisonValue::get(MidTy);
+ Value *V = PoisonValue::get(MidTy);
for (unsigned MidI = 0; MidI < FanIn; ++MidI)
V = Builder.CreateInsertElement(V, Op0[Op0I++], Builder.getInt32(MidI),
BCI.getName() + ".i" + Twine(ResI)
@@ -932,7 +932,7 @@ bool ScalarizerVisitor::finish() {
if (!Op->use_empty()) {
// The value is still needed, so recreate it using a series of
// InsertElements.
- Value *Res = PoisonValue::get(Op->getType());
+ Value *Res = PoisonValue::get(Op->getType());
if (auto *Ty = dyn_cast<VectorType>(Op->getType())) {
BasicBlock *BB = Op->getParent();
unsigned Count = cast<FixedVectorType>(Ty)->getNumElements();
@@ -942,7 +942,7 @@ bool ScalarizerVisitor::finish() {
for (unsigned I = 0; I < Count; ++I)
Res = Builder.CreateInsertElement(Res, CV[I], Builder.getInt32(I),
Op->getName() + ".upto" + Twine(I));
- Res->takeName(Op);
+ Res->takeName(Op);
} else {
assert(CV.size() == 1 && Op->getType() == CV[0]->getType());
Res = CV[0];
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp
index c63a069193..f216956406 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp
@@ -155,7 +155,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h"
+#include "llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DepthFirstIterator.h"
@@ -178,7 +178,7 @@
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
@@ -344,14 +344,14 @@ private:
/// A pass that tries to split every GEP in the function into a variadic
/// base and a constant offset. It is a FunctionPass because searching for the
/// constant offset may inspect other basic blocks.
-class SeparateConstOffsetFromGEPLegacyPass : public FunctionPass {
+class SeparateConstOffsetFromGEPLegacyPass : public FunctionPass {
public:
static char ID;
- SeparateConstOffsetFromGEPLegacyPass(bool LowerGEP = false)
+ SeparateConstOffsetFromGEPLegacyPass(bool LowerGEP = false)
: FunctionPass(ID), LowerGEP(LowerGEP) {
- initializeSeparateConstOffsetFromGEPLegacyPassPass(
- *PassRegistry::getPassRegistry());
+ initializeSeparateConstOffsetFromGEPLegacyPassPass(
+ *PassRegistry::getPassRegistry());
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -366,23 +366,23 @@ public:
bool runOnFunction(Function &F) override;
private:
- bool LowerGEP;
-};
-
-/// A pass that tries to split every GEP in the function into a variadic
-/// base and a constant offset. It is a FunctionPass because searching for the
-/// constant offset may inspect other basic blocks.
-class SeparateConstOffsetFromGEP {
-public:
- SeparateConstOffsetFromGEP(
- DominatorTree *DT, ScalarEvolution *SE, LoopInfo *LI,
- TargetLibraryInfo *TLI,
- function_ref<TargetTransformInfo &(Function &)> GetTTI, bool LowerGEP)
- : DT(DT), SE(SE), LI(LI), TLI(TLI), GetTTI(GetTTI), LowerGEP(LowerGEP) {}
-
- bool run(Function &F);
-
-private:
+ bool LowerGEP;
+};
+
+/// A pass that tries to split every GEP in the function into a variadic
+/// base and a constant offset. It is a FunctionPass because searching for the
+/// constant offset may inspect other basic blocks.
+class SeparateConstOffsetFromGEP {
+public:
+ SeparateConstOffsetFromGEP(
+ DominatorTree *DT, ScalarEvolution *SE, LoopInfo *LI,
+ TargetLibraryInfo *TLI,
+ function_ref<TargetTransformInfo &(Function &)> GetTTI, bool LowerGEP)
+ : DT(DT), SE(SE), LI(LI), TLI(TLI), GetTTI(GetTTI), LowerGEP(LowerGEP) {}
+
+ bool run(Function &F);
+
+private:
/// Tries to split the given GEP into a variadic base and a constant offset,
/// and returns true if the splitting succeeds.
bool splitGEP(GetElementPtrInst *GEP);
@@ -467,8 +467,8 @@ private:
ScalarEvolution *SE;
LoopInfo *LI;
TargetLibraryInfo *TLI;
- // Retrieved lazily since not always used.
- function_ref<TargetTransformInfo &(Function &)> GetTTI;
+ // Retrieved lazily since not always used.
+ function_ref<TargetTransformInfo &(Function &)> GetTTI;
/// Whether to lower a GEP with multiple indices into arithmetic operations or
/// multiple GEPs with a single index.
@@ -480,10 +480,10 @@ private:
} // end anonymous namespace
-char SeparateConstOffsetFromGEPLegacyPass::ID = 0;
+char SeparateConstOffsetFromGEPLegacyPass::ID = 0;
INITIALIZE_PASS_BEGIN(
- SeparateConstOffsetFromGEPLegacyPass, "separate-const-offset-from-gep",
+ SeparateConstOffsetFromGEPLegacyPass, "separate-const-offset-from-gep",
"Split GEPs to a variadic base and a constant offset for better CSE", false,
false)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
@@ -492,12 +492,12 @@ INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_END(
- SeparateConstOffsetFromGEPLegacyPass, "separate-const-offset-from-gep",
+ SeparateConstOffsetFromGEPLegacyPass, "separate-const-offset-from-gep",
"Split GEPs to a variadic base and a constant offset for better CSE", false,
false)
FunctionPass *llvm::createSeparateConstOffsetFromGEPPass(bool LowerGEP) {
- return new SeparateConstOffsetFromGEPLegacyPass(LowerGEP);
+ return new SeparateConstOffsetFromGEPLegacyPass(LowerGEP);
}
bool ConstantOffsetExtractor::CanTraceInto(bool SignExtended,
@@ -902,8 +902,8 @@ void SeparateConstOffsetFromGEP::lowerToSingleIndexGEPs(
// If we created a GEP with constant index, and the base is loop invariant,
// then we swap the first one with it, so LICM can move constant GEP out
// later.
- auto *FirstGEP = dyn_cast_or_null<GetElementPtrInst>(FirstResult);
- auto *SecondGEP = dyn_cast<GetElementPtrInst>(ResultPtr);
+ auto *FirstGEP = dyn_cast_or_null<GetElementPtrInst>(FirstResult);
+ auto *SecondGEP = dyn_cast<GetElementPtrInst>(ResultPtr);
if (isSwapCandidate && isLegalToSwapOperand(FirstGEP, SecondGEP, L))
swapGEPOperand(FirstGEP, SecondGEP);
@@ -978,7 +978,7 @@ bool SeparateConstOffsetFromGEP::splitGEP(GetElementPtrInst *GEP) {
if (!NeedsExtraction)
return Changed;
- TargetTransformInfo &TTI = GetTTI(*GEP->getFunction());
+ TargetTransformInfo &TTI = GetTTI(*GEP->getFunction());
// If LowerGEP is disabled, before really splitting the GEP, check whether the
// backend supports the addressing mode we are about to produce. If no, this
@@ -1143,25 +1143,25 @@ bool SeparateConstOffsetFromGEP::splitGEP(GetElementPtrInst *GEP) {
return true;
}
-bool SeparateConstOffsetFromGEPLegacyPass::runOnFunction(Function &F) {
+bool SeparateConstOffsetFromGEPLegacyPass::runOnFunction(Function &F) {
if (skipFunction(F))
return false;
- auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
- auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
- auto GetTTI = [this](Function &F) -> TargetTransformInfo & {
- return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
- };
- SeparateConstOffsetFromGEP Impl(DT, SE, LI, TLI, GetTTI, LowerGEP);
- return Impl.run(F);
-}
-
-bool SeparateConstOffsetFromGEP::run(Function &F) {
+ auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
+ auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
+ auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
+ auto GetTTI = [this](Function &F) -> TargetTransformInfo & {
+ return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
+ };
+ SeparateConstOffsetFromGEP Impl(DT, SE, LI, TLI, GetTTI, LowerGEP);
+ return Impl.run(F);
+}
+
+bool SeparateConstOffsetFromGEP::run(Function &F) {
if (DisableSeparateConstOffsetFromGEP)
return false;
- DL = &F.getParent()->getDataLayout();
+ DL = &F.getParent()->getDataLayout();
bool Changed = false;
for (BasicBlock &B : F) {
for (BasicBlock::iterator I = B.begin(), IE = B.end(); I != IE;)
@@ -1368,20 +1368,20 @@ void SeparateConstOffsetFromGEP::swapGEPOperand(GetElementPtrInst *First,
} else
First->setIsInBounds(true);
}
-
-PreservedAnalyses
-SeparateConstOffsetFromGEPPass::run(Function &F, FunctionAnalysisManager &AM) {
- auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
- auto *SE = &AM.getResult<ScalarEvolutionAnalysis>(F);
- auto *LI = &AM.getResult<LoopAnalysis>(F);
- auto *TLI = &AM.getResult<TargetLibraryAnalysis>(F);
- auto GetTTI = [&AM](Function &F) -> TargetTransformInfo & {
- return AM.getResult<TargetIRAnalysis>(F);
- };
- SeparateConstOffsetFromGEP Impl(DT, SE, LI, TLI, GetTTI, LowerGEP);
- if (!Impl.run(F))
- return PreservedAnalyses::all();
- PreservedAnalyses PA;
- PA.preserveSet<CFGAnalyses>();
- return PA;
-}
+
+PreservedAnalyses
+SeparateConstOffsetFromGEPPass::run(Function &F, FunctionAnalysisManager &AM) {
+ auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
+ auto *SE = &AM.getResult<ScalarEvolutionAnalysis>(F);
+ auto *LI = &AM.getResult<LoopAnalysis>(F);
+ auto *TLI = &AM.getResult<TargetLibraryAnalysis>(F);
+ auto GetTTI = [&AM](Function &F) -> TargetTransformInfo & {
+ return AM.getResult<TargetIRAnalysis>(F);
+ };
+ SeparateConstOffsetFromGEP Impl(DT, SE, LI, TLI, GetTTI, LowerGEP);
+ if (!Impl.run(F))
+ return PreservedAnalyses::all();
+ PreservedAnalyses PA;
+ PA.preserveSet<CFGAnalyses>();
+ return PA;
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
index 8318870308..9d3c8d0f37 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
@@ -26,14 +26,14 @@
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/MemorySSA.h"
#include "llvm/Analysis/MemorySSAUpdater.h"
-#include "llvm/Analysis/MustExecute.h"
-#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/MustExecute.h"
+#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
-#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
@@ -51,7 +51,7 @@
#include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Cloning.h"
-#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include <algorithm>
@@ -96,11 +96,11 @@ static cl::opt<bool> UnswitchGuards(
"simple-loop-unswitch-guards", cl::init(true), cl::Hidden,
cl::desc("If enabled, simple loop unswitching will also consider "
"llvm.experimental.guard intrinsics as unswitch candidates."));
-static cl::opt<bool> DropNonTrivialImplicitNullChecks(
- "simple-loop-unswitch-drop-non-trivial-implicit-null-checks",
- cl::init(false), cl::Hidden,
- cl::desc("If enabled, drop make.implicit metadata in unswitched implicit "
- "null checks to save time analyzing if we can keep it."));
+static cl::opt<bool> DropNonTrivialImplicitNullChecks(
+ "simple-loop-unswitch-drop-non-trivial-implicit-null-checks",
+ cl::init(false), cl::Hidden,
+ cl::desc("If enabled, drop make.implicit metadata in unswitched implicit "
+ "null checks to save time analyzing if we can keep it."));
/// Collect all of the loop invariant input values transitively used by the
/// homogeneous instruction graph from a given root.
@@ -692,9 +692,9 @@ static bool unswitchTrivialSwitch(Loop &L, SwitchInst &SI, DominatorTree &DT,
// successor.
BasicBlock *CommonSuccBB = nullptr;
if (SI.getNumCases() > 0 &&
- all_of(drop_begin(SI.cases()), [&SI](const SwitchInst::CaseHandle &Case) {
- return Case.getCaseSuccessor() == SI.case_begin()->getCaseSuccessor();
- }))
+ all_of(drop_begin(SI.cases()), [&SI](const SwitchInst::CaseHandle &Case) {
+ return Case.getCaseSuccessor() == SI.case_begin()->getCaseSuccessor();
+ }))
CommonSuccBB = SI.case_begin()->getCaseSuccessor();
if (!DefaultExitBB) {
// If we're not unswitching the default, we need it to match any cases to
@@ -855,11 +855,11 @@ static bool unswitchTrivialSwitch(Loop &L, SwitchInst &SI, DominatorTree &DT,
}
if (MSSAU) {
- MSSAU->applyUpdates(DTUpdates, DT, /*UpdateDT=*/true);
+ MSSAU->applyUpdates(DTUpdates, DT, /*UpdateDT=*/true);
if (VerifyMemorySSA)
MSSAU->getMemorySSA()->verifyMemorySSA();
- } else {
- DT.applyUpdates(DTUpdates);
+ } else {
+ DT.applyUpdates(DTUpdates);
}
assert(DT.verify(DominatorTree::VerificationLevel::Fast));
@@ -1140,22 +1140,22 @@ static BasicBlock *buildClonedLoopBlocks(
// Replace the cloned branch with an unconditional branch to the cloned
// unswitched successor.
auto *ClonedSuccBB = cast<BasicBlock>(VMap.lookup(UnswitchedSuccBB));
- Instruction *ClonedTerminator = ClonedParentBB->getTerminator();
- // Trivial Simplification. If Terminator is a conditional branch and
- // condition becomes dead - erase it.
- Value *ClonedConditionToErase = nullptr;
- if (auto *BI = dyn_cast<BranchInst>(ClonedTerminator))
- ClonedConditionToErase = BI->getCondition();
- else if (auto *SI = dyn_cast<SwitchInst>(ClonedTerminator))
- ClonedConditionToErase = SI->getCondition();
-
- ClonedTerminator->eraseFromParent();
+ Instruction *ClonedTerminator = ClonedParentBB->getTerminator();
+ // Trivial Simplification. If Terminator is a conditional branch and
+ // condition becomes dead - erase it.
+ Value *ClonedConditionToErase = nullptr;
+ if (auto *BI = dyn_cast<BranchInst>(ClonedTerminator))
+ ClonedConditionToErase = BI->getCondition();
+ else if (auto *SI = dyn_cast<SwitchInst>(ClonedTerminator))
+ ClonedConditionToErase = SI->getCondition();
+
+ ClonedTerminator->eraseFromParent();
BranchInst::Create(ClonedSuccBB, ClonedParentBB);
- if (ClonedConditionToErase)
- RecursivelyDeleteTriviallyDeadInstructions(ClonedConditionToErase, nullptr,
- MSSAU);
-
+ if (ClonedConditionToErase)
+ RecursivelyDeleteTriviallyDeadInstructions(ClonedConditionToErase, nullptr,
+ MSSAU);
+
// If there are duplicate entries in the PHI nodes because of multiple edges
// to the unswitched successor, we need to nuke all but one as we replaced it
// with a direct branch.
@@ -1214,7 +1214,7 @@ static Loop *cloneLoopNest(Loop &OrigRootL, Loop *RootParentL,
LI.addTopLevelLoop(ClonedRootL);
AddClonedBlocksToLoop(OrigRootL, *ClonedRootL);
- if (OrigRootL.isInnermost())
+ if (OrigRootL.isInnermost())
return ClonedRootL;
// If we have a nest, we can quickly clone the entire loop nest using an
@@ -2090,23 +2090,23 @@ static void unswitchNontrivialInvariants(
DominatingSucc, *VMaps.back(), DTUpdates, AC, DT, LI, MSSAU);
}
- // Drop metadata if we may break its semantics by moving this instr into the
- // split block.
- if (TI.getMetadata(LLVMContext::MD_make_implicit)) {
- if (DropNonTrivialImplicitNullChecks)
- // Do not spend time trying to understand if we can keep it, just drop it
- // to save compile time.
- TI.setMetadata(LLVMContext::MD_make_implicit, nullptr);
- else {
- // It is only legal to preserve make.implicit metadata if we are
- // guaranteed no reach implicit null check after following this branch.
- ICFLoopSafetyInfo SafetyInfo;
- SafetyInfo.computeLoopSafetyInfo(&L);
- if (!SafetyInfo.isGuaranteedToExecute(TI, &DT, &L))
- TI.setMetadata(LLVMContext::MD_make_implicit, nullptr);
- }
- }
-
+ // Drop metadata if we may break its semantics by moving this instr into the
+ // split block.
+ if (TI.getMetadata(LLVMContext::MD_make_implicit)) {
+ if (DropNonTrivialImplicitNullChecks)
+ // Do not spend time trying to understand if we can keep it, just drop it
+ // to save compile time.
+ TI.setMetadata(LLVMContext::MD_make_implicit, nullptr);
+ else {
+ // It is only legal to preserve make.implicit metadata if we are
+ // guaranteed no reach implicit null check after following this branch.
+ ICFLoopSafetyInfo SafetyInfo;
+ SafetyInfo.computeLoopSafetyInfo(&L);
+ if (!SafetyInfo.isGuaranteedToExecute(TI, &DT, &L))
+ TI.setMetadata(LLVMContext::MD_make_implicit, nullptr);
+ }
+ }
+
// The stitching of the branched code back together depends on whether we're
// doing full unswitching or not with the exception that we always want to
// nuke the initial terminator placed in the split block.
@@ -2353,12 +2353,12 @@ static void unswitchNontrivialInvariants(
for (Loop *UpdatedL :
llvm::concat<Loop *>(NonChildClonedLoops, HoistedLoops)) {
UpdateLoop(*UpdatedL);
- if (UpdatedL->isOutermost())
+ if (UpdatedL->isOutermost())
OuterExitL = nullptr;
}
if (IsStillLoop) {
UpdateLoop(L);
- if (L.isOutermost())
+ if (L.isOutermost())
OuterExitL = nullptr;
}
@@ -2706,10 +2706,10 @@ unswitchBestCondition(Loop &L, DominatorTree &DT, LoopInfo &LI,
// (convergent, noduplicate, or cross-basic-block tokens).
// FIXME: We might be able to safely handle some of these in non-duplicated
// regions.
- TargetTransformInfo::TargetCostKind CostKind =
- L.getHeader()->getParent()->hasMinSize()
- ? TargetTransformInfo::TCK_CodeSize
- : TargetTransformInfo::TCK_SizeAndLatency;
+ TargetTransformInfo::TargetCostKind CostKind =
+ L.getHeader()->getParent()->hasMinSize()
+ ? TargetTransformInfo::TCK_CodeSize
+ : TargetTransformInfo::TCK_SizeAndLatency;
int LoopCost = 0;
for (auto *BB : L.blocks()) {
int Cost = 0;
@@ -2723,7 +2723,7 @@ unswitchBestCondition(Loop &L, DominatorTree &DT, LoopInfo &LI,
if (CB->isConvergent() || CB->cannotDuplicate())
return false;
- Cost += TTI.getUserCost(&I, CostKind);
+ Cost += TTI.getUserCost(&I, CostKind);
}
assert(Cost >= 0 && "Must not have negative costs!");
LoopCost += Cost;
@@ -2904,10 +2904,10 @@ static bool unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI,
if (!NonTrivial && !EnableNonTrivialUnswitch)
return false;
- // Skip non-trivial unswitching for optsize functions.
- if (L.getHeader()->getParent()->hasOptSize())
- return false;
-
+ // Skip non-trivial unswitching for optsize functions.
+ if (L.getHeader()->getParent()->hasOptSize())
+ return false;
+
// For non-trivial unswitching, because it often creates new loops, we rely on
// the pass manager to iterate on the loops rather than trying to immediately
// reach a fixed point. There is no substantial advantage to iterating
@@ -2920,7 +2920,7 @@ static bool unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI,
return true;
// No other opportunities to unswitch.
- return false;
+ return false;
}
PreservedAnalyses SimpleLoopUnswitchPass::run(Loop &L, LoopAnalysisManager &AM,
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/SimplifyCFGPass.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/SimplifyCFGPass.cpp
index 7fdd5c659d..38e7109ead 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/SimplifyCFGPass.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/SimplifyCFGPass.cpp
@@ -25,25 +25,25 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/CFG.h"
-#include "llvm/Analysis/DomTreeUpdater.h"
+#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Dominators.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Scalar/SimplifyCFG.h"
#include "llvm/Transforms/Utils/Local.h"
-#include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
+#include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
#include <utility>
using namespace llvm;
@@ -65,10 +65,10 @@ static cl::opt<bool> UserForwardSwitchCond(
"forward-switch-cond", cl::Hidden, cl::init(false),
cl::desc("Forward switch condition to phi ops (default = false)"));
-static cl::opt<bool> UserHoistCommonInsts(
- "hoist-common-insts", cl::Hidden, cl::init(false),
- cl::desc("hoist common instructions (default = false)"));
-
+static cl::opt<bool> UserHoistCommonInsts(
+ "hoist-common-insts", cl::Hidden, cl::init(false),
+ cl::desc("hoist common instructions (default = false)"));
+
static cl::opt<bool> UserSinkCommonInsts(
"sink-common-insts", cl::Hidden, cl::init(false),
cl::desc("Sink common instructions (default = false)"));
@@ -78,18 +78,18 @@ STATISTIC(NumSimpl, "Number of blocks simplified");
/// If we have more than one empty (other than phi node) return blocks,
/// merge them together to promote recursive block merging.
-static bool mergeEmptyReturnBlocks(Function &F, DomTreeUpdater *DTU) {
+static bool mergeEmptyReturnBlocks(Function &F, DomTreeUpdater *DTU) {
bool Changed = false;
- std::vector<DominatorTree::UpdateType> Updates;
- SmallVector<BasicBlock *, 8> DeadBlocks;
-
+ std::vector<DominatorTree::UpdateType> Updates;
+ SmallVector<BasicBlock *, 8> DeadBlocks;
+
BasicBlock *RetBlock = nullptr;
// Scan all the blocks in the function, looking for empty return blocks.
- for (BasicBlock &BB : make_early_inc_range(F)) {
- if (DTU && DTU->isBBPendingDeletion(&BB))
- continue;
+ for (BasicBlock &BB : make_early_inc_range(F)) {
+ if (DTU && DTU->isBBPendingDeletion(&BB))
+ continue;
// Only look at return blocks.
ReturnInst *Ret = dyn_cast<ReturnInst>(BB.getTerminator());
@@ -140,18 +140,18 @@ static bool mergeEmptyReturnBlocks(Function &F, DomTreeUpdater *DTU) {
if (Ret->getNumOperands() == 0 ||
Ret->getOperand(0) ==
cast<ReturnInst>(RetBlock->getTerminator())->getOperand(0)) {
- // All predecessors of BB should now branch to RetBlock instead.
- if (DTU) {
- for (auto *Predecessor : predecessors(&BB)) {
- // But, iff Predecessor already branches to RetBlock,
- // don't (re-)add DomTree edge, because it already exists.
- if (!is_contained(successors(Predecessor), RetBlock))
- Updates.push_back({DominatorTree::Insert, Predecessor, RetBlock});
- Updates.push_back({DominatorTree::Delete, Predecessor, &BB});
- }
- }
+ // All predecessors of BB should now branch to RetBlock instead.
+ if (DTU) {
+ for (auto *Predecessor : predecessors(&BB)) {
+ // But, iff Predecessor already branches to RetBlock,
+ // don't (re-)add DomTree edge, because it already exists.
+ if (!is_contained(successors(Predecessor), RetBlock))
+ Updates.push_back({DominatorTree::Insert, Predecessor, RetBlock});
+ Updates.push_back({DominatorTree::Delete, Predecessor, &BB});
+ }
+ }
BB.replaceAllUsesWith(RetBlock);
- DeadBlocks.emplace_back(&BB);
+ DeadBlocks.emplace_back(&BB);
continue;
}
@@ -175,55 +175,55 @@ static bool mergeEmptyReturnBlocks(Function &F, DomTreeUpdater *DTU) {
RetBlockPHI->addIncoming(Ret->getOperand(0), &BB);
BB.getTerminator()->eraseFromParent();
BranchInst::Create(RetBlock, &BB);
- if (DTU)
- Updates.push_back({DominatorTree::Insert, &BB, RetBlock});
+ if (DTU)
+ Updates.push_back({DominatorTree::Insert, &BB, RetBlock});
+ }
+
+ if (DTU) {
+ DTU->applyUpdates(Updates);
+ for (auto *BB : DeadBlocks)
+ DTU->deleteBB(BB);
+ } else {
+ for (auto *BB : DeadBlocks)
+ BB->eraseFromParent();
}
- if (DTU) {
- DTU->applyUpdates(Updates);
- for (auto *BB : DeadBlocks)
- DTU->deleteBB(BB);
- } else {
- for (auto *BB : DeadBlocks)
- BB->eraseFromParent();
- }
-
return Changed;
}
/// Call SimplifyCFG on all the blocks in the function,
/// iterating until no more changes are made.
static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
- DomTreeUpdater *DTU,
+ DomTreeUpdater *DTU,
const SimplifyCFGOptions &Options) {
bool Changed = false;
bool LocalChange = true;
SmallVector<std::pair<const BasicBlock *, const BasicBlock *>, 32> Edges;
FindFunctionBackedges(F, Edges);
- SmallPtrSet<BasicBlock *, 16> UniqueLoopHeaders;
+ SmallPtrSet<BasicBlock *, 16> UniqueLoopHeaders;
for (unsigned i = 0, e = Edges.size(); i != e; ++i)
- UniqueLoopHeaders.insert(const_cast<BasicBlock *>(Edges[i].second));
+ UniqueLoopHeaders.insert(const_cast<BasicBlock *>(Edges[i].second));
+
+ SmallVector<WeakVH, 16> LoopHeaders(UniqueLoopHeaders.begin(),
+ UniqueLoopHeaders.end());
- SmallVector<WeakVH, 16> LoopHeaders(UniqueLoopHeaders.begin(),
- UniqueLoopHeaders.end());
-
while (LocalChange) {
LocalChange = false;
// Loop over all of the basic blocks and remove them if they are unneeded.
for (Function::iterator BBIt = F.begin(); BBIt != F.end(); ) {
- BasicBlock &BB = *BBIt++;
- if (DTU) {
- assert(
- !DTU->isBBPendingDeletion(&BB) &&
- "Should not end up trying to simplify blocks marked for removal.");
- // Make sure that the advanced iterator does not point at the blocks
- // that are marked for removal, skip over all such blocks.
- while (BBIt != F.end() && DTU->isBBPendingDeletion(&*BBIt))
- ++BBIt;
- }
- if (simplifyCFG(&BB, TTI, DTU, Options, LoopHeaders)) {
+ BasicBlock &BB = *BBIt++;
+ if (DTU) {
+ assert(
+ !DTU->isBBPendingDeletion(&BB) &&
+ "Should not end up trying to simplify blocks marked for removal.");
+ // Make sure that the advanced iterator does not point at the blocks
+ // that are marked for removal, skip over all such blocks.
+ while (BBIt != F.end() && DTU->isBBPendingDeletion(&*BBIt))
+ ++BBIt;
+ }
+ if (simplifyCFG(&BB, TTI, DTU, Options, LoopHeaders)) {
LocalChange = true;
++NumSimpl;
}
@@ -233,15 +233,15 @@ static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
return Changed;
}
-static bool simplifyFunctionCFGImpl(Function &F, const TargetTransformInfo &TTI,
- DominatorTree *DT,
- const SimplifyCFGOptions &Options) {
- DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
+static bool simplifyFunctionCFGImpl(Function &F, const TargetTransformInfo &TTI,
+ DominatorTree *DT,
+ const SimplifyCFGOptions &Options) {
+ DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
+
+ bool EverChanged = removeUnreachableBlocks(F, DT ? &DTU : nullptr);
+ EverChanged |= mergeEmptyReturnBlocks(F, DT ? &DTU : nullptr);
+ EverChanged |= iterativelySimplifyCFG(F, TTI, DT ? &DTU : nullptr, Options);
- bool EverChanged = removeUnreachableBlocks(F, DT ? &DTU : nullptr);
- EverChanged |= mergeEmptyReturnBlocks(F, DT ? &DTU : nullptr);
- EverChanged |= iterativelySimplifyCFG(F, TTI, DT ? &DTU : nullptr, Options);
-
// If neither pass changed anything, we're done.
if (!EverChanged) return false;
@@ -250,75 +250,75 @@ static bool simplifyFunctionCFGImpl(Function &F, const TargetTransformInfo &TTI,
// iterate between the two optimizations. We structure the code like this to
// avoid rerunning iterativelySimplifyCFG if the second pass of
// removeUnreachableBlocks doesn't do anything.
- if (!removeUnreachableBlocks(F, DT ? &DTU : nullptr))
+ if (!removeUnreachableBlocks(F, DT ? &DTU : nullptr))
return true;
do {
- EverChanged = iterativelySimplifyCFG(F, TTI, DT ? &DTU : nullptr, Options);
- EverChanged |= removeUnreachableBlocks(F, DT ? &DTU : nullptr);
+ EverChanged = iterativelySimplifyCFG(F, TTI, DT ? &DTU : nullptr, Options);
+ EverChanged |= removeUnreachableBlocks(F, DT ? &DTU : nullptr);
} while (EverChanged);
return true;
}
-static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI,
- DominatorTree *DT,
- const SimplifyCFGOptions &Options) {
- assert((!RequireAndPreserveDomTree ||
- (DT && DT->verify(DominatorTree::VerificationLevel::Full))) &&
- "Original domtree is invalid?");
-
- bool Changed = simplifyFunctionCFGImpl(F, TTI, DT, Options);
-
- assert((!RequireAndPreserveDomTree ||
- (DT && DT->verify(DominatorTree::VerificationLevel::Full))) &&
- "Failed to maintain validity of domtree!");
-
- return Changed;
-}
-
+static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI,
+ DominatorTree *DT,
+ const SimplifyCFGOptions &Options) {
+ assert((!RequireAndPreserveDomTree ||
+ (DT && DT->verify(DominatorTree::VerificationLevel::Full))) &&
+ "Original domtree is invalid?");
+
+ bool Changed = simplifyFunctionCFGImpl(F, TTI, DT, Options);
+
+ assert((!RequireAndPreserveDomTree ||
+ (DT && DT->verify(DominatorTree::VerificationLevel::Full))) &&
+ "Failed to maintain validity of domtree!");
+
+ return Changed;
+}
+
// Command-line settings override compile-time settings.
-static void applyCommandLineOverridesToOptions(SimplifyCFGOptions &Options) {
- if (UserBonusInstThreshold.getNumOccurrences())
- Options.BonusInstThreshold = UserBonusInstThreshold;
- if (UserForwardSwitchCond.getNumOccurrences())
- Options.ForwardSwitchCondToPhi = UserForwardSwitchCond;
- if (UserSwitchToLookup.getNumOccurrences())
- Options.ConvertSwitchToLookupTable = UserSwitchToLookup;
- if (UserKeepLoops.getNumOccurrences())
- Options.NeedCanonicalLoop = UserKeepLoops;
- if (UserHoistCommonInsts.getNumOccurrences())
- Options.HoistCommonInsts = UserHoistCommonInsts;
- if (UserSinkCommonInsts.getNumOccurrences())
- Options.SinkCommonInsts = UserSinkCommonInsts;
+static void applyCommandLineOverridesToOptions(SimplifyCFGOptions &Options) {
+ if (UserBonusInstThreshold.getNumOccurrences())
+ Options.BonusInstThreshold = UserBonusInstThreshold;
+ if (UserForwardSwitchCond.getNumOccurrences())
+ Options.ForwardSwitchCondToPhi = UserForwardSwitchCond;
+ if (UserSwitchToLookup.getNumOccurrences())
+ Options.ConvertSwitchToLookupTable = UserSwitchToLookup;
+ if (UserKeepLoops.getNumOccurrences())
+ Options.NeedCanonicalLoop = UserKeepLoops;
+ if (UserHoistCommonInsts.getNumOccurrences())
+ Options.HoistCommonInsts = UserHoistCommonInsts;
+ if (UserSinkCommonInsts.getNumOccurrences())
+ Options.SinkCommonInsts = UserSinkCommonInsts;
+}
+
+SimplifyCFGPass::SimplifyCFGPass() : Options() {
+ applyCommandLineOverridesToOptions(Options);
+}
+
+SimplifyCFGPass::SimplifyCFGPass(const SimplifyCFGOptions &Opts)
+ : Options(Opts) {
+ applyCommandLineOverridesToOptions(Options);
}
-SimplifyCFGPass::SimplifyCFGPass() : Options() {
- applyCommandLineOverridesToOptions(Options);
-}
-
-SimplifyCFGPass::SimplifyCFGPass(const SimplifyCFGOptions &Opts)
- : Options(Opts) {
- applyCommandLineOverridesToOptions(Options);
-}
-
PreservedAnalyses SimplifyCFGPass::run(Function &F,
FunctionAnalysisManager &AM) {
auto &TTI = AM.getResult<TargetIRAnalysis>(F);
Options.AC = &AM.getResult<AssumptionAnalysis>(F);
- DominatorTree *DT = nullptr;
- if (RequireAndPreserveDomTree)
- DT = &AM.getResult<DominatorTreeAnalysis>(F);
- if (F.hasFnAttribute(Attribute::OptForFuzzing)) {
- Options.setSimplifyCondBranch(false).setFoldTwoEntryPHINode(false);
- } else {
- Options.setSimplifyCondBranch(true).setFoldTwoEntryPHINode(true);
- }
- if (!simplifyFunctionCFG(F, TTI, DT, Options))
+ DominatorTree *DT = nullptr;
+ if (RequireAndPreserveDomTree)
+ DT = &AM.getResult<DominatorTreeAnalysis>(F);
+ if (F.hasFnAttribute(Attribute::OptForFuzzing)) {
+ Options.setSimplifyCondBranch(false).setFoldTwoEntryPHINode(false);
+ } else {
+ Options.setSimplifyCondBranch(true).setFoldTwoEntryPHINode(true);
+ }
+ if (!simplifyFunctionCFG(F, TTI, DT, Options))
return PreservedAnalyses::all();
PreservedAnalyses PA;
- if (RequireAndPreserveDomTree)
- PA.preserve<DominatorTreeAnalysis>();
+ if (RequireAndPreserveDomTree)
+ PA.preserve<DominatorTreeAnalysis>();
PA.preserve<GlobalsAA>();
return PA;
}
@@ -329,14 +329,14 @@ struct CFGSimplifyPass : public FunctionPass {
SimplifyCFGOptions Options;
std::function<bool(const Function &)> PredicateFtor;
- CFGSimplifyPass(SimplifyCFGOptions Options_ = SimplifyCFGOptions(),
+ CFGSimplifyPass(SimplifyCFGOptions Options_ = SimplifyCFGOptions(),
std::function<bool(const Function &)> Ftor = nullptr)
- : FunctionPass(ID), Options(Options_), PredicateFtor(std::move(Ftor)) {
+ : FunctionPass(ID), Options(Options_), PredicateFtor(std::move(Ftor)) {
initializeCFGSimplifyPassPass(*PassRegistry::getPassRegistry());
// Check for command-line overrides of options for debug/customization.
- applyCommandLineOverridesToOptions(Options);
+ applyCommandLineOverridesToOptions(Options);
}
bool runOnFunction(Function &F) override {
@@ -344,9 +344,9 @@ struct CFGSimplifyPass : public FunctionPass {
return false;
Options.AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
- DominatorTree *DT = nullptr;
- if (RequireAndPreserveDomTree)
- DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ DominatorTree *DT = nullptr;
+ if (RequireAndPreserveDomTree)
+ DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
if (F.hasFnAttribute(Attribute::OptForFuzzing)) {
Options.setSimplifyCondBranch(false)
.setFoldTwoEntryPHINode(false);
@@ -356,15 +356,15 @@ struct CFGSimplifyPass : public FunctionPass {
}
auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
- return simplifyFunctionCFG(F, TTI, DT, Options);
+ return simplifyFunctionCFG(F, TTI, DT, Options);
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<AssumptionCacheTracker>();
- if (RequireAndPreserveDomTree)
- AU.addRequired<DominatorTreeWrapperPass>();
+ if (RequireAndPreserveDomTree)
+ AU.addRequired<DominatorTreeWrapperPass>();
AU.addRequired<TargetTransformInfoWrapperPass>();
- if (RequireAndPreserveDomTree)
- AU.addPreserved<DominatorTreeWrapperPass>();
+ if (RequireAndPreserveDomTree)
+ AU.addPreserved<DominatorTreeWrapperPass>();
AU.addPreserved<GlobalsAAWrapperPass>();
}
};
@@ -375,13 +375,13 @@ INITIALIZE_PASS_BEGIN(CFGSimplifyPass, "simplifycfg", "Simplify the CFG", false,
false)
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
-INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_END(CFGSimplifyPass, "simplifycfg", "Simplify the CFG", false,
false)
// Public interface to the CFGSimplification pass
FunctionPass *
-llvm::createCFGSimplificationPass(SimplifyCFGOptions Options,
+llvm::createCFGSimplificationPass(SimplifyCFGOptions Options,
std::function<bool(const Function &)> Ftor) {
- return new CFGSimplifyPass(Options, std::move(Ftor));
+ return new CFGSimplifyPass(Options, std::move(Ftor));
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/Sink.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/Sink.cpp
index ffff0e605a..89cfbe384b 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/Sink.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/Sink.cpp
@@ -99,7 +99,7 @@ static bool IsAcceptableTarget(Instruction *Inst, BasicBlock *SuccToSinkTo,
return false;
}
- return true;
+ return true;
}
/// SinkInstruction - Determine whether it is safe to sink the specified machine
@@ -130,37 +130,37 @@ static bool SinkInstruction(Instruction *Inst,
// decide.
BasicBlock *SuccToSinkTo = nullptr;
- // Find the nearest common dominator of all users as the candidate.
- BasicBlock *BB = Inst->getParent();
- for (Use &U : Inst->uses()) {
- Instruction *UseInst = cast<Instruction>(U.getUser());
- BasicBlock *UseBlock = UseInst->getParent();
- // Don't worry about dead users.
- if (!DT.isReachableFromEntry(UseBlock))
- continue;
- if (PHINode *PN = dyn_cast<PHINode>(UseInst)) {
- // PHI nodes use the operand in the predecessor block, not the block with
- // the PHI.
- unsigned Num = PHINode::getIncomingValueNumForOperand(U.getOperandNo());
- UseBlock = PN->getIncomingBlock(Num);
- }
- if (SuccToSinkTo)
- SuccToSinkTo = DT.findNearestCommonDominator(SuccToSinkTo, UseBlock);
- else
- SuccToSinkTo = UseBlock;
- // The current basic block needs to dominate the candidate.
- if (!DT.dominates(BB, SuccToSinkTo))
- return false;
+ // Find the nearest common dominator of all users as the candidate.
+ BasicBlock *BB = Inst->getParent();
+ for (Use &U : Inst->uses()) {
+ Instruction *UseInst = cast<Instruction>(U.getUser());
+ BasicBlock *UseBlock = UseInst->getParent();
+ // Don't worry about dead users.
+ if (!DT.isReachableFromEntry(UseBlock))
+ continue;
+ if (PHINode *PN = dyn_cast<PHINode>(UseInst)) {
+ // PHI nodes use the operand in the predecessor block, not the block with
+ // the PHI.
+ unsigned Num = PHINode::getIncomingValueNumForOperand(U.getOperandNo());
+ UseBlock = PN->getIncomingBlock(Num);
+ }
+ if (SuccToSinkTo)
+ SuccToSinkTo = DT.findNearestCommonDominator(SuccToSinkTo, UseBlock);
+ else
+ SuccToSinkTo = UseBlock;
+ // The current basic block needs to dominate the candidate.
+ if (!DT.dominates(BB, SuccToSinkTo))
+ return false;
}
- if (SuccToSinkTo) {
- // The nearest common dominator may be in a parent loop of BB, which may not
- // be beneficial. Find an ancestor.
- while (SuccToSinkTo != BB &&
- !IsAcceptableTarget(Inst, SuccToSinkTo, DT, LI))
- SuccToSinkTo = DT.getNode(SuccToSinkTo)->getIDom()->getBlock();
- if (SuccToSinkTo == BB)
- SuccToSinkTo = nullptr;
+ if (SuccToSinkTo) {
+ // The nearest common dominator may be in a parent loop of BB, which may not
+ // be beneficial. Find an ancestor.
+ while (SuccToSinkTo != BB &&
+ !IsAcceptableTarget(Inst, SuccToSinkTo, DT, LI))
+ SuccToSinkTo = DT.getNode(SuccToSinkTo)->getIDom()->getBlock();
+ if (SuccToSinkTo == BB)
+ SuccToSinkTo = nullptr;
}
// If we couldn't find a block to sink to, ignore this instruction.
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/SpeculateAroundPHIs.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/SpeculateAroundPHIs.cpp
index b201837ea6..9b18c945d9 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/SpeculateAroundPHIs.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/SpeculateAroundPHIs.cpp
@@ -756,10 +756,10 @@ static bool tryToSpeculatePHIs(SmallVectorImpl<PHINode *> &PNs,
// For each PHI node in this block, check whether there are immediate folding
// opportunities from speculation, and whether that speculation will be
// valid. This determise the set of safe PHIs to speculate.
- llvm::erase_if(PNs, [&](PHINode *PN) {
- return !isSafeAndProfitableToSpeculateAroundPHI(
- *PN, CostSavingsMap, PotentialSpecSet, UnsafeSet, DT, TTI);
- });
+ llvm::erase_if(PNs, [&](PHINode *PN) {
+ return !isSafeAndProfitableToSpeculateAroundPHI(
+ *PN, CostSavingsMap, PotentialSpecSet, UnsafeSet, DT, TTI);
+ });
// If no PHIs were profitable, skip.
if (PNs.empty()) {
LLVM_DEBUG(dbgs() << " No safe and profitable PHIs found!\n");
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/SpeculativeExecution.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/SpeculativeExecution.cpp
index 4dbeb21638..c78185f2a6 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/SpeculativeExecution.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/SpeculativeExecution.cpp
@@ -245,13 +245,13 @@ static unsigned ComputeSpeculationCost(const Instruction *I,
case Instruction::FNeg:
case Instruction::ICmp:
case Instruction::FCmp:
- case Instruction::Trunc:
- case Instruction::Freeze:
- case Instruction::ExtractElement:
- case Instruction::InsertElement:
- case Instruction::ShuffleVector:
- case Instruction::ExtractValue:
- case Instruction::InsertValue:
+ case Instruction::Trunc:
+ case Instruction::Freeze:
+ case Instruction::ExtractElement:
+ case Instruction::InsertElement:
+ case Instruction::ShuffleVector:
+ case Instruction::ExtractValue:
+ case Instruction::InsertValue:
return TTI.getUserCost(I, TargetTransformInfo::TCK_SizeAndLatency);
default:
@@ -281,7 +281,7 @@ bool SpeculativeExecutionPass::considerHoistingFromTo(
for (const Value *V : U->operand_values()) {
if (const Instruction *I = dyn_cast<Instruction>(V)) {
- if (NotHoisted.contains(I))
+ if (NotHoisted.contains(I))
return false;
}
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp
index f8177f1f99..577992ccb5 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp
@@ -55,7 +55,7 @@
// - When (i' - i) is constant but i and i' are not, we could still perform
// SLSR.
-#include "llvm/Transforms/Scalar/StraightLineStrengthReduce.h"
+#include "llvm/Transforms/Scalar/StraightLineStrengthReduce.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/SmallVector.h"
@@ -96,39 +96,39 @@ static const unsigned UnknownAddressSpace =
namespace {
-class StraightLineStrengthReduceLegacyPass : public FunctionPass {
- const DataLayout *DL = nullptr;
-
+class StraightLineStrengthReduceLegacyPass : public FunctionPass {
+ const DataLayout *DL = nullptr;
+
+public:
+ static char ID;
+
+ StraightLineStrengthReduceLegacyPass() : FunctionPass(ID) {
+ initializeStraightLineStrengthReduceLegacyPassPass(
+ *PassRegistry::getPassRegistry());
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<DominatorTreeWrapperPass>();
+ AU.addRequired<ScalarEvolutionWrapperPass>();
+ AU.addRequired<TargetTransformInfoWrapperPass>();
+ // We do not modify the shape of the CFG.
+ AU.setPreservesCFG();
+ }
+
+ bool doInitialization(Module &M) override {
+ DL = &M.getDataLayout();
+ return false;
+ }
+
+ bool runOnFunction(Function &F) override;
+};
+
+class StraightLineStrengthReduce {
public:
- static char ID;
-
- StraightLineStrengthReduceLegacyPass() : FunctionPass(ID) {
- initializeStraightLineStrengthReduceLegacyPassPass(
- *PassRegistry::getPassRegistry());
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<DominatorTreeWrapperPass>();
- AU.addRequired<ScalarEvolutionWrapperPass>();
- AU.addRequired<TargetTransformInfoWrapperPass>();
- // We do not modify the shape of the CFG.
- AU.setPreservesCFG();
- }
-
- bool doInitialization(Module &M) override {
- DL = &M.getDataLayout();
- return false;
- }
-
- bool runOnFunction(Function &F) override;
-};
-
-class StraightLineStrengthReduce {
-public:
- StraightLineStrengthReduce(const DataLayout *DL, DominatorTree *DT,
- ScalarEvolution *SE, TargetTransformInfo *TTI)
- : DL(DL), DT(DT), SE(SE), TTI(TTI) {}
-
+ StraightLineStrengthReduce(const DataLayout *DL, DominatorTree *DT,
+ ScalarEvolution *SE, TargetTransformInfo *TTI)
+ : DL(DL), DT(DT), SE(SE), TTI(TTI) {}
+
// SLSR candidate. Such a candidate must be in one of the forms described in
// the header comments.
struct Candidate {
@@ -176,7 +176,7 @@ public:
Candidate *Basis = nullptr;
};
- bool runOnFunction(Function &F);
+ bool runOnFunction(Function &F);
private:
// Returns true if Basis is a basis for C, i.e., Basis dominates C and they
@@ -256,18 +256,18 @@ private:
} // end anonymous namespace
-char StraightLineStrengthReduceLegacyPass::ID = 0;
+char StraightLineStrengthReduceLegacyPass::ID = 0;
-INITIALIZE_PASS_BEGIN(StraightLineStrengthReduceLegacyPass, "slsr",
+INITIALIZE_PASS_BEGIN(StraightLineStrengthReduceLegacyPass, "slsr",
"Straight line strength reduction", false, false)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
-INITIALIZE_PASS_END(StraightLineStrengthReduceLegacyPass, "slsr",
+INITIALIZE_PASS_END(StraightLineStrengthReduceLegacyPass, "slsr",
"Straight line strength reduction", false, false)
FunctionPass *llvm::createStraightLineStrengthReducePass() {
- return new StraightLineStrengthReduceLegacyPass();
+ return new StraightLineStrengthReduceLegacyPass();
}
bool StraightLineStrengthReduce::isBasisFor(const Candidate &Basis,
@@ -285,7 +285,7 @@ bool StraightLineStrengthReduce::isBasisFor(const Candidate &Basis,
static bool isGEPFoldable(GetElementPtrInst *GEP,
const TargetTransformInfo *TTI) {
- SmallVector<const Value *, 4> Indices(GEP->indices());
+ SmallVector<const Value *, 4> Indices(GEP->indices());
return TTI->getGEPCost(GEP->getSourceElementType(), GEP->getPointerOperand(),
Indices) == TargetTransformInfo::TCC_Free;
}
@@ -715,17 +715,17 @@ void StraightLineStrengthReduce::rewriteCandidateWithBasis(
UnlinkedInstructions.push_back(C.Ins);
}
-bool StraightLineStrengthReduceLegacyPass::runOnFunction(Function &F) {
+bool StraightLineStrengthReduceLegacyPass::runOnFunction(Function &F) {
if (skipFunction(F))
return false;
- auto *TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
- auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
- return StraightLineStrengthReduce(DL, DT, SE, TTI).runOnFunction(F);
-}
-
-bool StraightLineStrengthReduce::runOnFunction(Function &F) {
+ auto *TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
+ auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
+ return StraightLineStrengthReduce(DL, DT, SE, TTI).runOnFunction(F);
+}
+
+bool StraightLineStrengthReduce::runOnFunction(Function &F) {
// Traverse the dominator tree in the depth-first order. This order makes sure
// all bases of a candidate are in Candidates when we process it.
for (const auto Node : depth_first(DT))
@@ -755,25 +755,25 @@ bool StraightLineStrengthReduce::runOnFunction(Function &F) {
UnlinkedInstructions.clear();
return Ret;
}
-
-namespace llvm {
-
-PreservedAnalyses
-StraightLineStrengthReducePass::run(Function &F, FunctionAnalysisManager &AM) {
- const DataLayout *DL = &F.getParent()->getDataLayout();
- auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
- auto *SE = &AM.getResult<ScalarEvolutionAnalysis>(F);
- auto *TTI = &AM.getResult<TargetIRAnalysis>(F);
-
- if (!StraightLineStrengthReduce(DL, DT, SE, TTI).runOnFunction(F))
- return PreservedAnalyses::all();
-
- PreservedAnalyses PA;
- PA.preserveSet<CFGAnalyses>();
- PA.preserve<DominatorTreeAnalysis>();
- PA.preserve<ScalarEvolutionAnalysis>();
- PA.preserve<TargetIRAnalysis>();
- return PA;
-}
-
-} // namespace llvm
+
+namespace llvm {
+
+PreservedAnalyses
+StraightLineStrengthReducePass::run(Function &F, FunctionAnalysisManager &AM) {
+ const DataLayout *DL = &F.getParent()->getDataLayout();
+ auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
+ auto *SE = &AM.getResult<ScalarEvolutionAnalysis>(F);
+ auto *TTI = &AM.getResult<TargetIRAnalysis>(F);
+
+ if (!StraightLineStrengthReduce(DL, DT, SE, TTI).runOnFunction(F))
+ return PreservedAnalyses::all();
+
+ PreservedAnalyses PA;
+ PA.preserveSet<CFGAnalyses>();
+ PA.preserve<DominatorTreeAnalysis>();
+ PA.preserve<ScalarEvolutionAnalysis>();
+ PA.preserve<TargetIRAnalysis>();
+ return PA;
+}
+
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/StructurizeCFG.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/StructurizeCFG.cpp
index ae83f06ead..3e15cad5f3 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/StructurizeCFG.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/StructurizeCFG.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/Scalar/StructurizeCFG.h"
+#include "llvm/Transforms/Scalar/StructurizeCFG.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SCCIterator.h"
@@ -29,7 +29,7 @@
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Metadata.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
@@ -57,7 +57,7 @@ using namespace llvm::PatternMatch;
#define DEBUG_TYPE "structurizecfg"
// The name for newly created blocks.
-const char FlowBlockName[] = "Flow";
+const char FlowBlockName[] = "Flow";
namespace {
@@ -236,7 +236,7 @@ public:
/// consist of a network of PHI nodes where the true incoming values expresses
/// breaks and the false values expresses continue states.
-class StructurizeCFG {
+class StructurizeCFG {
Type *Boolean;
ConstantInt *BoolTrue;
ConstantInt *BoolFalse;
@@ -245,7 +245,7 @@ class StructurizeCFG {
Function *Func;
Region *ParentRegion;
- LegacyDivergenceAnalysis *DA = nullptr;
+ LegacyDivergenceAnalysis *DA = nullptr;
DominatorTree *DT;
SmallVector<RegionNode *, 8> Order;
@@ -310,35 +310,35 @@ class StructurizeCFG {
void rebuildSSA();
public:
- void init(Region *R);
- bool run(Region *R, DominatorTree *DT);
- bool makeUniformRegion(Region *R, LegacyDivergenceAnalysis *DA);
-};
-
-class StructurizeCFGLegacyPass : public RegionPass {
- bool SkipUniformRegions;
-
-public:
+ void init(Region *R);
+ bool run(Region *R, DominatorTree *DT);
+ bool makeUniformRegion(Region *R, LegacyDivergenceAnalysis *DA);
+};
+
+class StructurizeCFGLegacyPass : public RegionPass {
+ bool SkipUniformRegions;
+
+public:
static char ID;
- explicit StructurizeCFGLegacyPass(bool SkipUniformRegions_ = false)
- : RegionPass(ID), SkipUniformRegions(SkipUniformRegions_) {
+ explicit StructurizeCFGLegacyPass(bool SkipUniformRegions_ = false)
+ : RegionPass(ID), SkipUniformRegions(SkipUniformRegions_) {
if (ForceSkipUniformRegions.getNumOccurrences())
SkipUniformRegions = ForceSkipUniformRegions.getValue();
- initializeStructurizeCFGLegacyPassPass(*PassRegistry::getPassRegistry());
+ initializeStructurizeCFGLegacyPassPass(*PassRegistry::getPassRegistry());
}
- bool runOnRegion(Region *R, RGPassManager &RGM) override {
- StructurizeCFG SCFG;
- SCFG.init(R);
- if (SkipUniformRegions) {
- LegacyDivergenceAnalysis *DA = &getAnalysis<LegacyDivergenceAnalysis>();
- if (SCFG.makeUniformRegion(R, DA))
- return false;
- }
- DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- return SCFG.run(R, DT);
- }
+ bool runOnRegion(Region *R, RGPassManager &RGM) override {
+ StructurizeCFG SCFG;
+ SCFG.init(R);
+ if (SkipUniformRegions) {
+ LegacyDivergenceAnalysis *DA = &getAnalysis<LegacyDivergenceAnalysis>();
+ if (SCFG.makeUniformRegion(R, DA))
+ return false;
+ }
+ DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ return SCFG.run(R, DT);
+ }
StringRef getPassName() const override { return "Structurize control flow"; }
@@ -355,16 +355,16 @@ public:
} // end anonymous namespace
-char StructurizeCFGLegacyPass::ID = 0;
+char StructurizeCFGLegacyPass::ID = 0;
-INITIALIZE_PASS_BEGIN(StructurizeCFGLegacyPass, "structurizecfg",
- "Structurize the CFG", false, false)
+INITIALIZE_PASS_BEGIN(StructurizeCFGLegacyPass, "structurizecfg",
+ "Structurize the CFG", false, false)
INITIALIZE_PASS_DEPENDENCY(LegacyDivergenceAnalysis)
-INITIALIZE_PASS_DEPENDENCY(LowerSwitchLegacyPass)
+INITIALIZE_PASS_DEPENDENCY(LowerSwitchLegacyPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(RegionInfoPass)
-INITIALIZE_PASS_END(StructurizeCFGLegacyPass, "structurizecfg",
- "Structurize the CFG", false, false)
+INITIALIZE_PASS_END(StructurizeCFGLegacyPass, "structurizecfg",
+ "Structurize the CFG", false, false)
/// Build up the general order of nodes, by performing a topological sort of the
/// parent region's nodes, while ensuring that there is no outer cycle node
@@ -1008,59 +1008,59 @@ static bool hasOnlyUniformBranches(Region *R, unsigned UniformMDKindID,
return SubRegionsAreUniform || (ConditionalDirectChildren <= 1);
}
-void StructurizeCFG::init(Region *R) {
- LLVMContext &Context = R->getEntry()->getContext();
-
- Boolean = Type::getInt1Ty(Context);
- BoolTrue = ConstantInt::getTrue(Context);
- BoolFalse = ConstantInt::getFalse(Context);
- BoolUndef = UndefValue::get(Boolean);
-
- this->DA = nullptr;
-}
-
-bool StructurizeCFG::makeUniformRegion(Region *R,
- LegacyDivergenceAnalysis *DA) {
+void StructurizeCFG::init(Region *R) {
+ LLVMContext &Context = R->getEntry()->getContext();
+
+ Boolean = Type::getInt1Ty(Context);
+ BoolTrue = ConstantInt::getTrue(Context);
+ BoolFalse = ConstantInt::getFalse(Context);
+ BoolUndef = UndefValue::get(Boolean);
+
+ this->DA = nullptr;
+}
+
+bool StructurizeCFG::makeUniformRegion(Region *R,
+ LegacyDivergenceAnalysis *DA) {
if (R->isTopLevelRegion())
return false;
- this->DA = DA;
- // TODO: We could probably be smarter here with how we handle sub-regions.
- // We currently rely on the fact that metadata is set by earlier invocations
- // of the pass on sub-regions, and that this metadata doesn't get lost --
- // but we shouldn't rely on metadata for correctness!
- unsigned UniformMDKindID =
- R->getEntry()->getContext().getMDKindID("structurizecfg.uniform");
-
- if (hasOnlyUniformBranches(R, UniformMDKindID, *DA)) {
- LLVM_DEBUG(dbgs() << "Skipping region with uniform control flow: " << *R
- << '\n');
-
- // Mark all direct child block terminators as having been treated as
- // uniform. To account for a possible future in which non-uniform
- // sub-regions are treated more cleverly, indirect children are not
- // marked as uniform.
- MDNode *MD = MDNode::get(R->getEntry()->getParent()->getContext(), {});
- for (RegionNode *E : R->elements()) {
- if (E->isSubRegion())
- continue;
-
- if (Instruction *Term = E->getEntry()->getTerminator())
- Term->setMetadata(UniformMDKindID, MD);
- }
-
- return true;
+ this->DA = DA;
+ // TODO: We could probably be smarter here with how we handle sub-regions.
+ // We currently rely on the fact that metadata is set by earlier invocations
+ // of the pass on sub-regions, and that this metadata doesn't get lost --
+ // but we shouldn't rely on metadata for correctness!
+ unsigned UniformMDKindID =
+ R->getEntry()->getContext().getMDKindID("structurizecfg.uniform");
+
+ if (hasOnlyUniformBranches(R, UniformMDKindID, *DA)) {
+ LLVM_DEBUG(dbgs() << "Skipping region with uniform control flow: " << *R
+ << '\n');
+
+ // Mark all direct child block terminators as having been treated as
+ // uniform. To account for a possible future in which non-uniform
+ // sub-regions are treated more cleverly, indirect children are not
+ // marked as uniform.
+ MDNode *MD = MDNode::get(R->getEntry()->getParent()->getContext(), {});
+ for (RegionNode *E : R->elements()) {
+ if (E->isSubRegion())
+ continue;
+
+ if (Instruction *Term = E->getEntry()->getTerminator())
+ Term->setMetadata(UniformMDKindID, MD);
+ }
+
+ return true;
}
- return false;
-}
-
-/// Run the transformation for each region found
-bool StructurizeCFG::run(Region *R, DominatorTree *DT) {
- if (R->isTopLevelRegion())
- return false;
-
- this->DT = DT;
-
+ return false;
+}
+
+/// Run the transformation for each region found
+bool StructurizeCFG::run(Region *R, DominatorTree *DT) {
+ if (R->isTopLevelRegion())
+ return false;
+
+ this->DT = DT;
+
Func = R->getEntry()->getParent();
ParentRegion = R;
@@ -1088,33 +1088,33 @@ bool StructurizeCFG::run(Region *R, DominatorTree *DT) {
}
Pass *llvm::createStructurizeCFGPass(bool SkipUniformRegions) {
- return new StructurizeCFGLegacyPass(SkipUniformRegions);
+ return new StructurizeCFGLegacyPass(SkipUniformRegions);
+}
+
+static void addRegionIntoQueue(Region &R, std::vector<Region *> &Regions) {
+ Regions.push_back(&R);
+ for (const auto &E : R)
+ addRegionIntoQueue(*E, Regions);
+}
+
+PreservedAnalyses StructurizeCFGPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+
+ bool Changed = false;
+ DominatorTree *DT = &AM.getResult<DominatorTreeAnalysis>(F);
+ auto &RI = AM.getResult<RegionInfoAnalysis>(F);
+ std::vector<Region *> Regions;
+ addRegionIntoQueue(*RI.getTopLevelRegion(), Regions);
+ while (!Regions.empty()) {
+ Region *R = Regions.back();
+ StructurizeCFG SCFG;
+ SCFG.init(R);
+ Changed |= SCFG.run(R, DT);
+ Regions.pop_back();
+ }
+ if (!Changed)
+ return PreservedAnalyses::all();
+ PreservedAnalyses PA;
+ PA.preserve<DominatorTreeAnalysis>();
+ return PA;
}
-
-static void addRegionIntoQueue(Region &R, std::vector<Region *> &Regions) {
- Regions.push_back(&R);
- for (const auto &E : R)
- addRegionIntoQueue(*E, Regions);
-}
-
-PreservedAnalyses StructurizeCFGPass::run(Function &F,
- FunctionAnalysisManager &AM) {
-
- bool Changed = false;
- DominatorTree *DT = &AM.getResult<DominatorTreeAnalysis>(F);
- auto &RI = AM.getResult<RegionInfoAnalysis>(F);
- std::vector<Region *> Regions;
- addRegionIntoQueue(*RI.getTopLevelRegion(), Regions);
- while (!Regions.empty()) {
- Region *R = Regions.back();
- StructurizeCFG SCFG;
- SCFG.init(R);
- Changed |= SCFG.run(R, DT);
- Regions.pop_back();
- }
- if (!Changed)
- return PreservedAnalyses::all();
- PreservedAnalyses PA;
- PA.preserve<DominatorTreeAnalysis>();
- return PA;
-}
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/TailRecursionElimination.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/TailRecursionElimination.cpp
index 50f7ac0a31..9e7cccc884 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/TailRecursionElimination.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/TailRecursionElimination.cpp
@@ -92,10 +92,10 @@ STATISTIC(NumAccumAdded, "Number of accumulators introduced");
/// Scan the specified function for alloca instructions.
/// If it contains any dynamic allocas, returns false.
static bool canTRE(Function &F) {
- // FIXME: The code generator produces really bad code when an 'escaping
- // alloca' is changed from being a static alloca to being a dynamic alloca.
- // Until this is resolved, disable this transformation if that would ever
- // happen. This bug is PR962.
+ // FIXME: The code generator produces really bad code when an 'escaping
+ // alloca' is changed from being a static alloca to being a dynamic alloca.
+ // Until this is resolved, disable this transformation if that would ever
+ // happen. This bug is PR962.
return llvm::all_of(instructions(F), [](Instruction &I) {
auto *AI = dyn_cast<AllocaInst>(&I);
return !AI || AI->isStaticAlloca();
@@ -240,11 +240,11 @@ static bool markTails(Function &F, bool &AllCallsAreTailCalls,
Escaped = ESCAPED;
CallInst *CI = dyn_cast<CallInst>(&I);
- // A PseudoProbeInst has the IntrInaccessibleMemOnly tag hence it is
- // considered accessing memory and will be marked as a tail call if we
- // don't bail out here.
- if (!CI || CI->isTailCall() || isa<DbgInfoIntrinsic>(&I) ||
- isa<PseudoProbeInst>(&I))
+ // A PseudoProbeInst has the IntrInaccessibleMemOnly tag hence it is
+ // considered accessing memory and will be marked as a tail call if we
+ // don't bail out here.
+ if (!CI || CI->isTailCall() || isa<DbgInfoIntrinsic>(&I) ||
+ isa<PseudoProbeInst>(&I))
continue;
bool IsNoTail = CI->isNoTailCall() || CI->hasOperandBundles();
@@ -286,7 +286,7 @@ static bool markTails(Function &F, bool &AllCallsAreTailCalls,
}
}
- for (auto *SuccBB : successors(BB)) {
+ for (auto *SuccBB : successors(BB)) {
auto &State = Visited[SuccBB];
if (State < Escaped) {
State = Escaped;
@@ -426,7 +426,7 @@ class TailRecursionEliminator {
DomTreeUpdater &DTU)
: F(F), TTI(TTI), AA(AA), ORE(ORE), DTU(DTU) {}
- CallInst *findTRECandidate(BasicBlock *BB,
+ CallInst *findTRECandidate(BasicBlock *BB,
bool CannotTailCallElimCallsMarkedTail);
void createTailRecurseLoopHeader(CallInst *CI);
@@ -435,9 +435,9 @@ class TailRecursionEliminator {
bool eliminateCall(CallInst *CI);
- void cleanupAndFinalize();
+ void cleanupAndFinalize();
- bool processBlock(BasicBlock &BB, bool CannotTailCallElimCallsMarkedTail);
+ bool processBlock(BasicBlock &BB, bool CannotTailCallElimCallsMarkedTail);
public:
static bool eliminate(Function &F, const TargetTransformInfo *TTI,
@@ -447,8 +447,8 @@ public:
} // namespace
CallInst *TailRecursionEliminator::findTRECandidate(
- BasicBlock *BB, bool CannotTailCallElimCallsMarkedTail) {
- Instruction *TI = BB->getTerminator();
+ BasicBlock *BB, bool CannotTailCallElimCallsMarkedTail) {
+ Instruction *TI = BB->getTerminator();
if (&BB->front() == TI) // Make sure there is something before the terminator.
return nullptr;
@@ -747,50 +747,50 @@ void TailRecursionEliminator::cleanupAndFinalize() {
}
}
-bool TailRecursionEliminator::processBlock(
- BasicBlock &BB, bool CannotTailCallElimCallsMarkedTail) {
- Instruction *TI = BB.getTerminator();
-
- if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
- if (BI->isConditional())
- return false;
-
- BasicBlock *Succ = BI->getSuccessor(0);
- ReturnInst *Ret = dyn_cast<ReturnInst>(Succ->getFirstNonPHIOrDbg(true));
-
- if (!Ret)
- return false;
-
- CallInst *CI = findTRECandidate(&BB, CannotTailCallElimCallsMarkedTail);
-
- if (!CI)
- return false;
-
- LLVM_DEBUG(dbgs() << "FOLDING: " << *Succ
- << "INTO UNCOND BRANCH PRED: " << BB);
- FoldReturnIntoUncondBranch(Ret, Succ, &BB, &DTU);
- ++NumRetDuped;
-
- // If all predecessors of Succ have been eliminated by
- // FoldReturnIntoUncondBranch, delete it. It is important to empty it,
- // because the ret instruction in there is still using a value which
- // eliminateCall will attempt to remove. This block can only contain
- // instructions that can't have uses, therefore it is safe to remove.
- if (pred_empty(Succ))
- DTU.deleteBB(Succ);
-
- eliminateCall(CI);
- return true;
- } else if (isa<ReturnInst>(TI)) {
- CallInst *CI = findTRECandidate(&BB, CannotTailCallElimCallsMarkedTail);
-
- if (CI)
- return eliminateCall(CI);
- }
-
- return false;
-}
-
+bool TailRecursionEliminator::processBlock(
+ BasicBlock &BB, bool CannotTailCallElimCallsMarkedTail) {
+ Instruction *TI = BB.getTerminator();
+
+ if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
+ if (BI->isConditional())
+ return false;
+
+ BasicBlock *Succ = BI->getSuccessor(0);
+ ReturnInst *Ret = dyn_cast<ReturnInst>(Succ->getFirstNonPHIOrDbg(true));
+
+ if (!Ret)
+ return false;
+
+ CallInst *CI = findTRECandidate(&BB, CannotTailCallElimCallsMarkedTail);
+
+ if (!CI)
+ return false;
+
+ LLVM_DEBUG(dbgs() << "FOLDING: " << *Succ
+ << "INTO UNCOND BRANCH PRED: " << BB);
+ FoldReturnIntoUncondBranch(Ret, Succ, &BB, &DTU);
+ ++NumRetDuped;
+
+ // If all predecessors of Succ have been eliminated by
+ // FoldReturnIntoUncondBranch, delete it. It is important to empty it,
+ // because the ret instruction in there is still using a value which
+ // eliminateCall will attempt to remove. This block can only contain
+ // instructions that can't have uses, therefore it is safe to remove.
+ if (pred_empty(Succ))
+ DTU.deleteBB(Succ);
+
+ eliminateCall(CI);
+ return true;
+ } else if (isa<ReturnInst>(TI)) {
+ CallInst *CI = findTRECandidate(&BB, CannotTailCallElimCallsMarkedTail);
+
+ if (CI)
+ return eliminateCall(CI);
+ }
+
+ return false;
+}
+
bool TailRecursionEliminator::eliminate(Function &F,
const TargetTransformInfo *TTI,
AliasAnalysis *AA,
@@ -815,11 +815,11 @@ bool TailRecursionEliminator::eliminate(Function &F,
// TRE would deallocate variable sized allocas, TRE doesn't).
bool CanTRETailMarkedCall = canTRE(F);
- // Change any tail recursive calls to loops.
+ // Change any tail recursive calls to loops.
TailRecursionEliminator TRE(F, TTI, AA, ORE, DTU);
- for (BasicBlock &BB : F)
- MadeChange |= TRE.processBlock(BB, !CanTRETailMarkedCall);
+ for (BasicBlock &BB : F)
+ MadeChange |= TRE.processBlock(BB, !CanTRETailMarkedCall);
TRE.cleanupAndFinalize();
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/WarnMissedTransforms.cpp b/contrib/libs/llvm12/lib/Transforms/Scalar/WarnMissedTransforms.cpp
index ec00528465..80a7d3a43a 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/WarnMissedTransforms.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/WarnMissedTransforms.cpp
@@ -48,12 +48,12 @@ static void warnAboutLeftoverTransformations(Loop *L,
if (hasVectorizeTransformation(L) == TM_ForcedByUser) {
LLVM_DEBUG(dbgs() << "Leftover vectorization transformation\n");
- Optional<ElementCount> VectorizeWidth =
- getOptionalElementCountLoopAttribute(L);
+ Optional<ElementCount> VectorizeWidth =
+ getOptionalElementCountLoopAttribute(L);
Optional<int> InterleaveCount =
getOptionalIntLoopAttribute(L, "llvm.loop.interleave.count");
- if (!VectorizeWidth || VectorizeWidth->isVector())
+ if (!VectorizeWidth || VectorizeWidth->isVector())
ORE->emit(
DiagnosticInfoOptimizationFailure(DEBUG_TYPE,
"FailedRequestedVectorization",
diff --git a/contrib/libs/llvm12/lib/Transforms/Scalar/ya.make b/contrib/libs/llvm12/lib/Transforms/Scalar/ya.make
index 00b9ef5ca1..75501ae81a 100644
--- a/contrib/libs/llvm12/lib/Transforms/Scalar/ya.make
+++ b/contrib/libs/llvm12/lib/Transforms/Scalar/ya.make
@@ -12,14 +12,14 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine
- contrib/libs/llvm12/lib/Transforms/InstCombine
- contrib/libs/llvm12/lib/Transforms/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine
+ contrib/libs/llvm12/lib/Transforms/InstCombine
+ contrib/libs/llvm12/lib/Transforms/Utils
)
ADDINCL(
@@ -33,11 +33,11 @@ NO_UTIL()
SRCS(
ADCE.cpp
AlignmentFromAssumptions.cpp
- AnnotationRemarks.cpp
+ AnnotationRemarks.cpp
BDCE.cpp
CallSiteSplitting.cpp
ConstantHoisting.cpp
- ConstraintElimination.cpp
+ ConstraintElimination.cpp
CorrelatedValuePropagation.cpp
DCE.cpp
DeadStoreElimination.cpp
@@ -60,7 +60,7 @@ SRCS(
LoopDataPrefetch.cpp
LoopDeletion.cpp
LoopDistribute.cpp
- LoopFlatten.cpp
+ LoopFlatten.cpp
LoopFuse.cpp
LoopIdiomRecognize.cpp
LoopInstSimplify.cpp
@@ -97,7 +97,7 @@ SRCS(
SCCP.cpp
SROA.cpp
Scalar.cpp
- ScalarizeMaskedMemIntrin.cpp
+ ScalarizeMaskedMemIntrin.cpp
Scalarizer.cpp
SeparateConstOffsetFromGEP.cpp
SimpleLoopUnswitch.cpp
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/AssumeBundleBuilder.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/AssumeBundleBuilder.cpp
index c1f42de423..3daff3b443 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/AssumeBundleBuilder.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/AssumeBundleBuilder.cpp
@@ -52,7 +52,7 @@ namespace {
bool isUsefullToPreserve(Attribute::AttrKind Kind) {
switch (Kind) {
case Attribute::NonNull:
- case Attribute::NoUndef:
+ case Attribute::NoUndef:
case Attribute::Alignment:
case Attribute::Dereferenceable:
case Attribute::DereferenceableOrNull:
@@ -70,7 +70,7 @@ RetainedKnowledge canonicalizedKnowledge(RetainedKnowledge RK, Module *M) {
default:
return RK;
case Attribute::NonNull:
- RK.WasOn = getUnderlyingObject(RK.WasOn);
+ RK.WasOn = getUnderlyingObject(RK.WasOn);
return RK;
case Attribute::Alignment: {
Value *V = RK.WasOn->stripInBoundsOffsets([&](const Value *Strip) {
@@ -146,7 +146,7 @@ struct AssumeBuilderState {
if (!RK.WasOn)
return true;
if (RK.WasOn->getType()->isPointerTy()) {
- Value *UnderlyingPtr = getUnderlyingObject(RK.WasOn);
+ Value *UnderlyingPtr = getUnderlyingObject(RK.WasOn);
if (isa<AllocaInst>(UnderlyingPtr) || isa<GlobalValue>(UnderlyingPtr))
return false;
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/BasicBlockUtils.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/BasicBlockUtils.cpp
index faf7a757c3..6bcd42c4c6 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -105,7 +105,7 @@ void llvm::DeleteDeadBlocks(ArrayRef <BasicBlock *> BBs, DomTreeUpdater *DTU,
DetatchDeadBlocks(BBs, DTU ? &Updates : nullptr, KeepOneInputPHIs);
if (DTU)
- DTU->applyUpdates(Updates);
+ DTU->applyUpdates(Updates);
for (BasicBlock *BB : BBs)
if (DTU)
@@ -136,10 +136,10 @@ bool llvm::EliminateUnreachableBlocks(Function &F, DomTreeUpdater *DTU,
return !DeadBlocks.empty();
}
-bool llvm::FoldSingleEntryPHINodes(BasicBlock *BB,
+bool llvm::FoldSingleEntryPHINodes(BasicBlock *BB,
MemoryDependenceResults *MemDep) {
- if (!isa<PHINode>(BB->begin()))
- return false;
+ if (!isa<PHINode>(BB->begin()))
+ return false;
while (PHINode *PN = dyn_cast<PHINode>(BB->begin())) {
if (PN->getIncomingValue(0) != PN)
@@ -152,7 +152,7 @@ bool llvm::FoldSingleEntryPHINodes(BasicBlock *BB,
PN->eraseFromParent();
}
- return true;
+ return true;
}
bool llvm::DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI,
@@ -230,21 +230,21 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU,
// These dominator edges will be redirected from Pred.
std::vector<DominatorTree::UpdateType> Updates;
if (DTU) {
- SmallSetVector<BasicBlock *, 2> UniqueSuccessors(succ_begin(BB),
- succ_end(BB));
- Updates.reserve(1 + (2 * UniqueSuccessors.size()));
+ SmallSetVector<BasicBlock *, 2> UniqueSuccessors(succ_begin(BB),
+ succ_end(BB));
+ Updates.reserve(1 + (2 * UniqueSuccessors.size()));
// Add insert edges first. Experimentally, for the particular case of two
// blocks that can be merged, with a single successor and single predecessor
// respectively, it is beneficial to have all insert updates first. Deleting
// edges first may lead to unreachable blocks, followed by inserting edges
// making the blocks reachable again. Such DT updates lead to high compile
// times. We add inserts before deletes here to reduce compile time.
- for (BasicBlock *UniqueSuccessor : UniqueSuccessors)
+ for (BasicBlock *UniqueSuccessor : UniqueSuccessors)
// This successor of BB may already have PredBB as a predecessor.
- if (!llvm::is_contained(successors(PredBB), UniqueSuccessor))
- Updates.push_back({DominatorTree::Insert, PredBB, UniqueSuccessor});
- for (BasicBlock *UniqueSuccessor : UniqueSuccessors)
- Updates.push_back({DominatorTree::Delete, BB, UniqueSuccessor});
+ if (!llvm::is_contained(successors(PredBB), UniqueSuccessor))
+ Updates.push_back({DominatorTree::Insert, PredBB, UniqueSuccessor});
+ for (BasicBlock *UniqueSuccessor : UniqueSuccessors)
+ Updates.push_back({DominatorTree::Delete, BB, UniqueSuccessor});
Updates.push_back({DominatorTree::Delete, PredBB, BB});
}
@@ -305,7 +305,7 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU,
isa<UnreachableInst>(BB->getTerminator()) &&
"The successor list of BB isn't empty before "
"applying corresponding DTU updates.");
- DTU->applyUpdates(Updates);
+ DTU->applyUpdates(Updates);
DTU->deleteBB(BB);
} else {
BB->eraseFromParent(); // Nuke BB if DTU is nullptr.
@@ -497,16 +497,16 @@ void llvm::ReplaceInstWithInst(Instruction *From, Instruction *To) {
}
BasicBlock *llvm::SplitEdge(BasicBlock *BB, BasicBlock *Succ, DominatorTree *DT,
- LoopInfo *LI, MemorySSAUpdater *MSSAU,
- const Twine &BBName) {
+ LoopInfo *LI, MemorySSAUpdater *MSSAU,
+ const Twine &BBName) {
unsigned SuccNum = GetSuccessorNumber(BB, Succ);
// If this is a critical edge, let SplitCriticalEdge do it.
Instruction *LatchTerm = BB->getTerminator();
if (SplitCriticalEdge(
LatchTerm, SuccNum,
- CriticalEdgeSplittingOptions(DT, LI, MSSAU).setPreserveLCSSA(),
- BBName))
+ CriticalEdgeSplittingOptions(DT, LI, MSSAU).setPreserveLCSSA(),
+ BBName))
return LatchTerm->getSuccessor(SuccNum);
// If the edge isn't critical, then BB has a single successor or Succ has a
@@ -516,15 +516,15 @@ BasicBlock *llvm::SplitEdge(BasicBlock *BB, BasicBlock *Succ, DominatorTree *DT,
// block.
assert(SP == BB && "CFG broken");
SP = nullptr;
- return SplitBlock(Succ, &Succ->front(), DT, LI, MSSAU, BBName,
- /*Before=*/true);
+ return SplitBlock(Succ, &Succ->front(), DT, LI, MSSAU, BBName,
+ /*Before=*/true);
}
// Otherwise, if BB has a single successor, split it at the bottom of the
// block.
assert(BB->getTerminator()->getNumSuccessors() == 1 &&
"Should have a single succ!");
- return SplitBlock(BB, BB->getTerminator(), DT, LI, MSSAU, BBName);
+ return SplitBlock(BB, BB->getTerminator(), DT, LI, MSSAU, BBName);
}
unsigned
@@ -542,16 +542,16 @@ llvm::SplitAllCriticalEdges(Function &F,
return NumBroken;
}
-static BasicBlock *SplitBlockImpl(BasicBlock *Old, Instruction *SplitPt,
- DomTreeUpdater *DTU, DominatorTree *DT,
- LoopInfo *LI, MemorySSAUpdater *MSSAU,
- const Twine &BBName, bool Before) {
- if (Before) {
- DomTreeUpdater LocalDTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
- return splitBlockBefore(Old, SplitPt,
- DTU ? DTU : (DT ? &LocalDTU : nullptr), LI, MSSAU,
- BBName);
- }
+static BasicBlock *SplitBlockImpl(BasicBlock *Old, Instruction *SplitPt,
+ DomTreeUpdater *DTU, DominatorTree *DT,
+ LoopInfo *LI, MemorySSAUpdater *MSSAU,
+ const Twine &BBName, bool Before) {
+ if (Before) {
+ DomTreeUpdater LocalDTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
+ return splitBlockBefore(Old, SplitPt,
+ DTU ? DTU : (DT ? &LocalDTU : nullptr), LI, MSSAU,
+ BBName);
+ }
BasicBlock::iterator SplitIt = SplitPt->getIterator();
while (isa<PHINode>(SplitIt) || SplitIt->isEHPad())
++SplitIt;
@@ -565,21 +565,21 @@ static BasicBlock *SplitBlockImpl(BasicBlock *Old, Instruction *SplitPt,
if (Loop *L = LI->getLoopFor(Old))
L->addBasicBlockToLoop(New, *LI);
- if (DTU) {
- SmallVector<DominatorTree::UpdateType, 8> Updates;
+ if (DTU) {
+ SmallVector<DominatorTree::UpdateType, 8> Updates;
+ // Old dominates New. New node dominates all other nodes dominated by Old.
+ SmallSetVector<BasicBlock *, 8> UniqueSuccessorsOfOld(succ_begin(New),
+ succ_end(New));
+ Updates.push_back({DominatorTree::Insert, Old, New});
+ Updates.reserve(Updates.size() + 2 * UniqueSuccessorsOfOld.size());
+ for (BasicBlock *UniqueSuccessorOfOld : UniqueSuccessorsOfOld) {
+ Updates.push_back({DominatorTree::Insert, New, UniqueSuccessorOfOld});
+ Updates.push_back({DominatorTree::Delete, Old, UniqueSuccessorOfOld});
+ }
+
+ DTU->applyUpdates(Updates);
+ } else if (DT)
// Old dominates New. New node dominates all other nodes dominated by Old.
- SmallSetVector<BasicBlock *, 8> UniqueSuccessorsOfOld(succ_begin(New),
- succ_end(New));
- Updates.push_back({DominatorTree::Insert, Old, New});
- Updates.reserve(Updates.size() + 2 * UniqueSuccessorsOfOld.size());
- for (BasicBlock *UniqueSuccessorOfOld : UniqueSuccessorsOfOld) {
- Updates.push_back({DominatorTree::Insert, New, UniqueSuccessorOfOld});
- Updates.push_back({DominatorTree::Delete, Old, UniqueSuccessorOfOld});
- }
-
- DTU->applyUpdates(Updates);
- } else if (DT)
- // Old dominates New. New node dominates all other nodes dominated by Old.
if (DomTreeNode *OldNode = DT->getNode(Old)) {
std::vector<DomTreeNode *> Children(OldNode->begin(), OldNode->end());
@@ -596,94 +596,94 @@ static BasicBlock *SplitBlockImpl(BasicBlock *Old, Instruction *SplitPt,
return New;
}
-BasicBlock *llvm::SplitBlock(BasicBlock *Old, Instruction *SplitPt,
- DominatorTree *DT, LoopInfo *LI,
- MemorySSAUpdater *MSSAU, const Twine &BBName,
- bool Before) {
- return SplitBlockImpl(Old, SplitPt, /*DTU=*/nullptr, DT, LI, MSSAU, BBName,
- Before);
-}
-BasicBlock *llvm::SplitBlock(BasicBlock *Old, Instruction *SplitPt,
- DomTreeUpdater *DTU, LoopInfo *LI,
- MemorySSAUpdater *MSSAU, const Twine &BBName,
- bool Before) {
- return SplitBlockImpl(Old, SplitPt, DTU, /*DT=*/nullptr, LI, MSSAU, BBName,
- Before);
-}
-
-BasicBlock *llvm::splitBlockBefore(BasicBlock *Old, Instruction *SplitPt,
- DomTreeUpdater *DTU, LoopInfo *LI,
- MemorySSAUpdater *MSSAU,
- const Twine &BBName) {
-
- BasicBlock::iterator SplitIt = SplitPt->getIterator();
- while (isa<PHINode>(SplitIt) || SplitIt->isEHPad())
- ++SplitIt;
- std::string Name = BBName.str();
- BasicBlock *New = Old->splitBasicBlock(
- SplitIt, Name.empty() ? Old->getName() + ".split" : Name,
- /* Before=*/true);
-
- // The new block lives in whichever loop the old one did. This preserves
- // LCSSA as well, because we force the split point to be after any PHI nodes.
- if (LI)
- if (Loop *L = LI->getLoopFor(Old))
- L->addBasicBlockToLoop(New, *LI);
-
- if (DTU) {
- SmallVector<DominatorTree::UpdateType, 8> DTUpdates;
- // New dominates Old. The predecessor nodes of the Old node dominate
- // New node.
- SmallSetVector<BasicBlock *, 8> UniquePredecessorsOfOld(pred_begin(New),
- pred_end(New));
- DTUpdates.push_back({DominatorTree::Insert, New, Old});
- DTUpdates.reserve(DTUpdates.size() + 2 * UniquePredecessorsOfOld.size());
- for (BasicBlock *UniquePredecessorOfOld : UniquePredecessorsOfOld) {
- DTUpdates.push_back({DominatorTree::Insert, UniquePredecessorOfOld, New});
- DTUpdates.push_back({DominatorTree::Delete, UniquePredecessorOfOld, Old});
- }
-
- DTU->applyUpdates(DTUpdates);
-
- // Move MemoryAccesses still tracked in Old, but part of New now.
- // Update accesses in successor blocks accordingly.
- if (MSSAU) {
- MSSAU->applyUpdates(DTUpdates, DTU->getDomTree());
- if (VerifyMemorySSA)
- MSSAU->getMemorySSA()->verifyMemorySSA();
- }
- }
- return New;
-}
-
+BasicBlock *llvm::SplitBlock(BasicBlock *Old, Instruction *SplitPt,
+ DominatorTree *DT, LoopInfo *LI,
+ MemorySSAUpdater *MSSAU, const Twine &BBName,
+ bool Before) {
+ return SplitBlockImpl(Old, SplitPt, /*DTU=*/nullptr, DT, LI, MSSAU, BBName,
+ Before);
+}
+BasicBlock *llvm::SplitBlock(BasicBlock *Old, Instruction *SplitPt,
+ DomTreeUpdater *DTU, LoopInfo *LI,
+ MemorySSAUpdater *MSSAU, const Twine &BBName,
+ bool Before) {
+ return SplitBlockImpl(Old, SplitPt, DTU, /*DT=*/nullptr, LI, MSSAU, BBName,
+ Before);
+}
+
+BasicBlock *llvm::splitBlockBefore(BasicBlock *Old, Instruction *SplitPt,
+ DomTreeUpdater *DTU, LoopInfo *LI,
+ MemorySSAUpdater *MSSAU,
+ const Twine &BBName) {
+
+ BasicBlock::iterator SplitIt = SplitPt->getIterator();
+ while (isa<PHINode>(SplitIt) || SplitIt->isEHPad())
+ ++SplitIt;
+ std::string Name = BBName.str();
+ BasicBlock *New = Old->splitBasicBlock(
+ SplitIt, Name.empty() ? Old->getName() + ".split" : Name,
+ /* Before=*/true);
+
+ // The new block lives in whichever loop the old one did. This preserves
+ // LCSSA as well, because we force the split point to be after any PHI nodes.
+ if (LI)
+ if (Loop *L = LI->getLoopFor(Old))
+ L->addBasicBlockToLoop(New, *LI);
+
+ if (DTU) {
+ SmallVector<DominatorTree::UpdateType, 8> DTUpdates;
+ // New dominates Old. The predecessor nodes of the Old node dominate
+ // New node.
+ SmallSetVector<BasicBlock *, 8> UniquePredecessorsOfOld(pred_begin(New),
+ pred_end(New));
+ DTUpdates.push_back({DominatorTree::Insert, New, Old});
+ DTUpdates.reserve(DTUpdates.size() + 2 * UniquePredecessorsOfOld.size());
+ for (BasicBlock *UniquePredecessorOfOld : UniquePredecessorsOfOld) {
+ DTUpdates.push_back({DominatorTree::Insert, UniquePredecessorOfOld, New});
+ DTUpdates.push_back({DominatorTree::Delete, UniquePredecessorOfOld, Old});
+ }
+
+ DTU->applyUpdates(DTUpdates);
+
+ // Move MemoryAccesses still tracked in Old, but part of New now.
+ // Update accesses in successor blocks accordingly.
+ if (MSSAU) {
+ MSSAU->applyUpdates(DTUpdates, DTU->getDomTree());
+ if (VerifyMemorySSA)
+ MSSAU->getMemorySSA()->verifyMemorySSA();
+ }
+ }
+ return New;
+}
+
/// Update DominatorTree, LoopInfo, and LCCSA analysis information.
static void UpdateAnalysisInformation(BasicBlock *OldBB, BasicBlock *NewBB,
ArrayRef<BasicBlock *> Preds,
- DomTreeUpdater *DTU, DominatorTree *DT,
- LoopInfo *LI, MemorySSAUpdater *MSSAU,
+ DomTreeUpdater *DTU, DominatorTree *DT,
+ LoopInfo *LI, MemorySSAUpdater *MSSAU,
bool PreserveLCSSA, bool &HasLoopExit) {
// Update dominator tree if available.
- if (DTU) {
- // Recalculation of DomTree is needed when updating a forward DomTree and
- // the Entry BB is replaced.
- if (NewBB == &NewBB->getParent()->getEntryBlock() && DTU->hasDomTree()) {
- // The entry block was removed and there is no external interface for
- // the dominator tree to be notified of this change. In this corner-case
- // we recalculate the entire tree.
- DTU->recalculate(*NewBB->getParent());
- } else {
- // Split block expects NewBB to have a non-empty set of predecessors.
- SmallVector<DominatorTree::UpdateType, 8> Updates;
- SmallSetVector<BasicBlock *, 8> UniquePreds(Preds.begin(), Preds.end());
- Updates.push_back({DominatorTree::Insert, NewBB, OldBB});
- Updates.reserve(Updates.size() + 2 * UniquePreds.size());
- for (auto *UniquePred : UniquePreds) {
- Updates.push_back({DominatorTree::Insert, UniquePred, NewBB});
- Updates.push_back({DominatorTree::Delete, UniquePred, OldBB});
- }
- DTU->applyUpdates(Updates);
- }
- } else if (DT) {
+ if (DTU) {
+ // Recalculation of DomTree is needed when updating a forward DomTree and
+ // the Entry BB is replaced.
+ if (NewBB == &NewBB->getParent()->getEntryBlock() && DTU->hasDomTree()) {
+ // The entry block was removed and there is no external interface for
+ // the dominator tree to be notified of this change. In this corner-case
+ // we recalculate the entire tree.
+ DTU->recalculate(*NewBB->getParent());
+ } else {
+ // Split block expects NewBB to have a non-empty set of predecessors.
+ SmallVector<DominatorTree::UpdateType, 8> Updates;
+ SmallSetVector<BasicBlock *, 8> UniquePreds(Preds.begin(), Preds.end());
+ Updates.push_back({DominatorTree::Insert, NewBB, OldBB});
+ Updates.reserve(Updates.size() + 2 * UniquePreds.size());
+ for (auto *UniquePred : UniquePreds) {
+ Updates.push_back({DominatorTree::Insert, UniquePred, NewBB});
+ Updates.push_back({DominatorTree::Delete, UniquePred, OldBB});
+ }
+ DTU->applyUpdates(Updates);
+ }
+ } else if (DT) {
if (OldBB == DT->getRootNode()->getBlock()) {
assert(NewBB == &NewBB->getParent()->getEntryBlock());
DT->setNewRoot(NewBB);
@@ -701,8 +701,8 @@ static void UpdateAnalysisInformation(BasicBlock *OldBB, BasicBlock *NewBB,
if (!LI)
return;
- if (DTU && DTU->hasDomTree())
- DT = &DTU->getDomTree();
+ if (DTU && DTU->hasDomTree())
+ DT = &DTU->getDomTree();
assert(DT && "DT should be available to update LoopInfo!");
Loop *L = LI->getLoopFor(OldBB);
@@ -836,17 +836,17 @@ static void UpdatePHINodes(BasicBlock *OrigBB, BasicBlock *NewBB,
}
}
-static void SplitLandingPadPredecessorsImpl(
- BasicBlock *OrigBB, ArrayRef<BasicBlock *> Preds, const char *Suffix1,
- const char *Suffix2, SmallVectorImpl<BasicBlock *> &NewBBs,
- DomTreeUpdater *DTU, DominatorTree *DT, LoopInfo *LI,
- MemorySSAUpdater *MSSAU, bool PreserveLCSSA);
-
-static BasicBlock *
-SplitBlockPredecessorsImpl(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
- const char *Suffix, DomTreeUpdater *DTU,
- DominatorTree *DT, LoopInfo *LI,
- MemorySSAUpdater *MSSAU, bool PreserveLCSSA) {
+static void SplitLandingPadPredecessorsImpl(
+ BasicBlock *OrigBB, ArrayRef<BasicBlock *> Preds, const char *Suffix1,
+ const char *Suffix2, SmallVectorImpl<BasicBlock *> &NewBBs,
+ DomTreeUpdater *DTU, DominatorTree *DT, LoopInfo *LI,
+ MemorySSAUpdater *MSSAU, bool PreserveLCSSA);
+
+static BasicBlock *
+SplitBlockPredecessorsImpl(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
+ const char *Suffix, DomTreeUpdater *DTU,
+ DominatorTree *DT, LoopInfo *LI,
+ MemorySSAUpdater *MSSAU, bool PreserveLCSSA) {
// Do not attempt to split that which cannot be split.
if (!BB->canSplitPredecessors())
return nullptr;
@@ -857,8 +857,8 @@ SplitBlockPredecessorsImpl(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
SmallVector<BasicBlock*, 2> NewBBs;
std::string NewName = std::string(Suffix) + ".split-lp";
- SplitLandingPadPredecessorsImpl(BB, Preds, Suffix, NewName.c_str(), NewBBs,
- DTU, DT, LI, MSSAU, PreserveLCSSA);
+ SplitLandingPadPredecessorsImpl(BB, Preds, Suffix, NewName.c_str(), NewBBs,
+ DTU, DT, LI, MSSAU, PreserveLCSSA);
return NewBBs[0];
}
@@ -868,22 +868,22 @@ SplitBlockPredecessorsImpl(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
// The new block unconditionally branches to the old block.
BranchInst *BI = BranchInst::Create(BB, NewBB);
-
- Loop *L = nullptr;
- BasicBlock *OldLatch = nullptr;
+
+ Loop *L = nullptr;
+ BasicBlock *OldLatch = nullptr;
// Splitting the predecessors of a loop header creates a preheader block.
- if (LI && LI->isLoopHeader(BB)) {
- L = LI->getLoopFor(BB);
+ if (LI && LI->isLoopHeader(BB)) {
+ L = LI->getLoopFor(BB);
// Using the loop start line number prevents debuggers stepping into the
// loop body for this instruction.
- BI->setDebugLoc(L->getStartLoc());
-
- // If BB is the header of the Loop, it is possible that the loop is
- // modified, such that the current latch does not remain the latch of the
- // loop. If that is the case, the loop metadata from the current latch needs
- // to be applied to the new latch.
- OldLatch = L->getLoopLatch();
- } else
+ BI->setDebugLoc(L->getStartLoc());
+
+ // If BB is the header of the Loop, it is possible that the loop is
+ // modified, such that the current latch does not remain the latch of the
+ // loop. If that is the case, the loop metadata from the current latch needs
+ // to be applied to the new latch.
+ OldLatch = L->getLoopLatch();
+ } else
BI->setDebugLoc(BB->getFirstNonPHIOrDbg()->getDebugLoc());
// Move the edges from Preds to point to NewBB instead of BB.
@@ -910,7 +910,7 @@ SplitBlockPredecessorsImpl(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
// Update DominatorTree, LoopInfo, and LCCSA analysis information.
bool HasLoopExit = false;
- UpdateAnalysisInformation(BB, NewBB, Preds, DTU, DT, LI, MSSAU, PreserveLCSSA,
+ UpdateAnalysisInformation(BB, NewBB, Preds, DTU, DT, LI, MSSAU, PreserveLCSSA,
HasLoopExit);
if (!Preds.empty()) {
@@ -918,41 +918,41 @@ SplitBlockPredecessorsImpl(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
UpdatePHINodes(BB, NewBB, Preds, BI, HasLoopExit);
}
- if (OldLatch) {
- BasicBlock *NewLatch = L->getLoopLatch();
- if (NewLatch != OldLatch) {
- MDNode *MD = OldLatch->getTerminator()->getMetadata("llvm.loop");
- NewLatch->getTerminator()->setMetadata("llvm.loop", MD);
- OldLatch->getTerminator()->setMetadata("llvm.loop", nullptr);
- }
- }
-
+ if (OldLatch) {
+ BasicBlock *NewLatch = L->getLoopLatch();
+ if (NewLatch != OldLatch) {
+ MDNode *MD = OldLatch->getTerminator()->getMetadata("llvm.loop");
+ NewLatch->getTerminator()->setMetadata("llvm.loop", MD);
+ OldLatch->getTerminator()->setMetadata("llvm.loop", nullptr);
+ }
+ }
+
return NewBB;
}
-BasicBlock *llvm::SplitBlockPredecessors(BasicBlock *BB,
- ArrayRef<BasicBlock *> Preds,
- const char *Suffix, DominatorTree *DT,
- LoopInfo *LI, MemorySSAUpdater *MSSAU,
- bool PreserveLCSSA) {
- return SplitBlockPredecessorsImpl(BB, Preds, Suffix, /*DTU=*/nullptr, DT, LI,
- MSSAU, PreserveLCSSA);
-}
-BasicBlock *llvm::SplitBlockPredecessors(BasicBlock *BB,
- ArrayRef<BasicBlock *> Preds,
- const char *Suffix,
- DomTreeUpdater *DTU, LoopInfo *LI,
- MemorySSAUpdater *MSSAU,
- bool PreserveLCSSA) {
- return SplitBlockPredecessorsImpl(BB, Preds, Suffix, DTU,
- /*DT=*/nullptr, LI, MSSAU, PreserveLCSSA);
-}
-
-static void SplitLandingPadPredecessorsImpl(
- BasicBlock *OrigBB, ArrayRef<BasicBlock *> Preds, const char *Suffix1,
- const char *Suffix2, SmallVectorImpl<BasicBlock *> &NewBBs,
- DomTreeUpdater *DTU, DominatorTree *DT, LoopInfo *LI,
- MemorySSAUpdater *MSSAU, bool PreserveLCSSA) {
+BasicBlock *llvm::SplitBlockPredecessors(BasicBlock *BB,
+ ArrayRef<BasicBlock *> Preds,
+ const char *Suffix, DominatorTree *DT,
+ LoopInfo *LI, MemorySSAUpdater *MSSAU,
+ bool PreserveLCSSA) {
+ return SplitBlockPredecessorsImpl(BB, Preds, Suffix, /*DTU=*/nullptr, DT, LI,
+ MSSAU, PreserveLCSSA);
+}
+BasicBlock *llvm::SplitBlockPredecessors(BasicBlock *BB,
+ ArrayRef<BasicBlock *> Preds,
+ const char *Suffix,
+ DomTreeUpdater *DTU, LoopInfo *LI,
+ MemorySSAUpdater *MSSAU,
+ bool PreserveLCSSA) {
+ return SplitBlockPredecessorsImpl(BB, Preds, Suffix, DTU,
+ /*DT=*/nullptr, LI, MSSAU, PreserveLCSSA);
+}
+
+static void SplitLandingPadPredecessorsImpl(
+ BasicBlock *OrigBB, ArrayRef<BasicBlock *> Preds, const char *Suffix1,
+ const char *Suffix2, SmallVectorImpl<BasicBlock *> &NewBBs,
+ DomTreeUpdater *DTU, DominatorTree *DT, LoopInfo *LI,
+ MemorySSAUpdater *MSSAU, bool PreserveLCSSA) {
assert(OrigBB->isLandingPad() && "Trying to split a non-landing pad!");
// Create a new basic block for OrigBB's predecessors listed in Preds. Insert
@@ -977,8 +977,8 @@ static void SplitLandingPadPredecessorsImpl(
}
bool HasLoopExit = false;
- UpdateAnalysisInformation(OrigBB, NewBB1, Preds, DTU, DT, LI, MSSAU,
- PreserveLCSSA, HasLoopExit);
+ UpdateAnalysisInformation(OrigBB, NewBB1, Preds, DTU, DT, LI, MSSAU,
+ PreserveLCSSA, HasLoopExit);
// Update the PHI nodes in OrigBB with the values coming from NewBB1.
UpdatePHINodes(OrigBB, NewBB1, Preds, BI1, HasLoopExit);
@@ -1013,7 +1013,7 @@ static void SplitLandingPadPredecessorsImpl(
// Update DominatorTree, LoopInfo, and LCCSA analysis information.
HasLoopExit = false;
- UpdateAnalysisInformation(OrigBB, NewBB2, NewBB2Preds, DTU, DT, LI, MSSAU,
+ UpdateAnalysisInformation(OrigBB, NewBB2, NewBB2Preds, DTU, DT, LI, MSSAU,
PreserveLCSSA, HasLoopExit);
// Update the PHI nodes in OrigBB with the values coming from NewBB2.
@@ -1050,29 +1050,29 @@ static void SplitLandingPadPredecessorsImpl(
}
}
-void llvm::SplitLandingPadPredecessors(BasicBlock *OrigBB,
- ArrayRef<BasicBlock *> Preds,
- const char *Suffix1, const char *Suffix2,
- SmallVectorImpl<BasicBlock *> &NewBBs,
- DominatorTree *DT, LoopInfo *LI,
- MemorySSAUpdater *MSSAU,
- bool PreserveLCSSA) {
- return SplitLandingPadPredecessorsImpl(
- OrigBB, Preds, Suffix1, Suffix2, NewBBs,
- /*DTU=*/nullptr, DT, LI, MSSAU, PreserveLCSSA);
-}
-void llvm::SplitLandingPadPredecessors(BasicBlock *OrigBB,
- ArrayRef<BasicBlock *> Preds,
- const char *Suffix1, const char *Suffix2,
- SmallVectorImpl<BasicBlock *> &NewBBs,
- DomTreeUpdater *DTU, LoopInfo *LI,
- MemorySSAUpdater *MSSAU,
- bool PreserveLCSSA) {
- return SplitLandingPadPredecessorsImpl(OrigBB, Preds, Suffix1, Suffix2,
- NewBBs, DTU, /*DT=*/nullptr, LI, MSSAU,
- PreserveLCSSA);
-}
-
+void llvm::SplitLandingPadPredecessors(BasicBlock *OrigBB,
+ ArrayRef<BasicBlock *> Preds,
+ const char *Suffix1, const char *Suffix2,
+ SmallVectorImpl<BasicBlock *> &NewBBs,
+ DominatorTree *DT, LoopInfo *LI,
+ MemorySSAUpdater *MSSAU,
+ bool PreserveLCSSA) {
+ return SplitLandingPadPredecessorsImpl(
+ OrigBB, Preds, Suffix1, Suffix2, NewBBs,
+ /*DTU=*/nullptr, DT, LI, MSSAU, PreserveLCSSA);
+}
+void llvm::SplitLandingPadPredecessors(BasicBlock *OrigBB,
+ ArrayRef<BasicBlock *> Preds,
+ const char *Suffix1, const char *Suffix2,
+ SmallVectorImpl<BasicBlock *> &NewBBs,
+ DomTreeUpdater *DTU, LoopInfo *LI,
+ MemorySSAUpdater *MSSAU,
+ bool PreserveLCSSA) {
+ return SplitLandingPadPredecessorsImpl(OrigBB, Preds, Suffix1, Suffix2,
+ NewBBs, DTU, /*DT=*/nullptr, LI, MSSAU,
+ PreserveLCSSA);
+}
+
ReturnInst *llvm::FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
BasicBlock *Pred,
DomTreeUpdater *DTU) {
@@ -1132,24 +1132,24 @@ ReturnInst *llvm::FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
return cast<ReturnInst>(NewRet);
}
-static Instruction *
-SplitBlockAndInsertIfThenImpl(Value *Cond, Instruction *SplitBefore,
- bool Unreachable, MDNode *BranchWeights,
- DomTreeUpdater *DTU, DominatorTree *DT,
- LoopInfo *LI, BasicBlock *ThenBlock) {
- SmallVector<DominatorTree::UpdateType, 8> Updates;
+static Instruction *
+SplitBlockAndInsertIfThenImpl(Value *Cond, Instruction *SplitBefore,
+ bool Unreachable, MDNode *BranchWeights,
+ DomTreeUpdater *DTU, DominatorTree *DT,
+ LoopInfo *LI, BasicBlock *ThenBlock) {
+ SmallVector<DominatorTree::UpdateType, 8> Updates;
BasicBlock *Head = SplitBefore->getParent();
BasicBlock *Tail = Head->splitBasicBlock(SplitBefore->getIterator());
- if (DTU) {
- SmallSetVector<BasicBlock *, 8> UniqueSuccessorsOfHead(succ_begin(Tail),
- succ_end(Tail));
- Updates.push_back({DominatorTree::Insert, Head, Tail});
- Updates.reserve(Updates.size() + 2 * UniqueSuccessorsOfHead.size());
- for (BasicBlock *UniqueSuccessorOfHead : UniqueSuccessorsOfHead) {
- Updates.push_back({DominatorTree::Insert, Tail, UniqueSuccessorOfHead});
- Updates.push_back({DominatorTree::Delete, Head, UniqueSuccessorOfHead});
- }
- }
+ if (DTU) {
+ SmallSetVector<BasicBlock *, 8> UniqueSuccessorsOfHead(succ_begin(Tail),
+ succ_end(Tail));
+ Updates.push_back({DominatorTree::Insert, Head, Tail});
+ Updates.reserve(Updates.size() + 2 * UniqueSuccessorsOfHead.size());
+ for (BasicBlock *UniqueSuccessorOfHead : UniqueSuccessorsOfHead) {
+ Updates.push_back({DominatorTree::Insert, Tail, UniqueSuccessorOfHead});
+ Updates.push_back({DominatorTree::Delete, Head, UniqueSuccessorOfHead});
+ }
+ }
Instruction *HeadOldTerm = Head->getTerminator();
LLVMContext &C = Head->getContext();
Instruction *CheckTerm;
@@ -1158,24 +1158,24 @@ SplitBlockAndInsertIfThenImpl(Value *Cond, Instruction *SplitBefore,
ThenBlock = BasicBlock::Create(C, "", Head->getParent(), Tail);
if (Unreachable)
CheckTerm = new UnreachableInst(C, ThenBlock);
- else {
+ else {
CheckTerm = BranchInst::Create(Tail, ThenBlock);
- if (DTU)
- Updates.push_back({DominatorTree::Insert, ThenBlock, Tail});
- }
+ if (DTU)
+ Updates.push_back({DominatorTree::Insert, ThenBlock, Tail});
+ }
CheckTerm->setDebugLoc(SplitBefore->getDebugLoc());
} else
CheckTerm = ThenBlock->getTerminator();
BranchInst *HeadNewTerm =
- BranchInst::Create(/*ifTrue*/ ThenBlock, /*ifFalse*/ Tail, Cond);
- if (DTU)
- Updates.push_back({DominatorTree::Insert, Head, ThenBlock});
+ BranchInst::Create(/*ifTrue*/ ThenBlock, /*ifFalse*/ Tail, Cond);
+ if (DTU)
+ Updates.push_back({DominatorTree::Insert, Head, ThenBlock});
HeadNewTerm->setMetadata(LLVMContext::MD_prof, BranchWeights);
ReplaceInstWithInst(HeadOldTerm, HeadNewTerm);
- if (DTU)
- DTU->applyUpdates(Updates);
- else if (DT) {
+ if (DTU)
+ DTU->applyUpdates(Updates);
+ else if (DT) {
if (DomTreeNode *OldNode = DT->getNode(Head)) {
std::vector<DomTreeNode *> Children(OldNode->begin(), OldNode->end());
@@ -1201,27 +1201,27 @@ SplitBlockAndInsertIfThenImpl(Value *Cond, Instruction *SplitBefore,
return CheckTerm;
}
-Instruction *llvm::SplitBlockAndInsertIfThen(Value *Cond,
- Instruction *SplitBefore,
- bool Unreachable,
- MDNode *BranchWeights,
- DominatorTree *DT, LoopInfo *LI,
- BasicBlock *ThenBlock) {
- return SplitBlockAndInsertIfThenImpl(Cond, SplitBefore, Unreachable,
- BranchWeights,
- /*DTU=*/nullptr, DT, LI, ThenBlock);
-}
-Instruction *llvm::SplitBlockAndInsertIfThen(Value *Cond,
- Instruction *SplitBefore,
- bool Unreachable,
- MDNode *BranchWeights,
- DomTreeUpdater *DTU, LoopInfo *LI,
- BasicBlock *ThenBlock) {
- return SplitBlockAndInsertIfThenImpl(Cond, SplitBefore, Unreachable,
- BranchWeights, DTU, /*DT=*/nullptr, LI,
- ThenBlock);
-}
-
+Instruction *llvm::SplitBlockAndInsertIfThen(Value *Cond,
+ Instruction *SplitBefore,
+ bool Unreachable,
+ MDNode *BranchWeights,
+ DominatorTree *DT, LoopInfo *LI,
+ BasicBlock *ThenBlock) {
+ return SplitBlockAndInsertIfThenImpl(Cond, SplitBefore, Unreachable,
+ BranchWeights,
+ /*DTU=*/nullptr, DT, LI, ThenBlock);
+}
+Instruction *llvm::SplitBlockAndInsertIfThen(Value *Cond,
+ Instruction *SplitBefore,
+ bool Unreachable,
+ MDNode *BranchWeights,
+ DomTreeUpdater *DTU, LoopInfo *LI,
+ BasicBlock *ThenBlock) {
+ return SplitBlockAndInsertIfThenImpl(Cond, SplitBefore, Unreachable,
+ BranchWeights, DTU, /*DT=*/nullptr, LI,
+ ThenBlock);
+}
+
void llvm::SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore,
Instruction **ThenTerm,
Instruction **ElseTerm,
@@ -1532,7 +1532,7 @@ BasicBlock *llvm::CreateControlFlowHub(
SmallVector<DominatorTree::UpdateType, 16> Updates;
if (DTU) {
for (auto In : Incoming) {
- Updates.push_back({DominatorTree::Insert, In, FirstGuardBlock});
+ Updates.push_back({DominatorTree::Insert, In, FirstGuardBlock});
for (auto Succ : successors(In)) {
if (Outgoing.count(Succ))
Updates.push_back({DominatorTree::Delete, In, Succ});
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/BreakCriticalEdges.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/BreakCriticalEdges.cpp
index df6a710afe..939a1a3a86 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/BreakCriticalEdges.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/BreakCriticalEdges.cpp
@@ -134,9 +134,9 @@ static void createPHIsForSplitLoopExit(ArrayRef<BasicBlock *> Preds,
}
}
-BasicBlock *llvm::SplitCriticalEdge(Instruction *TI, unsigned SuccNum,
- const CriticalEdgeSplittingOptions &Options,
- const Twine &BBName) {
+BasicBlock *llvm::SplitCriticalEdge(Instruction *TI, unsigned SuccNum,
+ const CriticalEdgeSplittingOptions &Options,
+ const Twine &BBName) {
if (!isCriticalEdge(TI, SuccNum, Options.MergeIdenticalEdges))
return nullptr;
@@ -158,21 +158,21 @@ BasicBlock *llvm::SplitCriticalEdge(Instruction *TI, unsigned SuccNum,
SmallVector<BasicBlock *, 4> LoopPreds;
// Check if extra modifications will be required to preserve loop-simplify
// form after splitting. If it would require splitting blocks with IndirectBr
- // or CallBr terminators, bail out if preserving loop-simplify form is
- // requested.
+ // or CallBr terminators, bail out if preserving loop-simplify form is
+ // requested.
if (LI) {
if (Loop *TIL = LI->getLoopFor(TIBB)) {
- // The only way that we can break LoopSimplify form by splitting a
- // critical edge is if after the split there exists some edge from TIL to
- // DestBB *and* the only edge into DestBB from outside of TIL is that of
+ // The only way that we can break LoopSimplify form by splitting a
+ // critical edge is if after the split there exists some edge from TIL to
+ // DestBB *and* the only edge into DestBB from outside of TIL is that of
// NewBB. If the first isn't true, then LoopSimplify still holds, NewBB
// is the new exit block and it has no non-loop predecessors. If the
// second isn't true, then DestBB was not in LoopSimplify form prior to
// the split as it had a non-loop predecessor. In both of these cases,
// the predecessor must be directly in TIL, not in a subloop, or again
// LoopSimplify doesn't hold.
- for (BasicBlock *P : predecessors(DestBB)) {
+ for (BasicBlock *P : predecessors(DestBB)) {
if (P == TIBB)
continue; // The new block is known.
if (LI->getLoopFor(P) != TIL) {
@@ -185,10 +185,10 @@ BasicBlock *llvm::SplitCriticalEdge(Instruction *TI, unsigned SuccNum,
// Loop-simplify form can be preserved, if we can split all in-loop
// predecessors.
if (any_of(LoopPreds, [](BasicBlock *Pred) {
- const Instruction *T = Pred->getTerminator();
- if (const auto *CBR = dyn_cast<CallBrInst>(T))
- return CBR->getDefaultDest() != Pred;
- return isa<IndirectBrInst>(T);
+ const Instruction *T = Pred->getTerminator();
+ if (const auto *CBR = dyn_cast<CallBrInst>(T))
+ return CBR->getDefaultDest() != Pred;
+ return isa<IndirectBrInst>(T);
})) {
if (Options.PreserveLoopSimplify)
return nullptr;
@@ -198,13 +198,13 @@ BasicBlock *llvm::SplitCriticalEdge(Instruction *TI, unsigned SuccNum,
}
// Create a new basic block, linking it into the CFG.
- BasicBlock *NewBB = nullptr;
- if (BBName.str() != "")
- NewBB = BasicBlock::Create(TI->getContext(), BBName);
- else
- NewBB = BasicBlock::Create(TI->getContext(), TIBB->getName() + "." +
- DestBB->getName() +
- "_crit_edge");
+ BasicBlock *NewBB = nullptr;
+ if (BBName.str() != "")
+ NewBB = BasicBlock::Create(TI->getContext(), BBName);
+ else
+ NewBB = BasicBlock::Create(TI->getContext(), TIBB->getName() + "." +
+ DestBB->getName() +
+ "_crit_edge");
// Create our unconditional branch.
BranchInst *NewBI = BranchInst::Create(DestBB, NewBB);
NewBI->setDebugLoc(TI->getDebugLoc());
@@ -277,7 +277,7 @@ BasicBlock *llvm::SplitCriticalEdge(Instruction *TI, unsigned SuccNum,
SmallVector<DominatorTree::UpdateType, 3> Updates;
Updates.push_back({DominatorTree::Insert, TIBB, NewBB});
Updates.push_back({DominatorTree::Insert, NewBB, DestBB});
- if (!llvm::is_contained(successors(TIBB), DestBB))
+ if (!llvm::is_contained(successors(TIBB), DestBB))
Updates.push_back({DominatorTree::Delete, TIBB, DestBB});
if (DT)
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/BuildLibCalls.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/BuildLibCalls.cpp
index a35a9f6613..dba5403f27 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/BuildLibCalls.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -31,22 +31,22 @@ using namespace llvm;
//- Infer Attributes ---------------------------------------------------------//
STATISTIC(NumReadNone, "Number of functions inferred as readnone");
-STATISTIC(NumInaccessibleMemOnly,
- "Number of functions inferred as inaccessiblememonly");
+STATISTIC(NumInaccessibleMemOnly,
+ "Number of functions inferred as inaccessiblememonly");
STATISTIC(NumReadOnly, "Number of functions inferred as readonly");
STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");
-STATISTIC(NumInaccessibleMemOrArgMemOnly,
- "Number of functions inferred as inaccessiblemem_or_argmemonly");
+STATISTIC(NumInaccessibleMemOrArgMemOnly,
+ "Number of functions inferred as inaccessiblemem_or_argmemonly");
STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
-STATISTIC(NumWriteOnlyArg, "Number of arguments inferred as writeonly");
-STATISTIC(NumSExtArg, "Number of arguments inferred as signext");
+STATISTIC(NumWriteOnlyArg, "Number of arguments inferred as writeonly");
+STATISTIC(NumSExtArg, "Number of arguments inferred as signext");
STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");
STATISTIC(NumNoAlias, "Number of function returns inferred as noalias");
-STATISTIC(NumNoUndef, "Number of function returns inferred as noundef returns");
+STATISTIC(NumNoUndef, "Number of function returns inferred as noundef returns");
STATISTIC(NumNonNull, "Number of function returns inferred as nonnull returns");
STATISTIC(NumReturnedArg, "Number of arguments inferred as returned");
-STATISTIC(NumWillReturn, "Number of functions inferred as willreturn");
+STATISTIC(NumWillReturn, "Number of functions inferred as willreturn");
static bool setDoesNotAccessMemory(Function &F) {
if (F.doesNotAccessMemory())
@@ -56,14 +56,14 @@ static bool setDoesNotAccessMemory(Function &F) {
return true;
}
-static bool setOnlyAccessesInaccessibleMemory(Function &F) {
- if (F.onlyAccessesInaccessibleMemory())
- return false;
- F.setOnlyAccessesInaccessibleMemory();
- ++NumInaccessibleMemOnly;
- return true;
-}
-
+static bool setOnlyAccessesInaccessibleMemory(Function &F) {
+ if (F.onlyAccessesInaccessibleMemory())
+ return false;
+ F.setOnlyAccessesInaccessibleMemory();
+ ++NumInaccessibleMemOnly;
+ return true;
+}
+
static bool setOnlyReadsMemory(Function &F) {
if (F.onlyReadsMemory())
return false;
@@ -80,14 +80,14 @@ static bool setOnlyAccessesArgMemory(Function &F) {
return true;
}
-static bool setOnlyAccessesInaccessibleMemOrArgMem(Function &F) {
- if (F.onlyAccessesInaccessibleMemOrArgMem())
- return false;
- F.setOnlyAccessesInaccessibleMemOrArgMem();
- ++NumInaccessibleMemOrArgMemOnly;
- return true;
-}
-
+static bool setOnlyAccessesInaccessibleMemOrArgMem(Function &F) {
+ if (F.onlyAccessesInaccessibleMemOrArgMem())
+ return false;
+ F.setOnlyAccessesInaccessibleMemOrArgMem();
+ ++NumInaccessibleMemOrArgMemOnly;
+ return true;
+}
+
static bool setDoesNotThrow(Function &F) {
if (F.doesNotThrow())
return false;
@@ -128,48 +128,48 @@ static bool setOnlyReadsMemory(Function &F, unsigned ArgNo) {
return true;
}
-static bool setOnlyWritesMemory(Function &F, unsigned ArgNo) {
- if (F.hasParamAttribute(ArgNo, Attribute::WriteOnly))
+static bool setOnlyWritesMemory(Function &F, unsigned ArgNo) {
+ if (F.hasParamAttribute(ArgNo, Attribute::WriteOnly))
return false;
- F.addParamAttr(ArgNo, Attribute::WriteOnly);
- ++NumWriteOnlyArg;
+ F.addParamAttr(ArgNo, Attribute::WriteOnly);
+ ++NumWriteOnlyArg;
return true;
}
-static bool setSignExtendedArg(Function &F, unsigned ArgNo) {
- if (F.hasParamAttribute(ArgNo, Attribute::SExt))
- return false;
- F.addParamAttr(ArgNo, Attribute::SExt);
- ++NumSExtArg;
- return true;
-}
-
-static bool setRetNoUndef(Function &F) {
- if (!F.getReturnType()->isVoidTy() &&
- !F.hasAttribute(AttributeList::ReturnIndex, Attribute::NoUndef)) {
- F.addAttribute(AttributeList::ReturnIndex, Attribute::NoUndef);
- ++NumNoUndef;
- return true;
- }
- return false;
-}
-
-static bool setArgsNoUndef(Function &F) {
- bool Changed = false;
- for (unsigned ArgNo = 0; ArgNo < F.arg_size(); ++ArgNo) {
- if (!F.hasParamAttribute(ArgNo, Attribute::NoUndef)) {
- F.addParamAttr(ArgNo, Attribute::NoUndef);
- ++NumNoUndef;
- Changed = true;
- }
- }
- return Changed;
-}
-
-static bool setRetAndArgsNoUndef(Function &F) {
- return setRetNoUndef(F) | setArgsNoUndef(F);
-}
-
+static bool setSignExtendedArg(Function &F, unsigned ArgNo) {
+ if (F.hasParamAttribute(ArgNo, Attribute::SExt))
+ return false;
+ F.addParamAttr(ArgNo, Attribute::SExt);
+ ++NumSExtArg;
+ return true;
+}
+
+static bool setRetNoUndef(Function &F) {
+ if (!F.getReturnType()->isVoidTy() &&
+ !F.hasAttribute(AttributeList::ReturnIndex, Attribute::NoUndef)) {
+ F.addAttribute(AttributeList::ReturnIndex, Attribute::NoUndef);
+ ++NumNoUndef;
+ return true;
+ }
+ return false;
+}
+
+static bool setArgsNoUndef(Function &F) {
+ bool Changed = false;
+ for (unsigned ArgNo = 0; ArgNo < F.arg_size(); ++ArgNo) {
+ if (!F.hasParamAttribute(ArgNo, Attribute::NoUndef)) {
+ F.addParamAttr(ArgNo, Attribute::NoUndef);
+ ++NumNoUndef;
+ Changed = true;
+ }
+ }
+ return Changed;
+}
+
+static bool setRetAndArgsNoUndef(Function &F) {
+ return setRetNoUndef(F) | setArgsNoUndef(F);
+}
+
static bool setReturnedArg(Function &F, unsigned ArgNo) {
if (F.hasParamAttribute(ArgNo, Attribute::Returned))
return false;
@@ -192,14 +192,14 @@ static bool setDoesNotFreeMemory(Function &F) {
return true;
}
-static bool setWillReturn(Function &F) {
- if (F.hasFnAttribute(Attribute::WillReturn))
- return false;
- F.addFnAttr(Attribute::WillReturn);
- ++NumWillReturn;
- return true;
-}
-
+static bool setWillReturn(Function &F) {
+ if (F.hasFnAttribute(Attribute::WillReturn))
+ return false;
+ F.addFnAttr(Attribute::WillReturn);
+ ++NumWillReturn;
+ return true;
+}
+
bool llvm::inferLibFuncAttributes(Module *M, StringRef Name,
const TargetLibraryInfo &TLI) {
Function *F = M->getFunction(Name);
@@ -227,15 +227,15 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
Changed |= setOnlyReadsMemory(F);
Changed |= setDoesNotThrow(F);
Changed |= setOnlyAccessesArgMemory(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
return Changed;
case LibFunc_strchr:
case LibFunc_strrchr:
- Changed |= setOnlyAccessesArgMemory(F);
+ Changed |= setOnlyAccessesArgMemory(F);
Changed |= setOnlyReadsMemory(F);
Changed |= setDoesNotThrow(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
return Changed;
case LibFunc_strtol:
case LibFunc_strtod:
@@ -245,7 +245,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
case LibFunc_strtold:
case LibFunc_strtoull:
Changed |= setDoesNotThrow(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
@@ -253,23 +253,23 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
case LibFunc_strncpy:
case LibFunc_strcat:
case LibFunc_strncat:
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
Changed |= setReturnedArg(F, 0);
LLVM_FALLTHROUGH;
case LibFunc_stpcpy:
case LibFunc_stpncpy:
- Changed |= setOnlyAccessesArgMemory(F);
+ Changed |= setOnlyAccessesArgMemory(F);
Changed |= setDoesNotThrow(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 1);
- Changed |= setOnlyWritesMemory(F, 0);
+ Changed |= setOnlyWritesMemory(F, 0);
Changed |= setOnlyReadsMemory(F, 1);
- Changed |= setDoesNotAlias(F, 0);
- Changed |= setDoesNotAlias(F, 1);
+ Changed |= setDoesNotAlias(F, 0);
+ Changed |= setDoesNotAlias(F, 1);
return Changed;
case LibFunc_strxfrm:
Changed |= setDoesNotThrow(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 1);
@@ -278,70 +278,70 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
case LibFunc_strspn: // 0,1
case LibFunc_strncmp: // 0,1
case LibFunc_strcspn: // 0,1
- Changed |= setDoesNotThrow(F);
- Changed |= setOnlyAccessesArgMemory(F);
- Changed |= setWillReturn(F);
- Changed |= setOnlyReadsMemory(F);
- Changed |= setDoesNotCapture(F, 0);
- Changed |= setDoesNotCapture(F, 1);
- return Changed;
- case LibFunc_strcoll:
+ Changed |= setDoesNotThrow(F);
+ Changed |= setOnlyAccessesArgMemory(F);
+ Changed |= setWillReturn(F);
+ Changed |= setOnlyReadsMemory(F);
+ Changed |= setDoesNotCapture(F, 0);
+ Changed |= setDoesNotCapture(F, 1);
+ return Changed;
+ case LibFunc_strcoll:
case LibFunc_strcasecmp: // 0,1
case LibFunc_strncasecmp: //
- // Those functions may depend on the locale, which may be accessed through
- // global memory.
+ // Those functions may depend on the locale, which may be accessed through
+ // global memory.
Changed |= setOnlyReadsMemory(F);
Changed |= setDoesNotThrow(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
return Changed;
case LibFunc_strstr:
case LibFunc_strpbrk:
- Changed |= setOnlyAccessesArgMemory(F);
+ Changed |= setOnlyAccessesArgMemory(F);
Changed |= setOnlyReadsMemory(F);
Changed |= setDoesNotThrow(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 1);
return Changed;
case LibFunc_strtok:
case LibFunc_strtok_r:
Changed |= setDoesNotThrow(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
case LibFunc_scanf:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
case LibFunc_setbuf:
case LibFunc_setvbuf:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
return Changed;
case LibFunc_strdup:
case LibFunc_strndup:
- Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
+ Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
Changed |= setDoesNotThrow(F);
Changed |= setRetDoesNotAlias(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
case LibFunc_stat:
case LibFunc_statvfs:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
case LibFunc_sscanf:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
@@ -349,94 +349,94 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
case LibFunc_sprintf:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotAlias(F, 0);
- Changed |= setOnlyWritesMemory(F, 0);
+ Changed |= setOnlyWritesMemory(F, 0);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
case LibFunc_snprintf:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotAlias(F, 0);
- Changed |= setOnlyWritesMemory(F, 0);
+ Changed |= setOnlyWritesMemory(F, 0);
Changed |= setDoesNotCapture(F, 2);
Changed |= setOnlyReadsMemory(F, 2);
return Changed;
case LibFunc_setitimer:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 1);
Changed |= setDoesNotCapture(F, 2);
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
case LibFunc_system:
// May throw; "system" is a valid pthread cancellation point.
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
case LibFunc_malloc:
- case LibFunc_vec_malloc:
- Changed |= setOnlyAccessesInaccessibleMemory(F);
- Changed |= setRetNoUndef(F);
+ case LibFunc_vec_malloc:
+ Changed |= setOnlyAccessesInaccessibleMemory(F);
+ Changed |= setRetNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setRetDoesNotAlias(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
return Changed;
case LibFunc_memcmp:
- Changed |= setOnlyAccessesArgMemory(F);
+ Changed |= setOnlyAccessesArgMemory(F);
Changed |= setOnlyReadsMemory(F);
Changed |= setDoesNotThrow(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
return Changed;
case LibFunc_memchr:
case LibFunc_memrchr:
- Changed |= setDoesNotThrow(F);
- Changed |= setOnlyAccessesArgMemory(F);
+ Changed |= setDoesNotThrow(F);
+ Changed |= setOnlyAccessesArgMemory(F);
Changed |= setOnlyReadsMemory(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
return Changed;
case LibFunc_modf:
case LibFunc_modff:
case LibFunc_modfl:
Changed |= setDoesNotThrow(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 1);
return Changed;
case LibFunc_memcpy:
- Changed |= setDoesNotThrow(F);
- Changed |= setOnlyAccessesArgMemory(F);
- Changed |= setWillReturn(F);
+ Changed |= setDoesNotThrow(F);
+ Changed |= setOnlyAccessesArgMemory(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotAlias(F, 0);
- Changed |= setReturnedArg(F, 0);
- Changed |= setOnlyWritesMemory(F, 0);
+ Changed |= setReturnedArg(F, 0);
+ Changed |= setOnlyWritesMemory(F, 0);
Changed |= setDoesNotAlias(F, 1);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
case LibFunc_memmove:
- Changed |= setDoesNotThrow(F);
- Changed |= setOnlyAccessesArgMemory(F);
- Changed |= setWillReturn(F);
+ Changed |= setDoesNotThrow(F);
+ Changed |= setOnlyAccessesArgMemory(F);
+ Changed |= setWillReturn(F);
Changed |= setReturnedArg(F, 0);
- Changed |= setOnlyWritesMemory(F, 0);
+ Changed |= setOnlyWritesMemory(F, 0);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
case LibFunc_mempcpy:
case LibFunc_memccpy:
- Changed |= setDoesNotThrow(F);
- Changed |= setOnlyAccessesArgMemory(F);
- Changed |= setWillReturn(F);
+ Changed |= setDoesNotThrow(F);
+ Changed |= setOnlyAccessesArgMemory(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotAlias(F, 0);
- Changed |= setOnlyWritesMemory(F, 0);
+ Changed |= setOnlyWritesMemory(F, 0);
Changed |= setDoesNotAlias(F, 1);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 1);
@@ -445,57 +445,57 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
Changed |= setDoesNotThrow(F);
return Changed;
case LibFunc_memalign:
- Changed |= setOnlyAccessesInaccessibleMemory(F);
- Changed |= setRetNoUndef(F);
- Changed |= setDoesNotThrow(F);
+ Changed |= setOnlyAccessesInaccessibleMemory(F);
+ Changed |= setRetNoUndef(F);
+ Changed |= setDoesNotThrow(F);
Changed |= setRetDoesNotAlias(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
return Changed;
case LibFunc_mkdir:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
case LibFunc_mktime:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
return Changed;
case LibFunc_realloc:
- case LibFunc_vec_realloc:
- Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
- Changed |= setRetNoUndef(F);
+ case LibFunc_vec_realloc:
+ Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
+ Changed |= setRetNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setRetDoesNotAlias(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
return Changed;
- case LibFunc_reallocf:
- Changed |= setRetNoUndef(F);
- Changed |= setWillReturn(F);
- return Changed;
+ case LibFunc_reallocf:
+ Changed |= setRetNoUndef(F);
+ Changed |= setWillReturn(F);
+ return Changed;
case LibFunc_read:
// May throw; "read" is a valid pthread cancellation point.
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotCapture(F, 1);
return Changed;
case LibFunc_rewind:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
return Changed;
case LibFunc_rmdir:
case LibFunc_remove:
case LibFunc_realpath:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
case LibFunc_rename:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
@@ -503,7 +503,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
case LibFunc_readlink:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
@@ -511,52 +511,52 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
return Changed;
case LibFunc_write:
// May throw; "write" is a valid pthread cancellation point.
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
case LibFunc_aligned_alloc:
- Changed |= setOnlyAccessesInaccessibleMemory(F);
- Changed |= setRetNoUndef(F);
+ Changed |= setOnlyAccessesInaccessibleMemory(F);
+ Changed |= setRetNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setRetDoesNotAlias(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
return Changed;
case LibFunc_bcopy:
Changed |= setDoesNotThrow(F);
- Changed |= setOnlyAccessesArgMemory(F);
- Changed |= setWillReturn(F);
+ Changed |= setOnlyAccessesArgMemory(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
- Changed |= setOnlyReadsMemory(F, 0);
- Changed |= setOnlyWritesMemory(F, 1);
+ Changed |= setOnlyReadsMemory(F, 0);
+ Changed |= setOnlyWritesMemory(F, 1);
Changed |= setDoesNotCapture(F, 1);
return Changed;
case LibFunc_bcmp:
Changed |= setDoesNotThrow(F);
- Changed |= setOnlyAccessesArgMemory(F);
+ Changed |= setOnlyAccessesArgMemory(F);
Changed |= setOnlyReadsMemory(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
return Changed;
case LibFunc_bzero:
Changed |= setDoesNotThrow(F);
- Changed |= setOnlyAccessesArgMemory(F);
- Changed |= setWillReturn(F);
+ Changed |= setOnlyAccessesArgMemory(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
- Changed |= setOnlyWritesMemory(F, 0);
+ Changed |= setOnlyWritesMemory(F, 0);
return Changed;
case LibFunc_calloc:
- case LibFunc_vec_calloc:
- Changed |= setOnlyAccessesInaccessibleMemory(F);
- Changed |= setRetNoUndef(F);
+ case LibFunc_vec_calloc:
+ Changed |= setOnlyAccessesInaccessibleMemory(F);
+ Changed |= setRetNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setRetDoesNotAlias(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
return Changed;
case LibFunc_chmod:
case LibFunc_chown:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
@@ -564,7 +564,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
case LibFunc_ctermid:
case LibFunc_clearerr:
case LibFunc_closedir:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
return Changed;
@@ -574,17 +574,17 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
case LibFunc_atoll:
Changed |= setDoesNotThrow(F);
Changed |= setOnlyReadsMemory(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
return Changed;
case LibFunc_access:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
case LibFunc_fopen:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setRetDoesNotAlias(F);
Changed |= setDoesNotCapture(F, 0);
@@ -593,25 +593,25 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
case LibFunc_fdopen:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setRetDoesNotAlias(F);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
case LibFunc_feof:
- Changed |= setRetAndArgsNoUndef(F);
- Changed |= setDoesNotThrow(F);
- Changed |= setDoesNotCapture(F, 0);
- return Changed;
+ Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCapture(F, 0);
+ return Changed;
case LibFunc_free:
- case LibFunc_vec_free:
- Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
- Changed |= setArgsNoUndef(F);
- Changed |= setDoesNotThrow(F);
- Changed |= setWillReturn(F);
- Changed |= setDoesNotCapture(F, 0);
- return Changed;
+ case LibFunc_vec_free:
+ Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
+ Changed |= setArgsNoUndef(F);
+ Changed |= setDoesNotThrow(F);
+ Changed |= setWillReturn(F);
+ Changed |= setDoesNotCapture(F, 0);
+ return Changed;
case LibFunc_fseek:
case LibFunc_ftell:
case LibFunc_fgetc:
@@ -625,12 +625,12 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
case LibFunc_flockfile:
case LibFunc_funlockfile:
case LibFunc_ftrylockfile:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
return Changed;
case LibFunc_ferror:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F);
@@ -638,38 +638,38 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
case LibFunc_fputc:
case LibFunc_fputc_unlocked:
case LibFunc_fstat:
- Changed |= setRetAndArgsNoUndef(F);
- Changed |= setDoesNotThrow(F);
- Changed |= setDoesNotCapture(F, 1);
- return Changed;
+ Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCapture(F, 1);
+ return Changed;
case LibFunc_frexp:
case LibFunc_frexpf:
case LibFunc_frexpl:
- Changed |= setDoesNotThrow(F);
- Changed |= setWillReturn(F);
- Changed |= setDoesNotCapture(F, 1);
- return Changed;
+ Changed |= setDoesNotThrow(F);
+ Changed |= setWillReturn(F);
+ Changed |= setDoesNotCapture(F, 1);
+ return Changed;
case LibFunc_fstatvfs:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 1);
return Changed;
case LibFunc_fgets:
case LibFunc_fgets_unlocked:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 2);
return Changed;
case LibFunc_fread:
case LibFunc_fread_unlocked:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 3);
return Changed;
case LibFunc_fwrite:
case LibFunc_fwrite_unlocked:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 3);
@@ -677,7 +677,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
return Changed;
case LibFunc_fputs:
case LibFunc_fputs_unlocked:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
@@ -685,35 +685,35 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
return Changed;
case LibFunc_fscanf:
case LibFunc_fprintf:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
case LibFunc_fgetpos:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
return Changed;
case LibFunc_getc:
- Changed |= setRetAndArgsNoUndef(F);
- Changed |= setDoesNotThrow(F);
- Changed |= setDoesNotCapture(F, 0);
- return Changed;
+ Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCapture(F, 0);
+ return Changed;
case LibFunc_getlogin_r:
- Changed |= setRetAndArgsNoUndef(F);
- Changed |= setDoesNotThrow(F);
- Changed |= setDoesNotCapture(F, 0);
- return Changed;
+ Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCapture(F, 0);
+ return Changed;
case LibFunc_getc_unlocked:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
return Changed;
case LibFunc_getenv:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setOnlyReadsMemory(F);
Changed |= setDoesNotCapture(F, 0);
@@ -721,45 +721,45 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
case LibFunc_gets:
case LibFunc_getchar:
case LibFunc_getchar_unlocked:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
return Changed;
case LibFunc_getitimer:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 1);
return Changed;
case LibFunc_getpwnam:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
case LibFunc_ungetc:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 1);
return Changed;
case LibFunc_uname:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
return Changed;
case LibFunc_unlink:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
case LibFunc_unsetenv:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
case LibFunc_utime:
case LibFunc_utimes:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
@@ -768,36 +768,36 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
return Changed;
case LibFunc_putc:
case LibFunc_putc_unlocked:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 1);
return Changed;
case LibFunc_puts:
case LibFunc_printf:
case LibFunc_perror:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
case LibFunc_pread:
// May throw; "pread" is a valid pthread cancellation point.
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotCapture(F, 1);
return Changed;
case LibFunc_pwrite:
// May throw; "pwrite" is a valid pthread cancellation point.
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
case LibFunc_putchar:
case LibFunc_putchar_unlocked:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
return Changed;
case LibFunc_popen:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setRetDoesNotAlias(F);
Changed |= setDoesNotCapture(F, 0);
@@ -806,18 +806,18 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
case LibFunc_pclose:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
return Changed;
case LibFunc_vscanf:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
case LibFunc_vsscanf:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
@@ -825,35 +825,35 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
case LibFunc_vfscanf:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
case LibFunc_valloc:
- Changed |= setOnlyAccessesInaccessibleMemory(F);
- Changed |= setRetNoUndef(F);
+ Changed |= setOnlyAccessesInaccessibleMemory(F);
+ Changed |= setRetNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setRetDoesNotAlias(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
return Changed;
case LibFunc_vprintf:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
case LibFunc_vfprintf:
case LibFunc_vsprintf:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
case LibFunc_vsnprintf:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 2);
@@ -861,24 +861,24 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
return Changed;
case LibFunc_open:
// May throw; "open" is a valid pthread cancellation point.
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
case LibFunc_opendir:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setRetDoesNotAlias(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
case LibFunc_tmpfile:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setRetDoesNotAlias(F);
return Changed;
case LibFunc_times:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
return Changed;
@@ -890,29 +890,29 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
Changed |= setDoesNotAccessMemory(F);
return Changed;
case LibFunc_lstat:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
case LibFunc_lchown:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
case LibFunc_qsort:
// May throw; places call through function pointer.
- // Cannot give undef pointer/size
- Changed |= setRetAndArgsNoUndef(F);
+ // Cannot give undef pointer/size
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotCapture(F, 3);
return Changed;
case LibFunc_dunder_strdup:
case LibFunc_dunder_strndup:
Changed |= setDoesNotThrow(F);
Changed |= setRetDoesNotAlias(F);
- Changed |= setWillReturn(F);
+ Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
@@ -922,17 +922,17 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
case LibFunc_under_IO_getc:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
return Changed;
case LibFunc_under_IO_putc:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 1);
return Changed;
case LibFunc_dunder_isoc99_scanf:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
@@ -940,14 +940,14 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
case LibFunc_stat64:
case LibFunc_lstat64:
case LibFunc_statvfs64:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
case LibFunc_dunder_isoc99_sscanf:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
@@ -955,7 +955,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
case LibFunc_fopen64:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setRetDoesNotAlias(F);
Changed |= setDoesNotCapture(F, 0);
@@ -965,24 +965,24 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
return Changed;
case LibFunc_fseeko64:
case LibFunc_ftello64:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
return Changed;
case LibFunc_tmpfile64:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setRetDoesNotAlias(F);
return Changed;
case LibFunc_fstat64:
case LibFunc_fstatvfs64:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 1);
return Changed;
case LibFunc_open64:
// May throw; "open" is a valid pthread cancellation point.
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
return Changed;
@@ -990,7 +990,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
// Currently some platforms have the restrict keyword on the arguments to
// gettimeofday. To be conservative, do not add noalias to gettimeofday's
// arguments.
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
@@ -1001,155 +1001,155 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
case LibFunc_memset_pattern16:
Changed |= setOnlyAccessesArgMemory(F);
Changed |= setDoesNotCapture(F, 0);
- Changed |= setOnlyWritesMemory(F, 0);
+ Changed |= setOnlyWritesMemory(F, 0);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 1);
return Changed;
- case LibFunc_memset:
- Changed |= setOnlyAccessesArgMemory(F);
- Changed |= setWillReturn(F);
- Changed |= setDoesNotThrow(F);
- Changed |= setOnlyWritesMemory(F, 0);
- return Changed;
+ case LibFunc_memset:
+ Changed |= setOnlyAccessesArgMemory(F);
+ Changed |= setWillReturn(F);
+ Changed |= setDoesNotThrow(F);
+ Changed |= setOnlyWritesMemory(F, 0);
+ return Changed;
// int __nvvm_reflect(const char *)
case LibFunc_nvvm_reflect:
- Changed |= setRetAndArgsNoUndef(F);
+ Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotAccessMemory(F);
Changed |= setDoesNotThrow(F);
return Changed;
- case LibFunc_ldexp:
- case LibFunc_ldexpf:
- case LibFunc_ldexpl:
- Changed |= setSignExtendedArg(F, 1);
- Changed |= setWillReturn(F);
- return Changed;
- case LibFunc_abs:
- case LibFunc_acos:
- case LibFunc_acosf:
- case LibFunc_acosh:
- case LibFunc_acoshf:
- case LibFunc_acoshl:
- case LibFunc_acosl:
- case LibFunc_asin:
- case LibFunc_asinf:
- case LibFunc_asinh:
- case LibFunc_asinhf:
- case LibFunc_asinhl:
- case LibFunc_asinl:
- case LibFunc_atan:
- case LibFunc_atan2:
- case LibFunc_atan2f:
- case LibFunc_atan2l:
- case LibFunc_atanf:
- case LibFunc_atanh:
- case LibFunc_atanhf:
- case LibFunc_atanhl:
- case LibFunc_atanl:
- case LibFunc_cbrt:
- case LibFunc_cbrtf:
- case LibFunc_cbrtl:
- case LibFunc_ceil:
- case LibFunc_ceilf:
- case LibFunc_ceill:
- case LibFunc_copysign:
- case LibFunc_copysignf:
- case LibFunc_copysignl:
- case LibFunc_cos:
- case LibFunc_cosh:
- case LibFunc_coshf:
- case LibFunc_coshl:
- case LibFunc_cosf:
- case LibFunc_cosl:
- case LibFunc_cospi:
- case LibFunc_cospif:
- case LibFunc_exp:
- case LibFunc_expf:
- case LibFunc_expl:
- case LibFunc_exp2:
- case LibFunc_exp2f:
- case LibFunc_exp2l:
- case LibFunc_expm1:
- case LibFunc_expm1f:
- case LibFunc_expm1l:
- case LibFunc_fabs:
- case LibFunc_fabsf:
- case LibFunc_fabsl:
- case LibFunc_ffs:
- case LibFunc_ffsl:
- case LibFunc_ffsll:
- case LibFunc_floor:
- case LibFunc_floorf:
- case LibFunc_floorl:
- case LibFunc_fls:
- case LibFunc_flsl:
- case LibFunc_flsll:
- case LibFunc_fmax:
- case LibFunc_fmaxf:
- case LibFunc_fmaxl:
- case LibFunc_fmin:
- case LibFunc_fminf:
- case LibFunc_fminl:
- case LibFunc_fmod:
- case LibFunc_fmodf:
- case LibFunc_fmodl:
- case LibFunc_isascii:
- case LibFunc_isdigit:
- case LibFunc_labs:
- case LibFunc_llabs:
- case LibFunc_log:
- case LibFunc_log10:
- case LibFunc_log10f:
- case LibFunc_log10l:
- case LibFunc_log1p:
- case LibFunc_log1pf:
- case LibFunc_log1pl:
- case LibFunc_log2:
- case LibFunc_log2f:
- case LibFunc_log2l:
- case LibFunc_logb:
- case LibFunc_logbf:
- case LibFunc_logbl:
- case LibFunc_logf:
- case LibFunc_logl:
- case LibFunc_nearbyint:
- case LibFunc_nearbyintf:
- case LibFunc_nearbyintl:
- case LibFunc_pow:
- case LibFunc_powf:
- case LibFunc_powl:
- case LibFunc_rint:
- case LibFunc_rintf:
- case LibFunc_rintl:
- case LibFunc_round:
- case LibFunc_roundf:
- case LibFunc_roundl:
- case LibFunc_sin:
- case LibFunc_sincospif_stret:
- case LibFunc_sinf:
- case LibFunc_sinh:
- case LibFunc_sinhf:
- case LibFunc_sinhl:
- case LibFunc_sinl:
- case LibFunc_sinpi:
- case LibFunc_sinpif:
- case LibFunc_sqrt:
- case LibFunc_sqrtf:
- case LibFunc_sqrtl:
- case LibFunc_strnlen:
- case LibFunc_tan:
- case LibFunc_tanf:
- case LibFunc_tanh:
- case LibFunc_tanhf:
- case LibFunc_tanhl:
- case LibFunc_tanl:
- case LibFunc_toascii:
- case LibFunc_trunc:
- case LibFunc_truncf:
- case LibFunc_truncl:
- Changed |= setDoesNotThrow(F);
- Changed |= setDoesNotFreeMemory(F);
- Changed |= setWillReturn(F);
- return Changed;
+ case LibFunc_ldexp:
+ case LibFunc_ldexpf:
+ case LibFunc_ldexpl:
+ Changed |= setSignExtendedArg(F, 1);
+ Changed |= setWillReturn(F);
+ return Changed;
+ case LibFunc_abs:
+ case LibFunc_acos:
+ case LibFunc_acosf:
+ case LibFunc_acosh:
+ case LibFunc_acoshf:
+ case LibFunc_acoshl:
+ case LibFunc_acosl:
+ case LibFunc_asin:
+ case LibFunc_asinf:
+ case LibFunc_asinh:
+ case LibFunc_asinhf:
+ case LibFunc_asinhl:
+ case LibFunc_asinl:
+ case LibFunc_atan:
+ case LibFunc_atan2:
+ case LibFunc_atan2f:
+ case LibFunc_atan2l:
+ case LibFunc_atanf:
+ case LibFunc_atanh:
+ case LibFunc_atanhf:
+ case LibFunc_atanhl:
+ case LibFunc_atanl:
+ case LibFunc_cbrt:
+ case LibFunc_cbrtf:
+ case LibFunc_cbrtl:
+ case LibFunc_ceil:
+ case LibFunc_ceilf:
+ case LibFunc_ceill:
+ case LibFunc_copysign:
+ case LibFunc_copysignf:
+ case LibFunc_copysignl:
+ case LibFunc_cos:
+ case LibFunc_cosh:
+ case LibFunc_coshf:
+ case LibFunc_coshl:
+ case LibFunc_cosf:
+ case LibFunc_cosl:
+ case LibFunc_cospi:
+ case LibFunc_cospif:
+ case LibFunc_exp:
+ case LibFunc_expf:
+ case LibFunc_expl:
+ case LibFunc_exp2:
+ case LibFunc_exp2f:
+ case LibFunc_exp2l:
+ case LibFunc_expm1:
+ case LibFunc_expm1f:
+ case LibFunc_expm1l:
+ case LibFunc_fabs:
+ case LibFunc_fabsf:
+ case LibFunc_fabsl:
+ case LibFunc_ffs:
+ case LibFunc_ffsl:
+ case LibFunc_ffsll:
+ case LibFunc_floor:
+ case LibFunc_floorf:
+ case LibFunc_floorl:
+ case LibFunc_fls:
+ case LibFunc_flsl:
+ case LibFunc_flsll:
+ case LibFunc_fmax:
+ case LibFunc_fmaxf:
+ case LibFunc_fmaxl:
+ case LibFunc_fmin:
+ case LibFunc_fminf:
+ case LibFunc_fminl:
+ case LibFunc_fmod:
+ case LibFunc_fmodf:
+ case LibFunc_fmodl:
+ case LibFunc_isascii:
+ case LibFunc_isdigit:
+ case LibFunc_labs:
+ case LibFunc_llabs:
+ case LibFunc_log:
+ case LibFunc_log10:
+ case LibFunc_log10f:
+ case LibFunc_log10l:
+ case LibFunc_log1p:
+ case LibFunc_log1pf:
+ case LibFunc_log1pl:
+ case LibFunc_log2:
+ case LibFunc_log2f:
+ case LibFunc_log2l:
+ case LibFunc_logb:
+ case LibFunc_logbf:
+ case LibFunc_logbl:
+ case LibFunc_logf:
+ case LibFunc_logl:
+ case LibFunc_nearbyint:
+ case LibFunc_nearbyintf:
+ case LibFunc_nearbyintl:
+ case LibFunc_pow:
+ case LibFunc_powf:
+ case LibFunc_powl:
+ case LibFunc_rint:
+ case LibFunc_rintf:
+ case LibFunc_rintl:
+ case LibFunc_round:
+ case LibFunc_roundf:
+ case LibFunc_roundl:
+ case LibFunc_sin:
+ case LibFunc_sincospif_stret:
+ case LibFunc_sinf:
+ case LibFunc_sinh:
+ case LibFunc_sinhf:
+ case LibFunc_sinhl:
+ case LibFunc_sinl:
+ case LibFunc_sinpi:
+ case LibFunc_sinpif:
+ case LibFunc_sqrt:
+ case LibFunc_sqrtf:
+ case LibFunc_sqrtl:
+ case LibFunc_strnlen:
+ case LibFunc_tan:
+ case LibFunc_tanf:
+ case LibFunc_tanh:
+ case LibFunc_tanhf:
+ case LibFunc_tanhl:
+ case LibFunc_tanl:
+ case LibFunc_toascii:
+ case LibFunc_trunc:
+ case LibFunc_truncf:
+ case LibFunc_truncl:
+ Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotFreeMemory(F);
+ Changed |= setWillReturn(F);
+ return Changed;
default:
// FIXME: It'd be really nice to cover all the library functions we're
// aware of here.
@@ -1298,15 +1298,15 @@ Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
return CI;
}
-Value *llvm::emitMemPCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,
- const DataLayout &DL, const TargetLibraryInfo *TLI) {
- LLVMContext &Context = B.GetInsertBlock()->getContext();
- return emitLibCall(
- LibFunc_mempcpy, B.getInt8PtrTy(),
- {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)},
- {Dst, Src, Len}, B, TLI);
-}
-
+Value *llvm::emitMemPCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,
+ const DataLayout &DL, const TargetLibraryInfo *TLI) {
+ LLVMContext &Context = B.GetInsertBlock()->getContext();
+ return emitLibCall(
+ LibFunc_mempcpy, B.getInt8PtrTy(),
+ {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)},
+ {Dst, Src, Len}, B, TLI);
+}
+
Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B,
const DataLayout &DL, const TargetLibraryInfo *TLI) {
LLVMContext &Context = B.GetInsertBlock()->getContext();
@@ -1346,7 +1346,7 @@ Value *llvm::emitSNPrintf(Value *Dest, Value *Size, Value *Fmt,
ArrayRef<Value *> VariadicArgs, IRBuilderBase &B,
const TargetLibraryInfo *TLI) {
SmallVector<Value *, 8> Args{castToCStr(Dest, B), Size, castToCStr(Fmt, B)};
- llvm::append_range(Args, VariadicArgs);
+ llvm::append_range(Args, VariadicArgs);
return emitLibCall(LibFunc_snprintf, B.getInt32Ty(),
{B.getInt8PtrTy(), Size->getType(), B.getInt8PtrTy()},
Args, B, TLI, /*IsVaArgs=*/true);
@@ -1356,7 +1356,7 @@ Value *llvm::emitSPrintf(Value *Dest, Value *Fmt,
ArrayRef<Value *> VariadicArgs, IRBuilderBase &B,
const TargetLibraryInfo *TLI) {
SmallVector<Value *, 8> Args{castToCStr(Dest, B), castToCStr(Fmt, B)};
- llvm::append_range(Args, VariadicArgs);
+ llvm::append_range(Args, VariadicArgs);
return emitLibCall(LibFunc_sprintf, B.getInt32Ty(),
{B.getInt8PtrTy(), B.getInt8PtrTy()}, Args, B, TLI,
/*IsVaArgs=*/true);
@@ -1464,15 +1464,15 @@ Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
static Value *emitBinaryFloatFnCallHelper(Value *Op1, Value *Op2,
StringRef Name, IRBuilderBase &B,
- const AttributeList &Attrs,
- const TargetLibraryInfo *TLI = nullptr) {
+ const AttributeList &Attrs,
+ const TargetLibraryInfo *TLI = nullptr) {
assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
Module *M = B.GetInsertBlock()->getModule();
FunctionCallee Callee = M->getOrInsertFunction(Name, Op1->getType(),
Op1->getType(), Op2->getType());
- if (TLI != nullptr)
- inferLibFuncAttributes(M, Name, *TLI);
+ if (TLI != nullptr)
+ inferLibFuncAttributes(M, Name, *TLI);
CallInst *CI = B.CreateCall(Callee, { Op1, Op2 }, Name);
// The incoming attribute set may have come from a speculatable intrinsic, but
@@ -1508,7 +1508,7 @@ Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2,
StringRef Name = getFloatFnName(TLI, Op1->getType(),
DoubleFn, FloatFn, LongDoubleFn);
- return emitBinaryFloatFnCallHelper(Op1, Op2, Name, B, Attrs, TLI);
+ return emitBinaryFloatFnCallHelper(Op1, Op2, Name, B, Attrs, TLI);
}
Value *llvm::emitPutChar(Value *Char, IRBuilderBase &B,
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/CallGraphUpdater.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/CallGraphUpdater.cpp
index 7835063f46..b2763900e1 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/CallGraphUpdater.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/CallGraphUpdater.cpp
@@ -96,12 +96,12 @@ void CallGraphUpdater::reanalyzeFunction(Function &Fn) {
}
}
-void CallGraphUpdater::registerOutlinedFunction(Function &OriginalFn,
- Function &NewFn) {
+void CallGraphUpdater::registerOutlinedFunction(Function &OriginalFn,
+ Function &NewFn) {
if (CG)
CG->addToCallGraph(&NewFn);
else if (LCG)
- LCG->addSplitFunction(OriginalFn, NewFn);
+ LCG->addSplitFunction(OriginalFn, NewFn);
}
void CallGraphUpdater::removeFunction(Function &DeadFn) {
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/CallPromotionUtils.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/CallPromotionUtils.cpp
index 0a182983c7..bf08bf2747 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/CallPromotionUtils.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/CallPromotionUtils.cpp
@@ -112,7 +112,7 @@ static void createRetPHINode(Instruction *OrigInst, Instruction *NewInst,
Builder.SetInsertPoint(&MergeBlock->front());
PHINode *Phi = Builder.CreatePHI(OrigInst->getType(), 0);
- SmallVector<User *, 16> UsersToUpdate(OrigInst->users());
+ SmallVector<User *, 16> UsersToUpdate(OrigInst->users());
for (User *U : UsersToUpdate)
U->replaceUsesOfWith(OrigInst, Phi);
Phi->addIncoming(OrigInst, OrigInst->getParent());
@@ -163,7 +163,7 @@ static void createRetBitCast(CallBase &CB, Type *RetTy, CastInst **RetBitCast) {
// Save the users of the calling instruction. These uses will be changed to
// use the bitcast after we create it.
- SmallVector<User *, 16> UsersToUpdate(CB.users());
+ SmallVector<User *, 16> UsersToUpdate(CB.users());
// Determine an appropriate location to create the bitcast for the return
// value. The location depends on if we have a call or invoke instruction.
@@ -426,11 +426,11 @@ bool llvm::isLegalToPromote(const CallBase &CB, Function *Callee,
}
}
for (; I < NumArgs; I++) {
- // Vararg functions can have more arguments than parameters.
+ // Vararg functions can have more arguments than parameters.
assert(Callee->isVarArg());
if (CB.paramHasAttr(I, Attribute::StructRet)) {
- if (FailureReason)
- *FailureReason = "SRet arg to vararg function";
+ if (FailureReason)
+ *FailureReason = "SRet arg to vararg function";
return false;
}
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp
index 06dfd56a44..1f649fe6c7 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp
@@ -109,7 +109,7 @@ void CanonicalizeFreezeInLoopsImpl::InsertFreezeAndForgetFromSCEV(Use &U) {
auto *ValueToFr = U.get();
assert(L->contains(UserI->getParent()) &&
"Should not process an instruction that isn't inside the loop");
- if (isGuaranteedNotToBeUndefOrPoison(ValueToFr, nullptr, UserI, &DT))
+ if (isGuaranteedNotToBeUndefOrPoison(ValueToFr, nullptr, UserI, &DT))
return;
LLVM_DEBUG(dbgs() << "canonfr: inserting freeze:\n");
@@ -176,7 +176,7 @@ bool CanonicalizeFreezeInLoopsImpl::run() {
assert(StepI && "Step instruction should have been found");
// Drop flags from the step instruction.
- if (!isGuaranteedNotToBeUndefOrPoison(StepI, nullptr, StepI, &DT)) {
+ if (!isGuaranteedNotToBeUndefOrPoison(StepI, nullptr, StepI, &DT)) {
LLVM_DEBUG(dbgs() << "canonfr: drop flags: " << *StepI << "\n");
StepI->dropPoisonGeneratingFlags();
SE.forgetValue(StepI);
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/CloneFunction.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/CloneFunction.cpp
index cb36aa5521..6ab061510a 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/CloneFunction.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/CloneFunction.cpp
@@ -27,7 +27,7 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/MDBuilder.h"
+#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
@@ -37,8 +37,8 @@
#include <map>
using namespace llvm;
-#define DEBUG_TYPE "clone-function"
-
+#define DEBUG_TYPE "clone-function"
+
/// See comments in Cloning.h.
BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap,
const Twine &NameSuffix, Function *F,
@@ -140,10 +140,10 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
MD[SP].reset(SP);
}
- // Everything else beyond this point deals with function instructions,
- // so if we are dealing with a function declaration, we're done.
- if (OldFunc->isDeclaration())
- return;
+ // Everything else beyond this point deals with function instructions,
+ // so if we are dealing with a function declaration, we're done.
+ if (OldFunc->isDeclaration())
+ return;
// When we remap instructions, we want to avoid duplicating inlined
// DISubprograms, so record all subprograms we find as we duplicate
@@ -193,19 +193,19 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
for (DIType *Type : DIFinder.types())
VMap.MD()[Type].reset(Type);
- // Duplicate the metadata that is attached to the cloned function.
- // Subprograms/CUs/types that were already mapped to themselves won't be
- // duplicated.
- SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
- OldFunc->getAllMetadata(MDs);
- for (auto MD : MDs) {
- NewFunc->addMetadata(
- MD.first,
- *MapMetadata(MD.second, VMap,
- ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges,
- TypeMapper, Materializer));
- }
-
+ // Duplicate the metadata that is attached to the cloned function.
+ // Subprograms/CUs/types that were already mapped to themselves won't be
+ // duplicated.
+ SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
+ OldFunc->getAllMetadata(MDs);
+ for (auto MD : MDs) {
+ NewFunc->addMetadata(
+ MD.first,
+ *MapMetadata(MD.second, VMap,
+ ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges,
+ TypeMapper, Materializer));
+ }
+
// Loop over all of the instructions in the function, fixing up operand
// references as we go. This uses VMap to do all the hard work.
for (Function::iterator BB =
@@ -436,7 +436,7 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB,
CodeInfo->OperandBundleCallSites.push_back(NewInst);
// Recursively clone any reachable successor blocks.
- append_range(ToClone, successors(BB->getTerminator()));
+ append_range(ToClone, successors(BB->getTerminator()));
}
if (CodeInfo) {
@@ -676,7 +676,7 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
// Check if this block has become dead during inlining or other
// simplifications. Note that the first block will appear dead, as it has
// not yet been wired up properly.
- if (I != Begin && (pred_empty(&*I) || I->getSinglePredecessor() == &*I)) {
+ if (I != Begin && (pred_empty(&*I) || I->getSinglePredecessor() == &*I)) {
BasicBlock *DeadBB = &*I++;
DeleteDeadBlock(DeadBB);
continue;
@@ -884,116 +884,116 @@ BasicBlock *llvm::DuplicateInstructionsInSplitBetween(
return NewBB;
}
-
-void llvm::cloneNoAliasScopes(
- ArrayRef<MDNode *> NoAliasDeclScopes,
- DenseMap<MDNode *, MDNode *> &ClonedScopes,
- StringRef Ext, LLVMContext &Context) {
- MDBuilder MDB(Context);
-
- for (auto *ScopeList : NoAliasDeclScopes) {
- for (auto &MDOperand : ScopeList->operands()) {
- if (MDNode *MD = dyn_cast<MDNode>(MDOperand)) {
- AliasScopeNode SNANode(MD);
-
- std::string Name;
- auto ScopeName = SNANode.getName();
- if (!ScopeName.empty())
- Name = (Twine(ScopeName) + ":" + Ext).str();
- else
- Name = std::string(Ext);
-
- MDNode *NewScope = MDB.createAnonymousAliasScope(
- const_cast<MDNode *>(SNANode.getDomain()), Name);
- ClonedScopes.insert(std::make_pair(MD, NewScope));
- }
- }
- }
-}
-
-void llvm::adaptNoAliasScopes(
- Instruction *I, const DenseMap<MDNode *, MDNode *> &ClonedScopes,
- LLVMContext &Context) {
- auto CloneScopeList = [&](const MDNode *ScopeList) -> MDNode * {
- bool NeedsReplacement = false;
- SmallVector<Metadata *, 8> NewScopeList;
- for (auto &MDOp : ScopeList->operands()) {
- if (MDNode *MD = dyn_cast<MDNode>(MDOp)) {
- if (auto *NewMD = ClonedScopes.lookup(MD)) {
- NewScopeList.push_back(NewMD);
- NeedsReplacement = true;
- continue;
- }
- NewScopeList.push_back(MD);
- }
- }
- if (NeedsReplacement)
- return MDNode::get(Context, NewScopeList);
- return nullptr;
- };
-
- if (auto *Decl = dyn_cast<NoAliasScopeDeclInst>(I))
- if (auto *NewScopeList = CloneScopeList(Decl->getScopeList()))
- Decl->setScopeList(NewScopeList);
-
- auto replaceWhenNeeded = [&](unsigned MD_ID) {
- if (const MDNode *CSNoAlias = I->getMetadata(MD_ID))
- if (auto *NewScopeList = CloneScopeList(CSNoAlias))
- I->setMetadata(MD_ID, NewScopeList);
- };
- replaceWhenNeeded(LLVMContext::MD_noalias);
- replaceWhenNeeded(LLVMContext::MD_alias_scope);
-}
-
-void llvm::cloneAndAdaptNoAliasScopes(
- ArrayRef<MDNode *> NoAliasDeclScopes,
- ArrayRef<BasicBlock *> NewBlocks, LLVMContext &Context, StringRef Ext) {
- if (NoAliasDeclScopes.empty())
- return;
-
- DenseMap<MDNode *, MDNode *> ClonedScopes;
- LLVM_DEBUG(dbgs() << "cloneAndAdaptNoAliasScopes: cloning "
- << NoAliasDeclScopes.size() << " node(s)\n");
-
- cloneNoAliasScopes(NoAliasDeclScopes, ClonedScopes, Ext, Context);
- // Identify instructions using metadata that needs adaptation
- for (BasicBlock *NewBlock : NewBlocks)
- for (Instruction &I : *NewBlock)
- adaptNoAliasScopes(&I, ClonedScopes, Context);
-}
-
-void llvm::cloneAndAdaptNoAliasScopes(
- ArrayRef<MDNode *> NoAliasDeclScopes, Instruction *IStart,
- Instruction *IEnd, LLVMContext &Context, StringRef Ext) {
- if (NoAliasDeclScopes.empty())
- return;
-
- DenseMap<MDNode *, MDNode *> ClonedScopes;
- LLVM_DEBUG(dbgs() << "cloneAndAdaptNoAliasScopes: cloning "
- << NoAliasDeclScopes.size() << " node(s)\n");
-
- cloneNoAliasScopes(NoAliasDeclScopes, ClonedScopes, Ext, Context);
- // Identify instructions using metadata that needs adaptation
- assert(IStart->getParent() == IEnd->getParent() && "different basic block ?");
- auto ItStart = IStart->getIterator();
- auto ItEnd = IEnd->getIterator();
- ++ItEnd; // IEnd is included, increment ItEnd to get the end of the range
- for (auto &I : llvm::make_range(ItStart, ItEnd))
- adaptNoAliasScopes(&I, ClonedScopes, Context);
-}
-
-void llvm::identifyNoAliasScopesToClone(
- ArrayRef<BasicBlock *> BBs, SmallVectorImpl<MDNode *> &NoAliasDeclScopes) {
- for (BasicBlock *BB : BBs)
- for (Instruction &I : *BB)
- if (auto *Decl = dyn_cast<NoAliasScopeDeclInst>(&I))
- NoAliasDeclScopes.push_back(Decl->getScopeList());
-}
-
-void llvm::identifyNoAliasScopesToClone(
- BasicBlock::iterator Start, BasicBlock::iterator End,
- SmallVectorImpl<MDNode *> &NoAliasDeclScopes) {
- for (Instruction &I : make_range(Start, End))
- if (auto *Decl = dyn_cast<NoAliasScopeDeclInst>(&I))
- NoAliasDeclScopes.push_back(Decl->getScopeList());
-}
+
+void llvm::cloneNoAliasScopes(
+ ArrayRef<MDNode *> NoAliasDeclScopes,
+ DenseMap<MDNode *, MDNode *> &ClonedScopes,
+ StringRef Ext, LLVMContext &Context) {
+ MDBuilder MDB(Context);
+
+ for (auto *ScopeList : NoAliasDeclScopes) {
+ for (auto &MDOperand : ScopeList->operands()) {
+ if (MDNode *MD = dyn_cast<MDNode>(MDOperand)) {
+ AliasScopeNode SNANode(MD);
+
+ std::string Name;
+ auto ScopeName = SNANode.getName();
+ if (!ScopeName.empty())
+ Name = (Twine(ScopeName) + ":" + Ext).str();
+ else
+ Name = std::string(Ext);
+
+ MDNode *NewScope = MDB.createAnonymousAliasScope(
+ const_cast<MDNode *>(SNANode.getDomain()), Name);
+ ClonedScopes.insert(std::make_pair(MD, NewScope));
+ }
+ }
+ }
+}
+
+void llvm::adaptNoAliasScopes(
+ Instruction *I, const DenseMap<MDNode *, MDNode *> &ClonedScopes,
+ LLVMContext &Context) {
+ auto CloneScopeList = [&](const MDNode *ScopeList) -> MDNode * {
+ bool NeedsReplacement = false;
+ SmallVector<Metadata *, 8> NewScopeList;
+ for (auto &MDOp : ScopeList->operands()) {
+ if (MDNode *MD = dyn_cast<MDNode>(MDOp)) {
+ if (auto *NewMD = ClonedScopes.lookup(MD)) {
+ NewScopeList.push_back(NewMD);
+ NeedsReplacement = true;
+ continue;
+ }
+ NewScopeList.push_back(MD);
+ }
+ }
+ if (NeedsReplacement)
+ return MDNode::get(Context, NewScopeList);
+ return nullptr;
+ };
+
+ if (auto *Decl = dyn_cast<NoAliasScopeDeclInst>(I))
+ if (auto *NewScopeList = CloneScopeList(Decl->getScopeList()))
+ Decl->setScopeList(NewScopeList);
+
+ auto replaceWhenNeeded = [&](unsigned MD_ID) {
+ if (const MDNode *CSNoAlias = I->getMetadata(MD_ID))
+ if (auto *NewScopeList = CloneScopeList(CSNoAlias))
+ I->setMetadata(MD_ID, NewScopeList);
+ };
+ replaceWhenNeeded(LLVMContext::MD_noalias);
+ replaceWhenNeeded(LLVMContext::MD_alias_scope);
+}
+
+void llvm::cloneAndAdaptNoAliasScopes(
+ ArrayRef<MDNode *> NoAliasDeclScopes,
+ ArrayRef<BasicBlock *> NewBlocks, LLVMContext &Context, StringRef Ext) {
+ if (NoAliasDeclScopes.empty())
+ return;
+
+ DenseMap<MDNode *, MDNode *> ClonedScopes;
+ LLVM_DEBUG(dbgs() << "cloneAndAdaptNoAliasScopes: cloning "
+ << NoAliasDeclScopes.size() << " node(s)\n");
+
+ cloneNoAliasScopes(NoAliasDeclScopes, ClonedScopes, Ext, Context);
+ // Identify instructions using metadata that needs adaptation
+ for (BasicBlock *NewBlock : NewBlocks)
+ for (Instruction &I : *NewBlock)
+ adaptNoAliasScopes(&I, ClonedScopes, Context);
+}
+
+void llvm::cloneAndAdaptNoAliasScopes(
+ ArrayRef<MDNode *> NoAliasDeclScopes, Instruction *IStart,
+ Instruction *IEnd, LLVMContext &Context, StringRef Ext) {
+ if (NoAliasDeclScopes.empty())
+ return;
+
+ DenseMap<MDNode *, MDNode *> ClonedScopes;
+ LLVM_DEBUG(dbgs() << "cloneAndAdaptNoAliasScopes: cloning "
+ << NoAliasDeclScopes.size() << " node(s)\n");
+
+ cloneNoAliasScopes(NoAliasDeclScopes, ClonedScopes, Ext, Context);
+ // Identify instructions using metadata that needs adaptation
+ assert(IStart->getParent() == IEnd->getParent() && "different basic block ?");
+ auto ItStart = IStart->getIterator();
+ auto ItEnd = IEnd->getIterator();
+ ++ItEnd; // IEnd is included, increment ItEnd to get the end of the range
+ for (auto &I : llvm::make_range(ItStart, ItEnd))
+ adaptNoAliasScopes(&I, ClonedScopes, Context);
+}
+
+void llvm::identifyNoAliasScopesToClone(
+ ArrayRef<BasicBlock *> BBs, SmallVectorImpl<MDNode *> &NoAliasDeclScopes) {
+ for (BasicBlock *BB : BBs)
+ for (Instruction &I : *BB)
+ if (auto *Decl = dyn_cast<NoAliasScopeDeclInst>(&I))
+ NoAliasDeclScopes.push_back(Decl->getScopeList());
+}
+
+void llvm::identifyNoAliasScopesToClone(
+ BasicBlock::iterator Start, BasicBlock::iterator End,
+ SmallVectorImpl<MDNode *> &NoAliasDeclScopes) {
+ for (Instruction &I : make_range(Start, End))
+ if (auto *Decl = dyn_cast<NoAliasScopeDeclInst>(&I))
+ NoAliasDeclScopes.push_back(Decl->getScopeList());
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/CloneModule.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/CloneModule.cpp
index 43e6c4b542..a6327bbf21 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/CloneModule.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/CloneModule.cpp
@@ -117,14 +117,14 @@ std::unique_ptr<Module> llvm::CloneModule(
//
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) {
- GlobalVariable *GV = cast<GlobalVariable>(VMap[&*I]);
-
- SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
- I->getAllMetadata(MDs);
- for (auto MD : MDs)
- GV->addMetadata(MD.first,
- *MapMetadata(MD.second, VMap, RF_MoveDistinctMDs));
-
+ GlobalVariable *GV = cast<GlobalVariable>(VMap[&*I]);
+
+ SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
+ I->getAllMetadata(MDs);
+ for (auto MD : MDs)
+ GV->addMetadata(MD.first,
+ *MapMetadata(MD.second, VMap, RF_MoveDistinctMDs));
+
if (I->isDeclaration())
continue;
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/CodeExtractor.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/CodeExtractor.cpp
index 56dcc38ca5..390925a03b 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/CodeExtractor.cpp
@@ -535,46 +535,46 @@ void CodeExtractor::findAllocas(const CodeExtractorAnalysisCache &CEAC,
continue;
}
- // Find bitcasts in the outlined region that have lifetime marker users
- // outside that region. Replace the lifetime marker use with an
- // outside region bitcast to avoid unnecessary alloca/reload instructions
- // and extra lifetime markers.
- SmallVector<Instruction *, 2> LifetimeBitcastUsers;
- for (User *U : AI->users()) {
- if (!definedInRegion(Blocks, U))
- continue;
-
- if (U->stripInBoundsConstantOffsets() != AI)
- continue;
-
- Instruction *Bitcast = cast<Instruction>(U);
- for (User *BU : Bitcast->users()) {
- IntrinsicInst *IntrInst = dyn_cast<IntrinsicInst>(BU);
- if (!IntrInst)
- continue;
-
- if (!IntrInst->isLifetimeStartOrEnd())
- continue;
-
- if (definedInRegion(Blocks, IntrInst))
- continue;
-
- LLVM_DEBUG(dbgs() << "Replace use of extracted region bitcast"
- << *Bitcast << " in out-of-region lifetime marker "
- << *IntrInst << "\n");
- LifetimeBitcastUsers.push_back(IntrInst);
- }
- }
-
- for (Instruction *I : LifetimeBitcastUsers) {
- Module *M = AIFunc->getParent();
- LLVMContext &Ctx = M->getContext();
- auto *Int8PtrTy = Type::getInt8PtrTy(Ctx);
- CastInst *CastI =
- CastInst::CreatePointerCast(AI, Int8PtrTy, "lt.cast", I);
- I->replaceUsesOfWith(I->getOperand(1), CastI);
- }
-
+ // Find bitcasts in the outlined region that have lifetime marker users
+ // outside that region. Replace the lifetime marker use with an
+ // outside region bitcast to avoid unnecessary alloca/reload instructions
+ // and extra lifetime markers.
+ SmallVector<Instruction *, 2> LifetimeBitcastUsers;
+ for (User *U : AI->users()) {
+ if (!definedInRegion(Blocks, U))
+ continue;
+
+ if (U->stripInBoundsConstantOffsets() != AI)
+ continue;
+
+ Instruction *Bitcast = cast<Instruction>(U);
+ for (User *BU : Bitcast->users()) {
+ IntrinsicInst *IntrInst = dyn_cast<IntrinsicInst>(BU);
+ if (!IntrInst)
+ continue;
+
+ if (!IntrInst->isLifetimeStartOrEnd())
+ continue;
+
+ if (definedInRegion(Blocks, IntrInst))
+ continue;
+
+ LLVM_DEBUG(dbgs() << "Replace use of extracted region bitcast"
+ << *Bitcast << " in out-of-region lifetime marker "
+ << *IntrInst << "\n");
+ LifetimeBitcastUsers.push_back(IntrInst);
+ }
+ }
+
+ for (Instruction *I : LifetimeBitcastUsers) {
+ Module *M = AIFunc->getParent();
+ LLVMContext &Ctx = M->getContext();
+ auto *Int8PtrTy = Type::getInt8PtrTy(Ctx);
+ CastInst *CastI =
+ CastInst::CreatePointerCast(AI, Int8PtrTy, "lt.cast", I);
+ I->replaceUsesOfWith(I->getOperand(1), CastI);
+ }
+
// Follow any bitcasts.
SmallVector<Instruction *, 2> Bitcasts;
SmallVector<LifetimeMarkerInfo, 2> BitcastLifetimeInfo;
@@ -768,7 +768,7 @@ void CodeExtractor::severSplitPHINodesOfExits(
NewBB = BasicBlock::Create(ExitBB->getContext(),
ExitBB->getName() + ".split",
ExitBB->getParent(), ExitBB);
- SmallVector<BasicBlock *, 4> Preds(predecessors(ExitBB));
+ SmallVector<BasicBlock *, 4> Preds(predecessors(ExitBB));
for (BasicBlock *PredBB : Preds)
if (Blocks.count(PredBB))
PredBB->getTerminator()->replaceUsesOfWith(ExitBB, NewBB);
@@ -934,7 +934,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
case Attribute::WriteOnly:
case Attribute::ZExt:
case Attribute::ImmArg:
- case Attribute::ByRef:
+ case Attribute::ByRef:
case Attribute::EndAttrKinds:
case Attribute::EmptyKey:
case Attribute::TombstoneKey:
@@ -942,11 +942,11 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
// Those attributes should be safe to propagate to the extracted function.
case Attribute::AlwaysInline:
case Attribute::Cold:
- case Attribute::Hot:
+ case Attribute::Hot:
case Attribute::NoRecurse:
case Attribute::InlineHint:
case Attribute::MinSize:
- case Attribute::NoCallback:
+ case Attribute::NoCallback:
case Attribute::NoDuplicate:
case Attribute::NoFree:
case Attribute::NoImplicitFloat:
@@ -972,8 +972,8 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
case Attribute::StrictFP:
case Attribute::UWTable:
case Attribute::NoCfCheck:
- case Attribute::MustProgress:
- case Attribute::NoProfile:
+ case Attribute::MustProgress:
+ case Attribute::NoProfile:
break;
}
@@ -1478,7 +1478,7 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
// function arguments, as the parameters don't correspond to anything at the
// source level.
assert(OldSP->getUnit() && "Missing compile unit for subprogram");
- DIBuilder DIB(*OldFunc.getParent(), /*AllowUnresolved=*/false,
+ DIBuilder DIB(*OldFunc.getParent(), /*AllowUnresolved=*/false,
OldSP->getUnit());
auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagDefinition |
@@ -1549,7 +1549,7 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
// function.
for (Instruction &I : instructions(NewFunc)) {
if (const DebugLoc &DL = I.getDebugLoc())
- I.setDebugLoc(DILocation::get(Ctx, DL.getLine(), DL.getCol(), NewSP));
+ I.setDebugLoc(DILocation::get(Ctx, DL.getLine(), DL.getCol(), NewSP));
// Loop info metadata may contain line locations. Fix them up.
auto updateLoopInfoLoc = [&Ctx,
@@ -1560,7 +1560,7 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
updateLoopMetadataDebugLocations(I, updateLoopInfoLoc);
}
if (!TheCall.getDebugLoc())
- TheCall.setDebugLoc(DILocation::get(Ctx, 0, 0, OldSP));
+ TheCall.setDebugLoc(DILocation::get(Ctx, 0, 0, OldSP));
eraseDebugIntrinsicsWithNonLocalRefs(NewFunc);
}
@@ -1783,7 +1783,7 @@ bool CodeExtractor::verifyAssumptionCache(const Function &OldFunc,
const Function &NewFunc,
AssumptionCache *AC) {
for (auto AssumeVH : AC->assumptions()) {
- auto *I = dyn_cast_or_null<CallInst>(AssumeVH);
+ auto *I = dyn_cast_or_null<CallInst>(AssumeVH);
if (!I)
continue;
@@ -1795,12 +1795,12 @@ bool CodeExtractor::verifyAssumptionCache(const Function &OldFunc,
// that were previously in the old function, but that have now been moved
// to the new function.
for (auto AffectedValVH : AC->assumptionsFor(I->getOperand(0))) {
- auto *AffectedCI = dyn_cast_or_null<CallInst>(AffectedValVH);
+ auto *AffectedCI = dyn_cast_or_null<CallInst>(AffectedValVH);
if (!AffectedCI)
continue;
if (AffectedCI->getFunction() != &OldFunc)
return true;
- auto *AssumedInst = cast<Instruction>(AffectedCI->getOperand(0));
+ auto *AssumedInst = cast<Instruction>(AffectedCI->getOperand(0));
if (AssumedInst->getFunction() != &OldFunc)
return true;
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/CodeMoverUtils.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/CodeMoverUtils.cpp
index c341aadbd1..ce982c7403 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/CodeMoverUtils.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/CodeMoverUtils.cpp
@@ -355,32 +355,32 @@ bool llvm::isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint,
// Check if there exists instructions which may throw, may synchonize, or may
// never return, from I to InsertPoint.
if (!isSafeToSpeculativelyExecute(&I))
- if (llvm::any_of(InstsToCheck, [](Instruction *I) {
- if (I->mayThrow())
- return true;
-
- const CallBase *CB = dyn_cast<CallBase>(I);
- if (!CB)
- return false;
- if (!CB->hasFnAttr(Attribute::WillReturn))
- return true;
- if (!CB->hasFnAttr(Attribute::NoSync))
- return true;
-
- return false;
- })) {
+ if (llvm::any_of(InstsToCheck, [](Instruction *I) {
+ if (I->mayThrow())
+ return true;
+
+ const CallBase *CB = dyn_cast<CallBase>(I);
+ if (!CB)
+ return false;
+ if (!CB->hasFnAttr(Attribute::WillReturn))
+ return true;
+ if (!CB->hasFnAttr(Attribute::NoSync))
+ return true;
+
+ return false;
+ })) {
return reportInvalidCandidate(I, MayThrowException);
}
// Check if I has any output/flow/anti dependences with instructions from \p
// StartInst to \p EndInst.
- if (llvm::any_of(InstsToCheck, [&DI, &I](Instruction *CurInst) {
- auto DepResult = DI->depends(&I, CurInst, true);
- if (DepResult && (DepResult->isOutput() || DepResult->isFlow() ||
- DepResult->isAnti()))
- return true;
- return false;
- }))
+ if (llvm::any_of(InstsToCheck, [&DI, &I](Instruction *CurInst) {
+ auto DepResult = DI->depends(&I, CurInst, true);
+ if (DepResult && (DepResult->isOutput() || DepResult->isFlow() ||
+ DepResult->isAnti()))
+ return true;
+ return false;
+ }))
return reportInvalidCandidate(I, HasDependences);
return true;
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/Debugify.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/Debugify.cpp
index 816b849506..3e4d53c10d 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/Debugify.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/Debugify.cpp
@@ -20,7 +20,7 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/PassInstrumentation.h"
+#include "llvm/IR/PassInstrumentation.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
@@ -199,18 +199,18 @@ bool llvm::applyDebugifyMetadata(
return true;
}
-static bool applyDebugify(Function &F) {
- Module &M = *F.getParent();
- auto FuncIt = F.getIterator();
- return applyDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)),
- "FunctionDebugify: ", /*ApplyToMF=*/nullptr);
-}
-
-static bool applyDebugify(Module &M) {
- return applyDebugifyMetadata(M, M.functions(),
- "ModuleDebugify: ", /*ApplyToMF=*/nullptr);
-}
-
+static bool applyDebugify(Function &F) {
+ Module &M = *F.getParent();
+ auto FuncIt = F.getIterator();
+ return applyDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)),
+ "FunctionDebugify: ", /*ApplyToMF=*/nullptr);
+}
+
+static bool applyDebugify(Module &M) {
+ return applyDebugifyMetadata(M, M.functions(),
+ "ModuleDebugify: ", /*ApplyToMF=*/nullptr);
+}
+
bool llvm::stripDebugifyMetadata(Module &M) {
bool Changed = false;
@@ -239,7 +239,7 @@ bool llvm::stripDebugifyMetadata(Module &M) {
NamedMDNode *NMD = M.getModuleFlagsMetadata();
if (!NMD)
return Changed;
- SmallVector<MDNode *, 4> Flags(NMD->operands());
+ SmallVector<MDNode *, 4> Flags(NMD->operands());
NMD->clearOperands();
for (MDNode *Flag : Flags) {
MDString *Key = dyn_cast_or_null<MDString>(Flag->getOperand(1));
@@ -394,7 +394,7 @@ bool checkDebugifyMetadata(Module &M,
/// ModulePass for attaching synthetic debug info to everything, used with the
/// legacy module pass manager.
struct DebugifyModulePass : public ModulePass {
- bool runOnModule(Module &M) override { return applyDebugify(M); }
+ bool runOnModule(Module &M) override { return applyDebugify(M); }
DebugifyModulePass() : ModulePass(ID) {}
@@ -408,7 +408,7 @@ struct DebugifyModulePass : public ModulePass {
/// FunctionPass for attaching synthetic debug info to instructions within a
/// single function, used with the legacy module pass manager.
struct DebugifyFunctionPass : public FunctionPass {
- bool runOnFunction(Function &F) override { return applyDebugify(F); }
+ bool runOnFunction(Function &F) override { return applyDebugify(F); }
DebugifyFunctionPass() : FunctionPass(ID) {}
@@ -475,32 +475,32 @@ private:
} // end anonymous namespace
-void llvm::exportDebugifyStats(StringRef Path, const DebugifyStatsMap &Map) {
- std::error_code EC;
- raw_fd_ostream OS{Path, EC};
- if (EC) {
- errs() << "Could not open file: " << EC.message() << ", " << Path << '\n';
- return;
- }
-
- OS << "Pass Name" << ',' << "# of missing debug values" << ','
- << "# of missing locations" << ',' << "Missing/Expected value ratio" << ','
- << "Missing/Expected location ratio" << '\n';
- for (const auto &Entry : Map) {
- StringRef Pass = Entry.first;
- DebugifyStatistics Stats = Entry.second;
-
- OS << Pass << ',' << Stats.NumDbgValuesMissing << ','
- << Stats.NumDbgLocsMissing << ',' << Stats.getMissingValueRatio() << ','
- << Stats.getEmptyLocationRatio() << '\n';
- }
-}
-
-ModulePass *llvm::createDebugifyModulePass() {
- return new DebugifyModulePass();
-}
-
-FunctionPass *llvm::createDebugifyFunctionPass() {
+void llvm::exportDebugifyStats(StringRef Path, const DebugifyStatsMap &Map) {
+ std::error_code EC;
+ raw_fd_ostream OS{Path, EC};
+ if (EC) {
+ errs() << "Could not open file: " << EC.message() << ", " << Path << '\n';
+ return;
+ }
+
+ OS << "Pass Name" << ',' << "# of missing debug values" << ','
+ << "# of missing locations" << ',' << "Missing/Expected value ratio" << ','
+ << "Missing/Expected location ratio" << '\n';
+ for (const auto &Entry : Map) {
+ StringRef Pass = Entry.first;
+ DebugifyStatistics Stats = Entry.second;
+
+ OS << Pass << ',' << Stats.NumDbgValuesMissing << ','
+ << Stats.NumDbgLocsMissing << ',' << Stats.getMissingValueRatio() << ','
+ << Stats.getEmptyLocationRatio() << '\n';
+ }
+}
+
+ModulePass *llvm::createDebugifyModulePass() {
+ return new DebugifyModulePass();
+}
+
+FunctionPass *llvm::createDebugifyFunctionPass() {
return new DebugifyFunctionPass();
}
@@ -510,15 +510,15 @@ PreservedAnalyses NewPMDebugifyPass::run(Module &M, ModuleAnalysisManager &) {
return PreservedAnalyses::all();
}
-ModulePass *llvm::createCheckDebugifyModulePass(bool Strip,
- StringRef NameOfWrappedPass,
- DebugifyStatsMap *StatsMap) {
+ModulePass *llvm::createCheckDebugifyModulePass(bool Strip,
+ StringRef NameOfWrappedPass,
+ DebugifyStatsMap *StatsMap) {
return new CheckDebugifyModulePass(Strip, NameOfWrappedPass, StatsMap);
}
-FunctionPass *
-llvm::createCheckDebugifyFunctionPass(bool Strip, StringRef NameOfWrappedPass,
- DebugifyStatsMap *StatsMap) {
+FunctionPass *
+llvm::createCheckDebugifyFunctionPass(bool Strip, StringRef NameOfWrappedPass,
+ DebugifyStatsMap *StatsMap) {
return new CheckDebugifyFunctionPass(Strip, NameOfWrappedPass, StatsMap);
}
@@ -529,41 +529,41 @@ PreservedAnalyses NewPMCheckDebugifyPass::run(Module &M,
return PreservedAnalyses::all();
}
-static bool isIgnoredPass(StringRef PassID) {
- return isSpecialPass(PassID, {"PassManager", "PassAdaptor",
- "AnalysisManagerProxy", "PrintFunctionPass",
- "PrintModulePass", "BitcodeWriterPass",
- "ThinLTOBitcodeWriterPass", "VerifierPass"});
-}
-
-void DebugifyEachInstrumentation::registerCallbacks(
- PassInstrumentationCallbacks &PIC) {
- PIC.registerBeforeNonSkippedPassCallback([](StringRef P, Any IR) {
- if (isIgnoredPass(P))
- return;
- if (any_isa<const Function *>(IR))
- applyDebugify(*const_cast<Function *>(any_cast<const Function *>(IR)));
- else if (any_isa<const Module *>(IR))
- applyDebugify(*const_cast<Module *>(any_cast<const Module *>(IR)));
- });
- PIC.registerAfterPassCallback([this](StringRef P, Any IR,
- const PreservedAnalyses &PassPA) {
- if (isIgnoredPass(P))
- return;
- if (any_isa<const Function *>(IR)) {
- auto &F = *const_cast<Function *>(any_cast<const Function *>(IR));
- Module &M = *F.getParent();
- auto It = F.getIterator();
- checkDebugifyMetadata(M, make_range(It, std::next(It)), P,
- "CheckFunctionDebugify", /*Strip=*/true, &StatsMap);
- } else if (any_isa<const Module *>(IR)) {
- auto &M = *const_cast<Module *>(any_cast<const Module *>(IR));
- checkDebugifyMetadata(M, M.functions(), P, "CheckModuleDebugify",
- /*Strip=*/true, &StatsMap);
- }
- });
-}
-
+static bool isIgnoredPass(StringRef PassID) {
+ return isSpecialPass(PassID, {"PassManager", "PassAdaptor",
+ "AnalysisManagerProxy", "PrintFunctionPass",
+ "PrintModulePass", "BitcodeWriterPass",
+ "ThinLTOBitcodeWriterPass", "VerifierPass"});
+}
+
+void DebugifyEachInstrumentation::registerCallbacks(
+ PassInstrumentationCallbacks &PIC) {
+ PIC.registerBeforeNonSkippedPassCallback([](StringRef P, Any IR) {
+ if (isIgnoredPass(P))
+ return;
+ if (any_isa<const Function *>(IR))
+ applyDebugify(*const_cast<Function *>(any_cast<const Function *>(IR)));
+ else if (any_isa<const Module *>(IR))
+ applyDebugify(*const_cast<Module *>(any_cast<const Module *>(IR)));
+ });
+ PIC.registerAfterPassCallback([this](StringRef P, Any IR,
+ const PreservedAnalyses &PassPA) {
+ if (isIgnoredPass(P))
+ return;
+ if (any_isa<const Function *>(IR)) {
+ auto &F = *const_cast<Function *>(any_cast<const Function *>(IR));
+ Module &M = *F.getParent();
+ auto It = F.getIterator();
+ checkDebugifyMetadata(M, make_range(It, std::next(It)), P,
+ "CheckFunctionDebugify", /*Strip=*/true, &StatsMap);
+ } else if (any_isa<const Module *>(IR)) {
+ auto &M = *const_cast<Module *>(any_cast<const Module *>(IR));
+ checkDebugifyMetadata(M, M.functions(), P, "CheckModuleDebugify",
+ /*Strip=*/true, &StatsMap);
+ }
+ });
+}
+
char DebugifyModulePass::ID = 0;
static RegisterPass<DebugifyModulePass> DM("debugify",
"Attach debug info to everything");
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/EntryExitInstrumenter.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/EntryExitInstrumenter.cpp
index a68c090a9a..26f8e21952 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/EntryExitInstrumenter.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/EntryExitInstrumenter.cpp
@@ -83,7 +83,7 @@ static bool runOnFunction(Function &F, bool PostInlining) {
if (!EntryFunc.empty()) {
DebugLoc DL;
if (auto SP = F.getSubprogram())
- DL = DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
+ DL = DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
insertCall(F, EntryFunc, &*F.begin()->getFirstInsertionPt(), DL);
Changed = true;
@@ -97,14 +97,14 @@ static bool runOnFunction(Function &F, bool PostInlining) {
continue;
// If T is preceded by a musttail call, that's the real terminator.
- if (CallInst *CI = BB.getTerminatingMustTailCall())
- T = CI;
+ if (CallInst *CI = BB.getTerminatingMustTailCall())
+ T = CI;
DebugLoc DL;
if (DebugLoc TerminatorDL = T->getDebugLoc())
DL = TerminatorDL;
else if (auto SP = F.getSubprogram())
- DL = DILocation::get(SP->getContext(), 0, 0, SP);
+ DL = DILocation::get(SP->getContext(), 0, 0, SP);
insertCall(F, ExitFunc, T, DL);
Changed = true;
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/EscapeEnumerator.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/EscapeEnumerator.cpp
index 9646f29d8f..accedd5b4e 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/EscapeEnumerator.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/EscapeEnumerator.cpp
@@ -41,8 +41,8 @@ IRBuilder<> *EscapeEnumerator::Next() {
if (!isa<ReturnInst>(TI) && !isa<ResumeInst>(TI))
continue;
- if (CallInst *CI = CurBB->getTerminatingMustTailCall())
- TI = CI;
+ if (CallInst *CI = CurBB->getTerminatingMustTailCall())
+ TI = CI;
Builder.SetInsertPoint(TI);
return &Builder;
}
@@ -56,12 +56,12 @@ IRBuilder<> *EscapeEnumerator::Next() {
return nullptr;
// Find all 'call' instructions that may throw.
- // We cannot tranform calls with musttail tag.
+ // We cannot tranform calls with musttail tag.
SmallVector<Instruction *, 16> Calls;
for (BasicBlock &BB : F)
for (Instruction &II : BB)
if (CallInst *CI = dyn_cast<CallInst>(&II))
- if (!CI->doesNotThrow() && !CI->isMustTailCall())
+ if (!CI->doesNotThrow() && !CI->isMustTailCall())
Calls.push_back(CI);
if (Calls.empty())
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/Evaluator.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/Evaluator.cpp
index f21a60673a..732b00635e 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/Evaluator.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/Evaluator.cpp
@@ -183,11 +183,11 @@ evaluateBitcastFromPtr(Constant *Ptr, const DataLayout &DL,
std::function<Constant *(Constant *)> Func) {
Constant *Val;
while (!(Val = Func(Ptr))) {
- // If Ty is a non-opaque struct, we can convert the pointer to the struct
+ // If Ty is a non-opaque struct, we can convert the pointer to the struct
// into a pointer to its first member.
// FIXME: This could be extended to support arrays as well.
Type *Ty = cast<PointerType>(Ptr->getType())->getElementType();
- if (!isa<StructType>(Ty) || cast<StructType>(Ty)->isOpaque())
+ if (!isa<StructType>(Ty) || cast<StructType>(Ty)->isOpaque())
break;
IntegerType *IdxTy = IntegerType::get(Ty->getContext(), 32);
@@ -210,7 +210,7 @@ static Constant *getInitializer(Constant *C) {
Constant *Evaluator::ComputeLoadResult(Constant *P) {
// If this memory location has been recently stored, use the stored value: it
// is the most up-to-date.
- auto findMemLoc = [this](Constant *Ptr) { return MutatedMemory.lookup(Ptr); };
+ auto findMemLoc = [this](Constant *Ptr) { return MutatedMemory.lookup(Ptr); };
if (Constant *Val = findMemLoc(P))
return Val;
@@ -547,10 +547,10 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst,
LLVM_DEBUG(dbgs() << "Skipping sideeffect intrinsic.\n");
++CurInst;
continue;
- } else if (II->getIntrinsicID() == Intrinsic::pseudoprobe) {
- LLVM_DEBUG(dbgs() << "Skipping pseudoprobe intrinsic.\n");
- ++CurInst;
- continue;
+ } else if (II->getIntrinsicID() == Intrinsic::pseudoprobe) {
+ LLVM_DEBUG(dbgs() << "Skipping pseudoprobe intrinsic.\n");
+ ++CurInst;
+ continue;
}
LLVM_DEBUG(dbgs() << "Unknown intrinsic. Can not evaluate.\n");
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/FixIrreducible.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/FixIrreducible.cpp
index e9f1bf6b6b..44af95eef6 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/FixIrreducible.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/FixIrreducible.cpp
@@ -66,7 +66,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/Utils/FixIrreducible.h"
+#include "llvm/Transforms/Utils/FixIrreducible.h"
#include "llvm/ADT/SCCIterator.h"
#include "llvm/Analysis/LoopIterator.h"
#include "llvm/InitializePasses.h"
@@ -105,7 +105,7 @@ FunctionPass *llvm::createFixIrreduciblePass() { return new FixIrreducible(); }
INITIALIZE_PASS_BEGIN(FixIrreducible, "fix-irreducible",
"Convert irreducible control-flow into natural loops",
false /* Only looks at CFG */, false /* Analysis Pass */)
-INITIALIZE_PASS_DEPENDENCY(LowerSwitchLegacyPass)
+INITIALIZE_PASS_DEPENDENCY(LowerSwitchLegacyPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_END(FixIrreducible, "fix-irreducible",
@@ -305,7 +305,7 @@ static bool makeReducible(LoopInfo &LI, DominatorTree &DT, Graph &&G) {
return Changed;
}
-static bool FixIrreducibleImpl(Function &F, LoopInfo &LI, DominatorTree &DT) {
+static bool FixIrreducibleImpl(Function &F, LoopInfo &LI, DominatorTree &DT) {
LLVM_DEBUG(dbgs() << "===== Fix irreducible control-flow in function: "
<< F.getName() << "\n");
@@ -317,10 +317,10 @@ static bool FixIrreducibleImpl(Function &F, LoopInfo &LI, DominatorTree &DT) {
// Any SCCs reduced are now already in the list of top-level loops, so simply
// add them all to the worklist.
- append_range(WorkList, LI);
+ append_range(WorkList, LI);
while (!WorkList.empty()) {
- auto L = WorkList.pop_back_val();
+ auto L = WorkList.pop_back_val();
LLVM_DEBUG(dbgs() << "visiting loop with header "
<< L->getHeader()->getName() << "\n");
Changed |= makeReducible(LI, DT, *L);
@@ -331,21 +331,21 @@ static bool FixIrreducibleImpl(Function &F, LoopInfo &LI, DominatorTree &DT) {
return Changed;
}
-
-bool FixIrreducible::runOnFunction(Function &F) {
- auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- return FixIrreducibleImpl(F, LI, DT);
-}
-
-PreservedAnalyses FixIrreduciblePass::run(Function &F,
- FunctionAnalysisManager &AM) {
- auto &LI = AM.getResult<LoopAnalysis>(F);
- auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
- if (!FixIrreducibleImpl(F, LI, DT))
- return PreservedAnalyses::all();
- PreservedAnalyses PA;
- PA.preserve<LoopAnalysis>();
- PA.preserve<DominatorTreeAnalysis>();
- return PA;
-}
+
+bool FixIrreducible::runOnFunction(Function &F) {
+ auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
+ auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ return FixIrreducibleImpl(F, LI, DT);
+}
+
+PreservedAnalyses FixIrreduciblePass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ auto &LI = AM.getResult<LoopAnalysis>(F);
+ auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
+ if (!FixIrreducibleImpl(F, LI, DT))
+ return PreservedAnalyses::all();
+ PreservedAnalyses PA;
+ PA.preserve<LoopAnalysis>();
+ PA.preserve<DominatorTreeAnalysis>();
+ return PA;
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/FunctionComparator.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/FunctionComparator.cpp
index b4d11bd2f4..2696557a71 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/FunctionComparator.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/FunctionComparator.cpp
@@ -124,17 +124,17 @@ int FunctionComparator::cmpAttrs(const AttributeList L,
Type *TyL = LA.getValueAsType();
Type *TyR = RA.getValueAsType();
- if (TyL && TyR) {
- if (int Res = cmpTypes(TyL, TyR))
- return Res;
- continue;
- }
+ if (TyL && TyR) {
+ if (int Res = cmpTypes(TyL, TyR))
+ return Res;
+ continue;
+ }
// Two pointers, at least one null, so the comparison result is
// independent of the value of a real pointer.
- if (int Res = cmpNumbers((uint64_t)TyL, (uint64_t)TyR))
- return Res;
- continue;
+ if (int Res = cmpNumbers((uint64_t)TyL, (uint64_t)TyR))
+ return Res;
+ continue;
}
if (LA < RA)
return -1;
@@ -291,7 +291,7 @@ int FunctionComparator::cmpConstants(const Constant *L,
switch (L->getValueID()) {
case Value::UndefValueVal:
- case Value::PoisonValueVal:
+ case Value::PoisonValueVal:
case Value::ConstantTokenNoneVal:
return TypesRes;
case Value::ConstantIntVal: {
@@ -494,13 +494,13 @@ int FunctionComparator::cmpTypes(Type *TyL, Type *TyR) const {
case Type::ScalableVectorTyID: {
auto *STyL = cast<VectorType>(TyL);
auto *STyR = cast<VectorType>(TyR);
- if (STyL->getElementCount().isScalable() !=
- STyR->getElementCount().isScalable())
- return cmpNumbers(STyL->getElementCount().isScalable(),
- STyR->getElementCount().isScalable());
- if (STyL->getElementCount() != STyR->getElementCount())
- return cmpNumbers(STyL->getElementCount().getKnownMinValue(),
- STyR->getElementCount().getKnownMinValue());
+ if (STyL->getElementCount().isScalable() !=
+ STyR->getElementCount().isScalable())
+ return cmpNumbers(STyL->getElementCount().isScalable(),
+ STyR->getElementCount().isScalable());
+ if (STyL->getElementCount() != STyR->getElementCount())
+ return cmpNumbers(STyL->getElementCount().getKnownMinValue(),
+ STyR->getElementCount().getKnownMinValue());
return cmpTypes(STyL->getElementType(), STyR->getElementType());
}
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/GlobalStatus.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/GlobalStatus.cpp
index fbc0b4b45a..f782396be7 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/GlobalStatus.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/GlobalStatus.cpp
@@ -136,8 +136,8 @@ static bool analyzeGlobalAux(const Value *V, GlobalStatus &GS,
GS.StoredType = GlobalStatus::Stored;
}
}
- } else if (isa<BitCastInst>(I) || isa<GetElementPtrInst>(I) ||
- isa<AddrSpaceCastInst>(I)) {
+ } else if (isa<BitCastInst>(I) || isa<GetElementPtrInst>(I) ||
+ isa<AddrSpaceCastInst>(I)) {
// Skip over bitcasts and GEPs; we don't care about the type or offset
// of the pointer.
if (analyzeGlobalAux(I, GS, VisitedUsers))
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/GuardUtils.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/GuardUtils.cpp
index 2d18d45e43..4dbcbf80d3 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/GuardUtils.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/GuardUtils.cpp
@@ -30,7 +30,7 @@ static cl::opt<uint32_t> PredicatePassBranchWeight(
void llvm::makeGuardControlFlowExplicit(Function *DeoptIntrinsic,
CallInst *Guard, bool UseWC) {
OperandBundleDef DeoptOB(*Guard->getOperandBundle(LLVMContext::OB_deopt));
- SmallVector<Value *, 4> Args(drop_begin(Guard->args()));
+ SmallVector<Value *, 4> Args(drop_begin(Guard->args()));
auto *CheckBB = Guard->getParent();
auto *DeoptBlockTerm =
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/InjectTLIMappings.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/InjectTLIMappings.cpp
index dbaf00eb6d..a2b72e4e7f 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/InjectTLIMappings.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/InjectTLIMappings.cpp
@@ -16,7 +16,7 @@
#include "llvm/Analysis/DemandedBits.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/IntrinsicInst.h"
@@ -78,8 +78,8 @@ static void addMappingsFromTLI(const TargetLibraryInfo &TLI, CallInst &CI) {
if (CI.isNoBuiltin() || !CI.getCalledFunction())
return;
- StringRef ScalarName = CI.getCalledFunction()->getName();
-
+ StringRef ScalarName = CI.getCalledFunction()->getName();
+
// Nothing to be done if the TLI thinks the function is not
// vectorizable.
if (!TLI.isFunctionVectorizable(ScalarName))
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/InlineFunction.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/InlineFunction.cpp
index 9237e9a513..fb271a2118 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/InlineFunction.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/InlineFunction.cpp
@@ -79,12 +79,12 @@ EnableNoAliasConversion("enable-noalias-to-md-conversion", cl::init(true),
cl::Hidden,
cl::desc("Convert noalias attributes to metadata during inlining."));
-static cl::opt<bool>
- UseNoAliasIntrinsic("use-noalias-intrinsic-during-inlining", cl::Hidden,
- cl::ZeroOrMore, cl::init(true),
- cl::desc("Use the llvm.experimental.noalias.scope.decl "
- "intrinsic during inlining."));
-
+static cl::opt<bool>
+ UseNoAliasIntrinsic("use-noalias-intrinsic-during-inlining", cl::Hidden,
+ cl::ZeroOrMore, cl::init(true),
+ cl::desc("Use the llvm.experimental.noalias.scope.decl "
+ "intrinsic during inlining."));
+
// Disabled by default, because the added alignment assumptions may increase
// compile-time and block optimizations. This option is not suitable for use
// with frontends that emit comprehensive parameter alignment annotations.
@@ -777,150 +777,150 @@ static void HandleInlinedEHPad(InvokeInst *II, BasicBlock *FirstNewBlock,
UnwindDest->removePredecessor(InvokeBB);
}
-/// When inlining a call site that has !llvm.mem.parallel_loop_access,
-/// !llvm.access.group, !alias.scope or !noalias metadata, that metadata should
-/// be propagated to all memory-accessing cloned instructions.
-static void PropagateCallSiteMetadata(CallBase &CB, Function::iterator FStart,
- Function::iterator FEnd) {
- MDNode *MemParallelLoopAccess =
- CB.getMetadata(LLVMContext::MD_mem_parallel_loop_access);
- MDNode *AccessGroup = CB.getMetadata(LLVMContext::MD_access_group);
- MDNode *AliasScope = CB.getMetadata(LLVMContext::MD_alias_scope);
- MDNode *NoAlias = CB.getMetadata(LLVMContext::MD_noalias);
- if (!MemParallelLoopAccess && !AccessGroup && !AliasScope && !NoAlias)
+/// When inlining a call site that has !llvm.mem.parallel_loop_access,
+/// !llvm.access.group, !alias.scope or !noalias metadata, that metadata should
+/// be propagated to all memory-accessing cloned instructions.
+static void PropagateCallSiteMetadata(CallBase &CB, Function::iterator FStart,
+ Function::iterator FEnd) {
+ MDNode *MemParallelLoopAccess =
+ CB.getMetadata(LLVMContext::MD_mem_parallel_loop_access);
+ MDNode *AccessGroup = CB.getMetadata(LLVMContext::MD_access_group);
+ MDNode *AliasScope = CB.getMetadata(LLVMContext::MD_alias_scope);
+ MDNode *NoAlias = CB.getMetadata(LLVMContext::MD_noalias);
+ if (!MemParallelLoopAccess && !AccessGroup && !AliasScope && !NoAlias)
return;
- for (BasicBlock &BB : make_range(FStart, FEnd)) {
- for (Instruction &I : BB) {
- // This metadata is only relevant for instructions that access memory.
- if (!I.mayReadOrWriteMemory())
- continue;
-
- if (MemParallelLoopAccess) {
- // TODO: This probably should not overwrite MemParalleLoopAccess.
- MemParallelLoopAccess = MDNode::concatenate(
- I.getMetadata(LLVMContext::MD_mem_parallel_loop_access),
- MemParallelLoopAccess);
- I.setMetadata(LLVMContext::MD_mem_parallel_loop_access,
- MemParallelLoopAccess);
- }
-
- if (AccessGroup)
- I.setMetadata(LLVMContext::MD_access_group, uniteAccessGroups(
- I.getMetadata(LLVMContext::MD_access_group), AccessGroup));
-
- if (AliasScope)
- I.setMetadata(LLVMContext::MD_alias_scope, MDNode::concatenate(
- I.getMetadata(LLVMContext::MD_alias_scope), AliasScope));
-
- if (NoAlias)
- I.setMetadata(LLVMContext::MD_noalias, MDNode::concatenate(
- I.getMetadata(LLVMContext::MD_noalias), NoAlias));
- }
+ for (BasicBlock &BB : make_range(FStart, FEnd)) {
+ for (Instruction &I : BB) {
+ // This metadata is only relevant for instructions that access memory.
+ if (!I.mayReadOrWriteMemory())
+ continue;
+
+ if (MemParallelLoopAccess) {
+ // TODO: This probably should not overwrite MemParalleLoopAccess.
+ MemParallelLoopAccess = MDNode::concatenate(
+ I.getMetadata(LLVMContext::MD_mem_parallel_loop_access),
+ MemParallelLoopAccess);
+ I.setMetadata(LLVMContext::MD_mem_parallel_loop_access,
+ MemParallelLoopAccess);
+ }
+
+ if (AccessGroup)
+ I.setMetadata(LLVMContext::MD_access_group, uniteAccessGroups(
+ I.getMetadata(LLVMContext::MD_access_group), AccessGroup));
+
+ if (AliasScope)
+ I.setMetadata(LLVMContext::MD_alias_scope, MDNode::concatenate(
+ I.getMetadata(LLVMContext::MD_alias_scope), AliasScope));
+
+ if (NoAlias)
+ I.setMetadata(LLVMContext::MD_noalias, MDNode::concatenate(
+ I.getMetadata(LLVMContext::MD_noalias), NoAlias));
+ }
}
}
-/// Utility for cloning !noalias and !alias.scope metadata. When a code region
-/// using scoped alias metadata is inlined, the aliasing relationships may not
-/// hold between the two version. It is necessary to create a deep clone of the
-/// metadata, putting the two versions in separate scope domains.
-class ScopedAliasMetadataDeepCloner {
- using MetadataMap = DenseMap<const MDNode *, TrackingMDNodeRef>;
+/// Utility for cloning !noalias and !alias.scope metadata. When a code region
+/// using scoped alias metadata is inlined, the aliasing relationships may not
+/// hold between the two version. It is necessary to create a deep clone of the
+/// metadata, putting the two versions in separate scope domains.
+class ScopedAliasMetadataDeepCloner {
+ using MetadataMap = DenseMap<const MDNode *, TrackingMDNodeRef>;
SetVector<const MDNode *> MD;
- MetadataMap MDMap;
- void addRecursiveMetadataUses();
-
-public:
- ScopedAliasMetadataDeepCloner(const Function *F);
-
- /// Create a new clone of the scoped alias metadata, which will be used by
- /// subsequent remap() calls.
- void clone();
-
- /// Remap instructions in the given range from the original to the cloned
- /// metadata.
- void remap(Function::iterator FStart, Function::iterator FEnd);
-};
-
-ScopedAliasMetadataDeepCloner::ScopedAliasMetadataDeepCloner(
- const Function *F) {
- for (const BasicBlock &BB : *F) {
- for (const Instruction &I : BB) {
- if (const MDNode *M = I.getMetadata(LLVMContext::MD_alias_scope))
+ MetadataMap MDMap;
+ void addRecursiveMetadataUses();
+
+public:
+ ScopedAliasMetadataDeepCloner(const Function *F);
+
+ /// Create a new clone of the scoped alias metadata, which will be used by
+ /// subsequent remap() calls.
+ void clone();
+
+ /// Remap instructions in the given range from the original to the cloned
+ /// metadata.
+ void remap(Function::iterator FStart, Function::iterator FEnd);
+};
+
+ScopedAliasMetadataDeepCloner::ScopedAliasMetadataDeepCloner(
+ const Function *F) {
+ for (const BasicBlock &BB : *F) {
+ for (const Instruction &I : BB) {
+ if (const MDNode *M = I.getMetadata(LLVMContext::MD_alias_scope))
MD.insert(M);
- if (const MDNode *M = I.getMetadata(LLVMContext::MD_noalias))
+ if (const MDNode *M = I.getMetadata(LLVMContext::MD_noalias))
MD.insert(M);
-
- // We also need to clone the metadata in noalias intrinsics.
- if (const auto *Decl = dyn_cast<NoAliasScopeDeclInst>(&I))
- MD.insert(Decl->getScopeList());
+
+ // We also need to clone the metadata in noalias intrinsics.
+ if (const auto *Decl = dyn_cast<NoAliasScopeDeclInst>(&I))
+ MD.insert(Decl->getScopeList());
}
- }
- addRecursiveMetadataUses();
-}
+ }
+ addRecursiveMetadataUses();
+}
-void ScopedAliasMetadataDeepCloner::addRecursiveMetadataUses() {
+void ScopedAliasMetadataDeepCloner::addRecursiveMetadataUses() {
SmallVector<const Metadata *, 16> Queue(MD.begin(), MD.end());
while (!Queue.empty()) {
const MDNode *M = cast<MDNode>(Queue.pop_back_val());
- for (const Metadata *Op : M->operands())
- if (const MDNode *OpMD = dyn_cast<MDNode>(Op))
- if (MD.insert(OpMD))
- Queue.push_back(OpMD);
+ for (const Metadata *Op : M->operands())
+ if (const MDNode *OpMD = dyn_cast<MDNode>(Op))
+ if (MD.insert(OpMD))
+ Queue.push_back(OpMD);
}
-}
+}
+
+void ScopedAliasMetadataDeepCloner::clone() {
+ assert(MDMap.empty() && "clone() already called ?");
-void ScopedAliasMetadataDeepCloner::clone() {
- assert(MDMap.empty() && "clone() already called ?");
-
SmallVector<TempMDTuple, 16> DummyNodes;
for (const MDNode *I : MD) {
- DummyNodes.push_back(MDTuple::getTemporary(I->getContext(), None));
+ DummyNodes.push_back(MDTuple::getTemporary(I->getContext(), None));
MDMap[I].reset(DummyNodes.back().get());
}
// Create new metadata nodes to replace the dummy nodes, replacing old
// metadata references with either a dummy node or an already-created new
// node.
- SmallVector<Metadata *, 4> NewOps;
+ SmallVector<Metadata *, 4> NewOps;
for (const MDNode *I : MD) {
- for (const Metadata *Op : I->operands()) {
- if (const MDNode *M = dyn_cast<MDNode>(Op))
+ for (const Metadata *Op : I->operands()) {
+ if (const MDNode *M = dyn_cast<MDNode>(Op))
NewOps.push_back(MDMap[M]);
else
- NewOps.push_back(const_cast<Metadata *>(Op));
+ NewOps.push_back(const_cast<Metadata *>(Op));
}
- MDNode *NewM = MDNode::get(I->getContext(), NewOps);
+ MDNode *NewM = MDNode::get(I->getContext(), NewOps);
MDTuple *TempM = cast<MDTuple>(MDMap[I]);
assert(TempM->isTemporary() && "Expected temporary node");
TempM->replaceAllUsesWith(NewM);
- NewOps.clear();
+ NewOps.clear();
}
-}
-
-void ScopedAliasMetadataDeepCloner::remap(Function::iterator FStart,
- Function::iterator FEnd) {
- if (MDMap.empty())
- return; // Nothing to do.
-
- for (BasicBlock &BB : make_range(FStart, FEnd)) {
- for (Instruction &I : BB) {
- // TODO: The null checks for the MDMap.lookup() results should no longer
- // be necessary.
- if (MDNode *M = I.getMetadata(LLVMContext::MD_alias_scope))
- if (MDNode *MNew = MDMap.lookup(M))
- I.setMetadata(LLVMContext::MD_alias_scope, MNew);
-
- if (MDNode *M = I.getMetadata(LLVMContext::MD_noalias))
- if (MDNode *MNew = MDMap.lookup(M))
- I.setMetadata(LLVMContext::MD_noalias, MNew);
-
- if (auto *Decl = dyn_cast<NoAliasScopeDeclInst>(&I))
- if (MDNode *MNew = MDMap.lookup(Decl->getScopeList()))
- Decl->setScopeList(MNew);
- }
+}
+
+void ScopedAliasMetadataDeepCloner::remap(Function::iterator FStart,
+ Function::iterator FEnd) {
+ if (MDMap.empty())
+ return; // Nothing to do.
+
+ for (BasicBlock &BB : make_range(FStart, FEnd)) {
+ for (Instruction &I : BB) {
+ // TODO: The null checks for the MDMap.lookup() results should no longer
+ // be necessary.
+ if (MDNode *M = I.getMetadata(LLVMContext::MD_alias_scope))
+ if (MDNode *MNew = MDMap.lookup(M))
+ I.setMetadata(LLVMContext::MD_alias_scope, MNew);
+
+ if (MDNode *M = I.getMetadata(LLVMContext::MD_noalias))
+ if (MDNode *MNew = MDMap.lookup(M))
+ I.setMetadata(LLVMContext::MD_noalias, MNew);
+
+ if (auto *Decl = dyn_cast<NoAliasScopeDeclInst>(&I))
+ if (MDNode *MNew = MDMap.lookup(Decl->getScopeList()))
+ Decl->setScopeList(MNew);
+ }
}
}
@@ -977,17 +977,17 @@ static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap,
// property of the callee, but also all control dependencies in the caller.
MDNode *NewScope = MDB.createAnonymousAliasScope(NewDomain, Name);
NewScopes.insert(std::make_pair(A, NewScope));
-
- if (UseNoAliasIntrinsic) {
- // Introduce a llvm.experimental.noalias.scope.decl for the noalias
- // argument.
- MDNode *AScopeList = MDNode::get(CalledFunc->getContext(), NewScope);
- auto *NoAliasDecl =
- IRBuilder<>(&CB).CreateNoAliasScopeDeclaration(AScopeList);
- // Ignore the result for now. The result will be used when the
- // llvm.noalias intrinsic is introduced.
- (void)NoAliasDecl;
- }
+
+ if (UseNoAliasIntrinsic) {
+ // Introduce a llvm.experimental.noalias.scope.decl for the noalias
+ // argument.
+ MDNode *AScopeList = MDNode::get(CalledFunc->getContext(), NewScope);
+ auto *NoAliasDecl =
+ IRBuilder<>(&CB).CreateNoAliasScopeDeclaration(AScopeList);
+ // Ignore the result for now. The result will be used when the
+ // llvm.noalias intrinsic is introduced.
+ (void)NoAliasDecl;
+ }
}
// Iterate over all new instructions in the map; for all memory-access
@@ -1058,7 +1058,7 @@ static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap,
SmallSetVector<const Argument *, 4> NAPtrArgs;
for (const Value *V : PtrArgs) {
SmallVector<const Value *, 4> Objects;
- getUnderlyingObjects(V, Objects, /* LI = */ nullptr);
+ getUnderlyingObjects(V, Objects, /* LI = */ nullptr);
for (const Value *O : Objects)
ObjSet.insert(O);
@@ -1266,7 +1266,7 @@ static void AddAlignmentAssumptions(CallBase &CB, InlineFunctionInfo &IFI) {
Function *CalledFunc = CB.getCalledFunction();
for (Argument &Arg : CalledFunc->args()) {
unsigned Align = Arg.getType()->isPointerTy() ? Arg.getParamAlignment() : 0;
- if (Align && !Arg.hasPassPointeeByValueCopyAttr() && !Arg.hasNUses(0)) {
+ if (Align && !Arg.hasPassPointeeByValueCopyAttr() && !Arg.hasNUses(0)) {
if (!DTCalculated) {
DT.recalculate(*CB.getCaller());
DTCalculated = true;
@@ -1469,8 +1469,8 @@ static DebugLoc inlineDebugLoc(DebugLoc OrigDL, DILocation *InlinedAt,
LLVMContext &Ctx,
DenseMap<const MDNode *, MDNode *> &IANodes) {
auto IA = DebugLoc::appendInlinedAt(OrigDL, InlinedAt, Ctx, IANodes);
- return DILocation::get(Ctx, OrigDL.getLine(), OrigDL.getCol(),
- OrigDL.getScope(), IA);
+ return DILocation::get(Ctx, OrigDL.getLine(), OrigDL.getCol(),
+ OrigDL.getScope(), IA);
}
/// Update inlined instructions' line numbers to
@@ -1594,7 +1594,7 @@ static void updateCallProfile(Function *Callee, const ValueToValueMapTy &VMap,
return;
auto CallSiteCount = PSI ? PSI->getProfileCount(TheCall, CallerBFI) : None;
int64_t CallCount =
- std::min(CallSiteCount.getValueOr(0), CalleeEntryCount.getCount());
+ std::min(CallSiteCount.getValueOr(0), CalleeEntryCount.getCount());
updateProfileCallee(Callee, -CallCount, &VMap);
}
@@ -1785,14 +1785,14 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
// Keep a list of pair (dst, src) to emit byval initializations.
SmallVector<std::pair<Value*, Value*>, 4> ByValInit;
- // When inlining a function that contains noalias scope metadata,
- // this metadata needs to be cloned so that the inlined blocks
- // have different "unique scopes" at every call site.
- // Track the metadata that must be cloned. Do this before other changes to
- // the function, so that we do not get in trouble when inlining caller ==
- // callee.
- ScopedAliasMetadataDeepCloner SAMetadataCloner(CB.getCalledFunction());
-
+ // When inlining a function that contains noalias scope metadata,
+ // this metadata needs to be cloned so that the inlined blocks
+ // have different "unique scopes" at every call site.
+ // Track the metadata that must be cloned. Do this before other changes to
+ // the function, so that we do not get in trouble when inlining caller ==
+ // callee.
+ ScopedAliasMetadataDeepCloner SAMetadataCloner(CB.getCalledFunction());
+
auto &DL = Caller->getParent()->getDataLayout();
// Calculate the vector of arguments to pass into the function cloner, which
@@ -1883,8 +1883,8 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
MergedDeoptArgs.reserve(ParentDeopt->Inputs.size() +
ChildOB.Inputs.size());
- llvm::append_range(MergedDeoptArgs, ParentDeopt->Inputs);
- llvm::append_range(MergedDeoptArgs, ChildOB.Inputs);
+ llvm::append_range(MergedDeoptArgs, ParentDeopt->Inputs);
+ llvm::append_range(MergedDeoptArgs, ChildOB.Inputs);
OpDefs.emplace_back("deopt", std::move(MergedDeoptArgs));
}
@@ -1910,9 +1910,9 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
fixupLineNumbers(Caller, FirstNewBlock, &CB,
CalledFunc->getSubprogram() != nullptr);
- // Now clone the inlined noalias scope metadata.
- SAMetadataCloner.clone();
- SAMetadataCloner.remap(FirstNewBlock, Caller->end());
+ // Now clone the inlined noalias scope metadata.
+ SAMetadataCloner.clone();
+ SAMetadataCloner.remap(FirstNewBlock, Caller->end());
// Add noalias metadata if necessary.
AddAliasScopeMetadata(CB, VMap, DL, CalleeAAR);
@@ -1921,8 +1921,8 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
// function which feed into its return value.
AddReturnAttributes(CB, VMap);
- // Propagate metadata on the callsite if necessary.
- PropagateCallSiteMetadata(CB, FirstNewBlock, Caller->end());
+ // Propagate metadata on the callsite if necessary.
+ PropagateCallSiteMetadata(CB, FirstNewBlock, Caller->end());
// Register any cloned assumptions.
if (IFI.GetAssumptionCache)
@@ -2087,7 +2087,7 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
dyn_cast<ConstantInt>(AI->getArraySize())) {
auto &DL = Caller->getParent()->getDataLayout();
Type *AllocaType = AI->getAllocatedType();
- TypeSize AllocaTypeSize = DL.getTypeAllocSize(AllocaType);
+ TypeSize AllocaTypeSize = DL.getTypeAllocSize(AllocaType);
uint64_t AllocaArraySize = AIArraySize->getLimitedValue();
// Don't add markers for zero-sized allocas.
@@ -2096,10 +2096,10 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
// Check that array size doesn't saturate uint64_t and doesn't
// overflow when it's multiplied by type size.
- if (!AllocaTypeSize.isScalable() &&
- AllocaArraySize != std::numeric_limits<uint64_t>::max() &&
+ if (!AllocaTypeSize.isScalable() &&
+ AllocaArraySize != std::numeric_limits<uint64_t>::max() &&
std::numeric_limits<uint64_t>::max() / AllocaArraySize >=
- AllocaTypeSize.getFixedSize()) {
+ AllocaTypeSize.getFixedSize()) {
AllocaSize = ConstantInt::get(Type::getInt64Ty(AI->getContext()),
AllocaArraySize * AllocaTypeSize);
}
@@ -2225,7 +2225,7 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
// match the callee's return type, we also need to change the return type of
// the intrinsic.
if (Caller->getReturnType() == CB.getType()) {
- llvm::erase_if(Returns, [](ReturnInst *RI) {
+ llvm::erase_if(Returns, [](ReturnInst *RI) {
return RI->getParent()->getTerminatingDeoptimizeCall() != nullptr;
});
} else {
@@ -2251,7 +2251,7 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
auto *CurBB = RI->getParent();
RI->eraseFromParent();
- SmallVector<Value *, 4> CallArgs(DeoptCall->args());
+ SmallVector<Value *, 4> CallArgs(DeoptCall->args());
SmallVector<OperandBundleDef, 1> OpBundles;
DeoptCall->getOperandBundlesAsDefs(OpBundles);
@@ -2488,7 +2488,7 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
// If we inlined any musttail calls and the original return is now
// unreachable, delete it. It can only contain a bitcast and ret.
- if (InlinedMustTailCalls && pred_empty(AfterCallBB))
+ if (InlinedMustTailCalls && pred_empty(AfterCallBB))
AfterCallBB->eraseFromParent();
// We should always be able to fold the entry block of the function into the
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/InstructionNamer.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/InstructionNamer.cpp
index b86b5c5b12..f3499c9c8a 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/InstructionNamer.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/InstructionNamer.cpp
@@ -13,52 +13,52 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/Utils/InstructionNamer.h"
+#include "llvm/Transforms/Utils/InstructionNamer.h"
#include "llvm/IR/Function.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/Type.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Utils.h"
-
+
using namespace llvm;
namespace {
-void nameInstructions(Function &F) {
- for (auto &Arg : F.args()) {
- if (!Arg.hasName())
- Arg.setName("arg");
- }
+void nameInstructions(Function &F) {
+ for (auto &Arg : F.args()) {
+ if (!Arg.hasName())
+ Arg.setName("arg");
+ }
+
+ for (BasicBlock &BB : F) {
+ if (!BB.hasName())
+ BB.setName("bb");
- for (BasicBlock &BB : F) {
- if (!BB.hasName())
- BB.setName("bb");
-
- for (Instruction &I : BB) {
- if (!I.hasName() && !I.getType()->isVoidTy())
- I.setName("i");
+ for (Instruction &I : BB) {
+ if (!I.hasName() && !I.getType()->isVoidTy())
+ I.setName("i");
}
- }
-}
+ }
+}
-struct InstNamer : public FunctionPass {
- static char ID; // Pass identification, replacement for typeid
- InstNamer() : FunctionPass(ID) {
- initializeInstNamerPass(*PassRegistry::getPassRegistry());
- }
+struct InstNamer : public FunctionPass {
+ static char ID; // Pass identification, replacement for typeid
+ InstNamer() : FunctionPass(ID) {
+ initializeInstNamerPass(*PassRegistry::getPassRegistry());
+ }
- void getAnalysisUsage(AnalysisUsage &Info) const override {
- Info.setPreservesAll();
- }
+ void getAnalysisUsage(AnalysisUsage &Info) const override {
+ Info.setPreservesAll();
+ }
- bool runOnFunction(Function &F) override {
- nameInstructions(F);
- return true;
- }
-};
+ bool runOnFunction(Function &F) override {
+ nameInstructions(F);
+ return true;
+ }
+};
char InstNamer::ID = 0;
- } // namespace
+ } // namespace
INITIALIZE_PASS(InstNamer, "instnamer",
"Assign names to anonymous instructions", false, false)
@@ -70,9 +70,9 @@ char &llvm::InstructionNamerID = InstNamer::ID;
FunctionPass *llvm::createInstructionNamerPass() {
return new InstNamer();
}
-
-PreservedAnalyses InstructionNamerPass::run(Function &F,
- FunctionAnalysisManager &FAM) {
- nameInstructions(F);
- return PreservedAnalyses::all();
-}
+
+PreservedAnalyses InstructionNamerPass::run(Function &F,
+ FunctionAnalysisManager &FAM) {
+ nameInstructions(F);
+ return PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/LCSSA.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/LCSSA.cpp
index aad469a909..7437701f53 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/LCSSA.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/LCSSA.cpp
@@ -40,7 +40,7 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
-#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PredIteratorCache.h"
@@ -78,15 +78,15 @@ static bool isExitBlock(BasicBlock *BB,
/// rewrite the uses.
bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
const DominatorTree &DT, const LoopInfo &LI,
- ScalarEvolution *SE, IRBuilderBase &Builder,
- SmallVectorImpl<PHINode *> *PHIsToRemove) {
+ ScalarEvolution *SE, IRBuilderBase &Builder,
+ SmallVectorImpl<PHINode *> *PHIsToRemove) {
SmallVector<Use *, 16> UsesToRewrite;
- SmallSetVector<PHINode *, 16> LocalPHIsToRemove;
+ SmallSetVector<PHINode *, 16> LocalPHIsToRemove;
PredIteratorCache PredCache;
bool Changed = false;
- IRBuilderBase::InsertPointGuard InsertPtGuard(Builder);
-
+ IRBuilderBase::InsertPointGuard InsertPtGuard(Builder);
+
// Cache the Loop ExitBlocks across this loop. We expect to get a lot of
// instructions within the same loops, computing the exit blocks is
// expensive, and we're not mutating the loop structure.
@@ -111,10 +111,10 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
for (Use &U : I->uses()) {
Instruction *User = cast<Instruction>(U.getUser());
BasicBlock *UserBB = User->getParent();
-
- // For practical purposes, we consider that the use in a PHI
- // occurs in the respective predecessor block. For more info,
- // see the `phi` doc in LangRef and the LCSSA doc.
+
+ // For practical purposes, we consider that the use in a PHI
+ // occurs in the respective predecessor block. For more info,
+ // see the `phi` doc in LangRef and the LCSSA doc.
if (auto *PN = dyn_cast<PHINode>(User))
UserBB = PN->getIncomingBlock(U);
@@ -159,17 +159,17 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
// If we already inserted something for this BB, don't reprocess it.
if (SSAUpdate.HasValueForBlock(ExitBB))
continue;
- Builder.SetInsertPoint(&ExitBB->front());
- PHINode *PN = Builder.CreatePHI(I->getType(), PredCache.size(ExitBB),
- I->getName() + ".lcssa");
+ Builder.SetInsertPoint(&ExitBB->front());
+ PHINode *PN = Builder.CreatePHI(I->getType(), PredCache.size(ExitBB),
+ I->getName() + ".lcssa");
// Get the debug location from the original instruction.
PN->setDebugLoc(I->getDebugLoc());
-
- // Add inputs from inside the loop for this PHI. This is valid
- // because `I` dominates `ExitBB` (checked above). This implies
- // that every incoming block/edge is dominated by `I` as well,
- // i.e. we can add uses of `I` to those incoming edges/append to the incoming
- // blocks without violating the SSA dominance property.
+
+ // Add inputs from inside the loop for this PHI. This is valid
+ // because `I` dominates `ExitBB` (checked above). This implies
+ // that every incoming block/edge is dominated by `I` as well,
+ // i.e. we can add uses of `I` to those incoming edges/append to the incoming
+ // blocks without violating the SSA dominance property.
for (BasicBlock *Pred : PredCache.get(ExitBB)) {
PN->addIncoming(I, Pred);
@@ -205,17 +205,17 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
for (Use *UseToRewrite : UsesToRewrite) {
Instruction *User = cast<Instruction>(UseToRewrite->getUser());
BasicBlock *UserBB = User->getParent();
-
- // For practical purposes, we consider that the use in a PHI
- // occurs in the respective predecessor block. For more info,
- // see the `phi` doc in LangRef and the LCSSA doc.
+
+ // For practical purposes, we consider that the use in a PHI
+ // occurs in the respective predecessor block. For more info,
+ // see the `phi` doc in LangRef and the LCSSA doc.
if (auto *PN = dyn_cast<PHINode>(User))
UserBB = PN->getIncomingBlock(*UseToRewrite);
- // If this use is in an exit block, rewrite to use the newly inserted PHI.
- // This is required for correctness because SSAUpdate doesn't handle uses
- // in the same block. It assumes the PHI we inserted is at the end of the
- // block.
+ // If this use is in an exit block, rewrite to use the newly inserted PHI.
+ // This is required for correctness because SSAUpdate doesn't handle uses
+ // in the same block. It assumes the PHI we inserted is at the end of the
+ // block.
if (isa<PHINode>(UserBB->begin()) && isExitBlock(UserBB, ExitBlocks)) {
UseToRewrite->set(&UserBB->front());
continue;
@@ -265,29 +265,29 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
Worklist.push_back(PostProcessPN);
// Keep track of PHI nodes that we want to remove because they did not have
- // any uses rewritten.
+ // any uses rewritten.
for (PHINode *PN : AddedPHIs)
if (PN->use_empty())
- LocalPHIsToRemove.insert(PN);
-
+ LocalPHIsToRemove.insert(PN);
+
Changed = true;
}
-
- // Remove PHI nodes that did not have any uses rewritten or add them to
- // PHIsToRemove, so the caller can remove them after some additional cleanup.
- // We need to redo the use_empty() check here, because even if the PHI node
- // wasn't used when added to LocalPHIsToRemove, later added PHI nodes can be
- // using it. This cleanup is not guaranteed to handle trees/cycles of PHI
- // nodes that only are used by each other. Such situations has only been
- // noticed when the input IR contains unreachable code, and leaving some extra
- // redundant PHI nodes in such situations is considered a minor problem.
- if (PHIsToRemove) {
- PHIsToRemove->append(LocalPHIsToRemove.begin(), LocalPHIsToRemove.end());
- } else {
- for (PHINode *PN : LocalPHIsToRemove)
- if (PN->use_empty())
- PN->eraseFromParent();
- }
+
+ // Remove PHI nodes that did not have any uses rewritten or add them to
+ // PHIsToRemove, so the caller can remove them after some additional cleanup.
+ // We need to redo the use_empty() check here, because even if the PHI node
+ // wasn't used when added to LocalPHIsToRemove, later added PHI nodes can be
+ // using it. This cleanup is not guaranteed to handle trees/cycles of PHI
+ // nodes that only are used by each other. Such situations has only been
+ // noticed when the input IR contains unreachable code, and leaving some extra
+ // redundant PHI nodes in such situations is considered a minor problem.
+ if (PHIsToRemove) {
+ PHIsToRemove->append(LocalPHIsToRemove.begin(), LocalPHIsToRemove.end());
+ } else {
+ for (PHINode *PN : LocalPHIsToRemove)
+ if (PN->use_empty())
+ PN->eraseFromParent();
+ }
return Changed;
}
@@ -297,7 +297,7 @@ static void computeBlocksDominatingExits(
SmallSetVector<BasicBlock *, 8> &BlocksDominatingExits) {
// We start from the exit blocks, as every block trivially dominates itself
// (not strictly).
- SmallVector<BasicBlock *, 8> BBWorklist(ExitBlocks);
+ SmallVector<BasicBlock *, 8> BBWorklist(ExitBlocks);
while (!BBWorklist.empty()) {
BasicBlock *BB = BBWorklist.pop_back_val();
@@ -386,9 +386,9 @@ bool llvm::formLCSSA(Loop &L, const DominatorTree &DT, const LoopInfo *LI,
}
}
- IRBuilder<> Builder(L.getHeader()->getContext());
- Changed = formLCSSAForInstructions(Worklist, DT, *LI, SE, Builder);
-
+ IRBuilder<> Builder(L.getHeader()->getContext());
+ Changed = formLCSSAForInstructions(Worklist, DT, *LI, SE, Builder);
+
// If we modified the code, remove any caches about the loop from SCEV to
// avoid dangling entries.
// FIXME: This is a big hammer, can we clear the cache more selectively?
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/Local.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/Local.cpp
index 5d8d638169..ae26058c21 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/Local.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/Local.cpp
@@ -91,25 +91,25 @@ using namespace llvm::PatternMatch;
#define DEBUG_TYPE "local"
STATISTIC(NumRemoved, "Number of unreachable basic blocks removed");
-STATISTIC(NumPHICSEs, "Number of PHI's that got CSE'd");
-
-static cl::opt<bool> PHICSEDebugHash(
- "phicse-debug-hash",
-#ifdef EXPENSIVE_CHECKS
- cl::init(true),
-#else
- cl::init(false),
-#endif
- cl::Hidden,
- cl::desc("Perform extra assertion checking to verify that PHINodes's hash "
- "function is well-behaved w.r.t. its isEqual predicate"));
-
-static cl::opt<unsigned> PHICSENumPHISmallSize(
- "phicse-num-phi-smallsize", cl::init(32), cl::Hidden,
- cl::desc(
- "When the basic block contains not more than this number of PHI nodes, "
- "perform a (faster!) exhaustive search instead of set-driven one."));
-
+STATISTIC(NumPHICSEs, "Number of PHI's that got CSE'd");
+
+static cl::opt<bool> PHICSEDebugHash(
+ "phicse-debug-hash",
+#ifdef EXPENSIVE_CHECKS
+ cl::init(true),
+#else
+ cl::init(false),
+#endif
+ cl::Hidden,
+ cl::desc("Perform extra assertion checking to verify that PHINodes's hash "
+ "function is well-behaved w.r.t. its isEqual predicate"));
+
+static cl::opt<unsigned> PHICSENumPHISmallSize(
+ "phicse-num-phi-smallsize", cl::init(32), cl::Hidden,
+ cl::desc(
+ "When the basic block contains not more than this number of PHI nodes, "
+ "perform a (faster!) exhaustive search instead of set-driven one."));
+
// Max recursion depth for collectBitParts used when detecting bswap and
// bitreverse idioms
static const unsigned BitPartRecursionMaxDepth = 64;
@@ -134,7 +134,7 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions,
// Branch - See if we are conditional jumping on constant
if (auto *BI = dyn_cast<BranchInst>(T)) {
if (BI->isUnconditional()) return false; // Can't optimize uncond branch
-
+
BasicBlock *Dest1 = BI->getSuccessor(0);
BasicBlock *Dest2 = BI->getSuccessor(1);
@@ -155,25 +155,25 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions,
RecursivelyDeleteTriviallyDeadInstructions(Cond, TLI);
return true;
}
-
- if (auto *Cond = dyn_cast<ConstantInt>(BI->getCondition())) {
- // Are we branching on constant?
- // YES. Change to unconditional branch...
- BasicBlock *Destination = Cond->getZExtValue() ? Dest1 : Dest2;
- BasicBlock *OldDest = Cond->getZExtValue() ? Dest2 : Dest1;
-
- // Let the basic block know that we are letting go of it. Based on this,
- // it will adjust it's PHI nodes.
- OldDest->removePredecessor(BB);
-
- // Replace the conditional branch with an unconditional one.
- Builder.CreateBr(Destination);
- BI->eraseFromParent();
- if (DTU)
- DTU->applyUpdates({{DominatorTree::Delete, BB, OldDest}});
- return true;
- }
-
+
+ if (auto *Cond = dyn_cast<ConstantInt>(BI->getCondition())) {
+ // Are we branching on constant?
+ // YES. Change to unconditional branch...
+ BasicBlock *Destination = Cond->getZExtValue() ? Dest1 : Dest2;
+ BasicBlock *OldDest = Cond->getZExtValue() ? Dest2 : Dest1;
+
+ // Let the basic block know that we are letting go of it. Based on this,
+ // it will adjust it's PHI nodes.
+ OldDest->removePredecessor(BB);
+
+ // Replace the conditional branch with an unconditional one.
+ Builder.CreateBr(Destination);
+ BI->eraseFromParent();
+ if (DTU)
+ DTU->applyUpdates({{DominatorTree::Delete, BB, OldDest}});
+ return true;
+ }
+
return false;
}
@@ -190,8 +190,8 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions,
TheOnlyDest = SI->case_begin()->getCaseSuccessor();
}
- bool Changed = false;
-
+ bool Changed = false;
+
// Figure out which case it goes to.
for (auto i = SI->case_begin(), e = SI->case_end(); i != e;) {
// Found case matching a constant operand?
@@ -230,7 +230,7 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions,
DefaultDest->removePredecessor(ParentBB);
i = SI->removeCase(i);
e = SI->case_end();
- Changed = true;
+ Changed = true;
continue;
}
@@ -257,16 +257,16 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions,
Builder.CreateBr(TheOnlyDest);
BasicBlock *BB = SI->getParent();
- SmallSetVector<BasicBlock *, 8> RemovedSuccessors;
-
+ SmallSetVector<BasicBlock *, 8> RemovedSuccessors;
+
// Remove entries from PHI nodes which we no longer branch to...
- BasicBlock *SuccToKeep = TheOnlyDest;
+ BasicBlock *SuccToKeep = TheOnlyDest;
for (BasicBlock *Succ : successors(SI)) {
- if (DTU && Succ != TheOnlyDest)
- RemovedSuccessors.insert(Succ);
+ if (DTU && Succ != TheOnlyDest)
+ RemovedSuccessors.insert(Succ);
// Found case matching a constant operand?
- if (Succ == SuccToKeep) {
- SuccToKeep = nullptr; // Don't modify the first branch to TheOnlyDest
+ if (Succ == SuccToKeep) {
+ SuccToKeep = nullptr; // Don't modify the first branch to TheOnlyDest
} else {
Succ->removePredecessor(BB);
}
@@ -277,13 +277,13 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions,
SI->eraseFromParent();
if (DeleteDeadConditions)
RecursivelyDeleteTriviallyDeadInstructions(Cond, TLI);
- if (DTU) {
- std::vector<DominatorTree::UpdateType> Updates;
- Updates.reserve(RemovedSuccessors.size());
- for (auto *RemovedSuccessor : RemovedSuccessors)
- Updates.push_back({DominatorTree::Delete, BB, RemovedSuccessor});
- DTU->applyUpdates(Updates);
- }
+ if (DTU) {
+ std::vector<DominatorTree::UpdateType> Updates;
+ Updates.reserve(RemovedSuccessors.size());
+ for (auto *RemovedSuccessor : RemovedSuccessors)
+ Updates.push_back({DominatorTree::Delete, BB, RemovedSuccessor});
+ DTU->applyUpdates(Updates);
+ }
return true;
}
@@ -321,7 +321,7 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions,
SI->eraseFromParent();
return true;
}
- return Changed;
+ return Changed;
}
if (auto *IBI = dyn_cast<IndirectBrInst>(T)) {
@@ -329,20 +329,20 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions,
if (auto *BA =
dyn_cast<BlockAddress>(IBI->getAddress()->stripPointerCasts())) {
BasicBlock *TheOnlyDest = BA->getBasicBlock();
- SmallSetVector<BasicBlock *, 8> RemovedSuccessors;
+ SmallSetVector<BasicBlock *, 8> RemovedSuccessors;
// Insert the new branch.
Builder.CreateBr(TheOnlyDest);
- BasicBlock *SuccToKeep = TheOnlyDest;
+ BasicBlock *SuccToKeep = TheOnlyDest;
for (unsigned i = 0, e = IBI->getNumDestinations(); i != e; ++i) {
- BasicBlock *DestBB = IBI->getDestination(i);
- if (DTU && DestBB != TheOnlyDest)
- RemovedSuccessors.insert(DestBB);
- if (IBI->getDestination(i) == SuccToKeep) {
- SuccToKeep = nullptr;
+ BasicBlock *DestBB = IBI->getDestination(i);
+ if (DTU && DestBB != TheOnlyDest)
+ RemovedSuccessors.insert(DestBB);
+ if (IBI->getDestination(i) == SuccToKeep) {
+ SuccToKeep = nullptr;
} else {
- DestBB->removePredecessor(BB);
+ DestBB->removePredecessor(BB);
}
}
Value *Address = IBI->getAddress();
@@ -359,18 +359,18 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions,
// If we didn't find our destination in the IBI successor list, then we
// have undefined behavior. Replace the unconditional branch with an
// 'unreachable' instruction.
- if (SuccToKeep) {
+ if (SuccToKeep) {
BB->getTerminator()->eraseFromParent();
new UnreachableInst(BB->getContext(), BB);
}
- if (DTU) {
- std::vector<DominatorTree::UpdateType> Updates;
- Updates.reserve(RemovedSuccessors.size());
- for (auto *RemovedSuccessor : RemovedSuccessors)
- Updates.push_back({DominatorTree::Delete, BB, RemovedSuccessor});
- DTU->applyUpdates(Updates);
- }
+ if (DTU) {
+ std::vector<DominatorTree::UpdateType> Updates;
+ Updates.reserve(RemovedSuccessors.size());
+ for (auto *RemovedSuccessor : RemovedSuccessors)
+ Updates.push_back({DominatorTree::Delete, BB, RemovedSuccessor});
+ DTU->applyUpdates(Updates);
+ }
return true;
}
}
@@ -420,9 +420,9 @@ bool llvm::wouldInstructionBeTriviallyDead(Instruction *I,
return true;
}
- if (!I->willReturn())
- return false;
-
+ if (!I->willReturn())
+ return false;
+
if (!I->mayHaveSideEffects())
return true;
@@ -484,24 +484,24 @@ bool llvm::wouldInstructionBeTriviallyDead(Instruction *I,
/// trivially dead, delete them too, recursively. Return true if any
/// instructions were deleted.
bool llvm::RecursivelyDeleteTriviallyDeadInstructions(
- Value *V, const TargetLibraryInfo *TLI, MemorySSAUpdater *MSSAU,
- std::function<void(Value *)> AboutToDeleteCallback) {
+ Value *V, const TargetLibraryInfo *TLI, MemorySSAUpdater *MSSAU,
+ std::function<void(Value *)> AboutToDeleteCallback) {
Instruction *I = dyn_cast<Instruction>(V);
if (!I || !isInstructionTriviallyDead(I, TLI))
return false;
SmallVector<WeakTrackingVH, 16> DeadInsts;
DeadInsts.push_back(I);
- RecursivelyDeleteTriviallyDeadInstructions(DeadInsts, TLI, MSSAU,
- AboutToDeleteCallback);
+ RecursivelyDeleteTriviallyDeadInstructions(DeadInsts, TLI, MSSAU,
+ AboutToDeleteCallback);
return true;
}
bool llvm::RecursivelyDeleteTriviallyDeadInstructionsPermissive(
SmallVectorImpl<WeakTrackingVH> &DeadInsts, const TargetLibraryInfo *TLI,
- MemorySSAUpdater *MSSAU,
- std::function<void(Value *)> AboutToDeleteCallback) {
+ MemorySSAUpdater *MSSAU,
+ std::function<void(Value *)> AboutToDeleteCallback) {
unsigned S = 0, E = DeadInsts.size(), Alive = 0;
for (; S != E; ++S) {
auto *I = cast<Instruction>(DeadInsts[S]);
@@ -512,15 +512,15 @@ bool llvm::RecursivelyDeleteTriviallyDeadInstructionsPermissive(
}
if (Alive == E)
return false;
- RecursivelyDeleteTriviallyDeadInstructions(DeadInsts, TLI, MSSAU,
- AboutToDeleteCallback);
+ RecursivelyDeleteTriviallyDeadInstructions(DeadInsts, TLI, MSSAU,
+ AboutToDeleteCallback);
return true;
}
void llvm::RecursivelyDeleteTriviallyDeadInstructions(
SmallVectorImpl<WeakTrackingVH> &DeadInsts, const TargetLibraryInfo *TLI,
- MemorySSAUpdater *MSSAU,
- std::function<void(Value *)> AboutToDeleteCallback) {
+ MemorySSAUpdater *MSSAU,
+ std::function<void(Value *)> AboutToDeleteCallback) {
// Process the dead instruction list until empty.
while (!DeadInsts.empty()) {
Value *V = DeadInsts.pop_back_val();
@@ -534,9 +534,9 @@ void llvm::RecursivelyDeleteTriviallyDeadInstructions(
// Don't lose the debug info while deleting the instructions.
salvageDebugInfo(*I);
- if (AboutToDeleteCallback)
- AboutToDeleteCallback(I);
-
+ if (AboutToDeleteCallback)
+ AboutToDeleteCallback(I);
+
// Null out all of the instruction's operands to see if any operand becomes
// dead as we go.
for (Use &OpU : I->operands()) {
@@ -740,11 +740,11 @@ void llvm::MergeBasicBlockIntoOnlyPred(BasicBlock *DestBB,
if (DTU) {
for (auto I = pred_begin(PredBB), E = pred_end(PredBB); I != E; ++I) {
// This predecessor of PredBB may already have DestBB as a successor.
- if (!llvm::is_contained(successors(*I), DestBB))
+ if (!llvm::is_contained(successors(*I), DestBB))
Updates.push_back({DominatorTree::Insert, *I, DestBB});
- Updates.push_back({DominatorTree::Delete, *I, PredBB});
+ Updates.push_back({DominatorTree::Delete, *I, PredBB});
}
- Updates.push_back({DominatorTree::Delete, PredBB, DestBB});
+ Updates.push_back({DominatorTree::Delete, PredBB, DestBB});
}
// Zap anything that took the address of DestBB. Not doing this will give the
@@ -918,7 +918,7 @@ static void gatherIncomingValuesToPhi(PHINode *PN,
/// \param IncomingValues A map from block to value.
static void replaceUndefValuesInPhi(PHINode *PN,
const IncomingValueMap &IncomingValues) {
- SmallVector<unsigned> TrueUndefOps;
+ SmallVector<unsigned> TrueUndefOps;
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
Value *V = PN->getIncomingValue(i);
@@ -927,30 +927,30 @@ static void replaceUndefValuesInPhi(PHINode *PN,
BasicBlock *BB = PN->getIncomingBlock(i);
IncomingValueMap::const_iterator It = IncomingValues.find(BB);
- // Keep track of undef/poison incoming values. Those must match, so we fix
- // them up below if needed.
- // Note: this is conservatively correct, but we could try harder and group
- // the undef values per incoming basic block.
- if (It == IncomingValues.end()) {
- TrueUndefOps.push_back(i);
- continue;
- }
-
- // There is a defined value for this incoming block, so map this undef
- // incoming value to the defined value.
+ // Keep track of undef/poison incoming values. Those must match, so we fix
+ // them up below if needed.
+ // Note: this is conservatively correct, but we could try harder and group
+ // the undef values per incoming basic block.
+ if (It == IncomingValues.end()) {
+ TrueUndefOps.push_back(i);
+ continue;
+ }
+
+ // There is a defined value for this incoming block, so map this undef
+ // incoming value to the defined value.
PN->setIncomingValue(i, It->second);
}
-
- // If there are both undef and poison values incoming, then convert those
- // values to undef. It is invalid to have different values for the same
- // incoming block.
- unsigned PoisonCount = count_if(TrueUndefOps, [&](unsigned i) {
- return isa<PoisonValue>(PN->getIncomingValue(i));
- });
- if (PoisonCount != 0 && PoisonCount != TrueUndefOps.size()) {
- for (unsigned i : TrueUndefOps)
- PN->setIncomingValue(i, UndefValue::get(PN->getType()));
- }
+
+ // If there are both undef and poison values incoming, then convert those
+ // values to undef. It is invalid to have different values for the same
+ // incoming block.
+ unsigned PoisonCount = count_if(TrueUndefOps, [&](unsigned i) {
+ return isa<PoisonValue>(PN->getIncomingValue(i));
+ });
+ if (PoisonCount != 0 && PoisonCount != TrueUndefOps.size()) {
+ for (unsigned i : TrueUndefOps)
+ PN->setIncomingValue(i, UndefValue::get(PN->getType()));
+ }
}
/// Replace a value flowing from a block to a phi with
@@ -1072,15 +1072,15 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
SmallVector<DominatorTree::UpdateType, 32> Updates;
if (DTU) {
// All predecessors of BB will be moved to Succ.
- SmallSetVector<BasicBlock *, 8> Predecessors(pred_begin(BB), pred_end(BB));
- Updates.reserve(Updates.size() + 2 * Predecessors.size());
- for (auto *Predecessor : Predecessors) {
+ SmallSetVector<BasicBlock *, 8> Predecessors(pred_begin(BB), pred_end(BB));
+ Updates.reserve(Updates.size() + 2 * Predecessors.size());
+ for (auto *Predecessor : Predecessors) {
// This predecessor of BB may already have Succ as a successor.
- if (!llvm::is_contained(successors(Predecessor), Succ))
- Updates.push_back({DominatorTree::Insert, Predecessor, Succ});
- Updates.push_back({DominatorTree::Delete, Predecessor, BB});
+ if (!llvm::is_contained(successors(Predecessor), Succ))
+ Updates.push_back({DominatorTree::Insert, Predecessor, Succ});
+ Updates.push_back({DominatorTree::Delete, Predecessor, BB});
}
- Updates.push_back({DominatorTree::Delete, BB, Succ});
+ Updates.push_back({DominatorTree::Delete, BB, Succ});
}
if (isa<PHINode>(Succ->begin())) {
@@ -1136,7 +1136,7 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
"applying corresponding DTU updates.");
if (DTU) {
- DTU->applyUpdates(Updates);
+ DTU->applyUpdates(Updates);
DTU->deleteBB(BB);
} else {
BB->eraseFromParent(); // Delete the old basic block.
@@ -1144,43 +1144,43 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
return true;
}
-static bool EliminateDuplicatePHINodesNaiveImpl(BasicBlock *BB) {
+static bool EliminateDuplicatePHINodesNaiveImpl(BasicBlock *BB) {
+ // This implementation doesn't currently consider undef operands
+ // specially. Theoretically, two phis which are identical except for
+ // one having an undef where the other doesn't could be collapsed.
+
+ bool Changed = false;
+
+ // Examine each PHI.
+ // Note that increment of I must *NOT* be in the iteration_expression, since
+ // we don't want to immediately advance when we restart from the beginning.
+ for (auto I = BB->begin(); PHINode *PN = dyn_cast<PHINode>(I);) {
+ ++I;
+ // Is there an identical PHI node in this basic block?
+ // Note that we only look in the upper square's triangle,
+ // we already checked that the lower triangle PHI's aren't identical.
+ for (auto J = I; PHINode *DuplicatePN = dyn_cast<PHINode>(J); ++J) {
+ if (!DuplicatePN->isIdenticalToWhenDefined(PN))
+ continue;
+ // A duplicate. Replace this PHI with the base PHI.
+ ++NumPHICSEs;
+ DuplicatePN->replaceAllUsesWith(PN);
+ DuplicatePN->eraseFromParent();
+ Changed = true;
+
+ // The RAUW can change PHIs that we already visited.
+ I = BB->begin();
+ break; // Start over from the beginning.
+ }
+ }
+ return Changed;
+}
+
+static bool EliminateDuplicatePHINodesSetBasedImpl(BasicBlock *BB) {
// This implementation doesn't currently consider undef operands
// specially. Theoretically, two phis which are identical except for
// one having an undef where the other doesn't could be collapsed.
- bool Changed = false;
-
- // Examine each PHI.
- // Note that increment of I must *NOT* be in the iteration_expression, since
- // we don't want to immediately advance when we restart from the beginning.
- for (auto I = BB->begin(); PHINode *PN = dyn_cast<PHINode>(I);) {
- ++I;
- // Is there an identical PHI node in this basic block?
- // Note that we only look in the upper square's triangle,
- // we already checked that the lower triangle PHI's aren't identical.
- for (auto J = I; PHINode *DuplicatePN = dyn_cast<PHINode>(J); ++J) {
- if (!DuplicatePN->isIdenticalToWhenDefined(PN))
- continue;
- // A duplicate. Replace this PHI with the base PHI.
- ++NumPHICSEs;
- DuplicatePN->replaceAllUsesWith(PN);
- DuplicatePN->eraseFromParent();
- Changed = true;
-
- // The RAUW can change PHIs that we already visited.
- I = BB->begin();
- break; // Start over from the beginning.
- }
- }
- return Changed;
-}
-
-static bool EliminateDuplicatePHINodesSetBasedImpl(BasicBlock *BB) {
- // This implementation doesn't currently consider undef operands
- // specially. Theoretically, two phis which are identical except for
- // one having an undef where the other doesn't could be collapsed.
-
struct PHIDenseMapInfo {
static PHINode *getEmptyKey() {
return DenseMapInfo<PHINode *>::getEmptyKey();
@@ -1190,13 +1190,13 @@ static bool EliminateDuplicatePHINodesSetBasedImpl(BasicBlock *BB) {
return DenseMapInfo<PHINode *>::getTombstoneKey();
}
- static bool isSentinel(PHINode *PN) {
- return PN == getEmptyKey() || PN == getTombstoneKey();
- }
-
- // WARNING: this logic must be kept in sync with
- // Instruction::isIdenticalToWhenDefined()!
- static unsigned getHashValueImpl(PHINode *PN) {
+ static bool isSentinel(PHINode *PN) {
+ return PN == getEmptyKey() || PN == getTombstoneKey();
+ }
+
+ // WARNING: this logic must be kept in sync with
+ // Instruction::isIdenticalToWhenDefined()!
+ static unsigned getHashValueImpl(PHINode *PN) {
// Compute a hash value on the operands. Instcombine will likely have
// sorted them, which helps expose duplicates, but we have to check all
// the operands to be safe in case instcombine hasn't run.
@@ -1205,37 +1205,37 @@ static bool EliminateDuplicatePHINodesSetBasedImpl(BasicBlock *BB) {
hash_combine_range(PN->block_begin(), PN->block_end())));
}
- static unsigned getHashValue(PHINode *PN) {
-#ifndef NDEBUG
- // If -phicse-debug-hash was specified, return a constant -- this
- // will force all hashing to collide, so we'll exhaustively search
- // the table for a match, and the assertion in isEqual will fire if
- // there's a bug causing equal keys to hash differently.
- if (PHICSEDebugHash)
- return 0;
-#endif
- return getHashValueImpl(PN);
- }
-
- static bool isEqualImpl(PHINode *LHS, PHINode *RHS) {
- if (isSentinel(LHS) || isSentinel(RHS))
+ static unsigned getHashValue(PHINode *PN) {
+#ifndef NDEBUG
+ // If -phicse-debug-hash was specified, return a constant -- this
+ // will force all hashing to collide, so we'll exhaustively search
+ // the table for a match, and the assertion in isEqual will fire if
+ // there's a bug causing equal keys to hash differently.
+ if (PHICSEDebugHash)
+ return 0;
+#endif
+ return getHashValueImpl(PN);
+ }
+
+ static bool isEqualImpl(PHINode *LHS, PHINode *RHS) {
+ if (isSentinel(LHS) || isSentinel(RHS))
return LHS == RHS;
return LHS->isIdenticalTo(RHS);
}
-
- static bool isEqual(PHINode *LHS, PHINode *RHS) {
- // These comparisons are nontrivial, so assert that equality implies
- // hash equality (DenseMap demands this as an invariant).
- bool Result = isEqualImpl(LHS, RHS);
- assert(!Result || (isSentinel(LHS) && LHS == RHS) ||
- getHashValueImpl(LHS) == getHashValueImpl(RHS));
- return Result;
- }
+
+ static bool isEqual(PHINode *LHS, PHINode *RHS) {
+ // These comparisons are nontrivial, so assert that equality implies
+ // hash equality (DenseMap demands this as an invariant).
+ bool Result = isEqualImpl(LHS, RHS);
+ assert(!Result || (isSentinel(LHS) && LHS == RHS) ||
+ getHashValueImpl(LHS) == getHashValueImpl(RHS));
+ return Result;
+ }
};
// Set of unique PHINodes.
DenseSet<PHINode *, PHIDenseMapInfo> PHISet;
- PHISet.reserve(4 * PHICSENumPHISmallSize);
+ PHISet.reserve(4 * PHICSENumPHISmallSize);
// Examine each PHI.
bool Changed = false;
@@ -1243,7 +1243,7 @@ static bool EliminateDuplicatePHINodesSetBasedImpl(BasicBlock *BB) {
auto Inserted = PHISet.insert(PN);
if (!Inserted.second) {
// A duplicate. Replace this PHI with its duplicate.
- ++NumPHICSEs;
+ ++NumPHICSEs;
PN->replaceAllUsesWith(*Inserted.first);
PN->eraseFromParent();
Changed = true;
@@ -1258,63 +1258,63 @@ static bool EliminateDuplicatePHINodesSetBasedImpl(BasicBlock *BB) {
return Changed;
}
-bool llvm::EliminateDuplicatePHINodes(BasicBlock *BB) {
- if (
-#ifndef NDEBUG
- !PHICSEDebugHash &&
-#endif
- hasNItemsOrLess(BB->phis(), PHICSENumPHISmallSize))
- return EliminateDuplicatePHINodesNaiveImpl(BB);
- return EliminateDuplicatePHINodesSetBasedImpl(BB);
-}
-
-/// If the specified pointer points to an object that we control, try to modify
-/// the object's alignment to PrefAlign. Returns a minimum known alignment of
-/// the value after the operation, which may be lower than PrefAlign.
-///
-/// Increating value alignment isn't often possible though. If alignment is
-/// important, a more reliable approach is to simply align all global variables
-/// and allocation instructions to their preferred alignment from the beginning.
-static Align tryEnforceAlignment(Value *V, Align PrefAlign,
- const DataLayout &DL) {
+bool llvm::EliminateDuplicatePHINodes(BasicBlock *BB) {
+ if (
+#ifndef NDEBUG
+ !PHICSEDebugHash &&
+#endif
+ hasNItemsOrLess(BB->phis(), PHICSENumPHISmallSize))
+ return EliminateDuplicatePHINodesNaiveImpl(BB);
+ return EliminateDuplicatePHINodesSetBasedImpl(BB);
+}
+
+/// If the specified pointer points to an object that we control, try to modify
+/// the object's alignment to PrefAlign. Returns a minimum known alignment of
+/// the value after the operation, which may be lower than PrefAlign.
+///
+/// Increating value alignment isn't often possible though. If alignment is
+/// important, a more reliable approach is to simply align all global variables
+/// and allocation instructions to their preferred alignment from the beginning.
+static Align tryEnforceAlignment(Value *V, Align PrefAlign,
+ const DataLayout &DL) {
V = V->stripPointerCasts();
if (AllocaInst *AI = dyn_cast<AllocaInst>(V)) {
- // TODO: Ideally, this function would not be called if PrefAlign is smaller
- // than the current alignment, as the known bits calculation should have
- // already taken it into account. However, this is not always the case,
- // as computeKnownBits() has a depth limit, while stripPointerCasts()
- // doesn't.
- Align CurrentAlign = AI->getAlign();
- if (PrefAlign <= CurrentAlign)
- return CurrentAlign;
+ // TODO: Ideally, this function would not be called if PrefAlign is smaller
+ // than the current alignment, as the known bits calculation should have
+ // already taken it into account. However, this is not always the case,
+ // as computeKnownBits() has a depth limit, while stripPointerCasts()
+ // doesn't.
+ Align CurrentAlign = AI->getAlign();
+ if (PrefAlign <= CurrentAlign)
+ return CurrentAlign;
// If the preferred alignment is greater than the natural stack alignment
// then don't round up. This avoids dynamic stack realignment.
if (DL.exceedsNaturalStackAlignment(PrefAlign))
- return CurrentAlign;
+ return CurrentAlign;
AI->setAlignment(PrefAlign);
return PrefAlign;
}
if (auto *GO = dyn_cast<GlobalObject>(V)) {
// TODO: as above, this shouldn't be necessary.
- Align CurrentAlign = GO->getPointerAlignment(DL);
- if (PrefAlign <= CurrentAlign)
- return CurrentAlign;
+ Align CurrentAlign = GO->getPointerAlignment(DL);
+ if (PrefAlign <= CurrentAlign)
+ return CurrentAlign;
// If there is a large requested alignment and we can, bump up the alignment
// of the global. If the memory we set aside for the global may not be the
// memory used by the final program then it is impossible for us to reliably
// enforce the preferred alignment.
if (!GO->canIncreaseAlignment())
- return CurrentAlign;
+ return CurrentAlign;
GO->setAlignment(PrefAlign);
return PrefAlign;
}
- return Align(1);
+ return Align(1);
}
Align llvm::getOrEnforceKnownAlignment(Value *V, MaybeAlign PrefAlign,
@@ -1336,7 +1336,7 @@ Align llvm::getOrEnforceKnownAlignment(Value *V, MaybeAlign PrefAlign,
Align Alignment = Align(1ull << std::min(Known.getBitWidth() - 1, TrailZ));
if (PrefAlign && *PrefAlign > Alignment)
- Alignment = std::max(Alignment, tryEnforceAlignment(V, *PrefAlign, DL));
+ Alignment = std::max(Alignment, tryEnforceAlignment(V, *PrefAlign, DL));
// We don't need to make any adjustment.
return Alignment;
@@ -1374,22 +1374,22 @@ static bool PhiHasDebugValue(DILocalVariable *DIVar,
/// least n bits.
static bool valueCoversEntireFragment(Type *ValTy, DbgVariableIntrinsic *DII) {
const DataLayout &DL = DII->getModule()->getDataLayout();
- TypeSize ValueSize = DL.getTypeAllocSizeInBits(ValTy);
- if (Optional<uint64_t> FragmentSize = DII->getFragmentSizeInBits()) {
- assert(!ValueSize.isScalable() &&
- "Fragments don't work on scalable types.");
- return ValueSize.getFixedSize() >= *FragmentSize;
- }
+ TypeSize ValueSize = DL.getTypeAllocSizeInBits(ValTy);
+ if (Optional<uint64_t> FragmentSize = DII->getFragmentSizeInBits()) {
+ assert(!ValueSize.isScalable() &&
+ "Fragments don't work on scalable types.");
+ return ValueSize.getFixedSize() >= *FragmentSize;
+ }
// We can't always calculate the size of the DI variable (e.g. if it is a
// VLA). Try to use the size of the alloca that the dbg intrinsic describes
// intead.
if (DII->isAddressOfVariable())
if (auto *AI = dyn_cast_or_null<AllocaInst>(DII->getVariableLocation()))
- if (Optional<TypeSize> FragmentSize = AI->getAllocationSizeInBits(DL)) {
- assert(ValueSize.isScalable() == FragmentSize->isScalable() &&
- "Both sizes should agree on the scalable flag.");
- return TypeSize::isKnownGE(ValueSize, *FragmentSize);
- }
+ if (Optional<TypeSize> FragmentSize = AI->getAllocationSizeInBits(DL)) {
+ assert(ValueSize.isScalable() == FragmentSize->isScalable() &&
+ "Both sizes should agree on the scalable flag.");
+ return TypeSize::isKnownGE(ValueSize, *FragmentSize);
+ }
// Could not determine size of variable. Conservatively return false.
return false;
}
@@ -1404,7 +1404,7 @@ static DebugLoc getDebugValueLoc(DbgVariableIntrinsic *DII, Instruction *Src) {
MDNode *Scope = DeclareLoc.getScope();
DILocation *InlinedAt = DeclareLoc.getInlinedAt();
// Produce an unknown location with the correct scope / inlinedAt fields.
- return DILocation::get(DII->getContext(), 0, 0, Scope, InlinedAt);
+ return DILocation::get(DII->getContext(), 0, 0, Scope, InlinedAt);
}
/// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value
@@ -2021,10 +2021,10 @@ bool llvm::replaceAllDbgUsesWith(Instruction &From, Value &To,
return false;
}
-std::pair<unsigned, unsigned>
-llvm::removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB) {
+std::pair<unsigned, unsigned>
+llvm::removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB) {
unsigned NumDeadInst = 0;
- unsigned NumDeadDbgInst = 0;
+ unsigned NumDeadDbgInst = 0;
// Delete the instructions backwards, as it has a reduced likelihood of
// having to update as many def-use and use-def chains.
Instruction *EndInst = BB->getTerminator(); // Last not to be deleted.
@@ -2037,13 +2037,13 @@ llvm::removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB) {
EndInst = Inst;
continue;
}
- if (isa<DbgInfoIntrinsic>(Inst))
- ++NumDeadDbgInst;
- else
+ if (isa<DbgInfoIntrinsic>(Inst))
+ ++NumDeadDbgInst;
+ else
++NumDeadInst;
Inst->eraseFromParent();
}
- return {NumDeadInst, NumDeadDbgInst};
+ return {NumDeadInst, NumDeadDbgInst};
}
unsigned llvm::changeToUnreachable(Instruction *I, bool UseLLVMTrap,
@@ -2054,14 +2054,14 @@ unsigned llvm::changeToUnreachable(Instruction *I, bool UseLLVMTrap,
if (MSSAU)
MSSAU->changeToUnreachable(I);
- SmallSetVector<BasicBlock *, 8> UniqueSuccessors;
-
+ SmallSetVector<BasicBlock *, 8> UniqueSuccessors;
+
// Loop over all of the successors, removing BB's entry from any PHI
// nodes.
for (BasicBlock *Successor : successors(BB)) {
Successor->removePredecessor(BB, PreserveLCSSA);
if (DTU)
- UniqueSuccessors.insert(Successor);
+ UniqueSuccessors.insert(Successor);
}
// Insert a call to llvm.trap right before this. This turns the undefined
// behavior into a hard fail instead of falling through into random code.
@@ -2083,18 +2083,18 @@ unsigned llvm::changeToUnreachable(Instruction *I, bool UseLLVMTrap,
BB->getInstList().erase(BBI++);
++NumInstrsRemoved;
}
- if (DTU) {
- SmallVector<DominatorTree::UpdateType, 8> Updates;
- Updates.reserve(UniqueSuccessors.size());
- for (BasicBlock *UniqueSuccessor : UniqueSuccessors)
- Updates.push_back({DominatorTree::Delete, BB, UniqueSuccessor});
- DTU->applyUpdates(Updates);
- }
+ if (DTU) {
+ SmallVector<DominatorTree::UpdateType, 8> Updates;
+ Updates.reserve(UniqueSuccessors.size());
+ for (BasicBlock *UniqueSuccessor : UniqueSuccessors)
+ Updates.push_back({DominatorTree::Delete, BB, UniqueSuccessor});
+ DTU->applyUpdates(Updates);
+ }
return NumInstrsRemoved;
}
CallInst *llvm::createCallMatchingInvoke(InvokeInst *II) {
- SmallVector<Value *, 8> Args(II->args());
+ SmallVector<Value *, 8> Args(II->args());
SmallVector<OperandBundleDef, 1> OpBundles;
II->getOperandBundlesAsDefs(OpBundles);
CallInst *NewCall = CallInst::Create(II->getFunctionType(),
@@ -2135,7 +2135,7 @@ void llvm::changeToCall(InvokeInst *II, DomTreeUpdater *DTU) {
UnwindDestBB->removePredecessor(BB);
II->eraseFromParent();
if (DTU)
- DTU->applyUpdates({{DominatorTree::Delete, BB, UnwindDestBB}});
+ DTU->applyUpdates({{DominatorTree::Delete, BB, UnwindDestBB}});
}
BasicBlock *llvm::changeToInvokeAndSplitBasicBlock(CallInst *CI,
@@ -2151,7 +2151,7 @@ BasicBlock *llvm::changeToInvokeAndSplitBasicBlock(CallInst *CI,
BB->getInstList().pop_back();
// Create the new invoke instruction.
- SmallVector<Value *, 8> InvokeArgs(CI->args());
+ SmallVector<Value *, 8> InvokeArgs(CI->args());
SmallVector<OperandBundleDef, 1> OpBundles;
CI->getOperandBundlesAsDefs(OpBundles);
@@ -2282,7 +2282,7 @@ static bool markAliveBlocks(Function &F,
UnwindDestBB->removePredecessor(II->getParent());
II->eraseFromParent();
if (DTU)
- DTU->applyUpdates({{DominatorTree::Delete, BB, UnwindDestBB}});
+ DTU->applyUpdates({{DominatorTree::Delete, BB, UnwindDestBB}});
} else
changeToCall(II, DTU);
Changed = true;
@@ -2311,7 +2311,7 @@ static bool markAliveBlocks(Function &F,
}
};
- SmallMapVector<BasicBlock *, int, 8> NumPerSuccessorCases;
+ SmallMapVector<BasicBlock *, int, 8> NumPerSuccessorCases;
// Set of unique CatchPads.
SmallDenseMap<CatchPadInst *, detail::DenseSetEmpty, 4,
CatchPadDenseMapInfo, detail::DenseSetPair<CatchPadInst *>>
@@ -2321,22 +2321,22 @@ static bool markAliveBlocks(Function &F,
E = CatchSwitch->handler_end();
I != E; ++I) {
BasicBlock *HandlerBB = *I;
- ++NumPerSuccessorCases[HandlerBB];
+ ++NumPerSuccessorCases[HandlerBB];
auto *CatchPad = cast<CatchPadInst>(HandlerBB->getFirstNonPHI());
if (!HandlerSet.insert({CatchPad, Empty}).second) {
- --NumPerSuccessorCases[HandlerBB];
+ --NumPerSuccessorCases[HandlerBB];
CatchSwitch->removeHandler(I);
--I;
--E;
Changed = true;
}
}
- std::vector<DominatorTree::UpdateType> Updates;
- for (const std::pair<BasicBlock *, int> &I : NumPerSuccessorCases)
- if (I.second == 0)
- Updates.push_back({DominatorTree::Delete, BB, I.first});
- if (DTU)
- DTU->applyUpdates(Updates);
+ std::vector<DominatorTree::UpdateType> Updates;
+ for (const std::pair<BasicBlock *, int> &I : NumPerSuccessorCases)
+ if (I.second == 0)
+ Updates.push_back({DominatorTree::Delete, BB, I.first});
+ if (DTU)
+ DTU->applyUpdates(Updates);
}
Changed |= ConstantFoldTerminator(BB, true, nullptr, DTU);
@@ -2380,7 +2380,7 @@ void llvm::removeUnwindEdge(BasicBlock *BB, DomTreeUpdater *DTU) {
TI->replaceAllUsesWith(NewTI);
TI->eraseFromParent();
if (DTU)
- DTU->applyUpdates({{DominatorTree::Delete, BB, UnwindDest}});
+ DTU->applyUpdates({{DominatorTree::Delete, BB, UnwindDest}});
}
/// removeUnreachableBlocks - Remove blocks that are not reachable, even
@@ -2397,38 +2397,38 @@ bool llvm::removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU,
assert(Reachable.size() < F.size());
- // Are there any blocks left to actually delete?
- SmallSetVector<BasicBlock *, 8> BlocksToRemove;
+ // Are there any blocks left to actually delete?
+ SmallSetVector<BasicBlock *, 8> BlocksToRemove;
for (BasicBlock &BB : F) {
// Skip reachable basic blocks
if (Reachable.count(&BB))
continue;
- // Skip already-deleted blocks
- if (DTU && DTU->isBBPendingDeletion(&BB))
- continue;
- BlocksToRemove.insert(&BB);
- }
-
- if (BlocksToRemove.empty())
- return Changed;
-
- Changed = true;
- NumRemoved += BlocksToRemove.size();
-
+ // Skip already-deleted blocks
+ if (DTU && DTU->isBBPendingDeletion(&BB))
+ continue;
+ BlocksToRemove.insert(&BB);
+ }
+
+ if (BlocksToRemove.empty())
+ return Changed;
+
+ Changed = true;
+ NumRemoved += BlocksToRemove.size();
+
if (MSSAU)
- MSSAU->removeBlocks(BlocksToRemove);
+ MSSAU->removeBlocks(BlocksToRemove);
- // Loop over all of the basic blocks that are up for removal, dropping all of
+ // Loop over all of the basic blocks that are up for removal, dropping all of
// their internal references. Update DTU if available.
std::vector<DominatorTree::UpdateType> Updates;
- for (auto *BB : BlocksToRemove) {
- SmallSetVector<BasicBlock *, 8> UniqueSuccessors;
+ for (auto *BB : BlocksToRemove) {
+ SmallSetVector<BasicBlock *, 8> UniqueSuccessors;
for (BasicBlock *Successor : successors(BB)) {
- // Only remove references to BB in reachable successors of BB.
- if (Reachable.count(Successor))
+ // Only remove references to BB in reachable successors of BB.
+ if (Reachable.count(Successor))
Successor->removePredecessor(BB);
if (DTU)
- UniqueSuccessors.insert(Successor);
+ UniqueSuccessors.insert(Successor);
}
BB->dropAllReferences();
if (DTU) {
@@ -2442,22 +2442,22 @@ bool llvm::removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU,
new UnreachableInst(BB->getContext(), BB);
assert(succ_empty(BB) && "The successor list of BB isn't empty before "
"applying corresponding DTU updates.");
- Updates.reserve(Updates.size() + UniqueSuccessors.size());
- for (auto *UniqueSuccessor : UniqueSuccessors)
- Updates.push_back({DominatorTree::Delete, BB, UniqueSuccessor});
+ Updates.reserve(Updates.size() + UniqueSuccessors.size());
+ for (auto *UniqueSuccessor : UniqueSuccessors)
+ Updates.push_back({DominatorTree::Delete, BB, UniqueSuccessor});
}
}
if (DTU) {
- DTU->applyUpdates(Updates);
- for (auto *BB : BlocksToRemove)
+ DTU->applyUpdates(Updates);
+ for (auto *BB : BlocksToRemove)
DTU->deleteBB(BB);
} else {
- for (auto *BB : BlocksToRemove)
+ for (auto *BB : BlocksToRemove)
BB->eraseFromParent();
}
- return Changed;
+ return Changed;
}
void llvm::combineMetadata(Instruction *K, const Instruction *J,
@@ -2702,13 +2702,13 @@ bool llvm::callsGCLeafFunction(const CallBase *Call,
if (F->hasFnAttribute("gc-leaf-function"))
return true;
- if (auto IID = F->getIntrinsicID()) {
+ if (auto IID = F->getIntrinsicID()) {
// Most LLVM intrinsics do not take safepoints.
return IID != Intrinsic::experimental_gc_statepoint &&
- IID != Intrinsic::experimental_deoptimize &&
- IID != Intrinsic::memcpy_element_unordered_atomic &&
- IID != Intrinsic::memmove_element_unordered_atomic;
- }
+ IID != Intrinsic::experimental_deoptimize &&
+ IID != Intrinsic::memcpy_element_unordered_atomic &&
+ IID != Intrinsic::memmove_element_unordered_atomic;
+ }
}
// Lib calls can be materialized by some passes, and won't be
@@ -2836,7 +2836,7 @@ struct BitPart {
/// Analyze the specified subexpression and see if it is capable of providing
/// pieces of a bswap or bitreverse. The subexpression provides a potential
-/// piece of a bswap or bitreverse if it can be proved that each non-zero bit in
+/// piece of a bswap or bitreverse if it can be proved that each non-zero bit in
/// the output of the expression came from a corresponding bit in some other
/// value. This function is recursive, and the end result is a mapping of
/// bitnumber to bitnumber. It is the caller's responsibility to validate that
@@ -2848,10 +2848,10 @@ struct BitPart {
/// BitPart is returned with Provider set to %X and Provenance[24-31] set to
/// [0-7].
///
-/// For vector types, all analysis is performed at the per-element level. No
-/// cross-element analysis is supported (shuffle/insertion/reduction), and all
-/// constant masks must be splatted across all elements.
-///
+/// For vector types, all analysis is performed at the per-element level. No
+/// cross-element analysis is supported (shuffle/insertion/reduction), and all
+/// constant masks must be splatted across all elements.
+///
/// To avoid revisiting values, the BitPart results are memoized into the
/// provided map. To avoid unnecessary copying of BitParts, BitParts are
/// constructed in-place in the \c BPS map. Because of this \c BPS needs to
@@ -2869,7 +2869,7 @@ collectBitParts(Value *V, bool MatchBSwaps, bool MatchBitReversals,
return I->second;
auto &Result = BPS[V] = None;
- auto BitWidth = V->getType()->getScalarSizeInBits();
+ auto BitWidth = V->getType()->getScalarSizeInBits();
// Prevent stack overflow by limiting the recursion depth
if (Depth == BitPartRecursionMaxDepth) {
@@ -2877,16 +2877,16 @@ collectBitParts(Value *V, bool MatchBSwaps, bool MatchBitReversals,
return Result;
}
- if (auto *I = dyn_cast<Instruction>(V)) {
- Value *X, *Y;
- const APInt *C;
-
+ if (auto *I = dyn_cast<Instruction>(V)) {
+ Value *X, *Y;
+ const APInt *C;
+
// If this is an or instruction, it may be an inner node of the bswap.
- if (match(V, m_Or(m_Value(X), m_Value(Y)))) {
- const auto &A =
- collectBitParts(X, MatchBSwaps, MatchBitReversals, BPS, Depth + 1);
- const auto &B =
- collectBitParts(Y, MatchBSwaps, MatchBitReversals, BPS, Depth + 1);
+ if (match(V, m_Or(m_Value(X), m_Value(Y)))) {
+ const auto &A =
+ collectBitParts(X, MatchBSwaps, MatchBitReversals, BPS, Depth + 1);
+ const auto &B =
+ collectBitParts(Y, MatchBSwaps, MatchBitReversals, BPS, Depth + 1);
if (!A || !B)
return Result;
@@ -2895,31 +2895,31 @@ collectBitParts(Value *V, bool MatchBSwaps, bool MatchBitReversals,
return Result;
Result = BitPart(A->Provider, BitWidth);
- for (unsigned BitIdx = 0; BitIdx < BitWidth; ++BitIdx) {
- if (A->Provenance[BitIdx] != BitPart::Unset &&
- B->Provenance[BitIdx] != BitPart::Unset &&
- A->Provenance[BitIdx] != B->Provenance[BitIdx])
+ for (unsigned BitIdx = 0; BitIdx < BitWidth; ++BitIdx) {
+ if (A->Provenance[BitIdx] != BitPart::Unset &&
+ B->Provenance[BitIdx] != BitPart::Unset &&
+ A->Provenance[BitIdx] != B->Provenance[BitIdx])
return Result = None;
- if (A->Provenance[BitIdx] == BitPart::Unset)
- Result->Provenance[BitIdx] = B->Provenance[BitIdx];
+ if (A->Provenance[BitIdx] == BitPart::Unset)
+ Result->Provenance[BitIdx] = B->Provenance[BitIdx];
else
- Result->Provenance[BitIdx] = A->Provenance[BitIdx];
+ Result->Provenance[BitIdx] = A->Provenance[BitIdx];
}
return Result;
}
// If this is a logical shift by a constant, recurse then shift the result.
- if (match(V, m_LogicalShift(m_Value(X), m_APInt(C)))) {
- const APInt &BitShift = *C;
-
+ if (match(V, m_LogicalShift(m_Value(X), m_APInt(C)))) {
+ const APInt &BitShift = *C;
+
// Ensure the shift amount is defined.
- if (BitShift.uge(BitWidth))
+ if (BitShift.uge(BitWidth))
return Result;
- const auto &Res =
- collectBitParts(X, MatchBSwaps, MatchBitReversals, BPS, Depth + 1);
+ const auto &Res =
+ collectBitParts(X, MatchBSwaps, MatchBitReversals, BPS, Depth + 1);
if (!Res)
return Result;
Result = Res;
@@ -2927,11 +2927,11 @@ collectBitParts(Value *V, bool MatchBSwaps, bool MatchBitReversals,
// Perform the "shift" on BitProvenance.
auto &P = Result->Provenance;
if (I->getOpcode() == Instruction::Shl) {
- P.erase(std::prev(P.end(), BitShift.getZExtValue()), P.end());
- P.insert(P.begin(), BitShift.getZExtValue(), BitPart::Unset);
+ P.erase(std::prev(P.end(), BitShift.getZExtValue()), P.end());
+ P.insert(P.begin(), BitShift.getZExtValue(), BitPart::Unset);
} else {
- P.erase(P.begin(), std::next(P.begin(), BitShift.getZExtValue()));
- P.insert(P.end(), BitShift.getZExtValue(), BitPart::Unset);
+ P.erase(P.begin(), std::next(P.begin(), BitShift.getZExtValue()));
+ P.insert(P.end(), BitShift.getZExtValue(), BitPart::Unset);
}
return Result;
@@ -2939,111 +2939,111 @@ collectBitParts(Value *V, bool MatchBSwaps, bool MatchBitReversals,
// If this is a logical 'and' with a mask that clears bits, recurse then
// unset the appropriate bits.
- if (match(V, m_And(m_Value(X), m_APInt(C)))) {
- const APInt &AndMask = *C;
+ if (match(V, m_And(m_Value(X), m_APInt(C)))) {
+ const APInt &AndMask = *C;
// Check that the mask allows a multiple of 8 bits for a bswap, for an
// early exit.
unsigned NumMaskedBits = AndMask.countPopulation();
- if (!MatchBitReversals && (NumMaskedBits % 8) != 0)
+ if (!MatchBitReversals && (NumMaskedBits % 8) != 0)
return Result;
- const auto &Res =
- collectBitParts(X, MatchBSwaps, MatchBitReversals, BPS, Depth + 1);
+ const auto &Res =
+ collectBitParts(X, MatchBSwaps, MatchBitReversals, BPS, Depth + 1);
if (!Res)
return Result;
Result = Res;
- for (unsigned BitIdx = 0; BitIdx < BitWidth; ++BitIdx)
+ for (unsigned BitIdx = 0; BitIdx < BitWidth; ++BitIdx)
// If the AndMask is zero for this bit, clear the bit.
- if (AndMask[BitIdx] == 0)
- Result->Provenance[BitIdx] = BitPart::Unset;
+ if (AndMask[BitIdx] == 0)
+ Result->Provenance[BitIdx] = BitPart::Unset;
return Result;
}
// If this is a zext instruction zero extend the result.
- if (match(V, m_ZExt(m_Value(X)))) {
- const auto &Res =
- collectBitParts(X, MatchBSwaps, MatchBitReversals, BPS, Depth + 1);
+ if (match(V, m_ZExt(m_Value(X)))) {
+ const auto &Res =
+ collectBitParts(X, MatchBSwaps, MatchBitReversals, BPS, Depth + 1);
+ if (!Res)
+ return Result;
+
+ Result = BitPart(Res->Provider, BitWidth);
+ auto NarrowBitWidth = X->getType()->getScalarSizeInBits();
+ for (unsigned BitIdx = 0; BitIdx < NarrowBitWidth; ++BitIdx)
+ Result->Provenance[BitIdx] = Res->Provenance[BitIdx];
+ for (unsigned BitIdx = NarrowBitWidth; BitIdx < BitWidth; ++BitIdx)
+ Result->Provenance[BitIdx] = BitPart::Unset;
+ return Result;
+ }
+
+ // BITREVERSE - most likely due to us previous matching a partial
+ // bitreverse.
+ if (match(V, m_BitReverse(m_Value(X)))) {
+ const auto &Res =
+ collectBitParts(X, MatchBSwaps, MatchBitReversals, BPS, Depth + 1);
if (!Res)
return Result;
Result = BitPart(Res->Provider, BitWidth);
- auto NarrowBitWidth = X->getType()->getScalarSizeInBits();
- for (unsigned BitIdx = 0; BitIdx < NarrowBitWidth; ++BitIdx)
- Result->Provenance[BitIdx] = Res->Provenance[BitIdx];
- for (unsigned BitIdx = NarrowBitWidth; BitIdx < BitWidth; ++BitIdx)
- Result->Provenance[BitIdx] = BitPart::Unset;
+ for (unsigned BitIdx = 0; BitIdx < BitWidth; ++BitIdx)
+ Result->Provenance[(BitWidth - 1) - BitIdx] = Res->Provenance[BitIdx];
+ return Result;
+ }
+
+ // BSWAP - most likely due to us previous matching a partial bswap.
+ if (match(V, m_BSwap(m_Value(X)))) {
+ const auto &Res =
+ collectBitParts(X, MatchBSwaps, MatchBitReversals, BPS, Depth + 1);
+ if (!Res)
+ return Result;
+
+ unsigned ByteWidth = BitWidth / 8;
+ Result = BitPart(Res->Provider, BitWidth);
+ for (unsigned ByteIdx = 0; ByteIdx < ByteWidth; ++ByteIdx) {
+ unsigned ByteBitOfs = ByteIdx * 8;
+ for (unsigned BitIdx = 0; BitIdx < 8; ++BitIdx)
+ Result->Provenance[(BitWidth - 8 - ByteBitOfs) + BitIdx] =
+ Res->Provenance[ByteBitOfs + BitIdx];
+ }
+ return Result;
+ }
+
+ // Funnel 'double' shifts take 3 operands, 2 inputs and the shift
+ // amount (modulo).
+ // fshl(X,Y,Z): (X << (Z % BW)) | (Y >> (BW - (Z % BW)))
+ // fshr(X,Y,Z): (X << (BW - (Z % BW))) | (Y >> (Z % BW))
+ if (match(V, m_FShl(m_Value(X), m_Value(Y), m_APInt(C))) ||
+ match(V, m_FShr(m_Value(X), m_Value(Y), m_APInt(C)))) {
+ // We can treat fshr as a fshl by flipping the modulo amount.
+ unsigned ModAmt = C->urem(BitWidth);
+ if (cast<IntrinsicInst>(I)->getIntrinsicID() == Intrinsic::fshr)
+ ModAmt = BitWidth - ModAmt;
+
+ const auto &LHS =
+ collectBitParts(X, MatchBSwaps, MatchBitReversals, BPS, Depth + 1);
+ const auto &RHS =
+ collectBitParts(Y, MatchBSwaps, MatchBitReversals, BPS, Depth + 1);
+
+ // Check we have both sources and they are from the same provider.
+ if (!LHS || !RHS || !LHS->Provider || LHS->Provider != RHS->Provider)
+ return Result;
+
+ unsigned StartBitRHS = BitWidth - ModAmt;
+ Result = BitPart(LHS->Provider, BitWidth);
+ for (unsigned BitIdx = 0; BitIdx < StartBitRHS; ++BitIdx)
+ Result->Provenance[BitIdx + ModAmt] = LHS->Provenance[BitIdx];
+ for (unsigned BitIdx = 0; BitIdx < ModAmt; ++BitIdx)
+ Result->Provenance[BitIdx] = RHS->Provenance[BitIdx + StartBitRHS];
return Result;
}
-
- // BITREVERSE - most likely due to us previous matching a partial
- // bitreverse.
- if (match(V, m_BitReverse(m_Value(X)))) {
- const auto &Res =
- collectBitParts(X, MatchBSwaps, MatchBitReversals, BPS, Depth + 1);
- if (!Res)
- return Result;
-
- Result = BitPart(Res->Provider, BitWidth);
- for (unsigned BitIdx = 0; BitIdx < BitWidth; ++BitIdx)
- Result->Provenance[(BitWidth - 1) - BitIdx] = Res->Provenance[BitIdx];
- return Result;
- }
-
- // BSWAP - most likely due to us previous matching a partial bswap.
- if (match(V, m_BSwap(m_Value(X)))) {
- const auto &Res =
- collectBitParts(X, MatchBSwaps, MatchBitReversals, BPS, Depth + 1);
- if (!Res)
- return Result;
-
- unsigned ByteWidth = BitWidth / 8;
- Result = BitPart(Res->Provider, BitWidth);
- for (unsigned ByteIdx = 0; ByteIdx < ByteWidth; ++ByteIdx) {
- unsigned ByteBitOfs = ByteIdx * 8;
- for (unsigned BitIdx = 0; BitIdx < 8; ++BitIdx)
- Result->Provenance[(BitWidth - 8 - ByteBitOfs) + BitIdx] =
- Res->Provenance[ByteBitOfs + BitIdx];
- }
- return Result;
- }
-
- // Funnel 'double' shifts take 3 operands, 2 inputs and the shift
- // amount (modulo).
- // fshl(X,Y,Z): (X << (Z % BW)) | (Y >> (BW - (Z % BW)))
- // fshr(X,Y,Z): (X << (BW - (Z % BW))) | (Y >> (Z % BW))
- if (match(V, m_FShl(m_Value(X), m_Value(Y), m_APInt(C))) ||
- match(V, m_FShr(m_Value(X), m_Value(Y), m_APInt(C)))) {
- // We can treat fshr as a fshl by flipping the modulo amount.
- unsigned ModAmt = C->urem(BitWidth);
- if (cast<IntrinsicInst>(I)->getIntrinsicID() == Intrinsic::fshr)
- ModAmt = BitWidth - ModAmt;
-
- const auto &LHS =
- collectBitParts(X, MatchBSwaps, MatchBitReversals, BPS, Depth + 1);
- const auto &RHS =
- collectBitParts(Y, MatchBSwaps, MatchBitReversals, BPS, Depth + 1);
-
- // Check we have both sources and they are from the same provider.
- if (!LHS || !RHS || !LHS->Provider || LHS->Provider != RHS->Provider)
- return Result;
-
- unsigned StartBitRHS = BitWidth - ModAmt;
- Result = BitPart(LHS->Provider, BitWidth);
- for (unsigned BitIdx = 0; BitIdx < StartBitRHS; ++BitIdx)
- Result->Provenance[BitIdx + ModAmt] = LHS->Provenance[BitIdx];
- for (unsigned BitIdx = 0; BitIdx < ModAmt; ++BitIdx)
- Result->Provenance[BitIdx] = RHS->Provenance[BitIdx + StartBitRHS];
- return Result;
- }
}
// Okay, we got to something that isn't a shift, 'or' or 'and'. This must be
// the input value to the bswap/bitreverse.
Result = BitPart(V, BitWidth);
- for (unsigned BitIdx = 0; BitIdx < BitWidth; ++BitIdx)
- Result->Provenance[BitIdx] = BitIdx;
+ for (unsigned BitIdx = 0; BitIdx < BitWidth; ++BitIdx)
+ Result->Provenance[BitIdx] = BitIdx;
return Result;
}
@@ -3070,89 +3070,89 @@ bool llvm::recognizeBSwapOrBitReverseIdiom(
return false;
if (!MatchBSwaps && !MatchBitReversals)
return false;
- Type *ITy = I->getType();
- if (!ITy->isIntOrIntVectorTy() || ITy->getScalarSizeInBits() > 128)
- return false; // Can't do integer/elements > 128 bits.
+ Type *ITy = I->getType();
+ if (!ITy->isIntOrIntVectorTy() || ITy->getScalarSizeInBits() > 128)
+ return false; // Can't do integer/elements > 128 bits.
- Type *DemandedTy = ITy;
- if (I->hasOneUse())
- if (auto *Trunc = dyn_cast<TruncInst>(I->user_back()))
- DemandedTy = Trunc->getType();
+ Type *DemandedTy = ITy;
+ if (I->hasOneUse())
+ if (auto *Trunc = dyn_cast<TruncInst>(I->user_back()))
+ DemandedTy = Trunc->getType();
// Try to find all the pieces corresponding to the bswap.
std::map<Value *, Optional<BitPart>> BPS;
auto Res = collectBitParts(I, MatchBSwaps, MatchBitReversals, BPS, 0);
if (!Res)
return false;
- ArrayRef<int8_t> BitProvenance = Res->Provenance;
- assert(all_of(BitProvenance,
- [](int8_t I) { return I == BitPart::Unset || 0 <= I; }) &&
- "Illegal bit provenance index");
-
- // If the upper bits are zero, then attempt to perform as a truncated op.
- if (BitProvenance.back() == BitPart::Unset) {
- while (!BitProvenance.empty() && BitProvenance.back() == BitPart::Unset)
- BitProvenance = BitProvenance.drop_back();
- if (BitProvenance.empty())
- return false; // TODO - handle null value?
- DemandedTy = Type::getIntNTy(I->getContext(), BitProvenance.size());
- if (auto *IVecTy = dyn_cast<VectorType>(ITy))
- DemandedTy = VectorType::get(DemandedTy, IVecTy);
- }
-
- // Check BitProvenance hasn't found a source larger than the result type.
- unsigned DemandedBW = DemandedTy->getScalarSizeInBits();
- if (DemandedBW > ITy->getScalarSizeInBits())
- return false;
-
+ ArrayRef<int8_t> BitProvenance = Res->Provenance;
+ assert(all_of(BitProvenance,
+ [](int8_t I) { return I == BitPart::Unset || 0 <= I; }) &&
+ "Illegal bit provenance index");
+
+ // If the upper bits are zero, then attempt to perform as a truncated op.
+ if (BitProvenance.back() == BitPart::Unset) {
+ while (!BitProvenance.empty() && BitProvenance.back() == BitPart::Unset)
+ BitProvenance = BitProvenance.drop_back();
+ if (BitProvenance.empty())
+ return false; // TODO - handle null value?
+ DemandedTy = Type::getIntNTy(I->getContext(), BitProvenance.size());
+ if (auto *IVecTy = dyn_cast<VectorType>(ITy))
+ DemandedTy = VectorType::get(DemandedTy, IVecTy);
+ }
+
+ // Check BitProvenance hasn't found a source larger than the result type.
+ unsigned DemandedBW = DemandedTy->getScalarSizeInBits();
+ if (DemandedBW > ITy->getScalarSizeInBits())
+ return false;
+
// Now, is the bit permutation correct for a bswap or a bitreverse? We can
// only byteswap values with an even number of bytes.
- APInt DemandedMask = APInt::getAllOnesValue(DemandedBW);
- bool OKForBSwap = MatchBSwaps && (DemandedBW % 16) == 0;
- bool OKForBitReverse = MatchBitReversals;
- for (unsigned BitIdx = 0;
- (BitIdx < DemandedBW) && (OKForBSwap || OKForBitReverse); ++BitIdx) {
- if (BitProvenance[BitIdx] == BitPart::Unset) {
- DemandedMask.clearBit(BitIdx);
- continue;
- }
- OKForBSwap &= bitTransformIsCorrectForBSwap(BitProvenance[BitIdx], BitIdx,
- DemandedBW);
- OKForBitReverse &= bitTransformIsCorrectForBitReverse(BitProvenance[BitIdx],
- BitIdx, DemandedBW);
+ APInt DemandedMask = APInt::getAllOnesValue(DemandedBW);
+ bool OKForBSwap = MatchBSwaps && (DemandedBW % 16) == 0;
+ bool OKForBitReverse = MatchBitReversals;
+ for (unsigned BitIdx = 0;
+ (BitIdx < DemandedBW) && (OKForBSwap || OKForBitReverse); ++BitIdx) {
+ if (BitProvenance[BitIdx] == BitPart::Unset) {
+ DemandedMask.clearBit(BitIdx);
+ continue;
+ }
+ OKForBSwap &= bitTransformIsCorrectForBSwap(BitProvenance[BitIdx], BitIdx,
+ DemandedBW);
+ OKForBitReverse &= bitTransformIsCorrectForBitReverse(BitProvenance[BitIdx],
+ BitIdx, DemandedBW);
}
Intrinsic::ID Intrin;
- if (OKForBSwap)
+ if (OKForBSwap)
Intrin = Intrinsic::bswap;
- else if (OKForBitReverse)
+ else if (OKForBitReverse)
Intrin = Intrinsic::bitreverse;
else
return false;
- Function *F = Intrinsic::getDeclaration(I->getModule(), Intrin, DemandedTy);
- Value *Provider = Res->Provider;
-
- // We may need to truncate the provider.
- if (DemandedTy != Provider->getType()) {
- auto *Trunc =
- CastInst::CreateIntegerCast(Provider, DemandedTy, false, "trunc", I);
- InsertedInsts.push_back(Trunc);
- Provider = Trunc;
- }
-
- Instruction *Result = CallInst::Create(F, Provider, "rev", I);
- InsertedInsts.push_back(Result);
-
- if (!DemandedMask.isAllOnesValue()) {
- auto *Mask = ConstantInt::get(DemandedTy, DemandedMask);
- Result = BinaryOperator::Create(Instruction::And, Result, Mask, "mask", I);
- InsertedInsts.push_back(Result);
- }
-
- // We may need to zeroextend back to the result type.
- if (ITy != Result->getType()) {
- auto *ExtInst = CastInst::CreateIntegerCast(Result, ITy, false, "zext", I);
+ Function *F = Intrinsic::getDeclaration(I->getModule(), Intrin, DemandedTy);
+ Value *Provider = Res->Provider;
+
+ // We may need to truncate the provider.
+ if (DemandedTy != Provider->getType()) {
+ auto *Trunc =
+ CastInst::CreateIntegerCast(Provider, DemandedTy, false, "trunc", I);
+ InsertedInsts.push_back(Trunc);
+ Provider = Trunc;
+ }
+
+ Instruction *Result = CallInst::Create(F, Provider, "rev", I);
+ InsertedInsts.push_back(Result);
+
+ if (!DemandedMask.isAllOnesValue()) {
+ auto *Mask = ConstantInt::get(DemandedTy, DemandedMask);
+ Result = BinaryOperator::Create(Instruction::And, Result, Mask, "mask", I);
+ InsertedInsts.push_back(Result);
+ }
+
+ // We may need to zeroextend back to the result type.
+ if (ITy != Result->getType()) {
+ auto *ExtInst = CastInst::CreateIntegerCast(Result, ITy, false, "zext", I);
InsertedInsts.push_back(ExtInst);
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/LoopPeel.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/LoopPeel.cpp
index 10ffb140a7..befacb5917 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/LoopPeel.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/LoopPeel.cpp
@@ -1,862 +1,862 @@
-//===- LoopPeel.cpp -------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Loop Peeling Utilities.
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Utils/LoopPeel.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/LoopIterator.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Analysis/ScalarEvolutionExpressions.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/InstrTypes.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/MDBuilder.h"
-#include "llvm/IR/Metadata.h"
-#include "llvm/IR/PatternMatch.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "llvm/Transforms/Utils/Cloning.h"
-#include "llvm/Transforms/Utils/LoopSimplify.h"
-#include "llvm/Transforms/Utils/LoopUtils.h"
-#include "llvm/Transforms/Utils/UnrollLoop.h"
-#include "llvm/Transforms/Utils/ValueMapper.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <limits>
-
-using namespace llvm;
-using namespace llvm::PatternMatch;
-
-#define DEBUG_TYPE "loop-peel"
-
-STATISTIC(NumPeeled, "Number of loops peeled");
-
-static cl::opt<unsigned> UnrollPeelCount(
- "unroll-peel-count", cl::Hidden,
- cl::desc("Set the unroll peeling count, for testing purposes"));
-
-static cl::opt<bool>
- UnrollAllowPeeling("unroll-allow-peeling", cl::init(true), cl::Hidden,
- cl::desc("Allows loops to be peeled when the dynamic "
- "trip count is known to be low."));
-
-static cl::opt<bool>
- UnrollAllowLoopNestsPeeling("unroll-allow-loop-nests-peeling",
- cl::init(false), cl::Hidden,
- cl::desc("Allows loop nests to be peeled."));
-
-static cl::opt<unsigned> UnrollPeelMaxCount(
- "unroll-peel-max-count", cl::init(7), cl::Hidden,
- cl::desc("Max average trip count which will cause loop peeling."));
-
-static cl::opt<unsigned> UnrollForcePeelCount(
- "unroll-force-peel-count", cl::init(0), cl::Hidden,
- cl::desc("Force a peel count regardless of profiling information."));
-
-static cl::opt<bool> UnrollPeelMultiDeoptExit(
- "unroll-peel-multi-deopt-exit", cl::init(true), cl::Hidden,
- cl::desc("Allow peeling of loops with multiple deopt exits."));
-
-static const char *PeeledCountMetaData = "llvm.loop.peeled.count";
-
-// Designates that a Phi is estimated to become invariant after an "infinite"
-// number of loop iterations (i.e. only may become an invariant if the loop is
-// fully unrolled).
-static const unsigned InfiniteIterationsToInvariance =
- std::numeric_limits<unsigned>::max();
-
-// Check whether we are capable of peeling this loop.
-bool llvm::canPeel(Loop *L) {
- // Make sure the loop is in simplified form
- if (!L->isLoopSimplifyForm())
- return false;
-
- if (UnrollPeelMultiDeoptExit) {
- SmallVector<BasicBlock *, 4> Exits;
- L->getUniqueNonLatchExitBlocks(Exits);
-
- if (!Exits.empty()) {
- // Latch's terminator is a conditional branch, Latch is exiting and
- // all non Latch exits ends up with deoptimize.
- const BasicBlock *Latch = L->getLoopLatch();
- const BranchInst *T = dyn_cast<BranchInst>(Latch->getTerminator());
- return T && T->isConditional() && L->isLoopExiting(Latch) &&
- all_of(Exits, [](const BasicBlock *BB) {
- return BB->getTerminatingDeoptimizeCall();
- });
- }
- }
-
- // Only peel loops that contain a single exit
- if (!L->getExitingBlock() || !L->getUniqueExitBlock())
- return false;
-
- // Don't try to peel loops where the latch is not the exiting block.
- // This can be an indication of two different things:
- // 1) The loop is not rotated.
- // 2) The loop contains irreducible control flow that involves the latch.
- const BasicBlock *Latch = L->getLoopLatch();
- if (Latch != L->getExitingBlock())
- return false;
-
- // Peeling is only supported if the latch is a branch.
- if (!isa<BranchInst>(Latch->getTerminator()))
- return false;
-
- return true;
-}
-
-// This function calculates the number of iterations after which the given Phi
-// becomes an invariant. The pre-calculated values are memorized in the map. The
-// function (shortcut is I) is calculated according to the following definition:
-// Given %x = phi <Inputs from above the loop>, ..., [%y, %back.edge].
-// If %y is a loop invariant, then I(%x) = 1.
-// If %y is a Phi from the loop header, I(%x) = I(%y) + 1.
-// Otherwise, I(%x) is infinite.
-// TODO: Actually if %y is an expression that depends only on Phi %z and some
-// loop invariants, we can estimate I(%x) = I(%z) + 1. The example
-// looks like:
-// %x = phi(0, %a), <-- becomes invariant starting from 3rd iteration.
-// %y = phi(0, 5),
-// %a = %y + 1.
-static unsigned calculateIterationsToInvariance(
- PHINode *Phi, Loop *L, BasicBlock *BackEdge,
- SmallDenseMap<PHINode *, unsigned> &IterationsToInvariance) {
- assert(Phi->getParent() == L->getHeader() &&
- "Non-loop Phi should not be checked for turning into invariant.");
- assert(BackEdge == L->getLoopLatch() && "Wrong latch?");
- // If we already know the answer, take it from the map.
- auto I = IterationsToInvariance.find(Phi);
- if (I != IterationsToInvariance.end())
- return I->second;
-
- // Otherwise we need to analyze the input from the back edge.
- Value *Input = Phi->getIncomingValueForBlock(BackEdge);
- // Place infinity to map to avoid infinite recursion for cycled Phis. Such
- // cycles can never stop on an invariant.
- IterationsToInvariance[Phi] = InfiniteIterationsToInvariance;
- unsigned ToInvariance = InfiniteIterationsToInvariance;
-
- if (L->isLoopInvariant(Input))
- ToInvariance = 1u;
- else if (PHINode *IncPhi = dyn_cast<PHINode>(Input)) {
- // Only consider Phis in header block.
- if (IncPhi->getParent() != L->getHeader())
- return InfiniteIterationsToInvariance;
- // If the input becomes an invariant after X iterations, then our Phi
- // becomes an invariant after X + 1 iterations.
- unsigned InputToInvariance = calculateIterationsToInvariance(
- IncPhi, L, BackEdge, IterationsToInvariance);
- if (InputToInvariance != InfiniteIterationsToInvariance)
- ToInvariance = InputToInvariance + 1u;
- }
-
- // If we found that this Phi lies in an invariant chain, update the map.
- if (ToInvariance != InfiniteIterationsToInvariance)
- IterationsToInvariance[Phi] = ToInvariance;
- return ToInvariance;
-}
-
-// Return the number of iterations to peel off that make conditions in the
-// body true/false. For example, if we peel 2 iterations off the loop below,
-// the condition i < 2 can be evaluated at compile time.
-// for (i = 0; i < n; i++)
-// if (i < 2)
-// ..
-// else
-// ..
-// }
-static unsigned countToEliminateCompares(Loop &L, unsigned MaxPeelCount,
- ScalarEvolution &SE) {
- assert(L.isLoopSimplifyForm() && "Loop needs to be in loop simplify form");
- unsigned DesiredPeelCount = 0;
-
- for (auto *BB : L.blocks()) {
- auto *BI = dyn_cast<BranchInst>(BB->getTerminator());
- if (!BI || BI->isUnconditional())
- continue;
-
- // Ignore loop exit condition.
- if (L.getLoopLatch() == BB)
- continue;
-
- Value *Condition = BI->getCondition();
- Value *LeftVal, *RightVal;
- CmpInst::Predicate Pred;
- if (!match(Condition, m_ICmp(Pred, m_Value(LeftVal), m_Value(RightVal))))
- continue;
-
- const SCEV *LeftSCEV = SE.getSCEV(LeftVal);
- const SCEV *RightSCEV = SE.getSCEV(RightVal);
-
- // Do not consider predicates that are known to be true or false
- // independently of the loop iteration.
- if (SE.isKnownPredicate(Pred, LeftSCEV, RightSCEV) ||
- SE.isKnownPredicate(ICmpInst::getInversePredicate(Pred), LeftSCEV,
- RightSCEV))
- continue;
-
- // Check if we have a condition with one AddRec and one non AddRec
- // expression. Normalize LeftSCEV to be the AddRec.
- if (!isa<SCEVAddRecExpr>(LeftSCEV)) {
- if (isa<SCEVAddRecExpr>(RightSCEV)) {
- std::swap(LeftSCEV, RightSCEV);
- Pred = ICmpInst::getSwappedPredicate(Pred);
- } else
- continue;
- }
-
- const SCEVAddRecExpr *LeftAR = cast<SCEVAddRecExpr>(LeftSCEV);
-
- // Avoid huge SCEV computations in the loop below, make sure we only
- // consider AddRecs of the loop we are trying to peel.
- if (!LeftAR->isAffine() || LeftAR->getLoop() != &L)
- continue;
- if (!(ICmpInst::isEquality(Pred) && LeftAR->hasNoSelfWrap()) &&
- !SE.getMonotonicPredicateType(LeftAR, Pred))
- continue;
-
- // Check if extending the current DesiredPeelCount lets us evaluate Pred
- // or !Pred in the loop body statically.
- unsigned NewPeelCount = DesiredPeelCount;
-
- const SCEV *IterVal = LeftAR->evaluateAtIteration(
- SE.getConstant(LeftSCEV->getType(), NewPeelCount), SE);
-
- // If the original condition is not known, get the negated predicate
- // (which holds on the else branch) and check if it is known. This allows
- // us to peel of iterations that make the original condition false.
- if (!SE.isKnownPredicate(Pred, IterVal, RightSCEV))
- Pred = ICmpInst::getInversePredicate(Pred);
-
- const SCEV *Step = LeftAR->getStepRecurrence(SE);
- const SCEV *NextIterVal = SE.getAddExpr(IterVal, Step);
- auto PeelOneMoreIteration = [&IterVal, &NextIterVal, &SE, Step,
- &NewPeelCount]() {
- IterVal = NextIterVal;
- NextIterVal = SE.getAddExpr(IterVal, Step);
- NewPeelCount++;
- };
-
- auto CanPeelOneMoreIteration = [&NewPeelCount, &MaxPeelCount]() {
- return NewPeelCount < MaxPeelCount;
- };
-
- while (CanPeelOneMoreIteration() &&
- SE.isKnownPredicate(Pred, IterVal, RightSCEV))
- PeelOneMoreIteration();
-
- // With *that* peel count, does the predicate !Pred become known in the
- // first iteration of the loop body after peeling?
- if (!SE.isKnownPredicate(ICmpInst::getInversePredicate(Pred), IterVal,
- RightSCEV))
- continue; // If not, give up.
-
- // However, for equality comparisons, that isn't always sufficient to
- // eliminate the comparsion in loop body, we may need to peel one more
- // iteration. See if that makes !Pred become unknown again.
- if (ICmpInst::isEquality(Pred) &&
- !SE.isKnownPredicate(ICmpInst::getInversePredicate(Pred), NextIterVal,
- RightSCEV) &&
- !SE.isKnownPredicate(Pred, IterVal, RightSCEV) &&
- SE.isKnownPredicate(Pred, NextIterVal, RightSCEV)) {
- if (!CanPeelOneMoreIteration())
- continue; // Need to peel one more iteration, but can't. Give up.
- PeelOneMoreIteration(); // Great!
- }
-
- DesiredPeelCount = std::max(DesiredPeelCount, NewPeelCount);
- }
-
- return DesiredPeelCount;
-}
-
-// Return the number of iterations we want to peel off.
-void llvm::computePeelCount(Loop *L, unsigned LoopSize,
- TargetTransformInfo::PeelingPreferences &PP,
- unsigned &TripCount, ScalarEvolution &SE,
- unsigned Threshold) {
- assert(LoopSize > 0 && "Zero loop size is not allowed!");
- // Save the PP.PeelCount value set by the target in
- // TTI.getPeelingPreferences or by the flag -unroll-peel-count.
- unsigned TargetPeelCount = PP.PeelCount;
- PP.PeelCount = 0;
- if (!canPeel(L))
- return;
-
- // Only try to peel innermost loops by default.
- // The constraint can be relaxed by the target in TTI.getUnrollingPreferences
- // or by the flag -unroll-allow-loop-nests-peeling.
- if (!PP.AllowLoopNestsPeeling && !L->isInnermost())
- return;
-
- // If the user provided a peel count, use that.
- bool UserPeelCount = UnrollForcePeelCount.getNumOccurrences() > 0;
- if (UserPeelCount) {
- LLVM_DEBUG(dbgs() << "Force-peeling first " << UnrollForcePeelCount
- << " iterations.\n");
- PP.PeelCount = UnrollForcePeelCount;
- PP.PeelProfiledIterations = true;
- return;
- }
-
- // Skip peeling if it's disabled.
- if (!PP.AllowPeeling)
- return;
-
- unsigned AlreadyPeeled = 0;
- if (auto Peeled = getOptionalIntLoopAttribute(L, PeeledCountMetaData))
- AlreadyPeeled = *Peeled;
- // Stop if we already peeled off the maximum number of iterations.
- if (AlreadyPeeled >= UnrollPeelMaxCount)
- return;
-
- // Here we try to get rid of Phis which become invariants after 1, 2, ..., N
- // iterations of the loop. For this we compute the number for iterations after
- // which every Phi is guaranteed to become an invariant, and try to peel the
- // maximum number of iterations among these values, thus turning all those
- // Phis into invariants.
- // First, check that we can peel at least one iteration.
- if (2 * LoopSize <= Threshold && UnrollPeelMaxCount > 0) {
- // Store the pre-calculated values here.
- SmallDenseMap<PHINode *, unsigned> IterationsToInvariance;
- // Now go through all Phis to calculate their the number of iterations they
- // need to become invariants.
- // Start the max computation with the UP.PeelCount value set by the target
- // in TTI.getUnrollingPreferences or by the flag -unroll-peel-count.
- unsigned DesiredPeelCount = TargetPeelCount;
- BasicBlock *BackEdge = L->getLoopLatch();
- assert(BackEdge && "Loop is not in simplified form?");
- for (auto BI = L->getHeader()->begin(); isa<PHINode>(&*BI); ++BI) {
- PHINode *Phi = cast<PHINode>(&*BI);
- unsigned ToInvariance = calculateIterationsToInvariance(
- Phi, L, BackEdge, IterationsToInvariance);
- if (ToInvariance != InfiniteIterationsToInvariance)
- DesiredPeelCount = std::max(DesiredPeelCount, ToInvariance);
- }
-
- // Pay respect to limitations implied by loop size and the max peel count.
- unsigned MaxPeelCount = UnrollPeelMaxCount;
- MaxPeelCount = std::min(MaxPeelCount, Threshold / LoopSize - 1);
-
- DesiredPeelCount = std::max(DesiredPeelCount,
- countToEliminateCompares(*L, MaxPeelCount, SE));
-
- if (DesiredPeelCount > 0) {
- DesiredPeelCount = std::min(DesiredPeelCount, MaxPeelCount);
- // Consider max peel count limitation.
- assert(DesiredPeelCount > 0 && "Wrong loop size estimation?");
- if (DesiredPeelCount + AlreadyPeeled <= UnrollPeelMaxCount) {
- LLVM_DEBUG(dbgs() << "Peel " << DesiredPeelCount
- << " iteration(s) to turn"
- << " some Phis into invariants.\n");
- PP.PeelCount = DesiredPeelCount;
- PP.PeelProfiledIterations = false;
- return;
- }
- }
- }
-
- // Bail if we know the statically calculated trip count.
- // In this case we rather prefer partial unrolling.
- if (TripCount)
- return;
-
- // Do not apply profile base peeling if it is disabled.
- if (!PP.PeelProfiledIterations)
- return;
- // If we don't know the trip count, but have reason to believe the average
- // trip count is low, peeling should be beneficial, since we will usually
- // hit the peeled section.
- // We only do this in the presence of profile information, since otherwise
- // our estimates of the trip count are not reliable enough.
- if (L->getHeader()->getParent()->hasProfileData()) {
- Optional<unsigned> PeelCount = getLoopEstimatedTripCount(L);
- if (!PeelCount)
- return;
-
- LLVM_DEBUG(dbgs() << "Profile-based estimated trip count is " << *PeelCount
- << "\n");
-
- if (*PeelCount) {
- if ((*PeelCount + AlreadyPeeled <= UnrollPeelMaxCount) &&
- (LoopSize * (*PeelCount + 1) <= Threshold)) {
- LLVM_DEBUG(dbgs() << "Peeling first " << *PeelCount
- << " iterations.\n");
- PP.PeelCount = *PeelCount;
- return;
- }
- LLVM_DEBUG(dbgs() << "Requested peel count: " << *PeelCount << "\n");
- LLVM_DEBUG(dbgs() << "Already peel count: " << AlreadyPeeled << "\n");
- LLVM_DEBUG(dbgs() << "Max peel count: " << UnrollPeelMaxCount << "\n");
- LLVM_DEBUG(dbgs() << "Peel cost: " << LoopSize * (*PeelCount + 1)
- << "\n");
- LLVM_DEBUG(dbgs() << "Max peel cost: " << Threshold << "\n");
- }
- }
-}
-
-/// Update the branch weights of the latch of a peeled-off loop
-/// iteration.
-/// This sets the branch weights for the latch of the recently peeled off loop
-/// iteration correctly.
-/// Let F is a weight of the edge from latch to header.
-/// Let E is a weight of the edge from latch to exit.
-/// F/(F+E) is a probability to go to loop and E/(F+E) is a probability to
-/// go to exit.
-/// Then, Estimated TripCount = F / E.
-/// For I-th (counting from 0) peeled off iteration we set the the weights for
-/// the peeled latch as (TC - I, 1). It gives us reasonable distribution,
-/// The probability to go to exit 1/(TC-I) increases. At the same time
-/// the estimated trip count of remaining loop reduces by I.
-/// To avoid dealing with division rounding we can just multiple both part
-/// of weights to E and use weight as (F - I * E, E).
-///
-/// \param Header The copy of the header block that belongs to next iteration.
-/// \param LatchBR The copy of the latch branch that belongs to this iteration.
-/// \param[in,out] FallThroughWeight The weight of the edge from latch to
-/// header before peeling (in) and after peeled off one iteration (out).
-static void updateBranchWeights(BasicBlock *Header, BranchInst *LatchBR,
- uint64_t ExitWeight,
- uint64_t &FallThroughWeight) {
- // FallThroughWeight is 0 means that there is no branch weights on original
- // latch block or estimated trip count is zero.
- if (!FallThroughWeight)
- return;
-
- unsigned HeaderIdx = (LatchBR->getSuccessor(0) == Header ? 0 : 1);
- MDBuilder MDB(LatchBR->getContext());
- MDNode *WeightNode =
- HeaderIdx ? MDB.createBranchWeights(ExitWeight, FallThroughWeight)
- : MDB.createBranchWeights(FallThroughWeight, ExitWeight);
- LatchBR->setMetadata(LLVMContext::MD_prof, WeightNode);
- FallThroughWeight =
- FallThroughWeight > ExitWeight ? FallThroughWeight - ExitWeight : 1;
-}
-
-/// Initialize the weights.
-///
-/// \param Header The header block.
-/// \param LatchBR The latch branch.
-/// \param[out] ExitWeight The weight of the edge from Latch to Exit.
-/// \param[out] FallThroughWeight The weight of the edge from Latch to Header.
-static void initBranchWeights(BasicBlock *Header, BranchInst *LatchBR,
- uint64_t &ExitWeight,
- uint64_t &FallThroughWeight) {
- uint64_t TrueWeight, FalseWeight;
- if (!LatchBR->extractProfMetadata(TrueWeight, FalseWeight))
- return;
- unsigned HeaderIdx = LatchBR->getSuccessor(0) == Header ? 0 : 1;
- ExitWeight = HeaderIdx ? TrueWeight : FalseWeight;
- FallThroughWeight = HeaderIdx ? FalseWeight : TrueWeight;
-}
-
-/// Update the weights of original Latch block after peeling off all iterations.
-///
-/// \param Header The header block.
-/// \param LatchBR The latch branch.
-/// \param ExitWeight The weight of the edge from Latch to Exit.
-/// \param FallThroughWeight The weight of the edge from Latch to Header.
-static void fixupBranchWeights(BasicBlock *Header, BranchInst *LatchBR,
- uint64_t ExitWeight,
- uint64_t FallThroughWeight) {
- // FallThroughWeight is 0 means that there is no branch weights on original
- // latch block or estimated trip count is zero.
- if (!FallThroughWeight)
- return;
-
- // Sets the branch weights on the loop exit.
- MDBuilder MDB(LatchBR->getContext());
- unsigned HeaderIdx = LatchBR->getSuccessor(0) == Header ? 0 : 1;
- MDNode *WeightNode =
- HeaderIdx ? MDB.createBranchWeights(ExitWeight, FallThroughWeight)
- : MDB.createBranchWeights(FallThroughWeight, ExitWeight);
- LatchBR->setMetadata(LLVMContext::MD_prof, WeightNode);
-}
-
-/// Clones the body of the loop L, putting it between \p InsertTop and \p
-/// InsertBot.
-/// \param IterNumber The serial number of the iteration currently being
-/// peeled off.
-/// \param ExitEdges The exit edges of the original loop.
-/// \param[out] NewBlocks A list of the blocks in the newly created clone
-/// \param[out] VMap The value map between the loop and the new clone.
-/// \param LoopBlocks A helper for DFS-traversal of the loop.
-/// \param LVMap A value-map that maps instructions from the original loop to
-/// instructions in the last peeled-off iteration.
-static void cloneLoopBlocks(
- Loop *L, unsigned IterNumber, BasicBlock *InsertTop, BasicBlock *InsertBot,
- SmallVectorImpl<std::pair<BasicBlock *, BasicBlock *>> &ExitEdges,
- SmallVectorImpl<BasicBlock *> &NewBlocks, LoopBlocksDFS &LoopBlocks,
- ValueToValueMapTy &VMap, ValueToValueMapTy &LVMap, DominatorTree *DT,
- LoopInfo *LI, ArrayRef<MDNode *> LoopLocalNoAliasDeclScopes) {
- BasicBlock *Header = L->getHeader();
- BasicBlock *Latch = L->getLoopLatch();
- BasicBlock *PreHeader = L->getLoopPreheader();
-
- Function *F = Header->getParent();
- LoopBlocksDFS::RPOIterator BlockBegin = LoopBlocks.beginRPO();
- LoopBlocksDFS::RPOIterator BlockEnd = LoopBlocks.endRPO();
- Loop *ParentLoop = L->getParentLoop();
-
- // For each block in the original loop, create a new copy,
- // and update the value map with the newly created values.
- for (LoopBlocksDFS::RPOIterator BB = BlockBegin; BB != BlockEnd; ++BB) {
- BasicBlock *NewBB = CloneBasicBlock(*BB, VMap, ".peel", F);
- NewBlocks.push_back(NewBB);
-
- // If an original block is an immediate child of the loop L, its copy
- // is a child of a ParentLoop after peeling. If a block is a child of
- // a nested loop, it is handled in the cloneLoop() call below.
- if (ParentLoop && LI->getLoopFor(*BB) == L)
- ParentLoop->addBasicBlockToLoop(NewBB, *LI);
-
- VMap[*BB] = NewBB;
-
- // If dominator tree is available, insert nodes to represent cloned blocks.
- if (DT) {
- if (Header == *BB)
- DT->addNewBlock(NewBB, InsertTop);
- else {
- DomTreeNode *IDom = DT->getNode(*BB)->getIDom();
- // VMap must contain entry for IDom, as the iteration order is RPO.
- DT->addNewBlock(NewBB, cast<BasicBlock>(VMap[IDom->getBlock()]));
- }
- }
- }
-
- {
- // Identify what other metadata depends on the cloned version. After
- // cloning, replace the metadata with the corrected version for both
- // memory instructions and noalias intrinsics.
- std::string Ext = (Twine("Peel") + Twine(IterNumber)).str();
- cloneAndAdaptNoAliasScopes(LoopLocalNoAliasDeclScopes, NewBlocks,
- Header->getContext(), Ext);
- }
-
- // Recursively create the new Loop objects for nested loops, if any,
- // to preserve LoopInfo.
- for (Loop *ChildLoop : *L) {
- cloneLoop(ChildLoop, ParentLoop, VMap, LI, nullptr);
- }
-
- // Hook-up the control flow for the newly inserted blocks.
- // The new header is hooked up directly to the "top", which is either
- // the original loop preheader (for the first iteration) or the previous
- // iteration's exiting block (for every other iteration)
- InsertTop->getTerminator()->setSuccessor(0, cast<BasicBlock>(VMap[Header]));
-
- // Similarly, for the latch:
- // The original exiting edge is still hooked up to the loop exit.
- // The backedge now goes to the "bottom", which is either the loop's real
- // header (for the last peeled iteration) or the copied header of the next
- // iteration (for every other iteration)
- BasicBlock *NewLatch = cast<BasicBlock>(VMap[Latch]);
- BranchInst *LatchBR = cast<BranchInst>(NewLatch->getTerminator());
- for (unsigned idx = 0, e = LatchBR->getNumSuccessors(); idx < e; ++idx)
- if (LatchBR->getSuccessor(idx) == Header) {
- LatchBR->setSuccessor(idx, InsertBot);
- break;
- }
- if (DT)
- DT->changeImmediateDominator(InsertBot, NewLatch);
-
- // The new copy of the loop body starts with a bunch of PHI nodes
- // that pick an incoming value from either the preheader, or the previous
- // loop iteration. Since this copy is no longer part of the loop, we
- // resolve this statically:
- // For the first iteration, we use the value from the preheader directly.
- // For any other iteration, we replace the phi with the value generated by
- // the immediately preceding clone of the loop body (which represents
- // the previous iteration).
- for (BasicBlock::iterator I = Header->begin(); isa<PHINode>(I); ++I) {
- PHINode *NewPHI = cast<PHINode>(VMap[&*I]);
- if (IterNumber == 0) {
- VMap[&*I] = NewPHI->getIncomingValueForBlock(PreHeader);
- } else {
- Value *LatchVal = NewPHI->getIncomingValueForBlock(Latch);
- Instruction *LatchInst = dyn_cast<Instruction>(LatchVal);
- if (LatchInst && L->contains(LatchInst))
- VMap[&*I] = LVMap[LatchInst];
- else
- VMap[&*I] = LatchVal;
- }
- cast<BasicBlock>(VMap[Header])->getInstList().erase(NewPHI);
- }
-
- // Fix up the outgoing values - we need to add a value for the iteration
- // we've just created. Note that this must happen *after* the incoming
- // values are adjusted, since the value going out of the latch may also be
- // a value coming into the header.
- for (auto Edge : ExitEdges)
- for (PHINode &PHI : Edge.second->phis()) {
- Value *LatchVal = PHI.getIncomingValueForBlock(Edge.first);
- Instruction *LatchInst = dyn_cast<Instruction>(LatchVal);
- if (LatchInst && L->contains(LatchInst))
- LatchVal = VMap[LatchVal];
- PHI.addIncoming(LatchVal, cast<BasicBlock>(VMap[Edge.first]));
- }
-
- // LastValueMap is updated with the values for the current loop
- // which are used the next time this function is called.
- for (auto KV : VMap)
- LVMap[KV.first] = KV.second;
-}
-
-TargetTransformInfo::PeelingPreferences llvm::gatherPeelingPreferences(
- Loop *L, ScalarEvolution &SE, const TargetTransformInfo &TTI,
- Optional<bool> UserAllowPeeling,
- Optional<bool> UserAllowProfileBasedPeeling, bool UnrollingSpecficValues) {
- TargetTransformInfo::PeelingPreferences PP;
-
- // Set the default values.
- PP.PeelCount = 0;
- PP.AllowPeeling = true;
- PP.AllowLoopNestsPeeling = false;
- PP.PeelProfiledIterations = true;
-
- // Get the target specifc values.
- TTI.getPeelingPreferences(L, SE, PP);
-
- // User specified values using cl::opt.
- if (UnrollingSpecficValues) {
- if (UnrollPeelCount.getNumOccurrences() > 0)
- PP.PeelCount = UnrollPeelCount;
- if (UnrollAllowPeeling.getNumOccurrences() > 0)
- PP.AllowPeeling = UnrollAllowPeeling;
- if (UnrollAllowLoopNestsPeeling.getNumOccurrences() > 0)
- PP.AllowLoopNestsPeeling = UnrollAllowLoopNestsPeeling;
- }
-
- // User specifed values provided by argument.
- if (UserAllowPeeling.hasValue())
- PP.AllowPeeling = *UserAllowPeeling;
- if (UserAllowProfileBasedPeeling.hasValue())
- PP.PeelProfiledIterations = *UserAllowProfileBasedPeeling;
-
- return PP;
-}
-
-/// Peel off the first \p PeelCount iterations of loop \p L.
-///
-/// Note that this does not peel them off as a single straight-line block.
-/// Rather, each iteration is peeled off separately, and needs to check the
-/// exit condition.
-/// For loops that dynamically execute \p PeelCount iterations or less
-/// this provides a benefit, since the peeled off iterations, which account
-/// for the bulk of dynamic execution, can be further simplified by scalar
-/// optimizations.
-bool llvm::peelLoop(Loop *L, unsigned PeelCount, LoopInfo *LI,
- ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC,
- bool PreserveLCSSA) {
- assert(PeelCount > 0 && "Attempt to peel out zero iterations?");
- assert(canPeel(L) && "Attempt to peel a loop which is not peelable?");
-
- LoopBlocksDFS LoopBlocks(L);
- LoopBlocks.perform(LI);
-
- BasicBlock *Header = L->getHeader();
- BasicBlock *PreHeader = L->getLoopPreheader();
- BasicBlock *Latch = L->getLoopLatch();
- SmallVector<std::pair<BasicBlock *, BasicBlock *>, 4> ExitEdges;
- L->getExitEdges(ExitEdges);
-
- DenseMap<BasicBlock *, BasicBlock *> ExitIDom;
- if (DT) {
- // We'd like to determine the idom of exit block after peeling one
- // iteration.
- // Let Exit is exit block.
- // Let ExitingSet - is a set of predecessors of Exit block. They are exiting
- // blocks.
- // Let Latch' and ExitingSet' are copies after a peeling.
- // We'd like to find an idom'(Exit) - idom of Exit after peeling.
- // It is an evident that idom'(Exit) will be the nearest common dominator
- // of ExitingSet and ExitingSet'.
- // idom(Exit) is a nearest common dominator of ExitingSet.
- // idom(Exit)' is a nearest common dominator of ExitingSet'.
- // Taking into account that we have a single Latch, Latch' will dominate
- // Header and idom(Exit).
- // So the idom'(Exit) is nearest common dominator of idom(Exit)' and Latch'.
- // All these basic blocks are in the same loop, so what we find is
- // (nearest common dominator of idom(Exit) and Latch)'.
- // In the loop below we remember nearest common dominator of idom(Exit) and
- // Latch to update idom of Exit later.
- assert(L->hasDedicatedExits() && "No dedicated exits?");
- for (auto Edge : ExitEdges) {
- if (ExitIDom.count(Edge.second))
- continue;
- BasicBlock *BB = DT->findNearestCommonDominator(
- DT->getNode(Edge.second)->getIDom()->getBlock(), Latch);
- assert(L->contains(BB) && "IDom is not in a loop");
- ExitIDom[Edge.second] = BB;
- }
- }
-
- Function *F = Header->getParent();
-
- // Set up all the necessary basic blocks. It is convenient to split the
- // preheader into 3 parts - two blocks to anchor the peeled copy of the loop
- // body, and a new preheader for the "real" loop.
-
- // Peeling the first iteration transforms.
- //
- // PreHeader:
- // ...
- // Header:
- // LoopBody
- // If (cond) goto Header
- // Exit:
- //
- // into
- //
- // InsertTop:
- // LoopBody
- // If (!cond) goto Exit
- // InsertBot:
- // NewPreHeader:
- // ...
- // Header:
- // LoopBody
- // If (cond) goto Header
- // Exit:
- //
- // Each following iteration will split the current bottom anchor in two,
- // and put the new copy of the loop body between these two blocks. That is,
- // after peeling another iteration from the example above, we'll split
- // InsertBot, and get:
- //
- // InsertTop:
- // LoopBody
- // If (!cond) goto Exit
- // InsertBot:
- // LoopBody
- // If (!cond) goto Exit
- // InsertBot.next:
- // NewPreHeader:
- // ...
- // Header:
- // LoopBody
- // If (cond) goto Header
- // Exit:
-
- BasicBlock *InsertTop = SplitEdge(PreHeader, Header, DT, LI);
- BasicBlock *InsertBot =
- SplitBlock(InsertTop, InsertTop->getTerminator(), DT, LI);
- BasicBlock *NewPreHeader =
- SplitBlock(InsertBot, InsertBot->getTerminator(), DT, LI);
-
- InsertTop->setName(Header->getName() + ".peel.begin");
- InsertBot->setName(Header->getName() + ".peel.next");
- NewPreHeader->setName(PreHeader->getName() + ".peel.newph");
-
- ValueToValueMapTy LVMap;
-
- // If we have branch weight information, we'll want to update it for the
- // newly created branches.
- BranchInst *LatchBR =
- cast<BranchInst>(cast<BasicBlock>(Latch)->getTerminator());
- uint64_t ExitWeight = 0, FallThroughWeight = 0;
- initBranchWeights(Header, LatchBR, ExitWeight, FallThroughWeight);
-
- // Identify what noalias metadata is inside the loop: if it is inside the
- // loop, the associated metadata must be cloned for each iteration.
- SmallVector<MDNode *, 6> LoopLocalNoAliasDeclScopes;
- identifyNoAliasScopesToClone(L->getBlocks(), LoopLocalNoAliasDeclScopes);
-
- // For each peeled-off iteration, make a copy of the loop.
- for (unsigned Iter = 0; Iter < PeelCount; ++Iter) {
- SmallVector<BasicBlock *, 8> NewBlocks;
- ValueToValueMapTy VMap;
-
- cloneLoopBlocks(L, Iter, InsertTop, InsertBot, ExitEdges, NewBlocks,
- LoopBlocks, VMap, LVMap, DT, LI,
- LoopLocalNoAliasDeclScopes);
-
- // Remap to use values from the current iteration instead of the
- // previous one.
- remapInstructionsInBlocks(NewBlocks, VMap);
-
- if (DT) {
- // Latches of the cloned loops dominate over the loop exit, so idom of the
- // latter is the first cloned loop body, as original PreHeader dominates
- // the original loop body.
- if (Iter == 0)
- for (auto Exit : ExitIDom)
- DT->changeImmediateDominator(Exit.first,
- cast<BasicBlock>(LVMap[Exit.second]));
-#ifdef EXPENSIVE_CHECKS
- assert(DT->verify(DominatorTree::VerificationLevel::Fast));
-#endif
- }
-
- auto *LatchBRCopy = cast<BranchInst>(VMap[LatchBR]);
- updateBranchWeights(InsertBot, LatchBRCopy, ExitWeight, FallThroughWeight);
- // Remove Loop metadata from the latch branch instruction
- // because it is not the Loop's latch branch anymore.
- LatchBRCopy->setMetadata(LLVMContext::MD_loop, nullptr);
-
- InsertTop = InsertBot;
- InsertBot = SplitBlock(InsertBot, InsertBot->getTerminator(), DT, LI);
- InsertBot->setName(Header->getName() + ".peel.next");
-
- F->getBasicBlockList().splice(InsertTop->getIterator(),
- F->getBasicBlockList(),
- NewBlocks[0]->getIterator(), F->end());
- }
-
- // Now adjust the phi nodes in the loop header to get their initial values
- // from the last peeled-off iteration instead of the preheader.
- for (BasicBlock::iterator I = Header->begin(); isa<PHINode>(I); ++I) {
- PHINode *PHI = cast<PHINode>(I);
- Value *NewVal = PHI->getIncomingValueForBlock(Latch);
- Instruction *LatchInst = dyn_cast<Instruction>(NewVal);
- if (LatchInst && L->contains(LatchInst))
- NewVal = LVMap[LatchInst];
-
- PHI->setIncomingValueForBlock(NewPreHeader, NewVal);
- }
-
- fixupBranchWeights(Header, LatchBR, ExitWeight, FallThroughWeight);
-
- // Update Metadata for count of peeled off iterations.
- unsigned AlreadyPeeled = 0;
- if (auto Peeled = getOptionalIntLoopAttribute(L, PeeledCountMetaData))
- AlreadyPeeled = *Peeled;
- addStringMetadataToLoop(L, PeeledCountMetaData, AlreadyPeeled + PeelCount);
-
- if (Loop *ParentLoop = L->getParentLoop())
- L = ParentLoop;
-
- // We modified the loop, update SE.
- SE->forgetTopmostLoop(L);
-
- // Finally DomtTree must be correct.
- assert(DT->verify(DominatorTree::VerificationLevel::Fast));
-
- // FIXME: Incrementally update loop-simplify
- simplifyLoop(L, DT, LI, SE, AC, nullptr, PreserveLCSSA);
-
- NumPeeled++;
-
- return true;
-}
+//===- LoopPeel.cpp -------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Loop Peeling Utilities.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Utils/LoopPeel.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/LoopIterator.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/MDBuilder.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/PatternMatch.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Transforms/Utils/LoopSimplify.h"
+#include "llvm/Transforms/Utils/LoopUtils.h"
+#include "llvm/Transforms/Utils/UnrollLoop.h"
+#include "llvm/Transforms/Utils/ValueMapper.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <limits>
+
+using namespace llvm;
+using namespace llvm::PatternMatch;
+
+#define DEBUG_TYPE "loop-peel"
+
+STATISTIC(NumPeeled, "Number of loops peeled");
+
+static cl::opt<unsigned> UnrollPeelCount(
+ "unroll-peel-count", cl::Hidden,
+ cl::desc("Set the unroll peeling count, for testing purposes"));
+
+static cl::opt<bool>
+ UnrollAllowPeeling("unroll-allow-peeling", cl::init(true), cl::Hidden,
+ cl::desc("Allows loops to be peeled when the dynamic "
+ "trip count is known to be low."));
+
+static cl::opt<bool>
+ UnrollAllowLoopNestsPeeling("unroll-allow-loop-nests-peeling",
+ cl::init(false), cl::Hidden,
+ cl::desc("Allows loop nests to be peeled."));
+
+static cl::opt<unsigned> UnrollPeelMaxCount(
+ "unroll-peel-max-count", cl::init(7), cl::Hidden,
+ cl::desc("Max average trip count which will cause loop peeling."));
+
+static cl::opt<unsigned> UnrollForcePeelCount(
+ "unroll-force-peel-count", cl::init(0), cl::Hidden,
+ cl::desc("Force a peel count regardless of profiling information."));
+
+static cl::opt<bool> UnrollPeelMultiDeoptExit(
+ "unroll-peel-multi-deopt-exit", cl::init(true), cl::Hidden,
+ cl::desc("Allow peeling of loops with multiple deopt exits."));
+
+static const char *PeeledCountMetaData = "llvm.loop.peeled.count";
+
+// Designates that a Phi is estimated to become invariant after an "infinite"
+// number of loop iterations (i.e. only may become an invariant if the loop is
+// fully unrolled).
+static const unsigned InfiniteIterationsToInvariance =
+ std::numeric_limits<unsigned>::max();
+
+// Check whether we are capable of peeling this loop.
+bool llvm::canPeel(Loop *L) {
+ // Make sure the loop is in simplified form
+ if (!L->isLoopSimplifyForm())
+ return false;
+
+ if (UnrollPeelMultiDeoptExit) {
+ SmallVector<BasicBlock *, 4> Exits;
+ L->getUniqueNonLatchExitBlocks(Exits);
+
+ if (!Exits.empty()) {
+ // Latch's terminator is a conditional branch, Latch is exiting and
+ // all non Latch exits ends up with deoptimize.
+ const BasicBlock *Latch = L->getLoopLatch();
+ const BranchInst *T = dyn_cast<BranchInst>(Latch->getTerminator());
+ return T && T->isConditional() && L->isLoopExiting(Latch) &&
+ all_of(Exits, [](const BasicBlock *BB) {
+ return BB->getTerminatingDeoptimizeCall();
+ });
+ }
+ }
+
+ // Only peel loops that contain a single exit
+ if (!L->getExitingBlock() || !L->getUniqueExitBlock())
+ return false;
+
+ // Don't try to peel loops where the latch is not the exiting block.
+ // This can be an indication of two different things:
+ // 1) The loop is not rotated.
+ // 2) The loop contains irreducible control flow that involves the latch.
+ const BasicBlock *Latch = L->getLoopLatch();
+ if (Latch != L->getExitingBlock())
+ return false;
+
+ // Peeling is only supported if the latch is a branch.
+ if (!isa<BranchInst>(Latch->getTerminator()))
+ return false;
+
+ return true;
+}
+
+// This function calculates the number of iterations after which the given Phi
+// becomes an invariant. The pre-calculated values are memorized in the map. The
+// function (shortcut is I) is calculated according to the following definition:
+// Given %x = phi <Inputs from above the loop>, ..., [%y, %back.edge].
+// If %y is a loop invariant, then I(%x) = 1.
+// If %y is a Phi from the loop header, I(%x) = I(%y) + 1.
+// Otherwise, I(%x) is infinite.
+// TODO: Actually if %y is an expression that depends only on Phi %z and some
+// loop invariants, we can estimate I(%x) = I(%z) + 1. The example
+// looks like:
+// %x = phi(0, %a), <-- becomes invariant starting from 3rd iteration.
+// %y = phi(0, 5),
+// %a = %y + 1.
+static unsigned calculateIterationsToInvariance(
+ PHINode *Phi, Loop *L, BasicBlock *BackEdge,
+ SmallDenseMap<PHINode *, unsigned> &IterationsToInvariance) {
+ assert(Phi->getParent() == L->getHeader() &&
+ "Non-loop Phi should not be checked for turning into invariant.");
+ assert(BackEdge == L->getLoopLatch() && "Wrong latch?");
+ // If we already know the answer, take it from the map.
+ auto I = IterationsToInvariance.find(Phi);
+ if (I != IterationsToInvariance.end())
+ return I->second;
+
+ // Otherwise we need to analyze the input from the back edge.
+ Value *Input = Phi->getIncomingValueForBlock(BackEdge);
+ // Place infinity to map to avoid infinite recursion for cycled Phis. Such
+ // cycles can never stop on an invariant.
+ IterationsToInvariance[Phi] = InfiniteIterationsToInvariance;
+ unsigned ToInvariance = InfiniteIterationsToInvariance;
+
+ if (L->isLoopInvariant(Input))
+ ToInvariance = 1u;
+ else if (PHINode *IncPhi = dyn_cast<PHINode>(Input)) {
+ // Only consider Phis in header block.
+ if (IncPhi->getParent() != L->getHeader())
+ return InfiniteIterationsToInvariance;
+ // If the input becomes an invariant after X iterations, then our Phi
+ // becomes an invariant after X + 1 iterations.
+ unsigned InputToInvariance = calculateIterationsToInvariance(
+ IncPhi, L, BackEdge, IterationsToInvariance);
+ if (InputToInvariance != InfiniteIterationsToInvariance)
+ ToInvariance = InputToInvariance + 1u;
+ }
+
+ // If we found that this Phi lies in an invariant chain, update the map.
+ if (ToInvariance != InfiniteIterationsToInvariance)
+ IterationsToInvariance[Phi] = ToInvariance;
+ return ToInvariance;
+}
+
+// Return the number of iterations to peel off that make conditions in the
+// body true/false. For example, if we peel 2 iterations off the loop below,
+// the condition i < 2 can be evaluated at compile time.
+// for (i = 0; i < n; i++)
+// if (i < 2)
+// ..
+// else
+// ..
+// }
+static unsigned countToEliminateCompares(Loop &L, unsigned MaxPeelCount,
+ ScalarEvolution &SE) {
+ assert(L.isLoopSimplifyForm() && "Loop needs to be in loop simplify form");
+ unsigned DesiredPeelCount = 0;
+
+ for (auto *BB : L.blocks()) {
+ auto *BI = dyn_cast<BranchInst>(BB->getTerminator());
+ if (!BI || BI->isUnconditional())
+ continue;
+
+ // Ignore loop exit condition.
+ if (L.getLoopLatch() == BB)
+ continue;
+
+ Value *Condition = BI->getCondition();
+ Value *LeftVal, *RightVal;
+ CmpInst::Predicate Pred;
+ if (!match(Condition, m_ICmp(Pred, m_Value(LeftVal), m_Value(RightVal))))
+ continue;
+
+ const SCEV *LeftSCEV = SE.getSCEV(LeftVal);
+ const SCEV *RightSCEV = SE.getSCEV(RightVal);
+
+ // Do not consider predicates that are known to be true or false
+ // independently of the loop iteration.
+ if (SE.isKnownPredicate(Pred, LeftSCEV, RightSCEV) ||
+ SE.isKnownPredicate(ICmpInst::getInversePredicate(Pred), LeftSCEV,
+ RightSCEV))
+ continue;
+
+ // Check if we have a condition with one AddRec and one non AddRec
+ // expression. Normalize LeftSCEV to be the AddRec.
+ if (!isa<SCEVAddRecExpr>(LeftSCEV)) {
+ if (isa<SCEVAddRecExpr>(RightSCEV)) {
+ std::swap(LeftSCEV, RightSCEV);
+ Pred = ICmpInst::getSwappedPredicate(Pred);
+ } else
+ continue;
+ }
+
+ const SCEVAddRecExpr *LeftAR = cast<SCEVAddRecExpr>(LeftSCEV);
+
+ // Avoid huge SCEV computations in the loop below, make sure we only
+ // consider AddRecs of the loop we are trying to peel.
+ if (!LeftAR->isAffine() || LeftAR->getLoop() != &L)
+ continue;
+ if (!(ICmpInst::isEquality(Pred) && LeftAR->hasNoSelfWrap()) &&
+ !SE.getMonotonicPredicateType(LeftAR, Pred))
+ continue;
+
+ // Check if extending the current DesiredPeelCount lets us evaluate Pred
+ // or !Pred in the loop body statically.
+ unsigned NewPeelCount = DesiredPeelCount;
+
+ const SCEV *IterVal = LeftAR->evaluateAtIteration(
+ SE.getConstant(LeftSCEV->getType(), NewPeelCount), SE);
+
+ // If the original condition is not known, get the negated predicate
+ // (which holds on the else branch) and check if it is known. This allows
+ // us to peel of iterations that make the original condition false.
+ if (!SE.isKnownPredicate(Pred, IterVal, RightSCEV))
+ Pred = ICmpInst::getInversePredicate(Pred);
+
+ const SCEV *Step = LeftAR->getStepRecurrence(SE);
+ const SCEV *NextIterVal = SE.getAddExpr(IterVal, Step);
+ auto PeelOneMoreIteration = [&IterVal, &NextIterVal, &SE, Step,
+ &NewPeelCount]() {
+ IterVal = NextIterVal;
+ NextIterVal = SE.getAddExpr(IterVal, Step);
+ NewPeelCount++;
+ };
+
+ auto CanPeelOneMoreIteration = [&NewPeelCount, &MaxPeelCount]() {
+ return NewPeelCount < MaxPeelCount;
+ };
+
+ while (CanPeelOneMoreIteration() &&
+ SE.isKnownPredicate(Pred, IterVal, RightSCEV))
+ PeelOneMoreIteration();
+
+ // With *that* peel count, does the predicate !Pred become known in the
+ // first iteration of the loop body after peeling?
+ if (!SE.isKnownPredicate(ICmpInst::getInversePredicate(Pred), IterVal,
+ RightSCEV))
+ continue; // If not, give up.
+
+ // However, for equality comparisons, that isn't always sufficient to
+ // eliminate the comparsion in loop body, we may need to peel one more
+ // iteration. See if that makes !Pred become unknown again.
+ if (ICmpInst::isEquality(Pred) &&
+ !SE.isKnownPredicate(ICmpInst::getInversePredicate(Pred), NextIterVal,
+ RightSCEV) &&
+ !SE.isKnownPredicate(Pred, IterVal, RightSCEV) &&
+ SE.isKnownPredicate(Pred, NextIterVal, RightSCEV)) {
+ if (!CanPeelOneMoreIteration())
+ continue; // Need to peel one more iteration, but can't. Give up.
+ PeelOneMoreIteration(); // Great!
+ }
+
+ DesiredPeelCount = std::max(DesiredPeelCount, NewPeelCount);
+ }
+
+ return DesiredPeelCount;
+}
+
+// Return the number of iterations we want to peel off.
+void llvm::computePeelCount(Loop *L, unsigned LoopSize,
+ TargetTransformInfo::PeelingPreferences &PP,
+ unsigned &TripCount, ScalarEvolution &SE,
+ unsigned Threshold) {
+ assert(LoopSize > 0 && "Zero loop size is not allowed!");
+ // Save the PP.PeelCount value set by the target in
+ // TTI.getPeelingPreferences or by the flag -unroll-peel-count.
+ unsigned TargetPeelCount = PP.PeelCount;
+ PP.PeelCount = 0;
+ if (!canPeel(L))
+ return;
+
+ // Only try to peel innermost loops by default.
+ // The constraint can be relaxed by the target in TTI.getUnrollingPreferences
+ // or by the flag -unroll-allow-loop-nests-peeling.
+ if (!PP.AllowLoopNestsPeeling && !L->isInnermost())
+ return;
+
+ // If the user provided a peel count, use that.
+ bool UserPeelCount = UnrollForcePeelCount.getNumOccurrences() > 0;
+ if (UserPeelCount) {
+ LLVM_DEBUG(dbgs() << "Force-peeling first " << UnrollForcePeelCount
+ << " iterations.\n");
+ PP.PeelCount = UnrollForcePeelCount;
+ PP.PeelProfiledIterations = true;
+ return;
+ }
+
+ // Skip peeling if it's disabled.
+ if (!PP.AllowPeeling)
+ return;
+
+ unsigned AlreadyPeeled = 0;
+ if (auto Peeled = getOptionalIntLoopAttribute(L, PeeledCountMetaData))
+ AlreadyPeeled = *Peeled;
+ // Stop if we already peeled off the maximum number of iterations.
+ if (AlreadyPeeled >= UnrollPeelMaxCount)
+ return;
+
+ // Here we try to get rid of Phis which become invariants after 1, 2, ..., N
+ // iterations of the loop. For this we compute the number for iterations after
+ // which every Phi is guaranteed to become an invariant, and try to peel the
+ // maximum number of iterations among these values, thus turning all those
+ // Phis into invariants.
+ // First, check that we can peel at least one iteration.
+ if (2 * LoopSize <= Threshold && UnrollPeelMaxCount > 0) {
+ // Store the pre-calculated values here.
+ SmallDenseMap<PHINode *, unsigned> IterationsToInvariance;
+ // Now go through all Phis to calculate their the number of iterations they
+ // need to become invariants.
+ // Start the max computation with the UP.PeelCount value set by the target
+ // in TTI.getUnrollingPreferences or by the flag -unroll-peel-count.
+ unsigned DesiredPeelCount = TargetPeelCount;
+ BasicBlock *BackEdge = L->getLoopLatch();
+ assert(BackEdge && "Loop is not in simplified form?");
+ for (auto BI = L->getHeader()->begin(); isa<PHINode>(&*BI); ++BI) {
+ PHINode *Phi = cast<PHINode>(&*BI);
+ unsigned ToInvariance = calculateIterationsToInvariance(
+ Phi, L, BackEdge, IterationsToInvariance);
+ if (ToInvariance != InfiniteIterationsToInvariance)
+ DesiredPeelCount = std::max(DesiredPeelCount, ToInvariance);
+ }
+
+ // Pay respect to limitations implied by loop size and the max peel count.
+ unsigned MaxPeelCount = UnrollPeelMaxCount;
+ MaxPeelCount = std::min(MaxPeelCount, Threshold / LoopSize - 1);
+
+ DesiredPeelCount = std::max(DesiredPeelCount,
+ countToEliminateCompares(*L, MaxPeelCount, SE));
+
+ if (DesiredPeelCount > 0) {
+ DesiredPeelCount = std::min(DesiredPeelCount, MaxPeelCount);
+ // Consider max peel count limitation.
+ assert(DesiredPeelCount > 0 && "Wrong loop size estimation?");
+ if (DesiredPeelCount + AlreadyPeeled <= UnrollPeelMaxCount) {
+ LLVM_DEBUG(dbgs() << "Peel " << DesiredPeelCount
+ << " iteration(s) to turn"
+ << " some Phis into invariants.\n");
+ PP.PeelCount = DesiredPeelCount;
+ PP.PeelProfiledIterations = false;
+ return;
+ }
+ }
+ }
+
+ // Bail if we know the statically calculated trip count.
+ // In this case we rather prefer partial unrolling.
+ if (TripCount)
+ return;
+
+ // Do not apply profile base peeling if it is disabled.
+ if (!PP.PeelProfiledIterations)
+ return;
+ // If we don't know the trip count, but have reason to believe the average
+ // trip count is low, peeling should be beneficial, since we will usually
+ // hit the peeled section.
+ // We only do this in the presence of profile information, since otherwise
+ // our estimates of the trip count are not reliable enough.
+ if (L->getHeader()->getParent()->hasProfileData()) {
+ Optional<unsigned> PeelCount = getLoopEstimatedTripCount(L);
+ if (!PeelCount)
+ return;
+
+ LLVM_DEBUG(dbgs() << "Profile-based estimated trip count is " << *PeelCount
+ << "\n");
+
+ if (*PeelCount) {
+ if ((*PeelCount + AlreadyPeeled <= UnrollPeelMaxCount) &&
+ (LoopSize * (*PeelCount + 1) <= Threshold)) {
+ LLVM_DEBUG(dbgs() << "Peeling first " << *PeelCount
+ << " iterations.\n");
+ PP.PeelCount = *PeelCount;
+ return;
+ }
+ LLVM_DEBUG(dbgs() << "Requested peel count: " << *PeelCount << "\n");
+ LLVM_DEBUG(dbgs() << "Already peel count: " << AlreadyPeeled << "\n");
+ LLVM_DEBUG(dbgs() << "Max peel count: " << UnrollPeelMaxCount << "\n");
+ LLVM_DEBUG(dbgs() << "Peel cost: " << LoopSize * (*PeelCount + 1)
+ << "\n");
+ LLVM_DEBUG(dbgs() << "Max peel cost: " << Threshold << "\n");
+ }
+ }
+}
+
+/// Update the branch weights of the latch of a peeled-off loop
+/// iteration.
+/// This sets the branch weights for the latch of the recently peeled off loop
+/// iteration correctly.
+/// Let F is a weight of the edge from latch to header.
+/// Let E is a weight of the edge from latch to exit.
+/// F/(F+E) is a probability to go to loop and E/(F+E) is a probability to
+/// go to exit.
+/// Then, Estimated TripCount = F / E.
+/// For I-th (counting from 0) peeled off iteration we set the the weights for
+/// the peeled latch as (TC - I, 1). It gives us reasonable distribution,
+/// The probability to go to exit 1/(TC-I) increases. At the same time
+/// the estimated trip count of remaining loop reduces by I.
+/// To avoid dealing with division rounding we can just multiple both part
+/// of weights to E and use weight as (F - I * E, E).
+///
+/// \param Header The copy of the header block that belongs to next iteration.
+/// \param LatchBR The copy of the latch branch that belongs to this iteration.
+/// \param[in,out] FallThroughWeight The weight of the edge from latch to
+/// header before peeling (in) and after peeled off one iteration (out).
+static void updateBranchWeights(BasicBlock *Header, BranchInst *LatchBR,
+ uint64_t ExitWeight,
+ uint64_t &FallThroughWeight) {
+ // FallThroughWeight is 0 means that there is no branch weights on original
+ // latch block or estimated trip count is zero.
+ if (!FallThroughWeight)
+ return;
+
+ unsigned HeaderIdx = (LatchBR->getSuccessor(0) == Header ? 0 : 1);
+ MDBuilder MDB(LatchBR->getContext());
+ MDNode *WeightNode =
+ HeaderIdx ? MDB.createBranchWeights(ExitWeight, FallThroughWeight)
+ : MDB.createBranchWeights(FallThroughWeight, ExitWeight);
+ LatchBR->setMetadata(LLVMContext::MD_prof, WeightNode);
+ FallThroughWeight =
+ FallThroughWeight > ExitWeight ? FallThroughWeight - ExitWeight : 1;
+}
+
+/// Initialize the weights.
+///
+/// \param Header The header block.
+/// \param LatchBR The latch branch.
+/// \param[out] ExitWeight The weight of the edge from Latch to Exit.
+/// \param[out] FallThroughWeight The weight of the edge from Latch to Header.
+static void initBranchWeights(BasicBlock *Header, BranchInst *LatchBR,
+ uint64_t &ExitWeight,
+ uint64_t &FallThroughWeight) {
+ uint64_t TrueWeight, FalseWeight;
+ if (!LatchBR->extractProfMetadata(TrueWeight, FalseWeight))
+ return;
+ unsigned HeaderIdx = LatchBR->getSuccessor(0) == Header ? 0 : 1;
+ ExitWeight = HeaderIdx ? TrueWeight : FalseWeight;
+ FallThroughWeight = HeaderIdx ? FalseWeight : TrueWeight;
+}
+
+/// Update the weights of original Latch block after peeling off all iterations.
+///
+/// \param Header The header block.
+/// \param LatchBR The latch branch.
+/// \param ExitWeight The weight of the edge from Latch to Exit.
+/// \param FallThroughWeight The weight of the edge from Latch to Header.
+static void fixupBranchWeights(BasicBlock *Header, BranchInst *LatchBR,
+ uint64_t ExitWeight,
+ uint64_t FallThroughWeight) {
+ // FallThroughWeight is 0 means that there is no branch weights on original
+ // latch block or estimated trip count is zero.
+ if (!FallThroughWeight)
+ return;
+
+ // Sets the branch weights on the loop exit.
+ MDBuilder MDB(LatchBR->getContext());
+ unsigned HeaderIdx = LatchBR->getSuccessor(0) == Header ? 0 : 1;
+ MDNode *WeightNode =
+ HeaderIdx ? MDB.createBranchWeights(ExitWeight, FallThroughWeight)
+ : MDB.createBranchWeights(FallThroughWeight, ExitWeight);
+ LatchBR->setMetadata(LLVMContext::MD_prof, WeightNode);
+}
+
+/// Clones the body of the loop L, putting it between \p InsertTop and \p
+/// InsertBot.
+/// \param IterNumber The serial number of the iteration currently being
+/// peeled off.
+/// \param ExitEdges The exit edges of the original loop.
+/// \param[out] NewBlocks A list of the blocks in the newly created clone
+/// \param[out] VMap The value map between the loop and the new clone.
+/// \param LoopBlocks A helper for DFS-traversal of the loop.
+/// \param LVMap A value-map that maps instructions from the original loop to
+/// instructions in the last peeled-off iteration.
+static void cloneLoopBlocks(
+ Loop *L, unsigned IterNumber, BasicBlock *InsertTop, BasicBlock *InsertBot,
+ SmallVectorImpl<std::pair<BasicBlock *, BasicBlock *>> &ExitEdges,
+ SmallVectorImpl<BasicBlock *> &NewBlocks, LoopBlocksDFS &LoopBlocks,
+ ValueToValueMapTy &VMap, ValueToValueMapTy &LVMap, DominatorTree *DT,
+ LoopInfo *LI, ArrayRef<MDNode *> LoopLocalNoAliasDeclScopes) {
+ BasicBlock *Header = L->getHeader();
+ BasicBlock *Latch = L->getLoopLatch();
+ BasicBlock *PreHeader = L->getLoopPreheader();
+
+ Function *F = Header->getParent();
+ LoopBlocksDFS::RPOIterator BlockBegin = LoopBlocks.beginRPO();
+ LoopBlocksDFS::RPOIterator BlockEnd = LoopBlocks.endRPO();
+ Loop *ParentLoop = L->getParentLoop();
+
+ // For each block in the original loop, create a new copy,
+ // and update the value map with the newly created values.
+ for (LoopBlocksDFS::RPOIterator BB = BlockBegin; BB != BlockEnd; ++BB) {
+ BasicBlock *NewBB = CloneBasicBlock(*BB, VMap, ".peel", F);
+ NewBlocks.push_back(NewBB);
+
+ // If an original block is an immediate child of the loop L, its copy
+ // is a child of a ParentLoop after peeling. If a block is a child of
+ // a nested loop, it is handled in the cloneLoop() call below.
+ if (ParentLoop && LI->getLoopFor(*BB) == L)
+ ParentLoop->addBasicBlockToLoop(NewBB, *LI);
+
+ VMap[*BB] = NewBB;
+
+ // If dominator tree is available, insert nodes to represent cloned blocks.
+ if (DT) {
+ if (Header == *BB)
+ DT->addNewBlock(NewBB, InsertTop);
+ else {
+ DomTreeNode *IDom = DT->getNode(*BB)->getIDom();
+ // VMap must contain entry for IDom, as the iteration order is RPO.
+ DT->addNewBlock(NewBB, cast<BasicBlock>(VMap[IDom->getBlock()]));
+ }
+ }
+ }
+
+ {
+ // Identify what other metadata depends on the cloned version. After
+ // cloning, replace the metadata with the corrected version for both
+ // memory instructions and noalias intrinsics.
+ std::string Ext = (Twine("Peel") + Twine(IterNumber)).str();
+ cloneAndAdaptNoAliasScopes(LoopLocalNoAliasDeclScopes, NewBlocks,
+ Header->getContext(), Ext);
+ }
+
+ // Recursively create the new Loop objects for nested loops, if any,
+ // to preserve LoopInfo.
+ for (Loop *ChildLoop : *L) {
+ cloneLoop(ChildLoop, ParentLoop, VMap, LI, nullptr);
+ }
+
+ // Hook-up the control flow for the newly inserted blocks.
+ // The new header is hooked up directly to the "top", which is either
+ // the original loop preheader (for the first iteration) or the previous
+ // iteration's exiting block (for every other iteration)
+ InsertTop->getTerminator()->setSuccessor(0, cast<BasicBlock>(VMap[Header]));
+
+ // Similarly, for the latch:
+ // The original exiting edge is still hooked up to the loop exit.
+ // The backedge now goes to the "bottom", which is either the loop's real
+ // header (for the last peeled iteration) or the copied header of the next
+ // iteration (for every other iteration)
+ BasicBlock *NewLatch = cast<BasicBlock>(VMap[Latch]);
+ BranchInst *LatchBR = cast<BranchInst>(NewLatch->getTerminator());
+ for (unsigned idx = 0, e = LatchBR->getNumSuccessors(); idx < e; ++idx)
+ if (LatchBR->getSuccessor(idx) == Header) {
+ LatchBR->setSuccessor(idx, InsertBot);
+ break;
+ }
+ if (DT)
+ DT->changeImmediateDominator(InsertBot, NewLatch);
+
+ // The new copy of the loop body starts with a bunch of PHI nodes
+ // that pick an incoming value from either the preheader, or the previous
+ // loop iteration. Since this copy is no longer part of the loop, we
+ // resolve this statically:
+ // For the first iteration, we use the value from the preheader directly.
+ // For any other iteration, we replace the phi with the value generated by
+ // the immediately preceding clone of the loop body (which represents
+ // the previous iteration).
+ for (BasicBlock::iterator I = Header->begin(); isa<PHINode>(I); ++I) {
+ PHINode *NewPHI = cast<PHINode>(VMap[&*I]);
+ if (IterNumber == 0) {
+ VMap[&*I] = NewPHI->getIncomingValueForBlock(PreHeader);
+ } else {
+ Value *LatchVal = NewPHI->getIncomingValueForBlock(Latch);
+ Instruction *LatchInst = dyn_cast<Instruction>(LatchVal);
+ if (LatchInst && L->contains(LatchInst))
+ VMap[&*I] = LVMap[LatchInst];
+ else
+ VMap[&*I] = LatchVal;
+ }
+ cast<BasicBlock>(VMap[Header])->getInstList().erase(NewPHI);
+ }
+
+ // Fix up the outgoing values - we need to add a value for the iteration
+ // we've just created. Note that this must happen *after* the incoming
+ // values are adjusted, since the value going out of the latch may also be
+ // a value coming into the header.
+ for (auto Edge : ExitEdges)
+ for (PHINode &PHI : Edge.second->phis()) {
+ Value *LatchVal = PHI.getIncomingValueForBlock(Edge.first);
+ Instruction *LatchInst = dyn_cast<Instruction>(LatchVal);
+ if (LatchInst && L->contains(LatchInst))
+ LatchVal = VMap[LatchVal];
+ PHI.addIncoming(LatchVal, cast<BasicBlock>(VMap[Edge.first]));
+ }
+
+ // LastValueMap is updated with the values for the current loop
+ // which are used the next time this function is called.
+ for (auto KV : VMap)
+ LVMap[KV.first] = KV.second;
+}
+
+TargetTransformInfo::PeelingPreferences llvm::gatherPeelingPreferences(
+ Loop *L, ScalarEvolution &SE, const TargetTransformInfo &TTI,
+ Optional<bool> UserAllowPeeling,
+ Optional<bool> UserAllowProfileBasedPeeling, bool UnrollingSpecficValues) {
+ TargetTransformInfo::PeelingPreferences PP;
+
+ // Set the default values.
+ PP.PeelCount = 0;
+ PP.AllowPeeling = true;
+ PP.AllowLoopNestsPeeling = false;
+ PP.PeelProfiledIterations = true;
+
+ // Get the target specifc values.
+ TTI.getPeelingPreferences(L, SE, PP);
+
+ // User specified values using cl::opt.
+ if (UnrollingSpecficValues) {
+ if (UnrollPeelCount.getNumOccurrences() > 0)
+ PP.PeelCount = UnrollPeelCount;
+ if (UnrollAllowPeeling.getNumOccurrences() > 0)
+ PP.AllowPeeling = UnrollAllowPeeling;
+ if (UnrollAllowLoopNestsPeeling.getNumOccurrences() > 0)
+ PP.AllowLoopNestsPeeling = UnrollAllowLoopNestsPeeling;
+ }
+
+ // User specifed values provided by argument.
+ if (UserAllowPeeling.hasValue())
+ PP.AllowPeeling = *UserAllowPeeling;
+ if (UserAllowProfileBasedPeeling.hasValue())
+ PP.PeelProfiledIterations = *UserAllowProfileBasedPeeling;
+
+ return PP;
+}
+
+/// Peel off the first \p PeelCount iterations of loop \p L.
+///
+/// Note that this does not peel them off as a single straight-line block.
+/// Rather, each iteration is peeled off separately, and needs to check the
+/// exit condition.
+/// For loops that dynamically execute \p PeelCount iterations or less
+/// this provides a benefit, since the peeled off iterations, which account
+/// for the bulk of dynamic execution, can be further simplified by scalar
+/// optimizations.
+bool llvm::peelLoop(Loop *L, unsigned PeelCount, LoopInfo *LI,
+ ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC,
+ bool PreserveLCSSA) {
+ assert(PeelCount > 0 && "Attempt to peel out zero iterations?");
+ assert(canPeel(L) && "Attempt to peel a loop which is not peelable?");
+
+ LoopBlocksDFS LoopBlocks(L);
+ LoopBlocks.perform(LI);
+
+ BasicBlock *Header = L->getHeader();
+ BasicBlock *PreHeader = L->getLoopPreheader();
+ BasicBlock *Latch = L->getLoopLatch();
+ SmallVector<std::pair<BasicBlock *, BasicBlock *>, 4> ExitEdges;
+ L->getExitEdges(ExitEdges);
+
+ DenseMap<BasicBlock *, BasicBlock *> ExitIDom;
+ if (DT) {
+ // We'd like to determine the idom of exit block after peeling one
+ // iteration.
+ // Let Exit is exit block.
+ // Let ExitingSet - is a set of predecessors of Exit block. They are exiting
+ // blocks.
+ // Let Latch' and ExitingSet' are copies after a peeling.
+ // We'd like to find an idom'(Exit) - idom of Exit after peeling.
+ // It is an evident that idom'(Exit) will be the nearest common dominator
+ // of ExitingSet and ExitingSet'.
+ // idom(Exit) is a nearest common dominator of ExitingSet.
+ // idom(Exit)' is a nearest common dominator of ExitingSet'.
+ // Taking into account that we have a single Latch, Latch' will dominate
+ // Header and idom(Exit).
+ // So the idom'(Exit) is nearest common dominator of idom(Exit)' and Latch'.
+ // All these basic blocks are in the same loop, so what we find is
+ // (nearest common dominator of idom(Exit) and Latch)'.
+ // In the loop below we remember nearest common dominator of idom(Exit) and
+ // Latch to update idom of Exit later.
+ assert(L->hasDedicatedExits() && "No dedicated exits?");
+ for (auto Edge : ExitEdges) {
+ if (ExitIDom.count(Edge.second))
+ continue;
+ BasicBlock *BB = DT->findNearestCommonDominator(
+ DT->getNode(Edge.second)->getIDom()->getBlock(), Latch);
+ assert(L->contains(BB) && "IDom is not in a loop");
+ ExitIDom[Edge.second] = BB;
+ }
+ }
+
+ Function *F = Header->getParent();
+
+ // Set up all the necessary basic blocks. It is convenient to split the
+ // preheader into 3 parts - two blocks to anchor the peeled copy of the loop
+ // body, and a new preheader for the "real" loop.
+
+ // Peeling the first iteration transforms.
+ //
+ // PreHeader:
+ // ...
+ // Header:
+ // LoopBody
+ // If (cond) goto Header
+ // Exit:
+ //
+ // into
+ //
+ // InsertTop:
+ // LoopBody
+ // If (!cond) goto Exit
+ // InsertBot:
+ // NewPreHeader:
+ // ...
+ // Header:
+ // LoopBody
+ // If (cond) goto Header
+ // Exit:
+ //
+ // Each following iteration will split the current bottom anchor in two,
+ // and put the new copy of the loop body between these two blocks. That is,
+ // after peeling another iteration from the example above, we'll split
+ // InsertBot, and get:
+ //
+ // InsertTop:
+ // LoopBody
+ // If (!cond) goto Exit
+ // InsertBot:
+ // LoopBody
+ // If (!cond) goto Exit
+ // InsertBot.next:
+ // NewPreHeader:
+ // ...
+ // Header:
+ // LoopBody
+ // If (cond) goto Header
+ // Exit:
+
+ BasicBlock *InsertTop = SplitEdge(PreHeader, Header, DT, LI);
+ BasicBlock *InsertBot =
+ SplitBlock(InsertTop, InsertTop->getTerminator(), DT, LI);
+ BasicBlock *NewPreHeader =
+ SplitBlock(InsertBot, InsertBot->getTerminator(), DT, LI);
+
+ InsertTop->setName(Header->getName() + ".peel.begin");
+ InsertBot->setName(Header->getName() + ".peel.next");
+ NewPreHeader->setName(PreHeader->getName() + ".peel.newph");
+
+ ValueToValueMapTy LVMap;
+
+ // If we have branch weight information, we'll want to update it for the
+ // newly created branches.
+ BranchInst *LatchBR =
+ cast<BranchInst>(cast<BasicBlock>(Latch)->getTerminator());
+ uint64_t ExitWeight = 0, FallThroughWeight = 0;
+ initBranchWeights(Header, LatchBR, ExitWeight, FallThroughWeight);
+
+ // Identify what noalias metadata is inside the loop: if it is inside the
+ // loop, the associated metadata must be cloned for each iteration.
+ SmallVector<MDNode *, 6> LoopLocalNoAliasDeclScopes;
+ identifyNoAliasScopesToClone(L->getBlocks(), LoopLocalNoAliasDeclScopes);
+
+ // For each peeled-off iteration, make a copy of the loop.
+ for (unsigned Iter = 0; Iter < PeelCount; ++Iter) {
+ SmallVector<BasicBlock *, 8> NewBlocks;
+ ValueToValueMapTy VMap;
+
+ cloneLoopBlocks(L, Iter, InsertTop, InsertBot, ExitEdges, NewBlocks,
+ LoopBlocks, VMap, LVMap, DT, LI,
+ LoopLocalNoAliasDeclScopes);
+
+ // Remap to use values from the current iteration instead of the
+ // previous one.
+ remapInstructionsInBlocks(NewBlocks, VMap);
+
+ if (DT) {
+ // Latches of the cloned loops dominate over the loop exit, so idom of the
+ // latter is the first cloned loop body, as original PreHeader dominates
+ // the original loop body.
+ if (Iter == 0)
+ for (auto Exit : ExitIDom)
+ DT->changeImmediateDominator(Exit.first,
+ cast<BasicBlock>(LVMap[Exit.second]));
+#ifdef EXPENSIVE_CHECKS
+ assert(DT->verify(DominatorTree::VerificationLevel::Fast));
+#endif
+ }
+
+ auto *LatchBRCopy = cast<BranchInst>(VMap[LatchBR]);
+ updateBranchWeights(InsertBot, LatchBRCopy, ExitWeight, FallThroughWeight);
+ // Remove Loop metadata from the latch branch instruction
+ // because it is not the Loop's latch branch anymore.
+ LatchBRCopy->setMetadata(LLVMContext::MD_loop, nullptr);
+
+ InsertTop = InsertBot;
+ InsertBot = SplitBlock(InsertBot, InsertBot->getTerminator(), DT, LI);
+ InsertBot->setName(Header->getName() + ".peel.next");
+
+ F->getBasicBlockList().splice(InsertTop->getIterator(),
+ F->getBasicBlockList(),
+ NewBlocks[0]->getIterator(), F->end());
+ }
+
+ // Now adjust the phi nodes in the loop header to get their initial values
+ // from the last peeled-off iteration instead of the preheader.
+ for (BasicBlock::iterator I = Header->begin(); isa<PHINode>(I); ++I) {
+ PHINode *PHI = cast<PHINode>(I);
+ Value *NewVal = PHI->getIncomingValueForBlock(Latch);
+ Instruction *LatchInst = dyn_cast<Instruction>(NewVal);
+ if (LatchInst && L->contains(LatchInst))
+ NewVal = LVMap[LatchInst];
+
+ PHI->setIncomingValueForBlock(NewPreHeader, NewVal);
+ }
+
+ fixupBranchWeights(Header, LatchBR, ExitWeight, FallThroughWeight);
+
+ // Update Metadata for count of peeled off iterations.
+ unsigned AlreadyPeeled = 0;
+ if (auto Peeled = getOptionalIntLoopAttribute(L, PeeledCountMetaData))
+ AlreadyPeeled = *Peeled;
+ addStringMetadataToLoop(L, PeeledCountMetaData, AlreadyPeeled + PeelCount);
+
+ if (Loop *ParentLoop = L->getParentLoop())
+ L = ParentLoop;
+
+ // We modified the loop, update SE.
+ SE->forgetTopmostLoop(L);
+
+ // Finally DomtTree must be correct.
+ assert(DT->verify(DominatorTree::VerificationLevel::Fast));
+
+ // FIXME: Incrementally update loop-simplify
+ simplifyLoop(L, DT, LI, SE, AC, nullptr, PreserveLCSSA);
+
+ NumPeeled++;
+
+ return true;
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/LoopRotationUtils.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/LoopRotationUtils.cpp
index bf1f8bea39..b678efdc8d 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/LoopRotationUtils.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/LoopRotationUtils.cpp
@@ -35,7 +35,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
#include "llvm/Transforms/Utils/SSAUpdater.h"
@@ -44,8 +44,8 @@ using namespace llvm;
#define DEBUG_TYPE "loop-rotate"
-STATISTIC(NumNotRotatedDueToHeaderSize,
- "Number of loops not rotated due to the header size");
+STATISTIC(NumNotRotatedDueToHeaderSize,
+ "Number of loops not rotated due to the header size");
STATISTIC(NumRotated, "Number of loops rotated");
static cl::opt<bool>
@@ -66,17 +66,17 @@ class LoopRotate {
const SimplifyQuery &SQ;
bool RotationOnly;
bool IsUtilMode;
- bool PrepareForLTO;
+ bool PrepareForLTO;
public:
LoopRotate(unsigned MaxHeaderSize, LoopInfo *LI,
const TargetTransformInfo *TTI, AssumptionCache *AC,
DominatorTree *DT, ScalarEvolution *SE, MemorySSAUpdater *MSSAU,
- const SimplifyQuery &SQ, bool RotationOnly, bool IsUtilMode,
- bool PrepareForLTO)
+ const SimplifyQuery &SQ, bool RotationOnly, bool IsUtilMode,
+ bool PrepareForLTO)
: MaxHeaderSize(MaxHeaderSize), LI(LI), TTI(TTI), AC(AC), DT(DT), SE(SE),
MSSAU(MSSAU), SQ(SQ), RotationOnly(RotationOnly),
- IsUtilMode(IsUtilMode), PrepareForLTO(PrepareForLTO) {}
+ IsUtilMode(IsUtilMode), PrepareForLTO(PrepareForLTO) {}
bool processLoop(Loop *L);
private:
@@ -304,7 +304,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
CodeMetrics::collectEphemeralValues(L, AC, EphValues);
CodeMetrics Metrics;
- Metrics.analyzeBasicBlock(OrigHeader, *TTI, EphValues, PrepareForLTO);
+ Metrics.analyzeBasicBlock(OrigHeader, *TTI, EphValues, PrepareForLTO);
if (Metrics.notDuplicatable) {
LLVM_DEBUG(
dbgs() << "LoopRotation: NOT rotating - contains non-duplicatable"
@@ -324,14 +324,14 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
<< " instructions, which is more than the threshold ("
<< MaxHeaderSize << " instructions): ";
L->dump());
- ++NumNotRotatedDueToHeaderSize;
+ ++NumNotRotatedDueToHeaderSize;
return Rotated;
}
-
- // When preparing for LTO, avoid rotating loops with calls that could be
- // inlined during the LTO stage.
- if (PrepareForLTO && Metrics.NumInlineCandidates > 0)
- return Rotated;
+
+ // When preparing for LTO, avoid rotating loops with calls that could be
+ // inlined during the LTO stage.
+ if (PrepareForLTO && Metrics.NumInlineCandidates > 0)
+ return Rotated;
}
// Now, this loop is suitable for rotation.
@@ -401,14 +401,14 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
break;
}
- // Remember the local noalias scope declarations in the header. After the
- // rotation, they must be duplicated and the scope must be cloned. This
- // avoids unwanted interaction across iterations.
- SmallVector<NoAliasScopeDeclInst *, 6> NoAliasDeclInstructions;
- for (Instruction &I : *OrigHeader)
- if (auto *Decl = dyn_cast<NoAliasScopeDeclInst>(&I))
- NoAliasDeclInstructions.push_back(Decl);
-
+ // Remember the local noalias scope declarations in the header. After the
+ // rotation, they must be duplicated and the scope must be cloned. This
+ // avoids unwanted interaction across iterations.
+ SmallVector<NoAliasScopeDeclInst *, 6> NoAliasDeclInstructions;
+ for (Instruction &I : *OrigHeader)
+ if (auto *Decl = dyn_cast<NoAliasScopeDeclInst>(&I))
+ NoAliasDeclInstructions.push_back(Decl);
+
while (I != E) {
Instruction *Inst = &*I++;
@@ -469,69 +469,69 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
}
}
- if (!NoAliasDeclInstructions.empty()) {
- // There are noalias scope declarations:
- // (general):
- // Original: OrigPre { OrigHeader NewHeader ... Latch }
- // after: (OrigPre+OrigHeader') { NewHeader ... Latch OrigHeader }
- //
- // with D: llvm.experimental.noalias.scope.decl,
- // U: !noalias or !alias.scope depending on D
- // ... { D U1 U2 } can transform into:
- // (0) : ... { D U1 U2 } // no relevant rotation for this part
- // (1) : ... D' { U1 U2 D } // D is part of OrigHeader
- // (2) : ... D' U1' { U2 D U1 } // D, U1 are part of OrigHeader
- //
- // We now want to transform:
- // (1) -> : ... D' { D U1 U2 D'' }
- // (2) -> : ... D' U1' { D U2 D'' U1'' }
- // D: original llvm.experimental.noalias.scope.decl
- // D', U1': duplicate with replaced scopes
- // D'', U1'': different duplicate with replaced scopes
- // This ensures a safe fallback to 'may_alias' introduced by the rotate,
- // as U1'' and U1' scopes will not be compatible wrt to the local restrict
-
- // Clone the llvm.experimental.noalias.decl again for the NewHeader.
- Instruction *NewHeaderInsertionPoint = &(*NewHeader->getFirstNonPHI());
- for (NoAliasScopeDeclInst *NAD : NoAliasDeclInstructions) {
- LLVM_DEBUG(dbgs() << " Cloning llvm.experimental.noalias.scope.decl:"
- << *NAD << "\n");
- Instruction *NewNAD = NAD->clone();
- NewNAD->insertBefore(NewHeaderInsertionPoint);
- }
-
- // Scopes must now be duplicated, once for OrigHeader and once for
- // OrigPreHeader'.
- {
- auto &Context = NewHeader->getContext();
-
- SmallVector<MDNode *, 8> NoAliasDeclScopes;
- for (NoAliasScopeDeclInst *NAD : NoAliasDeclInstructions)
- NoAliasDeclScopes.push_back(NAD->getScopeList());
-
- LLVM_DEBUG(dbgs() << " Updating OrigHeader scopes\n");
- cloneAndAdaptNoAliasScopes(NoAliasDeclScopes, {OrigHeader}, Context,
- "h.rot");
- LLVM_DEBUG(OrigHeader->dump());
-
- // Keep the compile time impact low by only adapting the inserted block
- // of instructions in the OrigPreHeader. This might result in slightly
- // more aliasing between these instructions and those that were already
- // present, but it will be much faster when the original PreHeader is
- // large.
- LLVM_DEBUG(dbgs() << " Updating part of OrigPreheader scopes\n");
- auto *FirstDecl =
- cast<Instruction>(ValueMap[*NoAliasDeclInstructions.begin()]);
- auto *LastInst = &OrigPreheader->back();
- cloneAndAdaptNoAliasScopes(NoAliasDeclScopes, FirstDecl, LastInst,
- Context, "pre.rot");
- LLVM_DEBUG(OrigPreheader->dump());
-
- LLVM_DEBUG(dbgs() << " Updated NewHeader:\n");
- LLVM_DEBUG(NewHeader->dump());
- }
- }
-
+ if (!NoAliasDeclInstructions.empty()) {
+ // There are noalias scope declarations:
+ // (general):
+ // Original: OrigPre { OrigHeader NewHeader ... Latch }
+ // after: (OrigPre+OrigHeader') { NewHeader ... Latch OrigHeader }
+ //
+ // with D: llvm.experimental.noalias.scope.decl,
+ // U: !noalias or !alias.scope depending on D
+ // ... { D U1 U2 } can transform into:
+ // (0) : ... { D U1 U2 } // no relevant rotation for this part
+ // (1) : ... D' { U1 U2 D } // D is part of OrigHeader
+ // (2) : ... D' U1' { U2 D U1 } // D, U1 are part of OrigHeader
+ //
+ // We now want to transform:
+ // (1) -> : ... D' { D U1 U2 D'' }
+ // (2) -> : ... D' U1' { D U2 D'' U1'' }
+ // D: original llvm.experimental.noalias.scope.decl
+ // D', U1': duplicate with replaced scopes
+ // D'', U1'': different duplicate with replaced scopes
+ // This ensures a safe fallback to 'may_alias' introduced by the rotate,
+ // as U1'' and U1' scopes will not be compatible wrt to the local restrict
+
+ // Clone the llvm.experimental.noalias.decl again for the NewHeader.
+ Instruction *NewHeaderInsertionPoint = &(*NewHeader->getFirstNonPHI());
+ for (NoAliasScopeDeclInst *NAD : NoAliasDeclInstructions) {
+ LLVM_DEBUG(dbgs() << " Cloning llvm.experimental.noalias.scope.decl:"
+ << *NAD << "\n");
+ Instruction *NewNAD = NAD->clone();
+ NewNAD->insertBefore(NewHeaderInsertionPoint);
+ }
+
+ // Scopes must now be duplicated, once for OrigHeader and once for
+ // OrigPreHeader'.
+ {
+ auto &Context = NewHeader->getContext();
+
+ SmallVector<MDNode *, 8> NoAliasDeclScopes;
+ for (NoAliasScopeDeclInst *NAD : NoAliasDeclInstructions)
+ NoAliasDeclScopes.push_back(NAD->getScopeList());
+
+ LLVM_DEBUG(dbgs() << " Updating OrigHeader scopes\n");
+ cloneAndAdaptNoAliasScopes(NoAliasDeclScopes, {OrigHeader}, Context,
+ "h.rot");
+ LLVM_DEBUG(OrigHeader->dump());
+
+ // Keep the compile time impact low by only adapting the inserted block
+ // of instructions in the OrigPreHeader. This might result in slightly
+ // more aliasing between these instructions and those that were already
+ // present, but it will be much faster when the original PreHeader is
+ // large.
+ LLVM_DEBUG(dbgs() << " Updating part of OrigPreheader scopes\n");
+ auto *FirstDecl =
+ cast<Instruction>(ValueMap[*NoAliasDeclInstructions.begin()]);
+ auto *LastInst = &OrigPreheader->back();
+ cloneAndAdaptNoAliasScopes(NoAliasDeclScopes, FirstDecl, LastInst,
+ Context, "pre.rot");
+ LLVM_DEBUG(OrigPreheader->dump());
+
+ LLVM_DEBUG(dbgs() << " Updated NewHeader:\n");
+ LLVM_DEBUG(NewHeader->dump());
+ }
+ }
+
// Along with all the other instructions, we just cloned OrigHeader's
// terminator into OrigPreHeader. Fix up the PHI nodes in each of OrigHeader's
// successors by duplicating their incoming values for OrigHeader.
@@ -579,11 +579,11 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
Updates.push_back({DominatorTree::Delete, OrigPreheader, OrigHeader});
if (MSSAU) {
- MSSAU->applyUpdates(Updates, *DT, /*UpdateDT=*/true);
+ MSSAU->applyUpdates(Updates, *DT, /*UpdateDT=*/true);
if (VerifyMemorySSA)
MSSAU->getMemorySSA()->verifyMemorySSA();
- } else {
- DT->applyUpdates(Updates);
+ } else {
+ DT->applyUpdates(Updates);
}
}
@@ -657,10 +657,10 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
// connected by an unconditional branch. This is just a cleanup so the
// emitted code isn't too gross in this common case.
DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
- BasicBlock *PredBB = OrigHeader->getUniquePredecessor();
- bool DidMerge = MergeBlockIntoPredecessor(OrigHeader, &DTU, LI, MSSAU);
- if (DidMerge)
- RemoveRedundantDbgInstrs(PredBB);
+ BasicBlock *PredBB = OrigHeader->getUniquePredecessor();
+ bool DidMerge = MergeBlockIntoPredecessor(OrigHeader, &DTU, LI, MSSAU);
+ if (DidMerge)
+ RemoveRedundantDbgInstrs(PredBB);
if (MSSAU && VerifyMemorySSA)
MSSAU->getMemorySSA()->verifyMemorySSA();
@@ -824,8 +824,8 @@ bool llvm::LoopRotation(Loop *L, LoopInfo *LI, const TargetTransformInfo *TTI,
ScalarEvolution *SE, MemorySSAUpdater *MSSAU,
const SimplifyQuery &SQ, bool RotationOnly = true,
unsigned Threshold = unsigned(-1),
- bool IsUtilMode = true, bool PrepareForLTO) {
+ bool IsUtilMode = true, bool PrepareForLTO) {
LoopRotate LR(Threshold, LI, TTI, AC, DT, SE, MSSAU, SQ, RotationOnly,
- IsUtilMode, PrepareForLTO);
+ IsUtilMode, PrepareForLTO);
return LR.processLoop(L);
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/LoopSimplify.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/LoopSimplify.cpp
index 0b6f3de0e0..2e104334ad 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/LoopSimplify.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/LoopSimplify.cpp
@@ -163,7 +163,7 @@ BasicBlock *llvm::InsertPreheaderForLoop(Loop *L, DominatorTree *DT,
/// if it's not already in there. Stop predecessor traversal when we reach
/// StopBlock.
static void addBlockAndPredsToSet(BasicBlock *InputBB, BasicBlock *StopBlock,
- SmallPtrSetImpl<BasicBlock *> &Blocks) {
+ SmallPtrSetImpl<BasicBlock *> &Blocks) {
SmallVector<BasicBlock *, 8> Worklist;
Worklist.push_back(InputBB);
do {
@@ -171,7 +171,7 @@ static void addBlockAndPredsToSet(BasicBlock *InputBB, BasicBlock *StopBlock,
if (Blocks.insert(BB).second && BB != StopBlock)
// If BB is not already processed and it is not a stop block then
// insert its predecessor in the work list
- append_range(Worklist, predecessors(BB));
+ append_range(Worklist, predecessors(BB));
} while (!Worklist.empty());
}
@@ -305,8 +305,8 @@ static Loop *separateNestedLoop(Loop *L, BasicBlock *Preheader,
// Determine which blocks should stay in L and which should be moved out to
// the Outer loop now.
- SmallPtrSet<BasicBlock *, 4> BlocksInL;
- for (BasicBlock *P : predecessors(Header)) {
+ SmallPtrSet<BasicBlock *, 4> BlocksInL;
+ for (BasicBlock *P : predecessors(Header)) {
if (DT->dominates(Header, P))
addBlockAndPredsToSet(P, Header, BlocksInL);
}
@@ -679,7 +679,7 @@ ReprocessLoop:
// The block has now been cleared of all instructions except for
// a comparison and a conditional branch. SimplifyCFG may be able
// to fold it now.
- if (!FoldBranchToCommonDest(BI, /*DTU=*/nullptr, MSSAU))
+ if (!FoldBranchToCommonDest(BI, /*DTU=*/nullptr, MSSAU))
continue;
// Success. The block is now dead, so remove it from the loop,
@@ -687,7 +687,7 @@ ReprocessLoop:
LLVM_DEBUG(dbgs() << "LoopSimplify: Eliminating exiting block "
<< ExitingBlock->getName() << "\n");
- assert(pred_empty(ExitingBlock));
+ assert(pred_empty(ExitingBlock));
Changed = true;
LI->removeBlock(ExitingBlock);
@@ -832,8 +832,8 @@ bool LoopSimplify::runOnFunction(Function &F) {
bool PreserveLCSSA = mustPreserveAnalysisID(LCSSAID);
// Simplify each loop nest in the function.
- for (auto *L : *LI)
- Changed |= simplifyLoop(L, DT, LI, SE, AC, MSSAU.get(), PreserveLCSSA);
+ for (auto *L : *LI)
+ Changed |= simplifyLoop(L, DT, LI, SE, AC, MSSAU.get(), PreserveLCSSA);
#ifndef NDEBUG
if (PreserveLCSSA) {
@@ -862,9 +862,9 @@ PreservedAnalyses LoopSimplifyPass::run(Function &F,
// Note that we don't preserve LCSSA in the new PM, if you need it run LCSSA
// after simplifying the loops. MemorySSA is preserved if it exists.
- for (auto *L : *LI)
+ for (auto *L : *LI)
Changed |=
- simplifyLoop(L, DT, LI, SE, AC, MSSAU.get(), /*PreserveLCSSA*/ false);
+ simplifyLoop(L, DT, LI, SE, AC, MSSAU.get(), /*PreserveLCSSA*/ false);
if (!Changed)
return PreservedAnalyses::all();
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/LoopUnroll.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/LoopUnroll.cpp
index 6a80eba7a1..d4cd574052 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/LoopUnroll.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/LoopUnroll.cpp
@@ -59,7 +59,7 @@
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/Local.h"
-#include "llvm/Transforms/Utils/LoopPeel.h"
+#include "llvm/Transforms/Utils/LoopPeel.h"
#include "llvm/Transforms/Utils/LoopSimplify.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
#include "llvm/Transforms/Utils/SimplifyIndVar.h"
@@ -109,15 +109,15 @@ UnrollVerifyDomtree("unroll-verify-domtree", cl::Hidden,
/// insert a phi-node, otherwise LCSSA will be broken.
/// The function is just a helper function for llvm::UnrollLoop that returns
/// true if this situation occurs, indicating that LCSSA needs to be fixed.
-static bool needToInsertPhisForLCSSA(Loop *L,
- const std::vector<BasicBlock *> &Blocks,
+static bool needToInsertPhisForLCSSA(Loop *L,
+ const std::vector<BasicBlock *> &Blocks,
LoopInfo *LI) {
for (BasicBlock *BB : Blocks) {
if (LI->getLoopFor(BB) == L)
continue;
for (Instruction &I : *BB) {
for (Use &U : I.operands()) {
- if (const auto *Def = dyn_cast<Instruction>(U)) {
+ if (const auto *Def = dyn_cast<Instruction>(U)) {
Loop *DefLoop = LI->getLoopFor(Def->getParent());
if (!DefLoop)
continue;
@@ -288,12 +288,12 @@ LoopUnrollResult llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
OptimizationRemarkEmitter *ORE,
bool PreserveLCSSA, Loop **RemainderLoop) {
- if (!L->getLoopPreheader()) {
+ if (!L->getLoopPreheader()) {
LLVM_DEBUG(dbgs() << " Can't unroll; loop preheader-insertion failed.\n");
return LoopUnrollResult::Unmodified;
}
- if (!L->getLoopLatch()) {
+ if (!L->getLoopLatch()) {
LLVM_DEBUG(dbgs() << " Can't unroll; loop exit-block-insertion failed.\n");
return LoopUnrollResult::Unmodified;
}
@@ -304,7 +304,7 @@ LoopUnrollResult llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
return LoopUnrollResult::Unmodified;
}
- if (L->getHeader()->hasAddressTaken()) {
+ if (L->getHeader()->hasAddressTaken()) {
// The loop-rotate pass can be helpful to avoid this in many cases.
LLVM_DEBUG(
dbgs() << " Won't unroll loop: address of header block is taken.\n");
@@ -362,58 +362,58 @@ LoopUnrollResult llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
}
}
- // All these values should be taken only after peeling because they might have
- // changed.
- BasicBlock *Preheader = L->getLoopPreheader();
- BasicBlock *Header = L->getHeader();
- BasicBlock *LatchBlock = L->getLoopLatch();
- SmallVector<BasicBlock *, 4> ExitBlocks;
- L->getExitBlocks(ExitBlocks);
- std::vector<BasicBlock *> OriginalLoopBlocks = L->getBlocks();
-
- // Go through all exits of L and see if there are any phi-nodes there. We just
- // conservatively assume that they're inserted to preserve LCSSA form, which
- // means that complete unrolling might break this form. We need to either fix
- // it in-place after the transformation, or entirely rebuild LCSSA. TODO: For
- // now we just recompute LCSSA for the outer loop, but it should be possible
- // to fix it in-place.
- bool NeedToFixLCSSA =
- PreserveLCSSA && CompletelyUnroll &&
- any_of(ExitBlocks,
- [](const BasicBlock *BB) { return isa<PHINode>(BB->begin()); });
-
- // The current loop unroll pass can unroll loops that have
- // (1) single latch; and
- // (2a) latch is unconditional; or
- // (2b) latch is conditional and is an exiting block
- // FIXME: The implementation can be extended to work with more complicated
- // cases, e.g. loops with multiple latches.
- BranchInst *LatchBI = dyn_cast<BranchInst>(LatchBlock->getTerminator());
-
- // A conditional branch which exits the loop, which can be optimized to an
- // unconditional branch in the unrolled loop in some cases.
- BranchInst *ExitingBI = nullptr;
- bool LatchIsExiting = L->isLoopExiting(LatchBlock);
- if (LatchIsExiting)
- ExitingBI = LatchBI;
- else if (BasicBlock *ExitingBlock = L->getExitingBlock())
- ExitingBI = dyn_cast<BranchInst>(ExitingBlock->getTerminator());
- if (!LatchBI || (LatchBI->isConditional() && !LatchIsExiting)) {
- // If the peeling guard is changed this assert may be relaxed or even
- // deleted.
- assert(!Peeled && "Peeling guard changed!");
- LLVM_DEBUG(
- dbgs() << "Can't unroll; a conditional latch must exit the loop");
- return LoopUnrollResult::Unmodified;
- }
- LLVM_DEBUG({
- if (ExitingBI)
- dbgs() << " Exiting Block = " << ExitingBI->getParent()->getName()
- << "\n";
- else
- dbgs() << " No single exiting block\n";
- });
-
+ // All these values should be taken only after peeling because they might have
+ // changed.
+ BasicBlock *Preheader = L->getLoopPreheader();
+ BasicBlock *Header = L->getHeader();
+ BasicBlock *LatchBlock = L->getLoopLatch();
+ SmallVector<BasicBlock *, 4> ExitBlocks;
+ L->getExitBlocks(ExitBlocks);
+ std::vector<BasicBlock *> OriginalLoopBlocks = L->getBlocks();
+
+ // Go through all exits of L and see if there are any phi-nodes there. We just
+ // conservatively assume that they're inserted to preserve LCSSA form, which
+ // means that complete unrolling might break this form. We need to either fix
+ // it in-place after the transformation, or entirely rebuild LCSSA. TODO: For
+ // now we just recompute LCSSA for the outer loop, but it should be possible
+ // to fix it in-place.
+ bool NeedToFixLCSSA =
+ PreserveLCSSA && CompletelyUnroll &&
+ any_of(ExitBlocks,
+ [](const BasicBlock *BB) { return isa<PHINode>(BB->begin()); });
+
+ // The current loop unroll pass can unroll loops that have
+ // (1) single latch; and
+ // (2a) latch is unconditional; or
+ // (2b) latch is conditional and is an exiting block
+ // FIXME: The implementation can be extended to work with more complicated
+ // cases, e.g. loops with multiple latches.
+ BranchInst *LatchBI = dyn_cast<BranchInst>(LatchBlock->getTerminator());
+
+ // A conditional branch which exits the loop, which can be optimized to an
+ // unconditional branch in the unrolled loop in some cases.
+ BranchInst *ExitingBI = nullptr;
+ bool LatchIsExiting = L->isLoopExiting(LatchBlock);
+ if (LatchIsExiting)
+ ExitingBI = LatchBI;
+ else if (BasicBlock *ExitingBlock = L->getExitingBlock())
+ ExitingBI = dyn_cast<BranchInst>(ExitingBlock->getTerminator());
+ if (!LatchBI || (LatchBI->isConditional() && !LatchIsExiting)) {
+ // If the peeling guard is changed this assert may be relaxed or even
+ // deleted.
+ assert(!Peeled && "Peeling guard changed!");
+ LLVM_DEBUG(
+ dbgs() << "Can't unroll; a conditional latch must exit the loop");
+ return LoopUnrollResult::Unmodified;
+ }
+ LLVM_DEBUG({
+ if (ExitingBI)
+ dbgs() << " Exiting Block = " << ExitingBI->getParent()->getName()
+ << "\n";
+ else
+ dbgs() << " No single exiting block\n";
+ });
+
// Loops containing convergent instructions must have a count that divides
// their TripMultiple.
LLVM_DEBUG(
@@ -590,11 +590,11 @@ LoopUnrollResult llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
<< DIL->getFilename() << " Line: " << DIL->getLine());
}
- // Identify what noalias metadata is inside the loop: if it is inside the
- // loop, the associated metadata must be cloned for each iteration.
- SmallVector<MDNode *, 6> LoopLocalNoAliasDeclScopes;
- identifyNoAliasScopesToClone(L->getBlocks(), LoopLocalNoAliasDeclScopes);
-
+ // Identify what noalias metadata is inside the loop: if it is inside the
+ // loop, the associated metadata must be cloned for each iteration.
+ SmallVector<MDNode *, 6> LoopLocalNoAliasDeclScopes;
+ identifyNoAliasScopesToClone(L->getBlocks(), LoopLocalNoAliasDeclScopes);
+
for (unsigned It = 1; It != ULO.Count; ++It) {
SmallVector<BasicBlock *, 8> NewBlocks;
SmallDenseMap<const Loop *, Loop *, 4> NewLoops;
@@ -688,15 +688,15 @@ LoopUnrollResult llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
AC->registerAssumption(II);
}
}
-
- {
- // Identify what other metadata depends on the cloned version. After
- // cloning, replace the metadata with the corrected version for both
- // memory instructions and noalias intrinsics.
- std::string ext = (Twine("It") + Twine(It)).str();
- cloneAndAdaptNoAliasScopes(LoopLocalNoAliasDeclScopes, NewBlocks,
- Header->getContext(), ext);
- }
+
+ {
+ // Identify what other metadata depends on the cloned version. After
+ // cloning, replace the metadata with the corrected version for both
+ // memory instructions and noalias intrinsics.
+ std::string ext = (Twine("It") + Twine(It)).str();
+ cloneAndAdaptNoAliasScopes(LoopLocalNoAliasDeclScopes, NewBlocks,
+ Header->getContext(), ext);
+ }
}
// Loop over the PHI nodes in the original block, setting incoming values.
@@ -884,7 +884,7 @@ LoopUnrollResult llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
if (MergeBlockIntoPredecessor(Dest, &DTU, LI)) {
// Dest has been folded into Fold. Update our worklists accordingly.
std::replace(Latches.begin(), Latches.end(), Dest, Fold);
- llvm::erase_value(UnrolledLoopBlocks, Dest);
+ llvm::erase_value(UnrolledLoopBlocks, Dest);
}
}
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/LoopUnrollAndJam.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/LoopUnrollAndJam.cpp
index daa298e0f7..6e32a2b865 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/LoopUnrollAndJam.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/LoopUnrollAndJam.cpp
@@ -148,7 +148,7 @@ static bool processHeaderPhiOperands(BasicBlock *Header, BasicBlock *Latch,
}
while (!Worklist.empty()) {
- Instruction *I = Worklist.pop_back_val();
+ Instruction *I = Worklist.pop_back_val();
if (!Visit(I))
return false;
@@ -516,10 +516,10 @@ llvm::UnrollAndJamLoop(Loop *L, unsigned Count, unsigned TripCount,
cast<BranchInst>(SubLoopBlocksLast.back()->getTerminator());
SubTerm->setSuccessor(!SubLoopContinueOnTrue, SubLoopBlocksFirst[0]);
SubTerm->setSuccessor(SubLoopContinueOnTrue, AftBlocksFirst[0]);
- SubLoopBlocksFirst[0]->replacePhiUsesWith(ForeBlocksLast[0],
- ForeBlocksLast.back());
- SubLoopBlocksFirst[0]->replacePhiUsesWith(SubLoopBlocksLast[0],
- SubLoopBlocksLast.back());
+ SubLoopBlocksFirst[0]->replacePhiUsesWith(ForeBlocksLast[0],
+ ForeBlocksLast.back());
+ SubLoopBlocksFirst[0]->replacePhiUsesWith(SubLoopBlocksLast[0],
+ SubLoopBlocksLast.back());
for (unsigned It = 1; It != Count; It++) {
// Replace the conditional branch of the previous iteration subloop with an
@@ -529,10 +529,10 @@ llvm::UnrollAndJamLoop(Loop *L, unsigned Count, unsigned TripCount,
BranchInst::Create(SubLoopBlocksFirst[It], SubTerm);
SubTerm->eraseFromParent();
- SubLoopBlocksFirst[It]->replacePhiUsesWith(ForeBlocksLast[It],
- ForeBlocksLast.back());
- SubLoopBlocksFirst[It]->replacePhiUsesWith(SubLoopBlocksLast[It],
- SubLoopBlocksLast.back());
+ SubLoopBlocksFirst[It]->replacePhiUsesWith(ForeBlocksLast[It],
+ ForeBlocksLast.back());
+ SubLoopBlocksFirst[It]->replacePhiUsesWith(SubLoopBlocksLast[It],
+ SubLoopBlocksLast.back());
movePHIs(SubLoopBlocksFirst[It], SubLoopBlocksFirst[0]);
}
@@ -546,8 +546,8 @@ llvm::UnrollAndJamLoop(Loop *L, unsigned Count, unsigned TripCount,
assert(AftTerm->getSuccessor(ContinueOnTrue) == LoopExit &&
"Expecting the ContinueOnTrue successor of AftTerm to be LoopExit");
}
- AftBlocksFirst[0]->replacePhiUsesWith(SubLoopBlocksLast[0],
- SubLoopBlocksLast.back());
+ AftBlocksFirst[0]->replacePhiUsesWith(SubLoopBlocksLast[0],
+ SubLoopBlocksLast.back());
for (unsigned It = 1; It != Count; It++) {
// Replace the conditional branch of the previous iteration subloop with an
@@ -557,8 +557,8 @@ llvm::UnrollAndJamLoop(Loop *L, unsigned Count, unsigned TripCount,
BranchInst::Create(AftBlocksFirst[It], AftTerm);
AftTerm->eraseFromParent();
- AftBlocksFirst[It]->replacePhiUsesWith(SubLoopBlocksLast[It],
- SubLoopBlocksLast.back());
+ AftBlocksFirst[It]->replacePhiUsesWith(SubLoopBlocksLast[It],
+ SubLoopBlocksLast.back());
movePHIs(AftBlocksFirst[It], AftBlocksFirst[0]);
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/LoopUnrollRuntime.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/LoopUnrollRuntime.cpp
index 97a9bedcd1..0abf62be15 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/LoopUnrollRuntime.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/LoopUnrollRuntime.cpp
@@ -26,7 +26,7 @@
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Dominators.h"
-#include "llvm/IR/MDBuilder.h"
+#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/CommandLine.h"
@@ -505,32 +505,32 @@ static bool canProfitablyUnrollMultiExitLoop(
// know of kinds of multiexit loops that would benefit from unrolling.
}
-// Assign the maximum possible trip count as the back edge weight for the
-// remainder loop if the original loop comes with a branch weight.
-static void updateLatchBranchWeightsForRemainderLoop(Loop *OrigLoop,
- Loop *RemainderLoop,
- uint64_t UnrollFactor) {
- uint64_t TrueWeight, FalseWeight;
- BranchInst *LatchBR =
- cast<BranchInst>(OrigLoop->getLoopLatch()->getTerminator());
- if (LatchBR->extractProfMetadata(TrueWeight, FalseWeight)) {
- uint64_t ExitWeight = LatchBR->getSuccessor(0) == OrigLoop->getHeader()
- ? FalseWeight
- : TrueWeight;
- assert(UnrollFactor > 1);
- uint64_t BackEdgeWeight = (UnrollFactor - 1) * ExitWeight;
- BasicBlock *Header = RemainderLoop->getHeader();
- BasicBlock *Latch = RemainderLoop->getLoopLatch();
- auto *RemainderLatchBR = cast<BranchInst>(Latch->getTerminator());
- unsigned HeaderIdx = (RemainderLatchBR->getSuccessor(0) == Header ? 0 : 1);
- MDBuilder MDB(RemainderLatchBR->getContext());
- MDNode *WeightNode =
- HeaderIdx ? MDB.createBranchWeights(ExitWeight, BackEdgeWeight)
- : MDB.createBranchWeights(BackEdgeWeight, ExitWeight);
- RemainderLatchBR->setMetadata(LLVMContext::MD_prof, WeightNode);
- }
-}
-
+// Assign the maximum possible trip count as the back edge weight for the
+// remainder loop if the original loop comes with a branch weight.
+static void updateLatchBranchWeightsForRemainderLoop(Loop *OrigLoop,
+ Loop *RemainderLoop,
+ uint64_t UnrollFactor) {
+ uint64_t TrueWeight, FalseWeight;
+ BranchInst *LatchBR =
+ cast<BranchInst>(OrigLoop->getLoopLatch()->getTerminator());
+ if (LatchBR->extractProfMetadata(TrueWeight, FalseWeight)) {
+ uint64_t ExitWeight = LatchBR->getSuccessor(0) == OrigLoop->getHeader()
+ ? FalseWeight
+ : TrueWeight;
+ assert(UnrollFactor > 1);
+ uint64_t BackEdgeWeight = (UnrollFactor - 1) * ExitWeight;
+ BasicBlock *Header = RemainderLoop->getHeader();
+ BasicBlock *Latch = RemainderLoop->getLoopLatch();
+ auto *RemainderLatchBR = cast<BranchInst>(Latch->getTerminator());
+ unsigned HeaderIdx = (RemainderLatchBR->getSuccessor(0) == Header ? 0 : 1);
+ MDBuilder MDB(RemainderLatchBR->getContext());
+ MDNode *WeightNode =
+ HeaderIdx ? MDB.createBranchWeights(ExitWeight, BackEdgeWeight)
+ : MDB.createBranchWeights(BackEdgeWeight, ExitWeight);
+ RemainderLatchBR->setMetadata(LLVMContext::MD_prof, WeightNode);
+ }
+}
+
/// Insert code in the prolog/epilog code when unrolling a loop with a
/// run-time trip-count.
///
@@ -814,11 +814,11 @@ bool llvm::UnrollRuntimeLoopRemainder(
InsertTop, InsertBot,
NewPreHeader, NewBlocks, LoopBlocks, VMap, DT, LI);
- // Assign the maximum possible trip count as the back edge weight for the
- // remainder loop if the original loop comes with a branch weight.
- if (remainderLoop && !UnrollRemainder)
- updateLatchBranchWeightsForRemainderLoop(L, remainderLoop, Count);
-
+ // Assign the maximum possible trip count as the back edge weight for the
+ // remainder loop if the original loop comes with a branch weight.
+ if (remainderLoop && !UnrollRemainder)
+ updateLatchBranchWeightsForRemainderLoop(L, remainderLoop, Count);
+
// Insert the cloned blocks into the function.
F->getBasicBlockList().splice(InsertBot->getIterator(),
F->getBasicBlockList(),
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/LoopUtils.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/LoopUtils.cpp
index 3aeb7d1e02..f0f423e981 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/LoopUtils.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/LoopUtils.cpp
@@ -63,7 +63,7 @@ static cl::opt<bool> ForceReductionIntrinsic(
static const char *LLVMLoopDisableNonforced = "llvm.loop.disable_nonforced";
static const char *LLVMLoopDisableLICM = "llvm.licm.disable";
-static const char *LLVMLoopMustProgress = "llvm.loop.mustprogress";
+static const char *LLVMLoopMustProgress = "llvm.loop.mustprogress";
bool llvm::formDedicatedExitBlocks(Loop *L, DominatorTree *DT, LoopInfo *LI,
MemorySSAUpdater *MSSAU,
@@ -298,24 +298,24 @@ static Optional<bool> getOptionalBoolLoopAttribute(const Loop *TheLoop,
llvm_unreachable("unexpected number of options");
}
-bool llvm::getBooleanLoopAttribute(const Loop *TheLoop, StringRef Name) {
+bool llvm::getBooleanLoopAttribute(const Loop *TheLoop, StringRef Name) {
return getOptionalBoolLoopAttribute(TheLoop, Name).getValueOr(false);
}
-Optional<ElementCount>
-llvm::getOptionalElementCountLoopAttribute(Loop *TheLoop) {
- Optional<int> Width =
- getOptionalIntLoopAttribute(TheLoop, "llvm.loop.vectorize.width");
-
- if (Width.hasValue()) {
- Optional<int> IsScalable = getOptionalIntLoopAttribute(
- TheLoop, "llvm.loop.vectorize.scalable.enable");
- return ElementCount::get(*Width, IsScalable.getValueOr(false));
- }
-
- return None;
-}
-
+Optional<ElementCount>
+llvm::getOptionalElementCountLoopAttribute(Loop *TheLoop) {
+ Optional<int> Width =
+ getOptionalIntLoopAttribute(TheLoop, "llvm.loop.vectorize.width");
+
+ if (Width.hasValue()) {
+ Optional<int> IsScalable = getOptionalIntLoopAttribute(
+ TheLoop, "llvm.loop.vectorize.scalable.enable");
+ return ElementCount::get(*Width, IsScalable.getValueOr(false));
+ }
+
+ return None;
+}
+
llvm::Optional<int> llvm::getOptionalIntLoopAttribute(Loop *TheLoop,
StringRef Name) {
const MDOperand *AttrMD =
@@ -349,7 +349,7 @@ Optional<MDNode *> llvm::makeFollowupLoopID(
bool Changed = false;
if (InheritAllAttrs || InheritSomeAttrs) {
- for (const MDOperand &Existing : drop_begin(OrigLoopID->operands())) {
+ for (const MDOperand &Existing : drop_begin(OrigLoopID->operands())) {
MDNode *Op = cast<MDNode>(Existing.get());
auto InheritThisAttribute = [InheritSomeAttrs,
@@ -386,7 +386,7 @@ Optional<MDNode *> llvm::makeFollowupLoopID(
continue;
HasAnyFollowup = true;
- for (const MDOperand &Option : drop_begin(FollowupNode->operands())) {
+ for (const MDOperand &Option : drop_begin(FollowupNode->operands())) {
MDs.push_back(Option.get());
Changed = true;
}
@@ -419,10 +419,10 @@ bool llvm::hasDisableLICMTransformsHint(const Loop *L) {
return getBooleanLoopAttribute(L, LLVMLoopDisableLICM);
}
-bool llvm::hasMustProgress(const Loop *L) {
- return getBooleanLoopAttribute(L, LLVMLoopMustProgress);
-}
-
+bool llvm::hasMustProgress(const Loop *L) {
+ return getBooleanLoopAttribute(L, LLVMLoopMustProgress);
+}
+
TransformationMode llvm::hasUnrollTransformation(Loop *L) {
if (getBooleanLoopAttribute(L, "llvm.loop.unroll.disable"))
return TM_SuppressedByUser;
@@ -469,15 +469,15 @@ TransformationMode llvm::hasVectorizeTransformation(Loop *L) {
if (Enable == false)
return TM_SuppressedByUser;
- Optional<ElementCount> VectorizeWidth =
- getOptionalElementCountLoopAttribute(L);
+ Optional<ElementCount> VectorizeWidth =
+ getOptionalElementCountLoopAttribute(L);
Optional<int> InterleaveCount =
getOptionalIntLoopAttribute(L, "llvm.loop.interleave.count");
// 'Forcing' vector width and interleave count to one effectively disables
// this tranformation.
- if (Enable == true && VectorizeWidth && VectorizeWidth->isScalar() &&
- InterleaveCount == 1)
+ if (Enable == true && VectorizeWidth && VectorizeWidth->isScalar() &&
+ InterleaveCount == 1)
return TM_SuppressedByUser;
if (getBooleanLoopAttribute(L, "llvm.loop.isvectorized"))
@@ -486,10 +486,10 @@ TransformationMode llvm::hasVectorizeTransformation(Loop *L) {
if (Enable == true)
return TM_ForcedByUser;
- if ((VectorizeWidth && VectorizeWidth->isScalar()) && InterleaveCount == 1)
+ if ((VectorizeWidth && VectorizeWidth->isScalar()) && InterleaveCount == 1)
return TM_Disable;
- if ((VectorizeWidth && VectorizeWidth->isVector()) || InterleaveCount > 1)
+ if ((VectorizeWidth && VectorizeWidth->isVector()) || InterleaveCount > 1)
return TM_Enable;
if (hasDisableAllTransformsHint(L))
@@ -592,61 +592,61 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE,
// non-loop, it will be deleted in a future iteration of loop deletion pass.
IRBuilder<> Builder(OldBr);
- auto *ExitBlock = L->getUniqueExitBlock();
- DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
- if (ExitBlock) {
- assert(ExitBlock && "Should have a unique exit block!");
- assert(L->hasDedicatedExits() && "Loop should have dedicated exits!");
-
- Builder.CreateCondBr(Builder.getFalse(), L->getHeader(), ExitBlock);
- // Remove the old branch. The conditional branch becomes a new terminator.
- OldBr->eraseFromParent();
-
- // Rewrite phis in the exit block to get their inputs from the Preheader
- // instead of the exiting block.
- for (PHINode &P : ExitBlock->phis()) {
- // Set the zero'th element of Phi to be from the preheader and remove all
- // other incoming values. Given the loop has dedicated exits, all other
- // incoming values must be from the exiting blocks.
- int PredIndex = 0;
- P.setIncomingBlock(PredIndex, Preheader);
- // Removes all incoming values from all other exiting blocks (including
- // duplicate values from an exiting block).
- // Nuke all entries except the zero'th entry which is the preheader entry.
- // NOTE! We need to remove Incoming Values in the reverse order as done
- // below, to keep the indices valid for deletion (removeIncomingValues
- // updates getNumIncomingValues and shifts all values down into the
- // operand being deleted).
- for (unsigned i = 0, e = P.getNumIncomingValues() - 1; i != e; ++i)
- P.removeIncomingValue(e - i, false);
-
- assert((P.getNumIncomingValues() == 1 &&
- P.getIncomingBlock(PredIndex) == Preheader) &&
- "Should have exactly one value and that's from the preheader!");
+ auto *ExitBlock = L->getUniqueExitBlock();
+ DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
+ if (ExitBlock) {
+ assert(ExitBlock && "Should have a unique exit block!");
+ assert(L->hasDedicatedExits() && "Loop should have dedicated exits!");
+
+ Builder.CreateCondBr(Builder.getFalse(), L->getHeader(), ExitBlock);
+ // Remove the old branch. The conditional branch becomes a new terminator.
+ OldBr->eraseFromParent();
+
+ // Rewrite phis in the exit block to get their inputs from the Preheader
+ // instead of the exiting block.
+ for (PHINode &P : ExitBlock->phis()) {
+ // Set the zero'th element of Phi to be from the preheader and remove all
+ // other incoming values. Given the loop has dedicated exits, all other
+ // incoming values must be from the exiting blocks.
+ int PredIndex = 0;
+ P.setIncomingBlock(PredIndex, Preheader);
+ // Removes all incoming values from all other exiting blocks (including
+ // duplicate values from an exiting block).
+ // Nuke all entries except the zero'th entry which is the preheader entry.
+ // NOTE! We need to remove Incoming Values in the reverse order as done
+ // below, to keep the indices valid for deletion (removeIncomingValues
+ // updates getNumIncomingValues and shifts all values down into the
+ // operand being deleted).
+ for (unsigned i = 0, e = P.getNumIncomingValues() - 1; i != e; ++i)
+ P.removeIncomingValue(e - i, false);
+
+ assert((P.getNumIncomingValues() == 1 &&
+ P.getIncomingBlock(PredIndex) == Preheader) &&
+ "Should have exactly one value and that's from the preheader!");
+ }
+
+ if (DT) {
+ DTU.applyUpdates({{DominatorTree::Insert, Preheader, ExitBlock}});
+ if (MSSA) {
+ MSSAU->applyUpdates({{DominatorTree::Insert, Preheader, ExitBlock}},
+ *DT);
+ if (VerifyMemorySSA)
+ MSSA->verifyMemorySSA();
+ }
}
-
- if (DT) {
- DTU.applyUpdates({{DominatorTree::Insert, Preheader, ExitBlock}});
- if (MSSA) {
- MSSAU->applyUpdates({{DominatorTree::Insert, Preheader, ExitBlock}},
- *DT);
- if (VerifyMemorySSA)
- MSSA->verifyMemorySSA();
- }
- }
-
- // Disconnect the loop body by branching directly to its exit.
- Builder.SetInsertPoint(Preheader->getTerminator());
- Builder.CreateBr(ExitBlock);
- // Remove the old branch.
- Preheader->getTerminator()->eraseFromParent();
- } else {
- assert(L->hasNoExitBlocks() &&
- "Loop should have either zero or one exit blocks.");
-
- Builder.SetInsertPoint(OldBr);
- Builder.CreateUnreachable();
- Preheader->getTerminator()->eraseFromParent();
+
+ // Disconnect the loop body by branching directly to its exit.
+ Builder.SetInsertPoint(Preheader->getTerminator());
+ Builder.CreateBr(ExitBlock);
+ // Remove the old branch.
+ Preheader->getTerminator()->eraseFromParent();
+ } else {
+ assert(L->hasNoExitBlocks() &&
+ "Loop should have either zero or one exit blocks.");
+
+ Builder.SetInsertPoint(OldBr);
+ Builder.CreateUnreachable();
+ Preheader->getTerminator()->eraseFromParent();
}
if (DT) {
@@ -666,58 +666,58 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE,
llvm::SmallDenseSet<std::pair<DIVariable *, DIExpression *>, 4> DeadDebugSet;
llvm::SmallVector<DbgVariableIntrinsic *, 4> DeadDebugInst;
- if (ExitBlock) {
- // Given LCSSA form is satisfied, we should not have users of instructions
- // within the dead loop outside of the loop. However, LCSSA doesn't take
- // unreachable uses into account. We handle them here.
- // We could do it after drop all references (in this case all users in the
- // loop will be already eliminated and we have less work to do but according
- // to API doc of User::dropAllReferences only valid operation after dropping
- // references, is deletion. So let's substitute all usages of
- // instruction from the loop with undef value of corresponding type first.
- for (auto *Block : L->blocks())
- for (Instruction &I : *Block) {
- auto *Undef = UndefValue::get(I.getType());
- for (Value::use_iterator UI = I.use_begin(), E = I.use_end();
- UI != E;) {
- Use &U = *UI;
- ++UI;
- if (auto *Usr = dyn_cast<Instruction>(U.getUser()))
- if (L->contains(Usr->getParent()))
- continue;
- // If we have a DT then we can check that uses outside a loop only in
- // unreachable block.
- if (DT)
- assert(!DT->isReachableFromEntry(U) &&
- "Unexpected user in reachable block");
- U.set(Undef);
- }
- auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I);
- if (!DVI)
- continue;
- auto Key =
- DeadDebugSet.find({DVI->getVariable(), DVI->getExpression()});
- if (Key != DeadDebugSet.end())
- continue;
- DeadDebugSet.insert({DVI->getVariable(), DVI->getExpression()});
- DeadDebugInst.push_back(DVI);
+ if (ExitBlock) {
+ // Given LCSSA form is satisfied, we should not have users of instructions
+ // within the dead loop outside of the loop. However, LCSSA doesn't take
+ // unreachable uses into account. We handle them here.
+ // We could do it after drop all references (in this case all users in the
+ // loop will be already eliminated and we have less work to do but according
+ // to API doc of User::dropAllReferences only valid operation after dropping
+ // references, is deletion. So let's substitute all usages of
+ // instruction from the loop with undef value of corresponding type first.
+ for (auto *Block : L->blocks())
+ for (Instruction &I : *Block) {
+ auto *Undef = UndefValue::get(I.getType());
+ for (Value::use_iterator UI = I.use_begin(), E = I.use_end();
+ UI != E;) {
+ Use &U = *UI;
+ ++UI;
+ if (auto *Usr = dyn_cast<Instruction>(U.getUser()))
+ if (L->contains(Usr->getParent()))
+ continue;
+ // If we have a DT then we can check that uses outside a loop only in
+ // unreachable block.
+ if (DT)
+ assert(!DT->isReachableFromEntry(U) &&
+ "Unexpected user in reachable block");
+ U.set(Undef);
+ }
+ auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I);
+ if (!DVI)
+ continue;
+ auto Key =
+ DeadDebugSet.find({DVI->getVariable(), DVI->getExpression()});
+ if (Key != DeadDebugSet.end())
+ continue;
+ DeadDebugSet.insert({DVI->getVariable(), DVI->getExpression()});
+ DeadDebugInst.push_back(DVI);
}
- // After the loop has been deleted all the values defined and modified
- // inside the loop are going to be unavailable.
- // Since debug values in the loop have been deleted, inserting an undef
- // dbg.value truncates the range of any dbg.value before the loop where the
- // loop used to be. This is particularly important for constant values.
- DIBuilder DIB(*ExitBlock->getModule());
- Instruction *InsertDbgValueBefore = ExitBlock->getFirstNonPHI();
- assert(InsertDbgValueBefore &&
- "There should be a non-PHI instruction in exit block, else these "
- "instructions will have no parent.");
- for (auto *DVI : DeadDebugInst)
- DIB.insertDbgValueIntrinsic(UndefValue::get(Builder.getInt32Ty()),
- DVI->getVariable(), DVI->getExpression(),
- DVI->getDebugLoc(), InsertDbgValueBefore);
- }
+ // After the loop has been deleted all the values defined and modified
+ // inside the loop are going to be unavailable.
+ // Since debug values in the loop have been deleted, inserting an undef
+ // dbg.value truncates the range of any dbg.value before the loop where the
+ // loop used to be. This is particularly important for constant values.
+ DIBuilder DIB(*ExitBlock->getModule());
+ Instruction *InsertDbgValueBefore = ExitBlock->getFirstNonPHI();
+ assert(InsertDbgValueBefore &&
+ "There should be a non-PHI instruction in exit block, else these "
+ "instructions will have no parent.");
+ for (auto *DVI : DeadDebugInst)
+ DIB.insertDbgValueIntrinsic(UndefValue::get(Builder.getInt32Ty()),
+ DVI->getVariable(), DVI->getExpression(),
+ DVI->getDebugLoc(), InsertDbgValueBefore);
+ }
// Remove the block from the reference counting scheme, so that we can
// delete it freely later.
@@ -761,51 +761,51 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE,
}
}
-static Loop *getOutermostLoop(Loop *L) {
- while (Loop *Parent = L->getParentLoop())
- L = Parent;
- return L;
-}
-
-void llvm::breakLoopBackedge(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
- LoopInfo &LI, MemorySSA *MSSA) {
- auto *Latch = L->getLoopLatch();
- assert(Latch && "multiple latches not yet supported");
- auto *Header = L->getHeader();
- Loop *OutermostLoop = getOutermostLoop(L);
-
- SE.forgetLoop(L);
-
- // Note: By splitting the backedge, and then explicitly making it unreachable
- // we gracefully handle corner cases such as non-bottom tested loops and the
- // like. We also have the benefit of being able to reuse existing well tested
- // code. It might be worth special casing the common bottom tested case at
- // some point to avoid code churn.
-
- std::unique_ptr<MemorySSAUpdater> MSSAU;
- if (MSSA)
- MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
-
- auto *BackedgeBB = SplitEdge(Latch, Header, &DT, &LI, MSSAU.get());
-
- DomTreeUpdater DTU(&DT, DomTreeUpdater::UpdateStrategy::Eager);
- (void)changeToUnreachable(BackedgeBB->getTerminator(), /*UseTrap*/false,
- /*PreserveLCSSA*/true, &DTU, MSSAU.get());
-
- // Erase (and destroy) this loop instance. Handles relinking sub-loops
- // and blocks within the loop as needed.
- LI.erase(L);
-
- // If the loop we broke had a parent, then changeToUnreachable might have
- // caused a block to be removed from the parent loop (see loop_nest_lcssa
- // test case in zero-btc.ll for an example), thus changing the parent's
- // exit blocks. If that happened, we need to rebuild LCSSA on the outermost
- // loop which might have a had a block removed.
- if (OutermostLoop != L)
- formLCSSARecursively(*OutermostLoop, DT, &LI, &SE);
-}
-
-
+static Loop *getOutermostLoop(Loop *L) {
+ while (Loop *Parent = L->getParentLoop())
+ L = Parent;
+ return L;
+}
+
+void llvm::breakLoopBackedge(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
+ LoopInfo &LI, MemorySSA *MSSA) {
+ auto *Latch = L->getLoopLatch();
+ assert(Latch && "multiple latches not yet supported");
+ auto *Header = L->getHeader();
+ Loop *OutermostLoop = getOutermostLoop(L);
+
+ SE.forgetLoop(L);
+
+ // Note: By splitting the backedge, and then explicitly making it unreachable
+ // we gracefully handle corner cases such as non-bottom tested loops and the
+ // like. We also have the benefit of being able to reuse existing well tested
+ // code. It might be worth special casing the common bottom tested case at
+ // some point to avoid code churn.
+
+ std::unique_ptr<MemorySSAUpdater> MSSAU;
+ if (MSSA)
+ MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
+
+ auto *BackedgeBB = SplitEdge(Latch, Header, &DT, &LI, MSSAU.get());
+
+ DomTreeUpdater DTU(&DT, DomTreeUpdater::UpdateStrategy::Eager);
+ (void)changeToUnreachable(BackedgeBB->getTerminator(), /*UseTrap*/false,
+ /*PreserveLCSSA*/true, &DTU, MSSAU.get());
+
+ // Erase (and destroy) this loop instance. Handles relinking sub-loops
+ // and blocks within the loop as needed.
+ LI.erase(L);
+
+ // If the loop we broke had a parent, then changeToUnreachable might have
+ // caused a block to be removed from the parent loop (see loop_nest_lcssa
+ // test case in zero-btc.ll for an example), thus changing the parent's
+ // exit blocks. If that happened, we need to rebuild LCSSA on the outermost
+ // loop which might have a had a block removed.
+ if (OutermostLoop != L)
+ formLCSSARecursively(*OutermostLoop, DT, &LI, &SE);
+}
+
+
/// Checks if \p L has single exit through latch block except possibly
/// "deoptimizing" exits. Returns branch instruction terminating the loop
/// latch if above check is successful, nullptr otherwise.
@@ -918,29 +918,29 @@ bool llvm::hasIterationCountInvariantInParent(Loop *InnerLoop,
return true;
}
-Value *llvm::createMinMaxOp(IRBuilderBase &Builder, RecurKind RK, Value *Left,
- Value *Right) {
- CmpInst::Predicate Pred;
+Value *llvm::createMinMaxOp(IRBuilderBase &Builder, RecurKind RK, Value *Left,
+ Value *Right) {
+ CmpInst::Predicate Pred;
switch (RK) {
default:
llvm_unreachable("Unknown min/max recurrence kind");
- case RecurKind::UMin:
- Pred = CmpInst::ICMP_ULT;
+ case RecurKind::UMin:
+ Pred = CmpInst::ICMP_ULT;
break;
- case RecurKind::UMax:
- Pred = CmpInst::ICMP_UGT;
+ case RecurKind::UMax:
+ Pred = CmpInst::ICMP_UGT;
break;
- case RecurKind::SMin:
- Pred = CmpInst::ICMP_SLT;
+ case RecurKind::SMin:
+ Pred = CmpInst::ICMP_SLT;
break;
- case RecurKind::SMax:
- Pred = CmpInst::ICMP_SGT;
+ case RecurKind::SMax:
+ Pred = CmpInst::ICMP_SGT;
break;
- case RecurKind::FMin:
- Pred = CmpInst::FCMP_OLT;
+ case RecurKind::FMin:
+ Pred = CmpInst::FCMP_OLT;
break;
- case RecurKind::FMax:
- Pred = CmpInst::FCMP_OGT;
+ case RecurKind::FMax:
+ Pred = CmpInst::FCMP_OGT;
break;
}
@@ -950,15 +950,15 @@ Value *llvm::createMinMaxOp(IRBuilderBase &Builder, RecurKind RK, Value *Left,
FastMathFlags FMF;
FMF.setFast();
Builder.setFastMathFlags(FMF);
- Value *Cmp = Builder.CreateCmp(Pred, Left, Right, "rdx.minmax.cmp");
+ Value *Cmp = Builder.CreateCmp(Pred, Left, Right, "rdx.minmax.cmp");
Value *Select = Builder.CreateSelect(Cmp, Left, Right, "rdx.minmax.select");
return Select;
}
// Helper to generate an ordered reduction.
-Value *llvm::getOrderedReduction(IRBuilderBase &Builder, Value *Acc, Value *Src,
- unsigned Op, RecurKind RdxKind,
- ArrayRef<Value *> RedOps) {
+Value *llvm::getOrderedReduction(IRBuilderBase &Builder, Value *Acc, Value *Src,
+ unsigned Op, RecurKind RdxKind,
+ ArrayRef<Value *> RedOps) {
unsigned VF = cast<FixedVectorType>(Src->getType())->getNumElements();
// Extract and apply reduction ops in ascending order:
@@ -972,9 +972,9 @@ Value *llvm::getOrderedReduction(IRBuilderBase &Builder, Value *Acc, Value *Src,
Result = Builder.CreateBinOp((Instruction::BinaryOps)Op, Result, Ext,
"bin.rdx");
} else {
- assert(RecurrenceDescriptor::isMinMaxRecurrenceKind(RdxKind) &&
+ assert(RecurrenceDescriptor::isMinMaxRecurrenceKind(RdxKind) &&
"Invalid min/max");
- Result = createMinMaxOp(Builder, RdxKind, Result, Ext);
+ Result = createMinMaxOp(Builder, RdxKind, Result, Ext);
}
if (!RedOps.empty())
@@ -985,9 +985,9 @@ Value *llvm::getOrderedReduction(IRBuilderBase &Builder, Value *Acc, Value *Src,
}
// Helper to generate a log2 shuffle reduction.
-Value *llvm::getShuffleReduction(IRBuilderBase &Builder, Value *Src,
- unsigned Op, RecurKind RdxKind,
- ArrayRef<Value *> RedOps) {
+Value *llvm::getShuffleReduction(IRBuilderBase &Builder, Value *Src,
+ unsigned Op, RecurKind RdxKind,
+ ArrayRef<Value *> RedOps) {
unsigned VF = cast<FixedVectorType>(Src->getType())->getNumElements();
// VF is a power of 2 so we can emit the reduction using log2(VF) shuffles
// and vector ops, reducing the set of values being computed by half each
@@ -1004,16 +1004,16 @@ Value *llvm::getShuffleReduction(IRBuilderBase &Builder, Value *Src,
// Fill the rest of the mask with undef.
std::fill(&ShuffleMask[i / 2], ShuffleMask.end(), -1);
- Value *Shuf = Builder.CreateShuffleVector(TmpVec, ShuffleMask, "rdx.shuf");
+ Value *Shuf = Builder.CreateShuffleVector(TmpVec, ShuffleMask, "rdx.shuf");
if (Op != Instruction::ICmp && Op != Instruction::FCmp) {
// The builder propagates its fast-math-flags setting.
TmpVec = Builder.CreateBinOp((Instruction::BinaryOps)Op, TmpVec, Shuf,
"bin.rdx");
} else {
- assert(RecurrenceDescriptor::isMinMaxRecurrenceKind(RdxKind) &&
+ assert(RecurrenceDescriptor::isMinMaxRecurrenceKind(RdxKind) &&
"Invalid min/max");
- TmpVec = createMinMaxOp(Builder, RdxKind, TmpVec, Shuf);
+ TmpVec = createMinMaxOp(Builder, RdxKind, TmpVec, Shuf);
}
if (!RedOps.empty())
propagateIRFlags(TmpVec, RedOps);
@@ -1027,48 +1027,48 @@ Value *llvm::getShuffleReduction(IRBuilderBase &Builder, Value *Src,
return Builder.CreateExtractElement(TmpVec, Builder.getInt32(0));
}
-Value *llvm::createSimpleTargetReduction(IRBuilderBase &Builder,
- const TargetTransformInfo *TTI,
- Value *Src, RecurKind RdxKind,
- ArrayRef<Value *> RedOps) {
- unsigned Opcode = RecurrenceDescriptor::getOpcode(RdxKind);
- TargetTransformInfo::ReductionFlags RdxFlags;
- RdxFlags.IsMaxOp = RdxKind == RecurKind::SMax || RdxKind == RecurKind::UMax ||
- RdxKind == RecurKind::FMax;
- RdxFlags.IsSigned = RdxKind == RecurKind::SMax || RdxKind == RecurKind::SMin;
- if (!ForceReductionIntrinsic &&
- !TTI->useReductionIntrinsic(Opcode, Src->getType(), RdxFlags))
- return getShuffleReduction(Builder, Src, Opcode, RdxKind, RedOps);
-
- auto *SrcVecEltTy = cast<VectorType>(Src->getType())->getElementType();
- switch (RdxKind) {
- case RecurKind::Add:
- return Builder.CreateAddReduce(Src);
- case RecurKind::Mul:
- return Builder.CreateMulReduce(Src);
- case RecurKind::And:
- return Builder.CreateAndReduce(Src);
- case RecurKind::Or:
- return Builder.CreateOrReduce(Src);
- case RecurKind::Xor:
- return Builder.CreateXorReduce(Src);
- case RecurKind::FAdd:
- return Builder.CreateFAddReduce(ConstantFP::getNegativeZero(SrcVecEltTy),
- Src);
- case RecurKind::FMul:
- return Builder.CreateFMulReduce(ConstantFP::get(SrcVecEltTy, 1.0), Src);
- case RecurKind::SMax:
- return Builder.CreateIntMaxReduce(Src, true);
- case RecurKind::SMin:
- return Builder.CreateIntMinReduce(Src, true);
- case RecurKind::UMax:
- return Builder.CreateIntMaxReduce(Src, false);
- case RecurKind::UMin:
- return Builder.CreateIntMinReduce(Src, false);
- case RecurKind::FMax:
- return Builder.CreateFPMaxReduce(Src);
- case RecurKind::FMin:
- return Builder.CreateFPMinReduce(Src);
+Value *llvm::createSimpleTargetReduction(IRBuilderBase &Builder,
+ const TargetTransformInfo *TTI,
+ Value *Src, RecurKind RdxKind,
+ ArrayRef<Value *> RedOps) {
+ unsigned Opcode = RecurrenceDescriptor::getOpcode(RdxKind);
+ TargetTransformInfo::ReductionFlags RdxFlags;
+ RdxFlags.IsMaxOp = RdxKind == RecurKind::SMax || RdxKind == RecurKind::UMax ||
+ RdxKind == RecurKind::FMax;
+ RdxFlags.IsSigned = RdxKind == RecurKind::SMax || RdxKind == RecurKind::SMin;
+ if (!ForceReductionIntrinsic &&
+ !TTI->useReductionIntrinsic(Opcode, Src->getType(), RdxFlags))
+ return getShuffleReduction(Builder, Src, Opcode, RdxKind, RedOps);
+
+ auto *SrcVecEltTy = cast<VectorType>(Src->getType())->getElementType();
+ switch (RdxKind) {
+ case RecurKind::Add:
+ return Builder.CreateAddReduce(Src);
+ case RecurKind::Mul:
+ return Builder.CreateMulReduce(Src);
+ case RecurKind::And:
+ return Builder.CreateAndReduce(Src);
+ case RecurKind::Or:
+ return Builder.CreateOrReduce(Src);
+ case RecurKind::Xor:
+ return Builder.CreateXorReduce(Src);
+ case RecurKind::FAdd:
+ return Builder.CreateFAddReduce(ConstantFP::getNegativeZero(SrcVecEltTy),
+ Src);
+ case RecurKind::FMul:
+ return Builder.CreateFMulReduce(ConstantFP::get(SrcVecEltTy, 1.0), Src);
+ case RecurKind::SMax:
+ return Builder.CreateIntMaxReduce(Src, true);
+ case RecurKind::SMin:
+ return Builder.CreateIntMinReduce(Src, true);
+ case RecurKind::UMax:
+ return Builder.CreateIntMaxReduce(Src, false);
+ case RecurKind::UMin:
+ return Builder.CreateIntMinReduce(Src, false);
+ case RecurKind::FMax:
+ return Builder.CreateFPMaxReduce(Src);
+ case RecurKind::FMin:
+ return Builder.CreateFPMinReduce(Src);
default:
llvm_unreachable("Unhandled opcode");
}
@@ -1076,13 +1076,13 @@ Value *llvm::createSimpleTargetReduction(IRBuilderBase &Builder,
Value *llvm::createTargetReduction(IRBuilderBase &B,
const TargetTransformInfo *TTI,
- RecurrenceDescriptor &Desc, Value *Src) {
+ RecurrenceDescriptor &Desc, Value *Src) {
// TODO: Support in-order reductions based on the recurrence descriptor.
// All ops in the reduction inherit fast-math-flags from the recurrence
// descriptor.
IRBuilderBase::FastMathFlagGuard FMFGuard(B);
B.setFastMathFlags(Desc.getFastMathFlags());
- return createSimpleTargetReduction(B, TTI, Src, Desc.getRecurrenceKind());
+ return createSimpleTargetReduction(B, TTI, Src, Desc.getRecurrenceKind());
}
void llvm::propagateIRFlags(Value *I, ArrayRef<Value *> VL, Value *OpValue) {
@@ -1158,7 +1158,7 @@ static bool isValidRewrite(ScalarEvolution *SE, Value *FromVal, Value *ToVal) {
// producing an expression involving multiple pointers. Until then, we must
// bail out here.
//
- // Retrieve the pointer operand of the GEP. Don't use getUnderlyingObject
+ // Retrieve the pointer operand of the GEP. Don't use getUnderlyingObject
// because it understands lcssa phis while SCEV does not.
Value *FromPtr = FromVal;
Value *ToPtr = ToVal;
@@ -1175,7 +1175,7 @@ static bool isValidRewrite(ScalarEvolution *SE, Value *FromVal, Value *ToVal) {
// SCEV may have rewritten an expression that produces the GEP's pointer
// operand. That's ok as long as the pointer operand has the same base
- // pointer. Unlike getUnderlyingObject(), getPointerBase() will find the
+ // pointer. Unlike getUnderlyingObject(), getPointerBase() will find the
// base of a recurrence. This handles the case in which SCEV expansion
// converts a pointer type recurrence into a nonrecurrent pointer base
// indexed by an integer recurrence.
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/LoopVersioning.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/LoopVersioning.cpp
index b46592f2d7..599bd1feb2 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/LoopVersioning.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/LoopVersioning.cpp
@@ -16,12 +16,12 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Analysis/LoopAccessAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/MemorySSA.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/MemorySSA.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/MDBuilder.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
@@ -36,22 +36,22 @@ static cl::opt<bool>
cl::desc("Add no-alias annotation for instructions that "
"are disambiguated by memchecks"));
-LoopVersioning::LoopVersioning(const LoopAccessInfo &LAI,
- ArrayRef<RuntimePointerCheck> Checks, Loop *L,
- LoopInfo *LI, DominatorTree *DT,
- ScalarEvolution *SE)
- : VersionedLoop(L), NonVersionedLoop(nullptr),
- AliasChecks(Checks.begin(), Checks.end()),
- Preds(LAI.getPSE().getUnionPredicate()), LAI(LAI), LI(LI), DT(DT),
+LoopVersioning::LoopVersioning(const LoopAccessInfo &LAI,
+ ArrayRef<RuntimePointerCheck> Checks, Loop *L,
+ LoopInfo *LI, DominatorTree *DT,
+ ScalarEvolution *SE)
+ : VersionedLoop(L), NonVersionedLoop(nullptr),
+ AliasChecks(Checks.begin(), Checks.end()),
+ Preds(LAI.getPSE().getUnionPredicate()), LAI(LAI), LI(LI), DT(DT),
SE(SE) {
- assert(L->getUniqueExitBlock() && "No single exit block");
+ assert(L->getUniqueExitBlock() && "No single exit block");
}
void LoopVersioning::versionLoop(
const SmallVectorImpl<Instruction *> &DefsUsedOutside) {
- assert(VersionedLoop->isLoopSimplifyForm() &&
- "Loop is not in loop-simplify form");
-
+ assert(VersionedLoop->isLoopSimplifyForm() &&
+ "Loop is not in loop-simplify form");
+
Instruction *FirstCheckInst;
Instruction *MemRuntimeCheck;
Value *SCEVRuntimeCheck;
@@ -67,7 +67,7 @@ void LoopVersioning::versionLoop(
SCEVExpander Exp(*SE, RuntimeCheckBB->getModule()->getDataLayout(),
"scev.check");
SCEVRuntimeCheck =
- Exp.expandCodeForPredicate(&Preds, RuntimeCheckBB->getTerminator());
+ Exp.expandCodeForPredicate(&Preds, RuntimeCheckBB->getTerminator());
auto *CI = dyn_cast<ConstantInt>(SCEVRuntimeCheck);
// Discard the SCEV runtime check if it is always true.
@@ -118,11 +118,11 @@ void LoopVersioning::versionLoop(
// Adds the necessary PHI nodes for the versioned loops based on the
// loop-defined values used outside of the loop.
addPHINodes(DefsUsedOutside);
- formDedicatedExitBlocks(NonVersionedLoop, DT, LI, nullptr, true);
- formDedicatedExitBlocks(VersionedLoop, DT, LI, nullptr, true);
- assert(NonVersionedLoop->isLoopSimplifyForm() &&
- VersionedLoop->isLoopSimplifyForm() &&
- "The versioned loops should be in simplify form.");
+ formDedicatedExitBlocks(NonVersionedLoop, DT, LI, nullptr, true);
+ formDedicatedExitBlocks(VersionedLoop, DT, LI, nullptr, true);
+ assert(NonVersionedLoop->isLoopSimplifyForm() &&
+ VersionedLoop->isLoopSimplifyForm() &&
+ "The versioned loops should be in simplify form.");
}
void LoopVersioning::addPHINodes(
@@ -254,59 +254,59 @@ void LoopVersioning::annotateInstWithNoAlias(Instruction *VersionedInst,
}
namespace {
-bool runImpl(LoopInfo *LI, function_ref<const LoopAccessInfo &(Loop &)> GetLAA,
- DominatorTree *DT, ScalarEvolution *SE) {
- // Build up a worklist of inner-loops to version. This is necessary as the
- // act of versioning a loop creates new loops and can invalidate iterators
- // across the loops.
- SmallVector<Loop *, 8> Worklist;
-
- for (Loop *TopLevelLoop : *LI)
- for (Loop *L : depth_first(TopLevelLoop))
- // We only handle inner-most loops.
- if (L->isInnermost())
- Worklist.push_back(L);
-
- // Now walk the identified inner loops.
- bool Changed = false;
- for (Loop *L : Worklist) {
- if (!L->isLoopSimplifyForm() || !L->isRotatedForm() ||
- !L->getExitingBlock())
- continue;
- const LoopAccessInfo &LAI = GetLAA(*L);
- if (!LAI.hasConvergentOp() &&
- (LAI.getNumRuntimePointerChecks() ||
- !LAI.getPSE().getUnionPredicate().isAlwaysTrue())) {
- LoopVersioning LVer(LAI, LAI.getRuntimePointerChecking()->getChecks(), L,
- LI, DT, SE);
- LVer.versionLoop();
- LVer.annotateLoopWithNoAlias();
- Changed = true;
- }
- }
-
- return Changed;
-}
-
+bool runImpl(LoopInfo *LI, function_ref<const LoopAccessInfo &(Loop &)> GetLAA,
+ DominatorTree *DT, ScalarEvolution *SE) {
+ // Build up a worklist of inner-loops to version. This is necessary as the
+ // act of versioning a loop creates new loops and can invalidate iterators
+ // across the loops.
+ SmallVector<Loop *, 8> Worklist;
+
+ for (Loop *TopLevelLoop : *LI)
+ for (Loop *L : depth_first(TopLevelLoop))
+ // We only handle inner-most loops.
+ if (L->isInnermost())
+ Worklist.push_back(L);
+
+ // Now walk the identified inner loops.
+ bool Changed = false;
+ for (Loop *L : Worklist) {
+ if (!L->isLoopSimplifyForm() || !L->isRotatedForm() ||
+ !L->getExitingBlock())
+ continue;
+ const LoopAccessInfo &LAI = GetLAA(*L);
+ if (!LAI.hasConvergentOp() &&
+ (LAI.getNumRuntimePointerChecks() ||
+ !LAI.getPSE().getUnionPredicate().isAlwaysTrue())) {
+ LoopVersioning LVer(LAI, LAI.getRuntimePointerChecking()->getChecks(), L,
+ LI, DT, SE);
+ LVer.versionLoop();
+ LVer.annotateLoopWithNoAlias();
+ Changed = true;
+ }
+ }
+
+ return Changed;
+}
+
/// Also expose this is a pass. Currently this is only used for
/// unit-testing. It adds all memchecks necessary to remove all may-aliasing
/// array accesses from the loop.
-class LoopVersioningLegacyPass : public FunctionPass {
+class LoopVersioningLegacyPass : public FunctionPass {
public:
- LoopVersioningLegacyPass() : FunctionPass(ID) {
- initializeLoopVersioningLegacyPassPass(*PassRegistry::getPassRegistry());
+ LoopVersioningLegacyPass() : FunctionPass(ID) {
+ initializeLoopVersioningLegacyPassPass(*PassRegistry::getPassRegistry());
}
bool runOnFunction(Function &F) override {
auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- auto GetLAA = [&](Loop &L) -> const LoopAccessInfo & {
- return getAnalysis<LoopAccessLegacyAnalysis>().getInfo(&L);
- };
-
+ auto GetLAA = [&](Loop &L) -> const LoopAccessInfo & {
+ return getAnalysis<LoopAccessLegacyAnalysis>().getInfo(&L);
+ };
+
auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
- return runImpl(LI, GetLAA, DT, SE);
+ return runImpl(LI, GetLAA, DT, SE);
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -325,45 +325,45 @@ public:
#define LVER_OPTION "loop-versioning"
#define DEBUG_TYPE LVER_OPTION
-char LoopVersioningLegacyPass::ID;
+char LoopVersioningLegacyPass::ID;
static const char LVer_name[] = "Loop Versioning";
-INITIALIZE_PASS_BEGIN(LoopVersioningLegacyPass, LVER_OPTION, LVer_name, false,
- false)
+INITIALIZE_PASS_BEGIN(LoopVersioningLegacyPass, LVER_OPTION, LVer_name, false,
+ false)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopAccessLegacyAnalysis)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
-INITIALIZE_PASS_END(LoopVersioningLegacyPass, LVER_OPTION, LVer_name, false,
- false)
+INITIALIZE_PASS_END(LoopVersioningLegacyPass, LVER_OPTION, LVer_name, false,
+ false)
namespace llvm {
-FunctionPass *createLoopVersioningLegacyPass() {
- return new LoopVersioningLegacyPass();
+FunctionPass *createLoopVersioningLegacyPass() {
+ return new LoopVersioningLegacyPass();
}
-
-PreservedAnalyses LoopVersioningPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
- auto &LI = AM.getResult<LoopAnalysis>(F);
- auto &TTI = AM.getResult<TargetIRAnalysis>(F);
- auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
- auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
- auto &AA = AM.getResult<AAManager>(F);
- auto &AC = AM.getResult<AssumptionAnalysis>(F);
- MemorySSA *MSSA = EnableMSSALoopDependency
- ? &AM.getResult<MemorySSAAnalysis>(F).getMSSA()
- : nullptr;
-
- auto &LAM = AM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
- auto GetLAA = [&](Loop &L) -> const LoopAccessInfo & {
- LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE,
- TLI, TTI, nullptr, MSSA};
- return LAM.getResult<LoopAccessAnalysis>(L, AR);
- };
-
- if (runImpl(&LI, GetLAA, &DT, &SE))
- return PreservedAnalyses::none();
- return PreservedAnalyses::all();
+
+PreservedAnalyses LoopVersioningPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
+ auto &LI = AM.getResult<LoopAnalysis>(F);
+ auto &TTI = AM.getResult<TargetIRAnalysis>(F);
+ auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
+ auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
+ auto &AA = AM.getResult<AAManager>(F);
+ auto &AC = AM.getResult<AssumptionAnalysis>(F);
+ MemorySSA *MSSA = EnableMSSALoopDependency
+ ? &AM.getResult<MemorySSAAnalysis>(F).getMSSA()
+ : nullptr;
+
+ auto &LAM = AM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
+ auto GetLAA = [&](Loop &L) -> const LoopAccessInfo & {
+ LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE,
+ TLI, TTI, nullptr, MSSA};
+ return LAM.getResult<LoopAccessAnalysis>(L, AR);
+ };
+
+ if (runImpl(&LI, GetLAA, &DT, &SE))
+ return PreservedAnalyses::none();
+ return PreservedAnalyses::all();
}
-} // namespace llvm
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/LowerInvoke.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/LowerInvoke.cpp
index 9f85a3ab9c..fe0ff5899d 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/LowerInvoke.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/LowerInvoke.cpp
@@ -48,7 +48,7 @@ static bool runImpl(Function &F) {
bool Changed = false;
for (BasicBlock &BB : F)
if (InvokeInst *II = dyn_cast<InvokeInst>(BB.getTerminator())) {
- SmallVector<Value *, 16> CallArgs(II->args());
+ SmallVector<Value *, 16> CallArgs(II->args());
SmallVector<OperandBundleDef, 1> OpBundles;
II->getOperandBundlesAsDefs(OpBundles);
// Insert a normal call instruction...
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/LowerSwitch.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/LowerSwitch.cpp
index 6f72afc90c..ec8d7a7074 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/LowerSwitch.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/LowerSwitch.cpp
@@ -12,7 +12,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/Utils/LowerSwitch.h"
+#include "llvm/Transforms/Utils/LowerSwitch.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -27,7 +27,7 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instructions.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/Value.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
@@ -57,9 +57,9 @@ namespace {
} // end anonymous namespace
-namespace {
+namespace {
// Return true iff R is covered by Ranges.
-bool IsInRanges(const IntRange &R, const std::vector<IntRange> &Ranges) {
+bool IsInRanges(const IntRange &R, const std::vector<IntRange> &Ranges) {
// Note: Ranges must be sorted, non-overlapping and non-adjacent.
// Find the first range whose High field is >= R.High,
@@ -70,34 +70,34 @@ bool IsInRanges(const IntRange &R, const std::vector<IntRange> &Ranges) {
return I != Ranges.end() && I->Low <= R.Low;
}
-struct CaseRange {
- ConstantInt *Low;
- ConstantInt *High;
- BasicBlock *BB;
-
- CaseRange(ConstantInt *low, ConstantInt *high, BasicBlock *bb)
- : Low(low), High(high), BB(bb) {}
-};
-
-using CaseVector = std::vector<CaseRange>;
-using CaseItr = std::vector<CaseRange>::iterator;
-
-/// The comparison function for sorting the switch case values in the vector.
-/// WARNING: Case ranges should be disjoint!
-struct CaseCmp {
- bool operator()(const CaseRange &C1, const CaseRange &C2) {
- const ConstantInt *CI1 = cast<const ConstantInt>(C1.Low);
- const ConstantInt *CI2 = cast<const ConstantInt>(C2.High);
- return CI1->getValue().slt(CI2->getValue());
+struct CaseRange {
+ ConstantInt *Low;
+ ConstantInt *High;
+ BasicBlock *BB;
+
+ CaseRange(ConstantInt *low, ConstantInt *high, BasicBlock *bb)
+ : Low(low), High(high), BB(bb) {}
+};
+
+using CaseVector = std::vector<CaseRange>;
+using CaseItr = std::vector<CaseRange>::iterator;
+
+/// The comparison function for sorting the switch case values in the vector.
+/// WARNING: Case ranges should be disjoint!
+struct CaseCmp {
+ bool operator()(const CaseRange &C1, const CaseRange &C2) {
+ const ConstantInt *CI1 = cast<const ConstantInt>(C1.Low);
+ const ConstantInt *CI2 = cast<const ConstantInt>(C2.High);
+ return CI1->getValue().slt(CI2->getValue());
}
-};
+};
/// Used for debugging purposes.
LLVM_ATTRIBUTE_USED
-raw_ostream &operator<<(raw_ostream &O, const CaseVector &C) {
+raw_ostream &operator<<(raw_ostream &O, const CaseVector &C) {
O << "[";
- for (CaseVector::const_iterator B = C.begin(), E = C.end(); B != E;) {
+ for (CaseVector::const_iterator B = C.begin(), E = C.end(); B != E;) {
O << "[" << B->Low->getValue() << ", " << B->High->getValue() << "]";
if (++B != E)
O << ", ";
@@ -116,9 +116,9 @@ raw_ostream &operator<<(raw_ostream &O, const CaseVector &C) {
/// 2) Removed if subsequent incoming values now share the same case, i.e.,
/// multiple outcome edges are condensed into one. This is necessary to keep the
/// number of phi values equal to the number of branches to SuccBB.
-void FixPhis(
- BasicBlock *SuccBB, BasicBlock *OrigBB, BasicBlock *NewBB,
- const unsigned NumMergedCases = std::numeric_limits<unsigned>::max()) {
+void FixPhis(
+ BasicBlock *SuccBB, BasicBlock *OrigBB, BasicBlock *NewBB,
+ const unsigned NumMergedCases = std::numeric_limits<unsigned>::max()) {
for (BasicBlock::iterator I = SuccBB->begin(),
IE = SuccBB->getFirstNonPHI()->getIterator();
I != IE; ++I) {
@@ -149,80 +149,80 @@ void FixPhis(
}
}
-/// Create a new leaf block for the binary lookup tree. It checks if the
-/// switch's value == the case's value. If not, then it jumps to the default
-/// branch. At this point in the tree, the value can't be another valid case
-/// value, so the jump to the "default" branch is warranted.
-BasicBlock *NewLeafBlock(CaseRange &Leaf, Value *Val, ConstantInt *LowerBound,
- ConstantInt *UpperBound, BasicBlock *OrigBlock,
- BasicBlock *Default) {
- Function *F = OrigBlock->getParent();
- BasicBlock *NewLeaf = BasicBlock::Create(Val->getContext(), "LeafBlock");
- F->getBasicBlockList().insert(++OrigBlock->getIterator(), NewLeaf);
-
- // Emit comparison
- ICmpInst *Comp = nullptr;
- if (Leaf.Low == Leaf.High) {
- // Make the seteq instruction...
- Comp =
- new ICmpInst(*NewLeaf, ICmpInst::ICMP_EQ, Val, Leaf.Low, "SwitchLeaf");
- } else {
- // Make range comparison
- if (Leaf.Low == LowerBound) {
- // Val >= Min && Val <= Hi --> Val <= Hi
- Comp = new ICmpInst(*NewLeaf, ICmpInst::ICMP_SLE, Val, Leaf.High,
- "SwitchLeaf");
- } else if (Leaf.High == UpperBound) {
- // Val <= Max && Val >= Lo --> Val >= Lo
- Comp = new ICmpInst(*NewLeaf, ICmpInst::ICMP_SGE, Val, Leaf.Low,
- "SwitchLeaf");
- } else if (Leaf.Low->isZero()) {
- // Val >= 0 && Val <= Hi --> Val <=u Hi
- Comp = new ICmpInst(*NewLeaf, ICmpInst::ICMP_ULE, Val, Leaf.High,
- "SwitchLeaf");
- } else {
- // Emit V-Lo <=u Hi-Lo
- Constant *NegLo = ConstantExpr::getNeg(Leaf.Low);
- Instruction *Add = BinaryOperator::CreateAdd(
- Val, NegLo, Val->getName() + ".off", NewLeaf);
- Constant *UpperBound = ConstantExpr::getAdd(NegLo, Leaf.High);
- Comp = new ICmpInst(*NewLeaf, ICmpInst::ICMP_ULE, Add, UpperBound,
- "SwitchLeaf");
- }
- }
-
- // Make the conditional branch...
- BasicBlock *Succ = Leaf.BB;
- BranchInst::Create(Succ, Default, Comp, NewLeaf);
-
- // If there were any PHI nodes in this successor, rewrite one entry
- // from OrigBlock to come from NewLeaf.
- for (BasicBlock::iterator I = Succ->begin(); isa<PHINode>(I); ++I) {
- PHINode *PN = cast<PHINode>(I);
- // Remove all but one incoming entries from the cluster
- uint64_t Range = Leaf.High->getSExtValue() - Leaf.Low->getSExtValue();
- for (uint64_t j = 0; j < Range; ++j) {
- PN->removeIncomingValue(OrigBlock);
- }
-
- int BlockIdx = PN->getBasicBlockIndex(OrigBlock);
- assert(BlockIdx != -1 && "Switch didn't go to this successor??");
- PN->setIncomingBlock((unsigned)BlockIdx, NewLeaf);
- }
-
- return NewLeaf;
-}
-
+/// Create a new leaf block for the binary lookup tree. It checks if the
+/// switch's value == the case's value. If not, then it jumps to the default
+/// branch. At this point in the tree, the value can't be another valid case
+/// value, so the jump to the "default" branch is warranted.
+BasicBlock *NewLeafBlock(CaseRange &Leaf, Value *Val, ConstantInt *LowerBound,
+ ConstantInt *UpperBound, BasicBlock *OrigBlock,
+ BasicBlock *Default) {
+ Function *F = OrigBlock->getParent();
+ BasicBlock *NewLeaf = BasicBlock::Create(Val->getContext(), "LeafBlock");
+ F->getBasicBlockList().insert(++OrigBlock->getIterator(), NewLeaf);
+
+ // Emit comparison
+ ICmpInst *Comp = nullptr;
+ if (Leaf.Low == Leaf.High) {
+ // Make the seteq instruction...
+ Comp =
+ new ICmpInst(*NewLeaf, ICmpInst::ICMP_EQ, Val, Leaf.Low, "SwitchLeaf");
+ } else {
+ // Make range comparison
+ if (Leaf.Low == LowerBound) {
+ // Val >= Min && Val <= Hi --> Val <= Hi
+ Comp = new ICmpInst(*NewLeaf, ICmpInst::ICMP_SLE, Val, Leaf.High,
+ "SwitchLeaf");
+ } else if (Leaf.High == UpperBound) {
+ // Val <= Max && Val >= Lo --> Val >= Lo
+ Comp = new ICmpInst(*NewLeaf, ICmpInst::ICMP_SGE, Val, Leaf.Low,
+ "SwitchLeaf");
+ } else if (Leaf.Low->isZero()) {
+ // Val >= 0 && Val <= Hi --> Val <=u Hi
+ Comp = new ICmpInst(*NewLeaf, ICmpInst::ICMP_ULE, Val, Leaf.High,
+ "SwitchLeaf");
+ } else {
+ // Emit V-Lo <=u Hi-Lo
+ Constant *NegLo = ConstantExpr::getNeg(Leaf.Low);
+ Instruction *Add = BinaryOperator::CreateAdd(
+ Val, NegLo, Val->getName() + ".off", NewLeaf);
+ Constant *UpperBound = ConstantExpr::getAdd(NegLo, Leaf.High);
+ Comp = new ICmpInst(*NewLeaf, ICmpInst::ICMP_ULE, Add, UpperBound,
+ "SwitchLeaf");
+ }
+ }
+
+ // Make the conditional branch...
+ BasicBlock *Succ = Leaf.BB;
+ BranchInst::Create(Succ, Default, Comp, NewLeaf);
+
+ // If there were any PHI nodes in this successor, rewrite one entry
+ // from OrigBlock to come from NewLeaf.
+ for (BasicBlock::iterator I = Succ->begin(); isa<PHINode>(I); ++I) {
+ PHINode *PN = cast<PHINode>(I);
+ // Remove all but one incoming entries from the cluster
+ uint64_t Range = Leaf.High->getSExtValue() - Leaf.Low->getSExtValue();
+ for (uint64_t j = 0; j < Range; ++j) {
+ PN->removeIncomingValue(OrigBlock);
+ }
+
+ int BlockIdx = PN->getBasicBlockIndex(OrigBlock);
+ assert(BlockIdx != -1 && "Switch didn't go to this successor??");
+ PN->setIncomingBlock((unsigned)BlockIdx, NewLeaf);
+ }
+
+ return NewLeaf;
+}
+
/// Convert the switch statement into a binary lookup of the case values.
/// The function recursively builds this tree. LowerBound and UpperBound are
/// used to keep track of the bounds for Val that have already been checked by
/// a block emitted by one of the previous calls to switchConvert in the call
/// stack.
-BasicBlock *SwitchConvert(CaseItr Begin, CaseItr End, ConstantInt *LowerBound,
- ConstantInt *UpperBound, Value *Val,
- BasicBlock *Predecessor, BasicBlock *OrigBlock,
- BasicBlock *Default,
- const std::vector<IntRange> &UnreachableRanges) {
+BasicBlock *SwitchConvert(CaseItr Begin, CaseItr End, ConstantInt *LowerBound,
+ ConstantInt *UpperBound, Value *Val,
+ BasicBlock *Predecessor, BasicBlock *OrigBlock,
+ BasicBlock *Default,
+ const std::vector<IntRange> &UnreachableRanges) {
assert(LowerBound && UpperBound && "Bounds must be initialized");
unsigned Size = End - Begin;
@@ -234,10 +234,10 @@ BasicBlock *SwitchConvert(CaseItr Begin, CaseItr End, ConstantInt *LowerBound,
if (Begin->Low == LowerBound && Begin->High == UpperBound) {
unsigned NumMergedCases = 0;
NumMergedCases = UpperBound->getSExtValue() - LowerBound->getSExtValue();
- FixPhis(Begin->BB, OrigBlock, Predecessor, NumMergedCases);
+ FixPhis(Begin->BB, OrigBlock, Predecessor, NumMergedCases);
return Begin->BB;
}
- return NewLeafBlock(*Begin, Val, LowerBound, UpperBound, OrigBlock,
+ return NewLeafBlock(*Begin, Val, LowerBound, UpperBound, OrigBlock,
Default);
}
@@ -284,12 +284,12 @@ BasicBlock *SwitchConvert(CaseItr Begin, CaseItr End, ConstantInt *LowerBound,
ICmpInst* Comp = new ICmpInst(ICmpInst::ICMP_SLT,
Val, Pivot.Low, "Pivot");
- BasicBlock *LBranch =
- SwitchConvert(LHS.begin(), LHS.end(), LowerBound, NewUpperBound, Val,
- NewNode, OrigBlock, Default, UnreachableRanges);
- BasicBlock *RBranch =
- SwitchConvert(RHS.begin(), RHS.end(), NewLowerBound, UpperBound, Val,
- NewNode, OrigBlock, Default, UnreachableRanges);
+ BasicBlock *LBranch =
+ SwitchConvert(LHS.begin(), LHS.end(), LowerBound, NewUpperBound, Val,
+ NewNode, OrigBlock, Default, UnreachableRanges);
+ BasicBlock *RBranch =
+ SwitchConvert(RHS.begin(), RHS.end(), NewLowerBound, UpperBound, Val,
+ NewNode, OrigBlock, Default, UnreachableRanges);
F->getBasicBlockList().insert(++OrigBlock->getIterator(), NewNode);
NewNode->getInstList().push_back(Comp);
@@ -301,7 +301,7 @@ BasicBlock *SwitchConvert(CaseItr Begin, CaseItr End, ConstantInt *LowerBound,
/// Transform simple list of \p SI's cases into list of CaseRange's \p Cases.
/// \post \p Cases wouldn't contain references to \p SI's default BB.
/// \returns Number of \p SI's cases that do not reference \p SI's default BB.
-unsigned Clusterify(CaseVector &Cases, SwitchInst *SI) {
+unsigned Clusterify(CaseVector &Cases, SwitchInst *SI) {
unsigned NumSimpleCases = 0;
// Start with "simple" cases
@@ -342,9 +342,9 @@ unsigned Clusterify(CaseVector &Cases, SwitchInst *SI) {
/// Replace the specified switch instruction with a sequence of chained if-then
/// insts in a balanced binary search.
-void ProcessSwitchInst(SwitchInst *SI,
- SmallPtrSetImpl<BasicBlock *> &DeleteList,
- AssumptionCache *AC, LazyValueInfo *LVI) {
+void ProcessSwitchInst(SwitchInst *SI,
+ SmallPtrSetImpl<BasicBlock *> &DeleteList,
+ AssumptionCache *AC, LazyValueInfo *LVI) {
BasicBlock *OrigBlock = SI->getParent();
Function *F = OrigBlock->getParent();
Value *Val = SI->getCondition(); // The value we are switching on...
@@ -369,7 +369,7 @@ void ProcessSwitchInst(SwitchInst *SI,
if (Cases.empty()) {
BranchInst::Create(Default, OrigBlock);
// Remove all the references from Default's PHIs to OrigBlock, but one.
- FixPhis(Default, OrigBlock, OrigBlock);
+ FixPhis(Default, OrigBlock, OrigBlock);
SI->eraseFromParent();
return;
}
@@ -400,7 +400,7 @@ void ProcessSwitchInst(SwitchInst *SI,
// TODO Shouldn't this create a signed range?
ConstantRange KnownBitsRange =
ConstantRange::fromKnownBits(Known, /*IsSigned=*/false);
- const ConstantRange LVIRange = LVI->getConstantRange(Val, SI);
+ const ConstantRange LVIRange = LVI->getConstantRange(Val, SI);
ConstantRange ValRange = KnownBitsRange.intersectWith(LVIRange);
// We delegate removal of unreachable non-default cases to other passes. In
// the unlikely event that some of them survived, we just conservatively
@@ -474,8 +474,8 @@ void ProcessSwitchInst(SwitchInst *SI,
// cases.
assert(MaxPop > 0 && PopSucc);
Default = PopSucc;
- llvm::erase_if(Cases,
- [PopSucc](const CaseRange &R) { return R.BB == PopSucc; });
+ llvm::erase_if(Cases,
+ [PopSucc](const CaseRange &R) { return R.BB == PopSucc; });
// If there are no cases left, just branch.
if (Cases.empty()) {
@@ -501,12 +501,12 @@ void ProcessSwitchInst(SwitchInst *SI,
BranchInst::Create(Default, NewDefault);
BasicBlock *SwitchBlock =
- SwitchConvert(Cases.begin(), Cases.end(), LowerBound, UpperBound, Val,
+ SwitchConvert(Cases.begin(), Cases.end(), LowerBound, UpperBound, Val,
OrigBlock, OrigBlock, NewDefault, UnreachableRanges);
// If there are entries in any PHI nodes for the default edge, make sure
// to update them as well.
- FixPhis(Default, OrigBlock, NewDefault);
+ FixPhis(Default, OrigBlock, NewDefault);
// Branch to our shiny new if-then stuff...
BranchInst::Create(SwitchBlock, OrigBlock);
@@ -516,84 +516,84 @@ void ProcessSwitchInst(SwitchInst *SI,
OrigBlock->getInstList().erase(SI);
// If the Default block has no more predecessors just add it to DeleteList.
- if (pred_empty(OldDefault))
+ if (pred_empty(OldDefault))
DeleteList.insert(OldDefault);
}
-
-bool LowerSwitch(Function &F, LazyValueInfo *LVI, AssumptionCache *AC) {
- bool Changed = false;
- SmallPtrSet<BasicBlock *, 8> DeleteList;
-
- for (Function::iterator I = F.begin(), E = F.end(); I != E;) {
- BasicBlock *Cur =
- &*I++; // Advance over block so we don't traverse new blocks
-
- // If the block is a dead Default block that will be deleted later, don't
- // waste time processing it.
- if (DeleteList.count(Cur))
- continue;
-
- if (SwitchInst *SI = dyn_cast<SwitchInst>(Cur->getTerminator())) {
- Changed = true;
- ProcessSwitchInst(SI, DeleteList, AC, LVI);
- }
- }
-
- for (BasicBlock *BB : DeleteList) {
- LVI->eraseBlock(BB);
- DeleteDeadBlock(BB);
- }
-
- return Changed;
-}
-
-/// Replace all SwitchInst instructions with chained branch instructions.
-class LowerSwitchLegacyPass : public FunctionPass {
-public:
- // Pass identification, replacement for typeid
- static char ID;
-
- LowerSwitchLegacyPass() : FunctionPass(ID) {
- initializeLowerSwitchLegacyPassPass(*PassRegistry::getPassRegistry());
- }
-
- bool runOnFunction(Function &F) override;
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<LazyValueInfoWrapperPass>();
- }
-};
-
-} // end anonymous namespace
-
-char LowerSwitchLegacyPass::ID = 0;
-
-// Publicly exposed interface to pass...
-char &llvm::LowerSwitchID = LowerSwitchLegacyPass::ID;
-
-INITIALIZE_PASS_BEGIN(LowerSwitchLegacyPass, "lowerswitch",
- "Lower SwitchInst's to branches", false, false)
-INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
-INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass)
-INITIALIZE_PASS_END(LowerSwitchLegacyPass, "lowerswitch",
- "Lower SwitchInst's to branches", false, false)
-
-// createLowerSwitchPass - Interface to this file...
-FunctionPass *llvm::createLowerSwitchPass() {
- return new LowerSwitchLegacyPass();
-}
-
-bool LowerSwitchLegacyPass::runOnFunction(Function &F) {
- LazyValueInfo *LVI = &getAnalysis<LazyValueInfoWrapperPass>().getLVI();
- auto *ACT = getAnalysisIfAvailable<AssumptionCacheTracker>();
- AssumptionCache *AC = ACT ? &ACT->getAssumptionCache(F) : nullptr;
- return LowerSwitch(F, LVI, AC);
-}
-
-PreservedAnalyses LowerSwitchPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- LazyValueInfo *LVI = &AM.getResult<LazyValueAnalysis>(F);
- AssumptionCache *AC = AM.getCachedResult<AssumptionAnalysis>(F);
- return LowerSwitch(F, LVI, AC) ? PreservedAnalyses::none()
- : PreservedAnalyses::all();
-}
+
+bool LowerSwitch(Function &F, LazyValueInfo *LVI, AssumptionCache *AC) {
+ bool Changed = false;
+ SmallPtrSet<BasicBlock *, 8> DeleteList;
+
+ for (Function::iterator I = F.begin(), E = F.end(); I != E;) {
+ BasicBlock *Cur =
+ &*I++; // Advance over block so we don't traverse new blocks
+
+ // If the block is a dead Default block that will be deleted later, don't
+ // waste time processing it.
+ if (DeleteList.count(Cur))
+ continue;
+
+ if (SwitchInst *SI = dyn_cast<SwitchInst>(Cur->getTerminator())) {
+ Changed = true;
+ ProcessSwitchInst(SI, DeleteList, AC, LVI);
+ }
+ }
+
+ for (BasicBlock *BB : DeleteList) {
+ LVI->eraseBlock(BB);
+ DeleteDeadBlock(BB);
+ }
+
+ return Changed;
+}
+
+/// Replace all SwitchInst instructions with chained branch instructions.
+class LowerSwitchLegacyPass : public FunctionPass {
+public:
+ // Pass identification, replacement for typeid
+ static char ID;
+
+ LowerSwitchLegacyPass() : FunctionPass(ID) {
+ initializeLowerSwitchLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool runOnFunction(Function &F) override;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<LazyValueInfoWrapperPass>();
+ }
+};
+
+} // end anonymous namespace
+
+char LowerSwitchLegacyPass::ID = 0;
+
+// Publicly exposed interface to pass...
+char &llvm::LowerSwitchID = LowerSwitchLegacyPass::ID;
+
+INITIALIZE_PASS_BEGIN(LowerSwitchLegacyPass, "lowerswitch",
+ "Lower SwitchInst's to branches", false, false)
+INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
+INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass)
+INITIALIZE_PASS_END(LowerSwitchLegacyPass, "lowerswitch",
+ "Lower SwitchInst's to branches", false, false)
+
+// createLowerSwitchPass - Interface to this file...
+FunctionPass *llvm::createLowerSwitchPass() {
+ return new LowerSwitchLegacyPass();
+}
+
+bool LowerSwitchLegacyPass::runOnFunction(Function &F) {
+ LazyValueInfo *LVI = &getAnalysis<LazyValueInfoWrapperPass>().getLVI();
+ auto *ACT = getAnalysisIfAvailable<AssumptionCacheTracker>();
+ AssumptionCache *AC = ACT ? &ACT->getAssumptionCache(F) : nullptr;
+ return LowerSwitch(F, LVI, AC);
+}
+
+PreservedAnalyses LowerSwitchPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ LazyValueInfo *LVI = &AM.getResult<LazyValueAnalysis>(F);
+ AssumptionCache *AC = AM.getCachedResult<AssumptionAnalysis>(F);
+ return LowerSwitch(F, LVI, AC) ? PreservedAnalyses::none()
+ : PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/MatrixUtils.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/MatrixUtils.cpp
index 7dea93aaa7..6a137630de 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/MatrixUtils.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/MatrixUtils.cpp
@@ -1,104 +1,104 @@
-//===- MatrixUtils.cpp - Utilities to lower matrix intrinsics ---*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Utilities for generating tiled loops for matrix operations.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Utils/MatrixUtils.h"
-#include "llvm/Analysis/DomTreeUpdater.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Type.h"
-
-using namespace llvm;
-
-BasicBlock *TileInfo::CreateLoop(BasicBlock *Preheader, BasicBlock *Exit,
- Value *Bound, Value *Step, StringRef Name,
- IRBuilderBase &B, DomTreeUpdater &DTU, Loop *L,
- LoopInfo &LI) {
- LLVMContext &Ctx = Preheader->getContext();
- BasicBlock *Header = BasicBlock::Create(
- Preheader->getContext(), Name + ".header", Preheader->getParent(), Exit);
- BasicBlock *Body = BasicBlock::Create(Header->getContext(), Name + ".body",
- Header->getParent(), Exit);
- BasicBlock *Latch = BasicBlock::Create(Header->getContext(), Name + ".latch",
- Header->getParent(), Exit);
-
- Type *I32Ty = Type::getInt64Ty(Ctx);
- BranchInst::Create(Body, Header);
- BranchInst::Create(Latch, Body);
- PHINode *IV =
- PHINode::Create(I32Ty, 2, Name + ".iv", Header->getTerminator());
- IV->addIncoming(ConstantInt::get(I32Ty, 0), Preheader);
-
- B.SetInsertPoint(Latch);
- Value *Inc = B.CreateAdd(IV, Step, Name + ".step");
- Value *Cond = B.CreateICmpNE(Inc, Bound, Name + ".cond");
- BranchInst::Create(Header, Exit, Cond, Latch);
- IV->addIncoming(Inc, Latch);
-
- BranchInst *PreheaderBr = cast<BranchInst>(Preheader->getTerminator());
- BasicBlock *Tmp = PreheaderBr->getSuccessor(0);
- PreheaderBr->setSuccessor(0, Header);
- DTU.applyUpdatesPermissive({
- {DominatorTree::Delete, Preheader, Tmp},
- {DominatorTree::Insert, Header, Body},
- {DominatorTree::Insert, Body, Latch},
- {DominatorTree::Insert, Latch, Header},
- {DominatorTree::Insert, Latch, Exit},
- {DominatorTree::Insert, Preheader, Header},
- });
-
- L->addBasicBlockToLoop(Header, LI);
- L->addBasicBlockToLoop(Body, LI);
- L->addBasicBlockToLoop(Latch, LI);
- return Body;
-}
-
-// Creates the following loop nest skeleton:
-// for C = 0; C < NumColumns; C += TileSize
-// for R = 0; R < NumRows; R += TileSize
-// for K = 0; K < Inner ; K += TileSize
-BasicBlock *TileInfo::CreateTiledLoops(BasicBlock *Start, BasicBlock *End,
- IRBuilderBase &B, DomTreeUpdater &DTU,
- LoopInfo &LI) {
- Loop *ColLoop = LI.AllocateLoop();
- Loop *RowLoop = LI.AllocateLoop();
- Loop *InnerLoop = LI.AllocateLoop();
- RowLoop->addChildLoop(InnerLoop);
- ColLoop->addChildLoop(RowLoop);
- if (Loop *ParentL = LI.getLoopFor(Start))
- ParentL->addChildLoop(ColLoop);
- else
- LI.addTopLevelLoop(ColLoop);
-
- BasicBlock *ColBody =
- CreateLoop(Start, End, B.getInt64(NumColumns), B.getInt64(TileSize),
- "cols", B, DTU, ColLoop, LI);
- BasicBlock *ColLatch = ColBody->getSingleSuccessor();
- BasicBlock *RowBody =
- CreateLoop(ColBody, ColLatch, B.getInt64(NumRows), B.getInt64(TileSize),
- "rows", B, DTU, RowLoop, LI);
- RowLoopLatch = RowBody->getSingleSuccessor();
-
- BasicBlock *InnerBody =
- CreateLoop(RowBody, RowLoopLatch, B.getInt64(NumInner),
- B.getInt64(TileSize), "inner", B, DTU, InnerLoop, LI);
- InnerLoopLatch = InnerBody->getSingleSuccessor();
- ColumnLoopHeader = ColBody->getSinglePredecessor();
- RowLoopHeader = RowBody->getSinglePredecessor();
- InnerLoopHeader = InnerBody->getSinglePredecessor();
- CurrentRow = &*RowLoopHeader->begin();
- CurrentCol = &*ColumnLoopHeader->begin();
- CurrentK = &*InnerLoopHeader->begin();
-
- return InnerBody;
-}
+//===- MatrixUtils.cpp - Utilities to lower matrix intrinsics ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities for generating tiled loops for matrix operations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Utils/MatrixUtils.h"
+#include "llvm/Analysis/DomTreeUpdater.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Type.h"
+
+using namespace llvm;
+
+BasicBlock *TileInfo::CreateLoop(BasicBlock *Preheader, BasicBlock *Exit,
+ Value *Bound, Value *Step, StringRef Name,
+ IRBuilderBase &B, DomTreeUpdater &DTU, Loop *L,
+ LoopInfo &LI) {
+ LLVMContext &Ctx = Preheader->getContext();
+ BasicBlock *Header = BasicBlock::Create(
+ Preheader->getContext(), Name + ".header", Preheader->getParent(), Exit);
+ BasicBlock *Body = BasicBlock::Create(Header->getContext(), Name + ".body",
+ Header->getParent(), Exit);
+ BasicBlock *Latch = BasicBlock::Create(Header->getContext(), Name + ".latch",
+ Header->getParent(), Exit);
+
+ Type *I32Ty = Type::getInt64Ty(Ctx);
+ BranchInst::Create(Body, Header);
+ BranchInst::Create(Latch, Body);
+ PHINode *IV =
+ PHINode::Create(I32Ty, 2, Name + ".iv", Header->getTerminator());
+ IV->addIncoming(ConstantInt::get(I32Ty, 0), Preheader);
+
+ B.SetInsertPoint(Latch);
+ Value *Inc = B.CreateAdd(IV, Step, Name + ".step");
+ Value *Cond = B.CreateICmpNE(Inc, Bound, Name + ".cond");
+ BranchInst::Create(Header, Exit, Cond, Latch);
+ IV->addIncoming(Inc, Latch);
+
+ BranchInst *PreheaderBr = cast<BranchInst>(Preheader->getTerminator());
+ BasicBlock *Tmp = PreheaderBr->getSuccessor(0);
+ PreheaderBr->setSuccessor(0, Header);
+ DTU.applyUpdatesPermissive({
+ {DominatorTree::Delete, Preheader, Tmp},
+ {DominatorTree::Insert, Header, Body},
+ {DominatorTree::Insert, Body, Latch},
+ {DominatorTree::Insert, Latch, Header},
+ {DominatorTree::Insert, Latch, Exit},
+ {DominatorTree::Insert, Preheader, Header},
+ });
+
+ L->addBasicBlockToLoop(Header, LI);
+ L->addBasicBlockToLoop(Body, LI);
+ L->addBasicBlockToLoop(Latch, LI);
+ return Body;
+}
+
+// Creates the following loop nest skeleton:
+// for C = 0; C < NumColumns; C += TileSize
+// for R = 0; R < NumRows; R += TileSize
+// for K = 0; K < Inner ; K += TileSize
+BasicBlock *TileInfo::CreateTiledLoops(BasicBlock *Start, BasicBlock *End,
+ IRBuilderBase &B, DomTreeUpdater &DTU,
+ LoopInfo &LI) {
+ Loop *ColLoop = LI.AllocateLoop();
+ Loop *RowLoop = LI.AllocateLoop();
+ Loop *InnerLoop = LI.AllocateLoop();
+ RowLoop->addChildLoop(InnerLoop);
+ ColLoop->addChildLoop(RowLoop);
+ if (Loop *ParentL = LI.getLoopFor(Start))
+ ParentL->addChildLoop(ColLoop);
+ else
+ LI.addTopLevelLoop(ColLoop);
+
+ BasicBlock *ColBody =
+ CreateLoop(Start, End, B.getInt64(NumColumns), B.getInt64(TileSize),
+ "cols", B, DTU, ColLoop, LI);
+ BasicBlock *ColLatch = ColBody->getSingleSuccessor();
+ BasicBlock *RowBody =
+ CreateLoop(ColBody, ColLatch, B.getInt64(NumRows), B.getInt64(TileSize),
+ "rows", B, DTU, RowLoop, LI);
+ RowLoopLatch = RowBody->getSingleSuccessor();
+
+ BasicBlock *InnerBody =
+ CreateLoop(RowBody, RowLoopLatch, B.getInt64(NumInner),
+ B.getInt64(TileSize), "inner", B, DTU, InnerLoop, LI);
+ InnerLoopLatch = InnerBody->getSingleSuccessor();
+ ColumnLoopHeader = ColBody->getSinglePredecessor();
+ RowLoopHeader = RowBody->getSinglePredecessor();
+ InnerLoopHeader = InnerBody->getSinglePredecessor();
+ CurrentRow = &*RowLoopHeader->begin();
+ CurrentCol = &*ColumnLoopHeader->begin();
+ CurrentK = &*InnerLoopHeader->begin();
+
+ return InnerBody;
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/MetaRenamer.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/MetaRenamer.cpp
index 4a1be618ed..e350320e75 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/MetaRenamer.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/MetaRenamer.cpp
@@ -12,7 +12,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/Utils/MetaRenamer.h"
+#include "llvm/Transforms/Utils/MetaRenamer.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
@@ -26,7 +26,7 @@
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/TypeFinder.h"
#include "llvm/InitializePasses.h"
@@ -42,125 +42,125 @@ static const char *const metaNames[] = {
};
namespace {
-// This PRNG is from the ISO C spec. It is intentionally simple and
-// unsuitable for cryptographic use. We're just looking for enough
-// variety to surprise and delight users.
-struct PRNG {
- unsigned long next;
-
- void srand(unsigned int seed) { next = seed; }
-
- int rand() {
- next = next * 1103515245 + 12345;
- return (unsigned int)(next / 65536) % 32768;
- }
-};
-
-struct Renamer {
- Renamer(unsigned int seed) { prng.srand(seed); }
-
- const char *newName() {
- return metaNames[prng.rand() % array_lengthof(metaNames)];
- }
-
- PRNG prng;
-};
-
-void MetaRename(Function &F) {
- for (auto AI = F.arg_begin(), AE = F.arg_end(); AI != AE; ++AI)
- if (!AI->getType()->isVoidTy())
- AI->setName("arg");
-
- for (auto &BB : F) {
- BB.setName("bb");
-
- for (auto &I : BB)
- if (!I.getType()->isVoidTy())
- I.setName("tmp");
- }
-}
-
-void MetaRename(Module &M,
- function_ref<TargetLibraryInfo &(Function &)> GetTLI) {
- // Seed our PRNG with simple additive sum of ModuleID. We're looking to
- // simply avoid always having the same function names, and we need to
- // remain deterministic.
- unsigned int randSeed = 0;
- for (auto C : M.getModuleIdentifier())
- randSeed += C;
-
- Renamer renamer(randSeed);
-
- // Rename all aliases
- for (auto AI = M.alias_begin(), AE = M.alias_end(); AI != AE; ++AI) {
- StringRef Name = AI->getName();
- if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1))
- continue;
-
- AI->setName("alias");
- }
-
- // Rename all global variables
- for (auto GI = M.global_begin(), GE = M.global_end(); GI != GE; ++GI) {
- StringRef Name = GI->getName();
- if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1))
- continue;
-
- GI->setName("global");
- }
-
- // Rename all struct types
- TypeFinder StructTypes;
- StructTypes.run(M, true);
- for (StructType *STy : StructTypes) {
- if (STy->isLiteral() || STy->getName().empty())
- continue;
-
- SmallString<128> NameStorage;
- STy->setName(
- (Twine("struct.") + renamer.newName()).toStringRef(NameStorage));
- }
-
- // Rename all functions
- for (auto &F : M) {
- StringRef Name = F.getName();
- LibFunc Tmp;
- // Leave library functions alone because their presence or absence could
- // affect the behavior of other passes.
- if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1) ||
- GetTLI(F).getLibFunc(F, Tmp))
- continue;
-
- // Leave @main alone. The output of -metarenamer might be passed to
- // lli for execution and the latter needs a main entry point.
- if (Name != "main")
- F.setName(renamer.newName());
-
- MetaRename(F);
- }
-}
-
-struct MetaRenamer : public ModulePass {
- // Pass identification, replacement for typeid
- static char ID;
-
- MetaRenamer() : ModulePass(ID) {
- initializeMetaRenamerPass(*PassRegistry::getPassRegistry());
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<TargetLibraryInfoWrapperPass>();
- AU.setPreservesAll();
- }
-
- bool runOnModule(Module &M) override {
- auto GetTLI = [this](Function &F) -> TargetLibraryInfo & {
- return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
- };
- MetaRename(M, GetTLI);
- return true;
- }
-};
+// This PRNG is from the ISO C spec. It is intentionally simple and
+// unsuitable for cryptographic use. We're just looking for enough
+// variety to surprise and delight users.
+struct PRNG {
+ unsigned long next;
+
+ void srand(unsigned int seed) { next = seed; }
+
+ int rand() {
+ next = next * 1103515245 + 12345;
+ return (unsigned int)(next / 65536) % 32768;
+ }
+};
+
+struct Renamer {
+ Renamer(unsigned int seed) { prng.srand(seed); }
+
+ const char *newName() {
+ return metaNames[prng.rand() % array_lengthof(metaNames)];
+ }
+
+ PRNG prng;
+};
+
+void MetaRename(Function &F) {
+ for (auto AI = F.arg_begin(), AE = F.arg_end(); AI != AE; ++AI)
+ if (!AI->getType()->isVoidTy())
+ AI->setName("arg");
+
+ for (auto &BB : F) {
+ BB.setName("bb");
+
+ for (auto &I : BB)
+ if (!I.getType()->isVoidTy())
+ I.setName("tmp");
+ }
+}
+
+void MetaRename(Module &M,
+ function_ref<TargetLibraryInfo &(Function &)> GetTLI) {
+ // Seed our PRNG with simple additive sum of ModuleID. We're looking to
+ // simply avoid always having the same function names, and we need to
+ // remain deterministic.
+ unsigned int randSeed = 0;
+ for (auto C : M.getModuleIdentifier())
+ randSeed += C;
+
+ Renamer renamer(randSeed);
+
+ // Rename all aliases
+ for (auto AI = M.alias_begin(), AE = M.alias_end(); AI != AE; ++AI) {
+ StringRef Name = AI->getName();
+ if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1))
+ continue;
+
+ AI->setName("alias");
+ }
+
+ // Rename all global variables
+ for (auto GI = M.global_begin(), GE = M.global_end(); GI != GE; ++GI) {
+ StringRef Name = GI->getName();
+ if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1))
+ continue;
+
+ GI->setName("global");
+ }
+
+ // Rename all struct types
+ TypeFinder StructTypes;
+ StructTypes.run(M, true);
+ for (StructType *STy : StructTypes) {
+ if (STy->isLiteral() || STy->getName().empty())
+ continue;
+
+ SmallString<128> NameStorage;
+ STy->setName(
+ (Twine("struct.") + renamer.newName()).toStringRef(NameStorage));
+ }
+
+ // Rename all functions
+ for (auto &F : M) {
+ StringRef Name = F.getName();
+ LibFunc Tmp;
+ // Leave library functions alone because their presence or absence could
+ // affect the behavior of other passes.
+ if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1) ||
+ GetTLI(F).getLibFunc(F, Tmp))
+ continue;
+
+ // Leave @main alone. The output of -metarenamer might be passed to
+ // lli for execution and the latter needs a main entry point.
+ if (Name != "main")
+ F.setName(renamer.newName());
+
+ MetaRename(F);
+ }
+}
+
+struct MetaRenamer : public ModulePass {
+ // Pass identification, replacement for typeid
+ static char ID;
+
+ MetaRenamer() : ModulePass(ID) {
+ initializeMetaRenamerPass(*PassRegistry::getPassRegistry());
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<TargetLibraryInfoWrapperPass>();
+ AU.setPreservesAll();
+ }
+
+ bool runOnModule(Module &M) override {
+ auto GetTLI = [this](Function &F) -> TargetLibraryInfo & {
+ return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
+ };
+ MetaRename(M, GetTLI);
+ return true;
+ }
+};
} // end anonymous namespace
@@ -179,14 +179,14 @@ INITIALIZE_PASS_END(MetaRenamer, "metarenamer",
ModulePass *llvm::createMetaRenamerPass() {
return new MetaRenamer();
}
-
-PreservedAnalyses MetaRenamerPass::run(Module &M, ModuleAnalysisManager &AM) {
- FunctionAnalysisManager &FAM =
- AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
- auto GetTLI = [&FAM](Function &F) -> TargetLibraryInfo & {
- return FAM.getResult<TargetLibraryAnalysis>(F);
- };
- MetaRename(M, GetTLI);
-
- return PreservedAnalyses::all();
-}
+
+PreservedAnalyses MetaRenamerPass::run(Module &M, ModuleAnalysisManager &AM) {
+ FunctionAnalysisManager &FAM =
+ AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+ auto GetTLI = [&FAM](Function &F) -> TargetLibraryInfo & {
+ return FAM.getResult<TargetLibraryAnalysis>(F);
+ };
+ MetaRename(M, GetTLI);
+
+ return PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/PredicateInfo.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/PredicateInfo.cpp
index b53eab4c19..3312a6f945 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/PredicateInfo.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/PredicateInfo.cpp
@@ -53,10 +53,10 @@ static cl::opt<bool> VerifyPredicateInfo(
DEBUG_COUNTER(RenameCounter, "predicateinfo-rename",
"Controls which variables are renamed with predicateinfo");
-// Maximum number of conditions considered for renaming for each branch/assume.
-// This limits renaming of deep and/or chains.
-static const unsigned MaxCondsPerBranch = 8;
-
+// Maximum number of conditions considered for renaming for each branch/assume.
+// This limits renaming of deep and/or chains.
+static const unsigned MaxCondsPerBranch = 8;
+
namespace {
// Given a predicate info that is a type of branching terminator, get the
// branching block.
@@ -371,13 +371,13 @@ void PredicateInfoBuilder::convertUsesToDFSOrdered(
}
}
-bool shouldRename(Value *V) {
- // Only want real values, not constants. Additionally, operands with one use
- // are only being used in the comparison, which means they will not be useful
- // for us to consider for predicateinfo.
- return (isa<Instruction>(V) || isa<Argument>(V)) && !V->hasOneUse();
-}
-
+bool shouldRename(Value *V) {
+ // Only want real values, not constants. Additionally, operands with one use
+ // are only being used in the comparison, which means they will not be useful
+ // for us to consider for predicateinfo.
+ return (isa<Instruction>(V) || isa<Argument>(V)) && !V->hasOneUse();
+}
+
// Collect relevant operations from Comparison that we may want to insert copies
// for.
void collectCmpOps(CmpInst *Comparison, SmallVectorImpl<Value *> &CmpOperands) {
@@ -385,9 +385,9 @@ void collectCmpOps(CmpInst *Comparison, SmallVectorImpl<Value *> &CmpOperands) {
auto *Op1 = Comparison->getOperand(1);
if (Op0 == Op1)
return;
-
- CmpOperands.push_back(Op0);
- CmpOperands.push_back(Op1);
+
+ CmpOperands.push_back(Op0);
+ CmpOperands.push_back(Op1);
}
// Add Op, PB to the list of value infos for Op, and mark Op to be renamed.
@@ -405,31 +405,31 @@ void PredicateInfoBuilder::addInfoFor(SmallVectorImpl<Value *> &OpsToRename,
void PredicateInfoBuilder::processAssume(
IntrinsicInst *II, BasicBlock *AssumeBB,
SmallVectorImpl<Value *> &OpsToRename) {
- SmallVector<Value *, 4> Worklist;
- SmallPtrSet<Value *, 4> Visited;
- Worklist.push_back(II->getOperand(0));
- while (!Worklist.empty()) {
- Value *Cond = Worklist.pop_back_val();
- if (!Visited.insert(Cond).second)
- continue;
- if (Visited.size() > MaxCondsPerBranch)
- break;
-
- Value *Op0, *Op1;
- if (match(Cond, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
- Worklist.push_back(Op1);
- Worklist.push_back(Op0);
- }
-
- SmallVector<Value *, 4> Values;
- Values.push_back(Cond);
- if (auto *Cmp = dyn_cast<CmpInst>(Cond))
- collectCmpOps(Cmp, Values);
-
- for (Value *V : Values) {
- if (shouldRename(V)) {
- auto *PA = new PredicateAssume(V, II, Cond);
- addInfoFor(OpsToRename, V, PA);
+ SmallVector<Value *, 4> Worklist;
+ SmallPtrSet<Value *, 4> Visited;
+ Worklist.push_back(II->getOperand(0));
+ while (!Worklist.empty()) {
+ Value *Cond = Worklist.pop_back_val();
+ if (!Visited.insert(Cond).second)
+ continue;
+ if (Visited.size() > MaxCondsPerBranch)
+ break;
+
+ Value *Op0, *Op1;
+ if (match(Cond, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
+ Worklist.push_back(Op1);
+ Worklist.push_back(Op0);
+ }
+
+ SmallVector<Value *, 4> Values;
+ Values.push_back(Cond);
+ if (auto *Cmp = dyn_cast<CmpInst>(Cond))
+ collectCmpOps(Cmp, Values);
+
+ for (Value *V : Values) {
+ if (shouldRename(V)) {
+ auto *PA = new PredicateAssume(V, II, Cond);
+ addInfoFor(OpsToRename, V, PA);
}
}
}
@@ -443,44 +443,44 @@ void PredicateInfoBuilder::processBranch(
BasicBlock *FirstBB = BI->getSuccessor(0);
BasicBlock *SecondBB = BI->getSuccessor(1);
- for (BasicBlock *Succ : {FirstBB, SecondBB}) {
- bool TakenEdge = Succ == FirstBB;
- // Don't try to insert on a self-edge. This is mainly because we will
- // eliminate during renaming anyway.
- if (Succ == BranchBB)
- continue;
-
- SmallVector<Value *, 4> Worklist;
- SmallPtrSet<Value *, 4> Visited;
- Worklist.push_back(BI->getCondition());
- while (!Worklist.empty()) {
- Value *Cond = Worklist.pop_back_val();
- if (!Visited.insert(Cond).second)
+ for (BasicBlock *Succ : {FirstBB, SecondBB}) {
+ bool TakenEdge = Succ == FirstBB;
+ // Don't try to insert on a self-edge. This is mainly because we will
+ // eliminate during renaming anyway.
+ if (Succ == BranchBB)
+ continue;
+
+ SmallVector<Value *, 4> Worklist;
+ SmallPtrSet<Value *, 4> Visited;
+ Worklist.push_back(BI->getCondition());
+ while (!Worklist.empty()) {
+ Value *Cond = Worklist.pop_back_val();
+ if (!Visited.insert(Cond).second)
continue;
- if (Visited.size() > MaxCondsPerBranch)
- break;
-
- Value *Op0, *Op1;
- if (TakenEdge ? match(Cond, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))
- : match(Cond, m_LogicalOr(m_Value(Op0), m_Value(Op1)))) {
- Worklist.push_back(Op1);
- Worklist.push_back(Op0);
- }
-
- SmallVector<Value *, 4> Values;
- Values.push_back(Cond);
- if (auto *Cmp = dyn_cast<CmpInst>(Cond))
- collectCmpOps(Cmp, Values);
-
- for (Value *V : Values) {
- if (shouldRename(V)) {
- PredicateBase *PB =
- new PredicateBranch(V, BranchBB, Succ, Cond, TakenEdge);
- addInfoFor(OpsToRename, V, PB);
- if (!Succ->getSinglePredecessor())
- EdgeUsesOnly.insert({BranchBB, Succ});
- }
- }
+ if (Visited.size() > MaxCondsPerBranch)
+ break;
+
+ Value *Op0, *Op1;
+ if (TakenEdge ? match(Cond, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))
+ : match(Cond, m_LogicalOr(m_Value(Op0), m_Value(Op1)))) {
+ Worklist.push_back(Op1);
+ Worklist.push_back(Op0);
+ }
+
+ SmallVector<Value *, 4> Values;
+ Values.push_back(Cond);
+ if (auto *Cmp = dyn_cast<CmpInst>(Cond))
+ collectCmpOps(Cmp, Values);
+
+ for (Value *V : Values) {
+ if (shouldRename(V)) {
+ PredicateBase *PB =
+ new PredicateBranch(V, BranchBB, Succ, Cond, TakenEdge);
+ addInfoFor(OpsToRename, V, PB);
+ if (!Succ->getSinglePredecessor())
+ EdgeUsesOnly.insert({BranchBB, Succ});
+ }
+ }
}
}
}
@@ -799,56 +799,56 @@ PredicateInfo::~PredicateInfo() {
}
}
-Optional<PredicateConstraint> PredicateBase::getConstraint() const {
- switch (Type) {
- case PT_Assume:
- case PT_Branch: {
- bool TrueEdge = true;
- if (auto *PBranch = dyn_cast<PredicateBranch>(this))
- TrueEdge = PBranch->TrueEdge;
-
- if (Condition == RenamedOp) {
- return {{CmpInst::ICMP_EQ,
- TrueEdge ? ConstantInt::getTrue(Condition->getType())
- : ConstantInt::getFalse(Condition->getType())}};
- }
-
- CmpInst *Cmp = dyn_cast<CmpInst>(Condition);
- if (!Cmp) {
- // TODO: Make this an assertion once RenamedOp is fully accurate.
- return None;
- }
-
- CmpInst::Predicate Pred;
- Value *OtherOp;
- if (Cmp->getOperand(0) == RenamedOp) {
- Pred = Cmp->getPredicate();
- OtherOp = Cmp->getOperand(1);
- } else if (Cmp->getOperand(1) == RenamedOp) {
- Pred = Cmp->getSwappedPredicate();
- OtherOp = Cmp->getOperand(0);
- } else {
- // TODO: Make this an assertion once RenamedOp is fully accurate.
- return None;
- }
-
- // Invert predicate along false edge.
- if (!TrueEdge)
- Pred = CmpInst::getInversePredicate(Pred);
-
- return {{Pred, OtherOp}};
- }
- case PT_Switch:
- if (Condition != RenamedOp) {
- // TODO: Make this an assertion once RenamedOp is fully accurate.
- return None;
- }
-
- return {{CmpInst::ICMP_EQ, cast<PredicateSwitch>(this)->CaseValue}};
- }
- llvm_unreachable("Unknown predicate type");
-}
-
+Optional<PredicateConstraint> PredicateBase::getConstraint() const {
+ switch (Type) {
+ case PT_Assume:
+ case PT_Branch: {
+ bool TrueEdge = true;
+ if (auto *PBranch = dyn_cast<PredicateBranch>(this))
+ TrueEdge = PBranch->TrueEdge;
+
+ if (Condition == RenamedOp) {
+ return {{CmpInst::ICMP_EQ,
+ TrueEdge ? ConstantInt::getTrue(Condition->getType())
+ : ConstantInt::getFalse(Condition->getType())}};
+ }
+
+ CmpInst *Cmp = dyn_cast<CmpInst>(Condition);
+ if (!Cmp) {
+ // TODO: Make this an assertion once RenamedOp is fully accurate.
+ return None;
+ }
+
+ CmpInst::Predicate Pred;
+ Value *OtherOp;
+ if (Cmp->getOperand(0) == RenamedOp) {
+ Pred = Cmp->getPredicate();
+ OtherOp = Cmp->getOperand(1);
+ } else if (Cmp->getOperand(1) == RenamedOp) {
+ Pred = Cmp->getSwappedPredicate();
+ OtherOp = Cmp->getOperand(0);
+ } else {
+ // TODO: Make this an assertion once RenamedOp is fully accurate.
+ return None;
+ }
+
+ // Invert predicate along false edge.
+ if (!TrueEdge)
+ Pred = CmpInst::getInversePredicate(Pred);
+
+ return {{Pred, OtherOp}};
+ }
+ case PT_Switch:
+ if (Condition != RenamedOp) {
+ // TODO: Make this an assertion once RenamedOp is fully accurate.
+ return None;
+ }
+
+ return {{CmpInst::ICMP_EQ, cast<PredicateSwitch>(this)->CaseValue}};
+ }
+ llvm_unreachable("Unknown predicate type");
+}
+
void PredicateInfo::verifyPredicateInfo() const {}
char PredicateInfoPrinterLegacyPass::ID = 0;
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
index 014a9db12f..86bbb6a889 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
@@ -77,19 +77,19 @@ bool llvm::isAllocaPromotable(const AllocaInst *AI) {
if (SI->isVolatile())
return false;
} else if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(U)) {
- if (!II->isLifetimeStartOrEnd() && !II->isDroppable())
+ if (!II->isLifetimeStartOrEnd() && !II->isDroppable())
return false;
} else if (const BitCastInst *BCI = dyn_cast<BitCastInst>(U)) {
- if (!onlyUsedByLifetimeMarkersOrDroppableInsts(BCI))
+ if (!onlyUsedByLifetimeMarkersOrDroppableInsts(BCI))
return false;
} else if (const GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(U)) {
if (!GEPI->hasAllZeroIndices())
return false;
- if (!onlyUsedByLifetimeMarkersOrDroppableInsts(GEPI))
+ if (!onlyUsedByLifetimeMarkersOrDroppableInsts(GEPI))
+ return false;
+ } else if (const AddrSpaceCastInst *ASCI = dyn_cast<AddrSpaceCastInst>(U)) {
+ if (!onlyUsedByLifetimeMarkers(ASCI))
return false;
- } else if (const AddrSpaceCastInst *ASCI = dyn_cast<AddrSpaceCastInst>(U)) {
- if (!onlyUsedByLifetimeMarkers(ASCI))
- return false;
} else {
return false;
}
@@ -101,8 +101,8 @@ bool llvm::isAllocaPromotable(const AllocaInst *AI) {
namespace {
struct AllocaInfo {
- using DbgUserVec = SmallVector<DbgVariableIntrinsic *, 1>;
-
+ using DbgUserVec = SmallVector<DbgVariableIntrinsic *, 1>;
+
SmallVector<BasicBlock *, 32> DefiningBlocks;
SmallVector<BasicBlock *, 32> UsingBlocks;
@@ -110,7 +110,7 @@ struct AllocaInfo {
BasicBlock *OnlyBlock;
bool OnlyUsedInOneBlock;
- DbgUserVec DbgUsers;
+ DbgUserVec DbgUsers;
void clear() {
DefiningBlocks.clear();
@@ -118,7 +118,7 @@ struct AllocaInfo {
OnlyStore = nullptr;
OnlyBlock = nullptr;
OnlyUsedInOneBlock = true;
- DbgUsers.clear();
+ DbgUsers.clear();
}
/// Scan the uses of the specified alloca, filling in the AllocaInfo used
@@ -129,8 +129,8 @@ struct AllocaInfo {
// As we scan the uses of the alloca instruction, keep track of stores,
// and decide whether all of the loads and stores to the alloca are within
// the same basic block.
- for (User *U : AI->users()) {
- Instruction *User = cast<Instruction>(U);
+ for (User *U : AI->users()) {
+ Instruction *User = cast<Instruction>(U);
if (StoreInst *SI = dyn_cast<StoreInst>(User)) {
// Remember the basic blocks which define new values for the alloca
@@ -151,7 +151,7 @@ struct AllocaInfo {
}
}
- findDbgUsers(DbgUsers, AI);
+ findDbgUsers(DbgUsers, AI);
}
};
@@ -249,7 +249,7 @@ struct PromoteMem2Reg {
/// For each alloca, we keep track of the dbg.declare intrinsic that
/// describes it, if any, so that we can convert it to a dbg.value
/// intrinsic if the alloca gets promoted.
- SmallVector<AllocaInfo::DbgUserVec, 8> AllocaDbgUsers;
+ SmallVector<AllocaInfo::DbgUserVec, 8> AllocaDbgUsers;
/// The set of basic blocks the renamer has already visited.
SmallPtrSet<BasicBlock *, 16> Visited;
@@ -309,37 +309,37 @@ static void addAssumeNonNull(AssumptionCache *AC, LoadInst *LI) {
AC->registerAssumption(CI);
}
-static void removeIntrinsicUsers(AllocaInst *AI) {
+static void removeIntrinsicUsers(AllocaInst *AI) {
// Knowing that this alloca is promotable, we know that it's safe to kill all
// instructions except for load and store.
- for (auto UI = AI->use_begin(), UE = AI->use_end(); UI != UE;) {
- Instruction *I = cast<Instruction>(UI->getUser());
- Use &U = *UI;
+ for (auto UI = AI->use_begin(), UE = AI->use_end(); UI != UE;) {
+ Instruction *I = cast<Instruction>(UI->getUser());
+ Use &U = *UI;
++UI;
if (isa<LoadInst>(I) || isa<StoreInst>(I))
continue;
- // Drop the use of AI in droppable instructions.
- if (I->isDroppable()) {
- I->dropDroppableUse(U);
- continue;
- }
-
+ // Drop the use of AI in droppable instructions.
+ if (I->isDroppable()) {
+ I->dropDroppableUse(U);
+ continue;
+ }
+
if (!I->getType()->isVoidTy()) {
// The only users of this bitcast/GEP instruction are lifetime intrinsics.
// Follow the use/def chain to erase them now instead of leaving it for
// dead code elimination later.
- for (auto UUI = I->use_begin(), UUE = I->use_end(); UUI != UUE;) {
- Instruction *Inst = cast<Instruction>(UUI->getUser());
- Use &UU = *UUI;
+ for (auto UUI = I->use_begin(), UUE = I->use_end(); UUI != UUE;) {
+ Instruction *Inst = cast<Instruction>(UUI->getUser());
+ Use &UU = *UUI;
++UUI;
-
- // Drop the use of I in droppable instructions.
- if (Inst->isDroppable()) {
- Inst->dropDroppableUse(UU);
- continue;
- }
+
+ // Drop the use of I in droppable instructions.
+ if (Inst->isDroppable()) {
+ Inst->dropDroppableUse(UU);
+ continue;
+ }
Inst->eraseFromParent();
}
}
@@ -366,8 +366,8 @@ static bool rewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info,
// Clear out UsingBlocks. We will reconstruct it here if needed.
Info.UsingBlocks.clear();
- for (User *U : make_early_inc_range(AI->users())) {
- Instruction *UserInst = cast<Instruction>(U);
+ for (User *U : make_early_inc_range(AI->users())) {
+ Instruction *UserInst = cast<Instruction>(U);
if (UserInst == OnlyStore)
continue;
LoadInst *LI = cast<LoadInst>(UserInst);
@@ -423,14 +423,14 @@ static bool rewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info,
// Record debuginfo for the store and remove the declaration's
// debuginfo.
- for (DbgVariableIntrinsic *DII : Info.DbgUsers) {
- if (DII->isAddressOfVariable()) {
- DIBuilder DIB(*AI->getModule(), /*AllowUnresolved*/ false);
- ConvertDebugDeclareToDebugValue(DII, Info.OnlyStore, DIB);
- DII->eraseFromParent();
- } else if (DII->getExpression()->startsWithDeref()) {
- DII->eraseFromParent();
- }
+ for (DbgVariableIntrinsic *DII : Info.DbgUsers) {
+ if (DII->isAddressOfVariable()) {
+ DIBuilder DIB(*AI->getModule(), /*AllowUnresolved*/ false);
+ ConvertDebugDeclareToDebugValue(DII, Info.OnlyStore, DIB);
+ DII->eraseFromParent();
+ } else if (DII->getExpression()->startsWithDeref()) {
+ DII->eraseFromParent();
+ }
}
// Remove the (now dead) store and alloca.
Info.OnlyStore->eraseFromParent();
@@ -480,8 +480,8 @@ static bool promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info,
// Walk all of the loads from this alloca, replacing them with the nearest
// store above them, if any.
- for (User *U : make_early_inc_range(AI->users())) {
- LoadInst *LI = dyn_cast<LoadInst>(U);
+ for (User *U : make_early_inc_range(AI->users())) {
+ LoadInst *LI = dyn_cast<LoadInst>(U);
if (!LI)
continue;
@@ -525,11 +525,11 @@ static bool promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info,
while (!AI->use_empty()) {
StoreInst *SI = cast<StoreInst>(AI->user_back());
// Record debuginfo for the store before removing it.
- for (DbgVariableIntrinsic *DII : Info.DbgUsers) {
- if (DII->isAddressOfVariable()) {
- DIBuilder DIB(*AI->getModule(), /*AllowUnresolved*/ false);
- ConvertDebugDeclareToDebugValue(DII, SI, DIB);
- }
+ for (DbgVariableIntrinsic *DII : Info.DbgUsers) {
+ if (DII->isAddressOfVariable()) {
+ DIBuilder DIB(*AI->getModule(), /*AllowUnresolved*/ false);
+ ConvertDebugDeclareToDebugValue(DII, SI, DIB);
+ }
}
SI->eraseFromParent();
LBI.deleteValue(SI);
@@ -538,9 +538,9 @@ static bool promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info,
AI->eraseFromParent();
// The alloca's debuginfo can be removed as well.
- for (DbgVariableIntrinsic *DII : Info.DbgUsers)
- if (DII->isAddressOfVariable() || DII->getExpression()->startsWithDeref())
- DII->eraseFromParent();
+ for (DbgVariableIntrinsic *DII : Info.DbgUsers)
+ if (DII->isAddressOfVariable() || DII->getExpression()->startsWithDeref())
+ DII->eraseFromParent();
++NumLocalPromoted;
return true;
@@ -549,7 +549,7 @@ static bool promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info,
void PromoteMem2Reg::run() {
Function &F = *DT.getRoot()->getParent();
- AllocaDbgUsers.resize(Allocas.size());
+ AllocaDbgUsers.resize(Allocas.size());
AllocaInfo Info;
LargeBlockInfo LBI;
@@ -562,7 +562,7 @@ void PromoteMem2Reg::run() {
assert(AI->getParent()->getParent() == &F &&
"All allocas should be in the same function, which is same as DF!");
- removeIntrinsicUsers(AI);
+ removeIntrinsicUsers(AI);
if (AI->use_empty()) {
// If there are no uses of the alloca, just delete it now.
@@ -607,8 +607,8 @@ void PromoteMem2Reg::run() {
}
// Remember the dbg.declare intrinsic describing this alloca, if any.
- if (!Info.DbgUsers.empty())
- AllocaDbgUsers[AllocaNum] = Info.DbgUsers;
+ if (!Info.DbgUsers.empty())
+ AllocaDbgUsers[AllocaNum] = Info.DbgUsers;
// Keep the reverse mapping of the 'Allocas' array for the rename pass.
AllocaLookup[Allocas[AllocaNum]] = AllocaNum;
@@ -681,11 +681,11 @@ void PromoteMem2Reg::run() {
}
// Remove alloca's dbg.declare instrinsics from the function.
- for (auto &DbgUsers : AllocaDbgUsers) {
- for (auto *DII : DbgUsers)
- if (DII->isAddressOfVariable() || DII->getExpression()->startsWithDeref())
- DII->eraseFromParent();
- }
+ for (auto &DbgUsers : AllocaDbgUsers) {
+ for (auto *DII : DbgUsers)
+ if (DII->isAddressOfVariable() || DII->getExpression()->startsWithDeref())
+ DII->eraseFromParent();
+ }
// Loop over all of the PHI nodes and see if there are any that we can get
// rid of because they merge all of the same incoming values. This can
@@ -740,7 +740,7 @@ void PromoteMem2Reg::run() {
continue;
// Get the preds for BB.
- SmallVector<BasicBlock *, 16> Preds(predecessors(BB));
+ SmallVector<BasicBlock *, 16> Preds(predecessors(BB));
// Ok, now we know that all of the PHI nodes are missing entries for some
// basic blocks. Start by sorting the incoming predecessors for efficient
@@ -907,7 +907,7 @@ NextIteration:
// operands so far. Remember this count.
unsigned NewPHINumOperands = APN->getNumOperands();
- unsigned NumEdges = llvm::count(successors(Pred), BB);
+ unsigned NumEdges = llvm::count(successors(Pred), BB);
assert(NumEdges && "Must be at least one edge from Pred to BB!");
// Add entries for all the phis.
@@ -925,9 +925,9 @@ NextIteration:
// The currently active variable for this block is now the PHI.
IncomingVals[AllocaNo] = APN;
- for (DbgVariableIntrinsic *DII : AllocaDbgUsers[AllocaNo])
- if (DII->isAddressOfVariable())
- ConvertDebugDeclareToDebugValue(DII, APN, DIB);
+ for (DbgVariableIntrinsic *DII : AllocaDbgUsers[AllocaNo])
+ if (DII->isAddressOfVariable())
+ ConvertDebugDeclareToDebugValue(DII, APN, DIB);
// Get the next phi node.
++PNI;
@@ -986,9 +986,9 @@ NextIteration:
// Record debuginfo for the store before removing it.
IncomingLocs[AllocaNo] = SI->getDebugLoc();
- for (DbgVariableIntrinsic *DII : AllocaDbgUsers[ai->second])
- if (DII->isAddressOfVariable())
- ConvertDebugDeclareToDebugValue(DII, SI, DIB);
+ for (DbgVariableIntrinsic *DII : AllocaDbgUsers[ai->second])
+ if (DII->isAddressOfVariable())
+ ConvertDebugDeclareToDebugValue(DII, SI, DIB);
BB->getInstList().erase(SI);
}
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/SSAUpdater.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/SSAUpdater.cpp
index ba9c371085..c210d1c460 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/SSAUpdater.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/SSAUpdater.cpp
@@ -64,7 +64,7 @@ bool SSAUpdater::HasValueForBlock(BasicBlock *BB) const {
}
Value *SSAUpdater::FindValueForBlock(BasicBlock *BB) const {
- return getAvailableVals(AV).lookup(BB);
+ return getAvailableVals(AV).lookup(BB);
}
void SSAUpdater::AddAvailableValue(BasicBlock *BB, Value *V) {
@@ -253,10 +253,10 @@ public:
// We can get our predecessor info by walking the pred_iterator list,
// but it is relatively slow. If we already have PHI nodes in this
// block, walk one of them to get the predecessor list instead.
- if (PHINode *SomePhi = dyn_cast<PHINode>(BB->begin()))
- append_range(*Preds, SomePhi->blocks());
- else
- append_range(*Preds, predecessors(BB));
+ if (PHINode *SomePhi = dyn_cast<PHINode>(BB->begin()))
+ append_range(*Preds, SomePhi->blocks());
+ else
+ append_range(*Preds, predecessors(BB));
}
/// GetUndefVal - Get an undefined value of the same type as the value
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index 75ccdd81b0..6dbfb0b61f 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -27,7 +27,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Utils/LoopUtils.h"
+#include "llvm/Transforms/Utils/LoopUtils.h"
using namespace llvm;
@@ -39,7 +39,7 @@ cl::opt<unsigned> llvm::SCEVCheapExpansionBudget(
using namespace PatternMatch;
/// ReuseOrCreateCast - Arrange for there to be a cast of V to Ty at IP,
-/// reusing an existing cast if a suitable one (= dominating IP) exists, or
+/// reusing an existing cast if a suitable one (= dominating IP) exists, or
/// creating a new one.
Value *SCEVExpander::ReuseOrCreateCast(Value *V, Type *Ty,
Instruction::CastOps Op,
@@ -58,27 +58,27 @@ Value *SCEVExpander::ReuseOrCreateCast(Value *V, Type *Ty,
Instruction *Ret = nullptr;
// Check to see if there is already a cast!
- for (User *U : V->users()) {
- if (U->getType() != Ty)
- continue;
- CastInst *CI = dyn_cast<CastInst>(U);
- if (!CI || CI->getOpcode() != Op)
- continue;
-
- // Found a suitable cast that is at IP or comes before IP. Use it. Note that
- // the cast must also properly dominate the Builder's insertion point.
- if (IP->getParent() == CI->getParent() && &*BIP != CI &&
- (&*IP == CI || CI->comesBefore(&*IP))) {
- Ret = CI;
- break;
- }
- }
-
+ for (User *U : V->users()) {
+ if (U->getType() != Ty)
+ continue;
+ CastInst *CI = dyn_cast<CastInst>(U);
+ if (!CI || CI->getOpcode() != Op)
+ continue;
+
+ // Found a suitable cast that is at IP or comes before IP. Use it. Note that
+ // the cast must also properly dominate the Builder's insertion point.
+ if (IP->getParent() == CI->getParent() && &*BIP != CI &&
+ (&*IP == CI || CI->comesBefore(&*IP))) {
+ Ret = CI;
+ break;
+ }
+ }
+
// Create a new cast.
- if (!Ret) {
+ if (!Ret) {
Ret = CastInst::Create(Op, V, Ty, V->getName(), &*IP);
- rememberInstruction(Ret);
- }
+ rememberInstruction(Ret);
+ }
// We assert at the end of the function since IP might point to an
// instruction with different dominance properties than a cast
@@ -88,8 +88,8 @@ Value *SCEVExpander::ReuseOrCreateCast(Value *V, Type *Ty,
return Ret;
}
-BasicBlock::iterator
-SCEVExpander::findInsertPointAfter(Instruction *I, Instruction *MustDominate) {
+BasicBlock::iterator
+SCEVExpander::findInsertPointAfter(Instruction *I, Instruction *MustDominate) {
BasicBlock::iterator IP = ++I->getIterator();
if (auto *II = dyn_cast<InvokeInst>(I))
IP = II->getNormalDest()->begin();
@@ -100,17 +100,17 @@ SCEVExpander::findInsertPointAfter(Instruction *I, Instruction *MustDominate) {
if (isa<FuncletPadInst>(IP) || isa<LandingPadInst>(IP)) {
++IP;
} else if (isa<CatchSwitchInst>(IP)) {
- IP = MustDominate->getParent()->getFirstInsertionPt();
+ IP = MustDominate->getParent()->getFirstInsertionPt();
} else {
assert(!IP->isEHPad() && "unexpected eh pad!");
}
- // Adjust insert point to be after instructions inserted by the expander, so
- // we can re-use already inserted instructions. Avoid skipping past the
- // original \p MustDominate, in case it is an inserted instruction.
- while (isInsertedInstruction(&*IP) && &*IP != MustDominate)
- ++IP;
-
+ // Adjust insert point to be after instructions inserted by the expander, so
+ // we can re-use already inserted instructions. Avoid skipping past the
+ // original \p MustDominate, in case it is an inserted instruction.
+ while (isInsertedInstruction(&*IP) && &*IP != MustDominate)
+ ++IP;
+
return IP;
}
@@ -126,22 +126,22 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, Type *Ty) {
assert(SE.getTypeSizeInBits(V->getType()) == SE.getTypeSizeInBits(Ty) &&
"InsertNoopCastOfTo cannot change sizes!");
- // inttoptr only works for integral pointers. For non-integral pointers, we
- // can create a GEP on i8* null with the integral value as index. Note that
- // it is safe to use GEP of null instead of inttoptr here, because only
- // expressions already based on a GEP of null should be converted to pointers
- // during expansion.
- if (Op == Instruction::IntToPtr) {
- auto *PtrTy = cast<PointerType>(Ty);
- if (DL.isNonIntegralPointerType(PtrTy)) {
- auto *Int8PtrTy = Builder.getInt8PtrTy(PtrTy->getAddressSpace());
- assert(DL.getTypeAllocSize(Int8PtrTy->getElementType()) == 1 &&
- "alloc size of i8 must by 1 byte for the GEP to be correct");
- auto *GEP = Builder.CreateGEP(
- Builder.getInt8Ty(), Constant::getNullValue(Int8PtrTy), V, "uglygep");
- return Builder.CreateBitCast(GEP, Ty);
- }
- }
+ // inttoptr only works for integral pointers. For non-integral pointers, we
+ // can create a GEP on i8* null with the integral value as index. Note that
+ // it is safe to use GEP of null instead of inttoptr here, because only
+ // expressions already based on a GEP of null should be converted to pointers
+ // during expansion.
+ if (Op == Instruction::IntToPtr) {
+ auto *PtrTy = cast<PointerType>(Ty);
+ if (DL.isNonIntegralPointerType(PtrTy)) {
+ auto *Int8PtrTy = Builder.getInt8PtrTy(PtrTy->getAddressSpace());
+ assert(DL.getTypeAllocSize(Int8PtrTy->getElementType()) == 1 &&
+ "alloc size of i8 must by 1 byte for the GEP to be correct");
+ auto *GEP = Builder.CreateGEP(
+ Builder.getInt8Ty(), Constant::getNullValue(Int8PtrTy), V, "uglygep");
+ return Builder.CreateBitCast(GEP, Ty);
+ }
+ }
// Short-circuit unnecessary bitcasts.
if (Op == Instruction::BitCast) {
if (V->getType() == Ty)
@@ -186,7 +186,7 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, Type *Ty) {
// Cast the instruction immediately after the instruction.
Instruction *I = cast<Instruction>(V);
- BasicBlock::iterator IP = findInsertPointAfter(I, &*Builder.GetInsertPoint());
+ BasicBlock::iterator IP = findInsertPointAfter(I, &*Builder.GetInsertPoint());
return ReuseOrCreateCast(I, Ty, Op, IP);
}
@@ -309,7 +309,7 @@ static bool FactorOutConstant(const SCEV *&S, const SCEV *&Remainder,
if (const SCEVConstant *FC = dyn_cast<SCEVConstant>(Factor))
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(M->getOperand(0)))
if (!C->getAPInt().srem(FC->getAPInt())) {
- SmallVector<const SCEV *, 4> NewMulOps(M->operands());
+ SmallVector<const SCEV *, 4> NewMulOps(M->operands());
NewMulOps[0] = SE.getConstant(C->getAPInt().sdiv(FC->getAPInt()));
S = SE.getMulExpr(NewMulOps);
return true;
@@ -481,10 +481,10 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
// we didn't find any operands that could be factored, tentatively
// assume that element zero was selected (since the zero offset
// would obviously be folded away).
- Value *Scaled =
- ScaledOps.empty()
- ? Constant::getNullValue(Ty)
- : expandCodeForImpl(SE.getAddExpr(ScaledOps), Ty, false);
+ Value *Scaled =
+ ScaledOps.empty()
+ ? Constant::getNullValue(Ty)
+ : expandCodeForImpl(SE.getAddExpr(ScaledOps), Ty, false);
GepIndices.push_back(Scaled);
// Collect struct field index operands.
@@ -543,7 +543,7 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
SE.DT.dominates(cast<Instruction>(V), &*Builder.GetInsertPoint()));
// Expand the operands for a plain byte offset.
- Value *Idx = expandCodeForImpl(SE.getAddExpr(Ops), Ty, false);
+ Value *Idx = expandCodeForImpl(SE.getAddExpr(Ops), Ty, false);
// Fold a GEP with constant operands.
if (Constant *CLHS = dyn_cast<Constant>(V))
@@ -584,7 +584,7 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
}
// Emit a GEP.
- return Builder.CreateGEP(Builder.getInt8Ty(), V, Idx, "uglygep");
+ return Builder.CreateGEP(Builder.getInt8Ty(), V, Idx, "uglygep");
}
{
@@ -764,14 +764,14 @@ Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) {
Sum = expandAddToGEP(NewOps.begin(), NewOps.end(), PTy, Ty, expand(Op));
} else if (Op->isNonConstantNegative()) {
// Instead of doing a negate and add, just do a subtract.
- Value *W = expandCodeForImpl(SE.getNegativeSCEV(Op), Ty, false);
+ Value *W = expandCodeForImpl(SE.getNegativeSCEV(Op), Ty, false);
Sum = InsertNoopCastOfTo(Sum, Ty);
Sum = InsertBinop(Instruction::Sub, Sum, W, SCEV::FlagAnyWrap,
/*IsSafeToHoist*/ true);
++I;
} else {
// A simple add.
- Value *W = expandCodeForImpl(Op, Ty, false);
+ Value *W = expandCodeForImpl(Op, Ty, false);
Sum = InsertNoopCastOfTo(Sum, Ty);
// Canonicalize a constant to the RHS.
if (isa<Constant>(Sum)) std::swap(Sum, W);
@@ -823,7 +823,7 @@ Value *SCEVExpander::visitMulExpr(const SCEVMulExpr *S) {
// Calculate powers with exponents 1, 2, 4, 8 etc. and include those of them
// that are needed into the result.
- Value *P = expandCodeForImpl(I->second, Ty, false);
+ Value *P = expandCodeForImpl(I->second, Ty, false);
Value *Result = nullptr;
if (Exponent & 1)
Result = P;
@@ -882,7 +882,7 @@ Value *SCEVExpander::visitMulExpr(const SCEVMulExpr *S) {
Value *SCEVExpander::visitUDivExpr(const SCEVUDivExpr *S) {
Type *Ty = SE.getEffectiveSCEVType(S->getType());
- Value *LHS = expandCodeForImpl(S->getLHS(), Ty, false);
+ Value *LHS = expandCodeForImpl(S->getLHS(), Ty, false);
if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(S->getRHS())) {
const APInt &RHS = SC->getAPInt();
if (RHS.isPowerOf2())
@@ -891,7 +891,7 @@ Value *SCEVExpander::visitUDivExpr(const SCEVUDivExpr *S) {
SCEV::FlagAnyWrap, /*IsSafeToHoist*/ true);
}
- Value *RHS = expandCodeForImpl(S->getRHS(), Ty, false);
+ Value *RHS = expandCodeForImpl(S->getRHS(), Ty, false);
return InsertBinop(Instruction::UDiv, LHS, RHS, SCEV::FlagAnyWrap,
/*IsSafeToHoist*/ SE.isKnownNonZero(S->getRHS()));
}
@@ -911,7 +911,7 @@ static void ExposePointerBase(const SCEV *&Base, const SCEV *&Rest,
}
if (const SCEVAddExpr *A = dyn_cast<SCEVAddExpr>(Base)) {
Base = A->getOperand(A->getNumOperands()-1);
- SmallVector<const SCEV *, 8> NewAddOps(A->operands());
+ SmallVector<const SCEV *, 8> NewAddOps(A->operands());
NewAddOps.back() = Rest;
Rest = SE.getAddExpr(NewAddOps);
ExposePointerBase(Base, Rest, SE);
@@ -1089,7 +1089,7 @@ Value *SCEVExpander::expandIVInc(PHINode *PN, Value *StepV, const Loop *L,
GEPPtrTy = PointerType::get(Type::getInt1Ty(SE.getContext()),
GEPPtrTy->getAddressSpace());
IncV = expandAddToGEP(SE.getSCEV(StepV), GEPPtrTy, IntTy, PN);
- if (IncV->getType() != PN->getType())
+ if (IncV->getType() != PN->getType())
IncV = Builder.CreateBitCast(IncV, PN->getType());
} else {
IncV = useSubtract ?
@@ -1206,14 +1206,14 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
if (!SE.isSCEVable(PN.getType()))
continue;
- // We should not look for a incomplete PHI. Getting SCEV for a incomplete
- // PHI has no meaning at all.
- if (!PN.isComplete()) {
- DEBUG_WITH_TYPE(
- DebugType, dbgs() << "One incomplete PHI is found: " << PN << "\n");
- continue;
- }
-
+ // We should not look for a incomplete PHI. Getting SCEV for a incomplete
+ // PHI has no meaning at all.
+ if (!PN.isComplete()) {
+ DEBUG_WITH_TYPE(
+ DebugType, dbgs() << "One incomplete PHI is found: " << PN << "\n");
+ continue;
+ }
+
const SCEVAddRecExpr *PhiSCEV = dyn_cast<SCEVAddRecExpr>(SE.getSCEV(&PN));
if (!PhiSCEV)
continue;
@@ -1274,9 +1274,9 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
InsertedValues.insert(AddRecPhiMatch);
// Remember the increment.
rememberInstruction(IncV);
- // Those values were not actually inserted but re-used.
- ReusedValues.insert(AddRecPhiMatch);
- ReusedValues.insert(IncV);
+ // Those values were not actually inserted but re-used.
+ ReusedValues.insert(AddRecPhiMatch);
+ ReusedValues.insert(IncV);
return AddRecPhiMatch;
}
}
@@ -1297,9 +1297,9 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
// Expand code for the start value into the loop preheader.
assert(L->getLoopPreheader() &&
"Can't expand add recurrences without a loop preheader!");
- Value *StartV =
- expandCodeForImpl(Normalized->getStart(), ExpandTy,
- L->getLoopPreheader()->getTerminator(), false);
+ Value *StartV =
+ expandCodeForImpl(Normalized->getStart(), ExpandTy,
+ L->getLoopPreheader()->getTerminator(), false);
// StartV must have been be inserted into L's preheader to dominate the new
// phi.
@@ -1317,8 +1317,8 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
if (useSubtract)
Step = SE.getNegativeSCEV(Step);
// Expand the step somewhere that dominates the loop header.
- Value *StepV = expandCodeForImpl(
- Step, IntTy, &*L->getHeader()->getFirstInsertionPt(), false);
+ Value *StepV = expandCodeForImpl(
+ Step, IntTy, &*L->getHeader()->getFirstInsertionPt(), false);
// The no-wrap behavior proved by IsIncrement(NUW|NSW) is only applicable if
// we actually do emit an addition. It does not apply if we emit a
@@ -1440,17 +1440,17 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
assert(LatchBlock && "PostInc mode requires a unique loop latch!");
Result = PN->getIncomingValueForBlock(LatchBlock);
- // We might be introducing a new use of the post-inc IV that is not poison
- // safe, in which case we should drop poison generating flags. Only keep
- // those flags for which SCEV has proven that they always hold.
- if (isa<OverflowingBinaryOperator>(Result)) {
- auto *I = cast<Instruction>(Result);
- if (!S->hasNoUnsignedWrap())
- I->setHasNoUnsignedWrap(false);
- if (!S->hasNoSignedWrap())
- I->setHasNoSignedWrap(false);
- }
-
+ // We might be introducing a new use of the post-inc IV that is not poison
+ // safe, in which case we should drop poison generating flags. Only keep
+ // those flags for which SCEV has proven that they always hold.
+ if (isa<OverflowingBinaryOperator>(Result)) {
+ auto *I = cast<Instruction>(Result);
+ if (!S->hasNoUnsignedWrap())
+ I->setHasNoUnsignedWrap(false);
+ if (!S->hasNoSignedWrap())
+ I->setHasNoSignedWrap(false);
+ }
+
// For an expansion to use the postinc form, the client must call
// expandCodeFor with an InsertPoint that is either outside the PostIncLoop
// or dominated by IVIncInsertPos.
@@ -1474,8 +1474,8 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
{
// Expand the step somewhere that dominates the loop header.
SCEVInsertPointGuard Guard(Builder, this);
- StepV = expandCodeForImpl(
- Step, IntTy, &*L->getHeader()->getFirstInsertionPt(), false);
+ StepV = expandCodeForImpl(
+ Step, IntTy, &*L->getHeader()->getFirstInsertionPt(), false);
}
Result = expandIVInc(PN, StepV, L, ExpandTy, IntTy, useSubtract);
}
@@ -1489,13 +1489,13 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
if (ResTy != SE.getEffectiveSCEVType(ResTy))
Result = InsertNoopCastOfTo(Result, SE.getEffectiveSCEVType(ResTy));
// Truncate the result.
- if (TruncTy != Result->getType())
+ if (TruncTy != Result->getType())
Result = Builder.CreateTrunc(Result, TruncTy);
-
+
// Invert the result.
- if (InvertStep)
- Result = Builder.CreateSub(
- expandCodeForImpl(Normalized->getStart(), TruncTy, false), Result);
+ if (InvertStep)
+ Result = Builder.CreateSub(
+ expandCodeForImpl(Normalized->getStart(), TruncTy, false), Result);
}
// Re-apply any non-loop-dominating scale.
@@ -1503,22 +1503,22 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
assert(S->isAffine() && "Can't linearly scale non-affine recurrences.");
Result = InsertNoopCastOfTo(Result, IntTy);
Result = Builder.CreateMul(Result,
- expandCodeForImpl(PostLoopScale, IntTy, false));
+ expandCodeForImpl(PostLoopScale, IntTy, false));
}
// Re-apply any non-loop-dominating offset.
if (PostLoopOffset) {
if (PointerType *PTy = dyn_cast<PointerType>(ExpandTy)) {
if (Result->getType()->isIntegerTy()) {
- Value *Base = expandCodeForImpl(PostLoopOffset, ExpandTy, false);
+ Value *Base = expandCodeForImpl(PostLoopOffset, ExpandTy, false);
Result = expandAddToGEP(SE.getUnknown(Result), PTy, IntTy, Base);
} else {
Result = expandAddToGEP(PostLoopOffset, PTy, IntTy, Result);
}
} else {
Result = InsertNoopCastOfTo(Result, IntTy);
- Result = Builder.CreateAdd(
- Result, expandCodeForImpl(PostLoopOffset, IntTy, false));
+ Result = Builder.CreateAdd(
+ Result, expandCodeForImpl(PostLoopOffset, IntTy, false));
}
}
@@ -1559,15 +1559,15 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
Value *V = expand(SE.getAddRecExpr(NewOps, S->getLoop(),
S->getNoWrapFlags(SCEV::FlagNW)));
BasicBlock::iterator NewInsertPt =
- findInsertPointAfter(cast<Instruction>(V), &*Builder.GetInsertPoint());
- V = expandCodeForImpl(SE.getTruncateExpr(SE.getUnknown(V), Ty), nullptr,
- &*NewInsertPt, false);
+ findInsertPointAfter(cast<Instruction>(V), &*Builder.GetInsertPoint());
+ V = expandCodeForImpl(SE.getTruncateExpr(SE.getUnknown(V), Ty), nullptr,
+ &*NewInsertPt, false);
return V;
}
// {X,+,F} --> X + {0,+,F}
if (!S->getStart()->isZero()) {
- SmallVector<const SCEV *, 4> NewOps(S->operands());
+ SmallVector<const SCEV *, 4> NewOps(S->operands());
NewOps[0] = SE.getConstant(Ty, 0);
const SCEV *Rest = SE.getAddRecExpr(NewOps, L,
S->getNoWrapFlags(SCEV::FlagNW));
@@ -1674,34 +1674,34 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
return expand(T);
}
-Value *SCEVExpander::visitPtrToIntExpr(const SCEVPtrToIntExpr *S) {
- Value *V =
- expandCodeForImpl(S->getOperand(), S->getOperand()->getType(), false);
- return Builder.CreatePtrToInt(V, S->getType());
-}
-
+Value *SCEVExpander::visitPtrToIntExpr(const SCEVPtrToIntExpr *S) {
+ Value *V =
+ expandCodeForImpl(S->getOperand(), S->getOperand()->getType(), false);
+ return Builder.CreatePtrToInt(V, S->getType());
+}
+
Value *SCEVExpander::visitTruncateExpr(const SCEVTruncateExpr *S) {
Type *Ty = SE.getEffectiveSCEVType(S->getType());
- Value *V = expandCodeForImpl(
- S->getOperand(), SE.getEffectiveSCEVType(S->getOperand()->getType()),
- false);
- return Builder.CreateTrunc(V, Ty);
+ Value *V = expandCodeForImpl(
+ S->getOperand(), SE.getEffectiveSCEVType(S->getOperand()->getType()),
+ false);
+ return Builder.CreateTrunc(V, Ty);
}
Value *SCEVExpander::visitZeroExtendExpr(const SCEVZeroExtendExpr *S) {
Type *Ty = SE.getEffectiveSCEVType(S->getType());
- Value *V = expandCodeForImpl(
- S->getOperand(), SE.getEffectiveSCEVType(S->getOperand()->getType()),
- false);
- return Builder.CreateZExt(V, Ty);
+ Value *V = expandCodeForImpl(
+ S->getOperand(), SE.getEffectiveSCEVType(S->getOperand()->getType()),
+ false);
+ return Builder.CreateZExt(V, Ty);
}
Value *SCEVExpander::visitSignExtendExpr(const SCEVSignExtendExpr *S) {
Type *Ty = SE.getEffectiveSCEVType(S->getType());
- Value *V = expandCodeForImpl(
- S->getOperand(), SE.getEffectiveSCEVType(S->getOperand()->getType()),
- false);
- return Builder.CreateSExt(V, Ty);
+ Value *V = expandCodeForImpl(
+ S->getOperand(), SE.getEffectiveSCEVType(S->getOperand()->getType()),
+ false);
+ return Builder.CreateSExt(V, Ty);
}
Value *SCEVExpander::visitSMaxExpr(const SCEVSMaxExpr *S) {
@@ -1715,7 +1715,7 @@ Value *SCEVExpander::visitSMaxExpr(const SCEVSMaxExpr *S) {
Ty = SE.getEffectiveSCEVType(Ty);
LHS = InsertNoopCastOfTo(LHS, Ty);
}
- Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
+ Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
Value *ICmp = Builder.CreateICmpSGT(LHS, RHS);
Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "smax");
LHS = Sel;
@@ -1738,7 +1738,7 @@ Value *SCEVExpander::visitUMaxExpr(const SCEVUMaxExpr *S) {
Ty = SE.getEffectiveSCEVType(Ty);
LHS = InsertNoopCastOfTo(LHS, Ty);
}
- Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
+ Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
Value *ICmp = Builder.CreateICmpUGT(LHS, RHS);
Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "umax");
LHS = Sel;
@@ -1761,7 +1761,7 @@ Value *SCEVExpander::visitSMinExpr(const SCEVSMinExpr *S) {
Ty = SE.getEffectiveSCEVType(Ty);
LHS = InsertNoopCastOfTo(LHS, Ty);
}
- Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
+ Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
Value *ICmp = Builder.CreateICmpSLT(LHS, RHS);
Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "smin");
LHS = Sel;
@@ -1784,7 +1784,7 @@ Value *SCEVExpander::visitUMinExpr(const SCEVUMinExpr *S) {
Ty = SE.getEffectiveSCEVType(Ty);
LHS = InsertNoopCastOfTo(LHS, Ty);
}
- Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
+ Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
Value *ICmp = Builder.CreateICmpULT(LHS, RHS);
Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "umin");
LHS = Sel;
@@ -1796,45 +1796,45 @@ Value *SCEVExpander::visitUMinExpr(const SCEVUMinExpr *S) {
return LHS;
}
-Value *SCEVExpander::expandCodeForImpl(const SCEV *SH, Type *Ty,
- Instruction *IP, bool Root) {
+Value *SCEVExpander::expandCodeForImpl(const SCEV *SH, Type *Ty,
+ Instruction *IP, bool Root) {
setInsertPoint(IP);
- Value *V = expandCodeForImpl(SH, Ty, Root);
- return V;
+ Value *V = expandCodeForImpl(SH, Ty, Root);
+ return V;
}
-Value *SCEVExpander::expandCodeForImpl(const SCEV *SH, Type *Ty, bool Root) {
+Value *SCEVExpander::expandCodeForImpl(const SCEV *SH, Type *Ty, bool Root) {
// Expand the code for this SCEV.
Value *V = expand(SH);
-
- if (PreserveLCSSA) {
- if (auto *Inst = dyn_cast<Instruction>(V)) {
- // Create a temporary instruction to at the current insertion point, so we
- // can hand it off to the helper to create LCSSA PHIs if required for the
- // new use.
- // FIXME: Ideally formLCSSAForInstructions (used in fixupLCSSAFormFor)
- // would accept a insertion point and return an LCSSA phi for that
- // insertion point, so there is no need to insert & remove the temporary
- // instruction.
- Instruction *Tmp;
- if (Inst->getType()->isIntegerTy())
- Tmp =
- cast<Instruction>(Builder.CreateAdd(Inst, Inst, "tmp.lcssa.user"));
- else {
- assert(Inst->getType()->isPointerTy());
- Tmp = cast<Instruction>(
- Builder.CreateGEP(Inst, Builder.getInt32(1), "tmp.lcssa.user"));
- }
- V = fixupLCSSAFormFor(Tmp, 0);
-
- // Clean up temporary instruction.
- InsertedValues.erase(Tmp);
- InsertedPostIncValues.erase(Tmp);
- Tmp->eraseFromParent();
- }
- }
-
- InsertedExpressions[std::make_pair(SH, &*Builder.GetInsertPoint())] = V;
+
+ if (PreserveLCSSA) {
+ if (auto *Inst = dyn_cast<Instruction>(V)) {
+ // Create a temporary instruction to at the current insertion point, so we
+ // can hand it off to the helper to create LCSSA PHIs if required for the
+ // new use.
+ // FIXME: Ideally formLCSSAForInstructions (used in fixupLCSSAFormFor)
+ // would accept a insertion point and return an LCSSA phi for that
+ // insertion point, so there is no need to insert & remove the temporary
+ // instruction.
+ Instruction *Tmp;
+ if (Inst->getType()->isIntegerTy())
+ Tmp =
+ cast<Instruction>(Builder.CreateAdd(Inst, Inst, "tmp.lcssa.user"));
+ else {
+ assert(Inst->getType()->isPointerTy());
+ Tmp = cast<Instruction>(
+ Builder.CreateGEP(Inst, Builder.getInt32(1), "tmp.lcssa.user"));
+ }
+ V = fixupLCSSAFormFor(Tmp, 0);
+
+ // Clean up temporary instruction.
+ InsertedValues.erase(Tmp);
+ InsertedPostIncValues.erase(Tmp);
+ Tmp->eraseFromParent();
+ }
+ }
+
+ InsertedExpressions[std::make_pair(SH, &*Builder.GetInsertPoint())] = V;
if (Ty) {
assert(SE.getTypeSizeInBits(Ty) == SE.getTypeSizeInBits(SH->getType()) &&
"non-trivial casts should be done with the SCEVs directly!");
@@ -1918,12 +1918,12 @@ Value *SCEVExpander::expand(const SCEV *S) {
// there) so that it is guaranteed to dominate any user inside the loop.
if (L && SE.hasComputableLoopEvolution(S, L) && !PostIncLoops.count(L))
InsertPt = &*L->getHeader()->getFirstInsertionPt();
-
+
while (InsertPt->getIterator() != Builder.GetInsertPoint() &&
(isInsertedInstruction(InsertPt) ||
- isa<DbgInfoIntrinsic>(InsertPt))) {
+ isa<DbgInfoIntrinsic>(InsertPt))) {
InsertPt = &*std::next(InsertPt->getIterator());
- }
+ }
break;
}
}
@@ -1976,25 +1976,25 @@ Value *SCEVExpander::expand(const SCEV *S) {
}
void SCEVExpander::rememberInstruction(Value *I) {
- auto DoInsert = [this](Value *V) {
- if (!PostIncLoops.empty())
- InsertedPostIncValues.insert(V);
- else
- InsertedValues.insert(V);
- };
- DoInsert(I);
-
- if (!PreserveLCSSA)
- return;
-
- if (auto *Inst = dyn_cast<Instruction>(I)) {
- // A new instruction has been added, which might introduce new uses outside
- // a defining loop. Fix LCSSA from for each operand of the new instruction,
- // if required.
- for (unsigned OpIdx = 0, OpEnd = Inst->getNumOperands(); OpIdx != OpEnd;
- OpIdx++)
- fixupLCSSAFormFor(Inst, OpIdx);
- }
+ auto DoInsert = [this](Value *V) {
+ if (!PostIncLoops.empty())
+ InsertedPostIncValues.insert(V);
+ else
+ InsertedValues.insert(V);
+ };
+ DoInsert(I);
+
+ if (!PreserveLCSSA)
+ return;
+
+ if (auto *Inst = dyn_cast<Instruction>(I)) {
+ // A new instruction has been added, which might introduce new uses outside
+ // a defining loop. Fix LCSSA from for each operand of the new instruction,
+ // if required.
+ for (unsigned OpIdx = 0, OpEnd = Inst->getNumOperands(); OpIdx != OpEnd;
+ OpIdx++)
+ fixupLCSSAFormFor(Inst, OpIdx);
+ }
}
/// replaceCongruentIVs - Check for congruent phis in this loop header and
@@ -2017,8 +2017,8 @@ SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT,
// Put pointers at the back and make sure pointer < pointer = false.
if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
return RHS->getType()->isIntegerTy() && !LHS->getType()->isIntegerTy();
- return RHS->getType()->getPrimitiveSizeInBits().getFixedSize() <
- LHS->getType()->getPrimitiveSizeInBits().getFixedSize();
+ return RHS->getType()->getPrimitiveSizeInBits().getFixedSize() <
+ LHS->getType()->getPrimitiveSizeInBits().getFixedSize();
});
unsigned NumElim = 0;
@@ -2126,8 +2126,8 @@ SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT,
}
DEBUG_WITH_TYPE(DebugType, dbgs() << "INDVARS: Eliminated congruent iv: "
<< *Phi << '\n');
- DEBUG_WITH_TYPE(DebugType, dbgs() << "INDVARS: Original iv: "
- << *OrigPhiRef << '\n');
+ DEBUG_WITH_TYPE(DebugType, dbgs() << "INDVARS: Original iv: "
+ << *OrigPhiRef << '\n');
++NumElim;
Value *NewIV = OrigPhiRef;
if (OrigPhiRef->getType() != Phi->getType()) {
@@ -2179,156 +2179,156 @@ SCEVExpander::getRelatedExistingExpansion(const SCEV *S, const Instruction *At,
return None;
}
-template<typename T> static int costAndCollectOperands(
- const SCEVOperand &WorkItem, const TargetTransformInfo &TTI,
- TargetTransformInfo::TargetCostKind CostKind,
- SmallVectorImpl<SCEVOperand> &Worklist) {
-
- const T *S = cast<T>(WorkItem.S);
- int Cost = 0;
- // Object to help map SCEV operands to expanded IR instructions.
- struct OperationIndices {
- OperationIndices(unsigned Opc, size_t min, size_t max) :
- Opcode(Opc), MinIdx(min), MaxIdx(max) { }
- unsigned Opcode;
- size_t MinIdx;
- size_t MaxIdx;
- };
-
- // Collect the operations of all the instructions that will be needed to
- // expand the SCEVExpr. This is so that when we come to cost the operands,
- // we know what the generated user(s) will be.
- SmallVector<OperationIndices, 2> Operations;
-
- auto CastCost = [&](unsigned Opcode) {
- Operations.emplace_back(Opcode, 0, 0);
- return TTI.getCastInstrCost(Opcode, S->getType(),
- S->getOperand(0)->getType(),
- TTI::CastContextHint::None, CostKind);
- };
-
- auto ArithCost = [&](unsigned Opcode, unsigned NumRequired,
- unsigned MinIdx = 0, unsigned MaxIdx = 1) {
- Operations.emplace_back(Opcode, MinIdx, MaxIdx);
- return NumRequired *
- TTI.getArithmeticInstrCost(Opcode, S->getType(), CostKind);
- };
-
- auto CmpSelCost = [&](unsigned Opcode, unsigned NumRequired,
- unsigned MinIdx, unsigned MaxIdx) {
- Operations.emplace_back(Opcode, MinIdx, MaxIdx);
- Type *OpType = S->getOperand(0)->getType();
- return NumRequired * TTI.getCmpSelInstrCost(
- Opcode, OpType, CmpInst::makeCmpResultType(OpType),
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
- };
-
- switch (S->getSCEVType()) {
- case scCouldNotCompute:
- llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
- case scUnknown:
- case scConstant:
- return 0;
- case scPtrToInt:
- Cost = CastCost(Instruction::PtrToInt);
- break;
- case scTruncate:
- Cost = CastCost(Instruction::Trunc);
- break;
- case scZeroExtend:
- Cost = CastCost(Instruction::ZExt);
- break;
- case scSignExtend:
- Cost = CastCost(Instruction::SExt);
- break;
- case scUDivExpr: {
- unsigned Opcode = Instruction::UDiv;
- if (auto *SC = dyn_cast<SCEVConstant>(S->getOperand(1)))
- if (SC->getAPInt().isPowerOf2())
- Opcode = Instruction::LShr;
- Cost = ArithCost(Opcode, 1);
- break;
- }
- case scAddExpr:
- Cost = ArithCost(Instruction::Add, S->getNumOperands() - 1);
- break;
- case scMulExpr:
- // TODO: this is a very pessimistic cost modelling for Mul,
- // because of Bin Pow algorithm actually used by the expander,
- // see SCEVExpander::visitMulExpr(), ExpandOpBinPowN().
- Cost = ArithCost(Instruction::Mul, S->getNumOperands() - 1);
- break;
- case scSMaxExpr:
- case scUMaxExpr:
- case scSMinExpr:
- case scUMinExpr: {
- Cost += CmpSelCost(Instruction::ICmp, S->getNumOperands() - 1, 0, 1);
- Cost += CmpSelCost(Instruction::Select, S->getNumOperands() - 1, 0, 2);
- break;
- }
- case scAddRecExpr: {
- // In this polynominal, we may have some zero operands, and we shouldn't
- // really charge for those. So how many non-zero coeffients are there?
- int NumTerms = llvm::count_if(S->operands(), [](const SCEV *Op) {
- return !Op->isZero();
- });
-
- assert(NumTerms >= 1 && "Polynominal should have at least one term.");
- assert(!(*std::prev(S->operands().end()))->isZero() &&
- "Last operand should not be zero");
-
- // Ignoring constant term (operand 0), how many of the coeffients are u> 1?
- int NumNonZeroDegreeNonOneTerms =
- llvm::count_if(S->operands(), [](const SCEV *Op) {
- auto *SConst = dyn_cast<SCEVConstant>(Op);
- return !SConst || SConst->getAPInt().ugt(1);
- });
-
- // Much like with normal add expr, the polynominal will require
- // one less addition than the number of it's terms.
- int AddCost = ArithCost(Instruction::Add, NumTerms - 1,
- /*MinIdx*/1, /*MaxIdx*/1);
- // Here, *each* one of those will require a multiplication.
- int MulCost = ArithCost(Instruction::Mul, NumNonZeroDegreeNonOneTerms);
- Cost = AddCost + MulCost;
-
- // What is the degree of this polynominal?
- int PolyDegree = S->getNumOperands() - 1;
- assert(PolyDegree >= 1 && "Should be at least affine.");
-
- // The final term will be:
- // Op_{PolyDegree} * x ^ {PolyDegree}
- // Where x ^ {PolyDegree} will again require PolyDegree-1 mul operations.
- // Note that x ^ {PolyDegree} = x * x ^ {PolyDegree-1} so charging for
- // x ^ {PolyDegree} will give us x ^ {2} .. x ^ {PolyDegree-1} for free.
- // FIXME: this is conservatively correct, but might be overly pessimistic.
- Cost += MulCost * (PolyDegree - 1);
- break;
- }
- }
-
- for (auto &CostOp : Operations) {
- for (auto SCEVOp : enumerate(S->operands())) {
- // Clamp the index to account for multiple IR operations being chained.
- size_t MinIdx = std::max(SCEVOp.index(), CostOp.MinIdx);
- size_t OpIdx = std::min(MinIdx, CostOp.MaxIdx);
- Worklist.emplace_back(CostOp.Opcode, OpIdx, SCEVOp.value());
- }
- }
- return Cost;
-}
-
+template<typename T> static int costAndCollectOperands(
+ const SCEVOperand &WorkItem, const TargetTransformInfo &TTI,
+ TargetTransformInfo::TargetCostKind CostKind,
+ SmallVectorImpl<SCEVOperand> &Worklist) {
+
+ const T *S = cast<T>(WorkItem.S);
+ int Cost = 0;
+ // Object to help map SCEV operands to expanded IR instructions.
+ struct OperationIndices {
+ OperationIndices(unsigned Opc, size_t min, size_t max) :
+ Opcode(Opc), MinIdx(min), MaxIdx(max) { }
+ unsigned Opcode;
+ size_t MinIdx;
+ size_t MaxIdx;
+ };
+
+ // Collect the operations of all the instructions that will be needed to
+ // expand the SCEVExpr. This is so that when we come to cost the operands,
+ // we know what the generated user(s) will be.
+ SmallVector<OperationIndices, 2> Operations;
+
+ auto CastCost = [&](unsigned Opcode) {
+ Operations.emplace_back(Opcode, 0, 0);
+ return TTI.getCastInstrCost(Opcode, S->getType(),
+ S->getOperand(0)->getType(),
+ TTI::CastContextHint::None, CostKind);
+ };
+
+ auto ArithCost = [&](unsigned Opcode, unsigned NumRequired,
+ unsigned MinIdx = 0, unsigned MaxIdx = 1) {
+ Operations.emplace_back(Opcode, MinIdx, MaxIdx);
+ return NumRequired *
+ TTI.getArithmeticInstrCost(Opcode, S->getType(), CostKind);
+ };
+
+ auto CmpSelCost = [&](unsigned Opcode, unsigned NumRequired,
+ unsigned MinIdx, unsigned MaxIdx) {
+ Operations.emplace_back(Opcode, MinIdx, MaxIdx);
+ Type *OpType = S->getOperand(0)->getType();
+ return NumRequired * TTI.getCmpSelInstrCost(
+ Opcode, OpType, CmpInst::makeCmpResultType(OpType),
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ };
+
+ switch (S->getSCEVType()) {
+ case scCouldNotCompute:
+ llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
+ case scUnknown:
+ case scConstant:
+ return 0;
+ case scPtrToInt:
+ Cost = CastCost(Instruction::PtrToInt);
+ break;
+ case scTruncate:
+ Cost = CastCost(Instruction::Trunc);
+ break;
+ case scZeroExtend:
+ Cost = CastCost(Instruction::ZExt);
+ break;
+ case scSignExtend:
+ Cost = CastCost(Instruction::SExt);
+ break;
+ case scUDivExpr: {
+ unsigned Opcode = Instruction::UDiv;
+ if (auto *SC = dyn_cast<SCEVConstant>(S->getOperand(1)))
+ if (SC->getAPInt().isPowerOf2())
+ Opcode = Instruction::LShr;
+ Cost = ArithCost(Opcode, 1);
+ break;
+ }
+ case scAddExpr:
+ Cost = ArithCost(Instruction::Add, S->getNumOperands() - 1);
+ break;
+ case scMulExpr:
+ // TODO: this is a very pessimistic cost modelling for Mul,
+ // because of Bin Pow algorithm actually used by the expander,
+ // see SCEVExpander::visitMulExpr(), ExpandOpBinPowN().
+ Cost = ArithCost(Instruction::Mul, S->getNumOperands() - 1);
+ break;
+ case scSMaxExpr:
+ case scUMaxExpr:
+ case scSMinExpr:
+ case scUMinExpr: {
+ Cost += CmpSelCost(Instruction::ICmp, S->getNumOperands() - 1, 0, 1);
+ Cost += CmpSelCost(Instruction::Select, S->getNumOperands() - 1, 0, 2);
+ break;
+ }
+ case scAddRecExpr: {
+ // In this polynominal, we may have some zero operands, and we shouldn't
+ // really charge for those. So how many non-zero coeffients are there?
+ int NumTerms = llvm::count_if(S->operands(), [](const SCEV *Op) {
+ return !Op->isZero();
+ });
+
+ assert(NumTerms >= 1 && "Polynominal should have at least one term.");
+ assert(!(*std::prev(S->operands().end()))->isZero() &&
+ "Last operand should not be zero");
+
+ // Ignoring constant term (operand 0), how many of the coeffients are u> 1?
+ int NumNonZeroDegreeNonOneTerms =
+ llvm::count_if(S->operands(), [](const SCEV *Op) {
+ auto *SConst = dyn_cast<SCEVConstant>(Op);
+ return !SConst || SConst->getAPInt().ugt(1);
+ });
+
+ // Much like with normal add expr, the polynominal will require
+ // one less addition than the number of it's terms.
+ int AddCost = ArithCost(Instruction::Add, NumTerms - 1,
+ /*MinIdx*/1, /*MaxIdx*/1);
+ // Here, *each* one of those will require a multiplication.
+ int MulCost = ArithCost(Instruction::Mul, NumNonZeroDegreeNonOneTerms);
+ Cost = AddCost + MulCost;
+
+ // What is the degree of this polynominal?
+ int PolyDegree = S->getNumOperands() - 1;
+ assert(PolyDegree >= 1 && "Should be at least affine.");
+
+ // The final term will be:
+ // Op_{PolyDegree} * x ^ {PolyDegree}
+ // Where x ^ {PolyDegree} will again require PolyDegree-1 mul operations.
+ // Note that x ^ {PolyDegree} = x * x ^ {PolyDegree-1} so charging for
+ // x ^ {PolyDegree} will give us x ^ {2} .. x ^ {PolyDegree-1} for free.
+ // FIXME: this is conservatively correct, but might be overly pessimistic.
+ Cost += MulCost * (PolyDegree - 1);
+ break;
+ }
+ }
+
+ for (auto &CostOp : Operations) {
+ for (auto SCEVOp : enumerate(S->operands())) {
+ // Clamp the index to account for multiple IR operations being chained.
+ size_t MinIdx = std::max(SCEVOp.index(), CostOp.MinIdx);
+ size_t OpIdx = std::min(MinIdx, CostOp.MaxIdx);
+ Worklist.emplace_back(CostOp.Opcode, OpIdx, SCEVOp.value());
+ }
+ }
+ return Cost;
+}
+
bool SCEVExpander::isHighCostExpansionHelper(
- const SCEVOperand &WorkItem, Loop *L, const Instruction &At,
- int &BudgetRemaining, const TargetTransformInfo &TTI,
- SmallPtrSetImpl<const SCEV *> &Processed,
- SmallVectorImpl<SCEVOperand> &Worklist) {
+ const SCEVOperand &WorkItem, Loop *L, const Instruction &At,
+ int &BudgetRemaining, const TargetTransformInfo &TTI,
+ SmallPtrSetImpl<const SCEV *> &Processed,
+ SmallVectorImpl<SCEVOperand> &Worklist) {
if (BudgetRemaining < 0)
return true; // Already run out of budget, give up.
- const SCEV *S = WorkItem.S;
+ const SCEV *S = WorkItem.S;
// Was the cost of expansion of this expression already accounted for?
- if (!isa<SCEVConstant>(S) && !Processed.insert(S).second)
+ if (!isa<SCEVConstant>(S) && !Processed.insert(S).second)
return false; // We have already accounted for this expression.
// If we can find an existing value for this scev available at the point "At"
@@ -2336,37 +2336,37 @@ bool SCEVExpander::isHighCostExpansionHelper(
if (getRelatedExistingExpansion(S, &At, L))
return false; // Consider the expression to be free.
- TargetTransformInfo::TargetCostKind CostKind =
- L->getHeader()->getParent()->hasMinSize()
- ? TargetTransformInfo::TCK_CodeSize
- : TargetTransformInfo::TCK_RecipThroughput;
-
+ TargetTransformInfo::TargetCostKind CostKind =
+ L->getHeader()->getParent()->hasMinSize()
+ ? TargetTransformInfo::TCK_CodeSize
+ : TargetTransformInfo::TCK_RecipThroughput;
+
switch (S->getSCEVType()) {
- case scCouldNotCompute:
- llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
+ case scCouldNotCompute:
+ llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
case scUnknown:
- // Assume to be zero-cost.
- return false;
- case scConstant: {
- // Only evalulate the costs of constants when optimizing for size.
- if (CostKind != TargetTransformInfo::TCK_CodeSize)
- return 0;
- const APInt &Imm = cast<SCEVConstant>(S)->getAPInt();
- Type *Ty = S->getType();
- BudgetRemaining -= TTI.getIntImmCostInst(
- WorkItem.ParentOpcode, WorkItem.OperandIdx, Imm, Ty, CostKind);
- return BudgetRemaining < 0;
- }
- case scTruncate:
- case scPtrToInt:
- case scZeroExtend:
- case scSignExtend: {
- int Cost =
- costAndCollectOperands<SCEVCastExpr>(WorkItem, TTI, CostKind, Worklist);
- BudgetRemaining -= Cost;
+ // Assume to be zero-cost.
+ return false;
+ case scConstant: {
+ // Only evalulate the costs of constants when optimizing for size.
+ if (CostKind != TargetTransformInfo::TCK_CodeSize)
+ return 0;
+ const APInt &Imm = cast<SCEVConstant>(S)->getAPInt();
+ Type *Ty = S->getType();
+ BudgetRemaining -= TTI.getIntImmCostInst(
+ WorkItem.ParentOpcode, WorkItem.OperandIdx, Imm, Ty, CostKind);
+ return BudgetRemaining < 0;
+ }
+ case scTruncate:
+ case scPtrToInt:
+ case scZeroExtend:
+ case scSignExtend: {
+ int Cost =
+ costAndCollectOperands<SCEVCastExpr>(WorkItem, TTI, CostKind, Worklist);
+ BudgetRemaining -= Cost;
return false; // Will answer upon next entry into this function.
}
- case scUDivExpr: {
+ case scUDivExpr: {
// UDivExpr is very likely a UDiv that ScalarEvolution's HowFarToZero or
// HowManyLessThans produced to compute a precise expression, rather than a
// UDiv from the user's code. If we can't find a UDiv in the code with some
@@ -2379,36 +2379,36 @@ bool SCEVExpander::isHighCostExpansionHelper(
SE.getAddExpr(S, SE.getConstant(S->getType(), 1)), &At, L))
return false; // Consider it to be free.
- int Cost =
- costAndCollectOperands<SCEVUDivExpr>(WorkItem, TTI, CostKind, Worklist);
+ int Cost =
+ costAndCollectOperands<SCEVUDivExpr>(WorkItem, TTI, CostKind, Worklist);
// Need to count the cost of this UDiv.
- BudgetRemaining -= Cost;
+ BudgetRemaining -= Cost;
return false; // Will answer upon next entry into this function.
}
- case scAddExpr:
- case scMulExpr:
- case scUMaxExpr:
- case scSMaxExpr:
- case scUMinExpr:
- case scSMinExpr: {
- assert(cast<SCEVNAryExpr>(S)->getNumOperands() > 1 &&
+ case scAddExpr:
+ case scMulExpr:
+ case scUMaxExpr:
+ case scSMaxExpr:
+ case scUMinExpr:
+ case scSMinExpr: {
+ assert(cast<SCEVNAryExpr>(S)->getNumOperands() > 1 &&
"Nary expr should have more than 1 operand.");
// The simple nary expr will require one less op (or pair of ops)
// than the number of it's terms.
- int Cost =
- costAndCollectOperands<SCEVNAryExpr>(WorkItem, TTI, CostKind, Worklist);
- BudgetRemaining -= Cost;
- return BudgetRemaining < 0;
- }
- case scAddRecExpr: {
- assert(cast<SCEVAddRecExpr>(S)->getNumOperands() >= 2 &&
- "Polynomial should be at least linear");
- BudgetRemaining -= costAndCollectOperands<SCEVAddRecExpr>(
- WorkItem, TTI, CostKind, Worklist);
- return BudgetRemaining < 0;
- }
- }
- llvm_unreachable("Unknown SCEV kind!");
+ int Cost =
+ costAndCollectOperands<SCEVNAryExpr>(WorkItem, TTI, CostKind, Worklist);
+ BudgetRemaining -= Cost;
+ return BudgetRemaining < 0;
+ }
+ case scAddRecExpr: {
+ assert(cast<SCEVAddRecExpr>(S)->getNumOperands() >= 2 &&
+ "Polynomial should be at least linear");
+ BudgetRemaining -= costAndCollectOperands<SCEVAddRecExpr>(
+ WorkItem, TTI, CostKind, Worklist);
+ return BudgetRemaining < 0;
+ }
+ }
+ llvm_unreachable("Unknown SCEV kind!");
}
Value *SCEVExpander::expandCodeForPredicate(const SCEVPredicate *Pred,
@@ -2429,10 +2429,10 @@ Value *SCEVExpander::expandCodeForPredicate(const SCEVPredicate *Pred,
Value *SCEVExpander::expandEqualPredicate(const SCEVEqualPredicate *Pred,
Instruction *IP) {
- Value *Expr0 =
- expandCodeForImpl(Pred->getLHS(), Pred->getLHS()->getType(), IP, false);
- Value *Expr1 =
- expandCodeForImpl(Pred->getRHS(), Pred->getRHS()->getType(), IP, false);
+ Value *Expr0 =
+ expandCodeForImpl(Pred->getLHS(), Pred->getLHS()->getType(), IP, false);
+ Value *Expr1 =
+ expandCodeForImpl(Pred->getRHS(), Pred->getRHS()->getType(), IP, false);
Builder.SetInsertPoint(IP);
auto *I = Builder.CreateICmpNE(Expr0, Expr1, "ident.check");
@@ -2448,7 +2448,7 @@ Value *SCEVExpander::generateOverflowCheck(const SCEVAddRecExpr *AR,
const SCEV *ExitCount =
SE.getPredicatedBackedgeTakenCount(AR->getLoop(), Pred);
- assert(!isa<SCEVCouldNotCompute>(ExitCount) && "Invalid loop count");
+ assert(!isa<SCEVCouldNotCompute>(ExitCount) && "Invalid loop count");
const SCEV *Step = AR->getStepRecurrence(SE);
const SCEV *Start = AR->getStart();
@@ -2464,16 +2464,16 @@ Value *SCEVExpander::generateOverflowCheck(const SCEVAddRecExpr *AR,
IntegerType *CountTy = IntegerType::get(Loc->getContext(), SrcBits);
Builder.SetInsertPoint(Loc);
- Value *TripCountVal = expandCodeForImpl(ExitCount, CountTy, Loc, false);
+ Value *TripCountVal = expandCodeForImpl(ExitCount, CountTy, Loc, false);
IntegerType *Ty =
IntegerType::get(Loc->getContext(), SE.getTypeSizeInBits(ARTy));
Type *ARExpandTy = DL.isNonIntegralPointerType(ARTy) ? ARTy : Ty;
- Value *StepValue = expandCodeForImpl(Step, Ty, Loc, false);
- Value *NegStepValue =
- expandCodeForImpl(SE.getNegativeSCEV(Step), Ty, Loc, false);
- Value *StartValue = expandCodeForImpl(Start, ARExpandTy, Loc, false);
+ Value *StepValue = expandCodeForImpl(Step, Ty, Loc, false);
+ Value *NegStepValue =
+ expandCodeForImpl(SE.getNegativeSCEV(Step), Ty, Loc, false);
+ Value *StartValue = expandCodeForImpl(Start, ARExpandTy, Loc, false);
ConstantInt *Zero =
ConstantInt::get(Loc->getContext(), APInt::getNullValue(DstBits));
@@ -2533,7 +2533,7 @@ Value *SCEVExpander::generateOverflowCheck(const SCEVAddRecExpr *AR,
EndCheck = Builder.CreateOr(EndCheck, BackedgeCheck);
}
- return Builder.CreateOr(EndCheck, OfMul);
+ return Builder.CreateOr(EndCheck, OfMul);
}
Value *SCEVExpander::expandWrapPredicate(const SCEVWrapPredicate *Pred,
@@ -2576,34 +2576,34 @@ Value *SCEVExpander::expandUnionPredicate(const SCEVUnionPredicate *Union,
return Check;
}
-Value *SCEVExpander::fixupLCSSAFormFor(Instruction *User, unsigned OpIdx) {
- assert(PreserveLCSSA);
- SmallVector<Instruction *, 1> ToUpdate;
-
- auto *OpV = User->getOperand(OpIdx);
- auto *OpI = dyn_cast<Instruction>(OpV);
- if (!OpI)
- return OpV;
-
- Loop *DefLoop = SE.LI.getLoopFor(OpI->getParent());
- Loop *UseLoop = SE.LI.getLoopFor(User->getParent());
- if (!DefLoop || UseLoop == DefLoop || DefLoop->contains(UseLoop))
- return OpV;
-
- ToUpdate.push_back(OpI);
- SmallVector<PHINode *, 16> PHIsToRemove;
- formLCSSAForInstructions(ToUpdate, SE.DT, SE.LI, &SE, Builder, &PHIsToRemove);
- for (PHINode *PN : PHIsToRemove) {
- if (!PN->use_empty())
- continue;
- InsertedValues.erase(PN);
- InsertedPostIncValues.erase(PN);
- PN->eraseFromParent();
- }
-
- return User->getOperand(OpIdx);
-}
-
+Value *SCEVExpander::fixupLCSSAFormFor(Instruction *User, unsigned OpIdx) {
+ assert(PreserveLCSSA);
+ SmallVector<Instruction *, 1> ToUpdate;
+
+ auto *OpV = User->getOperand(OpIdx);
+ auto *OpI = dyn_cast<Instruction>(OpV);
+ if (!OpI)
+ return OpV;
+
+ Loop *DefLoop = SE.LI.getLoopFor(OpI->getParent());
+ Loop *UseLoop = SE.LI.getLoopFor(User->getParent());
+ if (!DefLoop || UseLoop == DefLoop || DefLoop->contains(UseLoop))
+ return OpV;
+
+ ToUpdate.push_back(OpI);
+ SmallVector<PHINode *, 16> PHIsToRemove;
+ formLCSSAForInstructions(ToUpdate, SE.DT, SE.LI, &SE, Builder, &PHIsToRemove);
+ for (PHINode *PN : PHIsToRemove) {
+ if (!PN->use_empty())
+ continue;
+ InsertedValues.erase(PN);
+ InsertedPostIncValues.erase(PN);
+ PN->eraseFromParent();
+ }
+
+ return User->getOperand(OpIdx);
+}
+
namespace {
// Search for a SCEV subexpression that is not safe to expand. Any expression
// that may expand to a !isSafeToSpeculativelyExecute value is unsafe, namely
@@ -2681,40 +2681,40 @@ bool isSafeToExpandAt(const SCEV *S, const Instruction *InsertionPoint,
}
return false;
}
-
-SCEVExpanderCleaner::~SCEVExpanderCleaner() {
- // Result is used, nothing to remove.
- if (ResultUsed)
- return;
-
- auto InsertedInstructions = Expander.getAllInsertedInstructions();
-#ifndef NDEBUG
- SmallPtrSet<Instruction *, 8> InsertedSet(InsertedInstructions.begin(),
- InsertedInstructions.end());
- (void)InsertedSet;
-#endif
- // Remove sets with value handles.
- Expander.clear();
-
- // Sort so that earlier instructions do not dominate later instructions.
- stable_sort(InsertedInstructions, [this](Instruction *A, Instruction *B) {
- return DT.dominates(B, A);
- });
- // Remove all inserted instructions.
- for (Instruction *I : InsertedInstructions) {
-
-#ifndef NDEBUG
- assert(all_of(I->users(),
- [&InsertedSet](Value *U) {
- return InsertedSet.contains(cast<Instruction>(U));
- }) &&
- "removed instruction should only be used by instructions inserted "
- "during expansion");
-#endif
- assert(!I->getType()->isVoidTy() &&
- "inserted instruction should have non-void types");
- I->replaceAllUsesWith(UndefValue::get(I->getType()));
- I->eraseFromParent();
- }
+
+SCEVExpanderCleaner::~SCEVExpanderCleaner() {
+ // Result is used, nothing to remove.
+ if (ResultUsed)
+ return;
+
+ auto InsertedInstructions = Expander.getAllInsertedInstructions();
+#ifndef NDEBUG
+ SmallPtrSet<Instruction *, 8> InsertedSet(InsertedInstructions.begin(),
+ InsertedInstructions.end());
+ (void)InsertedSet;
+#endif
+ // Remove sets with value handles.
+ Expander.clear();
+
+ // Sort so that earlier instructions do not dominate later instructions.
+ stable_sort(InsertedInstructions, [this](Instruction *A, Instruction *B) {
+ return DT.dominates(B, A);
+ });
+ // Remove all inserted instructions.
+ for (Instruction *I : InsertedInstructions) {
+
+#ifndef NDEBUG
+ assert(all_of(I->users(),
+ [&InsertedSet](Value *U) {
+ return InsertedSet.contains(cast<Instruction>(U));
+ }) &&
+ "removed instruction should only be used by instructions inserted "
+ "during expansion");
+#endif
+ assert(!I->getType()->isVoidTy() &&
+ "inserted instruction should have non-void types");
+ I->replaceAllUsesWith(UndefValue::get(I->getType()));
+ I->eraseFromParent();
+ }
+}
}
-}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/SimplifyCFG.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/SimplifyCFG.cpp
index a543253d5f..de9560df97 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -13,11 +13,11 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/ScopeExit.h"
-#include "llvm/ADT/Sequence.h"
+#include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -61,7 +61,7 @@
#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
-#include "llvm/IR/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -71,7 +71,7 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
-#include "llvm/Transforms/Utils/SSAUpdater.h"
+#include "llvm/Transforms/Utils/SSAUpdater.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include <algorithm>
#include <cassert>
@@ -90,12 +90,12 @@ using namespace PatternMatch;
#define DEBUG_TYPE "simplifycfg"
-cl::opt<bool> llvm::RequireAndPreserveDomTree(
- "simplifycfg-require-and-preserve-domtree", cl::Hidden, cl::ZeroOrMore,
- cl::init(false),
- cl::desc("Temorary development switch used to gradually uplift SimplifyCFG "
- "into preserving DomTree,"));
-
+cl::opt<bool> llvm::RequireAndPreserveDomTree(
+ "simplifycfg-require-and-preserve-domtree", cl::Hidden, cl::ZeroOrMore,
+ cl::init(false),
+ cl::desc("Temorary development switch used to gradually uplift SimplifyCFG "
+ "into preserving DomTree,"));
+
// Chosen as 2 so as to be cheap, but still to have enough power to fold
// a select, so the "clamp" idiom (of a min followed by a max) will be caught.
// To catch this, we need to fold a compare and a select, hence '2' being the
@@ -116,10 +116,10 @@ static cl::opt<bool> DupRet(
cl::desc("Duplicate return instructions into unconditional branches"));
static cl::opt<bool>
- HoistCommon("simplifycfg-hoist-common", cl::Hidden, cl::init(true),
- cl::desc("Hoist common instructions up to the parent block"));
-
-static cl::opt<bool>
+ HoistCommon("simplifycfg-hoist-common", cl::Hidden, cl::init(true),
+ cl::desc("Hoist common instructions up to the parent block"));
+
+static cl::opt<bool>
SinkCommon("simplifycfg-sink-common", cl::Hidden, cl::init(true),
cl::desc("Sink common instructions down to the end block"));
@@ -153,13 +153,13 @@ MaxSmallBlockSize("simplifycfg-max-small-block-size", cl::Hidden, cl::init(10),
cl::desc("Max size of a block which is still considered "
"small enough to thread through"));
-// Two is chosen to allow one negation and a logical combine.
-static cl::opt<unsigned>
- BranchFoldThreshold("simplifycfg-branch-fold-threshold", cl::Hidden,
- cl::init(2),
- cl::desc("Maximum cost of combining conditions when "
- "folding branches"));
-
+// Two is chosen to allow one negation and a logical combine.
+static cl::opt<unsigned>
+ BranchFoldThreshold("simplifycfg-branch-fold-threshold", cl::Hidden,
+ cl::init(2),
+ cl::desc("Maximum cost of combining conditions when "
+ "folding branches"));
+
STATISTIC(NumBitMaps, "Number of switch instructions turned into bitmaps");
STATISTIC(NumLinearMaps,
"Number of switch instructions turned into linear mapping");
@@ -169,22 +169,22 @@ STATISTIC(
NumLookupTablesHoles,
"Number of switch instructions turned into lookup tables (holes checked)");
STATISTIC(NumTableCmpReuses, "Number of reused switch table lookup compares");
-STATISTIC(NumFoldValueComparisonIntoPredecessors,
- "Number of value comparisons folded into predecessor basic blocks");
-STATISTIC(NumFoldBranchToCommonDest,
- "Number of branches folded into predecessor basic block");
-STATISTIC(
- NumHoistCommonCode,
- "Number of common instruction 'blocks' hoisted up to the begin block");
-STATISTIC(NumHoistCommonInstrs,
- "Number of common instructions hoisted up to the begin block");
-STATISTIC(NumSinkCommonCode,
- "Number of common instruction 'blocks' sunk down to the end block");
-STATISTIC(NumSinkCommonInstrs,
+STATISTIC(NumFoldValueComparisonIntoPredecessors,
+ "Number of value comparisons folded into predecessor basic blocks");
+STATISTIC(NumFoldBranchToCommonDest,
+ "Number of branches folded into predecessor basic block");
+STATISTIC(
+ NumHoistCommonCode,
+ "Number of common instruction 'blocks' hoisted up to the begin block");
+STATISTIC(NumHoistCommonInstrs,
+ "Number of common instructions hoisted up to the begin block");
+STATISTIC(NumSinkCommonCode,
+ "Number of common instruction 'blocks' sunk down to the end block");
+STATISTIC(NumSinkCommonInstrs,
"Number of common instructions sunk down to the end block");
STATISTIC(NumSpeculations, "Number of speculative executed instructions");
-STATISTIC(NumInvokes,
- "Number of invokes with empty resume blocks simplified into calls");
+STATISTIC(NumInvokes,
+ "Number of invokes with empty resume blocks simplified into calls");
namespace {
@@ -217,9 +217,9 @@ struct ValueEqualityComparisonCase {
class SimplifyCFGOpt {
const TargetTransformInfo &TTI;
- DomTreeUpdater *DTU;
+ DomTreeUpdater *DTU;
const DataLayout &DL;
- ArrayRef<WeakVH> LoopHeaders;
+ ArrayRef<WeakVH> LoopHeaders;
const SimplifyCFGOptions &Options;
bool Resimplify;
@@ -229,9 +229,9 @@ class SimplifyCFGOpt {
bool SimplifyEqualityComparisonWithOnlyPredecessor(Instruction *TI,
BasicBlock *Pred,
IRBuilder<> &Builder);
- bool PerformValueComparisonIntoPredecessorFolding(Instruction *TI, Value *&CV,
- Instruction *PTI,
- IRBuilder<> &Builder);
+ bool PerformValueComparisonIntoPredecessorFolding(Instruction *TI, Value *&CV,
+ Instruction *PTI,
+ IRBuilder<> &Builder);
bool FoldValueComparisonIntoPredecessors(Instruction *TI,
IRBuilder<> &Builder);
@@ -264,17 +264,17 @@ class SimplifyCFGOpt {
bool TurnSwitchRangeIntoICmp(SwitchInst *SI, IRBuilder<> &Builder);
public:
- SimplifyCFGOpt(const TargetTransformInfo &TTI, DomTreeUpdater *DTU,
- const DataLayout &DL, ArrayRef<WeakVH> LoopHeaders,
+ SimplifyCFGOpt(const TargetTransformInfo &TTI, DomTreeUpdater *DTU,
+ const DataLayout &DL, ArrayRef<WeakVH> LoopHeaders,
const SimplifyCFGOptions &Opts)
- : TTI(TTI), DTU(DTU), DL(DL), LoopHeaders(LoopHeaders), Options(Opts) {
- assert((!DTU || !DTU->hasPostDomTree()) &&
- "SimplifyCFG is not yet capable of maintaining validity of a "
- "PostDomTree, so don't ask for it.");
- }
-
- bool simplifyOnce(BasicBlock *BB);
- bool simplifyOnceImpl(BasicBlock *BB);
+ : TTI(TTI), DTU(DTU), DL(DL), LoopHeaders(LoopHeaders), Options(Opts) {
+ assert((!DTU || !DTU->hasPostDomTree()) &&
+ "SimplifyCFG is not yet capable of maintaining validity of a "
+ "PostDomTree, so don't ask for it.");
+ }
+
+ bool simplifyOnce(BasicBlock *BB);
+ bool simplifyOnceImpl(BasicBlock *BB);
bool run(BasicBlock *BB);
// Helper to set Resimplify and return change indication.
@@ -655,7 +655,7 @@ private:
/// vector.
/// One "Extra" case is allowed to differ from the other.
void gather(Value *V) {
- bool isEQ = match(V, m_LogicalOr(m_Value(), m_Value()));
+ bool isEQ = match(V, m_LogicalOr(m_Value(), m_Value()));
// Keep a stack (SmallVector for efficiency) for depth-first traversal
SmallVector<Value *, 8> DFT;
@@ -670,14 +670,14 @@ private:
if (Instruction *I = dyn_cast<Instruction>(V)) {
// If it is a || (or && depending on isEQ), process the operands.
- Value *Op0, *Op1;
- if (isEQ ? match(I, m_LogicalOr(m_Value(Op0), m_Value(Op1)))
- : match(I, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
- if (Visited.insert(Op1).second)
- DFT.push_back(Op1);
- if (Visited.insert(Op0).second)
- DFT.push_back(Op0);
-
+ Value *Op0, *Op1;
+ if (isEQ ? match(I, m_LogicalOr(m_Value(Op0), m_Value(Op1)))
+ : match(I, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
+ if (Visited.insert(Op1).second)
+ DFT.push_back(Op1);
+ if (Visited.insert(Op0).second)
+ DFT.push_back(Op0);
+
continue;
}
@@ -772,7 +772,7 @@ BasicBlock *SimplifyCFGOpt::GetValueEqualityComparisonCases(
static void
EliminateBlockCases(BasicBlock *BB,
std::vector<ValueEqualityComparisonCase> &Cases) {
- llvm::erase_value(Cases, BB);
+ llvm::erase_value(Cases, BB);
}
/// Return true if there are any keys in C1 that exist in C2 as well.
@@ -882,18 +882,18 @@ bool SimplifyCFGOpt::SimplifyEqualityComparisonWithOnlyPredecessor(
(void)NI;
// Remove PHI node entries for the dead edge.
- ThisCases[0].Dest->removePredecessor(PredDef);
+ ThisCases[0].Dest->removePredecessor(PredDef);
LLVM_DEBUG(dbgs() << "Threading pred instr: " << *Pred->getTerminator()
<< "Through successor TI: " << *TI << "Leaving: " << *NI
<< "\n");
EraseTerminatorAndDCECond(TI);
-
- if (DTU)
- DTU->applyUpdates(
- {{DominatorTree::Delete, PredDef, ThisCases[0].Dest}});
-
+
+ if (DTU)
+ DTU->applyUpdates(
+ {{DominatorTree::Delete, PredDef, ThisCases[0].Dest}});
+
return true;
}
@@ -906,25 +906,25 @@ bool SimplifyCFGOpt::SimplifyEqualityComparisonWithOnlyPredecessor(
LLVM_DEBUG(dbgs() << "Threading pred instr: " << *Pred->getTerminator()
<< "Through successor TI: " << *TI);
- SmallMapVector<BasicBlock *, int, 8> NumPerSuccessorCases;
+ SmallMapVector<BasicBlock *, int, 8> NumPerSuccessorCases;
for (SwitchInst::CaseIt i = SI->case_end(), e = SI->case_begin(); i != e;) {
--i;
- auto *Successor = i->getCaseSuccessor();
- ++NumPerSuccessorCases[Successor];
+ auto *Successor = i->getCaseSuccessor();
+ ++NumPerSuccessorCases[Successor];
if (DeadCases.count(i->getCaseValue())) {
- Successor->removePredecessor(PredDef);
+ Successor->removePredecessor(PredDef);
SI.removeCase(i);
- --NumPerSuccessorCases[Successor];
+ --NumPerSuccessorCases[Successor];
}
}
-
- std::vector<DominatorTree::UpdateType> Updates;
- for (const std::pair<BasicBlock *, int> &I : NumPerSuccessorCases)
- if (I.second == 0)
- Updates.push_back({DominatorTree::Delete, PredDef, I.first});
- if (DTU)
- DTU->applyUpdates(Updates);
-
+
+ std::vector<DominatorTree::UpdateType> Updates;
+ for (const std::pair<BasicBlock *, int> &I : NumPerSuccessorCases)
+ if (I.second == 0)
+ Updates.push_back({DominatorTree::Delete, PredDef, I.first});
+ if (DTU)
+ DTU->applyUpdates(Updates);
+
LLVM_DEBUG(dbgs() << "Leaving: " << *TI << "\n");
return true;
}
@@ -954,16 +954,16 @@ bool SimplifyCFGOpt::SimplifyEqualityComparisonWithOnlyPredecessor(
if (!TheRealDest)
TheRealDest = ThisDef;
- SmallSetVector<BasicBlock *, 2> RemovedSuccs;
-
+ SmallSetVector<BasicBlock *, 2> RemovedSuccs;
+
// Remove PHI node entries for dead edges.
BasicBlock *CheckEdge = TheRealDest;
for (BasicBlock *Succ : successors(TIBB))
- if (Succ != CheckEdge) {
- if (Succ != TheRealDest)
- RemovedSuccs.insert(Succ);
+ if (Succ != CheckEdge) {
+ if (Succ != TheRealDest)
+ RemovedSuccs.insert(Succ);
Succ->removePredecessor(TIBB);
- } else
+ } else
CheckEdge = nullptr;
// Insert the new branch.
@@ -975,13 +975,13 @@ bool SimplifyCFGOpt::SimplifyEqualityComparisonWithOnlyPredecessor(
<< "\n");
EraseTerminatorAndDCECond(TI);
- if (DTU) {
- SmallVector<DominatorTree::UpdateType, 2> Updates;
- Updates.reserve(RemovedSuccs.size());
- for (auto *RemovedSucc : RemovedSuccs)
- Updates.push_back({DominatorTree::Delete, TIBB, RemovedSucc});
- DTU->applyUpdates(Updates);
- }
+ if (DTU) {
+ SmallVector<DominatorTree::UpdateType, 2> Updates;
+ Updates.reserve(RemovedSuccs.size());
+ for (auto *RemovedSucc : RemovedSuccs)
+ Updates.push_back({DominatorTree::Delete, TIBB, RemovedSucc});
+ DTU->applyUpdates(Updates);
+ }
return true;
}
@@ -1049,300 +1049,300 @@ static void FitWeights(MutableArrayRef<uint64_t> Weights) {
}
}
-static void CloneInstructionsIntoPredecessorBlockAndUpdateSSAUses(
- BasicBlock *BB, BasicBlock *PredBlock, ValueToValueMapTy &VMap) {
- Instruction *PTI = PredBlock->getTerminator();
-
- // If we have bonus instructions, clone them into the predecessor block.
- // Note that there may be multiple predecessor blocks, so we cannot move
- // bonus instructions to a predecessor block.
- for (Instruction &BonusInst : *BB) {
- if (isa<DbgInfoIntrinsic>(BonusInst) || BonusInst.isTerminator())
- continue;
-
- Instruction *NewBonusInst = BonusInst.clone();
-
- if (PTI->getDebugLoc() != NewBonusInst->getDebugLoc()) {
- // Unless the instruction has the same !dbg location as the original
- // branch, drop it. When we fold the bonus instructions we want to make
- // sure we reset their debug locations in order to avoid stepping on
- // dead code caused by folding dead branches.
- NewBonusInst->setDebugLoc(DebugLoc());
- }
-
- RemapInstruction(NewBonusInst, VMap,
- RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
- VMap[&BonusInst] = NewBonusInst;
-
- // If we moved a load, we cannot any longer claim any knowledge about
- // its potential value. The previous information might have been valid
- // only given the branch precondition.
- // For an analogous reason, we must also drop all the metadata whose
- // semantics we don't understand. We *can* preserve !annotation, because
- // it is tied to the instruction itself, not the value or position.
- NewBonusInst->dropUnknownNonDebugMetadata(LLVMContext::MD_annotation);
-
- PredBlock->getInstList().insert(PTI->getIterator(), NewBonusInst);
- NewBonusInst->takeName(&BonusInst);
- BonusInst.setName(NewBonusInst->getName() + ".old");
-
- // Update (liveout) uses of bonus instructions,
- // now that the bonus instruction has been cloned into predecessor.
- SSAUpdater SSAUpdate;
- SSAUpdate.Initialize(BonusInst.getType(),
- (NewBonusInst->getName() + ".merge").str());
- SSAUpdate.AddAvailableValue(BB, &BonusInst);
- SSAUpdate.AddAvailableValue(PredBlock, NewBonusInst);
- for (Use &U : make_early_inc_range(BonusInst.uses()))
- SSAUpdate.RewriteUseAfterInsertions(U);
- }
-}
-
-bool SimplifyCFGOpt::PerformValueComparisonIntoPredecessorFolding(
- Instruction *TI, Value *&CV, Instruction *PTI, IRBuilder<> &Builder) {
- BasicBlock *BB = TI->getParent();
- BasicBlock *Pred = PTI->getParent();
-
- std::vector<DominatorTree::UpdateType> Updates;
-
- // Figure out which 'cases' to copy from SI to PSI.
- std::vector<ValueEqualityComparisonCase> BBCases;
- BasicBlock *BBDefault = GetValueEqualityComparisonCases(TI, BBCases);
-
- std::vector<ValueEqualityComparisonCase> PredCases;
- BasicBlock *PredDefault = GetValueEqualityComparisonCases(PTI, PredCases);
-
- // Based on whether the default edge from PTI goes to BB or not, fill in
- // PredCases and PredDefault with the new switch cases we would like to
- // build.
- SmallMapVector<BasicBlock *, int, 8> NewSuccessors;
-
- // Update the branch weight metadata along the way
- SmallVector<uint64_t, 8> Weights;
- bool PredHasWeights = HasBranchWeights(PTI);
- bool SuccHasWeights = HasBranchWeights(TI);
-
- if (PredHasWeights) {
- GetBranchWeights(PTI, Weights);
- // branch-weight metadata is inconsistent here.
- if (Weights.size() != 1 + PredCases.size())
- PredHasWeights = SuccHasWeights = false;
- } else if (SuccHasWeights)
- // If there are no predecessor weights but there are successor weights,
- // populate Weights with 1, which will later be scaled to the sum of
- // successor's weights
- Weights.assign(1 + PredCases.size(), 1);
-
- SmallVector<uint64_t, 8> SuccWeights;
- if (SuccHasWeights) {
- GetBranchWeights(TI, SuccWeights);
- // branch-weight metadata is inconsistent here.
- if (SuccWeights.size() != 1 + BBCases.size())
- PredHasWeights = SuccHasWeights = false;
- } else if (PredHasWeights)
- SuccWeights.assign(1 + BBCases.size(), 1);
-
- if (PredDefault == BB) {
- // If this is the default destination from PTI, only the edges in TI
- // that don't occur in PTI, or that branch to BB will be activated.
- std::set<ConstantInt *, ConstantIntOrdering> PTIHandled;
- for (unsigned i = 0, e = PredCases.size(); i != e; ++i)
- if (PredCases[i].Dest != BB)
- PTIHandled.insert(PredCases[i].Value);
- else {
- // The default destination is BB, we don't need explicit targets.
- std::swap(PredCases[i], PredCases.back());
-
- if (PredHasWeights || SuccHasWeights) {
- // Increase weight for the default case.
- Weights[0] += Weights[i + 1];
- std::swap(Weights[i + 1], Weights.back());
- Weights.pop_back();
+static void CloneInstructionsIntoPredecessorBlockAndUpdateSSAUses(
+ BasicBlock *BB, BasicBlock *PredBlock, ValueToValueMapTy &VMap) {
+ Instruction *PTI = PredBlock->getTerminator();
+
+ // If we have bonus instructions, clone them into the predecessor block.
+ // Note that there may be multiple predecessor blocks, so we cannot move
+ // bonus instructions to a predecessor block.
+ for (Instruction &BonusInst : *BB) {
+ if (isa<DbgInfoIntrinsic>(BonusInst) || BonusInst.isTerminator())
+ continue;
+
+ Instruction *NewBonusInst = BonusInst.clone();
+
+ if (PTI->getDebugLoc() != NewBonusInst->getDebugLoc()) {
+ // Unless the instruction has the same !dbg location as the original
+ // branch, drop it. When we fold the bonus instructions we want to make
+ // sure we reset their debug locations in order to avoid stepping on
+ // dead code caused by folding dead branches.
+ NewBonusInst->setDebugLoc(DebugLoc());
+ }
+
+ RemapInstruction(NewBonusInst, VMap,
+ RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
+ VMap[&BonusInst] = NewBonusInst;
+
+ // If we moved a load, we cannot any longer claim any knowledge about
+ // its potential value. The previous information might have been valid
+ // only given the branch precondition.
+ // For an analogous reason, we must also drop all the metadata whose
+ // semantics we don't understand. We *can* preserve !annotation, because
+ // it is tied to the instruction itself, not the value or position.
+ NewBonusInst->dropUnknownNonDebugMetadata(LLVMContext::MD_annotation);
+
+ PredBlock->getInstList().insert(PTI->getIterator(), NewBonusInst);
+ NewBonusInst->takeName(&BonusInst);
+ BonusInst.setName(NewBonusInst->getName() + ".old");
+
+ // Update (liveout) uses of bonus instructions,
+ // now that the bonus instruction has been cloned into predecessor.
+ SSAUpdater SSAUpdate;
+ SSAUpdate.Initialize(BonusInst.getType(),
+ (NewBonusInst->getName() + ".merge").str());
+ SSAUpdate.AddAvailableValue(BB, &BonusInst);
+ SSAUpdate.AddAvailableValue(PredBlock, NewBonusInst);
+ for (Use &U : make_early_inc_range(BonusInst.uses()))
+ SSAUpdate.RewriteUseAfterInsertions(U);
+ }
+}
+
+bool SimplifyCFGOpt::PerformValueComparisonIntoPredecessorFolding(
+ Instruction *TI, Value *&CV, Instruction *PTI, IRBuilder<> &Builder) {
+ BasicBlock *BB = TI->getParent();
+ BasicBlock *Pred = PTI->getParent();
+
+ std::vector<DominatorTree::UpdateType> Updates;
+
+ // Figure out which 'cases' to copy from SI to PSI.
+ std::vector<ValueEqualityComparisonCase> BBCases;
+ BasicBlock *BBDefault = GetValueEqualityComparisonCases(TI, BBCases);
+
+ std::vector<ValueEqualityComparisonCase> PredCases;
+ BasicBlock *PredDefault = GetValueEqualityComparisonCases(PTI, PredCases);
+
+ // Based on whether the default edge from PTI goes to BB or not, fill in
+ // PredCases and PredDefault with the new switch cases we would like to
+ // build.
+ SmallMapVector<BasicBlock *, int, 8> NewSuccessors;
+
+ // Update the branch weight metadata along the way
+ SmallVector<uint64_t, 8> Weights;
+ bool PredHasWeights = HasBranchWeights(PTI);
+ bool SuccHasWeights = HasBranchWeights(TI);
+
+ if (PredHasWeights) {
+ GetBranchWeights(PTI, Weights);
+ // branch-weight metadata is inconsistent here.
+ if (Weights.size() != 1 + PredCases.size())
+ PredHasWeights = SuccHasWeights = false;
+ } else if (SuccHasWeights)
+ // If there are no predecessor weights but there are successor weights,
+ // populate Weights with 1, which will later be scaled to the sum of
+ // successor's weights
+ Weights.assign(1 + PredCases.size(), 1);
+
+ SmallVector<uint64_t, 8> SuccWeights;
+ if (SuccHasWeights) {
+ GetBranchWeights(TI, SuccWeights);
+ // branch-weight metadata is inconsistent here.
+ if (SuccWeights.size() != 1 + BBCases.size())
+ PredHasWeights = SuccHasWeights = false;
+ } else if (PredHasWeights)
+ SuccWeights.assign(1 + BBCases.size(), 1);
+
+ if (PredDefault == BB) {
+ // If this is the default destination from PTI, only the edges in TI
+ // that don't occur in PTI, or that branch to BB will be activated.
+ std::set<ConstantInt *, ConstantIntOrdering> PTIHandled;
+ for (unsigned i = 0, e = PredCases.size(); i != e; ++i)
+ if (PredCases[i].Dest != BB)
+ PTIHandled.insert(PredCases[i].Value);
+ else {
+ // The default destination is BB, we don't need explicit targets.
+ std::swap(PredCases[i], PredCases.back());
+
+ if (PredHasWeights || SuccHasWeights) {
+ // Increase weight for the default case.
+ Weights[0] += Weights[i + 1];
+ std::swap(Weights[i + 1], Weights.back());
+ Weights.pop_back();
}
- PredCases.pop_back();
- --i;
- --e;
- }
-
- // Reconstruct the new switch statement we will be building.
- if (PredDefault != BBDefault) {
- PredDefault->removePredecessor(Pred);
- if (PredDefault != BB)
- Updates.push_back({DominatorTree::Delete, Pred, PredDefault});
- PredDefault = BBDefault;
- ++NewSuccessors[BBDefault];
- }
-
- unsigned CasesFromPred = Weights.size();
- uint64_t ValidTotalSuccWeight = 0;
- for (unsigned i = 0, e = BBCases.size(); i != e; ++i)
- if (!PTIHandled.count(BBCases[i].Value) && BBCases[i].Dest != BBDefault) {
- PredCases.push_back(BBCases[i]);
- ++NewSuccessors[BBCases[i].Dest];
+ PredCases.pop_back();
+ --i;
+ --e;
+ }
+
+ // Reconstruct the new switch statement we will be building.
+ if (PredDefault != BBDefault) {
+ PredDefault->removePredecessor(Pred);
+ if (PredDefault != BB)
+ Updates.push_back({DominatorTree::Delete, Pred, PredDefault});
+ PredDefault = BBDefault;
+ ++NewSuccessors[BBDefault];
+ }
+
+ unsigned CasesFromPred = Weights.size();
+ uint64_t ValidTotalSuccWeight = 0;
+ for (unsigned i = 0, e = BBCases.size(); i != e; ++i)
+ if (!PTIHandled.count(BBCases[i].Value) && BBCases[i].Dest != BBDefault) {
+ PredCases.push_back(BBCases[i]);
+ ++NewSuccessors[BBCases[i].Dest];
if (SuccHasWeights || PredHasWeights) {
- // The default weight is at index 0, so weight for the ith case
- // should be at index i+1. Scale the cases from successor by
- // PredDefaultWeight (Weights[0]).
- Weights.push_back(Weights[0] * SuccWeights[i + 1]);
- ValidTotalSuccWeight += SuccWeights[i + 1];
+ // The default weight is at index 0, so weight for the ith case
+ // should be at index i+1. Scale the cases from successor by
+ // PredDefaultWeight (Weights[0]).
+ Weights.push_back(Weights[0] * SuccWeights[i + 1]);
+ ValidTotalSuccWeight += SuccWeights[i + 1];
+ }
+ }
+
+ if (SuccHasWeights || PredHasWeights) {
+ ValidTotalSuccWeight += SuccWeights[0];
+ // Scale the cases from predecessor by ValidTotalSuccWeight.
+ for (unsigned i = 1; i < CasesFromPred; ++i)
+ Weights[i] *= ValidTotalSuccWeight;
+ // Scale the default weight by SuccDefaultWeight (SuccWeights[0]).
+ Weights[0] *= SuccWeights[0];
+ }
+ } else {
+ // If this is not the default destination from PSI, only the edges
+ // in SI that occur in PSI with a destination of BB will be
+ // activated.
+ std::set<ConstantInt *, ConstantIntOrdering> PTIHandled;
+ std::map<ConstantInt *, uint64_t> WeightsForHandled;
+ for (unsigned i = 0, e = PredCases.size(); i != e; ++i)
+ if (PredCases[i].Dest == BB) {
+ PTIHandled.insert(PredCases[i].Value);
+
+ if (PredHasWeights || SuccHasWeights) {
+ WeightsForHandled[PredCases[i].Value] = Weights[i + 1];
+ std::swap(Weights[i + 1], Weights.back());
+ Weights.pop_back();
}
- }
-
- if (SuccHasWeights || PredHasWeights) {
- ValidTotalSuccWeight += SuccWeights[0];
- // Scale the cases from predecessor by ValidTotalSuccWeight.
- for (unsigned i = 1; i < CasesFromPred; ++i)
- Weights[i] *= ValidTotalSuccWeight;
- // Scale the default weight by SuccDefaultWeight (SuccWeights[0]).
- Weights[0] *= SuccWeights[0];
- }
- } else {
- // If this is not the default destination from PSI, only the edges
- // in SI that occur in PSI with a destination of BB will be
- // activated.
- std::set<ConstantInt *, ConstantIntOrdering> PTIHandled;
- std::map<ConstantInt *, uint64_t> WeightsForHandled;
- for (unsigned i = 0, e = PredCases.size(); i != e; ++i)
- if (PredCases[i].Dest == BB) {
- PTIHandled.insert(PredCases[i].Value);
-
- if (PredHasWeights || SuccHasWeights) {
- WeightsForHandled[PredCases[i].Value] = Weights[i + 1];
- std::swap(Weights[i + 1], Weights.back());
- Weights.pop_back();
- }
-
- std::swap(PredCases[i], PredCases.back());
- PredCases.pop_back();
- --i;
- --e;
- }
-
- // Okay, now we know which constants were sent to BB from the
- // predecessor. Figure out where they will all go now.
- for (unsigned i = 0, e = BBCases.size(); i != e; ++i)
- if (PTIHandled.count(BBCases[i].Value)) {
- // If this is one we are capable of getting...
- if (PredHasWeights || SuccHasWeights)
- Weights.push_back(WeightsForHandled[BBCases[i].Value]);
- PredCases.push_back(BBCases[i]);
- ++NewSuccessors[BBCases[i].Dest];
- PTIHandled.erase(BBCases[i].Value); // This constant is taken care of
+
+ std::swap(PredCases[i], PredCases.back());
+ PredCases.pop_back();
+ --i;
+ --e;
}
- // If there are any constants vectored to BB that TI doesn't handle,
- // they must go to the default destination of TI.
- for (ConstantInt *I : PTIHandled) {
- if (PredHasWeights || SuccHasWeights)
- Weights.push_back(WeightsForHandled[I]);
- PredCases.push_back(ValueEqualityComparisonCase(I, BBDefault));
- ++NewSuccessors[BBDefault];
- }
- }
-
- // Okay, at this point, we know which new successor Pred will get. Make
- // sure we update the number of entries in the PHI nodes for these
- // successors.
- for (const std::pair<BasicBlock *, int /*Num*/> &NewSuccessor :
- NewSuccessors) {
- for (auto I : seq(0, NewSuccessor.second)) {
- (void)I;
- AddPredecessorToBlock(NewSuccessor.first, Pred, BB);
- }
- if (!is_contained(successors(Pred), NewSuccessor.first))
- Updates.push_back({DominatorTree::Insert, Pred, NewSuccessor.first});
- }
-
- Builder.SetInsertPoint(PTI);
- // Convert pointer to int before we switch.
- if (CV->getType()->isPointerTy()) {
- CV =
- Builder.CreatePtrToInt(CV, DL.getIntPtrType(CV->getType()), "magicptr");
- }
-
- // Now that the successors are updated, create the new Switch instruction.
- SwitchInst *NewSI = Builder.CreateSwitch(CV, PredDefault, PredCases.size());
- NewSI->setDebugLoc(PTI->getDebugLoc());
- for (ValueEqualityComparisonCase &V : PredCases)
- NewSI->addCase(V.Value, V.Dest);
-
- if (PredHasWeights || SuccHasWeights) {
- // Halve the weights if any of them cannot fit in an uint32_t
- FitWeights(Weights);
-
- SmallVector<uint32_t, 8> MDWeights(Weights.begin(), Weights.end());
-
- setBranchWeights(NewSI, MDWeights);
- }
-
- EraseTerminatorAndDCECond(PTI);
-
- // Okay, last check. If BB is still a successor of PSI, then we must
- // have an infinite loop case. If so, add an infinitely looping block
- // to handle the case to preserve the behavior of the code.
- BasicBlock *InfLoopBlock = nullptr;
- for (unsigned i = 0, e = NewSI->getNumSuccessors(); i != e; ++i)
- if (NewSI->getSuccessor(i) == BB) {
- if (!InfLoopBlock) {
- // Insert it at the end of the function, because it's either code,
- // or it won't matter if it's hot. :)
- InfLoopBlock =
- BasicBlock::Create(BB->getContext(), "infloop", BB->getParent());
- BranchInst::Create(InfLoopBlock, InfLoopBlock);
- Updates.push_back({DominatorTree::Insert, InfLoopBlock, InfLoopBlock});
+ // Okay, now we know which constants were sent to BB from the
+ // predecessor. Figure out where they will all go now.
+ for (unsigned i = 0, e = BBCases.size(); i != e; ++i)
+ if (PTIHandled.count(BBCases[i].Value)) {
+ // If this is one we are capable of getting...
+ if (PredHasWeights || SuccHasWeights)
+ Weights.push_back(WeightsForHandled[BBCases[i].Value]);
+ PredCases.push_back(BBCases[i]);
+ ++NewSuccessors[BBCases[i].Dest];
+ PTIHandled.erase(BBCases[i].Value); // This constant is taken care of
}
- NewSI->setSuccessor(i, InfLoopBlock);
- }
-
- if (InfLoopBlock)
- Updates.push_back({DominatorTree::Insert, Pred, InfLoopBlock});
-
- Updates.push_back({DominatorTree::Delete, Pred, BB});
-
- if (DTU)
- DTU->applyUpdates(Updates);
-
- ++NumFoldValueComparisonIntoPredecessors;
- return true;
-}
-
-/// The specified terminator is a value equality comparison instruction
-/// (either a switch or a branch on "X == c").
-/// See if any of the predecessors of the terminator block are value comparisons
-/// on the same value. If so, and if safe to do so, fold them together.
-bool SimplifyCFGOpt::FoldValueComparisonIntoPredecessors(Instruction *TI,
- IRBuilder<> &Builder) {
- BasicBlock *BB = TI->getParent();
- Value *CV = isValueEqualityComparison(TI); // CondVal
- assert(CV && "Not a comparison?");
-
- bool Changed = false;
-
- SmallSetVector<BasicBlock *, 16> Preds(pred_begin(BB), pred_end(BB));
- while (!Preds.empty()) {
- BasicBlock *Pred = Preds.pop_back_val();
- Instruction *PTI = Pred->getTerminator();
-
- // Don't try to fold into itself.
- if (Pred == BB)
- continue;
-
- // See if the predecessor is a comparison with the same value.
- Value *PCV = isValueEqualityComparison(PTI); // PredCondVal
- if (PCV != CV)
- continue;
-
- SmallSetVector<BasicBlock *, 4> FailBlocks;
- if (!SafeToMergeTerminators(TI, PTI, &FailBlocks)) {
- for (auto *Succ : FailBlocks) {
- if (!SplitBlockPredecessors(Succ, TI->getParent(), ".fold.split", DTU))
- return false;
- }
+
+ // If there are any constants vectored to BB that TI doesn't handle,
+ // they must go to the default destination of TI.
+ for (ConstantInt *I : PTIHandled) {
+ if (PredHasWeights || SuccHasWeights)
+ Weights.push_back(WeightsForHandled[I]);
+ PredCases.push_back(ValueEqualityComparisonCase(I, BBDefault));
+ ++NewSuccessors[BBDefault];
}
-
- PerformValueComparisonIntoPredecessorFolding(TI, CV, PTI, Builder);
- Changed = true;
+ }
+
+ // Okay, at this point, we know which new successor Pred will get. Make
+ // sure we update the number of entries in the PHI nodes for these
+ // successors.
+ for (const std::pair<BasicBlock *, int /*Num*/> &NewSuccessor :
+ NewSuccessors) {
+ for (auto I : seq(0, NewSuccessor.second)) {
+ (void)I;
+ AddPredecessorToBlock(NewSuccessor.first, Pred, BB);
+ }
+ if (!is_contained(successors(Pred), NewSuccessor.first))
+ Updates.push_back({DominatorTree::Insert, Pred, NewSuccessor.first});
+ }
+
+ Builder.SetInsertPoint(PTI);
+ // Convert pointer to int before we switch.
+ if (CV->getType()->isPointerTy()) {
+ CV =
+ Builder.CreatePtrToInt(CV, DL.getIntPtrType(CV->getType()), "magicptr");
+ }
+
+ // Now that the successors are updated, create the new Switch instruction.
+ SwitchInst *NewSI = Builder.CreateSwitch(CV, PredDefault, PredCases.size());
+ NewSI->setDebugLoc(PTI->getDebugLoc());
+ for (ValueEqualityComparisonCase &V : PredCases)
+ NewSI->addCase(V.Value, V.Dest);
+
+ if (PredHasWeights || SuccHasWeights) {
+ // Halve the weights if any of them cannot fit in an uint32_t
+ FitWeights(Weights);
+
+ SmallVector<uint32_t, 8> MDWeights(Weights.begin(), Weights.end());
+
+ setBranchWeights(NewSI, MDWeights);
+ }
+
+ EraseTerminatorAndDCECond(PTI);
+
+ // Okay, last check. If BB is still a successor of PSI, then we must
+ // have an infinite loop case. If so, add an infinitely looping block
+ // to handle the case to preserve the behavior of the code.
+ BasicBlock *InfLoopBlock = nullptr;
+ for (unsigned i = 0, e = NewSI->getNumSuccessors(); i != e; ++i)
+ if (NewSI->getSuccessor(i) == BB) {
+ if (!InfLoopBlock) {
+ // Insert it at the end of the function, because it's either code,
+ // or it won't matter if it's hot. :)
+ InfLoopBlock =
+ BasicBlock::Create(BB->getContext(), "infloop", BB->getParent());
+ BranchInst::Create(InfLoopBlock, InfLoopBlock);
+ Updates.push_back({DominatorTree::Insert, InfLoopBlock, InfLoopBlock});
+ }
+ NewSI->setSuccessor(i, InfLoopBlock);
+ }
+
+ if (InfLoopBlock)
+ Updates.push_back({DominatorTree::Insert, Pred, InfLoopBlock});
+
+ Updates.push_back({DominatorTree::Delete, Pred, BB});
+
+ if (DTU)
+ DTU->applyUpdates(Updates);
+
+ ++NumFoldValueComparisonIntoPredecessors;
+ return true;
+}
+
+/// The specified terminator is a value equality comparison instruction
+/// (either a switch or a branch on "X == c").
+/// See if any of the predecessors of the terminator block are value comparisons
+/// on the same value. If so, and if safe to do so, fold them together.
+bool SimplifyCFGOpt::FoldValueComparisonIntoPredecessors(Instruction *TI,
+ IRBuilder<> &Builder) {
+ BasicBlock *BB = TI->getParent();
+ Value *CV = isValueEqualityComparison(TI); // CondVal
+ assert(CV && "Not a comparison?");
+
+ bool Changed = false;
+
+ SmallSetVector<BasicBlock *, 16> Preds(pred_begin(BB), pred_end(BB));
+ while (!Preds.empty()) {
+ BasicBlock *Pred = Preds.pop_back_val();
+ Instruction *PTI = Pred->getTerminator();
+
+ // Don't try to fold into itself.
+ if (Pred == BB)
+ continue;
+
+ // See if the predecessor is a comparison with the same value.
+ Value *PCV = isValueEqualityComparison(PTI); // PredCondVal
+ if (PCV != CV)
+ continue;
+
+ SmallSetVector<BasicBlock *, 4> FailBlocks;
+ if (!SafeToMergeTerminators(TI, PTI, &FailBlocks)) {
+ for (auto *Succ : FailBlocks) {
+ if (!SplitBlockPredecessors(Succ, TI->getParent(), ".fold.split", DTU))
+ return false;
+ }
+ }
+
+ PerformValueComparisonIntoPredecessorFolding(TI, CV, PTI, Builder);
+ Changed = true;
}
return Changed;
}
@@ -1364,7 +1364,7 @@ static bool isSafeToHoistInvoke(BasicBlock *BB1, BasicBlock *BB2,
return true;
}
-static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValueMayBeModified = false);
+static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValueMayBeModified = false);
/// Given a conditional branch that goes to BB1 and BB2, hoist any common code
/// in the two blocks up into the branch block. The caller of this function
@@ -1401,12 +1401,12 @@ bool SimplifyCFGOpt::HoistThenElseCodeToIf(BranchInst *BI,
BasicBlock *BIParent = BI->getParent();
bool Changed = false;
-
- auto _ = make_scope_exit([&]() {
- if (Changed)
- ++NumHoistCommonCode;
- });
-
+
+ auto _ = make_scope_exit([&]() {
+ if (Changed)
+ ++NumHoistCommonCode;
+ });
+
do {
// If we are hoisting the terminator instruction, don't move one (making a
// broken BB), instead clone it, and remove BI.
@@ -1475,7 +1475,7 @@ bool SimplifyCFGOpt::HoistThenElseCodeToIf(BranchInst *BI,
I2->eraseFromParent();
Changed = true;
}
- ++NumHoistCommonInstrs;
+ ++NumHoistCommonInstrs;
I1 = &*BB1_Itr++;
I2 = &*BB2_Itr++;
@@ -1530,8 +1530,8 @@ HoistTerminator:
I2->replaceAllUsesWith(NT);
NT->takeName(I1);
}
- Changed = true;
- ++NumHoistCommonInstrs;
+ Changed = true;
+ ++NumHoistCommonInstrs;
// Ensure terminator gets a debug location, even an unknown one, in case
// it involves inlinable calls.
@@ -1573,20 +1573,20 @@ HoistTerminator:
}
}
- SmallVector<DominatorTree::UpdateType, 4> Updates;
-
+ SmallVector<DominatorTree::UpdateType, 4> Updates;
+
// Update any PHI nodes in our new successors.
- for (BasicBlock *Succ : successors(BB1)) {
+ for (BasicBlock *Succ : successors(BB1)) {
AddPredecessorToBlock(Succ, BIParent, BB1);
- Updates.push_back({DominatorTree::Insert, BIParent, Succ});
- }
- for (BasicBlock *Succ : successors(BI))
- Updates.push_back({DominatorTree::Delete, BIParent, Succ});
+ Updates.push_back({DominatorTree::Insert, BIParent, Succ});
+ }
+ for (BasicBlock *Succ : successors(BI))
+ Updates.push_back({DominatorTree::Delete, BIParent, Succ});
EraseTerminatorAndDCECond(BI);
- if (DTU)
- DTU->applyUpdates(Updates);
- return Changed;
+ if (DTU)
+ DTU->applyUpdates(Updates);
+ return Changed;
}
// Check lifetime markers.
@@ -1628,11 +1628,11 @@ static bool canSinkInstructions(
I->getType()->isTokenTy())
return false;
- // Do not try to sink an instruction in an infinite loop - it can cause
- // this algorithm to infinite loop.
- if (I->getParent()->getSingleSuccessor() == I->getParent())
- return false;
-
+ // Do not try to sink an instruction in an infinite loop - it can cause
+ // this algorithm to infinite loop.
+ if (I->getParent()->getSingleSuccessor() == I->getParent())
+ return false;
+
// Conservatively return false if I is an inline-asm instruction. Sinking
// and merging inline-asm instructions can potentially create arguments
// that cannot satisfy the inline-asm constraints.
@@ -1719,13 +1719,13 @@ static bool canSinkInstructions(
return true;
}
-// Assuming canSinkInstructions(Blocks) has returned true, sink the last
+// Assuming canSinkInstructions(Blocks) has returned true, sink the last
// instruction of every block in Blocks to their common successor, commoning
// into one instruction.
static bool sinkLastInstruction(ArrayRef<BasicBlock*> Blocks) {
auto *BBEnd = Blocks[0]->getTerminator()->getSuccessor(0);
- // canSinkInstructions returning true guarantees that every block has at
+ // canSinkInstructions returning true guarantees that every block has at
// least one non-terminator instruction.
SmallVector<Instruction*,4> Insts;
for (auto *BB : Blocks) {
@@ -1738,9 +1738,9 @@ static bool sinkLastInstruction(ArrayRef<BasicBlock*> Blocks) {
}
// The only checking we need to do now is that all users of all instructions
- // are the same PHI node. canSinkInstructions should have checked this but
- // it is slightly over-aggressive - it gets confused by commutative
- // instructions so double-check it here.
+ // are the same PHI node. canSinkInstructions should have checked this but
+ // it is slightly over-aggressive - it gets confused by commutative
+ // instructions so double-check it here.
Instruction *I0 = Insts.front();
if (!I0->user_empty()) {
auto *PNUse = dyn_cast<PHINode>(*I0->user_begin());
@@ -1751,11 +1751,11 @@ static bool sinkLastInstruction(ArrayRef<BasicBlock*> Blocks) {
return false;
}
- // We don't need to do any more checking here; canSinkInstructions should
+ // We don't need to do any more checking here; canSinkInstructions should
// have done it all for us.
SmallVector<Value*, 4> NewOperands;
for (unsigned O = 0, E = I0->getNumOperands(); O != E; ++O) {
- // This check is different to that in canSinkInstructions. There, we
+ // This check is different to that in canSinkInstructions. There, we
// cared about the global view once simplifycfg (and instcombine) have
// completed - it takes into account PHIs that become trivially
// simplifiable. However here we need a more local view; if an operand
@@ -1882,8 +1882,8 @@ namespace {
/// true, sink any common code from the predecessors to BB.
/// We also allow one predecessor to end with conditional branch (but no more
/// than one).
-static bool SinkCommonCodeFromPredecessors(BasicBlock *BB,
- DomTreeUpdater *DTU) {
+static bool SinkCommonCodeFromPredecessors(BasicBlock *BB,
+ DomTreeUpdater *DTU) {
// We support two situations:
// (1) all incoming arcs are unconditional
// (2) one incoming arc is conditional
@@ -1958,12 +1958,12 @@ static bool SinkCommonCodeFromPredecessors(BasicBlock *BB,
--LRI;
}
- // If no instructions can be sunk, early-return.
- if (ScanIdx == 0)
- return false;
-
- bool Changed = false;
-
+ // If no instructions can be sunk, early-return.
+ if (ScanIdx == 0)
+ return false;
+
+ bool Changed = false;
+
auto ProfitableToSinkInstruction = [&](LockstepReverseIterator &LRI) {
unsigned NumPHIdValues = 0;
for (auto *I : *LRI)
@@ -1978,7 +1978,7 @@ static bool SinkCommonCodeFromPredecessors(BasicBlock *BB,
return NumPHIInsts <= 1;
};
- if (Cond) {
+ if (Cond) {
// Check if we would actually sink anything first! This mutates the CFG and
// adds an extra block. The goal in doing this is to allow instructions that
// couldn't be sunk before to be sunk - obviously, speculatable instructions
@@ -2001,7 +2001,7 @@ static bool SinkCommonCodeFromPredecessors(BasicBlock *BB,
LLVM_DEBUG(dbgs() << "SINK: Splitting edge\n");
// We have a conditional edge and we're going to sink some instructions.
// Insert a new block postdominating all blocks we're going to sink from.
- if (!SplitBlockPredecessors(BB, UnconditionalPreds, ".sink.split", DTU))
+ if (!SplitBlockPredecessors(BB, UnconditionalPreds, ".sink.split", DTU))
// Edges couldn't be split.
return false;
Changed = true;
@@ -2019,8 +2019,8 @@ static bool SinkCommonCodeFromPredecessors(BasicBlock *BB,
// sink presuming a later value will also be sunk, but stop half way through
// and never actually sink it which means we produce more PHIs than intended.
// This is unlikely in practice though.
- unsigned SinkIdx = 0;
- for (; SinkIdx != ScanIdx; ++SinkIdx) {
+ unsigned SinkIdx = 0;
+ for (; SinkIdx != ScanIdx; ++SinkIdx) {
LLVM_DEBUG(dbgs() << "SINK: Sink: "
<< *UnconditionalPreds[0]->getTerminator()->getPrevNode()
<< "\n");
@@ -2035,18 +2035,18 @@ static bool SinkCommonCodeFromPredecessors(BasicBlock *BB,
break;
}
- if (!sinkLastInstruction(UnconditionalPreds)) {
- LLVM_DEBUG(
- dbgs()
- << "SINK: stopping here, failed to actually sink instruction!\n");
- break;
- }
-
- NumSinkCommonInstrs++;
+ if (!sinkLastInstruction(UnconditionalPreds)) {
+ LLVM_DEBUG(
+ dbgs()
+ << "SINK: stopping here, failed to actually sink instruction!\n");
+ break;
+ }
+
+ NumSinkCommonInstrs++;
Changed = true;
}
- if (SinkIdx != 0)
- ++NumSinkCommonCode;
+ if (SinkIdx != 0)
+ ++NumSinkCommonCode;
return Changed;
}
@@ -2090,9 +2090,9 @@ static Value *isSafeToSpeculateStore(Instruction *I, BasicBlock *BrBB,
// Look for a store to the same pointer in BrBB.
unsigned MaxNumInstToLookAt = 9;
- // Skip pseudo probe intrinsic calls which are not really killing any memory
- // accesses.
- for (Instruction &CurI : reverse(BrBB->instructionsWithoutDebug(true))) {
+ // Skip pseudo probe intrinsic calls which are not really killing any memory
+ // accesses.
+ for (Instruction &CurI : reverse(BrBB->instructionsWithoutDebug(true))) {
if (!MaxNumInstToLookAt)
break;
--MaxNumInstToLookAt;
@@ -2113,65 +2113,65 @@ static Value *isSafeToSpeculateStore(Instruction *I, BasicBlock *BrBB,
return nullptr;
}
-/// Estimate the cost of the insertion(s) and check that the PHI nodes can be
-/// converted to selects.
-static bool validateAndCostRequiredSelects(BasicBlock *BB, BasicBlock *ThenBB,
- BasicBlock *EndBB,
- unsigned &SpeculatedInstructions,
- int &BudgetRemaining,
- const TargetTransformInfo &TTI) {
- TargetTransformInfo::TargetCostKind CostKind =
- BB->getParent()->hasMinSize()
- ? TargetTransformInfo::TCK_CodeSize
- : TargetTransformInfo::TCK_SizeAndLatency;
-
- bool HaveRewritablePHIs = false;
- for (PHINode &PN : EndBB->phis()) {
- Value *OrigV = PN.getIncomingValueForBlock(BB);
- Value *ThenV = PN.getIncomingValueForBlock(ThenBB);
-
- // FIXME: Try to remove some of the duplication with HoistThenElseCodeToIf.
- // Skip PHIs which are trivial.
- if (ThenV == OrigV)
- continue;
-
- BudgetRemaining -=
- TTI.getCmpSelInstrCost(Instruction::Select, PN.getType(), nullptr,
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
-
- // Don't convert to selects if we could remove undefined behavior instead.
- if (passingValueIsAlwaysUndefined(OrigV, &PN) ||
- passingValueIsAlwaysUndefined(ThenV, &PN))
- return false;
-
- HaveRewritablePHIs = true;
- ConstantExpr *OrigCE = dyn_cast<ConstantExpr>(OrigV);
- ConstantExpr *ThenCE = dyn_cast<ConstantExpr>(ThenV);
- if (!OrigCE && !ThenCE)
- continue; // Known safe and cheap.
-
- if ((ThenCE && !isSafeToSpeculativelyExecute(ThenCE)) ||
- (OrigCE && !isSafeToSpeculativelyExecute(OrigCE)))
- return false;
- unsigned OrigCost = OrigCE ? ComputeSpeculationCost(OrigCE, TTI) : 0;
- unsigned ThenCost = ThenCE ? ComputeSpeculationCost(ThenCE, TTI) : 0;
- unsigned MaxCost =
- 2 * PHINodeFoldingThreshold * TargetTransformInfo::TCC_Basic;
- if (OrigCost + ThenCost > MaxCost)
- return false;
-
- // Account for the cost of an unfolded ConstantExpr which could end up
- // getting expanded into Instructions.
- // FIXME: This doesn't account for how many operations are combined in the
- // constant expression.
- ++SpeculatedInstructions;
- if (SpeculatedInstructions > 1)
- return false;
- }
-
- return HaveRewritablePHIs;
-}
-
+/// Estimate the cost of the insertion(s) and check that the PHI nodes can be
+/// converted to selects.
+static bool validateAndCostRequiredSelects(BasicBlock *BB, BasicBlock *ThenBB,
+ BasicBlock *EndBB,
+ unsigned &SpeculatedInstructions,
+ int &BudgetRemaining,
+ const TargetTransformInfo &TTI) {
+ TargetTransformInfo::TargetCostKind CostKind =
+ BB->getParent()->hasMinSize()
+ ? TargetTransformInfo::TCK_CodeSize
+ : TargetTransformInfo::TCK_SizeAndLatency;
+
+ bool HaveRewritablePHIs = false;
+ for (PHINode &PN : EndBB->phis()) {
+ Value *OrigV = PN.getIncomingValueForBlock(BB);
+ Value *ThenV = PN.getIncomingValueForBlock(ThenBB);
+
+ // FIXME: Try to remove some of the duplication with HoistThenElseCodeToIf.
+ // Skip PHIs which are trivial.
+ if (ThenV == OrigV)
+ continue;
+
+ BudgetRemaining -=
+ TTI.getCmpSelInstrCost(Instruction::Select, PN.getType(), nullptr,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
+
+ // Don't convert to selects if we could remove undefined behavior instead.
+ if (passingValueIsAlwaysUndefined(OrigV, &PN) ||
+ passingValueIsAlwaysUndefined(ThenV, &PN))
+ return false;
+
+ HaveRewritablePHIs = true;
+ ConstantExpr *OrigCE = dyn_cast<ConstantExpr>(OrigV);
+ ConstantExpr *ThenCE = dyn_cast<ConstantExpr>(ThenV);
+ if (!OrigCE && !ThenCE)
+ continue; // Known safe and cheap.
+
+ if ((ThenCE && !isSafeToSpeculativelyExecute(ThenCE)) ||
+ (OrigCE && !isSafeToSpeculativelyExecute(OrigCE)))
+ return false;
+ unsigned OrigCost = OrigCE ? ComputeSpeculationCost(OrigCE, TTI) : 0;
+ unsigned ThenCost = ThenCE ? ComputeSpeculationCost(ThenCE, TTI) : 0;
+ unsigned MaxCost =
+ 2 * PHINodeFoldingThreshold * TargetTransformInfo::TCC_Basic;
+ if (OrigCost + ThenCost > MaxCost)
+ return false;
+
+ // Account for the cost of an unfolded ConstantExpr which could end up
+ // getting expanded into Instructions.
+ // FIXME: This doesn't account for how many operations are combined in the
+ // constant expression.
+ ++SpeculatedInstructions;
+ if (SpeculatedInstructions > 1)
+ return false;
+ }
+
+ return HaveRewritablePHIs;
+}
+
/// Speculate a conditional basic block flattening the CFG.
///
/// Note that this is a very risky transform currently. Speculating
@@ -2218,8 +2218,8 @@ bool SimplifyCFGOpt::SpeculativelyExecuteBB(BranchInst *BI, BasicBlock *ThenBB,
BasicBlock *BB = BI->getParent();
BasicBlock *EndBB = ThenBB->getTerminator()->getSuccessor(0);
- int BudgetRemaining =
- PHINodeFoldingThreshold * TargetTransformInfo::TCC_Basic;
+ int BudgetRemaining =
+ PHINodeFoldingThreshold * TargetTransformInfo::TCC_Basic;
// If ThenBB is actually on the false edge of the conditional branch, remember
// to swap the select operands later.
@@ -2252,14 +2252,14 @@ bool SimplifyCFGOpt::SpeculativelyExecuteBB(BranchInst *BI, BasicBlock *ThenBB,
continue;
}
- // Skip pseudo probes. The consequence is we lose track of the branch
- // probability for ThenBB, which is fine since the optimization here takes
- // place regardless of the branch probability.
- if (isa<PseudoProbeInst>(I)) {
- SpeculatedDbgIntrinsics.push_back(I);
- continue;
- }
-
+ // Skip pseudo probes. The consequence is we lose track of the branch
+ // probability for ThenBB, which is fine since the optimization here takes
+ // place regardless of the branch probability.
+ if (isa<PseudoProbeInst>(I)) {
+ SpeculatedDbgIntrinsics.push_back(I);
+ continue;
+ }
+
// Only speculatively execute a single instruction (not counting the
// terminator) for now.
++SpeculatedInstructions;
@@ -2305,13 +2305,13 @@ bool SimplifyCFGOpt::SpeculativelyExecuteBB(BranchInst *BI, BasicBlock *ThenBB,
return false;
}
- // Check that we can insert the selects and that it's not too expensive to do
- // so.
- bool Convert = SpeculatedStore != nullptr;
- Convert |= validateAndCostRequiredSelects(BB, ThenBB, EndBB,
- SpeculatedInstructions,
- BudgetRemaining, TTI);
- if (!Convert || BudgetRemaining < 0)
+ // Check that we can insert the selects and that it's not too expensive to do
+ // so.
+ bool Convert = SpeculatedStore != nullptr;
+ Convert |= validateAndCostRequiredSelects(BB, ThenBB, EndBB,
+ SpeculatedInstructions,
+ BudgetRemaining, TTI);
+ if (!Convert || BudgetRemaining < 0)
return false;
// If we get here, we can hoist the instruction and if-convert.
@@ -2385,12 +2385,12 @@ static bool BlockIsSimpleEnoughToThreadThrough(BasicBlock *BB) {
for (Instruction &I : BB->instructionsWithoutDebug()) {
if (Size > MaxSmallBlockSize)
return false; // Don't clone large BB's.
-
- // Can't fold blocks that contain noduplicate or convergent calls.
- if (CallInst *CI = dyn_cast<CallInst>(&I))
- if (CI->cannotDuplicate() || CI->isConvergent())
- return false;
-
+
+ // Can't fold blocks that contain noduplicate or convergent calls.
+ if (CallInst *CI = dyn_cast<CallInst>(&I))
+ if (CI->cannotDuplicate() || CI->isConvergent())
+ return false;
+
// We will delete Phis while threading, so Phis should not be accounted in
// block's size
if (!isa<PHINode>(I))
@@ -2413,8 +2413,8 @@ static bool BlockIsSimpleEnoughToThreadThrough(BasicBlock *BB) {
/// If we have a conditional branch on a PHI node value that is defined in the
/// same block as the branch and if any PHI entries are constants, thread edges
/// corresponding to that entry to be branches to their ultimate destination.
-static bool FoldCondBranchOnPHI(BranchInst *BI, DomTreeUpdater *DTU,
- const DataLayout &DL, AssumptionCache *AC) {
+static bool FoldCondBranchOnPHI(BranchInst *BI, DomTreeUpdater *DTU,
+ const DataLayout &DL, AssumptionCache *AC) {
BasicBlock *BB = BI->getParent();
PHINode *PN = dyn_cast<PHINode>(BI->getCondition());
// NOTE: we currently cannot transform this case if the PHI node is used
@@ -2450,8 +2450,8 @@ static bool FoldCondBranchOnPHI(BranchInst *BI, DomTreeUpdater *DTU,
if (isa<IndirectBrInst>(PredBB->getTerminator()))
continue;
- SmallVector<DominatorTree::UpdateType, 3> Updates;
-
+ SmallVector<DominatorTree::UpdateType, 3> Updates;
+
// The dest block might have PHI nodes, other predecessors and other
// difficult cases. Instead of being smart about this, just insert a new
// block that jumps to the destination block, effectively splitting
@@ -2460,7 +2460,7 @@ static bool FoldCondBranchOnPHI(BranchInst *BI, DomTreeUpdater *DTU,
BasicBlock::Create(BB->getContext(), RealDest->getName() + ".critedge",
RealDest->getParent(), RealDest);
BranchInst *CritEdgeBranch = BranchInst::Create(RealDest, EdgeBB);
- Updates.push_back({DominatorTree::Insert, EdgeBB, RealDest});
+ Updates.push_back({DominatorTree::Insert, EdgeBB, RealDest});
CritEdgeBranch->setDebugLoc(BI->getDebugLoc());
// Update PHI nodes.
@@ -2519,14 +2519,14 @@ static bool FoldCondBranchOnPHI(BranchInst *BI, DomTreeUpdater *DTU,
PredBBTI->setSuccessor(i, EdgeBB);
}
- Updates.push_back({DominatorTree::Insert, PredBB, EdgeBB});
- Updates.push_back({DominatorTree::Delete, PredBB, BB});
-
- if (DTU)
- DTU->applyUpdates(Updates);
-
+ Updates.push_back({DominatorTree::Insert, PredBB, EdgeBB});
+ Updates.push_back({DominatorTree::Delete, PredBB, BB});
+
+ if (DTU)
+ DTU->applyUpdates(Updates);
+
// Recurse, simplifying any other constants.
- return FoldCondBranchOnPHI(BI, DTU, DL, AC) || true;
+ return FoldCondBranchOnPHI(BI, DTU, DL, AC) || true;
}
return false;
@@ -2535,7 +2535,7 @@ static bool FoldCondBranchOnPHI(BranchInst *BI, DomTreeUpdater *DTU,
/// Given a BB that starts with the specified two-entry PHI node,
/// see if we can eliminate it.
static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
- DomTreeUpdater *DTU, const DataLayout &DL) {
+ DomTreeUpdater *DTU, const DataLayout &DL) {
// Ok, this is a two entry PHI node. Check to see if this is a simple "if
// statement", which has a very simple dominance structure. Basically, we
// are trying to find the condition that is being branched on, which
@@ -2568,13 +2568,13 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
int BudgetRemaining =
TwoEntryPHINodeFoldingThreshold * TargetTransformInfo::TCC_Basic;
- bool Changed = false;
+ bool Changed = false;
for (BasicBlock::iterator II = BB->begin(); isa<PHINode>(II);) {
PHINode *PN = cast<PHINode>(II++);
if (Value *V = SimplifyInstruction(PN, {DL, PN})) {
PN->replaceAllUsesWith(V);
PN->eraseFromParent();
- Changed = true;
+ Changed = true;
continue;
}
@@ -2582,7 +2582,7 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
BudgetRemaining, TTI) ||
!DominatesMergePoint(PN->getIncomingValue(1), BB, AggressiveInsts,
BudgetRemaining, TTI))
- return Changed;
+ return Changed;
}
// If we folded the first phi, PN dangles at this point. Refresh it. If
@@ -2609,7 +2609,7 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
isa<BinaryOperator>(IfCond)) &&
!CanHoistNotFromBothValues(PN->getIncomingValue(0),
PN->getIncomingValue(1)))
- return Changed;
+ return Changed;
// If all PHI nodes are promotable, check to make sure that all instructions
// in the predecessor blocks can be promoted as well. If not, we won't be able
@@ -2623,12 +2623,12 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
} else {
DomBlock = *pred_begin(IfBlock1);
for (BasicBlock::iterator I = IfBlock1->begin(); !I->isTerminator(); ++I)
- if (!AggressiveInsts.count(&*I) && !isa<DbgInfoIntrinsic>(I) &&
- !isa<PseudoProbeInst>(I)) {
+ if (!AggressiveInsts.count(&*I) && !isa<DbgInfoIntrinsic>(I) &&
+ !isa<PseudoProbeInst>(I)) {
// This is not an aggressive instruction that we can promote.
// Because of this, we won't be able to get rid of the control flow, so
// the xform is not worth it.
- return Changed;
+ return Changed;
}
}
@@ -2637,12 +2637,12 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
} else {
DomBlock = *pred_begin(IfBlock2);
for (BasicBlock::iterator I = IfBlock2->begin(); !I->isTerminator(); ++I)
- if (!AggressiveInsts.count(&*I) && !isa<DbgInfoIntrinsic>(I) &&
- !isa<PseudoProbeInst>(I)) {
+ if (!AggressiveInsts.count(&*I) && !isa<DbgInfoIntrinsic>(I) &&
+ !isa<PseudoProbeInst>(I)) {
// This is not an aggressive instruction that we can promote.
// Because of this, we won't be able to get rid of the control flow, so
// the xform is not worth it.
- return Changed;
+ return Changed;
}
}
assert(DomBlock && "Failed to find root DomBlock");
@@ -2685,18 +2685,18 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
Instruction *OldTI = DomBlock->getTerminator();
Builder.SetInsertPoint(OldTI);
Builder.CreateBr(BB);
-
- SmallVector<DominatorTree::UpdateType, 3> Updates;
- if (DTU) {
- Updates.push_back({DominatorTree::Insert, DomBlock, BB});
- for (auto *Successor : successors(DomBlock))
- Updates.push_back({DominatorTree::Delete, DomBlock, Successor});
- }
-
+
+ SmallVector<DominatorTree::UpdateType, 3> Updates;
+ if (DTU) {
+ Updates.push_back({DominatorTree::Insert, DomBlock, BB});
+ for (auto *Successor : successors(DomBlock))
+ Updates.push_back({DominatorTree::Delete, DomBlock, Successor});
+ }
+
OldTI->eraseFromParent();
- if (DTU)
- DTU->applyUpdates(Updates);
-
+ if (DTU)
+ DTU->applyUpdates(Updates);
+
return true;
}
@@ -2705,11 +2705,11 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
/// introducing a select if the return values disagree.
bool SimplifyCFGOpt::SimplifyCondBranchToTwoReturns(BranchInst *BI,
IRBuilder<> &Builder) {
- auto *BB = BI->getParent();
+ auto *BB = BI->getParent();
assert(BI->isConditional() && "Must be a conditional branch");
BasicBlock *TrueSucc = BI->getSuccessor(0);
BasicBlock *FalseSucc = BI->getSuccessor(1);
- // NOTE: destinations may match, this could be degenerate uncond branch.
+ // NOTE: destinations may match, this could be degenerate uncond branch.
ReturnInst *TrueRet = cast<ReturnInst>(TrueSucc->getTerminator());
ReturnInst *FalseRet = cast<ReturnInst>(FalseSucc->getTerminator());
@@ -2726,17 +2726,17 @@ bool SimplifyCFGOpt::SimplifyCondBranchToTwoReturns(BranchInst *BI,
// there is no return value for this function, just change the
// branch into a return.
if (FalseRet->getNumOperands() == 0) {
- TrueSucc->removePredecessor(BB);
- FalseSucc->removePredecessor(BB);
+ TrueSucc->removePredecessor(BB);
+ FalseSucc->removePredecessor(BB);
Builder.CreateRetVoid();
EraseTerminatorAndDCECond(BI);
- if (DTU) {
- SmallVector<DominatorTree::UpdateType, 2> Updates;
- Updates.push_back({DominatorTree::Delete, BB, TrueSucc});
- if (TrueSucc != FalseSucc)
- Updates.push_back({DominatorTree::Delete, BB, FalseSucc});
- DTU->applyUpdates(Updates);
- }
+ if (DTU) {
+ SmallVector<DominatorTree::UpdateType, 2> Updates;
+ Updates.push_back({DominatorTree::Delete, BB, TrueSucc});
+ if (TrueSucc != FalseSucc)
+ Updates.push_back({DominatorTree::Delete, BB, FalseSucc});
+ DTU->applyUpdates(Updates);
+ }
return true;
}
@@ -2748,10 +2748,10 @@ bool SimplifyCFGOpt::SimplifyCondBranchToTwoReturns(BranchInst *BI,
// Unwrap any PHI nodes in the return blocks.
if (PHINode *TVPN = dyn_cast_or_null<PHINode>(TrueValue))
if (TVPN->getParent() == TrueSucc)
- TrueValue = TVPN->getIncomingValueForBlock(BB);
+ TrueValue = TVPN->getIncomingValueForBlock(BB);
if (PHINode *FVPN = dyn_cast_or_null<PHINode>(FalseValue))
if (FVPN->getParent() == FalseSucc)
- FalseValue = FVPN->getIncomingValueForBlock(BB);
+ FalseValue = FVPN->getIncomingValueForBlock(BB);
// In order for this transformation to be safe, we must be able to
// unconditionally execute both operands to the return. This is
@@ -2767,8 +2767,8 @@ bool SimplifyCFGOpt::SimplifyCondBranchToTwoReturns(BranchInst *BI,
// Okay, we collected all the mapped values and checked them for sanity, and
// defined to really do this transformation. First, update the CFG.
- TrueSucc->removePredecessor(BB);
- FalseSucc->removePredecessor(BB);
+ TrueSucc->removePredecessor(BB);
+ FalseSucc->removePredecessor(BB);
// Insert select instructions where needed.
Value *BrCond = BI->getCondition();
@@ -2793,13 +2793,13 @@ bool SimplifyCFGOpt::SimplifyCondBranchToTwoReturns(BranchInst *BI,
<< *TrueSucc << "\nFALSEBLOCK: " << *FalseSucc);
EraseTerminatorAndDCECond(BI);
- if (DTU) {
- SmallVector<DominatorTree::UpdateType, 2> Updates;
- Updates.push_back({DominatorTree::Delete, BB, TrueSucc});
- if (TrueSucc != FalseSucc)
- Updates.push_back({DominatorTree::Delete, BB, FalseSucc});
- DTU->applyUpdates(Updates);
- }
+ if (DTU) {
+ SmallVector<DominatorTree::UpdateType, 2> Updates;
+ Updates.push_back({DominatorTree::Delete, BB, TrueSucc});
+ if (TrueSucc != FalseSucc)
+ Updates.push_back({DominatorTree::Delete, BB, FalseSucc});
+ DTU->applyUpdates(Updates);
+ }
return true;
}
@@ -2827,169 +2827,169 @@ static bool extractPredSuccWeights(BranchInst *PBI, BranchInst *BI,
}
}
-// Determine if the two branches share a common destination,
-// and deduce a glue that we need to use to join branch's conditions
-// to arrive at the common destination.
-static Optional<std::pair<Instruction::BinaryOps, bool>>
-CheckIfCondBranchesShareCommonDestination(BranchInst *BI, BranchInst *PBI) {
- assert(BI && PBI && BI->isConditional() && PBI->isConditional() &&
- "Both blocks must end with a conditional branches.");
- assert(is_contained(predecessors(BI->getParent()), PBI->getParent()) &&
- "PredBB must be a predecessor of BB.");
-
- if (PBI->getSuccessor(0) == BI->getSuccessor(0))
- return {{Instruction::Or, false}};
- else if (PBI->getSuccessor(1) == BI->getSuccessor(1))
- return {{Instruction::And, false}};
- else if (PBI->getSuccessor(0) == BI->getSuccessor(1))
- return {{Instruction::And, true}};
- else if (PBI->getSuccessor(1) == BI->getSuccessor(0))
- return {{Instruction::Or, true}};
- return None;
-}
-
-static bool PerformBranchToCommonDestFolding(BranchInst *BI, BranchInst *PBI,
- DomTreeUpdater *DTU,
- MemorySSAUpdater *MSSAU) {
- BasicBlock *BB = BI->getParent();
- BasicBlock *PredBlock = PBI->getParent();
-
- // Determine if the two branches share a common destination.
- Instruction::BinaryOps Opc;
- bool InvertPredCond;
- std::tie(Opc, InvertPredCond) =
- *CheckIfCondBranchesShareCommonDestination(BI, PBI);
-
- LLVM_DEBUG(dbgs() << "FOLDING BRANCH TO COMMON DEST:\n" << *PBI << *BB);
-
- IRBuilder<> Builder(PBI);
- // The builder is used to create instructions to eliminate the branch in BB.
- // If BB's terminator has !annotation metadata, add it to the new
- // instructions.
- Builder.CollectMetadataToCopy(BB->getTerminator(),
- {LLVMContext::MD_annotation});
-
- // If we need to invert the condition in the pred block to match, do so now.
- if (InvertPredCond) {
- Value *NewCond = PBI->getCondition();
- if (NewCond->hasOneUse() && isa<CmpInst>(NewCond)) {
- CmpInst *CI = cast<CmpInst>(NewCond);
- CI->setPredicate(CI->getInversePredicate());
- } else {
- NewCond =
- Builder.CreateNot(NewCond, PBI->getCondition()->getName() + ".not");
- }
-
- PBI->setCondition(NewCond);
- PBI->swapSuccessors();
- }
-
- BasicBlock *UniqueSucc =
- PBI->getSuccessor(0) == BB ? BI->getSuccessor(0) : BI->getSuccessor(1);
-
- // Before cloning instructions, notify the successor basic block that it
- // is about to have a new predecessor. This will update PHI nodes,
- // which will allow us to update live-out uses of bonus instructions.
- AddPredecessorToBlock(UniqueSucc, PredBlock, BB, MSSAU);
-
- // Try to update branch weights.
- uint64_t PredTrueWeight, PredFalseWeight, SuccTrueWeight, SuccFalseWeight;
- if (extractPredSuccWeights(PBI, BI, PredTrueWeight, PredFalseWeight,
- SuccTrueWeight, SuccFalseWeight)) {
- SmallVector<uint64_t, 8> NewWeights;
-
- if (PBI->getSuccessor(0) == BB) {
- // PBI: br i1 %x, BB, FalseDest
- // BI: br i1 %y, UniqueSucc, FalseDest
- // TrueWeight is TrueWeight for PBI * TrueWeight for BI.
- NewWeights.push_back(PredTrueWeight * SuccTrueWeight);
- // FalseWeight is FalseWeight for PBI * TotalWeight for BI +
- // TrueWeight for PBI * FalseWeight for BI.
- // We assume that total weights of a BranchInst can fit into 32 bits.
- // Therefore, we will not have overflow using 64-bit arithmetic.
- NewWeights.push_back(PredFalseWeight *
- (SuccFalseWeight + SuccTrueWeight) +
- PredTrueWeight * SuccFalseWeight);
- } else {
- // PBI: br i1 %x, TrueDest, BB
- // BI: br i1 %y, TrueDest, UniqueSucc
- // TrueWeight is TrueWeight for PBI * TotalWeight for BI +
- // FalseWeight for PBI * TrueWeight for BI.
- NewWeights.push_back(PredTrueWeight * (SuccFalseWeight + SuccTrueWeight) +
- PredFalseWeight * SuccTrueWeight);
- // FalseWeight is FalseWeight for PBI * FalseWeight for BI.
- NewWeights.push_back(PredFalseWeight * SuccFalseWeight);
- }
-
- // Halve the weights if any of them cannot fit in an uint32_t
- FitWeights(NewWeights);
-
- SmallVector<uint32_t, 8> MDWeights(NewWeights.begin(), NewWeights.end());
- setBranchWeights(PBI, MDWeights[0], MDWeights[1]);
-
- // TODO: If BB is reachable from all paths through PredBlock, then we
- // could replace PBI's branch probabilities with BI's.
- } else
- PBI->setMetadata(LLVMContext::MD_prof, nullptr);
-
- // Now, update the CFG.
- PBI->setSuccessor(PBI->getSuccessor(0) != BB, UniqueSucc);
-
- if (DTU)
- DTU->applyUpdates({{DominatorTree::Insert, PredBlock, UniqueSucc},
- {DominatorTree::Delete, PredBlock, BB}});
-
- // If BI was a loop latch, it may have had associated loop metadata.
- // We need to copy it to the new latch, that is, PBI.
- if (MDNode *LoopMD = BI->getMetadata(LLVMContext::MD_loop))
- PBI->setMetadata(LLVMContext::MD_loop, LoopMD);
-
- ValueToValueMapTy VMap; // maps original values to cloned values
- CloneInstructionsIntoPredecessorBlockAndUpdateSSAUses(BB, PredBlock, VMap);
-
- // Now that the Cond was cloned into the predecessor basic block,
- // or/and the two conditions together.
- Instruction *NewCond = cast<Instruction>(Builder.CreateBinOp(
- Opc, PBI->getCondition(), VMap[BI->getCondition()], "or.cond"));
- PBI->setCondition(NewCond);
-
- // Copy any debug value intrinsics into the end of PredBlock.
- for (Instruction &I : *BB) {
- if (isa<DbgInfoIntrinsic>(I)) {
- Instruction *NewI = I.clone();
- RemapInstruction(NewI, VMap,
- RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
- NewI->insertBefore(PBI);
- }
- }
-
- ++NumFoldBranchToCommonDest;
- return true;
-}
-
+// Determine if the two branches share a common destination,
+// and deduce a glue that we need to use to join branch's conditions
+// to arrive at the common destination.
+static Optional<std::pair<Instruction::BinaryOps, bool>>
+CheckIfCondBranchesShareCommonDestination(BranchInst *BI, BranchInst *PBI) {
+ assert(BI && PBI && BI->isConditional() && PBI->isConditional() &&
+ "Both blocks must end with a conditional branches.");
+ assert(is_contained(predecessors(BI->getParent()), PBI->getParent()) &&
+ "PredBB must be a predecessor of BB.");
+
+ if (PBI->getSuccessor(0) == BI->getSuccessor(0))
+ return {{Instruction::Or, false}};
+ else if (PBI->getSuccessor(1) == BI->getSuccessor(1))
+ return {{Instruction::And, false}};
+ else if (PBI->getSuccessor(0) == BI->getSuccessor(1))
+ return {{Instruction::And, true}};
+ else if (PBI->getSuccessor(1) == BI->getSuccessor(0))
+ return {{Instruction::Or, true}};
+ return None;
+}
+
+static bool PerformBranchToCommonDestFolding(BranchInst *BI, BranchInst *PBI,
+ DomTreeUpdater *DTU,
+ MemorySSAUpdater *MSSAU) {
+ BasicBlock *BB = BI->getParent();
+ BasicBlock *PredBlock = PBI->getParent();
+
+ // Determine if the two branches share a common destination.
+ Instruction::BinaryOps Opc;
+ bool InvertPredCond;
+ std::tie(Opc, InvertPredCond) =
+ *CheckIfCondBranchesShareCommonDestination(BI, PBI);
+
+ LLVM_DEBUG(dbgs() << "FOLDING BRANCH TO COMMON DEST:\n" << *PBI << *BB);
+
+ IRBuilder<> Builder(PBI);
+ // The builder is used to create instructions to eliminate the branch in BB.
+ // If BB's terminator has !annotation metadata, add it to the new
+ // instructions.
+ Builder.CollectMetadataToCopy(BB->getTerminator(),
+ {LLVMContext::MD_annotation});
+
+ // If we need to invert the condition in the pred block to match, do so now.
+ if (InvertPredCond) {
+ Value *NewCond = PBI->getCondition();
+ if (NewCond->hasOneUse() && isa<CmpInst>(NewCond)) {
+ CmpInst *CI = cast<CmpInst>(NewCond);
+ CI->setPredicate(CI->getInversePredicate());
+ } else {
+ NewCond =
+ Builder.CreateNot(NewCond, PBI->getCondition()->getName() + ".not");
+ }
+
+ PBI->setCondition(NewCond);
+ PBI->swapSuccessors();
+ }
+
+ BasicBlock *UniqueSucc =
+ PBI->getSuccessor(0) == BB ? BI->getSuccessor(0) : BI->getSuccessor(1);
+
+ // Before cloning instructions, notify the successor basic block that it
+ // is about to have a new predecessor. This will update PHI nodes,
+ // which will allow us to update live-out uses of bonus instructions.
+ AddPredecessorToBlock(UniqueSucc, PredBlock, BB, MSSAU);
+
+ // Try to update branch weights.
+ uint64_t PredTrueWeight, PredFalseWeight, SuccTrueWeight, SuccFalseWeight;
+ if (extractPredSuccWeights(PBI, BI, PredTrueWeight, PredFalseWeight,
+ SuccTrueWeight, SuccFalseWeight)) {
+ SmallVector<uint64_t, 8> NewWeights;
+
+ if (PBI->getSuccessor(0) == BB) {
+ // PBI: br i1 %x, BB, FalseDest
+ // BI: br i1 %y, UniqueSucc, FalseDest
+ // TrueWeight is TrueWeight for PBI * TrueWeight for BI.
+ NewWeights.push_back(PredTrueWeight * SuccTrueWeight);
+ // FalseWeight is FalseWeight for PBI * TotalWeight for BI +
+ // TrueWeight for PBI * FalseWeight for BI.
+ // We assume that total weights of a BranchInst can fit into 32 bits.
+ // Therefore, we will not have overflow using 64-bit arithmetic.
+ NewWeights.push_back(PredFalseWeight *
+ (SuccFalseWeight + SuccTrueWeight) +
+ PredTrueWeight * SuccFalseWeight);
+ } else {
+ // PBI: br i1 %x, TrueDest, BB
+ // BI: br i1 %y, TrueDest, UniqueSucc
+ // TrueWeight is TrueWeight for PBI * TotalWeight for BI +
+ // FalseWeight for PBI * TrueWeight for BI.
+ NewWeights.push_back(PredTrueWeight * (SuccFalseWeight + SuccTrueWeight) +
+ PredFalseWeight * SuccTrueWeight);
+ // FalseWeight is FalseWeight for PBI * FalseWeight for BI.
+ NewWeights.push_back(PredFalseWeight * SuccFalseWeight);
+ }
+
+ // Halve the weights if any of them cannot fit in an uint32_t
+ FitWeights(NewWeights);
+
+ SmallVector<uint32_t, 8> MDWeights(NewWeights.begin(), NewWeights.end());
+ setBranchWeights(PBI, MDWeights[0], MDWeights[1]);
+
+ // TODO: If BB is reachable from all paths through PredBlock, then we
+ // could replace PBI's branch probabilities with BI's.
+ } else
+ PBI->setMetadata(LLVMContext::MD_prof, nullptr);
+
+ // Now, update the CFG.
+ PBI->setSuccessor(PBI->getSuccessor(0) != BB, UniqueSucc);
+
+ if (DTU)
+ DTU->applyUpdates({{DominatorTree::Insert, PredBlock, UniqueSucc},
+ {DominatorTree::Delete, PredBlock, BB}});
+
+ // If BI was a loop latch, it may have had associated loop metadata.
+ // We need to copy it to the new latch, that is, PBI.
+ if (MDNode *LoopMD = BI->getMetadata(LLVMContext::MD_loop))
+ PBI->setMetadata(LLVMContext::MD_loop, LoopMD);
+
+ ValueToValueMapTy VMap; // maps original values to cloned values
+ CloneInstructionsIntoPredecessorBlockAndUpdateSSAUses(BB, PredBlock, VMap);
+
+ // Now that the Cond was cloned into the predecessor basic block,
+ // or/and the two conditions together.
+ Instruction *NewCond = cast<Instruction>(Builder.CreateBinOp(
+ Opc, PBI->getCondition(), VMap[BI->getCondition()], "or.cond"));
+ PBI->setCondition(NewCond);
+
+ // Copy any debug value intrinsics into the end of PredBlock.
+ for (Instruction &I : *BB) {
+ if (isa<DbgInfoIntrinsic>(I)) {
+ Instruction *NewI = I.clone();
+ RemapInstruction(NewI, VMap,
+ RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
+ NewI->insertBefore(PBI);
+ }
+ }
+
+ ++NumFoldBranchToCommonDest;
+ return true;
+}
+
/// If this basic block is simple enough, and if a predecessor branches to us
/// and one of our successors, fold the block into the predecessor and use
/// logical operations to pick the right destination.
-bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU,
- MemorySSAUpdater *MSSAU,
- const TargetTransformInfo *TTI,
+bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU,
+ MemorySSAUpdater *MSSAU,
+ const TargetTransformInfo *TTI,
unsigned BonusInstThreshold) {
- // If this block ends with an unconditional branch,
- // let SpeculativelyExecuteBB() deal with it.
- if (!BI->isConditional())
- return false;
-
+ // If this block ends with an unconditional branch,
+ // let SpeculativelyExecuteBB() deal with it.
+ if (!BI->isConditional())
+ return false;
+
BasicBlock *BB = BI->getParent();
const unsigned PredCount = pred_size(BB);
bool Changed = false;
- TargetTransformInfo::TargetCostKind CostKind =
- BB->getParent()->hasMinSize() ? TargetTransformInfo::TCK_CodeSize
- : TargetTransformInfo::TCK_SizeAndLatency;
+ TargetTransformInfo::TargetCostKind CostKind =
+ BB->getParent()->hasMinSize() ? TargetTransformInfo::TCK_CodeSize
+ : TargetTransformInfo::TCK_SizeAndLatency;
- Instruction *Cond = dyn_cast<Instruction>(BI->getCondition());
+ Instruction *Cond = dyn_cast<Instruction>(BI->getCondition());
if (!Cond || (!isa<CmpInst>(Cond) && !isa<BinaryOperator>(Cond)) ||
Cond->getParent() != BB || !Cond->hasOneUse())
@@ -3002,15 +3002,15 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU,
// number of the bonus instructions we'll need to create when cloning into
// each predecessor does not exceed a certain threshold.
unsigned NumBonusInsts = 0;
- for (Instruction &I : *BB) {
- // Don't check the branch condition comparison itself.
- if (&I == Cond)
+ for (Instruction &I : *BB) {
+ // Don't check the branch condition comparison itself.
+ if (&I == Cond)
+ continue;
+ // Ignore dbg intrinsics, and the terminator.
+ if (isa<DbgInfoIntrinsic>(I) || isa<BranchInst>(I))
continue;
- // Ignore dbg intrinsics, and the terminator.
- if (isa<DbgInfoIntrinsic>(I) || isa<BranchInst>(I))
- continue;
- // I must be safe to execute unconditionally.
- if (!isSafeToSpeculativelyExecute(&I))
+ // I must be safe to execute unconditionally.
+ if (!isSafeToSpeculativelyExecute(&I))
return Changed;
// Account for the cost of duplicating this instruction into each
@@ -3031,7 +3031,7 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU,
return Changed;
// Finally, don't infinitely unroll conditional loops.
- if (is_contained(successors(BB), BB))
+ if (is_contained(successors(BB), BB))
return Changed;
for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
@@ -3041,31 +3041,31 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU,
// Check that we have two conditional branches. If there is a PHI node in
// the common successor, verify that the same value flows in from both
// blocks.
- if (!PBI || PBI->isUnconditional() || !SafeToMergeTerminators(BI, PBI))
+ if (!PBI || PBI->isUnconditional() || !SafeToMergeTerminators(BI, PBI))
continue;
// Determine if the two branches share a common destination.
- Instruction::BinaryOps Opc;
- bool InvertPredCond;
- if (auto Recepie = CheckIfCondBranchesShareCommonDestination(BI, PBI))
- std::tie(Opc, InvertPredCond) = *Recepie;
- else
- continue;
-
- // Check the cost of inserting the necessary logic before performing the
- // transformation.
- if (TTI) {
- Type *Ty = BI->getCondition()->getType();
- unsigned Cost = TTI->getArithmeticInstrCost(Opc, Ty, CostKind);
- if (InvertPredCond && (!PBI->getCondition()->hasOneUse() ||
- !isa<CmpInst>(PBI->getCondition())))
- Cost += TTI->getArithmeticInstrCost(Instruction::Xor, Ty, CostKind);
-
- if (Cost > BranchFoldThreshold)
+ Instruction::BinaryOps Opc;
+ bool InvertPredCond;
+ if (auto Recepie = CheckIfCondBranchesShareCommonDestination(BI, PBI))
+ std::tie(Opc, InvertPredCond) = *Recepie;
+ else
+ continue;
+
+ // Check the cost of inserting the necessary logic before performing the
+ // transformation.
+ if (TTI) {
+ Type *Ty = BI->getCondition()->getType();
+ unsigned Cost = TTI->getArithmeticInstrCost(Opc, Ty, CostKind);
+ if (InvertPredCond && (!PBI->getCondition()->hasOneUse() ||
+ !isa<CmpInst>(PBI->getCondition())))
+ Cost += TTI->getArithmeticInstrCost(Instruction::Xor, Ty, CostKind);
+
+ if (Cost > BranchFoldThreshold)
continue;
}
- return PerformBranchToCommonDestFolding(BI, PBI, DTU, MSSAU);
+ return PerformBranchToCommonDestFolding(BI, PBI, DTU, MSSAU);
}
return Changed;
}
@@ -3138,10 +3138,10 @@ static Value *ensureValueAvailableInSuccessor(Value *V, BasicBlock *BB,
return PHI;
}
-static bool mergeConditionalStoreToAddress(
- BasicBlock *PTB, BasicBlock *PFB, BasicBlock *QTB, BasicBlock *QFB,
- BasicBlock *PostBB, Value *Address, bool InvertPCond, bool InvertQCond,
- DomTreeUpdater *DTU, const DataLayout &DL, const TargetTransformInfo &TTI) {
+static bool mergeConditionalStoreToAddress(
+ BasicBlock *PTB, BasicBlock *PFB, BasicBlock *QTB, BasicBlock *QFB,
+ BasicBlock *PostBB, Value *Address, bool InvertPCond, bool InvertQCond,
+ DomTreeUpdater *DTU, const DataLayout &DL, const TargetTransformInfo &TTI) {
// For every pointer, there must be exactly two stores, one coming from
// PTB or PFB, and the other from QTB or QFB. We don't support more than one
// store (to any address) in PTB,PFB or QTB,QFB.
@@ -3216,7 +3216,7 @@ static bool mergeConditionalStoreToAddress(
return true;
};
- const std::array<StoreInst *, 2> FreeStores = {PStore, QStore};
+ const std::array<StoreInst *, 2> FreeStores = {PStore, QStore};
if (!MergeCondStoresAggressively &&
(!IsWorthwhile(PTB, FreeStores) || !IsWorthwhile(PFB, FreeStores) ||
!IsWorthwhile(QTB, FreeStores) || !IsWorthwhile(QFB, FreeStores)))
@@ -3230,8 +3230,8 @@ static bool mergeConditionalStoreToAddress(
// If QTB does not exist, then QFB's only predecessor has a conditional
// branch to QFB and PostBB.
BasicBlock *TruePred = QTB ? QTB : QFB->getSinglePredecessor();
- BasicBlock *NewBB =
- SplitBlockPredecessors(PostBB, {QFB, TruePred}, "condstore.split", DTU);
+ BasicBlock *NewBB =
+ SplitBlockPredecessors(PostBB, {QFB, TruePred}, "condstore.split", DTU);
if (!NewBB)
return false;
PostBB = NewBB;
@@ -3260,9 +3260,9 @@ static bool mergeConditionalStoreToAddress(
QPred = QB.CreateNot(QPred);
Value *CombinedPred = QB.CreateOr(PPred, QPred);
- auto *T = SplitBlockAndInsertIfThen(CombinedPred, &*QB.GetInsertPoint(),
- /*Unreachable=*/false,
- /*BranchWeights=*/nullptr, DTU);
+ auto *T = SplitBlockAndInsertIfThen(CombinedPred, &*QB.GetInsertPoint(),
+ /*Unreachable=*/false,
+ /*BranchWeights=*/nullptr, DTU);
QB.SetInsertPoint(T);
StoreInst *SI = cast<StoreInst>(QB.CreateStore(QPHI, Address));
AAMDNodes AAMD;
@@ -3282,7 +3282,7 @@ static bool mergeConditionalStoreToAddress(
}
static bool mergeConditionalStores(BranchInst *PBI, BranchInst *QBI,
- DomTreeUpdater *DTU, const DataLayout &DL,
+ DomTreeUpdater *DTU, const DataLayout &DL,
const TargetTransformInfo &TTI) {
// The intention here is to find diamonds or triangles (see below) where each
// conditional block contains a store to the same address. Both of these
@@ -3384,17 +3384,17 @@ static bool mergeConditionalStores(BranchInst *PBI, BranchInst *QBI,
bool Changed = false;
for (auto *Address : CommonAddresses)
- Changed |=
- mergeConditionalStoreToAddress(PTB, PFB, QTB, QFB, PostBB, Address,
- InvertPCond, InvertQCond, DTU, DL, TTI);
+ Changed |=
+ mergeConditionalStoreToAddress(PTB, PFB, QTB, QFB, PostBB, Address,
+ InvertPCond, InvertQCond, DTU, DL, TTI);
return Changed;
}
/// If the previous block ended with a widenable branch, determine if reusing
/// the target block is profitable and legal. This will have the effect of
/// "widening" PBI, but doesn't require us to reason about hosting safety.
-static bool tryWidenCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI,
- DomTreeUpdater *DTU) {
+static bool tryWidenCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI,
+ DomTreeUpdater *DTU) {
// TODO: This can be generalized in two important ways:
// 1) We can allow phi nodes in IfFalseBB and simply reuse all the input
// values from the PBI edge.
@@ -3417,25 +3417,25 @@ static bool tryWidenCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI,
if (BI->getSuccessor(1) != IfFalseBB && // no inf looping
BI->getSuccessor(1)->getTerminatingDeoptimizeCall() && // profitability
NoSideEffects(*BI->getParent())) {
- auto *OldSuccessor = BI->getSuccessor(1);
- OldSuccessor->removePredecessor(BI->getParent());
+ auto *OldSuccessor = BI->getSuccessor(1);
+ OldSuccessor->removePredecessor(BI->getParent());
BI->setSuccessor(1, IfFalseBB);
- if (DTU)
- DTU->applyUpdates(
- {{DominatorTree::Insert, BI->getParent(), IfFalseBB},
- {DominatorTree::Delete, BI->getParent(), OldSuccessor}});
+ if (DTU)
+ DTU->applyUpdates(
+ {{DominatorTree::Insert, BI->getParent(), IfFalseBB},
+ {DominatorTree::Delete, BI->getParent(), OldSuccessor}});
return true;
}
if (BI->getSuccessor(0) != IfFalseBB && // no inf looping
BI->getSuccessor(0)->getTerminatingDeoptimizeCall() && // profitability
NoSideEffects(*BI->getParent())) {
- auto *OldSuccessor = BI->getSuccessor(0);
- OldSuccessor->removePredecessor(BI->getParent());
+ auto *OldSuccessor = BI->getSuccessor(0);
+ OldSuccessor->removePredecessor(BI->getParent());
BI->setSuccessor(0, IfFalseBB);
- if (DTU)
- DTU->applyUpdates(
- {{DominatorTree::Insert, BI->getParent(), IfFalseBB},
- {DominatorTree::Delete, BI->getParent(), OldSuccessor}});
+ if (DTU)
+ DTU->applyUpdates(
+ {{DominatorTree::Insert, BI->getParent(), IfFalseBB},
+ {DominatorTree::Delete, BI->getParent(), OldSuccessor}});
return true;
}
return false;
@@ -3446,7 +3446,7 @@ static bool tryWidenCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI,
/// that PBI and BI are both conditional branches, and BI is in one of the
/// successor blocks of PBI - PBI branches to BI.
static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI,
- DomTreeUpdater *DTU,
+ DomTreeUpdater *DTU,
const DataLayout &DL,
const TargetTransformInfo &TTI) {
assert(PBI->isConditional() && BI->isConditional());
@@ -3500,7 +3500,7 @@ static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI,
// If the previous block ended with a widenable branch, determine if reusing
// the target block is profitable and legal. This will have the effect of
// "widening" PBI, but doesn't require us to reason about hosting safety.
- if (tryWidenCondBranchToCondBranch(PBI, BI, DTU))
+ if (tryWidenCondBranchToCondBranch(PBI, BI, DTU))
return true;
if (auto *CE = dyn_cast<ConstantExpr>(BI->getCondition()))
@@ -3510,7 +3510,7 @@ static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI,
// If both branches are conditional and both contain stores to the same
// address, remove the stores from the conditionals and create a conditional
// merged store at the end.
- if (MergeCondStores && mergeConditionalStores(PBI, BI, DTU, DL, TTI))
+ if (MergeCondStores && mergeConditionalStores(PBI, BI, DTU, DL, TTI))
return true;
// If this is a conditional branch in an empty block, and if any
@@ -3553,7 +3553,7 @@ static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI,
// case, it would be unsafe to hoist the operation into a select instruction.
BasicBlock *CommonDest = PBI->getSuccessor(PBIOp);
- BasicBlock *RemovedDest = PBI->getSuccessor(PBIOp ^ 1);
+ BasicBlock *RemovedDest = PBI->getSuccessor(PBIOp ^ 1);
unsigned NumPhis = 0;
for (BasicBlock::iterator II = CommonDest->begin(); isa<PHINode>(II);
++II, ++NumPhis) {
@@ -3579,8 +3579,8 @@ static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI,
LLVM_DEBUG(dbgs() << "FOLDING BRs:" << *PBI->getParent()
<< "AND: " << *BI->getParent());
- SmallVector<DominatorTree::UpdateType, 5> Updates;
-
+ SmallVector<DominatorTree::UpdateType, 5> Updates;
+
// If OtherDest *is* BB, then BB is a basic block with a single conditional
// branch in it, where one edge (OtherDest) goes back to itself but the other
// exits. We don't *know* that the program avoids the infinite loop
@@ -3594,7 +3594,7 @@ static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI,
BasicBlock *InfLoopBlock =
BasicBlock::Create(BB->getContext(), "infloop", BB->getParent());
BranchInst::Create(InfLoopBlock, InfLoopBlock);
- Updates.push_back({DominatorTree::Insert, InfLoopBlock, InfLoopBlock});
+ Updates.push_back({DominatorTree::Insert, InfLoopBlock, InfLoopBlock});
OtherDest = InfLoopBlock;
}
@@ -3621,12 +3621,12 @@ static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI,
PBI->setSuccessor(0, CommonDest);
PBI->setSuccessor(1, OtherDest);
- Updates.push_back({DominatorTree::Insert, PBI->getParent(), OtherDest});
- Updates.push_back({DominatorTree::Delete, PBI->getParent(), RemovedDest});
-
- if (DTU)
- DTU->applyUpdates(Updates);
-
+ Updates.push_back({DominatorTree::Insert, PBI->getParent(), OtherDest});
+ Updates.push_back({DominatorTree::Delete, PBI->getParent(), RemovedDest});
+
+ if (DTU)
+ DTU->applyUpdates(Updates);
+
// Update branch weight for PBI.
uint64_t PredTrueWeight, PredFalseWeight, SuccTrueWeight, SuccFalseWeight;
uint64_t PredCommon, PredOther, SuccCommon, SuccOther;
@@ -3706,7 +3706,7 @@ bool SimplifyCFGOpt::SimplifyTerminatorOnSelect(Instruction *OldTerm,
BasicBlock *FalseBB,
uint32_t TrueWeight,
uint32_t FalseWeight) {
- auto *BB = OldTerm->getParent();
+ auto *BB = OldTerm->getParent();
// Remove any superfluous successor edges from the CFG.
// First, figure out which successors to preserve.
// If TrueBB and FalseBB are equal, only try to preserve one copy of that
@@ -3714,8 +3714,8 @@ bool SimplifyCFGOpt::SimplifyTerminatorOnSelect(Instruction *OldTerm,
BasicBlock *KeepEdge1 = TrueBB;
BasicBlock *KeepEdge2 = TrueBB != FalseBB ? FalseBB : nullptr;
- SmallSetVector<BasicBlock *, 2> RemovedSuccessors;
-
+ SmallSetVector<BasicBlock *, 2> RemovedSuccessors;
+
// Then remove the rest.
for (BasicBlock *Succ : successors(OldTerm)) {
// Make sure only to keep exactly one copy of each edge.
@@ -3723,13 +3723,13 @@ bool SimplifyCFGOpt::SimplifyTerminatorOnSelect(Instruction *OldTerm,
KeepEdge1 = nullptr;
else if (Succ == KeepEdge2)
KeepEdge2 = nullptr;
- else {
- Succ->removePredecessor(BB,
+ else {
+ Succ->removePredecessor(BB,
/*KeepOneInputPHIs=*/true);
-
- if (Succ != TrueBB && Succ != FalseBB)
- RemovedSuccessors.insert(Succ);
- }
+
+ if (Succ != TrueBB && Succ != FalseBB)
+ RemovedSuccessors.insert(Succ);
+ }
}
IRBuilder<> Builder(OldTerm);
@@ -3737,11 +3737,11 @@ bool SimplifyCFGOpt::SimplifyTerminatorOnSelect(Instruction *OldTerm,
// Insert an appropriate new terminator.
if (!KeepEdge1 && !KeepEdge2) {
- if (TrueBB == FalseBB) {
+ if (TrueBB == FalseBB) {
// We were only looking for one successor, and it was present.
// Create an unconditional branch to it.
Builder.CreateBr(TrueBB);
- } else {
+ } else {
// We found both of the successors we were looking for.
// Create a conditional branch sharing the condition of the select.
BranchInst *NewBI = Builder.CreateCondBr(Cond, TrueBB, FalseBB);
@@ -3756,25 +3756,25 @@ bool SimplifyCFGOpt::SimplifyTerminatorOnSelect(Instruction *OldTerm,
// One of the selected values was a successor, but the other wasn't.
// Insert an unconditional branch to the one that was found;
// the edge to the one that wasn't must be unreachable.
- if (!KeepEdge1) {
+ if (!KeepEdge1) {
// Only TrueBB was found.
Builder.CreateBr(TrueBB);
- } else {
+ } else {
// Only FalseBB was found.
Builder.CreateBr(FalseBB);
- }
+ }
}
EraseTerminatorAndDCECond(OldTerm);
-
- if (DTU) {
- SmallVector<DominatorTree::UpdateType, 2> Updates;
- Updates.reserve(RemovedSuccessors.size());
- for (auto *RemovedSuccessor : RemovedSuccessors)
- Updates.push_back({DominatorTree::Delete, BB, RemovedSuccessor});
- DTU->applyUpdates(Updates);
- }
-
+
+ if (DTU) {
+ SmallVector<DominatorTree::UpdateType, 2> Updates;
+ Updates.reserve(RemovedSuccessors.size());
+ for (auto *RemovedSuccessor : RemovedSuccessors)
+ Updates.push_back({DominatorTree::Delete, BB, RemovedSuccessor});
+ DTU->applyUpdates(Updates);
+ }
+
return true;
}
@@ -3929,8 +3929,8 @@ bool SimplifyCFGOpt::tryToSimplifyUncondBranchWithICmpInIt(
ICI->replaceAllUsesWith(DefaultCst);
ICI->eraseFromParent();
- SmallVector<DominatorTree::UpdateType, 2> Updates;
-
+ SmallVector<DominatorTree::UpdateType, 2> Updates;
+
// Okay, the switch goes to this block on a default value. Add an edge from
// the switch to the merge point on the compared value.
BasicBlock *NewBB =
@@ -3944,17 +3944,17 @@ bool SimplifyCFGOpt::tryToSimplifyUncondBranchWithICmpInIt(
SIW.setSuccessorWeight(0, *NewW);
}
SIW.addCase(Cst, NewBB, NewW);
- Updates.push_back({DominatorTree::Insert, Pred, NewBB});
+ Updates.push_back({DominatorTree::Insert, Pred, NewBB});
}
// NewBB branches to the phi block, add the uncond branch and the phi entry.
Builder.SetInsertPoint(NewBB);
Builder.SetCurrentDebugLocation(SI->getDebugLoc());
Builder.CreateBr(SuccBlock);
- Updates.push_back({DominatorTree::Insert, NewBB, SuccBlock});
+ Updates.push_back({DominatorTree::Insert, NewBB, SuccBlock});
PHIUse->addIncoming(NewCst, NewBB);
- if (DTU)
- DTU->applyUpdates(Updates);
+ if (DTU)
+ DTU->applyUpdates(Updates);
return true;
}
@@ -3988,7 +3988,7 @@ bool SimplifyCFGOpt::SimplifyBranchOnICmpChain(BranchInst *BI,
if (UsedICmps <= 1)
return false;
- bool TrueWhenEqual = match(Cond, m_LogicalOr(m_Value(), m_Value()));
+ bool TrueWhenEqual = match(Cond, m_LogicalOr(m_Value(), m_Value()));
// There might be duplicate constants in the list, which the switch
// instruction can't handle, remove them now.
@@ -4020,15 +4020,15 @@ bool SimplifyCFGOpt::SimplifyBranchOnICmpChain(BranchInst *BI,
<< " cases into SWITCH. BB is:\n"
<< *BB);
- SmallVector<DominatorTree::UpdateType, 2> Updates;
-
+ SmallVector<DominatorTree::UpdateType, 2> Updates;
+
// If there are any extra values that couldn't be folded into the switch
// then we evaluate them with an explicit branch first. Split the block
// right before the condbr to handle it.
if (ExtraCase) {
- BasicBlock *NewBB = SplitBlock(BB, BI, DTU, /*LI=*/nullptr,
- /*MSSAU=*/nullptr, "switch.early.test");
-
+ BasicBlock *NewBB = SplitBlock(BB, BI, DTU, /*LI=*/nullptr,
+ /*MSSAU=*/nullptr, "switch.early.test");
+
// Remove the uncond branch added to the old block.
Instruction *OldTI = BB->getTerminator();
Builder.SetInsertPoint(OldTI);
@@ -4040,8 +4040,8 @@ bool SimplifyCFGOpt::SimplifyBranchOnICmpChain(BranchInst *BI,
OldTI->eraseFromParent();
- Updates.push_back({DominatorTree::Insert, BB, EdgeBB});
-
+ Updates.push_back({DominatorTree::Insert, BB, EdgeBB});
+
// If there are PHI nodes in EdgeBB, then we need to add a new entry to them
// for the edge we just added.
AddPredecessorToBlock(EdgeBB, BB, NewBB);
@@ -4077,8 +4077,8 @@ bool SimplifyCFGOpt::SimplifyBranchOnICmpChain(BranchInst *BI,
// Erase the old branch instruction.
EraseTerminatorAndDCECond(BI);
- if (DTU)
- DTU->applyUpdates(Updates);
+ if (DTU)
+ DTU->applyUpdates(Updates);
LLVM_DEBUG(dbgs() << " ** 'icmp' chain result is:\n" << *BB << '\n');
return true;
@@ -4095,36 +4095,36 @@ bool SimplifyCFGOpt::simplifyResume(ResumeInst *RI, IRBuilder<> &Builder) {
return false;
}
-// Check if cleanup block is empty
-static bool isCleanupBlockEmpty(iterator_range<BasicBlock::iterator> R) {
- for (Instruction &I : R) {
- auto *II = dyn_cast<IntrinsicInst>(&I);
- if (!II)
- return false;
-
- Intrinsic::ID IntrinsicID = II->getIntrinsicID();
- switch (IntrinsicID) {
- case Intrinsic::dbg_declare:
- case Intrinsic::dbg_value:
- case Intrinsic::dbg_label:
- case Intrinsic::lifetime_end:
- break;
- default:
- return false;
- }
- }
- return true;
-}
-
+// Check if cleanup block is empty
+static bool isCleanupBlockEmpty(iterator_range<BasicBlock::iterator> R) {
+ for (Instruction &I : R) {
+ auto *II = dyn_cast<IntrinsicInst>(&I);
+ if (!II)
+ return false;
+
+ Intrinsic::ID IntrinsicID = II->getIntrinsicID();
+ switch (IntrinsicID) {
+ case Intrinsic::dbg_declare:
+ case Intrinsic::dbg_value:
+ case Intrinsic::dbg_label:
+ case Intrinsic::lifetime_end:
+ break;
+ default:
+ return false;
+ }
+ }
+ return true;
+}
+
// Simplify resume that is shared by several landing pads (phi of landing pad).
bool SimplifyCFGOpt::simplifyCommonResume(ResumeInst *RI) {
BasicBlock *BB = RI->getParent();
- // Check that there are no other instructions except for debug and lifetime
- // intrinsics between the phi's and resume instruction.
- if (!isCleanupBlockEmpty(
- make_range(RI->getParent()->getFirstNonPHI(), BB->getTerminator())))
- return false;
+ // Check that there are no other instructions except for debug and lifetime
+ // intrinsics between the phi's and resume instruction.
+ if (!isCleanupBlockEmpty(
+ make_range(RI->getParent()->getFirstNonPHI(), BB->getTerminator())))
+ return false;
SmallSetVector<BasicBlock *, 4> TrivialUnwindBlocks;
auto *PhiLPInst = cast<PHINode>(RI->getValue());
@@ -4145,8 +4145,8 @@ bool SimplifyCFGOpt::simplifyCommonResume(ResumeInst *RI) {
if (IncomingValue != LandingPad)
continue;
- if (isCleanupBlockEmpty(
- make_range(LandingPad->getNextNode(), IncomingBB->getTerminator())))
+ if (isCleanupBlockEmpty(
+ make_range(LandingPad->getNextNode(), IncomingBB->getTerminator())))
TrivialUnwindBlocks.insert(IncomingBB);
}
@@ -4165,8 +4165,8 @@ bool SimplifyCFGOpt::simplifyCommonResume(ResumeInst *RI) {
for (pred_iterator PI = pred_begin(TrivialBB), PE = pred_end(TrivialBB);
PI != PE;) {
BasicBlock *Pred = *PI++;
- removeUnwindEdge(Pred, DTU);
- ++NumInvokes;
+ removeUnwindEdge(Pred, DTU);
+ ++NumInvokes;
}
// In each SimplifyCFG run, only the current processed block can be erased.
@@ -4176,17 +4176,17 @@ bool SimplifyCFGOpt::simplifyCommonResume(ResumeInst *RI) {
// predecessors.
TrivialBB->getTerminator()->eraseFromParent();
new UnreachableInst(RI->getContext(), TrivialBB);
- if (DTU)
- DTU->applyUpdates({{DominatorTree::Delete, TrivialBB, BB}});
+ if (DTU)
+ DTU->applyUpdates({{DominatorTree::Delete, TrivialBB, BB}});
}
// Delete the resume block if all its predecessors have been removed.
- if (pred_empty(BB)) {
- if (DTU)
- DTU->deleteBB(BB);
- else
- BB->eraseFromParent();
- }
+ if (pred_empty(BB)) {
+ if (DTU)
+ DTU->deleteBB(BB);
+ else
+ BB->eraseFromParent();
+ }
return !TrivialUnwindBlocks.empty();
}
@@ -4199,26 +4199,26 @@ bool SimplifyCFGOpt::simplifySingleResume(ResumeInst *RI) {
"Resume must unwind the exception that caused control to here");
// Check that there are no other instructions except for debug intrinsics.
- if (!isCleanupBlockEmpty(
- make_range<Instruction *>(LPInst->getNextNode(), RI)))
+ if (!isCleanupBlockEmpty(
+ make_range<Instruction *>(LPInst->getNextNode(), RI)))
return false;
// Turn all invokes that unwind here into calls and delete the basic block.
for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE;) {
BasicBlock *Pred = *PI++;
- removeUnwindEdge(Pred, DTU);
- ++NumInvokes;
+ removeUnwindEdge(Pred, DTU);
+ ++NumInvokes;
}
// The landingpad is now unreachable. Zap it.
- if (DTU)
- DTU->deleteBB(BB);
- else
- BB->eraseFromParent();
+ if (DTU)
+ DTU->deleteBB(BB);
+ else
+ BB->eraseFromParent();
return true;
}
-static bool removeEmptyCleanup(CleanupReturnInst *RI, DomTreeUpdater *DTU) {
+static bool removeEmptyCleanup(CleanupReturnInst *RI, DomTreeUpdater *DTU) {
// If this is a trivial cleanup pad that executes no instructions, it can be
// eliminated. If the cleanup pad continues to the caller, any predecessor
// that is an EH pad will be updated to continue to the caller and any
@@ -4239,8 +4239,8 @@ static bool removeEmptyCleanup(CleanupReturnInst *RI, DomTreeUpdater *DTU) {
return false;
// Check that there are no other instructions except for benign intrinsics.
- if (!isCleanupBlockEmpty(
- make_range<Instruction *>(CPInst->getNextNode(), RI)))
+ if (!isCleanupBlockEmpty(
+ make_range<Instruction *>(CPInst->getNextNode(), RI)))
return false;
// If the cleanup return we are simplifying unwinds to the caller, this will
@@ -4325,32 +4325,32 @@ static bool removeEmptyCleanup(CleanupReturnInst *RI, DomTreeUpdater *DTU) {
}
}
- std::vector<DominatorTree::UpdateType> Updates;
-
+ std::vector<DominatorTree::UpdateType> Updates;
+
for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE;) {
// The iterator must be updated here because we are removing this pred.
BasicBlock *PredBB = *PI++;
if (UnwindDest == nullptr) {
- if (DTU)
- DTU->applyUpdates(Updates);
- Updates.clear();
- removeUnwindEdge(PredBB, DTU);
- ++NumInvokes;
+ if (DTU)
+ DTU->applyUpdates(Updates);
+ Updates.clear();
+ removeUnwindEdge(PredBB, DTU);
+ ++NumInvokes;
} else {
Instruction *TI = PredBB->getTerminator();
TI->replaceUsesOfWith(BB, UnwindDest);
- Updates.push_back({DominatorTree::Insert, PredBB, UnwindDest});
- Updates.push_back({DominatorTree::Delete, PredBB, BB});
+ Updates.push_back({DominatorTree::Insert, PredBB, UnwindDest});
+ Updates.push_back({DominatorTree::Delete, PredBB, BB});
}
}
- if (DTU) {
- DTU->applyUpdates(Updates);
- DTU->deleteBB(BB);
- } else
- // The cleanup pad is now unreachable. Zap it.
- BB->eraseFromParent();
-
+ if (DTU) {
+ DTU->applyUpdates(Updates);
+ DTU->deleteBB(BB);
+ } else
+ // The cleanup pad is now unreachable. Zap it.
+ BB->eraseFromParent();
+
return true;
}
@@ -4397,7 +4397,7 @@ bool SimplifyCFGOpt::simplifyCleanupReturn(CleanupReturnInst *RI) {
if (mergeCleanupPad(RI))
return true;
- if (removeEmptyCleanup(RI, DTU))
+ if (removeEmptyCleanup(RI, DTU))
return true;
return false;
@@ -4428,16 +4428,16 @@ bool SimplifyCFGOpt::simplifyReturn(ReturnInst *RI, IRBuilder<> &Builder) {
BasicBlock *Pred = UncondBranchPreds.pop_back_val();
LLVM_DEBUG(dbgs() << "FOLDING: " << *BB
<< "INTO UNCOND BRANCH PRED: " << *Pred);
- (void)FoldReturnIntoUncondBranch(RI, BB, Pred, DTU);
+ (void)FoldReturnIntoUncondBranch(RI, BB, Pred, DTU);
}
// If we eliminated all predecessors of the block, delete the block now.
if (pred_empty(BB)) {
// We know there are no successors, so just nuke the block.
- if (DTU)
- DTU->deleteBB(BB);
- else
- BB->eraseFromParent();
+ if (DTU)
+ DTU->deleteBB(BB);
+ else
+ BB->eraseFromParent();
}
return true;
@@ -4517,26 +4517,26 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) {
if (&BB->front() != UI)
return Changed;
- std::vector<DominatorTree::UpdateType> Updates;
-
- SmallSetVector<BasicBlock *, 8> Preds(pred_begin(BB), pred_end(BB));
+ std::vector<DominatorTree::UpdateType> Updates;
+
+ SmallSetVector<BasicBlock *, 8> Preds(pred_begin(BB), pred_end(BB));
for (unsigned i = 0, e = Preds.size(); i != e; ++i) {
- auto *Predecessor = Preds[i];
- Instruction *TI = Predecessor->getTerminator();
+ auto *Predecessor = Preds[i];
+ Instruction *TI = Predecessor->getTerminator();
IRBuilder<> Builder(TI);
if (auto *BI = dyn_cast<BranchInst>(TI)) {
- // We could either have a proper unconditional branch,
- // or a degenerate conditional branch with matching destinations.
- if (all_of(BI->successors(),
- [BB](auto *Successor) { return Successor == BB; })) {
+ // We could either have a proper unconditional branch,
+ // or a degenerate conditional branch with matching destinations.
+ if (all_of(BI->successors(),
+ [BB](auto *Successor) { return Successor == BB; })) {
new UnreachableInst(TI->getContext(), TI);
TI->eraseFromParent();
Changed = true;
} else {
- assert(BI->isConditional() && "Can't get here with an uncond branch.");
+ assert(BI->isConditional() && "Can't get here with an uncond branch.");
Value* Cond = BI->getCondition();
- assert(BI->getSuccessor(0) != BI->getSuccessor(1) &&
- "The destinations are guaranteed to be different here.");
+ assert(BI->getSuccessor(0) != BI->getSuccessor(1) &&
+ "The destinations are guaranteed to be different here.");
if (BI->getSuccessor(0) == BB) {
Builder.CreateAssumption(Builder.CreateNot(Cond));
Builder.CreateBr(BI->getSuccessor(1));
@@ -4548,7 +4548,7 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) {
EraseTerminatorAndDCECond(BI);
Changed = true;
}
- Updates.push_back({DominatorTree::Delete, Predecessor, BB});
+ Updates.push_back({DominatorTree::Delete, Predecessor, BB});
} else if (auto *SI = dyn_cast<SwitchInst>(TI)) {
SwitchInstProfUpdateWrapper SU(*SI);
for (auto i = SU->case_begin(), e = SU->case_end(); i != e;) {
@@ -4561,23 +4561,23 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) {
e = SU->case_end();
Changed = true;
}
- // Note that the default destination can't be removed!
- if (SI->getDefaultDest() != BB)
- Updates.push_back({DominatorTree::Delete, Predecessor, BB});
+ // Note that the default destination can't be removed!
+ if (SI->getDefaultDest() != BB)
+ Updates.push_back({DominatorTree::Delete, Predecessor, BB});
} else if (auto *II = dyn_cast<InvokeInst>(TI)) {
if (II->getUnwindDest() == BB) {
- if (DTU)
- DTU->applyUpdates(Updates);
- Updates.clear();
- removeUnwindEdge(TI->getParent(), DTU);
+ if (DTU)
+ DTU->applyUpdates(Updates);
+ Updates.clear();
+ removeUnwindEdge(TI->getParent(), DTU);
Changed = true;
}
} else if (auto *CSI = dyn_cast<CatchSwitchInst>(TI)) {
if (CSI->getUnwindDest() == BB) {
- if (DTU)
- DTU->applyUpdates(Updates);
- Updates.clear();
- removeUnwindEdge(TI->getParent(), DTU);
+ if (DTU)
+ DTU->applyUpdates(Updates);
+ Updates.clear();
+ removeUnwindEdge(TI->getParent(), DTU);
Changed = true;
continue;
}
@@ -4592,53 +4592,53 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) {
Changed = true;
}
}
- Updates.push_back({DominatorTree::Delete, Predecessor, BB});
+ Updates.push_back({DominatorTree::Delete, Predecessor, BB});
if (CSI->getNumHandlers() == 0) {
if (CSI->hasUnwindDest()) {
- // Redirect all predecessors of the block containing CatchSwitchInst
- // to instead branch to the CatchSwitchInst's unwind destination.
- for (auto *PredecessorOfPredecessor : predecessors(Predecessor)) {
- Updates.push_back({DominatorTree::Insert, PredecessorOfPredecessor,
- CSI->getUnwindDest()});
- Updates.push_back(
- {DominatorTree::Delete, PredecessorOfPredecessor, Predecessor});
- }
- Predecessor->replaceAllUsesWith(CSI->getUnwindDest());
+ // Redirect all predecessors of the block containing CatchSwitchInst
+ // to instead branch to the CatchSwitchInst's unwind destination.
+ for (auto *PredecessorOfPredecessor : predecessors(Predecessor)) {
+ Updates.push_back({DominatorTree::Insert, PredecessorOfPredecessor,
+ CSI->getUnwindDest()});
+ Updates.push_back(
+ {DominatorTree::Delete, PredecessorOfPredecessor, Predecessor});
+ }
+ Predecessor->replaceAllUsesWith(CSI->getUnwindDest());
} else {
// Rewrite all preds to unwind to caller (or from invoke to call).
- if (DTU)
- DTU->applyUpdates(Updates);
- Updates.clear();
- SmallVector<BasicBlock *, 8> EHPreds(predecessors(Predecessor));
+ if (DTU)
+ DTU->applyUpdates(Updates);
+ Updates.clear();
+ SmallVector<BasicBlock *, 8> EHPreds(predecessors(Predecessor));
for (BasicBlock *EHPred : EHPreds)
- removeUnwindEdge(EHPred, DTU);
+ removeUnwindEdge(EHPred, DTU);
}
// The catchswitch is no longer reachable.
new UnreachableInst(CSI->getContext(), CSI);
CSI->eraseFromParent();
Changed = true;
}
- } else if (auto *CRI = dyn_cast<CleanupReturnInst>(TI)) {
- (void)CRI;
- assert(CRI->hasUnwindDest() && CRI->getUnwindDest() == BB &&
- "Expected to always have an unwind to BB.");
- Updates.push_back({DominatorTree::Delete, Predecessor, BB});
+ } else if (auto *CRI = dyn_cast<CleanupReturnInst>(TI)) {
+ (void)CRI;
+ assert(CRI->hasUnwindDest() && CRI->getUnwindDest() == BB &&
+ "Expected to always have an unwind to BB.");
+ Updates.push_back({DominatorTree::Delete, Predecessor, BB});
new UnreachableInst(TI->getContext(), TI);
TI->eraseFromParent();
Changed = true;
}
}
- if (DTU)
- DTU->applyUpdates(Updates);
-
+ if (DTU)
+ DTU->applyUpdates(Updates);
+
// If this block is now dead, remove it.
if (pred_empty(BB) && BB != &BB->getParent()->getEntryBlock()) {
// We know there are no successors, so just nuke the block.
- if (DTU)
- DTU->deleteBB(BB);
- else
- BB->eraseFromParent();
+ if (DTU)
+ DTU->deleteBB(BB);
+ else
+ BB->eraseFromParent();
return true;
}
@@ -4656,26 +4656,26 @@ static bool CasesAreContiguous(SmallVectorImpl<ConstantInt *> &Cases) {
return true;
}
-static void createUnreachableSwitchDefault(SwitchInst *Switch,
- DomTreeUpdater *DTU) {
+static void createUnreachableSwitchDefault(SwitchInst *Switch,
+ DomTreeUpdater *DTU) {
LLVM_DEBUG(dbgs() << "SimplifyCFG: switch default is dead.\n");
- auto *BB = Switch->getParent();
- BasicBlock *NewDefaultBlock = SplitBlockPredecessors(
- Switch->getDefaultDest(), Switch->getParent(), "", DTU);
- auto *OrigDefaultBlock = Switch->getDefaultDest();
+ auto *BB = Switch->getParent();
+ BasicBlock *NewDefaultBlock = SplitBlockPredecessors(
+ Switch->getDefaultDest(), Switch->getParent(), "", DTU);
+ auto *OrigDefaultBlock = Switch->getDefaultDest();
Switch->setDefaultDest(&*NewDefaultBlock);
- if (DTU)
- DTU->applyUpdates({{DominatorTree::Insert, BB, &*NewDefaultBlock},
- {DominatorTree::Delete, BB, OrigDefaultBlock}});
- SplitBlock(&*NewDefaultBlock, &NewDefaultBlock->front(), DTU);
- SmallVector<DominatorTree::UpdateType, 2> Updates;
- for (auto *Successor : successors(NewDefaultBlock))
- Updates.push_back({DominatorTree::Delete, NewDefaultBlock, Successor});
+ if (DTU)
+ DTU->applyUpdates({{DominatorTree::Insert, BB, &*NewDefaultBlock},
+ {DominatorTree::Delete, BB, OrigDefaultBlock}});
+ SplitBlock(&*NewDefaultBlock, &NewDefaultBlock->front(), DTU);
+ SmallVector<DominatorTree::UpdateType, 2> Updates;
+ for (auto *Successor : successors(NewDefaultBlock))
+ Updates.push_back({DominatorTree::Delete, NewDefaultBlock, Successor});
auto *NewTerminator = NewDefaultBlock->getTerminator();
new UnreachableInst(Switch->getContext(), NewTerminator);
EraseTerminatorAndDCECond(NewTerminator);
- if (DTU)
- DTU->applyUpdates(Updates);
+ if (DTU)
+ DTU->applyUpdates(Updates);
}
/// Turn a switch with two reachable destinations into an integer range
@@ -4687,8 +4687,8 @@ bool SimplifyCFGOpt::TurnSwitchRangeIntoICmp(SwitchInst *SI,
bool HasDefault =
!isa<UnreachableInst>(SI->getDefaultDest()->getFirstNonPHIOrDbg());
- auto *BB = SI->getParent();
-
+ auto *BB = SI->getParent();
+
// Partition the cases into two sets with different destinations.
BasicBlock *DestA = HasDefault ? SI->getDefaultDest() : nullptr;
BasicBlock *DestB = nullptr;
@@ -4792,23 +4792,23 @@ bool SimplifyCFGOpt::TurnSwitchRangeIntoICmp(SwitchInst *SI,
// Clean up the default block - it may have phis or other instructions before
// the unreachable terminator.
if (!HasDefault)
- createUnreachableSwitchDefault(SI, DTU);
+ createUnreachableSwitchDefault(SI, DTU);
+
+ auto *UnreachableDefault = SI->getDefaultDest();
- auto *UnreachableDefault = SI->getDefaultDest();
-
// Drop the switch.
SI->eraseFromParent();
- if (!HasDefault && DTU)
- DTU->applyUpdates({{DominatorTree::Delete, BB, UnreachableDefault}});
-
+ if (!HasDefault && DTU)
+ DTU->applyUpdates({{DominatorTree::Delete, BB, UnreachableDefault}});
+
return true;
}
/// Compute masked bits for the condition of a switch
/// and use it to remove dead cases.
-static bool eliminateDeadSwitchCases(SwitchInst *SI, DomTreeUpdater *DTU,
- AssumptionCache *AC,
+static bool eliminateDeadSwitchCases(SwitchInst *SI, DomTreeUpdater *DTU,
+ AssumptionCache *AC,
const DataLayout &DL) {
Value *Cond = SI->getCondition();
unsigned Bits = Cond->getType()->getIntegerBitWidth();
@@ -4822,15 +4822,15 @@ static bool eliminateDeadSwitchCases(SwitchInst *SI, DomTreeUpdater *DTU,
// Gather dead cases.
SmallVector<ConstantInt *, 8> DeadCases;
- SmallMapVector<BasicBlock *, int, 8> NumPerSuccessorCases;
+ SmallMapVector<BasicBlock *, int, 8> NumPerSuccessorCases;
for (auto &Case : SI->cases()) {
- auto *Successor = Case.getCaseSuccessor();
- ++NumPerSuccessorCases[Successor];
+ auto *Successor = Case.getCaseSuccessor();
+ ++NumPerSuccessorCases[Successor];
const APInt &CaseVal = Case.getCaseValue()->getValue();
if (Known.Zero.intersects(CaseVal) || !Known.One.isSubsetOf(CaseVal) ||
(CaseVal.getMinSignedBits() > MaxSignificantBitsInCond)) {
DeadCases.push_back(Case.getCaseValue());
- --NumPerSuccessorCases[Successor];
+ --NumPerSuccessorCases[Successor];
LLVM_DEBUG(dbgs() << "SimplifyCFG: switch case " << CaseVal
<< " is dead.\n");
}
@@ -4848,7 +4848,7 @@ static bool eliminateDeadSwitchCases(SwitchInst *SI, DomTreeUpdater *DTU,
if (HasDefault && DeadCases.empty() &&
NumUnknownBits < 64 /* avoid overflow */ &&
SI->getNumCases() == (1ULL << NumUnknownBits)) {
- createUnreachableSwitchDefault(SI, DTU);
+ createUnreachableSwitchDefault(SI, DTU);
return true;
}
@@ -4865,13 +4865,13 @@ static bool eliminateDeadSwitchCases(SwitchInst *SI, DomTreeUpdater *DTU,
SIW.removeCase(CaseI);
}
- std::vector<DominatorTree::UpdateType> Updates;
- for (const std::pair<BasicBlock *, int> &I : NumPerSuccessorCases)
- if (I.second == 0)
- Updates.push_back({DominatorTree::Delete, SI->getParent(), I.first});
- if (DTU)
- DTU->applyUpdates(Updates);
-
+ std::vector<DominatorTree::UpdateType> Updates;
+ for (const std::pair<BasicBlock *, int> &I : NumPerSuccessorCases)
+ if (I.second == 0)
+ Updates.push_back({DominatorTree::Delete, SI->getParent(), I.first});
+ if (DTU)
+ DTU->applyUpdates(Updates);
+
return true;
}
@@ -5227,19 +5227,19 @@ static Value *ConvertTwoCaseSwitch(const SwitchCaseResultVectorTy &ResultVector,
// a select, fixing up PHI nodes and basic blocks.
static void RemoveSwitchAfterSelectConversion(SwitchInst *SI, PHINode *PHI,
Value *SelectValue,
- IRBuilder<> &Builder,
- DomTreeUpdater *DTU) {
- std::vector<DominatorTree::UpdateType> Updates;
-
+ IRBuilder<> &Builder,
+ DomTreeUpdater *DTU) {
+ std::vector<DominatorTree::UpdateType> Updates;
+
BasicBlock *SelectBB = SI->getParent();
- BasicBlock *DestBB = PHI->getParent();
-
- if (!is_contained(predecessors(DestBB), SelectBB))
- Updates.push_back({DominatorTree::Insert, SelectBB, DestBB});
- Builder.CreateBr(DestBB);
-
- // Remove the switch.
-
+ BasicBlock *DestBB = PHI->getParent();
+
+ if (!is_contained(predecessors(DestBB), SelectBB))
+ Updates.push_back({DominatorTree::Insert, SelectBB, DestBB});
+ Builder.CreateBr(DestBB);
+
+ // Remove the switch.
+
while (PHI->getBasicBlockIndex(SelectBB) >= 0)
PHI->removeIncomingValue(SelectBB);
PHI->addIncoming(SelectValue, SelectBB);
@@ -5247,21 +5247,21 @@ static void RemoveSwitchAfterSelectConversion(SwitchInst *SI, PHINode *PHI,
for (unsigned i = 0, e = SI->getNumSuccessors(); i < e; ++i) {
BasicBlock *Succ = SI->getSuccessor(i);
- if (Succ == DestBB)
+ if (Succ == DestBB)
continue;
Succ->removePredecessor(SelectBB);
- Updates.push_back({DominatorTree::Delete, SelectBB, Succ});
+ Updates.push_back({DominatorTree::Delete, SelectBB, Succ});
}
SI->eraseFromParent();
- if (DTU)
- DTU->applyUpdates(Updates);
+ if (DTU)
+ DTU->applyUpdates(Updates);
}
/// If the switch is only used to initialize one or more
/// phi nodes in a common successor block with only two different
/// constant values, replace the switch with select.
static bool switchToSelect(SwitchInst *SI, IRBuilder<> &Builder,
- DomTreeUpdater *DTU, const DataLayout &DL,
+ DomTreeUpdater *DTU, const DataLayout &DL,
const TargetTransformInfo &TTI) {
Value *const Cond = SI->getCondition();
PHINode *PHI = nullptr;
@@ -5281,7 +5281,7 @@ static bool switchToSelect(SwitchInst *SI, IRBuilder<> &Builder,
Value *SelectValue =
ConvertTwoCaseSwitch(UniqueResults, DefaultResult, Cond, Builder);
if (SelectValue) {
- RemoveSwitchAfterSelectConversion(SI, PHI, SelectValue, Builder, DTU);
+ RemoveSwitchAfterSelectConversion(SI, PHI, SelectValue, Builder, DTU);
return true;
}
// The switch couldn't be converted into a select.
@@ -5666,12 +5666,12 @@ static void reuseTableCompare(
/// successor block with different constant values, replace the switch with
/// lookup tables.
static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
- DomTreeUpdater *DTU, const DataLayout &DL,
+ DomTreeUpdater *DTU, const DataLayout &DL,
const TargetTransformInfo &TTI) {
assert(SI->getNumCases() > 1 && "Degenerate switch?");
- BasicBlock *BB = SI->getParent();
- Function *Fn = BB->getParent();
+ BasicBlock *BB = SI->getParent();
+ Function *Fn = BB->getParent();
// Only build lookup table when we have a target that supports it or the
// attribute is not set.
if (!TTI.shouldBuildLookupTables() ||
@@ -5765,8 +5765,8 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
if (!ShouldBuildLookupTable(SI, TableSize, TTI, DL, ResultTypes))
return false;
- std::vector<DominatorTree::UpdateType> Updates;
-
+ std::vector<DominatorTree::UpdateType> Updates;
+
// Create the BB that does the lookups.
Module &Mod = *CommonDest->getParent()->getParent();
BasicBlock *LookupBB = BasicBlock::Create(
@@ -5799,7 +5799,7 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
if (!DefaultIsReachable || GeneratingCoveredLookupTable) {
Builder.CreateBr(LookupBB);
- Updates.push_back({DominatorTree::Insert, BB, LookupBB});
+ Updates.push_back({DominatorTree::Insert, BB, LookupBB});
// Note: We call removeProdecessor later since we need to be able to get the
// PHI value for the default case in case we're using a bit mask.
} else {
@@ -5807,7 +5807,7 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
TableIndex, ConstantInt::get(MinCaseVal->getType(), TableSize));
RangeCheckBranch =
Builder.CreateCondBr(Cmp, LookupBB, SI->getDefaultDest());
- Updates.push_back({DominatorTree::Insert, BB, LookupBB});
+ Updates.push_back({DominatorTree::Insert, BB, LookupBB});
}
// Populate the BB that does the lookups.
@@ -5845,18 +5845,18 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
Value *LoBit = Builder.CreateTrunc(
Shifted, Type::getInt1Ty(Mod.getContext()), "switch.lobit");
Builder.CreateCondBr(LoBit, LookupBB, SI->getDefaultDest());
- Updates.push_back({DominatorTree::Insert, MaskBB, LookupBB});
- Updates.push_back({DominatorTree::Insert, MaskBB, SI->getDefaultDest()});
+ Updates.push_back({DominatorTree::Insert, MaskBB, LookupBB});
+ Updates.push_back({DominatorTree::Insert, MaskBB, SI->getDefaultDest()});
Builder.SetInsertPoint(LookupBB);
- AddPredecessorToBlock(SI->getDefaultDest(), MaskBB, BB);
+ AddPredecessorToBlock(SI->getDefaultDest(), MaskBB, BB);
}
if (!DefaultIsReachable || GeneratingCoveredLookupTable) {
// We cached PHINodes in PHIs. To avoid accessing deleted PHINodes later,
// do not delete PHINodes here.
- SI->getDefaultDest()->removePredecessor(BB,
+ SI->getDefaultDest()->removePredecessor(BB,
/*KeepOneInputPHIs=*/true);
- Updates.push_back({DominatorTree::Delete, BB, SI->getDefaultDest()});
+ Updates.push_back({DominatorTree::Delete, BB, SI->getDefaultDest()});
}
bool ReturnedEarly = false;
@@ -5893,29 +5893,29 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
PHI->addIncoming(Result, LookupBB);
}
- if (!ReturnedEarly) {
+ if (!ReturnedEarly) {
Builder.CreateBr(CommonDest);
- Updates.push_back({DominatorTree::Insert, LookupBB, CommonDest});
- }
+ Updates.push_back({DominatorTree::Insert, LookupBB, CommonDest});
+ }
// Remove the switch.
- SmallSetVector<BasicBlock *, 8> RemovedSuccessors;
+ SmallSetVector<BasicBlock *, 8> RemovedSuccessors;
for (unsigned i = 0, e = SI->getNumSuccessors(); i < e; ++i) {
BasicBlock *Succ = SI->getSuccessor(i);
if (Succ == SI->getDefaultDest())
continue;
- Succ->removePredecessor(BB);
- RemovedSuccessors.insert(Succ);
+ Succ->removePredecessor(BB);
+ RemovedSuccessors.insert(Succ);
}
SI->eraseFromParent();
- if (DTU) {
- for (BasicBlock *RemovedSuccessor : RemovedSuccessors)
- Updates.push_back({DominatorTree::Delete, BB, RemovedSuccessor});
- DTU->applyUpdates(Updates);
- }
-
+ if (DTU) {
+ for (BasicBlock *RemovedSuccessor : RemovedSuccessors)
+ Updates.push_back({DominatorTree::Delete, BB, RemovedSuccessor});
+ DTU->applyUpdates(Updates);
+ }
+
++NumLookupTables;
if (NeedMask)
++NumLookupTablesHoles;
@@ -6051,10 +6051,10 @@ bool SimplifyCFGOpt::simplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
return requestResimplify();
// Remove unreachable cases.
- if (eliminateDeadSwitchCases(SI, DTU, Options.AC, DL))
+ if (eliminateDeadSwitchCases(SI, DTU, Options.AC, DL))
return requestResimplify();
- if (switchToSelect(SI, Builder, DTU, DL, TTI))
+ if (switchToSelect(SI, Builder, DTU, DL, TTI))
return requestResimplify();
if (Options.ForwardSwitchCondToPhi && ForwardSwitchConditionToPHI(SI))
@@ -6066,7 +6066,7 @@ bool SimplifyCFGOpt::simplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
// CVP. Therefore, only apply this transformation during late stages of the
// optimisation pipeline.
if (Options.ConvertSwitchToLookupTable &&
- SwitchToLookupTable(SI, Builder, DTU, DL, TTI))
+ SwitchToLookupTable(SI, Builder, DTU, DL, TTI))
return requestResimplify();
if (ReduceSwitchRange(SI, Builder, DL, TTI))
@@ -6081,12 +6081,12 @@ bool SimplifyCFGOpt::simplifyIndirectBr(IndirectBrInst *IBI) {
// Eliminate redundant destinations.
SmallPtrSet<Value *, 8> Succs;
- SmallSetVector<BasicBlock *, 8> RemovedSuccs;
+ SmallSetVector<BasicBlock *, 8> RemovedSuccs;
for (unsigned i = 0, e = IBI->getNumDestinations(); i != e; ++i) {
BasicBlock *Dest = IBI->getDestination(i);
if (!Dest->hasAddressTaken() || !Succs.insert(Dest).second) {
- if (!Dest->hasAddressTaken())
- RemovedSuccs.insert(Dest);
+ if (!Dest->hasAddressTaken())
+ RemovedSuccs.insert(Dest);
Dest->removePredecessor(BB);
IBI->removeDestination(i);
--i;
@@ -6095,14 +6095,14 @@ bool SimplifyCFGOpt::simplifyIndirectBr(IndirectBrInst *IBI) {
}
}
- if (DTU) {
- std::vector<DominatorTree::UpdateType> Updates;
- Updates.reserve(RemovedSuccs.size());
- for (auto *RemovedSucc : RemovedSuccs)
- Updates.push_back({DominatorTree::Delete, BB, RemovedSucc});
- DTU->applyUpdates(Updates);
- }
-
+ if (DTU) {
+ std::vector<DominatorTree::UpdateType> Updates;
+ Updates.reserve(RemovedSuccs.size());
+ for (auto *RemovedSucc : RemovedSuccs)
+ Updates.push_back({DominatorTree::Delete, BB, RemovedSucc});
+ DTU->applyUpdates(Updates);
+ }
+
if (IBI->getNumDestinations() == 0) {
// If the indirectbr has no successors, change it to unreachable.
new UnreachableInst(IBI->getContext(), IBI);
@@ -6146,7 +6146,7 @@ bool SimplifyCFGOpt::simplifyIndirectBr(IndirectBrInst *IBI) {
/// block when the inputs in the phi are the same for the two blocks being
/// merged. In some cases, this could result in removal of the PHI entirely.
static bool TryToMergeLandingPad(LandingPadInst *LPad, BranchInst *BI,
- BasicBlock *BB, DomTreeUpdater *DTU) {
+ BasicBlock *BB, DomTreeUpdater *DTU) {
auto Succ = BB->getUniqueSuccessor();
assert(Succ);
// If there's a phi in the successor block, we'd likely have to introduce
@@ -6167,8 +6167,8 @@ static bool TryToMergeLandingPad(LandingPadInst *LPad, BranchInst *BI,
if (!BI2 || !BI2->isIdenticalTo(BI))
continue;
- std::vector<DominatorTree::UpdateType> Updates;
-
+ std::vector<DominatorTree::UpdateType> Updates;
+
// We've found an identical block. Update our predecessors to take that
// path instead and make ourselves dead.
SmallPtrSet<BasicBlock *, 16> Preds;
@@ -6178,8 +6178,8 @@ static bool TryToMergeLandingPad(LandingPadInst *LPad, BranchInst *BI,
assert(II->getNormalDest() != BB && II->getUnwindDest() == BB &&
"unexpected successor");
II->setUnwindDest(OtherPred);
- Updates.push_back({DominatorTree::Insert, Pred, OtherPred});
- Updates.push_back({DominatorTree::Delete, Pred, BB});
+ Updates.push_back({DominatorTree::Insert, Pred, OtherPred});
+ Updates.push_back({DominatorTree::Delete, Pred, BB});
}
// The debug info in OtherPred doesn't cover the merged control flow that
@@ -6195,14 +6195,14 @@ static bool TryToMergeLandingPad(LandingPadInst *LPad, BranchInst *BI,
Succs.insert(succ_begin(BB), succ_end(BB));
for (BasicBlock *Succ : Succs) {
Succ->removePredecessor(BB);
- Updates.push_back({DominatorTree::Delete, BB, Succ});
+ Updates.push_back({DominatorTree::Delete, BB, Succ});
}
IRBuilder<> Builder(BI);
Builder.CreateUnreachable();
BI->eraseFromParent();
- if (DTU)
- DTU->applyUpdates(Updates);
+ if (DTU)
+ DTU->applyUpdates(Updates);
return true;
}
return false;
@@ -6227,11 +6227,11 @@ bool SimplifyCFGOpt::simplifyUncondBranch(BranchInst *BI,
// backedge, so we can eliminate BB.
bool NeedCanonicalLoop =
Options.NeedCanonicalLoop &&
- (!LoopHeaders.empty() && BB->hasNPredecessorsOrMore(2) &&
- (is_contained(LoopHeaders, BB) || is_contained(LoopHeaders, Succ)));
+ (!LoopHeaders.empty() && BB->hasNPredecessorsOrMore(2) &&
+ (is_contained(LoopHeaders, BB) || is_contained(LoopHeaders, Succ)));
BasicBlock::iterator I = BB->getFirstNonPHIOrDbg()->getIterator();
if (I->isTerminator() && BB != &BB->getParent()->getEntryBlock() &&
- !NeedCanonicalLoop && TryToSimplifyUncondBranchFromEmptyBlock(BB, DTU))
+ !NeedCanonicalLoop && TryToSimplifyUncondBranchFromEmptyBlock(BB, DTU))
return true;
// If the only instruction in the block is a seteq/setne comparison against a
@@ -6250,7 +6250,7 @@ bool SimplifyCFGOpt::simplifyUncondBranch(BranchInst *BI,
if (LandingPadInst *LPad = dyn_cast<LandingPadInst>(I)) {
for (++I; isa<DbgInfoIntrinsic>(I); ++I)
;
- if (I->isTerminator() && TryToMergeLandingPad(LPad, BI, BB, DTU))
+ if (I->isTerminator() && TryToMergeLandingPad(LPad, BI, BB, DTU))
return true;
}
@@ -6258,8 +6258,8 @@ bool SimplifyCFGOpt::simplifyUncondBranch(BranchInst *BI,
// branches to us and our successor, fold the comparison into the
// predecessor and use logical operations to update the incoming value
// for PHI nodes in common successor.
- if (FoldBranchToCommonDest(BI, DTU, /*MSSAU=*/nullptr, &TTI,
- Options.BonusInstThreshold))
+ if (FoldBranchToCommonDest(BI, DTU, /*MSSAU=*/nullptr, &TTI,
+ Options.BonusInstThreshold))
return requestResimplify();
return false;
}
@@ -6322,8 +6322,8 @@ bool SimplifyCFGOpt::simplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
// If this basic block is ONLY a compare and a branch, and if a predecessor
// branches to us and one of our successors, fold the comparison into the
// predecessor and use logical operations to pick the right destination.
- if (FoldBranchToCommonDest(BI, DTU, /*MSSAU=*/nullptr, &TTI,
- Options.BonusInstThreshold))
+ if (FoldBranchToCommonDest(BI, DTU, /*MSSAU=*/nullptr, &TTI,
+ Options.BonusInstThreshold))
return requestResimplify();
// We have a conditional branch to two blocks that are only reachable
@@ -6332,9 +6332,9 @@ bool SimplifyCFGOpt::simplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
// can hoist it up to the branching block.
if (BI->getSuccessor(0)->getSinglePredecessor()) {
if (BI->getSuccessor(1)->getSinglePredecessor()) {
- if (HoistCommon && Options.HoistCommonInsts)
- if (HoistThenElseCodeToIf(BI, TTI))
- return requestResimplify();
+ if (HoistCommon && Options.HoistCommonInsts)
+ if (HoistThenElseCodeToIf(BI, TTI))
+ return requestResimplify();
} else {
// If Successor #1 has multiple preds, we may be able to conditionally
// execute Successor #0 if it branches to Successor #1.
@@ -6358,14 +6358,14 @@ bool SimplifyCFGOpt::simplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
// through this block if any PHI node entries are constants.
if (PHINode *PN = dyn_cast<PHINode>(BI->getCondition()))
if (PN->getParent() == BI->getParent())
- if (FoldCondBranchOnPHI(BI, DTU, DL, Options.AC))
+ if (FoldCondBranchOnPHI(BI, DTU, DL, Options.AC))
return requestResimplify();
// Scan predecessor blocks for conditional branches.
for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
if (BranchInst *PBI = dyn_cast<BranchInst>((*PI)->getTerminator()))
if (PBI != BI && PBI->isConditional())
- if (SimplifyCondBranchToCondBranch(PBI, BI, DTU, DL, TTI))
+ if (SimplifyCondBranchToCondBranch(PBI, BI, DTU, DL, TTI))
return requestResimplify();
// Look for diamond patterns.
@@ -6373,14 +6373,14 @@ bool SimplifyCFGOpt::simplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
if (BasicBlock *PrevBB = allPredecessorsComeFromSameSource(BB))
if (BranchInst *PBI = dyn_cast<BranchInst>(PrevBB->getTerminator()))
if (PBI != BI && PBI->isConditional())
- if (mergeConditionalStores(PBI, BI, DTU, DL, TTI))
+ if (mergeConditionalStores(PBI, BI, DTU, DL, TTI))
return requestResimplify();
return false;
}
/// Check if passing a value to an instruction will cause undefined behavior.
-static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValueMayBeModified) {
+static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValueMayBeModified) {
Constant *C = dyn_cast<Constant>(V);
if (!C)
return false;
@@ -6403,15 +6403,15 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu
// Look through GEPs. A load from a GEP derived from NULL is still undefined
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Use))
- if (GEP->getPointerOperand() == I) {
- if (!GEP->isInBounds() || !GEP->hasAllZeroIndices())
- PtrValueMayBeModified = true;
- return passingValueIsAlwaysUndefined(V, GEP, PtrValueMayBeModified);
- }
+ if (GEP->getPointerOperand() == I) {
+ if (!GEP->isInBounds() || !GEP->hasAllZeroIndices())
+ PtrValueMayBeModified = true;
+ return passingValueIsAlwaysUndefined(V, GEP, PtrValueMayBeModified);
+ }
// Look through bitcasts.
if (BitCastInst *BC = dyn_cast<BitCastInst>(Use))
- return passingValueIsAlwaysUndefined(V, BC, PtrValueMayBeModified);
+ return passingValueIsAlwaysUndefined(V, BC, PtrValueMayBeModified);
// Load from null is undefined.
if (LoadInst *LI = dyn_cast<LoadInst>(Use))
@@ -6426,51 +6426,51 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu
SI->getPointerAddressSpace())) &&
SI->getPointerOperand() == I;
- if (auto *CB = dyn_cast<CallBase>(Use)) {
- if (C->isNullValue() && NullPointerIsDefined(CB->getFunction()))
- return false;
- // A call to null is undefined.
- if (CB->getCalledOperand() == I)
- return true;
-
- if (C->isNullValue()) {
- for (const llvm::Use &Arg : CB->args())
- if (Arg == I) {
- unsigned ArgIdx = CB->getArgOperandNo(&Arg);
- if (CB->paramHasAttr(ArgIdx, Attribute::NonNull) &&
- CB->paramHasAttr(ArgIdx, Attribute::NoUndef)) {
- // Passing null to a nonnnull+noundef argument is undefined.
- return !PtrValueMayBeModified;
- }
- }
- } else if (isa<UndefValue>(C)) {
- // Passing undef to a noundef argument is undefined.
- for (const llvm::Use &Arg : CB->args())
- if (Arg == I) {
- unsigned ArgIdx = CB->getArgOperandNo(&Arg);
- if (CB->paramHasAttr(ArgIdx, Attribute::NoUndef)) {
- // Passing undef to a noundef argument is undefined.
- return true;
- }
- }
- }
- }
+ if (auto *CB = dyn_cast<CallBase>(Use)) {
+ if (C->isNullValue() && NullPointerIsDefined(CB->getFunction()))
+ return false;
+ // A call to null is undefined.
+ if (CB->getCalledOperand() == I)
+ return true;
+
+ if (C->isNullValue()) {
+ for (const llvm::Use &Arg : CB->args())
+ if (Arg == I) {
+ unsigned ArgIdx = CB->getArgOperandNo(&Arg);
+ if (CB->paramHasAttr(ArgIdx, Attribute::NonNull) &&
+ CB->paramHasAttr(ArgIdx, Attribute::NoUndef)) {
+ // Passing null to a nonnnull+noundef argument is undefined.
+ return !PtrValueMayBeModified;
+ }
+ }
+ } else if (isa<UndefValue>(C)) {
+ // Passing undef to a noundef argument is undefined.
+ for (const llvm::Use &Arg : CB->args())
+ if (Arg == I) {
+ unsigned ArgIdx = CB->getArgOperandNo(&Arg);
+ if (CB->paramHasAttr(ArgIdx, Attribute::NoUndef)) {
+ // Passing undef to a noundef argument is undefined.
+ return true;
+ }
+ }
+ }
+ }
}
return false;
}
/// If BB has an incoming value that will always trigger undefined behavior
/// (eg. null pointer dereference), remove the branch leading here.
-static bool removeUndefIntroducingPredecessor(BasicBlock *BB,
- DomTreeUpdater *DTU) {
+static bool removeUndefIntroducingPredecessor(BasicBlock *BB,
+ DomTreeUpdater *DTU) {
for (PHINode &PHI : BB->phis())
for (unsigned i = 0, e = PHI.getNumIncomingValues(); i != e; ++i)
if (passingValueIsAlwaysUndefined(PHI.getIncomingValue(i), &PHI)) {
- BasicBlock *Predecessor = PHI.getIncomingBlock(i);
- Instruction *T = Predecessor->getTerminator();
+ BasicBlock *Predecessor = PHI.getIncomingBlock(i);
+ Instruction *T = Predecessor->getTerminator();
IRBuilder<> Builder(T);
if (BranchInst *BI = dyn_cast<BranchInst>(T)) {
- BB->removePredecessor(Predecessor);
+ BB->removePredecessor(Predecessor);
// Turn uncoditional branches into unreachables and remove the dead
// destination from conditional branches.
if (BI->isUnconditional())
@@ -6479,8 +6479,8 @@ static bool removeUndefIntroducingPredecessor(BasicBlock *BB,
Builder.CreateBr(BI->getSuccessor(0) == BB ? BI->getSuccessor(1)
: BI->getSuccessor(0));
BI->eraseFromParent();
- if (DTU)
- DTU->applyUpdates({{DominatorTree::Delete, Predecessor, BB}});
+ if (DTU)
+ DTU->applyUpdates({{DominatorTree::Delete, Predecessor, BB}});
return true;
}
// TODO: SwitchInst.
@@ -6489,7 +6489,7 @@ static bool removeUndefIntroducingPredecessor(BasicBlock *BB,
return false;
}
-bool SimplifyCFGOpt::simplifyOnceImpl(BasicBlock *BB) {
+bool SimplifyCFGOpt::simplifyOnceImpl(BasicBlock *BB) {
bool Changed = false;
assert(BB && BB->getParent() && "Block not embedded in function!");
@@ -6500,29 +6500,29 @@ bool SimplifyCFGOpt::simplifyOnceImpl(BasicBlock *BB) {
if ((pred_empty(BB) && BB != &BB->getParent()->getEntryBlock()) ||
BB->getSinglePredecessor() == BB) {
LLVM_DEBUG(dbgs() << "Removing BB: \n" << *BB);
- DeleteDeadBlock(BB, DTU);
+ DeleteDeadBlock(BB, DTU);
return true;
}
// Check to see if we can constant propagate this terminator instruction
// away...
- Changed |= ConstantFoldTerminator(BB, /*DeleteDeadConditions=*/true,
- /*TLI=*/nullptr, DTU);
+ Changed |= ConstantFoldTerminator(BB, /*DeleteDeadConditions=*/true,
+ /*TLI=*/nullptr, DTU);
// Check for and eliminate duplicate PHI nodes in this block.
Changed |= EliminateDuplicatePHINodes(BB);
// Check for and remove branches that will always cause undefined behavior.
- Changed |= removeUndefIntroducingPredecessor(BB, DTU);
+ Changed |= removeUndefIntroducingPredecessor(BB, DTU);
// Merge basic blocks into their predecessor if there is only one distinct
// pred, and if there is only one distinct successor of the predecessor, and
// if there are no PHI nodes.
- if (MergeBlockIntoPredecessor(BB, DTU))
+ if (MergeBlockIntoPredecessor(BB, DTU))
return true;
if (SinkCommon && Options.SinkCommonInsts)
- Changed |= SinkCommonCodeFromPredecessors(BB, DTU);
+ Changed |= SinkCommonCodeFromPredecessors(BB, DTU);
IRBuilder<> Builder(BB);
@@ -6531,7 +6531,7 @@ bool SimplifyCFGOpt::simplifyOnceImpl(BasicBlock *BB) {
// eliminate it, do so now.
if (auto *PN = dyn_cast<PHINode>(BB->begin()))
if (PN->getNumIncomingValues() == 2)
- Changed |= FoldTwoEntryPHINode(PN, TTI, DTU, DL);
+ Changed |= FoldTwoEntryPHINode(PN, TTI, DTU, DL);
}
Instruction *Terminator = BB->getTerminator();
@@ -6563,23 +6563,23 @@ bool SimplifyCFGOpt::simplifyOnceImpl(BasicBlock *BB) {
return Changed;
}
-bool SimplifyCFGOpt::simplifyOnce(BasicBlock *BB) {
- bool Changed = simplifyOnceImpl(BB);
-
- assert((!RequireAndPreserveDomTree ||
- (DTU &&
- DTU->getDomTree().verify(DominatorTree::VerificationLevel::Full))) &&
- "Failed to maintain validity of domtree!");
-
- return Changed;
-}
-
+bool SimplifyCFGOpt::simplifyOnce(BasicBlock *BB) {
+ bool Changed = simplifyOnceImpl(BB);
+
+ assert((!RequireAndPreserveDomTree ||
+ (DTU &&
+ DTU->getDomTree().verify(DominatorTree::VerificationLevel::Full))) &&
+ "Failed to maintain validity of domtree!");
+
+ return Changed;
+}
+
bool SimplifyCFGOpt::run(BasicBlock *BB) {
- assert((!RequireAndPreserveDomTree ||
- (DTU &&
- DTU->getDomTree().verify(DominatorTree::VerificationLevel::Full))) &&
- "Original domtree is invalid?");
-
+ assert((!RequireAndPreserveDomTree ||
+ (DTU &&
+ DTU->getDomTree().verify(DominatorTree::VerificationLevel::Full))) &&
+ "Original domtree is invalid?");
+
bool Changed = false;
// Repeated simplify BB as long as resimplification is requested.
@@ -6595,9 +6595,9 @@ bool SimplifyCFGOpt::run(BasicBlock *BB) {
}
bool llvm::simplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
- DomTreeUpdater *DTU, const SimplifyCFGOptions &Options,
- ArrayRef<WeakVH> LoopHeaders) {
- return SimplifyCFGOpt(TTI, RequireAndPreserveDomTree ? DTU : nullptr,
- BB->getModule()->getDataLayout(), LoopHeaders, Options)
+ DomTreeUpdater *DTU, const SimplifyCFGOptions &Options,
+ ArrayRef<WeakVH> LoopHeaders) {
+ return SimplifyCFGOpt(TTI, RequireAndPreserveDomTree ? DTU : nullptr,
+ BB->getModule()->getDataLayout(), LoopHeaders, Options)
.run(BB);
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/SimplifyIndVar.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/SimplifyIndVar.cpp
index 40a1e09818..290c04a7ad 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -194,12 +194,12 @@ bool SimplifyIndvar::makeIVComparisonInvariant(ICmpInst *ICmp,
auto *PN = dyn_cast<PHINode>(IVOperand);
if (!PN)
return false;
- auto LIP = SE->getLoopInvariantPredicate(Pred, S, X, L);
- if (!LIP)
+ auto LIP = SE->getLoopInvariantPredicate(Pred, S, X, L);
+ if (!LIP)
return false;
- ICmpInst::Predicate InvariantPredicate = LIP->Pred;
- const SCEV *InvariantLHS = LIP->LHS;
- const SCEV *InvariantRHS = LIP->RHS;
+ ICmpInst::Predicate InvariantPredicate = LIP->Pred;
+ const SCEV *InvariantLHS = LIP->LHS;
+ const SCEV *InvariantRHS = LIP->RHS;
// Rewrite the comparison to a loop invariant comparison if it can be done
// cheaply, where cheaply means "we don't need to emit any new
@@ -477,7 +477,7 @@ bool SimplifyIndvar::eliminateOverflowIntrinsic(WithOverflowInst *WO) {
if (WO->use_empty())
WO->eraseFromParent();
- Changed = true;
+ Changed = true;
return true;
}
@@ -968,1122 +968,1122 @@ bool simplifyLoopIVs(Loop *L, ScalarEvolution *SE, DominatorTree *DT,
}
} // namespace llvm
-
-//===----------------------------------------------------------------------===//
-// Widen Induction Variables - Extend the width of an IV to cover its
-// widest uses.
-//===----------------------------------------------------------------------===//
-
-class WidenIV {
- // Parameters
- PHINode *OrigPhi;
- Type *WideType;
-
- // Context
- LoopInfo *LI;
- Loop *L;
- ScalarEvolution *SE;
- DominatorTree *DT;
-
- // Does the module have any calls to the llvm.experimental.guard intrinsic
- // at all? If not we can avoid scanning instructions looking for guards.
- bool HasGuards;
-
- bool UsePostIncrementRanges;
-
- // Statistics
- unsigned NumElimExt = 0;
- unsigned NumWidened = 0;
-
- // Result
- PHINode *WidePhi = nullptr;
- Instruction *WideInc = nullptr;
- const SCEV *WideIncExpr = nullptr;
- SmallVectorImpl<WeakTrackingVH> &DeadInsts;
-
- SmallPtrSet<Instruction *,16> Widened;
-
- enum ExtendKind { ZeroExtended, SignExtended, Unknown };
-
- // A map tracking the kind of extension used to widen each narrow IV
- // and narrow IV user.
- // Key: pointer to a narrow IV or IV user.
- // Value: the kind of extension used to widen this Instruction.
- DenseMap<AssertingVH<Instruction>, ExtendKind> ExtendKindMap;
-
- using DefUserPair = std::pair<AssertingVH<Value>, AssertingVH<Instruction>>;
-
- // A map with control-dependent ranges for post increment IV uses. The key is
- // a pair of IV def and a use of this def denoting the context. The value is
- // a ConstantRange representing possible values of the def at the given
- // context.
- DenseMap<DefUserPair, ConstantRange> PostIncRangeInfos;
-
- Optional<ConstantRange> getPostIncRangeInfo(Value *Def,
- Instruction *UseI) {
- DefUserPair Key(Def, UseI);
- auto It = PostIncRangeInfos.find(Key);
- return It == PostIncRangeInfos.end()
- ? Optional<ConstantRange>(None)
- : Optional<ConstantRange>(It->second);
- }
-
- void calculatePostIncRanges(PHINode *OrigPhi);
- void calculatePostIncRange(Instruction *NarrowDef, Instruction *NarrowUser);
-
- void updatePostIncRangeInfo(Value *Def, Instruction *UseI, ConstantRange R) {
- DefUserPair Key(Def, UseI);
- auto It = PostIncRangeInfos.find(Key);
- if (It == PostIncRangeInfos.end())
- PostIncRangeInfos.insert({Key, R});
- else
- It->second = R.intersectWith(It->second);
- }
-
-public:
- /// Record a link in the Narrow IV def-use chain along with the WideIV that
- /// computes the same value as the Narrow IV def. This avoids caching Use*
- /// pointers.
- struct NarrowIVDefUse {
- Instruction *NarrowDef = nullptr;
- Instruction *NarrowUse = nullptr;
- Instruction *WideDef = nullptr;
-
- // True if the narrow def is never negative. Tracking this information lets
- // us use a sign extension instead of a zero extension or vice versa, when
- // profitable and legal.
- bool NeverNegative = false;
-
- NarrowIVDefUse(Instruction *ND, Instruction *NU, Instruction *WD,
- bool NeverNegative)
- : NarrowDef(ND), NarrowUse(NU), WideDef(WD),
- NeverNegative(NeverNegative) {}
- };
-
- WidenIV(const WideIVInfo &WI, LoopInfo *LInfo, ScalarEvolution *SEv,
- DominatorTree *DTree, SmallVectorImpl<WeakTrackingVH> &DI,
- bool HasGuards, bool UsePostIncrementRanges = true);
-
- PHINode *createWideIV(SCEVExpander &Rewriter);
-
- unsigned getNumElimExt() { return NumElimExt; };
- unsigned getNumWidened() { return NumWidened; };
-
-protected:
- Value *createExtendInst(Value *NarrowOper, Type *WideType, bool IsSigned,
- Instruction *Use);
-
- Instruction *cloneIVUser(NarrowIVDefUse DU, const SCEVAddRecExpr *WideAR);
- Instruction *cloneArithmeticIVUser(NarrowIVDefUse DU,
- const SCEVAddRecExpr *WideAR);
- Instruction *cloneBitwiseIVUser(NarrowIVDefUse DU);
-
- ExtendKind getExtendKind(Instruction *I);
-
- using WidenedRecTy = std::pair<const SCEVAddRecExpr *, ExtendKind>;
-
- WidenedRecTy getWideRecurrence(NarrowIVDefUse DU);
-
- WidenedRecTy getExtendedOperandRecurrence(NarrowIVDefUse DU);
-
- const SCEV *getSCEVByOpCode(const SCEV *LHS, const SCEV *RHS,
- unsigned OpCode) const;
-
- Instruction *widenIVUse(NarrowIVDefUse DU, SCEVExpander &Rewriter);
-
- bool widenLoopCompare(NarrowIVDefUse DU);
- bool widenWithVariantUse(NarrowIVDefUse DU);
-
- void pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef);
-
-private:
- SmallVector<NarrowIVDefUse, 8> NarrowIVUsers;
-};
-
-
-/// Determine the insertion point for this user. By default, insert immediately
-/// before the user. SCEVExpander or LICM will hoist loop invariants out of the
-/// loop. For PHI nodes, there may be multiple uses, so compute the nearest
-/// common dominator for the incoming blocks. A nullptr can be returned if no
-/// viable location is found: it may happen if User is a PHI and Def only comes
-/// to this PHI from unreachable blocks.
-static Instruction *getInsertPointForUses(Instruction *User, Value *Def,
- DominatorTree *DT, LoopInfo *LI) {
- PHINode *PHI = dyn_cast<PHINode>(User);
- if (!PHI)
- return User;
-
- Instruction *InsertPt = nullptr;
- for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i) {
- if (PHI->getIncomingValue(i) != Def)
- continue;
-
- BasicBlock *InsertBB = PHI->getIncomingBlock(i);
-
- if (!DT->isReachableFromEntry(InsertBB))
- continue;
-
- if (!InsertPt) {
- InsertPt = InsertBB->getTerminator();
- continue;
- }
- InsertBB = DT->findNearestCommonDominator(InsertPt->getParent(), InsertBB);
- InsertPt = InsertBB->getTerminator();
- }
-
- // If we have skipped all inputs, it means that Def only comes to Phi from
- // unreachable blocks.
- if (!InsertPt)
- return nullptr;
-
- auto *DefI = dyn_cast<Instruction>(Def);
- if (!DefI)
- return InsertPt;
-
- assert(DT->dominates(DefI, InsertPt) && "def does not dominate all uses");
-
- auto *L = LI->getLoopFor(DefI->getParent());
- assert(!L || L->contains(LI->getLoopFor(InsertPt->getParent())));
-
- for (auto *DTN = (*DT)[InsertPt->getParent()]; DTN; DTN = DTN->getIDom())
- if (LI->getLoopFor(DTN->getBlock()) == L)
- return DTN->getBlock()->getTerminator();
-
- llvm_unreachable("DefI dominates InsertPt!");
-}
-
-WidenIV::WidenIV(const WideIVInfo &WI, LoopInfo *LInfo, ScalarEvolution *SEv,
- DominatorTree *DTree, SmallVectorImpl<WeakTrackingVH> &DI,
- bool HasGuards, bool UsePostIncrementRanges)
- : OrigPhi(WI.NarrowIV), WideType(WI.WidestNativeType), LI(LInfo),
- L(LI->getLoopFor(OrigPhi->getParent())), SE(SEv), DT(DTree),
- HasGuards(HasGuards), UsePostIncrementRanges(UsePostIncrementRanges),
- DeadInsts(DI) {
- assert(L->getHeader() == OrigPhi->getParent() && "Phi must be an IV");
- ExtendKindMap[OrigPhi] = WI.IsSigned ? SignExtended : ZeroExtended;
-}
-
-Value *WidenIV::createExtendInst(Value *NarrowOper, Type *WideType,
- bool IsSigned, Instruction *Use) {
- // Set the debug location and conservative insertion point.
- IRBuilder<> Builder(Use);
- // Hoist the insertion point into loop preheaders as far as possible.
- for (const Loop *L = LI->getLoopFor(Use->getParent());
- L && L->getLoopPreheader() && L->isLoopInvariant(NarrowOper);
- L = L->getParentLoop())
- Builder.SetInsertPoint(L->getLoopPreheader()->getTerminator());
-
- return IsSigned ? Builder.CreateSExt(NarrowOper, WideType) :
- Builder.CreateZExt(NarrowOper, WideType);
-}
-
-/// Instantiate a wide operation to replace a narrow operation. This only needs
-/// to handle operations that can evaluation to SCEVAddRec. It can safely return
-/// 0 for any operation we decide not to clone.
-Instruction *WidenIV::cloneIVUser(WidenIV::NarrowIVDefUse DU,
- const SCEVAddRecExpr *WideAR) {
- unsigned Opcode = DU.NarrowUse->getOpcode();
- switch (Opcode) {
- default:
- return nullptr;
- case Instruction::Add:
- case Instruction::Mul:
- case Instruction::UDiv:
- case Instruction::Sub:
- return cloneArithmeticIVUser(DU, WideAR);
-
- case Instruction::And:
- case Instruction::Or:
- case Instruction::Xor:
- case Instruction::Shl:
- case Instruction::LShr:
- case Instruction::AShr:
- return cloneBitwiseIVUser(DU);
- }
-}
-
-Instruction *WidenIV::cloneBitwiseIVUser(WidenIV::NarrowIVDefUse DU) {
- Instruction *NarrowUse = DU.NarrowUse;
- Instruction *NarrowDef = DU.NarrowDef;
- Instruction *WideDef = DU.WideDef;
-
- LLVM_DEBUG(dbgs() << "Cloning bitwise IVUser: " << *NarrowUse << "\n");
-
- // Replace NarrowDef operands with WideDef. Otherwise, we don't know anything
- // about the narrow operand yet so must insert a [sz]ext. It is probably loop
- // invariant and will be folded or hoisted. If it actually comes from a
- // widened IV, it should be removed during a future call to widenIVUse.
- bool IsSigned = getExtendKind(NarrowDef) == SignExtended;
- Value *LHS = (NarrowUse->getOperand(0) == NarrowDef)
- ? WideDef
- : createExtendInst(NarrowUse->getOperand(0), WideType,
- IsSigned, NarrowUse);
- Value *RHS = (NarrowUse->getOperand(1) == NarrowDef)
- ? WideDef
- : createExtendInst(NarrowUse->getOperand(1), WideType,
- IsSigned, NarrowUse);
-
- auto *NarrowBO = cast<BinaryOperator>(NarrowUse);
- auto *WideBO = BinaryOperator::Create(NarrowBO->getOpcode(), LHS, RHS,
- NarrowBO->getName());
- IRBuilder<> Builder(NarrowUse);
- Builder.Insert(WideBO);
- WideBO->copyIRFlags(NarrowBO);
- return WideBO;
-}
-
-Instruction *WidenIV::cloneArithmeticIVUser(WidenIV::NarrowIVDefUse DU,
- const SCEVAddRecExpr *WideAR) {
- Instruction *NarrowUse = DU.NarrowUse;
- Instruction *NarrowDef = DU.NarrowDef;
- Instruction *WideDef = DU.WideDef;
-
- LLVM_DEBUG(dbgs() << "Cloning arithmetic IVUser: " << *NarrowUse << "\n");
-
- unsigned IVOpIdx = (NarrowUse->getOperand(0) == NarrowDef) ? 0 : 1;
-
- // We're trying to find X such that
- //
- // Widen(NarrowDef `op` NonIVNarrowDef) == WideAR == WideDef `op.wide` X
- //
- // We guess two solutions to X, sext(NonIVNarrowDef) and zext(NonIVNarrowDef),
- // and check using SCEV if any of them are correct.
-
- // Returns true if extending NonIVNarrowDef according to `SignExt` is a
- // correct solution to X.
- auto GuessNonIVOperand = [&](bool SignExt) {
- const SCEV *WideLHS;
- const SCEV *WideRHS;
-
- auto GetExtend = [this, SignExt](const SCEV *S, Type *Ty) {
- if (SignExt)
- return SE->getSignExtendExpr(S, Ty);
- return SE->getZeroExtendExpr(S, Ty);
- };
-
- if (IVOpIdx == 0) {
- WideLHS = SE->getSCEV(WideDef);
- const SCEV *NarrowRHS = SE->getSCEV(NarrowUse->getOperand(1));
- WideRHS = GetExtend(NarrowRHS, WideType);
- } else {
- const SCEV *NarrowLHS = SE->getSCEV(NarrowUse->getOperand(0));
- WideLHS = GetExtend(NarrowLHS, WideType);
- WideRHS = SE->getSCEV(WideDef);
- }
-
- // WideUse is "WideDef `op.wide` X" as described in the comment.
- const SCEV *WideUse =
- getSCEVByOpCode(WideLHS, WideRHS, NarrowUse->getOpcode());
-
- return WideUse == WideAR;
- };
-
- bool SignExtend = getExtendKind(NarrowDef) == SignExtended;
- if (!GuessNonIVOperand(SignExtend)) {
- SignExtend = !SignExtend;
- if (!GuessNonIVOperand(SignExtend))
- return nullptr;
- }
-
- Value *LHS = (NarrowUse->getOperand(0) == NarrowDef)
- ? WideDef
- : createExtendInst(NarrowUse->getOperand(0), WideType,
- SignExtend, NarrowUse);
- Value *RHS = (NarrowUse->getOperand(1) == NarrowDef)
- ? WideDef
- : createExtendInst(NarrowUse->getOperand(1), WideType,
- SignExtend, NarrowUse);
-
- auto *NarrowBO = cast<BinaryOperator>(NarrowUse);
- auto *WideBO = BinaryOperator::Create(NarrowBO->getOpcode(), LHS, RHS,
- NarrowBO->getName());
-
- IRBuilder<> Builder(NarrowUse);
- Builder.Insert(WideBO);
- WideBO->copyIRFlags(NarrowBO);
- return WideBO;
-}
-
-WidenIV::ExtendKind WidenIV::getExtendKind(Instruction *I) {
- auto It = ExtendKindMap.find(I);
- assert(It != ExtendKindMap.end() && "Instruction not yet extended!");
- return It->second;
-}
-
-const SCEV *WidenIV::getSCEVByOpCode(const SCEV *LHS, const SCEV *RHS,
- unsigned OpCode) const {
- switch (OpCode) {
- case Instruction::Add:
- return SE->getAddExpr(LHS, RHS);
- case Instruction::Sub:
- return SE->getMinusSCEV(LHS, RHS);
- case Instruction::Mul:
- return SE->getMulExpr(LHS, RHS);
- case Instruction::UDiv:
- return SE->getUDivExpr(LHS, RHS);
- default:
- llvm_unreachable("Unsupported opcode.");
- };
-}
-
-/// No-wrap operations can transfer sign extension of their result to their
-/// operands. Generate the SCEV value for the widened operation without
-/// actually modifying the IR yet. If the expression after extending the
-/// operands is an AddRec for this loop, return the AddRec and the kind of
-/// extension used.
-WidenIV::WidenedRecTy
-WidenIV::getExtendedOperandRecurrence(WidenIV::NarrowIVDefUse DU) {
- // Handle the common case of add<nsw/nuw>
- const unsigned OpCode = DU.NarrowUse->getOpcode();
- // Only Add/Sub/Mul instructions supported yet.
- if (OpCode != Instruction::Add && OpCode != Instruction::Sub &&
- OpCode != Instruction::Mul)
- return {nullptr, Unknown};
-
- // One operand (NarrowDef) has already been extended to WideDef. Now determine
- // if extending the other will lead to a recurrence.
- const unsigned ExtendOperIdx =
- DU.NarrowUse->getOperand(0) == DU.NarrowDef ? 1 : 0;
- assert(DU.NarrowUse->getOperand(1-ExtendOperIdx) == DU.NarrowDef && "bad DU");
-
- const SCEV *ExtendOperExpr = nullptr;
- const OverflowingBinaryOperator *OBO =
- cast<OverflowingBinaryOperator>(DU.NarrowUse);
- ExtendKind ExtKind = getExtendKind(DU.NarrowDef);
- if (ExtKind == SignExtended && OBO->hasNoSignedWrap())
- ExtendOperExpr = SE->getSignExtendExpr(
- SE->getSCEV(DU.NarrowUse->getOperand(ExtendOperIdx)), WideType);
- else if(ExtKind == ZeroExtended && OBO->hasNoUnsignedWrap())
- ExtendOperExpr = SE->getZeroExtendExpr(
- SE->getSCEV(DU.NarrowUse->getOperand(ExtendOperIdx)), WideType);
- else
- return {nullptr, Unknown};
-
- // When creating this SCEV expr, don't apply the current operations NSW or NUW
- // flags. This instruction may be guarded by control flow that the no-wrap
- // behavior depends on. Non-control-equivalent instructions can be mapped to
- // the same SCEV expression, and it would be incorrect to transfer NSW/NUW
- // semantics to those operations.
- const SCEV *lhs = SE->getSCEV(DU.WideDef);
- const SCEV *rhs = ExtendOperExpr;
-
- // Let's swap operands to the initial order for the case of non-commutative
- // operations, like SUB. See PR21014.
- if (ExtendOperIdx == 0)
- std::swap(lhs, rhs);
- const SCEVAddRecExpr *AddRec =
- dyn_cast<SCEVAddRecExpr>(getSCEVByOpCode(lhs, rhs, OpCode));
-
- if (!AddRec || AddRec->getLoop() != L)
- return {nullptr, Unknown};
-
- return {AddRec, ExtKind};
-}
-
-/// Is this instruction potentially interesting for further simplification after
-/// widening it's type? In other words, can the extend be safely hoisted out of
-/// the loop with SCEV reducing the value to a recurrence on the same loop. If
-/// so, return the extended recurrence and the kind of extension used. Otherwise
-/// return {nullptr, Unknown}.
-WidenIV::WidenedRecTy WidenIV::getWideRecurrence(WidenIV::NarrowIVDefUse DU) {
- if (!SE->isSCEVable(DU.NarrowUse->getType()))
- return {nullptr, Unknown};
-
- const SCEV *NarrowExpr = SE->getSCEV(DU.NarrowUse);
- if (SE->getTypeSizeInBits(NarrowExpr->getType()) >=
- SE->getTypeSizeInBits(WideType)) {
- // NarrowUse implicitly widens its operand. e.g. a gep with a narrow
- // index. So don't follow this use.
- return {nullptr, Unknown};
- }
-
- const SCEV *WideExpr;
- ExtendKind ExtKind;
- if (DU.NeverNegative) {
- WideExpr = SE->getSignExtendExpr(NarrowExpr, WideType);
- if (isa<SCEVAddRecExpr>(WideExpr))
- ExtKind = SignExtended;
- else {
- WideExpr = SE->getZeroExtendExpr(NarrowExpr, WideType);
- ExtKind = ZeroExtended;
- }
- } else if (getExtendKind(DU.NarrowDef) == SignExtended) {
- WideExpr = SE->getSignExtendExpr(NarrowExpr, WideType);
- ExtKind = SignExtended;
- } else {
- WideExpr = SE->getZeroExtendExpr(NarrowExpr, WideType);
- ExtKind = ZeroExtended;
- }
- const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(WideExpr);
- if (!AddRec || AddRec->getLoop() != L)
- return {nullptr, Unknown};
- return {AddRec, ExtKind};
-}
-
-/// This IV user cannot be widened. Replace this use of the original narrow IV
-/// with a truncation of the new wide IV to isolate and eliminate the narrow IV.
-static void truncateIVUse(WidenIV::NarrowIVDefUse DU, DominatorTree *DT,
- LoopInfo *LI) {
- auto *InsertPt = getInsertPointForUses(DU.NarrowUse, DU.NarrowDef, DT, LI);
- if (!InsertPt)
- return;
- LLVM_DEBUG(dbgs() << "INDVARS: Truncate IV " << *DU.WideDef << " for user "
- << *DU.NarrowUse << "\n");
- IRBuilder<> Builder(InsertPt);
- Value *Trunc = Builder.CreateTrunc(DU.WideDef, DU.NarrowDef->getType());
- DU.NarrowUse->replaceUsesOfWith(DU.NarrowDef, Trunc);
-}
-
-/// If the narrow use is a compare instruction, then widen the compare
-// (and possibly the other operand). The extend operation is hoisted into the
-// loop preheader as far as possible.
-bool WidenIV::widenLoopCompare(WidenIV::NarrowIVDefUse DU) {
- ICmpInst *Cmp = dyn_cast<ICmpInst>(DU.NarrowUse);
- if (!Cmp)
- return false;
-
- // We can legally widen the comparison in the following two cases:
- //
- // - The signedness of the IV extension and comparison match
- //
- // - The narrow IV is always positive (and thus its sign extension is equal
- // to its zero extension). For instance, let's say we're zero extending
- // %narrow for the following use
- //
- // icmp slt i32 %narrow, %val ... (A)
- //
- // and %narrow is always positive. Then
- //
- // (A) == icmp slt i32 sext(%narrow), sext(%val)
- // == icmp slt i32 zext(%narrow), sext(%val)
- bool IsSigned = getExtendKind(DU.NarrowDef) == SignExtended;
- if (!(DU.NeverNegative || IsSigned == Cmp->isSigned()))
- return false;
-
- Value *Op = Cmp->getOperand(Cmp->getOperand(0) == DU.NarrowDef ? 1 : 0);
- unsigned CastWidth = SE->getTypeSizeInBits(Op->getType());
- unsigned IVWidth = SE->getTypeSizeInBits(WideType);
- assert(CastWidth <= IVWidth && "Unexpected width while widening compare.");
-
- // Widen the compare instruction.
- auto *InsertPt = getInsertPointForUses(DU.NarrowUse, DU.NarrowDef, DT, LI);
- if (!InsertPt)
- return false;
- IRBuilder<> Builder(InsertPt);
- DU.NarrowUse->replaceUsesOfWith(DU.NarrowDef, DU.WideDef);
-
- // Widen the other operand of the compare, if necessary.
- if (CastWidth < IVWidth) {
- Value *ExtOp = createExtendInst(Op, WideType, Cmp->isSigned(), Cmp);
- DU.NarrowUse->replaceUsesOfWith(Op, ExtOp);
- }
- return true;
-}
-
-// The widenIVUse avoids generating trunc by evaluating the use as AddRec, this
-// will not work when:
-// 1) SCEV traces back to an instruction inside the loop that SCEV can not
-// expand, eg. add %indvar, (load %addr)
-// 2) SCEV finds a loop variant, eg. add %indvar, %loopvariant
-// While SCEV fails to avoid trunc, we can still try to use instruction
-// combining approach to prove trunc is not required. This can be further
-// extended with other instruction combining checks, but for now we handle the
-// following case (sub can be "add" and "mul", "nsw + sext" can be "nus + zext")
-//
-// Src:
-// %c = sub nsw %b, %indvar
-// %d = sext %c to i64
-// Dst:
-// %indvar.ext1 = sext %indvar to i64
-// %m = sext %b to i64
-// %d = sub nsw i64 %m, %indvar.ext1
-// Therefore, as long as the result of add/sub/mul is extended to wide type, no
-// trunc is required regardless of how %b is generated. This pattern is common
-// when calculating address in 64 bit architecture
-bool WidenIV::widenWithVariantUse(WidenIV::NarrowIVDefUse DU) {
- Instruction *NarrowUse = DU.NarrowUse;
- Instruction *NarrowDef = DU.NarrowDef;
- Instruction *WideDef = DU.WideDef;
-
- // Handle the common case of add<nsw/nuw>
- const unsigned OpCode = NarrowUse->getOpcode();
- // Only Add/Sub/Mul instructions are supported.
- if (OpCode != Instruction::Add && OpCode != Instruction::Sub &&
- OpCode != Instruction::Mul)
- return false;
-
- // The operand that is not defined by NarrowDef of DU. Let's call it the
- // other operand.
- assert((NarrowUse->getOperand(0) == NarrowDef ||
- NarrowUse->getOperand(1) == NarrowDef) &&
- "bad DU");
-
- const OverflowingBinaryOperator *OBO =
- cast<OverflowingBinaryOperator>(NarrowUse);
- ExtendKind ExtKind = getExtendKind(NarrowDef);
- bool CanSignExtend = ExtKind == SignExtended && OBO->hasNoSignedWrap();
- bool CanZeroExtend = ExtKind == ZeroExtended && OBO->hasNoUnsignedWrap();
- auto AnotherOpExtKind = ExtKind;
-
- // Check that all uses are either:
- // - narrow def (in case of we are widening the IV increment);
- // - single-input LCSSA Phis;
- // - comparison of the chosen type;
- // - extend of the chosen type (raison d'etre).
- SmallVector<Instruction *, 4> ExtUsers;
- SmallVector<PHINode *, 4> LCSSAPhiUsers;
- SmallVector<ICmpInst *, 4> ICmpUsers;
- for (Use &U : NarrowUse->uses()) {
- Instruction *User = cast<Instruction>(U.getUser());
- if (User == NarrowDef)
- continue;
- if (!L->contains(User)) {
- auto *LCSSAPhi = cast<PHINode>(User);
- // Make sure there is only 1 input, so that we don't have to split
- // critical edges.
- if (LCSSAPhi->getNumOperands() != 1)
- return false;
- LCSSAPhiUsers.push_back(LCSSAPhi);
- continue;
- }
- if (auto *ICmp = dyn_cast<ICmpInst>(User)) {
- auto Pred = ICmp->getPredicate();
- // We have 3 types of predicates: signed, unsigned and equality
- // predicates. For equality, it's legal to widen icmp for either sign and
- // zero extend. For sign extend, we can also do so for signed predicates,
- // likeweise for zero extend we can widen icmp for unsigned predicates.
- if (ExtKind == ZeroExtended && ICmpInst::isSigned(Pred))
- return false;
- if (ExtKind == SignExtended && ICmpInst::isUnsigned(Pred))
- return false;
- ICmpUsers.push_back(ICmp);
- continue;
- }
- if (ExtKind == SignExtended)
- User = dyn_cast<SExtInst>(User);
- else
- User = dyn_cast<ZExtInst>(User);
- if (!User || User->getType() != WideType)
- return false;
- ExtUsers.push_back(User);
- }
- if (ExtUsers.empty()) {
- DeadInsts.emplace_back(NarrowUse);
- return true;
- }
-
- // We'll prove some facts that should be true in the context of ext users. If
- // there is no users, we are done now. If there are some, pick their common
- // dominator as context.
- Instruction *Context = nullptr;
- for (auto *Ext : ExtUsers) {
- if (!Context || DT->dominates(Ext, Context))
- Context = Ext;
- else if (!DT->dominates(Context, Ext))
- // For users that don't have dominance relation, use common dominator.
- Context =
- DT->findNearestCommonDominator(Context->getParent(), Ext->getParent())
- ->getTerminator();
- }
- assert(Context && "Context not found?");
-
- if (!CanSignExtend && !CanZeroExtend) {
- // Because InstCombine turns 'sub nuw' to 'add' losing the no-wrap flag, we
- // will most likely not see it. Let's try to prove it.
- if (OpCode != Instruction::Add)
- return false;
- if (ExtKind != ZeroExtended)
- return false;
- const SCEV *LHS = SE->getSCEV(OBO->getOperand(0));
- const SCEV *RHS = SE->getSCEV(OBO->getOperand(1));
- // TODO: Support case for NarrowDef = NarrowUse->getOperand(1).
- if (NarrowUse->getOperand(0) != NarrowDef)
- return false;
- if (!SE->isKnownNegative(RHS))
- return false;
- bool ProvedSubNUW = SE->isKnownPredicateAt(
- ICmpInst::ICMP_UGE, LHS, SE->getNegativeSCEV(RHS), Context);
- if (!ProvedSubNUW)
- return false;
- // In fact, our 'add' is 'sub nuw'. We will need to widen the 2nd operand as
- // neg(zext(neg(op))), which is basically sext(op).
- AnotherOpExtKind = SignExtended;
- }
-
- // Verifying that Defining operand is an AddRec
- const SCEV *Op1 = SE->getSCEV(WideDef);
- const SCEVAddRecExpr *AddRecOp1 = dyn_cast<SCEVAddRecExpr>(Op1);
- if (!AddRecOp1 || AddRecOp1->getLoop() != L)
- return false;
-
- LLVM_DEBUG(dbgs() << "Cloning arithmetic IVUser: " << *NarrowUse << "\n");
-
- // Generating a widening use instruction.
- Value *LHS = (NarrowUse->getOperand(0) == NarrowDef)
- ? WideDef
- : createExtendInst(NarrowUse->getOperand(0), WideType,
- AnotherOpExtKind, NarrowUse);
- Value *RHS = (NarrowUse->getOperand(1) == NarrowDef)
- ? WideDef
- : createExtendInst(NarrowUse->getOperand(1), WideType,
- AnotherOpExtKind, NarrowUse);
-
- auto *NarrowBO = cast<BinaryOperator>(NarrowUse);
- auto *WideBO = BinaryOperator::Create(NarrowBO->getOpcode(), LHS, RHS,
- NarrowBO->getName());
- IRBuilder<> Builder(NarrowUse);
- Builder.Insert(WideBO);
- WideBO->copyIRFlags(NarrowBO);
- ExtendKindMap[NarrowUse] = ExtKind;
-
- for (Instruction *User : ExtUsers) {
- assert(User->getType() == WideType && "Checked before!");
- LLVM_DEBUG(dbgs() << "INDVARS: eliminating " << *User << " replaced by "
- << *WideBO << "\n");
- ++NumElimExt;
- User->replaceAllUsesWith(WideBO);
- DeadInsts.emplace_back(User);
- }
-
- for (PHINode *User : LCSSAPhiUsers) {
- assert(User->getNumOperands() == 1 && "Checked before!");
- Builder.SetInsertPoint(User);
- auto *WidePN =
- Builder.CreatePHI(WideBO->getType(), 1, User->getName() + ".wide");
- BasicBlock *LoopExitingBlock = User->getParent()->getSinglePredecessor();
- assert(LoopExitingBlock && L->contains(LoopExitingBlock) &&
- "Not a LCSSA Phi?");
- WidePN->addIncoming(WideBO, LoopExitingBlock);
- Builder.SetInsertPoint(&*User->getParent()->getFirstInsertionPt());
- auto *TruncPN = Builder.CreateTrunc(WidePN, User->getType());
- User->replaceAllUsesWith(TruncPN);
- DeadInsts.emplace_back(User);
- }
-
- for (ICmpInst *User : ICmpUsers) {
- Builder.SetInsertPoint(User);
- auto ExtendedOp = [&](Value * V)->Value * {
- if (V == NarrowUse)
- return WideBO;
- if (ExtKind == ZeroExtended)
- return Builder.CreateZExt(V, WideBO->getType());
- else
- return Builder.CreateSExt(V, WideBO->getType());
- };
- auto Pred = User->getPredicate();
- auto *LHS = ExtendedOp(User->getOperand(0));
- auto *RHS = ExtendedOp(User->getOperand(1));
- auto *WideCmp =
- Builder.CreateICmp(Pred, LHS, RHS, User->getName() + ".wide");
- User->replaceAllUsesWith(WideCmp);
- DeadInsts.emplace_back(User);
- }
-
- return true;
-}
-
-/// Determine whether an individual user of the narrow IV can be widened. If so,
-/// return the wide clone of the user.
-Instruction *WidenIV::widenIVUse(WidenIV::NarrowIVDefUse DU, SCEVExpander &Rewriter) {
- assert(ExtendKindMap.count(DU.NarrowDef) &&
- "Should already know the kind of extension used to widen NarrowDef");
-
- // Stop traversing the def-use chain at inner-loop phis or post-loop phis.
- if (PHINode *UsePhi = dyn_cast<PHINode>(DU.NarrowUse)) {
- if (LI->getLoopFor(UsePhi->getParent()) != L) {
- // For LCSSA phis, sink the truncate outside the loop.
- // After SimplifyCFG most loop exit targets have a single predecessor.
- // Otherwise fall back to a truncate within the loop.
- if (UsePhi->getNumOperands() != 1)
- truncateIVUse(DU, DT, LI);
- else {
- // Widening the PHI requires us to insert a trunc. The logical place
- // for this trunc is in the same BB as the PHI. This is not possible if
- // the BB is terminated by a catchswitch.
- if (isa<CatchSwitchInst>(UsePhi->getParent()->getTerminator()))
- return nullptr;
-
- PHINode *WidePhi =
- PHINode::Create(DU.WideDef->getType(), 1, UsePhi->getName() + ".wide",
- UsePhi);
- WidePhi->addIncoming(DU.WideDef, UsePhi->getIncomingBlock(0));
- IRBuilder<> Builder(&*WidePhi->getParent()->getFirstInsertionPt());
- Value *Trunc = Builder.CreateTrunc(WidePhi, DU.NarrowDef->getType());
- UsePhi->replaceAllUsesWith(Trunc);
- DeadInsts.emplace_back(UsePhi);
- LLVM_DEBUG(dbgs() << "INDVARS: Widen lcssa phi " << *UsePhi << " to "
- << *WidePhi << "\n");
- }
- return nullptr;
- }
- }
-
- // This narrow use can be widened by a sext if it's non-negative or its narrow
- // def was widended by a sext. Same for zext.
- auto canWidenBySExt = [&]() {
- return DU.NeverNegative || getExtendKind(DU.NarrowDef) == SignExtended;
- };
- auto canWidenByZExt = [&]() {
- return DU.NeverNegative || getExtendKind(DU.NarrowDef) == ZeroExtended;
- };
-
- // Our raison d'etre! Eliminate sign and zero extension.
- if ((isa<SExtInst>(DU.NarrowUse) && canWidenBySExt()) ||
- (isa<ZExtInst>(DU.NarrowUse) && canWidenByZExt())) {
- Value *NewDef = DU.WideDef;
- if (DU.NarrowUse->getType() != WideType) {
- unsigned CastWidth = SE->getTypeSizeInBits(DU.NarrowUse->getType());
- unsigned IVWidth = SE->getTypeSizeInBits(WideType);
- if (CastWidth < IVWidth) {
- // The cast isn't as wide as the IV, so insert a Trunc.
- IRBuilder<> Builder(DU.NarrowUse);
- NewDef = Builder.CreateTrunc(DU.WideDef, DU.NarrowUse->getType());
- }
- else {
- // A wider extend was hidden behind a narrower one. This may induce
- // another round of IV widening in which the intermediate IV becomes
- // dead. It should be very rare.
- LLVM_DEBUG(dbgs() << "INDVARS: New IV " << *WidePhi
- << " not wide enough to subsume " << *DU.NarrowUse
- << "\n");
- DU.NarrowUse->replaceUsesOfWith(DU.NarrowDef, DU.WideDef);
- NewDef = DU.NarrowUse;
- }
- }
- if (NewDef != DU.NarrowUse) {
- LLVM_DEBUG(dbgs() << "INDVARS: eliminating " << *DU.NarrowUse
- << " replaced by " << *DU.WideDef << "\n");
- ++NumElimExt;
- DU.NarrowUse->replaceAllUsesWith(NewDef);
- DeadInsts.emplace_back(DU.NarrowUse);
- }
- // Now that the extend is gone, we want to expose it's uses for potential
- // further simplification. We don't need to directly inform SimplifyIVUsers
- // of the new users, because their parent IV will be processed later as a
- // new loop phi. If we preserved IVUsers analysis, we would also want to
- // push the uses of WideDef here.
-
- // No further widening is needed. The deceased [sz]ext had done it for us.
- return nullptr;
- }
-
- // Does this user itself evaluate to a recurrence after widening?
- WidenedRecTy WideAddRec = getExtendedOperandRecurrence(DU);
- if (!WideAddRec.first)
- WideAddRec = getWideRecurrence(DU);
-
- assert((WideAddRec.first == nullptr) == (WideAddRec.second == Unknown));
- if (!WideAddRec.first) {
- // If use is a loop condition, try to promote the condition instead of
- // truncating the IV first.
- if (widenLoopCompare(DU))
- return nullptr;
-
- // We are here about to generate a truncate instruction that may hurt
- // performance because the scalar evolution expression computed earlier
- // in WideAddRec.first does not indicate a polynomial induction expression.
- // In that case, look at the operands of the use instruction to determine
- // if we can still widen the use instead of truncating its operand.
- if (widenWithVariantUse(DU))
- return nullptr;
-
- // This user does not evaluate to a recurrence after widening, so don't
- // follow it. Instead insert a Trunc to kill off the original use,
- // eventually isolating the original narrow IV so it can be removed.
- truncateIVUse(DU, DT, LI);
- return nullptr;
- }
- // Assume block terminators cannot evaluate to a recurrence. We can't to
- // insert a Trunc after a terminator if there happens to be a critical edge.
- assert(DU.NarrowUse != DU.NarrowUse->getParent()->getTerminator() &&
- "SCEV is not expected to evaluate a block terminator");
-
- // Reuse the IV increment that SCEVExpander created as long as it dominates
- // NarrowUse.
- Instruction *WideUse = nullptr;
- if (WideAddRec.first == WideIncExpr &&
- Rewriter.hoistIVInc(WideInc, DU.NarrowUse))
- WideUse = WideInc;
- else {
- WideUse = cloneIVUser(DU, WideAddRec.first);
- if (!WideUse)
- return nullptr;
- }
- // Evaluation of WideAddRec ensured that the narrow expression could be
- // extended outside the loop without overflow. This suggests that the wide use
- // evaluates to the same expression as the extended narrow use, but doesn't
- // absolutely guarantee it. Hence the following failsafe check. In rare cases
- // where it fails, we simply throw away the newly created wide use.
- if (WideAddRec.first != SE->getSCEV(WideUse)) {
- LLVM_DEBUG(dbgs() << "Wide use expression mismatch: " << *WideUse << ": "
- << *SE->getSCEV(WideUse) << " != " << *WideAddRec.first
- << "\n");
- DeadInsts.emplace_back(WideUse);
- return nullptr;
- }
-
- // if we reached this point then we are going to replace
- // DU.NarrowUse with WideUse. Reattach DbgValue then.
- replaceAllDbgUsesWith(*DU.NarrowUse, *WideUse, *WideUse, *DT);
-
- ExtendKindMap[DU.NarrowUse] = WideAddRec.second;
- // Returning WideUse pushes it on the worklist.
- return WideUse;
-}
-
-/// Add eligible users of NarrowDef to NarrowIVUsers.
-void WidenIV::pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef) {
- const SCEV *NarrowSCEV = SE->getSCEV(NarrowDef);
- bool NonNegativeDef =
- SE->isKnownPredicate(ICmpInst::ICMP_SGE, NarrowSCEV,
- SE->getZero(NarrowSCEV->getType()));
- for (User *U : NarrowDef->users()) {
- Instruction *NarrowUser = cast<Instruction>(U);
-
- // Handle data flow merges and bizarre phi cycles.
- if (!Widened.insert(NarrowUser).second)
- continue;
-
- bool NonNegativeUse = false;
- if (!NonNegativeDef) {
- // We might have a control-dependent range information for this context.
- if (auto RangeInfo = getPostIncRangeInfo(NarrowDef, NarrowUser))
- NonNegativeUse = RangeInfo->getSignedMin().isNonNegative();
- }
-
- NarrowIVUsers.emplace_back(NarrowDef, NarrowUser, WideDef,
- NonNegativeDef || NonNegativeUse);
- }
-}
-
-/// Process a single induction variable. First use the SCEVExpander to create a
-/// wide induction variable that evaluates to the same recurrence as the
-/// original narrow IV. Then use a worklist to forward traverse the narrow IV's
-/// def-use chain. After widenIVUse has processed all interesting IV users, the
-/// narrow IV will be isolated for removal by DeleteDeadPHIs.
-///
-/// It would be simpler to delete uses as they are processed, but we must avoid
-/// invalidating SCEV expressions.
-PHINode *WidenIV::createWideIV(SCEVExpander &Rewriter) {
- // Is this phi an induction variable?
- const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(SE->getSCEV(OrigPhi));
- if (!AddRec)
- return nullptr;
-
- // Widen the induction variable expression.
- const SCEV *WideIVExpr = getExtendKind(OrigPhi) == SignExtended
- ? SE->getSignExtendExpr(AddRec, WideType)
- : SE->getZeroExtendExpr(AddRec, WideType);
-
- assert(SE->getEffectiveSCEVType(WideIVExpr->getType()) == WideType &&
- "Expect the new IV expression to preserve its type");
-
- // Can the IV be extended outside the loop without overflow?
- AddRec = dyn_cast<SCEVAddRecExpr>(WideIVExpr);
- if (!AddRec || AddRec->getLoop() != L)
- return nullptr;
-
- // An AddRec must have loop-invariant operands. Since this AddRec is
- // materialized by a loop header phi, the expression cannot have any post-loop
- // operands, so they must dominate the loop header.
- assert(
- SE->properlyDominates(AddRec->getStart(), L->getHeader()) &&
- SE->properlyDominates(AddRec->getStepRecurrence(*SE), L->getHeader()) &&
- "Loop header phi recurrence inputs do not dominate the loop");
-
- // Iterate over IV uses (including transitive ones) looking for IV increments
- // of the form 'add nsw %iv, <const>'. For each increment and each use of
- // the increment calculate control-dependent range information basing on
- // dominating conditions inside of the loop (e.g. a range check inside of the
- // loop). Calculated ranges are stored in PostIncRangeInfos map.
- //
- // Control-dependent range information is later used to prove that a narrow
- // definition is not negative (see pushNarrowIVUsers). It's difficult to do
- // this on demand because when pushNarrowIVUsers needs this information some
- // of the dominating conditions might be already widened.
- if (UsePostIncrementRanges)
- calculatePostIncRanges(OrigPhi);
-
- // The rewriter provides a value for the desired IV expression. This may
- // either find an existing phi or materialize a new one. Either way, we
- // expect a well-formed cyclic phi-with-increments. i.e. any operand not part
- // of the phi-SCC dominates the loop entry.
- Instruction *InsertPt = &*L->getHeader()->getFirstInsertionPt();
- Value *ExpandInst = Rewriter.expandCodeFor(AddRec, WideType, InsertPt);
- // If the wide phi is not a phi node, for example a cast node, like bitcast,
- // inttoptr, ptrtoint, just skip for now.
- if (!(WidePhi = dyn_cast<PHINode>(ExpandInst))) {
- // if the cast node is an inserted instruction without any user, we should
- // remove it to make sure the pass don't touch the function as we can not
- // wide the phi.
- if (ExpandInst->hasNUses(0) &&
- Rewriter.isInsertedInstruction(cast<Instruction>(ExpandInst)))
- DeadInsts.emplace_back(ExpandInst);
- return nullptr;
- }
-
- // Remembering the WideIV increment generated by SCEVExpander allows
- // widenIVUse to reuse it when widening the narrow IV's increment. We don't
- // employ a general reuse mechanism because the call above is the only call to
- // SCEVExpander. Henceforth, we produce 1-to-1 narrow to wide uses.
- if (BasicBlock *LatchBlock = L->getLoopLatch()) {
- WideInc =
- cast<Instruction>(WidePhi->getIncomingValueForBlock(LatchBlock));
- WideIncExpr = SE->getSCEV(WideInc);
- // Propagate the debug location associated with the original loop increment
- // to the new (widened) increment.
- auto *OrigInc =
- cast<Instruction>(OrigPhi->getIncomingValueForBlock(LatchBlock));
- WideInc->setDebugLoc(OrigInc->getDebugLoc());
- }
-
- LLVM_DEBUG(dbgs() << "Wide IV: " << *WidePhi << "\n");
- ++NumWidened;
-
- // Traverse the def-use chain using a worklist starting at the original IV.
- assert(Widened.empty() && NarrowIVUsers.empty() && "expect initial state" );
-
- Widened.insert(OrigPhi);
- pushNarrowIVUsers(OrigPhi, WidePhi);
-
- while (!NarrowIVUsers.empty()) {
- WidenIV::NarrowIVDefUse DU = NarrowIVUsers.pop_back_val();
-
- // Process a def-use edge. This may replace the use, so don't hold a
- // use_iterator across it.
- Instruction *WideUse = widenIVUse(DU, Rewriter);
-
- // Follow all def-use edges from the previous narrow use.
- if (WideUse)
- pushNarrowIVUsers(DU.NarrowUse, WideUse);
-
- // widenIVUse may have removed the def-use edge.
- if (DU.NarrowDef->use_empty())
- DeadInsts.emplace_back(DU.NarrowDef);
- }
-
- // Attach any debug information to the new PHI.
- replaceAllDbgUsesWith(*OrigPhi, *WidePhi, *WidePhi, *DT);
-
- return WidePhi;
-}
-
-/// Calculates control-dependent range for the given def at the given context
-/// by looking at dominating conditions inside of the loop
-void WidenIV::calculatePostIncRange(Instruction *NarrowDef,
- Instruction *NarrowUser) {
- using namespace llvm::PatternMatch;
-
- Value *NarrowDefLHS;
- const APInt *NarrowDefRHS;
- if (!match(NarrowDef, m_NSWAdd(m_Value(NarrowDefLHS),
- m_APInt(NarrowDefRHS))) ||
- !NarrowDefRHS->isNonNegative())
- return;
-
- auto UpdateRangeFromCondition = [&] (Value *Condition,
- bool TrueDest) {
- CmpInst::Predicate Pred;
- Value *CmpRHS;
- if (!match(Condition, m_ICmp(Pred, m_Specific(NarrowDefLHS),
- m_Value(CmpRHS))))
- return;
-
- CmpInst::Predicate P =
- TrueDest ? Pred : CmpInst::getInversePredicate(Pred);
-
- auto CmpRHSRange = SE->getSignedRange(SE->getSCEV(CmpRHS));
- auto CmpConstrainedLHSRange =
- ConstantRange::makeAllowedICmpRegion(P, CmpRHSRange);
- auto NarrowDefRange = CmpConstrainedLHSRange.addWithNoWrap(
- *NarrowDefRHS, OverflowingBinaryOperator::NoSignedWrap);
-
- updatePostIncRangeInfo(NarrowDef, NarrowUser, NarrowDefRange);
- };
-
- auto UpdateRangeFromGuards = [&](Instruction *Ctx) {
- if (!HasGuards)
- return;
-
- for (Instruction &I : make_range(Ctx->getIterator().getReverse(),
- Ctx->getParent()->rend())) {
- Value *C = nullptr;
- if (match(&I, m_Intrinsic<Intrinsic::experimental_guard>(m_Value(C))))
- UpdateRangeFromCondition(C, /*TrueDest=*/true);
- }
- };
-
- UpdateRangeFromGuards(NarrowUser);
-
- BasicBlock *NarrowUserBB = NarrowUser->getParent();
- // If NarrowUserBB is statically unreachable asking dominator queries may
- // yield surprising results. (e.g. the block may not have a dom tree node)
- if (!DT->isReachableFromEntry(NarrowUserBB))
- return;
-
- for (auto *DTB = (*DT)[NarrowUserBB]->getIDom();
- L->contains(DTB->getBlock());
- DTB = DTB->getIDom()) {
- auto *BB = DTB->getBlock();
- auto *TI = BB->getTerminator();
- UpdateRangeFromGuards(TI);
-
- auto *BI = dyn_cast<BranchInst>(TI);
- if (!BI || !BI->isConditional())
- continue;
-
- auto *TrueSuccessor = BI->getSuccessor(0);
- auto *FalseSuccessor = BI->getSuccessor(1);
-
- auto DominatesNarrowUser = [this, NarrowUser] (BasicBlockEdge BBE) {
- return BBE.isSingleEdge() &&
- DT->dominates(BBE, NarrowUser->getParent());
- };
-
- if (DominatesNarrowUser(BasicBlockEdge(BB, TrueSuccessor)))
- UpdateRangeFromCondition(BI->getCondition(), /*TrueDest=*/true);
-
- if (DominatesNarrowUser(BasicBlockEdge(BB, FalseSuccessor)))
- UpdateRangeFromCondition(BI->getCondition(), /*TrueDest=*/false);
- }
-}
-
-/// Calculates PostIncRangeInfos map for the given IV
-void WidenIV::calculatePostIncRanges(PHINode *OrigPhi) {
- SmallPtrSet<Instruction *, 16> Visited;
- SmallVector<Instruction *, 6> Worklist;
- Worklist.push_back(OrigPhi);
- Visited.insert(OrigPhi);
-
- while (!Worklist.empty()) {
- Instruction *NarrowDef = Worklist.pop_back_val();
-
- for (Use &U : NarrowDef->uses()) {
- auto *NarrowUser = cast<Instruction>(U.getUser());
-
- // Don't go looking outside the current loop.
- auto *NarrowUserLoop = (*LI)[NarrowUser->getParent()];
- if (!NarrowUserLoop || !L->contains(NarrowUserLoop))
- continue;
-
- if (!Visited.insert(NarrowUser).second)
- continue;
-
- Worklist.push_back(NarrowUser);
-
- calculatePostIncRange(NarrowDef, NarrowUser);
- }
- }
-}
-
-PHINode *llvm::createWideIV(const WideIVInfo &WI,
- LoopInfo *LI, ScalarEvolution *SE, SCEVExpander &Rewriter,
- DominatorTree *DT, SmallVectorImpl<WeakTrackingVH> &DeadInsts,
- unsigned &NumElimExt, unsigned &NumWidened,
- bool HasGuards, bool UsePostIncrementRanges) {
- WidenIV Widener(WI, LI, SE, DT, DeadInsts, HasGuards, UsePostIncrementRanges);
- PHINode *WidePHI = Widener.createWideIV(Rewriter);
- NumElimExt = Widener.getNumElimExt();
- NumWidened = Widener.getNumWidened();
- return WidePHI;
-}
+
+//===----------------------------------------------------------------------===//
+// Widen Induction Variables - Extend the width of an IV to cover its
+// widest uses.
+//===----------------------------------------------------------------------===//
+
+class WidenIV {
+ // Parameters
+ PHINode *OrigPhi;
+ Type *WideType;
+
+ // Context
+ LoopInfo *LI;
+ Loop *L;
+ ScalarEvolution *SE;
+ DominatorTree *DT;
+
+ // Does the module have any calls to the llvm.experimental.guard intrinsic
+ // at all? If not we can avoid scanning instructions looking for guards.
+ bool HasGuards;
+
+ bool UsePostIncrementRanges;
+
+ // Statistics
+ unsigned NumElimExt = 0;
+ unsigned NumWidened = 0;
+
+ // Result
+ PHINode *WidePhi = nullptr;
+ Instruction *WideInc = nullptr;
+ const SCEV *WideIncExpr = nullptr;
+ SmallVectorImpl<WeakTrackingVH> &DeadInsts;
+
+ SmallPtrSet<Instruction *,16> Widened;
+
+ enum ExtendKind { ZeroExtended, SignExtended, Unknown };
+
+ // A map tracking the kind of extension used to widen each narrow IV
+ // and narrow IV user.
+ // Key: pointer to a narrow IV or IV user.
+ // Value: the kind of extension used to widen this Instruction.
+ DenseMap<AssertingVH<Instruction>, ExtendKind> ExtendKindMap;
+
+ using DefUserPair = std::pair<AssertingVH<Value>, AssertingVH<Instruction>>;
+
+ // A map with control-dependent ranges for post increment IV uses. The key is
+ // a pair of IV def and a use of this def denoting the context. The value is
+ // a ConstantRange representing possible values of the def at the given
+ // context.
+ DenseMap<DefUserPair, ConstantRange> PostIncRangeInfos;
+
+ Optional<ConstantRange> getPostIncRangeInfo(Value *Def,
+ Instruction *UseI) {
+ DefUserPair Key(Def, UseI);
+ auto It = PostIncRangeInfos.find(Key);
+ return It == PostIncRangeInfos.end()
+ ? Optional<ConstantRange>(None)
+ : Optional<ConstantRange>(It->second);
+ }
+
+ void calculatePostIncRanges(PHINode *OrigPhi);
+ void calculatePostIncRange(Instruction *NarrowDef, Instruction *NarrowUser);
+
+ void updatePostIncRangeInfo(Value *Def, Instruction *UseI, ConstantRange R) {
+ DefUserPair Key(Def, UseI);
+ auto It = PostIncRangeInfos.find(Key);
+ if (It == PostIncRangeInfos.end())
+ PostIncRangeInfos.insert({Key, R});
+ else
+ It->second = R.intersectWith(It->second);
+ }
+
+public:
+ /// Record a link in the Narrow IV def-use chain along with the WideIV that
+ /// computes the same value as the Narrow IV def. This avoids caching Use*
+ /// pointers.
+ struct NarrowIVDefUse {
+ Instruction *NarrowDef = nullptr;
+ Instruction *NarrowUse = nullptr;
+ Instruction *WideDef = nullptr;
+
+ // True if the narrow def is never negative. Tracking this information lets
+ // us use a sign extension instead of a zero extension or vice versa, when
+ // profitable and legal.
+ bool NeverNegative = false;
+
+ NarrowIVDefUse(Instruction *ND, Instruction *NU, Instruction *WD,
+ bool NeverNegative)
+ : NarrowDef(ND), NarrowUse(NU), WideDef(WD),
+ NeverNegative(NeverNegative) {}
+ };
+
+ WidenIV(const WideIVInfo &WI, LoopInfo *LInfo, ScalarEvolution *SEv,
+ DominatorTree *DTree, SmallVectorImpl<WeakTrackingVH> &DI,
+ bool HasGuards, bool UsePostIncrementRanges = true);
+
+ PHINode *createWideIV(SCEVExpander &Rewriter);
+
+ unsigned getNumElimExt() { return NumElimExt; };
+ unsigned getNumWidened() { return NumWidened; };
+
+protected:
+ Value *createExtendInst(Value *NarrowOper, Type *WideType, bool IsSigned,
+ Instruction *Use);
+
+ Instruction *cloneIVUser(NarrowIVDefUse DU, const SCEVAddRecExpr *WideAR);
+ Instruction *cloneArithmeticIVUser(NarrowIVDefUse DU,
+ const SCEVAddRecExpr *WideAR);
+ Instruction *cloneBitwiseIVUser(NarrowIVDefUse DU);
+
+ ExtendKind getExtendKind(Instruction *I);
+
+ using WidenedRecTy = std::pair<const SCEVAddRecExpr *, ExtendKind>;
+
+ WidenedRecTy getWideRecurrence(NarrowIVDefUse DU);
+
+ WidenedRecTy getExtendedOperandRecurrence(NarrowIVDefUse DU);
+
+ const SCEV *getSCEVByOpCode(const SCEV *LHS, const SCEV *RHS,
+ unsigned OpCode) const;
+
+ Instruction *widenIVUse(NarrowIVDefUse DU, SCEVExpander &Rewriter);
+
+ bool widenLoopCompare(NarrowIVDefUse DU);
+ bool widenWithVariantUse(NarrowIVDefUse DU);
+
+ void pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef);
+
+private:
+ SmallVector<NarrowIVDefUse, 8> NarrowIVUsers;
+};
+
+
+/// Determine the insertion point for this user. By default, insert immediately
+/// before the user. SCEVExpander or LICM will hoist loop invariants out of the
+/// loop. For PHI nodes, there may be multiple uses, so compute the nearest
+/// common dominator for the incoming blocks. A nullptr can be returned if no
+/// viable location is found: it may happen if User is a PHI and Def only comes
+/// to this PHI from unreachable blocks.
+static Instruction *getInsertPointForUses(Instruction *User, Value *Def,
+ DominatorTree *DT, LoopInfo *LI) {
+ PHINode *PHI = dyn_cast<PHINode>(User);
+ if (!PHI)
+ return User;
+
+ Instruction *InsertPt = nullptr;
+ for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i) {
+ if (PHI->getIncomingValue(i) != Def)
+ continue;
+
+ BasicBlock *InsertBB = PHI->getIncomingBlock(i);
+
+ if (!DT->isReachableFromEntry(InsertBB))
+ continue;
+
+ if (!InsertPt) {
+ InsertPt = InsertBB->getTerminator();
+ continue;
+ }
+ InsertBB = DT->findNearestCommonDominator(InsertPt->getParent(), InsertBB);
+ InsertPt = InsertBB->getTerminator();
+ }
+
+ // If we have skipped all inputs, it means that Def only comes to Phi from
+ // unreachable blocks.
+ if (!InsertPt)
+ return nullptr;
+
+ auto *DefI = dyn_cast<Instruction>(Def);
+ if (!DefI)
+ return InsertPt;
+
+ assert(DT->dominates(DefI, InsertPt) && "def does not dominate all uses");
+
+ auto *L = LI->getLoopFor(DefI->getParent());
+ assert(!L || L->contains(LI->getLoopFor(InsertPt->getParent())));
+
+ for (auto *DTN = (*DT)[InsertPt->getParent()]; DTN; DTN = DTN->getIDom())
+ if (LI->getLoopFor(DTN->getBlock()) == L)
+ return DTN->getBlock()->getTerminator();
+
+ llvm_unreachable("DefI dominates InsertPt!");
+}
+
+WidenIV::WidenIV(const WideIVInfo &WI, LoopInfo *LInfo, ScalarEvolution *SEv,
+ DominatorTree *DTree, SmallVectorImpl<WeakTrackingVH> &DI,
+ bool HasGuards, bool UsePostIncrementRanges)
+ : OrigPhi(WI.NarrowIV), WideType(WI.WidestNativeType), LI(LInfo),
+ L(LI->getLoopFor(OrigPhi->getParent())), SE(SEv), DT(DTree),
+ HasGuards(HasGuards), UsePostIncrementRanges(UsePostIncrementRanges),
+ DeadInsts(DI) {
+ assert(L->getHeader() == OrigPhi->getParent() && "Phi must be an IV");
+ ExtendKindMap[OrigPhi] = WI.IsSigned ? SignExtended : ZeroExtended;
+}
+
+Value *WidenIV::createExtendInst(Value *NarrowOper, Type *WideType,
+ bool IsSigned, Instruction *Use) {
+ // Set the debug location and conservative insertion point.
+ IRBuilder<> Builder(Use);
+ // Hoist the insertion point into loop preheaders as far as possible.
+ for (const Loop *L = LI->getLoopFor(Use->getParent());
+ L && L->getLoopPreheader() && L->isLoopInvariant(NarrowOper);
+ L = L->getParentLoop())
+ Builder.SetInsertPoint(L->getLoopPreheader()->getTerminator());
+
+ return IsSigned ? Builder.CreateSExt(NarrowOper, WideType) :
+ Builder.CreateZExt(NarrowOper, WideType);
+}
+
+/// Instantiate a wide operation to replace a narrow operation. This only needs
+/// to handle operations that can evaluation to SCEVAddRec. It can safely return
+/// 0 for any operation we decide not to clone.
+Instruction *WidenIV::cloneIVUser(WidenIV::NarrowIVDefUse DU,
+ const SCEVAddRecExpr *WideAR) {
+ unsigned Opcode = DU.NarrowUse->getOpcode();
+ switch (Opcode) {
+ default:
+ return nullptr;
+ case Instruction::Add:
+ case Instruction::Mul:
+ case Instruction::UDiv:
+ case Instruction::Sub:
+ return cloneArithmeticIVUser(DU, WideAR);
+
+ case Instruction::And:
+ case Instruction::Or:
+ case Instruction::Xor:
+ case Instruction::Shl:
+ case Instruction::LShr:
+ case Instruction::AShr:
+ return cloneBitwiseIVUser(DU);
+ }
+}
+
+Instruction *WidenIV::cloneBitwiseIVUser(WidenIV::NarrowIVDefUse DU) {
+ Instruction *NarrowUse = DU.NarrowUse;
+ Instruction *NarrowDef = DU.NarrowDef;
+ Instruction *WideDef = DU.WideDef;
+
+ LLVM_DEBUG(dbgs() << "Cloning bitwise IVUser: " << *NarrowUse << "\n");
+
+ // Replace NarrowDef operands with WideDef. Otherwise, we don't know anything
+ // about the narrow operand yet so must insert a [sz]ext. It is probably loop
+ // invariant and will be folded or hoisted. If it actually comes from a
+ // widened IV, it should be removed during a future call to widenIVUse.
+ bool IsSigned = getExtendKind(NarrowDef) == SignExtended;
+ Value *LHS = (NarrowUse->getOperand(0) == NarrowDef)
+ ? WideDef
+ : createExtendInst(NarrowUse->getOperand(0), WideType,
+ IsSigned, NarrowUse);
+ Value *RHS = (NarrowUse->getOperand(1) == NarrowDef)
+ ? WideDef
+ : createExtendInst(NarrowUse->getOperand(1), WideType,
+ IsSigned, NarrowUse);
+
+ auto *NarrowBO = cast<BinaryOperator>(NarrowUse);
+ auto *WideBO = BinaryOperator::Create(NarrowBO->getOpcode(), LHS, RHS,
+ NarrowBO->getName());
+ IRBuilder<> Builder(NarrowUse);
+ Builder.Insert(WideBO);
+ WideBO->copyIRFlags(NarrowBO);
+ return WideBO;
+}
+
+Instruction *WidenIV::cloneArithmeticIVUser(WidenIV::NarrowIVDefUse DU,
+ const SCEVAddRecExpr *WideAR) {
+ Instruction *NarrowUse = DU.NarrowUse;
+ Instruction *NarrowDef = DU.NarrowDef;
+ Instruction *WideDef = DU.WideDef;
+
+ LLVM_DEBUG(dbgs() << "Cloning arithmetic IVUser: " << *NarrowUse << "\n");
+
+ unsigned IVOpIdx = (NarrowUse->getOperand(0) == NarrowDef) ? 0 : 1;
+
+ // We're trying to find X such that
+ //
+ // Widen(NarrowDef `op` NonIVNarrowDef) == WideAR == WideDef `op.wide` X
+ //
+ // We guess two solutions to X, sext(NonIVNarrowDef) and zext(NonIVNarrowDef),
+ // and check using SCEV if any of them are correct.
+
+ // Returns true if extending NonIVNarrowDef according to `SignExt` is a
+ // correct solution to X.
+ auto GuessNonIVOperand = [&](bool SignExt) {
+ const SCEV *WideLHS;
+ const SCEV *WideRHS;
+
+ auto GetExtend = [this, SignExt](const SCEV *S, Type *Ty) {
+ if (SignExt)
+ return SE->getSignExtendExpr(S, Ty);
+ return SE->getZeroExtendExpr(S, Ty);
+ };
+
+ if (IVOpIdx == 0) {
+ WideLHS = SE->getSCEV(WideDef);
+ const SCEV *NarrowRHS = SE->getSCEV(NarrowUse->getOperand(1));
+ WideRHS = GetExtend(NarrowRHS, WideType);
+ } else {
+ const SCEV *NarrowLHS = SE->getSCEV(NarrowUse->getOperand(0));
+ WideLHS = GetExtend(NarrowLHS, WideType);
+ WideRHS = SE->getSCEV(WideDef);
+ }
+
+ // WideUse is "WideDef `op.wide` X" as described in the comment.
+ const SCEV *WideUse =
+ getSCEVByOpCode(WideLHS, WideRHS, NarrowUse->getOpcode());
+
+ return WideUse == WideAR;
+ };
+
+ bool SignExtend = getExtendKind(NarrowDef) == SignExtended;
+ if (!GuessNonIVOperand(SignExtend)) {
+ SignExtend = !SignExtend;
+ if (!GuessNonIVOperand(SignExtend))
+ return nullptr;
+ }
+
+ Value *LHS = (NarrowUse->getOperand(0) == NarrowDef)
+ ? WideDef
+ : createExtendInst(NarrowUse->getOperand(0), WideType,
+ SignExtend, NarrowUse);
+ Value *RHS = (NarrowUse->getOperand(1) == NarrowDef)
+ ? WideDef
+ : createExtendInst(NarrowUse->getOperand(1), WideType,
+ SignExtend, NarrowUse);
+
+ auto *NarrowBO = cast<BinaryOperator>(NarrowUse);
+ auto *WideBO = BinaryOperator::Create(NarrowBO->getOpcode(), LHS, RHS,
+ NarrowBO->getName());
+
+ IRBuilder<> Builder(NarrowUse);
+ Builder.Insert(WideBO);
+ WideBO->copyIRFlags(NarrowBO);
+ return WideBO;
+}
+
+WidenIV::ExtendKind WidenIV::getExtendKind(Instruction *I) {
+ auto It = ExtendKindMap.find(I);
+ assert(It != ExtendKindMap.end() && "Instruction not yet extended!");
+ return It->second;
+}
+
+const SCEV *WidenIV::getSCEVByOpCode(const SCEV *LHS, const SCEV *RHS,
+ unsigned OpCode) const {
+ switch (OpCode) {
+ case Instruction::Add:
+ return SE->getAddExpr(LHS, RHS);
+ case Instruction::Sub:
+ return SE->getMinusSCEV(LHS, RHS);
+ case Instruction::Mul:
+ return SE->getMulExpr(LHS, RHS);
+ case Instruction::UDiv:
+ return SE->getUDivExpr(LHS, RHS);
+ default:
+ llvm_unreachable("Unsupported opcode.");
+ };
+}
+
+/// No-wrap operations can transfer sign extension of their result to their
+/// operands. Generate the SCEV value for the widened operation without
+/// actually modifying the IR yet. If the expression after extending the
+/// operands is an AddRec for this loop, return the AddRec and the kind of
+/// extension used.
+WidenIV::WidenedRecTy
+WidenIV::getExtendedOperandRecurrence(WidenIV::NarrowIVDefUse DU) {
+ // Handle the common case of add<nsw/nuw>
+ const unsigned OpCode = DU.NarrowUse->getOpcode();
+ // Only Add/Sub/Mul instructions supported yet.
+ if (OpCode != Instruction::Add && OpCode != Instruction::Sub &&
+ OpCode != Instruction::Mul)
+ return {nullptr, Unknown};
+
+ // One operand (NarrowDef) has already been extended to WideDef. Now determine
+ // if extending the other will lead to a recurrence.
+ const unsigned ExtendOperIdx =
+ DU.NarrowUse->getOperand(0) == DU.NarrowDef ? 1 : 0;
+ assert(DU.NarrowUse->getOperand(1-ExtendOperIdx) == DU.NarrowDef && "bad DU");
+
+ const SCEV *ExtendOperExpr = nullptr;
+ const OverflowingBinaryOperator *OBO =
+ cast<OverflowingBinaryOperator>(DU.NarrowUse);
+ ExtendKind ExtKind = getExtendKind(DU.NarrowDef);
+ if (ExtKind == SignExtended && OBO->hasNoSignedWrap())
+ ExtendOperExpr = SE->getSignExtendExpr(
+ SE->getSCEV(DU.NarrowUse->getOperand(ExtendOperIdx)), WideType);
+ else if(ExtKind == ZeroExtended && OBO->hasNoUnsignedWrap())
+ ExtendOperExpr = SE->getZeroExtendExpr(
+ SE->getSCEV(DU.NarrowUse->getOperand(ExtendOperIdx)), WideType);
+ else
+ return {nullptr, Unknown};
+
+ // When creating this SCEV expr, don't apply the current operations NSW or NUW
+ // flags. This instruction may be guarded by control flow that the no-wrap
+ // behavior depends on. Non-control-equivalent instructions can be mapped to
+ // the same SCEV expression, and it would be incorrect to transfer NSW/NUW
+ // semantics to those operations.
+ const SCEV *lhs = SE->getSCEV(DU.WideDef);
+ const SCEV *rhs = ExtendOperExpr;
+
+ // Let's swap operands to the initial order for the case of non-commutative
+ // operations, like SUB. See PR21014.
+ if (ExtendOperIdx == 0)
+ std::swap(lhs, rhs);
+ const SCEVAddRecExpr *AddRec =
+ dyn_cast<SCEVAddRecExpr>(getSCEVByOpCode(lhs, rhs, OpCode));
+
+ if (!AddRec || AddRec->getLoop() != L)
+ return {nullptr, Unknown};
+
+ return {AddRec, ExtKind};
+}
+
+/// Is this instruction potentially interesting for further simplification after
+/// widening it's type? In other words, can the extend be safely hoisted out of
+/// the loop with SCEV reducing the value to a recurrence on the same loop. If
+/// so, return the extended recurrence and the kind of extension used. Otherwise
+/// return {nullptr, Unknown}.
+WidenIV::WidenedRecTy WidenIV::getWideRecurrence(WidenIV::NarrowIVDefUse DU) {
+ if (!SE->isSCEVable(DU.NarrowUse->getType()))
+ return {nullptr, Unknown};
+
+ const SCEV *NarrowExpr = SE->getSCEV(DU.NarrowUse);
+ if (SE->getTypeSizeInBits(NarrowExpr->getType()) >=
+ SE->getTypeSizeInBits(WideType)) {
+ // NarrowUse implicitly widens its operand. e.g. a gep with a narrow
+ // index. So don't follow this use.
+ return {nullptr, Unknown};
+ }
+
+ const SCEV *WideExpr;
+ ExtendKind ExtKind;
+ if (DU.NeverNegative) {
+ WideExpr = SE->getSignExtendExpr(NarrowExpr, WideType);
+ if (isa<SCEVAddRecExpr>(WideExpr))
+ ExtKind = SignExtended;
+ else {
+ WideExpr = SE->getZeroExtendExpr(NarrowExpr, WideType);
+ ExtKind = ZeroExtended;
+ }
+ } else if (getExtendKind(DU.NarrowDef) == SignExtended) {
+ WideExpr = SE->getSignExtendExpr(NarrowExpr, WideType);
+ ExtKind = SignExtended;
+ } else {
+ WideExpr = SE->getZeroExtendExpr(NarrowExpr, WideType);
+ ExtKind = ZeroExtended;
+ }
+ const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(WideExpr);
+ if (!AddRec || AddRec->getLoop() != L)
+ return {nullptr, Unknown};
+ return {AddRec, ExtKind};
+}
+
+/// This IV user cannot be widened. Replace this use of the original narrow IV
+/// with a truncation of the new wide IV to isolate and eliminate the narrow IV.
+static void truncateIVUse(WidenIV::NarrowIVDefUse DU, DominatorTree *DT,
+ LoopInfo *LI) {
+ auto *InsertPt = getInsertPointForUses(DU.NarrowUse, DU.NarrowDef, DT, LI);
+ if (!InsertPt)
+ return;
+ LLVM_DEBUG(dbgs() << "INDVARS: Truncate IV " << *DU.WideDef << " for user "
+ << *DU.NarrowUse << "\n");
+ IRBuilder<> Builder(InsertPt);
+ Value *Trunc = Builder.CreateTrunc(DU.WideDef, DU.NarrowDef->getType());
+ DU.NarrowUse->replaceUsesOfWith(DU.NarrowDef, Trunc);
+}
+
+/// If the narrow use is a compare instruction, then widen the compare
+// (and possibly the other operand). The extend operation is hoisted into the
+// loop preheader as far as possible.
+bool WidenIV::widenLoopCompare(WidenIV::NarrowIVDefUse DU) {
+ ICmpInst *Cmp = dyn_cast<ICmpInst>(DU.NarrowUse);
+ if (!Cmp)
+ return false;
+
+ // We can legally widen the comparison in the following two cases:
+ //
+ // - The signedness of the IV extension and comparison match
+ //
+ // - The narrow IV is always positive (and thus its sign extension is equal
+ // to its zero extension). For instance, let's say we're zero extending
+ // %narrow for the following use
+ //
+ // icmp slt i32 %narrow, %val ... (A)
+ //
+ // and %narrow is always positive. Then
+ //
+ // (A) == icmp slt i32 sext(%narrow), sext(%val)
+ // == icmp slt i32 zext(%narrow), sext(%val)
+ bool IsSigned = getExtendKind(DU.NarrowDef) == SignExtended;
+ if (!(DU.NeverNegative || IsSigned == Cmp->isSigned()))
+ return false;
+
+ Value *Op = Cmp->getOperand(Cmp->getOperand(0) == DU.NarrowDef ? 1 : 0);
+ unsigned CastWidth = SE->getTypeSizeInBits(Op->getType());
+ unsigned IVWidth = SE->getTypeSizeInBits(WideType);
+ assert(CastWidth <= IVWidth && "Unexpected width while widening compare.");
+
+ // Widen the compare instruction.
+ auto *InsertPt = getInsertPointForUses(DU.NarrowUse, DU.NarrowDef, DT, LI);
+ if (!InsertPt)
+ return false;
+ IRBuilder<> Builder(InsertPt);
+ DU.NarrowUse->replaceUsesOfWith(DU.NarrowDef, DU.WideDef);
+
+ // Widen the other operand of the compare, if necessary.
+ if (CastWidth < IVWidth) {
+ Value *ExtOp = createExtendInst(Op, WideType, Cmp->isSigned(), Cmp);
+ DU.NarrowUse->replaceUsesOfWith(Op, ExtOp);
+ }
+ return true;
+}
+
+// The widenIVUse avoids generating trunc by evaluating the use as AddRec, this
+// will not work when:
+// 1) SCEV traces back to an instruction inside the loop that SCEV can not
+// expand, eg. add %indvar, (load %addr)
+// 2) SCEV finds a loop variant, eg. add %indvar, %loopvariant
+// While SCEV fails to avoid trunc, we can still try to use instruction
+// combining approach to prove trunc is not required. This can be further
+// extended with other instruction combining checks, but for now we handle the
+// following case (sub can be "add" and "mul", "nsw + sext" can be "nus + zext")
+//
+// Src:
+// %c = sub nsw %b, %indvar
+// %d = sext %c to i64
+// Dst:
+// %indvar.ext1 = sext %indvar to i64
+// %m = sext %b to i64
+// %d = sub nsw i64 %m, %indvar.ext1
+// Therefore, as long as the result of add/sub/mul is extended to wide type, no
+// trunc is required regardless of how %b is generated. This pattern is common
+// when calculating address in 64 bit architecture
+bool WidenIV::widenWithVariantUse(WidenIV::NarrowIVDefUse DU) {
+ Instruction *NarrowUse = DU.NarrowUse;
+ Instruction *NarrowDef = DU.NarrowDef;
+ Instruction *WideDef = DU.WideDef;
+
+ // Handle the common case of add<nsw/nuw>
+ const unsigned OpCode = NarrowUse->getOpcode();
+ // Only Add/Sub/Mul instructions are supported.
+ if (OpCode != Instruction::Add && OpCode != Instruction::Sub &&
+ OpCode != Instruction::Mul)
+ return false;
+
+ // The operand that is not defined by NarrowDef of DU. Let's call it the
+ // other operand.
+ assert((NarrowUse->getOperand(0) == NarrowDef ||
+ NarrowUse->getOperand(1) == NarrowDef) &&
+ "bad DU");
+
+ const OverflowingBinaryOperator *OBO =
+ cast<OverflowingBinaryOperator>(NarrowUse);
+ ExtendKind ExtKind = getExtendKind(NarrowDef);
+ bool CanSignExtend = ExtKind == SignExtended && OBO->hasNoSignedWrap();
+ bool CanZeroExtend = ExtKind == ZeroExtended && OBO->hasNoUnsignedWrap();
+ auto AnotherOpExtKind = ExtKind;
+
+ // Check that all uses are either:
+ // - narrow def (in case of we are widening the IV increment);
+ // - single-input LCSSA Phis;
+ // - comparison of the chosen type;
+ // - extend of the chosen type (raison d'etre).
+ SmallVector<Instruction *, 4> ExtUsers;
+ SmallVector<PHINode *, 4> LCSSAPhiUsers;
+ SmallVector<ICmpInst *, 4> ICmpUsers;
+ for (Use &U : NarrowUse->uses()) {
+ Instruction *User = cast<Instruction>(U.getUser());
+ if (User == NarrowDef)
+ continue;
+ if (!L->contains(User)) {
+ auto *LCSSAPhi = cast<PHINode>(User);
+ // Make sure there is only 1 input, so that we don't have to split
+ // critical edges.
+ if (LCSSAPhi->getNumOperands() != 1)
+ return false;
+ LCSSAPhiUsers.push_back(LCSSAPhi);
+ continue;
+ }
+ if (auto *ICmp = dyn_cast<ICmpInst>(User)) {
+ auto Pred = ICmp->getPredicate();
+ // We have 3 types of predicates: signed, unsigned and equality
+ // predicates. For equality, it's legal to widen icmp for either sign and
+ // zero extend. For sign extend, we can also do so for signed predicates,
+ // likeweise for zero extend we can widen icmp for unsigned predicates.
+ if (ExtKind == ZeroExtended && ICmpInst::isSigned(Pred))
+ return false;
+ if (ExtKind == SignExtended && ICmpInst::isUnsigned(Pred))
+ return false;
+ ICmpUsers.push_back(ICmp);
+ continue;
+ }
+ if (ExtKind == SignExtended)
+ User = dyn_cast<SExtInst>(User);
+ else
+ User = dyn_cast<ZExtInst>(User);
+ if (!User || User->getType() != WideType)
+ return false;
+ ExtUsers.push_back(User);
+ }
+ if (ExtUsers.empty()) {
+ DeadInsts.emplace_back(NarrowUse);
+ return true;
+ }
+
+ // We'll prove some facts that should be true in the context of ext users. If
+ // there is no users, we are done now. If there are some, pick their common
+ // dominator as context.
+ Instruction *Context = nullptr;
+ for (auto *Ext : ExtUsers) {
+ if (!Context || DT->dominates(Ext, Context))
+ Context = Ext;
+ else if (!DT->dominates(Context, Ext))
+ // For users that don't have dominance relation, use common dominator.
+ Context =
+ DT->findNearestCommonDominator(Context->getParent(), Ext->getParent())
+ ->getTerminator();
+ }
+ assert(Context && "Context not found?");
+
+ if (!CanSignExtend && !CanZeroExtend) {
+ // Because InstCombine turns 'sub nuw' to 'add' losing the no-wrap flag, we
+ // will most likely not see it. Let's try to prove it.
+ if (OpCode != Instruction::Add)
+ return false;
+ if (ExtKind != ZeroExtended)
+ return false;
+ const SCEV *LHS = SE->getSCEV(OBO->getOperand(0));
+ const SCEV *RHS = SE->getSCEV(OBO->getOperand(1));
+ // TODO: Support case for NarrowDef = NarrowUse->getOperand(1).
+ if (NarrowUse->getOperand(0) != NarrowDef)
+ return false;
+ if (!SE->isKnownNegative(RHS))
+ return false;
+ bool ProvedSubNUW = SE->isKnownPredicateAt(
+ ICmpInst::ICMP_UGE, LHS, SE->getNegativeSCEV(RHS), Context);
+ if (!ProvedSubNUW)
+ return false;
+ // In fact, our 'add' is 'sub nuw'. We will need to widen the 2nd operand as
+ // neg(zext(neg(op))), which is basically sext(op).
+ AnotherOpExtKind = SignExtended;
+ }
+
+ // Verifying that Defining operand is an AddRec
+ const SCEV *Op1 = SE->getSCEV(WideDef);
+ const SCEVAddRecExpr *AddRecOp1 = dyn_cast<SCEVAddRecExpr>(Op1);
+ if (!AddRecOp1 || AddRecOp1->getLoop() != L)
+ return false;
+
+ LLVM_DEBUG(dbgs() << "Cloning arithmetic IVUser: " << *NarrowUse << "\n");
+
+ // Generating a widening use instruction.
+ Value *LHS = (NarrowUse->getOperand(0) == NarrowDef)
+ ? WideDef
+ : createExtendInst(NarrowUse->getOperand(0), WideType,
+ AnotherOpExtKind, NarrowUse);
+ Value *RHS = (NarrowUse->getOperand(1) == NarrowDef)
+ ? WideDef
+ : createExtendInst(NarrowUse->getOperand(1), WideType,
+ AnotherOpExtKind, NarrowUse);
+
+ auto *NarrowBO = cast<BinaryOperator>(NarrowUse);
+ auto *WideBO = BinaryOperator::Create(NarrowBO->getOpcode(), LHS, RHS,
+ NarrowBO->getName());
+ IRBuilder<> Builder(NarrowUse);
+ Builder.Insert(WideBO);
+ WideBO->copyIRFlags(NarrowBO);
+ ExtendKindMap[NarrowUse] = ExtKind;
+
+ for (Instruction *User : ExtUsers) {
+ assert(User->getType() == WideType && "Checked before!");
+ LLVM_DEBUG(dbgs() << "INDVARS: eliminating " << *User << " replaced by "
+ << *WideBO << "\n");
+ ++NumElimExt;
+ User->replaceAllUsesWith(WideBO);
+ DeadInsts.emplace_back(User);
+ }
+
+ for (PHINode *User : LCSSAPhiUsers) {
+ assert(User->getNumOperands() == 1 && "Checked before!");
+ Builder.SetInsertPoint(User);
+ auto *WidePN =
+ Builder.CreatePHI(WideBO->getType(), 1, User->getName() + ".wide");
+ BasicBlock *LoopExitingBlock = User->getParent()->getSinglePredecessor();
+ assert(LoopExitingBlock && L->contains(LoopExitingBlock) &&
+ "Not a LCSSA Phi?");
+ WidePN->addIncoming(WideBO, LoopExitingBlock);
+ Builder.SetInsertPoint(&*User->getParent()->getFirstInsertionPt());
+ auto *TruncPN = Builder.CreateTrunc(WidePN, User->getType());
+ User->replaceAllUsesWith(TruncPN);
+ DeadInsts.emplace_back(User);
+ }
+
+ for (ICmpInst *User : ICmpUsers) {
+ Builder.SetInsertPoint(User);
+ auto ExtendedOp = [&](Value * V)->Value * {
+ if (V == NarrowUse)
+ return WideBO;
+ if (ExtKind == ZeroExtended)
+ return Builder.CreateZExt(V, WideBO->getType());
+ else
+ return Builder.CreateSExt(V, WideBO->getType());
+ };
+ auto Pred = User->getPredicate();
+ auto *LHS = ExtendedOp(User->getOperand(0));
+ auto *RHS = ExtendedOp(User->getOperand(1));
+ auto *WideCmp =
+ Builder.CreateICmp(Pred, LHS, RHS, User->getName() + ".wide");
+ User->replaceAllUsesWith(WideCmp);
+ DeadInsts.emplace_back(User);
+ }
+
+ return true;
+}
+
+/// Determine whether an individual user of the narrow IV can be widened. If so,
+/// return the wide clone of the user.
+Instruction *WidenIV::widenIVUse(WidenIV::NarrowIVDefUse DU, SCEVExpander &Rewriter) {
+ assert(ExtendKindMap.count(DU.NarrowDef) &&
+ "Should already know the kind of extension used to widen NarrowDef");
+
+ // Stop traversing the def-use chain at inner-loop phis or post-loop phis.
+ if (PHINode *UsePhi = dyn_cast<PHINode>(DU.NarrowUse)) {
+ if (LI->getLoopFor(UsePhi->getParent()) != L) {
+ // For LCSSA phis, sink the truncate outside the loop.
+ // After SimplifyCFG most loop exit targets have a single predecessor.
+ // Otherwise fall back to a truncate within the loop.
+ if (UsePhi->getNumOperands() != 1)
+ truncateIVUse(DU, DT, LI);
+ else {
+ // Widening the PHI requires us to insert a trunc. The logical place
+ // for this trunc is in the same BB as the PHI. This is not possible if
+ // the BB is terminated by a catchswitch.
+ if (isa<CatchSwitchInst>(UsePhi->getParent()->getTerminator()))
+ return nullptr;
+
+ PHINode *WidePhi =
+ PHINode::Create(DU.WideDef->getType(), 1, UsePhi->getName() + ".wide",
+ UsePhi);
+ WidePhi->addIncoming(DU.WideDef, UsePhi->getIncomingBlock(0));
+ IRBuilder<> Builder(&*WidePhi->getParent()->getFirstInsertionPt());
+ Value *Trunc = Builder.CreateTrunc(WidePhi, DU.NarrowDef->getType());
+ UsePhi->replaceAllUsesWith(Trunc);
+ DeadInsts.emplace_back(UsePhi);
+ LLVM_DEBUG(dbgs() << "INDVARS: Widen lcssa phi " << *UsePhi << " to "
+ << *WidePhi << "\n");
+ }
+ return nullptr;
+ }
+ }
+
+ // This narrow use can be widened by a sext if it's non-negative or its narrow
+ // def was widended by a sext. Same for zext.
+ auto canWidenBySExt = [&]() {
+ return DU.NeverNegative || getExtendKind(DU.NarrowDef) == SignExtended;
+ };
+ auto canWidenByZExt = [&]() {
+ return DU.NeverNegative || getExtendKind(DU.NarrowDef) == ZeroExtended;
+ };
+
+ // Our raison d'etre! Eliminate sign and zero extension.
+ if ((isa<SExtInst>(DU.NarrowUse) && canWidenBySExt()) ||
+ (isa<ZExtInst>(DU.NarrowUse) && canWidenByZExt())) {
+ Value *NewDef = DU.WideDef;
+ if (DU.NarrowUse->getType() != WideType) {
+ unsigned CastWidth = SE->getTypeSizeInBits(DU.NarrowUse->getType());
+ unsigned IVWidth = SE->getTypeSizeInBits(WideType);
+ if (CastWidth < IVWidth) {
+ // The cast isn't as wide as the IV, so insert a Trunc.
+ IRBuilder<> Builder(DU.NarrowUse);
+ NewDef = Builder.CreateTrunc(DU.WideDef, DU.NarrowUse->getType());
+ }
+ else {
+ // A wider extend was hidden behind a narrower one. This may induce
+ // another round of IV widening in which the intermediate IV becomes
+ // dead. It should be very rare.
+ LLVM_DEBUG(dbgs() << "INDVARS: New IV " << *WidePhi
+ << " not wide enough to subsume " << *DU.NarrowUse
+ << "\n");
+ DU.NarrowUse->replaceUsesOfWith(DU.NarrowDef, DU.WideDef);
+ NewDef = DU.NarrowUse;
+ }
+ }
+ if (NewDef != DU.NarrowUse) {
+ LLVM_DEBUG(dbgs() << "INDVARS: eliminating " << *DU.NarrowUse
+ << " replaced by " << *DU.WideDef << "\n");
+ ++NumElimExt;
+ DU.NarrowUse->replaceAllUsesWith(NewDef);
+ DeadInsts.emplace_back(DU.NarrowUse);
+ }
+ // Now that the extend is gone, we want to expose it's uses for potential
+ // further simplification. We don't need to directly inform SimplifyIVUsers
+ // of the new users, because their parent IV will be processed later as a
+ // new loop phi. If we preserved IVUsers analysis, we would also want to
+ // push the uses of WideDef here.
+
+ // No further widening is needed. The deceased [sz]ext had done it for us.
+ return nullptr;
+ }
+
+ // Does this user itself evaluate to a recurrence after widening?
+ WidenedRecTy WideAddRec = getExtendedOperandRecurrence(DU);
+ if (!WideAddRec.first)
+ WideAddRec = getWideRecurrence(DU);
+
+ assert((WideAddRec.first == nullptr) == (WideAddRec.second == Unknown));
+ if (!WideAddRec.first) {
+ // If use is a loop condition, try to promote the condition instead of
+ // truncating the IV first.
+ if (widenLoopCompare(DU))
+ return nullptr;
+
+ // We are here about to generate a truncate instruction that may hurt
+ // performance because the scalar evolution expression computed earlier
+ // in WideAddRec.first does not indicate a polynomial induction expression.
+ // In that case, look at the operands of the use instruction to determine
+ // if we can still widen the use instead of truncating its operand.
+ if (widenWithVariantUse(DU))
+ return nullptr;
+
+ // This user does not evaluate to a recurrence after widening, so don't
+ // follow it. Instead insert a Trunc to kill off the original use,
+ // eventually isolating the original narrow IV so it can be removed.
+ truncateIVUse(DU, DT, LI);
+ return nullptr;
+ }
+ // Assume block terminators cannot evaluate to a recurrence. We can't to
+ // insert a Trunc after a terminator if there happens to be a critical edge.
+ assert(DU.NarrowUse != DU.NarrowUse->getParent()->getTerminator() &&
+ "SCEV is not expected to evaluate a block terminator");
+
+ // Reuse the IV increment that SCEVExpander created as long as it dominates
+ // NarrowUse.
+ Instruction *WideUse = nullptr;
+ if (WideAddRec.first == WideIncExpr &&
+ Rewriter.hoistIVInc(WideInc, DU.NarrowUse))
+ WideUse = WideInc;
+ else {
+ WideUse = cloneIVUser(DU, WideAddRec.first);
+ if (!WideUse)
+ return nullptr;
+ }
+ // Evaluation of WideAddRec ensured that the narrow expression could be
+ // extended outside the loop without overflow. This suggests that the wide use
+ // evaluates to the same expression as the extended narrow use, but doesn't
+ // absolutely guarantee it. Hence the following failsafe check. In rare cases
+ // where it fails, we simply throw away the newly created wide use.
+ if (WideAddRec.first != SE->getSCEV(WideUse)) {
+ LLVM_DEBUG(dbgs() << "Wide use expression mismatch: " << *WideUse << ": "
+ << *SE->getSCEV(WideUse) << " != " << *WideAddRec.first
+ << "\n");
+ DeadInsts.emplace_back(WideUse);
+ return nullptr;
+ }
+
+ // if we reached this point then we are going to replace
+ // DU.NarrowUse with WideUse. Reattach DbgValue then.
+ replaceAllDbgUsesWith(*DU.NarrowUse, *WideUse, *WideUse, *DT);
+
+ ExtendKindMap[DU.NarrowUse] = WideAddRec.second;
+ // Returning WideUse pushes it on the worklist.
+ return WideUse;
+}
+
+/// Add eligible users of NarrowDef to NarrowIVUsers.
+void WidenIV::pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef) {
+ const SCEV *NarrowSCEV = SE->getSCEV(NarrowDef);
+ bool NonNegativeDef =
+ SE->isKnownPredicate(ICmpInst::ICMP_SGE, NarrowSCEV,
+ SE->getZero(NarrowSCEV->getType()));
+ for (User *U : NarrowDef->users()) {
+ Instruction *NarrowUser = cast<Instruction>(U);
+
+ // Handle data flow merges and bizarre phi cycles.
+ if (!Widened.insert(NarrowUser).second)
+ continue;
+
+ bool NonNegativeUse = false;
+ if (!NonNegativeDef) {
+ // We might have a control-dependent range information for this context.
+ if (auto RangeInfo = getPostIncRangeInfo(NarrowDef, NarrowUser))
+ NonNegativeUse = RangeInfo->getSignedMin().isNonNegative();
+ }
+
+ NarrowIVUsers.emplace_back(NarrowDef, NarrowUser, WideDef,
+ NonNegativeDef || NonNegativeUse);
+ }
+}
+
+/// Process a single induction variable. First use the SCEVExpander to create a
+/// wide induction variable that evaluates to the same recurrence as the
+/// original narrow IV. Then use a worklist to forward traverse the narrow IV's
+/// def-use chain. After widenIVUse has processed all interesting IV users, the
+/// narrow IV will be isolated for removal by DeleteDeadPHIs.
+///
+/// It would be simpler to delete uses as they are processed, but we must avoid
+/// invalidating SCEV expressions.
+PHINode *WidenIV::createWideIV(SCEVExpander &Rewriter) {
+ // Is this phi an induction variable?
+ const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(SE->getSCEV(OrigPhi));
+ if (!AddRec)
+ return nullptr;
+
+ // Widen the induction variable expression.
+ const SCEV *WideIVExpr = getExtendKind(OrigPhi) == SignExtended
+ ? SE->getSignExtendExpr(AddRec, WideType)
+ : SE->getZeroExtendExpr(AddRec, WideType);
+
+ assert(SE->getEffectiveSCEVType(WideIVExpr->getType()) == WideType &&
+ "Expect the new IV expression to preserve its type");
+
+ // Can the IV be extended outside the loop without overflow?
+ AddRec = dyn_cast<SCEVAddRecExpr>(WideIVExpr);
+ if (!AddRec || AddRec->getLoop() != L)
+ return nullptr;
+
+ // An AddRec must have loop-invariant operands. Since this AddRec is
+ // materialized by a loop header phi, the expression cannot have any post-loop
+ // operands, so they must dominate the loop header.
+ assert(
+ SE->properlyDominates(AddRec->getStart(), L->getHeader()) &&
+ SE->properlyDominates(AddRec->getStepRecurrence(*SE), L->getHeader()) &&
+ "Loop header phi recurrence inputs do not dominate the loop");
+
+ // Iterate over IV uses (including transitive ones) looking for IV increments
+ // of the form 'add nsw %iv, <const>'. For each increment and each use of
+ // the increment calculate control-dependent range information basing on
+ // dominating conditions inside of the loop (e.g. a range check inside of the
+ // loop). Calculated ranges are stored in PostIncRangeInfos map.
+ //
+ // Control-dependent range information is later used to prove that a narrow
+ // definition is not negative (see pushNarrowIVUsers). It's difficult to do
+ // this on demand because when pushNarrowIVUsers needs this information some
+ // of the dominating conditions might be already widened.
+ if (UsePostIncrementRanges)
+ calculatePostIncRanges(OrigPhi);
+
+ // The rewriter provides a value for the desired IV expression. This may
+ // either find an existing phi or materialize a new one. Either way, we
+ // expect a well-formed cyclic phi-with-increments. i.e. any operand not part
+ // of the phi-SCC dominates the loop entry.
+ Instruction *InsertPt = &*L->getHeader()->getFirstInsertionPt();
+ Value *ExpandInst = Rewriter.expandCodeFor(AddRec, WideType, InsertPt);
+ // If the wide phi is not a phi node, for example a cast node, like bitcast,
+ // inttoptr, ptrtoint, just skip for now.
+ if (!(WidePhi = dyn_cast<PHINode>(ExpandInst))) {
+ // if the cast node is an inserted instruction without any user, we should
+ // remove it to make sure the pass don't touch the function as we can not
+ // wide the phi.
+ if (ExpandInst->hasNUses(0) &&
+ Rewriter.isInsertedInstruction(cast<Instruction>(ExpandInst)))
+ DeadInsts.emplace_back(ExpandInst);
+ return nullptr;
+ }
+
+ // Remembering the WideIV increment generated by SCEVExpander allows
+ // widenIVUse to reuse it when widening the narrow IV's increment. We don't
+ // employ a general reuse mechanism because the call above is the only call to
+ // SCEVExpander. Henceforth, we produce 1-to-1 narrow to wide uses.
+ if (BasicBlock *LatchBlock = L->getLoopLatch()) {
+ WideInc =
+ cast<Instruction>(WidePhi->getIncomingValueForBlock(LatchBlock));
+ WideIncExpr = SE->getSCEV(WideInc);
+ // Propagate the debug location associated with the original loop increment
+ // to the new (widened) increment.
+ auto *OrigInc =
+ cast<Instruction>(OrigPhi->getIncomingValueForBlock(LatchBlock));
+ WideInc->setDebugLoc(OrigInc->getDebugLoc());
+ }
+
+ LLVM_DEBUG(dbgs() << "Wide IV: " << *WidePhi << "\n");
+ ++NumWidened;
+
+ // Traverse the def-use chain using a worklist starting at the original IV.
+ assert(Widened.empty() && NarrowIVUsers.empty() && "expect initial state" );
+
+ Widened.insert(OrigPhi);
+ pushNarrowIVUsers(OrigPhi, WidePhi);
+
+ while (!NarrowIVUsers.empty()) {
+ WidenIV::NarrowIVDefUse DU = NarrowIVUsers.pop_back_val();
+
+ // Process a def-use edge. This may replace the use, so don't hold a
+ // use_iterator across it.
+ Instruction *WideUse = widenIVUse(DU, Rewriter);
+
+ // Follow all def-use edges from the previous narrow use.
+ if (WideUse)
+ pushNarrowIVUsers(DU.NarrowUse, WideUse);
+
+ // widenIVUse may have removed the def-use edge.
+ if (DU.NarrowDef->use_empty())
+ DeadInsts.emplace_back(DU.NarrowDef);
+ }
+
+ // Attach any debug information to the new PHI.
+ replaceAllDbgUsesWith(*OrigPhi, *WidePhi, *WidePhi, *DT);
+
+ return WidePhi;
+}
+
+/// Calculates control-dependent range for the given def at the given context
+/// by looking at dominating conditions inside of the loop
+void WidenIV::calculatePostIncRange(Instruction *NarrowDef,
+ Instruction *NarrowUser) {
+ using namespace llvm::PatternMatch;
+
+ Value *NarrowDefLHS;
+ const APInt *NarrowDefRHS;
+ if (!match(NarrowDef, m_NSWAdd(m_Value(NarrowDefLHS),
+ m_APInt(NarrowDefRHS))) ||
+ !NarrowDefRHS->isNonNegative())
+ return;
+
+ auto UpdateRangeFromCondition = [&] (Value *Condition,
+ bool TrueDest) {
+ CmpInst::Predicate Pred;
+ Value *CmpRHS;
+ if (!match(Condition, m_ICmp(Pred, m_Specific(NarrowDefLHS),
+ m_Value(CmpRHS))))
+ return;
+
+ CmpInst::Predicate P =
+ TrueDest ? Pred : CmpInst::getInversePredicate(Pred);
+
+ auto CmpRHSRange = SE->getSignedRange(SE->getSCEV(CmpRHS));
+ auto CmpConstrainedLHSRange =
+ ConstantRange::makeAllowedICmpRegion(P, CmpRHSRange);
+ auto NarrowDefRange = CmpConstrainedLHSRange.addWithNoWrap(
+ *NarrowDefRHS, OverflowingBinaryOperator::NoSignedWrap);
+
+ updatePostIncRangeInfo(NarrowDef, NarrowUser, NarrowDefRange);
+ };
+
+ auto UpdateRangeFromGuards = [&](Instruction *Ctx) {
+ if (!HasGuards)
+ return;
+
+ for (Instruction &I : make_range(Ctx->getIterator().getReverse(),
+ Ctx->getParent()->rend())) {
+ Value *C = nullptr;
+ if (match(&I, m_Intrinsic<Intrinsic::experimental_guard>(m_Value(C))))
+ UpdateRangeFromCondition(C, /*TrueDest=*/true);
+ }
+ };
+
+ UpdateRangeFromGuards(NarrowUser);
+
+ BasicBlock *NarrowUserBB = NarrowUser->getParent();
+ // If NarrowUserBB is statically unreachable asking dominator queries may
+ // yield surprising results. (e.g. the block may not have a dom tree node)
+ if (!DT->isReachableFromEntry(NarrowUserBB))
+ return;
+
+ for (auto *DTB = (*DT)[NarrowUserBB]->getIDom();
+ L->contains(DTB->getBlock());
+ DTB = DTB->getIDom()) {
+ auto *BB = DTB->getBlock();
+ auto *TI = BB->getTerminator();
+ UpdateRangeFromGuards(TI);
+
+ auto *BI = dyn_cast<BranchInst>(TI);
+ if (!BI || !BI->isConditional())
+ continue;
+
+ auto *TrueSuccessor = BI->getSuccessor(0);
+ auto *FalseSuccessor = BI->getSuccessor(1);
+
+ auto DominatesNarrowUser = [this, NarrowUser] (BasicBlockEdge BBE) {
+ return BBE.isSingleEdge() &&
+ DT->dominates(BBE, NarrowUser->getParent());
+ };
+
+ if (DominatesNarrowUser(BasicBlockEdge(BB, TrueSuccessor)))
+ UpdateRangeFromCondition(BI->getCondition(), /*TrueDest=*/true);
+
+ if (DominatesNarrowUser(BasicBlockEdge(BB, FalseSuccessor)))
+ UpdateRangeFromCondition(BI->getCondition(), /*TrueDest=*/false);
+ }
+}
+
+/// Calculates PostIncRangeInfos map for the given IV
+void WidenIV::calculatePostIncRanges(PHINode *OrigPhi) {
+ SmallPtrSet<Instruction *, 16> Visited;
+ SmallVector<Instruction *, 6> Worklist;
+ Worklist.push_back(OrigPhi);
+ Visited.insert(OrigPhi);
+
+ while (!Worklist.empty()) {
+ Instruction *NarrowDef = Worklist.pop_back_val();
+
+ for (Use &U : NarrowDef->uses()) {
+ auto *NarrowUser = cast<Instruction>(U.getUser());
+
+ // Don't go looking outside the current loop.
+ auto *NarrowUserLoop = (*LI)[NarrowUser->getParent()];
+ if (!NarrowUserLoop || !L->contains(NarrowUserLoop))
+ continue;
+
+ if (!Visited.insert(NarrowUser).second)
+ continue;
+
+ Worklist.push_back(NarrowUser);
+
+ calculatePostIncRange(NarrowDef, NarrowUser);
+ }
+ }
+}
+
+PHINode *llvm::createWideIV(const WideIVInfo &WI,
+ LoopInfo *LI, ScalarEvolution *SE, SCEVExpander &Rewriter,
+ DominatorTree *DT, SmallVectorImpl<WeakTrackingVH> &DeadInsts,
+ unsigned &NumElimExt, unsigned &NumWidened,
+ bool HasGuards, bool UsePostIncrementRanges) {
+ WidenIV Widener(WI, LI, SE, DT, DeadInsts, HasGuards, UsePostIncrementRanges);
+ PHINode *WidePHI = Widener.createWideIV(Rewriter);
+ NumElimExt = Widener.getNumElimExt();
+ NumWidened = Widener.getNumWidened();
+ return WidePHI;
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/SimplifyLibCalls.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 7217405b70..f9a9dd237b 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -541,8 +541,8 @@ Value *LibCallSimplifier::optimizeStrCpy(CallInst *CI, IRBuilderBase &B) {
B.CreateMemCpy(Dst, Align(1), Src, Align(1),
ConstantInt::get(DL.getIntPtrType(CI->getContext()), Len));
NewCI->setAttributes(CI->getAttributes());
- NewCI->removeAttributes(AttributeList::ReturnIndex,
- AttributeFuncs::typeIncompatible(NewCI->getType()));
+ NewCI->removeAttributes(AttributeList::ReturnIndex,
+ AttributeFuncs::typeIncompatible(NewCI->getType()));
return Dst;
}
@@ -570,8 +570,8 @@ Value *LibCallSimplifier::optimizeStpCpy(CallInst *CI, IRBuilderBase &B) {
// copy for us. Make a memcpy to copy the nul byte with align = 1.
CallInst *NewCI = B.CreateMemCpy(Dst, Align(1), Src, Align(1), LenV);
NewCI->setAttributes(CI->getAttributes());
- NewCI->removeAttributes(AttributeList::ReturnIndex,
- AttributeFuncs::typeIncompatible(NewCI->getType()));
+ NewCI->removeAttributes(AttributeList::ReturnIndex,
+ AttributeFuncs::typeIncompatible(NewCI->getType()));
return DstEnd;
}
@@ -612,27 +612,27 @@ Value *LibCallSimplifier::optimizeStrNCpy(CallInst *CI, IRBuilderBase &B) {
return Dst;
}
- // strncpy(a, "a", 4) - > memcpy(a, "a\0\0\0", 4)
- if (Len > SrcLen + 1) {
- if (Len <= 128) {
- StringRef Str;
- if (!getConstantStringInfo(Src, Str))
- return nullptr;
- std::string SrcStr = Str.str();
- SrcStr.resize(Len, '\0');
- Src = B.CreateGlobalString(SrcStr, "str");
- } else {
- return nullptr;
- }
- }
+ // strncpy(a, "a", 4) - > memcpy(a, "a\0\0\0", 4)
+ if (Len > SrcLen + 1) {
+ if (Len <= 128) {
+ StringRef Str;
+ if (!getConstantStringInfo(Src, Str))
+ return nullptr;
+ std::string SrcStr = Str.str();
+ SrcStr.resize(Len, '\0');
+ Src = B.CreateGlobalString(SrcStr, "str");
+ } else {
+ return nullptr;
+ }
+ }
Type *PT = Callee->getFunctionType()->getParamType(0);
// strncpy(x, s, c) -> memcpy(align 1 x, align 1 s, c) [s and c are constant]
CallInst *NewCI = B.CreateMemCpy(Dst, Align(1), Src, Align(1),
ConstantInt::get(DL.getIntPtrType(PT), Len));
NewCI->setAttributes(CI->getAttributes());
- NewCI->removeAttributes(AttributeList::ReturnIndex,
- AttributeFuncs::typeIncompatible(NewCI->getType()));
+ NewCI->removeAttributes(AttributeList::ReturnIndex,
+ AttributeFuncs::typeIncompatible(NewCI->getType()));
return Dst;
}
@@ -1108,8 +1108,8 @@ Value *LibCallSimplifier::optimizeMemCpy(CallInst *CI, IRBuilderBase &B) {
CallInst *NewCI = B.CreateMemCpy(CI->getArgOperand(0), Align(1),
CI->getArgOperand(1), Align(1), Size);
NewCI->setAttributes(CI->getAttributes());
- NewCI->removeAttributes(AttributeList::ReturnIndex,
- AttributeFuncs::typeIncompatible(NewCI->getType()));
+ NewCI->removeAttributes(AttributeList::ReturnIndex,
+ AttributeFuncs::typeIncompatible(NewCI->getType()));
return CI->getArgOperand(0);
}
@@ -1158,12 +1158,12 @@ Value *LibCallSimplifier::optimizeMemPCpy(CallInst *CI, IRBuilderBase &B) {
// mempcpy(x, y, n) -> llvm.memcpy(align 1 x, align 1 y, n), x + n
CallInst *NewCI =
B.CreateMemCpy(Dst, Align(1), CI->getArgOperand(1), Align(1), N);
- // Propagate attributes, but memcpy has no return value, so make sure that
- // any return attributes are compliant.
- // TODO: Attach return value attributes to the 1st operand to preserve them?
+ // Propagate attributes, but memcpy has no return value, so make sure that
+ // any return attributes are compliant.
+ // TODO: Attach return value attributes to the 1st operand to preserve them?
NewCI->setAttributes(CI->getAttributes());
- NewCI->removeAttributes(AttributeList::ReturnIndex,
- AttributeFuncs::typeIncompatible(NewCI->getType()));
+ NewCI->removeAttributes(AttributeList::ReturnIndex,
+ AttributeFuncs::typeIncompatible(NewCI->getType()));
return B.CreateInBoundsGEP(B.getInt8Ty(), Dst, N);
}
@@ -1177,8 +1177,8 @@ Value *LibCallSimplifier::optimizeMemMove(CallInst *CI, IRBuilderBase &B) {
CallInst *NewCI = B.CreateMemMove(CI->getArgOperand(0), Align(1),
CI->getArgOperand(1), Align(1), Size);
NewCI->setAttributes(CI->getAttributes());
- NewCI->removeAttributes(AttributeList::ReturnIndex,
- AttributeFuncs::typeIncompatible(NewCI->getType()));
+ NewCI->removeAttributes(AttributeList::ReturnIndex,
+ AttributeFuncs::typeIncompatible(NewCI->getType()));
return CI->getArgOperand(0);
}
@@ -1239,8 +1239,8 @@ Value *LibCallSimplifier::optimizeMemSet(CallInst *CI, IRBuilderBase &B) {
Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false);
CallInst *NewCI = B.CreateMemSet(CI->getArgOperand(0), Val, Size, Align(1));
NewCI->setAttributes(CI->getAttributes());
- NewCI->removeAttributes(AttributeList::ReturnIndex,
- AttributeFuncs::typeIncompatible(NewCI->getType()));
+ NewCI->removeAttributes(AttributeList::ReturnIndex,
+ AttributeFuncs::typeIncompatible(NewCI->getType()));
return CI->getArgOperand(0);
}
@@ -1653,14 +1653,14 @@ Value *LibCallSimplifier::replacePowWithSqrt(CallInst *Pow, IRBuilderBase &B) {
if (ExpoF->isNegative() && (!Pow->hasApproxFunc() && !Pow->hasAllowReassoc()))
return nullptr;
- // If we have a pow() library call (accesses memory) and we can't guarantee
- // that the base is not an infinity, give up:
- // pow(-Inf, 0.5) is optionally required to have a result of +Inf (not setting
- // errno), but sqrt(-Inf) is required by various standards to set errno.
- if (!Pow->doesNotAccessMemory() && !Pow->hasNoInfs() &&
- !isKnownNeverInfinity(Base, TLI))
- return nullptr;
-
+ // If we have a pow() library call (accesses memory) and we can't guarantee
+ // that the base is not an infinity, give up:
+ // pow(-Inf, 0.5) is optionally required to have a result of +Inf (not setting
+ // errno), but sqrt(-Inf) is required by various standards to set errno.
+ if (!Pow->doesNotAccessMemory() && !Pow->hasNoInfs() &&
+ !isKnownNeverInfinity(Base, TLI))
+ return nullptr;
+
Sqrt = getSqrtCall(Base, Attrs, Pow->doesNotAccessMemory(), Mod, B, TLI);
if (!Sqrt)
return nullptr;
@@ -1747,8 +1747,8 @@ Value *LibCallSimplifier::optimizePow(CallInst *Pow, IRBuilderBase &B) {
// pow(x, n) -> x * x * x * ...
const APFloat *ExpoF;
- if (AllowApprox && match(Expo, m_APFloat(ExpoF)) &&
- !ExpoF->isExactlyValue(0.5) && !ExpoF->isExactlyValue(-0.5)) {
+ if (AllowApprox && match(Expo, m_APFloat(ExpoF)) &&
+ !ExpoF->isExactlyValue(0.5) && !ExpoF->isExactlyValue(-0.5)) {
// We limit to a max of 7 multiplications, thus the maximum exponent is 32.
// If the exponent is an integer+0.5 we generate a call to sqrt and an
// additional fmul.
@@ -1774,8 +1774,8 @@ Value *LibCallSimplifier::optimizePow(CallInst *Pow, IRBuilderBase &B) {
Sqrt = getSqrtCall(Base, Pow->getCalledFunction()->getAttributes(),
Pow->doesNotAccessMemory(), M, B, TLI);
- if (!Sqrt)
- return nullptr;
+ if (!Sqrt)
+ return nullptr;
}
// We will memoize intermediate products of the Addition Chain.
@@ -2199,7 +2199,7 @@ Value *LibCallSimplifier::optimizeSinCosPi(CallInst *CI, IRBuilderBase &B) {
classifyArgUse(U, F, IsFloat, SinCalls, CosCalls, SinCosCalls);
// It's only worthwhile if both sinpi and cospi are actually used.
- if (SinCalls.empty() || CosCalls.empty())
+ if (SinCalls.empty() || CosCalls.empty())
return nullptr;
Value *Sin, *Cos, *SinCos;
@@ -2225,7 +2225,7 @@ void LibCallSimplifier::classifyArgUse(
SmallVectorImpl<CallInst *> &SinCosCalls) {
CallInst *CI = dyn_cast<CallInst>(Val);
- if (!CI || CI->use_empty())
+ if (!CI || CI->use_empty())
return;
// Don't consider calls in other functions.
@@ -2522,30 +2522,30 @@ Value *LibCallSimplifier::optimizeSPrintFString(CallInst *CI,
if (!CI->getArgOperand(2)->getType()->isPointerTy())
return nullptr;
- if (CI->use_empty())
- // sprintf(dest, "%s", str) -> strcpy(dest, str)
- return emitStrCpy(CI->getArgOperand(0), CI->getArgOperand(2), B, TLI);
-
- uint64_t SrcLen = GetStringLength(CI->getArgOperand(2));
- if (SrcLen) {
- B.CreateMemCpy(
- CI->getArgOperand(0), Align(1), CI->getArgOperand(2), Align(1),
- ConstantInt::get(DL.getIntPtrType(CI->getContext()), SrcLen));
- // Returns total number of characters written without null-character.
- return ConstantInt::get(CI->getType(), SrcLen - 1);
- } else if (Value *V = emitStpCpy(CI->getArgOperand(0), CI->getArgOperand(2),
- B, TLI)) {
- // sprintf(dest, "%s", str) -> stpcpy(dest, str) - dest
- Value *PtrDiff = B.CreatePtrDiff(V, CI->getArgOperand(0));
- return B.CreateIntCast(PtrDiff, CI->getType(), false);
- }
-
- bool OptForSize = CI->getFunction()->hasOptSize() ||
- llvm::shouldOptimizeForSize(CI->getParent(), PSI, BFI,
- PGSOQueryType::IRPass);
- if (OptForSize)
- return nullptr;
-
+ if (CI->use_empty())
+ // sprintf(dest, "%s", str) -> strcpy(dest, str)
+ return emitStrCpy(CI->getArgOperand(0), CI->getArgOperand(2), B, TLI);
+
+ uint64_t SrcLen = GetStringLength(CI->getArgOperand(2));
+ if (SrcLen) {
+ B.CreateMemCpy(
+ CI->getArgOperand(0), Align(1), CI->getArgOperand(2), Align(1),
+ ConstantInt::get(DL.getIntPtrType(CI->getContext()), SrcLen));
+ // Returns total number of characters written without null-character.
+ return ConstantInt::get(CI->getType(), SrcLen - 1);
+ } else if (Value *V = emitStpCpy(CI->getArgOperand(0), CI->getArgOperand(2),
+ B, TLI)) {
+ // sprintf(dest, "%s", str) -> stpcpy(dest, str) - dest
+ Value *PtrDiff = B.CreatePtrDiff(V, CI->getArgOperand(0));
+ return B.CreateIntCast(PtrDiff, CI->getType(), false);
+ }
+
+ bool OptForSize = CI->getFunction()->hasOptSize() ||
+ llvm::shouldOptimizeForSize(CI->getParent(), PSI, BFI,
+ PGSOQueryType::IRPass);
+ if (OptForSize)
+ return nullptr;
+
Value *Len = emitStrLen(CI->getArgOperand(2), B, DL, TLI);
if (!Len)
return nullptr;
@@ -3278,8 +3278,8 @@ Value *FortifiedLibCallSimplifier::optimizeMemCpyChk(CallInst *CI,
B.CreateMemCpy(CI->getArgOperand(0), Align(1), CI->getArgOperand(1),
Align(1), CI->getArgOperand(2));
NewCI->setAttributes(CI->getAttributes());
- NewCI->removeAttributes(AttributeList::ReturnIndex,
- AttributeFuncs::typeIncompatible(NewCI->getType()));
+ NewCI->removeAttributes(AttributeList::ReturnIndex,
+ AttributeFuncs::typeIncompatible(NewCI->getType()));
return CI->getArgOperand(0);
}
return nullptr;
@@ -3292,8 +3292,8 @@ Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(CallInst *CI,
B.CreateMemMove(CI->getArgOperand(0), Align(1), CI->getArgOperand(1),
Align(1), CI->getArgOperand(2));
NewCI->setAttributes(CI->getAttributes());
- NewCI->removeAttributes(AttributeList::ReturnIndex,
- AttributeFuncs::typeIncompatible(NewCI->getType()));
+ NewCI->removeAttributes(AttributeList::ReturnIndex,
+ AttributeFuncs::typeIncompatible(NewCI->getType()));
return CI->getArgOperand(0);
}
return nullptr;
@@ -3308,29 +3308,29 @@ Value *FortifiedLibCallSimplifier::optimizeMemSetChk(CallInst *CI,
CallInst *NewCI = B.CreateMemSet(CI->getArgOperand(0), Val,
CI->getArgOperand(2), Align(1));
NewCI->setAttributes(CI->getAttributes());
- NewCI->removeAttributes(AttributeList::ReturnIndex,
- AttributeFuncs::typeIncompatible(NewCI->getType()));
+ NewCI->removeAttributes(AttributeList::ReturnIndex,
+ AttributeFuncs::typeIncompatible(NewCI->getType()));
return CI->getArgOperand(0);
}
return nullptr;
}
-Value *FortifiedLibCallSimplifier::optimizeMemPCpyChk(CallInst *CI,
- IRBuilderBase &B) {
- const DataLayout &DL = CI->getModule()->getDataLayout();
- if (isFortifiedCallFoldable(CI, 3, 2))
- if (Value *Call = emitMemPCpy(CI->getArgOperand(0), CI->getArgOperand(1),
- CI->getArgOperand(2), B, DL, TLI)) {
- CallInst *NewCI = cast<CallInst>(Call);
- NewCI->setAttributes(CI->getAttributes());
- NewCI->removeAttributes(
- AttributeList::ReturnIndex,
- AttributeFuncs::typeIncompatible(NewCI->getType()));
- return NewCI;
- }
- return nullptr;
-}
-
+Value *FortifiedLibCallSimplifier::optimizeMemPCpyChk(CallInst *CI,
+ IRBuilderBase &B) {
+ const DataLayout &DL = CI->getModule()->getDataLayout();
+ if (isFortifiedCallFoldable(CI, 3, 2))
+ if (Value *Call = emitMemPCpy(CI->getArgOperand(0), CI->getArgOperand(1),
+ CI->getArgOperand(2), B, DL, TLI)) {
+ CallInst *NewCI = cast<CallInst>(Call);
+ NewCI->setAttributes(CI->getAttributes());
+ NewCI->removeAttributes(
+ AttributeList::ReturnIndex,
+ AttributeFuncs::typeIncompatible(NewCI->getType()));
+ return NewCI;
+ }
+ return nullptr;
+}
+
Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(CallInst *CI,
IRBuilderBase &B,
LibFunc Func) {
@@ -3411,7 +3411,7 @@ Value *FortifiedLibCallSimplifier::optimizeMemCCpyChk(CallInst *CI,
Value *FortifiedLibCallSimplifier::optimizeSNPrintfChk(CallInst *CI,
IRBuilderBase &B) {
if (isFortifiedCallFoldable(CI, 3, 1, None, 2)) {
- SmallVector<Value *, 8> VariadicArgs(drop_begin(CI->args(), 5));
+ SmallVector<Value *, 8> VariadicArgs(drop_begin(CI->args(), 5));
return emitSNPrintf(CI->getArgOperand(0), CI->getArgOperand(1),
CI->getArgOperand(4), VariadicArgs, B, TLI);
}
@@ -3422,7 +3422,7 @@ Value *FortifiedLibCallSimplifier::optimizeSNPrintfChk(CallInst *CI,
Value *FortifiedLibCallSimplifier::optimizeSPrintfChk(CallInst *CI,
IRBuilderBase &B) {
if (isFortifiedCallFoldable(CI, 2, None, None, 1)) {
- SmallVector<Value *, 8> VariadicArgs(drop_begin(CI->args(), 4));
+ SmallVector<Value *, 8> VariadicArgs(drop_begin(CI->args(), 4));
return emitSPrintf(CI->getArgOperand(0), CI->getArgOperand(3), VariadicArgs,
B, TLI);
}
@@ -3520,8 +3520,8 @@ Value *FortifiedLibCallSimplifier::optimizeCall(CallInst *CI,
switch (Func) {
case LibFunc_memcpy_chk:
return optimizeMemCpyChk(CI, Builder);
- case LibFunc_mempcpy_chk:
- return optimizeMemPCpyChk(CI, Builder);
+ case LibFunc_mempcpy_chk:
+ return optimizeMemPCpyChk(CI, Builder);
case LibFunc_memmove_chk:
return optimizeMemMoveChk(CI, Builder);
case LibFunc_memset_chk:
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/StripGCRelocates.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/StripGCRelocates.cpp
index 8ee1612931..1fa574f04c 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/StripGCRelocates.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/StripGCRelocates.cpp
@@ -13,7 +13,7 @@
// present.
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/Utils/StripGCRelocates.h"
+#include "llvm/Transforms/Utils/StripGCRelocates.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"
@@ -25,7 +25,7 @@
using namespace llvm;
-static bool stripGCRelocates(Function &F) {
+static bool stripGCRelocates(Function &F) {
// Nothing to do for declarations.
if (F.isDeclaration())
return false;
@@ -57,32 +57,32 @@ static bool stripGCRelocates(Function &F) {
return !GCRelocates.empty();
}
-PreservedAnalyses StripGCRelocates::run(Function &F,
- FunctionAnalysisManager &AM) {
- if (!stripGCRelocates(F))
- return PreservedAnalyses::all();
-
- // Removing gc.relocate preserves the CFG, but most other analysis probably
- // need to re-run.
- PreservedAnalyses PA;
- PA.preserveSet<CFGAnalyses>();
- return PA;
-}
-
-namespace {
-struct StripGCRelocatesLegacy : public FunctionPass {
- static char ID; // Pass identification, replacement for typeid
- StripGCRelocatesLegacy() : FunctionPass(ID) {
- initializeStripGCRelocatesLegacyPass(*PassRegistry::getPassRegistry());
- }
-
- void getAnalysisUsage(AnalysisUsage &Info) const override {}
-
- bool runOnFunction(Function &F) override { return ::stripGCRelocates(F); }
-};
-char StripGCRelocatesLegacy::ID = 0;
-} // namespace
-
-INITIALIZE_PASS(StripGCRelocatesLegacy, "strip-gc-relocates",
+PreservedAnalyses StripGCRelocates::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ if (!stripGCRelocates(F))
+ return PreservedAnalyses::all();
+
+ // Removing gc.relocate preserves the CFG, but most other analysis probably
+ // need to re-run.
+ PreservedAnalyses PA;
+ PA.preserveSet<CFGAnalyses>();
+ return PA;
+}
+
+namespace {
+struct StripGCRelocatesLegacy : public FunctionPass {
+ static char ID; // Pass identification, replacement for typeid
+ StripGCRelocatesLegacy() : FunctionPass(ID) {
+ initializeStripGCRelocatesLegacyPass(*PassRegistry::getPassRegistry());
+ }
+
+ void getAnalysisUsage(AnalysisUsage &Info) const override {}
+
+ bool runOnFunction(Function &F) override { return ::stripGCRelocates(F); }
+};
+char StripGCRelocatesLegacy::ID = 0;
+} // namespace
+
+INITIALIZE_PASS(StripGCRelocatesLegacy, "strip-gc-relocates",
"Strip gc.relocates inserted through RewriteStatepointsForGC",
true, false)
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/StripNonLineTableDebugInfo.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/StripNonLineTableDebugInfo.cpp
index 5b88ffa97a..10fda4df51 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/StripNonLineTableDebugInfo.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/StripNonLineTableDebugInfo.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/Utils/StripNonLineTableDebugInfo.h"
+#include "llvm/Transforms/Utils/StripNonLineTableDebugInfo.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
@@ -18,11 +18,11 @@ namespace {
/// This pass strips all debug info that is not related line tables.
/// The result will be the same as if the program where compiled with
/// -gline-tables-only.
-struct StripNonLineTableDebugLegacyPass : public ModulePass {
+struct StripNonLineTableDebugLegacyPass : public ModulePass {
static char ID; // Pass identification, replacement for typeid
- StripNonLineTableDebugLegacyPass() : ModulePass(ID) {
- initializeStripNonLineTableDebugLegacyPassPass(
- *PassRegistry::getPassRegistry());
+ StripNonLineTableDebugLegacyPass() : ModulePass(ID) {
+ initializeStripNonLineTableDebugLegacyPassPass(
+ *PassRegistry::getPassRegistry());
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -35,17 +35,17 @@ struct StripNonLineTableDebugLegacyPass : public ModulePass {
};
}
-char StripNonLineTableDebugLegacyPass::ID = 0;
-INITIALIZE_PASS(StripNonLineTableDebugLegacyPass,
- "strip-nonlinetable-debuginfo",
+char StripNonLineTableDebugLegacyPass::ID = 0;
+INITIALIZE_PASS(StripNonLineTableDebugLegacyPass,
+ "strip-nonlinetable-debuginfo",
"Strip all debug info except linetables", false, false)
-ModulePass *llvm::createStripNonLineTableDebugLegacyPass() {
- return new StripNonLineTableDebugLegacyPass();
+ModulePass *llvm::createStripNonLineTableDebugLegacyPass() {
+ return new StripNonLineTableDebugLegacyPass();
+}
+
+PreservedAnalyses
+StripNonLineTableDebugInfoPass::run(Module &M, ModuleAnalysisManager &AM) {
+ llvm::stripNonLineTableDebugInfo(M);
+ return PreservedAnalyses::all();
}
-
-PreservedAnalyses
-StripNonLineTableDebugInfoPass::run(Module &M, ModuleAnalysisManager &AM) {
- llvm::stripNonLineTableDebugInfo(M);
- return PreservedAnalyses::all();
-}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp
index 70187f6fce..3631733713 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
//
-// This pass is used to ensure that functions have at most one return and one
-// unreachable instruction in them.
+// This pass is used to ensure that functions have at most one return and one
+// unreachable instruction in them.
//
//===----------------------------------------------------------------------===//
@@ -20,66 +20,66 @@
#include "llvm/Transforms/Utils.h"
using namespace llvm;
-char UnifyFunctionExitNodesLegacyPass::ID = 0;
+char UnifyFunctionExitNodesLegacyPass::ID = 0;
-UnifyFunctionExitNodesLegacyPass::UnifyFunctionExitNodesLegacyPass()
- : FunctionPass(ID) {
- initializeUnifyFunctionExitNodesLegacyPassPass(
- *PassRegistry::getPassRegistry());
+UnifyFunctionExitNodesLegacyPass::UnifyFunctionExitNodesLegacyPass()
+ : FunctionPass(ID) {
+ initializeUnifyFunctionExitNodesLegacyPassPass(
+ *PassRegistry::getPassRegistry());
}
-INITIALIZE_PASS(UnifyFunctionExitNodesLegacyPass, "mergereturn",
+INITIALIZE_PASS(UnifyFunctionExitNodesLegacyPass, "mergereturn",
"Unify function exit nodes", false, false)
Pass *llvm::createUnifyFunctionExitNodesPass() {
- return new UnifyFunctionExitNodesLegacyPass();
+ return new UnifyFunctionExitNodesLegacyPass();
}
-void UnifyFunctionExitNodesLegacyPass::getAnalysisUsage(
- AnalysisUsage &AU) const {
+void UnifyFunctionExitNodesLegacyPass::getAnalysisUsage(
+ AnalysisUsage &AU) const {
// We preserve the non-critical-edgeness property
AU.addPreservedID(BreakCriticalEdgesID);
// This is a cluster of orthogonal Transforms
AU.addPreservedID(LowerSwitchID);
}
-namespace {
-
-bool unifyUnreachableBlocks(Function &F) {
- std::vector<BasicBlock *> UnreachableBlocks;
-
+namespace {
+
+bool unifyUnreachableBlocks(Function &F) {
+ std::vector<BasicBlock *> UnreachableBlocks;
+
for (BasicBlock &I : F)
- if (isa<UnreachableInst>(I.getTerminator()))
+ if (isa<UnreachableInst>(I.getTerminator()))
UnreachableBlocks.push_back(&I);
- if (UnreachableBlocks.size() <= 1)
- return false;
+ if (UnreachableBlocks.size() <= 1)
+ return false;
+
+ BasicBlock *UnreachableBlock =
+ BasicBlock::Create(F.getContext(), "UnifiedUnreachableBlock", &F);
+ new UnreachableInst(F.getContext(), UnreachableBlock);
- BasicBlock *UnreachableBlock =
- BasicBlock::Create(F.getContext(), "UnifiedUnreachableBlock", &F);
- new UnreachableInst(F.getContext(), UnreachableBlock);
-
- for (BasicBlock *BB : UnreachableBlocks) {
- BB->getInstList().pop_back(); // Remove the unreachable inst.
- BranchInst::Create(UnreachableBlock, BB);
+ for (BasicBlock *BB : UnreachableBlocks) {
+ BB->getInstList().pop_back(); // Remove the unreachable inst.
+ BranchInst::Create(UnreachableBlock, BB);
}
- return true;
-}
-
-bool unifyReturnBlocks(Function &F) {
- std::vector<BasicBlock *> ReturningBlocks;
-
- for (BasicBlock &I : F)
- if (isa<ReturnInst>(I.getTerminator()))
- ReturningBlocks.push_back(&I);
-
- if (ReturningBlocks.size() <= 1)
+ return true;
+}
+
+bool unifyReturnBlocks(Function &F) {
+ std::vector<BasicBlock *> ReturningBlocks;
+
+ for (BasicBlock &I : F)
+ if (isa<ReturnInst>(I.getTerminator()))
+ ReturningBlocks.push_back(&I);
+
+ if (ReturningBlocks.size() <= 1)
return false;
- // Insert a new basic block into the function, add PHI nodes (if the function
- // returns values), and convert all of the return instructions into
- // unconditional branches.
+ // Insert a new basic block into the function, add PHI nodes (if the function
+ // returns values), and convert all of the return instructions into
+ // unconditional branches.
BasicBlock *NewRetBlock = BasicBlock::Create(F.getContext(),
"UnifiedReturnBlock", &F);
@@ -105,25 +105,25 @@ bool unifyReturnBlocks(Function &F) {
BB->getInstList().pop_back(); // Remove the return insn
BranchInst::Create(NewRetBlock, BB);
}
-
+
return true;
}
-} // namespace
-
-// Unify all exit nodes of the CFG by creating a new BasicBlock, and converting
-// all returns to unconditional branches to this new basic block. Also, unify
-// all unreachable blocks.
-bool UnifyFunctionExitNodesLegacyPass::runOnFunction(Function &F) {
- bool Changed = false;
- Changed |= unifyUnreachableBlocks(F);
- Changed |= unifyReturnBlocks(F);
- return Changed;
-}
-
-PreservedAnalyses UnifyFunctionExitNodesPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- bool Changed = false;
- Changed |= unifyUnreachableBlocks(F);
- Changed |= unifyReturnBlocks(F);
- return Changed ? PreservedAnalyses() : PreservedAnalyses::all();
-}
+} // namespace
+
+// Unify all exit nodes of the CFG by creating a new BasicBlock, and converting
+// all returns to unconditional branches to this new basic block. Also, unify
+// all unreachable blocks.
+bool UnifyFunctionExitNodesLegacyPass::runOnFunction(Function &F) {
+ bool Changed = false;
+ Changed |= unifyUnreachableBlocks(F);
+ Changed |= unifyReturnBlocks(F);
+ return Changed;
+}
+
+PreservedAnalyses UnifyFunctionExitNodesPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ bool Changed = false;
+ Changed |= unifyUnreachableBlocks(F);
+ Changed |= unifyReturnBlocks(F);
+ return Changed ? PreservedAnalyses() : PreservedAnalyses::all();
+}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/UnifyLoopExits.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/UnifyLoopExits.cpp
index 1bca6040af..0b718ed613 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/UnifyLoopExits.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/UnifyLoopExits.cpp
@@ -16,8 +16,8 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/Utils/UnifyLoopExits.h"
-#include "llvm/ADT/MapVector.h"
+#include "llvm/Transforms/Utils/UnifyLoopExits.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/InitializePasses.h"
@@ -29,10 +29,10 @@
using namespace llvm;
namespace {
-struct UnifyLoopExitsLegacyPass : public FunctionPass {
+struct UnifyLoopExitsLegacyPass : public FunctionPass {
static char ID;
- UnifyLoopExitsLegacyPass() : FunctionPass(ID) {
- initializeUnifyLoopExitsLegacyPassPass(*PassRegistry::getPassRegistry());
+ UnifyLoopExitsLegacyPass() : FunctionPass(ID) {
+ initializeUnifyLoopExitsLegacyPassPass(*PassRegistry::getPassRegistry());
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -48,19 +48,19 @@ struct UnifyLoopExitsLegacyPass : public FunctionPass {
};
} // namespace
-char UnifyLoopExitsLegacyPass::ID = 0;
+char UnifyLoopExitsLegacyPass::ID = 0;
-FunctionPass *llvm::createUnifyLoopExitsPass() {
- return new UnifyLoopExitsLegacyPass();
-}
+FunctionPass *llvm::createUnifyLoopExitsPass() {
+ return new UnifyLoopExitsLegacyPass();
+}
-INITIALIZE_PASS_BEGIN(UnifyLoopExitsLegacyPass, "unify-loop-exits",
+INITIALIZE_PASS_BEGIN(UnifyLoopExitsLegacyPass, "unify-loop-exits",
"Fixup each natural loop to have a single exit block",
false /* Only looks at CFG */, false /* Analysis Pass */)
-INITIALIZE_PASS_DEPENDENCY(LowerSwitchLegacyPass)
+INITIALIZE_PASS_DEPENDENCY(LowerSwitchLegacyPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
-INITIALIZE_PASS_END(UnifyLoopExitsLegacyPass, "unify-loop-exits",
+INITIALIZE_PASS_END(UnifyLoopExitsLegacyPass, "unify-loop-exits",
"Fixup each natural loop to have a single exit block",
false /* Only looks at CFG */, false /* Analysis Pass */)
@@ -84,7 +84,7 @@ static void restoreSSA(const DominatorTree &DT, const Loop *L,
const SetVector<BasicBlock *> &Incoming,
BasicBlock *LoopExitBlock) {
using InstVector = SmallVector<Instruction *, 8>;
- using IIMap = MapVector<Instruction *, InstVector>;
+ using IIMap = MapVector<Instruction *, InstVector>;
IIMap ExternalUsers;
for (auto BB : L->blocks()) {
for (auto &I : *BB) {
@@ -207,7 +207,7 @@ static bool unifyLoopExits(DominatorTree &DT, LoopInfo &LI, Loop *L) {
return true;
}
-static bool runImpl(LoopInfo &LI, DominatorTree &DT) {
+static bool runImpl(LoopInfo &LI, DominatorTree &DT) {
bool Changed = false;
auto Loops = LI.getLoopsInPreorder();
@@ -218,28 +218,28 @@ static bool runImpl(LoopInfo &LI, DominatorTree &DT) {
}
return Changed;
}
-
-bool UnifyLoopExitsLegacyPass::runOnFunction(Function &F) {
- LLVM_DEBUG(dbgs() << "===== Unifying loop exits in function " << F.getName()
- << "\n");
- auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
-
- return runImpl(LI, DT);
-}
-
-namespace llvm {
-
-PreservedAnalyses UnifyLoopExitsPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- auto &LI = AM.getResult<LoopAnalysis>(F);
- auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
-
- if (!runImpl(LI, DT))
- return PreservedAnalyses::all();
- PreservedAnalyses PA;
- PA.preserve<LoopAnalysis>();
- PA.preserve<DominatorTreeAnalysis>();
- return PA;
-}
-} // namespace llvm
+
+bool UnifyLoopExitsLegacyPass::runOnFunction(Function &F) {
+ LLVM_DEBUG(dbgs() << "===== Unifying loop exits in function " << F.getName()
+ << "\n");
+ auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
+ auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+
+ return runImpl(LI, DT);
+}
+
+namespace llvm {
+
+PreservedAnalyses UnifyLoopExitsPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ auto &LI = AM.getResult<LoopAnalysis>(F);
+ auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
+
+ if (!runImpl(LI, DT))
+ return PreservedAnalyses::all();
+ PreservedAnalyses PA;
+ PA.preserve<LoopAnalysis>();
+ PA.preserve<DominatorTreeAnalysis>();
+ return PA;
+}
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp
index fa87b7384d..c57cec6be6 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/UniqueInternalLinkageNames.cpp
@@ -13,11 +13,11 @@
#include "llvm/Transforms/Utils/UniqueInternalLinkageNames.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/MDBuilder.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/InitializePasses.h"
-#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MD5.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
@@ -30,31 +30,31 @@ static bool uniqueifyInternalLinkageNames(Module &M) {
Md5.final(R);
SmallString<32> Str;
llvm::MD5::stringifyResult(R, Str);
- // Convert MD5hash to Decimal. Demangler suffixes can either contain numbers
- // or characters but not both.
- APInt IntHash = APInt(128, Str.str(), 16);
- // Prepend "__uniq" before the hash for tools like profilers to understand that
- // this symbol is of internal linkage type.
- std::string ModuleNameHash = (Twine(".__uniq.") + Twine(IntHash.toString(10, false))).str();
+ // Convert MD5hash to Decimal. Demangler suffixes can either contain numbers
+ // or characters but not both.
+ APInt IntHash = APInt(128, Str.str(), 16);
+ // Prepend "__uniq" before the hash for tools like profilers to understand that
+ // this symbol is of internal linkage type.
+ std::string ModuleNameHash = (Twine(".__uniq.") + Twine(IntHash.toString(10, false))).str();
bool Changed = false;
- MDBuilder MDB(M.getContext());
+ MDBuilder MDB(M.getContext());
// Append the module hash to all internal linkage functions.
for (auto &F : M) {
if (F.hasInternalLinkage()) {
F.setName(F.getName() + ModuleNameHash);
- F.addFnAttr("sample-profile-suffix-elision-policy", "selected");
- // Replace linkage names in the debug metadata.
- if (DISubprogram *SP = F.getSubprogram()) {
- if (SP->getRawLinkageName()) {
- auto *Name = MDB.createString(F.getName());
- SP->replaceRawLinkageName(Name);
- if (DISubprogram *SPDecl = SP->getDeclaration()) {
- if (SPDecl->getRawLinkageName())
- SPDecl->replaceRawLinkageName(Name);
- }
- }
- }
+ F.addFnAttr("sample-profile-suffix-elision-policy", "selected");
+ // Replace linkage names in the debug metadata.
+ if (DISubprogram *SP = F.getSubprogram()) {
+ if (SP->getRawLinkageName()) {
+ auto *Name = MDB.createString(F.getName());
+ SP->replaceRawLinkageName(Name);
+ if (DISubprogram *SPDecl = SP->getDeclaration()) {
+ if (SPDecl->getRawLinkageName())
+ SPDecl->replaceRawLinkageName(Name);
+ }
+ }
+ }
Changed = true;
}
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/Utils.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/Utils.cpp
index 6137c3092b..73c0532f3f 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/Utils.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/Utils.cpp
@@ -34,17 +34,17 @@ void llvm::initializeTransformUtils(PassRegistry &Registry) {
initializeLibCallsShrinkWrapLegacyPassPass(Registry);
initializeLoopSimplifyPass(Registry);
initializeLowerInvokeLegacyPassPass(Registry);
- initializeLowerSwitchLegacyPassPass(Registry);
+ initializeLowerSwitchLegacyPassPass(Registry);
initializeNameAnonGlobalLegacyPassPass(Registry);
initializePromoteLegacyPassPass(Registry);
- initializeStripNonLineTableDebugLegacyPassPass(Registry);
- initializeUnifyFunctionExitNodesLegacyPassPass(Registry);
+ initializeStripNonLineTableDebugLegacyPassPass(Registry);
+ initializeUnifyFunctionExitNodesLegacyPassPass(Registry);
initializeMetaRenamerPass(Registry);
- initializeStripGCRelocatesLegacyPass(Registry);
+ initializeStripGCRelocatesLegacyPass(Registry);
initializePredicateInfoPrinterLegacyPassPass(Registry);
initializeInjectTLIMappingsLegacyPass(Registry);
initializeFixIrreduciblePass(Registry);
- initializeUnifyLoopExitsLegacyPassPass(Registry);
+ initializeUnifyLoopExitsLegacyPassPass(Registry);
initializeUniqueInternalLinkageNamesLegacyPassPass(Registry);
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/VNCoercion.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/VNCoercion.cpp
index aa9c96db83..61cd8595a7 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/VNCoercion.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/VNCoercion.cpp
@@ -17,7 +17,7 @@ static bool isFirstClassAggregateOrScalableType(Type *Ty) {
bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy,
const DataLayout &DL) {
Type *StoredTy = StoredVal->getType();
-
+
if (StoredTy == LoadTy)
return true;
@@ -37,29 +37,29 @@ bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy,
if (StoreSize < DL.getTypeSizeInBits(LoadTy).getFixedSize())
return false;
- bool StoredNI = DL.isNonIntegralPointerType(StoredTy->getScalarType());
- bool LoadNI = DL.isNonIntegralPointerType(LoadTy->getScalarType());
+ bool StoredNI = DL.isNonIntegralPointerType(StoredTy->getScalarType());
+ bool LoadNI = DL.isNonIntegralPointerType(LoadTy->getScalarType());
// Don't coerce non-integral pointers to integers or vice versa.
- if (StoredNI != LoadNI) {
+ if (StoredNI != LoadNI) {
// As a special case, allow coercion of memset used to initialize
// an array w/null. Despite non-integral pointers not generally having a
// specific bit pattern, we do assume null is zero.
if (auto *CI = dyn_cast<Constant>(StoredVal))
return CI->isNullValue();
return false;
- } else if (StoredNI && LoadNI &&
- StoredTy->getPointerAddressSpace() !=
- LoadTy->getPointerAddressSpace()) {
- return false;
+ } else if (StoredNI && LoadNI &&
+ StoredTy->getPointerAddressSpace() !=
+ LoadTy->getPointerAddressSpace()) {
+ return false;
}
-
-
- // The implementation below uses inttoptr for vectors of unequal size; we
- // can't allow this for non integral pointers. We could teach it to extract
- // exact subvectors if desired.
- if (StoredNI && StoreSize != DL.getTypeSizeInBits(LoadTy).getFixedSize())
- return false;
-
+
+
+ // The implementation below uses inttoptr for vectors of unequal size; we
+ // can't allow this for non integral pointers. We could teach it to extract
+ // exact subvectors if desired.
+ if (StoredNI && StoreSize != DL.getTypeSizeInBits(LoadTy).getFixedSize())
+ return false;
+
return true;
}
@@ -236,8 +236,8 @@ int analyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr,
if (isFirstClassAggregateOrScalableType(StoredVal->getType()))
return -1;
- if (!canCoerceMustAliasedValueToLoad(StoredVal, LoadTy, DL))
- return -1;
+ if (!canCoerceMustAliasedValueToLoad(StoredVal, LoadTy, DL))
+ return -1;
Value *StorePtr = DepSI->getPointerOperand();
uint64_t StoreSize =
@@ -340,7 +340,7 @@ int analyzeLoadFromClobberingLoad(Type *LoadTy, Value *LoadPtr, LoadInst *DepLI,
if (DepLI->getType()->isStructTy() || DepLI->getType()->isArrayTy())
return -1;
- if (!canCoerceMustAliasedValueToLoad(DepLI, LoadTy, DL))
+ if (!canCoerceMustAliasedValueToLoad(DepLI, LoadTy, DL))
return -1;
Value *DepPtr = DepLI->getPointerOperand();
@@ -398,7 +398,7 @@ int analyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr,
if (!Src)
return -1;
- GlobalVariable *GV = dyn_cast<GlobalVariable>(getUnderlyingObject(Src));
+ GlobalVariable *GV = dyn_cast<GlobalVariable>(getUnderlyingObject(Src));
if (!GV || !GV->isConstant() || !GV->hasDefinitiveInitializer())
return -1;
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/ValueMapper.cpp b/contrib/libs/llvm12/lib/Transforms/Utils/ValueMapper.cpp
index 43e0439534..930e0b7ee0 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/ValueMapper.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/ValueMapper.cpp
@@ -819,15 +819,15 @@ void Mapper::flush() {
break;
case WorklistEntry::MapAppendingVar: {
unsigned PrefixSize = AppendingInits.size() - E.AppendingGVNumNewMembers;
- // mapAppendingVariable call can change AppendingInits if initalizer for
- // the variable depends on another appending global, because of that inits
- // need to be extracted and updated before the call.
- SmallVector<Constant *, 8> NewInits(
- drop_begin(AppendingInits, PrefixSize));
- AppendingInits.resize(PrefixSize);
+ // mapAppendingVariable call can change AppendingInits if initalizer for
+ // the variable depends on another appending global, because of that inits
+ // need to be extracted and updated before the call.
+ SmallVector<Constant *, 8> NewInits(
+ drop_begin(AppendingInits, PrefixSize));
+ AppendingInits.resize(PrefixSize);
mapAppendingVariable(*E.Data.AppendingGV.GV,
E.Data.AppendingGV.InitPrefix,
- E.AppendingGVIsOldCtorDtor, makeArrayRef(NewInits));
+ E.AppendingGVIsOldCtorDtor, makeArrayRef(NewInits));
break;
}
case WorklistEntry::MapGlobalIndirectSymbol:
@@ -901,13 +901,13 @@ void Mapper::remapInstruction(Instruction *I) {
LLVMContext &C = CB->getContext();
AttributeList Attrs = CB->getAttributes();
for (unsigned i = 0; i < Attrs.getNumAttrSets(); ++i) {
- for (Attribute::AttrKind TypedAttr :
- {Attribute::ByVal, Attribute::StructRet, Attribute::ByRef}) {
- if (Type *Ty = Attrs.getAttribute(i, TypedAttr).getValueAsType()) {
- Attrs = Attrs.replaceAttributeType(C, i, TypedAttr,
- TypeMapper->remapType(Ty));
- break;
- }
+ for (Attribute::AttrKind TypedAttr :
+ {Attribute::ByVal, Attribute::StructRet, Attribute::ByRef}) {
+ if (Type *Ty = Attrs.getAttribute(i, TypedAttr).getValueAsType()) {
+ Attrs = Attrs.replaceAttributeType(C, i, TypedAttr,
+ TypeMapper->remapType(Ty));
+ break;
+ }
}
}
CB->setAttributes(Attrs);
diff --git a/contrib/libs/llvm12/lib/Transforms/Utils/ya.make b/contrib/libs/llvm12/lib/Transforms/Utils/ya.make
index 35e2cfb7f1..c07d5d6db6 100644
--- a/contrib/libs/llvm12/lib/Transforms/Utils/ya.make
+++ b/contrib/libs/llvm12/lib/Transforms/Utils/ya.make
@@ -12,11 +12,11 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
@@ -63,7 +63,7 @@ SRCS(
LCSSA.cpp
LibCallsShrinkWrap.cpp
Local.cpp
- LoopPeel.cpp
+ LoopPeel.cpp
LoopRotationUtils.cpp
LoopSimplify.cpp
LoopUnroll.cpp
@@ -74,7 +74,7 @@ SRCS(
LowerInvoke.cpp
LowerMemIntrinsics.cpp
LowerSwitch.cpp
- MatrixUtils.cpp
+ MatrixUtils.cpp
Mem2Reg.cpp
MetaRenamer.cpp
ModuleUtils.cpp
diff --git a/contrib/libs/llvm12/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp b/contrib/libs/llvm12/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp
index 12f3203bd8..6ec5590d76 100644
--- a/contrib/libs/llvm12/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp
@@ -666,10 +666,10 @@ Vectorizer::getVectorizablePrefix(ArrayRef<Instruction *> Chain) {
cast<IntrinsicInst>(&I)->getIntrinsicID() ==
Intrinsic::sideeffect) {
// Ignore llvm.sideeffect calls.
- } else if (isa<IntrinsicInst>(&I) &&
- cast<IntrinsicInst>(&I)->getIntrinsicID() ==
- Intrinsic::pseudoprobe) {
- // Ignore llvm.pseudoprobe calls.
+ } else if (isa<IntrinsicInst>(&I) &&
+ cast<IntrinsicInst>(&I)->getIntrinsicID() ==
+ Intrinsic::pseudoprobe) {
+ // Ignore llvm.pseudoprobe calls.
} else if (IsLoadChain && (I.mayWriteToMemory() || I.mayThrow())) {
LLVM_DEBUG(dbgs() << "LSV: Found may-write/throw operation: " << I
<< '\n');
@@ -766,8 +766,8 @@ Vectorizer::getVectorizablePrefix(ArrayRef<Instruction *> Chain) {
return Chain.slice(0, ChainIdx);
}
-static ChainID getChainID(const Value *Ptr) {
- const Value *ObjPtr = getUnderlyingObject(Ptr);
+static ChainID getChainID(const Value *Ptr) {
+ const Value *ObjPtr = getUnderlyingObject(Ptr);
if (const auto *Sel = dyn_cast<SelectInst>(ObjPtr)) {
// The select's themselves are distinct instructions even if they share the
// same condition and evaluate to consecutive pointers for true and false
@@ -834,7 +834,7 @@ Vectorizer::collectInstructions(BasicBlock *BB) {
continue;
// Save the load locations.
- const ChainID ID = getChainID(Ptr);
+ const ChainID ID = getChainID(Ptr);
LoadRefs[ID].push_back(LI);
} else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {
if (!SI->isSimple())
@@ -880,7 +880,7 @@ Vectorizer::collectInstructions(BasicBlock *BB) {
continue;
// Save store location.
- const ChainID ID = getChainID(Ptr);
+ const ChainID ID = getChainID(Ptr);
StoreRefs[ID].push_back(SI);
}
}
@@ -1031,8 +1031,8 @@ bool Vectorizer::vectorizeStoreChain(
unsigned EltSzInBytes = Sz / 8;
unsigned SzInBytes = EltSzInBytes * ChainSize;
- FixedVectorType *VecTy;
- auto *VecStoreTy = dyn_cast<FixedVectorType>(StoreTy);
+ FixedVectorType *VecTy;
+ auto *VecStoreTy = dyn_cast<FixedVectorType>(StoreTy);
if (VecStoreTy)
VecTy = FixedVectorType::get(StoreTy->getScalarType(),
Chain.size() * VecStoreTy->getNumElements());
@@ -1184,7 +1184,7 @@ bool Vectorizer::vectorizeLoadChain(
unsigned EltSzInBytes = Sz / 8;
unsigned SzInBytes = EltSzInBytes * ChainSize;
VectorType *VecTy;
- auto *VecLoadTy = dyn_cast<FixedVectorType>(LoadTy);
+ auto *VecLoadTy = dyn_cast<FixedVectorType>(LoadTy);
if (VecLoadTy)
VecTy = FixedVectorType::get(LoadTy->getScalarType(),
Chain.size() * VecLoadTy->getNumElements());
diff --git a/contrib/libs/llvm12/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp b/contrib/libs/llvm12/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
index e40cd652e5..b8c21a0e1c 100644
--- a/contrib/libs/llvm12/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
@@ -13,16 +13,16 @@
// pass. It should be easy to create an analysis pass around it if there
// is a need (but D45420 needs to happen first).
//
-
+
#include "llvm/Transforms/Vectorize/LoopVectorizationLegality.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PatternMatch.h"
-#include "llvm/Transforms/Utils/SizeOpts.h"
+#include "llvm/Transforms/Utils/SizeOpts.h"
#include "llvm/Transforms/Vectorize/LoopVectorize.h"
using namespace llvm;
@@ -66,7 +66,7 @@ bool LoopVectorizeHints::Hint::validate(unsigned Val) {
return (Val <= 1);
case HK_ISVECTORIZED:
case HK_PREDICATE:
- case HK_SCALABLE:
+ case HK_SCALABLE:
return (Val == 0 || Val == 1);
}
return false;
@@ -79,8 +79,8 @@ LoopVectorizeHints::LoopVectorizeHints(const Loop *L,
Interleave("interleave.count", InterleaveOnlyWhenForced, HK_UNROLL),
Force("vectorize.enable", FK_Undefined, HK_FORCE),
IsVectorized("isvectorized", 0, HK_ISVECTORIZED),
- Predicate("vectorize.predicate.enable", FK_Undefined, HK_PREDICATE),
- Scalable("vectorize.scalable.enable", false, HK_SCALABLE), TheLoop(L),
+ Predicate("vectorize.predicate.enable", FK_Undefined, HK_PREDICATE),
+ Scalable("vectorize.scalable.enable", false, HK_SCALABLE), TheLoop(L),
ORE(ORE) {
// Populate values with existing loop metadata.
getHintsFromMetadata();
@@ -93,8 +93,8 @@ LoopVectorizeHints::LoopVectorizeHints(const Loop *L,
// If the vectorization width and interleaving count are both 1 then
// consider the loop to have been already vectorized because there's
// nothing more that we can do.
- IsVectorized.Value =
- getWidth() == ElementCount::getFixed(1) && Interleave.Value == 1;
+ IsVectorized.Value =
+ getWidth() == ElementCount::getFixed(1) && Interleave.Value == 1;
LLVM_DEBUG(if (InterleaveOnlyWhenForced && Interleave.Value == 1) dbgs()
<< "LV: Interleaving disabled by the pass manager\n");
}
@@ -167,7 +167,7 @@ void LoopVectorizeHints::emitRemarkWithHints() const {
if (Force.Value == LoopVectorizeHints::FK_Enabled) {
R << " (Force=" << NV("Force", true);
if (Width.Value != 0)
- R << ", Vector Width=" << NV("VectorWidth", getWidth());
+ R << ", Vector Width=" << NV("VectorWidth", getWidth());
if (Interleave.Value != 0)
R << ", Interleave Count=" << NV("InterleaveCount", Interleave.Value);
R << ")";
@@ -178,11 +178,11 @@ void LoopVectorizeHints::emitRemarkWithHints() const {
}
const char *LoopVectorizeHints::vectorizeAnalysisPassName() const {
- if (getWidth() == ElementCount::getFixed(1))
+ if (getWidth() == ElementCount::getFixed(1))
return LV_NAME;
if (getForce() == LoopVectorizeHints::FK_Disabled)
return LV_NAME;
- if (getForce() == LoopVectorizeHints::FK_Undefined && getWidth().isZero())
+ if (getForce() == LoopVectorizeHints::FK_Undefined && getWidth().isZero())
return LV_NAME;
return OptimizationRemarkAnalysis::AlwaysPrint;
}
@@ -233,8 +233,8 @@ void LoopVectorizeHints::setHint(StringRef Name, Metadata *Arg) {
return;
unsigned Val = C->getZExtValue();
- Hint *Hints[] = {&Width, &Interleave, &Force,
- &IsVectorized, &Predicate, &Scalable};
+ Hint *Hints[] = {&Width, &Interleave, &Force,
+ &IsVectorized, &Predicate, &Scalable};
for (auto H : Hints) {
if (Name == H->Name) {
if (H->validate(Val))
@@ -419,11 +419,11 @@ int LoopVectorizationLegality::isConsecutivePtr(Value *Ptr) {
const ValueToValueMap &Strides =
getSymbolicStrides() ? *getSymbolicStrides() : ValueToValueMap();
- Function *F = TheLoop->getHeader()->getParent();
- bool OptForSize = F->hasOptSize() ||
- llvm::shouldOptimizeForSize(TheLoop->getHeader(), PSI, BFI,
- PGSOQueryType::IRPass);
- bool CanAddPredicate = !OptForSize;
+ Function *F = TheLoop->getHeader()->getParent();
+ bool OptForSize = F->hasOptSize() ||
+ llvm::shouldOptimizeForSize(TheLoop->getHeader(), PSI, BFI,
+ PGSOQueryType::IRPass);
+ bool CanAddPredicate = !OptForSize;
int Stride = getPtrStride(PSE, Ptr, TheLoop, Strides, CanAddPredicate, false);
if (Stride == 1 || Stride == -1)
return Stride;
@@ -435,7 +435,7 @@ bool LoopVectorizationLegality::isUniform(Value *V) {
}
bool LoopVectorizationLegality::canVectorizeOuterLoop() {
- assert(!TheLoop->isInnermost() && "We are not vectorizing an outer loop.");
+ assert(!TheLoop->isInnermost() && "We are not vectorizing an outer loop.");
// Store the result and return it at the end instead of exiting early, in case
// allowExtraAnalysis is used to report multiple reasons for not vectorizing.
bool Result = true;
@@ -779,7 +779,7 @@ bool LoopVectorizationLegality::canVectorizeInstrs() {
// supported on the target.
if (ST->getMetadata(LLVMContext::MD_nontemporal)) {
// Arbitrarily try a vector of 2 elements.
- auto *VecTy = FixedVectorType::get(T, /*NumElts=*/2);
+ auto *VecTy = FixedVectorType::get(T, /*NumElts=*/2);
assert(VecTy && "did not find vectorized version of stored type");
if (!TTI->isLegalNTStore(VecTy, ST->getAlign())) {
reportVectorizationFailure(
@@ -794,7 +794,7 @@ bool LoopVectorizationLegality::canVectorizeInstrs() {
if (LD->getMetadata(LLVMContext::MD_nontemporal)) {
// For nontemporal loads, check that a nontemporal vector version is
// supported on the target (arbitrarily try a vector of 2 elements).
- auto *VecTy = FixedVectorType::get(I.getType(), /*NumElts=*/2);
+ auto *VecTy = FixedVectorType::get(I.getType(), /*NumElts=*/2);
assert(VecTy && "did not find vectorized version of load type");
if (!TTI->isLegalNTLoad(VecTy, LD->getAlign())) {
reportVectorizationFailure(
@@ -923,9 +923,9 @@ bool LoopVectorizationLegality::blockNeedsPredication(BasicBlock *BB) {
}
bool LoopVectorizationLegality::blockCanBePredicated(
- BasicBlock *BB, SmallPtrSetImpl<Value *> &SafePtrs,
- SmallPtrSetImpl<const Instruction *> &MaskedOp,
- SmallPtrSetImpl<Instruction *> &ConditionalAssumes) const {
+ BasicBlock *BB, SmallPtrSetImpl<Value *> &SafePtrs,
+ SmallPtrSetImpl<const Instruction *> &MaskedOp,
+ SmallPtrSetImpl<Instruction *> &ConditionalAssumes) const {
for (Instruction &I : *BB) {
// Check that we don't have a constant expression that can trap as operand.
for (Value *Operand : I.operands()) {
@@ -941,19 +941,19 @@ bool LoopVectorizationLegality::blockCanBePredicated(
continue;
}
- // Do not let llvm.experimental.noalias.scope.decl block the vectorization.
- // TODO: there might be cases that it should block the vectorization. Let's
- // ignore those for now.
- if (isa<NoAliasScopeDeclInst>(&I))
- continue;
-
+ // Do not let llvm.experimental.noalias.scope.decl block the vectorization.
+ // TODO: there might be cases that it should block the vectorization. Let's
+ // ignore those for now.
+ if (isa<NoAliasScopeDeclInst>(&I))
+ continue;
+
// We might be able to hoist the load.
if (I.mayReadFromMemory()) {
auto *LI = dyn_cast<LoadInst>(&I);
if (!LI)
return false;
if (!SafePtrs.count(LI->getPointerOperand())) {
- MaskedOp.insert(LI);
+ MaskedOp.insert(LI);
continue;
}
}
@@ -1012,7 +1012,7 @@ bool LoopVectorizationLegality::canVectorizeWithIfConvert() {
ScalarEvolution &SE = *PSE.getSE();
for (Instruction &I : *BB) {
LoadInst *LI = dyn_cast<LoadInst>(&I);
- if (LI && !LI->getType()->isVectorTy() && !mustSuppressSpeculation(*LI) &&
+ if (LI && !LI->getType()->isVectorTy() && !mustSuppressSpeculation(*LI) &&
isDereferenceableAndAlignedInLoop(LI, TheLoop, SE, *DT))
SafePointers.insert(LI->getPointerOperand());
}
@@ -1032,8 +1032,8 @@ bool LoopVectorizationLegality::canVectorizeWithIfConvert() {
// We must be able to predicate all blocks that need to be predicated.
if (blockNeedsPredication(BB)) {
- if (!blockCanBePredicated(BB, SafePointers, MaskedOp,
- ConditionalAssumes)) {
+ if (!blockCanBePredicated(BB, SafePointers, MaskedOp,
+ ConditionalAssumes)) {
reportVectorizationFailure(
"Control flow cannot be substituted for a select",
"control flow cannot be substituted for a select",
@@ -1058,7 +1058,7 @@ bool LoopVectorizationLegality::canVectorizeWithIfConvert() {
// Helper function to canVectorizeLoopNestCFG.
bool LoopVectorizationLegality::canVectorizeLoopCFG(Loop *Lp,
bool UseVPlanNativePath) {
- assert((UseVPlanNativePath || Lp->isInnermost()) &&
+ assert((UseVPlanNativePath || Lp->isInnermost()) &&
"VPlan-native path is not enabled.");
// TODO: ORE should be improved to show more accurate information when an
@@ -1094,14 +1094,14 @@ bool LoopVectorizationLegality::canVectorizeLoopCFG(Loop *Lp,
return false;
}
- // We currently must have a single "exit block" after the loop. Note that
- // multiple "exiting blocks" inside the loop are allowed, provided they all
- // reach the single exit block.
- // TODO: This restriction can be relaxed in the near future, it's here solely
- // to allow separation of changes for review. We need to generalize the phi
- // update logic in a number of places.
- if (!Lp->getUniqueExitBlock()) {
- reportVectorizationFailure("The loop must have a unique exit block",
+ // We currently must have a single "exit block" after the loop. Note that
+ // multiple "exiting blocks" inside the loop are allowed, provided they all
+ // reach the single exit block.
+ // TODO: This restriction can be relaxed in the near future, it's here solely
+ // to allow separation of changes for review. We need to generalize the phi
+ // update logic in a number of places.
+ if (!Lp->getUniqueExitBlock()) {
+ reportVectorizationFailure("The loop must have a unique exit block",
"loop control flow is not understood by vectorizer",
"CFGNotUnderstood", ORE, TheLoop);
if (DoExtraAnalysis)
@@ -1159,7 +1159,7 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
// Specific checks for outer loops. We skip the remaining legal checks at this
// point because they don't support outer loops.
- if (!TheLoop->isInnermost()) {
+ if (!TheLoop->isInnermost()) {
assert(UseVPlanNativePath && "VPlan-native path is not enabled.");
if (!canVectorizeOuterLoop()) {
@@ -1176,7 +1176,7 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
return Result;
}
- assert(TheLoop->isInnermost() && "Inner loop expected.");
+ assert(TheLoop->isInnermost() && "Inner loop expected.");
// Check if we can if-convert non-single-bb loops.
unsigned NumBlocks = TheLoop->getNumBlocks();
if (NumBlocks != 1 && !canVectorizeWithIfConvert()) {
@@ -1251,10 +1251,10 @@ bool LoopVectorizationLegality::prepareToFoldTailByMasking() {
Instruction *UI = cast<Instruction>(U);
if (TheLoop->contains(UI))
continue;
- LLVM_DEBUG(
- dbgs()
- << "LV: Cannot fold tail by masking, loop has an outside user for "
- << *UI << "\n");
+ LLVM_DEBUG(
+ dbgs()
+ << "LV: Cannot fold tail by masking, loop has an outside user for "
+ << *UI << "\n");
return false;
}
}
@@ -1262,25 +1262,25 @@ bool LoopVectorizationLegality::prepareToFoldTailByMasking() {
// The list of pointers that we can safely read and write to remains empty.
SmallPtrSet<Value *, 8> SafePointers;
- SmallPtrSet<const Instruction *, 8> TmpMaskedOp;
- SmallPtrSet<Instruction *, 8> TmpConditionalAssumes;
-
+ SmallPtrSet<const Instruction *, 8> TmpMaskedOp;
+ SmallPtrSet<Instruction *, 8> TmpConditionalAssumes;
+
// Check and mark all blocks for predication, including those that ordinarily
// do not need predication such as the header block.
for (BasicBlock *BB : TheLoop->blocks()) {
- if (!blockCanBePredicated(BB, SafePointers, TmpMaskedOp,
- TmpConditionalAssumes)) {
- LLVM_DEBUG(dbgs() << "LV: Cannot fold tail by masking as requested.\n");
+ if (!blockCanBePredicated(BB, SafePointers, TmpMaskedOp,
+ TmpConditionalAssumes)) {
+ LLVM_DEBUG(dbgs() << "LV: Cannot fold tail by masking as requested.\n");
return false;
}
}
LLVM_DEBUG(dbgs() << "LV: can fold tail by masking.\n");
-
- MaskedOp.insert(TmpMaskedOp.begin(), TmpMaskedOp.end());
- ConditionalAssumes.insert(TmpConditionalAssumes.begin(),
- TmpConditionalAssumes.end());
-
+
+ MaskedOp.insert(TmpMaskedOp.begin(), TmpMaskedOp.end());
+ ConditionalAssumes.insert(TmpConditionalAssumes.begin(),
+ TmpConditionalAssumes.end());
+
return true;
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Vectorize/LoopVectorizationPlanner.h b/contrib/libs/llvm12/lib/Transforms/Vectorize/LoopVectorizationPlanner.h
index 25e4a37d63..19797e6f78 100644
--- a/contrib/libs/llvm12/lib/Transforms/Vectorize/LoopVectorizationPlanner.h
+++ b/contrib/libs/llvm12/lib/Transforms/Vectorize/LoopVectorizationPlanner.h
@@ -34,7 +34,7 @@ namespace llvm {
class LoopVectorizationLegality;
class LoopVectorizationCostModel;
class PredicatedScalarEvolution;
-class VPRecipeBuilder;
+class VPRecipeBuilder;
/// VPlan-based builder utility analogous to IRBuilder.
class VPBuilder {
@@ -142,10 +142,10 @@ public:
return createInstruction(Instruction::BinaryOps::Or, {LHS, RHS});
}
- VPValue *createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal) {
- return createNaryOp(Instruction::Select, {Cond, TrueVal, FalseVal});
- }
-
+ VPValue *createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal) {
+ return createNaryOp(Instruction::Select, {Cond, TrueVal, FalseVal});
+ }
+
//===--------------------------------------------------------------------===//
// RAII helpers.
//===--------------------------------------------------------------------===//
@@ -176,22 +176,22 @@ public:
/// Information about vectorization costs
struct VectorizationFactor {
// Vector width with best cost
- ElementCount Width;
+ ElementCount Width;
// Cost of the loop with that width
unsigned Cost;
// Width 1 means no vectorization, cost 0 means uncomputed cost.
- static VectorizationFactor Disabled() {
- return {ElementCount::getFixed(1), 0};
- }
+ static VectorizationFactor Disabled() {
+ return {ElementCount::getFixed(1), 0};
+ }
bool operator==(const VectorizationFactor &rhs) const {
return Width == rhs.Width && Cost == rhs.Cost;
}
-
- bool operator!=(const VectorizationFactor &rhs) const {
- return !(*this == rhs);
- }
+
+ bool operator!=(const VectorizationFactor &rhs) const {
+ return !(*this == rhs);
+ }
};
/// Planner drives the vectorization process after having passed
@@ -237,10 +237,10 @@ class LoopVectorizationPlanner {
/// A builder used to construct the current plan.
VPBuilder Builder;
- /// The best number of elements of the vector types used in the
- /// transformed loop. BestVF = None means that vectorization is
- /// disabled.
- Optional<ElementCount> BestVF = None;
+ /// The best number of elements of the vector types used in the
+ /// transformed loop. BestVF = None means that vectorization is
+ /// disabled.
+ Optional<ElementCount> BestVF = None;
unsigned BestUF = 0;
public:
@@ -255,14 +255,14 @@ public:
/// Plan how to best vectorize, return the best VF and its cost, or None if
/// vectorization and interleaving should be avoided up front.
- Optional<VectorizationFactor> plan(ElementCount UserVF, unsigned UserIC);
+ Optional<VectorizationFactor> plan(ElementCount UserVF, unsigned UserIC);
/// Use the VPlan-native path to plan how to best vectorize, return the best
/// VF and its cost.
- VectorizationFactor planInVPlanNativePath(ElementCount UserVF);
+ VectorizationFactor planInVPlanNativePath(ElementCount UserVF);
/// Finalize the best decision and dispose of all other VPlans.
- void setBestPlan(ElementCount VF, unsigned UF);
+ void setBestPlan(ElementCount VF, unsigned UF);
/// Generate the IR code for the body of the vectorized loop according to the
/// best selected VPlan.
@@ -273,21 +273,21 @@ public:
O << *Plan;
}
- /// Look through the existing plans and return true if we have one with all
- /// the vectorization factors in question.
- bool hasPlanWithVFs(const ArrayRef<ElementCount> VFs) const {
- return any_of(VPlans, [&](const VPlanPtr &Plan) {
- return all_of(VFs, [&](const ElementCount &VF) {
- return Plan->hasVF(VF);
- });
- });
- }
-
+ /// Look through the existing plans and return true if we have one with all
+ /// the vectorization factors in question.
+ bool hasPlanWithVFs(const ArrayRef<ElementCount> VFs) const {
+ return any_of(VPlans, [&](const VPlanPtr &Plan) {
+ return all_of(VFs, [&](const ElementCount &VF) {
+ return Plan->hasVF(VF);
+ });
+ });
+ }
+
/// Test a \p Predicate on a \p Range of VF's. Return the value of applying
/// \p Predicate on Range.Start, possibly decreasing Range.End such that the
/// returned value holds for the entire \p Range.
static bool
- getDecisionAndClampRange(const std::function<bool(ElementCount)> &Predicate,
+ getDecisionAndClampRange(const std::function<bool(ElementCount)> &Predicate,
VFRange &Range);
protected:
@@ -299,7 +299,7 @@ protected:
/// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive,
/// according to the information gathered by Legal when it checked if it is
/// legal to vectorize the loop.
- void buildVPlans(ElementCount MinVF, ElementCount MaxVF);
+ void buildVPlans(ElementCount MinVF, ElementCount MaxVF);
private:
/// Build a VPlan according to the information gathered by Legal. \return a
@@ -310,20 +310,20 @@ private:
/// Build a VPlan using VPRecipes according to the information gather by
/// Legal. This method is only used for the legacy inner loop vectorizer.
VPlanPtr buildVPlanWithVPRecipes(
- VFRange &Range, SmallPtrSetImpl<Instruction *> &DeadInstructions,
+ VFRange &Range, SmallPtrSetImpl<Instruction *> &DeadInstructions,
const DenseMap<Instruction *, Instruction *> &SinkAfter);
/// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive,
/// according to the information gathered by Legal when it checked if it is
/// legal to vectorize the loop. This method creates VPlans using VPRecipes.
- void buildVPlansWithVPRecipes(ElementCount MinVF, ElementCount MaxVF);
-
- /// Adjust the recipes for any inloop reductions. The chain of instructions
- /// leading from the loop exit instr to the phi need to be converted to
- /// reductions, with one operand being vector and the other being the scalar
- /// reduction chain.
- void adjustRecipesForInLoopReductions(VPlanPtr &Plan,
- VPRecipeBuilder &RecipeBuilder);
+ void buildVPlansWithVPRecipes(ElementCount MinVF, ElementCount MaxVF);
+
+ /// Adjust the recipes for any inloop reductions. The chain of instructions
+ /// leading from the loop exit instr to the phi need to be converted to
+ /// reductions, with one operand being vector and the other being the scalar
+ /// reduction chain.
+ void adjustRecipesForInLoopReductions(VPlanPtr &Plan,
+ VPRecipeBuilder &RecipeBuilder);
};
} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/Transforms/Vectorize/LoopVectorize.cpp b/contrib/libs/llvm12/lib/Transforms/Vectorize/LoopVectorize.cpp
index decb6ce1d7..b456a97aa4 100644
--- a/contrib/libs/llvm12/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -130,7 +130,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/InstructionCost.h"
+#include "llvm/Support/InstructionCost.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
@@ -158,38 +158,38 @@ using namespace llvm;
#define LV_NAME "loop-vectorize"
#define DEBUG_TYPE LV_NAME
-#ifndef NDEBUG
-const char VerboseDebug[] = DEBUG_TYPE "-verbose";
-#endif
-
+#ifndef NDEBUG
+const char VerboseDebug[] = DEBUG_TYPE "-verbose";
+#endif
+
/// @{
/// Metadata attribute names
-const char LLVMLoopVectorizeFollowupAll[] = "llvm.loop.vectorize.followup_all";
-const char LLVMLoopVectorizeFollowupVectorized[] =
+const char LLVMLoopVectorizeFollowupAll[] = "llvm.loop.vectorize.followup_all";
+const char LLVMLoopVectorizeFollowupVectorized[] =
"llvm.loop.vectorize.followup_vectorized";
-const char LLVMLoopVectorizeFollowupEpilogue[] =
+const char LLVMLoopVectorizeFollowupEpilogue[] =
"llvm.loop.vectorize.followup_epilogue";
/// @}
STATISTIC(LoopsVectorized, "Number of loops vectorized");
STATISTIC(LoopsAnalyzed, "Number of loops analyzed for vectorization");
-STATISTIC(LoopsEpilogueVectorized, "Number of epilogues vectorized");
-
-static cl::opt<bool> EnableEpilogueVectorization(
- "enable-epilogue-vectorization", cl::init(true), cl::Hidden,
- cl::desc("Enable vectorization of epilogue loops."));
-
-static cl::opt<unsigned> EpilogueVectorizationForceVF(
- "epilogue-vectorization-force-VF", cl::init(1), cl::Hidden,
- cl::desc("When epilogue vectorization is enabled, and a value greater than "
- "1 is specified, forces the given VF for all applicable epilogue "
- "loops."));
-
-static cl::opt<unsigned> EpilogueVectorizationMinVF(
- "epilogue-vectorization-minimum-VF", cl::init(16), cl::Hidden,
- cl::desc("Only loops with vectorization factor equal to or larger than "
- "the specified value are considered for epilogue vectorization."));
-
+STATISTIC(LoopsEpilogueVectorized, "Number of epilogues vectorized");
+
+static cl::opt<bool> EnableEpilogueVectorization(
+ "enable-epilogue-vectorization", cl::init(true), cl::Hidden,
+ cl::desc("Enable vectorization of epilogue loops."));
+
+static cl::opt<unsigned> EpilogueVectorizationForceVF(
+ "epilogue-vectorization-force-VF", cl::init(1), cl::Hidden,
+ cl::desc("When epilogue vectorization is enabled, and a value greater than "
+ "1 is specified, forces the given VF for all applicable epilogue "
+ "loops."));
+
+static cl::opt<unsigned> EpilogueVectorizationMinVF(
+ "epilogue-vectorization-minimum-VF", cl::init(16), cl::Hidden,
+ cl::desc("Only loops with vectorization factor equal to or larger than "
+ "the specified value are considered for epilogue vectorization."));
+
/// Loops with a known constant trip count below this number are vectorized only
/// if no scalar iteration overheads are incurred.
static cl::opt<unsigned> TinyTripCountVectorThreshold(
@@ -198,37 +198,37 @@ static cl::opt<unsigned> TinyTripCountVectorThreshold(
"value are vectorized only if no scalar iteration overheads "
"are incurred."));
-// Option prefer-predicate-over-epilogue indicates that an epilogue is undesired,
-// that predication is preferred, and this lists all options. I.e., the
-// vectorizer will try to fold the tail-loop (epilogue) into the vector body
-// and predicate the instructions accordingly. If tail-folding fails, there are
-// different fallback strategies depending on these values:
-namespace PreferPredicateTy {
- enum Option {
- ScalarEpilogue = 0,
- PredicateElseScalarEpilogue,
- PredicateOrDontVectorize
- };
-} // namespace PreferPredicateTy
-
-static cl::opt<PreferPredicateTy::Option> PreferPredicateOverEpilogue(
- "prefer-predicate-over-epilogue",
- cl::init(PreferPredicateTy::ScalarEpilogue),
- cl::Hidden,
- cl::desc("Tail-folding and predication preferences over creating a scalar "
- "epilogue loop."),
- cl::values(clEnumValN(PreferPredicateTy::ScalarEpilogue,
- "scalar-epilogue",
- "Don't tail-predicate loops, create scalar epilogue"),
- clEnumValN(PreferPredicateTy::PredicateElseScalarEpilogue,
- "predicate-else-scalar-epilogue",
- "prefer tail-folding, create scalar epilogue if tail "
- "folding fails."),
- clEnumValN(PreferPredicateTy::PredicateOrDontVectorize,
- "predicate-dont-vectorize",
- "prefers tail-folding, don't attempt vectorization if "
- "tail-folding fails.")));
-
+// Option prefer-predicate-over-epilogue indicates that an epilogue is undesired,
+// that predication is preferred, and this lists all options. I.e., the
+// vectorizer will try to fold the tail-loop (epilogue) into the vector body
+// and predicate the instructions accordingly. If tail-folding fails, there are
+// different fallback strategies depending on these values:
+namespace PreferPredicateTy {
+ enum Option {
+ ScalarEpilogue = 0,
+ PredicateElseScalarEpilogue,
+ PredicateOrDontVectorize
+ };
+} // namespace PreferPredicateTy
+
+static cl::opt<PreferPredicateTy::Option> PreferPredicateOverEpilogue(
+ "prefer-predicate-over-epilogue",
+ cl::init(PreferPredicateTy::ScalarEpilogue),
+ cl::Hidden,
+ cl::desc("Tail-folding and predication preferences over creating a scalar "
+ "epilogue loop."),
+ cl::values(clEnumValN(PreferPredicateTy::ScalarEpilogue,
+ "scalar-epilogue",
+ "Don't tail-predicate loops, create scalar epilogue"),
+ clEnumValN(PreferPredicateTy::PredicateElseScalarEpilogue,
+ "predicate-else-scalar-epilogue",
+ "prefer tail-folding, create scalar epilogue if tail "
+ "folding fails."),
+ clEnumValN(PreferPredicateTy::PredicateOrDontVectorize,
+ "predicate-dont-vectorize",
+ "prefers tail-folding, don't attempt vectorization if "
+ "tail-folding fails.")));
+
static cl::opt<bool> MaximizeBandwidth(
"vectorizer-maximize-bandwidth", cl::init(false), cl::Hidden,
cl::desc("Maximize bandwidth when selecting vectorization factor which "
@@ -239,7 +239,7 @@ static cl::opt<bool> EnableInterleavedMemAccesses(
cl::desc("Enable vectorization on interleaved memory accesses in a loop"));
/// An interleave-group may need masking if it resides in a block that needs
-/// predication, or in order to mask away gaps.
+/// predication, or in order to mask away gaps.
static cl::opt<bool> EnableMaskedInterleavedMemAccesses(
"enable-masked-interleaved-mem-accesses", cl::init(false), cl::Hidden,
cl::desc("Enable vectorization on masked interleaved memory accesses in a loop"));
@@ -273,12 +273,12 @@ static cl::opt<unsigned> ForceTargetInstructionCost(
"an instruction to a single constant value. Mostly "
"useful for getting consistent testing."));
-static cl::opt<bool> ForceTargetSupportsScalableVectors(
- "force-target-supports-scalable-vectors", cl::init(false), cl::Hidden,
- cl::desc(
- "Pretend that scalable vectors are supported, even if the target does "
- "not support them. This flag should only be used for testing."));
-
+static cl::opt<bool> ForceTargetSupportsScalableVectors(
+ "force-target-supports-scalable-vectors", cl::init(false), cl::Hidden,
+ cl::desc(
+ "Pretend that scalable vectors are supported, even if the target does "
+ "not support them. This flag should only be used for testing."));
+
static cl::opt<unsigned> SmallLoopCost(
"small-loop-cost", cl::init(20), cl::Hidden,
cl::desc(
@@ -296,12 +296,12 @@ static cl::opt<bool> EnableLoadStoreRuntimeInterleave(
cl::desc(
"Enable runtime interleaving until load/store ports are saturated"));
-/// Interleave small loops with scalar reductions.
-static cl::opt<bool> InterleaveSmallLoopScalarReduction(
- "interleave-small-loop-scalar-reduction", cl::init(false), cl::Hidden,
- cl::desc("Enable interleaving for loops with small iteration counts that "
- "contain scalar reductions to expose ILP."));
-
+/// Interleave small loops with scalar reductions.
+static cl::opt<bool> InterleaveSmallLoopScalarReduction(
+ "interleave-small-loop-scalar-reduction", cl::init(false), cl::Hidden,
+ cl::desc("Enable interleaving for loops with small iteration counts that "
+ "contain scalar reductions to expose ILP."));
+
/// The number of stores in a loop that are allowed to need predication.
static cl::opt<unsigned> NumberOfStoresToPredicate(
"vectorize-num-stores-pred", cl::init(1), cl::Hidden,
@@ -320,17 +320,17 @@ static cl::opt<unsigned> MaxNestedScalarReductionIC(
cl::desc("The maximum interleave count to use when interleaving a scalar "
"reduction in a nested loop."));
-static cl::opt<bool>
- PreferInLoopReductions("prefer-inloop-reductions", cl::init(false),
- cl::Hidden,
- cl::desc("Prefer in-loop vector reductions, "
- "overriding the targets preference."));
-
-static cl::opt<bool> PreferPredicatedReductionSelect(
- "prefer-predicated-reduction-select", cl::init(false), cl::Hidden,
- cl::desc(
- "Prefer predicating a reduction operation over an after loop select."));
-
+static cl::opt<bool>
+ PreferInLoopReductions("prefer-inloop-reductions", cl::init(false),
+ cl::Hidden,
+ cl::desc("Prefer in-loop vector reductions, "
+ "overriding the targets preference."));
+
+static cl::opt<bool> PreferPredicatedReductionSelect(
+ "prefer-predicated-reduction-select", cl::init(false), cl::Hidden,
+ cl::desc(
+ "Prefer predicating a reduction operation over an after loop select."));
+
cl::opt<bool> EnableVPlanNativePath(
"enable-vplan-native-path", cl::init(false), cl::Hidden,
cl::desc("Enable VPlan-native vectorization path with "
@@ -372,11 +372,11 @@ static Type *getMemInstValueType(Value *I) {
/// A helper function that returns true if the given type is irregular. The
/// type is irregular if its allocated size doesn't equal the store size of an
-/// element of the corresponding vector type.
-static bool hasIrregularType(Type *Ty, const DataLayout &DL) {
- // Determine if an array of N elements of type Ty is "bitcast compatible"
- // with a <N x Ty> vector.
- // This is only true if there is no padding between the array elements.
+/// element of the corresponding vector type.
+static bool hasIrregularType(Type *Ty, const DataLayout &DL) {
+ // Determine if an array of N elements of type Ty is "bitcast compatible"
+ // with a <N x Ty> vector.
+ // This is only true if there is no padding between the array elements.
return DL.getTypeAllocSizeInBits(Ty) != DL.getTypeSizeInBits(Ty);
}
@@ -453,42 +453,42 @@ public:
LoopInfo *LI, DominatorTree *DT,
const TargetLibraryInfo *TLI,
const TargetTransformInfo *TTI, AssumptionCache *AC,
- OptimizationRemarkEmitter *ORE, ElementCount VecWidth,
+ OptimizationRemarkEmitter *ORE, ElementCount VecWidth,
unsigned UnrollFactor, LoopVectorizationLegality *LVL,
- LoopVectorizationCostModel *CM, BlockFrequencyInfo *BFI,
- ProfileSummaryInfo *PSI)
+ LoopVectorizationCostModel *CM, BlockFrequencyInfo *BFI,
+ ProfileSummaryInfo *PSI)
: OrigLoop(OrigLoop), PSE(PSE), LI(LI), DT(DT), TLI(TLI), TTI(TTI),
AC(AC), ORE(ORE), VF(VecWidth), UF(UnrollFactor),
Builder(PSE.getSE()->getContext()),
- VectorLoopValueMap(UnrollFactor, VecWidth), Legal(LVL), Cost(CM),
- BFI(BFI), PSI(PSI) {
- // Query this against the original loop and save it here because the profile
- // of the original loop header may change as the transformation happens.
- OptForSizeBasedOnProfile = llvm::shouldOptimizeForSize(
- OrigLoop->getHeader(), PSI, BFI, PGSOQueryType::IRPass);
- }
-
+ VectorLoopValueMap(UnrollFactor, VecWidth), Legal(LVL), Cost(CM),
+ BFI(BFI), PSI(PSI) {
+ // Query this against the original loop and save it here because the profile
+ // of the original loop header may change as the transformation happens.
+ OptForSizeBasedOnProfile = llvm::shouldOptimizeForSize(
+ OrigLoop->getHeader(), PSI, BFI, PGSOQueryType::IRPass);
+ }
+
virtual ~InnerLoopVectorizer() = default;
- /// Create a new empty loop that will contain vectorized instructions later
- /// on, while the old loop will be used as the scalar remainder. Control flow
- /// is generated around the vectorized (and scalar epilogue) loops consisting
- /// of various checks and bypasses. Return the pre-header block of the new
- /// loop.
- /// In the case of epilogue vectorization, this function is overriden to
- /// handle the more complex control flow around the loops.
- virtual BasicBlock *createVectorizedLoopSkeleton();
+ /// Create a new empty loop that will contain vectorized instructions later
+ /// on, while the old loop will be used as the scalar remainder. Control flow
+ /// is generated around the vectorized (and scalar epilogue) loops consisting
+ /// of various checks and bypasses. Return the pre-header block of the new
+ /// loop.
+ /// In the case of epilogue vectorization, this function is overriden to
+ /// handle the more complex control flow around the loops.
+ virtual BasicBlock *createVectorizedLoopSkeleton();
/// Widen a single instruction within the innermost loop.
- void widenInstruction(Instruction &I, VPValue *Def, VPUser &Operands,
+ void widenInstruction(Instruction &I, VPValue *Def, VPUser &Operands,
VPTransformState &State);
/// Widen a single call instruction within the innermost loop.
- void widenCallInstruction(CallInst &I, VPValue *Def, VPUser &ArgOperands,
+ void widenCallInstruction(CallInst &I, VPValue *Def, VPUser &ArgOperands,
VPTransformState &State);
/// Widen a single select instruction within the innermost loop.
- void widenSelectInstruction(SelectInst &I, VPValue *VPDef, VPUser &Operands,
+ void widenSelectInstruction(SelectInst &I, VPValue *VPDef, VPUser &Operands,
bool InvariantCond, VPTransformState &State);
/// Fix the vectorized code, taking care of header phi's, live-outs, and more.
@@ -504,15 +504,15 @@ public:
/// Vectorize a single GetElementPtrInst based on information gathered and
/// decisions taken during planning.
- void widenGEP(GetElementPtrInst *GEP, VPValue *VPDef, VPUser &Indices,
- unsigned UF, ElementCount VF, bool IsPtrLoopInvariant,
+ void widenGEP(GetElementPtrInst *GEP, VPValue *VPDef, VPUser &Indices,
+ unsigned UF, ElementCount VF, bool IsPtrLoopInvariant,
SmallBitVector &IsIndexLoopInvariant, VPTransformState &State);
/// Vectorize a single PHINode in a block. This method handles the induction
/// variable canonicalization. It supports both VF = 1 for unrolled loops and
/// arbitrary length vectors.
- void widenPHIInstruction(Instruction *PN, RecurrenceDescriptor *RdxDesc,
- Value *StartV, unsigned UF, ElementCount VF);
+ void widenPHIInstruction(Instruction *PN, RecurrenceDescriptor *RdxDesc,
+ Value *StartV, unsigned UF, ElementCount VF);
/// A helper function to scalarize a single Instruction in the innermost loop.
/// Generates a sequence of scalar instances for each lane between \p MinLane
@@ -526,8 +526,8 @@ public:
/// Widen an integer or floating-point induction variable \p IV. If \p Trunc
/// is provided, the integer induction variable will first be truncated to
/// the corresponding type.
- void widenIntOrFpInduction(PHINode *IV, Value *Start,
- TruncInst *Trunc = nullptr);
+ void widenIntOrFpInduction(PHINode *IV, Value *Start,
+ TruncInst *Trunc = nullptr);
/// getOrCreateVectorValue and getOrCreateScalarValue coordinate to generate a
/// vector or scalar value on-demand if one is not yet available. When
@@ -552,10 +552,10 @@ public:
/// value into a vector.
Value *getOrCreateVectorValue(Value *V, unsigned Part);
- void setVectorValue(Value *Scalar, unsigned Part, Value *Vector) {
- VectorLoopValueMap.setVectorValue(Scalar, Part, Vector);
- }
-
+ void setVectorValue(Value *Scalar, unsigned Part, Value *Vector) {
+ VectorLoopValueMap.setVectorValue(Scalar, Part, Vector);
+ }
+
/// Return a value in the new loop corresponding to \p V from the original
/// loop at unroll and vector indices \p Instance. If the value has been
/// vectorized but not scalarized, the necessary extractelement instruction
@@ -570,9 +570,9 @@ public:
/// BlockInMask is non-null. Use \p State to translate given VPValues to IR
/// values in the vectorized loop.
void vectorizeInterleaveGroup(const InterleaveGroup<Instruction> *Group,
- ArrayRef<VPValue *> VPDefs,
+ ArrayRef<VPValue *> VPDefs,
VPTransformState &State, VPValue *Addr,
- ArrayRef<VPValue *> StoredValues,
+ ArrayRef<VPValue *> StoredValues,
VPValue *BlockInMask = nullptr);
/// Vectorize Load and Store instructions with the base address given in \p
@@ -580,8 +580,8 @@ public:
/// non-null. Use \p State to translate given VPValues to IR values in the
/// vectorized loop.
void vectorizeMemoryInstruction(Instruction *Instr, VPTransformState &State,
- VPValue *Def, VPValue *Addr,
- VPValue *StoredValue, VPValue *BlockInMask);
+ VPValue *Def, VPValue *Addr,
+ VPValue *StoredValue, VPValue *BlockInMask);
/// Set the debug location in the builder using the debug location in
/// the instruction.
@@ -625,11 +625,11 @@ protected:
/// Clear NSW/NUW flags from reduction instructions if necessary.
void clearReductionWrapFlags(RecurrenceDescriptor &RdxDesc);
- /// Fixup the LCSSA phi nodes in the unique exit block. This simply
- /// means we need to add the appropriate incoming value from the middle
- /// block as exiting edges from the scalar epilogue loop (if present) are
- /// already in place, and we exit the vector loop exclusively to the middle
- /// block.
+ /// Fixup the LCSSA phi nodes in the unique exit block. This simply
+ /// means we need to add the appropriate incoming value from the middle
+ /// block as exiting edges from the scalar epilogue loop (if present) are
+ /// already in place, and we exit the vector loop exclusively to the middle
+ /// block.
void fixLCSSAPHIs();
/// Iteratively sink the scalarized operands of a predicated instruction into
@@ -668,8 +668,8 @@ protected:
/// truncate instruction, instead of widening the original IV, we widen a
/// version of the IV truncated to \p EntryVal's type.
void createVectorIntOrFpInductionPHI(const InductionDescriptor &II,
- Value *Step, Value *Start,
- Instruction *EntryVal);
+ Value *Step, Value *Start,
+ Instruction *EntryVal);
/// Returns true if an instruction \p I should be scalarized instead of
/// vectorized for the chosen vectorization factor.
@@ -737,28 +737,28 @@ protected:
const DataLayout &DL,
const InductionDescriptor &ID) const;
- /// Emit basic blocks (prefixed with \p Prefix) for the iteration check,
- /// vector loop preheader, middle block and scalar preheader. Also
- /// allocate a loop object for the new vector loop and return it.
- Loop *createVectorLoopSkeleton(StringRef Prefix);
-
- /// Create new phi nodes for the induction variables to resume iteration count
- /// in the scalar epilogue, from where the vectorized loop left off (given by
- /// \p VectorTripCount).
- /// In cases where the loop skeleton is more complicated (eg. epilogue
- /// vectorization) and the resume values can come from an additional bypass
- /// block, the \p AdditionalBypass pair provides information about the bypass
- /// block and the end value on the edge from bypass to this loop.
- void createInductionResumeValues(
- Loop *L, Value *VectorTripCount,
- std::pair<BasicBlock *, Value *> AdditionalBypass = {nullptr, nullptr});
-
- /// Complete the loop skeleton by adding debug MDs, creating appropriate
- /// conditional branches in the middle block, preparing the builder and
- /// running the verifier. Take in the vector loop \p L as argument, and return
- /// the preheader of the completed vector loop.
- BasicBlock *completeLoopSkeleton(Loop *L, MDNode *OrigLoopID);
-
+ /// Emit basic blocks (prefixed with \p Prefix) for the iteration check,
+ /// vector loop preheader, middle block and scalar preheader. Also
+ /// allocate a loop object for the new vector loop and return it.
+ Loop *createVectorLoopSkeleton(StringRef Prefix);
+
+ /// Create new phi nodes for the induction variables to resume iteration count
+ /// in the scalar epilogue, from where the vectorized loop left off (given by
+ /// \p VectorTripCount).
+ /// In cases where the loop skeleton is more complicated (eg. epilogue
+ /// vectorization) and the resume values can come from an additional bypass
+ /// block, the \p AdditionalBypass pair provides information about the bypass
+ /// block and the end value on the edge from bypass to this loop.
+ void createInductionResumeValues(
+ Loop *L, Value *VectorTripCount,
+ std::pair<BasicBlock *, Value *> AdditionalBypass = {nullptr, nullptr});
+
+ /// Complete the loop skeleton by adding debug MDs, creating appropriate
+ /// conditional branches in the middle block, preparing the builder and
+ /// running the verifier. Take in the vector loop \p L as argument, and return
+ /// the preheader of the completed vector loop.
+ BasicBlock *completeLoopSkeleton(Loop *L, MDNode *OrigLoopID);
+
/// Add additional metadata to \p To that was not present on \p Orig.
///
/// Currently this is used to add the noalias annotations based on the
@@ -777,11 +777,11 @@ protected:
/// vector of instructions.
void addMetadata(ArrayRef<Value *> To, Instruction *From);
- /// Allow subclasses to override and print debug traces before/after vplan
- /// execution, when trace information is requested.
- virtual void printDebugTracesAtStart(){};
- virtual void printDebugTracesAtEnd(){};
-
+ /// Allow subclasses to override and print debug traces before/after vplan
+ /// execution, when trace information is requested.
+ virtual void printDebugTracesAtStart(){};
+ virtual void printDebugTracesAtEnd(){};
+
/// The original loop.
Loop *OrigLoop;
@@ -820,7 +820,7 @@ protected:
/// The vectorization SIMD factor to use. Each vector will have this many
/// vector elements.
- ElementCount VF;
+ ElementCount VF;
/// The vectorization unroll factor to use. Each scalar is vectorized to this
/// many different vector instructions.
@@ -840,8 +840,8 @@ protected:
/// Middle Block between the vector and the scalar.
BasicBlock *LoopMiddleBlock;
- /// The (unique) ExitBlock of the scalar loop. Note that
- /// there can be multiple exiting edges reaching this block.
+ /// The (unique) ExitBlock of the scalar loop. Note that
+ /// there can be multiple exiting edges reaching this block.
BasicBlock *LoopExitBlock;
/// The vector loop body.
@@ -890,14 +890,14 @@ protected:
// Vector of original scalar PHIs whose corresponding widened PHIs need to be
// fixed up at the end of vector code generation.
SmallVector<PHINode *, 8> OrigPHIsToFix;
-
- /// BFI and PSI are used to check for profile guided size optimizations.
- BlockFrequencyInfo *BFI;
- ProfileSummaryInfo *PSI;
-
- // Whether this loop should be optimized for size based on profile guided size
- // optimizatios.
- bool OptForSizeBasedOnProfile;
+
+ /// BFI and PSI are used to check for profile guided size optimizations.
+ BlockFrequencyInfo *BFI;
+ ProfileSummaryInfo *PSI;
+
+ // Whether this loop should be optimized for size based on profile guided size
+ // optimizatios.
+ bool OptForSizeBasedOnProfile;
};
class InnerLoopUnroller : public InnerLoopVectorizer {
@@ -908,11 +908,11 @@ public:
const TargetTransformInfo *TTI, AssumptionCache *AC,
OptimizationRemarkEmitter *ORE, unsigned UnrollFactor,
LoopVectorizationLegality *LVL,
- LoopVectorizationCostModel *CM, BlockFrequencyInfo *BFI,
- ProfileSummaryInfo *PSI)
- : InnerLoopVectorizer(OrigLoop, PSE, LI, DT, TLI, TTI, AC, ORE,
- ElementCount::getFixed(1), UnrollFactor, LVL, CM,
- BFI, PSI) {}
+ LoopVectorizationCostModel *CM, BlockFrequencyInfo *BFI,
+ ProfileSummaryInfo *PSI)
+ : InnerLoopVectorizer(OrigLoop, PSE, LI, DT, TLI, TTI, AC, ORE,
+ ElementCount::getFixed(1), UnrollFactor, LVL, CM,
+ BFI, PSI) {}
private:
Value *getBroadcastInstrs(Value *V) override;
@@ -922,128 +922,128 @@ private:
Value *reverseVector(Value *Vec) override;
};
-/// Encapsulate information regarding vectorization of a loop and its epilogue.
-/// This information is meant to be updated and used across two stages of
-/// epilogue vectorization.
-struct EpilogueLoopVectorizationInfo {
- ElementCount MainLoopVF = ElementCount::getFixed(0);
- unsigned MainLoopUF = 0;
- ElementCount EpilogueVF = ElementCount::getFixed(0);
- unsigned EpilogueUF = 0;
- BasicBlock *MainLoopIterationCountCheck = nullptr;
- BasicBlock *EpilogueIterationCountCheck = nullptr;
- BasicBlock *SCEVSafetyCheck = nullptr;
- BasicBlock *MemSafetyCheck = nullptr;
- Value *TripCount = nullptr;
- Value *VectorTripCount = nullptr;
-
- EpilogueLoopVectorizationInfo(unsigned MVF, unsigned MUF, unsigned EVF,
- unsigned EUF)
- : MainLoopVF(ElementCount::getFixed(MVF)), MainLoopUF(MUF),
- EpilogueVF(ElementCount::getFixed(EVF)), EpilogueUF(EUF) {
- assert(EUF == 1 &&
- "A high UF for the epilogue loop is likely not beneficial.");
- }
-};
-
-/// An extension of the inner loop vectorizer that creates a skeleton for a
-/// vectorized loop that has its epilogue (residual) also vectorized.
-/// The idea is to run the vplan on a given loop twice, firstly to setup the
-/// skeleton and vectorize the main loop, and secondly to complete the skeleton
-/// from the first step and vectorize the epilogue. This is achieved by
-/// deriving two concrete strategy classes from this base class and invoking
-/// them in succession from the loop vectorizer planner.
-class InnerLoopAndEpilogueVectorizer : public InnerLoopVectorizer {
-public:
- InnerLoopAndEpilogueVectorizer(
- Loop *OrigLoop, PredicatedScalarEvolution &PSE, LoopInfo *LI,
- DominatorTree *DT, const TargetLibraryInfo *TLI,
- const TargetTransformInfo *TTI, AssumptionCache *AC,
- OptimizationRemarkEmitter *ORE, EpilogueLoopVectorizationInfo &EPI,
- LoopVectorizationLegality *LVL, llvm::LoopVectorizationCostModel *CM,
- BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI)
- : InnerLoopVectorizer(OrigLoop, PSE, LI, DT, TLI, TTI, AC, ORE,
- EPI.MainLoopVF, EPI.MainLoopUF, LVL, CM, BFI, PSI),
- EPI(EPI) {}
-
- // Override this function to handle the more complex control flow around the
- // three loops.
- BasicBlock *createVectorizedLoopSkeleton() final override {
- return createEpilogueVectorizedLoopSkeleton();
- }
-
- /// The interface for creating a vectorized skeleton using one of two
- /// different strategies, each corresponding to one execution of the vplan
- /// as described above.
- virtual BasicBlock *createEpilogueVectorizedLoopSkeleton() = 0;
-
- /// Holds and updates state information required to vectorize the main loop
- /// and its epilogue in two separate passes. This setup helps us avoid
- /// regenerating and recomputing runtime safety checks. It also helps us to
- /// shorten the iteration-count-check path length for the cases where the
- /// iteration count of the loop is so small that the main vector loop is
- /// completely skipped.
- EpilogueLoopVectorizationInfo &EPI;
-};
-
-/// A specialized derived class of inner loop vectorizer that performs
-/// vectorization of *main* loops in the process of vectorizing loops and their
-/// epilogues.
-class EpilogueVectorizerMainLoop : public InnerLoopAndEpilogueVectorizer {
-public:
- EpilogueVectorizerMainLoop(
- Loop *OrigLoop, PredicatedScalarEvolution &PSE, LoopInfo *LI,
- DominatorTree *DT, const TargetLibraryInfo *TLI,
- const TargetTransformInfo *TTI, AssumptionCache *AC,
- OptimizationRemarkEmitter *ORE, EpilogueLoopVectorizationInfo &EPI,
- LoopVectorizationLegality *LVL, llvm::LoopVectorizationCostModel *CM,
- BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI)
- : InnerLoopAndEpilogueVectorizer(OrigLoop, PSE, LI, DT, TLI, TTI, AC, ORE,
- EPI, LVL, CM, BFI, PSI) {}
- /// Implements the interface for creating a vectorized skeleton using the
- /// *main loop* strategy (ie the first pass of vplan execution).
- BasicBlock *createEpilogueVectorizedLoopSkeleton() final override;
-
-protected:
- /// Emits an iteration count bypass check once for the main loop (when \p
- /// ForEpilogue is false) and once for the epilogue loop (when \p
- /// ForEpilogue is true).
- BasicBlock *emitMinimumIterationCountCheck(Loop *L, BasicBlock *Bypass,
- bool ForEpilogue);
- void printDebugTracesAtStart() override;
- void printDebugTracesAtEnd() override;
-};
-
-// A specialized derived class of inner loop vectorizer that performs
-// vectorization of *epilogue* loops in the process of vectorizing loops and
-// their epilogues.
-class EpilogueVectorizerEpilogueLoop : public InnerLoopAndEpilogueVectorizer {
-public:
- EpilogueVectorizerEpilogueLoop(Loop *OrigLoop, PredicatedScalarEvolution &PSE,
- LoopInfo *LI, DominatorTree *DT,
- const TargetLibraryInfo *TLI,
- const TargetTransformInfo *TTI, AssumptionCache *AC,
- OptimizationRemarkEmitter *ORE,
- EpilogueLoopVectorizationInfo &EPI,
- LoopVectorizationLegality *LVL,
- llvm::LoopVectorizationCostModel *CM,
- BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI)
- : InnerLoopAndEpilogueVectorizer(OrigLoop, PSE, LI, DT, TLI, TTI, AC, ORE,
- EPI, LVL, CM, BFI, PSI) {}
- /// Implements the interface for creating a vectorized skeleton using the
- /// *epilogue loop* strategy (ie the second pass of vplan execution).
- BasicBlock *createEpilogueVectorizedLoopSkeleton() final override;
-
-protected:
- /// Emits an iteration count bypass check after the main vector loop has
- /// finished to see if there are any iterations left to execute by either
- /// the vector epilogue or the scalar epilogue.
- BasicBlock *emitMinimumVectorEpilogueIterCountCheck(Loop *L,
- BasicBlock *Bypass,
- BasicBlock *Insert);
- void printDebugTracesAtStart() override;
- void printDebugTracesAtEnd() override;
-};
+/// Encapsulate information regarding vectorization of a loop and its epilogue.
+/// This information is meant to be updated and used across two stages of
+/// epilogue vectorization.
+struct EpilogueLoopVectorizationInfo {
+ ElementCount MainLoopVF = ElementCount::getFixed(0);
+ unsigned MainLoopUF = 0;
+ ElementCount EpilogueVF = ElementCount::getFixed(0);
+ unsigned EpilogueUF = 0;
+ BasicBlock *MainLoopIterationCountCheck = nullptr;
+ BasicBlock *EpilogueIterationCountCheck = nullptr;
+ BasicBlock *SCEVSafetyCheck = nullptr;
+ BasicBlock *MemSafetyCheck = nullptr;
+ Value *TripCount = nullptr;
+ Value *VectorTripCount = nullptr;
+
+ EpilogueLoopVectorizationInfo(unsigned MVF, unsigned MUF, unsigned EVF,
+ unsigned EUF)
+ : MainLoopVF(ElementCount::getFixed(MVF)), MainLoopUF(MUF),
+ EpilogueVF(ElementCount::getFixed(EVF)), EpilogueUF(EUF) {
+ assert(EUF == 1 &&
+ "A high UF for the epilogue loop is likely not beneficial.");
+ }
+};
+
+/// An extension of the inner loop vectorizer that creates a skeleton for a
+/// vectorized loop that has its epilogue (residual) also vectorized.
+/// The idea is to run the vplan on a given loop twice, firstly to setup the
+/// skeleton and vectorize the main loop, and secondly to complete the skeleton
+/// from the first step and vectorize the epilogue. This is achieved by
+/// deriving two concrete strategy classes from this base class and invoking
+/// them in succession from the loop vectorizer planner.
+class InnerLoopAndEpilogueVectorizer : public InnerLoopVectorizer {
+public:
+ InnerLoopAndEpilogueVectorizer(
+ Loop *OrigLoop, PredicatedScalarEvolution &PSE, LoopInfo *LI,
+ DominatorTree *DT, const TargetLibraryInfo *TLI,
+ const TargetTransformInfo *TTI, AssumptionCache *AC,
+ OptimizationRemarkEmitter *ORE, EpilogueLoopVectorizationInfo &EPI,
+ LoopVectorizationLegality *LVL, llvm::LoopVectorizationCostModel *CM,
+ BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI)
+ : InnerLoopVectorizer(OrigLoop, PSE, LI, DT, TLI, TTI, AC, ORE,
+ EPI.MainLoopVF, EPI.MainLoopUF, LVL, CM, BFI, PSI),
+ EPI(EPI) {}
+
+ // Override this function to handle the more complex control flow around the
+ // three loops.
+ BasicBlock *createVectorizedLoopSkeleton() final override {
+ return createEpilogueVectorizedLoopSkeleton();
+ }
+
+ /// The interface for creating a vectorized skeleton using one of two
+ /// different strategies, each corresponding to one execution of the vplan
+ /// as described above.
+ virtual BasicBlock *createEpilogueVectorizedLoopSkeleton() = 0;
+
+ /// Holds and updates state information required to vectorize the main loop
+ /// and its epilogue in two separate passes. This setup helps us avoid
+ /// regenerating and recomputing runtime safety checks. It also helps us to
+ /// shorten the iteration-count-check path length for the cases where the
+ /// iteration count of the loop is so small that the main vector loop is
+ /// completely skipped.
+ EpilogueLoopVectorizationInfo &EPI;
+};
+
+/// A specialized derived class of inner loop vectorizer that performs
+/// vectorization of *main* loops in the process of vectorizing loops and their
+/// epilogues.
+class EpilogueVectorizerMainLoop : public InnerLoopAndEpilogueVectorizer {
+public:
+ EpilogueVectorizerMainLoop(
+ Loop *OrigLoop, PredicatedScalarEvolution &PSE, LoopInfo *LI,
+ DominatorTree *DT, const TargetLibraryInfo *TLI,
+ const TargetTransformInfo *TTI, AssumptionCache *AC,
+ OptimizationRemarkEmitter *ORE, EpilogueLoopVectorizationInfo &EPI,
+ LoopVectorizationLegality *LVL, llvm::LoopVectorizationCostModel *CM,
+ BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI)
+ : InnerLoopAndEpilogueVectorizer(OrigLoop, PSE, LI, DT, TLI, TTI, AC, ORE,
+ EPI, LVL, CM, BFI, PSI) {}
+ /// Implements the interface for creating a vectorized skeleton using the
+ /// *main loop* strategy (ie the first pass of vplan execution).
+ BasicBlock *createEpilogueVectorizedLoopSkeleton() final override;
+
+protected:
+ /// Emits an iteration count bypass check once for the main loop (when \p
+ /// ForEpilogue is false) and once for the epilogue loop (when \p
+ /// ForEpilogue is true).
+ BasicBlock *emitMinimumIterationCountCheck(Loop *L, BasicBlock *Bypass,
+ bool ForEpilogue);
+ void printDebugTracesAtStart() override;
+ void printDebugTracesAtEnd() override;
+};
+
+// A specialized derived class of inner loop vectorizer that performs
+// vectorization of *epilogue* loops in the process of vectorizing loops and
+// their epilogues.
+class EpilogueVectorizerEpilogueLoop : public InnerLoopAndEpilogueVectorizer {
+public:
+ EpilogueVectorizerEpilogueLoop(Loop *OrigLoop, PredicatedScalarEvolution &PSE,
+ LoopInfo *LI, DominatorTree *DT,
+ const TargetLibraryInfo *TLI,
+ const TargetTransformInfo *TTI, AssumptionCache *AC,
+ OptimizationRemarkEmitter *ORE,
+ EpilogueLoopVectorizationInfo &EPI,
+ LoopVectorizationLegality *LVL,
+ llvm::LoopVectorizationCostModel *CM,
+ BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI)
+ : InnerLoopAndEpilogueVectorizer(OrigLoop, PSE, LI, DT, TLI, TTI, AC, ORE,
+ EPI, LVL, CM, BFI, PSI) {}
+ /// Implements the interface for creating a vectorized skeleton using the
+ /// *epilogue loop* strategy (ie the second pass of vplan execution).
+ BasicBlock *createEpilogueVectorizedLoopSkeleton() final override;
+
+protected:
+ /// Emits an iteration count bypass check after the main vector loop has
+ /// finished to see if there are any iterations left to execute by either
+ /// the vector epilogue or the scalar epilogue.
+ BasicBlock *emitMinimumVectorEpilogueIterCountCheck(Loop *L,
+ BasicBlock *Bypass,
+ BasicBlock *Insert);
+ void printDebugTracesAtStart() override;
+ void printDebugTracesAtEnd() override;
+};
} // end namespace llvm
/// Look for a meaningful debug location on the instruction or it's
@@ -1070,9 +1070,9 @@ void InnerLoopVectorizer::setDebugLocFromInst(IRBuilder<> &B, const Value *Ptr)
const DILocation *DIL = Inst->getDebugLoc();
if (DIL && Inst->getFunction()->isDebugInfoForProfiling() &&
!isa<DbgInfoIntrinsic>(Inst)) {
- assert(!VF.isScalable() && "scalable vectors not yet supported.");
- auto NewDIL =
- DIL->cloneByMultiplyingDuplicationFactor(UF * VF.getKnownMinValue());
+ assert(!VF.isScalable() && "scalable vectors not yet supported.");
+ auto NewDIL =
+ DIL->cloneByMultiplyingDuplicationFactor(UF * VF.getKnownMinValue());
if (NewDIL)
B.SetCurrentDebugLocation(NewDIL.getValue());
else
@@ -1126,15 +1126,15 @@ static OptimizationRemarkAnalysis createLVAnalysis(const char *PassName,
return R;
}
-/// Return a value for Step multiplied by VF.
-static Value *createStepForVF(IRBuilder<> &B, Constant *Step, ElementCount VF) {
- assert(isa<ConstantInt>(Step) && "Expected an integer step");
- Constant *StepVal = ConstantInt::get(
- Step->getType(),
- cast<ConstantInt>(Step)->getSExtValue() * VF.getKnownMinValue());
- return VF.isScalable() ? B.CreateVScale(StepVal) : StepVal;
-}
-
+/// Return a value for Step multiplied by VF.
+static Value *createStepForVF(IRBuilder<> &B, Constant *Step, ElementCount VF) {
+ assert(isa<ConstantInt>(Step) && "Expected an integer step");
+ Constant *StepVal = ConstantInt::get(
+ Step->getType(),
+ cast<ConstantInt>(Step)->getSExtValue() * VF.getKnownMinValue());
+ return VF.isScalable() ? B.CreateVScale(StepVal) : StepVal;
+}
+
namespace llvm {
void reportVectorizationFailure(const StringRef DebugMsg,
@@ -1206,10 +1206,10 @@ enum ScalarEpilogueLowering {
CM_ScalarEpilogueNotAllowedLowTripLoop,
// Loop hint predicate indicating an epilogue is undesired.
- CM_ScalarEpilogueNotNeededUsePredicate,
-
- // Directive indicating we must either tail fold or not vectorize
- CM_ScalarEpilogueNotAllowedUsePredicate
+ CM_ScalarEpilogueNotNeededUsePredicate,
+
+ // Directive indicating we must either tail fold or not vectorize
+ CM_ScalarEpilogueNotAllowedUsePredicate
};
/// LoopVectorizationCostModel - estimates the expected speedups due to
@@ -1236,7 +1236,7 @@ public:
/// \return An upper bound for the vectorization factor, or None if
/// vectorization and interleaving should be avoided up front.
- Optional<ElementCount> computeMaxVF(ElementCount UserVF, unsigned UserIC);
+ Optional<ElementCount> computeMaxVF(ElementCount UserVF, unsigned UserIC);
/// \return True if runtime checks are required for vectorization, and false
/// otherwise.
@@ -1246,13 +1246,13 @@ public:
/// This method checks every power of two up to MaxVF. If UserVF is not ZERO
/// then this vectorization factor will be selected if vectorization is
/// possible.
- VectorizationFactor selectVectorizationFactor(ElementCount MaxVF);
- VectorizationFactor
- selectEpilogueVectorizationFactor(const ElementCount MaxVF,
- const LoopVectorizationPlanner &LVP);
+ VectorizationFactor selectVectorizationFactor(ElementCount MaxVF);
+ VectorizationFactor
+ selectEpilogueVectorizationFactor(const ElementCount MaxVF,
+ const LoopVectorizationPlanner &LVP);
/// Setup cost-based decisions for user vectorization factor.
- void selectUserVectorizationFactor(ElementCount UserVF) {
+ void selectUserVectorizationFactor(ElementCount UserVF) {
collectUniformsAndScalars(UserVF);
collectInstsToScalarize(UserVF);
}
@@ -1266,7 +1266,7 @@ public:
/// If interleave count has been specified by metadata it will be returned.
/// Otherwise, the interleave count is computed and returned. VF and LoopCost
/// are the selected vectorization factor and the cost of the selected VF.
- unsigned selectInterleaveCount(ElementCount VF, unsigned LoopCost);
+ unsigned selectInterleaveCount(ElementCount VF, unsigned LoopCost);
/// Memory access instruction may be vectorized in more than one way.
/// Form of instruction after vectorization depends on cost.
@@ -1275,7 +1275,7 @@ public:
/// the lists of loop-uniform and loop-scalar instructions.
/// The calculated cost is saved with widening decision in order to
/// avoid redundant calculations.
- void setCostBasedWideningDecision(ElementCount VF);
+ void setCostBasedWideningDecision(ElementCount VF);
/// A struct that represents some properties of the register usage
/// of a loop.
@@ -1290,16 +1290,16 @@ public:
/// \return Returns information about the register usages of the loop for the
/// given vectorization factors.
- SmallVector<RegisterUsage, 8>
- calculateRegisterUsage(ArrayRef<ElementCount> VFs);
+ SmallVector<RegisterUsage, 8>
+ calculateRegisterUsage(ArrayRef<ElementCount> VFs);
/// Collect values we want to ignore in the cost model.
void collectValuesToIgnore();
- /// Split reductions into those that happen in the loop, and those that happen
- /// outside. In loop reductions are collected into InLoopReductionChains.
- void collectInLoopReductions();
-
+ /// Split reductions into those that happen in the loop, and those that happen
+ /// outside. In loop reductions are collected into InLoopReductionChains.
+ void collectInLoopReductions();
+
/// \returns The smallest bitwidth each instruction can be represented with.
/// The vector equivalents of these instructions should be truncated to this
/// type.
@@ -1309,9 +1309,9 @@ public:
/// \returns True if it is more profitable to scalarize instruction \p I for
/// vectorization factor \p VF.
- bool isProfitableToScalarize(Instruction *I, ElementCount VF) const {
- assert(VF.isVector() &&
- "Profitable to scalarize relevant only for VF > 1.");
+ bool isProfitableToScalarize(Instruction *I, ElementCount VF) const {
+ assert(VF.isVector() &&
+ "Profitable to scalarize relevant only for VF > 1.");
// Cost model is not run in the VPlan-native path - return conservative
// result until this changes.
@@ -1325,8 +1325,8 @@ public:
}
/// Returns true if \p I is known to be uniform after vectorization.
- bool isUniformAfterVectorization(Instruction *I, ElementCount VF) const {
- if (VF.isScalar())
+ bool isUniformAfterVectorization(Instruction *I, ElementCount VF) const {
+ if (VF.isScalar())
return true;
// Cost model is not run in the VPlan-native path - return conservative
@@ -1341,8 +1341,8 @@ public:
}
/// Returns true if \p I is known to be scalar after vectorization.
- bool isScalarAfterVectorization(Instruction *I, ElementCount VF) const {
- if (VF.isScalar())
+ bool isScalarAfterVectorization(Instruction *I, ElementCount VF) const {
+ if (VF.isScalar())
return true;
// Cost model is not run in the VPlan-native path - return conservative
@@ -1358,8 +1358,8 @@ public:
/// \returns True if instruction \p I can be truncated to a smaller bitwidth
/// for vectorization factor \p VF.
- bool canTruncateToMinimalBitwidth(Instruction *I, ElementCount VF) const {
- return VF.isVector() && MinBWs.find(I) != MinBWs.end() &&
+ bool canTruncateToMinimalBitwidth(Instruction *I, ElementCount VF) const {
+ return VF.isVector() && MinBWs.find(I) != MinBWs.end() &&
!isProfitableToScalarize(I, VF) &&
!isScalarAfterVectorization(I, VF);
}
@@ -1376,18 +1376,18 @@ public:
/// Save vectorization decision \p W and \p Cost taken by the cost model for
/// instruction \p I and vector width \p VF.
- void setWideningDecision(Instruction *I, ElementCount VF, InstWidening W,
- InstructionCost Cost) {
- assert(VF.isVector() && "Expected VF >=2");
+ void setWideningDecision(Instruction *I, ElementCount VF, InstWidening W,
+ InstructionCost Cost) {
+ assert(VF.isVector() && "Expected VF >=2");
WideningDecisions[std::make_pair(I, VF)] = std::make_pair(W, Cost);
}
/// Save vectorization decision \p W and \p Cost taken by the cost model for
/// interleaving group \p Grp and vector width \p VF.
- void setWideningDecision(const InterleaveGroup<Instruction> *Grp,
- ElementCount VF, InstWidening W,
- InstructionCost Cost) {
- assert(VF.isVector() && "Expected VF >=2");
+ void setWideningDecision(const InterleaveGroup<Instruction> *Grp,
+ ElementCount VF, InstWidening W,
+ InstructionCost Cost) {
+ assert(VF.isVector() && "Expected VF >=2");
/// Broadcast this decicion to all instructions inside the group.
/// But the cost will be assigned to one instruction only.
for (unsigned i = 0; i < Grp->getFactor(); ++i) {
@@ -1403,14 +1403,14 @@ public:
/// Return the cost model decision for the given instruction \p I and vector
/// width \p VF. Return CM_Unknown if this instruction did not pass
/// through the cost modeling.
- InstWidening getWideningDecision(Instruction *I, ElementCount VF) {
- assert(VF.isVector() && "Expected VF to be a vector VF");
+ InstWidening getWideningDecision(Instruction *I, ElementCount VF) {
+ assert(VF.isVector() && "Expected VF to be a vector VF");
// Cost model is not run in the VPlan-native path - return conservative
// result until this changes.
if (EnableVPlanNativePath)
return CM_GatherScatter;
- std::pair<Instruction *, ElementCount> InstOnVF = std::make_pair(I, VF);
+ std::pair<Instruction *, ElementCount> InstOnVF = std::make_pair(I, VF);
auto Itr = WideningDecisions.find(InstOnVF);
if (Itr == WideningDecisions.end())
return CM_Unknown;
@@ -1419,9 +1419,9 @@ public:
/// Return the vectorization cost for the given instruction \p I and vector
/// width \p VF.
- InstructionCost getWideningCost(Instruction *I, ElementCount VF) {
- assert(VF.isVector() && "Expected VF >=2");
- std::pair<Instruction *, ElementCount> InstOnVF = std::make_pair(I, VF);
+ InstructionCost getWideningCost(Instruction *I, ElementCount VF) {
+ assert(VF.isVector() && "Expected VF >=2");
+ std::pair<Instruction *, ElementCount> InstOnVF = std::make_pair(I, VF);
assert(WideningDecisions.find(InstOnVF) != WideningDecisions.end() &&
"The cost is not calculated");
return WideningDecisions[InstOnVF].second;
@@ -1430,7 +1430,7 @@ public:
/// Return True if instruction \p I is an optimizable truncate whose operand
/// is an induction variable. Such a truncate will be removed by adding a new
/// induction variable with the destination type.
- bool isOptimizableIVTruncate(Instruction *I, ElementCount VF) {
+ bool isOptimizableIVTruncate(Instruction *I, ElementCount VF) {
// If the instruction is not a truncate, return false.
auto *Trunc = dyn_cast<TruncInst>(I);
if (!Trunc)
@@ -1455,14 +1455,14 @@ public:
/// Collects the instructions to scalarize for each predicated instruction in
/// the loop.
- void collectInstsToScalarize(ElementCount VF);
+ void collectInstsToScalarize(ElementCount VF);
/// Collect Uniform and Scalar values for the given \p VF.
/// The sets depend on CM decision for Load/Store instructions
/// that may be vectorized as interleave, gather-scatter or scalarized.
- void collectUniformsAndScalars(ElementCount VF) {
+ void collectUniformsAndScalars(ElementCount VF) {
// Do the analysis once.
- if (VF.isScalar() || Uniforms.find(VF) != Uniforms.end())
+ if (VF.isScalar() || Uniforms.find(VF) != Uniforms.end())
return;
setCostBasedWideningDecision(VF);
collectLoopUniforms(VF);
@@ -1513,8 +1513,8 @@ public:
/// instructions that may divide by zero.
/// If a non-zero VF has been calculated, we check if I will be scalarized
/// predication for that VF.
- bool isScalarWithPredication(Instruction *I,
- ElementCount VF = ElementCount::getFixed(1));
+ bool isScalarWithPredication(Instruction *I,
+ ElementCount VF = ElementCount::getFixed(1));
// Returns true if \p I is an instruction that will be predicated either
// through scalar predication or masked load/store or masked gather/scatter.
@@ -1531,16 +1531,16 @@ public:
/// Returns true if \p I is a memory instruction with consecutive memory
/// access that can be widened.
- bool
- memoryInstructionCanBeWidened(Instruction *I,
- ElementCount VF = ElementCount::getFixed(1));
+ bool
+ memoryInstructionCanBeWidened(Instruction *I,
+ ElementCount VF = ElementCount::getFixed(1));
/// Returns true if \p I is a memory instruction in an interleaved-group
/// of memory accesses that can be vectorized with wide vector loads/stores
/// and shuffles.
- bool
- interleavedAccessCanBeWidened(Instruction *I,
- ElementCount VF = ElementCount::getFixed(1));
+ bool
+ interleavedAccessCanBeWidened(Instruction *I,
+ ElementCount VF = ElementCount::getFixed(1));
/// Check if \p Instr belongs to any interleaved access group.
bool isAccessInterleaved(Instruction *Instr) {
@@ -1553,16 +1553,16 @@ public:
return InterleaveInfo.getInterleaveGroup(Instr);
}
- /// Returns true if we're required to use a scalar epilogue for at least
- /// the final iteration of the original loop.
+ /// Returns true if we're required to use a scalar epilogue for at least
+ /// the final iteration of the original loop.
bool requiresScalarEpilogue() const {
- if (!isScalarEpilogueAllowed())
- return false;
- // If we might exit from anywhere but the latch, must run the exiting
- // iteration in scalar form.
- if (TheLoop->getExitingBlock() != TheLoop->getLoopLatch())
- return true;
- return InterleaveInfo.requiresScalarEpilogue();
+ if (!isScalarEpilogueAllowed())
+ return false;
+ // If we might exit from anywhere but the latch, must run the exiting
+ // iteration in scalar form.
+ if (TheLoop->getExitingBlock() != TheLoop->getLoopLatch())
+ return true;
+ return InterleaveInfo.requiresScalarEpilogue();
}
/// Returns true if a scalar epilogue is not allowed due to optsize or a
@@ -1578,34 +1578,34 @@ public:
return foldTailByMasking() || Legal->blockNeedsPredication(BB);
}
- /// A SmallMapVector to store the InLoop reduction op chains, mapping phi
- /// nodes to the chain of instructions representing the reductions. Uses a
- /// MapVector to ensure deterministic iteration order.
- using ReductionChainMap =
- SmallMapVector<PHINode *, SmallVector<Instruction *, 4>, 4>;
-
- /// Return the chain of instructions representing an inloop reduction.
- const ReductionChainMap &getInLoopReductionChains() const {
- return InLoopReductionChains;
- }
-
- /// Returns true if the Phi is part of an inloop reduction.
- bool isInLoopReduction(PHINode *Phi) const {
- return InLoopReductionChains.count(Phi);
- }
-
+ /// A SmallMapVector to store the InLoop reduction op chains, mapping phi
+ /// nodes to the chain of instructions representing the reductions. Uses a
+ /// MapVector to ensure deterministic iteration order.
+ using ReductionChainMap =
+ SmallMapVector<PHINode *, SmallVector<Instruction *, 4>, 4>;
+
+ /// Return the chain of instructions representing an inloop reduction.
+ const ReductionChainMap &getInLoopReductionChains() const {
+ return InLoopReductionChains;
+ }
+
+ /// Returns true if the Phi is part of an inloop reduction.
+ bool isInLoopReduction(PHINode *Phi) const {
+ return InLoopReductionChains.count(Phi);
+ }
+
/// Estimate cost of an intrinsic call instruction CI if it were vectorized
/// with factor VF. Return the cost of the instruction, including
/// scalarization overhead if it's needed.
- InstructionCost getVectorIntrinsicCost(CallInst *CI, ElementCount VF);
+ InstructionCost getVectorIntrinsicCost(CallInst *CI, ElementCount VF);
/// Estimate cost of a call instruction CI if it were vectorized with factor
/// VF. Return the cost of the instruction, including scalarization overhead
/// if it's needed. The flag NeedToScalarize shows if the call needs to be
/// scalarized -
/// i.e. either vector version isn't available, or is too expensive.
- InstructionCost getVectorCallCost(CallInst *CI, ElementCount VF,
- bool &NeedToScalarize);
+ InstructionCost getVectorCallCost(CallInst *CI, ElementCount VF,
+ bool &NeedToScalarize);
/// Invalidates decisions already taken by the cost model.
void invalidateCostModelingDecisions() {
@@ -1620,8 +1620,8 @@ private:
/// \return An upper bound for the vectorization factor, a power-of-2 larger
/// than zero. One is returned if vectorization should best be avoided due
/// to cost.
- ElementCount computeFeasibleMaxVF(unsigned ConstTripCount,
- ElementCount UserVF);
+ ElementCount computeFeasibleMaxVF(unsigned ConstTripCount,
+ ElementCount UserVF);
/// The vectorization cost is a combination of the cost itself and a boolean
/// indicating whether any of the contributing operations will actually
@@ -1630,54 +1630,54 @@ private:
/// is
/// false, then all operations will be scalarized (i.e. no vectorization has
/// actually taken place).
- using VectorizationCostTy = std::pair<InstructionCost, bool>;
+ using VectorizationCostTy = std::pair<InstructionCost, bool>;
/// Returns the expected execution cost. The unit of the cost does
/// not matter because we use the 'cost' units to compare different
/// vector widths. The cost that is returned is *not* normalized by
/// the factor width.
- VectorizationCostTy expectedCost(ElementCount VF);
+ VectorizationCostTy expectedCost(ElementCount VF);
/// Returns the execution time cost of an instruction for a given vector
/// width. Vector width of one means scalar.
- VectorizationCostTy getInstructionCost(Instruction *I, ElementCount VF);
+ VectorizationCostTy getInstructionCost(Instruction *I, ElementCount VF);
/// The cost-computation logic from getInstructionCost which provides
/// the vector type as an output parameter.
- InstructionCost getInstructionCost(Instruction *I, ElementCount VF,
- Type *&VectorTy);
-
- /// Return the cost of instructions in an inloop reduction pattern, if I is
- /// part of that pattern.
- InstructionCost getReductionPatternCost(Instruction *I, ElementCount VF,
- Type *VectorTy,
- TTI::TargetCostKind CostKind);
-
+ InstructionCost getInstructionCost(Instruction *I, ElementCount VF,
+ Type *&VectorTy);
+
+ /// Return the cost of instructions in an inloop reduction pattern, if I is
+ /// part of that pattern.
+ InstructionCost getReductionPatternCost(Instruction *I, ElementCount VF,
+ Type *VectorTy,
+ TTI::TargetCostKind CostKind);
+
/// Calculate vectorization cost of memory instruction \p I.
- InstructionCost getMemoryInstructionCost(Instruction *I, ElementCount VF);
+ InstructionCost getMemoryInstructionCost(Instruction *I, ElementCount VF);
/// The cost computation for scalarized memory instruction.
- InstructionCost getMemInstScalarizationCost(Instruction *I, ElementCount VF);
+ InstructionCost getMemInstScalarizationCost(Instruction *I, ElementCount VF);
/// The cost computation for interleaving group of memory instructions.
- InstructionCost getInterleaveGroupCost(Instruction *I, ElementCount VF);
+ InstructionCost getInterleaveGroupCost(Instruction *I, ElementCount VF);
/// The cost computation for Gather/Scatter instruction.
- InstructionCost getGatherScatterCost(Instruction *I, ElementCount VF);
+ InstructionCost getGatherScatterCost(Instruction *I, ElementCount VF);
/// The cost computation for widening instruction \p I with consecutive
/// memory access.
- InstructionCost getConsecutiveMemOpCost(Instruction *I, ElementCount VF);
+ InstructionCost getConsecutiveMemOpCost(Instruction *I, ElementCount VF);
/// The cost calculation for Load/Store instruction \p I with uniform pointer -
/// Load: scalar load + broadcast.
/// Store: scalar store + (loop invariant value stored? 0 : extract of last
/// element)
- InstructionCost getUniformMemOpCost(Instruction *I, ElementCount VF);
+ InstructionCost getUniformMemOpCost(Instruction *I, ElementCount VF);
/// Estimate the overhead of scalarizing an instruction. This is a
/// convenience wrapper for the type-based getScalarizationOverhead API.
- InstructionCost getScalarizationOverhead(Instruction *I, ElementCount VF);
+ InstructionCost getScalarizationOverhead(Instruction *I, ElementCount VF);
/// Returns whether the instruction is a load or store and will be a emitted
/// as a vector operation.
@@ -1695,7 +1695,7 @@ private:
/// A type representing the costs for instructions if they were to be
/// scalarized rather than vectorized. The entries are Instruction-Cost
/// pairs.
- using ScalarCostsTy = DenseMap<Instruction *, InstructionCost>;
+ using ScalarCostsTy = DenseMap<Instruction *, InstructionCost>;
/// A set containing all BasicBlocks that are known to present after
/// vectorization as a predicated block.
@@ -1717,38 +1717,38 @@ private:
/// presence of a cost for an instruction in the mapping indicates that the
/// instruction will be scalarized when vectorizing with the associated
/// vectorization factor. The entries are VF-ScalarCostTy pairs.
- DenseMap<ElementCount, ScalarCostsTy> InstsToScalarize;
+ DenseMap<ElementCount, ScalarCostsTy> InstsToScalarize;
/// Holds the instructions known to be uniform after vectorization.
/// The data is collected per VF.
- DenseMap<ElementCount, SmallPtrSet<Instruction *, 4>> Uniforms;
+ DenseMap<ElementCount, SmallPtrSet<Instruction *, 4>> Uniforms;
/// Holds the instructions known to be scalar after vectorization.
/// The data is collected per VF.
- DenseMap<ElementCount, SmallPtrSet<Instruction *, 4>> Scalars;
+ DenseMap<ElementCount, SmallPtrSet<Instruction *, 4>> Scalars;
/// Holds the instructions (address computations) that are forced to be
/// scalarized.
- DenseMap<ElementCount, SmallPtrSet<Instruction *, 4>> ForcedScalars;
-
- /// PHINodes of the reductions that should be expanded in-loop along with
- /// their associated chains of reduction operations, in program order from top
- /// (PHI) to bottom
- ReductionChainMap InLoopReductionChains;
-
- /// A Map of inloop reduction operations and their immediate chain operand.
- /// FIXME: This can be removed once reductions can be costed correctly in
- /// vplan. This was added to allow quick lookup to the inloop operations,
- /// without having to loop through InLoopReductionChains.
- DenseMap<Instruction *, Instruction *> InLoopReductionImmediateChains;
-
+ DenseMap<ElementCount, SmallPtrSet<Instruction *, 4>> ForcedScalars;
+
+ /// PHINodes of the reductions that should be expanded in-loop along with
+ /// their associated chains of reduction operations, in program order from top
+ /// (PHI) to bottom
+ ReductionChainMap InLoopReductionChains;
+
+ /// A Map of inloop reduction operations and their immediate chain operand.
+ /// FIXME: This can be removed once reductions can be costed correctly in
+ /// vplan. This was added to allow quick lookup to the inloop operations,
+ /// without having to loop through InLoopReductionChains.
+ DenseMap<Instruction *, Instruction *> InLoopReductionImmediateChains;
+
/// Returns the expected difference in cost from scalarizing the expression
/// feeding a predicated instruction \p PredInst. The instructions to
/// scalarize and their scalar costs are collected in \p ScalarCosts. A
/// non-negative return value implies the expression will be scalarized.
/// Currently, only single-use chains are considered for scalarization.
int computePredInstDiscount(Instruction *PredInst, ScalarCostsTy &ScalarCosts,
- ElementCount VF);
+ ElementCount VF);
/// Collect the instructions that are uniform after vectorization. An
/// instruction is uniform if we represent it with a single scalar value in
@@ -1759,28 +1759,28 @@ private:
/// scalarized instruction will be represented by VF scalar values in the
/// vectorized loop, each corresponding to an iteration of the original
/// scalar loop.
- void collectLoopUniforms(ElementCount VF);
+ void collectLoopUniforms(ElementCount VF);
/// Collect the instructions that are scalar after vectorization. An
/// instruction is scalar if it is known to be uniform or will be scalarized
/// during vectorization. Non-uniform scalarized instructions will be
/// represented by VF values in the vectorized loop, each corresponding to an
/// iteration of the original scalar loop.
- void collectLoopScalars(ElementCount VF);
+ void collectLoopScalars(ElementCount VF);
/// Keeps cost model vectorization decision and cost for instructions.
/// Right now it is used for memory instructions only.
- using DecisionList = DenseMap<std::pair<Instruction *, ElementCount>,
- std::pair<InstWidening, InstructionCost>>;
+ using DecisionList = DenseMap<std::pair<Instruction *, ElementCount>,
+ std::pair<InstWidening, InstructionCost>>;
DecisionList WideningDecisions;
/// Returns true if \p V is expected to be vectorized and it needs to be
/// extracted.
- bool needsExtract(Value *V, ElementCount VF) const {
+ bool needsExtract(Value *V, ElementCount VF) const {
Instruction *I = dyn_cast<Instruction>(V);
- if (VF.isScalar() || !I || !TheLoop->contains(I) ||
- TheLoop->isLoopInvariant(I))
+ if (VF.isScalar() || !I || !TheLoop->contains(I) ||
+ TheLoop->isLoopInvariant(I))
return false;
// Assume we can vectorize V (and hence we need extraction) if the
@@ -1795,21 +1795,21 @@ private:
/// Returns a range containing only operands needing to be extracted.
SmallVector<Value *, 4> filterExtractingOperands(Instruction::op_range Ops,
- ElementCount VF) {
+ ElementCount VF) {
return SmallVector<Value *, 4>(make_filter_range(
Ops, [this, VF](Value *V) { return this->needsExtract(V, VF); }));
}
- /// Determines if we have the infrastructure to vectorize loop \p L and its
- /// epilogue, assuming the main loop is vectorized by \p VF.
- bool isCandidateForEpilogueVectorization(const Loop &L,
- const ElementCount VF) const;
-
- /// Returns true if epilogue vectorization is considered profitable, and
- /// false otherwise.
- /// \p VF is the vectorization factor chosen for the original loop.
- bool isEpilogueVectorizationProfitable(const ElementCount VF) const;
-
+ /// Determines if we have the infrastructure to vectorize loop \p L and its
+ /// epilogue, assuming the main loop is vectorized by \p VF.
+ bool isCandidateForEpilogueVectorization(const Loop &L,
+ const ElementCount VF) const;
+
+ /// Returns true if epilogue vectorization is considered profitable, and
+ /// false otherwise.
+ /// \p VF is the vectorization factor chosen for the original loop.
+ bool isEpilogueVectorizationProfitable(const ElementCount VF) const;
+
public:
/// The loop that we evaluate.
Loop *TheLoop;
@@ -1852,9 +1852,9 @@ public:
/// Values to ignore in the cost model when VF > 1.
SmallPtrSet<const Value *, 16> VecValuesToIgnore;
-
- /// Profitable vector factors.
- SmallVector<VectorizationFactor, 8> ProfitableVFs;
+
+ /// Profitable vector factors.
+ SmallVector<VectorizationFactor, 8> ProfitableVFs;
};
} // end namespace llvm
@@ -1875,7 +1875,7 @@ public:
// representation for pragma 'omp simd' is introduced.
static bool isExplicitVecOuterLoop(Loop *OuterLp,
OptimizationRemarkEmitter *ORE) {
- assert(!OuterLp->isInnermost() && "This is not an outer loop");
+ assert(!OuterLp->isInnermost() && "This is not an outer loop");
LoopVectorizeHints Hints(OuterLp, true /*DisableInterleaving*/, *ORE);
// Only outer loops with an explicit vectorization hint are supported.
@@ -1908,7 +1908,7 @@ static void collectSupportedLoops(Loop &L, LoopInfo *LI,
// now, only collect outer loops that have explicit vectorization hints. If we
// are stress testing the VPlan H-CFG construction, we collect the outermost
// loop of every loop nest.
- if (L.isInnermost() || VPlanBuildStressTest ||
+ if (L.isInnermost() || VPlanBuildStressTest ||
(EnableVPlanNativePath && isExplicitVecOuterLoop(&L, ORE))) {
LoopBlocksRPO RPOT(&L);
RPOT.perform(LI);
@@ -2022,8 +2022,8 @@ Value *InnerLoopVectorizer::getBroadcastInstrs(Value *V) {
}
void InnerLoopVectorizer::createVectorIntOrFpInductionPHI(
- const InductionDescriptor &II, Value *Step, Value *Start,
- Instruction *EntryVal) {
+ const InductionDescriptor &II, Value *Step, Value *Start,
+ Instruction *EntryVal) {
assert((isa<PHINode>(EntryVal) || isa<TruncInst>(EntryVal)) &&
"Expected either an induction phi-node or a truncate of it!");
@@ -2055,8 +2055,8 @@ void InnerLoopVectorizer::createVectorIntOrFpInductionPHI(
// Multiply the vectorization factor by the step using integer or
// floating-point arithmetic as appropriate.
- Value *ConstVF =
- getSignedIntOrFpConstant(Step->getType(), VF.getKnownMinValue());
+ Value *ConstVF =
+ getSignedIntOrFpConstant(Step->getType(), VF.getKnownMinValue());
Value *Mul = addFastMathFlag(Builder.CreateBinOp(MulOp, Step, ConstVF));
// Create a vector splat to use in the induction update.
@@ -2064,10 +2064,10 @@ void InnerLoopVectorizer::createVectorIntOrFpInductionPHI(
// FIXME: If the step is non-constant, we create the vector splat with
// IRBuilder. IRBuilder can constant-fold the multiply, but it doesn't
// handle a constant vector splat.
- assert(!VF.isScalable() && "scalable vectors not yet supported.");
- Value *SplatVF = isa<Constant>(Mul)
- ? ConstantVector::getSplat(VF, cast<Constant>(Mul))
- : Builder.CreateVectorSplat(VF, Mul);
+ assert(!VF.isScalable() && "scalable vectors not yet supported.");
+ Value *SplatVF = isa<Constant>(Mul)
+ ? ConstantVector::getSplat(VF, cast<Constant>(Mul))
+ : Builder.CreateVectorSplat(VF, Mul);
Builder.restoreIP(CurrIP);
// We may need to add the step a number of times, depending on the unroll
@@ -2143,8 +2143,8 @@ void InnerLoopVectorizer::recordVectorLoopValueForInductionCast(
VectorLoopValueMap.setVectorValue(CastInst, Part, VectorLoopVal);
}
-void InnerLoopVectorizer::widenIntOrFpInduction(PHINode *IV, Value *Start,
- TruncInst *Trunc) {
+void InnerLoopVectorizer::widenIntOrFpInduction(PHINode *IV, Value *Start,
+ TruncInst *Trunc) {
assert((IV->getType()->isIntegerTy() || IV != OldInduction) &&
"Primary induction variable must have an integer type");
@@ -2202,10 +2202,10 @@ void InnerLoopVectorizer::widenIntOrFpInduction(PHINode *IV, Value *Start,
auto CreateSplatIV = [&](Value *ScalarIV, Value *Step) {
Value *Broadcasted = getBroadcastInstrs(ScalarIV);
for (unsigned Part = 0; Part < UF; ++Part) {
- assert(!VF.isScalable() && "scalable vectors not yet supported.");
+ assert(!VF.isScalable() && "scalable vectors not yet supported.");
Value *EntryPart =
- getStepVector(Broadcasted, VF.getKnownMinValue() * Part, Step,
- ID.getInductionOpcode());
+ getStepVector(Broadcasted, VF.getKnownMinValue() * Part, Step,
+ ID.getInductionOpcode());
VectorLoopValueMap.setVectorValue(EntryVal, Part, EntryPart);
if (Trunc)
addMetadata(EntryPart, Trunc);
@@ -2215,7 +2215,7 @@ void InnerLoopVectorizer::widenIntOrFpInduction(PHINode *IV, Value *Start,
// Now do the actual transformations, and start with creating the step value.
Value *Step = CreateStepValue(ID.getStep());
- if (VF.isZero() || VF.isScalar()) {
+ if (VF.isZero() || VF.isScalar()) {
Value *ScalarIV = CreateScalarIV(Step);
CreateSplatIV(ScalarIV, Step);
return;
@@ -2226,7 +2226,7 @@ void InnerLoopVectorizer::widenIntOrFpInduction(PHINode *IV, Value *Start,
// least one user in the loop that is not widened.
auto NeedsScalarIV = needsScalarInduction(EntryVal);
if (!NeedsScalarIV) {
- createVectorIntOrFpInductionPHI(ID, Step, Start, EntryVal);
+ createVectorIntOrFpInductionPHI(ID, Step, Start, EntryVal);
return;
}
@@ -2234,7 +2234,7 @@ void InnerLoopVectorizer::widenIntOrFpInduction(PHINode *IV, Value *Start,
// create the phi node, we will splat the scalar induction variable in each
// loop iteration.
if (!shouldScalarizeInstruction(EntryVal)) {
- createVectorIntOrFpInductionPHI(ID, Step, Start, EntryVal);
+ createVectorIntOrFpInductionPHI(ID, Step, Start, EntryVal);
Value *ScalarIV = CreateScalarIV(Step);
// Create scalar steps that can be used by instructions we will later
// scalarize. Note that the addition of the scalar steps will not increase
@@ -2256,7 +2256,7 @@ void InnerLoopVectorizer::widenIntOrFpInduction(PHINode *IV, Value *Start,
Value *InnerLoopVectorizer::getStepVector(Value *Val, int StartIdx, Value *Step,
Instruction::BinaryOps BinOp) {
// Create and check the types.
- auto *ValVTy = cast<FixedVectorType>(Val->getType());
+ auto *ValVTy = cast<FixedVectorType>(Val->getType());
int VLen = ValVTy->getNumElements();
Type *STy = Val->getType()->getScalarType();
@@ -2313,7 +2313,7 @@ void InnerLoopVectorizer::buildScalarSteps(Value *ScalarIV, Value *Step,
Instruction *EntryVal,
const InductionDescriptor &ID) {
// We shouldn't have to build scalar steps if we aren't vectorizing.
- assert(VF.isVector() && "VF should be greater than one");
+ assert(VF.isVector() && "VF should be greater than one");
// Get the value type and ensure it and the step have the same integer type.
Type *ScalarIVTy = ScalarIV->getType()->getScalarType();
assert(ScalarIVTy == Step->getType() &&
@@ -2335,27 +2335,27 @@ void InnerLoopVectorizer::buildScalarSteps(Value *ScalarIV, Value *Step,
// iteration. If EntryVal is uniform, we only need to generate the first
// lane. Otherwise, we generate all VF values.
unsigned Lanes =
- Cost->isUniformAfterVectorization(cast<Instruction>(EntryVal), VF)
- ? 1
- : VF.getKnownMinValue();
- assert((!VF.isScalable() || Lanes == 1) &&
- "Should never scalarize a scalable vector");
+ Cost->isUniformAfterVectorization(cast<Instruction>(EntryVal), VF)
+ ? 1
+ : VF.getKnownMinValue();
+ assert((!VF.isScalable() || Lanes == 1) &&
+ "Should never scalarize a scalable vector");
// Compute the scalar steps and save the results in VectorLoopValueMap.
for (unsigned Part = 0; Part < UF; ++Part) {
for (unsigned Lane = 0; Lane < Lanes; ++Lane) {
- auto *IntStepTy = IntegerType::get(ScalarIVTy->getContext(),
- ScalarIVTy->getScalarSizeInBits());
- Value *StartIdx =
- createStepForVF(Builder, ConstantInt::get(IntStepTy, Part), VF);
- if (ScalarIVTy->isFloatingPointTy())
- StartIdx = Builder.CreateSIToFP(StartIdx, ScalarIVTy);
- StartIdx = addFastMathFlag(Builder.CreateBinOp(
- AddOp, StartIdx, getSignedIntOrFpConstant(ScalarIVTy, Lane)));
- // The step returned by `createStepForVF` is a runtime-evaluated value
- // when VF is scalable. Otherwise, it should be folded into a Constant.
- assert((VF.isScalable() || isa<Constant>(StartIdx)) &&
- "Expected StartIdx to be folded to a constant when VF is not "
- "scalable");
+ auto *IntStepTy = IntegerType::get(ScalarIVTy->getContext(),
+ ScalarIVTy->getScalarSizeInBits());
+ Value *StartIdx =
+ createStepForVF(Builder, ConstantInt::get(IntStepTy, Part), VF);
+ if (ScalarIVTy->isFloatingPointTy())
+ StartIdx = Builder.CreateSIToFP(StartIdx, ScalarIVTy);
+ StartIdx = addFastMathFlag(Builder.CreateBinOp(
+ AddOp, StartIdx, getSignedIntOrFpConstant(ScalarIVTy, Lane)));
+ // The step returned by `createStepForVF` is a runtime-evaluated value
+ // when VF is scalable. Otherwise, it should be folded into a Constant.
+ assert((VF.isScalable() || isa<Constant>(StartIdx)) &&
+ "Expected StartIdx to be folded to a constant when VF is not "
+ "scalable");
auto *Mul = addFastMathFlag(Builder.CreateBinOp(MulOp, StartIdx, Step));
auto *Add = addFastMathFlag(Builder.CreateBinOp(AddOp, ScalarIV, Mul));
VectorLoopValueMap.setScalarValue(EntryVal, {Part, Lane}, Add);
@@ -2389,7 +2389,7 @@ Value *InnerLoopVectorizer::getOrCreateVectorValue(Value *V, unsigned Part) {
// If we aren't vectorizing, we can just copy the scalar map values over to
// the vector map.
- if (VF.isScalar()) {
+ if (VF.isScalar()) {
VectorLoopValueMap.setVectorValue(V, Part, ScalarValue);
return ScalarValue;
}
@@ -2398,11 +2398,11 @@ Value *InnerLoopVectorizer::getOrCreateVectorValue(Value *V, unsigned Part) {
// is known to be uniform after vectorization, this corresponds to lane zero
// of the Part unroll iteration. Otherwise, the last instruction is the one
// we created for the last vector lane of the Part unroll iteration.
- unsigned LastLane = Cost->isUniformAfterVectorization(I, VF)
- ? 0
- : VF.getKnownMinValue() - 1;
- assert((!VF.isScalable() || LastLane == 0) &&
- "Scalable vectorization can't lead to any scalarized values.");
+ unsigned LastLane = Cost->isUniformAfterVectorization(I, VF)
+ ? 0
+ : VF.getKnownMinValue() - 1;
+ assert((!VF.isScalable() || LastLane == 0) &&
+ "Scalable vectorization can't lead to any scalarized values.");
auto *LastInst = cast<Instruction>(
VectorLoopValueMap.getScalarValue(V, {Part, LastLane}));
@@ -2423,11 +2423,11 @@ Value *InnerLoopVectorizer::getOrCreateVectorValue(Value *V, unsigned Part) {
VectorValue = getBroadcastInstrs(ScalarValue);
VectorLoopValueMap.setVectorValue(V, Part, VectorValue);
} else {
- // Initialize packing with insertelements to start from poison.
- assert(!VF.isScalable() && "VF is assumed to be non scalable.");
- Value *Poison = PoisonValue::get(VectorType::get(V->getType(), VF));
- VectorLoopValueMap.setVectorValue(V, Part, Poison);
- for (unsigned Lane = 0; Lane < VF.getKnownMinValue(); ++Lane)
+ // Initialize packing with insertelements to start from poison.
+ assert(!VF.isScalable() && "VF is assumed to be non scalable.");
+ Value *Poison = PoisonValue::get(VectorType::get(V->getType(), VF));
+ VectorLoopValueMap.setVectorValue(V, Part, Poison);
+ for (unsigned Lane = 0; Lane < VF.getKnownMinValue(); ++Lane)
packScalarIntoVectorValue(V, {Part, Lane});
VectorValue = VectorLoopValueMap.getVectorValue(V, Part);
}
@@ -2466,7 +2466,7 @@ InnerLoopVectorizer::getOrCreateScalarValue(Value *V,
// extractelement instruction.
auto *U = getOrCreateVectorValue(V, Instance.Part);
if (!U->getType()->isVectorTy()) {
- assert(VF.isScalar() && "Value not scalarized has non-vector type");
+ assert(VF.isScalar() && "Value not scalarized has non-vector type");
return U;
}
@@ -2491,12 +2491,12 @@ void InnerLoopVectorizer::packScalarIntoVectorValue(
Value *InnerLoopVectorizer::reverseVector(Value *Vec) {
assert(Vec->getType()->isVectorTy() && "Invalid type");
- assert(!VF.isScalable() && "Cannot reverse scalable vectors");
+ assert(!VF.isScalable() && "Cannot reverse scalable vectors");
SmallVector<int, 8> ShuffleMask;
- for (unsigned i = 0; i < VF.getKnownMinValue(); ++i)
- ShuffleMask.push_back(VF.getKnownMinValue() - i - 1);
+ for (unsigned i = 0; i < VF.getKnownMinValue(); ++i)
+ ShuffleMask.push_back(VF.getKnownMinValue() - i - 1);
- return Builder.CreateShuffleVector(Vec, ShuffleMask, "reverse");
+ return Builder.CreateShuffleVector(Vec, ShuffleMask, "reverse");
}
// Return whether we allow using masked interleave-groups (for dealing with
@@ -2521,9 +2521,9 @@ static bool useMaskedInterleavedAccesses(const TargetTransformInfo &TTI) {
// }
// To:
// %wide.vec = load <12 x i32> ; Read 4 tuples of R,G,B
-// %R.vec = shuffle %wide.vec, poison, <0, 3, 6, 9> ; R elements
-// %G.vec = shuffle %wide.vec, poison, <1, 4, 7, 10> ; G elements
-// %B.vec = shuffle %wide.vec, poison, <2, 5, 8, 11> ; B elements
+// %R.vec = shuffle %wide.vec, poison, <0, 3, 6, 9> ; R elements
+// %G.vec = shuffle %wide.vec, poison, <1, 4, 7, 10> ; G elements
+// %B.vec = shuffle %wide.vec, poison, <2, 5, 8, 11> ; B elements
//
// Or translate following interleaved store group (factor = 3):
// for (i = 0; i < N; i+=3) {
@@ -2534,22 +2534,22 @@ static bool useMaskedInterleavedAccesses(const TargetTransformInfo &TTI) {
// }
// To:
// %R_G.vec = shuffle %R.vec, %G.vec, <0, 1, 2, ..., 7>
-// %B_U.vec = shuffle %B.vec, poison, <0, 1, 2, 3, u, u, u, u>
+// %B_U.vec = shuffle %B.vec, poison, <0, 1, 2, 3, u, u, u, u>
// %interleaved.vec = shuffle %R_G.vec, %B_U.vec,
// <0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11> ; Interleave R,G,B elements
// store <12 x i32> %interleaved.vec ; Write 4 tuples of R,G,B
void InnerLoopVectorizer::vectorizeInterleaveGroup(
- const InterleaveGroup<Instruction> *Group, ArrayRef<VPValue *> VPDefs,
- VPTransformState &State, VPValue *Addr, ArrayRef<VPValue *> StoredValues,
- VPValue *BlockInMask) {
+ const InterleaveGroup<Instruction> *Group, ArrayRef<VPValue *> VPDefs,
+ VPTransformState &State, VPValue *Addr, ArrayRef<VPValue *> StoredValues,
+ VPValue *BlockInMask) {
Instruction *Instr = Group->getInsertPos();
const DataLayout &DL = Instr->getModule()->getDataLayout();
// Prepare for the vector type of the interleaved load/store.
Type *ScalarTy = getMemInstValueType(Instr);
unsigned InterleaveFactor = Group->getFactor();
- assert(!VF.isScalable() && "scalable vectors not yet supported.");
- auto *VecTy = VectorType::get(ScalarTy, VF * InterleaveFactor);
+ assert(!VF.isScalable() && "scalable vectors not yet supported.");
+ auto *VecTy = VectorType::get(ScalarTy, VF * InterleaveFactor);
// Prepare for the new pointers.
SmallVector<Value *, 2> AddrParts;
@@ -2565,10 +2565,10 @@ void InnerLoopVectorizer::vectorizeInterleaveGroup(
// pointer operand of the interleaved access is supposed to be uniform. For
// uniform instructions, we're only required to generate a value for the
// first vector lane in each unroll iteration.
- assert(!VF.isScalable() &&
- "scalable vector reverse operation is not implemented");
+ assert(!VF.isScalable() &&
+ "scalable vector reverse operation is not implemented");
if (Group->isReverse())
- Index += (VF.getKnownMinValue() - 1) * Group->getFactor();
+ Index += (VF.getKnownMinValue() - 1) * Group->getFactor();
for (unsigned Part = 0; Part < UF; Part++) {
Value *AddrPart = State.get(Addr, {Part, 0});
@@ -2599,12 +2599,12 @@ void InnerLoopVectorizer::vectorizeInterleaveGroup(
}
setDebugLocFromInst(Builder, Instr);
- Value *PoisonVec = PoisonValue::get(VecTy);
+ Value *PoisonVec = PoisonValue::get(VecTy);
Value *MaskForGaps = nullptr;
if (Group->requiresScalarEpilogue() && !Cost->isScalarEpilogueAllowed()) {
- assert(!VF.isScalable() && "scalable vectors not yet supported.");
- MaskForGaps = createBitMaskForGaps(Builder, VF.getKnownMinValue(), *Group);
+ assert(!VF.isScalable() && "scalable vectors not yet supported.");
+ MaskForGaps = createBitMaskForGaps(Builder, VF.getKnownMinValue(), *Group);
assert(MaskForGaps && "Mask for Gaps is required but it is null");
}
@@ -2620,11 +2620,11 @@ void InnerLoopVectorizer::vectorizeInterleaveGroup(
Value *GroupMask = MaskForGaps;
if (BlockInMask) {
Value *BlockInMaskPart = State.get(BlockInMask, Part);
- assert(!VF.isScalable() && "scalable vectors not yet supported.");
+ assert(!VF.isScalable() && "scalable vectors not yet supported.");
Value *ShuffledMask = Builder.CreateShuffleVector(
- BlockInMaskPart,
- createReplicatedMask(InterleaveFactor, VF.getKnownMinValue()),
- "interleaved.mask");
+ BlockInMaskPart,
+ createReplicatedMask(InterleaveFactor, VF.getKnownMinValue()),
+ "interleaved.mask");
GroupMask = MaskForGaps
? Builder.CreateBinOp(Instruction::And, ShuffledMask,
MaskForGaps)
@@ -2632,7 +2632,7 @@ void InnerLoopVectorizer::vectorizeInterleaveGroup(
}
NewLoad =
Builder.CreateMaskedLoad(AddrParts[Part], Group->getAlign(),
- GroupMask, PoisonVec, "wide.masked.vec");
+ GroupMask, PoisonVec, "wide.masked.vec");
}
else
NewLoad = Builder.CreateAlignedLoad(VecTy, AddrParts[Part],
@@ -2643,7 +2643,7 @@ void InnerLoopVectorizer::vectorizeInterleaveGroup(
// For each member in the group, shuffle out the appropriate data from the
// wide loads.
- unsigned J = 0;
+ unsigned J = 0;
for (unsigned I = 0; I < InterleaveFactor; ++I) {
Instruction *Member = Group->getMember(I);
@@ -2651,33 +2651,33 @@ void InnerLoopVectorizer::vectorizeInterleaveGroup(
if (!Member)
continue;
- assert(!VF.isScalable() && "scalable vectors not yet supported.");
- auto StrideMask =
- createStrideMask(I, InterleaveFactor, VF.getKnownMinValue());
+ assert(!VF.isScalable() && "scalable vectors not yet supported.");
+ auto StrideMask =
+ createStrideMask(I, InterleaveFactor, VF.getKnownMinValue());
for (unsigned Part = 0; Part < UF; Part++) {
Value *StridedVec = Builder.CreateShuffleVector(
- NewLoads[Part], StrideMask, "strided.vec");
+ NewLoads[Part], StrideMask, "strided.vec");
// If this member has different type, cast the result type.
if (Member->getType() != ScalarTy) {
- assert(!VF.isScalable() && "VF is assumed to be non scalable.");
- VectorType *OtherVTy = VectorType::get(Member->getType(), VF);
+ assert(!VF.isScalable() && "VF is assumed to be non scalable.");
+ VectorType *OtherVTy = VectorType::get(Member->getType(), VF);
StridedVec = createBitOrPointerCast(StridedVec, OtherVTy, DL);
}
if (Group->isReverse())
StridedVec = reverseVector(StridedVec);
- State.set(VPDefs[J], Member, StridedVec, Part);
+ State.set(VPDefs[J], Member, StridedVec, Part);
}
- ++J;
+ ++J;
}
return;
}
// The sub vector type for current instruction.
- assert(!VF.isScalable() && "VF is assumed to be non scalable.");
- auto *SubVT = VectorType::get(ScalarTy, VF);
+ assert(!VF.isScalable() && "VF is assumed to be non scalable.");
+ auto *SubVT = VectorType::get(ScalarTy, VF);
// Vectorize the interleaved store group.
for (unsigned Part = 0; Part < UF; Part++) {
@@ -2685,10 +2685,10 @@ void InnerLoopVectorizer::vectorizeInterleaveGroup(
SmallVector<Value *, 4> StoredVecs;
for (unsigned i = 0; i < InterleaveFactor; i++) {
// Interleaved store group doesn't allow a gap, so each index has a member
- assert(Group->getMember(i) && "Fail to get a member from an interleaved store group");
+ assert(Group->getMember(i) && "Fail to get a member from an interleaved store group");
+
+ Value *StoredVec = State.get(StoredValues[i], Part);
- Value *StoredVec = State.get(StoredValues[i], Part);
-
if (Group->isReverse())
StoredVec = reverseVector(StoredVec);
@@ -2704,17 +2704,17 @@ void InnerLoopVectorizer::vectorizeInterleaveGroup(
Value *WideVec = concatenateVectors(Builder, StoredVecs);
// Interleave the elements in the wide vector.
- assert(!VF.isScalable() && "scalable vectors not yet supported.");
+ assert(!VF.isScalable() && "scalable vectors not yet supported.");
Value *IVec = Builder.CreateShuffleVector(
- WideVec, createInterleaveMask(VF.getKnownMinValue(), InterleaveFactor),
+ WideVec, createInterleaveMask(VF.getKnownMinValue(), InterleaveFactor),
"interleaved.vec");
Instruction *NewStoreInstr;
if (BlockInMask) {
Value *BlockInMaskPart = State.get(BlockInMask, Part);
Value *ShuffledMask = Builder.CreateShuffleVector(
- BlockInMaskPart,
- createReplicatedMask(InterleaveFactor, VF.getKnownMinValue()),
+ BlockInMaskPart,
+ createReplicatedMask(InterleaveFactor, VF.getKnownMinValue()),
"interleaved.mask");
NewStoreInstr = Builder.CreateMaskedStore(
IVec, AddrParts[Part], Group->getAlign(), ShuffledMask);
@@ -2727,9 +2727,9 @@ void InnerLoopVectorizer::vectorizeInterleaveGroup(
}
}
-void InnerLoopVectorizer::vectorizeMemoryInstruction(
- Instruction *Instr, VPTransformState &State, VPValue *Def, VPValue *Addr,
- VPValue *StoredValue, VPValue *BlockInMask) {
+void InnerLoopVectorizer::vectorizeMemoryInstruction(
+ Instruction *Instr, VPTransformState &State, VPValue *Def, VPValue *Addr,
+ VPValue *StoredValue, VPValue *BlockInMask) {
// Attempt to issue a wide load.
LoadInst *LI = dyn_cast<LoadInst>(Instr);
StoreInst *SI = dyn_cast<StoreInst>(Instr);
@@ -2746,8 +2746,8 @@ void InnerLoopVectorizer::vectorizeMemoryInstruction(
"CM decision is not to widen the memory instruction");
Type *ScalarDataTy = getMemInstValueType(Instr);
-
- auto *DataTy = VectorType::get(ScalarDataTy, VF);
+
+ auto *DataTy = VectorType::get(ScalarDataTy, VF);
const Align Alignment = getLoadStoreAlignment(Instr);
// Determine if the pointer operand of the access is either consecutive or
@@ -2779,23 +2779,23 @@ void InnerLoopVectorizer::vectorizeMemoryInstruction(
InBounds = gep->isInBounds();
if (Reverse) {
- assert(!VF.isScalable() &&
- "Reversing vectors is not yet supported for scalable vectors.");
-
+ assert(!VF.isScalable() &&
+ "Reversing vectors is not yet supported for scalable vectors.");
+
// If the address is consecutive but reversed, then the
// wide store needs to start at the last vector element.
- PartPtr = cast<GetElementPtrInst>(Builder.CreateGEP(
- ScalarDataTy, Ptr, Builder.getInt32(-Part * VF.getKnownMinValue())));
+ PartPtr = cast<GetElementPtrInst>(Builder.CreateGEP(
+ ScalarDataTy, Ptr, Builder.getInt32(-Part * VF.getKnownMinValue())));
PartPtr->setIsInBounds(InBounds);
- PartPtr = cast<GetElementPtrInst>(Builder.CreateGEP(
- ScalarDataTy, PartPtr, Builder.getInt32(1 - VF.getKnownMinValue())));
+ PartPtr = cast<GetElementPtrInst>(Builder.CreateGEP(
+ ScalarDataTy, PartPtr, Builder.getInt32(1 - VF.getKnownMinValue())));
PartPtr->setIsInBounds(InBounds);
if (isMaskRequired) // Reverse of a null all-one mask is a null mask.
BlockInMaskParts[Part] = reverseVector(BlockInMaskParts[Part]);
} else {
- Value *Increment = createStepForVF(Builder, Builder.getInt32(Part), VF);
+ Value *Increment = createStepForVF(Builder, Builder.getInt32(Part), VF);
PartPtr = cast<GetElementPtrInst>(
- Builder.CreateGEP(ScalarDataTy, Ptr, Increment));
+ Builder.CreateGEP(ScalarDataTy, Ptr, Increment));
PartPtr->setIsInBounds(InBounds);
}
@@ -2850,7 +2850,7 @@ void InnerLoopVectorizer::vectorizeMemoryInstruction(
auto *VecPtr = CreateVecPtr(Part, State.get(Addr, {0, 0}));
if (isMaskRequired)
NewLI = Builder.CreateMaskedLoad(
- VecPtr, Alignment, BlockInMaskParts[Part], PoisonValue::get(DataTy),
+ VecPtr, Alignment, BlockInMaskParts[Part], PoisonValue::get(DataTy),
"wide.masked.load");
else
NewLI =
@@ -2861,8 +2861,8 @@ void InnerLoopVectorizer::vectorizeMemoryInstruction(
if (Reverse)
NewLI = reverseVector(NewLI);
}
-
- State.set(Def, Instr, NewLI, Part);
+
+ State.set(Def, Instr, NewLI, Part);
}
}
@@ -2872,12 +2872,12 @@ void InnerLoopVectorizer::scalarizeInstruction(Instruction *Instr, VPUser &User,
VPTransformState &State) {
assert(!Instr->getType()->isAggregateType() && "Can't handle vectors");
- // llvm.experimental.noalias.scope.decl intrinsics must only be duplicated for
- // the first lane and part.
- if (isa<NoAliasScopeDeclInst>(Instr))
- if (Instance.Lane != 0 || Instance.Part != 0)
- return;
-
+ // llvm.experimental.noalias.scope.decl intrinsics must only be duplicated for
+ // the first lane and part.
+ if (isa<NoAliasScopeDeclInst>(Instr))
+ if (Instance.Lane != 0 || Instance.Part != 0)
+ return;
+
setDebugLocFromInst(Builder, Instr);
// Does this instruction return a value ?
@@ -2890,12 +2890,12 @@ void InnerLoopVectorizer::scalarizeInstruction(Instruction *Instr, VPUser &User,
// Replace the operands of the cloned instructions with their scalar
// equivalents in the new loop.
for (unsigned op = 0, e = User.getNumOperands(); op != e; ++op) {
- auto *Operand = dyn_cast<Instruction>(Instr->getOperand(op));
- auto InputInstance = Instance;
- if (!Operand || !OrigLoop->contains(Operand) ||
- (Cost->isUniformAfterVectorization(Operand, State.VF)))
- InputInstance.Lane = 0;
- auto *NewOp = State.get(User.getOperand(op), InputInstance);
+ auto *Operand = dyn_cast<Instruction>(Instr->getOperand(op));
+ auto InputInstance = Instance;
+ if (!Operand || !OrigLoop->contains(Operand) ||
+ (Cost->isUniformAfterVectorization(Operand, State.VF)))
+ InputInstance.Lane = 0;
+ auto *NewOp = State.get(User.getOperand(op), InputInstance);
Cloned->setOperand(op, NewOp);
}
addNewMetadata(Cloned, Instr);
@@ -2903,9 +2903,9 @@ void InnerLoopVectorizer::scalarizeInstruction(Instruction *Instr, VPUser &User,
// Place the cloned scalar in the new loop.
Builder.Insert(Cloned);
- // TODO: Set result for VPValue of VPReciplicateRecipe. This requires
- // representing scalar values in VPTransformState. Add the cloned scalar to
- // the scalar map entry.
+ // TODO: Set result for VPValue of VPReciplicateRecipe. This requires
+ // representing scalar values in VPTransformState. Add the cloned scalar to
+ // the scalar map entry.
VectorLoopValueMap.setScalarValue(Instr, Instance, Cloned);
// If we just cloned a new assumption, add it the assumption cache.
@@ -2942,7 +2942,7 @@ PHINode *InnerLoopVectorizer::createInductionVariable(Loop *L, Value *Start,
Induction->addIncoming(Next, Latch);
// Create the compare.
Value *ICmp = Builder.CreateICmpEQ(Next, End);
- Builder.CreateCondBr(ICmp, L->getUniqueExitBlock(), Header);
+ Builder.CreateCondBr(ICmp, L->getUniqueExitBlock(), Header);
// Now we have two terminators. Remove the old one from the block.
Latch->getTerminator()->eraseFromParent();
@@ -2959,7 +2959,7 @@ Value *InnerLoopVectorizer::getOrCreateTripCount(Loop *L) {
// Find the loop boundaries.
ScalarEvolution *SE = PSE.getSE();
const SCEV *BackedgeTakenCount = PSE.getBackedgeTakenCount();
- assert(!isa<SCEVCouldNotCompute>(BackedgeTakenCount) &&
+ assert(!isa<SCEVCouldNotCompute>(BackedgeTakenCount) &&
"Invalid loop count");
Type *IdxTy = Legal->getWidestInductionType();
@@ -3005,8 +3005,8 @@ Value *InnerLoopVectorizer::getOrCreateVectorTripCount(Loop *L) {
IRBuilder<> Builder(L->getLoopPreheader()->getTerminator());
Type *Ty = TC->getType();
- // This is where we can make the step a runtime constant.
- Value *Step = createStepForVF(Builder, ConstantInt::get(Ty, UF), VF);
+ // This is where we can make the step a runtime constant.
+ Value *Step = createStepForVF(Builder, ConstantInt::get(Ty, UF), VF);
// If the tail is to be folded by masking, round the number of iterations N
// up to a multiple of Step instead of rounding down. This is done by first
@@ -3015,12 +3015,12 @@ Value *InnerLoopVectorizer::getOrCreateVectorTripCount(Loop *L) {
// that it starts at zero and its Step is a power of two; the loop will then
// exit, with the last early-exit vector comparison also producing all-true.
if (Cost->foldTailByMasking()) {
- assert(isPowerOf2_32(VF.getKnownMinValue() * UF) &&
+ assert(isPowerOf2_32(VF.getKnownMinValue() * UF) &&
"VF*UF must be a power of 2 when folding tail by masking");
- assert(!VF.isScalable() &&
- "Tail folding not yet supported for scalable vectors");
- TC = Builder.CreateAdd(
- TC, ConstantInt::get(Ty, VF.getKnownMinValue() * UF - 1), "n.rnd.up");
+ assert(!VF.isScalable() &&
+ "Tail folding not yet supported for scalable vectors");
+ TC = Builder.CreateAdd(
+ TC, ConstantInt::get(Ty, VF.getKnownMinValue() * UF - 1), "n.rnd.up");
}
// Now we need to generate the expression for the part of the loop that the
@@ -3030,18 +3030,18 @@ Value *InnerLoopVectorizer::getOrCreateVectorTripCount(Loop *L) {
// unroll factor (number of SIMD instructions).
Value *R = Builder.CreateURem(TC, Step, "n.mod.vf");
- // There are two cases where we need to ensure (at least) the last iteration
- // runs in the scalar remainder loop. Thus, if the step evenly divides
+ // There are two cases where we need to ensure (at least) the last iteration
+ // runs in the scalar remainder loop. Thus, if the step evenly divides
// the trip count, we set the remainder to be equal to the step. If the step
// does not evenly divide the trip count, no adjustment is necessary since
// there will already be scalar iterations. Note that the minimum iterations
- // check ensures that N >= Step. The cases are:
- // 1) If there is a non-reversed interleaved group that may speculatively
- // access memory out-of-bounds.
- // 2) If any instruction may follow a conditionally taken exit. That is, if
- // the loop contains multiple exiting blocks, or a single exiting block
- // which is not the latch.
- if (VF.isVector() && Cost->requiresScalarEpilogue()) {
+ // check ensures that N >= Step. The cases are:
+ // 1) If there is a non-reversed interleaved group that may speculatively
+ // access memory out-of-bounds.
+ // 2) If any instruction may follow a conditionally taken exit. That is, if
+ // the loop contains multiple exiting blocks, or a single exiting block
+ // which is not the latch.
+ if (VF.isVector() && Cost->requiresScalarEpilogue()) {
auto *IsZero = Builder.CreateICmpEQ(R, ConstantInt::get(R->getType(), 0));
R = Builder.CreateSelect(IsZero, Step, R);
}
@@ -3054,18 +3054,18 @@ Value *InnerLoopVectorizer::getOrCreateVectorTripCount(Loop *L) {
Value *InnerLoopVectorizer::createBitOrPointerCast(Value *V, VectorType *DstVTy,
const DataLayout &DL) {
// Verify that V is a vector type with same number of elements as DstVTy.
- auto *DstFVTy = cast<FixedVectorType>(DstVTy);
- unsigned VF = DstFVTy->getNumElements();
- auto *SrcVecTy = cast<FixedVectorType>(V->getType());
+ auto *DstFVTy = cast<FixedVectorType>(DstVTy);
+ unsigned VF = DstFVTy->getNumElements();
+ auto *SrcVecTy = cast<FixedVectorType>(V->getType());
assert((VF == SrcVecTy->getNumElements()) && "Vector dimensions do not match");
Type *SrcElemTy = SrcVecTy->getElementType();
- Type *DstElemTy = DstFVTy->getElementType();
+ Type *DstElemTy = DstFVTy->getElementType();
assert((DL.getTypeSizeInBits(SrcElemTy) == DL.getTypeSizeInBits(DstElemTy)) &&
"Vector elements must have same size");
// Do a direct cast if element types are castable.
if (CastInst::isBitOrNoopPointerCastable(SrcElemTy, DstElemTy, DL)) {
- return Builder.CreateBitOrPointerCast(V, DstFVTy);
+ return Builder.CreateBitOrPointerCast(V, DstFVTy);
}
// V cannot be directly casted to desired vector type.
// May happen when V is a floating point vector but DstVTy is a vector of
@@ -3079,7 +3079,7 @@ Value *InnerLoopVectorizer::createBitOrPointerCast(Value *V, VectorType *DstVTy,
IntegerType::getIntNTy(V->getContext(), DL.getTypeSizeInBits(SrcElemTy));
auto *VecIntTy = FixedVectorType::get(IntTy, VF);
Value *CastVal = Builder.CreateBitOrPointerCast(V, VecIntTy);
- return Builder.CreateBitOrPointerCast(CastVal, DstFVTy);
+ return Builder.CreateBitOrPointerCast(CastVal, DstFVTy);
}
void InnerLoopVectorizer::emitMinimumIterationCountCheck(Loop *L,
@@ -3100,11 +3100,11 @@ void InnerLoopVectorizer::emitMinimumIterationCountCheck(Loop *L,
// If tail is to be folded, vector loop takes care of all iterations.
Value *CheckMinIters = Builder.getFalse();
- if (!Cost->foldTailByMasking()) {
- Value *Step =
- createStepForVF(Builder, ConstantInt::get(Count->getType(), UF), VF);
- CheckMinIters = Builder.CreateICmp(P, Count, Step, "min.iters.check");
- }
+ if (!Cost->foldTailByMasking()) {
+ Value *Step =
+ createStepForVF(Builder, ConstantInt::get(Count->getType(), UF), VF);
+ CheckMinIters = Builder.CreateICmp(P, Count, Step, "min.iters.check");
+ }
// Create new preheader for vector loop.
LoopVectorPreHeader =
SplitBlock(TCCheckBlock, TCCheckBlock->getTerminator(), DT, LI, nullptr,
@@ -3141,9 +3141,9 @@ void InnerLoopVectorizer::emitSCEVChecks(Loop *L, BasicBlock *Bypass) {
if (C->isZero())
return;
- assert(!(SCEVCheckBlock->getParent()->hasOptSize() ||
- (OptForSizeBasedOnProfile &&
- Cost->Hints->getForce() != LoopVectorizeHints::FK_Enabled)) &&
+ assert(!(SCEVCheckBlock->getParent()->hasOptSize() ||
+ (OptForSizeBasedOnProfile &&
+ Cost->Hints->getForce() != LoopVectorizeHints::FK_Enabled)) &&
"Cannot SCEV check stride or overflow when optimizing for size");
SCEVCheckBlock->setName("vector.scevcheck");
@@ -3182,7 +3182,7 @@ void InnerLoopVectorizer::emitMemRuntimeChecks(Loop *L, BasicBlock *Bypass) {
if (!RtPtrChecking.Need)
return;
- if (MemCheckBlock->getParent()->hasOptSize() || OptForSizeBasedOnProfile) {
+ if (MemCheckBlock->getParent()->hasOptSize() || OptForSizeBasedOnProfile) {
assert(Cost->Hints->getForce() == LoopVectorizeHints::FK_Enabled &&
"Cannot emit memory checks when optimizing for size, unless forced "
"to vectorize.");
@@ -3202,33 +3202,33 @@ void InnerLoopVectorizer::emitMemRuntimeChecks(Loop *L, BasicBlock *Bypass) {
SplitBlock(MemCheckBlock, MemCheckBlock->getTerminator(), DT, LI, nullptr,
"vector.ph");
- auto *CondBranch = cast<BranchInst>(
- Builder.CreateCondBr(Builder.getTrue(), Bypass, LoopVectorPreHeader));
- ReplaceInstWithInst(MemCheckBlock->getTerminator(), CondBranch);
- LoopBypassBlocks.push_back(MemCheckBlock);
- AddedSafetyChecks = true;
-
+ auto *CondBranch = cast<BranchInst>(
+ Builder.CreateCondBr(Builder.getTrue(), Bypass, LoopVectorPreHeader));
+ ReplaceInstWithInst(MemCheckBlock->getTerminator(), CondBranch);
+ LoopBypassBlocks.push_back(MemCheckBlock);
+ AddedSafetyChecks = true;
+
// Update dominator only if this is first RT check.
if (LoopBypassBlocks.empty()) {
DT->changeImmediateDominator(Bypass, MemCheckBlock);
DT->changeImmediateDominator(LoopExitBlock, MemCheckBlock);
}
- Instruction *FirstCheckInst;
- Instruction *MemRuntimeCheck;
- std::tie(FirstCheckInst, MemRuntimeCheck) =
- addRuntimeChecks(MemCheckBlock->getTerminator(), OrigLoop,
- RtPtrChecking.getChecks(), RtPtrChecking.getSE());
- assert(MemRuntimeCheck && "no RT checks generated although RtPtrChecking "
- "claimed checks are required");
- CondBranch->setCondition(MemRuntimeCheck);
+ Instruction *FirstCheckInst;
+ Instruction *MemRuntimeCheck;
+ std::tie(FirstCheckInst, MemRuntimeCheck) =
+ addRuntimeChecks(MemCheckBlock->getTerminator(), OrigLoop,
+ RtPtrChecking.getChecks(), RtPtrChecking.getSE());
+ assert(MemRuntimeCheck && "no RT checks generated although RtPtrChecking "
+ "claimed checks are required");
+ CondBranch->setCondition(MemRuntimeCheck);
// We currently don't use LoopVersioning for the actual loop cloning but we
// still use it to add the noalias metadata.
- LVer = std::make_unique<LoopVersioning>(
- *Legal->getLAI(),
- Legal->getLAI()->getRuntimePointerChecking()->getChecks(), OrigLoop, LI,
- DT, PSE.getSE());
+ LVer = std::make_unique<LoopVersioning>(
+ *Legal->getLAI(),
+ Legal->getLAI()->getRuntimePointerChecking()->getChecks(), OrigLoop, LI,
+ DT, PSE.getSE());
LVer->prepareNoAliasMetadata();
}
@@ -3332,35 +3332,35 @@ Value *InnerLoopVectorizer::emitTransformedIndex(
llvm_unreachable("invalid enum");
}
-Loop *InnerLoopVectorizer::createVectorLoopSkeleton(StringRef Prefix) {
+Loop *InnerLoopVectorizer::createVectorLoopSkeleton(StringRef Prefix) {
LoopScalarBody = OrigLoop->getHeader();
LoopVectorPreHeader = OrigLoop->getLoopPreheader();
- LoopExitBlock = OrigLoop->getUniqueExitBlock();
+ LoopExitBlock = OrigLoop->getUniqueExitBlock();
assert(LoopExitBlock && "Must have an exit block");
assert(LoopVectorPreHeader && "Invalid loop structure");
LoopMiddleBlock =
SplitBlock(LoopVectorPreHeader, LoopVectorPreHeader->getTerminator(), DT,
- LI, nullptr, Twine(Prefix) + "middle.block");
+ LI, nullptr, Twine(Prefix) + "middle.block");
LoopScalarPreHeader =
SplitBlock(LoopMiddleBlock, LoopMiddleBlock->getTerminator(), DT, LI,
- nullptr, Twine(Prefix) + "scalar.ph");
-
- // Set up branch from middle block to the exit and scalar preheader blocks.
- // completeLoopSkeleton will update the condition to use an iteration check,
- // if required to decide whether to execute the remainder.
- BranchInst *BrInst =
- BranchInst::Create(LoopExitBlock, LoopScalarPreHeader, Builder.getTrue());
- auto *ScalarLatchTerm = OrigLoop->getLoopLatch()->getTerminator();
- BrInst->setDebugLoc(ScalarLatchTerm->getDebugLoc());
- ReplaceInstWithInst(LoopMiddleBlock->getTerminator(), BrInst);
-
+ nullptr, Twine(Prefix) + "scalar.ph");
+
+ // Set up branch from middle block to the exit and scalar preheader blocks.
+ // completeLoopSkeleton will update the condition to use an iteration check,
+ // if required to decide whether to execute the remainder.
+ BranchInst *BrInst =
+ BranchInst::Create(LoopExitBlock, LoopScalarPreHeader, Builder.getTrue());
+ auto *ScalarLatchTerm = OrigLoop->getLoopLatch()->getTerminator();
+ BrInst->setDebugLoc(ScalarLatchTerm->getDebugLoc());
+ ReplaceInstWithInst(LoopMiddleBlock->getTerminator(), BrInst);
+
// We intentionally don't let SplitBlock to update LoopInfo since
// LoopVectorBody should belong to another loop than LoopVectorPreHeader.
// LoopVectorBody is explicitly added to the correct place few lines later.
LoopVectorBody =
SplitBlock(LoopVectorPreHeader, LoopVectorPreHeader->getTerminator(), DT,
- nullptr, nullptr, Twine(Prefix) + "vector.body");
+ nullptr, nullptr, Twine(Prefix) + "vector.body");
// Update dominator for loop exit.
DT->changeImmediateDominator(LoopExitBlock, LoopMiddleBlock);
@@ -3377,16 +3377,16 @@ Loop *InnerLoopVectorizer::createVectorLoopSkeleton(StringRef Prefix) {
LI->addTopLevelLoop(Lp);
}
Lp->addBasicBlockToLoop(LoopVectorBody, *LI);
- return Lp;
-}
-
-void InnerLoopVectorizer::createInductionResumeValues(
- Loop *L, Value *VectorTripCount,
- std::pair<BasicBlock *, Value *> AdditionalBypass) {
- assert(VectorTripCount && L && "Expected valid arguments");
- assert(((AdditionalBypass.first && AdditionalBypass.second) ||
- (!AdditionalBypass.first && !AdditionalBypass.second)) &&
- "Inconsistent information about additional bypass.");
+ return Lp;
+}
+
+void InnerLoopVectorizer::createInductionResumeValues(
+ Loop *L, Value *VectorTripCount,
+ std::pair<BasicBlock *, Value *> AdditionalBypass) {
+ assert(VectorTripCount && L && "Expected valid arguments");
+ assert(((AdditionalBypass.first && AdditionalBypass.second) ||
+ (!AdditionalBypass.first && !AdditionalBypass.second)) &&
+ "Inconsistent information about additional bypass.");
// We are going to resume the execution of the scalar loop.
// Go over all of the induction variables that we found and fix the
// PHIs that are left in the scalar version of the loop.
@@ -3405,31 +3405,31 @@ void InnerLoopVectorizer::createInductionResumeValues(
// Copy original phi DL over to the new one.
BCResumeVal->setDebugLoc(OrigPhi->getDebugLoc());
Value *&EndValue = IVEndValues[OrigPhi];
- Value *EndValueFromAdditionalBypass = AdditionalBypass.second;
+ Value *EndValueFromAdditionalBypass = AdditionalBypass.second;
if (OrigPhi == OldInduction) {
// We know what the end value is.
- EndValue = VectorTripCount;
+ EndValue = VectorTripCount;
} else {
- IRBuilder<> B(L->getLoopPreheader()->getTerminator());
+ IRBuilder<> B(L->getLoopPreheader()->getTerminator());
Type *StepType = II.getStep()->getType();
Instruction::CastOps CastOp =
- CastInst::getCastOpcode(VectorTripCount, true, StepType, true);
- Value *CRD = B.CreateCast(CastOp, VectorTripCount, StepType, "cast.crd");
+ CastInst::getCastOpcode(VectorTripCount, true, StepType, true);
+ Value *CRD = B.CreateCast(CastOp, VectorTripCount, StepType, "cast.crd");
const DataLayout &DL = LoopScalarBody->getModule()->getDataLayout();
EndValue = emitTransformedIndex(B, CRD, PSE.getSE(), DL, II);
EndValue->setName("ind.end");
-
- // Compute the end value for the additional bypass (if applicable).
- if (AdditionalBypass.first) {
- B.SetInsertPoint(&(*AdditionalBypass.first->getFirstInsertionPt()));
- CastOp = CastInst::getCastOpcode(AdditionalBypass.second, true,
- StepType, true);
- CRD =
- B.CreateCast(CastOp, AdditionalBypass.second, StepType, "cast.crd");
- EndValueFromAdditionalBypass =
- emitTransformedIndex(B, CRD, PSE.getSE(), DL, II);
- EndValueFromAdditionalBypass->setName("ind.end");
- }
+
+ // Compute the end value for the additional bypass (if applicable).
+ if (AdditionalBypass.first) {
+ B.SetInsertPoint(&(*AdditionalBypass.first->getFirstInsertionPt()));
+ CastOp = CastInst::getCastOpcode(AdditionalBypass.second, true,
+ StepType, true);
+ CRD =
+ B.CreateCast(CastOp, AdditionalBypass.second, StepType, "cast.crd");
+ EndValueFromAdditionalBypass =
+ emitTransformedIndex(B, CRD, PSE.getSE(), DL, II);
+ EndValueFromAdditionalBypass->setName("ind.end");
+ }
}
// The new PHI merges the original incoming value, in case of a bypass,
// or the value at the end of the vectorized loop.
@@ -3440,44 +3440,44 @@ void InnerLoopVectorizer::createInductionResumeValues(
// value.
for (BasicBlock *BB : LoopBypassBlocks)
BCResumeVal->addIncoming(II.getStartValue(), BB);
-
- if (AdditionalBypass.first)
- BCResumeVal->setIncomingValueForBlock(AdditionalBypass.first,
- EndValueFromAdditionalBypass);
-
+
+ if (AdditionalBypass.first)
+ BCResumeVal->setIncomingValueForBlock(AdditionalBypass.first,
+ EndValueFromAdditionalBypass);
+
OrigPhi->setIncomingValueForBlock(LoopScalarPreHeader, BCResumeVal);
}
-}
+}
-BasicBlock *InnerLoopVectorizer::completeLoopSkeleton(Loop *L,
- MDNode *OrigLoopID) {
- assert(L && "Expected valid loop.");
+BasicBlock *InnerLoopVectorizer::completeLoopSkeleton(Loop *L,
+ MDNode *OrigLoopID) {
+ assert(L && "Expected valid loop.");
+
+ // The trip counts should be cached by now.
+ Value *Count = getOrCreateTripCount(L);
+ Value *VectorTripCount = getOrCreateVectorTripCount(L);
+
+ auto *ScalarLatchTerm = OrigLoop->getLoopLatch()->getTerminator();
- // The trip counts should be cached by now.
- Value *Count = getOrCreateTripCount(L);
- Value *VectorTripCount = getOrCreateVectorTripCount(L);
-
- auto *ScalarLatchTerm = OrigLoop->getLoopLatch()->getTerminator();
-
// Add a check in the middle block to see if we have completed
// all of the iterations in the first vector loop.
// If (N - N%VF) == N, then we *don't* need to run the remainder.
// If tail is to be folded, we know we don't need to run the remainder.
if (!Cost->foldTailByMasking()) {
- Instruction *CmpN = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ,
- Count, VectorTripCount, "cmp.n",
- LoopMiddleBlock->getTerminator());
+ Instruction *CmpN = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ,
+ Count, VectorTripCount, "cmp.n",
+ LoopMiddleBlock->getTerminator());
- // Here we use the same DebugLoc as the scalar loop latch terminator instead
+ // Here we use the same DebugLoc as the scalar loop latch terminator instead
// of the corresponding compare because they may have ended up with
// different line numbers and we want to avoid awkward line stepping while
// debugging. Eg. if the compare has got a line number inside the loop.
- CmpN->setDebugLoc(ScalarLatchTerm->getDebugLoc());
- cast<BranchInst>(LoopMiddleBlock->getTerminator())->setCondition(CmpN);
+ CmpN->setDebugLoc(ScalarLatchTerm->getDebugLoc());
+ cast<BranchInst>(LoopMiddleBlock->getTerminator())->setCondition(CmpN);
}
// Get ready to start creating new instructions into the vectorized body.
- assert(LoopVectorPreHeader == L->getLoopPreheader() &&
+ assert(LoopVectorPreHeader == L->getLoopPreheader() &&
"Inconsistent vector loop preheader");
Builder.SetInsertPoint(&*LoopVectorBody->getFirstInsertionPt());
@@ -3485,7 +3485,7 @@ BasicBlock *InnerLoopVectorizer::completeLoopSkeleton(Loop *L,
makeFollowupLoopID(OrigLoopID, {LLVMLoopVectorizeFollowupAll,
LLVMLoopVectorizeFollowupVectorized});
if (VectorizedLoopID.hasValue()) {
- L->setLoopID(VectorizedLoopID.getValue());
+ L->setLoopID(VectorizedLoopID.getValue());
// Do not setAlreadyVectorized if loop attributes have been defined
// explicitly.
@@ -3495,9 +3495,9 @@ BasicBlock *InnerLoopVectorizer::completeLoopSkeleton(Loop *L,
// Keep all loop hints from the original loop on the vector loop (we'll
// replace the vectorizer-specific hints below).
if (MDNode *LID = OrigLoop->getLoopID())
- L->setLoopID(LID);
+ L->setLoopID(LID);
- LoopVectorizeHints Hints(L, true, *ORE);
+ LoopVectorizeHints Hints(L, true, *ORE);
Hints.setAlreadyVectorized();
#ifdef EXPENSIVE_CHECKS
@@ -3508,91 +3508,91 @@ BasicBlock *InnerLoopVectorizer::completeLoopSkeleton(Loop *L,
return LoopVectorPreHeader;
}
-BasicBlock *InnerLoopVectorizer::createVectorizedLoopSkeleton() {
- /*
- In this function we generate a new loop. The new loop will contain
- the vectorized instructions while the old loop will continue to run the
- scalar remainder.
-
- [ ] <-- loop iteration number check.
- / |
- / v
- | [ ] <-- vector loop bypass (may consist of multiple blocks).
- | / |
- | / v
- || [ ] <-- vector pre header.
- |/ |
- | v
- | [ ] \
- | [ ]_| <-- vector loop.
- | |
- | v
- | -[ ] <--- middle-block.
- | / |
- | / v
- -|- >[ ] <--- new preheader.
- | |
- | v
- | [ ] \
- | [ ]_| <-- old scalar loop to handle remainder.
- \ |
- \ v
- >[ ] <-- exit block.
- ...
- */
-
- // Get the metadata of the original loop before it gets modified.
- MDNode *OrigLoopID = OrigLoop->getLoopID();
-
- // Create an empty vector loop, and prepare basic blocks for the runtime
- // checks.
- Loop *Lp = createVectorLoopSkeleton("");
-
- // Now, compare the new count to zero. If it is zero skip the vector loop and
- // jump to the scalar loop. This check also covers the case where the
- // backedge-taken count is uint##_max: adding one to it will overflow leading
- // to an incorrect trip count of zero. In this (rare) case we will also jump
- // to the scalar loop.
- emitMinimumIterationCountCheck(Lp, LoopScalarPreHeader);
-
- // Generate the code to check any assumptions that we've made for SCEV
- // expressions.
- emitSCEVChecks(Lp, LoopScalarPreHeader);
-
- // Generate the code that checks in runtime if arrays overlap. We put the
- // checks into a separate block to make the more common case of few elements
- // faster.
- emitMemRuntimeChecks(Lp, LoopScalarPreHeader);
-
- // Some loops have a single integer induction variable, while other loops
- // don't. One example is c++ iterators that often have multiple pointer
- // induction variables. In the code below we also support a case where we
- // don't have a single induction variable.
- //
- // We try to obtain an induction variable from the original loop as hard
- // as possible. However if we don't find one that:
- // - is an integer
- // - counts from zero, stepping by one
- // - is the size of the widest induction variable type
- // then we create a new one.
- OldInduction = Legal->getPrimaryInduction();
- Type *IdxTy = Legal->getWidestInductionType();
- Value *StartIdx = ConstantInt::get(IdxTy, 0);
- // The loop step is equal to the vectorization factor (num of SIMD elements)
- // times the unroll factor (num of SIMD instructions).
- Builder.SetInsertPoint(&*Lp->getHeader()->getFirstInsertionPt());
- Value *Step = createStepForVF(Builder, ConstantInt::get(IdxTy, UF), VF);
- Value *CountRoundDown = getOrCreateVectorTripCount(Lp);
- Induction =
- createInductionVariable(Lp, StartIdx, CountRoundDown, Step,
- getDebugLocFromInstOrOperands(OldInduction));
-
- // Emit phis for the new starting index of the scalar loop.
- createInductionResumeValues(Lp, CountRoundDown);
-
- return completeLoopSkeleton(Lp, OrigLoopID);
-}
-
+BasicBlock *InnerLoopVectorizer::createVectorizedLoopSkeleton() {
+ /*
+ In this function we generate a new loop. The new loop will contain
+ the vectorized instructions while the old loop will continue to run the
+ scalar remainder.
+
+ [ ] <-- loop iteration number check.
+ / |
+ / v
+ | [ ] <-- vector loop bypass (may consist of multiple blocks).
+ | / |
+ | / v
+ || [ ] <-- vector pre header.
+ |/ |
+ | v
+ | [ ] \
+ | [ ]_| <-- vector loop.
+ | |
+ | v
+ | -[ ] <--- middle-block.
+ | / |
+ | / v
+ -|- >[ ] <--- new preheader.
+ | |
+ | v
+ | [ ] \
+ | [ ]_| <-- old scalar loop to handle remainder.
+ \ |
+ \ v
+ >[ ] <-- exit block.
+ ...
+ */
+
+ // Get the metadata of the original loop before it gets modified.
+ MDNode *OrigLoopID = OrigLoop->getLoopID();
+
+ // Create an empty vector loop, and prepare basic blocks for the runtime
+ // checks.
+ Loop *Lp = createVectorLoopSkeleton("");
+
+ // Now, compare the new count to zero. If it is zero skip the vector loop and
+ // jump to the scalar loop. This check also covers the case where the
+ // backedge-taken count is uint##_max: adding one to it will overflow leading
+ // to an incorrect trip count of zero. In this (rare) case we will also jump
+ // to the scalar loop.
+ emitMinimumIterationCountCheck(Lp, LoopScalarPreHeader);
+
+ // Generate the code to check any assumptions that we've made for SCEV
+ // expressions.
+ emitSCEVChecks(Lp, LoopScalarPreHeader);
+
+ // Generate the code that checks in runtime if arrays overlap. We put the
+ // checks into a separate block to make the more common case of few elements
+ // faster.
+ emitMemRuntimeChecks(Lp, LoopScalarPreHeader);
+
+ // Some loops have a single integer induction variable, while other loops
+ // don't. One example is c++ iterators that often have multiple pointer
+ // induction variables. In the code below we also support a case where we
+ // don't have a single induction variable.
+ //
+ // We try to obtain an induction variable from the original loop as hard
+ // as possible. However if we don't find one that:
+ // - is an integer
+ // - counts from zero, stepping by one
+ // - is the size of the widest induction variable type
+ // then we create a new one.
+ OldInduction = Legal->getPrimaryInduction();
+ Type *IdxTy = Legal->getWidestInductionType();
+ Value *StartIdx = ConstantInt::get(IdxTy, 0);
+ // The loop step is equal to the vectorization factor (num of SIMD elements)
+ // times the unroll factor (num of SIMD instructions).
+ Builder.SetInsertPoint(&*Lp->getHeader()->getFirstInsertionPt());
+ Value *Step = createStepForVF(Builder, ConstantInt::get(IdxTy, UF), VF);
+ Value *CountRoundDown = getOrCreateVectorTripCount(Lp);
+ Induction =
+ createInductionVariable(Lp, StartIdx, CountRoundDown, Step,
+ getDebugLocFromInstOrOperands(OldInduction));
+
+ // Emit phis for the new starting index of the scalar loop.
+ createInductionResumeValues(Lp, CountRoundDown);
+
+ return completeLoopSkeleton(Lp, OrigLoopID);
+}
+
// Fix up external users of the induction variable. At this point, we are
// in LCSSA form, with all external PHIs that use the IV having one input value,
// coming from the remainder loop. We need those PHIs to also have a correct
@@ -3606,7 +3606,7 @@ void InnerLoopVectorizer::fixupIVUsers(PHINode *OrigPhi,
// value (the value that feeds into the phi from the loop latch).
// We allow both, but they, obviously, have different values.
- assert(OrigLoop->getUniqueExitBlock() && "Expected a single exit block");
+ assert(OrigLoop->getUniqueExitBlock() && "Expected a single exit block");
DenseMap<Value *, Value *> MissingVals;
@@ -3712,10 +3712,10 @@ static void cse(BasicBlock *BB) {
}
}
-InstructionCost
-LoopVectorizationCostModel::getVectorCallCost(CallInst *CI, ElementCount VF,
- bool &NeedToScalarize) {
- assert(!VF.isScalable() && "scalable vectors not yet supported.");
+InstructionCost
+LoopVectorizationCostModel::getVectorCallCost(CallInst *CI, ElementCount VF,
+ bool &NeedToScalarize) {
+ assert(!VF.isScalable() && "scalable vectors not yet supported.");
Function *F = CI->getCalledFunction();
Type *ScalarRetTy = CI->getType();
SmallVector<Type *, 4> Tys, ScalarTys;
@@ -3726,9 +3726,9 @@ LoopVectorizationCostModel::getVectorCallCost(CallInst *CI, ElementCount VF,
// to be vectors, so we need to extract individual elements from there,
// execute VF scalar calls, and then gather the result into the vector return
// value.
- InstructionCost ScalarCallCost =
- TTI.getCallInstrCost(F, ScalarRetTy, ScalarTys, TTI::TCK_RecipThroughput);
- if (VF.isScalar())
+ InstructionCost ScalarCallCost =
+ TTI.getCallInstrCost(F, ScalarRetTy, ScalarTys, TTI::TCK_RecipThroughput);
+ if (VF.isScalar())
return ScalarCallCost;
// Compute corresponding vector type for return value and arguments.
@@ -3738,33 +3738,33 @@ LoopVectorizationCostModel::getVectorCallCost(CallInst *CI, ElementCount VF,
// Compute costs of unpacking argument values for the scalar calls and
// packing the return values to a vector.
- InstructionCost ScalarizationCost = getScalarizationOverhead(CI, VF);
+ InstructionCost ScalarizationCost = getScalarizationOverhead(CI, VF);
- InstructionCost Cost =
- ScalarCallCost * VF.getKnownMinValue() + ScalarizationCost;
+ InstructionCost Cost =
+ ScalarCallCost * VF.getKnownMinValue() + ScalarizationCost;
// If we can't emit a vector call for this function, then the currently found
// cost is the cost we need to return.
NeedToScalarize = true;
- VFShape Shape = VFShape::get(*CI, VF, false /*HasGlobalPred*/);
+ VFShape Shape = VFShape::get(*CI, VF, false /*HasGlobalPred*/);
Function *VecFunc = VFDatabase(*CI).getVectorizedFunction(Shape);
if (!TLI || CI->isNoBuiltin() || !VecFunc)
return Cost;
// If the corresponding vector cost is cheaper, return its cost.
- InstructionCost VectorCallCost =
- TTI.getCallInstrCost(nullptr, RetTy, Tys, TTI::TCK_RecipThroughput);
+ InstructionCost VectorCallCost =
+ TTI.getCallInstrCost(nullptr, RetTy, Tys, TTI::TCK_RecipThroughput);
if (VectorCallCost < Cost) {
NeedToScalarize = false;
- Cost = VectorCallCost;
+ Cost = VectorCallCost;
}
return Cost;
}
-InstructionCost
-LoopVectorizationCostModel::getVectorIntrinsicCost(CallInst *CI,
- ElementCount VF) {
+InstructionCost
+LoopVectorizationCostModel::getVectorIntrinsicCost(CallInst *CI,
+ ElementCount VF) {
Intrinsic::ID ID = getVectorIntrinsicIDForCall(CI, TLI);
assert(ID && "Expected intrinsic call!");
@@ -3804,8 +3804,8 @@ void InnerLoopVectorizer::truncateToMinimalBitwidths() {
Type *ScalarTruncatedTy =
IntegerType::get(OriginalTy->getContext(), KV.second);
auto *TruncatedTy = FixedVectorType::get(
- ScalarTruncatedTy,
- cast<FixedVectorType>(OriginalTy)->getNumElements());
+ ScalarTruncatedTy,
+ cast<FixedVectorType>(OriginalTy)->getNumElements());
if (TruncatedTy == OriginalTy)
continue;
@@ -3855,13 +3855,13 @@ void InnerLoopVectorizer::truncateToMinimalBitwidths() {
break;
}
} else if (auto *SI = dyn_cast<ShuffleVectorInst>(I)) {
- auto Elements0 = cast<FixedVectorType>(SI->getOperand(0)->getType())
- ->getNumElements();
+ auto Elements0 = cast<FixedVectorType>(SI->getOperand(0)->getType())
+ ->getNumElements();
auto *O0 = B.CreateZExtOrTrunc(
SI->getOperand(0),
FixedVectorType::get(ScalarTruncatedTy, Elements0));
- auto Elements1 = cast<FixedVectorType>(SI->getOperand(1)->getType())
- ->getNumElements();
+ auto Elements1 = cast<FixedVectorType>(SI->getOperand(1)->getType())
+ ->getNumElements();
auto *O1 = B.CreateZExtOrTrunc(
SI->getOperand(1),
FixedVectorType::get(ScalarTruncatedTy, Elements1));
@@ -3871,16 +3871,16 @@ void InnerLoopVectorizer::truncateToMinimalBitwidths() {
// Don't do anything with the operands, just extend the result.
continue;
} else if (auto *IE = dyn_cast<InsertElementInst>(I)) {
- auto Elements = cast<FixedVectorType>(IE->getOperand(0)->getType())
- ->getNumElements();
+ auto Elements = cast<FixedVectorType>(IE->getOperand(0)->getType())
+ ->getNumElements();
auto *O0 = B.CreateZExtOrTrunc(
IE->getOperand(0),
FixedVectorType::get(ScalarTruncatedTy, Elements));
auto *O1 = B.CreateZExtOrTrunc(IE->getOperand(1), ScalarTruncatedTy);
NewI = B.CreateInsertElement(O0, O1, IE->getOperand(2));
} else if (auto *EE = dyn_cast<ExtractElementInst>(I)) {
- auto Elements = cast<FixedVectorType>(EE->getOperand(0)->getType())
- ->getNumElements();
+ auto Elements = cast<FixedVectorType>(EE->getOperand(0)->getType())
+ ->getNumElements();
auto *O0 = B.CreateZExtOrTrunc(
EE->getOperand(0),
FixedVectorType::get(ScalarTruncatedTy, Elements));
@@ -3922,7 +3922,7 @@ void InnerLoopVectorizer::truncateToMinimalBitwidths() {
void InnerLoopVectorizer::fixVectorizedLoop() {
// Insert truncates and extends for any truncated instructions as hints to
// InstCombine.
- if (VF.isVector())
+ if (VF.isVector())
truncateToMinimalBitwidths();
// Fix widened non-induction PHIs by setting up the PHI operands.
@@ -3963,13 +3963,13 @@ void InnerLoopVectorizer::fixVectorizedLoop() {
// profile is not inherently precise anyway. Note also possible bypass of
// vector code caused by legality checks is ignored, assigning all the weight
// to the vector loop, optimistically.
- //
- // For scalable vectorization we can't know at compile time how many iterations
- // of the loop are handled in one vector iteration, so instead assume a pessimistic
- // vscale of '1'.
- setProfileInfoAfterUnrolling(
- LI->getLoopFor(LoopScalarBody), LI->getLoopFor(LoopVectorBody),
- LI->getLoopFor(LoopScalarBody), VF.getKnownMinValue() * UF);
+ //
+ // For scalable vectorization we can't know at compile time how many iterations
+ // of the loop are handled in one vector iteration, so instead assume a pessimistic
+ // vscale of '1'.
+ setProfileInfoAfterUnrolling(
+ LI->getLoopFor(LoopScalarBody), LI->getLoopFor(LoopVectorBody),
+ LI->getLoopFor(LoopScalarBody), VF.getKnownMinValue() * UF);
}
void InnerLoopVectorizer::fixCrossIterationPHIs() {
@@ -4048,12 +4048,12 @@ void InnerLoopVectorizer::fixFirstOrderRecurrence(PHINode *Phi) {
// Create a vector from the initial value.
auto *VectorInit = ScalarInit;
- if (VF.isVector()) {
+ if (VF.isVector()) {
Builder.SetInsertPoint(LoopVectorPreHeader->getTerminator());
- assert(!VF.isScalable() && "VF is assumed to be non scalable.");
+ assert(!VF.isScalable() && "VF is assumed to be non scalable.");
VectorInit = Builder.CreateInsertElement(
- PoisonValue::get(VectorType::get(VectorInit->getType(), VF)), VectorInit,
- Builder.getInt32(VF.getKnownMinValue() - 1), "vector.recur.init");
+ PoisonValue::get(VectorType::get(VectorInit->getType(), VF)), VectorInit,
+ Builder.getInt32(VF.getKnownMinValue() - 1), "vector.recur.init");
}
// We constructed a temporary phi node in the first phase of vectorization.
@@ -4094,11 +4094,11 @@ void InnerLoopVectorizer::fixFirstOrderRecurrence(PHINode *Phi) {
// We will construct a vector for the recurrence by combining the values for
// the current and previous iterations. This is the required shuffle mask.
- assert(!VF.isScalable());
- SmallVector<int, 8> ShuffleMask(VF.getKnownMinValue());
- ShuffleMask[0] = VF.getKnownMinValue() - 1;
- for (unsigned I = 1; I < VF.getKnownMinValue(); ++I)
- ShuffleMask[I] = I + VF.getKnownMinValue() - 1;
+ assert(!VF.isScalable());
+ SmallVector<int, 8> ShuffleMask(VF.getKnownMinValue());
+ ShuffleMask[0] = VF.getKnownMinValue() - 1;
+ for (unsigned I = 1; I < VF.getKnownMinValue(); ++I)
+ ShuffleMask[I] = I + VF.getKnownMinValue() - 1;
// The vector from which to take the initial value for the current iteration
// (actual or unrolled). Initially, this is the vector phi node.
@@ -4108,10 +4108,10 @@ void InnerLoopVectorizer::fixFirstOrderRecurrence(PHINode *Phi) {
for (unsigned Part = 0; Part < UF; ++Part) {
Value *PreviousPart = getOrCreateVectorValue(Previous, Part);
Value *PhiPart = VectorLoopValueMap.getVectorValue(Phi, Part);
- auto *Shuffle =
- VF.isVector()
- ? Builder.CreateShuffleVector(Incoming, PreviousPart, ShuffleMask)
- : Incoming;
+ auto *Shuffle =
+ VF.isVector()
+ ? Builder.CreateShuffleVector(Incoming, PreviousPart, ShuffleMask)
+ : Incoming;
PhiPart->replaceAllUsesWith(Shuffle);
cast<Instruction>(PhiPart)->eraseFromParent();
VectorLoopValueMap.resetVectorValue(Phi, Part, Shuffle);
@@ -4124,11 +4124,11 @@ void InnerLoopVectorizer::fixFirstOrderRecurrence(PHINode *Phi) {
// Extract the last vector element in the middle block. This will be the
// initial value for the recurrence when jumping to the scalar loop.
auto *ExtractForScalar = Incoming;
- if (VF.isVector()) {
+ if (VF.isVector()) {
Builder.SetInsertPoint(LoopMiddleBlock->getTerminator());
ExtractForScalar = Builder.CreateExtractElement(
- ExtractForScalar, Builder.getInt32(VF.getKnownMinValue() - 1),
- "vector.recur.extract");
+ ExtractForScalar, Builder.getInt32(VF.getKnownMinValue() - 1),
+ "vector.recur.extract");
}
// Extract the second last element in the middle block if the
// Phi is used outside the loop. We need to extract the phi itself
@@ -4136,10 +4136,10 @@ void InnerLoopVectorizer::fixFirstOrderRecurrence(PHINode *Phi) {
// will be the value when jumping to the exit block from the LoopMiddleBlock,
// when the scalar loop is not run at all.
Value *ExtractForPhiUsedOutsideLoop = nullptr;
- if (VF.isVector())
+ if (VF.isVector())
ExtractForPhiUsedOutsideLoop = Builder.CreateExtractElement(
- Incoming, Builder.getInt32(VF.getKnownMinValue() - 2),
- "vector.recur.extract.for.phi");
+ Incoming, Builder.getInt32(VF.getKnownMinValue() - 2),
+ "vector.recur.extract.for.phi");
// When loop is unrolled without vectorizing, initialize
// ExtractForPhiUsedOutsideLoop with the value just prior to unrolled value of
// `Incoming`. This is analogous to the vectorized case above: extracting the
@@ -4163,13 +4163,13 @@ void InnerLoopVectorizer::fixFirstOrderRecurrence(PHINode *Phi) {
// vector recurrence we extracted in the middle block. Since the loop is in
// LCSSA form, we just need to find all the phi nodes for the original scalar
// recurrence in the exit block, and then add an edge for the middle block.
- // Note that LCSSA does not imply single entry when the original scalar loop
- // had multiple exiting edges (as we always run the last iteration in the
- // scalar epilogue); in that case, the exiting path through middle will be
- // dynamically dead and the value picked for the phi doesn't matter.
- for (PHINode &LCSSAPhi : LoopExitBlock->phis())
- if (any_of(LCSSAPhi.incoming_values(),
- [Phi](Value *V) { return V == Phi; }))
+ // Note that LCSSA does not imply single entry when the original scalar loop
+ // had multiple exiting edges (as we always run the last iteration in the
+ // scalar epilogue); in that case, the exiting path through middle will be
+ // dynamically dead and the value picked for the phi doesn't matter.
+ for (PHINode &LCSSAPhi : LoopExitBlock->phis())
+ if (any_of(LCSSAPhi.incoming_values(),
+ [Phi](Value *V) { return V == Phi; }))
LCSSAPhi.addIncoming(ExtractForPhiUsedOutsideLoop, LoopMiddleBlock);
}
@@ -4179,11 +4179,11 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi) {
"Unable to find the reduction variable");
RecurrenceDescriptor RdxDesc = Legal->getReductionVars()[Phi];
- RecurKind RK = RdxDesc.getRecurrenceKind();
+ RecurKind RK = RdxDesc.getRecurrenceKind();
TrackingVH<Value> ReductionStartValue = RdxDesc.getRecurrenceStartValue();
Instruction *LoopExitInst = RdxDesc.getLoopExitInstr();
setDebugLocFromInst(Builder, ReductionStartValue);
- bool IsInLoopReductionPhi = Cost->isInLoopReduction(Phi);
+ bool IsInLoopReductionPhi = Cost->isInLoopReduction(Phi);
// This is the vector-clone of the value that leaves the loop.
Type *VecTy = getOrCreateVectorValue(LoopExitInst, 0)->getType();
@@ -4215,9 +4215,9 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi) {
// If tail is folded by masking, the vector value to leave the loop should be
// a Select choosing between the vectorized LoopExitInst and vectorized Phi,
- // instead of the former. For an inloop reduction the reduction will already
- // be predicated, and does not need to be handled here.
- if (Cost->foldTailByMasking() && !IsInLoopReductionPhi) {
+ // instead of the former. For an inloop reduction the reduction will already
+ // be predicated, and does not need to be handled here.
+ if (Cost->foldTailByMasking() && !IsInLoopReductionPhi) {
for (unsigned Part = 0; Part < UF; ++Part) {
Value *VecLoopExitInst =
VectorLoopValueMap.getVectorValue(LoopExitInst, Part);
@@ -4231,31 +4231,31 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi) {
}
assert(Sel && "Reduction exit feeds no select");
VectorLoopValueMap.resetVectorValue(LoopExitInst, Part, Sel);
-
- // If the target can create a predicated operator for the reduction at no
- // extra cost in the loop (for example a predicated vadd), it can be
- // cheaper for the select to remain in the loop than be sunk out of it,
- // and so use the select value for the phi instead of the old
- // LoopExitValue.
- RecurrenceDescriptor RdxDesc = Legal->getReductionVars()[Phi];
- if (PreferPredicatedReductionSelect ||
- TTI->preferPredicatedReductionSelect(
- RdxDesc.getOpcode(), Phi->getType(),
- TargetTransformInfo::ReductionFlags())) {
- auto *VecRdxPhi = cast<PHINode>(getOrCreateVectorValue(Phi, Part));
- VecRdxPhi->setIncomingValueForBlock(
- LI->getLoopFor(LoopVectorBody)->getLoopLatch(), Sel);
- }
+
+ // If the target can create a predicated operator for the reduction at no
+ // extra cost in the loop (for example a predicated vadd), it can be
+ // cheaper for the select to remain in the loop than be sunk out of it,
+ // and so use the select value for the phi instead of the old
+ // LoopExitValue.
+ RecurrenceDescriptor RdxDesc = Legal->getReductionVars()[Phi];
+ if (PreferPredicatedReductionSelect ||
+ TTI->preferPredicatedReductionSelect(
+ RdxDesc.getOpcode(), Phi->getType(),
+ TargetTransformInfo::ReductionFlags())) {
+ auto *VecRdxPhi = cast<PHINode>(getOrCreateVectorValue(Phi, Part));
+ VecRdxPhi->setIncomingValueForBlock(
+ LI->getLoopFor(LoopVectorBody)->getLoopLatch(), Sel);
+ }
}
}
// If the vector reduction can be performed in a smaller type, we truncate
// then extend the loop exit value to enable InstCombine to evaluate the
// entire expression in the smaller type.
- if (VF.isVector() && Phi->getType() != RdxDesc.getRecurrenceType()) {
- assert(!IsInLoopReductionPhi && "Unexpected truncated inloop reduction!");
- assert(!VF.isScalable() && "scalable vectors not yet supported.");
- Type *RdxVecTy = VectorType::get(RdxDesc.getRecurrenceType(), VF);
+ if (VF.isVector() && Phi->getType() != RdxDesc.getRecurrenceType()) {
+ assert(!IsInLoopReductionPhi && "Unexpected truncated inloop reduction!");
+ assert(!VF.isScalable() && "scalable vectors not yet supported.");
+ Type *RdxVecTy = VectorType::get(RdxDesc.getRecurrenceType(), VF);
Builder.SetInsertPoint(
LI->getLoopFor(LoopVectorBody)->getLoopLatch()->getTerminator());
VectorParts RdxParts(UF);
@@ -4282,7 +4282,7 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi) {
// Reduce all of the unrolled parts into a single vector.
Value *ReducedPartRdx = VectorLoopValueMap.getVectorValue(LoopExitInst, 0);
- unsigned Op = RecurrenceDescriptor::getOpcode(RK);
+ unsigned Op = RecurrenceDescriptor::getOpcode(RK);
// The middle block terminator has already been assigned a DebugLoc here (the
// OrigLoop's single latch terminator). We want the whole middle block to
@@ -4301,14 +4301,14 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi) {
ReducedPartRdx, "bin.rdx"),
RdxDesc.getFastMathFlags());
else
- ReducedPartRdx = createMinMaxOp(Builder, RK, ReducedPartRdx, RdxPart);
+ ReducedPartRdx = createMinMaxOp(Builder, RK, ReducedPartRdx, RdxPart);
}
- // Create the reduction after the loop. Note that inloop reductions create the
- // target reduction in the loop using a Reduction recipe.
- if (VF.isVector() && !IsInLoopReductionPhi) {
+ // Create the reduction after the loop. Note that inloop reductions create the
+ // target reduction in the loop using a Reduction recipe.
+ if (VF.isVector() && !IsInLoopReductionPhi) {
ReducedPartRdx =
- createTargetReduction(Builder, TTI, RdxDesc, ReducedPartRdx);
+ createTargetReduction(Builder, TTI, RdxDesc, ReducedPartRdx);
// If the reduction can be performed in a smaller type, we need to extend
// the reduction to the wider type before we branch to the original loop.
if (Phi->getType() != RdxDesc.getRecurrenceType())
@@ -4329,16 +4329,16 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi) {
// Now, we need to fix the users of the reduction variable
// inside and outside of the scalar remainder loop.
- // We know that the loop is in LCSSA form. We need to update the PHI nodes
- // in the exit blocks. See comment on analogous loop in
- // fixFirstOrderRecurrence for a more complete explaination of the logic.
- for (PHINode &LCSSAPhi : LoopExitBlock->phis())
- if (any_of(LCSSAPhi.incoming_values(),
- [LoopExitInst](Value *V) { return V == LoopExitInst; }))
+ // We know that the loop is in LCSSA form. We need to update the PHI nodes
+ // in the exit blocks. See comment on analogous loop in
+ // fixFirstOrderRecurrence for a more complete explaination of the logic.
+ for (PHINode &LCSSAPhi : LoopExitBlock->phis())
+ if (any_of(LCSSAPhi.incoming_values(),
+ [LoopExitInst](Value *V) { return V == LoopExitInst; }))
LCSSAPhi.addIncoming(ReducedPartRdx, LoopMiddleBlock);
- // Fix the scalar loop reduction variable with the incoming reduction sum
- // from the vector body and from the backedge value.
+ // Fix the scalar loop reduction variable with the incoming reduction sum
+ // from the vector body and from the backedge value.
int IncomingEdgeBlockIdx =
Phi->getBasicBlockIndex(OrigLoop->getLoopLatch());
assert(IncomingEdgeBlockIdx >= 0 && "Invalid block index");
@@ -4350,8 +4350,8 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi) {
void InnerLoopVectorizer::clearReductionWrapFlags(
RecurrenceDescriptor &RdxDesc) {
- RecurKind RK = RdxDesc.getRecurrenceKind();
- if (RK != RecurKind::Add && RK != RecurKind::Mul)
+ RecurKind RK = RdxDesc.getRecurrenceKind();
+ if (RK != RecurKind::Add && RK != RecurKind::Mul)
return;
Instruction *LoopExitInstr = RdxDesc.getLoopExitInstr();
@@ -4380,27 +4380,27 @@ void InnerLoopVectorizer::clearReductionWrapFlags(
void InnerLoopVectorizer::fixLCSSAPHIs() {
for (PHINode &LCSSAPhi : LoopExitBlock->phis()) {
- if (LCSSAPhi.getBasicBlockIndex(LoopMiddleBlock) != -1)
- // Some phis were already hand updated by the reduction and recurrence
- // code above, leave them alone.
- continue;
-
- auto *IncomingValue = LCSSAPhi.getIncomingValue(0);
- // Non-instruction incoming values will have only one value.
- unsigned LastLane = 0;
- if (isa<Instruction>(IncomingValue))
- LastLane = Cost->isUniformAfterVectorization(
- cast<Instruction>(IncomingValue), VF)
- ? 0
- : VF.getKnownMinValue() - 1;
- assert((!VF.isScalable() || LastLane == 0) &&
- "scalable vectors dont support non-uniform scalars yet");
- // Can be a loop invariant incoming value or the last scalar value to be
- // extracted from the vectorized loop.
- Builder.SetInsertPoint(LoopMiddleBlock->getTerminator());
- Value *lastIncomingValue =
- getOrCreateScalarValue(IncomingValue, { UF - 1, LastLane });
- LCSSAPhi.addIncoming(lastIncomingValue, LoopMiddleBlock);
+ if (LCSSAPhi.getBasicBlockIndex(LoopMiddleBlock) != -1)
+ // Some phis were already hand updated by the reduction and recurrence
+ // code above, leave them alone.
+ continue;
+
+ auto *IncomingValue = LCSSAPhi.getIncomingValue(0);
+ // Non-instruction incoming values will have only one value.
+ unsigned LastLane = 0;
+ if (isa<Instruction>(IncomingValue))
+ LastLane = Cost->isUniformAfterVectorization(
+ cast<Instruction>(IncomingValue), VF)
+ ? 0
+ : VF.getKnownMinValue() - 1;
+ assert((!VF.isScalable() || LastLane == 0) &&
+ "scalable vectors dont support non-uniform scalars yet");
+ // Can be a loop invariant incoming value or the last scalar value to be
+ // extracted from the vectorized loop.
+ Builder.SetInsertPoint(LoopMiddleBlock->getTerminator());
+ Value *lastIncomingValue =
+ getOrCreateScalarValue(IncomingValue, { UF - 1, LastLane });
+ LCSSAPhi.addIncoming(lastIncomingValue, LoopMiddleBlock);
}
}
@@ -4504,9 +4504,9 @@ void InnerLoopVectorizer::fixNonInductionPHIs() {
}
}
-void InnerLoopVectorizer::widenGEP(GetElementPtrInst *GEP, VPValue *VPDef,
- VPUser &Operands, unsigned UF,
- ElementCount VF, bool IsPtrLoopInvariant,
+void InnerLoopVectorizer::widenGEP(GetElementPtrInst *GEP, VPValue *VPDef,
+ VPUser &Operands, unsigned UF,
+ ElementCount VF, bool IsPtrLoopInvariant,
SmallBitVector &IsIndexLoopInvariant,
VPTransformState &State) {
// Construct a vector GEP by widening the operands of the scalar GEP as
@@ -4515,7 +4515,7 @@ void InnerLoopVectorizer::widenGEP(GetElementPtrInst *GEP, VPValue *VPDef,
// is vector-typed. Thus, to keep the representation compact, we only use
// vector-typed operands for loop-varying values.
- if (VF.isVector() && IsPtrLoopInvariant && IsIndexLoopInvariant.all()) {
+ if (VF.isVector() && IsPtrLoopInvariant && IsIndexLoopInvariant.all()) {
// If we are vectorizing, but the GEP has only loop-invariant operands,
// the GEP we build (by only using vector-typed operands for
// loop-varying values) would be a scalar pointer. Thus, to ensure we
@@ -4531,7 +4531,7 @@ void InnerLoopVectorizer::widenGEP(GetElementPtrInst *GEP, VPValue *VPDef,
auto *Clone = Builder.Insert(GEP->clone());
for (unsigned Part = 0; Part < UF; ++Part) {
Value *EntryPart = Builder.CreateVectorSplat(VF, Clone);
- State.set(VPDef, GEP, EntryPart, Part);
+ State.set(VPDef, GEP, EntryPart, Part);
addMetadata(EntryPart, GEP);
}
} else {
@@ -4566,19 +4566,19 @@ void InnerLoopVectorizer::widenGEP(GetElementPtrInst *GEP, VPValue *VPDef,
? Builder.CreateInBoundsGEP(GEP->getSourceElementType(), Ptr,
Indices)
: Builder.CreateGEP(GEP->getSourceElementType(), Ptr, Indices);
- assert((VF.isScalar() || NewGEP->getType()->isVectorTy()) &&
+ assert((VF.isScalar() || NewGEP->getType()->isVectorTy()) &&
"NewGEP is not a pointer vector");
- State.set(VPDef, GEP, NewGEP, Part);
+ State.set(VPDef, GEP, NewGEP, Part);
addMetadata(NewGEP, GEP);
}
}
}
-void InnerLoopVectorizer::widenPHIInstruction(Instruction *PN,
- RecurrenceDescriptor *RdxDesc,
- Value *StartV, unsigned UF,
- ElementCount VF) {
- assert(!VF.isScalable() && "scalable vectors not yet supported.");
+void InnerLoopVectorizer::widenPHIInstruction(Instruction *PN,
+ RecurrenceDescriptor *RdxDesc,
+ Value *StartV, unsigned UF,
+ ElementCount VF) {
+ assert(!VF.isScalable() && "scalable vectors not yet supported.");
PHINode *P = cast<PHINode>(PN);
if (EnableVPlanNativePath) {
// Currently we enter here in the VPlan-native path for non-induction
@@ -4586,7 +4586,7 @@ void InnerLoopVectorizer::widenPHIInstruction(Instruction *PN,
// Create a vector phi with no operands - the vector phi operands will be
// set at the end of vector code generation.
Type *VecTy =
- (VF.isScalar()) ? PN->getType() : VectorType::get(PN->getType(), VF);
+ (VF.isScalar()) ? PN->getType() : VectorType::get(PN->getType(), VF);
Value *VecPhi = Builder.CreatePHI(VecTy, PN->getNumOperands(), "vec.phi");
VectorLoopValueMap.setVectorValue(P, 0, VecPhi);
OrigPHIsToFix.push_back(P);
@@ -4601,60 +4601,60 @@ void InnerLoopVectorizer::widenPHIInstruction(Instruction *PN,
// Phi nodes have cycles, so we need to vectorize them in two stages. This is
// stage #1: We create a new vector PHI node with no incoming edges. We'll use
// this value when we vectorize all of the instructions that use the PHI.
- if (RdxDesc || Legal->isFirstOrderRecurrence(P)) {
- Value *Iden = nullptr;
- bool ScalarPHI =
- (VF.isScalar()) || Cost->isInLoopReduction(cast<PHINode>(PN));
- Type *VecTy =
- ScalarPHI ? PN->getType() : VectorType::get(PN->getType(), VF);
-
- if (RdxDesc) {
- assert(Legal->isReductionVariable(P) && StartV &&
- "RdxDesc should only be set for reduction variables; in that case "
- "a StartV is also required");
- RecurKind RK = RdxDesc->getRecurrenceKind();
- if (RecurrenceDescriptor::isMinMaxRecurrenceKind(RK)) {
- // MinMax reduction have the start value as their identify.
- if (ScalarPHI) {
- Iden = StartV;
- } else {
- IRBuilderBase::InsertPointGuard IPBuilder(Builder);
- Builder.SetInsertPoint(LoopVectorPreHeader->getTerminator());
- StartV = Iden = Builder.CreateVectorSplat(VF, StartV, "minmax.ident");
- }
- } else {
- Constant *IdenC = RecurrenceDescriptor::getRecurrenceIdentity(
- RK, VecTy->getScalarType());
- Iden = IdenC;
-
- if (!ScalarPHI) {
- Iden = ConstantVector::getSplat(VF, IdenC);
- IRBuilderBase::InsertPointGuard IPBuilder(Builder);
- Builder.SetInsertPoint(LoopVectorPreHeader->getTerminator());
- Constant *Zero = Builder.getInt32(0);
- StartV = Builder.CreateInsertElement(Iden, StartV, Zero);
- }
- }
- }
-
+ if (RdxDesc || Legal->isFirstOrderRecurrence(P)) {
+ Value *Iden = nullptr;
+ bool ScalarPHI =
+ (VF.isScalar()) || Cost->isInLoopReduction(cast<PHINode>(PN));
+ Type *VecTy =
+ ScalarPHI ? PN->getType() : VectorType::get(PN->getType(), VF);
+
+ if (RdxDesc) {
+ assert(Legal->isReductionVariable(P) && StartV &&
+ "RdxDesc should only be set for reduction variables; in that case "
+ "a StartV is also required");
+ RecurKind RK = RdxDesc->getRecurrenceKind();
+ if (RecurrenceDescriptor::isMinMaxRecurrenceKind(RK)) {
+ // MinMax reduction have the start value as their identify.
+ if (ScalarPHI) {
+ Iden = StartV;
+ } else {
+ IRBuilderBase::InsertPointGuard IPBuilder(Builder);
+ Builder.SetInsertPoint(LoopVectorPreHeader->getTerminator());
+ StartV = Iden = Builder.CreateVectorSplat(VF, StartV, "minmax.ident");
+ }
+ } else {
+ Constant *IdenC = RecurrenceDescriptor::getRecurrenceIdentity(
+ RK, VecTy->getScalarType());
+ Iden = IdenC;
+
+ if (!ScalarPHI) {
+ Iden = ConstantVector::getSplat(VF, IdenC);
+ IRBuilderBase::InsertPointGuard IPBuilder(Builder);
+ Builder.SetInsertPoint(LoopVectorPreHeader->getTerminator());
+ Constant *Zero = Builder.getInt32(0);
+ StartV = Builder.CreateInsertElement(Iden, StartV, Zero);
+ }
+ }
+ }
+
for (unsigned Part = 0; Part < UF; ++Part) {
// This is phase one of vectorizing PHIs.
Value *EntryPart = PHINode::Create(
VecTy, 2, "vec.phi", &*LoopVectorBody->getFirstInsertionPt());
VectorLoopValueMap.setVectorValue(P, Part, EntryPart);
- if (StartV) {
- // Make sure to add the reduction start value only to the
- // first unroll part.
- Value *StartVal = (Part == 0) ? StartV : Iden;
- cast<PHINode>(EntryPart)->addIncoming(StartVal, LoopVectorPreHeader);
- }
+ if (StartV) {
+ // Make sure to add the reduction start value only to the
+ // first unroll part.
+ Value *StartVal = (Part == 0) ? StartV : Iden;
+ cast<PHINode>(EntryPart)->addIncoming(StartVal, LoopVectorPreHeader);
+ }
}
return;
}
- assert(!Legal->isReductionVariable(P) &&
- "reductions should be handled above");
-
+ assert(!Legal->isReductionVariable(P) &&
+ "reductions should be handled above");
+
setDebugLocFromInst(Builder, P);
// This PHINode must be an induction variable.
@@ -4675,74 +4675,74 @@ void InnerLoopVectorizer::widenPHIInstruction(Instruction *PN,
case InductionDescriptor::IK_PtrInduction: {
// Handle the pointer induction variable case.
assert(P->getType()->isPointerTy() && "Unexpected type.");
-
- if (Cost->isScalarAfterVectorization(P, VF)) {
- // This is the normalized GEP that starts counting at zero.
- Value *PtrInd =
- Builder.CreateSExtOrTrunc(Induction, II.getStep()->getType());
- // Determine the number of scalars we need to generate for each unroll
- // iteration. If the instruction is uniform, we only need to generate the
- // first lane. Otherwise, we generate all VF values.
- unsigned Lanes =
- Cost->isUniformAfterVectorization(P, VF) ? 1 : VF.getKnownMinValue();
- for (unsigned Part = 0; Part < UF; ++Part) {
- for (unsigned Lane = 0; Lane < Lanes; ++Lane) {
- Constant *Idx = ConstantInt::get(PtrInd->getType(),
- Lane + Part * VF.getKnownMinValue());
- Value *GlobalIdx = Builder.CreateAdd(PtrInd, Idx);
- Value *SclrGep =
- emitTransformedIndex(Builder, GlobalIdx, PSE.getSE(), DL, II);
- SclrGep->setName("next.gep");
- VectorLoopValueMap.setScalarValue(P, {Part, Lane}, SclrGep);
- }
+
+ if (Cost->isScalarAfterVectorization(P, VF)) {
+ // This is the normalized GEP that starts counting at zero.
+ Value *PtrInd =
+ Builder.CreateSExtOrTrunc(Induction, II.getStep()->getType());
+ // Determine the number of scalars we need to generate for each unroll
+ // iteration. If the instruction is uniform, we only need to generate the
+ // first lane. Otherwise, we generate all VF values.
+ unsigned Lanes =
+ Cost->isUniformAfterVectorization(P, VF) ? 1 : VF.getKnownMinValue();
+ for (unsigned Part = 0; Part < UF; ++Part) {
+ for (unsigned Lane = 0; Lane < Lanes; ++Lane) {
+ Constant *Idx = ConstantInt::get(PtrInd->getType(),
+ Lane + Part * VF.getKnownMinValue());
+ Value *GlobalIdx = Builder.CreateAdd(PtrInd, Idx);
+ Value *SclrGep =
+ emitTransformedIndex(Builder, GlobalIdx, PSE.getSE(), DL, II);
+ SclrGep->setName("next.gep");
+ VectorLoopValueMap.setScalarValue(P, {Part, Lane}, SclrGep);
+ }
}
- return;
+ return;
+ }
+ assert(isa<SCEVConstant>(II.getStep()) &&
+ "Induction step not a SCEV constant!");
+ Type *PhiType = II.getStep()->getType();
+
+ // Build a pointer phi
+ Value *ScalarStartValue = II.getStartValue();
+ Type *ScStValueType = ScalarStartValue->getType();
+ PHINode *NewPointerPhi =
+ PHINode::Create(ScStValueType, 2, "pointer.phi", Induction);
+ NewPointerPhi->addIncoming(ScalarStartValue, LoopVectorPreHeader);
+
+ // A pointer induction, performed by using a gep
+ BasicBlock *LoopLatch = LI->getLoopFor(LoopVectorBody)->getLoopLatch();
+ Instruction *InductionLoc = LoopLatch->getTerminator();
+ const SCEV *ScalarStep = II.getStep();
+ SCEVExpander Exp(*PSE.getSE(), DL, "induction");
+ Value *ScalarStepValue =
+ Exp.expandCodeFor(ScalarStep, PhiType, InductionLoc);
+ Value *InductionGEP = GetElementPtrInst::Create(
+ ScStValueType->getPointerElementType(), NewPointerPhi,
+ Builder.CreateMul(
+ ScalarStepValue,
+ ConstantInt::get(PhiType, VF.getKnownMinValue() * UF)),
+ "ptr.ind", InductionLoc);
+ NewPointerPhi->addIncoming(InductionGEP, LoopLatch);
+
+ // Create UF many actual address geps that use the pointer
+ // phi as base and a vectorized version of the step value
+ // (<step*0, ..., step*N>) as offset.
+ for (unsigned Part = 0; Part < UF; ++Part) {
+ SmallVector<Constant *, 8> Indices;
+ // Create a vector of consecutive numbers from zero to VF.
+ for (unsigned i = 0; i < VF.getKnownMinValue(); ++i)
+ Indices.push_back(
+ ConstantInt::get(PhiType, i + Part * VF.getKnownMinValue()));
+ Constant *StartOffset = ConstantVector::get(Indices);
+
+ Value *GEP = Builder.CreateGEP(
+ ScStValueType->getPointerElementType(), NewPointerPhi,
+ Builder.CreateMul(
+ StartOffset,
+ Builder.CreateVectorSplat(VF.getKnownMinValue(), ScalarStepValue),
+ "vector.gep"));
+ VectorLoopValueMap.setVectorValue(P, Part, GEP);
}
- assert(isa<SCEVConstant>(II.getStep()) &&
- "Induction step not a SCEV constant!");
- Type *PhiType = II.getStep()->getType();
-
- // Build a pointer phi
- Value *ScalarStartValue = II.getStartValue();
- Type *ScStValueType = ScalarStartValue->getType();
- PHINode *NewPointerPhi =
- PHINode::Create(ScStValueType, 2, "pointer.phi", Induction);
- NewPointerPhi->addIncoming(ScalarStartValue, LoopVectorPreHeader);
-
- // A pointer induction, performed by using a gep
- BasicBlock *LoopLatch = LI->getLoopFor(LoopVectorBody)->getLoopLatch();
- Instruction *InductionLoc = LoopLatch->getTerminator();
- const SCEV *ScalarStep = II.getStep();
- SCEVExpander Exp(*PSE.getSE(), DL, "induction");
- Value *ScalarStepValue =
- Exp.expandCodeFor(ScalarStep, PhiType, InductionLoc);
- Value *InductionGEP = GetElementPtrInst::Create(
- ScStValueType->getPointerElementType(), NewPointerPhi,
- Builder.CreateMul(
- ScalarStepValue,
- ConstantInt::get(PhiType, VF.getKnownMinValue() * UF)),
- "ptr.ind", InductionLoc);
- NewPointerPhi->addIncoming(InductionGEP, LoopLatch);
-
- // Create UF many actual address geps that use the pointer
- // phi as base and a vectorized version of the step value
- // (<step*0, ..., step*N>) as offset.
- for (unsigned Part = 0; Part < UF; ++Part) {
- SmallVector<Constant *, 8> Indices;
- // Create a vector of consecutive numbers from zero to VF.
- for (unsigned i = 0; i < VF.getKnownMinValue(); ++i)
- Indices.push_back(
- ConstantInt::get(PhiType, i + Part * VF.getKnownMinValue()));
- Constant *StartOffset = ConstantVector::get(Indices);
-
- Value *GEP = Builder.CreateGEP(
- ScStValueType->getPointerElementType(), NewPointerPhi,
- Builder.CreateMul(
- StartOffset,
- Builder.CreateVectorSplat(VF.getKnownMinValue(), ScalarStepValue),
- "vector.gep"));
- VectorLoopValueMap.setVectorValue(P, Part, GEP);
- }
}
}
}
@@ -4765,8 +4765,8 @@ static bool mayDivideByZero(Instruction &I) {
return !CInt || CInt->isZero();
}
-void InnerLoopVectorizer::widenInstruction(Instruction &I, VPValue *Def,
- VPUser &User,
+void InnerLoopVectorizer::widenInstruction(Instruction &I, VPValue *Def,
+ VPUser &User,
VPTransformState &State) {
switch (I.getOpcode()) {
case Instruction::Call:
@@ -4808,7 +4808,7 @@ void InnerLoopVectorizer::widenInstruction(Instruction &I, VPValue *Def,
VecOp->copyIRFlags(&I);
// Use this vector value for all users of the original instruction.
- State.set(Def, &I, V, Part);
+ State.set(Def, &I, V, Part);
addMetadata(V, &I);
}
@@ -4832,7 +4832,7 @@ void InnerLoopVectorizer::widenInstruction(Instruction &I, VPValue *Def,
} else {
C = Builder.CreateICmp(Cmp->getPredicate(), A, B);
}
- State.set(Def, &I, C, Part);
+ State.set(Def, &I, C, Part);
addMetadata(C, &I);
}
@@ -4856,12 +4856,12 @@ void InnerLoopVectorizer::widenInstruction(Instruction &I, VPValue *Def,
/// Vectorize casts.
Type *DestTy =
- (VF.isScalar()) ? CI->getType() : VectorType::get(CI->getType(), VF);
+ (VF.isScalar()) ? CI->getType() : VectorType::get(CI->getType(), VF);
for (unsigned Part = 0; Part < UF; ++Part) {
Value *A = State.get(User.getOperand(0), Part);
Value *Cast = Builder.CreateCast(CI->getOpcode(), A, DestTy);
- State.set(Def, &I, Cast, Part);
+ State.set(Def, &I, Cast, Part);
addMetadata(Cast, &I);
}
break;
@@ -4873,8 +4873,8 @@ void InnerLoopVectorizer::widenInstruction(Instruction &I, VPValue *Def,
} // end of switch.
}
-void InnerLoopVectorizer::widenCallInstruction(CallInst &I, VPValue *Def,
- VPUser &ArgOperands,
+void InnerLoopVectorizer::widenCallInstruction(CallInst &I, VPValue *Def,
+ VPUser &ArgOperands,
VPTransformState &State) {
assert(!isa<DbgInfoIntrinsic>(I) &&
"DbgInfoIntrinsic should have been dropped during VPlan construction");
@@ -4885,7 +4885,7 @@ void InnerLoopVectorizer::widenCallInstruction(CallInst &I, VPValue *Def,
SmallVector<Type *, 4> Tys;
for (Value *ArgOperand : CI->arg_operands())
- Tys.push_back(ToVectorTy(ArgOperand->getType(), VF.getKnownMinValue()));
+ Tys.push_back(ToVectorTy(ArgOperand->getType(), VF.getKnownMinValue()));
Intrinsic::ID ID = getVectorIntrinsicIDForCall(CI, TLI);
@@ -4893,13 +4893,13 @@ void InnerLoopVectorizer::widenCallInstruction(CallInst &I, VPValue *Def,
// version of the instruction.
// Is it beneficial to perform intrinsic call compared to lib call?
bool NeedToScalarize = false;
- InstructionCost CallCost = Cost->getVectorCallCost(CI, VF, NeedToScalarize);
- InstructionCost IntrinsicCost = ID ? Cost->getVectorIntrinsicCost(CI, VF) : 0;
- bool UseVectorIntrinsic = ID && IntrinsicCost <= CallCost;
+ InstructionCost CallCost = Cost->getVectorCallCost(CI, VF, NeedToScalarize);
+ InstructionCost IntrinsicCost = ID ? Cost->getVectorIntrinsicCost(CI, VF) : 0;
+ bool UseVectorIntrinsic = ID && IntrinsicCost <= CallCost;
assert((UseVectorIntrinsic || !NeedToScalarize) &&
"Instruction should be scalarized elsewhere.");
- assert(IntrinsicCost.isValid() && CallCost.isValid() &&
- "Cannot have invalid costs while widening");
+ assert(IntrinsicCost.isValid() && CallCost.isValid() &&
+ "Cannot have invalid costs while widening");
for (unsigned Part = 0; Part < UF; ++Part) {
SmallVector<Value *, 4> Args;
@@ -4918,15 +4918,15 @@ void InnerLoopVectorizer::widenCallInstruction(CallInst &I, VPValue *Def,
if (UseVectorIntrinsic) {
// Use vector version of the intrinsic.
Type *TysForDecl[] = {CI->getType()};
- if (VF.isVector()) {
- assert(!VF.isScalable() && "VF is assumed to be non scalable.");
- TysForDecl[0] = VectorType::get(CI->getType()->getScalarType(), VF);
- }
+ if (VF.isVector()) {
+ assert(!VF.isScalable() && "VF is assumed to be non scalable.");
+ TysForDecl[0] = VectorType::get(CI->getType()->getScalarType(), VF);
+ }
VectorF = Intrinsic::getDeclaration(M, ID, TysForDecl);
assert(VectorF && "Can't retrieve vector intrinsic.");
} else {
// Use vector version of the function call.
- const VFShape Shape = VFShape::get(*CI, VF, false /*HasGlobalPred*/);
+ const VFShape Shape = VFShape::get(*CI, VF, false /*HasGlobalPred*/);
#ifndef NDEBUG
assert(VFDatabase(*CI).getVectorizedFunction(Shape) != nullptr &&
"Can't create vector function.");
@@ -4940,12 +4940,12 @@ void InnerLoopVectorizer::widenCallInstruction(CallInst &I, VPValue *Def,
if (isa<FPMathOperator>(V))
V->copyFastMathFlags(CI);
- State.set(Def, &I, V, Part);
+ State.set(Def, &I, V, Part);
addMetadata(V, &I);
}
}
-void InnerLoopVectorizer::widenSelectInstruction(SelectInst &I, VPValue *VPDef,
+void InnerLoopVectorizer::widenSelectInstruction(SelectInst &I, VPValue *VPDef,
VPUser &Operands,
bool InvariantCond,
VPTransformState &State) {
@@ -4964,16 +4964,16 @@ void InnerLoopVectorizer::widenSelectInstruction(SelectInst &I, VPValue *VPDef,
Value *Op0 = State.get(Operands.getOperand(1), Part);
Value *Op1 = State.get(Operands.getOperand(2), Part);
Value *Sel = Builder.CreateSelect(Cond, Op0, Op1);
- State.set(VPDef, &I, Sel, Part);
+ State.set(VPDef, &I, Sel, Part);
addMetadata(Sel, &I);
}
}
-void LoopVectorizationCostModel::collectLoopScalars(ElementCount VF) {
+void LoopVectorizationCostModel::collectLoopScalars(ElementCount VF) {
// We should not collect Scalars more than once per VF. Right now, this
// function is called from collectUniformsAndScalars(), which already does
// this check. Collecting Scalars for VF=1 does not make any sense.
- assert(VF.isVector() && Scalars.find(VF) == Scalars.end() &&
+ assert(VF.isVector() && Scalars.find(VF) == Scalars.end() &&
"This function should not be visited twice for the same VF");
SmallSetVector<Instruction *, 8> Worklist;
@@ -4982,7 +4982,7 @@ void LoopVectorizationCostModel::collectLoopScalars(ElementCount VF) {
// accesses that will remain scalar.
SmallSetVector<Instruction *, 8> ScalarPtrs;
SmallPtrSet<Instruction *, 8> PossibleNonScalarPtrs;
- auto *Latch = TheLoop->getLoopLatch();
+ auto *Latch = TheLoop->getLoopLatch();
// A helper that returns true if the use of Ptr by MemAccess will be scalar.
// The pointer operands of loads and stores will be scalar as long as the
@@ -5008,33 +5008,33 @@ void LoopVectorizationCostModel::collectLoopScalars(ElementCount VF) {
!TheLoop->isLoopInvariant(V);
};
- auto isScalarPtrInduction = [&](Instruction *MemAccess, Value *Ptr) {
- if (!isa<PHINode>(Ptr) ||
- !Legal->getInductionVars().count(cast<PHINode>(Ptr)))
- return false;
- auto &Induction = Legal->getInductionVars()[cast<PHINode>(Ptr)];
- if (Induction.getKind() != InductionDescriptor::IK_PtrInduction)
- return false;
- return isScalarUse(MemAccess, Ptr);
- };
-
- // A helper that evaluates a memory access's use of a pointer. If the
- // pointer is actually the pointer induction of a loop, it is being
- // inserted into Worklist. If the use will be a scalar use, and the
- // pointer is only used by memory accesses, we place the pointer in
- // ScalarPtrs. Otherwise, the pointer is placed in PossibleNonScalarPtrs.
+ auto isScalarPtrInduction = [&](Instruction *MemAccess, Value *Ptr) {
+ if (!isa<PHINode>(Ptr) ||
+ !Legal->getInductionVars().count(cast<PHINode>(Ptr)))
+ return false;
+ auto &Induction = Legal->getInductionVars()[cast<PHINode>(Ptr)];
+ if (Induction.getKind() != InductionDescriptor::IK_PtrInduction)
+ return false;
+ return isScalarUse(MemAccess, Ptr);
+ };
+
+ // A helper that evaluates a memory access's use of a pointer. If the
+ // pointer is actually the pointer induction of a loop, it is being
+ // inserted into Worklist. If the use will be a scalar use, and the
+ // pointer is only used by memory accesses, we place the pointer in
+ // ScalarPtrs. Otherwise, the pointer is placed in PossibleNonScalarPtrs.
auto evaluatePtrUse = [&](Instruction *MemAccess, Value *Ptr) {
- if (isScalarPtrInduction(MemAccess, Ptr)) {
- Worklist.insert(cast<Instruction>(Ptr));
- Instruction *Update = cast<Instruction>(
- cast<PHINode>(Ptr)->getIncomingValueForBlock(Latch));
- Worklist.insert(Update);
- LLVM_DEBUG(dbgs() << "LV: Found new scalar instruction: " << *Ptr
- << "\n");
- LLVM_DEBUG(dbgs() << "LV: Found new scalar instruction: " << *Update
- << "\n");
- return;
- }
+ if (isScalarPtrInduction(MemAccess, Ptr)) {
+ Worklist.insert(cast<Instruction>(Ptr));
+ Instruction *Update = cast<Instruction>(
+ cast<PHINode>(Ptr)->getIncomingValueForBlock(Latch));
+ Worklist.insert(Update);
+ LLVM_DEBUG(dbgs() << "LV: Found new scalar instruction: " << *Ptr
+ << "\n");
+ LLVM_DEBUG(dbgs() << "LV: Found new scalar instruction: " << *Update
+ << "\n");
+ return;
+ }
// We only care about bitcast and getelementptr instructions contained in
// the loop.
if (!isLoopVaryingBitCastOrGEP(Ptr))
@@ -5058,9 +5058,9 @@ void LoopVectorizationCostModel::collectLoopScalars(ElementCount VF) {
};
// We seed the scalars analysis with three classes of instructions: (1)
- // instructions marked uniform-after-vectorization and (2) bitcast,
- // getelementptr and (pointer) phi instructions used by memory accesses
- // requiring a scalar use.
+ // instructions marked uniform-after-vectorization and (2) bitcast,
+ // getelementptr and (pointer) phi instructions used by memory accesses
+ // requiring a scalar use.
//
// (1) Add to the worklist all instructions that have been identified as
// uniform-after-vectorization.
@@ -5156,8 +5156,8 @@ void LoopVectorizationCostModel::collectLoopScalars(ElementCount VF) {
Scalars[VF].insert(Worklist.begin(), Worklist.end());
}
-bool LoopVectorizationCostModel::isScalarWithPredication(Instruction *I,
- ElementCount VF) {
+bool LoopVectorizationCostModel::isScalarWithPredication(Instruction *I,
+ ElementCount VF) {
if (!blockNeedsPredication(I->getParent()))
return false;
switch(I->getOpcode()) {
@@ -5171,7 +5171,7 @@ bool LoopVectorizationCostModel::isScalarWithPredication(Instruction *I,
auto *Ty = getMemInstValueType(I);
// We have already decided how to vectorize this instruction, get that
// result.
- if (VF.isVector()) {
+ if (VF.isVector()) {
InstWidening WideningDecision = getWideningDecision(I, VF);
assert(WideningDecision != CM_Unknown &&
"Widening decision should be ready at this moment");
@@ -5192,8 +5192,8 @@ bool LoopVectorizationCostModel::isScalarWithPredication(Instruction *I,
return false;
}
-bool LoopVectorizationCostModel::interleavedAccessCanBeWidened(
- Instruction *I, ElementCount VF) {
+bool LoopVectorizationCostModel::interleavedAccessCanBeWidened(
+ Instruction *I, ElementCount VF) {
assert(isAccessInterleaved(I) && "Expecting interleaved access.");
assert(getWideningDecision(I, VF) == CM_Unknown &&
"Decision should not be set yet.");
@@ -5204,7 +5204,7 @@ bool LoopVectorizationCostModel::interleavedAccessCanBeWidened(
// requires padding and will be scalarized.
auto &DL = I->getModule()->getDataLayout();
auto *ScalarTy = getMemInstValueType(I);
- if (hasIrregularType(ScalarTy, DL))
+ if (hasIrregularType(ScalarTy, DL))
return false;
// Check if masking is required.
@@ -5229,8 +5229,8 @@ bool LoopVectorizationCostModel::interleavedAccessCanBeWidened(
: TTI.isLegalMaskedStore(Ty, Alignment);
}
-bool LoopVectorizationCostModel::memoryInstructionCanBeWidened(
- Instruction *I, ElementCount VF) {
+bool LoopVectorizationCostModel::memoryInstructionCanBeWidened(
+ Instruction *I, ElementCount VF) {
// Get and ensure we have a valid memory instruction.
LoadInst *LI = dyn_cast<LoadInst>(I);
StoreInst *SI = dyn_cast<StoreInst>(I);
@@ -5251,19 +5251,19 @@ bool LoopVectorizationCostModel::memoryInstructionCanBeWidened(
// requires padding and will be scalarized.
auto &DL = I->getModule()->getDataLayout();
auto *ScalarTy = LI ? LI->getType() : SI->getValueOperand()->getType();
- if (hasIrregularType(ScalarTy, DL))
+ if (hasIrregularType(ScalarTy, DL))
return false;
return true;
}
-void LoopVectorizationCostModel::collectLoopUniforms(ElementCount VF) {
+void LoopVectorizationCostModel::collectLoopUniforms(ElementCount VF) {
// We should not collect Uniforms more than once per VF. Right now,
// this function is called from collectUniformsAndScalars(), which
// already does this check. Collecting Uniforms for VF=1 does not make any
// sense.
- assert(VF.isVector() && Uniforms.find(VF) == Uniforms.end() &&
+ assert(VF.isVector() && Uniforms.find(VF) == Uniforms.end() &&
"This function should not be visited twice for the same VF");
// Visit the list of Uniforms. If we'll not find any uniform value, we'll
@@ -5289,11 +5289,11 @@ void LoopVectorizationCostModel::collectLoopUniforms(ElementCount VF) {
// replicating region where only a single instance out of VF should be formed.
// TODO: optimize such seldom cases if found important, see PR40816.
auto addToWorklistIfAllowed = [&](Instruction *I) -> void {
- if (isOutOfScope(I)) {
- LLVM_DEBUG(dbgs() << "LV: Found not uniform due to scope: "
- << *I << "\n");
- return;
- }
+ if (isOutOfScope(I)) {
+ LLVM_DEBUG(dbgs() << "LV: Found not uniform due to scope: "
+ << *I << "\n");
+ return;
+ }
if (isScalarWithPredication(I, VF)) {
LLVM_DEBUG(dbgs() << "LV: Found not uniform being ScalarWithPredication: "
<< *I << "\n");
@@ -5310,71 +5310,71 @@ void LoopVectorizationCostModel::collectLoopUniforms(ElementCount VF) {
if (Cmp && TheLoop->contains(Cmp) && Cmp->hasOneUse())
addToWorklistIfAllowed(Cmp);
- auto isUniformDecision = [&](Instruction *I, ElementCount VF) {
+ auto isUniformDecision = [&](Instruction *I, ElementCount VF) {
InstWidening WideningDecision = getWideningDecision(I, VF);
assert(WideningDecision != CM_Unknown &&
"Widening decision should be ready at this moment");
- // A uniform memory op is itself uniform. We exclude uniform stores
- // here as they demand the last lane, not the first one.
- if (isa<LoadInst>(I) && Legal->isUniformMemOp(*I)) {
- assert(WideningDecision == CM_Scalarize);
- return true;
- }
-
+ // A uniform memory op is itself uniform. We exclude uniform stores
+ // here as they demand the last lane, not the first one.
+ if (isa<LoadInst>(I) && Legal->isUniformMemOp(*I)) {
+ assert(WideningDecision == CM_Scalarize);
+ return true;
+ }
+
return (WideningDecision == CM_Widen ||
WideningDecision == CM_Widen_Reverse ||
WideningDecision == CM_Interleave);
};
-
-
- // Returns true if Ptr is the pointer operand of a memory access instruction
- // I, and I is known to not require scalarization.
- auto isVectorizedMemAccessUse = [&](Instruction *I, Value *Ptr) -> bool {
- return getLoadStorePointerOperand(I) == Ptr && isUniformDecision(I, VF);
- };
-
- // Holds a list of values which are known to have at least one uniform use.
- // Note that there may be other uses which aren't uniform. A "uniform use"
- // here is something which only demands lane 0 of the unrolled iterations;
- // it does not imply that all lanes produce the same value (e.g. this is not
- // the usual meaning of uniform)
- SmallPtrSet<Value *, 8> HasUniformUse;
-
- // Scan the loop for instructions which are either a) known to have only
- // lane 0 demanded or b) are uses which demand only lane 0 of their operand.
+
+
+ // Returns true if Ptr is the pointer operand of a memory access instruction
+ // I, and I is known to not require scalarization.
+ auto isVectorizedMemAccessUse = [&](Instruction *I, Value *Ptr) -> bool {
+ return getLoadStorePointerOperand(I) == Ptr && isUniformDecision(I, VF);
+ };
+
+ // Holds a list of values which are known to have at least one uniform use.
+ // Note that there may be other uses which aren't uniform. A "uniform use"
+ // here is something which only demands lane 0 of the unrolled iterations;
+ // it does not imply that all lanes produce the same value (e.g. this is not
+ // the usual meaning of uniform)
+ SmallPtrSet<Value *, 8> HasUniformUse;
+
+ // Scan the loop for instructions which are either a) known to have only
+ // lane 0 demanded or b) are uses which demand only lane 0 of their operand.
for (auto *BB : TheLoop->blocks())
for (auto &I : *BB) {
// If there's no pointer operand, there's nothing to do.
- auto *Ptr = getLoadStorePointerOperand(&I);
+ auto *Ptr = getLoadStorePointerOperand(&I);
if (!Ptr)
continue;
- // A uniform memory op is itself uniform. We exclude uniform stores
- // here as they demand the last lane, not the first one.
- if (isa<LoadInst>(I) && Legal->isUniformMemOp(I))
- addToWorklistIfAllowed(&I);
+ // A uniform memory op is itself uniform. We exclude uniform stores
+ // here as they demand the last lane, not the first one.
+ if (isa<LoadInst>(I) && Legal->isUniformMemOp(I))
+ addToWorklistIfAllowed(&I);
- if (isUniformDecision(&I, VF)) {
- assert(isVectorizedMemAccessUse(&I, Ptr) && "consistency check");
- HasUniformUse.insert(Ptr);
- }
+ if (isUniformDecision(&I, VF)) {
+ assert(isVectorizedMemAccessUse(&I, Ptr) && "consistency check");
+ HasUniformUse.insert(Ptr);
+ }
}
- // Add to the worklist any operands which have *only* uniform (e.g. lane 0
- // demanding) users. Since loops are assumed to be in LCSSA form, this
- // disallows uses outside the loop as well.
- for (auto *V : HasUniformUse) {
- if (isOutOfScope(V))
- continue;
- auto *I = cast<Instruction>(V);
- auto UsersAreMemAccesses =
- llvm::all_of(I->users(), [&](User *U) -> bool {
- return isVectorizedMemAccessUse(cast<Instruction>(U), V);
- });
- if (UsersAreMemAccesses)
- addToWorklistIfAllowed(I);
- }
+ // Add to the worklist any operands which have *only* uniform (e.g. lane 0
+ // demanding) users. Since loops are assumed to be in LCSSA form, this
+ // disallows uses outside the loop as well.
+ for (auto *V : HasUniformUse) {
+ if (isOutOfScope(V))
+ continue;
+ auto *I = cast<Instruction>(V);
+ auto UsersAreMemAccesses =
+ llvm::all_of(I->users(), [&](User *U) -> bool {
+ return isVectorizedMemAccessUse(cast<Instruction>(U), V);
+ });
+ if (UsersAreMemAccesses)
+ addToWorklistIfAllowed(I);
+ }
// Expand Worklist in topological order: whenever a new instruction
// is added , its users should be already inside Worklist. It ensures
@@ -5397,7 +5397,7 @@ void LoopVectorizationCostModel::collectLoopUniforms(ElementCount VF) {
auto *OI = cast<Instruction>(OV);
if (llvm::all_of(OI->users(), [&](User *U) -> bool {
auto *J = cast<Instruction>(U);
- return Worklist.count(J) || isVectorizedMemAccessUse(J, OI);
+ return Worklist.count(J) || isVectorizedMemAccessUse(J, OI);
}))
addToWorklistIfAllowed(OI);
}
@@ -5475,8 +5475,8 @@ bool LoopVectorizationCostModel::runtimeChecksRequired() {
return false;
}
-Optional<ElementCount>
-LoopVectorizationCostModel::computeMaxVF(ElementCount UserVF, unsigned UserIC) {
+Optional<ElementCount>
+LoopVectorizationCostModel::computeMaxVF(ElementCount UserVF, unsigned UserIC) {
if (Legal->getRuntimePointerChecking()->Need && TTI.hasBranchDivergence()) {
// TODO: It may by useful to do since it's still likely to be dynamically
// uniform if the target can skip.
@@ -5498,9 +5498,9 @@ LoopVectorizationCostModel::computeMaxVF(ElementCount UserVF, unsigned UserIC) {
switch (ScalarEpilogueStatus) {
case CM_ScalarEpilogueAllowed:
- return computeFeasibleMaxVF(TC, UserVF);
- case CM_ScalarEpilogueNotAllowedUsePredicate:
- LLVM_FALLTHROUGH;
+ return computeFeasibleMaxVF(TC, UserVF);
+ case CM_ScalarEpilogueNotAllowedUsePredicate:
+ LLVM_FALLTHROUGH;
case CM_ScalarEpilogueNotNeededUsePredicate:
LLVM_DEBUG(
dbgs() << "LV: vector predicate hint/switch found.\n"
@@ -5521,26 +5521,26 @@ LoopVectorizationCostModel::computeMaxVF(ElementCount UserVF, unsigned UserIC) {
// for size.
if (runtimeChecksRequired())
return None;
-
+
break;
}
- // The only loops we can vectorize without a scalar epilogue, are loops with
- // a bottom-test and a single exiting block. We'd have to handle the fact
- // that not every instruction executes on the last iteration. This will
- // require a lane mask which varies through the vector loop body. (TODO)
- if (TheLoop->getExitingBlock() != TheLoop->getLoopLatch()) {
- // If there was a tail-folding hint/switch, but we can't fold the tail by
- // masking, fallback to a vectorization with a scalar epilogue.
- if (ScalarEpilogueStatus == CM_ScalarEpilogueNotNeededUsePredicate) {
- LLVM_DEBUG(dbgs() << "LV: Cannot fold tail by masking: vectorize with a "
- "scalar epilogue instead.\n");
- ScalarEpilogueStatus = CM_ScalarEpilogueAllowed;
- return computeFeasibleMaxVF(TC, UserVF);
- }
- return None;
- }
-
+ // The only loops we can vectorize without a scalar epilogue, are loops with
+ // a bottom-test and a single exiting block. We'd have to handle the fact
+ // that not every instruction executes on the last iteration. This will
+ // require a lane mask which varies through the vector loop body. (TODO)
+ if (TheLoop->getExitingBlock() != TheLoop->getLoopLatch()) {
+ // If there was a tail-folding hint/switch, but we can't fold the tail by
+ // masking, fallback to a vectorization with a scalar epilogue.
+ if (ScalarEpilogueStatus == CM_ScalarEpilogueNotNeededUsePredicate) {
+ LLVM_DEBUG(dbgs() << "LV: Cannot fold tail by masking: vectorize with a "
+ "scalar epilogue instead.\n");
+ ScalarEpilogueStatus = CM_ScalarEpilogueAllowed;
+ return computeFeasibleMaxVF(TC, UserVF);
+ }
+ return None;
+ }
+
// Now try the tail folding
// Invalidate interleave groups that require an epilogue if we can't mask
@@ -5553,22 +5553,22 @@ LoopVectorizationCostModel::computeMaxVF(ElementCount UserVF, unsigned UserIC) {
InterleaveInfo.invalidateGroupsRequiringScalarEpilogue();
}
- ElementCount MaxVF = computeFeasibleMaxVF(TC, UserVF);
- assert(!MaxVF.isScalable() &&
- "Scalable vectors do not yet support tail folding");
- assert((UserVF.isNonZero() || isPowerOf2_32(MaxVF.getFixedValue())) &&
- "MaxVF must be a power of 2");
- unsigned MaxVFtimesIC =
- UserIC ? MaxVF.getFixedValue() * UserIC : MaxVF.getFixedValue();
- // Avoid tail folding if the trip count is known to be a multiple of any VF we
- // chose.
- ScalarEvolution *SE = PSE.getSE();
- const SCEV *BackedgeTakenCount = PSE.getBackedgeTakenCount();
- const SCEV *ExitCount = SE->getAddExpr(
- BackedgeTakenCount, SE->getOne(BackedgeTakenCount->getType()));
- const SCEV *Rem = SE->getURemExpr(
- ExitCount, SE->getConstant(BackedgeTakenCount->getType(), MaxVFtimesIC));
- if (Rem->isZero()) {
+ ElementCount MaxVF = computeFeasibleMaxVF(TC, UserVF);
+ assert(!MaxVF.isScalable() &&
+ "Scalable vectors do not yet support tail folding");
+ assert((UserVF.isNonZero() || isPowerOf2_32(MaxVF.getFixedValue())) &&
+ "MaxVF must be a power of 2");
+ unsigned MaxVFtimesIC =
+ UserIC ? MaxVF.getFixedValue() * UserIC : MaxVF.getFixedValue();
+ // Avoid tail folding if the trip count is known to be a multiple of any VF we
+ // chose.
+ ScalarEvolution *SE = PSE.getSE();
+ const SCEV *BackedgeTakenCount = PSE.getBackedgeTakenCount();
+ const SCEV *ExitCount = SE->getAddExpr(
+ BackedgeTakenCount, SE->getOne(BackedgeTakenCount->getType()));
+ const SCEV *Rem = SE->getURemExpr(
+ ExitCount, SE->getConstant(BackedgeTakenCount->getType(), MaxVFtimesIC));
+ if (Rem->isZero()) {
// Accept MaxVF if we do not have a tail.
LLVM_DEBUG(dbgs() << "LV: No tail will remain for any chosen VF.\n");
return MaxVF;
@@ -5583,20 +5583,20 @@ LoopVectorizationCostModel::computeMaxVF(ElementCount UserVF, unsigned UserIC) {
return MaxVF;
}
- // If there was a tail-folding hint/switch, but we can't fold the tail by
- // masking, fallback to a vectorization with a scalar epilogue.
- if (ScalarEpilogueStatus == CM_ScalarEpilogueNotNeededUsePredicate) {
- LLVM_DEBUG(dbgs() << "LV: Cannot fold tail by masking: vectorize with a "
- "scalar epilogue instead.\n");
- ScalarEpilogueStatus = CM_ScalarEpilogueAllowed;
- return MaxVF;
- }
-
- if (ScalarEpilogueStatus == CM_ScalarEpilogueNotAllowedUsePredicate) {
- LLVM_DEBUG(dbgs() << "LV: Can't fold tail by masking: don't vectorize\n");
- return None;
- }
-
+ // If there was a tail-folding hint/switch, but we can't fold the tail by
+ // masking, fallback to a vectorization with a scalar epilogue.
+ if (ScalarEpilogueStatus == CM_ScalarEpilogueNotNeededUsePredicate) {
+ LLVM_DEBUG(dbgs() << "LV: Cannot fold tail by masking: vectorize with a "
+ "scalar epilogue instead.\n");
+ ScalarEpilogueStatus = CM_ScalarEpilogueAllowed;
+ return MaxVF;
+ }
+
+ if (ScalarEpilogueStatus == CM_ScalarEpilogueNotAllowedUsePredicate) {
+ LLVM_DEBUG(dbgs() << "LV: Can't fold tail by masking: don't vectorize\n");
+ return None;
+ }
+
if (TC == 0) {
reportVectorizationFailure(
"Unable to calculate the loop count due to complex control flow",
@@ -5614,33 +5614,33 @@ LoopVectorizationCostModel::computeMaxVF(ElementCount UserVF, unsigned UserIC) {
return None;
}
-ElementCount
-LoopVectorizationCostModel::computeFeasibleMaxVF(unsigned ConstTripCount,
- ElementCount UserVF) {
- bool IgnoreScalableUserVF = UserVF.isScalable() &&
- !TTI.supportsScalableVectors() &&
- !ForceTargetSupportsScalableVectors;
- if (IgnoreScalableUserVF) {
- LLVM_DEBUG(
- dbgs() << "LV: Ignoring VF=" << UserVF
- << " because target does not support scalable vectors.\n");
- ORE->emit([&]() {
- return OptimizationRemarkAnalysis(DEBUG_TYPE, "IgnoreScalableUserVF",
- TheLoop->getStartLoc(),
- TheLoop->getHeader())
- << "Ignoring VF=" << ore::NV("UserVF", UserVF)
- << " because target does not support scalable vectors.";
- });
- }
-
- // Beyond this point two scenarios are handled. If UserVF isn't specified
- // then a suitable VF is chosen. If UserVF is specified and there are
- // dependencies, check if it's legal. However, if a UserVF is specified and
- // there are no dependencies, then there's nothing to do.
- if (UserVF.isNonZero() && !IgnoreScalableUserVF &&
- Legal->isSafeForAnyVectorWidth())
- return UserVF;
-
+ElementCount
+LoopVectorizationCostModel::computeFeasibleMaxVF(unsigned ConstTripCount,
+ ElementCount UserVF) {
+ bool IgnoreScalableUserVF = UserVF.isScalable() &&
+ !TTI.supportsScalableVectors() &&
+ !ForceTargetSupportsScalableVectors;
+ if (IgnoreScalableUserVF) {
+ LLVM_DEBUG(
+ dbgs() << "LV: Ignoring VF=" << UserVF
+ << " because target does not support scalable vectors.\n");
+ ORE->emit([&]() {
+ return OptimizationRemarkAnalysis(DEBUG_TYPE, "IgnoreScalableUserVF",
+ TheLoop->getStartLoc(),
+ TheLoop->getHeader())
+ << "Ignoring VF=" << ore::NV("UserVF", UserVF)
+ << " because target does not support scalable vectors.";
+ });
+ }
+
+ // Beyond this point two scenarios are handled. If UserVF isn't specified
+ // then a suitable VF is chosen. If UserVF is specified and there are
+ // dependencies, check if it's legal. However, if a UserVF is specified and
+ // there are no dependencies, then there's nothing to do.
+ if (UserVF.isNonZero() && !IgnoreScalableUserVF &&
+ Legal->isSafeForAnyVectorWidth())
+ return UserVF;
+
MinBWs = computeMinimumValueSizes(TheLoop->getBlocks(), *DB, &TTI);
unsigned SmallestType, WidestType;
std::tie(SmallestType, WidestType) = getSmallestAndWidestTypes();
@@ -5650,63 +5650,63 @@ LoopVectorizationCostModel::computeFeasibleMaxVF(unsigned ConstTripCount,
// It is computed by MaxVF * sizeOf(type) * 8, where type is taken from
// the memory accesses that is most restrictive (involved in the smallest
// dependence distance).
- unsigned MaxSafeVectorWidthInBits = Legal->getMaxSafeVectorWidthInBits();
-
- // If the user vectorization factor is legally unsafe, clamp it to a safe
- // value. Otherwise, return as is.
- if (UserVF.isNonZero() && !IgnoreScalableUserVF) {
- unsigned MaxSafeElements =
- PowerOf2Floor(MaxSafeVectorWidthInBits / WidestType);
- ElementCount MaxSafeVF = ElementCount::getFixed(MaxSafeElements);
-
- if (UserVF.isScalable()) {
- Optional<unsigned> MaxVScale = TTI.getMaxVScale();
-
- // Scale VF by vscale before checking if it's safe.
- MaxSafeVF = ElementCount::getScalable(
- MaxVScale ? (MaxSafeElements / MaxVScale.getValue()) : 0);
-
- if (MaxSafeVF.isZero()) {
- // The dependence distance is too small to use scalable vectors,
- // fallback on fixed.
- LLVM_DEBUG(
- dbgs()
- << "LV: Max legal vector width too small, scalable vectorization "
- "unfeasible. Using fixed-width vectorization instead.\n");
- ORE->emit([&]() {
- return OptimizationRemarkAnalysis(DEBUG_TYPE, "ScalableVFUnfeasible",
- TheLoop->getStartLoc(),
- TheLoop->getHeader())
- << "Max legal vector width too small, scalable vectorization "
- << "unfeasible. Using fixed-width vectorization instead.";
- });
- return computeFeasibleMaxVF(
- ConstTripCount, ElementCount::getFixed(UserVF.getKnownMinValue()));
- }
- }
-
- LLVM_DEBUG(dbgs() << "LV: The max safe VF is: " << MaxSafeVF << ".\n");
-
- if (ElementCount::isKnownLE(UserVF, MaxSafeVF))
- return UserVF;
-
- LLVM_DEBUG(dbgs() << "LV: User VF=" << UserVF
- << " is unsafe, clamping to max safe VF=" << MaxSafeVF
- << ".\n");
- ORE->emit([&]() {
- return OptimizationRemarkAnalysis(DEBUG_TYPE, "VectorizationFactor",
- TheLoop->getStartLoc(),
- TheLoop->getHeader())
- << "User-specified vectorization factor "
- << ore::NV("UserVectorizationFactor", UserVF)
- << " is unsafe, clamping to maximum safe vectorization factor "
- << ore::NV("VectorizationFactor", MaxSafeVF);
- });
- return MaxSafeVF;
- }
-
- WidestRegister = std::min(WidestRegister, MaxSafeVectorWidthInBits);
-
+ unsigned MaxSafeVectorWidthInBits = Legal->getMaxSafeVectorWidthInBits();
+
+ // If the user vectorization factor is legally unsafe, clamp it to a safe
+ // value. Otherwise, return as is.
+ if (UserVF.isNonZero() && !IgnoreScalableUserVF) {
+ unsigned MaxSafeElements =
+ PowerOf2Floor(MaxSafeVectorWidthInBits / WidestType);
+ ElementCount MaxSafeVF = ElementCount::getFixed(MaxSafeElements);
+
+ if (UserVF.isScalable()) {
+ Optional<unsigned> MaxVScale = TTI.getMaxVScale();
+
+ // Scale VF by vscale before checking if it's safe.
+ MaxSafeVF = ElementCount::getScalable(
+ MaxVScale ? (MaxSafeElements / MaxVScale.getValue()) : 0);
+
+ if (MaxSafeVF.isZero()) {
+ // The dependence distance is too small to use scalable vectors,
+ // fallback on fixed.
+ LLVM_DEBUG(
+ dbgs()
+ << "LV: Max legal vector width too small, scalable vectorization "
+ "unfeasible. Using fixed-width vectorization instead.\n");
+ ORE->emit([&]() {
+ return OptimizationRemarkAnalysis(DEBUG_TYPE, "ScalableVFUnfeasible",
+ TheLoop->getStartLoc(),
+ TheLoop->getHeader())
+ << "Max legal vector width too small, scalable vectorization "
+ << "unfeasible. Using fixed-width vectorization instead.";
+ });
+ return computeFeasibleMaxVF(
+ ConstTripCount, ElementCount::getFixed(UserVF.getKnownMinValue()));
+ }
+ }
+
+ LLVM_DEBUG(dbgs() << "LV: The max safe VF is: " << MaxSafeVF << ".\n");
+
+ if (ElementCount::isKnownLE(UserVF, MaxSafeVF))
+ return UserVF;
+
+ LLVM_DEBUG(dbgs() << "LV: User VF=" << UserVF
+ << " is unsafe, clamping to max safe VF=" << MaxSafeVF
+ << ".\n");
+ ORE->emit([&]() {
+ return OptimizationRemarkAnalysis(DEBUG_TYPE, "VectorizationFactor",
+ TheLoop->getStartLoc(),
+ TheLoop->getHeader())
+ << "User-specified vectorization factor "
+ << ore::NV("UserVectorizationFactor", UserVF)
+ << " is unsafe, clamping to maximum safe vectorization factor "
+ << ore::NV("VectorizationFactor", MaxSafeVF);
+ });
+ return MaxSafeVF;
+ }
+
+ WidestRegister = std::min(WidestRegister, MaxSafeVectorWidthInBits);
+
// Ensure MaxVF is a power of 2; the dependence distance bound may not be.
// Note that both WidestRegister and WidestType may not be a powers of 2.
unsigned MaxVectorSize = PowerOf2Floor(WidestRegister / WidestType);
@@ -5716,13 +5716,13 @@ LoopVectorizationCostModel::computeFeasibleMaxVF(unsigned ConstTripCount,
LLVM_DEBUG(dbgs() << "LV: The Widest register safe to use is: "
<< WidestRegister << " bits.\n");
- assert(MaxVectorSize <= WidestRegister &&
- "Did not expect to pack so many elements"
- " into one vector!");
+ assert(MaxVectorSize <= WidestRegister &&
+ "Did not expect to pack so many elements"
+ " into one vector!");
if (MaxVectorSize == 0) {
LLVM_DEBUG(dbgs() << "LV: The target has no vector registers.\n");
MaxVectorSize = 1;
- return ElementCount::getFixed(MaxVectorSize);
+ return ElementCount::getFixed(MaxVectorSize);
} else if (ConstTripCount && ConstTripCount < MaxVectorSize &&
isPowerOf2_32(ConstTripCount)) {
// We need to clamp the VF to be the ConstTripCount. There is no point in
@@ -5730,7 +5730,7 @@ LoopVectorizationCostModel::computeFeasibleMaxVF(unsigned ConstTripCount,
LLVM_DEBUG(dbgs() << "LV: Clamping the MaxVF to the constant trip count: "
<< ConstTripCount << "\n");
MaxVectorSize = ConstTripCount;
- return ElementCount::getFixed(MaxVectorSize);
+ return ElementCount::getFixed(MaxVectorSize);
}
unsigned MaxVF = MaxVectorSize;
@@ -5738,10 +5738,10 @@ LoopVectorizationCostModel::computeFeasibleMaxVF(unsigned ConstTripCount,
(MaximizeBandwidth && isScalarEpilogueAllowed())) {
// Collect all viable vectorization factors larger than the default MaxVF
// (i.e. MaxVectorSize).
- SmallVector<ElementCount, 8> VFs;
+ SmallVector<ElementCount, 8> VFs;
unsigned NewMaxVectorSize = WidestRegister / SmallestType;
for (unsigned VS = MaxVectorSize * 2; VS <= NewMaxVectorSize; VS *= 2)
- VFs.push_back(ElementCount::getFixed(VS));
+ VFs.push_back(ElementCount::getFixed(VS));
// For each VF calculate its register usage.
auto RUs = calculateRegisterUsage(VFs);
@@ -5756,7 +5756,7 @@ LoopVectorizationCostModel::computeFeasibleMaxVF(unsigned ConstTripCount,
Selected = false;
}
if (Selected) {
- MaxVF = VFs[i].getKnownMinValue();
+ MaxVF = VFs[i].getKnownMinValue();
break;
}
}
@@ -5768,39 +5768,39 @@ LoopVectorizationCostModel::computeFeasibleMaxVF(unsigned ConstTripCount,
}
}
}
- return ElementCount::getFixed(MaxVF);
+ return ElementCount::getFixed(MaxVF);
}
VectorizationFactor
-LoopVectorizationCostModel::selectVectorizationFactor(ElementCount MaxVF) {
- // FIXME: This can be fixed for scalable vectors later, because at this stage
- // the LoopVectorizer will only consider vectorizing a loop with scalable
- // vectors when the loop has a hint to enable vectorization for a given VF.
- assert(!MaxVF.isScalable() && "scalable vectors not yet supported");
-
- InstructionCost ExpectedCost = expectedCost(ElementCount::getFixed(1)).first;
- LLVM_DEBUG(dbgs() << "LV: Scalar loop costs: " << ExpectedCost << ".\n");
- assert(ExpectedCost.isValid() && "Unexpected invalid cost for scalar loop");
-
+LoopVectorizationCostModel::selectVectorizationFactor(ElementCount MaxVF) {
+ // FIXME: This can be fixed for scalable vectors later, because at this stage
+ // the LoopVectorizer will only consider vectorizing a loop with scalable
+ // vectors when the loop has a hint to enable vectorization for a given VF.
+ assert(!MaxVF.isScalable() && "scalable vectors not yet supported");
+
+ InstructionCost ExpectedCost = expectedCost(ElementCount::getFixed(1)).first;
+ LLVM_DEBUG(dbgs() << "LV: Scalar loop costs: " << ExpectedCost << ".\n");
+ assert(ExpectedCost.isValid() && "Unexpected invalid cost for scalar loop");
+
unsigned Width = 1;
- const float ScalarCost = *ExpectedCost.getValue();
- float Cost = ScalarCost;
+ const float ScalarCost = *ExpectedCost.getValue();
+ float Cost = ScalarCost;
bool ForceVectorization = Hints->getForce() == LoopVectorizeHints::FK_Enabled;
- if (ForceVectorization && MaxVF.isVector()) {
+ if (ForceVectorization && MaxVF.isVector()) {
// Ignore scalar width, because the user explicitly wants vectorization.
// Initialize cost to max so that VF = 2 is, at least, chosen during cost
// evaluation.
Cost = std::numeric_limits<float>::max();
}
- for (unsigned i = 2; i <= MaxVF.getFixedValue(); i *= 2) {
+ for (unsigned i = 2; i <= MaxVF.getFixedValue(); i *= 2) {
// Notice that the vector loop needs to be executed less times, so
// we need to divide the cost of the vector loops by the width of
// the vector elements.
- VectorizationCostTy C = expectedCost(ElementCount::getFixed(i));
- assert(C.first.isValid() && "Unexpected invalid cost for vector loop");
- float VectorCost = *C.first.getValue() / (float)i;
+ VectorizationCostTy C = expectedCost(ElementCount::getFixed(i));
+ assert(C.first.isValid() && "Unexpected invalid cost for vector loop");
+ float VectorCost = *C.first.getValue() / (float)i;
LLVM_DEBUG(dbgs() << "LV: Vector loop of width " << i
<< " costs: " << (int)VectorCost << ".\n");
if (!C.second && !ForceVectorization) {
@@ -5809,13 +5809,13 @@ LoopVectorizationCostModel::selectVectorizationFactor(ElementCount MaxVF) {
<< " because it will not generate any vector instructions.\n");
continue;
}
-
- // If profitable add it to ProfitableVF list.
- if (VectorCost < ScalarCost) {
- ProfitableVFs.push_back(VectorizationFactor(
- {ElementCount::getFixed(i), (unsigned)VectorCost}));
- }
-
+
+ // If profitable add it to ProfitableVF list.
+ if (VectorCost < ScalarCost) {
+ ProfitableVFs.push_back(VectorizationFactor(
+ {ElementCount::getFixed(i), (unsigned)VectorCost}));
+ }
+
if (VectorCost < Cost) {
Cost = VectorCost;
Width = i;
@@ -5834,131 +5834,131 @@ LoopVectorizationCostModel::selectVectorizationFactor(ElementCount MaxVF) {
<< "LV: Vectorization seems to be not beneficial, "
<< "but was forced by a user.\n");
LLVM_DEBUG(dbgs() << "LV: Selecting VF: " << Width << ".\n");
- VectorizationFactor Factor = {ElementCount::getFixed(Width),
- (unsigned)(Width * Cost)};
+ VectorizationFactor Factor = {ElementCount::getFixed(Width),
+ (unsigned)(Width * Cost)};
return Factor;
}
-bool LoopVectorizationCostModel::isCandidateForEpilogueVectorization(
- const Loop &L, ElementCount VF) const {
- // Cross iteration phis such as reductions need special handling and are
- // currently unsupported.
- if (any_of(L.getHeader()->phis(), [&](PHINode &Phi) {
- return Legal->isFirstOrderRecurrence(&Phi) ||
- Legal->isReductionVariable(&Phi);
- }))
- return false;
-
- // Phis with uses outside of the loop require special handling and are
- // currently unsupported.
- for (auto &Entry : Legal->getInductionVars()) {
- // Look for uses of the value of the induction at the last iteration.
- Value *PostInc = Entry.first->getIncomingValueForBlock(L.getLoopLatch());
- for (User *U : PostInc->users())
- if (!L.contains(cast<Instruction>(U)))
- return false;
- // Look for uses of penultimate value of the induction.
- for (User *U : Entry.first->users())
- if (!L.contains(cast<Instruction>(U)))
- return false;
- }
-
- // Induction variables that are widened require special handling that is
- // currently not supported.
- if (any_of(Legal->getInductionVars(), [&](auto &Entry) {
- return !(this->isScalarAfterVectorization(Entry.first, VF) ||
- this->isProfitableToScalarize(Entry.first, VF));
- }))
- return false;
-
- return true;
-}
-
-bool LoopVectorizationCostModel::isEpilogueVectorizationProfitable(
- const ElementCount VF) const {
- // FIXME: We need a much better cost-model to take different parameters such
- // as register pressure, code size increase and cost of extra branches into
- // account. For now we apply a very crude heuristic and only consider loops
- // with vectorization factors larger than a certain value.
- // We also consider epilogue vectorization unprofitable for targets that don't
- // consider interleaving beneficial (eg. MVE).
- if (TTI.getMaxInterleaveFactor(VF.getKnownMinValue()) <= 1)
- return false;
- if (VF.getFixedValue() >= EpilogueVectorizationMinVF)
- return true;
- return false;
-}
-
-VectorizationFactor
-LoopVectorizationCostModel::selectEpilogueVectorizationFactor(
- const ElementCount MainLoopVF, const LoopVectorizationPlanner &LVP) {
- VectorizationFactor Result = VectorizationFactor::Disabled();
- if (!EnableEpilogueVectorization) {
- LLVM_DEBUG(dbgs() << "LEV: Epilogue vectorization is disabled.\n";);
- return Result;
- }
-
- if (!isScalarEpilogueAllowed()) {
- LLVM_DEBUG(
- dbgs() << "LEV: Unable to vectorize epilogue because no epilogue is "
- "allowed.\n";);
- return Result;
- }
-
- // FIXME: This can be fixed for scalable vectors later, because at this stage
- // the LoopVectorizer will only consider vectorizing a loop with scalable
- // vectors when the loop has a hint to enable vectorization for a given VF.
- if (MainLoopVF.isScalable()) {
- LLVM_DEBUG(dbgs() << "LEV: Epilogue vectorization for scalable vectors not "
- "yet supported.\n");
- return Result;
- }
-
- // Not really a cost consideration, but check for unsupported cases here to
- // simplify the logic.
- if (!isCandidateForEpilogueVectorization(*TheLoop, MainLoopVF)) {
- LLVM_DEBUG(
- dbgs() << "LEV: Unable to vectorize epilogue because the loop is "
- "not a supported candidate.\n";);
- return Result;
- }
-
- if (EpilogueVectorizationForceVF > 1) {
- LLVM_DEBUG(dbgs() << "LEV: Epilogue vectorization factor is forced.\n";);
- if (LVP.hasPlanWithVFs(
- {MainLoopVF, ElementCount::getFixed(EpilogueVectorizationForceVF)}))
- return {ElementCount::getFixed(EpilogueVectorizationForceVF), 0};
- else {
- LLVM_DEBUG(
- dbgs()
- << "LEV: Epilogue vectorization forced factor is not viable.\n";);
- return Result;
- }
- }
-
- if (TheLoop->getHeader()->getParent()->hasOptSize() ||
- TheLoop->getHeader()->getParent()->hasMinSize()) {
- LLVM_DEBUG(
- dbgs()
- << "LEV: Epilogue vectorization skipped due to opt for size.\n";);
- return Result;
- }
-
- if (!isEpilogueVectorizationProfitable(MainLoopVF))
- return Result;
-
- for (auto &NextVF : ProfitableVFs)
- if (ElementCount::isKnownLT(NextVF.Width, MainLoopVF) &&
- (Result.Width.getFixedValue() == 1 || NextVF.Cost < Result.Cost) &&
- LVP.hasPlanWithVFs({MainLoopVF, NextVF.Width}))
- Result = NextVF;
-
- if (Result != VectorizationFactor::Disabled())
- LLVM_DEBUG(dbgs() << "LEV: Vectorizing epilogue loop with VF = "
- << Result.Width.getFixedValue() << "\n";);
- return Result;
-}
-
+bool LoopVectorizationCostModel::isCandidateForEpilogueVectorization(
+ const Loop &L, ElementCount VF) const {
+ // Cross iteration phis such as reductions need special handling and are
+ // currently unsupported.
+ if (any_of(L.getHeader()->phis(), [&](PHINode &Phi) {
+ return Legal->isFirstOrderRecurrence(&Phi) ||
+ Legal->isReductionVariable(&Phi);
+ }))
+ return false;
+
+ // Phis with uses outside of the loop require special handling and are
+ // currently unsupported.
+ for (auto &Entry : Legal->getInductionVars()) {
+ // Look for uses of the value of the induction at the last iteration.
+ Value *PostInc = Entry.first->getIncomingValueForBlock(L.getLoopLatch());
+ for (User *U : PostInc->users())
+ if (!L.contains(cast<Instruction>(U)))
+ return false;
+ // Look for uses of penultimate value of the induction.
+ for (User *U : Entry.first->users())
+ if (!L.contains(cast<Instruction>(U)))
+ return false;
+ }
+
+ // Induction variables that are widened require special handling that is
+ // currently not supported.
+ if (any_of(Legal->getInductionVars(), [&](auto &Entry) {
+ return !(this->isScalarAfterVectorization(Entry.first, VF) ||
+ this->isProfitableToScalarize(Entry.first, VF));
+ }))
+ return false;
+
+ return true;
+}
+
+bool LoopVectorizationCostModel::isEpilogueVectorizationProfitable(
+ const ElementCount VF) const {
+ // FIXME: We need a much better cost-model to take different parameters such
+ // as register pressure, code size increase and cost of extra branches into
+ // account. For now we apply a very crude heuristic and only consider loops
+ // with vectorization factors larger than a certain value.
+ // We also consider epilogue vectorization unprofitable for targets that don't
+ // consider interleaving beneficial (eg. MVE).
+ if (TTI.getMaxInterleaveFactor(VF.getKnownMinValue()) <= 1)
+ return false;
+ if (VF.getFixedValue() >= EpilogueVectorizationMinVF)
+ return true;
+ return false;
+}
+
+VectorizationFactor
+LoopVectorizationCostModel::selectEpilogueVectorizationFactor(
+ const ElementCount MainLoopVF, const LoopVectorizationPlanner &LVP) {
+ VectorizationFactor Result = VectorizationFactor::Disabled();
+ if (!EnableEpilogueVectorization) {
+ LLVM_DEBUG(dbgs() << "LEV: Epilogue vectorization is disabled.\n";);
+ return Result;
+ }
+
+ if (!isScalarEpilogueAllowed()) {
+ LLVM_DEBUG(
+ dbgs() << "LEV: Unable to vectorize epilogue because no epilogue is "
+ "allowed.\n";);
+ return Result;
+ }
+
+ // FIXME: This can be fixed for scalable vectors later, because at this stage
+ // the LoopVectorizer will only consider vectorizing a loop with scalable
+ // vectors when the loop has a hint to enable vectorization for a given VF.
+ if (MainLoopVF.isScalable()) {
+ LLVM_DEBUG(dbgs() << "LEV: Epilogue vectorization for scalable vectors not "
+ "yet supported.\n");
+ return Result;
+ }
+
+ // Not really a cost consideration, but check for unsupported cases here to
+ // simplify the logic.
+ if (!isCandidateForEpilogueVectorization(*TheLoop, MainLoopVF)) {
+ LLVM_DEBUG(
+ dbgs() << "LEV: Unable to vectorize epilogue because the loop is "
+ "not a supported candidate.\n";);
+ return Result;
+ }
+
+ if (EpilogueVectorizationForceVF > 1) {
+ LLVM_DEBUG(dbgs() << "LEV: Epilogue vectorization factor is forced.\n";);
+ if (LVP.hasPlanWithVFs(
+ {MainLoopVF, ElementCount::getFixed(EpilogueVectorizationForceVF)}))
+ return {ElementCount::getFixed(EpilogueVectorizationForceVF), 0};
+ else {
+ LLVM_DEBUG(
+ dbgs()
+ << "LEV: Epilogue vectorization forced factor is not viable.\n";);
+ return Result;
+ }
+ }
+
+ if (TheLoop->getHeader()->getParent()->hasOptSize() ||
+ TheLoop->getHeader()->getParent()->hasMinSize()) {
+ LLVM_DEBUG(
+ dbgs()
+ << "LEV: Epilogue vectorization skipped due to opt for size.\n";);
+ return Result;
+ }
+
+ if (!isEpilogueVectorizationProfitable(MainLoopVF))
+ return Result;
+
+ for (auto &NextVF : ProfitableVFs)
+ if (ElementCount::isKnownLT(NextVF.Width, MainLoopVF) &&
+ (Result.Width.getFixedValue() == 1 || NextVF.Cost < Result.Cost) &&
+ LVP.hasPlanWithVFs({MainLoopVF, NextVF.Width}))
+ Result = NextVF;
+
+ if (Result != VectorizationFactor::Disabled())
+ LLVM_DEBUG(dbgs() << "LEV: Vectorizing epilogue loop with VF = "
+ << Result.Width.getFixedValue() << "\n";);
+ return Result;
+}
+
std::pair<unsigned, unsigned>
LoopVectorizationCostModel::getSmallestAndWidestTypes() {
unsigned MinWidth = -1U;
@@ -5985,11 +5985,11 @@ LoopVectorizationCostModel::getSmallestAndWidestTypes() {
if (!Legal->isReductionVariable(PN))
continue;
RecurrenceDescriptor RdxDesc = Legal->getReductionVars()[PN];
- if (PreferInLoopReductions ||
- TTI.preferInLoopReduction(RdxDesc.getOpcode(),
- RdxDesc.getRecurrenceType(),
- TargetTransformInfo::ReductionFlags()))
- continue;
+ if (PreferInLoopReductions ||
+ TTI.preferInLoopReduction(RdxDesc.getOpcode(),
+ RdxDesc.getRecurrenceType(),
+ TargetTransformInfo::ReductionFlags()))
+ continue;
T = RdxDesc.getRecurrenceType();
}
@@ -6020,7 +6020,7 @@ LoopVectorizationCostModel::getSmallestAndWidestTypes() {
return {MinWidth, MaxWidth};
}
-unsigned LoopVectorizationCostModel::selectInterleaveCount(ElementCount VF,
+unsigned LoopVectorizationCostModel::selectInterleaveCount(ElementCount VF,
unsigned LoopCost) {
// -- The interleave heuristics --
// We interleave the loop in order to expose ILP and reduce the loop overhead.
@@ -6043,15 +6043,15 @@ unsigned LoopVectorizationCostModel::selectInterleaveCount(ElementCount VF,
if (Legal->getMaxSafeDepDistBytes() != -1U)
return 1;
- auto BestKnownTC = getSmallBestKnownTC(*PSE.getSE(), TheLoop);
- const bool HasReductions = !Legal->getReductionVars().empty();
+ auto BestKnownTC = getSmallBestKnownTC(*PSE.getSE(), TheLoop);
+ const bool HasReductions = !Legal->getReductionVars().empty();
// Do not interleave loops with a relatively small known or estimated trip
- // count. But we will interleave when InterleaveSmallLoopScalarReduction is
- // enabled, and the code has scalar reductions(HasReductions && VF = 1),
- // because with the above conditions interleaving can expose ILP and break
- // cross iteration dependences for reductions.
- if (BestKnownTC && (*BestKnownTC < TinyTripCountInterleaveThreshold) &&
- !(InterleaveSmallLoopScalarReduction && HasReductions && VF.isScalar()))
+ // count. But we will interleave when InterleaveSmallLoopScalarReduction is
+ // enabled, and the code has scalar reductions(HasReductions && VF = 1),
+ // because with the above conditions interleaving can expose ILP and break
+ // cross iteration dependences for reductions.
+ if (BestKnownTC && (*BestKnownTC < TinyTripCountInterleaveThreshold) &&
+ !(InterleaveSmallLoopScalarReduction && HasReductions && VF.isScalar()))
return 1;
RegisterUsage R = calculateRegisterUsage({VF})[0];
@@ -6079,7 +6079,7 @@ unsigned LoopVectorizationCostModel::selectInterleaveCount(ElementCount VF,
LLVM_DEBUG(dbgs() << "LV: The target has " << TargetNumRegisters
<< " registers of "
<< TTI.getRegisterClassName(pair.first) << " register class\n");
- if (VF.isScalar()) {
+ if (VF.isScalar()) {
if (ForceTargetNumScalarRegs.getNumOccurrences() > 0)
TargetNumRegisters = ForceTargetNumScalarRegs;
} else {
@@ -6103,11 +6103,11 @@ unsigned LoopVectorizationCostModel::selectInterleaveCount(ElementCount VF,
}
// Clamp the interleave ranges to reasonable counts.
- unsigned MaxInterleaveCount =
- TTI.getMaxInterleaveFactor(VF.getKnownMinValue());
+ unsigned MaxInterleaveCount =
+ TTI.getMaxInterleaveFactor(VF.getKnownMinValue());
// Check if the user has overridden the max.
- if (VF.isScalar()) {
+ if (VF.isScalar()) {
if (ForceTargetMaxScalarInterleaveFactor.getNumOccurrences() > 0)
MaxInterleaveCount = ForceTargetMaxScalarInterleaveFactor;
} else {
@@ -6116,47 +6116,47 @@ unsigned LoopVectorizationCostModel::selectInterleaveCount(ElementCount VF,
}
// If trip count is known or estimated compile time constant, limit the
- // interleave count to be less than the trip count divided by VF, provided it
- // is at least 1.
- //
- // For scalable vectors we can't know if interleaving is beneficial. It may
- // not be beneficial for small loops if none of the lanes in the second vector
- // iterations is enabled. However, for larger loops, there is likely to be a
- // similar benefit as for fixed-width vectors. For now, we choose to leave
- // the InterleaveCount as if vscale is '1', although if some information about
- // the vector is known (e.g. min vector size), we can make a better decision.
+ // interleave count to be less than the trip count divided by VF, provided it
+ // is at least 1.
+ //
+ // For scalable vectors we can't know if interleaving is beneficial. It may
+ // not be beneficial for small loops if none of the lanes in the second vector
+ // iterations is enabled. However, for larger loops, there is likely to be a
+ // similar benefit as for fixed-width vectors. For now, we choose to leave
+ // the InterleaveCount as if vscale is '1', although if some information about
+ // the vector is known (e.g. min vector size), we can make a better decision.
if (BestKnownTC) {
- MaxInterleaveCount =
- std::min(*BestKnownTC / VF.getKnownMinValue(), MaxInterleaveCount);
- // Make sure MaxInterleaveCount is greater than 0.
- MaxInterleaveCount = std::max(1u, MaxInterleaveCount);
+ MaxInterleaveCount =
+ std::min(*BestKnownTC / VF.getKnownMinValue(), MaxInterleaveCount);
+ // Make sure MaxInterleaveCount is greater than 0.
+ MaxInterleaveCount = std::max(1u, MaxInterleaveCount);
}
- assert(MaxInterleaveCount > 0 &&
- "Maximum interleave count must be greater than 0");
+ assert(MaxInterleaveCount > 0 &&
+ "Maximum interleave count must be greater than 0");
// Clamp the calculated IC to be between the 1 and the max interleave count
// that the target and trip count allows.
if (IC > MaxInterleaveCount)
IC = MaxInterleaveCount;
- else
- // Make sure IC is greater than 0.
- IC = std::max(1u, IC);
-
- assert(IC > 0 && "Interleave count must be greater than 0.");
-
- // If we did not calculate the cost for VF (because the user selected the VF)
- // then we calculate the cost of VF here.
- if (LoopCost == 0) {
- assert(expectedCost(VF).first.isValid() && "Expected a valid cost");
- LoopCost = *expectedCost(VF).first.getValue();
- }
-
- assert(LoopCost && "Non-zero loop cost expected");
-
+ else
+ // Make sure IC is greater than 0.
+ IC = std::max(1u, IC);
+
+ assert(IC > 0 && "Interleave count must be greater than 0.");
+
+ // If we did not calculate the cost for VF (because the user selected the VF)
+ // then we calculate the cost of VF here.
+ if (LoopCost == 0) {
+ assert(expectedCost(VF).first.isValid() && "Expected a valid cost");
+ LoopCost = *expectedCost(VF).first.getValue();
+ }
+
+ assert(LoopCost && "Non-zero loop cost expected");
+
// Interleave if we vectorized this loop and there is a reduction that could
// benefit from interleaving.
- if (VF.isVector() && HasReductions) {
+ if (VF.isVector() && HasReductions) {
LLVM_DEBUG(dbgs() << "LV: Interleaving because of reductions.\n");
return IC;
}
@@ -6164,15 +6164,15 @@ unsigned LoopVectorizationCostModel::selectInterleaveCount(ElementCount VF,
// Note that if we've already vectorized the loop we will have done the
// runtime check and so interleaving won't require further checks.
bool InterleavingRequiresRuntimePointerCheck =
- (VF.isScalar() && Legal->getRuntimePointerChecking()->Need);
+ (VF.isScalar() && Legal->getRuntimePointerChecking()->Need);
// We want to interleave small loops in order to reduce the loop overhead and
// potentially expose ILP opportunities.
- LLVM_DEBUG(dbgs() << "LV: Loop cost is " << LoopCost << '\n'
- << "LV: IC is " << IC << '\n'
- << "LV: VF is " << VF << '\n');
- const bool AggressivelyInterleaveReductions =
- TTI.enableAggressiveInterleaving(HasReductions);
+ LLVM_DEBUG(dbgs() << "LV: Loop cost is " << LoopCost << '\n'
+ << "LV: IC is " << IC << '\n'
+ << "LV: VF is " << VF << '\n');
+ const bool AggressivelyInterleaveReductions =
+ TTI.enableAggressiveInterleaving(HasReductions);
if (!InterleavingRequiresRuntimePointerCheck && LoopCost < SmallLoopCost) {
// We assume that the cost overhead is 1 and we use the cost model
// to estimate the cost of the loop and interleave until the cost of the
@@ -6191,7 +6191,7 @@ unsigned LoopVectorizationCostModel::selectInterleaveCount(ElementCount VF,
// by this point), we can increase the critical path length if the loop
// we're interleaving is inside another loop. Limit, by default to 2, so the
// critical path only gets increased by one reduction operation.
- if (HasReductions && TheLoop->getLoopDepth() > 1) {
+ if (HasReductions && TheLoop->getLoopDepth() > 1) {
unsigned F = static_cast<unsigned>(MaxNestedScalarReductionIC);
SmallIC = std::min(SmallIC, F);
StoresIC = std::min(StoresIC, F);
@@ -6205,23 +6205,23 @@ unsigned LoopVectorizationCostModel::selectInterleaveCount(ElementCount VF,
return std::max(StoresIC, LoadsIC);
}
- // If there are scalar reductions and TTI has enabled aggressive
- // interleaving for reductions, we will interleave to expose ILP.
- if (InterleaveSmallLoopScalarReduction && VF.isScalar() &&
- AggressivelyInterleaveReductions) {
- LLVM_DEBUG(dbgs() << "LV: Interleaving to expose ILP.\n");
- // Interleave no less than SmallIC but not as aggressive as the normal IC
- // to satisfy the rare situation when resources are too limited.
- return std::max(IC / 2, SmallIC);
- } else {
- LLVM_DEBUG(dbgs() << "LV: Interleaving to reduce branch cost.\n");
- return SmallIC;
- }
+ // If there are scalar reductions and TTI has enabled aggressive
+ // interleaving for reductions, we will interleave to expose ILP.
+ if (InterleaveSmallLoopScalarReduction && VF.isScalar() &&
+ AggressivelyInterleaveReductions) {
+ LLVM_DEBUG(dbgs() << "LV: Interleaving to expose ILP.\n");
+ // Interleave no less than SmallIC but not as aggressive as the normal IC
+ // to satisfy the rare situation when resources are too limited.
+ return std::max(IC / 2, SmallIC);
+ } else {
+ LLVM_DEBUG(dbgs() << "LV: Interleaving to reduce branch cost.\n");
+ return SmallIC;
+ }
}
// Interleave if this is a large loop (small loops are already dealt with by
// this point) that could benefit from interleaving.
- if (AggressivelyInterleaveReductions) {
+ if (AggressivelyInterleaveReductions) {
LLVM_DEBUG(dbgs() << "LV: Interleaving to expose ILP.\n");
return IC;
}
@@ -6231,7 +6231,7 @@ unsigned LoopVectorizationCostModel::selectInterleaveCount(ElementCount VF,
}
SmallVector<LoopVectorizationCostModel::RegisterUsage, 8>
-LoopVectorizationCostModel::calculateRegisterUsage(ArrayRef<ElementCount> VFs) {
+LoopVectorizationCostModel::calculateRegisterUsage(ArrayRef<ElementCount> VFs) {
// This function calculates the register usage by measuring the highest number
// of values that are alive at a single location. Obviously, this is a very
// rough estimation. We scan the loop in a topological order in order and
@@ -6309,11 +6309,11 @@ LoopVectorizationCostModel::calculateRegisterUsage(ArrayRef<ElementCount> VFs) {
LLVM_DEBUG(dbgs() << "LV(REG): Calculating max register usage:\n");
// A lambda that gets the register usage for the given type and VF.
- const auto &TTICapture = TTI;
- auto GetRegUsage = [&TTICapture](Type *Ty, ElementCount VF) {
- if (Ty->isTokenTy() || !VectorType::isValidElementType(Ty))
+ const auto &TTICapture = TTI;
+ auto GetRegUsage = [&TTICapture](Type *Ty, ElementCount VF) {
+ if (Ty->isTokenTy() || !VectorType::isValidElementType(Ty))
return 0U;
- return TTICapture.getRegUsageForType(VectorType::get(Ty, VF));
+ return TTICapture.getRegUsageForType(VectorType::get(Ty, VF));
};
for (unsigned int i = 0, s = IdxToInstr.size(); i < s; ++i) {
@@ -6337,7 +6337,7 @@ LoopVectorizationCostModel::calculateRegisterUsage(ArrayRef<ElementCount> VFs) {
// Count the number of live intervals.
SmallMapVector<unsigned, unsigned, 4> RegUsage;
- if (VFs[j].isScalar()) {
+ if (VFs[j].isScalar()) {
for (auto Inst : OpenIntervals) {
unsigned ClassID = TTI.getRegisterClassForType(false, Inst->getType());
if (RegUsage.find(ClassID) == RegUsage.end())
@@ -6366,7 +6366,7 @@ LoopVectorizationCostModel::calculateRegisterUsage(ArrayRef<ElementCount> VFs) {
}
}
}
-
+
for (auto& pair : RegUsage) {
if (MaxUsages[j].find(pair.first) != MaxUsages[j].end())
MaxUsages[j][pair.first] = std::max(MaxUsages[j][pair.first], pair.second);
@@ -6384,12 +6384,12 @@ LoopVectorizationCostModel::calculateRegisterUsage(ArrayRef<ElementCount> VFs) {
for (unsigned i = 0, e = VFs.size(); i < e; ++i) {
SmallMapVector<unsigned, unsigned, 4> Invariant;
-
+
for (auto Inst : LoopInvariants) {
- unsigned Usage =
- VFs[i].isScalar() ? 1 : GetRegUsage(Inst->getType(), VFs[i]);
- unsigned ClassID =
- TTI.getRegisterClassForType(VFs[i].isVector(), Inst->getType());
+ unsigned Usage =
+ VFs[i].isScalar() ? 1 : GetRegUsage(Inst->getType(), VFs[i]);
+ unsigned ClassID =
+ TTI.getRegisterClassForType(VFs[i].isVector(), Inst->getType());
if (Invariant.find(ClassID) == Invariant.end())
Invariant[ClassID] = Usage;
else
@@ -6437,13 +6437,13 @@ bool LoopVectorizationCostModel::useEmulatedMaskMemRefHack(Instruction *I){
NumPredStores > NumberOfStoresToPredicate);
}
-void LoopVectorizationCostModel::collectInstsToScalarize(ElementCount VF) {
+void LoopVectorizationCostModel::collectInstsToScalarize(ElementCount VF) {
// If we aren't vectorizing the loop, or if we've already collected the
// instructions to scalarize, there's nothing to do. Collection may already
// have occurred if we have a user-selected VF and are now computing the
// expected cost for interleaving.
- if (VF.isScalar() || VF.isZero() ||
- InstsToScalarize.find(VF) != InstsToScalarize.end())
+ if (VF.isScalar() || VF.isZero() ||
+ InstsToScalarize.find(VF) != InstsToScalarize.end())
return;
// Initialize a mapping for VF in InstsToScalalarize. If we find that it's
@@ -6472,13 +6472,13 @@ void LoopVectorizationCostModel::collectInstsToScalarize(ElementCount VF) {
}
int LoopVectorizationCostModel::computePredInstDiscount(
- Instruction *PredInst, ScalarCostsTy &ScalarCosts, ElementCount VF) {
+ Instruction *PredInst, ScalarCostsTy &ScalarCosts, ElementCount VF) {
assert(!isUniformAfterVectorization(PredInst, VF) &&
"Instruction marked uniform-after-vectorization will be predicated");
// Initialize the discount to zero, meaning that the scalar version and the
// vector version cost the same.
- InstructionCost Discount = 0;
+ InstructionCost Discount = 0;
// Holds instructions to analyze. The instructions we visit are mapped in
// ScalarCosts. Those instructions are the ones that would be scalarized if
@@ -6533,27 +6533,27 @@ int LoopVectorizationCostModel::computePredInstDiscount(
// Compute the cost of the vector instruction. Note that this cost already
// includes the scalarization overhead of the predicated instruction.
- InstructionCost VectorCost = getInstructionCost(I, VF).first;
+ InstructionCost VectorCost = getInstructionCost(I, VF).first;
// Compute the cost of the scalarized instruction. This cost is the cost of
// the instruction as if it wasn't if-converted and instead remained in the
// predicated block. We will scale this cost by block probability after
// computing the scalarization overhead.
- assert(!VF.isScalable() && "scalable vectors not yet supported.");
- InstructionCost ScalarCost =
- VF.getKnownMinValue() *
- getInstructionCost(I, ElementCount::getFixed(1)).first;
+ assert(!VF.isScalable() && "scalable vectors not yet supported.");
+ InstructionCost ScalarCost =
+ VF.getKnownMinValue() *
+ getInstructionCost(I, ElementCount::getFixed(1)).first;
// Compute the scalarization overhead of needed insertelement instructions
// and phi nodes.
if (isScalarWithPredication(I) && !I->getType()->isVoidTy()) {
ScalarCost += TTI.getScalarizationOverhead(
cast<VectorType>(ToVectorTy(I->getType(), VF)),
- APInt::getAllOnesValue(VF.getKnownMinValue()), true, false);
- assert(!VF.isScalable() && "scalable vectors not yet supported.");
- ScalarCost +=
- VF.getKnownMinValue() *
- TTI.getCFInstrCost(Instruction::PHI, TTI::TCK_RecipThroughput);
+ APInt::getAllOnesValue(VF.getKnownMinValue()), true, false);
+ assert(!VF.isScalable() && "scalable vectors not yet supported.");
+ ScalarCost +=
+ VF.getKnownMinValue() *
+ TTI.getCFInstrCost(Instruction::PHI, TTI::TCK_RecipThroughput);
}
// Compute the scalarization overhead of needed extractelement
@@ -6566,12 +6566,12 @@ int LoopVectorizationCostModel::computePredInstDiscount(
"Instruction has non-scalar type");
if (canBeScalarized(J))
Worklist.push_back(J);
- else if (needsExtract(J, VF)) {
- assert(!VF.isScalable() && "scalable vectors not yet supported.");
+ else if (needsExtract(J, VF)) {
+ assert(!VF.isScalable() && "scalable vectors not yet supported.");
ScalarCost += TTI.getScalarizationOverhead(
cast<VectorType>(ToVectorTy(J->getType(), VF)),
- APInt::getAllOnesValue(VF.getKnownMinValue()), false, true);
- }
+ APInt::getAllOnesValue(VF.getKnownMinValue()), false, true);
+ }
}
// Scale the total scalar cost by block probability.
@@ -6583,11 +6583,11 @@ int LoopVectorizationCostModel::computePredInstDiscount(
ScalarCosts[I] = ScalarCost;
}
- return *Discount.getValue();
+ return *Discount.getValue();
}
LoopVectorizationCostModel::VectorizationCostTy
-LoopVectorizationCostModel::expectedCost(ElementCount VF) {
+LoopVectorizationCostModel::expectedCost(ElementCount VF) {
VectorizationCostTy Cost;
// For each block.
@@ -6597,15 +6597,15 @@ LoopVectorizationCostModel::expectedCost(ElementCount VF) {
// For each instruction in the old loop.
for (Instruction &I : BB->instructionsWithoutDebug()) {
// Skip ignored values.
- if (ValuesToIgnore.count(&I) ||
- (VF.isVector() && VecValuesToIgnore.count(&I)))
+ if (ValuesToIgnore.count(&I) ||
+ (VF.isVector() && VecValuesToIgnore.count(&I)))
continue;
VectorizationCostTy C = getInstructionCost(&I, VF);
// Check if we should override the cost.
if (ForceTargetInstructionCost.getNumOccurrences() > 0)
- C.first = InstructionCost(ForceTargetInstructionCost);
+ C.first = InstructionCost(ForceTargetInstructionCost);
BlockCost.first += C.first;
BlockCost.second |= C.second;
@@ -6618,10 +6618,10 @@ LoopVectorizationCostModel::expectedCost(ElementCount VF) {
// if-converted. This means that the block's instructions (aside from
// stores and instructions that may divide by zero) will now be
// unconditionally executed. For the scalar case, we may not always execute
- // the predicated block, if it is an if-else block. Thus, scale the block's
- // cost by the probability of executing it. blockNeedsPredication from
- // Legal is used so as to not include all blocks in tail folded loops.
- if (VF.isScalar() && Legal->blockNeedsPredication(BB))
+ // the predicated block, if it is an if-else block. Thus, scale the block's
+ // cost by the probability of executing it. blockNeedsPredication from
+ // Legal is used so as to not include all blocks in tail folded loops.
+ if (VF.isScalar() && Legal->blockNeedsPredication(BB))
BlockCost.first /= getReciprocalPredBlockProb();
Cost.first += BlockCost.first;
@@ -6666,12 +6666,12 @@ static bool isStrideMul(Instruction *I, LoopVectorizationLegality *Legal) {
Legal->hasStride(I->getOperand(1));
}
-InstructionCost
-LoopVectorizationCostModel::getMemInstScalarizationCost(Instruction *I,
- ElementCount VF) {
- assert(VF.isVector() &&
- "Scalarization cost of instruction implies vectorization.");
- assert(!VF.isScalable() && "scalable vectors not yet supported.");
+InstructionCost
+LoopVectorizationCostModel::getMemInstScalarizationCost(Instruction *I,
+ ElementCount VF) {
+ assert(VF.isVector() &&
+ "Scalarization cost of instruction implies vectorization.");
+ assert(!VF.isScalable() && "scalable vectors not yet supported.");
Type *ValTy = getMemInstValueType(I);
auto SE = PSE.getSE();
@@ -6684,15 +6684,15 @@ LoopVectorizationCostModel::getMemInstScalarizationCost(Instruction *I,
const SCEV *PtrSCEV = getAddressAccessSCEV(Ptr, Legal, PSE, TheLoop);
// Get the cost of the scalar memory instruction and address computation.
- InstructionCost Cost =
- VF.getKnownMinValue() * TTI.getAddressComputationCost(PtrTy, SE, PtrSCEV);
+ InstructionCost Cost =
+ VF.getKnownMinValue() * TTI.getAddressComputationCost(PtrTy, SE, PtrSCEV);
// Don't pass *I here, since it is scalar but will actually be part of a
// vectorized loop where the user of it is a vectorized instruction.
const Align Alignment = getLoadStoreAlignment(I);
- Cost += VF.getKnownMinValue() *
- TTI.getMemoryOpCost(I->getOpcode(), ValTy->getScalarType(), Alignment,
- AS, TTI::TCK_RecipThroughput);
+ Cost += VF.getKnownMinValue() *
+ TTI.getMemoryOpCost(I->getOpcode(), ValTy->getScalarType(), Alignment,
+ AS, TTI::TCK_RecipThroughput);
// Get the overhead of the extractelement and insertelement instructions
// we might create due to scalarization.
@@ -6713,9 +6713,9 @@ LoopVectorizationCostModel::getMemInstScalarizationCost(Instruction *I,
return Cost;
}
-InstructionCost
-LoopVectorizationCostModel::getConsecutiveMemOpCost(Instruction *I,
- ElementCount VF) {
+InstructionCost
+LoopVectorizationCostModel::getConsecutiveMemOpCost(Instruction *I,
+ ElementCount VF) {
Type *ValTy = getMemInstValueType(I);
auto *VectorTy = cast<VectorType>(ToVectorTy(ValTy, VF));
Value *Ptr = getLoadStorePointerOperand(I);
@@ -6726,7 +6726,7 @@ LoopVectorizationCostModel::getConsecutiveMemOpCost(Instruction *I,
assert((ConsecutiveStride == 1 || ConsecutiveStride == -1) &&
"Stride should be 1 or -1 for consecutive memory access");
const Align Alignment = getLoadStoreAlignment(I);
- InstructionCost Cost = 0;
+ InstructionCost Cost = 0;
if (Legal->isMaskRequired(I))
Cost += TTI.getMaskedMemoryOpCost(I->getOpcode(), VectorTy, Alignment, AS,
CostKind);
@@ -6740,11 +6740,11 @@ LoopVectorizationCostModel::getConsecutiveMemOpCost(Instruction *I,
return Cost;
}
-InstructionCost
-LoopVectorizationCostModel::getUniformMemOpCost(Instruction *I,
- ElementCount VF) {
- assert(Legal->isUniformMemOp(*I));
-
+InstructionCost
+LoopVectorizationCostModel::getUniformMemOpCost(Instruction *I,
+ ElementCount VF) {
+ assert(Legal->isUniformMemOp(*I));
+
Type *ValTy = getMemInstValueType(I);
auto *VectorTy = cast<VectorType>(ToVectorTy(ValTy, VF));
const Align Alignment = getLoadStoreAlignment(I);
@@ -6765,12 +6765,12 @@ LoopVectorizationCostModel::getUniformMemOpCost(Instruction *I,
(isLoopInvariantStoreValue
? 0
: TTI.getVectorInstrCost(Instruction::ExtractElement, VectorTy,
- VF.getKnownMinValue() - 1));
+ VF.getKnownMinValue() - 1));
}
-InstructionCost
-LoopVectorizationCostModel::getGatherScatterCost(Instruction *I,
- ElementCount VF) {
+InstructionCost
+LoopVectorizationCostModel::getGatherScatterCost(Instruction *I,
+ ElementCount VF) {
Type *ValTy = getMemInstValueType(I);
auto *VectorTy = cast<VectorType>(ToVectorTy(ValTy, VF));
const Align Alignment = getLoadStoreAlignment(I);
@@ -6782,9 +6782,9 @@ LoopVectorizationCostModel::getGatherScatterCost(Instruction *I,
TargetTransformInfo::TCK_RecipThroughput, I);
}
-InstructionCost
-LoopVectorizationCostModel::getInterleaveGroupCost(Instruction *I,
- ElementCount VF) {
+InstructionCost
+LoopVectorizationCostModel::getInterleaveGroupCost(Instruction *I,
+ ElementCount VF) {
Type *ValTy = getMemInstValueType(I);
auto *VectorTy = cast<VectorType>(ToVectorTy(ValTy, VF));
unsigned AS = getLoadStoreAddressSpace(I);
@@ -6793,8 +6793,8 @@ LoopVectorizationCostModel::getInterleaveGroupCost(Instruction *I,
assert(Group && "Fail to get an interleaved access group.");
unsigned InterleaveFactor = Group->getFactor();
- assert(!VF.isScalable() && "scalable vectors not yet supported.");
- auto *WideVecTy = VectorType::get(ValTy, VF * InterleaveFactor);
+ assert(!VF.isScalable() && "scalable vectors not yet supported.");
+ auto *WideVecTy = VectorType::get(ValTy, VF * InterleaveFactor);
// Holds the indices of existing members in an interleaved load group.
// An interleaved store group doesn't need this as it doesn't allow gaps.
@@ -6808,7 +6808,7 @@ LoopVectorizationCostModel::getInterleaveGroupCost(Instruction *I,
// Calculate the cost of the whole interleaved group.
bool UseMaskForGaps =
Group->requiresScalarEpilogue() && !isScalarEpilogueAllowed();
- InstructionCost Cost = TTI.getInterleavedMemoryOpCost(
+ InstructionCost Cost = TTI.getInterleavedMemoryOpCost(
I->getOpcode(), WideVecTy, Group->getFactor(), Indices, Group->getAlign(),
AS, TTI::TCK_RecipThroughput, Legal->isMaskRequired(I), UseMaskForGaps);
@@ -6822,122 +6822,122 @@ LoopVectorizationCostModel::getInterleaveGroupCost(Instruction *I,
return Cost;
}
-InstructionCost LoopVectorizationCostModel::getReductionPatternCost(
- Instruction *I, ElementCount VF, Type *Ty, TTI::TargetCostKind CostKind) {
- // Early exit for no inloop reductions
- if (InLoopReductionChains.empty() || VF.isScalar() || !isa<VectorType>(Ty))
- return InstructionCost::getInvalid();
- auto *VectorTy = cast<VectorType>(Ty);
-
- // We are looking for a pattern of, and finding the minimal acceptable cost:
- // reduce(mul(ext(A), ext(B))) or
- // reduce(mul(A, B)) or
- // reduce(ext(A)) or
- // reduce(A).
- // The basic idea is that we walk down the tree to do that, finding the root
- // reduction instruction in InLoopReductionImmediateChains. From there we find
- // the pattern of mul/ext and test the cost of the entire pattern vs the cost
- // of the components. If the reduction cost is lower then we return it for the
- // reduction instruction and 0 for the other instructions in the pattern. If
- // it is not we return an invalid cost specifying the orignal cost method
- // should be used.
- Instruction *RetI = I;
- if ((RetI->getOpcode() == Instruction::SExt ||
- RetI->getOpcode() == Instruction::ZExt)) {
- if (!RetI->hasOneUser())
- return InstructionCost::getInvalid();
- RetI = RetI->user_back();
- }
- if (RetI->getOpcode() == Instruction::Mul &&
- RetI->user_back()->getOpcode() == Instruction::Add) {
- if (!RetI->hasOneUser())
- return InstructionCost::getInvalid();
- RetI = RetI->user_back();
- }
-
- // Test if the found instruction is a reduction, and if not return an invalid
- // cost specifying the parent to use the original cost modelling.
- if (!InLoopReductionImmediateChains.count(RetI))
- return InstructionCost::getInvalid();
-
- // Find the reduction this chain is a part of and calculate the basic cost of
- // the reduction on its own.
- Instruction *LastChain = InLoopReductionImmediateChains[RetI];
- Instruction *ReductionPhi = LastChain;
- while (!isa<PHINode>(ReductionPhi))
- ReductionPhi = InLoopReductionImmediateChains[ReductionPhi];
-
- RecurrenceDescriptor RdxDesc =
- Legal->getReductionVars()[cast<PHINode>(ReductionPhi)];
- unsigned BaseCost = TTI.getArithmeticReductionCost(RdxDesc.getOpcode(),
- VectorTy, false, CostKind);
-
- // Get the operand that was not the reduction chain and match it to one of the
- // patterns, returning the better cost if it is found.
- Instruction *RedOp = RetI->getOperand(1) == LastChain
- ? dyn_cast<Instruction>(RetI->getOperand(0))
- : dyn_cast<Instruction>(RetI->getOperand(1));
-
- VectorTy = VectorType::get(I->getOperand(0)->getType(), VectorTy);
-
- if (RedOp && (isa<SExtInst>(RedOp) || isa<ZExtInst>(RedOp)) &&
- !TheLoop->isLoopInvariant(RedOp)) {
- bool IsUnsigned = isa<ZExtInst>(RedOp);
- auto *ExtType = VectorType::get(RedOp->getOperand(0)->getType(), VectorTy);
- InstructionCost RedCost = TTI.getExtendedAddReductionCost(
- /*IsMLA=*/false, IsUnsigned, RdxDesc.getRecurrenceType(), ExtType,
- CostKind);
-
- unsigned ExtCost =
- TTI.getCastInstrCost(RedOp->getOpcode(), VectorTy, ExtType,
- TTI::CastContextHint::None, CostKind, RedOp);
- if (RedCost.isValid() && RedCost < BaseCost + ExtCost)
- return I == RetI ? *RedCost.getValue() : 0;
- } else if (RedOp && RedOp->getOpcode() == Instruction::Mul) {
- Instruction *Mul = RedOp;
- Instruction *Op0 = dyn_cast<Instruction>(Mul->getOperand(0));
- Instruction *Op1 = dyn_cast<Instruction>(Mul->getOperand(1));
- if (Op0 && Op1 && (isa<SExtInst>(Op0) || isa<ZExtInst>(Op0)) &&
- Op0->getOpcode() == Op1->getOpcode() &&
- Op0->getOperand(0)->getType() == Op1->getOperand(0)->getType() &&
- !TheLoop->isLoopInvariant(Op0) && !TheLoop->isLoopInvariant(Op1)) {
- bool IsUnsigned = isa<ZExtInst>(Op0);
- auto *ExtType = VectorType::get(Op0->getOperand(0)->getType(), VectorTy);
- // reduce(mul(ext, ext))
- unsigned ExtCost =
- TTI.getCastInstrCost(Op0->getOpcode(), VectorTy, ExtType,
- TTI::CastContextHint::None, CostKind, Op0);
- unsigned MulCost =
- TTI.getArithmeticInstrCost(Mul->getOpcode(), VectorTy, CostKind);
-
- InstructionCost RedCost = TTI.getExtendedAddReductionCost(
- /*IsMLA=*/true, IsUnsigned, RdxDesc.getRecurrenceType(), ExtType,
- CostKind);
-
- if (RedCost.isValid() && RedCost < ExtCost * 2 + MulCost + BaseCost)
- return I == RetI ? *RedCost.getValue() : 0;
- } else {
- unsigned MulCost =
- TTI.getArithmeticInstrCost(Mul->getOpcode(), VectorTy, CostKind);
-
- InstructionCost RedCost = TTI.getExtendedAddReductionCost(
- /*IsMLA=*/true, true, RdxDesc.getRecurrenceType(), VectorTy,
- CostKind);
-
- if (RedCost.isValid() && RedCost < MulCost + BaseCost)
- return I == RetI ? *RedCost.getValue() : 0;
- }
- }
-
- return I == RetI ? BaseCost : InstructionCost::getInvalid();
-}
-
-InstructionCost
-LoopVectorizationCostModel::getMemoryInstructionCost(Instruction *I,
- ElementCount VF) {
+InstructionCost LoopVectorizationCostModel::getReductionPatternCost(
+ Instruction *I, ElementCount VF, Type *Ty, TTI::TargetCostKind CostKind) {
+ // Early exit for no inloop reductions
+ if (InLoopReductionChains.empty() || VF.isScalar() || !isa<VectorType>(Ty))
+ return InstructionCost::getInvalid();
+ auto *VectorTy = cast<VectorType>(Ty);
+
+ // We are looking for a pattern of, and finding the minimal acceptable cost:
+ // reduce(mul(ext(A), ext(B))) or
+ // reduce(mul(A, B)) or
+ // reduce(ext(A)) or
+ // reduce(A).
+ // The basic idea is that we walk down the tree to do that, finding the root
+ // reduction instruction in InLoopReductionImmediateChains. From there we find
+ // the pattern of mul/ext and test the cost of the entire pattern vs the cost
+ // of the components. If the reduction cost is lower then we return it for the
+ // reduction instruction and 0 for the other instructions in the pattern. If
+ // it is not we return an invalid cost specifying the orignal cost method
+ // should be used.
+ Instruction *RetI = I;
+ if ((RetI->getOpcode() == Instruction::SExt ||
+ RetI->getOpcode() == Instruction::ZExt)) {
+ if (!RetI->hasOneUser())
+ return InstructionCost::getInvalid();
+ RetI = RetI->user_back();
+ }
+ if (RetI->getOpcode() == Instruction::Mul &&
+ RetI->user_back()->getOpcode() == Instruction::Add) {
+ if (!RetI->hasOneUser())
+ return InstructionCost::getInvalid();
+ RetI = RetI->user_back();
+ }
+
+ // Test if the found instruction is a reduction, and if not return an invalid
+ // cost specifying the parent to use the original cost modelling.
+ if (!InLoopReductionImmediateChains.count(RetI))
+ return InstructionCost::getInvalid();
+
+ // Find the reduction this chain is a part of and calculate the basic cost of
+ // the reduction on its own.
+ Instruction *LastChain = InLoopReductionImmediateChains[RetI];
+ Instruction *ReductionPhi = LastChain;
+ while (!isa<PHINode>(ReductionPhi))
+ ReductionPhi = InLoopReductionImmediateChains[ReductionPhi];
+
+ RecurrenceDescriptor RdxDesc =
+ Legal->getReductionVars()[cast<PHINode>(ReductionPhi)];
+ unsigned BaseCost = TTI.getArithmeticReductionCost(RdxDesc.getOpcode(),
+ VectorTy, false, CostKind);
+
+ // Get the operand that was not the reduction chain and match it to one of the
+ // patterns, returning the better cost if it is found.
+ Instruction *RedOp = RetI->getOperand(1) == LastChain
+ ? dyn_cast<Instruction>(RetI->getOperand(0))
+ : dyn_cast<Instruction>(RetI->getOperand(1));
+
+ VectorTy = VectorType::get(I->getOperand(0)->getType(), VectorTy);
+
+ if (RedOp && (isa<SExtInst>(RedOp) || isa<ZExtInst>(RedOp)) &&
+ !TheLoop->isLoopInvariant(RedOp)) {
+ bool IsUnsigned = isa<ZExtInst>(RedOp);
+ auto *ExtType = VectorType::get(RedOp->getOperand(0)->getType(), VectorTy);
+ InstructionCost RedCost = TTI.getExtendedAddReductionCost(
+ /*IsMLA=*/false, IsUnsigned, RdxDesc.getRecurrenceType(), ExtType,
+ CostKind);
+
+ unsigned ExtCost =
+ TTI.getCastInstrCost(RedOp->getOpcode(), VectorTy, ExtType,
+ TTI::CastContextHint::None, CostKind, RedOp);
+ if (RedCost.isValid() && RedCost < BaseCost + ExtCost)
+ return I == RetI ? *RedCost.getValue() : 0;
+ } else if (RedOp && RedOp->getOpcode() == Instruction::Mul) {
+ Instruction *Mul = RedOp;
+ Instruction *Op0 = dyn_cast<Instruction>(Mul->getOperand(0));
+ Instruction *Op1 = dyn_cast<Instruction>(Mul->getOperand(1));
+ if (Op0 && Op1 && (isa<SExtInst>(Op0) || isa<ZExtInst>(Op0)) &&
+ Op0->getOpcode() == Op1->getOpcode() &&
+ Op0->getOperand(0)->getType() == Op1->getOperand(0)->getType() &&
+ !TheLoop->isLoopInvariant(Op0) && !TheLoop->isLoopInvariant(Op1)) {
+ bool IsUnsigned = isa<ZExtInst>(Op0);
+ auto *ExtType = VectorType::get(Op0->getOperand(0)->getType(), VectorTy);
+ // reduce(mul(ext, ext))
+ unsigned ExtCost =
+ TTI.getCastInstrCost(Op0->getOpcode(), VectorTy, ExtType,
+ TTI::CastContextHint::None, CostKind, Op0);
+ unsigned MulCost =
+ TTI.getArithmeticInstrCost(Mul->getOpcode(), VectorTy, CostKind);
+
+ InstructionCost RedCost = TTI.getExtendedAddReductionCost(
+ /*IsMLA=*/true, IsUnsigned, RdxDesc.getRecurrenceType(), ExtType,
+ CostKind);
+
+ if (RedCost.isValid() && RedCost < ExtCost * 2 + MulCost + BaseCost)
+ return I == RetI ? *RedCost.getValue() : 0;
+ } else {
+ unsigned MulCost =
+ TTI.getArithmeticInstrCost(Mul->getOpcode(), VectorTy, CostKind);
+
+ InstructionCost RedCost = TTI.getExtendedAddReductionCost(
+ /*IsMLA=*/true, true, RdxDesc.getRecurrenceType(), VectorTy,
+ CostKind);
+
+ if (RedCost.isValid() && RedCost < MulCost + BaseCost)
+ return I == RetI ? *RedCost.getValue() : 0;
+ }
+ }
+
+ return I == RetI ? BaseCost : InstructionCost::getInvalid();
+}
+
+InstructionCost
+LoopVectorizationCostModel::getMemoryInstructionCost(Instruction *I,
+ ElementCount VF) {
// Calculate scalar cost only. Vectorization cost should be ready at this
// moment.
- if (VF.isScalar()) {
+ if (VF.isScalar()) {
Type *ValTy = getMemInstValueType(I);
const Align Alignment = getLoadStoreAlignment(I);
unsigned AS = getLoadStoreAddressSpace(I);
@@ -6950,52 +6950,52 @@ LoopVectorizationCostModel::getMemoryInstructionCost(Instruction *I,
}
LoopVectorizationCostModel::VectorizationCostTy
-LoopVectorizationCostModel::getInstructionCost(Instruction *I,
- ElementCount VF) {
+LoopVectorizationCostModel::getInstructionCost(Instruction *I,
+ ElementCount VF) {
// If we know that this instruction will remain uniform, check the cost of
// the scalar version.
if (isUniformAfterVectorization(I, VF))
- VF = ElementCount::getFixed(1);
+ VF = ElementCount::getFixed(1);
- if (VF.isVector() && isProfitableToScalarize(I, VF))
+ if (VF.isVector() && isProfitableToScalarize(I, VF))
return VectorizationCostTy(InstsToScalarize[VF][I], false);
// Forced scalars do not have any scalarization overhead.
auto ForcedScalar = ForcedScalars.find(VF);
- if (VF.isVector() && ForcedScalar != ForcedScalars.end()) {
+ if (VF.isVector() && ForcedScalar != ForcedScalars.end()) {
auto InstSet = ForcedScalar->second;
if (InstSet.count(I))
- return VectorizationCostTy(
- (getInstructionCost(I, ElementCount::getFixed(1)).first *
- VF.getKnownMinValue()),
- false);
+ return VectorizationCostTy(
+ (getInstructionCost(I, ElementCount::getFixed(1)).first *
+ VF.getKnownMinValue()),
+ false);
}
Type *VectorTy;
- InstructionCost C = getInstructionCost(I, VF, VectorTy);
+ InstructionCost C = getInstructionCost(I, VF, VectorTy);
bool TypeNotScalarized =
- VF.isVector() && VectorTy->isVectorTy() &&
- TTI.getNumberOfParts(VectorTy) < VF.getKnownMinValue();
+ VF.isVector() && VectorTy->isVectorTy() &&
+ TTI.getNumberOfParts(VectorTy) < VF.getKnownMinValue();
return VectorizationCostTy(C, TypeNotScalarized);
}
-InstructionCost
-LoopVectorizationCostModel::getScalarizationOverhead(Instruction *I,
- ElementCount VF) {
+InstructionCost
+LoopVectorizationCostModel::getScalarizationOverhead(Instruction *I,
+ ElementCount VF) {
- assert(!VF.isScalable() &&
- "cannot compute scalarization overhead for scalable vectorization");
- if (VF.isScalar())
+ assert(!VF.isScalable() &&
+ "cannot compute scalarization overhead for scalable vectorization");
+ if (VF.isScalar())
return 0;
- InstructionCost Cost = 0;
+ InstructionCost Cost = 0;
Type *RetTy = ToVectorTy(I->getType(), VF);
if (!RetTy->isVoidTy() &&
(!isa<LoadInst>(I) || !TTI.supportsEfficientVectorElementLoadStore()))
Cost += TTI.getScalarizationOverhead(
- cast<VectorType>(RetTy), APInt::getAllOnesValue(VF.getKnownMinValue()),
- true, false);
+ cast<VectorType>(RetTy), APInt::getAllOnesValue(VF.getKnownMinValue()),
+ true, false);
// Some targets keep addresses scalar.
if (isa<LoadInst>(I) && !TTI.prefersVectorizedAddressing())
@@ -7012,11 +7012,11 @@ LoopVectorizationCostModel::getScalarizationOverhead(Instruction *I,
// Skip operands that do not require extraction/scalarization and do not incur
// any overhead.
return Cost + TTI.getOperandsScalarizationOverhead(
- filterExtractingOperands(Ops, VF), VF.getKnownMinValue());
+ filterExtractingOperands(Ops, VF), VF.getKnownMinValue());
}
-void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
- if (VF.isScalar())
+void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
+ if (VF.isScalar())
return;
NumPredStores = 0;
for (BasicBlock *BB : TheLoop->blocks()) {
@@ -7033,19 +7033,19 @@ void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
if (isa<StoreInst>(&I) && isScalarWithPredication(&I))
NumPredStores++;
- if (Legal->isUniformMemOp(I)) {
+ if (Legal->isUniformMemOp(I)) {
// TODO: Avoid replicating loads and stores instead of
// relying on instcombine to remove them.
// Load: Scalar load + broadcast
// Store: Scalar store + isLoopInvariantStoreValue ? 0 : extract
- InstructionCost Cost = getUniformMemOpCost(&I, VF);
+ InstructionCost Cost = getUniformMemOpCost(&I, VF);
setWideningDecision(&I, VF, CM_Scalarize, Cost);
continue;
}
// We assume that widening is the best solution when possible.
if (memoryInstructionCanBeWidened(&I, VF)) {
- InstructionCost Cost = getConsecutiveMemOpCost(&I, VF);
+ InstructionCost Cost = getConsecutiveMemOpCost(&I, VF);
int ConsecutiveStride =
Legal->isConsecutivePtr(getLoadStorePointerOperand(&I));
assert((ConsecutiveStride == 1 || ConsecutiveStride == -1) &&
@@ -7057,7 +7057,7 @@ void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
}
// Choose between Interleaving, Gather/Scatter or Scalarization.
- InstructionCost InterleaveCost = std::numeric_limits<int>::max();
+ InstructionCost InterleaveCost = std::numeric_limits<int>::max();
unsigned NumAccesses = 1;
if (isAccessInterleaved(&I)) {
auto Group = getInterleavedAccessGroup(&I);
@@ -7072,17 +7072,17 @@ void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
InterleaveCost = getInterleaveGroupCost(&I, VF);
}
- InstructionCost GatherScatterCost =
+ InstructionCost GatherScatterCost =
isLegalGatherOrScatter(&I)
? getGatherScatterCost(&I, VF) * NumAccesses
- : std::numeric_limits<int>::max();
+ : std::numeric_limits<int>::max();
- InstructionCost ScalarizationCost =
+ InstructionCost ScalarizationCost =
getMemInstScalarizationCost(&I, VF) * NumAccesses;
// Choose better solution for the current VF,
// write down this decision and use it during vectorization.
- InstructionCost Cost;
+ InstructionCost Cost;
InstWidening Decision;
if (InterleaveCost <= GatherScatterCost &&
InterleaveCost < ScalarizationCost) {
@@ -7126,7 +7126,7 @@ void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
// Add all instructions used to generate the addresses.
SmallVector<Instruction *, 4> Worklist;
- append_range(Worklist, AddrDefs);
+ append_range(Worklist, AddrDefs);
while (!Worklist.empty()) {
Instruction *I = Worklist.pop_back_val();
for (auto &Op : I->operands())
@@ -7145,18 +7145,18 @@ void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
InstWidening Decision = getWideningDecision(I, VF);
if (Decision == CM_Widen || Decision == CM_Widen_Reverse)
// Scalarize a widened load of address.
- setWideningDecision(
- I, VF, CM_Scalarize,
- (VF.getKnownMinValue() *
- getMemoryInstructionCost(I, ElementCount::getFixed(1))));
+ setWideningDecision(
+ I, VF, CM_Scalarize,
+ (VF.getKnownMinValue() *
+ getMemoryInstructionCost(I, ElementCount::getFixed(1))));
else if (auto Group = getInterleavedAccessGroup(I)) {
// Scalarize an interleave group of address loads.
for (unsigned I = 0; I < Group->getFactor(); ++I) {
if (Instruction *Member = Group->getMember(I))
- setWideningDecision(
- Member, VF, CM_Scalarize,
- (VF.getKnownMinValue() *
- getMemoryInstructionCost(Member, ElementCount::getFixed(1))));
+ setWideningDecision(
+ Member, VF, CM_Scalarize,
+ (VF.getKnownMinValue() *
+ getMemoryInstructionCost(Member, ElementCount::getFixed(1))));
}
}
} else
@@ -7166,9 +7166,9 @@ void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
}
}
-InstructionCost
-LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
- Type *&VectorTy) {
+InstructionCost
+LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
+ Type *&VectorTy) {
Type *RetTy = I->getType();
if (canTruncateToMinimalBitwidth(I, VF))
RetTy = IntegerType::get(RetTy->getContext(), MinBWs[I]);
@@ -7190,22 +7190,22 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
// blocks requires also an extract of its vector compare i1 element.
bool ScalarPredicatedBB = false;
BranchInst *BI = cast<BranchInst>(I);
- if (VF.isVector() && BI->isConditional() &&
+ if (VF.isVector() && BI->isConditional() &&
(PredicatedBBsAfterVectorization.count(BI->getSuccessor(0)) ||
PredicatedBBsAfterVectorization.count(BI->getSuccessor(1))))
ScalarPredicatedBB = true;
if (ScalarPredicatedBB) {
// Return cost for branches around scalarized and predicated blocks.
- assert(!VF.isScalable() && "scalable vectors not yet supported.");
+ assert(!VF.isScalable() && "scalable vectors not yet supported.");
auto *Vec_i1Ty =
- VectorType::get(IntegerType::getInt1Ty(RetTy->getContext()), VF);
- return (TTI.getScalarizationOverhead(
- Vec_i1Ty, APInt::getAllOnesValue(VF.getKnownMinValue()),
- false, true) +
- (TTI.getCFInstrCost(Instruction::Br, CostKind) *
- VF.getKnownMinValue()));
- } else if (I->getParent() == TheLoop->getLoopLatch() || VF.isScalar())
+ VectorType::get(IntegerType::getInt1Ty(RetTy->getContext()), VF);
+ return (TTI.getScalarizationOverhead(
+ Vec_i1Ty, APInt::getAllOnesValue(VF.getKnownMinValue()),
+ false, true) +
+ (TTI.getCFInstrCost(Instruction::Br, CostKind) *
+ VF.getKnownMinValue()));
+ } else if (I->getParent() == TheLoop->getLoopLatch() || VF.isScalar())
// The back-edge branch will remain, as will all scalar branches.
return TTI.getCFInstrCost(Instruction::Br, CostKind);
else
@@ -7220,20 +7220,20 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
// First-order recurrences are replaced by vector shuffles inside the loop.
// NOTE: Don't use ToVectorTy as SK_ExtractSubvector expects a vector type.
- if (VF.isVector() && Legal->isFirstOrderRecurrence(Phi))
- return TTI.getShuffleCost(
- TargetTransformInfo::SK_ExtractSubvector, cast<VectorType>(VectorTy),
- VF.getKnownMinValue() - 1, FixedVectorType::get(RetTy, 1));
+ if (VF.isVector() && Legal->isFirstOrderRecurrence(Phi))
+ return TTI.getShuffleCost(
+ TargetTransformInfo::SK_ExtractSubvector, cast<VectorType>(VectorTy),
+ VF.getKnownMinValue() - 1, FixedVectorType::get(RetTy, 1));
// Phi nodes in non-header blocks (not inductions, reductions, etc.) are
// converted into select instructions. We require N - 1 selects per phi
// node, where N is the number of incoming values.
- if (VF.isVector() && Phi->getParent() != TheLoop->getHeader())
+ if (VF.isVector() && Phi->getParent() != TheLoop->getHeader())
return (Phi->getNumIncomingValues() - 1) *
TTI.getCmpSelInstrCost(
Instruction::Select, ToVectorTy(Phi->getType(), VF),
ToVectorTy(Type::getInt1Ty(Phi->getContext()), VF),
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
return TTI.getCFInstrCost(Instruction::PHI, CostKind);
}
@@ -7245,19 +7245,19 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
// vector lane. Get the scalarization cost and scale this amount by the
// probability of executing the predicated block. If the instruction is not
// predicated, we fall through to the next case.
- if (VF.isVector() && isScalarWithPredication(I)) {
- InstructionCost Cost = 0;
+ if (VF.isVector() && isScalarWithPredication(I)) {
+ InstructionCost Cost = 0;
// These instructions have a non-void type, so account for the phi nodes
// that we will create. This cost is likely to be zero. The phi node
// cost, if any, should be scaled by the block probability because it
// models a copy at the end of each predicated block.
- Cost += VF.getKnownMinValue() *
- TTI.getCFInstrCost(Instruction::PHI, CostKind);
+ Cost += VF.getKnownMinValue() *
+ TTI.getCFInstrCost(Instruction::PHI, CostKind);
// The cost of the non-predicated instruction.
- Cost += VF.getKnownMinValue() *
- TTI.getArithmeticInstrCost(I->getOpcode(), RetTy, CostKind);
+ Cost += VF.getKnownMinValue() *
+ TTI.getArithmeticInstrCost(I->getOpcode(), RetTy, CostKind);
// The cost of insertelement and extractelement instructions needed for
// scalarization.
@@ -7286,13 +7286,13 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
// Since we will replace the stride by 1 the multiplication should go away.
if (I->getOpcode() == Instruction::Mul && isStrideMul(I, Legal))
return 0;
-
- // Detect reduction patterns
- InstructionCost RedCost;
- if ((RedCost = getReductionPatternCost(I, VF, VectorTy, CostKind))
- .isValid())
- return RedCost;
-
+
+ // Detect reduction patterns
+ InstructionCost RedCost;
+ if ((RedCost = getReductionPatternCost(I, VF, VectorTy, CostKind))
+ .isValid())
+ return RedCost;
+
// Certain instructions can be cheaper to vectorize if they have a constant
// second vector operand. One example of this are shifts on x86.
Value *Op2 = I->getOperand(1);
@@ -7303,15 +7303,15 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
Op2VK = TargetTransformInfo::OK_UniformValue;
SmallVector<const Value *, 4> Operands(I->operand_values());
- unsigned N = isScalarAfterVectorization(I, VF) ? VF.getKnownMinValue() : 1;
+ unsigned N = isScalarAfterVectorization(I, VF) ? VF.getKnownMinValue() : 1;
return N * TTI.getArithmeticInstrCost(
I->getOpcode(), VectorTy, CostKind,
TargetTransformInfo::OK_AnyValue,
Op2VK, TargetTransformInfo::OP_None, Op2VP, Operands, I);
}
case Instruction::FNeg: {
- assert(!VF.isScalable() && "VF is assumed to be non scalable.");
- unsigned N = isScalarAfterVectorization(I, VF) ? VF.getKnownMinValue() : 1;
+ assert(!VF.isScalable() && "VF is assumed to be non scalable.");
+ unsigned N = isScalarAfterVectorization(I, VF) ? VF.getKnownMinValue() : 1;
return N * TTI.getArithmeticInstrCost(
I->getOpcode(), VectorTy, CostKind,
TargetTransformInfo::OK_AnyValue,
@@ -7325,9 +7325,9 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
bool ScalarCond = (SE->isLoopInvariant(CondSCEV, TheLoop));
Type *CondTy = SI->getCondition()->getType();
if (!ScalarCond)
- CondTy = VectorType::get(CondTy, VF);
+ CondTy = VectorType::get(CondTy, VF);
return TTI.getCmpSelInstrCost(I->getOpcode(), VectorTy, CondTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind, I);
+ CmpInst::BAD_ICMP_PREDICATE, CostKind, I);
}
case Instruction::ICmp:
case Instruction::FCmp: {
@@ -7336,18 +7336,18 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
if (canTruncateToMinimalBitwidth(Op0AsInstruction, VF))
ValTy = IntegerType::get(ValTy->getContext(), MinBWs[Op0AsInstruction]);
VectorTy = ToVectorTy(ValTy, VF);
- return TTI.getCmpSelInstrCost(I->getOpcode(), VectorTy, nullptr,
- CmpInst::BAD_ICMP_PREDICATE, CostKind, I);
+ return TTI.getCmpSelInstrCost(I->getOpcode(), VectorTy, nullptr,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind, I);
}
case Instruction::Store:
case Instruction::Load: {
- ElementCount Width = VF;
- if (Width.isVector()) {
+ ElementCount Width = VF;
+ if (Width.isVector()) {
InstWidening Decision = getWideningDecision(I, Width);
assert(Decision != CM_Unknown &&
"CM decision should be taken at this point");
if (Decision == CM_Scalarize)
- Width = ElementCount::getFixed(1);
+ Width = ElementCount::getFixed(1);
}
VectorTy = ToVectorTy(getMemInstValueType(I), Width);
return getMemoryInstructionCost(I, VF);
@@ -7364,62 +7364,62 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
case Instruction::Trunc:
case Instruction::FPTrunc:
case Instruction::BitCast: {
- // Computes the CastContextHint from a Load/Store instruction.
- auto ComputeCCH = [&](Instruction *I) -> TTI::CastContextHint {
- assert((isa<LoadInst>(I) || isa<StoreInst>(I)) &&
- "Expected a load or a store!");
-
- if (VF.isScalar() || !TheLoop->contains(I))
- return TTI::CastContextHint::Normal;
-
- switch (getWideningDecision(I, VF)) {
- case LoopVectorizationCostModel::CM_GatherScatter:
- return TTI::CastContextHint::GatherScatter;
- case LoopVectorizationCostModel::CM_Interleave:
- return TTI::CastContextHint::Interleave;
- case LoopVectorizationCostModel::CM_Scalarize:
- case LoopVectorizationCostModel::CM_Widen:
- return Legal->isMaskRequired(I) ? TTI::CastContextHint::Masked
- : TTI::CastContextHint::Normal;
- case LoopVectorizationCostModel::CM_Widen_Reverse:
- return TTI::CastContextHint::Reversed;
- case LoopVectorizationCostModel::CM_Unknown:
- llvm_unreachable("Instr did not go through cost modelling?");
- }
-
- llvm_unreachable("Unhandled case!");
- };
-
- unsigned Opcode = I->getOpcode();
- TTI::CastContextHint CCH = TTI::CastContextHint::None;
- // For Trunc, the context is the only user, which must be a StoreInst.
- if (Opcode == Instruction::Trunc || Opcode == Instruction::FPTrunc) {
- if (I->hasOneUse())
- if (StoreInst *Store = dyn_cast<StoreInst>(*I->user_begin()))
- CCH = ComputeCCH(Store);
- }
- // For Z/Sext, the context is the operand, which must be a LoadInst.
- else if (Opcode == Instruction::ZExt || Opcode == Instruction::SExt ||
- Opcode == Instruction::FPExt) {
- if (LoadInst *Load = dyn_cast<LoadInst>(I->getOperand(0)))
- CCH = ComputeCCH(Load);
- }
-
+ // Computes the CastContextHint from a Load/Store instruction.
+ auto ComputeCCH = [&](Instruction *I) -> TTI::CastContextHint {
+ assert((isa<LoadInst>(I) || isa<StoreInst>(I)) &&
+ "Expected a load or a store!");
+
+ if (VF.isScalar() || !TheLoop->contains(I))
+ return TTI::CastContextHint::Normal;
+
+ switch (getWideningDecision(I, VF)) {
+ case LoopVectorizationCostModel::CM_GatherScatter:
+ return TTI::CastContextHint::GatherScatter;
+ case LoopVectorizationCostModel::CM_Interleave:
+ return TTI::CastContextHint::Interleave;
+ case LoopVectorizationCostModel::CM_Scalarize:
+ case LoopVectorizationCostModel::CM_Widen:
+ return Legal->isMaskRequired(I) ? TTI::CastContextHint::Masked
+ : TTI::CastContextHint::Normal;
+ case LoopVectorizationCostModel::CM_Widen_Reverse:
+ return TTI::CastContextHint::Reversed;
+ case LoopVectorizationCostModel::CM_Unknown:
+ llvm_unreachable("Instr did not go through cost modelling?");
+ }
+
+ llvm_unreachable("Unhandled case!");
+ };
+
+ unsigned Opcode = I->getOpcode();
+ TTI::CastContextHint CCH = TTI::CastContextHint::None;
+ // For Trunc, the context is the only user, which must be a StoreInst.
+ if (Opcode == Instruction::Trunc || Opcode == Instruction::FPTrunc) {
+ if (I->hasOneUse())
+ if (StoreInst *Store = dyn_cast<StoreInst>(*I->user_begin()))
+ CCH = ComputeCCH(Store);
+ }
+ // For Z/Sext, the context is the operand, which must be a LoadInst.
+ else if (Opcode == Instruction::ZExt || Opcode == Instruction::SExt ||
+ Opcode == Instruction::FPExt) {
+ if (LoadInst *Load = dyn_cast<LoadInst>(I->getOperand(0)))
+ CCH = ComputeCCH(Load);
+ }
+
// We optimize the truncation of induction variables having constant
// integer steps. The cost of these truncations is the same as the scalar
// operation.
if (isOptimizableIVTruncate(I, VF)) {
auto *Trunc = cast<TruncInst>(I);
return TTI.getCastInstrCost(Instruction::Trunc, Trunc->getDestTy(),
- Trunc->getSrcTy(), CCH, CostKind, Trunc);
+ Trunc->getSrcTy(), CCH, CostKind, Trunc);
}
- // Detect reduction patterns
- InstructionCost RedCost;
- if ((RedCost = getReductionPatternCost(I, VF, VectorTy, CostKind))
- .isValid())
- return RedCost;
-
+ // Detect reduction patterns
+ InstructionCost RedCost;
+ if ((RedCost = getReductionPatternCost(I, VF, VectorTy, CostKind))
+ .isValid())
+ return RedCost;
+
Type *SrcScalarTy = I->getOperand(0)->getType();
Type *SrcVecTy =
VectorTy->isVectorTy() ? ToVectorTy(SrcScalarTy, VF) : SrcScalarTy;
@@ -7430,39 +7430,39 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
//
// Calculate the modified src and dest types.
Type *MinVecTy = VectorTy;
- if (Opcode == Instruction::Trunc) {
+ if (Opcode == Instruction::Trunc) {
SrcVecTy = smallestIntegerVectorType(SrcVecTy, MinVecTy);
VectorTy =
largestIntegerVectorType(ToVectorTy(I->getType(), VF), MinVecTy);
- } else if (Opcode == Instruction::ZExt || Opcode == Instruction::SExt) {
+ } else if (Opcode == Instruction::ZExt || Opcode == Instruction::SExt) {
SrcVecTy = largestIntegerVectorType(SrcVecTy, MinVecTy);
VectorTy =
smallestIntegerVectorType(ToVectorTy(I->getType(), VF), MinVecTy);
}
}
- assert(!VF.isScalable() && "VF is assumed to be non scalable");
- unsigned N = isScalarAfterVectorization(I, VF) ? VF.getKnownMinValue() : 1;
- return N *
- TTI.getCastInstrCost(Opcode, VectorTy, SrcVecTy, CCH, CostKind, I);
+ assert(!VF.isScalable() && "VF is assumed to be non scalable");
+ unsigned N = isScalarAfterVectorization(I, VF) ? VF.getKnownMinValue() : 1;
+ return N *
+ TTI.getCastInstrCost(Opcode, VectorTy, SrcVecTy, CCH, CostKind, I);
}
case Instruction::Call: {
bool NeedToScalarize;
CallInst *CI = cast<CallInst>(I);
- InstructionCost CallCost = getVectorCallCost(CI, VF, NeedToScalarize);
- if (getVectorIntrinsicIDForCall(CI, TLI)) {
- InstructionCost IntrinsicCost = getVectorIntrinsicCost(CI, VF);
- return std::min(CallCost, IntrinsicCost);
- }
+ InstructionCost CallCost = getVectorCallCost(CI, VF, NeedToScalarize);
+ if (getVectorIntrinsicIDForCall(CI, TLI)) {
+ InstructionCost IntrinsicCost = getVectorIntrinsicCost(CI, VF);
+ return std::min(CallCost, IntrinsicCost);
+ }
return CallCost;
}
- case Instruction::ExtractValue:
- return TTI.getInstructionCost(I, TTI::TCK_RecipThroughput);
+ case Instruction::ExtractValue:
+ return TTI.getInstructionCost(I, TTI::TCK_RecipThroughput);
default:
// The cost of executing VF copies of the scalar instruction. This opcode
// is unknown. Assume that it is the same as 'mul'.
- return VF.getKnownMinValue() * TTI.getArithmeticInstrCost(
- Instruction::Mul, VectorTy, CostKind) +
+ return VF.getKnownMinValue() * TTI.getArithmeticInstrCost(
+ Instruction::Mul, VectorTy, CostKind) +
getScalarizationOverhead(I, VF);
} // end of switch.
}
@@ -7515,7 +7515,7 @@ void LoopVectorizationCostModel::collectValuesToIgnore() {
// detection.
for (auto &Reduction : Legal->getReductionVars()) {
RecurrenceDescriptor &RedDes = Reduction.second;
- const SmallPtrSetImpl<Instruction *> &Casts = RedDes.getCastInsts();
+ const SmallPtrSetImpl<Instruction *> &Casts = RedDes.getCastInsts();
VecValuesToIgnore.insert(Casts.begin(), Casts.end());
}
// Ignore type-casting instructions we identified during induction
@@ -7527,43 +7527,43 @@ void LoopVectorizationCostModel::collectValuesToIgnore() {
}
}
-void LoopVectorizationCostModel::collectInLoopReductions() {
- for (auto &Reduction : Legal->getReductionVars()) {
- PHINode *Phi = Reduction.first;
- RecurrenceDescriptor &RdxDesc = Reduction.second;
-
- // We don't collect reductions that are type promoted (yet).
- if (RdxDesc.getRecurrenceType() != Phi->getType())
- continue;
-
- // If the target would prefer this reduction to happen "in-loop", then we
- // want to record it as such.
- unsigned Opcode = RdxDesc.getOpcode();
- if (!PreferInLoopReductions &&
- !TTI.preferInLoopReduction(Opcode, Phi->getType(),
- TargetTransformInfo::ReductionFlags()))
- continue;
-
- // Check that we can correctly put the reductions into the loop, by
- // finding the chain of operations that leads from the phi to the loop
- // exit value.
- SmallVector<Instruction *, 4> ReductionOperations =
- RdxDesc.getReductionOpChain(Phi, TheLoop);
- bool InLoop = !ReductionOperations.empty();
- if (InLoop) {
- InLoopReductionChains[Phi] = ReductionOperations;
- // Add the elements to InLoopReductionImmediateChains for cost modelling.
- Instruction *LastChain = Phi;
- for (auto *I : ReductionOperations) {
- InLoopReductionImmediateChains[I] = LastChain;
- LastChain = I;
- }
- }
- LLVM_DEBUG(dbgs() << "LV: Using " << (InLoop ? "inloop" : "out of loop")
- << " reduction for phi: " << *Phi << "\n");
- }
-}
-
+void LoopVectorizationCostModel::collectInLoopReductions() {
+ for (auto &Reduction : Legal->getReductionVars()) {
+ PHINode *Phi = Reduction.first;
+ RecurrenceDescriptor &RdxDesc = Reduction.second;
+
+ // We don't collect reductions that are type promoted (yet).
+ if (RdxDesc.getRecurrenceType() != Phi->getType())
+ continue;
+
+ // If the target would prefer this reduction to happen "in-loop", then we
+ // want to record it as such.
+ unsigned Opcode = RdxDesc.getOpcode();
+ if (!PreferInLoopReductions &&
+ !TTI.preferInLoopReduction(Opcode, Phi->getType(),
+ TargetTransformInfo::ReductionFlags()))
+ continue;
+
+ // Check that we can correctly put the reductions into the loop, by
+ // finding the chain of operations that leads from the phi to the loop
+ // exit value.
+ SmallVector<Instruction *, 4> ReductionOperations =
+ RdxDesc.getReductionOpChain(Phi, TheLoop);
+ bool InLoop = !ReductionOperations.empty();
+ if (InLoop) {
+ InLoopReductionChains[Phi] = ReductionOperations;
+ // Add the elements to InLoopReductionImmediateChains for cost modelling.
+ Instruction *LastChain = Phi;
+ for (auto *I : ReductionOperations) {
+ InLoopReductionImmediateChains[I] = LastChain;
+ LastChain = I;
+ }
+ }
+ LLVM_DEBUG(dbgs() << "LV: Using " << (InLoop ? "inloop" : "out of loop")
+ << " reduction for phi: " << *Phi << "\n");
+ }
+}
+
// TODO: we could return a pair of values that specify the max VF and
// min VF, to be used in `buildVPlans(MinVF, MaxVF)` instead of
// `buildVPlans(VF, VF)`. We cannot do it because VPLAN at the moment
@@ -7577,40 +7577,40 @@ static unsigned determineVPlanVF(const unsigned WidestVectorRegBits,
}
VectorizationFactor
-LoopVectorizationPlanner::planInVPlanNativePath(ElementCount UserVF) {
- assert(!UserVF.isScalable() && "scalable vectors not yet supported");
- ElementCount VF = UserVF;
+LoopVectorizationPlanner::planInVPlanNativePath(ElementCount UserVF) {
+ assert(!UserVF.isScalable() && "scalable vectors not yet supported");
+ ElementCount VF = UserVF;
// Outer loop handling: They may require CFG and instruction level
// transformations before even evaluating whether vectorization is profitable.
// Since we cannot modify the incoming IR, we need to build VPlan upfront in
// the vectorization pipeline.
- if (!OrigLoop->isInnermost()) {
+ if (!OrigLoop->isInnermost()) {
// If the user doesn't provide a vectorization factor, determine a
// reasonable one.
- if (UserVF.isZero()) {
- VF = ElementCount::getFixed(
- determineVPlanVF(TTI->getRegisterBitWidth(true /* Vector*/), CM));
+ if (UserVF.isZero()) {
+ VF = ElementCount::getFixed(
+ determineVPlanVF(TTI->getRegisterBitWidth(true /* Vector*/), CM));
LLVM_DEBUG(dbgs() << "LV: VPlan computed VF " << VF << ".\n");
// Make sure we have a VF > 1 for stress testing.
- if (VPlanBuildStressTest && (VF.isScalar() || VF.isZero())) {
+ if (VPlanBuildStressTest && (VF.isScalar() || VF.isZero())) {
LLVM_DEBUG(dbgs() << "LV: VPlan stress testing: "
<< "overriding computed VF.\n");
- VF = ElementCount::getFixed(4);
+ VF = ElementCount::getFixed(4);
}
}
assert(EnableVPlanNativePath && "VPlan-native path is not enabled.");
- assert(isPowerOf2_32(VF.getKnownMinValue()) &&
- "VF needs to be a power of two");
- LLVM_DEBUG(dbgs() << "LV: Using " << (!UserVF.isZero() ? "user " : "")
- << "VF " << VF << " to build VPlans.\n");
+ assert(isPowerOf2_32(VF.getKnownMinValue()) &&
+ "VF needs to be a power of two");
+ LLVM_DEBUG(dbgs() << "LV: Using " << (!UserVF.isZero() ? "user " : "")
+ << "VF " << VF << " to build VPlans.\n");
buildVPlans(VF, VF);
// For VPlan build stress testing, we bail out after VPlan construction.
if (VPlanBuildStressTest)
return VectorizationFactor::Disabled();
- return {VF, 0 /*Cost*/};
+ return {VF, 0 /*Cost*/};
}
LLVM_DEBUG(
@@ -7619,10 +7619,10 @@ LoopVectorizationPlanner::planInVPlanNativePath(ElementCount UserVF) {
return VectorizationFactor::Disabled();
}
-Optional<VectorizationFactor>
-LoopVectorizationPlanner::plan(ElementCount UserVF, unsigned UserIC) {
- assert(OrigLoop->isInnermost() && "Inner loop expected.");
- Optional<ElementCount> MaybeMaxVF = CM.computeMaxVF(UserVF, UserIC);
+Optional<VectorizationFactor>
+LoopVectorizationPlanner::plan(ElementCount UserVF, unsigned UserIC) {
+ assert(OrigLoop->isInnermost() && "Inner loop expected.");
+ Optional<ElementCount> MaybeMaxVF = CM.computeMaxVF(UserVF, UserIC);
if (!MaybeMaxVF) // Cases that should not to be vectorized nor interleaved.
return None;
@@ -7640,55 +7640,55 @@ LoopVectorizationPlanner::plan(ElementCount UserVF, unsigned UserIC) {
CM.invalidateCostModelingDecisions();
}
- ElementCount MaxVF = MaybeMaxVF.getValue();
- assert(MaxVF.isNonZero() && "MaxVF is zero.");
-
- bool UserVFIsLegal = ElementCount::isKnownLE(UserVF, MaxVF);
- if (!UserVF.isZero() &&
- (UserVFIsLegal || (UserVF.isScalable() && MaxVF.isScalable()))) {
- // FIXME: MaxVF is temporarily used inplace of UserVF for illegal scalable
- // VFs here, this should be reverted to only use legal UserVFs once the
- // loop below supports scalable VFs.
- ElementCount VF = UserVFIsLegal ? UserVF : MaxVF;
- LLVM_DEBUG(dbgs() << "LV: Using " << (UserVFIsLegal ? "user" : "max")
- << " VF " << VF << ".\n");
- assert(isPowerOf2_32(VF.getKnownMinValue()) &&
- "VF needs to be a power of two");
+ ElementCount MaxVF = MaybeMaxVF.getValue();
+ assert(MaxVF.isNonZero() && "MaxVF is zero.");
+
+ bool UserVFIsLegal = ElementCount::isKnownLE(UserVF, MaxVF);
+ if (!UserVF.isZero() &&
+ (UserVFIsLegal || (UserVF.isScalable() && MaxVF.isScalable()))) {
+ // FIXME: MaxVF is temporarily used inplace of UserVF for illegal scalable
+ // VFs here, this should be reverted to only use legal UserVFs once the
+ // loop below supports scalable VFs.
+ ElementCount VF = UserVFIsLegal ? UserVF : MaxVF;
+ LLVM_DEBUG(dbgs() << "LV: Using " << (UserVFIsLegal ? "user" : "max")
+ << " VF " << VF << ".\n");
+ assert(isPowerOf2_32(VF.getKnownMinValue()) &&
+ "VF needs to be a power of two");
// Collect the instructions (and their associated costs) that will be more
// profitable to scalarize.
- CM.selectUserVectorizationFactor(VF);
- CM.collectInLoopReductions();
- buildVPlansWithVPRecipes(VF, VF);
+ CM.selectUserVectorizationFactor(VF);
+ CM.collectInLoopReductions();
+ buildVPlansWithVPRecipes(VF, VF);
LLVM_DEBUG(printPlans(dbgs()));
- return {{VF, 0}};
+ return {{VF, 0}};
}
- assert(!MaxVF.isScalable() &&
- "Scalable vectors not yet supported beyond this point");
+ assert(!MaxVF.isScalable() &&
+ "Scalable vectors not yet supported beyond this point");
- for (ElementCount VF = ElementCount::getFixed(1);
- ElementCount::isKnownLE(VF, MaxVF); VF *= 2) {
+ for (ElementCount VF = ElementCount::getFixed(1);
+ ElementCount::isKnownLE(VF, MaxVF); VF *= 2) {
// Collect Uniform and Scalar instructions after vectorization with VF.
CM.collectUniformsAndScalars(VF);
// Collect the instructions (and their associated costs) that will be more
// profitable to scalarize.
- if (VF.isVector())
+ if (VF.isVector())
CM.collectInstsToScalarize(VF);
}
- CM.collectInLoopReductions();
-
- buildVPlansWithVPRecipes(ElementCount::getFixed(1), MaxVF);
+ CM.collectInLoopReductions();
+
+ buildVPlansWithVPRecipes(ElementCount::getFixed(1), MaxVF);
LLVM_DEBUG(printPlans(dbgs()));
- if (MaxVF.isScalar())
+ if (MaxVF.isScalar())
return VectorizationFactor::Disabled();
// Select the optimal vectorization factor.
return CM.selectVectorizationFactor(MaxVF);
}
-void LoopVectorizationPlanner::setBestPlan(ElementCount VF, unsigned UF) {
+void LoopVectorizationPlanner::setBestPlan(ElementCount VF, unsigned UF) {
LLVM_DEBUG(dbgs() << "Setting best plan to VF=" << VF << ", UF=" << UF
<< '\n');
BestVF = VF;
@@ -7707,23 +7707,23 @@ void LoopVectorizationPlanner::executePlan(InnerLoopVectorizer &ILV,
// 1. Create a new empty loop. Unlink the old loop and connect the new one.
VPCallbackILV CallbackILV(ILV);
- assert(BestVF.hasValue() && "Vectorization Factor is missing");
-
- VPTransformState State{*BestVF,
- BestUF,
- OrigLoop,
- LI,
- DT,
- ILV.Builder,
- ILV.VectorLoopValueMap,
- &ILV,
- CallbackILV};
+ assert(BestVF.hasValue() && "Vectorization Factor is missing");
+
+ VPTransformState State{*BestVF,
+ BestUF,
+ OrigLoop,
+ LI,
+ DT,
+ ILV.Builder,
+ ILV.VectorLoopValueMap,
+ &ILV,
+ CallbackILV};
State.CFG.PrevBB = ILV.createVectorizedLoopSkeleton();
State.TripCount = ILV.getOrCreateTripCount(nullptr);
State.CanonicalIV = ILV.Induction;
- ILV.printDebugTracesAtStart();
-
+ ILV.printDebugTracesAtStart();
+
//===------------------------------------------------===//
//
// Notice: any optimization or new instruction that go
@@ -7739,48 +7739,48 @@ void LoopVectorizationPlanner::executePlan(InnerLoopVectorizer &ILV,
// 3. Fix the vectorized code: take care of header phi's, live-outs,
// predication, updating analyses.
ILV.fixVectorizedLoop();
-
- ILV.printDebugTracesAtEnd();
+
+ ILV.printDebugTracesAtEnd();
}
void LoopVectorizationPlanner::collectTriviallyDeadInstructions(
SmallPtrSetImpl<Instruction *> &DeadInstructions) {
- // We create new control-flow for the vectorized loop, so the original exit
- // conditions will be dead after vectorization if it's only used by the
- // terminator
- SmallVector<BasicBlock*> ExitingBlocks;
- OrigLoop->getExitingBlocks(ExitingBlocks);
- for (auto *BB : ExitingBlocks) {
- auto *Cmp = dyn_cast<Instruction>(BB->getTerminator()->getOperand(0));
- if (!Cmp || !Cmp->hasOneUse())
- continue;
-
- // TODO: we should introduce a getUniqueExitingBlocks on Loop
- if (!DeadInstructions.insert(Cmp).second)
- continue;
-
- // The operands of the icmp is often a dead trunc, used by IndUpdate.
- // TODO: can recurse through operands in general
- for (Value *Op : Cmp->operands()) {
- if (isa<TruncInst>(Op) && Op->hasOneUse())
- DeadInstructions.insert(cast<Instruction>(Op));
- }
- }
-
+ // We create new control-flow for the vectorized loop, so the original exit
+ // conditions will be dead after vectorization if it's only used by the
+ // terminator
+ SmallVector<BasicBlock*> ExitingBlocks;
+ OrigLoop->getExitingBlocks(ExitingBlocks);
+ for (auto *BB : ExitingBlocks) {
+ auto *Cmp = dyn_cast<Instruction>(BB->getTerminator()->getOperand(0));
+ if (!Cmp || !Cmp->hasOneUse())
+ continue;
+
+ // TODO: we should introduce a getUniqueExitingBlocks on Loop
+ if (!DeadInstructions.insert(Cmp).second)
+ continue;
+
+ // The operands of the icmp is often a dead trunc, used by IndUpdate.
+ // TODO: can recurse through operands in general
+ for (Value *Op : Cmp->operands()) {
+ if (isa<TruncInst>(Op) && Op->hasOneUse())
+ DeadInstructions.insert(cast<Instruction>(Op));
+ }
+ }
+
// We create new "steps" for induction variable updates to which the original
// induction variables map. An original update instruction will be dead if
// all its users except the induction variable are dead.
- auto *Latch = OrigLoop->getLoopLatch();
+ auto *Latch = OrigLoop->getLoopLatch();
for (auto &Induction : Legal->getInductionVars()) {
PHINode *Ind = Induction.first;
auto *IndUpdate = cast<Instruction>(Ind->getIncomingValueForBlock(Latch));
-
- // If the tail is to be folded by masking, the primary induction variable,
- // if exists, isn't dead: it will be used for masking. Don't kill it.
- if (CM.foldTailByMasking() && IndUpdate == Legal->getPrimaryInduction())
- continue;
-
+
+ // If the tail is to be folded by masking, the primary induction variable,
+ // if exists, isn't dead: it will be used for masking. Don't kill it.
+ if (CM.foldTailByMasking() && IndUpdate == Legal->getPrimaryInduction())
+ continue;
+
if (llvm::all_of(IndUpdate->users(), [&](User *U) -> bool {
return U == Ind || DeadInstructions.count(cast<Instruction>(U));
}))
@@ -7855,284 +7855,284 @@ static void AddRuntimeUnrollDisableMetaData(Loop *L) {
}
}
-//===--------------------------------------------------------------------===//
-// EpilogueVectorizerMainLoop
-//===--------------------------------------------------------------------===//
-
-/// This function is partially responsible for generating the control flow
-/// depicted in https://llvm.org/docs/Vectorizers.html#epilogue-vectorization.
-BasicBlock *EpilogueVectorizerMainLoop::createEpilogueVectorizedLoopSkeleton() {
- MDNode *OrigLoopID = OrigLoop->getLoopID();
- Loop *Lp = createVectorLoopSkeleton("");
-
- // Generate the code to check the minimum iteration count of the vector
- // epilogue (see below).
- EPI.EpilogueIterationCountCheck =
- emitMinimumIterationCountCheck(Lp, LoopScalarPreHeader, true);
- EPI.EpilogueIterationCountCheck->setName("iter.check");
-
- // Generate the code to check any assumptions that we've made for SCEV
- // expressions.
- BasicBlock *SavedPreHeader = LoopVectorPreHeader;
- emitSCEVChecks(Lp, LoopScalarPreHeader);
-
- // If a safety check was generated save it.
- if (SavedPreHeader != LoopVectorPreHeader)
- EPI.SCEVSafetyCheck = SavedPreHeader;
-
- // Generate the code that checks at runtime if arrays overlap. We put the
- // checks into a separate block to make the more common case of few elements
- // faster.
- SavedPreHeader = LoopVectorPreHeader;
- emitMemRuntimeChecks(Lp, LoopScalarPreHeader);
-
- // If a safety check was generated save/overwite it.
- if (SavedPreHeader != LoopVectorPreHeader)
- EPI.MemSafetyCheck = SavedPreHeader;
-
- // Generate the iteration count check for the main loop, *after* the check
- // for the epilogue loop, so that the path-length is shorter for the case
- // that goes directly through the vector epilogue. The longer-path length for
- // the main loop is compensated for, by the gain from vectorizing the larger
- // trip count. Note: the branch will get updated later on when we vectorize
- // the epilogue.
- EPI.MainLoopIterationCountCheck =
- emitMinimumIterationCountCheck(Lp, LoopScalarPreHeader, false);
-
- // Generate the induction variable.
- OldInduction = Legal->getPrimaryInduction();
- Type *IdxTy = Legal->getWidestInductionType();
- Value *StartIdx = ConstantInt::get(IdxTy, 0);
- Constant *Step = ConstantInt::get(IdxTy, VF.getKnownMinValue() * UF);
- Value *CountRoundDown = getOrCreateVectorTripCount(Lp);
- EPI.VectorTripCount = CountRoundDown;
- Induction =
- createInductionVariable(Lp, StartIdx, CountRoundDown, Step,
- getDebugLocFromInstOrOperands(OldInduction));
-
- // Skip induction resume value creation here because they will be created in
- // the second pass. If we created them here, they wouldn't be used anyway,
- // because the vplan in the second pass still contains the inductions from the
- // original loop.
-
- return completeLoopSkeleton(Lp, OrigLoopID);
-}
-
-void EpilogueVectorizerMainLoop::printDebugTracesAtStart() {
- LLVM_DEBUG({
- dbgs() << "Create Skeleton for epilogue vectorized loop (first pass)\n"
- << "Main Loop VF:" << EPI.MainLoopVF.getKnownMinValue()
- << ", Main Loop UF:" << EPI.MainLoopUF
- << ", Epilogue Loop VF:" << EPI.EpilogueVF.getKnownMinValue()
- << ", Epilogue Loop UF:" << EPI.EpilogueUF << "\n";
- });
-}
-
-void EpilogueVectorizerMainLoop::printDebugTracesAtEnd() {
- DEBUG_WITH_TYPE(VerboseDebug, {
- dbgs() << "intermediate fn:\n" << *Induction->getFunction() << "\n";
- });
-}
-
-BasicBlock *EpilogueVectorizerMainLoop::emitMinimumIterationCountCheck(
- Loop *L, BasicBlock *Bypass, bool ForEpilogue) {
- assert(L && "Expected valid Loop.");
- assert(Bypass && "Expected valid bypass basic block.");
- unsigned VFactor =
- ForEpilogue ? EPI.EpilogueVF.getKnownMinValue() : VF.getKnownMinValue();
- unsigned UFactor = ForEpilogue ? EPI.EpilogueUF : UF;
- Value *Count = getOrCreateTripCount(L);
- // Reuse existing vector loop preheader for TC checks.
- // Note that new preheader block is generated for vector loop.
- BasicBlock *const TCCheckBlock = LoopVectorPreHeader;
- IRBuilder<> Builder(TCCheckBlock->getTerminator());
-
- // Generate code to check if the loop's trip count is less than VF * UF of the
- // main vector loop.
- auto P =
- Cost->requiresScalarEpilogue() ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_ULT;
-
- Value *CheckMinIters = Builder.CreateICmp(
- P, Count, ConstantInt::get(Count->getType(), VFactor * UFactor),
- "min.iters.check");
-
- if (!ForEpilogue)
- TCCheckBlock->setName("vector.main.loop.iter.check");
-
- // Create new preheader for vector loop.
- LoopVectorPreHeader = SplitBlock(TCCheckBlock, TCCheckBlock->getTerminator(),
- DT, LI, nullptr, "vector.ph");
-
- if (ForEpilogue) {
- assert(DT->properlyDominates(DT->getNode(TCCheckBlock),
- DT->getNode(Bypass)->getIDom()) &&
- "TC check is expected to dominate Bypass");
-
- // Update dominator for Bypass & LoopExit.
- DT->changeImmediateDominator(Bypass, TCCheckBlock);
- DT->changeImmediateDominator(LoopExitBlock, TCCheckBlock);
-
- LoopBypassBlocks.push_back(TCCheckBlock);
-
- // Save the trip count so we don't have to regenerate it in the
- // vec.epilog.iter.check. This is safe to do because the trip count
- // generated here dominates the vector epilog iter check.
- EPI.TripCount = Count;
- }
-
- ReplaceInstWithInst(
- TCCheckBlock->getTerminator(),
- BranchInst::Create(Bypass, LoopVectorPreHeader, CheckMinIters));
-
- return TCCheckBlock;
-}
-
-//===--------------------------------------------------------------------===//
-// EpilogueVectorizerEpilogueLoop
-//===--------------------------------------------------------------------===//
-
-/// This function is partially responsible for generating the control flow
-/// depicted in https://llvm.org/docs/Vectorizers.html#epilogue-vectorization.
-BasicBlock *
-EpilogueVectorizerEpilogueLoop::createEpilogueVectorizedLoopSkeleton() {
- MDNode *OrigLoopID = OrigLoop->getLoopID();
- Loop *Lp = createVectorLoopSkeleton("vec.epilog.");
-
- // Now, compare the remaining count and if there aren't enough iterations to
- // execute the vectorized epilogue skip to the scalar part.
- BasicBlock *VecEpilogueIterationCountCheck = LoopVectorPreHeader;
- VecEpilogueIterationCountCheck->setName("vec.epilog.iter.check");
- LoopVectorPreHeader =
- SplitBlock(LoopVectorPreHeader, LoopVectorPreHeader->getTerminator(), DT,
- LI, nullptr, "vec.epilog.ph");
- emitMinimumVectorEpilogueIterCountCheck(Lp, LoopScalarPreHeader,
- VecEpilogueIterationCountCheck);
-
- // Adjust the control flow taking the state info from the main loop
- // vectorization into account.
- assert(EPI.MainLoopIterationCountCheck && EPI.EpilogueIterationCountCheck &&
- "expected this to be saved from the previous pass.");
- EPI.MainLoopIterationCountCheck->getTerminator()->replaceUsesOfWith(
- VecEpilogueIterationCountCheck, LoopVectorPreHeader);
-
- DT->changeImmediateDominator(LoopVectorPreHeader,
- EPI.MainLoopIterationCountCheck);
-
- EPI.EpilogueIterationCountCheck->getTerminator()->replaceUsesOfWith(
- VecEpilogueIterationCountCheck, LoopScalarPreHeader);
-
- if (EPI.SCEVSafetyCheck)
- EPI.SCEVSafetyCheck->getTerminator()->replaceUsesOfWith(
- VecEpilogueIterationCountCheck, LoopScalarPreHeader);
- if (EPI.MemSafetyCheck)
- EPI.MemSafetyCheck->getTerminator()->replaceUsesOfWith(
- VecEpilogueIterationCountCheck, LoopScalarPreHeader);
-
- DT->changeImmediateDominator(
- VecEpilogueIterationCountCheck,
- VecEpilogueIterationCountCheck->getSinglePredecessor());
-
- DT->changeImmediateDominator(LoopScalarPreHeader,
- EPI.EpilogueIterationCountCheck);
- DT->changeImmediateDominator(LoopExitBlock, EPI.EpilogueIterationCountCheck);
-
- // Keep track of bypass blocks, as they feed start values to the induction
- // phis in the scalar loop preheader.
- if (EPI.SCEVSafetyCheck)
- LoopBypassBlocks.push_back(EPI.SCEVSafetyCheck);
- if (EPI.MemSafetyCheck)
- LoopBypassBlocks.push_back(EPI.MemSafetyCheck);
- LoopBypassBlocks.push_back(EPI.EpilogueIterationCountCheck);
-
- // Generate a resume induction for the vector epilogue and put it in the
- // vector epilogue preheader
- Type *IdxTy = Legal->getWidestInductionType();
- PHINode *EPResumeVal = PHINode::Create(IdxTy, 2, "vec.epilog.resume.val",
- LoopVectorPreHeader->getFirstNonPHI());
- EPResumeVal->addIncoming(EPI.VectorTripCount, VecEpilogueIterationCountCheck);
- EPResumeVal->addIncoming(ConstantInt::get(IdxTy, 0),
- EPI.MainLoopIterationCountCheck);
-
- // Generate the induction variable.
- OldInduction = Legal->getPrimaryInduction();
- Value *CountRoundDown = getOrCreateVectorTripCount(Lp);
- Constant *Step = ConstantInt::get(IdxTy, VF.getKnownMinValue() * UF);
- Value *StartIdx = EPResumeVal;
- Induction =
- createInductionVariable(Lp, StartIdx, CountRoundDown, Step,
- getDebugLocFromInstOrOperands(OldInduction));
-
- // Generate induction resume values. These variables save the new starting
- // indexes for the scalar loop. They are used to test if there are any tail
- // iterations left once the vector loop has completed.
- // Note that when the vectorized epilogue is skipped due to iteration count
- // check, then the resume value for the induction variable comes from
- // the trip count of the main vector loop, hence passing the AdditionalBypass
- // argument.
- createInductionResumeValues(Lp, CountRoundDown,
- {VecEpilogueIterationCountCheck,
- EPI.VectorTripCount} /* AdditionalBypass */);
-
- AddRuntimeUnrollDisableMetaData(Lp);
- return completeLoopSkeleton(Lp, OrigLoopID);
-}
-
-BasicBlock *
-EpilogueVectorizerEpilogueLoop::emitMinimumVectorEpilogueIterCountCheck(
- Loop *L, BasicBlock *Bypass, BasicBlock *Insert) {
-
- assert(EPI.TripCount &&
- "Expected trip count to have been safed in the first pass.");
- assert(
- (!isa<Instruction>(EPI.TripCount) ||
- DT->dominates(cast<Instruction>(EPI.TripCount)->getParent(), Insert)) &&
- "saved trip count does not dominate insertion point.");
- Value *TC = EPI.TripCount;
- IRBuilder<> Builder(Insert->getTerminator());
- Value *Count = Builder.CreateSub(TC, EPI.VectorTripCount, "n.vec.remaining");
-
- // Generate code to check if the loop's trip count is less than VF * UF of the
- // vector epilogue loop.
- auto P =
- Cost->requiresScalarEpilogue() ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_ULT;
-
- Value *CheckMinIters = Builder.CreateICmp(
- P, Count,
- ConstantInt::get(Count->getType(),
- EPI.EpilogueVF.getKnownMinValue() * EPI.EpilogueUF),
- "min.epilog.iters.check");
-
- ReplaceInstWithInst(
- Insert->getTerminator(),
- BranchInst::Create(Bypass, LoopVectorPreHeader, CheckMinIters));
-
- LoopBypassBlocks.push_back(Insert);
- return Insert;
-}
-
-void EpilogueVectorizerEpilogueLoop::printDebugTracesAtStart() {
- LLVM_DEBUG({
- dbgs() << "Create Skeleton for epilogue vectorized loop (second pass)\n"
- << "Main Loop VF:" << EPI.MainLoopVF.getKnownMinValue()
- << ", Main Loop UF:" << EPI.MainLoopUF
- << ", Epilogue Loop VF:" << EPI.EpilogueVF.getKnownMinValue()
- << ", Epilogue Loop UF:" << EPI.EpilogueUF << "\n";
- });
-}
-
-void EpilogueVectorizerEpilogueLoop::printDebugTracesAtEnd() {
- DEBUG_WITH_TYPE(VerboseDebug, {
- dbgs() << "final fn:\n" << *Induction->getFunction() << "\n";
- });
-}
-
+//===--------------------------------------------------------------------===//
+// EpilogueVectorizerMainLoop
+//===--------------------------------------------------------------------===//
+
+/// This function is partially responsible for generating the control flow
+/// depicted in https://llvm.org/docs/Vectorizers.html#epilogue-vectorization.
+BasicBlock *EpilogueVectorizerMainLoop::createEpilogueVectorizedLoopSkeleton() {
+ MDNode *OrigLoopID = OrigLoop->getLoopID();
+ Loop *Lp = createVectorLoopSkeleton("");
+
+ // Generate the code to check the minimum iteration count of the vector
+ // epilogue (see below).
+ EPI.EpilogueIterationCountCheck =
+ emitMinimumIterationCountCheck(Lp, LoopScalarPreHeader, true);
+ EPI.EpilogueIterationCountCheck->setName("iter.check");
+
+ // Generate the code to check any assumptions that we've made for SCEV
+ // expressions.
+ BasicBlock *SavedPreHeader = LoopVectorPreHeader;
+ emitSCEVChecks(Lp, LoopScalarPreHeader);
+
+ // If a safety check was generated save it.
+ if (SavedPreHeader != LoopVectorPreHeader)
+ EPI.SCEVSafetyCheck = SavedPreHeader;
+
+ // Generate the code that checks at runtime if arrays overlap. We put the
+ // checks into a separate block to make the more common case of few elements
+ // faster.
+ SavedPreHeader = LoopVectorPreHeader;
+ emitMemRuntimeChecks(Lp, LoopScalarPreHeader);
+
+ // If a safety check was generated save/overwite it.
+ if (SavedPreHeader != LoopVectorPreHeader)
+ EPI.MemSafetyCheck = SavedPreHeader;
+
+ // Generate the iteration count check for the main loop, *after* the check
+ // for the epilogue loop, so that the path-length is shorter for the case
+ // that goes directly through the vector epilogue. The longer-path length for
+ // the main loop is compensated for, by the gain from vectorizing the larger
+ // trip count. Note: the branch will get updated later on when we vectorize
+ // the epilogue.
+ EPI.MainLoopIterationCountCheck =
+ emitMinimumIterationCountCheck(Lp, LoopScalarPreHeader, false);
+
+ // Generate the induction variable.
+ OldInduction = Legal->getPrimaryInduction();
+ Type *IdxTy = Legal->getWidestInductionType();
+ Value *StartIdx = ConstantInt::get(IdxTy, 0);
+ Constant *Step = ConstantInt::get(IdxTy, VF.getKnownMinValue() * UF);
+ Value *CountRoundDown = getOrCreateVectorTripCount(Lp);
+ EPI.VectorTripCount = CountRoundDown;
+ Induction =
+ createInductionVariable(Lp, StartIdx, CountRoundDown, Step,
+ getDebugLocFromInstOrOperands(OldInduction));
+
+ // Skip induction resume value creation here because they will be created in
+ // the second pass. If we created them here, they wouldn't be used anyway,
+ // because the vplan in the second pass still contains the inductions from the
+ // original loop.
+
+ return completeLoopSkeleton(Lp, OrigLoopID);
+}
+
+void EpilogueVectorizerMainLoop::printDebugTracesAtStart() {
+ LLVM_DEBUG({
+ dbgs() << "Create Skeleton for epilogue vectorized loop (first pass)\n"
+ << "Main Loop VF:" << EPI.MainLoopVF.getKnownMinValue()
+ << ", Main Loop UF:" << EPI.MainLoopUF
+ << ", Epilogue Loop VF:" << EPI.EpilogueVF.getKnownMinValue()
+ << ", Epilogue Loop UF:" << EPI.EpilogueUF << "\n";
+ });
+}
+
+void EpilogueVectorizerMainLoop::printDebugTracesAtEnd() {
+ DEBUG_WITH_TYPE(VerboseDebug, {
+ dbgs() << "intermediate fn:\n" << *Induction->getFunction() << "\n";
+ });
+}
+
+BasicBlock *EpilogueVectorizerMainLoop::emitMinimumIterationCountCheck(
+ Loop *L, BasicBlock *Bypass, bool ForEpilogue) {
+ assert(L && "Expected valid Loop.");
+ assert(Bypass && "Expected valid bypass basic block.");
+ unsigned VFactor =
+ ForEpilogue ? EPI.EpilogueVF.getKnownMinValue() : VF.getKnownMinValue();
+ unsigned UFactor = ForEpilogue ? EPI.EpilogueUF : UF;
+ Value *Count = getOrCreateTripCount(L);
+ // Reuse existing vector loop preheader for TC checks.
+ // Note that new preheader block is generated for vector loop.
+ BasicBlock *const TCCheckBlock = LoopVectorPreHeader;
+ IRBuilder<> Builder(TCCheckBlock->getTerminator());
+
+ // Generate code to check if the loop's trip count is less than VF * UF of the
+ // main vector loop.
+ auto P =
+ Cost->requiresScalarEpilogue() ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_ULT;
+
+ Value *CheckMinIters = Builder.CreateICmp(
+ P, Count, ConstantInt::get(Count->getType(), VFactor * UFactor),
+ "min.iters.check");
+
+ if (!ForEpilogue)
+ TCCheckBlock->setName("vector.main.loop.iter.check");
+
+ // Create new preheader for vector loop.
+ LoopVectorPreHeader = SplitBlock(TCCheckBlock, TCCheckBlock->getTerminator(),
+ DT, LI, nullptr, "vector.ph");
+
+ if (ForEpilogue) {
+ assert(DT->properlyDominates(DT->getNode(TCCheckBlock),
+ DT->getNode(Bypass)->getIDom()) &&
+ "TC check is expected to dominate Bypass");
+
+ // Update dominator for Bypass & LoopExit.
+ DT->changeImmediateDominator(Bypass, TCCheckBlock);
+ DT->changeImmediateDominator(LoopExitBlock, TCCheckBlock);
+
+ LoopBypassBlocks.push_back(TCCheckBlock);
+
+ // Save the trip count so we don't have to regenerate it in the
+ // vec.epilog.iter.check. This is safe to do because the trip count
+ // generated here dominates the vector epilog iter check.
+ EPI.TripCount = Count;
+ }
+
+ ReplaceInstWithInst(
+ TCCheckBlock->getTerminator(),
+ BranchInst::Create(Bypass, LoopVectorPreHeader, CheckMinIters));
+
+ return TCCheckBlock;
+}
+
+//===--------------------------------------------------------------------===//
+// EpilogueVectorizerEpilogueLoop
+//===--------------------------------------------------------------------===//
+
+/// This function is partially responsible for generating the control flow
+/// depicted in https://llvm.org/docs/Vectorizers.html#epilogue-vectorization.
+BasicBlock *
+EpilogueVectorizerEpilogueLoop::createEpilogueVectorizedLoopSkeleton() {
+ MDNode *OrigLoopID = OrigLoop->getLoopID();
+ Loop *Lp = createVectorLoopSkeleton("vec.epilog.");
+
+ // Now, compare the remaining count and if there aren't enough iterations to
+ // execute the vectorized epilogue skip to the scalar part.
+ BasicBlock *VecEpilogueIterationCountCheck = LoopVectorPreHeader;
+ VecEpilogueIterationCountCheck->setName("vec.epilog.iter.check");
+ LoopVectorPreHeader =
+ SplitBlock(LoopVectorPreHeader, LoopVectorPreHeader->getTerminator(), DT,
+ LI, nullptr, "vec.epilog.ph");
+ emitMinimumVectorEpilogueIterCountCheck(Lp, LoopScalarPreHeader,
+ VecEpilogueIterationCountCheck);
+
+ // Adjust the control flow taking the state info from the main loop
+ // vectorization into account.
+ assert(EPI.MainLoopIterationCountCheck && EPI.EpilogueIterationCountCheck &&
+ "expected this to be saved from the previous pass.");
+ EPI.MainLoopIterationCountCheck->getTerminator()->replaceUsesOfWith(
+ VecEpilogueIterationCountCheck, LoopVectorPreHeader);
+
+ DT->changeImmediateDominator(LoopVectorPreHeader,
+ EPI.MainLoopIterationCountCheck);
+
+ EPI.EpilogueIterationCountCheck->getTerminator()->replaceUsesOfWith(
+ VecEpilogueIterationCountCheck, LoopScalarPreHeader);
+
+ if (EPI.SCEVSafetyCheck)
+ EPI.SCEVSafetyCheck->getTerminator()->replaceUsesOfWith(
+ VecEpilogueIterationCountCheck, LoopScalarPreHeader);
+ if (EPI.MemSafetyCheck)
+ EPI.MemSafetyCheck->getTerminator()->replaceUsesOfWith(
+ VecEpilogueIterationCountCheck, LoopScalarPreHeader);
+
+ DT->changeImmediateDominator(
+ VecEpilogueIterationCountCheck,
+ VecEpilogueIterationCountCheck->getSinglePredecessor());
+
+ DT->changeImmediateDominator(LoopScalarPreHeader,
+ EPI.EpilogueIterationCountCheck);
+ DT->changeImmediateDominator(LoopExitBlock, EPI.EpilogueIterationCountCheck);
+
+ // Keep track of bypass blocks, as they feed start values to the induction
+ // phis in the scalar loop preheader.
+ if (EPI.SCEVSafetyCheck)
+ LoopBypassBlocks.push_back(EPI.SCEVSafetyCheck);
+ if (EPI.MemSafetyCheck)
+ LoopBypassBlocks.push_back(EPI.MemSafetyCheck);
+ LoopBypassBlocks.push_back(EPI.EpilogueIterationCountCheck);
+
+ // Generate a resume induction for the vector epilogue and put it in the
+ // vector epilogue preheader
+ Type *IdxTy = Legal->getWidestInductionType();
+ PHINode *EPResumeVal = PHINode::Create(IdxTy, 2, "vec.epilog.resume.val",
+ LoopVectorPreHeader->getFirstNonPHI());
+ EPResumeVal->addIncoming(EPI.VectorTripCount, VecEpilogueIterationCountCheck);
+ EPResumeVal->addIncoming(ConstantInt::get(IdxTy, 0),
+ EPI.MainLoopIterationCountCheck);
+
+ // Generate the induction variable.
+ OldInduction = Legal->getPrimaryInduction();
+ Value *CountRoundDown = getOrCreateVectorTripCount(Lp);
+ Constant *Step = ConstantInt::get(IdxTy, VF.getKnownMinValue() * UF);
+ Value *StartIdx = EPResumeVal;
+ Induction =
+ createInductionVariable(Lp, StartIdx, CountRoundDown, Step,
+ getDebugLocFromInstOrOperands(OldInduction));
+
+ // Generate induction resume values. These variables save the new starting
+ // indexes for the scalar loop. They are used to test if there are any tail
+ // iterations left once the vector loop has completed.
+ // Note that when the vectorized epilogue is skipped due to iteration count
+ // check, then the resume value for the induction variable comes from
+ // the trip count of the main vector loop, hence passing the AdditionalBypass
+ // argument.
+ createInductionResumeValues(Lp, CountRoundDown,
+ {VecEpilogueIterationCountCheck,
+ EPI.VectorTripCount} /* AdditionalBypass */);
+
+ AddRuntimeUnrollDisableMetaData(Lp);
+ return completeLoopSkeleton(Lp, OrigLoopID);
+}
+
+BasicBlock *
+EpilogueVectorizerEpilogueLoop::emitMinimumVectorEpilogueIterCountCheck(
+ Loop *L, BasicBlock *Bypass, BasicBlock *Insert) {
+
+ assert(EPI.TripCount &&
+ "Expected trip count to have been safed in the first pass.");
+ assert(
+ (!isa<Instruction>(EPI.TripCount) ||
+ DT->dominates(cast<Instruction>(EPI.TripCount)->getParent(), Insert)) &&
+ "saved trip count does not dominate insertion point.");
+ Value *TC = EPI.TripCount;
+ IRBuilder<> Builder(Insert->getTerminator());
+ Value *Count = Builder.CreateSub(TC, EPI.VectorTripCount, "n.vec.remaining");
+
+ // Generate code to check if the loop's trip count is less than VF * UF of the
+ // vector epilogue loop.
+ auto P =
+ Cost->requiresScalarEpilogue() ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_ULT;
+
+ Value *CheckMinIters = Builder.CreateICmp(
+ P, Count,
+ ConstantInt::get(Count->getType(),
+ EPI.EpilogueVF.getKnownMinValue() * EPI.EpilogueUF),
+ "min.epilog.iters.check");
+
+ ReplaceInstWithInst(
+ Insert->getTerminator(),
+ BranchInst::Create(Bypass, LoopVectorPreHeader, CheckMinIters));
+
+ LoopBypassBlocks.push_back(Insert);
+ return Insert;
+}
+
+void EpilogueVectorizerEpilogueLoop::printDebugTracesAtStart() {
+ LLVM_DEBUG({
+ dbgs() << "Create Skeleton for epilogue vectorized loop (second pass)\n"
+ << "Main Loop VF:" << EPI.MainLoopVF.getKnownMinValue()
+ << ", Main Loop UF:" << EPI.MainLoopUF
+ << ", Epilogue Loop VF:" << EPI.EpilogueVF.getKnownMinValue()
+ << ", Epilogue Loop UF:" << EPI.EpilogueUF << "\n";
+ });
+}
+
+void EpilogueVectorizerEpilogueLoop::printDebugTracesAtEnd() {
+ DEBUG_WITH_TYPE(VerboseDebug, {
+ dbgs() << "final fn:\n" << *Induction->getFunction() << "\n";
+ });
+}
+
bool LoopVectorizationPlanner::getDecisionAndClampRange(
- const std::function<bool(ElementCount)> &Predicate, VFRange &Range) {
- assert(!Range.isEmpty() && "Trying to test an empty VF range.");
+ const std::function<bool(ElementCount)> &Predicate, VFRange &Range) {
+ assert(!Range.isEmpty() && "Trying to test an empty VF range.");
bool PredicateAtRangeStart = Predicate(Range.Start);
- for (ElementCount TmpVF = Range.Start * 2;
- ElementCount::isKnownLT(TmpVF, Range.End); TmpVF *= 2)
+ for (ElementCount TmpVF = Range.Start * 2;
+ ElementCount::isKnownLT(TmpVF, Range.End); TmpVF *= 2)
if (Predicate(TmpVF) != PredicateAtRangeStart) {
Range.End = TmpVF;
break;
@@ -8146,11 +8146,11 @@ bool LoopVectorizationPlanner::getDecisionAndClampRange(
/// of VF's starting at a given VF and extending it as much as possible. Each
/// vectorization decision can potentially shorten this sub-range during
/// buildVPlan().
-void LoopVectorizationPlanner::buildVPlans(ElementCount MinVF,
- ElementCount MaxVF) {
- auto MaxVFPlusOne = MaxVF.getWithIncrement(1);
- for (ElementCount VF = MinVF; ElementCount::isKnownLT(VF, MaxVFPlusOne);) {
- VFRange SubRange = {VF, MaxVFPlusOne};
+void LoopVectorizationPlanner::buildVPlans(ElementCount MinVF,
+ ElementCount MaxVF) {
+ auto MaxVFPlusOne = MaxVF.getWithIncrement(1);
+ for (ElementCount VF = MinVF; ElementCount::isKnownLT(VF, MaxVFPlusOne);) {
+ VFRange SubRange = {VF, MaxVFPlusOne};
VPlans.push_back(buildVPlan(SubRange));
VF = SubRange.End;
}
@@ -8175,27 +8175,27 @@ VPValue *VPRecipeBuilder::createEdgeMask(BasicBlock *Src, BasicBlock *Dst,
if (!BI->isConditional() || BI->getSuccessor(0) == BI->getSuccessor(1))
return EdgeMaskCache[Edge] = SrcMask;
- // If source is an exiting block, we know the exit edge is dynamically dead
- // in the vector loop, and thus we don't need to restrict the mask. Avoid
- // adding uses of an otherwise potentially dead instruction.
- if (OrigLoop->isLoopExiting(Src))
- return EdgeMaskCache[Edge] = SrcMask;
-
- VPValue *EdgeMask = Plan->getOrAddVPValue(BI->getCondition());
+ // If source is an exiting block, we know the exit edge is dynamically dead
+ // in the vector loop, and thus we don't need to restrict the mask. Avoid
+ // adding uses of an otherwise potentially dead instruction.
+ if (OrigLoop->isLoopExiting(Src))
+ return EdgeMaskCache[Edge] = SrcMask;
+
+ VPValue *EdgeMask = Plan->getOrAddVPValue(BI->getCondition());
assert(EdgeMask && "No Edge Mask found for condition");
if (BI->getSuccessor(0) != Dst)
EdgeMask = Builder.createNot(EdgeMask);
- if (SrcMask) { // Otherwise block in-mask is all-one, no need to AND.
- // The condition is 'SrcMask && EdgeMask', which is equivalent to
- // 'select i1 SrcMask, i1 EdgeMask, i1 false'.
- // The select version does not introduce new UB if SrcMask is false and
- // EdgeMask is poison. Using 'and' here introduces undefined behavior.
- VPValue *False = Plan->getOrAddVPValue(
- ConstantInt::getFalse(BI->getCondition()->getType()));
- EdgeMask = Builder.createSelect(SrcMask, EdgeMask, False);
- }
+ if (SrcMask) { // Otherwise block in-mask is all-one, no need to AND.
+ // The condition is 'SrcMask && EdgeMask', which is equivalent to
+ // 'select i1 SrcMask, i1 EdgeMask, i1 false'.
+ // The select version does not introduce new UB if SrcMask is false and
+ // EdgeMask is poison. Using 'and' here introduces undefined behavior.
+ VPValue *False = Plan->getOrAddVPValue(
+ ConstantInt::getFalse(BI->getCondition()->getType()));
+ EdgeMask = Builder.createSelect(SrcMask, EdgeMask, False);
+ }
return EdgeMaskCache[Edge] = EdgeMask;
}
@@ -8216,34 +8216,34 @@ VPValue *VPRecipeBuilder::createBlockInMask(BasicBlock *BB, VPlanPtr &Plan) {
if (!CM.blockNeedsPredication(BB))
return BlockMaskCache[BB] = BlockMask; // Loop incoming mask is all-one.
- // Create the block in mask as the first non-phi instruction in the block.
- VPBuilder::InsertPointGuard Guard(Builder);
- auto NewInsertionPoint = Builder.getInsertBlock()->getFirstNonPhi();
- Builder.setInsertPoint(Builder.getInsertBlock(), NewInsertionPoint);
-
+ // Create the block in mask as the first non-phi instruction in the block.
+ VPBuilder::InsertPointGuard Guard(Builder);
+ auto NewInsertionPoint = Builder.getInsertBlock()->getFirstNonPhi();
+ Builder.setInsertPoint(Builder.getInsertBlock(), NewInsertionPoint);
+
// Introduce the early-exit compare IV <= BTC to form header block mask.
// This is used instead of IV < TC because TC may wrap, unlike BTC.
// Start by constructing the desired canonical IV.
VPValue *IV = nullptr;
if (Legal->getPrimaryInduction())
- IV = Plan->getOrAddVPValue(Legal->getPrimaryInduction());
+ IV = Plan->getOrAddVPValue(Legal->getPrimaryInduction());
else {
auto IVRecipe = new VPWidenCanonicalIVRecipe();
- Builder.getInsertBlock()->insert(IVRecipe, NewInsertionPoint);
+ Builder.getInsertBlock()->insert(IVRecipe, NewInsertionPoint);
IV = IVRecipe->getVPValue();
}
VPValue *BTC = Plan->getOrCreateBackedgeTakenCount();
bool TailFolded = !CM.isScalarEpilogueAllowed();
-
- if (TailFolded && CM.TTI.emitGetActiveLaneMask()) {
- // While ActiveLaneMask is a binary op that consumes the loop tripcount
- // as a second argument, we only pass the IV here and extract the
- // tripcount from the transform state where codegen of the VP instructions
- // happen.
- BlockMask = Builder.createNaryOp(VPInstruction::ActiveLaneMask, {IV});
- } else {
+
+ if (TailFolded && CM.TTI.emitGetActiveLaneMask()) {
+ // While ActiveLaneMask is a binary op that consumes the loop tripcount
+ // as a second argument, we only pass the IV here and extract the
+ // tripcount from the transform state where codegen of the VP instructions
+ // happen.
+ BlockMask = Builder.createNaryOp(VPInstruction::ActiveLaneMask, {IV});
+ } else {
BlockMask = Builder.createNaryOp(VPInstruction::ICmpULE, {IV, BTC});
- }
+ }
return BlockMaskCache[BB] = BlockMask;
}
@@ -8264,13 +8264,13 @@ VPValue *VPRecipeBuilder::createBlockInMask(BasicBlock *BB, VPlanPtr &Plan) {
return BlockMaskCache[BB] = BlockMask;
}
-VPRecipeBase *VPRecipeBuilder::tryToWidenMemory(Instruction *I, VFRange &Range,
- VPlanPtr &Plan) {
+VPRecipeBase *VPRecipeBuilder::tryToWidenMemory(Instruction *I, VFRange &Range,
+ VPlanPtr &Plan) {
assert((isa<LoadInst>(I) || isa<StoreInst>(I)) &&
"Must be called with either a load or store");
- auto willWiden = [&](ElementCount VF) -> bool {
- if (VF.isScalar())
+ auto willWiden = [&](ElementCount VF) -> bool {
+ if (VF.isScalar())
return false;
LoopVectorizationCostModel::InstWidening Decision =
CM.getWideningDecision(I, VF);
@@ -8301,22 +8301,22 @@ VPRecipeBase *VPRecipeBuilder::tryToWidenMemory(Instruction *I, VFRange &Range,
}
VPWidenIntOrFpInductionRecipe *
-VPRecipeBuilder::tryToOptimizeInductionPHI(PHINode *Phi, VPlan &Plan) const {
+VPRecipeBuilder::tryToOptimizeInductionPHI(PHINode *Phi, VPlan &Plan) const {
// Check if this is an integer or fp induction. If so, build the recipe that
// produces its scalar and vector values.
InductionDescriptor II = Legal->getInductionVars().lookup(Phi);
if (II.getKind() == InductionDescriptor::IK_IntInduction ||
- II.getKind() == InductionDescriptor::IK_FpInduction) {
- VPValue *Start = Plan.getOrAddVPValue(II.getStartValue());
- return new VPWidenIntOrFpInductionRecipe(Phi, Start);
- }
+ II.getKind() == InductionDescriptor::IK_FpInduction) {
+ VPValue *Start = Plan.getOrAddVPValue(II.getStartValue());
+ return new VPWidenIntOrFpInductionRecipe(Phi, Start);
+ }
return nullptr;
}
VPWidenIntOrFpInductionRecipe *
-VPRecipeBuilder::tryToOptimizeInductionTruncate(TruncInst *I, VFRange &Range,
- VPlan &Plan) const {
+VPRecipeBuilder::tryToOptimizeInductionTruncate(TruncInst *I, VFRange &Range,
+ VPlan &Plan) const {
// Optimize the special case where the source is a constant integer
// induction variable. Notice that we can only optimize the 'trunc' case
// because (a) FP conversions lose precision, (b) sext/zext may wrap, and
@@ -8325,21 +8325,21 @@ VPRecipeBuilder::tryToOptimizeInductionTruncate(TruncInst *I, VFRange &Range,
// Determine whether \p K is a truncation based on an induction variable that
// can be optimized.
auto isOptimizableIVTruncate =
- [&](Instruction *K) -> std::function<bool(ElementCount)> {
- return [=](ElementCount VF) -> bool {
- return CM.isOptimizableIVTruncate(K, VF);
- };
+ [&](Instruction *K) -> std::function<bool(ElementCount)> {
+ return [=](ElementCount VF) -> bool {
+ return CM.isOptimizableIVTruncate(K, VF);
+ };
};
if (LoopVectorizationPlanner::getDecisionAndClampRange(
- isOptimizableIVTruncate(I), Range)) {
-
- InductionDescriptor II =
- Legal->getInductionVars().lookup(cast<PHINode>(I->getOperand(0)));
- VPValue *Start = Plan.getOrAddVPValue(II.getStartValue());
+ isOptimizableIVTruncate(I), Range)) {
+
+ InductionDescriptor II =
+ Legal->getInductionVars().lookup(cast<PHINode>(I->getOperand(0)));
+ VPValue *Start = Plan.getOrAddVPValue(II.getStartValue());
return new VPWidenIntOrFpInductionRecipe(cast<PHINode>(I->getOperand(0)),
- Start, I);
- }
+ Start, I);
+ }
return nullptr;
}
@@ -8368,9 +8368,9 @@ VPWidenCallRecipe *VPRecipeBuilder::tryToWidenCall(CallInst *CI, VFRange &Range,
VPlan &Plan) const {
bool IsPredicated = LoopVectorizationPlanner::getDecisionAndClampRange(
- [this, CI](ElementCount VF) {
- return CM.isScalarWithPredication(CI, VF);
- },
+ [this, CI](ElementCount VF) {
+ return CM.isScalarWithPredication(CI, VF);
+ },
Range);
if (IsPredicated)
@@ -8378,23 +8378,23 @@ VPWidenCallRecipe *VPRecipeBuilder::tryToWidenCall(CallInst *CI, VFRange &Range,
Intrinsic::ID ID = getVectorIntrinsicIDForCall(CI, TLI);
if (ID && (ID == Intrinsic::assume || ID == Intrinsic::lifetime_end ||
- ID == Intrinsic::lifetime_start || ID == Intrinsic::sideeffect ||
- ID == Intrinsic::pseudoprobe ||
- ID == Intrinsic::experimental_noalias_scope_decl))
+ ID == Intrinsic::lifetime_start || ID == Intrinsic::sideeffect ||
+ ID == Intrinsic::pseudoprobe ||
+ ID == Intrinsic::experimental_noalias_scope_decl))
return nullptr;
- auto willWiden = [&](ElementCount VF) -> bool {
+ auto willWiden = [&](ElementCount VF) -> bool {
Intrinsic::ID ID = getVectorIntrinsicIDForCall(CI, TLI);
// The following case may be scalarized depending on the VF.
// The flag shows whether we use Intrinsic or a usual Call for vectorized
// version of the instruction.
// Is it beneficial to perform intrinsic call compared to lib call?
bool NeedToScalarize = false;
- InstructionCost CallCost = CM.getVectorCallCost(CI, VF, NeedToScalarize);
- InstructionCost IntrinsicCost = ID ? CM.getVectorIntrinsicCost(CI, VF) : 0;
- bool UseVectorIntrinsic = ID && IntrinsicCost <= CallCost;
- assert(IntrinsicCost.isValid() && CallCost.isValid() &&
- "Cannot have invalid costs while widening");
+ InstructionCost CallCost = CM.getVectorCallCost(CI, VF, NeedToScalarize);
+ InstructionCost IntrinsicCost = ID ? CM.getVectorIntrinsicCost(CI, VF) : 0;
+ bool UseVectorIntrinsic = ID && IntrinsicCost <= CallCost;
+ assert(IntrinsicCost.isValid() && CallCost.isValid() &&
+ "Cannot have invalid costs while widening");
return UseVectorIntrinsic || !NeedToScalarize;
};
@@ -8409,7 +8409,7 @@ bool VPRecipeBuilder::shouldWiden(Instruction *I, VFRange &Range) const {
!isa<StoreInst>(I) && "Instruction should have been handled earlier");
// Instruction should be widened, unless it is scalar after vectorization,
// scalarization is profitable or it is predicated.
- auto WillScalarize = [this, I](ElementCount VF) -> bool {
+ auto WillScalarize = [this, I](ElementCount VF) -> bool {
return CM.isScalarAfterVectorization(I, VF) ||
CM.isProfitableToScalarize(I, VF) ||
CM.isScalarWithPredication(I, VF);
@@ -8472,17 +8472,17 @@ VPBasicBlock *VPRecipeBuilder::handleReplication(
DenseMap<Instruction *, VPReplicateRecipe *> &PredInst2Recipe,
VPlanPtr &Plan) {
bool IsUniform = LoopVectorizationPlanner::getDecisionAndClampRange(
- [&](ElementCount VF) { return CM.isUniformAfterVectorization(I, VF); },
+ [&](ElementCount VF) { return CM.isUniformAfterVectorization(I, VF); },
Range);
bool IsPredicated = LoopVectorizationPlanner::getDecisionAndClampRange(
- [&](ElementCount VF) { return CM.isScalarWithPredication(I, VF); },
- Range);
+ [&](ElementCount VF) { return CM.isScalarWithPredication(I, VF); },
+ Range);
auto *Recipe = new VPReplicateRecipe(I, Plan->mapToVPValues(I->operands()),
IsUniform, IsPredicated);
setRecipe(I, Recipe);
- Plan->addVPValue(I, Recipe);
+ Plan->addVPValue(I, Recipe);
// Find if I uses a predicated instruction. If so, it will use its scalar
// value. Avoid hoisting the insert-element which packs the scalar value into
@@ -8524,9 +8524,9 @@ VPRegionBlock *VPRecipeBuilder::createReplicateRegion(Instruction *Instr,
assert(Instr->getParent() && "Predicated instruction not in any basic block");
auto *BOMRecipe = new VPBranchOnMaskRecipe(BlockInMask);
auto *Entry = new VPBasicBlock(Twine(RegionName) + ".entry", BOMRecipe);
- auto *PHIRecipe = Instr->getType()->isVoidTy()
- ? nullptr
- : new VPPredInstPHIRecipe(Plan->getOrAddVPValue(Instr));
+ auto *PHIRecipe = Instr->getType()->isVoidTy()
+ ? nullptr
+ : new VPPredInstPHIRecipe(Plan->getOrAddVPValue(Instr));
auto *Exit = new VPBasicBlock(Twine(RegionName) + ".continue", PHIRecipe);
auto *Pred = new VPBasicBlock(Twine(RegionName) + ".if", PredRecipe);
VPRegionBlock *Region = new VPRegionBlock(Entry, Exit, RegionName, true);
@@ -8554,21 +8554,21 @@ VPRecipeBase *VPRecipeBuilder::tryToCreateWidenRecipe(Instruction *Instr,
if (auto Phi = dyn_cast<PHINode>(Instr)) {
if (Phi->getParent() != OrigLoop->getHeader())
return tryToBlend(Phi, Plan);
- if ((Recipe = tryToOptimizeInductionPHI(Phi, *Plan)))
+ if ((Recipe = tryToOptimizeInductionPHI(Phi, *Plan)))
return Recipe;
-
- if (Legal->isReductionVariable(Phi)) {
- RecurrenceDescriptor &RdxDesc = Legal->getReductionVars()[Phi];
- VPValue *StartV =
- Plan->getOrAddVPValue(RdxDesc.getRecurrenceStartValue());
- return new VPWidenPHIRecipe(Phi, RdxDesc, *StartV);
- }
-
+
+ if (Legal->isReductionVariable(Phi)) {
+ RecurrenceDescriptor &RdxDesc = Legal->getReductionVars()[Phi];
+ VPValue *StartV =
+ Plan->getOrAddVPValue(RdxDesc.getRecurrenceStartValue());
+ return new VPWidenPHIRecipe(Phi, RdxDesc, *StartV);
+ }
+
return new VPWidenPHIRecipe(Phi);
}
- if (isa<TruncInst>(Instr) && (Recipe = tryToOptimizeInductionTruncate(
- cast<TruncInst>(Instr), Range, *Plan)))
+ if (isa<TruncInst>(Instr) && (Recipe = tryToOptimizeInductionTruncate(
+ cast<TruncInst>(Instr), Range, *Plan)))
return Recipe;
if (!shouldWiden(Instr, Range))
@@ -8588,9 +8588,9 @@ VPRecipeBase *VPRecipeBuilder::tryToCreateWidenRecipe(Instruction *Instr,
return tryToWiden(Instr, *Plan);
}
-void LoopVectorizationPlanner::buildVPlansWithVPRecipes(ElementCount MinVF,
- ElementCount MaxVF) {
- assert(OrigLoop->isInnermost() && "Inner loop expected.");
+void LoopVectorizationPlanner::buildVPlansWithVPRecipes(ElementCount MinVF,
+ ElementCount MaxVF) {
+ assert(OrigLoop->isInnermost() && "Inner loop expected.");
// Collect instructions from the original loop that will become trivially dead
// in the vectorized loop. We don't need to vectorize these instructions. For
@@ -8613,17 +8613,17 @@ void LoopVectorizationPlanner::buildVPlansWithVPRecipes(ElementCount MinVF,
for (Instruction *I : DeadInstructions)
SinkAfter.erase(I);
- auto MaxVFPlusOne = MaxVF.getWithIncrement(1);
- for (ElementCount VF = MinVF; ElementCount::isKnownLT(VF, MaxVFPlusOne);) {
- VFRange SubRange = {VF, MaxVFPlusOne};
- VPlans.push_back(
- buildVPlanWithVPRecipes(SubRange, DeadInstructions, SinkAfter));
+ auto MaxVFPlusOne = MaxVF.getWithIncrement(1);
+ for (ElementCount VF = MinVF; ElementCount::isKnownLT(VF, MaxVFPlusOne);) {
+ VFRange SubRange = {VF, MaxVFPlusOne};
+ VPlans.push_back(
+ buildVPlanWithVPRecipes(SubRange, DeadInstructions, SinkAfter));
VF = SubRange.End;
}
}
VPlanPtr LoopVectorizationPlanner::buildVPlanWithVPRecipes(
- VFRange &Range, SmallPtrSetImpl<Instruction *> &DeadInstructions,
+ VFRange &Range, SmallPtrSetImpl<Instruction *> &DeadInstructions,
const DenseMap<Instruction *, Instruction *> &SinkAfter) {
// Hold a mapping from predicated instructions to their recipes, in order to
@@ -8646,28 +8646,28 @@ VPlanPtr LoopVectorizationPlanner::buildVPlanWithVPRecipes(
RecipeBuilder.recordRecipeOf(Entry.first);
RecipeBuilder.recordRecipeOf(Entry.second);
}
- for (auto &Reduction : CM.getInLoopReductionChains()) {
- PHINode *Phi = Reduction.first;
- RecurKind Kind = Legal->getReductionVars()[Phi].getRecurrenceKind();
- const SmallVector<Instruction *, 4> &ReductionOperations = Reduction.second;
-
- RecipeBuilder.recordRecipeOf(Phi);
- for (auto &R : ReductionOperations) {
- RecipeBuilder.recordRecipeOf(R);
- // For min/max reducitons, where we have a pair of icmp/select, we also
- // need to record the ICmp recipe, so it can be removed later.
- if (RecurrenceDescriptor::isMinMaxRecurrenceKind(Kind))
- RecipeBuilder.recordRecipeOf(cast<Instruction>(R->getOperand(0)));
- }
- }
-
+ for (auto &Reduction : CM.getInLoopReductionChains()) {
+ PHINode *Phi = Reduction.first;
+ RecurKind Kind = Legal->getReductionVars()[Phi].getRecurrenceKind();
+ const SmallVector<Instruction *, 4> &ReductionOperations = Reduction.second;
+
+ RecipeBuilder.recordRecipeOf(Phi);
+ for (auto &R : ReductionOperations) {
+ RecipeBuilder.recordRecipeOf(R);
+ // For min/max reducitons, where we have a pair of icmp/select, we also
+ // need to record the ICmp recipe, so it can be removed later.
+ if (RecurrenceDescriptor::isMinMaxRecurrenceKind(Kind))
+ RecipeBuilder.recordRecipeOf(cast<Instruction>(R->getOperand(0)));
+ }
+ }
+
// For each interleave group which is relevant for this (possibly trimmed)
// Range, add it to the set of groups to be later applied to the VPlan and add
// placeholders for its members' Recipes which we'll be replacing with a
// single VPInterleaveRecipe.
for (InterleaveGroup<Instruction> *IG : IAI.getInterleaveGroups()) {
- auto applyIG = [IG, this](ElementCount VF) -> bool {
- return (VF.isVector() && // Query is illegal for VF == 1
+ auto applyIG = [IG, this](ElementCount VF) -> bool {
+ return (VF.isVector() && // Query is illegal for VF == 1
CM.getWideningDecision(IG->getInsertPos(), VF) ==
LoopVectorizationCostModel::CM_Interleave);
};
@@ -8715,11 +8715,11 @@ VPlanPtr LoopVectorizationPlanner::buildVPlanWithVPRecipes(
if (auto Recipe =
RecipeBuilder.tryToCreateWidenRecipe(Instr, Range, Plan)) {
- for (auto *Def : Recipe->definedValues()) {
- auto *UV = Def->getUnderlyingValue();
- Plan->addVPValue(UV, Def);
- }
-
+ for (auto *Def : Recipe->definedValues()) {
+ auto *UV = Def->getUnderlyingValue();
+ Plan->addVPValue(UV, Def);
+ }
+
RecipeBuilder.setRecipe(Instr, Recipe);
VPBB->appendRecipe(Recipe);
continue;
@@ -8755,18 +8755,18 @@ VPlanPtr LoopVectorizationPlanner::buildVPlanWithVPRecipes(
for (auto &Entry : SinkAfter) {
VPRecipeBase *Sink = RecipeBuilder.getRecipe(Entry.first);
VPRecipeBase *Target = RecipeBuilder.getRecipe(Entry.second);
- // If the target is in a replication region, make sure to move Sink to the
- // block after it, not into the replication region itself.
- if (auto *Region =
- dyn_cast_or_null<VPRegionBlock>(Target->getParent()->getParent())) {
- if (Region->isReplicator()) {
- assert(Region->getNumSuccessors() == 1 && "Expected SESE region!");
- VPBasicBlock *NextBlock =
- cast<VPBasicBlock>(Region->getSuccessors().front());
- Sink->moveBefore(*NextBlock, NextBlock->getFirstNonPhi());
- continue;
- }
- }
+ // If the target is in a replication region, make sure to move Sink to the
+ // block after it, not into the replication region itself.
+ if (auto *Region =
+ dyn_cast_or_null<VPRegionBlock>(Target->getParent()->getParent())) {
+ if (Region->isReplicator()) {
+ assert(Region->getNumSuccessors() == 1 && "Expected SESE region!");
+ VPBasicBlock *NextBlock =
+ cast<VPBasicBlock>(Region->getSuccessors().front());
+ Sink->moveBefore(*NextBlock, NextBlock->getFirstNonPhi());
+ continue;
+ }
+ }
Sink->moveAfter(Target);
}
@@ -8776,52 +8776,52 @@ VPlanPtr LoopVectorizationPlanner::buildVPlanWithVPRecipes(
for (auto IG : InterleaveGroups) {
auto *Recipe = cast<VPWidenMemoryInstructionRecipe>(
RecipeBuilder.getRecipe(IG->getInsertPos()));
- SmallVector<VPValue *, 4> StoredValues;
- for (unsigned i = 0; i < IG->getFactor(); ++i)
- if (auto *SI = dyn_cast_or_null<StoreInst>(IG->getMember(i)))
- StoredValues.push_back(Plan->getOrAddVPValue(SI->getOperand(0)));
-
- auto *VPIG = new VPInterleaveRecipe(IG, Recipe->getAddr(), StoredValues,
- Recipe->getMask());
- VPIG->insertBefore(Recipe);
- unsigned J = 0;
+ SmallVector<VPValue *, 4> StoredValues;
+ for (unsigned i = 0; i < IG->getFactor(); ++i)
+ if (auto *SI = dyn_cast_or_null<StoreInst>(IG->getMember(i)))
+ StoredValues.push_back(Plan->getOrAddVPValue(SI->getOperand(0)));
+
+ auto *VPIG = new VPInterleaveRecipe(IG, Recipe->getAddr(), StoredValues,
+ Recipe->getMask());
+ VPIG->insertBefore(Recipe);
+ unsigned J = 0;
for (unsigned i = 0; i < IG->getFactor(); ++i)
if (Instruction *Member = IG->getMember(i)) {
- if (!Member->getType()->isVoidTy()) {
- VPValue *OriginalV = Plan->getVPValue(Member);
- Plan->removeVPValueFor(Member);
- Plan->addVPValue(Member, VPIG->getVPValue(J));
- OriginalV->replaceAllUsesWith(VPIG->getVPValue(J));
- J++;
- }
+ if (!Member->getType()->isVoidTy()) {
+ VPValue *OriginalV = Plan->getVPValue(Member);
+ Plan->removeVPValueFor(Member);
+ Plan->addVPValue(Member, VPIG->getVPValue(J));
+ OriginalV->replaceAllUsesWith(VPIG->getVPValue(J));
+ J++;
+ }
RecipeBuilder.getRecipe(Member)->eraseFromParent();
}
}
- // Adjust the recipes for any inloop reductions.
- if (Range.Start.isVector())
- adjustRecipesForInLoopReductions(Plan, RecipeBuilder);
-
+ // Adjust the recipes for any inloop reductions.
+ if (Range.Start.isVector())
+ adjustRecipesForInLoopReductions(Plan, RecipeBuilder);
+
// Finally, if tail is folded by masking, introduce selects between the phi
// and the live-out instruction of each reduction, at the end of the latch.
- if (CM.foldTailByMasking() && !Legal->getReductionVars().empty()) {
+ if (CM.foldTailByMasking() && !Legal->getReductionVars().empty()) {
Builder.setInsertPoint(VPBB);
auto *Cond = RecipeBuilder.createBlockInMask(OrigLoop->getHeader(), Plan);
for (auto &Reduction : Legal->getReductionVars()) {
- if (CM.isInLoopReduction(Reduction.first))
- continue;
- VPValue *Phi = Plan->getOrAddVPValue(Reduction.first);
- VPValue *Red = Plan->getOrAddVPValue(Reduction.second.getLoopExitInstr());
+ if (CM.isInLoopReduction(Reduction.first))
+ continue;
+ VPValue *Phi = Plan->getOrAddVPValue(Reduction.first);
+ VPValue *Red = Plan->getOrAddVPValue(Reduction.second.getLoopExitInstr());
Builder.createNaryOp(Instruction::Select, {Cond, Red, Phi});
}
}
std::string PlanName;
raw_string_ostream RSO(PlanName);
- ElementCount VF = Range.Start;
+ ElementCount VF = Range.Start;
Plan->addVF(VF);
RSO << "Initial VPlan for VF={" << VF;
- for (VF *= 2; ElementCount::isKnownLT(VF, Range.End); VF *= 2) {
+ for (VF *= 2; ElementCount::isKnownLT(VF, Range.End); VF *= 2) {
Plan->addVF(VF);
RSO << "," << VF;
}
@@ -8837,7 +8837,7 @@ VPlanPtr LoopVectorizationPlanner::buildVPlan(VFRange &Range) {
// transformations before even evaluating whether vectorization is profitable.
// Since we cannot modify the incoming IR, we need to build VPlan upfront in
// the vectorization pipeline.
- assert(!OrigLoop->isInnermost());
+ assert(!OrigLoop->isInnermost());
assert(EnableVPlanNativePath && "VPlan-native path is not enabled.");
// Create new empty VPlan
@@ -8847,8 +8847,8 @@ VPlanPtr LoopVectorizationPlanner::buildVPlan(VFRange &Range) {
VPlanHCFGBuilder HCFGBuilder(OrigLoop, LI, *Plan);
HCFGBuilder.buildHierarchicalCFG();
- for (ElementCount VF = Range.Start; ElementCount::isKnownLT(VF, Range.End);
- VF *= 2)
+ for (ElementCount VF = Range.Start; ElementCount::isKnownLT(VF, Range.End);
+ VF *= 2)
Plan->addVF(VF);
if (EnableVPlanPredication) {
@@ -8866,67 +8866,67 @@ VPlanPtr LoopVectorizationPlanner::buildVPlan(VFRange &Range) {
return Plan;
}
-// Adjust the recipes for any inloop reductions. The chain of instructions
-// leading from the loop exit instr to the phi need to be converted to
-// reductions, with one operand being vector and the other being the scalar
-// reduction chain.
-void LoopVectorizationPlanner::adjustRecipesForInLoopReductions(
- VPlanPtr &Plan, VPRecipeBuilder &RecipeBuilder) {
- for (auto &Reduction : CM.getInLoopReductionChains()) {
- PHINode *Phi = Reduction.first;
- RecurrenceDescriptor &RdxDesc = Legal->getReductionVars()[Phi];
- const SmallVector<Instruction *, 4> &ReductionOperations = Reduction.second;
-
- // ReductionOperations are orders top-down from the phi's use to the
- // LoopExitValue. We keep a track of the previous item (the Chain) to tell
- // which of the two operands will remain scalar and which will be reduced.
- // For minmax the chain will be the select instructions.
- Instruction *Chain = Phi;
- for (Instruction *R : ReductionOperations) {
- VPRecipeBase *WidenRecipe = RecipeBuilder.getRecipe(R);
- RecurKind Kind = RdxDesc.getRecurrenceKind();
-
- VPValue *ChainOp = Plan->getVPValue(Chain);
- unsigned FirstOpId;
- if (RecurrenceDescriptor::isMinMaxRecurrenceKind(Kind)) {
- assert(isa<VPWidenSelectRecipe>(WidenRecipe) &&
- "Expected to replace a VPWidenSelectSC");
- FirstOpId = 1;
- } else {
- assert(isa<VPWidenRecipe>(WidenRecipe) &&
- "Expected to replace a VPWidenSC");
- FirstOpId = 0;
- }
- unsigned VecOpId =
- R->getOperand(FirstOpId) == Chain ? FirstOpId + 1 : FirstOpId;
- VPValue *VecOp = Plan->getVPValue(R->getOperand(VecOpId));
-
- auto *CondOp = CM.foldTailByMasking()
- ? RecipeBuilder.createBlockInMask(R->getParent(), Plan)
- : nullptr;
- VPReductionRecipe *RedRecipe = new VPReductionRecipe(
- &RdxDesc, R, ChainOp, VecOp, CondOp, Legal->hasFunNoNaNAttr(), TTI);
- WidenRecipe->getVPValue()->replaceAllUsesWith(RedRecipe);
- Plan->removeVPValueFor(R);
- Plan->addVPValue(R, RedRecipe);
- WidenRecipe->getParent()->insert(RedRecipe, WidenRecipe->getIterator());
- WidenRecipe->getVPValue()->replaceAllUsesWith(RedRecipe);
- WidenRecipe->eraseFromParent();
-
- if (RecurrenceDescriptor::isMinMaxRecurrenceKind(Kind)) {
- VPRecipeBase *CompareRecipe =
- RecipeBuilder.getRecipe(cast<Instruction>(R->getOperand(0)));
- assert(isa<VPWidenRecipe>(CompareRecipe) &&
- "Expected to replace a VPWidenSC");
- assert(cast<VPWidenRecipe>(CompareRecipe)->getNumUsers() == 0 &&
- "Expected no remaining users");
- CompareRecipe->eraseFromParent();
- }
- Chain = R;
- }
- }
-}
-
+// Adjust the recipes for any inloop reductions. The chain of instructions
+// leading from the loop exit instr to the phi need to be converted to
+// reductions, with one operand being vector and the other being the scalar
+// reduction chain.
+void LoopVectorizationPlanner::adjustRecipesForInLoopReductions(
+ VPlanPtr &Plan, VPRecipeBuilder &RecipeBuilder) {
+ for (auto &Reduction : CM.getInLoopReductionChains()) {
+ PHINode *Phi = Reduction.first;
+ RecurrenceDescriptor &RdxDesc = Legal->getReductionVars()[Phi];
+ const SmallVector<Instruction *, 4> &ReductionOperations = Reduction.second;
+
+ // ReductionOperations are orders top-down from the phi's use to the
+ // LoopExitValue. We keep a track of the previous item (the Chain) to tell
+ // which of the two operands will remain scalar and which will be reduced.
+ // For minmax the chain will be the select instructions.
+ Instruction *Chain = Phi;
+ for (Instruction *R : ReductionOperations) {
+ VPRecipeBase *WidenRecipe = RecipeBuilder.getRecipe(R);
+ RecurKind Kind = RdxDesc.getRecurrenceKind();
+
+ VPValue *ChainOp = Plan->getVPValue(Chain);
+ unsigned FirstOpId;
+ if (RecurrenceDescriptor::isMinMaxRecurrenceKind(Kind)) {
+ assert(isa<VPWidenSelectRecipe>(WidenRecipe) &&
+ "Expected to replace a VPWidenSelectSC");
+ FirstOpId = 1;
+ } else {
+ assert(isa<VPWidenRecipe>(WidenRecipe) &&
+ "Expected to replace a VPWidenSC");
+ FirstOpId = 0;
+ }
+ unsigned VecOpId =
+ R->getOperand(FirstOpId) == Chain ? FirstOpId + 1 : FirstOpId;
+ VPValue *VecOp = Plan->getVPValue(R->getOperand(VecOpId));
+
+ auto *CondOp = CM.foldTailByMasking()
+ ? RecipeBuilder.createBlockInMask(R->getParent(), Plan)
+ : nullptr;
+ VPReductionRecipe *RedRecipe = new VPReductionRecipe(
+ &RdxDesc, R, ChainOp, VecOp, CondOp, Legal->hasFunNoNaNAttr(), TTI);
+ WidenRecipe->getVPValue()->replaceAllUsesWith(RedRecipe);
+ Plan->removeVPValueFor(R);
+ Plan->addVPValue(R, RedRecipe);
+ WidenRecipe->getParent()->insert(RedRecipe, WidenRecipe->getIterator());
+ WidenRecipe->getVPValue()->replaceAllUsesWith(RedRecipe);
+ WidenRecipe->eraseFromParent();
+
+ if (RecurrenceDescriptor::isMinMaxRecurrenceKind(Kind)) {
+ VPRecipeBase *CompareRecipe =
+ RecipeBuilder.getRecipe(cast<Instruction>(R->getOperand(0)));
+ assert(isa<VPWidenRecipe>(CompareRecipe) &&
+ "Expected to replace a VPWidenSC");
+ assert(cast<VPWidenRecipe>(CompareRecipe)->getNumUsers() == 0 &&
+ "Expected no remaining users");
+ CompareRecipe->eraseFromParent();
+ }
+ Chain = R;
+ }
+ }
+}
+
Value* LoopVectorizationPlanner::VPCallbackILV::
getOrCreateVectorValues(Value *V, unsigned Part) {
return ILV.getOrCreateVectorValue(V, Part);
@@ -8954,35 +8954,35 @@ void VPInterleaveRecipe::print(raw_ostream &O, const Twine &Indent,
}
void VPWidenCallRecipe::execute(VPTransformState &State) {
- State.ILV->widenCallInstruction(*cast<CallInst>(getUnderlyingInstr()), this,
- *this, State);
+ State.ILV->widenCallInstruction(*cast<CallInst>(getUnderlyingInstr()), this,
+ *this, State);
}
void VPWidenSelectRecipe::execute(VPTransformState &State) {
- State.ILV->widenSelectInstruction(*cast<SelectInst>(getUnderlyingInstr()),
- this, *this, InvariantCond, State);
+ State.ILV->widenSelectInstruction(*cast<SelectInst>(getUnderlyingInstr()),
+ this, *this, InvariantCond, State);
}
void VPWidenRecipe::execute(VPTransformState &State) {
- State.ILV->widenInstruction(*getUnderlyingInstr(), this, *this, State);
+ State.ILV->widenInstruction(*getUnderlyingInstr(), this, *this, State);
}
void VPWidenGEPRecipe::execute(VPTransformState &State) {
- State.ILV->widenGEP(cast<GetElementPtrInst>(getUnderlyingInstr()), this,
- *this, State.UF, State.VF, IsPtrLoopInvariant,
+ State.ILV->widenGEP(cast<GetElementPtrInst>(getUnderlyingInstr()), this,
+ *this, State.UF, State.VF, IsPtrLoopInvariant,
IsIndexLoopInvariant, State);
}
void VPWidenIntOrFpInductionRecipe::execute(VPTransformState &State) {
assert(!State.Instance && "Int or FP induction being replicated.");
- State.ILV->widenIntOrFpInduction(IV, getStartValue()->getLiveInIRValue(),
- Trunc);
+ State.ILV->widenIntOrFpInduction(IV, getStartValue()->getLiveInIRValue(),
+ Trunc);
}
void VPWidenPHIRecipe::execute(VPTransformState &State) {
- Value *StartV =
- getStartValue() ? getStartValue()->getLiveInIRValue() : nullptr;
- State.ILV->widenPHIInstruction(Phi, RdxDesc, StartV, State.UF, State.VF);
+ Value *StartV =
+ getStartValue() ? getStartValue()->getLiveInIRValue() : nullptr;
+ State.ILV->widenPHIInstruction(Phi, RdxDesc, StartV, State.UF, State.VF);
}
void VPBlendRecipe::execute(VPTransformState &State) {
@@ -9026,59 +9026,59 @@ void VPBlendRecipe::execute(VPTransformState &State) {
void VPInterleaveRecipe::execute(VPTransformState &State) {
assert(!State.Instance && "Interleave group being replicated.");
- State.ILV->vectorizeInterleaveGroup(IG, definedValues(), State, getAddr(),
- getStoredValues(), getMask());
-}
-
-void VPReductionRecipe::execute(VPTransformState &State) {
- assert(!State.Instance && "Reduction being replicated.");
- for (unsigned Part = 0; Part < State.UF; ++Part) {
- RecurKind Kind = RdxDesc->getRecurrenceKind();
- Value *NewVecOp = State.get(getVecOp(), Part);
- if (VPValue *Cond = getCondOp()) {
- Value *NewCond = State.get(Cond, Part);
- VectorType *VecTy = cast<VectorType>(NewVecOp->getType());
- Constant *Iden = RecurrenceDescriptor::getRecurrenceIdentity(
- Kind, VecTy->getElementType());
- Constant *IdenVec =
- ConstantVector::getSplat(VecTy->getElementCount(), Iden);
- Value *Select = State.Builder.CreateSelect(NewCond, NewVecOp, IdenVec);
- NewVecOp = Select;
- }
- Value *NewRed =
- createTargetReduction(State.Builder, TTI, *RdxDesc, NewVecOp);
- Value *PrevInChain = State.get(getChainOp(), Part);
- Value *NextInChain;
- if (RecurrenceDescriptor::isMinMaxRecurrenceKind(Kind)) {
- NextInChain =
- createMinMaxOp(State.Builder, RdxDesc->getRecurrenceKind(),
- NewRed, PrevInChain);
- } else {
- NextInChain = State.Builder.CreateBinOp(
- (Instruction::BinaryOps)getUnderlyingInstr()->getOpcode(), NewRed,
- PrevInChain);
- }
- State.set(this, getUnderlyingInstr(), NextInChain, Part);
- }
-}
-
+ State.ILV->vectorizeInterleaveGroup(IG, definedValues(), State, getAddr(),
+ getStoredValues(), getMask());
+}
+
+void VPReductionRecipe::execute(VPTransformState &State) {
+ assert(!State.Instance && "Reduction being replicated.");
+ for (unsigned Part = 0; Part < State.UF; ++Part) {
+ RecurKind Kind = RdxDesc->getRecurrenceKind();
+ Value *NewVecOp = State.get(getVecOp(), Part);
+ if (VPValue *Cond = getCondOp()) {
+ Value *NewCond = State.get(Cond, Part);
+ VectorType *VecTy = cast<VectorType>(NewVecOp->getType());
+ Constant *Iden = RecurrenceDescriptor::getRecurrenceIdentity(
+ Kind, VecTy->getElementType());
+ Constant *IdenVec =
+ ConstantVector::getSplat(VecTy->getElementCount(), Iden);
+ Value *Select = State.Builder.CreateSelect(NewCond, NewVecOp, IdenVec);
+ NewVecOp = Select;
+ }
+ Value *NewRed =
+ createTargetReduction(State.Builder, TTI, *RdxDesc, NewVecOp);
+ Value *PrevInChain = State.get(getChainOp(), Part);
+ Value *NextInChain;
+ if (RecurrenceDescriptor::isMinMaxRecurrenceKind(Kind)) {
+ NextInChain =
+ createMinMaxOp(State.Builder, RdxDesc->getRecurrenceKind(),
+ NewRed, PrevInChain);
+ } else {
+ NextInChain = State.Builder.CreateBinOp(
+ (Instruction::BinaryOps)getUnderlyingInstr()->getOpcode(), NewRed,
+ PrevInChain);
+ }
+ State.set(this, getUnderlyingInstr(), NextInChain, Part);
+ }
+}
+
void VPReplicateRecipe::execute(VPTransformState &State) {
if (State.Instance) { // Generate a single instance.
- assert(!State.VF.isScalable() && "Can't scalarize a scalable vector");
- State.ILV->scalarizeInstruction(getUnderlyingInstr(), *this,
- *State.Instance, IsPredicated, State);
+ assert(!State.VF.isScalable() && "Can't scalarize a scalable vector");
+ State.ILV->scalarizeInstruction(getUnderlyingInstr(), *this,
+ *State.Instance, IsPredicated, State);
// Insert scalar instance packing it into a vector.
- if (AlsoPack && State.VF.isVector()) {
- // If we're constructing lane 0, initialize to start from poison.
+ if (AlsoPack && State.VF.isVector()) {
+ // If we're constructing lane 0, initialize to start from poison.
if (State.Instance->Lane == 0) {
- assert(!State.VF.isScalable() && "VF is assumed to be non scalable.");
- Value *Poison = PoisonValue::get(
- VectorType::get(getUnderlyingValue()->getType(), State.VF));
- State.ValueMap.setVectorValue(getUnderlyingInstr(),
- State.Instance->Part, Poison);
+ assert(!State.VF.isScalable() && "VF is assumed to be non scalable.");
+ Value *Poison = PoisonValue::get(
+ VectorType::get(getUnderlyingValue()->getType(), State.VF));
+ State.ValueMap.setVectorValue(getUnderlyingInstr(),
+ State.Instance->Part, Poison);
}
- State.ILV->packScalarIntoVectorValue(getUnderlyingInstr(),
- *State.Instance);
+ State.ILV->packScalarIntoVectorValue(getUnderlyingInstr(),
+ *State.Instance);
}
return;
}
@@ -9086,12 +9086,12 @@ void VPReplicateRecipe::execute(VPTransformState &State) {
// Generate scalar instances for all VF lanes of all UF parts, unless the
// instruction is uniform inwhich case generate only the first lane for each
// of the UF parts.
- unsigned EndLane = IsUniform ? 1 : State.VF.getKnownMinValue();
- assert((!State.VF.isScalable() || IsUniform) &&
- "Can't scalarize a scalable vector");
+ unsigned EndLane = IsUniform ? 1 : State.VF.getKnownMinValue();
+ assert((!State.VF.isScalable() || IsUniform) &&
+ "Can't scalarize a scalable vector");
for (unsigned Part = 0; Part < State.UF; ++Part)
for (unsigned Lane = 0; Lane < EndLane; ++Lane)
- State.ILV->scalarizeInstruction(getUnderlyingInstr(), *this, {Part, Lane},
+ State.ILV->scalarizeInstruction(getUnderlyingInstr(), *this, {Part, Lane},
IsPredicated, State);
}
@@ -9123,8 +9123,8 @@ void VPBranchOnMaskRecipe::execute(VPTransformState &State) {
void VPPredInstPHIRecipe::execute(VPTransformState &State) {
assert(State.Instance && "Predicated instruction PHI works per instance.");
- Instruction *ScalarPredInst =
- cast<Instruction>(State.get(getOperand(0), *State.Instance));
+ Instruction *ScalarPredInst =
+ cast<Instruction>(State.get(getOperand(0), *State.Instance));
BasicBlock *PredicatedBB = ScalarPredInst->getParent();
BasicBlock *PredicatingBB = PredicatedBB->getSinglePredecessor();
assert(PredicatingBB && "Predicated block has no single predecessor.");
@@ -9136,8 +9136,8 @@ void VPPredInstPHIRecipe::execute(VPTransformState &State) {
// also do that packing, thereby "hoisting" the insert-element sequence.
// Otherwise, a phi node for the scalar value is needed.
unsigned Part = State.Instance->Part;
- Instruction *PredInst =
- cast<Instruction>(getOperand(0)->getUnderlyingValue());
+ Instruction *PredInst =
+ cast<Instruction>(getOperand(0)->getUnderlyingValue());
if (State.ValueMap.hasVectorValue(PredInst, Part)) {
Value *VectorValue = State.ValueMap.getVectorValue(PredInst, Part);
InsertElementInst *IEI = cast<InsertElementInst>(VectorValue);
@@ -9148,17 +9148,17 @@ void VPPredInstPHIRecipe::execute(VPTransformState &State) {
} else {
Type *PredInstType = PredInst->getType();
PHINode *Phi = State.Builder.CreatePHI(PredInstType, 2);
- Phi->addIncoming(PoisonValue::get(ScalarPredInst->getType()), PredicatingBB);
+ Phi->addIncoming(PoisonValue::get(ScalarPredInst->getType()), PredicatingBB);
Phi->addIncoming(ScalarPredInst, PredicatedBB);
State.ValueMap.resetScalarValue(PredInst, *State.Instance, Phi);
}
}
void VPWidenMemoryInstructionRecipe::execute(VPTransformState &State) {
- VPValue *StoredValue = isStore() ? getStoredValue() : nullptr;
- State.ILV->vectorizeMemoryInstruction(&Ingredient, State,
- StoredValue ? nullptr : getVPValue(),
- getAddr(), StoredValue, getMask());
+ VPValue *StoredValue = isStore() ? getStoredValue() : nullptr;
+ State.ILV->vectorizeMemoryInstruction(&Ingredient, State,
+ StoredValue ? nullptr : getVPValue(),
+ getAddr(), StoredValue, getMask());
}
// Determine how to lower the scalar epilogue, which depends on 1) optimising
@@ -9172,51 +9172,51 @@ static ScalarEpilogueLowering getScalarEpilogueLowering(
LoopVectorizationLegality &LVL) {
// 1) OptSize takes precedence over all other options, i.e. if this is set,
// don't look at hints or options, and don't request a scalar epilogue.
- // (For PGSO, as shouldOptimizeForSize isn't currently accessible from
- // LoopAccessInfo (due to code dependency and not being able to reliably get
- // PSI/BFI from a loop analysis under NPM), we cannot suppress the collection
- // of strides in LoopAccessInfo::analyzeLoop() and vectorize without
- // versioning when the vectorization is forced, unlike hasOptSize. So revert
- // back to the old way and vectorize with versioning when forced. See D81345.)
- if (F->hasOptSize() || (llvm::shouldOptimizeForSize(L->getHeader(), PSI, BFI,
- PGSOQueryType::IRPass) &&
- Hints.getForce() != LoopVectorizeHints::FK_Enabled))
+ // (For PGSO, as shouldOptimizeForSize isn't currently accessible from
+ // LoopAccessInfo (due to code dependency and not being able to reliably get
+ // PSI/BFI from a loop analysis under NPM), we cannot suppress the collection
+ // of strides in LoopAccessInfo::analyzeLoop() and vectorize without
+ // versioning when the vectorization is forced, unlike hasOptSize. So revert
+ // back to the old way and vectorize with versioning when forced. See D81345.)
+ if (F->hasOptSize() || (llvm::shouldOptimizeForSize(L->getHeader(), PSI, BFI,
+ PGSOQueryType::IRPass) &&
+ Hints.getForce() != LoopVectorizeHints::FK_Enabled))
return CM_ScalarEpilogueNotAllowedOptSize;
- // 2) If set, obey the directives
- if (PreferPredicateOverEpilogue.getNumOccurrences()) {
- switch (PreferPredicateOverEpilogue) {
- case PreferPredicateTy::ScalarEpilogue:
- return CM_ScalarEpilogueAllowed;
- case PreferPredicateTy::PredicateElseScalarEpilogue:
- return CM_ScalarEpilogueNotNeededUsePredicate;
- case PreferPredicateTy::PredicateOrDontVectorize:
- return CM_ScalarEpilogueNotAllowedUsePredicate;
- };
- }
-
- // 3) If set, obey the hints
- switch (Hints.getPredicate()) {
- case LoopVectorizeHints::FK_Enabled:
- return CM_ScalarEpilogueNotNeededUsePredicate;
- case LoopVectorizeHints::FK_Disabled:
+ // 2) If set, obey the directives
+ if (PreferPredicateOverEpilogue.getNumOccurrences()) {
+ switch (PreferPredicateOverEpilogue) {
+ case PreferPredicateTy::ScalarEpilogue:
+ return CM_ScalarEpilogueAllowed;
+ case PreferPredicateTy::PredicateElseScalarEpilogue:
+ return CM_ScalarEpilogueNotNeededUsePredicate;
+ case PreferPredicateTy::PredicateOrDontVectorize:
+ return CM_ScalarEpilogueNotAllowedUsePredicate;
+ };
+ }
+
+ // 3) If set, obey the hints
+ switch (Hints.getPredicate()) {
+ case LoopVectorizeHints::FK_Enabled:
+ return CM_ScalarEpilogueNotNeededUsePredicate;
+ case LoopVectorizeHints::FK_Disabled:
return CM_ScalarEpilogueAllowed;
- };
+ };
- // 4) if the TTI hook indicates this is profitable, request predication.
- if (TTI->preferPredicateOverEpilogue(L, LI, *SE, *AC, TLI, DT,
- LVL.getLAI()))
+ // 4) if the TTI hook indicates this is profitable, request predication.
+ if (TTI->preferPredicateOverEpilogue(L, LI, *SE, *AC, TLI, DT,
+ LVL.getLAI()))
return CM_ScalarEpilogueNotNeededUsePredicate;
return CM_ScalarEpilogueAllowed;
}
-void VPTransformState::set(VPValue *Def, Value *IRDef, Value *V,
- unsigned Part) {
- set(Def, V, Part);
- ILV->setVectorValue(IRDef, Part, V);
-}
-
+void VPTransformState::set(VPValue *Def, Value *IRDef, Value *V,
+ unsigned Part) {
+ set(Def, V, Part);
+ ILV->setVectorValue(IRDef, Part, V);
+}
+
// Process the loop in the VPlan-native vectorization path. This path builds
// VPlan upfront in the vectorization pipeline, which allows to apply
// VPlan-to-VPlan transformations from the very beginning without modifying the
@@ -9228,7 +9228,7 @@ static bool processLoopInVPlanNativePath(
OptimizationRemarkEmitter *ORE, BlockFrequencyInfo *BFI,
ProfileSummaryInfo *PSI, LoopVectorizeHints &Hints) {
- if (isa<SCEVCouldNotCompute>(PSE.getBackedgeTakenCount())) {
+ if (isa<SCEVCouldNotCompute>(PSE.getBackedgeTakenCount())) {
LLVM_DEBUG(dbgs() << "LV: cannot compute the outer-loop trip count\n");
return false;
}
@@ -9247,7 +9247,7 @@ static bool processLoopInVPlanNativePath(
LoopVectorizationPlanner LVP(L, LI, TLI, TTI, LVL, CM, IAI, PSE);
// Get user vectorization factor.
- ElementCount UserVF = Hints.getWidth();
+ ElementCount UserVF = Hints.getWidth();
// Plan how to best vectorize, return the best VF and its cost.
const VectorizationFactor VF = LVP.planInVPlanNativePath(UserVF);
@@ -9262,7 +9262,7 @@ static bool processLoopInVPlanNativePath(
LVP.setBestPlan(VF.Width, 1);
InnerLoopVectorizer LB(L, PSE, LI, DT, TLI, TTI, AC, ORE, VF.Width, 1, LVL,
- &CM, BFI, PSI);
+ &CM, BFI, PSI);
LLVM_DEBUG(dbgs() << "Vectorizing outer loop in \""
<< L->getHeader()->getParent()->getName() << "\"\n");
LVP.executePlan(LB, DT);
@@ -9281,7 +9281,7 @@ LoopVectorizePass::LoopVectorizePass(LoopVectorizeOptions Opts)
!EnableLoopVectorization) {}
bool LoopVectorizePass::processLoop(Loop *L) {
- assert((EnableVPlanNativePath || L->isInnermost()) &&
+ assert((EnableVPlanNativePath || L->isInnermost()) &&
"VPlan-native path is not enabled. Only process inner loops.");
#ifndef NDEBUG
@@ -9326,7 +9326,7 @@ bool LoopVectorizePass::processLoop(Loop *L) {
// Check if it is legal to vectorize the loop.
LoopVectorizationRequirements Requirements(*ORE);
LoopVectorizationLegality LVL(L, PSE, DT, TTI, TLI, AA, F, GetLAA, LI, ORE,
- &Requirements, &Hints, DB, AC, BFI, PSI);
+ &Requirements, &Hints, DB, AC, BFI, PSI);
if (!LVL.canVectorize(EnableVPlanNativePath)) {
LLVM_DEBUG(dbgs() << "LV: Not vectorizing: Cannot prove legality.\n");
Hints.emitRemarkWithHints();
@@ -9343,11 +9343,11 @@ bool LoopVectorizePass::processLoop(Loop *L) {
// even evaluating whether vectorization is profitable. Since we cannot modify
// the incoming IR, we need to build VPlan upfront in the vectorization
// pipeline.
- if (!L->isInnermost())
+ if (!L->isInnermost())
return processLoopInVPlanNativePath(L, PSE, LI, DT, &LVL, TTI, TLI, DB, AC,
ORE, BFI, PSI, Hints);
- assert(L->isInnermost() && "Inner loop expected.");
+ assert(L->isInnermost() && "Inner loop expected.");
// Check the loop for a trip count threshold: vectorize loops with a tiny trip
// count by optimizing for size, to minimize overheads.
@@ -9412,7 +9412,7 @@ bool LoopVectorizePass::processLoop(Loop *L) {
LoopVectorizationPlanner LVP(L, LI, TLI, TTI, &LVL, CM, IAI, PSE);
// Get user vectorization factor and interleave count.
- ElementCount UserVF = Hints.getWidth();
+ ElementCount UserVF = Hints.getWidth();
unsigned UserIC = Hints.getInterleave();
// Plan how to best vectorize, return the best VF and its cost.
@@ -9437,7 +9437,7 @@ bool LoopVectorizePass::processLoop(Loop *L) {
return false;
}
- if (VF.Width.isScalar()) {
+ if (VF.Width.isScalar()) {
LLVM_DEBUG(dbgs() << "LV: Vectorization is possible but not beneficial.\n");
VecDiagMsg = std::make_pair(
"VectorizationNotBeneficial",
@@ -9526,8 +9526,8 @@ bool LoopVectorizePass::processLoop(Loop *L) {
assert(IC > 1 && "interleave count should not be 1 or 0");
// If we decided that it is not legal to vectorize the loop, then
// interleave it.
- InnerLoopUnroller Unroller(L, PSE, LI, DT, TLI, TTI, AC, ORE, IC, &LVL, &CM,
- BFI, PSI);
+ InnerLoopUnroller Unroller(L, PSE, LI, DT, TLI, TTI, AC, ORE, IC, &LVL, &CM,
+ BFI, PSI);
LVP.executePlan(Unroller, DT);
ORE->emit([&]() {
@@ -9539,51 +9539,51 @@ bool LoopVectorizePass::processLoop(Loop *L) {
} else {
// If we decided that it is *legal* to vectorize the loop, then do it.
- // Consider vectorizing the epilogue too if it's profitable.
- VectorizationFactor EpilogueVF =
- CM.selectEpilogueVectorizationFactor(VF.Width, LVP);
- if (EpilogueVF.Width.isVector()) {
-
- // The first pass vectorizes the main loop and creates a scalar epilogue
- // to be vectorized by executing the plan (potentially with a different
- // factor) again shortly afterwards.
- EpilogueLoopVectorizationInfo EPI(VF.Width.getKnownMinValue(), IC,
- EpilogueVF.Width.getKnownMinValue(), 1);
- EpilogueVectorizerMainLoop MainILV(L, PSE, LI, DT, TLI, TTI, AC, ORE, EPI,
- &LVL, &CM, BFI, PSI);
-
- LVP.setBestPlan(EPI.MainLoopVF, EPI.MainLoopUF);
- LVP.executePlan(MainILV, DT);
- ++LoopsVectorized;
-
- simplifyLoop(L, DT, LI, SE, AC, nullptr, false /* PreserveLCSSA */);
- formLCSSARecursively(*L, *DT, LI, SE);
-
- // Second pass vectorizes the epilogue and adjusts the control flow
- // edges from the first pass.
- LVP.setBestPlan(EPI.EpilogueVF, EPI.EpilogueUF);
- EPI.MainLoopVF = EPI.EpilogueVF;
- EPI.MainLoopUF = EPI.EpilogueUF;
- EpilogueVectorizerEpilogueLoop EpilogILV(L, PSE, LI, DT, TLI, TTI, AC,
- ORE, EPI, &LVL, &CM, BFI, PSI);
- LVP.executePlan(EpilogILV, DT);
- ++LoopsEpilogueVectorized;
-
- if (!MainILV.areSafetyChecksAdded())
- DisableRuntimeUnroll = true;
- } else {
- InnerLoopVectorizer LB(L, PSE, LI, DT, TLI, TTI, AC, ORE, VF.Width, IC,
- &LVL, &CM, BFI, PSI);
- LVP.executePlan(LB, DT);
- ++LoopsVectorized;
-
- // Add metadata to disable runtime unrolling a scalar loop when there are
- // no runtime checks about strides and memory. A scalar loop that is
- // rarely used is not worth unrolling.
- if (!LB.areSafetyChecksAdded())
- DisableRuntimeUnroll = true;
- }
-
+ // Consider vectorizing the epilogue too if it's profitable.
+ VectorizationFactor EpilogueVF =
+ CM.selectEpilogueVectorizationFactor(VF.Width, LVP);
+ if (EpilogueVF.Width.isVector()) {
+
+ // The first pass vectorizes the main loop and creates a scalar epilogue
+ // to be vectorized by executing the plan (potentially with a different
+ // factor) again shortly afterwards.
+ EpilogueLoopVectorizationInfo EPI(VF.Width.getKnownMinValue(), IC,
+ EpilogueVF.Width.getKnownMinValue(), 1);
+ EpilogueVectorizerMainLoop MainILV(L, PSE, LI, DT, TLI, TTI, AC, ORE, EPI,
+ &LVL, &CM, BFI, PSI);
+
+ LVP.setBestPlan(EPI.MainLoopVF, EPI.MainLoopUF);
+ LVP.executePlan(MainILV, DT);
+ ++LoopsVectorized;
+
+ simplifyLoop(L, DT, LI, SE, AC, nullptr, false /* PreserveLCSSA */);
+ formLCSSARecursively(*L, *DT, LI, SE);
+
+ // Second pass vectorizes the epilogue and adjusts the control flow
+ // edges from the first pass.
+ LVP.setBestPlan(EPI.EpilogueVF, EPI.EpilogueUF);
+ EPI.MainLoopVF = EPI.EpilogueVF;
+ EPI.MainLoopUF = EPI.EpilogueUF;
+ EpilogueVectorizerEpilogueLoop EpilogILV(L, PSE, LI, DT, TLI, TTI, AC,
+ ORE, EPI, &LVL, &CM, BFI, PSI);
+ LVP.executePlan(EpilogILV, DT);
+ ++LoopsEpilogueVectorized;
+
+ if (!MainILV.areSafetyChecksAdded())
+ DisableRuntimeUnroll = true;
+ } else {
+ InnerLoopVectorizer LB(L, PSE, LI, DT, TLI, TTI, AC, ORE, VF.Width, IC,
+ &LVL, &CM, BFI, PSI);
+ LVP.executePlan(LB, DT);
+ ++LoopsVectorized;
+
+ // Add metadata to disable runtime unrolling a scalar loop when there are
+ // no runtime checks about strides and memory. A scalar loop that is
+ // rarely used is not worth unrolling.
+ if (!LB.areSafetyChecksAdded())
+ DisableRuntimeUnroll = true;
+ }
+
// Report the vectorization decision.
ORE->emit([&]() {
return OptimizationRemark(LV_NAME, "Vectorized", L->getStartLoc(),
@@ -9696,8 +9696,8 @@ PreservedAnalyses LoopVectorizePass::run(Function &F,
auto &LAM = AM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
std::function<const LoopAccessInfo &(Loop &)> GetLAA =
[&](Loop &L) -> const LoopAccessInfo & {
- LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE,
- TLI, TTI, nullptr, MSSA};
+ LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE,
+ TLI, TTI, nullptr, MSSA};
return LAM.getResult<LoopAccessAnalysis>(L, AR);
};
auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
diff --git a/contrib/libs/llvm12/lib/Transforms/Vectorize/SLPVectorizer.cpp b/contrib/libs/llvm12/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 7cc322d4b6..0b63019791 100644
--- a/contrib/libs/llvm12/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -26,16 +26,16 @@
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/CodeMetrics.h"
#include "llvm/Analysis/DemandedBits.h"
#include "llvm/Analysis/GlobalsModRef.h"
-#include "llvm/Analysis/IVDescriptors.h"
+#include "llvm/Analysis/IVDescriptors.h"
#include "llvm/Analysis/LoopAccessAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/MemoryLocation.h"
@@ -80,7 +80,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/GraphWriter.h"
-#include "llvm/Support/InstructionCost.h"
+#include "llvm/Support/InstructionCost.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
@@ -128,10 +128,10 @@ static cl::opt<int>
MaxVectorRegSizeOption("slp-max-reg-size", cl::init(128), cl::Hidden,
cl::desc("Attempt to vectorize for this register size in bits"));
-static cl::opt<unsigned>
-MaxVFOption("slp-max-vf", cl::init(0), cl::Hidden,
- cl::desc("Maximum SLP vectorization factor (0=unlimited)"));
-
+static cl::opt<unsigned>
+MaxVFOption("slp-max-vf", cl::init(0), cl::Hidden,
+ cl::desc("Maximum SLP vectorization factor (0=unlimited)"));
+
static cl::opt<int>
MaxStoreLookup("slp-max-store-lookup", cl::init(32), cl::Hidden,
cl::desc("Maximum depth of the lookup for consecutive stores."));
@@ -206,12 +206,12 @@ static bool allSameBlock(ArrayRef<Value *> VL) {
if (!I0)
return false;
BasicBlock *BB = I0->getParent();
- for (int I = 1, E = VL.size(); I < E; I++) {
- auto *II = dyn_cast<Instruction>(VL[I]);
- if (!II)
+ for (int I = 1, E = VL.size(); I < E; I++) {
+ auto *II = dyn_cast<Instruction>(VL[I]);
+ if (!II)
return false;
- if (BB != II->getParent())
+ if (BB != II->getParent())
return false;
}
return true;
@@ -236,16 +236,16 @@ static bool isSplat(ArrayRef<Value *> VL) {
return true;
}
-/// \returns True if \p I is commutative, handles CmpInst and BinaryOperator.
+/// \returns True if \p I is commutative, handles CmpInst and BinaryOperator.
static bool isCommutative(Instruction *I) {
- if (auto *Cmp = dyn_cast<CmpInst>(I))
- return Cmp->isCommutative();
- if (auto *BO = dyn_cast<BinaryOperator>(I))
- return BO->isCommutative();
- // TODO: This should check for generic Instruction::isCommutative(), but
- // we need to confirm that the caller code correctly handles Intrinsics
- // for example (does not have 2 operands).
- return false;
+ if (auto *Cmp = dyn_cast<CmpInst>(I))
+ return Cmp->isCommutative();
+ if (auto *BO = dyn_cast<BinaryOperator>(I))
+ return BO->isCommutative();
+ // TODO: This should check for generic Instruction::isCommutative(), but
+ // we need to confirm that the caller code correctly handles Intrinsics
+ // for example (does not have 2 operands).
+ return false;
}
/// Checks if the vector of instructions can be represented as a shuffle, like:
@@ -257,7 +257,7 @@ static bool isCommutative(Instruction *I) {
/// %x3x3 = mul i8 %x3, %x3
/// %y1y1 = mul i8 %y1, %y1
/// %y2y2 = mul i8 %y2, %y2
-/// %ins1 = insertelement <4 x i8> poison, i8 %x0x0, i32 0
+/// %ins1 = insertelement <4 x i8> poison, i8 %x0x0, i32 0
/// %ins2 = insertelement <4 x i8> %ins1, i8 %x3x3, i32 1
/// %ins3 = insertelement <4 x i8> %ins2, i8 %y1y1, i32 2
/// %ins4 = insertelement <4 x i8> %ins3, i8 %y2y2, i32 3
@@ -272,13 +272,13 @@ static bool isCommutative(Instruction *I) {
/// %x3 = extractelement <4 x i8> %x, i32 3
/// %y1 = extractelement <4 x i8> %y, i32 1
/// %y2 = extractelement <4 x i8> %y, i32 2
-/// %1 = insertelement <4 x i8> poison, i8 %x0, i32 0
+/// %1 = insertelement <4 x i8> poison, i8 %x0, i32 0
/// %2 = insertelement <4 x i8> %1, i8 %x3, i32 1
/// %3 = insertelement <4 x i8> %2, i8 %y1, i32 2
/// %4 = insertelement <4 x i8> %3, i8 %y2, i32 3
/// %5 = mul <4 x i8> %4, %4
/// %6 = extractelement <4 x i8> %5, i32 0
-/// %ins1 = insertelement <4 x i8> poison, i8 %6, i32 0
+/// %ins1 = insertelement <4 x i8> poison, i8 %6, i32 0
/// %7 = extractelement <4 x i8> %5, i32 1
/// %ins2 = insertelement <4 x i8> %ins1, i8 %7, i32 1
/// %8 = extractelement <4 x i8> %5, i32 2
@@ -292,8 +292,8 @@ static bool isCommutative(Instruction *I) {
static Optional<TargetTransformInfo::ShuffleKind>
isShuffle(ArrayRef<Value *> VL) {
auto *EI0 = cast<ExtractElementInst>(VL[0]);
- unsigned Size =
- cast<FixedVectorType>(EI0->getVectorOperandType())->getNumElements();
+ unsigned Size =
+ cast<FixedVectorType>(EI0->getVectorOperandType())->getNumElements();
Value *Vec1 = nullptr;
Value *Vec2 = nullptr;
enum ShuffleMode { Unknown, Select, Permute };
@@ -302,7 +302,7 @@ isShuffle(ArrayRef<Value *> VL) {
auto *EI = cast<ExtractElementInst>(VL[I]);
auto *Vec = EI->getVectorOperand();
// All vector operands must have the same number of vector elements.
- if (cast<FixedVectorType>(Vec->getType())->getNumElements() != Size)
+ if (cast<FixedVectorType>(Vec->getType())->getNumElements() != Size)
return None;
auto *Idx = dyn_cast<ConstantInt>(EI->getIndexOperand());
if (!Idx)
@@ -311,7 +311,7 @@ isShuffle(ArrayRef<Value *> VL) {
if (Idx->getValue().uge(Size))
continue;
unsigned IntIdx = Idx->getValue().getZExtValue();
- // We can extractelement from undef or poison vector.
+ // We can extractelement from undef or poison vector.
if (isa<UndefValue>(Vec))
continue;
// For correct shuffling we have to have at most 2 different vector operands
@@ -508,7 +508,7 @@ static bool InTreeUserNeedToExtract(Value *Scalar, Instruction *UserInst,
}
/// \returns the AA location that is being access by the instruction.
-static MemoryLocation getLocation(Instruction *I, AAResults *AA) {
+static MemoryLocation getLocation(Instruction *I, AAResults *AA) {
if (StoreInst *SI = dyn_cast<StoreInst>(I))
return MemoryLocation::get(SI);
if (LoadInst *LI = dyn_cast<LoadInst>(I))
@@ -529,15 +529,15 @@ static bool isSimple(Instruction *I) {
namespace llvm {
-static void inversePermutation(ArrayRef<unsigned> Indices,
- SmallVectorImpl<int> &Mask) {
- Mask.clear();
- const unsigned E = Indices.size();
- Mask.resize(E, E + 1);
- for (unsigned I = 0; I < E; ++I)
- Mask[Indices[I]] = I;
-}
-
+static void inversePermutation(ArrayRef<unsigned> Indices,
+ SmallVectorImpl<int> &Mask) {
+ Mask.clear();
+ const unsigned E = Indices.size();
+ Mask.resize(E, E + 1);
+ for (unsigned I = 0; I < E; ++I)
+ Mask[Indices[I]] = I;
+}
+
namespace slpvectorizer {
/// Bottom Up SLP Vectorizer.
@@ -552,10 +552,10 @@ public:
using StoreList = SmallVector<StoreInst *, 8>;
using ExtraValueToDebugLocsMap =
MapVector<Value *, SmallVector<Instruction *, 2>>;
- using OrdersType = SmallVector<unsigned, 4>;
+ using OrdersType = SmallVector<unsigned, 4>;
BoUpSLP(Function *Func, ScalarEvolution *Se, TargetTransformInfo *Tti,
- TargetLibraryInfo *TLi, AAResults *Aa, LoopInfo *Li,
+ TargetLibraryInfo *TLi, AAResults *Aa, LoopInfo *Li,
DominatorTree *Dt, AssumptionCache *AC, DemandedBits *DB,
const DataLayout *DL, OptimizationRemarkEmitter *ORE)
: F(Func), SE(Se), TTI(Tti), TLI(TLi), AA(Aa), LI(Li), DT(Dt), AC(AC),
@@ -589,11 +589,11 @@ public:
/// \returns the cost incurred by unwanted spills and fills, caused by
/// holding live values over call sites.
- InstructionCost getSpillCost() const;
+ InstructionCost getSpillCost() const;
/// \returns the vectorization cost of the subtree that starts at \p VL.
/// A negative number means that this is profitable.
- InstructionCost getTreeCost();
+ InstructionCost getTreeCost();
/// Construct a vectorizable tree that starts at \p Roots, ignoring users for
/// the purpose of scheduling and extraction in the \p UserIgnoreLst.
@@ -630,14 +630,14 @@ public:
/// \returns The best order of instructions for vectorization.
Optional<ArrayRef<unsigned>> bestOrder() const {
- assert(llvm::all_of(
- NumOpsWantToKeepOrder,
- [this](const decltype(NumOpsWantToKeepOrder)::value_type &D) {
- return D.getFirst().size() ==
- VectorizableTree[0]->Scalars.size();
- }) &&
- "All orders must have the same size as number of instructions in "
- "tree node.");
+ assert(llvm::all_of(
+ NumOpsWantToKeepOrder,
+ [this](const decltype(NumOpsWantToKeepOrder)::value_type &D) {
+ return D.getFirst().size() ==
+ VectorizableTree[0]->Scalars.size();
+ }) &&
+ "All orders must have the same size as number of instructions in "
+ "tree node.");
auto I = std::max_element(
NumOpsWantToKeepOrder.begin(), NumOpsWantToKeepOrder.end(),
[](const decltype(NumOpsWantToKeepOrder)::value_type &D1,
@@ -651,81 +651,81 @@ public:
return makeArrayRef(I->getFirst());
}
- /// Builds the correct order for root instructions.
- /// If some leaves have the same instructions to be vectorized, we may
- /// incorrectly evaluate the best order for the root node (it is built for the
- /// vector of instructions without repeated instructions and, thus, has less
- /// elements than the root node). This function builds the correct order for
- /// the root node.
- /// For example, if the root node is \<a+b, a+c, a+d, f+e\>, then the leaves
- /// are \<a, a, a, f\> and \<b, c, d, e\>. When we try to vectorize the first
- /// leaf, it will be shrink to \<a, b\>. If instructions in this leaf should
- /// be reordered, the best order will be \<1, 0\>. We need to extend this
- /// order for the root node. For the root node this order should look like
- /// \<3, 0, 1, 2\>. This function extends the order for the reused
- /// instructions.
- void findRootOrder(OrdersType &Order) {
- // If the leaf has the same number of instructions to vectorize as the root
- // - order must be set already.
- unsigned RootSize = VectorizableTree[0]->Scalars.size();
- if (Order.size() == RootSize)
- return;
- SmallVector<unsigned, 4> RealOrder(Order.size());
- std::swap(Order, RealOrder);
- SmallVector<int, 4> Mask;
- inversePermutation(RealOrder, Mask);
- Order.assign(Mask.begin(), Mask.end());
- // The leaf has less number of instructions - need to find the true order of
- // the root.
- // Scan the nodes starting from the leaf back to the root.
- const TreeEntry *PNode = VectorizableTree.back().get();
- SmallVector<const TreeEntry *, 4> Nodes(1, PNode);
- SmallPtrSet<const TreeEntry *, 4> Visited;
- while (!Nodes.empty() && Order.size() != RootSize) {
- const TreeEntry *PNode = Nodes.pop_back_val();
- if (!Visited.insert(PNode).second)
- continue;
- const TreeEntry &Node = *PNode;
- for (const EdgeInfo &EI : Node.UserTreeIndices)
- if (EI.UserTE)
- Nodes.push_back(EI.UserTE);
- if (Node.ReuseShuffleIndices.empty())
- continue;
- // Build the order for the parent node.
- OrdersType NewOrder(Node.ReuseShuffleIndices.size(), RootSize);
- SmallVector<unsigned, 4> OrderCounter(Order.size(), 0);
- // The algorithm of the order extension is:
- // 1. Calculate the number of the same instructions for the order.
- // 2. Calculate the index of the new order: total number of instructions
- // with order less than the order of the current instruction + reuse
- // number of the current instruction.
- // 3. The new order is just the index of the instruction in the original
- // vector of the instructions.
- for (unsigned I : Node.ReuseShuffleIndices)
- ++OrderCounter[Order[I]];
- SmallVector<unsigned, 4> CurrentCounter(Order.size(), 0);
- for (unsigned I = 0, E = Node.ReuseShuffleIndices.size(); I < E; ++I) {
- unsigned ReusedIdx = Node.ReuseShuffleIndices[I];
- unsigned OrderIdx = Order[ReusedIdx];
- unsigned NewIdx = 0;
- for (unsigned J = 0; J < OrderIdx; ++J)
- NewIdx += OrderCounter[J];
- NewIdx += CurrentCounter[OrderIdx];
- ++CurrentCounter[OrderIdx];
- assert(NewOrder[NewIdx] == RootSize &&
- "The order index should not be written already.");
- NewOrder[NewIdx] = I;
- }
- std::swap(Order, NewOrder);
- }
- assert(Order.size() == RootSize &&
- "Root node is expected or the size of the order must be the same as "
- "the number of elements in the root node.");
- assert(llvm::all_of(Order,
- [RootSize](unsigned Val) { return Val != RootSize; }) &&
- "All indices must be initialized");
- }
-
+ /// Builds the correct order for root instructions.
+ /// If some leaves have the same instructions to be vectorized, we may
+ /// incorrectly evaluate the best order for the root node (it is built for the
+ /// vector of instructions without repeated instructions and, thus, has less
+ /// elements than the root node). This function builds the correct order for
+ /// the root node.
+ /// For example, if the root node is \<a+b, a+c, a+d, f+e\>, then the leaves
+ /// are \<a, a, a, f\> and \<b, c, d, e\>. When we try to vectorize the first
+ /// leaf, it will be shrink to \<a, b\>. If instructions in this leaf should
+ /// be reordered, the best order will be \<1, 0\>. We need to extend this
+ /// order for the root node. For the root node this order should look like
+ /// \<3, 0, 1, 2\>. This function extends the order for the reused
+ /// instructions.
+ void findRootOrder(OrdersType &Order) {
+ // If the leaf has the same number of instructions to vectorize as the root
+ // - order must be set already.
+ unsigned RootSize = VectorizableTree[0]->Scalars.size();
+ if (Order.size() == RootSize)
+ return;
+ SmallVector<unsigned, 4> RealOrder(Order.size());
+ std::swap(Order, RealOrder);
+ SmallVector<int, 4> Mask;
+ inversePermutation(RealOrder, Mask);
+ Order.assign(Mask.begin(), Mask.end());
+ // The leaf has less number of instructions - need to find the true order of
+ // the root.
+ // Scan the nodes starting from the leaf back to the root.
+ const TreeEntry *PNode = VectorizableTree.back().get();
+ SmallVector<const TreeEntry *, 4> Nodes(1, PNode);
+ SmallPtrSet<const TreeEntry *, 4> Visited;
+ while (!Nodes.empty() && Order.size() != RootSize) {
+ const TreeEntry *PNode = Nodes.pop_back_val();
+ if (!Visited.insert(PNode).second)
+ continue;
+ const TreeEntry &Node = *PNode;
+ for (const EdgeInfo &EI : Node.UserTreeIndices)
+ if (EI.UserTE)
+ Nodes.push_back(EI.UserTE);
+ if (Node.ReuseShuffleIndices.empty())
+ continue;
+ // Build the order for the parent node.
+ OrdersType NewOrder(Node.ReuseShuffleIndices.size(), RootSize);
+ SmallVector<unsigned, 4> OrderCounter(Order.size(), 0);
+ // The algorithm of the order extension is:
+ // 1. Calculate the number of the same instructions for the order.
+ // 2. Calculate the index of the new order: total number of instructions
+ // with order less than the order of the current instruction + reuse
+ // number of the current instruction.
+ // 3. The new order is just the index of the instruction in the original
+ // vector of the instructions.
+ for (unsigned I : Node.ReuseShuffleIndices)
+ ++OrderCounter[Order[I]];
+ SmallVector<unsigned, 4> CurrentCounter(Order.size(), 0);
+ for (unsigned I = 0, E = Node.ReuseShuffleIndices.size(); I < E; ++I) {
+ unsigned ReusedIdx = Node.ReuseShuffleIndices[I];
+ unsigned OrderIdx = Order[ReusedIdx];
+ unsigned NewIdx = 0;
+ for (unsigned J = 0; J < OrderIdx; ++J)
+ NewIdx += OrderCounter[J];
+ NewIdx += CurrentCounter[OrderIdx];
+ ++CurrentCounter[OrderIdx];
+ assert(NewOrder[NewIdx] == RootSize &&
+ "The order index should not be written already.");
+ NewOrder[NewIdx] = I;
+ }
+ std::swap(Order, NewOrder);
+ }
+ assert(Order.size() == RootSize &&
+ "Root node is expected or the size of the order must be the same as "
+ "the number of elements in the root node.");
+ assert(llvm::all_of(Order,
+ [RootSize](unsigned Val) { return Val != RootSize; }) &&
+ "All indices must be initialized");
+ }
+
/// \return The vector element size in bits to use when vectorizing the
/// expression tree ending at \p V. If V is a store, the size is the width of
/// the stored value. Otherwise, the size is the width of the largest loaded
@@ -747,12 +747,12 @@ public:
return MinVecRegSize;
}
- unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) const {
- unsigned MaxVF = MaxVFOption.getNumOccurrences() ?
- MaxVFOption : TTI->getMaximumVF(ElemWidth, Opcode);
- return MaxVF ? MaxVF : UINT_MAX;
- }
-
+ unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) const {
+ unsigned MaxVF = MaxVFOption.getNumOccurrences() ?
+ MaxVFOption : TTI->getMaximumVF(ElemWidth, Opcode);
+ return MaxVF ? MaxVF : UINT_MAX;
+ }
+
/// Check if homogeneous aggregate is isomorphic to some VectorType.
/// Accepts homogeneous multidimensional aggregate of scalars/vectors like
/// {[4 x i16], [4 x i16]}, { <2 x float>, <2 x float> },
@@ -772,7 +772,7 @@ public:
/// effectively impossible for the backend to undo.
/// TODO: If load combining is allowed in the IR optimizer, this analysis
/// may not be necessary.
- bool isLoadCombineReductionCandidate(RecurKind RdxKind) const;
+ bool isLoadCombineReductionCandidate(RecurKind RdxKind) const;
/// Assume that a vector of stores of bitwise-or/shifted/zexted loaded values
/// can be load combined in the backend. Load combining may not be allowed in
@@ -987,14 +987,14 @@ public:
std::array<std::pair<Value *, int>, 2> Values = {{LHS, RHS}};
for (int Idx = 0, IdxE = Values.size(); Idx != IdxE; ++Idx) {
Value *V = Values[Idx].first;
- if (isa<Constant>(V)) {
- // Since this is a function pass, it doesn't make semantic sense to
- // walk the users of a subclass of Constant. The users could be in
- // another function, or even another module that happens to be in
- // the same LLVMContext.
- continue;
- }
-
+ if (isa<Constant>(V)) {
+ // Since this is a function pass, it doesn't make semantic sense to
+ // walk the users of a subclass of Constant. The users could be in
+ // another function, or even another module that happens to be in
+ // the same LLVMContext.
+ continue;
+ }
+
// Calculate the absolute lane, using the minimum relative lane of LHS
// and RHS as base and Idx as the offset.
int Ln = std::min(LHS.second, RHS.second) + Idx;
@@ -1503,7 +1503,7 @@ private:
bool areAllUsersVectorized(Instruction *I) const;
/// \returns the cost of the vectorizable entry.
- InstructionCost getEntryCost(TreeEntry *E);
+ InstructionCost getEntryCost(TreeEntry *E);
/// This is the recursive part of buildTree.
void buildTree_rec(ArrayRef<Value *> Roots, unsigned Depth,
@@ -1525,21 +1525,21 @@ private:
/// \returns the scalarization cost for this type. Scalarization in this
/// context means the creation of vectors from a group of scalars.
- InstructionCost
- getGatherCost(FixedVectorType *Ty,
- const DenseSet<unsigned> &ShuffledIndices) const;
+ InstructionCost
+ getGatherCost(FixedVectorType *Ty,
+ const DenseSet<unsigned> &ShuffledIndices) const;
/// \returns the scalarization cost for this list of values. Assuming that
/// this subtree gets vectorized, we may need to extract the values from the
/// roots. This method calculates the cost of extracting the values.
- InstructionCost getGatherCost(ArrayRef<Value *> VL) const;
+ InstructionCost getGatherCost(ArrayRef<Value *> VL) const;
/// Set the Builder insert point to one after the last instruction in
/// the bundle
void setInsertPointAfterBundle(TreeEntry *E);
/// \returns a vector from a collection of scalars in \p VL.
- Value *gather(ArrayRef<Value *> VL);
+ Value *gather(ArrayRef<Value *> VL);
/// \returns whether the VectorizableTree is fully vectorizable and will
/// be beneficial even the tree height is tiny.
@@ -1573,17 +1573,17 @@ private:
/// The Scalars are vectorized into this value. It is initialized to Null.
Value *VectorizedValue = nullptr;
- /// Do we need to gather this sequence or vectorize it
- /// (either with vector instruction or with scatter/gather
- /// intrinsics for store/load)?
- enum EntryState { Vectorize, ScatterVectorize, NeedToGather };
+ /// Do we need to gather this sequence or vectorize it
+ /// (either with vector instruction or with scatter/gather
+ /// intrinsics for store/load)?
+ enum EntryState { Vectorize, ScatterVectorize, NeedToGather };
EntryState State;
/// Does this sequence require some shuffling?
SmallVector<int, 4> ReuseShuffleIndices;
/// Does this entry require reordering?
- SmallVector<unsigned, 4> ReorderIndices;
+ SmallVector<unsigned, 4> ReorderIndices;
/// Points back to the VectorizableTree.
///
@@ -1724,9 +1724,9 @@ private:
case Vectorize:
dbgs() << "Vectorize\n";
break;
- case ScatterVectorize:
- dbgs() << "ScatterVectorize\n";
- break;
+ case ScatterVectorize:
+ dbgs() << "ScatterVectorize\n";
+ break;
case NeedToGather:
dbgs() << "NeedToGather\n";
break;
@@ -1748,7 +1748,7 @@ private:
dbgs() << "NULL\n";
dbgs() << "ReuseShuffleIndices: ";
if (ReuseShuffleIndices.empty())
- dbgs() << "Empty";
+ dbgs() << "Empty";
else
for (unsigned ReuseIdx : ReuseShuffleIndices)
dbgs() << ReuseIdx << ", ";
@@ -1765,55 +1765,55 @@ private:
#endif
};
-#ifndef NDEBUG
- void dumpTreeCosts(TreeEntry *E, InstructionCost ReuseShuffleCost,
- InstructionCost VecCost,
- InstructionCost ScalarCost) const {
- dbgs() << "SLP: Calculated costs for Tree:\n"; E->dump();
- dbgs() << "SLP: Costs:\n";
- dbgs() << "SLP: ReuseShuffleCost = " << ReuseShuffleCost << "\n";
- dbgs() << "SLP: VectorCost = " << VecCost << "\n";
- dbgs() << "SLP: ScalarCost = " << ScalarCost << "\n";
- dbgs() << "SLP: ReuseShuffleCost + VecCost - ScalarCost = " <<
- ReuseShuffleCost + VecCost - ScalarCost << "\n";
- }
-#endif
-
+#ifndef NDEBUG
+ void dumpTreeCosts(TreeEntry *E, InstructionCost ReuseShuffleCost,
+ InstructionCost VecCost,
+ InstructionCost ScalarCost) const {
+ dbgs() << "SLP: Calculated costs for Tree:\n"; E->dump();
+ dbgs() << "SLP: Costs:\n";
+ dbgs() << "SLP: ReuseShuffleCost = " << ReuseShuffleCost << "\n";
+ dbgs() << "SLP: VectorCost = " << VecCost << "\n";
+ dbgs() << "SLP: ScalarCost = " << ScalarCost << "\n";
+ dbgs() << "SLP: ReuseShuffleCost + VecCost - ScalarCost = " <<
+ ReuseShuffleCost + VecCost - ScalarCost << "\n";
+ }
+#endif
+
/// Create a new VectorizableTree entry.
TreeEntry *newTreeEntry(ArrayRef<Value *> VL, Optional<ScheduleData *> Bundle,
const InstructionsState &S,
const EdgeInfo &UserTreeIdx,
ArrayRef<unsigned> ReuseShuffleIndices = None,
ArrayRef<unsigned> ReorderIndices = None) {
- TreeEntry::EntryState EntryState =
- Bundle ? TreeEntry::Vectorize : TreeEntry::NeedToGather;
- return newTreeEntry(VL, EntryState, Bundle, S, UserTreeIdx,
- ReuseShuffleIndices, ReorderIndices);
- }
-
- TreeEntry *newTreeEntry(ArrayRef<Value *> VL,
- TreeEntry::EntryState EntryState,
- Optional<ScheduleData *> Bundle,
- const InstructionsState &S,
- const EdgeInfo &UserTreeIdx,
- ArrayRef<unsigned> ReuseShuffleIndices = None,
- ArrayRef<unsigned> ReorderIndices = None) {
- assert(((!Bundle && EntryState == TreeEntry::NeedToGather) ||
- (Bundle && EntryState != TreeEntry::NeedToGather)) &&
- "Need to vectorize gather entry?");
+ TreeEntry::EntryState EntryState =
+ Bundle ? TreeEntry::Vectorize : TreeEntry::NeedToGather;
+ return newTreeEntry(VL, EntryState, Bundle, S, UserTreeIdx,
+ ReuseShuffleIndices, ReorderIndices);
+ }
+
+ TreeEntry *newTreeEntry(ArrayRef<Value *> VL,
+ TreeEntry::EntryState EntryState,
+ Optional<ScheduleData *> Bundle,
+ const InstructionsState &S,
+ const EdgeInfo &UserTreeIdx,
+ ArrayRef<unsigned> ReuseShuffleIndices = None,
+ ArrayRef<unsigned> ReorderIndices = None) {
+ assert(((!Bundle && EntryState == TreeEntry::NeedToGather) ||
+ (Bundle && EntryState != TreeEntry::NeedToGather)) &&
+ "Need to vectorize gather entry?");
VectorizableTree.push_back(std::make_unique<TreeEntry>(VectorizableTree));
TreeEntry *Last = VectorizableTree.back().get();
Last->Idx = VectorizableTree.size() - 1;
Last->Scalars.insert(Last->Scalars.begin(), VL.begin(), VL.end());
- Last->State = EntryState;
+ Last->State = EntryState;
Last->ReuseShuffleIndices.append(ReuseShuffleIndices.begin(),
ReuseShuffleIndices.end());
- Last->ReorderIndices.append(ReorderIndices.begin(), ReorderIndices.end());
+ Last->ReorderIndices.append(ReorderIndices.begin(), ReorderIndices.end());
Last->setOperations(S);
- if (Last->State != TreeEntry::NeedToGather) {
- for (Value *V : VL) {
- assert(!getTreeEntry(V) && "Scalar already in tree!");
- ScalarToTreeEntry[V] = Last;
+ if (Last->State != TreeEntry::NeedToGather) {
+ for (Value *V : VL) {
+ assert(!getTreeEntry(V) && "Scalar already in tree!");
+ ScalarToTreeEntry[V] = Last;
}
// Update the scheduler bundle to point to this TreeEntry.
unsigned Lane = 0;
@@ -1849,10 +1849,10 @@ private:
}
#endif
- TreeEntry *getTreeEntry(Value *V) { return ScalarToTreeEntry.lookup(V); }
+ TreeEntry *getTreeEntry(Value *V) { return ScalarToTreeEntry.lookup(V); }
const TreeEntry *getTreeEntry(Value *V) const {
- return ScalarToTreeEntry.lookup(V);
+ return ScalarToTreeEntry.lookup(V);
}
/// Maps a specific scalar to its tree entry.
@@ -2374,7 +2374,7 @@ private:
ScalarEvolution *SE;
TargetTransformInfo *TTI;
TargetLibraryInfo *TLI;
- AAResults *AA;
+ AAResults *AA;
LoopInfo *LI;
DominatorTree *DT;
AssumptionCache *AC;
@@ -2473,9 +2473,9 @@ template <> struct DOTGraphTraits<BoUpSLP *> : public DefaultDOTGraphTraits {
}
for (auto V : Entry->Scalars) {
OS << *V;
- if (llvm::any_of(R->ExternalUses, [&](const BoUpSLP::ExternalUser &EU) {
- return EU.Scalar == V;
- }))
+ if (llvm::any_of(R->ExternalUses, [&](const BoUpSLP::ExternalUser &EU) {
+ return EU.Scalar == V;
+ }))
OS << " <extract>";
OS << "\n";
}
@@ -2507,17 +2507,17 @@ BoUpSLP::~BoUpSLP() {
"trying to erase instruction with users.");
Pair.getFirst()->eraseFromParent();
}
-#ifdef EXPENSIVE_CHECKS
- // If we could guarantee that this call is not extremely slow, we could
- // remove the ifdef limitation (see PR47712).
+#ifdef EXPENSIVE_CHECKS
+ // If we could guarantee that this call is not extremely slow, we could
+ // remove the ifdef limitation (see PR47712).
assert(!verifyFunction(*F, &dbgs()));
-#endif
+#endif
}
void BoUpSLP::eraseInstructions(ArrayRef<Value *> AV) {
for (auto *V : AV) {
if (auto *I = dyn_cast<Instruction>(V))
- eraseInstruction(I, /*ReplaceOpsWithUndef=*/true);
+ eraseInstruction(I, /*ReplaceOpsWithUndef=*/true);
};
}
@@ -2742,11 +2742,11 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
auto *PH = cast<PHINode>(VL0);
// Check for terminator values (e.g. invoke).
- for (Value *V : VL)
- for (unsigned I = 0, E = PH->getNumIncomingValues(); I < E; ++I) {
+ for (Value *V : VL)
+ for (unsigned I = 0, E = PH->getNumIncomingValues(); I < E; ++I) {
Instruction *Term = dyn_cast<Instruction>(
- cast<PHINode>(V)->getIncomingValueForBlock(
- PH->getIncomingBlock(I)));
+ cast<PHINode>(V)->getIncomingValueForBlock(
+ PH->getIncomingBlock(I)));
if (Term && Term->isTerminator()) {
LLVM_DEBUG(dbgs()
<< "SLP: Need to swizzle PHINodes (terminator use).\n");
@@ -2763,13 +2763,13 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
// Keeps the reordered operands to avoid code duplication.
SmallVector<ValueList, 2> OperandsVec;
- for (unsigned I = 0, E = PH->getNumIncomingValues(); I < E; ++I) {
+ for (unsigned I = 0, E = PH->getNumIncomingValues(); I < E; ++I) {
ValueList Operands;
// Prepare the operand vector.
- for (Value *V : VL)
- Operands.push_back(cast<PHINode>(V)->getIncomingValueForBlock(
- PH->getIncomingBlock(I)));
- TE->setOperand(I, Operands);
+ for (Value *V : VL)
+ Operands.push_back(cast<PHINode>(V)->getIncomingValueForBlock(
+ PH->getIncomingBlock(I)));
+ TE->setOperand(I, Operands);
OperandsVec.push_back(Operands);
}
for (unsigned OpIdx = 0, OpE = OperandsVec.size(); OpIdx != OpE; ++OpIdx)
@@ -2803,9 +2803,9 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
// Insert new order with initial value 0, if it does not exist,
// otherwise return the iterator to the existing one.
newTreeEntry(VL, Bundle /*vectorized*/, S, UserTreeIdx,
- ReuseShuffleIndicies, CurrentOrder);
- findRootOrder(CurrentOrder);
- ++NumOpsWantToKeepOrder[CurrentOrder];
+ ReuseShuffleIndicies, CurrentOrder);
+ findRootOrder(CurrentOrder);
+ ++NumOpsWantToKeepOrder[CurrentOrder];
// This is a special case, as it does not gather, but at the same time
// we are not extending buildTree_rec() towards the operands.
ValueList Op0;
@@ -2884,21 +2884,21 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
// Need to reorder.
TreeEntry *TE =
newTreeEntry(VL, Bundle /*vectorized*/, S, UserTreeIdx,
- ReuseShuffleIndicies, CurrentOrder);
+ ReuseShuffleIndicies, CurrentOrder);
TE->setOperandsInOrder();
LLVM_DEBUG(dbgs() << "SLP: added a vector of jumbled loads.\n");
- findRootOrder(CurrentOrder);
- ++NumOpsWantToKeepOrder[CurrentOrder];
+ findRootOrder(CurrentOrder);
+ ++NumOpsWantToKeepOrder[CurrentOrder];
}
return;
}
- // Vectorizing non-consecutive loads with `llvm.masked.gather`.
- TreeEntry *TE = newTreeEntry(VL, TreeEntry::ScatterVectorize, Bundle, S,
- UserTreeIdx, ReuseShuffleIndicies);
- TE->setOperandsInOrder();
- buildTree_rec(PointerOps, Depth + 1, {TE, 0});
- LLVM_DEBUG(dbgs() << "SLP: added a vector of non-consecutive loads.\n");
- return;
+ // Vectorizing non-consecutive loads with `llvm.masked.gather`.
+ TreeEntry *TE = newTreeEntry(VL, TreeEntry::ScatterVectorize, Bundle, S,
+ UserTreeIdx, ReuseShuffleIndicies);
+ TE->setOperandsInOrder();
+ buildTree_rec(PointerOps, Depth + 1, {TE, 0});
+ LLVM_DEBUG(dbgs() << "SLP: added a vector of non-consecutive loads.\n");
+ return;
}
LLVM_DEBUG(dbgs() << "SLP: Gathering non-consecutive loads.\n");
@@ -3033,8 +3033,8 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
for (unsigned i = 0, e = VL0->getNumOperands(); i < e; ++i) {
ValueList Operands;
// Prepare the operand vector.
- for (Value *V : VL)
- Operands.push_back(cast<Instruction>(V)->getOperand(i));
+ for (Value *V : VL)
+ Operands.push_back(cast<Instruction>(V)->getOperand(i));
buildTree_rec(Operands, Depth + 1, {TE, i});
}
@@ -3102,16 +3102,16 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
case Instruction::Store: {
// Check if the stores are consecutive or if we need to swizzle them.
llvm::Type *ScalarTy = cast<StoreInst>(VL0)->getValueOperand()->getType();
- // Avoid types that are padded when being allocated as scalars, while
- // being packed together in a vector (such as i1).
- if (DL->getTypeSizeInBits(ScalarTy) !=
- DL->getTypeAllocSizeInBits(ScalarTy)) {
- BS.cancelScheduling(VL, VL0);
- newTreeEntry(VL, None /*not vectorized*/, S, UserTreeIdx,
- ReuseShuffleIndicies);
- LLVM_DEBUG(dbgs() << "SLP: Gathering stores of non-packed type.\n");
- return;
- }
+ // Avoid types that are padded when being allocated as scalars, while
+ // being packed together in a vector (such as i1).
+ if (DL->getTypeSizeInBits(ScalarTy) !=
+ DL->getTypeAllocSizeInBits(ScalarTy)) {
+ BS.cancelScheduling(VL, VL0);
+ newTreeEntry(VL, None /*not vectorized*/, S, UserTreeIdx,
+ ReuseShuffleIndicies);
+ LLVM_DEBUG(dbgs() << "SLP: Gathering stores of non-packed type.\n");
+ return;
+ }
// Make sure all stores in the bundle are simple - we can't vectorize
// atomic or volatile stores.
SmallVector<Value *, 4> PointerOps(VL.size());
@@ -3163,12 +3163,12 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
} else {
TreeEntry *TE =
newTreeEntry(VL, Bundle /*vectorized*/, S, UserTreeIdx,
- ReuseShuffleIndicies, CurrentOrder);
+ ReuseShuffleIndicies, CurrentOrder);
TE->setOperandsInOrder();
buildTree_rec(Operands, Depth + 1, {TE, 0});
LLVM_DEBUG(dbgs() << "SLP: added a vector of jumbled stores.\n");
- findRootOrder(CurrentOrder);
- ++NumOpsWantToKeepOrder[CurrentOrder];
+ findRootOrder(CurrentOrder);
+ ++NumOpsWantToKeepOrder[CurrentOrder];
}
return;
}
@@ -3187,7 +3187,7 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
Intrinsic::ID ID = getVectorIntrinsicIDForCall(CI, TLI);
VFShape Shape = VFShape::get(
- *CI, ElementCount::getFixed(static_cast<unsigned int>(VL.size())),
+ *CI, ElementCount::getFixed(static_cast<unsigned int>(VL.size())),
false /*HasGlobalPred*/);
Function *VecFunc = VFDatabase(*CI).getVectorizedFunction(Shape);
@@ -3324,7 +3324,7 @@ unsigned BoUpSLP::canMapToVector(Type *T, const DataLayout &DL) const {
N *= AT->getNumElements();
EltTy = AT->getElementType();
} else {
- auto *VT = cast<FixedVectorType>(EltTy);
+ auto *VT = cast<FixedVectorType>(EltTy);
N *= VT->getNumElements();
EltTy = VT->getElementType();
}
@@ -3362,7 +3362,7 @@ bool BoUpSLP::canReuseExtract(ArrayRef<Value *> VL, Value *OpValue,
if (!LI || !LI->isSimple() || !LI->hasNUses(VL.size()))
return false;
} else {
- NElts = cast<FixedVectorType>(Vec->getType())->getNumElements();
+ NElts = cast<FixedVectorType>(Vec->getType())->getNumElements();
}
if (NElts != VL.size())
@@ -3406,26 +3406,26 @@ bool BoUpSLP::canReuseExtract(ArrayRef<Value *> VL, Value *OpValue,
}
bool BoUpSLP::areAllUsersVectorized(Instruction *I) const {
- return I->hasOneUse() || llvm::all_of(I->users(), [this](User *U) {
+ return I->hasOneUse() || llvm::all_of(I->users(), [this](User *U) {
return ScalarToTreeEntry.count(U) > 0;
});
}
-static std::pair<InstructionCost, InstructionCost>
-getVectorCallCosts(CallInst *CI, FixedVectorType *VecTy,
- TargetTransformInfo *TTI, TargetLibraryInfo *TLI) {
+static std::pair<InstructionCost, InstructionCost>
+getVectorCallCosts(CallInst *CI, FixedVectorType *VecTy,
+ TargetTransformInfo *TTI, TargetLibraryInfo *TLI) {
Intrinsic::ID ID = getVectorIntrinsicIDForCall(CI, TLI);
// Calculate the cost of the scalar and vector calls.
- IntrinsicCostAttributes CostAttrs(ID, *CI, VecTy->getElementCount());
- auto IntrinsicCost =
+ IntrinsicCostAttributes CostAttrs(ID, *CI, VecTy->getElementCount());
+ auto IntrinsicCost =
TTI->getIntrinsicInstrCost(CostAttrs, TTI::TCK_RecipThroughput);
- auto Shape = VFShape::get(*CI, ElementCount::getFixed(static_cast<unsigned>(
- VecTy->getNumElements())),
- false /*HasGlobalPred*/);
+ auto Shape = VFShape::get(*CI, ElementCount::getFixed(static_cast<unsigned>(
+ VecTy->getNumElements())),
+ false /*HasGlobalPred*/);
Function *VecFunc = VFDatabase(*CI).getVectorizedFunction(Shape);
- auto LibCost = IntrinsicCost;
+ auto LibCost = IntrinsicCost;
if (!CI->isNoBuiltin() && VecFunc) {
// Calculate the cost of the vector library call.
SmallVector<Type *, 4> VecTys;
@@ -3440,7 +3440,7 @@ getVectorCallCosts(CallInst *CI, FixedVectorType *VecTy,
return {IntrinsicCost, LibCost};
}
-InstructionCost BoUpSLP::getEntryCost(TreeEntry *E) {
+InstructionCost BoUpSLP::getEntryCost(TreeEntry *E) {
ArrayRef<Value*> VL = E->Scalars;
Type *ScalarTy = VL[0]->getType();
@@ -3459,7 +3459,7 @@ InstructionCost BoUpSLP::getEntryCost(TreeEntry *E) {
unsigned ReuseShuffleNumbers = E->ReuseShuffleIndices.size();
bool NeedToShuffleReuses = !E->ReuseShuffleIndices.empty();
- InstructionCost ReuseShuffleCost = 0;
+ InstructionCost ReuseShuffleCost = 0;
if (NeedToShuffleReuses) {
ReuseShuffleCost =
TTI->getShuffleCost(TargetTransformInfo::SK_PermuteSingleSrc, VecTy);
@@ -3475,8 +3475,8 @@ InstructionCost BoUpSLP::getEntryCost(TreeEntry *E) {
allSameType(VL) && allSameBlock(VL)) {
Optional<TargetTransformInfo::ShuffleKind> ShuffleKind = isShuffle(VL);
if (ShuffleKind.hasValue()) {
- InstructionCost Cost =
- TTI->getShuffleCost(ShuffleKind.getValue(), VecTy);
+ InstructionCost Cost =
+ TTI->getShuffleCost(ShuffleKind.getValue(), VecTy);
for (auto *V : VL) {
// If all users of instruction are going to be vectorized and this
// instruction itself is not going to be vectorized, consider this
@@ -3495,9 +3495,9 @@ InstructionCost BoUpSLP::getEntryCost(TreeEntry *E) {
}
return ReuseShuffleCost + getGatherCost(VL);
}
- assert((E->State == TreeEntry::Vectorize ||
- E->State == TreeEntry::ScatterVectorize) &&
- "Unhandled state");
+ assert((E->State == TreeEntry::Vectorize ||
+ E->State == TreeEntry::ScatterVectorize) &&
+ "Unhandled state");
assert(E->getOpcode() && allSameType(VL) && allSameBlock(VL) && "Invalid VL");
Instruction *VL0 = E->getMainOp();
unsigned ShuffleOrOp =
@@ -3536,37 +3536,37 @@ InstructionCost BoUpSLP::getEntryCost(TreeEntry *E) {
TTI->getVectorInstrCost(Instruction::ExtractElement, VecTy, Idx);
}
}
- InstructionCost DeadCost = ReuseShuffleCost;
+ InstructionCost DeadCost = ReuseShuffleCost;
if (!E->ReorderIndices.empty()) {
// TODO: Merge this shuffle with the ReuseShuffleCost.
DeadCost += TTI->getShuffleCost(
TargetTransformInfo::SK_PermuteSingleSrc, VecTy);
}
- for (unsigned I = 0, E = VL.size(); I < E; ++I) {
- Instruction *EI = cast<Instruction>(VL[I]);
+ for (unsigned I = 0, E = VL.size(); I < E; ++I) {
+ Instruction *EI = cast<Instruction>(VL[I]);
// If all users are going to be vectorized, instruction can be
// considered as dead.
// The same, if have only one user, it will be vectorized for sure.
- if (areAllUsersVectorized(EI)) {
+ if (areAllUsersVectorized(EI)) {
// Take credit for instruction that will become dead.
- if (EI->hasOneUse()) {
- Instruction *Ext = EI->user_back();
+ if (EI->hasOneUse()) {
+ Instruction *Ext = EI->user_back();
if ((isa<SExtInst>(Ext) || isa<ZExtInst>(Ext)) &&
all_of(Ext->users(),
[](User *U) { return isa<GetElementPtrInst>(U); })) {
// Use getExtractWithExtendCost() to calculate the cost of
// extractelement/ext pair.
DeadCost -= TTI->getExtractWithExtendCost(
- Ext->getOpcode(), Ext->getType(), VecTy, I);
+ Ext->getOpcode(), Ext->getType(), VecTy, I);
// Add back the cost of s|zext which is subtracted separately.
DeadCost += TTI->getCastInstrCost(
- Ext->getOpcode(), Ext->getType(), EI->getType(),
- TTI::getCastContextHint(Ext), CostKind, Ext);
+ Ext->getOpcode(), Ext->getType(), EI->getType(),
+ TTI::getCastContextHint(Ext), CostKind, Ext);
continue;
}
}
DeadCost -=
- TTI->getVectorInstrCost(Instruction::ExtractElement, VecTy, I);
+ TTI->getVectorInstrCost(Instruction::ExtractElement, VecTy, I);
}
}
return DeadCost;
@@ -3584,78 +3584,78 @@ InstructionCost BoUpSLP::getEntryCost(TreeEntry *E) {
case Instruction::FPTrunc:
case Instruction::BitCast: {
Type *SrcTy = VL0->getOperand(0)->getType();
- InstructionCost ScalarEltCost =
- TTI->getCastInstrCost(E->getOpcode(), ScalarTy, SrcTy,
- TTI::getCastContextHint(VL0), CostKind, VL0);
+ InstructionCost ScalarEltCost =
+ TTI->getCastInstrCost(E->getOpcode(), ScalarTy, SrcTy,
+ TTI::getCastContextHint(VL0), CostKind, VL0);
if (NeedToShuffleReuses) {
ReuseShuffleCost -= (ReuseShuffleNumbers - VL.size()) * ScalarEltCost;
}
// Calculate the cost of this instruction.
- InstructionCost ScalarCost = VL.size() * ScalarEltCost;
+ InstructionCost ScalarCost = VL.size() * ScalarEltCost;
auto *SrcVecTy = FixedVectorType::get(SrcTy, VL.size());
- InstructionCost VecCost = 0;
+ InstructionCost VecCost = 0;
// Check if the values are candidates to demote.
if (!MinBWs.count(VL0) || VecTy != SrcVecTy) {
- VecCost =
- ReuseShuffleCost +
- TTI->getCastInstrCost(E->getOpcode(), VecTy, SrcVecTy,
- TTI::getCastContextHint(VL0), CostKind, VL0);
+ VecCost =
+ ReuseShuffleCost +
+ TTI->getCastInstrCost(E->getOpcode(), VecTy, SrcVecTy,
+ TTI::getCastContextHint(VL0), CostKind, VL0);
}
- LLVM_DEBUG(dumpTreeCosts(E, ReuseShuffleCost, VecCost, ScalarCost));
+ LLVM_DEBUG(dumpTreeCosts(E, ReuseShuffleCost, VecCost, ScalarCost));
return VecCost - ScalarCost;
}
case Instruction::FCmp:
case Instruction::ICmp:
case Instruction::Select: {
// Calculate the cost of this instruction.
- InstructionCost ScalarEltCost =
- TTI->getCmpSelInstrCost(E->getOpcode(), ScalarTy, Builder.getInt1Ty(),
- CmpInst::BAD_ICMP_PREDICATE, CostKind, VL0);
+ InstructionCost ScalarEltCost =
+ TTI->getCmpSelInstrCost(E->getOpcode(), ScalarTy, Builder.getInt1Ty(),
+ CmpInst::BAD_ICMP_PREDICATE, CostKind, VL0);
if (NeedToShuffleReuses) {
ReuseShuffleCost -= (ReuseShuffleNumbers - VL.size()) * ScalarEltCost;
}
auto *MaskTy = FixedVectorType::get(Builder.getInt1Ty(), VL.size());
- InstructionCost ScalarCost = VecTy->getNumElements() * ScalarEltCost;
-
- // Check if all entries in VL are either compares or selects with compares
- // as condition that have the same predicates.
- CmpInst::Predicate VecPred = CmpInst::BAD_ICMP_PREDICATE;
- bool First = true;
- for (auto *V : VL) {
- CmpInst::Predicate CurrentPred;
- auto MatchCmp = m_Cmp(CurrentPred, m_Value(), m_Value());
- if ((!match(V, m_Select(MatchCmp, m_Value(), m_Value())) &&
- !match(V, MatchCmp)) ||
- (!First && VecPred != CurrentPred)) {
- VecPred = CmpInst::BAD_ICMP_PREDICATE;
- break;
- }
- First = false;
- VecPred = CurrentPred;
- }
-
- InstructionCost VecCost = TTI->getCmpSelInstrCost(
- E->getOpcode(), VecTy, MaskTy, VecPred, CostKind, VL0);
- // Check if it is possible and profitable to use min/max for selects in
- // VL.
- //
- auto IntrinsicAndUse = canConvertToMinOrMaxIntrinsic(VL);
- if (IntrinsicAndUse.first != Intrinsic::not_intrinsic) {
- IntrinsicCostAttributes CostAttrs(IntrinsicAndUse.first, VecTy,
- {VecTy, VecTy});
- InstructionCost IntrinsicCost =
- TTI->getIntrinsicInstrCost(CostAttrs, CostKind);
- // If the selects are the only uses of the compares, they will be dead
- // and we can adjust the cost by removing their cost.
- if (IntrinsicAndUse.second)
- IntrinsicCost -=
- TTI->getCmpSelInstrCost(Instruction::ICmp, VecTy, MaskTy,
- CmpInst::BAD_ICMP_PREDICATE, CostKind);
- VecCost = std::min(VecCost, IntrinsicCost);
- }
- LLVM_DEBUG(dumpTreeCosts(E, ReuseShuffleCost, VecCost, ScalarCost));
+ InstructionCost ScalarCost = VecTy->getNumElements() * ScalarEltCost;
+
+ // Check if all entries in VL are either compares or selects with compares
+ // as condition that have the same predicates.
+ CmpInst::Predicate VecPred = CmpInst::BAD_ICMP_PREDICATE;
+ bool First = true;
+ for (auto *V : VL) {
+ CmpInst::Predicate CurrentPred;
+ auto MatchCmp = m_Cmp(CurrentPred, m_Value(), m_Value());
+ if ((!match(V, m_Select(MatchCmp, m_Value(), m_Value())) &&
+ !match(V, MatchCmp)) ||
+ (!First && VecPred != CurrentPred)) {
+ VecPred = CmpInst::BAD_ICMP_PREDICATE;
+ break;
+ }
+ First = false;
+ VecPred = CurrentPred;
+ }
+
+ InstructionCost VecCost = TTI->getCmpSelInstrCost(
+ E->getOpcode(), VecTy, MaskTy, VecPred, CostKind, VL0);
+ // Check if it is possible and profitable to use min/max for selects in
+ // VL.
+ //
+ auto IntrinsicAndUse = canConvertToMinOrMaxIntrinsic(VL);
+ if (IntrinsicAndUse.first != Intrinsic::not_intrinsic) {
+ IntrinsicCostAttributes CostAttrs(IntrinsicAndUse.first, VecTy,
+ {VecTy, VecTy});
+ InstructionCost IntrinsicCost =
+ TTI->getIntrinsicInstrCost(CostAttrs, CostKind);
+ // If the selects are the only uses of the compares, they will be dead
+ // and we can adjust the cost by removing their cost.
+ if (IntrinsicAndUse.second)
+ IntrinsicCost -=
+ TTI->getCmpSelInstrCost(Instruction::ICmp, VecTy, MaskTy,
+ CmpInst::BAD_ICMP_PREDICATE, CostKind);
+ VecCost = std::min(VecCost, IntrinsicCost);
+ }
+ LLVM_DEBUG(dumpTreeCosts(E, ReuseShuffleCost, VecCost, ScalarCost));
return ReuseShuffleCost + VecCost - ScalarCost;
}
case Instruction::FNeg:
@@ -3715,17 +3715,17 @@ InstructionCost BoUpSLP::getEntryCost(TreeEntry *E) {
}
SmallVector<const Value *, 4> Operands(VL0->operand_values());
- InstructionCost ScalarEltCost =
- TTI->getArithmeticInstrCost(E->getOpcode(), ScalarTy, CostKind, Op1VK,
- Op2VK, Op1VP, Op2VP, Operands, VL0);
+ InstructionCost ScalarEltCost =
+ TTI->getArithmeticInstrCost(E->getOpcode(), ScalarTy, CostKind, Op1VK,
+ Op2VK, Op1VP, Op2VP, Operands, VL0);
if (NeedToShuffleReuses) {
ReuseShuffleCost -= (ReuseShuffleNumbers - VL.size()) * ScalarEltCost;
}
- InstructionCost ScalarCost = VecTy->getNumElements() * ScalarEltCost;
- InstructionCost VecCost =
- TTI->getArithmeticInstrCost(E->getOpcode(), VecTy, CostKind, Op1VK,
- Op2VK, Op1VP, Op2VP, Operands, VL0);
- LLVM_DEBUG(dumpTreeCosts(E, ReuseShuffleCost, VecCost, ScalarCost));
+ InstructionCost ScalarCost = VecTy->getNumElements() * ScalarEltCost;
+ InstructionCost VecCost =
+ TTI->getArithmeticInstrCost(E->getOpcode(), VecTy, CostKind, Op1VK,
+ Op2VK, Op1VP, Op2VP, Operands, VL0);
+ LLVM_DEBUG(dumpTreeCosts(E, ReuseShuffleCost, VecCost, ScalarCost));
return ReuseShuffleCost + VecCost - ScalarCost;
}
case Instruction::GetElementPtr: {
@@ -3734,42 +3734,42 @@ InstructionCost BoUpSLP::getEntryCost(TreeEntry *E) {
TargetTransformInfo::OperandValueKind Op2VK =
TargetTransformInfo::OK_UniformConstantValue;
- InstructionCost ScalarEltCost = TTI->getArithmeticInstrCost(
- Instruction::Add, ScalarTy, CostKind, Op1VK, Op2VK);
+ InstructionCost ScalarEltCost = TTI->getArithmeticInstrCost(
+ Instruction::Add, ScalarTy, CostKind, Op1VK, Op2VK);
if (NeedToShuffleReuses) {
ReuseShuffleCost -= (ReuseShuffleNumbers - VL.size()) * ScalarEltCost;
}
- InstructionCost ScalarCost = VecTy->getNumElements() * ScalarEltCost;
- InstructionCost VecCost = TTI->getArithmeticInstrCost(
- Instruction::Add, VecTy, CostKind, Op1VK, Op2VK);
- LLVM_DEBUG(dumpTreeCosts(E, ReuseShuffleCost, VecCost, ScalarCost));
+ InstructionCost ScalarCost = VecTy->getNumElements() * ScalarEltCost;
+ InstructionCost VecCost = TTI->getArithmeticInstrCost(
+ Instruction::Add, VecTy, CostKind, Op1VK, Op2VK);
+ LLVM_DEBUG(dumpTreeCosts(E, ReuseShuffleCost, VecCost, ScalarCost));
return ReuseShuffleCost + VecCost - ScalarCost;
}
case Instruction::Load: {
// Cost of wide load - cost of scalar loads.
Align alignment = cast<LoadInst>(VL0)->getAlign();
- InstructionCost ScalarEltCost = TTI->getMemoryOpCost(
- Instruction::Load, ScalarTy, alignment, 0, CostKind, VL0);
+ InstructionCost ScalarEltCost = TTI->getMemoryOpCost(
+ Instruction::Load, ScalarTy, alignment, 0, CostKind, VL0);
if (NeedToShuffleReuses) {
ReuseShuffleCost -= (ReuseShuffleNumbers - VL.size()) * ScalarEltCost;
}
- InstructionCost ScalarLdCost = VecTy->getNumElements() * ScalarEltCost;
- InstructionCost VecLdCost;
- if (E->State == TreeEntry::Vectorize) {
- VecLdCost = TTI->getMemoryOpCost(Instruction::Load, VecTy, alignment, 0,
- CostKind, VL0);
- } else {
- assert(E->State == TreeEntry::ScatterVectorize && "Unknown EntryState");
- VecLdCost = TTI->getGatherScatterOpCost(
- Instruction::Load, VecTy, cast<LoadInst>(VL0)->getPointerOperand(),
- /*VariableMask=*/false, alignment, CostKind, VL0);
- }
+ InstructionCost ScalarLdCost = VecTy->getNumElements() * ScalarEltCost;
+ InstructionCost VecLdCost;
+ if (E->State == TreeEntry::Vectorize) {
+ VecLdCost = TTI->getMemoryOpCost(Instruction::Load, VecTy, alignment, 0,
+ CostKind, VL0);
+ } else {
+ assert(E->State == TreeEntry::ScatterVectorize && "Unknown EntryState");
+ VecLdCost = TTI->getGatherScatterOpCost(
+ Instruction::Load, VecTy, cast<LoadInst>(VL0)->getPointerOperand(),
+ /*VariableMask=*/false, alignment, CostKind, VL0);
+ }
if (!E->ReorderIndices.empty()) {
// TODO: Merge this shuffle with the ReuseShuffleCost.
VecLdCost += TTI->getShuffleCost(
TargetTransformInfo::SK_PermuteSingleSrc, VecTy);
}
- LLVM_DEBUG(dumpTreeCosts(E, ReuseShuffleCost, VecLdCost, ScalarLdCost));
+ LLVM_DEBUG(dumpTreeCosts(E, ReuseShuffleCost, VecLdCost, ScalarLdCost));
return ReuseShuffleCost + VecLdCost - ScalarLdCost;
}
case Instruction::Store: {
@@ -3778,19 +3778,19 @@ InstructionCost BoUpSLP::getEntryCost(TreeEntry *E) {
auto *SI =
cast<StoreInst>(IsReorder ? VL[E->ReorderIndices.front()] : VL0);
Align Alignment = SI->getAlign();
- InstructionCost ScalarEltCost = TTI->getMemoryOpCost(
- Instruction::Store, ScalarTy, Alignment, 0, CostKind, VL0);
+ InstructionCost ScalarEltCost = TTI->getMemoryOpCost(
+ Instruction::Store, ScalarTy, Alignment, 0, CostKind, VL0);
if (NeedToShuffleReuses)
ReuseShuffleCost = -(ReuseShuffleNumbers - VL.size()) * ScalarEltCost;
- InstructionCost ScalarStCost = VecTy->getNumElements() * ScalarEltCost;
- InstructionCost VecStCost = TTI->getMemoryOpCost(
- Instruction::Store, VecTy, Alignment, 0, CostKind, VL0);
+ InstructionCost ScalarStCost = VecTy->getNumElements() * ScalarEltCost;
+ InstructionCost VecStCost = TTI->getMemoryOpCost(
+ Instruction::Store, VecTy, Alignment, 0, CostKind, VL0);
if (IsReorder) {
// TODO: Merge this shuffle with the ReuseShuffleCost.
VecStCost += TTI->getShuffleCost(
TargetTransformInfo::SK_PermuteSingleSrc, VecTy);
}
- LLVM_DEBUG(dumpTreeCosts(E, ReuseShuffleCost, VecStCost, ScalarStCost));
+ LLVM_DEBUG(dumpTreeCosts(E, ReuseShuffleCost, VecStCost, ScalarStCost));
return ReuseShuffleCost + VecStCost - ScalarStCost;
}
case Instruction::Call: {
@@ -3798,17 +3798,17 @@ InstructionCost BoUpSLP::getEntryCost(TreeEntry *E) {
Intrinsic::ID ID = getVectorIntrinsicIDForCall(CI, TLI);
// Calculate the cost of the scalar and vector calls.
- IntrinsicCostAttributes CostAttrs(ID, *CI, ElementCount::getFixed(1), 1);
- InstructionCost ScalarEltCost =
- TTI->getIntrinsicInstrCost(CostAttrs, CostKind);
+ IntrinsicCostAttributes CostAttrs(ID, *CI, ElementCount::getFixed(1), 1);
+ InstructionCost ScalarEltCost =
+ TTI->getIntrinsicInstrCost(CostAttrs, CostKind);
if (NeedToShuffleReuses) {
ReuseShuffleCost -= (ReuseShuffleNumbers - VL.size()) * ScalarEltCost;
}
- InstructionCost ScalarCallCost = VecTy->getNumElements() * ScalarEltCost;
+ InstructionCost ScalarCallCost = VecTy->getNumElements() * ScalarEltCost;
auto VecCallCosts = getVectorCallCosts(CI, VecTy, TTI, TLI);
- InstructionCost VecCallCost =
- std::min(VecCallCosts.first, VecCallCosts.second);
+ InstructionCost VecCallCost =
+ std::min(VecCallCosts.first, VecCallCosts.second);
LLVM_DEBUG(dbgs() << "SLP: Call cost " << VecCallCost - ScalarCallCost
<< " (" << VecCallCost << "-" << ScalarCallCost << ")"
@@ -3823,7 +3823,7 @@ InstructionCost BoUpSLP::getEntryCost(TreeEntry *E) {
(Instruction::isCast(E->getOpcode()) &&
Instruction::isCast(E->getAltOpcode()))) &&
"Invalid Shuffle Vector Operand");
- InstructionCost ScalarCost = 0;
+ InstructionCost ScalarCost = 0;
if (NeedToShuffleReuses) {
for (unsigned Idx : E->ReuseShuffleIndices) {
Instruction *I = cast<Instruction>(VL[Idx]);
@@ -3841,7 +3841,7 @@ InstructionCost BoUpSLP::getEntryCost(TreeEntry *E) {
}
// VecCost is equal to sum of the cost of creating 2 vectors
// and the cost of creating shuffle.
- InstructionCost VecCost = 0;
+ InstructionCost VecCost = 0;
if (Instruction::isBinaryOp(E->getOpcode())) {
VecCost = TTI->getArithmeticInstrCost(E->getOpcode(), VecTy, CostKind);
VecCost += TTI->getArithmeticInstrCost(E->getAltOpcode(), VecTy,
@@ -3852,12 +3852,12 @@ InstructionCost BoUpSLP::getEntryCost(TreeEntry *E) {
auto *Src0Ty = FixedVectorType::get(Src0SclTy, VL.size());
auto *Src1Ty = FixedVectorType::get(Src1SclTy, VL.size());
VecCost = TTI->getCastInstrCost(E->getOpcode(), VecTy, Src0Ty,
- TTI::CastContextHint::None, CostKind);
+ TTI::CastContextHint::None, CostKind);
VecCost += TTI->getCastInstrCost(E->getAltOpcode(), VecTy, Src1Ty,
- TTI::CastContextHint::None, CostKind);
+ TTI::CastContextHint::None, CostKind);
}
VecCost += TTI->getShuffleCost(TargetTransformInfo::SK_Select, VecTy, 0);
- LLVM_DEBUG(dumpTreeCosts(E, ReuseShuffleCost, VecCost, ScalarCost));
+ LLVM_DEBUG(dumpTreeCosts(E, ReuseShuffleCost, VecCost, ScalarCost));
return ReuseShuffleCost + VecCost - ScalarCost;
}
default:
@@ -3895,13 +3895,13 @@ static bool isLoadCombineCandidateImpl(Value *Root, unsigned NumElts,
TargetTransformInfo *TTI) {
// Look past the root to find a source value. Arbitrarily follow the
// path through operand 0 of any 'or'. Also, peek through optional
- // shift-left-by-multiple-of-8-bits.
+ // shift-left-by-multiple-of-8-bits.
Value *ZextLoad = Root;
- const APInt *ShAmtC;
+ const APInt *ShAmtC;
while (!isa<ConstantExpr>(ZextLoad) &&
(match(ZextLoad, m_Or(m_Value(), m_Value())) ||
- (match(ZextLoad, m_Shl(m_Value(), m_APInt(ShAmtC))) &&
- ShAmtC->urem(8) == 0)))
+ (match(ZextLoad, m_Shl(m_Value(), m_APInt(ShAmtC))) &&
+ ShAmtC->urem(8) == 0)))
ZextLoad = cast<BinaryOperator>(ZextLoad)->getOperand(0);
// Check if the input is an extended load of the required or/shift expression.
@@ -3925,8 +3925,8 @@ static bool isLoadCombineCandidateImpl(Value *Root, unsigned NumElts,
return true;
}
-bool BoUpSLP::isLoadCombineReductionCandidate(RecurKind RdxKind) const {
- if (RdxKind != RecurKind::Or)
+bool BoUpSLP::isLoadCombineReductionCandidate(RecurKind RdxKind) const {
+ if (RdxKind != RecurKind::Or)
return false;
unsigned NumElts = VectorizableTree[0]->Scalars.size();
@@ -3967,35 +3967,35 @@ bool BoUpSLP::isTreeTinyAndNotFullyVectorizable() const {
return true;
}
-InstructionCost BoUpSLP::getSpillCost() const {
+InstructionCost BoUpSLP::getSpillCost() const {
// Walk from the bottom of the tree to the top, tracking which values are
// live. When we see a call instruction that is not part of our tree,
// query TTI to see if there is a cost to keeping values live over it
// (for example, if spills and fills are required).
unsigned BundleWidth = VectorizableTree.front()->Scalars.size();
- InstructionCost Cost = 0;
+ InstructionCost Cost = 0;
SmallPtrSet<Instruction*, 4> LiveValues;
Instruction *PrevInst = nullptr;
- // The entries in VectorizableTree are not necessarily ordered by their
- // position in basic blocks. Collect them and order them by dominance so later
- // instructions are guaranteed to be visited first. For instructions in
- // different basic blocks, we only scan to the beginning of the block, so
- // their order does not matter, as long as all instructions in a basic block
- // are grouped together. Using dominance ensures a deterministic order.
- SmallVector<Instruction *, 16> OrderedScalars;
+ // The entries in VectorizableTree are not necessarily ordered by their
+ // position in basic blocks. Collect them and order them by dominance so later
+ // instructions are guaranteed to be visited first. For instructions in
+ // different basic blocks, we only scan to the beginning of the block, so
+ // their order does not matter, as long as all instructions in a basic block
+ // are grouped together. Using dominance ensures a deterministic order.
+ SmallVector<Instruction *, 16> OrderedScalars;
for (const auto &TEPtr : VectorizableTree) {
Instruction *Inst = dyn_cast<Instruction>(TEPtr->Scalars[0]);
if (!Inst)
continue;
- OrderedScalars.push_back(Inst);
- }
- llvm::stable_sort(OrderedScalars, [this](Instruction *A, Instruction *B) {
- return DT->dominates(B, A);
- });
+ OrderedScalars.push_back(Inst);
+ }
+ llvm::stable_sort(OrderedScalars, [this](Instruction *A, Instruction *B) {
+ return DT->dominates(B, A);
+ });
- for (Instruction *Inst : OrderedScalars) {
+ for (Instruction *Inst : OrderedScalars) {
if (!PrevInst) {
PrevInst = Inst;
continue;
@@ -4049,8 +4049,8 @@ InstructionCost BoUpSLP::getSpillCost() const {
return Cost;
}
-InstructionCost BoUpSLP::getTreeCost() {
- InstructionCost Cost = 0;
+InstructionCost BoUpSLP::getTreeCost() {
+ InstructionCost Cost = 0;
LLVM_DEBUG(dbgs() << "SLP: Calculating cost for tree of size "
<< VectorizableTree.size() << ".\n");
@@ -4080,16 +4080,16 @@ InstructionCost BoUpSLP::getTreeCost() {
}))
continue;
- InstructionCost C = getEntryCost(&TE);
- Cost += C;
+ InstructionCost C = getEntryCost(&TE);
+ Cost += C;
LLVM_DEBUG(dbgs() << "SLP: Adding cost " << C
<< " for bundle that starts with " << *TE.Scalars[0]
- << ".\n"
- << "SLP: Current total cost = " << Cost << "\n");
+ << ".\n"
+ << "SLP: Current total cost = " << Cost << "\n");
}
SmallPtrSet<Value *, 16> ExtractCostCalculated;
- InstructionCost ExtractCost = 0;
+ InstructionCost ExtractCost = 0;
for (ExternalUser &EU : ExternalUses) {
// We only add extract cost once for the same scalar.
if (!ExtractCostCalculated.insert(EU.Scalar).second)
@@ -4119,13 +4119,13 @@ InstructionCost BoUpSLP::getTreeCost() {
}
}
- InstructionCost SpillCost = getSpillCost();
+ InstructionCost SpillCost = getSpillCost();
Cost += SpillCost + ExtractCost;
-#ifndef NDEBUG
- SmallString<256> Str;
+#ifndef NDEBUG
+ SmallString<256> Str;
{
- raw_svector_ostream OS(Str);
+ raw_svector_ostream OS(Str);
OS << "SLP: Spill Cost = " << SpillCost << ".\n"
<< "SLP: Extract Cost = " << ExtractCost << ".\n"
<< "SLP: Total Cost = " << Cost << ".\n";
@@ -4133,28 +4133,28 @@ InstructionCost BoUpSLP::getTreeCost() {
LLVM_DEBUG(dbgs() << Str);
if (ViewSLPTree)
ViewGraph(this, "SLP" + F->getName(), false, Str);
-#endif
+#endif
return Cost;
}
-InstructionCost
-BoUpSLP::getGatherCost(FixedVectorType *Ty,
- const DenseSet<unsigned> &ShuffledIndices) const {
+InstructionCost
+BoUpSLP::getGatherCost(FixedVectorType *Ty,
+ const DenseSet<unsigned> &ShuffledIndices) const {
unsigned NumElts = Ty->getNumElements();
APInt DemandedElts = APInt::getNullValue(NumElts);
- for (unsigned I = 0; I < NumElts; ++I)
- if (!ShuffledIndices.count(I))
- DemandedElts.setBit(I);
- InstructionCost Cost =
- TTI->getScalarizationOverhead(Ty, DemandedElts, /*Insert*/ true,
- /*Extract*/ false);
+ for (unsigned I = 0; I < NumElts; ++I)
+ if (!ShuffledIndices.count(I))
+ DemandedElts.setBit(I);
+ InstructionCost Cost =
+ TTI->getScalarizationOverhead(Ty, DemandedElts, /*Insert*/ true,
+ /*Extract*/ false);
if (!ShuffledIndices.empty())
Cost += TTI->getShuffleCost(TargetTransformInfo::SK_PermuteSingleSrc, Ty);
return Cost;
}
-InstructionCost BoUpSLP::getGatherCost(ArrayRef<Value *> VL) const {
+InstructionCost BoUpSLP::getGatherCost(ArrayRef<Value *> VL) const {
// Find the type of the operands in VL.
Type *ScalarTy = VL[0]->getType();
if (StoreInst *SI = dyn_cast<StoreInst>(VL[0]))
@@ -4196,10 +4196,10 @@ void BoUpSLP::setInsertPointAfterBundle(TreeEntry *E) {
// should be in this block.
auto *Front = E->getMainOp();
auto *BB = Front->getParent();
- assert(llvm::all_of(E->Scalars, [=](Value *V) -> bool {
- auto *I = cast<Instruction>(V);
- return !E->isOpcodeOrAlt(I) || I->getParent() == BB;
- }));
+ assert(llvm::all_of(E->Scalars, [=](Value *V) -> bool {
+ auto *I = cast<Instruction>(V);
+ return !E->isOpcodeOrAlt(I) || I->getParent() == BB;
+ }));
// The last instruction in the bundle in program order.
Instruction *LastInst = nullptr;
@@ -4252,30 +4252,30 @@ void BoUpSLP::setInsertPointAfterBundle(TreeEntry *E) {
Builder.SetCurrentDebugLocation(Front->getDebugLoc());
}
-Value *BoUpSLP::gather(ArrayRef<Value *> VL) {
- Value *Val0 =
- isa<StoreInst>(VL[0]) ? cast<StoreInst>(VL[0])->getValueOperand() : VL[0];
- FixedVectorType *VecTy = FixedVectorType::get(Val0->getType(), VL.size());
- Value *Vec = PoisonValue::get(VecTy);
- unsigned InsIndex = 0;
- for (Value *Val : VL) {
- Vec = Builder.CreateInsertElement(Vec, Val, Builder.getInt32(InsIndex++));
- auto *InsElt = dyn_cast<InsertElementInst>(Vec);
- if (!InsElt)
- continue;
- GatherSeq.insert(InsElt);
- CSEBlocks.insert(InsElt->getParent());
- // Add to our 'need-to-extract' list.
- if (TreeEntry *Entry = getTreeEntry(Val)) {
- // Find which lane we need to extract.
- unsigned FoundLane = std::distance(Entry->Scalars.begin(),
- find(Entry->Scalars, Val));
- assert(FoundLane < Entry->Scalars.size() && "Couldn't find extract lane");
- if (!Entry->ReuseShuffleIndices.empty()) {
- FoundLane = std::distance(Entry->ReuseShuffleIndices.begin(),
- find(Entry->ReuseShuffleIndices, FoundLane));
- }
- ExternalUses.push_back(ExternalUser(Val, InsElt, FoundLane));
+Value *BoUpSLP::gather(ArrayRef<Value *> VL) {
+ Value *Val0 =
+ isa<StoreInst>(VL[0]) ? cast<StoreInst>(VL[0])->getValueOperand() : VL[0];
+ FixedVectorType *VecTy = FixedVectorType::get(Val0->getType(), VL.size());
+ Value *Vec = PoisonValue::get(VecTy);
+ unsigned InsIndex = 0;
+ for (Value *Val : VL) {
+ Vec = Builder.CreateInsertElement(Vec, Val, Builder.getInt32(InsIndex++));
+ auto *InsElt = dyn_cast<InsertElementInst>(Vec);
+ if (!InsElt)
+ continue;
+ GatherSeq.insert(InsElt);
+ CSEBlocks.insert(InsElt->getParent());
+ // Add to our 'need-to-extract' list.
+ if (TreeEntry *Entry = getTreeEntry(Val)) {
+ // Find which lane we need to extract.
+ unsigned FoundLane = std::distance(Entry->Scalars.begin(),
+ find(Entry->Scalars, Val));
+ assert(FoundLane < Entry->Scalars.size() && "Couldn't find extract lane");
+ if (!Entry->ReuseShuffleIndices.empty()) {
+ FoundLane = std::distance(Entry->ReuseShuffleIndices.begin(),
+ find(Entry->ReuseShuffleIndices, FoundLane));
+ }
+ ExternalUses.push_back(ExternalUser(Val, InsElt, FoundLane));
}
}
@@ -4299,7 +4299,7 @@ Value *BoUpSLP::vectorizeTree(ArrayRef<Value *> VL) {
for (int Idx : E->ReuseShuffleIndices)
if (UsedIdxs.insert(Idx).second)
UniqueIdxs.emplace_back(Idx);
- V = Builder.CreateShuffleVector(V, UniqueIdxs);
+ V = Builder.CreateShuffleVector(V, UniqueIdxs);
}
}
return V;
@@ -4327,15 +4327,15 @@ Value *BoUpSLP::vectorizeTree(ArrayRef<Value *> VL) {
VL = UniqueValues;
}
- Value *Vec = gather(VL);
+ Value *Vec = gather(VL);
if (!ReuseShuffleIndicies.empty()) {
- Vec = Builder.CreateShuffleVector(Vec, ReuseShuffleIndicies, "shuffle");
- if (auto *I = dyn_cast<Instruction>(Vec)) {
+ Vec = Builder.CreateShuffleVector(Vec, ReuseShuffleIndicies, "shuffle");
+ if (auto *I = dyn_cast<Instruction>(Vec)) {
GatherSeq.insert(I);
CSEBlocks.insert(I->getParent());
}
}
- return Vec;
+ return Vec;
}
Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
@@ -4349,28 +4349,28 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
bool NeedToShuffleReuses = !E->ReuseShuffleIndices.empty();
if (E->State == TreeEntry::NeedToGather) {
setInsertPointAfterBundle(E);
- Value *Vec = gather(E->Scalars);
+ Value *Vec = gather(E->Scalars);
if (NeedToShuffleReuses) {
- Vec = Builder.CreateShuffleVector(Vec, E->ReuseShuffleIndices, "shuffle");
- if (auto *I = dyn_cast<Instruction>(Vec)) {
+ Vec = Builder.CreateShuffleVector(Vec, E->ReuseShuffleIndices, "shuffle");
+ if (auto *I = dyn_cast<Instruction>(Vec)) {
GatherSeq.insert(I);
CSEBlocks.insert(I->getParent());
}
}
- E->VectorizedValue = Vec;
- return Vec;
+ E->VectorizedValue = Vec;
+ return Vec;
}
- assert((E->State == TreeEntry::Vectorize ||
- E->State == TreeEntry::ScatterVectorize) &&
- "Unhandled state");
+ assert((E->State == TreeEntry::Vectorize ||
+ E->State == TreeEntry::ScatterVectorize) &&
+ "Unhandled state");
unsigned ShuffleOrOp =
E->isAltShuffle() ? (unsigned)Instruction::ShuffleVector : E->getOpcode();
- Instruction *VL0 = E->getMainOp();
- Type *ScalarTy = VL0->getType();
- if (auto *Store = dyn_cast<StoreInst>(VL0))
- ScalarTy = Store->getValueOperand()->getType();
- auto *VecTy = FixedVectorType::get(ScalarTy, E->Scalars.size());
+ Instruction *VL0 = E->getMainOp();
+ Type *ScalarTy = VL0->getType();
+ if (auto *Store = dyn_cast<StoreInst>(VL0))
+ ScalarTy = Store->getValueOperand()->getType();
+ auto *VecTy = FixedVectorType::get(ScalarTy, E->Scalars.size());
switch (ShuffleOrOp) {
case Instruction::PHI: {
auto *PH = cast<PHINode>(VL0);
@@ -4378,9 +4378,9 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
Builder.SetCurrentDebugLocation(PH->getDebugLoc());
PHINode *NewPhi = Builder.CreatePHI(VecTy, PH->getNumIncomingValues());
Value *V = NewPhi;
- if (NeedToShuffleReuses)
- V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
-
+ if (NeedToShuffleReuses)
+ V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
+
E->VectorizedValue = V;
// PHINodes may have multiple entries from the same block. We want to
@@ -4413,33 +4413,33 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
SmallVector<int, 4> Mask;
inversePermutation(E->ReorderIndices, Mask);
Builder.SetInsertPoint(VL0);
- V = Builder.CreateShuffleVector(V, Mask, "reorder_shuffle");
+ V = Builder.CreateShuffleVector(V, Mask, "reorder_shuffle");
}
if (NeedToShuffleReuses) {
// TODO: Merge this shuffle with the ReorderShuffleMask.
if (E->ReorderIndices.empty())
Builder.SetInsertPoint(VL0);
- V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
+ V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
}
E->VectorizedValue = V;
return V;
}
case Instruction::ExtractValue: {
- auto *LI = cast<LoadInst>(E->getSingleOperand(0));
+ auto *LI = cast<LoadInst>(E->getSingleOperand(0));
Builder.SetInsertPoint(LI);
- auto *PtrTy = PointerType::get(VecTy, LI->getPointerAddressSpace());
+ auto *PtrTy = PointerType::get(VecTy, LI->getPointerAddressSpace());
Value *Ptr = Builder.CreateBitCast(LI->getOperand(0), PtrTy);
LoadInst *V = Builder.CreateAlignedLoad(VecTy, Ptr, LI->getAlign());
Value *NewV = propagateMetadata(V, E->Scalars);
if (!E->ReorderIndices.empty()) {
SmallVector<int, 4> Mask;
inversePermutation(E->ReorderIndices, Mask);
- NewV = Builder.CreateShuffleVector(NewV, Mask, "reorder_shuffle");
+ NewV = Builder.CreateShuffleVector(NewV, Mask, "reorder_shuffle");
}
if (NeedToShuffleReuses) {
// TODO: Merge this shuffle with the ReorderShuffleMask.
- NewV = Builder.CreateShuffleVector(NewV, E->ReuseShuffleIndices,
- "shuffle");
+ NewV = Builder.CreateShuffleVector(NewV, E->ReuseShuffleIndices,
+ "shuffle");
}
E->VectorizedValue = NewV;
return NewV;
@@ -4467,9 +4467,9 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
auto *CI = cast<CastInst>(VL0);
Value *V = Builder.CreateCast(CI->getOpcode(), InVec, VecTy);
- if (NeedToShuffleReuses)
- V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
-
+ if (NeedToShuffleReuses)
+ V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
+
E->VectorizedValue = V;
++NumVectorInstructions;
return V;
@@ -4489,9 +4489,9 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
CmpInst::Predicate P0 = cast<CmpInst>(VL0)->getPredicate();
Value *V = Builder.CreateCmp(P0, L, R);
propagateIRFlags(V, E->Scalars, VL0);
- if (NeedToShuffleReuses)
- V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
-
+ if (NeedToShuffleReuses)
+ V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
+
E->VectorizedValue = V;
++NumVectorInstructions;
return V;
@@ -4509,9 +4509,9 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
}
Value *V = Builder.CreateSelect(Cond, True, False);
- if (NeedToShuffleReuses)
- V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
-
+ if (NeedToShuffleReuses)
+ V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
+
E->VectorizedValue = V;
++NumVectorInstructions;
return V;
@@ -4532,9 +4532,9 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
if (auto *I = dyn_cast<Instruction>(V))
V = propagateMetadata(I, E->Scalars);
- if (NeedToShuffleReuses)
- V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
-
+ if (NeedToShuffleReuses)
+ V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
+
E->VectorizedValue = V;
++NumVectorInstructions;
@@ -4575,9 +4575,9 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
if (auto *I = dyn_cast<Instruction>(V))
V = propagateMetadata(I, E->Scalars);
- if (NeedToShuffleReuses)
- V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
-
+ if (NeedToShuffleReuses)
+ V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
+
E->VectorizedValue = V;
++NumVectorInstructions;
@@ -4592,40 +4592,40 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
setInsertPointAfterBundle(E);
LoadInst *LI = cast<LoadInst>(VL0);
- Instruction *NewLI;
+ Instruction *NewLI;
unsigned AS = LI->getPointerAddressSpace();
- Value *PO = LI->getPointerOperand();
- if (E->State == TreeEntry::Vectorize) {
-
- Value *VecPtr = Builder.CreateBitCast(PO, VecTy->getPointerTo(AS));
-
- // The pointer operand uses an in-tree scalar so we add the new BitCast
- // to ExternalUses list to make sure that an extract will be generated
- // in the future.
- if (getTreeEntry(PO))
- ExternalUses.emplace_back(PO, cast<User>(VecPtr), 0);
-
- NewLI = Builder.CreateAlignedLoad(VecTy, VecPtr, LI->getAlign());
- } else {
- assert(E->State == TreeEntry::ScatterVectorize && "Unhandled state");
- Value *VecPtr = vectorizeTree(E->getOperand(0));
- // Use the minimum alignment of the gathered loads.
- Align CommonAlignment = LI->getAlign();
- for (Value *V : E->Scalars)
- CommonAlignment =
- commonAlignment(CommonAlignment, cast<LoadInst>(V)->getAlign());
- NewLI = Builder.CreateMaskedGather(VecPtr, CommonAlignment);
- }
- Value *V = propagateMetadata(NewLI, E->Scalars);
-
+ Value *PO = LI->getPointerOperand();
+ if (E->State == TreeEntry::Vectorize) {
+
+ Value *VecPtr = Builder.CreateBitCast(PO, VecTy->getPointerTo(AS));
+
+ // The pointer operand uses an in-tree scalar so we add the new BitCast
+ // to ExternalUses list to make sure that an extract will be generated
+ // in the future.
+ if (getTreeEntry(PO))
+ ExternalUses.emplace_back(PO, cast<User>(VecPtr), 0);
+
+ NewLI = Builder.CreateAlignedLoad(VecTy, VecPtr, LI->getAlign());
+ } else {
+ assert(E->State == TreeEntry::ScatterVectorize && "Unhandled state");
+ Value *VecPtr = vectorizeTree(E->getOperand(0));
+ // Use the minimum alignment of the gathered loads.
+ Align CommonAlignment = LI->getAlign();
+ for (Value *V : E->Scalars)
+ CommonAlignment =
+ commonAlignment(CommonAlignment, cast<LoadInst>(V)->getAlign());
+ NewLI = Builder.CreateMaskedGather(VecPtr, CommonAlignment);
+ }
+ Value *V = propagateMetadata(NewLI, E->Scalars);
+
if (IsReorder) {
SmallVector<int, 4> Mask;
inversePermutation(E->ReorderIndices, Mask);
- V = Builder.CreateShuffleVector(V, Mask, "reorder_shuffle");
+ V = Builder.CreateShuffleVector(V, Mask, "reorder_shuffle");
}
if (NeedToShuffleReuses) {
// TODO: Merge this shuffle with the ReorderShuffleMask.
- V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
+ V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
}
E->VectorizedValue = V;
++NumVectorInstructions;
@@ -4643,7 +4643,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
if (IsReorder) {
SmallVector<int, 4> Mask(E->ReorderIndices.begin(),
E->ReorderIndices.end());
- VecValue = Builder.CreateShuffleVector(VecValue, Mask, "reorder_shuf");
+ VecValue = Builder.CreateShuffleVector(VecValue, Mask, "reorder_shuf");
}
Value *ScalarPtr = SI->getPointerOperand();
Value *VecPtr = Builder.CreateBitCast(
@@ -4658,9 +4658,9 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
ExternalUses.push_back(ExternalUser(ScalarPtr, cast<User>(VecPtr), 0));
Value *V = propagateMetadata(ST, E->Scalars);
- if (NeedToShuffleReuses)
- V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
-
+ if (NeedToShuffleReuses)
+ V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
+
E->VectorizedValue = V;
++NumVectorInstructions;
return V;
@@ -4697,9 +4697,9 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
if (Instruction *I = dyn_cast<Instruction>(V))
V = propagateMetadata(I, E->Scalars);
- if (NeedToShuffleReuses)
- V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
-
+ if (NeedToShuffleReuses)
+ V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
+
E->VectorizedValue = V;
++NumVectorInstructions;
@@ -4739,10 +4739,10 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
Function *CF;
if (!UseIntrinsic) {
- VFShape Shape =
- VFShape::get(*CI, ElementCount::getFixed(static_cast<unsigned>(
- VecTy->getNumElements())),
- false /*HasGlobalPred*/);
+ VFShape Shape =
+ VFShape::get(*CI, ElementCount::getFixed(static_cast<unsigned>(
+ VecTy->getNumElements())),
+ false /*HasGlobalPred*/);
CF = VFDatabase(*CI).getVectorizedFunction(Shape);
} else {
Type *Tys[] = {FixedVectorType::get(CI->getType(), E->Scalars.size())};
@@ -4760,9 +4760,9 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
ExternalUses.push_back(ExternalUser(ScalarArg, cast<User>(V), 0));
propagateIRFlags(V, E->Scalars, VL0);
- if (NeedToShuffleReuses)
- V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
-
+ if (NeedToShuffleReuses)
+ V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
+
E->VectorizedValue = V;
++NumVectorInstructions;
return V;
@@ -4827,9 +4827,9 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
Value *V = Builder.CreateShuffleVector(V0, V1, Mask);
if (Instruction *I = dyn_cast<Instruction>(V))
V = propagateMetadata(I, E->Scalars);
- if (NeedToShuffleReuses)
- V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
-
+ if (NeedToShuffleReuses)
+ V = Builder.CreateShuffleVector(V, E->ReuseShuffleIndices, "shuffle");
+
E->VectorizedValue = V;
++NumVectorInstructions;
@@ -4894,8 +4894,8 @@ BoUpSLP::vectorizeTree(ExtraValueToDebugLocsMap &ExternallyUsedValues) {
continue;
TreeEntry *E = getTreeEntry(Scalar);
assert(E && "Invalid scalar");
- assert(E->State != TreeEntry::NeedToGather &&
- "Extracting from a gather list");
+ assert(E->State != TreeEntry::NeedToGather &&
+ "Extracting from a gather list");
Value *Vec = E->VectorizedValue;
assert(Vec && "Can't find vectorizable value");
@@ -5053,8 +5053,8 @@ void BoUpSLP::optimizeGatherSequence() {
// instructions into different buckets based on the insert lane.
SmallVector<Instruction *, 16> Visited;
for (auto I = CSEWorkList.begin(), E = CSEWorkList.end(); I != E; ++I) {
- assert(*I &&
- (I == CSEWorkList.begin() || !DT->dominates(*I, *std::prev(I))) &&
+ assert(*I &&
+ (I == CSEWorkList.begin() || !DT->dominates(*I, *std::prev(I))) &&
"Worklist not sorted properly!");
BasicBlock *BB = (*I)->getBlock();
// For all instructions in blocks containing gather sequences:
@@ -5164,7 +5164,7 @@ BoUpSLP::BlockScheduling::tryScheduleBundle(ArrayRef<Value *> VL, BoUpSLP *SLP,
// cancelScheduling).
while (!Bundle->isReady() && !ReadyInsts.empty()) {
- ScheduleData *pickedSD = ReadyInsts.pop_back_val();
+ ScheduleData *pickedSD = ReadyInsts.pop_back_val();
if (pickedSD->isSchedulingEntity() && pickedSD->isReady()) {
schedule(pickedSD, ReadyInsts);
@@ -5308,9 +5308,9 @@ void BoUpSLP::BlockScheduling::initScheduleData(Instruction *FromI,
if (I->mayReadOrWriteMemory() &&
(!isa<IntrinsicInst>(I) ||
- (cast<IntrinsicInst>(I)->getIntrinsicID() != Intrinsic::sideeffect &&
- cast<IntrinsicInst>(I)->getIntrinsicID() !=
- Intrinsic::pseudoprobe))) {
+ (cast<IntrinsicInst>(I)->getIntrinsicID() != Intrinsic::sideeffect &&
+ cast<IntrinsicInst>(I)->getIntrinsicID() !=
+ Intrinsic::pseudoprobe))) {
// Update the linked list of memory accessing instructions.
if (CurrentLoadStore) {
CurrentLoadStore->NextLoadStore = SD;
@@ -5337,7 +5337,7 @@ void BoUpSLP::BlockScheduling::calculateDependencies(ScheduleData *SD,
WorkList.push_back(SD);
while (!WorkList.empty()) {
- ScheduleData *SD = WorkList.pop_back_val();
+ ScheduleData *SD = WorkList.pop_back_val();
ScheduleData *BundleMember = SD;
while (BundleMember) {
@@ -5534,15 +5534,15 @@ void BoUpSLP::scheduleBlock(BlockScheduling *BS) {
}
unsigned BoUpSLP::getVectorElementSize(Value *V) {
- // If V is a store, just return the width of the stored value (or value
- // truncated just before storing) without traversing the expression tree.
- // This is the common case.
- if (auto *Store = dyn_cast<StoreInst>(V)) {
- if (auto *Trunc = dyn_cast<TruncInst>(Store->getValueOperand()))
- return DL->getTypeSizeInBits(Trunc->getSrcTy());
- else
- return DL->getTypeSizeInBits(Store->getValueOperand()->getType());
- }
+ // If V is a store, just return the width of the stored value (or value
+ // truncated just before storing) without traversing the expression tree.
+ // This is the common case.
+ if (auto *Store = dyn_cast<StoreInst>(V)) {
+ if (auto *Trunc = dyn_cast<TruncInst>(Store->getValueOperand()))
+ return DL->getTypeSizeInBits(Trunc->getSrcTy());
+ else
+ return DL->getTypeSizeInBits(Store->getValueOperand()->getType());
+ }
auto E = InstrElementSize.find(V);
if (E != InstrElementSize.end())
@@ -5891,7 +5891,7 @@ PreservedAnalyses SLPVectorizerPass::run(Function &F, FunctionAnalysisManager &A
bool SLPVectorizerPass::runImpl(Function &F, ScalarEvolution *SE_,
TargetTransformInfo *TTI_,
- TargetLibraryInfo *TLI_, AAResults *AA_,
+ TargetLibraryInfo *TLI_, AAResults *AA_,
LoopInfo *LI_, DominatorTree *DT_,
AssumptionCache *AC_, DemandedBits *DB_,
OptimizationRemarkEmitter *ORE_) {
@@ -5991,11 +5991,11 @@ bool SLPVectorizerPass::vectorizeStoreChain(ArrayRef<Value *> Chain, BoUpSLP &R,
R.computeMinimumValueSizes();
- InstructionCost Cost = R.getTreeCost();
+ InstructionCost Cost = R.getTreeCost();
- LLVM_DEBUG(dbgs() << "SLP: Found cost = " << Cost << " for VF =" << VF << "\n");
+ LLVM_DEBUG(dbgs() << "SLP: Found cost = " << Cost << " for VF =" << VF << "\n");
if (Cost < -SLPCostThreshold) {
- LLVM_DEBUG(dbgs() << "SLP: Decided to vectorize cost = " << Cost << "\n");
+ LLVM_DEBUG(dbgs() << "SLP: Decided to vectorize cost = " << Cost << "\n");
using namespace ore;
@@ -6068,7 +6068,7 @@ bool SLPVectorizerPass::vectorizeStores(ArrayRef<StoreInst *> Stores,
// If a vector register can't hold 1 element, we are done.
unsigned MaxVecRegSize = R.getMaxVecRegSize();
- unsigned EltSize = R.getVectorElementSize(Operands[0]);
+ unsigned EltSize = R.getVectorElementSize(Operands[0]);
if (MaxVecRegSize % EltSize != 0)
continue;
@@ -6119,7 +6119,7 @@ void SLPVectorizerPass::collectSeedInstructions(BasicBlock *BB) {
continue;
if (!isValidElementType(SI->getValueOperand()->getType()))
continue;
- Stores[getUnderlyingObject(SI->getPointerOperand())].push_back(SI);
+ Stores[getUnderlyingObject(SI->getPointerOperand())].push_back(SI);
}
// Ignore getelementptr instructions that have more than one index, a
@@ -6183,7 +6183,7 @@ bool SLPVectorizerPass::tryToVectorizeList(ArrayRef<Value *> VL, BoUpSLP &R,
unsigned Sz = R.getVectorElementSize(I0);
unsigned MinVF = std::max(2U, R.getMinVecRegSize() / Sz);
unsigned MaxVF = std::max<unsigned>(PowerOf2Floor(VL.size()), MinVF);
- MaxVF = std::min(R.getMaximumVF(Sz, S.getOpcode()), MaxVF);
+ MaxVF = std::min(R.getMaximumVF(Sz, S.getOpcode()), MaxVF);
if (MaxVF < 2) {
R.getORE()->emit([&]() {
return OptimizationRemarkMissed(SV_NAME, "SmallVF", I0)
@@ -6195,7 +6195,7 @@ bool SLPVectorizerPass::tryToVectorizeList(ArrayRef<Value *> VL, BoUpSLP &R,
bool Changed = false;
bool CandidateFound = false;
- InstructionCost MinCost = SLPCostThreshold.getValue();
+ InstructionCost MinCost = SLPCostThreshold.getValue();
bool CompensateUseCost =
!InsertUses.empty() && llvm::all_of(InsertUses, [](const Value *V) {
@@ -6251,7 +6251,7 @@ bool SLPVectorizerPass::tryToVectorizeList(ArrayRef<Value *> VL, BoUpSLP &R,
continue;
R.computeMinimumValueSizes();
- InstructionCost Cost = R.getTreeCost();
+ InstructionCost Cost = R.getTreeCost();
CandidateFound = true;
if (CompensateUseCost) {
// TODO: Use TTI's getScalarizationOverhead for sequence of inserts
@@ -6261,7 +6261,7 @@ bool SLPVectorizerPass::tryToVectorizeList(ArrayRef<Value *> VL, BoUpSLP &R,
// part should also switch to same interface.
// For example, the following case is projected code after SLP:
// %4 = extractelement <4 x i64> %3, i32 0
- // %v0 = insertelement <4 x i64> poison, i64 %4, i32 0
+ // %v0 = insertelement <4 x i64> poison, i64 %4, i32 0
// %5 = extractelement <4 x i64> %3, i32 1
// %v1 = insertelement <4 x i64> %v0, i64 %5, i32 1
// %6 = extractelement <4 x i64> %3, i32 2
@@ -6281,7 +6281,7 @@ bool SLPVectorizerPass::tryToVectorizeList(ArrayRef<Value *> VL, BoUpSLP &R,
// Switching to the TTI interface might help a bit.
// Alternative solution could be pattern-match to detect a no-op or
// shuffle.
- InstructionCost UserCost = 0;
+ InstructionCost UserCost = 0;
for (unsigned Lane = 0; Lane < OpsWidth; Lane++) {
auto *IE = cast<InsertElementInst>(InsertUses[I + Lane]);
if (auto *CI = dyn_cast<ConstantInt>(IE->getOperand(2)))
@@ -6376,16 +6376,16 @@ namespace {
/// Model horizontal reductions.
///
-/// A horizontal reduction is a tree of reduction instructions that has values
-/// that can be put into a vector as its leaves. For example:
+/// A horizontal reduction is a tree of reduction instructions that has values
+/// that can be put into a vector as its leaves. For example:
///
/// mul mul mul mul
/// \ / \ /
/// + +
/// \ /
/// +
-/// This tree has "mul" as its leaf values and "+" as its reduction
-/// instructions. A reduction can feed into a store or a binary operation
+/// This tree has "mul" as its leaf values and "+" as its reduction
+/// instructions. A reduction can feed into a store or a binary operation
/// feeding a phi.
/// ...
/// \ /
@@ -6403,345 +6403,345 @@ namespace {
class HorizontalReduction {
using ReductionOpsType = SmallVector<Value *, 16>;
using ReductionOpsListType = SmallVector<ReductionOpsType, 2>;
- ReductionOpsListType ReductionOps;
+ ReductionOpsListType ReductionOps;
SmallVector<Value *, 32> ReducedVals;
// Use map vector to make stable output.
MapVector<Instruction *, Value *> ExtraArgs;
- WeakTrackingVH ReductionRoot;
- /// The type of reduction operation.
- RecurKind RdxKind;
-
- /// Checks if instruction is associative and can be vectorized.
- static bool isVectorizable(RecurKind Kind, Instruction *I) {
- if (Kind == RecurKind::None)
- return false;
- if (RecurrenceDescriptor::isIntMinMaxRecurrenceKind(Kind))
- return true;
-
- if (Kind == RecurKind::FMax || Kind == RecurKind::FMin) {
- // FP min/max are associative except for NaN and -0.0. We do not
- // have to rule out -0.0 here because the intrinsic semantics do not
- // specify a fixed result for it.
- return I->getFastMathFlags().noNaNs();
- }
-
- return I->isAssociative();
- }
-
- /// Checks if the ParentStackElem.first should be marked as a reduction
- /// operation with an extra argument or as extra argument itself.
- void markExtraArg(std::pair<Instruction *, unsigned> &ParentStackElem,
- Value *ExtraArg) {
- if (ExtraArgs.count(ParentStackElem.first)) {
- ExtraArgs[ParentStackElem.first] = nullptr;
- // We ran into something like:
- // ParentStackElem.first = ExtraArgs[ParentStackElem.first] + ExtraArg.
- // The whole ParentStackElem.first should be considered as an extra value
- // in this case.
- // Do not perform analysis of remaining operands of ParentStackElem.first
- // instruction, this whole instruction is an extra argument.
- RecurKind ParentRdxKind = getRdxKind(ParentStackElem.first);
- ParentStackElem.second = getNumberOfOperands(ParentRdxKind);
- } else {
- // We ran into something like:
- // ParentStackElem.first += ... + ExtraArg + ...
- ExtraArgs[ParentStackElem.first] = ExtraArg;
- }
- }
-
- /// Creates reduction operation with the current opcode.
- static Value *createOp(IRBuilder<> &Builder, RecurKind Kind, Value *LHS,
- Value *RHS, const Twine &Name) {
- unsigned RdxOpcode = RecurrenceDescriptor::getOpcode(Kind);
- switch (Kind) {
- case RecurKind::Add:
- case RecurKind::Mul:
- case RecurKind::Or:
- case RecurKind::And:
- case RecurKind::Xor:
- case RecurKind::FAdd:
- case RecurKind::FMul:
- return Builder.CreateBinOp((Instruction::BinaryOps)RdxOpcode, LHS, RHS,
- Name);
- case RecurKind::FMax:
- return Builder.CreateBinaryIntrinsic(Intrinsic::maxnum, LHS, RHS);
- case RecurKind::FMin:
- return Builder.CreateBinaryIntrinsic(Intrinsic::minnum, LHS, RHS);
-
- case RecurKind::SMax: {
- Value *Cmp = Builder.CreateICmpSGT(LHS, RHS, Name);
- return Builder.CreateSelect(Cmp, LHS, RHS, Name);
- }
- case RecurKind::SMin: {
- Value *Cmp = Builder.CreateICmpSLT(LHS, RHS, Name);
- return Builder.CreateSelect(Cmp, LHS, RHS, Name);
- }
- case RecurKind::UMax: {
- Value *Cmp = Builder.CreateICmpUGT(LHS, RHS, Name);
- return Builder.CreateSelect(Cmp, LHS, RHS, Name);
- }
- case RecurKind::UMin: {
- Value *Cmp = Builder.CreateICmpULT(LHS, RHS, Name);
- return Builder.CreateSelect(Cmp, LHS, RHS, Name);
- }
- default:
- llvm_unreachable("Unknown reduction operation.");
- }
- }
-
- /// Creates reduction operation with the current opcode with the IR flags
- /// from \p ReductionOps.
- static Value *createOp(IRBuilder<> &Builder, RecurKind RdxKind, Value *LHS,
- Value *RHS, const Twine &Name,
- const ReductionOpsListType &ReductionOps) {
- Value *Op = createOp(Builder, RdxKind, LHS, RHS, Name);
- if (RecurrenceDescriptor::isIntMinMaxRecurrenceKind(RdxKind)) {
- if (auto *Sel = dyn_cast<SelectInst>(Op))
- propagateIRFlags(Sel->getCondition(), ReductionOps[0]);
- propagateIRFlags(Op, ReductionOps[1]);
- return Op;
- }
- propagateIRFlags(Op, ReductionOps[0]);
- return Op;
- }
- /// Creates reduction operation with the current opcode with the IR flags
- /// from \p I.
- static Value *createOp(IRBuilder<> &Builder, RecurKind RdxKind, Value *LHS,
- Value *RHS, const Twine &Name, Instruction *I) {
- Value *Op = createOp(Builder, RdxKind, LHS, RHS, Name);
- if (RecurrenceDescriptor::isIntMinMaxRecurrenceKind(RdxKind)) {
- if (auto *Sel = dyn_cast<SelectInst>(Op)) {
- propagateIRFlags(Sel->getCondition(),
- cast<SelectInst>(I)->getCondition());
- }
- }
- propagateIRFlags(Op, I);
- return Op;
- }
-
- static RecurKind getRdxKind(Instruction *I) {
- assert(I && "Expected instruction for reduction matching");
- TargetTransformInfo::ReductionFlags RdxFlags;
- if (match(I, m_Add(m_Value(), m_Value())))
- return RecurKind::Add;
- if (match(I, m_Mul(m_Value(), m_Value())))
- return RecurKind::Mul;
- if (match(I, m_And(m_Value(), m_Value())))
- return RecurKind::And;
- if (match(I, m_Or(m_Value(), m_Value())))
- return RecurKind::Or;
- if (match(I, m_Xor(m_Value(), m_Value())))
- return RecurKind::Xor;
- if (match(I, m_FAdd(m_Value(), m_Value())))
- return RecurKind::FAdd;
- if (match(I, m_FMul(m_Value(), m_Value())))
- return RecurKind::FMul;
-
- if (match(I, m_Intrinsic<Intrinsic::maxnum>(m_Value(), m_Value())))
- return RecurKind::FMax;
- if (match(I, m_Intrinsic<Intrinsic::minnum>(m_Value(), m_Value())))
- return RecurKind::FMin;
-
- if (match(I, m_SMax(m_Value(), m_Value())))
- return RecurKind::SMax;
- if (match(I, m_SMin(m_Value(), m_Value())))
- return RecurKind::SMin;
- if (match(I, m_UMax(m_Value(), m_Value())))
- return RecurKind::UMax;
- if (match(I, m_UMin(m_Value(), m_Value())))
- return RecurKind::UMin;
-
- if (auto *Select = dyn_cast<SelectInst>(I)) {
- // Try harder: look for min/max pattern based on instructions producing
- // same values such as: select ((cmp Inst1, Inst2), Inst1, Inst2).
- // During the intermediate stages of SLP, it's very common to have
- // pattern like this (since optimizeGatherSequence is run only once
- // at the end):
- // %1 = extractelement <2 x i32> %a, i32 0
- // %2 = extractelement <2 x i32> %a, i32 1
- // %cond = icmp sgt i32 %1, %2
- // %3 = extractelement <2 x i32> %a, i32 0
- // %4 = extractelement <2 x i32> %a, i32 1
- // %select = select i1 %cond, i32 %3, i32 %4
- CmpInst::Predicate Pred;
- Instruction *L1;
- Instruction *L2;
-
- Value *LHS = Select->getTrueValue();
- Value *RHS = Select->getFalseValue();
- Value *Cond = Select->getCondition();
-
- // TODO: Support inverse predicates.
- if (match(Cond, m_Cmp(Pred, m_Specific(LHS), m_Instruction(L2)))) {
- if (!isa<ExtractElementInst>(RHS) ||
- !L2->isIdenticalTo(cast<Instruction>(RHS)))
- return RecurKind::None;
- } else if (match(Cond, m_Cmp(Pred, m_Instruction(L1), m_Specific(RHS)))) {
- if (!isa<ExtractElementInst>(LHS) ||
- !L1->isIdenticalTo(cast<Instruction>(LHS)))
- return RecurKind::None;
- } else {
- if (!isa<ExtractElementInst>(LHS) || !isa<ExtractElementInst>(RHS))
- return RecurKind::None;
- if (!match(Cond, m_Cmp(Pred, m_Instruction(L1), m_Instruction(L2))) ||
- !L1->isIdenticalTo(cast<Instruction>(LHS)) ||
- !L2->isIdenticalTo(cast<Instruction>(RHS)))
- return RecurKind::None;
- }
-
- TargetTransformInfo::ReductionFlags RdxFlags;
- switch (Pred) {
- default:
- return RecurKind::None;
- case CmpInst::ICMP_SGT:
- case CmpInst::ICMP_SGE:
- return RecurKind::SMax;
- case CmpInst::ICMP_SLT:
- case CmpInst::ICMP_SLE:
- return RecurKind::SMin;
- case CmpInst::ICMP_UGT:
- case CmpInst::ICMP_UGE:
- return RecurKind::UMax;
- case CmpInst::ICMP_ULT:
- case CmpInst::ICMP_ULE:
- return RecurKind::UMin;
- }
- }
- return RecurKind::None;
- }
-
- /// Return true if this operation is a cmp+select idiom.
- static bool isCmpSel(RecurKind Kind) {
- return RecurrenceDescriptor::isIntMinMaxRecurrenceKind(Kind);
- }
-
- /// Get the index of the first operand.
- static unsigned getFirstOperandIndex(RecurKind Kind) {
- // We allow calling this before 'Kind' is set, so handle that specially.
- if (Kind == RecurKind::None)
- return 0;
- return isCmpSel(Kind) ? 1 : 0;
- }
-
- /// Total number of operands in the reduction operation.
- static unsigned getNumberOfOperands(RecurKind Kind) {
- return isCmpSel(Kind) ? 3 : 2;
- }
-
- /// Checks if the instruction is in basic block \p BB.
- /// For a min/max reduction check that both compare and select are in \p BB.
- static bool hasSameParent(RecurKind Kind, Instruction *I, BasicBlock *BB,
- bool IsRedOp) {
- if (IsRedOp && isCmpSel(Kind)) {
- auto *Cmp = cast<Instruction>(cast<SelectInst>(I)->getCondition());
- return I->getParent() == BB && Cmp && Cmp->getParent() == BB;
- }
- return I->getParent() == BB;
- }
-
- /// Expected number of uses for reduction operations/reduced values.
- static bool hasRequiredNumberOfUses(RecurKind Kind, Instruction *I,
- bool IsReductionOp) {
- // SelectInst must be used twice while the condition op must have single
- // use only.
- if (isCmpSel(Kind))
- return I->hasNUses(2) &&
- (!IsReductionOp ||
- cast<SelectInst>(I)->getCondition()->hasOneUse());
-
- // Arithmetic reduction operation must be used once only.
- return I->hasOneUse();
- }
-
- /// Initializes the list of reduction operations.
- void initReductionOps(RecurKind Kind) {
- if (isCmpSel(Kind))
- ReductionOps.assign(2, ReductionOpsType());
- else
- ReductionOps.assign(1, ReductionOpsType());
- }
-
- /// Add all reduction operations for the reduction instruction \p I.
- void addReductionOps(RecurKind Kind, Instruction *I) {
- assert(Kind != RecurKind::None && "Expected reduction operation.");
- if (isCmpSel(Kind)) {
- ReductionOps[0].emplace_back(cast<SelectInst>(I)->getCondition());
- ReductionOps[1].emplace_back(I);
- } else {
- ReductionOps[0].emplace_back(I);
- }
- }
-
- static Value *getLHS(RecurKind Kind, Instruction *I) {
- if (Kind == RecurKind::None)
- return nullptr;
- return I->getOperand(getFirstOperandIndex(Kind));
- }
- static Value *getRHS(RecurKind Kind, Instruction *I) {
- if (Kind == RecurKind::None)
- return nullptr;
- return I->getOperand(getFirstOperandIndex(Kind) + 1);
- }
-
+ WeakTrackingVH ReductionRoot;
+ /// The type of reduction operation.
+ RecurKind RdxKind;
+
+ /// Checks if instruction is associative and can be vectorized.
+ static bool isVectorizable(RecurKind Kind, Instruction *I) {
+ if (Kind == RecurKind::None)
+ return false;
+ if (RecurrenceDescriptor::isIntMinMaxRecurrenceKind(Kind))
+ return true;
+
+ if (Kind == RecurKind::FMax || Kind == RecurKind::FMin) {
+ // FP min/max are associative except for NaN and -0.0. We do not
+ // have to rule out -0.0 here because the intrinsic semantics do not
+ // specify a fixed result for it.
+ return I->getFastMathFlags().noNaNs();
+ }
+
+ return I->isAssociative();
+ }
+
+ /// Checks if the ParentStackElem.first should be marked as a reduction
+ /// operation with an extra argument or as extra argument itself.
+ void markExtraArg(std::pair<Instruction *, unsigned> &ParentStackElem,
+ Value *ExtraArg) {
+ if (ExtraArgs.count(ParentStackElem.first)) {
+ ExtraArgs[ParentStackElem.first] = nullptr;
+ // We ran into something like:
+ // ParentStackElem.first = ExtraArgs[ParentStackElem.first] + ExtraArg.
+ // The whole ParentStackElem.first should be considered as an extra value
+ // in this case.
+ // Do not perform analysis of remaining operands of ParentStackElem.first
+ // instruction, this whole instruction is an extra argument.
+ RecurKind ParentRdxKind = getRdxKind(ParentStackElem.first);
+ ParentStackElem.second = getNumberOfOperands(ParentRdxKind);
+ } else {
+ // We ran into something like:
+ // ParentStackElem.first += ... + ExtraArg + ...
+ ExtraArgs[ParentStackElem.first] = ExtraArg;
+ }
+ }
+
+ /// Creates reduction operation with the current opcode.
+ static Value *createOp(IRBuilder<> &Builder, RecurKind Kind, Value *LHS,
+ Value *RHS, const Twine &Name) {
+ unsigned RdxOpcode = RecurrenceDescriptor::getOpcode(Kind);
+ switch (Kind) {
+ case RecurKind::Add:
+ case RecurKind::Mul:
+ case RecurKind::Or:
+ case RecurKind::And:
+ case RecurKind::Xor:
+ case RecurKind::FAdd:
+ case RecurKind::FMul:
+ return Builder.CreateBinOp((Instruction::BinaryOps)RdxOpcode, LHS, RHS,
+ Name);
+ case RecurKind::FMax:
+ return Builder.CreateBinaryIntrinsic(Intrinsic::maxnum, LHS, RHS);
+ case RecurKind::FMin:
+ return Builder.CreateBinaryIntrinsic(Intrinsic::minnum, LHS, RHS);
+
+ case RecurKind::SMax: {
+ Value *Cmp = Builder.CreateICmpSGT(LHS, RHS, Name);
+ return Builder.CreateSelect(Cmp, LHS, RHS, Name);
+ }
+ case RecurKind::SMin: {
+ Value *Cmp = Builder.CreateICmpSLT(LHS, RHS, Name);
+ return Builder.CreateSelect(Cmp, LHS, RHS, Name);
+ }
+ case RecurKind::UMax: {
+ Value *Cmp = Builder.CreateICmpUGT(LHS, RHS, Name);
+ return Builder.CreateSelect(Cmp, LHS, RHS, Name);
+ }
+ case RecurKind::UMin: {
+ Value *Cmp = Builder.CreateICmpULT(LHS, RHS, Name);
+ return Builder.CreateSelect(Cmp, LHS, RHS, Name);
+ }
+ default:
+ llvm_unreachable("Unknown reduction operation.");
+ }
+ }
+
+ /// Creates reduction operation with the current opcode with the IR flags
+ /// from \p ReductionOps.
+ static Value *createOp(IRBuilder<> &Builder, RecurKind RdxKind, Value *LHS,
+ Value *RHS, const Twine &Name,
+ const ReductionOpsListType &ReductionOps) {
+ Value *Op = createOp(Builder, RdxKind, LHS, RHS, Name);
+ if (RecurrenceDescriptor::isIntMinMaxRecurrenceKind(RdxKind)) {
+ if (auto *Sel = dyn_cast<SelectInst>(Op))
+ propagateIRFlags(Sel->getCondition(), ReductionOps[0]);
+ propagateIRFlags(Op, ReductionOps[1]);
+ return Op;
+ }
+ propagateIRFlags(Op, ReductionOps[0]);
+ return Op;
+ }
+ /// Creates reduction operation with the current opcode with the IR flags
+ /// from \p I.
+ static Value *createOp(IRBuilder<> &Builder, RecurKind RdxKind, Value *LHS,
+ Value *RHS, const Twine &Name, Instruction *I) {
+ Value *Op = createOp(Builder, RdxKind, LHS, RHS, Name);
+ if (RecurrenceDescriptor::isIntMinMaxRecurrenceKind(RdxKind)) {
+ if (auto *Sel = dyn_cast<SelectInst>(Op)) {
+ propagateIRFlags(Sel->getCondition(),
+ cast<SelectInst>(I)->getCondition());
+ }
+ }
+ propagateIRFlags(Op, I);
+ return Op;
+ }
+
+ static RecurKind getRdxKind(Instruction *I) {
+ assert(I && "Expected instruction for reduction matching");
+ TargetTransformInfo::ReductionFlags RdxFlags;
+ if (match(I, m_Add(m_Value(), m_Value())))
+ return RecurKind::Add;
+ if (match(I, m_Mul(m_Value(), m_Value())))
+ return RecurKind::Mul;
+ if (match(I, m_And(m_Value(), m_Value())))
+ return RecurKind::And;
+ if (match(I, m_Or(m_Value(), m_Value())))
+ return RecurKind::Or;
+ if (match(I, m_Xor(m_Value(), m_Value())))
+ return RecurKind::Xor;
+ if (match(I, m_FAdd(m_Value(), m_Value())))
+ return RecurKind::FAdd;
+ if (match(I, m_FMul(m_Value(), m_Value())))
+ return RecurKind::FMul;
+
+ if (match(I, m_Intrinsic<Intrinsic::maxnum>(m_Value(), m_Value())))
+ return RecurKind::FMax;
+ if (match(I, m_Intrinsic<Intrinsic::minnum>(m_Value(), m_Value())))
+ return RecurKind::FMin;
+
+ if (match(I, m_SMax(m_Value(), m_Value())))
+ return RecurKind::SMax;
+ if (match(I, m_SMin(m_Value(), m_Value())))
+ return RecurKind::SMin;
+ if (match(I, m_UMax(m_Value(), m_Value())))
+ return RecurKind::UMax;
+ if (match(I, m_UMin(m_Value(), m_Value())))
+ return RecurKind::UMin;
+
+ if (auto *Select = dyn_cast<SelectInst>(I)) {
+ // Try harder: look for min/max pattern based on instructions producing
+ // same values such as: select ((cmp Inst1, Inst2), Inst1, Inst2).
+ // During the intermediate stages of SLP, it's very common to have
+ // pattern like this (since optimizeGatherSequence is run only once
+ // at the end):
+ // %1 = extractelement <2 x i32> %a, i32 0
+ // %2 = extractelement <2 x i32> %a, i32 1
+ // %cond = icmp sgt i32 %1, %2
+ // %3 = extractelement <2 x i32> %a, i32 0
+ // %4 = extractelement <2 x i32> %a, i32 1
+ // %select = select i1 %cond, i32 %3, i32 %4
+ CmpInst::Predicate Pred;
+ Instruction *L1;
+ Instruction *L2;
+
+ Value *LHS = Select->getTrueValue();
+ Value *RHS = Select->getFalseValue();
+ Value *Cond = Select->getCondition();
+
+ // TODO: Support inverse predicates.
+ if (match(Cond, m_Cmp(Pred, m_Specific(LHS), m_Instruction(L2)))) {
+ if (!isa<ExtractElementInst>(RHS) ||
+ !L2->isIdenticalTo(cast<Instruction>(RHS)))
+ return RecurKind::None;
+ } else if (match(Cond, m_Cmp(Pred, m_Instruction(L1), m_Specific(RHS)))) {
+ if (!isa<ExtractElementInst>(LHS) ||
+ !L1->isIdenticalTo(cast<Instruction>(LHS)))
+ return RecurKind::None;
+ } else {
+ if (!isa<ExtractElementInst>(LHS) || !isa<ExtractElementInst>(RHS))
+ return RecurKind::None;
+ if (!match(Cond, m_Cmp(Pred, m_Instruction(L1), m_Instruction(L2))) ||
+ !L1->isIdenticalTo(cast<Instruction>(LHS)) ||
+ !L2->isIdenticalTo(cast<Instruction>(RHS)))
+ return RecurKind::None;
+ }
+
+ TargetTransformInfo::ReductionFlags RdxFlags;
+ switch (Pred) {
+ default:
+ return RecurKind::None;
+ case CmpInst::ICMP_SGT:
+ case CmpInst::ICMP_SGE:
+ return RecurKind::SMax;
+ case CmpInst::ICMP_SLT:
+ case CmpInst::ICMP_SLE:
+ return RecurKind::SMin;
+ case CmpInst::ICMP_UGT:
+ case CmpInst::ICMP_UGE:
+ return RecurKind::UMax;
+ case CmpInst::ICMP_ULT:
+ case CmpInst::ICMP_ULE:
+ return RecurKind::UMin;
+ }
+ }
+ return RecurKind::None;
+ }
+
+ /// Return true if this operation is a cmp+select idiom.
+ static bool isCmpSel(RecurKind Kind) {
+ return RecurrenceDescriptor::isIntMinMaxRecurrenceKind(Kind);
+ }
+
+ /// Get the index of the first operand.
+ static unsigned getFirstOperandIndex(RecurKind Kind) {
+ // We allow calling this before 'Kind' is set, so handle that specially.
+ if (Kind == RecurKind::None)
+ return 0;
+ return isCmpSel(Kind) ? 1 : 0;
+ }
+
+ /// Total number of operands in the reduction operation.
+ static unsigned getNumberOfOperands(RecurKind Kind) {
+ return isCmpSel(Kind) ? 3 : 2;
+ }
+
+ /// Checks if the instruction is in basic block \p BB.
+ /// For a min/max reduction check that both compare and select are in \p BB.
+ static bool hasSameParent(RecurKind Kind, Instruction *I, BasicBlock *BB,
+ bool IsRedOp) {
+ if (IsRedOp && isCmpSel(Kind)) {
+ auto *Cmp = cast<Instruction>(cast<SelectInst>(I)->getCondition());
+ return I->getParent() == BB && Cmp && Cmp->getParent() == BB;
+ }
+ return I->getParent() == BB;
+ }
+
+ /// Expected number of uses for reduction operations/reduced values.
+ static bool hasRequiredNumberOfUses(RecurKind Kind, Instruction *I,
+ bool IsReductionOp) {
+ // SelectInst must be used twice while the condition op must have single
+ // use only.
+ if (isCmpSel(Kind))
+ return I->hasNUses(2) &&
+ (!IsReductionOp ||
+ cast<SelectInst>(I)->getCondition()->hasOneUse());
+
+ // Arithmetic reduction operation must be used once only.
+ return I->hasOneUse();
+ }
+
+ /// Initializes the list of reduction operations.
+ void initReductionOps(RecurKind Kind) {
+ if (isCmpSel(Kind))
+ ReductionOps.assign(2, ReductionOpsType());
+ else
+ ReductionOps.assign(1, ReductionOpsType());
+ }
+
+ /// Add all reduction operations for the reduction instruction \p I.
+ void addReductionOps(RecurKind Kind, Instruction *I) {
+ assert(Kind != RecurKind::None && "Expected reduction operation.");
+ if (isCmpSel(Kind)) {
+ ReductionOps[0].emplace_back(cast<SelectInst>(I)->getCondition());
+ ReductionOps[1].emplace_back(I);
+ } else {
+ ReductionOps[0].emplace_back(I);
+ }
+ }
+
+ static Value *getLHS(RecurKind Kind, Instruction *I) {
+ if (Kind == RecurKind::None)
+ return nullptr;
+ return I->getOperand(getFirstOperandIndex(Kind));
+ }
+ static Value *getRHS(RecurKind Kind, Instruction *I) {
+ if (Kind == RecurKind::None)
+ return nullptr;
+ return I->getOperand(getFirstOperandIndex(Kind) + 1);
+ }
+
public:
HorizontalReduction() = default;
/// Try to find a reduction tree.
bool matchAssociativeReduction(PHINode *Phi, Instruction *B) {
assert((!Phi || is_contained(Phi->operands(), B)) &&
- "Phi needs to use the binary operator");
+ "Phi needs to use the binary operator");
- RdxKind = getRdxKind(B);
+ RdxKind = getRdxKind(B);
// We could have a initial reductions that is not an add.
// r *= v1 + v2 + v3 + v4
// In such a case start looking for a tree rooted in the first '+'.
if (Phi) {
- if (getLHS(RdxKind, B) == Phi) {
+ if (getLHS(RdxKind, B) == Phi) {
Phi = nullptr;
- B = dyn_cast<Instruction>(getRHS(RdxKind, B));
- if (!B)
- return false;
- RdxKind = getRdxKind(B);
- } else if (getRHS(RdxKind, B) == Phi) {
+ B = dyn_cast<Instruction>(getRHS(RdxKind, B));
+ if (!B)
+ return false;
+ RdxKind = getRdxKind(B);
+ } else if (getRHS(RdxKind, B) == Phi) {
Phi = nullptr;
- B = dyn_cast<Instruction>(getLHS(RdxKind, B));
- if (!B)
- return false;
- RdxKind = getRdxKind(B);
+ B = dyn_cast<Instruction>(getLHS(RdxKind, B));
+ if (!B)
+ return false;
+ RdxKind = getRdxKind(B);
}
}
- if (!isVectorizable(RdxKind, B))
+ if (!isVectorizable(RdxKind, B))
return false;
- // Analyze "regular" integer/FP types for reductions - no target-specific
- // types or pointers.
+ // Analyze "regular" integer/FP types for reductions - no target-specific
+ // types or pointers.
Type *Ty = B->getType();
- if (!isValidElementType(Ty) || Ty->isPointerTy())
+ if (!isValidElementType(Ty) || Ty->isPointerTy())
return false;
ReductionRoot = B;
- // The opcode for leaf values that we perform a reduction on.
- // For example: load(x) + load(y) + load(z) + fptoui(w)
- // The leaf opcode for 'w' does not match, so we don't include it as a
- // potential candidate for the reduction.
- unsigned LeafOpcode = 0;
-
+ // The opcode for leaf values that we perform a reduction on.
+ // For example: load(x) + load(y) + load(z) + fptoui(w)
+ // The leaf opcode for 'w' does not match, so we don't include it as a
+ // potential candidate for the reduction.
+ unsigned LeafOpcode = 0;
+
// Post order traverse the reduction tree starting at B. We only handle true
// trees containing only binary operators.
SmallVector<std::pair<Instruction *, unsigned>, 32> Stack;
- Stack.push_back(std::make_pair(B, getFirstOperandIndex(RdxKind)));
- initReductionOps(RdxKind);
+ Stack.push_back(std::make_pair(B, getFirstOperandIndex(RdxKind)));
+ initReductionOps(RdxKind);
while (!Stack.empty()) {
Instruction *TreeN = Stack.back().first;
- unsigned EdgeToVisit = Stack.back().second++;
- const RecurKind TreeRdxKind = getRdxKind(TreeN);
- bool IsReducedValue = TreeRdxKind != RdxKind;
+ unsigned EdgeToVisit = Stack.back().second++;
+ const RecurKind TreeRdxKind = getRdxKind(TreeN);
+ bool IsReducedValue = TreeRdxKind != RdxKind;
- // Postorder visit.
- if (IsReducedValue || EdgeToVisit == getNumberOfOperands(TreeRdxKind)) {
+ // Postorder visit.
+ if (IsReducedValue || EdgeToVisit == getNumberOfOperands(TreeRdxKind)) {
if (IsReducedValue)
ReducedVals.push_back(TreeN);
else {
@@ -6759,7 +6759,7 @@ public:
markExtraArg(Stack[Stack.size() - 2], TreeN);
ExtraArgs.erase(TreeN);
} else
- addReductionOps(RdxKind, TreeN);
+ addReductionOps(RdxKind, TreeN);
}
// Retract.
Stack.pop_back();
@@ -6767,72 +6767,72 @@ public:
}
// Visit left or right.
- Value *EdgeVal = TreeN->getOperand(EdgeToVisit);
- auto *I = dyn_cast<Instruction>(EdgeVal);
- if (!I) {
- // Edge value is not a reduction instruction or a leaf instruction.
- // (It may be a constant, function argument, or something else.)
- markExtraArg(Stack.back(), EdgeVal);
- continue;
- }
- RecurKind EdgeRdxKind = getRdxKind(I);
- // Continue analysis if the next operand is a reduction operation or
- // (possibly) a leaf value. If the leaf value opcode is not set,
- // the first met operation != reduction operation is considered as the
- // leaf opcode.
- // Only handle trees in the current basic block.
- // Each tree node needs to have minimal number of users except for the
- // ultimate reduction.
- const bool IsRdxInst = EdgeRdxKind == RdxKind;
- if (I != Phi && I != B &&
- hasSameParent(RdxKind, I, B->getParent(), IsRdxInst) &&
- hasRequiredNumberOfUses(RdxKind, I, IsRdxInst) &&
- (!LeafOpcode || LeafOpcode == I->getOpcode() || IsRdxInst)) {
- if (IsRdxInst) {
- // We need to be able to reassociate the reduction operations.
- if (!isVectorizable(EdgeRdxKind, I)) {
+ Value *EdgeVal = TreeN->getOperand(EdgeToVisit);
+ auto *I = dyn_cast<Instruction>(EdgeVal);
+ if (!I) {
+ // Edge value is not a reduction instruction or a leaf instruction.
+ // (It may be a constant, function argument, or something else.)
+ markExtraArg(Stack.back(), EdgeVal);
+ continue;
+ }
+ RecurKind EdgeRdxKind = getRdxKind(I);
+ // Continue analysis if the next operand is a reduction operation or
+ // (possibly) a leaf value. If the leaf value opcode is not set,
+ // the first met operation != reduction operation is considered as the
+ // leaf opcode.
+ // Only handle trees in the current basic block.
+ // Each tree node needs to have minimal number of users except for the
+ // ultimate reduction.
+ const bool IsRdxInst = EdgeRdxKind == RdxKind;
+ if (I != Phi && I != B &&
+ hasSameParent(RdxKind, I, B->getParent(), IsRdxInst) &&
+ hasRequiredNumberOfUses(RdxKind, I, IsRdxInst) &&
+ (!LeafOpcode || LeafOpcode == I->getOpcode() || IsRdxInst)) {
+ if (IsRdxInst) {
+ // We need to be able to reassociate the reduction operations.
+ if (!isVectorizable(EdgeRdxKind, I)) {
// I is an extra argument for TreeN (its parent operation).
markExtraArg(Stack.back(), I);
continue;
}
- } else if (!LeafOpcode) {
- LeafOpcode = I->getOpcode();
+ } else if (!LeafOpcode) {
+ LeafOpcode = I->getOpcode();
}
- Stack.push_back(std::make_pair(I, getFirstOperandIndex(EdgeRdxKind)));
- continue;
+ Stack.push_back(std::make_pair(I, getFirstOperandIndex(EdgeRdxKind)));
+ continue;
}
- // I is an extra argument for TreeN (its parent operation).
- markExtraArg(Stack.back(), I);
+ // I is an extra argument for TreeN (its parent operation).
+ markExtraArg(Stack.back(), I);
}
return true;
}
- /// Attempt to vectorize the tree found by matchAssociativeReduction.
+ /// Attempt to vectorize the tree found by matchAssociativeReduction.
bool tryToReduce(BoUpSLP &V, TargetTransformInfo *TTI) {
- // If there are a sufficient number of reduction values, reduce
- // to a nearby power-of-2. We can safely generate oversized
+ // If there are a sufficient number of reduction values, reduce
+ // to a nearby power-of-2. We can safely generate oversized
// vectors and rely on the backend to split them to legal sizes.
unsigned NumReducedVals = ReducedVals.size();
if (NumReducedVals < 4)
return false;
- // Intersect the fast-math-flags from all reduction operations.
- FastMathFlags RdxFMF;
- RdxFMF.set();
- for (ReductionOpsType &RdxOp : ReductionOps) {
- for (Value *RdxVal : RdxOp) {
- if (auto *FPMO = dyn_cast<FPMathOperator>(RdxVal))
- RdxFMF &= FPMO->getFastMathFlags();
- }
- }
+ // Intersect the fast-math-flags from all reduction operations.
+ FastMathFlags RdxFMF;
+ RdxFMF.set();
+ for (ReductionOpsType &RdxOp : ReductionOps) {
+ for (Value *RdxVal : RdxOp) {
+ if (auto *FPMO = dyn_cast<FPMathOperator>(RdxVal))
+ RdxFMF &= FPMO->getFastMathFlags();
+ }
+ }
IRBuilder<> Builder(cast<Instruction>(ReductionRoot));
- Builder.setFastMathFlags(RdxFMF);
+ Builder.setFastMathFlags(RdxFMF);
BoUpSLP::ExtraValueToDebugLocsMap ExternallyUsedValues;
- // The same extra argument may be used several times, so log each attempt
+ // The same extra argument may be used several times, so log each attempt
// to use it.
- for (const std::pair<Instruction *, Value *> &Pair : ExtraArgs) {
+ for (const std::pair<Instruction *, Value *> &Pair : ExtraArgs) {
assert(Pair.first && "DebugLoc must be set.");
ExternallyUsedValues[Pair.second].push_back(Pair.first);
}
@@ -6852,48 +6852,48 @@ public:
// so set it as externally used to prevent it from being deleted.
ExternallyUsedValues[ReductionRoot];
SmallVector<Value *, 16> IgnoreList;
- for (ReductionOpsType &RdxOp : ReductionOps)
- IgnoreList.append(RdxOp.begin(), RdxOp.end());
-
- unsigned ReduxWidth = PowerOf2Floor(NumReducedVals);
- if (NumReducedVals > ReduxWidth) {
- // In the loop below, we are building a tree based on a window of
- // 'ReduxWidth' values.
- // If the operands of those values have common traits (compare predicate,
- // constant operand, etc), then we want to group those together to
- // minimize the cost of the reduction.
-
- // TODO: This should be extended to count common operands for
- // compares and binops.
-
- // Step 1: Count the number of times each compare predicate occurs.
- SmallDenseMap<unsigned, unsigned> PredCountMap;
- for (Value *RdxVal : ReducedVals) {
- CmpInst::Predicate Pred;
- if (match(RdxVal, m_Cmp(Pred, m_Value(), m_Value())))
- ++PredCountMap[Pred];
- }
- // Step 2: Sort the values so the most common predicates come first.
- stable_sort(ReducedVals, [&PredCountMap](Value *A, Value *B) {
- CmpInst::Predicate PredA, PredB;
- if (match(A, m_Cmp(PredA, m_Value(), m_Value())) &&
- match(B, m_Cmp(PredB, m_Value(), m_Value()))) {
- return PredCountMap[PredA] > PredCountMap[PredB];
- }
- return false;
- });
- }
-
- Value *VectorizedTree = nullptr;
- unsigned i = 0;
+ for (ReductionOpsType &RdxOp : ReductionOps)
+ IgnoreList.append(RdxOp.begin(), RdxOp.end());
+
+ unsigned ReduxWidth = PowerOf2Floor(NumReducedVals);
+ if (NumReducedVals > ReduxWidth) {
+ // In the loop below, we are building a tree based on a window of
+ // 'ReduxWidth' values.
+ // If the operands of those values have common traits (compare predicate,
+ // constant operand, etc), then we want to group those together to
+ // minimize the cost of the reduction.
+
+ // TODO: This should be extended to count common operands for
+ // compares and binops.
+
+ // Step 1: Count the number of times each compare predicate occurs.
+ SmallDenseMap<unsigned, unsigned> PredCountMap;
+ for (Value *RdxVal : ReducedVals) {
+ CmpInst::Predicate Pred;
+ if (match(RdxVal, m_Cmp(Pred, m_Value(), m_Value())))
+ ++PredCountMap[Pred];
+ }
+ // Step 2: Sort the values so the most common predicates come first.
+ stable_sort(ReducedVals, [&PredCountMap](Value *A, Value *B) {
+ CmpInst::Predicate PredA, PredB;
+ if (match(A, m_Cmp(PredA, m_Value(), m_Value())) &&
+ match(B, m_Cmp(PredB, m_Value(), m_Value()))) {
+ return PredCountMap[PredA] > PredCountMap[PredB];
+ }
+ return false;
+ });
+ }
+
+ Value *VectorizedTree = nullptr;
+ unsigned i = 0;
while (i < NumReducedVals - ReduxWidth + 1 && ReduxWidth > 2) {
- ArrayRef<Value *> VL(&ReducedVals[i], ReduxWidth);
+ ArrayRef<Value *> VL(&ReducedVals[i], ReduxWidth);
V.buildTree(VL, ExternallyUsedValues, IgnoreList);
Optional<ArrayRef<unsigned>> Order = V.bestOrder();
- if (Order) {
- assert(Order->size() == VL.size() &&
- "Order size must be the same as number of vectorized "
- "instructions.");
+ if (Order) {
+ assert(Order->size() == VL.size() &&
+ "Order size must be the same as number of vectorized "
+ "instructions.");
// TODO: reorder tree nodes without tree rebuilding.
SmallVector<Value *, 4> ReorderedOps(VL.size());
llvm::transform(*Order, ReorderedOps.begin(),
@@ -6902,66 +6902,66 @@ public:
}
if (V.isTreeTinyAndNotFullyVectorizable())
break;
- if (V.isLoadCombineReductionCandidate(RdxKind))
+ if (V.isLoadCombineReductionCandidate(RdxKind))
break;
V.computeMinimumValueSizes();
// Estimate cost.
- InstructionCost TreeCost = V.getTreeCost();
- InstructionCost ReductionCost =
- getReductionCost(TTI, ReducedVals[i], ReduxWidth);
- InstructionCost Cost = TreeCost + ReductionCost;
- if (!Cost.isValid()) {
- LLVM_DEBUG(dbgs() << "Encountered invalid baseline cost.\n");
- return false;
- }
+ InstructionCost TreeCost = V.getTreeCost();
+ InstructionCost ReductionCost =
+ getReductionCost(TTI, ReducedVals[i], ReduxWidth);
+ InstructionCost Cost = TreeCost + ReductionCost;
+ if (!Cost.isValid()) {
+ LLVM_DEBUG(dbgs() << "Encountered invalid baseline cost.\n");
+ return false;
+ }
if (Cost >= -SLPCostThreshold) {
- V.getORE()->emit([&]() {
- return OptimizationRemarkMissed(SV_NAME, "HorSLPNotBeneficial",
- cast<Instruction>(VL[0]))
- << "Vectorizing horizontal reduction is possible"
- << "but not beneficial with cost " << ore::NV("Cost", Cost)
- << " and threshold "
- << ore::NV("Threshold", -SLPCostThreshold);
- });
- break;
+ V.getORE()->emit([&]() {
+ return OptimizationRemarkMissed(SV_NAME, "HorSLPNotBeneficial",
+ cast<Instruction>(VL[0]))
+ << "Vectorizing horizontal reduction is possible"
+ << "but not beneficial with cost " << ore::NV("Cost", Cost)
+ << " and threshold "
+ << ore::NV("Threshold", -SLPCostThreshold);
+ });
+ break;
}
LLVM_DEBUG(dbgs() << "SLP: Vectorizing horizontal reduction at cost:"
<< Cost << ". (HorRdx)\n");
V.getORE()->emit([&]() {
- return OptimizationRemark(SV_NAME, "VectorizedHorizontalReduction",
- cast<Instruction>(VL[0]))
- << "Vectorized horizontal reduction with cost "
- << ore::NV("Cost", Cost) << " and with tree size "
- << ore::NV("TreeSize", V.getTreeSize());
+ return OptimizationRemark(SV_NAME, "VectorizedHorizontalReduction",
+ cast<Instruction>(VL[0]))
+ << "Vectorized horizontal reduction with cost "
+ << ore::NV("Cost", Cost) << " and with tree size "
+ << ore::NV("TreeSize", V.getTreeSize());
});
// Vectorize a tree.
DebugLoc Loc = cast<Instruction>(ReducedVals[i])->getDebugLoc();
Value *VectorizedRoot = V.vectorizeTree(ExternallyUsedValues);
- // Emit a reduction. If the root is a select (min/max idiom), the insert
+ // Emit a reduction. If the root is a select (min/max idiom), the insert
// point is the compare condition of that select.
Instruction *RdxRootInst = cast<Instruction>(ReductionRoot);
- if (isCmpSel(RdxKind))
+ if (isCmpSel(RdxKind))
Builder.SetInsertPoint(getCmpForMinMaxReduction(RdxRootInst));
else
Builder.SetInsertPoint(RdxRootInst);
Value *ReducedSubTree =
emitReduction(VectorizedRoot, Builder, ReduxWidth, TTI);
-
- if (!VectorizedTree) {
- // Initialize the final value in the reduction.
- VectorizedTree = ReducedSubTree;
- } else {
- // Update the final value in the reduction.
+
+ if (!VectorizedTree) {
+ // Initialize the final value in the reduction.
+ VectorizedTree = ReducedSubTree;
+ } else {
+ // Update the final value in the reduction.
Builder.SetCurrentDebugLocation(Loc);
- VectorizedTree = createOp(Builder, RdxKind, VectorizedTree,
- ReducedSubTree, "op.rdx", ReductionOps);
- }
+ VectorizedTree = createOp(Builder, RdxKind, VectorizedTree,
+ ReducedSubTree, "op.rdx", ReductionOps);
+ }
i += ReduxWidth;
ReduxWidth = PowerOf2Floor(NumReducedVals - i);
}
@@ -6971,15 +6971,15 @@ public:
for (; i < NumReducedVals; ++i) {
auto *I = cast<Instruction>(ReducedVals[i]);
Builder.SetCurrentDebugLocation(I->getDebugLoc());
- VectorizedTree =
- createOp(Builder, RdxKind, VectorizedTree, I, "", ReductionOps);
+ VectorizedTree =
+ createOp(Builder, RdxKind, VectorizedTree, I, "", ReductionOps);
}
for (auto &Pair : ExternallyUsedValues) {
// Add each externally used value to the final reduction.
for (auto *I : Pair.second) {
Builder.SetCurrentDebugLocation(I->getDebugLoc());
- VectorizedTree = createOp(Builder, RdxKind, VectorizedTree,
- Pair.first, "op.extra", I);
+ VectorizedTree = createOp(Builder, RdxKind, VectorizedTree,
+ Pair.first, "op.extra", I);
}
}
@@ -6987,7 +6987,7 @@ public:
// select, we also have to RAUW for the compare instruction feeding the
// reduction root. That's because the original compare may have extra uses
// besides the final select of the reduction.
- if (isCmpSel(RdxKind)) {
+ if (isCmpSel(RdxKind)) {
if (auto *VecSelect = dyn_cast<SelectInst>(VectorizedTree)) {
Instruction *ScalarCmp =
getCmpForMinMaxReduction(cast<Instruction>(ReductionRoot));
@@ -7003,68 +7003,68 @@ public:
return VectorizedTree != nullptr;
}
- unsigned numReductionValues() const { return ReducedVals.size(); }
+ unsigned numReductionValues() const { return ReducedVals.size(); }
private:
/// Calculate the cost of a reduction.
- InstructionCost getReductionCost(TargetTransformInfo *TTI,
- Value *FirstReducedVal,
- unsigned ReduxWidth) {
+ InstructionCost getReductionCost(TargetTransformInfo *TTI,
+ Value *FirstReducedVal,
+ unsigned ReduxWidth) {
Type *ScalarTy = FirstReducedVal->getType();
- FixedVectorType *VectorTy = FixedVectorType::get(ScalarTy, ReduxWidth);
- InstructionCost VectorCost, ScalarCost;
- switch (RdxKind) {
- case RecurKind::Add:
- case RecurKind::Mul:
- case RecurKind::Or:
- case RecurKind::And:
- case RecurKind::Xor:
- case RecurKind::FAdd:
- case RecurKind::FMul: {
- unsigned RdxOpcode = RecurrenceDescriptor::getOpcode(RdxKind);
- VectorCost = TTI->getArithmeticReductionCost(RdxOpcode, VectorTy,
- /*IsPairwiseForm=*/false);
- ScalarCost = TTI->getArithmeticInstrCost(RdxOpcode, ScalarTy);
+ FixedVectorType *VectorTy = FixedVectorType::get(ScalarTy, ReduxWidth);
+ InstructionCost VectorCost, ScalarCost;
+ switch (RdxKind) {
+ case RecurKind::Add:
+ case RecurKind::Mul:
+ case RecurKind::Or:
+ case RecurKind::And:
+ case RecurKind::Xor:
+ case RecurKind::FAdd:
+ case RecurKind::FMul: {
+ unsigned RdxOpcode = RecurrenceDescriptor::getOpcode(RdxKind);
+ VectorCost = TTI->getArithmeticReductionCost(RdxOpcode, VectorTy,
+ /*IsPairwiseForm=*/false);
+ ScalarCost = TTI->getArithmeticInstrCost(RdxOpcode, ScalarTy);
break;
- }
- case RecurKind::FMax:
- case RecurKind::FMin: {
- auto *VecCondTy = cast<VectorType>(CmpInst::makeCmpResultType(VectorTy));
- VectorCost =
- TTI->getMinMaxReductionCost(VectorTy, VecCondTy,
- /*pairwise=*/false, /*unsigned=*/false);
- ScalarCost =
- TTI->getCmpSelInstrCost(Instruction::FCmp, ScalarTy) +
- TTI->getCmpSelInstrCost(Instruction::Select, ScalarTy,
- CmpInst::makeCmpResultType(ScalarTy));
+ }
+ case RecurKind::FMax:
+ case RecurKind::FMin: {
+ auto *VecCondTy = cast<VectorType>(CmpInst::makeCmpResultType(VectorTy));
+ VectorCost =
+ TTI->getMinMaxReductionCost(VectorTy, VecCondTy,
+ /*pairwise=*/false, /*unsigned=*/false);
+ ScalarCost =
+ TTI->getCmpSelInstrCost(Instruction::FCmp, ScalarTy) +
+ TTI->getCmpSelInstrCost(Instruction::Select, ScalarTy,
+ CmpInst::makeCmpResultType(ScalarTy));
break;
}
- case RecurKind::SMax:
- case RecurKind::SMin:
- case RecurKind::UMax:
- case RecurKind::UMin: {
- auto *VecCondTy = cast<VectorType>(CmpInst::makeCmpResultType(VectorTy));
- bool IsUnsigned =
- RdxKind == RecurKind::UMax || RdxKind == RecurKind::UMin;
- VectorCost =
- TTI->getMinMaxReductionCost(VectorTy, VecCondTy,
- /*IsPairwiseForm=*/false, IsUnsigned);
- ScalarCost =
- TTI->getCmpSelInstrCost(Instruction::ICmp, ScalarTy) +
+ case RecurKind::SMax:
+ case RecurKind::SMin:
+ case RecurKind::UMax:
+ case RecurKind::UMin: {
+ auto *VecCondTy = cast<VectorType>(CmpInst::makeCmpResultType(VectorTy));
+ bool IsUnsigned =
+ RdxKind == RecurKind::UMax || RdxKind == RecurKind::UMin;
+ VectorCost =
+ TTI->getMinMaxReductionCost(VectorTy, VecCondTy,
+ /*IsPairwiseForm=*/false, IsUnsigned);
+ ScalarCost =
+ TTI->getCmpSelInstrCost(Instruction::ICmp, ScalarTy) +
TTI->getCmpSelInstrCost(Instruction::Select, ScalarTy,
CmpInst::makeCmpResultType(ScalarTy));
break;
- }
- default:
+ }
+ default:
llvm_unreachable("Expected arithmetic or min/max reduction operation");
}
- // Scalar cost is repeated for N-1 elements.
- ScalarCost *= (ReduxWidth - 1);
- LLVM_DEBUG(dbgs() << "SLP: Adding cost " << VectorCost - ScalarCost
+ // Scalar cost is repeated for N-1 elements.
+ ScalarCost *= (ReduxWidth - 1);
+ LLVM_DEBUG(dbgs() << "SLP: Adding cost " << VectorCost - ScalarCost
<< " for reduction that starts with " << *FirstReducedVal
- << " (It is a splitting reduction)\n");
- return VectorCost - ScalarCost;
+ << " (It is a splitting reduction)\n");
+ return VectorCost - ScalarCost;
}
/// Emit a horizontal reduction of the vectorized value.
@@ -7074,142 +7074,142 @@ private:
assert(isPowerOf2_32(ReduxWidth) &&
"We only handle power-of-two reductions for now");
- return createSimpleTargetReduction(Builder, TTI, VectorizedValue, RdxKind,
- ReductionOps.back());
- }
-};
-
-} // end anonymous namespace
-
-static Optional<unsigned> getAggregateSize(Instruction *InsertInst) {
- if (auto *IE = dyn_cast<InsertElementInst>(InsertInst))
- return cast<FixedVectorType>(IE->getType())->getNumElements();
-
- unsigned AggregateSize = 1;
- auto *IV = cast<InsertValueInst>(InsertInst);
- Type *CurrentType = IV->getType();
- do {
- if (auto *ST = dyn_cast<StructType>(CurrentType)) {
- for (auto *Elt : ST->elements())
- if (Elt != ST->getElementType(0)) // check homogeneity
- return None;
- AggregateSize *= ST->getNumElements();
- CurrentType = ST->getElementType(0);
- } else if (auto *AT = dyn_cast<ArrayType>(CurrentType)) {
- AggregateSize *= AT->getNumElements();
- CurrentType = AT->getElementType();
- } else if (auto *VT = dyn_cast<FixedVectorType>(CurrentType)) {
- AggregateSize *= VT->getNumElements();
- return AggregateSize;
- } else if (CurrentType->isSingleValueType()) {
- return AggregateSize;
- } else {
- return None;
- }
- } while (true);
-}
-
-static Optional<unsigned> getOperandIndex(Instruction *InsertInst,
- unsigned OperandOffset) {
- unsigned OperandIndex = OperandOffset;
- if (auto *IE = dyn_cast<InsertElementInst>(InsertInst)) {
- if (auto *CI = dyn_cast<ConstantInt>(IE->getOperand(2))) {
- auto *VT = cast<FixedVectorType>(IE->getType());
- OperandIndex *= VT->getNumElements();
- OperandIndex += CI->getZExtValue();
- return OperandIndex;
- }
- return None;
- }
-
- auto *IV = cast<InsertValueInst>(InsertInst);
- Type *CurrentType = IV->getType();
- for (unsigned int Index : IV->indices()) {
- if (auto *ST = dyn_cast<StructType>(CurrentType)) {
- OperandIndex *= ST->getNumElements();
- CurrentType = ST->getElementType(Index);
- } else if (auto *AT = dyn_cast<ArrayType>(CurrentType)) {
- OperandIndex *= AT->getNumElements();
- CurrentType = AT->getElementType();
- } else {
- return None;
- }
- OperandIndex += Index;
- }
- return OperandIndex;
-}
-
-static bool findBuildAggregate_rec(Instruction *LastInsertInst,
- TargetTransformInfo *TTI,
- SmallVectorImpl<Value *> &BuildVectorOpds,
- SmallVectorImpl<Value *> &InsertElts,
- unsigned OperandOffset) {
- do {
- Value *InsertedOperand = LastInsertInst->getOperand(1);
- Optional<unsigned> OperandIndex =
- getOperandIndex(LastInsertInst, OperandOffset);
- if (!OperandIndex)
- return false;
- if (isa<InsertElementInst>(InsertedOperand) ||
- isa<InsertValueInst>(InsertedOperand)) {
- if (!findBuildAggregate_rec(cast<Instruction>(InsertedOperand), TTI,
- BuildVectorOpds, InsertElts, *OperandIndex))
- return false;
- } else {
- BuildVectorOpds[*OperandIndex] = InsertedOperand;
- InsertElts[*OperandIndex] = LastInsertInst;
- }
- if (isa<UndefValue>(LastInsertInst->getOperand(0)))
- return true;
- LastInsertInst = dyn_cast<Instruction>(LastInsertInst->getOperand(0));
- } while (LastInsertInst != nullptr &&
- (isa<InsertValueInst>(LastInsertInst) ||
- isa<InsertElementInst>(LastInsertInst)) &&
- LastInsertInst->hasOneUse());
- return false;
-}
-
+ return createSimpleTargetReduction(Builder, TTI, VectorizedValue, RdxKind,
+ ReductionOps.back());
+ }
+};
+
+} // end anonymous namespace
+
+static Optional<unsigned> getAggregateSize(Instruction *InsertInst) {
+ if (auto *IE = dyn_cast<InsertElementInst>(InsertInst))
+ return cast<FixedVectorType>(IE->getType())->getNumElements();
+
+ unsigned AggregateSize = 1;
+ auto *IV = cast<InsertValueInst>(InsertInst);
+ Type *CurrentType = IV->getType();
+ do {
+ if (auto *ST = dyn_cast<StructType>(CurrentType)) {
+ for (auto *Elt : ST->elements())
+ if (Elt != ST->getElementType(0)) // check homogeneity
+ return None;
+ AggregateSize *= ST->getNumElements();
+ CurrentType = ST->getElementType(0);
+ } else if (auto *AT = dyn_cast<ArrayType>(CurrentType)) {
+ AggregateSize *= AT->getNumElements();
+ CurrentType = AT->getElementType();
+ } else if (auto *VT = dyn_cast<FixedVectorType>(CurrentType)) {
+ AggregateSize *= VT->getNumElements();
+ return AggregateSize;
+ } else if (CurrentType->isSingleValueType()) {
+ return AggregateSize;
+ } else {
+ return None;
+ }
+ } while (true);
+}
+
+static Optional<unsigned> getOperandIndex(Instruction *InsertInst,
+ unsigned OperandOffset) {
+ unsigned OperandIndex = OperandOffset;
+ if (auto *IE = dyn_cast<InsertElementInst>(InsertInst)) {
+ if (auto *CI = dyn_cast<ConstantInt>(IE->getOperand(2))) {
+ auto *VT = cast<FixedVectorType>(IE->getType());
+ OperandIndex *= VT->getNumElements();
+ OperandIndex += CI->getZExtValue();
+ return OperandIndex;
+ }
+ return None;
+ }
+
+ auto *IV = cast<InsertValueInst>(InsertInst);
+ Type *CurrentType = IV->getType();
+ for (unsigned int Index : IV->indices()) {
+ if (auto *ST = dyn_cast<StructType>(CurrentType)) {
+ OperandIndex *= ST->getNumElements();
+ CurrentType = ST->getElementType(Index);
+ } else if (auto *AT = dyn_cast<ArrayType>(CurrentType)) {
+ OperandIndex *= AT->getNumElements();
+ CurrentType = AT->getElementType();
+ } else {
+ return None;
+ }
+ OperandIndex += Index;
+ }
+ return OperandIndex;
+}
+
+static bool findBuildAggregate_rec(Instruction *LastInsertInst,
+ TargetTransformInfo *TTI,
+ SmallVectorImpl<Value *> &BuildVectorOpds,
+ SmallVectorImpl<Value *> &InsertElts,
+ unsigned OperandOffset) {
+ do {
+ Value *InsertedOperand = LastInsertInst->getOperand(1);
+ Optional<unsigned> OperandIndex =
+ getOperandIndex(LastInsertInst, OperandOffset);
+ if (!OperandIndex)
+ return false;
+ if (isa<InsertElementInst>(InsertedOperand) ||
+ isa<InsertValueInst>(InsertedOperand)) {
+ if (!findBuildAggregate_rec(cast<Instruction>(InsertedOperand), TTI,
+ BuildVectorOpds, InsertElts, *OperandIndex))
+ return false;
+ } else {
+ BuildVectorOpds[*OperandIndex] = InsertedOperand;
+ InsertElts[*OperandIndex] = LastInsertInst;
+ }
+ if (isa<UndefValue>(LastInsertInst->getOperand(0)))
+ return true;
+ LastInsertInst = dyn_cast<Instruction>(LastInsertInst->getOperand(0));
+ } while (LastInsertInst != nullptr &&
+ (isa<InsertValueInst>(LastInsertInst) ||
+ isa<InsertElementInst>(LastInsertInst)) &&
+ LastInsertInst->hasOneUse());
+ return false;
+}
+
/// Recognize construction of vectors like
-/// %ra = insertelement <4 x float> poison, float %s0, i32 0
+/// %ra = insertelement <4 x float> poison, float %s0, i32 0
/// %rb = insertelement <4 x float> %ra, float %s1, i32 1
/// %rc = insertelement <4 x float> %rb, float %s2, i32 2
/// %rd = insertelement <4 x float> %rc, float %s3, i32 3
/// starting from the last insertelement or insertvalue instruction.
///
-/// Also recognize homogeneous aggregates like {<2 x float>, <2 x float>},
+/// Also recognize homogeneous aggregates like {<2 x float>, <2 x float>},
/// {{float, float}, {float, float}}, [2 x {float, float}] and so on.
/// See llvm/test/Transforms/SLPVectorizer/X86/pr42022.ll for examples.
///
/// Assume LastInsertInst is of InsertElementInst or InsertValueInst type.
///
/// \return true if it matches.
-static bool findBuildAggregate(Instruction *LastInsertInst,
- TargetTransformInfo *TTI,
+static bool findBuildAggregate(Instruction *LastInsertInst,
+ TargetTransformInfo *TTI,
SmallVectorImpl<Value *> &BuildVectorOpds,
SmallVectorImpl<Value *> &InsertElts) {
-
+
assert((isa<InsertElementInst>(LastInsertInst) ||
isa<InsertValueInst>(LastInsertInst)) &&
"Expected insertelement or insertvalue instruction!");
-
- assert((BuildVectorOpds.empty() && InsertElts.empty()) &&
- "Expected empty result vectors!");
-
- Optional<unsigned> AggregateSize = getAggregateSize(LastInsertInst);
- if (!AggregateSize)
- return false;
- BuildVectorOpds.resize(*AggregateSize);
- InsertElts.resize(*AggregateSize);
-
- if (findBuildAggregate_rec(LastInsertInst, TTI, BuildVectorOpds, InsertElts,
- 0)) {
- llvm::erase_value(BuildVectorOpds, nullptr);
- llvm::erase_value(InsertElts, nullptr);
- if (BuildVectorOpds.size() >= 2)
- return true;
- }
-
- return false;
+
+ assert((BuildVectorOpds.empty() && InsertElts.empty()) &&
+ "Expected empty result vectors!");
+
+ Optional<unsigned> AggregateSize = getAggregateSize(LastInsertInst);
+ if (!AggregateSize)
+ return false;
+ BuildVectorOpds.resize(*AggregateSize);
+ InsertElts.resize(*AggregateSize);
+
+ if (findBuildAggregate_rec(LastInsertInst, TTI, BuildVectorOpds, InsertElts,
+ 0)) {
+ llvm::erase_value(BuildVectorOpds, nullptr);
+ llvm::erase_value(InsertElts, nullptr);
+ if (BuildVectorOpds.size() >= 2)
+ return true;
+ }
+
+ return false;
}
static bool PhiTypeSorterFunc(Value *V, Value *V2) {
@@ -7267,16 +7267,16 @@ static Value *getReductionValue(const DominatorTree *DT, PHINode *P,
return nullptr;
}
-static bool matchRdxBop(Instruction *I, Value *&V0, Value *&V1) {
- if (match(I, m_BinOp(m_Value(V0), m_Value(V1))))
- return true;
- if (match(I, m_Intrinsic<Intrinsic::maxnum>(m_Value(V0), m_Value(V1))))
- return true;
- if (match(I, m_Intrinsic<Intrinsic::minnum>(m_Value(V0), m_Value(V1))))
- return true;
- return false;
-}
-
+static bool matchRdxBop(Instruction *I, Value *&V0, Value *&V1) {
+ if (match(I, m_BinOp(m_Value(V0), m_Value(V1))))
+ return true;
+ if (match(I, m_Intrinsic<Intrinsic::maxnum>(m_Value(V0), m_Value(V1))))
+ return true;
+ if (match(I, m_Intrinsic<Intrinsic::minnum>(m_Value(V0), m_Value(V1))))
+ return true;
+ return false;
+}
+
/// Attempt to reduce a horizontal reduction.
/// If it is legal to match a horizontal reduction feeding the phi node \a P
/// with reduction operators \a Root (or one of its operands) in a basic block
@@ -7316,10 +7316,10 @@ static bool tryToVectorizeHorReductionOrInstOperands(
Instruction *Inst;
unsigned Level;
std::tie(Inst, Level) = Stack.pop_back_val();
- Value *B0, *B1;
- bool IsBinop = matchRdxBop(Inst, B0, B1);
- bool IsSelect = match(Inst, m_Select(m_Value(), m_Value(), m_Value()));
- if (IsBinop || IsSelect) {
+ Value *B0, *B1;
+ bool IsBinop = matchRdxBop(Inst, B0, B1);
+ bool IsSelect = match(Inst, m_Select(m_Value(), m_Value(), m_Value()));
+ if (IsBinop || IsSelect) {
HorizontalReduction HorRdx;
if (HorRdx.matchAssociativeReduction(P, Inst)) {
if (HorRdx.tryToReduce(R, TTI)) {
@@ -7330,10 +7330,10 @@ static bool tryToVectorizeHorReductionOrInstOperands(
continue;
}
}
- if (P && IsBinop) {
- Inst = dyn_cast<Instruction>(B0);
+ if (P && IsBinop) {
+ Inst = dyn_cast<Instruction>(B0);
if (Inst == P)
- Inst = dyn_cast<Instruction>(B1);
+ Inst = dyn_cast<Instruction>(B1);
if (!Inst) {
// Set P to nullptr to avoid re-analysis of phi node in
// matchAssociativeReduction function unless this is the root node.
@@ -7366,7 +7366,7 @@ static bool tryToVectorizeHorReductionOrInstOperands(
bool SLPVectorizerPass::vectorizeRootInstruction(PHINode *P, Value *V,
BasicBlock *BB, BoUpSLP &R,
TargetTransformInfo *TTI) {
- auto *I = dyn_cast_or_null<Instruction>(V);
+ auto *I = dyn_cast_or_null<Instruction>(V);
if (!I)
return false;
@@ -7388,7 +7388,7 @@ bool SLPVectorizerPass::vectorizeInsertValueInst(InsertValueInst *IVI,
SmallVector<Value *, 16> BuildVectorOpds;
SmallVector<Value *, 16> BuildVectorInsts;
- if (!findBuildAggregate(IVI, TTI, BuildVectorOpds, BuildVectorInsts))
+ if (!findBuildAggregate(IVI, TTI, BuildVectorOpds, BuildVectorInsts))
return false;
LLVM_DEBUG(dbgs() << "SLP: array mappable to vector: " << *IVI << "\n");
@@ -7475,7 +7475,7 @@ bool SLPVectorizerPass::vectorizeChainsInBlock(BasicBlock *BB, BoUpSLP &R) {
// Look for the next elements with the same type.
SmallVector<Value *, 4>::iterator SameTypeIt = IncIt;
while (SameTypeIt != E &&
- (*SameTypeIt)->getType() == (*IncIt)->getType()) {
+ (*SameTypeIt)->getType() == (*IncIt)->getType()) {
VisitedInstrs.insert(*SameTypeIt);
++SameTypeIt;
}
@@ -7507,17 +7507,17 @@ bool SLPVectorizerPass::vectorizeChainsInBlock(BasicBlock *BB, BoUpSLP &R) {
SmallVector<Instruction *, 8> PostProcessInstructions;
SmallDenseSet<Instruction *, 4> KeyNodes;
for (BasicBlock::iterator it = BB->begin(), e = BB->end(); it != e; ++it) {
- // Skip instructions with scalable type. The num of elements is unknown at
- // compile-time for scalable type.
- if (isa<ScalableVectorType>(it->getType()))
- continue;
-
+ // Skip instructions with scalable type. The num of elements is unknown at
+ // compile-time for scalable type.
+ if (isa<ScalableVectorType>(it->getType()))
+ continue;
+
// Skip instructions marked for the deletion.
if (R.isDeleted(&*it))
continue;
// We may go through BB multiple times so skip the one we have checked.
if (!VisitedInstrs.insert(&*it).second) {
- if (it->use_empty() && KeyNodes.contains(&*it) &&
+ if (it->use_empty() && KeyNodes.contains(&*it) &&
vectorizeSimpleInstructions(PostProcessInstructions, BB, R)) {
// We would like to start over since some instructions are deleted
// and the iterator may become invalid value.
@@ -7534,29 +7534,29 @@ bool SLPVectorizerPass::vectorizeChainsInBlock(BasicBlock *BB, BoUpSLP &R) {
// Try to vectorize reductions that use PHINodes.
if (PHINode *P = dyn_cast<PHINode>(it)) {
// Check that the PHI is a reduction PHI.
- if (P->getNumIncomingValues() == 2) {
- // Try to match and vectorize a horizontal reduction.
- if (vectorizeRootInstruction(P, getReductionValue(DT, P, BB, LI), BB, R,
- TTI)) {
- Changed = true;
- it = BB->begin();
- e = BB->end();
- continue;
- }
- }
- // Try to vectorize the incoming values of the PHI, to catch reductions
- // that feed into PHIs.
- for (unsigned I = 0, E = P->getNumIncomingValues(); I != E; I++) {
- // Skip if the incoming block is the current BB for now. Also, bypass
- // unreachable IR for efficiency and to avoid crashing.
- // TODO: Collect the skipped incoming values and try to vectorize them
- // after processing BB.
- if (BB == P->getIncomingBlock(I) ||
- !DT->isReachableFromEntry(P->getIncomingBlock(I)))
- continue;
-
- Changed |= vectorizeRootInstruction(nullptr, P->getIncomingValue(I),
- P->getIncomingBlock(I), R, TTI);
+ if (P->getNumIncomingValues() == 2) {
+ // Try to match and vectorize a horizontal reduction.
+ if (vectorizeRootInstruction(P, getReductionValue(DT, P, BB, LI), BB, R,
+ TTI)) {
+ Changed = true;
+ it = BB->begin();
+ e = BB->end();
+ continue;
+ }
+ }
+ // Try to vectorize the incoming values of the PHI, to catch reductions
+ // that feed into PHIs.
+ for (unsigned I = 0, E = P->getNumIncomingValues(); I != E; I++) {
+ // Skip if the incoming block is the current BB for now. Also, bypass
+ // unreachable IR for efficiency and to avoid crashing.
+ // TODO: Collect the skipped incoming values and try to vectorize them
+ // after processing BB.
+ if (BB == P->getIncomingBlock(I) ||
+ !DT->isReachableFromEntry(P->getIncomingBlock(I)))
+ continue;
+
+ Changed |= vectorizeRootInstruction(nullptr, P->getIncomingValue(I),
+ P->getIncomingBlock(I), R, TTI);
}
continue;
}
@@ -7620,7 +7620,7 @@ bool SLPVectorizerPass::vectorizeGEPIndices(BasicBlock *BB, BoUpSLP &R) {
unsigned MaxElts = MaxVecRegSize / EltSize;
for (unsigned BI = 0, BE = Entry.second.size(); BI < BE; BI += MaxElts) {
auto Len = std::min<unsigned>(BE - BI, MaxElts);
- ArrayRef<GetElementPtrInst *> GEPList(&Entry.second[BI], Len);
+ ArrayRef<GetElementPtrInst *> GEPList(&Entry.second[BI], Len);
// Initialize a set a candidate getelementptrs. Note that we use a
// SetVector here to preserve program order. If the index computations
diff --git a/contrib/libs/llvm12/lib/Transforms/Vectorize/VPRecipeBuilder.h b/contrib/libs/llvm12/lib/Transforms/Vectorize/VPRecipeBuilder.h
index dd33853d34..8737016760 100644
--- a/contrib/libs/llvm12/lib/Transforms/Vectorize/VPRecipeBuilder.h
+++ b/contrib/libs/llvm12/lib/Transforms/Vectorize/VPRecipeBuilder.h
@@ -61,19 +61,19 @@ class VPRecipeBuilder {
/// Check if the load or store instruction \p I should widened for \p
/// Range.Start and potentially masked. Such instructions are handled by a
/// recipe that takes an additional VPInstruction for the mask.
- VPRecipeBase *tryToWidenMemory(Instruction *I, VFRange &Range,
- VPlanPtr &Plan);
+ VPRecipeBase *tryToWidenMemory(Instruction *I, VFRange &Range,
+ VPlanPtr &Plan);
/// Check if an induction recipe should be constructed for \I. If so build and
/// return it. If not, return null.
- VPWidenIntOrFpInductionRecipe *tryToOptimizeInductionPHI(PHINode *Phi,
- VPlan &Plan) const;
+ VPWidenIntOrFpInductionRecipe *tryToOptimizeInductionPHI(PHINode *Phi,
+ VPlan &Plan) const;
/// Optimize the special case where the operand of \p I is a constant integer
/// induction variable.
VPWidenIntOrFpInductionRecipe *
- tryToOptimizeInductionTruncate(TruncInst *I, VFRange &Range,
- VPlan &Plan) const;
+ tryToOptimizeInductionTruncate(TruncInst *I, VFRange &Range,
+ VPlan &Plan) const;
/// Handle non-loop phi nodes. Currently all such phi nodes are turned into
/// a sequence of select instructions as the vectorizer currently performs
diff --git a/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlan.cpp b/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlan.cpp
index e65b4ea4a7..b26399e0ae 100644
--- a/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlan.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlan.cpp
@@ -20,10 +20,10 @@
#include "VPlanDominatorTree.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/PostOrderIterator.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/Analysis/IVDescriptors.h"
+#include "llvm/Analysis/IVDescriptors.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
@@ -58,69 +58,69 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const VPValue &V) {
return OS;
}
-VPValue::VPValue(const unsigned char SC, Value *UV, VPDef *Def)
- : SubclassID(SC), UnderlyingVal(UV), Def(Def) {
- if (Def)
- Def->addDefinedValue(this);
-}
-
-VPValue::~VPValue() {
- assert(Users.empty() && "trying to delete a VPValue with remaining users");
- if (Def)
- Def->removeDefinedValue(this);
-}
-
+VPValue::VPValue(const unsigned char SC, Value *UV, VPDef *Def)
+ : SubclassID(SC), UnderlyingVal(UV), Def(Def) {
+ if (Def)
+ Def->addDefinedValue(this);
+}
+
+VPValue::~VPValue() {
+ assert(Users.empty() && "trying to delete a VPValue with remaining users");
+ if (Def)
+ Def->removeDefinedValue(this);
+}
+
void VPValue::print(raw_ostream &OS, VPSlotTracker &SlotTracker) const {
- if (const VPRecipeBase *R = dyn_cast_or_null<VPRecipeBase>(Def))
- R->print(OS, "", SlotTracker);
+ if (const VPRecipeBase *R = dyn_cast_or_null<VPRecipeBase>(Def))
+ R->print(OS, "", SlotTracker);
else
printAsOperand(OS, SlotTracker);
}
-void VPValue::dump() const {
- const VPRecipeBase *Instr = dyn_cast_or_null<VPRecipeBase>(this->Def);
- VPSlotTracker SlotTracker(
- (Instr && Instr->getParent()) ? Instr->getParent()->getPlan() : nullptr);
- print(dbgs(), SlotTracker);
- dbgs() << "\n";
-}
-
-void VPDef::dump() const {
- const VPRecipeBase *Instr = dyn_cast_or_null<VPRecipeBase>(this);
- VPSlotTracker SlotTracker(
- (Instr && Instr->getParent()) ? Instr->getParent()->getPlan() : nullptr);
- print(dbgs(), "", SlotTracker);
- dbgs() << "\n";
-}
-
-VPUser *VPRecipeBase::toVPUser() {
- if (auto *U = dyn_cast<VPInstruction>(this))
- return U;
- if (auto *U = dyn_cast<VPWidenRecipe>(this))
- return U;
- if (auto *U = dyn_cast<VPWidenCallRecipe>(this))
- return U;
- if (auto *U = dyn_cast<VPWidenSelectRecipe>(this))
- return U;
- if (auto *U = dyn_cast<VPWidenGEPRecipe>(this))
- return U;
- if (auto *U = dyn_cast<VPBlendRecipe>(this))
- return U;
- if (auto *U = dyn_cast<VPInterleaveRecipe>(this))
- return U;
- if (auto *U = dyn_cast<VPReplicateRecipe>(this))
- return U;
- if (auto *U = dyn_cast<VPBranchOnMaskRecipe>(this))
- return U;
- if (auto *U = dyn_cast<VPWidenMemoryInstructionRecipe>(this))
- return U;
- if (auto *U = dyn_cast<VPReductionRecipe>(this))
- return U;
- if (auto *U = dyn_cast<VPPredInstPHIRecipe>(this))
- return U;
- return nullptr;
-}
-
+void VPValue::dump() const {
+ const VPRecipeBase *Instr = dyn_cast_or_null<VPRecipeBase>(this->Def);
+ VPSlotTracker SlotTracker(
+ (Instr && Instr->getParent()) ? Instr->getParent()->getPlan() : nullptr);
+ print(dbgs(), SlotTracker);
+ dbgs() << "\n";
+}
+
+void VPDef::dump() const {
+ const VPRecipeBase *Instr = dyn_cast_or_null<VPRecipeBase>(this);
+ VPSlotTracker SlotTracker(
+ (Instr && Instr->getParent()) ? Instr->getParent()->getPlan() : nullptr);
+ print(dbgs(), "", SlotTracker);
+ dbgs() << "\n";
+}
+
+VPUser *VPRecipeBase::toVPUser() {
+ if (auto *U = dyn_cast<VPInstruction>(this))
+ return U;
+ if (auto *U = dyn_cast<VPWidenRecipe>(this))
+ return U;
+ if (auto *U = dyn_cast<VPWidenCallRecipe>(this))
+ return U;
+ if (auto *U = dyn_cast<VPWidenSelectRecipe>(this))
+ return U;
+ if (auto *U = dyn_cast<VPWidenGEPRecipe>(this))
+ return U;
+ if (auto *U = dyn_cast<VPBlendRecipe>(this))
+ return U;
+ if (auto *U = dyn_cast<VPInterleaveRecipe>(this))
+ return U;
+ if (auto *U = dyn_cast<VPReplicateRecipe>(this))
+ return U;
+ if (auto *U = dyn_cast<VPBranchOnMaskRecipe>(this))
+ return U;
+ if (auto *U = dyn_cast<VPWidenMemoryInstructionRecipe>(this))
+ return U;
+ if (auto *U = dyn_cast<VPReductionRecipe>(this))
+ return U;
+ if (auto *U = dyn_cast<VPPredInstPHIRecipe>(this))
+ return U;
+ return nullptr;
+}
+
// Get the top-most entry block of \p Start. This is the entry block of the
// containing VPlan. This function is templated to support both const and non-const blocks
template <typename T> static T *getPlanEntry(T *Start) {
@@ -200,43 +200,43 @@ VPBlockBase *VPBlockBase::getEnclosingBlockWithPredecessors() {
}
void VPBlockBase::deleteCFG(VPBlockBase *Entry) {
- SmallVector<VPBlockBase *, 8> Blocks(depth_first(Entry));
+ SmallVector<VPBlockBase *, 8> Blocks(depth_first(Entry));
for (VPBlockBase *Block : Blocks)
delete Block;
}
-VPBasicBlock::iterator VPBasicBlock::getFirstNonPhi() {
- iterator It = begin();
- while (It != end() && (isa<VPWidenPHIRecipe>(&*It) ||
- isa<VPWidenIntOrFpInductionRecipe>(&*It) ||
- isa<VPPredInstPHIRecipe>(&*It) ||
- isa<VPWidenCanonicalIVRecipe>(&*It)))
- It++;
- return It;
-}
-
-Value *VPTransformState::get(VPValue *Def, const VPIteration &Instance) {
- if (!Def->getDef() && OrigLoop->isLoopInvariant(Def->getLiveInIRValue()))
- return Def->getLiveInIRValue();
-
- if (hasScalarValue(Def, Instance))
- return Data.PerPartScalars[Def][Instance.Part][Instance.Lane];
-
- if (hasVectorValue(Def, Instance.Part)) {
- assert(Data.PerPartOutput.count(Def));
- auto *VecPart = Data.PerPartOutput[Def][Instance.Part];
- if (!VecPart->getType()->isVectorTy()) {
- assert(Instance.Lane == 0 && "cannot get lane > 0 for scalar");
- return VecPart;
- }
- // TODO: Cache created scalar values.
- return Builder.CreateExtractElement(VecPart,
- Builder.getInt32(Instance.Lane));
- }
- return Callback.getOrCreateScalarValue(VPValue2Value[Def], Instance);
-}
-
+VPBasicBlock::iterator VPBasicBlock::getFirstNonPhi() {
+ iterator It = begin();
+ while (It != end() && (isa<VPWidenPHIRecipe>(&*It) ||
+ isa<VPWidenIntOrFpInductionRecipe>(&*It) ||
+ isa<VPPredInstPHIRecipe>(&*It) ||
+ isa<VPWidenCanonicalIVRecipe>(&*It)))
+ It++;
+ return It;
+}
+
+Value *VPTransformState::get(VPValue *Def, const VPIteration &Instance) {
+ if (!Def->getDef() && OrigLoop->isLoopInvariant(Def->getLiveInIRValue()))
+ return Def->getLiveInIRValue();
+
+ if (hasScalarValue(Def, Instance))
+ return Data.PerPartScalars[Def][Instance.Part][Instance.Lane];
+
+ if (hasVectorValue(Def, Instance.Part)) {
+ assert(Data.PerPartOutput.count(Def));
+ auto *VecPart = Data.PerPartOutput[Def][Instance.Part];
+ if (!VecPart->getType()->isVectorTy()) {
+ assert(Instance.Lane == 0 && "cannot get lane > 0 for scalar");
+ return VecPart;
+ }
+ // TODO: Cache created scalar values.
+ return Builder.CreateExtractElement(VecPart,
+ Builder.getInt32(Instance.Lane));
+ }
+ return Callback.getOrCreateScalarValue(VPValue2Value[Def], Instance);
+}
+
BasicBlock *
VPBasicBlock::createEmptyBasicBlock(VPTransformState::CFGState &CFG) {
// BB stands for IR BasicBlocks. VPBB stands for VPlan VPBasicBlocks.
@@ -354,24 +354,24 @@ void VPBasicBlock::execute(VPTransformState *State) {
LLVM_DEBUG(dbgs() << "LV: filled BB:" << *NewBB);
}
-void VPBasicBlock::dropAllReferences(VPValue *NewValue) {
- for (VPRecipeBase &R : Recipes) {
- for (auto *Def : R.definedValues())
- Def->replaceAllUsesWith(NewValue);
-
- if (auto *User = R.toVPUser())
- for (unsigned I = 0, E = User->getNumOperands(); I != E; I++)
- User->setOperand(I, NewValue);
- }
-}
-
-void VPRegionBlock::dropAllReferences(VPValue *NewValue) {
- for (VPBlockBase *Block : depth_first(Entry))
- // Drop all references in VPBasicBlocks and replace all uses with
- // DummyValue.
- Block->dropAllReferences(NewValue);
-}
-
+void VPBasicBlock::dropAllReferences(VPValue *NewValue) {
+ for (VPRecipeBase &R : Recipes) {
+ for (auto *Def : R.definedValues())
+ Def->replaceAllUsesWith(NewValue);
+
+ if (auto *User = R.toVPUser())
+ for (unsigned I = 0, E = User->getNumOperands(); I != E; I++)
+ User->setOperand(I, NewValue);
+ }
+}
+
+void VPRegionBlock::dropAllReferences(VPValue *NewValue) {
+ for (VPBlockBase *Block : depth_first(Entry))
+ // Drop all references in VPBasicBlocks and replace all uses with
+ // DummyValue.
+ Block->dropAllReferences(NewValue);
+}
+
void VPRegionBlock::execute(VPTransformState *State) {
ReversePostOrderTraversal<VPBlockBase *> RPOT(Entry);
@@ -405,9 +405,9 @@ void VPRegionBlock::execute(VPTransformState *State) {
for (unsigned Part = 0, UF = State->UF; Part < UF; ++Part) {
State->Instance->Part = Part;
- assert(!State->VF.isScalable() && "VF is assumed to be non scalable.");
- for (unsigned Lane = 0, VF = State->VF.getKnownMinValue(); Lane < VF;
- ++Lane) {
+ assert(!State->VF.isScalable() && "VF is assumed to be non scalable.");
+ for (unsigned Lane = 0, VF = State->VF.getKnownMinValue(); Lane < VF;
+ ++Lane) {
State->Instance->Lane = Lane;
// Visit the VPBlocks connected to \p this, starting from it.
for (VPBlockBase *Block : RPOT) {
@@ -453,14 +453,14 @@ void VPRecipeBase::moveAfter(VPRecipeBase *InsertPos) {
insertAfter(InsertPos);
}
-void VPRecipeBase::moveBefore(VPBasicBlock &BB,
- iplist<VPRecipeBase>::iterator I) {
- assert(I == BB.end() || I->getParent() == &BB);
- removeFromParent();
- Parent = &BB;
- BB.getRecipeList().insert(I, this);
-}
-
+void VPRecipeBase::moveBefore(VPBasicBlock &BB,
+ iplist<VPRecipeBase>::iterator I) {
+ assert(I == BB.end() || I->getParent() == &BB);
+ removeFromParent();
+ Parent = &BB;
+ BB.getRecipeList().insert(I, this);
+}
+
void VPInstruction::generateInstruction(VPTransformState &State,
unsigned Part) {
IRBuilder<> &Builder = State.Builder;
@@ -498,14 +498,14 @@ void VPInstruction::generateInstruction(VPTransformState &State,
case VPInstruction::ActiveLaneMask: {
// Get first lane of vector induction variable.
Value *VIVElem0 = State.get(getOperand(0), {Part, 0});
- // Get the original loop tripcount.
- Value *ScalarTC = State.TripCount;
+ // Get the original loop tripcount.
+ Value *ScalarTC = State.TripCount;
auto *Int1Ty = Type::getInt1Ty(Builder.getContext());
- auto *PredTy = FixedVectorType::get(Int1Ty, State.VF.getKnownMinValue());
+ auto *PredTy = FixedVectorType::get(Int1Ty, State.VF.getKnownMinValue());
Instruction *Call = Builder.CreateIntrinsic(
- Intrinsic::get_active_lane_mask, {PredTy, ScalarTC->getType()},
- {VIVElem0, ScalarTC}, nullptr, "active.lane.mask");
+ Intrinsic::get_active_lane_mask, {PredTy, ScalarTC->getType()},
+ {VIVElem0, ScalarTC}, nullptr, "active.lane.mask");
State.set(this, Call, Part);
break;
}
@@ -520,14 +520,14 @@ void VPInstruction::execute(VPTransformState &State) {
generateInstruction(State, Part);
}
-void VPInstruction::dump() const {
- VPSlotTracker SlotTracker(getParent()->getPlan());
- print(dbgs(), "", SlotTracker);
-}
-
+void VPInstruction::dump() const {
+ VPSlotTracker SlotTracker(getParent()->getPlan());
+ print(dbgs(), "", SlotTracker);
+}
+
void VPInstruction::print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const {
- O << "EMIT ";
+ O << "EMIT ";
if (hasResult()) {
printAsOperand(O, SlotTracker);
@@ -573,7 +573,7 @@ void VPlan::execute(VPTransformState *State) {
"trip.count.minus.1");
auto VF = State->VF;
Value *VTCMO =
- VF.isScalar() ? TCMO : Builder.CreateVectorSplat(VF, TCMO, "broadcast");
+ VF.isScalar() ? TCMO : Builder.CreateVectorSplat(VF, TCMO, "broadcast");
for (unsigned Part = 0, UF = State->UF; Part < UF; ++Part)
State->set(BackedgeTakenCount, VTCMO, Part);
}
@@ -778,7 +778,7 @@ void VPlanPrinter::dumpBasicBlock(const VPBasicBlock *BasicBlock) {
// Dump the block predicate.
const VPValue *Pred = BasicBlock->getPredicate();
if (Pred) {
- OS << " +\n" << Indent << " \"BlockPredicate: \"";
+ OS << " +\n" << Indent << " \"BlockPredicate: \"";
if (const VPInstruction *PredI = dyn_cast<VPInstruction>(Pred)) {
PredI->printAsOperand(OS, SlotTracker);
OS << " (" << DOT::EscapeString(PredI->getParent()->getName())
@@ -788,7 +788,7 @@ void VPlanPrinter::dumpBasicBlock(const VPBasicBlock *BasicBlock) {
}
for (const VPRecipeBase &Recipe : *BasicBlock) {
- OS << " +\n" << Indent << "\"";
+ OS << " +\n" << Indent << "\"";
Recipe.print(OS, Indent, SlotTracker);
OS << "\\l\"";
}
@@ -827,7 +827,7 @@ void VPlanPrinter::dumpRegion(const VPRegionBlock *Region) {
dumpEdges(Region);
}
-void VPlanPrinter::printAsIngredient(raw_ostream &O, const Value *V) {
+void VPlanPrinter::printAsIngredient(raw_ostream &O, const Value *V) {
std::string IngredientString;
raw_string_ostream RSO(IngredientString);
if (auto *Inst = dyn_cast<Instruction>(V)) {
@@ -850,45 +850,45 @@ void VPlanPrinter::printAsIngredient(raw_ostream &O, const Value *V) {
void VPWidenCallRecipe::print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const {
- O << "WIDEN-CALL ";
-
- auto *CI = cast<CallInst>(getUnderlyingInstr());
- if (CI->getType()->isVoidTy())
- O << "void ";
- else {
- printAsOperand(O, SlotTracker);
- O << " = ";
- }
-
- O << "call @" << CI->getCalledFunction()->getName() << "(";
- printOperands(O, SlotTracker);
- O << ")";
+ O << "WIDEN-CALL ";
+
+ auto *CI = cast<CallInst>(getUnderlyingInstr());
+ if (CI->getType()->isVoidTy())
+ O << "void ";
+ else {
+ printAsOperand(O, SlotTracker);
+ O << " = ";
+ }
+
+ O << "call @" << CI->getCalledFunction()->getName() << "(";
+ printOperands(O, SlotTracker);
+ O << ")";
}
void VPWidenSelectRecipe::print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const {
- O << "WIDEN-SELECT ";
- printAsOperand(O, SlotTracker);
- O << " = select ";
- getOperand(0)->printAsOperand(O, SlotTracker);
- O << ", ";
- getOperand(1)->printAsOperand(O, SlotTracker);
- O << ", ";
- getOperand(2)->printAsOperand(O, SlotTracker);
- O << (InvariantCond ? " (condition is loop invariant)" : "");
+ O << "WIDEN-SELECT ";
+ printAsOperand(O, SlotTracker);
+ O << " = select ";
+ getOperand(0)->printAsOperand(O, SlotTracker);
+ O << ", ";
+ getOperand(1)->printAsOperand(O, SlotTracker);
+ O << ", ";
+ getOperand(2)->printAsOperand(O, SlotTracker);
+ O << (InvariantCond ? " (condition is loop invariant)" : "");
}
void VPWidenRecipe::print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const {
- O << "WIDEN ";
- printAsOperand(O, SlotTracker);
- O << " = " << getUnderlyingInstr()->getOpcodeName() << " ";
- printOperands(O, SlotTracker);
+ O << "WIDEN ";
+ printAsOperand(O, SlotTracker);
+ O << " = " << getUnderlyingInstr()->getOpcodeName() << " ";
+ printOperands(O, SlotTracker);
}
void VPWidenIntOrFpInductionRecipe::print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const {
- O << "WIDEN-INDUCTION";
+ O << "WIDEN-INDUCTION";
if (Trunc) {
O << "\\l\"";
O << " +\n" << Indent << "\" " << VPlanIngredient(IV) << "\\l\"";
@@ -899,26 +899,26 @@ void VPWidenIntOrFpInductionRecipe::print(raw_ostream &O, const Twine &Indent,
void VPWidenGEPRecipe::print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const {
- O << "WIDEN-GEP ";
+ O << "WIDEN-GEP ";
O << (IsPtrLoopInvariant ? "Inv" : "Var");
size_t IndicesNumber = IsIndexLoopInvariant.size();
for (size_t I = 0; I < IndicesNumber; ++I)
O << "[" << (IsIndexLoopInvariant[I] ? "Inv" : "Var") << "]";
-
- O << " ";
- printAsOperand(O, SlotTracker);
- O << " = getelementptr ";
- printOperands(O, SlotTracker);
+
+ O << " ";
+ printAsOperand(O, SlotTracker);
+ O << " = getelementptr ";
+ printOperands(O, SlotTracker);
}
void VPWidenPHIRecipe::print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const {
- O << "WIDEN-PHI " << VPlanIngredient(Phi);
+ O << "WIDEN-PHI " << VPlanIngredient(Phi);
}
void VPBlendRecipe::print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const {
- O << "BLEND ";
+ O << "BLEND ";
Phi->printAsOperand(O, false);
O << " =";
if (getNumIncomingValues() == 1) {
@@ -936,75 +936,75 @@ void VPBlendRecipe::print(raw_ostream &O, const Twine &Indent,
}
}
-void VPReductionRecipe::print(raw_ostream &O, const Twine &Indent,
- VPSlotTracker &SlotTracker) const {
- O << "REDUCE ";
- printAsOperand(O, SlotTracker);
- O << " = ";
- getChainOp()->printAsOperand(O, SlotTracker);
- O << " + reduce." << Instruction::getOpcodeName(RdxDesc->getOpcode())
- << " (";
- getVecOp()->printAsOperand(O, SlotTracker);
- if (getCondOp()) {
- O << ", ";
- getCondOp()->printAsOperand(O, SlotTracker);
- }
- O << ")";
-}
-
+void VPReductionRecipe::print(raw_ostream &O, const Twine &Indent,
+ VPSlotTracker &SlotTracker) const {
+ O << "REDUCE ";
+ printAsOperand(O, SlotTracker);
+ O << " = ";
+ getChainOp()->printAsOperand(O, SlotTracker);
+ O << " + reduce." << Instruction::getOpcodeName(RdxDesc->getOpcode())
+ << " (";
+ getVecOp()->printAsOperand(O, SlotTracker);
+ if (getCondOp()) {
+ O << ", ";
+ getCondOp()->printAsOperand(O, SlotTracker);
+ }
+ O << ")";
+}
+
void VPReplicateRecipe::print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const {
- O << (IsUniform ? "CLONE " : "REPLICATE ");
-
- if (!getUnderlyingInstr()->getType()->isVoidTy()) {
- printAsOperand(O, SlotTracker);
- O << " = ";
- }
- O << Instruction::getOpcodeName(getUnderlyingInstr()->getOpcode()) << " ";
- printOperands(O, SlotTracker);
-
+ O << (IsUniform ? "CLONE " : "REPLICATE ");
+
+ if (!getUnderlyingInstr()->getType()->isVoidTy()) {
+ printAsOperand(O, SlotTracker);
+ O << " = ";
+ }
+ O << Instruction::getOpcodeName(getUnderlyingInstr()->getOpcode()) << " ";
+ printOperands(O, SlotTracker);
+
if (AlsoPack)
O << " (S->V)";
}
void VPPredInstPHIRecipe::print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const {
- O << "PHI-PREDICATED-INSTRUCTION ";
- printOperands(O, SlotTracker);
+ O << "PHI-PREDICATED-INSTRUCTION ";
+ printOperands(O, SlotTracker);
}
void VPWidenMemoryInstructionRecipe::print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const {
- O << "WIDEN ";
-
- if (!isStore()) {
- getVPValue()->printAsOperand(O, SlotTracker);
- O << " = ";
+ O << "WIDEN ";
+
+ if (!isStore()) {
+ getVPValue()->printAsOperand(O, SlotTracker);
+ O << " = ";
}
- O << Instruction::getOpcodeName(Ingredient.getOpcode()) << " ";
-
- printOperands(O, SlotTracker);
+ O << Instruction::getOpcodeName(Ingredient.getOpcode()) << " ";
+
+ printOperands(O, SlotTracker);
}
void VPWidenCanonicalIVRecipe::execute(VPTransformState &State) {
Value *CanonicalIV = State.CanonicalIV;
Type *STy = CanonicalIV->getType();
IRBuilder<> Builder(State.CFG.PrevBB->getTerminator());
- ElementCount VF = State.VF;
- assert(!VF.isScalable() && "the code following assumes non scalables ECs");
- Value *VStart = VF.isScalar()
+ ElementCount VF = State.VF;
+ assert(!VF.isScalable() && "the code following assumes non scalables ECs");
+ Value *VStart = VF.isScalar()
? CanonicalIV
- : Builder.CreateVectorSplat(VF.getKnownMinValue(),
- CanonicalIV, "broadcast");
+ : Builder.CreateVectorSplat(VF.getKnownMinValue(),
+ CanonicalIV, "broadcast");
for (unsigned Part = 0, UF = State.UF; Part < UF; ++Part) {
SmallVector<Constant *, 8> Indices;
- for (unsigned Lane = 0; Lane < VF.getKnownMinValue(); ++Lane)
- Indices.push_back(
- ConstantInt::get(STy, Part * VF.getKnownMinValue() + Lane));
+ for (unsigned Lane = 0; Lane < VF.getKnownMinValue(); ++Lane)
+ Indices.push_back(
+ ConstantInt::get(STy, Part * VF.getKnownMinValue() + Lane));
// If VF == 1, there is only one iteration in the loop above, thus the
// element pushed back into Indices is ConstantInt::get(STy, Part)
- Constant *VStep =
- VF.isScalar() ? Indices.back() : ConstantVector::get(Indices);
+ Constant *VStep =
+ VF.isScalar() ? Indices.back() : ConstantVector::get(Indices);
// Add the consecutive indices to the vector value.
Value *CanonicalVectorIV = Builder.CreateAdd(VStart, VStep, "vec.iv");
State.set(getVPValue(), CanonicalVectorIV, Part);
@@ -1013,7 +1013,7 @@ void VPWidenCanonicalIVRecipe::execute(VPTransformState &State) {
void VPWidenCanonicalIVRecipe::print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const {
- O << "EMIT ";
+ O << "EMIT ";
getVPValue()->printAsOperand(O, SlotTracker);
O << " = WIDEN-CANONICAL-INDUCTION";
}
@@ -1021,18 +1021,18 @@ void VPWidenCanonicalIVRecipe::print(raw_ostream &O, const Twine &Indent,
template void DomTreeBuilder::Calculate<VPDominatorTree>(VPDominatorTree &DT);
void VPValue::replaceAllUsesWith(VPValue *New) {
- for (unsigned J = 0; J < getNumUsers();) {
- VPUser *User = Users[J];
- unsigned NumUsers = getNumUsers();
+ for (unsigned J = 0; J < getNumUsers();) {
+ VPUser *User = Users[J];
+ unsigned NumUsers = getNumUsers();
for (unsigned I = 0, E = User->getNumOperands(); I < E; ++I)
if (User->getOperand(I) == this)
User->setOperand(I, New);
- // If a user got removed after updating the current user, the next user to
- // update will be moved to the current position, so we only need to
- // increment the index if the number of users did not change.
- if (NumUsers == getNumUsers())
- J++;
- }
+ // If a user got removed after updating the current user, the next user to
+ // update will be moved to the current position, so we only need to
+ // increment the index if the number of users did not change.
+ if (NumUsers == getNumUsers())
+ J++;
+ }
}
void VPValue::printAsOperand(raw_ostream &OS, VPSlotTracker &Tracker) const {
@@ -1050,12 +1050,12 @@ void VPValue::printAsOperand(raw_ostream &OS, VPSlotTracker &Tracker) const {
OS << "vp<%" << Tracker.getSlot(this) << ">";
}
-void VPUser::printOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const {
- interleaveComma(operands(), O, [&O, &SlotTracker](VPValue *Op) {
- Op->printAsOperand(O, SlotTracker);
- });
-}
-
+void VPUser::printOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const {
+ interleaveComma(operands(), O, [&O, &SlotTracker](VPValue *Op) {
+ Op->printAsOperand(O, SlotTracker);
+ });
+}
+
void VPInterleavedAccessInfo::visitRegion(VPRegionBlock *Region,
Old2NewTy &Old2New,
InterleavedAccessInfo &IAI) {
@@ -1122,8 +1122,8 @@ void VPSlotTracker::assignSlots(const VPRegionBlock *Region) {
void VPSlotTracker::assignSlots(const VPBasicBlock *VPBB) {
for (const VPRecipeBase &Recipe : *VPBB) {
- for (VPValue *Def : Recipe.definedValues())
- assignSlot(Def);
+ for (VPValue *Def : Recipe.definedValues())
+ assignSlot(Def);
}
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlan.h b/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlan.h
index eec59ef006..2cce127cd4 100644
--- a/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlan.h
+++ b/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlan.h
@@ -53,7 +53,7 @@ class DominatorTree;
class InnerLoopVectorizer;
class LoopInfo;
class raw_ostream;
-class RecurrenceDescriptor;
+class RecurrenceDescriptor;
class Value;
class VPBasicBlock;
class VPRegionBlock;
@@ -65,22 +65,22 @@ class VPlanSlp;
/// [1, 9) = {1, 2, 4, 8}
struct VFRange {
// A power of 2.
- const ElementCount Start;
+ const ElementCount Start;
// Need not be a power of 2. If End <= Start range is empty.
- ElementCount End;
-
- bool isEmpty() const {
- return End.getKnownMinValue() <= Start.getKnownMinValue();
- }
-
- VFRange(const ElementCount &Start, const ElementCount &End)
- : Start(Start), End(End) {
- assert(Start.isScalable() == End.isScalable() &&
- "Both Start and End should have the same scalable flag");
- assert(isPowerOf2_32(Start.getKnownMinValue()) &&
- "Expected Start to be a power of 2");
- }
+ ElementCount End;
+
+ bool isEmpty() const {
+ return End.getKnownMinValue() <= Start.getKnownMinValue();
+ }
+
+ VFRange(const ElementCount &Start, const ElementCount &End)
+ : Start(Start), End(End) {
+ assert(Start.isScalable() == End.isScalable() &&
+ "Both Start and End should have the same scalable flag");
+ assert(isPowerOf2_32(Start.getKnownMinValue()) &&
+ "Expected Start to be a power of 2");
+ }
};
using VPlanPtr = std::unique_ptr<VPlan>;
@@ -125,7 +125,7 @@ private:
/// The vectorization factor. Each entry in the scalar map contains UF x VF
/// scalar values.
- ElementCount VF;
+ ElementCount VF;
/// The vector and scalar map storage. We use std::map and not DenseMap
/// because insertions to DenseMap invalidate its iterators.
@@ -136,7 +136,7 @@ private:
public:
/// Construct an empty map with the given unroll and vectorization factors.
- VectorizerValueMap(unsigned UF, ElementCount VF) : UF(UF), VF(VF) {}
+ VectorizerValueMap(unsigned UF, ElementCount VF) : UF(UF), VF(VF) {}
/// \return True if the map has any vector entry for \p Key.
bool hasAnyVectorValue(Value *Key) const {
@@ -161,14 +161,14 @@ public:
/// \return True if the map has a scalar entry for \p Key and \p Instance.
bool hasScalarValue(Value *Key, const VPIteration &Instance) const {
assert(Instance.Part < UF && "Queried Scalar Part is too large.");
- assert(Instance.Lane < VF.getKnownMinValue() &&
- "Queried Scalar Lane is too large.");
-
+ assert(Instance.Lane < VF.getKnownMinValue() &&
+ "Queried Scalar Lane is too large.");
+
if (!hasAnyScalarValue(Key))
return false;
const ScalarParts &Entry = ScalarMapStorage.find(Key)->second;
assert(Entry.size() == UF && "ScalarParts has wrong dimensions.");
- assert(Entry[Instance.Part].size() == VF.getKnownMinValue() &&
+ assert(Entry[Instance.Part].size() == VF.getKnownMinValue() &&
"ScalarParts has wrong dimensions.");
return Entry[Instance.Part][Instance.Lane] != nullptr;
}
@@ -207,7 +207,7 @@ public:
// TODO: Consider storing uniform values only per-part, as they occupy
// lane 0 only, keeping the other VF-1 redundant entries null.
for (unsigned Part = 0; Part < UF; ++Part)
- Entry[Part].resize(VF.getKnownMinValue(), nullptr);
+ Entry[Part].resize(VF.getKnownMinValue(), nullptr);
ScalarMapStorage[Key] = Entry;
}
ScalarMapStorage[Key][Instance.Part][Instance.Lane] = Scalar;
@@ -246,15 +246,15 @@ struct VPCallback {
/// VPTransformState holds information passed down when "executing" a VPlan,
/// needed for generating the output IR.
struct VPTransformState {
- VPTransformState(ElementCount VF, unsigned UF, Loop *OrigLoop, LoopInfo *LI,
- DominatorTree *DT, IRBuilder<> &Builder,
- VectorizerValueMap &ValueMap, InnerLoopVectorizer *ILV,
- VPCallback &Callback)
- : VF(VF), UF(UF), Instance(), OrigLoop(OrigLoop), LI(LI), DT(DT),
- Builder(Builder), ValueMap(ValueMap), ILV(ILV), Callback(Callback) {}
+ VPTransformState(ElementCount VF, unsigned UF, Loop *OrigLoop, LoopInfo *LI,
+ DominatorTree *DT, IRBuilder<> &Builder,
+ VectorizerValueMap &ValueMap, InnerLoopVectorizer *ILV,
+ VPCallback &Callback)
+ : VF(VF), UF(UF), Instance(), OrigLoop(OrigLoop), LI(LI), DT(DT),
+ Builder(Builder), ValueMap(ValueMap), ILV(ILV), Callback(Callback) {}
/// The chosen Vectorization and Unroll Factors of the loop being vectorized.
- ElementCount VF;
+ ElementCount VF;
unsigned UF;
/// Hold the indices to generate specific scalar instructions. Null indicates
@@ -269,9 +269,9 @@ struct VPTransformState {
typedef SmallVector<Value *, 2> PerPartValuesTy;
DenseMap<VPValue *, PerPartValuesTy> PerPartOutput;
-
- using ScalarsPerPartValuesTy = SmallVector<SmallVector<Value *, 4>, 2>;
- DenseMap<VPValue *, ScalarsPerPartValuesTy> PerPartScalars;
+
+ using ScalarsPerPartValuesTy = SmallVector<SmallVector<Value *, 4>, 2>;
+ DenseMap<VPValue *, ScalarsPerPartValuesTy> PerPartScalars;
} Data;
/// Get the generated Value for a given VPValue and a given Part. Note that
@@ -288,23 +288,23 @@ struct VPTransformState {
}
/// Get the generated Value for a given VPValue and given Part and Lane.
- Value *get(VPValue *Def, const VPIteration &Instance);
-
- bool hasVectorValue(VPValue *Def, unsigned Part) {
- auto I = Data.PerPartOutput.find(Def);
- return I != Data.PerPartOutput.end() && Part < I->second.size() &&
- I->second[Part];
- }
-
- bool hasScalarValue(VPValue *Def, VPIteration Instance) {
- auto I = Data.PerPartScalars.find(Def);
- if (I == Data.PerPartScalars.end())
- return false;
- return Instance.Part < I->second.size() &&
- Instance.Lane < I->second[Instance.Part].size() &&
- I->second[Instance.Part][Instance.Lane];
- }
-
+ Value *get(VPValue *Def, const VPIteration &Instance);
+
+ bool hasVectorValue(VPValue *Def, unsigned Part) {
+ auto I = Data.PerPartOutput.find(Def);
+ return I != Data.PerPartOutput.end() && Part < I->second.size() &&
+ I->second[Part];
+ }
+
+ bool hasScalarValue(VPValue *Def, VPIteration Instance) {
+ auto I = Data.PerPartScalars.find(Def);
+ if (I == Data.PerPartScalars.end())
+ return false;
+ return Instance.Part < I->second.size() &&
+ Instance.Lane < I->second[Instance.Part].size() &&
+ I->second[Instance.Part][Instance.Lane];
+ }
+
/// Set the generated Value for a given VPValue and a given Part.
void set(VPValue *Def, Value *V, unsigned Part) {
if (!Data.PerPartOutput.count(Def)) {
@@ -313,19 +313,19 @@ struct VPTransformState {
}
Data.PerPartOutput[Def][Part] = V;
}
- void set(VPValue *Def, Value *IRDef, Value *V, unsigned Part);
-
- void set(VPValue *Def, Value *V, const VPIteration &Instance) {
- auto Iter = Data.PerPartScalars.insert({Def, {}});
- auto &PerPartVec = Iter.first->second;
- while (PerPartVec.size() <= Instance.Part)
- PerPartVec.emplace_back();
- auto &Scalars = PerPartVec[Instance.Part];
- while (Scalars.size() <= Instance.Lane)
- Scalars.push_back(nullptr);
- Scalars[Instance.Lane] = V;
- }
-
+ void set(VPValue *Def, Value *IRDef, Value *V, unsigned Part);
+
+ void set(VPValue *Def, Value *V, const VPIteration &Instance) {
+ auto Iter = Data.PerPartScalars.insert({Def, {}});
+ auto &PerPartVec = Iter.first->second;
+ while (PerPartVec.size() <= Instance.Part)
+ PerPartVec.emplace_back();
+ auto &Scalars = PerPartVec[Instance.Part];
+ while (Scalars.size() <= Instance.Lane)
+ Scalars.push_back(nullptr);
+ Scalars[Instance.Lane] = V;
+ }
+
/// Hold state information used when constructing the CFG of the output IR,
/// traversing the VPBasicBlocks and generating corresponding IR BasicBlocks.
struct CFGState {
@@ -351,9 +351,9 @@ struct VPTransformState {
CFGState() = default;
} CFG;
- /// Hold a pointer to the original loop.
- Loop *OrigLoop;
-
+ /// Hold a pointer to the original loop.
+ Loop *OrigLoop;
+
/// Hold a pointer to LoopInfo to register new basic blocks in the loop.
LoopInfo *LI;
@@ -427,14 +427,14 @@ class VPBlockBase {
/// Remove \p Predecessor from the predecessors of this block.
void removePredecessor(VPBlockBase *Predecessor) {
- auto Pos = find(Predecessors, Predecessor);
+ auto Pos = find(Predecessors, Predecessor);
assert(Pos && "Predecessor does not exist");
Predecessors.erase(Pos);
}
/// Remove \p Successor from the successors of this block.
void removeSuccessor(VPBlockBase *Successor) {
- auto Pos = find(Successors, Successor);
+ auto Pos = find(Successors, Successor);
assert(Pos && "Successor does not exist");
Successors.erase(Pos);
}
@@ -627,19 +627,19 @@ public:
// hoisted into a VPBlockBase.
return true;
}
-
- /// Replace all operands of VPUsers in the block with \p NewValue and also
- /// replaces all uses of VPValues defined in the block with NewValue.
- virtual void dropAllReferences(VPValue *NewValue) = 0;
+
+ /// Replace all operands of VPUsers in the block with \p NewValue and also
+ /// replaces all uses of VPValues defined in the block with NewValue.
+ virtual void dropAllReferences(VPValue *NewValue) = 0;
};
/// VPRecipeBase is a base class modeling a sequence of one or more output IR
-/// instructions. VPRecipeBase owns the the VPValues it defines through VPDef
-/// and is responsible for deleting its defined values. Single-value
-/// VPRecipeBases that also inherit from VPValue must make sure to inherit from
-/// VPRecipeBase before VPValue.
-class VPRecipeBase : public ilist_node_with_parent<VPRecipeBase, VPBasicBlock>,
- public VPDef {
+/// instructions. VPRecipeBase owns the the VPValues it defines through VPDef
+/// and is responsible for deleting its defined values. Single-value
+/// VPRecipeBases that also inherit from VPValue must make sure to inherit from
+/// VPRecipeBase before VPValue.
+class VPRecipeBase : public ilist_node_with_parent<VPRecipeBase, VPBasicBlock>,
+ public VPDef {
friend VPBasicBlock;
friend class VPBlockUtils;
@@ -648,7 +648,7 @@ class VPRecipeBase : public ilist_node_with_parent<VPRecipeBase, VPBasicBlock>,
VPBasicBlock *Parent = nullptr;
public:
- VPRecipeBase(const unsigned char SC) : VPDef(SC) {}
+ VPRecipeBase(const unsigned char SC) : VPDef(SC) {}
virtual ~VPRecipeBase() = default;
/// \return the VPBasicBlock which this VPRecipe belongs to.
@@ -671,11 +671,11 @@ public:
/// the VPBasicBlock that MovePos lives in, right after MovePos.
void moveAfter(VPRecipeBase *MovePos);
- /// Unlink this recipe and insert into BB before I.
- ///
- /// \pre I is a valid iterator into BB.
- void moveBefore(VPBasicBlock &BB, iplist<VPRecipeBase>::iterator I);
-
+ /// Unlink this recipe and insert into BB before I.
+ ///
+ /// \pre I is a valid iterator into BB.
+ void moveBefore(VPBasicBlock &BB, iplist<VPRecipeBase>::iterator I);
+
/// This method unlinks 'this' from the containing basic block, but does not
/// delete it.
void removeFromParent();
@@ -684,46 +684,46 @@ public:
///
/// \returns an iterator pointing to the element after the erased one
iplist<VPRecipeBase>::iterator eraseFromParent();
-
- /// Returns a pointer to a VPUser, if the recipe inherits from VPUser or
- /// nullptr otherwise.
- VPUser *toVPUser();
-
- /// Returns the underlying instruction, if the recipe is a VPValue or nullptr
- /// otherwise.
- Instruction *getUnderlyingInstr() {
- return cast<Instruction>(getVPValue()->getUnderlyingValue());
- }
- const Instruction *getUnderlyingInstr() const {
- return cast<Instruction>(getVPValue()->getUnderlyingValue());
- }
-
- /// Method to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VPDef *D) {
- // All VPDefs are also VPRecipeBases.
- return true;
- }
+
+ /// Returns a pointer to a VPUser, if the recipe inherits from VPUser or
+ /// nullptr otherwise.
+ VPUser *toVPUser();
+
+ /// Returns the underlying instruction, if the recipe is a VPValue or nullptr
+ /// otherwise.
+ Instruction *getUnderlyingInstr() {
+ return cast<Instruction>(getVPValue()->getUnderlyingValue());
+ }
+ const Instruction *getUnderlyingInstr() const {
+ return cast<Instruction>(getVPValue()->getUnderlyingValue());
+ }
+
+ /// Method to support type inquiry through isa, cast, and dyn_cast.
+ static inline bool classof(const VPDef *D) {
+ // All VPDefs are also VPRecipeBases.
+ return true;
+ }
};
-inline bool VPUser::classof(const VPDef *Def) {
- return Def->getVPDefID() == VPRecipeBase::VPInstructionSC ||
- Def->getVPDefID() == VPRecipeBase::VPWidenSC ||
- Def->getVPDefID() == VPRecipeBase::VPWidenCallSC ||
- Def->getVPDefID() == VPRecipeBase::VPWidenSelectSC ||
- Def->getVPDefID() == VPRecipeBase::VPWidenGEPSC ||
- Def->getVPDefID() == VPRecipeBase::VPBlendSC ||
- Def->getVPDefID() == VPRecipeBase::VPInterleaveSC ||
- Def->getVPDefID() == VPRecipeBase::VPReplicateSC ||
- Def->getVPDefID() == VPRecipeBase::VPReductionSC ||
- Def->getVPDefID() == VPRecipeBase::VPBranchOnMaskSC ||
- Def->getVPDefID() == VPRecipeBase::VPWidenMemoryInstructionSC;
-}
-
+inline bool VPUser::classof(const VPDef *Def) {
+ return Def->getVPDefID() == VPRecipeBase::VPInstructionSC ||
+ Def->getVPDefID() == VPRecipeBase::VPWidenSC ||
+ Def->getVPDefID() == VPRecipeBase::VPWidenCallSC ||
+ Def->getVPDefID() == VPRecipeBase::VPWidenSelectSC ||
+ Def->getVPDefID() == VPRecipeBase::VPWidenGEPSC ||
+ Def->getVPDefID() == VPRecipeBase::VPBlendSC ||
+ Def->getVPDefID() == VPRecipeBase::VPInterleaveSC ||
+ Def->getVPDefID() == VPRecipeBase::VPReplicateSC ||
+ Def->getVPDefID() == VPRecipeBase::VPReductionSC ||
+ Def->getVPDefID() == VPRecipeBase::VPBranchOnMaskSC ||
+ Def->getVPDefID() == VPRecipeBase::VPWidenMemoryInstructionSC;
+}
+
/// This is a concrete Recipe that models a single VPlan-level instruction.
/// While as any Recipe it may generate a sequence of IR instructions when
/// executed, these instructions would always form a single-def expression as
/// the VPInstruction is also a single def-use vertex.
-class VPInstruction : public VPRecipeBase, public VPUser, public VPValue {
+class VPInstruction : public VPRecipeBase, public VPUser, public VPValue {
friend class VPlanSlp;
public:
@@ -749,22 +749,22 @@ protected:
public:
VPInstruction(unsigned Opcode, ArrayRef<VPValue *> Operands)
- : VPRecipeBase(VPRecipeBase::VPInstructionSC), VPUser(Operands),
- VPValue(VPValue::VPVInstructionSC, nullptr, this), Opcode(Opcode) {}
-
- VPInstruction(unsigned Opcode, ArrayRef<VPInstruction *> Operands)
- : VPRecipeBase(VPRecipeBase::VPInstructionSC), VPUser({}),
- VPValue(VPValue::VPVInstructionSC, nullptr, this), Opcode(Opcode) {
- for (auto *I : Operands)
- addOperand(I->getVPValue());
- }
-
+ : VPRecipeBase(VPRecipeBase::VPInstructionSC), VPUser(Operands),
+ VPValue(VPValue::VPVInstructionSC, nullptr, this), Opcode(Opcode) {}
+
+ VPInstruction(unsigned Opcode, ArrayRef<VPInstruction *> Operands)
+ : VPRecipeBase(VPRecipeBase::VPInstructionSC), VPUser({}),
+ VPValue(VPValue::VPVInstructionSC, nullptr, this), Opcode(Opcode) {
+ for (auto *I : Operands)
+ addOperand(I->getVPValue());
+ }
+
VPInstruction(unsigned Opcode, std::initializer_list<VPValue *> Operands)
: VPInstruction(Opcode, ArrayRef<VPValue *>(Operands)) {}
/// Method to support type inquiry through isa, cast, and dyn_cast.
static inline bool classof(const VPValue *V) {
- return V->getVPValueID() == VPValue::VPVInstructionSC;
+ return V->getVPValueID() == VPValue::VPVInstructionSC;
}
VPInstruction *clone() const {
@@ -773,8 +773,8 @@ public:
}
/// Method to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VPDef *R) {
- return R->getVPDefID() == VPRecipeBase::VPInstructionSC;
+ static inline bool classof(const VPDef *R) {
+ return R->getVPDefID() == VPRecipeBase::VPInstructionSC;
}
unsigned getOpcode() const { return Opcode; }
@@ -784,12 +784,12 @@ public:
/// provided.
void execute(VPTransformState &State) override;
- /// Print the VPInstruction to \p O.
+ /// Print the VPInstruction to \p O.
void print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const override;
- /// Print the VPInstruction to dbgs() (for debugging).
- void dump() const;
+ /// Print the VPInstruction to dbgs() (for debugging).
+ void dump() const;
/// Return true if this instruction may modify memory.
bool mayWriteToMemory() const {
@@ -823,22 +823,22 @@ public:
/// VPWidenRecipe is a recipe for producing a copy of vector type its
/// ingredient. This recipe covers most of the traditional vectorization cases
/// where each ingredient transforms into a vectorized version of itself.
-class VPWidenRecipe : public VPRecipeBase, public VPValue, public VPUser {
+class VPWidenRecipe : public VPRecipeBase, public VPValue, public VPUser {
public:
template <typename IterT>
VPWidenRecipe(Instruction &I, iterator_range<IterT> Operands)
- : VPRecipeBase(VPRecipeBase::VPWidenSC),
- VPValue(VPValue::VPVWidenSC, &I, this), VPUser(Operands) {}
+ : VPRecipeBase(VPRecipeBase::VPWidenSC),
+ VPValue(VPValue::VPVWidenSC, &I, this), VPUser(Operands) {}
~VPWidenRecipe() override = default;
/// Method to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VPDef *D) {
- return D->getVPDefID() == VPRecipeBase::VPWidenSC;
+ static inline bool classof(const VPDef *D) {
+ return D->getVPDefID() == VPRecipeBase::VPWidenSC;
+ }
+ static inline bool classof(const VPValue *V) {
+ return V->getVPValueID() == VPValue::VPVWidenSC;
}
- static inline bool classof(const VPValue *V) {
- return V->getVPValueID() == VPValue::VPVWidenSC;
- }
/// Produce widened copies of all Ingredients.
void execute(VPTransformState &State) override;
@@ -849,19 +849,19 @@ public:
};
/// A recipe for widening Call instructions.
-class VPWidenCallRecipe : public VPRecipeBase, public VPUser, public VPValue {
+class VPWidenCallRecipe : public VPRecipeBase, public VPUser, public VPValue {
public:
template <typename IterT>
VPWidenCallRecipe(CallInst &I, iterator_range<IterT> CallArguments)
- : VPRecipeBase(VPRecipeBase::VPWidenCallSC), VPUser(CallArguments),
- VPValue(VPValue::VPVWidenCallSC, &I, this) {}
+ : VPRecipeBase(VPRecipeBase::VPWidenCallSC), VPUser(CallArguments),
+ VPValue(VPValue::VPVWidenCallSC, &I, this) {}
~VPWidenCallRecipe() override = default;
/// Method to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VPDef *D) {
- return D->getVPDefID() == VPRecipeBase::VPWidenCallSC;
+ static inline bool classof(const VPDef *D) {
+ return D->getVPDefID() == VPRecipeBase::VPWidenCallSC;
}
/// Produce a widened version of the call instruction.
@@ -873,7 +873,7 @@ public:
};
/// A recipe for widening select instructions.
-class VPWidenSelectRecipe : public VPRecipeBase, public VPUser, public VPValue {
+class VPWidenSelectRecipe : public VPRecipeBase, public VPUser, public VPValue {
/// Is the condition of the select loop invariant?
bool InvariantCond;
@@ -882,15 +882,15 @@ public:
template <typename IterT>
VPWidenSelectRecipe(SelectInst &I, iterator_range<IterT> Operands,
bool InvariantCond)
- : VPRecipeBase(VPRecipeBase::VPWidenSelectSC), VPUser(Operands),
- VPValue(VPValue::VPVWidenSelectSC, &I, this),
+ : VPRecipeBase(VPRecipeBase::VPWidenSelectSC), VPUser(Operands),
+ VPValue(VPValue::VPVWidenSelectSC, &I, this),
InvariantCond(InvariantCond) {}
~VPWidenSelectRecipe() override = default;
/// Method to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VPDef *D) {
- return D->getVPDefID() == VPRecipeBase::VPWidenSelectSC;
+ static inline bool classof(const VPDef *D) {
+ return D->getVPDefID() == VPRecipeBase::VPWidenSelectSC;
}
/// Produce a widened version of the select instruction.
@@ -902,24 +902,24 @@ public:
};
/// A recipe for handling GEP instructions.
-class VPWidenGEPRecipe : public VPRecipeBase,
- public VPUser,
- public VPValue {
+class VPWidenGEPRecipe : public VPRecipeBase,
+ public VPUser,
+ public VPValue {
bool IsPtrLoopInvariant;
SmallBitVector IsIndexLoopInvariant;
public:
template <typename IterT>
- VPWidenGEPRecipe(GetElementPtrInst *GEP, iterator_range<IterT> Operands)
- : VPRecipeBase(VPRecipeBase::VPWidenGEPSC), VPUser(Operands),
- VPValue(VPWidenGEPSC, GEP, this),
- IsIndexLoopInvariant(GEP->getNumIndices(), false) {}
-
- template <typename IterT>
+ VPWidenGEPRecipe(GetElementPtrInst *GEP, iterator_range<IterT> Operands)
+ : VPRecipeBase(VPRecipeBase::VPWidenGEPSC), VPUser(Operands),
+ VPValue(VPWidenGEPSC, GEP, this),
+ IsIndexLoopInvariant(GEP->getNumIndices(), false) {}
+
+ template <typename IterT>
VPWidenGEPRecipe(GetElementPtrInst *GEP, iterator_range<IterT> Operands,
Loop *OrigLoop)
- : VPRecipeBase(VPRecipeBase::VPWidenGEPSC), VPUser(Operands),
- VPValue(VPValue::VPVWidenGEPSC, GEP, this),
+ : VPRecipeBase(VPRecipeBase::VPWidenGEPSC), VPUser(Operands),
+ VPValue(VPValue::VPVWidenGEPSC, GEP, this),
IsIndexLoopInvariant(GEP->getNumIndices(), false) {
IsPtrLoopInvariant = OrigLoop->isLoopInvariant(GEP->getPointerOperand());
for (auto Index : enumerate(GEP->indices()))
@@ -929,8 +929,8 @@ public:
~VPWidenGEPRecipe() override = default;
/// Method to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VPDef *D) {
- return D->getVPDefID() == VPRecipeBase::VPWidenGEPSC;
+ static inline bool classof(const VPDef *D) {
+ return D->getVPDefID() == VPRecipeBase::VPWidenGEPSC;
}
/// Generate the gep nodes.
@@ -943,25 +943,25 @@ public:
/// A recipe for handling phi nodes of integer and floating-point inductions,
/// producing their vector and scalar values.
-class VPWidenIntOrFpInductionRecipe : public VPRecipeBase, public VPUser {
+class VPWidenIntOrFpInductionRecipe : public VPRecipeBase, public VPUser {
PHINode *IV;
TruncInst *Trunc;
public:
- VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start,
- TruncInst *Trunc = nullptr)
- : VPRecipeBase(VPWidenIntOrFpInductionSC), VPUser({Start}), IV(IV),
- Trunc(Trunc) {
- if (Trunc)
- new VPValue(Trunc, this);
- else
- new VPValue(IV, this);
- }
+ VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start,
+ TruncInst *Trunc = nullptr)
+ : VPRecipeBase(VPWidenIntOrFpInductionSC), VPUser({Start}), IV(IV),
+ Trunc(Trunc) {
+ if (Trunc)
+ new VPValue(Trunc, this);
+ else
+ new VPValue(IV, this);
+ }
~VPWidenIntOrFpInductionRecipe() override = default;
/// Method to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VPDef *D) {
- return D->getVPDefID() == VPRecipeBase::VPWidenIntOrFpInductionSC;
+ static inline bool classof(const VPDef *D) {
+ return D->getVPDefID() == VPRecipeBase::VPWidenIntOrFpInductionSC;
}
/// Generate the vectorized and scalarized versions of the phi node as
@@ -971,38 +971,38 @@ public:
/// Print the recipe.
void print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const override;
-
- /// Returns the start value of the induction.
- VPValue *getStartValue() { return getOperand(0); }
+
+ /// Returns the start value of the induction.
+ VPValue *getStartValue() { return getOperand(0); }
};
/// A recipe for handling all phi nodes except for integer and FP inductions.
-/// For reduction PHIs, RdxDesc must point to the corresponding recurrence
-/// descriptor and the start value is the first operand of the recipe.
-class VPWidenPHIRecipe : public VPRecipeBase, public VPUser {
+/// For reduction PHIs, RdxDesc must point to the corresponding recurrence
+/// descriptor and the start value is the first operand of the recipe.
+class VPWidenPHIRecipe : public VPRecipeBase, public VPUser {
PHINode *Phi;
- /// Descriptor for a reduction PHI.
- RecurrenceDescriptor *RdxDesc = nullptr;
-
+ /// Descriptor for a reduction PHI.
+ RecurrenceDescriptor *RdxDesc = nullptr;
+
public:
- /// Create a new VPWidenPHIRecipe for the reduction \p Phi described by \p
- /// RdxDesc.
- VPWidenPHIRecipe(PHINode *Phi, RecurrenceDescriptor &RdxDesc, VPValue &Start)
- : VPWidenPHIRecipe(Phi) {
- this->RdxDesc = &RdxDesc;
- addOperand(&Start);
- }
-
- /// Create a VPWidenPHIRecipe for \p Phi
- VPWidenPHIRecipe(PHINode *Phi) : VPRecipeBase(VPWidenPHISC), Phi(Phi) {
- new VPValue(Phi, this);
- }
+ /// Create a new VPWidenPHIRecipe for the reduction \p Phi described by \p
+ /// RdxDesc.
+ VPWidenPHIRecipe(PHINode *Phi, RecurrenceDescriptor &RdxDesc, VPValue &Start)
+ : VPWidenPHIRecipe(Phi) {
+ this->RdxDesc = &RdxDesc;
+ addOperand(&Start);
+ }
+
+ /// Create a VPWidenPHIRecipe for \p Phi
+ VPWidenPHIRecipe(PHINode *Phi) : VPRecipeBase(VPWidenPHISC), Phi(Phi) {
+ new VPValue(Phi, this);
+ }
~VPWidenPHIRecipe() override = default;
/// Method to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VPDef *D) {
- return D->getVPDefID() == VPRecipeBase::VPWidenPHISC;
+ static inline bool classof(const VPDef *D) {
+ return D->getVPDefID() == VPRecipeBase::VPWidenPHISC;
}
/// Generate the phi/select nodes.
@@ -1011,25 +1011,25 @@ public:
/// Print the recipe.
void print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const override;
-
- /// Returns the start value of the phi, if it is a reduction.
- VPValue *getStartValue() {
- return getNumOperands() == 0 ? nullptr : getOperand(0);
- }
+
+ /// Returns the start value of the phi, if it is a reduction.
+ VPValue *getStartValue() {
+ return getNumOperands() == 0 ? nullptr : getOperand(0);
+ }
};
/// A recipe for vectorizing a phi-node as a sequence of mask-based select
/// instructions.
-class VPBlendRecipe : public VPRecipeBase, public VPUser {
+class VPBlendRecipe : public VPRecipeBase, public VPUser {
PHINode *Phi;
-public:
+public:
/// The blend operation is a User of the incoming values and of their
/// respective masks, ordered [I0, M0, I1, M1, ...]. Note that a single value
/// might be incoming with a full mask for which there is no VPValue.
VPBlendRecipe(PHINode *Phi, ArrayRef<VPValue *> Operands)
- : VPRecipeBase(VPBlendSC), VPUser(Operands), Phi(Phi) {
- new VPValue(Phi, this);
+ : VPRecipeBase(VPBlendSC), VPUser(Operands), Phi(Phi) {
+ new VPValue(Phi, this);
assert(Operands.size() > 0 &&
((Operands.size() == 1) || (Operands.size() % 2 == 0)) &&
"Expected either a single incoming value or a positive even number "
@@ -1037,19 +1037,19 @@ public:
}
/// Method to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VPDef *D) {
- return D->getVPDefID() == VPRecipeBase::VPBlendSC;
+ static inline bool classof(const VPDef *D) {
+ return D->getVPDefID() == VPRecipeBase::VPBlendSC;
}
/// Return the number of incoming values, taking into account that a single
/// incoming value has no mask.
- unsigned getNumIncomingValues() const { return (getNumOperands() + 1) / 2; }
+ unsigned getNumIncomingValues() const { return (getNumOperands() + 1) / 2; }
/// Return incoming value number \p Idx.
- VPValue *getIncomingValue(unsigned Idx) const { return getOperand(Idx * 2); }
+ VPValue *getIncomingValue(unsigned Idx) const { return getOperand(Idx * 2); }
/// Return mask number \p Idx.
- VPValue *getMask(unsigned Idx) const { return getOperand(Idx * 2 + 1); }
+ VPValue *getMask(unsigned Idx) const { return getOperand(Idx * 2 + 1); }
/// Generate the phi/select nodes.
void execute(VPTransformState &State) override;
@@ -1060,60 +1060,60 @@ public:
};
/// VPInterleaveRecipe is a recipe for transforming an interleave group of load
-/// or stores into one wide load/store and shuffles. The first operand of a
-/// VPInterleave recipe is the address, followed by the stored values, followed
-/// by an optional mask.
-class VPInterleaveRecipe : public VPRecipeBase, public VPUser {
+/// or stores into one wide load/store and shuffles. The first operand of a
+/// VPInterleave recipe is the address, followed by the stored values, followed
+/// by an optional mask.
+class VPInterleaveRecipe : public VPRecipeBase, public VPUser {
const InterleaveGroup<Instruction> *IG;
- bool HasMask = false;
-
+ bool HasMask = false;
+
public:
VPInterleaveRecipe(const InterleaveGroup<Instruction> *IG, VPValue *Addr,
- ArrayRef<VPValue *> StoredValues, VPValue *Mask)
- : VPRecipeBase(VPInterleaveSC), VPUser(Addr), IG(IG) {
- for (unsigned i = 0; i < IG->getFactor(); ++i)
- if (Instruction *I = IG->getMember(i)) {
- if (I->getType()->isVoidTy())
- continue;
- new VPValue(I, this);
- }
-
- for (auto *SV : StoredValues)
- addOperand(SV);
- if (Mask) {
- HasMask = true;
- addOperand(Mask);
- }
+ ArrayRef<VPValue *> StoredValues, VPValue *Mask)
+ : VPRecipeBase(VPInterleaveSC), VPUser(Addr), IG(IG) {
+ for (unsigned i = 0; i < IG->getFactor(); ++i)
+ if (Instruction *I = IG->getMember(i)) {
+ if (I->getType()->isVoidTy())
+ continue;
+ new VPValue(I, this);
+ }
+
+ for (auto *SV : StoredValues)
+ addOperand(SV);
+ if (Mask) {
+ HasMask = true;
+ addOperand(Mask);
+ }
}
~VPInterleaveRecipe() override = default;
/// Method to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VPDef *D) {
- return D->getVPDefID() == VPRecipeBase::VPInterleaveSC;
+ static inline bool classof(const VPDef *D) {
+ return D->getVPDefID() == VPRecipeBase::VPInterleaveSC;
}
/// Return the address accessed by this recipe.
VPValue *getAddr() const {
- return getOperand(0); // Address is the 1st, mandatory operand.
+ return getOperand(0); // Address is the 1st, mandatory operand.
}
/// Return the mask used by this recipe. Note that a full mask is represented
/// by a nullptr.
VPValue *getMask() const {
// Mask is optional and therefore the last, currently 2nd operand.
- return HasMask ? getOperand(getNumOperands() - 1) : nullptr;
- }
-
- /// Return the VPValues stored by this interleave group. If it is a load
- /// interleave group, return an empty ArrayRef.
- ArrayRef<VPValue *> getStoredValues() const {
- // The first operand is the address, followed by the stored values, followed
- // by an optional mask.
- return ArrayRef<VPValue *>(op_begin(), getNumOperands())
- .slice(1, getNumOperands() - (HasMask ? 2 : 1));
- }
-
+ return HasMask ? getOperand(getNumOperands() - 1) : nullptr;
+ }
+
+ /// Return the VPValues stored by this interleave group. If it is a load
+ /// interleave group, return an empty ArrayRef.
+ ArrayRef<VPValue *> getStoredValues() const {
+ // The first operand is the address, followed by the stored values, followed
+ // by an optional mask.
+ return ArrayRef<VPValue *>(op_begin(), getNumOperands())
+ .slice(1, getNumOperands() - (HasMask ? 2 : 1));
+ }
+
/// Generate the wide load or store, and shuffles.
void execute(VPTransformState &State) override;
@@ -1124,61 +1124,61 @@ public:
const InterleaveGroup<Instruction> *getInterleaveGroup() { return IG; }
};
-/// A recipe to represent inloop reduction operations, performing a reduction on
-/// a vector operand into a scalar value, and adding the result to a chain.
-/// The Operands are {ChainOp, VecOp, [Condition]}.
-class VPReductionRecipe : public VPRecipeBase, public VPUser, public VPValue {
- /// The recurrence decriptor for the reduction in question.
- RecurrenceDescriptor *RdxDesc;
- /// Fast math flags to use for the resulting reduction operation.
- bool NoNaN;
- /// Pointer to the TTI, needed to create the target reduction
- const TargetTransformInfo *TTI;
-
-public:
- VPReductionRecipe(RecurrenceDescriptor *R, Instruction *I, VPValue *ChainOp,
- VPValue *VecOp, VPValue *CondOp, bool NoNaN,
- const TargetTransformInfo *TTI)
- : VPRecipeBase(VPRecipeBase::VPReductionSC), VPUser({ChainOp, VecOp}),
- VPValue(VPValue::VPVReductionSC, I, this), RdxDesc(R), NoNaN(NoNaN),
- TTI(TTI) {
- if (CondOp)
- addOperand(CondOp);
- }
-
- ~VPReductionRecipe() override = default;
-
- /// Method to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VPValue *V) {
- return V->getVPValueID() == VPValue::VPVReductionSC;
- }
-
- static inline bool classof(const VPDef *D) {
- return D->getVPDefID() == VPRecipeBase::VPReductionSC;
- }
-
- /// Generate the reduction in the loop
- void execute(VPTransformState &State) override;
-
- /// Print the recipe.
- void print(raw_ostream &O, const Twine &Indent,
- VPSlotTracker &SlotTracker) const override;
-
- /// The VPValue of the scalar Chain being accumulated.
- VPValue *getChainOp() const { return getOperand(0); }
- /// The VPValue of the vector value to be reduced.
- VPValue *getVecOp() const { return getOperand(1); }
- /// The VPValue of the condition for the block.
- VPValue *getCondOp() const {
- return getNumOperands() > 2 ? getOperand(2) : nullptr;
- }
-};
-
+/// A recipe to represent inloop reduction operations, performing a reduction on
+/// a vector operand into a scalar value, and adding the result to a chain.
+/// The Operands are {ChainOp, VecOp, [Condition]}.
+class VPReductionRecipe : public VPRecipeBase, public VPUser, public VPValue {
+ /// The recurrence decriptor for the reduction in question.
+ RecurrenceDescriptor *RdxDesc;
+ /// Fast math flags to use for the resulting reduction operation.
+ bool NoNaN;
+ /// Pointer to the TTI, needed to create the target reduction
+ const TargetTransformInfo *TTI;
+
+public:
+ VPReductionRecipe(RecurrenceDescriptor *R, Instruction *I, VPValue *ChainOp,
+ VPValue *VecOp, VPValue *CondOp, bool NoNaN,
+ const TargetTransformInfo *TTI)
+ : VPRecipeBase(VPRecipeBase::VPReductionSC), VPUser({ChainOp, VecOp}),
+ VPValue(VPValue::VPVReductionSC, I, this), RdxDesc(R), NoNaN(NoNaN),
+ TTI(TTI) {
+ if (CondOp)
+ addOperand(CondOp);
+ }
+
+ ~VPReductionRecipe() override = default;
+
+ /// Method to support type inquiry through isa, cast, and dyn_cast.
+ static inline bool classof(const VPValue *V) {
+ return V->getVPValueID() == VPValue::VPVReductionSC;
+ }
+
+ static inline bool classof(const VPDef *D) {
+ return D->getVPDefID() == VPRecipeBase::VPReductionSC;
+ }
+
+ /// Generate the reduction in the loop
+ void execute(VPTransformState &State) override;
+
+ /// Print the recipe.
+ void print(raw_ostream &O, const Twine &Indent,
+ VPSlotTracker &SlotTracker) const override;
+
+ /// The VPValue of the scalar Chain being accumulated.
+ VPValue *getChainOp() const { return getOperand(0); }
+ /// The VPValue of the vector value to be reduced.
+ VPValue *getVecOp() const { return getOperand(1); }
+ /// The VPValue of the condition for the block.
+ VPValue *getCondOp() const {
+ return getNumOperands() > 2 ? getOperand(2) : nullptr;
+ }
+};
+
/// VPReplicateRecipe replicates a given instruction producing multiple scalar
/// copies of the original scalar type, one per lane, instead of producing a
/// single copy of widened type for all lanes. If the instruction is known to be
/// uniform only one copy, per lane zero, will be generated.
-class VPReplicateRecipe : public VPRecipeBase, public VPUser, public VPValue {
+class VPReplicateRecipe : public VPRecipeBase, public VPUser, public VPValue {
/// Indicator if only a single replica per lane is needed.
bool IsUniform;
@@ -1192,9 +1192,9 @@ public:
template <typename IterT>
VPReplicateRecipe(Instruction *I, iterator_range<IterT> Operands,
bool IsUniform, bool IsPredicated = false)
- : VPRecipeBase(VPReplicateSC), VPUser(Operands),
- VPValue(VPVReplicateSC, I, this), IsUniform(IsUniform),
- IsPredicated(IsPredicated) {
+ : VPRecipeBase(VPReplicateSC), VPUser(Operands),
+ VPValue(VPVReplicateSC, I, this), IsUniform(IsUniform),
+ IsPredicated(IsPredicated) {
// Retain the previous behavior of predicateInstructions(), where an
// insert-element of a predicated instruction got hoisted into the
// predicated basic block iff it was its only user. This is achieved by
@@ -1206,14 +1206,14 @@ public:
~VPReplicateRecipe() override = default;
/// Method to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VPDef *D) {
- return D->getVPDefID() == VPRecipeBase::VPReplicateSC;
+ static inline bool classof(const VPDef *D) {
+ return D->getVPDefID() == VPRecipeBase::VPReplicateSC;
+ }
+
+ static inline bool classof(const VPValue *V) {
+ return V->getVPValueID() == VPValue::VPVReplicateSC;
}
- static inline bool classof(const VPValue *V) {
- return V->getVPValueID() == VPValue::VPVReplicateSC;
- }
-
/// Generate replicas of the desired Ingredient. Replicas will be generated
/// for all parts and lanes unless a specific part and lane are specified in
/// the \p State.
@@ -1224,21 +1224,21 @@ public:
/// Print the recipe.
void print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const override;
-
- bool isUniform() const { return IsUniform; }
+
+ bool isUniform() const { return IsUniform; }
};
/// A recipe for generating conditional branches on the bits of a mask.
-class VPBranchOnMaskRecipe : public VPRecipeBase, public VPUser {
+class VPBranchOnMaskRecipe : public VPRecipeBase, public VPUser {
public:
VPBranchOnMaskRecipe(VPValue *BlockInMask) : VPRecipeBase(VPBranchOnMaskSC) {
if (BlockInMask) // nullptr means all-one mask.
- addOperand(BlockInMask);
+ addOperand(BlockInMask);
}
/// Method to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VPDef *D) {
- return D->getVPDefID() == VPRecipeBase::VPBranchOnMaskSC;
+ static inline bool classof(const VPDef *D) {
+ return D->getVPDefID() == VPRecipeBase::VPBranchOnMaskSC;
}
/// Generate the extraction of the appropriate bit from the block mask and the
@@ -1250,7 +1250,7 @@ public:
VPSlotTracker &SlotTracker) const override {
O << " +\n" << Indent << "\"BRANCH-ON-MASK ";
if (VPValue *Mask = getMask())
- Mask->printAsOperand(O, SlotTracker);
+ Mask->printAsOperand(O, SlotTracker);
else
O << " All-One";
O << "\\l\"";
@@ -1259,9 +1259,9 @@ public:
/// Return the mask used by this recipe. Note that a full mask is represented
/// by a nullptr.
VPValue *getMask() const {
- assert(getNumOperands() <= 1 && "should have either 0 or 1 operands");
+ assert(getNumOperands() <= 1 && "should have either 0 or 1 operands");
// Mask is optional.
- return getNumOperands() == 1 ? getOperand(0) : nullptr;
+ return getNumOperands() == 1 ? getOperand(0) : nullptr;
}
};
@@ -1270,20 +1270,20 @@ public:
/// order to merge values that are set under such a branch and feed their uses.
/// The phi nodes can be scalar or vector depending on the users of the value.
/// This recipe works in concert with VPBranchOnMaskRecipe.
-class VPPredInstPHIRecipe : public VPRecipeBase, public VPUser {
+class VPPredInstPHIRecipe : public VPRecipeBase, public VPUser {
public:
/// Construct a VPPredInstPHIRecipe given \p PredInst whose value needs a phi
/// nodes after merging back from a Branch-on-Mask.
- VPPredInstPHIRecipe(VPValue *PredV)
- : VPRecipeBase(VPPredInstPHISC), VPUser(PredV) {
- new VPValue(PredV->getUnderlyingValue(), this);
- }
+ VPPredInstPHIRecipe(VPValue *PredV)
+ : VPRecipeBase(VPPredInstPHISC), VPUser(PredV) {
+ new VPValue(PredV->getUnderlyingValue(), this);
+ }
~VPPredInstPHIRecipe() override = default;
/// Method to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VPDef *D) {
- return D->getVPDefID() == VPRecipeBase::VPPredInstPHISC;
+ static inline bool classof(const VPDef *D) {
+ return D->getVPDefID() == VPRecipeBase::VPPredInstPHISC;
}
/// Generates phi nodes for live-outs as needed to retain SSA form.
@@ -1300,59 +1300,59 @@ public:
/// - For store: Address, stored value, optional mask
/// TODO: We currently execute only per-part unless a specific instance is
/// provided.
-class VPWidenMemoryInstructionRecipe : public VPRecipeBase,
- public VPUser {
- Instruction &Ingredient;
+class VPWidenMemoryInstructionRecipe : public VPRecipeBase,
+ public VPUser {
+ Instruction &Ingredient;
void setMask(VPValue *Mask) {
if (!Mask)
return;
- addOperand(Mask);
+ addOperand(Mask);
}
bool isMasked() const {
- return isStore() ? getNumOperands() == 3 : getNumOperands() == 2;
+ return isStore() ? getNumOperands() == 3 : getNumOperands() == 2;
}
public:
VPWidenMemoryInstructionRecipe(LoadInst &Load, VPValue *Addr, VPValue *Mask)
- : VPRecipeBase(VPWidenMemoryInstructionSC), VPUser({Addr}),
- Ingredient(Load) {
- new VPValue(VPValue::VPVMemoryInstructionSC, &Load, this);
+ : VPRecipeBase(VPWidenMemoryInstructionSC), VPUser({Addr}),
+ Ingredient(Load) {
+ new VPValue(VPValue::VPVMemoryInstructionSC, &Load, this);
setMask(Mask);
}
VPWidenMemoryInstructionRecipe(StoreInst &Store, VPValue *Addr,
VPValue *StoredValue, VPValue *Mask)
- : VPRecipeBase(VPWidenMemoryInstructionSC), VPUser({Addr, StoredValue}),
- Ingredient(Store) {
+ : VPRecipeBase(VPWidenMemoryInstructionSC), VPUser({Addr, StoredValue}),
+ Ingredient(Store) {
setMask(Mask);
}
/// Method to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VPDef *D) {
- return D->getVPDefID() == VPRecipeBase::VPWidenMemoryInstructionSC;
+ static inline bool classof(const VPDef *D) {
+ return D->getVPDefID() == VPRecipeBase::VPWidenMemoryInstructionSC;
}
/// Return the address accessed by this recipe.
VPValue *getAddr() const {
- return getOperand(0); // Address is the 1st, mandatory operand.
+ return getOperand(0); // Address is the 1st, mandatory operand.
}
/// Return the mask used by this recipe. Note that a full mask is represented
/// by a nullptr.
VPValue *getMask() const {
// Mask is optional and therefore the last operand.
- return isMasked() ? getOperand(getNumOperands() - 1) : nullptr;
+ return isMasked() ? getOperand(getNumOperands() - 1) : nullptr;
}
- /// Returns true if this recipe is a store.
- bool isStore() const { return isa<StoreInst>(Ingredient); }
-
+ /// Returns true if this recipe is a store.
+ bool isStore() const { return isa<StoreInst>(Ingredient); }
+
/// Return the address accessed by this recipe.
VPValue *getStoredValue() const {
- assert(isStore() && "Stored value only available for store instructions");
- return getOperand(1); // Stored value is the 2nd, mandatory operand.
+ assert(isStore() && "Stored value only available for store instructions");
+ return getOperand(1); // Stored value is the 2nd, mandatory operand.
}
/// Generate the wide load/store.
@@ -1365,16 +1365,16 @@ public:
/// A Recipe for widening the canonical induction variable of the vector loop.
class VPWidenCanonicalIVRecipe : public VPRecipeBase {
-public:
- VPWidenCanonicalIVRecipe() : VPRecipeBase(VPWidenCanonicalIVSC) {
- new VPValue(nullptr, this);
- }
+public:
+ VPWidenCanonicalIVRecipe() : VPRecipeBase(VPWidenCanonicalIVSC) {
+ new VPValue(nullptr, this);
+ }
~VPWidenCanonicalIVRecipe() override = default;
/// Method to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VPDef *D) {
- return D->getVPDefID() == VPRecipeBase::VPWidenCanonicalIVSC;
+ static inline bool classof(const VPDef *D) {
+ return D->getVPDefID() == VPRecipeBase::VPWidenCanonicalIVSC;
}
/// Generate a canonical vector induction variable of the vector loop, with
@@ -1461,11 +1461,11 @@ public:
/// this VPBasicBlock, thereby "executing" the VPlan.
void execute(struct VPTransformState *State) override;
- /// Return the position of the first non-phi node recipe in the block.
- iterator getFirstNonPhi();
-
- void dropAllReferences(VPValue *NewValue) override;
-
+ /// Return the position of the first non-phi node recipe in the block.
+ iterator getFirstNonPhi();
+
+ void dropAllReferences(VPValue *NewValue) override;
+
private:
/// Create an IR BasicBlock to hold the output instructions generated by this
/// VPBasicBlock, and return it. Update the CFGState accordingly.
@@ -1506,11 +1506,11 @@ public:
IsReplicator(IsReplicator) {}
~VPRegionBlock() override {
- if (Entry) {
- VPValue DummyValue;
- Entry->dropAllReferences(&DummyValue);
+ if (Entry) {
+ VPValue DummyValue;
+ Entry->dropAllReferences(&DummyValue);
deleteCFG(Entry);
- }
+ }
}
/// Method to support type inquiry through isa, cast, and dyn_cast.
@@ -1555,8 +1555,8 @@ public:
/// The method which generates the output IR instructions that correspond to
/// this VPRegionBlock, thereby "executing" the VPlan.
void execute(struct VPTransformState *State) override;
-
- void dropAllReferences(VPValue *NewValue) override;
+
+ void dropAllReferences(VPValue *NewValue) override;
};
//===----------------------------------------------------------------------===//
@@ -1694,7 +1694,7 @@ class VPlan {
VPBlockBase *Entry;
/// Holds the VFs applicable to this VPlan.
- SmallSetVector<ElementCount, 2> VFs;
+ SmallSetVector<ElementCount, 2> VFs;
/// Holds the name of the VPlan, for printing.
std::string Name;
@@ -1714,10 +1714,10 @@ class VPlan {
/// VPlan.
Value2VPValueTy Value2VPValue;
- /// Contains all VPValues that been allocated by addVPValue directly and need
- /// to be free when the plan's destructor is called.
- SmallVector<VPValue *, 16> VPValuesToFree;
-
+ /// Contains all VPValues that been allocated by addVPValue directly and need
+ /// to be free when the plan's destructor is called.
+ SmallVector<VPValue *, 16> VPValuesToFree;
+
/// Holds the VPLoopInfo analysis for this VPlan.
VPLoopInfo VPLInfo;
@@ -1731,15 +1731,15 @@ public:
}
~VPlan() {
- if (Entry) {
- VPValue DummyValue;
- for (VPBlockBase *Block : depth_first(Entry))
- Block->dropAllReferences(&DummyValue);
-
+ if (Entry) {
+ VPValue DummyValue;
+ for (VPBlockBase *Block : depth_first(Entry))
+ Block->dropAllReferences(&DummyValue);
+
VPBlockBase::deleteCFG(Entry);
- }
- for (VPValue *VPV : VPValuesToFree)
- delete VPV;
+ }
+ for (VPValue *VPV : VPValuesToFree)
+ delete VPV;
if (BackedgeTakenCount)
delete BackedgeTakenCount;
for (VPValue *Def : VPExternalDefs)
@@ -1767,9 +1767,9 @@ public:
return BackedgeTakenCount;
}
- void addVF(ElementCount VF) { VFs.insert(VF); }
+ void addVF(ElementCount VF) { VFs.insert(VF); }
- bool hasVF(ElementCount VF) { return VFs.count(VF); }
+ bool hasVF(ElementCount VF) { return VFs.count(VF); }
const std::string &getName() const { return Name; }
@@ -1789,17 +1789,17 @@ public:
void addVPValue(Value *V) {
assert(V && "Trying to add a null Value to VPlan");
assert(!Value2VPValue.count(V) && "Value already exists in VPlan");
- VPValue *VPV = new VPValue(V);
- Value2VPValue[V] = VPV;
- VPValuesToFree.push_back(VPV);
+ VPValue *VPV = new VPValue(V);
+ Value2VPValue[V] = VPV;
+ VPValuesToFree.push_back(VPV);
+ }
+
+ void addVPValue(Value *V, VPValue *VPV) {
+ assert(V && "Trying to add a null Value to VPlan");
+ assert(!Value2VPValue.count(V) && "Value already exists in VPlan");
+ Value2VPValue[V] = VPV;
}
- void addVPValue(Value *V, VPValue *VPV) {
- assert(V && "Trying to add a null Value to VPlan");
- assert(!Value2VPValue.count(V) && "Value already exists in VPlan");
- Value2VPValue[V] = VPV;
- }
-
VPValue *getVPValue(Value *V) {
assert(V && "Trying to get the VPValue of a null Value");
assert(Value2VPValue.count(V) && "Value does not exist in VPlan");
@@ -1813,8 +1813,8 @@ public:
return getVPValue(V);
}
- void removeVPValueFor(Value *V) { Value2VPValue.erase(V); }
-
+ void removeVPValueFor(Value *V) { Value2VPValue.erase(V); }
+
/// Return the VPLoopInfo analysis for this VPlan.
VPLoopInfo &getVPLoopInfo() { return VPLInfo; }
const VPLoopInfo &getVPLoopInfo() const { return VPLInfo; }
@@ -1892,13 +1892,13 @@ private:
void dump();
- static void printAsIngredient(raw_ostream &O, const Value *V);
+ static void printAsIngredient(raw_ostream &O, const Value *V);
};
struct VPlanIngredient {
- const Value *V;
+ const Value *V;
- VPlanIngredient(const Value *V) : V(V) {}
+ VPlanIngredient(const Value *V) : V(V) {}
};
inline raw_ostream &operator<<(raw_ostream &OS, const VPlanIngredient &I) {
@@ -2048,7 +2048,7 @@ public:
/// \returns nullptr if doesn't have such group.
InterleaveGroup<VPInstruction> *
getInterleaveGroup(VPInstruction *Instr) const {
- return InterleaveGroupMap.lookup(Instr);
+ return InterleaveGroupMap.lookup(Instr);
}
};
@@ -2132,7 +2132,7 @@ class VPlanSlp {
public:
VPlanSlp(VPInterleavedAccessInfo &IAI, VPBasicBlock &BB) : IAI(IAI), BB(BB) {}
- ~VPlanSlp() = default;
+ ~VPlanSlp() = default;
/// Tries to build an SLP tree rooted at \p Operands and returns a
/// VPInstruction combining \p Operands, if they can be combined.
diff --git a/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanPredicator.cpp b/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanPredicator.cpp
index 7da23508b7..ac3b3505dc 100644
--- a/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanPredicator.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanPredicator.cpp
@@ -191,7 +191,7 @@ void VPlanPredicator::predicateRegionRec(VPRegionBlock *Region) {
// Generate edge predicates and append them to the block predicate. RPO is
// necessary since the predecessor blocks' block predicate needs to be set
// before the current block's block predicate can be computed.
- for (VPBlockBase *Block : RPOT) {
+ for (VPBlockBase *Block : RPOT) {
// TODO: Handle nested regions once we start generating the same.
assert(!isa<VPRegionBlock>(Block) && "Nested region not expected");
createOrPropagatePredicates(Block, Region);
@@ -208,7 +208,7 @@ void VPlanPredicator::linearizeRegionRec(VPRegionBlock *Region) {
ReversePostOrderTraversal<VPBlockBase *> RPOT(Region->getEntry());
VPBlockBase *PrevBlock = nullptr;
- for (VPBlockBase *CurrBlock : RPOT) {
+ for (VPBlockBase *CurrBlock : RPOT) {
// TODO: Handle nested regions once we start generating the same.
assert(!isa<VPRegionBlock>(CurrBlock) && "Nested region not expected");
diff --git a/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanSLP.cpp b/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanSLP.cpp
index 5b8145ff62..6f21bf4429 100644
--- a/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanSLP.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanSLP.cpp
@@ -124,7 +124,7 @@ bool VPlanSlp::areVectorizable(ArrayRef<VPValue *> Operands) const {
for (auto &I : *Parent) {
auto *VPI = cast<VPInstruction>(&I);
if (VPI->getOpcode() == Instruction::Load &&
- llvm::is_contained(Operands, VPI))
+ llvm::is_contained(Operands, VPI))
LoadsSeen++;
if (LoadsSeen == Operands.size())
@@ -161,8 +161,8 @@ static SmallVector<VPValue *, 4> getOperands(ArrayRef<VPValue *> Values,
unsigned OperandIndex) {
SmallVector<VPValue *, 4> Operands;
for (VPValue *V : Values) {
- // Currently we only support VPInstructions.
- auto *U = cast<VPInstruction>(V);
+ // Currently we only support VPInstructions.
+ auto *U = cast<VPInstruction>(V);
Operands.push_back(U->getOperand(OperandIndex));
}
return Operands;
@@ -223,20 +223,20 @@ static bool areConsecutiveOrMatch(VPInstruction *A, VPInstruction *B,
/// Traverses and compares operands of V1 and V2 to MaxLevel.
static unsigned getLAScore(VPValue *V1, VPValue *V2, unsigned MaxLevel,
VPInterleavedAccessInfo &IAI) {
- auto *I1 = dyn_cast<VPInstruction>(V1);
- auto *I2 = dyn_cast<VPInstruction>(V2);
- // Currently we only support VPInstructions.
- if (!I1 || !I2)
+ auto *I1 = dyn_cast<VPInstruction>(V1);
+ auto *I2 = dyn_cast<VPInstruction>(V2);
+ // Currently we only support VPInstructions.
+ if (!I1 || !I2)
return 0;
if (MaxLevel == 0)
- return (unsigned)areConsecutiveOrMatch(I1, I2, IAI);
+ return (unsigned)areConsecutiveOrMatch(I1, I2, IAI);
unsigned Score = 0;
- for (unsigned I = 0, EV1 = I1->getNumOperands(); I < EV1; ++I)
- for (unsigned J = 0, EV2 = I2->getNumOperands(); J < EV2; ++J)
- Score +=
- getLAScore(I1->getOperand(I), I2->getOperand(J), MaxLevel - 1, IAI);
+ for (unsigned I = 0, EV1 = I1->getNumOperands(); I < EV1; ++I)
+ for (unsigned J = 0, EV2 = I2->getNumOperands(); J < EV2; ++J)
+ Score +=
+ getLAScore(I1->getOperand(I), I2->getOperand(J), MaxLevel - 1, IAI);
return Score;
}
@@ -466,8 +466,8 @@ VPInstruction *VPlanSlp::buildGraph(ArrayRef<VPValue *> Values) {
auto *VPI = new VPInstruction(Opcode, CombinedOperands);
VPI->setUnderlyingInstr(cast<VPInstruction>(Values[0])->getUnderlyingInstr());
- LLVM_DEBUG(dbgs() << "Create VPInstruction " << *VPI << " "
- << *cast<VPInstruction>(Values[0]) << "\n");
+ LLVM_DEBUG(dbgs() << "Create VPInstruction " << *VPI << " "
+ << *cast<VPInstruction>(Values[0]) << "\n");
addCombined(Values, VPI);
return VPI;
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanTransforms.cpp b/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanTransforms.cpp
index 6773dc5a61..1a54603faf 100644
--- a/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -48,8 +48,8 @@ void VPlanTransforms::VPInstructionsToVPRecipes(
VPInstruction *VPInst = cast<VPInstruction>(Ingredient);
Instruction *Inst = cast<Instruction>(VPInst->getUnderlyingValue());
if (DeadInstructions.count(Inst)) {
- VPValue DummyValue;
- VPInst->replaceAllUsesWith(&DummyValue);
+ VPValue DummyValue;
+ VPInst->replaceAllUsesWith(&DummyValue);
Ingredient->eraseFromParent();
continue;
}
@@ -68,8 +68,8 @@ void VPlanTransforms::VPInstructionsToVPRecipes(
InductionDescriptor II = Inductions.lookup(Phi);
if (II.getKind() == InductionDescriptor::IK_IntInduction ||
II.getKind() == InductionDescriptor::IK_FpInduction) {
- VPValue *Start = Plan->getOrAddVPValue(II.getStartValue());
- NewRecipe = new VPWidenIntOrFpInductionRecipe(Phi, Start);
+ VPValue *Start = Plan->getOrAddVPValue(II.getStartValue());
+ NewRecipe = new VPWidenIntOrFpInductionRecipe(Phi, Start);
} else
NewRecipe = new VPWidenPHIRecipe(Phi);
} else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
@@ -80,11 +80,11 @@ void VPlanTransforms::VPInstructionsToVPRecipes(
new VPWidenRecipe(*Inst, Plan->mapToVPValues(Inst->operands()));
NewRecipe->insertBefore(Ingredient);
- if (NewRecipe->getNumDefinedValues() == 1)
- VPInst->replaceAllUsesWith(NewRecipe->getVPValue());
- else
- assert(NewRecipe->getNumDefinedValues() == 0 &&
- "Only recpies with zero or one defined values expected");
+ if (NewRecipe->getNumDefinedValues() == 1)
+ VPInst->replaceAllUsesWith(NewRecipe->getVPValue());
+ else
+ assert(NewRecipe->getNumDefinedValues() == 0 &&
+ "Only recpies with zero or one defined values expected");
Ingredient->eraseFromParent();
}
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanValue.h b/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanValue.h
index b43c8398b6..ed572ca366 100644
--- a/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanValue.h
+++ b/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanValue.h
@@ -10,9 +10,9 @@
/// This file contains the declarations of the entities induced by Vectorization
/// Plans, e.g. the instructions the VPlan intends to generate if executed.
/// VPlan models the following entities:
-/// VPValue VPUser VPDef
-/// | |
-/// VPInstruction
+/// VPValue VPUser VPDef
+/// | |
+/// VPInstruction
/// These are documented in docs/VectorizationPlan.rst.
///
//===----------------------------------------------------------------------===//
@@ -21,9 +21,9 @@
#define LLVM_TRANSFORMS_VECTORIZE_VPLAN_VALUE_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/TinyPtrVector.h"
+#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/ADT/iterator_range.h"
namespace llvm {
@@ -31,11 +31,11 @@ namespace llvm {
// Forward declarations.
class raw_ostream;
class Value;
-class VPDef;
+class VPDef;
class VPSlotTracker;
class VPUser;
-class VPRecipeBase;
-class VPWidenMemoryInstructionRecipe;
+class VPRecipeBase;
+class VPWidenMemoryInstructionRecipe;
// This is the base class of the VPlan Def/Use graph, used for modeling the data
// flow into, within and out of the VPlan. VPValues can stand for live-ins
@@ -43,14 +43,14 @@ class VPWidenMemoryInstructionRecipe;
// and live-outs which the VPlan will need to fix accordingly.
class VPValue {
friend class VPBuilder;
- friend class VPDef;
- friend class VPInstruction;
+ friend class VPDef;
+ friend class VPInstruction;
friend struct VPlanTransforms;
friend class VPBasicBlock;
friend class VPInterleavedAccessInfo;
friend class VPSlotTracker;
- friend class VPRecipeBase;
- friend class VPWidenMemoryInstructionRecipe;
+ friend class VPRecipeBase;
+ friend class VPWidenMemoryInstructionRecipe;
const unsigned char SubclassID; ///< Subclass identifier (for isa/dyn_cast).
@@ -60,12 +60,12 @@ protected:
// Hold the underlying Value, if any, attached to this VPValue.
Value *UnderlyingVal;
- /// Pointer to the VPDef that defines this VPValue. If it is nullptr, the
- /// VPValue is not defined by any recipe modeled in VPlan.
- VPDef *Def;
+ /// Pointer to the VPDef that defines this VPValue. If it is nullptr, the
+ /// VPValue is not defined by any recipe modeled in VPlan.
+ VPDef *Def;
+
+ VPValue(const unsigned char SC, Value *UV = nullptr, VPDef *Def = nullptr);
- VPValue(const unsigned char SC, Value *UV = nullptr, VPDef *Def = nullptr);
-
// DESIGN PRINCIPLE: Access to the underlying IR must be strictly limited to
// the front-end and back-end of VPlan so that the middle-end is as
// independent as possible of the underlying IR. We grant access to the
@@ -80,33 +80,33 @@ protected:
}
public:
- /// Return the underlying Value attached to this VPValue.
- Value *getUnderlyingValue() { return UnderlyingVal; }
- const Value *getUnderlyingValue() const { return UnderlyingVal; }
-
+ /// Return the underlying Value attached to this VPValue.
+ Value *getUnderlyingValue() { return UnderlyingVal; }
+ const Value *getUnderlyingValue() const { return UnderlyingVal; }
+
/// An enumeration for keeping track of the concrete subclass of VPValue that
/// are actually instantiated. Values of this enumeration are kept in the
/// SubclassID field of the VPValue objects. They are used for concrete
/// type identification.
- enum {
- VPValueSC,
- VPVInstructionSC,
- VPVMemoryInstructionSC,
- VPVReductionSC,
- VPVReplicateSC,
- VPVWidenSC,
- VPVWidenCallSC,
- VPVWidenGEPSC,
- VPVWidenSelectSC,
- };
-
- VPValue(Value *UV = nullptr, VPDef *Def = nullptr)
- : VPValue(VPValueSC, UV, Def) {}
+ enum {
+ VPValueSC,
+ VPVInstructionSC,
+ VPVMemoryInstructionSC,
+ VPVReductionSC,
+ VPVReplicateSC,
+ VPVWidenSC,
+ VPVWidenCallSC,
+ VPVWidenGEPSC,
+ VPVWidenSelectSC,
+ };
+
+ VPValue(Value *UV = nullptr, VPDef *Def = nullptr)
+ : VPValue(VPValueSC, UV, Def) {}
VPValue(const VPValue &) = delete;
VPValue &operator=(const VPValue &) = delete;
- virtual ~VPValue();
-
+ virtual ~VPValue();
+
/// \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.
@@ -115,28 +115,28 @@ public:
void printAsOperand(raw_ostream &OS, VPSlotTracker &Tracker) const;
void print(raw_ostream &OS, VPSlotTracker &Tracker) const;
- /// Dump the value to stderr (for debugging).
- void dump() const;
-
+ /// Dump the value to stderr (for debugging).
+ void dump() const;
+
unsigned getNumUsers() const { return Users.size(); }
void addUser(VPUser &User) { Users.push_back(&User); }
- /// Remove a single \p User from the list of users.
- void removeUser(VPUser &User) {
- bool Found = false;
- // The same user can be added multiple times, e.g. because the same VPValue
- // is used twice by the same VPUser. Remove a single one.
- erase_if(Users, [&User, &Found](VPUser *Other) {
- if (Found)
- return false;
- if (Other == &User) {
- Found = true;
- return true;
- }
- return false;
- });
- }
-
+ /// Remove a single \p User from the list of users.
+ void removeUser(VPUser &User) {
+ bool Found = false;
+ // The same user can be added multiple times, e.g. because the same VPValue
+ // is used twice by the same VPUser. Remove a single one.
+ erase_if(Users, [&User, &Found](VPUser *Other) {
+ if (Found)
+ return false;
+ if (Other == &User) {
+ Found = true;
+ return true;
+ }
+ return false;
+ });
+ }
+
typedef SmallVectorImpl<VPUser *>::iterator user_iterator;
typedef SmallVectorImpl<VPUser *>::const_iterator const_user_iterator;
typedef iterator_range<user_iterator> user_range;
@@ -164,17 +164,17 @@ public:
}
void replaceAllUsesWith(VPValue *New);
-
- VPDef *getDef() { return Def; }
-
- /// Returns the underlying IR value, if this VPValue is defined outside the
- /// scope of VPlan. Returns nullptr if the VPValue is defined by a VPDef
- /// inside a VPlan.
- Value *getLiveInIRValue() {
- assert(!getDef() &&
- "VPValue is not a live-in; it is defined by a VPDef inside a VPlan");
- return getUnderlyingValue();
- }
+
+ VPDef *getDef() { return Def; }
+
+ /// Returns the underlying IR value, if this VPValue is defined outside the
+ /// scope of VPlan. Returns nullptr if the VPValue is defined by a VPDef
+ /// inside a VPlan.
+ Value *getLiveInIRValue() {
+ assert(!getDef() &&
+ "VPValue is not a live-in; it is defined by a VPDef inside a VPlan");
+ return getUnderlyingValue();
+ }
};
typedef DenseMap<Value *, VPValue *> Value2VPValueTy;
@@ -184,32 +184,32 @@ raw_ostream &operator<<(raw_ostream &OS, const VPValue &V);
/// This class augments VPValue with operands which provide the inverse def-use
/// edges from VPValue's users to their defs.
-class VPUser {
+class VPUser {
SmallVector<VPValue *, 2> Operands;
protected:
- /// Print the operands to \p O.
- void printOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const;
-
-public:
- VPUser() {}
- VPUser(ArrayRef<VPValue *> Operands) {
+ /// Print the operands to \p O.
+ void printOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const;
+
+public:
+ VPUser() {}
+ VPUser(ArrayRef<VPValue *> Operands) {
for (VPValue *Operand : Operands)
addOperand(Operand);
}
VPUser(std::initializer_list<VPValue *> Operands)
: VPUser(ArrayRef<VPValue *>(Operands)) {}
- template <typename IterT> VPUser(iterator_range<IterT> Operands) {
+ template <typename IterT> VPUser(iterator_range<IterT> Operands) {
for (VPValue *Operand : Operands)
addOperand(Operand);
}
VPUser(const VPUser &) = delete;
VPUser &operator=(const VPUser &) = delete;
- virtual ~VPUser() {
- for (VPValue *Op : operands())
- Op->removeUser(*this);
+ virtual ~VPUser() {
+ for (VPValue *Op : operands())
+ Op->removeUser(*this);
}
void addOperand(VPValue *Operand) {
@@ -223,11 +223,11 @@ public:
return Operands[N];
}
- void setOperand(unsigned I, VPValue *New) {
- Operands[I]->removeUser(*this);
- Operands[I] = New;
- New->addUser(*this);
- }
+ void setOperand(unsigned I, VPValue *New) {
+ Operands[I]->removeUser(*this);
+ Operands[I] = New;
+ New->addUser(*this);
+ }
typedef SmallVectorImpl<VPValue *>::iterator operand_iterator;
typedef SmallVectorImpl<VPValue *>::const_iterator const_operand_iterator;
@@ -242,110 +242,110 @@ public:
const_operand_range operands() const {
return const_operand_range(op_begin(), op_end());
}
-
- /// Method to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VPDef *Recipe);
+
+ /// Method to support type inquiry through isa, cast, and dyn_cast.
+ static inline bool classof(const VPDef *Recipe);
};
-
-/// This class augments a recipe with a set of VPValues defined by the recipe.
-/// It allows recipes to define zero, one or multiple VPValues. A VPDef owns
-/// the VPValues it defines and is responsible for deleting its defined values.
-/// Single-value VPDefs that also inherit from VPValue must make sure to inherit
-/// from VPDef before VPValue.
-class VPDef {
- friend class VPValue;
-
- /// Subclass identifier (for isa/dyn_cast).
- const unsigned char SubclassID;
-
- /// The VPValues defined by this VPDef.
- TinyPtrVector<VPValue *> DefinedValues;
-
- /// Add \p V as a defined value by this VPDef.
- void addDefinedValue(VPValue *V) {
- assert(V->getDef() == this &&
- "can only add VPValue already linked with this VPDef");
- DefinedValues.push_back(V);
- }
-
- /// Remove \p V from the values defined by this VPDef. \p V must be a defined
- /// value of this VPDef.
- void removeDefinedValue(VPValue *V) {
- assert(V->getDef() == this &&
- "can only remove VPValue linked with this VPDef");
- assert(is_contained(DefinedValues, V) &&
- "VPValue to remove must be in DefinedValues");
- erase_value(DefinedValues, V);
- V->Def = nullptr;
- }
-
-public:
- /// An enumeration for keeping track of the concrete subclass of VPRecipeBase
- /// that is actually instantiated. Values of this enumeration are kept in the
- /// SubclassID field of the VPRecipeBase objects. They are used for concrete
- /// type identification.
- using VPRecipeTy = enum {
- VPBlendSC,
- VPBranchOnMaskSC,
- VPInstructionSC,
- VPInterleaveSC,
- VPPredInstPHISC,
- VPReductionSC,
- VPReplicateSC,
- VPWidenCallSC,
- VPWidenCanonicalIVSC,
- VPWidenGEPSC,
- VPWidenIntOrFpInductionSC,
- VPWidenMemoryInstructionSC,
- VPWidenPHISC,
- VPWidenSC,
- VPWidenSelectSC
- };
-
- VPDef(const unsigned char SC) : SubclassID(SC) {}
-
- virtual ~VPDef() {
- for (VPValue *D : make_early_inc_range(DefinedValues)) {
- assert(D->Def == this &&
- "all defined VPValues should point to the containing VPDef");
- assert(D->getNumUsers() == 0 &&
- "all defined VPValues should have no more users");
- D->Def = nullptr;
- delete D;
- }
- }
-
- /// Returns the VPValue with index \p I defined by the VPDef.
- VPValue *getVPValue(unsigned I = 0) {
- assert(DefinedValues[I] && "defined value must be non-null");
- return DefinedValues[I];
- }
- const VPValue *getVPValue(unsigned I = 0) const {
- assert(DefinedValues[I] && "defined value must be non-null");
- return DefinedValues[I];
- }
-
- /// Returns an ArrayRef of the values defined by the VPDef.
- ArrayRef<VPValue *> definedValues() { return DefinedValues; }
- /// Returns an ArrayRef of the values defined by the VPDef.
- ArrayRef<VPValue *> definedValues() const { return DefinedValues; }
-
- /// Returns the number of values defined by the VPDef.
- unsigned getNumDefinedValues() const { return DefinedValues.size(); }
-
- /// \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.
- unsigned getVPDefID() const { return SubclassID; }
-
- /// Dump the VPDef to stderr (for debugging).
- void dump() const;
-
- /// Each concrete VPDef prints itself.
- virtual void print(raw_ostream &O, const Twine &Indent,
- VPSlotTracker &SlotTracker) const = 0;
-};
-
+
+/// This class augments a recipe with a set of VPValues defined by the recipe.
+/// It allows recipes to define zero, one or multiple VPValues. A VPDef owns
+/// the VPValues it defines and is responsible for deleting its defined values.
+/// Single-value VPDefs that also inherit from VPValue must make sure to inherit
+/// from VPDef before VPValue.
+class VPDef {
+ friend class VPValue;
+
+ /// Subclass identifier (for isa/dyn_cast).
+ const unsigned char SubclassID;
+
+ /// The VPValues defined by this VPDef.
+ TinyPtrVector<VPValue *> DefinedValues;
+
+ /// Add \p V as a defined value by this VPDef.
+ void addDefinedValue(VPValue *V) {
+ assert(V->getDef() == this &&
+ "can only add VPValue already linked with this VPDef");
+ DefinedValues.push_back(V);
+ }
+
+ /// Remove \p V from the values defined by this VPDef. \p V must be a defined
+ /// value of this VPDef.
+ void removeDefinedValue(VPValue *V) {
+ assert(V->getDef() == this &&
+ "can only remove VPValue linked with this VPDef");
+ assert(is_contained(DefinedValues, V) &&
+ "VPValue to remove must be in DefinedValues");
+ erase_value(DefinedValues, V);
+ V->Def = nullptr;
+ }
+
+public:
+ /// An enumeration for keeping track of the concrete subclass of VPRecipeBase
+ /// that is actually instantiated. Values of this enumeration are kept in the
+ /// SubclassID field of the VPRecipeBase objects. They are used for concrete
+ /// type identification.
+ using VPRecipeTy = enum {
+ VPBlendSC,
+ VPBranchOnMaskSC,
+ VPInstructionSC,
+ VPInterleaveSC,
+ VPPredInstPHISC,
+ VPReductionSC,
+ VPReplicateSC,
+ VPWidenCallSC,
+ VPWidenCanonicalIVSC,
+ VPWidenGEPSC,
+ VPWidenIntOrFpInductionSC,
+ VPWidenMemoryInstructionSC,
+ VPWidenPHISC,
+ VPWidenSC,
+ VPWidenSelectSC
+ };
+
+ VPDef(const unsigned char SC) : SubclassID(SC) {}
+
+ virtual ~VPDef() {
+ for (VPValue *D : make_early_inc_range(DefinedValues)) {
+ assert(D->Def == this &&
+ "all defined VPValues should point to the containing VPDef");
+ assert(D->getNumUsers() == 0 &&
+ "all defined VPValues should have no more users");
+ D->Def = nullptr;
+ delete D;
+ }
+ }
+
+ /// Returns the VPValue with index \p I defined by the VPDef.
+ VPValue *getVPValue(unsigned I = 0) {
+ assert(DefinedValues[I] && "defined value must be non-null");
+ return DefinedValues[I];
+ }
+ const VPValue *getVPValue(unsigned I = 0) const {
+ assert(DefinedValues[I] && "defined value must be non-null");
+ return DefinedValues[I];
+ }
+
+ /// Returns an ArrayRef of the values defined by the VPDef.
+ ArrayRef<VPValue *> definedValues() { return DefinedValues; }
+ /// Returns an ArrayRef of the values defined by the VPDef.
+ ArrayRef<VPValue *> definedValues() const { return DefinedValues; }
+
+ /// Returns the number of values defined by the VPDef.
+ unsigned getNumDefinedValues() const { return DefinedValues.size(); }
+
+ /// \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.
+ unsigned getVPDefID() const { return SubclassID; }
+
+ /// Dump the VPDef to stderr (for debugging).
+ void dump() const;
+
+ /// Each concrete VPDef prints itself.
+ virtual void print(raw_ostream &O, const Twine &Indent,
+ VPSlotTracker &SlotTracker) const = 0;
+};
+
class VPlan;
class VPBasicBlock;
class VPRegionBlock;
@@ -365,7 +365,7 @@ class VPSlotTracker {
void assignSlots(const VPlan &Plan);
public:
- VPSlotTracker(const VPlan *Plan = nullptr) {
+ VPSlotTracker(const VPlan *Plan = nullptr) {
if (Plan)
assignSlots(*Plan);
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanVerifier.cpp b/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanVerifier.cpp
index b8abab63df..6eec8d14de 100644
--- a/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanVerifier.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Vectorize/VPlanVerifier.cpp
@@ -65,7 +65,7 @@ static void verifyBlocksInRegion(const VPRegionBlock *Region) {
for (const VPBlockBase *Succ : Successors) {
// There must be a bi-directional link between block and successor.
const auto &SuccPreds = Succ->getPredecessors();
- assert(llvm::is_contained(SuccPreds, VPB) && "Missing predecessor link.");
+ assert(llvm::is_contained(SuccPreds, VPB) && "Missing predecessor link.");
(void)SuccPreds;
}
@@ -84,7 +84,7 @@ static void verifyBlocksInRegion(const VPRegionBlock *Region) {
// There must be a bi-directional link between block and predecessor.
const auto &PredSuccs = Pred->getSuccessors();
- assert(llvm::is_contained(PredSuccs, VPB) && "Missing successor link.");
+ assert(llvm::is_contained(PredSuccs, VPB) && "Missing successor link.");
(void)PredSuccs;
}
}
diff --git a/contrib/libs/llvm12/lib/Transforms/Vectorize/VectorCombine.cpp b/contrib/libs/llvm12/lib/Transforms/Vectorize/VectorCombine.cpp
index 7b0a72de4e..787f146bdd 100644
--- a/contrib/libs/llvm12/lib/Transforms/Vectorize/VectorCombine.cpp
+++ b/contrib/libs/llvm12/lib/Transforms/Vectorize/VectorCombine.cpp
@@ -16,7 +16,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/GlobalsModRef.h"
-#include "llvm/Analysis/Loads.h"
+#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/VectorUtils.h"
@@ -34,7 +34,7 @@ using namespace llvm;
using namespace llvm::PatternMatch;
#define DEBUG_TYPE "vector-combine"
-STATISTIC(NumVecLoad, "Number of vector loads formed");
+STATISTIC(NumVecLoad, "Number of vector loads formed");
STATISTIC(NumVecCmp, "Number of vector compares formed");
STATISTIC(NumVecBO, "Number of vector binops formed");
STATISTIC(NumVecCmpBO, "Number of vector compare + binop formed");
@@ -67,7 +67,7 @@ private:
const TargetTransformInfo &TTI;
const DominatorTree &DT;
- bool vectorizeLoadInsert(Instruction &I);
+ bool vectorizeLoadInsert(Instruction &I);
ExtractElementInst *getShuffleExtract(ExtractElementInst *Ext0,
ExtractElementInst *Ext1,
unsigned PreferredExtractIndex) const;
@@ -91,138 +91,138 @@ static void replaceValue(Value &Old, Value &New) {
New.takeName(&Old);
}
-bool VectorCombine::vectorizeLoadInsert(Instruction &I) {
- // Match insert into fixed vector of scalar value.
- // TODO: Handle non-zero insert index.
- auto *Ty = dyn_cast<FixedVectorType>(I.getType());
- Value *Scalar;
- if (!Ty || !match(&I, m_InsertElt(m_Undef(), m_Value(Scalar), m_ZeroInt())) ||
- !Scalar->hasOneUse())
- return false;
-
- // Optionally match an extract from another vector.
- Value *X;
- bool HasExtract = match(Scalar, m_ExtractElt(m_Value(X), m_ZeroInt()));
- if (!HasExtract)
- X = Scalar;
-
- // Match source value as load of scalar or vector.
- // Do not vectorize scalar load (widening) if atomic/volatile or under
- // asan/hwasan/memtag/tsan. The widened load may load data from dirty regions
- // or create data races non-existent in the source.
- auto *Load = dyn_cast<LoadInst>(X);
- if (!Load || !Load->isSimple() || !Load->hasOneUse() ||
- Load->getFunction()->hasFnAttribute(Attribute::SanitizeMemTag) ||
- mustSuppressSpeculation(*Load))
- return false;
-
- const DataLayout &DL = I.getModule()->getDataLayout();
- Value *SrcPtr = Load->getPointerOperand()->stripPointerCasts();
- assert(isa<PointerType>(SrcPtr->getType()) && "Expected a pointer type");
-
- // If original AS != Load's AS, we can't bitcast the original pointer and have
- // to use Load's operand instead. Ideally we would want to strip pointer casts
- // without changing AS, but there's no API to do that ATM.
- unsigned AS = Load->getPointerAddressSpace();
- if (AS != SrcPtr->getType()->getPointerAddressSpace())
- SrcPtr = Load->getPointerOperand();
-
- // We are potentially transforming byte-sized (8-bit) memory accesses, so make
- // sure we have all of our type-based constraints in place for this target.
- Type *ScalarTy = Scalar->getType();
- uint64_t ScalarSize = ScalarTy->getPrimitiveSizeInBits();
- unsigned MinVectorSize = TTI.getMinVectorRegisterBitWidth();
- if (!ScalarSize || !MinVectorSize || MinVectorSize % ScalarSize != 0 ||
- ScalarSize % 8 != 0)
- return false;
-
- // Check safety of replacing the scalar load with a larger vector load.
- // We use minimal alignment (maximum flexibility) because we only care about
- // the dereferenceable region. When calculating cost and creating a new op,
- // we may use a larger value based on alignment attributes.
- unsigned MinVecNumElts = MinVectorSize / ScalarSize;
- auto *MinVecTy = VectorType::get(ScalarTy, MinVecNumElts, false);
- unsigned OffsetEltIndex = 0;
- Align Alignment = Load->getAlign();
- if (!isSafeToLoadUnconditionally(SrcPtr, MinVecTy, Align(1), DL, Load, &DT)) {
- // It is not safe to load directly from the pointer, but we can still peek
- // through gep offsets and check if it safe to load from a base address with
- // updated alignment. If it is, we can shuffle the element(s) into place
- // after loading.
- unsigned OffsetBitWidth = DL.getIndexTypeSizeInBits(SrcPtr->getType());
- APInt Offset(OffsetBitWidth, 0);
- SrcPtr = SrcPtr->stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
-
- // We want to shuffle the result down from a high element of a vector, so
- // the offset must be positive.
- if (Offset.isNegative())
- return false;
-
- // The offset must be a multiple of the scalar element to shuffle cleanly
- // in the element's size.
- uint64_t ScalarSizeInBytes = ScalarSize / 8;
- if (Offset.urem(ScalarSizeInBytes) != 0)
- return false;
-
- // If we load MinVecNumElts, will our target element still be loaded?
- OffsetEltIndex = Offset.udiv(ScalarSizeInBytes).getZExtValue();
- if (OffsetEltIndex >= MinVecNumElts)
- return false;
-
- if (!isSafeToLoadUnconditionally(SrcPtr, MinVecTy, Align(1), DL, Load, &DT))
- return false;
-
- // Update alignment with offset value. Note that the offset could be negated
- // to more accurately represent "(new) SrcPtr - Offset = (old) SrcPtr", but
- // negation does not change the result of the alignment calculation.
- Alignment = commonAlignment(Alignment, Offset.getZExtValue());
- }
-
- // Original pattern: insertelt undef, load [free casts of] PtrOp, 0
- // Use the greater of the alignment on the load or its source pointer.
- Alignment = std::max(SrcPtr->getPointerAlignment(DL), Alignment);
- Type *LoadTy = Load->getType();
- InstructionCost OldCost =
- TTI.getMemoryOpCost(Instruction::Load, LoadTy, Alignment, AS);
- APInt DemandedElts = APInt::getOneBitSet(MinVecNumElts, 0);
- OldCost += TTI.getScalarizationOverhead(MinVecTy, DemandedElts,
- /* Insert */ true, HasExtract);
-
- // New pattern: load VecPtr
- InstructionCost NewCost =
- TTI.getMemoryOpCost(Instruction::Load, MinVecTy, Alignment, AS);
- // Optionally, we are shuffling the loaded vector element(s) into place.
- if (OffsetEltIndex)
- NewCost += TTI.getShuffleCost(TTI::SK_PermuteSingleSrc, MinVecTy);
-
- // We can aggressively convert to the vector form because the backend can
- // invert this transform if it does not result in a performance win.
- if (OldCost < NewCost || !NewCost.isValid())
- return false;
-
- // It is safe and potentially profitable to load a vector directly:
- // inselt undef, load Scalar, 0 --> load VecPtr
- IRBuilder<> Builder(Load);
- Value *CastedPtr = Builder.CreateBitCast(SrcPtr, MinVecTy->getPointerTo(AS));
- Value *VecLd = Builder.CreateAlignedLoad(MinVecTy, CastedPtr, Alignment);
-
- // Set everything but element 0 to undef to prevent poison from propagating
- // from the extra loaded memory. This will also optionally shrink/grow the
- // vector from the loaded size to the output size.
- // We assume this operation has no cost in codegen if there was no offset.
- // Note that we could use freeze to avoid poison problems, but then we might
- // still need a shuffle to change the vector size.
- unsigned OutputNumElts = Ty->getNumElements();
- SmallVector<int, 16> Mask(OutputNumElts, UndefMaskElem);
- assert(OffsetEltIndex < MinVecNumElts && "Address offset too big");
- Mask[0] = OffsetEltIndex;
- VecLd = Builder.CreateShuffleVector(VecLd, Mask);
-
- replaceValue(I, *VecLd);
- ++NumVecLoad;
- return true;
-}
-
+bool VectorCombine::vectorizeLoadInsert(Instruction &I) {
+ // Match insert into fixed vector of scalar value.
+ // TODO: Handle non-zero insert index.
+ auto *Ty = dyn_cast<FixedVectorType>(I.getType());
+ Value *Scalar;
+ if (!Ty || !match(&I, m_InsertElt(m_Undef(), m_Value(Scalar), m_ZeroInt())) ||
+ !Scalar->hasOneUse())
+ return false;
+
+ // Optionally match an extract from another vector.
+ Value *X;
+ bool HasExtract = match(Scalar, m_ExtractElt(m_Value(X), m_ZeroInt()));
+ if (!HasExtract)
+ X = Scalar;
+
+ // Match source value as load of scalar or vector.
+ // Do not vectorize scalar load (widening) if atomic/volatile or under
+ // asan/hwasan/memtag/tsan. The widened load may load data from dirty regions
+ // or create data races non-existent in the source.
+ auto *Load = dyn_cast<LoadInst>(X);
+ if (!Load || !Load->isSimple() || !Load->hasOneUse() ||
+ Load->getFunction()->hasFnAttribute(Attribute::SanitizeMemTag) ||
+ mustSuppressSpeculation(*Load))
+ return false;
+
+ const DataLayout &DL = I.getModule()->getDataLayout();
+ Value *SrcPtr = Load->getPointerOperand()->stripPointerCasts();
+ assert(isa<PointerType>(SrcPtr->getType()) && "Expected a pointer type");
+
+ // If original AS != Load's AS, we can't bitcast the original pointer and have
+ // to use Load's operand instead. Ideally we would want to strip pointer casts
+ // without changing AS, but there's no API to do that ATM.
+ unsigned AS = Load->getPointerAddressSpace();
+ if (AS != SrcPtr->getType()->getPointerAddressSpace())
+ SrcPtr = Load->getPointerOperand();
+
+ // We are potentially transforming byte-sized (8-bit) memory accesses, so make
+ // sure we have all of our type-based constraints in place for this target.
+ Type *ScalarTy = Scalar->getType();
+ uint64_t ScalarSize = ScalarTy->getPrimitiveSizeInBits();
+ unsigned MinVectorSize = TTI.getMinVectorRegisterBitWidth();
+ if (!ScalarSize || !MinVectorSize || MinVectorSize % ScalarSize != 0 ||
+ ScalarSize % 8 != 0)
+ return false;
+
+ // Check safety of replacing the scalar load with a larger vector load.
+ // We use minimal alignment (maximum flexibility) because we only care about
+ // the dereferenceable region. When calculating cost and creating a new op,
+ // we may use a larger value based on alignment attributes.
+ unsigned MinVecNumElts = MinVectorSize / ScalarSize;
+ auto *MinVecTy = VectorType::get(ScalarTy, MinVecNumElts, false);
+ unsigned OffsetEltIndex = 0;
+ Align Alignment = Load->getAlign();
+ if (!isSafeToLoadUnconditionally(SrcPtr, MinVecTy, Align(1), DL, Load, &DT)) {
+ // It is not safe to load directly from the pointer, but we can still peek
+ // through gep offsets and check if it safe to load from a base address with
+ // updated alignment. If it is, we can shuffle the element(s) into place
+ // after loading.
+ unsigned OffsetBitWidth = DL.getIndexTypeSizeInBits(SrcPtr->getType());
+ APInt Offset(OffsetBitWidth, 0);
+ SrcPtr = SrcPtr->stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
+
+ // We want to shuffle the result down from a high element of a vector, so
+ // the offset must be positive.
+ if (Offset.isNegative())
+ return false;
+
+ // The offset must be a multiple of the scalar element to shuffle cleanly
+ // in the element's size.
+ uint64_t ScalarSizeInBytes = ScalarSize / 8;
+ if (Offset.urem(ScalarSizeInBytes) != 0)
+ return false;
+
+ // If we load MinVecNumElts, will our target element still be loaded?
+ OffsetEltIndex = Offset.udiv(ScalarSizeInBytes).getZExtValue();
+ if (OffsetEltIndex >= MinVecNumElts)
+ return false;
+
+ if (!isSafeToLoadUnconditionally(SrcPtr, MinVecTy, Align(1), DL, Load, &DT))
+ return false;
+
+ // Update alignment with offset value. Note that the offset could be negated
+ // to more accurately represent "(new) SrcPtr - Offset = (old) SrcPtr", but
+ // negation does not change the result of the alignment calculation.
+ Alignment = commonAlignment(Alignment, Offset.getZExtValue());
+ }
+
+ // Original pattern: insertelt undef, load [free casts of] PtrOp, 0
+ // Use the greater of the alignment on the load or its source pointer.
+ Alignment = std::max(SrcPtr->getPointerAlignment(DL), Alignment);
+ Type *LoadTy = Load->getType();
+ InstructionCost OldCost =
+ TTI.getMemoryOpCost(Instruction::Load, LoadTy, Alignment, AS);
+ APInt DemandedElts = APInt::getOneBitSet(MinVecNumElts, 0);
+ OldCost += TTI.getScalarizationOverhead(MinVecTy, DemandedElts,
+ /* Insert */ true, HasExtract);
+
+ // New pattern: load VecPtr
+ InstructionCost NewCost =
+ TTI.getMemoryOpCost(Instruction::Load, MinVecTy, Alignment, AS);
+ // Optionally, we are shuffling the loaded vector element(s) into place.
+ if (OffsetEltIndex)
+ NewCost += TTI.getShuffleCost(TTI::SK_PermuteSingleSrc, MinVecTy);
+
+ // We can aggressively convert to the vector form because the backend can
+ // invert this transform if it does not result in a performance win.
+ if (OldCost < NewCost || !NewCost.isValid())
+ return false;
+
+ // It is safe and potentially profitable to load a vector directly:
+ // inselt undef, load Scalar, 0 --> load VecPtr
+ IRBuilder<> Builder(Load);
+ Value *CastedPtr = Builder.CreateBitCast(SrcPtr, MinVecTy->getPointerTo(AS));
+ Value *VecLd = Builder.CreateAlignedLoad(MinVecTy, CastedPtr, Alignment);
+
+ // Set everything but element 0 to undef to prevent poison from propagating
+ // from the extra loaded memory. This will also optionally shrink/grow the
+ // vector from the loaded size to the output size.
+ // We assume this operation has no cost in codegen if there was no offset.
+ // Note that we could use freeze to avoid poison problems, but then we might
+ // still need a shuffle to change the vector size.
+ unsigned OutputNumElts = Ty->getNumElements();
+ SmallVector<int, 16> Mask(OutputNumElts, UndefMaskElem);
+ assert(OffsetEltIndex < MinVecNumElts && "Address offset too big");
+ Mask[0] = OffsetEltIndex;
+ VecLd = Builder.CreateShuffleVector(VecLd, Mask);
+
+ replaceValue(I, *VecLd);
+ ++NumVecLoad;
+ return true;
+}
+
/// Determine which, if any, of the inputs should be replaced by a shuffle
/// followed by extract from a different index.
ExtractElementInst *VectorCombine::getShuffleExtract(
@@ -241,15 +241,15 @@ ExtractElementInst *VectorCombine::getShuffleExtract(
Type *VecTy = Ext0->getVectorOperand()->getType();
assert(VecTy == Ext1->getVectorOperand()->getType() && "Need matching types");
- InstructionCost Cost0 =
- TTI.getVectorInstrCost(Ext0->getOpcode(), VecTy, Index0);
- InstructionCost Cost1 =
- TTI.getVectorInstrCost(Ext1->getOpcode(), VecTy, Index1);
-
- // If both costs are invalid no shuffle is needed
- if (!Cost0.isValid() && !Cost1.isValid())
- return nullptr;
-
+ InstructionCost Cost0 =
+ TTI.getVectorInstrCost(Ext0->getOpcode(), VecTy, Index0);
+ InstructionCost Cost1 =
+ TTI.getVectorInstrCost(Ext1->getOpcode(), VecTy, Index1);
+
+ // If both costs are invalid no shuffle is needed
+ if (!Cost0.isValid() && !Cost1.isValid())
+ return nullptr;
+
// We are extracting from 2 different indexes, so one operand must be shuffled
// before performing a vector operation and/or extract. The more expensive
// extract will be replaced by a shuffle.
@@ -284,7 +284,7 @@ bool VectorCombine::isExtractExtractCheap(ExtractElementInst *Ext0,
"Expected constant extract indexes");
Type *ScalarTy = Ext0->getType();
auto *VecTy = cast<VectorType>(Ext0->getOperand(0)->getType());
- InstructionCost ScalarOpCost, VectorOpCost;
+ InstructionCost ScalarOpCost, VectorOpCost;
// Get cost estimates for scalar and vector versions of the operation.
bool IsBinOp = Instruction::isBinaryOp(Opcode);
@@ -305,9 +305,9 @@ bool VectorCombine::isExtractExtractCheap(ExtractElementInst *Ext0,
unsigned Ext0Index = cast<ConstantInt>(Ext0->getOperand(1))->getZExtValue();
unsigned Ext1Index = cast<ConstantInt>(Ext1->getOperand(1))->getZExtValue();
- InstructionCost Extract0Cost =
+ InstructionCost Extract0Cost =
TTI.getVectorInstrCost(Instruction::ExtractElement, VecTy, Ext0Index);
- InstructionCost Extract1Cost =
+ InstructionCost Extract1Cost =
TTI.getVectorInstrCost(Instruction::ExtractElement, VecTy, Ext1Index);
// A more expensive extract will always be replaced by a splat shuffle.
@@ -317,11 +317,11 @@ bool VectorCombine::isExtractExtractCheap(ExtractElementInst *Ext0,
// TODO: Evaluate whether that always results in lowest cost. Alternatively,
// check the cost of creating a broadcast shuffle and shuffling both
// operands to element 0.
- InstructionCost CheapExtractCost = std::min(Extract0Cost, Extract1Cost);
+ InstructionCost CheapExtractCost = std::min(Extract0Cost, Extract1Cost);
// Extra uses of the extracts mean that we include those costs in the
// vector total because those instructions will not be eliminated.
- InstructionCost OldCost, NewCost;
+ InstructionCost OldCost, NewCost;
if (Ext0->getOperand(0) == Ext1->getOperand(0) && Ext0Index == Ext1Index) {
// Handle a special case. If the 2 extracts are identical, adjust the
// formulas to account for that. The extra use charge allows for either the
@@ -372,7 +372,7 @@ static Value *createShiftShuffle(Value *Vec, unsigned OldIndex,
auto *VecTy = cast<FixedVectorType>(Vec->getType());
SmallVector<int, 32> ShufMask(VecTy->getNumElements(), UndefMaskElem);
ShufMask[NewIndex] = OldIndex;
- return Builder.CreateShuffleVector(Vec, ShufMask, "shift");
+ return Builder.CreateShuffleVector(Vec, ShufMask, "shift");
}
/// Given an extract element instruction with constant index operand, shuffle
@@ -506,23 +506,23 @@ bool VectorCombine::foldBitcastShuf(Instruction &I) {
m_OneUse(m_Shuffle(m_Value(V), m_Undef(), m_Mask(Mask))))))
return false;
- // 1) Do not fold bitcast shuffle for scalable type. First, shuffle cost for
- // scalable type is unknown; Second, we cannot reason if the narrowed shuffle
- // mask for scalable type is a splat or not.
- // 2) Disallow non-vector casts and length-changing shuffles.
+ // 1) Do not fold bitcast shuffle for scalable type. First, shuffle cost for
+ // scalable type is unknown; Second, we cannot reason if the narrowed shuffle
+ // mask for scalable type is a splat or not.
+ // 2) Disallow non-vector casts and length-changing shuffles.
// TODO: We could allow any shuffle.
- auto *DestTy = dyn_cast<FixedVectorType>(I.getType());
- auto *SrcTy = dyn_cast<FixedVectorType>(V->getType());
- if (!SrcTy || !DestTy || I.getOperand(0)->getType() != SrcTy)
+ auto *DestTy = dyn_cast<FixedVectorType>(I.getType());
+ auto *SrcTy = dyn_cast<FixedVectorType>(V->getType());
+ if (!SrcTy || !DestTy || I.getOperand(0)->getType() != SrcTy)
return false;
// The new shuffle must not cost more than the old shuffle. The bitcast is
// moved ahead of the shuffle, so assume that it has the same cost as before.
- InstructionCost DestCost =
- TTI.getShuffleCost(TargetTransformInfo::SK_PermuteSingleSrc, DestTy);
- InstructionCost SrcCost =
- TTI.getShuffleCost(TargetTransformInfo::SK_PermuteSingleSrc, SrcTy);
- if (DestCost > SrcCost || !DestCost.isValid())
+ InstructionCost DestCost =
+ TTI.getShuffleCost(TargetTransformInfo::SK_PermuteSingleSrc, DestTy);
+ InstructionCost SrcCost =
+ TTI.getShuffleCost(TargetTransformInfo::SK_PermuteSingleSrc, SrcTy);
+ if (DestCost > SrcCost || !DestCost.isValid())
return false;
unsigned DestNumElts = DestTy->getNumElements();
@@ -545,7 +545,7 @@ bool VectorCombine::foldBitcastShuf(Instruction &I) {
// bitcast (shuf V, MaskC) --> shuf (bitcast V), MaskC'
++NumShufOfBitcast;
Value *CastV = Builder.CreateBitCast(V, DestTy);
- Value *Shuf = Builder.CreateShuffleVector(CastV, NewMask);
+ Value *Shuf = Builder.CreateShuffleVector(CastV, NewMask);
replaceValue(I, *Shuf);
return true;
}
@@ -612,7 +612,7 @@ bool VectorCombine::scalarizeBinopOrCmp(Instruction &I) {
"Unexpected types for insert element into binop or cmp");
unsigned Opcode = I.getOpcode();
- InstructionCost ScalarOpCost, VectorOpCost;
+ InstructionCost ScalarOpCost, VectorOpCost;
if (IsCmp) {
ScalarOpCost = TTI.getCmpSelInstrCost(Opcode, ScalarTy);
VectorOpCost = TTI.getCmpSelInstrCost(Opcode, VecTy);
@@ -623,16 +623,16 @@ bool VectorCombine::scalarizeBinopOrCmp(Instruction &I) {
// Get cost estimate for the insert element. This cost will factor into
// both sequences.
- InstructionCost InsertCost =
+ InstructionCost InsertCost =
TTI.getVectorInstrCost(Instruction::InsertElement, VecTy, Index);
- InstructionCost OldCost =
- (IsConst0 ? 0 : InsertCost) + (IsConst1 ? 0 : InsertCost) + VectorOpCost;
- InstructionCost NewCost = ScalarOpCost + InsertCost +
- (IsConst0 ? 0 : !Ins0->hasOneUse() * InsertCost) +
- (IsConst1 ? 0 : !Ins1->hasOneUse() * InsertCost);
+ InstructionCost OldCost =
+ (IsConst0 ? 0 : InsertCost) + (IsConst1 ? 0 : InsertCost) + VectorOpCost;
+ InstructionCost NewCost = ScalarOpCost + InsertCost +
+ (IsConst0 ? 0 : !Ins0->hasOneUse() * InsertCost) +
+ (IsConst1 ? 0 : !Ins1->hasOneUse() * InsertCost);
// We want to scalarize unless the vector variant actually has lower cost.
- if (OldCost < NewCost || !NewCost.isValid())
+ if (OldCost < NewCost || !NewCost.isValid())
return false;
// vec_op (inselt VecC0, V0, Index), (inselt VecC1, V1, Index) -->
@@ -712,8 +712,8 @@ bool VectorCombine::foldExtractedCmps(Instruction &I) {
if (!VecTy)
return false;
- InstructionCost OldCost =
- TTI.getVectorInstrCost(Ext0->getOpcode(), VecTy, Index0);
+ InstructionCost OldCost =
+ TTI.getVectorInstrCost(Ext0->getOpcode(), VecTy, Index0);
OldCost += TTI.getVectorInstrCost(Ext1->getOpcode(), VecTy, Index1);
OldCost += TTI.getCmpSelInstrCost(CmpOpcode, I0->getType()) * 2;
OldCost += TTI.getArithmeticInstrCost(I.getOpcode(), I.getType());
@@ -724,7 +724,7 @@ bool VectorCombine::foldExtractedCmps(Instruction &I) {
int CheapIndex = ConvertToShuf == Ext0 ? Index1 : Index0;
int ExpensiveIndex = ConvertToShuf == Ext0 ? Index0 : Index1;
auto *CmpTy = cast<FixedVectorType>(CmpInst::makeCmpResultType(X->getType()));
- InstructionCost NewCost = TTI.getCmpSelInstrCost(CmpOpcode, X->getType());
+ InstructionCost NewCost = TTI.getCmpSelInstrCost(CmpOpcode, X->getType());
NewCost +=
TTI.getShuffleCost(TargetTransformInfo::SK_PermuteSingleSrc, CmpTy);
NewCost += TTI.getArithmeticInstrCost(I.getOpcode(), CmpTy);
@@ -733,7 +733,7 @@ bool VectorCombine::foldExtractedCmps(Instruction &I) {
// Aggressively form vector ops if the cost is equal because the transform
// may enable further optimization.
// Codegen can reverse this transform (scalarize) if it was not profitable.
- if (OldCost < NewCost || !NewCost.isValid())
+ if (OldCost < NewCost || !NewCost.isValid())
return false;
// Create a vector constant from the 2 scalar constants.
@@ -758,10 +758,10 @@ bool VectorCombine::run() {
if (DisableVectorCombine)
return false;
- // Don't attempt vectorization if the target does not support vectors.
- if (!TTI.getNumberOfRegisters(TTI.getRegisterClassForType(/*Vector*/ true)))
- return false;
-
+ // Don't attempt vectorization if the target does not support vectors.
+ if (!TTI.getNumberOfRegisters(TTI.getRegisterClassForType(/*Vector*/ true)))
+ return false;
+
bool MadeChange = false;
for (BasicBlock &BB : F) {
// Ignore unreachable basic blocks.
@@ -775,7 +775,7 @@ bool VectorCombine::run() {
if (isa<DbgInfoIntrinsic>(I))
continue;
Builder.SetInsertPoint(&I);
- MadeChange |= vectorizeLoadInsert(I);
+ MadeChange |= vectorizeLoadInsert(I);
MadeChange |= foldExtractExtract(I);
MadeChange |= foldBitcastShuf(I);
MadeChange |= scalarizeBinopOrCmp(I);
diff --git a/contrib/libs/llvm12/lib/Transforms/Vectorize/ya.make b/contrib/libs/llvm12/lib/Transforms/Vectorize/ya.make
index a3879c3129..a68c667bde 100644
--- a/contrib/libs/llvm12/lib/Transforms/Vectorize/ya.make
+++ b/contrib/libs/llvm12/lib/Transforms/Vectorize/ya.make
@@ -12,12 +12,12 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Transforms/Utils
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Transforms/Utils
)
ADDINCL(
diff --git a/contrib/libs/llvm12/provides.pbtxt b/contrib/libs/llvm12/provides.pbtxt
index 3674550db2..52f7e3b149 100644
--- a/contrib/libs/llvm12/provides.pbtxt
+++ b/contrib/libs/llvm12/provides.pbtxt
@@ -1,175 +1,175 @@
-p { i: "llvm" x: "LLVMAArch64AsmParser" ix: true peerdir: "contrib/libs/llvm12/lib/Target/AArch64/AsmParser" }
-p { i: "llvm" x: "LLVMAArch64CodeGen" ix: true peerdir: "contrib/libs/llvm12/lib/Target/AArch64" }
-p { i: "llvm" x: "LLVMAArch64Desc" ix: true peerdir: "contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc" }
-p { i: "llvm" x: "LLVMAArch64Disassembler" ix: true peerdir: "contrib/libs/llvm12/lib/Target/AArch64/Disassembler" }
-p { i: "llvm" x: "LLVMAArch64Info" ix: true peerdir: "contrib/libs/llvm12/lib/Target/AArch64/TargetInfo" }
-p { i: "llvm" x: "LLVMAArch64Utils" ix: true peerdir: "contrib/libs/llvm12/lib/Target/AArch64/Utils" }
-p { i: "llvm" x: "LLVMARMAsmParser" ix: true peerdir: "contrib/libs/llvm12/lib/Target/ARM/AsmParser" }
-p { i: "llvm" x: "LLVMARMCodeGen" ix: true peerdir: "contrib/libs/llvm12/lib/Target/ARM" }
-p { i: "llvm" x: "LLVMARMDesc" ix: true peerdir: "contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc" }
-p { i: "llvm" x: "LLVMARMDisassembler" ix: true peerdir: "contrib/libs/llvm12/lib/Target/ARM/Disassembler" }
-p { i: "llvm" x: "LLVMARMInfo" ix: true peerdir: "contrib/libs/llvm12/lib/Target/ARM/TargetInfo" }
-p { i: "llvm" x: "LLVMARMUtils" ix: true peerdir: "contrib/libs/llvm12/lib/Target/ARM/Utils" }
-p { i: "llvm" x: "LLVMAggressiveInstCombine" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine" }
-p { i: "llvm" x: "LLVMAnalysis" ix: true peerdir: "contrib/libs/llvm12/lib/Analysis" }
-p { i: "llvm" x: "LLVMAsmParser" ix: true peerdir: "contrib/libs/llvm12/lib/AsmParser" }
-p { i: "llvm" x: "LLVMAsmPrinter" ix: true peerdir: "contrib/libs/llvm12/lib/CodeGen/AsmPrinter" }
-p { i: "llvm" x: "LLVMBPFAsmParser" ix: true peerdir: "contrib/libs/llvm12/lib/Target/BPF/AsmParser" }
-p { i: "llvm" x: "LLVMBPFCodeGen" ix: true peerdir: "contrib/libs/llvm12/lib/Target/BPF" }
-p { i: "llvm" x: "LLVMBPFDesc" ix: true peerdir: "contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc" }
-p { i: "llvm" x: "LLVMBPFDisassembler" ix: true peerdir: "contrib/libs/llvm12/lib/Target/BPF/Disassembler" }
-p { i: "llvm" x: "LLVMBPFInfo" ix: true peerdir: "contrib/libs/llvm12/lib/Target/BPF/TargetInfo" }
-p { i: "llvm" x: "LLVMBinaryFormat" ix: true peerdir: "contrib/libs/llvm12/lib/BinaryFormat" }
-p { i: "llvm" x: "LLVMBitReader" ix: true peerdir: "contrib/libs/llvm12/lib/Bitcode/Reader" }
-p { i: "llvm" x: "LLVMBitWriter" ix: true peerdir: "contrib/libs/llvm12/lib/Bitcode/Writer" }
-p { i: "llvm" x: "LLVMBitstreamReader" ix: true peerdir: "contrib/libs/llvm12/lib/Bitstream/Reader" }
-p { i: "llvm" x: "LLVMCFGuard" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/CFGuard" }
-p { i: "llvm" x: "LLVMCFIVerify" ix: true peerdir: "contrib/libs/llvm12/tools/llvm-cfi-verify/lib" }
-p { i: "llvm" x: "LLVMCodeGen" ix: true peerdir: "contrib/libs/llvm12/lib/CodeGen" }
-p { i: "llvm" x: "LLVMCore" ix: true peerdir: "contrib/libs/llvm12/lib/IR" }
-p { i: "llvm" x: "LLVMCoroutines" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/Coroutines" }
-p { i: "llvm" x: "LLVMCoverage" ix: true peerdir: "contrib/libs/llvm12/lib/ProfileData/Coverage" }
-p { i: "llvm" x: "LLVMDWARFLinker" ix: true peerdir: "contrib/libs/llvm12/lib/DWARFLinker" }
-p { i: "llvm" x: "LLVMDebugInfoCodeView" ix: true peerdir: "contrib/libs/llvm12/lib/DebugInfo/CodeView" }
-p { i: "llvm" x: "LLVMDebugInfoDWARF" ix: true peerdir: "contrib/libs/llvm12/lib/DebugInfo/DWARF" }
-p { i: "llvm" x: "LLVMDebugInfoGSYM" ix: true peerdir: "contrib/libs/llvm12/lib/DebugInfo/GSYM" }
-p { i: "llvm" x: "LLVMDebugInfoMSF" ix: true peerdir: "contrib/libs/llvm12/lib/DebugInfo/MSF" }
-p { i: "llvm" x: "LLVMDebugInfoPDB" ix: true peerdir: "contrib/libs/llvm12/lib/DebugInfo/PDB" }
-p { i: "llvm" x: "LLVMDemangle" ix: true peerdir: "contrib/libs/llvm12/lib/Demangle" }
-p { i: "llvm" x: "LLVMDlltoolDriver" ix: true peerdir: "contrib/libs/llvm12/lib/ToolDrivers/llvm-dlltool" }
-p { i: "llvm" x: "LLVMExecutionEngine" ix: true peerdir: "contrib/libs/llvm12/lib/ExecutionEngine" }
-p { i: "llvm" x: "LLVMExegesis" ix: true peerdir: "contrib/libs/llvm12/tools/llvm-exegesis/lib" }
-p { i: "llvm" x: "LLVMExegesisAArch64" ix: true peerdir: "contrib/libs/llvm12/tools/llvm-exegesis/lib/AArch64" }
-p { i: "llvm" x: "LLVMExegesisPowerPC" ix: true peerdir: "contrib/libs/llvm12/tools/llvm-exegesis/lib/PowerPC" }
-p { i: "llvm" x: "LLVMExegesisX86" ix: true peerdir: "contrib/libs/llvm12/tools/llvm-exegesis/lib/X86" }
-p { i: "llvm" x: "LLVMExtensions" ix: true peerdir: "contrib/libs/llvm12/lib/Extensions" }
-p { i: "llvm" x: "LLVMFileCheck" ix: true peerdir: "contrib/libs/llvm12/lib/FileCheck" }
-p { i: "llvm" x: "LLVMFrontendOpenACC" ix: true peerdir: "contrib/libs/llvm12/lib/Frontend/OpenACC" }
-p { i: "llvm" x: "LLVMFrontendOpenMP" ix: true peerdir: "contrib/libs/llvm12/lib/Frontend/OpenMP" }
-p { i: "llvm" x: "LLVMFuzzMutate" ix: true peerdir: "contrib/libs/llvm12/lib/FuzzMutate" }
-p { i: "llvm" x: "LLVMGlobalISel" ix: true peerdir: "contrib/libs/llvm12/lib/CodeGen/GlobalISel" }
-p { i: "llvm" x: "LLVMHelloNew" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/HelloNew" }
-p { i: "llvm" x: "LLVMIRReader" ix: true peerdir: "contrib/libs/llvm12/lib/IRReader" }
-p { i: "llvm" x: "LLVMInstCombine" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/InstCombine" }
-p { i: "llvm" x: "LLVMInstrumentation" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/Instrumentation" }
-p { i: "llvm" x: "LLVMInterfaceStub" ix: true peerdir: "contrib/libs/llvm12/lib/InterfaceStub" }
-p { i: "llvm" x: "LLVMInterpreter" ix: true peerdir: "contrib/libs/llvm12/lib/ExecutionEngine/Interpreter" }
-p { i: "llvm" x: "LLVMJITLink" ix: true peerdir: "contrib/libs/llvm12/lib/ExecutionEngine/JITLink" }
-p { i: "llvm" x: "LLVMLTO" ix: true peerdir: "contrib/libs/llvm12/lib/LTO" }
-p { i: "llvm" x: "LLVMLibDriver" ix: true peerdir: "contrib/libs/llvm12/lib/ToolDrivers/llvm-lib" }
-p { i: "llvm" x: "LLVMLineEditor" ix: true peerdir: "contrib/libs/llvm12/lib/LineEditor" }
-p { i: "llvm" x: "LLVMLinker" ix: true peerdir: "contrib/libs/llvm12/lib/Linker" }
-p { i: "llvm" x: "LLVMMC" ix: true peerdir: "contrib/libs/llvm12/lib/MC" }
-p { i: "llvm" x: "LLVMMCA" ix: true peerdir: "contrib/libs/llvm12/lib/MCA" }
-p { i: "llvm" x: "LLVMMCDisassembler" ix: true peerdir: "contrib/libs/llvm12/lib/MC/MCDisassembler" }
-p { i: "llvm" x: "LLVMMCJIT" ix: true peerdir: "contrib/libs/llvm12/lib/ExecutionEngine/MCJIT" }
-p { i: "llvm" x: "LLVMMCParser" ix: true peerdir: "contrib/libs/llvm12/lib/MC/MCParser" }
-p { i: "llvm" x: "LLVMMIRParser" ix: true peerdir: "contrib/libs/llvm12/lib/CodeGen/MIRParser" }
-p { i: "llvm" x: "LLVMNVPTXCodeGen" ix: true peerdir: "contrib/libs/llvm12/lib/Target/NVPTX" }
-p { i: "llvm" x: "LLVMNVPTXDesc" ix: true peerdir: "contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc" }
-p { i: "llvm" x: "LLVMNVPTXInfo" ix: true peerdir: "contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo" }
-p { i: "llvm" x: "LLVMObjCARCOpts" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/ObjCARC" }
-p { i: "llvm" x: "LLVMObject" ix: true peerdir: "contrib/libs/llvm12/lib/Object" }
-p { i: "llvm" x: "LLVMObjectYAML" ix: true peerdir: "contrib/libs/llvm12/lib/ObjectYAML" }
-p { i: "llvm" x: "LLVMOption" ix: true peerdir: "contrib/libs/llvm12/lib/Option" }
-p { i: "llvm" x: "LLVMOrcJIT" ix: true peerdir: "contrib/libs/llvm12/lib/ExecutionEngine/Orc" }
-p { i: "llvm" x: "LLVMOrcShared" ix: true peerdir: "contrib/libs/llvm12/lib/ExecutionEngine/Orc/Shared" }
-p { i: "llvm" x: "LLVMOrcTargetProcess" ix: true peerdir: "contrib/libs/llvm12/lib/ExecutionEngine/Orc/TargetProcess" }
-p { i: "llvm" x: "LLVMPasses" ix: true peerdir: "contrib/libs/llvm12/lib/Passes" }
-p { i: "llvm" x: "LLVMPerfJITEvents" ix: true peerdir: "contrib/libs/llvm12/lib/ExecutionEngine/PerfJITEvents" }
-p { i: "llvm" x: "LLVMPowerPCAsmParser" ix: true peerdir: "contrib/libs/llvm12/lib/Target/PowerPC/AsmParser" }
-p { i: "llvm" x: "LLVMPowerPCCodeGen" ix: true peerdir: "contrib/libs/llvm12/lib/Target/PowerPC" }
-p { i: "llvm" x: "LLVMPowerPCDesc" ix: true peerdir: "contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc" }
-p { i: "llvm" x: "LLVMPowerPCDisassembler" ix: true peerdir: "contrib/libs/llvm12/lib/Target/PowerPC/Disassembler" }
-p { i: "llvm" x: "LLVMPowerPCInfo" ix: true peerdir: "contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo" }
-p { i: "llvm" x: "LLVMProfileData" ix: true peerdir: "contrib/libs/llvm12/lib/ProfileData" }
-p { i: "llvm" x: "LLVMRemarks" ix: true peerdir: "contrib/libs/llvm12/lib/Remarks" }
-p { i: "llvm" x: "LLVMRuntimeDyld" ix: true peerdir: "contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld" }
-p { i: "llvm" x: "LLVMScalarOpts" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/Scalar" }
-p { i: "llvm" x: "LLVMSelectionDAG" ix: true peerdir: "contrib/libs/llvm12/lib/CodeGen/SelectionDAG" }
-p { i: "llvm" x: "LLVMSupport" ix: true peerdir: "contrib/libs/llvm12/lib/Support" }
-p { i: "llvm" x: "LLVMSymbolize" ix: true peerdir: "contrib/libs/llvm12/lib/DebugInfo/Symbolize" }
-p { i: "llvm" x: "LLVMTableGen" ix: true peerdir: "contrib/libs/llvm12/lib/TableGen" }
-p { i: "llvm" x: "LLVMTableGenGlobalISel" ix: true peerdir: "contrib/libs/llvm12/utils/TableGen/GlobalISel" }
-p { i: "llvm" x: "LLVMTarget" ix: true peerdir: "contrib/libs/llvm12/lib/Target" }
-p { i: "llvm" x: "LLVMTextAPI" ix: true peerdir: "contrib/libs/llvm12/lib/TextAPI/MachO" }
-p { i: "llvm" x: "LLVMTransformUtils" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/Utils" }
-p { i: "llvm" x: "LLVMVectorize" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/Vectorize" }
-p { i: "llvm" x: "LLVMWindowsManifest" ix: true peerdir: "contrib/libs/llvm12/lib/WindowsManifest" }
-p { i: "llvm" x: "LLVMX86AsmParser" ix: true peerdir: "contrib/libs/llvm12/lib/Target/X86/AsmParser" }
-p { i: "llvm" x: "LLVMX86CodeGen" ix: true peerdir: "contrib/libs/llvm12/lib/Target/X86" }
-p { i: "llvm" x: "LLVMX86Desc" ix: true peerdir: "contrib/libs/llvm12/lib/Target/X86/MCTargetDesc" }
-p { i: "llvm" x: "LLVMX86Disassembler" ix: true peerdir: "contrib/libs/llvm12/lib/Target/X86/Disassembler" }
-p { i: "llvm" x: "LLVMX86Info" ix: true peerdir: "contrib/libs/llvm12/lib/Target/X86/TargetInfo" }
-p { i: "llvm" x: "LLVMXRay" ix: true peerdir: "contrib/libs/llvm12/lib/XRay" }
-p { i: "llvm" x: "LLVMgold" ix: true peerdir: "contrib/libs/llvm12/tools/gold" }
-p { i: "llvm" x: "LLVMipo" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/IPO" }
-p { i: "llvm" x: "LTO" ix: true peerdir: "contrib/libs/llvm12/tools/lto" }
-p { i: "llvm" x: "Polly" ix: true peerdir: "contrib/libs/llvm12/tools/polly/lib" }
-p { i: "llvm" x: "PollyISL" ix: true peerdir: "contrib/libs/llvm12/tools/polly/lib/External/isl" }
-p { i: "llvm" x: "PollyPPCG" ix: true peerdir: "contrib/libs/llvm12/tools/polly/lib/External/ppcg" }
-p { i: "llvm" x: "Remarks" ix: true peerdir: "contrib/libs/llvm12/tools/remarks-shlib" }
-p { x: "bugpoint" peerdir: "contrib/libs/llvm12/tools/bugpoint" }
-p { x: "dsymutil" peerdir: "contrib/libs/llvm12/tools/dsymutil" }
-p { x: "llc" peerdir: "contrib/libs/llvm12/tools/llc" }
-p { x: "lli" peerdir: "contrib/libs/llvm12/tools/lli" }
-p { x: "lli-child-target" peerdir: "contrib/libs/llvm12/tools/lli/ChildTarget" }
-p { x: "llvm-ar" peerdir: "contrib/libs/llvm12/tools/llvm-ar" }
-p { x: "llvm-as" peerdir: "contrib/libs/llvm12/tools/llvm-as" }
-p { x: "llvm-bcanalyzer" peerdir: "contrib/libs/llvm12/tools/llvm-bcanalyzer" }
-p { x: "llvm-cat" peerdir: "contrib/libs/llvm12/tools/llvm-cat" }
-p { x: "llvm-cfi-verify" peerdir: "contrib/libs/llvm12/tools/llvm-cfi-verify" }
-p { x: "llvm-config" peerdir: "contrib/libs/llvm12/tools/llvm-config" }
-p { x: "llvm-cov" peerdir: "contrib/libs/llvm12/tools/llvm-cov" }
-p { x: "llvm-cvtres" peerdir: "contrib/libs/llvm12/tools/llvm-cvtres" }
-p { x: "llvm-cxxdump" peerdir: "contrib/libs/llvm12/tools/llvm-cxxdump" }
-p { x: "llvm-cxxfilt" peerdir: "contrib/libs/llvm12/tools/llvm-cxxfilt" }
-p { x: "llvm-cxxmap" peerdir: "contrib/libs/llvm12/tools/llvm-cxxmap" }
-p { x: "llvm-diff" peerdir: "contrib/libs/llvm12/tools/llvm-diff" }
-p { x: "llvm-dis" peerdir: "contrib/libs/llvm12/tools/llvm-dis" }
-p { x: "llvm-dwarfdump" peerdir: "contrib/libs/llvm12/tools/llvm-dwarfdump" }
-p { x: "llvm-dwp" peerdir: "contrib/libs/llvm12/tools/llvm-dwp" }
-p { x: "llvm-elfabi" peerdir: "contrib/libs/llvm12/tools/llvm-elfabi" }
-p { x: "llvm-exegesis" peerdir: "contrib/libs/llvm12/tools/llvm-exegesis" }
-p { x: "llvm-extract" peerdir: "contrib/libs/llvm12/tools/llvm-extract" }
-p { x: "llvm-gsymutil" peerdir: "contrib/libs/llvm12/tools/llvm-gsymutil" }
-p { x: "llvm-ifs" peerdir: "contrib/libs/llvm12/tools/llvm-ifs" }
-p { x: "llvm-jitlink" peerdir: "contrib/libs/llvm12/tools/llvm-jitlink" }
-p { x: "llvm-jitlink-executor" peerdir: "contrib/libs/llvm12/tools/llvm-jitlink/llvm-jitlink-executor" }
-p { x: "llvm-libtool-darwin" peerdir: "contrib/libs/llvm12/tools/llvm-libtool-darwin" }
-p { x: "llvm-link" peerdir: "contrib/libs/llvm12/tools/llvm-link" }
-p { x: "llvm-lipo" peerdir: "contrib/libs/llvm12/tools/llvm-lipo" }
-p { x: "llvm-lto" peerdir: "contrib/libs/llvm12/tools/llvm-lto" }
-p { x: "llvm-lto2" peerdir: "contrib/libs/llvm12/tools/llvm-lto2" }
-p { x: "llvm-mc" peerdir: "contrib/libs/llvm12/tools/llvm-mc" }
-p { x: "llvm-mca" peerdir: "contrib/libs/llvm12/tools/llvm-mca" }
-p { x: "llvm-ml" peerdir: "contrib/libs/llvm12/tools/llvm-ml" }
-p { x: "llvm-modextract" peerdir: "contrib/libs/llvm12/tools/llvm-modextract" }
-p { x: "llvm-mt" peerdir: "contrib/libs/llvm12/tools/llvm-mt" }
-p { x: "llvm-nm" peerdir: "contrib/libs/llvm12/tools/llvm-nm" }
-p { x: "llvm-objcopy" peerdir: "contrib/libs/llvm12/tools/llvm-objcopy" }
-p { x: "llvm-objdump" peerdir: "contrib/libs/llvm12/tools/llvm-objdump" }
-p { x: "llvm-opt-report" peerdir: "contrib/libs/llvm12/tools/llvm-opt-report" }
-p { x: "llvm-pdbutil" peerdir: "contrib/libs/llvm12/tools/llvm-pdbutil" }
-p { x: "llvm-profdata" peerdir: "contrib/libs/llvm12/tools/llvm-profdata" }
-p { x: "llvm-profgen" peerdir: "contrib/libs/llvm12/tools/llvm-profgen" }
-p { x: "llvm-rc" peerdir: "contrib/libs/llvm12/tools/llvm-rc" }
-p { x: "llvm-readobj" peerdir: "contrib/libs/llvm12/tools/llvm-readobj" }
-p { x: "llvm-reduce" peerdir: "contrib/libs/llvm12/tools/llvm-reduce" }
-p { x: "llvm-rtdyld" peerdir: "contrib/libs/llvm12/tools/llvm-rtdyld" }
-p { x: "llvm-size" peerdir: "contrib/libs/llvm12/tools/llvm-size" }
-p { x: "llvm-split" peerdir: "contrib/libs/llvm12/tools/llvm-split" }
-p { x: "llvm-stress" peerdir: "contrib/libs/llvm12/tools/llvm-stress" }
-p { x: "llvm-strings" peerdir: "contrib/libs/llvm12/tools/llvm-strings" }
-p { x: "llvm-symbolizer" peerdir: "contrib/libs/llvm12/tools/llvm-symbolizer" }
-p { x: "llvm-tblgen" peerdir: "contrib/libs/llvm12/utils/TableGen" }
-p { x: "llvm-undname" peerdir: "contrib/libs/llvm12/tools/llvm-undname" }
-p { x: "llvm-xray" peerdir: "contrib/libs/llvm12/tools/llvm-xray" }
-p { x: "obj2yaml" peerdir: "contrib/libs/llvm12/tools/obj2yaml" }
-p { x: "opt" peerdir: "contrib/libs/llvm12/tools/opt" }
-p { x: "sancov" peerdir: "contrib/libs/llvm12/tools/sancov" }
-p { x: "sanstats" peerdir: "contrib/libs/llvm12/tools/sanstats" }
-p { x: "split-file" peerdir: "contrib/libs/llvm12/tools/split-file" }
-p { x: "verify-uselistorder" peerdir: "contrib/libs/llvm12/tools/verify-uselistorder" }
-p { x: "yaml2obj" peerdir: "contrib/libs/llvm12/tools/yaml2obj" }
-p { i: "llvm/include" addincl: "contrib/libs/llvm12/include" addinclbuild: true }
+p { i: "llvm" x: "LLVMAArch64AsmParser" ix: true peerdir: "contrib/libs/llvm12/lib/Target/AArch64/AsmParser" }
+p { i: "llvm" x: "LLVMAArch64CodeGen" ix: true peerdir: "contrib/libs/llvm12/lib/Target/AArch64" }
+p { i: "llvm" x: "LLVMAArch64Desc" ix: true peerdir: "contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc" }
+p { i: "llvm" x: "LLVMAArch64Disassembler" ix: true peerdir: "contrib/libs/llvm12/lib/Target/AArch64/Disassembler" }
+p { i: "llvm" x: "LLVMAArch64Info" ix: true peerdir: "contrib/libs/llvm12/lib/Target/AArch64/TargetInfo" }
+p { i: "llvm" x: "LLVMAArch64Utils" ix: true peerdir: "contrib/libs/llvm12/lib/Target/AArch64/Utils" }
+p { i: "llvm" x: "LLVMARMAsmParser" ix: true peerdir: "contrib/libs/llvm12/lib/Target/ARM/AsmParser" }
+p { i: "llvm" x: "LLVMARMCodeGen" ix: true peerdir: "contrib/libs/llvm12/lib/Target/ARM" }
+p { i: "llvm" x: "LLVMARMDesc" ix: true peerdir: "contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc" }
+p { i: "llvm" x: "LLVMARMDisassembler" ix: true peerdir: "contrib/libs/llvm12/lib/Target/ARM/Disassembler" }
+p { i: "llvm" x: "LLVMARMInfo" ix: true peerdir: "contrib/libs/llvm12/lib/Target/ARM/TargetInfo" }
+p { i: "llvm" x: "LLVMARMUtils" ix: true peerdir: "contrib/libs/llvm12/lib/Target/ARM/Utils" }
+p { i: "llvm" x: "LLVMAggressiveInstCombine" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine" }
+p { i: "llvm" x: "LLVMAnalysis" ix: true peerdir: "contrib/libs/llvm12/lib/Analysis" }
+p { i: "llvm" x: "LLVMAsmParser" ix: true peerdir: "contrib/libs/llvm12/lib/AsmParser" }
+p { i: "llvm" x: "LLVMAsmPrinter" ix: true peerdir: "contrib/libs/llvm12/lib/CodeGen/AsmPrinter" }
+p { i: "llvm" x: "LLVMBPFAsmParser" ix: true peerdir: "contrib/libs/llvm12/lib/Target/BPF/AsmParser" }
+p { i: "llvm" x: "LLVMBPFCodeGen" ix: true peerdir: "contrib/libs/llvm12/lib/Target/BPF" }
+p { i: "llvm" x: "LLVMBPFDesc" ix: true peerdir: "contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc" }
+p { i: "llvm" x: "LLVMBPFDisassembler" ix: true peerdir: "contrib/libs/llvm12/lib/Target/BPF/Disassembler" }
+p { i: "llvm" x: "LLVMBPFInfo" ix: true peerdir: "contrib/libs/llvm12/lib/Target/BPF/TargetInfo" }
+p { i: "llvm" x: "LLVMBinaryFormat" ix: true peerdir: "contrib/libs/llvm12/lib/BinaryFormat" }
+p { i: "llvm" x: "LLVMBitReader" ix: true peerdir: "contrib/libs/llvm12/lib/Bitcode/Reader" }
+p { i: "llvm" x: "LLVMBitWriter" ix: true peerdir: "contrib/libs/llvm12/lib/Bitcode/Writer" }
+p { i: "llvm" x: "LLVMBitstreamReader" ix: true peerdir: "contrib/libs/llvm12/lib/Bitstream/Reader" }
+p { i: "llvm" x: "LLVMCFGuard" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/CFGuard" }
+p { i: "llvm" x: "LLVMCFIVerify" ix: true peerdir: "contrib/libs/llvm12/tools/llvm-cfi-verify/lib" }
+p { i: "llvm" x: "LLVMCodeGen" ix: true peerdir: "contrib/libs/llvm12/lib/CodeGen" }
+p { i: "llvm" x: "LLVMCore" ix: true peerdir: "contrib/libs/llvm12/lib/IR" }
+p { i: "llvm" x: "LLVMCoroutines" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/Coroutines" }
+p { i: "llvm" x: "LLVMCoverage" ix: true peerdir: "contrib/libs/llvm12/lib/ProfileData/Coverage" }
+p { i: "llvm" x: "LLVMDWARFLinker" ix: true peerdir: "contrib/libs/llvm12/lib/DWARFLinker" }
+p { i: "llvm" x: "LLVMDebugInfoCodeView" ix: true peerdir: "contrib/libs/llvm12/lib/DebugInfo/CodeView" }
+p { i: "llvm" x: "LLVMDebugInfoDWARF" ix: true peerdir: "contrib/libs/llvm12/lib/DebugInfo/DWARF" }
+p { i: "llvm" x: "LLVMDebugInfoGSYM" ix: true peerdir: "contrib/libs/llvm12/lib/DebugInfo/GSYM" }
+p { i: "llvm" x: "LLVMDebugInfoMSF" ix: true peerdir: "contrib/libs/llvm12/lib/DebugInfo/MSF" }
+p { i: "llvm" x: "LLVMDebugInfoPDB" ix: true peerdir: "contrib/libs/llvm12/lib/DebugInfo/PDB" }
+p { i: "llvm" x: "LLVMDemangle" ix: true peerdir: "contrib/libs/llvm12/lib/Demangle" }
+p { i: "llvm" x: "LLVMDlltoolDriver" ix: true peerdir: "contrib/libs/llvm12/lib/ToolDrivers/llvm-dlltool" }
+p { i: "llvm" x: "LLVMExecutionEngine" ix: true peerdir: "contrib/libs/llvm12/lib/ExecutionEngine" }
+p { i: "llvm" x: "LLVMExegesis" ix: true peerdir: "contrib/libs/llvm12/tools/llvm-exegesis/lib" }
+p { i: "llvm" x: "LLVMExegesisAArch64" ix: true peerdir: "contrib/libs/llvm12/tools/llvm-exegesis/lib/AArch64" }
+p { i: "llvm" x: "LLVMExegesisPowerPC" ix: true peerdir: "contrib/libs/llvm12/tools/llvm-exegesis/lib/PowerPC" }
+p { i: "llvm" x: "LLVMExegesisX86" ix: true peerdir: "contrib/libs/llvm12/tools/llvm-exegesis/lib/X86" }
+p { i: "llvm" x: "LLVMExtensions" ix: true peerdir: "contrib/libs/llvm12/lib/Extensions" }
+p { i: "llvm" x: "LLVMFileCheck" ix: true peerdir: "contrib/libs/llvm12/lib/FileCheck" }
+p { i: "llvm" x: "LLVMFrontendOpenACC" ix: true peerdir: "contrib/libs/llvm12/lib/Frontend/OpenACC" }
+p { i: "llvm" x: "LLVMFrontendOpenMP" ix: true peerdir: "contrib/libs/llvm12/lib/Frontend/OpenMP" }
+p { i: "llvm" x: "LLVMFuzzMutate" ix: true peerdir: "contrib/libs/llvm12/lib/FuzzMutate" }
+p { i: "llvm" x: "LLVMGlobalISel" ix: true peerdir: "contrib/libs/llvm12/lib/CodeGen/GlobalISel" }
+p { i: "llvm" x: "LLVMHelloNew" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/HelloNew" }
+p { i: "llvm" x: "LLVMIRReader" ix: true peerdir: "contrib/libs/llvm12/lib/IRReader" }
+p { i: "llvm" x: "LLVMInstCombine" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/InstCombine" }
+p { i: "llvm" x: "LLVMInstrumentation" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/Instrumentation" }
+p { i: "llvm" x: "LLVMInterfaceStub" ix: true peerdir: "contrib/libs/llvm12/lib/InterfaceStub" }
+p { i: "llvm" x: "LLVMInterpreter" ix: true peerdir: "contrib/libs/llvm12/lib/ExecutionEngine/Interpreter" }
+p { i: "llvm" x: "LLVMJITLink" ix: true peerdir: "contrib/libs/llvm12/lib/ExecutionEngine/JITLink" }
+p { i: "llvm" x: "LLVMLTO" ix: true peerdir: "contrib/libs/llvm12/lib/LTO" }
+p { i: "llvm" x: "LLVMLibDriver" ix: true peerdir: "contrib/libs/llvm12/lib/ToolDrivers/llvm-lib" }
+p { i: "llvm" x: "LLVMLineEditor" ix: true peerdir: "contrib/libs/llvm12/lib/LineEditor" }
+p { i: "llvm" x: "LLVMLinker" ix: true peerdir: "contrib/libs/llvm12/lib/Linker" }
+p { i: "llvm" x: "LLVMMC" ix: true peerdir: "contrib/libs/llvm12/lib/MC" }
+p { i: "llvm" x: "LLVMMCA" ix: true peerdir: "contrib/libs/llvm12/lib/MCA" }
+p { i: "llvm" x: "LLVMMCDisassembler" ix: true peerdir: "contrib/libs/llvm12/lib/MC/MCDisassembler" }
+p { i: "llvm" x: "LLVMMCJIT" ix: true peerdir: "contrib/libs/llvm12/lib/ExecutionEngine/MCJIT" }
+p { i: "llvm" x: "LLVMMCParser" ix: true peerdir: "contrib/libs/llvm12/lib/MC/MCParser" }
+p { i: "llvm" x: "LLVMMIRParser" ix: true peerdir: "contrib/libs/llvm12/lib/CodeGen/MIRParser" }
+p { i: "llvm" x: "LLVMNVPTXCodeGen" ix: true peerdir: "contrib/libs/llvm12/lib/Target/NVPTX" }
+p { i: "llvm" x: "LLVMNVPTXDesc" ix: true peerdir: "contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc" }
+p { i: "llvm" x: "LLVMNVPTXInfo" ix: true peerdir: "contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo" }
+p { i: "llvm" x: "LLVMObjCARCOpts" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/ObjCARC" }
+p { i: "llvm" x: "LLVMObject" ix: true peerdir: "contrib/libs/llvm12/lib/Object" }
+p { i: "llvm" x: "LLVMObjectYAML" ix: true peerdir: "contrib/libs/llvm12/lib/ObjectYAML" }
+p { i: "llvm" x: "LLVMOption" ix: true peerdir: "contrib/libs/llvm12/lib/Option" }
+p { i: "llvm" x: "LLVMOrcJIT" ix: true peerdir: "contrib/libs/llvm12/lib/ExecutionEngine/Orc" }
+p { i: "llvm" x: "LLVMOrcShared" ix: true peerdir: "contrib/libs/llvm12/lib/ExecutionEngine/Orc/Shared" }
+p { i: "llvm" x: "LLVMOrcTargetProcess" ix: true peerdir: "contrib/libs/llvm12/lib/ExecutionEngine/Orc/TargetProcess" }
+p { i: "llvm" x: "LLVMPasses" ix: true peerdir: "contrib/libs/llvm12/lib/Passes" }
+p { i: "llvm" x: "LLVMPerfJITEvents" ix: true peerdir: "contrib/libs/llvm12/lib/ExecutionEngine/PerfJITEvents" }
+p { i: "llvm" x: "LLVMPowerPCAsmParser" ix: true peerdir: "contrib/libs/llvm12/lib/Target/PowerPC/AsmParser" }
+p { i: "llvm" x: "LLVMPowerPCCodeGen" ix: true peerdir: "contrib/libs/llvm12/lib/Target/PowerPC" }
+p { i: "llvm" x: "LLVMPowerPCDesc" ix: true peerdir: "contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc" }
+p { i: "llvm" x: "LLVMPowerPCDisassembler" ix: true peerdir: "contrib/libs/llvm12/lib/Target/PowerPC/Disassembler" }
+p { i: "llvm" x: "LLVMPowerPCInfo" ix: true peerdir: "contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo" }
+p { i: "llvm" x: "LLVMProfileData" ix: true peerdir: "contrib/libs/llvm12/lib/ProfileData" }
+p { i: "llvm" x: "LLVMRemarks" ix: true peerdir: "contrib/libs/llvm12/lib/Remarks" }
+p { i: "llvm" x: "LLVMRuntimeDyld" ix: true peerdir: "contrib/libs/llvm12/lib/ExecutionEngine/RuntimeDyld" }
+p { i: "llvm" x: "LLVMScalarOpts" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/Scalar" }
+p { i: "llvm" x: "LLVMSelectionDAG" ix: true peerdir: "contrib/libs/llvm12/lib/CodeGen/SelectionDAG" }
+p { i: "llvm" x: "LLVMSupport" ix: true peerdir: "contrib/libs/llvm12/lib/Support" }
+p { i: "llvm" x: "LLVMSymbolize" ix: true peerdir: "contrib/libs/llvm12/lib/DebugInfo/Symbolize" }
+p { i: "llvm" x: "LLVMTableGen" ix: true peerdir: "contrib/libs/llvm12/lib/TableGen" }
+p { i: "llvm" x: "LLVMTableGenGlobalISel" ix: true peerdir: "contrib/libs/llvm12/utils/TableGen/GlobalISel" }
+p { i: "llvm" x: "LLVMTarget" ix: true peerdir: "contrib/libs/llvm12/lib/Target" }
+p { i: "llvm" x: "LLVMTextAPI" ix: true peerdir: "contrib/libs/llvm12/lib/TextAPI/MachO" }
+p { i: "llvm" x: "LLVMTransformUtils" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/Utils" }
+p { i: "llvm" x: "LLVMVectorize" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/Vectorize" }
+p { i: "llvm" x: "LLVMWindowsManifest" ix: true peerdir: "contrib/libs/llvm12/lib/WindowsManifest" }
+p { i: "llvm" x: "LLVMX86AsmParser" ix: true peerdir: "contrib/libs/llvm12/lib/Target/X86/AsmParser" }
+p { i: "llvm" x: "LLVMX86CodeGen" ix: true peerdir: "contrib/libs/llvm12/lib/Target/X86" }
+p { i: "llvm" x: "LLVMX86Desc" ix: true peerdir: "contrib/libs/llvm12/lib/Target/X86/MCTargetDesc" }
+p { i: "llvm" x: "LLVMX86Disassembler" ix: true peerdir: "contrib/libs/llvm12/lib/Target/X86/Disassembler" }
+p { i: "llvm" x: "LLVMX86Info" ix: true peerdir: "contrib/libs/llvm12/lib/Target/X86/TargetInfo" }
+p { i: "llvm" x: "LLVMXRay" ix: true peerdir: "contrib/libs/llvm12/lib/XRay" }
+p { i: "llvm" x: "LLVMgold" ix: true peerdir: "contrib/libs/llvm12/tools/gold" }
+p { i: "llvm" x: "LLVMipo" ix: true peerdir: "contrib/libs/llvm12/lib/Transforms/IPO" }
+p { i: "llvm" x: "LTO" ix: true peerdir: "contrib/libs/llvm12/tools/lto" }
+p { i: "llvm" x: "Polly" ix: true peerdir: "contrib/libs/llvm12/tools/polly/lib" }
+p { i: "llvm" x: "PollyISL" ix: true peerdir: "contrib/libs/llvm12/tools/polly/lib/External/isl" }
+p { i: "llvm" x: "PollyPPCG" ix: true peerdir: "contrib/libs/llvm12/tools/polly/lib/External/ppcg" }
+p { i: "llvm" x: "Remarks" ix: true peerdir: "contrib/libs/llvm12/tools/remarks-shlib" }
+p { x: "bugpoint" peerdir: "contrib/libs/llvm12/tools/bugpoint" }
+p { x: "dsymutil" peerdir: "contrib/libs/llvm12/tools/dsymutil" }
+p { x: "llc" peerdir: "contrib/libs/llvm12/tools/llc" }
+p { x: "lli" peerdir: "contrib/libs/llvm12/tools/lli" }
+p { x: "lli-child-target" peerdir: "contrib/libs/llvm12/tools/lli/ChildTarget" }
+p { x: "llvm-ar" peerdir: "contrib/libs/llvm12/tools/llvm-ar" }
+p { x: "llvm-as" peerdir: "contrib/libs/llvm12/tools/llvm-as" }
+p { x: "llvm-bcanalyzer" peerdir: "contrib/libs/llvm12/tools/llvm-bcanalyzer" }
+p { x: "llvm-cat" peerdir: "contrib/libs/llvm12/tools/llvm-cat" }
+p { x: "llvm-cfi-verify" peerdir: "contrib/libs/llvm12/tools/llvm-cfi-verify" }
+p { x: "llvm-config" peerdir: "contrib/libs/llvm12/tools/llvm-config" }
+p { x: "llvm-cov" peerdir: "contrib/libs/llvm12/tools/llvm-cov" }
+p { x: "llvm-cvtres" peerdir: "contrib/libs/llvm12/tools/llvm-cvtres" }
+p { x: "llvm-cxxdump" peerdir: "contrib/libs/llvm12/tools/llvm-cxxdump" }
+p { x: "llvm-cxxfilt" peerdir: "contrib/libs/llvm12/tools/llvm-cxxfilt" }
+p { x: "llvm-cxxmap" peerdir: "contrib/libs/llvm12/tools/llvm-cxxmap" }
+p { x: "llvm-diff" peerdir: "contrib/libs/llvm12/tools/llvm-diff" }
+p { x: "llvm-dis" peerdir: "contrib/libs/llvm12/tools/llvm-dis" }
+p { x: "llvm-dwarfdump" peerdir: "contrib/libs/llvm12/tools/llvm-dwarfdump" }
+p { x: "llvm-dwp" peerdir: "contrib/libs/llvm12/tools/llvm-dwp" }
+p { x: "llvm-elfabi" peerdir: "contrib/libs/llvm12/tools/llvm-elfabi" }
+p { x: "llvm-exegesis" peerdir: "contrib/libs/llvm12/tools/llvm-exegesis" }
+p { x: "llvm-extract" peerdir: "contrib/libs/llvm12/tools/llvm-extract" }
+p { x: "llvm-gsymutil" peerdir: "contrib/libs/llvm12/tools/llvm-gsymutil" }
+p { x: "llvm-ifs" peerdir: "contrib/libs/llvm12/tools/llvm-ifs" }
+p { x: "llvm-jitlink" peerdir: "contrib/libs/llvm12/tools/llvm-jitlink" }
+p { x: "llvm-jitlink-executor" peerdir: "contrib/libs/llvm12/tools/llvm-jitlink/llvm-jitlink-executor" }
+p { x: "llvm-libtool-darwin" peerdir: "contrib/libs/llvm12/tools/llvm-libtool-darwin" }
+p { x: "llvm-link" peerdir: "contrib/libs/llvm12/tools/llvm-link" }
+p { x: "llvm-lipo" peerdir: "contrib/libs/llvm12/tools/llvm-lipo" }
+p { x: "llvm-lto" peerdir: "contrib/libs/llvm12/tools/llvm-lto" }
+p { x: "llvm-lto2" peerdir: "contrib/libs/llvm12/tools/llvm-lto2" }
+p { x: "llvm-mc" peerdir: "contrib/libs/llvm12/tools/llvm-mc" }
+p { x: "llvm-mca" peerdir: "contrib/libs/llvm12/tools/llvm-mca" }
+p { x: "llvm-ml" peerdir: "contrib/libs/llvm12/tools/llvm-ml" }
+p { x: "llvm-modextract" peerdir: "contrib/libs/llvm12/tools/llvm-modextract" }
+p { x: "llvm-mt" peerdir: "contrib/libs/llvm12/tools/llvm-mt" }
+p { x: "llvm-nm" peerdir: "contrib/libs/llvm12/tools/llvm-nm" }
+p { x: "llvm-objcopy" peerdir: "contrib/libs/llvm12/tools/llvm-objcopy" }
+p { x: "llvm-objdump" peerdir: "contrib/libs/llvm12/tools/llvm-objdump" }
+p { x: "llvm-opt-report" peerdir: "contrib/libs/llvm12/tools/llvm-opt-report" }
+p { x: "llvm-pdbutil" peerdir: "contrib/libs/llvm12/tools/llvm-pdbutil" }
+p { x: "llvm-profdata" peerdir: "contrib/libs/llvm12/tools/llvm-profdata" }
+p { x: "llvm-profgen" peerdir: "contrib/libs/llvm12/tools/llvm-profgen" }
+p { x: "llvm-rc" peerdir: "contrib/libs/llvm12/tools/llvm-rc" }
+p { x: "llvm-readobj" peerdir: "contrib/libs/llvm12/tools/llvm-readobj" }
+p { x: "llvm-reduce" peerdir: "contrib/libs/llvm12/tools/llvm-reduce" }
+p { x: "llvm-rtdyld" peerdir: "contrib/libs/llvm12/tools/llvm-rtdyld" }
+p { x: "llvm-size" peerdir: "contrib/libs/llvm12/tools/llvm-size" }
+p { x: "llvm-split" peerdir: "contrib/libs/llvm12/tools/llvm-split" }
+p { x: "llvm-stress" peerdir: "contrib/libs/llvm12/tools/llvm-stress" }
+p { x: "llvm-strings" peerdir: "contrib/libs/llvm12/tools/llvm-strings" }
+p { x: "llvm-symbolizer" peerdir: "contrib/libs/llvm12/tools/llvm-symbolizer" }
+p { x: "llvm-tblgen" peerdir: "contrib/libs/llvm12/utils/TableGen" }
+p { x: "llvm-undname" peerdir: "contrib/libs/llvm12/tools/llvm-undname" }
+p { x: "llvm-xray" peerdir: "contrib/libs/llvm12/tools/llvm-xray" }
+p { x: "obj2yaml" peerdir: "contrib/libs/llvm12/tools/obj2yaml" }
+p { x: "opt" peerdir: "contrib/libs/llvm12/tools/opt" }
+p { x: "sancov" peerdir: "contrib/libs/llvm12/tools/sancov" }
+p { x: "sanstats" peerdir: "contrib/libs/llvm12/tools/sanstats" }
+p { x: "split-file" peerdir: "contrib/libs/llvm12/tools/split-file" }
+p { x: "verify-uselistorder" peerdir: "contrib/libs/llvm12/tools/verify-uselistorder" }
+p { x: "yaml2obj" peerdir: "contrib/libs/llvm12/tools/yaml2obj" }
+p { i: "llvm/include" addincl: "contrib/libs/llvm12/include" addinclbuild: true }
diff --git a/contrib/libs/llvm12/tools/dsymutil/BinaryHolder.cpp b/contrib/libs/llvm12/tools/dsymutil/BinaryHolder.cpp
index 3b2e1d462c..f83521346c 100644
--- a/contrib/libs/llvm12/tools/dsymutil/BinaryHolder.cpp
+++ b/contrib/libs/llvm12/tools/dsymutil/BinaryHolder.cpp
@@ -87,8 +87,8 @@ Error BinaryHolder::ArchiveEntry::load(IntrusiveRefCntPtr<vfs::FileSystem> VFS,
}
Error BinaryHolder::ObjectEntry::load(IntrusiveRefCntPtr<vfs::FileSystem> VFS,
- StringRef Filename, TimestampTy Timestamp,
- bool Verbose) {
+ StringRef Filename, TimestampTy Timestamp,
+ bool Verbose) {
// Try to load regular binary and force it to be memory mapped.
auto ErrOrBuff = (Filename == "-")
? MemoryBuffer::getSTDIN()
@@ -96,18 +96,18 @@ Error BinaryHolder::ObjectEntry::load(IntrusiveRefCntPtr<vfs::FileSystem> VFS,
if (auto Err = ErrOrBuff.getError())
return errorCodeToError(Err);
- if (Filename != "-" && Timestamp != sys::TimePoint<>()) {
- llvm::ErrorOr<vfs::Status> Stat = VFS->status(Filename);
- if (!Stat)
- return errorCodeToError(Stat.getError());
- if (Timestamp != std::chrono::time_point_cast<std::chrono::seconds>(
- Stat->getLastModificationTime()))
- WithColor::warning() << Filename
- << ": timestamp mismatch between object file ("
- << Stat->getLastModificationTime()
- << ") and debug map (" << Timestamp << ")\n";
- }
-
+ if (Filename != "-" && Timestamp != sys::TimePoint<>()) {
+ llvm::ErrorOr<vfs::Status> Stat = VFS->status(Filename);
+ if (!Stat)
+ return errorCodeToError(Stat.getError());
+ if (Timestamp != std::chrono::time_point_cast<std::chrono::seconds>(
+ Stat->getLastModificationTime()))
+ WithColor::warning() << Filename
+ << ": timestamp mismatch between object file ("
+ << Stat->getLastModificationTime()
+ << ") and debug map (" << Timestamp << ")\n";
+ }
+
MemBuffer = std::move(*ErrOrBuff);
if (Verbose)
@@ -193,14 +193,14 @@ BinaryHolder::ArchiveEntry::getObjectEntry(StringRef Filename,
return ModTimeOrErr.takeError();
if (Timestamp != sys::TimePoint<>() &&
- Timestamp != std::chrono::time_point_cast<std::chrono::seconds>(
- ModTimeOrErr.get())) {
+ Timestamp != std::chrono::time_point_cast<std::chrono::seconds>(
+ ModTimeOrErr.get())) {
if (Verbose)
- WithColor::warning()
- << *NameOrErr
- << ": timestamp mismatch between archive member ("
- << ModTimeOrErr.get() << ") and debug map (" << Timestamp
- << ")\n";
+ WithColor::warning()
+ << *NameOrErr
+ << ": timestamp mismatch between archive member ("
+ << ModTimeOrErr.get() << ") and debug map (" << Timestamp
+ << ")\n";
continue;
}
@@ -264,7 +264,7 @@ BinaryHolder::getObjectEntry(StringRef Filename, TimestampTy Timestamp) {
std::lock_guard<std::mutex> Lock(ObjectCacheMutex);
if (!ObjectCache.count(Filename)) {
ObjectEntry &OE = ObjectCache[Filename];
- auto Err = OE.load(VFS, Filename, Timestamp, Verbose);
+ auto Err = OE.load(VFS, Filename, Timestamp, Verbose);
if (Err) {
ObjectCache.erase(Filename);
return std::move(Err);
diff --git a/contrib/libs/llvm12/tools/dsymutil/BinaryHolder.h b/contrib/libs/llvm12/tools/dsymutil/BinaryHolder.h
index dff33a752f..5e81fe4b93 100644
--- a/contrib/libs/llvm12/tools/dsymutil/BinaryHolder.h
+++ b/contrib/libs/llvm12/tools/dsymutil/BinaryHolder.h
@@ -58,7 +58,7 @@ public:
public:
/// Load the given object binary in memory.
Error load(IntrusiveRefCntPtr<vfs::FileSystem> VFS, StringRef Filename,
- TimestampTy Timestamp, bool Verbose = false);
+ TimestampTy Timestamp, bool Verbose = false);
/// Access all owned ObjectFiles.
std::vector<const object::ObjectFile *> getObjects() const;
diff --git a/contrib/libs/llvm12/tools/dsymutil/DebugMap.cpp b/contrib/libs/llvm12/tools/dsymutil/DebugMap.cpp
index a1e4536dfd..605c1317b9 100644
--- a/contrib/libs/llvm12/tools/dsymutil/DebugMap.cpp
+++ b/contrib/libs/llvm12/tools/dsymutil/DebugMap.cpp
@@ -60,7 +60,7 @@ void DebugMapObject::print(raw_ostream &OS) const {
using Entry = std::pair<StringRef, SymbolMapping>;
std::vector<Entry> Entries;
Entries.reserve(Symbols.getNumItems());
- for (const auto &Sym : Symbols)
+ for (const auto &Sym : Symbols)
Entries.push_back(std::make_pair(Sym.getKey(), Sym.getValue()));
llvm::sort(Entries, [](const Entry &LHS, const Entry &RHS) {
return LHS.first < RHS.first;
diff --git a/contrib/libs/llvm12/tools/dsymutil/DwarfLinkerForBinary.cpp b/contrib/libs/llvm12/tools/dsymutil/DwarfLinkerForBinary.cpp
index 28aa8496ff..29408e7c49 100644
--- a/contrib/libs/llvm12/tools/dsymutil/DwarfLinkerForBinary.cpp
+++ b/contrib/libs/llvm12/tools/dsymutil/DwarfLinkerForBinary.cpp
@@ -262,7 +262,7 @@ static Error emitRemarks(const LinkOptions &Options, StringRef BinaryPath,
return Error::success();
}
-ErrorOr<DWARFFile &>
+ErrorOr<DWARFFile &>
DwarfLinkerForBinary::loadObject(const DebugMapObject &Obj,
const DebugMap &DebugMap,
remarks::RemarkLinker &RL) {
@@ -274,7 +274,7 @@ DwarfLinkerForBinary::loadObject(const DebugMapObject &Obj,
AddressMapForLinking.push_back(
std::make_unique<AddressManager>(*this, *ErrorOrObj, Obj));
- ObjectsForLinking.push_back(std::make_unique<DWARFFile>(
+ ObjectsForLinking.push_back(std::make_unique<DWARFFile>(
Obj.getObjectFilename(), ContextForLinking.back().get(),
AddressMapForLinking.back().get(),
Obj.empty() ? Obj.getWarnings() : EmptyWarnings));
@@ -334,7 +334,7 @@ bool DwarfLinkerForBinary::link(const DebugMap &Map) {
});
GeneralLinker.setObjFileLoader(
[&DebugMap, &RL, this](StringRef ContainerName,
- StringRef Path) -> ErrorOr<DWARFFile &> {
+ StringRef Path) -> ErrorOr<DWARFFile &> {
auto &Obj = DebugMap.addDebugMapObject(
Path, sys::TimePoint<std::chrono::seconds>(), MachO::N_OSO);
@@ -412,10 +412,10 @@ bool DwarfLinkerForBinary::link(const DebugMap &Map) {
Stat.getLastModificationTime());
if (ModificationTime != Obj->getTimestamp()) {
// Not using the helper here as we can easily stream TimePoint<>.
- WithColor::warning()
- << File << ": timestamp mismatch between swift interface file ("
- << sys::TimePoint<>(Obj->getTimestamp()) << ") and debug map ("
- << sys::TimePoint<>(Obj->getTimestamp()) << ")\n";
+ WithColor::warning()
+ << File << ": timestamp mismatch between swift interface file ("
+ << sys::TimePoint<>(Obj->getTimestamp()) << ") and debug map ("
+ << sys::TimePoint<>(Obj->getTimestamp()) << ")\n";
continue;
}
}
@@ -430,7 +430,7 @@ bool DwarfLinkerForBinary::link(const DebugMap &Map) {
if (auto ErrorOrObj = loadObject(*Obj, Map, RL))
GeneralLinker.addObjectFile(*ErrorOrObj);
else {
- ObjectsForLinking.push_back(std::make_unique<DWARFFile>(
+ ObjectsForLinking.push_back(std::make_unique<DWARFFile>(
Obj->getObjectFilename(), nullptr, nullptr,
Obj->empty() ? Obj->getWarnings() : EmptyWarnings));
GeneralLinker.addObjectFile(*ObjectsForLinking.back());
@@ -489,7 +489,7 @@ static bool isMachOPairedReloc(uint64_t RelocType, uint64_t Arch) {
/// ValidRelocs array.
void DwarfLinkerForBinary::AddressManager::findValidRelocsMachO(
const object::SectionRef &Section, const object::MachOObjectFile &Obj,
- const DebugMapObject &DMO, std::vector<ValidReloc> &ValidRelocs) {
+ const DebugMapObject &DMO, std::vector<ValidReloc> &ValidRelocs) {
Expected<StringRef> ContentsOrErr = Section.getContents();
if (!ContentsOrErr) {
consumeError(ContentsOrErr.takeError());
@@ -511,8 +511,8 @@ void DwarfLinkerForBinary::AddressManager::findValidRelocsMachO(
if (isMachOPairedReloc(Obj.getAnyRelocationType(MachOReloc),
Obj.getArch())) {
SkipNext = true;
- Linker.reportWarning("unsupported relocation in " + *Section.getName() +
- " section.",
+ Linker.reportWarning("unsupported relocation in " + *Section.getName() +
+ " section.",
DMO.getObjectFilename());
continue;
}
@@ -520,8 +520,8 @@ void DwarfLinkerForBinary::AddressManager::findValidRelocsMachO(
unsigned RelocSize = 1 << Obj.getAnyRelocationLength(MachOReloc);
uint64_t Offset64 = Reloc.getOffset();
if ((RelocSize != 4 && RelocSize != 8)) {
- Linker.reportWarning("unsupported relocation in " + *Section.getName() +
- " section.",
+ Linker.reportWarning("unsupported relocation in " + *Section.getName() +
+ " section.",
DMO.getObjectFilename());
continue;
}
@@ -566,33 +566,33 @@ void DwarfLinkerForBinary::AddressManager::findValidRelocsMachO(
/// appropriate handler depending on the object file format.
bool DwarfLinkerForBinary::AddressManager::findValidRelocs(
const object::SectionRef &Section, const object::ObjectFile &Obj,
- const DebugMapObject &DMO, std::vector<ValidReloc> &Relocs) {
+ const DebugMapObject &DMO, std::vector<ValidReloc> &Relocs) {
// Dispatch to the right handler depending on the file type.
if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(&Obj))
- findValidRelocsMachO(Section, *MachOObj, DMO, Relocs);
+ findValidRelocsMachO(Section, *MachOObj, DMO, Relocs);
else
Linker.reportWarning(Twine("unsupported object file type: ") +
Obj.getFileName(),
DMO.getObjectFilename());
- if (Relocs.empty())
+ if (Relocs.empty())
return false;
// Sort the relocations by offset. We will walk the DIEs linearly in
// the file, this allows us to just keep an index in the relocation
// array that we advance during our walk, rather than resorting to
// some associative container. See DwarfLinkerForBinary::NextValidReloc.
- llvm::sort(Relocs);
+ llvm::sort(Relocs);
return true;
}
-/// Look for relocations in the debug_info and debug_addr section that match
-/// entries in the debug map. These relocations will drive the Dwarf link by
-/// indicating which DIEs refer to symbols present in the linked binary.
+/// Look for relocations in the debug_info and debug_addr section that match
+/// entries in the debug map. These relocations will drive the Dwarf link by
+/// indicating which DIEs refer to symbols present in the linked binary.
/// \returns whether there are any valid relocations in the debug info.
-bool DwarfLinkerForBinary::AddressManager::findValidRelocsInDebugSections(
+bool DwarfLinkerForBinary::AddressManager::findValidRelocsInDebugSections(
const object::ObjectFile &Obj, const DebugMapObject &DMO) {
// Find the debug_info section.
- bool FoundValidRelocs = false;
+ bool FoundValidRelocs = false;
for (const object::SectionRef &Section : Obj.sections()) {
StringRef SectionName;
if (Expected<StringRef> NameOrErr = Section.getName())
@@ -601,44 +601,44 @@ bool DwarfLinkerForBinary::AddressManager::findValidRelocsInDebugSections(
consumeError(NameOrErr.takeError());
SectionName = SectionName.substr(SectionName.find_first_not_of("._"));
- if (SectionName == "debug_info")
- FoundValidRelocs |=
- findValidRelocs(Section, Obj, DMO, ValidDebugInfoRelocs);
- if (SectionName == "debug_addr")
- FoundValidRelocs |=
- findValidRelocs(Section, Obj, DMO, ValidDebugAddrRelocs);
+ if (SectionName == "debug_info")
+ FoundValidRelocs |=
+ findValidRelocs(Section, Obj, DMO, ValidDebugInfoRelocs);
+ if (SectionName == "debug_addr")
+ FoundValidRelocs |=
+ findValidRelocs(Section, Obj, DMO, ValidDebugAddrRelocs);
}
- return FoundValidRelocs;
+ return FoundValidRelocs;
}
-bool DwarfLinkerForBinary::AddressManager::hasValidDebugAddrRelocationAt(
- uint64_t Offset) {
- auto It = std::lower_bound(ValidDebugAddrRelocs.begin(),
- ValidDebugAddrRelocs.end(), Offset);
- return It != ValidDebugAddrRelocs.end();
-}
-
-bool DwarfLinkerForBinary::AddressManager::hasValidDebugInfoRelocationAt(
+bool DwarfLinkerForBinary::AddressManager::hasValidDebugAddrRelocationAt(
+ uint64_t Offset) {
+ auto It = std::lower_bound(ValidDebugAddrRelocs.begin(),
+ ValidDebugAddrRelocs.end(), Offset);
+ return It != ValidDebugAddrRelocs.end();
+}
+
+bool DwarfLinkerForBinary::AddressManager::hasValidDebugInfoRelocationAt(
uint64_t StartOffset, uint64_t EndOffset, CompileUnit::DIEInfo &Info) {
assert(NextValidReloc == 0 ||
- StartOffset > ValidDebugInfoRelocs[NextValidReloc - 1].Offset);
- if (NextValidReloc >= ValidDebugInfoRelocs.size())
+ StartOffset > ValidDebugInfoRelocs[NextValidReloc - 1].Offset);
+ if (NextValidReloc >= ValidDebugInfoRelocs.size())
return false;
- uint64_t RelocOffset = ValidDebugInfoRelocs[NextValidReloc].Offset;
+ uint64_t RelocOffset = ValidDebugInfoRelocs[NextValidReloc].Offset;
// We might need to skip some relocs that we didn't consider. For
// example the high_pc of a discarded DIE might contain a reloc that
// is in the list because it actually corresponds to the start of a
// function that is in the debug map.
- while (RelocOffset < StartOffset &&
- NextValidReloc < ValidDebugInfoRelocs.size() - 1)
- RelocOffset = ValidDebugInfoRelocs[++NextValidReloc].Offset;
+ while (RelocOffset < StartOffset &&
+ NextValidReloc < ValidDebugInfoRelocs.size() - 1)
+ RelocOffset = ValidDebugInfoRelocs[++NextValidReloc].Offset;
if (RelocOffset < StartOffset || RelocOffset >= EndOffset)
return false;
- const auto &ValidReloc = ValidDebugInfoRelocs[NextValidReloc++];
+ const auto &ValidReloc = ValidDebugInfoRelocs[NextValidReloc++];
const auto &Mapping = ValidReloc.Mapping->getValue();
const uint64_t BinaryAddress = Mapping.BinaryAddress;
const uint64_t ObjectAddress = Mapping.ObjectAddress
@@ -657,71 +657,71 @@ bool DwarfLinkerForBinary::AddressManager::hasValidDebugInfoRelocationAt(
return true;
}
-/// Get the starting and ending (exclusive) offset for the
-/// attribute with index \p Idx descibed by \p Abbrev. \p Offset is
-/// supposed to point to the position of the first attribute described
-/// by \p Abbrev.
-/// \return [StartOffset, EndOffset) as a pair.
-static std::pair<uint64_t, uint64_t>
-getAttributeOffsets(const DWARFAbbreviationDeclaration *Abbrev, unsigned Idx,
- uint64_t Offset, const DWARFUnit &Unit) {
- DataExtractor Data = Unit.getDebugInfoExtractor();
-
- for (unsigned I = 0; I < Idx; ++I)
- DWARFFormValue::skipValue(Abbrev->getFormByIndex(I), Data, &Offset,
- Unit.getFormParams());
-
- uint64_t End = Offset;
- DWARFFormValue::skipValue(Abbrev->getFormByIndex(Idx), Data, &End,
- Unit.getFormParams());
-
- return std::make_pair(Offset, End);
-}
-
-bool DwarfLinkerForBinary::AddressManager::hasLiveMemoryLocation(
- const DWARFDie &DIE, CompileUnit::DIEInfo &MyInfo) {
- const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
-
- Optional<uint32_t> LocationIdx =
- Abbrev->findAttributeIndex(dwarf::DW_AT_location);
- if (!LocationIdx)
- return false;
-
- uint64_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode());
- uint64_t LocationOffset, LocationEndOffset;
- std::tie(LocationOffset, LocationEndOffset) =
- getAttributeOffsets(Abbrev, *LocationIdx, Offset, *DIE.getDwarfUnit());
-
- // FIXME: Support relocations debug_addr.
- return hasValidDebugInfoRelocationAt(LocationOffset, LocationEndOffset,
- MyInfo);
-}
-
-bool DwarfLinkerForBinary::AddressManager::hasLiveAddressRange(
- const DWARFDie &DIE, CompileUnit::DIEInfo &MyInfo) {
- const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
-
- Optional<uint32_t> LowPcIdx = Abbrev->findAttributeIndex(dwarf::DW_AT_low_pc);
- if (!LowPcIdx)
- return false;
-
- dwarf::Form Form = Abbrev->getFormByIndex(*LowPcIdx);
-
- if (Form == dwarf::DW_FORM_addr) {
- uint64_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode());
- uint64_t LowPcOffset, LowPcEndOffset;
- std::tie(LowPcOffset, LowPcEndOffset) =
- getAttributeOffsets(Abbrev, *LowPcIdx, Offset, *DIE.getDwarfUnit());
- return hasValidDebugInfoRelocationAt(LowPcOffset, LowPcEndOffset, MyInfo);
- }
-
- if (Form == dwarf::DW_FORM_addrx) {
- Optional<DWARFFormValue> AddrValue = DIE.find(dwarf::DW_AT_low_pc);
- return hasValidDebugAddrRelocationAt(*AddrValue->getAsAddress());
- }
-
- return false;
-}
+/// Get the starting and ending (exclusive) offset for the
+/// attribute with index \p Idx descibed by \p Abbrev. \p Offset is
+/// supposed to point to the position of the first attribute described
+/// by \p Abbrev.
+/// \return [StartOffset, EndOffset) as a pair.
+static std::pair<uint64_t, uint64_t>
+getAttributeOffsets(const DWARFAbbreviationDeclaration *Abbrev, unsigned Idx,
+ uint64_t Offset, const DWARFUnit &Unit) {
+ DataExtractor Data = Unit.getDebugInfoExtractor();
+
+ for (unsigned I = 0; I < Idx; ++I)
+ DWARFFormValue::skipValue(Abbrev->getFormByIndex(I), Data, &Offset,
+ Unit.getFormParams());
+
+ uint64_t End = Offset;
+ DWARFFormValue::skipValue(Abbrev->getFormByIndex(Idx), Data, &End,
+ Unit.getFormParams());
+
+ return std::make_pair(Offset, End);
+}
+
+bool DwarfLinkerForBinary::AddressManager::hasLiveMemoryLocation(
+ const DWARFDie &DIE, CompileUnit::DIEInfo &MyInfo) {
+ const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
+
+ Optional<uint32_t> LocationIdx =
+ Abbrev->findAttributeIndex(dwarf::DW_AT_location);
+ if (!LocationIdx)
+ return false;
+
+ uint64_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode());
+ uint64_t LocationOffset, LocationEndOffset;
+ std::tie(LocationOffset, LocationEndOffset) =
+ getAttributeOffsets(Abbrev, *LocationIdx, Offset, *DIE.getDwarfUnit());
+
+ // FIXME: Support relocations debug_addr.
+ return hasValidDebugInfoRelocationAt(LocationOffset, LocationEndOffset,
+ MyInfo);
+}
+
+bool DwarfLinkerForBinary::AddressManager::hasLiveAddressRange(
+ const DWARFDie &DIE, CompileUnit::DIEInfo &MyInfo) {
+ const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
+
+ Optional<uint32_t> LowPcIdx = Abbrev->findAttributeIndex(dwarf::DW_AT_low_pc);
+ if (!LowPcIdx)
+ return false;
+
+ dwarf::Form Form = Abbrev->getFormByIndex(*LowPcIdx);
+
+ if (Form == dwarf::DW_FORM_addr) {
+ uint64_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode());
+ uint64_t LowPcOffset, LowPcEndOffset;
+ std::tie(LowPcOffset, LowPcEndOffset) =
+ getAttributeOffsets(Abbrev, *LowPcIdx, Offset, *DIE.getDwarfUnit());
+ return hasValidDebugInfoRelocationAt(LowPcOffset, LowPcEndOffset, MyInfo);
+ }
+
+ if (Form == dwarf::DW_FORM_addrx) {
+ Optional<DWARFFormValue> AddrValue = DIE.find(dwarf::DW_AT_low_pc);
+ return hasValidDebugAddrRelocationAt(*AddrValue->getAsAddress());
+ }
+
+ return false;
+}
/// Apply the valid relocations found by findValidRelocs() to
/// the buffer \p Data, taking into account that Data is at \p BaseOffset
/// in the debug_info section.
@@ -734,22 +734,22 @@ bool DwarfLinkerForBinary::AddressManager::applyValidRelocs(
MutableArrayRef<char> Data, uint64_t BaseOffset, bool IsLittleEndian) {
assert(areRelocationsResolved());
assert((NextValidReloc == 0 ||
- BaseOffset > ValidDebugInfoRelocs[NextValidReloc - 1].Offset) &&
+ BaseOffset > ValidDebugInfoRelocs[NextValidReloc - 1].Offset) &&
"BaseOffset should only be increasing.");
- if (NextValidReloc >= ValidDebugInfoRelocs.size())
+ if (NextValidReloc >= ValidDebugInfoRelocs.size())
return false;
// Skip relocs that haven't been applied.
- while (NextValidReloc < ValidDebugInfoRelocs.size() &&
- ValidDebugInfoRelocs[NextValidReloc].Offset < BaseOffset)
+ while (NextValidReloc < ValidDebugInfoRelocs.size() &&
+ ValidDebugInfoRelocs[NextValidReloc].Offset < BaseOffset)
++NextValidReloc;
bool Applied = false;
uint64_t EndOffset = BaseOffset + Data.size();
- while (NextValidReloc < ValidDebugInfoRelocs.size() &&
- ValidDebugInfoRelocs[NextValidReloc].Offset >= BaseOffset &&
- ValidDebugInfoRelocs[NextValidReloc].Offset < EndOffset) {
- const auto &ValidReloc = ValidDebugInfoRelocs[NextValidReloc++];
+ while (NextValidReloc < ValidDebugInfoRelocs.size() &&
+ ValidDebugInfoRelocs[NextValidReloc].Offset >= BaseOffset &&
+ ValidDebugInfoRelocs[NextValidReloc].Offset < EndOffset) {
+ const auto &ValidReloc = ValidDebugInfoRelocs[NextValidReloc++];
assert(ValidReloc.Offset - BaseOffset < Data.size());
assert(ValidReloc.Offset - BaseOffset + ValidReloc.Size <= Data.size());
char Buf[8];
@@ -767,17 +767,17 @@ bool DwarfLinkerForBinary::AddressManager::applyValidRelocs(
return Applied;
}
-llvm::Expected<uint64_t>
-DwarfLinkerForBinary::AddressManager::relocateIndexedAddr(uint64_t Offset) {
- auto It = std::lower_bound(ValidDebugAddrRelocs.begin(),
- ValidDebugAddrRelocs.end(), Offset);
- if (It == ValidDebugAddrRelocs.end())
- return createStringError(
- std::make_error_code(std::errc::invalid_argument),
- "no relocation for offset %llu in debug_addr section", Offset);
- return It->Mapping->getValue().BinaryAddress + It->Addend;
-}
-
+llvm::Expected<uint64_t>
+DwarfLinkerForBinary::AddressManager::relocateIndexedAddr(uint64_t Offset) {
+ auto It = std::lower_bound(ValidDebugAddrRelocs.begin(),
+ ValidDebugAddrRelocs.end(), Offset);
+ if (It == ValidDebugAddrRelocs.end())
+ return createStringError(
+ std::make_error_code(std::errc::invalid_argument),
+ "no relocation for offset %llu in debug_addr section", Offset);
+ return It->Mapping->getValue().BinaryAddress + It->Addend;
+}
+
bool linkDwarf(raw_fd_ostream &OutFile, BinaryHolder &BinHolder,
const DebugMap &DM, LinkOptions Options) {
DwarfLinkerForBinary Linker(OutFile, BinHolder, std::move(Options));
diff --git a/contrib/libs/llvm12/tools/dsymutil/DwarfLinkerForBinary.h b/contrib/libs/llvm12/tools/dsymutil/DwarfLinkerForBinary.h
index b17aac137f..c6c07d689f 100644
--- a/contrib/libs/llvm12/tools/dsymutil/DwarfLinkerForBinary.h
+++ b/contrib/libs/llvm12/tools/dsymutil/DwarfLinkerForBinary.h
@@ -70,17 +70,17 @@ private:
bool operator<(const ValidReloc &RHS) const {
return Offset < RHS.Offset;
}
- bool operator<(uint64_t RHS) const { return Offset < RHS; }
+ bool operator<(uint64_t RHS) const { return Offset < RHS; }
};
const DwarfLinkerForBinary &Linker;
/// The valid relocations for the current DebugMapObject.
/// This vector is sorted by relocation offset.
- /// {
- std::vector<ValidReloc> ValidDebugInfoRelocs;
- std::vector<ValidReloc> ValidDebugAddrRelocs;
- /// }
+ /// {
+ std::vector<ValidReloc> ValidDebugInfoRelocs;
+ std::vector<ValidReloc> ValidDebugAddrRelocs;
+ /// }
/// Index into ValidRelocs of the next relocation to consider. As we walk
/// the DIEs in acsending file offset and as ValidRelocs is sorted by file
@@ -94,7 +94,7 @@ private:
AddressManager(DwarfLinkerForBinary &Linker, const object::ObjectFile &Obj,
const DebugMapObject &DMO)
: Linker(Linker) {
- findValidRelocsInDebugSections(Obj, DMO);
+ findValidRelocsInDebugSections(Obj, DMO);
// Iterate over the debug map entries and put all the ones that are
// functions (because they have a size) into the Ranges map. This map is
@@ -128,56 +128,56 @@ private:
bool hasValidRelocs(bool ResetRelocsPtr = true) override {
if (ResetRelocsPtr)
NextValidReloc = 0;
- return !ValidDebugInfoRelocs.empty() || !ValidDebugAddrRelocs.empty();
+ return !ValidDebugInfoRelocs.empty() || !ValidDebugAddrRelocs.empty();
}
/// \defgroup FindValidRelocations Translate debug map into a list
/// of relevant relocations
///
/// @{
- bool findValidRelocsInDebugSections(const object::ObjectFile &Obj,
- const DebugMapObject &DMO);
+ bool findValidRelocsInDebugSections(const object::ObjectFile &Obj,
+ const DebugMapObject &DMO);
bool findValidRelocs(const object::SectionRef &Section,
const object::ObjectFile &Obj,
- const DebugMapObject &DMO,
- std::vector<ValidReloc> &ValidRelocs);
+ const DebugMapObject &DMO,
+ std::vector<ValidReloc> &ValidRelocs);
void findValidRelocsMachO(const object::SectionRef &Section,
const object::MachOObjectFile &Obj,
- const DebugMapObject &DMO,
- std::vector<ValidReloc> &ValidRelocs);
+ const DebugMapObject &DMO,
+ std::vector<ValidReloc> &ValidRelocs);
/// @}
- /// Checks that there is a relocation in the debug_addr section against a
- /// debug map entry between \p StartOffset and \p NextOffset.
- ///
- /// This function must be called with offsets in strictly ascending order
- /// because it never looks back at relocations it already 'went past'.
- /// \returns true and sets Info.InDebugMap if it is the case.
- bool hasValidDebugInfoRelocationAt(uint64_t StartOffset, uint64_t EndOffset,
- CompileUnit::DIEInfo &Info);
-
- /// Checks that there is a relocation in the debug_addr section against a
- /// debug map entry at the given offset.
- bool hasValidDebugAddrRelocationAt(uint64_t Offset);
-
- bool hasLiveMemoryLocation(const DWARFDie &DIE,
- CompileUnit::DIEInfo &Info) override;
- bool hasLiveAddressRange(const DWARFDie &DIE,
- CompileUnit::DIEInfo &Info) override;
-
+ /// Checks that there is a relocation in the debug_addr section against a
+ /// debug map entry between \p StartOffset and \p NextOffset.
+ ///
+ /// This function must be called with offsets in strictly ascending order
+ /// because it never looks back at relocations it already 'went past'.
+ /// \returns true and sets Info.InDebugMap if it is the case.
+ bool hasValidDebugInfoRelocationAt(uint64_t StartOffset, uint64_t EndOffset,
+ CompileUnit::DIEInfo &Info);
+
+ /// Checks that there is a relocation in the debug_addr section against a
+ /// debug map entry at the given offset.
+ bool hasValidDebugAddrRelocationAt(uint64_t Offset);
+
+ bool hasLiveMemoryLocation(const DWARFDie &DIE,
+ CompileUnit::DIEInfo &Info) override;
+ bool hasLiveAddressRange(const DWARFDie &DIE,
+ CompileUnit::DIEInfo &Info) override;
+
bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
bool IsLittleEndian) override;
- llvm::Expected<uint64_t> relocateIndexedAddr(uint64_t Offset) override;
-
+ llvm::Expected<uint64_t> relocateIndexedAddr(uint64_t Offset) override;
+
RangesTy &getValidAddressRanges() override { return AddressRanges; }
void clear() override {
AddressRanges.clear();
- ValidDebugInfoRelocs.clear();
- ValidDebugAddrRelocs.clear();
+ ValidDebugInfoRelocs.clear();
+ ValidDebugAddrRelocs.clear();
NextValidReloc = 0;
}
};
@@ -191,7 +191,7 @@ private:
/// Attempt to load a debug object from disk.
ErrorOr<const object::ObjectFile &> loadObject(const DebugMapObject &Obj,
const Triple &triple);
- ErrorOr<DWARFFile &> loadObject(const DebugMapObject &Obj,
+ ErrorOr<DWARFFile &> loadObject(const DebugMapObject &Obj,
const DebugMap &DebugMap,
remarks::RemarkLinker &RL);
@@ -199,7 +199,7 @@ private:
BinaryHolder &BinHolder;
LinkOptions Options;
std::unique_ptr<DwarfStreamer> Streamer;
- std::vector<std::unique_ptr<DWARFFile>> ObjectsForLinking;
+ std::vector<std::unique_ptr<DWARFFile>> ObjectsForLinking;
std::vector<std::unique_ptr<DWARFContext>> ContextForLinking;
std::vector<std::unique_ptr<AddressManager>> AddressMapForLinking;
std::vector<std::string> EmptyWarnings;
diff --git a/contrib/libs/llvm12/tools/dsymutil/MachODebugMapParser.cpp b/contrib/libs/llvm12/tools/dsymutil/MachODebugMapParser.cpp
index 95b53c7aa0..37848c561a 100644
--- a/contrib/libs/llvm12/tools/dsymutil/MachODebugMapParser.cpp
+++ b/contrib/libs/llvm12/tools/dsymutil/MachODebugMapParser.cpp
@@ -564,7 +564,7 @@ void MachODebugMapParser::loadMainBinarySymbols(
continue;
}
Section = *SectionOrErr;
- if ((Section == MainBinary.section_end() || Section->isText()) && !Extern)
+ if ((Section == MainBinary.section_end() || Section->isText()) && !Extern)
continue;
uint64_t Addr = cantFail(Sym.getValue());
Expected<StringRef> NameOrErr = Sym.getName();
diff --git a/contrib/libs/llvm12/tools/dsymutil/MachOUtils.cpp b/contrib/libs/llvm12/tools/dsymutil/MachOUtils.cpp
index 84c3f450a1..943af43058 100644
--- a/contrib/libs/llvm12/tools/dsymutil/MachOUtils.cpp
+++ b/contrib/libs/llvm12/tools/dsymutil/MachOUtils.cpp
@@ -239,36 +239,36 @@ getSection(const object::MachOObjectFile &Obj,
// Transfer \a Segment from \a Obj to the output file. This calls into \a Writer
// to write these load commands directly in the output file at the current
// position.
-//
+//
// The function also tries to find a hole in the address map to fit the __DWARF
// segment of \a DwarfSegmentSize size. \a EndAddress is updated to point at the
// highest segment address.
-//
+//
// When the __LINKEDIT segment is transferred, its offset and size are set resp.
// to \a LinkeditOffset and \a LinkeditSize.
-//
-// When the eh_frame section is transferred, its offset and size are set resp.
-// to \a EHFrameOffset and \a EHFrameSize.
+//
+// When the eh_frame section is transferred, its offset and size are set resp.
+// to \a EHFrameOffset and \a EHFrameSize.
template <typename SegmentTy>
static void transferSegmentAndSections(
const object::MachOObjectFile::LoadCommandInfo &LCI, SegmentTy Segment,
const object::MachOObjectFile &Obj, MachObjectWriter &Writer,
- uint64_t LinkeditOffset, uint64_t LinkeditSize, uint64_t EHFrameOffset,
- uint64_t EHFrameSize, uint64_t DwarfSegmentSize, uint64_t &GapForDwarf,
- uint64_t &EndAddress) {
+ uint64_t LinkeditOffset, uint64_t LinkeditSize, uint64_t EHFrameOffset,
+ uint64_t EHFrameSize, uint64_t DwarfSegmentSize, uint64_t &GapForDwarf,
+ uint64_t &EndAddress) {
if (StringRef("__DWARF") == Segment.segname)
return;
- if (StringRef("__TEXT") == Segment.segname && EHFrameSize > 0) {
- Segment.fileoff = EHFrameOffset;
- Segment.filesize = EHFrameSize;
- } else if (StringRef("__LINKEDIT") == Segment.segname) {
+ if (StringRef("__TEXT") == Segment.segname && EHFrameSize > 0) {
+ Segment.fileoff = EHFrameOffset;
+ Segment.filesize = EHFrameSize;
+ } else if (StringRef("__LINKEDIT") == Segment.segname) {
Segment.fileoff = LinkeditOffset;
Segment.filesize = LinkeditSize;
// Resize vmsize by rounding to the page size.
Segment.vmsize = alignTo(LinkeditSize, 0x1000);
- } else {
- Segment.fileoff = Segment.filesize = 0;
+ } else {
+ Segment.fileoff = Segment.filesize = 0;
}
// Check if the end address of the last segment and our current
@@ -289,12 +289,12 @@ static void transferSegmentAndSections(
Writer.W.OS.write(reinterpret_cast<char *>(&Segment), sizeof(Segment));
for (unsigned i = 0; i < nsects; ++i) {
auto Sect = getSection(Obj, Segment, LCI, i);
- if (StringRef("__eh_frame") == Sect.sectname) {
- Sect.offset = EHFrameOffset;
- Sect.reloff = Sect.nreloc = 0;
- } else {
- Sect.offset = Sect.reloff = Sect.nreloc = 0;
- }
+ if (StringRef("__eh_frame") == Sect.sectname) {
+ Sect.offset = EHFrameOffset;
+ Sect.reloff = Sect.nreloc = 0;
+ } else {
+ Sect.offset = Sect.reloff = Sect.nreloc = 0;
+ }
if (Obj.isLittleEndian() != sys::IsLittleEndianHost)
MachO::swapStruct(Sect);
Writer.W.OS.write(reinterpret_cast<char *>(&Sect), sizeof(Sect));
@@ -431,27 +431,27 @@ bool generateDsymCompanion(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
++NumLoadCommands;
}
- // If we have a valid eh_frame to copy, do it.
- uint64_t EHFrameSize = 0;
- StringRef EHFrameData;
- for (const object::SectionRef &Section : InputBinary.sections()) {
- Expected<StringRef> NameOrErr = Section.getName();
- if (!NameOrErr) {
- consumeError(NameOrErr.takeError());
- continue;
- }
- StringRef SectionName = *NameOrErr;
- SectionName = SectionName.substr(SectionName.find_first_not_of("._"));
- if (SectionName == "eh_frame") {
- if (Expected<StringRef> ContentsOrErr = Section.getContents()) {
- EHFrameData = *ContentsOrErr;
- EHFrameSize = Section.getSize();
- } else {
- consumeError(ContentsOrErr.takeError());
- }
- }
- }
-
+ // If we have a valid eh_frame to copy, do it.
+ uint64_t EHFrameSize = 0;
+ StringRef EHFrameData;
+ for (const object::SectionRef &Section : InputBinary.sections()) {
+ Expected<StringRef> NameOrErr = Section.getName();
+ if (!NameOrErr) {
+ consumeError(NameOrErr.takeError());
+ continue;
+ }
+ StringRef SectionName = *NameOrErr;
+ SectionName = SectionName.substr(SectionName.find_first_not_of("._"));
+ if (SectionName == "eh_frame") {
+ if (Expected<StringRef> ContentsOrErr = Section.getContents()) {
+ EHFrameData = *ContentsOrErr;
+ EHFrameSize = Section.getSize();
+ } else {
+ consumeError(ContentsOrErr.takeError());
+ }
+ }
+ }
+
unsigned HeaderSize =
Is64Bit ? sizeof(MachO::mach_header_64) : sizeof(MachO::mach_header);
// We will copy every segment that isn't __DWARF.
@@ -531,10 +531,10 @@ bool generateDsymCompanion(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
Writer.writeSymtabLoadCommand(SymtabStart, NumSyms, StringStart,
NewStringsSize);
- uint64_t EHFrameStart = StringStart + NewStringsSize;
- EHFrameStart = alignTo(EHFrameStart, 0x1000);
-
- uint64_t DwarfSegmentStart = EHFrameStart + EHFrameSize;
+ uint64_t EHFrameStart = StringStart + NewStringsSize;
+ EHFrameStart = alignTo(EHFrameStart, 0x1000);
+
+ uint64_t DwarfSegmentStart = EHFrameStart + EHFrameSize;
DwarfSegmentStart = alignTo(DwarfSegmentStart, 0x1000);
// Write the load commands for the segments and sections we 'import' from
@@ -543,15 +543,15 @@ bool generateDsymCompanion(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
uint64_t GapForDwarf = UINT64_MAX;
for (auto &LCI : InputBinary.load_commands()) {
if (LCI.C.cmd == MachO::LC_SEGMENT)
- transferSegmentAndSections(
- LCI, InputBinary.getSegmentLoadCommand(LCI), InputBinary, Writer,
- SymtabStart, StringStart + NewStringsSize - SymtabStart, EHFrameStart,
- EHFrameSize, DwarfSegmentSize, GapForDwarf, EndAddress);
+ transferSegmentAndSections(
+ LCI, InputBinary.getSegmentLoadCommand(LCI), InputBinary, Writer,
+ SymtabStart, StringStart + NewStringsSize - SymtabStart, EHFrameStart,
+ EHFrameSize, DwarfSegmentSize, GapForDwarf, EndAddress);
else if (LCI.C.cmd == MachO::LC_SEGMENT_64)
- transferSegmentAndSections(
- LCI, InputBinary.getSegment64LoadCommand(LCI), InputBinary, Writer,
- SymtabStart, StringStart + NewStringsSize - SymtabStart, EHFrameStart,
- EHFrameSize, DwarfSegmentSize, GapForDwarf, EndAddress);
+ transferSegmentAndSections(
+ LCI, InputBinary.getSegment64LoadCommand(LCI), InputBinary, Writer,
+ SymtabStart, StringStart + NewStringsSize - SymtabStart, EHFrameStart,
+ EHFrameSize, DwarfSegmentSize, GapForDwarf, EndAddress);
}
uint64_t DwarfVMAddr = alignTo(EndAddress, 0x1000);
@@ -594,17 +594,17 @@ bool generateDsymCompanion(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
}
assert(OutFile.tell() == StringStart + NewStringsSize);
- // Pad till the EH frame start.
- OutFile.write_zeros(EHFrameStart - (StringStart + NewStringsSize));
- assert(OutFile.tell() == EHFrameStart);
-
- // Transfer eh_frame.
- if (EHFrameSize > 0)
- OutFile << EHFrameData;
- assert(OutFile.tell() == EHFrameStart + EHFrameSize);
-
+ // Pad till the EH frame start.
+ OutFile.write_zeros(EHFrameStart - (StringStart + NewStringsSize));
+ assert(OutFile.tell() == EHFrameStart);
+
+ // Transfer eh_frame.
+ if (EHFrameSize > 0)
+ OutFile << EHFrameData;
+ assert(OutFile.tell() == EHFrameStart + EHFrameSize);
+
// Pad till the Dwarf segment start.
- OutFile.write_zeros(DwarfSegmentStart - (EHFrameStart + EHFrameSize));
+ OutFile.write_zeros(DwarfSegmentStart - (EHFrameStart + EHFrameSize));
assert(OutFile.tell() == DwarfSegmentStart);
// Emit the Dwarf sections contents.
diff --git a/contrib/libs/llvm12/tools/dsymutil/SymbolMap.cpp b/contrib/libs/llvm12/tools/dsymutil/SymbolMap.cpp
index 0897b824a3..07a54795a8 100644
--- a/contrib/libs/llvm12/tools/dsymutil/SymbolMap.cpp
+++ b/contrib/libs/llvm12/tools/dsymutil/SymbolMap.cpp
@@ -47,7 +47,7 @@ StringRef SymbolMapTranslator::operator()(StringRef Input) {
return Translation;
// Objective-C symbols for the MachO symbol table start with a \1. Please see
- // `MangleContext::mangleObjCMethodName` in clang.
+ // `MangleContext::mangleObjCMethodName` in clang.
if (Translation[0] == 1)
return StringRef(Translation).drop_front();
diff --git a/contrib/libs/llvm12/tools/dsymutil/dsymutil.cpp b/contrib/libs/llvm12/tools/dsymutil/dsymutil.cpp
index 528a5d8848..347b2dd916 100644
--- a/contrib/libs/llvm12/tools/dsymutil/dsymutil.cpp
+++ b/contrib/libs/llvm12/tools/dsymutil/dsymutil.cpp
@@ -17,7 +17,7 @@
#include "LinkUtils.h"
#include "MachOUtils.h"
#include "Reproducer.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
@@ -157,7 +157,7 @@ static Error verifyOptions(const DsymutilOptions &Options) {
errc::invalid_argument);
}
- if (Options.LinkOpts.Update && llvm::is_contained(Options.InputFiles, "-")) {
+ if (Options.LinkOpts.Update && llvm::is_contained(Options.InputFiles, "-")) {
// FIXME: We cannot use stdin for an update because stdin will be
// consumed by the BinaryHolder during the debugmap parsing, and
// then we will want to consume it again in DwarfLinker. If we
diff --git a/contrib/libs/llvm12/tools/dsymutil/ya.make b/contrib/libs/llvm12/tools/dsymutil/ya.make
index a243a1c5a4..8a3b747e01 100644
--- a/contrib/libs/llvm12/tools/dsymutil/ya.make
+++ b/contrib/libs/llvm12/tools/dsymutil/ya.make
@@ -12,69 +12,69 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Analysis
- contrib/libs/llvm12/lib/AsmParser
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/Bitcode/Reader
- contrib/libs/llvm12/lib/Bitcode/Writer
- contrib/libs/llvm12/lib/Bitstream/Reader
- contrib/libs/llvm12/lib/CodeGen
- contrib/libs/llvm12/lib/CodeGen/AsmPrinter
- contrib/libs/llvm12/lib/CodeGen/GlobalISel
- contrib/libs/llvm12/lib/CodeGen/SelectionDAG
- contrib/libs/llvm12/lib/DWARFLinker
- contrib/libs/llvm12/lib/DebugInfo/CodeView
- contrib/libs/llvm12/lib/DebugInfo/DWARF
- contrib/libs/llvm12/lib/Demangle
- contrib/libs/llvm12/lib/Frontend/OpenMP
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/IRReader
- contrib/libs/llvm12/lib/Linker
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/MC/MCDisassembler
- contrib/libs/llvm12/lib/MC/MCParser
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/Option
- contrib/libs/llvm12/lib/ProfileData
- contrib/libs/llvm12/lib/Remarks
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target
- contrib/libs/llvm12/lib/Target/AArch64
- contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc
- contrib/libs/llvm12/lib/Target/AArch64/TargetInfo
- contrib/libs/llvm12/lib/Target/AArch64/Utils
- contrib/libs/llvm12/lib/Target/ARM
- contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc
- contrib/libs/llvm12/lib/Target/ARM/TargetInfo
- contrib/libs/llvm12/lib/Target/ARM/Utils
- contrib/libs/llvm12/lib/Target/BPF
- contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc
- contrib/libs/llvm12/lib/Target/BPF/TargetInfo
- contrib/libs/llvm12/lib/Target/NVPTX
- contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc
- contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo
- contrib/libs/llvm12/lib/Target/PowerPC
- contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc
- contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo
- contrib/libs/llvm12/lib/Target/X86
- contrib/libs/llvm12/lib/Target/X86/MCTargetDesc
- contrib/libs/llvm12/lib/Target/X86/TargetInfo
- contrib/libs/llvm12/lib/TextAPI/MachO
- contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine
- contrib/libs/llvm12/lib/Transforms/CFGuard
- contrib/libs/llvm12/lib/Transforms/IPO
- contrib/libs/llvm12/lib/Transforms/InstCombine
- contrib/libs/llvm12/lib/Transforms/Instrumentation
- contrib/libs/llvm12/lib/Transforms/Scalar
- contrib/libs/llvm12/lib/Transforms/Utils
- contrib/libs/llvm12/lib/Transforms/Vectorize
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Analysis
+ contrib/libs/llvm12/lib/AsmParser
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/Bitcode/Reader
+ contrib/libs/llvm12/lib/Bitcode/Writer
+ contrib/libs/llvm12/lib/Bitstream/Reader
+ contrib/libs/llvm12/lib/CodeGen
+ contrib/libs/llvm12/lib/CodeGen/AsmPrinter
+ contrib/libs/llvm12/lib/CodeGen/GlobalISel
+ contrib/libs/llvm12/lib/CodeGen/SelectionDAG
+ contrib/libs/llvm12/lib/DWARFLinker
+ contrib/libs/llvm12/lib/DebugInfo/CodeView
+ contrib/libs/llvm12/lib/DebugInfo/DWARF
+ contrib/libs/llvm12/lib/Demangle
+ contrib/libs/llvm12/lib/Frontend/OpenMP
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/IRReader
+ contrib/libs/llvm12/lib/Linker
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/MC/MCDisassembler
+ contrib/libs/llvm12/lib/MC/MCParser
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/Option
+ contrib/libs/llvm12/lib/ProfileData
+ contrib/libs/llvm12/lib/Remarks
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target
+ contrib/libs/llvm12/lib/Target/AArch64
+ contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/AArch64/TargetInfo
+ contrib/libs/llvm12/lib/Target/AArch64/Utils
+ contrib/libs/llvm12/lib/Target/ARM
+ contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/ARM/TargetInfo
+ contrib/libs/llvm12/lib/Target/ARM/Utils
+ contrib/libs/llvm12/lib/Target/BPF
+ contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/BPF/TargetInfo
+ contrib/libs/llvm12/lib/Target/NVPTX
+ contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo
+ contrib/libs/llvm12/lib/Target/PowerPC
+ contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo
+ contrib/libs/llvm12/lib/Target/X86
+ contrib/libs/llvm12/lib/Target/X86/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/X86/TargetInfo
+ contrib/libs/llvm12/lib/TextAPI/MachO
+ contrib/libs/llvm12/lib/Transforms/AggressiveInstCombine
+ contrib/libs/llvm12/lib/Transforms/CFGuard
+ contrib/libs/llvm12/lib/Transforms/IPO
+ contrib/libs/llvm12/lib/Transforms/InstCombine
+ contrib/libs/llvm12/lib/Transforms/Instrumentation
+ contrib/libs/llvm12/lib/Transforms/Scalar
+ contrib/libs/llvm12/lib/Transforms/Utils
+ contrib/libs/llvm12/lib/Transforms/Vectorize
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/dsymutil
- contrib/libs/llvm12/tools/dsymutil
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/dsymutil
+ contrib/libs/llvm12/tools/dsymutil
)
NO_COMPILER_WARNINGS()
@@ -94,10 +94,10 @@ SRCS(
)
IF (OS_DARWIN AND ARCH_AARCH64)
- LDFLAGS(
+ LDFLAGS(
-framework
CoreFoundation
- )
+ )
ENDIF()
END()
diff --git a/contrib/libs/llvm12/tools/llvm-cvtres/llvm-cvtres.cpp b/contrib/libs/llvm12/tools/llvm-cvtres/llvm-cvtres.cpp
index 8810faf985..11cfb466e1 100644
--- a/contrib/libs/llvm12/tools/llvm-cvtres/llvm-cvtres.cpp
+++ b/contrib/libs/llvm12/tools/llvm-cvtres/llvm-cvtres.cpp
@@ -66,7 +66,7 @@ public:
};
}
-static LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg) {
+static LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg) {
errs() << Msg;
exit(1);
}
@@ -75,7 +75,7 @@ static void reportError(StringRef Input, std::error_code EC) {
reportError(Twine(Input) + ": " + EC.message() + ".\n");
}
-static void error(Error EC) {
+static void error(Error EC) {
if (!EC)
return;
handleAllErrors(std::move(EC),
diff --git a/contrib/libs/llvm12/tools/llvm-cvtres/ya.make b/contrib/libs/llvm12/tools/llvm-cvtres/ya.make
index 9de91aedc9..fc7b01fdb7 100644
--- a/contrib/libs/llvm12/tools/llvm-cvtres/ya.make
+++ b/contrib/libs/llvm12/tools/llvm-cvtres/ya.make
@@ -12,25 +12,25 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/Bitcode/Reader
- contrib/libs/llvm12/lib/Bitstream/Reader
- contrib/libs/llvm12/lib/Demangle
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/MC/MCParser
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/Option
- contrib/libs/llvm12/lib/Remarks
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/TextAPI/MachO
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/Bitcode/Reader
+ contrib/libs/llvm12/lib/Bitstream/Reader
+ contrib/libs/llvm12/lib/Demangle
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/MC/MCParser
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/Option
+ contrib/libs/llvm12/lib/Remarks
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/TextAPI/MachO
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-cvtres
- contrib/libs/llvm12/tools/llvm-cvtres
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-cvtres
+ contrib/libs/llvm12/tools/llvm-cvtres
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/tools/llvm-lipo/llvm-lipo.cpp b/contrib/libs/llvm12/tools/llvm-lipo/llvm-lipo.cpp
index 425434092a..7fbe489ecc 100644
--- a/contrib/libs/llvm12/tools/llvm-lipo/llvm-lipo.cpp
+++ b/contrib/libs/llvm12/tools/llvm-lipo/llvm-lipo.cpp
@@ -12,14 +12,14 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
-#include "llvm/BinaryFormat/MachO.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
#include "llvm/Object/Binary.h"
-#include "llvm/Object/IRObjectFile.h"
+#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/MachOUniversal.h"
-#include "llvm/Object/MachOUniversalWriter.h"
+#include "llvm/Object/MachOUniversalWriter.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
@@ -34,7 +34,7 @@ using namespace llvm;
using namespace llvm::object;
static const StringRef ToolName = "llvm-lipo";
-static LLVMContext LLVMCtx;
+static LLVMContext LLVMCtx;
LLVM_ATTRIBUTE_NORETURN static void reportError(Twine Message) {
WithColor::error(errs(), ToolName) << Message << "\n";
@@ -42,15 +42,15 @@ LLVM_ATTRIBUTE_NORETURN static void reportError(Twine Message) {
exit(EXIT_FAILURE);
}
-LLVM_ATTRIBUTE_NORETURN static void reportError(Error E) {
- assert(E);
- std::string Buf;
- raw_string_ostream OS(Buf);
- logAllUnhandledErrors(std::move(E), OS);
- OS.flush();
- reportError(Buf);
-}
-
+LLVM_ATTRIBUTE_NORETURN static void reportError(Error E) {
+ assert(E);
+ std::string Buf;
+ raw_string_ostream OS(Buf);
+ logAllUnhandledErrors(std::move(E), OS);
+ OS.flush();
+ reportError(Buf);
+}
+
LLVM_ATTRIBUTE_NORETURN static void reportError(StringRef File, Error E) {
assert(E);
std::string Buf;
@@ -118,18 +118,18 @@ struct Config {
LipoAction ActionToPerform;
};
-static Slice createSliceFromArchive(const Archive &A) {
- Expected<Slice> ArchiveOrSlice = Slice::create(A, &LLVMCtx);
- if (!ArchiveOrSlice)
- reportError(A.getFileName(), ArchiveOrSlice.takeError());
- return *ArchiveOrSlice;
+static Slice createSliceFromArchive(const Archive &A) {
+ Expected<Slice> ArchiveOrSlice = Slice::create(A, &LLVMCtx);
+ if (!ArchiveOrSlice)
+ reportError(A.getFileName(), ArchiveOrSlice.takeError());
+ return *ArchiveOrSlice;
}
-static Slice createSliceFromIR(const IRObjectFile &IRO, unsigned Align) {
- Expected<Slice> IROrErr = Slice::create(IRO, Align);
- if (!IROrErr)
- reportError(IRO.getFileName(), IROrErr.takeError());
- return *IROrErr;
+static Slice createSliceFromIR(const IRObjectFile &IRO, unsigned Align) {
+ Expected<Slice> IROrErr = Slice::create(IRO, Align);
+ if (!IROrErr)
+ reportError(IRO.getFileName(), IROrErr.takeError());
+ return *IROrErr;
}
} // end namespace
@@ -319,20 +319,20 @@ static SmallVector<OwningBinary<Binary>, 1>
readInputBinaries(ArrayRef<InputFile> InputFiles) {
SmallVector<OwningBinary<Binary>, 1> InputBinaries;
for (const InputFile &IF : InputFiles) {
- Expected<OwningBinary<Binary>> BinaryOrErr =
- createBinary(IF.FileName, &LLVMCtx);
+ Expected<OwningBinary<Binary>> BinaryOrErr =
+ createBinary(IF.FileName, &LLVMCtx);
if (!BinaryOrErr)
reportError(IF.FileName, BinaryOrErr.takeError());
const Binary *B = BinaryOrErr->getBinary();
- if (!B->isArchive() && !B->isMachO() && !B->isMachOUniversalBinary() &&
- !B->isIR())
+ if (!B->isArchive() && !B->isMachO() && !B->isMachOUniversalBinary() &&
+ !B->isIR())
reportError("File " + IF.FileName + " has unsupported binary format");
- if (IF.ArchType && (B->isMachO() || B->isArchive() || B->isIR())) {
- const auto S = B->isMachO()
- ? Slice(*cast<MachOObjectFile>(B))
- : B->isArchive()
- ? createSliceFromArchive(*cast<Archive>(B))
- : createSliceFromIR(*cast<IRObjectFile>(B), 0);
+ if (IF.ArchType && (B->isMachO() || B->isArchive() || B->isIR())) {
+ const auto S = B->isMachO()
+ ? Slice(*cast<MachOObjectFile>(B))
+ : B->isArchive()
+ ? createSliceFromArchive(*cast<Archive>(B))
+ : createSliceFromIR(*cast<IRObjectFile>(B), 0);
const auto SpecifiedCPUType = MachO::getCPUTypeFromArchitecture(
MachO::getArchitectureFromName(
Triple(*IF.ArchType).getArchName()))
@@ -384,53 +384,53 @@ static void printBinaryArchs(const Binary *Binary, raw_ostream &OS) {
// Prints trailing space for compatibility with cctools lipo.
if (auto UO = dyn_cast<MachOUniversalBinary>(Binary)) {
for (const auto &O : UO->objects()) {
- // Order here is important, because both MachOObjectFile and
- // IRObjectFile can be created with a binary that has embedded bitcode.
+ // Order here is important, because both MachOObjectFile and
+ // IRObjectFile can be created with a binary that has embedded bitcode.
Expected<std::unique_ptr<MachOObjectFile>> MachOObjOrError =
O.getAsObjectFile();
if (MachOObjOrError) {
- OS << Slice(*(MachOObjOrError->get())).getArchString() << " ";
+ OS << Slice(*(MachOObjOrError->get())).getArchString() << " ";
+ continue;
+ }
+ Expected<std::unique_ptr<IRObjectFile>> IROrError =
+ O.getAsIRObject(LLVMCtx);
+ if (IROrError) {
+ consumeError(MachOObjOrError.takeError());
+ Expected<Slice> SliceOrErr = Slice::create(**IROrError, O.getAlign());
+ if (!SliceOrErr) {
+ reportError(Binary->getFileName(), SliceOrErr.takeError());
+ continue;
+ }
+ OS << SliceOrErr.get().getArchString() << " ";
continue;
}
- Expected<std::unique_ptr<IRObjectFile>> IROrError =
- O.getAsIRObject(LLVMCtx);
- if (IROrError) {
- consumeError(MachOObjOrError.takeError());
- Expected<Slice> SliceOrErr = Slice::create(**IROrError, O.getAlign());
- if (!SliceOrErr) {
- reportError(Binary->getFileName(), SliceOrErr.takeError());
- continue;
- }
- OS << SliceOrErr.get().getArchString() << " ";
- continue;
- }
Expected<std::unique_ptr<Archive>> ArchiveOrError = O.getAsArchive();
if (ArchiveOrError) {
consumeError(MachOObjOrError.takeError());
- consumeError(IROrError.takeError());
- OS << createSliceFromArchive(**ArchiveOrError).getArchString() << " ";
+ consumeError(IROrError.takeError());
+ OS << createSliceFromArchive(**ArchiveOrError).getArchString() << " ";
continue;
}
consumeError(ArchiveOrError.takeError());
reportError(Binary->getFileName(), MachOObjOrError.takeError());
- reportError(Binary->getFileName(), IROrError.takeError());
+ reportError(Binary->getFileName(), IROrError.takeError());
}
OS << "\n";
return;
}
-
- if (const auto *MachO = dyn_cast<MachOObjectFile>(Binary)) {
- OS << Slice(*MachO).getArchString() << " \n";
- return;
- }
-
- // This should be always the case, as this is tested in readInputBinaries
- const auto *IR = cast<IRObjectFile>(Binary);
- Expected<Slice> SliceOrErr = createSliceFromIR(*IR, 0);
- if (!SliceOrErr)
- reportError(IR->getFileName(), SliceOrErr.takeError());
-
- OS << SliceOrErr->getArchString() << " \n";
+
+ if (const auto *MachO = dyn_cast<MachOObjectFile>(Binary)) {
+ OS << Slice(*MachO).getArchString() << " \n";
+ return;
+ }
+
+ // This should be always the case, as this is tested in readInputBinaries
+ const auto *IR = cast<IRObjectFile>(Binary);
+ Expected<Slice> SliceOrErr = createSliceFromIR(*IR, 0);
+ if (!SliceOrErr)
+ reportError(IR->getFileName(), SliceOrErr.takeError());
+
+ OS << SliceOrErr->getArchString() << " \n";
}
LLVM_ATTRIBUTE_NORETURN
@@ -480,23 +480,23 @@ static void thinSlice(ArrayRef<OwningBinary<Binary>> InputBinaries,
auto *UO = cast<MachOUniversalBinary>(InputBinaries.front().getBinary());
Expected<std::unique_ptr<MachOObjectFile>> Obj =
UO->getMachOObjectForArch(ArchType);
- Expected<std::unique_ptr<IRObjectFile>> IRObj =
- UO->getIRObjectForArch(ArchType, LLVMCtx);
+ Expected<std::unique_ptr<IRObjectFile>> IRObj =
+ UO->getIRObjectForArch(ArchType, LLVMCtx);
Expected<std::unique_ptr<Archive>> Ar = UO->getArchiveForArch(ArchType);
- if (!Obj && !IRObj && !Ar)
+ if (!Obj && !IRObj && !Ar)
reportError("fat input file " + UO->getFileName() +
" does not contain the specified architecture " + ArchType +
" to thin it to");
- Binary *B;
- // Order here is important, because both Obj and IRObj will be valid with a
- // binary that has embedded bitcode.
- if (Obj)
- B = Obj->get();
- else if (IRObj)
- B = IRObj->get();
- else
- B = Ar->get();
-
+ Binary *B;
+ // Order here is important, because both Obj and IRObj will be valid with a
+ // binary that has embedded bitcode.
+ if (Obj)
+ B = Obj->get();
+ else if (IRObj)
+ B = IRObj->get();
+ else
+ B = Ar->get();
+
Expected<std::unique_ptr<FileOutputBuffer>> OutFileOrError =
FileOutputBuffer::create(OutputFileName,
B->getMemoryBufferRef().getBufferSize(),
@@ -538,8 +538,8 @@ static void updateAlignments(Range &Slices,
static void checkUnusedAlignments(ArrayRef<Slice> Slices,
const StringMap<const uint32_t> &Alignments) {
auto HasArch = [&](StringRef Arch) {
- return llvm::any_of(Slices,
- [Arch](Slice S) { return S.getArchString() == Arch; });
+ return llvm::any_of(Slices,
+ [Arch](Slice S) { return S.getArchString() == Arch; });
};
for (StringRef Arch : Alignments.keys())
if (!HasArch(Arch))
@@ -550,47 +550,47 @@ static void checkUnusedAlignments(ArrayRef<Slice> Slices,
// Updates vector ExtractedObjects with the MachOObjectFiles extracted from
// Universal Binary files to transfer ownership.
-static SmallVector<Slice, 2>
-buildSlices(ArrayRef<OwningBinary<Binary>> InputBinaries,
- const StringMap<const uint32_t> &Alignments,
- SmallVectorImpl<std::unique_ptr<SymbolicFile>> &ExtractedObjects) {
+static SmallVector<Slice, 2>
+buildSlices(ArrayRef<OwningBinary<Binary>> InputBinaries,
+ const StringMap<const uint32_t> &Alignments,
+ SmallVectorImpl<std::unique_ptr<SymbolicFile>> &ExtractedObjects) {
SmallVector<Slice, 2> Slices;
for (auto &IB : InputBinaries) {
const Binary *InputBinary = IB.getBinary();
if (auto UO = dyn_cast<MachOUniversalBinary>(InputBinary)) {
for (const auto &O : UO->objects()) {
- // Order here is important, because both MachOObjectFile and
- // IRObjectFile can be created with a binary that has embedded bitcode.
+ // Order here is important, because both MachOObjectFile and
+ // IRObjectFile can be created with a binary that has embedded bitcode.
Expected<std::unique_ptr<MachOObjectFile>> BinaryOrError =
O.getAsObjectFile();
- if (BinaryOrError) {
- Slices.emplace_back(*(BinaryOrError.get()), O.getAlign());
- ExtractedObjects.push_back(std::move(BinaryOrError.get()));
- continue;
- }
- Expected<std::unique_ptr<IRObjectFile>> IROrError =
- O.getAsIRObject(LLVMCtx);
- if (IROrError) {
- consumeError(BinaryOrError.takeError());
- Slice S = createSliceFromIR(**IROrError, O.getAlign());
- ExtractedObjects.emplace_back(std::move(IROrError.get()));
- Slices.emplace_back(std::move(S));
- continue;
- }
- reportError(InputBinary->getFileName(), BinaryOrError.takeError());
+ if (BinaryOrError) {
+ Slices.emplace_back(*(BinaryOrError.get()), O.getAlign());
+ ExtractedObjects.push_back(std::move(BinaryOrError.get()));
+ continue;
+ }
+ Expected<std::unique_ptr<IRObjectFile>> IROrError =
+ O.getAsIRObject(LLVMCtx);
+ if (IROrError) {
+ consumeError(BinaryOrError.takeError());
+ Slice S = createSliceFromIR(**IROrError, O.getAlign());
+ ExtractedObjects.emplace_back(std::move(IROrError.get()));
+ Slices.emplace_back(std::move(S));
+ continue;
+ }
+ reportError(InputBinary->getFileName(), BinaryOrError.takeError());
}
- } else if (const auto *O = dyn_cast<MachOObjectFile>(InputBinary)) {
- Slices.emplace_back(*O);
- } else if (const auto *A = dyn_cast<Archive>(InputBinary)) {
- Slices.push_back(createSliceFromArchive(*A));
- } else if (const auto *IRO = dyn_cast<IRObjectFile>(InputBinary)) {
- // Original Apple's lipo set the alignment to 0
- Expected<Slice> SliceOrErr = Slice::create(*IRO, 0);
- if (!SliceOrErr) {
- reportError(InputBinary->getFileName(), SliceOrErr.takeError());
- continue;
- }
- Slices.emplace_back(std::move(SliceOrErr.get()));
+ } else if (const auto *O = dyn_cast<MachOObjectFile>(InputBinary)) {
+ Slices.emplace_back(*O);
+ } else if (const auto *A = dyn_cast<Archive>(InputBinary)) {
+ Slices.push_back(createSliceFromArchive(*A));
+ } else if (const auto *IRO = dyn_cast<IRObjectFile>(InputBinary)) {
+ // Original Apple's lipo set the alignment to 0
+ Expected<Slice> SliceOrErr = Slice::create(*IRO, 0);
+ if (!SliceOrErr) {
+ reportError(InputBinary->getFileName(), SliceOrErr.takeError());
+ continue;
+ }
+ Slices.emplace_back(std::move(SliceOrErr.get()));
} else {
llvm_unreachable("Unexpected binary format");
}
@@ -606,16 +606,16 @@ static void createUniversalBinary(ArrayRef<OwningBinary<Binary>> InputBinaries,
assert(InputBinaries.size() >= 1 && "Incorrect number of input binaries");
assert(!OutputFileName.empty() && "Create expects a single output file");
- SmallVector<std::unique_ptr<SymbolicFile>, 1> ExtractedObjects;
+ SmallVector<std::unique_ptr<SymbolicFile>, 1> ExtractedObjects;
SmallVector<Slice, 1> Slices =
buildSlices(InputBinaries, Alignments, ExtractedObjects);
checkArchDuplicates(Slices);
checkUnusedAlignments(Slices, Alignments);
- llvm::stable_sort(Slices);
- if (Error E = writeUniversalBinary(Slices, OutputFileName))
- reportError(std::move(E));
-
+ llvm::stable_sort(Slices);
+ if (Error E = writeUniversalBinary(Slices, OutputFileName))
+ reportError(std::move(E));
+
exit(EXIT_SUCCESS);
}
@@ -634,7 +634,7 @@ static void extractSlice(ArrayRef<OwningBinary<Binary>> InputBinaries,
" must be a fat file when the -extract option is specified");
}
- SmallVector<std::unique_ptr<SymbolicFile>, 2> ExtractedObjects;
+ SmallVector<std::unique_ptr<SymbolicFile>, 2> ExtractedObjects;
SmallVector<Slice, 2> Slices =
buildSlices(InputBinaries, Alignments, ExtractedObjects);
erase_if(Slices, [ArchType](const Slice &S) {
@@ -645,10 +645,10 @@ static void extractSlice(ArrayRef<OwningBinary<Binary>> InputBinaries,
reportError(
"fat input file " + InputBinaries.front().getBinary()->getFileName() +
" does not contain the specified architecture " + ArchType);
-
- llvm::stable_sort(Slices);
- if (Error E = writeUniversalBinary(Slices, OutputFileName))
- reportError(std::move(E));
+
+ llvm::stable_sort(Slices);
+ if (Error E = writeUniversalBinary(Slices, OutputFileName))
+ reportError(std::move(E));
exit(EXIT_SUCCESS);
}
@@ -664,7 +664,7 @@ buildReplacementSlices(ArrayRef<OwningBinary<Binary>> ReplacementBinaries,
if (!O)
reportError("replacement file: " + ReplacementBinary->getFileName() +
" is a fat file (must be a thin file)");
- Slice S(*O);
+ Slice S(*O);
auto Entry = Slices.try_emplace(S.getArchString(), S);
if (!Entry.second)
reportError("-replace " + S.getArchString() +
@@ -696,7 +696,7 @@ static void replaceSlices(ArrayRef<OwningBinary<Binary>> InputBinaries,
StringMap<Slice> ReplacementSlices =
buildReplacementSlices(ReplacementBinaries, Alignments);
- SmallVector<std::unique_ptr<SymbolicFile>, 2> ExtractedObjects;
+ SmallVector<std::unique_ptr<SymbolicFile>, 2> ExtractedObjects;
SmallVector<Slice, 2> Slices =
buildSlices(InputBinaries, Alignments, ExtractedObjects);
@@ -715,10 +715,10 @@ static void replaceSlices(ArrayRef<OwningBinary<Binary>> InputBinaries,
" does not contain that architecture");
checkUnusedAlignments(Slices, Alignments);
-
- llvm::stable_sort(Slices);
- if (Error E = writeUniversalBinary(Slices, OutputFileName))
- reportError(std::move(E));
+
+ llvm::stable_sort(Slices);
+ if (Error E = writeUniversalBinary(Slices, OutputFileName))
+ reportError(std::move(E));
exit(EXIT_SUCCESS);
}
diff --git a/contrib/libs/llvm12/tools/llvm-lipo/ya.make b/contrib/libs/llvm12/tools/llvm-lipo/ya.make
index a48a15a45e..afb28b31ce 100644
--- a/contrib/libs/llvm12/tools/llvm-lipo/ya.make
+++ b/contrib/libs/llvm12/tools/llvm-lipo/ya.make
@@ -12,55 +12,55 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/Bitcode/Reader
- contrib/libs/llvm12/lib/Bitstream/Reader
- contrib/libs/llvm12/lib/Demangle
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/MC/MCParser
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/Option
- contrib/libs/llvm12/lib/Remarks
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target/AArch64
- contrib/libs/llvm12/lib/Target/AArch64/AsmParser
- contrib/libs/llvm12/lib/Target/AArch64/Disassembler
- contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc
- contrib/libs/llvm12/lib/Target/AArch64/TargetInfo
- contrib/libs/llvm12/lib/Target/AArch64/Utils
- contrib/libs/llvm12/lib/Target/ARM
- contrib/libs/llvm12/lib/Target/ARM/AsmParser
- contrib/libs/llvm12/lib/Target/ARM/Disassembler
- contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc
- contrib/libs/llvm12/lib/Target/ARM/TargetInfo
- contrib/libs/llvm12/lib/Target/ARM/Utils
- contrib/libs/llvm12/lib/Target/BPF
- contrib/libs/llvm12/lib/Target/BPF/AsmParser
- contrib/libs/llvm12/lib/Target/BPF/Disassembler
- contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc
- contrib/libs/llvm12/lib/Target/BPF/TargetInfo
- contrib/libs/llvm12/lib/Target/NVPTX
- contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc
- contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo
- contrib/libs/llvm12/lib/Target/PowerPC
- contrib/libs/llvm12/lib/Target/PowerPC/AsmParser
- contrib/libs/llvm12/lib/Target/PowerPC/Disassembler
- contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc
- contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo
- contrib/libs/llvm12/lib/Target/X86
- contrib/libs/llvm12/lib/Target/X86/AsmParser
- contrib/libs/llvm12/lib/Target/X86/Disassembler
- contrib/libs/llvm12/lib/Target/X86/MCTargetDesc
- contrib/libs/llvm12/lib/Target/X86/TargetInfo
- contrib/libs/llvm12/lib/TextAPI/MachO
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/Bitcode/Reader
+ contrib/libs/llvm12/lib/Bitstream/Reader
+ contrib/libs/llvm12/lib/Demangle
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/MC/MCParser
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/Option
+ contrib/libs/llvm12/lib/Remarks
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target/AArch64
+ contrib/libs/llvm12/lib/Target/AArch64/AsmParser
+ contrib/libs/llvm12/lib/Target/AArch64/Disassembler
+ contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/AArch64/TargetInfo
+ contrib/libs/llvm12/lib/Target/AArch64/Utils
+ contrib/libs/llvm12/lib/Target/ARM
+ contrib/libs/llvm12/lib/Target/ARM/AsmParser
+ contrib/libs/llvm12/lib/Target/ARM/Disassembler
+ contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/ARM/TargetInfo
+ contrib/libs/llvm12/lib/Target/ARM/Utils
+ contrib/libs/llvm12/lib/Target/BPF
+ contrib/libs/llvm12/lib/Target/BPF/AsmParser
+ contrib/libs/llvm12/lib/Target/BPF/Disassembler
+ contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/BPF/TargetInfo
+ contrib/libs/llvm12/lib/Target/NVPTX
+ contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo
+ contrib/libs/llvm12/lib/Target/PowerPC
+ contrib/libs/llvm12/lib/Target/PowerPC/AsmParser
+ contrib/libs/llvm12/lib/Target/PowerPC/Disassembler
+ contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo
+ contrib/libs/llvm12/lib/Target/X86
+ contrib/libs/llvm12/lib/Target/X86/AsmParser
+ contrib/libs/llvm12/lib/Target/X86/Disassembler
+ contrib/libs/llvm12/lib/Target/X86/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/X86/TargetInfo
+ contrib/libs/llvm12/lib/TextAPI/MachO
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-lipo
- contrib/libs/llvm12/tools/llvm-lipo
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-lipo
+ contrib/libs/llvm12/tools/llvm-lipo
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/tools/llvm-ml/Opts.td b/contrib/libs/llvm12/tools/llvm-ml/Opts.td
index 4e4766484d..4c2757b057 100644
--- a/contrib/libs/llvm12/tools/llvm-ml/Opts.td
+++ b/contrib/libs/llvm12/tools/llvm-ml/Opts.td
@@ -1,110 +1,110 @@
-include "llvm/Option/OptParser.td"
-
-// For LLVM-specific options, we prefer a two-dash prefix, but accept one for
-// compatibility with llvm-mc. For clear separation from ML.EXE compatible
-// options, slash is not accepted.
-class LLVMFlag<string name> : Flag<["--", "-"], name>;
-class LLVMJoined<string name> : Joined<["--", "-"], name>;
-class LLVMJoinedOrSeparate<string name> : JoinedOrSeparate<["--", "-"], name>;
-class LLVMSeparate<string name> : Separate<["--", "-"], name>;
-
-def ml_Group : OptionGroup<"<ml options>">,
- HelpText<"ML.EXE COMPATIBILITY OPTIONS">;
-class MLFlag<string name> : Flag<["/", "-"], name>, Group<ml_Group>;
-class MLJoined<string name> : Joined<["/", "-"], name>, Group<ml_Group>;
-class MLJoinedOrSeparate<string name> : JoinedOrSeparate<["/", "-"], name>,
- Group<ml_Group>;
-class MLSeparate<string name> : Separate<["/", "-"], name>, Group<ml_Group>;
-
-def unsupported_Group : OptionGroup<"unsupported">, Flags<[HelpHidden]>,
- HelpText<"UNSUPPORTED ML.EXE COMPATIBILITY OPTIONS">;
-class UnsupportedFlag<string name> : Flag<["/", "-"], name>,
- Group<unsupported_Group>;
-class UnsupportedJoined<string name> : Joined<["/", "-"], name>,
- Group<unsupported_Group>;
-class UnsupportedJoinedOrSeparate<string name> :
- JoinedOrSeparate<["/", "-"], name>, Group<unsupported_Group>;
-class UnsupportedSeparate<string name> : Separate<["/", "-"], name>,
- Group<unsupported_Group>;
-
-def help : MLFlag<"?">,
- HelpText<"Display available options">;
-def help_long : MLFlag<"help">, Alias<help>;
-def assemble_only : MLFlag<"c">, HelpText<"Assemble only; do not link">;
-def define : MLJoinedOrSeparate<"D">, MetaVarName<"<macro>=<value>">,
- HelpText<"Define <macro> to <value> (or blank if <value> "
- "omitted)">;
-def output_file : MLJoinedOrSeparate<"Fo">, HelpText<"Names the output file">;
-def include_path : MLJoinedOrSeparate<"I">,
- HelpText<"Sets path for include files">;
-def safeseh : MLFlag<"safeseh">,
- HelpText<"Mark resulting object files as either containing no "
- "exception handlers or containing exception handlers "
- "that are all declared with .SAFESEH. Only available in "
- "32-bit.">;
-def assembly_file : MLJoinedOrSeparate<"Ta">,
- HelpText<"Assemble source file with name not ending with "
- "the .asm extension">;
-
-def bitness : LLVMJoined<"m">, Values<"32,64">,
- HelpText<"Target platform (x86 or x86-64)">;
-def as_lex : LLVMFlag<"as-lex">,
- HelpText<"Lex tokens from a .asm file without assembling">;
-def filetype : LLVMJoined<"filetype=">, Values<"obj,s,null">,
- HelpText<"Emit a file with the given type">;
-def output_att_asm : LLVMFlag<"output-att-asm">,
- HelpText<"Use ATT syntax for output assembly">;
-def show_encoding : LLVMFlag<"show-encoding">,
- HelpText<"Show instruction encodings in output assembly">;
-def show_inst : LLVMFlag<"show-inst">,
- HelpText<"Show internal instruction representation in output "
- "assembly">;
-def show_inst_operands : LLVMFlag<"show-inst-operands">,
- HelpText<"Show instructions operands as parsed">;
-def print_imm_hex : LLVMFlag<"print-imm-hex">,
- HelpText<"Prefer hex format for immediate values in output "
- "assembly">;
-def preserve_comments : LLVMFlag<"preserve-comments">,
- HelpText<"Preserve comments in output assembly">;
-def save_temp_labels : LLVMFlag<"save-temp-labels">,
- HelpText<"Don't discard temporary labels">;
-
-def tiny_model_support : UnsupportedFlag<"AT">, HelpText<"">;
-def alternate_linker : UnsupportedJoined<"Bl">, HelpText<"">;
-def coff_object_file : UnsupportedFlag<"coff">, HelpText<"">;
-def preserve_identifier_case : UnsupportedFlag<"Cp">, HelpText<"">;
-def uppercase_identifiers : UnsupportedFlag<"Cu">, HelpText<"">;
-def preserve_extern_case : UnsupportedFlag<"Cx">, HelpText<"">;
-def output_preprocessed : UnsupportedFlag<"EP">, HelpText<"">;
-def errorreport : UnsupportedJoined<"ERRORREPORT">, HelpText<"">;
-def stacksize : UnsupportedSeparate<"F">, HelpText<"">;
-def executable_file : UnsupportedSeparate<"Fe">, HelpText<"">;
-def code_listing_file : UnsupportedJoined<"FI">, HelpText<"">;
-def linker_map_file : UnsupportedJoined<"Fm">, HelpText<"">;
-def fp_emulator_fixups : UnsupportedFlag<"FPi">, HelpText<"">;
-def source_browser_file : UnsupportedJoined<"Fr">, HelpText<"">;
-def extended_source_browser_file : UnsupportedJoined<"FR">, HelpText<"">;
-def pascal_conventions : UnsupportedFlag<"Gc">, HelpText<"">;
-def c_conventions : UnsupportedFlag<"Gd">, HelpText<"">;
-def stdcall_conventions : UnsupportedFlag<"GZ">, HelpText<"">;
-def extern_name_limit : UnsupportedSeparate<"H">, HelpText<"">;
-def nologo : UnsupportedFlag<"nologo">, HelpText<"">;
-def omf_object_file : UnsupportedFlag<"omf">, HelpText<"">;
-def full_listing : UnsupportedFlag<"Sa">, HelpText<"">;
-def first_pass_listing : UnsupportedFlag<"Sf">, HelpText<"">;
-def listing_width : UnsupportedSeparate<"SI">, HelpText<"">;
-def listing_without_symbols : UnsupportedFlag<"Sn">, HelpText<"">;
-def listing_page_length : UnsupportedSeparate<"Sp">, HelpText<"">;
-def listing_subtitle : UnsupportedSeparate<"Ss">, HelpText<"">;
-def listing_title : UnsupportedSeparate<"St">, HelpText<"">;
-def listing_false_conditionals : UnsupportedFlag<"Sx">, HelpText<"">;
-def extra_warnings : UnsupportedFlag<"w">, HelpText<"">;
-def warning_level : UnsupportedJoined<"W">, HelpText<"">;
-def error_on_warning : UnsupportedFlag<"WX">, HelpText<"">;
-def ignore_include_envvar : UnsupportedFlag<"X">, HelpText<"">;
-def line_number_info : UnsupportedFlag<"Zd">, HelpText<"">;
-def export_all_symbols : UnsupportedFlag<"Zf">, HelpText<"">;
-def codeview_info : UnsupportedFlag<"Zi">, HelpText<"">;
-def enable_m510_option : UnsupportedFlag<"Zm">, HelpText<"">;
-def structure_packing : UnsupportedJoined<"Zp">, HelpText<"">;
-def parse_only : UnsupportedFlag<"Zs">, HelpText<"">;
+include "llvm/Option/OptParser.td"
+
+// For LLVM-specific options, we prefer a two-dash prefix, but accept one for
+// compatibility with llvm-mc. For clear separation from ML.EXE compatible
+// options, slash is not accepted.
+class LLVMFlag<string name> : Flag<["--", "-"], name>;
+class LLVMJoined<string name> : Joined<["--", "-"], name>;
+class LLVMJoinedOrSeparate<string name> : JoinedOrSeparate<["--", "-"], name>;
+class LLVMSeparate<string name> : Separate<["--", "-"], name>;
+
+def ml_Group : OptionGroup<"<ml options>">,
+ HelpText<"ML.EXE COMPATIBILITY OPTIONS">;
+class MLFlag<string name> : Flag<["/", "-"], name>, Group<ml_Group>;
+class MLJoined<string name> : Joined<["/", "-"], name>, Group<ml_Group>;
+class MLJoinedOrSeparate<string name> : JoinedOrSeparate<["/", "-"], name>,
+ Group<ml_Group>;
+class MLSeparate<string name> : Separate<["/", "-"], name>, Group<ml_Group>;
+
+def unsupported_Group : OptionGroup<"unsupported">, Flags<[HelpHidden]>,
+ HelpText<"UNSUPPORTED ML.EXE COMPATIBILITY OPTIONS">;
+class UnsupportedFlag<string name> : Flag<["/", "-"], name>,
+ Group<unsupported_Group>;
+class UnsupportedJoined<string name> : Joined<["/", "-"], name>,
+ Group<unsupported_Group>;
+class UnsupportedJoinedOrSeparate<string name> :
+ JoinedOrSeparate<["/", "-"], name>, Group<unsupported_Group>;
+class UnsupportedSeparate<string name> : Separate<["/", "-"], name>,
+ Group<unsupported_Group>;
+
+def help : MLFlag<"?">,
+ HelpText<"Display available options">;
+def help_long : MLFlag<"help">, Alias<help>;
+def assemble_only : MLFlag<"c">, HelpText<"Assemble only; do not link">;
+def define : MLJoinedOrSeparate<"D">, MetaVarName<"<macro>=<value>">,
+ HelpText<"Define <macro> to <value> (or blank if <value> "
+ "omitted)">;
+def output_file : MLJoinedOrSeparate<"Fo">, HelpText<"Names the output file">;
+def include_path : MLJoinedOrSeparate<"I">,
+ HelpText<"Sets path for include files">;
+def safeseh : MLFlag<"safeseh">,
+ HelpText<"Mark resulting object files as either containing no "
+ "exception handlers or containing exception handlers "
+ "that are all declared with .SAFESEH. Only available in "
+ "32-bit.">;
+def assembly_file : MLJoinedOrSeparate<"Ta">,
+ HelpText<"Assemble source file with name not ending with "
+ "the .asm extension">;
+
+def bitness : LLVMJoined<"m">, Values<"32,64">,
+ HelpText<"Target platform (x86 or x86-64)">;
+def as_lex : LLVMFlag<"as-lex">,
+ HelpText<"Lex tokens from a .asm file without assembling">;
+def filetype : LLVMJoined<"filetype=">, Values<"obj,s,null">,
+ HelpText<"Emit a file with the given type">;
+def output_att_asm : LLVMFlag<"output-att-asm">,
+ HelpText<"Use ATT syntax for output assembly">;
+def show_encoding : LLVMFlag<"show-encoding">,
+ HelpText<"Show instruction encodings in output assembly">;
+def show_inst : LLVMFlag<"show-inst">,
+ HelpText<"Show internal instruction representation in output "
+ "assembly">;
+def show_inst_operands : LLVMFlag<"show-inst-operands">,
+ HelpText<"Show instructions operands as parsed">;
+def print_imm_hex : LLVMFlag<"print-imm-hex">,
+ HelpText<"Prefer hex format for immediate values in output "
+ "assembly">;
+def preserve_comments : LLVMFlag<"preserve-comments">,
+ HelpText<"Preserve comments in output assembly">;
+def save_temp_labels : LLVMFlag<"save-temp-labels">,
+ HelpText<"Don't discard temporary labels">;
+
+def tiny_model_support : UnsupportedFlag<"AT">, HelpText<"">;
+def alternate_linker : UnsupportedJoined<"Bl">, HelpText<"">;
+def coff_object_file : UnsupportedFlag<"coff">, HelpText<"">;
+def preserve_identifier_case : UnsupportedFlag<"Cp">, HelpText<"">;
+def uppercase_identifiers : UnsupportedFlag<"Cu">, HelpText<"">;
+def preserve_extern_case : UnsupportedFlag<"Cx">, HelpText<"">;
+def output_preprocessed : UnsupportedFlag<"EP">, HelpText<"">;
+def errorreport : UnsupportedJoined<"ERRORREPORT">, HelpText<"">;
+def stacksize : UnsupportedSeparate<"F">, HelpText<"">;
+def executable_file : UnsupportedSeparate<"Fe">, HelpText<"">;
+def code_listing_file : UnsupportedJoined<"FI">, HelpText<"">;
+def linker_map_file : UnsupportedJoined<"Fm">, HelpText<"">;
+def fp_emulator_fixups : UnsupportedFlag<"FPi">, HelpText<"">;
+def source_browser_file : UnsupportedJoined<"Fr">, HelpText<"">;
+def extended_source_browser_file : UnsupportedJoined<"FR">, HelpText<"">;
+def pascal_conventions : UnsupportedFlag<"Gc">, HelpText<"">;
+def c_conventions : UnsupportedFlag<"Gd">, HelpText<"">;
+def stdcall_conventions : UnsupportedFlag<"GZ">, HelpText<"">;
+def extern_name_limit : UnsupportedSeparate<"H">, HelpText<"">;
+def nologo : UnsupportedFlag<"nologo">, HelpText<"">;
+def omf_object_file : UnsupportedFlag<"omf">, HelpText<"">;
+def full_listing : UnsupportedFlag<"Sa">, HelpText<"">;
+def first_pass_listing : UnsupportedFlag<"Sf">, HelpText<"">;
+def listing_width : UnsupportedSeparate<"SI">, HelpText<"">;
+def listing_without_symbols : UnsupportedFlag<"Sn">, HelpText<"">;
+def listing_page_length : UnsupportedSeparate<"Sp">, HelpText<"">;
+def listing_subtitle : UnsupportedSeparate<"Ss">, HelpText<"">;
+def listing_title : UnsupportedSeparate<"St">, HelpText<"">;
+def listing_false_conditionals : UnsupportedFlag<"Sx">, HelpText<"">;
+def extra_warnings : UnsupportedFlag<"w">, HelpText<"">;
+def warning_level : UnsupportedJoined<"W">, HelpText<"">;
+def error_on_warning : UnsupportedFlag<"WX">, HelpText<"">;
+def ignore_include_envvar : UnsupportedFlag<"X">, HelpText<"">;
+def line_number_info : UnsupportedFlag<"Zd">, HelpText<"">;
+def export_all_symbols : UnsupportedFlag<"Zf">, HelpText<"">;
+def codeview_info : UnsupportedFlag<"Zi">, HelpText<"">;
+def enable_m510_option : UnsupportedFlag<"Zm">, HelpText<"">;
+def structure_packing : UnsupportedJoined<"Zp">, HelpText<"">;
+def parse_only : UnsupportedFlag<"Zs">, HelpText<"">;
diff --git a/contrib/libs/llvm12/tools/llvm-ml/llvm-ml.cpp b/contrib/libs/llvm12/tools/llvm-ml/llvm-ml.cpp
index 5c21d0bb40..1733dcd472 100644
--- a/contrib/libs/llvm12/tools/llvm-ml/llvm-ml.cpp
+++ b/contrib/libs/llvm12/tools/llvm-ml/llvm-ml.cpp
@@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCCodeEmitter.h"
@@ -25,17 +25,17 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCTargetOptionsCommandFlags.h"
-#include "llvm/Option/Arg.h"
-#include "llvm/Option/ArgList.h"
-#include "llvm/Option/Option.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/Option.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/FileUtilities.h"
-#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
@@ -43,55 +43,55 @@
#include "llvm/Support/WithColor.h"
using namespace llvm;
-using namespace llvm::opt;
+using namespace llvm::opt;
-namespace {
+namespace {
-enum ID {
- OPT_INVALID = 0, // This is not an option ID.
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR, VALUES) \
- OPT_##ID,
-#include "Opts.inc"
-#undef OPTION
+enum ID {
+ OPT_INVALID = 0, // This is not an option ID.
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ OPT_##ID,
+#include "Opts.inc"
+#undef OPTION
};
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
-#include "Opts.inc"
-#undef PREFIX
-
-static const opt::OptTable::Info InfoTable[] = {
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR, VALUES) \
- { \
- PREFIX, NAME, HELPTEXT, \
- METAVAR, OPT_##ID, opt::Option::KIND##Class, \
- PARAM, FLAGS, OPT_##GROUP, \
- OPT_##ALIAS, ALIASARGS, VALUES},
-#include "Opts.inc"
-#undef OPTION
+#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
+#include "Opts.inc"
+#undef PREFIX
+
+static const opt::OptTable::Info InfoTable[] = {
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ { \
+ PREFIX, NAME, HELPTEXT, \
+ METAVAR, OPT_##ID, opt::Option::KIND##Class, \
+ PARAM, FLAGS, OPT_##GROUP, \
+ OPT_##ALIAS, ALIASARGS, VALUES},
+#include "Opts.inc"
+#undef OPTION
};
-class MLOptTable : public opt::OptTable {
-public:
- MLOptTable() : OptTable(InfoTable, /*IgnoreCase=*/false) {}
+class MLOptTable : public opt::OptTable {
+public:
+ MLOptTable() : OptTable(InfoTable, /*IgnoreCase=*/false) {}
};
-} // namespace
+} // namespace
-static Triple GetTriple(StringRef ProgName, opt::InputArgList &Args) {
+static Triple GetTriple(StringRef ProgName, opt::InputArgList &Args) {
// Figure out the target triple.
- StringRef DefaultBitness = "32";
- SmallString<255> Program = ProgName;
- sys::path::replace_extension(Program, "");
- if (Program.endswith("ml64"))
- DefaultBitness = "64";
-
- StringRef TripleName =
- StringSwitch<StringRef>(Args.getLastArgValue(OPT_bitness, DefaultBitness))
- .Case("32", "i386-pc-windows")
- .Case("64", "x86_64-pc-windows")
- .Default("");
- return Triple(Triple::normalize(TripleName));
+ StringRef DefaultBitness = "32";
+ SmallString<255> Program = ProgName;
+ sys::path::replace_extension(Program, "");
+ if (Program.endswith("ml64"))
+ DefaultBitness = "64";
+
+ StringRef TripleName =
+ StringSwitch<StringRef>(Args.getLastArgValue(OPT_bitness, DefaultBitness))
+ .Case("32", "i386-pc-windows")
+ .Case("64", "x86_64-pc-windows")
+ .Default("");
+ return Triple(Triple::normalize(TripleName));
}
static std::unique_ptr<ToolOutputFile> GetOutputStream(StringRef Path) {
@@ -108,10 +108,10 @@ static std::unique_ptr<ToolOutputFile> GetOutputStream(StringRef Path) {
static int AsLexInput(SourceMgr &SrcMgr, MCAsmInfo &MAI, raw_ostream &OS) {
AsmLexer Lexer(MAI);
Lexer.setBuffer(SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer());
- Lexer.setLexMasmIntegers(true);
- Lexer.useMasmDefaultRadix(true);
- Lexer.setLexMasmHexFloats(true);
- Lexer.setLexMasmStrings(true);
+ Lexer.setLexMasmIntegers(true);
+ Lexer.useMasmDefaultRadix(true);
+ Lexer.setLexMasmHexFloats(true);
+ Lexer.setLexMasmStrings(true);
bool Error = false;
while (Lexer.Lex().isNot(AsmToken::Eof)) {
@@ -124,13 +124,13 @@ static int AsLexInput(SourceMgr &SrcMgr, MCAsmInfo &MAI, raw_ostream &OS) {
return Error;
}
-static int AssembleInput(StringRef ProgName, const Target *TheTarget,
+static int AssembleInput(StringRef ProgName, const Target *TheTarget,
SourceMgr &SrcMgr, MCContext &Ctx, MCStreamer &Str,
MCAsmInfo &MAI, MCSubtargetInfo &STI,
- MCInstrInfo &MCII, MCTargetOptions &MCOptions,
- const opt::ArgList &InputArgs) {
+ MCInstrInfo &MCII, MCTargetOptions &MCOptions,
+ const opt::ArgList &InputArgs) {
std::unique_ptr<MCAsmParser> Parser(
- createMCMasmParser(SrcMgr, Ctx, Str, MAI, 0));
+ createMCMasmParser(SrcMgr, Ctx, Str, MAI, 0));
std::unique_ptr<MCTargetAsmParser> TAP(
TheTarget->createMCAsmParser(STI, *Parser, MCII, MCOptions));
@@ -140,32 +140,32 @@ static int AssembleInput(StringRef ProgName, const Target *TheTarget,
return 1;
}
- Parser->setShowParsedOperands(InputArgs.hasArg(OPT_show_inst_operands));
+ Parser->setShowParsedOperands(InputArgs.hasArg(OPT_show_inst_operands));
Parser->setTargetParser(*TAP);
Parser->getLexer().setLexMasmIntegers(true);
- Parser->getLexer().useMasmDefaultRadix(true);
- Parser->getLexer().setLexMasmHexFloats(true);
- Parser->getLexer().setLexMasmStrings(true);
-
- auto Defines = InputArgs.getAllArgValues(OPT_define);
- for (StringRef Define : Defines) {
- const auto NameValue = Define.split('=');
- StringRef Name = NameValue.first, Value = NameValue.second;
- if (Parser->defineMacro(Name, Value)) {
- WithColor::error(errs(), ProgName)
- << "can't define macro '" << Name << "' = '" << Value << "'\n";
- return 1;
- }
- }
-
+ Parser->getLexer().useMasmDefaultRadix(true);
+ Parser->getLexer().setLexMasmHexFloats(true);
+ Parser->getLexer().setLexMasmStrings(true);
+
+ auto Defines = InputArgs.getAllArgValues(OPT_define);
+ for (StringRef Define : Defines) {
+ const auto NameValue = Define.split('=');
+ StringRef Name = NameValue.first, Value = NameValue.second;
+ if (Parser->defineMacro(Name, Value)) {
+ WithColor::error(errs(), ProgName)
+ << "can't define macro '" << Name << "' = '" << Value << "'\n";
+ return 1;
+ }
+ }
+
int Res = Parser->Run(/*NoInitialTextSection=*/true);
return Res;
}
-int main(int Argc, char **Argv) {
- InitLLVM X(Argc, Argv);
- StringRef ProgName = sys::path::filename(Argv[0]);
+int main(int Argc, char **Argv) {
+ InitLLVM X(Argc, Argv);
+ StringRef ProgName = sys::path::filename(Argv[0]);
// Initialize targets and assembly printers/parsers.
llvm::InitializeAllTargetInfos();
@@ -173,81 +173,81 @@ int main(int Argc, char **Argv) {
llvm::InitializeAllAsmParsers();
llvm::InitializeAllDisassemblers();
- MLOptTable T;
- unsigned MissingArgIndex, MissingArgCount;
- ArrayRef<const char *> ArgsArr = makeArrayRef(Argv + 1, Argc - 1);
- opt::InputArgList InputArgs =
- T.ParseArgs(ArgsArr, MissingArgIndex, MissingArgCount);
-
- std::string InputFilename;
- for (auto *Arg : InputArgs.filtered(OPT_INPUT)) {
- std::string ArgString = Arg->getAsString(InputArgs);
- if (ArgString == "-" || StringRef(ArgString).endswith(".asm")) {
- if (!InputFilename.empty()) {
- WithColor::warning(errs(), ProgName)
- << "does not support multiple assembly files in one command; "
- << "ignoring '" << InputFilename << "'\n";
- }
- InputFilename = ArgString;
- } else {
- std::string Diag;
- raw_string_ostream OS(Diag);
- OS << "invalid option '" << ArgString << "'";
-
- std::string Nearest;
- if (T.findNearest(ArgString, Nearest) < 2)
- OS << ", did you mean '" << Nearest << "'?";
-
- WithColor::error(errs(), ProgName) << OS.str() << '\n';
- exit(1);
- }
- }
- for (auto *Arg : InputArgs.filtered(OPT_assembly_file)) {
- if (!InputFilename.empty()) {
- WithColor::warning(errs(), ProgName)
- << "does not support multiple assembly files in one command; "
- << "ignoring '" << InputFilename << "'\n";
- }
- InputFilename = Arg->getAsString(InputArgs);
- }
-
- for (auto *Arg : InputArgs.filtered(OPT_unsupported_Group)) {
- WithColor::warning(errs(), ProgName)
- << "ignoring unsupported '" << Arg->getOption().getName()
- << "' option\n";
- }
-
- if (InputArgs.hasArg(OPT_help)) {
- std::string Usage = llvm::formatv("{0} [ /options ] file", ProgName).str();
- T.PrintHelp(outs(), Usage.c_str(), "LLVM MASM Assembler",
- /*ShowHidden=*/false);
- return 0;
- } else if (InputFilename.empty()) {
- outs() << "USAGE: " << ProgName << " [ /options ] file\n"
- << "Run \"" << ProgName << " /?\" or \"" << ProgName
- << " /help\" for more info.\n";
- return 0;
- }
-
- MCTargetOptions MCOptions;
+ MLOptTable T;
+ unsigned MissingArgIndex, MissingArgCount;
+ ArrayRef<const char *> ArgsArr = makeArrayRef(Argv + 1, Argc - 1);
+ opt::InputArgList InputArgs =
+ T.ParseArgs(ArgsArr, MissingArgIndex, MissingArgCount);
+
+ std::string InputFilename;
+ for (auto *Arg : InputArgs.filtered(OPT_INPUT)) {
+ std::string ArgString = Arg->getAsString(InputArgs);
+ if (ArgString == "-" || StringRef(ArgString).endswith(".asm")) {
+ if (!InputFilename.empty()) {
+ WithColor::warning(errs(), ProgName)
+ << "does not support multiple assembly files in one command; "
+ << "ignoring '" << InputFilename << "'\n";
+ }
+ InputFilename = ArgString;
+ } else {
+ std::string Diag;
+ raw_string_ostream OS(Diag);
+ OS << "invalid option '" << ArgString << "'";
+
+ std::string Nearest;
+ if (T.findNearest(ArgString, Nearest) < 2)
+ OS << ", did you mean '" << Nearest << "'?";
+
+ WithColor::error(errs(), ProgName) << OS.str() << '\n';
+ exit(1);
+ }
+ }
+ for (auto *Arg : InputArgs.filtered(OPT_assembly_file)) {
+ if (!InputFilename.empty()) {
+ WithColor::warning(errs(), ProgName)
+ << "does not support multiple assembly files in one command; "
+ << "ignoring '" << InputFilename << "'\n";
+ }
+ InputFilename = Arg->getAsString(InputArgs);
+ }
+
+ for (auto *Arg : InputArgs.filtered(OPT_unsupported_Group)) {
+ WithColor::warning(errs(), ProgName)
+ << "ignoring unsupported '" << Arg->getOption().getName()
+ << "' option\n";
+ }
+
+ if (InputArgs.hasArg(OPT_help)) {
+ std::string Usage = llvm::formatv("{0} [ /options ] file", ProgName).str();
+ T.PrintHelp(outs(), Usage.c_str(), "LLVM MASM Assembler",
+ /*ShowHidden=*/false);
+ return 0;
+ } else if (InputFilename.empty()) {
+ outs() << "USAGE: " << ProgName << " [ /options ] file\n"
+ << "Run \"" << ProgName << " /?\" or \"" << ProgName
+ << " /help\" for more info.\n";
+ return 0;
+ }
+
+ MCTargetOptions MCOptions;
MCOptions.AssemblyLanguage = "masm";
- Triple TheTriple = GetTriple(ProgName, InputArgs);
- std::string Error;
- const Target *TheTarget = TargetRegistry::lookupTarget("", TheTriple, Error);
- if (!TheTarget) {
- WithColor::error(errs(), ProgName) << Error;
+ Triple TheTriple = GetTriple(ProgName, InputArgs);
+ std::string Error;
+ const Target *TheTarget = TargetRegistry::lookupTarget("", TheTriple, Error);
+ if (!TheTarget) {
+ WithColor::error(errs(), ProgName) << Error;
return 1;
- }
- const std::string &TripleName = TheTriple.getTriple();
-
- bool SafeSEH = InputArgs.hasArg(OPT_safeseh);
- if (SafeSEH && !(TheTriple.isArch32Bit() && TheTriple.isX86())) {
- WithColor::warning()
- << "/safeseh applies only to 32-bit X86 platforms; ignoring.\n";
- SafeSEH = false;
- }
-
+ }
+ const std::string &TripleName = TheTriple.getTriple();
+
+ bool SafeSEH = InputArgs.hasArg(OPT_safeseh);
+ if (SafeSEH && !(TheTriple.isArch32Bit() && TheTriple.isX86())) {
+ WithColor::warning()
+ << "/safeseh applies only to 32-bit X86 platforms; ignoring.\n";
+ SafeSEH = false;
+ }
+
ErrorOr<std::unique_ptr<MemoryBuffer>> BufferPtr =
MemoryBuffer::getFileOrSTDIN(InputFilename);
if (std::error_code EC = BufferPtr.getError()) {
@@ -263,7 +263,7 @@ int main(int Argc, char **Argv) {
// Record the location of the include directories so that the lexer can find
// it later.
- SrcMgr.setIncludeDirs(InputArgs.getAllArgValues(OPT_include_path));
+ SrcMgr.setIncludeDirs(InputArgs.getAllArgValues(OPT_include_path));
std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
assert(MRI && "Unable to create target register info!");
@@ -272,7 +272,7 @@ int main(int Argc, char **Argv) {
TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
assert(MAI && "Unable to create target asm info!");
- MAI->setPreserveAsmComments(InputArgs.hasArg(OPT_preserve_comments));
+ MAI->setPreserveAsmComments(InputArgs.hasArg(OPT_preserve_comments));
// FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
// MCObjectFileInfo needs a MCContext reference in order to initialize itself.
@@ -281,25 +281,25 @@ int main(int Argc, char **Argv) {
MOFI.InitMCObjectFileInfo(TheTriple, /*PIC=*/false, Ctx,
/*LargeCodeModel=*/true);
- if (InputArgs.hasArg(OPT_save_temp_labels))
+ if (InputArgs.hasArg(OPT_save_temp_labels))
Ctx.setAllowTemporaryLabels(false);
- // Set compilation information.
- SmallString<128> CWD;
- if (!sys::fs::current_path(CWD))
- Ctx.setCompilationDir(CWD);
- Ctx.setMainFileName(InputFilename);
-
- StringRef FileType = InputArgs.getLastArgValue(OPT_filetype, "obj");
- SmallString<255> DefaultOutputFilename;
- if (InputArgs.hasArg(OPT_as_lex)) {
- DefaultOutputFilename = "-";
+ // Set compilation information.
+ SmallString<128> CWD;
+ if (!sys::fs::current_path(CWD))
+ Ctx.setCompilationDir(CWD);
+ Ctx.setMainFileName(InputFilename);
+
+ StringRef FileType = InputArgs.getLastArgValue(OPT_filetype, "obj");
+ SmallString<255> DefaultOutputFilename;
+ if (InputArgs.hasArg(OPT_as_lex)) {
+ DefaultOutputFilename = "-";
} else {
- DefaultOutputFilename = InputFilename;
- sys::path::replace_extension(DefaultOutputFilename, FileType);
+ DefaultOutputFilename = InputFilename;
+ sys::path::replace_extension(DefaultOutputFilename, FileType);
}
- const StringRef OutputFilename =
- InputArgs.getLastArgValue(OPT_output_file, DefaultOutputFilename);
+ const StringRef OutputFilename =
+ InputArgs.getLastArgValue(OPT_output_file, DefaultOutputFilename);
std::unique_ptr<ToolOutputFile> Out = GetOutputStream(OutputFilename);
if (!Out)
return 1;
@@ -309,19 +309,19 @@ int main(int Argc, char **Argv) {
std::unique_ptr<MCStreamer> Str;
std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
- assert(MCII && "Unable to create instruction info!");
-
+ assert(MCII && "Unable to create instruction info!");
+
std::unique_ptr<MCSubtargetInfo> STI(TheTarget->createMCSubtargetInfo(
TripleName, /*CPU=*/"", /*Features=*/""));
- assert(STI && "Unable to create subtarget info!");
+ assert(STI && "Unable to create subtarget info!");
MCInstPrinter *IP = nullptr;
- if (FileType == "s") {
- const bool OutputATTAsm = InputArgs.hasArg(OPT_output_att_asm);
+ if (FileType == "s") {
+ const bool OutputATTAsm = InputArgs.hasArg(OPT_output_att_asm);
const unsigned OutputAsmVariant = OutputATTAsm ? 0U // ATT dialect
: 1U; // Intel dialect
- IP = TheTarget->createMCInstPrinter(TheTriple, OutputAsmVariant, *MAI,
- *MCII, *MRI);
+ IP = TheTarget->createMCInstPrinter(TheTriple, OutputAsmVariant, *MAI,
+ *MCII, *MRI);
if (!IP) {
WithColor::error()
@@ -332,24 +332,24 @@ int main(int Argc, char **Argv) {
}
// Set the display preference for hex vs. decimal immediates.
- IP->setPrintImmHex(InputArgs.hasArg(OPT_print_imm_hex));
+ IP->setPrintImmHex(InputArgs.hasArg(OPT_print_imm_hex));
// Set up the AsmStreamer.
std::unique_ptr<MCCodeEmitter> CE;
- if (InputArgs.hasArg(OPT_show_encoding))
+ if (InputArgs.hasArg(OPT_show_encoding))
CE.reset(TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx));
std::unique_ptr<MCAsmBackend> MAB(
TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions));
auto FOut = std::make_unique<formatted_raw_ostream>(*OS);
- Str.reset(TheTarget->createAsmStreamer(
- Ctx, std::move(FOut), /*asmverbose*/ true,
- /*useDwarfDirectory*/ true, IP, std::move(CE), std::move(MAB),
- InputArgs.hasArg(OPT_show_inst)));
+ Str.reset(TheTarget->createAsmStreamer(
+ Ctx, std::move(FOut), /*asmverbose*/ true,
+ /*useDwarfDirectory*/ true, IP, std::move(CE), std::move(MAB),
+ InputArgs.hasArg(OPT_show_inst)));
- } else if (FileType == "null") {
+ } else if (FileType == "null") {
Str.reset(TheTarget->createNullStreamer(Ctx));
- } else if (FileType == "obj") {
+ } else if (FileType == "obj") {
if (!Out->os().supportsSeeking()) {
BOS = std::make_unique<buffer_ostream>(Out->os());
OS = BOS.get();
@@ -362,37 +362,37 @@ int main(int Argc, char **Argv) {
MAB->createObjectWriter(*OS), std::unique_ptr<MCCodeEmitter>(CE), *STI,
MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible,
/*DWARFMustBeAtTheEnd*/ false));
- } else {
- llvm_unreachable("Invalid file type!");
+ } else {
+ llvm_unreachable("Invalid file type!");
+ }
+
+ if (TheTriple.isOSBinFormatCOFF()) {
+ // Emit an absolute @feat.00 symbol. This is a features bitfield read by
+ // link.exe.
+ int64_t Feat00Flags = 0x2;
+ if (SafeSEH) {
+ // According to the PE-COFF spec, the LSB of this value marks the object
+ // for "registered SEH". This means that all SEH handler entry points
+ // must be registered in .sxdata. Use of any unregistered handlers will
+ // cause the process to terminate immediately.
+ Feat00Flags |= 0x1;
+ }
+ MCSymbol *Feat00Sym = Ctx.getOrCreateSymbol("@feat.00");
+ Feat00Sym->setRedefinable(true);
+ Str->emitSymbolAttribute(Feat00Sym, MCSA_Global);
+ Str->emitAssignment(Feat00Sym, MCConstantExpr::create(Feat00Flags, Ctx));
}
- if (TheTriple.isOSBinFormatCOFF()) {
- // Emit an absolute @feat.00 symbol. This is a features bitfield read by
- // link.exe.
- int64_t Feat00Flags = 0x2;
- if (SafeSEH) {
- // According to the PE-COFF spec, the LSB of this value marks the object
- // for "registered SEH". This means that all SEH handler entry points
- // must be registered in .sxdata. Use of any unregistered handlers will
- // cause the process to terminate immediately.
- Feat00Flags |= 0x1;
- }
- MCSymbol *Feat00Sym = Ctx.getOrCreateSymbol("@feat.00");
- Feat00Sym->setRedefinable(true);
- Str->emitSymbolAttribute(Feat00Sym, MCSA_Global);
- Str->emitAssignment(Feat00Sym, MCConstantExpr::create(Feat00Flags, Ctx));
- }
-
// Use Assembler information for parsing.
Str->setUseAssemblerInfoForParsing(true);
int Res = 1;
- if (InputArgs.hasArg(OPT_as_lex)) {
- // -as-lex; Lex only, and output a stream of tokens
+ if (InputArgs.hasArg(OPT_as_lex)) {
+ // -as-lex; Lex only, and output a stream of tokens
Res = AsLexInput(SrcMgr, *MAI, Out->os());
- } else {
+ } else {
Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI,
- *MCII, MCOptions, InputArgs);
+ *MCII, MCOptions, InputArgs);
}
// Keep output if no errors.
diff --git a/contrib/libs/llvm12/tools/llvm-ml/ya.make b/contrib/libs/llvm12/tools/llvm-ml/ya.make
index 7816f1d57b..5371cfd851 100644
--- a/contrib/libs/llvm12/tools/llvm-ml/ya.make
+++ b/contrib/libs/llvm12/tools/llvm-ml/ya.make
@@ -12,44 +12,44 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/Demangle
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/MC/MCDisassembler
- contrib/libs/llvm12/lib/MC/MCParser
- contrib/libs/llvm12/lib/Option
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/Target/AArch64/AsmParser
- contrib/libs/llvm12/lib/Target/AArch64/Disassembler
- contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc
- contrib/libs/llvm12/lib/Target/AArch64/TargetInfo
- contrib/libs/llvm12/lib/Target/AArch64/Utils
- contrib/libs/llvm12/lib/Target/ARM/AsmParser
- contrib/libs/llvm12/lib/Target/ARM/Disassembler
- contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc
- contrib/libs/llvm12/lib/Target/ARM/TargetInfo
- contrib/libs/llvm12/lib/Target/ARM/Utils
- contrib/libs/llvm12/lib/Target/BPF/AsmParser
- contrib/libs/llvm12/lib/Target/BPF/Disassembler
- contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc
- contrib/libs/llvm12/lib/Target/BPF/TargetInfo
- contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc
- contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo
- contrib/libs/llvm12/lib/Target/PowerPC/AsmParser
- contrib/libs/llvm12/lib/Target/PowerPC/Disassembler
- contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc
- contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo
- contrib/libs/llvm12/lib/Target/X86/AsmParser
- contrib/libs/llvm12/lib/Target/X86/Disassembler
- contrib/libs/llvm12/lib/Target/X86/MCTargetDesc
- contrib/libs/llvm12/lib/Target/X86/TargetInfo
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/Demangle
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/MC/MCDisassembler
+ contrib/libs/llvm12/lib/MC/MCParser
+ contrib/libs/llvm12/lib/Option
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/Target/AArch64/AsmParser
+ contrib/libs/llvm12/lib/Target/AArch64/Disassembler
+ contrib/libs/llvm12/lib/Target/AArch64/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/AArch64/TargetInfo
+ contrib/libs/llvm12/lib/Target/AArch64/Utils
+ contrib/libs/llvm12/lib/Target/ARM/AsmParser
+ contrib/libs/llvm12/lib/Target/ARM/Disassembler
+ contrib/libs/llvm12/lib/Target/ARM/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/ARM/TargetInfo
+ contrib/libs/llvm12/lib/Target/ARM/Utils
+ contrib/libs/llvm12/lib/Target/BPF/AsmParser
+ contrib/libs/llvm12/lib/Target/BPF/Disassembler
+ contrib/libs/llvm12/lib/Target/BPF/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/BPF/TargetInfo
+ contrib/libs/llvm12/lib/Target/NVPTX/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/NVPTX/TargetInfo
+ contrib/libs/llvm12/lib/Target/PowerPC/AsmParser
+ contrib/libs/llvm12/lib/Target/PowerPC/Disassembler
+ contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo
+ contrib/libs/llvm12/lib/Target/X86/AsmParser
+ contrib/libs/llvm12/lib/Target/X86/Disassembler
+ contrib/libs/llvm12/lib/Target/X86/MCTargetDesc
+ contrib/libs/llvm12/lib/Target/X86/TargetInfo
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-ml
- contrib/libs/llvm12/tools/llvm-ml
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-ml
+ contrib/libs/llvm12/tools/llvm-ml
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/tools/llvm-mt/llvm-mt.cpp b/contrib/libs/llvm12/tools/llvm-mt/llvm-mt.cpp
index 64029c96fc..997e5acbe2 100644
--- a/contrib/libs/llvm12/tools/llvm-mt/llvm-mt.cpp
+++ b/contrib/libs/llvm12/tools/llvm-mt/llvm-mt.cpp
@@ -64,7 +64,7 @@ public:
};
} // namespace
-LLVM_ATTRIBUTE_NORETURN static void reportError(Twine Msg) {
+LLVM_ATTRIBUTE_NORETURN static void reportError(Twine Msg) {
WithColor::error(errs(), "llvm-mt") << Msg << '\n';
exit(1);
}
@@ -73,7 +73,7 @@ static void reportError(StringRef Input, std::error_code EC) {
reportError(Twine(Input) + ": " + EC.message());
}
-static void error(Error EC) {
+static void error(Error EC) {
if (EC)
handleAllErrors(std::move(EC), [&](const ErrorInfoBase &EI) {
reportError(EI.message());
diff --git a/contrib/libs/llvm12/tools/llvm-mt/ya.make b/contrib/libs/llvm12/tools/llvm-mt/ya.make
index 6a57401b55..83a363a067 100644
--- a/contrib/libs/llvm12/tools/llvm-mt/ya.make
+++ b/contrib/libs/llvm12/tools/llvm-mt/ya.make
@@ -12,17 +12,17 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Demangle
- contrib/libs/llvm12/lib/Option
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/WindowsManifest
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Demangle
+ contrib/libs/llvm12/lib/Option
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/WindowsManifest
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-mt
- contrib/libs/llvm12/tools/llvm-mt
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-mt
+ contrib/libs/llvm12/tools/llvm-mt
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/BitcodeStripOpts.td b/contrib/libs/llvm12/tools/llvm-objcopy/BitcodeStripOpts.td
index 5abaa3b2ce..cc178164b0 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/BitcodeStripOpts.td
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/BitcodeStripOpts.td
@@ -1,24 +1,24 @@
-//===-- BitcodeStripOpts.td - llvm-bitcode-strip options ---------------*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file describes the command line options of llvm-bitcode-strip.
-//
-//===----------------------------------------------------------------------===//
-
-include "llvm/Option/OptParser.td"
-
-def help : Flag<["--"], "help">;
-
-def h : Flag<["-"], "h">, Alias<help>;
-
-def version : Flag<["--"], "version">,
- HelpText<"Print the version and exit.">;
-
-def V : Flag<["-"], "V">,
- Alias<version>,
- HelpText<"Alias for --version">;
+//===-- BitcodeStripOpts.td - llvm-bitcode-strip options ---------------*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the command line options of llvm-bitcode-strip.
+//
+//===----------------------------------------------------------------------===//
+
+include "llvm/Option/OptParser.td"
+
+def help : Flag<["--"], "help">;
+
+def h : Flag<["-"], "h">, Alias<help>;
+
+def version : Flag<["--"], "version">,
+ HelpText<"Print the version and exit.">;
+
+def V : Flag<["-"], "V">,
+ Alias<version>,
+ HelpText<"Alias for --version">;
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
index cb2d66df74..b5de8a45a8 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
@@ -39,12 +39,12 @@ static uint64_t getNextRVA(const Object &Obj) {
Obj.IsPE ? Obj.PeHeader.SectionAlignment : 1);
}
-static Expected<std::vector<uint8_t>>
-createGnuDebugLinkSectionContents(StringRef File) {
+static Expected<std::vector<uint8_t>>
+createGnuDebugLinkSectionContents(StringRef File) {
ErrorOr<std::unique_ptr<MemoryBuffer>> LinkTargetOrErr =
MemoryBuffer::getFile(File);
if (!LinkTargetOrErr)
- return createFileError(File, LinkTargetOrErr.getError());
+ return createFileError(File, LinkTargetOrErr.getError());
auto LinkTarget = std::move(*LinkTargetOrErr);
uint32_t CRC32 = llvm::crc32(arrayRefFromStringRef(LinkTarget->getBuffer()));
@@ -81,17 +81,17 @@ static void addSection(Object &Obj, StringRef Name, ArrayRef<uint8_t> Contents,
Obj.addSections(Sec);
}
-static Error addGnuDebugLink(Object &Obj, StringRef DebugLinkFile) {
- Expected<std::vector<uint8_t>> Contents =
+static Error addGnuDebugLink(Object &Obj, StringRef DebugLinkFile) {
+ Expected<std::vector<uint8_t>> Contents =
createGnuDebugLinkSectionContents(DebugLinkFile);
- if (!Contents)
- return Contents.takeError();
-
- addSection(Obj, ".gnu_debuglink", *Contents,
+ if (!Contents)
+ return Contents.takeError();
+
+ addSection(Obj, ".gnu_debuglink", *Contents,
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
IMAGE_SCN_MEM_DISCARDABLE);
-
- return Error::success();
+
+ return Error::success();
}
static void setSectionFlags(Section &Sec, SectionFlag AllFlags) {
@@ -179,7 +179,7 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
Sym.Name = I->getValue();
}
- auto ToRemove = [&](const Symbol &Sym) -> Expected<bool> {
+ auto ToRemove = [&](const Symbol &Sym) -> Expected<bool> {
// For StripAll, all relocations have been stripped and we remove all
// symbols.
if (Config.StripAll || Config.StripAllGNU)
@@ -188,10 +188,10 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
if (Config.SymbolsToRemove.matches(Sym.Name)) {
// Explicitly removing a referenced symbol is an error.
if (Sym.Referenced)
- return createStringError(
- llvm::errc::invalid_argument,
- "'" + Config.OutputFilename + "': not stripping symbol '" +
- Sym.Name.str() + "' because it is named in a relocation");
+ return createStringError(
+ llvm::errc::invalid_argument,
+ "'" + Config.OutputFilename + "': not stripping symbol '" +
+ Sym.Name.str() + "' because it is named in a relocation");
return true;
}
@@ -216,12 +216,12 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
}
return false;
- };
+ };
+
+ // Actually do removals of symbols.
+ if (Error Err = Obj.removeSymbols(ToRemove))
+ return Err;
- // Actually do removals of symbols.
- if (Error Err = Obj.removeSymbols(ToRemove))
- return Err;
-
if (!Config.SetSectionFlags.empty())
for (Section &Sec : Obj.getMutableSections()) {
const auto It = Config.SetSectionFlags.find(Sec.Name);
@@ -246,8 +246,8 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
}
if (!Config.AddGnuDebugLink.empty())
- if (Error E = addGnuDebugLink(Obj, Config.AddGnuDebugLink))
- return E;
+ if (Error E = addGnuDebugLink(Obj, Config.AddGnuDebugLink))
+ return E;
if (Config.AllowBrokenLinks || !Config.BuildIdLinkDir.empty() ||
Config.BuildIdLinkInput || Config.BuildIdLinkOutput ||
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.cpp b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.cpp
index 166ddce160..1c17b8408e 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.cpp
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.cpp
@@ -31,23 +31,23 @@ void Object::updateSymbols() {
}
const Symbol *Object::findSymbol(size_t UniqueId) const {
- return SymbolMap.lookup(UniqueId);
+ return SymbolMap.lookup(UniqueId);
}
-Error Object::removeSymbols(
- function_ref<Expected<bool>(const Symbol &)> ToRemove) {
- Error Errs = Error::success();
- llvm::erase_if(Symbols, [ToRemove, &Errs](const Symbol &Sym) {
- Expected<bool> ShouldRemove = ToRemove(Sym);
- if (!ShouldRemove) {
- Errs = joinErrors(std::move(Errs), ShouldRemove.takeError());
- return false;
- }
- return *ShouldRemove;
- });
-
+Error Object::removeSymbols(
+ function_ref<Expected<bool>(const Symbol &)> ToRemove) {
+ Error Errs = Error::success();
+ llvm::erase_if(Symbols, [ToRemove, &Errs](const Symbol &Sym) {
+ Expected<bool> ShouldRemove = ToRemove(Sym);
+ if (!ShouldRemove) {
+ Errs = joinErrors(std::move(Errs), ShouldRemove.takeError());
+ return false;
+ }
+ return *ShouldRemove;
+ });
+
updateSymbols();
- return Errs;
+ return Errs;
}
Error Object::markSymbols() {
@@ -83,34 +83,34 @@ void Object::updateSections() {
}
const Section *Object::findSection(ssize_t UniqueId) const {
- return SectionMap.lookup(UniqueId);
+ return SectionMap.lookup(UniqueId);
}
void Object::removeSections(function_ref<bool(const Section &)> ToRemove) {
DenseSet<ssize_t> AssociatedSections;
auto RemoveAssociated = [&AssociatedSections](const Section &Sec) {
- return AssociatedSections.contains(Sec.UniqueId);
+ return AssociatedSections.contains(Sec.UniqueId);
};
do {
DenseSet<ssize_t> RemovedSections;
- llvm::erase_if(Sections, [ToRemove, &RemovedSections](const Section &Sec) {
- bool Remove = ToRemove(Sec);
- if (Remove)
- RemovedSections.insert(Sec.UniqueId);
- return Remove;
- });
+ llvm::erase_if(Sections, [ToRemove, &RemovedSections](const Section &Sec) {
+ bool Remove = ToRemove(Sec);
+ if (Remove)
+ RemovedSections.insert(Sec.UniqueId);
+ return Remove;
+ });
// Remove all symbols referring to the removed sections.
AssociatedSections.clear();
- llvm::erase_if(
- Symbols, [&RemovedSections, &AssociatedSections](const Symbol &Sym) {
- // If there are sections that are associative to a removed
- // section,
- // remove those as well as nothing will include them (and we can't
- // leave them dangling).
- if (RemovedSections.count(Sym.AssociativeComdatTargetSectionId) == 1)
- AssociatedSections.insert(Sym.TargetSectionId);
- return RemovedSections.contains(Sym.TargetSectionId);
- });
+ llvm::erase_if(
+ Symbols, [&RemovedSections, &AssociatedSections](const Symbol &Sym) {
+ // If there are sections that are associative to a removed
+ // section,
+ // remove those as well as nothing will include them (and we can't
+ // leave them dangling).
+ if (RemovedSections.count(Sym.AssociativeComdatTargetSectionId) == 1)
+ AssociatedSections.insert(Sym.TargetSectionId);
+ return RemovedSections.contains(Sym.TargetSectionId);
+ });
ToRemove = RemoveAssociated;
} while (!AssociatedSections.empty());
updateSections();
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.h b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.h
index 77d8467c61..0e854b58cb 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.h
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.h
@@ -26,7 +26,7 @@ namespace coff {
struct Relocation {
Relocation() = default;
- Relocation(const object::coff_relocation &R) : Reloc(R) {}
+ Relocation(const object::coff_relocation &R) : Reloc(R) {}
object::coff_relocation Reloc;
size_t Target = 0;
@@ -116,7 +116,7 @@ struct Object {
const Symbol *findSymbol(size_t UniqueId) const;
void addSymbols(ArrayRef<Symbol> NewSymbols);
- Error removeSymbols(function_ref<Expected<bool>(const Symbol &)> ToRemove);
+ Error removeSymbols(function_ref<Expected<bool>(const Symbol &)> ToRemove);
// Set the Referenced field on all Symbols, based on relocations in
// all sections.
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/CopyConfig.cpp b/contrib/libs/llvm12/tools/llvm-objcopy/CopyConfig.cpp
index c589508201..ba74759a34 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/CopyConfig.cpp
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/CopyConfig.cpp
@@ -101,43 +101,43 @@ public:
InstallNameToolOptTable() : OptTable(InstallNameToolInfoTable) {}
};
-enum BitcodeStripID {
- BITCODE_STRIP_INVALID = 0, // This is not an option ID.
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR, VALUES) \
- BITCODE_STRIP_##ID,
-#include "BitcodeStripOpts.inc"
-#undef OPTION
-};
-
-#define PREFIX(NAME, VALUE) const char *const BITCODE_STRIP_##NAME[] = VALUE;
-#include "BitcodeStripOpts.inc"
-#undef PREFIX
-
-static const opt::OptTable::Info BitcodeStripInfoTable[] = {
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR, VALUES) \
- {BITCODE_STRIP_##PREFIX, \
- NAME, \
- HELPTEXT, \
- METAVAR, \
- BITCODE_STRIP_##ID, \
- opt::Option::KIND##Class, \
- PARAM, \
- FLAGS, \
- BITCODE_STRIP_##GROUP, \
- BITCODE_STRIP_##ALIAS, \
- ALIASARGS, \
- VALUES},
-#include "BitcodeStripOpts.inc"
-#undef OPTION
-};
-
-class BitcodeStripOptTable : public opt::OptTable {
-public:
- BitcodeStripOptTable() : OptTable(BitcodeStripInfoTable) {}
-};
-
+enum BitcodeStripID {
+ BITCODE_STRIP_INVALID = 0, // This is not an option ID.
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ BITCODE_STRIP_##ID,
+#include "BitcodeStripOpts.inc"
+#undef OPTION
+};
+
+#define PREFIX(NAME, VALUE) const char *const BITCODE_STRIP_##NAME[] = VALUE;
+#include "BitcodeStripOpts.inc"
+#undef PREFIX
+
+static const opt::OptTable::Info BitcodeStripInfoTable[] = {
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ {BITCODE_STRIP_##PREFIX, \
+ NAME, \
+ HELPTEXT, \
+ METAVAR, \
+ BITCODE_STRIP_##ID, \
+ opt::Option::KIND##Class, \
+ PARAM, \
+ FLAGS, \
+ BITCODE_STRIP_##GROUP, \
+ BITCODE_STRIP_##ALIAS, \
+ ALIASARGS, \
+ VALUES},
+#include "BitcodeStripOpts.inc"
+#undef OPTION
+};
+
+class BitcodeStripOptTable : public opt::OptTable {
+public:
+ BitcodeStripOptTable() : OptTable(BitcodeStripInfoTable) {}
+};
+
enum StripID {
STRIP_INVALID = 0, // This is not an option ID.
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
@@ -432,7 +432,7 @@ template <class T> static ErrorOr<T> getAsInteger(StringRef Val) {
namespace {
-enum class ToolType { Objcopy, Strip, InstallNameTool, BitcodeStrip };
+enum class ToolType { Objcopy, Strip, InstallNameTool, BitcodeStrip };
} // anonymous namespace
@@ -452,10 +452,10 @@ static void printHelp(const opt::OptTable &OptTable, raw_ostream &OS,
ToolName = "llvm-install-name-tool";
HelpText = " [options] input";
break;
- case ToolType::BitcodeStrip:
- ToolName = "llvm-bitcode-strip";
- HelpText = " [options] input";
- break;
+ case ToolType::BitcodeStrip:
+ ToolName = "llvm-bitcode-strip";
+ HelpText = " [options] input";
+ break;
}
OptTable.PrintHelp(OS, (ToolName + HelpText).str().c_str(),
(ToolName + " tool").str().c_str());
@@ -895,9 +895,9 @@ parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr) {
for (auto Arg : InputArgs.filtered(INSTALL_NAME_TOOL_add_rpath))
Config.RPathToAdd.push_back(Arg->getValue());
- for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_prepend_rpath))
- Config.RPathToPrepend.push_back(Arg->getValue());
-
+ for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_prepend_rpath))
+ Config.RPathToPrepend.push_back(Arg->getValue());
+
for (auto Arg : InputArgs.filtered(INSTALL_NAME_TOOL_delete_rpath)) {
StringRef RPath = Arg->getValue();
@@ -905,13 +905,13 @@ parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr) {
if (is_contained(Config.RPathToAdd, RPath))
return createStringError(
errc::invalid_argument,
- "cannot specify both -add_rpath '%s' and -delete_rpath '%s'",
+ "cannot specify both -add_rpath '%s' and -delete_rpath '%s'",
+ RPath.str().c_str(), RPath.str().c_str());
+ if (is_contained(Config.RPathToPrepend, RPath))
+ return createStringError(
+ errc::invalid_argument,
+ "cannot specify both -prepend_rpath '%s' and -delete_rpath '%s'",
RPath.str().c_str(), RPath.str().c_str());
- if (is_contained(Config.RPathToPrepend, RPath))
- return createStringError(
- errc::invalid_argument,
- "cannot specify both -prepend_rpath '%s' and -delete_rpath '%s'",
- RPath.str().c_str(), RPath.str().c_str());
Config.RPathsToRemove.insert(RPath);
}
@@ -930,47 +930,47 @@ parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr) {
});
if (It1 != Config.RPathsToUpdate.end())
return createStringError(errc::invalid_argument,
- "cannot specify both -rpath '" +
- It1->getFirst() + "' '" + It1->getSecond() +
- "' and -rpath '" + Old + "' '" + New + "'");
+ "cannot specify both -rpath '" +
+ It1->getFirst() + "' '" + It1->getSecond() +
+ "' and -rpath '" + Old + "' '" + New + "'");
// Cannot specify the same rpath under both -delete_rpath and -rpath
auto It2 = find_if(Config.RPathsToRemove, Match);
if (It2 != Config.RPathsToRemove.end())
return createStringError(errc::invalid_argument,
- "cannot specify both -delete_rpath '" + *It2 +
- "' and -rpath '" + Old + "' '" + New + "'");
+ "cannot specify both -delete_rpath '" + *It2 +
+ "' and -rpath '" + Old + "' '" + New + "'");
// Cannot specify the same rpath under both -add_rpath and -rpath
auto It3 = find_if(Config.RPathToAdd, Match);
if (It3 != Config.RPathToAdd.end())
return createStringError(errc::invalid_argument,
- "cannot specify both -add_rpath '" + *It3 +
- "' and -rpath '" + Old + "' '" + New + "'");
-
- // Cannot specify the same rpath under both -prepend_rpath and -rpath.
- auto It4 = find_if(Config.RPathToPrepend, Match);
- if (It4 != Config.RPathToPrepend.end())
- return createStringError(errc::invalid_argument,
- "cannot specify both -prepend_rpath '" + *It4 +
- "' and -rpath '" + Old + "' '" + New + "'");
-
+ "cannot specify both -add_rpath '" + *It3 +
+ "' and -rpath '" + Old + "' '" + New + "'");
+
+ // Cannot specify the same rpath under both -prepend_rpath and -rpath.
+ auto It4 = find_if(Config.RPathToPrepend, Match);
+ if (It4 != Config.RPathToPrepend.end())
+ return createStringError(errc::invalid_argument,
+ "cannot specify both -prepend_rpath '" + *It4 +
+ "' and -rpath '" + Old + "' '" + New + "'");
+
Config.RPathsToUpdate.insert({Old, New});
}
- if (auto *Arg = InputArgs.getLastArg(INSTALL_NAME_TOOL_id)) {
+ if (auto *Arg = InputArgs.getLastArg(INSTALL_NAME_TOOL_id)) {
Config.SharedLibId = Arg->getValue();
- if (Config.SharedLibId->empty())
- return createStringError(errc::invalid_argument,
- "cannot specify an empty id");
- }
+ if (Config.SharedLibId->empty())
+ return createStringError(errc::invalid_argument,
+ "cannot specify an empty id");
+ }
- for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_change))
+ for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_change))
Config.InstallNamesToUpdate.insert({Arg->getValue(0), Arg->getValue(1)});
- Config.RemoveAllRpaths =
- InputArgs.hasArg(INSTALL_NAME_TOOL_delete_all_rpaths);
-
+ Config.RemoveAllRpaths =
+ InputArgs.hasArg(INSTALL_NAME_TOOL_delete_all_rpaths);
+
SmallVector<StringRef, 2> Positional;
for (auto Arg : InputArgs.filtered(INSTALL_NAME_TOOL_UNKNOWN))
return createStringError(errc::invalid_argument, "unknown argument '%s'",
@@ -990,50 +990,50 @@ parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr) {
return std::move(DC);
}
-Expected<DriverConfig>
-parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr) {
- DriverConfig DC;
- CopyConfig Config;
- BitcodeStripOptTable T;
- unsigned MissingArgumentIndex, MissingArgumentCount;
- opt::InputArgList InputArgs =
- T.ParseArgs(ArgsArr, MissingArgumentIndex, MissingArgumentCount);
-
- if (InputArgs.size() == 0) {
- printHelp(T, errs(), ToolType::BitcodeStrip);
- exit(1);
- }
-
- if (InputArgs.hasArg(BITCODE_STRIP_help)) {
- printHelp(T, outs(), ToolType::BitcodeStrip);
- exit(0);
- }
-
- if (InputArgs.hasArg(BITCODE_STRIP_version)) {
- outs() << "llvm-bitcode-strip, compatible with cctools "
- "bitcode_strip\n";
- cl::PrintVersionMessage();
- exit(0);
- }
-
- for (auto *Arg : InputArgs.filtered(BITCODE_STRIP_UNKNOWN))
- return createStringError(errc::invalid_argument, "unknown argument '%s'",
- Arg->getAsString(InputArgs).c_str());
-
- SmallVector<StringRef, 2> Positional;
- for (auto *Arg : InputArgs.filtered(BITCODE_STRIP_INPUT))
- Positional.push_back(Arg->getValue());
- if (Positional.size() > 1)
- return createStringError(errc::invalid_argument,
- "llvm-bitcode-strip expects a single input file");
- assert(!Positional.empty());
- Config.InputFilename = Positional[0];
- Config.OutputFilename = Positional[0];
-
- DC.CopyConfigs.push_back(std::move(Config));
- return std::move(DC);
-}
-
+Expected<DriverConfig>
+parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr) {
+ DriverConfig DC;
+ CopyConfig Config;
+ BitcodeStripOptTable T;
+ unsigned MissingArgumentIndex, MissingArgumentCount;
+ opt::InputArgList InputArgs =
+ T.ParseArgs(ArgsArr, MissingArgumentIndex, MissingArgumentCount);
+
+ if (InputArgs.size() == 0) {
+ printHelp(T, errs(), ToolType::BitcodeStrip);
+ exit(1);
+ }
+
+ if (InputArgs.hasArg(BITCODE_STRIP_help)) {
+ printHelp(T, outs(), ToolType::BitcodeStrip);
+ exit(0);
+ }
+
+ if (InputArgs.hasArg(BITCODE_STRIP_version)) {
+ outs() << "llvm-bitcode-strip, compatible with cctools "
+ "bitcode_strip\n";
+ cl::PrintVersionMessage();
+ exit(0);
+ }
+
+ for (auto *Arg : InputArgs.filtered(BITCODE_STRIP_UNKNOWN))
+ return createStringError(errc::invalid_argument, "unknown argument '%s'",
+ Arg->getAsString(InputArgs).c_str());
+
+ SmallVector<StringRef, 2> Positional;
+ for (auto *Arg : InputArgs.filtered(BITCODE_STRIP_INPUT))
+ Positional.push_back(Arg->getValue());
+ if (Positional.size() > 1)
+ return createStringError(errc::invalid_argument,
+ "llvm-bitcode-strip expects a single input file");
+ assert(!Positional.empty());
+ Config.InputFilename = Positional[0];
+ Config.OutputFilename = Positional[0];
+
+ DC.CopyConfigs.push_back(std::move(Config));
+ return std::move(DC);
+}
+
// ParseStripOptions returns the config and sets the input arguments. If a
// help flag is set then ParseStripOptions will print the help messege and
// exit.
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/CopyConfig.h b/contrib/libs/llvm12/tools/llvm-objcopy/CopyConfig.h
index 467e1c41f1..07eac9d2bb 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/CopyConfig.h
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/CopyConfig.h
@@ -178,7 +178,7 @@ struct CopyConfig {
std::vector<StringRef> DumpSection;
std::vector<StringRef> SymbolsToAdd;
std::vector<StringRef> RPathToAdd;
- std::vector<StringRef> RPathToPrepend;
+ std::vector<StringRef> RPathToPrepend;
DenseMap<StringRef, StringRef> RPathsToUpdate;
DenseMap<StringRef, StringRef> InstallNamesToUpdate;
DenseSet<StringRef> RPathsToRemove;
@@ -231,9 +231,9 @@ struct CopyConfig {
bool StripUnneeded = false;
bool Weaken = false;
bool DecompressDebugSections = false;
- // install-name-tool's --delete_all_rpaths
- bool RemoveAllRpaths = false;
-
+ // install-name-tool's --delete_all_rpaths
+ bool RemoveAllRpaths = false;
+
DebugCompressionType CompressionType = DebugCompressionType::None;
// parseELFConfig performs ELF-specific command-line parsing. Fills `ELF` on
@@ -271,11 +271,11 @@ parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
Expected<DriverConfig>
parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr);
-// ParseBitcodeStripOptions returns the config and sets the input arguments.
-// If a help flag is set then ParseBitcodeStripOptions will print the help
-// messege and exit.
-Expected<DriverConfig> parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr);
-
+// ParseBitcodeStripOptions returns the config and sets the input arguments.
+// If a help flag is set then ParseBitcodeStripOptions will print the help
+// messege and exit.
+Expected<DriverConfig> parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr);
+
// ParseStripOptions returns the config and sets the input arguments. If a
// help flag is set then ParseStripOptions will print the help messege and
// exit. ErrorCallback is used to handle recoverable errors. An Error returned
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/contrib/libs/llvm12/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
index ee808a2d9d..c53a34bc46 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
@@ -184,28 +184,28 @@ findBuildID(const CopyConfig &Config, const object::ELFFile<ELFT> &In) {
return createFileError(Config.InputFilename, std::move(Err));
}
- return createFileError(Config.InputFilename,
- createStringError(llvm::errc::invalid_argument,
- "could not find build ID"));
+ return createFileError(Config.InputFilename,
+ createStringError(llvm::errc::invalid_argument,
+ "could not find build ID"));
}
static Expected<ArrayRef<uint8_t>>
findBuildID(const CopyConfig &Config, const object::ELFObjectFileBase &In) {
if (auto *O = dyn_cast<ELFObjectFile<ELF32LE>>(&In))
- return findBuildID(Config, O->getELFFile());
+ return findBuildID(Config, O->getELFFile());
else if (auto *O = dyn_cast<ELFObjectFile<ELF64LE>>(&In))
- return findBuildID(Config, O->getELFFile());
+ return findBuildID(Config, O->getELFFile());
else if (auto *O = dyn_cast<ELFObjectFile<ELF32BE>>(&In))
- return findBuildID(Config, O->getELFFile());
+ return findBuildID(Config, O->getELFFile());
else if (auto *O = dyn_cast<ELFObjectFile<ELF64BE>>(&In))
- return findBuildID(Config, O->getELFFile());
+ return findBuildID(Config, O->getELFFile());
llvm_unreachable("Bad file format");
}
template <class... Ts>
-static Error makeStringError(std::error_code EC, const Twine &Msg,
- Ts &&... Args) {
+static Error makeStringError(std::error_code EC, const Twine &Msg,
+ Ts &&... Args) {
std::string FullMsg = (EC.message() + ": " + Msg).str();
return createStringError(EC, FullMsg.c_str(), std::forward<Ts>(Args)...);
}
@@ -265,23 +265,23 @@ static Error linkToBuildIdDir(const CopyConfig &Config, StringRef ToLink,
static Error splitDWOToFile(const CopyConfig &Config, const Reader &Reader,
StringRef File, ElfType OutputElfType) {
- Expected<std::unique_ptr<Object>> DWOFile = Reader.create(false);
- if (!DWOFile)
- return DWOFile.takeError();
-
+ Expected<std::unique_ptr<Object>> DWOFile = Reader.create(false);
+ if (!DWOFile)
+ return DWOFile.takeError();
+
auto OnlyKeepDWOPred = [&DWOFile](const SectionBase &Sec) {
- return onlyKeepDWOPred(**DWOFile, Sec);
+ return onlyKeepDWOPred(**DWOFile, Sec);
};
- if (Error E =
- (*DWOFile)->removeSections(Config.AllowBrokenLinks, OnlyKeepDWOPred))
+ if (Error E =
+ (*DWOFile)->removeSections(Config.AllowBrokenLinks, OnlyKeepDWOPred))
return E;
if (Config.OutputArch) {
- (*DWOFile)->Machine = Config.OutputArch.getValue().EMachine;
- (*DWOFile)->OSABI = Config.OutputArch.getValue().OSABI;
+ (*DWOFile)->Machine = Config.OutputArch.getValue().EMachine;
+ (*DWOFile)->OSABI = Config.OutputArch.getValue().OSABI;
}
FileBuffer FB(File);
- std::unique_ptr<Writer> Writer =
- createWriter(Config, **DWOFile, FB, OutputElfType);
+ std::unique_ptr<Writer> Writer =
+ createWriter(Config, **DWOFile, FB, OutputElfType);
if (Error E = Writer->finalize())
return E;
return Writer->write();
@@ -316,39 +316,39 @@ static bool isCompressable(const SectionBase &Sec) {
StringRef(Sec.Name).startswith(".debug");
}
-static Error replaceDebugSections(
+static Error replaceDebugSections(
Object &Obj, SectionPred &RemovePred,
- function_ref<bool(const SectionBase &)> ShouldReplace,
- function_ref<Expected<SectionBase *>(const SectionBase *)> AddSection) {
+ function_ref<bool(const SectionBase &)> ShouldReplace,
+ function_ref<Expected<SectionBase *>(const SectionBase *)> AddSection) {
// Build a list of the debug sections we are going to replace.
- // We can't call `AddSection` while iterating over sections,
+ // We can't call `AddSection` while iterating over sections,
// because it would mutate the sections array.
SmallVector<SectionBase *, 13> ToReplace;
for (auto &Sec : Obj.sections())
- if (ShouldReplace(Sec))
+ if (ShouldReplace(Sec))
ToReplace.push_back(&Sec);
// Build a mapping from original section to a new one.
DenseMap<SectionBase *, SectionBase *> FromTo;
- for (SectionBase *S : ToReplace) {
- Expected<SectionBase *> NewSection = AddSection(S);
- if (!NewSection)
- return NewSection.takeError();
-
- FromTo[S] = *NewSection;
- }
-
+ for (SectionBase *S : ToReplace) {
+ Expected<SectionBase *> NewSection = AddSection(S);
+ if (!NewSection)
+ return NewSection.takeError();
+
+ FromTo[S] = *NewSection;
+ }
+
// Now we want to update the target sections of relocation
// sections. Also we will update the relocations themselves
// to update the symbol references.
for (auto &Sec : Obj.sections())
Sec.replaceSectionReferences(FromTo);
- RemovePred = [ShouldReplace, RemovePred](const SectionBase &Sec) {
- return ShouldReplace(Sec) || RemovePred(Sec);
+ RemovePred = [ShouldReplace, RemovePred](const SectionBase &Sec) {
+ return ShouldReplace(Sec) || RemovePred(Sec);
};
-
- return Error::success();
+
+ return Error::success();
}
static bool isUnneededSymbol(const Symbol &Sym) {
@@ -587,29 +587,29 @@ static Error replaceAndRemoveSections(const CopyConfig &Config, Object &Obj) {
};
}
- if (Config.CompressionType != DebugCompressionType::None) {
- if (Error Err = replaceDebugSections(
- Obj, RemovePred, isCompressable,
- [&Config, &Obj](const SectionBase *S) -> Expected<SectionBase *> {
- Expected<CompressedSection> NewSection =
- CompressedSection::create(*S, Config.CompressionType);
- if (!NewSection)
- return NewSection.takeError();
-
- return &Obj.addSection<CompressedSection>(std::move(*NewSection));
- }))
- return Err;
- } else if (Config.DecompressDebugSections) {
- if (Error Err = replaceDebugSections(
- Obj, RemovePred,
- [](const SectionBase &S) { return isa<CompressedSection>(&S); },
- [&Obj](const SectionBase *S) {
- const CompressedSection *CS = cast<CompressedSection>(S);
- return &Obj.addSection<DecompressedSection>(*CS);
- }))
- return Err;
- }
-
+ if (Config.CompressionType != DebugCompressionType::None) {
+ if (Error Err = replaceDebugSections(
+ Obj, RemovePred, isCompressable,
+ [&Config, &Obj](const SectionBase *S) -> Expected<SectionBase *> {
+ Expected<CompressedSection> NewSection =
+ CompressedSection::create(*S, Config.CompressionType);
+ if (!NewSection)
+ return NewSection.takeError();
+
+ return &Obj.addSection<CompressedSection>(std::move(*NewSection));
+ }))
+ return Err;
+ } else if (Config.DecompressDebugSections) {
+ if (Error Err = replaceDebugSections(
+ Obj, RemovePred,
+ [](const SectionBase &S) { return isa<CompressedSection>(&S); },
+ [&Obj](const SectionBase *S) {
+ const CompressedSection *CS = cast<CompressedSection>(S);
+ return &Obj.addSection<DecompressedSection>(*CS);
+ }))
+ return Err;
+ }
+
return Obj.removeSections(Config.AllowBrokenLinks, RemovePred);
}
@@ -748,9 +748,9 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj,
// If the symbol table was previously removed, we need to create a new one
// before adding new symbols.
- if (!Obj.SymbolTable && !Config.ELF->SymbolsToAdd.empty())
- if (Error E = Obj.addNewSymbolTable())
- return E;
+ if (!Obj.SymbolTable && !Config.ELF->SymbolsToAdd.empty())
+ if (Error E = Obj.addNewSymbolTable())
+ return E;
for (const NewSymbolInfo &SI : Config.ELF->SymbolsToAdd) {
SectionBase *Sec = Obj.findSection(SI.SectionName);
@@ -760,17 +760,17 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj,
Sec ? (uint16_t)SYMBOL_SIMPLE_INDEX : (uint16_t)SHN_ABS, 0);
}
- // --set-section-flags works with sections added by --add-section.
- if (!Config.SetSectionFlags.empty()) {
- for (auto &Sec : Obj.sections()) {
- const auto Iter = Config.SetSectionFlags.find(Sec.Name);
- if (Iter != Config.SetSectionFlags.end()) {
- const SectionFlagsUpdate &SFU = Iter->second;
- setSectionFlagsAndType(Sec, SFU.NewFlags);
- }
- }
- }
-
+ // --set-section-flags works with sections added by --add-section.
+ if (!Config.SetSectionFlags.empty()) {
+ for (auto &Sec : Obj.sections()) {
+ const auto Iter = Config.SetSectionFlags.find(Sec.Name);
+ if (Iter != Config.SetSectionFlags.end()) {
+ const SectionFlagsUpdate &SFU = Iter->second;
+ setSectionFlagsAndType(Sec, SFU.NewFlags);
+ }
+ }
+ }
+
if (Config.EntryExpr)
Obj.Entry = Config.EntryExpr(Obj.Entry);
return Error::success();
@@ -788,15 +788,15 @@ static Error writeOutput(const CopyConfig &Config, Object &Obj, Buffer &Out,
Error executeObjcopyOnIHex(const CopyConfig &Config, MemoryBuffer &In,
Buffer &Out) {
IHexReader Reader(&In);
- Expected<std::unique_ptr<Object>> Obj = Reader.create(true);
- if (!Obj)
- return Obj.takeError();
-
+ Expected<std::unique_ptr<Object>> Obj = Reader.create(true);
+ if (!Obj)
+ return Obj.takeError();
+
const ElfType OutputElfType =
- getOutputElfType(Config.OutputArch.getValueOr(MachineInfo()));
- if (Error E = handleArgs(Config, **Obj, Reader, OutputElfType))
+ getOutputElfType(Config.OutputArch.getValueOr(MachineInfo()));
+ if (Error E = handleArgs(Config, **Obj, Reader, OutputElfType))
return E;
- return writeOutput(Config, **Obj, Out, OutputElfType);
+ return writeOutput(Config, **Obj, Out, OutputElfType);
}
Error executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In,
@@ -804,26 +804,26 @@ Error executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In,
uint8_t NewSymbolVisibility =
Config.ELF->NewSymbolVisibility.getValueOr((uint8_t)ELF::STV_DEFAULT);
BinaryReader Reader(&In, NewSymbolVisibility);
- Expected<std::unique_ptr<Object>> Obj = Reader.create(true);
- if (!Obj)
- return Obj.takeError();
+ Expected<std::unique_ptr<Object>> Obj = Reader.create(true);
+ if (!Obj)
+ return Obj.takeError();
// Prefer OutputArch (-O<format>) if set, otherwise fallback to BinaryArch
// (-B<arch>).
const ElfType OutputElfType =
getOutputElfType(Config.OutputArch.getValueOr(MachineInfo()));
- if (Error E = handleArgs(Config, **Obj, Reader, OutputElfType))
+ if (Error E = handleArgs(Config, **Obj, Reader, OutputElfType))
return E;
- return writeOutput(Config, **Obj, Out, OutputElfType);
+ return writeOutput(Config, **Obj, Out, OutputElfType);
}
Error executeObjcopyOnBinary(const CopyConfig &Config,
object::ELFObjectFileBase &In, Buffer &Out) {
ELFReader Reader(&In, Config.ExtractPartition);
- Expected<std::unique_ptr<Object>> Obj =
- Reader.create(!Config.SymbolsToAdd.empty());
- if (!Obj)
- return Obj.takeError();
+ Expected<std::unique_ptr<Object>> Obj =
+ Reader.create(!Config.SymbolsToAdd.empty());
+ if (!Obj)
+ return Obj.takeError();
// Prefer OutputArch (-O<format>) if set, otherwise infer it from the input.
const ElfType OutputElfType =
Config.OutputArch ? getOutputElfType(Config.OutputArch.getValue())
@@ -849,10 +849,10 @@ Error executeObjcopyOnBinary(const CopyConfig &Config,
Config.BuildIdLinkInput.getValue(), BuildIdBytes))
return E;
- if (Error E = handleArgs(Config, **Obj, Reader, OutputElfType))
+ if (Error E = handleArgs(Config, **Obj, Reader, OutputElfType))
return createFileError(Config.InputFilename, std::move(E));
- if (Error E = writeOutput(Config, **Obj, Out, OutputElfType))
+ if (Error E = writeOutput(Config, **Obj, Out, OutputElfType))
return createFileError(Config.InputFilename, std::move(E));
if (!Config.BuildIdLinkDir.empty() && Config.BuildIdLinkOutput)
if (Error E =
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/ELF/Object.cpp b/contrib/libs/llvm12/tools/llvm-objcopy/ELF/Object.cpp
index 4aea09fb50..0ff82f951b 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/ELF/Object.cpp
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/ELF/Object.cpp
@@ -14,7 +14,7 @@
#include "llvm/ADT/iterator_range.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCTargetOptions.h"
-#include "llvm/Object/ELF.h"
+#include "llvm/Object/ELF.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Endian.h"
@@ -51,15 +51,15 @@ template <class ELFT> void ELFWriter<ELFT>::writePhdr(const Segment &Seg) {
}
Error SectionBase::removeSectionReferences(
- bool, function_ref<bool(const SectionBase *)>) {
+ bool, function_ref<bool(const SectionBase *)>) {
return Error::success();
}
-Error SectionBase::removeSymbols(function_ref<bool(const Symbol &)>) {
+Error SectionBase::removeSymbols(function_ref<bool(const Symbol &)>) {
return Error::success();
}
-Error SectionBase::initialize(SectionTableRef) { return Error::success(); }
+Error SectionBase::initialize(SectionTableRef) { return Error::success(); }
void SectionBase::finalize() {}
void SectionBase::markSymbols() {}
void SectionBase::replaceSectionReferences(
@@ -81,98 +81,98 @@ template <class ELFT> void ELFWriter<ELFT>::writeShdr(const SectionBase &Sec) {
Shdr.sh_entsize = Sec.EntrySize;
}
-template <class ELFT> Error ELFSectionSizer<ELFT>::visit(Section &) {
- return Error::success();
-}
+template <class ELFT> Error ELFSectionSizer<ELFT>::visit(Section &) {
+ return Error::success();
+}
-template <class ELFT> Error ELFSectionSizer<ELFT>::visit(OwnedDataSection &) {
- return Error::success();
-}
+template <class ELFT> Error ELFSectionSizer<ELFT>::visit(OwnedDataSection &) {
+ return Error::success();
+}
-template <class ELFT> Error ELFSectionSizer<ELFT>::visit(StringTableSection &) {
- return Error::success();
-}
+template <class ELFT> Error ELFSectionSizer<ELFT>::visit(StringTableSection &) {
+ return Error::success();
+}
template <class ELFT>
-Error ELFSectionSizer<ELFT>::visit(DynamicRelocationSection &) {
- return Error::success();
-}
+Error ELFSectionSizer<ELFT>::visit(DynamicRelocationSection &) {
+ return Error::success();
+}
template <class ELFT>
-Error ELFSectionSizer<ELFT>::visit(SymbolTableSection &Sec) {
+Error ELFSectionSizer<ELFT>::visit(SymbolTableSection &Sec) {
Sec.EntrySize = sizeof(Elf_Sym);
Sec.Size = Sec.Symbols.size() * Sec.EntrySize;
// Align to the largest field in Elf_Sym.
Sec.Align = ELFT::Is64Bits ? sizeof(Elf_Xword) : sizeof(Elf_Word);
- return Error::success();
+ return Error::success();
}
template <class ELFT>
-Error ELFSectionSizer<ELFT>::visit(RelocationSection &Sec) {
+Error ELFSectionSizer<ELFT>::visit(RelocationSection &Sec) {
Sec.EntrySize = Sec.Type == SHT_REL ? sizeof(Elf_Rel) : sizeof(Elf_Rela);
Sec.Size = Sec.Relocations.size() * Sec.EntrySize;
// Align to the largest field in Elf_Rel(a).
Sec.Align = ELFT::Is64Bits ? sizeof(Elf_Xword) : sizeof(Elf_Word);
- return Error::success();
+ return Error::success();
}
template <class ELFT>
-Error ELFSectionSizer<ELFT>::visit(GnuDebugLinkSection &) {
- return Error::success();
-}
+Error ELFSectionSizer<ELFT>::visit(GnuDebugLinkSection &) {
+ return Error::success();
+}
-template <class ELFT> Error ELFSectionSizer<ELFT>::visit(GroupSection &Sec) {
+template <class ELFT> Error ELFSectionSizer<ELFT>::visit(GroupSection &Sec) {
Sec.Size = sizeof(Elf_Word) + Sec.GroupMembers.size() * sizeof(Elf_Word);
- return Error::success();
+ return Error::success();
}
template <class ELFT>
-Error ELFSectionSizer<ELFT>::visit(SectionIndexSection &) {
- return Error::success();
-}
+Error ELFSectionSizer<ELFT>::visit(SectionIndexSection &) {
+ return Error::success();
+}
-template <class ELFT> Error ELFSectionSizer<ELFT>::visit(CompressedSection &) {
- return Error::success();
-}
+template <class ELFT> Error ELFSectionSizer<ELFT>::visit(CompressedSection &) {
+ return Error::success();
+}
template <class ELFT>
-Error ELFSectionSizer<ELFT>::visit(DecompressedSection &) {
- return Error::success();
-}
+Error ELFSectionSizer<ELFT>::visit(DecompressedSection &) {
+ return Error::success();
+}
-Error BinarySectionWriter::visit(const SectionIndexSection &Sec) {
- return createStringError(errc::operation_not_permitted,
- "cannot write symbol section index table '" +
- Sec.Name + "' ");
+Error BinarySectionWriter::visit(const SectionIndexSection &Sec) {
+ return createStringError(errc::operation_not_permitted,
+ "cannot write symbol section index table '" +
+ Sec.Name + "' ");
}
-Error BinarySectionWriter::visit(const SymbolTableSection &Sec) {
- return createStringError(errc::operation_not_permitted,
- "cannot write symbol table '" + Sec.Name +
- "' out to binary");
+Error BinarySectionWriter::visit(const SymbolTableSection &Sec) {
+ return createStringError(errc::operation_not_permitted,
+ "cannot write symbol table '" + Sec.Name +
+ "' out to binary");
}
-Error BinarySectionWriter::visit(const RelocationSection &Sec) {
- return createStringError(errc::operation_not_permitted,
- "cannot write relocation section '" + Sec.Name +
- "' out to binary");
+Error BinarySectionWriter::visit(const RelocationSection &Sec) {
+ return createStringError(errc::operation_not_permitted,
+ "cannot write relocation section '" + Sec.Name +
+ "' out to binary");
}
-Error BinarySectionWriter::visit(const GnuDebugLinkSection &Sec) {
- return createStringError(errc::operation_not_permitted,
- "cannot write '" + Sec.Name + "' out to binary");
+Error BinarySectionWriter::visit(const GnuDebugLinkSection &Sec) {
+ return createStringError(errc::operation_not_permitted,
+ "cannot write '" + Sec.Name + "' out to binary");
}
-Error BinarySectionWriter::visit(const GroupSection &Sec) {
- return createStringError(errc::operation_not_permitted,
- "cannot write '" + Sec.Name + "' out to binary");
+Error BinarySectionWriter::visit(const GroupSection &Sec) {
+ return createStringError(errc::operation_not_permitted,
+ "cannot write '" + Sec.Name + "' out to binary");
}
-Error SectionWriter::visit(const Section &Sec) {
+Error SectionWriter::visit(const Section &Sec) {
if (Sec.Type != SHT_NOBITS)
llvm::copy(Sec.Contents, Out.getBufferStart() + Sec.Offset);
-
- return Error::success();
+
+ return Error::success();
}
static bool addressOverflows32bit(uint64_t Addr) {
@@ -377,34 +377,34 @@ uint64_t IHexSectionWriterBase::writeBaseAddr(uint64_t Addr) {
return Base;
}
-void IHexSectionWriterBase::writeData(uint8_t, uint16_t,
+void IHexSectionWriterBase::writeData(uint8_t, uint16_t,
ArrayRef<uint8_t> Data) {
Offset += IHexRecord::getLineLength(Data.size());
}
-Error IHexSectionWriterBase::visit(const Section &Sec) {
+Error IHexSectionWriterBase::visit(const Section &Sec) {
writeSection(&Sec, Sec.Contents);
- return Error::success();
+ return Error::success();
}
-Error IHexSectionWriterBase::visit(const OwnedDataSection &Sec) {
+Error IHexSectionWriterBase::visit(const OwnedDataSection &Sec) {
writeSection(&Sec, Sec.Data);
- return Error::success();
+ return Error::success();
}
-Error IHexSectionWriterBase::visit(const StringTableSection &Sec) {
+Error IHexSectionWriterBase::visit(const StringTableSection &Sec) {
// Check that sizer has already done its work
assert(Sec.Size == Sec.StrTabBuilder.getSize());
// We are free to pass an invalid pointer to writeSection as long
// as we don't actually write any data. The real writer class has
// to override this method .
writeSection(&Sec, {nullptr, static_cast<size_t>(Sec.Size)});
- return Error::success();
+ return Error::success();
}
-Error IHexSectionWriterBase::visit(const DynamicRelocationSection &Sec) {
+Error IHexSectionWriterBase::visit(const DynamicRelocationSection &Sec) {
writeSection(&Sec, Sec.Contents);
- return Error::success();
+ return Error::success();
}
void IHexSectionWriter::writeData(uint8_t Type, uint16_t Addr,
@@ -414,25 +414,25 @@ void IHexSectionWriter::writeData(uint8_t Type, uint16_t Addr,
Offset += HexData.size();
}
-Error IHexSectionWriter::visit(const StringTableSection &Sec) {
+Error IHexSectionWriter::visit(const StringTableSection &Sec) {
assert(Sec.Size == Sec.StrTabBuilder.getSize());
std::vector<uint8_t> Data(Sec.Size);
Sec.StrTabBuilder.write(Data.data());
writeSection(&Sec, Data);
- return Error::success();
+ return Error::success();
}
-Error Section::accept(SectionVisitor &Visitor) const {
- return Visitor.visit(*this);
-}
+Error Section::accept(SectionVisitor &Visitor) const {
+ return Visitor.visit(*this);
+}
-Error Section::accept(MutableSectionVisitor &Visitor) {
- return Visitor.visit(*this);
-}
+Error Section::accept(MutableSectionVisitor &Visitor) {
+ return Visitor.visit(*this);
+}
-Error SectionWriter::visit(const OwnedDataSection &Sec) {
+Error SectionWriter::visit(const OwnedDataSection &Sec) {
llvm::copy(Sec.Data, Out.getBufferStart() + Sec.Offset);
- return Error::success();
+ return Error::success();
}
static constexpr std::array<uint8_t, 4> ZlibGnuMagic = {{'Z', 'L', 'I', 'B'}};
@@ -459,7 +459,7 @@ getDecompressedSizeAndAlignment(ArrayRef<uint8_t> Data) {
}
template <class ELFT>
-Error ELFSectionWriter<ELFT>::visit(const DecompressedSection &Sec) {
+Error ELFSectionWriter<ELFT>::visit(const DecompressedSection &Sec) {
const size_t DataOffset = isDataGnuCompressed(Sec.OriginalData)
? (ZlibGnuMagic.size() + sizeof(Sec.Size))
: sizeof(Elf_Chdr_Impl<ELFT>);
@@ -469,37 +469,37 @@ Error ELFSectionWriter<ELFT>::visit(const DecompressedSection &Sec) {
Sec.OriginalData.size() - DataOffset);
SmallVector<char, 128> DecompressedContent;
- if (Error Err = zlib::uncompress(CompressedContent, DecompressedContent,
- static_cast<size_t>(Sec.Size)))
- return createStringError(errc::invalid_argument,
- "'" + Sec.Name + "': " + toString(std::move(Err)));
+ if (Error Err = zlib::uncompress(CompressedContent, DecompressedContent,
+ static_cast<size_t>(Sec.Size)))
+ return createStringError(errc::invalid_argument,
+ "'" + Sec.Name + "': " + toString(std::move(Err)));
uint8_t *Buf = Out.getBufferStart() + Sec.Offset;
std::copy(DecompressedContent.begin(), DecompressedContent.end(), Buf);
-
- return Error::success();
+
+ return Error::success();
}
-Error BinarySectionWriter::visit(const DecompressedSection &Sec) {
- return createStringError(errc::operation_not_permitted,
- "cannot write compressed section '" + Sec.Name +
- "' ");
+Error BinarySectionWriter::visit(const DecompressedSection &Sec) {
+ return createStringError(errc::operation_not_permitted,
+ "cannot write compressed section '" + Sec.Name +
+ "' ");
}
-Error DecompressedSection::accept(SectionVisitor &Visitor) const {
- return Visitor.visit(*this);
+Error DecompressedSection::accept(SectionVisitor &Visitor) const {
+ return Visitor.visit(*this);
}
-Error DecompressedSection::accept(MutableSectionVisitor &Visitor) {
- return Visitor.visit(*this);
+Error DecompressedSection::accept(MutableSectionVisitor &Visitor) {
+ return Visitor.visit(*this);
}
-Error OwnedDataSection::accept(SectionVisitor &Visitor) const {
- return Visitor.visit(*this);
+Error OwnedDataSection::accept(SectionVisitor &Visitor) const {
+ return Visitor.visit(*this);
}
-Error OwnedDataSection::accept(MutableSectionVisitor &Visitor) {
- return Visitor.visit(*this);
+Error OwnedDataSection::accept(MutableSectionVisitor &Visitor) {
+ return Visitor.visit(*this);
}
void OwnedDataSection::appendHexData(StringRef HexData) {
@@ -511,18 +511,18 @@ void OwnedDataSection::appendHexData(StringRef HexData) {
Size = Data.size();
}
-Error BinarySectionWriter::visit(const CompressedSection &Sec) {
- return createStringError(errc::operation_not_permitted,
- "cannot write compressed section '" + Sec.Name +
- "' ");
+Error BinarySectionWriter::visit(const CompressedSection &Sec) {
+ return createStringError(errc::operation_not_permitted,
+ "cannot write compressed section '" + Sec.Name +
+ "' ");
}
template <class ELFT>
-Error ELFSectionWriter<ELFT>::visit(const CompressedSection &Sec) {
+Error ELFSectionWriter<ELFT>::visit(const CompressedSection &Sec) {
uint8_t *Buf = Out.getBufferStart() + Sec.Offset;
if (Sec.CompressionType == DebugCompressionType::None) {
std::copy(Sec.OriginalData.begin(), Sec.OriginalData.end(), Buf);
- return Error::success();
+ return Error::success();
}
if (Sec.CompressionType == DebugCompressionType::GNU) {
@@ -543,42 +543,42 @@ Error ELFSectionWriter<ELFT>::visit(const CompressedSection &Sec) {
}
std::copy(Sec.CompressedData.begin(), Sec.CompressedData.end(), Buf);
- return Error::success();
-}
-
-Expected<CompressedSection>
-CompressedSection::create(const SectionBase &Sec,
- DebugCompressionType CompressionType) {
- Error Err = Error::success();
- CompressedSection Section(Sec, CompressionType, Err);
-
- if (Err)
- return std::move(Err);
-
- return Section;
-}
-Expected<CompressedSection>
-CompressedSection::create(ArrayRef<uint8_t> CompressedData,
- uint64_t DecompressedSize,
- uint64_t DecompressedAlign) {
- return CompressedSection(CompressedData, DecompressedSize, DecompressedAlign);
-}
-
+ return Error::success();
+}
+
+Expected<CompressedSection>
+CompressedSection::create(const SectionBase &Sec,
+ DebugCompressionType CompressionType) {
+ Error Err = Error::success();
+ CompressedSection Section(Sec, CompressionType, Err);
+
+ if (Err)
+ return std::move(Err);
+
+ return Section;
+}
+Expected<CompressedSection>
+CompressedSection::create(ArrayRef<uint8_t> CompressedData,
+ uint64_t DecompressedSize,
+ uint64_t DecompressedAlign) {
+ return CompressedSection(CompressedData, DecompressedSize, DecompressedAlign);
+}
+
CompressedSection::CompressedSection(const SectionBase &Sec,
- DebugCompressionType CompressionType,
- Error &OutErr)
+ DebugCompressionType CompressionType,
+ Error &OutErr)
: SectionBase(Sec), CompressionType(CompressionType),
DecompressedSize(Sec.OriginalData.size()), DecompressedAlign(Sec.Align) {
- ErrorAsOutParameter EAO(&OutErr);
-
- if (Error Err = zlib::compress(
+ ErrorAsOutParameter EAO(&OutErr);
+
+ if (Error Err = zlib::compress(
StringRef(reinterpret_cast<const char *>(OriginalData.data()),
OriginalData.size()),
- CompressedData)) {
- OutErr = createStringError(llvm::errc::invalid_argument,
- "'" + Name + "': " + toString(std::move(Err)));
- return;
- }
+ CompressedData)) {
+ OutErr = createStringError(llvm::errc::invalid_argument,
+ "'" + Name + "': " + toString(std::move(Err)));
+ return;
+ }
size_t ChdrSize;
if (CompressionType == DebugCompressionType::GNU) {
@@ -604,12 +604,12 @@ CompressedSection::CompressedSection(ArrayRef<uint8_t> CompressedData,
OriginalData = CompressedData;
}
-Error CompressedSection::accept(SectionVisitor &Visitor) const {
- return Visitor.visit(*this);
+Error CompressedSection::accept(SectionVisitor &Visitor) const {
+ return Visitor.visit(*this);
}
-Error CompressedSection::accept(MutableSectionVisitor &Visitor) {
- return Visitor.visit(*this);
+Error CompressedSection::accept(MutableSectionVisitor &Visitor) {
+ return Visitor.visit(*this);
}
void StringTableSection::addString(StringRef Name) { StrTabBuilder.add(Name); }
@@ -623,51 +623,51 @@ void StringTableSection::prepareForLayout() {
Size = StrTabBuilder.getSize();
}
-Error SectionWriter::visit(const StringTableSection &Sec) {
+Error SectionWriter::visit(const StringTableSection &Sec) {
Sec.StrTabBuilder.write(Out.getBufferStart() + Sec.Offset);
- return Error::success();
+ return Error::success();
}
-Error StringTableSection::accept(SectionVisitor &Visitor) const {
- return Visitor.visit(*this);
+Error StringTableSection::accept(SectionVisitor &Visitor) const {
+ return Visitor.visit(*this);
}
-Error StringTableSection::accept(MutableSectionVisitor &Visitor) {
- return Visitor.visit(*this);
+Error StringTableSection::accept(MutableSectionVisitor &Visitor) {
+ return Visitor.visit(*this);
}
template <class ELFT>
-Error ELFSectionWriter<ELFT>::visit(const SectionIndexSection &Sec) {
+Error ELFSectionWriter<ELFT>::visit(const SectionIndexSection &Sec) {
uint8_t *Buf = Out.getBufferStart() + Sec.Offset;
llvm::copy(Sec.Indexes, reinterpret_cast<Elf_Word *>(Buf));
- return Error::success();
+ return Error::success();
}
-Error SectionIndexSection::initialize(SectionTableRef SecTable) {
+Error SectionIndexSection::initialize(SectionTableRef SecTable) {
Size = 0;
- Expected<SymbolTableSection *> Sec =
- SecTable.getSectionOfType<SymbolTableSection>(
- Link,
- "Link field value " + Twine(Link) + " in section " + Name +
- " is invalid",
- "Link field value " + Twine(Link) + " in section " + Name +
- " is not a symbol table");
- if (!Sec)
- return Sec.takeError();
-
- setSymTab(*Sec);
+ Expected<SymbolTableSection *> Sec =
+ SecTable.getSectionOfType<SymbolTableSection>(
+ Link,
+ "Link field value " + Twine(Link) + " in section " + Name +
+ " is invalid",
+ "Link field value " + Twine(Link) + " in section " + Name +
+ " is not a symbol table");
+ if (!Sec)
+ return Sec.takeError();
+
+ setSymTab(*Sec);
Symbols->setShndxTable(this);
- return Error::success();
+ return Error::success();
}
void SectionIndexSection::finalize() { Link = Symbols->Index; }
-Error SectionIndexSection::accept(SectionVisitor &Visitor) const {
- return Visitor.visit(*this);
+Error SectionIndexSection::accept(SectionVisitor &Visitor) const {
+ return Visitor.visit(*this);
}
-Error SectionIndexSection::accept(MutableSectionVisitor &Visitor) {
- return Visitor.visit(*this);
+Error SectionIndexSection::accept(MutableSectionVisitor &Visitor) {
+ return Visitor.visit(*this);
}
static bool isValidReservedSectionIndex(uint16_t Index, uint16_t Machine) {
@@ -750,7 +750,7 @@ void SymbolTableSection::addSymbol(Twine Name, uint8_t Bind, uint8_t Type,
}
Error SymbolTableSection::removeSectionReferences(
- bool AllowBrokenLinks, function_ref<bool(const SectionBase *)> ToRemove) {
+ bool AllowBrokenLinks, function_ref<bool(const SectionBase *)> ToRemove) {
if (ToRemove(SectionIndexTable))
SectionIndexTable = nullptr;
if (ToRemove(SymbolNames)) {
@@ -793,20 +793,20 @@ void SymbolTableSection::replaceSectionReferences(
Sym->DefinedIn = To;
}
-Error SymbolTableSection::initialize(SectionTableRef SecTable) {
+Error SymbolTableSection::initialize(SectionTableRef SecTable) {
Size = 0;
- Expected<StringTableSection *> Sec =
- SecTable.getSectionOfType<StringTableSection>(
- Link,
- "Symbol table has link index of " + Twine(Link) +
- " which is not a valid index",
- "Symbol table has link index of " + Twine(Link) +
- " which is not a string table");
- if (!Sec)
- return Sec.takeError();
-
- setStrTab(*Sec);
- return Error::success();
+ Expected<StringTableSection *> Sec =
+ SecTable.getSectionOfType<StringTableSection>(
+ Link,
+ "Symbol table has link index of " + Twine(Link) +
+ " which is not a valid index",
+ "Symbol table has link index of " + Twine(Link) +
+ " which is not a string table");
+ if (!Sec)
+ return Sec.takeError();
+
+ setStrTab(*Sec);
+ return Error::success();
}
void SymbolTableSection::finalize() {
@@ -851,25 +851,25 @@ void SymbolTableSection::fillShndxTable() {
}
}
-Expected<const Symbol *>
-SymbolTableSection::getSymbolByIndex(uint32_t Index) const {
+Expected<const Symbol *>
+SymbolTableSection::getSymbolByIndex(uint32_t Index) const {
if (Symbols.size() <= Index)
- return createStringError(errc::invalid_argument,
- "invalid symbol index: " + Twine(Index));
+ return createStringError(errc::invalid_argument,
+ "invalid symbol index: " + Twine(Index));
return Symbols[Index].get();
}
-Expected<Symbol *> SymbolTableSection::getSymbolByIndex(uint32_t Index) {
- Expected<const Symbol *> Sym =
- static_cast<const SymbolTableSection *>(this)->getSymbolByIndex(Index);
- if (!Sym)
- return Sym.takeError();
-
- return const_cast<Symbol *>(*Sym);
+Expected<Symbol *> SymbolTableSection::getSymbolByIndex(uint32_t Index) {
+ Expected<const Symbol *> Sym =
+ static_cast<const SymbolTableSection *>(this)->getSymbolByIndex(Index);
+ if (!Sym)
+ return Sym.takeError();
+
+ return const_cast<Symbol *>(*Sym);
}
template <class ELFT>
-Error ELFSectionWriter<ELFT>::visit(const SymbolTableSection &Sec) {
+Error ELFSectionWriter<ELFT>::visit(const SymbolTableSection &Sec) {
Elf_Sym *Sym = reinterpret_cast<Elf_Sym *>(Out.getBufferStart() + Sec.Offset);
// Loop though symbols setting each entry of the symbol table.
for (const std::unique_ptr<Symbol> &Symbol : Sec.Symbols) {
@@ -882,19 +882,19 @@ Error ELFSectionWriter<ELFT>::visit(const SymbolTableSection &Sec) {
Sym->st_shndx = Symbol->getShndx();
++Sym;
}
- return Error::success();
+ return Error::success();
}
-Error SymbolTableSection::accept(SectionVisitor &Visitor) const {
- return Visitor.visit(*this);
+Error SymbolTableSection::accept(SectionVisitor &Visitor) const {
+ return Visitor.visit(*this);
}
-Error SymbolTableSection::accept(MutableSectionVisitor &Visitor) {
- return Visitor.visit(*this);
+Error SymbolTableSection::accept(MutableSectionVisitor &Visitor) {
+ return Visitor.visit(*this);
}
Error RelocationSection::removeSectionReferences(
- bool AllowBrokenLinks, function_ref<bool(const SectionBase *)> ToRemove) {
+ bool AllowBrokenLinks, function_ref<bool(const SectionBase *)> ToRemove) {
if (ToRemove(Symbols)) {
if (!AllowBrokenLinks)
return createStringError(
@@ -921,33 +921,33 @@ Error RelocationSection::removeSectionReferences(
}
template <class SymTabType>
-Error RelocSectionWithSymtabBase<SymTabType>::initialize(
+Error RelocSectionWithSymtabBase<SymTabType>::initialize(
SectionTableRef SecTable) {
- if (Link != SHN_UNDEF) {
- Expected<SymTabType *> Sec = SecTable.getSectionOfType<SymTabType>(
+ if (Link != SHN_UNDEF) {
+ Expected<SymTabType *> Sec = SecTable.getSectionOfType<SymTabType>(
Link,
"Link field value " + Twine(Link) + " in section " + Name +
" is invalid",
"Link field value " + Twine(Link) + " in section " + Name +
- " is not a symbol table");
- if (!Sec)
- return Sec.takeError();
-
- setSymTab(*Sec);
- }
-
- if (Info != SHN_UNDEF) {
- Expected<SectionBase *> Sec =
- SecTable.getSection(Info, "Info field value " + Twine(Info) +
- " in section " + Name + " is invalid");
- if (!Sec)
- return Sec.takeError();
-
- setSection(*Sec);
- } else
+ " is not a symbol table");
+ if (!Sec)
+ return Sec.takeError();
+
+ setSymTab(*Sec);
+ }
+
+ if (Info != SHN_UNDEF) {
+ Expected<SectionBase *> Sec =
+ SecTable.getSection(Info, "Info field value " + Twine(Info) +
+ " in section " + Name + " is invalid");
+ if (!Sec)
+ return Sec.takeError();
+
+ setSection(*Sec);
+ } else
setSection(nullptr);
-
- return Error::success();
+
+ return Error::success();
}
template <class SymTabType>
@@ -959,7 +959,7 @@ void RelocSectionWithSymtabBase<SymTabType>::finalize() {
}
template <class ELFT>
-static void setAddend(Elf_Rel_Impl<ELFT, false> &, uint64_t) {}
+static void setAddend(Elf_Rel_Impl<ELFT, false> &, uint64_t) {}
template <class ELFT>
static void setAddend(Elf_Rel_Impl<ELFT, true> &Rela, uint64_t Addend) {
@@ -978,21 +978,21 @@ static void writeRel(const RelRange &Relocations, T *Buf) {
}
template <class ELFT>
-Error ELFSectionWriter<ELFT>::visit(const RelocationSection &Sec) {
+Error ELFSectionWriter<ELFT>::visit(const RelocationSection &Sec) {
uint8_t *Buf = Out.getBufferStart() + Sec.Offset;
if (Sec.Type == SHT_REL)
writeRel(Sec.Relocations, reinterpret_cast<Elf_Rel *>(Buf));
else
writeRel(Sec.Relocations, reinterpret_cast<Elf_Rela *>(Buf));
- return Error::success();
+ return Error::success();
}
-Error RelocationSection::accept(SectionVisitor &Visitor) const {
- return Visitor.visit(*this);
+Error RelocationSection::accept(SectionVisitor &Visitor) const {
+ return Visitor.visit(*this);
}
-Error RelocationSection::accept(MutableSectionVisitor &Visitor) {
- return Visitor.visit(*this);
+Error RelocationSection::accept(MutableSectionVisitor &Visitor) {
+ return Visitor.visit(*this);
}
Error RelocationSection::removeSymbols(
@@ -1019,17 +1019,17 @@ void RelocationSection::replaceSectionReferences(
SecToApplyRel = To;
}
-Error SectionWriter::visit(const DynamicRelocationSection &Sec) {
+Error SectionWriter::visit(const DynamicRelocationSection &Sec) {
llvm::copy(Sec.Contents, Out.getBufferStart() + Sec.Offset);
- return Error::success();
+ return Error::success();
}
-Error DynamicRelocationSection::accept(SectionVisitor &Visitor) const {
- return Visitor.visit(*this);
+Error DynamicRelocationSection::accept(SectionVisitor &Visitor) const {
+ return Visitor.visit(*this);
}
-Error DynamicRelocationSection::accept(MutableSectionVisitor &Visitor) {
- return Visitor.visit(*this);
+Error DynamicRelocationSection::accept(MutableSectionVisitor &Visitor) {
+ return Visitor.visit(*this);
}
Error DynamicRelocationSection::removeSectionReferences(
@@ -1115,22 +1115,22 @@ void GroupSection::onRemove() {
Sec->Flags &= ~SHF_GROUP;
}
-Error Section::initialize(SectionTableRef SecTable) {
+Error Section::initialize(SectionTableRef SecTable) {
if (Link == ELF::SHN_UNDEF)
- return Error::success();
-
- Expected<SectionBase *> Sec =
+ return Error::success();
+
+ Expected<SectionBase *> Sec =
SecTable.getSection(Link, "Link field value " + Twine(Link) +
" in section " + Name + " is invalid");
- if (!Sec)
- return Sec.takeError();
-
- LinkSection = *Sec;
-
+ if (!Sec)
+ return Sec.takeError();
+
+ LinkSection = *Sec;
+
if (LinkSection->Type == ELF::SHT_SYMTAB)
LinkSection = nullptr;
-
- return Error::success();
+
+ return Error::success();
}
void Section::finalize() { this->Link = LinkSection ? LinkSection->Index : 0; }
@@ -1159,39 +1159,39 @@ GnuDebugLinkSection::GnuDebugLinkSection(StringRef File,
}
template <class ELFT>
-Error ELFSectionWriter<ELFT>::visit(const GnuDebugLinkSection &Sec) {
+Error ELFSectionWriter<ELFT>::visit(const GnuDebugLinkSection &Sec) {
unsigned char *Buf = Out.getBufferStart() + Sec.Offset;
Elf_Word *CRC =
reinterpret_cast<Elf_Word *>(Buf + Sec.Size - sizeof(Elf_Word));
*CRC = Sec.CRC32;
llvm::copy(Sec.FileName, Buf);
- return Error::success();
+ return Error::success();
}
-Error GnuDebugLinkSection::accept(SectionVisitor &Visitor) const {
- return Visitor.visit(*this);
+Error GnuDebugLinkSection::accept(SectionVisitor &Visitor) const {
+ return Visitor.visit(*this);
}
-Error GnuDebugLinkSection::accept(MutableSectionVisitor &Visitor) {
- return Visitor.visit(*this);
+Error GnuDebugLinkSection::accept(MutableSectionVisitor &Visitor) {
+ return Visitor.visit(*this);
}
template <class ELFT>
-Error ELFSectionWriter<ELFT>::visit(const GroupSection &Sec) {
+Error ELFSectionWriter<ELFT>::visit(const GroupSection &Sec) {
ELF::Elf32_Word *Buf =
reinterpret_cast<ELF::Elf32_Word *>(Out.getBufferStart() + Sec.Offset);
*Buf++ = Sec.FlagWord;
for (SectionBase *S : Sec.GroupMembers)
support::endian::write32<ELFT::TargetEndianness>(Buf++, S->Index);
- return Error::success();
+ return Error::success();
}
-Error GroupSection::accept(SectionVisitor &Visitor) const {
- return Visitor.visit(*this);
+Error GroupSection::accept(SectionVisitor &Visitor) const {
+ return Visitor.visit(*this);
}
-Error GroupSection::accept(MutableSectionVisitor &Visitor) {
- return Visitor.visit(*this);
+Error GroupSection::accept(MutableSectionVisitor &Visitor) {
+ return Visitor.visit(*this);
}
// Returns true IFF a section is wholly inside the range of a segment
@@ -1271,12 +1271,12 @@ SymbolTableSection *BasicELFBuilder::addSymTab(StringTableSection *StrTab) {
return &SymTab;
}
-Error BasicELFBuilder::initSections() {
+Error BasicELFBuilder::initSections() {
for (SectionBase &Sec : Obj->sections())
- if (Error Err = Sec.initialize(Obj->sections()))
- return Err;
-
- return Error::success();
+ if (Error Err = Sec.initialize(Obj->sections()))
+ return Err;
+
+ return Error::success();
}
void BinaryELFBuilder::addData(SymbolTableSection *SymTab) {
@@ -1303,13 +1303,13 @@ void BinaryELFBuilder::addData(SymbolTableSection *SymTab) {
0);
}
-Expected<std::unique_ptr<Object>> BinaryELFBuilder::build() {
+Expected<std::unique_ptr<Object>> BinaryELFBuilder::build() {
initFileHeader();
initHeaderSegment();
SymbolTableSection *SymTab = addSymTab(addStrTab());
- if (Error Err = initSections())
- return std::move(Err);
+ if (Error Err = initSections())
+ return std::move(Err);
addData(SymTab);
return std::move(Obj);
@@ -1360,13 +1360,13 @@ void IHexELFBuilder::addDataSections() {
}
}
-Expected<std::unique_ptr<Object>> IHexELFBuilder::build() {
+Expected<std::unique_ptr<Object>> IHexELFBuilder::build() {
initFileHeader();
initHeaderSegment();
StringTableSection *StrTab = addStrTab();
addSymTab(StrTab);
- if (Error Err = initSections())
- return std::move(Err);
+ if (Error Err = initSections())
+ return std::move(Err);
addDataSections();
return std::move(Obj);
@@ -1388,37 +1388,37 @@ template <class ELFT> void ELFBuilder<ELFT>::setParentSegment(Segment &Child) {
}
}
-template <class ELFT> Error ELFBuilder<ELFT>::findEhdrOffset() {
+template <class ELFT> Error ELFBuilder<ELFT>::findEhdrOffset() {
if (!ExtractPartition)
- return Error::success();
+ return Error::success();
for (const SectionBase &Sec : Obj.sections()) {
if (Sec.Type == SHT_LLVM_PART_EHDR && Sec.Name == *ExtractPartition) {
EhdrOffset = Sec.Offset;
- return Error::success();
+ return Error::success();
}
}
- return createStringError(errc::invalid_argument,
- "could not find partition named '" +
- *ExtractPartition + "'");
+ return createStringError(errc::invalid_argument,
+ "could not find partition named '" +
+ *ExtractPartition + "'");
}
template <class ELFT>
-Error ELFBuilder<ELFT>::readProgramHeaders(const ELFFile<ELFT> &HeadersFile) {
+Error ELFBuilder<ELFT>::readProgramHeaders(const ELFFile<ELFT> &HeadersFile) {
uint32_t Index = 0;
-
- Expected<typename ELFFile<ELFT>::Elf_Phdr_Range> Headers =
- HeadersFile.program_headers();
- if (!Headers)
- return Headers.takeError();
-
- for (const typename ELFFile<ELFT>::Elf_Phdr &Phdr : *Headers) {
+
+ Expected<typename ELFFile<ELFT>::Elf_Phdr_Range> Headers =
+ HeadersFile.program_headers();
+ if (!Headers)
+ return Headers.takeError();
+
+ for (const typename ELFFile<ELFT>::Elf_Phdr &Phdr : *Headers) {
if (Phdr.p_offset + Phdr.p_filesz > HeadersFile.getBufSize())
- return createStringError(
- errc::invalid_argument,
- "program header with offset 0x" + Twine::utohexstr(Phdr.p_offset) +
- " and file size 0x" + Twine::utohexstr(Phdr.p_filesz) +
- " goes past the end of the file");
+ return createStringError(
+ errc::invalid_argument,
+ "program header with offset 0x" + Twine::utohexstr(Phdr.p_offset) +
+ " and file size 0x" + Twine::utohexstr(Phdr.p_filesz) +
+ " goes past the end of the file");
ArrayRef<uint8_t> Data{HeadersFile.base() + Phdr.p_offset,
(size_t)Phdr.p_filesz};
@@ -1445,7 +1445,7 @@ Error ELFBuilder<ELFT>::readProgramHeaders(const ELFFile<ELFT> &HeadersFile) {
ElfHdr.Index = Index++;
ElfHdr.OriginalOffset = ElfHdr.Offset = EhdrOffset;
- const typename ELFT::Ehdr &Ehdr = HeadersFile.getHeader();
+ const typename ELFT::Ehdr &Ehdr = HeadersFile.getHeader();
auto &PrHdr = Obj.ProgramHdrSegment;
PrHdr.Type = PT_PHDR;
PrHdr.Flags = 0;
@@ -1466,16 +1466,16 @@ Error ELFBuilder<ELFT>::readProgramHeaders(const ELFFile<ELFT> &HeadersFile) {
setParentSegment(Child);
setParentSegment(ElfHdr);
setParentSegment(PrHdr);
-
- return Error::success();
+
+ return Error::success();
}
template <class ELFT>
-Error ELFBuilder<ELFT>::initGroupSection(GroupSection *GroupSec) {
+Error ELFBuilder<ELFT>::initGroupSection(GroupSection *GroupSec) {
if (GroupSec->Align % sizeof(ELF::Elf32_Word) != 0)
- return createStringError(errc::invalid_argument,
- "invalid alignment " + Twine(GroupSec->Align) +
- " of group section '" + GroupSec->Name + "'");
+ return createStringError(errc::invalid_argument,
+ "invalid alignment " + Twine(GroupSec->Align) +
+ " of group section '" + GroupSec->Name + "'");
SectionTableRef SecTable = Obj.sections();
if (GroupSec->Link != SHN_UNDEF) {
auto SymTab = SecTable.template getSectionOfType<SymbolTableSection>(
@@ -1484,23 +1484,23 @@ Error ELFBuilder<ELFT>::initGroupSection(GroupSection *GroupSec) {
GroupSec->Name + "' is invalid",
"link field value '" + Twine(GroupSec->Link) + "' in section '" +
GroupSec->Name + "' is not a symbol table");
- if (!SymTab)
- return SymTab.takeError();
-
- Expected<Symbol *> Sym = (*SymTab)->getSymbolByIndex(GroupSec->Info);
+ if (!SymTab)
+ return SymTab.takeError();
+
+ Expected<Symbol *> Sym = (*SymTab)->getSymbolByIndex(GroupSec->Info);
if (!Sym)
- return createStringError(errc::invalid_argument,
- "info field value '" + Twine(GroupSec->Info) +
- "' in section '" + GroupSec->Name +
- "' is not a valid symbol index");
- GroupSec->setSymTab(*SymTab);
- GroupSec->setSymbol(*Sym);
+ return createStringError(errc::invalid_argument,
+ "info field value '" + Twine(GroupSec->Info) +
+ "' in section '" + GroupSec->Name +
+ "' is not a valid symbol index");
+ GroupSec->setSymTab(*SymTab);
+ GroupSec->setSymbol(*Sym);
}
if (GroupSec->Contents.size() % sizeof(ELF::Elf32_Word) ||
GroupSec->Contents.empty())
- return createStringError(errc::invalid_argument,
- "the content of the section " + GroupSec->Name +
- " is malformed");
+ return createStringError(errc::invalid_argument,
+ "the content of the section " + GroupSec->Name +
+ " is malformed");
const ELF::Elf32_Word *Word =
reinterpret_cast<const ELF::Elf32_Word *>(GroupSec->Contents.data());
const ELF::Elf32_Word *End =
@@ -1508,103 +1508,103 @@ Error ELFBuilder<ELFT>::initGroupSection(GroupSection *GroupSec) {
GroupSec->setFlagWord(*Word++);
for (; Word != End; ++Word) {
uint32_t Index = support::endian::read32<ELFT::TargetEndianness>(Word);
- Expected<SectionBase *> Sec = SecTable.getSection(
+ Expected<SectionBase *> Sec = SecTable.getSection(
Index, "group member index " + Twine(Index) + " in section '" +
- GroupSec->Name + "' is invalid");
- if (!Sec)
- return Sec.takeError();
-
- GroupSec->addMember(*Sec);
+ GroupSec->Name + "' is invalid");
+ if (!Sec)
+ return Sec.takeError();
+
+ GroupSec->addMember(*Sec);
}
-
- return Error::success();
+
+ return Error::success();
}
template <class ELFT>
-Error ELFBuilder<ELFT>::initSymbolTable(SymbolTableSection *SymTab) {
- Expected<const Elf_Shdr *> Shdr = ElfFile.getSection(SymTab->Index);
- if (!Shdr)
- return Shdr.takeError();
-
- Expected<StringRef> StrTabData = ElfFile.getStringTableForSymtab(**Shdr);
- if (!StrTabData)
- return StrTabData.takeError();
-
+Error ELFBuilder<ELFT>::initSymbolTable(SymbolTableSection *SymTab) {
+ Expected<const Elf_Shdr *> Shdr = ElfFile.getSection(SymTab->Index);
+ if (!Shdr)
+ return Shdr.takeError();
+
+ Expected<StringRef> StrTabData = ElfFile.getStringTableForSymtab(**Shdr);
+ if (!StrTabData)
+ return StrTabData.takeError();
+
ArrayRef<Elf_Word> ShndxData;
- Expected<typename ELFFile<ELFT>::Elf_Sym_Range> Symbols =
- ElfFile.symbols(*Shdr);
- if (!Symbols)
- return Symbols.takeError();
-
- for (const typename ELFFile<ELFT>::Elf_Sym &Sym : *Symbols) {
+ Expected<typename ELFFile<ELFT>::Elf_Sym_Range> Symbols =
+ ElfFile.symbols(*Shdr);
+ if (!Symbols)
+ return Symbols.takeError();
+
+ for (const typename ELFFile<ELFT>::Elf_Sym &Sym : *Symbols) {
SectionBase *DefSection = nullptr;
- Expected<StringRef> Name = Sym.getName(*StrTabData);
- if (!Name)
- return Name.takeError();
-
+ Expected<StringRef> Name = Sym.getName(*StrTabData);
+ if (!Name)
+ return Name.takeError();
+
if (Sym.st_shndx == SHN_XINDEX) {
if (SymTab->getShndxTable() == nullptr)
- return createStringError(errc::invalid_argument,
- "symbol '" + *Name +
- "' has index SHN_XINDEX but no "
- "SHT_SYMTAB_SHNDX section exists");
+ return createStringError(errc::invalid_argument,
+ "symbol '" + *Name +
+ "' has index SHN_XINDEX but no "
+ "SHT_SYMTAB_SHNDX section exists");
if (ShndxData.data() == nullptr) {
- Expected<const Elf_Shdr *> ShndxSec =
- ElfFile.getSection(SymTab->getShndxTable()->Index);
- if (!ShndxSec)
- return ShndxSec.takeError();
-
- Expected<ArrayRef<Elf_Word>> Data =
- ElfFile.template getSectionContentsAsArray<Elf_Word>(**ShndxSec);
- if (!Data)
- return Data.takeError();
-
- ShndxData = *Data;
- if (ShndxData.size() != Symbols->size())
- return createStringError(
- errc::invalid_argument,
- "symbol section index table does not have the same number of "
- "entries as the symbol table");
+ Expected<const Elf_Shdr *> ShndxSec =
+ ElfFile.getSection(SymTab->getShndxTable()->Index);
+ if (!ShndxSec)
+ return ShndxSec.takeError();
+
+ Expected<ArrayRef<Elf_Word>> Data =
+ ElfFile.template getSectionContentsAsArray<Elf_Word>(**ShndxSec);
+ if (!Data)
+ return Data.takeError();
+
+ ShndxData = *Data;
+ if (ShndxData.size() != Symbols->size())
+ return createStringError(
+ errc::invalid_argument,
+ "symbol section index table does not have the same number of "
+ "entries as the symbol table");
}
- Elf_Word Index = ShndxData[&Sym - Symbols->begin()];
- Expected<SectionBase *> Sec = Obj.sections().getSection(
+ Elf_Word Index = ShndxData[&Sym - Symbols->begin()];
+ Expected<SectionBase *> Sec = Obj.sections().getSection(
Index,
- "symbol '" + *Name + "' has invalid section index " + Twine(Index));
- if (!Sec)
- return Sec.takeError();
-
- DefSection = *Sec;
+ "symbol '" + *Name + "' has invalid section index " + Twine(Index));
+ if (!Sec)
+ return Sec.takeError();
+
+ DefSection = *Sec;
} else if (Sym.st_shndx >= SHN_LORESERVE) {
if (!isValidReservedSectionIndex(Sym.st_shndx, Obj.Machine)) {
- return createStringError(
- errc::invalid_argument,
- "symbol '" + *Name +
- "' has unsupported value greater than or equal "
- "to SHN_LORESERVE: " +
- Twine(Sym.st_shndx));
+ return createStringError(
+ errc::invalid_argument,
+ "symbol '" + *Name +
+ "' has unsupported value greater than or equal "
+ "to SHN_LORESERVE: " +
+ Twine(Sym.st_shndx));
}
} else if (Sym.st_shndx != SHN_UNDEF) {
- Expected<SectionBase *> Sec = Obj.sections().getSection(
- Sym.st_shndx, "symbol '" + *Name +
+ Expected<SectionBase *> Sec = Obj.sections().getSection(
+ Sym.st_shndx, "symbol '" + *Name +
"' is defined has invalid section index " +
Twine(Sym.st_shndx));
- if (!Sec)
- return Sec.takeError();
-
- DefSection = *Sec;
+ if (!Sec)
+ return Sec.takeError();
+
+ DefSection = *Sec;
}
- SymTab->addSymbol(*Name, Sym.getBinding(), Sym.getType(), DefSection,
+ SymTab->addSymbol(*Name, Sym.getBinding(), Sym.getType(), DefSection,
Sym.getValue(), Sym.st_other, Sym.st_shndx, Sym.st_size);
}
-
- return Error::success();
+
+ return Error::success();
}
template <class ELFT>
-static void getAddend(uint64_t &, const Elf_Rel_Impl<ELFT, false> &) {}
+static void getAddend(uint64_t &, const Elf_Rel_Impl<ELFT, false> &) {}
template <class ELFT>
static void getAddend(uint64_t &ToSet, const Elf_Rel_Impl<ELFT, true> &Rela) {
@@ -1612,8 +1612,8 @@ static void getAddend(uint64_t &ToSet, const Elf_Rel_Impl<ELFT, true> &Rela) {
}
template <class T>
-static Error initRelocations(RelocationSection *Relocs,
- SymbolTableSection *SymbolTable, T RelRange) {
+static Error initRelocations(RelocationSection *Relocs,
+ SymbolTableSection *SymbolTable, T RelRange) {
for (const auto &Rel : RelRange) {
Relocation ToAdd;
ToAdd.Offset = Rel.r_offset;
@@ -1622,54 +1622,54 @@ static Error initRelocations(RelocationSection *Relocs,
if (uint32_t Sym = Rel.getSymbol(false)) {
if (!SymbolTable)
- return createStringError(
- errc::invalid_argument,
- "'" + Relocs->Name + "': relocation references symbol with index " +
- Twine(Sym) + ", but there is no symbol table");
- Expected<Symbol *> SymByIndex = SymbolTable->getSymbolByIndex(Sym);
- if (!SymByIndex)
- return SymByIndex.takeError();
-
- ToAdd.RelocSymbol = *SymByIndex;
+ return createStringError(
+ errc::invalid_argument,
+ "'" + Relocs->Name + "': relocation references symbol with index " +
+ Twine(Sym) + ", but there is no symbol table");
+ Expected<Symbol *> SymByIndex = SymbolTable->getSymbolByIndex(Sym);
+ if (!SymByIndex)
+ return SymByIndex.takeError();
+
+ ToAdd.RelocSymbol = *SymByIndex;
}
Relocs->addRelocation(ToAdd);
}
-
- return Error::success();
+
+ return Error::success();
}
-Expected<SectionBase *> SectionTableRef::getSection(uint32_t Index,
- Twine ErrMsg) {
+Expected<SectionBase *> SectionTableRef::getSection(uint32_t Index,
+ Twine ErrMsg) {
if (Index == SHN_UNDEF || Index > Sections.size())
- return createStringError(errc::invalid_argument, ErrMsg);
+ return createStringError(errc::invalid_argument, ErrMsg);
return Sections[Index - 1].get();
}
template <class T>
-Expected<T *> SectionTableRef::getSectionOfType(uint32_t Index,
- Twine IndexErrMsg,
- Twine TypeErrMsg) {
- Expected<SectionBase *> BaseSec = getSection(Index, IndexErrMsg);
- if (!BaseSec)
- return BaseSec.takeError();
-
- if (T *Sec = dyn_cast<T>(*BaseSec))
+Expected<T *> SectionTableRef::getSectionOfType(uint32_t Index,
+ Twine IndexErrMsg,
+ Twine TypeErrMsg) {
+ Expected<SectionBase *> BaseSec = getSection(Index, IndexErrMsg);
+ if (!BaseSec)
+ return BaseSec.takeError();
+
+ if (T *Sec = dyn_cast<T>(*BaseSec))
return Sec;
-
- return createStringError(errc::invalid_argument, TypeErrMsg);
+
+ return createStringError(errc::invalid_argument, TypeErrMsg);
}
template <class ELFT>
-Expected<SectionBase &> ELFBuilder<ELFT>::makeSection(const Elf_Shdr &Shdr) {
+Expected<SectionBase &> ELFBuilder<ELFT>::makeSection(const Elf_Shdr &Shdr) {
switch (Shdr.sh_type) {
case SHT_REL:
case SHT_RELA:
if (Shdr.sh_flags & SHF_ALLOC) {
- if (Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr))
- return Obj.addSection<DynamicRelocationSection>(*Data);
- else
- return Data.takeError();
+ if (Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr))
+ return Obj.addSection<DynamicRelocationSection>(*Data);
+ else
+ return Data.takeError();
}
return Obj.addSection<RelocationSection>();
case SHT_STRTAB:
@@ -1677,35 +1677,35 @@ Expected<SectionBase &> ELFBuilder<ELFT>::makeSection(const Elf_Shdr &Shdr) {
// mean altering the memory image. There are no special link types or
// anything so we can just use a Section.
if (Shdr.sh_flags & SHF_ALLOC) {
- if (Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr))
- return Obj.addSection<Section>(*Data);
- else
- return Data.takeError();
+ if (Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr))
+ return Obj.addSection<Section>(*Data);
+ else
+ return Data.takeError();
}
return Obj.addSection<StringTableSection>();
case SHT_HASH:
case SHT_GNU_HASH:
// Hash tables should refer to SHT_DYNSYM which we're not going to change.
// Because of this we don't need to mess with the hash tables either.
- if (Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr))
- return Obj.addSection<Section>(*Data);
- else
- return Data.takeError();
+ if (Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr))
+ return Obj.addSection<Section>(*Data);
+ else
+ return Data.takeError();
case SHT_GROUP:
- if (Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr))
- return Obj.addSection<GroupSection>(*Data);
- else
- return Data.takeError();
+ if (Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr))
+ return Obj.addSection<GroupSection>(*Data);
+ else
+ return Data.takeError();
case SHT_DYNSYM:
- if (Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr))
- return Obj.addSection<DynamicSymbolTableSection>(*Data);
- else
- return Data.takeError();
+ if (Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr))
+ return Obj.addSection<DynamicSymbolTableSection>(*Data);
+ else
+ return Data.takeError();
case SHT_DYNAMIC:
- if (Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr))
- return Obj.addSection<DynamicSection>(*Data);
- else
- return Data.takeError();
+ if (Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr))
+ return Obj.addSection<DynamicSection>(*Data);
+ else
+ return Data.takeError();
case SHT_SYMTAB: {
auto &SymTab = Obj.addSection<SymbolTableSection>();
Obj.SymbolTable = &SymTab;
@@ -1717,176 +1717,176 @@ Expected<SectionBase &> ELFBuilder<ELFT>::makeSection(const Elf_Shdr &Shdr) {
return ShndxSection;
}
case SHT_NOBITS:
- return Obj.addSection<Section>(ArrayRef<uint8_t>());
+ return Obj.addSection<Section>(ArrayRef<uint8_t>());
default: {
- Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr);
- if (!Data)
- return Data.takeError();
-
- Expected<StringRef> Name = ElfFile.getSectionName(Shdr);
- if (!Name)
- return Name.takeError();
-
- if (Name->startswith(".zdebug") || (Shdr.sh_flags & ELF::SHF_COMPRESSED)) {
+ Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr);
+ if (!Data)
+ return Data.takeError();
+
+ Expected<StringRef> Name = ElfFile.getSectionName(Shdr);
+ if (!Name)
+ return Name.takeError();
+
+ if (Name->startswith(".zdebug") || (Shdr.sh_flags & ELF::SHF_COMPRESSED)) {
uint64_t DecompressedSize, DecompressedAlign;
std::tie(DecompressedSize, DecompressedAlign) =
- getDecompressedSizeAndAlignment<ELFT>(*Data);
- Expected<CompressedSection> NewSection =
- CompressedSection::create(*Data, DecompressedSize, DecompressedAlign);
- if (!NewSection)
- return NewSection.takeError();
-
- return Obj.addSection<CompressedSection>(std::move(*NewSection));
+ getDecompressedSizeAndAlignment<ELFT>(*Data);
+ Expected<CompressedSection> NewSection =
+ CompressedSection::create(*Data, DecompressedSize, DecompressedAlign);
+ if (!NewSection)
+ return NewSection.takeError();
+
+ return Obj.addSection<CompressedSection>(std::move(*NewSection));
}
- return Obj.addSection<Section>(*Data);
+ return Obj.addSection<Section>(*Data);
}
}
}
-template <class ELFT> Error ELFBuilder<ELFT>::readSectionHeaders() {
+template <class ELFT> Error ELFBuilder<ELFT>::readSectionHeaders() {
uint32_t Index = 0;
- Expected<typename ELFFile<ELFT>::Elf_Shdr_Range> Sections =
- ElfFile.sections();
- if (!Sections)
- return Sections.takeError();
-
- for (const typename ELFFile<ELFT>::Elf_Shdr &Shdr : *Sections) {
+ Expected<typename ELFFile<ELFT>::Elf_Shdr_Range> Sections =
+ ElfFile.sections();
+ if (!Sections)
+ return Sections.takeError();
+
+ for (const typename ELFFile<ELFT>::Elf_Shdr &Shdr : *Sections) {
if (Index == 0) {
++Index;
continue;
}
- Expected<SectionBase &> Sec = makeSection(Shdr);
- if (!Sec)
- return Sec.takeError();
-
- Expected<StringRef> SecName = ElfFile.getSectionName(Shdr);
- if (!SecName)
- return SecName.takeError();
- Sec->Name = SecName->str();
- Sec->Type = Sec->OriginalType = Shdr.sh_type;
- Sec->Flags = Sec->OriginalFlags = Shdr.sh_flags;
- Sec->Addr = Shdr.sh_addr;
- Sec->Offset = Shdr.sh_offset;
- Sec->OriginalOffset = Shdr.sh_offset;
- Sec->Size = Shdr.sh_size;
- Sec->Link = Shdr.sh_link;
- Sec->Info = Shdr.sh_info;
- Sec->Align = Shdr.sh_addralign;
- Sec->EntrySize = Shdr.sh_entsize;
- Sec->Index = Index++;
- Sec->OriginalIndex = Sec->Index;
- Sec->OriginalData =
+ Expected<SectionBase &> Sec = makeSection(Shdr);
+ if (!Sec)
+ return Sec.takeError();
+
+ Expected<StringRef> SecName = ElfFile.getSectionName(Shdr);
+ if (!SecName)
+ return SecName.takeError();
+ Sec->Name = SecName->str();
+ Sec->Type = Sec->OriginalType = Shdr.sh_type;
+ Sec->Flags = Sec->OriginalFlags = Shdr.sh_flags;
+ Sec->Addr = Shdr.sh_addr;
+ Sec->Offset = Shdr.sh_offset;
+ Sec->OriginalOffset = Shdr.sh_offset;
+ Sec->Size = Shdr.sh_size;
+ Sec->Link = Shdr.sh_link;
+ Sec->Info = Shdr.sh_info;
+ Sec->Align = Shdr.sh_addralign;
+ Sec->EntrySize = Shdr.sh_entsize;
+ Sec->Index = Index++;
+ Sec->OriginalIndex = Sec->Index;
+ Sec->OriginalData =
ArrayRef<uint8_t>(ElfFile.base() + Shdr.sh_offset,
(Shdr.sh_type == SHT_NOBITS) ? 0 : Shdr.sh_size);
}
-
- return Error::success();
+
+ return Error::success();
}
-template <class ELFT> Error ELFBuilder<ELFT>::readSections(bool EnsureSymtab) {
- uint32_t ShstrIndex = ElfFile.getHeader().e_shstrndx;
- if (ShstrIndex == SHN_XINDEX) {
- Expected<const Elf_Shdr *> Sec = ElfFile.getSection(0);
- if (!Sec)
- return Sec.takeError();
+template <class ELFT> Error ELFBuilder<ELFT>::readSections(bool EnsureSymtab) {
+ uint32_t ShstrIndex = ElfFile.getHeader().e_shstrndx;
+ if (ShstrIndex == SHN_XINDEX) {
+ Expected<const Elf_Shdr *> Sec = ElfFile.getSection(0);
+ if (!Sec)
+ return Sec.takeError();
+
+ ShstrIndex = (*Sec)->sh_link;
+ }
- ShstrIndex = (*Sec)->sh_link;
- }
-
if (ShstrIndex == SHN_UNDEF)
Obj.HadShdrs = false;
- else {
- Expected<StringTableSection *> Sec =
+ else {
+ Expected<StringTableSection *> Sec =
Obj.sections().template getSectionOfType<StringTableSection>(
ShstrIndex,
"e_shstrndx field value " + Twine(ShstrIndex) + " in elf header " +
" is invalid",
"e_shstrndx field value " + Twine(ShstrIndex) + " in elf header " +
" does not reference a string table");
- if (!Sec)
- return Sec.takeError();
+ if (!Sec)
+ return Sec.takeError();
+
+ Obj.SectionNames = *Sec;
+ }
- Obj.SectionNames = *Sec;
- }
-
// If a section index table exists we'll need to initialize it before we
// initialize the symbol table because the symbol table might need to
// reference it.
if (Obj.SectionIndexTable)
- if (Error Err = Obj.SectionIndexTable->initialize(Obj.sections()))
- return Err;
+ if (Error Err = Obj.SectionIndexTable->initialize(Obj.sections()))
+ return Err;
// Now that all of the sections have been added we can fill out some extra
// details about symbol tables. We need the symbol table filled out before
// any relocations.
if (Obj.SymbolTable) {
- if (Error Err = Obj.SymbolTable->initialize(Obj.sections()))
- return Err;
- if (Error Err = initSymbolTable(Obj.SymbolTable))
- return Err;
+ if (Error Err = Obj.SymbolTable->initialize(Obj.sections()))
+ return Err;
+ if (Error Err = initSymbolTable(Obj.SymbolTable))
+ return Err;
} else if (EnsureSymtab) {
- if (Error Err = Obj.addNewSymbolTable())
- return Err;
+ if (Error Err = Obj.addNewSymbolTable())
+ return Err;
}
// Now that all sections and symbols have been added we can add
// relocations that reference symbols and set the link and info fields for
// relocation sections.
- for (SectionBase &Sec : Obj.sections()) {
+ for (SectionBase &Sec : Obj.sections()) {
if (&Sec == Obj.SymbolTable)
continue;
- if (Error Err = Sec.initialize(Obj.sections()))
- return Err;
+ if (Error Err = Sec.initialize(Obj.sections()))
+ return Err;
if (auto RelSec = dyn_cast<RelocationSection>(&Sec)) {
- Expected<typename ELFFile<ELFT>::Elf_Shdr_Range> Sections =
- ElfFile.sections();
- if (!Sections)
- return Sections.takeError();
-
- const typename ELFFile<ELFT>::Elf_Shdr *Shdr =
- Sections->begin() + RelSec->Index;
- if (RelSec->Type == SHT_REL) {
- Expected<typename ELFFile<ELFT>::Elf_Rel_Range> Rels =
- ElfFile.rels(*Shdr);
- if (!Rels)
- return Rels.takeError();
-
- if (Error Err = initRelocations(RelSec, Obj.SymbolTable, *Rels))
- return Err;
- } else {
- Expected<typename ELFFile<ELFT>::Elf_Rela_Range> Relas =
- ElfFile.relas(*Shdr);
- if (!Relas)
- return Relas.takeError();
-
- if (Error Err = initRelocations(RelSec, Obj.SymbolTable, *Relas))
- return Err;
- }
+ Expected<typename ELFFile<ELFT>::Elf_Shdr_Range> Sections =
+ ElfFile.sections();
+ if (!Sections)
+ return Sections.takeError();
+
+ const typename ELFFile<ELFT>::Elf_Shdr *Shdr =
+ Sections->begin() + RelSec->Index;
+ if (RelSec->Type == SHT_REL) {
+ Expected<typename ELFFile<ELFT>::Elf_Rel_Range> Rels =
+ ElfFile.rels(*Shdr);
+ if (!Rels)
+ return Rels.takeError();
+
+ if (Error Err = initRelocations(RelSec, Obj.SymbolTable, *Rels))
+ return Err;
+ } else {
+ Expected<typename ELFFile<ELFT>::Elf_Rela_Range> Relas =
+ ElfFile.relas(*Shdr);
+ if (!Relas)
+ return Relas.takeError();
+
+ if (Error Err = initRelocations(RelSec, Obj.SymbolTable, *Relas))
+ return Err;
+ }
} else if (auto GroupSec = dyn_cast<GroupSection>(&Sec)) {
- if (Error Err = initGroupSection(GroupSec))
- return Err;
+ if (Error Err = initGroupSection(GroupSec))
+ return Err;
}
}
-
- return Error::success();
+
+ return Error::success();
}
-template <class ELFT> Error ELFBuilder<ELFT>::build(bool EnsureSymtab) {
- if (Error E = readSectionHeaders())
- return E;
- if (Error E = findEhdrOffset())
- return E;
+template <class ELFT> Error ELFBuilder<ELFT>::build(bool EnsureSymtab) {
+ if (Error E = readSectionHeaders())
+ return E;
+ if (Error E = findEhdrOffset())
+ return E;
// The ELFFile whose ELF headers and program headers are copied into the
// output file. Normally the same as ElfFile, but if we're extracting a
// loadable partition it will point to the partition's headers.
- Expected<ELFFile<ELFT>> HeadersFile = ELFFile<ELFT>::create(toStringRef(
- {ElfFile.base() + EhdrOffset, ElfFile.getBufSize() - EhdrOffset}));
- if (!HeadersFile)
- return HeadersFile.takeError();
+ Expected<ELFFile<ELFT>> HeadersFile = ELFFile<ELFT>::create(toStringRef(
+ {ElfFile.base() + EhdrOffset, ElfFile.getBufSize() - EhdrOffset}));
+ if (!HeadersFile)
+ return HeadersFile.takeError();
- const typename ELFFile<ELFT>::Elf_Ehdr &Ehdr = HeadersFile->getHeader();
+ const typename ELFFile<ELFT>::Elf_Ehdr &Ehdr = HeadersFile->getHeader();
Obj.OSABI = Ehdr.e_ident[EI_OSABI];
Obj.ABIVersion = Ehdr.e_ident[EI_ABIVERSION];
Obj.Type = Ehdr.e_type;
@@ -1895,17 +1895,17 @@ template <class ELFT> Error ELFBuilder<ELFT>::build(bool EnsureSymtab) {
Obj.Entry = Ehdr.e_entry;
Obj.Flags = Ehdr.e_flags;
- if (Error E = readSections(EnsureSymtab))
- return E;
- return readProgramHeaders(*HeadersFile);
+ if (Error E = readSections(EnsureSymtab))
+ return E;
+ return readProgramHeaders(*HeadersFile);
}
Writer::~Writer() {}
Reader::~Reader() {}
-Expected<std::unique_ptr<Object>>
-BinaryReader::create(bool /*EnsureSymtab*/) const {
+Expected<std::unique_ptr<Object>>
+BinaryReader::create(bool /*EnsureSymtab*/) const {
return BinaryELFBuilder(MemBuf, NewSymbolVisibility).build();
}
@@ -1935,39 +1935,39 @@ Expected<std::vector<IHexRecord>> IHexReader::parse() const {
return std::move(Records);
}
-Expected<std::unique_ptr<Object>>
-IHexReader::create(bool /*EnsureSymtab*/) const {
- Expected<std::vector<IHexRecord>> Records = parse();
- if (!Records)
- return Records.takeError();
-
- return IHexELFBuilder(*Records).build();
+Expected<std::unique_ptr<Object>>
+IHexReader::create(bool /*EnsureSymtab*/) const {
+ Expected<std::vector<IHexRecord>> Records = parse();
+ if (!Records)
+ return Records.takeError();
+
+ return IHexELFBuilder(*Records).build();
}
-Expected<std::unique_ptr<Object>> ELFReader::create(bool EnsureSymtab) const {
+Expected<std::unique_ptr<Object>> ELFReader::create(bool EnsureSymtab) const {
auto Obj = std::make_unique<Object>();
if (auto *O = dyn_cast<ELFObjectFile<ELF32LE>>(Bin)) {
ELFBuilder<ELF32LE> Builder(*O, *Obj, ExtractPartition);
- if (Error Err = Builder.build(EnsureSymtab))
- return std::move(Err);
- return std::move(Obj);
+ if (Error Err = Builder.build(EnsureSymtab))
+ return std::move(Err);
+ return std::move(Obj);
} else if (auto *O = dyn_cast<ELFObjectFile<ELF64LE>>(Bin)) {
ELFBuilder<ELF64LE> Builder(*O, *Obj, ExtractPartition);
- if (Error Err = Builder.build(EnsureSymtab))
- return std::move(Err);
- return std::move(Obj);
+ if (Error Err = Builder.build(EnsureSymtab))
+ return std::move(Err);
+ return std::move(Obj);
} else if (auto *O = dyn_cast<ELFObjectFile<ELF32BE>>(Bin)) {
ELFBuilder<ELF32BE> Builder(*O, *Obj, ExtractPartition);
- if (Error Err = Builder.build(EnsureSymtab))
- return std::move(Err);
- return std::move(Obj);
+ if (Error Err = Builder.build(EnsureSymtab))
+ return std::move(Err);
+ return std::move(Obj);
} else if (auto *O = dyn_cast<ELFObjectFile<ELF64BE>>(Bin)) {
ELFBuilder<ELF64BE> Builder(*O, *Obj, ExtractPartition);
- if (Error Err = Builder.build(EnsureSymtab))
- return std::move(Err);
- return std::move(Obj);
+ if (Error Err = Builder.build(EnsureSymtab))
+ return std::move(Err);
+ return std::move(Obj);
}
- return createStringError(errc::invalid_argument, "invalid file type");
+ return createStringError(errc::invalid_argument, "invalid file type");
}
template <class ELFT> void ELFWriter<ELFT>::writeEhdr() {
@@ -2061,16 +2061,16 @@ template <class ELFT> void ELFWriter<ELFT>::writeShdrs() {
writeShdr(Sec);
}
-template <class ELFT> Error ELFWriter<ELFT>::writeSectionData() {
+template <class ELFT> Error ELFWriter<ELFT>::writeSectionData() {
for (SectionBase &Sec : Obj.sections())
// Segments are responsible for writing their contents, so only write the
// section data if the section is not in a segment. Note that this renders
// sections in segments effectively immutable.
if (Sec.ParentSegment == nullptr)
- if (Error Err = Sec.accept(*SecWriter))
- return Err;
-
- return Error::success();
+ if (Error Err = Sec.accept(*SecWriter))
+ return Err;
+
+ return Error::success();
}
template <class ELFT> void ELFWriter<ELFT>::writeSegmentData() {
@@ -2097,8 +2097,8 @@ ELFWriter<ELFT>::ELFWriter(Object &Obj, Buffer &Buf, bool WSH,
: Writer(Obj, Buf), WriteSectionHeaders(WSH && Obj.HadShdrs),
OnlyKeepDebug(OnlyKeepDebug) {}
-Error Object::removeSections(
- bool AllowBrokenLinks, std::function<bool(const SectionBase &)> ToRemove) {
+Error Object::removeSections(
+ bool AllowBrokenLinks, std::function<bool(const SectionBase &)> ToRemove) {
auto Iter = std::stable_partition(
std::begin(Sections), std::end(Sections), [=](const SecPtr &Sec) {
@@ -2134,8 +2134,8 @@ Error Object::removeSections(
// a live section critically depends on a section being removed somehow
// (e.g. the removed section is referenced by a relocation).
for (auto &KeepSec : make_range(std::begin(Sections), Iter)) {
- if (Error E = KeepSec->removeSectionReferences(
- AllowBrokenLinks, [&RemoveSections](const SectionBase *Sec) {
+ if (Error E = KeepSec->removeSectionReferences(
+ AllowBrokenLinks, [&RemoveSections](const SectionBase *Sec) {
return RemoveSections.find(Sec) != RemoveSections.end();
}))
return E;
@@ -2157,7 +2157,7 @@ Error Object::removeSymbols(function_ref<bool(const Symbol &)> ToRemove) {
return Error::success();
}
-Error Object::addNewSymbolTable() {
+Error Object::addNewSymbolTable() {
assert(!SymbolTable && "Object must not has a SymbolTable.");
// Reuse an existing SHT_STRTAB section if it exists.
@@ -2178,13 +2178,13 @@ Error Object::addNewSymbolTable() {
SymbolTableSection &SymTab = addSection<SymbolTableSection>();
SymTab.Name = ".symtab";
SymTab.Link = StrTab->Index;
- if (Error Err = SymTab.initialize(sections()))
- return Err;
+ if (Error Err = SymTab.initialize(sections()))
+ return Err;
SymTab.addSymbol("", 0, 0, nullptr, 0, 0, 0, 0);
SymbolTable = &SymTab;
-
- return Error::success();
+
+ return Error::success();
}
void Object::sortSections() {
@@ -2305,19 +2305,19 @@ static uint64_t layoutSectionsForOnlyKeepDebug(Object &Obj, uint64_t Off) {
return Off;
}
-// Rewrite p_offset and p_filesz of non-PT_PHDR segments after sh_offset values
-// have been updated.
+// Rewrite p_offset and p_filesz of non-PT_PHDR segments after sh_offset values
+// have been updated.
static uint64_t layoutSegmentsForOnlyKeepDebug(std::vector<Segment *> &Segments,
uint64_t HdrEnd) {
uint64_t MaxOffset = 0;
for (Segment *Seg : Segments) {
- // An empty segment contains no section (see sectionWithinSegment). If it
- // has a parent segment, copy the parent segment's offset field. This works
- // for empty PT_TLS. We don't handle empty segments without a parent for
- // now.
- if (Seg->ParentSegment != nullptr && Seg->MemSize == 0)
- Seg->Offset = Seg->ParentSegment->Offset;
-
+ // An empty segment contains no section (see sectionWithinSegment). If it
+ // has a parent segment, copy the parent segment's offset field. This works
+ // for empty PT_TLS. We don't handle empty segments without a parent for
+ // now.
+ if (Seg->ParentSegment != nullptr && Seg->MemSize == 0)
+ Seg->Offset = Seg->ParentSegment->Offset;
+
const SectionBase *FirstSec = Seg->firstSection();
if (Seg->Type == PT_PHDR || !FirstSec)
continue;
@@ -2405,8 +2405,8 @@ template <class ELFT> Error ELFWriter<ELFT>::write() {
writeSegmentData();
writeEhdr();
writePhdrs();
- if (Error E = writeSectionData())
- return E;
+ if (Error E = writeSectionData())
+ return E;
if (WriteSectionHeaders)
writeShdrs();
return Buf.commit();
@@ -2451,8 +2451,8 @@ template <class ELFT> Error ELFWriter<ELFT>::finalize() {
if (Obj.sections().size() >= SHN_LORESERVE) {
SectionTableRef Sections = Obj.sections();
NeedsLargeIndexes =
- any_of(drop_begin(Sections, SHN_LORESERVE),
- [](const SectionBase &Sec) { return Sec.HasSymbol; });
+ any_of(drop_begin(Sections, SHN_LORESERVE),
+ [](const SectionBase &Sec) { return Sec.HasSymbol; });
// TODO: handle case where only one section needs the large index table but
// only needs it because the large index table hasn't been removed yet.
}
@@ -2495,8 +2495,8 @@ template <class ELFT> Error ELFWriter<ELFT>::finalize() {
auto SecSizer = std::make_unique<ELFSectionSizer<ELFT>>();
for (SectionBase &Sec : Obj.sections()) {
Sec.Index = Index++;
- if (Error Err = Sec.accept(*SecSizer))
- return Err;
+ if (Error Err = Sec.accept(*SecSizer))
+ return Err;
}
// The symbol table does not update all other sections on update. For
@@ -2537,9 +2537,9 @@ template <class ELFT> Error ELFWriter<ELFT>::finalize() {
Error BinaryWriter::write() {
for (const SectionBase &Sec : Obj.allocSections())
- if (Error Err = Sec.accept(*SecWriter))
- return Err;
-
+ if (Error Err = Sec.accept(*SecWriter))
+ return Err;
+
return Buf.commit();
}
@@ -2611,8 +2611,8 @@ Error IHexWriter::write() {
IHexSectionWriter Writer(Buf);
// Write sections.
for (const SectionBase *Sec : Sections)
- if (Error Err = Sec->accept(Writer))
- return Err;
+ if (Error Err = Sec->accept(Writer))
+ return Err;
uint64_t Offset = Writer.getBufferOffset();
// Write entry point address.
@@ -2628,8 +2628,8 @@ Error IHexWriter::checkSection(const SectionBase &Sec) {
if (addressOverflows32bit(Addr) || addressOverflows32bit(Addr + Sec.Size - 1))
return createStringError(
errc::invalid_argument,
- "Section '%s' address range [0x%llx, 0x%llx] is not 32 bit",
- Sec.Name.c_str(), Addr, Addr + Sec.Size - 1);
+ "Section '%s' address range [0x%llx, 0x%llx] is not 32 bit",
+ Sec.Name.c_str(), Addr, Addr + Sec.Size - 1);
return Error::success();
}
@@ -2666,8 +2666,8 @@ Error IHexWriter::finalize() {
IHexSectionWriterBase LengthCalc(Buf);
for (const SectionBase *Sec : Sections)
- if (Error Err = Sec->accept(LengthCalc))
- return Err;
+ if (Error Err = Sec->accept(LengthCalc))
+ return Err;
// We need space to write section records + StartAddress record
// (if start adress is not zero) + EndOfFile record.
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/ELF/Object.h b/contrib/libs/llvm12/tools/llvm-objcopy/ELF/Object.h
index 01caa5d42a..0205c2d4f3 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/ELF/Object.h
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/ELF/Object.h
@@ -61,11 +61,11 @@ public:
iterator end() const { return iterator(Sections.data() + Sections.size()); }
size_t size() const { return Sections.size(); }
- Expected<SectionBase *> getSection(uint32_t Index, Twine ErrMsg);
+ Expected<SectionBase *> getSection(uint32_t Index, Twine ErrMsg);
template <class T>
- Expected<T *> getSectionOfType(uint32_t Index, Twine IndexErrMsg,
- Twine TypeErrMsg);
+ Expected<T *> getSectionOfType(uint32_t Index, Twine IndexErrMsg,
+ Twine TypeErrMsg);
};
enum ElfType { ELFT_ELF32LE, ELFT_ELF64LE, ELFT_ELF32BE, ELFT_ELF64BE };
@@ -74,34 +74,34 @@ class SectionVisitor {
public:
virtual ~SectionVisitor() = default;
- virtual Error visit(const Section &Sec) = 0;
- virtual Error visit(const OwnedDataSection &Sec) = 0;
- virtual Error visit(const StringTableSection &Sec) = 0;
- virtual Error visit(const SymbolTableSection &Sec) = 0;
- virtual Error visit(const RelocationSection &Sec) = 0;
- virtual Error visit(const DynamicRelocationSection &Sec) = 0;
- virtual Error visit(const GnuDebugLinkSection &Sec) = 0;
- virtual Error visit(const GroupSection &Sec) = 0;
- virtual Error visit(const SectionIndexSection &Sec) = 0;
- virtual Error visit(const CompressedSection &Sec) = 0;
- virtual Error visit(const DecompressedSection &Sec) = 0;
+ virtual Error visit(const Section &Sec) = 0;
+ virtual Error visit(const OwnedDataSection &Sec) = 0;
+ virtual Error visit(const StringTableSection &Sec) = 0;
+ virtual Error visit(const SymbolTableSection &Sec) = 0;
+ virtual Error visit(const RelocationSection &Sec) = 0;
+ virtual Error visit(const DynamicRelocationSection &Sec) = 0;
+ virtual Error visit(const GnuDebugLinkSection &Sec) = 0;
+ virtual Error visit(const GroupSection &Sec) = 0;
+ virtual Error visit(const SectionIndexSection &Sec) = 0;
+ virtual Error visit(const CompressedSection &Sec) = 0;
+ virtual Error visit(const DecompressedSection &Sec) = 0;
};
class MutableSectionVisitor {
public:
virtual ~MutableSectionVisitor() = default;
- virtual Error visit(Section &Sec) = 0;
- virtual Error visit(OwnedDataSection &Sec) = 0;
- virtual Error visit(StringTableSection &Sec) = 0;
- virtual Error visit(SymbolTableSection &Sec) = 0;
- virtual Error visit(RelocationSection &Sec) = 0;
- virtual Error visit(DynamicRelocationSection &Sec) = 0;
- virtual Error visit(GnuDebugLinkSection &Sec) = 0;
- virtual Error visit(GroupSection &Sec) = 0;
- virtual Error visit(SectionIndexSection &Sec) = 0;
- virtual Error visit(CompressedSection &Sec) = 0;
- virtual Error visit(DecompressedSection &Sec) = 0;
+ virtual Error visit(Section &Sec) = 0;
+ virtual Error visit(OwnedDataSection &Sec) = 0;
+ virtual Error visit(StringTableSection &Sec) = 0;
+ virtual Error visit(SymbolTableSection &Sec) = 0;
+ virtual Error visit(RelocationSection &Sec) = 0;
+ virtual Error visit(DynamicRelocationSection &Sec) = 0;
+ virtual Error visit(GnuDebugLinkSection &Sec) = 0;
+ virtual Error visit(GroupSection &Sec) = 0;
+ virtual Error visit(SectionIndexSection &Sec) = 0;
+ virtual Error visit(CompressedSection &Sec) = 0;
+ virtual Error visit(DecompressedSection &Sec) = 0;
};
class SectionWriter : public SectionVisitor {
@@ -111,17 +111,17 @@ protected:
public:
virtual ~SectionWriter() = default;
- Error visit(const Section &Sec) override;
- Error visit(const OwnedDataSection &Sec) override;
- Error visit(const StringTableSection &Sec) override;
- Error visit(const DynamicRelocationSection &Sec) override;
- virtual Error visit(const SymbolTableSection &Sec) override = 0;
- virtual Error visit(const RelocationSection &Sec) override = 0;
- virtual Error visit(const GnuDebugLinkSection &Sec) override = 0;
- virtual Error visit(const GroupSection &Sec) override = 0;
- virtual Error visit(const SectionIndexSection &Sec) override = 0;
- virtual Error visit(const CompressedSection &Sec) override = 0;
- virtual Error visit(const DecompressedSection &Sec) override = 0;
+ Error visit(const Section &Sec) override;
+ Error visit(const OwnedDataSection &Sec) override;
+ Error visit(const StringTableSection &Sec) override;
+ Error visit(const DynamicRelocationSection &Sec) override;
+ virtual Error visit(const SymbolTableSection &Sec) override = 0;
+ virtual Error visit(const RelocationSection &Sec) override = 0;
+ virtual Error visit(const GnuDebugLinkSection &Sec) override = 0;
+ virtual Error visit(const GroupSection &Sec) override = 0;
+ virtual Error visit(const SectionIndexSection &Sec) override = 0;
+ virtual Error visit(const CompressedSection &Sec) override = 0;
+ virtual Error visit(const DecompressedSection &Sec) override = 0;
explicit SectionWriter(Buffer &Buf) : Out(Buf) {}
};
@@ -135,13 +135,13 @@ private:
public:
virtual ~ELFSectionWriter() {}
- Error visit(const SymbolTableSection &Sec) override;
- Error visit(const RelocationSection &Sec) override;
- Error visit(const GnuDebugLinkSection &Sec) override;
- Error visit(const GroupSection &Sec) override;
- Error visit(const SectionIndexSection &Sec) override;
- Error visit(const CompressedSection &Sec) override;
- Error visit(const DecompressedSection &Sec) override;
+ Error visit(const SymbolTableSection &Sec) override;
+ Error visit(const RelocationSection &Sec) override;
+ Error visit(const GnuDebugLinkSection &Sec) override;
+ Error visit(const GroupSection &Sec) override;
+ Error visit(const SectionIndexSection &Sec) override;
+ Error visit(const CompressedSection &Sec) override;
+ Error visit(const DecompressedSection &Sec) override;
explicit ELFSectionWriter(Buffer &Buf) : SectionWriter(Buf) {}
};
@@ -155,17 +155,17 @@ private:
using Elf_Xword = typename ELFT::Xword;
public:
- Error visit(Section &Sec) override;
- Error visit(OwnedDataSection &Sec) override;
- Error visit(StringTableSection &Sec) override;
- Error visit(DynamicRelocationSection &Sec) override;
- Error visit(SymbolTableSection &Sec) override;
- Error visit(RelocationSection &Sec) override;
- Error visit(GnuDebugLinkSection &Sec) override;
- Error visit(GroupSection &Sec) override;
- Error visit(SectionIndexSection &Sec) override;
- Error visit(CompressedSection &Sec) override;
- Error visit(DecompressedSection &Sec) override;
+ Error visit(Section &Sec) override;
+ Error visit(OwnedDataSection &Sec) override;
+ Error visit(StringTableSection &Sec) override;
+ Error visit(DynamicRelocationSection &Sec) override;
+ Error visit(SymbolTableSection &Sec) override;
+ Error visit(RelocationSection &Sec) override;
+ Error visit(GnuDebugLinkSection &Sec) override;
+ Error visit(GroupSection &Sec) override;
+ Error visit(SectionIndexSection &Sec) override;
+ Error visit(CompressedSection &Sec) override;
+ Error visit(DecompressedSection &Sec) override;
};
#define MAKE_SEC_WRITER_FRIEND \
@@ -179,13 +179,13 @@ class BinarySectionWriter : public SectionWriter {
public:
virtual ~BinarySectionWriter() {}
- Error visit(const SymbolTableSection &Sec) override;
- Error visit(const RelocationSection &Sec) override;
- Error visit(const GnuDebugLinkSection &Sec) override;
- Error visit(const GroupSection &Sec) override;
- Error visit(const SectionIndexSection &Sec) override;
- Error visit(const CompressedSection &Sec) override;
- Error visit(const DecompressedSection &Sec) override;
+ Error visit(const SymbolTableSection &Sec) override;
+ Error visit(const RelocationSection &Sec) override;
+ Error visit(const GnuDebugLinkSection &Sec) override;
+ Error visit(const GroupSection &Sec) override;
+ Error visit(const SectionIndexSection &Sec) override;
+ Error visit(const CompressedSection &Sec) override;
+ Error visit(const DecompressedSection &Sec) override;
explicit BinarySectionWriter(Buffer &Buf) : SectionWriter(Buf) {}
};
@@ -286,10 +286,10 @@ public:
explicit IHexSectionWriterBase(Buffer &Buf) : BinarySectionWriter(Buf) {}
uint64_t getBufferOffset() const { return Offset; }
- Error visit(const Section &Sec) final;
- Error visit(const OwnedDataSection &Sec) final;
- Error visit(const StringTableSection &Sec) override;
- Error visit(const DynamicRelocationSection &Sec) final;
+ Error visit(const Section &Sec) final;
+ Error visit(const OwnedDataSection &Sec) final;
+ Error visit(const StringTableSection &Sec) override;
+ Error visit(const DynamicRelocationSection &Sec) final;
using BinarySectionWriter::visit;
};
@@ -299,7 +299,7 @@ public:
IHexSectionWriter(Buffer &Buf) : IHexSectionWriterBase(Buf) {}
void writeData(uint8_t Type, uint16_t Addr, ArrayRef<uint8_t> Data) override;
- Error visit(const StringTableSection &Sec) override;
+ Error visit(const StringTableSection &Sec) override;
};
class Writer {
@@ -330,7 +330,7 @@ private:
void writePhdrs();
void writeShdrs();
- Error writeSectionData();
+ Error writeSectionData();
void writeSegmentData();
void assignOffsets();
@@ -391,7 +391,7 @@ public:
uint64_t HeaderOffset = 0;
uint32_t Index = 0;
- uint32_t OriginalIndex = 0;
+ uint32_t OriginalIndex = 0;
uint64_t OriginalFlags = 0;
uint64_t OriginalType = ELF::SHT_NULL;
uint64_t OriginalOffset = std::numeric_limits<uint64_t>::max();
@@ -407,22 +407,22 @@ public:
uint64_t Size = 0;
uint64_t Type = ELF::SHT_NULL;
ArrayRef<uint8_t> OriginalData;
- bool HasSymbol = false;
+ bool HasSymbol = false;
SectionBase() = default;
SectionBase(const SectionBase &) = default;
virtual ~SectionBase() = default;
- virtual Error initialize(SectionTableRef SecTable);
+ virtual Error initialize(SectionTableRef SecTable);
virtual void finalize();
// Remove references to these sections. The list of sections must be sorted.
virtual Error
removeSectionReferences(bool AllowBrokenLinks,
function_ref<bool(const SectionBase *)> ToRemove);
virtual Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove);
- virtual Error accept(SectionVisitor &Visitor) const = 0;
- virtual Error accept(MutableSectionVisitor &Visitor) = 0;
+ virtual Error accept(SectionVisitor &Visitor) const = 0;
+ virtual Error accept(MutableSectionVisitor &Visitor) = 0;
virtual void markSymbols();
virtual void
replaceSectionReferences(const DenseMap<SectionBase *, SectionBase *> &);
@@ -436,9 +436,9 @@ private:
bool operator()(const SectionBase *Lhs, const SectionBase *Rhs) const {
// Some sections might have the same address if one of them is empty. To
// fix this we can use the lexicographic ordering on ->Addr and the
- // original index.
+ // original index.
if (Lhs->OriginalOffset == Rhs->OriginalOffset)
- return Lhs->OriginalIndex < Rhs->OriginalIndex;
+ return Lhs->OriginalIndex < Rhs->OriginalIndex;
return Lhs->OriginalOffset < Rhs->OriginalOffset;
}
};
@@ -483,12 +483,12 @@ class Section : public SectionBase {
public:
explicit Section(ArrayRef<uint8_t> Data) : Contents(Data) {}
- Error accept(SectionVisitor &Visitor) const override;
- Error accept(MutableSectionVisitor &Visitor) override;
- Error removeSectionReferences(
- bool AllowBrokenLinks,
+ Error accept(SectionVisitor &Visitor) const override;
+ Error accept(MutableSectionVisitor &Visitor) override;
+ Error removeSectionReferences(
+ bool AllowBrokenLinks,
function_ref<bool(const SectionBase *)> ToRemove) override;
- Error initialize(SectionTableRef SecTable) override;
+ Error initialize(SectionTableRef SecTable) override;
void finalize() override;
};
@@ -516,8 +516,8 @@ public:
}
void appendHexData(StringRef HexData);
- Error accept(SectionVisitor &Sec) const override;
- Error accept(MutableSectionVisitor &Visitor) override;
+ Error accept(SectionVisitor &Sec) const override;
+ Error accept(MutableSectionVisitor &Visitor) override;
};
class CompressedSection : public SectionBase {
@@ -529,28 +529,28 @@ class CompressedSection : public SectionBase {
SmallVector<char, 128> CompressedData;
public:
- static Expected<CompressedSection>
- create(const SectionBase &Sec, DebugCompressionType CompressionType);
- static Expected<CompressedSection> create(ArrayRef<uint8_t> CompressedData,
- uint64_t DecompressedSize,
- uint64_t DecompressedAlign);
+ static Expected<CompressedSection>
+ create(const SectionBase &Sec, DebugCompressionType CompressionType);
+ static Expected<CompressedSection> create(ArrayRef<uint8_t> CompressedData,
+ uint64_t DecompressedSize,
+ uint64_t DecompressedAlign);
uint64_t getDecompressedSize() const { return DecompressedSize; }
uint64_t getDecompressedAlign() const { return DecompressedAlign; }
- Error accept(SectionVisitor &Visitor) const override;
- Error accept(MutableSectionVisitor &Visitor) override;
+ Error accept(SectionVisitor &Visitor) const override;
+ Error accept(MutableSectionVisitor &Visitor) override;
static bool classof(const SectionBase *S) {
return (S->OriginalFlags & ELF::SHF_COMPRESSED) ||
(StringRef(S->Name).startswith(".zdebug"));
}
-
-private:
- CompressedSection(const SectionBase &Sec,
- DebugCompressionType CompressionType, Error &Err);
- CompressedSection(ArrayRef<uint8_t> CompressedData, uint64_t DecompressedSize,
- uint64_t DecompressedAlign);
+
+private:
+ CompressedSection(const SectionBase &Sec,
+ DebugCompressionType CompressionType, Error &Err);
+ CompressedSection(ArrayRef<uint8_t> CompressedData, uint64_t DecompressedSize,
+ uint64_t DecompressedAlign);
};
class DecompressedSection : public SectionBase {
@@ -566,8 +566,8 @@ public:
Name = "." + Name.substr(2);
}
- Error accept(SectionVisitor &Visitor) const override;
- Error accept(MutableSectionVisitor &Visitor) override;
+ Error accept(SectionVisitor &Visitor) const override;
+ Error accept(MutableSectionVisitor &Visitor) override;
};
// There are two types of string tables that can exist, dynamic and not dynamic.
@@ -591,8 +591,8 @@ public:
void addString(StringRef Name);
uint32_t findIndex(StringRef Name) const;
void prepareForLayout();
- Error accept(SectionVisitor &Visitor) const override;
- Error accept(MutableSectionVisitor &Visitor) override;
+ Error accept(SectionVisitor &Visitor) const override;
+ Error accept(MutableSectionVisitor &Visitor) override;
static bool classof(const SectionBase *S) {
if (S->OriginalFlags & ELF::SHF_ALLOC)
@@ -649,18 +649,18 @@ public:
virtual ~SectionIndexSection() {}
void addIndex(uint32_t Index) {
assert(Size > 0);
- Indexes.push_back(Index);
+ Indexes.push_back(Index);
}
void reserve(size_t NumSymbols) {
Indexes.reserve(NumSymbols);
Size = NumSymbols * 4;
- }
+ }
void setSymTab(SymbolTableSection *SymTab) { Symbols = SymTab; }
- Error initialize(SectionTableRef SecTable) override;
+ Error initialize(SectionTableRef SecTable) override;
void finalize() override;
- Error accept(SectionVisitor &Visitor) const override;
- Error accept(MutableSectionVisitor &Visitor) override;
+ Error accept(SectionVisitor &Visitor) const override;
+ Error accept(MutableSectionVisitor &Visitor) override;
SectionIndexSection() {
Name = ".symtab_shndx";
@@ -698,17 +698,17 @@ public:
const SectionIndexSection *getShndxTable() const { return SectionIndexTable; }
void fillShndxTable();
const SectionBase *getStrTab() const { return SymbolNames; }
- Expected<const Symbol *> getSymbolByIndex(uint32_t Index) const;
- Expected<Symbol *> getSymbolByIndex(uint32_t Index);
+ Expected<const Symbol *> getSymbolByIndex(uint32_t Index) const;
+ Expected<Symbol *> getSymbolByIndex(uint32_t Index);
void updateSymbols(function_ref<void(Symbol &)> Callable);
- Error removeSectionReferences(
- bool AllowBrokenLinks,
+ Error removeSectionReferences(
+ bool AllowBrokenLinks,
function_ref<bool(const SectionBase *)> ToRemove) override;
- Error initialize(SectionTableRef SecTable) override;
+ Error initialize(SectionTableRef SecTable) override;
void finalize() override;
- Error accept(SectionVisitor &Visitor) const override;
- Error accept(MutableSectionVisitor &Visitor) override;
+ Error accept(SectionVisitor &Visitor) const override;
+ Error accept(MutableSectionVisitor &Visitor) override;
Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
void replaceSectionReferences(
const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
@@ -759,7 +759,7 @@ protected:
SymTabType *Symbols = nullptr;
public:
- Error initialize(SectionTableRef SecTable) override;
+ Error initialize(SectionTableRef SecTable) override;
void finalize() override;
};
@@ -771,10 +771,10 @@ class RelocationSection
public:
void addRelocation(Relocation Rel) { Relocations.push_back(Rel); }
- Error accept(SectionVisitor &Visitor) const override;
- Error accept(MutableSectionVisitor &Visitor) override;
- Error removeSectionReferences(
- bool AllowBrokenLinks,
+ Error accept(SectionVisitor &Visitor) const override;
+ Error accept(MutableSectionVisitor &Visitor) override;
+ Error removeSectionReferences(
+ bool AllowBrokenLinks,
function_ref<bool(const SectionBase *)> ToRemove) override;
Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
void markSymbols() override;
@@ -810,8 +810,8 @@ public:
void setFlagWord(ELF::Elf32_Word W) { FlagWord = W; }
void addMember(SectionBase *Sec) { GroupMembers.push_back(Sec); }
- Error accept(SectionVisitor &) const override;
- Error accept(MutableSectionVisitor &Visitor) override;
+ Error accept(SectionVisitor &) const override;
+ Error accept(MutableSectionVisitor &Visitor) override;
void finalize() override;
Error removeSectionReferences(
bool AllowBrokenLinks,
@@ -855,8 +855,8 @@ private:
public:
explicit DynamicRelocationSection(ArrayRef<uint8_t> Data) : Contents(Data) {}
- Error accept(SectionVisitor &) const override;
- Error accept(MutableSectionVisitor &Visitor) override;
+ Error accept(SectionVisitor &) const override;
+ Error accept(MutableSectionVisitor &Visitor) override;
Error removeSectionReferences(
bool AllowBrokenLinks,
function_ref<bool(const SectionBase *)> ToRemove) override;
@@ -880,14 +880,14 @@ private:
public:
// If we add this section from an external source we can use this ctor.
explicit GnuDebugLinkSection(StringRef File, uint32_t PrecomputedCRC);
- Error accept(SectionVisitor &Visitor) const override;
- Error accept(MutableSectionVisitor &Visitor) override;
+ Error accept(SectionVisitor &Visitor) const override;
+ Error accept(MutableSectionVisitor &Visitor) override;
};
class Reader {
public:
virtual ~Reader();
- virtual Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const = 0;
+ virtual Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const = 0;
};
using object::Binary;
@@ -903,7 +903,7 @@ protected:
void initHeaderSegment();
StringTableSection *addStrTab();
SymbolTableSection *addSymTab(StringTableSection *StrTab);
- Error initSections();
+ Error initSections();
public:
BasicELFBuilder() : Obj(std::make_unique<Object>()) {}
@@ -919,7 +919,7 @@ public:
: BasicELFBuilder(), MemBuf(MB),
NewSymbolVisibility(NewSymbolVisibility) {}
- Expected<std::unique_ptr<Object>> build();
+ Expected<std::unique_ptr<Object>> build();
};
class IHexELFBuilder : public BasicELFBuilder {
@@ -931,7 +931,7 @@ public:
IHexELFBuilder(const std::vector<IHexRecord> &Records)
: BasicELFBuilder(), Records(Records) {}
- Expected<std::unique_ptr<Object>> build();
+ Expected<std::unique_ptr<Object>> build();
};
template <class ELFT> class ELFBuilder {
@@ -946,21 +946,21 @@ private:
Optional<StringRef> ExtractPartition;
void setParentSegment(Segment &Child);
- Error readProgramHeaders(const ELFFile<ELFT> &HeadersFile);
- Error initGroupSection(GroupSection *GroupSec);
- Error initSymbolTable(SymbolTableSection *SymTab);
- Error readSectionHeaders();
- Error readSections(bool EnsureSymtab);
- Error findEhdrOffset();
- Expected<SectionBase &> makeSection(const Elf_Shdr &Shdr);
+ Error readProgramHeaders(const ELFFile<ELFT> &HeadersFile);
+ Error initGroupSection(GroupSection *GroupSec);
+ Error initSymbolTable(SymbolTableSection *SymTab);
+ Error readSectionHeaders();
+ Error readSections(bool EnsureSymtab);
+ Error findEhdrOffset();
+ Expected<SectionBase &> makeSection(const Elf_Shdr &Shdr);
public:
ELFBuilder(const ELFObjectFile<ELFT> &ElfObj, Object &Obj,
Optional<StringRef> ExtractPartition)
- : ElfFile(ElfObj.getELFFile()), Obj(Obj),
+ : ElfFile(ElfObj.getELFFile()), Obj(Obj),
ExtractPartition(ExtractPartition) {}
- Error build(bool EnsureSymtab);
+ Error build(bool EnsureSymtab);
};
class BinaryReader : public Reader {
@@ -970,7 +970,7 @@ class BinaryReader : public Reader {
public:
BinaryReader(MemoryBuffer *MB, const uint8_t NewSymbolVisibility)
: MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {}
- Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
+ Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
};
class IHexReader : public Reader {
@@ -992,7 +992,7 @@ class IHexReader : public Reader {
public:
IHexReader(MemoryBuffer *MB) : MemBuf(MB) {}
- Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
+ Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
};
class ELFReader : public Reader {
@@ -1000,7 +1000,7 @@ class ELFReader : public Reader {
Optional<StringRef> ExtractPartition;
public:
- Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
+ Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
explicit ELFReader(Binary *B, Optional<StringRef> ExtractPartition)
: Bin(B), ExtractPartition(ExtractPartition) {}
};
@@ -1084,7 +1084,7 @@ public:
Ptr->Index = Sections.size();
return *Ptr;
}
- Error addNewSymbolTable();
+ Error addNewSymbolTable();
Segment &addSegment(ArrayRef<uint8_t> Data) {
Segments.emplace_back(std::make_unique<Segment>(Data));
return *Segments.back();
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/InstallNameToolOpts.td b/contrib/libs/llvm12/tools/llvm-objcopy/InstallNameToolOpts.td
index 6444425f2d..88dea84400 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/InstallNameToolOpts.td
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/InstallNameToolOpts.td
@@ -18,15 +18,15 @@ def h : Flag<["-"], "h">, Alias<help>;
def add_rpath : Option<["-", "--"], "add_rpath", KIND_SEPARATE>,
HelpText<"Add new rpath">;
-def prepend_rpath : Option<["-", "--"], "prepend_rpath", KIND_SEPARATE>,
- HelpText<"Add new rpath before other rpaths">;
-
+def prepend_rpath : Option<["-", "--"], "prepend_rpath", KIND_SEPARATE>,
+ HelpText<"Add new rpath before other rpaths">;
+
def delete_rpath: Option<["-", "--"], "delete_rpath", KIND_SEPARATE>,
HelpText<"Delete specified rpath">;
-def delete_all_rpaths: Flag<["-", "--"], "delete_all_rpaths">,
- HelpText<"Delete all rpath directives">;
-
+def delete_all_rpaths: Flag<["-", "--"], "delete_all_rpaths">,
+ HelpText<"Delete all rpath directives">;
+
def rpath: MultiArg<["-", "--"], "rpath", 2>,
HelpText<"Change rpath path name">;
@@ -38,7 +38,7 @@ def change: MultiArg<["-", "--"], "change", 2>,
def version : Flag<["--"], "version">,
HelpText<"Print the version and exit.">;
-
-def V : Flag<["-"], "V">,
- Alias<version>,
- HelpText<"Alias for --version">;
+
+def V : Flag<["-"], "V">,
+ Alias<version>,
+ HelpText<"Alias for --version">;
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp b/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp
index 849a1e4ea4..8e2bf36238 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp
@@ -15,14 +15,14 @@ namespace llvm {
namespace objcopy {
namespace macho {
-StringTableBuilder::Kind
-MachOLayoutBuilder::getStringTableBuilderKind(const Object &O, bool Is64Bit) {
- if (O.Header.FileType == MachO::HeaderFileType::MH_OBJECT)
- return Is64Bit ? StringTableBuilder::MachO64 : StringTableBuilder::MachO;
- return Is64Bit ? StringTableBuilder::MachO64Linked
- : StringTableBuilder::MachOLinked;
-}
-
+StringTableBuilder::Kind
+MachOLayoutBuilder::getStringTableBuilderKind(const Object &O, bool Is64Bit) {
+ if (O.Header.FileType == MachO::HeaderFileType::MH_OBJECT)
+ return Is64Bit ? StringTableBuilder::MachO64 : StringTableBuilder::MachO;
+ return Is64Bit ? StringTableBuilder::MachO64Linked
+ : StringTableBuilder::MachOLinked;
+}
+
uint32_t MachOLayoutBuilder::computeSizeOfCmds() const {
uint32_t Size = 0;
for (const LoadCommand &LC : O.LoadCommands) {
@@ -156,7 +156,7 @@ uint64_t MachOLayoutBuilder::layoutSegments() {
"Section's address cannot be smaller than Segment's one");
uint32_t SectOffset = Sec->Addr - SegmentVmAddr;
if (IsObjectFile) {
- if (!Sec->hasValidOffset()) {
+ if (!Sec->hasValidOffset()) {
Sec->Offset = 0;
} else {
uint64_t PaddingSize =
@@ -166,7 +166,7 @@ uint64_t MachOLayoutBuilder::layoutSegments() {
SegFileSize += PaddingSize + Sec->Size;
}
} else {
- if (!Sec->hasValidOffset()) {
+ if (!Sec->hasValidOffset()) {
Sec->Offset = 0;
} else {
Sec->Offset = SegOffset + SectOffset;
@@ -260,8 +260,8 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
sizeof(uint32_t) * O.IndirectSymTable.Symbols.size();
uint64_t StartOfCodeSignature =
StartOfSymbolStrings + StrTableBuilder.getSize();
- if (O.CodeSignatureCommandIndex)
- StartOfCodeSignature = alignTo(StartOfCodeSignature, 16);
+ if (O.CodeSignatureCommandIndex)
+ StartOfCodeSignature = alignTo(StartOfCodeSignature, 16);
uint64_t LinkEditSize =
(StartOfCodeSignature + O.CodeSignature.Data.size()) - StartOfLinkEdit;
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOLayoutBuilder.h b/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOLayoutBuilder.h
index 3b8d81cdf3..5fe6683e27 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOLayoutBuilder.h
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOLayoutBuilder.h
@@ -23,7 +23,7 @@ class MachOLayoutBuilder {
// Points to the __LINKEDIT segment if it exists.
MachO::macho_load_command *LinkEditLoadCommand = nullptr;
- StringTableBuilder StrTableBuilder;
+ StringTableBuilder StrTableBuilder;
uint32_t computeSizeOfCmds() const;
void constructStringTable();
@@ -33,13 +33,13 @@ class MachOLayoutBuilder {
uint64_t layoutRelocations(uint64_t Offset);
Error layoutTail(uint64_t Offset);
- static StringTableBuilder::Kind getStringTableBuilderKind(const Object &O,
- bool Is64Bit);
-
+ static StringTableBuilder::Kind getStringTableBuilderKind(const Object &O,
+ bool Is64Bit);
+
public:
MachOLayoutBuilder(Object &O, bool Is64Bit, uint64_t PageSize)
- : O(O), Is64Bit(Is64Bit), PageSize(PageSize),
- StrTableBuilder(getStringTableBuilderKind(O, Is64Bit)) {}
+ : O(O), Is64Bit(Is64Bit), PageSize(PageSize),
+ StrTableBuilder(getStringTableBuilderKind(O, Is64Bit)) {}
// Recomputes and updates fields in the given object such as file offsets.
Error layout();
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOObjcopy.cpp b/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
index 2af5b116d1..fef4a0ae55 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
@@ -8,13 +8,13 @@
#include "MachOObjcopy.h"
#include "../CopyConfig.h"
-#include "../llvm-objcopy.h"
+#include "../llvm-objcopy.h"
#include "MachOReader.h"
#include "MachOWriter.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/Object/ArchiveWriter.h"
-#include "llvm/Object/MachOUniversal.h"
-#include "llvm/Object/MachOUniversalWriter.h"
+#include "llvm/Object/ArchiveWriter.h"
+#include "llvm/Object/MachOUniversal.h"
+#include "llvm/Object/MachOUniversalWriter.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
@@ -137,14 +137,14 @@ static Error processLoadCommands(const CopyConfig &Config, Object &Obj) {
DenseSet<StringRef> RPathsToRemove(Config.RPathsToRemove.begin(),
Config.RPathsToRemove.end());
- LoadCommandPred RemovePred = [&RPathsToRemove,
- &Config](const LoadCommand &LC) {
+ LoadCommandPred RemovePred = [&RPathsToRemove,
+ &Config](const LoadCommand &LC) {
if (LC.MachOLoadCommand.load_command_data.cmd == MachO::LC_RPATH) {
- // When removing all RPaths we don't need to care
- // about what it contains
- if (Config.RemoveAllRpaths)
- return true;
-
+ // When removing all RPaths we don't need to care
+ // about what it contains
+ if (Config.RemoveAllRpaths)
+ return true;
+
StringRef RPath = getPayloadString(LC);
if (RPathsToRemove.count(RPath)) {
RPathsToRemove.erase(RPath);
@@ -178,22 +178,22 @@ static Error processLoadCommands(const CopyConfig &Config, Object &Obj) {
for (const auto &OldNew : Config.RPathsToUpdate) {
StringRef Old = OldNew.getFirst();
StringRef New = OldNew.getSecond();
- if (!RPaths.contains(Old))
+ if (!RPaths.contains(Old))
return createStringError(errc::invalid_argument,
"no LC_RPATH load command with path: " + Old);
- if (RPaths.contains(New))
+ if (RPaths.contains(New))
return createStringError(errc::invalid_argument,
- "rpath '" + New +
- "' would create a duplicate load command");
+ "rpath '" + New +
+ "' would create a duplicate load command");
}
// Update load commands.
for (LoadCommand &LC : Obj.LoadCommands) {
switch (LC.MachOLoadCommand.load_command_data.cmd) {
case MachO::LC_ID_DYLIB:
- if (Config.SharedLibId)
- updateLoadCommandPayloadString<MachO::dylib_command>(
- LC, *Config.SharedLibId);
+ if (Config.SharedLibId)
+ updateLoadCommandPayloadString<MachO::dylib_command>(
+ LC, *Config.SharedLibId);
break;
case MachO::LC_RPATH: {
@@ -220,30 +220,30 @@ static Error processLoadCommands(const CopyConfig &Config, Object &Obj) {
// Add new RPaths.
for (StringRef RPath : Config.RPathToAdd) {
- if (RPaths.contains(RPath))
+ if (RPaths.contains(RPath))
+ return createStringError(errc::invalid_argument,
+ "rpath '" + RPath +
+ "' would create a duplicate load command");
+ RPaths.insert(RPath);
+ Obj.LoadCommands.push_back(buildRPathLoadCommand(RPath));
+ }
+
+ for (StringRef RPath : Config.RPathToPrepend) {
+ if (RPaths.contains(RPath))
return createStringError(errc::invalid_argument,
- "rpath '" + RPath +
- "' would create a duplicate load command");
+ "rpath '" + RPath +
+ "' would create a duplicate load command");
+
RPaths.insert(RPath);
- Obj.LoadCommands.push_back(buildRPathLoadCommand(RPath));
+ Obj.LoadCommands.insert(Obj.LoadCommands.begin(),
+ buildRPathLoadCommand(RPath));
}
- for (StringRef RPath : Config.RPathToPrepend) {
- if (RPaths.contains(RPath))
- return createStringError(errc::invalid_argument,
- "rpath '" + RPath +
- "' would create a duplicate load command");
-
- RPaths.insert(RPath);
- Obj.LoadCommands.insert(Obj.LoadCommands.begin(),
- buildRPathLoadCommand(RPath));
- }
-
- // Unlike appending rpaths, the indexes of subsequent load commands must
- // be recalculated after prepending one.
- if (!Config.RPathToPrepend.empty())
- Obj.updateLoadCommandIndexes();
-
+ // Unlike appending rpaths, the indexes of subsequent load commands must
+ // be recalculated after prepending one.
+ if (!Config.RPathToPrepend.empty())
+ Obj.updateLoadCommandIndexes();
+
return Error::success();
}
@@ -280,34 +280,34 @@ static Error addSection(StringRef SecName, StringRef Filename, Object &Obj) {
StringRef TargetSegName = Pair.first;
Section Sec(TargetSegName, Pair.second);
Sec.Content = Obj.NewSectionsContents.save(Buf->getBuffer());
- Sec.Size = Sec.Content.size();
+ Sec.Size = Sec.Content.size();
// Add the a section into an existing segment.
for (LoadCommand &LC : Obj.LoadCommands) {
Optional<StringRef> SegName = LC.getSegmentName();
if (SegName && SegName == TargetSegName) {
- uint64_t Addr = *LC.getSegmentVMAddr();
- for (const std::unique_ptr<Section> &S : LC.Sections)
- Addr = std::max(Addr, S->Addr + S->Size);
+ uint64_t Addr = *LC.getSegmentVMAddr();
+ for (const std::unique_ptr<Section> &S : LC.Sections)
+ Addr = std::max(Addr, S->Addr + S->Size);
LC.Sections.push_back(std::make_unique<Section>(Sec));
- LC.Sections.back()->Addr = Addr;
+ LC.Sections.back()->Addr = Addr;
return Error::success();
}
}
// There's no segment named TargetSegName. Create a new load command and
// Insert a new section into it.
- LoadCommand &NewSegment =
- Obj.addSegment(TargetSegName, alignTo(Sec.Size, 16384));
+ LoadCommand &NewSegment =
+ Obj.addSegment(TargetSegName, alignTo(Sec.Size, 16384));
NewSegment.Sections.push_back(std::make_unique<Section>(Sec));
- NewSegment.Sections.back()->Addr = *NewSegment.getSegmentVMAddr();
+ NewSegment.Sections.back()->Addr = *NewSegment.getSegmentVMAddr();
return Error::success();
}
// isValidMachOCannonicalName returns success if Name is a MachO cannonical name
// ("<segment>,<section>") and lengths of both segment and section names are
// valid.
-static Error isValidMachOCannonicalName(StringRef Name) {
+static Error isValidMachOCannonicalName(StringRef Name) {
if (Name.count(',') != 1)
return createStringError(errc::invalid_argument,
"invalid section name '%s' (should be formatted "
@@ -340,7 +340,7 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
Config.ExtractDWO || Config.LocalizeHidden || Config.PreserveDates ||
Config.StripAllGNU || Config.StripDWO || Config.StripNonAlloc ||
Config.StripSections || Config.Weaken || Config.DecompressDebugSections ||
- Config.StripUnneeded || Config.DiscardMode == DiscardType::Locals ||
+ Config.StripUnneeded || Config.DiscardMode == DiscardType::Locals ||
!Config.SymbolsToAdd.empty() || Config.EntryExpr) {
return createStringError(llvm::errc::invalid_argument,
"option not supported by llvm-objcopy for MachO");
@@ -388,11 +388,11 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
Error executeObjcopyOnBinary(const CopyConfig &Config,
object::MachOObjectFile &In, Buffer &Out) {
MachOReader Reader(In);
- Expected<std::unique_ptr<Object>> O = Reader.create();
+ Expected<std::unique_ptr<Object>> O = Reader.create();
if (!O)
- return createFileError(Config.InputFilename, O.takeError());
+ return createFileError(Config.InputFilename, O.takeError());
- if (Error E = handleArgs(Config, **O))
+ if (Error E = handleArgs(Config, **O))
return createFileError(Config.InputFilename, std::move(E));
// Page size used for alignment of segment sizes in Mach-O executables and
@@ -408,81 +408,81 @@ Error executeObjcopyOnBinary(const CopyConfig &Config,
PageSize = 4096;
}
- MachOWriter Writer(**O, In.is64Bit(), In.isLittleEndian(), PageSize, Out);
+ MachOWriter Writer(**O, In.is64Bit(), In.isLittleEndian(), PageSize, Out);
if (auto E = Writer.finalize())
return E;
return Writer.write();
}
-Error executeObjcopyOnMachOUniversalBinary(CopyConfig &Config,
- const MachOUniversalBinary &In,
- Buffer &Out) {
- SmallVector<OwningBinary<Binary>, 2> Binaries;
- SmallVector<Slice, 2> Slices;
- for (const auto &O : In.objects()) {
- Expected<std::unique_ptr<Archive>> ArOrErr = O.getAsArchive();
- if (ArOrErr) {
- Expected<std::vector<NewArchiveMember>> NewArchiveMembersOrErr =
- createNewArchiveMembers(Config, **ArOrErr);
- if (!NewArchiveMembersOrErr)
- return NewArchiveMembersOrErr.takeError();
- Expected<std::unique_ptr<MemoryBuffer>> OutputBufferOrErr =
- writeArchiveToBuffer(*NewArchiveMembersOrErr,
- (*ArOrErr)->hasSymbolTable(), (*ArOrErr)->kind(),
- Config.DeterministicArchives,
- (*ArOrErr)->isThin());
- if (!OutputBufferOrErr)
- return OutputBufferOrErr.takeError();
- Expected<std::unique_ptr<Binary>> BinaryOrErr =
- object::createBinary(**OutputBufferOrErr);
- if (!BinaryOrErr)
- return BinaryOrErr.takeError();
- Binaries.emplace_back(std::move(*BinaryOrErr),
- std::move(*OutputBufferOrErr));
- Slices.emplace_back(*cast<Archive>(Binaries.back().getBinary()),
- O.getCPUType(), O.getCPUSubType(),
- O.getArchFlagName(), O.getAlign());
- continue;
- }
- // The methods getAsArchive, getAsObjectFile, getAsIRObject of the class
- // ObjectForArch return an Error in case of the type mismatch. We need to
- // check each in turn to see what kind of slice this is, so ignore errors
- // produced along the way.
- consumeError(ArOrErr.takeError());
-
- Expected<std::unique_ptr<MachOObjectFile>> ObjOrErr = O.getAsObjectFile();
- if (!ObjOrErr) {
- consumeError(ObjOrErr.takeError());
- return createStringError(std::errc::invalid_argument,
- "slice for '%s' of the universal Mach-O binary "
- "'%s' is not a Mach-O object or an archive",
- O.getArchFlagName().c_str(),
- Config.InputFilename.str().c_str());
- }
- std::string ArchFlagName = O.getArchFlagName();
- MemBuffer MB(ArchFlagName);
- if (Error E = executeObjcopyOnBinary(Config, **ObjOrErr, MB))
- return E;
- std::unique_ptr<WritableMemoryBuffer> OutputBuffer =
- MB.releaseMemoryBuffer();
- Expected<std::unique_ptr<Binary>> BinaryOrErr =
- object::createBinary(*OutputBuffer);
- if (!BinaryOrErr)
- return BinaryOrErr.takeError();
- Binaries.emplace_back(std::move(*BinaryOrErr), std::move(OutputBuffer));
- Slices.emplace_back(*cast<MachOObjectFile>(Binaries.back().getBinary()),
- O.getAlign());
- }
- Expected<std::unique_ptr<MemoryBuffer>> B =
- writeUniversalBinaryToBuffer(Slices);
- if (!B)
- return B.takeError();
- if (Error E = Out.allocate((*B)->getBufferSize()))
- return E;
- memcpy(Out.getBufferStart(), (*B)->getBufferStart(), (*B)->getBufferSize());
- return Out.commit();
-}
-
+Error executeObjcopyOnMachOUniversalBinary(CopyConfig &Config,
+ const MachOUniversalBinary &In,
+ Buffer &Out) {
+ SmallVector<OwningBinary<Binary>, 2> Binaries;
+ SmallVector<Slice, 2> Slices;
+ for (const auto &O : In.objects()) {
+ Expected<std::unique_ptr<Archive>> ArOrErr = O.getAsArchive();
+ if (ArOrErr) {
+ Expected<std::vector<NewArchiveMember>> NewArchiveMembersOrErr =
+ createNewArchiveMembers(Config, **ArOrErr);
+ if (!NewArchiveMembersOrErr)
+ return NewArchiveMembersOrErr.takeError();
+ Expected<std::unique_ptr<MemoryBuffer>> OutputBufferOrErr =
+ writeArchiveToBuffer(*NewArchiveMembersOrErr,
+ (*ArOrErr)->hasSymbolTable(), (*ArOrErr)->kind(),
+ Config.DeterministicArchives,
+ (*ArOrErr)->isThin());
+ if (!OutputBufferOrErr)
+ return OutputBufferOrErr.takeError();
+ Expected<std::unique_ptr<Binary>> BinaryOrErr =
+ object::createBinary(**OutputBufferOrErr);
+ if (!BinaryOrErr)
+ return BinaryOrErr.takeError();
+ Binaries.emplace_back(std::move(*BinaryOrErr),
+ std::move(*OutputBufferOrErr));
+ Slices.emplace_back(*cast<Archive>(Binaries.back().getBinary()),
+ O.getCPUType(), O.getCPUSubType(),
+ O.getArchFlagName(), O.getAlign());
+ continue;
+ }
+ // The methods getAsArchive, getAsObjectFile, getAsIRObject of the class
+ // ObjectForArch return an Error in case of the type mismatch. We need to
+ // check each in turn to see what kind of slice this is, so ignore errors
+ // produced along the way.
+ consumeError(ArOrErr.takeError());
+
+ Expected<std::unique_ptr<MachOObjectFile>> ObjOrErr = O.getAsObjectFile();
+ if (!ObjOrErr) {
+ consumeError(ObjOrErr.takeError());
+ return createStringError(std::errc::invalid_argument,
+ "slice for '%s' of the universal Mach-O binary "
+ "'%s' is not a Mach-O object or an archive",
+ O.getArchFlagName().c_str(),
+ Config.InputFilename.str().c_str());
+ }
+ std::string ArchFlagName = O.getArchFlagName();
+ MemBuffer MB(ArchFlagName);
+ if (Error E = executeObjcopyOnBinary(Config, **ObjOrErr, MB))
+ return E;
+ std::unique_ptr<WritableMemoryBuffer> OutputBuffer =
+ MB.releaseMemoryBuffer();
+ Expected<std::unique_ptr<Binary>> BinaryOrErr =
+ object::createBinary(*OutputBuffer);
+ if (!BinaryOrErr)
+ return BinaryOrErr.takeError();
+ Binaries.emplace_back(std::move(*BinaryOrErr), std::move(OutputBuffer));
+ Slices.emplace_back(*cast<MachOObjectFile>(Binaries.back().getBinary()),
+ O.getAlign());
+ }
+ Expected<std::unique_ptr<MemoryBuffer>> B =
+ writeUniversalBinaryToBuffer(Slices);
+ if (!B)
+ return B.takeError();
+ if (Error E = Out.allocate((*B)->getBufferSize()))
+ return E;
+ memcpy(Out.getBufferStart(), (*B)->getBufferStart(), (*B)->getBufferSize());
+ return Out.commit();
+}
+
} // end namespace macho
} // end namespace objcopy
} // end namespace llvm
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOObjcopy.h b/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOObjcopy.h
index e79db34e8b..c3f5391f79 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOObjcopy.h
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOObjcopy.h
@@ -24,10 +24,10 @@ class Buffer;
namespace macho {
Error executeObjcopyOnBinary(const CopyConfig &Config,
object::MachOObjectFile &In, Buffer &Out);
-
-Error executeObjcopyOnMachOUniversalBinary(
- CopyConfig &Config, const object::MachOUniversalBinary &In, Buffer &Out);
-
+
+Error executeObjcopyOnMachOUniversalBinary(
+ CopyConfig &Config, const object::MachOUniversalBinary &In, Buffer &Out);
+
} // end namespace macho
} // end namespace objcopy
} // end namespace llvm
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOReader.cpp b/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOReader.cpp
index 495d54046f..548a85bd49 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOReader.cpp
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOReader.cpp
@@ -10,7 +10,7 @@
#include "Object.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/Object/MachO.h"
-#include "llvm/Support/Errc.h"
+#include "llvm/Support/Errc.h"
#include <memory>
namespace llvm {
@@ -35,7 +35,7 @@ Section constructSectionCommon(SectionType Sec, uint32_t Index) {
S.Index = Index;
S.Addr = Sec.addr;
S.Size = Sec.size;
- S.OriginalOffset = Sec.offset;
+ S.OriginalOffset = Sec.offset;
S.Align = Sec.align;
S.RelOff = Sec.reloff;
S.NReloc = Sec.nreloc;
@@ -60,7 +60,7 @@ template <> Section constructSection(MachO::section_64 Sec, uint32_t Index) {
}
template <typename SectionType, typename SegmentType>
-Expected<std::vector<std::unique_ptr<Section>>>
+Expected<std::vector<std::unique_ptr<Section>>>
extractSections(const object::MachOObjectFile::LoadCommandInfo &LoadCmd,
const object::MachOObjectFile &MachOObj,
uint32_t &NextSectionIndex) {
@@ -85,16 +85,16 @@ extractSections(const object::MachOObjectFile::LoadCommandInfo &LoadCmd,
Expected<object::SectionRef> SecRef =
MachOObj.getSection(NextSectionIndex++);
if (!SecRef)
- return SecRef.takeError();
+ return SecRef.takeError();
- Expected<ArrayRef<uint8_t>> Data =
- MachOObj.getSectionContents(SecRef->getRawDataRefImpl());
- if (!Data)
- return Data.takeError();
+ Expected<ArrayRef<uint8_t>> Data =
+ MachOObj.getSectionContents(SecRef->getRawDataRefImpl());
+ if (!Data)
+ return Data.takeError();
+
+ S.Content =
+ StringRef(reinterpret_cast<const char *>(Data->data()), Data->size());
- S.Content =
- StringRef(reinterpret_cast<const char *>(Data->data()), Data->size());
-
S.Relocations.reserve(S.NReloc);
for (auto RI = MachOObj.section_rel_begin(SecRef->getRawDataRefImpl()),
RE = MachOObj.section_rel_end(SecRef->getRawDataRefImpl());
@@ -110,10 +110,10 @@ extractSections(const object::MachOObjectFile::LoadCommandInfo &LoadCmd,
assert(S.NReloc == S.Relocations.size() &&
"Incorrect number of relocations");
}
- return std::move(Sections);
+ return std::move(Sections);
}
-Error MachOReader::readLoadCommands(Object &O) const {
+Error MachOReader::readLoadCommands(Object &O) const {
// For MachO sections indices start from 1.
uint32_t NextSectionIndex = 1;
for (auto LoadCmd : MachOObj.load_commands()) {
@@ -123,20 +123,20 @@ Error MachOReader::readLoadCommands(Object &O) const {
O.CodeSignatureCommandIndex = O.LoadCommands.size();
break;
case MachO::LC_SEGMENT:
- if (Expected<std::vector<std::unique_ptr<Section>>> Sections =
- extractSections<MachO::section, MachO::segment_command>(
- LoadCmd, MachOObj, NextSectionIndex))
- LC.Sections = std::move(*Sections);
- else
- return Sections.takeError();
+ if (Expected<std::vector<std::unique_ptr<Section>>> Sections =
+ extractSections<MachO::section, MachO::segment_command>(
+ LoadCmd, MachOObj, NextSectionIndex))
+ LC.Sections = std::move(*Sections);
+ else
+ return Sections.takeError();
break;
case MachO::LC_SEGMENT_64:
- if (Expected<std::vector<std::unique_ptr<Section>>> Sections =
- extractSections<MachO::section_64, MachO::segment_command_64>(
- LoadCmd, MachOObj, NextSectionIndex))
- LC.Sections = std::move(*Sections);
- else
- return Sections.takeError();
+ if (Expected<std::vector<std::unique_ptr<Section>>> Sections =
+ extractSections<MachO::section_64, MachO::segment_command_64>(
+ LoadCmd, MachOObj, NextSectionIndex))
+ LC.Sections = std::move(*Sections);
+ else
+ return Sections.takeError();
break;
case MachO::LC_SYMTAB:
O.SymTabCommandIndex = O.LoadCommands.size();
@@ -184,7 +184,7 @@ Error MachOReader::readLoadCommands(Object &O) const {
}
O.LoadCommands.push_back(std::move(LC));
}
- return Error::success();
+ return Error::success();
}
template <typename nlist_t>
@@ -316,11 +316,11 @@ void MachOReader::readSwiftVersion(Object &O) const {
}
}
-Expected<std::unique_ptr<Object>> MachOReader::create() const {
+Expected<std::unique_ptr<Object>> MachOReader::create() const {
auto Obj = std::make_unique<Object>();
readHeader(*Obj);
- if (Error E = readLoadCommands(*Obj))
- return std::move(E);
+ if (Error E = readLoadCommands(*Obj))
+ return std::move(E);
readSymbolTable(*Obj);
setSymbolInRelocationInfo(*Obj);
readRebaseInfo(*Obj);
@@ -333,7 +333,7 @@ Expected<std::unique_ptr<Object>> MachOReader::create() const {
readFunctionStartsData(*Obj);
readIndirectSymbolTable(*Obj);
readSwiftVersion(*Obj);
- return std::move(Obj);
+ return std::move(Obj);
}
} // end namespace macho
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOReader.h b/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOReader.h
index c42e58d0da..b446e02865 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOReader.h
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOReader.h
@@ -21,14 +21,14 @@ namespace macho {
class Reader {
public:
virtual ~Reader(){};
- virtual Expected<std::unique_ptr<Object>> create() const = 0;
+ virtual Expected<std::unique_ptr<Object>> create() const = 0;
};
class MachOReader : public Reader {
const object::MachOObjectFile &MachOObj;
void readHeader(Object &O) const;
- Error readLoadCommands(Object &O) const;
+ Error readLoadCommands(Object &O) const;
void readSymbolTable(Object &O) const;
void setSymbolInRelocationInfo(Object &O) const;
void readRebaseInfo(Object &O) const;
@@ -46,7 +46,7 @@ class MachOReader : public Reader {
public:
explicit MachOReader(const object::MachOObjectFile &Obj) : MachOObj(Obj) {}
- Expected<std::unique_ptr<Object>> create() const override;
+ Expected<std::unique_ptr<Object>> create() const override;
};
} // end namespace macho
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOWriter.cpp b/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOWriter.cpp
index 7ff05ed9e0..56dd08df3b 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOWriter.cpp
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/MachO/MachOWriter.cpp
@@ -121,14 +121,14 @@ size_t MachOWriter::totalSize() const {
// Otherwise, use the last section / reloction.
for (const LoadCommand &LC : O.LoadCommands)
for (const std::unique_ptr<Section> &S : LC.Sections) {
- if (!S->hasValidOffset()) {
- assert((S->Offset == 0) && "Skipped section's offset must be zero");
- assert((S->isVirtualSection() || S->Size == 0) &&
- "Non-zero-fill sections with zero offset must have zero size");
- continue;
- }
- assert((S->Offset != 0) &&
- "Non-zero-fill section's offset cannot be zero");
+ if (!S->hasValidOffset()) {
+ assert((S->Offset == 0) && "Skipped section's offset must be zero");
+ assert((S->isVirtualSection() || S->Size == 0) &&
+ "Non-zero-fill sections with zero offset must have zero size");
+ continue;
+ }
+ assert((S->Offset != 0) &&
+ "Non-zero-fill section's offset cannot be zero");
Ends.push_back(S->Offset + S->Size);
if (S->RelOff)
Ends.push_back(S->RelOff +
@@ -248,12 +248,12 @@ void MachOWriter::writeSectionInLoadCommand(const Section &Sec, uint8_t *&Out) {
void MachOWriter::writeSections() {
for (const LoadCommand &LC : O.LoadCommands)
for (const std::unique_ptr<Section> &Sec : LC.Sections) {
- if (!Sec->hasValidOffset()) {
- assert((Sec->Offset == 0) && "Skipped section's offset must be zero");
- assert((Sec->isVirtualSection() || Sec->Size == 0) &&
- "Non-zero-fill sections with zero offset must have zero size");
+ if (!Sec->hasValidOffset()) {
+ assert((Sec->Offset == 0) && "Skipped section's offset must be zero");
+ assert((Sec->isVirtualSection() || Sec->Size == 0) &&
+ "Non-zero-fill sections with zero offset must have zero size");
continue;
- }
+ }
assert(Sec->Offset && "Section offset can not be zero");
assert((Sec->Size == Sec->Content.size()) && "Incorrect section size");
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/MachO/Object.cpp b/contrib/libs/llvm12/tools/llvm-objcopy/MachO/Object.cpp
index 1f7e04c14e..cdb97531fb 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/MachO/Object.cpp
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/MachO/Object.cpp
@@ -26,7 +26,7 @@ SymbolEntry *SymbolTable::getSymbolByIndex(uint32_t Index) {
void SymbolTable::removeSymbols(
function_ref<bool(const std::unique_ptr<SymbolEntry> &)> ToRemove) {
- llvm::erase_if(Symbols, ToRemove);
+ llvm::erase_if(Symbols, ToRemove);
}
void Object::updateLoadCommandIndexes() {
@@ -108,54 +108,54 @@ Error Object::removeSections(
return Error::success();
}
-uint64_t Object::nextAvailableSegmentAddress() const {
- uint64_t HeaderSize =
- is64Bit() ? sizeof(MachO::mach_header_64) : sizeof(MachO::mach_header);
- uint64_t Addr = HeaderSize + Header.SizeOfCmds;
- for (const LoadCommand &LC : LoadCommands) {
- const MachO::macho_load_command &MLC = LC.MachOLoadCommand;
- switch (MLC.load_command_data.cmd) {
- case MachO::LC_SEGMENT:
- Addr = std::max(Addr,
- static_cast<uint64_t>(MLC.segment_command_data.vmaddr) +
- MLC.segment_command_data.vmsize);
- break;
- case MachO::LC_SEGMENT_64:
- Addr = std::max(Addr, MLC.segment_command_64_data.vmaddr +
- MLC.segment_command_64_data.vmsize);
- break;
- default:
- continue;
- }
- }
- return Addr;
+uint64_t Object::nextAvailableSegmentAddress() const {
+ uint64_t HeaderSize =
+ is64Bit() ? sizeof(MachO::mach_header_64) : sizeof(MachO::mach_header);
+ uint64_t Addr = HeaderSize + Header.SizeOfCmds;
+ for (const LoadCommand &LC : LoadCommands) {
+ const MachO::macho_load_command &MLC = LC.MachOLoadCommand;
+ switch (MLC.load_command_data.cmd) {
+ case MachO::LC_SEGMENT:
+ Addr = std::max(Addr,
+ static_cast<uint64_t>(MLC.segment_command_data.vmaddr) +
+ MLC.segment_command_data.vmsize);
+ break;
+ case MachO::LC_SEGMENT_64:
+ Addr = std::max(Addr, MLC.segment_command_64_data.vmaddr +
+ MLC.segment_command_64_data.vmsize);
+ break;
+ default:
+ continue;
+ }
+ }
+ return Addr;
}
template <typename SegmentType>
-static void
-constructSegment(SegmentType &Seg, llvm::MachO::LoadCommandType CmdType,
- StringRef SegName, uint64_t SegVMAddr, uint64_t SegVMSize) {
+static void
+constructSegment(SegmentType &Seg, llvm::MachO::LoadCommandType CmdType,
+ StringRef SegName, uint64_t SegVMAddr, uint64_t SegVMSize) {
assert(SegName.size() <= sizeof(Seg.segname) && "too long segment name");
memset(&Seg, 0, sizeof(SegmentType));
Seg.cmd = CmdType;
strncpy(Seg.segname, SegName.data(), SegName.size());
- Seg.maxprot |=
- (MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE);
- Seg.initprot |=
- (MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE);
- Seg.vmaddr = SegVMAddr;
- Seg.vmsize = SegVMSize;
+ Seg.maxprot |=
+ (MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE);
+ Seg.initprot |=
+ (MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE);
+ Seg.vmaddr = SegVMAddr;
+ Seg.vmsize = SegVMSize;
}
-LoadCommand &Object::addSegment(StringRef SegName, uint64_t SegVMSize) {
+LoadCommand &Object::addSegment(StringRef SegName, uint64_t SegVMSize) {
LoadCommand LC;
- const uint64_t SegVMAddr = nextAvailableSegmentAddress();
+ const uint64_t SegVMAddr = nextAvailableSegmentAddress();
if (is64Bit())
constructSegment(LC.MachOLoadCommand.segment_command_64_data,
- MachO::LC_SEGMENT_64, SegName, SegVMAddr, SegVMSize);
+ MachO::LC_SEGMENT_64, SegName, SegVMAddr, SegVMSize);
else
constructSegment(LC.MachOLoadCommand.segment_command_data,
- MachO::LC_SEGMENT, SegName, SegVMAddr, SegVMSize);
+ MachO::LC_SEGMENT, SegName, SegVMAddr, SegVMSize);
LoadCommands.push_back(std::move(LC));
return LoadCommands.back();
@@ -179,18 +179,18 @@ Optional<StringRef> LoadCommand::getSegmentName() const {
}
}
-Optional<uint64_t> LoadCommand::getSegmentVMAddr() const {
- const MachO::macho_load_command &MLC = MachOLoadCommand;
- switch (MLC.load_command_data.cmd) {
- case MachO::LC_SEGMENT:
- return MLC.segment_command_data.vmaddr;
- case MachO::LC_SEGMENT_64:
- return MLC.segment_command_64_data.vmaddr;
- default:
- return None;
- }
-}
-
+Optional<uint64_t> LoadCommand::getSegmentVMAddr() const {
+ const MachO::macho_load_command &MLC = MachOLoadCommand;
+ switch (MLC.load_command_data.cmd) {
+ case MachO::LC_SEGMENT:
+ return MLC.segment_command_data.vmaddr;
+ case MachO::LC_SEGMENT_64:
+ return MLC.segment_command_64_data.vmaddr;
+ default:
+ return None;
+ }
+}
+
} // end namespace macho
} // end namespace objcopy
} // end namespace llvm
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/MachO/Object.h b/contrib/libs/llvm12/tools/llvm-objcopy/MachO/Object.h
index 111023017d..0bb4b344b2 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/MachO/Object.h
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/MachO/Object.h
@@ -44,8 +44,8 @@ struct Section {
std::string CanonicalName;
uint64_t Addr = 0;
uint64_t Size = 0;
- // Offset in the input file.
- Optional<uint32_t> OriginalOffset;
+ // Offset in the input file.
+ Optional<uint32_t> OriginalOffset;
uint32_t Offset = 0;
uint32_t Align = 0;
uint32_t RelOff = 0;
@@ -75,10 +75,10 @@ struct Section {
getType() == MachO::S_GB_ZEROFILL ||
getType() == MachO::S_THREAD_LOCAL_ZEROFILL);
}
-
- bool hasValidOffset() const {
- return !(isVirtualSection() || (OriginalOffset && *OriginalOffset == 0));
- }
+
+ bool hasValidOffset() const {
+ return !(isVirtualSection() || (OriginalOffset && *OriginalOffset == 0));
+ }
};
struct LoadCommand {
@@ -100,9 +100,9 @@ struct LoadCommand {
// Returns the segment name if the load command is a segment command.
Optional<StringRef> getSegmentName() const;
-
- // Returns the segment vm address if the load command is a segment command.
- Optional<uint64_t> getSegmentVMAddr() const;
+
+ // Returns the segment vm address if the load command is a segment command.
+ Optional<uint64_t> getSegmentVMAddr() const;
};
// A symbol information. Fields which starts with "n_" are same as them in the
@@ -343,14 +343,14 @@ struct Object {
/// Creates a new segment load command in the object and returns a reference
/// to the newly created load command. The caller should verify that SegName
/// is not too long (SegName.size() should be less than or equal to 16).
- LoadCommand &addSegment(StringRef SegName, uint64_t SegVMSize);
+ LoadCommand &addSegment(StringRef SegName, uint64_t SegVMSize);
bool is64Bit() const {
return Header.Magic == MachO::MH_MAGIC_64 ||
Header.Magic == MachO::MH_CIGAM_64;
}
-
- uint64_t nextAvailableSegmentAddress() const;
+
+ uint64_t nextAvailableSegmentAddress() const;
};
} // end namespace macho
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/llvm-objcopy.cpp b/contrib/libs/llvm12/tools/llvm-objcopy/llvm-objcopy.cpp
index 5d1366cad7..7fd2acd11e 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/llvm-objcopy.cpp
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/llvm-objcopy.cpp
@@ -25,7 +25,7 @@
#include "llvm/Object/ELFTypes.h"
#include "llvm/Object/Error.h"
#include "llvm/Object/MachO.h"
-#include "llvm/Object/MachOUniversal.h"
+#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/Wasm.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
@@ -57,34 +57,34 @@ namespace objcopy {
// The name this program was invoked as.
StringRef ToolName;
-ErrorSuccess reportWarning(Error E) {
+ErrorSuccess reportWarning(Error E) {
assert(E);
- WithColor::warning(errs(), ToolName) << toString(std::move(E)) << '\n';
- return Error::success();
+ WithColor::warning(errs(), ToolName) << toString(std::move(E)) << '\n';
+ return Error::success();
}
-static Expected<DriverConfig> getDriverConfig(ArrayRef<const char *> Args) {
- StringRef Stem = sys::path::stem(ToolName);
- auto Is = [=](StringRef Tool) {
- // We need to recognize the following filenames:
- //
- // llvm-objcopy -> objcopy
- // strip-10.exe -> strip
- // powerpc64-unknown-freebsd13-objcopy -> objcopy
- // llvm-install-name-tool -> install-name-tool
- auto I = Stem.rfind_lower(Tool);
- return I != StringRef::npos &&
- (I + Tool.size() == Stem.size() || !isAlnum(Stem[I + Tool.size()]));
- };
-
- if (Is("bitcode-strip") || Is("bitcode_strip"))
- return parseBitcodeStripOptions(Args);
- else if (Is("strip"))
- return parseStripOptions(Args, reportWarning);
- else if (Is("install-name-tool") || Is("install_name_tool"))
- return parseInstallNameToolOptions(Args);
- else
- return parseObjcopyOptions(Args, reportWarning);
+static Expected<DriverConfig> getDriverConfig(ArrayRef<const char *> Args) {
+ StringRef Stem = sys::path::stem(ToolName);
+ auto Is = [=](StringRef Tool) {
+ // We need to recognize the following filenames:
+ //
+ // llvm-objcopy -> objcopy
+ // strip-10.exe -> strip
+ // powerpc64-unknown-freebsd13-objcopy -> objcopy
+ // llvm-install-name-tool -> install-name-tool
+ auto I = Stem.rfind_lower(Tool);
+ return I != StringRef::npos &&
+ (I + Tool.size() == Stem.size() || !isAlnum(Stem[I + Tool.size()]));
+ };
+
+ if (Is("bitcode-strip") || Is("bitcode_strip"))
+ return parseBitcodeStripOptions(Args);
+ else if (Is("strip"))
+ return parseStripOptions(Args, reportWarning);
+ else if (Is("install-name-tool") || Is("install_name_tool"))
+ return parseInstallNameToolOptions(Args);
+ else
+ return parseObjcopyOptions(Args, reportWarning);
}
} // end namespace objcopy
@@ -169,10 +169,10 @@ static Error executeObjcopyOnBinary(CopyConfig &Config, object::Binary &In,
return coff::executeObjcopyOnBinary(Config, *COFFBinary, Out);
else if (auto *MachOBinary = dyn_cast<object::MachOObjectFile>(&In))
return macho::executeObjcopyOnBinary(Config, *MachOBinary, Out);
- else if (auto *MachOUniversalBinary =
- dyn_cast<object::MachOUniversalBinary>(&In))
- return macho::executeObjcopyOnMachOUniversalBinary(
- Config, *MachOUniversalBinary, Out);
+ else if (auto *MachOUniversalBinary =
+ dyn_cast<object::MachOUniversalBinary>(&In))
+ return macho::executeObjcopyOnMachOUniversalBinary(
+ Config, *MachOUniversalBinary, Out);
else if (auto *WasmBinary = dyn_cast<object::WasmObjectFile>(&In))
return objcopy::wasm::executeObjcopyOnBinary(Config, *WasmBinary, Out);
else
@@ -180,11 +180,11 @@ static Error executeObjcopyOnBinary(CopyConfig &Config, object::Binary &In,
"unsupported object file format");
}
-namespace llvm {
-namespace objcopy {
-
-Expected<std::vector<NewArchiveMember>>
-createNewArchiveMembers(CopyConfig &Config, const Archive &Ar) {
+namespace llvm {
+namespace objcopy {
+
+Expected<std::vector<NewArchiveMember>>
+createNewArchiveMembers(CopyConfig &Config, const Archive &Ar) {
std::vector<NewArchiveMember> NewArchiveMembers;
Error Err = Error::success();
for (const Archive::Child &Child : Ar.children(Err)) {
@@ -199,7 +199,7 @@ createNewArchiveMembers(CopyConfig &Config, const Archive &Ar) {
MemBuffer MB(ChildNameOrErr.get());
if (Error E = executeObjcopyOnBinary(Config, *ChildOrErr->get(), MB))
- return std::move(E);
+ return std::move(E);
Expected<NewArchiveMember> Member =
NewArchiveMember::getOldMember(Child, Config.DeterministicArchives);
@@ -211,19 +211,19 @@ createNewArchiveMembers(CopyConfig &Config, const Archive &Ar) {
}
if (Err)
return createFileError(Config.InputFilename, std::move(Err));
- return std::move(NewArchiveMembers);
-}
-
-} // end namespace objcopy
-} // end namespace llvm
-
-static Error executeObjcopyOnArchive(CopyConfig &Config,
- const object::Archive &Ar) {
- Expected<std::vector<NewArchiveMember>> NewArchiveMembersOrErr =
- createNewArchiveMembers(Config, Ar);
- if (!NewArchiveMembersOrErr)
- return NewArchiveMembersOrErr.takeError();
- return deepWriteArchive(Config.OutputFilename, *NewArchiveMembersOrErr,
+ return std::move(NewArchiveMembers);
+}
+
+} // end namespace objcopy
+} // end namespace llvm
+
+static Error executeObjcopyOnArchive(CopyConfig &Config,
+ const object::Archive &Ar) {
+ Expected<std::vector<NewArchiveMember>> NewArchiveMembersOrErr =
+ createNewArchiveMembers(Config, Ar);
+ if (!NewArchiveMembersOrErr)
+ return NewArchiveMembersOrErr.takeError();
+ return deepWriteArchive(Config.OutputFilename, *NewArchiveMembersOrErr,
Ar.hasSymbolTable(), Ar.kind(),
Config.DeterministicArchives, Ar.isThin());
}
@@ -353,8 +353,8 @@ int main(int argc, char **argv) {
NewArgv);
auto Args = makeArrayRef(NewArgv).drop_front();
- Expected<DriverConfig> DriverConfig = getDriverConfig(Args);
-
+ Expected<DriverConfig> DriverConfig = getDriverConfig(Args);
+
if (!DriverConfig) {
logAllUnhandledErrors(DriverConfig.takeError(),
WithColor::error(errs(), ToolName));
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/llvm-objcopy.h b/contrib/libs/llvm12/tools/llvm-objcopy/llvm-objcopy.h
index fa9fa4c1a5..97a166769f 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/llvm-objcopy.h
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/llvm-objcopy.h
@@ -13,19 +13,19 @@
namespace llvm {
-struct NewArchiveMember;
-
-namespace object {
-
-class Archive;
-
-} // end namespace object
-
-namespace objcopy {
-struct CopyConfig;
-Expected<std::vector<NewArchiveMember>>
-createNewArchiveMembers(CopyConfig &Config, const object::Archive &Ar);
-
+struct NewArchiveMember;
+
+namespace object {
+
+class Archive;
+
+} // end namespace object
+
+namespace objcopy {
+struct CopyConfig;
+Expected<std::vector<NewArchiveMember>>
+createNewArchiveMembers(CopyConfig &Config, const object::Archive &Ar);
+
} // end namespace objcopy
} // end namespace llvm
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/wasm/Object.cpp b/contrib/libs/llvm12/tools/llvm-objcopy/wasm/Object.cpp
index 3e39e16f15..e7a2956fed 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/wasm/Object.cpp
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/wasm/Object.cpp
@@ -26,7 +26,7 @@ void Object::addSectionWithOwnedContents(
void Object::removeSections(function_ref<bool(const Section &)> ToRemove) {
// TODO: remove reloc sections for the removed section, handle symbols, etc.
- llvm::erase_if(Sections, ToRemove);
+ llvm::erase_if(Sections, ToRemove);
}
} // end namespace wasm
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/ya.make b/contrib/libs/llvm12/tools/llvm-objcopy/ya.make
index 461adedfd6..13845f4bfa 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/ya.make
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/ya.make
@@ -12,25 +12,25 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/Bitcode/Reader
- contrib/libs/llvm12/lib/Bitstream/Reader
- contrib/libs/llvm12/lib/Demangle
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/MC/MCParser
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/Option
- contrib/libs/llvm12/lib/Remarks
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/TextAPI/MachO
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/Bitcode/Reader
+ contrib/libs/llvm12/lib/Bitstream/Reader
+ contrib/libs/llvm12/lib/Demangle
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/MC/MCParser
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/Option
+ contrib/libs/llvm12/lib/Remarks
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/TextAPI/MachO
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-objcopy
- contrib/libs/llvm12/tools/llvm-objcopy
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-objcopy
+ contrib/libs/llvm12/tools/llvm-objcopy
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/tools/llvm-rc/Opts.td b/contrib/libs/llvm12/tools/llvm-rc/Opts.td
index 065fb3f7cd..613f0a0db3 100644
--- a/contrib/libs/llvm12/tools/llvm-rc/Opts.td
+++ b/contrib/libs/llvm12/tools/llvm-rc/Opts.td
@@ -4,55 +4,55 @@ include "llvm/Option/OptParser.td"
// These options seem to be important for the tool
// and should be implemented.
-def fileout : JoinedOrSeparate<[ "/", "-" ], "FO">,
+def fileout : JoinedOrSeparate<[ "/", "-" ], "FO">,
HelpText<"Change the output file location.">;
-def define : Separate<[ "/", "-" ], "D">,
+def define : Separate<[ "/", "-" ], "D">,
HelpText<"Define a symbol for the C preprocessor.">;
-def undef : Separate<[ "/", "-" ], "U">,
+def undef : Separate<[ "/", "-" ], "U">,
HelpText<"Undefine a symbol for the C preprocessor.">;
-def lang_id : JoinedOrSeparate<[ "/", "-" ], "L">,
+def lang_id : JoinedOrSeparate<[ "/", "-" ], "L">,
HelpText<"Set the default language identifier.">;
-def lang_name : Separate<[ "/", "-" ], "LN">,
+def lang_name : Separate<[ "/", "-" ], "LN">,
HelpText<"Set the default language name.">;
-def includepath : Separate<[ "/", "-" ], "I">, HelpText<"Add an include path.">;
-def noinclude : Flag<[ "/", "-" ], "X">, HelpText<"Ignore 'include' variable.">;
+def includepath : Separate<[ "/", "-" ], "I">, HelpText<"Add an include path.">;
+def noinclude : Flag<[ "/", "-" ], "X">, HelpText<"Ignore 'include' variable.">;
-def add_null : Flag<[ "/", "-" ], "N">,
+def add_null : Flag<[ "/", "-" ], "N">,
HelpText<"Null-terminate all strings in the string table.">;
-def dupid_nowarn : Flag<[ "/", "-" ], "Y">,
+def dupid_nowarn : Flag<[ "/", "-" ], "Y">,
HelpText<"Suppress warnings on duplicate resource IDs.">;
-def verbose : Flag<[ "/", "-" ], "V">, HelpText<"Be verbose.">;
-def help : Flag<[ "/", "-" ], "?">, HelpText<"Display this help and exit.">;
-def h : Flag<[ "/", "-" ], "H">,
- Alias<help>,
+def verbose : Flag<[ "/", "-" ], "V">, HelpText<"Be verbose.">;
+def help : Flag<[ "/", "-" ], "?">, HelpText<"Display this help and exit.">;
+def h : Flag<[ "/", "-" ], "H">,
+ Alias<help>,
HelpText<"Display this help and exit.">;
-def dry_run : Flag<[ "/", "-" ], "dry-run">,
+def dry_run : Flag<[ "/", "-" ], "dry-run">,
HelpText<"Don't compile the input; only try to parse it.">;
-def codepage : JoinedOrSeparate<[ "/", "-" ], "C">,
+def codepage : JoinedOrSeparate<[ "/", "-" ], "C">,
HelpText<"Set the codepage used for input strings.">;
// Unused switches (at least for now). These will stay unimplemented
// in an early stage of development and can be ignored. However, we need to
// parse them in order to preserve the compatibility with the original tool.
-def nologo : Flag<[ "/", "-" ], "NOLOGO">;
-def r : Flag<[ "/", "-" ], "R">;
-def sl : Flag<[ "/", "-" ], "SL">;
+def nologo : Flag<[ "/", "-" ], "NOLOGO">;
+def r : Flag<[ "/", "-" ], "R">;
+def sl : Flag<[ "/", "-" ], "SL">;
// (Codepages support.)
-def w : Flag<[ "/", "-" ], "W">;
+def w : Flag<[ "/", "-" ], "W">;
// (Support of MUI and similar.)
-def fm : Separate<[ "/", "-" ], "FM">;
-def q : Separate<[ "/", "-" ], "Q">;
-def g : Flag<[ "/", "-" ], "G">;
-def gn : Flag<[ "/", "-" ], "GN">;
-def g1 : Flag<[ "/", "-" ], "G1">;
-def g2 : Flag<[ "/", "-" ], "G2">;
+def fm : Separate<[ "/", "-" ], "FM">;
+def q : Separate<[ "/", "-" ], "Q">;
+def g : Flag<[ "/", "-" ], "G">;
+def gn : Flag<[ "/", "-" ], "GN">;
+def g1 : Flag<[ "/", "-" ], "G1">;
+def g2 : Flag<[ "/", "-" ], "G2">;
diff --git a/contrib/libs/llvm12/tools/llvm-rc/ResourceFileWriter.cpp b/contrib/libs/llvm12/tools/llvm-rc/ResourceFileWriter.cpp
index 8b2de62cb1..553bb754ae 100644
--- a/contrib/libs/llvm12/tools/llvm-rc/ResourceFileWriter.cpp
+++ b/contrib/libs/llvm12/tools/llvm-rc/ResourceFileWriter.cpp
@@ -138,8 +138,8 @@ enum class NullHandlingMethod {
};
// Parses an identifier or string and returns a processed version of it:
-// * Strip the string boundary quotes.
-// * Convert the input code page characters to UTF16.
+// * Strip the string boundary quotes.
+// * Convert the input code page characters to UTF16.
// * Squash "" to a single ".
// * Replace the escape sequences with their processed version.
// For identifiers, this is no-op.
@@ -1514,16 +1514,16 @@ ResourceFileWriter::loadFile(StringRef File) const {
SmallString<128> Cwd;
std::unique_ptr<MemoryBuffer> Result;
- // 0. The file path is absolute or has a root directory, so we shouldn't
- // try to append it on top of other base directories. (An absolute path
- // must have a root directory, but e.g. the path "\dir\file" on windows
- // isn't considered absolute, but it does have a root directory. As long as
- // sys::path::append doesn't handle appending an absolute path or a path
- // starting with a root directory on top of a base, we must handle this
- // case separately at the top. C++17's path::append handles that case
- // properly though, so if using that to append paths below, this early
- // exception case could be removed.)
- if (sys::path::has_root_directory(File))
+ // 0. The file path is absolute or has a root directory, so we shouldn't
+ // try to append it on top of other base directories. (An absolute path
+ // must have a root directory, but e.g. the path "\dir\file" on windows
+ // isn't considered absolute, but it does have a root directory. As long as
+ // sys::path::append doesn't handle appending an absolute path or a path
+ // starting with a root directory on top of a base, we must handle this
+ // case separately at the top. C++17's path::append handles that case
+ // properly though, so if using that to append paths below, this early
+ // exception case could be removed.)
+ if (sys::path::has_root_directory(File))
return errorOrToExpected(MemoryBuffer::getFile(File, -1, false));
// 1. The current working directory.
diff --git a/contrib/libs/llvm12/tools/llvm-rc/ResourceScriptParser.cpp b/contrib/libs/llvm12/tools/llvm-rc/ResourceScriptParser.cpp
index d39665996d..5141ac0c38 100644
--- a/contrib/libs/llvm12/tools/llvm-rc/ResourceScriptParser.cpp
+++ b/contrib/libs/llvm12/tools/llvm-rc/ResourceScriptParser.cpp
@@ -777,10 +777,10 @@ RCParser::parseVersionInfoFixed() {
// VERSION variations take multiple integers.
size_t NumInts = RetType::isVersionType(FixedType) ? 4 : 1;
- ASSIGN_OR_RETURN(ArgsResult, readIntsWithCommas(1, NumInts));
+ ASSIGN_OR_RETURN(ArgsResult, readIntsWithCommas(1, NumInts));
SmallVector<uint32_t, 4> ArgInts(ArgsResult->begin(), ArgsResult->end());
- while (ArgInts.size() < NumInts)
- ArgInts.push_back(0);
+ while (ArgInts.size() < NumInts)
+ ArgInts.push_back(0);
Result.setValue(FixedType, ArgInts);
}
diff --git a/contrib/libs/llvm12/tools/llvm-rc/ResourceScriptStmt.h b/contrib/libs/llvm12/tools/llvm-rc/ResourceScriptStmt.h
index 6102a1c51e..27fbea3ae8 100644
--- a/contrib/libs/llvm12/tools/llvm-rc/ResourceScriptStmt.h
+++ b/contrib/libs/llvm12/tools/llvm-rc/ResourceScriptStmt.h
@@ -289,9 +289,9 @@ public:
: RCResource(Flags),
OptStatements(std::make_unique<OptionalStmtList>(std::move(Stmts))) {}
- Error applyStmts(Visitor *V) const override {
- return OptStatements->visit(V);
- }
+ Error applyStmts(Visitor *V) const override {
+ return OptStatements->visit(V);
+ }
};
// LANGUAGE statement. It can occur both as a top-level statement (in such
diff --git a/contrib/libs/llvm12/tools/llvm-rc/llvm-rc.cpp b/contrib/libs/llvm12/tools/llvm-rc/llvm-rc.cpp
index 415701ddac..e9027a21d4 100644
--- a/contrib/libs/llvm12/tools/llvm-rc/llvm-rc.cpp
+++ b/contrib/libs/llvm12/tools/llvm-rc/llvm-rc.cpp
@@ -92,12 +92,12 @@ int main(int Argc, const char **Argv) {
opt::InputArgList InputArgs = T.ParseArgs(ArgsArr, MAI, MAC);
// The tool prints nothing when invoked with no command-line arguments.
- if (InputArgs.hasArg(OPT_help)) {
+ if (InputArgs.hasArg(OPT_help)) {
T.PrintHelp(outs(), "rc [options] file...", "Resource Converter", false);
return 0;
}
- const bool BeVerbose = InputArgs.hasArg(OPT_verbose);
+ const bool BeVerbose = InputArgs.hasArg(OPT_verbose);
std::vector<std::string> InArgsInfo = InputArgs.getAllArgValues(OPT_INPUT);
if (DashDash != Argv + Argc)
@@ -141,14 +141,14 @@ int main(int Argc, const char **Argv) {
SmallString<128> InputFile(InArgsInfo[0]);
llvm::sys::fs::make_absolute(InputFile);
Params.InputFilePath = InputFile;
- Params.Include = InputArgs.getAllArgValues(OPT_includepath);
- Params.NoInclude = InputArgs.getAllArgValues(OPT_noinclude);
+ Params.Include = InputArgs.getAllArgValues(OPT_includepath);
+ Params.NoInclude = InputArgs.getAllArgValues(OPT_noinclude);
- if (InputArgs.hasArg(OPT_codepage)) {
- if (InputArgs.getLastArgValue(OPT_codepage)
+ if (InputArgs.hasArg(OPT_codepage)) {
+ if (InputArgs.getLastArgValue(OPT_codepage)
.getAsInteger(10, Params.CodePage))
fatalError("Invalid code page: " +
- InputArgs.getLastArgValue(OPT_codepage));
+ InputArgs.getLastArgValue(OPT_codepage));
switch (Params.CodePage) {
case CpAcp:
case CpWin1252:
@@ -161,10 +161,10 @@ int main(int Argc, const char **Argv) {
}
std::unique_ptr<ResourceFileWriter> Visitor;
- bool IsDryRun = InputArgs.hasArg(OPT_dry_run);
+ bool IsDryRun = InputArgs.hasArg(OPT_dry_run);
if (!IsDryRun) {
- auto OutArgsInfo = InputArgs.getAllArgValues(OPT_fileout);
+ auto OutArgsInfo = InputArgs.getAllArgValues(OPT_fileout);
if (OutArgsInfo.empty()) {
SmallString<128> OutputFile = InputFile;
llvm::sys::path::replace_extension(OutputFile, "res");
@@ -182,17 +182,17 @@ int main(int Argc, const char **Argv) {
fatalError("Error opening output file '" + OutArgsInfo[0] +
"': " + EC.message());
Visitor = std::make_unique<ResourceFileWriter>(Params, std::move(FOut));
- Visitor->AppendNull = InputArgs.hasArg(OPT_add_null);
+ Visitor->AppendNull = InputArgs.hasArg(OPT_add_null);
ExitOnErr(NullResource().visit(Visitor.get()));
// Set the default language; choose en-US arbitrarily.
unsigned PrimaryLangId = 0x09, SubLangId = 0x01;
- if (InputArgs.hasArg(OPT_lang_id)) {
+ if (InputArgs.hasArg(OPT_lang_id)) {
unsigned LangId;
- if (InputArgs.getLastArgValue(OPT_lang_id).getAsInteger(16, LangId))
+ if (InputArgs.getLastArgValue(OPT_lang_id).getAsInteger(16, LangId))
fatalError("Invalid language id: " +
- InputArgs.getLastArgValue(OPT_lang_id));
+ InputArgs.getLastArgValue(OPT_lang_id));
PrimaryLangId = LangId & 0x3ff;
SubLangId = LangId >> 10;
}
diff --git a/contrib/libs/llvm12/tools/llvm-rc/ya.make b/contrib/libs/llvm12/tools/llvm-rc/ya.make
index b54fb969ea..e69f41f542 100644
--- a/contrib/libs/llvm12/tools/llvm-rc/ya.make
+++ b/contrib/libs/llvm12/tools/llvm-rc/ya.make
@@ -12,16 +12,16 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/Demangle
- contrib/libs/llvm12/lib/Option
- contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/Demangle
+ contrib/libs/llvm12/lib/Option
+ contrib/libs/llvm12/lib/Support
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-rc
- contrib/libs/llvm12/tools/llvm-rc
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-rc
+ contrib/libs/llvm12/tools/llvm-rc
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/tools/llvm-symbolizer/Opts.td b/contrib/libs/llvm12/tools/llvm-symbolizer/Opts.td
index aff1181799..ac23639f13 100644
--- a/contrib/libs/llvm12/tools/llvm-symbolizer/Opts.td
+++ b/contrib/libs/llvm12/tools/llvm-symbolizer/Opts.td
@@ -1,71 +1,71 @@
-include "llvm/Option/OptParser.td"
-
-multiclass B<string name, string help1, string help2> {
- def NAME: Flag<["--", "-"], name>, HelpText<help1>;
- def no_ # NAME: Flag<["--", "-"], "no-" # name>, HelpText<help2>;
-}
-
-multiclass Eq<string name, string help> {
- def NAME #_EQ : Joined<["--", "-"], name #"=">,
- HelpText<help>;
- def : Separate<["--", "-"], name>, Alias<!cast<Joined>(NAME #_EQ)>;
-}
-
-class F<string name, string help>: Flag<["--", "-"], name>, HelpText<help>;
-
-def addresses : F<"addresses", "Show address before line information">;
-defm adjust_vma
- : Eq<"adjust-vma", "Add specified offset to object file addresses">,
- MetaVarName<"<offset>">;
-def basenames : Flag<["--"], "basenames">, HelpText<"Strip directory names from paths">;
-defm debug_file_directory : Eq<"debug-file-directory", "Path to directory where to look for debug files">, MetaVarName<"<dir>">;
-defm default_arch : Eq<"default-arch", "Default architecture (for multi-arch objects)">;
-defm demangle : B<"demangle", "Demangle function names", "Don't demangle function names">;
-def functions : F<"functions", "Print function name for a given address">;
-def functions_EQ : Joined<["--"], "functions=">, HelpText<"Print function name for a given address">, Values<"none,short,linkage">;
-def help : F<"help", "Display this help">;
-defm dwp : Eq<"dwp", "Path to DWP file to be use for any split CUs">, MetaVarName<"<file>">;
-defm dsym_hint : Eq<"dsym-hint", "Path to .dSYM bundles to search for debug info for the object files">, MetaVarName<"<dir>">;
-defm fallback_debug_path : Eq<"fallback-debug-path", "Fallback path for debug binaries">, MetaVarName<"<dir>">;
-defm inlines : B<"inlines", "Print all inlined frames for a given address",
- "Do not print inlined frames">;
-defm obj
- : Eq<"obj", "Path to object file to be symbolized (if not provided, "
- "object file should be specified for each input line)">, MetaVarName<"<file>">;
-defm output_style
- : Eq<"output-style", "Specify print style. Supported styles: LLVM, GNU">,
- MetaVarName<"style">,
- Values<"LLVM,GNU">;
-def pretty_print : F<"pretty-print", "Make the output more human friendly">;
-defm print_source_context_lines : Eq<"print-source-context-lines", "Print N lines of source file context">;
-def relative_address : F<"relative-address", "Interpret addresses as addresses relative to the image base">;
-def relativenames : F<"relativenames", "Strip the compilation directory from paths">;
-defm untag_addresses : B<"untag-addresses", "", "Remove memory tags from addresses before symbolization">;
-def use_dia: F<"dia", "Use the DIA library to access symbols (Windows only)">;
-def verbose : F<"verbose", "Print verbose line info">;
-def version : F<"version", "Display the version">;
-
-def : Flag<["-"], "a">, Alias<addresses>, HelpText<"Alias for --addresses">;
-def : F<"print-address", "Alias for --addresses">, Alias<addresses>;
-def : Flag<["-"], "C">, Alias<demangle>, HelpText<"Alias for --demangle">;
-def : Joined<["--"], "exe=">, Alias<obj_EQ>, HelpText<"Alias for --obj">, MetaVarName<"<file>">;
-def : Separate<["--"], "exe">, Alias<obj_EQ>, HelpText<"Alias for --obj">, MetaVarName<"<file>">;
-def : JoinedOrSeparate<["-"], "e">, Alias<obj_EQ>, HelpText<"Alias for --obj">, MetaVarName<"<file>">;
-def : Joined<["-"], "e=">, Alias<obj_EQ>, HelpText<"Alias for --obj">, MetaVarName<"<file>">;
-def : Flag<["-"], "f">, Alias<functions>, HelpText<"Alias for --functions">;
-def : Joined<["-"], "f=">, Alias<functions_EQ>, HelpText<"Alias for --functions=">;
-def : Flag<["-"], "h">, Alias<help>;
-def : Flag<["-"], "i">, Alias<inlines>, HelpText<"Alias for --inlines">;
-def : F<"inlining", "Alias for --inlines">, Alias<inlines>;
-def : Flag<["-"], "p">, Alias<pretty_print>, HelpText<"Alias for --pretty-print">;
-def : Flag<["-"], "s">, Alias<basenames>, HelpText<"Alias for --basenames">;
-def : Flag<["-"], "v">, Alias<version>, HelpText<"Alias for --version">;
-
-// Compatibility aliases for old asan_symbolize.py and sanitizer binaries (before 2020-08).
-def : Flag<["--"], "inlining=true">, Alias<inlines>, HelpText<"Alias for --inlines">;
-def : Flag<["--"], "inlining=false">, Alias<no_inlines>, HelpText<"Alias for --no-inlines">;
-// Compatibility aliases for pprof's symbolizer.
-def : Flag<["-"], "demangle=true">, Alias<demangle>, HelpText<"Alias for --demangle">;
-def : Flag<["-"], "demangle=false">, Alias<no_demangle>, HelpText<"Alias for --no-demangle">;
-// Compatibility no-op options.
-def : Flag<["--"], "use-symbol-table=true">;
+include "llvm/Option/OptParser.td"
+
+multiclass B<string name, string help1, string help2> {
+ def NAME: Flag<["--", "-"], name>, HelpText<help1>;
+ def no_ # NAME: Flag<["--", "-"], "no-" # name>, HelpText<help2>;
+}
+
+multiclass Eq<string name, string help> {
+ def NAME #_EQ : Joined<["--", "-"], name #"=">,
+ HelpText<help>;
+ def : Separate<["--", "-"], name>, Alias<!cast<Joined>(NAME #_EQ)>;
+}
+
+class F<string name, string help>: Flag<["--", "-"], name>, HelpText<help>;
+
+def addresses : F<"addresses", "Show address before line information">;
+defm adjust_vma
+ : Eq<"adjust-vma", "Add specified offset to object file addresses">,
+ MetaVarName<"<offset>">;
+def basenames : Flag<["--"], "basenames">, HelpText<"Strip directory names from paths">;
+defm debug_file_directory : Eq<"debug-file-directory", "Path to directory where to look for debug files">, MetaVarName<"<dir>">;
+defm default_arch : Eq<"default-arch", "Default architecture (for multi-arch objects)">;
+defm demangle : B<"demangle", "Demangle function names", "Don't demangle function names">;
+def functions : F<"functions", "Print function name for a given address">;
+def functions_EQ : Joined<["--"], "functions=">, HelpText<"Print function name for a given address">, Values<"none,short,linkage">;
+def help : F<"help", "Display this help">;
+defm dwp : Eq<"dwp", "Path to DWP file to be use for any split CUs">, MetaVarName<"<file>">;
+defm dsym_hint : Eq<"dsym-hint", "Path to .dSYM bundles to search for debug info for the object files">, MetaVarName<"<dir>">;
+defm fallback_debug_path : Eq<"fallback-debug-path", "Fallback path for debug binaries">, MetaVarName<"<dir>">;
+defm inlines : B<"inlines", "Print all inlined frames for a given address",
+ "Do not print inlined frames">;
+defm obj
+ : Eq<"obj", "Path to object file to be symbolized (if not provided, "
+ "object file should be specified for each input line)">, MetaVarName<"<file>">;
+defm output_style
+ : Eq<"output-style", "Specify print style. Supported styles: LLVM, GNU">,
+ MetaVarName<"style">,
+ Values<"LLVM,GNU">;
+def pretty_print : F<"pretty-print", "Make the output more human friendly">;
+defm print_source_context_lines : Eq<"print-source-context-lines", "Print N lines of source file context">;
+def relative_address : F<"relative-address", "Interpret addresses as addresses relative to the image base">;
+def relativenames : F<"relativenames", "Strip the compilation directory from paths">;
+defm untag_addresses : B<"untag-addresses", "", "Remove memory tags from addresses before symbolization">;
+def use_dia: F<"dia", "Use the DIA library to access symbols (Windows only)">;
+def verbose : F<"verbose", "Print verbose line info">;
+def version : F<"version", "Display the version">;
+
+def : Flag<["-"], "a">, Alias<addresses>, HelpText<"Alias for --addresses">;
+def : F<"print-address", "Alias for --addresses">, Alias<addresses>;
+def : Flag<["-"], "C">, Alias<demangle>, HelpText<"Alias for --demangle">;
+def : Joined<["--"], "exe=">, Alias<obj_EQ>, HelpText<"Alias for --obj">, MetaVarName<"<file>">;
+def : Separate<["--"], "exe">, Alias<obj_EQ>, HelpText<"Alias for --obj">, MetaVarName<"<file>">;
+def : JoinedOrSeparate<["-"], "e">, Alias<obj_EQ>, HelpText<"Alias for --obj">, MetaVarName<"<file>">;
+def : Joined<["-"], "e=">, Alias<obj_EQ>, HelpText<"Alias for --obj">, MetaVarName<"<file>">;
+def : Flag<["-"], "f">, Alias<functions>, HelpText<"Alias for --functions">;
+def : Joined<["-"], "f=">, Alias<functions_EQ>, HelpText<"Alias for --functions=">;
+def : Flag<["-"], "h">, Alias<help>;
+def : Flag<["-"], "i">, Alias<inlines>, HelpText<"Alias for --inlines">;
+def : F<"inlining", "Alias for --inlines">, Alias<inlines>;
+def : Flag<["-"], "p">, Alias<pretty_print>, HelpText<"Alias for --pretty-print">;
+def : Flag<["-"], "s">, Alias<basenames>, HelpText<"Alias for --basenames">;
+def : Flag<["-"], "v">, Alias<version>, HelpText<"Alias for --version">;
+
+// Compatibility aliases for old asan_symbolize.py and sanitizer binaries (before 2020-08).
+def : Flag<["--"], "inlining=true">, Alias<inlines>, HelpText<"Alias for --inlines">;
+def : Flag<["--"], "inlining=false">, Alias<no_inlines>, HelpText<"Alias for --no-inlines">;
+// Compatibility aliases for pprof's symbolizer.
+def : Flag<["-"], "demangle=true">, Alias<demangle>, HelpText<"Alias for --demangle">;
+def : Flag<["-"], "demangle=false">, Alias<no_demangle>, HelpText<"Alias for --no-demangle">;
+// Compatibility no-op options.
+def : Flag<["--"], "use-symbol-table=true">;
diff --git a/contrib/libs/llvm12/tools/llvm-symbolizer/llvm-symbolizer.cpp b/contrib/libs/llvm12/tools/llvm-symbolizer/llvm-symbolizer.cpp
index f85ed6dc7e..8734c2d740 100644
--- a/contrib/libs/llvm12/tools/llvm-symbolizer/llvm-symbolizer.cpp
+++ b/contrib/libs/llvm12/tools/llvm-symbolizer/llvm-symbolizer.cpp
@@ -14,21 +14,21 @@
//
//===----------------------------------------------------------------------===//
-#include "Opts.inc"
+#include "Opts.inc"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Config/config.h"
+#include "llvm/Config/config.h"
#include "llvm/DebugInfo/Symbolize/DIPrinter.h"
#include "llvm/DebugInfo/Symbolize/Symbolize.h"
-#include "llvm/Option/Arg.h"
-#include "llvm/Option/ArgList.h"
-#include "llvm/Option/Option.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/Option.h"
#include "llvm/Support/COM.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/StringSaver.h"
+#include "llvm/Support/StringSaver.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstdio>
@@ -38,37 +38,37 @@
using namespace llvm;
using namespace symbolize;
-namespace {
-enum ID {
- OPT_INVALID = 0, // This is not an option ID.
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR, VALUES) \
- OPT_##ID,
-#include "Opts.inc"
-#undef OPTION
-};
+namespace {
+enum ID {
+ OPT_INVALID = 0, // This is not an option ID.
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ OPT_##ID,
+#include "Opts.inc"
+#undef OPTION
+};
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
-#include "Opts.inc"
-#undef PREFIX
+#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
+#include "Opts.inc"
+#undef PREFIX
-static const opt::OptTable::Info InfoTable[] = {
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR, VALUES) \
- { \
- PREFIX, NAME, HELPTEXT, \
- METAVAR, OPT_##ID, opt::Option::KIND##Class, \
- PARAM, FLAGS, OPT_##GROUP, \
- OPT_##ALIAS, ALIASARGS, VALUES},
-#include "Opts.inc"
-#undef OPTION
-};
+static const opt::OptTable::Info InfoTable[] = {
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ { \
+ PREFIX, NAME, HELPTEXT, \
+ METAVAR, OPT_##ID, opt::Option::KIND##Class, \
+ PARAM, FLAGS, OPT_##GROUP, \
+ OPT_##ALIAS, ALIASARGS, VALUES},
+#include "Opts.inc"
+#undef OPTION
+};
-class SymbolizerOptTable : public opt::OptTable {
-public:
- SymbolizerOptTable() : OptTable(InfoTable, true) {}
-};
-} // namespace
+class SymbolizerOptTable : public opt::OptTable {
+public:
+ SymbolizerOptTable() : OptTable(InfoTable, true) {}
+};
+} // namespace
static cl::list<std::string> ClInputAddresses(cl::Positional,
cl::desc("<input addresses>..."),
@@ -89,8 +89,8 @@ enum class Command {
Frame,
};
-static bool parseCommand(StringRef BinaryName, bool IsAddr2Line,
- StringRef InputString, Command &Cmd,
+static bool parseCommand(StringRef BinaryName, bool IsAddr2Line,
+ StringRef InputString, Command &Cmd,
std::string &ModuleName, uint64_t &ModuleOffset) {
const char kDelimiters[] = " \n\r";
ModuleName = "";
@@ -106,7 +106,7 @@ static bool parseCommand(StringRef BinaryName, bool IsAddr2Line,
}
const char *Pos = InputString.data();
// Skip delimiters and parse input filename (if needed).
- if (BinaryName.empty()) {
+ if (BinaryName.empty()) {
Pos += strspn(Pos, kDelimiters);
if (*Pos == '"' || *Pos == '\'') {
char Quote = *Pos;
@@ -122,7 +122,7 @@ static bool parseCommand(StringRef BinaryName, bool IsAddr2Line,
Pos += NameLength;
}
} else {
- ModuleName = BinaryName.str();
+ ModuleName = BinaryName.str();
}
// Skip delimiters and parse module offset.
Pos += strspn(Pos, kDelimiters);
@@ -135,26 +135,26 @@ static bool parseCommand(StringRef BinaryName, bool IsAddr2Line,
return !Offset.getAsInteger(IsAddr2Line ? 16 : 0, ModuleOffset);
}
-static void symbolizeInput(const opt::InputArgList &Args, uint64_t AdjustVMA,
- bool IsAddr2Line, DIPrinter::OutputStyle OutputStyle,
- StringRef InputString, LLVMSymbolizer &Symbolizer,
- DIPrinter &Printer) {
+static void symbolizeInput(const opt::InputArgList &Args, uint64_t AdjustVMA,
+ bool IsAddr2Line, DIPrinter::OutputStyle OutputStyle,
+ StringRef InputString, LLVMSymbolizer &Symbolizer,
+ DIPrinter &Printer) {
Command Cmd;
std::string ModuleName;
uint64_t Offset = 0;
- if (!parseCommand(Args.getLastArgValue(OPT_obj_EQ), IsAddr2Line,
- StringRef(InputString), Cmd, ModuleName, Offset)) {
+ if (!parseCommand(Args.getLastArgValue(OPT_obj_EQ), IsAddr2Line,
+ StringRef(InputString), Cmd, ModuleName, Offset)) {
outs() << InputString << "\n";
return;
}
- if (Args.hasArg(OPT_addresses)) {
+ if (Args.hasArg(OPT_addresses)) {
outs() << "0x";
outs().write_hex(Offset);
- StringRef Delimiter = Args.hasArg(OPT_pretty_print) ? ": " : "\n";
+ StringRef Delimiter = Args.hasArg(OPT_pretty_print) ? ": " : "\n";
outs() << Delimiter;
}
- Offset -= AdjustVMA;
+ Offset -= AdjustVMA;
if (Cmd == Command::Data) {
auto ResOrErr = Symbolizer.symbolizeData(
ModuleName, {Offset, object::SectionedAddress::UndefSection});
@@ -168,182 +168,182 @@ static void symbolizeInput(const opt::InputArgList &Args, uint64_t AdjustVMA,
if (ResOrErr->empty())
outs() << "??\n";
}
- } else if (Args.hasFlag(OPT_inlines, OPT_no_inlines, !IsAddr2Line)) {
+ } else if (Args.hasFlag(OPT_inlines, OPT_no_inlines, !IsAddr2Line)) {
auto ResOrErr = Symbolizer.symbolizeInlinedCode(
ModuleName, {Offset, object::SectionedAddress::UndefSection});
Printer << (error(ResOrErr) ? DIInliningInfo() : ResOrErr.get());
- } else if (OutputStyle == DIPrinter::OutputStyle::GNU) {
- // With PrintFunctions == FunctionNameKind::LinkageName (default)
- // and UseSymbolTable == true (also default), Symbolizer.symbolizeCode()
+ } else if (OutputStyle == DIPrinter::OutputStyle::GNU) {
+ // With PrintFunctions == FunctionNameKind::LinkageName (default)
+ // and UseSymbolTable == true (also default), Symbolizer.symbolizeCode()
// may override the name of an inlined function with the name of the topmost
// caller function in the inlining chain. This contradicts the existing
// behavior of addr2line. Symbolizer.symbolizeInlinedCode() overrides only
// the topmost function, which suits our needs better.
auto ResOrErr = Symbolizer.symbolizeInlinedCode(
ModuleName, {Offset, object::SectionedAddress::UndefSection});
- if (!ResOrErr || ResOrErr->getNumberOfFrames() == 0) {
- error(ResOrErr);
- Printer << DILineInfo();
- } else {
- Printer << ResOrErr->getFrame(0);
- }
+ if (!ResOrErr || ResOrErr->getNumberOfFrames() == 0) {
+ error(ResOrErr);
+ Printer << DILineInfo();
+ } else {
+ Printer << ResOrErr->getFrame(0);
+ }
} else {
auto ResOrErr = Symbolizer.symbolizeCode(
ModuleName, {Offset, object::SectionedAddress::UndefSection});
Printer << (error(ResOrErr) ? DILineInfo() : ResOrErr.get());
}
- if (OutputStyle == DIPrinter::OutputStyle::LLVM)
+ if (OutputStyle == DIPrinter::OutputStyle::LLVM)
outs() << "\n";
}
-static void printHelp(StringRef ToolName, const SymbolizerOptTable &Tbl,
- raw_ostream &OS) {
- const char HelpText[] = " [options] addresses...";
- Tbl.PrintHelp(OS, (ToolName + HelpText).str().c_str(),
- ToolName.str().c_str());
- // TODO Replace this with OptTable API once it adds extrahelp support.
- OS << "\nPass @FILE as argument to read options from FILE.\n";
-}
+static void printHelp(StringRef ToolName, const SymbolizerOptTable &Tbl,
+ raw_ostream &OS) {
+ const char HelpText[] = " [options] addresses...";
+ Tbl.PrintHelp(OS, (ToolName + HelpText).str().c_str(),
+ ToolName.str().c_str());
+ // TODO Replace this with OptTable API once it adds extrahelp support.
+ OS << "\nPass @FILE as argument to read options from FILE.\n";
+}
-static opt::InputArgList parseOptions(int Argc, char *Argv[], bool IsAddr2Line,
- StringSaver &Saver,
- SymbolizerOptTable &Tbl) {
- StringRef ToolName = IsAddr2Line ? "llvm-addr2line" : "llvm-symbolizer";
- Tbl.setGroupedShortOptions(true);
- // The environment variable specifies initial options which can be overridden
- // by commnad line options.
- Tbl.setInitialOptionsFromEnvironment(IsAddr2Line ? "LLVM_ADDR2LINE_OPTS"
- : "LLVM_SYMBOLIZER_OPTS");
- bool HasError = false;
- opt::InputArgList Args =
- Tbl.parseArgs(Argc, Argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) {
- errs() << ("error: " + Msg + "\n");
- HasError = true;
- });
- if (HasError)
- exit(1);
- if (Args.hasArg(OPT_help)) {
- printHelp(ToolName, Tbl, outs());
- exit(0);
- }
- if (Args.hasArg(OPT_version)) {
- outs() << ToolName << '\n';
- cl::PrintVersionMessage();
- exit(0);
- }
+static opt::InputArgList parseOptions(int Argc, char *Argv[], bool IsAddr2Line,
+ StringSaver &Saver,
+ SymbolizerOptTable &Tbl) {
+ StringRef ToolName = IsAddr2Line ? "llvm-addr2line" : "llvm-symbolizer";
+ Tbl.setGroupedShortOptions(true);
+ // The environment variable specifies initial options which can be overridden
+ // by commnad line options.
+ Tbl.setInitialOptionsFromEnvironment(IsAddr2Line ? "LLVM_ADDR2LINE_OPTS"
+ : "LLVM_SYMBOLIZER_OPTS");
+ bool HasError = false;
+ opt::InputArgList Args =
+ Tbl.parseArgs(Argc, Argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) {
+ errs() << ("error: " + Msg + "\n");
+ HasError = true;
+ });
+ if (HasError)
+ exit(1);
+ if (Args.hasArg(OPT_help)) {
+ printHelp(ToolName, Tbl, outs());
+ exit(0);
+ }
+ if (Args.hasArg(OPT_version)) {
+ outs() << ToolName << '\n';
+ cl::PrintVersionMessage();
+ exit(0);
+ }
- return Args;
-}
-
-template <typename T>
-static void parseIntArg(const opt::InputArgList &Args, int ID, T &Value) {
- if (const opt::Arg *A = Args.getLastArg(ID)) {
- StringRef V(A->getValue());
- if (!llvm::to_integer(V, Value, 0)) {
- errs() << A->getSpelling() +
- ": expected a non-negative integer, but got '" + V + "'";
- exit(1);
- }
- } else {
- Value = 0;
+ return Args;
+}
+
+template <typename T>
+static void parseIntArg(const opt::InputArgList &Args, int ID, T &Value) {
+ if (const opt::Arg *A = Args.getLastArg(ID)) {
+ StringRef V(A->getValue());
+ if (!llvm::to_integer(V, Value, 0)) {
+ errs() << A->getSpelling() +
+ ": expected a non-negative integer, but got '" + V + "'";
+ exit(1);
+ }
+ } else {
+ Value = 0;
}
-}
+}
-static FunctionNameKind decideHowToPrintFunctions(const opt::InputArgList &Args,
- bool IsAddr2Line) {
- if (Args.hasArg(OPT_functions))
- return FunctionNameKind::LinkageName;
- if (const opt::Arg *A = Args.getLastArg(OPT_functions_EQ))
- return StringSwitch<FunctionNameKind>(A->getValue())
- .Case("none", FunctionNameKind::None)
- .Case("short", FunctionNameKind::ShortName)
- .Default(FunctionNameKind::LinkageName);
- return IsAddr2Line ? FunctionNameKind::None : FunctionNameKind::LinkageName;
-}
+static FunctionNameKind decideHowToPrintFunctions(const opt::InputArgList &Args,
+ bool IsAddr2Line) {
+ if (Args.hasArg(OPT_functions))
+ return FunctionNameKind::LinkageName;
+ if (const opt::Arg *A = Args.getLastArg(OPT_functions_EQ))
+ return StringSwitch<FunctionNameKind>(A->getValue())
+ .Case("none", FunctionNameKind::None)
+ .Case("short", FunctionNameKind::ShortName)
+ .Default(FunctionNameKind::LinkageName);
+ return IsAddr2Line ? FunctionNameKind::None : FunctionNameKind::LinkageName;
+}
-int main(int argc, char **argv) {
- InitLLVM X(argc, argv);
- sys::InitializeCOMRAII COM(sys::COMThreadingMode::MultiThreaded);
+int main(int argc, char **argv) {
+ InitLLVM X(argc, argv);
+ sys::InitializeCOMRAII COM(sys::COMThreadingMode::MultiThreaded);
+
+ bool IsAddr2Line = sys::path::stem(argv[0]).contains("addr2line");
+ BumpPtrAllocator A;
+ StringSaver Saver(A);
+ SymbolizerOptTable Tbl;
+ opt::InputArgList Args = parseOptions(argc, argv, IsAddr2Line, Saver, Tbl);
- bool IsAddr2Line = sys::path::stem(argv[0]).contains("addr2line");
- BumpPtrAllocator A;
- StringSaver Saver(A);
- SymbolizerOptTable Tbl;
- opt::InputArgList Args = parseOptions(argc, argv, IsAddr2Line, Saver, Tbl);
-
LLVMSymbolizer::Options Opts;
- uint64_t AdjustVMA;
- unsigned SourceContextLines;
- parseIntArg(Args, OPT_adjust_vma_EQ, AdjustVMA);
- if (const opt::Arg *A = Args.getLastArg(OPT_basenames, OPT_relativenames)) {
- Opts.PathStyle =
- A->getOption().matches(OPT_basenames)
- ? DILineInfoSpecifier::FileLineInfoKind::BaseNameOnly
- : DILineInfoSpecifier::FileLineInfoKind::RelativeFilePath;
- } else {
- Opts.PathStyle = DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath;
- }
- Opts.DebugFileDirectory = Args.getAllArgValues(OPT_debug_file_directory_EQ);
- Opts.DefaultArch = Args.getLastArgValue(OPT_default_arch_EQ).str();
- Opts.Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, !IsAddr2Line);
- Opts.DWPName = Args.getLastArgValue(OPT_dwp_EQ).str();
- Opts.FallbackDebugPath =
- Args.getLastArgValue(OPT_fallback_debug_path_EQ).str();
- Opts.PrintFunctions = decideHowToPrintFunctions(Args, IsAddr2Line);
- parseIntArg(Args, OPT_print_source_context_lines_EQ, SourceContextLines);
- Opts.RelativeAddresses = Args.hasArg(OPT_relative_address);
- Opts.UntagAddresses =
- Args.hasFlag(OPT_untag_addresses, OPT_no_untag_addresses, !IsAddr2Line);
- Opts.UseDIA = Args.hasArg(OPT_use_dia);
-#if !defined(LLVM_ENABLE_DIA_SDK)
- if (Opts.UseDIA) {
- WithColor::warning() << "DIA not available; using native PDB reader\n";
- Opts.UseDIA = false;
- }
-#endif
- Opts.UseSymbolTable = true;
+ uint64_t AdjustVMA;
+ unsigned SourceContextLines;
+ parseIntArg(Args, OPT_adjust_vma_EQ, AdjustVMA);
+ if (const opt::Arg *A = Args.getLastArg(OPT_basenames, OPT_relativenames)) {
+ Opts.PathStyle =
+ A->getOption().matches(OPT_basenames)
+ ? DILineInfoSpecifier::FileLineInfoKind::BaseNameOnly
+ : DILineInfoSpecifier::FileLineInfoKind::RelativeFilePath;
+ } else {
+ Opts.PathStyle = DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath;
+ }
+ Opts.DebugFileDirectory = Args.getAllArgValues(OPT_debug_file_directory_EQ);
+ Opts.DefaultArch = Args.getLastArgValue(OPT_default_arch_EQ).str();
+ Opts.Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, !IsAddr2Line);
+ Opts.DWPName = Args.getLastArgValue(OPT_dwp_EQ).str();
+ Opts.FallbackDebugPath =
+ Args.getLastArgValue(OPT_fallback_debug_path_EQ).str();
+ Opts.PrintFunctions = decideHowToPrintFunctions(Args, IsAddr2Line);
+ parseIntArg(Args, OPT_print_source_context_lines_EQ, SourceContextLines);
+ Opts.RelativeAddresses = Args.hasArg(OPT_relative_address);
+ Opts.UntagAddresses =
+ Args.hasFlag(OPT_untag_addresses, OPT_no_untag_addresses, !IsAddr2Line);
+ Opts.UseDIA = Args.hasArg(OPT_use_dia);
+#if !defined(LLVM_ENABLE_DIA_SDK)
+ if (Opts.UseDIA) {
+ WithColor::warning() << "DIA not available; using native PDB reader\n";
+ Opts.UseDIA = false;
+ }
+#endif
+ Opts.UseSymbolTable = true;
- for (const opt::Arg *A : Args.filtered(OPT_dsym_hint_EQ)) {
- StringRef Hint(A->getValue());
- if (sys::path::extension(Hint) == ".dSYM") {
- Opts.DsymHints.emplace_back(Hint);
+ for (const opt::Arg *A : Args.filtered(OPT_dsym_hint_EQ)) {
+ StringRef Hint(A->getValue());
+ if (sys::path::extension(Hint) == ".dSYM") {
+ Opts.DsymHints.emplace_back(Hint);
} else {
- errs() << "Warning: invalid dSYM hint: \"" << Hint
- << "\" (must have the '.dSYM' extension).\n";
+ errs() << "Warning: invalid dSYM hint: \"" << Hint
+ << "\" (must have the '.dSYM' extension).\n";
}
}
-
- auto OutputStyle =
- IsAddr2Line ? DIPrinter::OutputStyle::GNU : DIPrinter::OutputStyle::LLVM;
- if (const opt::Arg *A = Args.getLastArg(OPT_output_style_EQ)) {
- OutputStyle = strcmp(A->getValue(), "GNU") == 0
- ? DIPrinter::OutputStyle::GNU
- : DIPrinter::OutputStyle::LLVM;
- }
-
+
+ auto OutputStyle =
+ IsAddr2Line ? DIPrinter::OutputStyle::GNU : DIPrinter::OutputStyle::LLVM;
+ if (const opt::Arg *A = Args.getLastArg(OPT_output_style_EQ)) {
+ OutputStyle = strcmp(A->getValue(), "GNU") == 0
+ ? DIPrinter::OutputStyle::GNU
+ : DIPrinter::OutputStyle::LLVM;
+ }
+
LLVMSymbolizer Symbolizer(Opts);
- DIPrinter Printer(outs(), Opts.PrintFunctions != FunctionNameKind::None,
- Args.hasArg(OPT_pretty_print), SourceContextLines,
- Args.hasArg(OPT_verbose), OutputStyle);
+ DIPrinter Printer(outs(), Opts.PrintFunctions != FunctionNameKind::None,
+ Args.hasArg(OPT_pretty_print), SourceContextLines,
+ Args.hasArg(OPT_verbose), OutputStyle);
- std::vector<std::string> InputAddresses = Args.getAllArgValues(OPT_INPUT);
- if (InputAddresses.empty()) {
+ std::vector<std::string> InputAddresses = Args.getAllArgValues(OPT_INPUT);
+ if (InputAddresses.empty()) {
const int kMaxInputStringLength = 1024;
char InputString[kMaxInputStringLength];
while (fgets(InputString, sizeof(InputString), stdin)) {
// Strip newline characters.
std::string StrippedInputString(InputString);
- llvm::erase_if(StrippedInputString,
- [](char c) { return c == '\r' || c == '\n'; });
- symbolizeInput(Args, AdjustVMA, IsAddr2Line, OutputStyle,
- StrippedInputString, Symbolizer, Printer);
+ llvm::erase_if(StrippedInputString,
+ [](char c) { return c == '\r' || c == '\n'; });
+ symbolizeInput(Args, AdjustVMA, IsAddr2Line, OutputStyle,
+ StrippedInputString, Symbolizer, Printer);
outs().flush();
}
} else {
- for (StringRef Address : InputAddresses)
- symbolizeInput(Args, AdjustVMA, IsAddr2Line, OutputStyle, Address,
- Symbolizer, Printer);
+ for (StringRef Address : InputAddresses)
+ symbolizeInput(Args, AdjustVMA, IsAddr2Line, OutputStyle, Address,
+ Symbolizer, Printer);
}
return 0;
diff --git a/contrib/libs/llvm12/tools/llvm-symbolizer/ya.make b/contrib/libs/llvm12/tools/llvm-symbolizer/ya.make
index 1c060ecda0..1f13f78269 100644
--- a/contrib/libs/llvm12/tools/llvm-symbolizer/ya.make
+++ b/contrib/libs/llvm12/tools/llvm-symbolizer/ya.make
@@ -12,30 +12,30 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/include
- contrib/libs/llvm12/lib/BinaryFormat
- contrib/libs/llvm12/lib/Bitcode/Reader
- contrib/libs/llvm12/lib/Bitstream/Reader
- contrib/libs/llvm12/lib/DebugInfo/CodeView
- contrib/libs/llvm12/lib/DebugInfo/DWARF
- contrib/libs/llvm12/lib/DebugInfo/MSF
- contrib/libs/llvm12/lib/DebugInfo/PDB
- contrib/libs/llvm12/lib/DebugInfo/Symbolize
- contrib/libs/llvm12/lib/Demangle
- contrib/libs/llvm12/lib/IR
- contrib/libs/llvm12/lib/MC
- contrib/libs/llvm12/lib/MC/MCParser
- contrib/libs/llvm12/lib/Object
- contrib/libs/llvm12/lib/Option
- contrib/libs/llvm12/lib/Remarks
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/TextAPI/MachO
+ contrib/libs/llvm12
+ contrib/libs/llvm12/include
+ contrib/libs/llvm12/lib/BinaryFormat
+ contrib/libs/llvm12/lib/Bitcode/Reader
+ contrib/libs/llvm12/lib/Bitstream/Reader
+ contrib/libs/llvm12/lib/DebugInfo/CodeView
+ contrib/libs/llvm12/lib/DebugInfo/DWARF
+ contrib/libs/llvm12/lib/DebugInfo/MSF
+ contrib/libs/llvm12/lib/DebugInfo/PDB
+ contrib/libs/llvm12/lib/DebugInfo/Symbolize
+ contrib/libs/llvm12/lib/Demangle
+ contrib/libs/llvm12/lib/IR
+ contrib/libs/llvm12/lib/MC
+ contrib/libs/llvm12/lib/MC/MCParser
+ contrib/libs/llvm12/lib/Object
+ contrib/libs/llvm12/lib/Option
+ contrib/libs/llvm12/lib/Remarks
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/TextAPI/MachO
)
ADDINCL(
- ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-symbolizer
- contrib/libs/llvm12/tools/llvm-symbolizer
+ ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/tools/llvm-symbolizer
+ contrib/libs/llvm12/tools/llvm-symbolizer
)
NO_COMPILER_WARNINGS()
diff --git a/contrib/libs/llvm12/utils/DSAclean.py b/contrib/libs/llvm12/utils/DSAclean.py
index 1cd9b6a8d6..c5fb56b037 100755
--- a/contrib/libs/llvm12/utils/DSAclean.py
+++ b/contrib/libs/llvm12/utils/DSAclean.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python
#changelog:
#10/13/2005b: replaced the # in tmp(.#*)* with alphanumeric and _, this will then remove
diff --git a/contrib/libs/llvm12/utils/DSAextract.py b/contrib/libs/llvm12/utils/DSAextract.py
index b9a0492fbc..1d93f1e30c 100755
--- a/contrib/libs/llvm12/utils/DSAextract.py
+++ b/contrib/libs/llvm12/utils/DSAextract.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python
#this is a script to extract given named nodes from a dot file, with
#the associated edges. An edge is kept iff for edge x -> y
diff --git a/contrib/libs/llvm12/utils/TableGen/AsmMatcherEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/AsmMatcherEmitter.cpp
index 245aab5049..9d304910ba 100644
--- a/contrib/libs/llvm12/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/AsmMatcherEmitter.cpp
@@ -612,7 +612,7 @@ struct MatchableInfo {
/// operator< - Compare two matchables.
bool operator<(const MatchableInfo &RHS) const {
// The primary comparator is the instruction mnemonic.
- if (int Cmp = Mnemonic.compare_lower(RHS.Mnemonic))
+ if (int Cmp = Mnemonic.compare_lower(RHS.Mnemonic))
return Cmp == -1;
if (AsmOperands.size() != RHS.AsmOperands.size())
@@ -789,8 +789,8 @@ public:
}
bool hasOptionalOperands() const {
- return any_of(Classes,
- [](const ClassInfo &Class) { return Class.IsOptional; });
+ return any_of(Classes,
+ [](const ClassInfo &Class) { return Class.IsOptional; });
}
};
@@ -1017,7 +1017,7 @@ void MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info,
case '$': {
if (InTok) {
- addAsmOperand(String.slice(Prev, i), IsIsolatedToken);
+ addAsmOperand(String.slice(Prev, i), IsIsolatedToken);
InTok = false;
IsIsolatedToken = false;
}
@@ -1112,7 +1112,7 @@ static std::string getEnumNameForToken(StringRef Str) {
case '-': Res += "_MINUS_"; break;
case '#': Res += "_HASH_"; break;
default:
- if (isAlnum(*it))
+ if (isAlnum(*it))
Res += *it;
else
Res += "_" + utostr((unsigned) *it) + "_";
@@ -1977,7 +1977,7 @@ emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
}
CvtOS << " unsigned OpIdx;\n";
CvtOS << " Inst.setOpcode(Opcode);\n";
- CvtOS << " for (const uint8_t *p = Converter; *p; p += 2) {\n";
+ CvtOS << " for (const uint8_t *p = Converter; *p; p += 2) {\n";
if (HasOptionalOperands) {
CvtOS << " OpIdx = *(p + 1) - DefaultsOffset[*(p + 1)];\n";
} else {
@@ -1987,14 +1987,14 @@ emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
CvtOS << " default: llvm_unreachable(\"invalid conversion entry!\");\n";
CvtOS << " case CVT_Reg:\n";
CvtOS << " static_cast<" << TargetOperandClass
- << " &>(*Operands[OpIdx]).addRegOperands(Inst, 1);\n";
+ << " &>(*Operands[OpIdx]).addRegOperands(Inst, 1);\n";
CvtOS << " break;\n";
CvtOS << " case CVT_Tied: {\n";
CvtOS << " assert(OpIdx < (size_t)(std::end(TiedAsmOperandTable) -\n";
- CvtOS << " std::begin(TiedAsmOperandTable)) &&\n";
+ CvtOS << " std::begin(TiedAsmOperandTable)) &&\n";
CvtOS << " \"Tied operand not found\");\n";
CvtOS << " unsigned TiedResOpnd = TiedAsmOperandTable[OpIdx][0];\n";
- CvtOS << " if (TiedResOpnd != (uint8_t)-1)\n";
+ CvtOS << " if (TiedResOpnd != (uint8_t)-1)\n";
CvtOS << " Inst.addOperand(Inst.getOperand(TiedResOpnd));\n";
CvtOS << " break;\n";
CvtOS << " }\n";
@@ -2009,7 +2009,7 @@ emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
<< " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
<< " unsigned NumMCOperands = 0;\n"
<< " const uint8_t *Converter = ConversionTable[Kind];\n"
- << " for (const uint8_t *p = Converter; *p; p += 2) {\n"
+ << " for (const uint8_t *p = Converter; *p; p += 2) {\n"
<< " switch (*p) {\n"
<< " default: llvm_unreachable(\"invalid conversion entry!\");\n"
<< " case CVT_Reg:\n"
@@ -2126,12 +2126,12 @@ emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
<< OpInfo.MINumOperands << ");\n"
<< " } else {\n"
<< " static_cast<" << TargetOperandClass
- << " &>(*Operands[OpIdx])." << Op.Class->RenderMethod
+ << " &>(*Operands[OpIdx])." << Op.Class->RenderMethod
<< "(Inst, " << OpInfo.MINumOperands << ");\n"
<< " }\n";
} else {
CvtOS << " static_cast<" << TargetOperandClass
- << " &>(*Operands[OpIdx])." << Op.Class->RenderMethod
+ << " &>(*Operands[OpIdx])." << Op.Class->RenderMethod
<< "(Inst, " << OpInfo.MINumOperands << ");\n";
}
CvtOS << " break;\n";
@@ -2387,9 +2387,9 @@ static void emitMatchClassEnumeration(CodeGenTarget &Target,
static void emitOperandMatchErrorDiagStrings(AsmMatcherInfo &Info, raw_ostream &OS) {
// If the target does not use DiagnosticString for any operands, don't emit
// an unused function.
- if (llvm::all_of(Info.Classes, [](const ClassInfo &CI) {
- return CI.DiagnosticString.empty();
- }))
+ if (llvm::all_of(Info.Classes, [](const ClassInfo &CI) {
+ return CI.DiagnosticString.empty();
+ }))
return;
OS << "static const char *getMatchKindDiag(" << Info.Target.getName()
@@ -2445,7 +2445,7 @@ static void emitValidateOperandClass(AsmMatcherInfo &Info,
OS << "static unsigned validateOperandClass(MCParsedAsmOperand &GOp, "
<< "MatchClassKind Kind) {\n";
OS << " " << Info.Target.getName() << "Operand &Operand = ("
- << Info.Target.getName() << "Operand &)GOp;\n";
+ << Info.Target.getName() << "Operand &)GOp;\n";
// The InvalidMatchClass is not to match any operand.
OS << " if (Kind == InvalidMatchClass)\n";
@@ -2808,7 +2808,7 @@ static bool emitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info,
Record *AsmVariant = Target.getAsmParserVariant(VC);
int AsmParserVariantNo = AsmVariant->getValueAsInt("Variant");
StringRef AsmParserVariantName = AsmVariant->getValueAsString("Name");
- OS << " case " << AsmParserVariantNo << ":\n";
+ OS << " case " << AsmParserVariantNo << ":\n";
emitMnemonicAliasVariant(OS, Info, Aliases, /*Indent=*/2,
AsmParserVariantName);
OS << " break;\n";
@@ -2877,7 +2877,7 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
OS << " { ";
// Store a pascal-style length byte in the mnemonic.
- std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.lower();
+ std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.lower();
OS << StringTable.GetOrAddStringOffset(LenMnemonic, false)
<< " /* " << II.Mnemonic << " */, ";
@@ -2975,7 +2975,7 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
"FeatureBitsets[it->RequiredFeaturesIdx];\n";
OS << " if (!ParseForAllFeatures && (AvailableFeatures & "
"RequiredFeatures) != RequiredFeatures)\n";
- OS << " continue;\n\n";
+ OS << " continue;\n\n";
// Emit check to ensure the operand number matches.
OS << " // check if the operand in question has a custom parser.\n";
@@ -3008,10 +3008,10 @@ static void emitAsmTiedOperandConstraints(CodeGenTarget &Target,
OS << " uint64_t &ErrorInfo) {\n";
OS << " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n";
OS << " const uint8_t *Converter = ConversionTable[Kind];\n";
- OS << " for (const uint8_t *p = Converter; *p; p += 2) {\n";
+ OS << " for (const uint8_t *p = Converter; *p; p += 2) {\n";
OS << " switch (*p) {\n";
OS << " case CVT_Tied: {\n";
- OS << " unsigned OpIdx = *(p + 1);\n";
+ OS << " unsigned OpIdx = *(p + 1);\n";
OS << " assert(OpIdx < (size_t)(std::end(TiedAsmOperandTable) -\n";
OS << " std::begin(TiedAsmOperandTable)) &&\n";
OS << " \"Tied operand not found\");\n";
@@ -3083,7 +3083,7 @@ static void emitMnemonicSpellChecker(raw_ostream &OS, CodeGenTarget &Target,
OS << "\n";
OS << " std::string Res = \", did you mean: \";\n";
OS << " unsigned i = 0;\n";
- OS << " for (; i < Candidates.size() - 1; i++)\n";
+ OS << " for (; i < Candidates.size() - 1; i++)\n";
OS << " Res += Candidates[i].str() + \", \";\n";
OS << " return Res + Candidates[i].str() + \"?\";\n";
}
@@ -3091,68 +3091,68 @@ static void emitMnemonicSpellChecker(raw_ostream &OS, CodeGenTarget &Target,
OS << "\n";
}
-static void emitMnemonicChecker(raw_ostream &OS,
- CodeGenTarget &Target,
- unsigned VariantCount,
- bool HasMnemonicFirst,
- bool HasMnemonicAliases) {
- OS << "static bool " << Target.getName()
- << "CheckMnemonic(StringRef Mnemonic,\n";
- OS << " "
- << "const FeatureBitset &AvailableFeatures,\n";
- OS << " "
- << "unsigned VariantID) {\n";
-
- if (!VariantCount) {
- OS << " return false;\n";
- } else {
- if (HasMnemonicAliases) {
- OS << " // Process all MnemonicAliases to remap the mnemonic.\n";
- OS << " applyMnemonicAliases(Mnemonic, AvailableFeatures, VariantID);";
- OS << "\n\n";
- }
- OS << " // Find the appropriate table for this asm variant.\n";
- OS << " const MatchEntry *Start, *End;\n";
- OS << " switch (VariantID) {\n";
- OS << " default: llvm_unreachable(\"invalid variant!\");\n";
- for (unsigned VC = 0; VC != VariantCount; ++VC) {
- Record *AsmVariant = Target.getAsmParserVariant(VC);
- int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
- OS << " case " << AsmVariantNo << ": Start = std::begin(MatchTable" << VC
- << "); End = std::end(MatchTable" << VC << "); break;\n";
- }
- OS << " }\n\n";
-
- OS << " // Search the table.\n";
- if (HasMnemonicFirst) {
- OS << " auto MnemonicRange = "
- "std::equal_range(Start, End, Mnemonic, LessOpcode());\n\n";
- } else {
- OS << " auto MnemonicRange = std::make_pair(Start, End);\n";
- OS << " unsigned SIndex = Mnemonic.empty() ? 0 : 1;\n";
- OS << " if (!Mnemonic.empty())\n";
- OS << " MnemonicRange = "
- << "std::equal_range(Start, End, Mnemonic.lower(), LessOpcode());\n\n";
- }
-
- OS << " if (MnemonicRange.first == MnemonicRange.second)\n";
- OS << " return false;\n\n";
-
- OS << " for (const MatchEntry *it = MnemonicRange.first, "
- << "*ie = MnemonicRange.second;\n";
- OS << " it != ie; ++it) {\n";
- OS << " const FeatureBitset &RequiredFeatures =\n";
- OS << " FeatureBitsets[it->RequiredFeaturesIdx];\n";
- OS << " if ((AvailableFeatures & RequiredFeatures) == ";
- OS << "RequiredFeatures)\n";
- OS << " return true;\n";
- OS << " }\n";
- OS << " return false;\n";
- }
- OS << "}\n";
- OS << "\n";
-}
-
+static void emitMnemonicChecker(raw_ostream &OS,
+ CodeGenTarget &Target,
+ unsigned VariantCount,
+ bool HasMnemonicFirst,
+ bool HasMnemonicAliases) {
+ OS << "static bool " << Target.getName()
+ << "CheckMnemonic(StringRef Mnemonic,\n";
+ OS << " "
+ << "const FeatureBitset &AvailableFeatures,\n";
+ OS << " "
+ << "unsigned VariantID) {\n";
+
+ if (!VariantCount) {
+ OS << " return false;\n";
+ } else {
+ if (HasMnemonicAliases) {
+ OS << " // Process all MnemonicAliases to remap the mnemonic.\n";
+ OS << " applyMnemonicAliases(Mnemonic, AvailableFeatures, VariantID);";
+ OS << "\n\n";
+ }
+ OS << " // Find the appropriate table for this asm variant.\n";
+ OS << " const MatchEntry *Start, *End;\n";
+ OS << " switch (VariantID) {\n";
+ OS << " default: llvm_unreachable(\"invalid variant!\");\n";
+ for (unsigned VC = 0; VC != VariantCount; ++VC) {
+ Record *AsmVariant = Target.getAsmParserVariant(VC);
+ int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
+ OS << " case " << AsmVariantNo << ": Start = std::begin(MatchTable" << VC
+ << "); End = std::end(MatchTable" << VC << "); break;\n";
+ }
+ OS << " }\n\n";
+
+ OS << " // Search the table.\n";
+ if (HasMnemonicFirst) {
+ OS << " auto MnemonicRange = "
+ "std::equal_range(Start, End, Mnemonic, LessOpcode());\n\n";
+ } else {
+ OS << " auto MnemonicRange = std::make_pair(Start, End);\n";
+ OS << " unsigned SIndex = Mnemonic.empty() ? 0 : 1;\n";
+ OS << " if (!Mnemonic.empty())\n";
+ OS << " MnemonicRange = "
+ << "std::equal_range(Start, End, Mnemonic.lower(), LessOpcode());\n\n";
+ }
+
+ OS << " if (MnemonicRange.first == MnemonicRange.second)\n";
+ OS << " return false;\n\n";
+
+ OS << " for (const MatchEntry *it = MnemonicRange.first, "
+ << "*ie = MnemonicRange.second;\n";
+ OS << " it != ie; ++it) {\n";
+ OS << " const FeatureBitset &RequiredFeatures =\n";
+ OS << " FeatureBitsets[it->RequiredFeaturesIdx];\n";
+ OS << " if ((AvailableFeatures & RequiredFeatures) == ";
+ OS << "RequiredFeatures)\n";
+ OS << " return true;\n";
+ OS << " }\n";
+ OS << " return false;\n";
+ }
+ OS << "}\n";
+ OS << "\n";
+}
+
// Emit a function mapping match classes to strings, for debugging.
static void emitMatchClassKindNames(std::forward_list<ClassInfo> &Infos,
raw_ostream &OS) {
@@ -3252,7 +3252,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << "#undef GET_ASSEMBLER_HEADER\n";
OS << " // This should be included into the middle of the declaration of\n";
OS << " // your subclasses implementation of MCTargetAsmParser.\n";
- OS << " FeatureBitset ComputeAvailableFeatures(const FeatureBitset &FB) const;\n";
+ OS << " FeatureBitset ComputeAvailableFeatures(const FeatureBitset &FB) const;\n";
if (HasOptionalOperands) {
OS << " void convertToMCInst(unsigned Kind, MCInst &Inst, "
<< "unsigned Opcode,\n"
@@ -3382,7 +3382,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
HasDeprecation |= MI->HasDeprecation;
// Store a pascal-style length byte in the mnemonic.
- std::string LenMnemonic = char(MI->Mnemonic.size()) + MI->Mnemonic.lower();
+ std::string LenMnemonic = char(MI->Mnemonic.size()) + MI->Mnemonic.lower();
MaxMnemonicIndex = std::max(MaxMnemonicIndex,
StringTable.GetOrAddStringOffset(LenMnemonic, false));
}
@@ -3496,8 +3496,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
continue;
// Store a pascal-style length byte in the mnemonic.
- std::string LenMnemonic =
- char(MI->Mnemonic.size()) + MI->Mnemonic.lower();
+ std::string LenMnemonic =
+ char(MI->Mnemonic.size()) + MI->Mnemonic.lower();
OS << " { " << StringTable.GetOrAddStringOffset(LenMnemonic, false)
<< " /* " << MI->Mnemonic << " */, "
<< Target.getInstNamespace() << "::"
@@ -3556,12 +3556,12 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " // Get the instruction mnemonic, which is the first token.\n";
if (HasMnemonicFirst) {
OS << " StringRef Mnemonic = ((" << Target.getName()
- << "Operand &)*Operands[0]).getToken();\n\n";
+ << "Operand &)*Operands[0]).getToken();\n\n";
} else {
OS << " StringRef Mnemonic;\n";
OS << " if (Operands[0]->isToken())\n";
OS << " Mnemonic = ((" << Target.getName()
- << "Operand &)*Operands[0]).getToken();\n\n";
+ << "Operand &)*Operands[0]).getToken();\n\n";
}
if (HasMnemonicAliases) {
@@ -3611,7 +3611,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
}
OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"AsmMatcher: found \" <<\n"
- << " std::distance(MnemonicRange.first, MnemonicRange.second) <<\n"
+ << " std::distance(MnemonicRange.first, MnemonicRange.second) <<\n"
<< " \" encodings with mnemonic '\" << Mnemonic << \"'\\n\");\n\n";
OS << " // Return a more specific error code if no mnemonics match.\n";
@@ -3786,10 +3786,10 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " FeatureBitset NewMissingFeatures = RequiredFeatures & "
"~AvailableFeatures;\n";
OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Missing target features:\";\n";
- OS << " for (unsigned I = 0, E = NewMissingFeatures.size(); I != E; ++I)\n";
- OS << " if (NewMissingFeatures[I])\n";
- OS << " dbgs() << ' ' << I;\n";
- OS << " dbgs() << \"\\n\");\n";
+ OS << " for (unsigned I = 0, E = NewMissingFeatures.size(); I != E; ++I)\n";
+ OS << " if (NewMissingFeatures[I])\n";
+ OS << " dbgs() << ' ' << I;\n";
+ OS << " dbgs() << \"\\n\");\n";
if (ReportMultipleNearMisses) {
OS << " FeaturesNearMiss = NearMissInfo::getMissedFeature(NewMissingFeatures);\n";
} else {
@@ -3924,7 +3924,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " getTargetOptions().MCNoDeprecatedWarn &&\n";
OS << " MII.getDeprecatedInfo(Inst, getSTI(), Info)) {\n";
OS << " SMLoc Loc = ((" << Target.getName()
- << "Operand &)*Operands[0]).getStartLoc();\n";
+ << "Operand &)*Operands[0]).getStartLoc();\n";
OS << " getParser().Warning(Loc, Info, None);\n";
OS << " }\n";
}
@@ -3967,14 +3967,14 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
emitMnemonicSpellChecker(OS, Target, VariantCount);
OS << "#endif // GET_MNEMONIC_SPELL_CHECKER\n\n";
-
- OS << "\n#ifdef GET_MNEMONIC_CHECKER\n";
- OS << "#undef GET_MNEMONIC_CHECKER\n\n";
-
- emitMnemonicChecker(OS, Target, VariantCount,
- HasMnemonicFirst, HasMnemonicAliases);
-
- OS << "#endif // GET_MNEMONIC_CHECKER\n\n";
+
+ OS << "\n#ifdef GET_MNEMONIC_CHECKER\n";
+ OS << "#undef GET_MNEMONIC_CHECKER\n\n";
+
+ emitMnemonicChecker(OS, Target, VariantCount,
+ HasMnemonicFirst, HasMnemonicAliases);
+
+ OS << "#endif // GET_MNEMONIC_CHECKER\n\n";
}
namespace llvm {
diff --git a/contrib/libs/llvm12/utils/TableGen/AsmWriterEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/AsmWriterEmitter.cpp
index 41f41e8ed2..92df204475 100644
--- a/contrib/libs/llvm12/utils/TableGen/AsmWriterEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/AsmWriterEmitter.cpp
@@ -65,14 +65,14 @@ public:
void run(raw_ostream &o);
private:
- void EmitGetMnemonic(
- raw_ostream &o,
- std::vector<std::vector<std::string>> &TableDrivenOperandPrinters,
- unsigned &BitsLeft, unsigned &AsmStrBits);
- void EmitPrintInstruction(
- raw_ostream &o,
- std::vector<std::vector<std::string>> &TableDrivenOperandPrinters,
- unsigned &BitsLeft, unsigned &AsmStrBits);
+ void EmitGetMnemonic(
+ raw_ostream &o,
+ std::vector<std::vector<std::string>> &TableDrivenOperandPrinters,
+ unsigned &BitsLeft, unsigned &AsmStrBits);
+ void EmitPrintInstruction(
+ raw_ostream &o,
+ std::vector<std::vector<std::string>> &TableDrivenOperandPrinters,
+ unsigned &BitsLeft, unsigned &AsmStrBits);
void EmitGetRegisterName(raw_ostream &o);
void EmitPrintAliasInstruction(raw_ostream &O);
@@ -218,11 +218,11 @@ FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands,
// Otherwise, scan to see if all of the other instructions in this command
// set share the operand.
- if (any_of(drop_begin(Idxs), [&](unsigned Idx) {
- const AsmWriterInst &OtherInst = Instructions[Idx];
- return OtherInst.Operands.size() == Op ||
- OtherInst.Operands[Op] != FirstInst.Operands[Op];
- }))
+ if (any_of(drop_begin(Idxs), [&](unsigned Idx) {
+ const AsmWriterInst &OtherInst = Instructions[Idx];
+ return OtherInst.Operands.size() == Op ||
+ OtherInst.Operands[Op] != FirstInst.Operands[Op];
+ }))
break;
// Okay, everything in this command set has the same next operand. Add it
@@ -293,19 +293,19 @@ static void UnescapeAliasString(std::string &Str) {
}
}
-void AsmWriterEmitter::EmitGetMnemonic(
- raw_ostream &O,
- std::vector<std::vector<std::string>> &TableDrivenOperandPrinters,
- unsigned &BitsLeft, unsigned &AsmStrBits) {
+void AsmWriterEmitter::EmitGetMnemonic(
+ raw_ostream &O,
+ std::vector<std::vector<std::string>> &TableDrivenOperandPrinters,
+ unsigned &BitsLeft, unsigned &AsmStrBits) {
Record *AsmWriter = Target.getAsmWriter();
StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget");
- O << "/// getMnemonic - This method is automatically generated by "
+ O << "/// getMnemonic - This method is automatically generated by "
"tablegen\n"
"/// from the instruction set description.\n"
- "std::pair<const char *, uint64_t> "
- << Target.getName() << ClassName << "::getMnemonic(const MCInst *MI) {\n";
+ "std::pair<const char *, uint64_t> "
+ << Target.getName() << ClassName << "::getMnemonic(const MCInst *MI) {\n";
// Build an aggregate string, and build a table of offsets into it.
SequenceToOffsetTable<std::string> StringTable;
@@ -351,11 +351,11 @@ void AsmWriterEmitter::EmitGetMnemonic(
}
// Figure out how many bits we used for the string index.
- AsmStrBits = Log2_32_Ceil(MaxStringIdx + 2);
+ AsmStrBits = Log2_32_Ceil(MaxStringIdx + 2);
// To reduce code size, we compactify common instructions into a few bits
// in the opcode-indexed table.
- BitsLeft = OpcodeInfoBits - AsmStrBits;
+ BitsLeft = OpcodeInfoBits - AsmStrBits;
while (true) {
std::vector<std::string> UniqueOperandCommands;
@@ -435,48 +435,48 @@ void AsmWriterEmitter::EmitGetMnemonic(
++Table;
}
- O << " // Emit the opcode for the instruction.\n";
- O << BitsString;
-
- // Return mnemonic string and bits.
- O << " return {AsmStrs+(Bits & " << (1 << AsmStrBits) - 1
- << ")-1, Bits};\n\n";
-
- O << "}\n";
-}
-
-/// EmitPrintInstruction - Generate the code for the "printInstruction" method
-/// implementation. Destroys all instances of AsmWriterInst information, by
-/// clearing the Instructions vector.
-void AsmWriterEmitter::EmitPrintInstruction(
- raw_ostream &O,
- std::vector<std::vector<std::string>> &TableDrivenOperandPrinters,
- unsigned &BitsLeft, unsigned &AsmStrBits) {
- const unsigned OpcodeInfoBits = 64;
- Record *AsmWriter = Target.getAsmWriter();
- StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
- bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget");
-
- O << "/// printInstruction - This method is automatically generated by "
- "tablegen\n"
- "/// from the instruction set description.\n"
- "void "
- << Target.getName() << ClassName
- << "::printInstruction(const MCInst *MI, uint64_t Address, "
- << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "")
- << "raw_ostream &O) {\n";
-
+ O << " // Emit the opcode for the instruction.\n";
+ O << BitsString;
+
+ // Return mnemonic string and bits.
+ O << " return {AsmStrs+(Bits & " << (1 << AsmStrBits) - 1
+ << ")-1, Bits};\n\n";
+
+ O << "}\n";
+}
+
+/// EmitPrintInstruction - Generate the code for the "printInstruction" method
+/// implementation. Destroys all instances of AsmWriterInst information, by
+/// clearing the Instructions vector.
+void AsmWriterEmitter::EmitPrintInstruction(
+ raw_ostream &O,
+ std::vector<std::vector<std::string>> &TableDrivenOperandPrinters,
+ unsigned &BitsLeft, unsigned &AsmStrBits) {
+ const unsigned OpcodeInfoBits = 64;
+ Record *AsmWriter = Target.getAsmWriter();
+ StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
+ bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget");
+
+ O << "/// printInstruction - This method is automatically generated by "
+ "tablegen\n"
+ "/// from the instruction set description.\n"
+ "void "
+ << Target.getName() << ClassName
+ << "::printInstruction(const MCInst *MI, uint64_t Address, "
+ << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "")
+ << "raw_ostream &O) {\n";
+
// Emit the initial tab character.
O << " O << \"\\t\";\n\n";
// Emit the starting string.
- O << " auto MnemonicInfo = getMnemonic(MI);\n\n";
- O << " O << MnemonicInfo.first;\n\n";
+ O << " auto MnemonicInfo = getMnemonic(MI);\n\n";
+ O << " O << MnemonicInfo.first;\n\n";
+
+ O << " uint" << ((BitsLeft < (OpcodeInfoBits - 32)) ? 64 : 32)
+ << "_t Bits = MnemonicInfo.second;\n"
+ << " assert(Bits != 0 && \"Cannot print this instruction.\");\n";
- O << " uint" << ((BitsLeft < (OpcodeInfoBits - 32)) ? 64 : 32)
- << "_t Bits = MnemonicInfo.second;\n"
- << " assert(Bits != 0 && \"Cannot print this instruction.\");\n";
-
// Output the table driven operand information.
BitsLeft = OpcodeInfoBits-AsmStrBits;
for (unsigned i = 0, e = TableDrivenOperandPrinters.size(); i != e; ++i) {
@@ -521,8 +521,8 @@ void AsmWriterEmitter::EmitPrintInstruction(
}
// Okay, delete instructions with no operand info left.
- llvm::erase_if(Instructions,
- [](AsmWriterInst &Inst) { return Inst.Operands.empty(); });
+ llvm::erase_if(Instructions,
+ [](AsmWriterInst &Inst) { return Inst.Operands.empty(); });
// Because this is a vector, we want to emit from the end. Reverse all of the
// elements in the vector.
@@ -713,7 +713,7 @@ public:
++Next;
} else {
// $name, just eat the usual suspects.
- while (I != End && (isAlnum(*I) || *I == '_'))
+ while (I != End && (isAlnum(*I) || *I == '_'))
++I;
Next = I;
}
@@ -1260,10 +1260,10 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
<< " break;\n";
for (unsigned i = 0; i < MCOpPredicates.size(); ++i) {
- StringRef MCOpPred = MCOpPredicates[i]->getValueAsString("MCOperandPredicate");
- O << " case " << i + 1 << ": {\n"
- << MCOpPred.data() << "\n"
- << " }\n";
+ StringRef MCOpPred = MCOpPredicates[i]->getValueAsString("MCOperandPredicate");
+ O << " case " << i + 1 << ": {\n"
+ << MCOpPred.data() << "\n"
+ << " }\n";
}
O << " }\n"
<< "}\n\n";
@@ -1287,11 +1287,11 @@ AsmWriterEmitter::AsmWriterEmitter(RecordKeeper &R) : Records(R), Target(R) {
}
void AsmWriterEmitter::run(raw_ostream &O) {
- std::vector<std::vector<std::string>> TableDrivenOperandPrinters;
- unsigned BitsLeft = 0;
- unsigned AsmStrBits = 0;
- EmitGetMnemonic(O, TableDrivenOperandPrinters, BitsLeft, AsmStrBits);
- EmitPrintInstruction(O, TableDrivenOperandPrinters, BitsLeft, AsmStrBits);
+ std::vector<std::vector<std::string>> TableDrivenOperandPrinters;
+ unsigned BitsLeft = 0;
+ unsigned AsmStrBits = 0;
+ EmitGetMnemonic(O, TableDrivenOperandPrinters, BitsLeft, AsmStrBits);
+ EmitPrintInstruction(O, TableDrivenOperandPrinters, BitsLeft, AsmStrBits);
EmitGetRegisterName(O);
EmitPrintAliasInstruction(O);
}
diff --git a/contrib/libs/llvm12/utils/TableGen/AsmWriterInst.cpp b/contrib/libs/llvm12/utils/TableGen/AsmWriterInst.cpp
index 76d05e3c2c..cf24f79334 100644
--- a/contrib/libs/llvm12/utils/TableGen/AsmWriterInst.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/AsmWriterInst.cpp
@@ -18,7 +18,7 @@
using namespace llvm;
-static bool isIdentChar(char C) { return isAlnum(C) || C == '_'; }
+static bool isIdentChar(char C) { return isAlnum(C) || C == '_'; }
std::string AsmWriterOperand::getCode(bool PassSubtarget) const {
if (OperandType == isLiteralTextOperand) {
diff --git a/contrib/libs/llvm12/utils/TableGen/CallingConvEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/CallingConvEmitter.cpp
index c11f307032..9e997483d2 100644
--- a/contrib/libs/llvm12/utils/TableGen/CallingConvEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/CallingConvEmitter.cpp
@@ -38,7 +38,7 @@ void CallingConvEmitter::run(raw_ostream &O) {
// Emit prototypes for all of the non-custom CC's so that they can forward ref
// each other.
- Records.startTimer("Emit prototypes");
+ Records.startTimer("Emit prototypes");
for (Record *CC : CCs) {
if (!CC->getValueAsBit("Custom")) {
unsigned Pad = CC->getName().size();
@@ -57,7 +57,7 @@ void CallingConvEmitter::run(raw_ostream &O) {
}
// Emit each non-custom calling convention description in full.
- Records.startTimer("Emit full descriptions");
+ Records.startTimer("Emit full descriptions");
for (Record *CC : CCs) {
if (!CC->getValueAsBit("Custom"))
EmitCallingConv(CC, O);
@@ -87,7 +87,7 @@ void CallingConvEmitter::EmitCallingConv(Record *CC, raw_ostream &O) {
EmitAction(CCActions->getElementAsRecord(i), 2, O);
}
- O << "\n return true; // CC didn't match.\n";
+ O << "\n return true; // CC didn't match.\n";
O << "}\n";
}
@@ -240,11 +240,11 @@ void CallingConvEmitter::EmitAction(Record *Action,
O << IndentStr << "LocInfo = CCValAssign::FPExt;\n";
} else {
O << IndentStr << "if (ArgFlags.isSExt())\n"
- << IndentStr << " LocInfo = CCValAssign::SExt;\n"
+ << IndentStr << " LocInfo = CCValAssign::SExt;\n"
<< IndentStr << "else if (ArgFlags.isZExt())\n"
- << IndentStr << " LocInfo = CCValAssign::ZExt;\n"
+ << IndentStr << " LocInfo = CCValAssign::ZExt;\n"
<< IndentStr << "else\n"
- << IndentStr << " LocInfo = CCValAssign::AExt;\n";
+ << IndentStr << " LocInfo = CCValAssign::AExt;\n";
}
} else if (Action->isSubClassOf("CCPromoteToUpperBitsInType")) {
Record *DestTy = Action->getValueAsDef("DestTy");
@@ -256,11 +256,11 @@ void CallingConvEmitter::EmitAction(Record *Action,
"point");
} else {
O << IndentStr << "if (ArgFlags.isSExt())\n"
- << IndentStr << " LocInfo = CCValAssign::SExtUpper;\n"
+ << IndentStr << " LocInfo = CCValAssign::SExtUpper;\n"
<< IndentStr << "else if (ArgFlags.isZExt())\n"
- << IndentStr << " LocInfo = CCValAssign::ZExtUpper;\n"
+ << IndentStr << " LocInfo = CCValAssign::ZExtUpper;\n"
<< IndentStr << "else\n"
- << IndentStr << " LocInfo = CCValAssign::AExtUpper;\n";
+ << IndentStr << " LocInfo = CCValAssign::AExtUpper;\n";
}
} else if (Action->isSubClassOf("CCBitConvertToType")) {
Record *DestTy = Action->getValueAsDef("DestTy");
@@ -284,7 +284,7 @@ void CallingConvEmitter::EmitAction(Record *Action,
O << IndentStr
<< "if (" << Action->getValueAsString("FuncName") << "(ValNo, ValVT, "
<< "LocVT, LocInfo, ArgFlags, State))\n";
- O << IndentStr << " return false;\n";
+ O << IndentStr << " return false;\n";
} else {
errs() << *Action;
PrintFatalError(Action->getLoc(), "Unknown CCAction!");
diff --git a/contrib/libs/llvm12/utils/TableGen/CodeEmitterGen.cpp b/contrib/libs/llvm12/utils/TableGen/CodeEmitterGen.cpp
index b92036616b..0b9a84de05 100644
--- a/contrib/libs/llvm12/utils/TableGen/CodeEmitterGen.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/CodeEmitterGen.cpp
@@ -311,7 +311,7 @@ std::string CodeEmitterGen::getInstructionCaseForEncoding(Record *R, Record *Enc
for (const RecordVal &RV : EncodingDef->getValues()) {
// Ignore fixed fields in the record, we're looking for values like:
// bits<5> RST = { ?, ?, ?, ?, ? };
- if (RV.isNonconcreteOK() || RV.getValue()->isComplete())
+ if (RV.isNonconcreteOK() || RV.getValue()->isComplete())
continue;
AddCodeToMergeInOperand(R, BI, std::string(RV.getName()), NumberedOp,
@@ -483,7 +483,7 @@ void CodeEmitterGen::run(raw_ostream &o) {
<< " Inst = Inst.zext(" << BitWidth << ");\n"
<< " if (Scratch.getBitWidth() != " << BitWidth << ")\n"
<< " Scratch = Scratch.zext(" << BitWidth << ");\n"
- << " LoadIntFromMemory(Inst, (uint8_t *)&InstBits[opcode * " << NumWords
+ << " LoadIntFromMemory(Inst, (uint8_t *)&InstBits[opcode * " << NumWords
<< "], " << NumBytes << ");\n"
<< " APInt &Value = Inst;\n"
<< " APInt &op = Scratch;\n"
@@ -643,9 +643,9 @@ void CodeEmitterGen::run(raw_ostream &o) {
<< " report_fatal_error(Msg.str());\n"
<< " }\n"
<< "#else\n"
- << " // Silence unused variable warning on targets that don't use MCII for "
+ << " // Silence unused variable warning on targets that don't use MCII for "
"other purposes (e.g. BPF).\n"
- << " (void)MCII;\n"
+ << " (void)MCII;\n"
<< "#endif // NDEBUG\n";
o << "}\n";
o << "#endif\n";
diff --git a/contrib/libs/llvm12/utils/TableGen/CodeGenDAGPatterns.cpp b/contrib/libs/llvm12/utils/TableGen/CodeGenDAGPatterns.cpp
index 742fa65cdf..1ca4a68eb1 100644
--- a/contrib/libs/llvm12/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -507,9 +507,9 @@ bool TypeInfer::EnforceSmallerThan(TypeSetByHwMode &Small,
// Always treat non-scalable MVTs as smaller than scalable MVTs for the
// purposes of ordering.
auto ASize = std::make_tuple(A.isScalableVector(), A.getScalarSizeInBits(),
- A.getSizeInBits().getKnownMinSize());
+ A.getSizeInBits().getKnownMinSize());
auto BSize = std::make_tuple(B.isScalableVector(), B.getScalarSizeInBits(),
- B.getSizeInBits().getKnownMinSize());
+ B.getSizeInBits().getKnownMinSize());
return ASize < BSize;
};
auto SameKindLE = [](MVT A, MVT B) -> bool {
@@ -520,10 +520,10 @@ bool TypeInfer::EnforceSmallerThan(TypeSetByHwMode &Small,
std::make_tuple(B.isVector(), B.isScalableVector()))
return false;
- return std::make_tuple(A.getScalarSizeInBits(),
- A.getSizeInBits().getKnownMinSize()) <=
- std::make_tuple(B.getScalarSizeInBits(),
- B.getSizeInBits().getKnownMinSize());
+ return std::make_tuple(A.getScalarSizeInBits(),
+ A.getSizeInBits().getKnownMinSize()) <=
+ std::make_tuple(B.getScalarSizeInBits(),
+ B.getSizeInBits().getKnownMinSize());
};
for (unsigned M : Modes) {
@@ -730,14 +730,14 @@ bool TypeInfer::EnforceSameSize(TypeSetByHwMode &A, TypeSetByHwMode &B) {
if (B.empty())
Changed |= EnforceAny(B);
- auto NoSize = [](const SmallSet<TypeSize, 2> &Sizes, MVT T) -> bool {
+ auto NoSize = [](const SmallSet<TypeSize, 2> &Sizes, MVT T) -> bool {
return !Sizes.count(T.getSizeInBits());
};
for (unsigned M : union_modes(A, B)) {
TypeSetByHwMode::SetType &AS = A.get(M);
TypeSetByHwMode::SetType &BS = B.get(M);
- SmallSet<TypeSize, 2> AN, BN;
+ SmallSet<TypeSize, 2> AN, BN;
for (MVT T : AS)
AN.insert(T.getSizeInBits());
@@ -873,7 +873,7 @@ bool TreePredicateFn::hasPredCode() const {
}
std::string TreePredicateFn::getPredCode() const {
- std::string Code;
+ std::string Code;
if (!isLoad() && !isStore() && !isAtomic()) {
Record *MemoryVT = getMemoryVT();
@@ -2390,7 +2390,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
MVT::SimpleValueType VT = P.second.SimpleTy;
if (VT == MVT::iPTR || VT == MVT::iPTRAny)
continue;
- unsigned Size = MVT(VT).getFixedSizeInBits();
+ unsigned Size = MVT(VT).getFixedSizeInBits();
// Make sure that the value is representable for this type.
if (Size >= 32)
continue;
@@ -3088,7 +3088,7 @@ CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R,
VerifyInstructionFlags();
}
-Record *CodeGenDAGPatterns::getSDNodeNamed(StringRef Name) const {
+Record *CodeGenDAGPatterns::getSDNodeNamed(StringRef Name) const {
Record *N = Records.getDef(Name);
if (!N || !N->isSubClassOf("SDNode"))
PrintFatalError("Error getting SDNode '" + Name + "'!");
@@ -3591,9 +3591,9 @@ static bool hasNullFragReference(DagInit *DI) {
if (Operator->getName() == "null_frag") return true;
// If any of the arguments reference the null fragment, return true.
for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) {
- if (auto Arg = dyn_cast<DefInit>(DI->getArg(i)))
- if (Arg->getDef()->getName() == "null_frag")
- return true;
+ if (auto Arg = dyn_cast<DefInit>(DI->getArg(i)))
+ if (Arg->getDef()->getName() == "null_frag")
+ return true;
DagInit *Arg = dyn_cast<DagInit>(DI->getArg(i));
if (Arg && hasNullFragReference(Arg))
return true;
@@ -3701,11 +3701,11 @@ void CodeGenDAGPatterns::parseInstructionPattern(
for (unsigned i = 0; i != NumResults; ++i) {
if (i == CGI.Operands.size()) {
const std::string &OpName =
- llvm::find_if(
- InstResults,
- [](const std::pair<std::string, TreePatternNodePtr> &P) {
- return P.second;
- })
+ llvm::find_if(
+ InstResults,
+ [](const std::pair<std::string, TreePatternNodePtr> &P) {
+ return P.second;
+ })
->first;
I.error("'" + OpName + "' set but does not appear in operand list!");
@@ -4294,7 +4294,7 @@ void CodeGenDAGPatterns::ExpandHwModeBasedTypes() {
std::vector<Predicate> Preds = P.Predicates;
const std::vector<Predicate> &MC = ModeChecks[Mode];
- llvm::append_range(Preds, MC);
+ llvm::append_range(Preds, MC);
PatternsToMatch.emplace_back(P.getSrcRecord(), Preds, std::move(NewSrc),
std::move(NewDst), P.getDstRegs(),
P.getAddedComplexity(), Record::getNewUID(),
diff --git a/contrib/libs/llvm12/utils/TableGen/CodeGenDAGPatterns.h b/contrib/libs/llvm12/utils/TableGen/CodeGenDAGPatterns.h
index 42e2c2ff67..bc939fe9ac 100644
--- a/contrib/libs/llvm12/utils/TableGen/CodeGenDAGPatterns.h
+++ b/contrib/libs/llvm12/utils/TableGen/CodeGenDAGPatterns.h
@@ -188,7 +188,7 @@ private:
struct TypeSetByHwMode : public InfoByHwMode<MachineValueTypeSet> {
using SetType = MachineValueTypeSet;
- SmallVector<unsigned, 16> AddrSpaces;
+ SmallVector<unsigned, 16> AddrSpaces;
TypeSetByHwMode() = default;
TypeSetByHwMode(const TypeSetByHwMode &VTS) = default;
@@ -1176,7 +1176,7 @@ public:
const CodeGenTarget &getTargetInfo() const { return Target; }
const TypeSetByHwMode &getLegalTypes() const { return LegalVTS; }
- Record *getSDNodeNamed(StringRef Name) const;
+ Record *getSDNodeNamed(StringRef Name) const;
const SDNodeInfo &getSDNodeInfo(Record *R) const {
auto F = SDNodes.find(R);
diff --git a/contrib/libs/llvm12/utils/TableGen/CodeGenInstruction.cpp b/contrib/libs/llvm12/utils/TableGen/CodeGenInstruction.cpp
index 042cbb5e62..960fe08677 100644
--- a/contrib/libs/llvm12/utils/TableGen/CodeGenInstruction.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/CodeGenInstruction.cpp
@@ -472,7 +472,7 @@ HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const {
/// include text from the specified variant, returning the new string.
std::string CodeGenInstruction::
FlattenAsmStringVariants(StringRef Cur, unsigned Variant) {
- std::string Res;
+ std::string Res;
for (;;) {
// Find the start of the next variant string.
diff --git a/contrib/libs/llvm12/utils/TableGen/CodeGenIntrinsics.h b/contrib/libs/llvm12/utils/TableGen/CodeGenIntrinsics.h
index af876f1ad8..c469f662a4 100644
--- a/contrib/libs/llvm12/utils/TableGen/CodeGenIntrinsics.h
+++ b/contrib/libs/llvm12/utils/TableGen/CodeGenIntrinsics.h
@@ -148,7 +148,7 @@ struct CodeGenIntrinsic {
enum ArgAttrKind {
NoCapture,
NoAlias,
- NoUndef,
+ NoUndef,
Returned,
ReadOnly,
WriteOnly,
@@ -177,13 +177,13 @@ struct CodeGenIntrinsic {
return Properties & (1 << Prop);
}
- /// Goes through all IntrProperties that have IsDefault
- /// value set and sets the property.
- void setDefaultProperties(Record *R, std::vector<Record *> DefaultProperties);
-
- /// Helper function to set property \p Name to true;
- void setProperty(Record *R);
-
+ /// Goes through all IntrProperties that have IsDefault
+ /// value set and sets the property.
+ void setDefaultProperties(Record *R, std::vector<Record *> DefaultProperties);
+
+ /// Helper function to set property \p Name to true;
+ void setProperty(Record *R);
+
/// Returns true if the parameter at \p ParamIdx is a pointer type. Returns
/// false if the parameter is not a pointer, or \p ParamIdx is greater than
/// the size of \p IS.ParamVTs.
@@ -193,7 +193,7 @@ struct CodeGenIntrinsic {
bool isParamImmArg(unsigned ParamIdx) const;
- CodeGenIntrinsic(Record *R, std::vector<Record *> DefaultProperties);
+ CodeGenIntrinsic(Record *R, std::vector<Record *> DefaultProperties);
};
class CodeGenIntrinsicTable {
diff --git a/contrib/libs/llvm12/utils/TableGen/CodeGenMapTable.cpp b/contrib/libs/llvm12/utils/TableGen/CodeGenMapTable.cpp
index f3edd18211..289a20a96f 100644
--- a/contrib/libs/llvm12/utils/TableGen/CodeGenMapTable.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/CodeGenMapTable.cpp
@@ -144,15 +144,15 @@ public:
}
}
- const std::string &getName() const { return Name; }
+ const std::string &getName() const { return Name; }
- const std::string &getFilterClass() const { return FilterClass; }
+ const std::string &getFilterClass() const { return FilterClass; }
- ListInit *getRowFields() const { return RowFields; }
+ ListInit *getRowFields() const { return RowFields; }
- ListInit *getColFields() const { return ColFields; }
+ ListInit *getColFields() const { return ColFields; }
- ListInit *getKeyCol() const { return KeyCol; }
+ ListInit *getKeyCol() const { return KeyCol; }
const std::vector<ListInit*> &getValueCols() const {
return ValueCols;
@@ -190,7 +190,7 @@ private:
public:
MapTableEmitter(CodeGenTarget &Target, RecordKeeper &Records, Record *IMRec):
Target(Target), InstrMapDesc(IMRec) {
- const std::string &FilterClass = InstrMapDesc.getFilterClass();
+ const std::string &FilterClass = InstrMapDesc.getFilterClass();
InstrDefs = Records.getAllDerivedDefinitions(FilterClass);
}
@@ -374,7 +374,7 @@ unsigned MapTableEmitter::emitBinSearchTable(raw_ostream &OS) {
for (unsigned i = 0; i < TotalNumInstr; i++) {
Record *CurInstr = NumberedInstructions[i]->TheDef;
std::vector<Record*> ColInstrs = MapTable[CurInstr];
- std::string OutStr;
+ std::string OutStr;
unsigned RelExists = 0;
if (!ColInstrs.empty()) {
for (unsigned j = 0; j < NumCol; j++) {
@@ -412,7 +412,7 @@ void MapTableEmitter::emitBinSearch(raw_ostream &OS, unsigned TableSize) {
OS << " unsigned start = 0;\n";
OS << " unsigned end = " << TableSize << ";\n";
OS << " while (start < end) {\n";
- OS << " mid = start + (end - start) / 2;\n";
+ OS << " mid = start + (end - start) / 2;\n";
OS << " if (Opcode == " << InstrMapDesc.getName() << "Table[mid][0]) {\n";
OS << " break;\n";
OS << " }\n";
diff --git a/contrib/libs/llvm12/utils/TableGen/CodeGenRegisters.cpp b/contrib/libs/llvm12/utils/TableGen/CodeGenRegisters.cpp
index 48e91b05cd..f9a7ba6bba 100644
--- a/contrib/libs/llvm12/utils/TableGen/CodeGenRegisters.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/CodeGenRegisters.cpp
@@ -196,7 +196,7 @@ void CodeGenRegister::buildObjectGraph(CodeGenRegBank &RegBank) {
}
}
-StringRef CodeGenRegister::getName() const {
+StringRef CodeGenRegister::getName() const {
assert(TheDef && "no def");
return TheDef->getName();
}
@@ -496,10 +496,10 @@ void CodeGenRegister::computeSecondarySubRegs(CodeGenRegBank &RegBank) {
assert(getSubRegIndex(SubReg) == SubRegIdx && "LeadingSuperRegs correct");
for (CodeGenRegister *SubReg : Cand->ExplicitSubRegs) {
if (CodeGenSubRegIndex *SubRegIdx = getSubRegIndex(SubReg)) {
- if (SubRegIdx->ConcatenationOf.empty())
+ if (SubRegIdx->ConcatenationOf.empty())
Parts.push_back(SubRegIdx);
- else
- append_range(Parts, SubRegIdx->ConcatenationOf);
+ else
+ append_range(Parts, SubRegIdx->ConcatenationOf);
} else {
// Sub-register doesn't exist.
Parts.clear();
@@ -742,8 +742,8 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
TopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1) {
GeneratePressureSet = R->getValueAsBit("GeneratePressureSet");
std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes");
- if (TypeList.empty())
- PrintFatalError(R->getLoc(), "RegTypes list must not be empty!");
+ if (TypeList.empty())
+ PrintFatalError(R->getLoc(), "RegTypes list must not be empty!");
for (unsigned i = 0, e = TypeList.size(); i != e; ++i) {
Record *Type = TypeList[i];
if (!Type->isSubClassOf("ValueType"))
@@ -998,8 +998,8 @@ CodeGenRegisterClass::getMatchingSubClassWithSubRegs(
const CodeGenRegisterClass *B) {
// If there are multiple, identical register classes, prefer the original
// register class.
- if (A == B)
- return false;
+ if (A == B)
+ return false;
if (A->getMembers().size() == B->getMembers().size())
return A == this;
return A->getMembers().size() > B->getMembers().size();
@@ -1237,7 +1237,7 @@ CodeGenSubRegIndex *CodeGenRegBank::getSubRegIdx(Record *Def) {
const CodeGenSubRegIndex *
CodeGenRegBank::findSubRegIdx(const Record* Def) const {
- return Def2SubRegIdx.lookup(Def);
+ return Def2SubRegIdx.lookup(Def);
}
CodeGenRegister *CodeGenRegBank::getReg(Record *Def) {
@@ -2009,7 +2009,7 @@ void CodeGenRegBank::computeRegUnitSets() {
if (RCRegUnits.empty())
continue;
- LLVM_DEBUG(dbgs() << "RC " << RC.getName() << " Units:\n";
+ LLVM_DEBUG(dbgs() << "RC " << RC.getName() << " Units:\n";
for (auto U
: RCRegUnits) printRegUnitName(U);
dbgs() << "\n UnitSetIDs:");
diff --git a/contrib/libs/llvm12/utils/TableGen/CodeGenRegisters.h b/contrib/libs/llvm12/utils/TableGen/CodeGenRegisters.h
index b6b7e42812..5228e6518f 100644
--- a/contrib/libs/llvm12/utils/TableGen/CodeGenRegisters.h
+++ b/contrib/libs/llvm12/utils/TableGen/CodeGenRegisters.h
@@ -163,7 +163,7 @@ namespace llvm {
CodeGenRegister(Record *R, unsigned Enum);
- StringRef getName() const;
+ StringRef getName() const;
// Extract more information from TheDef. This is used to build an object
// graph after all CodeGenRegister objects have been created.
@@ -353,7 +353,7 @@ namespace llvm {
unsigned getNumValueTypes() const { return VTs.size(); }
bool hasType(const ValueTypeByHwMode &VT) const {
- return llvm::is_contained(VTs, VT);
+ return llvm::is_contained(VTs, VT);
}
const ValueTypeByHwMode &getValueTypeNum(unsigned VTNum) const {
diff --git a/contrib/libs/llvm12/utils/TableGen/CodeGenSchedule.cpp b/contrib/libs/llvm12/utils/TableGen/CodeGenSchedule.cpp
index 0e1161d79d..b20eb6eff4 100644
--- a/contrib/libs/llvm12/utils/TableGen/CodeGenSchedule.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/CodeGenSchedule.cpp
@@ -86,7 +86,7 @@ struct InstRegexOp : public SetTheory::Operator {
auto Pseudos = Instructions.slice(NumGeneric, NumPseudos);
auto NonPseudos = Instructions.slice(NumGeneric + NumPseudos);
- for (Init *Arg : Expr->getArgs()) {
+ for (Init *Arg : Expr->getArgs()) {
StringInit *SI = dyn_cast<StringInit>(Arg);
if (!SI)
PrintFatalError(Loc, "instregex requires pattern string: " +
@@ -248,7 +248,7 @@ void CodeGenSchedModels::checkSTIPredicates() const {
}
PrintError(R->getLoc(), "STIPredicate " + Name + " multiply declared.");
- PrintFatalNote(It->second->getLoc(), "Previous declaration was here.");
+ PrintFatalNote(It->second->getLoc(), "Previous declaration was here.");
}
// Disallow InstructionEquivalenceClasses with an empty instruction list.
@@ -283,7 +283,7 @@ static APInt constructOperandMask(ArrayRef<int64_t> Indices) {
static void
processSTIPredicate(STIPredicateFunction &Fn,
- const ProcModelMapTy &ProcModelMap) {
+ const ProcModelMapTy &ProcModelMap) {
DenseMap<const Record *, unsigned> Opcode2Index;
using OpcodeMapPair = std::pair<const Record *, OpcodeInfo>;
std::vector<OpcodeMapPair> OpcodeMappings;
@@ -453,8 +453,8 @@ void CodeGenSchedModels::checkMCInstPredicates() const {
PrintError(TIIPred->getLoc(),
"TIIPredicate " + Name + " is multiply defined.");
- PrintFatalNote(It->second->getLoc(),
- " Previous definition of " + Name + " was here.");
+ PrintFatalNote(It->second->getLoc(),
+ " Previous definition of " + Name + " was here.");
}
}
@@ -950,9 +950,9 @@ void CodeGenSchedModels::collectSchedClasses() {
}
// If ProcIndices contains zero, the class applies to all processors.
LLVM_DEBUG({
- if (!llvm::is_contained(ProcIndices, 0)) {
+ if (!llvm::is_contained(ProcIndices, 0)) {
for (const CodeGenProcModel &PM : ProcModels) {
- if (!llvm::is_contained(ProcIndices, PM.Index))
+ if (!llvm::is_contained(ProcIndices, PM.Index))
dbgs() << "No machine model for " << Inst->TheDef->getName()
<< " on processor " << PM.ModelName << '\n';
}
@@ -1080,14 +1080,14 @@ void CodeGenSchedModels::createInstRWClass(Record *InstRWDef) {
if (RWD->getValueAsDef("SchedModel") == RWModelDef &&
RWModelDef->getValueAsBit("FullInstRWOverlapCheck")) {
assert(!InstDefs.empty()); // Checked at function start.
- PrintError(
- InstRWDef->getLoc(),
- "Overlapping InstRW definition for \"" +
- InstDefs.front()->getName() +
- "\" also matches previous \"" +
- RWD->getValue("Instrs")->getValue()->getAsString() +
- "\".");
- PrintFatalNote(RWD->getLoc(), "Previous match was here.");
+ PrintError(
+ InstRWDef->getLoc(),
+ "Overlapping InstRW definition for \"" +
+ InstDefs.front()->getName() +
+ "\" also matches previous \"" +
+ RWD->getValue("Instrs")->getValue()->getAsString() +
+ "\".");
+ PrintFatalNote(RWD->getLoc(), "Previous match was here.");
}
}
LLVM_DEBUG(dbgs() << "InstRW: Reuse SC " << OldSCIdx << ":"
@@ -1116,13 +1116,13 @@ void CodeGenSchedModels::createInstRWClass(Record *InstRWDef) {
for (Record *OldRWDef : SchedClasses[OldSCIdx].InstRWs) {
if (OldRWDef->getValueAsDef("SchedModel") == RWModelDef) {
assert(!InstDefs.empty()); // Checked at function start.
- PrintError(
- InstRWDef->getLoc(),
- "Overlapping InstRW definition for \"" +
- InstDefs.front()->getName() + "\" also matches previous \"" +
- OldRWDef->getValue("Instrs")->getValue()->getAsString() +
- "\".");
- PrintFatalNote(OldRWDef->getLoc(), "Previous match was here.");
+ PrintError(
+ InstRWDef->getLoc(),
+ "Overlapping InstRW definition for \"" +
+ InstDefs.front()->getName() + "\" also matches previous \"" +
+ OldRWDef->getValue("Instrs")->getValue()->getAsString() +
+ "\".");
+ PrintFatalNote(OldRWDef->getLoc(), "Previous match was here.");
}
assert(OldRWDef != InstRWDef &&
"SchedClass has duplicate InstRW def");
@@ -1208,10 +1208,10 @@ void CodeGenSchedModels::collectProcItinRW() {
// Gather the unsupported features for processor models.
void CodeGenSchedModels::collectProcUnsupportedFeatures() {
- for (CodeGenProcModel &ProcModel : ProcModels)
- append_range(
- ProcModel.UnsupportedFeaturesDefs,
- ProcModel.ModelDef->getValueAsListOfDefs("UnsupportedFeatures"));
+ for (CodeGenProcModel &ProcModel : ProcModels)
+ append_range(
+ ProcModel.UnsupportedFeaturesDefs,
+ ProcModel.ModelDef->getValueAsListOfDefs("UnsupportedFeatures"));
}
/// Infer new classes from existing classes. In the process, this may create new
@@ -1247,7 +1247,7 @@ void CodeGenSchedModels::inferFromItinClass(Record *ItinClassDef,
bool HasMatch = false;
for (const Record *Rec : PM.ItinRWDefs) {
RecVec Matched = Rec->getValueAsListOfDefs("MatchedItinClasses");
- if (!llvm::is_contained(Matched, ItinClassDef))
+ if (!llvm::is_contained(Matched, ItinClassDef))
continue;
if (HasMatch)
PrintFatalError(Rec->getLoc(), "Duplicate itinerary class "
@@ -1280,7 +1280,7 @@ void CodeGenSchedModels::inferFromInstRWs(unsigned SCIdx) {
findRWs(Rec->getValueAsListOfDefs("OperandReadWrites"), Writes, Reads);
unsigned PIdx = getProcModel(Rec->getValueAsDef("SchedModel")).Index;
inferFromRW(Writes, Reads, SCIdx, PIdx); // May mutate SchedClasses.
- SchedClasses[SCIdx].InstRWProcIndices.insert(PIdx);
+ SchedClasses[SCIdx].InstRWProcIndices.insert(PIdx);
}
}
@@ -1313,13 +1313,13 @@ struct PredTransition {
SmallVector<PredCheck, 4> PredTerm;
SmallVector<SmallVector<unsigned,4>, 16> WriteSequences;
SmallVector<SmallVector<unsigned,4>, 16> ReadSequences;
- unsigned ProcIndex = 0;
-
- PredTransition() = default;
- PredTransition(ArrayRef<PredCheck> PT, unsigned ProcId) {
- PredTerm.assign(PT.begin(), PT.end());
- ProcIndex = ProcId;
- }
+ unsigned ProcIndex = 0;
+
+ PredTransition() = default;
+ PredTransition(ArrayRef<PredCheck> PT, unsigned ProcId) {
+ PredTerm.assign(PT.begin(), PT.end());
+ ProcIndex = ProcId;
+ }
};
// Encapsulate a set of partially constructed transitions.
@@ -1332,18 +1332,18 @@ public:
PredTransitions(CodeGenSchedModels &sm): SchedModels(sm) {}
- bool substituteVariantOperand(const SmallVectorImpl<unsigned> &RWSeq,
+ bool substituteVariantOperand(const SmallVectorImpl<unsigned> &RWSeq,
bool IsRead, unsigned StartIdx);
- bool substituteVariants(const PredTransition &Trans);
+ bool substituteVariants(const PredTransition &Trans);
#ifndef NDEBUG
void dump() const;
#endif
private:
- bool mutuallyExclusive(Record *PredDef, ArrayRef<Record *> Preds,
- ArrayRef<PredCheck> Term);
+ bool mutuallyExclusive(Record *PredDef, ArrayRef<Record *> Preds,
+ ArrayRef<PredCheck> Term);
void getIntersectingVariants(
const CodeGenSchedRW &SchedRW, unsigned TransIdx,
std::vector<TransVariant> &IntersectingVariants);
@@ -1362,7 +1362,7 @@ private:
// are always checked in the order they are defined in the .td file. Later
// conditions implicitly negate any prior condition.
bool PredTransitions::mutuallyExclusive(Record *PredDef,
- ArrayRef<Record *> Preds,
+ ArrayRef<Record *> Preds,
ArrayRef<PredCheck> Term) {
for (const PredCheck &PC: Term) {
if (PC.Predicate == PredDef)
@@ -1373,49 +1373,49 @@ bool PredTransitions::mutuallyExclusive(Record *PredDef,
RecVec Variants = SchedRW.TheDef->getValueAsListOfDefs("Variants");
if (any_of(Variants, [PredDef](const Record *R) {
return R->getValueAsDef("Predicate") == PredDef;
- })) {
- // To check if PredDef is mutually exclusive with PC we also need to
- // check that PC.Predicate is exclusive with all predicates from variant
- // we're expanding. Consider following RW sequence with two variants
- // (1 & 2), where A, B and C are predicates from corresponding SchedVars:
- //
- // 1:A/B - 2:C/B
- //
- // Here C is not mutually exclusive with variant (1), because A doesn't
- // exist in variant (2). This means we have possible transitions from A
- // to C and from A to B, and fully expanded sequence would look like:
- //
- // if (A & C) return ...;
- // if (A & B) return ...;
- // if (B) return ...;
- //
- // Now let's consider another sequence:
- //
- // 1:A/B - 2:A/B
- //
- // Here A in variant (2) is mutually exclusive with variant (1), because
- // A also exists in (2). This means A->B transition is impossible and
- // expanded sequence would look like:
- //
- // if (A) return ...;
- // if (B) return ...;
- if (!count(Preds, PC.Predicate))
- continue;
+ })) {
+ // To check if PredDef is mutually exclusive with PC we also need to
+ // check that PC.Predicate is exclusive with all predicates from variant
+ // we're expanding. Consider following RW sequence with two variants
+ // (1 & 2), where A, B and C are predicates from corresponding SchedVars:
+ //
+ // 1:A/B - 2:C/B
+ //
+ // Here C is not mutually exclusive with variant (1), because A doesn't
+ // exist in variant (2). This means we have possible transitions from A
+ // to C and from A to B, and fully expanded sequence would look like:
+ //
+ // if (A & C) return ...;
+ // if (A & B) return ...;
+ // if (B) return ...;
+ //
+ // Now let's consider another sequence:
+ //
+ // 1:A/B - 2:A/B
+ //
+ // Here A in variant (2) is mutually exclusive with variant (1), because
+ // A also exists in (2). This means A->B transition is impossible and
+ // expanded sequence would look like:
+ //
+ // if (A) return ...;
+ // if (B) return ...;
+ if (!count(Preds, PC.Predicate))
+ continue;
return true;
}
}
return false;
}
-static std::vector<Record *> getAllPredicates(ArrayRef<TransVariant> Variants,
- unsigned ProcId) {
- std::vector<Record *> Preds;
- for (auto &Variant : Variants) {
- if (!Variant.VarOrSeqDef->isSubClassOf("SchedVar"))
- continue;
- Preds.push_back(Variant.VarOrSeqDef->getValueAsDef("Predicate"));
+static std::vector<Record *> getAllPredicates(ArrayRef<TransVariant> Variants,
+ unsigned ProcId) {
+ std::vector<Record *> Preds;
+ for (auto &Variant : Variants) {
+ if (!Variant.VarOrSeqDef->isSubClassOf("SchedVar"))
+ continue;
+ Preds.push_back(Variant.VarOrSeqDef->getValueAsDef("Predicate"));
}
- return Preds;
+ return Preds;
}
// Populate IntersectingVariants with any variants or aliased sequences of the
@@ -1434,14 +1434,14 @@ void PredTransitions::getIntersectingVariants(
Record *ModelDef = SchedRW.TheDef->getValueAsDef("SchedModel");
VarProcIdx = SchedModels.getProcModel(ModelDef).Index;
}
- if (VarProcIdx == 0 || VarProcIdx == TransVec[TransIdx].ProcIndex) {
- // Push each variant. Assign TransVecIdx later.
- const RecVec VarDefs = SchedRW.TheDef->getValueAsListOfDefs("Variants");
- for (Record *VarDef : VarDefs)
- Variants.emplace_back(VarDef, SchedRW.Index, VarProcIdx, 0);
- if (VarProcIdx == 0)
- GenericRW = true;
- }
+ if (VarProcIdx == 0 || VarProcIdx == TransVec[TransIdx].ProcIndex) {
+ // Push each variant. Assign TransVecIdx later.
+ const RecVec VarDefs = SchedRW.TheDef->getValueAsListOfDefs("Variants");
+ for (Record *VarDef : VarDefs)
+ Variants.emplace_back(VarDef, SchedRW.Index, VarProcIdx, 0);
+ if (VarProcIdx == 0)
+ GenericRW = true;
+ }
}
for (RecIter AI = SchedRW.Aliases.begin(), AE = SchedRW.Aliases.end();
AI != AE; ++AI) {
@@ -1453,17 +1453,17 @@ void PredTransitions::getIntersectingVariants(
Record *ModelDef = (*AI)->getValueAsDef("SchedModel");
AliasProcIdx = SchedModels.getProcModel(ModelDef).Index;
}
- if (AliasProcIdx && AliasProcIdx != TransVec[TransIdx].ProcIndex)
- continue;
- if (!Variants.empty()) {
- const CodeGenProcModel &PM =
- *(SchedModels.procModelBegin() + AliasProcIdx);
- PrintFatalError((*AI)->getLoc(),
- "Multiple variants defined for processor " +
- PM.ModelName +
- " Ensure only one SchedAlias exists per RW.");
- }
-
+ if (AliasProcIdx && AliasProcIdx != TransVec[TransIdx].ProcIndex)
+ continue;
+ if (!Variants.empty()) {
+ const CodeGenProcModel &PM =
+ *(SchedModels.procModelBegin() + AliasProcIdx);
+ PrintFatalError((*AI)->getLoc(),
+ "Multiple variants defined for processor " +
+ PM.ModelName +
+ " Ensure only one SchedAlias exists per RW.");
+ }
+
const CodeGenSchedRW &AliasRW =
SchedModels.getSchedRW((*AI)->getValueAsDef("AliasRW"));
@@ -1477,17 +1477,17 @@ void PredTransitions::getIntersectingVariants(
if (AliasProcIdx == 0)
GenericRW = true;
}
- std::vector<Record *> AllPreds =
- getAllPredicates(Variants, TransVec[TransIdx].ProcIndex);
+ std::vector<Record *> AllPreds =
+ getAllPredicates(Variants, TransVec[TransIdx].ProcIndex);
for (TransVariant &Variant : Variants) {
// Don't expand variants if the processor models don't intersect.
// A zero processor index means any processor.
if (Variant.VarOrSeqDef->isSubClassOf("SchedVar")) {
Record *PredDef = Variant.VarOrSeqDef->getValueAsDef("Predicate");
- if (mutuallyExclusive(PredDef, AllPreds, TransVec[TransIdx].PredTerm))
+ if (mutuallyExclusive(PredDef, AllPreds, TransVec[TransIdx].PredTerm))
continue;
}
-
+
if (IntersectingVariants.empty()) {
// The first variant builds on the existing transition.
Variant.TransVecIdx = TransIdx;
@@ -1534,7 +1534,7 @@ pushVariant(const TransVariant &VInfo, bool IsRead) {
if (SchedRW.IsVariadic) {
unsigned OperIdx = RWSequences.size()-1;
// Make N-1 copies of this transition's last sequence.
- RWSequences.reserve(RWSequences.size() + SelectedRWs.size() - 1);
+ RWSequences.reserve(RWSequences.size() + SelectedRWs.size() - 1);
RWSequences.insert(RWSequences.end(), SelectedRWs.size() - 1,
RWSequences[OperIdx]);
// Push each of the N elements of the SelectedRWs onto a copy of the last
@@ -1548,7 +1548,7 @@ pushVariant(const TransVariant &VInfo, bool IsRead) {
ExpandedRWs.push_back(*RWI);
else
SchedModels.expandRWSequence(*RWI, ExpandedRWs, IsRead);
- llvm::append_range(RWSequences[OperIdx], ExpandedRWs);
+ llvm::append_range(RWSequences[OperIdx], ExpandedRWs);
}
assert(OperIdx == RWSequences.size() && "missed a sequence");
}
@@ -1564,7 +1564,7 @@ pushVariant(const TransVariant &VInfo, bool IsRead) {
else
SchedModels.expandRWSequence(*RWI, ExpandedRWs, IsRead);
}
- llvm::append_range(Seq, ExpandedRWs);
+ llvm::append_range(Seq, ExpandedRWs);
}
}
@@ -1572,9 +1572,9 @@ pushVariant(const TransVariant &VInfo, bool IsRead) {
// operand. StartIdx is an index into TransVec where partial results
// starts. RWSeq must be applied to all transitions between StartIdx and the end
// of TransVec.
-bool PredTransitions::substituteVariantOperand(
- const SmallVectorImpl<unsigned> &RWSeq, bool IsRead, unsigned StartIdx) {
- bool Subst = false;
+bool PredTransitions::substituteVariantOperand(
+ const SmallVectorImpl<unsigned> &RWSeq, bool IsRead, unsigned StartIdx) {
+ bool Subst = false;
// Visit each original RW within the current sequence.
for (SmallVectorImpl<unsigned>::const_iterator
RWI = RWSeq.begin(), RWE = RWSeq.end(); RWI != RWE; ++RWI) {
@@ -1584,25 +1584,25 @@ bool PredTransitions::substituteVariantOperand(
// revisited (TransEnd must be loop invariant).
for (unsigned TransIdx = StartIdx, TransEnd = TransVec.size();
TransIdx != TransEnd; ++TransIdx) {
- // Distribute this partial PredTransition across intersecting variants.
- // This will push a copies of TransVec[TransIdx] on the back of TransVec.
- std::vector<TransVariant> IntersectingVariants;
- getIntersectingVariants(SchedRW, TransIdx, IntersectingVariants);
- // Now expand each variant on top of its copy of the transition.
- for (const TransVariant &IV : IntersectingVariants)
- pushVariant(IV, IsRead);
- if (IntersectingVariants.empty()) {
+ // Distribute this partial PredTransition across intersecting variants.
+ // This will push a copies of TransVec[TransIdx] on the back of TransVec.
+ std::vector<TransVariant> IntersectingVariants;
+ getIntersectingVariants(SchedRW, TransIdx, IntersectingVariants);
+ // Now expand each variant on top of its copy of the transition.
+ for (const TransVariant &IV : IntersectingVariants)
+ pushVariant(IV, IsRead);
+ if (IntersectingVariants.empty()) {
if (IsRead)
TransVec[TransIdx].ReadSequences.back().push_back(*RWI);
else
TransVec[TransIdx].WriteSequences.back().push_back(*RWI);
continue;
- } else {
- Subst = true;
+ } else {
+ Subst = true;
}
}
}
- return Subst;
+ return Subst;
}
// For each variant of a Read/Write in Trans, substitute the sequence of
@@ -1611,13 +1611,13 @@ bool PredTransitions::substituteVariantOperand(
// predicates should result in linear growth in the total number variants.
//
// This is one step in a breadth-first search of nested variants.
-bool PredTransitions::substituteVariants(const PredTransition &Trans) {
+bool PredTransitions::substituteVariants(const PredTransition &Trans) {
// Build up a set of partial results starting at the back of
// PredTransitions. Remember the first new transition.
unsigned StartIdx = TransVec.size();
- bool Subst = false;
- assert(Trans.ProcIndex != 0);
- TransVec.emplace_back(Trans.PredTerm, Trans.ProcIndex);
+ bool Subst = false;
+ assert(Trans.ProcIndex != 0);
+ TransVec.emplace_back(Trans.PredTerm, Trans.ProcIndex);
// Visit each original write sequence.
for (SmallVectorImpl<SmallVector<unsigned,4>>::const_iterator
@@ -1628,7 +1628,7 @@ bool PredTransitions::substituteVariants(const PredTransition &Trans) {
TransVec.begin() + StartIdx, E = TransVec.end(); I != E; ++I) {
I->WriteSequences.emplace_back();
}
- Subst |= substituteVariantOperand(*WSI, /*IsRead=*/false, StartIdx);
+ Subst |= substituteVariantOperand(*WSI, /*IsRead=*/false, StartIdx);
}
// Visit each original read sequence.
for (SmallVectorImpl<SmallVector<unsigned,4>>::const_iterator
@@ -1639,37 +1639,37 @@ bool PredTransitions::substituteVariants(const PredTransition &Trans) {
TransVec.begin() + StartIdx, E = TransVec.end(); I != E; ++I) {
I->ReadSequences.emplace_back();
}
- Subst |= substituteVariantOperand(*RSI, /*IsRead=*/true, StartIdx);
- }
- return Subst;
-}
-
-static void addSequences(CodeGenSchedModels &SchedModels,
- const SmallVectorImpl<SmallVector<unsigned, 4>> &Seqs,
- IdxVec &Result, bool IsRead) {
- for (const auto &S : Seqs)
- if (!S.empty())
- Result.push_back(SchedModels.findOrInsertRW(S, IsRead));
-}
-
-#ifndef NDEBUG
-static void dumpRecVec(const RecVec &RV) {
- for (const Record *R : RV)
- dbgs() << R->getName() << ", ";
-}
-#endif
-
-static void dumpTransition(const CodeGenSchedModels &SchedModels,
- const CodeGenSchedClass &FromSC,
- const CodeGenSchedTransition &SCTrans,
- const RecVec &Preds) {
- LLVM_DEBUG(dbgs() << "Adding transition from " << FromSC.Name << "("
- << FromSC.Index << ") to "
- << SchedModels.getSchedClass(SCTrans.ToClassIdx).Name << "("
- << SCTrans.ToClassIdx << ") on pred term: (";
- dumpRecVec(Preds);
- dbgs() << ") on processor (" << SCTrans.ProcIndex << ")\n");
-}
+ Subst |= substituteVariantOperand(*RSI, /*IsRead=*/true, StartIdx);
+ }
+ return Subst;
+}
+
+static void addSequences(CodeGenSchedModels &SchedModels,
+ const SmallVectorImpl<SmallVector<unsigned, 4>> &Seqs,
+ IdxVec &Result, bool IsRead) {
+ for (const auto &S : Seqs)
+ if (!S.empty())
+ Result.push_back(SchedModels.findOrInsertRW(S, IsRead));
+}
+
+#ifndef NDEBUG
+static void dumpRecVec(const RecVec &RV) {
+ for (const Record *R : RV)
+ dbgs() << R->getName() << ", ";
+}
+#endif
+
+static void dumpTransition(const CodeGenSchedModels &SchedModels,
+ const CodeGenSchedClass &FromSC,
+ const CodeGenSchedTransition &SCTrans,
+ const RecVec &Preds) {
+ LLVM_DEBUG(dbgs() << "Adding transition from " << FromSC.Name << "("
+ << FromSC.Index << ") to "
+ << SchedModels.getSchedClass(SCTrans.ToClassIdx).Name << "("
+ << SCTrans.ToClassIdx << ") on pred term: (";
+ dumpRecVec(Preds);
+ dbgs() << ") on processor (" << SCTrans.ProcIndex << ")\n");
+}
// Create a new SchedClass for each variant found by inferFromRW. Pass
static void inferFromTransitions(ArrayRef<PredTransition> LastTransitions,
unsigned FromClassIdx,
@@ -1678,25 +1678,25 @@ static void inferFromTransitions(ArrayRef<PredTransition> LastTransitions,
// requires creating a new SchedClass.
for (ArrayRef<PredTransition>::iterator
I = LastTransitions.begin(), E = LastTransitions.end(); I != E; ++I) {
- // Variant expansion (substituteVariants) may create unconditional
- // transitions. We don't need to build sched classes for them.
- if (I->PredTerm.empty())
- continue;
- IdxVec OperWritesVariant, OperReadsVariant;
- addSequences(SchedModels, I->WriteSequences, OperWritesVariant, false);
- addSequences(SchedModels, I->ReadSequences, OperReadsVariant, true);
+ // Variant expansion (substituteVariants) may create unconditional
+ // transitions. We don't need to build sched classes for them.
+ if (I->PredTerm.empty())
+ continue;
+ IdxVec OperWritesVariant, OperReadsVariant;
+ addSequences(SchedModels, I->WriteSequences, OperWritesVariant, false);
+ addSequences(SchedModels, I->ReadSequences, OperReadsVariant, true);
CodeGenSchedTransition SCTrans;
-
- // Transition should not contain processor indices already assigned to
- // InstRWs in this scheduling class.
- const CodeGenSchedClass &FromSC = SchedModels.getSchedClass(FromClassIdx);
- if (FromSC.InstRWProcIndices.count(I->ProcIndex))
- continue;
- SCTrans.ProcIndex = I->ProcIndex;
+
+ // Transition should not contain processor indices already assigned to
+ // InstRWs in this scheduling class.
+ const CodeGenSchedClass &FromSC = SchedModels.getSchedClass(FromClassIdx);
+ if (FromSC.InstRWProcIndices.count(I->ProcIndex))
+ continue;
+ SCTrans.ProcIndex = I->ProcIndex;
SCTrans.ToClassIdx =
- SchedModels.addSchedClass(/*ItinClassDef=*/nullptr, OperWritesVariant,
- OperReadsVariant, I->ProcIndex);
-
+ SchedModels.addSchedClass(/*ItinClassDef=*/nullptr, OperWritesVariant,
+ OperReadsVariant, I->ProcIndex);
+
// The final PredTerm is unique set of predicates guarding the transition.
RecVec Preds;
transform(I->PredTerm, std::back_inserter(Preds),
@@ -1704,36 +1704,36 @@ static void inferFromTransitions(ArrayRef<PredTransition> LastTransitions,
return P.Predicate;
});
Preds.erase(std::unique(Preds.begin(), Preds.end()), Preds.end());
- dumpTransition(SchedModels, FromSC, SCTrans, Preds);
+ dumpTransition(SchedModels, FromSC, SCTrans, Preds);
SCTrans.PredTerm = std::move(Preds);
SchedModels.getSchedClass(FromClassIdx)
.Transitions.push_back(std::move(SCTrans));
}
}
-std::vector<unsigned> CodeGenSchedModels::getAllProcIndices() const {
- std::vector<unsigned> ProcIdVec;
- for (const auto &PM : ProcModelMap)
- if (PM.second != 0)
- ProcIdVec.push_back(PM.second);
- // The order of the keys (Record pointers) of ProcModelMap are not stable.
- // Sort to stabalize the values.
- llvm::sort(ProcIdVec);
- return ProcIdVec;
-}
-
-static std::vector<PredTransition>
-makePerProcessorTransitions(const PredTransition &Trans,
- ArrayRef<unsigned> ProcIndices) {
- std::vector<PredTransition> PerCpuTransVec;
- for (unsigned ProcId : ProcIndices) {
- assert(ProcId != 0);
- PerCpuTransVec.push_back(Trans);
- PerCpuTransVec.back().ProcIndex = ProcId;
- }
- return PerCpuTransVec;
-}
-
+std::vector<unsigned> CodeGenSchedModels::getAllProcIndices() const {
+ std::vector<unsigned> ProcIdVec;
+ for (const auto &PM : ProcModelMap)
+ if (PM.second != 0)
+ ProcIdVec.push_back(PM.second);
+ // The order of the keys (Record pointers) of ProcModelMap are not stable.
+ // Sort to stabalize the values.
+ llvm::sort(ProcIdVec);
+ return ProcIdVec;
+}
+
+static std::vector<PredTransition>
+makePerProcessorTransitions(const PredTransition &Trans,
+ ArrayRef<unsigned> ProcIndices) {
+ std::vector<PredTransition> PerCpuTransVec;
+ for (unsigned ProcId : ProcIndices) {
+ assert(ProcId != 0);
+ PerCpuTransVec.push_back(Trans);
+ PerCpuTransVec.back().ProcIndex = ProcId;
+ }
+ return PerCpuTransVec;
+}
+
// Create new SchedClasses for the given ReadWrite list. If any of the
// ReadWrites refers to a SchedVariant, create a new SchedClass for each variant
// of the ReadWrite list, following Aliases if necessary.
@@ -1767,21 +1767,21 @@ void CodeGenSchedModels::inferFromRW(ArrayRef<unsigned> OperWrites,
}
LLVM_DEBUG(dbgs() << '\n');
- LastTransitions = makePerProcessorTransitions(
- LastTransitions[0], llvm::is_contained(ProcIndices, 0)
- ? ArrayRef<unsigned>(getAllProcIndices())
- : ProcIndices);
+ LastTransitions = makePerProcessorTransitions(
+ LastTransitions[0], llvm::is_contained(ProcIndices, 0)
+ ? ArrayRef<unsigned>(getAllProcIndices())
+ : ProcIndices);
// Collect all PredTransitions for individual operands.
// Iterate until no variant writes remain.
- bool SubstitutedAny;
- do {
- SubstitutedAny = false;
+ bool SubstitutedAny;
+ do {
+ SubstitutedAny = false;
PredTransitions Transitions(*this);
for (const PredTransition &Trans : LastTransitions)
- SubstitutedAny |= Transitions.substituteVariants(Trans);
+ SubstitutedAny |= Transitions.substituteVariants(Trans);
LLVM_DEBUG(Transitions.dump());
LastTransitions.swap(Transitions.TransVec);
- } while (SubstitutedAny);
+ } while (SubstitutedAny);
// WARNING: We are about to mutate the SchedClasses vector. Do not refer to
// OperWrites, OperReads, or ProcIndices after calling inferFromTransitions.
@@ -1824,7 +1824,7 @@ void CodeGenSchedModels::verifyProcResourceGroups(CodeGenProcModel &PM) {
OtherUnits.begin(), OtherUnits.end())
!= CheckUnits.end()) {
// CheckUnits and OtherUnits overlap
- llvm::append_range(OtherUnits, CheckUnits);
+ llvm::append_range(OtherUnits, CheckUnits);
if (!hasSuperGroup(OtherUnits, PM)) {
PrintFatalError((PM.ProcResourceDefs[i])->getLoc(),
"proc resource group overlaps with "
@@ -2046,7 +2046,7 @@ void CodeGenSchedModels::collectItinProcResources(Record *ItinClassDef) {
for (RecIter II = PM.ItinRWDefs.begin(), IE = PM.ItinRWDefs.end();
II != IE; ++II) {
RecVec Matched = (*II)->getValueAsListOfDefs("MatchedItinClasses");
- if (!llvm::is_contained(Matched, ItinClassDef))
+ if (!llvm::is_contained(Matched, ItinClassDef))
continue;
if (HasMatch)
PrintFatalError((*II)->getLoc(), "Duplicate itinerary class "
@@ -2247,14 +2247,14 @@ void CodeGenSchedClass::dump(const CodeGenSchedModels* SchedModels) const {
dbgs().indent(10);
}
}
- dbgs() << "\n ProcIdx: "; dumpIdxVec(ProcIndices);
+ dbgs() << "\n ProcIdx: "; dumpIdxVec(ProcIndices);
if (!Transitions.empty()) {
dbgs() << "\n Transitions for Proc ";
for (const CodeGenSchedTransition &Transition : Transitions) {
- dbgs() << Transition.ProcIndex << ", ";
+ dbgs() << Transition.ProcIndex << ", ";
}
}
- dbgs() << '\n';
+ dbgs() << '\n';
}
void PredTransitions::dump() const {
diff --git a/contrib/libs/llvm12/utils/TableGen/CodeGenSchedule.h b/contrib/libs/llvm12/utils/TableGen/CodeGenSchedule.h
index 7702b6a31b..9020447c94 100644
--- a/contrib/libs/llvm12/utils/TableGen/CodeGenSchedule.h
+++ b/contrib/libs/llvm12/utils/TableGen/CodeGenSchedule.h
@@ -16,12 +16,12 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/SetTheory.h"
-#include <map>
+#include <map>
namespace llvm {
@@ -96,7 +96,7 @@ struct CodeGenSchedRW {
/// Represent a transition between SchedClasses induced by SchedVariant.
struct CodeGenSchedTransition {
unsigned ToClassIdx;
- unsigned ProcIndex;
+ unsigned ProcIndex;
RecVec PredTerm;
};
@@ -141,8 +141,8 @@ struct CodeGenSchedClass {
// Instructions should be ignored by this class because they have been split
// off to join another inferred class.
RecVec InstRWs;
- // InstRWs processor indices. Filled in inferFromInstRWs
- DenseSet<unsigned> InstRWProcIndices;
+ // InstRWs processor indices. Filled in inferFromInstRWs
+ DenseSet<unsigned> InstRWProcIndices;
CodeGenSchedClass(unsigned Index, std::string Name, Record *ItinClassDef)
: Index(Index), Name(std::move(Name)), ItinClassDef(ItinClassDef) {}
@@ -362,7 +362,7 @@ public:
OpcodeGroup(OpcodeGroup &&Other) = default;
void addOpcode(const Record *Opcode) {
- assert(!llvm::is_contained(Opcodes, Opcode) && "Opcode already in set!");
+ assert(!llvm::is_contained(Opcodes, Opcode) && "Opcode already in set!");
Opcodes.push_back(Opcode);
}
@@ -410,8 +410,8 @@ public:
ArrayRef<OpcodeGroup> getGroups() const { return Groups; }
};
-using ProcModelMapTy = DenseMap<const Record *, unsigned>;
-
+using ProcModelMapTy = DenseMap<const Record *, unsigned>;
+
/// Top level container for machine model data.
class CodeGenSchedModels {
RecordKeeper &Records;
@@ -445,7 +445,7 @@ class CodeGenSchedModels {
InstClassMapTy InstrClassMap;
std::vector<STIPredicateFunction> STIPredicates;
- std::vector<unsigned> getAllProcIndices() const;
+ std::vector<unsigned> getAllProcIndices() const;
public:
CodeGenSchedModels(RecordKeeper& RK, const CodeGenTarget &TGT);
diff --git a/contrib/libs/llvm12/utils/TableGen/CodeGenTarget.cpp b/contrib/libs/llvm12/utils/TableGen/CodeGenTarget.cpp
index bf728ec269..8f6d212df5 100644
--- a/contrib/libs/llvm12/utils/TableGen/CodeGenTarget.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/CodeGenTarget.cpp
@@ -76,7 +76,7 @@ StringRef llvm::getEnumName(MVT::SimpleValueType T) {
case MVT::f128: return "MVT::f128";
case MVT::ppcf128: return "MVT::ppcf128";
case MVT::x86mmx: return "MVT::x86mmx";
- case MVT::x86amx: return "MVT::x86amx";
+ case MVT::x86amx: return "MVT::x86amx";
case MVT::Glue: return "MVT::Glue";
case MVT::isVoid: return "MVT::isVoid";
case MVT::v1i1: return "MVT::v1i1";
@@ -87,7 +87,7 @@ StringRef llvm::getEnumName(MVT::SimpleValueType T) {
case MVT::v32i1: return "MVT::v32i1";
case MVT::v64i1: return "MVT::v64i1";
case MVT::v128i1: return "MVT::v128i1";
- case MVT::v256i1: return "MVT::v256i1";
+ case MVT::v256i1: return "MVT::v256i1";
case MVT::v512i1: return "MVT::v512i1";
case MVT::v1024i1: return "MVT::v1024i1";
case MVT::v1i8: return "MVT::v1i8";
@@ -128,9 +128,9 @@ StringRef llvm::getEnumName(MVT::SimpleValueType T) {
case MVT::v8i64: return "MVT::v8i64";
case MVT::v16i64: return "MVT::v16i64";
case MVT::v32i64: return "MVT::v32i64";
- case MVT::v64i64: return "MVT::v64i64";
- case MVT::v128i64: return "MVT::v128i64";
- case MVT::v256i64: return "MVT::v256i64";
+ case MVT::v64i64: return "MVT::v64i64";
+ case MVT::v128i64: return "MVT::v128i64";
+ case MVT::v256i64: return "MVT::v256i64";
case MVT::v1i128: return "MVT::v1i128";
case MVT::v2f16: return "MVT::v2f16";
case MVT::v3f16: return "MVT::v3f16";
@@ -168,9 +168,9 @@ StringRef llvm::getEnumName(MVT::SimpleValueType T) {
case MVT::v8f64: return "MVT::v8f64";
case MVT::v16f64: return "MVT::v16f64";
case MVT::v32f64: return "MVT::v32f64";
- case MVT::v64f64: return "MVT::v64f64";
- case MVT::v128f64: return "MVT::v128f64";
- case MVT::v256f64: return "MVT::v256f64";
+ case MVT::v64f64: return "MVT::v64f64";
+ case MVT::v128f64: return "MVT::v128f64";
+ case MVT::v256f64: return "MVT::v256f64";
case MVT::nxv1i1: return "MVT::nxv1i1";
case MVT::nxv2i1: return "MVT::nxv2i1";
case MVT::nxv4i1: return "MVT::nxv4i1";
@@ -212,22 +212,22 @@ StringRef llvm::getEnumName(MVT::SimpleValueType T) {
case MVT::nxv2bf16: return "MVT::nxv2bf16";
case MVT::nxv4bf16: return "MVT::nxv4bf16";
case MVT::nxv8bf16: return "MVT::nxv8bf16";
- case MVT::nxv1f32: return "MVT::nxv1f32";
- case MVT::nxv2f32: return "MVT::nxv2f32";
- case MVT::nxv4f32: return "MVT::nxv4f32";
- case MVT::nxv8f32: return "MVT::nxv8f32";
- case MVT::nxv16f32: return "MVT::nxv16f32";
- case MVT::nxv1f64: return "MVT::nxv1f64";
- case MVT::nxv2f64: return "MVT::nxv2f64";
- case MVT::nxv4f64: return "MVT::nxv4f64";
- case MVT::nxv8f64: return "MVT::nxv8f64";
- case MVT::token: return "MVT::token";
- case MVT::Metadata: return "MVT::Metadata";
- case MVT::iPTR: return "MVT::iPTR";
- case MVT::iPTRAny: return "MVT::iPTRAny";
- case MVT::Untyped: return "MVT::Untyped";
- case MVT::funcref: return "MVT::funcref";
- case MVT::externref: return "MVT::externref";
+ case MVT::nxv1f32: return "MVT::nxv1f32";
+ case MVT::nxv2f32: return "MVT::nxv2f32";
+ case MVT::nxv4f32: return "MVT::nxv4f32";
+ case MVT::nxv8f32: return "MVT::nxv8f32";
+ case MVT::nxv16f32: return "MVT::nxv16f32";
+ case MVT::nxv1f64: return "MVT::nxv1f64";
+ case MVT::nxv2f64: return "MVT::nxv2f64";
+ case MVT::nxv4f64: return "MVT::nxv4f64";
+ case MVT::nxv8f64: return "MVT::nxv8f64";
+ case MVT::token: return "MVT::token";
+ case MVT::Metadata: return "MVT::Metadata";
+ case MVT::iPTR: return "MVT::iPTR";
+ case MVT::iPTRAny: return "MVT::iPTRAny";
+ case MVT::Untyped: return "MVT::Untyped";
+ case MVT::funcref: return "MVT::funcref";
+ case MVT::externref: return "MVT::externref";
default: llvm_unreachable("ILLEGAL VALUE TYPE!");
}
}
@@ -260,29 +260,29 @@ CodeGenTarget::CodeGenTarget(RecordKeeper &records)
CodeGenTarget::~CodeGenTarget() {
}
-StringRef CodeGenTarget::getName() const { return TargetRec->getName(); }
+StringRef CodeGenTarget::getName() const { return TargetRec->getName(); }
-/// getInstNamespace - Find and return the target machine's instruction
-/// namespace. The namespace is cached because it is requested multiple times.
+/// getInstNamespace - Find and return the target machine's instruction
+/// namespace. The namespace is cached because it is requested multiple times.
StringRef CodeGenTarget::getInstNamespace() const {
- if (InstNamespace.empty()) {
- for (const CodeGenInstruction *Inst : getInstructionsByEnumValue()) {
- // We are not interested in the "TargetOpcode" namespace.
- if (Inst->Namespace != "TargetOpcode") {
- InstNamespace = Inst->Namespace;
- break;
- }
- }
+ if (InstNamespace.empty()) {
+ for (const CodeGenInstruction *Inst : getInstructionsByEnumValue()) {
+ // We are not interested in the "TargetOpcode" namespace.
+ if (Inst->Namespace != "TargetOpcode") {
+ InstNamespace = Inst->Namespace;
+ break;
+ }
+ }
}
- return InstNamespace;
+ return InstNamespace;
+}
+
+StringRef CodeGenTarget::getRegNamespace() const {
+ auto &RegClasses = RegBank->getRegClasses();
+ return RegClasses.size() > 0 ? RegClasses.front().Namespace : "";
}
-StringRef CodeGenTarget::getRegNamespace() const {
- auto &RegClasses = RegBank->getRegClasses();
- return RegClasses.size() > 0 ? RegClasses.front().Namespace : "";
-}
-
Record *CodeGenTarget::getInstructionSet() const {
return TargetRec->getValueAsDef("InstructionSet");
}
@@ -341,8 +341,8 @@ CodeGenRegBank &CodeGenTarget::getRegBank() const {
Optional<CodeGenRegisterClass *>
CodeGenTarget::getSuperRegForSubReg(const ValueTypeByHwMode &ValueTy,
CodeGenRegBank &RegBank,
- const CodeGenSubRegIndex *SubIdx,
- bool MustBeAllocatable) const {
+ const CodeGenSubRegIndex *SubIdx,
+ bool MustBeAllocatable) const {
std::vector<CodeGenRegisterClass *> Candidates;
auto &RegClasses = RegBank.getRegClasses();
@@ -355,13 +355,13 @@ CodeGenTarget::getSuperRegForSubReg(const ValueTypeByHwMode &ValueTy,
continue;
// We have a class. Check if it supports this value type.
- if (!llvm::is_contained(SubClassWithSubReg->VTs, ValueTy))
+ if (!llvm::is_contained(SubClassWithSubReg->VTs, ValueTy))
+ continue;
+
+ // If necessary, check that it is allocatable.
+ if (MustBeAllocatable && !SubClassWithSubReg->Allocatable)
continue;
- // If necessary, check that it is allocatable.
- if (MustBeAllocatable && !SubClassWithSubReg->Allocatable)
- continue;
-
// We have a register class which supports both the value type and
// subregister index. Remember it.
Candidates.push_back(SubClassWithSubReg);
@@ -395,7 +395,7 @@ void CodeGenTarget::ReadRegAltNameIndices() const {
/// getRegisterByName - If there is a register with the specific AsmName,
/// return it.
const CodeGenRegister *CodeGenTarget::getRegisterByName(StringRef Name) const {
- return getRegBank().getRegistersByName().lookup(Name);
+ return getRegBank().getRegistersByName().lookup(Name);
}
std::vector<ValueTypeByHwMode> CodeGenTarget::getRegisterVTs(Record *R)
@@ -405,7 +405,7 @@ std::vector<ValueTypeByHwMode> CodeGenTarget::getRegisterVTs(Record *R)
for (const auto &RC : getRegBank().getRegClasses()) {
if (RC.contains(Reg)) {
ArrayRef<ValueTypeByHwMode> InVTs = RC.getValueTypes();
- llvm::append_range(Result, InVTs);
+ llvm::append_range(Result, InVTs);
}
}
@@ -418,7 +418,7 @@ std::vector<ValueTypeByHwMode> CodeGenTarget::getRegisterVTs(Record *R)
void CodeGenTarget::ReadLegalValueTypes() const {
for (const auto &RC : getRegBank().getRegClasses())
- llvm::append_range(LegalValueTypes, RC.VTs);
+ llvm::append_range(LegalValueTypes, RC.VTs);
// Remove duplicates.
llvm::sort(LegalValueTypes);
@@ -612,19 +612,19 @@ ComplexPattern::ComplexPattern(Record *R) {
//===----------------------------------------------------------------------===//
CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) {
- std::vector<Record *> IntrProperties =
- RC.getAllDerivedDefinitions("IntrinsicProperty");
-
- std::vector<Record *> DefaultProperties;
- for (Record *Rec : IntrProperties)
- if (Rec->getValueAsBit("IsDefault"))
- DefaultProperties.push_back(Rec);
-
- std::vector<Record *> Defs = RC.getAllDerivedDefinitions("Intrinsic");
+ std::vector<Record *> IntrProperties =
+ RC.getAllDerivedDefinitions("IntrinsicProperty");
+
+ std::vector<Record *> DefaultProperties;
+ for (Record *Rec : IntrProperties)
+ if (Rec->getValueAsBit("IsDefault"))
+ DefaultProperties.push_back(Rec);
+
+ std::vector<Record *> Defs = RC.getAllDerivedDefinitions("Intrinsic");
Intrinsics.reserve(Defs.size());
for (unsigned I = 0, e = Defs.size(); I != e; ++I)
- Intrinsics.push_back(CodeGenIntrinsic(Defs[I], DefaultProperties));
+ Intrinsics.push_back(CodeGenIntrinsic(Defs[I], DefaultProperties));
llvm::sort(Intrinsics,
[](const CodeGenIntrinsic &LHS, const CodeGenIntrinsic &RHS) {
@@ -640,8 +640,8 @@ CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) {
Targets.back().Count = Intrinsics.size() - Targets.back().Offset;
}
-CodeGenIntrinsic::CodeGenIntrinsic(Record *R,
- std::vector<Record *> DefaultProperties) {
+CodeGenIntrinsic::CodeGenIntrinsic(Record *R,
+ std::vector<Record *> DefaultProperties) {
TheDef = R;
std::string DefName = std::string(R->getName());
ArrayRef<SMLoc> DefLoc = R->getLoc();
@@ -794,12 +794,12 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R,
assert(Property->isSubClassOf("IntrinsicProperty") &&
"Expected a property!");
- setProperty(Property);
+ setProperty(Property);
}
- // Set default properties to true.
- setDefaultProperties(R, DefaultProperties);
-
+ // Set default properties to true.
+ setDefaultProperties(R, DefaultProperties);
+
// Also record the SDPatternOperator Properties.
Properties = parseSDPatternOperatorProperties(R);
@@ -807,92 +807,92 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R,
llvm::sort(ArgumentAttributes);
}
-void CodeGenIntrinsic::setDefaultProperties(
- Record *R, std::vector<Record *> DefaultProperties) {
- // opt-out of using default attributes.
- if (R->getValueAsBit("DisableDefaultAttributes"))
- return;
-
- for (Record *Rec : DefaultProperties)
- setProperty(Rec);
-}
-
-void CodeGenIntrinsic::setProperty(Record *R) {
- if (R->getName() == "IntrNoMem")
- ModRef = NoMem;
- else if (R->getName() == "IntrReadMem") {
- if (!(ModRef & MR_Ref))
- PrintFatalError(TheDef->getLoc(),
- Twine("IntrReadMem cannot be used after IntrNoMem or "
- "IntrWriteMem. Default is ReadWrite"));
- ModRef = ModRefBehavior(ModRef & ~MR_Mod);
- } else if (R->getName() == "IntrWriteMem") {
- if (!(ModRef & MR_Mod))
- PrintFatalError(TheDef->getLoc(),
- Twine("IntrWriteMem cannot be used after IntrNoMem or "
- "IntrReadMem. Default is ReadWrite"));
- ModRef = ModRefBehavior(ModRef & ~MR_Ref);
- } else if (R->getName() == "IntrArgMemOnly")
- ModRef = ModRefBehavior((ModRef & ~MR_Anywhere) | MR_ArgMem);
- else if (R->getName() == "IntrInaccessibleMemOnly")
- ModRef = ModRefBehavior((ModRef & ~MR_Anywhere) | MR_InaccessibleMem);
- else if (R->getName() == "IntrInaccessibleMemOrArgMemOnly")
- ModRef = ModRefBehavior((ModRef & ~MR_Anywhere) | MR_ArgMem |
- MR_InaccessibleMem);
- else if (R->getName() == "Commutative")
- isCommutative = true;
- else if (R->getName() == "Throws")
- canThrow = true;
- else if (R->getName() == "IntrNoDuplicate")
- isNoDuplicate = true;
- else if (R->getName() == "IntrConvergent")
- isConvergent = true;
- else if (R->getName() == "IntrNoReturn")
- isNoReturn = true;
- else if (R->getName() == "IntrNoSync")
- isNoSync = true;
- else if (R->getName() == "IntrNoFree")
- isNoFree = true;
- else if (R->getName() == "IntrWillReturn")
- isWillReturn = !isNoReturn;
- else if (R->getName() == "IntrCold")
- isCold = true;
- else if (R->getName() == "IntrSpeculatable")
- isSpeculatable = true;
- else if (R->getName() == "IntrHasSideEffects")
- hasSideEffects = true;
- else if (R->isSubClassOf("NoCapture")) {
- unsigned ArgNo = R->getValueAsInt("ArgNo");
- ArgumentAttributes.emplace_back(ArgNo, NoCapture, 0);
- } else if (R->isSubClassOf("NoAlias")) {
- unsigned ArgNo = R->getValueAsInt("ArgNo");
- ArgumentAttributes.emplace_back(ArgNo, NoAlias, 0);
- } else if (R->isSubClassOf("NoUndef")) {
- unsigned ArgNo = R->getValueAsInt("ArgNo");
- ArgumentAttributes.emplace_back(ArgNo, NoUndef, 0);
- } else if (R->isSubClassOf("Returned")) {
- unsigned ArgNo = R->getValueAsInt("ArgNo");
- ArgumentAttributes.emplace_back(ArgNo, Returned, 0);
- } else if (R->isSubClassOf("ReadOnly")) {
- unsigned ArgNo = R->getValueAsInt("ArgNo");
- ArgumentAttributes.emplace_back(ArgNo, ReadOnly, 0);
- } else if (R->isSubClassOf("WriteOnly")) {
- unsigned ArgNo = R->getValueAsInt("ArgNo");
- ArgumentAttributes.emplace_back(ArgNo, WriteOnly, 0);
- } else if (R->isSubClassOf("ReadNone")) {
- unsigned ArgNo = R->getValueAsInt("ArgNo");
- ArgumentAttributes.emplace_back(ArgNo, ReadNone, 0);
- } else if (R->isSubClassOf("ImmArg")) {
- unsigned ArgNo = R->getValueAsInt("ArgNo");
- ArgumentAttributes.emplace_back(ArgNo, ImmArg, 0);
- } else if (R->isSubClassOf("Align")) {
- unsigned ArgNo = R->getValueAsInt("ArgNo");
- uint64_t Align = R->getValueAsInt("Align");
- ArgumentAttributes.emplace_back(ArgNo, Alignment, Align);
- } else
- llvm_unreachable("Unknown property!");
-}
-
+void CodeGenIntrinsic::setDefaultProperties(
+ Record *R, std::vector<Record *> DefaultProperties) {
+ // opt-out of using default attributes.
+ if (R->getValueAsBit("DisableDefaultAttributes"))
+ return;
+
+ for (Record *Rec : DefaultProperties)
+ setProperty(Rec);
+}
+
+void CodeGenIntrinsic::setProperty(Record *R) {
+ if (R->getName() == "IntrNoMem")
+ ModRef = NoMem;
+ else if (R->getName() == "IntrReadMem") {
+ if (!(ModRef & MR_Ref))
+ PrintFatalError(TheDef->getLoc(),
+ Twine("IntrReadMem cannot be used after IntrNoMem or "
+ "IntrWriteMem. Default is ReadWrite"));
+ ModRef = ModRefBehavior(ModRef & ~MR_Mod);
+ } else if (R->getName() == "IntrWriteMem") {
+ if (!(ModRef & MR_Mod))
+ PrintFatalError(TheDef->getLoc(),
+ Twine("IntrWriteMem cannot be used after IntrNoMem or "
+ "IntrReadMem. Default is ReadWrite"));
+ ModRef = ModRefBehavior(ModRef & ~MR_Ref);
+ } else if (R->getName() == "IntrArgMemOnly")
+ ModRef = ModRefBehavior((ModRef & ~MR_Anywhere) | MR_ArgMem);
+ else if (R->getName() == "IntrInaccessibleMemOnly")
+ ModRef = ModRefBehavior((ModRef & ~MR_Anywhere) | MR_InaccessibleMem);
+ else if (R->getName() == "IntrInaccessibleMemOrArgMemOnly")
+ ModRef = ModRefBehavior((ModRef & ~MR_Anywhere) | MR_ArgMem |
+ MR_InaccessibleMem);
+ else if (R->getName() == "Commutative")
+ isCommutative = true;
+ else if (R->getName() == "Throws")
+ canThrow = true;
+ else if (R->getName() == "IntrNoDuplicate")
+ isNoDuplicate = true;
+ else if (R->getName() == "IntrConvergent")
+ isConvergent = true;
+ else if (R->getName() == "IntrNoReturn")
+ isNoReturn = true;
+ else if (R->getName() == "IntrNoSync")
+ isNoSync = true;
+ else if (R->getName() == "IntrNoFree")
+ isNoFree = true;
+ else if (R->getName() == "IntrWillReturn")
+ isWillReturn = !isNoReturn;
+ else if (R->getName() == "IntrCold")
+ isCold = true;
+ else if (R->getName() == "IntrSpeculatable")
+ isSpeculatable = true;
+ else if (R->getName() == "IntrHasSideEffects")
+ hasSideEffects = true;
+ else if (R->isSubClassOf("NoCapture")) {
+ unsigned ArgNo = R->getValueAsInt("ArgNo");
+ ArgumentAttributes.emplace_back(ArgNo, NoCapture, 0);
+ } else if (R->isSubClassOf("NoAlias")) {
+ unsigned ArgNo = R->getValueAsInt("ArgNo");
+ ArgumentAttributes.emplace_back(ArgNo, NoAlias, 0);
+ } else if (R->isSubClassOf("NoUndef")) {
+ unsigned ArgNo = R->getValueAsInt("ArgNo");
+ ArgumentAttributes.emplace_back(ArgNo, NoUndef, 0);
+ } else if (R->isSubClassOf("Returned")) {
+ unsigned ArgNo = R->getValueAsInt("ArgNo");
+ ArgumentAttributes.emplace_back(ArgNo, Returned, 0);
+ } else if (R->isSubClassOf("ReadOnly")) {
+ unsigned ArgNo = R->getValueAsInt("ArgNo");
+ ArgumentAttributes.emplace_back(ArgNo, ReadOnly, 0);
+ } else if (R->isSubClassOf("WriteOnly")) {
+ unsigned ArgNo = R->getValueAsInt("ArgNo");
+ ArgumentAttributes.emplace_back(ArgNo, WriteOnly, 0);
+ } else if (R->isSubClassOf("ReadNone")) {
+ unsigned ArgNo = R->getValueAsInt("ArgNo");
+ ArgumentAttributes.emplace_back(ArgNo, ReadNone, 0);
+ } else if (R->isSubClassOf("ImmArg")) {
+ unsigned ArgNo = R->getValueAsInt("ArgNo");
+ ArgumentAttributes.emplace_back(ArgNo, ImmArg, 0);
+ } else if (R->isSubClassOf("Align")) {
+ unsigned ArgNo = R->getValueAsInt("ArgNo");
+ uint64_t Align = R->getValueAsInt("Align");
+ ArgumentAttributes.emplace_back(ArgNo, Alignment, Align);
+ } else
+ llvm_unreachable("Unknown property!");
+}
+
bool CodeGenIntrinsic::isParamAPointer(unsigned ParamIdx) const {
if (ParamIdx >= IS.ParamVTs.size())
return false;
diff --git a/contrib/libs/llvm12/utils/TableGen/CodeGenTarget.h b/contrib/libs/llvm12/utils/TableGen/CodeGenTarget.h
index 10bdab7e21..9de9b512f7 100644
--- a/contrib/libs/llvm12/utils/TableGen/CodeGenTarget.h
+++ b/contrib/libs/llvm12/utils/TableGen/CodeGenTarget.h
@@ -60,7 +60,7 @@ class CodeGenTarget {
mutable std::unique_ptr<CodeGenSchedModels> SchedModels;
- mutable StringRef InstNamespace;
+ mutable StringRef InstNamespace;
mutable std::vector<const CodeGenInstruction*> InstrsByEnum;
mutable unsigned NumPseudoInstructions = 0;
public:
@@ -68,15 +68,15 @@ public:
~CodeGenTarget();
Record *getTargetRecord() const { return TargetRec; }
- StringRef getName() const;
+ StringRef getName() const;
/// getInstNamespace - Return the target-specific instruction namespace.
///
StringRef getInstNamespace() const;
- /// getRegNamespace - Return the target-specific register namespace.
- StringRef getRegNamespace() const;
-
+ /// getRegNamespace - Return the target-specific register namespace.
+ StringRef getRegNamespace() const;
+
/// getInstructionSet - Return the InstructionSet object.
///
Record *getInstructionSet() const;
@@ -111,8 +111,8 @@ public:
/// covers \p SubIdx if it exists.
Optional<CodeGenRegisterClass *>
getSuperRegForSubReg(const ValueTypeByHwMode &Ty, CodeGenRegBank &RegBank,
- const CodeGenSubRegIndex *SubIdx,
- bool MustBeAllocatable = false) const;
+ const CodeGenSubRegIndex *SubIdx,
+ bool MustBeAllocatable = false) const;
/// getRegisterByName - If there is a register with the specific AsmName,
/// return it.
diff --git a/contrib/libs/llvm12/utils/TableGen/DAGISelEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/DAGISelEmitter.cpp
index 7e9a624877..32ed0bf987 100644
--- a/contrib/libs/llvm12/utils/TableGen/DAGISelEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/DAGISelEmitter.cpp
@@ -23,10 +23,10 @@ namespace {
/// DAGISelEmitter - The top-level class which coordinates construction
/// and emission of the instruction selector.
class DAGISelEmitter {
- RecordKeeper &Records; // Just so we can get at the timing functions.
+ RecordKeeper &Records; // Just so we can get at the timing functions.
CodeGenDAGPatterns CGP;
public:
- explicit DAGISelEmitter(RecordKeeper &R) : Records(R), CGP(R) {}
+ explicit DAGISelEmitter(RecordKeeper &R) : Records(R), CGP(R) {}
void run(raw_ostream &OS);
};
} // End anonymous namespace
@@ -151,7 +151,7 @@ void DAGISelEmitter::run(raw_ostream &OS) {
});
// Add all the patterns to a temporary list so we can sort them.
- Records.startTimer("Sort patterns");
+ Records.startTimer("Sort patterns");
std::vector<const PatternToMatch*> Patterns;
for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(), E = CGP.ptm_end();
I != E; ++I)
@@ -159,10 +159,10 @@ void DAGISelEmitter::run(raw_ostream &OS) {
// We want to process the matches in order of minimal cost. Sort the patterns
// so the least cost one is at the start.
- llvm::stable_sort(Patterns, PatternSortingPredicate(CGP));
+ llvm::stable_sort(Patterns, PatternSortingPredicate(CGP));
// Convert each variant of each pattern into a Matcher.
- Records.startTimer("Convert to matchers");
+ Records.startTimer("Convert to matchers");
std::vector<Matcher*> PatternMatchers;
for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
for (unsigned Variant = 0; ; ++Variant) {
@@ -176,19 +176,19 @@ void DAGISelEmitter::run(raw_ostream &OS) {
std::unique_ptr<Matcher> TheMatcher =
std::make_unique<ScopeMatcher>(PatternMatchers);
- Records.startTimer("Optimize matchers");
+ Records.startTimer("Optimize matchers");
OptimizeMatcher(TheMatcher, CGP);
-
+
//Matcher->dump();
-
- Records.startTimer("Emit matcher table");
+
+ Records.startTimer("Emit matcher table");
EmitMatcherTable(TheMatcher.get(), CGP, OS);
}
namespace llvm {
void EmitDAGISel(RecordKeeper &RK, raw_ostream &OS) {
- RK.startTimer("Parse patterns");
+ RK.startTimer("Parse patterns");
DAGISelEmitter(RK).run(OS);
}
diff --git a/contrib/libs/llvm12/utils/TableGen/DAGISelMatcher.h b/contrib/libs/llvm12/utils/TableGen/DAGISelMatcher.h
index 370ad82c54..ff9a0cb335 100644
--- a/contrib/libs/llvm12/utils/TableGen/DAGISelMatcher.h
+++ b/contrib/libs/llvm12/utils/TableGen/DAGISelMatcher.h
@@ -31,7 +31,7 @@ Matcher *ConvertPatternToMatcher(const PatternToMatch &Pattern,unsigned Variant,
const CodeGenDAGPatterns &CGP);
void OptimizeMatcher(std::unique_ptr<Matcher> &Matcher,
const CodeGenDAGPatterns &CGP);
-void EmitMatcherTable(Matcher *Matcher, const CodeGenDAGPatterns &CGP,
+void EmitMatcherTable(Matcher *Matcher, const CodeGenDAGPatterns &CGP,
raw_ostream &OS);
@@ -41,7 +41,7 @@ class Matcher {
// The next matcher node that is executed after this one. Null if this is the
// last stage of a match.
std::unique_ptr<Matcher> Next;
- size_t Size; // Size in bytes of matcher and all its children (if any).
+ size_t Size; // Size in bytes of matcher and all its children (if any).
virtual void anchor();
public:
enum KindTy {
@@ -86,10 +86,10 @@ public:
EmitNode, // Create a DAG node
EmitNodeXForm, // Run a SDNodeXForm
CompleteMatch, // Finish a match and update the results.
- MorphNodeTo, // Build a node, finish a match and update results.
-
- // Highest enum value; watch out when adding more.
- HighestKind = MorphNodeTo
+ MorphNodeTo, // Build a node, finish a match and update results.
+
+ // Highest enum value; watch out when adding more.
+ HighestKind = MorphNodeTo
};
const KindTy Kind;
@@ -98,8 +98,8 @@ protected:
public:
virtual ~Matcher() {}
- unsigned getSize() const { return Size; }
- void setSize(unsigned sz) { Size = sz; }
+ unsigned getSize() const { return Size; }
+ void setSize(unsigned sz) { Size = sz; }
KindTy getKind() const { return Kind; }
Matcher *getNext() { return Next.get(); }
@@ -706,7 +706,7 @@ public:
const ComplexPattern &getPattern() const { return Pattern; }
unsigned getMatchNumber() const { return MatchNumber; }
- std::string getName() const { return Name; }
+ std::string getName() const { return Name; }
unsigned getFirstResult() const { return FirstResult; }
static bool classof(const Matcher *N) {
@@ -763,8 +763,8 @@ private:
}
};
-/// CheckImmAllOnesVMatcher - This checks if the current node is a build_vector
-/// or splat_vector of all ones.
+/// CheckImmAllOnesVMatcher - This checks if the current node is a build_vector
+/// or splat_vector of all ones.
class CheckImmAllOnesVMatcher : public Matcher {
public:
CheckImmAllOnesVMatcher() : Matcher(CheckImmAllOnesV) {}
@@ -779,8 +779,8 @@ private:
bool isContradictoryImpl(const Matcher *M) const override;
};
-/// CheckImmAllZerosVMatcher - This checks if the current node is a
-/// build_vector or splat_vector of all zeros.
+/// CheckImmAllZerosVMatcher - This checks if the current node is a
+/// build_vector or splat_vector of all zeros.
class CheckImmAllZerosVMatcher : public Matcher {
public:
CheckImmAllZerosVMatcher() : Matcher(CheckImmAllZerosV) {}
diff --git a/contrib/libs/llvm12/utils/TableGen/DAGISelMatcherEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/DAGISelMatcherEmitter.cpp
index 21ae8b3551..03528a46ae 100644
--- a/contrib/libs/llvm12/utils/TableGen/DAGISelMatcherEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -23,7 +23,7 @@
#include "llvm/Support/SourceMgr.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
-
+
using namespace llvm;
enum {
@@ -48,8 +48,8 @@ namespace {
class MatcherTableEmitter {
const CodeGenDAGPatterns &CGP;
- SmallVector<unsigned, Matcher::HighestKind+1> OpcodeCounts;
-
+ SmallVector<unsigned, Matcher::HighestKind+1> OpcodeCounts;
+
DenseMap<TreePattern *, unsigned> NodePredicateMap;
std::vector<TreePredicateFn> NodePredicates;
std::vector<TreePredicateFn> NodePredicatesWithOperands;
@@ -82,15 +82,15 @@ class MatcherTableEmitter {
}
public:
- MatcherTableEmitter(const CodeGenDAGPatterns &cgp) : CGP(cgp) {
- OpcodeCounts.assign(Matcher::HighestKind+1, 0);
- }
+ MatcherTableEmitter(const CodeGenDAGPatterns &cgp) : CGP(cgp) {
+ OpcodeCounts.assign(Matcher::HighestKind+1, 0);
+ }
- unsigned EmitMatcherList(const Matcher *N, const unsigned Indent,
+ unsigned EmitMatcherList(const Matcher *N, const unsigned Indent,
unsigned StartIdx, raw_ostream &OS);
- unsigned SizeMatcherList(Matcher *N, raw_ostream &OS);
-
+ unsigned SizeMatcherList(Matcher *N, raw_ostream &OS);
+
void EmitPredicateFunctions(raw_ostream &OS);
void EmitHistogram(const Matcher *N, raw_ostream &OS);
@@ -101,9 +101,9 @@ private:
void EmitNodePredicatesFunction(const std::vector<TreePredicateFn> &Preds,
StringRef Decl, raw_ostream &OS);
- unsigned SizeMatcher(Matcher *N, raw_ostream &OS);
-
- unsigned EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
+ unsigned SizeMatcher(Matcher *N, raw_ostream &OS);
+
+ unsigned EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
raw_ostream &OS);
unsigned getNodePredicate(TreePredicateFn Pred) {
@@ -173,7 +173,7 @@ static std::string GetPatFromTreePatternNode(const TreePatternNode *N) {
return str;
}
-static size_t GetVBRSize(unsigned Val) {
+static size_t GetVBRSize(unsigned Val) {
if (Val <= 127) return 1;
unsigned NumBytes = 0;
@@ -227,78 +227,78 @@ static std::string getIncludePath(const Record *R) {
return str;
}
-/// This function traverses the matcher tree and sizes all the nodes
-/// that are children of the three kinds of nodes that have them.
-unsigned MatcherTableEmitter::
-SizeMatcherList(Matcher *N, raw_ostream &OS) {
- unsigned Size = 0;
- while (N) {
- Size += SizeMatcher(N, OS);
- N = N->getNext();
- }
- return Size;
-}
-
-/// This function sizes the children of the three kinds of nodes that
-/// have them. It does so by using special cases for those three
-/// nodes, but sharing the code in EmitMatcher() for the other kinds.
-unsigned MatcherTableEmitter::
-SizeMatcher(Matcher *N, raw_ostream &OS) {
- unsigned Idx = 0;
-
- ++OpcodeCounts[N->getKind()];
- switch (N->getKind()) {
- // The Scope matcher has its kind, a series of child size + child,
- // and a trailing zero.
- case Matcher::Scope: {
- ScopeMatcher *SM = cast<ScopeMatcher>(N);
- assert(SM->getNext() == nullptr && "Scope matcher should not have next");
- unsigned Size = 1; // Count the kind.
- for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i) {
- const size_t ChildSize = SizeMatcherList(SM->getChild(i), OS);
- assert(ChildSize != 0 && "Matcher cannot have child of size 0");
- SM->getChild(i)->setSize(ChildSize);
- Size += GetVBRSize(ChildSize) + ChildSize; // Count VBR and child size.
- }
- ++Size; // Count the zero sentinel.
- return Size;
- }
-
- // SwitchOpcode and SwitchType have their kind, a series of child size +
- // opcode/type + child, and a trailing zero.
- case Matcher::SwitchOpcode:
- case Matcher::SwitchType: {
- unsigned Size = 1; // Count the kind.
- unsigned NumCases;
- if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N))
- NumCases = SOM->getNumCases();
- else
- NumCases = cast<SwitchTypeMatcher>(N)->getNumCases();
- for (unsigned i = 0, e = NumCases; i != e; ++i) {
- Matcher *Child;
- if (SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) {
- Child = SOM->getCaseMatcher(i);
- Size += 2; // Count the child's opcode.
- } else {
- Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i);
- ++Size; // Count the child's type.
- }
- const size_t ChildSize = SizeMatcherList(Child, OS);
- assert(ChildSize != 0 && "Matcher cannot have child of size 0");
- Child->setSize(ChildSize);
- Size += GetVBRSize(ChildSize) + ChildSize; // Count VBR and child size.
- }
- ++Size; // Count the zero sentinel.
- return Size;
- }
-
- default:
- // Employ the matcher emitter to size other matchers.
- return EmitMatcher(N, 0, Idx, OS);
- }
- llvm_unreachable("Unreachable");
-}
-
+/// This function traverses the matcher tree and sizes all the nodes
+/// that are children of the three kinds of nodes that have them.
+unsigned MatcherTableEmitter::
+SizeMatcherList(Matcher *N, raw_ostream &OS) {
+ unsigned Size = 0;
+ while (N) {
+ Size += SizeMatcher(N, OS);
+ N = N->getNext();
+ }
+ return Size;
+}
+
+/// This function sizes the children of the three kinds of nodes that
+/// have them. It does so by using special cases for those three
+/// nodes, but sharing the code in EmitMatcher() for the other kinds.
+unsigned MatcherTableEmitter::
+SizeMatcher(Matcher *N, raw_ostream &OS) {
+ unsigned Idx = 0;
+
+ ++OpcodeCounts[N->getKind()];
+ switch (N->getKind()) {
+ // The Scope matcher has its kind, a series of child size + child,
+ // and a trailing zero.
+ case Matcher::Scope: {
+ ScopeMatcher *SM = cast<ScopeMatcher>(N);
+ assert(SM->getNext() == nullptr && "Scope matcher should not have next");
+ unsigned Size = 1; // Count the kind.
+ for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i) {
+ const size_t ChildSize = SizeMatcherList(SM->getChild(i), OS);
+ assert(ChildSize != 0 && "Matcher cannot have child of size 0");
+ SM->getChild(i)->setSize(ChildSize);
+ Size += GetVBRSize(ChildSize) + ChildSize; // Count VBR and child size.
+ }
+ ++Size; // Count the zero sentinel.
+ return Size;
+ }
+
+ // SwitchOpcode and SwitchType have their kind, a series of child size +
+ // opcode/type + child, and a trailing zero.
+ case Matcher::SwitchOpcode:
+ case Matcher::SwitchType: {
+ unsigned Size = 1; // Count the kind.
+ unsigned NumCases;
+ if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N))
+ NumCases = SOM->getNumCases();
+ else
+ NumCases = cast<SwitchTypeMatcher>(N)->getNumCases();
+ for (unsigned i = 0, e = NumCases; i != e; ++i) {
+ Matcher *Child;
+ if (SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) {
+ Child = SOM->getCaseMatcher(i);
+ Size += 2; // Count the child's opcode.
+ } else {
+ Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i);
+ ++Size; // Count the child's type.
+ }
+ const size_t ChildSize = SizeMatcherList(Child, OS);
+ assert(ChildSize != 0 && "Matcher cannot have child of size 0");
+ Child->setSize(ChildSize);
+ Size += GetVBRSize(ChildSize) + ChildSize; // Count VBR and child size.
+ }
+ ++Size; // Count the zero sentinel.
+ return Size;
+ }
+
+ default:
+ // Employ the matcher emitter to size other matchers.
+ return EmitMatcher(N, 0, Idx, OS);
+ }
+ llvm_unreachable("Unreachable");
+}
+
static void BeginEmitFunction(raw_ostream &OS, StringRef RetType,
StringRef Decl, bool AddOverride) {
OS << "#ifdef GET_DAGISEL_DECL\n";
@@ -330,7 +330,7 @@ void MatcherTableEmitter::EmitPatternMatchTable(raw_ostream &OS) {
BeginEmitFunction(OS, "StringRef", "getPatternForIndex(unsigned Index)",
true/*AddOverride*/);
OS << "{\n";
- OS << "static const char *PATTERN_MATCH_TABLE[] = {\n";
+ OS << "static const char *PATTERN_MATCH_TABLE[] = {\n";
for (const auto &It : VecPatterns) {
OS << "\"" << It.first << "\",\n";
@@ -344,7 +344,7 @@ void MatcherTableEmitter::EmitPatternMatchTable(raw_ostream &OS) {
BeginEmitFunction(OS, "StringRef", "getIncludePathForIndex(unsigned Index)",
true/*AddOverride*/);
OS << "{\n";
- OS << "static const char *INCLUDE_PATH_TABLE[] = {\n";
+ OS << "static const char *INCLUDE_PATH_TABLE[] = {\n";
for (const auto &It : VecIncludeStrings) {
OS << "\"" << It << "\",\n";
@@ -359,7 +359,7 @@ void MatcherTableEmitter::EmitPatternMatchTable(raw_ostream &OS) {
/// EmitMatcher - Emit bytes for the specified matcher and return
/// the number of bytes emitted.
unsigned MatcherTableEmitter::
-EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
+EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
raw_ostream &OS) {
OS.indent(Indent);
@@ -381,21 +381,21 @@ EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
OS.indent(Indent);
}
- size_t ChildSize = SM->getChild(i)->getSize();
- size_t VBRSize = GetVBRSize(ChildSize);
- EmitVBRValue(ChildSize, OS);
+ size_t ChildSize = SM->getChild(i)->getSize();
+ size_t VBRSize = GetVBRSize(ChildSize);
+ EmitVBRValue(ChildSize, OS);
if (!OmitComments) {
- OS << "/*->" << CurrentIdx + VBRSize + ChildSize << "*/";
+ OS << "/*->" << CurrentIdx + VBRSize + ChildSize << "*/";
if (i == 0)
OS << " // " << SM->getNumChildren() << " children in Scope";
}
- OS << '\n';
+ OS << '\n';
- ChildSize = EmitMatcherList(SM->getChild(i), Indent+1,
- CurrentIdx + VBRSize, OS);
- assert(ChildSize == SM->getChild(i)->getSize() &&
- "Emitted child size does not match calculated size");
- CurrentIdx += VBRSize + ChildSize;
+ ChildSize = EmitMatcherList(SM->getChild(i), Indent+1,
+ CurrentIdx + VBRSize, OS);
+ assert(ChildSize == SM->getChild(i)->getSize() &&
+ "Emitted child size does not match calculated size");
+ CurrentIdx += VBRSize + ChildSize;
}
// Emit a zero as a sentinel indicating end of 'Scope'.
@@ -534,19 +534,19 @@ EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
"/*SwitchOpcode*/ " : "/*SwitchType*/ ");
}
- size_t ChildSize = Child->getSize();
- CurrentIdx += EmitVBRValue(ChildSize, OS) + IdxSize;
+ size_t ChildSize = Child->getSize();
+ CurrentIdx += EmitVBRValue(ChildSize, OS) + IdxSize;
if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N))
OS << "TARGET_VAL(" << SOM->getCaseOpcode(i).getEnumName() << "),";
else
OS << getEnumName(cast<SwitchTypeMatcher>(N)->getCaseType(i)) << ',';
if (!OmitComments)
- OS << "// ->" << CurrentIdx + ChildSize;
+ OS << "// ->" << CurrentIdx + ChildSize;
OS << '\n';
-
- ChildSize = EmitMatcherList(Child, Indent+1, CurrentIdx, OS);
- assert(ChildSize == Child->getSize() &&
- "Emitted child size does not match calculated size");
+
+ ChildSize = EmitMatcherList(Child, Indent+1, CurrentIdx, OS);
+ assert(ChildSize == Child->getSize() &&
+ "Emitted child size does not match calculated size");
CurrentIdx += ChildSize;
}
@@ -559,7 +559,7 @@ EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
" // EndSwitchOpcode" : " // EndSwitchType");
OS << '\n';
- return CurrentIdx - StartIdx + 1;
+ return CurrentIdx - StartIdx + 1;
}
case Matcher::CheckType:
@@ -853,10 +853,10 @@ EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
llvm_unreachable("Unreachable");
}
-/// This function traverses the matcher tree and emits all the nodes.
-/// The nodes have already been sized.
+/// This function traverses the matcher tree and emits all the nodes.
+/// The nodes have already been sized.
unsigned MatcherTableEmitter::
-EmitMatcherList(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
+EmitMatcherList(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
raw_ostream &OS) {
unsigned Size = 0;
while (N) {
@@ -885,12 +885,12 @@ void MatcherTableEmitter::EmitNodePredicatesFunction(
OS << " default: llvm_unreachable(\"Invalid predicate in table?\");\n";
for (unsigned i = 0, e = Preds.size(); i != e; ++i) {
// Emit the predicate code corresponding to this pattern.
- const TreePredicateFn PredFn = Preds[i];
+ const TreePredicateFn PredFn = Preds[i];
assert(!PredFn.isAlwaysTrue() && "No code in this predicate");
- OS << " case " << i << ": {\n";
+ OS << " case " << i << ": {\n";
for (auto *SimilarPred :
- NodePredicatesByCodeToRun[PredFn.getCodeToRunOnSDNode()])
+ NodePredicatesByCodeToRun[PredFn.getCodeToRunOnSDNode()])
OS << " // " << TreePredicateFn(SimilarPred).getFnName() <<'\n';
OS << PredFn.getCodeToRunOnSDNode() << "\n }\n";
@@ -931,7 +931,7 @@ void MatcherTableEmitter::EmitPredicateFunctions(raw_ostream &OS) {
BeginEmitFunction(OS, "bool",
"CheckComplexPattern(SDNode *Root, SDNode *Parent,\n"
" SDValue N, unsigned PatternNo,\n"
- " SmallVectorImpl<std::pair<SDValue, SDNode *>> &Result)",
+ " SmallVectorImpl<std::pair<SDValue, SDNode *>> &Result)",
true/*AddOverride*/);
OS << "{\n";
OS << " unsigned NextRes = Result.size();\n";
@@ -1071,16 +1071,16 @@ void MatcherTableEmitter::EmitHistogram(const Matcher *M,
return;
OS << " // Opcode Histogram:\n";
- for (unsigned i = 0, e = OpcodeCounts.size(); i != e; ++i) {
+ for (unsigned i = 0, e = OpcodeCounts.size(); i != e; ++i) {
OS << " // #"
<< left_justify(getOpcodeString((Matcher::KindTy)i), HistOpcWidth)
- << " = " << OpcodeCounts[i] << '\n';
+ << " = " << OpcodeCounts[i] << '\n';
}
OS << '\n';
}
-void llvm::EmitMatcherTable(Matcher *TheMatcher,
+void llvm::EmitMatcherTable(Matcher *TheMatcher,
const CodeGenDAGPatterns &CGP,
raw_ostream &OS) {
OS << "#if defined(GET_DAGISEL_DECL) && defined(GET_DAGISEL_BODY)\n";
@@ -1115,23 +1115,23 @@ void llvm::EmitMatcherTable(Matcher *TheMatcher,
BeginEmitFunction(OS, "void", "SelectCode(SDNode *N)", false/*AddOverride*/);
MatcherTableEmitter MatcherEmitter(CGP);
- // First we size all the children of the three kinds of matchers that have
- // them. This is done by sharing the code in EmitMatcher(). but we don't
- // want to emit anything, so we turn off comments and use a null stream.
- bool SaveOmitComments = OmitComments;
- OmitComments = true;
- raw_null_ostream NullOS;
- unsigned TotalSize = MatcherEmitter.SizeMatcherList(TheMatcher, NullOS);
- OmitComments = SaveOmitComments;
-
- // Now that the matchers are sized, we can emit the code for them to the
- // final stream.
+ // First we size all the children of the three kinds of matchers that have
+ // them. This is done by sharing the code in EmitMatcher(). but we don't
+ // want to emit anything, so we turn off comments and use a null stream.
+ bool SaveOmitComments = OmitComments;
+ OmitComments = true;
+ raw_null_ostream NullOS;
+ unsigned TotalSize = MatcherEmitter.SizeMatcherList(TheMatcher, NullOS);
+ OmitComments = SaveOmitComments;
+
+ // Now that the matchers are sized, we can emit the code for them to the
+ // final stream.
OS << "{\n";
OS << " // Some target values are emitted as 2 bytes, TARGET_VAL handles\n";
OS << " // this.\n";
OS << " #define TARGET_VAL(X) X & 255, unsigned(X) >> 8\n";
OS << " static const unsigned char MatcherTable[] = {\n";
- TotalSize = MatcherEmitter.EmitMatcherList(TheMatcher, 1, 0, OS);
+ TotalSize = MatcherEmitter.EmitMatcherList(TheMatcher, 1, 0, OS);
OS << " 0\n }; // Total Array size is " << (TotalSize+1) << " bytes\n\n";
MatcherEmitter.EmitHistogram(TheMatcher, OS);
diff --git a/contrib/libs/llvm12/utils/TableGen/DAGISelMatcherGen.cpp b/contrib/libs/llvm12/utils/TableGen/DAGISelMatcherGen.cpp
index 1e6a497df7..f7415b87e1 100644
--- a/contrib/libs/llvm12/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/DAGISelMatcherGen.cpp
@@ -282,9 +282,9 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
// check to ensure that this gets folded into the normal top-level
// OpcodeSwitch.
if (N == Pattern.getSrcPattern()) {
- MVT VT = N->getSimpleType(0);
- StringRef Name = VT.isScalableVector() ? "splat_vector" : "build_vector";
- const SDNodeInfo &NI = CGP.getSDNodeInfo(CGP.getSDNodeNamed(Name));
+ MVT VT = N->getSimpleType(0);
+ StringRef Name = VT.isScalableVector() ? "splat_vector" : "build_vector";
+ const SDNodeInfo &NI = CGP.getSDNodeInfo(CGP.getSDNodeNamed(Name));
AddMatcher(new CheckOpcodeMatcher(NI));
}
return AddMatcher(new CheckImmAllOnesVMatcher());
@@ -294,9 +294,9 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
// check to ensure that this gets folded into the normal top-level
// OpcodeSwitch.
if (N == Pattern.getSrcPattern()) {
- MVT VT = N->getSimpleType(0);
- StringRef Name = VT.isScalableVector() ? "splat_vector" : "build_vector";
- const SDNodeInfo &NI = CGP.getSDNodeInfo(CGP.getSDNodeNamed(Name));
+ MVT VT = N->getSimpleType(0);
+ StringRef Name = VT.isScalableVector() ? "splat_vector" : "build_vector";
+ const SDNodeInfo &NI = CGP.getSDNodeInfo(CGP.getSDNodeNamed(Name));
AddMatcher(new CheckOpcodeMatcher(NI));
}
return AddMatcher(new CheckImmAllZerosVMatcher());
@@ -748,7 +748,7 @@ void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N,
}
}
- errs() << "unhandled leaf node:\n";
+ errs() << "unhandled leaf node:\n";
N->dump();
}
diff --git a/contrib/libs/llvm12/utils/TableGen/DFAEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/DFAEmitter.cpp
index 71abb47ca2..781cb0636f 100644
--- a/contrib/libs/llvm12/utils/TableGen/DFAEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/DFAEmitter.cpp
@@ -346,7 +346,7 @@ Transition::Transition(Record *R, Automaton *Parent) {
} else if (isa<IntRecTy>(SymbolV->getType())) {
Actions.emplace_back(nullptr, R->getValueAsInt(A), "");
Types.emplace_back("unsigned");
- } else if (isa<StringRecTy>(SymbolV->getType())) {
+ } else if (isa<StringRecTy>(SymbolV->getType())) {
Actions.emplace_back(nullptr, 0, std::string(R->getValueAsString(A)));
Types.emplace_back("std::string");
} else {
diff --git a/contrib/libs/llvm12/utils/TableGen/DFAPacketizerEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/DFAPacketizerEmitter.cpp
index d4ae9208f5..40d9385e5e 100644
--- a/contrib/libs/llvm12/utils/TableGen/DFAPacketizerEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/DFAPacketizerEmitter.cpp
@@ -263,7 +263,7 @@ void DFAPacketizerEmitter::emitForItineraries(
OS << " " << ProcModelStartIdx[Model] << ", // " << Model->ModelName
<< "\n";
}
- OS << " " << ScheduleClasses.size() << "\n};\n\n";
+ OS << " " << ScheduleClasses.size() << "\n};\n\n";
// The type of a state in the nondeterministic automaton we're defining.
using NfaStateTy = uint64_t;
diff --git a/contrib/libs/llvm12/utils/TableGen/DirectiveEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/DirectiveEmitter.cpp
index 6da6be1129..c9daa9b241 100644
--- a/contrib/libs/llvm12/utils/TableGen/DirectiveEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/DirectiveEmitter.cpp
@@ -11,7 +11,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/TableGen/DirectiveEmitter.h"
+#include "llvm/TableGen/DirectiveEmitter.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSet.h"
@@ -42,13 +42,13 @@ namespace llvm {
// Generate enum class
void GenerateEnumClass(const std::vector<Record *> &Records, raw_ostream &OS,
- StringRef Enum, StringRef Prefix,
- const DirectiveLanguage &DirLang) {
+ StringRef Enum, StringRef Prefix,
+ const DirectiveLanguage &DirLang) {
OS << "\n";
OS << "enum class " << Enum << " {\n";
for (const auto &R : Records) {
- BaseRecord Rec{R};
- OS << " " << Prefix << Rec.getFormattedName() << ",\n";
+ BaseRecord Rec{R};
+ OS << " " << Prefix << Rec.getFormattedName() << ",\n";
}
OS << "};\n";
OS << "\n";
@@ -60,130 +60,130 @@ void GenerateEnumClass(const std::vector<Record *> &Records, raw_ostream &OS,
// At the same time we do not loose the strong type guarantees of the enum
// class, that is we cannot pass an unsigned as Directive without an explicit
// cast.
- if (DirLang.hasMakeEnumAvailableInNamespace()) {
+ if (DirLang.hasMakeEnumAvailableInNamespace()) {
OS << "\n";
for (const auto &R : Records) {
- BaseRecord Rec{R};
- OS << "constexpr auto " << Prefix << Rec.getFormattedName() << " = "
- << "llvm::" << DirLang.getCppNamespace() << "::" << Enum
- << "::" << Prefix << Rec.getFormattedName() << ";\n";
+ BaseRecord Rec{R};
+ OS << "constexpr auto " << Prefix << Rec.getFormattedName() << " = "
+ << "llvm::" << DirLang.getCppNamespace() << "::" << Enum
+ << "::" << Prefix << Rec.getFormattedName() << ";\n";
}
}
}
-// Generate enums for values that clauses can take.
-// Also generate function declarations for get<Enum>Name(StringRef Str).
-void GenerateEnumClauseVal(const std::vector<Record *> &Records,
- raw_ostream &OS, const DirectiveLanguage &DirLang,
- std::string &EnumHelperFuncs) {
- for (const auto &R : Records) {
- Clause C{R};
- const auto &ClauseVals = C.getClauseVals();
- if (ClauseVals.size() <= 0)
- continue;
-
- const auto &EnumName = C.getEnumName();
- if (EnumName.size() == 0) {
- PrintError("enumClauseValue field not set in Clause" +
- C.getFormattedName() + ".");
- return;
- }
-
- OS << "\n";
- OS << "enum class " << EnumName << " {\n";
- for (const auto &CV : ClauseVals) {
- ClauseVal CVal{CV};
- OS << " " << CV->getName() << "=" << CVal.getValue() << ",\n";
- }
- OS << "};\n";
-
- if (DirLang.hasMakeEnumAvailableInNamespace()) {
- OS << "\n";
- for (const auto &CV : ClauseVals) {
- OS << "constexpr auto " << CV->getName() << " = "
- << "llvm::" << DirLang.getCppNamespace() << "::" << EnumName
- << "::" << CV->getName() << ";\n";
- }
- EnumHelperFuncs += (llvm::Twine(EnumName) + llvm::Twine(" get") +
- llvm::Twine(EnumName) + llvm::Twine("(StringRef);\n"))
- .str();
-
- EnumHelperFuncs +=
- (llvm::Twine("llvm::StringRef get") + llvm::Twine(DirLang.getName()) +
- llvm::Twine(EnumName) + llvm::Twine("Name(") +
- llvm::Twine(EnumName) + llvm::Twine(");\n"))
- .str();
- }
- }
-}
-
-bool HasDuplicateClauses(const std::vector<Record *> &Clauses,
- const Directive &Directive,
- llvm::StringSet<> &CrtClauses) {
- bool HasError = false;
- for (const auto &C : Clauses) {
- VersionedClause VerClause{C};
- const auto insRes = CrtClauses.insert(VerClause.getClause().getName());
- if (!insRes.second) {
- PrintError("Clause " + VerClause.getClause().getRecordName() +
- " already defined on directive " + Directive.getRecordName());
- HasError = true;
- }
- }
- return HasError;
-}
-
-// Check for duplicate clauses in lists. Clauses cannot appear twice in the
-// three allowed list. Also, since required implies allowed, clauses cannot
-// appear in both the allowedClauses and requiredClauses lists.
-bool HasDuplicateClausesInDirectives(const std::vector<Record *> &Directives) {
- bool HasDuplicate = false;
- for (const auto &D : Directives) {
- Directive Dir{D};
- llvm::StringSet<> Clauses;
- // Check for duplicates in the three allowed lists.
- if (HasDuplicateClauses(Dir.getAllowedClauses(), Dir, Clauses) ||
- HasDuplicateClauses(Dir.getAllowedOnceClauses(), Dir, Clauses) ||
- HasDuplicateClauses(Dir.getAllowedExclusiveClauses(), Dir, Clauses)) {
- HasDuplicate = true;
- }
- // Check for duplicate between allowedClauses and required
- Clauses.clear();
- if (HasDuplicateClauses(Dir.getAllowedClauses(), Dir, Clauses) ||
- HasDuplicateClauses(Dir.getRequiredClauses(), Dir, Clauses)) {
- HasDuplicate = true;
- }
- if (HasDuplicate)
- PrintFatalError("One or more clauses are defined multiple times on"
- " directive " +
- Dir.getRecordName());
- }
-
- return HasDuplicate;
-}
-
-// Check consitency of records. Return true if an error has been detected.
-// Return false if the records are valid.
-bool DirectiveLanguage::HasValidityErrors() const {
- if (getDirectiveLanguages().size() != 1) {
- PrintFatalError("A single definition of DirectiveLanguage is needed.");
- return true;
- }
-
- return HasDuplicateClausesInDirectives(getDirectives());
-}
-
+// Generate enums for values that clauses can take.
+// Also generate function declarations for get<Enum>Name(StringRef Str).
+void GenerateEnumClauseVal(const std::vector<Record *> &Records,
+ raw_ostream &OS, const DirectiveLanguage &DirLang,
+ std::string &EnumHelperFuncs) {
+ for (const auto &R : Records) {
+ Clause C{R};
+ const auto &ClauseVals = C.getClauseVals();
+ if (ClauseVals.size() <= 0)
+ continue;
+
+ const auto &EnumName = C.getEnumName();
+ if (EnumName.size() == 0) {
+ PrintError("enumClauseValue field not set in Clause" +
+ C.getFormattedName() + ".");
+ return;
+ }
+
+ OS << "\n";
+ OS << "enum class " << EnumName << " {\n";
+ for (const auto &CV : ClauseVals) {
+ ClauseVal CVal{CV};
+ OS << " " << CV->getName() << "=" << CVal.getValue() << ",\n";
+ }
+ OS << "};\n";
+
+ if (DirLang.hasMakeEnumAvailableInNamespace()) {
+ OS << "\n";
+ for (const auto &CV : ClauseVals) {
+ OS << "constexpr auto " << CV->getName() << " = "
+ << "llvm::" << DirLang.getCppNamespace() << "::" << EnumName
+ << "::" << CV->getName() << ";\n";
+ }
+ EnumHelperFuncs += (llvm::Twine(EnumName) + llvm::Twine(" get") +
+ llvm::Twine(EnumName) + llvm::Twine("(StringRef);\n"))
+ .str();
+
+ EnumHelperFuncs +=
+ (llvm::Twine("llvm::StringRef get") + llvm::Twine(DirLang.getName()) +
+ llvm::Twine(EnumName) + llvm::Twine("Name(") +
+ llvm::Twine(EnumName) + llvm::Twine(");\n"))
+ .str();
+ }
+ }
+}
+
+bool HasDuplicateClauses(const std::vector<Record *> &Clauses,
+ const Directive &Directive,
+ llvm::StringSet<> &CrtClauses) {
+ bool HasError = false;
+ for (const auto &C : Clauses) {
+ VersionedClause VerClause{C};
+ const auto insRes = CrtClauses.insert(VerClause.getClause().getName());
+ if (!insRes.second) {
+ PrintError("Clause " + VerClause.getClause().getRecordName() +
+ " already defined on directive " + Directive.getRecordName());
+ HasError = true;
+ }
+ }
+ return HasError;
+}
+
+// Check for duplicate clauses in lists. Clauses cannot appear twice in the
+// three allowed list. Also, since required implies allowed, clauses cannot
+// appear in both the allowedClauses and requiredClauses lists.
+bool HasDuplicateClausesInDirectives(const std::vector<Record *> &Directives) {
+ bool HasDuplicate = false;
+ for (const auto &D : Directives) {
+ Directive Dir{D};
+ llvm::StringSet<> Clauses;
+ // Check for duplicates in the three allowed lists.
+ if (HasDuplicateClauses(Dir.getAllowedClauses(), Dir, Clauses) ||
+ HasDuplicateClauses(Dir.getAllowedOnceClauses(), Dir, Clauses) ||
+ HasDuplicateClauses(Dir.getAllowedExclusiveClauses(), Dir, Clauses)) {
+ HasDuplicate = true;
+ }
+ // Check for duplicate between allowedClauses and required
+ Clauses.clear();
+ if (HasDuplicateClauses(Dir.getAllowedClauses(), Dir, Clauses) ||
+ HasDuplicateClauses(Dir.getRequiredClauses(), Dir, Clauses)) {
+ HasDuplicate = true;
+ }
+ if (HasDuplicate)
+ PrintFatalError("One or more clauses are defined multiple times on"
+ " directive " +
+ Dir.getRecordName());
+ }
+
+ return HasDuplicate;
+}
+
+// Check consitency of records. Return true if an error has been detected.
+// Return false if the records are valid.
+bool DirectiveLanguage::HasValidityErrors() const {
+ if (getDirectiveLanguages().size() != 1) {
+ PrintFatalError("A single definition of DirectiveLanguage is needed.");
+ return true;
+ }
+
+ return HasDuplicateClausesInDirectives(getDirectives());
+}
+
// Generate the declaration section for the enumeration in the directive
// language
void EmitDirectivesDecl(RecordKeeper &Records, raw_ostream &OS) {
- const auto DirLang = DirectiveLanguage{Records};
- if (DirLang.HasValidityErrors())
+ const auto DirLang = DirectiveLanguage{Records};
+ if (DirLang.HasValidityErrors())
return;
- OS << "#ifndef LLVM_" << DirLang.getName() << "_INC\n";
- OS << "#define LLVM_" << DirLang.getName() << "_INC\n";
+ OS << "#ifndef LLVM_" << DirLang.getName() << "_INC\n";
+ OS << "#define LLVM_" << DirLang.getName() << "_INC\n";
- if (DirLang.hasEnableBitmaskEnumInNamespace())
+ if (DirLang.hasEnableBitmaskEnumInNamespace())
OS << "\n#include \"llvm/ADT/BitmaskEnum.h\"\n";
OS << "\n";
@@ -192,48 +192,48 @@ void EmitDirectivesDecl(RecordKeeper &Records, raw_ostream &OS) {
// Open namespaces defined in the directive language
llvm::SmallVector<StringRef, 2> Namespaces;
- llvm::SplitString(DirLang.getCppNamespace(), Namespaces, "::");
+ llvm::SplitString(DirLang.getCppNamespace(), Namespaces, "::");
for (auto Ns : Namespaces)
OS << "namespace " << Ns << " {\n";
- if (DirLang.hasEnableBitmaskEnumInNamespace())
+ if (DirLang.hasEnableBitmaskEnumInNamespace())
OS << "\nLLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();\n";
// Emit Directive enumeration
- GenerateEnumClass(DirLang.getDirectives(), OS, "Directive",
- DirLang.getDirectivePrefix(), DirLang);
+ GenerateEnumClass(DirLang.getDirectives(), OS, "Directive",
+ DirLang.getDirectivePrefix(), DirLang);
// Emit Clause enumeration
- GenerateEnumClass(DirLang.getClauses(), OS, "Clause",
- DirLang.getClausePrefix(), DirLang);
+ GenerateEnumClass(DirLang.getClauses(), OS, "Clause",
+ DirLang.getClausePrefix(), DirLang);
+
+ // Emit ClauseVal enumeration
+ std::string EnumHelperFuncs;
+ GenerateEnumClauseVal(DirLang.getClauses(), OS, DirLang, EnumHelperFuncs);
- // Emit ClauseVal enumeration
- std::string EnumHelperFuncs;
- GenerateEnumClauseVal(DirLang.getClauses(), OS, DirLang, EnumHelperFuncs);
-
// Generic function signatures
OS << "\n";
OS << "// Enumeration helper functions\n";
- OS << "Directive get" << DirLang.getName()
+ OS << "Directive get" << DirLang.getName()
<< "DirectiveKind(llvm::StringRef Str);\n";
OS << "\n";
- OS << "llvm::StringRef get" << DirLang.getName()
+ OS << "llvm::StringRef get" << DirLang.getName()
<< "DirectiveName(Directive D);\n";
OS << "\n";
- OS << "Clause get" << DirLang.getName()
- << "ClauseKind(llvm::StringRef Str);\n";
+ OS << "Clause get" << DirLang.getName()
+ << "ClauseKind(llvm::StringRef Str);\n";
OS << "\n";
- OS << "llvm::StringRef get" << DirLang.getName() << "ClauseName(Clause C);\n";
+ OS << "llvm::StringRef get" << DirLang.getName() << "ClauseName(Clause C);\n";
OS << "\n";
OS << "/// Return true if \\p C is a valid clause for \\p D in version \\p "
<< "Version.\n";
OS << "bool isAllowedClauseForDirective(Directive D, "
<< "Clause C, unsigned Version);\n";
OS << "\n";
- if (EnumHelperFuncs.length() > 0) {
- OS << EnumHelperFuncs;
- OS << "\n";
- }
+ if (EnumHelperFuncs.length() > 0) {
+ OS << EnumHelperFuncs;
+ OS << "\n";
+ }
// Closing namespaces
for (auto Ns : llvm::reverse(Namespaces))
@@ -241,183 +241,183 @@ void EmitDirectivesDecl(RecordKeeper &Records, raw_ostream &OS) {
OS << "} // namespace llvm\n";
- OS << "#endif // LLVM_" << DirLang.getName() << "_INC\n";
+ OS << "#endif // LLVM_" << DirLang.getName() << "_INC\n";
}
// Generate function implementation for get<Enum>Name(StringRef Str)
void GenerateGetName(const std::vector<Record *> &Records, raw_ostream &OS,
- StringRef Enum, const DirectiveLanguage &DirLang,
- StringRef Prefix) {
+ StringRef Enum, const DirectiveLanguage &DirLang,
+ StringRef Prefix) {
OS << "\n";
- OS << "llvm::StringRef llvm::" << DirLang.getCppNamespace() << "::get"
- << DirLang.getName() << Enum << "Name(" << Enum << " Kind) {\n";
+ OS << "llvm::StringRef llvm::" << DirLang.getCppNamespace() << "::get"
+ << DirLang.getName() << Enum << "Name(" << Enum << " Kind) {\n";
OS << " switch (Kind) {\n";
for (const auto &R : Records) {
- BaseRecord Rec{R};
- OS << " case " << Prefix << Rec.getFormattedName() << ":\n";
+ BaseRecord Rec{R};
+ OS << " case " << Prefix << Rec.getFormattedName() << ":\n";
OS << " return \"";
- if (Rec.getAlternativeName().empty())
- OS << Rec.getName();
+ if (Rec.getAlternativeName().empty())
+ OS << Rec.getName();
else
- OS << Rec.getAlternativeName();
+ OS << Rec.getAlternativeName();
OS << "\";\n";
}
OS << " }\n"; // switch
- OS << " llvm_unreachable(\"Invalid " << DirLang.getName() << " " << Enum
+ OS << " llvm_unreachable(\"Invalid " << DirLang.getName() << " " << Enum
<< " kind\");\n";
OS << "}\n";
}
// Generate function implementation for get<Enum>Kind(StringRef Str)
void GenerateGetKind(const std::vector<Record *> &Records, raw_ostream &OS,
- StringRef Enum, const DirectiveLanguage &DirLang,
- StringRef Prefix, bool ImplicitAsUnknown) {
+ StringRef Enum, const DirectiveLanguage &DirLang,
+ StringRef Prefix, bool ImplicitAsUnknown) {
- auto DefaultIt = llvm::find_if(
- Records, [](Record *R) { return R->getValueAsBit("isDefault") == true; });
+ auto DefaultIt = llvm::find_if(
+ Records, [](Record *R) { return R->getValueAsBit("isDefault") == true; });
if (DefaultIt == Records.end()) {
- PrintError("At least one " + Enum + " must be defined as default.");
+ PrintError("At least one " + Enum + " must be defined as default.");
return;
}
- BaseRecord DefaultRec{(*DefaultIt)};
+ BaseRecord DefaultRec{(*DefaultIt)};
OS << "\n";
- OS << Enum << " llvm::" << DirLang.getCppNamespace() << "::get"
- << DirLang.getName() << Enum << "Kind(llvm::StringRef Str) {\n";
+ OS << Enum << " llvm::" << DirLang.getCppNamespace() << "::get"
+ << DirLang.getName() << Enum << "Kind(llvm::StringRef Str) {\n";
OS << " return llvm::StringSwitch<" << Enum << ">(Str)\n";
for (const auto &R : Records) {
- BaseRecord Rec{R};
+ BaseRecord Rec{R};
if (ImplicitAsUnknown && R->getValueAsBit("isImplicit")) {
- OS << " .Case(\"" << Rec.getName() << "\"," << Prefix
- << DefaultRec.getFormattedName() << ")\n";
+ OS << " .Case(\"" << Rec.getName() << "\"," << Prefix
+ << DefaultRec.getFormattedName() << ")\n";
} else {
- OS << " .Case(\"" << Rec.getName() << "\"," << Prefix
- << Rec.getFormattedName() << ")\n";
+ OS << " .Case(\"" << Rec.getName() << "\"," << Prefix
+ << Rec.getFormattedName() << ")\n";
}
}
- OS << " .Default(" << Prefix << DefaultRec.getFormattedName() << ");\n";
+ OS << " .Default(" << Prefix << DefaultRec.getFormattedName() << ");\n";
OS << "}\n";
}
-// Generate function implementation for get<ClauseVal>Kind(StringRef Str)
-void GenerateGetKindClauseVal(const DirectiveLanguage &DirLang,
- raw_ostream &OS) {
- for (const auto &R : DirLang.getClauses()) {
- Clause C{R};
- const auto &ClauseVals = C.getClauseVals();
- if (ClauseVals.size() <= 0)
- continue;
-
- auto DefaultIt = llvm::find_if(ClauseVals, [](Record *CV) {
- return CV->getValueAsBit("isDefault") == true;
- });
-
- if (DefaultIt == ClauseVals.end()) {
- PrintError("At least one val in Clause " + C.getFormattedName() +
- " must be defined as default.");
- return;
- }
- const auto DefaultName = (*DefaultIt)->getName();
-
- const auto &EnumName = C.getEnumName();
- if (EnumName.size() == 0) {
- PrintError("enumClauseValue field not set in Clause" +
- C.getFormattedName() + ".");
- return;
- }
-
- OS << "\n";
- OS << EnumName << " llvm::" << DirLang.getCppNamespace() << "::get"
- << EnumName << "(llvm::StringRef Str) {\n";
- OS << " return llvm::StringSwitch<" << EnumName << ">(Str)\n";
- for (const auto &CV : ClauseVals) {
- ClauseVal CVal{CV};
- OS << " .Case(\"" << CVal.getFormattedName() << "\"," << CV->getName()
- << ")\n";
- }
- OS << " .Default(" << DefaultName << ");\n";
- OS << "}\n";
-
- OS << "\n";
- OS << "llvm::StringRef llvm::" << DirLang.getCppNamespace() << "::get"
- << DirLang.getName() << EnumName
- << "Name(llvm::" << DirLang.getCppNamespace() << "::" << EnumName
- << " x) {\n";
- OS << " switch (x) {\n";
- for (const auto &CV : ClauseVals) {
- ClauseVal CVal{CV};
- OS << " case " << CV->getName() << ":\n";
- OS << " return \"" << CVal.getFormattedName() << "\";\n";
- }
- OS << " }\n"; // switch
- OS << " llvm_unreachable(\"Invalid " << DirLang.getName() << " "
- << EnumName << " kind\");\n";
- OS << "}\n";
- }
-}
-
+// Generate function implementation for get<ClauseVal>Kind(StringRef Str)
+void GenerateGetKindClauseVal(const DirectiveLanguage &DirLang,
+ raw_ostream &OS) {
+ for (const auto &R : DirLang.getClauses()) {
+ Clause C{R};
+ const auto &ClauseVals = C.getClauseVals();
+ if (ClauseVals.size() <= 0)
+ continue;
+
+ auto DefaultIt = llvm::find_if(ClauseVals, [](Record *CV) {
+ return CV->getValueAsBit("isDefault") == true;
+ });
+
+ if (DefaultIt == ClauseVals.end()) {
+ PrintError("At least one val in Clause " + C.getFormattedName() +
+ " must be defined as default.");
+ return;
+ }
+ const auto DefaultName = (*DefaultIt)->getName();
+
+ const auto &EnumName = C.getEnumName();
+ if (EnumName.size() == 0) {
+ PrintError("enumClauseValue field not set in Clause" +
+ C.getFormattedName() + ".");
+ return;
+ }
+
+ OS << "\n";
+ OS << EnumName << " llvm::" << DirLang.getCppNamespace() << "::get"
+ << EnumName << "(llvm::StringRef Str) {\n";
+ OS << " return llvm::StringSwitch<" << EnumName << ">(Str)\n";
+ for (const auto &CV : ClauseVals) {
+ ClauseVal CVal{CV};
+ OS << " .Case(\"" << CVal.getFormattedName() << "\"," << CV->getName()
+ << ")\n";
+ }
+ OS << " .Default(" << DefaultName << ");\n";
+ OS << "}\n";
+
+ OS << "\n";
+ OS << "llvm::StringRef llvm::" << DirLang.getCppNamespace() << "::get"
+ << DirLang.getName() << EnumName
+ << "Name(llvm::" << DirLang.getCppNamespace() << "::" << EnumName
+ << " x) {\n";
+ OS << " switch (x) {\n";
+ for (const auto &CV : ClauseVals) {
+ ClauseVal CVal{CV};
+ OS << " case " << CV->getName() << ":\n";
+ OS << " return \"" << CVal.getFormattedName() << "\";\n";
+ }
+ OS << " }\n"; // switch
+ OS << " llvm_unreachable(\"Invalid " << DirLang.getName() << " "
+ << EnumName << " kind\");\n";
+ OS << "}\n";
+ }
+}
+
void GenerateCaseForVersionedClauses(const std::vector<Record *> &Clauses,
raw_ostream &OS, StringRef DirectiveName,
- const DirectiveLanguage &DirLang,
+ const DirectiveLanguage &DirLang,
llvm::StringSet<> &Cases) {
for (const auto &C : Clauses) {
- VersionedClause VerClause{C};
-
- const auto ClauseFormattedName = VerClause.getClause().getFormattedName();
-
- if (Cases.find(ClauseFormattedName) == Cases.end()) {
- Cases.insert(ClauseFormattedName);
- OS << " case " << DirLang.getClausePrefix() << ClauseFormattedName
- << ":\n";
- OS << " return " << VerClause.getMinVersion()
- << " <= Version && " << VerClause.getMaxVersion() << " >= Version;\n";
+ VersionedClause VerClause{C};
+
+ const auto ClauseFormattedName = VerClause.getClause().getFormattedName();
+
+ if (Cases.find(ClauseFormattedName) == Cases.end()) {
+ Cases.insert(ClauseFormattedName);
+ OS << " case " << DirLang.getClausePrefix() << ClauseFormattedName
+ << ":\n";
+ OS << " return " << VerClause.getMinVersion()
+ << " <= Version && " << VerClause.getMaxVersion() << " >= Version;\n";
}
}
}
// Generate the isAllowedClauseForDirective function implementation.
-void GenerateIsAllowedClause(const DirectiveLanguage &DirLang,
- raw_ostream &OS) {
+void GenerateIsAllowedClause(const DirectiveLanguage &DirLang,
+ raw_ostream &OS) {
OS << "\n";
- OS << "bool llvm::" << DirLang.getCppNamespace()
- << "::isAllowedClauseForDirective("
+ OS << "bool llvm::" << DirLang.getCppNamespace()
+ << "::isAllowedClauseForDirective("
<< "Directive D, Clause C, unsigned Version) {\n";
- OS << " assert(unsigned(D) <= llvm::" << DirLang.getCppNamespace()
+ OS << " assert(unsigned(D) <= llvm::" << DirLang.getCppNamespace()
<< "::Directive_enumSize);\n";
- OS << " assert(unsigned(C) <= llvm::" << DirLang.getCppNamespace()
+ OS << " assert(unsigned(C) <= llvm::" << DirLang.getCppNamespace()
<< "::Clause_enumSize);\n";
OS << " switch (D) {\n";
- for (const auto &D : DirLang.getDirectives()) {
- Directive Dir{D};
+ for (const auto &D : DirLang.getDirectives()) {
+ Directive Dir{D};
- OS << " case " << DirLang.getDirectivePrefix() << Dir.getFormattedName()
+ OS << " case " << DirLang.getDirectivePrefix() << Dir.getFormattedName()
<< ":\n";
- if (Dir.getAllowedClauses().size() == 0 &&
- Dir.getAllowedOnceClauses().size() == 0 &&
- Dir.getAllowedExclusiveClauses().size() == 0 &&
- Dir.getRequiredClauses().size() == 0) {
+ if (Dir.getAllowedClauses().size() == 0 &&
+ Dir.getAllowedOnceClauses().size() == 0 &&
+ Dir.getAllowedExclusiveClauses().size() == 0 &&
+ Dir.getRequiredClauses().size() == 0) {
OS << " return false;\n";
} else {
OS << " switch (C) {\n";
llvm::StringSet<> Cases;
- GenerateCaseForVersionedClauses(Dir.getAllowedClauses(), OS,
- Dir.getName(), DirLang, Cases);
+ GenerateCaseForVersionedClauses(Dir.getAllowedClauses(), OS,
+ Dir.getName(), DirLang, Cases);
- GenerateCaseForVersionedClauses(Dir.getAllowedOnceClauses(), OS,
- Dir.getName(), DirLang, Cases);
+ GenerateCaseForVersionedClauses(Dir.getAllowedOnceClauses(), OS,
+ Dir.getName(), DirLang, Cases);
- GenerateCaseForVersionedClauses(Dir.getAllowedExclusiveClauses(), OS,
- Dir.getName(), DirLang, Cases);
+ GenerateCaseForVersionedClauses(Dir.getAllowedExclusiveClauses(), OS,
+ Dir.getName(), DirLang, Cases);
- GenerateCaseForVersionedClauses(Dir.getRequiredClauses(), OS,
- Dir.getName(), DirLang, Cases);
+ GenerateCaseForVersionedClauses(Dir.getRequiredClauses(), OS,
+ Dir.getName(), DirLang, Cases);
OS << " default:\n";
OS << " return false;\n";
@@ -427,32 +427,32 @@ void GenerateIsAllowedClause(const DirectiveLanguage &DirLang,
}
OS << " }\n"; // End of directives switch
- OS << " llvm_unreachable(\"Invalid " << DirLang.getName()
+ OS << " llvm_unreachable(\"Invalid " << DirLang.getName()
<< " Directive kind\");\n";
OS << "}\n"; // End of function isAllowedClauseForDirective
}
// Generate a simple enum set with the give clauses.
void GenerateClauseSet(const std::vector<Record *> &Clauses, raw_ostream &OS,
- StringRef ClauseSetPrefix, Directive &Dir,
- const DirectiveLanguage &DirLang) {
+ StringRef ClauseSetPrefix, Directive &Dir,
+ const DirectiveLanguage &DirLang) {
OS << "\n";
- OS << " static " << DirLang.getClauseEnumSetClass() << " " << ClauseSetPrefix
- << DirLang.getDirectivePrefix() << Dir.getFormattedName() << " {\n";
+ OS << " static " << DirLang.getClauseEnumSetClass() << " " << ClauseSetPrefix
+ << DirLang.getDirectivePrefix() << Dir.getFormattedName() << " {\n";
for (const auto &C : Clauses) {
- VersionedClause VerClause{C};
- OS << " llvm::" << DirLang.getCppNamespace()
- << "::Clause::" << DirLang.getClausePrefix()
- << VerClause.getClause().getFormattedName() << ",\n";
+ VersionedClause VerClause{C};
+ OS << " llvm::" << DirLang.getCppNamespace()
+ << "::Clause::" << DirLang.getClausePrefix()
+ << VerClause.getClause().getFormattedName() << ",\n";
}
OS << " };\n";
}
// Generate an enum set for the 4 kinds of clauses linked to a directive.
-void GenerateDirectiveClauseSets(const DirectiveLanguage &DirLang,
- raw_ostream &OS) {
+void GenerateDirectiveClauseSets(const DirectiveLanguage &DirLang,
+ raw_ostream &OS) {
IfDefScope Scope("GEN_FLANG_DIRECTIVE_CLAUSE_SETS", OS);
@@ -461,24 +461,24 @@ void GenerateDirectiveClauseSets(const DirectiveLanguage &DirLang,
// Open namespaces defined in the directive language.
llvm::SmallVector<StringRef, 2> Namespaces;
- llvm::SplitString(DirLang.getCppNamespace(), Namespaces, "::");
+ llvm::SplitString(DirLang.getCppNamespace(), Namespaces, "::");
for (auto Ns : Namespaces)
OS << "namespace " << Ns << " {\n";
- for (const auto &D : DirLang.getDirectives()) {
- Directive Dir{D};
+ for (const auto &D : DirLang.getDirectives()) {
+ Directive Dir{D};
OS << "\n";
- OS << " // Sets for " << Dir.getName() << "\n";
-
- GenerateClauseSet(Dir.getAllowedClauses(), OS, "allowedClauses_", Dir,
- DirLang);
- GenerateClauseSet(Dir.getAllowedOnceClauses(), OS, "allowedOnceClauses_",
- Dir, DirLang);
- GenerateClauseSet(Dir.getAllowedExclusiveClauses(), OS,
- "allowedExclusiveClauses_", Dir, DirLang);
- GenerateClauseSet(Dir.getRequiredClauses(), OS, "requiredClauses_", Dir,
- DirLang);
+ OS << " // Sets for " << Dir.getName() << "\n";
+
+ GenerateClauseSet(Dir.getAllowedClauses(), OS, "allowedClauses_", Dir,
+ DirLang);
+ GenerateClauseSet(Dir.getAllowedOnceClauses(), OS, "allowedOnceClauses_",
+ Dir, DirLang);
+ GenerateClauseSet(Dir.getAllowedExclusiveClauses(), OS,
+ "allowedExclusiveClauses_", Dir, DirLang);
+ GenerateClauseSet(Dir.getRequiredClauses(), OS, "requiredClauses_", Dir,
+ DirLang);
}
// Closing namespaces
@@ -491,286 +491,286 @@ void GenerateDirectiveClauseSets(const DirectiveLanguage &DirLang,
// Generate a map of directive (key) with DirectiveClauses struct as values.
// The struct holds the 4 sets of enumeration for the 4 kinds of clauses
// allowances (allowed, allowed once, allowed exclusive and required).
-void GenerateDirectiveClauseMap(const DirectiveLanguage &DirLang,
- raw_ostream &OS) {
+void GenerateDirectiveClauseMap(const DirectiveLanguage &DirLang,
+ raw_ostream &OS) {
IfDefScope Scope("GEN_FLANG_DIRECTIVE_CLAUSE_MAP", OS);
OS << "\n";
- OS << "{\n";
+ OS << "{\n";
- for (const auto &D : DirLang.getDirectives()) {
- Directive Dir{D};
- OS << " {llvm::" << DirLang.getCppNamespace()
- << "::Directive::" << DirLang.getDirectivePrefix()
- << Dir.getFormattedName() << ",\n";
+ for (const auto &D : DirLang.getDirectives()) {
+ Directive Dir{D};
+ OS << " {llvm::" << DirLang.getCppNamespace()
+ << "::Directive::" << DirLang.getDirectivePrefix()
+ << Dir.getFormattedName() << ",\n";
OS << " {\n";
- OS << " llvm::" << DirLang.getCppNamespace() << "::allowedClauses_"
- << DirLang.getDirectivePrefix() << Dir.getFormattedName() << ",\n";
- OS << " llvm::" << DirLang.getCppNamespace() << "::allowedOnceClauses_"
- << DirLang.getDirectivePrefix() << Dir.getFormattedName() << ",\n";
- OS << " llvm::" << DirLang.getCppNamespace()
- << "::allowedExclusiveClauses_" << DirLang.getDirectivePrefix()
- << Dir.getFormattedName() << ",\n";
- OS << " llvm::" << DirLang.getCppNamespace() << "::requiredClauses_"
- << DirLang.getDirectivePrefix() << Dir.getFormattedName() << ",\n";
+ OS << " llvm::" << DirLang.getCppNamespace() << "::allowedClauses_"
+ << DirLang.getDirectivePrefix() << Dir.getFormattedName() << ",\n";
+ OS << " llvm::" << DirLang.getCppNamespace() << "::allowedOnceClauses_"
+ << DirLang.getDirectivePrefix() << Dir.getFormattedName() << ",\n";
+ OS << " llvm::" << DirLang.getCppNamespace()
+ << "::allowedExclusiveClauses_" << DirLang.getDirectivePrefix()
+ << Dir.getFormattedName() << ",\n";
+ OS << " llvm::" << DirLang.getCppNamespace() << "::requiredClauses_"
+ << DirLang.getDirectivePrefix() << Dir.getFormattedName() << ",\n";
OS << " }\n";
OS << " },\n";
}
- OS << "}\n";
+ OS << "}\n";
+}
+
+// Generate classes entry for Flang clauses in the Flang parse-tree
+// If the clause as a non-generic class, no entry is generated.
+// If the clause does not hold a value, an EMPTY_CLASS is used.
+// If the clause class is generic then a WRAPPER_CLASS is used. When the value
+// is optional, the value class is wrapped into a std::optional.
+void GenerateFlangClauseParserClass(const DirectiveLanguage &DirLang,
+ raw_ostream &OS) {
+
+ IfDefScope Scope("GEN_FLANG_CLAUSE_PARSER_CLASSES", OS);
+
+ OS << "\n";
+
+ for (const auto &C : DirLang.getClauses()) {
+ Clause Clause{C};
+ if (!Clause.getFlangClass().empty()) {
+ OS << "WRAPPER_CLASS(" << Clause.getFormattedParserClassName() << ", ";
+ if (Clause.isValueOptional() && Clause.isValueList()) {
+ OS << "std::optional<std::list<" << Clause.getFlangClass() << ">>";
+ } else if (Clause.isValueOptional()) {
+ OS << "std::optional<" << Clause.getFlangClass() << ">";
+ } else if (Clause.isValueList()) {
+ OS << "std::list<" << Clause.getFlangClass() << ">";
+ } else {
+ OS << Clause.getFlangClass();
+ }
+ } else {
+ OS << "EMPTY_CLASS(" << Clause.getFormattedParserClassName();
+ }
+ OS << ");\n";
+ }
+}
+
+// Generate a list of the different clause classes for Flang.
+void GenerateFlangClauseParserClassList(const DirectiveLanguage &DirLang,
+ raw_ostream &OS) {
+
+ IfDefScope Scope("GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST", OS);
+
+ OS << "\n";
+ llvm::interleaveComma(DirLang.getClauses(), OS, [&](Record *C) {
+ Clause Clause{C};
+ OS << Clause.getFormattedParserClassName() << "\n";
+ });
}
-// Generate classes entry for Flang clauses in the Flang parse-tree
-// If the clause as a non-generic class, no entry is generated.
-// If the clause does not hold a value, an EMPTY_CLASS is used.
-// If the clause class is generic then a WRAPPER_CLASS is used. When the value
-// is optional, the value class is wrapped into a std::optional.
-void GenerateFlangClauseParserClass(const DirectiveLanguage &DirLang,
- raw_ostream &OS) {
-
- IfDefScope Scope("GEN_FLANG_CLAUSE_PARSER_CLASSES", OS);
-
- OS << "\n";
-
- for (const auto &C : DirLang.getClauses()) {
- Clause Clause{C};
- if (!Clause.getFlangClass().empty()) {
- OS << "WRAPPER_CLASS(" << Clause.getFormattedParserClassName() << ", ";
- if (Clause.isValueOptional() && Clause.isValueList()) {
- OS << "std::optional<std::list<" << Clause.getFlangClass() << ">>";
- } else if (Clause.isValueOptional()) {
- OS << "std::optional<" << Clause.getFlangClass() << ">";
- } else if (Clause.isValueList()) {
- OS << "std::list<" << Clause.getFlangClass() << ">";
- } else {
- OS << Clause.getFlangClass();
- }
- } else {
- OS << "EMPTY_CLASS(" << Clause.getFormattedParserClassName();
- }
- OS << ");\n";
- }
+// Generate dump node list for the clauses holding a generic class name.
+void GenerateFlangClauseDump(const DirectiveLanguage &DirLang,
+ raw_ostream &OS) {
+
+ IfDefScope Scope("GEN_FLANG_DUMP_PARSE_TREE_CLAUSES", OS);
+
+ OS << "\n";
+ for (const auto &C : DirLang.getClauses()) {
+ Clause Clause{C};
+ OS << "NODE(" << DirLang.getFlangClauseBaseClass() << ", "
+ << Clause.getFormattedParserClassName() << ")\n";
+ }
}
-// Generate a list of the different clause classes for Flang.
-void GenerateFlangClauseParserClassList(const DirectiveLanguage &DirLang,
- raw_ostream &OS) {
-
- IfDefScope Scope("GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST", OS);
-
- OS << "\n";
- llvm::interleaveComma(DirLang.getClauses(), OS, [&](Record *C) {
- Clause Clause{C};
- OS << Clause.getFormattedParserClassName() << "\n";
- });
-}
-
-// Generate dump node list for the clauses holding a generic class name.
-void GenerateFlangClauseDump(const DirectiveLanguage &DirLang,
- raw_ostream &OS) {
-
- IfDefScope Scope("GEN_FLANG_DUMP_PARSE_TREE_CLAUSES", OS);
-
- OS << "\n";
- for (const auto &C : DirLang.getClauses()) {
- Clause Clause{C};
- OS << "NODE(" << DirLang.getFlangClauseBaseClass() << ", "
- << Clause.getFormattedParserClassName() << ")\n";
+// Generate Unparse functions for clauses classes in the Flang parse-tree
+// If the clause is a non-generic class, no entry is generated.
+void GenerateFlangClauseUnparse(const DirectiveLanguage &DirLang,
+ raw_ostream &OS) {
+
+ IfDefScope Scope("GEN_FLANG_CLAUSE_UNPARSE", OS);
+
+ OS << "\n";
+
+ for (const auto &C : DirLang.getClauses()) {
+ Clause Clause{C};
+ if (!Clause.getFlangClass().empty()) {
+ if (Clause.isValueOptional() && Clause.getDefaultValue().empty()) {
+ OS << "void Unparse(const " << DirLang.getFlangClauseBaseClass()
+ << "::" << Clause.getFormattedParserClassName() << " &x) {\n";
+ OS << " Word(\"" << Clause.getName().upper() << "\");\n";
+
+ OS << " Walk(\"(\", x.v, \")\");\n";
+ OS << "}\n";
+ } else if (Clause.isValueOptional()) {
+ OS << "void Unparse(const " << DirLang.getFlangClauseBaseClass()
+ << "::" << Clause.getFormattedParserClassName() << " &x) {\n";
+ OS << " Word(\"" << Clause.getName().upper() << "\");\n";
+ OS << " Put(\"(\");\n";
+ OS << " if (x.v.has_value())\n";
+ if (Clause.isValueList())
+ OS << " Walk(x.v, \",\");\n";
+ else
+ OS << " Walk(x.v);\n";
+ OS << " else\n";
+ OS << " Put(\"" << Clause.getDefaultValue() << "\");\n";
+ OS << " Put(\")\");\n";
+ OS << "}\n";
+ } else {
+ OS << "void Unparse(const " << DirLang.getFlangClauseBaseClass()
+ << "::" << Clause.getFormattedParserClassName() << " &x) {\n";
+ OS << " Word(\"" << Clause.getName().upper() << "\");\n";
+ OS << " Put(\"(\");\n";
+ if (Clause.isValueList())
+ OS << " Walk(x.v, \",\");\n";
+ else
+ OS << " Walk(x.v);\n";
+ OS << " Put(\")\");\n";
+ OS << "}\n";
+ }
+ } else {
+ OS << "void Before(const " << DirLang.getFlangClauseBaseClass()
+ << "::" << Clause.getFormattedParserClassName() << " &) { Word(\""
+ << Clause.getName().upper() << "\"); }\n";
+ }
}
-}
-
-// Generate Unparse functions for clauses classes in the Flang parse-tree
-// If the clause is a non-generic class, no entry is generated.
-void GenerateFlangClauseUnparse(const DirectiveLanguage &DirLang,
- raw_ostream &OS) {
-
- IfDefScope Scope("GEN_FLANG_CLAUSE_UNPARSE", OS);
-
- OS << "\n";
-
- for (const auto &C : DirLang.getClauses()) {
- Clause Clause{C};
- if (!Clause.getFlangClass().empty()) {
- if (Clause.isValueOptional() && Clause.getDefaultValue().empty()) {
- OS << "void Unparse(const " << DirLang.getFlangClauseBaseClass()
- << "::" << Clause.getFormattedParserClassName() << " &x) {\n";
- OS << " Word(\"" << Clause.getName().upper() << "\");\n";
-
- OS << " Walk(\"(\", x.v, \")\");\n";
- OS << "}\n";
- } else if (Clause.isValueOptional()) {
- OS << "void Unparse(const " << DirLang.getFlangClauseBaseClass()
- << "::" << Clause.getFormattedParserClassName() << " &x) {\n";
- OS << " Word(\"" << Clause.getName().upper() << "\");\n";
- OS << " Put(\"(\");\n";
- OS << " if (x.v.has_value())\n";
- if (Clause.isValueList())
- OS << " Walk(x.v, \",\");\n";
- else
- OS << " Walk(x.v);\n";
- OS << " else\n";
- OS << " Put(\"" << Clause.getDefaultValue() << "\");\n";
- OS << " Put(\")\");\n";
- OS << "}\n";
- } else {
- OS << "void Unparse(const " << DirLang.getFlangClauseBaseClass()
- << "::" << Clause.getFormattedParserClassName() << " &x) {\n";
- OS << " Word(\"" << Clause.getName().upper() << "\");\n";
- OS << " Put(\"(\");\n";
- if (Clause.isValueList())
- OS << " Walk(x.v, \",\");\n";
- else
- OS << " Walk(x.v);\n";
- OS << " Put(\")\");\n";
- OS << "}\n";
- }
- } else {
- OS << "void Before(const " << DirLang.getFlangClauseBaseClass()
- << "::" << Clause.getFormattedParserClassName() << " &) { Word(\""
- << Clause.getName().upper() << "\"); }\n";
- }
- }
}
-// Generate the implementation section for the enumeration in the directive
-// language
-void EmitDirectivesFlangImpl(const DirectiveLanguage &DirLang,
- raw_ostream &OS) {
-
- GenerateDirectiveClauseSets(DirLang, OS);
-
- GenerateDirectiveClauseMap(DirLang, OS);
-
- GenerateFlangClauseParserClass(DirLang, OS);
-
- GenerateFlangClauseParserClassList(DirLang, OS);
-
- GenerateFlangClauseDump(DirLang, OS);
-
- GenerateFlangClauseUnparse(DirLang, OS);
-}
-
-void GenerateClauseClassMacro(const DirectiveLanguage &DirLang,
- raw_ostream &OS) {
- // Generate macros style information for legacy code in clang
- IfDefScope Scope("GEN_CLANG_CLAUSE_CLASS", OS);
-
- OS << "\n";
-
- OS << "#ifndef CLAUSE\n";
- OS << "#define CLAUSE(Enum, Str, Implicit)\n";
- OS << "#endif\n";
- OS << "#ifndef CLAUSE_CLASS\n";
- OS << "#define CLAUSE_CLASS(Enum, Str, Class)\n";
- OS << "#endif\n";
- OS << "#ifndef CLAUSE_NO_CLASS\n";
- OS << "#define CLAUSE_NO_CLASS(Enum, Str)\n";
- OS << "#endif\n";
- OS << "\n";
- OS << "#define __CLAUSE(Name, Class) \\\n";
- OS << " CLAUSE(" << DirLang.getClausePrefix()
- << "##Name, #Name, /* Implicit */ false) \\\n";
- OS << " CLAUSE_CLASS(" << DirLang.getClausePrefix()
- << "##Name, #Name, Class)\n";
- OS << "#define __CLAUSE_NO_CLASS(Name) \\\n";
- OS << " CLAUSE(" << DirLang.getClausePrefix()
- << "##Name, #Name, /* Implicit */ false) \\\n";
- OS << " CLAUSE_NO_CLASS(" << DirLang.getClausePrefix() << "##Name, #Name)\n";
- OS << "#define __IMPLICIT_CLAUSE_CLASS(Name, Str, Class) \\\n";
- OS << " CLAUSE(" << DirLang.getClausePrefix()
- << "##Name, Str, /* Implicit */ true) \\\n";
- OS << " CLAUSE_CLASS(" << DirLang.getClausePrefix()
- << "##Name, Str, Class)\n";
- OS << "#define __IMPLICIT_CLAUSE_NO_CLASS(Name, Str) \\\n";
- OS << " CLAUSE(" << DirLang.getClausePrefix()
- << "##Name, Str, /* Implicit */ true) \\\n";
- OS << " CLAUSE_NO_CLASS(" << DirLang.getClausePrefix() << "##Name, Str)\n";
- OS << "\n";
-
- for (const auto &R : DirLang.getClauses()) {
- Clause C{R};
- if (C.getClangClass().empty()) { // NO_CLASS
- if (C.isImplicit()) {
- OS << "__IMPLICIT_CLAUSE_NO_CLASS(" << C.getFormattedName() << ", \""
- << C.getFormattedName() << "\")\n";
- } else {
- OS << "__CLAUSE_NO_CLASS(" << C.getFormattedName() << ")\n";
- }
- } else { // CLASS
- if (C.isImplicit()) {
- OS << "__IMPLICIT_CLAUSE_CLASS(" << C.getFormattedName() << ", \""
- << C.getFormattedName() << "\", " << C.getClangClass() << ")\n";
- } else {
- OS << "__CLAUSE(" << C.getFormattedName() << ", " << C.getClangClass()
- << ")\n";
- }
- }
+// Generate the implementation section for the enumeration in the directive
+// language
+void EmitDirectivesFlangImpl(const DirectiveLanguage &DirLang,
+ raw_ostream &OS) {
+
+ GenerateDirectiveClauseSets(DirLang, OS);
+
+ GenerateDirectiveClauseMap(DirLang, OS);
+
+ GenerateFlangClauseParserClass(DirLang, OS);
+
+ GenerateFlangClauseParserClassList(DirLang, OS);
+
+ GenerateFlangClauseDump(DirLang, OS);
+
+ GenerateFlangClauseUnparse(DirLang, OS);
+}
+
+void GenerateClauseClassMacro(const DirectiveLanguage &DirLang,
+ raw_ostream &OS) {
+ // Generate macros style information for legacy code in clang
+ IfDefScope Scope("GEN_CLANG_CLAUSE_CLASS", OS);
+
+ OS << "\n";
+
+ OS << "#ifndef CLAUSE\n";
+ OS << "#define CLAUSE(Enum, Str, Implicit)\n";
+ OS << "#endif\n";
+ OS << "#ifndef CLAUSE_CLASS\n";
+ OS << "#define CLAUSE_CLASS(Enum, Str, Class)\n";
+ OS << "#endif\n";
+ OS << "#ifndef CLAUSE_NO_CLASS\n";
+ OS << "#define CLAUSE_NO_CLASS(Enum, Str)\n";
+ OS << "#endif\n";
+ OS << "\n";
+ OS << "#define __CLAUSE(Name, Class) \\\n";
+ OS << " CLAUSE(" << DirLang.getClausePrefix()
+ << "##Name, #Name, /* Implicit */ false) \\\n";
+ OS << " CLAUSE_CLASS(" << DirLang.getClausePrefix()
+ << "##Name, #Name, Class)\n";
+ OS << "#define __CLAUSE_NO_CLASS(Name) \\\n";
+ OS << " CLAUSE(" << DirLang.getClausePrefix()
+ << "##Name, #Name, /* Implicit */ false) \\\n";
+ OS << " CLAUSE_NO_CLASS(" << DirLang.getClausePrefix() << "##Name, #Name)\n";
+ OS << "#define __IMPLICIT_CLAUSE_CLASS(Name, Str, Class) \\\n";
+ OS << " CLAUSE(" << DirLang.getClausePrefix()
+ << "##Name, Str, /* Implicit */ true) \\\n";
+ OS << " CLAUSE_CLASS(" << DirLang.getClausePrefix()
+ << "##Name, Str, Class)\n";
+ OS << "#define __IMPLICIT_CLAUSE_NO_CLASS(Name, Str) \\\n";
+ OS << " CLAUSE(" << DirLang.getClausePrefix()
+ << "##Name, Str, /* Implicit */ true) \\\n";
+ OS << " CLAUSE_NO_CLASS(" << DirLang.getClausePrefix() << "##Name, Str)\n";
+ OS << "\n";
+
+ for (const auto &R : DirLang.getClauses()) {
+ Clause C{R};
+ if (C.getClangClass().empty()) { // NO_CLASS
+ if (C.isImplicit()) {
+ OS << "__IMPLICIT_CLAUSE_NO_CLASS(" << C.getFormattedName() << ", \""
+ << C.getFormattedName() << "\")\n";
+ } else {
+ OS << "__CLAUSE_NO_CLASS(" << C.getFormattedName() << ")\n";
+ }
+ } else { // CLASS
+ if (C.isImplicit()) {
+ OS << "__IMPLICIT_CLAUSE_CLASS(" << C.getFormattedName() << ", \""
+ << C.getFormattedName() << "\", " << C.getClangClass() << ")\n";
+ } else {
+ OS << "__CLAUSE(" << C.getFormattedName() << ", " << C.getClangClass()
+ << ")\n";
+ }
+ }
}
- OS << "\n";
- OS << "#undef __IMPLICIT_CLAUSE_NO_CLASS\n";
- OS << "#undef __IMPLICIT_CLAUSE_CLASS\n";
- OS << "#undef __CLAUSE\n";
- OS << "#undef CLAUSE_NO_CLASS\n";
- OS << "#undef CLAUSE_CLASS\n";
- OS << "#undef CLAUSE\n";
-}
-
-// Generate the implementation section for the enumeration in the directive
-// language.
-void EmitDirectivesGen(RecordKeeper &Records, raw_ostream &OS) {
- const auto DirLang = DirectiveLanguage{Records};
- if (DirLang.HasValidityErrors())
- return;
-
- EmitDirectivesFlangImpl(DirLang, OS);
-
- GenerateClauseClassMacro(DirLang, OS);
-}
-
-// Generate the implementation for the enumeration in the directive
-// language. This code can be included in library.
-void EmitDirectivesImpl(RecordKeeper &Records, raw_ostream &OS) {
- const auto DirLang = DirectiveLanguage{Records};
- if (DirLang.HasValidityErrors())
- return;
-
- if (!DirLang.getIncludeHeader().empty())
- OS << "#include \"" << DirLang.getIncludeHeader() << "\"\n\n";
-
+ OS << "\n";
+ OS << "#undef __IMPLICIT_CLAUSE_NO_CLASS\n";
+ OS << "#undef __IMPLICIT_CLAUSE_CLASS\n";
+ OS << "#undef __CLAUSE\n";
+ OS << "#undef CLAUSE_NO_CLASS\n";
+ OS << "#undef CLAUSE_CLASS\n";
+ OS << "#undef CLAUSE\n";
+}
+
+// Generate the implementation section for the enumeration in the directive
+// language.
+void EmitDirectivesGen(RecordKeeper &Records, raw_ostream &OS) {
+ const auto DirLang = DirectiveLanguage{Records};
+ if (DirLang.HasValidityErrors())
+ return;
+
+ EmitDirectivesFlangImpl(DirLang, OS);
+
+ GenerateClauseClassMacro(DirLang, OS);
+}
+
+// Generate the implementation for the enumeration in the directive
+// language. This code can be included in library.
+void EmitDirectivesImpl(RecordKeeper &Records, raw_ostream &OS) {
+ const auto DirLang = DirectiveLanguage{Records};
+ if (DirLang.HasValidityErrors())
+ return;
+
+ if (!DirLang.getIncludeHeader().empty())
+ OS << "#include \"" << DirLang.getIncludeHeader() << "\"\n\n";
+
OS << "#include \"llvm/ADT/StringRef.h\"\n";
OS << "#include \"llvm/ADT/StringSwitch.h\"\n";
OS << "#include \"llvm/Support/ErrorHandling.h\"\n";
OS << "\n";
OS << "using namespace llvm;\n";
llvm::SmallVector<StringRef, 2> Namespaces;
- llvm::SplitString(DirLang.getCppNamespace(), Namespaces, "::");
+ llvm::SplitString(DirLang.getCppNamespace(), Namespaces, "::");
for (auto Ns : Namespaces)
OS << "using namespace " << Ns << ";\n";
// getDirectiveKind(StringRef Str)
- GenerateGetKind(DirLang.getDirectives(), OS, "Directive", DirLang,
- DirLang.getDirectivePrefix(), /*ImplicitAsUnknown=*/false);
+ GenerateGetKind(DirLang.getDirectives(), OS, "Directive", DirLang,
+ DirLang.getDirectivePrefix(), /*ImplicitAsUnknown=*/false);
// getDirectiveName(Directive Kind)
- GenerateGetName(DirLang.getDirectives(), OS, "Directive", DirLang,
- DirLang.getDirectivePrefix());
+ GenerateGetName(DirLang.getDirectives(), OS, "Directive", DirLang,
+ DirLang.getDirectivePrefix());
// getClauseKind(StringRef Str)
- GenerateGetKind(DirLang.getClauses(), OS, "Clause", DirLang,
- DirLang.getClausePrefix(),
- /*ImplicitAsUnknown=*/true);
+ GenerateGetKind(DirLang.getClauses(), OS, "Clause", DirLang,
+ DirLang.getClausePrefix(),
+ /*ImplicitAsUnknown=*/true);
// getClauseName(Clause Kind)
- GenerateGetName(DirLang.getClauses(), OS, "Clause", DirLang,
- DirLang.getClausePrefix());
+ GenerateGetName(DirLang.getClauses(), OS, "Clause", DirLang,
+ DirLang.getClausePrefix());
+
+ // get<ClauseVal>Kind(StringRef Str)
+ GenerateGetKindClauseVal(DirLang, OS);
- // get<ClauseVal>Kind(StringRef Str)
- GenerateGetKindClauseVal(DirLang, OS);
-
// isAllowedClauseForDirective(Directive D, Clause C, unsigned Version)
- GenerateIsAllowedClause(DirLang, OS);
+ GenerateIsAllowedClause(DirLang, OS);
}
} // namespace llvm
diff --git a/contrib/libs/llvm12/utils/TableGen/ExegesisEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/ExegesisEmitter.cpp
index 452b4e36b1..4e532c3716 100644
--- a/contrib/libs/llvm12/utils/TableGen/ExegesisEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/ExegesisEmitter.cpp
@@ -144,7 +144,7 @@ void ExegesisEmitter::emitPfmCountersInfo(const Record &Def,
void ExegesisEmitter::emitPfmCounters(raw_ostream &OS) const {
// Emit the counter name table.
- OS << "\nstatic const char *" << Target << "PfmCounterNames[] = {\n";
+ OS << "\nstatic const char *" << Target << "PfmCounterNames[] = {\n";
for (const auto &NameAndIndex : PfmCounterNameTable)
OS << " \"" << NameAndIndex.first << "\", // " << NameAndIndex.second
<< "\n";
diff --git a/contrib/libs/llvm12/utils/TableGen/FixedLenDecoderEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/FixedLenDecoderEmitter.cpp
index 4ed833866d..01b39df055 100644
--- a/contrib/libs/llvm12/utils/TableGen/FixedLenDecoderEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/FixedLenDecoderEmitter.cpp
@@ -226,8 +226,8 @@ typedef std::vector<bit_value_t> insn_t;
namespace {
-static const uint64_t NO_FIXED_SEGMENTS_SENTINEL = -1ULL;
-
+static const uint64_t NO_FIXED_SEGMENTS_SENTINEL = -1ULL;
+
class FilterChooser;
/// Filter - Filter works with FilterChooser to produce the decoding tree for
@@ -281,7 +281,7 @@ protected:
std::vector<EncodingIDAndOpcode> VariableInstructions;
// Map of well-known segment value to its delegate.
- std::map<uint64_t, std::unique_ptr<const FilterChooser>> FilterChooserMap;
+ std::map<uint64_t, std::unique_ptr<const FilterChooser>> FilterChooserMap;
// Number of instructions which fall under FilteredInstructions category.
unsigned NumFiltered;
@@ -307,7 +307,7 @@ public:
const FilterChooser &getVariableFC() const {
assert(NumFiltered == 1);
assert(FilterChooserMap.size() == 1);
- return *(FilterChooserMap.find(NO_FIXED_SEGMENTS_SENTINEL)->second);
+ return *(FilterChooserMap.find(NO_FIXED_SEGMENTS_SENTINEL)->second);
}
// Divides the decoding task into sub tasks and delegates them to the
@@ -604,9 +604,9 @@ void Filter::recurse() {
// Delegates to an inferior filter chooser for further processing on this
// group of instructions whose segment values are variable.
- FilterChooserMap.insert(std::make_pair(NO_FIXED_SEGMENTS_SENTINEL,
- std::make_unique<FilterChooser>(Owner->AllInstructions,
- VariableInstructions, Owner->Operands, BitValueArray, *Owner)));
+ FilterChooserMap.insert(std::make_pair(NO_FIXED_SEGMENTS_SENTINEL,
+ std::make_unique<FilterChooser>(Owner->AllInstructions,
+ VariableInstructions, Owner->Operands, BitValueArray, *Owner)));
}
// No need to recurse for a singleton filtered instruction.
@@ -675,7 +675,7 @@ void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
for (auto &Filter : FilterChooserMap) {
// Field value -1 implies a non-empty set of variable instructions.
// See also recurse().
- if (Filter.first == NO_FIXED_SEGMENTS_SENTINEL) {
+ if (Filter.first == NO_FIXED_SEGMENTS_SENTINEL) {
HasFallthrough = true;
// Each scope should always have at least one filter value to check
@@ -722,7 +722,7 @@ void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
assert(TableInfo.FixupStack.size() > 1 && "fixup stack underflow!");
FixupScopeList::iterator Source = TableInfo.FixupStack.end() - 1;
FixupScopeList::iterator Dest = Source - 1;
- llvm::append_range(*Dest, *Source);
+ llvm::append_range(*Dest, *Source);
TableInfo.FixupStack.pop_back();
// If there is no fallthrough, then the final filter should get fixed
@@ -942,7 +942,7 @@ emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates,
// The predicate function is just a big switch statement based on the
// input predicate index.
OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, "
- << "const FeatureBitset &Bits) {\n";
+ << "const FeatureBitset &Bits) {\n";
Indentation += 2;
if (!Predicates.empty()) {
OS.indent(Indentation) << "switch (Idx) {\n";
@@ -966,7 +966,7 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders,
unsigned Indentation) const {
// The decoder function is just a big switch statement based on the
// input decoder index.
- OS.indent(Indentation) << "template <typename InsnType>\n";
+ OS.indent(Indentation) << "template <typename InsnType>\n";
OS.indent(Indentation) << "static DecodeStatus decodeToMCInst(DecodeStatus S,"
<< " unsigned Idx, InsnType insn, MCInst &MI,\n";
OS.indent(Indentation) << " uint64_t "
@@ -1193,7 +1193,7 @@ bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
if (!Pred->getValue("AssemblerMatcherPredicate"))
continue;
- if (!isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
+ if (!isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
continue;
const DagInit *D = Pred->getValueAsDag("AssemblerCondDag");
@@ -1887,7 +1887,7 @@ populateInstruction(CodeGenTarget &Target, const Record &EncodingDef,
for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
// Ignore fixed fields in the record, we're looking for values like:
// bits<5> RST = { ?, ?, ?, ?, ? };
- if (Vals[i].isNonconcreteOK() || Vals[i].getValue()->isComplete())
+ if (Vals[i].isNonconcreteOK() || Vals[i].getValue()->isComplete())
continue;
// Determine if Vals[i] actually contributes to the Inst encoding.
@@ -2010,8 +2010,8 @@ populateInstruction(CodeGenTarget &Target, const Record &EncodingDef,
// For each operand, see if we can figure out where it is encoded.
for (const auto &Op : InOutOperands) {
if (!NumberedInsnOperands[std::string(Op.second)].empty()) {
- llvm::append_range(InsnOperands,
- NumberedInsnOperands[std::string(Op.second)]);
+ llvm::append_range(InsnOperands,
+ NumberedInsnOperands[std::string(Op.second)]);
continue;
}
if (!NumberedInsnOperands[TiedNames[std::string(Op.second)]].empty()) {
@@ -2162,7 +2162,7 @@ static void emitFieldFromInstruction(formatted_raw_ostream &OS) {
<< "// * Support shift (<<, >>) with signed and unsigned integers on the "
"RHS\n"
<< "// * Support put (<<) to raw_ostream&\n"
- << "template <typename InsnType>\n"
+ << "template <typename InsnType>\n"
<< "#if defined(_MSC_VER) && !defined(__clang__)\n"
<< "__declspec(noinline)\n"
<< "#endif\n"
@@ -2182,7 +2182,7 @@ static void emitFieldFromInstruction(formatted_raw_ostream &OS) {
<< " return (insn & fieldMask) >> startBit;\n"
<< "}\n"
<< "\n"
- << "template <typename InsnType>\n"
+ << "template <typename InsnType>\n"
<< "static InsnType fieldFromInstruction(InsnType insn, unsigned "
"startBit,\n"
<< " unsigned numBits, "
@@ -2193,7 +2193,7 @@ static void emitFieldFromInstruction(formatted_raw_ostream &OS) {
<< " return (insn >> startBit) & fieldMask;\n"
<< "}\n"
<< "\n"
- << "template <typename InsnType>\n"
+ << "template <typename InsnType>\n"
<< "static InsnType fieldFromInstruction(InsnType insn, unsigned "
"startBit,\n"
<< " unsigned numBits) {\n"
@@ -2205,14 +2205,14 @@ static void emitFieldFromInstruction(formatted_raw_ostream &OS) {
// emitDecodeInstruction - Emit the templated helper function
// decodeInstruction().
static void emitDecodeInstruction(formatted_raw_ostream &OS) {
- OS << "template <typename InsnType>\n"
+ OS << "template <typename InsnType>\n"
<< "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], "
"MCInst &MI,\n"
<< " InsnType insn, uint64_t "
"Address,\n"
<< " const void *DisAsm,\n"
<< " const MCSubtargetInfo &STI) {\n"
- << " const FeatureBitset &Bits = STI.getFeatureBits();\n"
+ << " const FeatureBitset &Bits = STI.getFeatureBits();\n"
<< "\n"
<< " const uint8_t *Ptr = DecodeTable;\n"
<< " InsnType CurFieldValue = 0;\n"
@@ -2374,7 +2374,7 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) {
<< " if (Fail)\n"
<< " S = MCDisassembler::SoftFail;\n"
<< " LLVM_DEBUG(dbgs() << Loc << \": OPC_SoftFail: \" << (Fail ? "
- "\"FAIL\\n\" : \"PASS\\n\"));\n"
+ "\"FAIL\\n\" : \"PASS\\n\"));\n"
<< " break;\n"
<< " }\n"
<< " case MCD::OPC_Fail: {\n"
@@ -2392,7 +2392,7 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) {
void FixedLenDecoderEmitter::run(raw_ostream &o) {
formatted_raw_ostream OS(o);
OS << "#include \"llvm/MC/MCInst.h\"\n";
- OS << "#include \"llvm/Support/DataTypes.h\"\n";
+ OS << "#include \"llvm/Support/DataTypes.h\"\n";
OS << "#include \"llvm/Support/Debug.h\"\n";
OS << "#include \"llvm/Support/LEB128.h\"\n";
OS << "#include \"llvm/Support/raw_ostream.h\"\n";
diff --git a/contrib/libs/llvm12/utils/TableGen/GICombinerEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/GICombinerEmitter.cpp
index 9390a062ba..ab00cff639 100644
--- a/contrib/libs/llvm12/utils/TableGen/GICombinerEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/GICombinerEmitter.cpp
@@ -150,7 +150,7 @@ protected:
/// A block of arbitrary C++ to finish testing the match.
/// FIXME: This is a temporary measure until we have actual pattern matching
- const StringInit *MatchingFixupCode = nullptr;
+ const StringInit *MatchingFixupCode = nullptr;
/// The MatchData defined by the match stage and required by the apply stage.
/// This allows the plumbing of arbitrary data from C++ predicates between the
@@ -199,7 +199,7 @@ public:
unsigned allocUID() { return UID++; }
StringRef getName() const { return TheDef.getName(); }
const Record &getDef() const { return TheDef; }
- const StringInit *getMatchingFixupCode() const { return MatchingFixupCode; }
+ const StringInit *getMatchingFixupCode() const { return MatchingFixupCode; }
size_t getNumRoots() const { return Roots.size(); }
GIMatchDag &getMatchDag() { return MatchDag; }
@@ -432,9 +432,9 @@ bool CombineRule::parseInstructionMatcher(
}
if (InstrOperand.isDef()) {
- if (any_of(Roots, [&](const RootInfo &X) {
+ if (any_of(Roots, [&](const RootInfo &X) {
return X.getPatternSymbol() == Name;
- })) {
+ })) {
N->setMatchRoot();
}
}
@@ -460,9 +460,9 @@ bool CombineRule::parseWipMatchOpcodeMatcher(const CodeGenTarget &Target,
MatchDag.addInstrNode(makeDebugName(*this, Name), insertStrTab(Name),
MatchDag.getContext().makeEmptyOperandList());
- if (any_of(Roots, [&](const RootInfo &X) {
+ if (any_of(Roots, [&](const RootInfo &X) {
return ArgName && X.getPatternSymbol() == ArgName->getValue();
- })) {
+ })) {
N->setMatchRoot();
}
@@ -514,10 +514,10 @@ bool CombineRule::parseMatcher(const CodeGenTarget &Target) {
// Parse arbitrary C++ code we have in lieu of supporting MIR matching
- if (const StringInit *StringI = dyn_cast<StringInit>(Matchers->getArg(I))) {
+ if (const StringInit *StringI = dyn_cast<StringInit>(Matchers->getArg(I))) {
assert(!MatchingFixupCode &&
"Only one block of arbitrary code is currently permitted");
- MatchingFixupCode = StringI;
+ MatchingFixupCode = StringI;
MatchDag.setHasPostMatchPredicate(true);
continue;
}
@@ -589,7 +589,7 @@ bool CombineRule::parseMatcher(const CodeGenTarget &Target) {
}
class GICombinerEmitter {
- RecordKeeper &Records;
+ RecordKeeper &Records;
StringRef Name;
const CodeGenTarget &Target;
Record *Combiner;
@@ -622,7 +622,7 @@ public:
GICombinerEmitter::GICombinerEmitter(RecordKeeper &RK,
const CodeGenTarget &Target,
StringRef Name, Record *Combiner)
- : Records(RK), Name(Name), Target(Target), Combiner(Combiner) {}
+ : Records(RK), Name(Name), Target(Target), Combiner(Combiner) {}
void GICombinerEmitter::emitNameMatcher(raw_ostream &OS) const {
std::vector<std::pair<std::string, std::string>> Cases;
@@ -758,7 +758,7 @@ void GICombinerEmitter::generateCodeForTree(raw_ostream &OS,
DagInit *Applyer = RuleDef.getValueAsDag("Apply");
if (Applyer->getOperatorAsDef(RuleDef.getLoc())->getName() !=
"apply") {
- PrintError(RuleDef.getLoc(), "Expected 'apply' operator in Apply DAG");
+ PrintError(RuleDef.getLoc(), "Expected 'apply' operator in Apply DAG");
return;
}
@@ -799,16 +799,16 @@ void GICombinerEmitter::generateCodeForTree(raw_ostream &OS,
OS << Indent << " && [&]() {\n"
<< Indent << " "
<< CodeExpander(Rule->getMatchingFixupCode()->getValue(), Expansions,
- RuleDef.getLoc(), ShowExpansions)
+ RuleDef.getLoc(), ShowExpansions)
<< "\n"
<< Indent << " return true;\n"
<< Indent << " }()";
}
OS << ") {\n" << Indent << " ";
- if (const StringInit *Code = dyn_cast<StringInit>(Applyer->getArg(0))) {
+ if (const StringInit *Code = dyn_cast<StringInit>(Applyer->getArg(0))) {
OS << CodeExpander(Code->getAsUnquotedString(), Expansions,
- RuleDef.getLoc(), ShowExpansions)
+ RuleDef.getLoc(), ShowExpansions)
<< "\n"
<< Indent << " return true;\n"
<< Indent << " }\n";
@@ -846,7 +846,7 @@ static void emitAdditionalHelperMethodArguments(raw_ostream &OS,
}
void GICombinerEmitter::run(raw_ostream &OS) {
- Records.startTimer("Gather rules");
+ Records.startTimer("Gather rules");
gatherRules(Rules, Combiner->getValueAsListOfDefs("Rules"));
if (StopAfterParse) {
MatchDagCtx.print(errs());
@@ -858,7 +858,7 @@ void GICombinerEmitter::run(raw_ostream &OS) {
PrintFatalError(Combiner->getLoc(), "Failed to parse one or more rules");
LLVM_DEBUG(dbgs() << "Optimizing tree for " << Rules.size() << " rules\n");
std::unique_ptr<GIMatchTree> Tree;
- Records.startTimer("Optimize combiner");
+ Records.startTimer("Optimize combiner");
{
GIMatchTreeBuilder TreeBuilder(0);
for (const auto &Rule : Rules) {
@@ -881,7 +881,7 @@ void GICombinerEmitter::run(raw_ostream &OS) {
return;
}
- Records.startTimer("Emit combiner");
+ Records.startTimer("Emit combiner");
OS << "#ifdef " << Name.upper() << "_GENCOMBINERHELPER_DEPS\n"
<< "#include \"llvm/ADT/SparseBitVector.h\"\n"
<< "namespace llvm {\n"
@@ -905,10 +905,10 @@ void GICombinerEmitter::run(raw_ostream &OS) {
if (!StateClass.empty())
OS << " : public " << StateClass;
OS << " {\n"
- << " const " << getClassName() << "RuleConfig *RuleConfig;\n"
+ << " const " << getClassName() << "RuleConfig *RuleConfig;\n"
<< "\n"
<< "public:\n"
- << " template <typename... Args>" << getClassName() << "(const "
+ << " template <typename... Args>" << getClassName() << "(const "
<< getClassName() << "RuleConfig &RuleConfig, Args &&... args) : ";
if (!StateClass.empty())
OS << StateClass << "(std::forward<Args>(args)...), ";
@@ -938,9 +938,9 @@ void GICombinerEmitter::run(raw_ostream &OS) {
<< " if (First >= Last)\n"
<< " report_fatal_error(\"Beginning of range should be before "
"end of range\");\n"
- << " return {{*First, *Last + 1}};\n"
+ << " return {{*First, *Last + 1}};\n"
<< " } else if (RangePair.first == \"*\") {\n"
- << " return {{0, " << Rules.size() << "}};\n"
+ << " return {{0, " << Rules.size() << "}};\n"
<< " } else {\n"
<< " const auto I = getRuleIdxForIdentifier(RangePair.first);\n"
<< " if (!I.hasValue())\n"
@@ -954,7 +954,7 @@ void GICombinerEmitter::run(raw_ostream &OS) {
OS << "bool " << getClassName() << "RuleConfig::setRule"
<< (Enabled ? "Enabled" : "Disabled") << "(StringRef RuleIdentifier) {\n"
<< " auto MaybeRange = getRuleRangeForIdentifier(RuleIdentifier);\n"
- << " if (!MaybeRange.hasValue())\n"
+ << " if (!MaybeRange.hasValue())\n"
<< " return false;\n"
<< " for (auto I = MaybeRange->first; I < MaybeRange->second; ++I)\n"
<< " DisabledRules." << (Enabled ? "reset" : "set") << "(I);\n"
@@ -1017,7 +1017,7 @@ void GICombinerEmitter::run(raw_ostream &OS) {
<< " MachineBasicBlock *MBB = MI.getParent();\n"
<< " MachineFunction *MF = MBB->getParent();\n"
<< " MachineRegisterInfo &MRI = MF->getRegInfo();\n"
- << " SmallVector<MachineInstr *, 8> MIs = {&MI};\n\n"
+ << " SmallVector<MachineInstr *, 8> MIs = {&MI};\n\n"
<< " (void)MBB; (void)MF; (void)MRI; (void)RuleConfig;\n\n";
OS << " // Match data\n";
diff --git a/contrib/libs/llvm12/utils/TableGen/GlobalISel/CodeExpander.cpp b/contrib/libs/llvm12/utils/TableGen/GlobalISel/CodeExpander.cpp
index 43efd58f02..3ebb293f46 100644
--- a/contrib/libs/llvm12/utils/TableGen/GlobalISel/CodeExpander.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/GlobalISel/CodeExpander.cpp
@@ -58,15 +58,15 @@ void CodeExpander::emit(raw_ostream &OS) const {
// Warn if we split because no terminator was found.
StringRef EndVar = StartVar.drop_front(2 /* ${ */ + Var.size());
if (EndVar.empty()) {
- PrintWarning(Loc, "Unterminated expansion '${" + Var + "'");
- PrintNote("Code: [{" + Code + "}]");
+ PrintWarning(Loc, "Unterminated expansion '${" + Var + "'");
+ PrintNote("Code: [{" + Code + "}]");
}
auto ValueI = Expansions.find(Var);
if (ValueI == Expansions.end()) {
- PrintError(Loc,
- "Attempt to expand an undeclared variable '" + Var + "'");
- PrintNote("Code: [{" + Code + "}]");
+ PrintError(Loc,
+ "Attempt to expand an undeclared variable '" + Var + "'");
+ PrintNote("Code: [{" + Code + "}]");
}
if (ShowExpansions)
OS << "/*$" << Var << "{*/";
@@ -76,8 +76,8 @@ void CodeExpander::emit(raw_ostream &OS) const {
continue;
}
- PrintWarning(Loc, "Assuming missing escape character: \\$");
- PrintNote("Code: [{" + Code + "}]");
+ PrintWarning(Loc, "Assuming missing escape character: \\$");
+ PrintNote("Code: [{" + Code + "}]");
OS << "$";
Current = Current.drop_front(1);
}
diff --git a/contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchDag.cpp b/contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchDag.cpp
index 1a4bd0a7b5..7e037dd03b 100644
--- a/contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchDag.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchDag.cpp
@@ -41,7 +41,7 @@ void GIMatchDag::writeDOTGraph(raw_ostream &OS, StringRef ID) const {
SmallVector<std::pair<unsigned, StringRef>, 8> ToPrint;
for (const auto &Assignment : N->user_assigned_operand_names())
ToPrint.emplace_back(Assignment.first, Assignment.second);
- llvm::sort(ToPrint);
+ llvm::sort(ToPrint);
StringRef Separator = "";
for (const auto &Assignment : ToPrint) {
OS << Separator << "$" << Assignment.second << "=getOperand("
diff --git a/contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchDagInstr.cpp b/contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchDagInstr.cpp
index 250d35733d..ad9fbea8f8 100644
--- a/contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchDagInstr.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchDagInstr.cpp
@@ -27,7 +27,7 @@ void GIMatchDagInstr::print(raw_ostream &OS) const {
SmallVector<std::pair<unsigned, StringRef>, 8> ToPrint;
for (const auto &Assignment : UserAssignedNamesForOperands)
ToPrint.emplace_back(Assignment.first, Assignment.second);
- llvm::sort(ToPrint);
+ llvm::sort(ToPrint);
StringRef Separator = "";
for (const auto &Assignment : ToPrint) {
OS << Separator << "$" << Assignment.second << "=getOperand("
diff --git a/contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchTree.cpp b/contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchTree.cpp
index 1991ca5b20..d08a83333c 100644
--- a/contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchTree.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchTree.cpp
@@ -121,7 +121,7 @@ void GIMatchTreeBuilderLeafInfo::declareInstr(const GIMatchDagInstr *Instr, unsi
Info.bindOperandVariable(VarBinding.second, ID, VarBinding.first);
// Clear the bit indicating we haven't visited this instr.
- const auto &NodeI = find(MatchDag.instr_nodes(), Instr);
+ const auto &NodeI = find(MatchDag.instr_nodes(), Instr);
assert(NodeI != MatchDag.instr_nodes_end() && "Instr isn't in this DAG");
unsigned InstrIdx = MatchDag.getInstrNodeIdx(NodeI);
RemainingInstrNodes.reset(InstrIdx);
@@ -265,10 +265,10 @@ void GIMatchTreeBuilder::runStep() {
LLVM_DEBUG(dbgs() << "Leaf contains multiple rules, drop after the first "
"fully tested rule\n");
auto FirstFullyTested =
- llvm::find_if(Leaves, [](const GIMatchTreeBuilderLeafInfo &X) {
- return X.isFullyTraversed() && X.isFullyTested() &&
- !X.getMatchDag().hasPostMatchPredicate();
- });
+ llvm::find_if(Leaves, [](const GIMatchTreeBuilderLeafInfo &X) {
+ return X.isFullyTraversed() && X.isFullyTested() &&
+ !X.getMatchDag().hasPostMatchPredicate();
+ });
if (FirstFullyTested != Leaves.end())
FirstFullyTested++;
@@ -454,7 +454,7 @@ void GIMatchTreeOpcodePartitioner::repartition(
// predicates for one instruction in the same DAG. That should be
// impossible.
assert(AllOpcodes && "Conflicting opcode predicates");
- append_range(OpcodesForThisPredicate, OpcodeP->getInstrs());
+ append_range(OpcodesForThisPredicate, OpcodeP->getInstrs());
}
for (const CodeGenInstruction *Expected : OpcodesForThisPredicate) {
diff --git a/contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchTree.h b/contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchTree.h
index 4de73e37e6..bf41a2e0e2 100644
--- a/contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchTree.h
+++ b/contrib/libs/llvm12/utils/TableGen/GlobalISel/GIMatchTree.h
@@ -353,7 +353,7 @@ public:
void declareOperand(unsigned InstrID, unsigned OpIdx);
GIMatchTreeInstrInfo *getInstrInfo(unsigned ID) const {
- return InstrIDToInfo.lookup(ID);
+ return InstrIDToInfo.lookup(ID);
}
void dump(raw_ostream &OS) const {
diff --git a/contrib/libs/llvm12/utils/TableGen/GlobalISel/ya.make b/contrib/libs/llvm12/utils/TableGen/GlobalISel/ya.make
index 803b878bc4..4a072b7300 100644
--- a/contrib/libs/llvm12/utils/TableGen/GlobalISel/ya.make
+++ b/contrib/libs/llvm12/utils/TableGen/GlobalISel/ya.make
@@ -12,7 +12,7 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
+ contrib/libs/llvm12
)
ADDINCL(
diff --git a/contrib/libs/llvm12/utils/TableGen/GlobalISelEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/GlobalISelEmitter.cpp
index f99d7d9f4c..0a6985a3ea 100644
--- a/contrib/libs/llvm12/utils/TableGen/GlobalISelEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/GlobalISelEmitter.cpp
@@ -187,21 +187,21 @@ class InstructionMatcher;
static Optional<LLTCodeGen> MVTToLLT(MVT::SimpleValueType SVT) {
MVT VT(SVT);
- if (VT.isScalableVector())
- return None;
-
- if (VT.isFixedLengthVector() && VT.getVectorNumElements() != 1)
+ if (VT.isScalableVector())
+ return None;
+
+ if (VT.isFixedLengthVector() && VT.getVectorNumElements() != 1)
return LLTCodeGen(
LLT::vector(VT.getVectorNumElements(), VT.getScalarSizeInBits()));
if (VT.isInteger() || VT.isFloatingPoint())
return LLTCodeGen(LLT::scalar(VT.getSizeInBits()));
-
+
return None;
}
static std::string explainPredicates(const TreePatternNode *N) {
- std::string Explanation;
+ std::string Explanation;
StringRef Separator = "";
for (const TreePredicateCall &Call : N->getPredicateCalls()) {
const TreePredicateFn &P = Call.Fn;
@@ -305,8 +305,8 @@ static Error failedImport(const Twine &Reason) {
}
static Error isTrivialOperatorNode(const TreePatternNode *N) {
- std::string Explanation;
- std::string Separator;
+ std::string Explanation;
+ std::string Separator;
bool HasUnsupportedPredicate = false;
for (const TreePredicateCall &Call : N->getPredicateCalls()) {
@@ -393,10 +393,10 @@ getNameForFeatureBitset(const std::vector<Record *> &FeatureBitset) {
return Name;
}
-static std::string getScopedName(unsigned Scope, const std::string &Name) {
- return ("pred:" + Twine(Scope) + ":" + Name).str();
-}
-
+static std::string getScopedName(unsigned Scope, const std::string &Name) {
+ return ("pred:" + Twine(Scope) + ":" + Name).str();
+}
+
//===- MatchTable Helpers -------------------------------------------------===//
class MatchTable;
@@ -453,8 +453,8 @@ public:
MatchTableRecord(Optional<unsigned> LabelID_, StringRef EmitStr,
unsigned NumElements, unsigned Flags,
int64_t RawValue = std::numeric_limits<int64_t>::min())
- : LabelID(LabelID_.getValueOr(~0u)), EmitStr(EmitStr),
- NumElements(NumElements), Flags(Flags), RawValue(RawValue) {
+ : LabelID(LabelID_.getValueOr(~0u)), EmitStr(EmitStr),
+ NumElements(NumElements), Flags(Flags), RawValue(RawValue) {
assert((!LabelID_.hasValue() || LabelID != ~0u) &&
"This value is reserved for non-labels");
}
@@ -859,11 +859,11 @@ protected:
DefinedComplexPatternSubOperandMap;
/// A map of Symbolic Names to ComplexPattern sub-operands.
DefinedComplexPatternSubOperandMap ComplexSubOperands;
- /// A map used to for multiple referenced error check of ComplexSubOperand.
- /// ComplexSubOperand can't be referenced multiple from different operands,
- /// however multiple references from same operand are allowed since that is
- /// how 'same operand checks' are generated.
- StringMap<std::string> ComplexSubOperandsParentName;
+ /// A map used to for multiple referenced error check of ComplexSubOperand.
+ /// ComplexSubOperand can't be referenced multiple from different operands,
+ /// however multiple references from same operand are allowed since that is
+ /// how 'same operand checks' are generated.
+ StringMap<std::string> ComplexSubOperandsParentName;
uint64_t RuleID;
static uint64_t NextRuleID;
@@ -929,25 +929,25 @@ public:
void definePhysRegOperand(Record *Reg, OperandMatcher &OM);
Error defineComplexSubOperand(StringRef SymbolicName, Record *ComplexPattern,
- unsigned RendererID, unsigned SubOperandID,
- StringRef ParentSymbolicName) {
- std::string ParentName(ParentSymbolicName);
- if (ComplexSubOperands.count(SymbolicName)) {
- const std::string &RecordedParentName =
- ComplexSubOperandsParentName[SymbolicName];
- if (RecordedParentName != ParentName)
- return failedImport("Error: Complex suboperand " + SymbolicName +
- " referenced by different operands: " +
- RecordedParentName + " and " + ParentName + ".");
- // Complex suboperand referenced more than once from same the operand is
- // used to generate 'same operand check'. Emitting of
- // GIR_ComplexSubOperandRenderer for them is already handled.
- return Error::success();
- }
+ unsigned RendererID, unsigned SubOperandID,
+ StringRef ParentSymbolicName) {
+ std::string ParentName(ParentSymbolicName);
+ if (ComplexSubOperands.count(SymbolicName)) {
+ const std::string &RecordedParentName =
+ ComplexSubOperandsParentName[SymbolicName];
+ if (RecordedParentName != ParentName)
+ return failedImport("Error: Complex suboperand " + SymbolicName +
+ " referenced by different operands: " +
+ RecordedParentName + " and " + ParentName + ".");
+ // Complex suboperand referenced more than once from same the operand is
+ // used to generate 'same operand check'. Emitting of
+ // GIR_ComplexSubOperandRenderer for them is already handled.
+ return Error::success();
+ }
ComplexSubOperands[SymbolicName] =
std::make_tuple(ComplexPattern, RendererID, SubOperandID);
- ComplexSubOperandsParentName[SymbolicName] = ParentName;
+ ComplexSubOperandsParentName[SymbolicName] = ParentName;
return Error::success();
}
@@ -1108,7 +1108,7 @@ public:
IPM_MemoryVsLLTSize,
IPM_MemoryAddressSpace,
IPM_MemoryAlignment,
- IPM_VectorSplatImm,
+ IPM_VectorSplatImm,
IPM_GenericPredicate,
OPM_SameOperand,
OPM_ComplexPattern,
@@ -1121,7 +1121,7 @@ public:
OPM_PointerToAny,
OPM_RegBank,
OPM_MBB,
- OPM_RecordNamedOperand,
+ OPM_RecordNamedOperand,
};
protected:
@@ -1291,15 +1291,15 @@ public:
: OperandPredicateMatcher(OPM_PointerToAny, InsnVarID, OpIdx),
SizeInBits(SizeInBits) {}
- static bool classof(const PredicateMatcher *P) {
+ static bool classof(const PredicateMatcher *P) {
return P->getKind() == OPM_PointerToAny;
}
- bool isIdentical(const PredicateMatcher &B) const override {
- return OperandPredicateMatcher::isIdentical(B) &&
- SizeInBits == cast<PointerToAnyOperandMatcher>(&B)->SizeInBits;
- }
-
+ bool isIdentical(const PredicateMatcher &B) const override {
+ return OperandPredicateMatcher::isIdentical(B) &&
+ SizeInBits == cast<PointerToAnyOperandMatcher>(&B)->SizeInBits;
+ }
+
void emitPredicateOpcodes(MatchTable &Table,
RuleMatcher &Rule) const override {
Table << MatchTable::Opcode("GIM_CheckPointerToAny")
@@ -1310,40 +1310,40 @@ public:
}
};
-/// Generates code to record named operand in RecordedOperands list at StoreIdx.
-/// Predicates with 'let PredicateCodeUsesOperands = 1' get RecordedOperands as
-/// an argument to predicate's c++ code once all operands have been matched.
-class RecordNamedOperandMatcher : public OperandPredicateMatcher {
-protected:
- unsigned StoreIdx;
- std::string Name;
-
-public:
- RecordNamedOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
- unsigned StoreIdx, StringRef Name)
- : OperandPredicateMatcher(OPM_RecordNamedOperand, InsnVarID, OpIdx),
- StoreIdx(StoreIdx), Name(Name) {}
-
- static bool classof(const PredicateMatcher *P) {
- return P->getKind() == OPM_RecordNamedOperand;
- }
-
- bool isIdentical(const PredicateMatcher &B) const override {
- return OperandPredicateMatcher::isIdentical(B) &&
- StoreIdx == cast<RecordNamedOperandMatcher>(&B)->StoreIdx &&
- Name == cast<RecordNamedOperandMatcher>(&B)->Name;
- }
-
- void emitPredicateOpcodes(MatchTable &Table,
- RuleMatcher &Rule) const override {
- Table << MatchTable::Opcode("GIM_RecordNamedOperand")
- << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
- << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
- << MatchTable::Comment("StoreIdx") << MatchTable::IntValue(StoreIdx)
- << MatchTable::Comment("Name : " + Name) << MatchTable::LineBreak;
- }
-};
-
+/// Generates code to record named operand in RecordedOperands list at StoreIdx.
+/// Predicates with 'let PredicateCodeUsesOperands = 1' get RecordedOperands as
+/// an argument to predicate's c++ code once all operands have been matched.
+class RecordNamedOperandMatcher : public OperandPredicateMatcher {
+protected:
+ unsigned StoreIdx;
+ std::string Name;
+
+public:
+ RecordNamedOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
+ unsigned StoreIdx, StringRef Name)
+ : OperandPredicateMatcher(OPM_RecordNamedOperand, InsnVarID, OpIdx),
+ StoreIdx(StoreIdx), Name(Name) {}
+
+ static bool classof(const PredicateMatcher *P) {
+ return P->getKind() == OPM_RecordNamedOperand;
+ }
+
+ bool isIdentical(const PredicateMatcher &B) const override {
+ return OperandPredicateMatcher::isIdentical(B) &&
+ StoreIdx == cast<RecordNamedOperandMatcher>(&B)->StoreIdx &&
+ Name == cast<RecordNamedOperandMatcher>(&B)->Name;
+ }
+
+ void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const override {
+ Table << MatchTable::Opcode("GIM_RecordNamedOperand")
+ << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
+ << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
+ << MatchTable::Comment("StoreIdx") << MatchTable::IntValue(StoreIdx)
+ << MatchTable::Comment("Name : " + Name) << MatchTable::LineBreak;
+ }
+};
+
/// Generates code to check that an operand is a particular target constant.
class ComplexPatternOperandMatcher : public OperandPredicateMatcher {
protected:
@@ -1583,7 +1583,7 @@ public:
AllocatedTemporariesBaseID(AllocatedTemporariesBaseID) {}
bool hasSymbolicName() const { return !SymbolicName.empty(); }
- StringRef getSymbolicName() const { return SymbolicName; }
+ StringRef getSymbolicName() const { return SymbolicName; }
void setSymbolicName(StringRef Name) {
assert(SymbolicName.empty() && "Operand already has a symbolic name");
SymbolicName = std::string(Name);
@@ -1730,23 +1730,23 @@ PredicateListMatcher<PredicateMatcher>::getNoPredicateComment() const {
/// Generates code to check the opcode of an instruction.
class InstructionOpcodeMatcher : public InstructionPredicateMatcher {
protected:
- // Allow matching one to several, similar opcodes that share properties. This
- // is to handle patterns where one SelectionDAG operation maps to multiple
- // GlobalISel ones (e.g. G_BUILD_VECTOR and G_BUILD_VECTOR_TRUNC). The first
- // is treated as the canonical opcode.
- SmallVector<const CodeGenInstruction *, 2> Insts;
+ // Allow matching one to several, similar opcodes that share properties. This
+ // is to handle patterns where one SelectionDAG operation maps to multiple
+ // GlobalISel ones (e.g. G_BUILD_VECTOR and G_BUILD_VECTOR_TRUNC). The first
+ // is treated as the canonical opcode.
+ SmallVector<const CodeGenInstruction *, 2> Insts;
static DenseMap<const CodeGenInstruction *, unsigned> OpcodeValues;
-
- MatchTableRecord getInstValue(const CodeGenInstruction *I) const {
- const auto VI = OpcodeValues.find(I);
- if (VI != OpcodeValues.end())
- return MatchTable::NamedValue(I->Namespace, I->TheDef->getName(),
- VI->second);
- return MatchTable::NamedValue(I->Namespace, I->TheDef->getName());
- }
-
+
+ MatchTableRecord getInstValue(const CodeGenInstruction *I) const {
+ const auto VI = OpcodeValues.find(I);
+ if (VI != OpcodeValues.end())
+ return MatchTable::NamedValue(I->Namespace, I->TheDef->getName(),
+ VI->second);
+ return MatchTable::NamedValue(I->Namespace, I->TheDef->getName());
+ }
+
public:
static void initOpcodeValuesMap(const CodeGenTarget &Target) {
OpcodeValues.clear();
@@ -1756,13 +1756,13 @@ public:
OpcodeValues[I] = OpcodeValue++;
}
- InstructionOpcodeMatcher(unsigned InsnVarID,
- ArrayRef<const CodeGenInstruction *> I)
- : InstructionPredicateMatcher(IPM_Opcode, InsnVarID),
- Insts(I.begin(), I.end()) {
- assert((Insts.size() == 1 || Insts.size() == 2) &&
- "unexpected number of opcode alternatives");
- }
+ InstructionOpcodeMatcher(unsigned InsnVarID,
+ ArrayRef<const CodeGenInstruction *> I)
+ : InstructionPredicateMatcher(IPM_Opcode, InsnVarID),
+ Insts(I.begin(), I.end()) {
+ assert((Insts.size() == 1 || Insts.size() == 2) &&
+ "unexpected number of opcode alternatives");
+ }
static bool classof(const PredicateMatcher *P) {
return P->getKind() == IPM_Opcode;
@@ -1770,19 +1770,19 @@ public:
bool isIdentical(const PredicateMatcher &B) const override {
return InstructionPredicateMatcher::isIdentical(B) &&
- Insts == cast<InstructionOpcodeMatcher>(&B)->Insts;
- }
-
- bool hasValue() const override {
- return Insts.size() == 1 && OpcodeValues.count(Insts[0]);
- }
-
- // TODO: This is used for the SwitchMatcher optimization. We should be able to
- // return a list of the opcodes to match.
+ Insts == cast<InstructionOpcodeMatcher>(&B)->Insts;
+ }
+
+ bool hasValue() const override {
+ return Insts.size() == 1 && OpcodeValues.count(Insts[0]);
+ }
+
+ // TODO: This is used for the SwitchMatcher optimization. We should be able to
+ // return a list of the opcodes to match.
MatchTableRecord getValue() const override {
- assert(Insts.size() == 1);
-
- const CodeGenInstruction *I = Insts[0];
+ assert(Insts.size() == 1);
+
+ const CodeGenInstruction *I = Insts[0];
const auto VI = OpcodeValues.find(I);
if (VI != OpcodeValues.end())
return MatchTable::NamedValue(I->Namespace, I->TheDef->getName(),
@@ -1792,14 +1792,14 @@ public:
void emitPredicateOpcodes(MatchTable &Table,
RuleMatcher &Rule) const override {
- StringRef CheckType = Insts.size() == 1 ?
- "GIM_CheckOpcode" : "GIM_CheckOpcodeIsEither";
- Table << MatchTable::Opcode(CheckType) << MatchTable::Comment("MI")
- << MatchTable::IntValue(InsnVarID);
-
- for (const CodeGenInstruction *I : Insts)
- Table << getInstValue(I);
- Table << MatchTable::LineBreak;
+ StringRef CheckType = Insts.size() == 1 ?
+ "GIM_CheckOpcode" : "GIM_CheckOpcodeIsEither";
+ Table << MatchTable::Opcode(CheckType) << MatchTable::Comment("MI")
+ << MatchTable::IntValue(InsnVarID);
+
+ for (const CodeGenInstruction *I : Insts)
+ Table << getInstValue(I);
+ Table << MatchTable::LineBreak;
}
/// Compare the priority of this object and B.
@@ -1817,32 +1817,32 @@ public:
// using instruction frequency information to improve compile time.
if (const InstructionOpcodeMatcher *BO =
dyn_cast<InstructionOpcodeMatcher>(&B))
- return Insts[0]->TheDef->getName() < BO->Insts[0]->TheDef->getName();
+ return Insts[0]->TheDef->getName() < BO->Insts[0]->TheDef->getName();
return false;
};
bool isConstantInstruction() const {
- return Insts.size() == 1 && Insts[0]->TheDef->getName() == "G_CONSTANT";
- }
-
- // The first opcode is the canonical opcode, and later are alternatives.
- StringRef getOpcode() const {
- return Insts[0]->TheDef->getName();
- }
-
- ArrayRef<const CodeGenInstruction *> getAlternativeOpcodes() {
- return Insts;
- }
-
- bool isVariadicNumOperands() const {
- // If one is variadic, they all should be.
- return Insts[0]->Operands.isVariadic;
- }
-
+ return Insts.size() == 1 && Insts[0]->TheDef->getName() == "G_CONSTANT";
+ }
+
+ // The first opcode is the canonical opcode, and later are alternatives.
+ StringRef getOpcode() const {
+ return Insts[0]->TheDef->getName();
+ }
+
+ ArrayRef<const CodeGenInstruction *> getAlternativeOpcodes() {
+ return Insts;
+ }
+
+ bool isVariadicNumOperands() const {
+ // If one is variadic, they all should be.
+ return Insts[0]->Operands.isVariadic;
+ }
+
StringRef getOperandType(unsigned OpIdx) const {
- // Types expected to be uniform for all alternatives.
- return Insts[0]->Operands[OpIdx].OperandType;
+ // Types expected to be uniform for all alternatives.
+ return Insts[0]->Operands[OpIdx].OperandType;
}
};
@@ -2125,42 +2125,42 @@ public:
}
};
-// Matcher for immAllOnesV/immAllZerosV
-class VectorSplatImmPredicateMatcher : public InstructionPredicateMatcher {
-public:
- enum SplatKind {
- AllZeros,
- AllOnes
- };
-
-private:
- SplatKind Kind;
-
-public:
- VectorSplatImmPredicateMatcher(unsigned InsnVarID, SplatKind K)
- : InstructionPredicateMatcher(IPM_VectorSplatImm, InsnVarID), Kind(K) {}
-
- static bool classof(const PredicateMatcher *P) {
- return P->getKind() == IPM_VectorSplatImm;
- }
-
- bool isIdentical(const PredicateMatcher &B) const override {
- return InstructionPredicateMatcher::isIdentical(B) &&
- Kind == static_cast<const VectorSplatImmPredicateMatcher &>(B).Kind;
- }
-
- void emitPredicateOpcodes(MatchTable &Table,
- RuleMatcher &Rule) const override {
- if (Kind == AllOnes)
- Table << MatchTable::Opcode("GIM_CheckIsBuildVectorAllOnes");
- else
- Table << MatchTable::Opcode("GIM_CheckIsBuildVectorAllZeros");
-
- Table << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID);
- Table << MatchTable::LineBreak;
- }
-};
-
+// Matcher for immAllOnesV/immAllZerosV
+class VectorSplatImmPredicateMatcher : public InstructionPredicateMatcher {
+public:
+ enum SplatKind {
+ AllZeros,
+ AllOnes
+ };
+
+private:
+ SplatKind Kind;
+
+public:
+ VectorSplatImmPredicateMatcher(unsigned InsnVarID, SplatKind K)
+ : InstructionPredicateMatcher(IPM_VectorSplatImm, InsnVarID), Kind(K) {}
+
+ static bool classof(const PredicateMatcher *P) {
+ return P->getKind() == IPM_VectorSplatImm;
+ }
+
+ bool isIdentical(const PredicateMatcher &B) const override {
+ return InstructionPredicateMatcher::isIdentical(B) &&
+ Kind == static_cast<const VectorSplatImmPredicateMatcher &>(B).Kind;
+ }
+
+ void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const override {
+ if (Kind == AllOnes)
+ Table << MatchTable::Opcode("GIM_CheckIsBuildVectorAllOnes");
+ else
+ Table << MatchTable::Opcode("GIM_CheckIsBuildVectorAllZeros");
+
+ Table << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID);
+ Table << MatchTable::LineBreak;
+ }
+};
+
/// Generates code to check an arbitrary C++ instruction predicate.
class GenericInstructionPredicateMatcher : public InstructionPredicateMatcher {
protected:
@@ -2217,9 +2217,9 @@ protected:
SmallVector<std::pair<Record *, unsigned>, 2> PhysRegInputs;
public:
- InstructionMatcher(RuleMatcher &Rule, StringRef SymbolicName,
- bool NumOpsCheck = true)
- : Rule(Rule), NumOperandsCheck(NumOpsCheck), SymbolicName(SymbolicName) {
+ InstructionMatcher(RuleMatcher &Rule, StringRef SymbolicName,
+ bool NumOpsCheck = true)
+ : Rule(Rule), NumOperandsCheck(NumOpsCheck), SymbolicName(SymbolicName) {
// We create a new instruction matcher.
// Get a new ID for that instruction.
InsnVarID = Rule.implicitlyDefineInsnVar(*this);
@@ -2249,10 +2249,10 @@ public:
}
OperandMatcher &getOperand(unsigned OpIdx) {
- auto I = llvm::find_if(Operands,
- [&OpIdx](const std::unique_ptr<OperandMatcher> &X) {
- return X->getOpIdx() == OpIdx;
- });
+ auto I = llvm::find_if(Operands,
+ [&OpIdx](const std::unique_ptr<OperandMatcher> &X) {
+ return X->getOpIdx() == OpIdx;
+ });
if (I != Operands.end())
return **I;
llvm_unreachable("Failed to lookup operand");
@@ -2408,10 +2408,10 @@ protected:
public:
InstructionOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
- RuleMatcher &Rule, StringRef SymbolicName,
- bool NumOpsCheck = true)
+ RuleMatcher &Rule, StringRef SymbolicName,
+ bool NumOpsCheck = true)
: OperandPredicateMatcher(OPM_Instruction, InsnVarID, OpIdx),
- InsnMatcher(new InstructionMatcher(Rule, SymbolicName, NumOpsCheck)) {}
+ InsnMatcher(new InstructionMatcher(Rule, SymbolicName, NumOpsCheck)) {}
static bool classof(const PredicateMatcher *P) {
return P->getKind() == OPM_Instruction;
@@ -2537,7 +2537,7 @@ public:
return R->getKind() == OR_Copy;
}
- StringRef getSymbolicName() const { return SymbolicName; }
+ StringRef getSymbolicName() const { return SymbolicName; }
void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
@@ -2604,7 +2604,7 @@ public:
return R->getKind() == OR_CopyOrAddZeroReg;
}
- StringRef getSymbolicName() const { return SymbolicName; }
+ StringRef getSymbolicName() const { return SymbolicName; }
void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
@@ -2641,7 +2641,7 @@ public:
return R->getKind() == OR_CopyConstantAsImm;
}
- StringRef getSymbolicName() const { return SymbolicName; }
+ StringRef getSymbolicName() const { return SymbolicName; }
void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
@@ -2672,7 +2672,7 @@ public:
return R->getKind() == OR_CopyFConstantAsFPImm;
}
- StringRef getSymbolicName() const { return SymbolicName; }
+ StringRef getSymbolicName() const { return SymbolicName; }
void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
@@ -2706,7 +2706,7 @@ public:
return R->getKind() == OR_CopySubReg;
}
- StringRef getSymbolicName() const { return SymbolicName; }
+ StringRef getSymbolicName() const { return SymbolicName; }
void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
@@ -2729,13 +2729,13 @@ protected:
unsigned InsnID;
const Record *RegisterDef;
bool IsDef;
- const CodeGenTarget &Target;
+ const CodeGenTarget &Target;
public:
- AddRegisterRenderer(unsigned InsnID, const CodeGenTarget &Target,
- const Record *RegisterDef, bool IsDef = false)
+ AddRegisterRenderer(unsigned InsnID, const CodeGenTarget &Target,
+ const Record *RegisterDef, bool IsDef = false)
: OperandRenderer(OR_Register), InsnID(InsnID), RegisterDef(RegisterDef),
- IsDef(IsDef), Target(Target) {}
+ IsDef(IsDef), Target(Target) {}
static bool classof(const OperandRenderer *R) {
return R->getKind() == OR_Register;
@@ -2743,17 +2743,17 @@ public:
void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Table << MatchTable::Opcode("GIR_AddRegister")
- << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID);
- if (RegisterDef->getName() != "zero_reg") {
- Table << MatchTable::NamedValue(
- (RegisterDef->getValue("Namespace")
- ? RegisterDef->getValueAsString("Namespace")
- : ""),
- RegisterDef->getName());
- } else {
- Table << MatchTable::NamedValue(Target.getRegNamespace(), "NoRegister");
- }
- Table << MatchTable::Comment("AddRegisterRegFlags");
+ << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID);
+ if (RegisterDef->getName() != "zero_reg") {
+ Table << MatchTable::NamedValue(
+ (RegisterDef->getValue("Namespace")
+ ? RegisterDef->getValueAsString("Namespace")
+ : ""),
+ RegisterDef->getName());
+ } else {
+ Table << MatchTable::NamedValue(Target.getRegNamespace(), "NoRegister");
+ }
+ Table << MatchTable::Comment("AddRegisterRegFlags");
// TODO: This is encoded as a 64-bit element, but only 16 or 32-bits are
// really needed for a physical register reference. We can pack the
@@ -2775,14 +2775,14 @@ protected:
unsigned TempRegID;
const CodeGenSubRegIndex *SubRegIdx;
bool IsDef;
- bool IsDead;
+ bool IsDead;
public:
TempRegRenderer(unsigned InsnID, unsigned TempRegID, bool IsDef = false,
- const CodeGenSubRegIndex *SubReg = nullptr,
- bool IsDead = false)
+ const CodeGenSubRegIndex *SubReg = nullptr,
+ bool IsDead = false)
: OperandRenderer(OR_Register), InsnID(InsnID), TempRegID(TempRegID),
- SubRegIdx(SubReg), IsDef(IsDef), IsDead(IsDead) {}
+ SubRegIdx(SubReg), IsDef(IsDef), IsDead(IsDead) {}
static bool classof(const OperandRenderer *R) {
return R->getKind() == OR_TempRegister;
@@ -2799,13 +2799,13 @@ public:
<< MatchTable::Comment("TempRegID") << MatchTable::IntValue(TempRegID)
<< MatchTable::Comment("TempRegFlags");
- if (IsDef) {
- SmallString<32> RegFlags;
- RegFlags += "RegState::Define";
- if (IsDead)
- RegFlags += "|RegState::Dead";
- Table << MatchTable::NamedValue(RegFlags);
- } else
+ if (IsDef) {
+ SmallString<32> RegFlags;
+ RegFlags += "RegState::Define";
+ if (IsDead)
+ RegFlags += "|RegState::Dead";
+ Table << MatchTable::NamedValue(RegFlags);
+ } else
Table << MatchTable::IntValue(0);
if (SubRegIdx)
@@ -3518,16 +3518,16 @@ private:
// Rule coverage information.
Optional<CodeGenCoverage> RuleCoverage;
- /// Variables used to help with collecting of named operands for predicates
- /// with 'let PredicateCodeUsesOperands = 1'. WaitingForNamedOperands is set
- /// to the number of named operands that predicate expects. Store locations in
- /// StoreIdxForName correspond to the order in which operand names appear in
- /// predicate's argument list.
- /// When we visit named leaf operand and WaitingForNamedOperands is not zero,
- /// add matcher that will record operand and decrease counter.
- unsigned WaitingForNamedOperands = 0;
- StringMap<unsigned> StoreIdxForName;
-
+ /// Variables used to help with collecting of named operands for predicates
+ /// with 'let PredicateCodeUsesOperands = 1'. WaitingForNamedOperands is set
+ /// to the number of named operands that predicate expects. Store locations in
+ /// StoreIdxForName correspond to the order in which operand names appear in
+ /// predicate's argument list.
+ /// When we visit named leaf operand and WaitingForNamedOperands is not zero,
+ /// add matcher that will record operand and decrease counter.
+ unsigned WaitingForNamedOperands = 0;
+ StringMap<unsigned> StoreIdxForName;
+
void gatherOpcodeValues();
void gatherTypeIDValues();
void gatherNodeEquivs();
@@ -3559,11 +3559,11 @@ private:
const TreePatternNode *Dst);
Expected<action_iterator>
- importExplicitDefRenderers(action_iterator InsertPt, RuleMatcher &M,
- BuildMIAction &DstMIBuilder,
- const TreePatternNode *Dst);
-
- Expected<action_iterator>
+ importExplicitDefRenderers(action_iterator InsertPt, RuleMatcher &M,
+ BuildMIAction &DstMIBuilder,
+ const TreePatternNode *Dst);
+
+ Expected<action_iterator>
importExplicitUseRenderers(action_iterator InsertPt, RuleMatcher &M,
BuildMIAction &DstMIBuilder,
const llvm::TreePatternNode *Dst);
@@ -3580,8 +3580,8 @@ private:
void emitCxxPredicateFns(raw_ostream &OS, StringRef CodeFieldName,
StringRef TypeIdentifier, StringRef ArgType,
- StringRef ArgName, StringRef AdditionalArgs,
- StringRef AdditionalDeclarations,
+ StringRef ArgName, StringRef AdditionalArgs,
+ StringRef AdditionalDeclarations,
std::function<bool(const Record *R)> Filter);
void emitImmPredicateFns(raw_ostream &OS, StringRef TypeIdentifier,
StringRef ArgType,
@@ -3623,12 +3623,12 @@ private:
Optional<const CodeGenRegisterClass *>
inferRegClassFromPattern(TreePatternNode *N);
- // Add builtin predicates.
- Expected<InstructionMatcher &>
- addBuiltinPredicates(const Record *SrcGIEquivOrNull,
- const TreePredicateFn &Predicate,
- InstructionMatcher &InsnMatcher, bool &HasAddedMatcher);
-
+ // Add builtin predicates.
+ Expected<InstructionMatcher &>
+ addBuiltinPredicates(const Record *SrcGIEquivOrNull,
+ const TreePredicateFn &Predicate,
+ InstructionMatcher &InsnMatcher, bool &HasAddedMatcher);
+
public:
/// Takes a sequence of \p Rules and group them based on the predicates
/// they share. \p MatcherStorage is used as a memory container
@@ -3736,147 +3736,147 @@ GlobalISelEmitter::importRulePredicates(RuleMatcher &M,
return Error::success();
}
-Expected<InstructionMatcher &> GlobalISelEmitter::addBuiltinPredicates(
- const Record *SrcGIEquivOrNull, const TreePredicateFn &Predicate,
- InstructionMatcher &InsnMatcher, bool &HasAddedMatcher) {
- if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) {
- if (const ListInit *AddrSpaces = Predicate.getAddressSpaces()) {
- SmallVector<unsigned, 4> ParsedAddrSpaces;
-
- for (Init *Val : AddrSpaces->getValues()) {
- IntInit *IntVal = dyn_cast<IntInit>(Val);
- if (!IntVal)
- return failedImport("Address space is not an integer");
- ParsedAddrSpaces.push_back(IntVal->getValue());
- }
-
- if (!ParsedAddrSpaces.empty()) {
- InsnMatcher.addPredicate<MemoryAddressSpacePredicateMatcher>(
- 0, ParsedAddrSpaces);
- }
- }
-
- int64_t MinAlign = Predicate.getMinAlignment();
- if (MinAlign > 0)
- InsnMatcher.addPredicate<MemoryAlignmentPredicateMatcher>(0, MinAlign);
- }
-
- // G_LOAD is used for both non-extending and any-extending loads.
- if (Predicate.isLoad() && Predicate.isNonExtLoad()) {
- InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
- 0, MemoryVsLLTSizePredicateMatcher::EqualTo, 0);
- return InsnMatcher;
- }
- if (Predicate.isLoad() && Predicate.isAnyExtLoad()) {
- InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
- 0, MemoryVsLLTSizePredicateMatcher::LessThan, 0);
- return InsnMatcher;
- }
-
- if (Predicate.isStore()) {
- if (Predicate.isTruncStore()) {
- // FIXME: If MemoryVT is set, we end up with 2 checks for the MMO size.
- InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
- 0, MemoryVsLLTSizePredicateMatcher::LessThan, 0);
- return InsnMatcher;
- }
- if (Predicate.isNonTruncStore()) {
- // We need to check the sizes match here otherwise we could incorrectly
- // match truncating stores with non-truncating ones.
- InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
- 0, MemoryVsLLTSizePredicateMatcher::EqualTo, 0);
- }
- }
-
- // No check required. We already did it by swapping the opcode.
- if (!SrcGIEquivOrNull->isValueUnset("IfSignExtend") &&
- Predicate.isSignExtLoad())
- return InsnMatcher;
-
- // No check required. We already did it by swapping the opcode.
- if (!SrcGIEquivOrNull->isValueUnset("IfZeroExtend") &&
- Predicate.isZeroExtLoad())
- return InsnMatcher;
-
- // No check required. G_STORE by itself is a non-extending store.
- if (Predicate.isNonTruncStore())
- return InsnMatcher;
-
- if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) {
- if (Predicate.getMemoryVT() != nullptr) {
- Optional<LLTCodeGen> MemTyOrNone =
- MVTToLLT(getValueType(Predicate.getMemoryVT()));
-
- if (!MemTyOrNone)
- return failedImport("MemVT could not be converted to LLT");
-
- // MMO's work in bytes so we must take care of unusual types like i1
- // don't round down.
- unsigned MemSizeInBits =
- llvm::alignTo(MemTyOrNone->get().getSizeInBits(), 8);
-
- InsnMatcher.addPredicate<MemorySizePredicateMatcher>(0,
- MemSizeInBits / 8);
- return InsnMatcher;
- }
- }
-
- if (Predicate.isLoad() || Predicate.isStore()) {
- // No check required. A G_LOAD/G_STORE is an unindexed load.
- if (Predicate.isUnindexed())
- return InsnMatcher;
- }
-
- if (Predicate.isAtomic()) {
- if (Predicate.isAtomicOrderingMonotonic()) {
- InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Monotonic");
- return InsnMatcher;
- }
- if (Predicate.isAtomicOrderingAcquire()) {
- InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Acquire");
- return InsnMatcher;
- }
- if (Predicate.isAtomicOrderingRelease()) {
- InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Release");
- return InsnMatcher;
- }
- if (Predicate.isAtomicOrderingAcquireRelease()) {
- InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
- "AcquireRelease");
- return InsnMatcher;
- }
- if (Predicate.isAtomicOrderingSequentiallyConsistent()) {
- InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
- "SequentiallyConsistent");
- return InsnMatcher;
- }
- }
-
- if (Predicate.isAtomicOrderingAcquireOrStronger()) {
- InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
- "Acquire", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
- return InsnMatcher;
- }
- if (Predicate.isAtomicOrderingWeakerThanAcquire()) {
- InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
- "Acquire", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan);
- return InsnMatcher;
- }
-
- if (Predicate.isAtomicOrderingReleaseOrStronger()) {
- InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
- "Release", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
- return InsnMatcher;
- }
- if (Predicate.isAtomicOrderingWeakerThanRelease()) {
- InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
- "Release", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan);
- return InsnMatcher;
- }
- HasAddedMatcher = false;
- return InsnMatcher;
-}
-
+Expected<InstructionMatcher &> GlobalISelEmitter::addBuiltinPredicates(
+ const Record *SrcGIEquivOrNull, const TreePredicateFn &Predicate,
+ InstructionMatcher &InsnMatcher, bool &HasAddedMatcher) {
+ if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) {
+ if (const ListInit *AddrSpaces = Predicate.getAddressSpaces()) {
+ SmallVector<unsigned, 4> ParsedAddrSpaces;
+
+ for (Init *Val : AddrSpaces->getValues()) {
+ IntInit *IntVal = dyn_cast<IntInit>(Val);
+ if (!IntVal)
+ return failedImport("Address space is not an integer");
+ ParsedAddrSpaces.push_back(IntVal->getValue());
+ }
+
+ if (!ParsedAddrSpaces.empty()) {
+ InsnMatcher.addPredicate<MemoryAddressSpacePredicateMatcher>(
+ 0, ParsedAddrSpaces);
+ }
+ }
+
+ int64_t MinAlign = Predicate.getMinAlignment();
+ if (MinAlign > 0)
+ InsnMatcher.addPredicate<MemoryAlignmentPredicateMatcher>(0, MinAlign);
+ }
+
+ // G_LOAD is used for both non-extending and any-extending loads.
+ if (Predicate.isLoad() && Predicate.isNonExtLoad()) {
+ InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
+ 0, MemoryVsLLTSizePredicateMatcher::EqualTo, 0);
+ return InsnMatcher;
+ }
+ if (Predicate.isLoad() && Predicate.isAnyExtLoad()) {
+ InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
+ 0, MemoryVsLLTSizePredicateMatcher::LessThan, 0);
+ return InsnMatcher;
+ }
+
+ if (Predicate.isStore()) {
+ if (Predicate.isTruncStore()) {
+ // FIXME: If MemoryVT is set, we end up with 2 checks for the MMO size.
+ InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
+ 0, MemoryVsLLTSizePredicateMatcher::LessThan, 0);
+ return InsnMatcher;
+ }
+ if (Predicate.isNonTruncStore()) {
+ // We need to check the sizes match here otherwise we could incorrectly
+ // match truncating stores with non-truncating ones.
+ InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
+ 0, MemoryVsLLTSizePredicateMatcher::EqualTo, 0);
+ }
+ }
+
+ // No check required. We already did it by swapping the opcode.
+ if (!SrcGIEquivOrNull->isValueUnset("IfSignExtend") &&
+ Predicate.isSignExtLoad())
+ return InsnMatcher;
+
+ // No check required. We already did it by swapping the opcode.
+ if (!SrcGIEquivOrNull->isValueUnset("IfZeroExtend") &&
+ Predicate.isZeroExtLoad())
+ return InsnMatcher;
+
+ // No check required. G_STORE by itself is a non-extending store.
+ if (Predicate.isNonTruncStore())
+ return InsnMatcher;
+
+ if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) {
+ if (Predicate.getMemoryVT() != nullptr) {
+ Optional<LLTCodeGen> MemTyOrNone =
+ MVTToLLT(getValueType(Predicate.getMemoryVT()));
+
+ if (!MemTyOrNone)
+ return failedImport("MemVT could not be converted to LLT");
+
+ // MMO's work in bytes so we must take care of unusual types like i1
+ // don't round down.
+ unsigned MemSizeInBits =
+ llvm::alignTo(MemTyOrNone->get().getSizeInBits(), 8);
+
+ InsnMatcher.addPredicate<MemorySizePredicateMatcher>(0,
+ MemSizeInBits / 8);
+ return InsnMatcher;
+ }
+ }
+
+ if (Predicate.isLoad() || Predicate.isStore()) {
+ // No check required. A G_LOAD/G_STORE is an unindexed load.
+ if (Predicate.isUnindexed())
+ return InsnMatcher;
+ }
+
+ if (Predicate.isAtomic()) {
+ if (Predicate.isAtomicOrderingMonotonic()) {
+ InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Monotonic");
+ return InsnMatcher;
+ }
+ if (Predicate.isAtomicOrderingAcquire()) {
+ InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Acquire");
+ return InsnMatcher;
+ }
+ if (Predicate.isAtomicOrderingRelease()) {
+ InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Release");
+ return InsnMatcher;
+ }
+ if (Predicate.isAtomicOrderingAcquireRelease()) {
+ InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
+ "AcquireRelease");
+ return InsnMatcher;
+ }
+ if (Predicate.isAtomicOrderingSequentiallyConsistent()) {
+ InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
+ "SequentiallyConsistent");
+ return InsnMatcher;
+ }
+ }
+
+ if (Predicate.isAtomicOrderingAcquireOrStronger()) {
+ InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
+ "Acquire", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
+ return InsnMatcher;
+ }
+ if (Predicate.isAtomicOrderingWeakerThanAcquire()) {
+ InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
+ "Acquire", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan);
+ return InsnMatcher;
+ }
+
+ if (Predicate.isAtomicOrderingReleaseOrStronger()) {
+ InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
+ "Release", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
+ return InsnMatcher;
+ }
+ if (Predicate.isAtomicOrderingWeakerThanRelease()) {
+ InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
+ "Release", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan);
+ return InsnMatcher;
+ }
+ HasAddedMatcher = false;
+ return InsnMatcher;
+}
+
Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
const TreePatternNode *Src, unsigned &TempOpIdx) {
@@ -3918,7 +3918,7 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
for (const TreePredicateCall &Call : Src->getPredicateCalls()) {
const TreePredicateFn &Predicate = Call.Fn;
- bool HasAddedBuiltinMatcher = true;
+ bool HasAddedBuiltinMatcher = true;
if (Predicate.isAlwaysTrue())
continue;
@@ -3927,35 +3927,35 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
continue;
}
- auto InsnMatcherOrError = addBuiltinPredicates(
- SrcGIEquivOrNull, Predicate, InsnMatcher, HasAddedBuiltinMatcher);
- if (auto Error = InsnMatcherOrError.takeError())
- return std::move(Error);
-
- if (Predicate.hasGISelPredicateCode()) {
- if (Predicate.usesOperands()) {
- assert(WaitingForNamedOperands == 0 &&
- "previous predicate didn't find all operands or "
- "nested predicate that uses operands");
- TreePattern *TP = Predicate.getOrigPatFragRecord();
- WaitingForNamedOperands = TP->getNumArgs();
- for (unsigned i = 0; i < WaitingForNamedOperands; ++i)
- StoreIdxForName[getScopedName(Call.Scope, TP->getArgName(i))] = i;
+ auto InsnMatcherOrError = addBuiltinPredicates(
+ SrcGIEquivOrNull, Predicate, InsnMatcher, HasAddedBuiltinMatcher);
+ if (auto Error = InsnMatcherOrError.takeError())
+ return std::move(Error);
+
+ if (Predicate.hasGISelPredicateCode()) {
+ if (Predicate.usesOperands()) {
+ assert(WaitingForNamedOperands == 0 &&
+ "previous predicate didn't find all operands or "
+ "nested predicate that uses operands");
+ TreePattern *TP = Predicate.getOrigPatFragRecord();
+ WaitingForNamedOperands = TP->getNumArgs();
+ for (unsigned i = 0; i < WaitingForNamedOperands; ++i)
+ StoreIdxForName[getScopedName(Call.Scope, TP->getArgName(i))] = i;
}
- InsnMatcher.addPredicate<GenericInstructionPredicateMatcher>(Predicate);
+ InsnMatcher.addPredicate<GenericInstructionPredicateMatcher>(Predicate);
continue;
}
- if (!HasAddedBuiltinMatcher) {
- return failedImport("Src pattern child has predicate (" +
- explainPredicates(Src) + ")");
+ if (!HasAddedBuiltinMatcher) {
+ return failedImport("Src pattern child has predicate (" +
+ explainPredicates(Src) + ")");
}
- }
+ }
- bool IsAtomic = false;
+ bool IsAtomic = false;
if (SrcGIEquivOrNull && SrcGIEquivOrNull->getValueAsBit("CheckMMOIsNonAtomic"))
InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("NotAtomic");
else if (SrcGIEquivOrNull && SrcGIEquivOrNull->getValueAsBit("CheckMMOIsAtomic")) {
- IsAtomic = true;
+ IsAtomic = true;
InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
"Unordered", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
}
@@ -4009,27 +4009,27 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
}
}
- // Hack around an unfortunate mistake in how atomic store (and really
- // atomicrmw in general) operands were ordered. A ISD::STORE used the order
- // <stored value>, <pointer> order. ISD::ATOMIC_STORE used the opposite,
- // <pointer>, <stored value>. In GlobalISel there's just the one store
- // opcode, so we need to swap the operands here to get the right type check.
- if (IsAtomic && SrcGIOrNull->TheDef->getName() == "G_STORE") {
- assert(NumChildren == 2 && "wrong operands for atomic store");
-
- TreePatternNode *PtrChild = Src->getChild(0);
- TreePatternNode *ValueChild = Src->getChild(1);
-
- if (auto Error = importChildMatcher(Rule, InsnMatcher, PtrChild, true,
- false, 1, TempOpIdx))
- return std::move(Error);
-
- if (auto Error = importChildMatcher(Rule, InsnMatcher, ValueChild, false,
- false, 0, TempOpIdx))
- return std::move(Error);
- return InsnMatcher;
- }
-
+ // Hack around an unfortunate mistake in how atomic store (and really
+ // atomicrmw in general) operands were ordered. A ISD::STORE used the order
+ // <stored value>, <pointer> order. ISD::ATOMIC_STORE used the opposite,
+ // <pointer>, <stored value>. In GlobalISel there's just the one store
+ // opcode, so we need to swap the operands here to get the right type check.
+ if (IsAtomic && SrcGIOrNull->TheDef->getName() == "G_STORE") {
+ assert(NumChildren == 2 && "wrong operands for atomic store");
+
+ TreePatternNode *PtrChild = Src->getChild(0);
+ TreePatternNode *ValueChild = Src->getChild(1);
+
+ if (auto Error = importChildMatcher(Rule, InsnMatcher, PtrChild, true,
+ false, 1, TempOpIdx))
+ return std::move(Error);
+
+ if (auto Error = importChildMatcher(Rule, InsnMatcher, ValueChild, false,
+ false, 0, TempOpIdx))
+ return std::move(Error);
+ return InsnMatcher;
+ }
+
// Match the used operands (i.e. the children of the operator).
bool IsIntrinsic =
SrcGIOrNull->TheDef->getName() == "G_INTRINSIC" ||
@@ -4120,22 +4120,22 @@ Error GlobalISelEmitter::importChildMatcher(
bool OperandIsImmArg, unsigned OpIdx, unsigned &TempOpIdx) {
Record *PhysReg = nullptr;
- std::string SrcChildName = std::string(getSrcChildName(SrcChild, PhysReg));
- if (!SrcChild->isLeaf() &&
- SrcChild->getOperator()->isSubClassOf("ComplexPattern")) {
- // The "name" of a non-leaf complex pattern (MY_PAT $op1, $op2) is
- // "MY_PAT:op1:op2" and the ones with same "name" represent same operand.
- std::string PatternName = std::string(SrcChild->getOperator()->getName());
- for (unsigned i = 0; i < SrcChild->getNumChildren(); ++i) {
- PatternName += ":";
- PatternName += SrcChild->getChild(i)->getName();
- }
- SrcChildName = PatternName;
- }
+ std::string SrcChildName = std::string(getSrcChildName(SrcChild, PhysReg));
+ if (!SrcChild->isLeaf() &&
+ SrcChild->getOperator()->isSubClassOf("ComplexPattern")) {
+ // The "name" of a non-leaf complex pattern (MY_PAT $op1, $op2) is
+ // "MY_PAT:op1:op2" and the ones with same "name" represent same operand.
+ std::string PatternName = std::string(SrcChild->getOperator()->getName());
+ for (unsigned i = 0; i < SrcChild->getNumChildren(); ++i) {
+ PatternName += ":";
+ PatternName += SrcChild->getChild(i)->getName();
+ }
+ SrcChildName = PatternName;
+ }
OperandMatcher &OM =
- PhysReg ? InsnMatcher.addPhysRegInput(PhysReg, OpIdx, TempOpIdx)
- : InsnMatcher.addOperand(OpIdx, SrcChildName, TempOpIdx);
+ PhysReg ? InsnMatcher.addPhysRegInput(PhysReg, OpIdx, TempOpIdx)
+ : InsnMatcher.addOperand(OpIdx, SrcChildName, TempOpIdx);
if (OM.isSameAsAnotherOperand())
return Error::success();
@@ -4182,9 +4182,9 @@ Error GlobalISelEmitter::importChildMatcher(
for (unsigned i = 0, e = SrcChild->getNumChildren(); i != e; ++i) {
auto *SubOperand = SrcChild->getChild(i);
if (!SubOperand->getName().empty()) {
- if (auto Error = Rule.defineComplexSubOperand(
- SubOperand->getName(), SrcChild->getOperator(), RendererID, i,
- SrcChildName))
+ if (auto Error = Rule.defineComplexSubOperand(
+ SubOperand->getName(), SrcChild->getOperator(), RendererID, i,
+ SrcChildName))
return Error;
}
}
@@ -4230,13 +4230,13 @@ Error GlobalISelEmitter::importChildMatcher(
if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild->getLeafValue())) {
auto *ChildRec = ChildDefInit->getDef();
- if (WaitingForNamedOperands) {
- auto PA = SrcChild->getNamesAsPredicateArg().begin();
- std::string Name = getScopedName(PA->getScope(), PA->getIdentifier());
- OM.addPredicate<RecordNamedOperandMatcher>(StoreIdxForName[Name], Name);
- --WaitingForNamedOperands;
- }
-
+ if (WaitingForNamedOperands) {
+ auto PA = SrcChild->getNamesAsPredicateArg().begin();
+ std::string Name = getScopedName(PA->getScope(), PA->getIdentifier());
+ OM.addPredicate<RecordNamedOperandMatcher>(StoreIdxForName[Name], Name);
+ --WaitingForNamedOperands;
+ }
+
// Check for register classes.
if (ChildRec->isSubClassOf("RegisterClass") ||
ChildRec->isSubClassOf("RegisterOperand")) {
@@ -4279,40 +4279,40 @@ Error GlobalISelEmitter::importChildMatcher(
if (ChildRec->getName() == "srcvalue")
return Error::success();
- const bool ImmAllOnesV = ChildRec->getName() == "immAllOnesV";
- if (ImmAllOnesV || ChildRec->getName() == "immAllZerosV") {
- auto MaybeInsnOperand = OM.addPredicate<InstructionOperandMatcher>(
- InsnMatcher.getRuleMatcher(), SrcChild->getName(), false);
- InstructionOperandMatcher &InsnOperand = **MaybeInsnOperand;
-
- ValueTypeByHwMode VTy = ChildTypes.front().getValueTypeByHwMode();
-
- const CodeGenInstruction &BuildVector
- = Target.getInstruction(RK.getDef("G_BUILD_VECTOR"));
- const CodeGenInstruction &BuildVectorTrunc
- = Target.getInstruction(RK.getDef("G_BUILD_VECTOR_TRUNC"));
-
- // Treat G_BUILD_VECTOR as the canonical opcode, and G_BUILD_VECTOR_TRUNC
- // as an alternative.
- InsnOperand.getInsnMatcher().addPredicate<InstructionOpcodeMatcher>(
- makeArrayRef({&BuildVector, &BuildVectorTrunc}));
-
- // TODO: Handle both G_BUILD_VECTOR and G_BUILD_VECTOR_TRUNC We could
- // theoretically not emit any opcode check, but getOpcodeMatcher currently
- // has to succeed.
- OperandMatcher &OM =
- InsnOperand.getInsnMatcher().addOperand(0, "", TempOpIdx);
- if (auto Error =
- OM.addTypeCheckPredicate(VTy, false /* OperandIsAPointer */))
- return failedImport(toString(std::move(Error)) +
- " for result of Src pattern operator");
-
- InsnOperand.getInsnMatcher().addPredicate<VectorSplatImmPredicateMatcher>(
- ImmAllOnesV ? VectorSplatImmPredicateMatcher::AllOnes
- : VectorSplatImmPredicateMatcher::AllZeros);
- return Error::success();
- }
-
+ const bool ImmAllOnesV = ChildRec->getName() == "immAllOnesV";
+ if (ImmAllOnesV || ChildRec->getName() == "immAllZerosV") {
+ auto MaybeInsnOperand = OM.addPredicate<InstructionOperandMatcher>(
+ InsnMatcher.getRuleMatcher(), SrcChild->getName(), false);
+ InstructionOperandMatcher &InsnOperand = **MaybeInsnOperand;
+
+ ValueTypeByHwMode VTy = ChildTypes.front().getValueTypeByHwMode();
+
+ const CodeGenInstruction &BuildVector
+ = Target.getInstruction(RK.getDef("G_BUILD_VECTOR"));
+ const CodeGenInstruction &BuildVectorTrunc
+ = Target.getInstruction(RK.getDef("G_BUILD_VECTOR_TRUNC"));
+
+ // Treat G_BUILD_VECTOR as the canonical opcode, and G_BUILD_VECTOR_TRUNC
+ // as an alternative.
+ InsnOperand.getInsnMatcher().addPredicate<InstructionOpcodeMatcher>(
+ makeArrayRef({&BuildVector, &BuildVectorTrunc}));
+
+ // TODO: Handle both G_BUILD_VECTOR and G_BUILD_VECTOR_TRUNC We could
+ // theoretically not emit any opcode check, but getOpcodeMatcher currently
+ // has to succeed.
+ OperandMatcher &OM =
+ InsnOperand.getInsnMatcher().addOperand(0, "", TempOpIdx);
+ if (auto Error =
+ OM.addTypeCheckPredicate(VTy, false /* OperandIsAPointer */))
+ return failedImport(toString(std::move(Error)) +
+ " for result of Src pattern operator");
+
+ InsnOperand.getInsnMatcher().addPredicate<VectorSplatImmPredicateMatcher>(
+ ImmAllOnesV ? VectorSplatImmPredicateMatcher::AllOnes
+ : VectorSplatImmPredicateMatcher::AllZeros);
+ return Error::success();
+ }
+
return failedImport(
"Src pattern child def is an unsupported tablegen class");
}
@@ -4424,7 +4424,7 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
return failedImport("Dst operand has an unsupported type");
if (ChildRec->isSubClassOf("Register")) {
- DstMIBuilder.addRenderer<AddRegisterRenderer>(Target, ChildRec);
+ DstMIBuilder.addRenderer<AddRegisterRenderer>(Target, ChildRec);
return InsertPt;
}
@@ -4484,15 +4484,15 @@ Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
&Target.getInstruction(RK.getDef("COPY")));
BuildMIAction &CopyToPhysRegMIBuilder =
*static_cast<BuildMIAction *>(InsertPt->get());
- CopyToPhysRegMIBuilder.addRenderer<AddRegisterRenderer>(Target,
- PhysInput.first,
+ CopyToPhysRegMIBuilder.addRenderer<AddRegisterRenderer>(Target,
+ PhysInput.first,
true);
CopyToPhysRegMIBuilder.addRenderer<CopyPhysRegRenderer>(PhysInput.first);
}
- if (auto Error = importExplicitDefRenderers(InsertPt, M, DstMIBuilder, Dst)
- .takeError())
- return std::move(Error);
+ if (auto Error = importExplicitDefRenderers(InsertPt, M, DstMIBuilder, Dst)
+ .takeError())
+ return std::move(Error);
if (auto Error = importExplicitUseRenderers(InsertPt, M, DstMIBuilder, Dst)
.takeError())
@@ -4644,39 +4644,39 @@ Expected<action_iterator> GlobalISelEmitter::createInstructionRenderer(
DstI);
}
-Expected<action_iterator> GlobalISelEmitter::importExplicitDefRenderers(
- action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
- const TreePatternNode *Dst) {
+Expected<action_iterator> GlobalISelEmitter::importExplicitDefRenderers(
+ action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
+ const TreePatternNode *Dst) {
const CodeGenInstruction *DstI = DstMIBuilder.getCGI();
- const unsigned NumDefs = DstI->Operands.NumDefs;
- if (NumDefs == 0)
- return InsertPt;
-
- DstMIBuilder.addRenderer<CopyRenderer>(DstI->Operands[0].Name);
-
- // Some instructions have multiple defs, but are missing a type entry
- // (e.g. s_cc_out operands).
- if (Dst->getExtTypes().size() < NumDefs)
- return failedImport("unhandled discarded def");
-
- // Patterns only handle a single result, so any result after the first is an
- // implicitly dead def.
- for (unsigned I = 1; I < NumDefs; ++I) {
- const TypeSetByHwMode &ExtTy = Dst->getExtType(I);
- if (!ExtTy.isMachineValueType())
- return failedImport("unsupported typeset");
-
- auto OpTy = MVTToLLT(ExtTy.getMachineValueType().SimpleTy);
- if (!OpTy)
- return failedImport("unsupported type");
-
- unsigned TempRegID = M.allocateTempRegID();
- InsertPt =
- M.insertAction<MakeTempRegisterAction>(InsertPt, *OpTy, TempRegID);
- DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID, true, nullptr, true);
- }
-
- return InsertPt;
+ const unsigned NumDefs = DstI->Operands.NumDefs;
+ if (NumDefs == 0)
+ return InsertPt;
+
+ DstMIBuilder.addRenderer<CopyRenderer>(DstI->Operands[0].Name);
+
+ // Some instructions have multiple defs, but are missing a type entry
+ // (e.g. s_cc_out operands).
+ if (Dst->getExtTypes().size() < NumDefs)
+ return failedImport("unhandled discarded def");
+
+ // Patterns only handle a single result, so any result after the first is an
+ // implicitly dead def.
+ for (unsigned I = 1; I < NumDefs; ++I) {
+ const TypeSetByHwMode &ExtTy = Dst->getExtType(I);
+ if (!ExtTy.isMachineValueType())
+ return failedImport("unsupported typeset");
+
+ auto OpTy = MVTToLLT(ExtTy.getMachineValueType().SimpleTy);
+ if (!OpTy)
+ return failedImport("unsupported type");
+
+ unsigned TempRegID = M.allocateTempRegID();
+ InsertPt =
+ M.insertAction<MakeTempRegisterAction>(InsertPt, *OpTy, TempRegID);
+ DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID, true, nullptr, true);
+ }
+
+ return InsertPt;
}
Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers(
@@ -4690,8 +4690,8 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers(
// EXTRACT_SUBREG needs to use a subregister COPY.
if (Name == "EXTRACT_SUBREG") {
- if (!Dst->getChild(1)->isLeaf())
- return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
+ if (!Dst->getChild(1)->isLeaf())
+ return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
DefInit *SubRegInit = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue());
if (!SubRegInit)
return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
@@ -4878,7 +4878,7 @@ Error GlobalISelEmitter::importDefaultOperandRenderers(
IDMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
} else {
- DstMIBuilder.addRenderer<AddRegisterRenderer>(Target, Def);
+ DstMIBuilder.addRenderer<AddRegisterRenderer>(Target, Def);
}
continue;
}
@@ -4953,17 +4953,17 @@ GlobalISelEmitter::inferRegClassFromPattern(TreePatternNode *N) {
return None;
return getRegClassFromLeaf(RCChild);
}
- if (InstName == "INSERT_SUBREG") {
- TreePatternNode *Child0 = N->getChild(0);
- assert(Child0->getNumTypes() == 1 && "Unexpected number of types!");
- const TypeSetByHwMode &VTy = Child0->getExtType(0);
- return inferSuperRegisterClassForNode(VTy, Child0, N->getChild(2));
- }
- if (InstName == "EXTRACT_SUBREG") {
- assert(N->getNumTypes() == 1 && "Unexpected number of types!");
- const TypeSetByHwMode &VTy = N->getExtType(0);
- return inferSuperRegisterClass(VTy, N->getChild(1));
- }
+ if (InstName == "INSERT_SUBREG") {
+ TreePatternNode *Child0 = N->getChild(0);
+ assert(Child0->getNumTypes() == 1 && "Unexpected number of types!");
+ const TypeSetByHwMode &VTy = Child0->getExtType(0);
+ return inferSuperRegisterClassForNode(VTy, Child0, N->getChild(2));
+ }
+ if (InstName == "EXTRACT_SUBREG") {
+ assert(N->getNumTypes() == 1 && "Unexpected number of types!");
+ const TypeSetByHwMode &VTy = N->getExtType(0);
+ return inferSuperRegisterClass(VTy, N->getChild(1));
+ }
// Handle destination record types that we can safely infer a register class
// from.
@@ -5000,8 +5000,8 @@ GlobalISelEmitter::inferSuperRegisterClass(const TypeSetByHwMode &Ty,
// Use the information we found above to find a minimal register class which
// supports the subregister and type we want.
auto RC =
- Target.getSuperRegForSubReg(Ty.getValueTypeByHwMode(), CGRegs, SubIdx,
- /* MustBeAllocatable */ true);
+ Target.getSuperRegForSubReg(Ty.getValueTypeByHwMode(), CGRegs, SubIdx,
+ /* MustBeAllocatable */ true);
if (!RC)
return None;
return *RC;
@@ -5089,8 +5089,8 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
if (Dst->isLeaf()) {
Record *RCDef = getInitValueAsRegClass(Dst->getLeafValue());
- if (RCDef) {
- const CodeGenRegisterClass &RC = Target.getRegisterClass(RCDef);
+ if (RCDef) {
+ const CodeGenRegisterClass &RC = Target.getRegisterClass(RCDef);
// We need to replace the def and all its uses with the specified
// operand. However, we must also insert COPY's wherever needed.
@@ -5126,8 +5126,8 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
auto &DstI = Target.getInstruction(DstOp);
StringRef DstIName = DstI.TheDef->getName();
- if (DstI.Operands.NumDefs < Src->getExtTypes().size())
- return failedImport("Src pattern result has more defs than dst MI (" +
+ if (DstI.Operands.NumDefs < Src->getExtTypes().size())
+ return failedImport("Src pattern result has more defs than dst MI (" +
to_string(Src->getExtTypes().size()) + " def(s) vs " +
to_string(DstI.Operands.NumDefs) + " def(s))");
@@ -5347,8 +5347,8 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
// trouble than it's worth.
void GlobalISelEmitter::emitCxxPredicateFns(
raw_ostream &OS, StringRef CodeFieldName, StringRef TypeIdentifier,
- StringRef ArgType, StringRef ArgName, StringRef AdditionalArgs,
- StringRef AdditionalDeclarations,
+ StringRef ArgType, StringRef ArgName, StringRef AdditionalArgs,
+ StringRef AdditionalDeclarations,
std::function<bool(const Record *R)> Filter) {
std::vector<const Record *> MatchedRecords;
const auto &Defs = RK.getAllDerivedDefinitions("PatFrag");
@@ -5373,7 +5373,7 @@ void GlobalISelEmitter::emitCxxPredicateFns(
OS << "bool " << Target.getName() << "InstructionSelector::test" << ArgName
<< "Predicate_" << TypeIdentifier << "(unsigned PredicateID, " << ArgType << " "
- << ArgName << AdditionalArgs <<") const {\n"
+ << ArgName << AdditionalArgs <<") const {\n"
<< AdditionalDeclarations;
if (!AdditionalDeclarations.empty())
OS << "\n";
@@ -5399,13 +5399,13 @@ void GlobalISelEmitter::emitImmPredicateFns(
raw_ostream &OS, StringRef TypeIdentifier, StringRef ArgType,
std::function<bool(const Record *R)> Filter) {
return emitCxxPredicateFns(OS, "ImmediateCode", TypeIdentifier, ArgType,
- "Imm", "", "", Filter);
+ "Imm", "", "", Filter);
}
void GlobalISelEmitter::emitMIPredicateFns(raw_ostream &OS) {
return emitCxxPredicateFns(
OS, "GISelPredicateCode", "MI", "const MachineInstr &", "MI",
- ", const std::array<const MachineOperand *, 3> &Operands",
+ ", const std::array<const MachineOperand *, 3> &Operands",
" const MachineFunction &MF = *MI.getParent()->getParent();\n"
" const MachineRegisterInfo &MRI = MF.getRegInfo();\n"
" (void)MRI;",
@@ -5431,7 +5431,7 @@ std::vector<Matcher *> GlobalISelEmitter::optimizeRules(
// added rules out of it and make sure to re-create the group to properly
// re-initialize it:
if (CurrentGroup->size() < 2)
- append_range(OptRules, CurrentGroup->matchers());
+ append_range(OptRules, CurrentGroup->matchers());
else {
CurrentGroup->finalize();
OptRules.push_back(CurrentGroup.get());
@@ -5480,13 +5480,13 @@ GlobalISelEmitter::buildMatchTable(MutableArrayRef<RuleMatcher> Rules,
OpcodeOrder[Opcode] = CurrentOrdering++;
}
- llvm::stable_sort(InputRules, [&OpcodeOrder](const Matcher *A,
- const Matcher *B) {
- auto *L = static_cast<const RuleMatcher *>(A);
- auto *R = static_cast<const RuleMatcher *>(B);
- return std::make_tuple(OpcodeOrder[L->getOpcode()], L->getNumOperands()) <
- std::make_tuple(OpcodeOrder[R->getOpcode()], R->getNumOperands());
- });
+ llvm::stable_sort(InputRules, [&OpcodeOrder](const Matcher *A,
+ const Matcher *B) {
+ auto *L = static_cast<const RuleMatcher *>(A);
+ auto *R = static_cast<const RuleMatcher *>(B);
+ return std::make_tuple(OpcodeOrder[L->getOpcode()], L->getNumOperands()) <
+ std::make_tuple(OpcodeOrder[R->getOpcode()], R->getNumOperands());
+ });
for (Matcher *Rule : InputRules)
Rule->optimize();
@@ -5619,7 +5619,7 @@ void GlobalISelEmitter::run(raw_ostream &OS) {
<< " typedef void(" << Target.getName()
<< "InstructionSelector::*CustomRendererFn)(MachineInstrBuilder &, const "
- "MachineInstr &, int) "
+ "MachineInstr &, int) "
"const;\n"
<< " const ISelInfoTy<PredicateBitset, ComplexMatcherMemFn, "
"CustomRendererFn> "
@@ -5635,8 +5635,8 @@ void GlobalISelEmitter::run(raw_ostream &OS) {
<< " bool testImmPredicate_APFloat(unsigned PredicateID, const APFloat "
"&Imm) const override;\n"
<< " const int64_t *getMatchTable() const override;\n"
- << " bool testMIPredicate_MI(unsigned PredicateID, const MachineInstr &MI"
- ", const std::array<const MachineOperand *, 3> &Operands) "
+ << " bool testMIPredicate_MI(unsigned PredicateID, const MachineInstr &MI"
+ ", const std::array<const MachineOperand *, 3> &Operands) "
"const override;\n"
<< "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n";
@@ -5672,7 +5672,7 @@ void GlobalISelEmitter::run(raw_ostream &OS) {
OS << "void " << Target.getName() << "InstructionSelector"
"::setupGeneratedPerFunctionState(MachineFunction &MF) {\n"
" AvailableFunctionFeatures = computeAvailableFunctionFeatures("
- "(const " << Target.getName() << "Subtarget *)&MF.getSubtarget(), &MF);\n"
+ "(const " << Target.getName() << "Subtarget *)&MF.getSubtarget(), &MF);\n"
"}\n";
if (Target.getName() == "X86" || Target.getName() == "AArch64") {
@@ -5690,7 +5690,7 @@ void GlobalISelEmitter::run(raw_ostream &OS) {
// Emit a table containing the LLT objects needed by the matcher and an enum
// for the matcher to reference them with.
std::vector<LLTCodeGen> TypeObjects;
- append_range(TypeObjects, KnownTypes);
+ append_range(TypeObjects, KnownTypes);
llvm::sort(TypeObjects);
OS << "// LLT Objects.\n"
<< "enum {\n";
@@ -5792,7 +5792,7 @@ void GlobalISelEmitter::run(raw_ostream &OS) {
<< "enum {\n"
<< " GICR_Invalid,\n";
for (const auto &Record : CustomRendererFns)
- OS << " GICR_" << Record->getValueAsString("RendererFn") << ",\n";
+ OS << " GICR_" << Record->getValueAsString("RendererFn") << ",\n";
OS << "};\n";
OS << Target.getName() << "InstructionSelector::CustomRendererFn\n"
@@ -6085,10 +6085,10 @@ void SwitchMatcher::finalize() {
if (empty())
return;
- llvm::stable_sort(Matchers, [](const Matcher *L, const Matcher *R) {
- return L->getFirstCondition().getValue() <
- R->getFirstCondition().getValue();
- });
+ llvm::stable_sort(Matchers, [](const Matcher *L, const Matcher *R) {
+ return L->getFirstCondition().getValue() <
+ R->getFirstCondition().getValue();
+ });
Condition = Matchers[0]->popFirstCondition();
for (unsigned I = 1, E = Values.size(); I < E; ++I)
Matchers[I]->popFirstCondition();
diff --git a/contrib/libs/llvm12/utils/TableGen/InstrInfoEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/InstrInfoEmitter.cpp
index 8199a9839f..9ff385faec 100644
--- a/contrib/libs/llvm12/utils/TableGen/InstrInfoEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/InstrInfoEmitter.cpp
@@ -182,10 +182,10 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
if (Constraint.isNone())
Res += "0";
else if (Constraint.isEarlyClobber())
- Res += "MCOI_EARLY_CLOBBER";
+ Res += "MCOI_EARLY_CLOBBER";
else {
assert(Constraint.isTied());
- Res += "MCOI_TIED_TO(" + utostr(Constraint.getTiedOperand()) + ")";
+ Res += "MCOI_TIED_TO(" + utostr(Constraint.getTiedOperand()) + ")";
}
Result.push_back(Res);
@@ -279,7 +279,7 @@ void InstrInfoEmitter::emitOperandNameMappings(raw_ostream &OS,
for (const auto &Op : Operands)
OS << " " << Op.first << " = " << Op.second << ",\n";
- OS << " OPERAND_LAST";
+ OS << " OPERAND_LAST";
OS << "\n};\n";
OS << "} // end namespace OpName\n";
OS << "} // end namespace " << Namespace << "\n";
@@ -315,7 +315,7 @@ void InstrInfoEmitter::emitOperandNameMappings(raw_ostream &OS,
OS << " return OperandMap[" << TableIndex++ << "][NamedIdx];\n";
}
- OS << " default: return -1;\n";
+ OS << " default: return -1;\n";
OS << " }\n";
} else {
// There are no operands, so no need to emit anything
@@ -370,7 +370,7 @@ void InstrInfoEmitter::emitOperandTypeMappings(
OS << "namespace " << Namespace << " {\n";
OS << "LLVM_READONLY\n";
OS << "static int getOperandType(uint16_t Opcode, uint16_t OpIdx) {\n";
- // TODO: Factor out duplicate operand lists to compress the tables.
+ // TODO: Factor out duplicate operand lists to compress the tables.
if (!NumberedInstructions.empty()) {
std::vector<int> OperandOffsets;
std::vector<Record *> OperandRecords;
@@ -384,7 +384,7 @@ void InstrInfoEmitter::emitOperandTypeMappings(
OperandRecords.push_back(Op.Rec);
++CurrentOffset;
} else {
- for (Init *Arg : MIOI->getArgs()) {
+ for (Init *Arg : MIOI->getArgs()) {
OperandRecords.push_back(cast<DefInit>(Arg)->getDef());
++CurrentOffset;
}
@@ -392,26 +392,26 @@ void InstrInfoEmitter::emitOperandTypeMappings(
}
}
- // Emit the table of offsets (indexes) into the operand type table.
- // Size the unsigned integer offset to save space.
- assert(OperandRecords.size() <= UINT32_MAX &&
- "Too many operands for offset table");
- OS << ((OperandRecords.size() <= UINT16_MAX) ? " const uint16_t"
- : " const uint32_t");
- OS << " Offsets[] = {\n";
+ // Emit the table of offsets (indexes) into the operand type table.
+ // Size the unsigned integer offset to save space.
+ assert(OperandRecords.size() <= UINT32_MAX &&
+ "Too many operands for offset table");
+ OS << ((OperandRecords.size() <= UINT16_MAX) ? " const uint16_t"
+ : " const uint32_t");
+ OS << " Offsets[] = {\n";
for (int I = 0, E = OperandOffsets.size(); I != E; ++I)
OS << " " << OperandOffsets[I] << ",\n";
OS << " };\n";
// Add an entry for the end so that we don't need to special case it below.
OperandOffsets.push_back(OperandRecords.size());
-
+
// Emit the actual operand types in a flat table.
- // Size the signed integer operand type to save space.
- assert(EnumVal <= INT16_MAX &&
- "Too many operand types for operand types table");
- OS << ((EnumVal <= INT8_MAX) ? " const int8_t" : " const int16_t");
- OS << " OpcodeOperandTypes[] = {\n ";
+ // Size the signed integer operand type to save space.
+ assert(EnumVal <= INT16_MAX &&
+ "Too many operand types for operand types table");
+ OS << ((EnumVal <= INT8_MAX) ? " const int8_t" : " const int16_t");
+ OS << " OpcodeOperandTypes[] = {\n ";
for (int I = 0, E = OperandRecords.size(), CurOffset = 1; I != E; ++I) {
// We print each Opcode's operands in its own row.
if (I == OperandOffsets[CurOffset]) {
@@ -541,7 +541,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
unsigned ListNumber = 0;
// Emit all of the instruction's implicit uses and defs.
- Records.startTimer("Emit uses/defs");
+ Records.startTimer("Emit uses/defs");
for (const CodeGenInstruction *II : Target.getInstructionsByEnumValue()) {
Record *Inst = II->TheDef;
std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses");
@@ -559,12 +559,12 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
OperandInfoMapTy OperandInfoIDs;
// Emit all of the operand info records.
- Records.startTimer("Emit operand info");
+ Records.startTimer("Emit operand info");
EmitOperandInfo(OS, OperandInfoIDs);
// Emit all of the MCInstrDesc records in their ENUM ordering.
//
- Records.startTimer("Emit InstrDesc records");
+ Records.startTimer("Emit InstrDesc records");
OS << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n";
ArrayRef<const CodeGenInstruction*> NumberedInstructions =
Target.getInstructionsByEnumValue();
@@ -580,7 +580,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
OS << "};\n\n";
// Emit the array of instruction names.
- Records.startTimer("Emit instruction names");
+ Records.startTimer("Emit instruction names");
InstrNames.layout();
InstrNames.emitStringLiteralDef(OS, Twine("extern const char ") + TargetName +
"InstrNameData[]");
@@ -641,7 +641,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
}
// MCInstrInfo initialization routine.
- Records.startTimer("Emit initialization routine");
+ Records.startTimer("Emit initialization routine");
OS << "static inline void Init" << TargetName
<< "MCInstrInfo(MCInstrInfo *II) {\n";
OS << " II->InitMCInstrInfo(" << TargetName << "Insts, " << TargetName
@@ -720,13 +720,13 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n";
- Records.startTimer("Emit operand name mappings");
+ Records.startTimer("Emit operand name mappings");
emitOperandNameMappings(OS, Target, NumberedInstructions);
- Records.startTimer("Emit operand type mappings");
+ Records.startTimer("Emit operand type mappings");
emitOperandTypeMappings(OS, Target, NumberedInstructions);
- Records.startTimer("Emit helper methods");
+ Records.startTimer("Emit helper methods");
emitMCIIHelperMethods(OS, TargetName);
}
@@ -879,9 +879,9 @@ void InstrInfoEmitter::emitEnums(raw_ostream &OS) {
namespace llvm {
void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) {
- RK.startTimer("Analyze DAG patterns");
+ RK.startTimer("Analyze DAG patterns");
InstrInfoEmitter(RK).run(OS);
- RK.startTimer("Emit map table");
+ RK.startTimer("Emit map table");
EmitMapTable(RK, OS);
}
diff --git a/contrib/libs/llvm12/utils/TableGen/IntrinsicEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/IntrinsicEmitter.cpp
index 5b199c55a3..978d24c830 100644
--- a/contrib/libs/llvm12/utils/TableGen/IntrinsicEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/IntrinsicEmitter.cpp
@@ -246,16 +246,16 @@ enum IIT_Info {
IIT_SUBDIVIDE4_ARG = 45,
IIT_VEC_OF_BITCASTS_TO_INT = 46,
IIT_V128 = 47,
- IIT_BF16 = 48,
- IIT_STRUCT9 = 49,
- IIT_V256 = 50,
- IIT_AMX = 51
+ IIT_BF16 = 48,
+ IIT_STRUCT9 = 49,
+ IIT_V256 = 50,
+ IIT_AMX = 51
};
static void EncodeFixedValueType(MVT::SimpleValueType VT,
std::vector<unsigned char> &Sig) {
if (MVT(VT).isInteger()) {
- unsigned BitWidth = MVT(VT).getFixedSizeInBits();
+ unsigned BitWidth = MVT(VT).getFixedSizeInBits();
switch (BitWidth) {
default: PrintFatalError("unhandled integer type width in intrinsic!");
case 1: return Sig.push_back(IIT_I1);
@@ -277,7 +277,7 @@ static void EncodeFixedValueType(MVT::SimpleValueType VT,
case MVT::token: return Sig.push_back(IIT_TOKEN);
case MVT::Metadata: return Sig.push_back(IIT_METADATA);
case MVT::x86mmx: return Sig.push_back(IIT_MMX);
- case MVT::x86amx: return Sig.push_back(IIT_AMX);
+ case MVT::x86amx: return Sig.push_back(IIT_AMX);
// MVT::OtherVT is used to mean the empty struct type here.
case MVT::Other: return Sig.push_back(IIT_EMPTYSTRUCT);
// MVT::isVoid is used to represent varargs here.
@@ -388,7 +388,7 @@ static void EncodeFixedType(Record *R, std::vector<unsigned char> &ArgCodes,
case 32: Sig.push_back(IIT_V32); break;
case 64: Sig.push_back(IIT_V64); break;
case 128: Sig.push_back(IIT_V128); break;
- case 256: Sig.push_back(IIT_V256); break;
+ case 256: Sig.push_back(IIT_V256); break;
case 512: Sig.push_back(IIT_V512); break;
case 1024: Sig.push_back(IIT_V1024); break;
}
@@ -474,7 +474,7 @@ static void ComputeFixedEncoding(const CodeGenIntrinsic &Int,
case 6: TypeSig.push_back(IIT_STRUCT6); break;
case 7: TypeSig.push_back(IIT_STRUCT7); break;
case 8: TypeSig.push_back(IIT_STRUCT8); break;
- case 9: TypeSig.push_back(IIT_STRUCT9); break;
+ case 9: TypeSig.push_back(IIT_STRUCT9); break;
default: llvm_unreachable("Unhandled case in struct");
}
@@ -639,12 +639,12 @@ void IntrinsicEmitter::EmitAttributes(const CodeGenIntrinsicTable &Ints,
unsigned &N = UniqAttributes[&intrinsic];
if (N) continue;
N = ++AttrNum;
- assert(N < 65536 && "Too many unique attributes for table!");
+ assert(N < 65536 && "Too many unique attributes for table!");
}
// Emit an array of AttributeList. Most intrinsics will have at least one
// entry, for the function itself (index ~1), which is usually nounwind.
- OS << " static const uint16_t IntrinsicsToAttributesMap[] = {\n";
+ OS << " static const uint16_t IntrinsicsToAttributesMap[] = {\n";
for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
const CodeGenIntrinsic &intrinsic = Ints[i];
@@ -693,12 +693,12 @@ void IntrinsicEmitter::EmitAttributes(const CodeGenIntrinsicTable &Ints,
OS << "Attribute::NoAlias";
addComma = true;
break;
- case CodeGenIntrinsic::NoUndef:
- if (addComma)
- OS << ",";
- OS << "Attribute::NoUndef";
- addComma = true;
- break;
+ case CodeGenIntrinsic::NoUndef:
+ if (addComma)
+ OS << ",";
+ OS << "Attribute::NoUndef";
+ addComma = true;
+ break;
case CodeGenIntrinsic::Returned:
if (addComma)
OS << ",";
diff --git a/contrib/libs/llvm12/utils/TableGen/OptParserEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/OptParserEmitter.cpp
index 292ee49a8a..8e6c05885e 100644
--- a/contrib/libs/llvm12/utils/TableGen/OptParserEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/OptParserEmitter.cpp
@@ -20,7 +20,7 @@
using namespace llvm;
-static std::string getOptionName(const Record &R) {
+static std::string getOptionName(const Record &R) {
// Use the record name unless EnumName is defined.
if (isa<UnsetInit>(R.getValueInit("EnumName")))
return std::string(R.getName());
@@ -35,20 +35,20 @@ static raw_ostream &write_cstring(raw_ostream &OS, llvm::StringRef Str) {
return OS;
}
-static std::string getOptionSpelling(const Record &R, size_t &PrefixLength) {
+static std::string getOptionSpelling(const Record &R, size_t &PrefixLength) {
std::vector<StringRef> Prefixes = R.getValueAsListOfStrings("Prefixes");
StringRef Name = R.getValueAsString("Name");
-
+
if (Prefixes.empty()) {
PrefixLength = 0;
return Name.str();
}
-
+
PrefixLength = Prefixes[0].size();
return (Twine(Prefixes[0]) + Twine(Name)).str();
}
-static std::string getOptionSpelling(const Record &R) {
+static std::string getOptionSpelling(const Record &R) {
size_t PrefixLength;
return getOptionSpelling(R, PrefixLength);
}
@@ -60,29 +60,29 @@ static void emitNameUsingSpelling(raw_ostream &OS, const Record &R) {
OS << "[" << PrefixLength << "]";
}
-class MarshallingInfo {
+class MarshallingInfo {
public:
- static constexpr const char *MacroName = "OPTION_WITH_MARSHALLING";
+ static constexpr const char *MacroName = "OPTION_WITH_MARSHALLING";
const Record &R;
bool ShouldAlwaysEmit;
- StringRef MacroPrefix;
+ StringRef MacroPrefix;
StringRef KeyPath;
StringRef DefaultValue;
StringRef NormalizedValuesScope;
- StringRef ImpliedCheck;
- StringRef ImpliedValue;
- StringRef ShouldParse;
+ StringRef ImpliedCheck;
+ StringRef ImpliedValue;
+ StringRef ShouldParse;
StringRef Normalizer;
StringRef Denormalizer;
- StringRef ValueMerger;
- StringRef ValueExtractor;
+ StringRef ValueMerger;
+ StringRef ValueExtractor;
int TableIndex = -1;
std::vector<StringRef> Values;
std::vector<StringRef> NormalizedValues;
std::string ValueTableName;
- static size_t NextTableIndex;
-
+ static size_t NextTableIndex;
+
static constexpr const char *ValueTablePreamble = R"(
struct SimpleEnumValue {
const char *Name;
@@ -98,39 +98,39 @@ struct SimpleEnumValueTable {
static constexpr const char *ValueTablesDecl =
"static const SimpleEnumValueTable SimpleEnumValueTables[] = ";
- MarshallingInfo(const Record &R) : R(R) {}
-
- std::string getMacroName() const {
- return (MacroPrefix + MarshallingInfo::MacroName).str();
- }
-
- void emit(raw_ostream &OS) const {
- write_cstring(OS, StringRef(getOptionSpelling(R)));
+ MarshallingInfo(const Record &R) : R(R) {}
+
+ std::string getMacroName() const {
+ return (MacroPrefix + MarshallingInfo::MacroName).str();
+ }
+
+ void emit(raw_ostream &OS) const {
+ write_cstring(OS, StringRef(getOptionSpelling(R)));
+ OS << ", ";
+ OS << ShouldParse;
+ OS << ", ";
+ OS << ShouldAlwaysEmit;
+ OS << ", ";
+ OS << KeyPath;
+ OS << ", ";
+ emitScopedNormalizedValue(OS, DefaultValue);
+ OS << ", ";
+ OS << ImpliedCheck;
+ OS << ", ";
+ emitScopedNormalizedValue(OS, ImpliedValue);
OS << ", ";
- OS << ShouldParse;
- OS << ", ";
- OS << ShouldAlwaysEmit;
- OS << ", ";
- OS << KeyPath;
- OS << ", ";
- emitScopedNormalizedValue(OS, DefaultValue);
- OS << ", ";
- OS << ImpliedCheck;
- OS << ", ";
- emitScopedNormalizedValue(OS, ImpliedValue);
- OS << ", ";
OS << Normalizer;
OS << ", ";
OS << Denormalizer;
OS << ", ";
- OS << ValueMerger;
- OS << ", ";
- OS << ValueExtractor;
- OS << ", ";
+ OS << ValueMerger;
+ OS << ", ";
+ OS << ValueExtractor;
+ OS << ", ";
OS << TableIndex;
}
- Optional<StringRef> emitValueTable(raw_ostream &OS) const {
+ Optional<StringRef> emitValueTable(raw_ostream &OS) const {
if (TableIndex == -1)
return {};
OS << "static const SimpleEnumValue " << ValueTableName << "[] = {\n";
@@ -146,64 +146,64 @@ struct SimpleEnumValueTable {
return StringRef(ValueTableName);
}
-private:
- void emitScopedNormalizedValue(raw_ostream &OS,
- StringRef NormalizedValue) const {
- if (!NormalizedValuesScope.empty())
- OS << NormalizedValuesScope << "::";
- OS << NormalizedValue;
- }
-};
-
-size_t MarshallingInfo::NextTableIndex = 0;
-
-static MarshallingInfo createMarshallingInfo(const Record &R) {
- assert(!isa<UnsetInit>(R.getValueInit("KeyPath")) &&
- !isa<UnsetInit>(R.getValueInit("DefaultValue")) &&
- !isa<UnsetInit>(R.getValueInit("ValueMerger")) &&
- "MarshallingInfo must have a provide a keypath, default value and a "
- "value merger");
-
- MarshallingInfo Ret(R);
-
- Ret.ShouldAlwaysEmit = R.getValueAsBit("ShouldAlwaysEmit");
- Ret.MacroPrefix = R.getValueAsString("MacroPrefix");
- Ret.KeyPath = R.getValueAsString("KeyPath");
- Ret.DefaultValue = R.getValueAsString("DefaultValue");
- Ret.NormalizedValuesScope = R.getValueAsString("NormalizedValuesScope");
- Ret.ImpliedCheck = R.getValueAsString("ImpliedCheck");
- Ret.ImpliedValue =
- R.getValueAsOptionalString("ImpliedValue").getValueOr(Ret.DefaultValue);
-
- Ret.ShouldParse = R.getValueAsString("ShouldParse");
- Ret.Normalizer = R.getValueAsString("Normalizer");
- Ret.Denormalizer = R.getValueAsString("Denormalizer");
- Ret.ValueMerger = R.getValueAsString("ValueMerger");
- Ret.ValueExtractor = R.getValueAsString("ValueExtractor");
-
- if (!isa<UnsetInit>(R.getValueInit("NormalizedValues"))) {
- assert(!isa<UnsetInit>(R.getValueInit("Values")) &&
- "Cannot provide normalized values for value-less options");
- Ret.TableIndex = MarshallingInfo::NextTableIndex++;
- Ret.NormalizedValues = R.getValueAsListOfStrings("NormalizedValues");
- Ret.Values.reserve(Ret.NormalizedValues.size());
- Ret.ValueTableName = getOptionName(R) + "ValueTable";
-
- StringRef ValuesStr = R.getValueAsString("Values");
- for (;;) {
- size_t Idx = ValuesStr.find(',');
- if (Idx == StringRef::npos)
- break;
- if (Idx > 0)
- Ret.Values.push_back(ValuesStr.slice(0, Idx));
- ValuesStr = ValuesStr.slice(Idx + 1, StringRef::npos);
+private:
+ void emitScopedNormalizedValue(raw_ostream &OS,
+ StringRef NormalizedValue) const {
+ if (!NormalizedValuesScope.empty())
+ OS << NormalizedValuesScope << "::";
+ OS << NormalizedValue;
+ }
+};
+
+size_t MarshallingInfo::NextTableIndex = 0;
+
+static MarshallingInfo createMarshallingInfo(const Record &R) {
+ assert(!isa<UnsetInit>(R.getValueInit("KeyPath")) &&
+ !isa<UnsetInit>(R.getValueInit("DefaultValue")) &&
+ !isa<UnsetInit>(R.getValueInit("ValueMerger")) &&
+ "MarshallingInfo must have a provide a keypath, default value and a "
+ "value merger");
+
+ MarshallingInfo Ret(R);
+
+ Ret.ShouldAlwaysEmit = R.getValueAsBit("ShouldAlwaysEmit");
+ Ret.MacroPrefix = R.getValueAsString("MacroPrefix");
+ Ret.KeyPath = R.getValueAsString("KeyPath");
+ Ret.DefaultValue = R.getValueAsString("DefaultValue");
+ Ret.NormalizedValuesScope = R.getValueAsString("NormalizedValuesScope");
+ Ret.ImpliedCheck = R.getValueAsString("ImpliedCheck");
+ Ret.ImpliedValue =
+ R.getValueAsOptionalString("ImpliedValue").getValueOr(Ret.DefaultValue);
+
+ Ret.ShouldParse = R.getValueAsString("ShouldParse");
+ Ret.Normalizer = R.getValueAsString("Normalizer");
+ Ret.Denormalizer = R.getValueAsString("Denormalizer");
+ Ret.ValueMerger = R.getValueAsString("ValueMerger");
+ Ret.ValueExtractor = R.getValueAsString("ValueExtractor");
+
+ if (!isa<UnsetInit>(R.getValueInit("NormalizedValues"))) {
+ assert(!isa<UnsetInit>(R.getValueInit("Values")) &&
+ "Cannot provide normalized values for value-less options");
+ Ret.TableIndex = MarshallingInfo::NextTableIndex++;
+ Ret.NormalizedValues = R.getValueAsListOfStrings("NormalizedValues");
+ Ret.Values.reserve(Ret.NormalizedValues.size());
+ Ret.ValueTableName = getOptionName(R) + "ValueTable";
+
+ StringRef ValuesStr = R.getValueAsString("Values");
+ for (;;) {
+ size_t Idx = ValuesStr.find(',');
+ if (Idx == StringRef::npos)
+ break;
+ if (Idx > 0)
+ Ret.Values.push_back(ValuesStr.slice(0, Idx));
+ ValuesStr = ValuesStr.slice(Idx + 1, StringRef::npos);
}
- if (!ValuesStr.empty())
- Ret.Values.push_back(ValuesStr);
+ if (!ValuesStr.empty())
+ Ret.Values.push_back(ValuesStr);
- assert(Ret.Values.size() == Ret.NormalizedValues.size() &&
- "The number of normalized values doesn't match the number of "
- "values");
+ assert(Ret.Values.size() == Ret.NormalizedValues.size() &&
+ "The number of normalized values doesn't match the number of "
+ "values");
}
return Ret;
@@ -228,12 +228,12 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
PrefixesT Prefixes;
Prefixes.insert(std::make_pair(PrefixKeyT(), "prefix_0"));
unsigned CurPrefix = 0;
- for (const Record &R : llvm::make_pointee_range(Opts)) {
- std::vector<StringRef> RPrefixes = R.getValueAsListOfStrings("Prefixes");
- PrefixKeyT PrefixKey(RPrefixes.begin(), RPrefixes.end());
+ for (const Record &R : llvm::make_pointee_range(Opts)) {
+ std::vector<StringRef> RPrefixes = R.getValueAsListOfStrings("Prefixes");
+ PrefixKeyT PrefixKey(RPrefixes.begin(), RPrefixes.end());
unsigned NewPrefix = CurPrefix + 1;
- std::string Prefix = (Twine("prefix_") + Twine(NewPrefix)).str();
- if (Prefixes.insert(std::make_pair(PrefixKey, Prefix)).second)
+ std::string Prefix = (Twine("prefix_") + Twine(NewPrefix)).str();
+ if (Prefixes.insert(std::make_pair(PrefixKey, Prefix)).second)
CurPrefix = NewPrefix;
}
@@ -243,16 +243,16 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
OS << "// Prefixes\n\n";
OS << "#ifdef PREFIX\n";
OS << "#define COMMA ,\n";
- for (const auto &Prefix : Prefixes) {
+ for (const auto &Prefix : Prefixes) {
OS << "PREFIX(";
// Prefix name.
- OS << Prefix.second;
+ OS << Prefix.second;
// Prefix values.
OS << ", {";
- for (StringRef PrefixKey : Prefix.first)
- OS << "\"" << PrefixKey << "\" COMMA ";
+ for (StringRef PrefixKey : Prefix.first)
+ OS << "\"" << PrefixKey << "\" COMMA ";
OS << "nullptr})\n";
}
OS << "#undef COMMA\n";
@@ -261,7 +261,7 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
OS << "/////////\n";
OS << "// Groups\n\n";
OS << "#ifdef OPTION\n";
- for (const Record &R : llvm::make_pointee_range(Groups)) {
+ for (const Record &R : llvm::make_pointee_range(Groups)) {
// Start a single option entry.
OS << "OPTION(";
@@ -308,8 +308,8 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
auto WriteOptRecordFields = [&](raw_ostream &OS, const Record &R) {
// The option prefix;
- std::vector<StringRef> RPrefixes = R.getValueAsListOfStrings("Prefixes");
- OS << Prefixes[PrefixKeyT(RPrefixes.begin(), RPrefixes.end())] << ", ";
+ std::vector<StringRef> RPrefixes = R.getValueAsListOfStrings("Prefixes");
+ OS << Prefixes[PrefixKeyT(RPrefixes.begin(), RPrefixes.end())] << ", ";
// The option string.
emitNameUsingSpelling(OS, R);
@@ -346,8 +346,8 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
OS << "nullptr";
} else {
OS << "\"";
- for (StringRef AliasArg : AliasArgs)
- OS << AliasArg << "\\0";
+ for (StringRef AliasArg : AliasArgs)
+ OS << AliasArg << "\\0";
OS << "\"";
}
@@ -391,63 +391,63 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
OS << "nullptr";
};
- auto IsMarshallingOption = [](const Record &R) {
- return !isa<UnsetInit>(R.getValueInit("KeyPath")) &&
- !R.getValueAsString("KeyPath").empty();
- };
+ auto IsMarshallingOption = [](const Record &R) {
+ return !isa<UnsetInit>(R.getValueInit("KeyPath")) &&
+ !R.getValueAsString("KeyPath").empty();
+ };
- std::vector<const Record *> OptsWithMarshalling;
- for (const Record &R : llvm::make_pointee_range(Opts)) {
+ std::vector<const Record *> OptsWithMarshalling;
+ for (const Record &R : llvm::make_pointee_range(Opts)) {
// Start a single option entry.
OS << "OPTION(";
WriteOptRecordFields(OS, R);
OS << ")\n";
- if (IsMarshallingOption(R))
- OptsWithMarshalling.push_back(&R);
+ if (IsMarshallingOption(R))
+ OptsWithMarshalling.push_back(&R);
}
OS << "#endif // OPTION\n";
- auto CmpMarshallingOpts = [](const Record *const *A, const Record *const *B) {
- unsigned AID = (*A)->getID();
- unsigned BID = (*B)->getID();
-
- if (AID < BID)
- return -1;
- if (AID > BID)
- return 1;
- return 0;
- };
- // The RecordKeeper stores records (options) in lexicographical order, and we
- // have reordered the options again when generating prefix groups. We need to
- // restore the original definition order of options with marshalling to honor
- // the topology of the dependency graph implied by `DefaultAnyOf`.
- array_pod_sort(OptsWithMarshalling.begin(), OptsWithMarshalling.end(),
- CmpMarshallingOpts);
-
- std::vector<MarshallingInfo> MarshallingInfos;
- for (const auto *R : OptsWithMarshalling)
- MarshallingInfos.push_back(createMarshallingInfo(*R));
-
- for (const auto &MI : MarshallingInfos) {
- OS << "#ifdef " << MI.getMacroName() << "\n";
- OS << MI.getMacroName() << "(";
- WriteOptRecordFields(OS, MI.R);
+ auto CmpMarshallingOpts = [](const Record *const *A, const Record *const *B) {
+ unsigned AID = (*A)->getID();
+ unsigned BID = (*B)->getID();
+
+ if (AID < BID)
+ return -1;
+ if (AID > BID)
+ return 1;
+ return 0;
+ };
+ // The RecordKeeper stores records (options) in lexicographical order, and we
+ // have reordered the options again when generating prefix groups. We need to
+ // restore the original definition order of options with marshalling to honor
+ // the topology of the dependency graph implied by `DefaultAnyOf`.
+ array_pod_sort(OptsWithMarshalling.begin(), OptsWithMarshalling.end(),
+ CmpMarshallingOpts);
+
+ std::vector<MarshallingInfo> MarshallingInfos;
+ for (const auto *R : OptsWithMarshalling)
+ MarshallingInfos.push_back(createMarshallingInfo(*R));
+
+ for (const auto &MI : MarshallingInfos) {
+ OS << "#ifdef " << MI.getMacroName() << "\n";
+ OS << MI.getMacroName() << "(";
+ WriteOptRecordFields(OS, MI.R);
OS << ", ";
- MI.emit(OS);
+ MI.emit(OS);
OS << ")\n";
- OS << "#endif // " << MI.getMacroName() << "\n";
+ OS << "#endif // " << MI.getMacroName() << "\n";
}
OS << "\n";
OS << "#ifdef SIMPLE_ENUM_VALUE_TABLE";
OS << "\n";
- OS << MarshallingInfo::ValueTablePreamble;
+ OS << MarshallingInfo::ValueTablePreamble;
std::vector<StringRef> ValueTableNames;
- for (const auto &MI : MarshallingInfos)
- if (auto MaybeValueTableName = MI.emitValueTable(OS))
+ for (const auto &MI : MarshallingInfos)
+ if (auto MaybeValueTableName = MI.emitValueTable(OS))
ValueTableNames.push_back(*MaybeValueTableName);
- OS << MarshallingInfo::ValueTablesDecl << "{";
+ OS << MarshallingInfo::ValueTablesDecl << "{";
for (auto ValueTableName : ValueTableNames)
OS << "{" << ValueTableName << ", sizeof(" << ValueTableName
<< ") / sizeof(SimpleEnumValue)"
@@ -463,7 +463,7 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
OS << "#ifdef OPTTABLE_ARG_INIT\n";
OS << "//////////\n";
OS << "// Option Values\n\n";
- for (const Record &R : llvm::make_pointee_range(Opts)) {
+ for (const Record &R : llvm::make_pointee_range(Opts)) {
if (isa<UnsetInit>(R.getValueInit("ValuesCode")))
continue;
OS << "{\n";
diff --git a/contrib/libs/llvm12/utils/TableGen/PredicateExpander.cpp b/contrib/libs/llvm12/utils/TableGen/PredicateExpander.cpp
index 1bff258abd..a76640f6d1 100644
--- a/contrib/libs/llvm12/utils/TableGen/PredicateExpander.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/PredicateExpander.cpp
@@ -198,18 +198,18 @@ void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) {
<< "getOperand(" << OpIndex << ").isImm() ";
}
-void PredicateExpander::expandCheckFunctionPredicateWithTII(
- raw_ostream &OS, StringRef MCInstFn, StringRef MachineInstrFn,
- StringRef TIIPtr) {
- if (!shouldExpandForMC()) {
- OS << (TIIPtr.empty() ? "TII" : TIIPtr) << "->" << MachineInstrFn;
- OS << (isByRef() ? "(MI)" : "(*MI)");
- return;
- }
-
- OS << MCInstFn << (isByRef() ? "(MI" : "(*MI") << ", MCII)";
-}
-
+void PredicateExpander::expandCheckFunctionPredicateWithTII(
+ raw_ostream &OS, StringRef MCInstFn, StringRef MachineInstrFn,
+ StringRef TIIPtr) {
+ if (!shouldExpandForMC()) {
+ OS << (TIIPtr.empty() ? "TII" : TIIPtr) << "->" << MachineInstrFn;
+ OS << (isByRef() ? "(MI)" : "(*MI)");
+ return;
+ }
+
+ OS << MCInstFn << (isByRef() ? "(MI" : "(*MI") << ", MCII)";
+}
+
void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS,
StringRef MCInstFn,
StringRef MachineInstrFn) {
@@ -370,19 +370,19 @@ void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) {
return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
/* AllOf */ false);
- if (Rec->isSubClassOf("CheckFunctionPredicate")) {
+ if (Rec->isSubClassOf("CheckFunctionPredicate")) {
return expandCheckFunctionPredicate(
OS, Rec->getValueAsString("MCInstFnName"),
Rec->getValueAsString("MachineInstrFnName"));
- }
-
- if (Rec->isSubClassOf("CheckFunctionPredicateWithTII")) {
- return expandCheckFunctionPredicateWithTII(
- OS, Rec->getValueAsString("MCInstFnName"),
- Rec->getValueAsString("MachineInstrFnName"),
- Rec->getValueAsString("TIIPtrName"));
- }
-
+ }
+
+ if (Rec->isSubClassOf("CheckFunctionPredicateWithTII")) {
+ return expandCheckFunctionPredicateWithTII(
+ OS, Rec->getValueAsString("MCInstFnName"),
+ Rec->getValueAsString("MachineInstrFnName"),
+ Rec->getValueAsString("TIIPtrName"));
+ }
+
if (Rec->isSubClassOf("CheckNonPortable"))
return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock"));
diff --git a/contrib/libs/llvm12/utils/TableGen/PredicateExpander.h b/contrib/libs/llvm12/utils/TableGen/PredicateExpander.h
index 06925d413d..29cca92d90 100644
--- a/contrib/libs/llvm12/utils/TableGen/PredicateExpander.h
+++ b/contrib/libs/llvm12/utils/TableGen/PredicateExpander.h
@@ -79,9 +79,9 @@ public:
void expandCheckInvalidRegOperand(raw_ostream &OS, int OpIndex);
void expandCheckFunctionPredicate(raw_ostream &OS, StringRef MCInstFn,
StringRef MachineInstrFn);
- void expandCheckFunctionPredicateWithTII(raw_ostream &OS, StringRef MCInstFn,
- StringRef MachineInstrFn,
- StringRef TIIPtr);
+ void expandCheckFunctionPredicateWithTII(raw_ostream &OS, StringRef MCInstFn,
+ StringRef MachineInstrFn,
+ StringRef TIIPtr);
void expandCheckNonPortable(raw_ostream &OS, StringRef CodeBlock);
void expandPredicate(raw_ostream &OS, const Record *Rec);
void expandReturnStatement(raw_ostream &OS, const Record *Rec);
diff --git a/contrib/libs/llvm12/utils/TableGen/PseudoLoweringEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/PseudoLoweringEmitter.cpp
index 7569326cb3..e05409db67 100644
--- a/contrib/libs/llvm12/utils/TableGen/PseudoLoweringEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/PseudoLoweringEmitter.cpp
@@ -89,15 +89,15 @@ addDagOperandMapping(Record *Rec, DagInit *Dag, CodeGenInstruction &Insn,
// problem.
// FIXME: We probably shouldn't ever get a non-zero BaseIdx here.
assert(BaseIdx == 0 && "Named subargument in pseudo expansion?!");
- // FIXME: Are the message operand types backward?
- if (DI->getDef() != Insn.Operands[BaseIdx + i].Rec) {
- PrintError(Rec, "In pseudo instruction '" + Rec->getName() +
- "', operand type '" + DI->getDef()->getName() +
- "' does not match expansion operand type '" +
- Insn.Operands[BaseIdx + i].Rec->getName() + "'");
- PrintFatalNote(DI->getDef(),
- "Value was assigned at the following location:");
- }
+ // FIXME: Are the message operand types backward?
+ if (DI->getDef() != Insn.Operands[BaseIdx + i].Rec) {
+ PrintError(Rec, "In pseudo instruction '" + Rec->getName() +
+ "', operand type '" + DI->getDef()->getName() +
+ "' does not match expansion operand type '" +
+ Insn.Operands[BaseIdx + i].Rec->getName() + "'");
+ PrintFatalNote(DI->getDef(),
+ "Value was assigned at the following location:");
+ }
// Source operand maps to destination operand. The Data element
// will be filled in later, just set the Kind for now. Do it
// for each corresponding MachineInstr operand, not just the first.
@@ -132,38 +132,38 @@ void PseudoLoweringEmitter::evaluateExpansion(Record *Rec) {
LLVM_DEBUG(dbgs() << " Result: " << *Dag << "\n");
DefInit *OpDef = dyn_cast<DefInit>(Dag->getOperator());
- if (!OpDef) {
- PrintError(Rec, "In pseudo instruction '" + Rec->getName() +
- "', result operator is not a record");
- PrintFatalNote(Rec->getValue("ResultInst"),
- "Result was assigned at the following location:");
- }
+ if (!OpDef) {
+ PrintError(Rec, "In pseudo instruction '" + Rec->getName() +
+ "', result operator is not a record");
+ PrintFatalNote(Rec->getValue("ResultInst"),
+ "Result was assigned at the following location:");
+ }
Record *Operator = OpDef->getDef();
- if (!Operator->isSubClassOf("Instruction")) {
- PrintError(Rec, "In pseudo instruction '" + Rec->getName() +
- "', result operator '" + Operator->getName() +
- "' is not an instruction");
- PrintFatalNote(Rec->getValue("ResultInst"),
- "Result was assigned at the following location:");
- }
+ if (!Operator->isSubClassOf("Instruction")) {
+ PrintError(Rec, "In pseudo instruction '" + Rec->getName() +
+ "', result operator '" + Operator->getName() +
+ "' is not an instruction");
+ PrintFatalNote(Rec->getValue("ResultInst"),
+ "Result was assigned at the following location:");
+ }
CodeGenInstruction Insn(Operator);
- if (Insn.isCodeGenOnly || Insn.isPseudo) {
- PrintError(Rec, "In pseudo instruction '" + Rec->getName() +
- "', result operator '" + Operator->getName() +
- "' cannot be a pseudo instruction");
- PrintFatalNote(Rec->getValue("ResultInst"),
- "Result was assigned at the following location:");
- }
-
- if (Insn.Operands.size() != Dag->getNumArgs()) {
- PrintError(Rec, "In pseudo instruction '" + Rec->getName() +
- "', result operator '" + Operator->getName() +
- "' has the wrong number of operands");
- PrintFatalNote(Rec->getValue("ResultInst"),
- "Result was assigned at the following location:");
- }
+ if (Insn.isCodeGenOnly || Insn.isPseudo) {
+ PrintError(Rec, "In pseudo instruction '" + Rec->getName() +
+ "', result operator '" + Operator->getName() +
+ "' cannot be a pseudo instruction");
+ PrintFatalNote(Rec->getValue("ResultInst"),
+ "Result was assigned at the following location:");
+ }
+
+ if (Insn.Operands.size() != Dag->getNumArgs()) {
+ PrintError(Rec, "In pseudo instruction '" + Rec->getName() +
+ "', result operator '" + Operator->getName() +
+ "' has the wrong number of operands");
+ PrintFatalNote(Rec->getValue("ResultInst"),
+ "Result was assigned at the following location:");
+ }
unsigned NumMIOperands = 0;
for (unsigned i = 0, e = Insn.Operands.size(); i != e; ++i)
@@ -196,13 +196,13 @@ void PseudoLoweringEmitter::evaluateExpansion(Record *Rec) {
continue;
StringMap<unsigned>::iterator SourceOp =
SourceOperands.find(Dag->getArgNameStr(i));
- if (SourceOp == SourceOperands.end()) {
- PrintError(Rec, "In pseudo instruction '" + Rec->getName() +
- "', output operand '" + Dag->getArgNameStr(i) +
- "' has no matching source operand");
- PrintFatalNote(Rec->getValue("ResultInst"),
- "Value was assigned at the following location:");
- }
+ if (SourceOp == SourceOperands.end()) {
+ PrintError(Rec, "In pseudo instruction '" + Rec->getName() +
+ "', output operand '" + Dag->getArgNameStr(i) +
+ "' has no matching source operand");
+ PrintFatalNote(Rec->getValue("ResultInst"),
+ "Value was assigned at the following location:");
+ }
// Map the source operand to the destination operand index for each
// MachineInstr operand.
for (unsigned I = 0, E = Insn.Operands[i].MINumOperands; I != E; ++I)
@@ -226,15 +226,15 @@ void PseudoLoweringEmitter::emitLoweringEmitter(raw_ostream &o) {
if (!Expansions.empty()) {
o << " switch (MI->getOpcode()) {\n"
- << " default: return false;\n";
+ << " default: return false;\n";
for (auto &Expansion : Expansions) {
CodeGenInstruction &Source = Expansion.Source;
CodeGenInstruction &Dest = Expansion.Dest;
- o << " case " << Source.Namespace << "::"
+ o << " case " << Source.Namespace << "::"
<< Source.TheDef->getName() << ": {\n"
- << " MCInst TmpInst;\n"
- << " MCOperand MCOp;\n"
- << " TmpInst.setOpcode(" << Dest.Namespace << "::"
+ << " MCInst TmpInst;\n"
+ << " MCOperand MCOp;\n"
+ << " TmpInst.setOpcode(" << Dest.Namespace << "::"
<< Dest.TheDef->getName() << ");\n";
// Copy the operands from the source instruction.
@@ -243,23 +243,23 @@ void PseudoLoweringEmitter::emitLoweringEmitter(raw_ostream &o) {
// expansion DAG.
unsigned MIOpNo = 0;
for (const auto &DestOperand : Dest.Operands) {
- o << " // Operand: " << DestOperand.Name << "\n";
+ o << " // Operand: " << DestOperand.Name << "\n";
for (unsigned i = 0, e = DestOperand.MINumOperands; i != e; ++i) {
switch (Expansion.OperandMap[MIOpNo + i].Kind) {
case OpData::Operand:
- o << " lowerOperand(MI->getOperand("
+ o << " lowerOperand(MI->getOperand("
<< Source.Operands[Expansion.OperandMap[MIOpNo].Data
.Operand].MIOperandNo + i
<< "), MCOp);\n"
- << " TmpInst.addOperand(MCOp);\n";
+ << " TmpInst.addOperand(MCOp);\n";
break;
case OpData::Imm:
- o << " TmpInst.addOperand(MCOperand::createImm("
+ o << " TmpInst.addOperand(MCOperand::createImm("
<< Expansion.OperandMap[MIOpNo + i].Data.Imm << "));\n";
break;
case OpData::Reg: {
Record *Reg = Expansion.OperandMap[MIOpNo + i].Data.Reg;
- o << " TmpInst.addOperand(MCOperand::createReg(";
+ o << " TmpInst.addOperand(MCOperand::createReg(";
// "zero_reg" is special.
if (Reg->getName() == "zero_reg")
o << "0";
@@ -275,15 +275,15 @@ void PseudoLoweringEmitter::emitLoweringEmitter(raw_ostream &o) {
}
if (Dest.Operands.isVariadic) {
MIOpNo = Source.Operands.size() + 1;
- o << " // variable_ops\n";
- o << " for (unsigned i = " << MIOpNo
+ o << " // variable_ops\n";
+ o << " for (unsigned i = " << MIOpNo
<< ", e = MI->getNumOperands(); i != e; ++i)\n"
- << " if (lowerOperand(MI->getOperand(i), MCOp))\n"
- << " TmpInst.addOperand(MCOp);\n";
+ << " if (lowerOperand(MI->getOperand(i), MCOp))\n"
+ << " TmpInst.addOperand(MCOp);\n";
}
- o << " EmitToStreamer(OutStreamer, TmpInst);\n"
- << " break;\n"
- << " }\n";
+ o << " EmitToStreamer(OutStreamer, TmpInst);\n"
+ << " break;\n"
+ << " }\n";
}
o << " }\n return true;";
} else
@@ -293,18 +293,18 @@ void PseudoLoweringEmitter::emitLoweringEmitter(raw_ostream &o) {
}
void PseudoLoweringEmitter::run(raw_ostream &o) {
- StringRef Classes[] = {"PseudoInstExpansion", "Instruction"};
- std::vector<Record *> Insts =
- Records.getAllDerivedDefinitions(makeArrayRef(Classes));
+ StringRef Classes[] = {"PseudoInstExpansion", "Instruction"};
+ std::vector<Record *> Insts =
+ Records.getAllDerivedDefinitions(makeArrayRef(Classes));
// Process the pseudo expansion definitions, validating them as we do so.
- Records.startTimer("Process definitions");
+ Records.startTimer("Process definitions");
for (unsigned i = 0, e = Insts.size(); i != e; ++i)
evaluateExpansion(Insts[i]);
// Generate expansion code to lower the pseudo to an MCInst of the real
// instruction.
- Records.startTimer("Emit expansion code");
+ Records.startTimer("Emit expansion code");
emitLoweringEmitter(o);
}
diff --git a/contrib/libs/llvm12/utils/TableGen/RISCVCompressInstEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/RISCVCompressInstEmitter.cpp
index e3ec2c7f21..183c8f9494 100644
--- a/contrib/libs/llvm12/utils/TableGen/RISCVCompressInstEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/RISCVCompressInstEmitter.cpp
@@ -37,11 +37,11 @@
// compressing/uncompressing MCInst instructions, plus
// some helper functions:
//
-// bool compressInst(MCInst &OutInst, const MCInst &MI,
+// bool compressInst(MCInst &OutInst, const MCInst &MI,
// const MCSubtargetInfo &STI,
// MCContext &Context);
//
-// bool uncompressInst(MCInst &OutInst, const MCInst &MI,
+// bool uncompressInst(MCInst &OutInst, const MCInst &MI,
// const MCRegisterInfo &MRI,
// const MCSubtargetInfo &STI);
//
@@ -101,12 +101,12 @@ class RISCVCompressInstEmitter {
IndexedMap<OpData>
DestOperandMap; // Maps operands in the Dest Instruction
// to the corresponding Source instruction operand.
- bool IsCompressOnly;
+ bool IsCompressOnly;
CompressPat(CodeGenInstruction &S, CodeGenInstruction &D,
std::vector<Record *> RF, IndexedMap<OpData> &SourceMap,
- IndexedMap<OpData> &DestMap, bool IsCompressOnly)
+ IndexedMap<OpData> &DestMap, bool IsCompressOnly)
: Source(S), Dest(D), PatReqFeatures(RF), SourceOperandMap(SourceMap),
- DestOperandMap(DestMap), IsCompressOnly(IsCompressOnly) {}
+ DestOperandMap(DestMap), IsCompressOnly(IsCompressOnly) {}
};
enum EmitterType { Compress, Uncompress, CheckCompress };
RecordKeeper &Records;
@@ -139,12 +139,12 @@ public:
} // End anonymous namespace.
bool RISCVCompressInstEmitter::validateRegister(Record *Reg, Record *RegClass) {
- assert(Reg->isSubClassOf("Register") && "Reg record should be a Register");
- assert(RegClass->isSubClassOf("RegisterClass") &&
- "RegClass record should be a RegisterClass");
+ assert(Reg->isSubClassOf("Register") && "Reg record should be a Register");
+ assert(RegClass->isSubClassOf("RegisterClass") &&
+ "RegClass record should be a RegisterClass");
const CodeGenRegisterClass &RC = Target.getRegisterClass(RegClass);
const CodeGenRegister *R = Target.getRegisterByName(Reg->getName().lower());
- assert((R != nullptr) && "Register not defined!!");
+ assert((R != nullptr) && "Register not defined!!");
return RC.contains(R);
}
@@ -237,9 +237,9 @@ void RISCVCompressInstEmitter::addDagOperandMapping(
if (Inst.Operands[i].Rec->isSubClassOf("RegisterClass"))
PrintFatalError(
Rec->getLoc(),
- "Error in Dag '" + Dag->getAsString() + "' Found immediate: '" +
- II->getAsString() +
- "' but corresponding instruction operand expected a register!");
+ "Error in Dag '" + Dag->getAsString() + "' Found immediate: '" +
+ II->getAsString() +
+ "' but corresponding instruction operand expected a register!");
// No pattern validation check possible for values of fixed immediate.
OperandMap[i].Kind = OpData::Imm;
OperandMap[i].Data.Imm = II->getValue();
@@ -285,7 +285,7 @@ static bool verifyDagOpCount(CodeGenInstruction &Inst, DagInit *Dag,
}
static bool validateArgsTypes(Init *Arg1, Init *Arg2) {
- return cast<DefInit>(Arg1)->getDef() == cast<DefInit>(Arg2)->getDef();
+ return cast<DefInit>(Arg1)->getDef() == cast<DefInit>(Arg2)->getDef();
}
// Creates a mapping between the operand name in the Dag (e.g. $rs1) and
@@ -467,8 +467,8 @@ void RISCVCompressInstEmitter::evaluateCompressPat(Record *Rec) {
});
CompressPatterns.push_back(CompressPat(SourceInst, DestInst, PatReqFeatures,
- SourceOperandMap, DestOperandMap,
- Rec->getValueAsBit("isCompressOnly")));
+ SourceOperandMap, DestOperandMap,
+ Rec->getValueAsBit("isCompressOnly")));
}
static void
@@ -511,7 +511,7 @@ getReqFeatures(std::set<std::pair<bool, StringRef>> &FeaturesSet,
static unsigned getPredicates(DenseMap<const Record *, unsigned> &PredicateMap,
std::vector<const Record *> &Predicates,
Record *Rec, StringRef Name) {
- unsigned &Entry = PredicateMap[Rec];
+ unsigned &Entry = PredicateMap[Rec];
if (Entry)
return Entry;
@@ -522,28 +522,28 @@ static unsigned getPredicates(DenseMap<const Record *, unsigned> &PredicateMap,
}
PrintFatalError(Rec->getLoc(), "No " + Name +
- " predicate on this operand at all: '" +
- Rec->getName() + "'");
+ " predicate on this operand at all: '" +
+ Rec->getName() + "'");
return 0;
}
-static void printPredicates(const std::vector<const Record *> &Predicates,
+static void printPredicates(const std::vector<const Record *> &Predicates,
StringRef Name, raw_ostream &o) {
for (unsigned i = 0; i < Predicates.size(); ++i) {
- StringRef Pred = Predicates[i]->getValueAsString(Name);
- o << " case " << i + 1 << ": {\n"
- << " // " << Predicates[i]->getName() << "\n"
- << " " << Pred << "\n"
- << " }\n";
+ StringRef Pred = Predicates[i]->getValueAsString(Name);
+ o << " case " << i + 1 << ": {\n"
+ << " // " << Predicates[i]->getName() << "\n"
+ << " " << Pred << "\n"
+ << " }\n";
}
}
-static void mergeCondAndCode(raw_ostream &CombinedStream, StringRef CondStr,
- StringRef CodeStr) {
- // Remove first indentation and last '&&'.
- CondStr = CondStr.drop_front(6).drop_back(4);
- CombinedStream.indent(4) << "if (" << CondStr << ") {\n";
- CombinedStream << CodeStr;
+static void mergeCondAndCode(raw_ostream &CombinedStream, StringRef CondStr,
+ StringRef CodeStr) {
+ // Remove first indentation and last '&&'.
+ CondStr = CondStr.drop_front(6).drop_back(4);
+ CombinedStream.indent(4) << "if (" << CondStr << ") {\n";
+ CombinedStream << CodeStr;
CombinedStream.indent(4) << " return true;\n";
CombinedStream.indent(4) << "} // if\n";
}
@@ -556,20 +556,20 @@ void RISCVCompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
"'PassSubtarget' is false. SubTargetInfo object is needed "
"for target features.\n");
- StringRef Namespace = Target.getName();
+ StringRef Namespace = Target.getName();
// Sort entries in CompressPatterns to handle instructions that can have more
// than one candidate for compression\uncompression, e.g ADD can be
// transformed to a C_ADD or a C_MV. When emitting 'uncompress()' function the
// source and destination are flipped and the sort key needs to change
// accordingly.
- llvm::stable_sort(CompressPatterns, [EType](const CompressPat &LHS,
- const CompressPat &RHS) {
- if (EType == EmitterType::Compress || EType == EmitterType::CheckCompress)
- return (LHS.Source.TheDef->getName() < RHS.Source.TheDef->getName());
- else
- return (LHS.Dest.TheDef->getName() < RHS.Dest.TheDef->getName());
- });
+ llvm::stable_sort(CompressPatterns, [EType](const CompressPat &LHS,
+ const CompressPat &RHS) {
+ if (EType == EmitterType::Compress || EType == EmitterType::CheckCompress)
+ return (LHS.Source.TheDef->getName() < RHS.Source.TheDef->getName());
+ else
+ return (LHS.Dest.TheDef->getName() < RHS.Dest.TheDef->getName());
+ });
// A list of MCOperandPredicates for all operands in use, and the reverse map.
std::vector<const Record *> MCOpPredicates;
@@ -595,17 +595,17 @@ void RISCVCompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
<< "#undef GEN_CHECK_COMPRESS_INSTR\n\n";
if (EType == EmitterType::Compress) {
- FuncH << "static bool compressInst(MCInst &OutInst,\n";
+ FuncH << "static bool compressInst(MCInst &OutInst,\n";
FuncH.indent(25) << "const MCInst &MI,\n";
FuncH.indent(25) << "const MCSubtargetInfo &STI,\n";
FuncH.indent(25) << "MCContext &Context) {\n";
} else if (EType == EmitterType::Uncompress){
- FuncH << "static bool uncompressInst(MCInst &OutInst,\n";
+ FuncH << "static bool uncompressInst(MCInst &OutInst,\n";
FuncH.indent(27) << "const MCInst &MI,\n";
FuncH.indent(27) << "const MCRegisterInfo &MRI,\n";
FuncH.indent(27) << "const MCSubtargetInfo &STI) {\n";
} else if (EType == EmitterType::CheckCompress) {
- FuncH << "static bool isCompressibleInst(const MachineInstr &MI,\n";
+ FuncH << "static bool isCompressibleInst(const MachineInstr &MI,\n";
FuncH.indent(27) << "const RISCVSubtarget *Subtarget,\n";
FuncH.indent(27) << "const MCRegisterInfo &MRI,\n";
FuncH.indent(27) << "const MCSubtargetInfo &STI) {\n";
@@ -623,10 +623,10 @@ void RISCVCompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
return;
}
- std::string CaseString;
+ std::string CaseString;
raw_string_ostream CaseStream(CaseString);
- StringRef PrevOp;
- StringRef CurOp;
+ StringRef PrevOp;
+ StringRef CurOp;
CaseStream << " switch (MI.getOpcode()) {\n";
CaseStream << " default: return false;\n";
@@ -636,9 +636,9 @@ void RISCVCompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
EType == EmitterType::Compress || EType == EmitterType::Uncompress;
for (auto &CompressPat : CompressPatterns) {
- if (EType == EmitterType::Uncompress && CompressPat.IsCompressOnly)
- continue;
-
+ if (EType == EmitterType::Uncompress && CompressPat.IsCompressOnly)
+ continue;
+
std::string CondString;
std::string CodeString;
raw_string_ostream CondStream(CondString);
@@ -652,10 +652,10 @@ void RISCVCompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
IndexedMap<OpData> &DestOperandMap = CompressOrCheck ?
CompressPat.DestOperandMap : CompressPat.SourceOperandMap;
- CurOp = Source.TheDef->getName();
+ CurOp = Source.TheDef->getName();
// Check current and previous opcode to decide to continue or end a case.
if (CurOp != PrevOp) {
- if (!PrevOp.empty())
+ if (!PrevOp.empty())
CaseStream.indent(6) << "break;\n } // case " + PrevOp + "\n";
CaseStream.indent(4) << "case " + Namespace + "::" + CurOp + ": {\n";
}
@@ -676,9 +676,9 @@ void RISCVCompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
// Emit checks for all required features.
for (auto &Op : FeaturesSet) {
StringRef Not = Op.first ? "!" : "";
- CondStream.indent(6) << Not << "STI.getFeatureBits()[" << Namespace
- << "::" << Op.second << "]"
- << " &&\n";
+ CondStream.indent(6) << Not << "STI.getFeatureBits()[" << Namespace
+ << "::" << Op.second << "]"
+ << " &&\n";
}
// Emit checks for all required feature groups.
@@ -687,8 +687,8 @@ void RISCVCompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
for (auto &Op : Set) {
bool isLast = &Op == &*Set.rbegin();
StringRef Not = Op.first ? "!" : "";
- CondStream << Not << "STI.getFeatureBits()[" << Namespace
- << "::" << Op.second << "]";
+ CondStream << Not << "STI.getFeatureBits()[" << Namespace
+ << "::" << Op.second << "]";
if (!isLast)
CondStream << " || ";
}
@@ -701,8 +701,8 @@ void RISCVCompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
if (SourceOperandMap[OpNo].TiedOpIdx != -1) {
if (Source.Operands[OpNo].Rec->isSubClassOf("RegisterClass"))
CondStream.indent(6)
- << "(MI.getOperand(" << OpNo << ").getReg() == MI.getOperand("
- << SourceOperandMap[OpNo].TiedOpIdx << ").getReg()) &&\n";
+ << "(MI.getOperand(" << OpNo << ").getReg() == MI.getOperand("
+ << SourceOperandMap[OpNo].TiedOpIdx << ").getReg()) &&\n";
else
PrintFatalError("Unexpected tied operand types!\n");
}
@@ -713,26 +713,26 @@ void RISCVCompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
break;
case OpData::Imm:
CondStream.indent(6)
- << "(MI.getOperand(" << OpNo << ").isImm()) &&\n"
- << " (MI.getOperand(" << OpNo
- << ").getImm() == " << SourceOperandMap[OpNo].Data.Imm << ") &&\n";
+ << "(MI.getOperand(" << OpNo << ").isImm()) &&\n"
+ << " (MI.getOperand(" << OpNo
+ << ").getImm() == " << SourceOperandMap[OpNo].Data.Imm << ") &&\n";
break;
case OpData::Reg: {
Record *Reg = SourceOperandMap[OpNo].Data.Reg;
- CondStream.indent(6)
- << "(MI.getOperand(" << OpNo << ").getReg() == " << Namespace
- << "::" << Reg->getName() << ") &&\n";
+ CondStream.indent(6)
+ << "(MI.getOperand(" << OpNo << ").getReg() == " << Namespace
+ << "::" << Reg->getName() << ") &&\n";
break;
}
}
}
- CodeStream.indent(6) << "// " << Dest.AsmString << "\n";
+ CodeStream.indent(6) << "// " << Dest.AsmString << "\n";
if (CompressOrUncompress)
- CodeStream.indent(6) << "OutInst.setOpcode(" << Namespace
- << "::" << Dest.TheDef->getName() << ");\n";
+ CodeStream.indent(6) << "OutInst.setOpcode(" << Namespace
+ << "::" << Dest.TheDef->getName() << ");\n";
OpNo = 0;
for (const auto &DestOperand : Dest.Operands) {
- CodeStream.indent(6) << "// Operand: " << DestOperand.Name << "\n";
+ CodeStream.indent(6) << "// Operand: " << DestOperand.Name << "\n";
switch (DestOperandMap[OpNo].Kind) {
case OpData::Operand: {
unsigned OpIdx = DestOperandMap[OpNo].Data.Operand;
@@ -744,67 +744,67 @@ void RISCVCompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
// Don't check register class if this is a tied operand, it was done
// for the operand its tied to.
if (DestOperand.getTiedRegister() == -1)
- CondStream.indent(6) << "(MRI.getRegClass(" << Namespace
- << "::" << DestOperand.Rec->getName()
- << "RegClassID).contains(MI.getOperand("
- << OpIdx << ").getReg())) &&\n";
+ CondStream.indent(6) << "(MRI.getRegClass(" << Namespace
+ << "::" << DestOperand.Rec->getName()
+ << "RegClassID).contains(MI.getOperand("
+ << OpIdx << ").getReg())) &&\n";
if (CompressOrUncompress)
- CodeStream.indent(6)
- << "OutInst.addOperand(MI.getOperand(" << OpIdx << "));\n";
+ CodeStream.indent(6)
+ << "OutInst.addOperand(MI.getOperand(" << OpIdx << "));\n";
} else {
// Handling immediate operands.
if (CompressOrUncompress) {
- unsigned Entry =
- getPredicates(MCOpPredicateMap, MCOpPredicates, DestOperand.Rec,
- "MCOperandPredicate");
- CondStream.indent(6)
- << Namespace << "ValidateMCOperand("
- << "MI.getOperand(" << OpIdx << "), STI, " << Entry << ") &&\n";
+ unsigned Entry =
+ getPredicates(MCOpPredicateMap, MCOpPredicates, DestOperand.Rec,
+ "MCOperandPredicate");
+ CondStream.indent(6)
+ << Namespace << "ValidateMCOperand("
+ << "MI.getOperand(" << OpIdx << "), STI, " << Entry << ") &&\n";
} else {
- unsigned Entry =
- getPredicates(ImmLeafPredicateMap, ImmLeafPredicates,
- DestOperand.Rec, "ImmediateCode");
- CondStream.indent(6)
- << "MI.getOperand(" << OpIdx << ").isImm() &&\n";
- CondStream.indent(6) << Namespace << "ValidateMachineOperand("
- << "MI.getOperand(" << OpIdx
- << "), Subtarget, " << Entry << ") &&\n";
+ unsigned Entry =
+ getPredicates(ImmLeafPredicateMap, ImmLeafPredicates,
+ DestOperand.Rec, "ImmediateCode");
+ CondStream.indent(6)
+ << "MI.getOperand(" << OpIdx << ").isImm() &&\n";
+ CondStream.indent(6) << Namespace << "ValidateMachineOperand("
+ << "MI.getOperand(" << OpIdx
+ << "), Subtarget, " << Entry << ") &&\n";
}
if (CompressOrUncompress)
- CodeStream.indent(6)
- << "OutInst.addOperand(MI.getOperand(" << OpIdx << "));\n";
+ CodeStream.indent(6)
+ << "OutInst.addOperand(MI.getOperand(" << OpIdx << "));\n";
}
break;
}
case OpData::Imm: {
if (CompressOrUncompress) {
unsigned Entry = getPredicates(MCOpPredicateMap, MCOpPredicates,
- DestOperand.Rec, "MCOperandPredicate");
+ DestOperand.Rec, "MCOperandPredicate");
CondStream.indent(6)
- << Namespace << "ValidateMCOperand("
- << "MCOperand::createImm(" << DestOperandMap[OpNo].Data.Imm
- << "), STI, " << Entry << ") &&\n";
+ << Namespace << "ValidateMCOperand("
+ << "MCOperand::createImm(" << DestOperandMap[OpNo].Data.Imm
+ << "), STI, " << Entry << ") &&\n";
} else {
unsigned Entry = getPredicates(ImmLeafPredicateMap, ImmLeafPredicates,
- DestOperand.Rec, "ImmediateCode");
+ DestOperand.Rec, "ImmediateCode");
CondStream.indent(6)
- << Namespace
- << "ValidateMachineOperand(MachineOperand::CreateImm("
- << DestOperandMap[OpNo].Data.Imm << "), SubTarget, " << Entry
- << ") &&\n";
+ << Namespace
+ << "ValidateMachineOperand(MachineOperand::CreateImm("
+ << DestOperandMap[OpNo].Data.Imm << "), SubTarget, " << Entry
+ << ") &&\n";
}
if (CompressOrUncompress)
- CodeStream.indent(6) << "OutInst.addOperand(MCOperand::createImm("
- << DestOperandMap[OpNo].Data.Imm << "));\n";
+ CodeStream.indent(6) << "OutInst.addOperand(MCOperand::createImm("
+ << DestOperandMap[OpNo].Data.Imm << "));\n";
} break;
case OpData::Reg: {
if (CompressOrUncompress) {
// Fixed register has been validated at pattern validation time.
Record *Reg = DestOperandMap[OpNo].Data.Reg;
- CodeStream.indent(6)
- << "OutInst.addOperand(MCOperand::createReg(" << Namespace
- << "::" << Reg->getName() << "));\n";
+ CodeStream.indent(6)
+ << "OutInst.addOperand(MCOperand::createReg(" << Namespace
+ << "::" << Reg->getName() << "));\n";
}
} break;
}
@@ -812,12 +812,12 @@ void RISCVCompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
}
if (CompressOrUncompress)
CodeStream.indent(6) << "OutInst.setLoc(MI.getLoc());\n";
- mergeCondAndCode(CaseStream, CondStream.str(), CodeStream.str());
+ mergeCondAndCode(CaseStream, CondStream.str(), CodeStream.str());
PrevOp = CurOp;
}
Func << CaseStream.str() << "\n";
// Close brace for the last case.
- Func.indent(4) << "} // case " << CurOp << "\n";
+ Func.indent(4) << "} // case " << CurOp << "\n";
Func.indent(2) << "} // switch\n";
Func.indent(2) << "return false;\n}\n";
@@ -842,7 +842,7 @@ void RISCVCompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
<< "ValidateMachineOperand(const MachineOperand &MO,\n"
<< " const RISCVSubtarget *Subtarget,\n"
<< " unsigned PredicateIndex) {\n"
- << " int64_t Imm = MO.getImm();\n"
+ << " int64_t Imm = MO.getImm();\n"
<< " switch (PredicateIndex) {\n"
<< " default:\n"
<< " llvm_unreachable(\"Unknown ImmLeaf Predicate kind\");\n"
@@ -868,7 +868,7 @@ void RISCVCompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
}
void RISCVCompressInstEmitter::run(raw_ostream &o) {
- std::vector<Record *> Insts = Records.getAllDerivedDefinitions("CompressPat");
+ std::vector<Record *> Insts = Records.getAllDerivedDefinitions("CompressPat");
// Process the CompressPat definitions, validating them as we do so.
for (unsigned i = 0, e = Insts.size(); i != e; ++i)
diff --git a/contrib/libs/llvm12/utils/TableGen/RegisterBankEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/RegisterBankEmitter.cpp
index 7e09e70c72..0725657150 100644
--- a/contrib/libs/llvm12/utils/TableGen/RegisterBankEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/RegisterBankEmitter.cpp
@@ -71,7 +71,7 @@ public:
/// Add a register class to the bank without duplicates.
void addRegisterClass(const CodeGenRegisterClass *RC) {
- if (llvm::is_contained(RCs, RC))
+ if (llvm::is_contained(RCs, RC))
return;
// FIXME? We really want the register size rather than the spill size
@@ -128,12 +128,12 @@ void RegisterBankEmitter::emitHeader(raw_ostream &OS,
// <Target>RegisterBankInfo.h
OS << "namespace llvm {\n"
<< "namespace " << TargetName << " {\n"
- << "enum : unsigned {\n";
-
- OS << " InvalidRegBankID = ~0u,\n";
- unsigned ID = 0;
+ << "enum : unsigned {\n";
+
+ OS << " InvalidRegBankID = ~0u,\n";
+ unsigned ID = 0;
for (const auto &Bank : Banks)
- OS << " " << Bank.getEnumeratorName() << " = " << ID++ << ",\n";
+ OS << " " << Bank.getEnumeratorName() << " = " << ID++ << ",\n";
OS << " NumRegisterBanks,\n"
<< "};\n"
<< "} // end namespace " << TargetName << "\n"
@@ -168,7 +168,7 @@ void RegisterBankEmitter::emitBaseClassDefinition(
/// to the class.
static void visitRegisterBankClasses(
const CodeGenRegBank &RegisterClassHierarchy,
- const CodeGenRegisterClass *RC, const Twine &Kind,
+ const CodeGenRegisterClass *RC, const Twine &Kind,
std::function<void(const CodeGenRegisterClass *, StringRef)> VisitFn,
SmallPtrSetImpl<const CodeGenRegisterClass *> &VisitedRCs) {
@@ -182,7 +182,7 @@ static void visitRegisterBankClasses(
for (const auto &PossibleSubclass : RegisterClassHierarchy.getRegClasses()) {
std::string TmpKind =
- (Kind + " (" + PossibleSubclass.getName() + ")").str();
+ (Kind + " (" + PossibleSubclass.getName() + ")").str();
// Visit each subclass of an explicitly named class.
if (RC != &PossibleSubclass && RC->hasSubClass(&PossibleSubclass))
@@ -279,7 +279,7 @@ void RegisterBankEmitter::run(raw_ostream &OS) {
StringRef TargetName = Target.getName();
const CodeGenRegBank &RegisterClassHierarchy = Target.getRegBank();
- Records.startTimer("Analyze records");
+ Records.startTimer("Analyze records");
std::vector<RegisterBank> Banks;
for (const auto &V : Records.getAllDerivedDefinitions("RegisterBank")) {
SmallPtrSet<const CodeGenRegisterClass *, 8> VisitedRCs;
@@ -301,7 +301,7 @@ void RegisterBankEmitter::run(raw_ostream &OS) {
}
// Warn about ambiguous MIR caused by register bank/class name clashes.
- Records.startTimer("Warn ambiguous");
+ Records.startTimer("Warn ambiguous");
for (const auto &Class : RegisterClassHierarchy.getRegClasses()) {
for (const auto &Bank : Banks) {
if (Bank.getName().lower() == StringRef(Class.getName()).lower()) {
@@ -314,7 +314,7 @@ void RegisterBankEmitter::run(raw_ostream &OS) {
}
}
- Records.startTimer("Emit output");
+ Records.startTimer("Emit output");
emitSourceFileHeader("Register Bank Source Fragments", OS);
OS << "#ifdef GET_REGBANK_DECLARATIONS\n"
<< "#undef GET_REGBANK_DECLARATIONS\n";
diff --git a/contrib/libs/llvm12/utils/TableGen/RegisterInfoEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/RegisterInfoEmitter.cpp
index 0d3b5fd4e9..dce7594dec 100644
--- a/contrib/libs/llvm12/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/RegisterInfoEmitter.cpp
@@ -127,7 +127,7 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS,
OS << " " << Reg.getName() << " = " << Reg.EnumValue << ",\n";
assert(Registers.size() == Registers.back().EnumValue &&
"Register enum value mismatch!");
- OS << " NUM_TARGET_REGS // " << Registers.size()+1 << "\n";
+ OS << " NUM_TARGET_REGS // " << Registers.size()+1 << "\n";
OS << "};\n";
if (!Namespace.empty())
OS << "} // end namespace " << Namespace << "\n";
@@ -146,7 +146,7 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS,
for (const auto &RC : RegisterClasses)
OS << " " << RC.getName() << "RegClassID"
<< " = " << RC.EnumValue << ",\n";
- OS << "\n};\n";
+ OS << "\n};\n";
if (!Namespace.empty())
OS << "} // end namespace " << Namespace << "\n\n";
}
@@ -323,7 +323,7 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
OS << "/// Get the dimensions of register pressure impacted by this "
<< "register class.\n"
<< "/// Returns a -1 terminated array of pressure set IDs\n"
- << "const int *" << ClassName << "::\n"
+ << "const int *" << ClassName << "::\n"
<< "getRegClassPressureSets(const TargetRegisterClass *RC) const {\n";
OS << " static const " << getMinimalTypeForRange(PSetsSeqs.size() - 1, 32)
<< " RCSetStartTable[] = {\n ";
@@ -337,7 +337,7 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
OS << "/// Get the dimensions of register pressure impacted by this "
<< "register unit.\n"
<< "/// Returns a -1 terminated array of pressure set IDs\n"
- << "const int *" << ClassName << "::\n"
+ << "const int *" << ClassName << "::\n"
<< "getRegUnitPressureSets(unsigned RegUnit) const {\n"
<< " assert(RegUnit < " << RegBank.getNumNativeRegUnits()
<< " && \"invalid register unit\");\n";
@@ -356,10 +356,10 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
using DwarfRegNumsMapPair = std::pair<Record*, std::vector<int64_t>>;
using DwarfRegNumsVecTy = std::vector<DwarfRegNumsMapPair>;
-static void finalizeDwarfRegNumsKeys(DwarfRegNumsVecTy &DwarfRegNums) {
+static void finalizeDwarfRegNumsKeys(DwarfRegNumsVecTy &DwarfRegNums) {
// Sort and unique to get a map-like vector. We want the last assignment to
// match previous behaviour.
- llvm::stable_sort(DwarfRegNums, on_first<LessRecordRegister>());
+ llvm::stable_sort(DwarfRegNums, on_first<LessRecordRegister>());
// Warn about duplicate assignments.
const Record *LastSeenReg = nullptr;
for (const auto &X : DwarfRegNums) {
@@ -461,16 +461,16 @@ void RegisterInfoEmitter::EmitRegMappingTables(
DefInit *DI = cast<DefInit>(V->getValue());
Record *Alias = DI->getDef();
- const auto &AliasIter = llvm::lower_bound(
- DwarfRegNums, Alias, [](const DwarfRegNumsMapPair &A, const Record *B) {
- return LessRecordRegister()(A.first, B);
- });
+ const auto &AliasIter = llvm::lower_bound(
+ DwarfRegNums, Alias, [](const DwarfRegNumsMapPair &A, const Record *B) {
+ return LessRecordRegister()(A.first, B);
+ });
assert(AliasIter != DwarfRegNums.end() && AliasIter->first == Alias &&
"Expected Alias to be present in map");
- const auto &RegIter = llvm::lower_bound(
- DwarfRegNums, Reg, [](const DwarfRegNumsMapPair &A, const Record *B) {
- return LessRecordRegister()(A.first, B);
- });
+ const auto &RegIter = llvm::lower_bound(
+ DwarfRegNums, Reg, [](const DwarfRegNumsMapPair &A, const Record *B) {
+ return LessRecordRegister()(A.first, B);
+ });
assert(RegIter != DwarfRegNums.end() && RegIter->first == Reg &&
"Expected Reg to be present in map");
RegIter->second = AliasIter->second;
@@ -957,7 +957,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
const auto &RUMasks = Reg.getRegUnitLaneMasks();
MaskVec &LaneMaskVec = RegUnitLaneMasks[i];
assert(LaneMaskVec.empty());
- llvm::append_range(LaneMaskVec, RUMasks);
+ llvm::append_range(LaneMaskVec, RUMasks);
// Terminator mask should not be used inside of the list.
#ifndef NDEBUG
for (LaneBitmask M : LaneMaskVec) {
@@ -1164,7 +1164,7 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
<< " LaneBitmask reverseComposeSubRegIndexLaneMaskImpl"
<< "(unsigned, LaneBitmask) const override;\n"
<< " const TargetRegisterClass *getSubClassWithSubReg"
- << "(const TargetRegisterClass *, unsigned) const override;\n";
+ << "(const TargetRegisterClass *, unsigned) const override;\n";
}
OS << " const RegClassWeight &getRegClassWeight("
<< "const TargetRegisterClass *RC) const override;\n"
@@ -1285,8 +1285,8 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
OS << CGH.getMode(M).Name;
OS << ")\n";
for (const auto &RC : RegisterClasses) {
- assert(RC.EnumValue == EV && "Unexpected order of register classes");
- ++EV;
+ assert(RC.EnumValue == EV && "Unexpected order of register classes");
+ ++EV;
(void)EV;
const RegSizeInfo &RI = RC.RSI.get(M);
OS << " { " << RI.RegSize << ", " << RI.SpillSize << ", "
@@ -1433,7 +1433,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
}
OS << "\nnamespace {\n";
- OS << " const TargetRegisterClass *const RegisterClasses[] = {\n";
+ OS << " const TargetRegisterClass *const RegisterClasses[] = {\n";
for (const auto &RC : RegisterClasses)
OS << " &" << RC.getQualifiedName() << "RegClass,\n";
OS << " };\n";
@@ -1613,16 +1613,16 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
void RegisterInfoEmitter::run(raw_ostream &OS) {
CodeGenRegBank &RegBank = Target.getRegBank();
- Records.startTimer("Print enums");
+ Records.startTimer("Print enums");
runEnums(OS, Target, RegBank);
-
- Records.startTimer("Print MC registers");
+
+ Records.startTimer("Print MC registers");
runMCDesc(OS, Target, RegBank);
-
- Records.startTimer("Print header fragment");
+
+ Records.startTimer("Print header fragment");
runTargetHeader(OS, Target, RegBank);
-
- Records.startTimer("Print target registers");
+
+ Records.startTimer("Print target registers");
runTargetDesc(OS, Target, RegBank);
if (RegisterInfoDebug)
diff --git a/contrib/libs/llvm12/utils/TableGen/SearchableTableEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/SearchableTableEmitter.cpp
index 484b886f41..912d43b2ca 100644
--- a/contrib/libs/llvm12/utils/TableGen/SearchableTableEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/SearchableTableEmitter.cpp
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#include "CodeGenIntrinsics.h"
-#include "llvm/ADT/ArrayRef.h"
+#include "CodeGenIntrinsics.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Format.h"
@@ -54,7 +54,7 @@ struct GenericEnum {
struct GenericField {
std::string Name;
RecTy *RecType = nullptr;
- bool IsCode = false;
+ bool IsCode = false;
bool IsIntrinsic = false;
bool IsInstruction = false;
GenericEnum *Enum = nullptr;
@@ -64,14 +64,14 @@ struct GenericField {
struct SearchIndex {
std::string Name;
- SMLoc Loc; // Source location of PrimaryKey or Key field definition.
+ SMLoc Loc; // Source location of PrimaryKey or Key field definition.
SmallVector<GenericField, 1> Fields;
bool EarlyOut = false;
};
struct GenericTable {
std::string Name;
- ArrayRef<SMLoc> Locs; // Source locations from the Record instance.
+ ArrayRef<SMLoc> Locs; // Source locations from the Record instance.
std::string PreprocessorGuard;
std::string CppTypeName;
SmallVector<GenericField, 2> Fields;
@@ -110,14 +110,14 @@ private:
TypeInArgument,
};
- std::string primaryRepresentation(SMLoc Loc, const GenericField &Field,
- Init *I) {
- if (StringInit *SI = dyn_cast<StringInit>(I)) {
- if (Field.IsCode || SI->hasCodeFormat())
- return std::string(SI->getValue());
- else
- return SI->getAsString();
- } else if (BitsInit *BI = dyn_cast<BitsInit>(I))
+ std::string primaryRepresentation(SMLoc Loc, const GenericField &Field,
+ Init *I) {
+ if (StringInit *SI = dyn_cast<StringInit>(I)) {
+ if (Field.IsCode || SI->hasCodeFormat())
+ return std::string(SI->getValue());
+ else
+ return SI->getAsString();
+ } else if (BitsInit *BI = dyn_cast<BitsInit>(I))
return "0x" + utohexstr(getAsInt(BI));
else if (BitInit *BI = dyn_cast<BitInit>(I))
return BI->getValue() ? "true" : "false";
@@ -128,12 +128,12 @@ private:
else if (Field.Enum) {
auto *Entry = Field.Enum->EntryMap[cast<DefInit>(I)->getDef()];
if (!Entry)
- PrintFatalError(Loc,
- Twine("Entry for field '") + Field.Name + "' is null");
+ PrintFatalError(Loc,
+ Twine("Entry for field '") + Field.Name + "' is null");
return std::string(Entry->first);
}
- PrintFatalError(Loc, Twine("invalid field type for field '") + Field.Name +
- "'; expected: bit, bits, string, or code");
+ PrintFatalError(Loc, Twine("invalid field type for field '") + Field.Name +
+ "'; expected: bit, bits, string, or code");
}
bool isIntrinsic(Init *I) {
@@ -145,16 +145,16 @@ private:
CodeGenIntrinsic &getIntrinsic(Init *I) {
std::unique_ptr<CodeGenIntrinsic> &Intr = Intrinsics[I];
if (!Intr)
- Intr = std::make_unique<CodeGenIntrinsic>(cast<DefInit>(I)->getDef(),
- std::vector<Record *>());
+ Intr = std::make_unique<CodeGenIntrinsic>(cast<DefInit>(I)->getDef(),
+ std::vector<Record *>());
return *Intr;
}
bool compareBy(Record *LHS, Record *RHS, const SearchIndex &Index);
- std::string searchableFieldType(const GenericTable &Table,
- const SearchIndex &Index,
- const GenericField &Field, TypeContext Ctx) {
+ std::string searchableFieldType(const GenericTable &Table,
+ const SearchIndex &Index,
+ const GenericField &Field, TypeContext Ctx) {
if (isa<StringRecTy>(Field.RecType)) {
if (Ctx == TypeInStaticStruct)
return "const char *";
@@ -171,16 +171,16 @@ private:
return "uint32_t";
if (NumBits <= 64)
return "uint64_t";
- PrintFatalError(Index.Loc, Twine("In table '") + Table.Name +
- "' lookup method '" + Index.Name +
- "', key field '" + Field.Name +
- "' of type bits is too large");
+ PrintFatalError(Index.Loc, Twine("In table '") + Table.Name +
+ "' lookup method '" + Index.Name +
+ "', key field '" + Field.Name +
+ "' of type bits is too large");
} else if (Field.Enum || Field.IsIntrinsic || Field.IsInstruction)
return "unsigned";
- PrintFatalError(Index.Loc,
- Twine("In table '") + Table.Name + "' lookup method '" +
- Index.Name + "', key field '" + Field.Name +
- "' has invalid type: " + Field.RecType->getAsString());
+ PrintFatalError(Index.Loc,
+ Twine("In table '") + Table.Name + "' lookup method '" +
+ Index.Name + "', key field '" + Field.Name +
+ "' has invalid type: " + Field.RecType->getAsString());
}
void emitGenericTable(const GenericTable &Table, raw_ostream &OS);
@@ -193,7 +193,7 @@ private:
bool parseFieldType(GenericField &Field, Init *II);
std::unique_ptr<SearchIndex>
- parseSearchIndex(GenericTable &Table, const RecordVal *RecVal, StringRef Name,
+ parseSearchIndex(GenericTable &Table, const RecordVal *RecVal, StringRef Name,
const std::vector<StringRef> &Key, bool EarlyOut);
void collectEnumEntries(GenericEnum &Enum, StringRef NameField,
StringRef ValueField,
@@ -268,8 +268,8 @@ bool SearchableTableEmitter::compareBy(Record *LHS, Record *RHS,
if (LHSv > RHSv)
return false;
} else {
- std::string LHSs = primaryRepresentation(Index.Loc, Field, LHSI);
- std::string RHSs = primaryRepresentation(Index.Loc, Field, RHSI);
+ std::string LHSs = primaryRepresentation(Index.Loc, Field, LHSI);
+ std::string RHSs = primaryRepresentation(Index.Loc, Field, RHSI);
if (isa<StringRecTy>(Field.RecType)) {
LHSs = StringRef(LHSs).upper();
@@ -324,8 +324,8 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table,
} else {
OS << " struct IndexType {\n";
for (const auto &Field : Index.Fields) {
- OS << " "
- << searchableFieldType(Table, Index, Field, TypeInStaticStruct) << " "
+ OS << " "
+ << searchableFieldType(Table, Index, Field, TypeInStaticStruct) << " "
<< Field.Name << ";\n";
}
OS << " unsigned _index;\n";
@@ -338,10 +338,10 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table,
for (unsigned i = 0; i < Table.Entries.size(); ++i)
Entries.emplace_back(Table.Entries[i], i);
- llvm::stable_sort(Entries, [&](const std::pair<Record *, unsigned> &LHS,
- const std::pair<Record *, unsigned> &RHS) {
- return compareBy(LHS.first, RHS.first, Index);
- });
+ llvm::stable_sort(Entries, [&](const std::pair<Record *, unsigned> &LHS,
+ const std::pair<Record *, unsigned> &RHS) {
+ return compareBy(LHS.first, RHS.first, Index);
+ });
IndexRowsStorage.reserve(Entries.size());
for (const auto &Entry : Entries) {
@@ -354,8 +354,8 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table,
OS << ", ";
NeedComma = true;
- std::string Repr = primaryRepresentation(
- Index.Loc, Field, Entry.first->getValueInit(Field.Name));
+ std::string Repr = primaryRepresentation(
+ Index.Loc, Field, Entry.first->getValueInit(Field.Name));
if (isa<StringRecTy>(Field.RecType))
Repr = StringRef(Repr).upper();
OS << Repr;
@@ -398,10 +398,10 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table,
if (Index.EarlyOut) {
const GenericField &Field = Index.Fields[0];
- std::string FirstRepr = primaryRepresentation(
- Index.Loc, Field, IndexRows[0]->getValueInit(Field.Name));
+ std::string FirstRepr = primaryRepresentation(
+ Index.Loc, Field, IndexRows[0]->getValueInit(Field.Name));
std::string LastRepr = primaryRepresentation(
- Index.Loc, Field, IndexRows.back()->getValueInit(Field.Name));
+ Index.Loc, Field, IndexRows.back()->getValueInit(Field.Name));
OS << " if ((" << Field.Name << " < " << FirstRepr << ") ||\n";
OS << " (" << Field.Name << " > " << LastRepr << "))\n";
OS << " return nullptr;\n\n";
@@ -409,11 +409,11 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table,
OS << " struct KeyType {\n";
for (const auto &Field : Index.Fields) {
- OS << " " << searchableFieldType(Table, Index, Field, TypeInTempStruct)
- << " " << Field.Name << ";\n";
+ OS << " " << searchableFieldType(Table, Index, Field, TypeInTempStruct)
+ << " " << Field.Name << ";\n";
}
OS << " };\n";
- OS << " KeyType Key = {";
+ OS << " KeyType Key = {";
bool NeedComma = false;
for (const auto &Field : Index.Fields) {
if (NeedComma)
@@ -424,14 +424,14 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table,
if (isa<StringRecTy>(Field.RecType)) {
OS << ".upper()";
if (IsPrimary)
- PrintFatalError(Index.Loc,
- Twine("In table '") + Table.Name +
- "', use a secondary lookup method for "
- "case-insensitive comparison of field '" +
- Field.Name + "'");
+ PrintFatalError(Index.Loc,
+ Twine("In table '") + Table.Name +
+ "', use a secondary lookup method for "
+ "case-insensitive comparison of field '" +
+ Field.Name + "'");
}
}
- OS << "};\n";
+ OS << "};\n";
OS << " auto Table = makeArrayRef(" << IndexName << ");\n";
OS << " auto Idx = std::lower_bound(Table.begin(), Table.end(), Key,\n";
@@ -488,8 +488,8 @@ void SearchableTableEmitter::emitLookupDeclaration(const GenericTable &Table,
OS << ", ";
NeedComma = true;
- OS << searchableFieldType(Table, Index, Field, TypeInArgument) << " "
- << Field.Name;
+ OS << searchableFieldType(Table, Index, Field, TypeInArgument) << " "
+ << Field.Name;
}
OS << ")";
}
@@ -524,8 +524,8 @@ void SearchableTableEmitter::emitGenericTable(const GenericTable &Table,
OS << ", ";
NeedComma = true;
- OS << primaryRepresentation(Table.Locs[0], Field,
- Entry->getValueInit(Field.Name));
+ OS << primaryRepresentation(Table.Locs[0], Field,
+ Entry->getValueInit(Field.Name));
}
OS << " }, // " << i << "\n";
@@ -542,49 +542,49 @@ void SearchableTableEmitter::emitGenericTable(const GenericTable &Table,
OS << "#endif\n\n";
}
-bool SearchableTableEmitter::parseFieldType(GenericField &Field, Init *TypeOf) {
- if (auto Type = dyn_cast<StringInit>(TypeOf)) {
- if (Type->getValue() == "code") {
- Field.IsCode = true;
+bool SearchableTableEmitter::parseFieldType(GenericField &Field, Init *TypeOf) {
+ if (auto Type = dyn_cast<StringInit>(TypeOf)) {
+ if (Type->getValue() == "code") {
+ Field.IsCode = true;
return true;
- } else {
- if (Record *TypeRec = Records.getDef(Type->getValue())) {
- if (TypeRec->isSubClassOf("GenericEnum")) {
- Field.Enum = EnumMap[TypeRec];
- Field.RecType = RecordRecTy::get(Field.Enum->Class);
- return true;
- }
- }
+ } else {
+ if (Record *TypeRec = Records.getDef(Type->getValue())) {
+ if (TypeRec->isSubClassOf("GenericEnum")) {
+ Field.Enum = EnumMap[TypeRec];
+ Field.RecType = RecordRecTy::get(Field.Enum->Class);
+ return true;
+ }
+ }
}
}
return false;
}
-std::unique_ptr<SearchIndex> SearchableTableEmitter::parseSearchIndex(
- GenericTable &Table, const RecordVal *KeyRecVal, StringRef Name,
- const std::vector<StringRef> &Key, bool EarlyOut) {
+std::unique_ptr<SearchIndex> SearchableTableEmitter::parseSearchIndex(
+ GenericTable &Table, const RecordVal *KeyRecVal, StringRef Name,
+ const std::vector<StringRef> &Key, bool EarlyOut) {
auto Index = std::make_unique<SearchIndex>();
Index->Name = std::string(Name);
- Index->Loc = KeyRecVal->getLoc();
+ Index->Loc = KeyRecVal->getLoc();
Index->EarlyOut = EarlyOut;
for (const auto &FieldName : Key) {
const GenericField *Field = Table.getFieldByName(FieldName);
if (!Field)
- PrintFatalError(
- KeyRecVal,
- Twine("In table '") + Table.Name +
- "', 'PrimaryKey' or 'Key' refers to nonexistent field '" +
- FieldName + "'");
-
+ PrintFatalError(
+ KeyRecVal,
+ Twine("In table '") + Table.Name +
+ "', 'PrimaryKey' or 'Key' refers to nonexistent field '" +
+ FieldName + "'");
+
Index->Fields.push_back(*Field);
}
if (EarlyOut && isa<StringRecTy>(Index->Fields[0].RecType)) {
PrintFatalError(
- KeyRecVal, Twine("In lookup method '") + Name + "', early-out is not " +
- "supported for a first key field of type string");
+ KeyRecVal, Twine("In lookup method '") + Name + "', early-out is not " +
+ "supported for a first key field of type string");
}
return Index;
@@ -609,11 +609,11 @@ void SearchableTableEmitter::collectEnumEntries(
}
if (ValueField.empty()) {
- llvm::stable_sort(Enum.Entries,
- [](const std::unique_ptr<GenericEnum::Entry> &LHS,
- const std::unique_ptr<GenericEnum::Entry> &RHS) {
- return LHS->first < RHS->first;
- });
+ llvm::stable_sort(Enum.Entries,
+ [](const std::unique_ptr<GenericEnum::Entry> &LHS,
+ const std::unique_ptr<GenericEnum::Entry> &RHS) {
+ return LHS->first < RHS->first;
+ });
for (size_t i = 0; i < Enum.Entries.size(); ++i)
Enum.Entries[i]->second = i;
@@ -623,33 +623,33 @@ void SearchableTableEmitter::collectEnumEntries(
void SearchableTableEmitter::collectTableEntries(
GenericTable &Table, const std::vector<Record *> &Items) {
if (Items.empty())
- PrintFatalError(Table.Locs,
- Twine("Table '") + Table.Name + "' has no entries");
+ PrintFatalError(Table.Locs,
+ Twine("Table '") + Table.Name + "' has no entries");
for (auto EntryRec : Items) {
for (auto &Field : Table.Fields) {
auto TI = dyn_cast<TypedInit>(EntryRec->getValueInit(Field.Name));
if (!TI || !TI->isComplete()) {
- PrintFatalError(EntryRec, Twine("Record '") + EntryRec->getName() +
- "' for table '" + Table.Name +
- "' is missing field '" + Field.Name +
- "'");
+ PrintFatalError(EntryRec, Twine("Record '") + EntryRec->getName() +
+ "' for table '" + Table.Name +
+ "' is missing field '" + Field.Name +
+ "'");
}
if (!Field.RecType) {
Field.RecType = TI->getType();
} else {
RecTy *Ty = resolveTypes(Field.RecType, TI->getType());
if (!Ty)
- PrintFatalError(EntryRec->getValue(Field.Name),
- Twine("Field '") + Field.Name + "' of table '" +
- Table.Name + "' entry has incompatible type: " +
- TI->getType()->getAsString() + " vs. " +
- Field.RecType->getAsString());
+ PrintFatalError(EntryRec->getValue(Field.Name),
+ Twine("Field '") + Field.Name + "' of table '" +
+ Table.Name + "' entry has incompatible type: " +
+ TI->getType()->getAsString() + " vs. " +
+ Field.RecType->getAsString());
Field.RecType = Ty;
}
}
- Table.Entries.push_back(EntryRec); // Add record to table's record list.
+ Table.Entries.push_back(EntryRec); // Add record to table's record list.
}
Record *IntrinsicClass = Records.getClass("Intrinsic");
@@ -690,9 +690,9 @@ void SearchableTableEmitter::run(raw_ostream &OS) {
StringRef FilterClass = EnumRec->getValueAsString("FilterClass");
Enum->Class = Records.getClass(FilterClass);
if (!Enum->Class)
- PrintFatalError(EnumRec->getValue("FilterClass"),
- Twine("Enum FilterClass '") + FilterClass +
- "' does not exist");
+ PrintFatalError(EnumRec->getValue("FilterClass"),
+ Twine("Enum FilterClass '") + FilterClass +
+ "' does not exist");
collectEnumEntries(*Enum, NameField, ValueField,
Records.getAllDerivedDefinitions(FilterClass));
@@ -703,44 +703,44 @@ void SearchableTableEmitter::run(raw_ostream &OS) {
for (auto TableRec : Records.getAllDerivedDefinitions("GenericTable")) {
auto Table = std::make_unique<GenericTable>();
Table->Name = std::string(TableRec->getName());
- Table->Locs = TableRec->getLoc();
+ Table->Locs = TableRec->getLoc();
Table->PreprocessorGuard = std::string(TableRec->getName());
Table->CppTypeName = std::string(TableRec->getValueAsString("CppTypeName"));
std::vector<StringRef> Fields = TableRec->getValueAsListOfStrings("Fields");
for (const auto &FieldName : Fields) {
- Table->Fields.emplace_back(FieldName); // Construct a GenericField.
-
- if (auto TypeOfRecordVal = TableRec->getValue(("TypeOf_" + FieldName).str())) {
- if (!parseFieldType(Table->Fields.back(), TypeOfRecordVal->getValue())) {
- PrintError(TypeOfRecordVal,
- Twine("Table '") + Table->Name +
- "' has invalid 'TypeOf_" + FieldName +
- "': " + TypeOfRecordVal->getValue()->getAsString());
- PrintFatalNote("The 'TypeOf_xxx' field must be a string naming a "
- "GenericEnum record, or \"code\"");
+ Table->Fields.emplace_back(FieldName); // Construct a GenericField.
+
+ if (auto TypeOfRecordVal = TableRec->getValue(("TypeOf_" + FieldName).str())) {
+ if (!parseFieldType(Table->Fields.back(), TypeOfRecordVal->getValue())) {
+ PrintError(TypeOfRecordVal,
+ Twine("Table '") + Table->Name +
+ "' has invalid 'TypeOf_" + FieldName +
+ "': " + TypeOfRecordVal->getValue()->getAsString());
+ PrintFatalNote("The 'TypeOf_xxx' field must be a string naming a "
+ "GenericEnum record, or \"code\"");
}
}
}
- StringRef FilterClass = TableRec->getValueAsString("FilterClass");
- if (!Records.getClass(FilterClass))
- PrintFatalError(TableRec->getValue("FilterClass"),
- Twine("Table FilterClass '") +
- FilterClass + "' does not exist");
+ StringRef FilterClass = TableRec->getValueAsString("FilterClass");
+ if (!Records.getClass(FilterClass))
+ PrintFatalError(TableRec->getValue("FilterClass"),
+ Twine("Table FilterClass '") +
+ FilterClass + "' does not exist");
+
+ collectTableEntries(*Table, Records.getAllDerivedDefinitions(FilterClass));
- collectTableEntries(*Table, Records.getAllDerivedDefinitions(FilterClass));
-
if (!TableRec->isValueUnset("PrimaryKey")) {
Table->PrimaryKey =
- parseSearchIndex(*Table, TableRec->getValue("PrimaryKey"),
- TableRec->getValueAsString("PrimaryKeyName"),
+ parseSearchIndex(*Table, TableRec->getValue("PrimaryKey"),
+ TableRec->getValueAsString("PrimaryKeyName"),
TableRec->getValueAsListOfStrings("PrimaryKey"),
TableRec->getValueAsBit("PrimaryKeyEarlyOut"));
- llvm::stable_sort(Table->Entries, [&](Record *LHS, Record *RHS) {
- return compareBy(LHS, RHS, *Table->PrimaryKey);
- });
+ llvm::stable_sort(Table->Entries, [&](Record *LHS, Record *RHS) {
+ return compareBy(LHS, RHS, *Table->PrimaryKey);
+ });
}
TableMap.insert(std::make_pair(TableRec, Table.get()));
@@ -751,16 +751,16 @@ void SearchableTableEmitter::run(raw_ostream &OS) {
Record *TableRec = IndexRec->getValueAsDef("Table");
auto It = TableMap.find(TableRec);
if (It == TableMap.end())
- PrintFatalError(IndexRec->getValue("Table"),
+ PrintFatalError(IndexRec->getValue("Table"),
Twine("SearchIndex '") + IndexRec->getName() +
- "' refers to nonexistent table '" +
+ "' refers to nonexistent table '" +
TableRec->getName());
GenericTable &Table = *It->second;
- Table.Indices.push_back(
- parseSearchIndex(Table, IndexRec->getValue("Key"), IndexRec->getName(),
- IndexRec->getValueAsListOfStrings("Key"),
- IndexRec->getValueAsBit("EarlyOut")));
+ Table.Indices.push_back(
+ parseSearchIndex(Table, IndexRec->getValue("Key"), IndexRec->getName(),
+ IndexRec->getValueAsListOfStrings("Key"),
+ IndexRec->getValueAsBit("EarlyOut")));
}
// Translate legacy tables.
@@ -791,7 +791,7 @@ void SearchableTableEmitter::run(raw_ostream &OS) {
auto Table = std::make_unique<GenericTable>();
Table->Name = (Twine(Class->getName()) + "sList").str();
- Table->Locs = Class->getLoc();
+ Table->Locs = Class->getLoc();
Table->PreprocessorGuard = Class->getName().upper();
Table->CppTypeName = std::string(Class->getName());
@@ -814,8 +814,8 @@ void SearchableTableEmitter::run(raw_ostream &OS) {
Class->getValueAsListOfStrings("SearchableFields")) {
std::string Name =
(Twine("lookup") + Table->CppTypeName + "By" + Field).str();
- Table->Indices.push_back(parseSearchIndex(*Table, Class->getValue(Field),
- Name, {Field}, false));
+ Table->Indices.push_back(parseSearchIndex(*Table, Class->getValue(Field),
+ Name, {Field}, false));
}
Tables.emplace_back(std::move(Table));
diff --git a/contrib/libs/llvm12/utils/TableGen/SubtargetEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/SubtargetEmitter.cpp
index 5da6a153a6..7d2b4b929d 100644
--- a/contrib/libs/llvm12/utils/TableGen/SubtargetEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/SubtargetEmitter.cpp
@@ -266,15 +266,15 @@ SubtargetEmitter::CPUKeyValues(raw_ostream &OS,
for (Record *Processor : ProcessorList) {
StringRef Name = Processor->getValueAsString("Name");
RecVec FeatureList = Processor->getValueAsListOfDefs("Features");
- RecVec TuneFeatureList = Processor->getValueAsListOfDefs("TuneFeatures");
+ RecVec TuneFeatureList = Processor->getValueAsListOfDefs("TuneFeatures");
// Emit as { "cpu", "description", 0, { f1 , f2 , ... fn } },
OS << " { "
<< "\"" << Name << "\", ";
printFeatureMask(OS, FeatureList, FeatureMap);
- OS << ", ";
- printFeatureMask(OS, TuneFeatureList, FeatureMap);
+ OS << ", ";
+ printFeatureMask(OS, TuneFeatureList, FeatureMap);
// Emit the scheduler model pointer.
const std::string &ProcModelName =
@@ -730,8 +730,8 @@ void SubtargetEmitter::EmitLoadStoreQueueInfo(const CodeGenProcModel &ProcModel,
unsigned QueueID = 0;
if (ProcModel.LoadQueue) {
const Record *Queue = ProcModel.LoadQueue->getValueAsDef("QueueDescriptor");
- QueueID = 1 + std::distance(ProcModel.ProcResourceDefs.begin(),
- find(ProcModel.ProcResourceDefs, Queue));
+ QueueID = 1 + std::distance(ProcModel.ProcResourceDefs.begin(),
+ find(ProcModel.ProcResourceDefs, Queue));
}
OS << " " << QueueID << ", // Resource Descriptor for the Load Queue\n";
@@ -739,8 +739,8 @@ void SubtargetEmitter::EmitLoadStoreQueueInfo(const CodeGenProcModel &ProcModel,
if (ProcModel.StoreQueue) {
const Record *Queue =
ProcModel.StoreQueue->getValueAsDef("QueueDescriptor");
- QueueID = 1 + std::distance(ProcModel.ProcResourceDefs.begin(),
- find(ProcModel.ProcResourceDefs, Queue));
+ QueueID = 1 + std::distance(ProcModel.ProcResourceDefs.begin(),
+ find(ProcModel.ProcResourceDefs, Queue));
}
OS << " " << QueueID << ", // Resource Descriptor for the Store Queue\n";
}
@@ -1003,7 +1003,7 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
bool HasVariants = false;
for (const CodeGenSchedTransition &CGT :
make_range(SC.Transitions.begin(), SC.Transitions.end())) {
- if (CGT.ProcIndex == ProcModel.Index) {
+ if (CGT.ProcIndex == ProcModel.Index) {
HasVariants = true;
break;
}
@@ -1216,8 +1216,8 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
}
else {
SCDesc.WriteLatencyIdx = SchedTables.WriteLatencies.size();
- llvm::append_range(SchedTables.WriteLatencies, WriteLatencies);
- llvm::append_range(SchedTables.WriterNames, WriterNames);
+ llvm::append_range(SchedTables.WriteLatencies, WriteLatencies);
+ llvm::append_range(SchedTables.WriterNames, WriterNames);
}
// ReadAdvanceEntries must remain in operand order.
SCDesc.NumReadAdvanceEntries = ReadAdvanceEntries.size();
@@ -1229,7 +1229,7 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
SCDesc.ReadAdvanceIdx = RAPos - SchedTables.ReadAdvanceEntries.begin();
else {
SCDesc.ReadAdvanceIdx = SchedTables.ReadAdvanceEntries.size();
- llvm::append_range(SchedTables.ReadAdvanceEntries, ReadAdvanceEntries);
+ llvm::append_range(SchedTables.ReadAdvanceEntries, ReadAdvanceEntries);
}
}
}
@@ -1436,11 +1436,11 @@ static void emitPredicateProlog(const RecordKeeper &Records, raw_ostream &OS) {
OS << Buffer;
}
-static bool isTruePredicate(const Record *Rec) {
- return Rec->isSubClassOf("MCSchedPredicate") &&
- Rec->getValueAsDef("Pred")->isSubClassOf("MCTrue");
-}
-
+static bool isTruePredicate(const Record *Rec) {
+ return Rec->isSubClassOf("MCSchedPredicate") &&
+ Rec->getValueAsDef("Pred")->isSubClassOf("MCTrue");
+}
+
static void emitPredicates(const CodeGenSchedTransition &T,
const CodeGenSchedClass &SC, PredicateExpander &PE,
raw_ostream &OS) {
@@ -1449,7 +1449,7 @@ static void emitPredicates(const CodeGenSchedTransition &T,
// If not all predicates are MCTrue, then we need an if-stmt.
unsigned NumNonTruePreds =
- T.PredTerm.size() - count_if(T.PredTerm, isTruePredicate);
+ T.PredTerm.size() - count_if(T.PredTerm, isTruePredicate);
SS.indent(PE.getIndentLevel() * 2);
@@ -1461,7 +1461,7 @@ static void emitPredicates(const CodeGenSchedTransition &T,
for (const Record *Rec : T.PredTerm) {
// Skip predicates that evaluate to "true".
- if (isTruePredicate(Rec))
+ if (isTruePredicate(Rec))
continue;
if (FirstNonTruePredicate) {
@@ -1497,8 +1497,8 @@ static void emitPredicates(const CodeGenSchedTransition &T,
// Used by method `SubtargetEmitter::emitSchedModelHelpersImpl()` to generate
// epilogue code for the auto-generated helper.
-static void emitSchedModelHelperEpilogue(raw_ostream &OS,
- bool ShouldReturnZero) {
+static void emitSchedModelHelperEpilogue(raw_ostream &OS,
+ bool ShouldReturnZero) {
if (ShouldReturnZero) {
OS << " // Don't know how to resolve this scheduling class.\n"
<< " return 0;\n";
@@ -1508,15 +1508,15 @@ static void emitSchedModelHelperEpilogue(raw_ostream &OS,
OS << " report_fatal_error(\"Expected a variant SchedClass\");\n";
}
-static bool hasMCSchedPredicates(const CodeGenSchedTransition &T) {
+static bool hasMCSchedPredicates(const CodeGenSchedTransition &T) {
return all_of(T.PredTerm, [](const Record *Rec) {
return Rec->isSubClassOf("MCSchedPredicate");
});
}
-static void collectVariantClasses(const CodeGenSchedModels &SchedModels,
- IdxVec &VariantClasses,
- bool OnlyExpandMCInstPredicates) {
+static void collectVariantClasses(const CodeGenSchedModels &SchedModels,
+ IdxVec &VariantClasses,
+ bool OnlyExpandMCInstPredicates) {
for (const CodeGenSchedClass &SC : SchedModels.schedClasses()) {
// Ignore non-variant scheduling classes.
if (SC.Transitions.empty())
@@ -1535,24 +1535,24 @@ static void collectVariantClasses(const CodeGenSchedModels &SchedModels,
}
}
-static void collectProcessorIndices(const CodeGenSchedClass &SC,
- IdxVec &ProcIndices) {
+static void collectProcessorIndices(const CodeGenSchedClass &SC,
+ IdxVec &ProcIndices) {
// A variant scheduling class may define transitions for multiple
// processors. This function identifies wich processors are associated with
// transition rules specified by variant class `SC`.
for (const CodeGenSchedTransition &T : SC.Transitions) {
IdxVec PI;
- std::set_union(&T.ProcIndex, &T.ProcIndex + 1, ProcIndices.begin(),
- ProcIndices.end(), std::back_inserter(PI));
+ std::set_union(&T.ProcIndex, &T.ProcIndex + 1, ProcIndices.begin(),
+ ProcIndices.end(), std::back_inserter(PI));
ProcIndices.swap(PI);
}
}
-static bool isAlwaysTrue(const CodeGenSchedTransition &T) {
- return llvm::all_of(T.PredTerm,
- [](const Record *R) { return isTruePredicate(R); });
-}
-
+static bool isAlwaysTrue(const CodeGenSchedTransition &T) {
+ return llvm::all_of(T.PredTerm,
+ [](const Record *R) { return isTruePredicate(R); });
+}
+
void SubtargetEmitter::emitSchedModelHelpersImpl(
raw_ostream &OS, bool OnlyExpandMCInstPredicates) {
IdxVec VariantClasses;
@@ -1595,9 +1595,9 @@ void SubtargetEmitter::emitSchedModelHelpersImpl(
}
// Now emit transitions associated with processor PI.
- const CodeGenSchedTransition *FinalT = nullptr;
+ const CodeGenSchedTransition *FinalT = nullptr;
for (const CodeGenSchedTransition &T : SC.Transitions) {
- if (PI != 0 && T.ProcIndex != PI)
+ if (PI != 0 && T.ProcIndex != PI)
continue;
// Emit only transitions based on MCSchedPredicate, if it's the case.
@@ -1610,17 +1610,17 @@ void SubtargetEmitter::emitSchedModelHelpersImpl(
if (OnlyExpandMCInstPredicates && !hasMCSchedPredicates(T))
continue;
- // If transition is folded to 'return X' it should be the last one.
- if (isAlwaysTrue(T)) {
- FinalT = &T;
- continue;
- }
+ // If transition is folded to 'return X' it should be the last one.
+ if (isAlwaysTrue(T)) {
+ FinalT = &T;
+ continue;
+ }
PE.setIndentLevel(3);
emitPredicates(T, SchedModels.getSchedClass(T.ToClassIdx), PE, OS);
}
- if (FinalT)
- emitPredicates(*FinalT, SchedModels.getSchedClass(FinalT->ToClassIdx),
- PE, OS);
+ if (FinalT)
+ emitPredicates(*FinalT, SchedModels.getSchedClass(FinalT->ToClassIdx),
+ PE, OS);
OS << " }\n";
@@ -1654,9 +1654,9 @@ void SubtargetEmitter::EmitSchedModelHelpers(const std::string &ClassName,
OS << "unsigned " << ClassName
<< "\n::resolveVariantSchedClass(unsigned SchedClass, const MCInst *MI,"
- << " const MCInstrInfo *MCII, unsigned CPUID) const {\n"
+ << " const MCInstrInfo *MCII, unsigned CPUID) const {\n"
<< " return " << Target << "_MC"
- << "::resolveVariantSchedClassImpl(SchedClass, MI, MCII, CPUID);\n"
+ << "::resolveVariantSchedClassImpl(SchedClass, MI, MCII, CPUID);\n"
<< "} // " << ClassName << "::resolveVariantSchedClass\n\n";
STIPredicateExpander PE(Target);
@@ -1700,19 +1700,19 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS,
<< "// subtarget options.\n"
<< "void llvm::";
OS << Target;
- OS << "Subtarget::ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, "
- << "StringRef FS) {\n"
+ OS << "Subtarget::ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, "
+ << "StringRef FS) {\n"
<< " LLVM_DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n"
- << " LLVM_DEBUG(dbgs() << \"\\nCPU:\" << CPU);\n"
- << " LLVM_DEBUG(dbgs() << \"\\nTuneCPU:\" << TuneCPU << \"\\n\\n\");\n";
+ << " LLVM_DEBUG(dbgs() << \"\\nCPU:\" << CPU);\n"
+ << " LLVM_DEBUG(dbgs() << \"\\nTuneCPU:\" << TuneCPU << \"\\n\\n\");\n";
if (Features.empty()) {
OS << "}\n";
return;
}
- OS << " InitMCProcessorInfo(CPU, TuneCPU, FS);\n"
- << " const FeatureBitset &Bits = getFeatureBits();\n";
+ OS << " InitMCProcessorInfo(CPU, TuneCPU, FS);\n"
+ << " const FeatureBitset &Bits = getFeatureBits();\n";
for (Record *R : Features) {
// Next record
@@ -1737,28 +1737,28 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS,
void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) {
OS << "namespace " << Target << "_MC {\n"
<< "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,\n"
- << " const MCInst *MI, const MCInstrInfo *MCII, unsigned CPUID) {\n";
+ << " const MCInst *MI, const MCInstrInfo *MCII, unsigned CPUID) {\n";
emitSchedModelHelpersImpl(OS, /* OnlyExpandMCPredicates */ true);
OS << "}\n";
OS << "} // end namespace " << Target << "_MC\n\n";
OS << "struct " << Target
<< "GenMCSubtargetInfo : public MCSubtargetInfo {\n";
- OS << " " << Target << "GenMCSubtargetInfo(const Triple &TT,\n"
- << " StringRef CPU, StringRef TuneCPU, StringRef FS,\n"
- << " ArrayRef<SubtargetFeatureKV> PF,\n"
+ OS << " " << Target << "GenMCSubtargetInfo(const Triple &TT,\n"
+ << " StringRef CPU, StringRef TuneCPU, StringRef FS,\n"
+ << " ArrayRef<SubtargetFeatureKV> PF,\n"
<< " ArrayRef<SubtargetSubTypeKV> PD,\n"
<< " const MCWriteProcResEntry *WPR,\n"
<< " const MCWriteLatencyEntry *WL,\n"
<< " const MCReadAdvanceEntry *RA, const InstrStage *IS,\n"
<< " const unsigned *OC, const unsigned *FP) :\n"
- << " MCSubtargetInfo(TT, CPU, TuneCPU, FS, PF, PD,\n"
+ << " MCSubtargetInfo(TT, CPU, TuneCPU, FS, PF, PD,\n"
<< " WPR, WL, RA, IS, OC, FP) { }\n\n"
<< " unsigned resolveVariantSchedClass(unsigned SchedClass,\n"
- << " const MCInst *MI, const MCInstrInfo *MCII,\n"
- << " unsigned CPUID) const override {\n"
+ << " const MCInst *MI, const MCInstrInfo *MCII,\n"
+ << " unsigned CPUID) const override {\n"
<< " return " << Target << "_MC"
- << "::resolveVariantSchedClassImpl(SchedClass, MI, MCII, CPUID);\n";
+ << "::resolveVariantSchedClassImpl(SchedClass, MI, MCII, CPUID);\n";
OS << " }\n";
if (TGT.getHwModes().getNumModeIds() > 1)
OS << " unsigned getHwMode() const override;\n";
@@ -1829,9 +1829,9 @@ void SubtargetEmitter::run(raw_ostream &OS) {
OS << "\nstatic inline MCSubtargetInfo *create" << Target
<< "MCSubtargetInfoImpl("
- << "const Triple &TT, StringRef CPU, StringRef TuneCPU, StringRef FS) {\n";
- OS << " return new " << Target
- << "GenMCSubtargetInfo(TT, CPU, TuneCPU, FS, ";
+ << "const Triple &TT, StringRef CPU, StringRef TuneCPU, StringRef FS) {\n";
+ OS << " return new " << Target
+ << "GenMCSubtargetInfo(TT, CPU, TuneCPU, FS, ";
if (NumFeatures)
OS << Target << "FeatureKV, ";
else
@@ -1875,18 +1875,18 @@ void SubtargetEmitter::run(raw_ostream &OS) {
OS << "class DFAPacketizer;\n";
OS << "namespace " << Target << "_MC {\n"
<< "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,"
- << " const MCInst *MI, const MCInstrInfo *MCII, unsigned CPUID);\n"
+ << " const MCInst *MI, const MCInstrInfo *MCII, unsigned CPUID);\n"
<< "} // end namespace " << Target << "_MC\n\n";
OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n"
<< " explicit " << ClassName << "(const Triple &TT, StringRef CPU, "
- << "StringRef TuneCPU, StringRef FS);\n"
+ << "StringRef TuneCPU, StringRef FS);\n"
<< "public:\n"
<< " unsigned resolveSchedClass(unsigned SchedClass, "
<< " const MachineInstr *DefMI,"
<< " const TargetSchedModel *SchedModel) const override;\n"
<< " unsigned resolveVariantSchedClass(unsigned SchedClass,"
- << " const MCInst *MI, const MCInstrInfo *MCII,"
- << " unsigned CPUID) const override;\n"
+ << " const MCInst *MI, const MCInstrInfo *MCII,"
+ << " unsigned CPUID) const override;\n"
<< " DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)"
<< " const;\n";
if (TGT.getHwModes().getNumModeIds() > 1)
@@ -1923,8 +1923,8 @@ void SubtargetEmitter::run(raw_ostream &OS) {
}
OS << ClassName << "::" << ClassName << "(const Triple &TT, StringRef CPU, "
- << "StringRef TuneCPU, StringRef FS)\n"
- << " : TargetSubtargetInfo(TT, CPU, TuneCPU, FS, ";
+ << "StringRef TuneCPU, StringRef FS)\n"
+ << " : TargetSubtargetInfo(TT, CPU, TuneCPU, FS, ";
if (NumFeatures)
OS << "makeArrayRef(" << Target << "FeatureKV, " << NumFeatures << "), ";
else
diff --git a/contrib/libs/llvm12/utils/TableGen/SubtargetFeatureInfo.cpp b/contrib/libs/llvm12/utils/TableGen/SubtargetFeatureInfo.cpp
index b8ed4e97a0..105ed82c9d 100644
--- a/contrib/libs/llvm12/utils/TableGen/SubtargetFeatureInfo.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/SubtargetFeatureInfo.cpp
@@ -9,7 +9,7 @@
#include "SubtargetFeatureInfo.h"
#include "Types.h"
#include "llvm/Config/llvm-config.h"
-#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include <map>
@@ -112,7 +112,7 @@ void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
StringRef TargetName, StringRef ClassName, StringRef FuncName,
SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
OS << "FeatureBitset " << TargetName << ClassName << "::\n"
- << FuncName << "(const FeatureBitset &FB) const {\n";
+ << FuncName << "(const FeatureBitset &FB) const {\n";
OS << " FeatureBitset Features;\n";
for (const auto &SF : SubtargetFeatures) {
const SubtargetFeatureInfo &SFI = SF.second;
diff --git a/contrib/libs/llvm12/utils/TableGen/TableGen.cpp b/contrib/libs/llvm12/utils/TableGen/TableGen.cpp
index d514e00c6c..6d851da347 100644
--- a/contrib/libs/llvm12/utils/TableGen/TableGen.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/TableGen.cpp
@@ -12,7 +12,7 @@
#include "TableGenBackends.h" // Declares all backends.
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/InitLLVM.h"
#include "llvm/TableGen/Main.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/SetTheory.h"
@@ -21,8 +21,8 @@ using namespace llvm;
enum ActionType {
PrintRecords,
- PrintDetailedRecords,
- NullBackend,
+ PrintDetailedRecords,
+ NullBackend,
DumpJSON,
GenEmitter,
GenRegisterInfo,
@@ -74,10 +74,10 @@ cl::opt<ActionType> Action(
cl::values(
clEnumValN(PrintRecords, "print-records",
"Print all records to stdout (default)"),
- clEnumValN(PrintDetailedRecords, "print-detailed-records",
- "Print full details of all records to stdout"),
- clEnumValN(NullBackend, "null-backend",
- "Do nothing after parsing (useful for timing)"),
+ clEnumValN(PrintDetailedRecords, "print-detailed-records",
+ "Print full details of all records to stdout"),
+ clEnumValN(NullBackend, "null-backend",
+ "Do nothing after parsing (useful for timing)"),
clEnumValN(DumpJSON, "dump-json",
"Dump all records as machine-readable JSON"),
clEnumValN(GenEmitter, "gen-emitter", "Generate machine code emitter"),
@@ -148,13 +148,13 @@ cl::opt<std::string> Class("class", cl::desc("Print Enum list for this class"),
bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
switch (Action) {
case PrintRecords:
- OS << Records; // No argument, dump all contents
+ OS << Records; // No argument, dump all contents
+ break;
+ case PrintDetailedRecords:
+ EmitDetailedRecords(Records, OS);
+ break;
+ case NullBackend: // No backend at all.
break;
- case PrintDetailedRecords:
- EmitDetailedRecords(Records, OS);
- break;
- case NullBackend: // No backend at all.
- break;
case DumpJSON:
EmitJSON(Records, OS);
break;
@@ -279,7 +279,7 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
}
int main(int argc, char **argv) {
- InitLLVM X(argc, argv);
+ InitLLVM X(argc, argv);
cl::ParseCommandLineOptions(argc, argv);
return TableGenMain(argv[0], &LLVMTableGenMain);
diff --git a/contrib/libs/llvm12/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp
index 803cd12abc..7518b262e6 100644
--- a/contrib/libs/llvm12/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp
@@ -39,15 +39,15 @@ void emitWebAssemblyDisassemblerTables(
->getValue());
if (Opc == 0xFFFFFFFF)
continue; // No opcode defined.
- assert(Opc <= 0xFFFFFF);
- unsigned Prefix;
- if (Opc <= 0xFFFF) {
- Prefix = Opc >> 8;
- Opc = Opc & 0xFF;
- } else {
- Prefix = Opc >> 16;
- Opc = Opc & 0xFFFF;
- }
+ assert(Opc <= 0xFFFFFF);
+ unsigned Prefix;
+ if (Opc <= 0xFFFF) {
+ Prefix = Opc >> 8;
+ Opc = Opc & 0xFF;
+ } else {
+ Prefix = Opc >> 16;
+ Opc = Opc & 0xFFFF;
+ }
auto &CGIP = OpcodeTable[Prefix][Opc];
// All wasm instructions have a StackBased field of type string, we only
// want the instructions for which this is "true".
@@ -139,7 +139,7 @@ void emitWebAssemblyDisassemblerTables(
}
// Store operands if no prior occurrence.
if (OperandStart == OperandTable.size()) {
- llvm::append_range(OperandTable, CurOperandList);
+ llvm::append_range(OperandTable, CurOperandList);
}
OS << OperandStart;
} else {
diff --git a/contrib/libs/llvm12/utils/TableGen/X86DisassemblerTables.cpp b/contrib/libs/llvm12/utils/TableGen/X86DisassemblerTables.cpp
index fa103849a6..331664f875 100644
--- a/contrib/libs/llvm12/utils/TableGen/X86DisassemblerTables.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/X86DisassemblerTables.cpp
@@ -763,7 +763,7 @@ void DisassemblerTables::emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2,
}
if (index == 256) {
// If all 256 entries are MODRM_ONEENTRY, omit output.
- static_assert(MODRM_ONEENTRY == 0, "");
+ static_assert(MODRM_ONEENTRY == 0, "");
--i2;
o2 << "},\n";
} else {
diff --git a/contrib/libs/llvm12/utils/TableGen/X86FoldTablesEmitter.cpp b/contrib/libs/llvm12/utils/TableGen/X86FoldTablesEmitter.cpp
index f6e80751f6..85d9262151 100644
--- a/contrib/libs/llvm12/utils/TableGen/X86FoldTablesEmitter.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/X86FoldTablesEmitter.cpp
@@ -127,15 +127,15 @@ class X86FoldTablesEmitter {
OS << "0 },\n";
}
-
- bool operator<(const X86FoldTableEntry &RHS) const {
- bool LHSpseudo = RegInst->TheDef->getValueAsBit("isPseudo");
- bool RHSpseudo = RHS.RegInst->TheDef->getValueAsBit("isPseudo");
- if (LHSpseudo != RHSpseudo)
- return LHSpseudo;
-
- return RegInst->TheDef->getName() < RHS.RegInst->TheDef->getName();
- }
+
+ bool operator<(const X86FoldTableEntry &RHS) const {
+ bool LHSpseudo = RegInst->TheDef->getValueAsBit("isPseudo");
+ bool RHSpseudo = RHS.RegInst->TheDef->getValueAsBit("isPseudo");
+ if (LHSpseudo != RHSpseudo)
+ return LHSpseudo;
+
+ return RegInst->TheDef->getName() < RHS.RegInst->TheDef->getName();
+ }
};
typedef std::vector<X86FoldTableEntry> FoldTable;
@@ -234,7 +234,7 @@ static inline unsigned int getRegOperandSize(const Record *RegRec) {
}
// Return the size of the memory operand
-static inline unsigned getMemOperandSize(const Record *MemRec) {
+static inline unsigned getMemOperandSize(const Record *MemRec) {
if (MemRec->isSubClassOf("Operand")) {
StringRef Name =
MemRec->getValueAsDef("ParserMatchClass")->getValueAsString("Name");
@@ -654,14 +654,14 @@ void X86FoldTablesEmitter::run(formatted_raw_ostream &OS) {
&(Target.getInstruction(MemInstIter)), Entry.Strategy);
}
- // Sort the tables before printing.
- llvm::sort(Table2Addr);
- llvm::sort(Table0);
- llvm::sort(Table1);
- llvm::sort(Table2);
- llvm::sort(Table3);
- llvm::sort(Table4);
-
+ // Sort the tables before printing.
+ llvm::sort(Table2Addr);
+ llvm::sort(Table0);
+ llvm::sort(Table1);
+ llvm::sort(Table2);
+ llvm::sort(Table3);
+ llvm::sort(Table4);
+
// Print all tables.
printTable(Table2Addr, "Table2Addr", OS);
printTable(Table0, "Table0", OS);
diff --git a/contrib/libs/llvm12/utils/TableGen/X86RecognizableInstr.cpp b/contrib/libs/llvm12/utils/TableGen/X86RecognizableInstr.cpp
index 0d1c7a32b2..e4b7c05cfb 100644
--- a/contrib/libs/llvm12/utils/TableGen/X86RecognizableInstr.cpp
+++ b/contrib/libs/llvm12/utils/TableGen/X86RecognizableInstr.cpp
@@ -54,7 +54,7 @@ static uint8_t byteFromBitsInit(BitsInit &init) {
/// @param rec - The record from which to extract the value.
/// @param name - The name of the field in the record.
/// @return - The field, as translated by byteFromBitsInit().
-static uint8_t byteFromRec(const Record* rec, StringRef name) {
+static uint8_t byteFromRec(const Record* rec, StringRef name) {
BitsInit* bits = rec->getValueAsBitsInit(name);
return byteFromBitsInit(*bits);
}
diff --git a/contrib/libs/llvm12/utils/TableGen/ya.make b/contrib/libs/llvm12/utils/TableGen/ya.make
index d93e2ce27c..69c2241a4d 100644
--- a/contrib/libs/llvm12/utils/TableGen/ya.make
+++ b/contrib/libs/llvm12/utils/TableGen/ya.make
@@ -12,11 +12,11 @@ LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
PEERDIR(
- contrib/libs/llvm12
- contrib/libs/llvm12/lib/Demangle
- contrib/libs/llvm12/lib/Support
- contrib/libs/llvm12/lib/TableGen
- contrib/libs/llvm12/utils/TableGen/GlobalISel
+ contrib/libs/llvm12
+ contrib/libs/llvm12/lib/Demangle
+ contrib/libs/llvm12/lib/Support
+ contrib/libs/llvm12/lib/TableGen
+ contrib/libs/llvm12/utils/TableGen/GlobalISel
)
ADDINCL(
diff --git a/contrib/libs/llvm12/ya.make b/contrib/libs/llvm12/ya.make
index a984cfc606..50b4d51565 100644
--- a/contrib/libs/llvm12/ya.make
+++ b/contrib/libs/llvm12/ya.make
@@ -7,7 +7,7 @@ OWNER(
g:cpp-contrib
)
-VERSION(12.0.1)
+VERSION(12.0.1)
ORIGINAL_SOURCE(https://github.com/llvm/llvm-project/releases/download/llvmorg-12.0.1/llvm-12.0.1.src.tar.xz)
@@ -19,8 +19,8 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
ADDINCL(
- GLOBAL ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/include
- GLOBAL contrib/libs/llvm12/include
+ GLOBAL ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/include
+ GLOBAL contrib/libs/llvm12/include
)
END()
@@ -51,17 +51,17 @@ RECURSE(
lib/ExecutionEngine/JITLink
lib/ExecutionEngine/MCJIT
lib/ExecutionEngine/Orc
- lib/ExecutionEngine/Orc/Shared
- lib/ExecutionEngine/Orc/TargetProcess
+ lib/ExecutionEngine/Orc/Shared
+ lib/ExecutionEngine/Orc/TargetProcess
lib/ExecutionEngine/RuntimeDyld
lib/Extensions
- lib/FileCheck
+ lib/FileCheck
lib/Frontend/OpenACC
lib/Frontend/OpenMP
lib/FuzzMutate
lib/IR
lib/IRReader
- lib/InterfaceStub
+ lib/InterfaceStub
lib/LTO
lib/LineEditor
lib/Linker
@@ -109,13 +109,13 @@ RECURSE(
lib/Target/X86/Disassembler
lib/Target/X86/MCTargetDesc
lib/Target/X86/TargetInfo
- lib/TextAPI/MachO
+ lib/TextAPI/MachO
lib/ToolDrivers/llvm-dlltool
lib/ToolDrivers/llvm-lib
lib/Transforms/AggressiveInstCombine
lib/Transforms/CFGuard
lib/Transforms/Coroutines
- lib/Transforms/HelloNew
+ lib/Transforms/HelloNew
lib/Transforms/IPO
lib/Transforms/InstCombine
lib/Transforms/Instrumentation
@@ -156,8 +156,8 @@ RECURSE(
tools/llvm-gsymutil
tools/llvm-ifs
tools/llvm-jitlink
- tools/llvm-jitlink/llvm-jitlink-executor
- tools/llvm-libtool-darwin
+ tools/llvm-jitlink/llvm-jitlink-executor
+ tools/llvm-libtool-darwin
tools/llvm-link
tools/llvm-lipo
tools/llvm-lto
@@ -173,7 +173,7 @@ RECURSE(
tools/llvm-opt-report
tools/llvm-pdbutil
tools/llvm-profdata
- tools/llvm-profgen
+ tools/llvm-profgen
tools/llvm-rc
tools/llvm-readobj
tools/llvm-reduce
@@ -194,7 +194,7 @@ RECURSE(
tools/remarks-shlib
tools/sancov
tools/sanstats
- tools/split-file
+ tools/split-file
tools/verify-uselistorder
tools/yaml2obj
utils/TableGen
diff --git a/contrib/libs/lzmasdk/7zVersion.h b/contrib/libs/lzmasdk/7zVersion.h
index fcc1ec405e..c176823a4d 100644
--- a/contrib/libs/lzmasdk/7zVersion.h
+++ b/contrib/libs/lzmasdk/7zVersion.h
@@ -1,27 +1,27 @@
-#define MY_VER_MAJOR 19
-#define MY_VER_MINOR 00
-#define MY_VER_BUILD 0
-#define MY_VERSION_NUMBERS "19.00"
-#define MY_VERSION MY_VERSION_NUMBERS
-
-#ifdef MY_CPU_NAME
- #define MY_VERSION_CPU MY_VERSION " (" MY_CPU_NAME ")"
-#else
- #define MY_VERSION_CPU MY_VERSION
-#endif
-
-#define MY_DATE "2019-02-21"
-#undef MY_COPYRIGHT
-#undef MY_VERSION_COPYRIGHT_DATE
-#define MY_AUTHOR_NAME "Igor Pavlov"
-#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
-#define MY_COPYRIGHT_CR "Copyright (c) 1999-2018 Igor Pavlov"
-
-#ifdef USE_COPYRIGHT_CR
- #define MY_COPYRIGHT MY_COPYRIGHT_CR
-#else
- #define MY_COPYRIGHT MY_COPYRIGHT_PD
-#endif
-
-#define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE
-#define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE
+#define MY_VER_MAJOR 19
+#define MY_VER_MINOR 00
+#define MY_VER_BUILD 0
+#define MY_VERSION_NUMBERS "19.00"
+#define MY_VERSION MY_VERSION_NUMBERS
+
+#ifdef MY_CPU_NAME
+ #define MY_VERSION_CPU MY_VERSION " (" MY_CPU_NAME ")"
+#else
+ #define MY_VERSION_CPU MY_VERSION
+#endif
+
+#define MY_DATE "2019-02-21"
+#undef MY_COPYRIGHT
+#undef MY_VERSION_COPYRIGHT_DATE
+#define MY_AUTHOR_NAME "Igor Pavlov"
+#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
+#define MY_COPYRIGHT_CR "Copyright (c) 1999-2018 Igor Pavlov"
+
+#ifdef USE_COPYRIGHT_CR
+ #define MY_COPYRIGHT MY_COPYRIGHT_CR
+#else
+ #define MY_COPYRIGHT MY_COPYRIGHT_PD
+#endif
+
+#define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE
diff --git a/contrib/libs/lzmasdk/Aes.c b/contrib/libs/lzmasdk/Aes.c
index dc85b78788..1cdd0e787b 100644
--- a/contrib/libs/lzmasdk/Aes.c
+++ b/contrib/libs/lzmasdk/Aes.c
@@ -1,306 +1,306 @@
-/* Aes.c -- AES encryption / decryption
-2017-01-24 : Igor Pavlov : Public domain */
-
-#include "Precomp.h"
-
-#include "Aes.h"
-#include "CpuArch.h"
-
-static UInt32 T[256 * 4];
-static const Byte Sbox[256] = {
- 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
- 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
- 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
- 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
- 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
- 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
- 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
- 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
- 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
- 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
- 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
- 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
- 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
- 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
- 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
- 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};
-
-void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks);
-void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks);
-void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks);
-
-void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
-void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
-void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
-
-AES_CODE_FUNC g_AesCbc_Encode;
-AES_CODE_FUNC g_AesCbc_Decode;
-AES_CODE_FUNC g_AesCtr_Code;
-
-static UInt32 D[256 * 4];
-static Byte InvS[256];
-
-static const Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
-
-#define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF)
-
-#define Ui32(a0, a1, a2, a3) ((UInt32)(a0) | ((UInt32)(a1) << 8) | ((UInt32)(a2) << 16) | ((UInt32)(a3) << 24))
-
-#define gb0(x) ( (x) & 0xFF)
-#define gb1(x) (((x) >> ( 8)) & 0xFF)
-#define gb2(x) (((x) >> (16)) & 0xFF)
-#define gb3(x) (((x) >> (24)))
-
-#define gb(n, x) gb ## n(x)
-
-#define TT(x) (T + (x << 8))
-#define DD(x) (D + (x << 8))
-
-
-void AesGenTables(void)
-{
- unsigned i;
- for (i = 0; i < 256; i++)
- InvS[Sbox[i]] = (Byte)i;
-
- for (i = 0; i < 256; i++)
- {
- {
- UInt32 a1 = Sbox[i];
- UInt32 a2 = xtime(a1);
- UInt32 a3 = a2 ^ a1;
- TT(0)[i] = Ui32(a2, a1, a1, a3);
- TT(1)[i] = Ui32(a3, a2, a1, a1);
- TT(2)[i] = Ui32(a1, a3, a2, a1);
- TT(3)[i] = Ui32(a1, a1, a3, a2);
- }
- {
- UInt32 a1 = InvS[i];
- UInt32 a2 = xtime(a1);
- UInt32 a4 = xtime(a2);
- UInt32 a8 = xtime(a4);
- UInt32 a9 = a8 ^ a1;
- UInt32 aB = a8 ^ a2 ^ a1;
- UInt32 aD = a8 ^ a4 ^ a1;
- UInt32 aE = a8 ^ a4 ^ a2;
- DD(0)[i] = Ui32(aE, a9, aD, aB);
- DD(1)[i] = Ui32(aB, aE, a9, aD);
- DD(2)[i] = Ui32(aD, aB, aE, a9);
- DD(3)[i] = Ui32(a9, aD, aB, aE);
- }
- }
-
- g_AesCbc_Encode = AesCbc_Encode;
- g_AesCbc_Decode = AesCbc_Decode;
- g_AesCtr_Code = AesCtr_Code;
-
- #ifdef MY_CPU_X86_OR_AMD64
- if (CPU_Is_Aes_Supported())
- {
- g_AesCbc_Encode = AesCbc_Encode_Intel;
- g_AesCbc_Decode = AesCbc_Decode_Intel;
- g_AesCtr_Code = AesCtr_Code_Intel;
- }
- #endif
-}
-
-
-#define HT(i, x, s) TT(x)[gb(x, s[(i + x) & 3])]
-
-#define HT4(m, i, s, p) m[i] = \
- HT(i, 0, s) ^ \
- HT(i, 1, s) ^ \
- HT(i, 2, s) ^ \
- HT(i, 3, s) ^ w[p + i]
-
-#define HT16(m, s, p) \
- HT4(m, 0, s, p); \
- HT4(m, 1, s, p); \
- HT4(m, 2, s, p); \
- HT4(m, 3, s, p); \
-
-#define FT(i, x) Sbox[gb(x, m[(i + x) & 3])]
-#define FT4(i) dest[i] = Ui32(FT(i, 0), FT(i, 1), FT(i, 2), FT(i, 3)) ^ w[i];
-
-
-#define HD(i, x, s) DD(x)[gb(x, s[(i - x) & 3])]
-
-#define HD4(m, i, s, p) m[i] = \
- HD(i, 0, s) ^ \
- HD(i, 1, s) ^ \
- HD(i, 2, s) ^ \
- HD(i, 3, s) ^ w[p + i];
-
-#define HD16(m, s, p) \
- HD4(m, 0, s, p); \
- HD4(m, 1, s, p); \
- HD4(m, 2, s, p); \
- HD4(m, 3, s, p); \
-
-#define FD(i, x) InvS[gb(x, m[(i - x) & 3])]
-#define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i];
-
-void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize)
-{
- unsigned i, wSize;
- wSize = keySize + 28;
- keySize /= 4;
- w[0] = ((UInt32)keySize / 2) + 3;
- w += 4;
-
- for (i = 0; i < keySize; i++, key += 4)
- w[i] = GetUi32(key);
-
- for (; i < wSize; i++)
- {
- UInt32 t = w[(size_t)i - 1];
- unsigned rem = i % keySize;
- if (rem == 0)
- t = Ui32(Sbox[gb1(t)] ^ Rcon[i / keySize], Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]);
- else if (keySize > 6 && rem == 4)
- t = Ui32(Sbox[gb0(t)], Sbox[gb1(t)], Sbox[gb2(t)], Sbox[gb3(t)]);
- w[i] = w[i - keySize] ^ t;
- }
-}
-
-void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize)
-{
- unsigned i, num;
- Aes_SetKey_Enc(w, key, keySize);
- num = keySize + 20;
- w += 8;
- for (i = 0; i < num; i++)
- {
- UInt32 r = w[i];
- w[i] =
- DD(0)[Sbox[gb0(r)]] ^
- DD(1)[Sbox[gb1(r)]] ^
- DD(2)[Sbox[gb2(r)]] ^
- DD(3)[Sbox[gb3(r)]];
- }
-}
-
-/* Aes_Encode and Aes_Decode functions work with little-endian words.
- src and dest are pointers to 4 UInt32 words.
- src and dest can point to same block */
-
-static void Aes_Encode(const UInt32 *w, UInt32 *dest, const UInt32 *src)
-{
- UInt32 s[4];
- UInt32 m[4];
- UInt32 numRounds2 = w[0];
- w += 4;
- s[0] = src[0] ^ w[0];
- s[1] = src[1] ^ w[1];
- s[2] = src[2] ^ w[2];
- s[3] = src[3] ^ w[3];
- w += 4;
- for (;;)
- {
- HT16(m, s, 0);
- if (--numRounds2 == 0)
- break;
- HT16(s, m, 4);
- w += 8;
- }
- w += 4;
- FT4(0); FT4(1); FT4(2); FT4(3);
-}
-
-static void Aes_Decode(const UInt32 *w, UInt32 *dest, const UInt32 *src)
-{
- UInt32 s[4];
- UInt32 m[4];
- UInt32 numRounds2 = w[0];
- w += 4 + numRounds2 * 8;
- s[0] = src[0] ^ w[0];
- s[1] = src[1] ^ w[1];
- s[2] = src[2] ^ w[2];
- s[3] = src[3] ^ w[3];
- for (;;)
- {
- w -= 8;
- HD16(m, s, 4);
- if (--numRounds2 == 0)
- break;
- HD16(s, m, 0);
- }
- FD4(0); FD4(1); FD4(2); FD4(3);
-}
-
-void AesCbc_Init(UInt32 *p, const Byte *iv)
-{
- unsigned i;
- for (i = 0; i < 4; i++)
- p[i] = GetUi32(iv + i * 4);
-}
-
-void MY_FAST_CALL AesCbc_Encode(UInt32 *p, Byte *data, size_t numBlocks)
-{
- for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE)
- {
- p[0] ^= GetUi32(data);
- p[1] ^= GetUi32(data + 4);
- p[2] ^= GetUi32(data + 8);
- p[3] ^= GetUi32(data + 12);
-
- Aes_Encode(p + 4, p, p);
-
- SetUi32(data, p[0]);
- SetUi32(data + 4, p[1]);
- SetUi32(data + 8, p[2]);
- SetUi32(data + 12, p[3]);
- }
-}
-
-void MY_FAST_CALL AesCbc_Decode(UInt32 *p, Byte *data, size_t numBlocks)
-{
- UInt32 in[4], out[4];
- for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE)
- {
- in[0] = GetUi32(data);
- in[1] = GetUi32(data + 4);
- in[2] = GetUi32(data + 8);
- in[3] = GetUi32(data + 12);
-
- Aes_Decode(p + 4, out, in);
-
- SetUi32(data, p[0] ^ out[0]);
- SetUi32(data + 4, p[1] ^ out[1]);
- SetUi32(data + 8, p[2] ^ out[2]);
- SetUi32(data + 12, p[3] ^ out[3]);
-
- p[0] = in[0];
- p[1] = in[1];
- p[2] = in[2];
- p[3] = in[3];
- }
-}
-
-void MY_FAST_CALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks)
-{
- for (; numBlocks != 0; numBlocks--)
- {
- UInt32 temp[4];
- unsigned i;
-
- if (++p[0] == 0)
- p[1]++;
-
- Aes_Encode(p + 4, temp, p);
-
- for (i = 0; i < 4; i++, data += 4)
- {
- UInt32 t = temp[i];
-
- #ifdef MY_CPU_LE_UNALIGN
- *((UInt32 *)data) ^= t;
- #else
- data[0] ^= (t & 0xFF);
- data[1] ^= ((t >> 8) & 0xFF);
- data[2] ^= ((t >> 16) & 0xFF);
- data[3] ^= ((t >> 24));
- #endif
- }
- }
-}
+/* Aes.c -- AES encryption / decryption
+2017-01-24 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include "Aes.h"
+#include "CpuArch.h"
+
+static UInt32 T[256 * 4];
+static const Byte Sbox[256] = {
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};
+
+void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks);
+void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks);
+void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks);
+
+void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
+void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
+void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
+
+AES_CODE_FUNC g_AesCbc_Encode;
+AES_CODE_FUNC g_AesCbc_Decode;
+AES_CODE_FUNC g_AesCtr_Code;
+
+static UInt32 D[256 * 4];
+static Byte InvS[256];
+
+static const Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
+
+#define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF)
+
+#define Ui32(a0, a1, a2, a3) ((UInt32)(a0) | ((UInt32)(a1) << 8) | ((UInt32)(a2) << 16) | ((UInt32)(a3) << 24))
+
+#define gb0(x) ( (x) & 0xFF)
+#define gb1(x) (((x) >> ( 8)) & 0xFF)
+#define gb2(x) (((x) >> (16)) & 0xFF)
+#define gb3(x) (((x) >> (24)))
+
+#define gb(n, x) gb ## n(x)
+
+#define TT(x) (T + (x << 8))
+#define DD(x) (D + (x << 8))
+
+
+void AesGenTables(void)
+{
+ unsigned i;
+ for (i = 0; i < 256; i++)
+ InvS[Sbox[i]] = (Byte)i;
+
+ for (i = 0; i < 256; i++)
+ {
+ {
+ UInt32 a1 = Sbox[i];
+ UInt32 a2 = xtime(a1);
+ UInt32 a3 = a2 ^ a1;
+ TT(0)[i] = Ui32(a2, a1, a1, a3);
+ TT(1)[i] = Ui32(a3, a2, a1, a1);
+ TT(2)[i] = Ui32(a1, a3, a2, a1);
+ TT(3)[i] = Ui32(a1, a1, a3, a2);
+ }
+ {
+ UInt32 a1 = InvS[i];
+ UInt32 a2 = xtime(a1);
+ UInt32 a4 = xtime(a2);
+ UInt32 a8 = xtime(a4);
+ UInt32 a9 = a8 ^ a1;
+ UInt32 aB = a8 ^ a2 ^ a1;
+ UInt32 aD = a8 ^ a4 ^ a1;
+ UInt32 aE = a8 ^ a4 ^ a2;
+ DD(0)[i] = Ui32(aE, a9, aD, aB);
+ DD(1)[i] = Ui32(aB, aE, a9, aD);
+ DD(2)[i] = Ui32(aD, aB, aE, a9);
+ DD(3)[i] = Ui32(a9, aD, aB, aE);
+ }
+ }
+
+ g_AesCbc_Encode = AesCbc_Encode;
+ g_AesCbc_Decode = AesCbc_Decode;
+ g_AesCtr_Code = AesCtr_Code;
+
+ #ifdef MY_CPU_X86_OR_AMD64
+ if (CPU_Is_Aes_Supported())
+ {
+ g_AesCbc_Encode = AesCbc_Encode_Intel;
+ g_AesCbc_Decode = AesCbc_Decode_Intel;
+ g_AesCtr_Code = AesCtr_Code_Intel;
+ }
+ #endif
+}
+
+
+#define HT(i, x, s) TT(x)[gb(x, s[(i + x) & 3])]
+
+#define HT4(m, i, s, p) m[i] = \
+ HT(i, 0, s) ^ \
+ HT(i, 1, s) ^ \
+ HT(i, 2, s) ^ \
+ HT(i, 3, s) ^ w[p + i]
+
+#define HT16(m, s, p) \
+ HT4(m, 0, s, p); \
+ HT4(m, 1, s, p); \
+ HT4(m, 2, s, p); \
+ HT4(m, 3, s, p); \
+
+#define FT(i, x) Sbox[gb(x, m[(i + x) & 3])]
+#define FT4(i) dest[i] = Ui32(FT(i, 0), FT(i, 1), FT(i, 2), FT(i, 3)) ^ w[i];
+
+
+#define HD(i, x, s) DD(x)[gb(x, s[(i - x) & 3])]
+
+#define HD4(m, i, s, p) m[i] = \
+ HD(i, 0, s) ^ \
+ HD(i, 1, s) ^ \
+ HD(i, 2, s) ^ \
+ HD(i, 3, s) ^ w[p + i];
+
+#define HD16(m, s, p) \
+ HD4(m, 0, s, p); \
+ HD4(m, 1, s, p); \
+ HD4(m, 2, s, p); \
+ HD4(m, 3, s, p); \
+
+#define FD(i, x) InvS[gb(x, m[(i - x) & 3])]
+#define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i];
+
+void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize)
+{
+ unsigned i, wSize;
+ wSize = keySize + 28;
+ keySize /= 4;
+ w[0] = ((UInt32)keySize / 2) + 3;
+ w += 4;
+
+ for (i = 0; i < keySize; i++, key += 4)
+ w[i] = GetUi32(key);
+
+ for (; i < wSize; i++)
+ {
+ UInt32 t = w[(size_t)i - 1];
+ unsigned rem = i % keySize;
+ if (rem == 0)
+ t = Ui32(Sbox[gb1(t)] ^ Rcon[i / keySize], Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]);
+ else if (keySize > 6 && rem == 4)
+ t = Ui32(Sbox[gb0(t)], Sbox[gb1(t)], Sbox[gb2(t)], Sbox[gb3(t)]);
+ w[i] = w[i - keySize] ^ t;
+ }
+}
+
+void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize)
+{
+ unsigned i, num;
+ Aes_SetKey_Enc(w, key, keySize);
+ num = keySize + 20;
+ w += 8;
+ for (i = 0; i < num; i++)
+ {
+ UInt32 r = w[i];
+ w[i] =
+ DD(0)[Sbox[gb0(r)]] ^
+ DD(1)[Sbox[gb1(r)]] ^
+ DD(2)[Sbox[gb2(r)]] ^
+ DD(3)[Sbox[gb3(r)]];
+ }
+}
+
+/* Aes_Encode and Aes_Decode functions work with little-endian words.
+ src and dest are pointers to 4 UInt32 words.
+ src and dest can point to same block */
+
+static void Aes_Encode(const UInt32 *w, UInt32 *dest, const UInt32 *src)
+{
+ UInt32 s[4];
+ UInt32 m[4];
+ UInt32 numRounds2 = w[0];
+ w += 4;
+ s[0] = src[0] ^ w[0];
+ s[1] = src[1] ^ w[1];
+ s[2] = src[2] ^ w[2];
+ s[3] = src[3] ^ w[3];
+ w += 4;
+ for (;;)
+ {
+ HT16(m, s, 0);
+ if (--numRounds2 == 0)
+ break;
+ HT16(s, m, 4);
+ w += 8;
+ }
+ w += 4;
+ FT4(0); FT4(1); FT4(2); FT4(3);
+}
+
+static void Aes_Decode(const UInt32 *w, UInt32 *dest, const UInt32 *src)
+{
+ UInt32 s[4];
+ UInt32 m[4];
+ UInt32 numRounds2 = w[0];
+ w += 4 + numRounds2 * 8;
+ s[0] = src[0] ^ w[0];
+ s[1] = src[1] ^ w[1];
+ s[2] = src[2] ^ w[2];
+ s[3] = src[3] ^ w[3];
+ for (;;)
+ {
+ w -= 8;
+ HD16(m, s, 4);
+ if (--numRounds2 == 0)
+ break;
+ HD16(s, m, 0);
+ }
+ FD4(0); FD4(1); FD4(2); FD4(3);
+}
+
+void AesCbc_Init(UInt32 *p, const Byte *iv)
+{
+ unsigned i;
+ for (i = 0; i < 4; i++)
+ p[i] = GetUi32(iv + i * 4);
+}
+
+void MY_FAST_CALL AesCbc_Encode(UInt32 *p, Byte *data, size_t numBlocks)
+{
+ for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE)
+ {
+ p[0] ^= GetUi32(data);
+ p[1] ^= GetUi32(data + 4);
+ p[2] ^= GetUi32(data + 8);
+ p[3] ^= GetUi32(data + 12);
+
+ Aes_Encode(p + 4, p, p);
+
+ SetUi32(data, p[0]);
+ SetUi32(data + 4, p[1]);
+ SetUi32(data + 8, p[2]);
+ SetUi32(data + 12, p[3]);
+ }
+}
+
+void MY_FAST_CALL AesCbc_Decode(UInt32 *p, Byte *data, size_t numBlocks)
+{
+ UInt32 in[4], out[4];
+ for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE)
+ {
+ in[0] = GetUi32(data);
+ in[1] = GetUi32(data + 4);
+ in[2] = GetUi32(data + 8);
+ in[3] = GetUi32(data + 12);
+
+ Aes_Decode(p + 4, out, in);
+
+ SetUi32(data, p[0] ^ out[0]);
+ SetUi32(data + 4, p[1] ^ out[1]);
+ SetUi32(data + 8, p[2] ^ out[2]);
+ SetUi32(data + 12, p[3] ^ out[3]);
+
+ p[0] = in[0];
+ p[1] = in[1];
+ p[2] = in[2];
+ p[3] = in[3];
+ }
+}
+
+void MY_FAST_CALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks)
+{
+ for (; numBlocks != 0; numBlocks--)
+ {
+ UInt32 temp[4];
+ unsigned i;
+
+ if (++p[0] == 0)
+ p[1]++;
+
+ Aes_Encode(p + 4, temp, p);
+
+ for (i = 0; i < 4; i++, data += 4)
+ {
+ UInt32 t = temp[i];
+
+ #ifdef MY_CPU_LE_UNALIGN
+ *((UInt32 *)data) ^= t;
+ #else
+ data[0] ^= (t & 0xFF);
+ data[1] ^= ((t >> 8) & 0xFF);
+ data[2] ^= ((t >> 16) & 0xFF);
+ data[3] ^= ((t >> 24));
+ #endif
+ }
+ }
+}
diff --git a/contrib/libs/lzmasdk/Aes.h b/contrib/libs/lzmasdk/Aes.h
index 167865600c..64979b5bcb 100644
--- a/contrib/libs/lzmasdk/Aes.h
+++ b/contrib/libs/lzmasdk/Aes.h
@@ -1,38 +1,38 @@
-/* Aes.h -- AES encryption / decryption
-2013-01-18 : Igor Pavlov : Public domain */
-
-#ifndef __AES_H
-#define __AES_H
-
-#include "7zTypes.h"
-
-EXTERN_C_BEGIN
-
-#define AES_BLOCK_SIZE 16
-
-/* Call AesGenTables one time before other AES functions */
-void AesGenTables(void);
-
-/* UInt32 pointers must be 16-byte aligned */
-
-/* 16-byte (4 * 32-bit words) blocks: 1 (IV) + 1 (keyMode) + 15 (AES-256 roundKeys) */
-#define AES_NUM_IVMRK_WORDS ((1 + 1 + 15) * 4)
-
-/* aes - 16-byte aligned pointer to keyMode+roundKeys sequence */
-/* keySize = 16 or 24 or 32 (bytes) */
-typedef void (MY_FAST_CALL *AES_SET_KEY_FUNC)(UInt32 *aes, const Byte *key, unsigned keySize);
-void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *aes, const Byte *key, unsigned keySize);
-void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *aes, const Byte *key, unsigned keySize);
-
-/* ivAes - 16-byte aligned pointer to iv+keyMode+roundKeys sequence: UInt32[AES_NUM_IVMRK_WORDS] */
-void AesCbc_Init(UInt32 *ivAes, const Byte *iv); /* iv size is AES_BLOCK_SIZE */
-/* data - 16-byte aligned pointer to data */
-/* numBlocks - the number of 16-byte blocks in data array */
-typedef void (MY_FAST_CALL *AES_CODE_FUNC)(UInt32 *ivAes, Byte *data, size_t numBlocks);
-extern AES_CODE_FUNC g_AesCbc_Encode;
-extern AES_CODE_FUNC g_AesCbc_Decode;
-extern AES_CODE_FUNC g_AesCtr_Code;
-
-EXTERN_C_END
-
-#endif
+/* Aes.h -- AES encryption / decryption
+2013-01-18 : Igor Pavlov : Public domain */
+
+#ifndef __AES_H
+#define __AES_H
+
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
+#define AES_BLOCK_SIZE 16
+
+/* Call AesGenTables one time before other AES functions */
+void AesGenTables(void);
+
+/* UInt32 pointers must be 16-byte aligned */
+
+/* 16-byte (4 * 32-bit words) blocks: 1 (IV) + 1 (keyMode) + 15 (AES-256 roundKeys) */
+#define AES_NUM_IVMRK_WORDS ((1 + 1 + 15) * 4)
+
+/* aes - 16-byte aligned pointer to keyMode+roundKeys sequence */
+/* keySize = 16 or 24 or 32 (bytes) */
+typedef void (MY_FAST_CALL *AES_SET_KEY_FUNC)(UInt32 *aes, const Byte *key, unsigned keySize);
+void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *aes, const Byte *key, unsigned keySize);
+void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *aes, const Byte *key, unsigned keySize);
+
+/* ivAes - 16-byte aligned pointer to iv+keyMode+roundKeys sequence: UInt32[AES_NUM_IVMRK_WORDS] */
+void AesCbc_Init(UInt32 *ivAes, const Byte *iv); /* iv size is AES_BLOCK_SIZE */
+/* data - 16-byte aligned pointer to data */
+/* numBlocks - the number of 16-byte blocks in data array */
+typedef void (MY_FAST_CALL *AES_CODE_FUNC)(UInt32 *ivAes, Byte *data, size_t numBlocks);
+extern AES_CODE_FUNC g_AesCbc_Encode;
+extern AES_CODE_FUNC g_AesCbc_Decode;
+extern AES_CODE_FUNC g_AesCtr_Code;
+
+EXTERN_C_END
+
+#endif
diff --git a/contrib/libs/lzmasdk/AesOpt.c b/contrib/libs/lzmasdk/AesOpt.c
index 6ade8f42ff..00291288ba 100644
--- a/contrib/libs/lzmasdk/AesOpt.c
+++ b/contrib/libs/lzmasdk/AesOpt.c
@@ -1,188 +1,188 @@
-/* AesOpt.c -- Intel's AES
-2017-06-08 : Igor Pavlov : Public domain */
-
-#include "Precomp.h"
-
-#include "CpuArch.h"
-
-#ifdef MY_CPU_X86_OR_AMD64
-#if (_MSC_VER > 1500) || (_MSC_FULL_VER >= 150030729)
-#define USE_INTEL_AES
-#endif
-#endif
-
-#ifdef USE_INTEL_AES
-
+/* AesOpt.c -- Intel's AES
+2017-06-08 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include "CpuArch.h"
+
+#ifdef MY_CPU_X86_OR_AMD64
+#if (_MSC_VER > 1500) || (_MSC_FULL_VER >= 150030729)
+#define USE_INTEL_AES
+#endif
+#endif
+
+#ifdef USE_INTEL_AES
+
#if defined(__clang__)
#define TARGET_AES __attribute__((__target__("aes")))
#else
#define TARGET_AES
#endif
-#include <wmmintrin.h>
-
+#include <wmmintrin.h>
+
void TARGET_AES MY_FAST_CALL AesCbc_Encode_Intel(__m128i *p, __m128i *data, size_t numBlocks)
-{
- __m128i m = *p;
- for (; numBlocks != 0; numBlocks--, data++)
- {
- UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1;
- const __m128i *w = p + 3;
- m = _mm_xor_si128(m, *data);
- m = _mm_xor_si128(m, p[2]);
- do
- {
- m = _mm_aesenc_si128(m, w[0]);
- m = _mm_aesenc_si128(m, w[1]);
- w += 2;
- }
- while (--numRounds2 != 0);
- m = _mm_aesenc_si128(m, w[0]);
- m = _mm_aesenclast_si128(m, w[1]);
- *data = m;
- }
- *p = m;
-}
-
-#define NUM_WAYS 3
-
-#define AES_OP_W(op, n) { \
- const __m128i t = w[n]; \
- m0 = op(m0, t); \
- m1 = op(m1, t); \
- m2 = op(m2, t); \
- }
-
-#define AES_DEC(n) AES_OP_W(_mm_aesdec_si128, n)
-#define AES_DEC_LAST(n) AES_OP_W(_mm_aesdeclast_si128, n)
-#define AES_ENC(n) AES_OP_W(_mm_aesenc_si128, n)
-#define AES_ENC_LAST(n) AES_OP_W(_mm_aesenclast_si128, n)
-
+{
+ __m128i m = *p;
+ for (; numBlocks != 0; numBlocks--, data++)
+ {
+ UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1;
+ const __m128i *w = p + 3;
+ m = _mm_xor_si128(m, *data);
+ m = _mm_xor_si128(m, p[2]);
+ do
+ {
+ m = _mm_aesenc_si128(m, w[0]);
+ m = _mm_aesenc_si128(m, w[1]);
+ w += 2;
+ }
+ while (--numRounds2 != 0);
+ m = _mm_aesenc_si128(m, w[0]);
+ m = _mm_aesenclast_si128(m, w[1]);
+ *data = m;
+ }
+ *p = m;
+}
+
+#define NUM_WAYS 3
+
+#define AES_OP_W(op, n) { \
+ const __m128i t = w[n]; \
+ m0 = op(m0, t); \
+ m1 = op(m1, t); \
+ m2 = op(m2, t); \
+ }
+
+#define AES_DEC(n) AES_OP_W(_mm_aesdec_si128, n)
+#define AES_DEC_LAST(n) AES_OP_W(_mm_aesdeclast_si128, n)
+#define AES_ENC(n) AES_OP_W(_mm_aesenc_si128, n)
+#define AES_ENC_LAST(n) AES_OP_W(_mm_aesenclast_si128, n)
+
void TARGET_AES MY_FAST_CALL AesCbc_Decode_Intel(__m128i *p, __m128i *data, size_t numBlocks)
-{
- __m128i iv = *p;
- for (; numBlocks >= NUM_WAYS; numBlocks -= NUM_WAYS, data += NUM_WAYS)
- {
- UInt32 numRounds2 = *(const UInt32 *)(p + 1);
- const __m128i *w = p + numRounds2 * 2;
- __m128i m0, m1, m2;
- {
- const __m128i t = w[2];
- m0 = _mm_xor_si128(t, data[0]);
- m1 = _mm_xor_si128(t, data[1]);
- m2 = _mm_xor_si128(t, data[2]);
- }
- numRounds2--;
- do
- {
- AES_DEC(1)
- AES_DEC(0)
- w -= 2;
- }
- while (--numRounds2 != 0);
- AES_DEC(1)
- AES_DEC_LAST(0)
-
- {
- __m128i t;
- t = _mm_xor_si128(m0, iv); iv = data[0]; data[0] = t;
- t = _mm_xor_si128(m1, iv); iv = data[1]; data[1] = t;
- t = _mm_xor_si128(m2, iv); iv = data[2]; data[2] = t;
- }
- }
- for (; numBlocks != 0; numBlocks--, data++)
- {
- UInt32 numRounds2 = *(const UInt32 *)(p + 1);
- const __m128i *w = p + numRounds2 * 2;
- __m128i m = _mm_xor_si128(w[2], *data);
- numRounds2--;
- do
- {
- m = _mm_aesdec_si128(m, w[1]);
- m = _mm_aesdec_si128(m, w[0]);
- w -= 2;
- }
- while (--numRounds2 != 0);
- m = _mm_aesdec_si128(m, w[1]);
- m = _mm_aesdeclast_si128(m, w[0]);
-
- m = _mm_xor_si128(m, iv);
- iv = *data;
- *data = m;
- }
- *p = iv;
-}
-
+{
+ __m128i iv = *p;
+ for (; numBlocks >= NUM_WAYS; numBlocks -= NUM_WAYS, data += NUM_WAYS)
+ {
+ UInt32 numRounds2 = *(const UInt32 *)(p + 1);
+ const __m128i *w = p + numRounds2 * 2;
+ __m128i m0, m1, m2;
+ {
+ const __m128i t = w[2];
+ m0 = _mm_xor_si128(t, data[0]);
+ m1 = _mm_xor_si128(t, data[1]);
+ m2 = _mm_xor_si128(t, data[2]);
+ }
+ numRounds2--;
+ do
+ {
+ AES_DEC(1)
+ AES_DEC(0)
+ w -= 2;
+ }
+ while (--numRounds2 != 0);
+ AES_DEC(1)
+ AES_DEC_LAST(0)
+
+ {
+ __m128i t;
+ t = _mm_xor_si128(m0, iv); iv = data[0]; data[0] = t;
+ t = _mm_xor_si128(m1, iv); iv = data[1]; data[1] = t;
+ t = _mm_xor_si128(m2, iv); iv = data[2]; data[2] = t;
+ }
+ }
+ for (; numBlocks != 0; numBlocks--, data++)
+ {
+ UInt32 numRounds2 = *(const UInt32 *)(p + 1);
+ const __m128i *w = p + numRounds2 * 2;
+ __m128i m = _mm_xor_si128(w[2], *data);
+ numRounds2--;
+ do
+ {
+ m = _mm_aesdec_si128(m, w[1]);
+ m = _mm_aesdec_si128(m, w[0]);
+ w -= 2;
+ }
+ while (--numRounds2 != 0);
+ m = _mm_aesdec_si128(m, w[1]);
+ m = _mm_aesdeclast_si128(m, w[0]);
+
+ m = _mm_xor_si128(m, iv);
+ iv = *data;
+ *data = m;
+ }
+ *p = iv;
+}
+
void TARGET_AES MY_FAST_CALL AesCtr_Code_Intel(__m128i *p, __m128i *data, size_t numBlocks)
-{
- __m128i ctr = *p;
+{
+ __m128i ctr = *p;
__m128i one = _mm_set_epi64x(1, 0);
- for (; numBlocks >= NUM_WAYS; numBlocks -= NUM_WAYS, data += NUM_WAYS)
- {
- UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1;
- const __m128i *w = p;
- __m128i m0, m1, m2;
- {
- const __m128i t = w[2];
- ctr = _mm_add_epi64(ctr, one); m0 = _mm_xor_si128(ctr, t);
- ctr = _mm_add_epi64(ctr, one); m1 = _mm_xor_si128(ctr, t);
- ctr = _mm_add_epi64(ctr, one); m2 = _mm_xor_si128(ctr, t);
- }
- w += 3;
- do
- {
- AES_ENC(0)
- AES_ENC(1)
- w += 2;
- }
- while (--numRounds2 != 0);
- AES_ENC(0)
- AES_ENC_LAST(1)
- data[0] = _mm_xor_si128(data[0], m0);
- data[1] = _mm_xor_si128(data[1], m1);
- data[2] = _mm_xor_si128(data[2], m2);
- }
- for (; numBlocks != 0; numBlocks--, data++)
- {
- UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1;
- const __m128i *w = p;
- __m128i m;
- ctr = _mm_add_epi64(ctr, one);
- m = _mm_xor_si128(ctr, p[2]);
- w += 3;
- do
- {
- m = _mm_aesenc_si128(m, w[0]);
- m = _mm_aesenc_si128(m, w[1]);
- w += 2;
- }
- while (--numRounds2 != 0);
- m = _mm_aesenc_si128(m, w[0]);
- m = _mm_aesenclast_si128(m, w[1]);
- *data = _mm_xor_si128(*data, m);
- }
- *p = ctr;
-}
-
-#else
-
-void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks);
-void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks);
-void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks);
-
-void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *p, Byte *data, size_t numBlocks)
-{
- AesCbc_Encode(p, data, numBlocks);
-}
-
-void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *p, Byte *data, size_t numBlocks)
-{
- AesCbc_Decode(p, data, numBlocks);
-}
-
-void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *p, Byte *data, size_t numBlocks)
-{
- AesCtr_Code(p, data, numBlocks);
-}
-
-#endif
+ for (; numBlocks >= NUM_WAYS; numBlocks -= NUM_WAYS, data += NUM_WAYS)
+ {
+ UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1;
+ const __m128i *w = p;
+ __m128i m0, m1, m2;
+ {
+ const __m128i t = w[2];
+ ctr = _mm_add_epi64(ctr, one); m0 = _mm_xor_si128(ctr, t);
+ ctr = _mm_add_epi64(ctr, one); m1 = _mm_xor_si128(ctr, t);
+ ctr = _mm_add_epi64(ctr, one); m2 = _mm_xor_si128(ctr, t);
+ }
+ w += 3;
+ do
+ {
+ AES_ENC(0)
+ AES_ENC(1)
+ w += 2;
+ }
+ while (--numRounds2 != 0);
+ AES_ENC(0)
+ AES_ENC_LAST(1)
+ data[0] = _mm_xor_si128(data[0], m0);
+ data[1] = _mm_xor_si128(data[1], m1);
+ data[2] = _mm_xor_si128(data[2], m2);
+ }
+ for (; numBlocks != 0; numBlocks--, data++)
+ {
+ UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1;
+ const __m128i *w = p;
+ __m128i m;
+ ctr = _mm_add_epi64(ctr, one);
+ m = _mm_xor_si128(ctr, p[2]);
+ w += 3;
+ do
+ {
+ m = _mm_aesenc_si128(m, w[0]);
+ m = _mm_aesenc_si128(m, w[1]);
+ w += 2;
+ }
+ while (--numRounds2 != 0);
+ m = _mm_aesenc_si128(m, w[0]);
+ m = _mm_aesenclast_si128(m, w[1]);
+ *data = _mm_xor_si128(*data, m);
+ }
+ *p = ctr;
+}
+
+#else
+
+void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks);
+void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks);
+void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks);
+
+void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *p, Byte *data, size_t numBlocks)
+{
+ AesCbc_Encode(p, data, numBlocks);
+}
+
+void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *p, Byte *data, size_t numBlocks)
+{
+ AesCbc_Decode(p, data, numBlocks);
+}
+
+void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *p, Byte *data, size_t numBlocks)
+{
+ AesCtr_Code(p, data, numBlocks);
+}
+
+#endif
diff --git a/contrib/libs/lzmasdk/Bra.c b/contrib/libs/lzmasdk/Bra.c
index e04546ff30..aed17e330d 100644
--- a/contrib/libs/lzmasdk/Bra.c
+++ b/contrib/libs/lzmasdk/Bra.c
@@ -1,230 +1,230 @@
-/* Bra.c -- Converters for RISC code
-2017-04-04 : Igor Pavlov : Public domain */
-
-#include "Precomp.h"
-
-#include "CpuArch.h"
-#include "Bra.h"
-
-SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
-{
- Byte *p;
- const Byte *lim;
- size &= ~(size_t)3;
- ip += 4;
- p = data;
- lim = data + size;
-
- if (encoding)
-
- for (;;)
- {
- for (;;)
- {
- if (p >= lim)
- return p - data;
- p += 4;
- if (p[-1] == 0xEB)
- break;
- }
- {
- UInt32 v = GetUi32(p - 4);
- v <<= 2;
- v += ip + (UInt32)(p - data);
- v >>= 2;
- v &= 0x00FFFFFF;
- v |= 0xEB000000;
- SetUi32(p - 4, v);
- }
- }
-
- for (;;)
- {
- for (;;)
- {
- if (p >= lim)
- return p - data;
- p += 4;
- if (p[-1] == 0xEB)
- break;
- }
- {
- UInt32 v = GetUi32(p - 4);
- v <<= 2;
- v -= ip + (UInt32)(p - data);
- v >>= 2;
- v &= 0x00FFFFFF;
- v |= 0xEB000000;
- SetUi32(p - 4, v);
- }
- }
-}
-
-
-SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
-{
- Byte *p;
- const Byte *lim;
- size &= ~(size_t)1;
- p = data;
- lim = data + size - 4;
-
- if (encoding)
-
- for (;;)
- {
- UInt32 b1;
- for (;;)
- {
- UInt32 b3;
- if (p > lim)
- return p - data;
- b1 = p[1];
- b3 = p[3];
- p += 2;
- b1 ^= 8;
- if ((b3 & b1) >= 0xF8)
- break;
- }
- {
- UInt32 v =
- ((UInt32)b1 << 19)
- + (((UInt32)p[1] & 0x7) << 8)
- + (((UInt32)p[-2] << 11))
- + (p[0]);
-
- p += 2;
- {
- UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
- v += cur;
- }
-
- p[-4] = (Byte)(v >> 11);
- p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
- p[-2] = (Byte)v;
- p[-1] = (Byte)(0xF8 | (v >> 8));
- }
- }
-
- for (;;)
- {
- UInt32 b1;
- for (;;)
- {
- UInt32 b3;
- if (p > lim)
- return p - data;
- b1 = p[1];
- b3 = p[3];
- p += 2;
- b1 ^= 8;
- if ((b3 & b1) >= 0xF8)
- break;
- }
- {
- UInt32 v =
- ((UInt32)b1 << 19)
- + (((UInt32)p[1] & 0x7) << 8)
- + (((UInt32)p[-2] << 11))
- + (p[0]);
-
- p += 2;
- {
- UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
- v -= cur;
- }
-
- /*
- SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000));
- SetUi16(p - 2, (UInt16)(v | 0xF800));
- */
-
- p[-4] = (Byte)(v >> 11);
- p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
- p[-2] = (Byte)v;
- p[-1] = (Byte)(0xF8 | (v >> 8));
- }
- }
-}
-
-
-SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
-{
- Byte *p;
- const Byte *lim;
- size &= ~(size_t)3;
- ip -= 4;
- p = data;
- lim = data + size;
-
- for (;;)
- {
- for (;;)
- {
- if (p >= lim)
- return p - data;
- p += 4;
- /* if ((v & 0xFC000003) == 0x48000001) */
- if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1)
- break;
- }
- {
- UInt32 v = GetBe32(p - 4);
- if (encoding)
- v += ip + (UInt32)(p - data);
- else
- v -= ip + (UInt32)(p - data);
- v &= 0x03FFFFFF;
- v |= 0x48000000;
- SetBe32(p - 4, v);
- }
- }
-}
-
-
-SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
-{
- Byte *p;
- const Byte *lim;
- size &= ~(size_t)3;
- ip -= 4;
- p = data;
- lim = data + size;
-
- for (;;)
- {
- for (;;)
- {
- if (p >= lim)
- return p - data;
- /*
- v = GetBe32(p);
- p += 4;
- m = v + ((UInt32)5 << 29);
- m ^= (UInt32)7 << 29;
- m += (UInt32)1 << 22;
- if ((m & ((UInt32)0x1FF << 23)) == 0)
- break;
- */
- p += 4;
- if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) ||
- (p[-4] == 0x7F && (p[-3] >= 0xC0)))
- break;
- }
- {
- UInt32 v = GetBe32(p - 4);
- v <<= 2;
- if (encoding)
- v += ip + (UInt32)(p - data);
- else
- v -= ip + (UInt32)(p - data);
-
- v &= 0x01FFFFFF;
- v -= (UInt32)1 << 24;
- v ^= 0xFF000000;
- v >>= 2;
- v |= 0x40000000;
- SetBe32(p - 4, v);
- }
- }
-}
+/* Bra.c -- Converters for RISC code
+2017-04-04 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include "CpuArch.h"
+#include "Bra.h"
+
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+ Byte *p;
+ const Byte *lim;
+ size &= ~(size_t)3;
+ ip += 4;
+ p = data;
+ lim = data + size;
+
+ if (encoding)
+
+ for (;;)
+ {
+ for (;;)
+ {
+ if (p >= lim)
+ return p - data;
+ p += 4;
+ if (p[-1] == 0xEB)
+ break;
+ }
+ {
+ UInt32 v = GetUi32(p - 4);
+ v <<= 2;
+ v += ip + (UInt32)(p - data);
+ v >>= 2;
+ v &= 0x00FFFFFF;
+ v |= 0xEB000000;
+ SetUi32(p - 4, v);
+ }
+ }
+
+ for (;;)
+ {
+ for (;;)
+ {
+ if (p >= lim)
+ return p - data;
+ p += 4;
+ if (p[-1] == 0xEB)
+ break;
+ }
+ {
+ UInt32 v = GetUi32(p - 4);
+ v <<= 2;
+ v -= ip + (UInt32)(p - data);
+ v >>= 2;
+ v &= 0x00FFFFFF;
+ v |= 0xEB000000;
+ SetUi32(p - 4, v);
+ }
+ }
+}
+
+
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+ Byte *p;
+ const Byte *lim;
+ size &= ~(size_t)1;
+ p = data;
+ lim = data + size - 4;
+
+ if (encoding)
+
+ for (;;)
+ {
+ UInt32 b1;
+ for (;;)
+ {
+ UInt32 b3;
+ if (p > lim)
+ return p - data;
+ b1 = p[1];
+ b3 = p[3];
+ p += 2;
+ b1 ^= 8;
+ if ((b3 & b1) >= 0xF8)
+ break;
+ }
+ {
+ UInt32 v =
+ ((UInt32)b1 << 19)
+ + (((UInt32)p[1] & 0x7) << 8)
+ + (((UInt32)p[-2] << 11))
+ + (p[0]);
+
+ p += 2;
+ {
+ UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
+ v += cur;
+ }
+
+ p[-4] = (Byte)(v >> 11);
+ p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
+ p[-2] = (Byte)v;
+ p[-1] = (Byte)(0xF8 | (v >> 8));
+ }
+ }
+
+ for (;;)
+ {
+ UInt32 b1;
+ for (;;)
+ {
+ UInt32 b3;
+ if (p > lim)
+ return p - data;
+ b1 = p[1];
+ b3 = p[3];
+ p += 2;
+ b1 ^= 8;
+ if ((b3 & b1) >= 0xF8)
+ break;
+ }
+ {
+ UInt32 v =
+ ((UInt32)b1 << 19)
+ + (((UInt32)p[1] & 0x7) << 8)
+ + (((UInt32)p[-2] << 11))
+ + (p[0]);
+
+ p += 2;
+ {
+ UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
+ v -= cur;
+ }
+
+ /*
+ SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000));
+ SetUi16(p - 2, (UInt16)(v | 0xF800));
+ */
+
+ p[-4] = (Byte)(v >> 11);
+ p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
+ p[-2] = (Byte)v;
+ p[-1] = (Byte)(0xF8 | (v >> 8));
+ }
+ }
+}
+
+
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+ Byte *p;
+ const Byte *lim;
+ size &= ~(size_t)3;
+ ip -= 4;
+ p = data;
+ lim = data + size;
+
+ for (;;)
+ {
+ for (;;)
+ {
+ if (p >= lim)
+ return p - data;
+ p += 4;
+ /* if ((v & 0xFC000003) == 0x48000001) */
+ if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1)
+ break;
+ }
+ {
+ UInt32 v = GetBe32(p - 4);
+ if (encoding)
+ v += ip + (UInt32)(p - data);
+ else
+ v -= ip + (UInt32)(p - data);
+ v &= 0x03FFFFFF;
+ v |= 0x48000000;
+ SetBe32(p - 4, v);
+ }
+ }
+}
+
+
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+ Byte *p;
+ const Byte *lim;
+ size &= ~(size_t)3;
+ ip -= 4;
+ p = data;
+ lim = data + size;
+
+ for (;;)
+ {
+ for (;;)
+ {
+ if (p >= lim)
+ return p - data;
+ /*
+ v = GetBe32(p);
+ p += 4;
+ m = v + ((UInt32)5 << 29);
+ m ^= (UInt32)7 << 29;
+ m += (UInt32)1 << 22;
+ if ((m & ((UInt32)0x1FF << 23)) == 0)
+ break;
+ */
+ p += 4;
+ if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) ||
+ (p[-4] == 0x7F && (p[-3] >= 0xC0)))
+ break;
+ }
+ {
+ UInt32 v = GetBe32(p - 4);
+ v <<= 2;
+ if (encoding)
+ v += ip + (UInt32)(p - data);
+ else
+ v -= ip + (UInt32)(p - data);
+
+ v &= 0x01FFFFFF;
+ v -= (UInt32)1 << 24;
+ v ^= 0xFF000000;
+ v >>= 2;
+ v |= 0x40000000;
+ SetBe32(p - 4, v);
+ }
+ }
+}
diff --git a/contrib/libs/lzmasdk/Bra.h b/contrib/libs/lzmasdk/Bra.h
index f24c36ed6b..855e37a6b5 100644
--- a/contrib/libs/lzmasdk/Bra.h
+++ b/contrib/libs/lzmasdk/Bra.h
@@ -1,64 +1,64 @@
-/* Bra.h -- Branch converters for executables
-2013-01-18 : Igor Pavlov : Public domain */
-
-#ifndef __BRA_H
-#define __BRA_H
-
-#include "7zTypes.h"
-
-EXTERN_C_BEGIN
-
-/*
-These functions convert relative addresses to absolute addresses
-in CALL instructions to increase the compression ratio.
-
- In:
- data - data buffer
- size - size of data
- ip - current virtual Instruction Pinter (IP) value
- state - state variable for x86 converter
- encoding - 0 (for decoding), 1 (for encoding)
-
- Out:
- state - state variable for x86 converter
-
- Returns:
- The number of processed bytes. If you call these functions with multiple calls,
- you must start next call with first byte after block of processed bytes.
-
- Type Endian Alignment LookAhead
-
- x86 little 1 4
- ARMT little 2 2
- ARM little 4 0
- PPC big 4 0
- SPARC big 4 0
- IA64 little 16 0
-
- size must be >= Alignment + LookAhead, if it's not last block.
- If (size < Alignment + LookAhead), converter returns 0.
-
- Example:
-
- UInt32 ip = 0;
- for ()
- {
- ; size must be >= Alignment + LookAhead, if it's not last block
- SizeT processed = Convert(data, size, ip, 1);
- data += processed;
- size -= processed;
- ip += processed;
- }
-*/
-
-#define x86_Convert_Init(state) { state = 0; }
-SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
-SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
-SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
-SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
-SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
-SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
-
-EXTERN_C_END
-
-#endif
+/* Bra.h -- Branch converters for executables
+2013-01-18 : Igor Pavlov : Public domain */
+
+#ifndef __BRA_H
+#define __BRA_H
+
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
+/*
+These functions convert relative addresses to absolute addresses
+in CALL instructions to increase the compression ratio.
+
+ In:
+ data - data buffer
+ size - size of data
+ ip - current virtual Instruction Pinter (IP) value
+ state - state variable for x86 converter
+ encoding - 0 (for decoding), 1 (for encoding)
+
+ Out:
+ state - state variable for x86 converter
+
+ Returns:
+ The number of processed bytes. If you call these functions with multiple calls,
+ you must start next call with first byte after block of processed bytes.
+
+ Type Endian Alignment LookAhead
+
+ x86 little 1 4
+ ARMT little 2 2
+ ARM little 4 0
+ PPC big 4 0
+ SPARC big 4 0
+ IA64 little 16 0
+
+ size must be >= Alignment + LookAhead, if it's not last block.
+ If (size < Alignment + LookAhead), converter returns 0.
+
+ Example:
+
+ UInt32 ip = 0;
+ for ()
+ {
+ ; size must be >= Alignment + LookAhead, if it's not last block
+ SizeT processed = Convert(data, size, ip, 1);
+ data += processed;
+ size -= processed;
+ ip += processed;
+ }
+*/
+
+#define x86_Convert_Init(state) { state = 0; }
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+
+EXTERN_C_END
+
+#endif
diff --git a/contrib/libs/lzmasdk/Bra86.c b/contrib/libs/lzmasdk/Bra86.c
index 0a4747fe2e..93ed4d762b 100644
--- a/contrib/libs/lzmasdk/Bra86.c
+++ b/contrib/libs/lzmasdk/Bra86.c
@@ -1,82 +1,82 @@
-/* Bra86.c -- Converter for x86 code (BCJ)
-2017-04-03 : Igor Pavlov : Public domain */
-
-#include "Precomp.h"
-
-#include "Bra.h"
-
-#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0)
-
-SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
-{
- SizeT pos = 0;
- UInt32 mask = *state & 7;
- if (size < 5)
- return 0;
- size -= 4;
- ip += 5;
-
- for (;;)
- {
- Byte *p = data + pos;
- const Byte *limit = data + size;
- for (; p < limit; p++)
- if ((*p & 0xFE) == 0xE8)
- break;
-
- {
- SizeT d = (SizeT)(p - data - pos);
- pos = (SizeT)(p - data);
- if (p >= limit)
- {
- *state = (d > 2 ? 0 : mask >> (unsigned)d);
- return pos;
- }
- if (d > 2)
- mask = 0;
- else
- {
- mask >>= (unsigned)d;
- if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1])))
- {
- mask = (mask >> 1) | 4;
- pos++;
- continue;
- }
- }
- }
-
- if (Test86MSByte(p[4]))
- {
- UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
- UInt32 cur = ip + (UInt32)pos;
- pos += 5;
- if (encoding)
- v += cur;
- else
- v -= cur;
- if (mask != 0)
- {
- unsigned sh = (mask & 6) << 2;
- if (Test86MSByte((Byte)(v >> sh)))
- {
- v ^= (((UInt32)0x100 << sh) - 1);
- if (encoding)
- v += cur;
- else
- v -= cur;
- }
- mask = 0;
- }
- p[1] = (Byte)v;
- p[2] = (Byte)(v >> 8);
- p[3] = (Byte)(v >> 16);
- p[4] = (Byte)(0 - ((v >> 24) & 1));
- }
- else
- {
- mask = (mask >> 1) | 4;
- pos++;
- }
- }
-}
+/* Bra86.c -- Converter for x86 code (BCJ)
+2017-04-03 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include "Bra.h"
+
+#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0)
+
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
+{
+ SizeT pos = 0;
+ UInt32 mask = *state & 7;
+ if (size < 5)
+ return 0;
+ size -= 4;
+ ip += 5;
+
+ for (;;)
+ {
+ Byte *p = data + pos;
+ const Byte *limit = data + size;
+ for (; p < limit; p++)
+ if ((*p & 0xFE) == 0xE8)
+ break;
+
+ {
+ SizeT d = (SizeT)(p - data - pos);
+ pos = (SizeT)(p - data);
+ if (p >= limit)
+ {
+ *state = (d > 2 ? 0 : mask >> (unsigned)d);
+ return pos;
+ }
+ if (d > 2)
+ mask = 0;
+ else
+ {
+ mask >>= (unsigned)d;
+ if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1])))
+ {
+ mask = (mask >> 1) | 4;
+ pos++;
+ continue;
+ }
+ }
+ }
+
+ if (Test86MSByte(p[4]))
+ {
+ UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
+ UInt32 cur = ip + (UInt32)pos;
+ pos += 5;
+ if (encoding)
+ v += cur;
+ else
+ v -= cur;
+ if (mask != 0)
+ {
+ unsigned sh = (mask & 6) << 2;
+ if (Test86MSByte((Byte)(v >> sh)))
+ {
+ v ^= (((UInt32)0x100 << sh) - 1);
+ if (encoding)
+ v += cur;
+ else
+ v -= cur;
+ }
+ mask = 0;
+ }
+ p[1] = (Byte)v;
+ p[2] = (Byte)(v >> 8);
+ p[3] = (Byte)(v >> 16);
+ p[4] = (Byte)(0 - ((v >> 24) & 1));
+ }
+ else
+ {
+ mask = (mask >> 1) | 4;
+ pos++;
+ }
+ }
+}
diff --git a/contrib/libs/lzmasdk/BraIA64.c b/contrib/libs/lzmasdk/BraIA64.c
index 7cccd47b50..d1dbc62c55 100644
--- a/contrib/libs/lzmasdk/BraIA64.c
+++ b/contrib/libs/lzmasdk/BraIA64.c
@@ -1,53 +1,53 @@
-/* BraIA64.c -- Converter for IA-64 code
-2017-01-26 : Igor Pavlov : Public domain */
-
-#include "Precomp.h"
-
-#include "CpuArch.h"
-#include "Bra.h"
-
-SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
-{
- SizeT i;
- if (size < 16)
- return 0;
- size -= 16;
- i = 0;
- do
- {
- unsigned m = ((UInt32)0x334B0000 >> (data[i] & 0x1E)) & 3;
- if (m)
- {
- m++;
- do
- {
- Byte *p = data + (i + (size_t)m * 5 - 8);
- if (((p[3] >> m) & 15) == 5
- && (((p[-1] | ((UInt32)p[0] << 8)) >> m) & 0x70) == 0)
- {
- unsigned raw = GetUi32(p);
- unsigned v = raw >> m;
- v = (v & 0xFFFFF) | ((v & (1 << 23)) >> 3);
-
- v <<= 4;
- if (encoding)
- v += ip + (UInt32)i;
- else
- v -= ip + (UInt32)i;
- v >>= 4;
-
- v &= 0x1FFFFF;
- v += 0x700000;
- v &= 0x8FFFFF;
- raw &= ~((UInt32)0x8FFFFF << m);
- raw |= (v << m);
- SetUi32(p, raw);
- }
- }
- while (++m <= 4);
- }
- i += 16;
- }
- while (i <= size);
- return i;
-}
+/* BraIA64.c -- Converter for IA-64 code
+2017-01-26 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include "CpuArch.h"
+#include "Bra.h"
+
+SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+ SizeT i;
+ if (size < 16)
+ return 0;
+ size -= 16;
+ i = 0;
+ do
+ {
+ unsigned m = ((UInt32)0x334B0000 >> (data[i] & 0x1E)) & 3;
+ if (m)
+ {
+ m++;
+ do
+ {
+ Byte *p = data + (i + (size_t)m * 5 - 8);
+ if (((p[3] >> m) & 15) == 5
+ && (((p[-1] | ((UInt32)p[0] << 8)) >> m) & 0x70) == 0)
+ {
+ unsigned raw = GetUi32(p);
+ unsigned v = raw >> m;
+ v = (v & 0xFFFFF) | ((v & (1 << 23)) >> 3);
+
+ v <<= 4;
+ if (encoding)
+ v += ip + (UInt32)i;
+ else
+ v -= ip + (UInt32)i;
+ v >>= 4;
+
+ v &= 0x1FFFFF;
+ v += 0x700000;
+ v &= 0x8FFFFF;
+ raw &= ~((UInt32)0x8FFFFF << m);
+ raw |= (v << m);
+ SetUi32(p, raw);
+ }
+ }
+ while (++m <= 4);
+ }
+ i += 16;
+ }
+ while (i <= size);
+ return i;
+}
diff --git a/contrib/libs/lzmasdk/CpuArch.c b/contrib/libs/lzmasdk/CpuArch.c
index ca84088e38..02e482e088 100644
--- a/contrib/libs/lzmasdk/CpuArch.c
+++ b/contrib/libs/lzmasdk/CpuArch.c
@@ -1,218 +1,218 @@
-/* CpuArch.c -- CPU specific code
-2018-02-18: Igor Pavlov : Public domain */
-
-#include "Precomp.h"
-
-#include "CpuArch.h"
-
-#ifdef MY_CPU_X86_OR_AMD64
-
-#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
-#define USE_ASM
-#endif
-
-#if !defined(USE_ASM) && _MSC_VER >= 1500
-#include <intrin.h>
-#endif
-
-#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
-static UInt32 CheckFlag(UInt32 flag)
-{
- #ifdef _MSC_VER
- __asm pushfd;
- __asm pop EAX;
- __asm mov EDX, EAX;
- __asm xor EAX, flag;
- __asm push EAX;
- __asm popfd;
- __asm pushfd;
- __asm pop EAX;
- __asm xor EAX, EDX;
- __asm push EDX;
- __asm popfd;
- __asm and flag, EAX;
- #else
- __asm__ __volatile__ (
- "pushf\n\t"
- "pop %%EAX\n\t"
- "movl %%EAX,%%EDX\n\t"
- "xorl %0,%%EAX\n\t"
- "push %%EAX\n\t"
- "popf\n\t"
- "pushf\n\t"
- "pop %%EAX\n\t"
- "xorl %%EDX,%%EAX\n\t"
- "push %%EDX\n\t"
- "popf\n\t"
- "andl %%EAX, %0\n\t":
- "=c" (flag) : "c" (flag) :
- "%eax", "%edx");
- #endif
- return flag;
-}
-#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
-#else
-#define CHECK_CPUID_IS_SUPPORTED
-#endif
-
-void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
-{
- #ifdef USE_ASM
-
- #ifdef _MSC_VER
-
- UInt32 a2, b2, c2, d2;
- __asm xor EBX, EBX;
- __asm xor ECX, ECX;
- __asm xor EDX, EDX;
- __asm mov EAX, function;
- __asm cpuid;
- __asm mov a2, EAX;
- __asm mov b2, EBX;
- __asm mov c2, ECX;
- __asm mov d2, EDX;
-
- *a = a2;
- *b = b2;
- *c = c2;
- *d = d2;
-
- #else
-
- __asm__ __volatile__ (
- #if defined(MY_CPU_AMD64) && defined(__PIC__)
- "mov %%rbx, %%rdi;"
- "cpuid;"
- "xchg %%rbx, %%rdi;"
- : "=a" (*a) ,
- "=D" (*b) ,
- #elif defined(MY_CPU_X86) && defined(__PIC__)
- "mov %%ebx, %%edi;"
- "cpuid;"
- "xchgl %%ebx, %%edi;"
- : "=a" (*a) ,
- "=D" (*b) ,
- #else
- "cpuid"
- : "=a" (*a) ,
- "=b" (*b) ,
- #endif
- "=c" (*c) ,
- "=d" (*d)
- : "0" (function)) ;
-
- #endif
-
- #else
-
- int CPUInfo[4];
- __cpuid(CPUInfo, function);
- *a = CPUInfo[0];
- *b = CPUInfo[1];
- *c = CPUInfo[2];
- *d = CPUInfo[3];
-
- #endif
-}
-
-BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p)
-{
- CHECK_CPUID_IS_SUPPORTED
- MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
- MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
- return True;
-}
-
-static const UInt32 kVendors[][3] =
-{
- { 0x756E6547, 0x49656E69, 0x6C65746E},
- { 0x68747541, 0x69746E65, 0x444D4163},
- { 0x746E6543, 0x48727561, 0x736C7561}
-};
-
-int x86cpuid_GetFirm(const Cx86cpuid *p)
-{
- unsigned i;
- for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
- {
- const UInt32 *v = kVendors[i];
- if (v[0] == p->vendor[0] &&
- v[1] == p->vendor[1] &&
- v[2] == p->vendor[2])
- return (int)i;
- }
- return -1;
-}
-
-BoolInt CPU_Is_InOrder()
-{
- Cx86cpuid p;
- int firm;
- UInt32 family, model;
- if (!x86cpuid_CheckAndRead(&p))
- return True;
-
- family = x86cpuid_GetFamily(p.ver);
- model = x86cpuid_GetModel(p.ver);
-
- firm = x86cpuid_GetFirm(&p);
-
- switch (firm)
- {
- case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
- /* In-Order Atom CPU */
- model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
- || model == 0x26 /* 45 nm, Z6xx */
- || model == 0x27 /* 32 nm, Z2460 */
- || model == 0x35 /* 32 nm, Z2760 */
- || model == 0x36 /* 32 nm, N2xxx, D2xxx */
- )));
- case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
- case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
- }
- return True;
-}
-
-#if !defined(MY_CPU_AMD64) && defined(_WIN32)
-#include <windows.h>
-static BoolInt CPU_Sys_Is_SSE_Supported()
-{
- OSVERSIONINFO vi;
- vi.dwOSVersionInfoSize = sizeof(vi);
- if (!GetVersionEx(&vi))
- return False;
- return (vi.dwMajorVersion >= 5);
-}
-#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
-#else
-#define CHECK_SYS_SSE_SUPPORT
-#endif
-
-BoolInt CPU_Is_Aes_Supported()
-{
- Cx86cpuid p;
- CHECK_SYS_SSE_SUPPORT
- if (!x86cpuid_CheckAndRead(&p))
- return False;
- return (p.c >> 25) & 1;
-}
-
-BoolInt CPU_IsSupported_PageGB()
-{
- Cx86cpuid cpuid;
- if (!x86cpuid_CheckAndRead(&cpuid))
- return False;
- {
- UInt32 d[4] = { 0 };
- MyCPUID(0x80000000, &d[0], &d[1], &d[2], &d[3]);
- if (d[0] < 0x80000001)
- return False;
- }
- {
- UInt32 d[4] = { 0 };
- MyCPUID(0x80000001, &d[0], &d[1], &d[2], &d[3]);
- return (d[3] >> 26) & 1;
- }
-}
-
-#endif
+/* CpuArch.c -- CPU specific code
+2018-02-18: Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include "CpuArch.h"
+
+#ifdef MY_CPU_X86_OR_AMD64
+
+#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
+#define USE_ASM
+#endif
+
+#if !defined(USE_ASM) && _MSC_VER >= 1500
+#include <intrin.h>
+#endif
+
+#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
+static UInt32 CheckFlag(UInt32 flag)
+{
+ #ifdef _MSC_VER
+ __asm pushfd;
+ __asm pop EAX;
+ __asm mov EDX, EAX;
+ __asm xor EAX, flag;
+ __asm push EAX;
+ __asm popfd;
+ __asm pushfd;
+ __asm pop EAX;
+ __asm xor EAX, EDX;
+ __asm push EDX;
+ __asm popfd;
+ __asm and flag, EAX;
+ #else
+ __asm__ __volatile__ (
+ "pushf\n\t"
+ "pop %%EAX\n\t"
+ "movl %%EAX,%%EDX\n\t"
+ "xorl %0,%%EAX\n\t"
+ "push %%EAX\n\t"
+ "popf\n\t"
+ "pushf\n\t"
+ "pop %%EAX\n\t"
+ "xorl %%EDX,%%EAX\n\t"
+ "push %%EDX\n\t"
+ "popf\n\t"
+ "andl %%EAX, %0\n\t":
+ "=c" (flag) : "c" (flag) :
+ "%eax", "%edx");
+ #endif
+ return flag;
+}
+#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
+#else
+#define CHECK_CPUID_IS_SUPPORTED
+#endif
+
+void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
+{
+ #ifdef USE_ASM
+
+ #ifdef _MSC_VER
+
+ UInt32 a2, b2, c2, d2;
+ __asm xor EBX, EBX;
+ __asm xor ECX, ECX;
+ __asm xor EDX, EDX;
+ __asm mov EAX, function;
+ __asm cpuid;
+ __asm mov a2, EAX;
+ __asm mov b2, EBX;
+ __asm mov c2, ECX;
+ __asm mov d2, EDX;
+
+ *a = a2;
+ *b = b2;
+ *c = c2;
+ *d = d2;
+
+ #else
+
+ __asm__ __volatile__ (
+ #if defined(MY_CPU_AMD64) && defined(__PIC__)
+ "mov %%rbx, %%rdi;"
+ "cpuid;"
+ "xchg %%rbx, %%rdi;"
+ : "=a" (*a) ,
+ "=D" (*b) ,
+ #elif defined(MY_CPU_X86) && defined(__PIC__)
+ "mov %%ebx, %%edi;"
+ "cpuid;"
+ "xchgl %%ebx, %%edi;"
+ : "=a" (*a) ,
+ "=D" (*b) ,
+ #else
+ "cpuid"
+ : "=a" (*a) ,
+ "=b" (*b) ,
+ #endif
+ "=c" (*c) ,
+ "=d" (*d)
+ : "0" (function)) ;
+
+ #endif
+
+ #else
+
+ int CPUInfo[4];
+ __cpuid(CPUInfo, function);
+ *a = CPUInfo[0];
+ *b = CPUInfo[1];
+ *c = CPUInfo[2];
+ *d = CPUInfo[3];
+
+ #endif
+}
+
+BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p)
+{
+ CHECK_CPUID_IS_SUPPORTED
+ MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
+ MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
+ return True;
+}
+
+static const UInt32 kVendors[][3] =
+{
+ { 0x756E6547, 0x49656E69, 0x6C65746E},
+ { 0x68747541, 0x69746E65, 0x444D4163},
+ { 0x746E6543, 0x48727561, 0x736C7561}
+};
+
+int x86cpuid_GetFirm(const Cx86cpuid *p)
+{
+ unsigned i;
+ for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
+ {
+ const UInt32 *v = kVendors[i];
+ if (v[0] == p->vendor[0] &&
+ v[1] == p->vendor[1] &&
+ v[2] == p->vendor[2])
+ return (int)i;
+ }
+ return -1;
+}
+
+BoolInt CPU_Is_InOrder()
+{
+ Cx86cpuid p;
+ int firm;
+ UInt32 family, model;
+ if (!x86cpuid_CheckAndRead(&p))
+ return True;
+
+ family = x86cpuid_GetFamily(p.ver);
+ model = x86cpuid_GetModel(p.ver);
+
+ firm = x86cpuid_GetFirm(&p);
+
+ switch (firm)
+ {
+ case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
+ /* In-Order Atom CPU */
+ model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
+ || model == 0x26 /* 45 nm, Z6xx */
+ || model == 0x27 /* 32 nm, Z2460 */
+ || model == 0x35 /* 32 nm, Z2760 */
+ || model == 0x36 /* 32 nm, N2xxx, D2xxx */
+ )));
+ case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
+ case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
+ }
+ return True;
+}
+
+#if !defined(MY_CPU_AMD64) && defined(_WIN32)
+#include <windows.h>
+static BoolInt CPU_Sys_Is_SSE_Supported()
+{
+ OSVERSIONINFO vi;
+ vi.dwOSVersionInfoSize = sizeof(vi);
+ if (!GetVersionEx(&vi))
+ return False;
+ return (vi.dwMajorVersion >= 5);
+}
+#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
+#else
+#define CHECK_SYS_SSE_SUPPORT
+#endif
+
+BoolInt CPU_Is_Aes_Supported()
+{
+ Cx86cpuid p;
+ CHECK_SYS_SSE_SUPPORT
+ if (!x86cpuid_CheckAndRead(&p))
+ return False;
+ return (p.c >> 25) & 1;
+}
+
+BoolInt CPU_IsSupported_PageGB()
+{
+ Cx86cpuid cpuid;
+ if (!x86cpuid_CheckAndRead(&cpuid))
+ return False;
+ {
+ UInt32 d[4] = { 0 };
+ MyCPUID(0x80000000, &d[0], &d[1], &d[2], &d[3]);
+ if (d[0] < 0x80000001)
+ return False;
+ }
+ {
+ UInt32 d[4] = { 0 };
+ MyCPUID(0x80000001, &d[0], &d[1], &d[2], &d[3]);
+ return (d[3] >> 26) & 1;
+ }
+}
+
+#endif
diff --git a/contrib/libs/lzmasdk/CpuArch.h b/contrib/libs/lzmasdk/CpuArch.h
index 31ec712268..bd42938802 100644
--- a/contrib/libs/lzmasdk/CpuArch.h
+++ b/contrib/libs/lzmasdk/CpuArch.h
@@ -1,336 +1,336 @@
-/* CpuArch.h -- CPU specific code
-2018-02-18 : Igor Pavlov : Public domain */
-
-#ifndef __CPU_ARCH_H
-#define __CPU_ARCH_H
-
-#include "7zTypes.h"
-
-EXTERN_C_BEGIN
-
-/*
-MY_CPU_LE means that CPU is LITTLE ENDIAN.
-MY_CPU_BE means that CPU is BIG ENDIAN.
-If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
-
-MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
-*/
-
-#if defined(_M_X64) \
- || defined(_M_AMD64) \
- || defined(__x86_64__) \
- || defined(__AMD64__) \
- || defined(__amd64__)
- #define MY_CPU_AMD64
- #ifdef __ILP32__
- #define MY_CPU_NAME "x32"
- #else
- #define MY_CPU_NAME "x64"
- #endif
- #define MY_CPU_64BIT
-#endif
-
-
-#if defined(_M_IX86) \
- || defined(__i386__)
- #define MY_CPU_X86
- #define MY_CPU_NAME "x86"
- #define MY_CPU_32BIT
-#endif
-
-
-#if defined(_M_ARM64) \
- || defined(__AARCH64EL__) \
- || defined(__AARCH64EB__) \
- || defined(__aarch64__)
- #define MY_CPU_ARM64
- #define MY_CPU_NAME "arm64"
- #define MY_CPU_64BIT
-#endif
-
-
-#if defined(_M_ARM) \
- || defined(_M_ARM_NT) \
- || defined(_M_ARMT) \
- || defined(__arm__) \
- || defined(__thumb__) \
- || defined(__ARMEL__) \
- || defined(__ARMEB__) \
- || defined(__THUMBEL__) \
- || defined(__THUMBEB__)
- #define MY_CPU_ARM
- #define MY_CPU_NAME "arm"
- #define MY_CPU_32BIT
-#endif
-
-
-#if defined(_M_IA64) \
- || defined(__ia64__)
- #define MY_CPU_IA64
- #define MY_CPU_NAME "ia64"
- #define MY_CPU_64BIT
-#endif
-
-
-#if defined(__mips64) \
- || defined(__mips64__) \
- || (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))
- #define MY_CPU_NAME "mips64"
- #define MY_CPU_64BIT
-#elif defined(__mips__)
- #define MY_CPU_NAME "mips"
- /* #define MY_CPU_32BIT */
-#endif
-
-
-#if defined(__ppc64__) \
- || defined(__powerpc64__)
- #ifdef __ILP32__
- #define MY_CPU_NAME "ppc64-32"
- #else
- #define MY_CPU_NAME "ppc64"
- #endif
- #define MY_CPU_64BIT
-#elif defined(__ppc__) \
- || defined(__powerpc__)
- #define MY_CPU_NAME "ppc"
- #define MY_CPU_32BIT
-#endif
-
-
-#if defined(__sparc64__)
- #define MY_CPU_NAME "sparc64"
- #define MY_CPU_64BIT
-#elif defined(__sparc__)
- #define MY_CPU_NAME "sparc"
- /* #define MY_CPU_32BIT */
-#endif
-
-
-#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
-#define MY_CPU_X86_OR_AMD64
-#endif
-
-
-#ifdef _WIN32
-
- #ifdef MY_CPU_ARM
- #define MY_CPU_ARM_LE
- #endif
-
- #ifdef MY_CPU_ARM64
- #define MY_CPU_ARM64_LE
- #endif
-
- #ifdef _M_IA64
- #define MY_CPU_IA64_LE
- #endif
-
-#endif
-
-
-#if defined(MY_CPU_X86_OR_AMD64) \
- || defined(MY_CPU_ARM_LE) \
- || defined(MY_CPU_ARM64_LE) \
- || defined(MY_CPU_IA64_LE) \
- || defined(__LITTLE_ENDIAN__) \
- || defined(__ARMEL__) \
- || defined(__THUMBEL__) \
- || defined(__AARCH64EL__) \
- || defined(__MIPSEL__) \
- || defined(__MIPSEL) \
- || defined(_MIPSEL) \
- || defined(__BFIN__) \
- || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
- #define MY_CPU_LE
-#endif
-
-#if defined(__BIG_ENDIAN__) \
- || defined(__ARMEB__) \
- || defined(__THUMBEB__) \
- || defined(__AARCH64EB__) \
- || defined(__MIPSEB__) \
- || defined(__MIPSEB) \
- || defined(_MIPSEB) \
- || defined(__m68k__) \
- || defined(__s390__) \
- || defined(__s390x__) \
- || defined(__zarch__) \
- || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
- #define MY_CPU_BE
-#endif
-
-
-#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
- #error Stop_Compiling_Bad_Endian
-#endif
-
-
-#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
- #error Stop_Compiling_Bad_32_64_BIT
-#endif
-
-
-#ifndef MY_CPU_NAME
- #ifdef MY_CPU_LE
- #define MY_CPU_NAME "LE"
- #elif defined(MY_CPU_BE)
- #define MY_CPU_NAME "BE"
- #else
- /*
- #define MY_CPU_NAME ""
- */
- #endif
-#endif
-
-
-
-
-
-#ifdef MY_CPU_LE
- #if defined(MY_CPU_X86_OR_AMD64) \
- || defined(MY_CPU_ARM64) \
- || defined(__ARM_FEATURE_UNALIGNED)
- #define MY_CPU_LE_UNALIGN
- #endif
-#endif
-
-
-#ifdef MY_CPU_LE_UNALIGN
-
-#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
-#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
-#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
-
-#define SetUi16(p, v) { *(UInt16 *)(p) = (v); }
-#define SetUi32(p, v) { *(UInt32 *)(p) = (v); }
-#define SetUi64(p, v) { *(UInt64 *)(p) = (v); }
-
-#else
-
-#define GetUi16(p) ( (UInt16) ( \
- ((const Byte *)(p))[0] | \
- ((UInt16)((const Byte *)(p))[1] << 8) ))
-
-#define GetUi32(p) ( \
- ((const Byte *)(p))[0] | \
- ((UInt32)((const Byte *)(p))[1] << 8) | \
- ((UInt32)((const Byte *)(p))[2] << 16) | \
- ((UInt32)((const Byte *)(p))[3] << 24))
-
-#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
-
-#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
- _ppp_[0] = (Byte)_vvv_; \
- _ppp_[1] = (Byte)(_vvv_ >> 8); }
-
-#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
- _ppp_[0] = (Byte)_vvv_; \
- _ppp_[1] = (Byte)(_vvv_ >> 8); \
- _ppp_[2] = (Byte)(_vvv_ >> 16); \
- _ppp_[3] = (Byte)(_vvv_ >> 24); }
-
-#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
- SetUi32(_ppp2_ , (UInt32)_vvv2_); \
- SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
-
-#endif
-
-#ifdef __has_builtin
- #define MY__has_builtin(x) __has_builtin(x)
-#else
- #define MY__has_builtin(x) 0
-#endif
-
-#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
-
-/* Note: we use bswap instruction, that is unsupported in 386 cpu */
-
-#include <stdlib.h>
-
-#pragma intrinsic(_byteswap_ushort)
-#pragma intrinsic(_byteswap_ulong)
-#pragma intrinsic(_byteswap_uint64)
-
-/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */
-#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
-#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
-
-#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
-
-#elif defined(MY_CPU_LE_UNALIGN) && ( \
- (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
- || (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) )
-
-/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const Byte *)(p)) */
-#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
-#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
-
-#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v)
-
-#else
-
-#define GetBe32(p) ( \
- ((UInt32)((const Byte *)(p))[0] << 24) | \
- ((UInt32)((const Byte *)(p))[1] << 16) | \
- ((UInt32)((const Byte *)(p))[2] << 8) | \
- ((const Byte *)(p))[3] )
-
-#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
-
-#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
- _ppp_[0] = (Byte)(_vvv_ >> 24); \
- _ppp_[1] = (Byte)(_vvv_ >> 16); \
- _ppp_[2] = (Byte)(_vvv_ >> 8); \
- _ppp_[3] = (Byte)_vvv_; }
-
-#endif
-
-
-#ifndef GetBe16
-
-#define GetBe16(p) ( (UInt16) ( \
- ((UInt16)((const Byte *)(p))[0] << 8) | \
- ((const Byte *)(p))[1] ))
-
-#endif
-
-
-
-#ifdef MY_CPU_X86_OR_AMD64
-
-typedef struct
-{
- UInt32 maxFunc;
- UInt32 vendor[3];
- UInt32 ver;
- UInt32 b;
- UInt32 c;
- UInt32 d;
-} Cx86cpuid;
-
-enum
-{
- CPU_FIRM_INTEL,
- CPU_FIRM_AMD,
- CPU_FIRM_VIA
-};
-
-void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
-
-BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p);
-int x86cpuid_GetFirm(const Cx86cpuid *p);
-
-#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
-#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))
-#define x86cpuid_GetStepping(ver) (ver & 0xF)
-
-BoolInt CPU_Is_InOrder();
-BoolInt CPU_Is_Aes_Supported();
-BoolInt CPU_IsSupported_PageGB();
-
-#endif
-
-EXTERN_C_END
-
-#endif
+/* CpuArch.h -- CPU specific code
+2018-02-18 : Igor Pavlov : Public domain */
+
+#ifndef __CPU_ARCH_H
+#define __CPU_ARCH_H
+
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
+/*
+MY_CPU_LE means that CPU is LITTLE ENDIAN.
+MY_CPU_BE means that CPU is BIG ENDIAN.
+If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
+
+MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
+*/
+
+#if defined(_M_X64) \
+ || defined(_M_AMD64) \
+ || defined(__x86_64__) \
+ || defined(__AMD64__) \
+ || defined(__amd64__)
+ #define MY_CPU_AMD64
+ #ifdef __ILP32__
+ #define MY_CPU_NAME "x32"
+ #else
+ #define MY_CPU_NAME "x64"
+ #endif
+ #define MY_CPU_64BIT
+#endif
+
+
+#if defined(_M_IX86) \
+ || defined(__i386__)
+ #define MY_CPU_X86
+ #define MY_CPU_NAME "x86"
+ #define MY_CPU_32BIT
+#endif
+
+
+#if defined(_M_ARM64) \
+ || defined(__AARCH64EL__) \
+ || defined(__AARCH64EB__) \
+ || defined(__aarch64__)
+ #define MY_CPU_ARM64
+ #define MY_CPU_NAME "arm64"
+ #define MY_CPU_64BIT
+#endif
+
+
+#if defined(_M_ARM) \
+ || defined(_M_ARM_NT) \
+ || defined(_M_ARMT) \
+ || defined(__arm__) \
+ || defined(__thumb__) \
+ || defined(__ARMEL__) \
+ || defined(__ARMEB__) \
+ || defined(__THUMBEL__) \
+ || defined(__THUMBEB__)
+ #define MY_CPU_ARM
+ #define MY_CPU_NAME "arm"
+ #define MY_CPU_32BIT
+#endif
+
+
+#if defined(_M_IA64) \
+ || defined(__ia64__)
+ #define MY_CPU_IA64
+ #define MY_CPU_NAME "ia64"
+ #define MY_CPU_64BIT
+#endif
+
+
+#if defined(__mips64) \
+ || defined(__mips64__) \
+ || (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))
+ #define MY_CPU_NAME "mips64"
+ #define MY_CPU_64BIT
+#elif defined(__mips__)
+ #define MY_CPU_NAME "mips"
+ /* #define MY_CPU_32BIT */
+#endif
+
+
+#if defined(__ppc64__) \
+ || defined(__powerpc64__)
+ #ifdef __ILP32__
+ #define MY_CPU_NAME "ppc64-32"
+ #else
+ #define MY_CPU_NAME "ppc64"
+ #endif
+ #define MY_CPU_64BIT
+#elif defined(__ppc__) \
+ || defined(__powerpc__)
+ #define MY_CPU_NAME "ppc"
+ #define MY_CPU_32BIT
+#endif
+
+
+#if defined(__sparc64__)
+ #define MY_CPU_NAME "sparc64"
+ #define MY_CPU_64BIT
+#elif defined(__sparc__)
+ #define MY_CPU_NAME "sparc"
+ /* #define MY_CPU_32BIT */
+#endif
+
+
+#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
+#define MY_CPU_X86_OR_AMD64
+#endif
+
+
+#ifdef _WIN32
+
+ #ifdef MY_CPU_ARM
+ #define MY_CPU_ARM_LE
+ #endif
+
+ #ifdef MY_CPU_ARM64
+ #define MY_CPU_ARM64_LE
+ #endif
+
+ #ifdef _M_IA64
+ #define MY_CPU_IA64_LE
+ #endif
+
+#endif
+
+
+#if defined(MY_CPU_X86_OR_AMD64) \
+ || defined(MY_CPU_ARM_LE) \
+ || defined(MY_CPU_ARM64_LE) \
+ || defined(MY_CPU_IA64_LE) \
+ || defined(__LITTLE_ENDIAN__) \
+ || defined(__ARMEL__) \
+ || defined(__THUMBEL__) \
+ || defined(__AARCH64EL__) \
+ || defined(__MIPSEL__) \
+ || defined(__MIPSEL) \
+ || defined(_MIPSEL) \
+ || defined(__BFIN__) \
+ || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
+ #define MY_CPU_LE
+#endif
+
+#if defined(__BIG_ENDIAN__) \
+ || defined(__ARMEB__) \
+ || defined(__THUMBEB__) \
+ || defined(__AARCH64EB__) \
+ || defined(__MIPSEB__) \
+ || defined(__MIPSEB) \
+ || defined(_MIPSEB) \
+ || defined(__m68k__) \
+ || defined(__s390__) \
+ || defined(__s390x__) \
+ || defined(__zarch__) \
+ || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
+ #define MY_CPU_BE
+#endif
+
+
+#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
+ #error Stop_Compiling_Bad_Endian
+#endif
+
+
+#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
+ #error Stop_Compiling_Bad_32_64_BIT
+#endif
+
+
+#ifndef MY_CPU_NAME
+ #ifdef MY_CPU_LE
+ #define MY_CPU_NAME "LE"
+ #elif defined(MY_CPU_BE)
+ #define MY_CPU_NAME "BE"
+ #else
+ /*
+ #define MY_CPU_NAME ""
+ */
+ #endif
+#endif
+
+
+
+
+
+#ifdef MY_CPU_LE
+ #if defined(MY_CPU_X86_OR_AMD64) \
+ || defined(MY_CPU_ARM64) \
+ || defined(__ARM_FEATURE_UNALIGNED)
+ #define MY_CPU_LE_UNALIGN
+ #endif
+#endif
+
+
+#ifdef MY_CPU_LE_UNALIGN
+
+#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
+#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
+#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
+
+#define SetUi16(p, v) { *(UInt16 *)(p) = (v); }
+#define SetUi32(p, v) { *(UInt32 *)(p) = (v); }
+#define SetUi64(p, v) { *(UInt64 *)(p) = (v); }
+
+#else
+
+#define GetUi16(p) ( (UInt16) ( \
+ ((const Byte *)(p))[0] | \
+ ((UInt16)((const Byte *)(p))[1] << 8) ))
+
+#define GetUi32(p) ( \
+ ((const Byte *)(p))[0] | \
+ ((UInt32)((const Byte *)(p))[1] << 8) | \
+ ((UInt32)((const Byte *)(p))[2] << 16) | \
+ ((UInt32)((const Byte *)(p))[3] << 24))
+
+#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
+
+#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
+ _ppp_[0] = (Byte)_vvv_; \
+ _ppp_[1] = (Byte)(_vvv_ >> 8); }
+
+#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
+ _ppp_[0] = (Byte)_vvv_; \
+ _ppp_[1] = (Byte)(_vvv_ >> 8); \
+ _ppp_[2] = (Byte)(_vvv_ >> 16); \
+ _ppp_[3] = (Byte)(_vvv_ >> 24); }
+
+#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
+ SetUi32(_ppp2_ , (UInt32)_vvv2_); \
+ SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
+
+#endif
+
+#ifdef __has_builtin
+ #define MY__has_builtin(x) __has_builtin(x)
+#else
+ #define MY__has_builtin(x) 0
+#endif
+
+#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
+
+/* Note: we use bswap instruction, that is unsupported in 386 cpu */
+
+#include <stdlib.h>
+
+#pragma intrinsic(_byteswap_ushort)
+#pragma intrinsic(_byteswap_ulong)
+#pragma intrinsic(_byteswap_uint64)
+
+/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */
+#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
+#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
+
+#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
+
+#elif defined(MY_CPU_LE_UNALIGN) && ( \
+ (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
+ || (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) )
+
+/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const Byte *)(p)) */
+#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
+#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
+
+#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v)
+
+#else
+
+#define GetBe32(p) ( \
+ ((UInt32)((const Byte *)(p))[0] << 24) | \
+ ((UInt32)((const Byte *)(p))[1] << 16) | \
+ ((UInt32)((const Byte *)(p))[2] << 8) | \
+ ((const Byte *)(p))[3] )
+
+#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
+
+#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
+ _ppp_[0] = (Byte)(_vvv_ >> 24); \
+ _ppp_[1] = (Byte)(_vvv_ >> 16); \
+ _ppp_[2] = (Byte)(_vvv_ >> 8); \
+ _ppp_[3] = (Byte)_vvv_; }
+
+#endif
+
+
+#ifndef GetBe16
+
+#define GetBe16(p) ( (UInt16) ( \
+ ((UInt16)((const Byte *)(p))[0] << 8) | \
+ ((const Byte *)(p))[1] ))
+
+#endif
+
+
+
+#ifdef MY_CPU_X86_OR_AMD64
+
+typedef struct
+{
+ UInt32 maxFunc;
+ UInt32 vendor[3];
+ UInt32 ver;
+ UInt32 b;
+ UInt32 c;
+ UInt32 d;
+} Cx86cpuid;
+
+enum
+{
+ CPU_FIRM_INTEL,
+ CPU_FIRM_AMD,
+ CPU_FIRM_VIA
+};
+
+void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
+
+BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p);
+int x86cpuid_GetFirm(const Cx86cpuid *p);
+
+#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
+#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))
+#define x86cpuid_GetStepping(ver) (ver & 0xF)
+
+BoolInt CPU_Is_InOrder();
+BoolInt CPU_Is_Aes_Supported();
+BoolInt CPU_IsSupported_PageGB();
+
+#endif
+
+EXTERN_C_END
+
+#endif
diff --git a/contrib/libs/lzmasdk/Lzma2Dec.c b/contrib/libs/lzmasdk/Lzma2Dec.c
index 9d9517eb1e..4e138a4aef 100644
--- a/contrib/libs/lzmasdk/Lzma2Dec.c
+++ b/contrib/libs/lzmasdk/Lzma2Dec.c
@@ -1,488 +1,488 @@
-/* Lzma2Dec.c -- LZMA2 Decoder
-2019-02-02 : Igor Pavlov : Public domain */
-
-/* #define SHOW_DEBUG_INFO */
-
-#include "Precomp.h"
-
-#ifdef SHOW_DEBUG_INFO
-#include <stdio.h>
-#endif
-
-#include <string.h>
-
-#include "Lzma2Dec.h"
-
-/*
-00000000 - End of data
-00000001 U U - Uncompressed, reset dic, need reset state and set new prop
-00000010 U U - Uncompressed, no reset
-100uuuuu U U P P - LZMA, no reset
-101uuuuu U U P P - LZMA, reset state
-110uuuuu U U P P S - LZMA, reset state + set new prop
-111uuuuu U U P P S - LZMA, reset state + set new prop, reset dic
-
- u, U - Unpack Size
- P - Pack Size
- S - Props
-*/
-
-#define LZMA2_CONTROL_COPY_RESET_DIC 1
-
-#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & (1 << 7)) == 0)
-
-#define LZMA2_LCLP_MAX 4
-#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
-
-#ifdef SHOW_DEBUG_INFO
-#define PRF(x) x
-#else
-#define PRF(x)
-#endif
-
-typedef enum
-{
- LZMA2_STATE_CONTROL,
- LZMA2_STATE_UNPACK0,
- LZMA2_STATE_UNPACK1,
- LZMA2_STATE_PACK0,
- LZMA2_STATE_PACK1,
- LZMA2_STATE_PROP,
- LZMA2_STATE_DATA,
- LZMA2_STATE_DATA_CONT,
- LZMA2_STATE_FINISHED,
- LZMA2_STATE_ERROR
-} ELzma2State;
-
-static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
-{
- UInt32 dicSize;
- if (prop > 40)
- return SZ_ERROR_UNSUPPORTED;
- dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
- props[0] = (Byte)LZMA2_LCLP_MAX;
- props[1] = (Byte)(dicSize);
- props[2] = (Byte)(dicSize >> 8);
- props[3] = (Byte)(dicSize >> 16);
- props[4] = (Byte)(dicSize >> 24);
- return SZ_OK;
-}
-
-SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
-{
- Byte props[LZMA_PROPS_SIZE];
- RINOK(Lzma2Dec_GetOldProps(prop, props));
- return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
-}
-
-SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
-{
- Byte props[LZMA_PROPS_SIZE];
- RINOK(Lzma2Dec_GetOldProps(prop, props));
- return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
-}
-
-void Lzma2Dec_Init(CLzma2Dec *p)
-{
- p->state = LZMA2_STATE_CONTROL;
- p->needInitLevel = 0xE0;
- p->isExtraMode = False;
- p->unpackSize = 0;
-
- // p->decoder.dicPos = 0; // we can use it instead of full init
- LzmaDec_Init(&p->decoder);
-}
-
-static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
-{
- switch (p->state)
- {
- case LZMA2_STATE_CONTROL:
- p->isExtraMode = False;
- p->control = b;
- PRF(printf("\n %8X", (unsigned)p->decoder.dicPos));
- PRF(printf(" %02X", (unsigned)b));
- if (b == 0)
- return LZMA2_STATE_FINISHED;
- if (LZMA2_IS_UNCOMPRESSED_STATE(p))
- {
- if (b == LZMA2_CONTROL_COPY_RESET_DIC)
- p->needInitLevel = 0xC0;
- else if (b > 2 || p->needInitLevel == 0xE0)
- return LZMA2_STATE_ERROR;
- }
- else
- {
- if (b < p->needInitLevel)
- return LZMA2_STATE_ERROR;
- p->needInitLevel = 0;
- p->unpackSize = (UInt32)(b & 0x1F) << 16;
- }
- return LZMA2_STATE_UNPACK0;
-
- case LZMA2_STATE_UNPACK0:
- p->unpackSize |= (UInt32)b << 8;
- return LZMA2_STATE_UNPACK1;
-
- case LZMA2_STATE_UNPACK1:
- p->unpackSize |= (UInt32)b;
- p->unpackSize++;
- PRF(printf(" %7u", (unsigned)p->unpackSize));
- return LZMA2_IS_UNCOMPRESSED_STATE(p) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
-
- case LZMA2_STATE_PACK0:
- p->packSize = (UInt32)b << 8;
- return LZMA2_STATE_PACK1;
-
- case LZMA2_STATE_PACK1:
- p->packSize |= (UInt32)b;
- p->packSize++;
- // if (p->packSize < 5) return LZMA2_STATE_ERROR;
- PRF(printf(" %5u", (unsigned)p->packSize));
- return (p->control & 0x40) ? LZMA2_STATE_PROP : LZMA2_STATE_DATA;
-
- case LZMA2_STATE_PROP:
- {
- unsigned lc, lp;
- if (b >= (9 * 5 * 5))
- return LZMA2_STATE_ERROR;
- lc = b % 9;
- b /= 9;
- p->decoder.prop.pb = (Byte)(b / 5);
- lp = b % 5;
- if (lc + lp > LZMA2_LCLP_MAX)
- return LZMA2_STATE_ERROR;
- p->decoder.prop.lc = (Byte)lc;
- p->decoder.prop.lp = (Byte)lp;
- return LZMA2_STATE_DATA;
- }
- }
- return LZMA2_STATE_ERROR;
-}
-
-static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
-{
- memcpy(p->dic + p->dicPos, src, size);
- p->dicPos += size;
- if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
- p->checkDicSize = p->prop.dicSize;
- p->processedPos += (UInt32)size;
-}
-
-void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState);
-
-
-SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
-{
- SizeT inSize = *srcLen;
- *srcLen = 0;
- *status = LZMA_STATUS_NOT_SPECIFIED;
-
- while (p->state != LZMA2_STATE_ERROR)
- {
- SizeT dicPos;
-
- if (p->state == LZMA2_STATE_FINISHED)
- {
- *status = LZMA_STATUS_FINISHED_WITH_MARK;
- return SZ_OK;
- }
-
- dicPos = p->decoder.dicPos;
-
- if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
- {
- *status = LZMA_STATUS_NOT_FINISHED;
- return SZ_OK;
- }
-
- if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
- {
- if (*srcLen == inSize)
- {
- *status = LZMA_STATUS_NEEDS_MORE_INPUT;
- return SZ_OK;
- }
- (*srcLen)++;
- p->state = Lzma2Dec_UpdateState(p, *src++);
- if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
- break;
- continue;
- }
-
- {
- SizeT inCur = inSize - *srcLen;
- SizeT outCur = dicLimit - dicPos;
- ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
-
- if (outCur >= p->unpackSize)
- {
- outCur = (SizeT)p->unpackSize;
- curFinishMode = LZMA_FINISH_END;
- }
-
- if (LZMA2_IS_UNCOMPRESSED_STATE(p))
- {
- if (inCur == 0)
- {
- *status = LZMA_STATUS_NEEDS_MORE_INPUT;
- return SZ_OK;
- }
-
- if (p->state == LZMA2_STATE_DATA)
- {
- BoolInt initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
- LzmaDec_InitDicAndState(&p->decoder, initDic, False);
- }
-
- if (inCur > outCur)
- inCur = outCur;
- if (inCur == 0)
- break;
-
- LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur);
-
- src += inCur;
- *srcLen += inCur;
- p->unpackSize -= (UInt32)inCur;
- p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
- }
- else
- {
- SRes res;
-
- if (p->state == LZMA2_STATE_DATA)
- {
- BoolInt initDic = (p->control >= 0xE0);
- BoolInt initState = (p->control >= 0xA0);
- LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
- p->state = LZMA2_STATE_DATA_CONT;
- }
-
- if (inCur > p->packSize)
- inCur = (SizeT)p->packSize;
-
- res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status);
-
- src += inCur;
- *srcLen += inCur;
- p->packSize -= (UInt32)inCur;
- outCur = p->decoder.dicPos - dicPos;
- p->unpackSize -= (UInt32)outCur;
-
- if (res != 0)
- break;
-
- if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
- {
- if (p->packSize == 0)
- break;
- return SZ_OK;
- }
-
- if (inCur == 0 && outCur == 0)
- {
- if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
- || p->unpackSize != 0
- || p->packSize != 0)
- break;
- p->state = LZMA2_STATE_CONTROL;
- }
-
- *status = LZMA_STATUS_NOT_SPECIFIED;
- }
- }
- }
-
- *status = LZMA_STATUS_NOT_SPECIFIED;
- p->state = LZMA2_STATE_ERROR;
- return SZ_ERROR_DATA;
-}
-
-
-
-
-ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p,
- SizeT outSize,
- const Byte *src, SizeT *srcLen,
- int checkFinishBlock)
-{
- SizeT inSize = *srcLen;
- *srcLen = 0;
-
- while (p->state != LZMA2_STATE_ERROR)
- {
- if (p->state == LZMA2_STATE_FINISHED)
- return (ELzma2ParseStatus)LZMA_STATUS_FINISHED_WITH_MARK;
-
- if (outSize == 0 && !checkFinishBlock)
- return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
-
- if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
- {
- if (*srcLen == inSize)
- return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
- (*srcLen)++;
-
- p->state = Lzma2Dec_UpdateState(p, *src++);
-
- if (p->state == LZMA2_STATE_UNPACK0)
- {
- // if (p->decoder.dicPos != 0)
- if (p->control == LZMA2_CONTROL_COPY_RESET_DIC || p->control >= 0xE0)
- return LZMA2_PARSE_STATUS_NEW_BLOCK;
- // if (outSize == 0) return LZMA_STATUS_NOT_FINISHED;
- }
-
- // The following code can be commented.
- // It's not big problem, if we read additional input bytes.
- // It will be stopped later in LZMA2_STATE_DATA / LZMA2_STATE_DATA_CONT state.
-
- if (outSize == 0 && p->state != LZMA2_STATE_FINISHED)
- {
- // checkFinishBlock is true. So we expect that block must be finished,
- // We can return LZMA_STATUS_NOT_SPECIFIED or LZMA_STATUS_NOT_FINISHED here
- // break;
- return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
- }
-
- if (p->state == LZMA2_STATE_DATA)
- return LZMA2_PARSE_STATUS_NEW_CHUNK;
-
- continue;
- }
-
- if (outSize == 0)
- return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
-
- {
- SizeT inCur = inSize - *srcLen;
-
- if (LZMA2_IS_UNCOMPRESSED_STATE(p))
- {
- if (inCur == 0)
- return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
- if (inCur > p->unpackSize)
- inCur = p->unpackSize;
- if (inCur > outSize)
- inCur = outSize;
- p->decoder.dicPos += inCur;
- src += inCur;
- *srcLen += inCur;
- outSize -= inCur;
- p->unpackSize -= (UInt32)inCur;
- p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
- }
- else
- {
- p->isExtraMode = True;
-
- if (inCur == 0)
- {
- if (p->packSize != 0)
- return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
- }
- else if (p->state == LZMA2_STATE_DATA)
- {
- p->state = LZMA2_STATE_DATA_CONT;
- if (*src != 0)
- {
- // first byte of lzma chunk must be Zero
- *srcLen += 1;
- p->packSize--;
- break;
- }
- }
-
- if (inCur > p->packSize)
- inCur = (SizeT)p->packSize;
-
- src += inCur;
- *srcLen += inCur;
- p->packSize -= (UInt32)inCur;
-
- if (p->packSize == 0)
- {
- SizeT rem = outSize;
- if (rem > p->unpackSize)
- rem = p->unpackSize;
- p->decoder.dicPos += rem;
- p->unpackSize -= (UInt32)rem;
- outSize -= rem;
- if (p->unpackSize == 0)
- p->state = LZMA2_STATE_CONTROL;
- }
- }
- }
- }
-
- p->state = LZMA2_STATE_ERROR;
- return (ELzma2ParseStatus)LZMA_STATUS_NOT_SPECIFIED;
-}
-
-
-
-
-SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
-{
- SizeT outSize = *destLen, inSize = *srcLen;
- *srcLen = *destLen = 0;
-
- for (;;)
- {
- SizeT inCur = inSize, outCur, dicPos;
- ELzmaFinishMode curFinishMode;
- SRes res;
-
- if (p->decoder.dicPos == p->decoder.dicBufSize)
- p->decoder.dicPos = 0;
- dicPos = p->decoder.dicPos;
- curFinishMode = LZMA_FINISH_ANY;
- outCur = p->decoder.dicBufSize - dicPos;
-
- if (outCur >= outSize)
- {
- outCur = outSize;
- curFinishMode = finishMode;
- }
-
- res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status);
-
- src += inCur;
- inSize -= inCur;
- *srcLen += inCur;
- outCur = p->decoder.dicPos - dicPos;
- memcpy(dest, p->decoder.dic + dicPos, outCur);
- dest += outCur;
- outSize -= outCur;
- *destLen += outCur;
- if (res != 0)
- return res;
- if (outCur == 0 || outSize == 0)
- return SZ_OK;
- }
-}
-
-
-SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
- Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc)
-{
- CLzma2Dec p;
- SRes res;
- SizeT outSize = *destLen, inSize = *srcLen;
- *destLen = *srcLen = 0;
- *status = LZMA_STATUS_NOT_SPECIFIED;
- Lzma2Dec_Construct(&p);
- RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc));
- p.decoder.dic = dest;
- p.decoder.dicBufSize = outSize;
- Lzma2Dec_Init(&p);
- *srcLen = inSize;
- res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
- *destLen = p.decoder.dicPos;
- if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
- res = SZ_ERROR_INPUT_EOF;
- Lzma2Dec_FreeProbs(&p, alloc);
- return res;
-}
+/* Lzma2Dec.c -- LZMA2 Decoder
+2019-02-02 : Igor Pavlov : Public domain */
+
+/* #define SHOW_DEBUG_INFO */
+
+#include "Precomp.h"
+
+#ifdef SHOW_DEBUG_INFO
+#include <stdio.h>
+#endif
+
+#include <string.h>
+
+#include "Lzma2Dec.h"
+
+/*
+00000000 - End of data
+00000001 U U - Uncompressed, reset dic, need reset state and set new prop
+00000010 U U - Uncompressed, no reset
+100uuuuu U U P P - LZMA, no reset
+101uuuuu U U P P - LZMA, reset state
+110uuuuu U U P P S - LZMA, reset state + set new prop
+111uuuuu U U P P S - LZMA, reset state + set new prop, reset dic
+
+ u, U - Unpack Size
+ P - Pack Size
+ S - Props
+*/
+
+#define LZMA2_CONTROL_COPY_RESET_DIC 1
+
+#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & (1 << 7)) == 0)
+
+#define LZMA2_LCLP_MAX 4
+#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
+
+#ifdef SHOW_DEBUG_INFO
+#define PRF(x) x
+#else
+#define PRF(x)
+#endif
+
+typedef enum
+{
+ LZMA2_STATE_CONTROL,
+ LZMA2_STATE_UNPACK0,
+ LZMA2_STATE_UNPACK1,
+ LZMA2_STATE_PACK0,
+ LZMA2_STATE_PACK1,
+ LZMA2_STATE_PROP,
+ LZMA2_STATE_DATA,
+ LZMA2_STATE_DATA_CONT,
+ LZMA2_STATE_FINISHED,
+ LZMA2_STATE_ERROR
+} ELzma2State;
+
+static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
+{
+ UInt32 dicSize;
+ if (prop > 40)
+ return SZ_ERROR_UNSUPPORTED;
+ dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
+ props[0] = (Byte)LZMA2_LCLP_MAX;
+ props[1] = (Byte)(dicSize);
+ props[2] = (Byte)(dicSize >> 8);
+ props[3] = (Byte)(dicSize >> 16);
+ props[4] = (Byte)(dicSize >> 24);
+ return SZ_OK;
+}
+
+SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
+{
+ Byte props[LZMA_PROPS_SIZE];
+ RINOK(Lzma2Dec_GetOldProps(prop, props));
+ return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
+}
+
+SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
+{
+ Byte props[LZMA_PROPS_SIZE];
+ RINOK(Lzma2Dec_GetOldProps(prop, props));
+ return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
+}
+
+void Lzma2Dec_Init(CLzma2Dec *p)
+{
+ p->state = LZMA2_STATE_CONTROL;
+ p->needInitLevel = 0xE0;
+ p->isExtraMode = False;
+ p->unpackSize = 0;
+
+ // p->decoder.dicPos = 0; // we can use it instead of full init
+ LzmaDec_Init(&p->decoder);
+}
+
+static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
+{
+ switch (p->state)
+ {
+ case LZMA2_STATE_CONTROL:
+ p->isExtraMode = False;
+ p->control = b;
+ PRF(printf("\n %8X", (unsigned)p->decoder.dicPos));
+ PRF(printf(" %02X", (unsigned)b));
+ if (b == 0)
+ return LZMA2_STATE_FINISHED;
+ if (LZMA2_IS_UNCOMPRESSED_STATE(p))
+ {
+ if (b == LZMA2_CONTROL_COPY_RESET_DIC)
+ p->needInitLevel = 0xC0;
+ else if (b > 2 || p->needInitLevel == 0xE0)
+ return LZMA2_STATE_ERROR;
+ }
+ else
+ {
+ if (b < p->needInitLevel)
+ return LZMA2_STATE_ERROR;
+ p->needInitLevel = 0;
+ p->unpackSize = (UInt32)(b & 0x1F) << 16;
+ }
+ return LZMA2_STATE_UNPACK0;
+
+ case LZMA2_STATE_UNPACK0:
+ p->unpackSize |= (UInt32)b << 8;
+ return LZMA2_STATE_UNPACK1;
+
+ case LZMA2_STATE_UNPACK1:
+ p->unpackSize |= (UInt32)b;
+ p->unpackSize++;
+ PRF(printf(" %7u", (unsigned)p->unpackSize));
+ return LZMA2_IS_UNCOMPRESSED_STATE(p) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
+
+ case LZMA2_STATE_PACK0:
+ p->packSize = (UInt32)b << 8;
+ return LZMA2_STATE_PACK1;
+
+ case LZMA2_STATE_PACK1:
+ p->packSize |= (UInt32)b;
+ p->packSize++;
+ // if (p->packSize < 5) return LZMA2_STATE_ERROR;
+ PRF(printf(" %5u", (unsigned)p->packSize));
+ return (p->control & 0x40) ? LZMA2_STATE_PROP : LZMA2_STATE_DATA;
+
+ case LZMA2_STATE_PROP:
+ {
+ unsigned lc, lp;
+ if (b >= (9 * 5 * 5))
+ return LZMA2_STATE_ERROR;
+ lc = b % 9;
+ b /= 9;
+ p->decoder.prop.pb = (Byte)(b / 5);
+ lp = b % 5;
+ if (lc + lp > LZMA2_LCLP_MAX)
+ return LZMA2_STATE_ERROR;
+ p->decoder.prop.lc = (Byte)lc;
+ p->decoder.prop.lp = (Byte)lp;
+ return LZMA2_STATE_DATA;
+ }
+ }
+ return LZMA2_STATE_ERROR;
+}
+
+static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
+{
+ memcpy(p->dic + p->dicPos, src, size);
+ p->dicPos += size;
+ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
+ p->checkDicSize = p->prop.dicSize;
+ p->processedPos += (UInt32)size;
+}
+
+void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState);
+
+
+SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+ SizeT inSize = *srcLen;
+ *srcLen = 0;
+ *status = LZMA_STATUS_NOT_SPECIFIED;
+
+ while (p->state != LZMA2_STATE_ERROR)
+ {
+ SizeT dicPos;
+
+ if (p->state == LZMA2_STATE_FINISHED)
+ {
+ *status = LZMA_STATUS_FINISHED_WITH_MARK;
+ return SZ_OK;
+ }
+
+ dicPos = p->decoder.dicPos;
+
+ if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
+ {
+ *status = LZMA_STATUS_NOT_FINISHED;
+ return SZ_OK;
+ }
+
+ if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
+ {
+ if (*srcLen == inSize)
+ {
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+ return SZ_OK;
+ }
+ (*srcLen)++;
+ p->state = Lzma2Dec_UpdateState(p, *src++);
+ if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
+ break;
+ continue;
+ }
+
+ {
+ SizeT inCur = inSize - *srcLen;
+ SizeT outCur = dicLimit - dicPos;
+ ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
+
+ if (outCur >= p->unpackSize)
+ {
+ outCur = (SizeT)p->unpackSize;
+ curFinishMode = LZMA_FINISH_END;
+ }
+
+ if (LZMA2_IS_UNCOMPRESSED_STATE(p))
+ {
+ if (inCur == 0)
+ {
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+ return SZ_OK;
+ }
+
+ if (p->state == LZMA2_STATE_DATA)
+ {
+ BoolInt initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
+ LzmaDec_InitDicAndState(&p->decoder, initDic, False);
+ }
+
+ if (inCur > outCur)
+ inCur = outCur;
+ if (inCur == 0)
+ break;
+
+ LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur);
+
+ src += inCur;
+ *srcLen += inCur;
+ p->unpackSize -= (UInt32)inCur;
+ p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
+ }
+ else
+ {
+ SRes res;
+
+ if (p->state == LZMA2_STATE_DATA)
+ {
+ BoolInt initDic = (p->control >= 0xE0);
+ BoolInt initState = (p->control >= 0xA0);
+ LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
+ p->state = LZMA2_STATE_DATA_CONT;
+ }
+
+ if (inCur > p->packSize)
+ inCur = (SizeT)p->packSize;
+
+ res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status);
+
+ src += inCur;
+ *srcLen += inCur;
+ p->packSize -= (UInt32)inCur;
+ outCur = p->decoder.dicPos - dicPos;
+ p->unpackSize -= (UInt32)outCur;
+
+ if (res != 0)
+ break;
+
+ if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
+ {
+ if (p->packSize == 0)
+ break;
+ return SZ_OK;
+ }
+
+ if (inCur == 0 && outCur == 0)
+ {
+ if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+ || p->unpackSize != 0
+ || p->packSize != 0)
+ break;
+ p->state = LZMA2_STATE_CONTROL;
+ }
+
+ *status = LZMA_STATUS_NOT_SPECIFIED;
+ }
+ }
+ }
+
+ *status = LZMA_STATUS_NOT_SPECIFIED;
+ p->state = LZMA2_STATE_ERROR;
+ return SZ_ERROR_DATA;
+}
+
+
+
+
+ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p,
+ SizeT outSize,
+ const Byte *src, SizeT *srcLen,
+ int checkFinishBlock)
+{
+ SizeT inSize = *srcLen;
+ *srcLen = 0;
+
+ while (p->state != LZMA2_STATE_ERROR)
+ {
+ if (p->state == LZMA2_STATE_FINISHED)
+ return (ELzma2ParseStatus)LZMA_STATUS_FINISHED_WITH_MARK;
+
+ if (outSize == 0 && !checkFinishBlock)
+ return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
+
+ if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
+ {
+ if (*srcLen == inSize)
+ return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
+ (*srcLen)++;
+
+ p->state = Lzma2Dec_UpdateState(p, *src++);
+
+ if (p->state == LZMA2_STATE_UNPACK0)
+ {
+ // if (p->decoder.dicPos != 0)
+ if (p->control == LZMA2_CONTROL_COPY_RESET_DIC || p->control >= 0xE0)
+ return LZMA2_PARSE_STATUS_NEW_BLOCK;
+ // if (outSize == 0) return LZMA_STATUS_NOT_FINISHED;
+ }
+
+ // The following code can be commented.
+ // It's not big problem, if we read additional input bytes.
+ // It will be stopped later in LZMA2_STATE_DATA / LZMA2_STATE_DATA_CONT state.
+
+ if (outSize == 0 && p->state != LZMA2_STATE_FINISHED)
+ {
+ // checkFinishBlock is true. So we expect that block must be finished,
+ // We can return LZMA_STATUS_NOT_SPECIFIED or LZMA_STATUS_NOT_FINISHED here
+ // break;
+ return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
+ }
+
+ if (p->state == LZMA2_STATE_DATA)
+ return LZMA2_PARSE_STATUS_NEW_CHUNK;
+
+ continue;
+ }
+
+ if (outSize == 0)
+ return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
+
+ {
+ SizeT inCur = inSize - *srcLen;
+
+ if (LZMA2_IS_UNCOMPRESSED_STATE(p))
+ {
+ if (inCur == 0)
+ return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
+ if (inCur > p->unpackSize)
+ inCur = p->unpackSize;
+ if (inCur > outSize)
+ inCur = outSize;
+ p->decoder.dicPos += inCur;
+ src += inCur;
+ *srcLen += inCur;
+ outSize -= inCur;
+ p->unpackSize -= (UInt32)inCur;
+ p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
+ }
+ else
+ {
+ p->isExtraMode = True;
+
+ if (inCur == 0)
+ {
+ if (p->packSize != 0)
+ return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
+ }
+ else if (p->state == LZMA2_STATE_DATA)
+ {
+ p->state = LZMA2_STATE_DATA_CONT;
+ if (*src != 0)
+ {
+ // first byte of lzma chunk must be Zero
+ *srcLen += 1;
+ p->packSize--;
+ break;
+ }
+ }
+
+ if (inCur > p->packSize)
+ inCur = (SizeT)p->packSize;
+
+ src += inCur;
+ *srcLen += inCur;
+ p->packSize -= (UInt32)inCur;
+
+ if (p->packSize == 0)
+ {
+ SizeT rem = outSize;
+ if (rem > p->unpackSize)
+ rem = p->unpackSize;
+ p->decoder.dicPos += rem;
+ p->unpackSize -= (UInt32)rem;
+ outSize -= rem;
+ if (p->unpackSize == 0)
+ p->state = LZMA2_STATE_CONTROL;
+ }
+ }
+ }
+ }
+
+ p->state = LZMA2_STATE_ERROR;
+ return (ELzma2ParseStatus)LZMA_STATUS_NOT_SPECIFIED;
+}
+
+
+
+
+SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+ SizeT outSize = *destLen, inSize = *srcLen;
+ *srcLen = *destLen = 0;
+
+ for (;;)
+ {
+ SizeT inCur = inSize, outCur, dicPos;
+ ELzmaFinishMode curFinishMode;
+ SRes res;
+
+ if (p->decoder.dicPos == p->decoder.dicBufSize)
+ p->decoder.dicPos = 0;
+ dicPos = p->decoder.dicPos;
+ curFinishMode = LZMA_FINISH_ANY;
+ outCur = p->decoder.dicBufSize - dicPos;
+
+ if (outCur >= outSize)
+ {
+ outCur = outSize;
+ curFinishMode = finishMode;
+ }
+
+ res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status);
+
+ src += inCur;
+ inSize -= inCur;
+ *srcLen += inCur;
+ outCur = p->decoder.dicPos - dicPos;
+ memcpy(dest, p->decoder.dic + dicPos, outCur);
+ dest += outCur;
+ outSize -= outCur;
+ *destLen += outCur;
+ if (res != 0)
+ return res;
+ if (outCur == 0 || outSize == 0)
+ return SZ_OK;
+ }
+}
+
+
+SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+ Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc)
+{
+ CLzma2Dec p;
+ SRes res;
+ SizeT outSize = *destLen, inSize = *srcLen;
+ *destLen = *srcLen = 0;
+ *status = LZMA_STATUS_NOT_SPECIFIED;
+ Lzma2Dec_Construct(&p);
+ RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc));
+ p.decoder.dic = dest;
+ p.decoder.dicBufSize = outSize;
+ Lzma2Dec_Init(&p);
+ *srcLen = inSize;
+ res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
+ *destLen = p.decoder.dicPos;
+ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
+ res = SZ_ERROR_INPUT_EOF;
+ Lzma2Dec_FreeProbs(&p, alloc);
+ return res;
+}
diff --git a/contrib/libs/lzmasdk/Lzma2Dec.h b/contrib/libs/lzmasdk/Lzma2Dec.h
index 74948d910b..b8ddeac890 100644
--- a/contrib/libs/lzmasdk/Lzma2Dec.h
+++ b/contrib/libs/lzmasdk/Lzma2Dec.h
@@ -1,120 +1,120 @@
-/* Lzma2Dec.h -- LZMA2 Decoder
-2018-02-19 : Igor Pavlov : Public domain */
-
-#ifndef __LZMA2_DEC_H
-#define __LZMA2_DEC_H
-
-#include "LzmaDec.h"
-
-EXTERN_C_BEGIN
-
-/* ---------- State Interface ---------- */
-
-typedef struct
-{
- unsigned state;
- Byte control;
- Byte needInitLevel;
- Byte isExtraMode;
- Byte _pad_;
- UInt32 packSize;
- UInt32 unpackSize;
- CLzmaDec decoder;
-} CLzma2Dec;
-
-#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)
-#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc)
-#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc)
-
-SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
-SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
-void Lzma2Dec_Init(CLzma2Dec *p);
-
-/*
-finishMode:
- It has meaning only if the decoding reaches output limit (*destLen or dicLimit).
- LZMA_FINISH_ANY - use smallest number of input bytes
- LZMA_FINISH_END - read EndOfStream marker after decoding
-
-Returns:
- SZ_OK
- status:
- LZMA_STATUS_FINISHED_WITH_MARK
- LZMA_STATUS_NOT_FINISHED
- LZMA_STATUS_NEEDS_MORE_INPUT
- SZ_ERROR_DATA - Data error
-*/
-
-SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
-
-SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen,
- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
-
-
-/* ---------- LZMA2 block and chunk parsing ---------- */
-
-/*
-Lzma2Dec_Parse() parses compressed data stream up to next independent block or next chunk data.
-It can return LZMA_STATUS_* code or LZMA2_PARSE_STATUS_* code:
- - LZMA2_PARSE_STATUS_NEW_BLOCK - there is new block, and 1 additional byte (control byte of next block header) was read from input.
- - LZMA2_PARSE_STATUS_NEW_CHUNK - there is new chunk, and only lzma2 header of new chunk was read.
- CLzma2Dec::unpackSize contains unpack size of that chunk
-*/
-
-typedef enum
-{
-/*
- LZMA_STATUS_NOT_SPECIFIED // data error
- LZMA_STATUS_FINISHED_WITH_MARK
- LZMA_STATUS_NOT_FINISHED //
- LZMA_STATUS_NEEDS_MORE_INPUT
- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK // unused
-*/
- LZMA2_PARSE_STATUS_NEW_BLOCK = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + 1,
- LZMA2_PARSE_STATUS_NEW_CHUNK
-} ELzma2ParseStatus;
-
-ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p,
- SizeT outSize, // output size
- const Byte *src, SizeT *srcLen,
- int checkFinishBlock // set (checkFinishBlock = 1), if it must read full input data, if decoder.dicPos reaches blockMax position.
- );
-
-/*
-LZMA2 parser doesn't decode LZMA chunks, so we must read
- full input LZMA chunk to decode some part of LZMA chunk.
-
-Lzma2Dec_GetUnpackExtra() returns the value that shows
- max possible number of output bytes that can be output by decoder
- at current input positon.
-*/
-
-#define Lzma2Dec_GetUnpackExtra(p) ((p)->isExtraMode ? (p)->unpackSize : 0);
-
-
-/* ---------- One Call Interface ---------- */
-
-/*
-finishMode:
- It has meaning only if the decoding reaches output limit (*destLen).
- LZMA_FINISH_ANY - use smallest number of input bytes
- LZMA_FINISH_END - read EndOfStream marker after decoding
-
-Returns:
- SZ_OK
- status:
- LZMA_STATUS_FINISHED_WITH_MARK
- LZMA_STATUS_NOT_FINISHED
- SZ_ERROR_DATA - Data error
- SZ_ERROR_MEM - Memory allocation error
- SZ_ERROR_UNSUPPORTED - Unsupported properties
- SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
-*/
-
-SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
- Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc);
-
-EXTERN_C_END
-
-#endif
+/* Lzma2Dec.h -- LZMA2 Decoder
+2018-02-19 : Igor Pavlov : Public domain */
+
+#ifndef __LZMA2_DEC_H
+#define __LZMA2_DEC_H
+
+#include "LzmaDec.h"
+
+EXTERN_C_BEGIN
+
+/* ---------- State Interface ---------- */
+
+typedef struct
+{
+ unsigned state;
+ Byte control;
+ Byte needInitLevel;
+ Byte isExtraMode;
+ Byte _pad_;
+ UInt32 packSize;
+ UInt32 unpackSize;
+ CLzmaDec decoder;
+} CLzma2Dec;
+
+#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)
+#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc)
+#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc)
+
+SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
+SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
+void Lzma2Dec_Init(CLzma2Dec *p);
+
+/*
+finishMode:
+ It has meaning only if the decoding reaches output limit (*destLen or dicLimit).
+ LZMA_FINISH_ANY - use smallest number of input bytes
+ LZMA_FINISH_END - read EndOfStream marker after decoding
+
+Returns:
+ SZ_OK
+ status:
+ LZMA_STATUS_FINISHED_WITH_MARK
+ LZMA_STATUS_NOT_FINISHED
+ LZMA_STATUS_NEEDS_MORE_INPUT
+ SZ_ERROR_DATA - Data error
+*/
+
+SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
+
+SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen,
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
+
+
+/* ---------- LZMA2 block and chunk parsing ---------- */
+
+/*
+Lzma2Dec_Parse() parses compressed data stream up to next independent block or next chunk data.
+It can return LZMA_STATUS_* code or LZMA2_PARSE_STATUS_* code:
+ - LZMA2_PARSE_STATUS_NEW_BLOCK - there is new block, and 1 additional byte (control byte of next block header) was read from input.
+ - LZMA2_PARSE_STATUS_NEW_CHUNK - there is new chunk, and only lzma2 header of new chunk was read.
+ CLzma2Dec::unpackSize contains unpack size of that chunk
+*/
+
+typedef enum
+{
+/*
+ LZMA_STATUS_NOT_SPECIFIED // data error
+ LZMA_STATUS_FINISHED_WITH_MARK
+ LZMA_STATUS_NOT_FINISHED //
+ LZMA_STATUS_NEEDS_MORE_INPUT
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK // unused
+*/
+ LZMA2_PARSE_STATUS_NEW_BLOCK = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + 1,
+ LZMA2_PARSE_STATUS_NEW_CHUNK
+} ELzma2ParseStatus;
+
+ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p,
+ SizeT outSize, // output size
+ const Byte *src, SizeT *srcLen,
+ int checkFinishBlock // set (checkFinishBlock = 1), if it must read full input data, if decoder.dicPos reaches blockMax position.
+ );
+
+/*
+LZMA2 parser doesn't decode LZMA chunks, so we must read
+ full input LZMA chunk to decode some part of LZMA chunk.
+
+Lzma2Dec_GetUnpackExtra() returns the value that shows
+ max possible number of output bytes that can be output by decoder
+ at current input positon.
+*/
+
+#define Lzma2Dec_GetUnpackExtra(p) ((p)->isExtraMode ? (p)->unpackSize : 0);
+
+
+/* ---------- One Call Interface ---------- */
+
+/*
+finishMode:
+ It has meaning only if the decoding reaches output limit (*destLen).
+ LZMA_FINISH_ANY - use smallest number of input bytes
+ LZMA_FINISH_END - read EndOfStream marker after decoding
+
+Returns:
+ SZ_OK
+ status:
+ LZMA_STATUS_FINISHED_WITH_MARK
+ LZMA_STATUS_NOT_FINISHED
+ SZ_ERROR_DATA - Data error
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_UNSUPPORTED - Unsupported properties
+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
+*/
+
+SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+ Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc);
+
+EXTERN_C_END
+
+#endif
diff --git a/contrib/libs/lzmasdk/Lzma2Enc.c b/contrib/libs/lzmasdk/Lzma2Enc.c
index a6fb10daac..5c1ad49312 100644
--- a/contrib/libs/lzmasdk/Lzma2Enc.c
+++ b/contrib/libs/lzmasdk/Lzma2Enc.c
@@ -1,803 +1,803 @@
-/* Lzma2Enc.c -- LZMA2 Encoder
-2018-07-04 : Igor Pavlov : Public domain */
-
-#include "Precomp.h"
-
-#include <string.h>
-
-/* #define _7ZIP_ST */
-
-#include "Lzma2Enc.h"
-
-#ifndef _7ZIP_ST
-#include "MtCoder.h"
-#else
-#define MTCODER__THREADS_MAX 1
-#endif
-
-#define LZMA2_CONTROL_LZMA (1 << 7)
-#define LZMA2_CONTROL_COPY_NO_RESET 2
-#define LZMA2_CONTROL_COPY_RESET_DIC 1
-#define LZMA2_CONTROL_EOF 0
-
-#define LZMA2_LCLP_MAX 4
-
-#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
-
-#define LZMA2_PACK_SIZE_MAX (1 << 16)
-#define LZMA2_COPY_CHUNK_SIZE LZMA2_PACK_SIZE_MAX
-#define LZMA2_UNPACK_SIZE_MAX (1 << 21)
-#define LZMA2_KEEP_WINDOW_SIZE LZMA2_UNPACK_SIZE_MAX
-
-#define LZMA2_CHUNK_SIZE_COMPRESSED_MAX ((1 << 16) + 16)
-
-
-#define PRF(x) /* x */
-
-
-/* ---------- CLimitedSeqInStream ---------- */
-
-typedef struct
-{
- ISeqInStream vt;
- ISeqInStream *realStream;
- UInt64 limit;
- UInt64 processed;
- int finished;
-} CLimitedSeqInStream;
-
-static void LimitedSeqInStream_Init(CLimitedSeqInStream *p)
-{
- p->limit = (UInt64)(Int64)-1;
- p->processed = 0;
- p->finished = 0;
-}
-
-static SRes LimitedSeqInStream_Read(const ISeqInStream *pp, void *data, size_t *size)
-{
- CLimitedSeqInStream *p = CONTAINER_FROM_VTBL(pp, CLimitedSeqInStream, vt);
- size_t size2 = *size;
- SRes res = SZ_OK;
-
- if (p->limit != (UInt64)(Int64)-1)
- {
- UInt64 rem = p->limit - p->processed;
- if (size2 > rem)
- size2 = (size_t)rem;
- }
- if (size2 != 0)
- {
- res = ISeqInStream_Read(p->realStream, data, &size2);
- p->finished = (size2 == 0 ? 1 : 0);
- p->processed += size2;
- }
- *size = size2;
- return res;
-}
-
-
-/* ---------- CLzma2EncInt ---------- */
-
-typedef struct
-{
- CLzmaEncHandle enc;
- Byte propsAreSet;
- Byte propsByte;
- Byte needInitState;
- Byte needInitProp;
- UInt64 srcPos;
-} CLzma2EncInt;
-
-
-static SRes Lzma2EncInt_InitStream(CLzma2EncInt *p, const CLzma2EncProps *props)
-{
- if (!p->propsAreSet)
- {
- SizeT propsSize = LZMA_PROPS_SIZE;
- Byte propsEncoded[LZMA_PROPS_SIZE];
- RINOK(LzmaEnc_SetProps(p->enc, &props->lzmaProps));
- RINOK(LzmaEnc_WriteProperties(p->enc, propsEncoded, &propsSize));
- p->propsByte = propsEncoded[0];
- p->propsAreSet = True;
- }
- return SZ_OK;
-}
-
-static void Lzma2EncInt_InitBlock(CLzma2EncInt *p)
-{
- p->srcPos = 0;
- p->needInitState = True;
- p->needInitProp = True;
-}
-
-
-SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ISeqInStream *inStream, UInt32 keepWindowSize,
- ISzAllocPtr alloc, ISzAllocPtr allocBig);
-SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
- UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig);
-SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, BoolInt reInit,
- Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize);
-const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp);
-void LzmaEnc_Finish(CLzmaEncHandle pp);
-void LzmaEnc_SaveState(CLzmaEncHandle pp);
-void LzmaEnc_RestoreState(CLzmaEncHandle pp);
-
-/*
-UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp);
-*/
-
-static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
- size_t *packSizeRes, ISeqOutStream *outStream)
-{
- size_t packSizeLimit = *packSizeRes;
- size_t packSize = packSizeLimit;
- UInt32 unpackSize = LZMA2_UNPACK_SIZE_MAX;
- unsigned lzHeaderSize = 5 + (p->needInitProp ? 1 : 0);
- BoolInt useCopyBlock;
- SRes res;
-
- *packSizeRes = 0;
- if (packSize < lzHeaderSize)
- return SZ_ERROR_OUTPUT_EOF;
- packSize -= lzHeaderSize;
-
- LzmaEnc_SaveState(p->enc);
- res = LzmaEnc_CodeOneMemBlock(p->enc, p->needInitState,
- outBuf + lzHeaderSize, &packSize, LZMA2_PACK_SIZE_MAX, &unpackSize);
-
- PRF(printf("\npackSize = %7d unpackSize = %7d ", packSize, unpackSize));
-
- if (unpackSize == 0)
- return res;
-
- if (res == SZ_OK)
- useCopyBlock = (packSize + 2 >= unpackSize || packSize > (1 << 16));
- else
- {
- if (res != SZ_ERROR_OUTPUT_EOF)
- return res;
- res = SZ_OK;
- useCopyBlock = True;
- }
-
- if (useCopyBlock)
- {
- size_t destPos = 0;
- PRF(printf("################# COPY "));
-
- while (unpackSize > 0)
- {
- UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE;
- if (packSizeLimit - destPos < u + 3)
- return SZ_ERROR_OUTPUT_EOF;
- outBuf[destPos++] = (Byte)(p->srcPos == 0 ? LZMA2_CONTROL_COPY_RESET_DIC : LZMA2_CONTROL_COPY_NO_RESET);
- outBuf[destPos++] = (Byte)((u - 1) >> 8);
- outBuf[destPos++] = (Byte)(u - 1);
- memcpy(outBuf + destPos, LzmaEnc_GetCurBuf(p->enc) - unpackSize, u);
- unpackSize -= u;
- destPos += u;
- p->srcPos += u;
-
- if (outStream)
- {
- *packSizeRes += destPos;
- if (ISeqOutStream_Write(outStream, outBuf, destPos) != destPos)
- return SZ_ERROR_WRITE;
- destPos = 0;
- }
- else
- *packSizeRes = destPos;
- /* needInitState = True; */
- }
-
- LzmaEnc_RestoreState(p->enc);
- return SZ_OK;
- }
-
- {
- size_t destPos = 0;
- UInt32 u = unpackSize - 1;
- UInt32 pm = (UInt32)(packSize - 1);
- unsigned mode = (p->srcPos == 0) ? 3 : (p->needInitState ? (p->needInitProp ? 2 : 1) : 0);
-
- PRF(printf(" "));
-
- outBuf[destPos++] = (Byte)(LZMA2_CONTROL_LZMA | (mode << 5) | ((u >> 16) & 0x1F));
- outBuf[destPos++] = (Byte)(u >> 8);
- outBuf[destPos++] = (Byte)u;
- outBuf[destPos++] = (Byte)(pm >> 8);
- outBuf[destPos++] = (Byte)pm;
-
- if (p->needInitProp)
- outBuf[destPos++] = p->propsByte;
-
- p->needInitProp = False;
- p->needInitState = False;
- destPos += packSize;
- p->srcPos += unpackSize;
-
- if (outStream)
- if (ISeqOutStream_Write(outStream, outBuf, destPos) != destPos)
- return SZ_ERROR_WRITE;
-
- *packSizeRes = destPos;
- return SZ_OK;
- }
-}
-
-
-/* ---------- Lzma2 Props ---------- */
-
-void Lzma2EncProps_Init(CLzma2EncProps *p)
-{
- LzmaEncProps_Init(&p->lzmaProps);
- p->blockSize = LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO;
- p->numBlockThreads_Reduced = -1;
- p->numBlockThreads_Max = -1;
- p->numTotalThreads = -1;
-}
-
-void Lzma2EncProps_Normalize(CLzma2EncProps *p)
-{
- UInt64 fileSize;
- int t1, t1n, t2, t2r, t3;
- {
- CLzmaEncProps lzmaProps = p->lzmaProps;
- LzmaEncProps_Normalize(&lzmaProps);
- t1n = lzmaProps.numThreads;
- }
-
- t1 = p->lzmaProps.numThreads;
- t2 = p->numBlockThreads_Max;
- t3 = p->numTotalThreads;
-
- if (t2 > MTCODER__THREADS_MAX)
- t2 = MTCODER__THREADS_MAX;
-
- if (t3 <= 0)
- {
- if (t2 <= 0)
- t2 = 1;
- t3 = t1n * t2;
- }
- else if (t2 <= 0)
- {
- t2 = t3 / t1n;
- if (t2 == 0)
- {
- t1 = 1;
- t2 = t3;
- }
- if (t2 > MTCODER__THREADS_MAX)
- t2 = MTCODER__THREADS_MAX;
- }
- else if (t1 <= 0)
- {
- t1 = t3 / t2;
- if (t1 == 0)
- t1 = 1;
- }
- else
- t3 = t1n * t2;
-
- p->lzmaProps.numThreads = t1;
-
- t2r = t2;
-
- fileSize = p->lzmaProps.reduceSize;
-
- if ( p->blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID
- && p->blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO
- && (p->blockSize < fileSize || fileSize == (UInt64)(Int64)-1))
- p->lzmaProps.reduceSize = p->blockSize;
-
- LzmaEncProps_Normalize(&p->lzmaProps);
-
- p->lzmaProps.reduceSize = fileSize;
-
- t1 = p->lzmaProps.numThreads;
-
- if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID)
- {
- t2r = t2 = 1;
- t3 = t1;
- }
- else if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO && t2 <= 1)
- {
- /* if there is no block multi-threading, we use SOLID block */
- p->blockSize = LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID;
- }
- else
- {
- if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO)
- {
- const UInt32 kMinSize = (UInt32)1 << 20;
- const UInt32 kMaxSize = (UInt32)1 << 28;
- const UInt32 dictSize = p->lzmaProps.dictSize;
- UInt64 blockSize = (UInt64)dictSize << 2;
- if (blockSize < kMinSize) blockSize = kMinSize;
- if (blockSize > kMaxSize) blockSize = kMaxSize;
- if (blockSize < dictSize) blockSize = dictSize;
- blockSize += (kMinSize - 1);
- blockSize &= ~(UInt64)(kMinSize - 1);
- p->blockSize = blockSize;
- }
-
- if (t2 > 1 && fileSize != (UInt64)(Int64)-1)
- {
- UInt64 numBlocks = fileSize / p->blockSize;
- if (numBlocks * p->blockSize != fileSize)
- numBlocks++;
- if (numBlocks < (unsigned)t2)
- {
- t2r = (unsigned)numBlocks;
- if (t2r == 0)
- t2r = 1;
- t3 = t1 * t2r;
- }
- }
- }
-
- p->numBlockThreads_Max = t2;
- p->numBlockThreads_Reduced = t2r;
- p->numTotalThreads = t3;
-}
-
-
-static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
-{
- return (p && ICompressProgress_Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
-}
-
-
-/* ---------- Lzma2 ---------- */
-
-typedef struct
-{
- Byte propEncoded;
- CLzma2EncProps props;
- UInt64 expectedDataSize;
-
- Byte *tempBufLzma;
-
- ISzAllocPtr alloc;
- ISzAllocPtr allocBig;
-
- CLzma2EncInt coders[MTCODER__THREADS_MAX];
-
- #ifndef _7ZIP_ST
-
- ISeqOutStream *outStream;
- Byte *outBuf;
- size_t outBuf_Rem; /* remainder in outBuf */
-
- size_t outBufSize; /* size of allocated outBufs[i] */
- size_t outBufsDataSizes[MTCODER__BLOCKS_MAX];
- BoolInt mtCoder_WasConstructed;
- CMtCoder mtCoder;
- Byte *outBufs[MTCODER__BLOCKS_MAX];
-
- #endif
-
-} CLzma2Enc;
-
-
-
-CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig)
-{
- CLzma2Enc *p = (CLzma2Enc *)ISzAlloc_Alloc(alloc, sizeof(CLzma2Enc));
- if (!p)
- return NULL;
- Lzma2EncProps_Init(&p->props);
- Lzma2EncProps_Normalize(&p->props);
- p->expectedDataSize = (UInt64)(Int64)-1;
- p->tempBufLzma = NULL;
- p->alloc = alloc;
- p->allocBig = allocBig;
- {
- unsigned i;
- for (i = 0; i < MTCODER__THREADS_MAX; i++)
- p->coders[i].enc = NULL;
- }
-
- #ifndef _7ZIP_ST
- p->mtCoder_WasConstructed = False;
- {
- unsigned i;
- for (i = 0; i < MTCODER__BLOCKS_MAX; i++)
- p->outBufs[i] = NULL;
- p->outBufSize = 0;
- }
- #endif
-
- return p;
-}
-
-
-#ifndef _7ZIP_ST
-
-static void Lzma2Enc_FreeOutBufs(CLzma2Enc *p)
-{
- unsigned i;
- for (i = 0; i < MTCODER__BLOCKS_MAX; i++)
- if (p->outBufs[i])
- {
- ISzAlloc_Free(p->alloc, p->outBufs[i]);
- p->outBufs[i] = NULL;
- }
- p->outBufSize = 0;
-}
-
-#endif
-
-
-void Lzma2Enc_Destroy(CLzma2EncHandle pp)
-{
- CLzma2Enc *p = (CLzma2Enc *)pp;
- unsigned i;
- for (i = 0; i < MTCODER__THREADS_MAX; i++)
- {
- CLzma2EncInt *t = &p->coders[i];
- if (t->enc)
- {
- LzmaEnc_Destroy(t->enc, p->alloc, p->allocBig);
- t->enc = NULL;
- }
- }
-
-
- #ifndef _7ZIP_ST
- if (p->mtCoder_WasConstructed)
- {
- MtCoder_Destruct(&p->mtCoder);
- p->mtCoder_WasConstructed = False;
- }
- Lzma2Enc_FreeOutBufs(p);
- #endif
-
- ISzAlloc_Free(p->alloc, p->tempBufLzma);
- p->tempBufLzma = NULL;
-
- ISzAlloc_Free(p->alloc, pp);
-}
-
-
-SRes Lzma2Enc_SetProps(CLzma2EncHandle pp, const CLzma2EncProps *props)
-{
- CLzma2Enc *p = (CLzma2Enc *)pp;
- CLzmaEncProps lzmaProps = props->lzmaProps;
- LzmaEncProps_Normalize(&lzmaProps);
- if (lzmaProps.lc + lzmaProps.lp > LZMA2_LCLP_MAX)
- return SZ_ERROR_PARAM;
- p->props = *props;
- Lzma2EncProps_Normalize(&p->props);
- return SZ_OK;
-}
-
-
-void Lzma2Enc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize)
-{
- CLzma2Enc *p = (CLzma2Enc *)pp;
- p->expectedDataSize = expectedDataSiize;
-}
-
-
-Byte Lzma2Enc_WriteProperties(CLzma2EncHandle pp)
-{
- CLzma2Enc *p = (CLzma2Enc *)pp;
- unsigned i;
- UInt32 dicSize = LzmaEncProps_GetDictSize(&p->props.lzmaProps);
- for (i = 0; i < 40; i++)
- if (dicSize <= LZMA2_DIC_SIZE_FROM_PROP(i))
- break;
- return (Byte)i;
-}
-
-
-static SRes Lzma2Enc_EncodeMt1(
- CLzma2Enc *me,
- CLzma2EncInt *p,
- ISeqOutStream *outStream,
- Byte *outBuf, size_t *outBufSize,
- ISeqInStream *inStream,
- const Byte *inData, size_t inDataSize,
- int finished,
- ICompressProgress *progress)
-{
- UInt64 unpackTotal = 0;
- UInt64 packTotal = 0;
- size_t outLim = 0;
- CLimitedSeqInStream limitedInStream;
-
- if (outBuf)
- {
- outLim = *outBufSize;
- *outBufSize = 0;
- }
-
- if (!p->enc)
- {
- p->propsAreSet = False;
- p->enc = LzmaEnc_Create(me->alloc);
- if (!p->enc)
- return SZ_ERROR_MEM;
- }
-
- limitedInStream.realStream = inStream;
- if (inStream)
- {
- limitedInStream.vt.Read = LimitedSeqInStream_Read;
- }
-
- if (!outBuf)
- {
- // outStream version works only in one thread. So we use CLzma2Enc::tempBufLzma
- if (!me->tempBufLzma)
- {
- me->tempBufLzma = (Byte *)ISzAlloc_Alloc(me->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
- if (!me->tempBufLzma)
- return SZ_ERROR_MEM;
- }
- }
-
- RINOK(Lzma2EncInt_InitStream(p, &me->props));
-
- for (;;)
- {
- SRes res = SZ_OK;
- size_t inSizeCur = 0;
-
- Lzma2EncInt_InitBlock(p);
-
- LimitedSeqInStream_Init(&limitedInStream);
- limitedInStream.limit = me->props.blockSize;
-
- if (inStream)
- {
- UInt64 expected = (UInt64)(Int64)-1;
- // inStream version works only in one thread. So we use CLzma2Enc::expectedDataSize
- if (me->expectedDataSize != (UInt64)(Int64)-1
- && me->expectedDataSize >= unpackTotal)
- expected = me->expectedDataSize - unpackTotal;
- if (me->props.blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID
- && expected > me->props.blockSize)
- expected = (size_t)me->props.blockSize;
-
- LzmaEnc_SetDataSize(p->enc, expected);
-
- RINOK(LzmaEnc_PrepareForLzma2(p->enc,
- &limitedInStream.vt,
- LZMA2_KEEP_WINDOW_SIZE,
- me->alloc,
- me->allocBig));
- }
- else
- {
- inSizeCur = inDataSize - (size_t)unpackTotal;
- if (me->props.blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID
- && inSizeCur > me->props.blockSize)
- inSizeCur = (size_t)me->props.blockSize;
-
- // LzmaEnc_SetDataSize(p->enc, inSizeCur);
-
- RINOK(LzmaEnc_MemPrepare(p->enc,
- inData + (size_t)unpackTotal, inSizeCur,
- LZMA2_KEEP_WINDOW_SIZE,
- me->alloc,
- me->allocBig));
- }
-
- for (;;)
- {
- size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX;
- if (outBuf)
- packSize = outLim - (size_t)packTotal;
-
- res = Lzma2EncInt_EncodeSubblock(p,
- outBuf ? outBuf + (size_t)packTotal : me->tempBufLzma, &packSize,
- outBuf ? NULL : outStream);
-
- if (res != SZ_OK)
- break;
-
- packTotal += packSize;
- if (outBuf)
- *outBufSize = (size_t)packTotal;
-
- res = Progress(progress, unpackTotal + p->srcPos, packTotal);
- if (res != SZ_OK)
- break;
-
- /*
- if (LzmaEnc_GetNumAvailableBytes(p->enc) == 0)
- break;
- */
-
- if (packSize == 0)
- break;
- }
-
- LzmaEnc_Finish(p->enc);
-
- unpackTotal += p->srcPos;
-
- RINOK(res);
-
- if (p->srcPos != (inStream ? limitedInStream.processed : inSizeCur))
- return SZ_ERROR_FAIL;
-
- if (inStream ? limitedInStream.finished : (unpackTotal == inDataSize))
- {
- if (finished)
- {
- if (outBuf)
- {
- size_t destPos = *outBufSize;
- if (destPos >= outLim)
- return SZ_ERROR_OUTPUT_EOF;
- outBuf[destPos] = 0;
- *outBufSize = destPos + 1;
- }
- else
- {
- Byte b = 0;
- if (ISeqOutStream_Write(outStream, &b, 1) != 1)
- return SZ_ERROR_WRITE;
- }
- }
- return SZ_OK;
- }
- }
-}
-
-
-
-#ifndef _7ZIP_ST
-
-static SRes Lzma2Enc_MtCallback_Code(void *pp, unsigned coderIndex, unsigned outBufIndex,
- const Byte *src, size_t srcSize, int finished)
-{
- CLzma2Enc *me = (CLzma2Enc *)pp;
- size_t destSize = me->outBufSize;
- SRes res;
- CMtProgressThunk progressThunk;
-
- Byte *dest = me->outBufs[outBufIndex];
-
- me->outBufsDataSizes[outBufIndex] = 0;
-
- if (!dest)
- {
- dest = (Byte *)ISzAlloc_Alloc(me->alloc, me->outBufSize);
- if (!dest)
- return SZ_ERROR_MEM;
- me->outBufs[outBufIndex] = dest;
- }
-
- MtProgressThunk_CreateVTable(&progressThunk);
- progressThunk.mtProgress = &me->mtCoder.mtProgress;
- progressThunk.inSize = 0;
- progressThunk.outSize = 0;
-
- res = Lzma2Enc_EncodeMt1(me,
- &me->coders[coderIndex],
- NULL, dest, &destSize,
- NULL, src, srcSize,
- finished,
- &progressThunk.vt);
-
- me->outBufsDataSizes[outBufIndex] = destSize;
-
- return res;
-}
-
-
-static SRes Lzma2Enc_MtCallback_Write(void *pp, unsigned outBufIndex)
-{
- CLzma2Enc *me = (CLzma2Enc *)pp;
- size_t size = me->outBufsDataSizes[outBufIndex];
- const Byte *data = me->outBufs[outBufIndex];
-
- if (me->outStream)
- return ISeqOutStream_Write(me->outStream, data, size) == size ? SZ_OK : SZ_ERROR_WRITE;
-
- if (size > me->outBuf_Rem)
- return SZ_ERROR_OUTPUT_EOF;
- memcpy(me->outBuf, data, size);
- me->outBuf_Rem -= size;
- me->outBuf += size;
- return SZ_OK;
-}
-
-#endif
-
-
-
-SRes Lzma2Enc_Encode2(CLzma2EncHandle pp,
- ISeqOutStream *outStream,
- Byte *outBuf, size_t *outBufSize,
- ISeqInStream *inStream,
- const Byte *inData, size_t inDataSize,
- ICompressProgress *progress)
-{
- CLzma2Enc *p = (CLzma2Enc *)pp;
-
- if (inStream && inData)
- return SZ_ERROR_PARAM;
-
- if (outStream && outBuf)
- return SZ_ERROR_PARAM;
-
- {
- unsigned i;
- for (i = 0; i < MTCODER__THREADS_MAX; i++)
- p->coders[i].propsAreSet = False;
- }
-
- #ifndef _7ZIP_ST
-
- if (p->props.numBlockThreads_Reduced > 1)
- {
- IMtCoderCallback2 vt;
-
- if (!p->mtCoder_WasConstructed)
- {
- p->mtCoder_WasConstructed = True;
- MtCoder_Construct(&p->mtCoder);
- }
-
- vt.Code = Lzma2Enc_MtCallback_Code;
- vt.Write = Lzma2Enc_MtCallback_Write;
-
- p->outStream = outStream;
- p->outBuf = NULL;
- p->outBuf_Rem = 0;
- if (!outStream)
- {
- p->outBuf = outBuf;
- p->outBuf_Rem = *outBufSize;
- *outBufSize = 0;
- }
-
- p->mtCoder.allocBig = p->allocBig;
- p->mtCoder.progress = progress;
- p->mtCoder.inStream = inStream;
- p->mtCoder.inData = inData;
- p->mtCoder.inDataSize = inDataSize;
- p->mtCoder.mtCallback = &vt;
- p->mtCoder.mtCallbackObject = p;
-
- p->mtCoder.blockSize = (size_t)p->props.blockSize;
- if (p->mtCoder.blockSize != p->props.blockSize)
- return SZ_ERROR_PARAM; /* SZ_ERROR_MEM */
-
- {
- size_t destBlockSize = p->mtCoder.blockSize + (p->mtCoder.blockSize >> 10) + 16;
- if (destBlockSize < p->mtCoder.blockSize)
- return SZ_ERROR_PARAM;
- if (p->outBufSize != destBlockSize)
- Lzma2Enc_FreeOutBufs(p);
- p->outBufSize = destBlockSize;
- }
-
- p->mtCoder.numThreadsMax = p->props.numBlockThreads_Max;
- p->mtCoder.expectedDataSize = p->expectedDataSize;
-
- {
- SRes res = MtCoder_Code(&p->mtCoder);
- if (!outStream)
- *outBufSize = p->outBuf - outBuf;
- return res;
- }
- }
-
- #endif
-
-
- return Lzma2Enc_EncodeMt1(p,
- &p->coders[0],
- outStream, outBuf, outBufSize,
- inStream, inData, inDataSize,
- True, /* finished */
- progress);
-}
+/* Lzma2Enc.c -- LZMA2 Encoder
+2018-07-04 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include <string.h>
+
+/* #define _7ZIP_ST */
+
+#include "Lzma2Enc.h"
+
+#ifndef _7ZIP_ST
+#include "MtCoder.h"
+#else
+#define MTCODER__THREADS_MAX 1
+#endif
+
+#define LZMA2_CONTROL_LZMA (1 << 7)
+#define LZMA2_CONTROL_COPY_NO_RESET 2
+#define LZMA2_CONTROL_COPY_RESET_DIC 1
+#define LZMA2_CONTROL_EOF 0
+
+#define LZMA2_LCLP_MAX 4
+
+#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
+
+#define LZMA2_PACK_SIZE_MAX (1 << 16)
+#define LZMA2_COPY_CHUNK_SIZE LZMA2_PACK_SIZE_MAX
+#define LZMA2_UNPACK_SIZE_MAX (1 << 21)
+#define LZMA2_KEEP_WINDOW_SIZE LZMA2_UNPACK_SIZE_MAX
+
+#define LZMA2_CHUNK_SIZE_COMPRESSED_MAX ((1 << 16) + 16)
+
+
+#define PRF(x) /* x */
+
+
+/* ---------- CLimitedSeqInStream ---------- */
+
+typedef struct
+{
+ ISeqInStream vt;
+ ISeqInStream *realStream;
+ UInt64 limit;
+ UInt64 processed;
+ int finished;
+} CLimitedSeqInStream;
+
+static void LimitedSeqInStream_Init(CLimitedSeqInStream *p)
+{
+ p->limit = (UInt64)(Int64)-1;
+ p->processed = 0;
+ p->finished = 0;
+}
+
+static SRes LimitedSeqInStream_Read(const ISeqInStream *pp, void *data, size_t *size)
+{
+ CLimitedSeqInStream *p = CONTAINER_FROM_VTBL(pp, CLimitedSeqInStream, vt);
+ size_t size2 = *size;
+ SRes res = SZ_OK;
+
+ if (p->limit != (UInt64)(Int64)-1)
+ {
+ UInt64 rem = p->limit - p->processed;
+ if (size2 > rem)
+ size2 = (size_t)rem;
+ }
+ if (size2 != 0)
+ {
+ res = ISeqInStream_Read(p->realStream, data, &size2);
+ p->finished = (size2 == 0 ? 1 : 0);
+ p->processed += size2;
+ }
+ *size = size2;
+ return res;
+}
+
+
+/* ---------- CLzma2EncInt ---------- */
+
+typedef struct
+{
+ CLzmaEncHandle enc;
+ Byte propsAreSet;
+ Byte propsByte;
+ Byte needInitState;
+ Byte needInitProp;
+ UInt64 srcPos;
+} CLzma2EncInt;
+
+
+static SRes Lzma2EncInt_InitStream(CLzma2EncInt *p, const CLzma2EncProps *props)
+{
+ if (!p->propsAreSet)
+ {
+ SizeT propsSize = LZMA_PROPS_SIZE;
+ Byte propsEncoded[LZMA_PROPS_SIZE];
+ RINOK(LzmaEnc_SetProps(p->enc, &props->lzmaProps));
+ RINOK(LzmaEnc_WriteProperties(p->enc, propsEncoded, &propsSize));
+ p->propsByte = propsEncoded[0];
+ p->propsAreSet = True;
+ }
+ return SZ_OK;
+}
+
+static void Lzma2EncInt_InitBlock(CLzma2EncInt *p)
+{
+ p->srcPos = 0;
+ p->needInitState = True;
+ p->needInitProp = True;
+}
+
+
+SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ISeqInStream *inStream, UInt32 keepWindowSize,
+ ISzAllocPtr alloc, ISzAllocPtr allocBig);
+SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
+ UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig);
+SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, BoolInt reInit,
+ Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize);
+const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp);
+void LzmaEnc_Finish(CLzmaEncHandle pp);
+void LzmaEnc_SaveState(CLzmaEncHandle pp);
+void LzmaEnc_RestoreState(CLzmaEncHandle pp);
+
+/*
+UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp);
+*/
+
+static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
+ size_t *packSizeRes, ISeqOutStream *outStream)
+{
+ size_t packSizeLimit = *packSizeRes;
+ size_t packSize = packSizeLimit;
+ UInt32 unpackSize = LZMA2_UNPACK_SIZE_MAX;
+ unsigned lzHeaderSize = 5 + (p->needInitProp ? 1 : 0);
+ BoolInt useCopyBlock;
+ SRes res;
+
+ *packSizeRes = 0;
+ if (packSize < lzHeaderSize)
+ return SZ_ERROR_OUTPUT_EOF;
+ packSize -= lzHeaderSize;
+
+ LzmaEnc_SaveState(p->enc);
+ res = LzmaEnc_CodeOneMemBlock(p->enc, p->needInitState,
+ outBuf + lzHeaderSize, &packSize, LZMA2_PACK_SIZE_MAX, &unpackSize);
+
+ PRF(printf("\npackSize = %7d unpackSize = %7d ", packSize, unpackSize));
+
+ if (unpackSize == 0)
+ return res;
+
+ if (res == SZ_OK)
+ useCopyBlock = (packSize + 2 >= unpackSize || packSize > (1 << 16));
+ else
+ {
+ if (res != SZ_ERROR_OUTPUT_EOF)
+ return res;
+ res = SZ_OK;
+ useCopyBlock = True;
+ }
+
+ if (useCopyBlock)
+ {
+ size_t destPos = 0;
+ PRF(printf("################# COPY "));
+
+ while (unpackSize > 0)
+ {
+ UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE;
+ if (packSizeLimit - destPos < u + 3)
+ return SZ_ERROR_OUTPUT_EOF;
+ outBuf[destPos++] = (Byte)(p->srcPos == 0 ? LZMA2_CONTROL_COPY_RESET_DIC : LZMA2_CONTROL_COPY_NO_RESET);
+ outBuf[destPos++] = (Byte)((u - 1) >> 8);
+ outBuf[destPos++] = (Byte)(u - 1);
+ memcpy(outBuf + destPos, LzmaEnc_GetCurBuf(p->enc) - unpackSize, u);
+ unpackSize -= u;
+ destPos += u;
+ p->srcPos += u;
+
+ if (outStream)
+ {
+ *packSizeRes += destPos;
+ if (ISeqOutStream_Write(outStream, outBuf, destPos) != destPos)
+ return SZ_ERROR_WRITE;
+ destPos = 0;
+ }
+ else
+ *packSizeRes = destPos;
+ /* needInitState = True; */
+ }
+
+ LzmaEnc_RestoreState(p->enc);
+ return SZ_OK;
+ }
+
+ {
+ size_t destPos = 0;
+ UInt32 u = unpackSize - 1;
+ UInt32 pm = (UInt32)(packSize - 1);
+ unsigned mode = (p->srcPos == 0) ? 3 : (p->needInitState ? (p->needInitProp ? 2 : 1) : 0);
+
+ PRF(printf(" "));
+
+ outBuf[destPos++] = (Byte)(LZMA2_CONTROL_LZMA | (mode << 5) | ((u >> 16) & 0x1F));
+ outBuf[destPos++] = (Byte)(u >> 8);
+ outBuf[destPos++] = (Byte)u;
+ outBuf[destPos++] = (Byte)(pm >> 8);
+ outBuf[destPos++] = (Byte)pm;
+
+ if (p->needInitProp)
+ outBuf[destPos++] = p->propsByte;
+
+ p->needInitProp = False;
+ p->needInitState = False;
+ destPos += packSize;
+ p->srcPos += unpackSize;
+
+ if (outStream)
+ if (ISeqOutStream_Write(outStream, outBuf, destPos) != destPos)
+ return SZ_ERROR_WRITE;
+
+ *packSizeRes = destPos;
+ return SZ_OK;
+ }
+}
+
+
+/* ---------- Lzma2 Props ---------- */
+
+void Lzma2EncProps_Init(CLzma2EncProps *p)
+{
+ LzmaEncProps_Init(&p->lzmaProps);
+ p->blockSize = LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO;
+ p->numBlockThreads_Reduced = -1;
+ p->numBlockThreads_Max = -1;
+ p->numTotalThreads = -1;
+}
+
+void Lzma2EncProps_Normalize(CLzma2EncProps *p)
+{
+ UInt64 fileSize;
+ int t1, t1n, t2, t2r, t3;
+ {
+ CLzmaEncProps lzmaProps = p->lzmaProps;
+ LzmaEncProps_Normalize(&lzmaProps);
+ t1n = lzmaProps.numThreads;
+ }
+
+ t1 = p->lzmaProps.numThreads;
+ t2 = p->numBlockThreads_Max;
+ t3 = p->numTotalThreads;
+
+ if (t2 > MTCODER__THREADS_MAX)
+ t2 = MTCODER__THREADS_MAX;
+
+ if (t3 <= 0)
+ {
+ if (t2 <= 0)
+ t2 = 1;
+ t3 = t1n * t2;
+ }
+ else if (t2 <= 0)
+ {
+ t2 = t3 / t1n;
+ if (t2 == 0)
+ {
+ t1 = 1;
+ t2 = t3;
+ }
+ if (t2 > MTCODER__THREADS_MAX)
+ t2 = MTCODER__THREADS_MAX;
+ }
+ else if (t1 <= 0)
+ {
+ t1 = t3 / t2;
+ if (t1 == 0)
+ t1 = 1;
+ }
+ else
+ t3 = t1n * t2;
+
+ p->lzmaProps.numThreads = t1;
+
+ t2r = t2;
+
+ fileSize = p->lzmaProps.reduceSize;
+
+ if ( p->blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID
+ && p->blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO
+ && (p->blockSize < fileSize || fileSize == (UInt64)(Int64)-1))
+ p->lzmaProps.reduceSize = p->blockSize;
+
+ LzmaEncProps_Normalize(&p->lzmaProps);
+
+ p->lzmaProps.reduceSize = fileSize;
+
+ t1 = p->lzmaProps.numThreads;
+
+ if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID)
+ {
+ t2r = t2 = 1;
+ t3 = t1;
+ }
+ else if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO && t2 <= 1)
+ {
+ /* if there is no block multi-threading, we use SOLID block */
+ p->blockSize = LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID;
+ }
+ else
+ {
+ if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO)
+ {
+ const UInt32 kMinSize = (UInt32)1 << 20;
+ const UInt32 kMaxSize = (UInt32)1 << 28;
+ const UInt32 dictSize = p->lzmaProps.dictSize;
+ UInt64 blockSize = (UInt64)dictSize << 2;
+ if (blockSize < kMinSize) blockSize = kMinSize;
+ if (blockSize > kMaxSize) blockSize = kMaxSize;
+ if (blockSize < dictSize) blockSize = dictSize;
+ blockSize += (kMinSize - 1);
+ blockSize &= ~(UInt64)(kMinSize - 1);
+ p->blockSize = blockSize;
+ }
+
+ if (t2 > 1 && fileSize != (UInt64)(Int64)-1)
+ {
+ UInt64 numBlocks = fileSize / p->blockSize;
+ if (numBlocks * p->blockSize != fileSize)
+ numBlocks++;
+ if (numBlocks < (unsigned)t2)
+ {
+ t2r = (unsigned)numBlocks;
+ if (t2r == 0)
+ t2r = 1;
+ t3 = t1 * t2r;
+ }
+ }
+ }
+
+ p->numBlockThreads_Max = t2;
+ p->numBlockThreads_Reduced = t2r;
+ p->numTotalThreads = t3;
+}
+
+
+static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
+{
+ return (p && ICompressProgress_Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
+}
+
+
+/* ---------- Lzma2 ---------- */
+
+typedef struct
+{
+ Byte propEncoded;
+ CLzma2EncProps props;
+ UInt64 expectedDataSize;
+
+ Byte *tempBufLzma;
+
+ ISzAllocPtr alloc;
+ ISzAllocPtr allocBig;
+
+ CLzma2EncInt coders[MTCODER__THREADS_MAX];
+
+ #ifndef _7ZIP_ST
+
+ ISeqOutStream *outStream;
+ Byte *outBuf;
+ size_t outBuf_Rem; /* remainder in outBuf */
+
+ size_t outBufSize; /* size of allocated outBufs[i] */
+ size_t outBufsDataSizes[MTCODER__BLOCKS_MAX];
+ BoolInt mtCoder_WasConstructed;
+ CMtCoder mtCoder;
+ Byte *outBufs[MTCODER__BLOCKS_MAX];
+
+ #endif
+
+} CLzma2Enc;
+
+
+
+CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig)
+{
+ CLzma2Enc *p = (CLzma2Enc *)ISzAlloc_Alloc(alloc, sizeof(CLzma2Enc));
+ if (!p)
+ return NULL;
+ Lzma2EncProps_Init(&p->props);
+ Lzma2EncProps_Normalize(&p->props);
+ p->expectedDataSize = (UInt64)(Int64)-1;
+ p->tempBufLzma = NULL;
+ p->alloc = alloc;
+ p->allocBig = allocBig;
+ {
+ unsigned i;
+ for (i = 0; i < MTCODER__THREADS_MAX; i++)
+ p->coders[i].enc = NULL;
+ }
+
+ #ifndef _7ZIP_ST
+ p->mtCoder_WasConstructed = False;
+ {
+ unsigned i;
+ for (i = 0; i < MTCODER__BLOCKS_MAX; i++)
+ p->outBufs[i] = NULL;
+ p->outBufSize = 0;
+ }
+ #endif
+
+ return p;
+}
+
+
+#ifndef _7ZIP_ST
+
+static void Lzma2Enc_FreeOutBufs(CLzma2Enc *p)
+{
+ unsigned i;
+ for (i = 0; i < MTCODER__BLOCKS_MAX; i++)
+ if (p->outBufs[i])
+ {
+ ISzAlloc_Free(p->alloc, p->outBufs[i]);
+ p->outBufs[i] = NULL;
+ }
+ p->outBufSize = 0;
+}
+
+#endif
+
+
+void Lzma2Enc_Destroy(CLzma2EncHandle pp)
+{
+ CLzma2Enc *p = (CLzma2Enc *)pp;
+ unsigned i;
+ for (i = 0; i < MTCODER__THREADS_MAX; i++)
+ {
+ CLzma2EncInt *t = &p->coders[i];
+ if (t->enc)
+ {
+ LzmaEnc_Destroy(t->enc, p->alloc, p->allocBig);
+ t->enc = NULL;
+ }
+ }
+
+
+ #ifndef _7ZIP_ST
+ if (p->mtCoder_WasConstructed)
+ {
+ MtCoder_Destruct(&p->mtCoder);
+ p->mtCoder_WasConstructed = False;
+ }
+ Lzma2Enc_FreeOutBufs(p);
+ #endif
+
+ ISzAlloc_Free(p->alloc, p->tempBufLzma);
+ p->tempBufLzma = NULL;
+
+ ISzAlloc_Free(p->alloc, pp);
+}
+
+
+SRes Lzma2Enc_SetProps(CLzma2EncHandle pp, const CLzma2EncProps *props)
+{
+ CLzma2Enc *p = (CLzma2Enc *)pp;
+ CLzmaEncProps lzmaProps = props->lzmaProps;
+ LzmaEncProps_Normalize(&lzmaProps);
+ if (lzmaProps.lc + lzmaProps.lp > LZMA2_LCLP_MAX)
+ return SZ_ERROR_PARAM;
+ p->props = *props;
+ Lzma2EncProps_Normalize(&p->props);
+ return SZ_OK;
+}
+
+
+void Lzma2Enc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize)
+{
+ CLzma2Enc *p = (CLzma2Enc *)pp;
+ p->expectedDataSize = expectedDataSiize;
+}
+
+
+Byte Lzma2Enc_WriteProperties(CLzma2EncHandle pp)
+{
+ CLzma2Enc *p = (CLzma2Enc *)pp;
+ unsigned i;
+ UInt32 dicSize = LzmaEncProps_GetDictSize(&p->props.lzmaProps);
+ for (i = 0; i < 40; i++)
+ if (dicSize <= LZMA2_DIC_SIZE_FROM_PROP(i))
+ break;
+ return (Byte)i;
+}
+
+
+static SRes Lzma2Enc_EncodeMt1(
+ CLzma2Enc *me,
+ CLzma2EncInt *p,
+ ISeqOutStream *outStream,
+ Byte *outBuf, size_t *outBufSize,
+ ISeqInStream *inStream,
+ const Byte *inData, size_t inDataSize,
+ int finished,
+ ICompressProgress *progress)
+{
+ UInt64 unpackTotal = 0;
+ UInt64 packTotal = 0;
+ size_t outLim = 0;
+ CLimitedSeqInStream limitedInStream;
+
+ if (outBuf)
+ {
+ outLim = *outBufSize;
+ *outBufSize = 0;
+ }
+
+ if (!p->enc)
+ {
+ p->propsAreSet = False;
+ p->enc = LzmaEnc_Create(me->alloc);
+ if (!p->enc)
+ return SZ_ERROR_MEM;
+ }
+
+ limitedInStream.realStream = inStream;
+ if (inStream)
+ {
+ limitedInStream.vt.Read = LimitedSeqInStream_Read;
+ }
+
+ if (!outBuf)
+ {
+ // outStream version works only in one thread. So we use CLzma2Enc::tempBufLzma
+ if (!me->tempBufLzma)
+ {
+ me->tempBufLzma = (Byte *)ISzAlloc_Alloc(me->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
+ if (!me->tempBufLzma)
+ return SZ_ERROR_MEM;
+ }
+ }
+
+ RINOK(Lzma2EncInt_InitStream(p, &me->props));
+
+ for (;;)
+ {
+ SRes res = SZ_OK;
+ size_t inSizeCur = 0;
+
+ Lzma2EncInt_InitBlock(p);
+
+ LimitedSeqInStream_Init(&limitedInStream);
+ limitedInStream.limit = me->props.blockSize;
+
+ if (inStream)
+ {
+ UInt64 expected = (UInt64)(Int64)-1;
+ // inStream version works only in one thread. So we use CLzma2Enc::expectedDataSize
+ if (me->expectedDataSize != (UInt64)(Int64)-1
+ && me->expectedDataSize >= unpackTotal)
+ expected = me->expectedDataSize - unpackTotal;
+ if (me->props.blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID
+ && expected > me->props.blockSize)
+ expected = (size_t)me->props.blockSize;
+
+ LzmaEnc_SetDataSize(p->enc, expected);
+
+ RINOK(LzmaEnc_PrepareForLzma2(p->enc,
+ &limitedInStream.vt,
+ LZMA2_KEEP_WINDOW_SIZE,
+ me->alloc,
+ me->allocBig));
+ }
+ else
+ {
+ inSizeCur = inDataSize - (size_t)unpackTotal;
+ if (me->props.blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID
+ && inSizeCur > me->props.blockSize)
+ inSizeCur = (size_t)me->props.blockSize;
+
+ // LzmaEnc_SetDataSize(p->enc, inSizeCur);
+
+ RINOK(LzmaEnc_MemPrepare(p->enc,
+ inData + (size_t)unpackTotal, inSizeCur,
+ LZMA2_KEEP_WINDOW_SIZE,
+ me->alloc,
+ me->allocBig));
+ }
+
+ for (;;)
+ {
+ size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX;
+ if (outBuf)
+ packSize = outLim - (size_t)packTotal;
+
+ res = Lzma2EncInt_EncodeSubblock(p,
+ outBuf ? outBuf + (size_t)packTotal : me->tempBufLzma, &packSize,
+ outBuf ? NULL : outStream);
+
+ if (res != SZ_OK)
+ break;
+
+ packTotal += packSize;
+ if (outBuf)
+ *outBufSize = (size_t)packTotal;
+
+ res = Progress(progress, unpackTotal + p->srcPos, packTotal);
+ if (res != SZ_OK)
+ break;
+
+ /*
+ if (LzmaEnc_GetNumAvailableBytes(p->enc) == 0)
+ break;
+ */
+
+ if (packSize == 0)
+ break;
+ }
+
+ LzmaEnc_Finish(p->enc);
+
+ unpackTotal += p->srcPos;
+
+ RINOK(res);
+
+ if (p->srcPos != (inStream ? limitedInStream.processed : inSizeCur))
+ return SZ_ERROR_FAIL;
+
+ if (inStream ? limitedInStream.finished : (unpackTotal == inDataSize))
+ {
+ if (finished)
+ {
+ if (outBuf)
+ {
+ size_t destPos = *outBufSize;
+ if (destPos >= outLim)
+ return SZ_ERROR_OUTPUT_EOF;
+ outBuf[destPos] = 0;
+ *outBufSize = destPos + 1;
+ }
+ else
+ {
+ Byte b = 0;
+ if (ISeqOutStream_Write(outStream, &b, 1) != 1)
+ return SZ_ERROR_WRITE;
+ }
+ }
+ return SZ_OK;
+ }
+ }
+}
+
+
+
+#ifndef _7ZIP_ST
+
+static SRes Lzma2Enc_MtCallback_Code(void *pp, unsigned coderIndex, unsigned outBufIndex,
+ const Byte *src, size_t srcSize, int finished)
+{
+ CLzma2Enc *me = (CLzma2Enc *)pp;
+ size_t destSize = me->outBufSize;
+ SRes res;
+ CMtProgressThunk progressThunk;
+
+ Byte *dest = me->outBufs[outBufIndex];
+
+ me->outBufsDataSizes[outBufIndex] = 0;
+
+ if (!dest)
+ {
+ dest = (Byte *)ISzAlloc_Alloc(me->alloc, me->outBufSize);
+ if (!dest)
+ return SZ_ERROR_MEM;
+ me->outBufs[outBufIndex] = dest;
+ }
+
+ MtProgressThunk_CreateVTable(&progressThunk);
+ progressThunk.mtProgress = &me->mtCoder.mtProgress;
+ progressThunk.inSize = 0;
+ progressThunk.outSize = 0;
+
+ res = Lzma2Enc_EncodeMt1(me,
+ &me->coders[coderIndex],
+ NULL, dest, &destSize,
+ NULL, src, srcSize,
+ finished,
+ &progressThunk.vt);
+
+ me->outBufsDataSizes[outBufIndex] = destSize;
+
+ return res;
+}
+
+
+static SRes Lzma2Enc_MtCallback_Write(void *pp, unsigned outBufIndex)
+{
+ CLzma2Enc *me = (CLzma2Enc *)pp;
+ size_t size = me->outBufsDataSizes[outBufIndex];
+ const Byte *data = me->outBufs[outBufIndex];
+
+ if (me->outStream)
+ return ISeqOutStream_Write(me->outStream, data, size) == size ? SZ_OK : SZ_ERROR_WRITE;
+
+ if (size > me->outBuf_Rem)
+ return SZ_ERROR_OUTPUT_EOF;
+ memcpy(me->outBuf, data, size);
+ me->outBuf_Rem -= size;
+ me->outBuf += size;
+ return SZ_OK;
+}
+
+#endif
+
+
+
+SRes Lzma2Enc_Encode2(CLzma2EncHandle pp,
+ ISeqOutStream *outStream,
+ Byte *outBuf, size_t *outBufSize,
+ ISeqInStream *inStream,
+ const Byte *inData, size_t inDataSize,
+ ICompressProgress *progress)
+{
+ CLzma2Enc *p = (CLzma2Enc *)pp;
+
+ if (inStream && inData)
+ return SZ_ERROR_PARAM;
+
+ if (outStream && outBuf)
+ return SZ_ERROR_PARAM;
+
+ {
+ unsigned i;
+ for (i = 0; i < MTCODER__THREADS_MAX; i++)
+ p->coders[i].propsAreSet = False;
+ }
+
+ #ifndef _7ZIP_ST
+
+ if (p->props.numBlockThreads_Reduced > 1)
+ {
+ IMtCoderCallback2 vt;
+
+ if (!p->mtCoder_WasConstructed)
+ {
+ p->mtCoder_WasConstructed = True;
+ MtCoder_Construct(&p->mtCoder);
+ }
+
+ vt.Code = Lzma2Enc_MtCallback_Code;
+ vt.Write = Lzma2Enc_MtCallback_Write;
+
+ p->outStream = outStream;
+ p->outBuf = NULL;
+ p->outBuf_Rem = 0;
+ if (!outStream)
+ {
+ p->outBuf = outBuf;
+ p->outBuf_Rem = *outBufSize;
+ *outBufSize = 0;
+ }
+
+ p->mtCoder.allocBig = p->allocBig;
+ p->mtCoder.progress = progress;
+ p->mtCoder.inStream = inStream;
+ p->mtCoder.inData = inData;
+ p->mtCoder.inDataSize = inDataSize;
+ p->mtCoder.mtCallback = &vt;
+ p->mtCoder.mtCallbackObject = p;
+
+ p->mtCoder.blockSize = (size_t)p->props.blockSize;
+ if (p->mtCoder.blockSize != p->props.blockSize)
+ return SZ_ERROR_PARAM; /* SZ_ERROR_MEM */
+
+ {
+ size_t destBlockSize = p->mtCoder.blockSize + (p->mtCoder.blockSize >> 10) + 16;
+ if (destBlockSize < p->mtCoder.blockSize)
+ return SZ_ERROR_PARAM;
+ if (p->outBufSize != destBlockSize)
+ Lzma2Enc_FreeOutBufs(p);
+ p->outBufSize = destBlockSize;
+ }
+
+ p->mtCoder.numThreadsMax = p->props.numBlockThreads_Max;
+ p->mtCoder.expectedDataSize = p->expectedDataSize;
+
+ {
+ SRes res = MtCoder_Code(&p->mtCoder);
+ if (!outStream)
+ *outBufSize = p->outBuf - outBuf;
+ return res;
+ }
+ }
+
+ #endif
+
+
+ return Lzma2Enc_EncodeMt1(p,
+ &p->coders[0],
+ outStream, outBuf, outBufSize,
+ inStream, inData, inDataSize,
+ True, /* finished */
+ progress);
+}
diff --git a/contrib/libs/lzmasdk/Lzma2Enc.h b/contrib/libs/lzmasdk/Lzma2Enc.h
index b67986ce51..6a6110ff7e 100644
--- a/contrib/libs/lzmasdk/Lzma2Enc.h
+++ b/contrib/libs/lzmasdk/Lzma2Enc.h
@@ -1,55 +1,55 @@
-/* Lzma2Enc.h -- LZMA2 Encoder
-2017-07-27 : Igor Pavlov : Public domain */
-
-#ifndef __LZMA2_ENC_H
-#define __LZMA2_ENC_H
-
-#include "LzmaEnc.h"
-
-EXTERN_C_BEGIN
-
-#define LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO 0
-#define LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID ((UInt64)(Int64)-1)
-
-typedef struct
-{
- CLzmaEncProps lzmaProps;
- UInt64 blockSize;
- int numBlockThreads_Reduced;
- int numBlockThreads_Max;
- int numTotalThreads;
-} CLzma2EncProps;
-
-void Lzma2EncProps_Init(CLzma2EncProps *p);
-void Lzma2EncProps_Normalize(CLzma2EncProps *p);
-
-/* ---------- CLzmaEnc2Handle Interface ---------- */
-
-/* Lzma2Enc_* functions can return the following exit codes:
-SRes:
- SZ_OK - OK
- SZ_ERROR_MEM - Memory allocation error
- SZ_ERROR_PARAM - Incorrect paramater in props
- SZ_ERROR_WRITE - ISeqOutStream write callback error
- SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output
- SZ_ERROR_PROGRESS - some break from progress callback
- SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
-*/
-
-typedef void * CLzma2EncHandle;
-
-CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig);
-void Lzma2Enc_Destroy(CLzma2EncHandle p);
-SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props);
-void Lzma2Enc_SetDataSize(CLzma2EncHandle p, UInt64 expectedDataSiize);
-Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p);
-SRes Lzma2Enc_Encode2(CLzma2EncHandle p,
- ISeqOutStream *outStream,
- Byte *outBuf, size_t *outBufSize,
- ISeqInStream *inStream,
- const Byte *inData, size_t inDataSize,
- ICompressProgress *progress);
-
-EXTERN_C_END
-
-#endif
+/* Lzma2Enc.h -- LZMA2 Encoder
+2017-07-27 : Igor Pavlov : Public domain */
+
+#ifndef __LZMA2_ENC_H
+#define __LZMA2_ENC_H
+
+#include "LzmaEnc.h"
+
+EXTERN_C_BEGIN
+
+#define LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO 0
+#define LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID ((UInt64)(Int64)-1)
+
+typedef struct
+{
+ CLzmaEncProps lzmaProps;
+ UInt64 blockSize;
+ int numBlockThreads_Reduced;
+ int numBlockThreads_Max;
+ int numTotalThreads;
+} CLzma2EncProps;
+
+void Lzma2EncProps_Init(CLzma2EncProps *p);
+void Lzma2EncProps_Normalize(CLzma2EncProps *p);
+
+/* ---------- CLzmaEnc2Handle Interface ---------- */
+
+/* Lzma2Enc_* functions can return the following exit codes:
+SRes:
+ SZ_OK - OK
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_PARAM - Incorrect paramater in props
+ SZ_ERROR_WRITE - ISeqOutStream write callback error
+ SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output
+ SZ_ERROR_PROGRESS - some break from progress callback
+ SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
+*/
+
+typedef void * CLzma2EncHandle;
+
+CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig);
+void Lzma2Enc_Destroy(CLzma2EncHandle p);
+SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props);
+void Lzma2Enc_SetDataSize(CLzma2EncHandle p, UInt64 expectedDataSiize);
+Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p);
+SRes Lzma2Enc_Encode2(CLzma2EncHandle p,
+ ISeqOutStream *outStream,
+ Byte *outBuf, size_t *outBufSize,
+ ISeqInStream *inStream,
+ const Byte *inData, size_t inDataSize,
+ ICompressProgress *progress);
+
+EXTERN_C_END
+
+#endif
diff --git a/contrib/libs/lzmasdk/LzmaEnc.c b/contrib/libs/lzmasdk/LzmaEnc.c
index 3f2ce1a8bc..0ee2922390 100644
--- a/contrib/libs/lzmasdk/LzmaEnc.c
+++ b/contrib/libs/lzmasdk/LzmaEnc.c
@@ -2259,9 +2259,9 @@ void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig)
}
-SRes LzmaEnc_CodeOneBlock(CLzmaEncHandle pp, UInt32 maxPackSize, UInt32 maxUnpackSize)
+SRes LzmaEnc_CodeOneBlock(CLzmaEncHandle pp, UInt32 maxPackSize, UInt32 maxUnpackSize)
{
- CLzmaEnc *p = (CLzmaEnc *) pp;
+ CLzmaEnc *p = (CLzmaEnc *) pp;
UInt32 nowPos32, startPos32;
if (p->needInit)
{
@@ -2716,7 +2716,7 @@ static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr
return SZ_OK;
}
-SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream,
+SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream,
ISzAllocPtr alloc, ISzAllocPtr allocBig)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
@@ -2975,10 +2975,10 @@ SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
LzmaEnc_Destroy(p, alloc, allocBig);
return res;
}
-
-BoolInt LzmaEnc_IsFinished(CLzmaEncHandle pp)
-{
- CLzmaEnc *p = (CLzmaEnc *)pp;
- return p->finished;
-}
-
+
+BoolInt LzmaEnc_IsFinished(CLzmaEncHandle pp)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ return p->finished;
+}
+
diff --git a/contrib/libs/lzmasdk/LzmaEnc.h b/contrib/libs/lzmasdk/LzmaEnc.h
index 24b3919ce8..37a0906c7e 100644
--- a/contrib/libs/lzmasdk/LzmaEnc.h
+++ b/contrib/libs/lzmasdk/LzmaEnc.h
@@ -73,11 +73,11 @@ SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
EXTERN_C_END
-/* ---------- Streaming Interface ---------- */
-
-SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ISzAllocPtr alloc, ISzAllocPtr allocBig);
-SRes LzmaEnc_CodeOneBlock(CLzmaEncHandle pp, UInt32 maxPackSize, UInt32 maxUnpackSize);
-BoolInt LzmaEnc_IsFinished(CLzmaEncHandle pp);
-void LzmaEnc_Finish(CLzmaEncHandle pp);
-
+/* ---------- Streaming Interface ---------- */
+
+SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ISzAllocPtr alloc, ISzAllocPtr allocBig);
+SRes LzmaEnc_CodeOneBlock(CLzmaEncHandle pp, UInt32 maxPackSize, UInt32 maxUnpackSize);
+BoolInt LzmaEnc_IsFinished(CLzmaEncHandle pp);
+void LzmaEnc_Finish(CLzmaEncHandle pp);
+
#endif
diff --git a/contrib/libs/lzmasdk/MtCoder.h b/contrib/libs/lzmasdk/MtCoder.h
index 20e8cc16c6..5a5f4d11b9 100644
--- a/contrib/libs/lzmasdk/MtCoder.h
+++ b/contrib/libs/lzmasdk/MtCoder.h
@@ -1,141 +1,141 @@
-/* MtCoder.h -- Multi-thread Coder
-2018-07-04 : Igor Pavlov : Public domain */
-
-#ifndef __MT_CODER_H
-#define __MT_CODER_H
-
-#include "MtDec.h"
-
-EXTERN_C_BEGIN
-
-/*
- if ( defined MTCODER__USE_WRITE_THREAD) : main thread writes all data blocks to output stream
- if (not defined MTCODER__USE_WRITE_THREAD) : any coder thread can write data blocks to output stream
-*/
-/* #define MTCODER__USE_WRITE_THREAD */
-
-#ifndef _7ZIP_ST
- #define MTCODER__GET_NUM_BLOCKS_FROM_THREADS(numThreads) ((numThreads) + (numThreads) / 8 + 1)
- #define MTCODER__THREADS_MAX 64
- #define MTCODER__BLOCKS_MAX (MTCODER__GET_NUM_BLOCKS_FROM_THREADS(MTCODER__THREADS_MAX) + 3)
-#else
- #define MTCODER__THREADS_MAX 1
- #define MTCODER__BLOCKS_MAX 1
-#endif
-
-
-#ifndef _7ZIP_ST
-
-
-typedef struct
-{
- ICompressProgress vt;
- CMtProgress *mtProgress;
- UInt64 inSize;
- UInt64 outSize;
-} CMtProgressThunk;
-
-void MtProgressThunk_CreateVTable(CMtProgressThunk *p);
-
-#define MtProgressThunk_Init(p) { (p)->inSize = 0; (p)->outSize = 0; }
-
-
-struct _CMtCoder;
-
-
-typedef struct
-{
- struct _CMtCoder *mtCoder;
- unsigned index;
- int stop;
- Byte *inBuf;
-
- CAutoResetEvent startEvent;
- CThread thread;
-} CMtCoderThread;
-
-
-typedef struct
-{
- SRes (*Code)(void *p, unsigned coderIndex, unsigned outBufIndex,
- const Byte *src, size_t srcSize, int finished);
- SRes (*Write)(void *p, unsigned outBufIndex);
-} IMtCoderCallback2;
-
-
-typedef struct
-{
- SRes res;
- unsigned bufIndex;
- BoolInt finished;
-} CMtCoderBlock;
-
-
-typedef struct _CMtCoder
-{
- /* input variables */
-
- size_t blockSize; /* size of input block */
- unsigned numThreadsMax;
- UInt64 expectedDataSize;
-
- ISeqInStream *inStream;
- const Byte *inData;
- size_t inDataSize;
-
- ICompressProgress *progress;
- ISzAllocPtr allocBig;
-
- IMtCoderCallback2 *mtCallback;
- void *mtCallbackObject;
-
-
- /* internal variables */
-
- size_t allocatedBufsSize;
-
- CAutoResetEvent readEvent;
- CSemaphore blocksSemaphore;
-
- BoolInt stopReading;
- SRes readRes;
-
- #ifdef MTCODER__USE_WRITE_THREAD
- CAutoResetEvent writeEvents[MTCODER__BLOCKS_MAX];
- #else
- CAutoResetEvent finishedEvent;
- SRes writeRes;
- unsigned writeIndex;
- Byte ReadyBlocks[MTCODER__BLOCKS_MAX];
- LONG numFinishedThreads;
- #endif
-
- unsigned numStartedThreadsLimit;
- unsigned numStartedThreads;
-
- unsigned numBlocksMax;
- unsigned blockIndex;
- UInt64 readProcessed;
-
- CCriticalSection cs;
-
- unsigned freeBlockHead;
- unsigned freeBlockList[MTCODER__BLOCKS_MAX];
-
- CMtProgress mtProgress;
- CMtCoderBlock blocks[MTCODER__BLOCKS_MAX];
- CMtCoderThread threads[MTCODER__THREADS_MAX];
-} CMtCoder;
-
-
-void MtCoder_Construct(CMtCoder *p);
-void MtCoder_Destruct(CMtCoder *p);
-SRes MtCoder_Code(CMtCoder *p);
-
-
-#endif
-
-
-EXTERN_C_END
-
-#endif
+/* MtCoder.h -- Multi-thread Coder
+2018-07-04 : Igor Pavlov : Public domain */
+
+#ifndef __MT_CODER_H
+#define __MT_CODER_H
+
+#include "MtDec.h"
+
+EXTERN_C_BEGIN
+
+/*
+ if ( defined MTCODER__USE_WRITE_THREAD) : main thread writes all data blocks to output stream
+ if (not defined MTCODER__USE_WRITE_THREAD) : any coder thread can write data blocks to output stream
+*/
+/* #define MTCODER__USE_WRITE_THREAD */
+
+#ifndef _7ZIP_ST
+ #define MTCODER__GET_NUM_BLOCKS_FROM_THREADS(numThreads) ((numThreads) + (numThreads) / 8 + 1)
+ #define MTCODER__THREADS_MAX 64
+ #define MTCODER__BLOCKS_MAX (MTCODER__GET_NUM_BLOCKS_FROM_THREADS(MTCODER__THREADS_MAX) + 3)
+#else
+ #define MTCODER__THREADS_MAX 1
+ #define MTCODER__BLOCKS_MAX 1
+#endif
+
+
+#ifndef _7ZIP_ST
+
+
+typedef struct
+{
+ ICompressProgress vt;
+ CMtProgress *mtProgress;
+ UInt64 inSize;
+ UInt64 outSize;
+} CMtProgressThunk;
+
+void MtProgressThunk_CreateVTable(CMtProgressThunk *p);
+
+#define MtProgressThunk_Init(p) { (p)->inSize = 0; (p)->outSize = 0; }
+
+
+struct _CMtCoder;
+
+
+typedef struct
+{
+ struct _CMtCoder *mtCoder;
+ unsigned index;
+ int stop;
+ Byte *inBuf;
+
+ CAutoResetEvent startEvent;
+ CThread thread;
+} CMtCoderThread;
+
+
+typedef struct
+{
+ SRes (*Code)(void *p, unsigned coderIndex, unsigned outBufIndex,
+ const Byte *src, size_t srcSize, int finished);
+ SRes (*Write)(void *p, unsigned outBufIndex);
+} IMtCoderCallback2;
+
+
+typedef struct
+{
+ SRes res;
+ unsigned bufIndex;
+ BoolInt finished;
+} CMtCoderBlock;
+
+
+typedef struct _CMtCoder
+{
+ /* input variables */
+
+ size_t blockSize; /* size of input block */
+ unsigned numThreadsMax;
+ UInt64 expectedDataSize;
+
+ ISeqInStream *inStream;
+ const Byte *inData;
+ size_t inDataSize;
+
+ ICompressProgress *progress;
+ ISzAllocPtr allocBig;
+
+ IMtCoderCallback2 *mtCallback;
+ void *mtCallbackObject;
+
+
+ /* internal variables */
+
+ size_t allocatedBufsSize;
+
+ CAutoResetEvent readEvent;
+ CSemaphore blocksSemaphore;
+
+ BoolInt stopReading;
+ SRes readRes;
+
+ #ifdef MTCODER__USE_WRITE_THREAD
+ CAutoResetEvent writeEvents[MTCODER__BLOCKS_MAX];
+ #else
+ CAutoResetEvent finishedEvent;
+ SRes writeRes;
+ unsigned writeIndex;
+ Byte ReadyBlocks[MTCODER__BLOCKS_MAX];
+ LONG numFinishedThreads;
+ #endif
+
+ unsigned numStartedThreadsLimit;
+ unsigned numStartedThreads;
+
+ unsigned numBlocksMax;
+ unsigned blockIndex;
+ UInt64 readProcessed;
+
+ CCriticalSection cs;
+
+ unsigned freeBlockHead;
+ unsigned freeBlockList[MTCODER__BLOCKS_MAX];
+
+ CMtProgress mtProgress;
+ CMtCoderBlock blocks[MTCODER__BLOCKS_MAX];
+ CMtCoderThread threads[MTCODER__THREADS_MAX];
+} CMtCoder;
+
+
+void MtCoder_Construct(CMtCoder *p);
+void MtCoder_Destruct(CMtCoder *p);
+SRes MtCoder_Code(CMtCoder *p);
+
+
+#endif
+
+
+EXTERN_C_END
+
+#endif
diff --git a/contrib/libs/lzmasdk/MtDec.h b/contrib/libs/lzmasdk/MtDec.h
index 78154c8b67..9b57766724 100644
--- a/contrib/libs/lzmasdk/MtDec.h
+++ b/contrib/libs/lzmasdk/MtDec.h
@@ -1,201 +1,201 @@
-/* MtDec.h -- Multi-thread Decoder
-2018-07-04 : Igor Pavlov : Public domain */
-
-#ifndef __MT_DEC_H
-#define __MT_DEC_H
-
-#include "7zTypes.h"
-
-#ifndef _7ZIP_ST
-#include "Threads.h"
-#endif
-
-EXTERN_C_BEGIN
-
-#ifndef _7ZIP_ST
-
-#ifndef _7ZIP_ST
- #define MTDEC__THREADS_MAX 32
-#else
- #define MTDEC__THREADS_MAX 1
-#endif
-
-
-typedef struct
-{
- ICompressProgress *progress;
- SRes res;
- UInt64 totalInSize;
- UInt64 totalOutSize;
- CCriticalSection cs;
-} CMtProgress;
-
-void MtProgress_Init(CMtProgress *p, ICompressProgress *progress);
-SRes MtProgress_Progress_ST(CMtProgress *p);
-SRes MtProgress_ProgressAdd(CMtProgress *p, UInt64 inSize, UInt64 outSize);
-SRes MtProgress_GetError(CMtProgress *p);
-void MtProgress_SetError(CMtProgress *p, SRes res);
-
-struct _CMtDec;
-
-typedef struct
-{
- struct _CMtDec *mtDec;
- unsigned index;
- void *inBuf;
-
- size_t inDataSize_Start; // size of input data in start block
- UInt64 inDataSize; // total size of input data in all blocks
-
- CThread thread;
- CAutoResetEvent canRead;
- CAutoResetEvent canWrite;
- void *allocaPtr;
-} CMtDecThread;
-
-void MtDecThread_FreeInBufs(CMtDecThread *t);
-
-
-typedef enum
-{
- MTDEC_PARSE_CONTINUE, // continue this block with more input data
- MTDEC_PARSE_OVERFLOW, // MT buffers overflow, need switch to single-thread
- MTDEC_PARSE_NEW, // new block
- MTDEC_PARSE_END // end of block threading. But we still can return to threading after Write(&needContinue)
-} EMtDecParseState;
-
-typedef struct
-{
- // in
- int startCall;
- const Byte *src;
- size_t srcSize;
- // in : (srcSize == 0) is allowed
- // out : it's allowed to return less that actually was used ?
- int srcFinished;
-
- // out
- EMtDecParseState state;
- BoolInt canCreateNewThread;
- UInt64 outPos; // check it (size_t)
-} CMtDecCallbackInfo;
-
-
-typedef struct
-{
- void (*Parse)(void *p, unsigned coderIndex, CMtDecCallbackInfo *ci);
-
- // PreCode() and Code():
- // (SRes_return_result != SZ_OK) means stop decoding, no need another blocks
- SRes (*PreCode)(void *p, unsigned coderIndex);
- SRes (*Code)(void *p, unsigned coderIndex,
- const Byte *src, size_t srcSize, int srcFinished,
- UInt64 *inCodePos, UInt64 *outCodePos, int *stop);
- // stop - means stop another Code calls
-
-
- /* Write() must be called, if Parse() was called
- set (needWrite) if
- {
- && (was not interrupted by progress)
- && (was not interrupted in previous block)
- }
-
- out:
- if (*needContinue), decoder still need to continue decoding with new iteration,
- even after MTDEC_PARSE_END
- if (*canRecode), we didn't flush current block data, so we still can decode current block later.
- */
- SRes (*Write)(void *p, unsigned coderIndex,
- BoolInt needWriteToStream,
- const Byte *src, size_t srcSize,
- // int srcFinished,
- BoolInt *needContinue,
- BoolInt *canRecode);
-} IMtDecCallback;
-
-
-
-typedef struct _CMtDec
-{
- /* input variables */
-
- size_t inBufSize; /* size of input block */
- unsigned numThreadsMax;
- // size_t inBlockMax;
- unsigned numThreadsMax_2;
-
- ISeqInStream *inStream;
- // const Byte *inData;
- // size_t inDataSize;
-
- ICompressProgress *progress;
- ISzAllocPtr alloc;
-
- IMtDecCallback *mtCallback;
- void *mtCallbackObject;
-
-
- /* internal variables */
-
- size_t allocatedBufsSize;
-
- BoolInt exitThread;
- WRes exitThreadWRes;
-
- UInt64 blockIndex;
- BoolInt isAllocError;
- BoolInt overflow;
- SRes threadingErrorSRes;
-
- BoolInt needContinue;
-
- // CAutoResetEvent finishedEvent;
-
- SRes readRes;
- SRes codeRes;
-
- BoolInt wasInterrupted;
-
- unsigned numStartedThreads_Limit;
- unsigned numStartedThreads;
-
- Byte *crossBlock;
- size_t crossStart;
- size_t crossEnd;
- UInt64 readProcessed;
- BoolInt readWasFinished;
- UInt64 inProcessed;
-
- unsigned filledThreadStart;
- unsigned numFilledThreads;
-
- #ifndef _7ZIP_ST
- BoolInt needInterrupt;
- UInt64 interruptIndex;
- CMtProgress mtProgress;
- CMtDecThread threads[MTDEC__THREADS_MAX];
- #endif
-} CMtDec;
-
-
-void MtDec_Construct(CMtDec *p);
-void MtDec_Destruct(CMtDec *p);
-
-/*
-MtDec_Code() returns:
- SZ_OK - in most cases
- MY_SRes_HRESULT_FROM_WRes(WRes_error) - in case of unexpected error in threading function
-*/
-
-SRes MtDec_Code(CMtDec *p);
-Byte *MtDec_GetCrossBuff(CMtDec *p);
-
-int MtDec_PrepareRead(CMtDec *p);
-const Byte *MtDec_Read(CMtDec *p, size_t *inLim);
-
-#endif
-
-EXTERN_C_END
-
-#endif
+/* MtDec.h -- Multi-thread Decoder
+2018-07-04 : Igor Pavlov : Public domain */
+
+#ifndef __MT_DEC_H
+#define __MT_DEC_H
+
+#include "7zTypes.h"
+
+#ifndef _7ZIP_ST
+#include "Threads.h"
+#endif
+
+EXTERN_C_BEGIN
+
+#ifndef _7ZIP_ST
+
+#ifndef _7ZIP_ST
+ #define MTDEC__THREADS_MAX 32
+#else
+ #define MTDEC__THREADS_MAX 1
+#endif
+
+
+typedef struct
+{
+ ICompressProgress *progress;
+ SRes res;
+ UInt64 totalInSize;
+ UInt64 totalOutSize;
+ CCriticalSection cs;
+} CMtProgress;
+
+void MtProgress_Init(CMtProgress *p, ICompressProgress *progress);
+SRes MtProgress_Progress_ST(CMtProgress *p);
+SRes MtProgress_ProgressAdd(CMtProgress *p, UInt64 inSize, UInt64 outSize);
+SRes MtProgress_GetError(CMtProgress *p);
+void MtProgress_SetError(CMtProgress *p, SRes res);
+
+struct _CMtDec;
+
+typedef struct
+{
+ struct _CMtDec *mtDec;
+ unsigned index;
+ void *inBuf;
+
+ size_t inDataSize_Start; // size of input data in start block
+ UInt64 inDataSize; // total size of input data in all blocks
+
+ CThread thread;
+ CAutoResetEvent canRead;
+ CAutoResetEvent canWrite;
+ void *allocaPtr;
+} CMtDecThread;
+
+void MtDecThread_FreeInBufs(CMtDecThread *t);
+
+
+typedef enum
+{
+ MTDEC_PARSE_CONTINUE, // continue this block with more input data
+ MTDEC_PARSE_OVERFLOW, // MT buffers overflow, need switch to single-thread
+ MTDEC_PARSE_NEW, // new block
+ MTDEC_PARSE_END // end of block threading. But we still can return to threading after Write(&needContinue)
+} EMtDecParseState;
+
+typedef struct
+{
+ // in
+ int startCall;
+ const Byte *src;
+ size_t srcSize;
+ // in : (srcSize == 0) is allowed
+ // out : it's allowed to return less that actually was used ?
+ int srcFinished;
+
+ // out
+ EMtDecParseState state;
+ BoolInt canCreateNewThread;
+ UInt64 outPos; // check it (size_t)
+} CMtDecCallbackInfo;
+
+
+typedef struct
+{
+ void (*Parse)(void *p, unsigned coderIndex, CMtDecCallbackInfo *ci);
+
+ // PreCode() and Code():
+ // (SRes_return_result != SZ_OK) means stop decoding, no need another blocks
+ SRes (*PreCode)(void *p, unsigned coderIndex);
+ SRes (*Code)(void *p, unsigned coderIndex,
+ const Byte *src, size_t srcSize, int srcFinished,
+ UInt64 *inCodePos, UInt64 *outCodePos, int *stop);
+ // stop - means stop another Code calls
+
+
+ /* Write() must be called, if Parse() was called
+ set (needWrite) if
+ {
+ && (was not interrupted by progress)
+ && (was not interrupted in previous block)
+ }
+
+ out:
+ if (*needContinue), decoder still need to continue decoding with new iteration,
+ even after MTDEC_PARSE_END
+ if (*canRecode), we didn't flush current block data, so we still can decode current block later.
+ */
+ SRes (*Write)(void *p, unsigned coderIndex,
+ BoolInt needWriteToStream,
+ const Byte *src, size_t srcSize,
+ // int srcFinished,
+ BoolInt *needContinue,
+ BoolInt *canRecode);
+} IMtDecCallback;
+
+
+
+typedef struct _CMtDec
+{
+ /* input variables */
+
+ size_t inBufSize; /* size of input block */
+ unsigned numThreadsMax;
+ // size_t inBlockMax;
+ unsigned numThreadsMax_2;
+
+ ISeqInStream *inStream;
+ // const Byte *inData;
+ // size_t inDataSize;
+
+ ICompressProgress *progress;
+ ISzAllocPtr alloc;
+
+ IMtDecCallback *mtCallback;
+ void *mtCallbackObject;
+
+
+ /* internal variables */
+
+ size_t allocatedBufsSize;
+
+ BoolInt exitThread;
+ WRes exitThreadWRes;
+
+ UInt64 blockIndex;
+ BoolInt isAllocError;
+ BoolInt overflow;
+ SRes threadingErrorSRes;
+
+ BoolInt needContinue;
+
+ // CAutoResetEvent finishedEvent;
+
+ SRes readRes;
+ SRes codeRes;
+
+ BoolInt wasInterrupted;
+
+ unsigned numStartedThreads_Limit;
+ unsigned numStartedThreads;
+
+ Byte *crossBlock;
+ size_t crossStart;
+ size_t crossEnd;
+ UInt64 readProcessed;
+ BoolInt readWasFinished;
+ UInt64 inProcessed;
+
+ unsigned filledThreadStart;
+ unsigned numFilledThreads;
+
+ #ifndef _7ZIP_ST
+ BoolInt needInterrupt;
+ UInt64 interruptIndex;
+ CMtProgress mtProgress;
+ CMtDecThread threads[MTDEC__THREADS_MAX];
+ #endif
+} CMtDec;
+
+
+void MtDec_Construct(CMtDec *p);
+void MtDec_Destruct(CMtDec *p);
+
+/*
+MtDec_Code() returns:
+ SZ_OK - in most cases
+ MY_SRes_HRESULT_FROM_WRes(WRes_error) - in case of unexpected error in threading function
+*/
+
+SRes MtDec_Code(CMtDec *p);
+Byte *MtDec_GetCrossBuff(CMtDec *p);
+
+int MtDec_PrepareRead(CMtDec *p);
+const Byte *MtDec_Read(CMtDec *p, size_t *inLim);
+
+#endif
+
+EXTERN_C_END
+
+#endif
diff --git a/contrib/libs/lzmasdk/RotateDefs.h b/contrib/libs/lzmasdk/RotateDefs.h
index 129199f232..8f01d1a6c5 100644
--- a/contrib/libs/lzmasdk/RotateDefs.h
+++ b/contrib/libs/lzmasdk/RotateDefs.h
@@ -1,30 +1,30 @@
-/* RotateDefs.h -- Rotate functions
-2015-03-25 : Igor Pavlov : Public domain */
-
-#ifndef __ROTATE_DEFS_H
-#define __ROTATE_DEFS_H
-
-#ifdef _MSC_VER
-
-#include <stdlib.h>
-
-/* don't use _rotl with MINGW. It can insert slow call to function. */
-
-/* #if (_MSC_VER >= 1200) */
-#pragma intrinsic(_rotl)
-#pragma intrinsic(_rotr)
-/* #endif */
-
-#define rotlFixed(x, n) _rotl((x), (n))
-#define rotrFixed(x, n) _rotr((x), (n))
-
-#else
-
-/* new compilers can translate these macros to fast commands. */
-
-#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
-#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
-
-#endif
-
-#endif
+/* RotateDefs.h -- Rotate functions
+2015-03-25 : Igor Pavlov : Public domain */
+
+#ifndef __ROTATE_DEFS_H
+#define __ROTATE_DEFS_H
+
+#ifdef _MSC_VER
+
+#include <stdlib.h>
+
+/* don't use _rotl with MINGW. It can insert slow call to function. */
+
+/* #if (_MSC_VER >= 1200) */
+#pragma intrinsic(_rotl)
+#pragma intrinsic(_rotr)
+/* #endif */
+
+#define rotlFixed(x, n) _rotl((x), (n))
+#define rotrFixed(x, n) _rotr((x), (n))
+
+#else
+
+/* new compilers can translate these macros to fast commands. */
+
+#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
+
+#endif
+
+#endif
diff --git a/contrib/libs/lzmasdk/Sha256.c b/contrib/libs/lzmasdk/Sha256.c
index 56daa25d5f..04b688c6bd 100644
--- a/contrib/libs/lzmasdk/Sha256.c
+++ b/contrib/libs/lzmasdk/Sha256.c
@@ -1,248 +1,248 @@
-/* Crypto/Sha256.c -- SHA-256 Hash
-2017-04-03 : Igor Pavlov : Public domain
-This code is based on public domain code from Wei Dai's Crypto++ library. */
-
-#include "Precomp.h"
-
-#include <string.h>
-
-#include "CpuArch.h"
-#include "RotateDefs.h"
-#include "Sha256.h"
-
-/* define it for speed optimization */
-#ifndef _SFX
-#define _SHA256_UNROLL
-#define _SHA256_UNROLL2
-#endif
-
-/* #define _SHA256_UNROLL2 */
-
-void Sha256_Init(CSha256 *p)
-{
- p->state[0] = 0x6a09e667;
- p->state[1] = 0xbb67ae85;
- p->state[2] = 0x3c6ef372;
- p->state[3] = 0xa54ff53a;
- p->state[4] = 0x510e527f;
- p->state[5] = 0x9b05688c;
- p->state[6] = 0x1f83d9ab;
- p->state[7] = 0x5be0cd19;
- p->count = 0;
-}
-
-#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22))
-#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25))
-#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3))
-#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10))
-
-#define blk0(i) (W[i])
-#define blk2(i) (W[i] += s1(W[((i)-2)&15]) + W[((i)-7)&15] + s0(W[((i)-15)&15]))
-
-#define Ch(x,y,z) (z^(x&(y^z)))
-#define Maj(x,y,z) ((x&y)|(z&(x|y)))
-
-#ifdef _SHA256_UNROLL2
-
-#define R(a,b,c,d,e,f,g,h, i) \
- h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + (j ? blk2(i) : blk0(i)); \
- d += h; \
- h += S0(a) + Maj(a, b, c)
-
-#define RX_8(i) \
- R(a,b,c,d,e,f,g,h, i); \
- R(h,a,b,c,d,e,f,g, i+1); \
- R(g,h,a,b,c,d,e,f, i+2); \
- R(f,g,h,a,b,c,d,e, i+3); \
- R(e,f,g,h,a,b,c,d, i+4); \
- R(d,e,f,g,h,a,b,c, i+5); \
- R(c,d,e,f,g,h,a,b, i+6); \
- R(b,c,d,e,f,g,h,a, i+7)
-
-#define RX_16 RX_8(0); RX_8(8);
-
-#else
-
-#define a(i) T[(0-(i))&7]
-#define b(i) T[(1-(i))&7]
-#define c(i) T[(2-(i))&7]
-#define d(i) T[(3-(i))&7]
-#define e(i) T[(4-(i))&7]
-#define f(i) T[(5-(i))&7]
-#define g(i) T[(6-(i))&7]
-#define h(i) T[(7-(i))&7]
-
-#define R(i) \
- h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[(i)+(size_t)(j)] + (j ? blk2(i) : blk0(i)); \
- d(i) += h(i); \
- h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) \
-
-#ifdef _SHA256_UNROLL
-
-#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7);
-#define RX_16 RX_8(0); RX_8(8);
-
-#else
-
-#define RX_16 unsigned i; for (i = 0; i < 16; i++) { R(i); }
-
-#endif
-
-#endif
-
-static const UInt32 K[64] = {
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
- 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
- 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
- 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
- 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
- 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
- 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
- 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
- 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-};
-
-static void Sha256_WriteByteBlock(CSha256 *p)
-{
- UInt32 W[16];
- unsigned j;
- UInt32 *state;
-
- #ifdef _SHA256_UNROLL2
- UInt32 a,b,c,d,e,f,g,h;
- #else
- UInt32 T[8];
- #endif
-
- for (j = 0; j < 16; j += 4)
- {
- const Byte *ccc = p->buffer + j * 4;
- W[j ] = GetBe32(ccc);
- W[j + 1] = GetBe32(ccc + 4);
- W[j + 2] = GetBe32(ccc + 8);
- W[j + 3] = GetBe32(ccc + 12);
- }
-
- state = p->state;
-
- #ifdef _SHA256_UNROLL2
- a = state[0];
- b = state[1];
- c = state[2];
- d = state[3];
- e = state[4];
- f = state[5];
- g = state[6];
- h = state[7];
- #else
- for (j = 0; j < 8; j++)
- T[j] = state[j];
- #endif
-
- for (j = 0; j < 64; j += 16)
- {
- RX_16
- }
-
- #ifdef _SHA256_UNROLL2
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
- state[4] += e;
- state[5] += f;
- state[6] += g;
- state[7] += h;
- #else
- for (j = 0; j < 8; j++)
- state[j] += T[j];
- #endif
-
- /* Wipe variables */
- /* memset(W, 0, sizeof(W)); */
- /* memset(T, 0, sizeof(T)); */
-}
-
-#undef S0
-#undef S1
-#undef s0
-#undef s1
-
-void Sha256_Update(CSha256 *p, const Byte *data, size_t size)
-{
- if (size == 0)
- return;
-
- {
- unsigned pos = (unsigned)p->count & 0x3F;
- unsigned num;
-
- p->count += size;
-
- num = 64 - pos;
- if (num > size)
- {
- memcpy(p->buffer + pos, data, size);
- return;
- }
-
- size -= num;
- memcpy(p->buffer + pos, data, num);
- data += num;
- }
-
- for (;;)
- {
- Sha256_WriteByteBlock(p);
- if (size < 64)
- break;
- size -= 64;
- memcpy(p->buffer, data, 64);
- data += 64;
- }
-
- if (size != 0)
- memcpy(p->buffer, data, size);
-}
-
-void Sha256_Final(CSha256 *p, Byte *digest)
-{
- unsigned pos = (unsigned)p->count & 0x3F;
- unsigned i;
-
- p->buffer[pos++] = 0x80;
-
- while (pos != (64 - 8))
- {
- pos &= 0x3F;
- if (pos == 0)
- Sha256_WriteByteBlock(p);
- p->buffer[pos++] = 0;
- }
-
- {
- UInt64 numBits = (p->count << 3);
- SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32));
- SetBe32(p->buffer + 64 - 4, (UInt32)(numBits));
- }
-
- Sha256_WriteByteBlock(p);
-
- for (i = 0; i < 8; i += 2)
- {
- UInt32 v0 = p->state[i];
- UInt32 v1 = p->state[i + 1];
- SetBe32(digest , v0);
- SetBe32(digest + 4, v1);
- digest += 8;
- }
-
- Sha256_Init(p);
-}
+/* Crypto/Sha256.c -- SHA-256 Hash
+2017-04-03 : Igor Pavlov : Public domain
+This code is based on public domain code from Wei Dai's Crypto++ library. */
+
+#include "Precomp.h"
+
+#include <string.h>
+
+#include "CpuArch.h"
+#include "RotateDefs.h"
+#include "Sha256.h"
+
+/* define it for speed optimization */
+#ifndef _SFX
+#define _SHA256_UNROLL
+#define _SHA256_UNROLL2
+#endif
+
+/* #define _SHA256_UNROLL2 */
+
+void Sha256_Init(CSha256 *p)
+{
+ p->state[0] = 0x6a09e667;
+ p->state[1] = 0xbb67ae85;
+ p->state[2] = 0x3c6ef372;
+ p->state[3] = 0xa54ff53a;
+ p->state[4] = 0x510e527f;
+ p->state[5] = 0x9b05688c;
+ p->state[6] = 0x1f83d9ab;
+ p->state[7] = 0x5be0cd19;
+ p->count = 0;
+}
+
+#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22))
+#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25))
+#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3))
+#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10))
+
+#define blk0(i) (W[i])
+#define blk2(i) (W[i] += s1(W[((i)-2)&15]) + W[((i)-7)&15] + s0(W[((i)-15)&15]))
+
+#define Ch(x,y,z) (z^(x&(y^z)))
+#define Maj(x,y,z) ((x&y)|(z&(x|y)))
+
+#ifdef _SHA256_UNROLL2
+
+#define R(a,b,c,d,e,f,g,h, i) \
+ h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + (j ? blk2(i) : blk0(i)); \
+ d += h; \
+ h += S0(a) + Maj(a, b, c)
+
+#define RX_8(i) \
+ R(a,b,c,d,e,f,g,h, i); \
+ R(h,a,b,c,d,e,f,g, i+1); \
+ R(g,h,a,b,c,d,e,f, i+2); \
+ R(f,g,h,a,b,c,d,e, i+3); \
+ R(e,f,g,h,a,b,c,d, i+4); \
+ R(d,e,f,g,h,a,b,c, i+5); \
+ R(c,d,e,f,g,h,a,b, i+6); \
+ R(b,c,d,e,f,g,h,a, i+7)
+
+#define RX_16 RX_8(0); RX_8(8);
+
+#else
+
+#define a(i) T[(0-(i))&7]
+#define b(i) T[(1-(i))&7]
+#define c(i) T[(2-(i))&7]
+#define d(i) T[(3-(i))&7]
+#define e(i) T[(4-(i))&7]
+#define f(i) T[(5-(i))&7]
+#define g(i) T[(6-(i))&7]
+#define h(i) T[(7-(i))&7]
+
+#define R(i) \
+ h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[(i)+(size_t)(j)] + (j ? blk2(i) : blk0(i)); \
+ d(i) += h(i); \
+ h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) \
+
+#ifdef _SHA256_UNROLL
+
+#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7);
+#define RX_16 RX_8(0); RX_8(8);
+
+#else
+
+#define RX_16 unsigned i; for (i = 0; i < 16; i++) { R(i); }
+
+#endif
+
+#endif
+
+static const UInt32 K[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+static void Sha256_WriteByteBlock(CSha256 *p)
+{
+ UInt32 W[16];
+ unsigned j;
+ UInt32 *state;
+
+ #ifdef _SHA256_UNROLL2
+ UInt32 a,b,c,d,e,f,g,h;
+ #else
+ UInt32 T[8];
+ #endif
+
+ for (j = 0; j < 16; j += 4)
+ {
+ const Byte *ccc = p->buffer + j * 4;
+ W[j ] = GetBe32(ccc);
+ W[j + 1] = GetBe32(ccc + 4);
+ W[j + 2] = GetBe32(ccc + 8);
+ W[j + 3] = GetBe32(ccc + 12);
+ }
+
+ state = p->state;
+
+ #ifdef _SHA256_UNROLL2
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ f = state[5];
+ g = state[6];
+ h = state[7];
+ #else
+ for (j = 0; j < 8; j++)
+ T[j] = state[j];
+ #endif
+
+ for (j = 0; j < 64; j += 16)
+ {
+ RX_16
+ }
+
+ #ifdef _SHA256_UNROLL2
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ state[5] += f;
+ state[6] += g;
+ state[7] += h;
+ #else
+ for (j = 0; j < 8; j++)
+ state[j] += T[j];
+ #endif
+
+ /* Wipe variables */
+ /* memset(W, 0, sizeof(W)); */
+ /* memset(T, 0, sizeof(T)); */
+}
+
+#undef S0
+#undef S1
+#undef s0
+#undef s1
+
+void Sha256_Update(CSha256 *p, const Byte *data, size_t size)
+{
+ if (size == 0)
+ return;
+
+ {
+ unsigned pos = (unsigned)p->count & 0x3F;
+ unsigned num;
+
+ p->count += size;
+
+ num = 64 - pos;
+ if (num > size)
+ {
+ memcpy(p->buffer + pos, data, size);
+ return;
+ }
+
+ size -= num;
+ memcpy(p->buffer + pos, data, num);
+ data += num;
+ }
+
+ for (;;)
+ {
+ Sha256_WriteByteBlock(p);
+ if (size < 64)
+ break;
+ size -= 64;
+ memcpy(p->buffer, data, 64);
+ data += 64;
+ }
+
+ if (size != 0)
+ memcpy(p->buffer, data, size);
+}
+
+void Sha256_Final(CSha256 *p, Byte *digest)
+{
+ unsigned pos = (unsigned)p->count & 0x3F;
+ unsigned i;
+
+ p->buffer[pos++] = 0x80;
+
+ while (pos != (64 - 8))
+ {
+ pos &= 0x3F;
+ if (pos == 0)
+ Sha256_WriteByteBlock(p);
+ p->buffer[pos++] = 0;
+ }
+
+ {
+ UInt64 numBits = (p->count << 3);
+ SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32));
+ SetBe32(p->buffer + 64 - 4, (UInt32)(numBits));
+ }
+
+ Sha256_WriteByteBlock(p);
+
+ for (i = 0; i < 8; i += 2)
+ {
+ UInt32 v0 = p->state[i];
+ UInt32 v1 = p->state[i + 1];
+ SetBe32(digest , v0);
+ SetBe32(digest + 4, v1);
+ digest += 8;
+ }
+
+ Sha256_Init(p);
+}
diff --git a/contrib/libs/lzmasdk/Sha256.h b/contrib/libs/lzmasdk/Sha256.h
index b8ee495207..3f455dbc0d 100644
--- a/contrib/libs/lzmasdk/Sha256.h
+++ b/contrib/libs/lzmasdk/Sha256.h
@@ -1,26 +1,26 @@
-/* Sha256.h -- SHA-256 Hash
-2013-01-18 : Igor Pavlov : Public domain */
-
-#ifndef __CRYPTO_SHA256_H
-#define __CRYPTO_SHA256_H
-
-#include "7zTypes.h"
-
-EXTERN_C_BEGIN
-
-#define SHA256_DIGEST_SIZE 32
-
-typedef struct
-{
- UInt32 state[8];
- UInt64 count;
- Byte buffer[64];
-} CSha256;
-
-void Sha256_Init(CSha256 *p);
-void Sha256_Update(CSha256 *p, const Byte *data, size_t size);
-void Sha256_Final(CSha256 *p, Byte *digest);
-
-EXTERN_C_END
-
-#endif
+/* Sha256.h -- SHA-256 Hash
+2013-01-18 : Igor Pavlov : Public domain */
+
+#ifndef __CRYPTO_SHA256_H
+#define __CRYPTO_SHA256_H
+
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
+#define SHA256_DIGEST_SIZE 32
+
+typedef struct
+{
+ UInt32 state[8];
+ UInt64 count;
+ Byte buffer[64];
+} CSha256;
+
+void Sha256_Init(CSha256 *p);
+void Sha256_Update(CSha256 *p, const Byte *data, size_t size);
+void Sha256_Final(CSha256 *p, Byte *digest);
+
+EXTERN_C_END
+
+#endif
diff --git a/contrib/libs/lzmasdk/Threads.h b/contrib/libs/lzmasdk/Threads.h
index 17a1a5a550..e53ace4356 100644
--- a/contrib/libs/lzmasdk/Threads.h
+++ b/contrib/libs/lzmasdk/Threads.h
@@ -1,68 +1,68 @@
-/* Threads.h -- multithreading library
-2017-06-18 : Igor Pavlov : Public domain */
-
-#ifndef __7Z_THREADS_H
-#define __7Z_THREADS_H
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-#include "7zTypes.h"
-
-EXTERN_C_BEGIN
-
-WRes HandlePtr_Close(HANDLE *h);
-WRes Handle_WaitObject(HANDLE h);
-
-typedef HANDLE CThread;
-#define Thread_Construct(p) *(p) = NULL
-#define Thread_WasCreated(p) (*(p) != NULL)
-#define Thread_Close(p) HandlePtr_Close(p)
-#define Thread_Wait(p) Handle_WaitObject(*(p))
-
-typedef
-#ifdef UNDER_CE
- DWORD
-#else
- unsigned
-#endif
- THREAD_FUNC_RET_TYPE;
-
-#define THREAD_FUNC_CALL_TYPE MY_STD_CALL
-#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
-typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *);
-WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param);
-
-typedef HANDLE CEvent;
-typedef CEvent CAutoResetEvent;
-typedef CEvent CManualResetEvent;
-#define Event_Construct(p) *(p) = NULL
-#define Event_IsCreated(p) (*(p) != NULL)
-#define Event_Close(p) HandlePtr_Close(p)
-#define Event_Wait(p) Handle_WaitObject(*(p))
-WRes Event_Set(CEvent *p);
-WRes Event_Reset(CEvent *p);
-WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled);
-WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p);
-WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled);
-WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p);
-
-typedef HANDLE CSemaphore;
-#define Semaphore_Construct(p) *(p) = NULL
-#define Semaphore_IsCreated(p) (*(p) != NULL)
-#define Semaphore_Close(p) HandlePtr_Close(p)
-#define Semaphore_Wait(p) Handle_WaitObject(*(p))
-WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);
-WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);
-WRes Semaphore_Release1(CSemaphore *p);
-
-typedef CRITICAL_SECTION CCriticalSection;
-WRes CriticalSection_Init(CCriticalSection *p);
-#define CriticalSection_Delete(p) DeleteCriticalSection(p)
-#define CriticalSection_Enter(p) EnterCriticalSection(p)
-#define CriticalSection_Leave(p) LeaveCriticalSection(p)
-
-EXTERN_C_END
-
-#endif
+/* Threads.h -- multithreading library
+2017-06-18 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_THREADS_H
+#define __7Z_THREADS_H
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
+WRes HandlePtr_Close(HANDLE *h);
+WRes Handle_WaitObject(HANDLE h);
+
+typedef HANDLE CThread;
+#define Thread_Construct(p) *(p) = NULL
+#define Thread_WasCreated(p) (*(p) != NULL)
+#define Thread_Close(p) HandlePtr_Close(p)
+#define Thread_Wait(p) Handle_WaitObject(*(p))
+
+typedef
+#ifdef UNDER_CE
+ DWORD
+#else
+ unsigned
+#endif
+ THREAD_FUNC_RET_TYPE;
+
+#define THREAD_FUNC_CALL_TYPE MY_STD_CALL
+#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
+typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *);
+WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param);
+
+typedef HANDLE CEvent;
+typedef CEvent CAutoResetEvent;
+typedef CEvent CManualResetEvent;
+#define Event_Construct(p) *(p) = NULL
+#define Event_IsCreated(p) (*(p) != NULL)
+#define Event_Close(p) HandlePtr_Close(p)
+#define Event_Wait(p) Handle_WaitObject(*(p))
+WRes Event_Set(CEvent *p);
+WRes Event_Reset(CEvent *p);
+WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled);
+WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p);
+WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled);
+WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p);
+
+typedef HANDLE CSemaphore;
+#define Semaphore_Construct(p) *(p) = NULL
+#define Semaphore_IsCreated(p) (*(p) != NULL)
+#define Semaphore_Close(p) HandlePtr_Close(p)
+#define Semaphore_Wait(p) Handle_WaitObject(*(p))
+WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);
+WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);
+WRes Semaphore_Release1(CSemaphore *p);
+
+typedef CRITICAL_SECTION CCriticalSection;
+WRes CriticalSection_Init(CCriticalSection *p);
+#define CriticalSection_Delete(p) DeleteCriticalSection(p)
+#define CriticalSection_Enter(p) EnterCriticalSection(p)
+#define CriticalSection_Leave(p) LeaveCriticalSection(p)
+
+EXTERN_C_END
+
+#endif
diff --git a/contrib/libs/lzmasdk/ya.make b/contrib/libs/lzmasdk/ya.make
index fd283a8089..db0a55788d 100644
--- a/contrib/libs/lzmasdk/ya.make
+++ b/contrib/libs/lzmasdk/ya.make
@@ -18,20 +18,20 @@ NO_UTIL()
SRCS(
7zStream.c
- Aes.c
- AesOpt.c
+ Aes.c
+ AesOpt.c
Alloc.c
- Bra.c
- Bra86.c
- BraIA64.c
- CpuArch.c
- LzFind.c
- Lzma2Dec.c
- Lzma2Enc.c
+ Bra.c
+ Bra86.c
+ BraIA64.c
+ CpuArch.c
+ LzFind.c
+ Lzma2Dec.c
+ Lzma2Enc.c
LzmaDec.c
LzmaEnc.c
LzmaLib.c
- Sha256.c
+ Sha256.c
)
END()
diff --git a/contrib/libs/nayuki_md5/ya.make b/contrib/libs/nayuki_md5/ya.make
index ad12cad0cb..15a6141c7a 100644
--- a/contrib/libs/nayuki_md5/ya.make
+++ b/contrib/libs/nayuki_md5/ya.make
@@ -4,10 +4,10 @@ LICENSE(MIT)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(2016)
-
-ORIGINAL_SOURCE(https://www.nayuki.io/page/fast-md5-hash-implementation-in-x86-assembly)
-
+VERSION(2016)
+
+ORIGINAL_SOURCE(https://www.nayuki.io/page/fast-md5-hash-implementation-in-x86-assembly)
+
OWNER(
pg
g:contrib
diff --git a/contrib/libs/protobuf/ya.make b/contrib/libs/protobuf/ya.make
index cae7ba7eb9..044e24badd 100644
--- a/contrib/libs/protobuf/ya.make
+++ b/contrib/libs/protobuf/ya.make
@@ -1,4 +1,4 @@
-# Generated by devtools/yamaker from nixpkgs 21.11.
+# Generated by devtools/yamaker from nixpkgs 21.11.
LIBRARY()
diff --git a/contrib/libs/python/Include/bytes_methods.h b/contrib/libs/python/Include/bytes_methods.h
index 65e30aa9a1..f74e146029 100644
--- a/contrib/libs/python/Include/bytes_methods.h
+++ b/contrib/libs/python/Include/bytes_methods.h
@@ -1,7 +1,7 @@
#pragma once
#ifdef USE_PYTHON3
-#error "No <bytes_methods.h> in Python3"
+#error "No <bytes_methods.h> in Python3"
#else
#include <contrib/tools/python/src/Include/bytes_methods.h>
#endif
diff --git a/contrib/libs/python/Include/context.h b/contrib/libs/python/Include/context.h
index e8121f90a4..61ed2c0dd1 100644
--- a/contrib/libs/python/Include/context.h
+++ b/contrib/libs/python/Include/context.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/context.h>
-#else
-#error "No <context.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/context.h>
+#else
+#error "No <context.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/abstract.h b/contrib/libs/python/Include/cpython/abstract.h
index c7e3a4f235..06fa02d641 100644
--- a/contrib/libs/python/Include/cpython/abstract.h
+++ b/contrib/libs/python/Include/cpython/abstract.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/abstract.h>
-#else
-#error "No <cpython/abstract.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/abstract.h>
+#else
+#error "No <cpython/abstract.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/bytearrayobject.h b/contrib/libs/python/Include/cpython/bytearrayobject.h
index 0acb4ce6d1..5ed47993c2 100644
--- a/contrib/libs/python/Include/cpython/bytearrayobject.h
+++ b/contrib/libs/python/Include/cpython/bytearrayobject.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/bytearrayobject.h>
-#else
-#error "No <cpython/bytearrayobject.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/bytearrayobject.h>
+#else
+#error "No <cpython/bytearrayobject.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/bytesobject.h b/contrib/libs/python/Include/cpython/bytesobject.h
index acb4f37b2f..d960c6a903 100644
--- a/contrib/libs/python/Include/cpython/bytesobject.h
+++ b/contrib/libs/python/Include/cpython/bytesobject.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/bytesobject.h>
-#else
-#error "No <cpython/bytesobject.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/bytesobject.h>
+#else
+#error "No <cpython/bytesobject.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/ceval.h b/contrib/libs/python/Include/cpython/ceval.h
index 402e9c5e79..dcefa8e58b 100644
--- a/contrib/libs/python/Include/cpython/ceval.h
+++ b/contrib/libs/python/Include/cpython/ceval.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/ceval.h>
-#else
-#error "No <cpython/ceval.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/ceval.h>
+#else
+#error "No <cpython/ceval.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/code.h b/contrib/libs/python/Include/cpython/code.h
index ed679b23f3..b652426858 100644
--- a/contrib/libs/python/Include/cpython/code.h
+++ b/contrib/libs/python/Include/cpython/code.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/code.h>
-#else
-#error "No <cpython/code.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/code.h>
+#else
+#error "No <cpython/code.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/dictobject.h b/contrib/libs/python/Include/cpython/dictobject.h
index 45f6897bc4..e5a4c02e71 100644
--- a/contrib/libs/python/Include/cpython/dictobject.h
+++ b/contrib/libs/python/Include/cpython/dictobject.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/dictobject.h>
-#else
-#error "No <cpython/dictobject.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/dictobject.h>
+#else
+#error "No <cpython/dictobject.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/fileobject.h b/contrib/libs/python/Include/cpython/fileobject.h
index ebb6e7bccf..de9bc96c48 100644
--- a/contrib/libs/python/Include/cpython/fileobject.h
+++ b/contrib/libs/python/Include/cpython/fileobject.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/fileobject.h>
-#else
-#error "No <cpython/fileobject.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/fileobject.h>
+#else
+#error "No <cpython/fileobject.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/fileutils.h b/contrib/libs/python/Include/cpython/fileutils.h
index 321ba5ae19..38d4c523e5 100644
--- a/contrib/libs/python/Include/cpython/fileutils.h
+++ b/contrib/libs/python/Include/cpython/fileutils.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/fileutils.h>
-#else
-#error "No <cpython/fileutils.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/fileutils.h>
+#else
+#error "No <cpython/fileutils.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/frameobject.h b/contrib/libs/python/Include/cpython/frameobject.h
index 0603377054..b681d4b1c9 100644
--- a/contrib/libs/python/Include/cpython/frameobject.h
+++ b/contrib/libs/python/Include/cpython/frameobject.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/frameobject.h>
-#else
-#error "No <cpython/frameobject.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/frameobject.h>
+#else
+#error "No <cpython/frameobject.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/import.h b/contrib/libs/python/Include/cpython/import.h
index 5775143e9f..149b0f716e 100644
--- a/contrib/libs/python/Include/cpython/import.h
+++ b/contrib/libs/python/Include/cpython/import.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/import.h>
-#else
-#error "No <cpython/import.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/import.h>
+#else
+#error "No <cpython/import.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/initconfig.h b/contrib/libs/python/Include/cpython/initconfig.h
index 43412713b0..a00b133147 100644
--- a/contrib/libs/python/Include/cpython/initconfig.h
+++ b/contrib/libs/python/Include/cpython/initconfig.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/initconfig.h>
-#else
-#error "No <cpython/initconfig.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/initconfig.h>
+#else
+#error "No <cpython/initconfig.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/interpreteridobject.h b/contrib/libs/python/Include/cpython/interpreteridobject.h
index f180113907..110dfc0899 100644
--- a/contrib/libs/python/Include/cpython/interpreteridobject.h
+++ b/contrib/libs/python/Include/cpython/interpreteridobject.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/interpreteridobject.h>
-#else
-#error "No <cpython/interpreteridobject.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/interpreteridobject.h>
+#else
+#error "No <cpython/interpreteridobject.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/listobject.h b/contrib/libs/python/Include/cpython/listobject.h
index 02ed8a8b88..f5edc4f307 100644
--- a/contrib/libs/python/Include/cpython/listobject.h
+++ b/contrib/libs/python/Include/cpython/listobject.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/listobject.h>
-#else
-#error "No <cpython/listobject.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/listobject.h>
+#else
+#error "No <cpython/listobject.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/methodobject.h b/contrib/libs/python/Include/cpython/methodobject.h
index ebea12d5e9..fbaba4bdc7 100644
--- a/contrib/libs/python/Include/cpython/methodobject.h
+++ b/contrib/libs/python/Include/cpython/methodobject.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/methodobject.h>
-#else
-#error "No <cpython/methodobject.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/methodobject.h>
+#else
+#error "No <cpython/methodobject.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/object.h b/contrib/libs/python/Include/cpython/object.h
index 8c0e00e09d..91204cfce4 100644
--- a/contrib/libs/python/Include/cpython/object.h
+++ b/contrib/libs/python/Include/cpython/object.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/object.h>
-#else
-#error "No <cpython/object.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/object.h>
+#else
+#error "No <cpython/object.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/objimpl.h b/contrib/libs/python/Include/cpython/objimpl.h
index db126e0c2f..a787c6f70e 100644
--- a/contrib/libs/python/Include/cpython/objimpl.h
+++ b/contrib/libs/python/Include/cpython/objimpl.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/objimpl.h>
-#else
-#error "No <cpython/objimpl.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/objimpl.h>
+#else
+#error "No <cpython/objimpl.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/pyerrors.h b/contrib/libs/python/Include/cpython/pyerrors.h
index 5c006b2c7f..6064161ac1 100644
--- a/contrib/libs/python/Include/cpython/pyerrors.h
+++ b/contrib/libs/python/Include/cpython/pyerrors.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/pyerrors.h>
-#else
-#error "No <cpython/pyerrors.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/pyerrors.h>
+#else
+#error "No <cpython/pyerrors.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/pylifecycle.h b/contrib/libs/python/Include/cpython/pylifecycle.h
index dc778caaff..099f148ef2 100644
--- a/contrib/libs/python/Include/cpython/pylifecycle.h
+++ b/contrib/libs/python/Include/cpython/pylifecycle.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/pylifecycle.h>
-#else
-#error "No <cpython/pylifecycle.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/pylifecycle.h>
+#else
+#error "No <cpython/pylifecycle.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/pymem.h b/contrib/libs/python/Include/cpython/pymem.h
index 3408da66a6..e3256925b6 100644
--- a/contrib/libs/python/Include/cpython/pymem.h
+++ b/contrib/libs/python/Include/cpython/pymem.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/pymem.h>
-#else
-#error "No <cpython/pymem.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/pymem.h>
+#else
+#error "No <cpython/pymem.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/pystate.h b/contrib/libs/python/Include/cpython/pystate.h
index 1224aabb34..c8e5cbc23b 100644
--- a/contrib/libs/python/Include/cpython/pystate.h
+++ b/contrib/libs/python/Include/cpython/pystate.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/pystate.h>
-#else
-#error "No <cpython/pystate.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/pystate.h>
+#else
+#error "No <cpython/pystate.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/sysmodule.h b/contrib/libs/python/Include/cpython/sysmodule.h
index 32e1723ce8..3e827d58a5 100644
--- a/contrib/libs/python/Include/cpython/sysmodule.h
+++ b/contrib/libs/python/Include/cpython/sysmodule.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/sysmodule.h>
-#else
-#error "No <cpython/sysmodule.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/sysmodule.h>
+#else
+#error "No <cpython/sysmodule.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/traceback.h b/contrib/libs/python/Include/cpython/traceback.h
index bd5c6c5b11..9b9e2dc9a5 100644
--- a/contrib/libs/python/Include/cpython/traceback.h
+++ b/contrib/libs/python/Include/cpython/traceback.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/traceback.h>
-#else
-#error "No <cpython/traceback.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/traceback.h>
+#else
+#error "No <cpython/traceback.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/tupleobject.h b/contrib/libs/python/Include/cpython/tupleobject.h
index 795ff03fc0..7bc25aaee2 100644
--- a/contrib/libs/python/Include/cpython/tupleobject.h
+++ b/contrib/libs/python/Include/cpython/tupleobject.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/tupleobject.h>
-#else
-#error "No <cpython/tupleobject.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/tupleobject.h>
+#else
+#error "No <cpython/tupleobject.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/cpython/unicodeobject.h b/contrib/libs/python/Include/cpython/unicodeobject.h
index fcbe1d6f31..260680d0ea 100644
--- a/contrib/libs/python/Include/cpython/unicodeobject.h
+++ b/contrib/libs/python/Include/cpython/unicodeobject.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/cpython/unicodeobject.h>
-#else
-#error "No <cpython/unicodeobject.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/cpython/unicodeobject.h>
+#else
+#error "No <cpython/unicodeobject.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/dtoa.h b/contrib/libs/python/Include/dtoa.h
index f827f3b9a8..d8c51a71f4 100644
--- a/contrib/libs/python/Include/dtoa.h
+++ b/contrib/libs/python/Include/dtoa.h
@@ -1,7 +1,7 @@
#pragma once
#ifdef USE_PYTHON3
-#error "No <dtoa.h> in Python3"
+#error "No <dtoa.h> in Python3"
#else
#include <contrib/tools/python/src/Include/dtoa.h>
#endif
diff --git a/contrib/libs/python/Include/exports.h b/contrib/libs/python/Include/exports.h
index ed9814c5b6..fdc68cfcf1 100644
--- a/contrib/libs/python/Include/exports.h
+++ b/contrib/libs/python/Include/exports.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/exports.h>
-#else
-#error "No <exports.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/exports.h>
+#else
+#error "No <exports.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/genericaliasobject.h b/contrib/libs/python/Include/genericaliasobject.h
index 44ec40f703..4d218b7e3f 100644
--- a/contrib/libs/python/Include/genericaliasobject.h
+++ b/contrib/libs/python/Include/genericaliasobject.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/genericaliasobject.h>
-#else
-#error "No <genericaliasobject.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/genericaliasobject.h>
+#else
+#error "No <genericaliasobject.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/interpreteridobject.h b/contrib/libs/python/Include/interpreteridobject.h
index c616b51ae7..1cd695d50f 100644
--- a/contrib/libs/python/Include/interpreteridobject.h
+++ b/contrib/libs/python/Include/interpreteridobject.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/interpreteridobject.h>
-#else
-#error "No <interpreteridobject.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/interpreteridobject.h>
+#else
+#error "No <interpreteridobject.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/metagrammar.h b/contrib/libs/python/Include/metagrammar.h
index 6c5f057a51..ab897e3820 100644
--- a/contrib/libs/python/Include/metagrammar.h
+++ b/contrib/libs/python/Include/metagrammar.h
@@ -1,7 +1,7 @@
#pragma once
#ifdef USE_PYTHON3
-#error "No <metagrammar.h> in Python3"
+#error "No <metagrammar.h> in Python3"
#else
#include <contrib/tools/python/src/Include/metagrammar.h>
#endif
diff --git a/contrib/libs/python/Include/pgen.h b/contrib/libs/python/Include/pgen.h
index 2d61f5d16c..b4a3a7dc8d 100644
--- a/contrib/libs/python/Include/pgen.h
+++ b/contrib/libs/python/Include/pgen.h
@@ -1,7 +1,7 @@
#pragma once
#ifdef USE_PYTHON3
-#error "No <pgen.h> in Python3"
+#error "No <pgen.h> in Python3"
#else
#include <contrib/tools/python/src/Include/pgen.h>
#endif
diff --git a/contrib/libs/python/Include/pgenheaders.h b/contrib/libs/python/Include/pgenheaders.h
index f1f841d845..1f859aebad 100644
--- a/contrib/libs/python/Include/pgenheaders.h
+++ b/contrib/libs/python/Include/pgenheaders.h
@@ -1,7 +1,7 @@
#pragma once
#ifdef USE_PYTHON3
-#error "No <pgenheaders.h> in Python3"
+#error "No <pgenheaders.h> in Python3"
#else
#include <contrib/tools/python/src/Include/pgenheaders.h>
#endif
diff --git a/contrib/libs/python/Include/picklebufobject.h b/contrib/libs/python/Include/picklebufobject.h
index 34f6e1b90c..70eba96ded 100644
--- a/contrib/libs/python/Include/picklebufobject.h
+++ b/contrib/libs/python/Include/picklebufobject.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/picklebufobject.h>
-#else
-#error "No <picklebufobject.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/picklebufobject.h>
+#else
+#error "No <picklebufobject.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/pyframe.h b/contrib/libs/python/Include/pyframe.h
index 08bf5e306b..69985948aa 100644
--- a/contrib/libs/python/Include/pyframe.h
+++ b/contrib/libs/python/Include/pyframe.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/pyframe.h>
-#else
-#error "No <pyframe.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/pyframe.h>
+#else
+#error "No <pyframe.h> in Python2"
+#endif
diff --git a/contrib/libs/python/Include/pygetopt.h b/contrib/libs/python/Include/pygetopt.h
index 7338e0c0ca..3e591b03ce 100644
--- a/contrib/libs/python/Include/pygetopt.h
+++ b/contrib/libs/python/Include/pygetopt.h
@@ -1,7 +1,7 @@
#pragma once
#ifdef USE_PYTHON3
-#error "No <pygetopt.h> in Python3"
+#error "No <pygetopt.h> in Python3"
#else
#include <contrib/tools/python/src/Include/pygetopt.h>
#endif
diff --git a/contrib/libs/python/Include/tracemalloc.h b/contrib/libs/python/Include/tracemalloc.h
index e3e6a4b360..cc29c6ff7e 100644
--- a/contrib/libs/python/Include/tracemalloc.h
+++ b/contrib/libs/python/Include/tracemalloc.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#ifdef USE_PYTHON3
-#include <contrib/tools/python3/src/Include/tracemalloc.h>
-#else
-#error "No <tracemalloc.h> in Python2"
-#endif
+#pragma once
+
+#ifdef USE_PYTHON3
+#include <contrib/tools/python3/src/Include/tracemalloc.h>
+#else
+#error "No <tracemalloc.h> in Python2"
+#endif
diff --git a/contrib/libs/rapidjson/ya.make b/contrib/libs/rapidjson/ya.make
index c9d27e8c38..0b26c5cc64 100644
--- a/contrib/libs/rapidjson/ya.make
+++ b/contrib/libs/rapidjson/ya.make
@@ -9,8 +9,8 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(1.1.0)
-
+VERSION(1.1.0)
+
OWNER(
g:contrib
g:cpp-contrib
diff --git a/contrib/libs/sparsehash/ya.make b/contrib/libs/sparsehash/ya.make
index b0f8994436..d12785158a 100644
--- a/contrib/libs/sparsehash/ya.make
+++ b/contrib/libs/sparsehash/ya.make
@@ -9,7 +9,7 @@ LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
OWNER(g:cpp-contrib)
VERSION(2.0.4)
-
+
ADDINCL(
GLOBAL contrib/libs/sparsehash/src
)
diff --git a/contrib/libs/sqlite3/config.h b/contrib/libs/sqlite3/config.h
index eb40462f4f..7b733f75a2 100644
--- a/contrib/libs/sqlite3/config.h
+++ b/contrib/libs/sqlite3/config.h
@@ -114,13 +114,13 @@
#define PACKAGE_NAME "sqlite"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "sqlite 3.37.2"
+#define PACKAGE_STRING "sqlite 3.37.2"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "sqlite"
/* Define to the version of this package. */
-#define PACKAGE_VERSION "3.37.2"
+#define PACKAGE_VERSION "3.37.2"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
diff --git a/contrib/libs/sqlite3/sqlite3.h b/contrib/libs/sqlite3/sqlite3.h
index ea85478b8a..4463e8ec13 100644
--- a/contrib/libs/sqlite3/sqlite3.h
+++ b/contrib/libs/sqlite3/sqlite3.h
@@ -146,9 +146,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.37.2"
-#define SQLITE_VERSION_NUMBER 3037002
-#define SQLITE_SOURCE_ID "2022-01-06 13:25:41 872ba256cbf61d9290b571c0e6d82a20c224ca3ad82971edc46b29818d5dalt1"
+#define SQLITE_VERSION "3.37.2"
+#define SQLITE_VERSION_NUMBER 3037002
+#define SQLITE_SOURCE_ID "2022-01-06 13:25:41 872ba256cbf61d9290b571c0e6d82a20c224ca3ad82971edc46b29818d5dalt1"
/*
** CAPI3REF: Run-Time Library Version Numbers
diff --git a/contrib/libs/tbb/ya.make b/contrib/libs/tbb/ya.make
index 201f0ad915..97b9caf037 100644
--- a/contrib/libs/tbb/ya.make
+++ b/contrib/libs/tbb/ya.make
@@ -1,4 +1,4 @@
-# Generated by devtools/yamaker from nixpkgs 32f7980afb5e33f1e078a51e715b9f102f396a69.
+# Generated by devtools/yamaker from nixpkgs 32f7980afb5e33f1e078a51e715b9f102f396a69.
LIBRARY()
@@ -7,7 +7,7 @@ OWNER(
g:cpp-contrib
)
-VERSION(2021.2.0)
+VERSION(2021.2.0)
ORIGINAL_SOURCE(https://github.com/oneapi-src/oneTBB/archive/v2021.2.0.tar.gz)
@@ -56,15 +56,15 @@ SRCS(
src/tbb/version.cpp
)
-IF (CLANG OR CLANG_CL)
- IF (ARCH_I386 OR ARCH_I686 OR ARCH_X86_64)
- CFLAGS(
- -mrtm
- -mwaitpkg
- )
- ENDIF()
-ENDIF()
-
+IF (CLANG OR CLANG_CL)
+ IF (ARCH_I386 OR ARCH_I686 OR ARCH_X86_64)
+ CFLAGS(
+ -mrtm
+ -mwaitpkg
+ )
+ ENDIF()
+ENDIF()
+
IF (OS_WINDOWS)
CFLAGS(
-DUSE_WINTHREAD
diff --git a/contrib/libs/xz/ya.make b/contrib/libs/xz/ya.make
index 5ce4ed52c9..3448d44354 100644
--- a/contrib/libs/xz/ya.make
+++ b/contrib/libs/xz/ya.make
@@ -3,8 +3,8 @@ OWNER(
g:cpp-contrib
)
-VERSION(5.2.4)
-
+VERSION(5.2.4)
+
RECURSE(
common
liblzma
diff --git a/contrib/libs/ya.make b/contrib/libs/ya.make
index bf38206063..9c4640fdcf 100644
--- a/contrib/libs/ya.make
+++ b/contrib/libs/ya.make
@@ -31,8 +31,8 @@ RECURSE(
cereal
ceres-solver
chromaprint
- clang12
- clang12-rt
+ clang12
+ clang12-rt
clapack
cld2
cnpy
@@ -148,7 +148,7 @@ RECURSE(
libevent
libexslt
libfdk-aac
- libfuzzer12
+ libfuzzer12
libgeotiff
libgit2
libgraphqlparser
@@ -207,7 +207,7 @@ RECURSE(
linuxvdso
liquidfun
llvm11
- llvm12
+ llvm12
llvm8
lmdbxx
lmdbxx/check
diff --git a/contrib/libs/yaml-cpp/ya.make b/contrib/libs/yaml-cpp/ya.make
index 8e2d7b827c..058caf92fa 100644
--- a/contrib/libs/yaml-cpp/ya.make
+++ b/contrib/libs/yaml-cpp/ya.make
@@ -4,8 +4,8 @@ LICENSE(MIT)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(0.5.3)
-
+VERSION(0.5.3)
+
OWNER(
g:antiinfra
g:contrib
diff --git a/contrib/libs/yaml/License b/contrib/libs/yaml/License
index e8f596b4de..3d82c281ee 100644
--- a/contrib/libs/yaml/License
+++ b/contrib/libs/yaml/License
@@ -1,5 +1,5 @@
-Copyright (c) 2017-2020 Ingy döt Net
-Copyright (c) 2006-2016 Kirill Simonov
+Copyright (c) 2017-2020 Ingy döt Net
+Copyright (c) 2006-2016 Kirill Simonov
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
diff --git a/contrib/libs/yaml/include/yaml.h b/contrib/libs/yaml/include/yaml.h
index b7ad2eeb2a..7ccd5ed97a 100644
--- a/contrib/libs/yaml/include/yaml.h
+++ b/contrib/libs/yaml/include/yaml.h
@@ -1,7 +1,7 @@
/**
* @file yaml.h
* @brief Public interface for libyaml.
- *
+ *
* Include the header file with the code:
* @code
* #include <yaml.h>
@@ -28,9 +28,9 @@ extern "C" {
#define YAML_DECLARE_STATIC
-#if defined(__MINGW32__)
-# define YAML_DECLARE(type) type
-#elif defined(_WIN32)
+#if defined(__MINGW32__)
+# define YAML_DECLARE(type) type
+#elif defined(_WIN32)
# if defined(YAML_DECLARE_STATIC)
# define YAML_DECLARE(type) type
# elif defined(YAML_DECLARE_EXPORT)
@@ -234,7 +234,7 @@ typedef enum yaml_token_type_e {
/** A BLOCK-SEQUENCE-START token. */
YAML_BLOCK_SEQUENCE_START_TOKEN,
- /** A BLOCK-MAPPING-START token. */
+ /** A BLOCK-MAPPING-START token. */
YAML_BLOCK_MAPPING_START_TOKEN,
/** A BLOCK-END token. */
YAML_BLOCK_END_TOKEN,
@@ -392,7 +392,7 @@ typedef struct yaml_event_s {
/** The event data. */
union {
-
+
/** The stream parameters (for @c YAML_STREAM_START_EVENT). */
struct {
/** The document encoding. */
@@ -554,7 +554,7 @@ yaml_document_end_event_initialize(yaml_event_t *event, int implicit);
*/
YAML_DECLARE(int)
-yaml_alias_event_initialize(yaml_event_t *event, const yaml_char_t *anchor);
+yaml_alias_event_initialize(yaml_event_t *event, const yaml_char_t *anchor);
/**
* Create a SCALAR event.
@@ -580,8 +580,8 @@ yaml_alias_event_initialize(yaml_event_t *event, const yaml_char_t *anchor);
YAML_DECLARE(int)
yaml_scalar_event_initialize(yaml_event_t *event,
- const yaml_char_t *anchor, const yaml_char_t *tag,
- const yaml_char_t *value, int length,
+ const yaml_char_t *anchor, const yaml_char_t *tag,
+ const yaml_char_t *value, int length,
int plain_implicit, int quoted_implicit,
yaml_scalar_style_t style);
@@ -603,7 +603,7 @@ yaml_scalar_event_initialize(yaml_event_t *event,
YAML_DECLARE(int)
yaml_sequence_start_event_initialize(yaml_event_t *event,
- const yaml_char_t *anchor, const yaml_char_t *tag, int implicit,
+ const yaml_char_t *anchor, const yaml_char_t *tag, int implicit,
yaml_sequence_style_t style);
/**
@@ -635,7 +635,7 @@ yaml_sequence_end_event_initialize(yaml_event_t *event);
YAML_DECLARE(int)
yaml_mapping_start_event_initialize(yaml_event_t *event,
- const yaml_char_t *anchor, const yaml_char_t *tag, int implicit,
+ const yaml_char_t *anchor, const yaml_char_t *tag, int implicit,
yaml_mapping_style_t style);
/**
@@ -667,7 +667,7 @@ yaml_event_delete(yaml_event_t *event);
/** The tag @c !!null with the only possible value: @c null. */
#define YAML_NULL_TAG "tag:yaml.org,2002:null"
-/** The tag @c !!bool with the values: @c true and @c false. */
+/** The tag @c !!bool with the values: @c true and @c false. */
#define YAML_BOOL_TAG "tag:yaml.org,2002:bool"
/** The tag @c !!str for string values. */
#define YAML_STR_TAG "tag:yaml.org,2002:str"
@@ -728,7 +728,7 @@ struct yaml_node_s {
/** The node data. */
union {
-
+
/** The scalar parameters (for @c YAML_SCALAR_NODE). */
struct {
/** The scalar value. */
@@ -898,7 +898,7 @@ yaml_document_get_root_node(yaml_document_t *document);
YAML_DECLARE(int)
yaml_document_add_scalar(yaml_document_t *document,
- const yaml_char_t *tag, const yaml_char_t *value, int length,
+ const yaml_char_t *tag, const yaml_char_t *value, int length,
yaml_scalar_style_t style);
/**
@@ -915,7 +915,7 @@ yaml_document_add_scalar(yaml_document_t *document,
YAML_DECLARE(int)
yaml_document_add_sequence(yaml_document_t *document,
- const yaml_char_t *tag, yaml_sequence_style_t style);
+ const yaml_char_t *tag, yaml_sequence_style_t style);
/**
* Create a MAPPING node and attach it to the document.
@@ -931,7 +931,7 @@ yaml_document_add_sequence(yaml_document_t *document,
YAML_DECLARE(int)
yaml_document_add_mapping(yaml_document_t *document,
- const yaml_char_t *tag, yaml_mapping_style_t style);
+ const yaml_char_t *tag, yaml_mapping_style_t style);
/**
* Add an item to a SEQUENCE node.
@@ -939,7 +939,7 @@ yaml_document_add_mapping(yaml_document_t *document,
* @param[in,out] document A document object.
* @param[in] sequence The sequence node id.
* @param[in] item The item node id.
- *
+ *
* @returns @c 1 if the function succeeded, @c 0 on error.
*/
@@ -954,7 +954,7 @@ yaml_document_append_sequence_item(yaml_document_t *document,
* @param[in] mapping The mapping node id.
* @param[in] key The key node id.
* @param[in] value The value node id.
- *
+ *
* @returns @c 1 if the function succeeded, @c 0 on error.
*/
@@ -1022,7 +1022,7 @@ typedef enum yaml_parser_state_e {
YAML_PARSE_DOCUMENT_CONTENT_STATE,
/** Expect DOCUMENT-END. */
YAML_PARSE_DOCUMENT_END_STATE,
-
+
/** Expect a block node. */
YAML_PARSE_BLOCK_NODE_STATE,
/** Expect a block node or indentless sequence. */
@@ -1033,7 +1033,7 @@ typedef enum yaml_parser_state_e {
YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE,
/** Expect an entry of a block sequence. */
YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE,
-
+
/** Expect an entry of an indentless sequence. */
YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE,
/** Expect the first key of a block mapping. */
@@ -1044,7 +1044,7 @@ typedef enum yaml_parser_state_e {
YAML_PARSE_BLOCK_MAPPING_VALUE_STATE,
/** Expect the first entry of a flow sequence. */
YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE,
-
+
/** Expect an entry of a flow sequence. */
YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE,
/** Expect a key of an ordered mapping. */
@@ -1056,7 +1056,7 @@ typedef enum yaml_parser_state_e {
/** Expect the first key of a flow mapping. */
YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE,
/** Expect a key of a flow mapping. */
-
+
YAML_PARSE_FLOW_MAPPING_KEY_STATE,
/** Expect a value of a flow mapping. */
YAML_PARSE_FLOW_MAPPING_VALUE_STATE,
@@ -1211,7 +1211,7 @@ typedef struct yaml_parser_s {
/** The number of tokens fetched from the queue. */
size_t tokens_parsed;
- /** Does the tokens queue contain a token ready for dequeueing. */
+ /** Does the tokens queue contain a token ready for dequeueing. */
int token_available;
/** The indentation levels stack. */
@@ -1452,7 +1452,7 @@ yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
* @param[in,out] parser A parser object.
* @param[out] document An empty document object.
*
- * @returns @c 1 if the function succeeded, @c 0 on error.
+ * @returns @c 1 if the function succeeded, @c 0 on error.
*/
YAML_DECLARE(int)
@@ -1495,7 +1495,7 @@ typedef enum yaml_emitter_state_e {
YAML_EMIT_DOCUMENT_CONTENT_STATE,
/** Expect DOCUMENT-END. */
YAML_EMIT_DOCUMENT_END_STATE,
-
+
/** Expect the first item of a flow sequence. */
YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE,
/** Expect an item of a flow sequence. */
@@ -1506,7 +1506,7 @@ typedef enum yaml_emitter_state_e {
YAML_EMIT_FLOW_MAPPING_KEY_STATE,
/** Expect a value for a simple key of a flow mapping. */
YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE,
-
+
/** Expect a value of a flow mapping. */
YAML_EMIT_FLOW_MAPPING_VALUE_STATE,
/** Expect the first item of a block sequence. */
@@ -1517,7 +1517,7 @@ typedef enum yaml_emitter_state_e {
YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE,
/** Expect the key of a block mapping. */
YAML_EMIT_BLOCK_MAPPING_KEY_STATE,
-
+
/** Expect a value for a simple key of a block mapping. */
YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE,
/** Expect a value of a block mapping. */
@@ -1526,18 +1526,18 @@ typedef enum yaml_emitter_state_e {
YAML_EMIT_END_STATE
} yaml_emitter_state_t;
-
-/* This is needed for C++ */
-
-typedef struct yaml_anchors_s {
- /** The number of references. */
- int references;
- /** The anchor id. */
- int anchor;
- /** If the node has been emitted? */
- int serialized;
-} yaml_anchors_t;
-
+
+/* This is needed for C++ */
+
+typedef struct yaml_anchors_s {
+ /** The number of references. */
+ int references;
+ /** The anchor id. */
+ int anchor;
+ /** If the node has been emitted? */
+ int serialized;
+} yaml_anchors_t;
+
/**
* The emitter structure.
*
@@ -1569,7 +1569,7 @@ typedef struct yaml_emitter_s {
/** Write handler. */
yaml_write_handler_t *write_handler;
- /** A pointer for passing to the write handler. */
+ /** A pointer for passing to the write handler. */
void *write_handler_data;
/** Standard (string or file) output data. */
@@ -1763,7 +1763,7 @@ typedef struct yaml_emitter_s {
int closed;
/** The information associated with the document nodes. */
- yaml_anchors_t *anchors;
+ yaml_anchors_t *anchors;
/** The last assigned anchor id. */
int last_anchor_id;
@@ -1867,7 +1867,7 @@ YAML_DECLARE(void)
yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical);
/**
- * Set the indentation increment.
+ * Set the indentation increment.
*
* @param[in,out] emitter An emitter object.
* @param[in] indent The indentation increment (1 < . < 10).
@@ -1954,8 +1954,8 @@ yaml_emitter_close(yaml_emitter_t *emitter);
*
* The documen object may be generated using the yaml_parser_load() function
* or the yaml_document_initialize() function. The emitter takes the
- * responsibility for the document object and destroys its content after
- * it is emitted. The document object is destroyed even if the function fails.
+ * responsibility for the document object and destroys its content after
+ * it is emitted. The document object is destroyed even if the function fails.
*
* @param[in,out] emitter An emitter object.
* @param[in,out] document A document object.
diff --git a/contrib/libs/yaml/src/api.c b/contrib/libs/yaml/src/api.c
index d670f327eb..16f88bd762 100644
--- a/contrib/libs/yaml/src/api.c
+++ b/contrib/libs/yaml/src/api.c
@@ -74,7 +74,7 @@ YAML_DECLARE(int)
yaml_string_extend(yaml_char_t **start,
yaml_char_t **pointer, yaml_char_t **end)
{
- yaml_char_t *new_start = (yaml_char_t *)yaml_realloc((void*)*start, (*end - *start)*2);
+ yaml_char_t *new_start = (yaml_char_t *)yaml_realloc((void*)*start, (*end - *start)*2);
if (!new_start) return 0;
@@ -94,9 +94,9 @@ yaml_string_extend(yaml_char_t **start,
YAML_DECLARE(int)
yaml_string_join(
yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
- yaml_char_t **b_start, yaml_char_t **b_pointer, SHIM(yaml_char_t **b_end))
+ yaml_char_t **b_start, yaml_char_t **b_pointer, SHIM(yaml_char_t **b_end))
{
- UNUSED_PARAM(b_end)
+ UNUSED_PARAM(b_end)
if (*b_start == *b_pointer)
return 1;
@@ -118,13 +118,13 @@ yaml_string_join(
YAML_DECLARE(int)
yaml_stack_extend(void **start, void **top, void **end)
{
- void *new_start;
+ void *new_start;
+
+ if ((char *)*end - (char *)*start >= INT_MAX / 2)
+ return 0;
+
+ new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2);
- if ((char *)*end - (char *)*start >= INT_MAX / 2)
- return 0;
-
- new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2);
-
if (!new_start) return 0;
*top = (char *)new_start + ((char *)*top - (char *)*start);
@@ -183,17 +183,17 @@ yaml_parser_initialize(yaml_parser_t *parser)
goto error;
if (!BUFFER_INIT(parser, parser->buffer, INPUT_BUFFER_SIZE))
goto error;
- if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_SIZE, yaml_token_t*))
+ if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_SIZE, yaml_token_t*))
goto error;
- if (!STACK_INIT(parser, parser->indents, int*))
+ if (!STACK_INIT(parser, parser->indents, int*))
goto error;
- if (!STACK_INIT(parser, parser->simple_keys, yaml_simple_key_t*))
+ if (!STACK_INIT(parser, parser->simple_keys, yaml_simple_key_t*))
goto error;
- if (!STACK_INIT(parser, parser->states, yaml_parser_state_t*))
+ if (!STACK_INIT(parser, parser->states, yaml_parser_state_t*))
goto error;
- if (!STACK_INIT(parser, parser->marks, yaml_mark_t*))
+ if (!STACK_INIT(parser, parser->marks, yaml_mark_t*))
goto error;
- if (!STACK_INIT(parser, parser->tag_directives, yaml_tag_directive_t*))
+ if (!STACK_INIT(parser, parser->tag_directives, yaml_tag_directive_t*))
goto error;
return 1;
@@ -249,7 +249,7 @@ static int
yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
size_t *size_read)
{
- yaml_parser_t *parser = (yaml_parser_t *)data;
+ yaml_parser_t *parser = (yaml_parser_t *)data;
if (parser->input.string.current == parser->input.string.end) {
*size_read = 0;
@@ -275,7 +275,7 @@ static int
yaml_file_read_handler(void *data, unsigned char *buffer, size_t size,
size_t *size_read)
{
- yaml_parser_t *parser = (yaml_parser_t *)data;
+ yaml_parser_t *parser = (yaml_parser_t *)data;
*size_read = fread(buffer, 1, size, parser->input.file);
return !ferror(parser->input.file);
@@ -361,13 +361,13 @@ yaml_emitter_initialize(yaml_emitter_t *emitter)
goto error;
if (!BUFFER_INIT(emitter, emitter->raw_buffer, OUTPUT_RAW_BUFFER_SIZE))
goto error;
- if (!STACK_INIT(emitter, emitter->states, yaml_emitter_state_t*))
+ if (!STACK_INIT(emitter, emitter->states, yaml_emitter_state_t*))
goto error;
- if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_SIZE, yaml_event_t*))
+ if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_SIZE, yaml_event_t*))
goto error;
- if (!STACK_INIT(emitter, emitter->indents, int*))
+ if (!STACK_INIT(emitter, emitter->indents, int*))
goto error;
- if (!STACK_INIT(emitter, emitter->tag_directives, yaml_tag_directive_t*))
+ if (!STACK_INIT(emitter, emitter->tag_directives, yaml_tag_directive_t*))
goto error;
return 1;
@@ -419,9 +419,9 @@ yaml_emitter_delete(yaml_emitter_t *emitter)
static int
yaml_string_write_handler(void *data, unsigned char *buffer, size_t size)
{
- yaml_emitter_t *emitter = (yaml_emitter_t *)data;
+ yaml_emitter_t *emitter = (yaml_emitter_t *)data;
- if (emitter->output.string.size - *emitter->output.string.size_written
+ if (emitter->output.string.size - *emitter->output.string.size_written
< size) {
memcpy(emitter->output.string.buffer
+ *emitter->output.string.size_written,
@@ -445,7 +445,7 @@ yaml_string_write_handler(void *data, unsigned char *buffer, size_t size)
static int
yaml_file_write_handler(void *data, unsigned char *buffer, size_t size)
{
- yaml_emitter_t *emitter = (yaml_emitter_t *)data;
+ yaml_emitter_t *emitter = (yaml_emitter_t *)data;
return (fwrite(buffer, 1, size, emitter->output.file) == size);
}
@@ -623,10 +623,10 @@ yaml_token_delete(yaml_token_t *token)
*/
static int
-yaml_check_utf8(const yaml_char_t *start, size_t length)
+yaml_check_utf8(const yaml_char_t *start, size_t length)
{
- const yaml_char_t *end = start+length;
- const yaml_char_t *pointer = start;
+ const yaml_char_t *end = start+length;
+ const yaml_char_t *pointer = start;
while (pointer < end) {
unsigned char octet;
@@ -723,7 +723,7 @@ yaml_document_start_event_initialize(yaml_event_t *event,
/* Valid tag directives are expected. */
if (version_directive) {
- version_directive_copy = YAML_MALLOC_STATIC(yaml_version_directive_t);
+ version_directive_copy = YAML_MALLOC_STATIC(yaml_version_directive_t);
if (!version_directive_copy) goto error;
version_directive_copy->major = version_directive->major;
version_directive_copy->minor = version_directive->minor;
@@ -731,7 +731,7 @@ yaml_document_start_event_initialize(yaml_event_t *event,
if (tag_directives_start != tag_directives_end) {
yaml_tag_directive_t *tag_directive;
- if (!STACK_INIT(&context, tag_directives_copy, yaml_tag_directive_t*))
+ if (!STACK_INIT(&context, tag_directives_copy, yaml_tag_directive_t*))
goto error;
for (tag_directive = tag_directives_start;
tag_directive != tag_directives_end; tag_directive ++) {
@@ -794,7 +794,7 @@ yaml_document_end_event_initialize(yaml_event_t *event, int implicit)
*/
YAML_DECLARE(int)
-yaml_alias_event_initialize(yaml_event_t *event, const yaml_char_t *anchor)
+yaml_alias_event_initialize(yaml_event_t *event, const yaml_char_t *anchor)
{
yaml_mark_t mark = { 0, 0, 0 };
yaml_char_t *anchor_copy = NULL;
@@ -819,8 +819,8 @@ yaml_alias_event_initialize(yaml_event_t *event, const yaml_char_t *anchor)
YAML_DECLARE(int)
yaml_scalar_event_initialize(yaml_event_t *event,
- const yaml_char_t *anchor, const yaml_char_t *tag,
- const yaml_char_t *value, int length,
+ const yaml_char_t *anchor, const yaml_char_t *tag,
+ const yaml_char_t *value, int length,
int plain_implicit, int quoted_implicit,
yaml_scalar_style_t style)
{
@@ -849,7 +849,7 @@ yaml_scalar_event_initialize(yaml_event_t *event,
}
if (!yaml_check_utf8(value, length)) goto error;
- value_copy = YAML_MALLOC(length+1);
+ value_copy = YAML_MALLOC(length+1);
if (!value_copy) goto error;
memcpy(value_copy, value, length);
value_copy[length] = '\0';
@@ -873,7 +873,7 @@ error:
YAML_DECLARE(int)
yaml_sequence_start_event_initialize(yaml_event_t *event,
- const yaml_char_t *anchor, const yaml_char_t *tag, int implicit,
+ const yaml_char_t *anchor, const yaml_char_t *tag, int implicit,
yaml_sequence_style_t style)
{
yaml_mark_t mark = { 0, 0, 0 };
@@ -928,7 +928,7 @@ yaml_sequence_end_event_initialize(yaml_event_t *event)
YAML_DECLARE(int)
yaml_mapping_start_event_initialize(yaml_event_t *event,
- const yaml_char_t *anchor, const yaml_char_t *tag, int implicit,
+ const yaml_char_t *anchor, const yaml_char_t *tag, int implicit,
yaml_mapping_style_t style)
{
yaml_mark_t mark = { 0, 0, 0 };
@@ -1061,10 +1061,10 @@ yaml_document_initialize(yaml_document_t *document,
(tag_directives_start == tag_directives_end));
/* Valid tag directives are expected. */
- if (!STACK_INIT(&context, nodes, yaml_node_t*)) goto error;
+ if (!STACK_INIT(&context, nodes, yaml_node_t*)) goto error;
if (version_directive) {
- version_directive_copy = YAML_MALLOC_STATIC(yaml_version_directive_t);
+ version_directive_copy = YAML_MALLOC_STATIC(yaml_version_directive_t);
if (!version_directive_copy) goto error;
version_directive_copy->major = version_directive->major;
version_directive_copy->minor = version_directive->minor;
@@ -1072,7 +1072,7 @@ yaml_document_initialize(yaml_document_t *document,
if (tag_directives_start != tag_directives_end) {
yaml_tag_directive_t *tag_directive;
- if (!STACK_INIT(&context, tag_directives_copy, yaml_tag_directive_t*))
+ if (!STACK_INIT(&context, tag_directives_copy, yaml_tag_directive_t*))
goto error;
for (tag_directive = tag_directives_start;
tag_directive != tag_directives_end; tag_directive ++) {
@@ -1193,7 +1193,7 @@ yaml_document_get_root_node(yaml_document_t *document)
YAML_DECLARE(int)
yaml_document_add_scalar(yaml_document_t *document,
- const yaml_char_t *tag, const yaml_char_t *value, int length,
+ const yaml_char_t *tag, const yaml_char_t *value, int length,
yaml_scalar_style_t style)
{
struct {
@@ -1220,7 +1220,7 @@ yaml_document_add_scalar(yaml_document_t *document,
}
if (!yaml_check_utf8(value, length)) goto error;
- value_copy = YAML_MALLOC(length+1);
+ value_copy = YAML_MALLOC(length+1);
if (!value_copy) goto error;
memcpy(value_copy, value, length);
value_copy[length] = '\0';
@@ -1243,7 +1243,7 @@ error:
YAML_DECLARE(int)
yaml_document_add_sequence(yaml_document_t *document,
- const yaml_char_t *tag, yaml_sequence_style_t style)
+ const yaml_char_t *tag, yaml_sequence_style_t style)
{
struct {
yaml_error_type_t error;
@@ -1267,7 +1267,7 @@ yaml_document_add_sequence(yaml_document_t *document,
tag_copy = yaml_strdup(tag);
if (!tag_copy) goto error;
- if (!STACK_INIT(&context, items, yaml_node_item_t*)) goto error;
+ if (!STACK_INIT(&context, items, yaml_node_item_t*)) goto error;
SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,
style, mark, mark);
@@ -1288,7 +1288,7 @@ error:
YAML_DECLARE(int)
yaml_document_add_mapping(yaml_document_t *document,
- const yaml_char_t *tag, yaml_mapping_style_t style)
+ const yaml_char_t *tag, yaml_mapping_style_t style)
{
struct {
yaml_error_type_t error;
@@ -1312,7 +1312,7 @@ yaml_document_add_mapping(yaml_document_t *document,
tag_copy = yaml_strdup(tag);
if (!tag_copy) goto error;
- if (!STACK_INIT(&context, pairs, yaml_node_pair_t*)) goto error;
+ if (!STACK_INIT(&context, pairs, yaml_node_pair_t*)) goto error;
MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,
style, mark, mark);
diff --git a/contrib/libs/yaml/src/config.h b/contrib/libs/yaml/src/config.h
index d71932721d..22a2296e5e 100644
--- a/contrib/libs/yaml/src/config.h
+++ b/contrib/libs/yaml/src/config.h
@@ -1,82 +1,82 @@
-/* include/config.h. Generated from config.h.in by configure. */
-/* include/config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdio.h> header file. */
-#define HAVE_STDIO_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
-#define LT_OBJDIR ".libs/"
-
-/* Name of package */
-#define PACKAGE "yaml"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "https://github.com/yaml/libyaml/issues/new"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "yaml"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "yaml 0.2.5"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "yaml"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "0.2.5"
-
-/* Define to 1 if all of the C90 standard headers exist (not just the ones
- required in a freestanding environment). This macro is provided for
- backward compatibility; new code need not use it. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "0.2.5"
-
-/* Define the major version number. */
+/* include/config.h. Generated from config.h.in by configure. */
+/* include/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#define HAVE_STDIO_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* Name of package */
+#define PACKAGE "yaml"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "https://github.com/yaml/libyaml/issues/new"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "yaml"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "yaml 0.2.5"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "yaml"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "0.2.5"
+
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+ required in a freestanding environment). This macro is provided for
+ backward compatibility; new code need not use it. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "0.2.5"
+
+/* Define the major version number. */
#define YAML_VERSION_MAJOR 0
-
-/* Define the minor version number. */
-#define YAML_VERSION_MINOR 2
-
-/* Define the patch version number. */
-#define YAML_VERSION_PATCH 5
-
-/* Define the version string. */
-#define YAML_VERSION_STRING "0.2.5"
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-/* #undef size_t */
+
+/* Define the minor version number. */
+#define YAML_VERSION_MINOR 2
+
+/* Define the patch version number. */
+#define YAML_VERSION_PATCH 5
+
+/* Define the version string. */
+#define YAML_VERSION_STRING "0.2.5"
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
diff --git a/contrib/libs/yaml/src/dumper.c b/contrib/libs/yaml/src/dumper.c
index a0b2c2f50f..1fe940b674 100644
--- a/contrib/libs/yaml/src/dumper.c
+++ b/contrib/libs/yaml/src/dumper.c
@@ -131,7 +131,7 @@ yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document)
assert(emitter->opened); /* Emitter should be opened. */
- emitter->anchors = (yaml_anchors_t*)yaml_malloc(sizeof(*(emitter->anchors))
+ emitter->anchors = (yaml_anchors_t*)yaml_malloc(sizeof(*(emitter->anchors))
* (document->nodes.top - document->nodes.start));
if (!emitter->anchors) goto error;
memset(emitter->anchors, 0, sizeof(*(emitter->anchors))
@@ -245,9 +245,9 @@ yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index)
#define ANCHOR_TEMPLATE_LENGTH 16
static yaml_char_t *
-yaml_emitter_generate_anchor(SHIM(yaml_emitter_t *emitter), int anchor_id)
+yaml_emitter_generate_anchor(SHIM(yaml_emitter_t *emitter), int anchor_id)
{
- yaml_char_t *anchor = YAML_MALLOC(ANCHOR_TEMPLATE_LENGTH);
+ yaml_char_t *anchor = YAML_MALLOC(ANCHOR_TEMPLATE_LENGTH);
if (!anchor) return NULL;
diff --git a/contrib/libs/yaml/src/emitter.c b/contrib/libs/yaml/src/emitter.c
index ed0b323934..609b28a4c6 100644
--- a/contrib/libs/yaml/src/emitter.c
+++ b/contrib/libs/yaml/src/emitter.c
@@ -16,7 +16,7 @@
#define PUT(emitter,value) \
(FLUSH(emitter) \
&& (*(emitter->buffer.pointer++) = (yaml_char_t)(value), \
- emitter->column++, \
+ emitter->column++, \
1))
/*
@@ -221,7 +221,7 @@ yaml_emitter_write_indent(yaml_emitter_t *emitter);
static int
yaml_emitter_write_indicator(yaml_emitter_t *emitter,
- const char *indicator, int need_whitespace,
+ const char *indicator, int need_whitespace,
int is_whitespace, int is_indention);
static int
@@ -495,7 +495,7 @@ static int
yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
yaml_event_t *event)
{
- emitter->open_ended = 0;
+ emitter->open_ended = 0;
if (event->type == YAML_STREAM_START_EVENT)
{
if (!emitter->encoding) {
@@ -518,7 +518,7 @@ yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
if (emitter->best_width < 0) {
emitter->best_width = INT_MAX;
}
-
+
if (!emitter->line_break) {
emitter->line_break = YAML_LN_BREAK;
}
@@ -598,24 +598,24 @@ yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
if (!yaml_emitter_write_indent(emitter))
return 0;
}
- emitter->open_ended = 0;
+ emitter->open_ended = 0;
if (event->data.document_start.version_directive) {
implicit = 0;
if (!yaml_emitter_write_indicator(emitter, "%YAML", 1, 0, 0))
return 0;
- if (event->data.document_start.version_directive->minor == 1) {
- if (!yaml_emitter_write_indicator(emitter, "1.1", 1, 0, 0))
- return 0;
- }
- else {
- if (!yaml_emitter_write_indicator(emitter, "1.2", 1, 0, 0))
- return 0;
- }
+ if (event->data.document_start.version_directive->minor == 1) {
+ if (!yaml_emitter_write_indicator(emitter, "1.1", 1, 0, 0))
+ return 0;
+ }
+ else {
+ if (!yaml_emitter_write_indicator(emitter, "1.2", 1, 0, 0))
+ return 0;
+ }
if (!yaml_emitter_write_indent(emitter))
return 0;
}
-
+
if (event->data.document_start.tag_directives.start
!= event->data.document_start.tag_directives.end) {
implicit = 0;
@@ -652,25 +652,25 @@ yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
emitter->state = YAML_EMIT_DOCUMENT_CONTENT_STATE;
- emitter->open_ended = 0;
+ emitter->open_ended = 0;
return 1;
}
else if (event->type == YAML_STREAM_END_EVENT)
{
- /**
- * This can happen if a block scalar with trailing empty lines
- * is at the end of the stream
- */
- if (emitter->open_ended == 2)
- {
- if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
- return 0;
- emitter->open_ended = 0;
- if (!yaml_emitter_write_indent(emitter))
- return 0;
- }
+ /**
+ * This can happen if a block scalar with trailing empty lines
+ * is at the end of the stream
+ */
+ if (emitter->open_ended == 2)
+ {
+ if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
+ return 0;
+ emitter->open_ended = 0;
+ if (!yaml_emitter_write_indent(emitter))
+ return 0;
+ }
if (!yaml_emitter_flush(emitter))
return 0;
@@ -712,12 +712,12 @@ yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
if (!event->data.document_end.implicit) {
if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
return 0;
- emitter->open_ended = 0;
+ emitter->open_ended = 0;
if (!yaml_emitter_write_indent(emitter))
return 0;
}
- else if (!emitter->open_ended)
- emitter->open_ended = 1;
+ else if (!emitter->open_ended)
+ emitter->open_ended = 1;
if (!yaml_emitter_flush(emitter))
return 0;
@@ -738,7 +738,7 @@ yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
}
/*
- *
+ *
* Expect a flow item node.
*/
@@ -1019,12 +1019,12 @@ yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
*/
static int
-yaml_emitter_emit_alias(yaml_emitter_t *emitter, SHIM(yaml_event_t *event))
+yaml_emitter_emit_alias(yaml_emitter_t *emitter, SHIM(yaml_event_t *event))
{
if (!yaml_emitter_process_anchor(emitter))
return 0;
- if (emitter->simple_key_context)
- if (!PUT(emitter, ' ')) return 0;
+ if (emitter->simple_key_context)
+ if (!PUT(emitter, ' ')) return 0;
emitter->state = POP(emitter, emitter->states);
return 1;
@@ -1106,7 +1106,7 @@ yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event)
*/
static int
-yaml_emitter_check_empty_document(SHIM(yaml_emitter_t *emitter))
+yaml_emitter_check_empty_document(SHIM(yaml_emitter_t *emitter))
{
return 0;
}
@@ -1253,7 +1253,7 @@ yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event)
}
/*
- * Write an anchor.
+ * Write an anchor.
*/
static int
@@ -1352,10 +1352,10 @@ static int
yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
yaml_version_directive_t version_directive)
{
- if (version_directive.major != 1 || (
- version_directive.minor != 1
- && version_directive.minor != 2
- )) {
+ if (version_directive.major != 1 || (
+ version_directive.minor != 1
+ && version_directive.minor != 2
+ )) {
return yaml_emitter_set_emitter_error(emitter,
"incompatible %YAML directive");
}
@@ -1424,7 +1424,7 @@ yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
{
size_t anchor_length;
yaml_string_t string;
-
+
anchor_length = strlen((char *)anchor);
STRING_ASSIGN(string, anchor, anchor_length);
@@ -1515,7 +1515,7 @@ yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
int break_space = 0;
int space_break = 0;
- int preceded_by_whitespace = 0;
+ int preceded_by_whitespace = 0;
int followed_by_whitespace = 0;
int previous_space = 0;
int previous_break = 0;
@@ -1546,7 +1546,7 @@ yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
flow_indicators = 1;
}
- preceded_by_whitespace = 1;
+ preceded_by_whitespace = 1;
followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
while (string.pointer != string.end)
@@ -1592,7 +1592,7 @@ yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
}
}
- if (CHECK(string, '#') && preceded_by_whitespace) {
+ if (CHECK(string, '#') && preceded_by_whitespace) {
flow_indicators = 1;
block_indicators = 1;
}
@@ -1641,7 +1641,7 @@ yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
previous_break = 0;
}
- preceded_by_whitespace = IS_BLANKZ(string);
+ preceded_by_whitespace = IS_BLANKZ(string);
MOVE(string);
if (string.pointer != string.end) {
followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
@@ -1806,7 +1806,7 @@ yaml_emitter_write_indent(yaml_emitter_t *emitter)
static int
yaml_emitter_write_indicator(yaml_emitter_t *emitter,
- const char *indicator, int need_whitespace,
+ const char *indicator, int need_whitespace,
int is_whitespace, int is_indention)
{
size_t indicator_length;
@@ -1925,17 +1925,17 @@ yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
STRING_ASSIGN(string, value, length);
- /**
- * Avoid trailing spaces for empty values in block mode.
- * In flow mode, we still want the space to prevent ambiguous things
- * like {a:}.
- * Currently, the emitter forbids any plain empty scalar in flow mode
- * (e.g. it outputs {a: ''} instead), so emitter->flow_level will
- * never be true here.
- * But if the emitter is ever changed to allow emitting empty values,
- * the check for flow_level is already here.
- */
- if (!emitter->whitespace && (length || emitter->flow_level)) {
+ /**
+ * Avoid trailing spaces for empty values in block mode.
+ * In flow mode, we still want the space to prevent ambiguous things
+ * like {a:}.
+ * Currently, the emitter forbids any plain empty scalar in flow mode
+ * (e.g. it outputs {a: ''} instead), so emitter->flow_level will
+ * never be true here.
+ * But if the emitter is ever changed to allow emitting empty values,
+ * the check for flow_level is already here.
+ */
+ if (!emitter->whitespace && (length || emitter->flow_level)) {
if (!PUT(emitter, ' ')) return 0;
}
@@ -2035,9 +2035,9 @@ yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
}
}
- if (breaks)
- if (!yaml_emitter_write_indent(emitter)) return 0;
-
+ if (breaks)
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+
if (!yaml_emitter_write_indicator(emitter, "'", 0, 0, 0))
return 0;
@@ -2208,7 +2208,7 @@ yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
yaml_string_t string)
{
char indent_hint[2];
- const char *chomp_hint = NULL;
+ const char *chomp_hint = NULL;
if (IS_SPACE(string) || IS_BREAK(string))
{
@@ -2237,7 +2237,7 @@ yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
else if (string.start == string.pointer)
{
chomp_hint = "+";
- emitter->open_ended = 2;
+ emitter->open_ended = 2;
}
else
{
@@ -2247,7 +2247,7 @@ yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
if (IS_BREAK(string))
{
chomp_hint = "+";
- emitter->open_ended = 2;
+ emitter->open_ended = 2;
}
}
}
diff --git a/contrib/libs/yaml/src/loader.c b/contrib/libs/yaml/src/loader.c
index 9d1a34a1c1..dea8ac428c 100644
--- a/contrib/libs/yaml/src/loader.c
+++ b/contrib/libs/yaml/src/loader.c
@@ -38,47 +38,47 @@ static void
yaml_parser_delete_aliases(yaml_parser_t *parser);
/*
- * Document loading context.
- */
-struct loader_ctx {
- int *start;
- int *end;
- int *top;
-};
-
-/*
+ * Document loading context.
+ */
+struct loader_ctx {
+ int *start;
+ int *end;
+ int *top;
+};
+
+/*
* Composer functions.
*/
-static int
-yaml_parser_load_nodes(yaml_parser_t *parser, struct loader_ctx *ctx);
+static int
+yaml_parser_load_nodes(yaml_parser_t *parser, struct loader_ctx *ctx);
static int
-yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *event);
+yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *event);
static int
-yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *event,
- struct loader_ctx *ctx);
+yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx);
static int
-yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *event,
- struct loader_ctx *ctx);
+yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx);
static int
-yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *event,
- struct loader_ctx *ctx);
+yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx);
static int
-yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *event,
- struct loader_ctx *ctx);
+yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx);
static int
-yaml_parser_load_sequence_end(yaml_parser_t *parser, yaml_event_t *event,
- struct loader_ctx *ctx);
+yaml_parser_load_sequence_end(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx);
+
+static int
+yaml_parser_load_mapping_end(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx);
-static int
-yaml_parser_load_mapping_end(yaml_parser_t *parser, yaml_event_t *event,
- struct loader_ctx *ctx);
-
/*
* Load the next document of the stream.
*/
@@ -92,7 +92,7 @@ yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
assert(document); /* Non-NULL document object is expected. */
memset(document, 0, sizeof(yaml_document_t));
- if (!STACK_INIT(parser, document->nodes, yaml_node_t*))
+ if (!STACK_INIT(parser, document->nodes, yaml_node_t*))
goto error;
if (!parser->stream_start_produced) {
@@ -110,7 +110,7 @@ yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
return 1;
}
- if (!STACK_INIT(parser, parser->aliases, yaml_alias_data_t*))
+ if (!STACK_INIT(parser, parser->aliases, yaml_alias_data_t*))
goto error;
parser->document = document;
@@ -182,78 +182,78 @@ yaml_parser_delete_aliases(yaml_parser_t *parser)
*/
static int
-yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *event)
+yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *event)
{
- struct loader_ctx ctx = { NULL, NULL, NULL };
+ struct loader_ctx ctx = { NULL, NULL, NULL };
- assert(event->type == YAML_DOCUMENT_START_EVENT);
+ assert(event->type == YAML_DOCUMENT_START_EVENT);
/* DOCUMENT-START is expected. */
parser->document->version_directive
- = event->data.document_start.version_directive;
+ = event->data.document_start.version_directive;
parser->document->tag_directives.start
- = event->data.document_start.tag_directives.start;
+ = event->data.document_start.tag_directives.start;
parser->document->tag_directives.end
- = event->data.document_start.tag_directives.end;
+ = event->data.document_start.tag_directives.end;
parser->document->start_implicit
- = event->data.document_start.implicit;
- parser->document->start_mark = event->start_mark;
+ = event->data.document_start.implicit;
+ parser->document->start_mark = event->start_mark;
- if (!STACK_INIT(parser, ctx, int*)) return 0;
- if (!yaml_parser_load_nodes(parser, &ctx)) {
- STACK_DEL(parser, ctx);
- return 0;
- }
- STACK_DEL(parser, ctx);
+ if (!STACK_INIT(parser, ctx, int*)) return 0;
+ if (!yaml_parser_load_nodes(parser, &ctx)) {
+ STACK_DEL(parser, ctx);
+ return 0;
+ }
+ STACK_DEL(parser, ctx);
return 1;
}
/*
- * Compose a node tree.
+ * Compose a node tree.
*/
static int
-yaml_parser_load_nodes(yaml_parser_t *parser, struct loader_ctx *ctx)
+yaml_parser_load_nodes(yaml_parser_t *parser, struct loader_ctx *ctx)
{
- yaml_event_t event;
-
- do {
- if (!yaml_parser_parse(parser, &event)) return 0;
-
- switch (event.type) {
- case YAML_ALIAS_EVENT:
- if (!yaml_parser_load_alias(parser, &event, ctx)) return 0;
- break;
- case YAML_SCALAR_EVENT:
- if (!yaml_parser_load_scalar(parser, &event, ctx)) return 0;
- break;
- case YAML_SEQUENCE_START_EVENT:
- if (!yaml_parser_load_sequence(parser, &event, ctx)) return 0;
- break;
- case YAML_SEQUENCE_END_EVENT:
- if (!yaml_parser_load_sequence_end(parser, &event, ctx))
- return 0;
- break;
- case YAML_MAPPING_START_EVENT:
- if (!yaml_parser_load_mapping(parser, &event, ctx)) return 0;
- break;
- case YAML_MAPPING_END_EVENT:
- if (!yaml_parser_load_mapping_end(parser, &event, ctx))
- return 0;
- break;
- default:
- assert(0); /* Could not happen. */
- return 0;
- case YAML_DOCUMENT_END_EVENT:
- break;
- }
- } while (event.type != YAML_DOCUMENT_END_EVENT);
-
- parser->document->end_implicit = event.data.document_end.implicit;
- parser->document->end_mark = event.end_mark;
-
- return 1;
+ yaml_event_t event;
+
+ do {
+ if (!yaml_parser_parse(parser, &event)) return 0;
+
+ switch (event.type) {
+ case YAML_ALIAS_EVENT:
+ if (!yaml_parser_load_alias(parser, &event, ctx)) return 0;
+ break;
+ case YAML_SCALAR_EVENT:
+ if (!yaml_parser_load_scalar(parser, &event, ctx)) return 0;
+ break;
+ case YAML_SEQUENCE_START_EVENT:
+ if (!yaml_parser_load_sequence(parser, &event, ctx)) return 0;
+ break;
+ case YAML_SEQUENCE_END_EVENT:
+ if (!yaml_parser_load_sequence_end(parser, &event, ctx))
+ return 0;
+ break;
+ case YAML_MAPPING_START_EVENT:
+ if (!yaml_parser_load_mapping(parser, &event, ctx)) return 0;
+ break;
+ case YAML_MAPPING_END_EVENT:
+ if (!yaml_parser_load_mapping_end(parser, &event, ctx))
+ return 0;
+ break;
+ default:
+ assert(0); /* Could not happen. */
+ return 0;
+ case YAML_DOCUMENT_END_EVENT:
+ break;
+ }
+ } while (event.type != YAML_DOCUMENT_END_EVENT);
+
+ parser->document->end_implicit = event.data.document_end.implicit;
+ parser->document->end_mark = event.end_mark;
+
+ return 1;
}
/*
@@ -278,8 +278,8 @@ yaml_parser_register_anchor(yaml_parser_t *parser,
if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
yaml_free(anchor);
return yaml_parser_set_composer_error_context(parser,
- "found duplicate anchor; first occurrence",
- alias_data->mark, "second occurrence", data.mark);
+ "found duplicate anchor; first occurrence",
+ alias_data->mark, "second occurrence", data.mark);
}
}
@@ -292,79 +292,79 @@ yaml_parser_register_anchor(yaml_parser_t *parser,
}
/*
- * Compose node into its parent in the stree.
- */
-
-static int
-yaml_parser_load_node_add(yaml_parser_t *parser, struct loader_ctx *ctx,
- int index)
-{
- struct yaml_node_s *parent;
- int parent_index;
-
- if (STACK_EMPTY(parser, *ctx)) {
- /* This is the root node, there's no tree to add it to. */
- return 1;
- }
-
- parent_index = *((*ctx).top - 1);
- parent = &parser->document->nodes.start[parent_index-1];
-
- switch (parent->type) {
- case YAML_SEQUENCE_NODE:
- if (!STACK_LIMIT(parser, parent->data.sequence.items, INT_MAX-1))
- return 0;
- if (!PUSH(parser, parent->data.sequence.items, index))
- return 0;
- break;
- case YAML_MAPPING_NODE: {
- yaml_node_pair_t pair;
- if (!STACK_EMPTY(parser, parent->data.mapping.pairs)) {
- yaml_node_pair_t *p = parent->data.mapping.pairs.top - 1;
- if (p->key != 0 && p->value == 0) {
- p->value = index;
- break;
- }
- }
-
- pair.key = index;
- pair.value = 0;
- if (!STACK_LIMIT(parser, parent->data.mapping.pairs, INT_MAX-1))
- return 0;
- if (!PUSH(parser, parent->data.mapping.pairs, pair))
- return 0;
-
- break;
- }
- default:
- assert(0); /* Could not happen. */
- return 0;
- }
- return 1;
-}
-
-/*
+ * Compose node into its parent in the stree.
+ */
+
+static int
+yaml_parser_load_node_add(yaml_parser_t *parser, struct loader_ctx *ctx,
+ int index)
+{
+ struct yaml_node_s *parent;
+ int parent_index;
+
+ if (STACK_EMPTY(parser, *ctx)) {
+ /* This is the root node, there's no tree to add it to. */
+ return 1;
+ }
+
+ parent_index = *((*ctx).top - 1);
+ parent = &parser->document->nodes.start[parent_index-1];
+
+ switch (parent->type) {
+ case YAML_SEQUENCE_NODE:
+ if (!STACK_LIMIT(parser, parent->data.sequence.items, INT_MAX-1))
+ return 0;
+ if (!PUSH(parser, parent->data.sequence.items, index))
+ return 0;
+ break;
+ case YAML_MAPPING_NODE: {
+ yaml_node_pair_t pair;
+ if (!STACK_EMPTY(parser, parent->data.mapping.pairs)) {
+ yaml_node_pair_t *p = parent->data.mapping.pairs.top - 1;
+ if (p->key != 0 && p->value == 0) {
+ p->value = index;
+ break;
+ }
+ }
+
+ pair.key = index;
+ pair.value = 0;
+ if (!STACK_LIMIT(parser, parent->data.mapping.pairs, INT_MAX-1))
+ return 0;
+ if (!PUSH(parser, parent->data.mapping.pairs, pair))
+ return 0;
+
+ break;
+ }
+ default:
+ assert(0); /* Could not happen. */
+ return 0;
+ }
+ return 1;
+}
+
+/*
* Compose a node corresponding to an alias.
*/
static int
-yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *event,
- struct loader_ctx *ctx)
+yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx)
{
- yaml_char_t *anchor = event->data.alias.anchor;
+ yaml_char_t *anchor = event->data.alias.anchor;
yaml_alias_data_t *alias_data;
for (alias_data = parser->aliases.start;
alias_data != parser->aliases.top; alias_data ++) {
if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
yaml_free(anchor);
- return yaml_parser_load_node_add(parser, ctx, alias_data->index);
+ return yaml_parser_load_node_add(parser, ctx, alias_data->index);
}
}
yaml_free(anchor);
return yaml_parser_set_composer_error(parser, "found undefined alias",
- event->start_mark);
+ event->start_mark);
}
/*
@@ -372,12 +372,12 @@ yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *event,
*/
static int
-yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *event,
- struct loader_ctx *ctx)
+yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx)
{
yaml_node_t node;
int index;
- yaml_char_t *tag = event->data.scalar.tag;
+ yaml_char_t *tag = event->data.scalar.tag;
if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
@@ -387,23 +387,23 @@ yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *event,
if (!tag) goto error;
}
- SCALAR_NODE_INIT(node, tag, event->data.scalar.value,
- event->data.scalar.length, event->data.scalar.style,
- event->start_mark, event->end_mark);
+ SCALAR_NODE_INIT(node, tag, event->data.scalar.value,
+ event->data.scalar.length, event->data.scalar.style,
+ event->start_mark, event->end_mark);
if (!PUSH(parser, parser->document->nodes, node)) goto error;
index = parser->document->nodes.top - parser->document->nodes.start;
if (!yaml_parser_register_anchor(parser, index,
- event->data.scalar.anchor)) return 0;
+ event->data.scalar.anchor)) return 0;
- return yaml_parser_load_node_add(parser, ctx, index);
+ return yaml_parser_load_node_add(parser, ctx, index);
error:
yaml_free(tag);
- yaml_free(event->data.scalar.anchor);
- yaml_free(event->data.scalar.value);
+ yaml_free(event->data.scalar.anchor);
+ yaml_free(event->data.scalar.value);
return 0;
}
@@ -412,8 +412,8 @@ error:
*/
static int
-yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *event,
- struct loader_ctx *ctx)
+yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx)
{
yaml_node_t node;
struct {
@@ -421,8 +421,8 @@ yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *event,
yaml_node_item_t *end;
yaml_node_item_t *top;
} items = { NULL, NULL, NULL };
- int index;
- yaml_char_t *tag = event->data.sequence_start.tag;
+ int index;
+ yaml_char_t *tag = event->data.sequence_start.tag;
if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
@@ -432,56 +432,56 @@ yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *event,
if (!tag) goto error;
}
- if (!STACK_INIT(parser, items, yaml_node_item_t*)) goto error;
+ if (!STACK_INIT(parser, items, yaml_node_item_t*)) goto error;
SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
- event->data.sequence_start.style,
- event->start_mark, event->end_mark);
+ event->data.sequence_start.style,
+ event->start_mark, event->end_mark);
if (!PUSH(parser, parser->document->nodes, node)) goto error;
index = parser->document->nodes.top - parser->document->nodes.start;
if (!yaml_parser_register_anchor(parser, index,
- event->data.sequence_start.anchor)) return 0;
+ event->data.sequence_start.anchor)) return 0;
- if (!yaml_parser_load_node_add(parser, ctx, index)) return 0;
+ if (!yaml_parser_load_node_add(parser, ctx, index)) return 0;
- if (!STACK_LIMIT(parser, *ctx, INT_MAX-1)) return 0;
- if (!PUSH(parser, *ctx, index)) return 0;
+ if (!STACK_LIMIT(parser, *ctx, INT_MAX-1)) return 0;
+ if (!PUSH(parser, *ctx, index)) return 0;
- return 1;
+ return 1;
error:
yaml_free(tag);
- yaml_free(event->data.sequence_start.anchor);
+ yaml_free(event->data.sequence_start.anchor);
return 0;
}
-static int
-yaml_parser_load_sequence_end(yaml_parser_t *parser, yaml_event_t *event,
- struct loader_ctx *ctx)
-{
- int index;
-
- assert(((*ctx).top - (*ctx).start) > 0);
-
- index = *((*ctx).top - 1);
- assert(parser->document->nodes.start[index-1].type == YAML_SEQUENCE_NODE);
- parser->document->nodes.start[index-1].end_mark = event->end_mark;
-
- (void)POP(parser, *ctx);
-
- return 1;
-}
-
+static int
+yaml_parser_load_sequence_end(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx)
+{
+ int index;
+
+ assert(((*ctx).top - (*ctx).start) > 0);
+
+ index = *((*ctx).top - 1);
+ assert(parser->document->nodes.start[index-1].type == YAML_SEQUENCE_NODE);
+ parser->document->nodes.start[index-1].end_mark = event->end_mark;
+
+ (void)POP(parser, *ctx);
+
+ return 1;
+}
+
/*
* Compose a mapping node.
*/
static int
-yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *event,
- struct loader_ctx *ctx)
+yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx)
{
yaml_node_t node;
struct {
@@ -490,7 +490,7 @@ yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *event,
yaml_node_pair_t *top;
} pairs = { NULL, NULL, NULL };
int index;
- yaml_char_t *tag = event->data.mapping_start.tag;
+ yaml_char_t *tag = event->data.mapping_start.tag;
if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
@@ -500,45 +500,45 @@ yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *event,
if (!tag) goto error;
}
- if (!STACK_INIT(parser, pairs, yaml_node_pair_t*)) goto error;
+ if (!STACK_INIT(parser, pairs, yaml_node_pair_t*)) goto error;
MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
- event->data.mapping_start.style,
- event->start_mark, event->end_mark);
+ event->data.mapping_start.style,
+ event->start_mark, event->end_mark);
if (!PUSH(parser, parser->document->nodes, node)) goto error;
index = parser->document->nodes.top - parser->document->nodes.start;
if (!yaml_parser_register_anchor(parser, index,
- event->data.mapping_start.anchor)) return 0;
+ event->data.mapping_start.anchor)) return 0;
- if (!yaml_parser_load_node_add(parser, ctx, index)) return 0;
+ if (!yaml_parser_load_node_add(parser, ctx, index)) return 0;
- if (!STACK_LIMIT(parser, *ctx, INT_MAX-1)) return 0;
- if (!PUSH(parser, *ctx, index)) return 0;
+ if (!STACK_LIMIT(parser, *ctx, INT_MAX-1)) return 0;
+ if (!PUSH(parser, *ctx, index)) return 0;
- return 1;
+ return 1;
error:
yaml_free(tag);
- yaml_free(event->data.mapping_start.anchor);
+ yaml_free(event->data.mapping_start.anchor);
return 0;
}
-static int
-yaml_parser_load_mapping_end(yaml_parser_t *parser, yaml_event_t *event,
- struct loader_ctx *ctx)
-{
- int index;
-
- assert(((*ctx).top - (*ctx).start) > 0);
-
- index = *((*ctx).top - 1);
- assert(parser->document->nodes.start[index-1].type == YAML_MAPPING_NODE);
- parser->document->nodes.start[index-1].end_mark = event->end_mark;
-
- (void)POP(parser, *ctx);
-
- return 1;
-} \ No newline at end of file
+static int
+yaml_parser_load_mapping_end(yaml_parser_t *parser, yaml_event_t *event,
+ struct loader_ctx *ctx)
+{
+ int index;
+
+ assert(((*ctx).top - (*ctx).start) > 0);
+
+ index = *((*ctx).top - 1);
+ assert(parser->document->nodes.start[index-1].type == YAML_MAPPING_NODE);
+ parser->document->nodes.start[index-1].end_mark = event->end_mark;
+
+ (void)POP(parser, *ctx);
+
+ return 1;
+} \ No newline at end of file
diff --git a/contrib/libs/yaml/src/parser.c b/contrib/libs/yaml/src/parser.c
index 605cc5ee01..ec2f8d3e05 100644
--- a/contrib/libs/yaml/src/parser.c
+++ b/contrib/libs/yaml/src/parser.c
@@ -605,7 +605,7 @@ yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) {
size_t prefix_len = strlen((char *)tag_directive->prefix);
size_t suffix_len = strlen((char *)tag_suffix);
- tag = YAML_MALLOC(prefix_len+suffix_len+1);
+ tag = YAML_MALLOC(prefix_len+suffix_len+1);
if (!tag) {
parser->error = YAML_MEMORY_ERROR;
goto error;
@@ -685,7 +685,7 @@ yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
return 1;
}
else if (anchor || tag) {
- yaml_char_t *value = YAML_MALLOC(1);
+ yaml_char_t *value = YAML_MALLOC(1);
if (!value) {
parser->error = YAML_MEMORY_ERROR;
goto error;
@@ -760,7 +760,7 @@ yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
else if (token->type == YAML_BLOCK_END_TOKEN)
{
parser->state = POP(parser, parser->states);
- (void)POP(parser, parser->marks);
+ (void)POP(parser, parser->marks);
SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
SKIP_TOKEN(parser);
return 1;
@@ -869,7 +869,7 @@ yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
else if (token->type == YAML_BLOCK_END_TOKEN)
{
parser->state = POP(parser, parser->states);
- (void)POP(parser, parser->marks);
+ (void)POP(parser, parser->marks);
MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
SKIP_TOKEN(parser);
return 1;
@@ -994,7 +994,7 @@ yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
}
parser->state = POP(parser, parser->states);
- (void)POP(parser, parser->marks);
+ (void)POP(parser, parser->marks);
SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
SKIP_TOKEN(parser);
return 1;
@@ -1154,7 +1154,7 @@ yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
}
parser->state = POP(parser, parser->states);
- (void)POP(parser, parser->marks);
+ (void)POP(parser, parser->marks);
MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
SKIP_TOKEN(parser);
return 1;
@@ -1208,7 +1208,7 @@ yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
{
yaml_char_t *value;
- value = YAML_MALLOC(1);
+ value = YAML_MALLOC(1);
if (!value) {
parser->error = YAML_MEMORY_ERROR;
return 0;
@@ -1245,7 +1245,7 @@ yaml_parser_process_directives(yaml_parser_t *parser,
} tag_directives = { NULL, NULL, NULL };
yaml_token_t *token;
- if (!STACK_INIT(parser, tag_directives, yaml_tag_directive_t*))
+ if (!STACK_INIT(parser, tag_directives, yaml_tag_directive_t*))
goto error;
token = PEEK_TOKEN(parser);
@@ -1261,15 +1261,15 @@ yaml_parser_process_directives(yaml_parser_t *parser,
goto error;
}
if (token->data.version_directive.major != 1
- || (
- token->data.version_directive.minor != 1
- && token->data.version_directive.minor != 2
- )) {
+ || (
+ token->data.version_directive.minor != 1
+ && token->data.version_directive.minor != 2
+ )) {
yaml_parser_set_parser_error(parser,
"found incompatible YAML document", token->start_mark);
goto error;
}
- version_directive = YAML_MALLOC_STATIC(yaml_version_directive_t);
+ version_directive = YAML_MALLOC_STATIC(yaml_version_directive_t);
if (!version_directive) {
parser->error = YAML_MEMORY_ERROR;
goto error;
@@ -1294,7 +1294,7 @@ yaml_parser_process_directives(yaml_parser_t *parser,
token = PEEK_TOKEN(parser);
if (!token) goto error;
}
-
+
for (default_tag_directive = default_tag_directives;
default_tag_directive->handle; default_tag_directive++) {
if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1,
@@ -1319,8 +1319,8 @@ yaml_parser_process_directives(yaml_parser_t *parser,
STACK_DEL(parser, tag_directives);
}
- if (!version_directive_ref)
- yaml_free(version_directive);
+ if (!version_directive_ref)
+ yaml_free(version_directive);
return 1;
error:
diff --git a/contrib/libs/yaml/src/reader.c b/contrib/libs/yaml/src/reader.c
index 7169d5accd..f3ac54c251 100644
--- a/contrib/libs/yaml/src/reader.c
+++ b/contrib/libs/yaml/src/reader.c
@@ -52,7 +52,7 @@ yaml_parser_determine_encoding(yaml_parser_t *parser)
{
/* Ensure that we had enough bytes in the raw buffer. */
- while (!parser->eof
+ while (!parser->eof
&& parser->raw_buffer.last - parser->raw_buffer.pointer < 3) {
if (!yaml_parser_update_raw_buffer(parser)) {
return 0;
@@ -295,7 +295,7 @@ yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
parser->offset, value);
break;
-
+
case YAML_UTF16LE_ENCODING:
case YAML_UTF16BE_ENCODING:
@@ -318,7 +318,7 @@ yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
*
* The following formulas are used for decoding
* and encoding characters using surrogate pairs:
- *
+ *
* U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF)
* U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF)
* W1 = 110110yyyyyyyyyy
@@ -460,10 +460,10 @@ yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
}
- if (parser->offset >= MAX_FILE_SIZE) {
+ if (parser->offset >= MAX_FILE_SIZE) {
return yaml_parser_set_reader_error(parser, "input is too long",
- parser->offset, -1);
- }
+ parser->offset, -1);
+ }
return 1;
}
diff --git a/contrib/libs/yaml/src/scanner.c b/contrib/libs/yaml/src/scanner.c
index 551b69476d..c6b4987656 100644
--- a/contrib/libs/yaml/src/scanner.c
+++ b/contrib/libs/yaml/src/scanner.c
@@ -38,8 +38,8 @@
* BLOCK-END # Indentation decrease.
* FLOW-SEQUENCE-START # '['
* FLOW-SEQUENCE-END # ']'
- * FLOW-MAPPING-START # '{'
- * FLOW-MAPPING-END # '}'
+ * FLOW-MAPPING-START # '{'
+ * FLOW-MAPPING-END # '}'
* BLOCK-ENTRY # '-'
* FLOW-ENTRY # ','
* KEY # '?' or nothing (simple keys).
@@ -70,7 +70,7 @@
* %TAG !yaml! tag:yaml.org,2002:
* ---
*
- * The corresponding sequence of tokens:
+ * The corresponding sequence of tokens:
*
* STREAM-START(utf-8)
* VERSION-DIRECTIVE(1,1)
@@ -348,7 +348,7 @@
* SCALAR("another value",plain)
* KEY
* SCALAR("a mapping",plain)
- * VALUE
+ * VALUE
* BLOCK-MAPPING-START
* KEY
* SCALAR("key 1",plain)
@@ -712,7 +712,7 @@ yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive,
yaml_mark_t start_mark, yaml_char_t **handle);
static int
-yaml_parser_scan_tag_uri(yaml_parser_t *parser, int uri_char, int directive,
+yaml_parser_scan_tag_uri(yaml_parser_t *parser, int uri_char, int directive,
yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri);
static int
@@ -763,7 +763,7 @@ yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token)
}
/* Fetch the next token from the queue. */
-
+
*token = DEQUEUE(parser, parser->tokens);
parser->token_available = 0;
parser->tokens_parsed ++;
@@ -1115,7 +1115,7 @@ yaml_parser_save_simple_key(yaml_parser_t *parser)
yaml_simple_key_t simple_key;
simple_key.possible = 1;
simple_key.required = required;
- simple_key.token_number =
+ simple_key.token_number =
parser->tokens_parsed + (parser->tokens.tail - parser->tokens.head);
simple_key.mark = parser->mark;
@@ -1189,7 +1189,7 @@ yaml_parser_decrease_flow_level(yaml_parser_t *parser)
{
if (parser->flow_level) {
parser->flow_level --;
- (void)POP(parser, parser->simple_keys);
+ (void)POP(parser, parser->simple_keys);
}
return 1;
@@ -1199,7 +1199,7 @@ yaml_parser_decrease_flow_level(yaml_parser_t *parser)
* Push the current indentation level to the stack and set the new level
* the current column is greater than the indentation level. In this case,
* append or insert the specified token into the token queue.
- *
+ *
*/
static int
@@ -1250,7 +1250,7 @@ yaml_parser_roll_indent(yaml_parser_t *parser, ptrdiff_t column,
/*
* Pop indentation levels from the indents stack until the current level
- * becomes less or equal to the column. For each indentation level, append
+ * becomes less or equal to the column. For each indentation level, append
* the BLOCK-END token.
*/
@@ -1265,7 +1265,7 @@ yaml_parser_unroll_indent(yaml_parser_t *parser, ptrdiff_t column)
if (parser->flow_level)
return 1;
- /* Loop through the indentation levels in the stack. */
+ /* Loop through the indentation levels in the stack. */
while (parser->indent > column)
{
@@ -1637,7 +1637,7 @@ yaml_parser_fetch_key(yaml_parser_t *parser)
if (!parser->flow_level)
{
- /* Check if we are allowed to start a new key (not necessary simple). */
+ /* Check if we are allowed to start a new key (not necessary simple). */
if (!parser->simple_key_allowed) {
return yaml_parser_set_scanner_error(parser, NULL, parser->mark,
@@ -1937,7 +1937,7 @@ yaml_parser_scan_to_next_token(yaml_parser_t *parser)
*
* - in the flow context;
* - in the block context, but not at the beginning of the line or
- * after '-', '?', or ':' (complex value).
+ * after '-', '?', or ':' (complex value).
*/
if (!CACHE(parser, 1)) return 0;
@@ -2052,7 +2052,7 @@ yaml_parser_scan_directive(yaml_parser_t *parser, yaml_token_t *token)
else
{
yaml_parser_set_scanner_error(parser, "while scanning a directive",
- start_mark, "found unknown directive name");
+ start_mark, "found unknown directive name");
goto error;
}
@@ -2293,7 +2293,7 @@ yaml_parser_scan_tag_directive_value(yaml_parser_t *parser,
/* Scan a prefix. */
- if (!yaml_parser_scan_tag_uri(parser, 1, 1, NULL, start_mark, &prefix_value))
+ if (!yaml_parser_scan_tag_uri(parser, 1, 1, NULL, start_mark, &prefix_value))
goto error;
/* Expect a whitespace or line break. */
@@ -2400,7 +2400,7 @@ yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token)
{
/* Set the handle to '' */
- handle = YAML_MALLOC(1);
+ handle = YAML_MALLOC(1);
if (!handle) goto error;
handle[0] = '\0';
@@ -2411,7 +2411,7 @@ yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token)
/* Consume the tag value. */
- if (!yaml_parser_scan_tag_uri(parser, 1, 0, NULL, start_mark, &suffix))
+ if (!yaml_parser_scan_tag_uri(parser, 1, 0, NULL, start_mark, &suffix))
goto error;
/* Check for '>' and eat it. */
@@ -2439,20 +2439,20 @@ yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token)
{
/* Scan the suffix now. */
- if (!yaml_parser_scan_tag_uri(parser, 0, 0, NULL, start_mark, &suffix))
+ if (!yaml_parser_scan_tag_uri(parser, 0, 0, NULL, start_mark, &suffix))
goto error;
}
else
{
/* It wasn't a handle after all. Scan the rest of the tag. */
- if (!yaml_parser_scan_tag_uri(parser, 0, 0, handle, start_mark, &suffix))
+ if (!yaml_parser_scan_tag_uri(parser, 0, 0, handle, start_mark, &suffix))
goto error;
/* Set the handle to '!'. */
yaml_free(handle);
- handle = YAML_MALLOC(2);
+ handle = YAML_MALLOC(2);
if (!handle) goto error;
handle[0] = '!';
handle[1] = '\0';
@@ -2475,11 +2475,11 @@ yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token)
if (!CACHE(parser, 1)) goto error;
if (!IS_BLANKZ(parser->buffer)) {
- if (!parser->flow_level || !CHECK(parser->buffer, ',') ) {
- yaml_parser_set_scanner_error(parser, "while scanning a tag",
- start_mark, "did not find expected whitespace or line break");
- goto error;
- }
+ if (!parser->flow_level || !CHECK(parser->buffer, ',') ) {
+ yaml_parser_set_scanner_error(parser, "while scanning a tag",
+ start_mark, "did not find expected whitespace or line break");
+ goto error;
+ }
}
end_mark = parser->mark;
@@ -2568,7 +2568,7 @@ error:
*/
static int
-yaml_parser_scan_tag_uri(yaml_parser_t *parser, int uri_char, int directive,
+yaml_parser_scan_tag_uri(yaml_parser_t *parser, int uri_char, int directive,
yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri)
{
size_t length = head ? strlen((char *)head) : 0;
@@ -2604,11 +2604,11 @@ yaml_parser_scan_tag_uri(yaml_parser_t *parser, int uri_char, int directive,
* The set of characters that may appear in URI is as follows:
*
* '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&',
- * '=', '+', '$', '.', '!', '~', '*', '\'', '(', ')', '%'.
- *
- * If we are inside a verbatim tag <...> (parameter uri_char is true)
- * then also the following flow indicators are allowed:
- * ',', '[', ']'
+ * '=', '+', '$', '.', '!', '~', '*', '\'', '(', ')', '%'.
+ *
+ * If we are inside a verbatim tag <...> (parameter uri_char is true)
+ * then also the following flow indicators are allowed:
+ * ',', '[', ']'
*/
while (IS_ALPHA(parser->buffer) || CHECK(parser->buffer, ';')
@@ -2616,22 +2616,22 @@ yaml_parser_scan_tag_uri(yaml_parser_t *parser, int uri_char, int directive,
|| CHECK(parser->buffer, ':') || CHECK(parser->buffer, '@')
|| CHECK(parser->buffer, '&') || CHECK(parser->buffer, '=')
|| CHECK(parser->buffer, '+') || CHECK(parser->buffer, '$')
- || CHECK(parser->buffer, '.') || CHECK(parser->buffer, '%')
+ || CHECK(parser->buffer, '.') || CHECK(parser->buffer, '%')
|| CHECK(parser->buffer, '!') || CHECK(parser->buffer, '~')
|| CHECK(parser->buffer, '*') || CHECK(parser->buffer, '\'')
|| CHECK(parser->buffer, '(') || CHECK(parser->buffer, ')')
- || (uri_char && (
- CHECK(parser->buffer, ',')
- || CHECK(parser->buffer, '[') || CHECK(parser->buffer, ']')
- )
- ))
+ || (uri_char && (
+ CHECK(parser->buffer, ',')
+ || CHECK(parser->buffer, '[') || CHECK(parser->buffer, ']')
+ )
+ ))
{
/* Check if it is a URI-escape sequence. */
if (CHECK(parser->buffer, '%')) {
- if (!STRING_EXTEND(parser, string))
- goto error;
-
+ if (!STRING_EXTEND(parser, string))
+ goto error;
+
if (!yaml_parser_scan_uri_escapes(parser,
directive, start_mark, &string)) goto error;
}
@@ -2782,15 +2782,15 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token,
if (IS_DIGIT(parser->buffer))
{
- /* Check that the indentation is greater than 0. */
+ /* Check that the indentation is greater than 0. */
if (CHECK(parser->buffer, '0')) {
yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
- start_mark, "found an indentation indicator equal to 0");
+ start_mark, "found an indentation indicator equal to 0");
goto error;
}
- /* Get the indentation level and eat the indicator. */
+ /* Get the indentation level and eat the indicator. */
increment = AS_DIGIT(parser->buffer);
@@ -2804,7 +2804,7 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token,
{
if (CHECK(parser->buffer, '0')) {
yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
- start_mark, "found an indentation indicator equal to 0");
+ start_mark, "found an indentation indicator equal to 0");
goto error;
}
@@ -2854,7 +2854,7 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token,
end_mark = parser->mark;
- /* Set the indentation level if it was specified. */
+ /* Set the indentation level if it was specified. */
if (increment) {
indent = parser->indent >= 0 ? parser->indent+increment : increment;
@@ -2869,7 +2869,7 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token,
if (!CACHE(parser, 1)) goto error;
- while ((int)parser->mark.column == indent && !(IS_Z(parser->buffer)))
+ while ((int)parser->mark.column == indent && !(IS_Z(parser->buffer)))
{
/*
* We are at the beginning of a non-empty line.
@@ -2920,7 +2920,7 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token,
if (!READ_LINE(parser, leading_break)) goto error;
- /* Eat the following indentation spaces and line breaks. */
+ /* Eat the following indentation spaces and line breaks. */
if (!yaml_parser_scan_block_scalar_breaks(parser,
&indent, &trailing_breaks, start_mark, &end_mark)) goto error;
@@ -2955,8 +2955,8 @@ error:
}
/*
- * Scan indentation spaces and line breaks for a block scalar. Determine the
- * indentation level if needed.
+ * Scan indentation spaces and line breaks for a block scalar. Determine the
+ * indentation level if needed.
*/
static int
@@ -2968,11 +2968,11 @@ yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser,
*end_mark = parser->mark;
- /* Eat the indentation spaces and line breaks. */
+ /* Eat the indentation spaces and line breaks. */
while (1)
{
- /* Eat the indentation spaces. */
+ /* Eat the indentation spaces. */
if (!CACHE(parser, 1)) return 0;
@@ -2985,12 +2985,12 @@ yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser,
if ((int)parser->mark.column > max_indent)
max_indent = (int)parser->mark.column;
- /* Check for a tab character messing the indentation. */
+ /* Check for a tab character messing the indentation. */
if ((!*indent || (int)parser->mark.column < *indent)
&& IS_TAB(parser->buffer)) {
return yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
- start_mark, "found a tab character where an indentation space is expected");
+ start_mark, "found a tab character where an indentation space is expected");
}
/* Have we found a non-empty line? */
@@ -3014,7 +3014,7 @@ yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser,
*indent = 1;
}
- return 1;
+ return 1;
}
/*
@@ -3169,8 +3169,8 @@ yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token,
*(string.pointer++) = '"';
break;
- case '/':
- *(string.pointer++) = '/';
+ case '/':
+ *(string.pointer++) = '/';
break;
case '\\':
@@ -3287,11 +3287,11 @@ yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token,
/* Check if we are at the end of the scalar. */
- /* Fix for crash unitialized value crash
- * Credit for the bug and input is to OSS Fuzz
- * Credit for the fix to Alex Gaynor
- */
- if (!CACHE(parser, 1)) goto error;
+ /* Fix for crash unitialized value crash
+ * Credit for the bug and input is to OSS Fuzz
+ * Credit for the fix to Alex Gaynor
+ */
+ if (!CACHE(parser, 1)) goto error;
if (CHECK(parser->buffer, single ? '\'' : '"'))
break;
@@ -3439,22 +3439,22 @@ yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token)
while (!IS_BLANKZ(parser->buffer))
{
- /* Check for "x:" + one of ',?[]{}' in the flow context. TODO: Fix the test "spec-08-13".
- * This is not completely according to the spec
- * See http://yaml.org/spec/1.1/#id907281 9.1.3. Plain
- */
+ /* Check for "x:" + one of ',?[]{}' in the flow context. TODO: Fix the test "spec-08-13".
+ * This is not completely according to the spec
+ * See http://yaml.org/spec/1.1/#id907281 9.1.3. Plain
+ */
if (parser->flow_level
&& CHECK(parser->buffer, ':')
- && (
- CHECK_AT(parser->buffer, ',', 1)
- || CHECK_AT(parser->buffer, '?', 1)
- || CHECK_AT(parser->buffer, '[', 1)
- || CHECK_AT(parser->buffer, ']', 1)
- || CHECK_AT(parser->buffer, '{', 1)
- || CHECK_AT(parser->buffer, '}', 1)
- )
- ) {
+ && (
+ CHECK_AT(parser->buffer, ',', 1)
+ || CHECK_AT(parser->buffer, '?', 1)
+ || CHECK_AT(parser->buffer, '[', 1)
+ || CHECK_AT(parser->buffer, ']', 1)
+ || CHECK_AT(parser->buffer, '{', 1)
+ || CHECK_AT(parser->buffer, '}', 1)
+ )
+ ) {
yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
start_mark, "found unexpected ':'");
goto error;
@@ -3464,8 +3464,8 @@ yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token)
if ((CHECK(parser->buffer, ':') && IS_BLANKZ_AT(parser->buffer, 1))
|| (parser->flow_level &&
- (CHECK(parser->buffer, ',')
- || CHECK(parser->buffer, '[')
+ (CHECK(parser->buffer, ',')
+ || CHECK(parser->buffer, '[')
|| CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{')
|| CHECK(parser->buffer, '}'))))
break;
@@ -3527,12 +3527,12 @@ yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token)
{
if (IS_BLANK(parser->buffer))
{
- /* Check for tab characters that abuse indentation. */
+ /* Check for tab characters that abuse indentation. */
if (leading_blanks && (int)parser->mark.column < indent
&& IS_TAB(parser->buffer)) {
yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
- start_mark, "found a tab character that violates indentation");
+ start_mark, "found a tab character that violates indentation");
goto error;
}
@@ -3565,7 +3565,7 @@ yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token)
if (!CACHE(parser, 1)) goto error;
}
- /* Check indentation level. */
+ /* Check indentation level. */
if (!parser->flow_level && (int)parser->mark.column < indent)
break;
diff --git a/contrib/libs/yaml/src/writer.c b/contrib/libs/yaml/src/writer.c
index b90019f5cb..5d57f392f1 100644
--- a/contrib/libs/yaml/src/writer.c
+++ b/contrib/libs/yaml/src/writer.c
@@ -74,7 +74,7 @@ yaml_emitter_flush(yaml_emitter_t *emitter)
unsigned int value;
size_t k;
- /*
+ /*
* See the "reader.c" code for more details on UTF-8 encoding. Note
* that we assume that the buffer contains a valid UTF-8 sequence.
*/
diff --git a/contrib/libs/yaml/src/yaml_private.h b/contrib/libs/yaml/src/yaml_private.h
index dd83d8dcf9..b3351c4165 100644
--- a/contrib/libs/yaml/src/yaml_private.h
+++ b/contrib/libs/yaml/src/yaml_private.h
@@ -1,6 +1,6 @@
-#if HAVE_CONFIG_H
+#if HAVE_CONFIG_H
#include "config.h"
-#endif
+#endif
#include <yaml.h>
@@ -67,17 +67,17 @@ yaml_parser_fetch_more_tokens(yaml_parser_t *parser);
#define OUTPUT_RAW_BUFFER_SIZE (OUTPUT_BUFFER_SIZE*2+2)
/*
- * The maximum size of a YAML input file.
- * This used to be PTRDIFF_MAX, but that's not entirely portable
- * because stdint.h isn't available on all platforms.
- * It is not entirely clear why this isn't the maximum value
- * that can fit into the parser->offset field.
- */
-
-#define MAX_FILE_SIZE (~(size_t)0 / 2)
-
-
-/*
+ * The maximum size of a YAML input file.
+ * This used to be PTRDIFF_MAX, but that's not entirely portable
+ * because stdint.h isn't available on all platforms.
+ * It is not entirely clear why this isn't the maximum value
+ * that can fit into the parser->offset field.
+ */
+
+#define MAX_FILE_SIZE (~(size_t)0 / 2)
+
+
+/*
* The size of other stacks and queues.
*/
@@ -90,7 +90,7 @@ yaml_parser_fetch_more_tokens(yaml_parser_t *parser);
*/
#define BUFFER_INIT(context,buffer,size) \
- (((buffer).start = (yaml_char_t *)yaml_malloc(size)) ? \
+ (((buffer).start = (yaml_char_t *)yaml_malloc(size)) ? \
((buffer).last = (buffer).pointer = (buffer).start, \
(buffer).end = (buffer).start+(size), \
1) : \
@@ -130,7 +130,7 @@ yaml_string_join(
(value).pointer = (string))
#define STRING_INIT(context,string,size) \
- (((string).start = YAML_MALLOC(size)) ? \
+ (((string).start = YAML_MALLOC(size)) ? \
((string).pointer = (string).start, \
(string).end = (string).start+(size), \
memset((string).start, 0, (size)), \
@@ -143,12 +143,12 @@ yaml_string_join(
(string).start = (string).pointer = (string).end = 0)
#define STRING_EXTEND(context,string) \
- ((((string).pointer+5 < (string).end) \
+ ((((string).pointer+5 < (string).end) \
|| yaml_string_extend(&(string).start, \
- &(string).pointer, &(string).end)) ? \
- 1 : \
- ((context)->error = YAML_MEMORY_ERROR, \
- 0))
+ &(string).pointer, &(string).end)) ? \
+ 1 : \
+ ((context)->error = YAML_MEMORY_ERROR, \
+ 0))
#define CLEAR(context,string) \
((string).pointer = (string).start, \
@@ -171,14 +171,14 @@ yaml_string_join(
* Check the octet at the specified position.
*/
-#define CHECK_AT(string,octet,offset) \
+#define CHECK_AT(string,octet,offset) \
((string).pointer[offset] == (yaml_char_t)(octet))
/*
* Check the current octet in the buffer.
*/
-#define CHECK(string,octet) (CHECK_AT((string),(octet),0))
+#define CHECK(string,octet) (CHECK_AT((string),(octet),0))
/*
* Check if the character at the specified position is an alphabetical
@@ -420,10 +420,10 @@ yaml_stack_extend(void **start, void **top, void **end);
YAML_DECLARE(int)
yaml_queue_extend(void **start, void **head, void **tail, void **end);
-#define STACK_INIT(context,stack,type) \
- (((stack).start = (type)yaml_malloc(INITIAL_STACK_SIZE*sizeof(*(stack).start))) ? \
+#define STACK_INIT(context,stack,type) \
+ (((stack).start = (type)yaml_malloc(INITIAL_STACK_SIZE*sizeof(*(stack).start))) ? \
((stack).top = (stack).start, \
- (stack).end = (stack).start+INITIAL_STACK_SIZE, \
+ (stack).end = (stack).start+INITIAL_STACK_SIZE, \
1) : \
((context)->error = YAML_MEMORY_ERROR, \
0))
@@ -453,8 +453,8 @@ yaml_queue_extend(void **start, void **head, void **tail, void **end);
#define POP(context,stack) \
(*(--(stack).top))
-#define QUEUE_INIT(context,queue,size,type) \
- (((queue).start = (type)yaml_malloc((size)*sizeof(*(queue).start))) ? \
+#define QUEUE_INIT(context,queue,size,type) \
+ (((queue).start = (type)yaml_malloc((size)*sizeof(*(queue).start))) ? \
((queue).head = (queue).tail = (queue).start, \
(queue).end = (queue).start+(size), \
1) : \
@@ -658,27 +658,27 @@ yaml_queue_extend(void **start, void **head, void **tail, void **end);
(node).data.mapping.pairs.top = (node_pairs_start), \
(node).data.mapping.style = (node_style))
-/* Strict C compiler warning helpers */
-
-#if defined(__clang__) || defined(__GNUC__)
-# define HASATTRIBUTE_UNUSED
-#endif
-#ifdef HASATTRIBUTE_UNUSED
-# define __attribute__unused__ __attribute__((__unused__))
-#else
-# define __attribute__unused__
-#endif
-
-/* Shim arguments are arguments that must be included in your function,
- * but serve no purpose inside. Silence compiler warnings. */
-#define SHIM(a) /*@unused@*/ a __attribute__unused__
-
-/* UNUSED_PARAM() marks a shim argument in the body to silence compiler warnings */
-#ifdef __clang__
-# define UNUSED_PARAM(a) (void)(a);
-#else
-# define UNUSED_PARAM(a) /*@-noeffect*/if (0) (void)(a)/*@=noeffect*/;
-#endif
-
-#define YAML_MALLOC_STATIC(type) (type*)yaml_malloc(sizeof(type))
-#define YAML_MALLOC(size) (yaml_char_t *)yaml_malloc(size)
+/* Strict C compiler warning helpers */
+
+#if defined(__clang__) || defined(__GNUC__)
+# define HASATTRIBUTE_UNUSED
+#endif
+#ifdef HASATTRIBUTE_UNUSED
+# define __attribute__unused__ __attribute__((__unused__))
+#else
+# define __attribute__unused__
+#endif
+
+/* Shim arguments are arguments that must be included in your function,
+ * but serve no purpose inside. Silence compiler warnings. */
+#define SHIM(a) /*@unused@*/ a __attribute__unused__
+
+/* UNUSED_PARAM() marks a shim argument in the body to silence compiler warnings */
+#ifdef __clang__
+# define UNUSED_PARAM(a) (void)(a);
+#else
+# define UNUSED_PARAM(a) /*@-noeffect*/if (0) (void)(a)/*@=noeffect*/;
+#endif
+
+#define YAML_MALLOC_STATIC(type) (type*)yaml_malloc(sizeof(type))
+#define YAML_MALLOC(size) (yaml_char_t *)yaml_malloc(size)
diff --git a/contrib/libs/yaml/ya.make b/contrib/libs/yaml/ya.make
index d408b1e2ea..547a2b2a63 100644
--- a/contrib/libs/yaml/ya.make
+++ b/contrib/libs/yaml/ya.make
@@ -1,5 +1,5 @@
-# Generated by devtools/yamaker from nixpkgs 21.11.
-
+# Generated by devtools/yamaker from nixpkgs 21.11.
+
LIBRARY()
OWNER(
@@ -7,27 +7,27 @@ OWNER(
g:cpp-contrib
)
-VERSION(0.2.5)
+VERSION(0.2.5)
ORIGINAL_SOURCE(https://github.com/yaml/libyaml/archive/0.2.5.tar.gz)
-LICENSE(MIT)
-
-LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-
+LICENSE(MIT)
+
+LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
+
ADDINCL(
GLOBAL contrib/libs/yaml/include
- contrib/libs/yaml/src
+ contrib/libs/yaml/src
)
NO_COMPILER_WARNINGS()
-NO_RUNTIME()
-
-CFLAGS(
- -DHAVE_CONFIG_H
-)
-
+NO_RUNTIME()
+
+CFLAGS(
+ -DHAVE_CONFIG_H
+)
+
SRCS(
src/api.c
src/dumper.c
diff --git a/contrib/libs/zstd/programs/zstd/ya.make b/contrib/libs/zstd/programs/zstd/ya.make
index 26caf570e4..684f19e513 100644
--- a/contrib/libs/zstd/programs/zstd/ya.make
+++ b/contrib/libs/zstd/programs/zstd/ya.make
@@ -16,12 +16,12 @@ PEERDIR(
contrib/libs/zstd
)
-ADDINCL(
- contrib/libs/zstd/lib
- contrib/libs/zstd/lib/common
- contrib/libs/zstd/programs
-)
-
+ADDINCL(
+ contrib/libs/zstd/lib
+ contrib/libs/zstd/lib/common
+ contrib/libs/zstd/programs
+)
+
NO_COMPILER_WARNINGS()
NO_RUNTIME()
@@ -31,18 +31,18 @@ CFLAGS(
-DZSTD_MULTITHREAD
)
-SRCDIR(contrib/libs/zstd/programs)
+SRCDIR(contrib/libs/zstd/programs)
SRCS(
- benchfn.c
- benchzstd.c
- datagen.c
- dibio.c
- fileio.c
- timefn.c
- util.c
- zstdcli.c
- zstdcli_trace.c
+ benchfn.c
+ benchzstd.c
+ datagen.c
+ dibio.c
+ fileio.c
+ timefn.c
+ util.c
+ zstdcli.c
+ zstdcli_trace.c
)
END()
diff --git a/contrib/libs/zstd/ya.make b/contrib/libs/zstd/ya.make
index 86f5bbeee5..70d6705d1e 100644
--- a/contrib/libs/zstd/ya.make
+++ b/contrib/libs/zstd/ya.make
@@ -1,4 +1,4 @@
-# Generated by devtools/yamaker from nixpkgs 21.11.
+# Generated by devtools/yamaker from nixpkgs 21.11.
LIBRARY()
@@ -26,12 +26,12 @@ PEERDIR(
contrib/libs/xxhash
)
-ADDINCL(
- contrib/libs/zstd/lib
- contrib/libs/zstd/lib/common
- contrib/libs/zstd/lib/legacy
-)
-
+ADDINCL(
+ contrib/libs/zstd/lib
+ contrib/libs/zstd/lib/common
+ contrib/libs/zstd/lib/legacy
+)
+
NO_COMPILER_WARNINGS()
NO_RUNTIME()
diff --git a/contrib/libs/zstd06/ya.make b/contrib/libs/zstd06/ya.make
index 621169350d..e35f69f443 100644
--- a/contrib/libs/zstd06/ya.make
+++ b/contrib/libs/zstd06/ya.make
@@ -1,7 +1,7 @@
LIBRARY()
-VERSION(0.6.2)
-
+VERSION(0.6.2)
+
LICENSE(
BSD-2-Clause AND
MIT